diff --git a/.abigenrc b/.abigenrc deleted file mode 100644 index 82d12596320c..000000000000 --- a/.abigenrc +++ /dev/null @@ -1 +0,0 @@ -v1.10.25 diff --git a/.changeset/config.json b/.changeset/config.json index 293e745de7d7..6fd32816ad74 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,5 +7,6 @@ "access": "public", "baseBranch": "develop", "updateInternalDependencies": "patch", + "privatePackages": { "version": true, "tag": true }, "ignore": [] } diff --git a/.changeset/neat-carrots-camp.md b/.changeset/neat-carrots-camp.md new file mode 100644 index 000000000000..0253c49f451b --- /dev/null +++ b/.changeset/neat-carrots-camp.md @@ -0,0 +1,5 @@ +--- +'@eth-optimism/sdk': patch +--- + +Minor optimizations and improvements to FPAC functions. diff --git a/.circleci/config.yml b/.circleci/config.yml index 9804389292ee..2e0e84ac42e9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,9 +1,37 @@ version: 2.1 +parameters: + ci_builder_image: + type: string + default: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:v0.43.0 + ci_builder_rust_image: + type: string + default: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder-rust:latest + base_image: + type: string + default: default + # The dispatch parameters are used to manually dispatch pipelines that normally only run post-merge on develop + # from the CircleCI UI. Example configuration: + # when: + # or: + # - equal: [ "develop", <> ] + # - equal: [ true, <> ] + # Add a new `*_dispatch` parameter for any pipeline you want manual dispatch for. + main_dispatch: + type: boolean + default: true # default to running main in case the manual run cancelled an automatic run + fault_proofs_dispatch: + type: boolean + default: false + kontrol_dispatch: + type: boolean + default: false + orbs: go: circleci/go@1.8.0 gcp-cli: circleci/gcp-cli@3.0.1 slack: circleci/slack@4.10.1 + shellcheck: circleci/shellcheck@3.2.0 commands: gcp-oidc-authenticate: description: "Authenticate with GCP using a CircleCI OIDC token." @@ -45,41 +73,53 @@ commands: gcloud auth login --brief --cred-file "<< parameters.gcp_cred_config_file_path >>" # Configure ADC echo "export GOOGLE_APPLICATION_CREDENTIALS='<< parameters.gcp_cred_config_file_path >>'" | tee -a "$BASH_ENV" + check-changed: description: "Conditionally halts a step if certain modules change" parameters: patterns: type: string description: "Comma-separated list of dependencies" + no_go_deps: + type: string + default: "" + description: "If set, does not trigger on `go.mod` / `go.sum` changes." steps: - run: name: "Check for changes" + environment: + CHECK_CHANGED_NO_GO_DEPS: "<>" command: | cd ops/check-changed pip3 install -r requirements.txt python3 main.py "<>" + notify-failures-on-develop: description: "Notify Slack" parameters: channel: type: string default: C03N11M0BBN + mentions: + type: string + default: "" steps: - slack/notify: channel: << parameters.channel >> event: fail template: basic_fail_1 branch_pattern: develop + mentions: "<< parameters.mentions >>" jobs: cannon-go-lint-and-test: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> resource_class: medium steps: - checkout - check-changed: - patterns: cannon,packages/contracts-bedrock/src/cannon + patterns: cannon,packages/contracts-bedrock/src/cannon,op-preimage,go.mod - run: name: prep Cannon results dir command: mkdir -p /tmp/test-results @@ -105,7 +145,7 @@ jobs: path: /tmp/test-results cannon-build-test-vectors: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> resource_class: medium steps: - checkout @@ -118,16 +158,23 @@ jobs: pnpm-monorepo: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> resource_class: xlarge steps: - checkout - - check-changed: - patterns: op-chain-ops,packages/ + - run: + name: "Check L1 geth version" + command: ./ops/scripts/geth-version-checker.sh || (echo "geth version is wrong, update ci-builder"; false) + - run: + name: git submodules + command: make submodules - restore_cache: name: Restore PNPM Package Cache keys: - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} + - restore_cache: + name: Restore Go modules cache + key: gomod-{{ checksum "go.sum" }} # Fetch node_modules into the pnpm store # This will cache node_modules based on pnpm-lock so other steps can instantly install them with `pnpm install --prefer-offline` # --prefer-offline installs node_modules instantly by just reading from cache if it exists rather than fetching from network @@ -144,18 +191,47 @@ jobs: - "node_modules" - run: name: Install dependencies - command: pnpm install --frozen-lockfile --offline + command: pnpm install:ci:offline - run: name: print forge version command: forge --version - run: name: Build monorepo + environment: + FOUNDRY_PROFILE: ci command: pnpm build + - run: + name: Generate FPAC allocs + command: DEVNET_FPAC="true" make devnet-allocs + - run: + name: Copy FPAC allocs to .devnet-fpac + command: cp -r .devnet/ .devnet-fault-proofs/ + - run: + name: Generate Plasma allocs + command: DEVNET_PLASMA="true" make devnet-allocs + - run: + name: Copy Plasma allocs to .devnet-plasma + command: cp -r .devnet/ .devnet-plasma/ + - run: + name: Generate non-FPAC allocs + command: make devnet-allocs - persist_to_workspace: root: "." paths: - "packages/**/dist" + - "packages/contracts-bedrock/cache" + - "packages/contracts-bedrock/artifacts" - "packages/contracts-bedrock/forge-artifacts" + - "packages/contracts-bedrock/tsconfig.tsbuildinfo" + - "packages/contracts-bedrock/tsconfig.build.tsbuildinfo" + - ".devnet/allocs-l1.json" + - ".devnet/addresses.json" + - ".devnet-fault-proofs/allocs-l1.json" + - ".devnet-fault-proofs/addresses.json" + - ".devnet-plasma/allocs-l1.json" + - ".devnet-plasma/addresses.json" + - "packages/contracts-bedrock/deploy-config/devnetL1.json" + - "packages/contracts-bedrock/deployments/devnetL1" docker-build: environment: @@ -192,9 +268,13 @@ jobs: description: Run the release script type: boolean default: false + resource_class: + description: Docker resoruce class + type: string + default: medium machine: - image: ubuntu-2204:2022.07.1 - resource_class: medium + image: <> + resource_class: "<>" docker_layer_caching: true # we rely on this for faster builds, and actively warm it up for builds with common stages steps: - checkout @@ -213,13 +293,6 @@ jobs: - "<>" steps: - gcp-oidc-authenticate - # Below is CircleCI recommended way of specifying nameservers on an Ubuntu box: - # https://support.circleci.com/hc/en-us/articles/7323511028251-How-to-set-custom-DNS-on-Ubuntu-based-images-using-netplan - - run: sudo sed -i '13 i \ \ \ \ \ \ \ \ \ \ \ \ nameservers:' /etc/netplan/50-cloud-init.yaml - - run: sudo sed -i '14 i \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ addresses:' /etc/netplan/50-cloud-init.yaml - - run: sudo sed -i "s/addresses:/ addresses":" [8.8.8.8, 8.8.4.4] /g" /etc/netplan/50-cloud-init.yaml - - run: cat /etc/netplan/50-cloud-init.yaml - - run: sudo netplan apply - run: name: Build command: | @@ -296,20 +369,53 @@ jobs: name: Tag command: | ./ops/scripts/ci-docker-tag-op-stack-release.sh <>/<> $CIRCLE_TAG $CIRCLE_SHA1 + - when: + condition: + and: + - or: + - "<>" + - "<>" + - equal: [develop, << pipeline.git.branch >>] + steps: + - gcp-oidc-authenticate: + service_account_email: GCP_SERVICE_ATTESTOR_ACCOUNT_EMAIL + - run: + name: Sign + command: | + git clone https://github.com/ethereum-optimism/binary_signer + cd binary_signer/signer + git checkout tags/v1.0.3 + + IMAGE_PATH="<>/<>/<>:<>" + echo $IMAGE_PATH + pip3 install -r requirements.txt + + python3 ./sign_image.py --command="sign"\ + --attestor-project-name="$ATTESTOR_PROJECT_NAME"\ + --attestor-name="$ATTESTOR_NAME"\ + --image-path="$IMAGE_PATH"\ + --signer-logging-level="INFO"\ + --attestor-key-id="//cloudkms.googleapis.com/v1/projects/$ATTESTOR_PROJECT_NAME/locations/global/keyRings/$ATTESTOR_NAME-key-ring/cryptoKeys/$ATTESTOR_NAME-key/cryptoKeyVersions/1" + + contracts-bedrock-coverage: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> resource_class: xlarge steps: - checkout + - run: + name: git submodules + command: make submodules - check-changed: patterns: contracts-bedrock,op-node - run: name: print forge version command: forge --version working_directory: packages/contracts-bedrock + # We do not use the pre-built contracts becuase forge coverage uses different optimizer settings - run: name: test and generate coverage command: pnpm coverage:lcov @@ -325,12 +431,24 @@ jobs: contracts-bedrock-tests: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> resource_class: xlarge steps: - checkout + - run: + name: git submodules + command: make submodules + - restore_cache: + name: Restore PNPM Package Cache + keys: + - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} + - attach_workspace: { at: "." } - check-changed: patterns: contracts-bedrock,op-node + # populate node modules from the cache + - run: + name: Install dependencies + command: pnpm install:ci - run: name: print forge version command: forge --version @@ -345,23 +463,39 @@ jobs: contracts-bedrock-checks: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> resource_class: xlarge steps: - checkout + - run: + name: git submodules + command: make submodules - restore_cache: name: Restore PNPM Package Cache keys: - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} + - attach_workspace: { at: "." } - check-changed: patterns: contracts-bedrock,op-node + - setup_remote_docker: + docker_layer_caching: true # populate node modules from the cache - run: name: Install dependencies - command: pnpm install --frozen-lockfile --prefer-offline + command: pnpm install:ci + # Note: this step needs to come first because one of the later steps modifies the cache & forces a contracts rebuild - run: - name: build contracts - command: pnpm build + name: forge version + command: forge --version + - run: + name: semver lock + command: | + pnpm semver-lock + git diff --exit-code semver-lock.json || echo "export SEMVER_LOCK_STATUS=1" >> "$BASH_ENV" + working_directory: packages/contracts-bedrock + - run: + name: check deploy configs + command: pnpm validate-deploy-configs || echo "export DEPLOY_CONFIGS_STATUS=1" >> "$BASH_ENV" working_directory: packages/contracts-bedrock - run: name: lint @@ -371,24 +505,11 @@ jobs: - run: name: gas snapshot command: | - forge --version pnpm gas-snapshot --check || echo "export GAS_SNAPSHOT_STATUS=1" >> "$BASH_ENV" environment: FOUNDRY_PROFILE: ci working_directory: packages/contracts-bedrock no_output_timeout: 15m - - run: - name: storage snapshot - command: | - pnpm storage-snapshot - git diff --exit-code .storage-layout || echo "export STORAGE_SNAPSHOT_STATUS=1" >> "$BASH_ENV" - working_directory: packages/contracts-bedrock - - run: - name: semver lock - command: | - pnpm semver-lock - git diff --exit-code semver-lock.json || echo "export SEMVER_LOCK_STATUS=1" >> "$BASH_ENV" - working_directory: packages/contracts-bedrock - run: name: invariant docs command: | @@ -396,22 +517,19 @@ jobs: git diff --exit-code ./invariant-docs/*.md || echo "export INVARIANT_DOCS_STATUS=1" >> "$BASH_ENV" working_directory: packages/contracts-bedrock - run: - name: check deploy configs - command: pnpm validate-deploy-configs || echo "export DEPLOY_CONFIGS_STATUS=1" >> "$BASH_ENV" + name: snapshots + command: | + pnpm snapshots:check || echo "export SNAPSHOTS_STATUS=1" >> "$BASH_ENV" working_directory: packages/contracts-bedrock - run: name: check statuses command: | if [[ "$LINT_STATUS" -ne 0 ]]; then - FAILED=1 echo "Linting failed, see job output for details." + FAILED=1 fi if [[ "$GAS_SNAPSHOT_STATUS" -ne 0 ]]; then - FAILED=1 echo "Gas snapshot failed, see job output for details." - fi - if [[ "$STORAGE_SNAPSHOT_STATUS" -ne 0 ]]; then - echo "Storage snapshot failed, see job output for details." FAILED=1 fi if [[ "$SEMVER_LOCK_STATUS" -ne 0 ]]; then @@ -426,37 +544,28 @@ jobs: echo "Deploy config check failed, see job output for details." FAILED=1 fi + if [[ "$SNAPSHOTS_STATUS" -ne 0 ]]; then + echo "Snapshots check failed, see job output for details." + FAILED=1 + fi if [[ "$FAILED" -ne 0 ]]; then exit 1 fi - contracts-bedrock-slither: - docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - resource_class: large - steps: - - checkout - - check-changed: - patterns: contracts-bedrock - - run: - name: slither - command: | - slither --version && pnpm slither || echo "Slither failed" - contracts-bedrock-validate-spaces: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> + resource_class: medium steps: - checkout - - attach_workspace: { at: "." } - restore_cache: name: Restore PNPM Package Cache keys: - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - # populate node modules from the cache + - attach_workspace: { at: "." } - run: name: Install dependencies - command: pnpm install --frozen-lockfile --prefer-offline + command: pnpm install:ci - check-changed: patterns: contracts-bedrock - run: @@ -466,8 +575,8 @@ jobs: op-bindings-build: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - resource_class: large + - image: <> + resource_class: xlarge steps: - checkout - run: @@ -475,6 +584,30 @@ jobs: command: make && git diff --exit-code working_directory: op-bindings + bindgen-remote: + docker: + - image: <> + resource_class: xlarge + steps: + - checkout + - run: + name: bindgen remote bindings + command: make bindgen-remote && git diff --exit-code + working_directory: op-bindings + - notify-failures-on-develop + + bindgen-test-e2e: + docker: + - image: <> + resource_class: xlarge + steps: + - checkout + - run: + name: bindgen test E2E + command: make test-bindgen-e2e + working_directory: op-bindings-e2e + - notify-failures-on-develop + js-lint-test: parameters: package_name: @@ -488,7 +621,7 @@ jobs: description: Coverage flag name type: string docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> resource_class: large steps: - checkout @@ -502,7 +635,7 @@ jobs: # populate node modules from the cache - run: name: Install dependencies - command: pnpm install --frozen-lockfile --prefer-offline + command: pnpm install:ci - run: name: Lint command: pnpm lint && git diff --exit-code @@ -517,8 +650,8 @@ jobs: contracts-ts-tests: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - resource_class: large + - image: <> + resource_class: medium steps: - checkout - attach_workspace: { at: "." } @@ -531,7 +664,7 @@ jobs: # populate node modules from the cache - run: name: Install dependencies - command: pnpm install --frozen-lockfile --prefer-offline + command: pnpm install:ci - run: name: Check generated and build command: pnpm generate:check @@ -539,8 +672,8 @@ jobs: sdk-next-tests: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - resource_class: large + - image: <> + resource_class: medium steps: - checkout - attach_workspace: { at: "." } @@ -553,7 +686,7 @@ jobs: # populate node modules from the cache - run: name: Install dependencies - command: pnpm install --frozen-lockfile --prefer-offline + command: pnpm install:ci - run: name: anvil-l1 background: true @@ -593,7 +726,7 @@ jobs: todo-issues: machine: - image: ubuntu-2204:2022.07.1 + image: <> steps: - checkout - run: @@ -604,51 +737,6 @@ jobs: command: ./ops/scripts/todo-checker.sh --verbose - notify-failures-on-develop - bedrock-markdown: - machine: - image: ubuntu-2204:2022.07.1 - steps: - - checkout - - check-changed: - patterns: specs/(.*)\.md$ - - run: - name: Install pnpm package manager - command: | - npm i pnpm --global - - run: - name: pnpm dev deps - command: pnpm install --frozen-lockfile --prefer-offline - - run: - name: specs toc - command: pnpm lint:specs:toc && git diff --exit-code ./specs - - run: - name: markdown lint - command: pnpm lint:specs:check - - bedrock-markdown-links: - machine: - image: ubuntu-2204:2022.07.1 - steps: - - checkout - - run: - name: Install pnpm package manager - command: | - npm i pnpm --global - - run: - name: Install node_modules - command: | - pnpm install --frozen-lockfile --prefer-offline - - run: - name: Lint check - command: | - pnpm lint:specs:check - - run: - name: link lint - command: | - make bedrock-markdown-links - - notify-failures-on-develop: - channel: C055R639XT9 #notify-link-check - fuzz-golang: parameters: package_name: @@ -658,7 +746,7 @@ jobs: description: changed pattern to fire fuzzer on type: string docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> steps: - checkout - check-changed: @@ -680,7 +768,7 @@ jobs: depcheck: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> steps: - checkout - attach_workspace: { at: "." } @@ -705,7 +793,7 @@ jobs: l1-geth-version-check: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> steps: - checkout - run: @@ -714,7 +802,7 @@ jobs: go-lint: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> steps: - checkout - restore_cache: @@ -746,7 +834,7 @@ jobs: description: Go Module Name type: string docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest # only used to enable codecov. + - image: <> # only used to enable codecov. resource_class: xlarge steps: - checkout @@ -779,40 +867,72 @@ jobs: go-e2e-test: parameters: + fpac: + type: string + default: '' module: description: Go Module Name type: string target: description: The make target to execute type: string - cannon_enabled: - description: Whether to include cannon tests - default: true + parallelism: + description: Number of parallel test runs + type: integer + default: 6 + notify: + description: Whether to notify on failure type: boolean + default: false + mentions: + description: Slack user or group to mention when notifying of failures + type: string + default: "" + environment: + DEVNET_FPAC: 'false' + OP_E2E_USE_FPAC: 'false' docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> resource_class: xlarge - # Note: Tests are split between runs manually. - # Tests default to run on the first executor but can be moved to the second with: - # InitParallel(t, UseExecutor(1)) - # Any tests assigned to an executor greater than the number available automatically use the last executor. - # Executor indexes start from 0 - parallelism: 2 + parallelism: <> steps: - checkout + - when: + condition: + equal: ['-fault-proofs', <>] + steps: + - run: + name: Set DEVNET_FPAC = true + command: echo 'export DEVNET_FPAC=true' >> $BASH_ENV + - run: + name: Set OP_E2E_USE_FPAC = true + command: echo 'export OP_E2E_USE_FPAC=true' >> $BASH_ENV + - when: + condition: + equal: ['-plasma', <>] + steps: + - run: + name: Set OP_E2E_USE_PLASMA = true + command: echo 'export OP_E2E_USE_PLASMA=true' >> $BASH_ENV - check-changed: patterns: op-(.+),cannon,contracts-bedrock - run: name: prep results dir command: mkdir -p /tmp/test-results + - restore_cache: + name: Restore Go modules cache + key: gomod-{{ checksum "go.sum" }} + - restore_cache: + name: Restore Go build cache + key: golang-build-cache - attach_workspace: at: /tmp/workspace - run: name: Load devnet-allocs command: | mkdir -p .devnet - cp /tmp/workspace/.devnet/allocs-l1.json .devnet/allocs-l1.json - cp /tmp/workspace/.devnet/addresses.json .devnet/addresses.json + cp /tmp/workspace/.devnet<>/allocs-l1.json .devnet/allocs-l1.json + cp /tmp/workspace/.devnet<>/addresses.json .devnet/addresses.json cp /tmp/workspace/packages/contracts-bedrock/deploy-config/devnetL1.json packages/contracts-bedrock/deploy-config/devnetL1.json cp -r /tmp/workspace/packages/contracts-bedrock/deployments/devnetL1 packages/contracts-bedrock/deployments/devnetL1 - run: @@ -820,14 +940,28 @@ jobs: command: go tool dist list | grep mips - run: name: run tests + no_output_timeout: 20m command: | - export OP_E2E_CANNON_ENABLED="<>" + mkdir -p /testlogs + + # The below env var gets overridden when running make test-cannon, but we + # need to explicitly set it here to prevent Cannon from running when we don't + # want it to. + export OP_E2E_CANNON_ENABLED="false" # Note: We don't use circle CI test splits because we need to split by test name, not by package. There is an additional # constraint that gotestsum does not currently (nor likely will) accept files from different pacakges when building. - JUNIT_FILE=/tmp/test-results/<>_<>.xml make <> + JUNIT_FILE=/tmp/test-results/<>_<>.xml make <> 2>&1 | tee /testlogs/test.log working_directory: <> + - store_artifacts: + path: /testlogs + when: always - store_test_results: path: /tmp/test-results + - when: + condition: "<>" + steps: + - notify-failures-on-develop: + mentions: "<>" go-lint-test-build: parameters: @@ -846,7 +980,8 @@ jobs: type: string default: this-package-does-not-exist docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> + resource_class: medium steps: - checkout - check-changed: @@ -855,14 +990,14 @@ jobs: name: Lint command: make lint working_directory: <> - - store_test_results: - path: /test-results - run: name: Test command: | mkdir -p /test-results - gotestsum --junitfile /test-results/tests.xml + gotestsum --format=standard-verbose --junitfile /test-results/tests.xml -- -parallel=2 working_directory: <> + - store_test_results: + path: /test-results - when: condition: equal: [ true, <> ] @@ -873,12 +1008,29 @@ jobs: working_directory: <> indexer-tests: + parameters: + fpac: + type: string + default: '' + environment: + DEVNET_FPAC: 'false' + OP_E2E_USE_FPAC: 'false' docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> - image: cimg/postgres:14.1 - resource_class: large + resource_class: xlarge steps: - checkout + - when: + condition: + equal: ['fault-proofs', <>] + steps: + - run: + name: Set DEVNET_FPAC = true + command: echo 'export DEVNET_FPAC=true' >> $BASH_ENV + - run: + name: Set OP_E2E_USE_FPAC = true + command: echo 'export OP_E2E_USE_FPAC=true' >> $BASH_ENV - check-changed: patterns: indexer - run: @@ -887,7 +1039,7 @@ jobs: working_directory: indexer - run: name: git submodules - command: git submodule update --init --recursive + command: make submodules - run: name: generate cannon prestate command: make cannon-prestate @@ -908,8 +1060,7 @@ jobs: working_directory: indexer - run: name: Install node_modules - command: pnpm install --frozen-lockfile --prefer-offline - working_directory: indexer/api-ts + command: pnpm install:ci - run: name: Install tygo command: go install github.com/gzuidhof/tygo@latest @@ -921,7 +1072,7 @@ jobs: cannon-prestate: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> steps: - checkout - restore_cache: @@ -951,7 +1102,8 @@ jobs: devnet-allocs: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> + resource_class: xlarge steps: - checkout - restore_cache: @@ -961,7 +1113,7 @@ jobs: key: golang-build-cache - run: name: git submodules - command: git submodule update --init --recursive + command: make submodules - run: name: generate devnet allocs command: make devnet-allocs @@ -975,14 +1127,26 @@ jobs: devnet: machine: - image: ubuntu-2204:2022.10.2 + image: <> + parameters: + fpac: + type: string environment: DOCKER_BUILDKIT: 1 DEVNET_NO_BUILD: 'true' + # Default value; Can be overridden. + DEVNET_FPAC: 'false' steps: - checkout + - when: + condition: + equal: ['-fault-proofs', <>] + steps: + - run: + name: Set DEVNET_FPAC = true + command: echo 'export DEVNET_FPAC=true' >> $BASH_ENV - check-changed: - patterns: op-(.+),packages,ops-bedrock + patterns: op-(.+),packages,ops-bedrock,bedrock-devnet - run: name: Install latest golang command: | @@ -991,6 +1155,14 @@ jobs: sudo tar -C /usr/local -xzf go1.21.1.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin go version + - run: + name: Install Geth + command: | + wget https://gethstore.blob.core.windows.net/builds/geth-alltools-linux-amd64-1.13.4-3f907d6a.tar.gz + # geth only provides md5 sums sadly + echo 'c2e3d38372cb8081ed01591246a7556f geth-alltools-linux-amd64-1.13.4-3f907d6a.tar.gz' | md5sum -c - + tar -xzvf geth-alltools-linux-amd64-1.13.4-3f907d6a.tar.gz + sudo cp geth-alltools-linux-amd64-1.13.4-3f907d6a/* /usr/local/bin - run: name: foundryup command: | @@ -1000,9 +1172,6 @@ jobs: echo 'export PATH=$HOME/.foundry/bin:$PATH' >> $BASH_ENV source $HOME/.bashrc forge --version - - run: - name: install geth - command: make install-geth - run: name: Install NVM command: | @@ -1020,45 +1189,32 @@ jobs: npm i pnpm --global - run: name: git submodules - command: git submodule update --init --recursive - - run: - name: Install and build - command: | - pnpm install --frozen-lockfile --prefer-offline && pnpm build + command: make submodules - attach_workspace: - at: /tmp/workspace - - run: - name: Load cannon pre-state - command: | - mkdir -p op-program/bin - cp /tmp/workspace/op-program/bin/prestate.json op-program/bin/prestate.json - cp /tmp/workspace/op-program/bin/meta.json op-program/bin/meta.json - cp /tmp/workspace/op-program/bin/prestate-proof.json op-program/bin/prestate-proof.json - - run: - name: Load devnet-allocs - command: | - mkdir -p .devnet - cp /tmp/workspace/.devnet/allocs-l1.json .devnet/allocs-l1.json - cp /tmp/workspace/.devnet/addresses.json .devnet/addresses.json - cp /tmp/workspace/packages/contracts-bedrock/deploy-config/devnetL1.json packages/contracts-bedrock/deploy-config/devnetL1.json - cp -r /tmp/workspace/packages/contracts-bedrock/deployments/devnetL1 packages/contracts-bedrock/deployments/devnetL1 + at: "." - run: name: Load and tag docker images command: | IMAGE_BASE_PREFIX="us-docker.pkg.dev/oplabs-tools-artifacts/images" # Load from previous docker-build job - docker load < "/tmp/workspace/op-stack-go.tar" - docker load < "/tmp/workspace/op-node.tar" - docker load < "/tmp/workspace/op-proposer.tar" - docker load < "/tmp/workspace/op-batcher.tar" + docker load < "./op-stack-go.tar" + docker load < "./op-node.tar" + docker load < "./op-proposer.tar" + docker load < "./op-batcher.tar" # rename to the tags that the docker-compose of the devnet expects docker tag "$IMAGE_BASE_PREFIX/op-stack-go:<>" "$IMAGE_BASE_PREFIX/op-stack-go:devnet" docker tag "$IMAGE_BASE_PREFIX/op-node:<>" "$IMAGE_BASE_PREFIX/op-node:devnet" docker tag "$IMAGE_BASE_PREFIX/op-proposer:<>" "$IMAGE_BASE_PREFIX/op-proposer:devnet" docker tag "$IMAGE_BASE_PREFIX/op-batcher:<>" "$IMAGE_BASE_PREFIX/op-batcher:devnet" + - run: + name: pnpm i + command: | + pnpm i && pnpm build - run: name: Bring up the stack - command: make devnet-up + command: | + # Specify like this to avoid a forced rebuild of the contracts + devnet L1 + PYTHONPATH=./bedrock-devnet python3 ./bedrock-devnet/main.py --monorepo-dir=. - run: name: Test the stack command: make devnet-test @@ -1087,12 +1243,23 @@ jobs: command: | docker logs ops-bedrock-op-proposer-1 || echo "No logs." when: on_fail + - run: + name: Dump op-challenger logs + command: | + docker logs ops-bedrock-op-challenger-1 || echo "No logs." + when: on_fail - run: name: Log deployment artifact command: | cat broadcast/Deploy.s.sol/900/run-latest.json || echo "No deployment file found" when: on_fail working_directory: packages/contracts-bedrock + - run: + name: Log devnet config + command: | + cat deploy-config/devnetL1.json || echo "No devnet config found" + when: on_fail + working_directory: packages/contracts-bedrock - run: name: Log artifacts directory command: | @@ -1142,7 +1309,7 @@ jobs: go-mod-download: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> parameters: file: default: go.sum @@ -1163,27 +1330,67 @@ jobs: - run: command: go mod download name: Download Go module dependencies + - run: + name: "Go mod tidy" + command: make mod-tidy && git diff --exit-code + - run: + name: run Go linter + command: | + # Identify how many cores it defaults to + golangci-lint --help | grep concurrency + make lint-go + working_directory: . - save_cache: key: << parameters.key >>-{{ checksum "<< parameters.file >>" }} name: Save Go modules cache paths: - "/go/pkg/mod" - go-mod-tidy: + op-service-rethdb-tests: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> steps: - checkout + - check-changed: + patterns: op-service,op-node - restore_cache: name: Restore Go modules cache key: gomod-{{ checksum "go.sum" }} - run: - name: "Go mod tidy" - command: make mod-tidy && git diff --exit-code + name: Cargo fmt + clippy + command: | + cargo +nightly fmt -- --check + cargo +nightly clippy --all --all-features -- -D warnings + working_directory: op-service/rethdb-reader + - run: + name: Generate testdata db + command: cargo test + working_directory: op-service/rethdb-reader + - run: + name: Build dylib + command: cargo build --release + working_directory: op-service/rethdb-reader + - run: + name: Update LD_LIBRARY_PATH + command: echo 'export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/root/project/op-service/rethdb-reader/target/release"' >> $BASH_ENV + - run: + name: Run op-service RethDB tests + command: | + gotestsum --format=standard-verbose --junitfile=/tmp/test-results/op-service.xml \ + -- -parallel=8 -coverpkg=github.com/ethereum-optimism/optimism/... -coverprofile=coverage.out \ + -run TestRethDB -tags rethdb -v + working_directory: op-service/sources + # TODO(CLI-148): Fix codecov + #- run: + #name: upload coverage + #command: codecov --verbose --clean --flags bedrock-rethdb-go-tests bedrock-go-tests: # just a helper, that depends on all the actual test jobs docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + # Use a smaller base image to avoid pulling the huge ci-builder + # image which is not needed for this job and sometimes misses + # the cache. + - image: cimg/base:2024.01 resource_class: medium steps: - run: echo Done @@ -1194,15 +1401,16 @@ jobs: steps: - checkout - run: - name: verify-goerli + name: verify-sepolia command: | - make verify-goerli + make verify-sepolia working_directory: op-program - - notify-failures-on-develop + - notify-failures-on-develop: + mentions: "@proofs-squad" op-program-compat: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> steps: - checkout - restore_cache: @@ -1211,14 +1419,14 @@ jobs: - restore_cache: key: golang-build-cache - run: - name: compat-goerli + name: compat-sepolia command: | - make run-goerli-verify + make verify-compat working_directory: op-program check-generated-mocks-op-node: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> steps: - checkout - check-changed: @@ -1229,7 +1437,7 @@ jobs: check-generated-mocks-op-service: docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> steps: - checkout - check-changed: @@ -1253,20 +1461,52 @@ jobs: type: string default: "" docker: - - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + - image: <> steps: - checkout - run: name: Verify Values Match command: | ./ops/scripts/ci-match-values-between-files.sh "<< parameters.file1_path >>" "<< parameters.pattern_file1 >>" "<< parameters.file2_path >>" "<< parameters.pattern_file2 >>" + + kontrol-tests: + docker: + - image: << pipeline.parameters.ci_builder_image >> + resource_class: xlarge + steps: + - checkout + - run: + name: Checkout Submodule + command: make submodules + - check-changed: + no_go_deps: "true" + patterns: contracts-bedrock/test/kontrol,contracts-bedrock/src/L1/OptimismPortal\.sol,contracts-bedrock/src/L1/L1CrossDomainMessenger\.sol,contracts-bedrock/src/L1/L1ERC721Bridge\.sol,contracts-bedrock/src/L1/L1StandardBridge\.sol,contracts-bedrock/src/L1/ResourceMetering\.sol,contracts-bedrock/src/universal/StandardBridge\.sol,contracts-bedrock/src/universal/ERC721Bridge\.sol,contracts-bedrock/src/universal/CrossDomainMessenger\.sol + - setup_remote_docker: + docker_layer_caching: true + - run: + name: Run Kontrol Tests + command: pnpm test:kontrol + working_directory: ./packages/contracts-bedrock + - store_artifacts: + path: ./packages/contracts-bedrock/test/kontrol/logs/kontrol-results_latest.tar.gz + - store_test_results: + path: ./packages/contracts-bedrock + - notify-failures-on-develop + workflows: main: when: - not: - equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] + and: + - or: + # Trigger on new commits + - equal: [ webhook, << pipeline.trigger_source >> ] + # Trigger on manual triggers if explicitly requested + - equal: [ true, << pipeline.parameters.main_dispatch >> ] + - not: + equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] jobs: - - pnpm-monorepo + - pnpm-monorepo: + name: pnpm-monorepo - js-lint-test: name: common-ts-tests coverage_flag: common-ts-tests @@ -1279,12 +1519,13 @@ workflows: package_name: core-utils requires: - pnpm-monorepo - - contracts-bedrock-tests + - contracts-bedrock-tests: + requires: + - pnpm-monorepo - contracts-bedrock-coverage - contracts-bedrock-checks: requires: - pnpm-monorepo - - contracts-bedrock-slither - contracts-bedrock-validate-spaces: requires: - pnpm-monorepo @@ -1324,112 +1565,136 @@ workflows: name: proxyd-tests binary_name: proxyd working_directory: proxyd - - indexer-tests - - l1-geth-version-check + - indexer-tests: + name: indexer-tests<< matrix.fpac >> + matrix: + parameters: + fpac: ["", "-fault-proofs"] - semgrep-scan - go-mod-download - - go-mod-tidy: + - fuzz-golang: + name: op-challenger-fuzz + package_name: op-challenger + on_changes: op-challenger requires: ["go-mod-download"] - - devnet-allocs: # devnet-allocs uses op-node genesis sub-command - requires: - - "go-mod-tidy" - - l1-geth-version-check - - bedrock-markdown - - go-lint: # we combine most of the go-lint work for two reasons: (1) warm up the Go build cache, (2) reduce sum of lint time - name: op-stack-go-lint - requires: [ "go-mod-tidy" ] - fuzz-golang: name: op-node-fuzz package_name: op-node on_changes: op-node - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - fuzz-golang: name: op-service-fuzz package_name: op-service on_changes: op-service - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - fuzz-golang: name: op-chain-ops-fuzz package_name: op-chain-ops on_changes: op-chain-ops,op-bindings - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - fuzz-golang: name: cannon-fuzz package_name: cannon on_changes: cannon,packages/contracts-bedrock/src/cannon - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - go-test: name: op-heartbeat-tests module: op-heartbeat - requires: [ "op-stack-go-lint" ] + requires: [ "go-mod-download" ] - go-test: name: op-batcher-tests module: op-batcher - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - go-test: name: op-bindings-tests module: op-bindings - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - go-test: name: op-chain-ops-tests module: op-chain-ops - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - go-test: name: op-node-tests module: op-node - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - go-test: name: op-proposer-tests module: op-proposer - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - go-test: name: op-challenger-tests module: op-challenger - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] + - go-test: + name: op-dispute-mon-tests + module: op-dispute-mon + requires: ["go-mod-download"] + - go-test: + name: op-conductor-tests + module: op-conductor + requires: ["go-mod-download"] - go-test: name: op-program-tests module: op-program - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - go-test: name: op-service-tests module: op-service - requires: ["op-stack-go-lint"] + requires: ["go-mod-download"] - go-e2e-test: - name: op-e2e-WS-tests + name: op-e2e-HTTP-tests<< matrix.fpac >> + matrix: + parameters: + fpac: ["", "-fault-proofs"] module: op-e2e - target: test-ws + target: test-http + parallelism: 4 requires: - - op-stack-go-lint - - devnet-allocs + - go-mod-download + - pnpm-monorepo - go-e2e-test: - name: op-e2e-HTTP-tests + name: op-e2e-action-tests<< matrix.fpac >> + matrix: + parameters: + fpac: ["", "-fault-proofs", "-plasma"] module: op-e2e - target: test-http - cannon_enabled: false + target: test-actions + parallelism: 1 requires: - - op-stack-go-lint - - devnet-allocs + - go-mod-download + - pnpm-monorepo + - go-e2e-test: + name: op-e2e-fault-proof-tests + module: op-e2e + target: test-fault-proofs + parallelism: 4 + requires: + - pnpm-monorepo + - cannon-prestate - go-e2e-test: - name: op-e2e-ext-geth-tests + name: op-e2e-ext-geth-tests<< matrix.fpac >> + matrix: + parameters: + fpac: ["", "-fault-proofs"] module: op-e2e target: test-external-geth - cannon_enabled: false requires: - - op-stack-go-lint - - devnet-allocs - - l1-geth-version-check + - go-mod-download + - pnpm-monorepo + - op-service-rethdb-tests: + requires: + - go-mod-download - op-program-compat: requires: - op-program-tests - bedrock-go-tests: requires: - go-mod-download - - go-mod-tidy - cannon-build-test-vectors - cannon-go-lint-and-test - check-generated-mocks-op-node - check-generated-mocks-op-service - - op-stack-go-lint + - go-mod-download - op-batcher-tests - op-bindings-tests - op-chain-ops-tests @@ -1437,11 +1702,15 @@ workflows: - op-node-tests - op-proposer-tests - op-challenger-tests + - op-dispute-mon-tests + - op-conductor-tests - op-program-tests - op-program-compat - op-service-tests - - op-e2e-WS-tests + - op-service-rethdb-tests - op-e2e-HTTP-tests + - op-e2e-fault-proof-tests + - op-e2e-action-tests - op-e2e-ext-geth-tests - docker-build: # just to warm up the cache (other jobs run in parallel) name: op-stack-go-docker-build @@ -1478,6 +1747,18 @@ workflows: docker_tags: <>,<> requires: ['op-stack-go-docker-build'] save_image_tag: <> # for devnet later + - docker-build: + name: op-dispute-mon-docker-build + docker_name: op-dispute-mon + docker_tags: <>,<> + requires: ['op-stack-go-docker-build'] + save_image_tag: <> # for devnet later + - docker-build: + name: op-conductor-docker-build + docker_name: op-conductor + docker_tags: <>,<> + requires: ['op-stack-go-docker-build'] + save_image_tag: <> # for devnet later - docker-build: name: op-heartbeat-docker-build docker_name: op-heartbeat @@ -1485,14 +1766,17 @@ workflows: requires: ['op-stack-go-docker-build'] save_image_tag: <> # for devnet later - cannon-prestate: - requires: ["op-stack-go-lint"] + requires: + - go-mod-download - devnet: + matrix: + parameters: + fpac: ["legacy", "fault-proofs"] requires: - - op-node-docker-build + - pnpm-monorepo - op-batcher-docker-build - op-proposer-docker-build - - l1-geth-version-check - - devnet-allocs + - op-node-docker-build - cannon-prestate - docker-build: name: indexer-docker-build @@ -1506,11 +1790,13 @@ workflows: - check-generated-mocks-op-service - cannon-go-lint-and-test - cannon-build-test-vectors - - check-values-match: - pattern_file1: "uint8 internal constant INITIALIZER =" - pattern_file2: "const initializedValue =" - file1_path: "packages/contracts-bedrock/src/libraries/Constants.sol" - file2_path: "op-chain-ops/genesis/config.go" + - shellcheck/check: + name: shell-check + # We don't need the `exclude` key as the orb detects the `.shellcheckrc` + dir: . + ignore-dirs: + ./packages/contracts-bedrock/lib + release: when: not: @@ -1520,14 +1806,14 @@ workflows: type: approval filters: tags: - only: /^(proxyd|indexer|ci-builder|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)\/v.*/ + only: /^(proxyd|chain-mon|indexer|ci-builder(-rust)?|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)\/v.*/ branches: ignore: /.*/ - docker-build: # just to warm up the cache (other jobs run in parallel) name: op-stack-go-docker-build-release filters: tags: - only: /^(proxyd|indexer|ci-builder|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)\/v.*/ + only: /^(proxyd|chain-mon|indexer|ci-builder(-rust)?|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)\/v.*/ branches: ignore: /.*/ docker_name: op-stack-go @@ -1610,6 +1896,36 @@ workflows: release: true context: - oplabs-gcr-release + - docker-build: + name: op-dispute-mon-docker-release + filters: + tags: + only: /^op-dispute-mon\/v.*/ + branches: + ignore: /.*/ + docker_name: op-dispute-mon + docker_tags: <> + requires: ['op-stack-go-docker-build-release'] + platforms: "linux/amd64,linux/arm64" + publish: true + release: true + context: + - oplabs-gcr-release + - docker-build: + name: op-conductor-docker-release + filters: + tags: + only: /^op-conductor\/v.*/ + branches: + ignore: /.*/ + docker_name: op-conductor + docker_tags: <> + requires: ['op-stack-go-docker-build-release'] + platforms: "linux/amd64,linux/arm64" + publish: true + release: true + context: + - oplabs-gcr-release - docker-build: name: op-ufm-docker-release filters: @@ -1655,6 +1971,22 @@ workflows: - oplabs-gcr-release requires: - hold + - docker-build: + name: chain-mon-docker-release + filters: + tags: + only: /^chain-mon\/v.*/ + branches: + ignore: /.*/ + docker_name: chain-mon + docker_tags: <>,latest + publish: true + release: true + resource_class: xlarge + context: + - oplabs-gcr-release + requires: + - hold - docker-build: name: ci-builder-docker-release filters: @@ -1666,6 +1998,23 @@ workflows: docker_tags: <>,latest publish: true release: true + resource_class: xlarge + context: + - oplabs-gcr + requires: + - hold + - docker-build: + name: ci-builder-rust-docker-release + filters: + tags: + only: /^ci-builder-rust\/v.*/ + branches: + ignore: /.*/ + docker_name: ci-builder-rust + docker_tags: <>,latest + publish: true + release: true + resource_class: xlarge context: - oplabs-gcr requires: @@ -1704,12 +2053,48 @@ workflows: - slack - oplabs-fpp-nodes - scheduled-link-check: + develop-fault-proofs: when: - equal: [ build_daily, <> ] + and: + - or: + - equal: [ "develop", <> ] + - equal: [ true, <> ] + - not: + equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] jobs: - - bedrock-markdown-links: - context: slack + - go-mod-download + - cannon-prestate: + requires: + - go-mod-download + - pnpm-monorepo: + name: pnpm-monorepo + requires: + - go-mod-download + - go-e2e-test: + name: op-e2e-cannon-tests + module: op-e2e + target: test-cannon + parallelism: 4 + notify: true + mentions: "@proofs-squad" + requires: + - pnpm-monorepo + - cannon-prestate + context: + - slack + + develop-kontrol-tests: + when: + and: + - or: + - equal: [ "develop", <> ] + - equal: [ true, <> ] + - not: + equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] + jobs: + - kontrol-tests: + context: + - slack scheduled-docker-publish: when: @@ -1773,6 +2158,26 @@ workflows: context: - oplabs-gcr - slack + - docker-build: + name: op-dispute-mon-docker-publish + docker_name: op-dispute-mon + docker_tags: <>,<> + requires: [ 'op-stack-go-docker-build-publish' ] + platforms: "linux/amd64,linux/arm64" + publish: true + context: + - oplabs-gcr + - slack + - docker-build: + name: op-conductor-docker-publish + docker_name: op-conductor + docker_tags: <>,<> + requires: [ 'op-stack-go-docker-build-publish' ] + platforms: "linux/amd64,linux/arm64" + publish: true + context: + - oplabs-gcr + - slack - docker-build: name: op-heartbeat-docker-publish docker_name: op-heartbeat @@ -1796,6 +2201,17 @@ workflows: name: chain-mon-docker-publish docker_name: chain-mon docker_tags: <>,<> + resource_class: xlarge + publish: true + context: + - oplabs-gcr + - slack + - docker-build: + name: contracts-bedrock-docker-publish + docker_name: contracts-bedrock + docker_tags: <>,<> + resource_class: xlarge + requires: [ 'chain-mon-docker-publish' ] # use the cached base image publish: true context: - oplabs-gcr @@ -1808,3 +2224,16 @@ workflows: context: - oplabs-gcr - slack + + scheduled-bindgen: + when: + equal: [ build_daily, <> ] + jobs: + - bindgen-remote: + context: + - slack + - oplabs-etherscan + - bindgen-test-e2e: + context: + - slack + - oplabs-etherscan diff --git a/.coderabbit.yml b/.coderabbit.yml new file mode 100644 index 000000000000..2b0209adcf38 --- /dev/null +++ b/.coderabbit.yml @@ -0,0 +1,25 @@ +language: "en" +early_access: false +reviews: + high_level_summary: false + poem: false + review_status: false + collapse_walkthrough: true + path_filters: + - "!**/*.json" + - "!op-bindings/bindings/**" + path_instructions: + - path: "**.sol" + instructions: "Focus on the following areas: + - Security + - Identifying test cases which are lacking + - Removing unnecessary code + " + auto_review: + enabled: true + drafts: false + base_branches: + - "develop" + - "feat/*" +chat: + auto_reply: true diff --git a/.envrc.example b/.envrc.example new file mode 100644 index 000000000000..0ea9d7ea1bac --- /dev/null +++ b/.envrc.example @@ -0,0 +1,55 @@ +################################################## +# Getting Started # +################################################## + +# Admin account +export GS_ADMIN_ADDRESS= +export GS_ADMIN_PRIVATE_KEY= + +# Batcher account +export GS_BATCHER_ADDRESS= +export GS_BATCHER_PRIVATE_KEY= + +# Proposer account +export GS_PROPOSER_ADDRESS= +export GS_PROPOSER_PRIVATE_KEY= + +# Sequencer account +export GS_SEQUENCER_ADDRESS= +export GS_SEQUENCER_PRIVATE_KEY= + +################################################## +# op-node Configuration # +################################################## + +# The kind of RPC provider, used to inform optimal transactions receipts +# fetching. Valid options: alchemy, quicknode, infura, parity, nethermind, +# debug_geth, erigon, basic, any. +export L1_RPC_KIND= + +################################################## +# Contract Deployment # +################################################## + +# RPC URL for the L1 network to interact with +export L1_RPC_URL= + +# Salt used via CREATE2 to determine implementation addresses +# NOTE: If you want to deploy contracts from scratch you MUST reload this +# variable to ensure the salt is regenerated and the contracts are +# deployed to new addresses (otherwise deployment will fail) +export IMPL_SALT=$(openssl rand -hex 32) + +# Name for the deployed network +export DEPLOYMENT_CONTEXT=getting-started + +# Optional Tenderly details for simulation link during deployment +export TENDERLY_PROJECT= +export TENDERLY_USERNAME= + +# Optional Etherscan API key for contract verification +export ETHERSCAN_API_KEY= + +# Private key to use for contract deployments, you don't need to worry about +# this for the Getting Started guide. +export PRIVATE_KEY= diff --git a/.eslintrc.js b/.eslintrc.js index af5b30881efa..0152c354b87f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -113,7 +113,6 @@ module.exports = { indent: 'off', 'jsdoc/check-alignment': 'error', 'jsdoc/check-indentation': 'error', - 'jsdoc/newline-after-description': 'error', 'linebreak-style': 'off', 'max-classes-per-file': 'off', 'max-len': 'off', diff --git a/.foundryrc b/.foundryrc deleted file mode 100644 index 0a8ddf64ab6e..000000000000 --- a/.foundryrc +++ /dev/null @@ -1 +0,0 @@ -ee5d02c3ef5f55a06b069e4a70a820661a9130c8 diff --git a/.gethrc b/.gethrc deleted file mode 100644 index dd64e523ec44..000000000000 --- a/.gethrc +++ /dev/null @@ -1 +0,0 @@ -v1.13.4 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a142b138a992..9bfa44258161 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -12,8 +12,8 @@ /op-bootnode @ethereum-optimism/go-reviewers /op-chain-ops @ethereum-optimism/go-reviewers /op-challenger @ethereum-optimism/go-reviewers +/op-dispute-mon @ethereum-optimism/go-reviewers /op-e2e @ethereum-optimism/go-reviewers -/op-exporter @ethereum-optimism/go-reviewers /op-heartbeat @ethereum-optimism/go-reviewers /op-node @ethereum-optimism/go-reviewers /op-node/rollup @protolambda @trianglesphere @ajsutton @@ -23,12 +23,13 @@ /op-service @ethereum-optimism/go-reviewers /op-wheel @ethereum-optimism/go-reviewers /ops-bedrock @ethereum-optimism/go-reviewers +/op-conductor @0x00101010 @zhwrd @mslipper # Ops -/.circleci @ethereum-optimism/infra-reviewers -/.github @ethereum-optimism/infra-reviewers -/ops @ethereum-optimism/infra-reviewers -/docker-bake.hcl @ethereum-optimism/infra-reviewers +/.circleci @ethereum-optimism/monorepo-ops-reviewers +/.github @ethereum-optimism/monorepo-ops-reviewers +/ops @ethereum-optimism/monorepo-ops-reviewers +/docker-bake.hcl @ethereum-optimism/monorepo-ops-reviewers # Misc /proxyd @ethereum-optimism/infra-reviewers diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 6bf7d59aeac5..f45efa027414 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -7,7 +7,7 @@ runs: uses: pnpm/action-setup@v2 with: version: 8.6.5 - - name: Setup node 16.x + - name: Setup node uses: actions/setup-node@v3 with: node-version-file: .nvmrc @@ -19,10 +19,10 @@ runs: - name: Install node dependencies shell: bash - run: pnpm install --frozen-lockfile + run: pnpm install:ci - name: Derive appropriate SHAs for base and head for `nx affected` commands uses: nrwl/nx-set-shas@v3 - with: + with: main-branch-name: "develop" - run: | echo "nx using following shas:" diff --git a/.github/mergify.yml b/.github/mergify.yml index eacdb802e324..6cda289acf09 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -144,14 +144,6 @@ pull_request_rules: label: add: - A-op-e2e - - name: Add A-op-exporter label - conditions: - - 'files~=^op-exporter/' - - '#label<5' - actions: - label: - add: - - A-op-exporter - name: Add A-op-heartbeat label conditions: - 'files~=^op-heartbeat/' diff --git a/.github/workflows/close-stale.yml b/.github/workflows/close-stale.yml index 0a1a5fe8b62f..da7567fe8796 100644 --- a/.github/workflows/close-stale.yml +++ b/.github/workflows/close-stale.yml @@ -7,7 +7,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v4 + - uses: actions/stale@v9 with: stale-issue-message: 'This issue is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 5 days.' close-issue-message: 'The issue is closed due to long inactivity. You can reopen it for further questions or comments.' diff --git a/.github/workflows/release-docker-canary.yml b/.github/workflows/release-docker-canary.yml index 559d56a155f1..61ddf994f94c 100644 --- a/.github/workflows/release-docker-canary.yml +++ b/.github/workflows/release-docker-canary.yml @@ -15,13 +15,13 @@ jobs: runs-on: ubuntu-latest # map the step outputs to job outputs outputs: - fault-mon: ${{ steps.packages.outputs.fault-mon }} balance-mon: ${{ steps.packages.outputs.balance-mon }} drippie-mon: ${{ steps.packages.outputs.drippie-mon }} - wd-mon: ${{ steps.packages.outputs.wd-mon }} + fault-mon: ${{ steps.packages.outputs.fault-mon }} + multisig-mon: ${{ steps.packages.outputs.multisig-mon }} replica-mon: ${{ steps.packages.outputs.replica-mon }} + wd-mon: ${{ steps.packages.outputs.wd-mon }} canary-docker-tag: ${{ steps.docker-image-name.outputs.canary-docker-tag }} - op-exporter: ${{ steps.packages.outputs.op-exporter }} endpoint-monitor: ${{ steps.packages.outputs.endpoint-monitor }} steps: @@ -97,10 +97,10 @@ jobs: push: true tags: ethereumoptimism/balance-mon:${{ needs.canary-publish.outputs.canary-docker-tag }} - drippie-mon: - name: Publish Drippie Monitor Version ${{ needs.canary-publish.outputs.canary-docker-tag }} + multisig-mon: + name: Publish Multisig Monitor Version ${{ needs.canary-publish.outputs.canary-docker-tag }} needs: canary-publish - if: needs.canary-publish.outputs.drippie-mon != '' + if: needs.canary-publish.outputs.multisig-mon != '' runs-on: ubuntu-latest steps: @@ -120,14 +120,14 @@ jobs: with: context: . file: ./ops/docker/Dockerfile.packages - target: drippie-mon + target: multisig-mon push: true - tags: ethereumoptimism/drippie-mon:${{ needs.canary-publish.outputs.canary-docker-tag }} + tags: ethereumoptimism/multisig-mon:${{ needs.canary-publish.outputs.canary-docker-tag }} - wd-mon: - name: Publish Withdrawal Monitor Version ${{ needs.canary-publish.outputs.canary-docker-tag }} + drippie-mon: + name: Publish Drippie Monitor Version ${{ needs.canary-publish.outputs.canary-docker-tag }} needs: canary-publish - if: needs.canary-publish.outputs.wd-mon != '' + if: needs.canary-publish.outputs.drippie-mon != '' runs-on: ubuntu-latest steps: @@ -147,14 +147,14 @@ jobs: with: context: . file: ./ops/docker/Dockerfile.packages - target: wd-mon + target: drippie-mon push: true - tags: ethereumoptimism/wd-mon:${{ needs.canary-publish.outputs.canary-docker-tag }} + tags: ethereumoptimism/drippie-mon:${{ needs.canary-publish.outputs.canary-docker-tag }} - replica-mon: - name: Publish replica-mon Version ${{ needs.canary-publish.outputs.canary-docker-tag }} + wd-mon: + name: Publish Withdrawal Monitor Version ${{ needs.canary-publish.outputs.canary-docker-tag }} needs: canary-publish - if: needs.canary-publish.outputs.replica-mon != '' + if: needs.canary-publish.outputs.wd-mon != '' runs-on: ubuntu-latest steps: @@ -174,14 +174,14 @@ jobs: with: context: . file: ./ops/docker/Dockerfile.packages - target: replica-mon + target: wd-mon push: true - tags: ethereumoptimism/replica-mon:${{ needs.canary-publish.outputs.canary-docker-tag }} + tags: ethereumoptimism/wd-mon:${{ needs.canary-publish.outputs.canary-docker-tag }} - op-exporter: - name: Publish op-exporter Version ${{ needs.canary-publish.outputs.canary-docker-tag }} + replica-mon: + name: Publish replica-mon Version ${{ needs.canary-publish.outputs.canary-docker-tag }} needs: canary-publish - if: needs.canary-publish.outputs.op-exporter != '' + if: needs.canary-publish.outputs.replica-mon != '' runs-on: ubuntu-latest steps: @@ -196,24 +196,14 @@ jobs: username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }} password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }} - - name: Set build args - id: build_args - run: | - echo ::set-output name=GITDATE::"$(date +%d-%m-%Y)" - echo ::set-output name=GITVERSION::$(jq -r .version ./op-exporter/package.json) - echo ::set-output name=GITCOMMIT::"$GITHUB_SHA" - - name: Build and push uses: docker/build-push-action@v2 with: context: . - file: ./op-exporter/Dockerfile= + file: ./ops/docker/Dockerfile.packages + target: replica-mon push: true - tags: ethereumoptimism/op-exporter:${{ needs.canary-publish.outputs.op-exporter }} - build-args: | - GITDATE=${{ steps.build_args.outputs.GITDATE }} - GITCOMMIT=${{ steps.build_args.outputs.GITCOMMIT }} - GITVERSION=${{ steps.build_args.outputs.GITVERSION }} + tags: ethereumoptimism/replica-mon:${{ needs.canary-publish.outputs.canary-docker-tag }} endpoint-monitor: name: Publish endpoint-monitor Version ${{ needs.canary-publish.outputs.canary-docker-tag }} diff --git a/.github/workflows/release-snapshot.yml b/.github/workflows/release-snapshot.yml index e6811be3f781..372c970e2b99 100644 --- a/.github/workflows/release-snapshot.yml +++ b/.github/workflows/release-snapshot.yml @@ -29,6 +29,11 @@ jobs: env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Verify NPM Token is valid + run: npm whoami + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Publish snapshots uses: seek-oss/changesets-snapshot@v0 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4ecc0e211316..469db26b5d3a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,12 +16,12 @@ jobs: if: github.repository == 'ethereum-optimism/optimism' # map the step outputs to job outputs outputs: - fault-mon: ${{ steps.packages.outputs.fault-mon }} - balance-mon: ${{ steps.packages.outputs.drippie-mon }} + balance-mon: ${{ steps.packages.outputs.balance-mon }} drippie-mon: ${{ steps.packages.outputs.drippie-mon }} - wd-mon: ${{ steps.packages.outputs.wd-mon }} + fault-mon: ${{ steps.packages.outputs.fault-mon }} + multisig-mon: ${{ steps.packages.outputs.multisig-mon }} replica-mon: ${{ steps.packages.outputs.replica-mon }} - op-exporter: ${{ steps.packages.outputs.op-exporter }} + wd-mon: ${{ steps.packages.outputs.wd-mon }} endpoint-monitor: ${{ steps.packages.outputs.endpoint-monitor }} # Permissions necessary for Changesets to push a new branch and open PRs # (for automated Version Packages PRs), and request the JWT for provenance. @@ -41,11 +41,23 @@ jobs: - name: Setup uses: ./.github/actions/setup + - name: Check if NPM_TOKEN is set + id: check_token + run: | + if [ -z "${{ secrets.NPM_TOKEN }}" ]; then + echo "NPM_TOKEN is not set. Is it set it in your repository secrets?" + exit 1 + fi + shell: bash + - name: Set deployment token run: npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}" env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Verify NPM Token is valid + run: npm whoami + # Makes a pr to publish the changesets that when # merged will publish to npm # see https://github.com/changesets/action @@ -68,10 +80,10 @@ jobs: run: | node ops/scripts/ci-versions.js ${{ toJSON(steps.changesets.outputs.publishedPackages) }} - op-exporter: - name: Publish op-exporter Version ${{ needs.release.outputs.op-exporter}} + fault-mon: + name: Publish fault-mon Version ${{ needs.release.outputs.fault-mon }} needs: release - if: needs.release.outputs.op-exporter != '' + if: needs.release.outputs.fault-mon != '' runs-on: ubuntu-latest steps: @@ -86,29 +98,19 @@ jobs: username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }} password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }} - - name: Set build args - id: build_args - run: | - echo ::set-output name=GITDATE::"$(date +%d-%m-%Y)" - echo ::set-output name=GITVERSION::$(jq -r .version ./op-exporter/package.json) - echo ::set-output name=GITCOMMIT::"$GITHUB_SHA" - - name: Build and push uses: docker/build-push-action@v2 with: context: . - file: ./op-exporter/Dockerfile + file: ./ops/docker/Dockerfile.packages + target: fault-mon push: true - tags: ethereumoptimism/op-exporter:${{ needs.release.outputs.op-exporter }},ethereumoptimism/op-exporter:latest - build-args: | - GITDATE=${{ steps.build_args.outputs.GITDATE }} - GITCOMMIT=${{ steps.build_args.outputs.GITCOMMIT }} - GITVERSION=${{ steps.build_args.outputs.GITVERSION }} + tags: ethereumoptimism/fault-mon:${{ needs.release.outputs.fault-mon }},ethereumoptimism/fault-mon:latest - fault-mon: - name: Publish fault-mon Version ${{ needs.release.outputs.fault-mon }} + wd-mon: + name: Publish Withdrawal Monitor Version ${{ needs.release.outputs.wd-mon }} needs: release - if: needs.release.outputs.fault-mon != '' + if: needs.release.outputs.wd-mon != '' runs-on: ubuntu-latest steps: @@ -128,14 +130,14 @@ jobs: with: context: . file: ./ops/docker/Dockerfile.packages - target: fault-mon + target: wd-mon push: true - tags: ethereumoptimism/fault-mon:${{ needs.release.outputs.fault-mon }},ethereumoptimism/fault-mon:latest + tags: ethereumoptimism/wd-mon:${{ needs.release.outputs.wd-mon }},ethereumoptimism/wd-mon:latest - wd-mon: - name: Publish Withdrawal Monitor Version ${{ needs.release.outputs.wd-mon }} + balance-mon: + name: Publish Balance Monitor Version ${{ needs.release.outputs.balance-mon }} needs: release - if: needs.release.outputs.wd-mon != '' + if: needs.release.outputs.balance-mon != '' runs-on: ubuntu-latest steps: @@ -155,14 +157,14 @@ jobs: with: context: . file: ./ops/docker/Dockerfile.packages - target: wd-mon + target: balance-mon push: true - tags: ethereumoptimism/wd-mon:${{ needs.release.outputs.wd-mon }},ethereumoptimism/wd-mon:latest + tags: ethereumoptimism/balance-mon:${{ needs.release.outputs.balance-mon }},ethereumoptimism/balance-mon:latest - balance-mon: - name: Publish Balance Monitor Version ${{ needs.release.outputs.balance-mon }} + multisig-mon: + name: Publish Multisig Monitor Version ${{ needs.release.outputs.multisig-mon }} needs: release - if: needs.release.outputs.balance-mon != '' + if: needs.release.outputs.multisig-mon != '' runs-on: ubuntu-latest steps: @@ -182,9 +184,9 @@ jobs: with: context: . file: ./ops/docker/Dockerfile.packages - target: balance-mon + target: multisig-mon push: true - tags: ethereumoptimism/balance-mon:${{ needs.release.outputs.balance-mon }},ethereumoptimism/balance-mon:latest + tags: ethereumoptimism/multisig-mon:${{ needs.release.outputs.multisig-mon }},ethereumoptimism/multisig-mon:latest drippie-mon: name: Publish Drippie Monitor Version ${{ needs.release.outputs.drippie-mon }} diff --git a/.github/workflows/slither.yml b/.github/workflows/slither.yml new file mode 100644 index 000000000000..f8935a75070a --- /dev/null +++ b/.github/workflows/slither.yml @@ -0,0 +1,39 @@ +name: 'Slither Analysis' + +on: + workflow_dispatch: + pull_request: + push: + branches: + - develop + +jobs: + slither-analyze: + runs-on: ubuntu-latest + container: + image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:v0.43.0 + steps: + - uses: actions/checkout@v4 + + # Workaround to prevent slither-action from trying to install JS deps. + # Without this step, it detects the `package.json`, and since there is no + # lockfile it defaults `npm install` which fails due to the preinstall + # script to enforce pnpm. https://github.com/crytic/slither-action/issues/44#issuecomment-1338183656 + - name: Remove package.json + run: rm packages/contracts-bedrock/package.json + + - name: Run Slither + uses: crytic/slither-action@v0.3.1 + id: slither + with: + target: packages/contracts-bedrock + slither-config: packages/contracts-bedrock/slither.config.json + fail-on: config + sarif: results.sarif + slither-args: --triage-database packages/contracts-bedrock/slither.db.json + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v3 + if: always() + with: + sarif_file: ${{ steps.slither.outputs.sarif }} diff --git a/.github/workflows/tag-service.yml b/.github/workflows/tag-service.yml index 2567a5a333ad..35e2c6d8c805 100644 --- a/.github/workflows/tag-service.yml +++ b/.github/workflows/tag-service.yml @@ -19,6 +19,7 @@ on: type: choice options: - ci-builder + - ci-builder-rust - indexer - op-heartbeat - chain-mon @@ -26,9 +27,12 @@ on: - op-batcher - op-proposer - op-challenger + - op-program + - op-dispute-mon - op-ufm - proxyd - ufm-metamask + - op-contracts prerelease: description: Increment major/minor/patch as prerelease? required: false @@ -45,7 +49,7 @@ jobs: - name: Fetch tags run: git fetch --tags origin --force - name: Setup Python 3.10 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.10" - name: Install deps diff --git a/.gitignore b/.gitignore index 7e43dbf2efc1..54c16a1f67c3 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ packages/contracts-bedrock/deployments/anvil .env .env* !.env.example +!.envrc.example *.log .devnet @@ -41,8 +42,6 @@ coverage.out # Ignore bedrock go bindings local output files op-bindings/bin -op-exporter - __pycache__ diff --git a/.gitmodules b/.gitmodules index e3bf55582296..5ac336fdb249 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,3 +17,12 @@ path = packages/contracts-bedrock/lib/safe-contracts url = https://github.com/safe-global/safe-contracts branch = v1.4.0 +[submodule "packages/contracts-bedrock/lib/kontrol-cheatcodes"] + path = packages/contracts-bedrock/lib/kontrol-cheatcodes + url = https://github.com/runtimeverification/kontrol-cheatcodes +[submodule "packages/contracts-bedrock/lib/solady"] + path = packages/contracts-bedrock/lib/solady + url = https://github.com/Vectorized/solady +[submodule "packages/contracts-bedrock/lib/lib-keccak"] + path = packages/contracts-bedrock/lib/lib-keccak + url = https://github.com/ethereum-optimism/lib-keccak diff --git a/.markdownlint.json b/.markdownlint.json deleted file mode 100644 index f4e96a2481d0..000000000000 --- a/.markdownlint.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "line_length": { - "line_length": 120, - "strict": false, - "stern": true, - "code_blocks": false, - "tables": false, - }, - "no-blanks-blockquote": false, - "single-title": false, - "no-emphasis-as-heading": false, -} diff --git a/.prettierrc.js b/.prettierrc.js index f945261bf1cd..7b70850614ea 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,25 +1,10 @@ module.exports = { $schema: 'http://json.schemastore.org/prettierrc', - plugins: ['prettier-plugin-solidity'], + plugins: [], trailingComma: 'es5', tabWidth: 2, semi: false, singleQuote: true, arrowParens: 'always', - overrides: [ - { - files: '*.sol', - options: { - // These options are native to Prettier. - printWidth: 100, - tabWidth: 4, - useTabs: false, - singleQuote: false, - bracketSpacing: true, - // These options are specific to the Solidity Plugin - explicitTypes: 'always', - compiler: '>=0.8.15', - }, - }, - ], + overrides: [], } diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 000000000000..6eccb2a81279 --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1 @@ +disable=SC2002 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 96cd56173c13..c854c6eb91eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ There are plenty of ways to contribute, in particular we appreciate support in the following areas: - Reporting issues. For security issues see [Security policy](https://github.com/ethereum-optimism/.github/blob/master/SECURITY.md). -- Fixing and responding to existing issues. You can start off with those tagged ["good first issue"](https://github.com/ethereum-optimism/optimism/contribute) which are meant as introductory issues for external contributors. +- Fixing and responding to existing issues. You can start off with those tagged ["good first issue"](https://github.com/ethereum-optimism/optimism/labels/D-good-first-issue) which are meant as introductory issues for external contributors. - Improving the [community site](https://community.optimism.io/), [documentation](https://github.com/ethereum-optimism/community-hub) and [tutorials](https://github.com/ethereum-optimism/optimism-tutorial). - Become an "Optimizer" and answer questions in the [Optimism Discord](https://discord.optimism.io). - Get involved in the protocol design process by proposing changes or new features or write parts of the spec yourself in the [specs subdirectory](./specs/). @@ -30,6 +30,8 @@ We recommend using the [Conventional Commits](https://www.conventionalcommits.or Unless your PR is ready for immediate review and merging, please mark it as 'draft' (or simply do not open a PR yet). +Once ready for review, make sure to include a thorough PR description to help reviewers. You can read more about the guidelines for opening PRs in the [PR Guidelines](docs/handbook/pr-guidelines.md) file. + **Bonus:** Add comments to the diff under the "Files Changed" tab on the PR page to clarify any sections where you think we might have questions about the approach taken. ### Response time: @@ -68,6 +70,7 @@ You'll need the following: * [Docker Compose](https://docs.docker.com/compose/install/) * [Go](https://go.dev/dl/) * [Foundry](https://getfoundry.sh) +* [jq](https://jqlang.github.io/jq/) * [go-ethereum](https://github.com/ethereum/go-ethereum) ### Setup @@ -103,6 +106,7 @@ To build all of the [TypeScript packages](./packages), run: ```bash pnpm clean +pnpm install pnpm build ``` @@ -139,6 +143,7 @@ Finally, **if you're running into weird problems and nothing seems to be working ```bash cd optimism pnpm clean +pnpm install pnpm build cd ops docker compose down -v @@ -159,7 +164,7 @@ docker compose logs --follow Before running tests: **follow the above instructions to get everything built.** -#### Running unit tests +#### Running unit tests (typescript) Run unit tests for all packages in parallel via: @@ -174,6 +179,16 @@ cd packages/package-to-test pnpm test ``` +#### Running unit tests (Go) + +Change directory to the package you want to run tests for. Then: +```shell +go test ./... +``` + +#### Running e2e tests (Go) +See [this document](./op-e2e/README.md) + #### Running contract static analysis We perform static analysis with [`slither`](https://github.com/crytic/slither). diff --git a/LICENSE b/LICENSE index a19c072c21af..2633f89b4e2e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ (The MIT License) -Copyright 2020-2023 Optimism +Copyright 2020-2024 Optimism Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Makefile b/Makefile index ff7a8d0fc9ba..3825fb178ed2 100644 --- a/Makefile +++ b/Makefile @@ -20,18 +20,20 @@ build-ts: submodules if [ -n "$$NVM_DIR" ]; then \ . $$NVM_DIR/nvm.sh && nvm use; \ fi - pnpm install + pnpm install:ci + pnpm prepare pnpm build .PHONY: build-ts ci-builder: docker build -t ci-builder -f ops/docker/ci-builder/Dockerfile . +.PHONY: ci-builder golang-docker: # We don't use a buildx builder here, and just load directly into regular docker, for convenience. GIT_COMMIT=$$(git rev-parse HEAD) \ GIT_DATE=$$(git show -s --format='%ct') \ - IMAGE_TAGS=$$GIT_COMMIT,latest \ + IMAGE_TAGS=$$(git rev-parse HEAD),latest \ docker buildx bake \ --progress plain \ --load \ @@ -39,12 +41,17 @@ golang-docker: op-node op-batcher op-proposer op-challenger .PHONY: golang-docker +contracts-bedrock-docker: + IMAGE_TAGS=$$(git rev-parse HEAD),latest \ + docker buildx bake \ + --progress plain \ + --load \ + -f docker-bake.hcl \ + contracts-bedrock +.PHONY: contracts-bedrock-docker + submodules: - # CI will checkout submodules on its own (and fails on these commands) - if [ -z "$$GITHUB_ENV" ]; then \ - git submodule init; \ - git submodule update --recursive; \ - fi + git submodule update --init --recursive .PHONY: submodules op-bindings: @@ -75,6 +82,10 @@ op-challenger: make -C ./op-challenger op-challenger .PHONY: op-challenger +op-dispute-mon: + make -C ./op-dispute-mon op-dispute-mon +.PHONY: op-dispute-mon + op-program: make -C ./op-program op-program .PHONY: op-program @@ -83,10 +94,15 @@ cannon: make -C ./cannon cannon .PHONY: cannon +reproducible-prestate: + make -C ./op-program reproducible-prestate +.PHONY: reproducible-prestate + cannon-prestate: op-program cannon #./cannon/bin/cannon load-elf --path op-program/bin/op-program-client.elf --out op-program/bin/prestate.json --meta op-program/bin/meta.json #./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate.json --meta op-program/bin/meta.json --proof-fmt 'op-program/bin/%d.json' --output "" #mv op-program/bin/0.json op-program/bin/prestate-proof.json +.PHONY: cannon-prestate mod-tidy: # Below GOPRIVATE line allows mod-tidy to be run immediately after @@ -95,6 +111,7 @@ mod-tidy: # # See https://proxy.golang.org/ for more info. export GOPRIVATE="github.com/ethereum-optimism" && go mod tidy + make -C ./op-ufm mod-tidy .PHONY: mod-tidy clean: @@ -105,7 +122,7 @@ nuke: clean devnet-clean git clean -Xdf .PHONY: nuke -pre-devnet: +pre-devnet: submodules @if ! [ -x "$(command -v geth)" ]; then \ make install-geth; \ fi @@ -119,9 +136,6 @@ devnet-up: pre-devnet PYTHONPATH=./bedrock-devnet $(PYTHON) ./bedrock-devnet/main.py --monorepo-dir=. .PHONY: devnet-up -# alias for devnet-up -devnet-up-deploy: devnet-up - devnet-test: pre-devnet PYTHONPATH=./bedrock-devnet $(PYTHON) ./bedrock-devnet/main.py --monorepo-dir=. --test .PHONY: devnet-test @@ -140,10 +154,11 @@ devnet-clean: devnet-allocs: pre-devnet PYTHONPATH=./bedrock-devnet $(PYTHON) ./bedrock-devnet/main.py --monorepo-dir=. --allocs +.PHONY: devnet-allocs devnet-logs: @(cd ./ops-bedrock && docker compose logs -f) - .PHONY: devnet-logs +.PHONY: devnet-logs test-unit: make -C ./op-node test @@ -167,6 +182,7 @@ semgrep: clean-node-modules: rm -rf node_modules rm -rf packages/**/node_modules +.PHONY: clean-node-modules tag-bedrock-go-modules: ./ops/scripts/tag-bedrock-go-modules.sh $(BEDROCK_TAGS_REMOTE) $(VERSION) @@ -178,14 +194,14 @@ update-op-geth: bedrock-markdown-links: docker run --init -it -v `pwd`:/input lycheeverse/lychee --verbose --no-progress --exclude-loopback \ - --exclude twitter.com --exclude explorer.optimism.io --exclude linux-mips.org \ + --exclude twitter.com --exclude explorer.optimism.io --exclude linux-mips.org --exclude vitalik.ca \ --exclude-mail /input/README.md "/input/specs/**/*.md" +.PHONY: bedrock-markdown-links install-geth: ./ops/scripts/geth-version-checker.sh && \ (echo "Geth versions match, not installing geth..."; true) || \ (echo "Versions do not match, installing geth!"; \ - go install -v github.com/ethereum/go-ethereum/cmd/geth@$(shell cat .gethrc); \ + go install -v github.com/ethereum/go-ethereum/cmd/geth@$(shell jq -r .geth < versions.json); \ echo "Installed geth!"; true) .PHONY: install-geth - diff --git a/bedrock-devnet/devnet/__init__.py b/bedrock-devnet/devnet/__init__.py index c692034b28a0..b23980720571 100644 --- a/bedrock-devnet/devnet/__init__.py +++ b/bedrock-devnet/devnet/__init__.py @@ -10,6 +10,7 @@ import requests import shutil import http.client +import gzip from multiprocessing import Process, Queue import concurrent.futures from collections import namedtuple @@ -27,6 +28,11 @@ log = logging.getLogger() +# Global environment variables +DEVNET_NO_BUILD = os.getenv('DEVNET_NO_BUILD') == "true" +DEVNET_FPAC = os.getenv('DEVNET_FPAC') == "true" +DEVNET_PLASMA = os.getenv('DEVNET_PLASMA') == "true" + class Bunch: def __init__(self, **kwds): self.__dict__.update(kwds) @@ -59,6 +65,7 @@ def main(): devnet_dir = pjoin(monorepo_dir, '.devnet') contracts_bedrock_dir = pjoin(monorepo_dir, 'packages', 'contracts-bedrock') deployment_dir = pjoin(contracts_bedrock_dir, 'deployments', 'devnetL1') + forge_dump_path = pjoin(contracts_bedrock_dir, 'Deploy-900.json') op_node_dir = pjoin(args.monorepo_dir, 'op-node') ops_bedrock_dir = pjoin(monorepo_dir, 'ops-bedrock') deploy_config_dir = pjoin(contracts_bedrock_dir, 'deploy-config') @@ -72,6 +79,7 @@ def main(): devnet_dir=devnet_dir, contracts_bedrock_dir=contracts_bedrock_dir, deployment_dir=deployment_dir, + forge_dump_path=forge_dump_path, l1_deployments_path=pjoin(deployment_dir, '.deploy'), deploy_config_dir=deploy_config_dir, devnet_config_path=devnet_config_path, @@ -160,6 +168,11 @@ def init_devnet_l1_deploy_config(paths, update_timestamp=False): deploy_config = read_json(paths.devnet_config_template_path) if update_timestamp: deploy_config['l1GenesisBlockTimestamp'] = '{:#x}'.format(int(time.time())) + if DEVNET_FPAC: + deploy_config['useFaultProofs'] = True + deploy_config['faultGameMaxDuration'] = 10 + if DEVNET_PLASMA: + deploy_config['usePlasma'] = True write_json(paths.devnet_config_path, deploy_config) def devnet_l1_genesis(paths): @@ -307,9 +320,9 @@ def devnet_deploy(paths): 'go', 'run', 'cmd/main.go', 'genesis', 'l2', '--l1-rpc', 'http://localhost:8545', '--deploy-config', paths.devnet_config_path, - '--deployment-dir', paths.deployment_dir, - '--outfile.l2', pjoin(paths.devnet_dir, 'genesis-l2.json'), - '--outfile.rollup', pjoin(paths.devnet_dir, 'rollup.json') + '--l1-deployments', paths.addresses_json_path, + '--outfile.l2', paths.genesis_l2_path, + '--outfile.rollup', paths.rollup_config_path ], cwd=paths.op_node_dir) if os.path.exists(devnet_cfg_backup): @@ -319,6 +332,7 @@ def devnet_deploy(paths): rollup_config = read_json(paths.rollup_config_path) addresses = read_json(paths.addresses_json_path) + # Start the L2. log.info('Bringing up L2.') run_command(['docker', 'compose', 'up', '-d', 'l2'], cwd=paths.ops_bedrock_dir, env={ 'PWD': paths.ops_bedrock_dir @@ -337,31 +351,6 @@ def devnet_deploy(paths): log.info('Devnet ready.') - -def eth_accounts(url): - log.info(f'Fetch eth_accounts {url}') - conn = http.client.HTTPConnection(url) - headers = {'Content-type': 'application/json'} - body = '{"id":2, "jsonrpc":"2.0", "method": "eth_accounts", "params":[]}' - conn.request('POST', '/', body, headers) - response = conn.getresponse() - data = response.read().decode() - conn.close() - return data - - -def debug_dumpBlock(url): - log.info(f'Fetch debug_dumpBlock {url}') - conn = http.client.HTTPConnection(url) - headers = {'Content-type': 'application/json'} - body = '{"id":3, "jsonrpc":"2.0", "method": "debug_dumpBlock", "params":["latest"]}' - conn.request('POST', '/', body, headers) - response = conn.getresponse() - data = response.read().decode() - conn.close() - return data - - def wait_for_rpc_server(url): log.info(f'Waiting for RPC server at {url}') body = '{"id":1, "jsonrpc":"2.0", "method": "eth_chainId", "params":[]}' @@ -386,12 +375,6 @@ def wait_for_rpc_server(url): def devnet_test(paths): - # Check the L2 config - run_command( - ['go', 'run', 'cmd/check-l2/main.go', '--l2-rpc-url', 'http://localhost:9545', '--l1-rpc-url', 'http://localhost:8545'], - cwd=paths.ops_chain_ops, - ) - # Run the two commands with different signers, so the ethereum nonce management does not conflict # And do not use devnet system addresses, to avoid breaking fee-estimation or nonce values. run_commands([ diff --git a/cannon/cmd/json.go b/cannon/cmd/json.go deleted file mode 100644 index df7bae8a82d6..000000000000 --- a/cannon/cmd/json.go +++ /dev/null @@ -1,65 +0,0 @@ -package cmd - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "os" - "path" - - "github.com/ethereum-optimism/optimism/op-service/ioutil" -) - -func loadJSON[X any](inputPath string) (*X, error) { - if inputPath == "" { - return nil, errors.New("no path specified") - } - var f io.ReadCloser - f, err := ioutil.OpenDecompressed(inputPath) - if err != nil { - return nil, fmt.Errorf("failed to open file %q: %w", inputPath, err) - } - defer f.Close() - var state X - if err := json.NewDecoder(f).Decode(&state); err != nil { - return nil, fmt.Errorf("failed to decode file %q: %w", inputPath, err) - } - return &state, nil -} - -func writeJSON[X any](outputPath string, value X) error { - if outputPath == "" { - return nil - } - var out io.Writer - finish := func() error { return nil } - if outputPath != "-" { - // Write to a tmp file but reserve the file extension if present - tmpPath := outputPath + "-tmp" + path.Ext(outputPath) - f, err := ioutil.OpenCompressed(tmpPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755) - if err != nil { - return fmt.Errorf("failed to open output file: %w", err) - } - defer f.Close() - out = f - finish = func() error { - // Rename the file into place as atomically as the OS will allow - return os.Rename(tmpPath, outputPath) - } - } else { - out = os.Stdout - } - enc := json.NewEncoder(out) - if err := enc.Encode(value); err != nil { - return fmt.Errorf("failed to encode to JSON: %w", err) - } - _, err := out.Write([]byte{'\n'}) - if err != nil { - return fmt.Errorf("failed to append new-line: %w", err) - } - if err := finish(); err != nil { - return fmt.Errorf("failed to finish write: %w", err) - } - return nil -} diff --git a/cannon/cmd/load_elf.go b/cannon/cmd/load_elf.go index 5cfc3078e905..7c41fc3c0ef6 100644 --- a/cannon/cmd/load_elf.go +++ b/cannon/cmd/load_elf.go @@ -7,6 +7,7 @@ import ( "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) var ( @@ -66,10 +67,10 @@ func LoadELF(ctx *cli.Context) error { if err != nil { return fmt.Errorf("failed to compute program metadata: %w", err) } - if err := writeJSON[*mipsevm.Metadata](ctx.Path(LoadELFMetaFlag.Name), meta); err != nil { + if err := jsonutil.WriteJSON[*mipsevm.Metadata](ctx.Path(LoadELFMetaFlag.Name), meta, OutFilePerm); err != nil { return fmt.Errorf("failed to output metadata: %w", err) } - return writeJSON[*mipsevm.State](ctx.Path(LoadELFOutFlag.Name), state) + return jsonutil.WriteJSON[*mipsevm.State](ctx.Path(LoadELFOutFlag.Name), state, OutFilePerm) } var LoadELFCommand = &cli.Command{ diff --git a/cannon/cmd/log.go b/cannon/cmd/log.go index cc829bb2e71e..04e168b9ecfb 100644 --- a/cannon/cmd/log.go +++ b/cannon/cmd/log.go @@ -3,14 +3,11 @@ package cmd import ( "io" + "golang.org/x/exp/slog" + "github.com/ethereum/go-ethereum/log" ) -func Logger(w io.Writer, lvl log.Lvl) log.Logger { - h := log.StreamHandler(w, log.LogfmtFormat()) - h = log.SyncHandler(h) - h = log.LvlFilterHandler(lvl, h) - l := log.New() - l.SetHandler(h) - return l +func Logger(w io.Writer, lvl slog.Level) log.Logger { + return log.NewLogger(log.LogfmtHandlerWithLevel(w, lvl)) } diff --git a/cannon/cmd/matcher.go b/cannon/cmd/matcher.go index 2f0267c143b2..b569ef6df6bd 100644 --- a/cannon/cmd/matcher.go +++ b/cannon/cmd/matcher.go @@ -4,11 +4,13 @@ import ( "fmt" "strconv" "strings" - - "github.com/ethereum-optimism/optimism/cannon/mipsevm" ) -type StepMatcher func(st *mipsevm.State) bool +type VMState interface { + GetStep() uint64 +} + +type StepMatcher func(st VMState) bool type StepMatcherFlag struct { repr string @@ -26,11 +28,11 @@ func MustStepMatcherFlag(pattern string) *StepMatcherFlag { func (m *StepMatcherFlag) Set(value string) error { m.repr = value if value == "" || value == "never" { - m.matcher = func(st *mipsevm.State) bool { + m.matcher = func(st VMState) bool { return false } } else if value == "always" { - m.matcher = func(st *mipsevm.State) bool { + m.matcher = func(st VMState) bool { return true } } else if strings.HasPrefix(value, "=") { @@ -38,16 +40,16 @@ func (m *StepMatcherFlag) Set(value string) error { if err != nil { return fmt.Errorf("failed to parse step number: %w", err) } - m.matcher = func(st *mipsevm.State) bool { - return st.Step == when + m.matcher = func(st VMState) bool { + return st.GetStep() == when } } else if strings.HasPrefix(value, "%") { when, err := strconv.ParseUint(value[1:], 0, 64) if err != nil { return fmt.Errorf("failed to parse step interval number: %w", err) } - m.matcher = func(st *mipsevm.State) bool { - return st.Step%when == 0 + m.matcher = func(st VMState) bool { + return st.GetStep()%when == 0 } } else { return fmt.Errorf("unrecognized step matcher: %q", value) @@ -61,7 +63,7 @@ func (m *StepMatcherFlag) String() string { func (m *StepMatcherFlag) Matcher() StepMatcher { if m.matcher == nil { // Set(value) is not called for omitted inputs, default to never matching. - return func(st *mipsevm.State) bool { + return func(st VMState) bool { return false } } diff --git a/cannon/cmd/run.go b/cannon/cmd/run.go index 86234684fd4c..dd77eea1ac68 100644 --- a/cannon/cmd/run.go +++ b/cannon/cmd/run.go @@ -5,6 +5,9 @@ import ( "fmt" "os" "os/exec" + "slices" + "strconv" + "strings" "time" "github.com/ethereum/go-ethereum/common" @@ -16,6 +19,7 @@ import ( "github.com/ethereum-optimism/optimism/cannon/mipsevm" preimage "github.com/ethereum-optimism/optimism/op-preimage" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) var ( @@ -64,6 +68,21 @@ var ( Value: new(StepMatcherFlag), Required: false, } + RunStopAtPreimageFlag = &cli.StringFlag{ + Name: "stop-at-preimage", + Usage: "stop at the first preimage request matching this key", + Required: false, + } + RunStopAtPreimageTypeFlag = &cli.StringFlag{ + Name: "stop-at-preimage-type", + Usage: "stop at the first preimage request matching this type", + Required: false, + } + RunStopAtPreimageLargerThanFlag = &cli.StringFlag{ + Name: "stop-at-preimage-larger-than", + Usage: "stop at the first step that requests a preimage larger than the specified size (in bytes)", + Required: false, + } RunMetaFlag = &cli.PathFlag{ Name: "meta", Usage: "path to metadata file for symbol lookup for enhanced debugging info during execution.", @@ -80,6 +99,8 @@ var ( Name: "pprof.cpu", Usage: "enable pprof cpu profiling", } + + OutFilePerm = os.FileMode(0o755) ) type Proof struct { @@ -224,15 +245,54 @@ func Run(ctx *cli.Context) error { defer profile.Start(profile.NoShutdownHook, profile.ProfilePath("."), profile.CPUProfile).Stop() } - state, err := loadJSON[mipsevm.State](ctx.Path(RunInputFlag.Name)) + state, err := jsonutil.LoadJSON[mipsevm.State](ctx.Path(RunInputFlag.Name)) if err != nil { return err } - l := Logger(os.Stderr, log.LvlInfo) + l := Logger(os.Stderr, log.LevelInfo) outLog := &mipsevm.LoggingWriter{Name: "program std-out", Log: l} errLog := &mipsevm.LoggingWriter{Name: "program std-err", Log: l} + stopAtAnyPreimage := false + var stopAtPreimageKeyPrefix []byte + stopAtPreimageOffset := uint32(0) + if ctx.IsSet(RunStopAtPreimageFlag.Name) { + val := ctx.String(RunStopAtPreimageFlag.Name) + parts := strings.Split(val, "@") + if len(parts) > 2 { + return fmt.Errorf("invalid %v: %v", RunStopAtPreimageFlag.Name, val) + } + stopAtPreimageKeyPrefix = common.FromHex(parts[0]) + if len(parts) == 2 { + x, err := strconv.ParseUint(parts[1], 10, 32) + if err != nil { + return fmt.Errorf("invalid preimage offset: %w", err) + } + stopAtPreimageOffset = uint32(x) + } + } else { + switch ctx.String(RunStopAtPreimageTypeFlag.Name) { + case "local": + stopAtPreimageKeyPrefix = []byte{byte(preimage.LocalKeyType)} + case "keccak": + stopAtPreimageKeyPrefix = []byte{byte(preimage.Keccak256KeyType)} + case "sha256": + stopAtPreimageKeyPrefix = []byte{byte(preimage.Sha256KeyType)} + case "blob": + stopAtPreimageKeyPrefix = []byte{byte(preimage.BlobKeyType)} + case "precompile": + stopAtPreimageKeyPrefix = []byte{byte(preimage.PrecompileKeyType)} + case "any": + stopAtAnyPreimage = true + case "": + // 0 preimage type is forbidden so will not stop at any preimage + default: + return fmt.Errorf("invalid preimage type %q", ctx.String(RunStopAtPreimageTypeFlag.Name)) + } + } + stopAtPreimageLargerThan := ctx.Int(RunStopAtPreimageLargerThanFlag.Name) + // split CLI args after first '--' args := ctx.Args().Slice() for i, arg := range args { @@ -268,7 +328,7 @@ func Run(ctx *cli.Context) error { l.Info("no metadata file specified, defaulting to empty metadata") meta = &mipsevm.Metadata{Symbols: nil} // provide empty metadata by default } else { - if m, err := loadJSON[mipsevm.Metadata](metaPath); err != nil { + if m, err := jsonutil.LoadJSON[mipsevm.Metadata](metaPath); err != nil { return fmt.Errorf("failed to load metadata: %w", err) } else { meta = m @@ -317,11 +377,12 @@ func Run(ctx *cli.Context) error { } if stopAt(state) { + l.Info("Reached stop at") break } if snapshotAt(state) { - if err := writeJSON(fmt.Sprintf(snapshotFmt, step), state); err != nil { + if err := jsonutil.WriteJSON(fmt.Sprintf(snapshotFmt, step), state, OutFilePerm); err != nil { return fmt.Errorf("failed to write state snapshot: %w", err) } } @@ -351,7 +412,7 @@ func Run(ctx *cli.Context) error { proof.OracleValue = witness.PreimageValue proof.OracleOffset = witness.PreimageOffset } - if err := writeJSON(fmt.Sprintf(proofFmt, step), proof); err != nil { + if err := jsonutil.WriteJSON(fmt.Sprintf(proofFmt, step), proof, OutFilePerm); err != nil { return fmt.Errorf("failed to write proof data: %w", err) } } else { @@ -360,9 +421,29 @@ func Run(ctx *cli.Context) error { return fmt.Errorf("failed at step %d (PC: %08x): %w", step, state.PC, err) } } + + lastPreimageKey, lastPreimageValue, lastPreimageOffset := us.LastPreimage() + if lastPreimageOffset != ^uint32(0) { + if stopAtAnyPreimage { + l.Info("Stopping at preimage read") + break + } + if len(stopAtPreimageKeyPrefix) > 0 && + slices.Equal(lastPreimageKey[:len(stopAtPreimageKeyPrefix)], stopAtPreimageKeyPrefix) { + if stopAtPreimageOffset == lastPreimageOffset { + l.Info("Stopping at preimage read", "keyPrefix", common.Bytes2Hex(stopAtPreimageKeyPrefix), "offset", lastPreimageOffset) + break + } + } + if stopAtPreimageLargerThan != 0 && len(lastPreimageValue) > stopAtPreimageLargerThan { + l.Info("Stopping at preimage read", "size", len(lastPreimageValue), "min", stopAtPreimageLargerThan) + break + } + } } + l.Info("Execution stopped", "exited", state.Exited, "code", state.ExitCode) - if err := writeJSON(ctx.Path(RunOutputFlag.Name), state); err != nil { + if err := jsonutil.WriteJSON(ctx.Path(RunOutputFlag.Name), state, OutFilePerm); err != nil { return fmt.Errorf("failed to write state output: %w", err) } return nil @@ -381,6 +462,9 @@ var RunCommand = &cli.Command{ RunSnapshotAtFlag, RunSnapshotFmtFlag, RunStopAtFlag, + RunStopAtPreimageFlag, + RunStopAtPreimageTypeFlag, + RunStopAtPreimageLargerThanFlag, RunMetaFlag, RunInfoAtFlag, RunPProfCPU, diff --git a/cannon/cmd/witness.go b/cannon/cmd/witness.go index d92a27779180..c2f38daa3621 100644 --- a/cannon/cmd/witness.go +++ b/cannon/cmd/witness.go @@ -5,6 +5,7 @@ import ( "os" "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" "github.com/urfave/cli/v2" ) @@ -25,7 +26,7 @@ var ( func Witness(ctx *cli.Context) error { input := ctx.Path(WitnessInputFlag.Name) output := ctx.Path(WitnessOutputFlag.Name) - state, err := loadJSON[mipsevm.State](input) + state, err := jsonutil.LoadJSON[mipsevm.State](input) if err != nil { return fmt.Errorf("invalid input state (%v): %w", input, err) } diff --git a/cannon/docs/README.md b/cannon/docs/README.md index 006ccfaf51fe..90fbcd34dbd6 100644 --- a/cannon/docs/README.md +++ b/cannon/docs/README.md @@ -12,7 +12,7 @@ to reproduce the same instruction onchain as offchain. This is an onchain implementation of big-endian 32-bit MIPS instruction execution. This covers MIPS III, R3000, as required by the `mips` Go compiler/runtime target. -The systemcall instruction is implemented to simulate a minimal subset of the Linux kernel, +The syscall instruction is implemented to simulate a minimal subset of the Linux kernel, just enough to serve the needs of a basic Go program: allocate memory, read/write to certain file-descriptors, and exit. @@ -30,7 +30,7 @@ The difference is that it has access to the full memory, and pre-image oracle. And as it executes each step, it can optionally produce the witness data for the step, to repeat it onchain. The Cannon CLI is used to load a program into an initial state, -transition it N steps quickly without witness generation, and 1 step while producing a witness. +transition it to N steps quickly without witness generation, and 1 step while producing a witness. `mipsevm` is instrumented for proof generation and handles delay-slots by isolating each individual instruction and tracking `nextPC` to emulate the delayed `PC` changes after delay-slot execution. @@ -45,7 +45,7 @@ There are 3 types of witness data involved in onchain execution: ### Packed State The Packed State is provided in every executed onchain instruction. -See [Cannon VM Specs](../../specs/cannon-fault-proof-vm.md#state) for +See [Cannon VM Specs](https://github.com/ethereum-optimism/specs/blob/main/specs/experimental/fault-proof/cannon-fault-proof-vm.md#state) for details on the state structure. The packed state is small! The `State` data can be packed in such a small amount of EVM words, @@ -90,7 +90,7 @@ where the write is over the same memory as was last read. The memory access is specifically: - instruction (4 byte) read at `PC` - load or syscall mem read, always aligned 4 bytes, read at any `addr` -- store or syscall mem write, always aligned 4 bytes, at ths same `addr` +- store or syscall mem write, always aligned 4 bytes, at the same `addr` Writing only once, at the last read leaf, also means that the leaf can be safely updated and the same proof-data that was used to verify the read, can be used to reconstruct the new `memRoot` of the memory tree, @@ -99,10 +99,10 @@ since all sibling data that is combined with the new leaf value was already auth ### Pre-image data Pre-image data is accessed through syscalls exclusively. -The OP-stack fault-proof [Pre-image Oracle specs](../../specs/fault-proof.md#pre-image-oracle) +The OP-stack fault-proof [Pre-image Oracle specs](https://github.com/ethereum-optimism/specs/blob/main/specs/fault-proof.md#pre-image-oracle) define the ABI for communicating pre-images. -This ABI is implemented by the VM by intercepting the `read`/`write` syscalls to specific file descriptors. See [Cannon VM Specs](../../specs/cannon-fault-proof-vm.md#io) for more details. +This ABI is implemented by the VM by intercepting the `read`/`write` syscalls to specific file descriptors. See [Cannon VM Specs](https://github.com/ethereum-optimism/specs/blob/main/specs/cannon-fault-proof-vm.md#io) for more details. The data is loaded into `PreimageOracle.sol` using the respective loading function based on the pre-image type. And then retrieved during execution of the `read` syscall. diff --git a/cannon/example/claim/go.mod b/cannon/example/claim/go.mod index dcf894c5e5c0..8a286a3e4a05 100644 --- a/cannon/example/claim/go.mod +++ b/cannon/example/claim/go.mod @@ -7,8 +7,8 @@ toolchain go1.21.1 require github.com/ethereum-optimism/optimism v0.0.0 require ( - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/sys v0.18.0 // indirect ) replace github.com/ethereum-optimism/optimism v0.0.0 => ../../.. diff --git a/cannon/example/claim/go.sum b/cannon/example/claim/go.sum index 77ceb34ab78c..f5cfc4a02848 100644 --- a/cannon/example/claim/go.sum +++ b/cannon/example/claim/go.sum @@ -2,13 +2,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/cannon/mipsevm/evm.go b/cannon/mipsevm/evm.go index 7c6ddd8f5c48..27bd085b70a6 100644 --- a/cannon/mipsevm/evm.go +++ b/cannon/mipsevm/evm.go @@ -2,10 +2,8 @@ package mipsevm import ( "encoding/binary" - "encoding/json" "fmt" "math/big" - "os" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -19,71 +17,19 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-chain-ops/srcmap" ) -var ( - StepBytes4 []byte - LoadKeccak256PreimagePartBytes4 []byte - LoadLocalDataBytes4 []byte -) - -func init() { - mipsAbi, err := bindings.MIPSMetaData.GetAbi() - if err != nil { - panic(fmt.Errorf("failed to load MIPS ABI: %w", err)) - } - StepBytes4 = mipsAbi.Methods["step"].ID[:4] - - preimageAbi, err := bindings.PreimageOracleMetaData.GetAbi() - if err != nil { - panic(fmt.Errorf("failed to load pre-image oracle ABI: %w", err)) - } - LoadKeccak256PreimagePartBytes4 = preimageAbi.Methods["loadKeccak256PreimagePart"].ID[:4] - LoadLocalDataBytes4 = preimageAbi.Methods["loadLocalData"].ID[:4] -} - // LoadContracts loads the Cannon contracts, from op-bindings package func LoadContracts() (*Contracts, error) { var mips, oracle Contract mips.DeployedBytecode.Object = hexutil.MustDecode(bindings.MIPSDeployedBin) - mips.DeployedBytecode.SourceMap = bindings.MIPSDeployedSourceMap oracle.DeployedBytecode.Object = hexutil.MustDecode(bindings.PreimageOracleDeployedBin) - oracle.DeployedBytecode.SourceMap = bindings.PreimageOracleDeployedSourceMap return &Contracts{ MIPS: &mips, Oracle: &oracle, }, nil } -// LoadContractsFromFiles loads the Cannon contracts, from local filesystem -func LoadContractsFromFiles() (*Contracts, error) { - mips, err := LoadContract("MIPS") - if err != nil { - return nil, err - } - oracle, err := LoadContract("PreimageOracle") - if err != nil { - return nil, err - } - return &Contracts{ - MIPS: mips, - Oracle: oracle, - }, nil -} - -func LoadContract(name string) (*Contract, error) { - dat, err := os.ReadFile(fmt.Sprintf("../../packages/contracts-bedrock/forge-artifacts/%s.sol/%s.json", name, name)) - if err != nil { - return nil, fmt.Errorf("failed to read contract JSON definition of %q: %w", name, err) - } - var out Contract - if err := json.Unmarshal(dat, &out); err != nil { - return nil, fmt.Errorf("failed to parse contract JSON definition of %q: %w", name, err) - } - return &out, nil -} - type Contract struct { DeployedBytecode struct { Object hexutil.Bytes `json:"object"` @@ -93,10 +39,6 @@ type Contract struct { // ignore abi,bytecode,etc. } -func (c *Contract) SourceMap(sourcePaths []string) (*srcmap.SourceMap, error) { - return srcmap.ParseSourceMap(sourcePaths, c.DeployedBytecode.Object, c.DeployedBytecode.SourceMap) -} - type Contracts struct { MIPS *Contract Oracle *Contract @@ -110,9 +52,14 @@ type Addresses struct { } func NewEVMEnv(contracts *Contracts, addrs *Addresses) (*vm.EVM, *state.StateDB) { - chainCfg := params.MainnetChainConfig - offsetBlocks := uint64(1000) // blocks after shanghai fork - bc := &testChain{startTime: *chainCfg.ShanghaiTime + offsetBlocks*12} + // Temporary hack until Cancun is activated on mainnet + cpy := *params.MainnetChainConfig + chainCfg := &cpy // don't modify the global chain config + // Activate Cancun for EIP-4844 KZG point evaluation precompile + cancunActivation := *chainCfg.ShanghaiTime + 10 + chainCfg.CancunTime = &cancunActivation + offsetBlocks := uint64(1000) // blocks after cancun fork + bc := &testChain{startTime: *chainCfg.CancunTime + offsetBlocks*12} header := bc.GetHeader(common.Hash{}, 17034870+offsetBlocks) db := rawdb.NewMemoryDatabase() statedb := state.NewDatabase(db) diff --git a/cannon/mipsevm/evm_test.go b/cannon/mipsevm/evm_test.go index a6d1362026ba..274521edce1e 100644 --- a/cannon/mipsevm/evm_test.go +++ b/cannon/mipsevm/evm_test.go @@ -3,22 +3,23 @@ package mipsevm import ( "bytes" "debug/elf" + "errors" + "fmt" "io" "math/big" "os" "path" - "strings" "testing" "time" + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + preimage "github.com/ethereum-optimism/optimism/op-preimage" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/stretchr/testify/require" - - "github.com/ethereum-optimism/optimism/op-chain-ops/srcmap" ) func testContractsSetup(t require.TestingT) (*Contracts, *Addresses) { @@ -35,37 +36,30 @@ func testContractsSetup(t require.TestingT) (*Contracts, *Addresses) { return contracts, addrs } -func SourceMapTracer(t *testing.T, contracts *Contracts, addrs *Addresses) vm.EVMLogger { - t.Fatal("TODO(clabby): The source map tracer is disabled until source IDs have been added to foundry artifacts.") - - contractsDir := "../../packages/contracts-bedrock" - mipsSrcMap, err := contracts.MIPS.SourceMap([]string{path.Join(contractsDir, "src/cannon/MIPS.sol")}) - require.NoError(t, err) - oracleSrcMap, err := contracts.Oracle.SourceMap([]string{path.Join(contractsDir, "src/cannon/PreimageOracle.sol")}) - require.NoError(t, err) - - return srcmap.NewSourceMapTracer(map[common.Address]*srcmap.SourceMap{addrs.MIPS: mipsSrcMap, addrs.Oracle: oracleSrcMap}, os.Stdout) -} - func MarkdownTracer() vm.EVMLogger { return logger.NewMarkdownLogger(&logger.Config{}, os.Stdout) } type MIPSEVM struct { - env *vm.EVM - evmState *state.StateDB - addrs *Addresses + env *vm.EVM + evmState *state.StateDB + addrs *Addresses + localOracle PreimageOracle } func NewMIPSEVM(contracts *Contracts, addrs *Addresses) *MIPSEVM { env, evmState := NewEVMEnv(contracts, addrs) - return &MIPSEVM{env, evmState, addrs} + return &MIPSEVM{env, evmState, addrs, nil} } func (m *MIPSEVM) SetTracer(tracer vm.EVMLogger) { m.env.Config.Tracer = tracer } +func (m *MIPSEVM) SetLocalOracle(oracle PreimageOracle) { + m.localOracle = oracle +} + // Step is a pure function that computes the poststate from the VM state encoded in the StepWitness. func (m *MIPSEVM) Step(t *testing.T, stepWitness *StepWitness) []byte { sender := common.Address{0x13, 0x37} @@ -76,13 +70,13 @@ func (m *MIPSEVM) Step(t *testing.T, stepWitness *StepWitness) []byte { if stepWitness.HasPreimage() { t.Logf("reading preimage key %x at offset %d", stepWitness.PreimageKey, stepWitness.PreimageOffset) - poInput, err := stepWitness.EncodePreimageOracleInput(0) + poInput, err := encodePreimageOracleInput(t, stepWitness, LocalContext{}, m.localOracle) require.NoError(t, err, "encode preimage oracle input") _, leftOverGas, err := m.env.Call(vm.AccountRef(sender), m.addrs.Oracle, poInput, startingGas, big.NewInt(0)) require.NoErrorf(t, err, "evm should not fail, took %d gas", startingGas-leftOverGas) } - input := stepWitness.EncodeStepInput(0) + input := encodeStepInput(t, stepWitness, LocalContext{}) ret, leftOverGas, err := m.env.Call(vm.AccountRef(sender), m.addrs.MIPS, input, startingGas, big.NewInt(0)) require.NoError(t, err, "evm should not fail") require.Len(t, ret, 32, "expecting 32-byte state hash") @@ -101,25 +95,84 @@ func (m *MIPSEVM) Step(t *testing.T, stepWitness *StepWitness) []byte { return evmPost } +func encodeStepInput(t *testing.T, wit *StepWitness, localContext LocalContext) []byte { + mipsAbi, err := bindings.MIPSMetaData.GetAbi() + require.NoError(t, err) + + input, err := mipsAbi.Pack("step", wit.State, wit.MemProof, localContext) + require.NoError(t, err) + return input +} + +func encodePreimageOracleInput(t *testing.T, wit *StepWitness, localContext LocalContext, localOracle PreimageOracle) ([]byte, error) { + if wit.PreimageKey == ([32]byte{}) { + return nil, errors.New("cannot encode pre-image oracle input, witness has no pre-image to proof") + } + + preimageAbi, err := bindings.PreimageOracleMetaData.GetAbi() + require.NoError(t, err, "failed to load pre-image oracle ABI") + + switch preimage.KeyType(wit.PreimageKey[0]) { + case preimage.LocalKeyType: + if len(wit.PreimageValue) > 32+8 { + return nil, fmt.Errorf("local pre-image exceeds maximum size of 32 bytes with key 0x%x", wit.PreimageKey) + } + preimagePart := wit.PreimageValue[8:] + var tmp [32]byte + copy(tmp[:], preimagePart) + input, err := preimageAbi.Pack("loadLocalData", + new(big.Int).SetBytes(wit.PreimageKey[1:]), + localContext, + tmp, + new(big.Int).SetUint64(uint64(len(preimagePart))), + new(big.Int).SetUint64(uint64(wit.PreimageOffset)), + ) + require.NoError(t, err) + return input, nil + case preimage.Keccak256KeyType: + input, err := preimageAbi.Pack( + "loadKeccak256PreimagePart", + new(big.Int).SetUint64(uint64(wit.PreimageOffset)), + wit.PreimageValue[8:]) + require.NoError(t, err) + return input, nil + case preimage.PrecompileKeyType: + if localOracle == nil { + return nil, fmt.Errorf("local oracle is required for precompile preimages") + } + preimage := localOracle.GetPreimage(preimage.Keccak256Key(wit.PreimageKey).PreimageKey()) + precompile := common.BytesToAddress(preimage[:20]) + callInput := preimage[20:] + input, err := preimageAbi.Pack( + "loadPrecompilePreimagePart", + new(big.Int).SetUint64(uint64(wit.PreimageOffset)), + precompile, + callInput, + ) + require.NoError(t, err) + return input, nil + default: + return nil, fmt.Errorf("unsupported pre-image type %d, cannot prepare preimage with key %x offset %d for oracle", + wit.PreimageKey[0], wit.PreimageKey, wit.PreimageOffset) + } +} + func TestEVM(t *testing.T) { testFiles, err := os.ReadDir("open_mips_tests/test/bin") require.NoError(t, err) contracts, addrs := testContractsSetup(t) - var tracer vm.EVMLogger // no-tracer by default, but see SourceMapTracer and MarkdownTracer - //tracer = SourceMapTracer(t, contracts, addrs) + var tracer vm.EVMLogger // no-tracer by default, but MarkdownTracer for _, f := range testFiles { t.Run(f.Name(), func(t *testing.T) { - var oracle PreimageOracle - if strings.HasPrefix(f.Name(), "oracle") { - oracle = staticOracle(t, []byte("hello world")) - } + oracle := selectOracleFixture(t, f.Name()) // Short-circuit early for exit_group.bin exitGroup := f.Name() == "exit_group.bin" evm := NewMIPSEVM(contracts, addrs) evm.SetTracer(tracer) + evm.SetLocalOracle(oracle) fn := path.Join("open_mips_tests/test/bin", f.Name()) programMem, err := os.ReadFile(fn) @@ -149,8 +202,8 @@ func TestEVM(t *testing.T) { // verify the post-state matches. // TODO: maybe more readable to decode the evmPost state, and do attribute-wise comparison. goPost := goState.state.EncodeWitness() - require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), - "mipsevm produced different state than EVM") + require.Equalf(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), + "mipsevm produced different state than EVM at step %d", state.Step) } if exitGroup { require.NotEqual(t, uint32(endAddr), goState.state.PC, "must not reach end") @@ -170,15 +223,13 @@ func TestEVM(t *testing.T) { func TestEVMSingleStep(t *testing.T) { contracts, addrs := testContractsSetup(t) var tracer vm.EVMLogger - //tracer = SourceMapTracer(t, contracts, addrs) - type testInput struct { + cases := []struct { name string pc uint32 nextPC uint32 insn uint32 - } - cases := []testInput{ + }{ {"j MSB set target", 0, 4, 0x0A_00_00_02}, // j 0x02_00_00_02 {"j non-zero PC region", 0x10000000, 0x10000004, 0x08_00_00_02}, // j 0x2 {"jal MSB set target", 0, 4, 0x0E_00_00_02}, // jal 0x02_00_00_02 @@ -206,19 +257,17 @@ func TestEVMSingleStep(t *testing.T) { func TestEVMFault(t *testing.T) { contracts, addrs := testContractsSetup(t) - var tracer vm.EVMLogger // no-tracer by default, but see SourceMapTracer and MarkdownTracer - //tracer = SourceMapTracer(t, contracts, addrs) + var tracer vm.EVMLogger // no-tracer by default, but see MarkdownTracer sender := common.Address{0x13, 0x37} env, evmState := NewEVMEnv(contracts, addrs) env.Config.Tracer = tracer - type testInput struct { + cases := []struct { name string nextPC uint32 insn uint32 - } - cases := []testInput{ + }{ {"illegal instruction", 0, 0xFF_FF_FF_FF}, {"branch in delay-slot", 8, 0x11_02_00_03}, {"jump in delay-slot", 8, 0x0c_00_00_0c}, @@ -241,7 +290,7 @@ func TestEVMFault(t *testing.T) { State: initialState.EncodeWitness(), MemProof: insnProof[:], } - input := stepWitness.EncodeStepInput(0) + input := encodeStepInput(t, stepWitness, LocalContext{}) startingGas := uint64(30_000_000) _, _, err := env.Call(vm.AccountRef(sender), addrs.MIPS, input, startingGas, big.NewInt(0)) @@ -254,8 +303,7 @@ func TestEVMFault(t *testing.T) { func TestHelloEVM(t *testing.T) { contracts, addrs := testContractsSetup(t) - var tracer vm.EVMLogger // no-tracer by default, but see SourceMapTracer and MarkdownTracer - //tracer = SourceMapTracer(t, contracts, addrs) + var tracer vm.EVMLogger // no-tracer by default, but see MarkdownTracer elfProgram, err := elf.Open("../example/bin/hello.elf") require.NoError(t, err, "open ELF file") @@ -305,8 +353,7 @@ func TestHelloEVM(t *testing.T) { func TestClaimEVM(t *testing.T) { contracts, addrs := testContractsSetup(t) - var tracer vm.EVMLogger // no-tracer by default, but see SourceMapTracer and MarkdownTracer - //tracer = SourceMapTracer(t, contracts, addrs) + var tracer vm.EVMLogger // no-tracer by default, but see MarkdownTracer elfProgram, err := elf.Open("../example/bin/claim.elf") require.NoError(t, err, "open ELF file") diff --git a/cannon/mipsevm/fuzz_evm_test.go b/cannon/mipsevm/fuzz_evm_test.go index 60be06b29658..404d4e028af0 100644 --- a/cannon/mipsevm/fuzz_evm_test.go +++ b/cannon/mipsevm/fuzz_evm_test.go @@ -322,6 +322,7 @@ func FuzzStateHintRead(f *testing.F) { require.Equal(t, preStateRoot, state.Memory.MerkleRoot()) require.Equal(t, uint64(1), state.Step) require.Equal(t, preStatePreimageKey, state.PreimageKey) + require.Equal(t, expectedRegisters, state.Registers) evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) @@ -439,6 +440,7 @@ func FuzzStateHintWrite(f *testing.F) { require.Equal(t, preStateRoot, state.Memory.MerkleRoot()) require.Equal(t, uint64(1), state.Step) require.Equal(t, preStatePreimageKey, state.PreimageKey) + require.Equal(t, expectedRegisters, state.Registers) evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) @@ -471,9 +473,9 @@ func FuzzStatePreimageWrite(f *testing.F) { expectedRegisters := state.Registers sz := 4 - (addr & 0x3) if sz < count { - sz = count + count = sz } - expectedRegisters[2] = sz + expectedRegisters[2] = count oracle := staticOracle(t, preimageData) goState := NewInstrumentedState(state, oracle, os.Stdout, os.Stderr) @@ -491,6 +493,7 @@ func FuzzStatePreimageWrite(f *testing.F) { require.Equal(t, preStateRoot, state.Memory.MerkleRoot()) require.Equal(t, uint64(1), state.Step) require.Equal(t, uint32(0), state.PreimageOffset) + require.Equal(t, expectedRegisters, state.Registers) evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) diff --git a/cannon/mipsevm/instrumented.go b/cannon/mipsevm/instrumented.go index 4e090b8014e1..fc276effd89f 100644 --- a/cannon/mipsevm/instrumented.go +++ b/cannon/mipsevm/instrumented.go @@ -80,3 +80,7 @@ func (m *InstrumentedState) Step(proof bool) (wit *StepWitness, err error) { } return } + +func (m *InstrumentedState) LastPreimage() ([32]byte, []byte, uint32) { + return m.lastPreimageKey, m.lastPreimage, m.lastPreimageOffset +} diff --git a/cannon/mipsevm/open_mips_tests/test/bin/oracle.bin b/cannon/mipsevm/open_mips_tests/test/bin/oracle.bin index a506c1736ac7..f2c5a4c2c7a7 100644 Binary files a/cannon/mipsevm/open_mips_tests/test/bin/oracle.bin and b/cannon/mipsevm/open_mips_tests/test/bin/oracle.bin differ diff --git a/cannon/mipsevm/open_mips_tests/test/bin/oracle_kzg.bin b/cannon/mipsevm/open_mips_tests/test/bin/oracle_kzg.bin new file mode 100644 index 000000000000..20a642fa430c Binary files /dev/null and b/cannon/mipsevm/open_mips_tests/test/bin/oracle_kzg.bin differ diff --git a/cannon/mipsevm/open_mips_tests/test/oracle.asm b/cannon/mipsevm/open_mips_tests/test/oracle.asm index c306f6d17664..a8c73b2c3e16 100644 --- a/cannon/mipsevm/open_mips_tests/test/oracle.asm +++ b/cannon/mipsevm/open_mips_tests/test/oracle.asm @@ -69,10 +69,6 @@ $readloop: addiu $t0, $t0, -1 bnez $t0, $readloop nop -# reading the pre-image stream at EOF should have no effect - li $a1, 0x31000008 - li $v0, 4003 - syscall # length at 0x31000000. We also check that the lower 32 bits are zero lui $s1, 0x3100 diff --git a/cannon/mipsevm/open_mips_tests/test/oracle_kzg.asm b/cannon/mipsevm/open_mips_tests/test/oracle_kzg.asm new file mode 100644 index 000000000000..8faf349bf3ab --- /dev/null +++ b/cannon/mipsevm/open_mips_tests/test/oracle_kzg.asm @@ -0,0 +1,102 @@ +.section .test, "x" + .balign 4 + .set noreorder + .global test + .ent test + +# load hash at 0x30001000 +# point evaluation precompile input - 01e798154708fe7789429634053cbf9f99b619f9f084048927333fce637f549b564c0a11a0f704f4fc3e8acfe0f8245f0ad1347b378fbf96e206da11a5d3630624d25032e67a7e6a4910df5834b8fe70e6bcfeeac0352434196bdf4b2485d5a18f59a8d2a1a625a17f3fea0fe5eb8c896db3764f3185481bc22f91b4aaffcca25f26936857bc3a7c2539ea8ec3a952b7873033e038326e87ed3e1276fd140253fa08e9fc25fb2d9a98527fc22a2c9612fbeafdad446cbc7bcdbdcd780af2c16a +# 0x0a44472c cb798bc5 954fc466 e6ee2c31 e1ca8a87 d000966c 629d679a 4a29921f = keccak(address(0xa) ++ precompile_input) +# 0x0644472c cb798bc5 954fc466 e6ee2c31 e1ca8a87 d000966c 629d679a 4a29921f = keccak(address(0xa) ++ precompile_input).key (precompile) +test: + lui $s0, 0x3000 + ori $s0, 0x1000 + + lui $t0, 0x0644 + ori $t0, 0x472c + sw $t0, 0($s0) + lui $t0, 0xcb79 + ori $t0, 0x8bc5 + sw $t0, 4($s0) + lui $t0, 0x954f + ori $t0, 0xc466 + sw $t0, 8($s0) + lui $t0, 0xe6ee + ori $t0, 0x2c31 + sw $t0, 0xc($s0) + lui $t0, 0xe1ca + ori $t0, 0x8a87 + sw $t0, 0x10($s0) + lui $t0, 0xd000 + ori $t0, 0x966c + sw $t0, 0x14($s0) + lui $t0, 0x629d + ori $t0, 0x679a + sw $t0, 0x18($s0) + lui $t0, 0x4a29 + ori $t0, 0x921f + sw $t0, 0x1c($s0) + +# preimage request - write(fdPreimageWrite, preimageData, 32) + li $a0, 6 + li $a1, 0x30001000 + li $t0, 8 + li $a2, 4 +$writeloop: + li $v0, 4004 + syscall + addiu $a1, $a1, 4 + addiu $t0, $t0, -1 + bnez $t0, $writeloop + nop + +# preimage response to 0x30002000 - read(fdPreimageRead, addr, count) +# read preimage length + li $a0, 5 + li $a1, 0x31000000 + li $a2, 4 + li $v0, 4003 + syscall + li $a1, 0x31000004 + li $v0, 4003 + syscall +# read the 1 byte precompile status and 3 bytes of return data + li $a1, 0x31000008 + li $v0, 4003 + syscall + nop + +# length at 0x31000000. We also check that the lower 32 bits are zero + lui $s1, 0x3100 + lw $t0, 0($s1) + sltiu $t6, $t0, 1 + li $s1, 0x31000004 + lw $t0, 0($s1) +# should be 1 + len(blobPrecompileReturnValue) = 65 + li $t4, 65 + subu $t5, $t0, $t4 + sltiu $v0, $t5, 1 + and $v0, $v0, $t6 + +# data at 0x31000008 +# first byte is 01 status. Next 3 bytes are 0 + lw $t0, 4($s1) + lui $t4, 0x0100 + ori $t4, 0x0000 + subu $t5, $t0, $t4 + sltiu $v1, $t5, 1 + and $v0, $v0, $v1 + +# save results + lui $s0, 0xbfff # Load the base address 0xbffffff0 + ori $s0, 0xfff0 + ori $s1, $0, 1 # Prepare the 'done' status + + sw $v0, 8($s0) # Set the test result + sw $s1, 4($s0) # Set 'done' + +$done: + jr $ra + nop + + .end test diff --git a/cannon/mipsevm/state.go b/cannon/mipsevm/state.go index f6f68914376e..fea495218a58 100644 --- a/cannon/mipsevm/state.go +++ b/cannon/mipsevm/state.go @@ -42,6 +42,8 @@ type State struct { LastHint hexutil.Bytes `json:"lastHint,omitempty"` } +func (s *State) GetStep() uint64 { return s.Step } + func (s *State) VMStatus() uint8 { return vmStatus(s.Exited, s.ExitCode) } @@ -81,7 +83,7 @@ const ( func (sw StateWitness) StateHash() (common.Hash, error) { if len(sw) != 226 { - return common.Hash{}, fmt.Errorf("Invalid witness length. Got %d, expected at least 88", len(sw)) + return common.Hash{}, fmt.Errorf("Invalid witness length. Got %d, expected 226", len(sw)) } hash := crypto.Keccak256Hash(sw) diff --git a/cannon/mipsevm/state_test.go b/cannon/mipsevm/state_test.go index 2e866cde574a..b430398c389b 100644 --- a/cannon/mipsevm/state_test.go +++ b/cannon/mipsevm/state_test.go @@ -31,10 +31,7 @@ func TestState(t *testing.T) { for _, f := range testFiles { t.Run(f.Name(), func(t *testing.T) { - var oracle PreimageOracle - if strings.HasPrefix(f.Name(), "oracle") { - oracle = staticOracle(t, []byte("hello world")) - } + oracle := selectOracleFixture(t, f.Name()) // Short-circuit early for exit_group.bin exitGroup := f.Name() == "exit_group.bin" @@ -269,3 +266,38 @@ func staticOracle(t *testing.T, preimageData []byte) *testOracle { }, } } + +func staticPrecompileOracle(t *testing.T, precompile common.Address, input []byte, result []byte) *testOracle { + return &testOracle{ + hint: func(v []byte) {}, + getPreimage: func(k [32]byte) []byte { + keyData := append(precompile.Bytes(), input...) + switch k[0] { + case byte(preimage.Keccak256KeyType): + if k != preimage.Keccak256Key(crypto.Keccak256Hash(keyData)).PreimageKey() { + t.Fatalf("invalid preimage request for %x", k) + } + return keyData + case byte(preimage.PrecompileKeyType): + if k != preimage.PrecompileKey(crypto.Keccak256Hash(keyData)).PreimageKey() { + t.Fatalf("invalid preimage request for %x", k) + } + return result + } + panic("unreachable") + }, + } +} + +func selectOracleFixture(t *testing.T, programName string) PreimageOracle { + if strings.HasPrefix(programName, "oracle_kzg") { + precompile := common.BytesToAddress([]byte{0xa}) + input := common.FromHex("01e798154708fe7789429634053cbf9f99b619f9f084048927333fce637f549b564c0a11a0f704f4fc3e8acfe0f8245f0ad1347b378fbf96e206da11a5d3630624d25032e67a7e6a4910df5834b8fe70e6bcfeeac0352434196bdf4b2485d5a18f59a8d2a1a625a17f3fea0fe5eb8c896db3764f3185481bc22f91b4aaffcca25f26936857bc3a7c2539ea8ec3a952b7873033e038326e87ed3e1276fd140253fa08e9fc25fb2d9a98527fc22a2c9612fbeafdad446cbc7bcdbdcd780af2c16a") + blobPrecompileReturnValue := common.FromHex("000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001") + return staticPrecompileOracle(t, precompile, input, append([]byte{0x1}, blobPrecompileReturnValue...)) + } else if strings.HasPrefix(programName, "oracle") { + return staticOracle(t, []byte("hello world")) + } else { + return nil + } +} diff --git a/cannon/mipsevm/witness.go b/cannon/mipsevm/witness.go index 7a4b8087b297..58039a86ea32 100644 --- a/cannon/mipsevm/witness.go +++ b/cannon/mipsevm/witness.go @@ -1,14 +1,8 @@ package mipsevm -import ( - "encoding/binary" - "errors" - "fmt" +import "github.com/ethereum/go-ethereum/common" - preimage "github.com/ethereum-optimism/optimism/op-preimage" -) - -type LocalContext uint64 +type LocalContext common.Hash type StepWitness struct { // encoded state witness @@ -21,78 +15,6 @@ type StepWitness struct { PreimageOffset uint32 } -func uint32ToBytes32(v uint32) []byte { - var out [32]byte - binary.BigEndian.PutUint32(out[32-4:], v) - return out[:] -} - -func uint64ToBytes32(v uint64) []byte { - var out [32]byte - binary.BigEndian.PutUint64(out[32-8:], v) - return out[:] -} - -func (wit *StepWitness) EncodeStepInput(localContext LocalContext) []byte { - abiStateLen := len(wit.State) - if abiStateLen%32 != 0 { - abiStateLen += 32 - (abiStateLen % 32) - } - // pad state to 32 byte multiple per ABI - abiState := make([]byte, abiStateLen) - copy(abiState, wit.State) - - var input []byte - input = append(input, StepBytes4...) - input = append(input, uint32ToBytes32(32*3)...) // state data offset in bytes - input = append(input, uint32ToBytes32(32*3+32+uint32(len(abiState)))...) // proof data offset in bytes - input = append(input, uint64ToBytes32(uint64(localContext))...) // local context in bytes - - input = append(input, uint32ToBytes32(uint32(len(wit.State)))...) // state data length in bytes - input = append(input, abiState[:]...) - input = append(input, uint32ToBytes32(uint32(len(wit.MemProof)))...) // proof data length in bytes - input = append(input, wit.MemProof[:]...) - return input -} - func (wit *StepWitness) HasPreimage() bool { return wit.PreimageKey != ([32]byte{}) } - -func (wit *StepWitness) EncodePreimageOracleInput(localContext LocalContext) ([]byte, error) { - if wit.PreimageKey == ([32]byte{}) { - return nil, errors.New("cannot encode pre-image oracle input, witness has no pre-image to proof") - } - - switch preimage.KeyType(wit.PreimageKey[0]) { - case preimage.LocalKeyType: - if len(wit.PreimageValue) > 32+8 { - return nil, fmt.Errorf("local pre-image exceeds maximum size of 32 bytes with key 0x%x", wit.PreimageKey) - } - var input []byte - input = append(input, LoadLocalDataBytes4...) - input = append(input, wit.PreimageKey[:]...) - input = append(input, uint64ToBytes32(uint64(localContext))...) // local context in bytes - - preimagePart := wit.PreimageValue[8:] - var tmp [32]byte - copy(tmp[:], preimagePart) - input = append(input, tmp[:]...) - input = append(input, uint32ToBytes32(uint32(len(wit.PreimageValue)-8))...) - input = append(input, uint32ToBytes32(wit.PreimageOffset)...) - // Note: we can pad calldata to 32 byte multiple, but don't strictly have to - return input, nil - case preimage.Keccak256KeyType: - var input []byte - input = append(input, LoadKeccak256PreimagePartBytes4...) - input = append(input, uint32ToBytes32(wit.PreimageOffset)...) - input = append(input, uint32ToBytes32(32+32)...) // partOffset, calldata offset - input = append(input, uint32ToBytes32(uint32(len(wit.PreimageValue))-8)...) - input = append(input, wit.PreimageValue[8:]...) - // Note: we can pad calldata to 32 byte multiple, but don't strictly have to - return input, nil - default: - return nil, fmt.Errorf("unsupported pre-image type %d, cannot prepare preimage with key %x offset %d for oracle", - wit.PreimageKey[0], wit.PreimageKey, wit.PreimageOffset) - } -} diff --git a/codecov.yml b/codecov.yml index 6edb2f3e455c..52aa7ea38a88 100644 --- a/codecov.yml +++ b/codecov.yml @@ -12,6 +12,7 @@ ignore: - "op-bindings/bindings/*.go" - "**/*.t.sol" - "packages/contracts-bedrock/test/**/*.sol" + - "packages/contracts-bedrock/scripts/**/*.sol" - "packages/contracts-bedrock/contracts/vendor/WETH9.sol" - 'packages/contracts-bedrock/contracts/EAS/**/*.sol' coverage: @@ -32,7 +33,7 @@ flag_management: individual_flags: - name: contracts-bedrock-tests paths: - - packages/contracts-bedrock + - packages/contracts-bedrock/src statuses: - type: patch target: 100% diff --git a/docker-bake.hcl b/docker-bake.hcl index d808f751b273..027f2adff683 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -93,6 +93,32 @@ target "op-challenger" { tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-challenger:${tag}"] } +target "op-dispute-mon" { + dockerfile = "Dockerfile" + context = "./op-dispute-mon" + args = { + OP_STACK_GO_BUILDER = "op-stack-go" + } + contexts = { + op-stack-go: "target:op-stack-go" + } + platforms = split(",", PLATFORMS) + tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-dispute-mon:${tag}"] +} + +target "op-conductor" { + dockerfile = "Dockerfile" + context = "./op-conductor" + args = { + OP_STACK_GO_BUILDER = "op-stack-go" + } + contexts = { + op-stack-go: "target:op-stack-go" + } + platforms = split(",", PLATFORMS) + tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-conductor:${tag}"] +} + target "op-heartbeat" { dockerfile = "Dockerfile" context = "./op-heartbeat" @@ -119,9 +145,22 @@ target "op-program" { tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-program:${tag}"] } +target "op-ufm" { + dockerfile = "./op-ufm/Dockerfile" + context = "./" + args = { + // op-ufm dockerfile has no _ in the args + GITCOMMIT = "${GIT_COMMIT}" + GITDATE = "${GIT_DATE}" + GITVERSION = "${GIT_VERSION}" + } + platforms = split(",", PLATFORMS) + tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-ufm:${tag}"] +} + target "proxyd" { - dockerfile = "Dockerfile" - context = "./proxyd" + dockerfile = "./proxyd/Dockerfile" + context = "./" args = { // proxyd dockerfile has no _ in the args GITCOMMIT = "${GIT_COMMIT}" @@ -177,7 +216,22 @@ target "ci-builder" { dockerfile = "./ops/docker/ci-builder/Dockerfile" context = "." platforms = split(",", PLATFORMS) + target="base-builder" tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/ci-builder:${tag}"] } +target "ci-builder-rust" { + dockerfile = "./ops/docker/ci-builder/Dockerfile" + context = "." + platforms = split(",", PLATFORMS) + target="rust-builder" + tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/ci-builder-rust:${tag}"] +} +target "contracts-bedrock" { + dockerfile = "./ops/docker/Dockerfile.packages" + context = "." + target = "contracts-bedrock" + platforms = split(",", PLATFORMS) + tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/contracts-bedrock:${tag}"] +} diff --git a/docs/fault-proof-alpha/README.md b/docs/fault-proof-alpha/README.md index e0c099134562..f46e51ba7dd2 100644 --- a/docs/fault-proof-alpha/README.md +++ b/docs/fault-proof-alpha/README.md @@ -11,7 +11,7 @@ finalized and may change without notice. * [Architecture Overview Video](https://www.youtube.com/watch?v=nIN5sNc6nQM) * [Fault Proof Alpha Deployment Information (Goerli)](./deployments.md) -* [Security Reseachers - Bug Bounty Program](./immunefi.md) +* [Security Researchers - Bug Bounty Program](./immunefi.md) ### Contents diff --git a/docs/fault-proof-alpha/manual.md b/docs/fault-proof-alpha/manual.md index 2ab48246281c..36580defa0d6 100644 --- a/docs/fault-proof-alpha/manual.md +++ b/docs/fault-proof-alpha/manual.md @@ -63,7 +63,7 @@ acts as an example of using `cast` to manually call `attack` and `defend`. ### Performing Steps -Attacking or defending are teh only available actions before the maximum depth of the game is reached. To counter claims +Attacking or defending are the only available actions before the maximum depth of the game is reached. To counter claims at the maximum depth, a step must be performed instead. Calling the `step` method in the `FaultDisputeGame` contract counters a claim at the maximum depth by running a single step of the cannon VM on chain. The `step` method will revert unless the cannon execution confirms the claim being countered is invalid. Note, if an actor's clock runs out at any diff --git a/docs/fault-proof-alpha/run-challenger.md b/docs/fault-proof-alpha/run-challenger.md index c7ed6af0ad8b..93017acac84c 100644 --- a/docs/fault-proof-alpha/run-challenger.md +++ b/docs/fault-proof-alpha/run-challenger.md @@ -18,7 +18,7 @@ ### Starting op-challenger -When executing `op-challenger`, there are a few placeholders that need to be set to concreate values: +When executing `op-challenger`, there are a few placeholders that need to be set to concrete values: - `` the Goerli L1 JSON RPC endpoint - `` the address of the dispute game factory contract (see @@ -29,7 +29,7 @@ When executing `op-challenger`, there are a few placeholders that need to be set - `` the private key for a funded Goerli account. For other ways to specify the account to use see `./op-challenger/bin/op-challenger --help` -From inside the monorepo directory, run the challenger with these placeholders set. +From inside the monorepo directory, run the challenger after setting these placeholders. ```bash # Build the required components @@ -40,7 +40,6 @@ make op-challenger op-program cannon --trace-type cannon \ --l1-eth-rpc \ --game-factory-address \ - --agree-with-proposed-output=true \ --datadir temp/challenger-goerli \ --cannon-network goerli \ --cannon-bin ./cannon/bin/cannon \ diff --git a/docs/handbook/pr-guidelines.md b/docs/handbook/pr-guidelines.md new file mode 100644 index 000000000000..cf133ada6c57 --- /dev/null +++ b/docs/handbook/pr-guidelines.md @@ -0,0 +1,49 @@ +# Pull Request Guidelines and Best Practices + + + + +- [Overview](#overview) +- [PR Lifecycle Best Practices](#pr-lifecycle-best-practices) + - [Before Starting PRs](#before-starting-prs) + - [Opening PRs](#opening-prs) + - [Reviewing PRs](#reviewing-prs) + - [Merging PRs](#merging-prs) + + + +## Overview + +This document contains guidelines and best practices in PRs that should be enforced as much as possible. The motivations and goals behind these best practices are: + +- **Ensure thorough reviews**: By the time the PR is merged, at least one other person—because there is always at least one reviewer—should understand the PR’s changes just as well as the PR author. This helps improve security by reducing bugs and single points of failure (i.e. there should never be only one person who understands certain code). +- **Reduce PR churn**: PRs should be quickly reviewable and mergeable without much churn (both in terms of code rewrites and comment cycles). This saves time by reducing the need for rebases due to conflicts. Similarly, too many review cycles are a burden for both PR authors and reviewers, and results in “review fatigue” where reviews become less careful and thorough, increasing the likelihood of bugs. +- **Traceability**: We should be able to look back at issues and PRs to understand why a certain decision was made or why a given approach was taken. + +## PR Lifecycle Best Practices + +This is organized by current state of PR, so it can be easily referenced frequently to help internalize the guidelines. + +### Before Starting PRs + +- **Keep PRs Focused**: Each PR should be a single, narrow, well-defined scope. + +### Opening PRs + +- **Review Your Own Code**: Reviewing the diff yourself *in a different context*, can be very useful for discovering issues, typos, and bugs before opening the PR. For example, write code in your IDE, then review it in the GitHub diff view. The perspective change forces you to slow down and helps reveal issues you may have missed. +- **Explain Decisions/Tradeoffs**: Explain rationale for any design/architecture decisions and implementation details in the PR description. If it closes an issue, remember to mention the issue it closes, e.g. `Closes `. Otherwise, just link to the issue. If there is no issue, whatever details would have been in the issue should be in the PR description. +- **Guide PR reviewers:** Let them know about areas of concern, under-tested areas, or vague requirements that should be ironed out. + +### Reviewing PRs + +- **Verify Requirements are Met**: If the PR claims to fix or close an issue, check that all the requirements in the issue are actually met. Otherwise the issue may be in a good place to merge, but just shouldn’t close the issue. +- **Focus on Tests**: The tests are the spec and therefore should be the focus of reviews. If tests are thorough and passing, the rest is an implementation detail (to an extent—don’t skip source code reviews) that can be fixed in a future optimization/cleanup PR. Make sure edge case behaviors are defined and handled. +- **Think like an Auditor:** What edge cases were ignored? How can the code break? When might it behave incorrectly and unexpectedly? What code should have been changed that isn’t in the diff? What implicit assumptions are made that might be invalid? +- **Ensure Comment Significance is Clear**: Indicate which comments are nits/optionals that the PR author can resolve, compared to which you want to follow up on. + - Prefix non-blocking comments with `[nit]` or `[non-blocking]`. +- **Consider Reviewing in Your IDE**: For example, GitHub has [this VSCode extension](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github) to review PRs. This provides more code context and enables review to benefit from your standard lints and IDE features, whereas GitHub’s diff shows none of that. + +### Merging PRs + +- **Resolve all Comments**: Comments can be resolved by (1) the PR author for nits/optionals, (2) the author or reviewer after discussions, or (3) extracting the comment into an issue to address in a future PR. For (3), ensure the new issue links to the specific comment thread. This is currently enforced by GitHub's merge requirements. +- **Other Standard Merge Requirements**: The PR must be approved by the appropriate reviewers, CI must passing, and other standard merge requirements apply. diff --git a/docs/security-reviews/2023_12_Trust_SuperchainConfigUpgrade.pdf b/docs/security-reviews/2023_12_Trust_SuperchainConfigUpgrade.pdf new file mode 100644 index 000000000000..b03c4491621f Binary files /dev/null and b/docs/security-reviews/2023_12_Trust_SuperchainConfigUpgrade.pdf differ diff --git a/docs/security-reviews/2024_02-MCP_L1-Cantina.pdf b/docs/security-reviews/2024_02-MCP_L1-Cantina.pdf new file mode 100644 index 000000000000..69f4891dd7ff Binary files /dev/null and b/docs/security-reviews/2024_02-MCP_L1-Cantina.pdf differ diff --git a/endpoint-monitor/endpoint_monitor.go b/endpoint-monitor/endpoint_monitor.go index 675a287a31f4..b08b8c199e59 100644 --- a/endpoint-monitor/endpoint_monitor.go +++ b/endpoint-monitor/endpoint_monitor.go @@ -36,7 +36,7 @@ func Main(version string) func(cliCtx *cli.Context) error { } l := oplog.NewLogger(oplog.AppOut(cliCtx), cfg.LogConfig) - oplog.SetGlobalLogHandler(l.GetHandler()) + oplog.SetGlobalLogHandler(l.Handler()) endpointMonitor := NewEndpointMonitor(cfg, l) l.Info(fmt.Sprintf("starting endpoint monitor with checkInterval=%s checkDuration=%s", cfg.CheckInterval, cfg.CheckDuration)) diff --git a/go.mod b/go.mod index 2e204e656d3a..441e778fba91 100644 --- a/go.mod +++ b/go.mod @@ -4,88 +4,92 @@ go 1.21 require ( github.com/BurntSushi/toml v1.3.2 - github.com/aws/aws-sdk-go-v2 v1.24.0 + github.com/aws/aws-sdk-go-v2 v1.26.1 github.com/aws/aws-sdk-go-v2/config v1.18.45 - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.25.4 - github.com/btcsuite/btcd v0.23.3 - github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.6 + github.com/btcsuite/btcd v0.24.0 + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 + github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4 + github.com/consensys/gnark-crypto v0.12.1 + github.com/crate-crypto/go-kzg-4844 v0.7.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 - github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492 - github.com/ethereum/go-ethereum v1.13.5-0.20231027145059-2d7dba024d76 + github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240306093353-c557df8e6f41 + github.com/ethereum/go-ethereum v1.13.8 github.com/fsnotify/fsnotify v1.7.0 - github.com/go-chi/chi/v5 v5.0.10 + github.com/go-chi/chi/v5 v5.0.12 github.com/go-chi/docgen v1.2.0 github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb github.com/google/go-cmp v0.6.0 github.com/google/gofuzz v1.2.1-0.20220503160820-4a35382e8fc8 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.6.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru/v2 v2.0.5 - github.com/holiman/uint256 v1.2.3 + github.com/hashicorp/raft v1.6.1 + github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e + github.com/holiman/uint256 v1.2.4 github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-ds-leveldb v0.5.0 - github.com/jackc/pgtype v1.14.0 - github.com/jackc/pgx/v5 v5.4.3 + github.com/jackc/pgtype v1.14.2 + github.com/jackc/pgx/v5 v5.5.5 github.com/libp2p/go-libp2p v0.32.1 github.com/libp2p/go-libp2p-mplex v0.9.0 github.com/libp2p/go-libp2p-pubsub v0.10.0 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/mattn/go-isatty v0.0.20 github.com/multiformats/go-base32 v0.1.0 - github.com/multiformats/go-multiaddr v0.12.1 + github.com/multiformats/go-multiaddr v0.12.2 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/olekukonko/tablewriter v0.0.5 - github.com/onsi/gomega v1.29.0 + github.com/onsi/gomega v1.31.1 github.com/pkg/errors v0.9.1 github.com/pkg/profile v1.7.0 - github.com/prometheus/client_golang v1.17.0 - github.com/stretchr/testify v1.8.4 - github.com/urfave/cli/v2 v2.25.7 - golang.org/x/crypto v0.18.0 + github.com/prometheus/client_golang v1.19.0 + github.com/stretchr/testify v1.9.0 + github.com/urfave/cli/v2 v2.27.1 + golang.org/x/crypto v0.21.0 golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 - golang.org/x/sync v0.5.0 - golang.org/x/term v0.16.0 - golang.org/x/time v0.3.0 - gorm.io/driver/postgres v1.5.4 - gorm.io/gorm v1.25.5 + golang.org/x/sync v0.6.0 + golang.org/x/term v0.18.0 + golang.org/x/time v0.5.0 + gorm.io/driver/postgres v1.5.7 + gorm.io/gorm v1.25.8 ) require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.13.43 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 // indirect - github.com/aws/smithy-go v1.19.0 // indirect + github.com/aws/smithy-go v1.20.2 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.7.0 // indirect + github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/boltdb/bolt v1.3.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect - github.com/btcsuite/btcd/btcutil v1.1.2 // indirect + github.com/btcsuite/btcd/btcutil v1.1.5 // indirect github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/cometbft/cometbft v0.37.2 // indirect github.com/consensys/bavard v0.1.13 // indirect - github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect - github.com/crate-crypto/go-ipa v0.0.0-20230601170251-1830d0757c80 // indirect - github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/cosmos/gogoproto v1.4.1 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect @@ -105,20 +109,19 @@ require ( github.com/flynn/noise v1.0.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect - github.com/gballet/go-verkle v0.0.0-20230607174250-df487255f46b // indirect + github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/golang/glog v1.1.2 // indirect + github.com/golang/glog v1.1.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect @@ -127,6 +130,10 @@ require ( github.com/gtank/merlin v0.1.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-bexpr v0.1.11 // indirect + github.com/hashicorp/go-hclog v1.6.2 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v0.5.5 // indirect + github.com/hashicorp/go-msgpack/v2 v2.1.1 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e // indirect @@ -141,6 +148,7 @@ require ( github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect @@ -149,7 +157,7 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c // indirect github.com/klauspost/compress v1.17.2 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -166,7 +174,6 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.56 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect @@ -186,15 +193,15 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 // indirect - github.com/onsi/ginkgo/v2 v2.13.0 // indirect + github.com/onsi/ginkgo/v2 v2.15.0 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/peterh/liner v1.2.0 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect - github.com/prometheus/common v0.44.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d // indirect github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44 // indirect @@ -203,7 +210,7 @@ require ( github.com/prysmaticlabs/prysm/v4 v4.2.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.4 // indirect - github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/quic-go v0.39.4 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect @@ -216,7 +223,7 @@ require ( github.com/sirupsen/logrus v1.9.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect @@ -232,13 +239,13 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/grpc v1.60.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + golang.org/x/tools v0.16.1 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/grpc v1.56.3 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -246,9 +253,10 @@ require ( rsc.io/tmplfunc v0.0.3 // indirect ) -// TODO replace to bnb-chain/op-geth -replace github.com/ethereum/go-ethereum => github.com/bnb-chain/op-geth v0.3.0-alpha +replace github.com/ethereum/go-ethereum v1.13.8 => github.com/welkin22/op-geth v1.101308.2-opbnb2 replace github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v1.0.0 -//replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain +// replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain + +//replace github.com/ethereum/go-ethereum v1.13.5 => ../go-ethereum diff --git a/go.sum b/go.sum index 6229e24605a8..d61d374a9665 100644 --- a/go.sum +++ b/go.sum @@ -1,22 +1,12 @@ -4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= -4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= -bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= -bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= -cloud.google.com/go v0.0.0-20170206221025-ce650573d812/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.25.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= -cloud.google.com/go v0.37.2/go.mod h1:H8IAquKe2L30IxoupDgqTaQvKSwF/c8prYHynGIWQbA= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= +cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -26,1370 +16,151 @@ cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6 cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= -cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= -cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= -cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= -cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= -cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= -cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= -cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= -cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= -cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk= -cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= -cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= -cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= -cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= -cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68= -cloud.google.com/go/accessapproval v1.7.2/go.mod h1:/gShiq9/kK/h8T/eEn1BTzalDvk0mZxJlhfw0p+Xuc0= -cloud.google.com/go/accessapproval v1.7.4/go.mod h1:/aTEh45LzplQgFYdQdwPMR9YdX0UlhBmvB84uAmQKUc= -cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= -cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= -cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= -cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= -cloud.google.com/go/accesscontextmanager v1.8.0/go.mod h1:uI+AI/r1oyWK99NN8cQ3UK76AMelMzgZCvJfsi2c+ps= -cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo= -cloud.google.com/go/accesscontextmanager v1.8.2/go.mod h1:E6/SCRM30elQJ2PKtFMs2YhfJpZSNcJyejhuzoId4Zk= -cloud.google.com/go/accesscontextmanager v1.8.4/go.mod h1:ParU+WbMpD34s5JFEnGAnPBYAgUHozaTmDJU7aCU9+M= -cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= -cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= -cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= -cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= -cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= -cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= -cloud.google.com/go/aiplatform v1.45.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= -cloud.google.com/go/aiplatform v1.48.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= -cloud.google.com/go/aiplatform v1.50.0/go.mod h1:IRc2b8XAMTa9ZmfJV1BCCQbieWWvDnP1A8znyz5N7y4= -cloud.google.com/go/aiplatform v1.51.0/go.mod h1:IRc2b8XAMTa9ZmfJV1BCCQbieWWvDnP1A8znyz5N7y4= -cloud.google.com/go/aiplatform v1.51.1/go.mod h1:kY3nIMAVQOK2XDqDPHaOuD9e+FdMA6OOpfBjsvaFSOo= -cloud.google.com/go/aiplatform v1.52.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= -cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= -cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= -cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= -cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= -cloud.google.com/go/analytics v0.21.2/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= -cloud.google.com/go/analytics v0.21.3/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= -cloud.google.com/go/analytics v0.21.4/go.mod h1:zZgNCxLCy8b2rKKVfC1YkC2vTrpfZmeRCySM3aUbskA= -cloud.google.com/go/analytics v0.21.6/go.mod h1:eiROFQKosh4hMaNhF85Oc9WO97Cpa7RggD40e/RBy8w= -cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= -cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= -cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= -cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA= -cloud.google.com/go/apigateway v1.6.2/go.mod h1:CwMC90nnZElorCW63P2pAYm25AtQrHfuOkbRSHj0bT8= -cloud.google.com/go/apigateway v1.6.4/go.mod h1:0EpJlVGH5HwAN4VF4Iec8TAzGN1aQgbxAWGJsnPCGGY= -cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= -cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= -cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= -cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs= -cloud.google.com/go/apigeeconnect v1.6.2/go.mod h1:s6O0CgXT9RgAxlq3DLXvG8riw8PYYbU/v25jqP3Dy18= -cloud.google.com/go/apigeeconnect v1.6.4/go.mod h1:CapQCWZ8TCjnU0d7PobxhpOdVz/OVJ2Hr/Zcuu1xFx0= -cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= -cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= -cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= -cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw= -cloud.google.com/go/apigeeregistry v0.7.2/go.mod h1:9CA2B2+TGsPKtfi3F7/1ncCCsL62NXBRfM6iPoGSM+8= -cloud.google.com/go/apigeeregistry v0.8.2/go.mod h1:h4v11TDGdeXJDJvImtgK2AFVvMIgGWjSb0HRnBSjcX8= -cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= -cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= -cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= -cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= -cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= -cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= -cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= -cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= -cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY= -cloud.google.com/go/appengine v1.8.2/go.mod h1:WMeJV9oZ51pvclqFN2PqHoGnys7rK0rz6s3Mp6yMvDo= -cloud.google.com/go/appengine v1.8.4/go.mod h1:TZ24v+wXBujtkK77CXCpjZbnuTvsFNT41MUaZ28D6vg= -cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= -cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= -cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= -cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg= -cloud.google.com/go/area120 v0.8.2/go.mod h1:a5qfo+x77SRLXnCynFWPUZhnZGeSgvQ+Y0v1kSItkh4= -cloud.google.com/go/area120 v0.8.4/go.mod h1:jfawXjxf29wyBXr48+W+GyX/f8fflxp642D/bb9v68M= -cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= -cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= -cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= -cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= -cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= -cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= -cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= -cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= -cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E= -cloud.google.com/go/artifactregistry v1.14.2/go.mod h1:Xk+QbsKEb0ElmyeMfdHAey41B+qBq3q5R5f5xD4XT3U= -cloud.google.com/go/artifactregistry v1.14.3/go.mod h1:A2/E9GXnsyXl7GUvQ/2CjHA+mVRoWAXC0brg2os+kNI= -cloud.google.com/go/artifactregistry v1.14.6/go.mod h1:np9LSFotNWHcjnOgh8UVK0RFPCTUGbO0ve3384xyHfE= -cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= -cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= -cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= -cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= -cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= -cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= -cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= -cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= -cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ= -cloud.google.com/go/asset v1.15.0/go.mod h1:tpKafV6mEut3+vN9ScGvCHXHj7FALFVta+okxFECHcg= -cloud.google.com/go/asset v1.15.1/go.mod h1:yX/amTvFWRpp5rcFq6XbCxzKT8RJUam1UoboE179jU4= -cloud.google.com/go/asset v1.15.3/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= -cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= -cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= -cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= -cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= -cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= -cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0= -cloud.google.com/go/assuredworkloads v1.11.2/go.mod h1:O1dfr+oZJMlE6mw0Bp0P1KZSlj5SghMBvTpZqIcUAW4= -cloud.google.com/go/assuredworkloads v1.11.4/go.mod h1:4pwwGNwy1RP0m+y12ef3Q/8PaiWrIDQ6nD2E8kvWI9U= -cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= -cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= -cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= -cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= -cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= -cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE= -cloud.google.com/go/automl v1.13.2/go.mod h1:gNY/fUmDEN40sP8amAX3MaXkxcqPIn7F1UIIPZpy4Mg= -cloud.google.com/go/automl v1.13.4/go.mod h1:ULqwX/OLZ4hBVfKQaMtxMSTlPx0GqGbWN8uA/1EqCP8= -cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= -cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= -cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= -cloud.google.com/go/baremetalsolution v1.1.1/go.mod h1:D1AV6xwOksJMV4OSlWHtWuFNZZYujJknMAP4Qa27QIA= -cloud.google.com/go/baremetalsolution v1.2.0/go.mod h1:68wi9AwPYkEWIUT4SvSGS9UJwKzNpshjHsH4lzk8iOw= -cloud.google.com/go/baremetalsolution v1.2.1/go.mod h1:3qKpKIw12RPXStwQXcbhfxVj1dqQGEvcmA+SX/mUR88= -cloud.google.com/go/baremetalsolution v1.2.3/go.mod h1:/UAQ5xG3faDdy180rCUv47e0jvpp3BFxT+Cl0PFjw5g= -cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= -cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= -cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= -cloud.google.com/go/batch v1.3.1/go.mod h1:VguXeQKXIYaeeIYbuozUmBR13AfL4SJP7IltNPS+A4A= -cloud.google.com/go/batch v1.4.1/go.mod h1:KdBmDD61K0ovcxoRHGrN6GmOBWeAOyCgKD0Mugx4Fkk= -cloud.google.com/go/batch v1.5.0/go.mod h1:KdBmDD61K0ovcxoRHGrN6GmOBWeAOyCgKD0Mugx4Fkk= -cloud.google.com/go/batch v1.5.1/go.mod h1:RpBuIYLkQu8+CWDk3dFD/t/jOCGuUpkpX+Y0n1Xccs8= -cloud.google.com/go/batch v1.6.3/go.mod h1:J64gD4vsNSA2O5TtDB5AAux3nJ9iV8U3ilg3JDBYejU= -cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= -cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= -cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= -cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= -cloud.google.com/go/beyondcorp v0.6.1/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= -cloud.google.com/go/beyondcorp v1.0.0/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= -cloud.google.com/go/beyondcorp v1.0.1/go.mod h1:zl/rWWAFVeV+kx+X2Javly7o1EIQThU4WlkynffL/lk= -cloud.google.com/go/beyondcorp v1.0.3/go.mod h1:HcBvnEd7eYr+HGDd5ZbuVmBYX019C6CEXBonXbCVwJo= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= -cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= -cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= -cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= -cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= -cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= -cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= -cloud.google.com/go/bigquery v1.52.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= -cloud.google.com/go/bigquery v1.53.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= -cloud.google.com/go/bigquery v1.55.0/go.mod h1:9Y5I3PN9kQWuid6183JFhOGOW3GcirA5LpsKCUn+2ec= -cloud.google.com/go/bigquery v1.56.0/go.mod h1:KDcsploXTEY7XT3fDQzMUZlpQLHzE4itubHrnmhUrZA= -cloud.google.com/go/bigquery v1.57.1/go.mod h1:iYzC0tGVWt1jqSzBHqCr3lrRn0u13E8e+AqowBsDgug= -cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= -cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= -cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= -cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= -cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= -cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= -cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA= -cloud.google.com/go/billing v1.17.0/go.mod h1:Z9+vZXEq+HwH7bhJkyI4OQcR6TSbeMrjlpEjO2vzY64= -cloud.google.com/go/billing v1.17.1/go.mod h1:Z9+vZXEq+HwH7bhJkyI4OQcR6TSbeMrjlpEjO2vzY64= -cloud.google.com/go/billing v1.17.2/go.mod h1:u/AdV/3wr3xoRBk5xvUzYMS1IawOAPwQMuHgHMdljDg= -cloud.google.com/go/billing v1.17.4/go.mod h1:5DOYQStCxquGprqfuid/7haD7th74kyMBHkjO/OvDtk= -cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= -cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= -cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= -cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= -cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= -cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U= -cloud.google.com/go/binaryauthorization v1.7.0/go.mod h1:Zn+S6QqTMn6odcMU1zDZCJxPjU2tZPV1oDl45lWY154= -cloud.google.com/go/binaryauthorization v1.7.1/go.mod h1:GTAyfRWYgcbsP3NJogpV3yeunbUIjx2T9xVeYovtURE= -cloud.google.com/go/binaryauthorization v1.7.3/go.mod h1:VQ/nUGRKhrStlGr+8GMS8f6/vznYLkdK5vaKfdCIpvU= -cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= -cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= -cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= -cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI= -cloud.google.com/go/certificatemanager v1.7.2/go.mod h1:15SYTDQMd00kdoW0+XY5d9e+JbOPjp24AvF48D8BbcQ= -cloud.google.com/go/certificatemanager v1.7.4/go.mod h1:FHAylPe/6IIKuaRmHbjbdLhGhVQ+CWHSD5Jq0k4+cCE= -cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= -cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= -cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= -cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= -cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc= -cloud.google.com/go/channel v1.17.0/go.mod h1:RpbhJsGi/lXWAUM1eF4IbQGbsfVlg2o8Iiy2/YLfVT0= -cloud.google.com/go/channel v1.17.1/go.mod h1:xqfzcOZAcP4b/hUDH0GkGg1Sd5to6di1HOJn/pi5uBQ= -cloud.google.com/go/channel v1.17.3/go.mod h1:QcEBuZLGGrUMm7kNj9IbU1ZfmJq2apotsV83hbxX7eE= -cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= -cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= -cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= -cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= -cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= -cloud.google.com/go/cloudbuild v1.10.1/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= -cloud.google.com/go/cloudbuild v1.13.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= -cloud.google.com/go/cloudbuild v1.14.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= -cloud.google.com/go/cloudbuild v1.14.1/go.mod h1:K7wGc/3zfvmYWOWwYTgF/d/UVJhS4pu+HAy7PL7mCsU= -cloud.google.com/go/cloudbuild v1.14.3/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= -cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= -cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= -cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= -cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI= -cloud.google.com/go/clouddms v1.7.0/go.mod h1:MW1dC6SOtI/tPNCciTsXtsGNEM0i0OccykPvv3hiYeM= -cloud.google.com/go/clouddms v1.7.1/go.mod h1:o4SR8U95+P7gZ/TX+YbJxehOCsM+fe6/brlrFquiszk= -cloud.google.com/go/clouddms v1.7.3/go.mod h1:fkN2HQQNUYInAU3NQ3vRLkV2iWs8lIdmBKOx4nrL6Hc= -cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= -cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= -cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= -cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= -cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= -cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= -cloud.google.com/go/cloudtasks v1.11.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= -cloud.google.com/go/cloudtasks v1.12.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= -cloud.google.com/go/cloudtasks v1.12.2/go.mod h1:A7nYkjNlW2gUoROg1kvJrQGhJP/38UaWwsnuBDOBVUk= -cloud.google.com/go/cloudtasks v1.12.4/go.mod h1:BEPu0Gtt2dU6FxZHNqqNdGqIG86qyWKBPGnsb7udGY0= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= -cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= -cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= -cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= -cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= -cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= -cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= -cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= -cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= -cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= -cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= -cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= -cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= -cloud.google.com/go/contactcenterinsights v1.9.1/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= -cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= -cloud.google.com/go/contactcenterinsights v1.11.0/go.mod h1:hutBdImE4XNZ1NV4vbPJKSFOnQruhC5Lj9bZqWMTKiU= -cloud.google.com/go/contactcenterinsights v1.11.1/go.mod h1:FeNP3Kg8iteKM80lMwSk3zZZKVxr+PGnAId6soKuXwE= -cloud.google.com/go/contactcenterinsights v1.11.3/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= -cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= -cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= -cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= -cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= -cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= -cloud.google.com/go/container v1.22.1/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= -cloud.google.com/go/container v1.24.0/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= -cloud.google.com/go/container v1.26.0/go.mod h1:YJCmRet6+6jnYYRS000T6k0D0xUXQgBSaJ7VwI8FBj4= -cloud.google.com/go/container v1.26.1/go.mod h1:5smONjPRUxeEpDG7bMKWfDL4sauswqEtnBK1/KKpR04= -cloud.google.com/go/container v1.27.1/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= -cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= -cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= -cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= -cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0= -cloud.google.com/go/containeranalysis v0.11.0/go.mod h1:4n2e99ZwpGxpNcz+YsFT1dfOHPQFGcAC8FN2M2/ne/U= -cloud.google.com/go/containeranalysis v0.11.1/go.mod h1:rYlUOM7nem1OJMKwE1SadufX0JP3wnXj844EtZAwWLY= -cloud.google.com/go/containeranalysis v0.11.3/go.mod h1:kMeST7yWFQMGjiG9K7Eov+fPNQcGhb8mXj/UcTiWw9U= -cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= -cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= -cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= -cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= -cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= -cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= -cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= -cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= -cloud.google.com/go/datacatalog v1.14.0/go.mod h1:h0PrGtlihoutNMp/uvwhawLQ9+c63Kz65UFqh49Yo+E= -cloud.google.com/go/datacatalog v1.14.1/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= -cloud.google.com/go/datacatalog v1.16.0/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= -cloud.google.com/go/datacatalog v1.17.1/go.mod h1:nCSYFHgtxh2MiEktWIz71s/X+7ds/UT9kp0PC7waCzE= -cloud.google.com/go/datacatalog v1.18.0/go.mod h1:nCSYFHgtxh2MiEktWIz71s/X+7ds/UT9kp0PC7waCzE= -cloud.google.com/go/datacatalog v1.18.1/go.mod h1:TzAWaz+ON1tkNr4MOcak8EBHX7wIRX/gZKM+yTVsv+A= -cloud.google.com/go/datacatalog v1.18.3/go.mod h1:5FR6ZIF8RZrtml0VUao22FxhdjkoG+a0866rEnObryM= -cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= -cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= -cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw= -cloud.google.com/go/dataflow v0.9.2/go.mod h1:vBfdBZ/ejlTaYIGB3zB4T08UshH70vbtZeMD+urnUSo= -cloud.google.com/go/dataflow v0.9.4/go.mod h1:4G8vAkHYCSzU8b/kmsoR2lWyHJD85oMJPHMtan40K8w= -cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= -cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= -cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= -cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= -cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= -cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M= -cloud.google.com/go/dataform v0.8.2/go.mod h1:X9RIqDs6NbGPLR80tnYoPNiO1w0wenKTb8PxxlhTMKM= -cloud.google.com/go/dataform v0.9.1/go.mod h1:pWTg+zGQ7i16pyn0bS1ruqIE91SdL2FDMvEYu/8oQxs= -cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= -cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= -cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= -cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI= -cloud.google.com/go/datafusion v1.7.2/go.mod h1:62K2NEC6DRlpNmI43WHMWf9Vg/YvN6QVi8EVwifElI0= -cloud.google.com/go/datafusion v1.7.4/go.mod h1:BBs78WTOLYkT4GVZIXQCZT3GFpkpDN4aBY4NDX/jVlM= -cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= -cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= -cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY= -cloud.google.com/go/datalabeling v0.8.2/go.mod h1:cyDvGHuJWu9U/cLDA7d8sb9a0tWLEletStu2sTmg3BE= -cloud.google.com/go/datalabeling v0.8.4/go.mod h1:Z1z3E6LHtffBGrNUkKwbwbDxTiXEApLzIgmymj8A3S8= -cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= -cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= -cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= -cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= -cloud.google.com/go/dataplex v1.8.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= -cloud.google.com/go/dataplex v1.9.0/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= -cloud.google.com/go/dataplex v1.9.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= -cloud.google.com/go/dataplex v1.10.1/go.mod h1:1MzmBv8FvjYfc7vDdxhnLFNskikkB+3vl475/XdCDhs= -cloud.google.com/go/dataplex v1.11.1/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= -cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= -cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= -cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= -cloud.google.com/go/dataproc/v2 v2.0.1/go.mod h1:7Ez3KRHdFGcfY7GcevBbvozX+zyWGcwLJvvAMwCaoZ4= -cloud.google.com/go/dataproc/v2 v2.2.0/go.mod h1:lZR7AQtwZPvmINx5J87DSOOpTfof9LVZju6/Qo4lmcY= -cloud.google.com/go/dataproc/v2 v2.2.1/go.mod h1:QdAJLaBjh+l4PVlVZcmrmhGccosY/omC1qwfQ61Zv/o= -cloud.google.com/go/dataproc/v2 v2.2.3/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= -cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= -cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= -cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= -cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8= -cloud.google.com/go/dataqna v0.8.2/go.mod h1:KNEqgx8TTmUipnQsScOoDpq/VlXVptUqVMZnt30WAPs= -cloud.google.com/go/dataqna v0.8.4/go.mod h1:mySRKjKg5Lz784P6sCov3p1QD+RZQONRMRjzGNcFd0c= +cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= -cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= -cloud.google.com/go/datastore v1.12.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= -cloud.google.com/go/datastore v1.12.1/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= -cloud.google.com/go/datastore v1.13.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= -cloud.google.com/go/datastore v1.14.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= -cloud.google.com/go/datastore v1.15.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= -cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= -cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= -cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= -cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= -cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= -cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= -cloud.google.com/go/datastream v1.9.1/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= -cloud.google.com/go/datastream v1.10.0/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= -cloud.google.com/go/datastream v1.10.1/go.mod h1:7ngSYwnw95YFyTd5tOGBxHlOZiL+OtpjheqU7t2/s/c= -cloud.google.com/go/datastream v1.10.3/go.mod h1:YR0USzgjhqA/Id0Ycu1VvZe8hEWwrkjuXrGbzeDOSEA= -cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= -cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= -cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= -cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= -cloud.google.com/go/deploy v1.11.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= -cloud.google.com/go/deploy v1.13.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= -cloud.google.com/go/deploy v1.13.1/go.mod h1:8jeadyLkH9qu9xgO3hVWw8jVr29N1mnW42gRJT8GY6g= -cloud.google.com/go/deploy v1.14.2/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= -cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= -cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= -cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= -cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= -cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= -cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= -cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= -cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= -cloud.google.com/go/dialogflow v1.38.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= -cloud.google.com/go/dialogflow v1.40.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= -cloud.google.com/go/dialogflow v1.43.0/go.mod h1:pDUJdi4elL0MFmt1REMvFkdsUTYSHq+rTCS8wg0S3+M= -cloud.google.com/go/dialogflow v1.44.0/go.mod h1:pDUJdi4elL0MFmt1REMvFkdsUTYSHq+rTCS8wg0S3+M= -cloud.google.com/go/dialogflow v1.44.1/go.mod h1:n/h+/N2ouKOO+rbe/ZnI186xImpqvCVj2DdsWS/0EAk= -cloud.google.com/go/dialogflow v1.44.3/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= -cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= -cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= -cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= -cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI= -cloud.google.com/go/dlp v1.10.2/go.mod h1:ZbdKIhcnyhILgccwVDzkwqybthh7+MplGC3kZVZsIOQ= -cloud.google.com/go/dlp v1.11.1/go.mod h1:/PA2EnioBeXTL/0hInwgj0rfsQb3lpE3R8XUJxqUNKI= -cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= -cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= -cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= -cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= -cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= -cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= -cloud.google.com/go/documentai v1.20.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= -cloud.google.com/go/documentai v1.22.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= -cloud.google.com/go/documentai v1.22.1/go.mod h1:LKs22aDHbJv7ufXuPypzRO7rG3ALLJxzdCXDPutw4Qc= -cloud.google.com/go/documentai v1.23.0/go.mod h1:LKs22aDHbJv7ufXuPypzRO7rG3ALLJxzdCXDPutw4Qc= -cloud.google.com/go/documentai v1.23.2/go.mod h1:Q/wcRT+qnuXOpjAkvOV4A+IeQl04q2/ReT7SSbytLSo= -cloud.google.com/go/documentai v1.23.5/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= -cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= -cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= -cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE= -cloud.google.com/go/domains v0.9.2/go.mod h1:3YvXGYzZG1Temjbk7EyGCuGGiXHJwVNmwIf+E/cUp5I= -cloud.google.com/go/domains v0.9.4/go.mod h1:27jmJGShuXYdUNjyDG0SodTfT5RwLi7xmH334Gvi3fY= -cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= -cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= -cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= -cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk= -cloud.google.com/go/edgecontainer v1.1.2/go.mod h1:wQRjIzqxEs9e9wrtle4hQPSR1Y51kqN75dgF7UllZZ4= -cloud.google.com/go/edgecontainer v1.1.4/go.mod h1:AvFdVuZuVGdgaE5YvlL1faAoa1ndRR/5XhXZvPBHbsE= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= -cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= -cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= -cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4= -cloud.google.com/go/essentialcontacts v1.6.3/go.mod h1:yiPCD7f2TkP82oJEFXFTou8Jl8L6LBRPeBEkTaO0Ggo= -cloud.google.com/go/essentialcontacts v1.6.5/go.mod h1:jjYbPzw0x+yglXC890l6ECJWdYeZ5dlYACTFL0U/VuM= -cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= -cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= -cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= -cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= -cloud.google.com/go/eventarc v1.12.1/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= -cloud.google.com/go/eventarc v1.13.0/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= -cloud.google.com/go/eventarc v1.13.1/go.mod h1:EqBxmGHFrruIara4FUQ3RHlgfCn7yo1HYsu2Hpt/C3Y= -cloud.google.com/go/eventarc v1.13.3/go.mod h1:RWH10IAZIRcj1s/vClXkBgMHwh59ts7hSWcqD3kaclg= -cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= -cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= -cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= -cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= -cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4= -cloud.google.com/go/filestore v1.7.2/go.mod h1:TYOlyJs25f/omgj+vY7/tIG/E7BX369triSPzE4LdgE= -cloud.google.com/go/filestore v1.7.4/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= -cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= -cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4= -cloud.google.com/go/firestore v1.12.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4= -cloud.google.com/go/firestore v1.13.0/go.mod h1:QojqqOh8IntInDUSTAh0c8ZsPYAr68Ma8c5DWOy8xb8= -cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= -cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= -cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= -cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= -cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= -cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= -cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= -cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= -cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE= -cloud.google.com/go/functions v1.15.2/go.mod h1:CHAjtcR6OU4XF2HuiVeriEdELNcnvRZSk1Q8RMqy4lE= -cloud.google.com/go/functions v1.15.4/go.mod h1:CAsTc3VlRMVvx+XqXxKqVevguqJpnVip4DdonFsX28I= -cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= -cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= -cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= -cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= -cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= -cloud.google.com/go/gaming v1.10.1/go.mod h1:XQQvtfP8Rb9Rxnxm5wFVpAp9zCQkJi2bLIb7iHGwB3s= -cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= -cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= -cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= -cloud.google.com/go/gkebackup v1.3.0/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= -cloud.google.com/go/gkebackup v1.3.1/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= -cloud.google.com/go/gkebackup v1.3.2/go.mod h1:OMZbXzEJloyXMC7gqdSB+EOEQ1AKcpGYvO3s1ec5ixk= -cloud.google.com/go/gkebackup v1.3.4/go.mod h1:gLVlbM8h/nHIs09ns1qx3q3eaXcGSELgNu1DWXYz1HI= -cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= -cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= -cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw= -cloud.google.com/go/gkeconnect v0.8.2/go.mod h1:6nAVhwchBJYgQCXD2pHBFQNiJNyAd/wyxljpaa6ZPrY= -cloud.google.com/go/gkeconnect v0.8.4/go.mod h1:84hZz4UMlDCKl8ifVW8layK4WHlMAFeq8vbzjU0yJkw= -cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= -cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= -cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= -cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY= -cloud.google.com/go/gkehub v0.14.2/go.mod h1:iyjYH23XzAxSdhrbmfoQdePnlMj2EWcvnR+tHdBQsCY= -cloud.google.com/go/gkehub v0.14.4/go.mod h1:Xispfu2MqnnFt8rV/2/3o73SK1snL8s9dYJ9G2oQMfc= -cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= -cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= -cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= -cloud.google.com/go/gkemulticloud v0.6.1/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= -cloud.google.com/go/gkemulticloud v1.0.0/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= -cloud.google.com/go/gkemulticloud v1.0.1/go.mod h1:AcrGoin6VLKT/fwZEYuqvVominLriQBCKmbjtnbMjG8= -cloud.google.com/go/gkemulticloud v1.0.3/go.mod h1:7NpJBN94U6DY1xHIbsDqB2+TFZUfjLUKLjUX8NGLor0= -cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= -cloud.google.com/go/grafeas v0.3.0/go.mod h1:P7hgN24EyONOTMyeJH6DxG4zD7fwiYa5Q6GUgyFSOU8= -cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= -cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= -cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= -cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY= -cloud.google.com/go/gsuiteaddons v1.6.2/go.mod h1:K65m9XSgs8hTF3X9nNTPi8IQueljSdYo9F+Mi+s4MyU= -cloud.google.com/go/gsuiteaddons v1.6.4/go.mod h1:rxtstw7Fx22uLOXBpsvb9DUbC+fiXs7rF4U29KHM/pE= -cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= -cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= -cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= -cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= -cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= -cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= -cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8= -cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk= -cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= -cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= -cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQyY5SE= -cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= -cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= -cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= -cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= -cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= -cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= -cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ= -cloud.google.com/go/iap v1.9.0/go.mod h1:01OFxd1R+NFrg78S+hoPV5PxEzv22HXaNqUUlmNHFuY= -cloud.google.com/go/iap v1.9.1/go.mod h1:SIAkY7cGMLohLSdBR25BuIxO+I4fXJiL06IBL7cy/5Q= -cloud.google.com/go/iap v1.9.3/go.mod h1:DTdutSZBqkkOm2HEOTBzhZxh2mwwxshfD/h3yofAiCw= -cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= -cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= -cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= -cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw= -cloud.google.com/go/ids v1.4.2/go.mod h1:3vw8DX6YddRu9BncxuzMyWn0g8+ooUjI2gslJ7FH3vk= -cloud.google.com/go/ids v1.4.4/go.mod h1:z+WUc2eEl6S/1aZWzwtVNWoSZslgzPxAboS0lZX0HjI= -cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= -cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= -cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= -cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= -cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk= -cloud.google.com/go/iot v1.7.2/go.mod h1:q+0P5zr1wRFpw7/MOgDXrG/HVA+l+cSwdObffkrpnSg= -cloud.google.com/go/iot v1.7.4/go.mod h1:3TWqDVvsddYBG++nHSZmluoCAVGr1hAcabbWZNKEZLk= -cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= -cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= -cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= -cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= -cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= -cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= -cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= -cloud.google.com/go/kms v1.11.0/go.mod h1:hwdiYC0xjnWsKQQCQQmIQnS9asjYVSK6jtXm+zFqXLM= -cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= -cloud.google.com/go/kms v1.15.0/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= -cloud.google.com/go/kms v1.15.2/go.mod h1:3hopT4+7ooWRCjc2DxgnpESFxhIraaI2IpAVUEhbT/w= -cloud.google.com/go/kms v1.15.3/go.mod h1:AJdXqHxS2GlPyduM99s9iGqi2nwbviBbhV/hdmt4iOQ= -cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI= -cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= -cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= -cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= -cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= -cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= -cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0= -cloud.google.com/go/language v1.11.0/go.mod h1:uDx+pFDdAKTY8ehpWbiXyQdz8tDSYLJbQcXsCkjYyvQ= -cloud.google.com/go/language v1.11.1/go.mod h1:Xyid9MG9WOX3utvDbpX7j3tXDmmDooMyMDqgUVpH17U= -cloud.google.com/go/language v1.12.2/go.mod h1:9idWapzr/JKXBBQ4lWqVX/hcadxB194ry20m/bTrhWc= -cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= -cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= -cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc= -cloud.google.com/go/lifesciences v0.9.2/go.mod h1:QHEOO4tDzcSAzeJg7s2qwnLM2ji8IRpQl4p6m5Z9yTA= -cloud.google.com/go/lifesciences v0.9.4/go.mod h1:bhm64duKhMi7s9jR9WYJYvjAFJwRqNj+Nia7hF0Z7JA= -cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= -cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= -cloud.google.com/go/logging v1.8.1/go.mod h1:TJjR+SimHwuC8MZ9cjByQulAMgni+RkXeI3wwctHJEI= -cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= -cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= -cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= -cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ= -cloud.google.com/go/longrunning v0.5.0/go.mod h1:0JNuqRShmscVAhIACGtskSAWtqtOoPkwP0YF1oVEchc= -cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= -cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUzqv2YttZiveCs= -cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= -cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= -cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= -cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= -cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak= -cloud.google.com/go/managedidentities v1.6.2/go.mod h1:5c2VG66eCa0WIq6IylRk3TBW83l161zkFvCj28X7jn8= -cloud.google.com/go/managedidentities v1.6.4/go.mod h1:WgyaECfHmF00t/1Uk8Oun3CQ2PGUtjc3e9Alh79wyiM= -cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= -cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= -cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= -cloud.google.com/go/maps v1.3.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s= -cloud.google.com/go/maps v1.4.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s= -cloud.google.com/go/maps v1.4.1/go.mod h1:BxSa0BnW1g2U2gNdbq5zikLlHUuHW0GFWh7sgML2kIY= -cloud.google.com/go/maps v1.6.1/go.mod h1:4+buOHhYXFBp58Zj/K+Lc1rCmJssxxF4pJ5CJnhdz18= -cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= -cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= -cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig= -cloud.google.com/go/mediatranslation v0.8.2/go.mod h1:c9pUaDRLkgHRx3irYE5ZC8tfXGrMYwNZdmDqKMSfFp8= -cloud.google.com/go/mediatranslation v0.8.4/go.mod h1:9WstgtNVAdN53m6TQa5GjIjLqKQPXe74hwSCxUP6nj4= -cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= -cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= -cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= -cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= -cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= -cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA= -cloud.google.com/go/memcache v1.10.2/go.mod h1:f9ZzJHLBrmd4BkguIAa/l/Vle6uTHzHokdnzSWOdQ6A= -cloud.google.com/go/memcache v1.10.4/go.mod h1:v/d8PuC8d1gD6Yn5+I3INzLR01IDn0N4Ym56RgikSI0= -cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= -cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= -cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= -cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= -cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= -cloud.google.com/go/metastore v1.11.1/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= -cloud.google.com/go/metastore v1.12.0/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= -cloud.google.com/go/metastore v1.13.0/go.mod h1:URDhpG6XLeh5K+Glq0NOt74OfrPKTwS62gEPZzb5SOk= -cloud.google.com/go/metastore v1.13.1/go.mod h1:IbF62JLxuZmhItCppcIfzBBfUFq0DIB9HPDoLgWrVOU= -cloud.google.com/go/metastore v1.13.3/go.mod h1:K+wdjXdtkdk7AQg4+sXS8bRrQa9gcOr+foOMF2tqINE= -cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= -cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= -cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= -cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= -cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM= -cloud.google.com/go/monitoring v1.16.0/go.mod h1:Ptp15HgAyM1fNICAojDMoNc/wUmn67mLHQfyqbw+poY= -cloud.google.com/go/monitoring v1.16.1/go.mod h1:6HsxddR+3y9j+o/cMJH6q/KJ/CBTvM/38L/1m7bTRJ4= -cloud.google.com/go/monitoring v1.16.3/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= -cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= -cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= -cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= -cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= -cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= -cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= -cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E= -cloud.google.com/go/networkconnectivity v1.13.0/go.mod h1:SAnGPes88pl7QRLUen2HmcBSE9AowVAcdug8c0RSBFk= -cloud.google.com/go/networkconnectivity v1.14.0/go.mod h1:SAnGPes88pl7QRLUen2HmcBSE9AowVAcdug8c0RSBFk= -cloud.google.com/go/networkconnectivity v1.14.1/go.mod h1:LyGPXR742uQcDxZ/wv4EI0Vu5N6NKJ77ZYVnDe69Zug= -cloud.google.com/go/networkconnectivity v1.14.3/go.mod h1:4aoeFdrJpYEXNvrnfyD5kIzs8YtHg945Og4koAjHQek= -cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= -cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= -cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= -cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0= -cloud.google.com/go/networkmanagement v1.9.0/go.mod h1:UTUaEU9YwbCAhhz3jEOHr+2/K/MrBk2XxOLS89LQzFw= -cloud.google.com/go/networkmanagement v1.9.1/go.mod h1:CCSYgrQQvW73EJawO2QamemYcOb57LvrDdDU51F0mcI= -cloud.google.com/go/networkmanagement v1.9.3/go.mod h1:y7WMO1bRLaP5h3Obm4tey+NquUvB93Co1oh4wpL+XcU= -cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= -cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= -cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= -cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ= -cloud.google.com/go/networksecurity v0.9.2/go.mod h1:jG0SeAttWzPMUILEHDUvFYdQTl8L/E/KC8iZDj85lEI= -cloud.google.com/go/networksecurity v0.9.4/go.mod h1:E9CeMZ2zDsNBkr8axKSYm8XyTqNhiCHf1JO/Vb8mD1w= -cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= -cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= -cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= -cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= -cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= -cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= -cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8= -cloud.google.com/go/notebooks v1.10.0/go.mod h1:SOPYMZnttHxqot0SGSFSkRrwE29eqnKPBJFqgWmiK2k= -cloud.google.com/go/notebooks v1.10.1/go.mod h1:5PdJc2SgAybE76kFQCWrTfJolCOUQXF97e+gteUUA6A= -cloud.google.com/go/notebooks v1.11.2/go.mod h1:z0tlHI/lREXC8BS2mIsUeR3agM1AkgLiS+Isov3SS70= -cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= -cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= -cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= -cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk= -cloud.google.com/go/optimization v1.5.0/go.mod h1:evo1OvTxeBRBu6ydPlrIRizKY/LJKo/drDMMRKqGEUU= -cloud.google.com/go/optimization v1.5.1/go.mod h1:NC0gnUD5MWVAF7XLdoYVPmYYVth93Q6BUzqAq3ZwtV8= -cloud.google.com/go/optimization v1.6.2/go.mod h1:mWNZ7B9/EyMCcwNl1frUGEuY6CPijSkz88Fz2vwKPOY= -cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= -cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= -cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= -cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8= -cloud.google.com/go/orchestration v1.8.2/go.mod h1:T1cP+6WyTmh6LSZzeUhvGf0uZVmJyTx7t8z7Vg87+A0= -cloud.google.com/go/orchestration v1.8.4/go.mod h1:d0lywZSVYtIoSZXb0iFjv9SaL13PGyVOKDxqGxEf/qI= -cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= -cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= -cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= -cloud.google.com/go/orgpolicy v1.11.0/go.mod h1:2RK748+FtVvnfuynxBzdnyu7sygtoZa1za/0ZfpOs1M= -cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE= -cloud.google.com/go/orgpolicy v1.11.2/go.mod h1:biRDpNwfyytYnmCRWZWxrKF22Nkz9eNVj9zyaBdpm1o= -cloud.google.com/go/orgpolicy v1.11.4/go.mod h1:0+aNV/nrfoTQ4Mytv+Aw+stBDBjNf4d8fYRA9herfJI= -cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= -cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= -cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= -cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= -cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= -cloud.google.com/go/osconfig v1.12.0/go.mod h1:8f/PaYzoS3JMVfdfTubkowZYGmAhUCjjwnjqWI7NVBc= -cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE= -cloud.google.com/go/osconfig v1.12.2/go.mod h1:eh9GPaMZpI6mEJEuhEjUJmaxvQ3gav+fFEJon1Y8Iw0= -cloud.google.com/go/osconfig v1.12.4/go.mod h1:B1qEwJ/jzqSRslvdOCI8Kdnp0gSng0xW4LOnIebQomA= -cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= -cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= -cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= -cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= -cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= -cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs= -cloud.google.com/go/oslogin v1.11.0/go.mod h1:8GMTJs4X2nOAUVJiPGqIWVcDaF0eniEto3xlOxaboXE= -cloud.google.com/go/oslogin v1.11.1/go.mod h1:OhD2icArCVNUxKqtK0mcSmKL7lgr0LVlQz+v9s1ujTg= -cloud.google.com/go/oslogin v1.12.2/go.mod h1:CQ3V8Jvw4Qo4WRhNPF0o+HAM4DiLuE27Ul9CX9g2QdY= -cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= -cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= -cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I= -cloud.google.com/go/phishingprotection v0.8.2/go.mod h1:LhJ91uyVHEYKSKcMGhOa14zMMWfbEdxG032oT6ECbC8= -cloud.google.com/go/phishingprotection v0.8.4/go.mod h1:6b3kNPAc2AQ6jZfFHioZKg9MQNybDg4ixFd4RPZZ2nE= -cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= -cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= -cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= -cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= -cloud.google.com/go/policytroubleshooter v1.7.1/go.mod h1:0NaT5v3Ag1M7U5r0GfDCpUFkWd9YqpubBWsQlhanRv0= -cloud.google.com/go/policytroubleshooter v1.8.0/go.mod h1:tmn5Ir5EToWe384EuboTcVQT7nTag2+DuH3uHmKd1HU= -cloud.google.com/go/policytroubleshooter v1.9.0/go.mod h1:+E2Lga7TycpeSTj2FsH4oXxTnrbHJGRlKhVZBLGgU64= -cloud.google.com/go/policytroubleshooter v1.9.1/go.mod h1:MYI8i0bCrL8cW+VHN1PoiBTyNZTstCg2WUw2eVC4c4U= -cloud.google.com/go/policytroubleshooter v1.10.2/go.mod h1:m4uF3f6LseVEnMV6nknlN2vYGRb+75ylQwJdnOXfnv0= -cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= -cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= -cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= -cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= -cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA= -cloud.google.com/go/privatecatalog v0.9.2/go.mod h1:RMA4ATa8IXfzvjrhhK8J6H4wwcztab+oZph3c6WmtFc= -cloud.google.com/go/privatecatalog v0.9.4/go.mod h1:SOjm93f+5hp/U3PqMZAHTtBtluqLygrDrVO8X8tYtG0= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w= -cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= -cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= -cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= -cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= -cloud.google.com/go/pubsub v1.32.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= -cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= -cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= -cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= -cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= -cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= -cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= -cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= -cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= -cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= -cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= -cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= -cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU= -cloud.google.com/go/recaptchaenterprise/v2 v2.8.0/go.mod h1:QuE8EdU9dEnesG8/kG3XuJyNsjEqMlMzg3v3scCJ46c= -cloud.google.com/go/recaptchaenterprise/v2 v2.8.1/go.mod h1:JZYZJOeZjgSSTGP4uz7NlQ4/d1w5hGmksVgM0lbEij0= -cloud.google.com/go/recaptchaenterprise/v2 v2.8.3/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= -cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= -cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= -cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE= -cloud.google.com/go/recommendationengine v0.8.2/go.mod h1:QIybYHPK58qir9CV2ix/re/M//Ty10OxjnnhWdaKS1Y= -cloud.google.com/go/recommendationengine v0.8.4/go.mod h1:GEteCf1PATl5v5ZsQ60sTClUE0phbWmo3rQ1Js8louU= -cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= -cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= -cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= -cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= -cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= -cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA= -cloud.google.com/go/recommender v1.11.0/go.mod h1:kPiRQhPyTJ9kyXPCG6u/dlPLbYfFlkwHNRwdzPVAoII= -cloud.google.com/go/recommender v1.11.1/go.mod h1:sGwFFAyI57v2Hc5LbIj+lTwXipGu9NW015rkaEM5B18= -cloud.google.com/go/recommender v1.11.3/go.mod h1:+FJosKKJSId1MBFeJ/TTyoGQZiEelQQIZMKYYD8ruK4= -cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= -cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= -cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= -cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= -cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= -cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg= -cloud.google.com/go/redis v1.13.2/go.mod h1:0Hg7pCMXS9uz02q+LoEVl5dNHUkIQv+C/3L76fandSA= -cloud.google.com/go/redis v1.14.1/go.mod h1:MbmBxN8bEnQI4doZPC1BzADU4HGocHBk2de3SbgOkqs= -cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= -cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= -cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= -cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= -cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= -cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8= -cloud.google.com/go/resourcemanager v1.9.2/go.mod h1:OujkBg1UZg5lX2yIyMo5Vz9O5hf7XQOSV7WxqxxMtQE= -cloud.google.com/go/resourcemanager v1.9.4/go.mod h1:N1dhP9RFvo3lUfwtfLWVxfUWq8+KUQ+XLlHLH3BoFJ0= -cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= -cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= -cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= -cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw= -cloud.google.com/go/resourcesettings v1.6.2/go.mod h1:mJIEDd9MobzunWMeniaMp6tzg4I2GvD3TTmPkc8vBXk= -cloud.google.com/go/resourcesettings v1.6.4/go.mod h1:pYTTkWdv2lmQcjsthbZLNBP4QW140cs7wqA3DuqErVI= -cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= -cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= -cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= -cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= -cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= -cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE= -cloud.google.com/go/retail v1.14.2/go.mod h1:W7rrNRChAEChX336QF7bnMxbsjugcOCPU44i5kbLiL8= -cloud.google.com/go/retail v1.14.4/go.mod h1:l/N7cMtY78yRnJqp5JW8emy7MB1nz8E4t2yfOmklYfg= -cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= -cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= -cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= -cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= -cloud.google.com/go/run v1.2.0/go.mod h1:36V1IlDzQ0XxbQjUx6IYbw8H3TJnWvhii963WW3B/bo= -cloud.google.com/go/run v1.3.0/go.mod h1:S/osX/4jIPZGg+ssuqh6GNgg7syixKe3YnprwehzHKU= -cloud.google.com/go/run v1.3.1/go.mod h1:cymddtZOzdwLIAsmS6s+Asl4JoXIDm/K1cpZTxV4Q5s= -cloud.google.com/go/run v1.3.3/go.mod h1:WSM5pGyJ7cfYyYbONVQBN4buz42zFqwG67Q3ch07iK4= -cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= -cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= -cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= -cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= -cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= -cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= -cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo= -cloud.google.com/go/scheduler v1.10.2/go.mod h1:O3jX6HRH5eKCA3FutMw375XHZJudNIKVonSCHv7ropY= -cloud.google.com/go/scheduler v1.10.4/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= -cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= -cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= -cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= -cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= -cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw= -cloud.google.com/go/secretmanager v1.11.2/go.mod h1:MQm4t3deoSub7+WNwiC4/tRYgDBHJgJPvswqQVB1Vss= -cloud.google.com/go/secretmanager v1.11.4/go.mod h1:wreJlbS9Zdq21lMzWmJ0XhWW2ZxgPeahsqeV/vZoJ3w= -cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= -cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= -cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= -cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= -cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= -cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= -cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= -cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA= -cloud.google.com/go/security v1.15.2/go.mod h1:2GVE/v1oixIRHDaClVbHuPcZwAqFM28mXuAKCfMgYIg= -cloud.google.com/go/security v1.15.4/go.mod h1:oN7C2uIZKhxCLiAAijKUCuHLZbIt/ghYEo8MqwD/Ty4= -cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= -cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= -cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= -cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= -cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= -cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= -cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ= -cloud.google.com/go/securitycenter v1.23.1/go.mod h1:w2HV3Mv/yKhbXKwOCu2i8bCuLtNP1IMHuiYQn4HJq5s= -cloud.google.com/go/securitycenter v1.24.2/go.mod h1:l1XejOngggzqwr4Fa2Cn+iWZGf+aBLTXtB/vXjy5vXM= -cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= -cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= -cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= -cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= -cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= -cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= -cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= -cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= -cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= -cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= -cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= -cloud.google.com/go/servicedirectory v1.10.1/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= -cloud.google.com/go/servicedirectory v1.11.0/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= -cloud.google.com/go/servicedirectory v1.11.1/go.mod h1:tJywXimEWzNzw9FvtNjsQxxJ3/41jseeILgwU/QLrGI= -cloud.google.com/go/servicedirectory v1.11.3/go.mod h1:LV+cHkomRLr67YoQy3Xq2tUXBGOs5z5bPofdq7qtiAw= -cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= -cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= -cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= -cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= -cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= -cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= -cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= -cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= -cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= -cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= -cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= -cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g= -cloud.google.com/go/shell v1.7.2/go.mod h1:KqRPKwBV0UyLickMn0+BY1qIyE98kKyI216sH/TuHmc= -cloud.google.com/go/shell v1.7.4/go.mod h1:yLeXB8eKLxw0dpEmXQ/FjriYrBijNsONpwnWsdPqlKM= -cloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk= -cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= -cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= -cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= -cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI= -cloud.google.com/go/spanner v1.49.0/go.mod h1:eGj9mQGK8+hkgSVbHNQ06pQ4oS+cyc4tXXd6Dif1KoM= -cloud.google.com/go/spanner v1.50.0/go.mod h1:eGj9mQGK8+hkgSVbHNQ06pQ4oS+cyc4tXXd6Dif1KoM= -cloud.google.com/go/spanner v1.51.0/go.mod h1:c5KNo5LQ1X5tJwma9rSQZsXNBDNvj4/n8BVc3LNahq0= -cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= -cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= -cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= -cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= -cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= -cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= -cloud.google.com/go/speech v1.17.1/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= -cloud.google.com/go/speech v1.19.0/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= -cloud.google.com/go/speech v1.19.1/go.mod h1:WcuaWz/3hOlzPFOVo9DUsblMIHwxP589y6ZMtaG+iAA= -cloud.google.com/go/speech v1.20.1/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= -cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= -cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= -cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= -cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= -cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= -cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= -cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA= -cloud.google.com/go/storagetransfer v1.10.1/go.mod h1:rS7Sy0BtPviWYTTJVWCSV4QrbBitgPeuK4/FKa4IdLs= -cloud.google.com/go/storagetransfer v1.10.3/go.mod h1:Up8LY2p6X68SZ+WToswpQbQHnJpOty/ACcMafuey8gc= -cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= -cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= -cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= -cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= -cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= -cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24= -cloud.google.com/go/talent v1.6.3/go.mod h1:xoDO97Qd4AK43rGjJvyBHMskiEf3KulgYzcH6YWOVoo= -cloud.google.com/go/talent v1.6.5/go.mod h1:Mf5cma696HmE+P2BWJ/ZwYqeJXEeU0UqjHFXVLadEDI= -cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= -cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= -cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= -cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk= -cloud.google.com/go/texttospeech v1.7.2/go.mod h1:VYPT6aTOEl3herQjFHYErTlSZJ4vB00Q2ZTmuVgluD4= -cloud.google.com/go/texttospeech v1.7.4/go.mod h1:vgv0002WvR4liGuSd5BJbWy4nDn5Ozco0uJymY5+U74= -cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= -cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= -cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= -cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E= -cloud.google.com/go/tpu v1.6.2/go.mod h1:NXh3NDwt71TsPZdtGWgAG5ThDfGd32X1mJ2cMaRlVgU= -cloud.google.com/go/tpu v1.6.4/go.mod h1:NAm9q3Rq2wIlGnOhpYICNI7+bpBebMJbh0yyp3aNw1Y= -cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= -cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= -cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= -cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= -cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk= -cloud.google.com/go/trace v1.10.2/go.mod h1:NPXemMi6MToRFcSxRl2uDnu/qAlAQ3oULUphcHGh1vA= -cloud.google.com/go/trace v1.10.4/go.mod h1:Nso99EDIK8Mj5/zmB+iGr9dosS/bzWCJ8wGmE6TXNWY= -cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= -cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= -cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= -cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= -cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= -cloud.google.com/go/translate v1.8.1/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= -cloud.google.com/go/translate v1.8.2/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= -cloud.google.com/go/translate v1.9.0/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= -cloud.google.com/go/translate v1.9.1/go.mod h1:TWIgDZknq2+JD4iRcojgeDtqGEp154HN/uL6hMvylS8= -cloud.google.com/go/translate v1.9.3/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= -cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= -cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= -cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= -cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= -cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= -cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= -cloud.google.com/go/video v1.17.1/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= -cloud.google.com/go/video v1.19.0/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= -cloud.google.com/go/video v1.20.0/go.mod h1:U3G3FTnsvAGqglq9LxgqzOiBc/Nt8zis8S+850N2DUM= -cloud.google.com/go/video v1.20.1/go.mod h1:3gJS+iDprnj8SY6pe0SwLeC5BUW80NjhwX7INWEuWGU= -cloud.google.com/go/video v1.20.3/go.mod h1:TnH/mNZKVHeNtpamsSPygSR0iHtvrR/cW1/GDjN5+GU= -cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= -cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= -cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= -cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= -cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= -cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo= -cloud.google.com/go/videointelligence v1.11.2/go.mod h1:ocfIGYtIVmIcWk1DsSGOoDiXca4vaZQII1C85qtoplc= -cloud.google.com/go/videointelligence v1.11.4/go.mod h1:kPBMAYsTPFiQxMLmmjpcZUMklJp3nC9+ipJJtprccD8= -cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= -cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= -cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= -cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= -cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= -cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= -cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= -cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU= -cloud.google.com/go/vision/v2 v2.7.3/go.mod h1:V0IcLCY7W+hpMKXK1JYE0LV5llEqVmj+UJChjvA1WsM= -cloud.google.com/go/vision/v2 v2.7.5/go.mod h1:GcviprJLFfK9OLf0z8Gm6lQb6ZFUulvpZws+mm6yPLM= -cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= -cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= -cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= -cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= -cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro= -cloud.google.com/go/vmmigration v1.7.2/go.mod h1:iA2hVj22sm2LLYXGPT1pB63mXHhrH1m/ruux9TwWLd8= -cloud.google.com/go/vmmigration v1.7.4/go.mod h1:yBXCmiLaB99hEl/G9ZooNx2GyzgsjKnw5fWcINRgD70= -cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= -cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= -cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= -cloud.google.com/go/vmwareengine v0.4.1/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= -cloud.google.com/go/vmwareengine v1.0.0/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= -cloud.google.com/go/vmwareengine v1.0.1/go.mod h1:aT3Xsm5sNx0QShk1Jc1B8OddrxAScYLwzVoaiXfdzzk= -cloud.google.com/go/vmwareengine v1.0.3/go.mod h1:QSpdZ1stlbfKtyt6Iu19M6XRxjmXO+vb5a/R6Fvy2y4= -cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= -cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= -cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= -cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs= -cloud.google.com/go/vpcaccess v1.7.2/go.mod h1:mmg/MnRHv+3e8FJUjeSibVFvQF1cCy2MsFaFqxeY1HU= -cloud.google.com/go/vpcaccess v1.7.4/go.mod h1:lA0KTvhtEOb/VOdnH/gwPuOzGgM+CWsmGu6bb4IoMKk= -cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= -cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= -cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= -cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= -cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= -cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc= -cloud.google.com/go/webrisk v1.9.2/go.mod h1:pY9kfDgAqxUpDBOrG4w8deLfhvJmejKB0qd/5uQIPBc= -cloud.google.com/go/webrisk v1.9.4/go.mod h1:w7m4Ib4C+OseSr2GL66m0zMBywdrVNTDKsdEsfMl7X0= -cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= -cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= -cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= -cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg= -cloud.google.com/go/websecurityscanner v1.6.2/go.mod h1:7YgjuU5tun7Eg2kpKgGnDuEOXWIrh8x8lWrJT4zfmas= -cloud.google.com/go/websecurityscanner v1.6.4/go.mod h1:mUiyMQ+dGpPPRkHgknIZeCzSHJ45+fY4F52nZFDHm2o= -cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= -cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= -cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= -cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= -cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= -cloud.google.com/go/workflows v1.12.0/go.mod h1:PYhSk2b6DhZ508tj8HXKaBh+OFe+xdl0dHF/tJdzPQM= -cloud.google.com/go/workflows v1.12.1/go.mod h1:5A95OhD/edtOhQd/O741NSfIMezNTbCwLM1P1tBRGHM= -cloud.google.com/go/workflows v1.12.3/go.mod h1:fmOUeeqEwPzIU81foMjTRQIdwQHADi/vEr1cx9R1m5g= -code.gitea.io/sdk/gitea v0.12.0/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY= -contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0= -contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0= -contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw= -contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= -contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= -contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= -github.com/Abirdcfly/dupword v0.0.9/go.mod h1:PzmHVLLZ27MvHSzV7eFmMXSFArWXZPZmfuuziuUrf2g= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= -github.com/AkihiroSuda/containerd-fuse-overlayfs v1.0.0/go.mod h1:0mMDvQFeLbbn1Wy8P2j3hwFhqBq+FKn8OZPno8WLmp8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= -github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= -github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= -github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v19.1.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v29.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v42.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0/go.mod h1:ceIuwmxDWptoW3eCqSXlnPsZFKh4X+R38dWPv7GS9Vs= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0/go.mod h1:s1tW/At+xHqjNFvWU4G0c0Qv33KOhvbGNj0RCTQDV8s= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0/go.mod h1:c+Lifp3EDEamAkPVzMooRNOK6CZjNSdEnf1A7jsI9u4= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1/go.mod h1:eZ4g6GUvXiGulfIbbhh1Xr4XwUYaYaWMqzGD/284wCA= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0/go.mod h1:+6KLcKIVgxoBDMqMO/Nvy7bZ9a0nbU3I1DtFQK3YvB4= -github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0= -github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v10.15.5+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v14.1.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= -github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= -github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= -github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= -github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= -github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= -github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= -github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= -github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= -github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= -github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= -github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= -github.com/AzureAD/microsoft-authentication-library-for-go v0.6.0/go.mod h1:BDJ5qMFKx9DugEg3+uQSDCdbYPr5s9vBTrL9P8TpqOU= -github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= -github.com/CloudyKit/jet/v6 v6.1.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= -github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190129172621-c8b1d7a94ddf/go.mod h1:aJ4qN3TfrelA6NZ6AXsXRfmEVaYin3EDbSPJrKS8OXo= -github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= -github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= -github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/KarpelesLab/reflink v0.0.2/go.mod h1:mB+2afhyn+eZTMFSH1gXunrgArTsiUBzfoAy0X2fatA= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20221202121132-bd37e8fb1d0d/go.mod h1:BSKhCg8phwi9taTm849mjagbJqs5fpFFXCc6uH4qaT4= -github.com/MariusVanDerWijden/tx-fuzz v1.0.2/go.mod h1:jrK+Lr2mr1+6Pm3LlQ6rGHgK3WRQ9VMTiX+2mPMe6ys= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/go-winio v0.4.15-0.20200908182639-5b44b70ab3ab/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= -github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= -github.com/Microsoft/hcsshim v0.8.10/go.mod h1:g5uw8EV2mAlzqe94tfNBNdr89fnbD/n3HV0OhsddkmM= -github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= -github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= -github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= -github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= -github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= -github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= -github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= -github.com/Microsoft/hcsshim v0.9.3/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= -github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= -github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= -github.com/Microsoft/hcsshim/test v0.0.0-20200826032352-301c83a30e7c/go.mod h1:30A5igQ91GEmhYJF8TaRP79pMBOYynRsyOByfVV0dU4= -github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= -github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= -github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= -github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= -github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= -github.com/VictoriaMetrics/fastcache v1.12.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/aclements/go-gg v0.0.0-20170118225347-6dbb4e4fefb0/go.mod h1:55qNq4vcpkIuHowELi5C8e+1yUHtoLoOUR9QU5j7Tes= -github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY= -github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= -github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= -github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/ajstarks/svgo v0.0.0-20210923152817-c3b6e2f0c527/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= -github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= -github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= -github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= -github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= -github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= -github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= -github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= -github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= -github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= -github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg= +github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= -github.com/apex/log v1.1.4/go.mod h1:AlpoD9aScyQfJDVHmLMEcx4oU6LqzkWp4Mg9GdAcEvQ= -github.com/apex/log v1.3.0/go.mod h1:jd8Vpsr46WAe3EZSQ/IUMs2qQD/GOycT5rPWCO1yGcs= -github.com/apex/logs v0.0.4/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo= -github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= -github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks= github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= github.com/aristanetworks/goarista v0.0.0-20200521140103-6c3304613b30/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE= -github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE= github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/ashanbrown/forbidigo v1.4.0/go.mod h1:IvgwB5Y4fzqSAj/WVXKWigoTkB0dzI2FBbpKWuh7ph8= -github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.15.90/go.mod h1:es1KtYUFs7le0xQ3rOihkuoVD90z7D0fR2Qm4S00/gU= -github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.19.45/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.25.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.31.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= -github.com/aws/aws-sdk-go-v2 v1.16.3/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= +github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= -github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7AwGuk= -github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1/go.mod h1:n8Bs1ElDD2wJ9kCRTczA83gYbBmjSwZp3umc6zF4EeM= -github.com/aws/aws-sdk-go-v2/config v1.15.5/go.mod h1:ZijHHh0xd/A+ZY53az0qzC5tT46kt4JVCePf2NX9Lk4= +github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA= +github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= +github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= github.com/aws/aws-sdk-go-v2/config v1.18.45 h1:Aka9bI7n8ysuwPeFdm77nfbyHCAKQ3z9ghB3S/38zes= github.com/aws/aws-sdk-go-v2/config v1.18.45/go.mod h1:ZwDUgFnQgsazQTnWfeLWk5GjeqTQTL8lMkoE1UXzxdE= -github.com/aws/aws-sdk-go-v2/credentials v1.12.0/go.mod h1:9YWk7VW+eyKsoIL6/CljkTrNVWBSK9pkqOPUuijid4A= +github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= github.com/aws/aws-sdk-go-v2/credentials v1.13.43 h1:LU8vo40zBlo3R7bAvBVy/ku4nxGEyZe9N8MqAeFTzF8= github.com/aws/aws-sdk-go-v2/credentials v1.13.43/go.mod h1:zWJBz1Yf1ZtX5NGax9ZdNjhhI4rgjfgsyk6vTY1yfVg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4/go.mod h1:u/s5/Z+ohUQOPXl00m2yJVyioWDECsbpXTQlaqSlufc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 h1:PIktER+hwIG286DqXyvVENjgLTAwGgoeriLDD5C+YlQ= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13/go.mod h1:f/Ib/qYjhV2/qdsf79H3QP/eRE4AkVyEf6sk7XfZ1tg= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.10/go.mod h1:p+ul5bLZSDRRXCZ/vePvfmZBH9akozXBJA5oMshWa5U= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10/go.mod h1:F+EZtuIwjlv35kRJPyBGcsA4f7bnSoz15zOQ2lJq1Z4= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9/go.mod h1:Xjqy+Nyj7VDLBtCMkQYOw1QYfAEZCVLrfI0ezve8wd4= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4/go.mod h1:8glyUqVIM4AmeenIsPo0oVh3+NUwnsQml2OFupfQW+0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 h1:aw39xVGeRWlWx9EzGVnhOR4yOjQDHPQ6o6NmBlscyQg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5/go.mod h1:FSaRudD0dXiMPK2UjknVwwTYyZMRsHv3TtkabsZih5I= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 h1:N94sVhRACtXyVcjXxrwK1SKFIJrA9pOJ5yu2eSHnmls= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9/go.mod h1:hqamLz7g1/4EJP+GH5NBhcUMLjW+gKLQabgyz6/7WAU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11/go.mod h1:0MR+sS1b/yxsfAPvAESrw8NfwUoxMinDyw6EYR9BS2U= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 h1:PG1F3OD1szkuQPzDw3CIQsRIrtTlUC3lP84taWzHlq0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5/go.mod h1:jU1li6RFryMz+so64PpKtudI+QzbKoIEivqdf6LNpOc= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 h1:hze8YsjSh8Wl1rYa1CJpRmXP21BvOBuc76YhW0HsuQ4= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.1/go.mod h1:l/BbcfqDCT3hePawhy4ZRtewjtdkl6GWtd9/U+1penQ= -github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1/go.mod h1:GeUru+8VzrTXV/83XyMJ80KpH8xO89VPoUileyNQ+tc= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.5/go.mod h1:S8TVP66AAkMMdYYCNZGvrdEq9YRm+qLXjio4FqRnrEE= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4/go.mod h1:uKkN7qmSIsNJVyMtxNQoCEYMvFEXbOg9fwCJPdfp2u8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37 h1:WWZA/I2K4ptBS1kg0kV1JbBtG/umed0vwHRrmcr9z7k= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.4/go.mod h1:oudbsSdDtazNj47z1ut1n37re9hDsKpk2ZI3v7KSxq0= -github.com/aws/aws-sdk-go-v2/service/route53 v1.30.2/go.mod h1:TQZBt/WaQy+zTHoW++rnl8JBrmZ0VO6EUbVua1+foCA= -github.com/aws/aws-sdk-go-v2/service/s3 v1.26.9/go.mod h1:iMYipLPXlWpBJ0KFX7QJHZ84rBydHBY8as2aQICTPWk= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.25.4 h1:gsiwBC1ca43hCwyYilWEsC1y/NSkLj9fGyIV7pRt42U= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.25.4/go.mod h1:4Ae1NCLK6ghmjzd45Tc33GgCKhUWD2ORAlULtMO1Cbs= -github.com/aws/aws-sdk-go-v2/service/sso v1.11.4/go.mod h1:cPDwJwsP4Kff9mldCXAmddjJL6JGQqtA3Mzer2zyr88= +github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.6 h1:TIOEjw0i2yyhmhRry3Oeu9YtiiHWISZ6j/irS1W3gX4= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.6/go.mod h1:3Ba++UwWd154xtP4FRX5pUK3Gt4up5sDHCve6kVfE+g= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 h1:JuPGc7IkOP4AaqcZSIcyqLpFSqBWK32rM9+a1g6u73k= github.com/aws/aws-sdk-go-v2/service/sso v1.15.2/go.mod h1:gsL4keucRCgW+xA85ALBpRFfdSLH4kHOVSnLMSuBECo= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 h1:HFiiRkf1SdaAmV3/BHOFZ9DjFynPHj8G/UIO1lQS+fk= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3/go.mod h1:a7bHA82fyUXOm+ZSWKU6PIoBxrjSprdLoM8xPYvzYVg= -github.com/aws/aws-sdk-go-v2/service/sts v1.16.4/go.mod h1:lfSYenAXtavyX2A1LsViglqlG9eEFYxNryTZS5rn3QE= +github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 h1:0BkLfgeDjfZnZ+MhB3ONb01u9pwFYTCZVhlsSSBvlbU= github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= -github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= +github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= -github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= -github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= +github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= +github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/bazelbuild/rules_go v0.23.2 h1:Wxu7JjqnF78cKZbsBsARLSXx/jlGaSLCnUV3mTlyHvM= github.com/bazelbuild/rules_go v0.23.2/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M= github.com/benbjohnson/clock v1.0.2/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= @@ -1398,65 +169,41 @@ github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= -github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= -github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= -github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= -github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/bnb-chain/greenfield-cometbft v1.0.0 h1:0r6hOJWD/+es0gxP/exKuN/krgXAr3LCn5/XlcgDWr8= github.com/bnb-chain/greenfield-cometbft v1.0.0/go.mod h1:f35mk/r5ab6yvzlqEWZt68LfUje68sYgMpVlt2CUYMk= -github.com/bnb-chain/op-geth v0.3.0-alpha h1:4bxV3Z6iDrWWUkErl9eRUmZ/f2SFdy8dPwARTbQebVw= -github.com/bnb-chain/op-geth v0.3.0-alpha/go.mod h1:GgNSaFvHsvsF+9YBwnQAbMrmEdtUJs5qJuB6H+x1Lho= -github.com/bombsimon/wsl/v2 v2.0.0/go.mod h1:mf25kr/SqFEPhhcxW1+7pxzGlW+hIl/hYTKY95VwV8U= -github.com/bombsimon/wsl/v2 v2.2.0/go.mod h1:Azh8c3XGEJl9LyX0/sFC+CKMc7Ssgua0g+6abzXN4Pg= -github.com/bombsimon/wsl/v3 v3.0.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= -github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= -github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo= -github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= -github.com/breml/bidichk v0.2.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc70T2A= -github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU= -github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= -github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= -github.com/btcsuite/btcd v0.23.3 h1:4KH/JKy9WiCd+iUS9Mu0Zp7Dnj17TGdKrg9xc/FGj24= -github.com/btcsuite/btcd v0.23.3/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= +github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= +github.com/btcsuite/btcd v0.24.0 h1:gL3uHE/IaFj6fcZSu03SvqPMSx7s/dPzfpG/atRwWdo= +github.com/btcsuite/btcd v0.24.0/go.mod h1:K4IDc1593s8jKXIF7yS7yCTSxrknB9z0STzc2j6XgE4= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= -github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= -github.com/btcsuite/btcd/btcutil v1.1.2/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= +github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= @@ -1470,319 +217,95 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/bufbuild/buf v1.7.0/go.mod h1:Go40fMAF46PnPLC7jJgTQhAI95pmC0+VtxFKVC0qLq0= -github.com/bufbuild/connect-go v0.2.0/go.mod h1:4efZ2eXFENwd4p7tuLaL9m0qtTsCOzuBvrohvRGevDM= -github.com/bufbuild/connect-go v1.0.0/go.mod h1:9iNvh/NOsfhNBUH5CtvXeVUskQO1xsrEviH7ZArwZ3I= -github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw= -github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo= +github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= -github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= -github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348/go.mod h1:f/miWtG3SSuTxKsNK3o58H1xl+XV6ZIfbC6p7lPPB8U= -github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= -github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= -github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= -github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U= -github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= -github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= -github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= -github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= -github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= -github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= -github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= -github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= -github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= -github.com/cloudflare/cloudflare-go v0.79.0/go.mod h1:gkHQf9xEubaQPEuerBuoinR9P8bf8a05Lq0X6WKy1Oc= +github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230428030218-4003588d1b74/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877 h1:1MLK4YpFtIEo3ZtMA5C795Wtv5VuUnrXX7mQG+aHg6o= -github.com/cockroachdb/datadriven v1.0.3-0.20230801171734-e384cf455877/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= -github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= -github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20230906160148-46873a6a7a06/go.mod h1:bynZ3gvVyhlvjLI7PT6dmZ7g76xzJ7HpxfjgkzCGz6s= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4 h1:PuHFhOUMnD62r80dN+Ik5qco2drekgsUSVdcHsvllec= github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4/go.mod h1:sEHm5NOXxyiAoKWhoFxT8xMgd/f3RA6qUqQ1BXKrh2E= -github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= +github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= -github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= -github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= -github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= -github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E= -github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= -github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= -github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= -github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= -github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= -github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= -github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= -github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= -github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= -github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= -github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= -github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.1-0.20201117152358-0edc412565dc/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ= -github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= -github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= -github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= -github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= -github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= -github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= -github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0NpumIq9ODB0kLtoE= -github.com/containerd/containerd v1.6.3-0.20220401172941-5ff8fce1fcc6/go.mod h1:WSt2SnDLAGWlu+Vl+EWay37seZLKqgRt6XLjIMy8SYM= -github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0= -github.com/containerd/containerd v1.6.9/go.mod h1:XVicUvkxOrftE2Q1YWUXgZwkkAxwQYNOFzYWvfVfEfQ= -github.com/containerd/containerd v1.6.18/go.mod h1:1RdCUu95+gc2v9t3IL+zIlpClSmew7/0YS8O5eQZrOw= -github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= -github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= -github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= -github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= -github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= -github.com/containerd/continuity v0.2.3-0.20220330195504-d132b287edc8/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= -github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= -github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= -github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= -github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= -github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= -github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= -github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= -github.com/containerd/fuse-overlayfs-snapshotter v1.0.2/go.mod h1:nRZceC8a7dRm3Ao6cJAwuJWPFiBPaibHiFntRUnzhwU= -github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= -github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= -github.com/containerd/go-cni v1.1.0/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= -github.com/containerd/go-cni v1.1.3/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= -github.com/containerd/go-cni v1.1.4/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= -github.com/containerd/go-cni v1.1.6/go.mod h1:BWtoWl5ghVymxu6MBjg79W9NZrCRyHIdUtk4cauMe34= -github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= -github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= -github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= -github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= -github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= -github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0= -github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= -github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= -github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= -github.com/containerd/imgcrypt v1.1.3/go.mod h1:/TPA1GIDXMzbj01yd8pIbQiLdQxed5ue1wb8bP7PQu4= -github.com/containerd/imgcrypt v1.1.4/go.mod h1:LorQnPtzL/T0IyCeftcsMEO7AqxUDbdO8j/tSUpgxvo= -github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= -github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= -github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= -github.com/containerd/nydus-snapshotter v0.3.1/go.mod h1:+8R7NX7vrjlxAgtidnsstwIhpzyTlriYPssTxH++uiM= -github.com/containerd/stargz-snapshotter v0.0.0-20201027054423-3a04e4c2c116/go.mod h1:o59b3PCKVAf9jjiKtCc/9hLAd+5p/rfhBfm6aBcTEr4= -github.com/containerd/stargz-snapshotter v0.11.3/go.mod h1:2j2EAUyvrLU4D9unYlTIwGhDKQIk74KJ9E71lJsQCVM= -github.com/containerd/stargz-snapshotter v0.13.0/go.mod h1:01uOvoNzN1T4kV+8HeVt9p29esO5/61x8+VP/KU4fvQ= -github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= -github.com/containerd/stargz-snapshotter/estargz v0.11.3/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0= -github.com/containerd/stargz-snapshotter/estargz v0.11.4/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0= -github.com/containerd/stargz-snapshotter/estargz v0.13.0/go.mod h1:m+9VaGJGlhCnrcEUod8mYumTmRgblwd3rC5UCEh2Yp0= -github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= -github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= -github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= -github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= -github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= -github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= -github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= -github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= -github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= -github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw= -github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y= -github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= -github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= -github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= -github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y= -github.com/containernetworking/cni v1.1.1/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= -github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= -github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= -github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE= -github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8= -github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= -github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= -github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= -github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= -github.com/containers/ocicrypt v1.1.3/go.mod h1:xpdkbVAuaH3WzbEabUd5yDsl9SwJA5pABH85425Es2g= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= -github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= -github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.4.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= +github.com/cosmos/gogoproto v1.4.1 h1:WoyH+0/jbCTzpKNvyav5FL1ZTWsp1im1MxEpJEzKUB8= github.com/cosmos/gogoproto v1.4.1/go.mod h1:Ac9lzL4vFpBMcptJROQ6dQ4M3pOEK5Z/l0Q9p+LoCr4= -github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= -github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-ipa v0.0.0-20230601170251-1830d0757c80 h1:DuBDHVjgGMPki7bAyh91+3cF1Vh34sAEdH8JQgbc2R0= -github.com/crate-crypto/go-ipa v0.0.0-20230601170251-1830d0757c80/go.mod h1:gzbVz57IDJgQ9rLQwfSk696JGWof8ftznEL9GoAv3NI= -github.com/crate-crypto/go-kzg-4844 v0.3.0/go.mod h1:SBP7ikXEgDnUPONgm33HtuDZEDtWa3L4QtN1ocJSEQ4= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= -github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= -github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= -github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= -github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= -github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= -github.com/daixiang0/gci v0.9.1/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= -github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= -github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= -github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -1791,95 +314,43 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= +github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= -github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= -github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= -github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= -github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= -github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018/go.mod h1:MIonLggsKgZLUSt414ExgwNtlOL5MuEoAJP514mwGe8= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= -github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= -github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/cli v0.0.0-20190925022749-754388324470/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.0-beta1.0.20201029214301-1d20b15adc38+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.13+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.14+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.21+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v23.0.0-rc.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= -github.com/docker/distribution v2.6.0-rc.1.0.20180327202408-83389a148052+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.0.0-20200511152416-a93e9eb0e95c/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v1.4.2-0.20180531152204-71cd53e4a197/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v17.12.0-ce-rc1.0.20200730172259-9f28837c1d93+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.0-beta1.0.20201110211921-af34b94a78a1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.3-0.20211208011758-87521affb077+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v23.0.0-rc.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= -github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= -github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= -github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= -github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/libnetwork v0.8.0-dev.2.0.20200917202933-d0951081b35f/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8= -github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo= github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= @@ -1889,346 +360,158 @@ github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:Htrtb github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/dvyukov/go-fuzz v0.0.0-20220726122315-1d375ef9f9f6/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/dot v0.11.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= -github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= -github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= -github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= -github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= -github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= -github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= -github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= -github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= -github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= -github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= -github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492 h1:FyzLzMLKMc9zcDYcSxbrLDglIRrGQJE9juFzIO35RmE= -github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492/go.mod h1:/70H/KqrtKcvWvNGVj6S3rAcLC+kUPr3t2aDmYIS+Xk= -github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240306093353-c557df8e6f41 h1:WKJvsRyW/YNgyT0P2x5U530ITOY8Dv9TrZnbliqSXd8= +github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240306093353-c557df8e6f41/go.mod h1:7xh2awFQqsiZxFrHKTgEd+InVfDRrkKVUIuK8SAFHp0= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= +github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/ferranbt/fastssz v0.0.0-20210120143747-11b9eff30ea9/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM= github.com/ferranbt/fastssz v0.0.0-20210905181407-59cf6761a7d5 h1:6dVcS0LktRSyEEgldFY4N9J17WjUoiJStttH+RZj0Wo= github.com/ferranbt/fastssz v0.0.0-20210905181407-59cf6761a7d5/go.mod h1:S8yiDeAXy8f88W4Ul+0dBMPx49S05byYbmZD6Uv94K4= -github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= -github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fjl/memsize v0.0.1 h1:+zhkb+dhUgx0/e+M8sF0QqiouvMQUiKR+QYvdxIOKcQ= github.com/fjl/memsize v0.0.1/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= -github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.3-0.20170329110642-4da3e2cfbabc/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= -github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM= -github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= -github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= -github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.1.1-0.20170914051019-70e1b1943d4f/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/gballet/go-verkle v0.0.0-20230607174250-df487255f46b h1:vMT47RYsrftsHSTQhqXwC3BYflo38OLC3Y4LtXtLyU0= -github.com/gballet/go-verkle v0.0.0-20230607174250-df487255f46b/go.mod h1:CDncRYVRSDqwakm282WEkjfaAj1hxU/v5RXxk5nXOiI= -github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= -github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1/go.mod h1:Az6Jt+M5idSED2YPGtwnfJV0kXohgdCBPmHGSYc1r04= -github.com/gdamore/tcell/v2 v2.5.3/go.mod h1:wSkrPaXoiIWZqW/g7Px4xc79di6FTcpB8tvaKJ6uGBo= -github.com/gdamore/tcell/v2 v2.6.0/go.mod h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= -github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= +github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= -github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= +github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/docgen v1.2.0 h1:da0Nq2PKU9W9pSOTUfVrKI1vIgTGpauo9cfh4Iwivek= github.com/go-chi/docgen v1.2.0/go.mod h1:G9W0G551cs2BFMSn/cnGwX+JBHEloAgo17MBhyrnhPI= github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns= -github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g= -github.com/go-critic/go-critic v0.4.3/go.mod h1:j4O3D4RoIwRqlZw5jJpx0BNfXWWbpcJoKu5cYSe4YmQ= -github.com/go-critic/go-critic v0.6.7/go.mod h1:fYZUijFdcnxgx6wPjQA2QEjIRaNCT0gO8bhexy6/QmE= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= -github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= -github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= -github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= -github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-billy/v5 v5.4.0/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= -github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= -github.com/go-git/go-git/v5 v5.5.2/go.mod h1:BE5hUJ5yaV2YMxhmaP4l6RBQ08kMxKSPD4BlxtH7OjI= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= -github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= -github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.2.1/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= -github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= -github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4= -github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= -github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astcopy v1.0.2/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= -github.com/go-toolsmith/astcopy v1.0.3/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= -github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.2/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= -github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= -github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= -github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= -github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= -github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= -github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= -github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= -github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= -github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= -github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= -github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= -github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM= -github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= -github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= -github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= -github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= -github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gofrs/flock v0.7.3/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= -github.com/gogo/googleapis v1.3.2/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= -github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/gddo v0.0.0-20200528160355-8d077c1d8f4c/go.mod h1:sam69Hju0uq+5uvLJUMDlsKlQ21Vrs1Kd/1YFPNYdOU= +github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20170918230701-e5d664eb928e/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -2238,10 +521,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -2257,7 +538,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -2268,48 +548,12 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= -github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= -github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= -github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= -github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.23.7/go.mod h1:g/38bxfhp4rI7zeWSxcdIeHTQGS58TCak8FYcyCmavQ= -github.com/golangci/golangci-lint v1.27.0/go.mod h1:+eZALfxIuthdrHPtfM7w/R3POJLjHDfJJw8XZl9xOng= -github.com/golangci/golangci-lint v1.51.2/go.mod h1:KH9Q7/3glwpYSknxUgUyLlAv46A8fsSKo1hH2wDvkr8= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/misspell v0.4.0/go.mod h1:W6O/bwV6lGDxUCChm2ykw9NQdd5bYd1Xkjo88UcWyJc= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc= -github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg= -github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks= -github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A= -github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw= -github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs= -github.com/google/crfs v0.0.0-20191108021818-71d77da419c9/go.mod h1:etGhoOqfwPkooV6aqoX3eBGQOJblqdoc9XvWOeuxpPw= -github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.1.1-0.20171103154506-982329095285/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -2322,27 +566,14 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.0.0-20191010200024-a3d713f9b7f8/go.mod h1:KyKXa9ciM8+lgMXwOVsXi7UxGrsf9mM61Mzs+xKUrKE= -github.com/google/go-containerregistry v0.1.2/go.mod h1:GPivBPgdAyd2SU+vf6EpsgOtWDuPqjW0hJZt4rNdTZ4= -github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= -github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= -github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= -github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.1-0.20220503160820-4a35382e8fc8 h1:Ep/joEub9YwcjRY6ND3+Y/w0ncE540RtGatVhtZL0/Q= github.com/google/gofuzz v1.2.1-0.20220503160820-4a35382e8fc8/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -2350,11 +581,7 @@ github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8v github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -2363,163 +590,60 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg= -github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= -github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -github.com/google/safehtml v0.0.2/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw= -github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs16741s= -github.com/google/wire v0.4.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= -github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= -github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= -github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= -github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= -github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= -github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= -github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= -github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= -github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/goreleaser/goreleaser v0.136.0/go.mod h1:wiKrPUeSNh6Wu8nUHxZydSOVQ/OZvOaO7DTtFqie904= -github.com/goreleaser/nfpm v1.2.1/go.mod h1:TtWrABZozuLOttX2uDlYyECfQX7x5XYkVxhjYcR6G9w= -github.com/goreleaser/nfpm v1.3.0/go.mod h1:w0p7Kc9TAUgWMyrub63ex3M2Mgw88M4GZXoTq5UCb40= -github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= -github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= -github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= -github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= -github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= -github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= -github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= -github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= -github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= -github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= -github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= +github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/gregjones/httpcache v0.0.0-20170920190843-316c5e0ff04e/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.2/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1 h1:X2vfSnm1WC8HEo0MBHZg2TcuDUHJj6kd1TmEAQncnSA= github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1/go.mod h1:oVMjMN64nzEcepv1kdZKgx1qNYt4Ro0Gqefiq2JWdis= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= -github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= -github.com/guptarohit/asciigraph v0.5.5/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= -github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= -github.com/hanwen/go-fuse/v2 v2.0.3/go.mod h1:0EQM6aH2ctVpvZ6a+onrQ/vaykxh2GH7hy3e13vzTUY= -github.com/hanwen/go-fuse/v2 v2.1.1-0.20220112183258-f57e95bda82d/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -2528,40 +652,32 @@ github.com/hashicorp/go-bexpr v0.1.11 h1:6DqdA/KBjurGby9yTY0bmkathya0lfwF2SeuubC github.com/hashicorp/go-bexpr v0.1.11/go.mod h1:f03lAo0duBlDIUMGCuad8oLcgejw4m7U+N8T+6Kz1AE= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I= +github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack/v2 v2.1.1 h1:xQEY9yB2wnHitoSzk/B9UjXWRQ67QKu5AOm8aFp8N3I= +github.com/hashicorp/go-msgpack/v2 v2.1.1/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -2573,89 +689,65 @@ github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft v1.6.1 h1:v/jm5fcYHvVkL0akByAp+IDdDSzCNCGhdO6VdB56HIM= +github.com/hashicorp/raft v1.6.1/go.mod h1:N1sKh6Vn47mrWvEArQgILTyng8GoDRNYlgKyK7PMjs0= +github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e h1:SK4y8oR4ZMHPvwVHryKI88kJPJda4UyWYvG5A6iEQxc= +github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e/go.mod h1:EMz/UIuG93P0MBeHh6CbXQAEe8ckVJLZjhD17lBzK5Q= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c/go.mod h1:fHzc09UnyJyqyW+bFuq864eh+wC7dj65aXmXLRe5to0= github.com/herumi/bls-eth-go-binary v0.0.0-20210130185500-57372fb27371/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e h1:wCMygKUQhmcQAjlk2Gquzq6dLmyMv2kF+llRspoRgrk= github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/goevmlab v0.0.0-20221201133036-b31966a5267d/go.mod h1:tQJ4EfAokPShVDyEwKslIWKyt0qA/z8u+iK3kAwO424= -github.com/holiman/goevmlab v0.0.0-20221207202144-89074274e1b7/go.mod h1:t5n9hEKnVqrEclta+MoEDjI2D9X7bi8OiWGmyYuNhMk= -github.com/holiman/goevmlab v0.0.0-20230917164918-f3777d0b880b/go.mod h1:Xf54jEqUJ0PwTEF9Z6e8FSLpnLpyB0QUfdHA3you/sw= -github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= -github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= -github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= -github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= -github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/cgosymbolizer v0.0.0-20200424224625-be1b05b0b279/go.mod h1:a5aratAVTWyz+nJMmDsN8O4XTfaLfdAsB1ysCmZX5Bw= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= -github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= -github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/in-toto/in-toto-golang v0.5.0/go.mod h1:/Rq0IZHLV7Ku5gielPT4wPHJfH1GdHMCq8+WPxw8/BE= github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= +github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c h1:qSHzRbhzK8RdXOsAdfDgO49TtqC1oZ+acxPrkfTxcCs= github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= +github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 h1:vilfsDSy7TDxedi9gyBkMvAirat/oRcL0lFdJBf6tdM= github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/informalsystems/tm-load-test v1.3.0/go.mod h1:OQ5AQ9TbT5hKWBNIwsMjn6Bf4O0U4b1kRc+0qZlQJKw= -github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= +github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= +github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= +github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= +github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= -github.com/ipfs/go-datastore v0.5.1/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= @@ -2680,22 +772,8 @@ github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHn github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= github.com/ipfs/go-log/v2 v2.4.0/go.mod h1:nPZnh7Cj7lwS3LpRU5Mwr2ol1c2gXIEXuF6aywqrtmo= -github.com/ipfs/go-log/v2 v2.5.0/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/httpexpect/v2 v2.3.1/go.mod h1:ICTf89VBKSD3KB0fsyyHviKF8G8hyepP0dOXJPWz3T0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/jade v1.1.4/go.mod h1:EDqR+ur9piDl6DUgs6qRrlfzmlx/D5UybogqrXvJTBE= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= -github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= -github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg= -github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg= -github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= -github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= @@ -2731,24 +809,24 @@ github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01C github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw= -github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.14.2 h1:QBdZQTKpPdBlw2AdKwHEyqUcm/lrl2cwWAHjCMyln/o= +github.com/jackc/pgtype v1.14.2/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c h1:Dznn52SgVIVst9UyOT9brctYUgxs+CvVfPaC3jKrA50= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= -github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jaguilar/vt100 v0.0.0-20150826170717-2703a27b14ea/go.mod h1:QMdK4dGB3YhEW2BmA1wgGpPYI3HZy/5gD705PXKUVSg= -github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= @@ -2757,157 +835,73 @@ github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= -github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= +github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= -github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= -github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= -github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= -github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f/go.mod h1:qr2b5kx4HbFS7/g4uYO5qv9ei8303JMsC7ESbYiqr2Q= -github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= -github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= -github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= -github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s= -github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= -github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= -github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/joonix/log v0.0.0-20200409080653-9c1d2ceb5f1d/go.mod h1:fS54ONkjDV71zS9CDx3V9K21gJg7byKSvI4ajuWFNJw= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/josharian/txtarfs v0.0.0-20210218200122-0702f000015a/go.mod h1:izVPOvVRsHiKkeGCT6tYBNWyDVuzj9wAaBb5R9qamfw= -github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= -github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/junk1tm/musttag v0.4.5/go.mod h1:XkcL/9O6RmD88JBXb+I15nYRl9W4ExhgQeCBEhfMC8U= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= +github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c h1:AqsttAyEyIEsNz5WLRwuRwjiT5CMDUfLk6cFJDVPebs= github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kataras/blocks v0.0.6/go.mod h1:UK+Iwk0Oxpc0GdoJja7sEildotAUKK1LYeYcVF0COWc= -github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/golog v0.1.7/go.mod h1:jOSQ+C5fUqsNSwurB/oAHq1IFSb0KI3l6GMa7xB6dZA= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/iris/v12 v12.2.0-beta5/go.mod h1:q26aoWJ0Knx/00iPKg5iizDK7oQQSPjbD8np0XDh6dc= -github.com/kataras/jwt v0.1.8/go.mod h1:Q5j2IkcIHnfwy+oNY3TVWuEBJNw0ADgCcXK9CaZwV4o= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/neffos v0.0.20/go.mod h1:srdvC/Uo8mgrApWW0AYtiiLgMbyNPf69qPsd2FhE6MQ= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/pio v0.0.10/go.mod h1:gS3ui9xSD+lAUpbYnjOGiQyY7sUMJO+EHpiRzhtZ5no= -github.com/kataras/pio v0.0.11/go.mod h1:38hH6SWH6m4DKSYmRhlrCJ5WItwWgCVrTNU62XZyUvI= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= -github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinms/leakybucket-go v0.0.0-20200115003610-082473db97ca/go.mod h1:ph+C5vpnCcQvKBwJwKLTK3JLNGnBXYlG7m7JjoC/zYA= -github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkHAIKE/contextcheck v1.1.3/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkSVWyLJOFW5qoo= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= +github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.2/go.mod h1:XoLfkAiA2KeZsYh4DbHxD7h3nR2AZNqVQOa+LJuqPYs= -github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= -github.com/korovkin/limiter v0.0.0-20221015170604-22eb1ceceddc/go.mod h1:mM0lzivCxB6c8msz/LOP9lJgZxy92GXwGcNG1A7UZEE= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -2917,43 +911,20 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= -github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= -github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= -github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= -github.com/ldez/tagliatelle v0.4.0/go.mod h1:mNtTfrHy2haaBAw+VT7IBV6VXBThS7TCreYWbBcJ87I= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= -github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= -github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= @@ -2972,14 +943,9 @@ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.17.0/go.mod h1:Fkin50rsGdv5mm5BshBUtPRZknt9esfmYXBOYcwOTgw= -github.com/libp2p/go-libp2p v0.22.0/go.mod h1:UDolmweypBSjQb2f7xutPnwZ/fxioLbMBxSjRksxxU4= -github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg= -github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.1.0/go.mod h1:wu+AnM9Ii2KgO5jMmS1rz9dvzTdj8BXqsPR9HR0XB7I= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= -github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-autonat v0.7.0/go.mod h1:uPvPn6J7cN+LCfFwW5tpOYvAz5NvPTc4iBamTV/WDMg= @@ -3007,7 +973,6 @@ github.com/libp2p/go-libp2p-core v0.10.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQR github.com/libp2p/go-libp2p-core v0.11.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= github.com/libp2p/go-libp2p-core v0.12.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= github.com/libp2p/go-libp2p-core v0.13.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= -github.com/libp2p/go-libp2p-core v0.19.0/go.mod h1:AkA+FUKQfYt1FLNef5fOPlo/naAWjKy/RCjkcPjqzYg= github.com/libp2p/go-libp2p-discovery v0.6.0/go.mod h1:/u1voHt0tKIe5oIA1RHBKQLVCWPna2dXmPNHc2zR9S8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= @@ -3038,7 +1003,6 @@ github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotl github.com/libp2p/go-libp2p-testing v0.4.2/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= github.com/libp2p/go-libp2p-testing v0.5.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= github.com/libp2p/go-libp2p-testing v0.6.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= -github.com/libp2p/go-libp2p-testing v0.11.0/go.mod h1:qG4sF27dfKFoK9KlVzK2y52LQKhp0VEmLjV5aDqr1Hg= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-tls v0.3.0/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= @@ -3061,7 +1025,6 @@ github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= github.com/libp2p/go-msgio v0.1.0/go.mod h1:eNlv2vy9V2X/kNldcZ+SShFE++o2Yjxwx6RAYsmgJnE= -github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= @@ -3071,16 +1034,13 @@ github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdm github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.1.5/go.mod h1:V1SR3AaECRkEQCoFFzYwVYWvYIEtlxx89+O3qcpCl4A= github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= -github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= github.com/libp2p/go-reuseport v0.1.0/go.mod h1:bQVn9hmfcTaoo0c9v5pBhOarsU1eNOBZdaAd2hzXRKU= -github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= @@ -3095,68 +1055,32 @@ github.com/libp2p/go-ws-transport v0.5.0/go.mod h1:I2juo1dNTbl8BKSBYo98XY85kU2xd github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux/v2 v2.3.0/go.mod h1:iTU+lOIn/2h0AgKcL49clNTwfEw+WSfDYrXe05EyKIs= -github.com/libp2p/go-yamux/v3 v3.1.2/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/libp2p/zeroconf/v2 v2.1.1/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= -github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= -github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= -github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lucas-clemente/quic-go v0.23.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= github.com/lucas-clemente/quic-go v0.24.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= -github.com/lucas-clemente/quic-go v0.28.1/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= -github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= -github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailgun/raymond/v2 v2.0.46/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/manifoldco/promptui v0.7.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= -github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= -github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= -github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= -github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= -github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= -github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= -github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= -github.com/marten-seemann/qtls-go1-19 v0.1.0/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= -github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= -github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= -github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= -github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= -github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= @@ -3166,13 +1090,11 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -3180,66 +1102,28 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= -github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= -github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/mediocregopher/radix/v3 v3.8.0/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= -github.com/mgechev/revive v1.2.5/go.mod h1:nFOXent79jMTISAfOAasKfy0Z2Ejq0WX7Qn/KAdYopI= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= -github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= -github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -3249,9 +1133,7 @@ github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4S github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= @@ -3263,95 +1145,40 @@ github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= -github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v0.0.0-20170523030023-d0303fe80992/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw= github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/moby/buildkit v0.8.1/go.mod h1:/kyU1hKy/aYCuP39GZA9MaKioovHku57N6cqlKZIaiQ= -github.com/moby/buildkit v0.10.3/go.mod h1:jxeOuly98l9gWHai0Ojrbnczrk/rf+o9/JqNhY+UCSo= -github.com/moby/buildkit v0.11.4/go.mod h1:P5Qi041LvCfhkfYBHry+Rwoo3Wi6H971J2ggE+PcIoo= -github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= -github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/sys/mount v0.1.0/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74= -github.com/moby/sys/mount v0.1.1/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74= -github.com/moby/sys/mount v0.3.0/go.mod h1:U2Z3ur2rXPFrFmy4q6WMwWrBOAQGYtYTRVM8BIvzbwk= -github.com/moby/sys/mount v0.3.3/go.mod h1:PBaEorSNTLG5t/+4EgukEQVlAvVEc6ZjTySwKdqp5K0= -github.com/moby/sys/mountinfo v0.1.0/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= -github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= -github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= -github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= -github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= -github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= -github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= -github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= -github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2/go.mod h1:TjQg8pa4iejrUrjiz0MCtMV38jdMNW4doKSiBrEvCQQ= -github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= -github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8= -github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= -github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= -github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= -github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= @@ -3368,12 +1195,8 @@ github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4 github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= -github.com/multiformats/go-multiaddr v0.6.0/go.mod h1:F4IpaKZuPP360tOMn2Tpyu0At8w23aRyVqeK0DbFeGM= -github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= -github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= -github.com/multiformats/go-multiaddr v0.12.1 h1:vm+BA/WZA8QZDp1pF1FWhi5CT3g1tbi5GJmqpb6wnlk= -github.com/multiformats/go-multiaddr v0.12.1/go.mod h1:7mPkiBMmLeFipt+nNSq9pHZUeJSt8lHBgH6yhj0YQzE= +github.com/multiformats/go-multiaddr v0.12.2 h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24= +github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0cW+jA/YrnqTOvKgi44M= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= @@ -3385,11 +1208,8 @@ github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysj github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= -github.com/multiformats/go-multicodec v0.5.0/go.mod h1:DiY2HFaEp5EhEXb/iYzVAunmyX/aSFMxq2KMKfWEues= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= @@ -3399,14 +1219,11 @@ github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpK github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= -github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -3416,294 +1233,121 @@ github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= -github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= -github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/jwt v1.2.2/go.mod h1:/xX356yQA6LuXI9xWW7mZNpxgF2mBmGecH+Fj34sP5Q= -github.com/nats-io/jwt/v2 v2.0.3/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY= -github.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= -github.com/nats-io/jwt/v2 v2.3.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats-server/v2 v2.5.0/go.mod h1:Kj86UtrXAL6LwYRA6H4RqzkHhK0Vcv2ZnKD5WbQ1t3g= -github.com/nats-io/nats-server/v2 v2.8.4/go.mod h1:8zZa+Al3WsESfmgSs98Fi06dRWLH5Bnq90m5bKD/eT4= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nats.go v1.12.1/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= -github.com/nats-io/nats.go v1.15.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= -github.com/nats-io/nats.go v1.16.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s= -github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= -github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/networkplumbing/go-nft v0.2.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.9.5/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA= -github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= -github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nunnatsa/ginkgolinter v0.8.1/go.mod h1:FYYLtszIdmzCH8XMaMPyxPVXZ7VCaIm55bA+gugx+14= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= -github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= -github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= -github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= -github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= -github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= -github.com/onsi/ginkgo/v2 v2.8.0/go.mod h1:6JsQiECmxCa3V5st74AL/AmsV482EDdVrGaVW6z3oYU= -github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= -github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= -github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= -github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= -github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= -github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= -github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= -github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= -github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= -github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= -github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= -github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= -github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= -github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= -github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= -github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= -github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= -github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= -github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= -github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= -github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= -github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= +github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc= github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw= -github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.3-0.20220303224323-02efb9a75ee1/go.mod h1:K/JAU0m27RFhDRX4PcFdIKntROP6y5Ed6O91aZYDQfs= -github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= -github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc10/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc92/go.mod h1:X1zlU4p7wOlX4+WRCz+hvlRv8phdL7UqbYD+vQwNMmE= -github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= -github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= -github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= -github.com/opencontainers/runc v1.1.1/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= -github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= -github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= -github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= -github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= -github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= -github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= -github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/opencontainers/selinux v1.10.2/go.mod h1:cARutUbaUrlRClyvxOICCgKixCs6L05aUsohzA3EkHQ= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= -github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= -github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= -github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM= -github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/package-url/packageurl-go v0.1.1-0.20220428063043-89078438f170/go.mod h1:uQd4a7Rh3ZsVg5j0lNyAfyxIeGde9yrlhjF78GzeW0c= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= -github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.0.1-0.20170904195809-1d6b12b7cb29/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= -github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/peterh/liner v1.2.0 h1:w/UPXyl5GfahFxcTOz2j9wCIHNI+pUPr2laqpojKNCg= github.com/peterh/liner v1.2.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= -github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= -github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= -github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= -github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU= -github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI= -github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= -github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= -github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= -github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= -github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU= -github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= -github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw= -github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw= -github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA= -github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= -github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= -github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= -github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ= -github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs= -github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A= -github.com/pjbgf/sha1cd v0.2.3/go.mod h1:HOK9QrgzdHpbc2Kzip0Q1yi3M2MFGPADtR6HjG65m5M= -github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= -github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= -github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pointlander/compress v1.1.1-0.20190518213731-ff44bd196cc3/go.mod h1:q5NXNGzqj5uPnVuhGkZfmgHqNUhf15VLi6L9kW0VEc0= -github.com/pointlander/jetset v1.0.1-0.20190518214125-eee7eff80bd4/go.mod h1:RdR1j20Aj5pB6+fw6Y9Ur7lMHpegTEjY1vc19hEZL40= -github.com/pointlander/peg v1.0.1/go.mod h1:5hsGDQR2oZI4QoWz0/Kdg3VSVEC31iJw/b7WjqCBGRI= -github.com/polyfloyd/go-errorlint v1.1.0/go.mod h1:Uss7Bc/izYG0leCMRx3WVlrpqWedSZk7V/FUQW6VJ6U= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= @@ -3711,29 +1355,20 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= -github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= @@ -3743,35 +1378,24 @@ github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16 github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/prom2json v1.3.0/go.mod h1:rMN7m0ApCowcoDlypBHlkNbp5eJQf/+1isKykIP5ZnM= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= -github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d h1:1dN7YAqMN3oAJ0LceWcyv/U4jHLh+5urnSnr4br6zg4= github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d/go.mod h1:kOmQ/zdobQf7HUohDTifDNFEZfNaSCIY5fkONPL+dWU= github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44 h1:c3p3UzV4vFA7xaCDphnDWOjpxcadrQ26l5b+ypsvyxo= @@ -3779,44 +1403,20 @@ github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44/go.mod h1:MA github.com/prysmaticlabs/go-bitfield v0.0.0-20210108222456-8e92c3709aa0/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4= -github.com/prysmaticlabs/gohashtree v0.0.0-20220517220438-192ee5ae6982/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= github.com/prysmaticlabs/gohashtree v0.0.3-alpha h1:1EVinCWdb3Lorq7xn8DYQHf48nCcdAM3Vb18KsFlRWY= github.com/prysmaticlabs/gohashtree v0.0.3-alpha/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c/go.mod h1:ZRws458tYHS/Zs936OQ6oCrL+Ict5O4Xpwve1UQ6C9M= github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20211014160335-757fae4f38c6/go.mod h1:ZVEbRdnMkGhp/pu35zq4SXxtvUwWK0J1MATtekZpH2Y= -github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294/go.mod h1:ZVEbRdnMkGhp/pu35zq4SXxtvUwWK0J1MATtekZpH2Y= github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b h1:XULhE6PdzCYSe5OEVFhuixNqL3mYVOq/3M+SUGnKr1Y= github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b/go.mod h1:bFzDfaj4xtisRey9RPkMJOhOJVwmtH3FChV7NPKV1Nk= github.com/prysmaticlabs/prysm/v4 v4.2.0 h1:87QoRT3Azs7c1Y6SnIq0+CNtQRbAt0sVKGj2OxRT1Rw= github.com/prysmaticlabs/prysm/v4 v4.2.0/go.mod h1:PQrQtHJeeqTz4K3udN/EX1Gs2xhWR4j93gSj0OQZ1f4= -github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA= -github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= -github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= -github.com/quasilyte/go-ruleguard v0.1.2-0.20200318202121-b00d7a75d3d8/go.mod h1:CGFX09Ci3pq9QZdj86B+VGIdNj4VyCo2iPOGS9esB/k= -github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= -github.com/quasilyte/go-ruleguard v0.3.19/go.mod h1:lHSn69Scl48I7Gt9cX3VrbsZYvYiBYszZOZW4A+oTEw= -github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= -github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= -github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= -github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= -github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= -github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= -github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= -github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo= -github.com/quic-go/quic-go v0.37.6/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= -github.com/quic-go/quic-go v0.39.0/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= -github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= -github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s= +github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc/go.mod h1:S8xSOnV3CgpNrWd0GQ/OoQfMtlg2uPRSuTzcSGrzwK8= @@ -3826,101 +1426,47 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5/go.mod h1:+u151txRmLpwxBmpYn9z3d1sdJdjRPQpsXuYeY9jNls= -github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96/go.mod h1:90HvCY7+oHHUKkbeMCiHt1WuFR2/hPJ9QrljDG+v6ls= -github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e/go.mod h1:80FQABjoFzZ2M5uEa6FUaJYEmqU2UOKojlFVak1UAwI= -github.com/rivo/tview v0.0.0-20221117065207-09f052e6ca98/go.mod h1:YX2wUZOcJGOIycErz2s9KvDaP0jnWwRCirQMPLPpQ+Y= -github.com/rivo/tview v0.0.0-20230330183452-5796b0cd5c1f/go.mod h1:nVwGv4MP47T0jvlk7KuTTjjuSmrGO4JF0iaiNt4bufE= +github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= -github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= -github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= -github.com/ryancurrah/gomodguard v1.0.4/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0fVb9d5fSEaLhoE= -github.com/ryancurrah/gomodguard v1.1.0/go.mod h1:4O8tr7hBODaGE6VIhfJDHcwzh5GUccKSJBU0UMXJFVM= -github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= -github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= -github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= -github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= -github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= -github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU= -github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/schollz/progressbar/v3 v3.3.4/go.mod h1:Rp5lZwpgtYmlvmGo1FyDwXMqagyRBQYSDwzlP9QDu84= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= -github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/secure-systems-lab/go-securesystemslib v0.4.0/go.mod h1:FGBZgq2tXWICsxWQW1msNf49F0Pf2Op5Htayx335Qbs= -github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83/go.mod h1:vvbZ2Ae7AzSq3/kywjUDxSNq2SJ27RxCz2un0H3ePqE= -github.com/securego/gosec v0.0.0-20200401082031-e946c8c39989/go.mod h1:i9l/TNj+yDFh9SZXUTvspXTjbFXgZGP/UvhU1S65A4A= -github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME= -github.com/securego/gosec/v2 v2.15.0/go.mod h1:VOjTrZOkUtSDt2QLSJmQBMWnvwiQPEjg0l+5juIqGk8= +github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc= -github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= -github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= -github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI= -github.com/shirou/gopsutil/v3 v3.23.1/go.mod h1:NN6mnm5/0k8jw4cBfCnJtr5L7ErOTg18tMNpgFkn0hA= -github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= @@ -3930,7 +1476,6 @@ github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9A github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= @@ -3940,118 +1485,57 @@ github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1l github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= -github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= -github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= -github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/assertions v1.13.0/go.mod h1:wDmR7qL282YbGsPy6H/yAsesrxfxaaSlJazyFLYVFx8= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= -github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= -github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= -github.com/sourcegraph/go-diff v0.5.3/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak= -github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM= -github.com/spdx/tools-golang v0.3.1-0.20230104082527-d6f58551be3f/go.mod h1:VHzvNsKAfAGqs4ZvwRL+7a0dNsL20s7lGui4K9C0xQM= github.com/spf13/afero v0.0.0-20170901052352-ee1bd8ee15a1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= -github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= -github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.1.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= -github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v0.0.0-20170901151539-12bd96e66386/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20170901120850-7aff26db30c1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= -github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= -github.com/spiffe/go-spiffe/v2 v2.1.1/go.mod h1:5qg6rpqlwIub0JAiF1UK9IMD6BpPTmvG6yfSgDBs5lg= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= -github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= -github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= -github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -4060,239 +1544,90 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= -github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= -github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/supranational/blst v0.3.5/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= -github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= -github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= -github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tdewolff/minify/v2 v2.12.1/go.mod h1:p5pwbvNs1ghbFED/ZW1towGsnnWwzvM8iz8l0eURi9g= -github.com/tdewolff/minify/v2 v2.12.4/go.mod h1:h+SRvSIX3kwgwTFOpSckvSxgax3uy8kZTSF1Ojrr3bk= -github.com/tdewolff/parse/v2 v2.6.3/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs= -github.com/tdewolff/parse/v2 v2.6.4/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs= -github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= -github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= -github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= -github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= -github.com/tetafro/godot v0.4.2/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= -github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e h1:cR8/SYRgyQCt5cNCMniB/ZScMkhI9nk8U5C7SbISXjo= github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e/go.mod h1:Tu4lItkATkonrYuvtVjG0/rhy15qrNGNTjPdaphtZ/8= -github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= -github.com/timonwong/loggercheck v0.9.3/go.mod h1:wUqnk9yAOIKtGA39l1KLE9Iz0QiTocu/YZoOf+OzFdw= -github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= -github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0= -github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao= -github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= +github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= -github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= -github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= -github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo= -github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tomarrell/wrapcheck/v2 v2.8.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= -github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= -github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= -github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= -github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= -github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85/go.mod h1:a7cilN64dG941IOXfhJhlH0qB92hxJ9A1ewrdUmJ6xo= -github.com/tonistiigi/fsutil v0.0.0-20220115021204-b19f7f9cb274/go.mod h1:oPAfvw32vlUJSjyDcQ3Bu0nb2ON2B+G0dtVN/SZNJiA= -github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa/go.mod h1:AvLEd1LEIl64G2Jpgwo7aVV5lGH0ePcKl0ygGIHNYl8= -github.com/tonistiigi/go-actions-cache v0.0.0-20220404170428-0bdeb6e1eac7/go.mod h1:qqvyZqkfwkoJuPU/bw61bItaoO0SJ8YSW0vSVRRvsRg= -github.com/tonistiigi/go-archvariant v1.0.0/go.mod h1:TxFmO5VS6vMq2kvs3ht04iPXtu2rUT/erOnGFYfk5Ho= -github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk= -github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc= github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef/go.mod h1:+SV/613m53DNAmlXPTWGZhIyt4E/qDvn9g/lOPRiy0A= -github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279/go.mod h1:GA3+Mq3kt3tYAfM0WZCu7ofy+GW9PuGysHfhr+6JX7s= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= -github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= -github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= -github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo= -github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= -github.com/urfave/cli/v2 v2.23.7/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= -github.com/urfave/cli/v2 v2.24.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= -github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= -github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= -github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= -github.com/uudashr/gocognit v1.0.5/go.mod h1:wgYz0mitoKOTysqxTDMOUXg+Jb5SvtihkfmugIZYpEA= -github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= +github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= -github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= -github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= -github.com/vdemeester/k8s-pkg-credentialprovider v1.17.4/go.mod h1:inCTmtUdr5KJbreVojo06krnTgaeAz/Z7lynpPk/Q2c= -github.com/vektra/mockery/v2 v2.14.0/go.mod h1:bnD1T8tExSgPD1ripLkDbr60JA9VtQeu12P3wgLZd7M= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE= -github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= -github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= -github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/wealdtech/go-bytesutil v1.1.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s= github.com/wealdtech/go-eth2-types/v2 v2.5.2/go.mod h1:8lkNUbgklSQ4LZ2oMSuxSdR7WwJW3L9ge1dcoCVyzws= github.com/wealdtech/go-eth2-util v1.6.3/go.mod h1:0hFMj/qtio288oZFHmAbCnPQ9OB3c4WFzs5NVPKTY4k= github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3/go.mod h1:qiIimacW5NhVRy8o+YxWo9YrecXqDAKKbL0+sOa0SJ4= github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.2/go.mod h1:k6kmiKWSWBTd4OxFifTEkPaBLhZspnO2KFD5XJY9nqg= +github.com/welkin22/op-geth v1.101308.2-opbnb2 h1:VRRSXyqw0zszivEBAcLuMi3uFZqunZzmAY0lNL95128= +github.com/welkin22/op-geth v1.101308.2-opbnb2/go.mod h1:kwg6KPGU98pFj2ZZF7z45FsKJdhIrfaQ7SW1Kac1RvY= github.com/wercker/journalhook v0.0.0-20180428041537-5d0a5ae867b3/go.mod h1:XCsSkdKK4gwBMNrOCZWww0pX6AOt+2gYc5Z6jBRrNVg= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= -github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= -github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= -github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= -github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= -github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= -github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= -github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= -github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= -github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= -github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= -github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= -go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= -go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= -go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= -go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= -go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= -go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o= -go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= -go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.19.1/go.mod h1:gug0GbSHa8Pafr0d2urOSgoXHZ6x/RUlaiT0d9pqb4A= -go.opencensus.io v0.19.2/go.mod h1:NO/8qkisMZLZ1FCsKNqtJPwc8/TaclWyY0B6wcYNg9M= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -4300,89 +1635,35 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0/go.mod h1:LsankqVDx4W+RhZNA5uWarULII/MBhF5qwCYxTuyXjs= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.33.0/go.mod h1:y/SlJpJQPd2UzfBCj0E9Flk9FDCtTyqUmaCB41qFrWI= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.3/go.mod h1:Dts42MGkzZne2yCru741+bFiTMWkIj/LLRizad7b9tw= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.29.0/go.mod h1:vHItvsnJtp7ES++nFLLFBzUWny7fJQSvTlxFcqQGUr4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.29.0/go.mod h1:tLYsuf2v8fZreBVwp9gVMhefZlLFZaUiNVSq8QxXRII= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= -go.opentelemetry.io/otel v1.4.0/go.mod h1:jeAqMFKy2uLIxCtKxoFj0FAL5zAPKQagc3+GtBWakzk= -go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4= -go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= -go.opentelemetry.io/otel v1.11.0/go.mod h1:H2KtuEphyMvlhZ+F7tg9GRhAOe60moNx61Ex+WmiKkk= -go.opentelemetry.io/otel/exporters/jaeger v1.4.1/go.mod h1:ZW7vkOu9nC1CxsD8bHNHCia5JUbwP39vxgd1q4Z5rCI= -go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1/go.mod h1:o5RW5o2pKpJLD5dNTCmjF1DorYwMeFJmb/rKr5sLaa8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1/go.mod h1:c6E4V3/U+miqjs/8l950wggHGL1qzlp0Ypj9xoGrPqo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.4.1/go.mod h1:VwYo0Hak6Efuy0TXsZs8o1hnV3dHDPNtDbycG0hI8+M= -go.opentelemetry.io/otel/internal/metric v0.27.0/go.mod h1:n1CVxRqKqYZtqyTh9U/onvKapPGv7y/rpyOTI+LFNzw= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/metric v0.27.0/go.mod h1:raXDJ7uP2/Jc0nVZWQjJtzoyssOYWu/+pjZqRzfvZ7g= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= -go.opentelemetry.io/otel/sdk v1.4.1/go.mod h1:NBwHDgDIBYjwK2WNu1OPgsIc2IJzmBXNnvIJxJc8BpE= -go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= -go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= -go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= -go.opentelemetry.io/otel/trace v1.4.0/go.mod h1:uc3eRsqDfWs9R7b92xbQbU42/eTNz4N+gLP8qJCi4aE= -go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc= -go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= -go.opentelemetry.io/otel/trace v1.11.0/go.mod h1:nyYjis9jy0gytE9LXGU+/m1sHTKbRY0fX0hulNNDP1U= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= -go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ= -go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA= go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= @@ -4392,24 +1673,14 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -4425,83 +1696,36 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -4510,42 +1734,13 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= -golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/exp v0.0.0-20230725012225-302865e7556b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/exp v0.0.0-20230810033253-352e893a4cad/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4= golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= -golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20221002003631-540bb7301a08/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -4556,7 +1751,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -4565,36 +1759,20 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -4604,23 +1782,16 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -4640,127 +1811,41 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220726230323-06994584191e/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM= -golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20220923203811-8be639271d50/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.1.1-0.20221027164007-c63010009c80/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/oauth2 v0.0.0-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= -golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= -golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= -golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -4768,17 +1853,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -4791,7 +1868,6 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -4806,46 +1882,31 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190620070143-6f217b454f45/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -4859,159 +1920,58 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201013081832-0aaa2718063a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210313202042-bd2e13477e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220727055044-e65921a090b8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -5023,16 +1983,6 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -5040,18 +1990,10 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -5059,69 +2001,41 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190228203856-589c23e65e65/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113232020-e2727e816f5a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191126055441-b0650ceb63d9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200102140908-9497f49d5709/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204192400-7124308813f3/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -5129,120 +2043,47 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= -golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.4.1-0.20221208213631-3f74d914ae6d/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= -golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= -golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= -golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= -gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= +gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= -gonum.org/v1/plot v0.10.0/go.mod h1:JWIHJ7U20drSQb/aDpTetJzfC1KlAPldJLpkSy88dvQ= -gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= -google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20170206182103-3d017632ea10/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20170921000349-586095a6e407/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.2.0/go.mod h1:IfRCZScioGtypHNTlz3gFk67J8uePVW7uDTBzXuIkhU= -google.golang.org/api v0.3.0/go.mod h1:IuvZyQh8jgscv8qWfQ4ABd8m7hEudgBFM/EdhA3BnXw= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.6.0/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= -google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -5252,104 +2093,41 @@ google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.34.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= -google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= -google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= -google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= -google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= -google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= -google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= -google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= -google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E= -google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= -google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= -google.golang.org/api v0.125.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= -google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= -google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= -google.golang.org/api v0.139.0/go.mod h1:CVagp6Eekz9CjGZ718Z+sloknzkDJE7Vc1Ckj9+viBk= -google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= -google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20170918111702-1e559d0a00ee/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20181219182458-5a97ab628bfb/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -5365,191 +2143,16 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210426193834-eac7f76ac494/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220706185917-7780775163c4/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= -google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= -google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= -google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= -google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= -google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= -google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= -google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= -google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= -google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto v0.0.0-20230629202037-9506855d4529/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= -google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= -google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:0ggbjUrZYpy1q+ANUS30SEoGZ53cdfwtbuG7Ptgy108= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= -google.golang.org/genproto v0.0.0-20230821184602-ccc8af3d0e93/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:CCviP9RmpZ1mxVr8MUjCnSiY09IbAXZxhLE6EhHIdPU= -google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= -google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:EMfReVxb80Dq1hhioy0sOsY9jCE46YDgHlJ7fWVUWRE= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= -google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= -google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:RdyHbowztCGQySiCvQPgWQWgWhGnouTdCflKoDBt32U= -google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= -google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:SUBoKXbI1Efip18FClrQVGjWcyd0QZd8KkvdP34t7ww= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= -google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405 h1:HJMDndgxest5n2y77fnErkM62iUsptE/H8p0dC2Huo4= -google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405/go.mod h1:oT32Z4o8Zv2xPQTg0pbVaPr0MPOH6f14RgXt7zfIpwg= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:8mL13HKkDa+IuJ8yruA3ci0q+0vsUz4m//+ottjwS5o= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230920183334-c177e329c48b/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= -google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v0.0.0-20170208002647-2a6bf6142e96/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -5561,60 +2164,24 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= -google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= -google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= -google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/grpc v1.60.0 h1:6FQAR0kM31P6MRdeluor2w2gPaS4SVNrD/DNTxrQ15k= -google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/grpc/examples v0.0.0-20201130180447-c456688b1860/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -5627,67 +2194,40 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610= gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -5695,31 +2235,21 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo= -gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0= -gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= -gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM= +gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= +gorm.io/gorm v1.25.8 h1:WAGEZ/aEcznN4D03laj8DKnehe1e9gYQAjW8xyPRdeo= +gorm.io/gorm v1.25.8/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -5727,198 +2257,31 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -honnef.co/go/tools v0.4.2/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= -honnef.co/go/tools v0.5.0-0.dev.0.20231205170804-aef76f4feee2/go.mod h1:J8YyqAvNy0yWpeKUOCONA1m2G4hH2CqUSo/5ZO2/5UA= -k8s.io/api v0.0.0-20180904230853-4e7be11eab3f/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= -k8s.io/api v0.17.4/go.mod h1:5qxx6vjmwUVG2nHQTKGlLts8Tbok8PzHl4vHtVFuZCA= k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= -k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw= -k8s.io/api v0.20.0/go.mod h1:HyLC5l5eoS/ygQYl1BXBgFzWNlkHiAuyNAbevIn+FKg= -k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= -k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= -k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= -k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= -k8s.io/api v0.23.4/go.mod h1:i77F4JfyNNrhOjZF7OwwNJS5Y1S9dpwvb9iYRYRczfI= -k8s.io/api v0.25.4/go.mod h1:IG2+RzyPQLllQxnhzD8KQNEu4c4YvyDTpSMztf4A0OQ= -k8s.io/apimachinery v0.0.0-20180904193909-def12e63c512/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= -k8s.io/apimachinery v0.17.4/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g= k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= -k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= -k8s.io/apimachinery v0.20.0/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= -k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= -k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= -k8s.io/apimachinery v0.23.4/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= -k8s.io/apimachinery v0.25.4/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= -k8s.io/apiserver v0.17.4/go.mod h1:5ZDQ6Xr5MNBxyi3iUZXS84QOhZl+W7Oq2us/29c0j9I= -k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= -k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= -k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= -k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ= -k8s.io/client-go v0.0.0-20180910083459-2cefa64ff137/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= -k8s.io/client-go v0.17.4/go.mod h1:ouF6o5pz3is8qU0/qYL2RnoxOPqgfuidYLowytyLJmc= k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= -k8s.io/client-go v0.19.0/go.mod h1:H9E/VT95blcFQnlyShFgnFT9ZnJOAceiUHM3MlRC+mU= -k8s.io/client-go v0.20.0/go.mod h1:4KWh/g+Ocd8KkCwKF8vUNnmqgv+EVnQDK4MBF4oB5tY= -k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= -k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= -k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y= -k8s.io/client-go v0.23.4/go.mod h1:PKnIL4pqLuvYUK1WU7RLTMYKPiIh7MYShLshtRY9cj0= -k8s.io/client-go v0.25.4/go.mod h1:8trHCAC83XKY0wsBIpbirZU4NTUpbuhc2JnI7OruGZw= -k8s.io/cloud-provider v0.17.4/go.mod h1:XEjKDzfD+b9MTLXQFlDGkk6Ho8SGMpaU8Uugx/KNK9U= -k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= -k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= -k8s.io/component-base v0.17.4/go.mod h1:5BRqHMbbQPm2kKu35v3G+CpVq4K0RJKC7TRioF0I9lE= -k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= -k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= -k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= -k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= -k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= -k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= -k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= -k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= -k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4= -k8s.io/cri-api v0.24.0-alpha.3/go.mod h1:c/NLI5Zdyup5+oEYqFO2IE32ptofNiZpS1nL2y51gAg= -k8s.io/cri-api v0.25.0/go.mod h1:J1rAyQkSJ2Q6I+aBMOVgg2/cbbebso6FNa0UagiR0kc= -k8s.io/cri-api v0.26.0-alpha.3/go.mod h1:E49tenyB7esgfIguEd7+g9qYhHOr9peyyBcSaeH6Gxw= -k8s.io/csi-translation-lib v0.17.4/go.mod h1:CsxmjwxEI0tTNMzffIAcgR9lX4wOh6AKHdxQrT7L0oo= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.3.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.80.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= -k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= -k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= -k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= -k8s.io/kubernetes v1.11.10/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/legacy-cloud-providers v0.17.4/go.mod h1:FikRNoD64ECjkxO36gkDgJeiQWwyZTuBkhu+yxOc1Js= -k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200520001619-278ece378a50/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= -modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20= -modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= -modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= -modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= -modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI= -modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= -modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= -modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= -modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= -modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g= -modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= -modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= -modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= -modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= -modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= -modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= -modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= -modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= -modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= -modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA= -modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0= -modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= -modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= -modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= -modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= -modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= -modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= -modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= -modernc.org/sqlite v1.18.2/go.mod h1:kvrTLEWgxUcHa2GfHBQtanR1H9ht3hTJNtKpzH9k1u0= -modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= -modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= -modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= -modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= -modernc.org/tcl v1.13.2/go.mod h1:7CLiGIPo1M8Rv1Mitpv5akc2+8fxUd2y2UzC/MfMzy0= -modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= -modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= -moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= -mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= -mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc= -mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is= -pack.ag/amqp v0.11.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= -sourcegraph.com/sqs/pbtypes v1.0.0/go.mod h1:3AciMUv4qUuRHRHhOG4TZOB+72GdPVz5k+c648qsFS4= diff --git a/indexer/CHANGELOG.md b/indexer/CHANGELOG.md deleted file mode 100644 index 985243323142..000000000000 --- a/indexer/CHANGELOG.md +++ /dev/null @@ -1,117 +0,0 @@ -# @eth-optimism/indexer - -## 0.7.0 - -### Minor Changes - -- ed50bd5b4: Bump indexer - -## 0.6.0 - -### Minor Changes - -- ecf0cc59b: Fix startup issues, add L2 conf depth - -## 0.5.0 - -### Minor Changes - -- f030d8660: Adds support for the OptimismPortal's new `WithdrawalProven` event to the indexer - -## 0.4.0 - -### Minor Changes - -- 1bfe79f20: Adds an implementation of the Two Step Withdrawals V2 proposal - -### Patch Changes - -- f49b71d50: Updated forge-std version - -## 0.3.3 - -### Patch Changes - -- 587f309bf: Fix the docker build - -## 0.3.2 - -### Patch Changes - -- f505078be: Update go-ethereum to v1.10.26 - -## 0.3.1 - -### Patch Changes - -- 4006ef3a: Delete unused flags - -## 0.3.0 - -### Minor Changes - -- 19e581d8: Bedrock support - -## 0.2.0 - -### Minor Changes - -- 4b0d5109: This release supports bedrock contracts and is configured for the public alpha testnet on goerli. - -## 0.1.4 - -### Patch Changes - -- 74babaa4: Delete dead file -- 3e67f784: Update go-ethereum to 1.10.21 -- ec8d6b7c: Remove some duplicated code - -## 0.1.3 - -### Patch Changes - -- f30a5d39: Fix contract bindings - -## 0.1.2 - -### Patch Changes - -- b3921408: Fix a couple semgrep issues -- c6f6d68b: Deduplicate some l2geth and geth utils -- 0b30ae05: Use op-bindings package for address manager - -## 0.1.1 - -### Patch Changes - -- 6f458607: Bump go-ethereum to 1.10.17 - -## 0.1.0 - -### Minor Changes - -- 79be3e80: Add airdrops API - -### Patch Changes - -- d7bb9625: fix context reuse - -## 0.0.4 - -### Patch Changes - -- 1df934a1: Don't spam the backend -- 94876e28: fix (indexer): update l2 bridge addresses - -## 0.0.3 - -### Patch Changes - -- 160f4c3d: Update docker image to use golang 1.18.0 - -## 0.0.2 - -### Patch Changes - -- 0e40dcb6: Indexer: initial release -- 93131547: Bump `go-ethereum` to `v1.10.16` diff --git a/indexer/Dockerfile b/indexer/Dockerfile index e464e44844b5..ac228dea8659 100644 --- a/indexer/Dockerfile +++ b/indexer/Dockerfile @@ -14,19 +14,17 @@ COPY ./indexer /app/indexer COPY ./op-bindings /app/op-bindings COPY ./op-service /app/op-service COPY ./op-node /app/op-node +COPY ./op-plasma /app/op-plasma +COPY ./op-chain-ops /app/op-chain-ops +COPY ./go.mod /app/go.mod +COPY ./go.sum /app/go.sum WORKDIR /app/indexer - RUN make indexer FROM alpine:3.18 - COPY --from=builder /app/indexer/indexer /usr/local/bin -COPY --from=builder /app/indexer/indexer.toml /app/indexer/indexer.toml COPY --from=builder /app/indexer/migrations /app/indexer/migrations -WORKDIR /app - -ENV INDEXER_MIGRATIONS_DIR="/app/indexer/migrations" - -CMD ["indexer", "index", "--config", "/app/indexer/indexer.toml"] +WORKDIR /app/indexer +CMD ["indexer"] diff --git a/indexer/Makefile b/indexer/Makefile index dfa102ecf77b..2384d74c921d 100644 --- a/indexer/Makefile +++ b/indexer/Makefile @@ -8,6 +8,9 @@ LDFLAGS := -ldflags "$(LDFLAGSSTRING)" indexer: env GO111MODULE=on go build -v $(LDFLAGS) ./cmd/indexer +up: + docker-compose up --build + clean: rm indexer diff --git a/indexer/README.md b/indexer/README.md index d5e6a96dad07..916f5c9dfd43 100644 --- a/indexer/README.md +++ b/indexer/README.md @@ -2,67 +2,76 @@ ## Getting started +### Configuration +The `indexer.toml` contains configuration for the indexer. The file is templated for the local devnet, however presets are available for [known networks](https://github.com/ethereum-optimism/optimism/blob/develop/indexer/config/presets.go). The file also templates keys needed for custom networks such as the rollup contract addresses and the `l1-starting-height` for the deployment height. -### Setup env -The `indexer.toml` stores a set of preset environmental variables that can be used to run the indexer with the exception of the network specific `l1-rpc` and `l2-rpc` variables. The `indexer.toml` file can be ran as a default config, otherwise a custom `.toml` config can provided via the `--config` flag when running the application. An optional `l1-starting-height` value can be provided to the indexer to specify the L1 starting block height to begin indexing from. This should be ideally be an L1 block that holds a correlated L2 genesis commitment. Furthermore, this value must be less than the current L1 block height to pass validation. If no starting height value is provided and the database is empty, the indexer will begin sequentially processing from L1 genesis. - -### Setup polling intervals -The indexer polls and processes batches from the L1 and L2 chains on a set interval/size. The default polling interval is 5 seconds for both chains with a default batch header size of 500. The polling frequency can be changed by setting the `l1-polling-interval` and `l2-polling-interval` values in the `indexer.toml` file. The batch header size can be changed by setting the `l1-batch-size` and `l2-batch-size` values in the `indexer.toml` file. +Required configuration is network specific `(l1|l2)-rpc` urls that point to archival nodes as well as the `(l1|l2)-polling-interval` & `(l1|l2)-header-buffer-size` keys which controls the of rate data retrieval from these notes. ### Testing All tests can be ran by running `make test` from the `/indexer` directory. This will run all unit and e2e tests. -**NOTE:** Successfully running the E2E tests requires spinning up a local L1 geth node and pre-populating it with necessary bedrock genesis state. This can be done by calling `make devnet-allocs` from the root of the optimism monorepo before running the indexer tests. More information on this can be found in the [op-e2e README](../op-e2e/README.md). - -### Run indexer vs goerli - -- install docker -- `cp example.env .env` -- fill in .env -- run `docker compose up` to start the indexer vs optimism goerli network - -### Run indexer with go +> **NOTE:** Successfully running the E2E tests requires spinning up a local devnet via [op-e2e](https://github.com/ethereum-optimism/optimism/tree/develop/op-e2e) and pre-populating it with necessary bedrock genesis state. This genesis state is generated by invoking the`make devnet-allocs` target from the root of the optimism monorepo before running the indexer tests. More information on this can be found in the [op-e2e README](../op-e2e/README.md). A postgres database through pwd-less user $DB_USER env variable on port 5432 must be available as well. -See the flags in `flags.go` for reference of what command line flags to pass to `go run` +### Run the Indexer (docker-compose) +The local [docker-compose.go](https://github.com/ethereum-optimism/optimism/blob/develop/indexer/docker-compose.yml) file spins up **index, api, postgres, prometheus and grafana** services. The `indexer.toml` file is setup for the local devnet. To run against a live network, update the `indexer.toml` with the desired configuration. -### Run indexer vs devnet +> The API, Postgres, and Grafana services are the only ones with ports mapped externally. Postgres database is mapped to port 5433 to deconflict any instances already running on the default port -TODO add indexer to the optimism devnet compose file (previously removed for breaking CI) +1. Install Deps: Docker, Genesis State: `make devnet-allocs` +2. Start Devnet `make devnet up`, Otherwise update `indexer.toml` to desired network config. +3. Start Indexer: `cd indexer && docker-compose up` +4. View the Grafana dashboard at http://localhost:3000 + - **User**: admin + - **Password**: optimism -### Run indexer vs a custom configuration +### Run the Indexer (Go Binary or Dockerfile) +1. Prepare the `indexer.toml` file +2. **Run database migrations**: `indexer migrate --config ` +3. Run index service, cmd: `indexer index --config ` +4. Run the api service, cmd: `indexer api --config ` -`docker-compose.dev.yml` is git ignored. Fill in your own docker-compose file here. +> Both the index and api services listen on an HTTP and Metrics port. Migrations should **always** be run prior to start the indexer to ensure latest schemas are set. ## Architecture -![Architectural Diagram](./assets/architecture.png) - +![Architectural Diagram](./ops/assets/architecture.png) The indexer application supports two separate services for collective operation: -**Indexer API** - Provides a lightweight API service that supports paginated lookups for bridge events. +**Indexer API** - Provides a lightweight API service that supports paginated lookups for bridge data. **Indexer Service** - A polling based service that constantly reads and persists OP Stack chain data (i.e, block meta, system contract events, synchronized bridge events) from a L1 and L2 chain. ### Indexer API -TBD +See `api/api.go` & `api/routes/` for available API endpoints to for paginated retrieval of bridge data. **TDB** docs. ### Indexer Service -![Service Component Diagram](./assets/indexer-service.png) +![Service Component Diagram](./ops/assets/indexer-service.png) The indexer service is responsible for polling and processing real-time batches of L1 and L2 chain data. The indexer service is currently composed of the following key components: -- **Poller Routines** - Individually polls the L1/L2 chain for new blocks and OP Stack system contract events. +- **Poller Routines** - Individually polls the L1/L2 chain for new blocks and OP Stack contract events. - **Insertion Routines** - Awaits new batches from the poller routines and inserts them into the database upon retrieval. - **Bridge Routine** - Polls the database directly for new L1 blocks and bridge events. Upon retrieval, the bridge routine will: -* Process and persist new bridge events -* Synchronize L1 proven/finalized withdrawals with their L2 initialization counterparts + * Process and persist new bridge events + * Synchronize L1 proven/finalized withdrawals with their L2 initialization counterparts + +#### L1 Poller +L1 blocks are only indexed if they contain L1 contract events. This is done to reduce the amount of unnecessary data that is indexed. Because of this, the `l1_block_headers` table will not contain every L1 block header unlike L2 blocks. -### L1 Polling -L1 blocks are only indexed if they contain L1 system contract events. This is done to reduce the amount of unnecessary data that is indexed. Because of this, the `l1_block_headers` table will not contain every L1 block header. +#### Database +The indexer service currently supports a Postgres database for storing L1/L2 OP Stack chain data. The most up-to-date database schemas can be found in the `./migrations` directory. **Run the idempotent migrations prior to starting the indexer** -#### API +#### HTTP The indexer service runs a lightweight health server adjacently to the main service. The health server exposes a single endpoint `/healthz` that can be used to check the health of the indexer service. The health assessment doesn't check dependency health (ie. database) but rather checks the health of the indexer service itself. -### Database -The indexer service currently supports a Postgres database for storing L1/L2 OP Stack chain data. The most up-to-date database schemas can be found in the `./migrations` directory. +#### Metrics +The indexer services exposes a set of Prometheus metrics that can be used to monitor the health of the service. The metrics are exposed via the `/metrics` endpoint on the health server. + + +## Security +All security related issues should be filed via github issues and will be triaged by the team. The following are some security considerations to be taken when running the service: +- Since the Indexer API only performs read operations on the database, access to the database for any API instances should be restricted to read-only operations. +- The API has no rate limiting or authentication/authorization mechanisms. It is recommended to place the API behind a reverse proxy that can provide these features. +- Postgres connection timeouts are unenforced in the services. It is recommended to configure the database to enforce connection timeouts to prevent connection exhaustion attacks. +- Setting confirmation count values too low can result in indexing failures due to chain reorgs. -## Metrics -The indexer services exposes a set of Prometheus metrics that can be used to monitor the health of the service. The metrics are exposed via the `/metrics` endpoint on the health server. \ No newline at end of file +## Troubleshooting +Please advise the [troubleshooting](./ops/docs/troubleshooting.md) guide for common failure scenarios and how to resolve them. diff --git a/indexer/api-ts/generated.ts b/indexer/api-ts/generated.ts index 9b19bb6da987..713aca927fce 100644 --- a/indexer/api-ts/generated.ts +++ b/indexer/api-ts/generated.ts @@ -3,6 +3,11 @@ ////////// // source: models.go +export interface QueryParams { + Address: any /* common.Address */; + Limit: number /* int */; + Cursor: string; +} /** * DepositItem ... Deposit item model for API responses */ @@ -34,12 +39,12 @@ export interface WithdrawalItem { from: string; to: string; transactionHash: string; - messageHash: string; + crossDomainMessageHash: string; timestamp: number /* uint64 */; l2BlockHash: string; amount: string; - proofTransactionHash: string; - claimTransactionHash: string; + l1ProvenTxHash: string; + l1FinalizedTxHash: string; l1TokenAddress: string; l2TokenAddress: string; } @@ -51,3 +56,9 @@ export interface WithdrawalResponse { hasNextPage: boolean; items: WithdrawalItem[]; } +export interface BridgeSupplyView { + l1DepositSum: number /* float64 */; + l2WithdrawalSum: number /* float64 */; + provenSum: number /* float64 */; + finalizedSum: number /* float64 */; +} diff --git a/indexer/api-ts/package.json b/indexer/api-ts/package.json index 16c4c7c9e824..492e2fee3a4b 100644 --- a/indexer/api-ts/package.json +++ b/indexer/api-ts/package.json @@ -16,8 +16,8 @@ "LICENSE" ], "scripts": { - "clean": "rm -rf generated.ts indexer.cjs indexer.js", - "generate": "npm run clean && tygo generate && mv ../api/models/index.ts generated.ts && tsup", + "generate:clean": "rm -rf generated.ts indexer.cjs indexer.js", + "generate": "npm run generate:clean && tygo generate && mv ../api/models/index.ts generated.ts && tsup", "test": "vitest" }, "keywords": [ @@ -33,7 +33,7 @@ "url": "https://github.com/ethereum-optimism/optimism.git" }, "devDependencies": { - "tsup": "^7.2.0", - "vitest": "^0.34.4" + "tsup": "^8.0.1", + "vitest": "^1.2.2" } } diff --git a/indexer/api/api.go b/indexer/api/api.go index 37a572515e26..ff2601283d38 100644 --- a/indexer/api/api.go +++ b/indexer/api/api.go @@ -6,45 +6,57 @@ import ( "fmt" "net" "net/http" - "runtime/debug" "strconv" - "sync" + "sync/atomic" + "time" + + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" + + "github.com/prometheus/client_golang/prometheus" + + "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/indexer/api/routes" + "github.com/ethereum-optimism/optimism/indexer/api/service" "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/op-service/httputil" "github.com/ethereum-optimism/optimism/op-service/metrics" - "github.com/ethereum/go-ethereum/log" - "github.com/go-chi/chi/v5" - "github.com/go-chi/chi/v5/middleware" - "github.com/prometheus/client_golang/prometheus" ) const ethereumAddressRegex = `^0x[a-fA-F0-9]{40}$` -// Api ... Indexer API struct -// TODO : Structured error responses -type API struct { - log log.Logger - router *chi.Mux - serverConfig config.ServerConfig - metricsConfig config.ServerConfig - metricsRegistry *prometheus.Registry -} - const ( MetricsNamespace = "op_indexer_api" addressParam = "{address:%s}" // Endpoint paths - // NOTE - This can be further broken out over time as new version iterations - // are implemented + DocsPath = "/docs" HealthPath = "/healthz" DepositsPath = "/api/v0/deposits/" WithdrawalsPath = "/api/v0/withdrawals/" + + SupplyPath = "/api/v0/supply" ) +// Api ... Indexer API struct +// TODO : Structured error responses +type APIService struct { + log log.Logger + router *chi.Mux + + bv database.BridgeTransfersView + dbClose func() error + + metricsRegistry *prometheus.Registry + + apiServer *httputil.HTTPServer + metricsServer *httputil.HTTPServer + + stopped atomic.Bool +} + // chiMetricsMiddleware ... Injects a metrics recorder into request processing middleware func chiMetricsMiddleware(rec metrics.HTTPRecorder) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { @@ -53,112 +65,121 @@ func chiMetricsMiddleware(rec metrics.HTTPRecorder) func(http.Handler) http.Hand } // NewApi ... Construct a new api instance -func NewApi(logger log.Logger, bv database.BridgeTransfersView, serverConfig config.ServerConfig, metricsConfig config.ServerConfig) *API { - // (1) Initialize dependencies - apiRouter := chi.NewRouter() - h := routes.NewRoutes(logger, bv, apiRouter) - - mr := metrics.NewRegistry() - promRecorder := metrics.NewPromHTTPRecorder(mr, MetricsNamespace) - - // (2) Inject routing middleware - apiRouter.Use(chiMetricsMiddleware(promRecorder)) - apiRouter.Use(middleware.Recoverer) - apiRouter.Use(middleware.Heartbeat(HealthPath)) +func NewApi(ctx context.Context, log log.Logger, cfg *Config) (*APIService, error) { + out := &APIService{log: log, metricsRegistry: metrics.NewRegistry()} + if err := out.initFromConfig(ctx, cfg); err != nil { + return nil, errors.Join(err, out.Stop(ctx)) // close any resources we may have opened already + } + return out, nil +} - // (3) Set GET routes - apiRouter.Get(fmt.Sprintf(DepositsPath+addressParam, ethereumAddressRegex), h.L1DepositsHandler) - apiRouter.Get(fmt.Sprintf(WithdrawalsPath+addressParam, ethereumAddressRegex), h.L2WithdrawalsHandler) +func (a *APIService) initFromConfig(ctx context.Context, cfg *Config) error { + if err := a.initDB(ctx, cfg.DB); err != nil { + return fmt.Errorf("failed to init DB: %w", err) + } + if err := a.startMetricsServer(cfg.MetricsServer); err != nil { + return fmt.Errorf("failed to start metrics server: %w", err) + } + a.initRouter(cfg.HTTPServer) + if err := a.startServer(cfg.HTTPServer); err != nil { + return fmt.Errorf("failed to start API server: %w", err) + } + return nil +} - return &API{log: logger, router: apiRouter, metricsRegistry: mr, serverConfig: serverConfig, metricsConfig: metricsConfig} +func (a *APIService) Start(ctx context.Context) error { + // Completed all setup-up jobs at init-time already, + // and the API service does not have any other special starting routines or background-jobs to start. + return nil } -// Run ... Runs the API server routines -func (a *API) Run(ctx context.Context) error { - var wg sync.WaitGroup - errCh := make(chan error, 2) - - // (1) Construct an inner function that will start a goroutine - // and handle any panics that occur on a shared error channel - processCtx, processCancel := context.WithCancel(ctx) - runProcess := func(start func(ctx context.Context) error) { - wg.Add(1) - go func() { - defer func() { - if err := recover(); err != nil { - a.log.Error("halting api on panic", "err", err) - debug.PrintStack() - errCh <- fmt.Errorf("panic: %v", err) - } - - processCancel() - wg.Done() - }() - - errCh <- start(processCtx) - }() +func (a *APIService) Stop(ctx context.Context) error { + var result error + if a.apiServer != nil { + if err := a.apiServer.Stop(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to stop API server: %w", err)) + } } + if a.metricsServer != nil { + if err := a.metricsServer.Stop(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err)) + } + } + if a.dbClose != nil { + if err := a.dbClose(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close DB: %w", err)) + } + } + a.stopped.Store(true) + a.log.Info("API service shutdown complete") + return result +} - // (2) Start the API and metrics servers - runProcess(a.startServer) - runProcess(a.startMetricsServer) +func (a *APIService) Stopped() bool { + return a.stopped.Load() +} - // (3) Wait for all processes to complete - wg.Wait() +// Addr ... returns the address that the HTTP server is listening on (excl. http:// prefix, just the host and port) +func (a *APIService) Addr() string { + if a.apiServer == nil { + return "" + } + return a.apiServer.Addr().String() +} - err := <-errCh +func (a *APIService) initDB(ctx context.Context, connector DBConnector) error { + db, err := connector.OpenDB(ctx, a.log) if err != nil { - a.log.Error("api stopped", "err", err) - } else { - a.log.Info("api stopped") + return fmt.Errorf("failed to connect to database: %w", err) } - - return err + a.dbClose = db.Closer + a.bv = db.BridgeTransfers + return nil } -// Port ... Returns the the port that server is listening on -func (a *API) Port() int { - return a.serverConfig.Port +func (a *APIService) initRouter(apiConfig config.ServerConfig) { + v := new(service.Validator) + + svc := service.New(v, a.bv, a.log) + apiRouter := chi.NewRouter() + h := routes.NewRoutes(a.log, apiRouter, svc) + + apiRouter.Use(middleware.Logger) + apiRouter.Use(middleware.Timeout(time.Duration(apiConfig.WriteTimeout) * time.Second)) + apiRouter.Use(middleware.Recoverer) + apiRouter.Use(middleware.Heartbeat(HealthPath)) + apiRouter.Use(chiMetricsMiddleware(metrics.NewPromHTTPRecorder(a.metricsRegistry, MetricsNamespace))) + + apiRouter.Get(fmt.Sprintf(DepositsPath+addressParam, ethereumAddressRegex), h.L1DepositsHandler) + apiRouter.Get(fmt.Sprintf(WithdrawalsPath+addressParam, ethereumAddressRegex), h.L2WithdrawalsHandler) + apiRouter.Get(SupplyPath, h.SupplyView) + apiRouter.Get(DocsPath, h.DocsHandler) + a.router = apiRouter } // startServer ... Starts the API server -func (a *API) startServer(ctx context.Context) error { - a.log.Debug("api server listening...", "port", a.serverConfig.Port) - addr := net.JoinHostPort(a.serverConfig.Host, strconv.Itoa(a.serverConfig.Port)) +func (a *APIService) startServer(serverConfig config.ServerConfig) error { + a.log.Debug("API server listening...", "port", serverConfig.Port) + + addr := net.JoinHostPort(serverConfig.Host, strconv.Itoa(serverConfig.Port)) srv, err := httputil.StartHTTPServer(addr, a.router) if err != nil { return fmt.Errorf("failed to start API server: %w", err) } - host, portStr, err := net.SplitHostPort(srv.Addr().String()) - if err != nil { - return errors.Join(err, srv.Close()) - } - port, err := strconv.Atoi(portStr) - if err != nil { - return errors.Join(err, srv.Close()) - } - - // Update the port in the config in case the OS chose a different port - // than the one we requested (e.g. using port 0 to fetch a random open port) - a.serverConfig.Host = host - a.serverConfig.Port = port - - <-ctx.Done() - if err := srv.Stop(context.Background()); err != nil { - return fmt.Errorf("failed to shutdown api server: %w", err) - } + a.log.Info("API server started", "addr", srv.Addr().String()) + a.apiServer = srv return nil } // startMetricsServer ... Starts the metrics server -func (a *API) startMetricsServer(ctx context.Context) error { - a.log.Debug("starting metrics server...", "port", a.metricsConfig.Port) - srv, err := metrics.StartServer(a.metricsRegistry, a.metricsConfig.Host, a.metricsConfig.Port) +func (a *APIService) startMetricsServer(metricsConfig config.ServerConfig) error { + a.log.Debug("starting metrics server...", "port", metricsConfig.Port) + srv, err := metrics.StartServer(a.metricsRegistry, metricsConfig.Host, metricsConfig.Port) if err != nil { return fmt.Errorf("failed to start metrics server: %w", err) } - <-ctx.Done() - defer a.log.Info("metrics server stopped") - return srv.Stop(context.Background()) + a.log.Info("Metrics server started", "addr", srv.Addr().String()) + a.metricsServer = srv + return nil } diff --git a/indexer/api/api_test.go b/indexer/api/api_test.go index 554fce28ce51..e69a22fbfcf4 100644 --- a/indexer/api/api_test.go +++ b/indexer/api/api_test.go @@ -1,6 +1,7 @@ package api import ( + "context" "encoding/json" "fmt" "net/http" @@ -24,11 +25,12 @@ var mockAddress = "0x4204204204204204204204204204204204204204" var apiConfig = config.ServerConfig{ Host: "localhost", - Port: 8080, + Port: 0, // random port, to allow parallel tests } + var metricsConfig = config.ServerConfig{ Host: "localhost", - Port: 7300, + Port: 0, // random port, to allow parallel tests } var ( @@ -93,10 +95,24 @@ func (mbv *MockBridgeTransfersView) L2BridgeWithdrawalsByAddress(address common. }, }, nil } + +func (mbv *MockBridgeTransfersView) L1TxDepositSum() (float64, error) { + return 69, nil +} +func (mbv *MockBridgeTransfersView) L2BridgeWithdrawalSum(database.WithdrawFilter) (float64, error) { + return 420, nil +} + func TestHealthz(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) - api := NewApi(logger, &MockBridgeTransfersView{}, apiConfig, metricsConfig) - request, err := http.NewRequest("GET", "/healthz", nil) + logger := testlog.Logger(t, log.LevelInfo) + cfg := &Config{ + DB: &TestDBConnector{BridgeTransfers: &MockBridgeTransfersView{}}, + HTTPServer: apiConfig, + MetricsServer: metricsConfig, + } + api, err := NewApi(context.Background(), logger, cfg) + require.NoError(t, err) + request, err := http.NewRequest("GET", "http://"+api.Addr()+"/healthz", nil) assert.Nil(t, err) responseRecorder := httptest.NewRecorder() @@ -106,9 +122,15 @@ func TestHealthz(t *testing.T) { } func TestL1BridgeDepositsHandler(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) - api := NewApi(logger, &MockBridgeTransfersView{}, apiConfig, metricsConfig) - request, err := http.NewRequest("GET", fmt.Sprintf("/api/v0/deposits/%s", mockAddress), nil) + logger := testlog.Logger(t, log.LevelInfo) + cfg := &Config{ + DB: &TestDBConnector{BridgeTransfers: &MockBridgeTransfersView{}}, + HTTPServer: apiConfig, + MetricsServer: metricsConfig, + } + api, err := NewApi(context.Background(), logger, cfg) + require.NoError(t, err) + request, err := http.NewRequest("GET", fmt.Sprintf("http://"+api.Addr()+"/api/v0/deposits/%s", mockAddress), nil) assert.Nil(t, err) responseRecorder := httptest.NewRecorder() @@ -129,9 +151,15 @@ func TestL1BridgeDepositsHandler(t *testing.T) { } func TestL2BridgeWithdrawalsByAddressHandler(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) - api := NewApi(logger, &MockBridgeTransfersView{}, apiConfig, metricsConfig) - request, err := http.NewRequest("GET", fmt.Sprintf("/api/v0/withdrawals/%s", mockAddress), nil) + logger := testlog.Logger(t, log.LevelInfo) + cfg := &Config{ + DB: &TestDBConnector{BridgeTransfers: &MockBridgeTransfersView{}}, + HTTPServer: apiConfig, + MetricsServer: metricsConfig, + } + api, err := NewApi(context.Background(), logger, cfg) + require.NoError(t, err) + request, err := http.NewRequest("GET", fmt.Sprintf("http://"+api.Addr()+"/api/v0/withdrawals/%s", mockAddress), nil) assert.Nil(t, err) responseRecorder := httptest.NewRecorder() @@ -149,8 +177,8 @@ func TestL2BridgeWithdrawalsByAddressHandler(t *testing.T) { assert.Equal(t, resp.Items[0].To, withdrawal.Tx.ToAddress.String()) assert.Equal(t, resp.Items[0].TransactionHash, common.HexToHash("0x789").String()) assert.Equal(t, resp.Items[0].Amount, withdrawal.Tx.Amount.String()) - assert.Equal(t, resp.Items[0].ProofTransactionHash, common.HexToHash("0x123").String()) - assert.Equal(t, resp.Items[0].ClaimTransactionHash, common.HexToHash("0x123").String()) + assert.Equal(t, resp.Items[0].L1ProvenTxHash, common.HexToHash("0x123").String()) + assert.Equal(t, resp.Items[0].L1FinalizedTxHash, common.HexToHash("0x123").String()) assert.Equal(t, resp.Items[0].L1TokenAddress, withdrawal.TokenPair.RemoteTokenAddress.String()) assert.Equal(t, resp.Items[0].L2TokenAddress, withdrawal.TokenPair.LocalTokenAddress.String()) assert.Equal(t, resp.Items[0].Timestamp, withdrawal.Tx.Timestamp) diff --git a/indexer/api/config.go b/indexer/api/config.go new file mode 100644 index 000000000000..9db26bfffc13 --- /dev/null +++ b/indexer/api/config.go @@ -0,0 +1,60 @@ +package api + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/indexer/config" + "github.com/ethereum-optimism/optimism/indexer/database" +) + +// DB represents the abstract DB access the API has. +type DB struct { + BridgeTransfers database.BridgeTransfersView + Closer func() error +} + +// DBConfigConnector implements a fully config based DBConnector +type DBConfigConnector struct { + config.DBConfig +} + +func (cfg *DBConfigConnector) OpenDB(ctx context.Context, log log.Logger) (*DB, error) { + db, err := database.NewDB(ctx, log, cfg.DBConfig) + if err != nil { + return nil, fmt.Errorf("failed to connect to database: %w", err) + } + return &DB{ + BridgeTransfers: db.BridgeTransfers, + Closer: db.Close, + }, nil +} + +type TestDBConnector struct { + BridgeTransfers database.BridgeTransfersView +} + +func (tdb *TestDBConnector) OpenDB(ctx context.Context, log log.Logger) (*DB, error) { + return &DB{ + BridgeTransfers: tdb.BridgeTransfers, + Closer: func() error { + log.Info("API service closed test DB view") + return nil + }, + }, nil +} + +// DBConnector is an interface: the config may provide different ways to access the DB. +// This is implemented in tests to provide custom DB views, or share the DB with other services. +type DBConnector interface { + OpenDB(ctx context.Context, log log.Logger) (*DB, error) +} + +// Config for the API service +type Config struct { + DB DBConnector + HTTPServer config.ServerConfig + MetricsServer config.ServerConfig +} diff --git a/indexer/api/models/models.go b/indexer/api/models/models.go index 6ccdeae2f057..f62b1dc6f33a 100644 --- a/indexer/api/models/models.go +++ b/indexer/api/models/models.go @@ -1,5 +1,15 @@ package models +import ( + "github.com/ethereum/go-ethereum/common" +) + +type QueryParams struct { + Address common.Address + Limit int + Cursor string +} + // DepositItem ... Deposit item model for API responses type DepositItem struct { Guid string `json:"guid"` @@ -23,18 +33,18 @@ type DepositResponse struct { // WithdrawalItem ... Data model for API JSON response type WithdrawalItem struct { - Guid string `json:"guid"` - From string `json:"from"` - To string `json:"to"` - TransactionHash string `json:"transactionHash"` - MessageHash string `json:"messageHash"` - Timestamp uint64 `json:"timestamp"` - L2BlockHash string `json:"l2BlockHash"` - Amount string `json:"amount"` - ProofTransactionHash string `json:"proofTransactionHash"` - ClaimTransactionHash string `json:"claimTransactionHash"` - L1TokenAddress string `json:"l1TokenAddress"` - L2TokenAddress string `json:"l2TokenAddress"` + Guid string `json:"guid"` + From string `json:"from"` + To string `json:"to"` + TransactionHash string `json:"transactionHash"` + CrossDomainMessageHash string `json:"crossDomainMessageHash"` + Timestamp uint64 `json:"timestamp"` + L2BlockHash string `json:"l2BlockHash"` + Amount string `json:"amount"` + L1ProvenTxHash string `json:"l1ProvenTxHash"` + L1FinalizedTxHash string `json:"l1FinalizedTxHash"` + L1TokenAddress string `json:"l1TokenAddress"` + L2TokenAddress string `json:"l2TokenAddress"` } // WithdrawalResponse ... Data model for API JSON response @@ -43,3 +53,10 @@ type WithdrawalResponse struct { HasNextPage bool `json:"hasNextPage"` Items []WithdrawalItem `json:"items"` } + +type BridgeSupplyView struct { + L1DepositSum float64 `json:"l1DepositSum"` + InitWithdrawalSum float64 `json:"l2WithdrawalSum"` + ProvenWithdrawSum float64 `json:"provenSum"` + FinalizedWithdrawSum float64 `json:"finalizedSum"` +} diff --git a/indexer/api/models/models_test.go b/indexer/api/models/models_test.go new file mode 100644 index 000000000000..0e60304c7357 --- /dev/null +++ b/indexer/api/models/models_test.go @@ -0,0 +1 @@ +package models_test diff --git a/indexer/api/routes/common.go b/indexer/api/routes/common.go index 8aad71ee3bd7..63a0106bd305 100644 --- a/indexer/api/routes/common.go +++ b/indexer/api/routes/common.go @@ -7,9 +7,6 @@ import ( const ( InternalServerError = "Internal server error" - - // defaultPageLimit ... Default page limit for pagination - defaultPageLimit = 100 ) // jsonResponse ... Marshals and writes a JSON response provided arbitrary data diff --git a/indexer/api/routes/deposits.go b/indexer/api/routes/deposits.go index 5bf6229a25a7..f66e70b6ab33 100644 --- a/indexer/api/routes/deposits.go +++ b/indexer/api/routes/deposits.go @@ -3,76 +3,32 @@ package routes import ( "net/http" - "github.com/ethereum-optimism/optimism/indexer/api/models" - - "github.com/ethereum-optimism/optimism/indexer/database" "github.com/go-chi/chi/v5" ) -// newDepositResponse ... Converts a database.L1BridgeDepositsResponse to an api.DepositResponse -func newDepositResponse(deposits *database.L1BridgeDepositsResponse) models.DepositResponse { - items := make([]models.DepositItem, len(deposits.Deposits)) - for i, deposit := range deposits.Deposits { - item := models.DepositItem{ - Guid: deposit.L1BridgeDeposit.TransactionSourceHash.String(), - L1BlockHash: deposit.L1BlockHash.String(), - Timestamp: deposit.L1BridgeDeposit.Tx.Timestamp, - L1TxHash: deposit.L1TransactionHash.String(), - L2TxHash: deposit.L2TransactionHash.String(), - From: deposit.L1BridgeDeposit.Tx.FromAddress.String(), - To: deposit.L1BridgeDeposit.Tx.ToAddress.String(), - Amount: deposit.L1BridgeDeposit.Tx.Amount.String(), - L1TokenAddress: deposit.L1BridgeDeposit.TokenPair.LocalTokenAddress.String(), - L2TokenAddress: deposit.L1BridgeDeposit.TokenPair.RemoteTokenAddress.String(), - } - items[i] = item - } - - return models.DepositResponse{ - Cursor: deposits.Cursor, - HasNextPage: deposits.HasNextPage, - Items: items, - } -} - // L1DepositsHandler ... Handles /api/v0/deposits/{address} GET requests func (h Routes) L1DepositsHandler(w http.ResponseWriter, r *http.Request) { - addressValue := chi.URLParam(r, "address") + address := chi.URLParam(r, "address") cursor := r.URL.Query().Get("cursor") - limitQuery := r.URL.Query().Get("limit") - - address, err := h.v.ParseValidateAddress(addressValue) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - h.logger.Error("Invalid address param", "param", addressValue) - h.logger.Error(err.Error()) - return - } + limit := r.URL.Query().Get("limit") - err = h.v.ValidateCursor(cursor) + params, err := h.svc.QueryParams(address, cursor, limit) if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - h.logger.Error("Invalid cursor param", "param", cursor, "err", err.Error()) - } - - limit, err := h.v.ParseValidateLimit(limitQuery) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - h.logger.Error("Invalid limit param", "param", limitQuery, "err", err.Error()) + http.Error(w, "invalid query params", http.StatusBadRequest) + h.logger.Error("error reading request params", "err", err.Error()) return } - deposits, err := h.view.L1BridgeDepositsByAddress(address, cursor, limit) + deposits, err := h.svc.GetDeposits(params) if err != nil { - http.Error(w, "Internal server error reading deposits", http.StatusInternalServerError) - h.logger.Error("Unable to read deposits from DB", "err", err.Error()) + http.Error(w, "internal server error", http.StatusInternalServerError) + h.logger.Error("error fetching deposits", "err", err.Error()) return } - response := newDepositResponse(deposits) - - err = jsonResponse(w, response, http.StatusOK) + resp := h.svc.DepositResponse(deposits) + err = jsonResponse(w, resp, http.StatusOK) if err != nil { - h.logger.Error("Error writing response", "err", err) + h.logger.Error("error writing response", "err", err) } } diff --git a/indexer/api/routes/routes.go b/indexer/api/routes/routes.go index 488805b08872..457a7ed92dd9 100644 --- a/indexer/api/routes/routes.go +++ b/indexer/api/routes/routes.go @@ -1,24 +1,22 @@ package routes import ( - "github.com/ethereum-optimism/optimism/indexer/database" + "github.com/ethereum-optimism/optimism/indexer/api/service" "github.com/ethereum/go-ethereum/log" "github.com/go-chi/chi/v5" ) -// Routes ... Route handler struct type Routes struct { logger log.Logger - view database.BridgeTransfersView router *chi.Mux - v *Validator + svc service.Service } // NewRoutes ... Construct a new route handler instance -func NewRoutes(logger log.Logger, bv database.BridgeTransfersView, r *chi.Mux) Routes { +func NewRoutes(l log.Logger, r *chi.Mux, svc service.Service) Routes { return Routes{ - logger: logger, - view: bv, + logger: l, router: r, + svc: svc, } } diff --git a/indexer/api/routes/supply.go b/indexer/api/routes/supply.go new file mode 100644 index 000000000000..4fa4c0aa6f2f --- /dev/null +++ b/indexer/api/routes/supply.go @@ -0,0 +1,21 @@ +package routes + +import ( + "net/http" +) + +// SupplyView ... Handles /api/v0/supply GET requests +func (h Routes) SupplyView(w http.ResponseWriter, r *http.Request) { + + view, err := h.svc.GetSupplyInfo() + if err != nil { + http.Error(w, "Internal server error", http.StatusInternalServerError) + h.logger.Error("error getting supply info", "err", err) + return + } + + err = jsonResponse(w, view, http.StatusOK) + if err != nil { + h.logger.Error("error writing response", "err", err) + } +} diff --git a/indexer/api/routes/validator.go b/indexer/api/routes/validator.go deleted file mode 100644 index 5d72a79ba8a4..000000000000 --- a/indexer/api/routes/validator.go +++ /dev/null @@ -1,62 +0,0 @@ -package routes - -import ( - "strconv" - - "errors" - - "github.com/ethereum/go-ethereum/common" -) - -// Validator ... Validates API user request parameters -type Validator struct{} - -// ParseValidateLimit ... Validates and parses the limit query parameters -func (v *Validator) ParseValidateLimit(limit string) (int, error) { - if limit == "" { - return defaultPageLimit, nil - } - - val, err := strconv.Atoi(limit) - if err != nil { - return 0, errors.New("limit must be an integer value") - } - - if val <= 0 { - return 0, errors.New("limit must be greater than 0") - } - - // TODO - Add a check against a max limit value - return val, nil -} - -// ParseValidateAddress ... Validates and parses the address query parameter -func (v *Validator) ParseValidateAddress(addr string) (common.Address, error) { - if !common.IsHexAddress(addr) { - return common.Address{}, errors.New("address must be represented as a valid hexadecimal string") - } - - parsedAddr := common.HexToAddress(addr) - if parsedAddr == common.HexToAddress("0x0") { - return common.Address{}, errors.New("address cannot be the zero address") - } - - return parsedAddr, nil -} - -// ValidateCursor ... Validates and parses the cursor query parameter -func (v *Validator) ValidateCursor(cursor string) error { - if cursor == "" { - return nil - } - - if len(cursor) != 66 { // 0x + 64 chars - return errors.New("cursor must be a 32 byte hex string") - } - - if cursor[:2] != "0x" { - return errors.New("cursor must begin with 0x") - } - - return nil -} diff --git a/indexer/api/routes/validator_test.go b/indexer/api/routes/validator_test.go deleted file mode 100644 index c59905a335fa..000000000000 --- a/indexer/api/routes/validator_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package routes - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestParseValidateLimit(t *testing.T) { - v := Validator{} - - // (1) Happy case - limit := "100" - _, err := v.ParseValidateLimit(limit) - require.NoError(t, err, "limit should be valid") - - // (2) Boundary validation - limit = "0" - _, err = v.ParseValidateLimit(limit) - require.Error(t, err, "limit must be greater than 0") - - // (3) Type validation - limit = "abc" - _, err = v.ParseValidateLimit(limit) - require.Error(t, err, "limit must be an integer value") -} - -func TestParseValidateAddress(t *testing.T) { - v := Validator{} - - // (1) Happy case - addr := "0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5" - _, err := v.ParseValidateAddress(addr) - require.NoError(t, err, "address should be pass") - - // (2) Invalid hex - addr = "🫡" - _, err = v.ParseValidateAddress(addr) - require.Error(t, err, "address must be represented as a valid hexadecimal string") - - // (3) Zero address - addr = "0x0000000000000000000000000000000000000000" - _, err = v.ParseValidateAddress(addr) - require.Error(t, err, "address cannot be black-hole value") -} - -func Test_ParseValidateCursor(t *testing.T) { - v := Validator{} - - // (1) Happy case - cursor := "0xf3fd2eb696dab4263550b938726f9b3606e334cce6ebe27446bc26cb700b94e0" - err := v.ValidateCursor(cursor) - require.NoError(t, err, "cursor should be pass") - - // (2) Invalid length - cursor = "0x000" - err = v.ValidateCursor(cursor) - require.Error(t, err, "cursor must be 32 byte hex string") - - // (3) Invalid hex - cursor = "0🫡" - err = v.ValidateCursor(cursor) - require.Error(t, err, "cursor must start with 0x") -} diff --git a/indexer/api/routes/withdrawals.go b/indexer/api/routes/withdrawals.go index 7c3ed399c00e..8c26b9e26f18 100644 --- a/indexer/api/routes/withdrawals.go +++ b/indexer/api/routes/withdrawals.go @@ -3,75 +3,31 @@ package routes import ( "net/http" - "github.com/ethereum-optimism/optimism/indexer/api/models" - "github.com/ethereum-optimism/optimism/indexer/database" "github.com/go-chi/chi/v5" ) -// FIXME make a pure function that returns a struct instead of newWithdrawalResponse -// newWithdrawalResponse ... Converts a database.L2BridgeWithdrawalsResponse to an api.WithdrawalResponse -func newWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) models.WithdrawalResponse { - items := make([]models.WithdrawalItem, len(withdrawals.Withdrawals)) - for i, withdrawal := range withdrawals.Withdrawals { - item := models.WithdrawalItem{ - Guid: withdrawal.L2BridgeWithdrawal.TransactionWithdrawalHash.String(), - L2BlockHash: withdrawal.L2BlockHash.String(), - Timestamp: withdrawal.L2BridgeWithdrawal.Tx.Timestamp, - From: withdrawal.L2BridgeWithdrawal.Tx.FromAddress.String(), - To: withdrawal.L2BridgeWithdrawal.Tx.ToAddress.String(), - TransactionHash: withdrawal.L2TransactionHash.String(), - Amount: withdrawal.L2BridgeWithdrawal.Tx.Amount.String(), - ProofTransactionHash: withdrawal.ProvenL1TransactionHash.String(), - ClaimTransactionHash: withdrawal.FinalizedL1TransactionHash.String(), - L1TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.RemoteTokenAddress.String(), - L2TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.LocalTokenAddress.String(), - } - items[i] = item - } - - return models.WithdrawalResponse{ - Cursor: withdrawals.Cursor, - HasNextPage: withdrawals.HasNextPage, - Items: items, - } -} - // L2WithdrawalsHandler ... Handles /api/v0/withdrawals/{address} GET requests func (h Routes) L2WithdrawalsHandler(w http.ResponseWriter, r *http.Request) { - addressValue := chi.URLParam(r, "address") + address := chi.URLParam(r, "address") cursor := r.URL.Query().Get("cursor") - limitQuery := r.URL.Query().Get("limit") - - address, err := h.v.ParseValidateAddress(addressValue) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - h.logger.Error("Invalid address param", "param", addressValue, "err", err) - return - } - - err = h.v.ValidateCursor(cursor) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - h.logger.Error("Invalid cursor param", "param", cursor, "err", err) - return - } + limit := r.URL.Query().Get("limit") - limit, err := h.v.ParseValidateLimit(limitQuery) + params, err := h.svc.QueryParams(address, cursor, limit) if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - h.logger.Error("Invalid query params", "err", err) + http.Error(w, "Invalid query params", http.StatusBadRequest) + h.logger.Error("Invalid query params", "err", err.Error()) return } - withdrawals, err := h.view.L2BridgeWithdrawalsByAddress(address, cursor, limit) + withdrawals, err := h.svc.GetWithdrawals(params) if err != nil { - http.Error(w, "Internal server error reading withdrawals", http.StatusInternalServerError) - h.logger.Error("Unable to read withdrawals from DB", "err", err.Error()) + http.Error(w, "Internal server error", http.StatusInternalServerError) + h.logger.Error("Error getting withdrawals", "err", err.Error()) return } - response := newWithdrawalResponse(withdrawals) - err = jsonResponse(w, response, http.StatusOK) + resp := h.svc.WithdrawResponse(withdrawals) + err = jsonResponse(w, resp, http.StatusOK) if err != nil { h.logger.Error("Error writing response", "err", err.Error()) } diff --git a/indexer/api/service/service.go b/indexer/api/service/service.go new file mode 100644 index 000000000000..ba61acb72f46 --- /dev/null +++ b/indexer/api/service/service.go @@ -0,0 +1,175 @@ +package service + +import ( + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/indexer/api/models" + "github.com/ethereum-optimism/optimism/indexer/database" + "github.com/ethereum/go-ethereum/common" +) + +type Service interface { + GetDeposits(*models.QueryParams) (*database.L1BridgeDepositsResponse, error) + DepositResponse(*database.L1BridgeDepositsResponse) models.DepositResponse + GetWithdrawals(params *models.QueryParams) (*database.L2BridgeWithdrawalsResponse, error) + WithdrawResponse(*database.L2BridgeWithdrawalsResponse) models.WithdrawalResponse + GetSupplyInfo() (*models.BridgeSupplyView, error) + + QueryParams(address, cursor, limit string) (*models.QueryParams, error) +} + +type HandlerSvc struct { + v *Validator + db database.BridgeTransfersView + logger log.Logger +} + +func New(v *Validator, db database.BridgeTransfersView, l log.Logger) Service { + return &HandlerSvc{ + logger: l, + v: v, + db: db, + } +} + +func (svc *HandlerSvc) QueryParams(a, c, l string) (*models.QueryParams, error) { + address, err := svc.v.ParseValidateAddress(a) + if err != nil { + svc.logger.Error("invalid address param", "param", a, "err", err) + return nil, err + } + + err = svc.v.ValidateCursor(c) + if err != nil { + svc.logger.Error("invalid cursor param", "cursor", c, "err", err) + return nil, err + } + + limit, err := svc.v.ParseValidateLimit(l) + if err != nil { + svc.logger.Error("invalid query param", "cursor", c, "err", err) + return nil, err + } + + return &models.QueryParams{ + Address: address, + Cursor: c, + Limit: limit, + }, nil + +} + +func (svc *HandlerSvc) GetWithdrawals(params *models.QueryParams) (*database.L2BridgeWithdrawalsResponse, error) { + withdrawals, err := svc.db.L2BridgeWithdrawalsByAddress(params.Address, params.Cursor, params.Limit) + if err != nil { + svc.logger.Error("error getting withdrawals", "err", err.Error(), "address", params.Address.String()) + return nil, err + } + + svc.logger.Debug("read withdrawals from db", "count", len(withdrawals.Withdrawals), "address", params.Address.String()) + return withdrawals, nil +} + +func (svc *HandlerSvc) WithdrawResponse(withdrawals *database.L2BridgeWithdrawalsResponse) models.WithdrawalResponse { + items := make([]models.WithdrawalItem, len(withdrawals.Withdrawals)) + for i, withdrawal := range withdrawals.Withdrawals { + + cdh := withdrawal.L2BridgeWithdrawal.CrossDomainMessageHash + if cdh == nil { // Zero value indicates that the withdrawal didn't have a cross domain message + cdh = &common.Hash{0} + } + + item := models.WithdrawalItem{ + Guid: withdrawal.L2BridgeWithdrawal.TransactionWithdrawalHash.String(), + L2BlockHash: withdrawal.L2BlockHash.String(), + Timestamp: withdrawal.L2BridgeWithdrawal.Tx.Timestamp, + From: withdrawal.L2BridgeWithdrawal.Tx.FromAddress.String(), + To: withdrawal.L2BridgeWithdrawal.Tx.ToAddress.String(), + TransactionHash: withdrawal.L2TransactionHash.String(), + Amount: withdrawal.L2BridgeWithdrawal.Tx.Amount.String(), + CrossDomainMessageHash: cdh.String(), + L1ProvenTxHash: withdrawal.ProvenL1TransactionHash.String(), + L1FinalizedTxHash: withdrawal.FinalizedL1TransactionHash.String(), + L1TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.RemoteTokenAddress.String(), + L2TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.LocalTokenAddress.String(), + } + items[i] = item + } + + return models.WithdrawalResponse{ + Cursor: withdrawals.Cursor, + HasNextPage: withdrawals.HasNextPage, + Items: items, + } +} + +func (svc *HandlerSvc) GetDeposits(params *models.QueryParams) (*database.L1BridgeDepositsResponse, error) { + deposits, err := svc.db.L1BridgeDepositsByAddress(params.Address, params.Cursor, params.Limit) + if err != nil { + svc.logger.Error("error getting deposits", "err", err.Error(), "address", params.Address.String()) + return nil, err + } + + svc.logger.Debug("read deposits from db", "count", len(deposits.Deposits), "address", params.Address.String()) + return deposits, nil +} + +// DepositResponse ... Converts a database.L1BridgeDepositsResponse to an api.DepositResponse +func (svc *HandlerSvc) DepositResponse(deposits *database.L1BridgeDepositsResponse) models.DepositResponse { + items := make([]models.DepositItem, len(deposits.Deposits)) + for i, deposit := range deposits.Deposits { + item := models.DepositItem{ + Guid: deposit.L1BridgeDeposit.TransactionSourceHash.String(), + L1BlockHash: deposit.L1BlockHash.String(), + Timestamp: deposit.L1BridgeDeposit.Tx.Timestamp, + L1TxHash: deposit.L1TransactionHash.String(), + L2TxHash: deposit.L2TransactionHash.String(), + From: deposit.L1BridgeDeposit.Tx.FromAddress.String(), + To: deposit.L1BridgeDeposit.Tx.ToAddress.String(), + Amount: deposit.L1BridgeDeposit.Tx.Amount.String(), + L1TokenAddress: deposit.L1BridgeDeposit.TokenPair.LocalTokenAddress.String(), + L2TokenAddress: deposit.L1BridgeDeposit.TokenPair.RemoteTokenAddress.String(), + } + items[i] = item + } + + return models.DepositResponse{ + Cursor: deposits.Cursor, + HasNextPage: deposits.HasNextPage, + Items: items, + } +} + +// GetSupplyInfo ... Fetch native bridge supply info +func (svc *HandlerSvc) GetSupplyInfo() (*models.BridgeSupplyView, error) { + depositSum, err := svc.db.L1TxDepositSum() + if err != nil { + svc.logger.Error("error getting deposit sum", "err", err) + return nil, err + } + + initSum, err := svc.db.L2BridgeWithdrawalSum(database.All) + if err != nil { + svc.logger.Error("error getting init sum", "err", err) + return nil, err + } + + provenSum, err := svc.db.L2BridgeWithdrawalSum(database.Proven) + if err != nil { + svc.logger.Error("error getting proven sum", "err", err) + return nil, err + } + + finalizedSum, err := svc.db.L2BridgeWithdrawalSum(database.Finalized) + if err != nil { + svc.logger.Error("error getting finalized sum", "err", err) + return nil, err + } + + return &models.BridgeSupplyView{ + L1DepositSum: depositSum, + InitWithdrawalSum: initSum, + ProvenWithdrawSum: provenSum, + FinalizedWithdrawSum: finalizedSum, + }, nil +} diff --git a/indexer/api/service/service_test.go b/indexer/api/service/service_test.go new file mode 100644 index 000000000000..1ec994148fa1 --- /dev/null +++ b/indexer/api/service/service_test.go @@ -0,0 +1,132 @@ +package service_test + +import ( + "fmt" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/indexer/api/service" + "github.com/ethereum-optimism/optimism/indexer/database" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func assertFieldsAreSet(t *testing.T, item any) { + structType := reflect.TypeOf(item) + + structVal := reflect.ValueOf(item) + fieldNum := structVal.NumField() + + for i := 0; i < fieldNum; i++ { + field := structVal.Field(i) + fieldName := structType.Field(i).Name + + isSet := field.IsValid() && !field.IsZero() + + require.True(t, isSet, fmt.Sprintf("%s in not set", fieldName)) + + } +} + +func TestWithdrawalResponse(t *testing.T) { + svc := service.New(nil, nil, nil) + cdh := common.HexToHash("0x2") + + withdraws := &database.L2BridgeWithdrawalsResponse{ + Withdrawals: []database.L2BridgeWithdrawalWithTransactionHashes{ + { + L2BridgeWithdrawal: database.L2BridgeWithdrawal{ + TransactionWithdrawalHash: common.HexToHash("0x1"), + BridgeTransfer: database.BridgeTransfer{ + CrossDomainMessageHash: &cdh, + Tx: database.Transaction{ + FromAddress: common.HexToAddress("0x3"), + ToAddress: common.HexToAddress("0x4"), + Timestamp: 5, + }, + TokenPair: database.TokenPair{ + LocalTokenAddress: common.HexToAddress("0x6"), + RemoteTokenAddress: common.HexToAddress("0x7"), + }, + }, + }, + }, + }, + } + + response := svc.WithdrawResponse(withdraws) + require.NotEmpty(t, response.Items) + require.Len(t, response.Items, 1) + assertFieldsAreSet(t, response.Items[0]) +} + +func TestDepositResponse(t *testing.T) { + cdh := common.HexToHash("0x2") + svc := service.New(nil, nil, nil) + + deposits := &database.L1BridgeDepositsResponse{ + Deposits: []database.L1BridgeDepositWithTransactionHashes{ + { + L1BridgeDeposit: database.L1BridgeDeposit{ + BridgeTransfer: database.BridgeTransfer{ + CrossDomainMessageHash: &cdh, + Tx: database.Transaction{ + FromAddress: common.HexToAddress("0x3"), + ToAddress: common.HexToAddress("0x4"), + Timestamp: 5, + }, + TokenPair: database.TokenPair{ + LocalTokenAddress: common.HexToAddress("0x6"), + RemoteTokenAddress: common.HexToAddress("0x7"), + }, + }, + }, + }, + }, + } + + response := svc.DepositResponse(deposits) + require.NotEmpty(t, response.Items) + require.Len(t, response.Items, 1) + assertFieldsAreSet(t, response.Items[0]) +} + +func TestQueryParams(t *testing.T) { + + var tests = []struct { + name string + test func(*testing.T, service.Service) + }{ + { + name: "empty params", + test: func(t *testing.T, svc service.Service) { + params, err := svc.QueryParams("", "", "") + require.Error(t, err) + require.Nil(t, params) + }, + }, + { + name: "empty params except address", + test: func(t *testing.T, svc service.Service) { + addr := common.HexToAddress("0x420") + params, err := svc.QueryParams(addr.String(), "", "") + require.NoError(t, err) + require.NotNil(t, params) + require.Equal(t, addr, params.Address) + require.Equal(t, 100, params.Limit) + require.Equal(t, "", params.Cursor) + }, + }, + } + + v := new(service.Validator) + svc := service.New(v, nil, log.New()) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.test(t, svc) + }) + } +} diff --git a/indexer/api/service/validator.go b/indexer/api/service/validator.go new file mode 100644 index 000000000000..4e6a72199ec7 --- /dev/null +++ b/indexer/api/service/validator.go @@ -0,0 +1,61 @@ +package service + +import ( + "errors" + "strconv" + + "github.com/ethereum/go-ethereum/common" +) + +// Validator ... Validates API user request parameters +type Validator struct{} + +// ParseValidateAddress ... Validates and parses the address query parameter +func (v *Validator) ParseValidateAddress(addr string) (common.Address, error) { + if !common.IsHexAddress(addr) { + return common.Address{}, errors.New("address must be represented as a valid hexadecimal string") + } + + parsedAddr := common.HexToAddress(addr) + if parsedAddr == common.HexToAddress("0x0") { + return common.Address{}, errors.New("address cannot be the zero address") + } + + return parsedAddr, nil +} + +// ValidateCursor ... Validates and parses the cursor query parameter +func (v *Validator) ValidateCursor(cursor string) error { + if cursor == "" { + return nil + } + + if len(cursor) != 66 { // 0x + 64 chars + return errors.New("cursor must be a 32 byte hex string") + } + + if cursor[:2] != "0x" { + return errors.New("cursor must begin with 0x") + } + + return nil +} + +// ParseValidateLimit ... Validates and parses the limit query parameters +func (v *Validator) ParseValidateLimit(limit string) (int, error) { + if limit == "" { + return 100, nil + } + + val, err := strconv.Atoi(limit) + if err != nil { + return 0, errors.New("limit must be an integer value") + } + + if val <= 0 { + return 0, errors.New("limit must be greater than 0") + } + + // TODO - Add a check against a max limit value + return val, nil +} diff --git a/indexer/api/service/validator_test.go b/indexer/api/service/validator_test.go new file mode 100644 index 000000000000..fa4a76e6e7b0 --- /dev/null +++ b/indexer/api/service/validator_test.go @@ -0,0 +1,64 @@ +package service + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParseValidateLimit(t *testing.T) { + v := Validator{} + + // (1) Happy case + limit := "100" + _, err := v.ParseValidateLimit(limit) + require.NoError(t, err, "limit should be valid") + + // (2) Boundary validation + limit = "0" + _, err = v.ParseValidateLimit(limit) + require.Error(t, err, "limit must be greater than 0") + + // (3) Type validation + limit = "abc" + _, err = v.ParseValidateLimit(limit) + require.Error(t, err, "limit must be an integer value") +} + +func TestParseValidateAddress(t *testing.T) { + v := Validator{} + + // (1) Happy case + addr := "0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5" + _, err := v.ParseValidateAddress(addr) + require.NoError(t, err, "address should be pass") + + // (2) Invalid hex + addr = "🫡" + _, err = v.ParseValidateAddress(addr) + require.Error(t, err, "address must be represented as a valid hexadecimal string") + + // (3) Zero address + addr = "0x0000000000000000000000000000000000000000" + _, err = v.ParseValidateAddress(addr) + require.Error(t, err, "address cannot be black-hole value") +} + +func Test_ParseValidateCursor(t *testing.T) { + v := Validator{} + + // (1) Happy case + cursor := "0xf3fd2eb696dab4263550b938726f9b3606e334cce6ebe27446bc26cb700b94e0" + err := v.ValidateCursor(cursor) + require.NoError(t, err, "cursor should be pass") + + // (2) Invalid length + cursor = "0x000" + err = v.ValidateCursor(cursor) + require.Error(t, err, "cursor must be 32 byte hex string") + + // (3) Invalid hex + cursor = "0🫡" + err = v.ValidateCursor(cursor) + require.Error(t, err, "cursor must start with 0x") +} diff --git a/indexer/client/client.go b/indexer/client/client.go index 567794d456bb..63fdc80a50db 100644 --- a/indexer/client/client.go +++ b/indexer/client/client.go @@ -23,6 +23,7 @@ const ( healthz = "get_health" deposits = "get_deposits" withdrawals = "get_withdrawals" + sum = "get_sum" ) // Option ... Provides configuration through callback injection @@ -124,7 +125,7 @@ func (c *Client) HealthCheck() error { // GetDepositsByAddress ... Gets a deposit response object provided an L1 address and cursor func (c *Client) GetDepositsByAddress(l1Address common.Address, cursor string) (*models.DepositResponse, error) { - var dResponse *models.DepositResponse + var response models.DepositResponse url := c.cfg.BaseURL + api.DepositsPath + l1Address.String() + urlParams endpoint := fmt.Sprintf(url, cursor, c.cfg.PaginationLimit) @@ -133,11 +134,11 @@ func (c *Client) GetDepositsByAddress(l1Address common.Address, cursor string) ( return nil, err } - if err := json.Unmarshal(resp, &dResponse); err != nil { + if err := json.Unmarshal(resp, &response); err != nil { return nil, err } - return dResponse, nil + return &response, nil } // GetAllDepositsByAddress ... Gets all deposits provided a L1 address @@ -164,6 +165,25 @@ func (c *Client) GetAllDepositsByAddress(l1Address common.Address) ([]models.Dep } +// GetSupplyAssessment ... Returns an assessment of the current supply +// on both L1 and L2. This includes the individual sums of +// (L1/L2) deposits and withdrawals +func (c *Client) GetSupplyAssessment() (*models.BridgeSupplyView, error) { + url := c.cfg.BaseURL + api.SupplyPath + + resp, err := c.doRecordRequest(sum, url) + if err != nil { + return nil, err + } + + var bsv *models.BridgeSupplyView + if err := json.Unmarshal(resp, &bsv); err != nil { + return nil, err + } + + return bsv, nil +} + // GetAllWithdrawalsByAddress ... Gets all withdrawals provided a L2 address func (c *Client) GetAllWithdrawalsByAddress(l2Address common.Address) ([]models.WithdrawalItem, error) { var withdrawals []models.WithdrawalItem diff --git a/indexer/cmd/indexer/cli.go b/indexer/cmd/indexer/cli.go index ebf3b2a48db9..3e28a681ad42 100644 --- a/indexer/cmd/indexer/cli.go +++ b/indexer/cmd/indexer/cli.go @@ -1,14 +1,23 @@ package main import ( + "context" + "fmt" + "math/big" + + "github.com/urfave/cli/v2" + + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum-optimism/optimism/indexer" "github.com/ethereum-optimism/optimism/indexer/api" "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" + "github.com/ethereum-optimism/optimism/indexer/node" + "github.com/ethereum-optimism/optimism/op-service/cliapp" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum/go-ethereum/params" - - "github.com/urfave/cli/v2" + "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/opio" ) var ( @@ -25,60 +34,55 @@ var ( Usage: "path to migrations folder", EnvVars: []string{"INDEXER_MIGRATIONS_DIR"}, } + ReorgFlag = &cli.Uint64Flag{ + Name: "l1-height", + Aliases: []string{"height"}, + Usage: `the lowest l1 height that has been reorg'd. All L1 data and derived L2 state will be deleted. Since not all L1 blocks are + indexed, this will find the maximum indexed height <= the marker, which may result in slightly more deleted state.`, + Required: true, + } ) -func runIndexer(ctx *cli.Context) error { +func runIndexer(ctx *cli.Context, shutdown context.CancelCauseFunc) (cliapp.Lifecycle, error) { log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "indexer") - oplog.SetGlobalLogHandler(log.GetHandler()) + oplog.SetGlobalLogHandler(log.Handler()) log.Info("running indexer...") cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name)) if err != nil { log.Error("failed to load config", "err", err) - return err - } - - db, err := database.NewDB(log, cfg.DB) - if err != nil { - log.Error("failed to connect to database", "err", err) - return err + return nil, err } - defer db.Close() - indexer, err := indexer.NewIndexer(log, db, cfg.Chain, cfg.RPCs, cfg.HTTPServer, cfg.MetricsServer) - if err != nil { - log.Error("failed to create indexer", "err", err) - return err - } - - return indexer.Run(ctx.Context) + return indexer.NewIndexer(ctx.Context, log, &cfg, shutdown) } -func runApi(ctx *cli.Context) error { +func runApi(ctx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, error) { log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "api") - oplog.SetGlobalLogHandler(log.GetHandler()) + oplog.SetGlobalLogHandler(log.Handler()) log.Info("running api...") cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name)) if err != nil { log.Error("failed to load config", "err", err) - return err + return nil, err } - db, err := database.NewDB(log, cfg.DB) - if err != nil { - log.Error("failed to connect to database", "err", err) - return err + apiCfg := &api.Config{ + DB: &api.DBConfigConnector{DBConfig: cfg.DB}, + HTTPServer: cfg.HTTPServer, + MetricsServer: cfg.MetricsServer, } - defer db.Close() - api := api.NewApi(log, db.BridgeTransfers, cfg.HTTPServer, cfg.MetricsServer) - return api.Run(ctx.Context) + return api.NewApi(ctx.Context, log, apiCfg) } func runMigrations(ctx *cli.Context) error { + // We don't maintain a complicated lifecycle here, just interrupt to shut down. + ctx.Context = opio.CancelOnInterrupt(ctx.Context) + log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "migrations") - oplog.SetGlobalLogHandler(log.GetHandler()) + oplog.SetGlobalLogHandler(log.Handler()) log.Info("running migrations...") cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name)) @@ -87,7 +91,7 @@ func runMigrations(ctx *cli.Context) error { return err } - db, err := database.NewDB(log, cfg.DB) + db, err := database.NewDB(ctx.Context, log, cfg.DB) if err != nil { log.Error("failed to connect to database", "err", err) return err @@ -98,11 +102,40 @@ func runMigrations(ctx *cli.Context) error { return db.ExecuteSQLMigration(migrationsDir) } +func runReorgDeletion(ctx *cli.Context) error { + fromL1Height := ctx.Uint64(ReorgFlag.Name) + + log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "reorg-deletion") + oplog.SetGlobalLogHandler(log.Handler()) + cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name)) + if err != nil { + return fmt.Errorf("failed to load config: %w", err) + } + + l1Clnt, err := node.DialEthClient(ctx.Context, cfg.RPCs.L1RPC, node.NewMetrics(metrics.NewRegistry(), "l1")) + if err != nil { + return fmt.Errorf("failed to dial L1 client: %w", err) + } + l1Header, err := l1Clnt.BlockHeaderByNumber(big.NewInt(int64(fromL1Height))) + if err != nil { + return fmt.Errorf("failed to query L1 header at height: %w", err) + } else if l1Header == nil { + return fmt.Errorf("no header found at height") + } + + db, err := database.NewDB(ctx.Context, log, cfg.DB) + if err != nil { + return fmt.Errorf("failed to connect to database: %w", err) + } + + defer db.Close() + return db.Transaction(func(db *database.DB) error { + return db.Blocks.DeleteReorgedState(l1Header.Time) + }) +} + func newCli(GitCommit string, GitDate string) *cli.App { - flags := []cli.Flag{ConfigFlag} - flags = append(flags, oplog.CLIFlags("INDEXER")...) - migrationFlags := []cli.Flag{MigrationsFlag, ConfigFlag} - migrationFlags = append(migrationFlags, oplog.CLIFlags("INDEXER")...) + flags := append([]cli.Flag{ConfigFlag}, oplog.CLIFlags("INDEXER")...) return &cli.App{ Version: params.VersionWithCommit(GitCommit, GitDate), Description: "An indexer of all optimism events with a serving api layer", @@ -112,20 +145,27 @@ func newCli(GitCommit string, GitDate string) *cli.App { Name: "api", Flags: flags, Description: "Runs the api service", - Action: runApi, + Action: cliapp.LifecycleCmd(runApi), }, { Name: "index", Flags: flags, Description: "Runs the indexing service", - Action: runIndexer, + Action: cliapp.LifecycleCmd(runIndexer), }, { Name: "migrate", - Flags: migrationFlags, + Flags: append(flags, MigrationsFlag), Description: "Runs the database migrations", Action: runMigrations, }, + { + Name: "reorg-delete", + Aliases: []string{"reorg"}, + Flags: append(flags, ReorgFlag), + Description: "Deletes data that has been reorg'ed out of the canonical L1 chain", + Action: runReorgDeletion, + }, { Name: "version", Description: "print version", diff --git a/indexer/cmd/indexer/main.go b/indexer/cmd/indexer/main.go index 9026ea7c796c..341f10c4366b 100644 --- a/indexer/cmd/indexer/main.go +++ b/indexer/cmd/indexer/main.go @@ -4,9 +4,10 @@ import ( "context" "os" + "github.com/ethereum/go-ethereum/log" + oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/opio" - "github.com/ethereum/go-ethereum/log" ) var ( @@ -15,16 +16,10 @@ var ( ) func main() { - // This is the most root context, used to propagate - // cancellations to all spawned application-level goroutines - ctx, cancel := context.WithCancel(context.Background()) - go func() { - opio.BlockOnInterrupts() - cancel() - }() - oplog.SetupDefaults() app := newCli(GitCommit, GitDate) + // sub-commands set up their individual interrupt lifecycles, which can block on the given interrupt as needed. + ctx := opio.WithInterruptBlocker(context.Background()) if err := app.RunContext(ctx, os.Args); err != nil { log.Error("application failed", "err", err) os.Exit(1) diff --git a/indexer/config/config.go b/indexer/config/config.go index c8ecb286a6c3..813e6c7c5d20 100644 --- a/indexer/config/config.go +++ b/indexer/config/config.go @@ -1,6 +1,7 @@ package config import ( + "errors" "fmt" "os" "reflect" @@ -11,13 +12,8 @@ import ( "github.com/ethereum/go-ethereum/log" ) -const ( - // default to 5 seconds - defaultLoopInterval = 5000 - defaultHeaderBufferSize = 500 -) - -// In the future, presets can just be onchain config and fetched on initialization +// In the future, presets can just be onchain system config with everything else +// fetched on initialization // Config represents the `indexer.toml` file used to configure the indexer type Config struct { @@ -35,8 +31,9 @@ type L1Contracts struct { SystemConfigProxy common.Address `toml:"system-config"` // rollup state - OptimismPortalProxy common.Address `toml:"optimism-portal"` - L2OutputOracleProxy common.Address `toml:"l2-output-oracle"` + OptimismPortalProxy common.Address `toml:"optimism-portal"` + L2OutputOracleProxy common.Address `toml:"l2-output-oracle"` + DisputeGameFactoryProxy common.Address `toml:"dispute-game-factory"` // bridging L1CrossDomainMessengerProxy common.Address `toml:"l1-cross-domain-messenger"` @@ -134,10 +131,11 @@ type DBConfig struct { Password string `toml:"password"` } -// Configures the a server +// Configures the server type ServerConfig struct { - Host string `toml:"host"` - Port int `toml:"port"` + Host string `toml:"host"` + Port int `toml:"port"` + WriteTimeout int `toml:"timeout"` } // LoadConfig loads the `indexer.toml` config file from a given path @@ -195,24 +193,21 @@ func LoadConfig(log log.Logger, path string) (Config, error) { } } - // Defaults for any unset options - + // Check to make sure some required properties are set + var errs error if cfg.Chain.L1PollingInterval == 0 { - cfg.Chain.L1PollingInterval = defaultLoopInterval + errs = errors.Join(err, errors.New("`l1-polling-interval` unset")) } - if cfg.Chain.L2PollingInterval == 0 { - cfg.Chain.L2PollingInterval = defaultLoopInterval + errs = errors.Join(err, errors.New("`l2-polling-interval` unset")) } - if cfg.Chain.L1HeaderBufferSize == 0 { - cfg.Chain.L1HeaderBufferSize = defaultHeaderBufferSize + errs = errors.Join(err, errors.New("`l1-header-buffer-size` unset")) } - if cfg.Chain.L2HeaderBufferSize == 0 { - cfg.Chain.L2HeaderBufferSize = defaultHeaderBufferSize + errs = errors.Join(err, errors.New("`l2-header-buffer-size` unset")) } log.Info("loaded chain config", "config", cfg.Chain) - return cfg, nil + return cfg, errs } diff --git a/indexer/config/config_test.go b/indexer/config/config_test.go index 4e0b0652c29d..043016b09512 100644 --- a/indexer/config/config_test.go +++ b/indexer/config/config_test.go @@ -12,7 +12,7 @@ import ( ) func TestLoadConfig(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) tmpfile, err := os.CreateTemp("", "test.toml") require.NoError(t, err) defer os.Remove(tmpfile.Name()) @@ -22,6 +22,11 @@ func TestLoadConfig(t *testing.T) { [chain] preset = 420 + l1-polling-interval = 5000 + l2-polling-interval = 5000 + l1-header-buffer-size = 1000 + l2-header-buffer-size = 1000 + [rpcs] l1-rpc = "https://l1.example.com" l2-rpc = "https://l2.example.com" @@ -58,6 +63,10 @@ func TestLoadConfig(t *testing.T) { require.Equal(t, conf.Chain.L1Contracts.L1CrossDomainMessengerProxy.String(), Presets[420].ChainConfig.L1Contracts.L1CrossDomainMessengerProxy.String()) require.Equal(t, conf.Chain.L1Contracts.L1StandardBridgeProxy.String(), Presets[420].ChainConfig.L1Contracts.L1StandardBridgeProxy.String()) require.Equal(t, conf.Chain.L1Contracts.L2OutputOracleProxy.String(), Presets[420].ChainConfig.L1Contracts.L2OutputOracleProxy.String()) + require.Equal(t, conf.Chain.L1PollingInterval, uint(5000)) + require.Equal(t, conf.Chain.L1HeaderBufferSize, uint(1000)) + require.Equal(t, conf.Chain.L2PollingInterval, uint(5000)) + require.Equal(t, conf.Chain.L2HeaderBufferSize, uint(1000)) require.Equal(t, conf.RPCs.L1RPC, "https://l1.example.com") require.Equal(t, conf.RPCs.L2RPC, "https://l2.example.com") require.Equal(t, conf.DB.Host, "127.0.0.1") @@ -79,12 +88,17 @@ func TestLoadConfigWithoutPreset(t *testing.T) { testData := ` [chain] + l1-polling-interval = 5000 + l2-polling-interval = 5000 + l1-header-buffer-size = 1000 + l2-header-buffer-size = 1000 [chain.l1-contracts] optimism-portal = "0x4205Fc579115071764c7423A4f12eDde41f106Ed" l2-output-oracle = "0x42097868233d1aa22e815a266982f2cf17685a27" l1-cross-domain-messenger = "0x420ce71c97B33Cc4729CF772ae268934F7ab5fA1" l1-standard-bridge = "0x4209fc46f92E8a1c0deC1b1747d010903E884bE1" + dispute-game-factory = "0x4209fc46f92E8a1c0deC1b1747d010903E884bE1" [rpcs] l1-rpc = "https://l1.example.com" @@ -99,7 +113,7 @@ func TestLoadConfigWithoutPreset(t *testing.T) { err = tmpfile.Close() require.NoError(t, err) - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) conf, err := LoadConfig(logger, tmpfile.Name()) require.NoError(t, err) @@ -108,12 +122,6 @@ func TestLoadConfigWithoutPreset(t *testing.T) { require.Equal(t, conf.Chain.L1Contracts.L1CrossDomainMessengerProxy.String(), common.HexToAddress("0x420ce71c97B33Cc4729CF772ae268934F7ab5fA1").String()) require.Equal(t, conf.Chain.L1Contracts.L1StandardBridgeProxy.String(), common.HexToAddress("0x4209fc46f92E8a1c0deC1b1747d010903E884bE1").String()) require.Equal(t, conf.Chain.Preset, 0) - - // Enforce polling default values - require.Equal(t, conf.Chain.L1PollingInterval, uint(5000)) - require.Equal(t, conf.Chain.L2PollingInterval, uint(5000)) - require.Equal(t, conf.Chain.L1HeaderBufferSize, uint(500)) - require.Equal(t, conf.Chain.L2HeaderBufferSize, uint(500)) } func TestLoadConfigWithUnknownPreset(t *testing.T) { @@ -139,7 +147,7 @@ func TestLoadConfigWithUnknownPreset(t *testing.T) { err = tmpfile.Close() require.NoError(t, err) - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) conf, err := LoadConfig(logger, tmpfile.Name()) require.Error(t, err) @@ -160,7 +168,8 @@ func TestLoadConfigPollingValues(t *testing.T) { l1-polling-interval = 1000 l2-polling-interval = 1005 l1-header-buffer-size = 100 - l2-header-buffer-size = 105` + l2-header-buffer-size = 105 + ` data := []byte(testData) err = os.WriteFile(tmpfile.Name(), data, 0644) @@ -170,7 +179,7 @@ func TestLoadConfigPollingValues(t *testing.T) { err = tmpfile.Close() require.NoError(t, err) - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) conf, err := LoadConfig(logger, tmpfile.Name()) require.NoError(t, err) @@ -190,6 +199,11 @@ func TestLoadedConfigPresetPrecendence(t *testing.T) { [chain] preset = 10 # Optimism Mainnet + l1-polling-interval = 1000 + l2-polling-interval = 1000 + l1-header-buffer-size = 100 + l2-header-buffer-size = 100 + # confirmation depths are explicitly set l1-confirmation-depth = 50 l2-confirmation-depth = 100 @@ -198,7 +212,6 @@ func TestLoadedConfigPresetPrecendence(t *testing.T) { [chain.l1-contracts] optimism-portal = "0x0000000000000000000000000000000000000001" - [rpcs] l1-rpc = "https://l1.example.com" l2-rpc = "https://l2.example.com" @@ -212,7 +225,7 @@ func TestLoadedConfigPresetPrecendence(t *testing.T) { err = tmpfile.Close() require.NoError(t, err) - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) conf, err := LoadConfig(logger, tmpfile.Name()) require.NoError(t, err) @@ -235,6 +248,11 @@ func TestLocalDevnet(t *testing.T) { [chain] preset = 901 + l1-polling-interval = 5000 + l2-polling-interval = 5000 + l1-header-buffer-size = 1000 + l2-header-buffer-size = 1000 + [rpcs] l1-rpc = "https://l1.example.com" l2-rpc = "https://l2.example.com" @@ -248,7 +266,7 @@ func TestLocalDevnet(t *testing.T) { err = tmpfile.Close() require.NoError(t, err) - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) conf, err := LoadConfig(logger, tmpfile.Name()) require.NoError(t, err) @@ -259,7 +277,7 @@ func TestLocalDevnet(t *testing.T) { } func TestThrowsOnUnknownKeys(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) tmpfile, err := os.CreateTemp("", "test.toml") require.NoError(t, err) defer os.Remove(tmpfile.Name()) diff --git a/indexer/config/devnet.go b/indexer/config/devnet.go index 09f8f31db66e..babc56bbba91 100644 --- a/indexer/config/devnet.go +++ b/indexer/config/devnet.go @@ -7,6 +7,8 @@ import ( "io/fs" "os" "path/filepath" + + op_service "github.com/ethereum-optimism/optimism/op-service" ) var DevnetPresetId = 901 @@ -17,19 +19,19 @@ func DevnetPreset() (*Preset, error) { return nil, err } - root, err := findMonorepoRoot(cwd) + root, err := op_service.FindMonorepoRoot(cwd) if err != nil { return nil, err } devnetFilepath := filepath.Join(root, ".devnet", "addresses.json") if _, err := os.Stat(devnetFilepath); errors.Is(err, fs.ErrNotExist) { - return nil, err + return nil, fmt.Errorf(".devnet/addresses.json not found. `make devnet-allocs` in monorepo root: %w", err) } content, err := os.ReadFile(devnetFilepath) if err != nil { - return nil, err + return nil, fmt.Errorf("unable to read .devnet/addressees.json") } var l1Contracts L1Contracts @@ -42,25 +44,3 @@ func DevnetPreset() (*Preset, error) { ChainConfig: ChainConfig{Preset: DevnetPresetId, L1Contracts: l1Contracts}, }, nil } - -// findMonorepoRoot will recursively search upwards for a go.mod file. -// This depends on the structure of the monorepo having a go.mod file at the root. -func findMonorepoRoot(startDir string) (string, error) { - dir, err := filepath.Abs(startDir) - if err != nil { - return "", err - } - for { - modulePath := filepath.Join(dir, "go.mod") - if _, err := os.Stat(modulePath); err == nil { - return dir, nil - } - parentDir := filepath.Dir(dir) - // Check if we reached the filesystem root - if parentDir == dir { - break - } - dir = parentDir - } - return "", fmt.Errorf("monorepo root not found") -} diff --git a/indexer/config/presets.go b/indexer/config/presets.go index c0bafbc7ffc9..a812b568e1f6 100644 --- a/indexer/config/presets.go +++ b/indexer/config/presets.go @@ -25,6 +25,7 @@ var Presets = map[int]Preset{ L1CrossDomainMessengerProxy: common.HexToAddress("0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1"), L1StandardBridgeProxy: common.HexToAddress("0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1"), L1ERC721BridgeProxy: common.HexToAddress("0x5a7749f83b81B301cAb5f48EB8516B986DAef23D"), + DisputeGameFactoryProxy: common.HexToAddress("0x1111111111111111111111111111111111111111"), // pre-bedrock LegacyCanonicalTransactionChain: common.HexToAddress("0x5e4e65926ba27467555eb562121fac00d24e9dd2"), @@ -33,6 +34,8 @@ var Presets = map[int]Preset{ L1StartingHeight: 13596466, L1BedrockStartingHeight: 17422590, L2BedrockStartingHeight: 105235063, + L1ConfirmationDepth: 10, + L2ConfirmationDepth: 75, }, }, 420: { @@ -47,6 +50,7 @@ var Presets = map[int]Preset{ L1CrossDomainMessengerProxy: common.HexToAddress("0x5086d1eEF304eb5284A0f6720f79403b4e9bE294"), L1StandardBridgeProxy: common.HexToAddress("0x636Af16bf2f682dD3109e60102b8E1A089FedAa8"), L1ERC721BridgeProxy: common.HexToAddress("0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9"), + DisputeGameFactoryProxy: common.HexToAddress("0x1111111111111111111111111111111111111111"), // pre-bedrock LegacyCanonicalTransactionChain: common.HexToAddress("0x607F755149cFEB3a14E1Dc3A4E2450Cde7dfb04D"), @@ -55,6 +59,8 @@ var Presets = map[int]Preset{ L1StartingHeight: 7017096, L1BedrockStartingHeight: 8300214, L2BedrockStartingHeight: 4061224, + L1ConfirmationDepth: 10, + L2ConfirmationDepth: 75, }, }, 11155420: { @@ -69,8 +75,11 @@ var Presets = map[int]Preset{ L1CrossDomainMessengerProxy: common.HexToAddress("0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef"), L1StandardBridgeProxy: common.HexToAddress("0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1"), L1ERC721BridgeProxy: common.HexToAddress("0xd83e03D576d23C9AEab8cC44Fa98d058D2176D1f"), + DisputeGameFactoryProxy: common.HexToAddress("0x1111111111111111111111111111111111111111"), }, - L1StartingHeight: 4071408, + L1StartingHeight: 4071408, + L1ConfirmationDepth: 10, + L2ConfirmationDepth: 75, }, }, 8453: { @@ -85,8 +94,11 @@ var Presets = map[int]Preset{ L1CrossDomainMessengerProxy: common.HexToAddress("0x866E82a600A1414e583f7F13623F1aC5d58b0Afa"), L1StandardBridgeProxy: common.HexToAddress("0x3154Cf16ccdb4C6d922629664174b904d80F2C35"), L1ERC721BridgeProxy: common.HexToAddress("0x608d94945A64503E642E6370Ec598e519a2C1E53"), + DisputeGameFactoryProxy: common.HexToAddress("0x1111111111111111111111111111111111111111"), }, - L1StartingHeight: 17481768, + L1StartingHeight: 17481768, + L1ConfirmationDepth: 10, + L2ConfirmationDepth: 75, }, }, 84531: { @@ -101,8 +113,11 @@ var Presets = map[int]Preset{ L1CrossDomainMessengerProxy: common.HexToAddress("0x8e5693140eA606bcEB98761d9beB1BC87383706D"), L1StandardBridgeProxy: common.HexToAddress("0xfA6D8Ee5BE770F84FC001D098C4bD604Fe01284a"), L1ERC721BridgeProxy: common.HexToAddress("0x5E0c967457347D5175bF82E8CCCC6480FCD7e568"), + DisputeGameFactoryProxy: common.HexToAddress("0x1111111111111111111111111111111111111111"), }, - L1StartingHeight: 8410981, + L1StartingHeight: 8410981, + L1ConfirmationDepth: 10, + L2ConfirmationDepth: 75, }, }, 84532: { @@ -117,8 +132,11 @@ var Presets = map[int]Preset{ L1CrossDomainMessengerProxy: common.HexToAddress("0xC34855F4De64F1840e5686e64278da901e261f20"), L1StandardBridgeProxy: common.HexToAddress("0xfd0Bf71F60660E2f608ed56e1659C450eB113120"), L1ERC721BridgeProxy: common.HexToAddress("0x21eFD066e581FA55Ef105170Cc04d74386a09190"), + DisputeGameFactoryProxy: common.HexToAddress("0x1111111111111111111111111111111111111111"), }, - L1StartingHeight: 4370868, + L1StartingHeight: 4370868, + L1ConfirmationDepth: 10, + L2ConfirmationDepth: 75, }, }, 7777777: { @@ -133,8 +151,11 @@ var Presets = map[int]Preset{ L1CrossDomainMessengerProxy: common.HexToAddress("0xdC40a14d9abd6F410226f1E6de71aE03441ca506"), L1StandardBridgeProxy: common.HexToAddress("0x3e2Ea9B92B7E48A52296fD261dc26fd995284631"), L1ERC721BridgeProxy: common.HexToAddress("0x83A4521A3573Ca87f3a971B169C5A0E1d34481c3"), + DisputeGameFactoryProxy: common.HexToAddress("0x1111111111111111111111111111111111111111"), }, - L1StartingHeight: 17473923, + L1StartingHeight: 17473923, + L1ConfirmationDepth: 10, + L2ConfirmationDepth: 75, }, }, 999: { @@ -149,8 +170,11 @@ var Presets = map[int]Preset{ L1CrossDomainMessengerProxy: common.HexToAddress("0xD87342e16352D33170557A7dA1e5fB966a60FafC"), L1StandardBridgeProxy: common.HexToAddress("0x7CC09AC2452D6555d5e0C213Ab9E2d44eFbFc956"), L1ERC721BridgeProxy: common.HexToAddress("0x57C1C6b596ce90C0e010c358DD4Aa052404bB70F"), + DisputeGameFactoryProxy: common.HexToAddress("0x1111111111111111111111111111111111111111"), }, - L1StartingHeight: 8942381, + L1StartingHeight: 8942381, + L1ConfirmationDepth: 10, + L2ConfirmationDepth: 75, }, }, 424: { @@ -165,8 +189,11 @@ var Presets = map[int]Preset{ L1CrossDomainMessengerProxy: common.HexToAddress("0x97BAf688E5d0465E149d1d5B497Ca99392a6760e"), L1StandardBridgeProxy: common.HexToAddress("0xD0204B9527C1bA7bD765Fa5CCD9355d38338272b"), L1ERC721BridgeProxy: common.HexToAddress("0xaFF0F8aaB6Cc9108D34b3B8423C76d2AF434d115"), + DisputeGameFactoryProxy: common.HexToAddress("0x1111111111111111111111111111111111111111"), }, - L1StartingHeight: 17672702, + L1StartingHeight: 17672702, + L1ConfirmationDepth: 10, + L2ConfirmationDepth: 75, }, }, 58008: { @@ -181,8 +208,11 @@ var Presets = map[int]Preset{ L1CrossDomainMessengerProxy: common.HexToAddress("0x97f3558Ce48FE71B8CeFA5497708A49531D5A8E1"), L1StandardBridgeProxy: common.HexToAddress("0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3"), L1ERC721BridgeProxy: common.HexToAddress("0xBA8397B6f255618D5985d0fB427D8c0496F3a5FA"), + DisputeGameFactoryProxy: common.HexToAddress("0x1111111111111111111111111111111111111111"), }, - L1StartingHeight: 17672702, + L1StartingHeight: 17672702, + L1ConfirmationDepth: 10, + L2ConfirmationDepth: 75, }, }, } diff --git a/indexer/database/blocks.go b/indexer/database/blocks.go index 8df6d8c35042..0f89f92e6b3c 100644 --- a/indexer/database/blocks.go +++ b/indexer/database/blocks.go @@ -37,6 +37,10 @@ func BlockHeaderFromHeader(header *types.Header) BlockHeader { } } +func (b BlockHeader) String() string { + return fmt.Sprintf("{Hash: %s, Number: %s}", b.Hash, b.Number) +} + type L1BlockHeader struct { BlockHeader `gorm:"embedded"` } @@ -48,13 +52,13 @@ type L2BlockHeader struct { type BlocksView interface { L1BlockHeader(common.Hash) (*L1BlockHeader, error) L1BlockHeaderWithFilter(BlockHeader) (*L1BlockHeader, error) + L1BlockHeaderWithScope(func(db *gorm.DB) *gorm.DB) (*L1BlockHeader, error) L1LatestBlockHeader() (*L1BlockHeader, error) L2BlockHeader(common.Hash) (*L2BlockHeader, error) L2BlockHeaderWithFilter(BlockHeader) (*L2BlockHeader, error) + L2BlockHeaderWithScope(func(db *gorm.DB) *gorm.DB) (*L2BlockHeader, error) L2LatestBlockHeader() (*L2BlockHeader, error) - - LatestObservedEpoch(*big.Int, uint64) (*Epoch, error) } type BlocksDB interface { @@ -62,6 +66,8 @@ type BlocksDB interface { StoreL1BlockHeaders([]L1BlockHeader) error StoreL2BlockHeaders([]L2BlockHeader) error + + DeleteReorgedState(uint64) error } /** @@ -94,8 +100,12 @@ func (db *blocksDB) L1BlockHeader(hash common.Hash) (*L1BlockHeader, error) { } func (db *blocksDB) L1BlockHeaderWithFilter(filter BlockHeader) (*L1BlockHeader, error) { + return db.L1BlockHeaderWithScope(func(gorm *gorm.DB) *gorm.DB { return gorm.Where(&filter) }) +} + +func (db *blocksDB) L1BlockHeaderWithScope(scope func(*gorm.DB) *gorm.DB) (*L1BlockHeader, error) { var l1Header L1BlockHeader - result := db.gorm.Where(&filter).Take(&l1Header) + result := db.gorm.Scopes(scope).Take(&l1Header) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return nil, nil @@ -137,8 +147,12 @@ func (db *blocksDB) L2BlockHeader(hash common.Hash) (*L2BlockHeader, error) { } func (db *blocksDB) L2BlockHeaderWithFilter(filter BlockHeader) (*L2BlockHeader, error) { + return db.L2BlockHeaderWithScope(func(gorm *gorm.DB) *gorm.DB { return gorm.Where(&filter) }) +} + +func (db *blocksDB) L2BlockHeaderWithScope(scope func(*gorm.DB) *gorm.DB) (*L2BlockHeader, error) { var l2Header L2BlockHeader - result := db.gorm.Where(&filter).Take(&l2Header) + result := db.gorm.Scopes(scope).Take(&l2Header) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return nil, nil @@ -162,103 +176,23 @@ func (db *blocksDB) L2LatestBlockHeader() (*L2BlockHeader, error) { return &l2Header, nil } -// Auxiliary Methods on both L1 & L2 +// Reorgs -type Epoch struct { - L1BlockHeader L1BlockHeader `gorm:"embedded"` - L2BlockHeader L2BlockHeader `gorm:"embedded"` -} - -// LatestObservedEpoch return the marker for latest epoch, observed on L1 & L2, within -// the specified bounds. In other words this returns the latest indexed L1 block that has -// a corresponding indexed L2 block with a matching L1Origin (equal timestamps). -// -// If `fromL1Height` (inclusive) is not specified, the search will start from genesis and -// continue all the way to latest indexed heights if `maxL1Range == 0`. -// -// For more, see the protocol spec: -// - https://github.com/ethereum-optimism/optimism/blob/develop/specs/derivation.md -func (db *blocksDB) LatestObservedEpoch(fromL1Height *big.Int, maxL1Range uint64) (*Epoch, error) { - // We use timestamps since that translates to both L1 & L2 - var fromTimestamp, toTimestamp uint64 - - // Lower Bound (the default `fromTimestamp = l1_starting_height` (default=0) suffices genesis representation) - var header L1BlockHeader - if fromL1Height != nil { - result := db.gorm.Where("number = ?", fromL1Height).Take(&header) - if result.Error != nil { - if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, nil - } - return nil, result.Error - } +func (db *blocksDB) DeleteReorgedState(timestamp uint64) error { + db.log.Info("deleting reorg'd state", "from_timestamp", timestamp) - fromTimestamp = header.Timestamp - } else { - // Take the lowest indexed L1 block to compute the lower bound - result := db.gorm.Order("number ASC").Take(&header) - if result.Error != nil { - if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, nil - } - return nil, result.Error - } - - fromL1Height = header.Number - fromTimestamp = header.Timestamp + // Delete reorg'd state. Block deletes cascades to all tables + l1Result := db.gorm.Delete(&L1BlockHeader{}, "timestamp >= ?", timestamp) + if l1Result.Error != nil { + return fmt.Errorf("unable to delete l1 state: %w", l1Result.Error) } + db.log.Info("L1 blocks (& derived events/tables) deleted", "block_count", l1Result.RowsAffected) - // Upper Bound (lowest timestamp indexed between L1/L2 bounded by `maxL1Range`) - { - l1QueryFilter := fmt.Sprintf("timestamp >= %d", fromTimestamp) - if maxL1Range > 0 { - maxHeight := new(big.Int).Add(fromL1Height, big.NewInt(int64(maxL1Range))) - l1QueryFilter = fmt.Sprintf("%s AND number <= %d", l1QueryFilter, maxHeight) - } - - // Fetch most recent header from l1_block_headers table - var l1Header L1BlockHeader - result := db.gorm.Where(l1QueryFilter).Order("timestamp DESC").Take(&l1Header) - if result.Error != nil { - if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, nil - } - return nil, result.Error - } - - toTimestamp = l1Header.Timestamp - - // Fetch most recent header from l2_block_headers table - var l2Header L2BlockHeader - result = db.gorm.Where("timestamp <= ?", toTimestamp).Order("timestamp DESC").Take(&l2Header) - if result.Error != nil { - if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, nil - } - return nil, result.Error - } - - if l2Header.Timestamp < toTimestamp { - toTimestamp = l2Header.Timestamp - } - } - - // Search for the latest indexed epoch within range. This is a faster query than doing an INNER JOIN between - // l1_block_headers and l2_block_headers which requires a full table scan to compute the resulting table. - l1Query := db.gorm.Table("l1_block_headers").Where("timestamp >= ? AND timestamp <= ?", fromTimestamp, toTimestamp) - l2Query := db.gorm.Table("l2_block_headers").Where("timestamp >= ? AND timestamp <= ?", fromTimestamp, toTimestamp) - query := db.gorm.Raw(`SELECT * FROM (?) AS l1_block_headers, (?) AS l2_block_headers - WHERE l1_block_headers.timestamp = l2_block_headers.timestamp - ORDER BY l2_block_headers.number DESC LIMIT 1`, l1Query, l2Query) - - var epoch Epoch - result := query.Take(&epoch) - if result.Error != nil { - if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, nil - } - return nil, result.Error + l2Result := db.gorm.Delete(&L2BlockHeader{}, "timestamp >= ?", timestamp) + if l2Result.Error != nil { + return fmt.Errorf("unable to delete l2 state: %w", l2Result.Error) } + db.log.Info("L2 blocks (& derived events/tables) deleted", "block_count", l2Result.RowsAffected) - return &epoch, nil + return nil } diff --git a/indexer/database/bridge_messages.go b/indexer/database/bridge_messages.go index a468c5f4b105..7a126635d84d 100644 --- a/indexer/database/bridge_messages.go +++ b/indexer/database/bridge_messages.go @@ -39,6 +39,11 @@ type L2BridgeMessage struct { TransactionWithdrawalHash common.Hash `gorm:"serializer:bytes"` } +type L2BridgeMessageVersionedMessageHash struct { + MessageHash common.Hash `gorm:"primaryKey;serializer:bytes"` + V1MessageHash common.Hash `gorm:"serializer:bytes"` +} + type BridgeMessagesView interface { L1BridgeMessage(common.Hash) (*L1BridgeMessage, error) L1BridgeMessageWithFilter(BridgeMessage) (*L1BridgeMessage, error) @@ -55,6 +60,8 @@ type BridgeMessagesDB interface { StoreL2BridgeMessages([]L2BridgeMessage) error MarkRelayedL2BridgeMessage(common.Hash, uuid.UUID) error + + StoreL2BridgeMessageV1MessageHashes([]L2BridgeMessageVersionedMessageHash) error } /** @@ -134,8 +141,33 @@ func (db bridgeMessagesDB) StoreL2BridgeMessages(messages []L2BridgeMessage) err return result.Error } +func (db bridgeMessagesDB) StoreL2BridgeMessageV1MessageHashes(versionedHashes []L2BridgeMessageVersionedMessageHash) error { + deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "message_hash"}}, DoNothing: true}) + result := deduped.Create(&versionedHashes) + if result.Error == nil && int(result.RowsAffected) < len(versionedHashes) { + db.log.Warn("ignored L2 bridge v1 message hash duplicates", "duplicates", len(versionedHashes)-int(result.RowsAffected)) + } + + return result.Error +} + func (db bridgeMessagesDB) L2BridgeMessage(msgHash common.Hash) (*L2BridgeMessage, error) { - return db.L2BridgeMessageWithFilter(BridgeMessage{MessageHash: msgHash}) + message, err := db.L2BridgeMessageWithFilter(BridgeMessage{MessageHash: msgHash}) + if message != nil || err != nil { + return message, err + } + + // check if this is a v1 hash of an older message + versioned := L2BridgeMessageVersionedMessageHash{V1MessageHash: msgHash} + result := db.gorm.Where(&versioned).Take(&versioned) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, nil + } + return nil, result.Error + } + + return db.L2BridgeMessageWithFilter(BridgeMessage{MessageHash: versioned.MessageHash}) } func (db bridgeMessagesDB) L2BridgeMessageWithFilter(filter BridgeMessage) (*L2BridgeMessage, error) { diff --git a/indexer/database/bridge_transactions.go b/indexer/database/bridge_transactions.go index 3089b8a87921..10482b7e1c27 100644 --- a/indexer/database/bridge_transactions.go +++ b/indexer/database/bridge_transactions.go @@ -50,9 +50,11 @@ type L2TransactionWithdrawal struct { type BridgeTransactionsView interface { L1TransactionDeposit(common.Hash) (*L1TransactionDeposit, error) L1LatestBlockHeader() (*L1BlockHeader, error) + L1LatestFinalizedBlockHeader() (*L1BlockHeader, error) L2TransactionWithdrawal(common.Hash) (*L2TransactionWithdrawal, error) L2LatestBlockHeader() (*L2BlockHeader, error) + L2LatestFinalizedBlockHeader() (*L2BlockHeader, error) } type BridgeTransactionsDB interface { @@ -106,23 +108,35 @@ func (db *bridgeTransactionsDB) L1TransactionDeposit(sourceHash common.Hash) (*L } func (db *bridgeTransactionsDB) L1LatestBlockHeader() (*L1BlockHeader, error) { - // Markers for an indexed bridge event - // L1: Latest Transaction Deposit, Latest Proven/Finalized Withdrawal - l1DepositQuery := db.gorm.Table("l1_transaction_deposits").Order("l1_transaction_deposits.timestamp DESC").Limit(1) - l1DepositQuery = l1DepositQuery.Joins("INNER JOIN l1_contract_events ON l1_contract_events.guid = l1_transaction_deposits.initiated_l1_event_guid") - l1DepositQuery = l1DepositQuery.Select("l1_contract_events.*") + // L1: Latest Transaction Deposit + l1Query := db.gorm.Where("timestamp = (?)", db.gorm.Table("l1_transaction_deposits").Select("MAX(timestamp)")) - l1ProvenQuery := db.gorm.Table("l2_transaction_withdrawals") - l1ProvenQuery = l1ProvenQuery.Joins("INNER JOIN l1_contract_events ON l1_contract_events.guid = l2_transaction_withdrawals.proven_l1_event_guid") - l1ProvenQuery = l1ProvenQuery.Order("l1_contract_events.timestamp DESC").Select("l1_contract_events.*").Limit(1) + var l1Header L1BlockHeader + result := l1Query.Take(&l1Header) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, nil + } + return nil, result.Error + } - l1FinalizedQuery := db.gorm.Table("l2_transaction_withdrawals") - l1FinalizedQuery = l1FinalizedQuery.Joins("INNER JOIN l1_contract_events ON l1_contract_events.guid = l2_transaction_withdrawals.proven_l1_event_guid") - l1FinalizedQuery = l1FinalizedQuery.Order("l1_contract_events.timestamp DESC").Select("l1_contract_events.*").Limit(1) + return &l1Header, nil +} + +func (db *bridgeTransactionsDB) L1LatestFinalizedBlockHeader() (*L1BlockHeader, error) { + // A Proven, Finalized Event or Relayed Message + + latestProvenWithdrawal := db.gorm.Table("l2_transaction_withdrawals").Where("proven_l1_event_guid IS NOT NULL").Order("timestamp DESC").Limit(1) + provenQuery := db.gorm.Table("l1_contract_events").Where("guid = (?)", latestProvenWithdrawal.Select("proven_l1_event_guid")) - l1Query := db.gorm.Table("((?) UNION (?) UNION (?)) AS latest_bridge_events", l1DepositQuery.Limit(1), l1ProvenQuery, l1FinalizedQuery) - l1Query = l1Query.Joins("INNER JOIN l1_block_headers ON l1_block_headers.hash = latest_bridge_events.block_hash") - l1Query = l1Query.Order("latest_bridge_events.timestamp DESC").Select("l1_block_headers.*") + latestFinalizedWithdrawal := db.gorm.Table("l2_transaction_withdrawals").Where("finalized_l1_event_guid IS NOT NULL").Order("timestamp DESC").Limit(1) + finalizedQuery := db.gorm.Table("l1_contract_events").Where("guid = (?)", latestFinalizedWithdrawal.Select("finalized_l1_event_guid")) + + latestRelayedWithdrawal := db.gorm.Table("l2_bridge_messages").Where("relayed_message_event_guid IS NOT NULL").Order("timestamp DESC").Limit(1) + relayedQuery := db.gorm.Table("l1_contract_events").Where("guid = (?)", latestRelayedWithdrawal.Select("relayed_message_event_guid")) + + events := db.gorm.Table("((?) UNION (?) UNION (?)) AS events", provenQuery, finalizedQuery, relayedQuery) + l1Query := db.gorm.Where("hash = (?)", events.Select("block_hash").Order("timestamp DESC").Limit(1)) var l1Header L1BlockHeader result := l1Query.Take(&l1Header) @@ -174,16 +188,17 @@ func (db *bridgeTransactionsDB) MarkL2TransactionWithdrawalProvenEvent(withdrawa if withdrawal.ProvenL1EventGUID != nil && withdrawal.ProvenL1EventGUID.ID() == provenL1EventGuid.ID() { return nil - } else if withdrawal.ProvenL1EventGUID != nil { - return fmt.Errorf("proven withdrawal %s re-proven with a different event %s", withdrawalHash, provenL1EventGuid) } + // Withdrawals can be re-proven in the event that the claim they were proven against was successfully + // challenged. Rather than track each individual dispute game, we allow the proven event to simply be + // overwritten. withdrawal.ProvenL1EventGUID = &provenL1EventGuid result := db.gorm.Save(&withdrawal) return result.Error } -// MarkL2TransactionWithdrawalProvenEvent links a withdrawn transaction in its finalized state +// MarkL2TransactionWithdrawalFinalizedEvent links a withdrawn transaction in its finalized state func (db *bridgeTransactionsDB) MarkL2TransactionWithdrawalFinalizedEvent(withdrawalHash common.Hash, finalizedL1EventGuid uuid.UUID, succeeded bool) error { withdrawal, err := db.L2TransactionWithdrawal(withdrawalHash) if err != nil { @@ -207,47 +222,36 @@ func (db *bridgeTransactionsDB) MarkL2TransactionWithdrawalFinalizedEvent(withdr } func (db *bridgeTransactionsDB) L2LatestBlockHeader() (*L2BlockHeader, error) { - // L2: Latest Withdrawal, Latest L2 Header of indexed deposit epoch - var latestWithdrawalHeader, latestL2DepositHeader *L2BlockHeader - - var withdrawHeader L2BlockHeader - withdrawalQuery := db.gorm.Table("l2_transaction_withdrawals").Order("timestamp DESC").Limit(1) - withdrawalQuery = withdrawalQuery.Joins("INNER JOIN l2_contract_events ON l2_contract_events.guid = l2_transaction_withdrawals.initiated_l2_event_guid") - withdrawalQuery = withdrawalQuery.Joins("INNER JOIN l2_block_headers ON l2_block_headers.hash = l2_contract_events.block_hash") - result := withdrawalQuery.Select("l2_block_headers.*").Take(&withdrawHeader) - if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, result.Error - } else if !errors.Is(result.Error, gorm.ErrRecordNotFound) { - latestWithdrawalHeader = &withdrawHeader - } + // L2: Block With The Latest Withdrawal + l2Query := db.gorm.Where("timestamp = (?)", db.gorm.Table("l2_transaction_withdrawals").Select("MAX(timestamp)")) - // Check for any deposits that may have been included after the latest withdrawal. However, since the bridge - // processor only inserts entries when the corresponding epoch has been indexed on both L1 and L2, we can - // simply look for the latest L2 block with at <= time of the latest L1 deposit. - var l1Deposit L1TransactionDeposit - result = db.gorm.Table("l1_transaction_deposits").Order("timestamp DESC").Limit(1).Take(&l1Deposit) - if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, result.Error - } else if !errors.Is(result.Error, gorm.ErrRecordNotFound) { - var l2DepositHeader L2BlockHeader - result := db.gorm.Table("l2_block_headers").Order("timestamp DESC").Limit(1).Where("timestamp <= ?", l1Deposit.Tx.Timestamp).Take(&l2DepositHeader) - if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, result.Error - } else if !errors.Is(result.Error, gorm.ErrRecordNotFound) { - latestL2DepositHeader = &l2DepositHeader + var l2Header L2BlockHeader + result := l2Query.Take(&l2Header) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, nil } + return nil, result.Error } - // compare - if latestWithdrawalHeader == nil { - return latestL2DepositHeader, nil - } else if latestL2DepositHeader == nil { - return latestWithdrawalHeader, nil - } + return &l2Header, nil +} + +func (db *bridgeTransactionsDB) L2LatestFinalizedBlockHeader() (*L2BlockHeader, error) { + // Only a Relayed message since we dont track L1 deposit inclusion status. + latestRelayedDeposit := db.gorm.Table("l1_bridge_messages").Where("relayed_message_event_guid IS NOT NULL").Order("timestamp DESC").Limit(1) + relayedQuery := db.gorm.Table("l2_contract_events").Where("guid = (?)", latestRelayedDeposit.Select("relayed_message_event_guid")) - if latestWithdrawalHeader.Timestamp >= latestL2DepositHeader.Timestamp { - return latestWithdrawalHeader, nil - } else { - return latestL2DepositHeader, nil + l2Query := db.gorm.Where("hash = (?)", relayedQuery.Select("block_hash")) + + var l2Header L2BlockHeader + result := l2Query.Take(&l2Header) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, nil + } + return nil, result.Error } + + return &l2Header, nil } diff --git a/indexer/database/bridge_transfers.go b/indexer/database/bridge_transfers.go index 543b63dbd8e9..51bf48d99065 100644 --- a/indexer/database/bridge_transfers.go +++ b/indexer/database/bridge_transfers.go @@ -3,6 +3,7 @@ package database import ( "errors" "fmt" + "strings" "gorm.io/gorm" "gorm.io/gorm/clause" @@ -61,10 +62,12 @@ type L2BridgeWithdrawalWithTransactionHashes struct { type BridgeTransfersView interface { L1BridgeDeposit(common.Hash) (*L1BridgeDeposit, error) + L1TxDepositSum() (float64, error) L1BridgeDepositWithFilter(BridgeTransfer) (*L1BridgeDeposit, error) L1BridgeDepositsByAddress(common.Address, string, int) (*L1BridgeDepositsResponse, error) L2BridgeWithdrawal(common.Hash) (*L2BridgeWithdrawal, error) + L2BridgeWithdrawalSum(filter WithdrawFilter) (float64, error) L2BridgeWithdrawalWithFilter(BridgeTransfer) (*L2BridgeWithdrawal, error) L2BridgeWithdrawalsByAddress(common.Address, string, int) (*L2BridgeWithdrawalsResponse, error) } @@ -136,6 +139,17 @@ type L1BridgeDepositsResponse struct { HasNextPage bool } +// L1TxDepositSum ... returns the sum of all l1 tx deposit mints in gwei +func (db *bridgeTransfersDB) L1TxDepositSum() (float64, error) { + var sum float64 + result := db.gorm.Model(&L1TransactionDeposit{}).Select("SUM(amount)").Scan(&sum) + if result.Error != nil { + return 0, result.Error + } + + return sum, nil +} + // L1BridgeDepositsByAddress retrieves a list of deposits initiated by the specified address, // coupled with the L1/L2 transaction hashes that complete the bridge transaction. func (db *bridgeTransfersDB) L1BridgeDepositsByAddress(address common.Address, cursor string, limit int) (*L1BridgeDepositsResponse, error) { @@ -233,6 +247,46 @@ func (db *bridgeTransfersDB) L2BridgeWithdrawal(txWithdrawalHash common.Hash) (* return &withdrawal, nil } +type WithdrawFilter uint8 + +const ( + All WithdrawFilter = iota // Same as "initialized" + Proven + Finalized +) + +func (db *bridgeTransfersDB) L2BridgeWithdrawalSum(filter WithdrawFilter) (float64, error) { + // Determine where filter + var clause string + switch filter { + case All: + clause = "" + + case Finalized: + clause = "finalized_l1_event_guid IS NOT NULL" + + case Proven: + clause = "proven_l1_event_guid IS NOT NULL" + + default: + return 0, fmt.Errorf("unknown filter argument: %d", filter) + } + + // NOTE - Scanning to float64 reduces precision versus scanning to big.Int since amount is a uint256 + // This is ok though given all bridges will never exceed max float64 (10^308 || 1.7E+308) in wei value locked + // since that would require 10^308 / 10^18 = 10^290 ETH locked in the bridge + var sum float64 + result := db.gorm.Model(&L2TransactionWithdrawal{}).Where(clause).Select("SUM(amount)").Scan(&sum) + if result.Error != nil && strings.Contains(result.Error.Error(), "converting NULL to float64 is unsupported") { + // no rows found + return 0, nil + } else if result.Error != nil { + return 0, result.Error + } else { + return sum, nil + } +} + // L2BridgeWithdrawalWithFilter queries for a bridge withdrawal with set fields in the `BridgeTransfer` filter func (db *bridgeTransfersDB) L2BridgeWithdrawalWithFilter(filter BridgeTransfer) (*L2BridgeWithdrawal, error) { var withdrawal L2BridgeWithdrawal diff --git a/indexer/database/db.go b/indexer/database/db.go index def83841f869..fdb8db253a04 100644 --- a/indexer/database/db.go +++ b/indexer/database/db.go @@ -30,7 +30,9 @@ type DB struct { BridgeTransactions BridgeTransactionsDB } -func NewDB(log log.Logger, dbConfig config.DBConfig) (*DB, error) { +// NewDB connects to the configured DB, and provides client-bindings to it. +// The initial connection may fail, or the dial may be cancelled with the provided context. +func NewDB(ctx context.Context, log log.Logger, dbConfig config.DBConfig) (*DB, error) { log = log.New("module", "db") dsn := fmt.Sprintf("host=%s dbname=%s sslmode=disable", dbConfig.Host, dbConfig.Name) diff --git a/indexer/database/mocks.go b/indexer/database/mocks.go index 6ad6f5c6e6e6..07303c7c1e6c 100644 --- a/indexer/database/mocks.go +++ b/indexer/database/mocks.go @@ -1,9 +1,8 @@ package database import ( - "math/big" - "github.com/ethereum/go-ethereum/common" + "gorm.io/gorm" "github.com/stretchr/testify/mock" ) @@ -27,6 +26,11 @@ func (m *MockBlocksView) L1BlockHeaderWithFilter(BlockHeader) (*L1BlockHeader, e return args.Get(0).(*L1BlockHeader), args.Error(1) } +func (m *MockBlocksView) L1BlockHeaderWithScope(func(*gorm.DB) *gorm.DB) (*L1BlockHeader, error) { + args := m.Called() + return args.Get(0).(*L1BlockHeader), args.Error(1) +} + func (m *MockBlocksView) L1LatestBlockHeader() (*L1BlockHeader, error) { args := m.Called() @@ -48,14 +52,14 @@ func (m *MockBlocksView) L2BlockHeaderWithFilter(BlockHeader) (*L2BlockHeader, e return args.Get(0).(*L2BlockHeader), args.Error(1) } -func (m *MockBlocksView) L2LatestBlockHeader() (*L2BlockHeader, error) { +func (m *MockBlocksView) L2BlockHeaderWithScope(func(*gorm.DB) *gorm.DB) (*L2BlockHeader, error) { args := m.Called() - return args.Get(0).(*L2BlockHeader), args.Error(1) + return args.Get(0).(*L2BlockHeader), args.Error(2) } -func (m *MockBlocksView) LatestObservedEpoch(*big.Int, uint64) (*Epoch, error) { +func (m *MockBlocksView) L2LatestBlockHeader() (*L2BlockHeader, error) { args := m.Called() - return args.Get(0).(*Epoch), args.Error(1) + return args.Get(0).(*L2BlockHeader), args.Error(1) } type MockBlocksDB struct { @@ -72,6 +76,11 @@ func (m *MockBlocksDB) StoreL2BlockHeaders(headers []L2BlockHeader) error { return args.Error(1) } +func (m *MockBlocksDB) DeleteReorgedState(timestamp uint64) error { + args := m.Called(timestamp) + return args.Error(1) +} + // MockDB is a mock database that can be used for testing type MockDB struct { MockBlocks *MockBlocksDB diff --git a/indexer/docker-compose.yml b/indexer/docker-compose.yml index 77c0d86d925a..f36aa0411508 100644 --- a/indexer/docker-compose.yml +++ b/indexer/docker-compose.yml @@ -2,166 +2,106 @@ version: '3.8' services: postgres: - image: postgres:latest + image: postgres:14.1 environment: - - POSTGRES_USER=db_username - - POSTGRES_PASSWORD=db_password - - POSTGRES_DB=db_name + - POSTGRES_USER=postgres + - POSTGRES_DB=indexer - PGDATA=/data/postgres - POSTGRES_HOST_AUTH_METHOD=trust healthcheck: - test: [ "CMD-SHELL", "pg_isready -q -U db_username -d db_name" ] + test: [ "CMD-SHELL", "pg_isready -q -U postgres -d indexer" ] ports: - - "5434:5432" + # deconflict with postgres that might be running already on + # the host machine + - "5433:5432" volumes: - postgres_data:/data/postgres - ./migrations:/docker-entrypoint-initdb.d/ - migrations: + index: build: context: .. dockerfile: indexer/Dockerfile - command: ["indexer", "migrate"] + command: ["/bin/sh", "-c", "indexer migrate && indexer index"] + expose: + - "8100" + - "7300" environment: - - INDEXER_RPC_URL_L1=$INDEXER_RPC_URL_L1 - - INDEXER_RPC_URL_L2=$INDEXER_RPC_URL_L2 - - INDEXER_CONFIG=/indexer/indexer.toml - - INDEXER_CHAIN_PRESET=$INDEXER_CHAIN_PRESET - - INDEXER_DB_PORT=5432 - - INDEXER_DB_HOST=postgres - - INDEXER_DB_USER=db_username - - INDEXER_DB_PASS=db_password - - INDEXER_DB_NAME=db_name + - INDEXER_CONFIG=/app/indexer/config.toml + - INDEXER_L1_RPC_URL=http://host.docker.internal:8545 + - INDEXER_L2_RPC_URL=http://host.docker.internal:9545 + - DB_HOST=postgres + - DB_PORT=5432 + - DB_USER=postgres + - DB_NAME=indexer volumes: - - ./indexer.toml:/indexer/indexer.toml - depends_on: - postgres: - condition: service_healthy - - indexer: - build: - context: .. - dockerfile: indexer/Dockerfile - command: ["indexer", "index"] - environment: - - INDEXER_RPC_URL_L1=$INDEXER_RPC_URL_L1 - - INDEXER_RPC_URL_L2=$INDEXER_RPC_URL_L2 - - INDEXER_CONFIG=/indexer/indexer.toml - - INDEXER_CHAIN_PRESET=$INDEXER_CHAIN_PRESET - - INDEXER_DB_PORT=5432 - - INDEXER_DB_HOST=postgres - - INDEXER_DB_USER=db_username - - INDEXER_DB_PASS=db_password - - INDEXER_DB_NAME=db_name - volumes: - - ./indexer.toml:/indexer/indexer.toml + - ./indexer.toml:/app/indexer/config.toml/:ro + # needed only when running against the local devnet such + # that it can bootstrap the local deployment addresses + - ../go.mod:/app/go.mod/:ro + - ../.devnet/addresses.json:/app/.devnet/addresses.json/:ro + healthcheck: + test: wget index:8100/healthz -q -O - > /dev/null 2>&1 depends_on: postgres: condition: service_healthy - migrations: - condition: service_started - api: build: context: .. dockerfile: indexer/Dockerfile command: ["indexer", "api"] - healthcheck: - test: wget localhost:8080/healthz -q -O - > /dev/null 2>&1 - environment: - # Note that you must index goerli with INDEXER_BEDROCK=false first, then - # reindex with INDEXER_BEDROCK=true or seed the database - - INDEXER_RPC_URL_L1=$INDEXER_RPC_URL_L1 - - INDEXER_RPC_URL_L2=$INDEXER_RPC_URL_L2 - - INDEXER_CONFIG=/indexer/indexer.toml - - INDEXER_CHAIN_PRESET=$INDEXER_CHAIN_PRESET - - INDEXER_DB_HOST=postgres - - INDEXER_DB_PORT=5432 - - INDEXER_DB_USER=db_username - - INDEXER_DB_PASS=db_password - - INDEXER_DB_NAME=db_name - volumes: - - ./indexer.toml:/indexer/indexer.toml - ports: - - 8080:8080 - depends_on: - postgres: - condition: service_healthy - - ui: - build: - context: .. - dockerfile: indexer/ui/Dockerfile environment: - - DATABASE_URL=${DATABASE_URL:-postgresql://db_username:db_password@postgres:5432/db_name} + - INDEXER_CONFIG=/app/indexer/config.toml + - DB_HOST=postgres + - DB_PORT=5432 + - DB_USER=postgres + - DB_NAME=indexer ports: - - 5555:5555 + - "8100:8100" + expose: + - "7300" + volumes: + - ./indexer.toml:/app/indexer/config.toml/:ro + # needed only when running against the local devnet such + # that it can bootstrap the local deployment addresses + - ../go.mod:/app/go.mod/:ro + - ../.devnet/addresses.json:/app/.devnet/addresses.json/:ro healthcheck: - test: wget localhost:5555 -q -O - > /dev/null 2>&1 + test: wget api:8100/healthz -q -O - > /dev/null 2>&1 depends_on: postgres: condition: service_healthy - - prisma-check: - restart: "no" - build: - context: .. - dockerfile: indexer/ui/Dockerfile - command: ./prisma.sh --check - environment: - - DATABASE_URL=${DATABASE_URL:-postgresql://db_username:db_password@postgres:5432/db_name} + + prometheus: + image: prom/prometheus:latest + expose: + - "9090" + volumes: + - ./ops/prometheus:/etc/prometheus/:ro + - prometheus_data:/prometheus depends_on: - indexer: + index: condition: service_healthy - postgres: + api: condition: service_healthy - backend-goerli: - image: ethereumoptimism/gateway-backend:latest - platform: linux/amd64 + grafana: + image: grafana/grafana:latest environment: - # this enables the backend to proxy history requests to the indexer - - BRIDGE_INDEXER_URI=http://api - - HOST=0.0.0.0 - - PORT=7300 - - MIGRATE_APP_DB_USER=${MIGRATE_APP_DB_USER:-postgres} - - MIGRATE_APP_DB_PASSWORD=${MIGRATE_APP_DB_PASSWORD:-db_password} - - APP_DB_HOST=${APP_DB_HOST:-postgres-app} - - APP_DB_USER=${APP_DB_USER:-gateway-backend-goerli@oplabs-local-web.iam} - - APP_DB_NAME=${APP_DB_NAME:-gateway} - - APP_DB_PORT=${APP_DB_PORT:-5432} - - INDEXER_DB_HOST=${INDEXER_DB_HOST_GOERLI:-postgres-goerli} - - INDEXER_DB_USER=${INDEXER_DB_USER_GOERLI:-db_username} - - INDEXER_DB_PASS=${INDEXER_DB_PASSWORD_GOERLI:-db_password} - - INDEXER_DB_NAME=${INDEXER_DB_NAME_GOERLI:-db_name} - - INDEXER_DB_PORT=${INDEXER_DB_PORT_GOERLI:-5432} - - DATABASE_URL=${DATABASE_URL_GOERLI:-postgres://db_username:db_password@postgres-goerli:5432/db_name} - - JSON_RPC_URLS_L1=$JSON_RPC_URLS_L1_GOERLI - - JSON_RPC_URLS_L2=$JSON_RPC_URLS_L2_GOERLI - - JSON_RPC_URLS_L2_GOERLI=$JSON_RPC_URLS_L2_GOERLI - - FAUCET_AUTH_ADMIN_WALLET_PRIVATE_KEY=$FAUCET_AUTH_ADMIN_WALLET_PRIVATE_KEY - - IRON_SESSION_SECRET=${IRON_SESSION_SECRET:-UNKNOWN_IRON_SESSION_PASSWORD_32} - - CHAIN_ID_L1=5 - - CHAIN_ID_L2=420 - - FLEEK_BUCKET_ADDRESS=34a609661-6774-441f-9fdb-453fdbb89931-bucket - - FLEEK_API_SECRET=$FLEEK_API_SECRET - - FLEEK_API_KEY=$FLEEK_API_KEY - - MOCK_MERKLE_PROOF=true - - LOOP_INTERVAL_MINUTES=.1 - - GITHUB_CLIENT_ID=$GITHUB_CLIENT_ID - - GITHUB_SECRET=$GITHUB_SECRET - - MAINNET_BEDROCK=true - - TRM_API_KEY=$TRM_API_KEY - - GOOGLE_CLOUD_STORAGE_BUCKET_NAME=oplabs-dev-web-content - # Recommend to uncomment for local dev unless you need it - #- BYPASS_EVENT_LOG_POLLER_BOOTSTRAP=true + - GF_SECURITY_ADMIN_PASSWORD=optimism + - GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH=/var/lib/grafana/dashboards/indexer.json ports: - - 7422:7300 - # overrides command in Dockerfile so we can hot reload the server in docker while developing - #command: ['pnpm', 'nx', 'run', '@gateway/backend:docker:watch'] - healthcheck: - test: curl http://0.0.0.0:7300/api/v0/healthz + - "3000:3000" + volumes: + - ./ops/grafana/provisioning:/etc/grafana/provisioning/:ro + - ./ops/grafana/dashboards:/var/lib/grafana/dashboards/:ro + - grafana_data:/var/lib/grafana + depends_on: + prometheus: + condition: service_started volumes: postgres_data: + prometheus_data: + grafana_data: diff --git a/indexer/e2e_tests/bridge_messages_e2e_test.go b/indexer/e2e_tests/bridge_messages_e2e_test.go index 577ae2af3ce6..b5a2cbc38856 100644 --- a/indexer/e2e_tests/bridge_messages_e2e_test.go +++ b/indexer/e2e_tests/bridge_messages_e2e_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" + e2etest_utils "github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils" "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" @@ -13,6 +15,7 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-node/withdrawals" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" @@ -33,7 +36,9 @@ func TestE2EBridgeL1CrossDomainMessenger(t *testing.T) { l1Opts.Value = big.NewInt(params.Ether) // (1) Send the Message - sentMsgTx, err := l1CrossDomainMessenger.SendMessage(l1Opts, aliceAddr, calldata, 100_000) + sentMsgTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return l1CrossDomainMessenger.SendMessage(opts, aliceAddr, calldata, 100_000) + }) require.NoError(t, err) sentMsgReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, sentMsgTx.Hash()) require.NoError(t, err) @@ -43,7 +48,7 @@ func TestE2EBridgeL1CrossDomainMessenger(t *testing.T) { // wait for processor catchup require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastL1Header return l1Header != nil && l1Header.Number.Uint64() >= sentMsgReceipt.BlockNumber.Uint64(), nil })) @@ -66,7 +71,7 @@ func TestE2EBridgeL1CrossDomainMessenger(t *testing.T) { require.Equal(t, aliceAddr, sentMessage.Tx.ToAddress) require.ElementsMatch(t, calldata, sentMessage.Tx.Data) - // (2) Process RelayedMesssage on inclusion + // (2) Process RelayedMessage on inclusion // - We dont assert that `RelayedMessageEventGUID` is nil prior to inclusion since there isn't a // a straightforward way of pausing/resuming the processors at the right time. The codepath is the // same for L2->L1 messages which does check for this so we are still covered @@ -77,7 +82,7 @@ func TestE2EBridgeL1CrossDomainMessenger(t *testing.T) { l2DepositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, transaction.L2TransactionHash) require.NoError(t, err) require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l2Header := testSuite.Indexer.BridgeProcessor.LatestL2Header + l2Header := testSuite.Indexer.BridgeProcessor.LastFinalizedL2Header return l2Header != nil && l2Header.Number.Uint64() >= l2DepositReceipt.BlockNumber.Uint64(), nil })) @@ -112,13 +117,22 @@ func TestE2EBridgeL2CrossDomainMessenger(t *testing.T) { l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig()) require.NoError(t, err) l1Opts.Value = l2Opts.Value - depositTx, err := optimismPortal.Receive(l1Opts) + depositTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return optimismPortal.Receive(opts) + }) + require.NoError(t, err) + depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) + require.NoError(t, err) + depositInfo, err := e2etest_utils.ParseDepositInfo(depositReceipt) require.NoError(t, err) - _, err = wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) + depositL2TxHash := types.NewTx(depositInfo.DepositTx).Hash() + _, err = wait.ForReceiptOK(context.Background(), testSuite.L2Client, depositL2TxHash) require.NoError(t, err) // (1) Send the Message - sentMsgTx, err := l2CrossDomainMessenger.SendMessage(l2Opts, aliceAddr, calldata, 100_000) + sentMsgTx, err := transactions.PadGasEstimate(l2Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return l2CrossDomainMessenger.SendMessage(opts, aliceAddr, calldata, 100_000) + }) require.NoError(t, err) sentMsgReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, sentMsgTx.Hash()) require.NoError(t, err) @@ -130,7 +144,7 @@ func TestE2EBridgeL2CrossDomainMessenger(t *testing.T) { // wait for processor catchup require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l2Header := testSuite.Indexer.BridgeProcessor.LatestL2Header + l2Header := testSuite.Indexer.BridgeProcessor.LastL2Header return l2Header != nil && l2Header.Number.Uint64() >= sentMsgReceipt.BlockNumber.Uint64(), nil })) @@ -155,11 +169,11 @@ func TestE2EBridgeL2CrossDomainMessenger(t *testing.T) { // (2) Process RelayedMessage on withdrawal finalization require.Nil(t, sentMessage.RelayedMessageEventGUID) - _, finalizedReceipt := op_e2e.ProveAndFinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.L1Client, testSuite.OpSys.EthInstances["sequencer"], testSuite.OpCfg.Secrets.Alice, sentMsgReceipt) + _, finalizedReceipt, _, _ := op_e2e.ProveAndFinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.OpSys, "sequencer", testSuite.OpCfg.Secrets.Alice, sentMsgReceipt) // wait for processor catchup require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastFinalizedL1Header return l1Header != nil && l1Header.Number.Uint64() >= finalizedReceipt.BlockNumber.Uint64(), nil })) diff --git a/indexer/e2e_tests/bridge_transactions_e2e_test.go b/indexer/e2e_tests/bridge_transactions_e2e_test.go index d703615016bf..9a3fde152eb7 100644 --- a/indexer/e2e_tests/bridge_transactions_e2e_test.go +++ b/indexer/e2e_tests/bridge_transactions_e2e_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" + e2etest_utils "github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" @@ -37,7 +39,9 @@ func TestE2EBridgeTransactionsOptimismPortalDeposits(t *testing.T) { // In the same deposit transaction, transfer, 0.5ETH to Bob. We do this to ensure we're only indexing // bridged funds from the source address versus any transferred value to a recipient in the same L2 transaction - depositTx, err := optimismPortal.DepositTransaction(l1Opts, bobAddr, big.NewInt(params.Ether/2), 100_000, false, calldata) + depositTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return optimismPortal.DepositTransaction(opts, bobAddr, big.NewInt(params.Ether/2), 100_000, false, calldata) + }) require.NoError(t, err) depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) require.NoError(t, err) @@ -49,7 +53,7 @@ func TestE2EBridgeTransactionsOptimismPortalDeposits(t *testing.T) { // wait for processor catchup require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastL1Header return l1Header != nil && l1Header.Number.Uint64() >= depositReceipt.BlockNumber.Uint64(), nil })) @@ -92,19 +96,28 @@ func TestE2EBridgeTransactionsL2ToL1MessagePasserWithdrawal(t *testing.T) { l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig()) require.NoError(t, err) l1Opts.Value = l2Opts.Value - depositTx, err := optimismPortal.Receive(l1Opts) + depositTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return optimismPortal.Receive(opts) + }) + require.NoError(t, err) + depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) require.NoError(t, err) - _, err = wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) + depositInfo, err := e2etest_utils.ParseDepositInfo(depositReceipt) + require.NoError(t, err) + depositL2TxHash := types.NewTx(depositInfo.DepositTx).Hash() + _, err = wait.ForReceiptOK(context.Background(), testSuite.L2Client, depositL2TxHash) require.NoError(t, err) - withdrawTx, err := l2ToL1MessagePasser.InitiateWithdrawal(l2Opts, aliceAddr, big.NewInt(100_000), calldata) + withdrawTx, err := transactions.PadGasEstimate(l2Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return l2ToL1MessagePasser.InitiateWithdrawal(opts, aliceAddr, big.NewInt(100_000), calldata) + }) require.NoError(t, err) withdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, withdrawTx.Hash()) require.NoError(t, err) // wait for processor catchup require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l2Header := testSuite.Indexer.BridgeProcessor.LatestL2Header + l2Header := testSuite.Indexer.BridgeProcessor.LastL2Header return l2Header != nil && l2Header.Number.Uint64() >= withdrawReceipt.BlockNumber.Uint64(), nil })) @@ -132,9 +145,9 @@ func TestE2EBridgeTransactionsL2ToL1MessagePasserWithdrawal(t *testing.T) { require.Nil(t, withdraw.ProvenL1EventGUID) require.Nil(t, withdraw.FinalizedL1EventGUID) - withdrawParams, proveReceipt := op_e2e.ProveWithdrawal(t, *testSuite.OpCfg, testSuite.L1Client, testSuite.OpSys.EthInstances["sequencer"], testSuite.OpCfg.Secrets.Alice, withdrawReceipt) + withdrawParams, proveReceipt := op_e2e.ProveWithdrawal(t, *testSuite.OpCfg, testSuite.OpSys, "sequencer", testSuite.OpCfg.Secrets.Alice, withdrawReceipt) require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastFinalizedL1Header return l1Header != nil && l1Header.Number.Uint64() >= proveReceipt.BlockNumber.Uint64(), nil })) @@ -150,9 +163,9 @@ func TestE2EBridgeTransactionsL2ToL1MessagePasserWithdrawal(t *testing.T) { // Test Withdrawal Finalized require.Nil(t, withdraw.FinalizedL1EventGUID) - finalizeReceipt := op_e2e.FinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.L1Client, testSuite.OpCfg.Secrets.Alice, proveReceipt, withdrawParams) + finalizeReceipt, _, _ := op_e2e.FinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.L1Client, testSuite.OpCfg.Secrets.Alice, proveReceipt, withdrawParams) require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastFinalizedL1Header return l1Header != nil && l1Header.Number.Uint64() >= finalizeReceipt.BlockNumber.Uint64(), nil })) @@ -181,7 +194,9 @@ func TestE2EBridgeTransactionsL2ToL1MessagePasserFailedWithdrawal(t *testing.T) require.NoError(t, err) l2Opts.Value = big.NewInt(params.Ether) - withdrawTx, err := l2ToL1MessagePasser.InitiateWithdrawal(l2Opts, aliceAddr, big.NewInt(100_000), nil) + withdrawTx, err := transactions.PadGasEstimate(l2Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return l2ToL1MessagePasser.InitiateWithdrawal(opts, aliceAddr, big.NewInt(100_000), nil) + }) require.NoError(t, err) withdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, withdrawTx.Hash()) require.NoError(t, err) @@ -192,9 +207,9 @@ func TestE2EBridgeTransactionsL2ToL1MessagePasserFailedWithdrawal(t *testing.T) require.NoError(t, err) // Prove&Finalize withdrawal - _, finalizeReceipt := op_e2e.ProveAndFinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.L1Client, testSuite.OpSys.EthInstances["sequencer"], testSuite.OpCfg.Secrets.Alice, withdrawReceipt) + _, finalizeReceipt, _, _ := op_e2e.ProveAndFinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.OpSys, "sequencer", testSuite.OpCfg.Secrets.Alice, withdrawReceipt) require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastFinalizedL1Header return l1Header != nil && l1Header.Number.Uint64() >= finalizeReceipt.BlockNumber.Uint64(), nil })) diff --git a/indexer/e2e_tests/bridge_transfers_e2e_test.go b/indexer/e2e_tests/bridge_transfers_e2e_test.go index 1c7405b121b5..7814d7c53fc8 100644 --- a/indexer/e2e_tests/bridge_transfers_e2e_test.go +++ b/indexer/e2e_tests/bridge_transfers_e2e_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/indexer/bigint" e2etest_utils "github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" @@ -37,7 +38,9 @@ func TestE2EBridgeTransfersStandardBridgeETHDeposit(t *testing.T) { l1Opts.Value = big.NewInt(params.Ether) // (1) Test Deposit Initiation - depositTx, err := l1StandardBridge.DepositETH(l1Opts, 200_000, []byte{byte(1)}) + depositTx, err := transactions.PadGasEstimate(l1Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return l1StandardBridge.DepositETH(opts, 200_000, []byte{byte(1)}) + }) require.NoError(t, err) depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) require.NoError(t, err) @@ -47,7 +50,7 @@ func TestE2EBridgeTransfersStandardBridgeETHDeposit(t *testing.T) { // wait for processor catchup require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastL1Header return l1Header != nil && l1Header.Number.Uint64() >= depositReceipt.BlockNumber.Uint64(), nil })) @@ -81,7 +84,7 @@ func TestE2EBridgeTransfersStandardBridgeETHDeposit(t *testing.T) { l2DepositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, types.NewTx(depositInfo.DepositTx).Hash()) require.NoError(t, err) require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l2Header := testSuite.Indexer.BridgeProcessor.LatestL2Header + l2Header := testSuite.Indexer.BridgeProcessor.LastFinalizedL2Header return l2Header != nil && l2Header.Number.Uint64() >= l2DepositReceipt.BlockNumber.Uint64(), nil })) @@ -104,7 +107,9 @@ func TestE2EBridgeTransfersOptimismPortalETHReceive(t *testing.T) { l1Opts.Value = big.NewInt(params.Ether) // (1) Test Deposit Initiation - portalDepositTx, err := optimismPortal.Receive(l1Opts) + portalDepositTx, err := transactions.PadGasEstimate(l1Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return optimismPortal.Receive(opts) + }) require.NoError(t, err) portalDepositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, portalDepositTx.Hash()) require.NoError(t, err) @@ -114,7 +119,7 @@ func TestE2EBridgeTransfersOptimismPortalETHReceive(t *testing.T) { // wait for processor catchup require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastL1Header return l1Header != nil && l1Header.Number.Uint64() >= portalDepositReceipt.BlockNumber.Uint64(), nil })) @@ -140,7 +145,7 @@ func TestE2EBridgeTransfersOptimismPortalETHReceive(t *testing.T) { l2DepositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, types.NewTx(depositInfo.DepositTx).Hash()) require.NoError(t, err) require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l2Header := testSuite.Indexer.BridgeProcessor.LatestL2Header + l2Header := testSuite.Indexer.BridgeProcessor.LastFinalizedL2Header return l2Header != nil && l2Header.Number.Uint64() >= l2DepositReceipt.BlockNumber.Uint64(), nil })) @@ -182,7 +187,7 @@ func TestE2EBridgeTransfersCursoredDeposits(t *testing.T) { // wait for processor catchup of the latest tx require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastL1Header return l1Header != nil && l1Header.Number.Uint64() >= depositReceipts[2].BlockNumber.Uint64(), nil })) @@ -237,20 +242,29 @@ func TestE2EBridgeTransfersStandardBridgeETHWithdrawal(t *testing.T) { l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig()) require.NoError(t, err) l1Opts.Value = l2Opts.Value - depositTx, err := optimismPortal.Receive(l1Opts) + depositTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return optimismPortal.Receive(opts) + }) require.NoError(t, err) - _, err = wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) + depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) + require.NoError(t, err) + depositInfo, err := e2etest_utils.ParseDepositInfo(depositReceipt) + require.NoError(t, err) + depositL2TxHash := types.NewTx(depositInfo.DepositTx).Hash() + _, err = wait.ForReceiptOK(context.Background(), testSuite.L2Client, depositL2TxHash) require.NoError(t, err) // (1) Test Withdrawal Initiation - withdrawTx, err := l2StandardBridge.Withdraw(l2Opts, predeploys.LegacyERC20ETHAddr, l2Opts.Value, 200_000, []byte{byte(1)}) + withdrawTx, err := transactions.PadGasEstimate(l2Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return l2StandardBridge.Withdraw(opts, predeploys.LegacyERC20ETHAddr, l2Opts.Value, 200_000, []byte{byte(1)}) + }) require.NoError(t, err) withdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, withdrawTx.Hash()) require.NoError(t, err) // wait for processor catchup require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l2Header := testSuite.Indexer.BridgeProcessor.LatestL2Header + l2Header := testSuite.Indexer.BridgeProcessor.LastL2Header return l2Header != nil && l2Header.Number.Uint64() >= withdrawReceipt.BlockNumber.Uint64(), nil })) @@ -286,9 +300,9 @@ func TestE2EBridgeTransfersStandardBridgeETHWithdrawal(t *testing.T) { require.Empty(t, aliceWithdrawals.Withdrawals[0].FinalizedL1TransactionHash) // wait for processor catchup - proveReceipt, finalizeReceipt := op_e2e.ProveAndFinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.L1Client, testSuite.OpSys.EthInstances["sequencer"], testSuite.OpCfg.Secrets.Alice, withdrawReceipt) + proveReceipt, finalizeReceipt, _, _ := op_e2e.ProveAndFinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.OpSys, "sequencer", testSuite.OpCfg.Secrets.Alice, withdrawReceipt) require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastFinalizedL1Header return l1Header != nil && l1Header.Number.Uint64() >= finalizeReceipt.BlockNumber.Uint64(), nil })) @@ -321,20 +335,29 @@ func TestE2EBridgeTransfersL2ToL1MessagePasserETHReceive(t *testing.T) { l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig()) require.NoError(t, err) l1Opts.Value = l2Opts.Value - depositTx, err := optimismPortal.Receive(l1Opts) + depositTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return optimismPortal.Receive(opts) + }) + require.NoError(t, err) + depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) + require.NoError(t, err) + depositInfo, err := e2etest_utils.ParseDepositInfo(depositReceipt) require.NoError(t, err) - _, err = wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) + depositL2TxHash := types.NewTx(depositInfo.DepositTx).Hash() + _, err = wait.ForReceiptOK(context.Background(), testSuite.L2Client, depositL2TxHash) require.NoError(t, err) // (1) Test Withdrawal Initiation - l2ToL1MessagePasserWithdrawTx, err := l2ToL1MessagePasser.Receive(l2Opts) + l2ToL1MessagePasserWithdrawTx, err := transactions.PadGasEstimate(l2Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return l2ToL1MessagePasser.Receive(opts) + }) require.NoError(t, err) l2ToL1WithdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, l2ToL1MessagePasserWithdrawTx.Hash()) require.NoError(t, err) // wait for processor catchup require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l2Header := testSuite.Indexer.BridgeProcessor.LatestL2Header + l2Header := testSuite.Indexer.BridgeProcessor.LastL2Header return l2Header != nil && l2Header.Number.Uint64() >= l2ToL1WithdrawReceipt.BlockNumber.Uint64(), nil })) @@ -365,9 +388,9 @@ func TestE2EBridgeTransfersL2ToL1MessagePasserETHReceive(t *testing.T) { require.Empty(t, aliceWithdrawals.Withdrawals[0].FinalizedL1TransactionHash) // wait for processor catchup - proveReceipt, finalizeReceipt := op_e2e.ProveAndFinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.L1Client, testSuite.OpSys.EthInstances["sequencer"], testSuite.OpCfg.Secrets.Alice, l2ToL1WithdrawReceipt) + proveReceipt, finalizeReceipt, _, _ := op_e2e.ProveAndFinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.OpSys, "sequencer", testSuite.OpCfg.Secrets.Alice, l2ToL1WithdrawReceipt) require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header + l1Header := testSuite.Indexer.BridgeProcessor.LastFinalizedL1Header return l1Header != nil && l1Header.Number.Uint64() >= finalizeReceipt.BlockNumber.Uint64(), nil })) @@ -410,7 +433,7 @@ func TestE2EBridgeTransfersCursoredWithdrawals(t *testing.T) { // wait for processor catchup of the latest tx require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l2Header := testSuite.Indexer.BridgeProcessor.LatestL2Header + l2Header := testSuite.Indexer.BridgeProcessor.LastL2Header return l2Header != nil && l2Header.Number.Uint64() >= withdrawReceipts[2].BlockNumber.Uint64(), nil })) @@ -447,7 +470,7 @@ func TestE2EBridgeTransfersCursoredWithdrawals(t *testing.T) { } } -func TestClientGetWithdrawals(t *testing.T) { +func TestClientBridgeFunctions(t *testing.T) { testSuite := createE2ETestSuite(t) // (1) Generate contract bindings for the L1 and L2 standard bridges @@ -461,23 +484,43 @@ func TestClientGetWithdrawals(t *testing.T) { bobAddr := testSuite.OpCfg.Secrets.Addresses().Bob type actor struct { - addr common.Address - priv *ecdsa.PrivateKey + addr common.Address + priv *ecdsa.PrivateKey + amt *big.Int + receipt *types.Receipt } + mintSum := bigint.Zero + actors := []actor{ { addr: aliceAddr, priv: testSuite.OpCfg.Secrets.Alice, + amt: big.NewInt(0), }, { addr: bobAddr, priv: testSuite.OpCfg.Secrets.Bob, + amt: big.NewInt(0), }, } + type supplies struct { + all *big.Int + proven *big.Int + finalized *big.Int + } + + s := supplies{ + all: big.NewInt(0), + proven: big.NewInt(0), + finalized: big.NewInt(0), + } + // (3) Iterate over each actor and deposit / withdraw - for _, actor := range actors { + for i, actor := range actors { + t.Logf("%d - simulating deposit/withdrawal flow for %s", i, actor.addr.String()) + l2Opts, err := bind.NewKeyedTransactorWithChainID(actor.priv, testSuite.OpCfg.L2ChainIDBig()) require.NoError(t, err) l2Opts.Value = big.NewInt(params.Ether) @@ -486,23 +529,41 @@ func TestClientGetWithdrawals(t *testing.T) { l1Opts, err := bind.NewKeyedTransactorWithChainID(actor.priv, testSuite.OpCfg.L1ChainIDBig()) require.NoError(t, err) l1Opts.Value = l2Opts.Value - depositTx, err := optimismPortal.Receive(l1Opts) + depositTx, err := transactions.PadGasEstimate(l1Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return optimismPortal.Receive(opts) + }) require.NoError(t, err) - _, err = wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) + depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) + require.NoError(t, err) + depositInfo, err := e2etest_utils.ParseDepositInfo(depositReceipt) + require.NoError(t, err) + depositL2TxHash := types.NewTx(depositInfo.DepositTx).Hash() + _, err = wait.ForReceiptOK(context.Background(), testSuite.L2Client, depositL2TxHash) require.NoError(t, err) + mintSum = new(big.Int).Add(mintSum, depositTx.Value()) + // (3.b) Initiate withdrawal transaction via L2ToL1MessagePasser contract - l2ToL1MessagePasserWithdrawTx, err := l2ToL1MessagePasser.Receive(l2Opts) + l2ToL1MessagePasserWithdrawTx, err := transactions.PadGasEstimate(l2Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return l2ToL1MessagePasser.Receive(opts) + }) require.NoError(t, err) l2ToL1WithdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, l2ToL1MessagePasserWithdrawTx.Hash()) require.NoError(t, err) - // (3.c) wait for indexer processor to catchup with the L2 block containing the withdrawal tx + // (3.c) wait for indexer processor to catchup with the L1 & L2 block containing the deposit & withdrawal tx require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { - l2Header := testSuite.Indexer.BridgeProcessor.LatestL2Header - return l2Header != nil && l2Header.Number.Uint64() >= l2ToL1WithdrawReceipt.BlockNumber.Uint64(), nil + l1Header := testSuite.Indexer.BridgeProcessor.LastL1Header + l2Header := testSuite.Indexer.BridgeProcessor.LastL2Header + seenL2 := l2Header != nil && l2Header.Number.Uint64() >= l2ToL1WithdrawReceipt.BlockNumber.Uint64() + seenL1 := l1Header != nil && l1Header.Number.Uint64() >= depositReceipt.BlockNumber.Uint64() + return seenL1 && seenL2, nil })) + s.all = new(big.Int).Add(s.all, l2ToL1MessagePasserWithdrawTx.Value()) + actors[i].receipt = l2ToL1WithdrawReceipt + actors[i].amt = l2ToL1MessagePasserWithdrawTx.Value() + // (3.d) Ensure that withdrawal and deposit txs are retrievable via API deposits, err := testSuite.Client.GetAllDepositsByAddress(actor.addr) require.NoError(t, err) @@ -513,6 +574,52 @@ func TestClientGetWithdrawals(t *testing.T) { require.NoError(t, err) require.Len(t, withdrawals, 1) require.Equal(t, l2ToL1MessagePasserWithdrawTx.Hash().String(), withdrawals[0].TransactionHash) + } + // (4) Ensure that supply assessment is correct + assessment, err := testSuite.Client.GetSupplyAssessment() + require.NoError(t, err) + + mintFloat, _ := mintSum.Float64() + require.Equal(t, mintFloat, assessment.L1DepositSum) + + withdrawFloat, _ := s.all.Float64() + require.Equal(t, withdrawFloat, assessment.InitWithdrawalSum) + + require.Equal(t, assessment.ProvenWithdrawSum, float64(0)) + require.Equal(t, assessment.FinalizedWithdrawSum, float64(0)) + + // (5) Prove & finalize withdrawals on L1 + for _, actor := range actors { + params, proveReceipt := op_e2e.ProveWithdrawal(t, *testSuite.OpCfg, testSuite.OpSys, "sequencer", actor.priv, actor.receipt) + require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { + l1Header := testSuite.Indexer.BridgeProcessor.LastL1Header + seen := l1Header != nil && l1Header.Number.Uint64() >= proveReceipt.BlockNumber.Uint64() + return seen, nil + })) + + s.proven = new(big.Int).Add(s.proven, actor.amt) + + finalReceipt, _, _ := op_e2e.FinalizeWithdrawal(t, *testSuite.OpCfg, testSuite.L1Client, actor.priv, proveReceipt, params) + require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { + l1Header := testSuite.Indexer.BridgeProcessor.LastFinalizedL1Header + seen := l1Header != nil && l1Header.Number.Uint64() >= finalReceipt.BlockNumber.Uint64() + return seen, nil + })) + + s.finalized = new(big.Int).Add(s.finalized, actor.amt) + } + + // (6) Validate assessment for proven & finalized withdrawals + assessment, err = testSuite.Client.GetSupplyAssessment() + require.NoError(t, err) + + proven, acc := s.proven.Float64() + require.Zero(t, acc) + require.Equal(t, proven, assessment.ProvenWithdrawSum) + + finalized, acc := s.finalized.Float64() + require.Zero(t, acc) + require.Equal(t, finalized, assessment.FinalizedWithdrawSum) } diff --git a/indexer/e2e_tests/etl_e2e_test.go b/indexer/e2e_tests/etl_e2e_test.go index 8d85ae9e77ac..fcde8b653709 100644 --- a/indexer/e2e_tests/etl_e2e_test.go +++ b/indexer/e2e_tests/etl_e2e_test.go @@ -8,7 +8,10 @@ import ( "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/bindingspreview" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-node/withdrawals" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -24,9 +27,29 @@ func TestE2EETL(t *testing.T) { l2OutputOracle, err := bindings.NewL2OutputOracle(testSuite.OpCfg.L1Deployments.L2OutputOracleProxy, testSuite.L1Client) require.NoError(t, err) + disputeGameFactory, err := bindings.NewDisputeGameFactoryCaller(testSuite.OpCfg.L1Deployments.DisputeGameFactoryProxy, testSuite.L1Client) + require.NoError(t, err) + + optimismPortal, err := bindingspreview.NewOptimismPortal2Caller(testSuite.OpCfg.L1Deployments.OptimismPortalProxy, testSuite.L1Client) + require.NoError(t, err) + // wait for at least 10 L2 blocks posted on L1 require.NoError(t, wait.For(context.Background(), time.Second, func() (bool, error) { - l2Height, err := l2OutputOracle.LatestBlockNumber(&bind.CallOpts{Context: context.Background()}) + var l2Height *big.Int + var err error + if e2eutils.UseFPAC() { + gameCount, err := disputeGameFactory.GameCount(&bind.CallOpts{Context: context.Background()}) + require.NoError(t, err) + if gameCount.Cmp(big.NewInt(0)) == 0 { + return false, nil + } + + latestGame, err := withdrawals.FindLatestGame(context.Background(), disputeGameFactory, optimismPortal) + require.NoError(t, err) + l2Height = new(big.Int).SetBytes(latestGame.ExtraData[0:32]) + } else { + l2Height, err = l2OutputOracle.LatestBlockNumber(&bind.CallOpts{Context: context.Background()}) + } return l2Height != nil && l2Height.Uint64() >= 9, err })) diff --git a/indexer/e2e_tests/reorg_e2e_test.go b/indexer/e2e_tests/reorg_e2e_test.go new file mode 100644 index 000000000000..a6245f47426e --- /dev/null +++ b/indexer/e2e_tests/reorg_e2e_test.go @@ -0,0 +1,92 @@ +package e2e_tests + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/indexer/database" + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" +) + +func TestE2EReorgDeletion(t *testing.T) { + testSuite := createE2ETestSuite(t) + + // Conduct an L1 Deposit/Withdrawal through the standard bridge + // which touches the CDM and root bridge contracts. Thus we'll e2e + // test that the deletes appropriately cascades to all tables + + l1StandardBridge, err := bindings.NewL1StandardBridge(testSuite.OpCfg.L1Deployments.L1StandardBridgeProxy, testSuite.L1Client) + require.NoError(t, err) + l2StandardBridge, err := bindings.NewL2StandardBridge(predeploys.L2StandardBridgeAddr, testSuite.L2Client) + require.NoError(t, err) + + aliceAddr := testSuite.OpCfg.Secrets.Addresses().Alice + + l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig()) + require.NoError(t, err) + l2Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L2ChainIDBig()) + require.NoError(t, err) + + l1Opts.Value = big.NewInt(params.Ether) + l2Opts.Value = big.NewInt(params.Ether) + + // wait for an L1 block (depends on an emitted event -- L2OO) to get indexed as a reference point prior to deletion + require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { + latestL1Header, err := testSuite.DB.Blocks.L1LatestBlockHeader() + return latestL1Header != nil, err + })) + + depositTx, err := l1StandardBridge.DepositETH(l1Opts, 200_000, []byte{byte(1)}) + require.NoError(t, err) + depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash()) + require.NoError(t, err) + require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { + l1Header := testSuite.Indexer.BridgeProcessor.LastL1Header + return l1Header != nil && l1Header.Number.Uint64() >= depositReceipt.BlockNumber.Uint64(), nil + })) + deposits, err := testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, "", 1) + require.NoError(t, err) + require.Len(t, deposits.Deposits, 1) + + withdrawTx, err := l2StandardBridge.Withdraw(l2Opts, predeploys.LegacyERC20ETHAddr, l2Opts.Value, 200_000, []byte{byte(1)}) + require.NoError(t, err) + withdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, withdrawTx.Hash()) + require.NoError(t, err) + require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { + l2Header := testSuite.Indexer.BridgeProcessor.LastL2Header + return l2Header != nil && l2Header.Number.Uint64() >= withdrawReceipt.BlockNumber.Uint64(), nil + })) + withdrawals, err := testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, "", 1) + require.NoError(t, err) + require.Len(t, withdrawals.Withdrawals, 1) + + // Stop the indexer and reorg out L1 state from the deposit transaction + // and implicitly the derived L2 state where the withdrawal was initiated + depositBlock, err := testSuite.DB.Blocks.L1BlockHeaderWithFilter(database.BlockHeader{Number: depositReceipt.BlockNumber}) + require.NoError(t, err) + require.NoError(t, testSuite.Indexer.Stop(context.Background())) + require.NoError(t, testSuite.DB.Blocks.DeleteReorgedState(deposits.Deposits[0].L1BridgeDeposit.Tx.Timestamp)) + + // L1 & L2 block state deleted appropriately + latestL1Header, err := testSuite.DB.Blocks.L2LatestBlockHeader() + require.NoError(t, err) + require.True(t, latestL1Header.Timestamp < depositBlock.Timestamp) + latestL2Header, err := testSuite.DB.Blocks.L2LatestBlockHeader() + require.NoError(t, err) + require.True(t, latestL2Header.Timestamp < depositBlock.Timestamp) + + // Deposits/Withdrawals deletes cascade appropriately from log deletion + deposits, err = testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, "", 1) + require.NoError(t, err) + require.Len(t, deposits.Deposits, 0) + withdrawals, err = testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, "", 1) + require.NoError(t, err) + require.Len(t, withdrawals.Withdrawals, 0) +} diff --git a/indexer/e2e_tests/setup.go b/indexer/e2e_tests/setup.go index ebd69112c8aa..ae7fc445f9b6 100644 --- a/indexer/e2e_tests/setup.go +++ b/indexer/e2e_tests/setup.go @@ -15,11 +15,15 @@ import ( "github.com/ethereum-optimism/optimism/indexer/database" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/metrics" "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" _ "github.com/jackc/pgx/v5/stdlib" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" ) @@ -30,11 +34,12 @@ import ( */ type E2ETestSuite struct { - t *testing.T + t *testing.T + MetricsRegistry *prometheus.Registry // API Client *client.Client - API *api.API + API *api.APIService // Indexer DB *database.DB @@ -49,21 +54,32 @@ type E2ETestSuite struct { L2Client *ethclient.Client } +func init() { + // Disable the global logger. Ideally we'd like to dump geth + // logs per-test but that's possible when running tests in + // parallel as the root logger is shared. + oplog.SetGlobalLogHandler(log.DiscardHandler()) +} + // createE2ETestSuite ... Create a new E2E test suite func createE2ETestSuite(t *testing.T) E2ETestSuite { dbUser := os.Getenv("DB_USER") dbName := setupTestDatabase(t) - // Rollup System Configuration. Unless specified, - // omit logs emitted by the various components. Maybe - // we can eventually dump these logs to a temp file - log.Root().SetHandler(log.DiscardHandler()) + // E2E tests can run on the order of magnitude of minutes. + // We mark the test as parallel before starting the devnet + // to reduce that number of idle routines when paused. + t.Parallel() + opCfg := op_e2e.DefaultSystemConfig(t) + + // Unless specified, omit logs emitted by the various components if len(os.Getenv("ENABLE_ROLLUP_LOGS")) == 0 { t.Log("set env 'ENABLE_ROLLUP_LOGS' to show rollup logs") - for name, logger := range opCfg.Loggers { + for name := range opCfg.Loggers { t.Logf("discarding logs for %s", name) - logger.SetHandler(log.DiscardHandler()) + noopLog := log.NewLogger(log.DiscardHandler()) + opCfg.Loggers[name] = noopLog } } @@ -73,13 +89,8 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite { t.Cleanup(func() { opSys.Close() }) // Indexer Configuration and Start - indexerCfg := config.Config{ - DB: config.DBConfig{ - Host: "127.0.0.1", - Port: 5432, - Name: dbName, - User: dbUser, - }, + indexerCfg := &config.Config{ + DB: config.DBConfig{Host: "127.0.0.1", Port: 5432, Name: dbName, User: dbUser}, RPCs: config.RPCsConfig{ L1RPC: opSys.EthInstances["l1"].HTTPEndpoint(), L2RPC: opSys.EthInstances["sequencer"].HTTPEndpoint(), @@ -96,82 +107,59 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite { L1CrossDomainMessengerProxy: opCfg.L1Deployments.L1CrossDomainMessengerProxy, L1StandardBridgeProxy: opCfg.L1Deployments.L1StandardBridgeProxy, L1ERC721BridgeProxy: opCfg.L1Deployments.L1ERC721BridgeProxy, + DisputeGameFactoryProxy: opCfg.L1Deployments.DisputeGameFactoryProxy, }, }, HTTPServer: config.ServerConfig{Host: "127.0.0.1", Port: 0}, MetricsServer: config.ServerConfig{Host: "127.0.0.1", Port: 0}, } - // E2E tests can run on the order of magnitude of minutes. Once - // the system is running, mark this test for Parallel execution - t.Parallel() - - // provide a DB for the unit test. disable logging - silentLog := testlog.Logger(t, log.LvlInfo) - silentLog.SetHandler(log.DiscardHandler()) - db, err := database.NewDB(silentLog, indexerCfg.DB) + indexerLog := testlog.Logger(t, log.LevelInfo).New("role", "indexer") + ix, err := indexer.NewIndexer(context.Background(), indexerLog, indexerCfg, func(cause error) { + if cause != nil { + t.Fatalf("indexer shut down with critical error: %v", cause) + } + }) require.NoError(t, err) - t.Cleanup(func() { db.Close() }) + require.NoError(t, ix.Start(context.Background()), "cleanly start indexer") + t.Cleanup(func() { require.NoError(t, ix.Stop(context.Background())) }) - indexerLog := testlog.Logger(t, log.LvlInfo).New("role", "indexer") - indexer, err := indexer.NewIndexer(indexerLog, db, indexerCfg.Chain, indexerCfg.RPCs, indexerCfg.HTTPServer, indexerCfg.MetricsServer) + dbLog := testlog.Logger(t, log.LvlInfo).New("role", "db") + db, err := database.NewDB(context.Background(), dbLog, indexerCfg.DB) require.NoError(t, err) + t.Cleanup(func() { db.Close() }) - indexerCtx, indexerStop := context.WithCancel(context.Background()) - go func() { - err := indexer.Run(indexerCtx) - if err != nil { // panicking here ensures that the test will exit - // during service failure. Using t.Fail() wouldn't be caught - // until all awaiting routines finish which would never happen. - panic(err) - } - }() - - apiLog := testlog.Logger(t, log.LvlInfo).New("role", "indexer_api") - - apiCfg := config.ServerConfig{ - Host: "127.0.0.1", - Port: 0, - } - - mCfg := config.ServerConfig{ - Host: "127.0.0.1", - Port: 0, + // API Configuration and Start + apiLog := testlog.Logger(t, log.LevelInfo).New("role", "indexer_api") + apiCfg := &api.Config{ + DB: &api.TestDBConnector{BridgeTransfers: db.BridgeTransfers}, // reuse the same DB + HTTPServer: config.ServerConfig{Host: "127.0.0.1", Port: 0}, + MetricsServer: config.ServerConfig{Host: "127.0.0.1", Port: 0}, } - api := api.NewApi(apiLog, db.BridgeTransfers, apiCfg, mCfg) - apiCtx, apiStop := context.WithCancel(context.Background()) - go func() { - err := api.Run(apiCtx) - if err != nil { - panic(err) - } - }() - + apiService, err := api.NewApi(context.Background(), apiLog, apiCfg) + require.NoError(t, err, "create indexer API service") + require.NoError(t, apiService.Start(context.Background()), "start indexer API service") t.Cleanup(func() { - apiStop() - indexerStop() + require.NoError(t, apiService.Stop(context.Background()), "cleanly shut down indexer") }) // Wait for the API to start listening time.Sleep(1 * time.Second) - client, err := client.NewClient(&client.Config{ - PaginationLimit: 100, - BaseURL: fmt.Sprintf("http://%s:%d", apiCfg.Host, api.Port()), - }) - - require.NoError(t, err) + client, err := client.NewClient(&client.Config{PaginationLimit: 100, BaseURL: "http://" + apiService.Addr()}) + require.NoError(t, err, "must open indexer API client") return E2ETestSuite{ - t: t, - Client: client, - DB: db, - Indexer: indexer, - OpCfg: &opCfg, - OpSys: opSys, - L1Client: opSys.Clients["l1"], - L2Client: opSys.Clients["sequencer"], + t: t, + MetricsRegistry: metrics.NewRegistry(), + Client: client, + DB: db, + Indexer: ix, + OpCfg: &opCfg, + OpSys: opSys, + L1Client: opSys.Clients["l1"], + L2Client: opSys.Clients["sequencer"], } } @@ -201,9 +189,8 @@ func setupTestDatabase(t *testing.T) string { Password: "", } - silentLog := log.New() - silentLog.SetHandler(log.DiscardHandler()) - db, err := database.NewDB(silentLog, dbConfig) + noopLog := log.NewLogger(log.DiscardHandler()) + db, err := database.NewDB(context.Background(), noopLog, dbConfig) require.NoError(t, err) defer db.Close() diff --git a/indexer/e2e_tests/utils/cross_domain_messages.go b/indexer/e2e_tests/utils/cross_domain_messages.go index eb30b072b62c..e36c453c7857 100644 --- a/indexer/e2e_tests/utils/cross_domain_messages.go +++ b/indexer/e2e_tests/utils/cross_domain_messages.go @@ -4,12 +4,11 @@ import ( "errors" "math/big" - "github.com/ethereum-optimism/optimism/indexer/processors/contracts" "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" ) type CrossDomainMessengerSentMessage struct { @@ -40,7 +39,17 @@ func ParseCrossDomainMessage(sentMessageReceipt *types.Receipt) (CrossDomainMess if err != nil { return CrossDomainMessengerSentMessage{}, err } - msgHash, err := CrossDomainMessengerSentMessageHash(sentMessage, sentMessageExtension.Value) + + msg := crossdomain.NewCrossDomainMessage( + sentMessage.MessageNonce, + sentMessage.Sender, + sentMessage.Target, + sentMessageExtension.Value, + sentMessage.GasLimit, + sentMessage.Message, + ) + + msgHash, err := msg.Hash() if err != nil { return CrossDomainMessengerSentMessage{}, err } @@ -51,17 +60,3 @@ func ParseCrossDomainMessage(sentMessageReceipt *types.Receipt) (CrossDomainMess return CrossDomainMessengerSentMessage{}, errors.New("missing SentMessage receipts") } - -func CrossDomainMessengerSentMessageHash(sentMessage *bindings.CrossDomainMessengerSentMessage, value *big.Int) (common.Hash, error) { - abi, err := bindings.CrossDomainMessengerMetaData.GetAbi() - if err != nil { - return common.Hash{}, err - } - - calldata, err := contracts.CrossDomainMessageCalldata(abi, sentMessage, value) - if err != nil { - return common.Hash{}, err - } - - return crypto.Keccak256Hash(calldata), nil -} diff --git a/indexer/etl/etl.go b/indexer/etl/etl.go index 501bc795ae93..44b468087d34 100644 --- a/indexer/etl/etl.go +++ b/indexer/etl/etl.go @@ -7,11 +7,13 @@ import ( "math/big" "time" - "github.com/ethereum-optimism/optimism/indexer/node" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/indexer/node" + "github.com/ethereum-optimism/optimism/op-service/clock" ) type Config struct { @@ -31,9 +33,15 @@ type ETL struct { headerTraversal *node.HeaderTraversal contracts []common.Address - etlBatches chan ETLBatch + etlBatches chan *ETLBatch EthClient node.EthClient + + // A reference that'll stay populated between intervals + // in the event of failures in order to retry. + headers []types.Header + + worker *clock.LoopFn } type ETLBatch struct { @@ -46,51 +54,53 @@ type ETLBatch struct { HeadersWithLog map[common.Hash]bool } -func (etl *ETL) Start(ctx context.Context) error { - done := ctx.Done() - pollTicker := time.NewTicker(etl.loopInterval) - defer pollTicker.Stop() +// Start starts the ETL polling routine. The ETL work should be stopped with Close(). +func (etl *ETL) Start() error { + if etl.worker != nil { + return errors.New("already started") + } + etl.worker = clock.NewLoopFn(clock.SystemClock, etl.tick, func() error { + etl.log.Info("shutting down batch producer") + close(etl.etlBatches) // can close the channel now, to signal to the consumer that we're done + return nil + }, etl.loopInterval) + return nil +} - // A reference that'll stay populated between intervals - // in the event of failures in order to retry. - var headers []types.Header - - etl.log.Info("starting etl...") - for { - select { - case <-done: - etl.log.Info("stopping etl") - return nil - - case <-pollTicker.C: - done := etl.metrics.RecordInterval() - if len(headers) > 0 { - etl.log.Info("retrying previous batch") - } else { - newHeaders, err := etl.headerTraversal.NextHeaders(etl.headerBufferSize) - if err != nil { - etl.log.Error("error querying for headers", "err", err) - } else if len(newHeaders) == 0 { - etl.log.Warn("no new headers. etl at head?") - } else { - headers = newHeaders - } - - latestHeader := etl.headerTraversal.LatestHeader() - if latestHeader != nil { - etl.metrics.RecordLatestHeight(latestHeader.Number) - } - } - - // only clear the reference if we were able to process this batch - err := etl.processBatch(headers) - if err == nil { - headers = nil - } - - done(err) +func (etl *ETL) Close() error { + if etl.worker == nil { + return nil // worker was not running + } + return etl.worker.Close() +} + +func (etl *ETL) tick(_ context.Context) { + done := etl.metrics.RecordInterval() + if len(etl.headers) > 0 { + etl.log.Info("retrying previous batch") + } else { + newHeaders, err := etl.headerTraversal.NextHeaders(etl.headerBufferSize) + if err != nil { + etl.log.Error("error querying for headers", "err", err) + } else if len(newHeaders) == 0 { + etl.log.Warn("no new headers. etl at head?") + } else { + etl.headers = newHeaders + } + + latestHeader := etl.headerTraversal.LatestHeader() + if latestHeader != nil { + etl.metrics.RecordLatestHeight(latestHeader.Number) } } + + // only clear the reference if we were able to process this batch + err := etl.processBatch(etl.headers) + if err == nil { + etl.headers = nil + } + + done(err) } func (etl *ETL) processBatch(headers []types.Header) error { @@ -121,8 +131,8 @@ func (etl *ETL) processBatch(headers []types.Header) error { batchLog.Warn("mismatch in FilterLog#ToBlock number", "queried_to_block_number", lastHeader.Number, "reported_to_block_number", logs.ToBlockHeader.Number) return fmt.Errorf("mismatch in FilterLog#ToBlock number") } else if logs.ToBlockHeader.Hash() != lastHeader.Hash() { - batchLog.Error("mismatch in FitlerLog#ToBlock block hash!!!", "queried_to_block_hash", lastHeader.Hash().String(), "reported_to_block_hash", logs.ToBlockHeader.Hash().String()) - return fmt.Errorf("mismatch in FitlerLog#ToBlock block hash!!!") + batchLog.Error("mismatch in FilterLog#ToBlock block hash!!!", "queried_to_block_hash", lastHeader.Hash().String(), "reported_to_block_hash", logs.ToBlockHeader.Hash().String()) + return fmt.Errorf("mismatch in FilterLog#ToBlock block hash!!!") } if len(logs.Logs) > 0 { @@ -143,6 +153,6 @@ func (etl *ETL) processBatch(headers []types.Header) error { // ensure we use unique downstream references for the etl batch headersRef := headers - etl.etlBatches <- ETLBatch{Logger: batchLog, Headers: headersRef, HeaderMap: headerMap, Logs: logs.Logs, HeadersWithLog: headersWithLog} + etl.etlBatches <- &ETLBatch{Logger: batchLog, Headers: headersRef, HeaderMap: headerMap, Logs: logs.Logs, HeadersWithLog: headersWithLog} return nil } diff --git a/indexer/etl/l1_etl.go b/indexer/etl/l1_etl.go index 490d45fe69ab..4fcd9b020365 100644 --- a/indexer/etl/l1_etl.go +++ b/indexer/etl/l1_etl.go @@ -8,26 +8,37 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/node" "github.com/ethereum-optimism/optimism/op-service/retry" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/tasks" ) type L1ETL struct { ETL + LatestHeader *types.Header + + // the batch handler may do work that we can interrupt on shutdown + resourceCtx context.Context + resourceCancel context.CancelFunc + + tasks tasks.Group - db *database.DB - mu *sync.Mutex + db *database.DB + + mu sync.Mutex listeners []chan interface{} } // NewL1ETL creates a new L1ETL instance that will start indexing from different starting points // depending on the state of the database and the supplied start height. -func NewL1ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, client node.EthClient, contracts config.L1Contracts) (*L1ETL, error) { +func NewL1ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, client node.EthClient, + contracts config.L1Contracts, shutdown context.CancelCauseFunc) (*L1ETL, error) { log = log.New("etl", "l1") zeroAddr := common.Address{} @@ -71,8 +82,10 @@ func NewL1ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, cli } // NOTE - The use of un-buffered channel here assumes that downstream consumers - // will be able to keep up with the rate of incoming batches - etlBatches := make(chan ETLBatch) + // will be able to keep up with the rate of incoming batches. + // When the producer closes the channel we stop consuming from it. + etlBatches := make(chan *ETLBatch) + etl := ETL{ loopInterval: time.Duration(cfg.LoopIntervalMsec) * time.Millisecond, headerBufferSize: uint64(cfg.HeaderBufferSize), @@ -86,82 +99,127 @@ func NewL1ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, cli EthClient: client, } - return &L1ETL{ETL: etl, db: db, mu: new(sync.Mutex)}, nil + resCtx, resCancel := context.WithCancel(context.Background()) + return &L1ETL{ + ETL: etl, + LatestHeader: fromHeader, + + db: db, + resourceCtx: resCtx, + resourceCancel: resCancel, + tasks: tasks.Group{HandleCrit: func(err error) { + shutdown(fmt.Errorf("critical error in L1 ETL: %w", err)) + }}, + }, nil } -func (l1Etl *L1ETL) Start(ctx context.Context) error { - errCh := make(chan error, 1) - go func() { - errCh <- l1Etl.ETL.Start(ctx) - }() +func (l1Etl *L1ETL) Close() error { + var result error + // close the producer + if err := l1Etl.ETL.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close internal ETL: %w", err)) + } + // tell the consumer it can stop what it's doing + l1Etl.resourceCancel() + // wait for consumer to pick up on closure of producer + if err := l1Etl.tasks.Wait(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to await batch handler completion: %w", err)) + } + // close listeners + for i := range l1Etl.listeners { + close(l1Etl.listeners[i]) + } + return result +} - for { - select { - case err := <-errCh: - return err - - // Index incoming batches (only L1 blocks that have an emitted log) - case batch := <-l1Etl.etlBatches: - l1BlockHeaders := make([]database.L1BlockHeader, 0, len(batch.Headers)) - for i := range batch.Headers { - if _, ok := batch.HeadersWithLog[batch.Headers[i].Hash()]; ok { - l1BlockHeaders = append(l1BlockHeaders, database.L1BlockHeader{BlockHeader: database.BlockHeaderFromHeader(&batch.Headers[i])}) - } - } +func (l1Etl *L1ETL) Start() error { + l1Etl.log.Info("starting etl...") - if len(l1BlockHeaders) == 0 { - batch.Logger.Info("no l1 blocks with logs in batch") - continue + // start ETL batch producer + if err := l1Etl.ETL.Start(); err != nil { + return fmt.Errorf("failed to start internal ETL: %w", err) + } + // start ETL batch consumer + l1Etl.tasks.Go(func() error { + for batch := range l1Etl.etlBatches { + if err := l1Etl.handleBatch(batch); err != nil { + return fmt.Errorf("failed to handle batch, stopping L2 ETL: %w", err) } + } + l1Etl.log.Info("no more batches, shutting down batch handler") + return nil + }) + return nil +} - l1ContractEvents := make([]database.L1ContractEvent, len(batch.Logs)) - for i := range batch.Logs { - timestamp := batch.HeaderMap[batch.Logs[i].BlockHash].Time - l1ContractEvents[i] = database.L1ContractEvent{ContractEvent: database.ContractEventFromLog(&batch.Logs[i], timestamp)} - l1Etl.ETL.metrics.RecordIndexedLog(batch.Logs[i].Address) - } +func (l1Etl *L1ETL) handleBatch(batch *ETLBatch) error { + // Index incoming batches (only L1 blocks that have an emitted log) + l1BlockHeaders := make([]database.L1BlockHeader, 0, len(batch.Headers)) + for i := range batch.Headers { + if _, ok := batch.HeadersWithLog[batch.Headers[i].Hash()]; ok { + l1BlockHeaders = append(l1BlockHeaders, database.L1BlockHeader{BlockHeader: database.BlockHeaderFromHeader(&batch.Headers[i])}) + } + } + + l1ContractEvents := make([]database.L1ContractEvent, len(batch.Logs)) + for i := range batch.Logs { + timestamp := batch.HeaderMap[batch.Logs[i].BlockHash].Time + l1ContractEvents[i] = database.L1ContractEvent{ContractEvent: database.ContractEventFromLog(&batch.Logs[i], timestamp)} + l1Etl.ETL.metrics.RecordIndexedLog(batch.Logs[i].Address) + } + + // Continually try to persist this batch. If it fails after 10 attempts, we simply error out + retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250} + if _, err := retry.Do[interface{}](l1Etl.resourceCtx, 10, retryStrategy, func() (interface{}, error) { + if len(l1BlockHeaders) == 0 { + return nil, nil // skip + } - // Continually try to persist this batch. If it fails after 10 attempts, we simply error out - retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250} - if _, err := retry.Do[interface{}](ctx, 10, retryStrategy, func() (interface{}, error) { - if err := l1Etl.db.Transaction(func(tx *database.DB) error { - if err := tx.Blocks.StoreL1BlockHeaders(l1BlockHeaders); err != nil { - return err - } - // we must have logs if we have l1 blocks - if err := tx.ContractEvents.StoreL1ContractEvents(l1ContractEvents); err != nil { - return err - } - return nil - }); err != nil { - batch.Logger.Error("unable to persist batch", "err", err) - return nil, err - } - - l1Etl.ETL.metrics.RecordIndexedHeaders(len(l1BlockHeaders)) - l1Etl.ETL.metrics.RecordIndexedLatestHeight(l1BlockHeaders[len(l1BlockHeaders)-1].Number) - - // a-ok! - return nil, nil - }); err != nil { + if err := l1Etl.db.Transaction(func(tx *database.DB) error { + if err := tx.Blocks.StoreL1BlockHeaders(l1BlockHeaders); err != nil { return err } - - batch.Logger.Info("indexed batch") - - // Notify Listeners - l1Etl.mu.Lock() - for i := range l1Etl.listeners { - select { - case l1Etl.listeners[i] <- struct{}{}: - default: - // do nothing if the listener hasn't picked - // up the previous notif - } + // we must have logs if we have l1 blocks + if err := tx.ContractEvents.StoreL1ContractEvents(l1ContractEvents); err != nil { + return err } - l1Etl.mu.Unlock() + return nil + }); err != nil { + batch.Logger.Error("unable to persist batch", "err", err) + return nil, fmt.Errorf("unable to persist batch: %w", err) } + + // a-ok! + return nil, nil + }); err != nil { + return err } + + if len(l1BlockHeaders) == 0 { + batch.Logger.Info("skipped batch. no logs found") + } else { + batch.Logger.Info("indexed batch") + } + + // Since not every L1 block is indexed, we still want our metrics to cover L1 blocks + // that have been observed so that a false stall alert isn't triggered on low activity + l1Etl.LatestHeader = &batch.Headers[len(batch.Headers)-1] + l1Etl.ETL.metrics.RecordIndexedHeaders(len(l1BlockHeaders)) + l1Etl.ETL.metrics.RecordEtlLatestHeight(l1Etl.LatestHeader.Number) + + // Notify Listeners + l1Etl.mu.Lock() + defer l1Etl.mu.Unlock() + for i := range l1Etl.listeners { + select { + case l1Etl.listeners[i] <- struct{}{}: + default: + // do nothing if the listener hasn't picked + // up the previous notif + } + } + + return nil } // Notify returns a channel that'll receive a value every time new data has diff --git a/indexer/etl/l1_etl_test.go b/indexer/etl/l1_etl_test.go index 0c6b49dbac9a..e57f16f6fd92 100644 --- a/indexer/etl/l1_etl_test.go +++ b/indexer/etl/l1_etl_test.go @@ -105,10 +105,12 @@ func TestL1ETLConstruction(t *testing.T) { t.Run(test.name, func(t *testing.T) { ts := test.construction() - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) cfg := Config{StartHeight: ts.start} - etl, err := NewL1ETL(cfg, logger, ts.db.DB, etlMetrics, ts.client, ts.contracts) + etl, err := NewL1ETL(cfg, logger, ts.db.DB, etlMetrics, ts.client, ts.contracts, func(cause error) { + t.Fatalf("crit error: %v", cause) + }) test.assertion(etl, err) }) } diff --git a/indexer/etl/l2_etl.go b/indexer/etl/l2_etl.go index f6b5ab0fabab..b88d71bf8932 100644 --- a/indexer/etl/l2_etl.go +++ b/indexer/etl/l2_etl.go @@ -3,24 +3,39 @@ package etl import ( "context" "errors" + "fmt" + "sync" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/node" "github.com/ethereum-optimism/optimism/op-service/retry" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/tasks" ) type L2ETL struct { ETL + LatestHeader *types.Header + + // the batch handler may do work that we can interrupt on shutdown + resourceCtx context.Context + resourceCancel context.CancelFunc + + tasks tasks.Group db *database.DB + + mu sync.Mutex + listeners []chan interface{} } -func NewL2ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, client node.EthClient, contracts config.L2Contracts) (*L2ETL, error) { +func NewL2ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, client node.EthClient, + contracts config.L2Contracts, shutdown context.CancelCauseFunc) (*L2ETL, error) { log = log.New("etl", "l2") zeroAddr := common.Address{} @@ -54,7 +69,7 @@ func NewL2ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, cli log.Info("no indexed state, starting from genesis") } - etlBatches := make(chan ETLBatch) + etlBatches := make(chan *ETLBatch) etl := ETL{ loopInterval: time.Duration(cfg.LoopIntervalMsec) * time.Millisecond, headerBufferSize: uint64(cfg.HeaderBufferSize), @@ -68,62 +83,126 @@ func NewL2ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, cli EthClient: client, } - return &L2ETL{ETL: etl, db: db}, nil + resCtx, resCancel := context.WithCancel(context.Background()) + return &L2ETL{ + ETL: etl, + LatestHeader: fromHeader, + + resourceCtx: resCtx, + resourceCancel: resCancel, + db: db, + tasks: tasks.Group{HandleCrit: func(err error) { + shutdown(fmt.Errorf("critical error in L2 ETL: %w", err)) + }}, + }, nil } -func (l2Etl *L2ETL) Start(ctx context.Context) error { - errCh := make(chan error, 1) - go func() { - errCh <- l2Etl.ETL.Start(ctx) - }() +func (l2Etl *L2ETL) Close() error { + var result error + // close the producer + if err := l2Etl.ETL.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close internal ETL: %w", err)) + } + // tell the consumer it can stop what it's doing + l2Etl.resourceCancel() + // wait for consumer to pick up on closure of producer + if err := l2Etl.tasks.Wait(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to await batch handler completion: %w", err)) + } + // close listeners + for i := range l2Etl.listeners { + close(l2Etl.listeners[i]) + } + return result +} - for { - select { - case err := <-errCh: - return err - - // Index incoming batches (all L2 Blocks) - case batch := <-l2Etl.etlBatches: - l2BlockHeaders := make([]database.L2BlockHeader, len(batch.Headers)) - for i := range batch.Headers { - l2BlockHeaders[i] = database.L2BlockHeader{BlockHeader: database.BlockHeaderFromHeader(&batch.Headers[i])} - } +func (l2Etl *L2ETL) Start() error { + l2Etl.log.Info("starting etl...") + + // start ETL batch producer + if err := l2Etl.ETL.Start(); err != nil { + return fmt.Errorf("failed to start internal ETL: %w", err) + } - l2ContractEvents := make([]database.L2ContractEvent, len(batch.Logs)) - for i := range batch.Logs { - timestamp := batch.HeaderMap[batch.Logs[i].BlockHash].Time - l2ContractEvents[i] = database.L2ContractEvent{ContractEvent: database.ContractEventFromLog(&batch.Logs[i], timestamp)} - l2Etl.ETL.metrics.RecordIndexedLog(batch.Logs[i].Address) + // start ETL batch consumer + l2Etl.tasks.Go(func() error { + for batch := range l2Etl.etlBatches { + if err := l2Etl.handleBatch(batch); err != nil { + return fmt.Errorf("failed to handle batch, stopping L2 ETL: %w", err) } + } + l2Etl.log.Info("no more batches, shutting down batch handler") + return nil + }) + return nil +} - // Continually try to persist this batch. If it fails after 10 attempts, we simply error out - retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250} - if _, err := retry.Do[interface{}](ctx, 10, retryStrategy, func() (interface{}, error) { - if err := l2Etl.db.Transaction(func(tx *database.DB) error { - if err := tx.Blocks.StoreL2BlockHeaders(l2BlockHeaders); err != nil { - return err - } - if len(l2ContractEvents) > 0 { - if err := tx.ContractEvents.StoreL2ContractEvents(l2ContractEvents); err != nil { - return err - } - } - return nil - }); err != nil { - batch.Logger.Error("unable to persist batch", "err", err) - return nil, err - } +func (l2Etl *L2ETL) handleBatch(batch *ETLBatch) error { + l2BlockHeaders := make([]database.L2BlockHeader, len(batch.Headers)) + for i := range batch.Headers { + l2BlockHeaders[i] = database.L2BlockHeader{BlockHeader: database.BlockHeaderFromHeader(&batch.Headers[i])} + } - l2Etl.ETL.metrics.RecordIndexedHeaders(len(l2BlockHeaders)) - l2Etl.ETL.metrics.RecordIndexedLatestHeight(l2BlockHeaders[len(l2BlockHeaders)-1].Number) + l2ContractEvents := make([]database.L2ContractEvent, len(batch.Logs)) + for i := range batch.Logs { + timestamp := batch.HeaderMap[batch.Logs[i].BlockHash].Time + l2ContractEvents[i] = database.L2ContractEvent{ContractEvent: database.ContractEventFromLog(&batch.Logs[i], timestamp)} + l2Etl.ETL.metrics.RecordIndexedLog(batch.Logs[i].Address) + } - // a-ok! - return nil, nil - }); err != nil { + // Continually try to persist this batch. If it fails after 10 attempts, we simply error out + retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250} + if _, err := retry.Do[interface{}](l2Etl.resourceCtx, 10, retryStrategy, func() (interface{}, error) { + if err := l2Etl.db.Transaction(func(tx *database.DB) error { + if err := tx.Blocks.StoreL2BlockHeaders(l2BlockHeaders); err != nil { return err } + if len(l2ContractEvents) > 0 { + if err := tx.ContractEvents.StoreL2ContractEvents(l2ContractEvents); err != nil { + return err + } + } + return nil + }); err != nil { + batch.Logger.Error("unable to persist batch", "err", err) + return nil, err + } + + // a-ok! + return nil, nil + }); err != nil { + return err + } + + batch.Logger.Info("indexed batch") - batch.Logger.Info("indexed batch") + // All L2 blocks are indexed so len(batch.Headers) == len(l2BlockHeaders) + l2Etl.LatestHeader = &batch.Headers[len(batch.Headers)-1] + l2Etl.ETL.metrics.RecordIndexedHeaders(len(l2BlockHeaders)) + l2Etl.ETL.metrics.RecordEtlLatestHeight(l2Etl.LatestHeader.Number) + + // Notify Listeners + l2Etl.mu.Lock() + defer l2Etl.mu.Unlock() + for i := range l2Etl.listeners { + select { + case l2Etl.listeners[i] <- struct{}{}: + default: + // do nothing if the listener hasn't picked + // up the previous notif } } + + return nil +} + +// Notify returns a channel that'll receive a value every time new data has +// been persisted by the L2ETL +func (l2Etl *L2ETL) Notify() <-chan interface{} { + receiver := make(chan interface{}) + l2Etl.mu.Lock() + defer l2Etl.mu.Unlock() + + l2Etl.listeners = append(l2Etl.listeners, receiver) + return receiver } diff --git a/indexer/etl/metrics.go b/indexer/etl/metrics.go index 3a2e70ccc770..5d4b8f6c07ec 100644 --- a/indexer/etl/metrics.go +++ b/indexer/etl/metrics.go @@ -16,8 +16,7 @@ type Metricer interface { RecordInterval() (done func(err error)) RecordLatestHeight(height *big.Int) - // Indexed Batches - RecordIndexedLatestHeight(height *big.Int) + RecordEtlLatestHeight(height *big.Int) RecordIndexedHeaders(size int) RecordIndexedLog(contractAddress common.Address) } @@ -28,9 +27,9 @@ type etlMetrics struct { intervalFailures prometheus.Counter latestHeight prometheus.Gauge - indexedLatestHeight prometheus.Gauge - indexedHeaders prometheus.Counter - indexedLogs *prometheus.CounterVec + etlLatestHeight prometheus.Gauge + indexedHeaders prometheus.Counter + indexedLogs *prometheus.CounterVec } func NewMetrics(registry *prometheus.Registry, subsystem string) Metricer { @@ -60,11 +59,11 @@ func NewMetrics(registry *prometheus.Registry, subsystem string) Metricer { Name: "latest_height", Help: "the latest height reported by the connected client", }), - indexedLatestHeight: factory.NewGauge(prometheus.GaugeOpts{ + etlLatestHeight: factory.NewGauge(prometheus.GaugeOpts{ Namespace: MetricsNamespace, Subsystem: subsystem, Name: "indexed_height", - Help: "the latest block height indexed into the database", + Help: "the latest block height after a processing interval by the etl", }), indexedHeaders: factory.NewCounter(prometheus.CounterOpts{ Namespace: MetricsNamespace, @@ -98,8 +97,8 @@ func (m *etlMetrics) RecordLatestHeight(height *big.Int) { m.latestHeight.Set(float64(height.Uint64())) } -func (m *etlMetrics) RecordIndexedLatestHeight(height *big.Int) { - m.indexedLatestHeight.Set(float64(height.Uint64())) +func (m *etlMetrics) RecordEtlLatestHeight(height *big.Int) { + m.etlLatestHeight.Set(float64(height.Uint64())) } func (m *etlMetrics) RecordIndexedHeaders(size int) { diff --git a/indexer/example.env b/indexer/example.env deleted file mode 100644 index 1dda0f1176a5..000000000000 --- a/indexer/example.env +++ /dev/null @@ -1,6 +0,0 @@ -# Fill me in with goerli uris and run docker-compose up to run indexer vs goerli -INDEXER_L1_ETH_RPC=FILL_ME_IN -INDEXER_L2_ETH_RPC=FILL_ME_IN - -# Fill in to use prisma studio ui with a db other than the default -# DATABASE_URL=FILL_ME_IN diff --git a/indexer/indexer.go b/indexer/indexer.go index 07f566650604..639871d018d1 100644 --- a/indexer/indexer.go +++ b/indexer/indexer.go @@ -2,12 +2,12 @@ package indexer import ( "context" + "errors" "fmt" "math/big" "net" - "runtime/debug" "strconv" - "sync" + "sync/atomic" "github.com/ethereum/go-ethereum/log" @@ -30,149 +30,235 @@ import ( // indexing the configured L1 and L2 chains type Indexer struct { log log.Logger - db *database.DB + DB *database.DB + + l1Client node.EthClient + l2Client node.EthClient - httpConfig config.ServerConfig - metricsConfig config.ServerConfig metricsRegistry *prometheus.Registry + apiServer *httputil.HTTPServer + metricsServer *httputil.HTTPServer + L1ETL *etl.L1ETL L2ETL *etl.L2ETL BridgeProcessor *processors.BridgeProcessor + + // shutdown requests the service that maintains the indexer to shut down, + // and provides the error-cause of the critical failure (if any). + shutdown context.CancelCauseFunc + + stopped atomic.Bool } // NewIndexer initializes an instance of the Indexer -func NewIndexer( - log log.Logger, - db *database.DB, - chainConfig config.ChainConfig, - rpcsConfig config.RPCsConfig, - httpConfig config.ServerConfig, - metricsConfig config.ServerConfig, -) (*Indexer, error) { - metricsRegistry := metrics.NewRegistry() - - // L1 - l1EthClient, err := node.DialEthClient(rpcsConfig.L1RPC, node.NewMetrics(metricsRegistry, "l1")) +func NewIndexer(ctx context.Context, log log.Logger, cfg *config.Config, shutdown context.CancelCauseFunc) (*Indexer, error) { + out := &Indexer{ + log: log, + metricsRegistry: metrics.NewRegistry(), + shutdown: shutdown, + } + if err := out.initFromConfig(ctx, cfg); err != nil { + return nil, errors.Join(err, out.Stop(ctx)) + } + return out, nil +} + +func (ix *Indexer) Start(ctx context.Context) error { + // If any of these services has a critical failure, + // the service can request a shutdown, while providing the error cause. + if err := ix.L1ETL.Start(); err != nil { + return fmt.Errorf("failed to start L1 ETL: %w", err) + } + if err := ix.L2ETL.Start(); err != nil { + return fmt.Errorf("failed to start L2 ETL: %w", err) + } + if err := ix.BridgeProcessor.Start(); err != nil { + return fmt.Errorf("failed to start bridge processor: %w", err) + } + return nil +} + +func (ix *Indexer) Stop(ctx context.Context) error { + if ix.stopped.Load() { + return nil + } + + var result error + + if ix.L1ETL != nil { + if err := ix.L1ETL.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close L1 ETL: %w", err)) + } + } + + if ix.L2ETL != nil { + if err := ix.L2ETL.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close L2 ETL: %w", err)) + } + } + + if ix.BridgeProcessor != nil { + if err := ix.BridgeProcessor.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close bridge processor: %w", err)) + } + } + + // Now that the ETLs are closed, we can stop the RPC clients + if ix.l1Client != nil { + ix.l1Client.Close() + } + if ix.l2Client != nil { + ix.l2Client.Close() + } + + if ix.apiServer != nil { + if err := ix.apiServer.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close indexer API server: %w", err)) + } + } + + // DB connection can be closed last, after all its potential users have shut down + if ix.DB != nil { + if err := ix.DB.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close DB: %w", err)) + } + } + + if ix.metricsServer != nil { + if err := ix.metricsServer.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close metrics server: %w", err)) + } + } + + ix.stopped.Store(true) + ix.log.Info("indexer stopped") + return result +} + +func (ix *Indexer) Stopped() bool { + return ix.stopped.Load() +} + +func (ix *Indexer) initFromConfig(ctx context.Context, cfg *config.Config) error { + if err := ix.initRPCClients(ctx, cfg.RPCs); err != nil { + return fmt.Errorf("failed to start RPC clients: %w", err) + } + if err := ix.initDB(ctx, cfg.DB); err != nil { + return fmt.Errorf("failed to init DB: %w", err) + } + if err := ix.initL1ETL(cfg.Chain); err != nil { + return fmt.Errorf("failed to init L1 ETL: %w", err) + } + if err := ix.initL2ETL(cfg.Chain); err != nil { + return fmt.Errorf("failed to init L2 ETL: %w", err) + } + if err := ix.initBridgeProcessor(cfg.Chain); err != nil { + return fmt.Errorf("failed to init Bridge-Processor: %w", err) + } + if err := ix.startHttpServer(ctx, cfg.HTTPServer); err != nil { + return fmt.Errorf("failed to start HTTP server: %w", err) + } + if err := ix.startMetricsServer(ctx, cfg.MetricsServer); err != nil { + return fmt.Errorf("failed to start Metrics server: %w", err) + } + return nil +} + +func (ix *Indexer) initRPCClients(ctx context.Context, rpcsConfig config.RPCsConfig) error { + l1EthClient, err := node.DialEthClient(ctx, rpcsConfig.L1RPC, node.NewMetrics(ix.metricsRegistry, "l1")) if err != nil { - return nil, err + return fmt.Errorf("failed to dial L1 client: %w", err) } + ix.l1Client = l1EthClient + + l2EthClient, err := node.DialEthClient(ctx, rpcsConfig.L2RPC, node.NewMetrics(ix.metricsRegistry, "l2")) + if err != nil { + return fmt.Errorf("failed to dial L2 client: %w", err) + } + ix.l2Client = l2EthClient + return nil +} + +func (ix *Indexer) initDB(ctx context.Context, cfg config.DBConfig) error { + db, err := database.NewDB(ctx, ix.log, cfg) + if err != nil { + return fmt.Errorf("failed to connect to database: %w", err) + } + ix.DB = db + return nil +} + +func (ix *Indexer) initL1ETL(chainConfig config.ChainConfig) error { l1Cfg := etl.Config{ LoopIntervalMsec: chainConfig.L1PollingInterval, HeaderBufferSize: chainConfig.L1HeaderBufferSize, ConfirmationDepth: big.NewInt(int64(chainConfig.L1ConfirmationDepth)), StartHeight: big.NewInt(int64(chainConfig.L1StartingHeight)), } - l1Etl, err := etl.NewL1ETL(l1Cfg, log, db, etl.NewMetrics(metricsRegistry, "l1"), l1EthClient, chainConfig.L1Contracts) + l1Etl, err := etl.NewL1ETL(l1Cfg, ix.log, ix.DB, etl.NewMetrics(ix.metricsRegistry, "l1"), + ix.l1Client, chainConfig.L1Contracts, ix.shutdown) if err != nil { - return nil, err + return err } + ix.L1ETL = l1Etl + return nil +} +func (ix *Indexer) initL2ETL(chainConfig config.ChainConfig) error { // L2 (defaults to predeploy contracts) - l2EthClient, err := node.DialEthClient(rpcsConfig.L2RPC, node.NewMetrics(metricsRegistry, "l2")) - if err != nil { - return nil, err - } l2Cfg := etl.Config{ LoopIntervalMsec: chainConfig.L2PollingInterval, HeaderBufferSize: chainConfig.L2HeaderBufferSize, ConfirmationDepth: big.NewInt(int64(chainConfig.L2ConfirmationDepth)), } - l2Etl, err := etl.NewL2ETL(l2Cfg, log, db, etl.NewMetrics(metricsRegistry, "l2"), l2EthClient, chainConfig.L2Contracts) + l2Etl, err := etl.NewL2ETL(l2Cfg, ix.log, ix.DB, etl.NewMetrics(ix.metricsRegistry, "l2"), + ix.l2Client, chainConfig.L2Contracts, ix.shutdown) if err != nil { - return nil, err + return err } + ix.L2ETL = l2Etl + return nil +} - // Bridge - bridgeProcessor, err := processors.NewBridgeProcessor(log, db, bridge.NewMetrics(metricsRegistry), l1Etl, chainConfig) +func (ix *Indexer) initBridgeProcessor(chainConfig config.ChainConfig) error { + bridgeProcessor, err := processors.NewBridgeProcessor( + ix.log, ix.DB, bridge.NewMetrics(ix.metricsRegistry), ix.L1ETL, ix.L2ETL, chainConfig, ix.shutdown) if err != nil { - return nil, err - } - - indexer := &Indexer{ - log: log, - db: db, - - httpConfig: httpConfig, - metricsConfig: metricsConfig, - metricsRegistry: metricsRegistry, - - L1ETL: l1Etl, - L2ETL: l2Etl, - BridgeProcessor: bridgeProcessor, + return err } - - return indexer, nil + ix.BridgeProcessor = bridgeProcessor + return nil } -func (i *Indexer) startHttpServer(ctx context.Context) error { - i.log.Debug("starting http server...", "port", i.httpConfig.Host) +func (ix *Indexer) startHttpServer(ctx context.Context, cfg config.ServerConfig) error { + ix.log.Debug("starting http server...", "port", cfg.Port) r := chi.NewRouter() + r.Use(middleware.Logger) r.Use(middleware.Heartbeat("/healthz")) - addr := net.JoinHostPort(i.httpConfig.Host, strconv.Itoa(i.httpConfig.Port)) + // needed so that the middlware gets invoked + r.Get("/", r.NotFoundHandler()) + + addr := net.JoinHostPort(cfg.Host, strconv.Itoa(cfg.Port)) srv, err := httputil.StartHTTPServer(addr, r) if err != nil { return fmt.Errorf("http server failed to start: %w", err) } - i.log.Info("http server started", "addr", srv.Addr()) - <-ctx.Done() - defer i.log.Info("http server stopped") - return srv.Stop(context.Background()) -} -func (i *Indexer) startMetricsServer(ctx context.Context) error { - i.log.Debug("starting metrics server...", "port", i.metricsConfig.Port) - srv, err := metrics.StartServer(i.metricsRegistry, i.metricsConfig.Host, i.metricsConfig.Port) - if err != nil { - return fmt.Errorf("metrics server failed to start: %w", err) - } - i.log.Info("metrics server started", "addr", srv.Addr()) - <-ctx.Done() - defer i.log.Info("metrics server stopped") - return srv.Stop(context.Background()) + ix.log.Info("http server started", "addr", srv.Addr()) + ix.apiServer = srv + return nil } -// Start starts the indexing service on L1 and L2 chains -func (i *Indexer) Run(ctx context.Context) error { - var wg sync.WaitGroup - errCh := make(chan error, 5) - - // if any goroutine halts, we stop the entire indexer - processCtx, processCancel := context.WithCancel(ctx) - runProcess := func(start func(ctx context.Context) error) { - wg.Add(1) - go func() { - defer func() { - if err := recover(); err != nil { - i.log.Error("halting indexer on panic", "err", err) - debug.PrintStack() - errCh <- fmt.Errorf("panic: %v", err) - } - - processCancel() - wg.Done() - }() - - errCh <- start(processCtx) - }() - } - - // Kick off all the dependent routines - runProcess(i.L1ETL.Start) - runProcess(i.L2ETL.Start) - runProcess(i.BridgeProcessor.Start) - runProcess(i.startMetricsServer) - runProcess(i.startHttpServer) - wg.Wait() - - err := <-errCh +func (ix *Indexer) startMetricsServer(ctx context.Context, cfg config.ServerConfig) error { + ix.log.Debug("starting metrics server...", "port", cfg.Port) + srv, err := metrics.StartServer(ix.metricsRegistry, cfg.Host, cfg.Port) if err != nil { - i.log.Error("indexer stopped", "err", err) - } else { - i.log.Info("indexer stopped") + return fmt.Errorf("metrics server failed to start: %w", err) } - - return err + ix.metricsServer = srv + ix.log.Info("metrics server started", "addr", srv.Addr()) + return nil } diff --git a/indexer/indexer.toml b/indexer/indexer.toml index b85c2008df27..572f350a3257 100644 --- a/indexer/indexer.toml +++ b/indexer/indexer.toml @@ -1,36 +1,60 @@ -# Chain configures l1 chain addresses -# Can configure them manually or use a preset L2 ChainId for known chains -# - i.e OP Mainnet, OP Goerli, Base, Base Goerli, Zora, Zora Goerli, etc [chain] -preset = $INDEXER_CHAIN_PRESET +## Required ETL configuration which controls +## the rate and and range at data retrieval +l1-polling-interval = 5000 # 5s +l2-polling-interval = 5000 -# L1 Config -l1-polling-interval = 0 -l1-header-buffer-size = 0 -l1-confirmation-depth = 0 -l1-starting-height = 0 +l1-header-buffer-size = 1000 +l2-header-buffer-size = 1000 -# L2 Config -l2-polling-interval = 0 -l2-header-buffer-size = 0 +l1-confirmation-depth = 0 # unnecessary for devnet l2-confirmation-depth = 0 +### Option 1: Utilize a known preset for chain configuration +### See config/presets.go for available presets. +### i.e OP, Base, Zora, PGN, etc. +preset = 901 # Local Devnet + +### Option 2: Custom Networks +### +### Deployment block height of the rollup. Must be set +### correctly otherwise the ETL will start from L1 +### genesis resulting in a lot of wasted work. Confirmation +### depths should be set appropriately to avoid a the ETL +### getting stuck terminally due to a reorg +# l1-starting-height = 0 +# +# l1-confirmation-depth = 10 +# l2-confirmation-depth = 75 (roughly 10 L1 block equivalent) +# +### These contract addresses MUST be the Proxy contract +### addresses and not the implementation +# [chain.l1-contracts] +# address-manager = "" +# system-config = "" +# optimism-portal = "" +# l2-output-oracle = "" +# l1-cross-domain-messenger = "" +# l1-standard-brigde = "" +# l1-erc721-bridge = "" +### + [rpcs] -l1-rpc = "${INDEXER_RPC_URL_L1}" -l2-rpc = "${INDEXER_RPC_URL_L2}" +l1-rpc = "${INDEXER_L1_RPC_URL}" +l2-rpc = "${INDEXER_L2_RPC_URL}" [db] -host = "$INDEXER_DB_HOST" -port = $INDEXER_DB_PORT -user = "$INDEXER_DB_USER" -password = "$INDEXER_DB_PASS" -name = "$INDEXER_DB_NAME" +host = "${DB_HOST}" +port = ${DB_PORT} +user = "${DB_USER}" +password = "${DB_PWD}" +name = "${DB_NAME}" [http] -host = "127.0.0.1" -port = 8080 +host = "0.0.0.0" +port = 8100 +timeout = 10 [metrics] -host = "127.0.0.1" +host = "0.0.0.0" port = 7300 - diff --git a/indexer/migrations/20230523_create_schema.sql b/indexer/migrations/20230523_create_schema.sql index 19f22dc38c43..7176c055bc3f 100644 --- a/indexer/migrations/20230523_create_schema.sql +++ b/indexer/migrations/20230523_create_schema.sql @@ -1,4 +1,3 @@ - DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint256') THEN @@ -57,13 +56,14 @@ CREATE TABLE IF NOT EXISTS l1_contract_events ( timestamp INTEGER NOT NULL CHECK (timestamp > 0), -- Raw Data - rlp_bytes VARCHAR NOT NULL + rlp_bytes VARCHAR NOT NULL, + + UNIQUE(block_hash, log_index) ); CREATE INDEX IF NOT EXISTS l1_contract_events_timestamp ON l1_contract_events(timestamp); CREATE INDEX IF NOT EXISTS l1_contract_events_block_hash ON l1_contract_events(block_hash); CREATE INDEX IF NOT EXISTS l1_contract_events_event_signature ON l1_contract_events(event_signature); CREATE INDEX IF NOT EXISTS l1_contract_events_contract_address ON l1_contract_events(contract_address); -ALTER TABLE l1_contract_events ADD UNIQUE (block_hash, log_index); CREATE TABLE IF NOT EXISTS l2_contract_events ( -- Searchable fields @@ -76,13 +76,14 @@ CREATE TABLE IF NOT EXISTS l2_contract_events ( timestamp INTEGER NOT NULL CHECK (timestamp > 0), -- Raw Data - rlp_bytes VARCHAR NOT NULL + rlp_bytes VARCHAR NOT NULL, + + UNIQUE(block_hash, log_index) ); CREATE INDEX IF NOT EXISTS l2_contract_events_timestamp ON l2_contract_events(timestamp); CREATE INDEX IF NOT EXISTS l2_contract_events_block_hash ON l2_contract_events(block_hash); CREATE INDEX IF NOT EXISTS l2_contract_events_event_signature ON l2_contract_events(event_signature); CREATE INDEX IF NOT EXISTS l2_contract_events_contract_address ON l2_contract_events(contract_address); -ALTER TABLE l2_contract_events ADD UNIQUE (block_hash, log_index); /** * BRIDGING DATA @@ -96,8 +97,8 @@ CREATE TABLE IF NOT EXISTS l1_transaction_deposits ( -- transaction data. NOTE: `to_address` is the recipient of funds transferred in value field of the -- L2 deposit transaction and not the amount minted on L1 from the source address. Hence the `amount` - -- column in this table does NOT indiciate the amount transferred to the recipient but instead funds - -- bridged from L1 into `from_address`. + -- column in this table does NOT indicate the amount transferred to the recipient but instead funds + -- bridged from L1 by the `from_address`. from_address VARCHAR NOT NULL, to_address VARCHAR NOT NULL, @@ -118,9 +119,12 @@ CREATE TABLE IF NOT EXISTS l2_transaction_withdrawals ( nonce UINT256 NOT NULL UNIQUE, initiated_l2_event_guid VARCHAR NOT NULL UNIQUE REFERENCES l2_contract_events(guid) ON DELETE CASCADE, - -- Multistep (bedrock) process of a withdrawal - proven_l1_event_guid VARCHAR UNIQUE REFERENCES l1_contract_events(guid) ON DELETE CASCADE, - finalized_l1_event_guid VARCHAR UNIQUE REFERENCES l1_contract_events(guid) ON DELETE CASCADE, + -- Multistep (bedrock) process of a withdrawal. With permissionless-output proposals, `proven_l1_event_guid` + -- should be treated as the last known proven event. It may be the case (rare) that the proven state of this + -- withdrawal was invalidated via a fault proof. This case is considered "rare" a malicious outputs are + -- disincentivezed via the posted bond. + proven_l1_event_guid VARCHAR UNIQUE REFERENCES l1_contract_events(guid) ON DELETE SET NULL ON UPDATE CASCADE, + finalized_l1_event_guid VARCHAR UNIQUE REFERENCES l1_contract_events(guid) ON DELETE SET NULL ON UPDATE CASCADE, succeeded BOOLEAN, -- transaction data @@ -133,6 +137,8 @@ CREATE TABLE IF NOT EXISTS l2_transaction_withdrawals ( ); CREATE INDEX IF NOT EXISTS l2_transaction_withdrawals_timestamp ON l2_transaction_withdrawals(timestamp); CREATE INDEX IF NOT EXISTS l2_transaction_withdrawals_initiated_l2_event_guid ON l2_transaction_withdrawals(initiated_l2_event_guid); +CREATE INDEX IF NOT EXISTS l2_transaction_withdrawals_proven_l1_event_guid ON l2_transaction_withdrawals(proven_l1_event_guid); +CREATE INDEX IF NOT EXISTS l2_transaction_withdrawals_finalized_l1_event_guid ON l2_transaction_withdrawals(finalized_l1_event_guid); CREATE INDEX IF NOT EXISTS l2_transaction_withdrawals_from_address ON l2_transaction_withdrawals(from_address); -- CrossDomainMessenger @@ -142,7 +148,7 @@ CREATE TABLE IF NOT EXISTS l1_bridge_messages( transaction_source_hash VARCHAR NOT NULL UNIQUE REFERENCES l1_transaction_deposits(source_hash) ON DELETE CASCADE, sent_message_event_guid VARCHAR NOT NULL UNIQUE REFERENCES l1_contract_events(guid) ON DELETE CASCADE, - relayed_message_event_guid VARCHAR UNIQUE REFERENCES l2_contract_events(guid) ON DELETE CASCADE, + relayed_message_event_guid VARCHAR UNIQUE REFERENCES l2_contract_events(guid) ON DELETE SET NULL ON UPDATE CASCADE, -- sent message from_address VARCHAR NOT NULL, @@ -154,6 +160,8 @@ CREATE TABLE IF NOT EXISTS l1_bridge_messages( ); CREATE INDEX IF NOT EXISTS l1_bridge_messages_timestamp ON l1_bridge_messages(timestamp); CREATE INDEX IF NOT EXISTS l1_bridge_messages_transaction_source_hash ON l1_bridge_messages(transaction_source_hash); +CREATE INDEX IF NOT EXISTS l1_bridge_messages_transaction_sent_message_event_guid ON l1_bridge_messages(sent_message_event_guid); +CREATE INDEX IF NOT EXISTS l1_bridge_messages_transaction_relayed_message_event_guid ON l1_bridge_messages(relayed_message_event_guid); CREATE INDEX IF NOT EXISTS l1_bridge_messages_from_address ON l1_bridge_messages(from_address); CREATE TABLE IF NOT EXISTS l2_bridge_messages( @@ -162,7 +170,7 @@ CREATE TABLE IF NOT EXISTS l2_bridge_messages( transaction_withdrawal_hash VARCHAR NOT NULL UNIQUE REFERENCES l2_transaction_withdrawals(withdrawal_hash) ON DELETE CASCADE, sent_message_event_guid VARCHAR NOT NULL UNIQUE REFERENCES l2_contract_events(guid) ON DELETE CASCADE, - relayed_message_event_guid VARCHAR UNIQUE REFERENCES l1_contract_events(guid) ON DELETE CASCADE, + relayed_message_event_guid VARCHAR UNIQUE REFERENCES l1_contract_events(guid) ON DELETE SET NULL ON UPDATE CASCADE, -- sent message from_address VARCHAR NOT NULL, @@ -174,8 +182,26 @@ CREATE TABLE IF NOT EXISTS l2_bridge_messages( ); CREATE INDEX IF NOT EXISTS l2_bridge_messages_timestamp ON l2_bridge_messages(timestamp); CREATE INDEX IF NOT EXISTS l2_bridge_messages_transaction_withdrawal_hash ON l2_bridge_messages(transaction_withdrawal_hash); +CREATE INDEX IF NOT EXISTS l2_bridge_messages_transaction_sent_message_event_guid ON l2_bridge_messages(sent_message_event_guid); +CREATE INDEX IF NOT EXISTS l2_bridge_messages_transaction_relayed_message_event_guid ON l2_bridge_messages(relayed_message_event_guid); CREATE INDEX IF NOT EXISTS l2_bridge_messages_from_address ON l2_bridge_messages(from_address); +/** + * Since the CDM uses the latest versioned message hash when emitting the `RelayedMessage` event, we need + * to keep track of all of the future versions of message hashes such that legacy messages can be queried + * queried for when relayed on L1 + * + * As new the CDM is updated with new versions, we need to ensure that there's a better way to correlate message between + * chains (adding the message nonce to the RelayedMessage event) or continue to add columns to this table and migrate + * unrelayed messages such that finalization logic can handle switching between the varying versioned message hashes + */ +CREATE TABLE IF NOT EXISTS l2_bridge_message_versioned_message_hashes( + message_hash VARCHAR PRIMARY KEY NOT NULL UNIQUE REFERENCES l2_bridge_messages(message_hash), + + -- only filled in if `message_hash` is for a v0 message + v1_message_hash VARCHAR UNIQUE +); + -- StandardBridge CREATE TABLE IF NOT EXISTS l1_bridge_deposits ( transaction_source_hash VARCHAR PRIMARY KEY REFERENCES l1_transaction_deposits(source_hash) ON DELETE CASCADE, diff --git a/indexer/node/client.go b/indexer/node/client.go index be046f930b48..1ad6f0a21e0a 100644 --- a/indexer/node/client.go +++ b/indexer/node/client.go @@ -40,23 +40,27 @@ type EthClient interface { StorageHash(common.Address, *big.Int) (common.Hash, error) FilterLogs(ethereum.FilterQuery) (Logs, error) + + // Close closes the underlying RPC connection. + // RPC close does not return any errors, but does shut down e.g. a websocket connection. + Close() } type clnt struct { rpc RPC } -func DialEthClient(rpcUrl string, metrics Metricer) (EthClient, error) { - ctxwt, cancel := context.WithTimeout(context.Background(), defaultDialTimeout) +func DialEthClient(ctx context.Context, rpcUrl string, metrics Metricer) (EthClient, error) { + ctx, cancel := context.WithTimeout(ctx, defaultDialTimeout) defer cancel() bOff := retry.Exponential() - rpcClient, err := retry.Do(ctxwt, defaultDialAttempts, bOff, func() (*rpc.Client, error) { + rpcClient, err := retry.Do(ctx, defaultDialAttempts, bOff, func() (*rpc.Client, error) { if !client.IsURLAvailable(rpcUrl) { return nil, fmt.Errorf("address unavailable (%s)", rpcUrl) } - client, err := rpc.DialContext(ctxwt, rpcUrl) + client, err := rpc.DialContext(ctx, rpcUrl) if err != nil { return nil, fmt.Errorf("failed to dial address (%s): %w", rpcUrl, err) } @@ -192,6 +196,10 @@ func (c *clnt) StorageHash(address common.Address, blockNumber *big.Int) (common return proof.StorageHash, nil } +func (c *clnt) Close() { + c.rpc.Close() +} + type Logs struct { Logs []types.Log ToBlockHeader *types.Header diff --git a/indexer/node/client_test.go b/indexer/node/client_test.go index 39e7eb2974a7..78cf5b5b82a5 100644 --- a/indexer/node/client_test.go +++ b/indexer/node/client_test.go @@ -1,6 +1,7 @@ package node import ( + "context" "fmt" "net" "strings" @@ -21,14 +22,14 @@ func TestDialEthClientUnavailable(t *testing.T) { metrics := &clientMetrics{} // available - _, err = DialEthClient(addr, metrics) + _, err = DialEthClient(context.Background(), addr, metrics) require.NoError(t, err) // :0 requests a new unbound port - _, err = DialEthClient("http://localhost:0", metrics) + _, err = DialEthClient(context.Background(), "http://localhost:0", metrics) require.Error(t, err) // Fail open if we don't recognize the scheme - _, err = DialEthClient("mailto://example.com", metrics) + _, err = DialEthClient(context.Background(), "mailto://example.com", metrics) require.Error(t, err) } diff --git a/indexer/node/mocks.go b/indexer/node/mocks.go index b18196307ee1..e01c6fcb1bca 100644 --- a/indexer/node/mocks.go +++ b/indexer/node/mocks.go @@ -45,3 +45,6 @@ func (m *MockEthClient) FilterLogs(query ethereum.FilterQuery) (Logs, error) { args := m.Called(query) return args.Get(0).(Logs), args.Error(1) } + +func (m *MockEthClient) Close() { +} diff --git a/indexer/assets/architecture.png b/indexer/ops/assets/architecture.png similarity index 100% rename from indexer/assets/architecture.png rename to indexer/ops/assets/architecture.png diff --git a/indexer/assets/indexer-service.png b/indexer/ops/assets/indexer-service.png similarity index 100% rename from indexer/assets/indexer-service.png rename to indexer/ops/assets/indexer-service.png diff --git a/indexer/ops/docs/troubleshooting.md b/indexer/ops/docs/troubleshooting.md new file mode 100644 index 000000000000..3147b57e3145 --- /dev/null +++ b/indexer/ops/docs/troubleshooting.md @@ -0,0 +1,82 @@ +# Troubleshooting Runbook +This document provides a set of troubleshooting steps for common failure scenarios and how to resolve them. + +## Indexer Troubleshooting + +### Postgres failures +1. Unable to connect to postgres database: + * Verify that the database is healthy and accessible. + * Verify that the database credentials are correct. + * Verify that the database is not rate limiting connections. + +2. Unable to insert or read rows: + * Verify that the database is healthy and accessible. + * Verify that the database credentials are correct. + * Verify that most recent`./migrations` schemas have been applied to the database. + +### Header Traversal Failure +Header traversal is a client abstraction that allows the indexer to sequentially traverse the chain via batches of blocks. The following are some common failure modes and how to resolve them: +1. `the HeaderTraversal and provider have diverged in state` +This error occurs when the indexer is operating on a different block state than the node. This is typically caused by network reorgs and is the result of `l1-confirmation-depth` or `l2-confirmation-depth` values being set too low. To resolve this issue, + * Delete blocks in the database back to a last known valid L1 height. See the `reorg-delete` command available in the cli that'll appropriately conduct the deletions. + * Increase confirmation depth values + * Restart the indexer + +2. `the HeaderTraversal's internal state is ahead of the provider` +This error occurs when the indexer is operating on a block that the upstream provider does not have. This typically occurs when resyncing upstream node services. This issue typically resolves itself once the upstream node service is fully synced. If the problem persists, please file an issue. + +### L1/L2 Processor Failures +The L1 and L2 processors are responsible for processing new blocks and system txs. Processor failures can spread and contaminate other downstream processors (i.e, bridge) as well. For example, if a L2 processor misses a block and fails to index a `MessagePassed` event, the bridge processor will fail to index the corresponding `WithdrawalProven` event and halt progress. The following are some common failure modes and how to resolve them: + +1. A processor stops syncing arbitrarily due to a network/connectivity issue or syncing too slow. + * Verify that `header-buffer-size` and `polling-interval` config values are sufficiently set in accordance with upstream node rate limits. If misconfigured, the indexer may be rate limited by the upstream node and fail to sync. + * Verify that the upstream dependency is healthy and accessible. + +2. A processor failed to index a block or system tx. This should never happen as resiliency is built into the processor interaction logic, but if it does, the following investigations should be made: + * Verify that `preset` is set to proper L2 chain ID or manually specified contract addresses are correct. If misconfigured, the indexer may be trying to index the wrong system contract addresses. There should be a log at startup that indicates the preset and system contract addresses being used. + * Verify that the upstream node dependency is healthy and accessible. + * Verify data tables to ensure that the block or system tx was indexed. If it wasn't indexed, please file an issue and resync the indexer (see below). + +### Bridge Processor Failures +The bridge processor is responsible for indexing bridge tx and events (i.e, withdrawals, deposits). The bridge processor actively subscribes to new information and scans for newly indexed initialized and finalized bridge events. + +1. A finalized bridge event has no corresponding initiation (e.g, a detected finalized withdrawal has no corresponding proven event persisted in DB). The bridge process will halt indexing until the event is resolved. + * Verify that the indexer is incorrect by checking the L1/L2 block explorers for the corresponding withdrawal hash. The hash should be present on the `OptimismPortal` contract (`provenWithdrawals()`, `finalizedWithdrawals()`) as well as the L2 `L2ToL1MessagePasser` contract (`sentMessages()`). Foundry's `cast logs` [command](https://book.getfoundry.sh/reference/cast/cast-logs) provides a way to quickly do these lookups. If the hash is not present, the withdrawal was not initiated and the bridge processor is correct to halt indexing + > TODO: script that scans for correlated events on L2 using withdrawal hash). If the hash is present, the bridge processor is incorrect and should be investigated further. Please file an issue with the details of the investigation. + +2. Bridge processor halting due to upstream L1/L2 processor failures. See above for troubleshooting steps for L1/L2 processor failures. + * Verify that the bridge processor is not halted due to upstream processor failures. If it is, remediate the upstream processor failures and restart the application. The bridge processor will be able to resume indexing from the last persisted heights. + +### Re-syncing +To resync a deployed indexer, the following steps should be taken: +1. Stop the running indexer service instance (especially if using blue/green deployment strategy). Deleting state while the application is running can cause data corruption since application startups begin operation at the most recent indexed state. +2. Delete the database state. This can be done by doing a cascading delete of both the l1/l2 `blocks` table. This will delete all blocks and associated data (i.e, system events, bridge txs). Since there's referential integrity between the blocks tables and all other table schema, the following commands will delete all data in the database: +```sql +TRUNCATE l1_block_headers CASCADE; +TRUNCATE l2_block_headers CASCADE; +``` +> The indexer syncs L1 & L2 state independently and can thus also be resynced individually as well. +3. Restart the indexer service. The indexer should detect that the database is empty and begin syncing from genesis (i.e, `l2_start_height = 0`, `l1_start_height = l1-starting-height`). This can be verified by checking the logs for the following message: +``` +no indexed state, starting from genesis +``` + +#### Re-syncing just the bridge processor +To resync the bridge processor without re-retrieving L1/L2 contract data, the following steps should be taken: +1. Stop the running indexer service instance. +2. Delete the bridge processor's database state. This can be done by doing performing cascading delete the root bridge tables -- `l1_transaction_deposits` and `l2_transaction_withdrawals`: +```sql +TRUNCATE l1_transaction_deposits CASCADE; +TRUNCATE l2_transaction_withdrawals CASCADE; +``` +> Similar to blocks & logs, deposits & withdrawals are synced independently and can thus be resynced individually as well. The bridge process is smart enough to pause finalization processing until the other side is caught up. For this reason, it's possible to just re-sync deposits or withdrawals. +3. Restart the indexer service. + +## API Troubleshooting + +### API is returning response errors +The API is a read-only service that does not modify the database. If the API is returning errors, it is likely due to the following reasons: + * Verify that the API is able to connect to the database. If the database is down, the API will return errors. + * Verify that http `timeout` env variable is set to a reasonable value. If the timeout is too low, the API may be timing out on requests and returning errors. + * Verify that rate limiting isn't enabled in request routing layer. If rate limiting is enabled, the API may be rate limited and returning errors. + * Verify that service isn't being overloaded by too many requests. If the service is overloaded, the API may be returning errors. diff --git a/indexer/ops/grafana/dashboards/indexer.json b/indexer/ops/grafana/dashboards/indexer.json new file mode 100644 index 000000000000..16a25e4ea93b --- /dev/null +++ b/indexer/ops/grafana/dashboards/indexer.json @@ -0,0 +1,2384 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 164, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 7, + "panels": [], + "title": "ETL Processor (Blocks & Logs)", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 1 + }, + "id": 3, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_etl_l1_indexed_height", + "instant": false, + "legendFormat": "ETL", + "range": true, + "refId": "A" + } + ], + "title": "Indexed L1 Height", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "fieldMinMax": false, + "mappings": [], + "min": 0, + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 4, + "y": 1 + }, + "id": 25, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_etl_l1_latest_height", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Reported L1 Height", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 7, + "y": 1 + }, + "id": 23, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_etl_l1_indexed_height\n / op_indexer_etl_l1_latest_height\n", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "L1 Sync %", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 14, + "x": 10, + "y": 1 + }, + "id": 20, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_etl_l1_interval_seconds_sum[$etl_rate_interval])\n/\nrate(op_indexer_etl_l1_interval_seconds_count[$etl_rate_interval])", + "instant": false, + "legendFormat": "l1", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_etl_l2_interval_seconds_sum[$etl_rate_interval])\n/\nrate(op_indexer_etl_l2_interval_seconds_count[$etl_rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "l2", + "range": true, + "refId": "B" + } + ], + "title": "AVG ETL Latency", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 5 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "disableTextWrap": false, + "editorMode": "code", + "exemplar": true, + "expr": "op_indexer_etl_l2_indexed_height", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Indexed L2 Height", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "min": 0, + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 4, + "y": 5 + }, + "id": 26, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_etl_l2_latest_height", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Reported L2 Height", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 7, + "y": 5 + }, + "id": 24, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_etl_l2_indexed_height\n / op_indexer_etl_l2_latest_height", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "L2 Sync %", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 17, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "sum by(contract) (rate(op_indexer_etl_l1_indexed_logs_total[$etl_rate_interval])) * 60", + "instant": false, + "legendFormat": "{{contract}}", + "range": true, + "refId": "A" + } + ], + "title": "Indexed L1 Logs / m", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 18, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "sum by(contract) (rate(op_indexer_etl_l2_indexed_logs_total[$etl_rate_interval])) * 60", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Indexed L2 Logs / m", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 8, + "panels": [], + "title": "Bridge Processor", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 17 + }, + "id": 5, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_bridge_height{chain=\"l1\", kind=\"initiated\"}", + "instant": false, + "legendFormat": "initiated", + "range": true, + "refId": "A" + } + ], + "title": "Initiated Bridge L1 Height", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 17 + }, + "id": 29, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_bridge_height{chain=\"l1\", kind=\"initiated\"} / on() op_indexer_etl_l1_indexed_height", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Initiated L1 Sync %", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 6, + "y": 17 + }, + "id": 27, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_bridge_height{chain=\"l1\", kind=\"finalized\"}", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Finalized L1 Bridge Height", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 17 + }, + "id": 32, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_bridge_height{chain=\"l1\", kind=\"finalized\"} / on() op_indexer_etl_l1_indexed_height", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Finalized L1 Sync %", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 17 + }, + "id": 22, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "max by(chain) \n(rate(op_indexer_bridge_interval_seconds_sum[$etl_rate_interval])\n/\nrate(op_indexer_bridge_interval_seconds_count[$etl_rate_interval]))", + "instant": false, + "legendFormat": "{{chain}}", + "range": true, + "refId": "A" + } + ], + "title": "AVG Bridge Processing Latency", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 21 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_bridge_height{chain=\"l2\", kind=\"initiated\"}", + "instant": false, + "legendFormat": "initiated", + "range": true, + "refId": "A" + } + ], + "title": "Initiated Bridge L2 Height", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 21 + }, + "id": 30, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_bridge_height{chain=\"l2\", kind=\"initiated\"} / on() op_indexer_etl_l2_indexed_height", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Initiated L2 Sync %", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 6, + "y": 21 + }, + "id": 28, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_bridge_height{chain=\"l2\", kind=\"finalized\"}", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Finalized Bridge L2 Height", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 21 + }, + "id": 31, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "10.3.0-63588", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "op_indexer_bridge_height{chain=\"l2\", kind=\"finalized\"} / on() op_indexer_etl_l2_indexed_height", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Finalized L2 Sync %", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 25 + }, + "id": 9, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(op_indexer_bridge_tx_deposits[$etl_rate_interval]) * 60", + "instant": false, + "legendFormat": "L1 Transaction Deposits", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(op_indexer_bridge_sent_messages{chain=\"l1\"}[$etl_rate_interval]) * 60", + "hide": false, + "instant": false, + "legendFormat": "L1 Sent Messages", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_relayed_messages{chain=\"l1\"}[$etl_rate_interval]) * 60", + "hide": false, + "instant": false, + "legendFormat": "L1 Relayed Messages", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_initiated_token_transfers{chain=\"l1\"}[$etl_rate_interval]) * 60", + "hide": false, + "instant": false, + "legendFormat": "L1 Initiated Bridge Transfers", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_finalized_token_transfers{chain=\"l1\"}[$etl_rate_interval]) * 60", + "hide": false, + "instant": false, + "legendFormat": "L1 Finalized Bridge Transfers", + "range": true, + "refId": "E" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_skipped_ovm1_withdrawals{chain=\"l1\"}[$etl_rate_interval]) * 60 ", + "hide": false, + "instant": false, + "legendFormat": "Skipped OVM1 Withdrawals", + "range": true, + "refId": "F" + } + ], + "title": "L1 Bridge Transactions / m", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 25 + }, + "id": 11, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_tx_minted_eth[$etl_rate_interval]) * 60", + "instant": false, + "legendFormat": "Minted ETH", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_tx_withdrawn_eth[$etl_rate_interval]) * 60", + "hide": false, + "instant": false, + "legendFormat": "Withdrawn ETH", + "range": true, + "refId": "B" + } + ], + "title": "Transferred ETH / m", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 32 + }, + "id": 10, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_tx_withdrawals[$etl_rate_interval]) * 60", + "instant": false, + "legendFormat": "L2 Transaction Withdrawals", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_sent_messages{chain=\"l2\"}[$etl_rate_interval]) * 60", + "hide": false, + "instant": false, + "legendFormat": "L2 Sent Messages", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_relayed_messages{chain=\"l2\"}[$etl_rate_interval]) * 60", + "hide": false, + "instant": false, + "legendFormat": "L2 Relayed Messages", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_initiated_token_transfers{chain=\"l2\"}[$etl_rate_interval]) * 60", + "hide": false, + "instant": false, + "legendFormat": "L2 Initiated Bridge Transfers", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "rate(op_indexer_bridge_finalized_token_transfers{chain=\"l2\"}[$etl_rate_interval]) * 60", + "hide": false, + "instant": false, + "legendFormat": "L2 Finalized Bridge Transfers", + "range": true, + "refId": "E" + } + ], + "title": "L2 Bridge Transactions / m", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 32 + }, + "id": 12, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum by(token_address) (rate(op_indexer_bridge_initiated_token_transfers{token_address!=\"0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000\"}[$etl_rate_interval])) * 60", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{token_address}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Transferred ERC20 / m", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 39 + }, + "id": 13, + "panels": [], + "title": "RPC", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqpm" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 40 + }, + "id": 14, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "sum by(method) (rate(op_indexer_rpc_l1_requests_total[$etl_rate_interval])) * 60", + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "sum by(method,error) (rate(op_indexer_rpc_l1_responses_total{error!=\"\"}[$etl_rate_interval])) * 60", + "hide": false, + "instant": false, + "legendFormat": "{{method}} (error: {{error}})", + "range": true, + "refId": "B" + } + ], + "title": "L1 RPC / m", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 40 + }, + "id": 16, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.3.0-62488", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "sum by(method) (rate(op_indexer_rpc_l1_request_duration_seconds_sum[$etl_rate_interval])\n/\nrate(op_indexer_rpc_l1_request_duration_seconds_count[$etl_rate_interval]))", + "hide": false, + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "A" + } + ], + "title": "AVG L1 RPC Latency", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqpm" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 47 + }, + "id": 15, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "sum by(method) (rate(op_indexer_rpc_l2_requests_total[$etl_rate_interval])) * 60", + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "sum by(method, error) (rate(op_indexer_rpc_l2_responses_total{error!=\"\"}[$etl_rate_interval])) * 60", + "hide": true, + "instant": false, + "legendFormat": "{{method}} (error: {{error}})", + "range": true, + "refId": "B" + } + ], + "title": "L2 RPC / m", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 2, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 47 + }, + "id": 19, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "6R74VAnVz" + }, + "editorMode": "code", + "expr": "sum by(method) (rate(op_indexer_rpc_l2_request_duration_seconds_sum[$etl_rate_interval])\n/\nrate(op_indexer_rpc_l2_request_duration_seconds_count[$etl_rate_interval]))", + "instant": false, + "legendFormat": "{{method}}", + "range": true, + "refId": "A" + } + ], + "title": "AVG L2 RPC Latency", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [ + { + "description": "The window used for `rate`, based on the ETL loop interval", + "hide": 2, + "name": "etl_rate_interval", + "query": "2m", + "skipUrlSync": false, + "type": "constant" + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Indexer", + "uid": "a3cdb010-d44b-4556-a61e-46d655f57bc4", + "version": 30, + "weekStart": "" +} diff --git a/indexer/ops/grafana/provisioning/dashboards/all.yml b/indexer/ops/grafana/provisioning/dashboards/all.yml new file mode 100644 index 000000000000..3ce6e7c5bc69 --- /dev/null +++ b/indexer/ops/grafana/provisioning/dashboards/all.yml @@ -0,0 +1,9 @@ +apiVersion: 1 +providers: +- name: 'default' + orgId: 1 + folder: '' + type: file + disableDeletion: false + options: + path: /var/lib/grafana/dashboards diff --git a/indexer/ops/grafana/provisioning/datasources/datasources.yml b/indexer/ops/grafana/provisioning/datasources/datasources.yml new file mode 100644 index 000000000000..d4e61af386f3 --- /dev/null +++ b/indexer/ops/grafana/provisioning/datasources/datasources.yml @@ -0,0 +1,9 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + uid: '6R74VAnVz' + access: proxy + url: http://prometheus:9090 + isDefault: true diff --git a/indexer/ops/prometheus/prometheus.yml b/indexer/ops/prometheus/prometheus.yml new file mode 100644 index 000000000000..3f8bdaad0b24 --- /dev/null +++ b/indexer/ops/prometheus/prometheus.yml @@ -0,0 +1,8 @@ +global: + scrape_interval: 5s + evaluation_interval: 5s + +scrape_configs: + - job_name: 'indexer' + static_configs: + - targets: ['index:7300'] diff --git a/indexer/processors/bridge.go b/indexer/processors/bridge.go index aed182a70bbb..d576f6b6265f 100644 --- a/indexer/processors/bridge.go +++ b/indexer/processors/bridge.go @@ -3,31 +3,46 @@ package processors import ( "context" "errors" + "fmt" "math/big" + "gorm.io/gorm" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/indexer/bigint" "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/etl" "github.com/ethereum-optimism/optimism/indexer/processors/bridge" - - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/tasks" ) +var blocksLimit = 500 + type BridgeProcessor struct { log log.Logger db *database.DB metrics bridge.Metricer + resourceCtx context.Context + resourceCancel context.CancelFunc + tasks tasks.Group + l1Etl *etl.L1ETL + l2Etl *etl.L2ETL chainConfig config.ChainConfig - LatestL1Header *types.Header - LatestL2Header *types.Header + LastL1Header *database.L1BlockHeader + LastL2Header *database.L2BlockHeader + + LastFinalizedL1Header *database.L1BlockHeader + LastFinalizedL2Header *database.L2BlockHeader } -func NewBridgeProcessor(log log.Logger, db *database.DB, metrics bridge.Metricer, l1Etl *etl.L1ETL, chainConfig config.ChainConfig) (*BridgeProcessor, error) { +func NewBridgeProcessor(log log.Logger, db *database.DB, metrics bridge.Metricer, l1Etl *etl.L1ETL, l2Etl *etl.L2ETL, + chainConfig config.ChainConfig, shutdown context.CancelCauseFunc) (*BridgeProcessor, error) { log = log.New("processor", "bridge") latestL1Header, err := db.BridgeTransactions.L1LatestBlockHeader() @@ -39,201 +54,366 @@ func NewBridgeProcessor(log log.Logger, db *database.DB, metrics bridge.Metricer return nil, err } - var l1Header, l2Header *types.Header - if latestL1Header == nil && latestL2Header == nil { - log.Info("no indexed state, starting from rollup genesis") - } else { - l1Height, l2Height := bigint.Zero, bigint.Zero - if latestL1Header != nil { - l1Height = latestL1Header.Number - l1Header = latestL1Header.RLPHeader.Header() - metrics.RecordLatestIndexedL1Height(l1Height) + latestFinalizedL1Header, err := db.BridgeTransactions.L1LatestFinalizedBlockHeader() + if err != nil { + return nil, err + } + latestFinalizedL2Header, err := db.BridgeTransactions.L2LatestFinalizedBlockHeader() + if err != nil { + return nil, err + } + + log.Info("detected indexed bridge state", + "l1_block", latestL1Header, "l2_block", latestL2Header, + "finalized_l1_block", latestFinalizedL1Header, "finalized_l2_block", latestFinalizedL2Header) + + resCtx, resCancel := context.WithCancel(context.Background()) + return &BridgeProcessor{ + log: log, + db: db, + metrics: metrics, + l1Etl: l1Etl, + l2Etl: l2Etl, + resourceCtx: resCtx, + resourceCancel: resCancel, + chainConfig: chainConfig, + LastL1Header: latestL1Header, + LastL2Header: latestL2Header, + LastFinalizedL1Header: latestFinalizedL1Header, + LastFinalizedL2Header: latestFinalizedL2Header, + tasks: tasks.Group{HandleCrit: func(err error) { + shutdown(fmt.Errorf("critical error in bridge processor: %w", err)) + }}, + }, nil +} + +func (b *BridgeProcessor) Start() error { + b.log.Info("starting bridge processor...") + // start L1 worker + b.tasks.Go(func() error { + l1EtlUpdates := b.l1Etl.Notify() + for range l1EtlUpdates { + b.log.Info("notified of traversed L1 state", "l1_etl_block_number", b.l1Etl.LatestHeader.Number) + if err := b.onL1Data(b.l1Etl.LatestHeader); err != nil { + b.log.Error("failed l1 bridge processing interval", "err", err) + } } - if latestL2Header != nil { - l2Height = latestL2Header.Number - l2Header = latestL2Header.RLPHeader.Header() - metrics.RecordLatestIndexedL2Height(l2Height) + b.log.Info("no more l1 etl updates. shutting down l1 task") + return nil + }) + // start L2 worker + b.tasks.Go(func() error { + l2EtlUpdates := b.l2Etl.Notify() + for range l2EtlUpdates { + b.log.Info("notified of traversed L2 state", "l2_etl_block_number", b.l2Etl.LatestHeader.Number) + if err := b.onL2Data(b.l2Etl.LatestHeader); err != nil { + b.log.Error("failed l2 bridge processing interval", "err", err) + } } - log.Info("detected latest indexed bridge state", "l1_block_number", l1Height, "l2_block_number", l2Height) - } + b.log.Info("no more l2 etl updates. shutting down l2 task") + return nil + }) + return nil +} - return &BridgeProcessor{log, db, metrics, l1Etl, chainConfig, l1Header, l2Header}, nil +func (b *BridgeProcessor) Close() error { + // signal that we can stop any ongoing work + b.resourceCancel() + // await the work to stop + return b.tasks.Wait() } -func (b *BridgeProcessor) Start(ctx context.Context) error { - done := ctx.Done() +// onL1Data will index new bridge events for the unvisited L1 state. As new L1 bridge events +// are processed, bridge finalization events can be processed on L2 in this same window. +func (b *BridgeProcessor) onL1Data(latestL1Header *types.Header) (errs error) { - // Fire off independently on startup to check for - // new data or if we've indexed new L1 data. - l1EtlUpdates := b.l1Etl.Notify() - startup := make(chan interface{}, 1) - startup <- nil + // Continue while unvisited state is available to process + for errs == nil { + done := b.metrics.RecordL1Interval() - b.log.Info("starting bridge processor...") - for { - select { - case <-done: - b.log.Info("stopping bridge processor") - return nil - - // Tickers - case <-startup: - case <-l1EtlUpdates: + lastL1Header := b.LastL1Header + lastFinalizedL2Header := b.LastFinalizedL2Header + + // Initiated L1 Events + if b.LastL1Header == nil || b.LastL1Header.Timestamp < latestL1Header.Time { + if err := b.processInitiatedL1Events(latestL1Header); err != nil { + errs = errors.Join(errs, fmt.Errorf("failed processing initiated l1 events: %w", err)) + } } - done := b.metrics.RecordInterval() - done(b.run()) - } -} + // Finalized L1 Events (on L2) + // - Not every L1 block is indexed so check against a false interval on start. + if b.LastL1Header != nil && (b.LastFinalizedL2Header == nil || b.LastFinalizedL2Header.Timestamp < latestL1Header.Time) { + if err := b.processFinalizedL2Events(latestL1Header); err != nil { + errs = errors.Join(errs, fmt.Errorf("failed processing finalized l2 events: %w", err)) + } + } -// Runs the processing loop. In order to ensure all seen bridge finalization events -// can be correlated with bridge initiated events, we establish a shared marker between -// L1 and L2 when processing events. The latest shared indexed time (epochs) between -// L1 and L2 serves as this shared marker. -func (b *BridgeProcessor) run() error { - // In the event where we have a large number of un-observed epochs, we cap the search - // of epochs by 10k. If this turns out to be a bottleneck, we can parallelize the processing - // of epochs to significantly speed up sync times. - maxEpochRange := uint64(10_000) - var lastEpoch *big.Int - if b.LatestL1Header != nil { - lastEpoch = b.LatestL1Header.Number - } - - latestEpoch, err := b.db.Blocks.LatestObservedEpoch(lastEpoch, maxEpochRange) - if err != nil { - return err - } else if latestEpoch == nil { - if b.LatestL1Header != nil || b.LatestL2Header != nil { - // Once we have some indexed state `latestEpoch != nil` as `LatestObservedEpoch` is inclusive in its search with the last provided epoch. - b.log.Error("bridge events indexed, but no observed epoch returned", "latest_bridge_l1_block_number", b.LatestL1Header.Number) - return errors.New("bridge events indexed, but no observed epoch returned") + done(errs) + + // Break if there has been no change in processed events. + if lastL1Header == b.LastL1Header && lastFinalizedL2Header == b.LastFinalizedL2Header { + break } - b.log.Warn("no observed epochs available. waiting...") - return nil } - if b.LatestL1Header != nil && latestEpoch.L1BlockHeader.Hash == b.LatestL1Header.Hash() { - b.log.Warn("all available epochs indexed", "latest_bridge_l1_block_number", b.LatestL1Header.Number) - return nil + return errs +} + +// onL2Data will index new bridge events for the unvisited L2 state. As new L2 bridge events +// are processed, bridge finalization events can be processed on L1 in this same window. +func (b *BridgeProcessor) onL2Data(latestL2Header *types.Header) (errs error) { + if latestL2Header.Number.Cmp(bigint.Zero) == 0 { + return nil // skip genesis } - // Integrity Checks + // Continue while unvisited state is available to process + for errs == nil { + done := b.metrics.RecordL2Interval() - genesisL1Height := big.NewInt(int64(b.chainConfig.L1StartingHeight)) - if latestEpoch.L1BlockHeader.Number.Cmp(genesisL1Height) < 0 { - b.log.Error("L1 epoch less than starting L1 height observed", "l1_starting_number", genesisL1Height, "latest_epoch_number", latestEpoch.L1BlockHeader.Number) - return errors.New("L1 epoch less than starting L1 height observed") - } - if b.LatestL1Header != nil && latestEpoch.L1BlockHeader.Number.Cmp(b.LatestL1Header.Number) <= 0 { - b.log.Error("non-increasing l1 block height observed", "latest_bridge_l1_block_number", b.LatestL1Header.Number, "latest_epoch_l1_block_number", latestEpoch.L1BlockHeader.Number) - return errors.New("non-increasing l1 block height observed") + lastL2Header := b.LastL2Header + lastFinalizedL1Header := b.LastFinalizedL1Header + + // Initiated L2 Events + if b.LastL2Header == nil || b.LastL2Header.Timestamp < latestL2Header.Time { + if err := b.processInitiatedL2Events(latestL2Header); err != nil { + errs = errors.Join(errs, fmt.Errorf("failed processing initiated l2 events: %w", err)) + } + } + + // Finalized L2 Events (on L1) + if b.LastL2Header != nil && (b.LastFinalizedL1Header == nil || b.LastFinalizedL1Header.Timestamp < latestL2Header.Time) { + if err := b.processFinalizedL1Events(latestL2Header); err != nil { + errs = errors.Join(errs, fmt.Errorf("failed processing finalized l1 events: %w", err)) + } + } + + done(errs) + + // Break if there has been no change in processed events. + if lastL2Header == b.LastL2Header && lastFinalizedL1Header == b.LastFinalizedL1Header { + break + } } - if b.LatestL2Header != nil && latestEpoch.L2BlockHeader.Number.Cmp(b.LatestL2Header.Number) <= 0 { - b.log.Error("non-increasing l2 block height observed", "latest_bridge_l2_block_number", b.LatestL2Header.Number, "latest_epoch_l2_block_number", latestEpoch.L2BlockHeader.Number) - return errors.New("non-increasing l2 block height observed") + + return errs +} + +// Process Initiated Bridge Events + +func (b *BridgeProcessor) processInitiatedL1Events(latestL1Header *types.Header) error { + l1BridgeLog := b.log.New("bridge", "l1", "kind", "initiated") + lastL1BlockNumber := big.NewInt(int64(b.chainConfig.L1StartingHeight - 1)) + if b.LastL1Header != nil { + lastL1BlockNumber = b.LastL1Header.Number } - toL1Height, toL2Height := latestEpoch.L1BlockHeader.Number, latestEpoch.L2BlockHeader.Number - fromL1Height, fromL2Height := genesisL1Height, bigint.Zero - if b.LatestL1Header != nil { - fromL1Height = new(big.Int).Add(b.LatestL1Header.Number, bigint.One) + // Latest unobserved L1 state bounded by `blockLimits` blocks. Since + // not every L1 block is indexed, we may have nothing to process. + toL1HeaderScope := func(db *gorm.DB) *gorm.DB { + newQuery := db.Session(&gorm.Session{NewDB: true}) // fresh subquery + headers := newQuery.Model(database.L1BlockHeader{}).Where("number > ? AND number <= ?", lastL1BlockNumber, latestL1Header.Number) + return db.Where("number = (?)", newQuery.Table("(?) AS block_numbers", headers.Order("number ASC").Limit(blocksLimit)).Select("MAX(number)")) } - if b.LatestL2Header != nil { - fromL2Height = new(big.Int).Add(b.LatestL2Header.Number, bigint.One) + toL1Header, err := b.db.Blocks.L1BlockHeaderWithScope(toL1HeaderScope) + if err != nil { + return fmt.Errorf("failed to query new L1 state: %w", err) + } else if toL1Header == nil { + l1BridgeLog.Debug("no new L1 state found") + return nil } - l1BedrockStartingHeight := big.NewInt(int64(b.chainConfig.L1BedrockStartingHeight)) - l2BedrockStartingHeight := big.NewInt(int64(b.chainConfig.L2BedrockStartingHeight)) - - batchLog := b.log.New("epoch_start_number", fromL1Height, "epoch_end_number", toL1Height) - batchLog.Info("unobserved epochs", "latest_l1_block_number", fromL1Height, "latest_l2_block_number", fromL2Height) + fromL1Height, toL1Height := new(big.Int).Add(lastL1BlockNumber, bigint.One), toL1Header.Number if err := b.db.Transaction(func(tx *database.DB) error { - l1BridgeLog := b.log.New("bridge", "l1") - l2BridgeLog := b.log.New("bridge", "l2") - - // FOR OP-MAINNET, OP-GOERLI ONLY! Specially handle the existence of pre-bedrock blocks - if l1BedrockStartingHeight.Cmp(fromL1Height) > 0 { + l1BedrockStartingHeight := big.NewInt(int64(b.chainConfig.L1BedrockStartingHeight)) + if l1BedrockStartingHeight.Cmp(fromL1Height) > 0 { // OP Mainnet & OP Goerli Only. legacyFromL1Height, legacyToL1Height := fromL1Height, toL1Height - legacyFromL2Height, legacyToL2Height := fromL2Height, toL2Height if l1BedrockStartingHeight.Cmp(toL1Height) <= 0 { legacyToL1Height = new(big.Int).Sub(l1BedrockStartingHeight, bigint.One) - legacyToL2Height = new(big.Int).Sub(l2BedrockStartingHeight, bigint.One) } - l1BridgeLog = l1BridgeLog.New("mode", "legacy", "from_l1_block_number", legacyFromL1Height, "to_l1_block_number", legacyToL1Height) - l1BridgeLog.Info("scanning for bridge events") - - l2BridgeLog = l2BridgeLog.New("mode", "legacy", "from_l2_block_number", legacyFromL2Height, "to_l2_block_number", legacyToL2Height) - l2BridgeLog.Info("scanning for bridge events") - - // First, find all possible initiated bridge events - if err := bridge.LegacyL1ProcessInitiatedBridgeEvents(l1BridgeLog, tx, b.metrics, b.chainConfig.L1Contracts, legacyFromL1Height, legacyToL1Height); err != nil { - batchLog.Error("failed to index legacy l1 initiated bridge events", "err", err) - return err - } - if err := bridge.LegacyL2ProcessInitiatedBridgeEvents(l2BridgeLog, tx, b.metrics, b.chainConfig.L2Contracts, legacyFromL2Height, legacyToL2Height); err != nil { - batchLog.Error("failed to index legacy l2 initiated bridge events", "err", err) + legacyBridgeLog := l1BridgeLog.New("mode", "legacy", "from_block_number", legacyFromL1Height, "to_block_number", legacyToL1Height) + legacyBridgeLog.Info("scanning for initiated bridge events") + if err := bridge.LegacyL1ProcessInitiatedBridgeEvents(legacyBridgeLog, tx, b.metrics, b.chainConfig.L1Contracts, legacyFromL1Height, legacyToL1Height); err != nil { return err + } else if legacyToL1Height.Cmp(toL1Height) == 0 { + return nil // a-ok! Entire range was legacy blocks } + legacyBridgeLog.Info("detected switch to bedrock", "bedrock_block_number", l1BedrockStartingHeight) + fromL1Height = l1BedrockStartingHeight + } - // Now that all initiated events have been indexed, it is ensured that all finalization can find their counterpart. - if err := bridge.LegacyL1ProcessFinalizedBridgeEvents(l1BridgeLog, tx, b.metrics, b.l1Etl.EthClient, b.chainConfig.L1Contracts, legacyFromL1Height, legacyToL1Height); err != nil { - batchLog.Error("failed to index legacy l1 finalized bridge events", "err", err) - return err + l1BridgeLog = l1BridgeLog.New("from_block_number", fromL1Height, "to_block_number", toL1Height) + l1BridgeLog.Info("scanning for initiated bridge events") + return bridge.L1ProcessInitiatedBridgeEvents(l1BridgeLog, tx, b.metrics, b.chainConfig.L1Contracts, fromL1Height, toL1Height) + }); err != nil { + return err + } + + b.LastL1Header = toL1Header + b.metrics.RecordL1LatestHeight(toL1Header.Number) + return nil +} + +func (b *BridgeProcessor) processInitiatedL2Events(latestL2Header *types.Header) error { + l2BridgeLog := b.log.New("bridge", "l2", "kind", "initiated") + lastL2BlockNumber := bigint.Zero + if b.LastL2Header != nil { + lastL2BlockNumber = b.LastL2Header.Number + } + + // Latest unobserved L2 state bounded by `blockLimits` blocks. + // Since every L2 block is indexed, we always expect new state. + toL2HeaderScope := func(db *gorm.DB) *gorm.DB { + newQuery := db.Session(&gorm.Session{NewDB: true}) // fresh subquery + headers := newQuery.Model(database.L2BlockHeader{}).Where("number > ? AND number <= ?", lastL2BlockNumber, latestL2Header.Number) + return db.Where("number = (?)", newQuery.Table("(?) AS block_numbers", headers.Order("number ASC").Limit(blocksLimit)).Select("MAX(number)")) + } + toL2Header, err := b.db.Blocks.L2BlockHeaderWithScope(toL2HeaderScope) + if err != nil { + return fmt.Errorf("failed to query new L2 state: %w", err) + } else if toL2Header == nil { + return fmt.Errorf("no new L2 state found") + } + + fromL2Height, toL2Height := new(big.Int).Add(lastL2BlockNumber, bigint.One), toL2Header.Number + if err := b.db.Transaction(func(tx *database.DB) error { + l2BedrockStartingHeight := big.NewInt(int64(b.chainConfig.L2BedrockStartingHeight)) + if l2BedrockStartingHeight.Cmp(fromL2Height) > 0 { // OP Mainnet & OP Goerli Only + legacyFromL2Height, legacyToL2Height := fromL2Height, toL2Height + if l2BedrockStartingHeight.Cmp(toL2Height) <= 0 { + legacyToL2Height = new(big.Int).Sub(l2BedrockStartingHeight, bigint.One) } - if err := bridge.LegacyL2ProcessFinalizedBridgeEvents(l2BridgeLog, tx, b.metrics, b.chainConfig.L2Contracts, legacyFromL2Height, legacyToL2Height); err != nil { - batchLog.Error("failed to index legacy l2l finalized bridge events", "err", err) + + legacyBridgeLog := l2BridgeLog.New("mode", "legacy", "from_block_number", legacyFromL2Height, "to_block_number", legacyToL2Height) + legacyBridgeLog.Info("scanning for initiated bridge events") + if err := bridge.LegacyL2ProcessInitiatedBridgeEvents(legacyBridgeLog, tx, b.metrics, b.chainConfig.Preset, b.chainConfig.L2Contracts, legacyFromL2Height, legacyToL2Height); err != nil { return err + } else if legacyToL2Height.Cmp(toL2Height) == 0 { + return nil // a-ok! Entire range was legacy blocks } + legacyBridgeLog.Info("detected switch to bedrock") + fromL2Height = l2BedrockStartingHeight + } - if legacyToL1Height.Cmp(toL1Height) == 0 { - // a-ok! entire batch was legacy blocks - return nil + l2BridgeLog = l2BridgeLog.New("from_block_number", fromL2Height, "to_block_number", toL2Height) + l2BridgeLog.Info("scanning for initiated bridge events") + return bridge.L2ProcessInitiatedBridgeEvents(l2BridgeLog, tx, b.metrics, b.chainConfig.L2Contracts, fromL2Height, toL2Height) + }); err != nil { + return err + } + + b.LastL2Header = toL2Header + b.metrics.RecordL2LatestHeight(toL2Header.Number) + return nil +} + +// Process Finalized Bridge Events + +func (b *BridgeProcessor) processFinalizedL1Events(latestL2Header *types.Header) error { + l1BridgeLog := b.log.New("bridge", "l1", "kind", "finalization") + lastFinalizedL1BlockNumber := big.NewInt(int64(b.chainConfig.L1StartingHeight) - 1) + if b.LastFinalizedL1Header != nil { + lastFinalizedL1BlockNumber = b.LastFinalizedL1Header.Number + } + + // Latest unfinalized L1 state bounded by `blockLimit` blocks that have had L2 bridge events + // indexed. Since L1 data is indexed independently, there may not be new L1 state to finalize + toL1HeaderScope := func(db *gorm.DB) *gorm.DB { + newQuery := db.Session(&gorm.Session{NewDB: true}) // fresh subquery + headers := newQuery.Model(database.L1BlockHeader{}).Where("number > ? AND timestamp <= ?", lastFinalizedL1BlockNumber, latestL2Header.Time) + return db.Where("number = (?)", newQuery.Table("(?) AS block_numbers", headers.Order("number ASC").Limit(blocksLimit)).Select("MAX(number)")) + } + toL1Header, err := b.db.Blocks.L1BlockHeaderWithScope(toL1HeaderScope) + if err != nil { + return fmt.Errorf("failed to query for latest unfinalized L1 state: %w", err) + } else if toL1Header == nil { + l1BridgeLog.Debug("no new l1 state to finalize", "last_finalized_block_number", lastFinalizedL1BlockNumber) + return nil + } + + fromL1Height, toL1Height := new(big.Int).Add(lastFinalizedL1BlockNumber, bigint.One), toL1Header.Number + if err := b.db.Transaction(func(tx *database.DB) error { + l1BedrockStartingHeight := big.NewInt(int64(b.chainConfig.L1BedrockStartingHeight)) + if l1BedrockStartingHeight.Cmp(fromL1Height) > 0 { + legacyFromL1Height, legacyToL1Height := fromL1Height, toL1Height + if l1BedrockStartingHeight.Cmp(toL1Height) <= 0 { + legacyToL1Height = new(big.Int).Sub(l1BedrockStartingHeight, bigint.One) } - batchLog.Info("detected switch to bedrock", "l1_bedrock_starting_height", l1BedrockStartingHeight, "l2_bedrock_starting_height", l2BedrockStartingHeight) + legacyBridgeLog := l1BridgeLog.New("mode", "legacy", "from_block_number", legacyFromL1Height, "to_block_number", legacyToL1Height) + legacyBridgeLog.Info("scanning for finalized bridge events") + if err := bridge.LegacyL1ProcessFinalizedBridgeEvents(legacyBridgeLog, tx, b.metrics, b.chainConfig.L1Contracts, legacyFromL1Height, legacyToL1Height); err != nil { + return err + } else if legacyToL1Height.Cmp(toL1Height) == 0 { + return nil // a-ok! Entire range was legacy blocks + } + legacyBridgeLog.Info("detected switch to bedrock") fromL1Height = l1BedrockStartingHeight - fromL2Height = l2BedrockStartingHeight } - l1BridgeLog = l1BridgeLog.New("from_l1_block_number", fromL1Height, "to_l1_block_number", toL1Height) - l1BridgeLog.Info("scanning for bridge events") + l1BridgeLog = l1BridgeLog.New("from_block_number", fromL1Height, "to_block_number", toL1Height) + l1BridgeLog.Info("scanning for finalized bridge events") + return bridge.L1ProcessFinalizedBridgeEvents(l1BridgeLog, tx, b.metrics, b.chainConfig.L1Contracts, fromL1Height, toL1Height) + }); err != nil { + return err + } - l2BridgeLog = l2BridgeLog.New("from_l2_block_number", fromL2Height, "to_l2_block_number", toL2Height) - l2BridgeLog.Info("scanning for bridge events") + b.LastFinalizedL1Header = toL1Header + b.metrics.RecordL1LatestFinalizedHeight(toL1Header.Number) + return nil +} - // First, find all possible initiated bridge events - if err := bridge.L1ProcessInitiatedBridgeEvents(l1BridgeLog, tx, b.metrics, b.chainConfig.L1Contracts, fromL1Height, toL1Height); err != nil { - batchLog.Error("failed to index l1 initiated bridge events", "err", err) - return err - } - if err := bridge.L2ProcessInitiatedBridgeEvents(l2BridgeLog, tx, b.metrics, b.chainConfig.L2Contracts, fromL2Height, toL2Height); err != nil { - batchLog.Error("failed to index l2 initiated bridge events", "err", err) - return err - } +func (b *BridgeProcessor) processFinalizedL2Events(latestL1Header *types.Header) error { + l2BridgeLog := b.log.New("bridge", "l2", "kind", "finalization") + lastFinalizedL2BlockNumber := bigint.Zero + if b.LastFinalizedL2Header != nil { + lastFinalizedL2BlockNumber = b.LastFinalizedL2Header.Number + } - // Now all finalization events can find their counterpart. - if err := bridge.L1ProcessFinalizedBridgeEvents(l1BridgeLog, tx, b.metrics, b.chainConfig.L1Contracts, fromL1Height, toL1Height); err != nil { - batchLog.Error("failed to index l1 finalized bridge events", "err", err) - return err - } - if err := bridge.L2ProcessFinalizedBridgeEvents(l2BridgeLog, tx, b.metrics, b.chainConfig.L2Contracts, fromL2Height, toL2Height); err != nil { - batchLog.Error("failed to index l2 finalized bridge events", "err", err) - return err + // Latest unfinalized L2 state bounded by `blockLimit` blocks that have had L1 bridge events + // indexed. Since L2 data is indexed independently, there may not be new L2 state to finalize + toL2HeaderScope := func(db *gorm.DB) *gorm.DB { + newQuery := db.Session(&gorm.Session{NewDB: true}) // fresh subquery + headers := newQuery.Model(database.L2BlockHeader{}).Where("number > ? AND timestamp <= ?", lastFinalizedL2BlockNumber, latestL1Header.Time) + return db.Where("number = (?)", newQuery.Table("(?) AS block_numbers", headers.Order("number ASC").Limit(blocksLimit)).Select("MAX(number)")) + } + toL2Header, err := b.db.Blocks.L2BlockHeaderWithScope(toL2HeaderScope) + if err != nil { + return fmt.Errorf("failed to query for latest unfinalized L2 state: %w", err) + } else if toL2Header == nil { + l2BridgeLog.Debug("no new l2 state to finalize", "last_finalized_block_number", lastFinalizedL2BlockNumber) + return nil + } + + fromL2Height, toL2Height := new(big.Int).Add(lastFinalizedL2BlockNumber, bigint.One), toL2Header.Number + if err := b.db.Transaction(func(tx *database.DB) error { + l2BedrockStartingHeight := big.NewInt(int64(b.chainConfig.L2BedrockStartingHeight)) + if l2BedrockStartingHeight.Cmp(fromL2Height) > 0 { + legacyFromL2Height, legacyToL2Height := fromL2Height, toL2Height + if l2BedrockStartingHeight.Cmp(toL2Height) <= 0 { + legacyToL2Height = new(big.Int).Sub(l2BedrockStartingHeight, bigint.One) + } + + legacyBridgeLog := l2BridgeLog.New("mode", "legacy", "from_block_number", legacyFromL2Height, "to_block_number", legacyToL2Height) + legacyBridgeLog.Info("scanning for finalized bridge events") + if err := bridge.LegacyL2ProcessFinalizedBridgeEvents(legacyBridgeLog, tx, b.metrics, b.chainConfig.L2Contracts, legacyFromL2Height, legacyToL2Height); err != nil { + return err + } else if legacyToL2Height.Cmp(toL2Height) == 0 { + return nil // a-ok! Entire range was legacy blocks + } + legacyBridgeLog.Info("detected switch to bedrock", "bedrock_block_number", l2BedrockStartingHeight) + fromL2Height = l2BedrockStartingHeight } - // a-ok - return nil + l2BridgeLog = l2BridgeLog.New("from_block_number", fromL2Height, "to_block_number", toL2Height) + l2BridgeLog.Info("scanning for finalized bridge events") + return bridge.L2ProcessFinalizedBridgeEvents(l2BridgeLog, tx, b.metrics, b.chainConfig.L2Contracts, fromL2Height, toL2Height) }); err != nil { return err } - batchLog.Info("indexed bridge events", "latest_l1_block_number", toL1Height, "latest_l2_block_number", toL2Height) - b.LatestL1Header = latestEpoch.L1BlockHeader.RLPHeader.Header() - b.metrics.RecordLatestIndexedL1Height(b.LatestL1Header.Number) - - b.LatestL2Header = latestEpoch.L2BlockHeader.RLPHeader.Header() - b.metrics.RecordLatestIndexedL2Height(b.LatestL2Header.Number) + b.LastFinalizedL2Header = toL2Header + b.metrics.RecordL2LatestFinalizedHeight(toL2Header.Number) return nil } diff --git a/indexer/processors/bridge/l1_bridge_processor.go b/indexer/processors/bridge/l1_bridge_processor.go index 106188b9e3f0..80c0f829732d 100644 --- a/indexer/processors/bridge/l1_bridge_processor.go +++ b/indexer/processors/bridge/l1_bridge_processor.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum-optimism/optimism/indexer/bigint" "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" + "github.com/ethereum-optimism/optimism/indexer/processors/bridge/ovm1" "github.com/ethereum-optimism/optimism/indexer/processors/contracts" "github.com/ethereum/go-ethereum/common" @@ -74,14 +75,15 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M // extract the deposit hash from the previous TransactionDepositedEvent portalDeposit, ok := portalDeposits[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex - 1}] if !ok { - log.Error("expected TransactionDeposit preceding SentMessage event", "tx_hash", sentMessage.Event.TransactionHash.String()) return fmt.Errorf("expected TransactionDeposit preceding SentMessage event. tx_hash = %s", sentMessage.Event.TransactionHash.String()) } else if portalDeposit.Event.TransactionHash != sentMessage.Event.TransactionHash { - log.Error("correlated events tx hash mismatch", "deposit_tx_hash", portalDeposit.Event.TransactionHash.String(), "message_tx_hash", sentMessage.Event.TransactionHash.String()) - return fmt.Errorf("correlated events tx hash mismatch") + return fmt.Errorf("correlated events tx hash mismatch. deposit_tx_hash = %s, message_tx_hash = %s", portalDeposit.Event.TransactionHash, sentMessage.Event.TransactionHash) } - bridgeMessages[i] = database.L1BridgeMessage{TransactionSourceHash: portalDeposit.DepositTx.SourceHash, BridgeMessage: sentMessage.BridgeMessage} + bridgeMessages[i] = database.L1BridgeMessage{ + TransactionSourceHash: portalDeposit.DepositTx.SourceHash, + BridgeMessage: sentMessage.BridgeMessage, + } } if len(bridgeMessages) > 0 { if err := db.BridgeMessages.StoreL1BridgeMessages(bridgeMessages); err != nil { @@ -107,20 +109,16 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M // extract the cross domain message hash & deposit source hash from the following events portalDeposit, ok := portalDeposits[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex + 1}] if !ok { - log.Error("expected TransactionDeposit following BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("expected TransactionDeposit following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) + return fmt.Errorf("expected TransactionDeposit following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash) } else if portalDeposit.Event.TransactionHash != initiatedBridge.Event.TransactionHash { - log.Error("correlated events tx hash mismatch", "deposit_tx_hash", portalDeposit.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("correlated events tx hash mismatch") + return fmt.Errorf("correlated events tx hash mismatch, bridge_tx_hash = %s, deposit_tx_hash = %s", initiatedBridge.Event.TransactionHash, portalDeposit.Event.TransactionHash) } sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex + 2}] if !ok { - log.Error("expected SentMessage following BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("expected SentMessage following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) + return fmt.Errorf("expected SentMessage following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash) } else if sentMessage.Event.TransactionHash != initiatedBridge.Event.TransactionHash { - log.Error("correlated events tx hash mismatch", "message_tx_hash", sentMessage.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("correlated events tx hash mismatch") + return fmt.Errorf("correlated events tx hash mismatch. bridge_tx_hash = %s, message_tx_hash = %s", initiatedBridge.Event.TransactionHash, sentMessage.Event.TransactionHash) } bridgedTokens[initiatedBridge.BridgeTransfer.TokenPair.LocalTokenAddress]++ @@ -143,7 +141,7 @@ func L1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L1M return nil } -// L1ProcessFinalizedBridgeEvent will query the database for all the finalization markers for all initiated +// L1ProcessFinalizedBridgeEvents will query the database for all the finalization markers for all initiated // bridge events. This covers every part of the multi-layered stack: // 1. OptimismPortal (Bedrock prove & finalize steps) // 2. L1CrossDomainMessenger (relayMessage marker) @@ -158,23 +156,34 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M log.Info("detected proven withdrawals", "size", len(provenWithdrawals)) } + skippedOVM1ProvenWithdrawals := 0 for i := range provenWithdrawals { - proven := provenWithdrawals[i] - withdrawal, err := db.BridgeTransactions.L2TransactionWithdrawal(proven.WithdrawalHash) + provenWithdrawal := provenWithdrawals[i] + withdrawal, err := db.BridgeTransactions.L2TransactionWithdrawal(provenWithdrawal.WithdrawalHash) if err != nil { return err } else if withdrawal == nil { - log.Error("missing indexed withdrawal on proven event!", "tx_hash", proven.Event.TransactionHash.String()) - return fmt.Errorf("missing indexed withdrawal! tx_hash = %s", proven.Event.TransactionHash.String()) + if _, ok := ovm1.PortalWithdrawalTransactions[provenWithdrawal.WithdrawalHash]; ok { + skippedOVM1ProvenWithdrawals++ + continue + } + return fmt.Errorf("missing indexed withdrawal! tx_hash = %s", provenWithdrawal.Event.TransactionHash) } - if err := db.BridgeTransactions.MarkL2TransactionWithdrawalProvenEvent(proven.WithdrawalHash, provenWithdrawals[i].Event.GUID); err != nil { - log.Error("failed to mark withdrawal as proven", "err", err, "tx_hash", proven.Event.TransactionHash.String()) - return err + if withdrawal.ProvenL1EventGUID != nil && withdrawal.ProvenL1EventGUID.ID() != provenWithdrawals[i].Event.GUID.ID() { + log.Info("detected re-proven withdrawal", "tx_hash", provenWithdrawal.Event.TransactionHash.String()) + } + + if err := db.BridgeTransactions.MarkL2TransactionWithdrawalProvenEvent(provenWithdrawal.WithdrawalHash, provenWithdrawals[i].Event.GUID); err != nil { + return fmt.Errorf("failed to mark withdrawal as proven. tx_hash = %s: %w", provenWithdrawal.Event.TransactionHash, err) } } if len(provenWithdrawals) > 0 { metrics.RecordL1ProvenWithdrawals(len(provenWithdrawals)) + if skippedOVM1ProvenWithdrawals > 0 { + metrics.RecordL1SkippedOVM1ProvenWithdrawals(skippedOVM1ProvenWithdrawals) + log.Info("skipped OVM 1.0 proven withdrawals", "size", skippedOVM1ProvenWithdrawals) + } } // (2) OptimismPortal (finalized withdrawals) @@ -186,23 +195,30 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M log.Info("detected finalized withdrawals", "size", len(finalizedWithdrawals)) } + skippedOVM1FinalizedWithdrawals := 0 for i := range finalizedWithdrawals { finalizedWithdrawal := finalizedWithdrawals[i] withdrawal, err := db.BridgeTransactions.L2TransactionWithdrawal(finalizedWithdrawal.WithdrawalHash) if err != nil { return err } else if withdrawal == nil { - log.Error("missing indexed withdrawal on finalization event!", "tx_hash", finalizedWithdrawal.Event.TransactionHash.String()) - return fmt.Errorf("missing indexed withdrawal on finalization! tx_hash: %s", finalizedWithdrawal.Event.TransactionHash.String()) + if _, ok := ovm1.PortalWithdrawalTransactions[finalizedWithdrawal.WithdrawalHash]; ok { + skippedOVM1FinalizedWithdrawals++ + continue + } + return fmt.Errorf("missing indexed withdrawal on finalization! tx_hash = %s", finalizedWithdrawal.Event.TransactionHash.String()) } if err = db.BridgeTransactions.MarkL2TransactionWithdrawalFinalizedEvent(finalizedWithdrawal.WithdrawalHash, finalizedWithdrawal.Event.GUID, finalizedWithdrawal.Success); err != nil { - log.Error("failed to mark withdrawal as finalized", "err", err, "tx_hash", finalizedWithdrawal.Event.TransactionHash.String()) - return err + return fmt.Errorf("failed to mark withdrawal as finalized. tx_hash = %s: %w", finalizedWithdrawal.Event.TransactionHash, err) } } if len(finalizedWithdrawals) > 0 { metrics.RecordL1FinalizedWithdrawals(len(finalizedWithdrawals)) + if skippedOVM1ProvenWithdrawals > 0 { + metrics.RecordL1SkippedOVM1FinalizedWithdrawals(skippedOVM1FinalizedWithdrawals) + log.Info("skipped OVM 1.0 finalized withdrawals", "size", skippedOVM1FinalizedWithdrawals) + } } // (3) L1CrossDomainMessenger @@ -214,23 +230,30 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M log.Info("detected relayed messages", "size", len(crossDomainRelayedMessages)) } + skippedOVM1Messages := 0 for i := range crossDomainRelayedMessages { - relayed := crossDomainRelayedMessages[i] - message, err := db.BridgeMessages.L2BridgeMessage(relayed.MessageHash) + relayedMessage := crossDomainRelayedMessages[i] + message, err := db.BridgeMessages.L2BridgeMessage(relayedMessage.MessageHash) if err != nil { return err } else if message == nil { - log.Error("missing indexed L2CrossDomainMessenger message", "tx_hash", relayed.Event.TransactionHash.String()) - return fmt.Errorf("missing indexed L2CrossDomainMessager message. tx_hash %s", relayed.Event.TransactionHash.String()) + if _, ok := ovm1.L1RelayedMessages[relayedMessage.MessageHash]; ok { + skippedOVM1Messages++ + continue + } + return fmt.Errorf("missing indexed L2CrossDomainMessager message! tx_hash = %s", relayedMessage.Event.TransactionHash.String()) } - if err := db.BridgeMessages.MarkRelayedL2BridgeMessage(relayed.MessageHash, relayed.Event.GUID); err != nil { - log.Error("failed to relay cross domain message", "err", err, "tx_hash", relayed.Event.TransactionHash.String()) - return err + if err := db.BridgeMessages.MarkRelayedL2BridgeMessage(relayedMessage.MessageHash, relayedMessage.Event.GUID); err != nil { + return fmt.Errorf("failed to relay cross domain message. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err) } } if len(crossDomainRelayedMessages) > 0 { metrics.RecordL1CrossDomainRelayedMessages(len(crossDomainRelayedMessages)) + if skippedOVM1Messages > 0 { // Logged as a warning just for visibility + metrics.RecordL1SkippedOVM1CrossDomainRelayedMessages(skippedOVM1Messages) + log.Info("skipped OVM 1.0 relayed L2CrossDomainMessenger withdrawals", "size", skippedOVM1Messages) + } } // (4) L1StandardBridge diff --git a/indexer/processors/bridge/l2_bridge_processor.go b/indexer/processors/bridge/l2_bridge_processor.go index 932b1c91c745..0fb99ad9fa20 100644 --- a/indexer/processors/bridge/l2_bridge_processor.go +++ b/indexer/processors/bridge/l2_bridge_processor.go @@ -72,11 +72,9 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M // extract the withdrawal hash from the previous MessagePassed event messagePassed, ok := messagesPassed[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex - 1}] if !ok { - log.Error("expected MessagePassedEvent preceding SentMessage", "tx_hash", sentMessage.Event.TransactionHash.String()) - return fmt.Errorf("expected MessagePassedEvent preceding SentMessage. tx_hash = %s", sentMessage.Event.TransactionHash.String()) + return fmt.Errorf("expected MessagePassedEvent preceding SentMessage. tx_hash = %s", sentMessage.Event.TransactionHash) } else if messagePassed.Event.TransactionHash != sentMessage.Event.TransactionHash { - log.Error("correlated events tx hash mismatch", "withdraw_tx_hash", messagePassed.Event.TransactionHash.String(), "message_tx_hash", sentMessage.Event.TransactionHash.String()) - return fmt.Errorf("correlated events tx hash mismatch") + return fmt.Errorf("correlated events tx hash mismatch. message_tx_hash = %s, withdraw_tx_hash = %s", sentMessage.Event.TransactionHash, messagePassed.Event.TransactionHash) } bridgeMessages[i] = database.L2BridgeMessage{TransactionWithdrawalHash: messagePassed.WithdrawalHash, BridgeMessage: sentMessage.BridgeMessage} @@ -105,20 +103,16 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M // extract the cross domain message hash & withdraw hash from the following events messagePassed, ok := messagesPassed[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex + 1}] if !ok { - log.Error("expected MessagePassed following BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("expected MessagePassed following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) + return fmt.Errorf("expected MessagePassed following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash) } else if messagePassed.Event.TransactionHash != initiatedBridge.Event.TransactionHash { - log.Error("correlated events tx hash mismatch", "withdraw_tx_hash", messagePassed.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("correlated events tx hash mismatch") + return fmt.Errorf("correlated events tx hash mismatch. bridge_tx_hash = %s, withdraw_tx_hash = %s", initiatedBridge.Event.TransactionHash, messagePassed.Event.TransactionHash) } sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex + 2}] if !ok { - log.Error("expected SentMessage following BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("expected SentMessage following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) + return fmt.Errorf("expected SentMessage following BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash) } else if sentMessage.Event.TransactionHash != initiatedBridge.Event.TransactionHash { - log.Error("correlated events tx hash mismatch", "message_tx_hash", sentMessage.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("correlated events tx hash mismatch") + return fmt.Errorf("correlated events tx hash mismatch. bridge_tx_hash = %s, message_tx_hash = %s", initiatedBridge.Event.TransactionHash, sentMessage.Event.TransactionHash) } bridgedTokens[initiatedBridge.BridgeTransfer.TokenPair.LocalTokenAddress]++ @@ -142,7 +136,7 @@ func L2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2M return nil } -// L2ProcessFinalizedBridgeEvent will query the database for all the finalization markers for all initiated +// L2ProcessFinalizedBridgeEvents will query the database for all the finalization markers for all initiated // bridge events. This covers every part of the multi-layered stack: // 1. L2CrossDomainMessenger (relayMessage marker) // 2. L2StandardBridge (no-op, since this is simply a wrapper over the L2CrossDomainMEssenger) @@ -164,13 +158,11 @@ func L2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L2M if err != nil { return err } else if message == nil { - log.Error("missing indexed L1CrossDomainMessenger message", "tx_hash", relayed.Event.TransactionHash.String()) - return fmt.Errorf("missing indexed L1CrossDomainMessager message. tx_hash = %s", relayed.Event.TransactionHash.String()) + return fmt.Errorf("missing indexed L1CrossDomainMessager message! tx_hash = %s", relayed.Event.TransactionHash) } if err := db.BridgeMessages.MarkRelayedL1BridgeMessage(relayed.MessageHash, relayed.Event.GUID); err != nil { - log.Error("failed to relay cross domain message", "err", err, "tx_hash", relayed.Event.TransactionHash.String()) - return err + return fmt.Errorf("failed to relay cross domain message. tx_hash = %s: %w", relayed.Event.TransactionHash, err) } } if len(crossDomainRelayedMessages) > 0 { diff --git a/indexer/processors/bridge/legacy_bridge_processor.go b/indexer/processors/bridge/legacy_bridge_processor.go index a0886a019f69..b9af31cf1172 100644 --- a/indexer/processors/bridge/legacy_bridge_processor.go +++ b/indexer/processors/bridge/legacy_bridge_processor.go @@ -10,13 +10,16 @@ import ( "github.com/ethereum-optimism/optimism/indexer/bigint" "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" - "github.com/ethereum-optimism/optimism/indexer/node" + "github.com/ethereum-optimism/optimism/indexer/processors/bridge/ovm1" "github.com/ethereum-optimism/optimism/indexer/processors/contracts" + + "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" ) // Legacy Bridge Initiation -// LegacyL1ProcessInitiatedEvents will query the data for bridge events within the specified block range +// LegacyL1ProcessInitiatedBridgeEvents will query the data for bridge events within the specified block range // according the pre-bedrock protocol. This follows: // 1. CanonicalTransactionChain // 2. L1CrossDomainMessenger @@ -75,11 +78,9 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri // extract the deposit hash from the previous TransactionDepositedEvent ctcTxDeposit, ok := ctcTxDeposits[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex - 1}] if !ok { - log.Error("expected TransactionEnqueued preceding SentMessage event", "tx_hash", sentMessage.Event.TransactionHash.String()) - return fmt.Errorf("expected TransactionEnqueued preceding SentMessage event. tx_hash = %s", sentMessage.Event.TransactionHash.String()) + return fmt.Errorf("expected TransactionEnqueued preceding SentMessage event. tx_hash = %s", sentMessage.Event.TransactionHash) } else if ctcTxDeposit.Event.TransactionHash != sentMessage.Event.TransactionHash { - log.Error("correlated events tx hash mismatch", "deposit_tx_hash", ctcTxDeposit.Event.TransactionHash.String(), "message_tx_hash", sentMessage.Event.TransactionHash.String()) - return fmt.Errorf("correlated events tx hash mismatch") + return fmt.Errorf("correlated events tx hash mismatch. deposit_tx_hash = %s, message_tx_hash = %s", ctcTxDeposit.Event.TransactionHash, sentMessage.Event.TransactionHash) } bridgeMessages[i] = database.L1BridgeMessage{TransactionSourceHash: ctcTxDeposit.TxHash, BridgeMessage: sentMessage.BridgeMessage} @@ -110,20 +111,16 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri // - Event Flow: TransactionEnqueued -> SentMessage -> DepositInitiated sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex - 1}] if !ok { - log.Error("expected SentMessage preceding BridgeInitiated event", "tx_hash", sentMessage.Event.TransactionHash.String()) - return fmt.Errorf("expected SentMessage preceding DepositInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) + return fmt.Errorf("expected SentMessage preceding DepositInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash) } else if sentMessage.Event.TransactionHash != initiatedBridge.Event.TransactionHash { - log.Error("correlated events tx hash mismatch", "message_tx_hash", sentMessage.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("correlated events tx hash mismatch") + return fmt.Errorf("correlated events tx hash mismatch. bridge_tx_hash = %s, message_tx_hash = %s", initiatedBridge.Event.TransactionHash, sentMessage.Event.TransactionHash) } ctcTxDeposit, ok := ctcTxDeposits[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex - 2}] if !ok { - log.Error("expected TransactionEnqueued preceding BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("expected TransactionEnqueued preceding BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash.String()) + return fmt.Errorf("expected TransactionEnqueued preceding BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash) } else if ctcTxDeposit.Event.TransactionHash != initiatedBridge.Event.TransactionHash { - log.Error("correlated events tx hash mismatch", "deposit_tx_hash", ctcTxDeposit.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("correlated events tx hash mismatch") + return fmt.Errorf("correlated events tx hash mismatch. bridge_tx_hash = %s, deposit_tx_hash = %s", initiatedBridge.Event.TransactionHash, ctcTxDeposit.Event.TransactionHash) } initiatedBridge.BridgeTransfer.CrossDomainMessageHash = &sentMessage.BridgeMessage.MessageHash @@ -146,12 +143,12 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri return nil } -// LegacyL2ProcessInitiatedEvents will query the data for bridge events within the specified block range +// LegacyL2ProcessInitiatedBridgeEvents will query the data for bridge events within the specified block range // according the pre-bedrock protocol. This follows: // 1. L2CrossDomainMessenger - The LegacyMessagePasser contract cannot be used as entrypoint to bridge transactions from L2. The protocol // only allows the L2CrossDomainMessenger as the sole sender when relaying a bridged message. // 2. L2StandardBridge -func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2Metricer, l2Contracts config.L2Contracts, fromHeight, toHeight *big.Int) error { +func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2Metricer, preset int, l2Contracts config.L2Contracts, fromHeight, toHeight *big.Int) error { // (1) L2CrossDomainMessenger crossDomainSentMessages, err := contracts.CrossDomainMessengerSentMessageEvents("l2", l2Contracts.L2CrossDomainMessenger, db, fromHeight, toHeight) if err != nil { @@ -169,31 +166,45 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri withdrawnWEI := bigint.Zero sentMessages := make(map[logKey]sentMessageEvent, len(crossDomainSentMessages)) bridgeMessages := make([]database.L2BridgeMessage, len(crossDomainSentMessages)) + versionedMessageHashes := make([]database.L2BridgeMessageVersionedMessageHash, len(crossDomainSentMessages)) transactionWithdrawals := make([]database.L2TransactionWithdrawal, len(crossDomainSentMessages)) for i := range crossDomainSentMessages { sentMessage := crossDomainSentMessages[i] withdrawnWEI = new(big.Int).Add(withdrawnWEI, sentMessage.BridgeMessage.Tx.Amount) - // We re-use the L2CrossDomainMessenger message hash as the withdrawal hash to remain consistent in the schema. + // Since these message can be relayed in bedrock, we utilize the migrated withdrawal hash + // and also store the v1 version of the message hash such that the bedrock l1 finalization + // processor works as expected. There will be some entries relayed pre-bedrock that will not + // require the entry but we'll store it anyways as a large % of these withdrawals are not relayed + // pre-bedrock. + + v1MessageHash, err := LegacyBridgeMessageV1MessageHash(&sentMessage.BridgeMessage) + if err != nil { + return fmt.Errorf("failed to compute versioned message hash: %w", err) + } + + withdrawalHash, err := LegacyBridgeMessageWithdrawalHash(preset, &sentMessage.BridgeMessage) + if err != nil { + return fmt.Errorf("failed to construct migrated withdrawal hash: %w", err) + } + transactionWithdrawals[i] = database.L2TransactionWithdrawal{ - WithdrawalHash: sentMessage.BridgeMessage.MessageHash, + WithdrawalHash: withdrawalHash, InitiatedL2EventGUID: sentMessage.Event.GUID, Nonce: sentMessage.BridgeMessage.Nonce, GasLimit: sentMessage.BridgeMessage.GasLimit, Tx: database.Transaction{ FromAddress: sentMessage.BridgeMessage.Tx.FromAddress, ToAddress: sentMessage.BridgeMessage.Tx.ToAddress, - Amount: big.NewInt(0), + Amount: bigint.Zero, Data: sentMessage.BridgeMessage.Tx.Data, Timestamp: sentMessage.Event.Timestamp, }, } - sentMessages[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex}] = sentMessageEvent{&sentMessage, sentMessage.BridgeMessage.MessageHash} - bridgeMessages[i] = database.L2BridgeMessage{ - TransactionWithdrawalHash: sentMessage.BridgeMessage.MessageHash, - BridgeMessage: sentMessage.BridgeMessage, - } + sentMessages[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex}] = sentMessageEvent{&sentMessage, withdrawalHash} + bridgeMessages[i] = database.L2BridgeMessage{TransactionWithdrawalHash: withdrawalHash, BridgeMessage: sentMessage.BridgeMessage} + versionedMessageHashes[i] = database.L2BridgeMessageVersionedMessageHash{MessageHash: sentMessage.BridgeMessage.MessageHash, V1MessageHash: v1MessageHash} } if len(bridgeMessages) > 0 { if err := db.BridgeTransactions.StoreL2TransactionWithdrawals(transactionWithdrawals); err != nil { @@ -202,6 +213,9 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri if err := db.BridgeMessages.StoreL2BridgeMessages(bridgeMessages); err != nil { return err } + if err := db.BridgeMessages.StoreL2BridgeMessageV1MessageHashes(versionedMessageHashes); err != nil { + return err + } withdrawnETH, _ := bigint.WeiToETH(withdrawnWEI).Float64() metrics.RecordL2TransactionWithdrawals(len(transactionWithdrawals), withdrawnETH) @@ -227,11 +241,9 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri // - Event Flow: TransactionEnqueued -> SentMessage -> DepositInitiated sentMessage, ok := sentMessages[logKey{initiatedBridge.Event.BlockHash, initiatedBridge.Event.LogIndex - 1}] if !ok { - log.Error("expected SentMessage preceding BridgeInitiated event", "tx_hash", initiatedBridge.Event.TransactionHash.String()) return fmt.Errorf("expected SentMessage preceding BridgeInitiated event. tx_hash = %s", initiatedBridge.Event.TransactionHash) } else if sentMessage.Event.TransactionHash != initiatedBridge.Event.TransactionHash { - log.Error("correlated events tx hash mismatch", "message_tx_hash", sentMessage.Event.TransactionHash.String(), "bridge_tx_hash", initiatedBridge.Event.TransactionHash.String()) - return fmt.Errorf("correlated events tx hash mismatch") + return fmt.Errorf("correlated events tx hash mismatch. bridge_tx_hash = %s, message_tx_hash = %s", initiatedBridge.Event.TransactionHash, sentMessage.Event.TransactionHash) } bridgedTokens[initiatedBridge.BridgeTransfer.TokenPair.LocalTokenAddress]++ @@ -260,7 +272,7 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri // according to the pre-bedrock protocol. This follows: // 1. L1CrossDomainMessenger // 2. L1StandardBridge -func LegacyL1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1Metricer, l1Client node.EthClient, l1Contracts config.L1Contracts, fromHeight, toHeight *big.Int) error { +func LegacyL1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1Metricer, l1Contracts config.L1Contracts, fromHeight, toHeight *big.Int) error { // (1) L1CrossDomainMessenger -> This is the root-most contract from which bridge events are finalized since withdrawals must be initiated from the // L2CrossDomainMessenger. Since there's no two-step withdrawal process, we mark the transaction as proven/finalized in the same step crossDomainRelayedMessages, err := contracts.CrossDomainMessengerRelayedMessageEvents("l1", l1Contracts.L1CrossDomainMessengerProxy, db, fromHeight, toHeight) @@ -271,66 +283,39 @@ func LegacyL1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metri log.Info("detected relayed messages", "size", len(crossDomainRelayedMessages)) } - skippedPreRegenesisMessages := 0 + skippedOVM1Messages := 0 for i := range crossDomainRelayedMessages { relayedMessage := crossDomainRelayedMessages[i] message, err := db.BridgeMessages.L2BridgeMessage(relayedMessage.MessageHash) if err != nil { return err } else if message == nil { - // Before surfacing an error about a missing withdrawal, we need to handle an edge case - // for OP-Mainnet pre-regensis withdrawals that no longer exist on L2. - tx, err := l1Client.TxByHash(relayedMessage.Event.TransactionHash) - if err != nil { - log.Error("unable to query legacy relayed tx", "tx_hash", relayedMessage.Event.TransactionHash.String(), "err", err) - return fmt.Errorf("unable to query legacy relayed tx_hash = %s: %w", relayedMessage.Event.TransactionHash.String(), err) - } else if tx == nil { - log.Error("missing tx for relayed message", "tx_hash", relayedMessage.Event.TransactionHash.String()) - return fmt.Errorf("missing tx for relayed message. tx_hash = %s", relayedMessage.Event.TransactionHash.String()) - } - - relayMessageData := tx.Data()[4:] - inputs, err := contracts.CrossDomainMessengerLegacyRelayMessageEncoding.Inputs.Unpack(relayMessageData) - if err != nil || inputs == nil { - log.Error("failed to extract XDomainCallData from relayMessage transaction", "err", err, "tx_hash", relayedMessage.Event.TransactionHash.String()) - return fmt.Errorf("unable to extract XDomainCallData from relayMessage transaction. err = %w. tx_hash = %s", err, relayedMessage.Event.TransactionHash.String()) - } - - // NOTE: Since OP-Mainnet is the only network to go through a regensis we can simply harcode the - // the starting message nonce at genesis (100k). Any relayed withdrawal on L1 with a lesser nonce - // is a clear indicator of a pre-regenesis withdrawal. - if inputs[3].(*big.Int).Int64() < 100_000 { - // skip pre-regenesis withdrawals - skippedPreRegenesisMessages++ + if _, ok := ovm1.L1RelayedMessages[relayedMessage.MessageHash]; ok { + skippedOVM1Messages++ continue - } else { - log.Error("missing indexed legacy L2CrossDomainMessenger message", "tx_hash", relayedMessage.Event.TransactionHash.String()) - return fmt.Errorf("missing indexed L2CrossDomainMessager message. tx_hash %s", relayedMessage.Event.TransactionHash.String()) } + + return fmt.Errorf("missing indexed L2CrossDomainMessenger message! tx_hash %s", relayedMessage.Event.TransactionHash.String()) } - // Mark the associated tx withdrawal as proven/finalized with the same event. The message hash is also the transaction withdrawal hash - if err := db.BridgeTransactions.MarkL2TransactionWithdrawalProvenEvent(relayedMessage.MessageHash, relayedMessage.Event.GUID); err != nil { - log.Error("failed to mark withdrawal as proven", "err", err) - return err + if err := db.BridgeMessages.MarkRelayedL2BridgeMessage(relayedMessage.MessageHash, relayedMessage.Event.GUID); err != nil { + return fmt.Errorf("failed to relay cross domain message. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err) } - if err := db.BridgeTransactions.MarkL2TransactionWithdrawalFinalizedEvent(relayedMessage.MessageHash, relayedMessage.Event.GUID, true); err != nil { - log.Error("failed to mark withdrawal as finalzed", "err", err) - return err + + // Mark the associated tx withdrawal as proven/finalized with the same event. + if err := db.BridgeTransactions.MarkL2TransactionWithdrawalProvenEvent(message.TransactionWithdrawalHash, relayedMessage.Event.GUID); err != nil { + return fmt.Errorf("failed to mark withdrawal as proven. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err) } - if err := db.BridgeMessages.MarkRelayedL2BridgeMessage(relayedMessage.MessageHash, relayedMessage.Event.GUID); err != nil { - log.Error("failed to relay cross domain message", "err", err) - return err + if err := db.BridgeTransactions.MarkL2TransactionWithdrawalFinalizedEvent(message.TransactionWithdrawalHash, relayedMessage.Event.GUID, true); err != nil { + return fmt.Errorf("failed to mark withdrawal as finalized. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err) } } if len(crossDomainRelayedMessages) > 0 { - metrics.RecordL1ProvenWithdrawals(len(crossDomainRelayedMessages)) - metrics.RecordL1FinalizedWithdrawals(len(crossDomainRelayedMessages)) metrics.RecordL1CrossDomainRelayedMessages(len(crossDomainRelayedMessages)) - } - if skippedPreRegenesisMessages > 0 { - // Logged as a warning just for visibility - log.Warn("skipped pre-regensis relayed L2CrossDomainMessenger withdrawals", "size", skippedPreRegenesisMessages) + if skippedOVM1Messages > 0 { // Logged as a warning just for visibility + metrics.RecordL1SkippedOVM1CrossDomainRelayedMessages(skippedOVM1Messages) + log.Info("skipped OVM 1.0 relayed L2CrossDomainMessenger withdrawals", "size", skippedOVM1Messages) + } } // (2) L1StandardBridge @@ -364,13 +349,11 @@ func LegacyL2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metri if err != nil { return err } else if message == nil { - log.Error("missing indexed legacy L1CrossDomainMessenger message", "tx_hash", relayedMessage.Event.TransactionHash.String()) - return fmt.Errorf("missing indexed L1CrossDomainMessager message. tx_hash = %s", relayedMessage.Event.TransactionHash.String()) + return fmt.Errorf("missing indexed L1CrossDomainMessager message! tx_hash = %s", relayedMessage.Event.TransactionHash) } if err := db.BridgeMessages.MarkRelayedL1BridgeMessage(relayedMessage.MessageHash, relayedMessage.Event.GUID); err != nil { - log.Error("failed to relay cross domain message", "err", err) - return err + return fmt.Errorf("failed to relay cross domain message: %w", err) } } if len(crossDomainRelayedMessages) > 0 { @@ -387,3 +370,27 @@ func LegacyL2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metri // a-ok! return nil } + +// Utils + +func LegacyBridgeMessageWithdrawalHash(preset int, msg *database.BridgeMessage) (common.Hash, error) { + l1Cdm := config.Presets[preset].ChainConfig.L1Contracts.L1CrossDomainMessengerProxy + legacyWithdrawal := crossdomain.NewLegacyWithdrawal(predeploys.L2CrossDomainMessengerAddr, msg.Tx.ToAddress, msg.Tx.FromAddress, msg.Tx.Data, msg.Nonce) + migratedWithdrawal, err := crossdomain.MigrateWithdrawal(legacyWithdrawal, &l1Cdm, big.NewInt(int64(preset))) + if err != nil { + return common.Hash{}, err + } + + return migratedWithdrawal.Hash() +} + +func LegacyBridgeMessageV1MessageHash(msg *database.BridgeMessage) (common.Hash, error) { + legacyWithdrawal := crossdomain.NewLegacyWithdrawal(predeploys.L2CrossDomainMessengerAddr, msg.Tx.ToAddress, msg.Tx.FromAddress, msg.Tx.Data, msg.Nonce) + value, err := legacyWithdrawal.Value() + if err != nil { + return common.Hash{}, fmt.Errorf("failed to extract ETH value from legacy bridge message: %w", err) + } + + // Note: GasLimit is always zero. Only the GasLimit for the withdrawal transaction was migrated + return crossdomain.HashCrossDomainMessageV1(msg.Nonce, msg.Tx.FromAddress, msg.Tx.ToAddress, value, new(big.Int), msg.Tx.Data) +} diff --git a/indexer/processors/bridge/legacy_bridge_processor_test.go b/indexer/processors/bridge/legacy_bridge_processor_test.go new file mode 100644 index 000000000000..b85eeb477812 --- /dev/null +++ b/indexer/processors/bridge/legacy_bridge_processor_test.go @@ -0,0 +1,85 @@ +package bridge + +import ( + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/indexer/bigint" + "github.com/ethereum-optimism/optimism/indexer/database" + "github.com/ethereum-optimism/optimism/indexer/processors/contracts" + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/stretchr/testify/require" +) + +func TestLegacyWithdrawalAndMessageHash(t *testing.T) { + // Pre-Bedrock OP-Goerli withdrawal that was proven post-bedrock + // - L1 proven withdrawal tx: 0xa8853a3532f40052385602c66512e438bc1e3736d3cb7abde359f5b9377441c7 + value := bigint.Zero + expectedWithdrawalHash := common.HexToHash("0xae99d25df3e38730f6ee6588733417e20a131923b84870be6aedb4f863b6302d") + + // Ensure the L2 Tx which correlates with the above proven withdrawal results in the same computed withdrawal hash + // - L2 withdrawal tx: 0x254d9c28add020404142f840ed794cea51f86c0f0a737e3e7bdd7e1e4550962e + abi, err := bindings.CrossDomainMessengerMetaData.GetAbi() + require.NoError(t, err) + + var sentMessage bindings.CrossDomainMessengerSentMessage + sentMessageEvent := abi.Events["SentMessage"] + logData := common.FromHex("0x0000000000000000000000004200000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4a9f9e67500000000000000000000000007865c6e87b9f70255377e024ace6630c1eaa37f0000000000000000000000003b8e53b3ab8e01fb57d0c9e893bc4d655aa67d84000000000000000000000000b91882244f7f82540f2941a759724523c7b9a166000000000000000000000000b91882244f7f82540f2941a759724523c7b9a166000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") + require.NoError(t, contracts.UnpackLog(&sentMessage, &types.Log{Data: logData, Topics: []common.Hash{sentMessageEvent.ID, common.HexToHash("0x000000000000000000000000636af16bf2f682dd3109e60102b8e1a089fedaa8")}}, sentMessageEvent.Name, abi)) + + // timestamp and message hash are filled in fields. not core to the event + msg := database.BridgeMessage{ + Nonce: sentMessage.MessageNonce, + GasLimit: sentMessage.GasLimit, + Tx: database.Transaction{FromAddress: sentMessage.Sender, ToAddress: sentMessage.Target, Amount: value, Data: sentMessage.Message}, + } + + hash, err := LegacyBridgeMessageWithdrawalHash(420, &msg) + require.NoError(t, err) + require.Equal(t, expectedWithdrawalHash, hash) + + // Ensure the relayed message hash (v1) matches + expectedMessageHash := common.HexToHash("0xcb16ecc1967f5d7aed909349a4351d28fbb396429ef7faf1c9d2a670e3ca906f") + v1MessageHash, err := LegacyBridgeMessageV1MessageHash(&msg) + require.NoError(t, err) + require.Equal(t, expectedMessageHash, v1MessageHash) + + // OP Mainnet hashes to also check for + // - since the message hash doesn't depend on the preset, we only need to check for the withdrawal hash + + expectedWithdrawalHash = common.HexToHash("0x9c0bc28a77328a405f21d51a32d32f038ebf7ce70e377ca48b2cd194ec024f15") + msg = database.BridgeMessage{ + Nonce: big.NewInt(100180), + GasLimit: bigint.Zero, + Tx: database.Transaction{ + FromAddress: common.HexToAddress("0x4200000000000000000000000000000000000010"), + ToAddress: common.HexToAddress("0x99c9fc46f92e8a1c0dec1b1747d010903e884be1"), + Amount: bigint.Zero, + Data: common.FromHex("0x1532ec34000000000000000000000000094a9009fe93a85658e4b49604fd8177620f8cd8000000000000000000000000094a9009fe93a85658e4b49604fd8177620f8cd8000000000000000000000000000000000000000000000000013abb2a2774ab0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000"), + }, + } + + hash, err = LegacyBridgeMessageWithdrawalHash(10, &msg) + require.NoError(t, err) + require.Equal(t, expectedWithdrawalHash, hash) + + expectedWithdrawalHash = common.HexToHash("0xeb1dd5ead967ad6860d64407413f86e50330ab123ca9adf2768145524c3f5323") + msg = database.BridgeMessage{ + Nonce: big.NewInt(100618), + GasLimit: bigint.Zero, + Tx: database.Transaction{ + FromAddress: common.HexToAddress("0x4200000000000000000000000000000000000010"), + ToAddress: common.HexToAddress("0x99c9fc46f92e8a1c0dec1b1747d010903e884be1"), + Amount: bigint.Zero, + Data: common.FromHex("0xa9f9e67500000000000000000000000028e1de268616a6ba0de59717ac5547589e6bb1180000000000000000000000003ef241d9ae02f2253d8a1bf0b35d68eab9925b400000000000000000000000003e579180cf01f0e2abf6ff4d566b7891fbf9b8680000000000000000000000003e579180cf01f0e2abf6ff4d566b7891fbf9b868000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000"), + }, + } + + hash, err = LegacyBridgeMessageWithdrawalHash(10, &msg) + require.NoError(t, err) + require.Equal(t, expectedWithdrawalHash, hash) +} diff --git a/indexer/processors/bridge/metrics.go b/indexer/processors/bridge/metrics.go index 5d8711642c1c..564658700272 100644 --- a/indexer/processors/bridge/metrics.go +++ b/indexer/processors/bridge/metrics.go @@ -14,7 +14,9 @@ var ( ) type L1Metricer interface { - RecordLatestIndexedL1Height(height *big.Int) + RecordL1Interval() (done func(err error)) + RecordL1LatestHeight(height *big.Int) + RecordL1LatestFinalizedHeight(height *big.Int) RecordL1TransactionDeposits(size int, mintedETH float64) RecordL1ProvenWithdrawals(size int) @@ -23,12 +25,18 @@ type L1Metricer interface { RecordL1CrossDomainSentMessages(size int) RecordL1CrossDomainRelayedMessages(size int) + RecordL1SkippedOVM1ProvenWithdrawals(size int) + RecordL1SkippedOVM1FinalizedWithdrawals(size int) + RecordL1SkippedOVM1CrossDomainRelayedMessages(size int) + RecordL1InitiatedBridgeTransfers(token common.Address, size int) RecordL1FinalizedBridgeTransfers(token common.Address, size int) } type L2Metricer interface { - RecordLatestIndexedL2Height(height *big.Int) + RecordL2Interval() (done func(err error)) + RecordL2LatestHeight(height *big.Int) + RecordL2LatestFinalizedHeight(height *big.Int) RecordL2TransactionWithdrawals(size int, withdrawnETH float64) @@ -42,28 +50,29 @@ type L2Metricer interface { type Metricer interface { L1Metricer L2Metricer - - RecordInterval() (done func(err error)) } type bridgeMetrics struct { - intervalTick prometheus.Counter - intervalDuration prometheus.Histogram - intervalFailures prometheus.Counter + latestHeight *prometheus.GaugeVec - latestL1Height prometheus.Gauge - latestL2Height prometheus.Gauge + intervalTick *prometheus.CounterVec + intervalDuration *prometheus.HistogramVec + intervalFailures *prometheus.CounterVec txDeposits prometheus.Counter - txMintedETH prometheus.Counter txWithdrawals prometheus.Counter - txWithdrawnETH prometheus.Counter provenWithdrawals prometheus.Counter finalizedWithdrawals prometheus.Counter + txMintedETH prometheus.Counter + txWithdrawnETH prometheus.Counter + sentMessages *prometheus.CounterVec relayedMessages *prometheus.CounterVec + skippedOVM1Withdrawals *prometheus.CounterVec + skippedOVM1RelayedMessages prometheus.Counter + initiatedBridgeTransfers *prometheus.CounterVec finalizedBridgeTransfers *prometheus.CounterVec } @@ -71,32 +80,34 @@ type bridgeMetrics struct { func NewMetrics(registry *prometheus.Registry) Metricer { factory := metrics.With(registry) return &bridgeMetrics{ - intervalTick: factory.NewCounter(prometheus.CounterOpts{ + intervalTick: factory.NewCounterVec(prometheus.CounterOpts{ Namespace: MetricsNamespace, Name: "intervals_total", Help: "number of times processing loop has run", + }, []string{ + "chain", }), - intervalDuration: factory.NewHistogram(prometheus.HistogramOpts{ + intervalDuration: factory.NewHistogramVec(prometheus.HistogramOpts{ Namespace: MetricsNamespace, Name: "interval_seconds", Help: "duration elapsed in the processing loop", + }, []string{ + "chain", }), - intervalFailures: factory.NewCounter(prometheus.CounterOpts{ + intervalFailures: factory.NewCounterVec(prometheus.CounterOpts{ Namespace: MetricsNamespace, Name: "interval_failures_total", Help: "number of failures encountered", + }, []string{ + "chain", }), - latestL1Height: factory.NewGauge(prometheus.GaugeOpts{ + latestHeight: factory.NewGaugeVec(prometheus.GaugeOpts{ Namespace: MetricsNamespace, - Subsystem: "l1", Name: "height", Help: "the latest processed l1 block height", - }), - latestL2Height: factory.NewGauge(prometheus.GaugeOpts{ - Namespace: MetricsNamespace, - Subsystem: "l2", - Name: "height", - Help: "the latest processed l2 block height", + }, []string{ + "chain", + "kind", }), txDeposits: factory.NewCounter(prometheus.CounterOpts{ Namespace: MetricsNamespace, @@ -111,7 +122,7 @@ func NewMetrics(registry *prometheus.Registry) Metricer { txWithdrawals: factory.NewCounter(prometheus.CounterOpts{ Namespace: MetricsNamespace, Name: "tx_withdrawals", - Help: "number of processed transactions withdrawn from l2", + Help: "number of initiated transaction withdrawals from l2", }), txWithdrawnETH: factory.NewCounter(prometheus.CounterOpts{ Namespace: MetricsNamespace, @@ -142,6 +153,18 @@ func NewMetrics(registry *prometheus.Registry) Metricer { }, []string{ "chain", }), + skippedOVM1Withdrawals: factory.NewCounterVec(prometheus.CounterOpts{ + Namespace: MetricsNamespace, + Name: "skipped_ovm1_withdrawals", + Help: "number of skipped ovm 1.0 withdrawals on l1 (proven|finalized)", + }, []string{ + "stage", + }), + skippedOVM1RelayedMessages: factory.NewCounter(prometheus.CounterOpts{ + Namespace: MetricsNamespace, + Name: "skipped_ovm1_relayed_messages", + Help: "number of skipped ovm 1.0 relayed messages on l1", + }), initiatedBridgeTransfers: factory.NewCounterVec(prometheus.CounterOpts{ Namespace: MetricsNamespace, Name: "initiated_token_transfers", @@ -161,21 +184,25 @@ func NewMetrics(registry *prometheus.Registry) Metricer { } } -func (m *bridgeMetrics) RecordInterval() func(error) { - m.intervalTick.Inc() - timer := prometheus.NewTimer(m.intervalDuration) +// L1Metricer + +func (m *bridgeMetrics) RecordL1Interval() func(error) { + m.intervalTick.WithLabelValues("l1").Inc() + timer := prometheus.NewTimer(m.intervalDuration.WithLabelValues("l1")) return func(err error) { timer.ObserveDuration() if err != nil { - m.intervalFailures.Inc() + m.intervalFailures.WithLabelValues("l1").Inc() } } } -// L1Metricer +func (m *bridgeMetrics) RecordL1LatestHeight(height *big.Int) { + m.latestHeight.WithLabelValues("l1", "initiated").Set(float64(height.Uint64())) +} -func (m *bridgeMetrics) RecordLatestIndexedL1Height(height *big.Int) { - m.latestL1Height.Set(float64(height.Uint64())) +func (m *bridgeMetrics) RecordL1LatestFinalizedHeight(height *big.Int) { + m.latestHeight.WithLabelValues("l1", "finalized").Set(float64(height.Uint64())) } func (m *bridgeMetrics) RecordL1TransactionDeposits(size int, mintedETH float64) { @@ -199,6 +226,18 @@ func (m *bridgeMetrics) RecordL1CrossDomainRelayedMessages(size int) { m.relayedMessages.WithLabelValues("l1").Add(float64(size)) } +func (m *bridgeMetrics) RecordL1SkippedOVM1ProvenWithdrawals(size int) { + m.skippedOVM1Withdrawals.WithLabelValues("proven").Add(float64(size)) +} + +func (m *bridgeMetrics) RecordL1SkippedOVM1FinalizedWithdrawals(size int) { + m.skippedOVM1Withdrawals.WithLabelValues("finalized").Add(float64(size)) +} + +func (m *bridgeMetrics) RecordL1SkippedOVM1CrossDomainRelayedMessages(size int) { + m.skippedOVM1RelayedMessages.Add(float64(size)) +} + func (m *bridgeMetrics) RecordL1InitiatedBridgeTransfers(tokenAddr common.Address, size int) { m.initiatedBridgeTransfers.WithLabelValues("l1", tokenAddr.String()).Add(float64(size)) } @@ -209,8 +248,23 @@ func (m *bridgeMetrics) RecordL1FinalizedBridgeTransfers(tokenAddr common.Addres // L2Metricer -func (m *bridgeMetrics) RecordLatestIndexedL2Height(height *big.Int) { - m.latestL2Height.Set(float64(height.Uint64())) +func (m *bridgeMetrics) RecordL2Interval() func(error) { + m.intervalTick.WithLabelValues("l2").Inc() + timer := prometheus.NewTimer(m.intervalDuration.WithLabelValues("l2")) + return func(err error) { + timer.ObserveDuration() + if err != nil { + m.intervalFailures.WithLabelValues("l2").Inc() + } + } +} + +func (m *bridgeMetrics) RecordL2LatestHeight(height *big.Int) { + m.latestHeight.WithLabelValues("l2", "initiated").Set(float64(height.Uint64())) +} + +func (m *bridgeMetrics) RecordL2LatestFinalizedHeight(height *big.Int) { + m.latestHeight.WithLabelValues("l2", "finalized").Set(float64(height.Uint64())) } func (m *bridgeMetrics) RecordL2TransactionWithdrawals(size int, withdrawnETH float64) { diff --git a/indexer/processors/bridge/ovm1/OVM1Withdrawals.csv b/indexer/processors/bridge/ovm1/OVM1Withdrawals.csv new file mode 100644 index 000000000000..20e6a9d26d38 --- /dev/null +++ b/indexer/processors/bridge/ovm1/OVM1Withdrawals.csv @@ -0,0 +1,11311 @@ +message_nonce,target,sender,data,relay_tx_hash,relay_timestamp,relay_message_version,post_regenesis_relay +54,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2317a30fbb53f328cc11324ab37337a28e73b84000000000000000000000000b2317a30fbb53f328cc11324ab37337a28e73b84000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +55,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000024e6cc41da6081bda289e6f589825f9ee7b00b200000000000000000000000000000000000000000000000041dedad6365b4017f,,,1,true +59,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000078edd760ff5b5b4604fb338d3cf7b6d5355c7ec00000000000000000000000000000000000000000000000580b5a096b8ce545d,,,1,true +64,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007244a3012d4363249326997f57909b61b6f5805c00000000000000000000000000000000000000000000000019c541b06cfb2524,,,1,true +92,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000fb6351b09a52db13d9255caaf0a12aff16ad973f000000000000000000000000000000000000000000000003b6c46a04ba030000,,,1,true +94,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3bbf6bfe155b1444d15a585ad1bea862ea9e29a000000000000000000000000c3bbf6bfe155b1444d15a585ad1bea862ea9e29a0000000000000000000000000000000000000000000000000000999c6cd7580000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +96,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d16d160ff95e492371eac5da4bf255806c088990000000000000000000000000000000000000000000000001668140a182aa8000,0x7da33b3858b471a78e8f32ff11bfaf207c7cf9966668d735e520482c90bcb410,2022-03-15 06:26:18.000 UTC,0,true +100,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000965555ae227348c6df04562805a538a395c42703000000000000000000000000000000000000000000000002ab7b260ff3fd0000,,,1,true +106,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008a8ea94f6e6fb36a863f63735ee7d1b5f03ea8160000000000000000000000000000000000000000000000056bc75e2d63100000,,,1,true +108,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000375c4952dfe5d5f0eae142f73cf8138ad496a722000000000000000000000000375c4952dfe5d5f0eae142f73cf8138ad496a722000000000000000000000000000000000000000000000000004380663abb800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +112,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d15472d58e1bf8fbfa4a9f87c5f3d4108d965b8f0000000000000000000000000000000000000000000000061f7c830b5c31981c,0xf71a79bb5601b4a889f8bc9df0135d59e4d197c8ccbb3585763a2a25bb6d54a7,2022-01-29 10:28:18.000 UTC,0,true +113,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d15472d58e1bf8fbfa4a9f87c5f3d4108d965b8f0000000000000000000000000000000000000000000000097f78f7ab6d34819f,0xaf946677090eb896aa8f7dc7887c22e86b1bbd8b951810efd615a31805bfcbb8,2022-01-29 10:26:21.000 UTC,0,true +122,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000088b74128df7cb82eb7c2167e89946f83ffc907e90000000000000000000000000000000000000000000000004bf720dbaf1d8000,,,1,true +127,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000754bdb78a3c01afc52f96f1982d04bc181ab0c730000000000000000000000000000000000000000000000000e35fa931a000000,,,1,true +134,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000005f45f8296be3f38119d0c56ad339f6bf66154b9b000000000000000000000000000000000000000000000000858cdd756176e000,,,1,true +138,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c8462eeeed1fe256c62f89678ebd6dcc1b04690e000000000000000000000000000000000000000000000001fd78d0905cf5b4d4,,,1,true +141,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e39fef30d17b45e7789812234ac4efc803ee96a8000000000000000000000000000000000000000000000002cf03207879168000,,,1,true +142,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000bc07f994bd3d83cddd732bc50b57a810036ddf30000000000000000000000000bc07f994bd3d83cddd732bc50b57a810036ddf30000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f196bba501bd8b6bfbe230dd6db39a93c72cb4f8000000000000000000000000f196bba501bd8b6bfbe230dd6db39a93c72cb4f80000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000068f180fcce6836688e9084f035309e29bf0a2095000000000000000000000000bc07f994bd3d83cddd732bc50b57a810036ddf30000000000000000000000000bc07f994bd3d83cddd732bc50b57a810036ddf3000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +158,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007c1908d49266ba2999c41b07b0895c33821f53a9000000000000000000000000000000000000000000000066ffcbfd5e5a300000,0xf535c5a9b784c3b17dc2a39cc94af42b017d5d648769dcf26b5041905d90a8d9,2022-01-25 02:16:14.000 UTC,0,true +160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000399bbde115cb626d8dafaf2e79a1373c96fc3dca000000000000000000000000399bbde115cb626d8dafaf2e79a1373c96fc3dca00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7f4a04c736cc1c5857231417e6cb8da9cadbec7000000000000000000000000d7f4a04c736cc1c5857231417e6cb8da9cadbec7000000000000000000000000000000000000000000000000001930514375200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +165,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abe26faee77419897090bc4c5a112d463443a662000000000000000000000000abe26faee77419897090bc4c5a112d463443a662000000000000000000000000000000000000000000000000000051dac207a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +167,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d0dff694dafd006a955ca2fce7a018d3aaac08f2000000000000000000000000d0dff694dafd006a955ca2fce7a018d3aaac08f20000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +169,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abe3bf5043ed0833d3da5148cd58d0f946891e61000000000000000000000000abe3bf5043ed0833d3da5148cd58d0f946891e610000000000000000000000000000000000000000000000000dde1037c52af00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +170,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019ac702381fdf8b63b04a990fb39e7bde92c97b000000000000000000000000019ac702381fdf8b63b04a990fb39e7bde92c97b0000000000000000000000000000000000000000000000000000ffcb9e57d400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab91a2449ff8e2836c02ca03a496bcef69d99f88000000000000000000000000ab91a2449ff8e2836c02ca03a496bcef69d99f880000000000000000000000000000000000000000000000000021c0331d5dc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +176,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c8462eeeed1fe256c62f89678ebd6dcc1b04690e000000000000000000000000000000000000000000000000b8156773856431aa,,,1,true +177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4569a42140eeb4ff9c31fea691fce2b6f974481000000000000000000000000e4569a42140eeb4ff9c31fea691fce2b6f974481000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fe30b7c0ed489493a42a8bc43b8a73ca72f67350000000000000000000000005fe30b7c0ed489493a42a8bc43b8a73ca72f6735000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b04336a8d37b7b1edc5db0b8f46918160df14ba2000000000000000000000000b04336a8d37b7b1edc5db0b8f46918160df14ba2000000000000000000000000000000000000000000000000000ffcb9e57d400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000580a5b2f32bd14af9da1e01ef41feb754f78c350000000000000000000000000580a5b2f32bd14af9da1e01ef41feb754f78c35000000000000000000000000000000000000000000000000000f6e9e1bbe3c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd90ad81ad93d9af1008a513d964f6fbc589034d000000000000000000000000fd90ad81ad93d9af1008a513d964f6fbc589034d000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9f96e8b78b3de62d164887e49a0c7b4c9a36d0944dae63333a9ccbdc41aaee84,2022-06-28 01:56:15.000 UTC,0,true +184,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c127c110ceade7370c8b327287f2a669ec7e93ba000000000000000000000000c127c110ceade7370c8b327287f2a669ec7e93ba000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc02bb12596ed3679c0d2e0d449bd61931d7f5c7000000000000000000000000cc02bb12596ed3679c0d2e0d449bd61931d7f5c700000000000000000000000000000000000000000000000000138a388a43c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +188,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000856b63349fb6c818ea7cd7305483ae0ef6956f6c000000000000000000000000856b63349fb6c818ea7cd7305483ae0ef6956f6c000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +191,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7258ec040748652576ffb447b228272b87ade4a000000000000000000000000a7258ec040748652576ffb447b228272b87ade4a000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +193,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba0c565110f65d181b9ff1d8a9f787b52857bb0c000000000000000000000000ba0c565110f65d181b9ff1d8a9f787b52857bb0c0000000000000000000000000000000000000000000000000013bc2edbd21c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +195,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001b001f4b78c511d3260bfa538d4a117cd30d55700000000000000000000000001b001f4b78c511d3260bfa538d4a117cd30d5570000000000000000000000000000000000000000000000000012738915d842bf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +196,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000068f180fcce6836688e9084f035309e29bf0a209500000000000000000000000069dc97ad2dc7b179bff12a6eadabf3685d52845e00000000000000000000000069dc97ad2dc7b179bff12a6eadabf3685d52845e000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +198,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006875d9b42502c79917910b0fc00c6a5a27f1fc6800000000000000000000000000000000000000000000000745b2dd303ca25a32,,,1,true +199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004678cb6580b20bd4340fb5269e91af3e921180d80000000000000000000000004678cb6580b20bd4340fb5269e91af3e921180d800000000000000000000000000000000000000000000000002e654d9e53e2b8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +201,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002e0dadd0174bb9f4099b3e04e4a2300de2893b0b0000000000000000000000000000000000000000000000131c31ed18c2068178,,,1,true +213,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000fb5e8a587733e1a8700e1d448f97a12bab4ad4ea00000000000000000000000000000000000000000000000032423e6918e514cc,,,1,true +214,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000fb5e8a587733e1a8700e1d448f97a12bab4ad4ea00000000000000000000000000000000000000000000000000f7855dcff405ec,,,1,true +216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000816a684f40b8b4b060a4df7a10cad589ef64e95e000000000000000000000000816a684f40b8b4b060a4df7a10cad589ef64e95e000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b34b95fe3d018f6047d6ff65b2b6cfc85bd29160000000000000000000000009b34b95fe3d018f6047d6ff65b2b6cfc85bd291600000000000000000000000000000000000000000000000001550f7dca70000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f28d4face9315ec0343d69e28b90712cb9aca453000000000000000000000000f28d4face9315ec0343d69e28b90712cb9aca453000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000828355119398b77d364f41ef6533dad936d5b5c1000000000000000000000000828355119398b77d364f41ef6533dad936d5b5c100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +229,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000b4a6b88dc7dbe1b437a40bf1637961b0d865871c000000000000000000000000b4a6b88dc7dbe1b437a40bf1637961b0d865871c00000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +230,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000289922fbbfbd38472d7e2a1652b33b834f7c0e49000000000000000000000000289922fbbfbd38472d7e2a1652b33b834f7c0e490000000000000000000000000000000000000000000000000c7d713b49da000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +231,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e5479903febb574aae0442c5434897d6825d9977000000000000000000000000e5479903febb574aae0442c5434897d6825d99770000000000000000000000000000000000000000000000000000000000e8413700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013711b99539d2860aa740c0180a50627d538c28e00000000000000000000000013711b99539d2860aa740c0180a50627d538c28e00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe227d786571d6544f07da9bd0e22f28166fe11f15b3aa401c3e6df1e4e8933a2,2021-12-28 06:33:53.000 UTC,0,true +236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca1fd44348eb3ffde505346e6a813c2f33c4b816000000000000000000000000ca1fd44348eb3ffde505346e6a813c2f33c4b816000000000000000000000000000000000000000000000000005543df729c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +244,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000260d2fb8c006d2ec9b9fa7b41f3f01f981a0adc5000000000000000000000000260d2fb8c006d2ec9b9fa7b41f3f01f981a0adc50000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031760f7cbd0a5a506c8b5822a1555b16c087f35b00000000000000000000000031760f7cbd0a5a506c8b5822a1555b16c087f35b00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039258caa0f56db9c9e26f3631586b424f0a6477300000000000000000000000039258caa0f56db9c9e26f3631586b424f0a64773000000000000000000000000000000000000000000000000000d0dc7821234b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e64cbca254788df4a8d29e3721d077d91d0d92a0000000000000000000000000e64cbca254788df4a8d29e3721d077d91d0d92a000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +252,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000005d6ea8c76ab5d7366578f4b36d798cc37219dc240000000000000000000000005d6ea8c76ab5d7366578f4b36d798cc37219dc240000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090a7b41610a25f7bf538bd27dc6e0434bd38933200000000000000000000000090a7b41610a25f7bf538bd27dc6e0434bd3893320000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a27dbbff05f36dc927137855e3381f0c20c1cdd0000000000000000000000005a27dbbff05f36dc927137855e3381f0c20c1cdd000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8fb6023652e27efa476745645e947b4bd3d12486bc37d301c166cb48aab63c1d,2021-12-31 23:34:04.000 UTC,0,true +264,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000912190dcb9dbd95106f3859e1d08ef290084d690000000000000000000000000912190dcb9dbd95106f3859e1d08ef290084d690000000000000000000000000000000000000000000000001a055690d9db8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b45e2b252969394a48e46616378f19b1f1f32bdd000000000000000000000000b45e2b252969394a48e46616378f19b1f1f32bdd000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000a3730477c3eb009d2dc4fc87ab2b1265251ed3be000000000000000000000000a3730477c3eb009d2dc4fc87ab2b1265251ed3be00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000070ba90062e0d6c89fe7c46074f20efd57a7557ef00000000000000000000000070ba90062e0d6c89fe7c46074f20efd57a7557ef00000000000000000000000000000000000000000000000000000000001e8bba00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +273,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000353a3b43d34247cbc3f8092187cdd849b5b31a77000000000000000000000000353a3b43d34247cbc3f8092187cdd849b5b31a770000000000000000000000000000000000000000000000000214e8348c4f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000075d4bdbf6593ed463e9625694272a0ff9a6d346f00000000000000000000000075d4bdbf6593ed463e9625694272a0ff9a6d346f0000000000000000000000000000000000000000000000000000000016ea135300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xb171cf2697c4858dcf9c3834fe0a02579067214bee40af96018c3d43c14f8675,2022-04-05 01:35:36.000 UTC,0,true +279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0004c86b1251b10c7bf4672ca2bc59247a99bf5000000000000000000000000f0004c86b1251b10c7bf4672ca2bc59247a99bf500000000000000000000000000000000000000000000000008807d578bb9440000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe7ce870d054c92c3483f25f07366e283104553f365c0909461c3b862b38eda53,2022-02-13 22:28:36.000 UTC,0,true +283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009534e4beb4f7e07bb88f4c6a067d666c29e1b4330000000000000000000000009534e4beb4f7e07bb88f4c6a067d666c29e1b433000000000000000000000000000000000000000000000000004115f16449000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5c161fcdac7d0d16e632626d815658983f583ea000000000000000000000000e5c161fcdac7d0d16e632626d815658983f583ea00000000000000000000000000000000000000000000000001f161421c8e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +289,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af4807d083287f205d897e6d00c6fde1bf0a241a000000000000000000000000af4807d083287f205d897e6d00c6fde1bf0a241a00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000063782e602106604145b60a64457f6e92fe2e6dd000000000000000000000000063782e602106604145b60a64457f6e92fe2e6dd0000000000000000000000000000000000000000000000000030950e55ca05a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +306,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004189a63be018f4e50d4f770314f1bf87d7d65c810000000000000000000000004189a63be018f4e50d4f770314f1bf87d7d65c810000000000000000000000000000000000000000000000041ef7e8dca25eaf6000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +307,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d346aaf41745f87e71c4f8af9647f4aab2c4c310000000000000000000000007d346aaf41745f87e71c4f8af9647f4aab2c4c31000000000000000000000000000000000000000000000000002ff293c2540fe600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +314,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a91c0df156a5f38aec0813d055aa0184fc478260000000000000000000000001a91c0df156a5f38aec0813d055aa0184fc4782600000000000000000000000000000000000000000000000000656b90ccad2f4e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +315,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e8b65b125afd293cdb2b496c4035ebf63e4d56a9000000000000000000000000e8b65b125afd293cdb2b496c4035ebf63e4d56a9000000000000000000000000000000000000000000000000846db28c6103bb2600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047b5ed2279478151d1631014aa90f876fec4a13600000000000000000000000047b5ed2279478151d1631014aa90f876fec4a136000000000000000000000000000000000000000000000000000c5630358fec7d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a59f7d6ac28e31715a76e949a805b7c1ae3ace50000000000000000000000002a59f7d6ac28e31715a76e949a805b7c1ae3ace500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +330,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a09b9febe45b40a1ab47c8cb323067161d6b9cb4000000000000000000000000a09b9febe45b40a1ab47c8cb323067161d6b9cb40000000000000000000000000000000000000000000000000c767bacdc9585a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +331,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027a557d1ab0a0f5dc9039aedee47ffcce6ca160400000000000000000000000027a557d1ab0a0f5dc9039aedee47ffcce6ca1604000000000000000000000000000000000000000000000000032ec990f8f8c30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +338,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058dc53f7175fdd30c70ab5717c6e91edd8aed01700000000000000000000000058dc53f7175fdd30c70ab5717c6e91edd8aed017000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000627b4c6e08eeb3712c24713f4eb561e3f33319c0000000000000000000000000627b4c6e08eeb3712c24713f4eb561e3f33319c0000000000000000000000000000000000000000000000000160ff79d502b10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +341,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000668540812466219a4cf9ef22151bb7e513010f17000000000000000000000000668540812466219a4cf9ef22151bb7e513010f170000000000000000000000000000000000000000000000000007224b9463672100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002079a46983c7e43ca9f26b3ce75f7baf78d8da170000000000000000000000002079a46983c7e43ca9f26b3ce75f7baf78d8da1700000000000000000000000000000000000000000000000000bd3648b1f6271a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +347,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032eec9f20f75442b3dc91279ff307e17c7a6d7e800000000000000000000000032eec9f20f75442b3dc91279ff307e17c7a6d7e8000000000000000000000000000000000000000000000000003e213d0c24066200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +349,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bd3fe6e83fec5a3f3dc99ebd1088cd0737eb82940000000000000000000000000000000000000000000000013e29f4dcdc610360,,,1,true +353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000601c6d9eff76ae8cd7bff5fc4900f20f6f80734f000000000000000000000000601c6d9eff76ae8cd7bff5fc4900f20f6f80734f000000000000000000000000000000000000000000000000455c201e31dbbd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +357,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ebaffbdc8c854f0aab0e7567d38541578ff3c047000000000000000000000000ebaffbdc8c854f0aab0e7567d38541578ff3c04700000000000000000000000000000000000000000000000000aaa2708f721c0100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +359,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b082ddfd74748b763f52f04558e5f814a56de67a00000000000000000000000000000000000000000000000b4ae9cf9d96b685b4,,,1,true +365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002eb96f3453c00517ef534aa172a18b385ecff9a60000000000000000000000002eb96f3453c00517ef534aa172a18b385ecff9a600000000000000000000000000000000000000000000000000ab82e6a86a13ae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa5b9a2dc716bd732c0633d576db4d9cceb36f55000000000000000000000000fa5b9a2dc716bd732c0633d576db4d9cceb36f5500000000000000000000000000000000000000000000000000309992eaa3ced800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000006b62e3d14992c702f136a84c95ee60b86fe822000000000000000000000000006b62e3d14992c702f136a84c95ee60b86fe82200000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033107b56647014f37375b8291a86409f81a148db00000000000000000000000033107b56647014f37375b8291a86409f81a148db00000000000000000000000000000000000000000000000002bc97d322f093fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +378,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c89d3625f581dfa803ff7c102b99b72efdc500c0000000000000000000000004c89d3625f581dfa803ff7c102b99b72efdc500c000000000000000000000000000000000000000000000000008a4a7f0a9da61f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +383,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ec800b12b4c2f4a88b59012c856bf9b727dbfecc0000000000000000000000000000000000000000000000000738cbbd18d8c417,,,1,true +386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac029a845c9c21bf2010b3769d0661fe7a696cf4000000000000000000000000ac029a845c9c21bf2010b3769d0661fe7a696cf40000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +388,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004409bc676c79a82f2319c72b204a349a96983d3600000000000000000000000000000000000000000000000bbc04f1385fb6ce3b,,,1,true +390,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001cd87070a7ca125c891c91d80ba148b1983ab62e0000000000000000000000001cd87070a7ca125c891c91d80ba148b1983ab62e000000000000000000000000000000000000000000000000008b9728c2e429c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +391,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000724b91be4efe9abf6d429528257b03f4acc84270000000000000000000000000724b91be4efe9abf6d429528257b03f4acc8427000000000000000000000000000000000000000000000000000ad3ec37a58a30800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033ea964bbda6dab2b4067e5ad82b132e5ba83eb200000000000000000000000033ea964bbda6dab2b4067e5ad82b132e5ba83eb200000000000000000000000000000000000000000000000000acbfcad808f97b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae8b31e6236bec753d01922bd7b6773287490c79000000000000000000000000ae8b31e6236bec753d01922bd7b6773287490c79000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e0ee214906cdaf22ed18cef730cf66ed4ae06420000000000000000000000001e0ee214906cdaf22ed18cef730cf66ed4ae064200000000000000000000000000000000000000000000000000d434498096afcd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d232c211c80c8ce716b884b8fcd784bb55e60530000000000000000000000002d232c211c80c8ce716b884b8fcd784bb55e60530000000000000000000000000000000000000000000000000008626851ab800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +402,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc03f894465e2b43be15a56918c4e298e2ee4be5000000000000000000000000fc03f894465e2b43be15a56918c4e298e2ee4be5000000000000000000000000000000000000000000000000000325cff345600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000897aaceb5620805a04b561c076ca49667d663238000000000000000000000000897aaceb5620805a04b561c076ca49667d66323800000000000000000000000000000000000000000000000000033302c9e0400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000cc0960243d099bcae96c0d1aeacdda01434d2ebc000000000000000000000000cc0960243d099bcae96c0d1aeacdda01434d2ebc000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xc8f77d7f04d24cb28453acd580e6c9672a09e54e8b6dff121541f6517e890d53,2022-05-13 20:38:58.000 UTC,0,true +410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc8a9dea9c4f9a8936cc9b4dad270635e76f1197000000000000000000000000fc8a9dea9c4f9a8936cc9b4dad270635e76f119700000000000000000000000000000000000000000000000001a313d48c855b9d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae8b31e6236bec753d01922bd7b6773287490c79000000000000000000000000ae8b31e6236bec753d01922bd7b6773287490c79000000000000000000000000000000000000000000000000013a240098815be200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d2fbb357c1017508f098d69ae7f19d63241d6560000000000000000000000009d2fbb357c1017508f098d69ae7f19d63241d6560000000000000000000000000000000000000000000000000005c1987b565b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +418,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d639c172c474d56ef85dae0431295466734c1970000000000000000000000001d639c172c474d56ef85dae0431295466734c1970000000000000000000000000000000000000000000000000003a2e68bb1e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a643bcc171e12448aa4202db2bfd4b008108a5a0000000000000000000000006a643bcc171e12448aa4202db2bfd4b008108a5a000000000000000000000000000000000000000000000000000401ba6660b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd0041184f9387a822216be34da1f4893ea7b426000000000000000000000000fd0041184f9387a822216be34da1f4893ea7b42600000000000000000000000000000000000000000000000000036674b409bec800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a68f7936d21439e9a5510628ce3dac6a4de79700000000000000000000000001a68f7936d21439e9a5510628ce3dac6a4de7970000000000000000000000000000000000000000000000000000134f491d4880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009aa1575e60d33cd8e750f3193bdfa7d5540fe1360000000000000000000000009aa1575e60d33cd8e750f3193bdfa7d5540fe1360000000000000000000000000000000000000000000000000001de83adaed97000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +423,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f2dc64360ebbe78c968338ed4baae1d141443400000000000000000000000004f2dc64360ebbe78c968338ed4baae1d1414434000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009512b8c1b63c9893258920b5998134a1261db85d0000000000000000000000009512b8c1b63c9893258920b5998134a1261db85d00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c8ac460603038da12ff2b6516d49929be9237939000000000000000000000000c8ac460603038da12ff2b6516d49929be923793900000000000000000000000000000000000000000000000000859d1923f388cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x645a8cb90a52ec276d592333f274536d358a1a32a9daff8cff3396c75910b163,2022-05-20 09:44:19.000 UTC,0,true +434,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c8ac460603038da12ff2b6516d49929be9237939000000000000000000000000c8ac460603038da12ff2b6516d49929be9237939000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efd67615d66e3819539021d40e155e1a6107f283000000000000000000000000efd67615d66e3819539021d40e155e1a6107f283000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d8c9e1104b01cc0354782c617ad0c523f19c1b2f000000000000000000000000d8c9e1104b01cc0354782c617ad0c523f19c1b2f000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000113b64de9690e22494dc3c4b6280156e2a25c487000000000000000000000000113b64de9690e22494dc3c4b6280156e2a25c48700000000000000000000000000000000000000000000000000189e45ae9af62200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +441,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000907a37f4fdcad959ca182538cfd9a6745cd673a6000000000000000000000000907a37f4fdcad959ca182538cfd9a6745cd673a60000000000000000000000000000000000000000000000000011cd58c3bd53ab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbb8cf019a716684771515e4e95ad0fa304f29da000000000000000000000000cbb8cf019a716684771515e4e95ad0fa304f29da0000000000000000000000000000000000000000000000000ddf0c7bc568580000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000536a32e1448cc9e8910d319d8d4639abfb13fbd9000000000000000000000000536a32e1448cc9e8910d319d8d4639abfb13fbd9000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000367e9c3ac0e28c1536d5503de72bfea24fa4ed8a000000000000000000000000367e9c3ac0e28c1536d5503de72bfea24fa4ed8a000000000000000000000000000000000000000000000000001fa2df261c180000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007b3e12359a738171e2872f4db665fe91bcbadbe00000000000000000000000007b3e12359a738171e2872f4db665fe91bcbadbe0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af4826b9a4cf2dfe5ffea76389b043b25bf381da000000000000000000000000af4826b9a4cf2dfe5ffea76389b043b25bf381da0000000000000000000000000000000000000000000000000062ac5c4705c25800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c865bcad9c26a1e24f15a7881e2d09400f518120000000000000000000000003c865bcad9c26a1e24f15a7881e2d09400f518120000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +453,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042eed31a8bb26099364b301ae087acfb037ba86400000000000000000000000042eed31a8bb26099364b301ae087acfb037ba86400000000000000000000000000000000000000000000000000025d365d84740000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +454,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061e09532c31973271474da3616fa71b38362a5c100000000000000000000000061e09532c31973271474da3616fa71b38362a5c100000000000000000000000000000000000000000000000000b324cbf51749e800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +455,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fde2205127903277f08f20d724abfb53c602f637000000000000000000000000fde2205127903277f08f20d724abfb53c602f63700000000000000000000000000000000000000000000000000baf6f1b3c8940000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f27c223b051ac3264c59b9ee8ca0f306406003a5000000000000000000000000f27c223b051ac3264c59b9ee8ca0f306406003a500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004524eb19cb5a1ddec08b2bf4569f480632070fdf0000000000000000000000004524eb19cb5a1ddec08b2bf4569f480632070fdf000000000000000000000000000000000000000000000000006632f18c69640f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e21b36ebede73eb8acc7e15e13407d629240cfbf000000000000000000000000e21b36ebede73eb8acc7e15e13407d629240cfbf000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +464,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3b5f18add21b6578e679d0de8ac7597d0095b73000000000000000000000000f3b5f18add21b6578e679d0de8ac7597d0095b73000000000000000000000000000000000000000000000000000051dac207a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb3a0ceeea78fc630ea6ac4c97eecd106aefa16e000000000000000000000000bb3a0ceeea78fc630ea6ac4c97eecd106aefa16e0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001506d1fc81a1b5505115884bc7b792f19f4ca2fc0000000000000000000000001506d1fc81a1b5505115884bc7b792f19f4ca2fc000000000000000000000000000000000000000000000000001f1776b40f34ae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a608aab1a651e665c8defd5b6cb392484ab37d75000000000000000000000000a608aab1a651e665c8defd5b6cb392484ab37d750000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +468,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea5b010320eff0aabd4099ac733314d829ee0c0f000000000000000000000000ea5b010320eff0aabd4099ac733314d829ee0c0f0000000000000000000000000000000000000000000000000033abab2f34f30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e17ba3491ef88c8ba6b8181313dd1219d403b08a000000000000000000000000e17ba3491ef88c8ba6b8181313dd1219d403b08a000000000000000000000000000000000000000000000000001c62fde17b34ee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000569bfce7a6a72439d699a795c54f66826674e138000000000000000000000000569bfce7a6a72439d699a795c54f66826674e13800000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000efcbec968df1286d57e16c2cf31edbde3aa11f39000000000000000000000000efcbec968df1286d57e16c2cf31edbde3aa11f390000000000000000000000000000000000000000000000000000000003636f1b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +479,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052679a46eb65176dcd38e4ce45089ed84b0bdbe600000000000000000000000052679a46eb65176dcd38e4ce45089ed84b0bdbe600000000000000000000000000000000000000000000000000164dc4d3c9289800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +481,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1ee06ef0176f9cc95765afef9ef10f451c035cd000000000000000000000000e1ee06ef0176f9cc95765afef9ef10f451c035cd000000000000000000000000000000000000000000000000006e0249c0a6103600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd615f5c8946e95a4cebe5bd7426cc6ed9a8bc7b653aed022bd2a4ce5705f9418,2022-05-22 10:29:02.000 UTC,0,true +482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a23abf4eb73af80af932ba9abf89f4efe1b4c960000000000000000000000004a23abf4eb73af80af932ba9abf89f4efe1b4c9600000000000000000000000000000000000000000000000000100c72142168dc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +483,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c2e73a5987801a130a0a01feab47d70a5ec04750000000000000000000000009c2e73a5987801a130a0a01feab47d70a5ec0475000000000000000000000000000000000000000000000000005e259c0e8c400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000710afef4052c2820059d13eb7ddc14700931cfe1000000000000000000000000710afef4052c2820059d13eb7ddc14700931cfe100000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x475aa869685120b676f179f2f1dcddc93b20d8e1c28b1dee9f5ba791ad162e43,2022-05-16 11:14:46.000 UTC,0,true +494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000384158caae0ec2f338b48500d09240bcb00e3747000000000000000000000000384158caae0ec2f338b48500d09240bcb00e374700000000000000000000000000000000000000000000000000f3c5f8538e269700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061f2bedbe48c49c38acd299ccdbfb814a23f9e4600000000000000000000000061f2bedbe48c49c38acd299ccdbfb814a23f9e46000000000000000000000000000000000000000000000000002dc1f68b6b4dc700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3ce0ab69bbcf986a5a1f7826f58205048d62d60000000000000000000000000e3ce0ab69bbcf986a5a1f7826f58205048d62d60000000000000000000000000000000000000000000000000014c2dc12e7fc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +502,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000979eabeb86b39f4ae7a0d60b3d2039dfee5ac2a4000000000000000000000000979eabeb86b39f4ae7a0d60b3d2039dfee5ac2a40000000000000000000000000000000000000000000000000031bced02db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +503,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085553c73886977397c0eb6231ac95f86015ece9a00000000000000000000000085553c73886977397c0eb6231ac95f86015ece9a0000000000000000000000000000000000000000000000000033558ec475928000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2f390af1b11083154a0a15bfd3e555f57d82737000000000000000000000000b2f390af1b11083154a0a15bfd3e555f57d8273700000000000000000000000000000000000000000000000000434009a354799600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed3c678f04d92c78c101154a271a50ad9089f443000000000000000000000000ed3c678f04d92c78c101154a271a50ad9089f443000000000000000000000000000000000000000000000000001a16ba969d05b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +511,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003585c5691d442442685623f071e0fcc9f5ae1e8e0000000000000000000000003585c5691d442442685623f071e0fcc9f5ae1e8e0000000000000000000000000000000000000000000000000032dd27da55020000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc765b78d01afaaaf650cd5723bb2a299fc15710bd2ee27d95d6b28aafb192e60,2021-12-12 11:37:47.000 UTC,0,true +513,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe9f4e4fc884fbab008947c09c6bd7ecab1d9510000000000000000000000000fe9f4e4fc884fbab008947c09c6bd7ecab1d95100000000000000000000000000000000000000000000000000022169ece6c250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +514,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f071f2ce06084811be5b2ef2e9d2773f53d32cb0000000000000000000000005f071f2ce06084811be5b2ef2e9d2773f53d32cb00000000000000000000000000000000000000000000000000f447514f945c1000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a82eb7116e2b3117be7ef111fe8e71197fda2fc7000000000000000000000000a82eb7116e2b3117be7ef111fe8e71197fda2fc70000000000000000000000000000000000000000000000000021d1d25511830000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +520,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000892140d07986898067079527a5fe5036a56cc893000000000000000000000000892140d07986898067079527a5fe5036a56cc89300000000000000000000000000000000000000000000000000aead1bb949d50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +522,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000813e2048b3a1e47bb8965bfccd5d70da2324c8b7000000000000000000000000813e2048b3a1e47bb8965bfccd5d70da2324c8b7000000000000000000000000000000000000000000000000000051dac207a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +523,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fbdc9fc797bc23d716c758821049e91103144280000000000000000000000005fbdc9fc797bc23d716c758821049e911031442800000000000000000000000000000000000000000000000000445d10e361770000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +524,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5119abbc91c0ef96de588b10df364e862dbc8f6000000000000000000000000a5119abbc91c0ef96de588b10df364e862dbc8f6000000000000000000000000000000000000000000000000003f88a45078c99300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +526,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c16414ac1fedfdac4f8a09674d994e1bbb9d7113000000000000000000000000c16414ac1fedfdac4f8a09674d994e1bbb9d7113000000000000000000000000000000000000000000000000f9b1e8abb4f6187300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xec62f271bfa1cd8dd5146a2f2f5a778d76012bb6f3fe4687f7bd75457bbda544,2021-12-24 05:11:57.000 UTC,0,true +527,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e30a466d244dffbc36ab3d616796a276ebcd760c0000000000000000000000000000000000000000000000005371a517ff288800,,,1,true +529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090ea7c4f89d11fc237a822e7395cd4b33f164e5800000000000000000000000090ea7c4f89d11fc237a822e7395cd4b33f164e580000000000000000000000000000000000000000000000000055febac9875e6e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b11cc193ba3ab9c2a0ed9eda03a4d795c7662620000000000000000000000003b11cc193ba3ab9c2a0ed9eda03a4d795c766262000000000000000000000000000000000000000000000000004418446a06d50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +534,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ef91ecd0142ae4c5163b2cf060c0563d49188c82000000000000000000000000ef91ecd0142ae4c5163b2cf060c0563d49188c820000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000913ef606ae851af034f2195c63f1c0324fb3e423000000000000000000000000913ef606ae851af034f2195c63f1c0324fb3e42300000000000000000000000000000000000000000000000000ba34e311fa030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008bc00f15af562e01d3faa3bc5d53f3aa7bbc59660000000000000000000000008bc00f15af562e01d3faa3bc5d53f3aa7bbc596600000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000beaae768c2534b882ca2cabf1f04d528b95163fd000000000000000000000000beaae768c2534b882ca2cabf1f04d528b95163fd000000000000000000000000000000000000000000000000011aafc1d8b9a90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000210e953c0f36dd6df7c07d745cb31660fdea7e72000000000000000000000000210e953c0f36dd6df7c07d745cb31660fdea7e72000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000039b678799337cb0e04dbdd192020ab4fe65783e000000000000000000000000039b678799337cb0e04dbdd192020ab4fe65783e00000000000000000000000000000000000000000000000000000000ca8231f800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069b4f1d198783baca5da8bb69f4447514ffa26df00000000000000000000000069b4f1d198783baca5da8bb69f4447514ffa26df000000000000000000000000000000000000000000000000013543d8b99fee9900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d030e6d9c9d0951d7d0e902fb0f27caa66d65286000000000000000000000000d030e6d9c9d0951d7d0e902fb0f27caa66d65286000000000000000000000000000000000000000000000000011547f1cab70d4c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf5ca5ec3366a8d1e6d73dcf91c7ae6d61cf4c2166874c87388ec35e5464e7872,2021-12-26 14:51:38.000 UTC,0,true +551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e59a19937237224b04aa25b293119ce1733dc580000000000000000000000009e59a19937237224b04aa25b293119ce1733dc5800000000000000000000000000000000000000000000000000963cd9ab5a73c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003753fa57980fd180655c281158e428ca994d6dfa0000000000000000000000003753fa57980fd180655c281158e428ca994d6dfa000000000000000000000000000000000000000000000000015e314a523b8d9b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2876ec5991f19a26bf4a32915b43a03e96d129a000000000000000000000000e2876ec5991f19a26bf4a32915b43a03e96d129a00000000000000000000000000000000000000000000000000688206bd1b360000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa0c63a5295eed86bbeb2e49ec44bc0ed4466ada000000000000000000000000fa0c63a5295eed86bbeb2e49ec44bc0ed4466ada000000000000000000000000000000000000000000000000013ad61b2b5b22c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016613d9c9f1fec0b1e08233602d7dedf27c5c86800000000000000000000000016613d9c9f1fec0b1e08233602d7dedf27c5c86800000000000000000000000000000000000000000000000002d9f9596ca4166a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016613d9c9f1fec0b1e08233602d7dedf27c5c86800000000000000000000000016613d9c9f1fec0b1e08233602d7dedf27c5c868000000000000000000000000000000000000000000000000007edef594c63ecb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000060655f1e1f87086b27e35ce8eef99945e2f4f6b000000000000000000000000060655f1e1f87086b27e35ce8eef99945e2f4f6b00000000000000000000000000000000000000000000000000233ba7346d80c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +562,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d67b76cf3dcc881255eb2262e788be03b2f5b9f0000000000000000000000003d67b76cf3dcc881255eb2262e788be03b2f5b9f000000000000000000000000000000000000000000000000008a6b67f927a90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d67b76cf3dcc881255eb2262e788be03b2f5b9f0000000000000000000000003d67b76cf3dcc881255eb2262e788be03b2f5b9f00000000000000000000000000000000000000000000000002ade43338cb380100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008bc00f15af562e01d3faa3bc5d53f3aa7bbc59660000000000000000000000008bc00f15af562e01d3faa3bc5d53f3aa7bbc5966000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +571,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f39fe64953c20757419d960ee6dbc5e6a19914d3000000000000000000000000f39fe64953c20757419d960ee6dbc5e6a19914d300000000000000000000000000000000000000000000000006ea19e7969e135e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc07f994bd3d83cddd732bc50b57a810036ddf30000000000000000000000000bc07f994bd3d83cddd732bc50b57a810036ddf30000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +579,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000603fe182e7e1c16e5003fd44cb7263cdb969642e000000000000000000000000603fe182e7e1c16e5003fd44cb7263cdb969642e00000000000000000000000000000000000000000000000000225b6b47c6c70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +580,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc07f994bd3d83cddd732bc50b57a810036ddf30000000000000000000000000bc07f994bd3d83cddd732bc50b57a810036ddf3000000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +581,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003e4a0e0593df6ffd10d459e06429b93399a3d80a0000000000000000000000003e4a0e0593df6ffd10d459e06429b93399a3d80a000000000000000000000000000000000000000000000000314efb91c16aafaf00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +585,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004329ef4ef2d9b407b277325ba744025ce437920f0000000000000000000000004329ef4ef2d9b407b277325ba744025ce437920f000000000000000000000000000000000000000000000000001aa535d3d0c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +587,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9499fc54c492118620f38b36b72c06632128157000000000000000000000000f9499fc54c492118620f38b36b72c06632128157000000000000000000000000000000000000000000000000001459f02296673000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +588,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9499fc54c492118620f38b36b72c06632128157000000000000000000000000f9499fc54c492118620f38b36b72c066321281570000000000000000000000000000000000000000000000000008b9f5fb47f97700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +589,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000083d420a602b5cd560ac5fa9bbca0d5e91e4cb9750000000000000000000000000000000000000000000000058235a9b32a882e78,,,1,true +590,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7015ab1a9f7348bc2598cd77eb3471092193188000000000000000000000000c7015ab1a9f7348bc2598cd77eb3471092193188000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +598,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004570d5b4177cf209944e8e3fb1f2a77021ffd5c50000000000000000000000004570d5b4177cf209944e8e3fb1f2a77021ffd5c5000000000000000000000000000000000000000000000000215cef5e3dbe2e1600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +602,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000024bf21c742791848cb37d228afad72a5a273b18100000000000000000000000000000000000000000000000059c531a9e3d6ea85,,,1,true +603,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29c64e997ea2488c444ff2eba812cf5c6de49b4000000000000000000000000c29c64e997ea2488c444ff2eba812cf5c6de49b40000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +604,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da989e943caff71f29284a39c8947410480a6e07000000000000000000000000da989e943caff71f29284a39c8947410480a6e070000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +606,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e75ec34b72a1deb5e267365297950fe2649e97d4000000000000000000000000e75ec34b72a1deb5e267365297950fe2649e97d4000000000000000000000000000000000000000000000000006e3ca455466f9800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +612,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002526ce6014e8c17aedea915fa7470d4b780ade980000000000000000000000002526ce6014e8c17aedea915fa7470d4b780ade9800000000000000000000000000000000000000000000000ad78ebc5ac620000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +615,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040f9ccc945d52d74b9a023cb295015d28d40d8f300000000000000000000000040f9ccc945d52d74b9a023cb295015d28d40d8f300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +618,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002526ce6014e8c17aedea915fa7470d4b780ade980000000000000000000000002526ce6014e8c17aedea915fa7470d4b780ade980000000000000000000000000000000000000000000000000195708d03af99c800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b797bc5cfd2dfa84a727328d8df28d0fde55ca40000000000000000000000008b797bc5cfd2dfa84a727328d8df28d0fde55ca400000000000000000000000000000000000000000000000000af366d1391760000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc202930867769a83b61cf5053b65d1845e76aea000000000000000000000000cc202930867769a83b61cf5053b65d1845e76aea0000000000000000000000000000000000000000000000000dadff6d8ea92e9500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa1fc47f1737b884d0f2941ea7afcec2904e543e64dff1b4c441d34e66abf9456,2021-11-24 15:55:04.000 UTC,0,true +633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004271eb0d4ddcc6856ad0d9eb987257ca2ac5278c0000000000000000000000004271eb0d4ddcc6856ad0d9eb987257ca2ac5278c0000000000000000000000000000000000000000000000000001033e1cf569ac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +639,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008822645150ae7e252c404381e07bc9c44552e9f50000000000000000000000008822645150ae7e252c404381e07bc9c44552e9f500000000000000000000000000000000000000000000000001175e4aa00dc4af00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000747439c899faa9a7e2a7695ce64d0909050e6169000000000000000000000000747439c899faa9a7e2a7695ce64d0909050e6169000000000000000000000000000000000000000000000000003a53fe592ae50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6cfc086526be4bd7cfc02a0c62f06530fc7212d000000000000000000000000a6cfc086526be4bd7cfc02a0c62f06530fc7212d000000000000000000000000000000000000000000000000001ea657463ba80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +645,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9732a70489c681bb5b8f53d9eedb83bbe04f04f000000000000000000000000a9732a70489c681bb5b8f53d9eedb83bbe04f04f00000000000000000000000000000000000000000000000000563851dd2db88300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +646,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035483b77a27a254d0f6248416e94e23ff7c8ef0f00000000000000000000000035483b77a27a254d0f6248416e94e23ff7c8ef0f00000000000000000000000000000000000000000000000000675da46edc155100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +649,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000012ef2cd4231d5cf655a6cdd4ac1524ffaa439c1700000000000000000000000012ef2cd4231d5cf655a6cdd4ac1524ffaa439c17000000000000000000000000000000000000000000000000000000016efcc01a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xf437d5e09082a184bbbdbd788edbc1808509297d76b04dc5be48bf0fc4095093,2022-06-01 07:42:30.000 UTC,0,true +650,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000d801699678375e43d14f67453e24f17ebbaef8a0000000000000000000000000d801699678375e43d14f67453e24f17ebbaef8a00000000000000000000000000000000000000000000000a35a2f021abc49e6b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +652,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e9f0b99751b49fffd7115eb0415d4aca11db8980000000000000000000000000e9f0b99751b49fffd7115eb0415d4aca11db898000000000000000000000000000000000000000000000000000f252719c5b74000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e53fb7989ad637f7a674e8db71e85cab60607183000000000000000000000000e53fb7989ad637f7a674e8db71e85cab6060718300000000000000000000000000000000000000000000000000c1bad3366c576800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e4e018514c72776fe0f48bdc13aa1aa49e88f610000000000000000000000004e4e018514c72776fe0f48bdc13aa1aa49e88f610000000000000000000000000000000000000000000000000011f0aeb6d599e500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +657,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000153509e78fd04144d482e27716ae14c52d7932b0000000000000000000000000153509e78fd04144d482e27716ae14c52d7932b0000000000000000000000000000000000000000000000000001f4daf5641a1c900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +658,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000006185ca50a8ab43726b08d8e65c6f2173fb2b2360000000000000000000000000000000000000000000000002055d2a7b6a90000,,,1,true +659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ace8dccf7bbc639f6de934a962c2d4880bf6d300000000000000000000000000ace8dccf7bbc639f6de934a962c2d4880bf6d30000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0d1212b52da5ed44b19f4328f5fe7708f825d81000000000000000000000000c0d1212b52da5ed44b19f4328f5fe7708f825d81000000000000000000000000000000000000000000000000002b8ad18d3d69f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbed0c05b25e16393b56973911c96e2f74b09b94faf87f7998a1042232347dcfb,2022-03-08 04:42:00.000 UTC,0,true +665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5a61d56ca395fcb87f148532369595e31286d0e000000000000000000000000c5a61d56ca395fcb87f148532369595e31286d0e00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1ae9c293db4cf469b0b6b59c8653555dedb7ad3bea0b52317bc880c456cbf592,2022-05-24 02:45:59.000 UTC,0,true +666,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e9fbf581059cabe23241f8307d96e9087baf7ea0000000000000000000000006e9fbf581059cabe23241f8307d96e9087baf7ea00000000000000000000000000000000000000000000000000a79bbcaeb99b9700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe76ffd8c97fc39b908574ddb3bd20c65199a3922be3153035514f4fb0c150327,2022-03-07 16:27:30.000 UTC,0,true +668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f96f50edb37a19216d87693e5db241e31bd37350000000000000000000000004f96f50edb37a19216d87693e5db241e31bd373500000000000000000000000000000000000000000000000164dc0424419e22c200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +671,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e7126dc2ba9e19d84c7d708f294a743fa4bce630000000000000000000000008e7126dc2ba9e19d84c7d708f294a743fa4bce6300000000000000000000000000000000000000000000000000b552f14bae975900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000896d781ddd4949990ad530e77550577a5cf4b990000000000000000000000000896d781ddd4949990ad530e77550577a5cf4b9900000000000000000000000000000000000000000000000002c1745542ba214200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +673,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f4b7ba1fb6fea41b7f159f1b86b8295f269abde0000000000000000000000000f4b7ba1fb6fea41b7f159f1b86b8295f269abde0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +677,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003e17fac953de2cd729b0ace7f6d4353387717e9e0000000000000000000000000000000000000000000000117b0e7dd162419429,,,1,true +681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005eee0073017bd5a3bc0f031c3ff84cf12302c04c0000000000000000000000005eee0073017bd5a3bc0f031c3ff84cf12302c04c00000000000000000000000000000000000000000000000005f8837463f91e9800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000479de3aaf6151ae39f74d55e1f440de66e85ddd4000000000000000000000000479de3aaf6151ae39f74d55e1f440de66e85ddd40000000000000000000000000000000000000000000000000159b5206e3c225d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +687,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe9f4e4fc884fbab008947c09c6bd7ecab1d9510000000000000000000000000fe9f4e4fc884fbab008947c09c6bd7ecab1d951000000000000000000000000000000000000000000000000000079fb988364a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +690,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d41a8fc6c7a6f07ce60b421f0f24c958e09211f0000000000000000000000008d41a8fc6c7a6f07ce60b421f0f24c958e09211f000000000000000000000000000000000000000000000000003b66a05eb12f2a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +691,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d41a8fc6c7a6f07ce60b421f0f24c958e09211f0000000000000000000000008d41a8fc6c7a6f07ce60b421f0f24c958e09211f000000000000000000000000000000000000000000000000002384e11c371cee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +692,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d105dd0a16290f4a3729cac5c4acaae8492b2590000000000000000000000007d105dd0a16290f4a3729cac5c4acaae8492b259000000000000000000000000000000000000000000000000001d568764f9ee1000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b35e598fc643037facde62dba4343e99f6294958000000000000000000000000b35e598fc643037facde62dba4343e99f62949580000000000000000000000000000000000000000000000000186cc6acd4b000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009fcdce0361c3a8a1b5d21afa25383605d26b0f350000000000000000000000009fcdce0361c3a8a1b5d21afa25383605d26b0f35000000000000000000000000000000000000000000000000013720fbf76cd94000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +699,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b9a250ef1a6a3673d2d4b6805bdb1059d22ecb30000000000000000000000003b9a250ef1a6a3673d2d4b6805bdb1059d22ecb300000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c7cb0f3a890df6b8c1de1d22ab9caecf81b172c0000000000000000000000007c7cb0f3a890df6b8c1de1d22ab9caecf81b172c000000000000000000000000000000000000000000000000006abe60bea5c73800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f62dd1a43d79cc5acbf94abf823cd33f816bdb90000000000000000000000009f62dd1a43d79cc5acbf94abf823cd33f816bdb9000000000000000000000000000000000000000000000000004e28e2290f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008da4bf2f8f0cd17849cc563eba0aa8fd6c14a3ac0000000000000000000000008da4bf2f8f0cd17849cc563eba0aa8fd6c14a3ac000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f14347ae79a734dbf84883bf2bfd3c285f860220000000000000000000000003f14347ae79a734dbf84883bf2bfd3c285f86022000000000000000000000000000000000000000000000000009c9328f7c9450000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000068f180fcce6836688e9084f035309e29bf0a20950000000000000000000000004ec6b6f9bcdda4432cc134779b62bf8770d925b20000000000000000000000004ec6b6f9bcdda4432cc134779b62bf8770d925b200000000000000000000000000000000000000000000000000000000000a68b300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +715,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000bfddb0906e960c1b3d965b6bd291208e8c5bbad1000000000000000000000000bfddb0906e960c1b3d965b6bd291208e8c5bbad1000000000000000000000000000000000000000000000002fcf22664b680c2c200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfddb0906e960c1b3d965b6bd291208e8c5bbad1000000000000000000000000bfddb0906e960c1b3d965b6bd291208e8c5bbad1000000000000000000000000000000000000000000000000001f1311dfbb5bc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +718,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000820d2e1f0e75e83078730605ee6fb436d7a7762f000000000000000000000000820d2e1f0e75e83078730605ee6fb436d7a7762f0000000000000000000000000000000000000000000000000169db2e213ce3d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +723,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af4f9aa4a83133ae981b5afeda7d764621c5fae6000000000000000000000000af4f9aa4a83133ae981b5afeda7d764621c5fae600000000000000000000000000000000000000000000000000031c84d188bd8300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +728,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bcc90a9ed7be531d2be62cbdb6324f0b9bf632f0000000000000000000000005bcc90a9ed7be531d2be62cbdb6324f0b9bf632f00000000000000000000000000000000000000000000000000049cd4f2c773c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cf2565d3f2711093ea24d4021248c7bc04697490000000000000000000000005cf2565d3f2711093ea24d4021248c7bc046974900000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000102e14acfc47ef75167763112024a9ed38596da0000000000000000000000000102e14acfc47ef75167763112024a9ed38596da0000000000000000000000000000000000000000000000000007c58508723800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x34f7bd635826f3bee79626633f454af90ae72171da7641bf354155128c179267,2022-02-26 12:48:03.000 UTC,0,true +738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000c9037fd858069e2fa03ce1eff31bda66ea3075c1000000000000000000000000c9037fd858069e2fa03ce1eff31bda66ea3075c100000000000000000000000000000000000000000000000000000000f732eff400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c024559c710123b6caf5d225b56913aab339aad0000000000000000000000000c024559c710123b6caf5d225b56913aab339aad0000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b08112a69b572e4b05000cfd837ef06b6a255bf1000000000000000000000000b08112a69b572e4b05000cfd837ef06b6a255bf100000000000000000000000000000000000000000000000006eacb8d12142b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +749,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b4afac1f985afd50cabaa1a607cc0e0e666fadc0000000000000000000000000b4afac1f985afd50cabaa1a607cc0e0e666fadc0000000000000000000000000000000000000000000000000014ef5dc3e86f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +752,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000017ba7a44e90155bb2bf1375bae9c423e48afd48e00000000000000000000000017ba7a44e90155bb2bf1375bae9c423e48afd48e0000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +755,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b9a250ef1a6a3673d2d4b6805bdb1059d22ecb30000000000000000000000003b9a250ef1a6a3673d2d4b6805bdb1059d22ecb300000000000000000000000000000000000000000000000000424de64d71700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +759,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000743c9d620d2b1943d3347e2120ff9998637042ac000000000000000000000000000000000000000000000002c06fad6cebdb4e00,,,1,true +761,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000015fc0f9a30b6353b6ea191d7c4ba6c8aade92d7000000000000000000000000015fc0f9a30b6353b6ea191d7c4ba6c8aade92d7000000000000000000000000000000000000000000000000003a7a486500c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9baae0cb8f88dc4d64233bbfa72431b50f38e7eb78671dd2f5e3ba69b34d8ae9,2022-03-14 09:24:52.000 UTC,0,true +762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d7d64469f37bab258e084f4b5e43677789d3ce80000000000000000000000002d7d64469f37bab258e084f4b5e43677789d3ce800000000000000000000000000000000000000000000000000883e62b58fc9a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +767,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000156825670f19b704d54249f6d4d053a217bf3115000000000000000000000000156825670f19b704d54249f6d4d053a217bf311500000000000000000000000000000000000000000000000000538411c27d619d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001420bddee23e28a2fab3d91b716dcfbfc2165ff90000000000000000000000001420bddee23e28a2fab3d91b716dcfbfc2165ff900000000000000000000000000000000000000000000000000439fe1e30c815e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +771,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000111bbc1f307cc9bde8dd181e17c36b17d342efd0000000000000000000000000111bbc1f307cc9bde8dd181e17c36b17d342efd00000000000000000000000000000000000000000000000057f6206a70a171d300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000111bbc1f307cc9bde8dd181e17c36b17d342efd0000000000000000000000000111bbc1f307cc9bde8dd181e17c36b17d342efd0000000000000000000000000000000000000000000000000000f99a97f0ae6e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +773,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d01b7ff2b2544529ee092240d406051756607260000000000000000000000000d01b7ff2b2544529ee092240d40605175660726000000000000000000000000000000000000000000000000013d09ce8566c91f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c16e9ce31179909a69f92c6b587e9255bb77fb16000000000000000000000000c16e9ce31179909a69f92c6b587e9255bb77fb16000000000000000000000000000000000000000000000000015f15ecdd140dcd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c7c63070372f67b49a269940aa6853e1dccf2950000000000000000000000007c7c63070372f67b49a269940aa6853e1dccf29500000000000000000000000000000000000000000000000000166392a19ebc8200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e6512dc17c28cb50ab0787c30a806bdc363930d0000000000000000000000006e6512dc17c28cb50ab0787c30a806bdc363930d0000000000000000000000000000000000000000000000000092c5488bbde8b900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +778,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000374b7cf2684850d687b25b13ebc0e3046980aaa8000000000000000000000000374b7cf2684850d687b25b13ebc0e3046980aaa8000000000000000000000000000000000000000000000000015f29b3382a05e700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9ee9b9620556054d5e400d0c12ba6393efbc05e000000000000000000000000a9ee9b9620556054d5e400d0c12ba6393efbc05e000000000000000000000000000000000000000000000000007b3fcb8e557aaa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094f6134e0879f82ecb3aabd67dba21fec57fd04300000000000000000000000094f6134e0879f82ecb3aabd67dba21fec57fd043000000000000000000000000000000000000000000000000000a3f04646f345100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042fb7812297ca741c665b3fd60a9310351d1546600000000000000000000000042fb7812297ca741c665b3fd60a9310351d1546600000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +793,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000058d797263f86ae8885c8757efe1a59bd179357c900000000000000000000000058d797263f86ae8885c8757efe1a59bd179357c90000000000000000000000000000000000000000000000ecaf0c2701a80d6a0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e65b845d994b7eaa59456c36f590907afd896628000000000000000000000000e65b845d994b7eaa59456c36f590907afd89662800000000000000000000000000000000000000000000000000154b191061470000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1dd073c0ee4bf474a5ce5b0d08a4e240115f176000000000000000000000000c1dd073c0ee4bf474a5ce5b0d08a4e240115f17600000000000000000000000000000000000000000000000000133af6d4f9a9c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +802,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000302d43d1a7c1313608f218446a4266fb312c461e000000000000000000000000302d43d1a7c1313608f218446a4266fb312c461e00000000000000000000000000000000000000000000000256b23d2620995e7200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +808,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008da4bf2f8f0cd17849cc563eba0aa8fd6c14a3ac0000000000000000000000008da4bf2f8f0cd17849cc563eba0aa8fd6c14a3ac000000000000000000000000000000000000000000000000002aade72a6bae1900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093f4de4246130b153149a2e26a469c555754559200000000000000000000000093f4de4246130b153149a2e26a469c5557545592000000000000000000000000000000000000000000000000026cd2012bc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +813,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7162203d69f761b8d899e8f6f2f12818f87738f000000000000000000000000b7162203d69f761b8d899e8f6f2f12818f87738f0000000000000000000000000000000000000000000000000060e3ed2b874c8100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0bbfefd6ef7834d869b7aabcbb5d1c538f3409ec1f4adeb6415c0d799800d406,2022-05-27 23:49:34.000 UTC,0,true +814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000298ed1d964a107517f2a135106e903fcf42e77c0000000000000000000000000298ed1d964a107517f2a135106e903fcf42e77c00000000000000000000000000000000000000000000000000398fd40c23830000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +815,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051d32336397884d86712814d73ee3f20610e395200000000000000000000000051d32336397884d86712814d73ee3f20610e3952000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d0864beb3a80a530f494427d6a03b9ca71112fb0000000000000000000000005d0864beb3a80a530f494427d6a03b9ca71112fb00000000000000000000000000000000000000000000000000099dbf4165158400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000334c5b9f732174caa4b7a67d2178b7e74a527003000000000000000000000000334c5b9f732174caa4b7a67d2178b7e74a52700300000000000000000000000000000000000000000000000000014c77db5eac9800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006089bceee94a485c61b311cb61934d5cf8a684e00000000000000000000000006089bceee94a485c61b311cb61934d5cf8a684e000000000000000000000000000000000000000000000000000029a18b7e930e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053c9286b4940281609433dc01c28d86c734b44c300000000000000000000000053c9286b4940281609433dc01c28d86c734b44c3000000000000000000000000000000000000000000000000002bcab74dd21e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032aa36adfe23c52de8737bdb7c7ebf2db4253e8900000000000000000000000032aa36adfe23c52de8737bdb7c7ebf2db4253e89000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032aa36adfe23c52de8737bdb7c7ebf2db4253e8900000000000000000000000032aa36adfe23c52de8737bdb7c7ebf2db4253e89000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041d657fd02fcedaa37df6cc785859423f03a58e900000000000000000000000041d657fd02fcedaa37df6cc785859423f03a58e900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +831,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000016b00db74167b7469dda63b674ca9a3b1b70c439000000000000000000000000000000000000000000000001c09b256500768132,,,1,true +832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000320ed2be452129381c87d0e4f4aabd7d9b7786fe000000000000000000000000320ed2be452129381c87d0e4f4aabd7d9b7786fe00000000000000000000000000000000000000000000000000000124ebd427c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x678959ef46816db82cec80e038adec4bb506d28570d4ff5174acc79960e62b16,2022-08-25 07:58:33.000 UTC,0,true +833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000320ed2be452129381c87d0e4f4aabd7d9b7786fe000000000000000000000000320ed2be452129381c87d0e4f4aabd7d9b7786fe00000000000000000000000000000000000000000000000000000000037c621500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa0ca4994434f8808b3255e0d03507dd4ab4f48b5bc652e5fabef0a93677d52aa,2022-08-25 08:03:39.000 UTC,0,true +834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009476b5d92f0f6411007ed481405c80c1801a60ce0000000000000000000000009476b5d92f0f6411007ed481405c80c1801a60ce000000000000000000000000000000000000000000000000004497af4bf2343b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +836,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000721c7fffe9ac426a028e616677811f755fa99eba000000000000000000000000721c7fffe9ac426a028e616677811f755fa99eba00000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe60e3cb6bbdca1879d62796e1e0ea174334493b000000000000000000000000fe60e3cb6bbdca1879d62796e1e0ea174334493b0000000000000000000000000000000000000000000000000046ce59bcae17de00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d346aaf41745f87e71c4f8af9647f4aab2c4c310000000000000000000000007d346aaf41745f87e71c4f8af9647f4aab2c4c31000000000000000000000000000000000000000000000000008736c880dac63700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003930934bfd0997f375c0749081b51dacee8d0aa40000000000000000000000003930934bfd0997f375c0749081b51dacee8d0aa40000000000000000000000000000000000000000000000000015265c76b9973900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6d301feb8c691989f4597cf37167a896085511b000000000000000000000000d6d301feb8c691989f4597cf37167a896085511b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b1815f2c8bf70385e23bf97ad86b152e8171cfc0000000000000000000000007b1815f2c8bf70385e23bf97ad86b152e8171cfc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076b7c065ee0ec58b4fcefdf8927063303d3e798900000000000000000000000076b7c065ee0ec58b4fcefdf8927063303d3e7989000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001632b9c770c809eab725e19cced79249c469aff40000000000000000000000001632b9c770c809eab725e19cced79249c469aff4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053f740aa1962c38b75da7e7eef74c8c05fe9f27600000000000000000000000053f740aa1962c38b75da7e7eef74c8c05fe9f27600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001852bdf59e59a6ef462f88976bc0e0208d022a2f0000000000000000000000001852bdf59e59a6ef462f88976bc0e0208d022a2f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbe934124a766bee19c36aeda167a885c6063f55000000000000000000000000cbe934124a766bee19c36aeda167a885c6063f5500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfb3f38a19e1a37eb3b76cfa01ec78149fa7f950000000000000000000000000cfb3f38a19e1a37eb3b76cfa01ec78149fa7f95000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dab481d9f9f3dde5157e10e7a3ed8ff4470d2390000000000000000000000002dab481d9f9f3dde5157e10e7a3ed8ff4470d23900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3e27850711e108033f2b007226bd29335092786000000000000000000000000c3e27850711e108033f2b007226bd2933509278600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +855,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051d32336397884d86712814d73ee3f20610e395200000000000000000000000051d32336397884d86712814d73ee3f20610e395200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c94a5d9648e17a0e30cc7f7f2e8f5cd8ef40bca0000000000000000000000008c94a5d9648e17a0e30cc7f7f2e8f5cd8ef40bca00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +858,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000146ab635fd9f49a57ceaeed6347fd4f9f4349ae4000000000000000000000000146ab635fd9f49a57ceaeed6347fd4f9f4349ae40000000000000000000000000000000000000000000000000078b29eef5bffd400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +862,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e54ff8766bb1c0d6d978495454e7b2fb041faed0000000000000000000000007e54ff8766bb1c0d6d978495454e7b2fb041faed00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef08c3d5b02cf6240cf71908d5dbd497e361584f000000000000000000000000ef08c3d5b02cf6240cf71908d5dbd497e361584f0000000000000000000000000000000000000000000000000014c1801dac030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca87dfe624d3fc05abcceeac9d50ec3f7a3541d1000000000000000000000000ca87dfe624d3fc05abcceeac9d50ec3f7a3541d1000000000000000000000000000000000000000000000000001943d81419d2c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +868,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d75741e7f919fe1ede40efcf920ff878de08a832000000000000000000000000d75741e7f919fe1ede40efcf920ff878de08a83200000000000000000000000000000000000000000000000000ea21ccda4fe51800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064895794c76167dd1566646357592be45893de9800000000000000000000000064895794c76167dd1566646357592be45893de9800000000000000000000000000000000000000000000000000592d824a2ce18d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7ce82898efc2afc8fe6e5bfa08c6f96536222a1000000000000000000000000a7ce82898efc2afc8fe6e5bfa08c6f96536222a10000000000000000000000000000000000000000000000000019945ca262000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef4b2f4ac237a4d52c6c3ae4e425cb174c583bf8000000000000000000000000ef4b2f4ac237a4d52c6c3ae4e425cb174c583bf800000000000000000000000000000000000000000000000000215f6fcde8180000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033d8b1655fa39d85ede7fdf89f98b0394166005000000000000000000000000033d8b1655fa39d85ede7fdf89f98b039416600500000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bef78bef9f383bf3bb5e337cec7a4d1160a7fa11000000000000000000000000bef78bef9f383bf3bb5e337cec7a4d1160a7fa1100000000000000000000000000000000000000000000000001617d9b5e28da0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091f10cffdeb9701f2a03d72ff309fb08857a9b4900000000000000000000000091f10cffdeb9701f2a03d72ff309fb08857a9b49000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a949f950d4ed54822eda2a09a67131e2cbd9d4d7000000000000000000000000a949f950d4ed54822eda2a09a67131e2cbd9d4d700000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9e62c014d644aebde25c253d0d8e3a40c83de47000000000000000000000000b9e62c014d644aebde25c253d0d8e3a40c83de47000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +898,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed1d5da0059f42ad19fb9837f0ba7fdc674fe877000000000000000000000000ed1d5da0059f42ad19fb9837f0ba7fdc674fe877000000000000000000000000000000000000000000000000000efc33ae0b787900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +901,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000daccce559a0571083556f39d05b177579613d83b000000000000000000000000daccce559a0571083556f39d05b177579613d83b0000000000000000000000000000000000000000000000000000922936fa9c7c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ffc862d7954dbae096d2d1402c5a0aca1e45c890000000000000000000000008ffc862d7954dbae096d2d1402c5a0aca1e45c89000000000000000000000000000000000000000000000000003fb6b7148a826000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084e3e0f568ed68b4f6827fe797444b3d5b1fd8b500000000000000000000000084e3e0f568ed68b4f6827fe797444b3d5b1fd8b5000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3de285e0dd68d90856007ba52bc2a26d6f70b6e000000000000000000000000a3de285e0dd68d90856007ba52bc2a26d6f70b6e00000000000000000000000000000000000000000000000003ecd513c54a24f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000bb50690db3897ca5b1f63cff6e0c061b93f9bfbd000000000000000000000000bb50690db3897ca5b1f63cff6e0c061b93f9bfbd0000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x6e4bcfbf482237019641baefddee70e0d83f3bf05bbee8908f270dcda0333189,2022-06-22 09:54:41.000 UTC,0,true +922,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022536213791b04d8201ba219665dab3835d993f300000000000000000000000022536213791b04d8201ba219665dab3835d993f3000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +924,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ca4a4e011bdeb6e5cbc229b882ee20ad3231096a000000000000000000000000000000000000000000000000431cc2c4404ddaa8,,,1,true +927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d364c5c6c803feae75db05ac248fd9dbcc88c210000000000000000000000000d364c5c6c803feae75db05ac248fd9dbcc88c21000000000000000000000000000000000000000000000000003b0aa9caaa432d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +929,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d64d37bdad19aa59d9c43ff4f756f19809bfd7610000000000000000000000000000000000000000000000001bc16d674ec80000,,,1,true +932,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000cde4d4fa46fe2878c6b0530c9b9ac9ab87a380390000000000000000000000000000000000000000000000254c3a5a4cbc5a1a6a,,,1,true +934,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a908362a06b3dbf4496f7d4a298060aaf4307a50000000000000000000000000a908362a06b3dbf4496f7d4a298060aaf4307a50000000000000000000000000000000000000000000000000020aa7d90d1230000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e2be318532598d2abf8cdb463c21847bae969580000000000000000000000008e2be318532598d2abf8cdb463c21847bae9695800000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +936,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d7e630afcf128feb8b9071a8412914478c00c22a0000000000000000000000000000000000000000000000021a085ff4c4dc3f8f,0x292ba9349489c85415df5cc382ab5a67fd5c9683c2c18316cba1349d1688531e,2022-01-07 08:02:58.000 UTC,0,true +937,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1ade89bb702737a2d5a70f50c00360e1fc1ec5c000000000000000000000000c1ade89bb702737a2d5a70f50c00360e1fc1ec5c00000000000000000000000000000000000000000000000000ed625104278f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7a7bd2c1f3c25b0420e71b7fa85fe03728392b6000000000000000000000000f7a7bd2c1f3c25b0420e71b7fa85fe03728392b600000000000000000000000000000000000000000000000006a94d74f430000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +942,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3fb28778630b99d76e4e4a68be58b50c38792a0000000000000000000000000d3fb28778630b99d76e4e4a68be58b50c38792a00000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +943,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ed963afed4188993754c045f2f7055d19a7a9da600000000000000000000000000000000000000000000000113ad12516d81cd00,,,1,true +950,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b2d5adcda64f8167c723105a8bccc542766208e0000000000000000000000004b2d5adcda64f8167c723105a8bccc542766208e000000000000000000000000000000000000000000000000005ac8162691fb7600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082adf06307538950bee34802c094aaf9114a338200000000000000000000000082adf06307538950bee34802c094aaf9114a33820000000000000000000000000000000000000000000000000011df27237b55ab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +955,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4ebb04b785136d815a0799018f497dc17984f98000000000000000000000000e4ebb04b785136d815a0799018f497dc17984f98000000000000000000000000000000000000000000000000004801933a55312000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009e29df3900f4ea3053e183cddb965f5a5b4559b00000000000000000000000009e29df3900f4ea3053e183cddb965f5a5b4559b00000000000000000000000000000000000000000000000000397e2a6ba1cf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +960,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000614cc7e2fad0a7565f10346c3b9430527abd93e3000000000000000000000000614cc7e2fad0a7565f10346c3b9430527abd93e3000000000000000000000000000000000000000000000000014d3dc45fb7edf100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e87e162ca440a1bc68f3e9ff6cba6f71c14e2060000000000000000000000000e87e162ca440a1bc68f3e9ff6cba6f71c14e206000000000000000000000000000000000000000000000000003610277d29410000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d16451a4b73e778bfec126025ba79716a17e32d0000000000000000000000003d16451a4b73e778bfec126025ba79716a17e32d000000000000000000000000000000000000000000000000003c67b5c3f5164000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ff8c5a477faac59fda54b7c517d4dc1674ebe560000000000000000000000009ff8c5a477faac59fda54b7c517d4dc1674ebe560000000000000000000000000000000000000000000000000000f233819ffe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079700e477be49b579a9984bb11edaadadbe9474900000000000000000000000079700e477be49b579a9984bb11edaadadbe94749000000000000000000000000000000000000000000000000087727c4a0fd000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da0e0ada73f37744803cb481b41c6d48265c06c8000000000000000000000000da0e0ada73f37744803cb481b41c6d48265c06c80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +974,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002526ce6014e8c17aedea915fa7470d4b780ade980000000000000000000000002526ce6014e8c17aedea915fa7470d4b780ade98000000000000000000000000000000000000000000000010af192ca5e4c4158a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f567a6ca93dec3203344094cb90f035cc853a248000000000000000000000000f567a6ca93dec3203344094cb90f035cc853a2480000000000000000000000000000000000000000000000000003a12138149e4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e577e9ee5f508f8e859f4ecd941797a3e1b6fa20000000000000000000000004e577e9ee5f508f8e859f4ecd941797a3e1b6fa2000000000000000000000000000000000000000000000000001f144334de77ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +989,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000038788c3718faf8e4d783ba97925417de795fe8a000000000000000000000000038788c3718faf8e4d783ba97925417de795fe8a00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +996,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e9a88971e957abb41bae4e2677cae258f0c1e760000000000000000000000006e9a88971e957abb41bae4e2677cae258f0c1e76000000000000000000000000000000000000000000000000001bb7a56f93966400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d925cbbc53f8d70a05eba2f7abf4eb35d95f5180000000000000000000000000d925cbbc53f8d70a05eba2f7abf4eb35d95f5180000000000000000000000000000000000000000000000000004b74275052fb2900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +999,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0eaf0c77c1362ad4de668755be5559eb47cfb9f000000000000000000000000f0eaf0c77c1362ad4de668755be5559eb47cfb9f000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1000,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004c78dfd78482e2c7321d8d14cfae862918cf8b0f00000000000000000000000000000000000000000000000094c152e23fe5b317,,,1,true +1001,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a17479c80de5502e5f5baef0bde186b2a251c5d0000000000000000000000002a17479c80de5502e5f5baef0bde186b2a251c5d00000000000000000000000000000000000000000000000000416d1d7776cba800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1005,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000140901c4487b1ea5a23271aa3debe02a42bcb3ed000000000000000000000000140901c4487b1ea5a23271aa3debe02a42bcb3ed0000000000000000000000000000000000000000000000000042d9087150f4c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1006,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000337d1e27ac8a9c7b87bb4f07d409594142575388000000000000000000000000337d1e27ac8a9c7b87bb4f07d4095941425753880000000000000000000000000000000000000000000000000032d39032695dd600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1008,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e987cbfd0b8af69c93ea544db8b8efdd4aba0de0000000000000000000000008e987cbfd0b8af69c93ea544db8b8efdd4aba0de0000000000000000000000000000000000000000000000000038b3978b55a45800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1012,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076a7df68eed6bbc1d68543b7a471d41158803e9400000000000000000000000076a7df68eed6bbc1d68543b7a471d41158803e9400000000000000000000000000000000000000000000000000053fb7b9db6b3200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1014,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000461b1938a232327a07bf47e202c5f6a27306812d000000000000000000000000461b1938a232327a07bf47e202c5f6a27306812d000000000000000000000000000000000000000000000000000ad6b9d7e928e700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006d7881358cf903f2c2db94a32d5c6ae9bc611f600000000000000000000000006d7881358cf903f2c2db94a32d5c6ae9bc611f60000000000000000000000000000000000000000000000000036b0cef2e6635200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1023,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008c843233f4ac89fd1f98825c3707b023f8427c280000000000000000000000000000000000000000000000000de0b6b3a7640000,,,1,true +1025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c330440814443d4774ba112819392c366f1bd978000000000000000000000000c330440814443d4774ba112819392c366f1bd9780000000000000000000000000000000000000000000000000068dd95d320801000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1027,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e19e26becff917f057ebb35217fdf4ab3252dffe000000000000000000000000e19e26becff917f057ebb35217fdf4ab3252dffe000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1028,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c4f1080f341e9bff5c2411745bb8e22221a6a5c3000000000000000000000000c4f1080f341e9bff5c2411745bb8e22221a6a5c300000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1029,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ba2dfc38fdf8a5f8dadf1e1c4ab4f73348bbda57000000000000000000000000ba2dfc38fdf8a5f8dadf1e1c4ab4f73348bbda57000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1030,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a0a961674f7eb74da9ef4087bb262b35a5191a82000000000000000000000000a0a961674f7eb74da9ef4087bb262b35a5191a82000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1031,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000848640772aa8b981c520084473c31aaad491ca75000000000000000000000000848640772aa8b981c520084473c31aaad491ca75000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1032,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003af154c87f854c934fc2a4fe45265dbce59bd4a30000000000000000000000003af154c87f854c934fc2a4fe45265dbce59bd4a3000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1033,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000396546635b56c60d3597e5c558490754d20bc46c000000000000000000000000396546635b56c60d3597e5c558490754d20bc46c00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1034,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000007e320d04c059aa33f7dcfe3c3add07be5a31b8900000000000000000000000007e320d04c059aa33f7dcfe3c3add07be5a31b89000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1036,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072713894bd21d2dea4c8f4eb6d0237af8fd2feb200000000000000000000000072713894bd21d2dea4c8f4eb6d0237af8fd2feb2000000000000000000000000000000000000000000000000007fce083dfbf71d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1043,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff6e3780b0b8645b797a889feebe876c2fccd06d000000000000000000000000ff6e3780b0b8645b797a889feebe876c2fccd06d000000000000000000000000000000000000000000000000000f1186da096b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1047,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b707a58ee408ac8334eaedfc9988deb12c98ac30000000000000000000000009b707a58ee408ac8334eaedfc9988deb12c98ac3000000000000000000000000000000000000000000000000000952e470f45afe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1048,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b023d464f60004438fb4a31014314febfebf98e4000000000000000000000000b023d464f60004438fb4a31014314febfebf98e400000000000000000000000000000000000000000000000000358795e50ffa6f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1049,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b43300442baec524da4546f71548d28a391c2a1a000000000000000000000000b43300442baec524da4546f71548d28a391c2a1a0000000000000000000000000000000000000000000000000097fc871921dce500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018fd93c3bb72d41662d858afffb740c8f73a214a00000000000000000000000018fd93c3bb72d41662d858afffb740c8f73a214a0000000000000000000000000000000000000000000000000046f0f4de7cadff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1052,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009efd9fc88d4b950ae11411005ffe81efcf1b96350000000000000000000000009efd9fc88d4b950ae11411005ffe81efcf1b9635000000000000000000000000000000000000000000000000007cd38292ddccac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eaed802a117a58a5e644a670a1b2d99be459be50000000000000000000000000eaed802a117a58a5e644a670a1b2d99be459be500000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd8f43f82697e17c507cfdfebf75b48d8db149b3000000000000000000000000fd8f43f82697e17c507cfdfebf75b48d8db149b3000000000000000000000000000000000000000000000000005c868c3fe6c2e200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xaff2309b92b6577ef9f94fcdfaa2d40f280a87386dafaf4f98b298c98a81d141,2022-11-02 12:32:11.000 UTC,0,true +1055,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e54ff8766bb1c0d6d978495454e7b2fb041faed0000000000000000000000007e54ff8766bb1c0d6d978495454e7b2fb041faed00000000000000000000000000000000000000000000000000305591732cdfd500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1058,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002bab814da5c1618815998f3e929ed11c24d7da380000000000000000000000002bab814da5c1618815998f3e929ed11c24d7da38000000000000000000000000000000000000000000000000001465c4d1332b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1063,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000353a3b43d34247cbc3f8092187cdd849b5b31a77000000000000000000000000353a3b43d34247cbc3f8092187cdd849b5b31a7700000000000000000000000000000000000000000000000000ab59003f284d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007afbac5f8f342ca0fba2019e2bcb0e0c57021c170000000000000000000000007afbac5f8f342ca0fba2019e2bcb0e0c57021c170000000000000000000000000000000000000000000000000c7d713b49da000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1072,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ee9d1d1eb00e090ff0a7f7c9a835007a623a249f000000000000000000000000ee9d1d1eb00e090ff0a7f7c9a835007a623a249f0000000000000000000000000000000000000000000000000000000002160ec000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1074,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000001c9e6a87b6ebf2f7099b04ac2fc4b6f0005688d30000000000000000000000001c9e6a87b6ebf2f7099b04ac2fc4b6f0005688d300000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000e6b811ace2fad511e2f35d702a2cd93f703b71b0000000000000000000000000e6b811ace2fad511e2f35d702a2cd93f703b71b00000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031c09f0616532f7a6f33d9ee4e1f45ea529481af00000000000000000000000031c09f0616532f7a6f33d9ee4e1f45ea529481af00000000000000000000000000000000000000000000000000aac7dfc7dd62a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007455898a8f461ceb5510c3f264b7290499501b5b0000000000000000000000007455898a8f461ceb5510c3f264b7290499501b5b00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025fb6a2730570702f9b2b5eba96a3cbb5e5b7fc300000000000000000000000025fb6a2730570702f9b2b5eba96a3cbb5e5b7fc30000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7debb68f2684074ec4354b68e36c34af363fd57000000000000000000000000a7debb68f2684074ec4354b68e36c34af363fd57000000000000000000000000000000000000000000000000026ac2d90ac6917c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbfb506a75cb4c32e6ed7490335de139ee0f69c0000000000000000000000000fbfb506a75cb4c32e6ed7490335de139ee0f69c0000000000000000000000000000000000000000000000000008a176a7ce1acba00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1095,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d35d60b1746caec2289c892eac7351d66d63455b000000000000000000000000d35d60b1746caec2289c892eac7351d66d63455b00000000000000000000000000000000000000000000000150328c82881d9f7a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1096,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9786da5d3abb6c404b79df28b7f402e58ef7c5b000000000000000000000000a9786da5d3abb6c404b79df28b7f402e58ef7c5b0000000000000000000000000000000000000000000000000398c13ef7a9113900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000327b9dee1830f8201efa751fd96f7b1ad0b300a1000000000000000000000000327b9dee1830f8201efa751fd96f7b1ad0b300a1000000000000000000000000000000000000000000000000cbdacd745c23cceb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc9d484c7376c5ce6e8357e9c349536f3d32229135d97337e5c3282e173fd5b98,2022-02-26 07:10:11.000 UTC,0,true +1099,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000068f180fcce6836688e9084f035309e29bf0a209500000000000000000000000054174d013e49a80b91ee14f819cadbf59fdaea1400000000000000000000000054174d013e49a80b91ee14f819cadbf59fdaea14000000000000000000000000000000000000000000000000000000000008cd7100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1100,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092eead2ea4b7044692dfdd524008c36c03b632fd00000000000000000000000092eead2ea4b7044692dfdd524008c36c03b632fd000000000000000000000000000000000000000000000000002b42758471029400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1103,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000f5aa47a543f7e083f99d4b978653ec9abb621b30000000000000000000000000f5aa47a543f7e083f99d4b978653ec9abb621b3000000000000000000000000000000000000000000000001158e460913d0000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1104,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000536a32e1448cc9e8910d319d8d4639abfb13fbd9000000000000000000000000536a32e1448cc9e8910d319d8d4639abfb13fbd900000000000000000000000000000000000000000000000000591d87458a455a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9d8b2ee00469d536cff87ebcd96a9a17ebb1fd7000000000000000000000000b9d8b2ee00469d536cff87ebcd96a9a17ebb1fd7000000000000000000000000000000000000000000000000001d6516992cd65c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1106,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b9d8b2ee00469d536cff87ebcd96a9a17ebb1fd7000000000000000000000000b9d8b2ee00469d536cff87ebcd96a9a17ebb1fd70000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cc8e16afefc8819fa51bd6206632d97a306f8320000000000000000000000002cc8e16afefc8819fa51bd6206632d97a306f83200000000000000000000000000000000000000000000000003537258ab134b2f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1115,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006487ab75368b2d73a0aee92399253e41bc4487a2000000000000000000000000000000000000000000000001edff8724f21d6d8c,,,1,true +1117,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfdda5827ed343b94e96a8fef9186646477753ac000000000000000000000000cfdda5827ed343b94e96a8fef9186646477753ac000000000000000000000000000000000000000000000000008c2224c367840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1118,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1cff704c6e6ce459e3e1544a9533cccbdad7b99000000000000000000000000f1cff704c6e6ce459e3e1544a9533cccbdad7b9900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1119,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d801699678375e43d14f67453e24f17ebbaef8a0000000000000000000000000d801699678375e43d14f67453e24f17ebbaef8a00000000000000000000000000000000000000000000000000ac0779dac4ca4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e421b5c6680bb06f25e0f8dd138c96913d2c1599000000000000000000000000e421b5c6680bb06f25e0f8dd138c96913d2c1599000000000000000000000000000000000000000000000000002137cc6296179500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1125,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002e8c157bd8bfede1beafc20c68981ee0053da0ca0000000000000000000000002e8c157bd8bfede1beafc20c68981ee0053da0ca000000000000000000000000000000000000000000000004a14257f7a4baaeb800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1126,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c297434911d5a22eef2925a63e78d211a77c31c40000000000000000000000000000000000000000000000056bc75e2d6310001d,0x43059fc4e3f0fdb2a5a047225f80b2af5063aa96226f6785ac247bea7710d950,2022-02-21 21:34:49.000 UTC,0,true +1130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4e076ec8c75afea19a8ae686104d3a819ce8bd5000000000000000000000000e4e076ec8c75afea19a8ae686104d3a819ce8bd5000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ee9d1d1eb00e090ff0a7f7c9a835007a623a249f000000000000000000000000ee9d1d1eb00e090ff0a7f7c9a835007a623a249f0000000000000000000000000000000000000000000000000000000000e4e1c000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1157,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016613d9c9f1fec0b1e08233602d7dedf27c5c86800000000000000000000000016613d9c9f1fec0b1e08233602d7dedf27c5c868000000000000000000000000000000000000000000000000012127e9d6e2624c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a1037e4c9599ca3b64193b3f255e3b47890caae0000000000000000000000000a1037e4c9599ca3b64193b3f255e3b47890caae00000000000000000000000000000000000000000000000000af2616bb6d400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ef9e17f94a39daedc52dd45b4354a9b49991d350000000000000000000000007ef9e17f94a39daedc52dd45b4354a9b49991d3500000000000000000000000000000000000000000000000000b9bfcc07ade21e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1164,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000264d8292fe15333f0ac54b859b5397c4d4bcbabd000000000000000000000000264d8292fe15333f0ac54b859b5397c4d4bcbabd000000000000000000000000000000000000000000000000015221e1bab1164c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1166,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000009f3716cb735a5caf42998c420f77a9c8a13fd3a40000000000000000000000009f3716cb735a5caf42998c420f77a9c8a13fd3a4000000000000000000000000000000000000000000000002b5e3af16b188000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1169,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000dbf6045e565f0a2ad62bca011b9878c1a4d111b6000000000000000000000000000000000000000000000004e72df8d23ac74482,,,1,true +1170,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e8b65b125afd293cdb2b496c4035ebf63e4d56a9000000000000000000000000e8b65b125afd293cdb2b496c4035ebf63e4d56a9000000000000000000000000000000000000000000000000cde8cfe6dadc110200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1171,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000010d823b4818f2454d57a33311eab952c87f40fa90000000000000000000000000000000000000000000000007b21c4eec19fa8d2,,,1,true +1173,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001854bb7718e8c5216de23d2e3eb5207d6d6d1a3a0000000000000000000000001854bb7718e8c5216de23d2e3eb5207d6d6d1a3a000000000000000000000000000000000000000000000000001e1c39e39c058700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1174,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c5cf11a157937d8ead1c0c3782b52f820f9bf880000000000000000000000000000000000000000000000003df1c2e53242c4ee8,,,1,true +1175,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ac87fbbf35e5504bee8daec50bef75d43ce20d920000000000000000000000000000000000000000000000004687a54cf7eba7b0,,,1,true +1176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005989ed76aa0ffc2d6b554d3867ae503e1e83f9800000000000000000000000005989ed76aa0ffc2d6b554d3867ae503e1e83f980000000000000000000000000000000000000000000000000007618a9245c66e400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x63878412d8bdc9a60b7a7f18aa5d1873578115ee55fd11e60f677f15fb87b899,2022-04-17 07:30:44.000 UTC,0,true +1178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003374af09950ad2f02524f2edec52ecd62846c5080000000000000000000000003374af09950ad2f02524f2edec52ecd62846c508000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002127575c191bd304072ee2325c007758243f6c2c0000000000000000000000002127575c191bd304072ee2325c007758243f6c2c000000000000000000000000000000000000000000000000004e48214fce08dc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb72b4fd0e3de5e2794cbf55745102a047aeeb75000000000000000000000000bb72b4fd0e3de5e2794cbf55745102a047aeeb7500000000000000000000000000000000000000000000000001388521ac47684600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1184,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002585d2b16bda2dbd183f2c3f0da9d38917b0a32a0000000000000000000000002585d2b16bda2dbd183f2c3f0da9d38917b0a32a000000000000000000000000000000000000000000000000004e1b760415c38500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d4cc652125ec9fd6db625f78f2a8bd9c3ba65db0000000000000000000000000d4cc652125ec9fd6db625f78f2a8bd9c3ba65db0000000000000000000000000000000000000000000000000afcb78257a172d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1186,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005285a30ecdc23188a46c0b0d9b16aa7c9490a0610000000000000000000000005285a30ecdc23188a46c0b0d9b16aa7c9490a0610000000000000000000000000000000000000000000000000080c5f981ab9bce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1192,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bed68d4550c1cb3e57eb350031a38323545add92000000000000000000000000bed68d4550c1cb3e57eb350031a38323545add92000000000000000000000000000000000000000000000000007c186d5b74baad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1193,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002f7b9f2f5f00dd2293b159b6e580a01e8da7acb10000000000000000000000002f7b9f2f5f00dd2293b159b6e580a01e8da7acb1000000000000000000000000000000000000000000000000000000001dcd650000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1197,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d7b1d6a7f71a9658a41b6d918ac89d8ff849d9f0000000000000000000000000d7b1d6a7f71a9658a41b6d918ac89d8ff849d9f00000000000000000000000000000000000000000000000000000000006756d0500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1198,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000061fd58a054249e2f2360bdf2b84751c453c5415c00000000000000000000000061fd58a054249e2f2360bdf2b84751c453c5415c0000000000000000000000000000000000000000000000000000000010c96f0d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061fd58a054249e2f2360bdf2b84751c453c5415c00000000000000000000000061fd58a054249e2f2360bdf2b84751c453c5415c00000000000000000000000000000000000000000000000000301819e71d72f000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1200,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000c6a45502408c9387442a2c7311fadb9fcfe3894c000000000000000000000000c6a45502408c9387442a2c7311fadb9fcfe3894c000000000000000000000000000000000000000000000000000000000fcff4c500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1201,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6a45502408c9387442a2c7311fadb9fcfe3894c000000000000000000000000c6a45502408c9387442a2c7311fadb9fcfe3894c000000000000000000000000000000000000000000000000002c89cbf199b81400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1202,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000a92380b1ca69ac47d1ea14af62d85a54461c7770000000000000000000000000a92380b1ca69ac47d1ea14af62d85a54461c7770000000000000000000000000000000000000000000000000000000006eaf84f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1203,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a92380b1ca69ac47d1ea14af62d85a54461c7770000000000000000000000000a92380b1ca69ac47d1ea14af62d85a54461c7770000000000000000000000000000000000000000000000000012754918ea8e4b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d6d92fc686d58b39a0e340364f7d2c476042d210000000000000000000000000d6d92fc686d58b39a0e340364f7d2c476042d21000000000000000000000000000000000000000000000000000e1825bac0c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1205,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000003b9288ba5dcc2051b1cd243bbaeddec8149ec50c0000000000000000000000003b9288ba5dcc2051b1cd243bbaeddec8149ec50c000000000000000000000000000000000000000000000000000000000661167000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b9288ba5dcc2051b1cd243bbaeddec8149ec50c0000000000000000000000003b9288ba5dcc2051b1cd243bbaeddec8149ec50c000000000000000000000000000000000000000000000000000d3b583ed1457000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e12e1354ce5b1b9f34fbdfb9a1d5c202ba772a8b000000000000000000000000e12e1354ce5b1b9f34fbdfb9a1d5c202ba772a8b000000000000000000000000000000000000000000000000000000001d2dcfbc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000b9e28d206a8b83d49adc829cf9436967e2271cbb000000000000000000000000b9e28d206a8b83d49adc829cf9436967e2271cbb00000000000000000000000000000000000000000000000000000000257a9b9000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1211,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4fb4c2c91735cae6c2f4460351fbc2cf7fefeeb000000000000000000000000b4fb4c2c91735cae6c2f4460351fbc2cf7fefeeb00000000000000000000000000000000000000000000000000131459b9a8e14000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1213,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032fbefd8c98f4c0e5a32065d738311a40753cf6800000000000000000000000032fbefd8c98f4c0e5a32065d738311a40753cf680000000000000000000000000000000000000000000000000031bced02db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000520fa873d99b54d9b2b81858d5a875105bdc89ce000000000000000000000000520fa873d99b54d9b2b81858d5a875105bdc89ce0000000000000000000000000000000000000000000000000b90ffea65f5212e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9b40f964ffd09289eb5673802424662bc810d48000000000000000000000000f9b40f964ffd09289eb5673802424662bc810d480000000000000000000000000000000000000000000000005f5cab4e3629e00900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x60fa219d00468668aea56eb572d0662ea1c315f27a199151706318a644549697,2021-11-26 05:15:37.000 UTC,0,true +1222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2ef0d026b5723bdeb4dc65c1e9e9847b4c8df36000000000000000000000000a2ef0d026b5723bdeb4dc65c1e9e9847b4c8df360000000000000000000000000000000000000000000000000044d552eb89410000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee20f85dd3f826700a6a42af4873a04af8ac6d75000000000000000000000000ee20f85dd3f826700a6a42af4873a04af8ac6d75000000000000000000000000000000000000000000000000013ef9cf04b74c1900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d7f583e20351d0c6d1012411522f7f1191233500000000000000000000000007d7f583e20351d0c6d1012411522f7f119123350000000000000000000000000000000000000000000000000001f8dc842d1030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000000afe81bbbbf6ef34080e6e7431933ca61760c0300000000000000000000000000afe81bbbbf6ef34080e6e7431933ca61760c0300000000000000000000000000000000000000000000000000000000808840c500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004673d1246248976ce891a39baf2b18fb54bad3f00000000000000000000000004673d1246248976ce891a39baf2b18fb54bad3f000000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fbd935c9972b6a4c0b6f7c6f650996677bf6e0a0000000000000000000000007fbd935c9972b6a4c0b6f7c6f650996677bf6e0a00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1245,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000681f284c82eb81054d6696acea2020fdc68f7ca3000000000000000000000000681f284c82eb81054d6696acea2020fdc68f7ca3000000000000000000000000000000000000000000000000000d46de5bad330000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1247,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ec9dd67af275fa69b6ecf7e4c3c4c0968a28fa80000000000000000000000001ec9dd67af275fa69b6ecf7e4c3c4c0968a28fa800000000000000000000000000000000000000000000000000292105c3ffa10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002178be208cd14257c3ff58a164a25fe510f14f9a0000000000000000000000002178be208cd14257c3ff58a164a25fe510f14f9a0000000000000000000000000000000000000000000000000096f5388ad3d8d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x59c6a1dc4b43c8a3a58854e88fead24b1c242705ea4b640c72a796d4a0c8e4e8,2022-04-28 09:29:56.000 UTC,0,true +1251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023af55034fe477c99c8eaa9586e6a21042bd39f000000000000000000000000023af55034fe477c99c8eaa9586e6a21042bd39f0000000000000000000000000000000000000000000000000011cf9cc0d600c9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1252,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c18e70163dfdb13e4057f67fbd1f4ad9c231653b000000000000000000000000c18e70163dfdb13e4057f67fbd1f4ad9c231653b00000000000000000000000000000000000000000000000001f61d86f432866000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc6f6e3d3948def0199f111b3a272555b0b18641000000000000000000000000cc6f6e3d3948def0199f111b3a272555b0b18641000000000000000000000000000000000000000000000000005166584f96c80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1261,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009241f27daffd0bb1df4f2a022584dd6c77843e640000000000000000000000009241f27daffd0bb1df4f2a022584dd6c77843e64000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072872adaea835f855d6303c130c7531208a7664200000000000000000000000072872adaea835f855d6303c130c7531208a76642000000000000000000000000000000000000000000000000004036246a43f55f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086c3d2697e675bb069a8c2d549f774cf73dcb04700000000000000000000000086c3d2697e675bb069a8c2d549f774cf73dcb04700000000000000000000000000000000000000000000000000201eef731c6a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e891f3072ea7c072e063f04ae78feed357256adc000000000000000000000000e891f3072ea7c072e063f04ae78feed357256adc00000000000000000000000000000000000000000000000000305fc5c17163dc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e843e87405219c50590da9f1c2e373b1ffc46cd2000000000000000000000000e843e87405219c50590da9f1c2e373b1ffc46cd2000000000000000000000000000000000000000000000000018785e89a3168ff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009da6e45e26a972cb86528abaeed47d010991d5650000000000000000000000009da6e45e26a972cb86528abaeed47d010991d565000000000000000000000000000000000000000000000000015947453f72902b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd7b2c3e167a1ffbda56917e13f0802affc326d5000000000000000000000000bd7b2c3e167a1ffbda56917e13f0802affc326d500000000000000000000000000000000000000000000000000237d2a77824f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007774a41c4dc14702c443140015f6aefc5989ff7f0000000000000000000000007774a41c4dc14702c443140015f6aefc5989ff7f0000000000000000000000000000000000000000000000000066ba2a33075c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2205674f3dab6aa7a87e02575d31492aa2f849164a56b0ec2213ed1726a1c3ab,2022-08-24 21:54:45.000 UTC,0,true +1281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e02e1dd6585b294b029640a929cfb11fd945f3d0000000000000000000000008e02e1dd6585b294b029640a929cfb11fd945f3d000000000000000000000000000000000000000000000000002393510ea1ed0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084c0430f3564520dcde45c3dfd7ceb79372e4fa300000000000000000000000084c0430f3564520dcde45c3dfd7ceb79372e4fa30000000000000000000000000000000000000000000000000026c7429d125c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ffe50d1f402276e73e581fb275f623c7e215f970000000000000000000000003ffe50d1f402276e73e581fb275f623c7e215f970000000000000000000000000000000000000000000000000023c12eb4de590000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1287,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2a46bd8bf27c5c1d0531dc6a61ccf6810c70127000000000000000000000000f2a46bd8bf27c5c1d0531dc6a61ccf6810c701270000000000000000000000000000000000000000000000000023eb6c86985b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa26c9b0e44ae0a6eb5a7019ef35defbac52f40b000000000000000000000000aa26c9b0e44ae0a6eb5a7019ef35defbac52f40b00000000000000000000000000000000000000000000000000248fea46a6330000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1291,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc05c664843bb1840e7bce0590ccdd7ce4145369000000000000000000000000bc05c664843bb1840e7bce0590ccdd7ce414536900000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1292,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009bac86db92e864e455a9ed08fac10c540b5fca4f0000000000000000000000000000000000000000000000033306863a53bee088,,,1,true +1293,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f032d8bbc918f7535256ab4fc6d8042f4f69f860000000000000000000000009f032d8bbc918f7535256ab4fc6d8042f4f69f8600000000000000000000000000000000000000000000000000231cf5a42f470000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001066f6f80fd2717594959a6cf5b24c4e2a348f800000000000000000000000001066f6f80fd2717594959a6cf5b24c4e2a348f8000000000000000000000000000000000000000000000000002509ce3d245b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1297,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000205319257fc9772c0add32950fac182a74dbeb3c000000000000000000000000205319257fc9772c0add32950fac182a74dbeb3c0000000000000000000000000000000000000000000000000022ff08ee5c260000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ca099a0636d7e9d1d347616ac822ff675e6e1e70000000000000000000000007ca099a0636d7e9d1d347616ac822ff675e6e1e7000000000000000000000000000000000000000000000000003ce662eae5882200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1300,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a79da05566ea8ffd181c45efd6f484616f6eadef000000000000000000000000a79da05566ea8ffd181c45efd6f484616f6eadef00000000000000000000000000000000000000000000000001cac0897fecfa8600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6cd700ecb0d37cd7cf6eaddd6b60a8ce44942c9000000000000000000000000f6cd700ecb0d37cd7cf6eaddd6b60a8ce44942c90000000000000000000000000000000000000000000000000018e8d8a3ef3a8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1302,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fbd935c9972b6a4c0b6f7c6f650996677bf6e0a0000000000000000000000007fbd935c9972b6a4c0b6f7c6f650996677bf6e0a00000000000000000000000000000000000000000000000000a4b14591901e7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005592e2e200ea9435c840d53fcc60ab5f78574fc90000000000000000000000005592e2e200ea9435c840d53fcc60ab5f78574fc900000000000000000000000000000000000000000000000000c55b3a2dea3bf800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1304,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006c15f3f8dd7418effc9090d54285f8e2af4d94a700000000000000000000000000000000000000000000000043f04042833e4ca4,,,1,true +1305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042ce658f25e182772cfe8b905f0971ef513f839100000000000000000000000042ce658f25e182772cfe8b905f0971ef513f839100000000000000000000000000000000000000000000000002b036e8e2deec8d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1308,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000b17237ee9553b7b07c0622cc436d97694cbbb53a000000000000000000000000b17237ee9553b7b07c0622cc436d97694cbbb53a0000000000000000000000000000000000000000000000000000000009c699c800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1311,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4d9c88c924079422e5ad77ee64b967ce4efd828000000000000000000000000f4d9c88c924079422e5ad77ee64b967ce4efd82800000000000000000000000000000000000000000000000000587ed569c7637e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d19f32620f647d08fa8b9a0fa5206fae15c0ed50000000000000000000000002d19f32620f647d08fa8b9a0fa5206fae15c0ed50000000000000000000000000000000000000000000000000093d286135fd7fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1319,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000dda42f12b8b2ccc6717c053a2b772bad24b08cbd00000000000000000000000000000000000000000000000029a2241af62c0000,,,1,true +1321,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bac79de245633fcc4fb32c19bc0ac93f406c9950000000000000000000000000bac79de245633fcc4fb32c19bc0ac93f406c99500000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1325,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011f3196443bfe5ad50513386e1c3826cbbd2d72f00000000000000000000000011f3196443bfe5ad50513386e1c3826cbbd2d72f00000000000000000000000000000000000000000000000000b8d560d0f4b8bd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1326,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa7ca3edcba0ebaf2eee83835881fb37710cfc87000000000000000000000000aa7ca3edcba0ebaf2eee83835881fb37710cfc8700000000000000000000000000000000000000000000000000b85e9e3992f5aa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1327,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000109bf98fabb56460bd1584e9410cf70982a80446000000000000000000000000109bf98fabb56460bd1584e9410cf70982a8044600000000000000000000000000000000000000000000000000b90497a830651700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1328,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ef540025be3d2c9932c4dcf7b9f45bf60dcb8a50000000000000000000000006ef540025be3d2c9932c4dcf7b9f45bf60dcb8a500000000000000000000000000000000000000000000000000b99942f9a1abee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a1271284ba4a1c01ed016128738005131314b4a0000000000000000000000003a1271284ba4a1c01ed016128738005131314b4a000000000000000000000000000000000000000000000000002d381090ecae9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1330,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023cfbc88ebb82e730fcd1c35225d19da1958d80500000000000000000000000023cfbc88ebb82e730fcd1c35225d19da1958d80500000000000000000000000000000000000000000000000000b9ef7a2ded708200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1331,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008752df4018957d0ad6a769a37fadd75a6a744b430000000000000000000000008752df4018957d0ad6a769a37fadd75a6a744b4300000000000000000000000000000000000000000000000000b2f2fad44fbcab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1333,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034ebbe40cc5fa34140e8b3627d6743116ee2f3c800000000000000000000000034ebbe40cc5fa34140e8b3627d6743116ee2f3c800000000000000000000000000000000000000000000000000aecb5217508d9500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1334,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c94f16940c0fb741c938e247602b130fbed1ee24000000000000000000000000c94f16940c0fb741c938e247602b130fbed1ee2400000000000000000000000000000000000000000000000000ae4b51f08e869b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1335,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fefd123d721c9a1e712b342dc7f0317760dfb8ab000000000000000000000000fefd123d721c9a1e712b342dc7f0317760dfb8ab00000000000000000000000000000000000000000000000000adba174d8a277500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1336,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064c263f0ff10b2cc940a7fad3f8b524792f39e0100000000000000000000000064c263f0ff10b2cc940a7fad3f8b524792f39e0100000000000000000000000000000000000000000000000000aee9f75b4d76c700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098098214ad5b1b08cc9d94e32f056e9a0de1811000000000000000000000000098098214ad5b1b08cc9d94e32f056e9a0de18110000000000000000000000000000000000000000000000000005a20720d1a580c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1341,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ad3532392b4a3d427f3af5c7dd3b3dd882f74439000000000000000000000000ad3532392b4a3d427f3af5c7dd3b3dd882f744390000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1344,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfbe0b8d935d6b65856c2f0eb39689abc0312e45000000000000000000000000cfbe0b8d935d6b65856c2f0eb39689abc0312e45000000000000000000000000000000000000000000000000000c67a263bf47ef00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddfba3aad19d3f466472b5ea8a5b0f77e59b4fc6000000000000000000000000ddfba3aad19d3f466472b5ea8a5b0f77e59b4fc6000000000000000000000000000000000000000000000000003d7e90b2e50e9900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fccd02660f1dfb2ce9d0f12e113da9a7aae8c071000000000000000000000000fccd02660f1dfb2ce9d0f12e113da9a7aae8c071000000000000000000000000000000000000000000000000015bc8bb5ee4fc6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1348,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ba63faeb8ccd03776b3118f4dab186c03aa05121000000000000000000000000ba63faeb8ccd03776b3118f4dab186c03aa051210000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4676e5e99b823e54b3e6c32c8143bb441633eea000000000000000000000000c4676e5e99b823e54b3e6c32c8143bb441633eea000000000000000000000000000000000000000000000000001b60a02488d03a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be53bedb9c0989c56fc1f3da448783886283d22b000000000000000000000000be53bedb9c0989c56fc1f3da448783886283d22b000000000000000000000000000000000000000000000000001836e549dfab7500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1356,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032730120eeeb23d0e1bd4e16cc7c5247906382e000000000000000000000000032730120eeeb23d0e1bd4e16cc7c5247906382e0000000000000000000000000000000000000000000000000007a3ff2645cc48400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1357,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbfb506a75cb4c32e6ed7490335de139ee0f69c0000000000000000000000000fbfb506a75cb4c32e6ed7490335de139ee0f69c000000000000000000000000000000000000000000000000000b33994503a2ab600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1358,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c388750a661cc0b99784bab2c55e1f38ff91643b000000000000000000000000c388750a661cc0b99784bab2c55e1f38ff91643b00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dadc03cd1b8b08b1bf60d3ef62bbe7f38ebeb216000000000000000000000000dadc03cd1b8b08b1bf60d3ef62bbe7f38ebeb216000000000000000000000000000000000000000000000000004c8d4405a4f87f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1366,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000257e746c20c91c84c06ca539675ff2981b35e35d000000000000000000000000257e746c20c91c84c06ca539675ff2981b35e35d000000000000000000000000000000000000000000000000002b0890e8c866b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcddbef2353c0d633879b9da8fdfdce83ef160a08864a9f60ed200315fc0581da,2022-05-28 14:53:49.000 UTC,0,true +1372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fa20d37e4dfbf3e8b22831f53ba028b753573950000000000000000000000004fa20d37e4dfbf3e8b22831f53ba028b7535739500000000000000000000000000000000000000000000000000a29fb3d5950e4500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1373,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000989d21bd4ab37e523f7347a2cc54ef824b2f23eb000000000000000000000000989d21bd4ab37e523f7347a2cc54ef824b2f23eb00000000000000000000000000000000000000000000000000a35d5697c301f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bdfe729e88070da6ae6b7bb9e85ce3c5fe204c30000000000000000000000001bdfe729e88070da6ae6b7bb9e85ce3c5fe204c300000000000000000000000000000000000000000000000000a1c9871d844ccf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1375,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb019359cd737d13d6391a18443b8b8a847f120b000000000000000000000000cb019359cd737d13d6391a18443b8b8a847f120b00000000000000000000000000000000000000000000000000a1b6c6a421e0f400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f8cd600c59dfd1f60b4a9472805e5e6e074155d0000000000000000000000003f8cd600c59dfd1f60b4a9472805e5e6e074155d00000000000000000000000000000000000000000000000000a195cab4cdacdc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024f2716cf24cc67f04b893049de5f3ef134c40d800000000000000000000000024f2716cf24cc67f04b893049de5f3ef134c40d800000000000000000000000000000000000000000000000000a157f9d3c8d58000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1378,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004290f59947ea594e396ae1147fb3c4b029209bda0000000000000000000000004290f59947ea594e396ae1147fb3c4b029209bda00000000000000000000000000000000000000000000000000a01ffe00551d7e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1380,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fe922789c0bd45e837e2becf103a1b456b52a260000000000000000000000008fe922789c0bd45e837e2becf103a1b456b52a26000000000000000000000000000000000000000000000000009d58108f2dd84f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1381,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f32844357f27d8c185255832b914dd7e3ecfb9a0000000000000000000000008f32844357f27d8c185255832b914dd7e3ecfb9a000000000000000000000000000000000000000000000000009bf5556607f1ec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1382,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd52c13827f012797005f57e4db3b8db155580f2000000000000000000000000bd52c13827f012797005f57e4db3b8db155580f2000000000000000000000000000000000000000000000000009cfe2281354f1400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056c9656662fad432973e8743e1f6d2a79df61a3500000000000000000000000056c9656662fad432973e8743e1f6d2a79df61a35000000000000000000000000000000000000000000000000002e4e5c43094c6600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fc914aeba65ae085469f9830070f0ef731b43d00000000000000000000000007fc914aeba65ae085469f9830070f0ef731b43d0000000000000000000000000000000000000000000000000003ca40d113c15f300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1389,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a03fcdd101ce5b7ac2e072df832866f918c572ff000000000000000000000000a03fcdd101ce5b7ac2e072df832866f918c572ff000000000000000000000000000000000000000000000000002a2c43ad31ca8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000007e2e5d94f11f358345a4ee14c4f1a8521315c03b0000000000000000000000007e2e5d94f11f358345a4ee14c4f1a8521315c03b0000000000000000000000000000000000000000000000000000000003831e1200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xbfbddc67d3be7a066fece984550e230e093b3e2c3cf382933224c0def974889f,2022-07-03 01:24:31.000 UTC,0,true +1395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e2e5d94f11f358345a4ee14c4f1a8521315c03b0000000000000000000000007e2e5d94f11f358345a4ee14c4f1a8521315c03b0000000000000000000000000000000000000000000000000000339234aa9be200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd8c53105ff2eae627eae60dce8aa62cb0452b5aeb72a47d6f005d9ccf1188258,2022-07-03 00:19:21.000 UTC,0,true +1396,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000001162e3d2c6771b3eca319d054e554ffacf5549000000000000000000000000001162e3d2c6771b3eca319d054e554ffacf55490000000000000000000000000000000000000000000000000cbd9f6b17c75e59300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1397,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000001162e3d2c6771b3eca319d054e554ffacf5549000000000000000000000000001162e3d2c6771b3eca319d054e554ffacf5549000000000000000000000000000000000000000000000000b80313c52f0bab66600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f3c06b4c50b17b4ceaa9d609356ebd57963d0110000000000000000000000006f3c06b4c50b17b4ceaa9d609356ebd57963d01100000000000000000000000000000000000000000000000000a6f2d46fcbbb6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d9e6cd0e64a4e989499b1b4995570eec94519260000000000000000000000007d9e6cd0e64a4e989499b1b4995570eec945192600000000000000000000000000000000000000000000000000a5594a6814449c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff6097d4c652481f1a1e3f25f7a5edc9f5d5625b000000000000000000000000ff6097d4c652481f1a1e3f25f7a5edc9f5d5625b00000000000000000000000000000000000000000000000000a35ee2cc6ed62700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013d77053696d78eb23e64e503787163df9967b5a00000000000000000000000013d77053696d78eb23e64e503787163df9967b5a00000000000000000000000000000000000000000000000000a3d8d41242c90c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1402,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6e068e68ee243b856b57098310ce0f8b2e57e12000000000000000000000000e6e068e68ee243b856b57098310ce0f8b2e57e1200000000000000000000000000000000000000000000000000a26dc3fa3b373000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092f7dfb5bfa167674441da031657417a0aaf3d8b00000000000000000000000092f7dfb5bfa167674441da031657417a0aaf3d8b00000000000000000000000000000000000000000000000000a2abe30e92503600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e47a137646c4499d9ca0c592224608f2f0d36cbe000000000000000000000000e47a137646c4499d9ca0c592224608f2f0d36cbe00000000000000000000000000000000000000000000000000a3b3836be701c100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001162e3d2c6771b3eca319d054e554ffacf5549000000000000000000000000001162e3d2c6771b3eca319d054e554ffacf554900000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f567a6ca93dec3203344094cb90f035cc853a248000000000000000000000000f567a6ca93dec3203344094cb90f035cc853a2480000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af7b3c54e066c54e4bfc08762678fd1bc2ade9b4000000000000000000000000af7b3c54e066c54e4bfc08762678fd1bc2ade9b400000000000000000000000000000000000000000000000000a21751a301fe0400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004b6c1d2c9ea868e8e37c035e1c7fcadd475d26000000000000000000000000004b6c1d2c9ea868e8e37c035e1c7fcadd475d26000000000000000000000000000000000000000000000000000a2cb95d6f78f6700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1409,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000032dda2351fd5d613db8dba322ef7a5e4fa08c83000000000000000000000000032dda2351fd5d613db8dba322ef7a5e4fa08c8300000000000000000000000000000000000000000000000000a263954eed155a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1410,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c877fcc358da9eb76f53aeebfbbdb6eefa0b313d00000000000000000000000000000000000000000000000e962d83195749bb35,0x64d2a01996b640311514acbd698e0870a5b9adc9ce3040338c0c521d0224439e,2021-11-23 09:17:37.000 UTC,0,true +1411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000125a2c1f7f2de8e47625c83e5eb012ab9ee9d113000000000000000000000000125a2c1f7f2de8e47625c83e5eb012ab9ee9d1130000000000000000000000000000000000000000000000000155e4498bb3208700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2181b9f7cc9c66e84f8811c0d94fda83a1a78459d49863d45748701d501273c9,2022-07-19 19:02:36.000 UTC,0,true +1414,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077109daf4c36b0af7975f539d22528b92f82ecae00000000000000000000000077109daf4c36b0af7975f539d22528b92f82ecae000000000000000000000000000000000000000000000000002ff3041cae3b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1418,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000706e8a1de4f372df952e26f01b6b7611b917bd2d000000000000000000000000706e8a1de4f372df952e26f01b6b7611b917bd2d0000000000000000000000000000000000000000000000000024f12ac0b6ff0900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082683f46c69e068f244d86103317b37ebbf9377900000000000000000000000082683f46c69e068f244d86103317b37ebbf937790000000000000000000000000000000000000000000000000010dbe79ee47c7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a62a664974939513f165703e76ab8e16ac8eb170000000000000000000000006a62a664974939513f165703e76ab8e16ac8eb170000000000000000000000000000000000000000000000000078e3288e5dfd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1427,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025b99f078903f7702d3f44b1f8a4fe88bc5d103600000000000000000000000025b99f078903f7702d3f44b1f8a4fe88bc5d1036000000000000000000000000000000000000000000000000000ffcb9e57d400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4a3fbd2434c9c1e846a039be62050a08b9fe783000000000000000000000000d4a3fbd2434c9c1e846a039be62050a08b9fe78300000000000000000000000000000000000000000000000002d30a217f0bd7a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fff2bcc4313a064d8655b6911bc2db2b9e1c9c98000000000000000000000000fff2bcc4313a064d8655b6911bc2db2b9e1c9c980000000000000000000000000000000000000000000000000003d12e9b292e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025f500fc10b0ce86cbe34b2290dc476742a8e0b900000000000000000000000025f500fc10b0ce86cbe34b2290dc476742a8e0b9000000000000000000000000000000000000000000000000004007ea86d6b90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1441,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089768ca7e116d7971519af950dbbdf6e80b9ded100000000000000000000000089768ca7e116d7971519af950dbbdf6e80b9ded1000000000000000000000000000000000000000000000000030d98d59a96000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d12301bcb812dbb016fbfa0faec1c1cb71ddc05f000000000000000000000000d12301bcb812dbb016fbfa0faec1c1cb71ddc05f00000000000000000000000000000000000000000000000000a5d8df81d7a1a700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1452,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000517905ce3f8193c46421b2f03312986efbd8874e000000000000000000000000517905ce3f8193c46421b2f03312986efbd8874e000000000000000000000000000000000000000000000000112865cc2351ee7a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1453,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bad367c336522f7a47e18d51c1287bd55c681120000000000000000000000001bad367c336522f7a47e18d51c1287bd55c6811200000000000000000000000000000000000000000000000000a5088d5fc63e0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1454,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ece2b12273e6d56d54f2034f71fe8db1805bc394000000000000000000000000ece2b12273e6d56d54f2034f71fe8db1805bc39400000000000000000000000000000000000000000000000000a5b2f7188b274f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1455,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ef7ec56d7d633a2c82af24f15a24182930310510000000000000000000000006ef7ec56d7d633a2c82af24f15a241829303105100000000000000000000000000000000000000000000000000a31ba5d9b31daa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000113be48e08958c98a066a9d21f0e0c6e9f4ce120000000000000000000000000113be48e08958c98a066a9d21f0e0c6e9f4ce1200000000000000000000000000000000000000000000000000a597e0b0b8bb6700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000701f52342947c3bd1f20464b8d40e0c6333bc1a0000000000000000000000000701f52342947c3bd1f20464b8d40e0c6333bc1a000000000000000000000000000000000000000000000000000a5c695375318f300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1458,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000946d691877f1775bf7e86ffbdabbb571ed8cfc3c000000000000000000000000946d691877f1775bf7e86ffbdabbb571ed8cfc3c00000000000000000000000000000000000000000000000000a7408840091e5500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e993f9f9f90205753dd99c85429b302770a7ea78000000000000000000000000e993f9f9f90205753dd99c85429b302770a7ea7800000000000000000000000000000000000000000000000000a5c6af5b5ba35500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da8cc3a462f7086a929f7cb985e9b937807cc165000000000000000000000000da8cc3a462f7086a929f7cb985e9b937807cc16500000000000000000000000000000000000000000000000000a517ce8c76281700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1461,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b327885341a84bb07a4c9d620e3c345e1b384349000000000000000000000000b327885341a84bb07a4c9d620e3c345e1b38434900000000000000000000000000000000000000000000000000a2cb67bda4c7cf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008969af66165d93f6124899f5af946635e1645d470000000000000000000000008969af66165d93f6124899f5af946635e1645d4700000000000000000000000000000000000000000000000000a2e77eb04f5f9a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eacb7edd74f53c4f8c7445cd55381e4b096fec10000000000000000000000000eacb7edd74f53c4f8c7445cd55381e4b096fec1000000000000000000000000000000000000000000000000000a31ba81d47e3bb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1464,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da1c5760fc4c48b3eae7c28b3cb53b3a8271035a000000000000000000000000da1c5760fc4c48b3eae7c28b3cb53b3a8271035a00000000000000000000000000000000000000000000000000a3c26a35dab4da00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087694c0a265346e6a3bfab4f1ae6b14eda7849c900000000000000000000000087694c0a265346e6a3bfab4f1ae6b14eda7849c900000000000000000000000000000000000000000000000000a1bfad5a02737d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065e8d46a51ce9b5e83a72409c4257b2971f4217700000000000000000000000065e8d46a51ce9b5e83a72409c4257b2971f4217700000000000000000000000000000000000000000000000000a30aad6803ed6e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5e581cb20e40bdb884e6647c96ecb2a51b13cbe000000000000000000000000a5e581cb20e40bdb884e6647c96ecb2a51b13cbe00000000000000000000000000000000000000000000000000a5ee0e93a9ca5700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1468,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ef3077374ce35b8c937eb22d1c85a71a2f79aeb0000000000000000000000005ef3077374ce35b8c937eb22d1c85a71a2f79aeb00000000000000000000000000000000000000000000000000a53791a384c4e700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000deea5b37603f88936f9ab2a932a4521b1e331c8a000000000000000000000000deea5b37603f88936f9ab2a932a4521b1e331c8a00000000000000000000000000000000000000000000000000a51a942d68312c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea3a5cb144b9922ada2a0148124a522cc3c00fa1000000000000000000000000ea3a5cb144b9922ada2a0148124a522cc3c00fa100000000000000000000000000000000000000000000000000a46a02456edf8e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000225d2b448852d9d582bdc262d1a37bf823650080000000000000000000000000225d2b448852d9d582bdc262d1a37bf8236500800000000000000000000000000000000000000000000000000a3de4a49757fde00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000748010fbe056562ef466901f1d38ce481f11b539000000000000000000000000748010fbe056562ef466901f1d38ce481f11b539000000000000000000000000000000000000000000000000000000001125d3b200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1479,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6ef13a56e52cf128d0881a4fcf1105754d7682e000000000000000000000000b6ef13a56e52cf128d0881a4fcf1105754d7682e000000000000000000000000000000000000000000000000005cc7a3362ea0e400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1481,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000002df99be208467d5b050d333244cdac0a998338e0000000000000000000000000000000000000000000000004563918244f40000,,,1,true +1485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf17fe365b6a160b48d8b2ba76f8a55becf4c7c1000000000000000000000000bf17fe365b6a160b48d8b2ba76f8a55becf4c7c100000000000000000000000000000000000000000000000000fcdc390dc0c13200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1487,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e84c2e90afec8491f94dd477bd11657cefc76900000000000000000000000002e84c2e90afec8491f94dd477bd11657cefc769000000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1492,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000818aa87368876d6864e64aa256cc6a2a43b54207000000000000000000000000818aa87368876d6864e64aa256cc6a2a43b542070000000000000000000000000000000000000000000000034214be8f108edb1a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1499,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a5372ec86fa34436299a95d3c10f0d721cdd018a00000000000000000000000000000000000000000000000214df071e9d692338,,,1,true +1501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa08a02f79951f410edf661b0f23202e9681e4c8000000000000000000000000aa08a02f79951f410edf661b0f23202e9681e4c8000000000000000000000000000000000000000000000000001acff920bde8d300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1502,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e66bb5ef7359906b46d2a99b10fbefb643526fa3000000000000000000000000e66bb5ef7359906b46d2a99b10fbefb643526fa3000000000000000000000000000000000000000000000000029f79a3e8e804c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090a7b41610a25f7bf538bd27dc6e0434bd38933200000000000000000000000090a7b41610a25f7bf538bd27dc6e0434bd38933200000000000000000000000000000000000000000000000000109581ed03f62200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000090a7b41610a25f7bf538bd27dc6e0434bd38933200000000000000000000000090a7b41610a25f7bf538bd27dc6e0434bd38933200000000000000000000000000000000000000000000000000000000023161ee00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1508,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003bd59ed16c462b4464091830dab828dce079076f000000000000000000000000000000000000000000000000316a92244d1ca800,0x0c89331ede9019a096912f6686d40b5bc109782815dbb9ccc93199b577f5998c,2021-11-25 23:30:38.000 UTC,0,true +1509,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009e63e63554469e0c98450c58e1472fdde65c07ec0000000000000000000000000000000000000000000000003782dace9d900000,,,1,true +1510,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b9afc24c66d04f773c97d733e4c058a0784fd88a0000000000000000000000000000000000000000000000002725ef1d20bf9400,,,1,true +1511,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007113457d2eb745bfaf2edcb586bc25658d637b7a0000000000000000000000007113457d2eb745bfaf2edcb586bc25658d637b7a0000000000000000000000000000000000000000000000000022764ad44f2a2400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061d04270a849004364795f5f3fde33a2068383fb00000000000000000000000061d04270a849004364795f5f3fde33a2068383fb00000000000000000000000000000000000000000000000000214880fac9e20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1525,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3320b4b93a482924a299334c5cb6c0fd7ca0fd3000000000000000000000000c3320b4b93a482924a299334c5cb6c0fd7ca0fd3000000000000000000000000000000000000000000000000014c55bb915e969b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1526,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ac0b447d5d976b1ec7d8a885c937e0efcc7edbe0000000000000000000000000ac0b447d5d976b1ec7d8a885c937e0efcc7edbe000000000000000000000000000000000000000000000000053c376bd45e001c700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x187a81c216dae186bad5bb5a505ac8c0a2418655808fb05f811907f539966a7b,2022-07-10 05:14:15.000 UTC,0,true +1528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008edb42bed2a8f10188096e2f90336e853deaac030000000000000000000000008edb42bed2a8f10188096e2f90336e853deaac03000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1532,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2e5d220874222ca63e45c419cc226c5f35e47bb000000000000000000000000d2e5d220874222ca63e45c419cc226c5f35e47bb000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d0ebdfceee6e8fd3e9be7032c671ecbd2d229032000000000000000000000000d0ebdfceee6e8fd3e9be7032c671ecbd2d229032000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002aaa03a8293053bd4b7fa1740ac94d935c66ee840000000000000000000000002aaa03a8293053bd4b7fa1740ac94d935c66ee8400000000000000000000000000000000000000000000000001550db544c8362b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000ef1ed3d10ce1c766291c7cf9153e1076a4220c20000000000000000000000000ef1ed3d10ce1c766291c7cf9153e1076a4220c20000000000000000000000000000000000000000000000000000000000f0f97000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1539,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d842bbf50af49dd35291737a139852b7bc48dce0000000000000000000000009d842bbf50af49dd35291737a139852b7bc48dce0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1542,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000d7c96322a62573b509ee0b1266e7aa713662c1300000000000000000000000000000000000000000000003683daaee596dcfdb4,,,1,true +1548,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006719dc6c087ec40261bf08ac1286fa4ceeb6c92500000000000000000000000000000000000000000000000367d3c36a5d62d210,,,1,true +1549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fe6a806e0a9858359e16c58e4f84c790171596b0000000000000000000000001fe6a806e0a9858359e16c58e4f84c790171596b00000000000000000000000000000000000000000000000000ed380acce0bf5800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1550,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033e580cee928d83a61b98905a1f9be68ea6279b800000000000000000000000033e580cee928d83a61b98905a1f9be68ea6279b800000000000000000000000000000000000000000000000003d6260ef6d43f3500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1551,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b3d381c886f47bd2c091ae7c785229aaf140b0e900000000000000000000000000000000000000000000000f742888823a4f73d0,0x4eaa1f74b5612b0dbf69e36a42e7c34f672541ef8d2f55fff126d6d7984ebb23,2022-04-10 12:27:58.000 UTC,0,true +1554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095b683dce50361469742e5184be34a7c6c02b78b00000000000000000000000095b683dce50361469742e5184be34a7c6c02b78b000000000000000000000000000000000000000000000000031fb736e764cce000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1c675dad880d1887c20b101e9a8fb604e6ad4eb000000000000000000000000c1c675dad880d1887c20b101e9a8fb604e6ad4eb000000000000000000000000000000000000000000000000005cbb9a209baeae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ab525dd1016e88f68ca3832c943dbbfd577806e0000000000000000000000006ab525dd1016e88f68ca3832c943dbbfd577806e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1595,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df10b1d95073a395b4ac15aba63edca8c0bcfea2000000000000000000000000df10b1d95073a395b4ac15aba63edca8c0bcfea200000000000000000000000000000000000000000000000000406b2a9cb110c500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1678,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c688cc5298ce97cf5b82a88229f3a40e3bf25530000000000000000000000000c688cc5298ce97cf5b82a88229f3a40e3bf255300000000000000000000000000000000000000000000000011dbe1f2dd930b4e200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b41167f0729aa2b8adb237474a134659e8f279e7000000000000000000000000b41167f0729aa2b8adb237474a134659e8f279e700000000000000000000000000000000000000000000000000aae1ff661e8dc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012d8bfd7284b36e77501e842a3222b5f8f30bf2f00000000000000000000000012d8bfd7284b36e77501e842a3222b5f8f30bf2f00000000000000000000000000000000000000000000000000008f9f8c8ac68500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000421cc7b6224accb6c12280e3b697c65d9d60ad70000000000000000000000000421cc7b6224accb6c12280e3b697c65d9d60ad7000000000000000000000000000000000000000000000000000437e2b560d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085ea4171aec13c433b87a303f9c6dda1da4c619b00000000000000000000000085ea4171aec13c433b87a303f9c6dda1da4c619b000000000000000000000000000000000000000000000000006da44d320b725c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acaec28670ff7ca851d4d802b123ac7c6dac25e3000000000000000000000000acaec28670ff7ca851d4d802b123ac7c6dac25e300000000000000000000000000000000000000000000000000089d8c5db7e3c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1705,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000052eebd82826a7b530839424ceab6ca3643eb0ef100000000000000000000000000000000000000000000000a5805f66b648d7777,,,1,true +1706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089768ca7e116d7971519af950dbbdf6e80b9ded100000000000000000000000089768ca7e116d7971519af950dbbdf6e80b9ded100000000000000000000000000000000000000000000000000e3c5ab9623177000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000163f875efda73c07f2035f21d532c57131afa09d000000000000000000000000163f875efda73c07f2035f21d532c57131afa09d00000000000000000000000000000000000000000000000000ec2c4aae16cef300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1708,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e6640ac10ddf31aeb3a88d7853496c0955388a30000000000000000000000009e6640ac10ddf31aeb3a88d7853496c0955388a300000000000000000000000000000000000000000000000000f1f1a3671aefae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1710,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001dd7c29dba3cfc8cd64220f7331e214a791a59890000000000000000000000001dd7c29dba3cfc8cd64220f7331e214a791a598900000000000000000000000000000000000000000000000001e76082dbe1ae5700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1711,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007819bffd6a93a941f9c9c68bb6eda17766fbe6090000000000000000000000007819bffd6a93a941f9c9c68bb6eda17766fbe60900000000000000000000000000000000000000000000000000faa9790caf06c500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1712,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9bb68e9735de702cbf517aa6c2fb6a36a13b0ce000000000000000000000000c9bb68e9735de702cbf517aa6c2fb6a36a13b0ce0000000000000000000000000000000000000000000000000081eff3be3833cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f7b076d0fcc7641eb968b4bf9983a830699d92a0000000000000000000000004f7b076d0fcc7641eb968b4bf9983a830699d92a00000000000000000000000000000000000000000000000000f556aecaa6d3cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6b070f15d10a39f429f25d10bbef42265b94dd1000000000000000000000000d6b070f15d10a39f429f25d10bbef42265b94dd1000000000000000000000000000000000000000000000000007d27de7f56687500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1715,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f71479d0e613ca73523e4f5d2051bd5c0003636d000000000000000000000000f71479d0e613ca73523e4f5d2051bd5c0003636d00000000000000000000000000000000000000000000000000f989b60b2663ea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006889f4dde0a2bc0830b49352d42e3a8707187daa0000000000000000000000006889f4dde0a2bc0830b49352d42e3a8707187daa0000000000000000000000000000000000000000000000000038c123fdd37d4300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce65009e934732446c5d80aec4bb48d1c6f18984000000000000000000000000ce65009e934732446c5d80aec4bb48d1c6f189840000000000000000000000000000000000000000000000000494654067e1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1718,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be31e3a92b3d0c2d9370663c7e1ff749322fa92f000000000000000000000000be31e3a92b3d0c2d9370663c7e1ff749322fa92f00000000000000000000000000000000000000000000000000564fef3460a1d100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1719,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4053c76dc251c22ec6d676835ac0b1c63ff11d9000000000000000000000000c4053c76dc251c22ec6d676835ac0b1c63ff11d900000000000000000000000000000000000000000000000001476c424a747f1900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078d79b027e11b21e13a1887fde77347790b8bca600000000000000000000000078d79b027e11b21e13a1887fde77347790b8bca600000000000000000000000000000000000000000000000000da99c000531a4600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1733,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004717c3df812351699483ce9ff8fc3ad191fa38f20000000000000000000000000000000000000000000000000de0b6b3a7640000,,,1,true +1734,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003054f483ea0746c497c44bf4ab2468f133ee41900000000000000000000000003054f483ea0746c497c44bf4ab2468f133ee4190000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1741,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000955d917e1fabf943bc670f87dfb75ce2fd44aee8000000000000000000000000955d917e1fabf943bc670f87dfb75ce2fd44aee80000000000000000000000000000000000000000000000000050cd3701bf847f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1746,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cab55b0de19c01cdd284535a3fe8d73a657525bb000000000000000000000000cab55b0de19c01cdd284535a3fe8d73a657525bb000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1747,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bd7fbaf67cf30b5b95f646823dd0bc096e646b080000000000000000000000000000000000000000000000006dac8818ccca3a8d,,,1,true +1751,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e699e8334d901986d9ff6bc5ae4b44ae5122f1ee0000000000000000000000000000000000000000000000007b0d1be7bfd9a806,0x6267f54b841217b6675df3ccd2d3f008649b4eae982f1f81cb736b377ade75db,2021-12-10 09:38:20.000 UTC,0,true +1755,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000058f4e544ed6a80af689b3d006659157b6ec4e0e300000000000000000000000000000000000000000000000036eeb4e0c66dc000,,,1,true +1756,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002613052b58e51177fbcb5c6665c460dad5c593310000000000000000000000002613052b58e51177fbcb5c6665c460dad5c5933100000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa4974fabe8b6a9e44cfc718c8e37e89b4115d0092011669cbbab4e8c406b9e9b,2022-03-10 22:21:34.000 UTC,0,true +1764,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007c614c9da4a195f209ef9e63e5c6f5801db86fab0000000000000000000000000000000000000000000000013c1ccb01b62c326c,,,1,true +1765,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e22ded5d8cb6c74bedca991c0f67925a38c5a6d2000000000000000000000000e22ded5d8cb6c74bedca991c0f67925a38c5a6d2000000000000000000000000000000000000000000000015b966eec8ec1f632900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd0ced634b49b8dc2032dae30e7125439ca7b909000000000000000000000000cd0ced634b49b8dc2032dae30e7125439ca7b909000000000000000000000000000000000000000000000000034e9d576016c51100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1772,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000025b1b0849a9653dcf70bf459c30763d5b7930706000000000000000000000000000000000000000000000000c110d83b2bffaa49,,,1,true +1777,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007c614c9da4a195f209ef9e63e5c6f5801db86fab000000000000000000000000000000000000000000000004979851ad093e06ac,,,1,true +1778,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a8e8cd60e86262b7d9cc5d08f3ec2f172f856830000000000000000000000006a8e8cd60e86262b7d9cc5d08f3ec2f172f856830000000000000000000000000000000000000000000000000003585d62261e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f17f232fb241c7cb6d200c0a7b2f77bb4268c280000000000000000000000000f17f232fb241c7cb6d200c0a7b2f77bb4268c280000000000000000000000000000000000000000000000000019cebd0b3d67f4900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1784,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf99bf53caa598d312ee72055e42c8bcf35d24e8000000000000000000000000cf99bf53caa598d312ee72055e42c8bcf35d24e8000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcacaa2951eb0d03b788d355f1226701b7ee475e000000000000000000000000bcacaa2951eb0d03b788d355f1226701b7ee475e000000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1792,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008db02f4db3d165630ab4181994be509e8eaf7f8200000000000000000000000000000000000000000000000ca0a17e135d851158,0xad6f01c8434823d354f10726cda60bcac980f278322d38a8fee6e1f4e009d4da,2021-11-27 19:59:45.000 UTC,0,true +1794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f4ef5c539a56291665fcca4e6b7a6446ad11cc10000000000000000000000005f4ef5c539a56291665fcca4e6b7a6446ad11cc10000000000000000000000000000000000000000000000000069290b0d5a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1799,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db45e0edd323939129792c15278b1204bd29ddd6000000000000000000000000db45e0edd323939129792c15278b1204bd29ddd6000000000000000000000000000000000000000000000000005250aeeb45690000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1807,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee5c256721abe58af6f582c0efd6774dd2765038000000000000000000000000ee5c256721abe58af6f582c0efd6774dd276503800000000000000000000000000000000000000000000000001352e852f89511e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1809,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ec15a5690361c73b9b60369ab1fa06c559496150000000000000000000000006ec15a5690361c73b9b60369ab1fa06c559496150000000000000000000000000000000000000000000000000078bec232ffe2df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a81c50289f16a7e556385d6bab17707e2ea23c50000000000000000000000006a81c50289f16a7e556385d6bab17707e2ea23c5000000000000000000000000000000000000000000000000005f7e5b739ac1cf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ccb23a9bbae99909b1102549f9a96c2b137a60ec000000000000000000000000ccb23a9bbae99909b1102549f9a96c2b137a60ec000000000000000000000000000000000000000000000000001dcf653460938000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d8c9bdfbb887a44bf45692f6d4d0576412f8b577000000000000000000000000d8c9bdfbb887a44bf45692f6d4d0576412f8b5770000000000000000000000000000000000000000000000000373d7d3e85d290000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7394f05f97257958361329a3fd4f879773c0469000000000000000000000000e7394f05f97257958361329a3fd4f879773c04690000000000000000000000000000000000000000000000000050cd433f02912100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1818,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000060da990aebdd785f50ea3202ff05bff1d0963dbe00000000000000000000000000000000000000000000000081cba1d16e377a7d,,,1,true +1819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c03b767ccc25b31a76cc50fa3c84cb859ef30f97000000000000000000000000c03b767ccc25b31a76cc50fa3c84cb859ef30f9700000000000000000000000000000000000000000000000000109a260574dcde00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f16c2bb24b4e844bd9fb9141cc6e812ee50f8330000000000000000000000006f16c2bb24b4e844bd9fb9141cc6e812ee50f833000000000000000000000000000000000000000000000000001c687f50fe852600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a434108cc9fe2a86796b4d4ac6bf61af1ad8eca1000000000000000000000000a434108cc9fe2a86796b4d4ac6bf61af1ad8eca1000000000000000000000000000000000000000000000000060422e3e632615e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1830,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000013a9bcf887142f70c53f52df7ccd9a832a72a77500000000000000000000000000000000000000000000000fe52cea9f3e6a2842,,,1,true +1837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000342dbb1fcb0f693bc991b87cab2edfb4f25b69ee000000000000000000000000342dbb1fcb0f693bc991b87cab2edfb4f25b69ee00000000000000000000000000000000000000000000000001101d6c5e198e4f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082683f46c69e068f244d86103317b37ebbf9377900000000000000000000000082683f46c69e068f244d86103317b37ebbf937790000000000000000000000000000000000000000000000000002dce362efac9c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1841,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000004e6f61590eac8016f21ab170c488f0350a8fa0000000000000000000000000000000000000000000000000f7671cc47aa1f92c,,,1,true +1846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d487c2f6f9dd15db0ce76181e6211a1ef9d8d920000000000000000000000005d487c2f6f9dd15db0ce76181e6211a1ef9d8d92000000000000000000000000000000000000000000000000d3b87598235f2cbf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1847,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000009bbf793fe17c934a933b57a9fb4add10289aa6a000000000000000000000000000000000000000000000000621beb6d38839193,,,1,true +1848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f13dffed9aa20fb22526463bed09c4e59e1b8330000000000000000000000004f13dffed9aa20fb22526463bed09c4e59e1b83300000000000000000000000000000000000000000000000000473a96fb049f6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe580c078056fcbb2086db9237a4ca2169706ec239035d62644ac0d4510eccfa9,2022-07-16 08:25:14.000 UTC,0,true +1850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009bbf793fe17c934a933b57a9fb4add10289aa6a00000000000000000000000009bbf793fe17c934a933b57a9fb4add10289aa6a00000000000000000000000000000000000000000000000000166e0719f5ccc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003637a131c537dfdabab3a5e964f70fa65c3640080000000000000000000000003637a131c537dfdabab3a5e964f70fa65c36400800000000000000000000000000000000000000000000000006e4641adad0a37d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076cdca9ce4ac4804884e1e778e68d256c8b087c100000000000000000000000076cdca9ce4ac4804884e1e778e68d256c8b087c1000000000000000000000000000000000000000000000000045be402e365f2c700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080af0af8c7ab024039f49fb4bb5f440b1297c41300000000000000000000000080af0af8c7ab024039f49fb4bb5f440b1297c41300000000000000000000000000000000000000000000000000ae2c5d4b720b4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc53b08b7c3ef1f64dbd9828724950edd650cc7170ca5d675fb8c0be34f908890,2022-02-27 09:15:08.000 UTC,0,true +1857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000732052b8d446acdb4e43282ec39c1a385c811b02000000000000000000000000732052b8d446acdb4e43282ec39c1a385c811b0200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1859,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2332295cfbcd03531a77b00a019f39335ab8d43000000000000000000000000c2332295cfbcd03531a77b00a019f39335ab8d43000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2a622b764878faf9ab9078ad31303b24fd4b707000000000000000000000000c2a622b764878faf9ab9078ad31303b24fd4b707000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b355df7a527f215f51af23396c69094955840e2c000000000000000000000000b355df7a527f215f51af23396c69094955840e2c000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1862,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000608972868362504b4820fc26aa60787f45159913000000000000000000000000608972868362504b4820fc26aa60787f45159913000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a7db7b42e26dc80a7091f72e2389b6cc9deb60d0000000000000000000000004a7db7b42e26dc80a7091f72e2389b6cc9deb60d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1866,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d0e4c670b1c3f9213ee13c79f16e2852d1582530000000000000000000000009d0e4c670b1c3f9213ee13c79f16e2852d158253000000000000000000000000000000000000000000000000001ed3bb1c4a6c0700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d0e4c670b1c3f9213ee13c79f16e2852d1582530000000000000000000000009d0e4c670b1c3f9213ee13c79f16e2852d15825300000000000000000000000000000000000000000000000000213e63812ae28100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0f080b0ff503f6d59edbf8551df24d02c69deef000000000000000000000000f0f080b0ff503f6d59edbf8551df24d02c69deef000000000000000000000000000000000000000000000000003f2ced8ccf31d800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1873,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002923be587904f3034ffab36c86c495df3c21bc970000000000000000000000000000000000000000000000008138721ac7458fe0,,,1,true +1879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c59b1008d098b19489a76fd90ce1d870d998492c000000000000000000000000c59b1008d098b19489a76fd90ce1d870d998492c0000000000000000000000000000000000000000000000000084b7651040d1f000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000725147c2bfa26fca5984b5ac1f7abf8719dc795d000000000000000000000000725147c2bfa26fca5984b5ac1f7abf8719dc795d00000000000000000000000000000000000000000000000000935168819a2d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5bd9cec8ecaa2de229fff140d4343584a86b370000000000000000000000000d5bd9cec8ecaa2de229fff140d4343584a86b370000000000000000000000000000000000000000000000000004487374723448a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd67285ea7e8efa60e0162e7b6ad6bfb57bd6f44000000000000000000000000bd67285ea7e8efa60e0162e7b6ad6bfb57bd6f44000000000000000000000000000000000000000000000000058adbe9880b120000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1890,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000082683f46c69e068f244d86103317b37ebbf9377900000000000000000000000082683f46c69e068f244d86103317b37ebbf937790000000000000000000000000000000000000000000000000035d1bd4bf9369600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d0172e88bd400884708318bac77bc69f76ae0820000000000000000000000008d0172e88bd400884708318bac77bc69f76ae082000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1895,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f89f1d06505962b95eca6f46387a75e2de1b3b68000000000000000000000000f89f1d06505962b95eca6f46387a75e2de1b3b68000000000000000000000000000000000000000000000000000017750f94750000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064b857f38efe672d8938a1022248e7ce9444525500000000000000000000000064b857f38efe672d8938a1022248e7ce944452550000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1900,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000889cb44823b35fc53dfc3a8b58a825beb6a737b5000000000000000000000000889cb44823b35fc53dfc3a8b58a825beb6a737b5000000000000000000000000000000000000000000000000007e18fb9c0a35ea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcb1e847f54fa1d901d3fc50f565f8cad5816f717c841bbdac07d32ffe0b8429f,2022-03-06 05:36:44.000 UTC,0,true +1901,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c0fdf40988bf0c03b0a600a37ea57b5909ab28f0000000000000000000000005c0fdf40988bf0c03b0a600a37ea57b5909ab28f00000000000000000000000000000000000000000000000001b667a56d48800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1910,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000982bfe6dac3ccdb324984311d5804dbb1cfd4faf000000000000000000000000982bfe6dac3ccdb324984311d5804dbb1cfd4faf000000000000000000000000000000000000000000000000022775fd824e31a700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1911,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001aedc8c5a2f163685d8ea7b93101d57eab683a840000000000000000000000001aedc8c5a2f163685d8ea7b93101d57eab683a8400000000000000000000000000000000000000000000000098a1fbea3abc65f000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1912,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000bd978c0e11680717f5116f8fd62a19ca325b4877000000000000000000000000bd978c0e11680717f5116f8fd62a19ca325b4877000000000000000000000000000000000000000000000002a1075cd4b4a2f73100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1917,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000321f5373fc2b56153a997d88b7fffdc1d413fcdc000000000000000000000000321f5373fc2b56153a997d88b7fffdc1d413fcdc000000000000000000000000000000000000000000000001998427cc5c934ceb00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000321f5373fc2b56153a997d88b7fffdc1d413fcdc000000000000000000000000321f5373fc2b56153a997d88b7fffdc1d413fcdc00000000000000000000000000000000000000000000000000066a534ecab04000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1922,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab303fec8e53841653128610c44ceab5da46c23f000000000000000000000000ab303fec8e53841653128610c44ceab5da46c23f0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1924,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b361234dc46ec6cb034eb692e6330c1ad57fedcd0000000000000000000000000000000000000000000000093739534d28680000,,,1,true +1926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003fa93b2d9b95faf616c4c749e958f87f1463b4fe0000000000000000000000003fa93b2d9b95faf616c4c749e958f87f1463b4fe000000000000000000000000000000000000000000000000001f1e32d9f5e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1933,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e0b56bca567be6daa6dd3e95d484f892a915108900000000000000000000000000000000000000000000000104ae218c7a8b51a6,,,1,true +1936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000043221135be9d8f9da1345e0242155b779c7633f000000000000000000000000043221135be9d8f9da1345e0242155b779c7633f0000000000000000000000000000000000000000000000000020ab9bf287af0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1942,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ab384c78ec3a44dfe0e3bc1cdcdd042534b055d0000000000000000000000007ab384c78ec3a44dfe0e3bc1cdcdd042534b055d000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1945,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f223460832b3afe7161d87584cfefba7608e4f0c000000000000000000000000f223460832b3afe7161d87584cfefba7608e4f0c0000000000000000000000000000000000000000000000000020091f01b4c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1946,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000edb797dfab3c6fd90295e6264ec4d672d73ac7d3000000000000000000000000edb797dfab3c6fd90295e6264ec4d672d73ac7d300000000000000000000000000000000000000000000000000794d5b3f0a146800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x810336c2a1dcd31b32485950e7faf34dd6867e81b83b70e399a46eb4e11e18bd,2022-03-13 10:34:11.000 UTC,0,true +1948,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000304c161c3a71fbe5867022648fbc7d9aa994a02d000000000000000000000000304c161c3a71fbe5867022648fbc7d9aa994a02d000000000000000000000000000000000000000000000005e870b03b127d1cc100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +1953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d38ac318aa5821a99b1fe1e6f0a6b5e8fe2941a7000000000000000000000000d38ac318aa5821a99b1fe1e6f0a6b5e8fe2941a70000000000000000000000000000000000000000000000000062f63cbdb886ae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1954,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a8e0f532656ab6c2cd83bef11f6e6ce1f7c18a9b00000000000000000000000000000000000000000000000a7669bd7132640000,,,1,true +1959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a73a8cb53f91a903b4b6202e85e347000d5433a5000000000000000000000000a73a8cb53f91a903b4b6202e85e347000d5433a5000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1960,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008b82ea55b70e93746bd13d858648772daeaedb1a000000000000000000000000000000000000000000000028885341dd125aeab0,,,1,true +1961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076ab70829b14430f35e600fd0dab42d2c88d570e00000000000000000000000076ab70829b14430f35e600fd0dab42d2c88d570e00000000000000000000000000000000000000000000000000534a3ccb0b680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078ace162a81d2588d6247478a39254b12b5c031600000000000000000000000078ace162a81d2588d6247478a39254b12b5c031600000000000000000000000000000000000000000000000000f2d7012e9b3c4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x501760f15d70a9221ddc582626a214a087d33d42d15fdc1527dab0e9a2892eef,2022-03-06 10:59:59.000 UTC,0,true +1963,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000046d95954dd98b03820c69a7e85e1631a2d3f04250000000000000000000000000000000000000000000000003b2862c2a12ca150,,,1,true +1968,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008afb85e94953c869f6652bc69f0e4c4bab0b9677000000000000000000000000000000000000000000000000aa54da1123ef48b4,,,1,true +1979,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044265dae5c21110b0dfdd421503ce3e1ca3280a500000000000000000000000044265dae5c21110b0dfdd421503ce3e1ca3280a500000000000000000000000000000000000000000000000000168fa0c1f2e6ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1980,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c03d9b3b58c8589172843f3deb7cb74a0d9d9e30000000000000000000000006c03d9b3b58c8589172843f3deb7cb74a0d9d9e300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012235b260b113ebef4a77b27bdc1c8da3e00109d00000000000000000000000012235b260b113ebef4a77b27bdc1c8da3e00109d0000000000000000000000000000000000000000000000000061d2f881fd6a8300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1983,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080f0171d4844436549c1f83b0e5c5ef7ce94371600000000000000000000000080f0171d4844436549c1f83b0e5c5ef7ce9437160000000000000000000000000000000000000000000000000020d74f2b7db0a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1984,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005eb71caeadf22107a578bc5261ec9a1e16fad5f80000000000000000000000005eb71caeadf22107a578bc5261ec9a1e16fad5f8000000000000000000000000000000000000000000000000015bc0230dede8a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe7a9176bbb48a1c6179f6d5c85b642065bdfdcde712658f80eadf9fd7a6e3e7a,2022-04-27 04:02:00.000 UTC,0,true +1985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007450fb048bd81d69c27676b93129f611af948c280000000000000000000000007450fb048bd81d69c27676b93129f611af948c2800000000000000000000000000000000000000000000000000853fcd8ddbdc5e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b053b3105844613bc91cd10443739cb6123c1ab0000000000000000000000000b053b3105844613bc91cd10443739cb6123c1ab000000000000000000000000000000000000000000000000002e0a6e55898f65e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1988,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce21d998c7c79c48124583c3bf85d96dccbf8224000000000000000000000000ce21d998c7c79c48124583c3bf85d96dccbf82240000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c6344ba5ebe67f6118b8129e37f67ca9c0d10de0000000000000000000000006c6344ba5ebe67f6118b8129e37f67ca9c0d10de00000000000000000000000000000000000000000000000004d37662ceaf1dc900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1992,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d8bb86b43ecd8e84aa3542853ca25655f519c0e0000000000000000000000006d8bb86b43ecd8e84aa3542853ca25655f519c0e00000000000000000000000000000000000000000000000000069309dde49dc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d77900479ef30963f4b5aa7d752b15795192ee15000000000000000000000000d77900479ef30963f4b5aa7d752b15795192ee1500000000000000000000000000000000000000000000000002bcc373fa1731d100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1995,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a87469931a348664fdf3125670cc1599c2150d07000000000000000000000000a87469931a348664fdf3125670cc1599c2150d0700000000000000000000000000000000000000000000000000ad0eeae705da0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1996,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dda41e662f2ed6609170431d11c885ab7158e19b000000000000000000000000dda41e662f2ed6609170431d11c885ab7158e19b000000000000000000000000000000000000000000000000001e9ef2ef19330000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043d19b7139089a63f051ab5b8c89cb425a9d861b00000000000000000000000043d19b7139089a63f051ab5b8c89cb425a9d861b000000000000000000000000000000000000000000000000001ef4872226090000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +1998,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000a95d8ae3c78b779d5aff68764a195a6c634be920000000000000000000000000a95d8ae3c78b779d5aff68764a195a6c634be920000000000000000000000000000000000000000000000053b4ef76346c592cc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x1e240da1e12e750274192d7e73d85f6589e51e74cddeb7f1fe2f96edb0d4eb53,2022-06-26 03:12:21.000 UTC,0,true +2003,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000634775efe2d77ff787fa843a57e752b9bd515f41000000000000000000000000634775efe2d77ff787fa843a57e752b9bd515f4100000000000000000000000000000000000000000000000000d6e16de1e9520500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2008,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055ec74b554fd87fb1273236b483a973e2734b0a100000000000000000000000055ec74b554fd87fb1273236b483a973e2734b0a10000000000000000000000000000000000000000000000000018feaa7f62e1f700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2010,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033630b553dfd9a9647c689cbff36a6017400021200000000000000000000000033630b553dfd9a9647c689cbff36a60174000212000000000000000000000000000000000000000000000000001718b815ff2d2100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000882ae064b136eb4f6f0095b07b87257806c80bab000000000000000000000000882ae064b136eb4f6f0095b07b87257806c80bab0000000000000000000000000000000000000000000000000000000002aea54000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2012,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000078902c0f6f7a3520340e38f87b36b2373e5f3f6a00000000000000000000000078902c0f6f7a3520340e38f87b36b2373e5f3f6a0000000000000000000000000000000000000000000000000000000002aea54000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ac495ea31d2002ac8fed73dfe98cffc04b9e82dc000000000000000000000000ac495ea31d2002ac8fed73dfe98cffc04b9e82dc0000000000000000000000000000000000000000000000000000000002aea54000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2014,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d02f64a4a523b6c981d7e1698f524e867c8d640c000000000000000000000000d02f64a4a523b6c981d7e1698f524e867c8d640c0000000000000000000000000000000000000000000000000000000002aea54000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2015,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000006a6d748b878629aabfb83acc10bb24ea5644f9480000000000000000000000006a6d748b878629aabfb83acc10bb24ea5644f9480000000000000000000000000000000000000000000000000000000002aea54000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2016,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000fc073b372d57c56718127fcf712f5d84c1fa07ff000000000000000000000000fc073b372d57c56718127fcf712f5d84c1fa07ff0000000000000000000000000000000000000000000000000000000002bde78000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2017,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000f9c05511c9baf7f1963d4c3c1cce87dff498ae41000000000000000000000000f9c05511c9baf7f1963d4c3c1cce87dff498ae410000000000000000000000000000000000000000000000000000000002bde78000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2018,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ac1866e1bfa099db65c77358e7c6e37833ebd899000000000000000000000000ac1866e1bfa099db65c77358e7c6e37833ebd8990000000000000000000000000000000000000000000000000000000002bde78000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2019,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000f447b6eed0c522a0625e08d48af99f4b2cafc2fd000000000000000000000000f447b6eed0c522a0625e08d48af99f4b2cafc2fd0000000000000000000000000000000000000000000000000000000002bde78000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000fa204a1b8d4d8da5577c1eacac9b7e5f3e896c70000000000000000000000000fa204a1b8d4d8da5577c1eacac9b7e5f3e896c7000000000000000000000000000000000000000000000000000000000014948e000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2024,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000012e322ef04da64246412536f8eb60d6a402a59f9000000000000000000000000000000000000000000000000db44e049bb2c0000,,,1,true +2025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ef58868d460c4d5784406960e1ef8aae1512be55000000000000000000000000ef58868d460c4d5784406960e1ef8aae1512be550000000000000000000000000000000000000000000000000000000005226fa700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c563d8cfcc4f747ddbd7b7f9b243f7ff0f4108aa000000000000000000000000c563d8cfcc4f747ddbd7b7f9b243f7ff0f4108aa00000000000000000000000000000000000000000000000001608039ea25fc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0b56bca567be6daa6dd3e95d484f892a9151089000000000000000000000000e0b56bca567be6daa6dd3e95d484f892a915108900000000000000000000000000000000000000000000000000046a078eec2a8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db851d1c7bd4370089bf04641e628cab2a538586000000000000000000000000db851d1c7bd4370089bf04641e628cab2a538586000000000000000000000000000000000000000000000000009c51c4521e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc4a04c3a9e4f3d6674e3ea292d946a8185abed9000000000000000000000000dc4a04c3a9e4f3d6674e3ea292d946a8185abed90000000000000000000000000000000000000000000000000040b2b33891dace00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e633336f44c164654eb8e0577a2ba420c776bd5e000000000000000000000000e633336f44c164654eb8e0577a2ba420c776bd5e000000000000000000000000000000000000000000000000003868fbd5aa43e100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2036,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028886a8f7bc0a58e04deb35c1531b34dc61acb5e00000000000000000000000028886a8f7bc0a58e04deb35c1531b34dc61acb5e000000000000000000000000000000000000000000000000006848f66a57f24a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2037,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000564a90617500a17eab836fcd9f811118079e19b7000000000000000000000000000000000000000000000000477dbd7cc4514834,,,1,true +2038,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b51c80fb02bb165593b3f82d845894fbadf1b040000000000000000000000001b51c80fb02bb165593b3f82d845894fbadf1b040000000000000000000000000000000000000000000000000250eaa302d9f98100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x780f6544bfbb7da05b60c09f5f3b5c43606d4bbbe291c73e51459e208269413e,2021-12-09 23:27:04.000 UTC,0,true +2039,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d0c3ba7132613925c6a5b5ed341f6b879d5e0f580000000000000000000000000000000000000000000000056cc00ece71570000,,,1,true +2040,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063d612aa37942803ba62e03c2f6fde6b061f6a6f00000000000000000000000063d612aa37942803ba62e03c2f6fde6b061f6a6f00000000000000000000000000000000000000000000000000058c0da2e2fc5800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2045,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1e36163263b89bb2e5d2d694d28e496f1881749000000000000000000000000c1e36163263b89bb2e5d2d694d28e496f18817490000000000000000000000000000000000000000000000000020267c86ac9b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2047,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008318990fba5fd78d7c963924fc4f4eaade5c3df90000000000000000000000008318990fba5fd78d7c963924fc4f4eaade5c3df9000000000000000000000000000000000000000000000000000c05e921153cf700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057460ac29351491c402ad53b3630e93a1941f95100000000000000000000000057460ac29351491c402ad53b3630e93a1941f9510000000000000000000000000000000000000000000000000051feeec6ec274000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2055,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a9d1138480226820ecb43abe6563ec0415fc2af0000000000000000000000006a9d1138480226820ecb43abe6563ec0415fc2af000000000000000000000000000000000000000000000000004db48f9a7e1e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2056,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e4a0e0593df6ffd10d459e06429b93399a3d80a0000000000000000000000003e4a0e0593df6ffd10d459e06429b93399a3d80a000000000000000000000000000000000000000000000000000a40ee2576238000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002daec6744e092a586240e653fc715f9d2cee90270000000000000000000000002daec6744e092a586240e653fc715f9d2cee90270000000000000000000000000000000000000000000000000156a1c1c7197d3f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4eeb4d6b029effa2b79e279f94c08be50437d78000000000000000000000000f4eeb4d6b029effa2b79e279f94c08be50437d7800000000000000000000000000000000000000000000000000011fe26917b57500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2062,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3de20dc08f50b3b5cbd68cb06ab798bcdae08a4000000000000000000000000f3de20dc08f50b3b5cbd68cb06ab798bcdae08a40000000000000000000000000000000000000000000000000010caae5801be4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2063,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e3b906074a29dd2fb1d9ab304bfd927f603b7200000000000000000000000005e3b906074a29dd2fb1d9ab304bfd927f603b720000000000000000000000000000000000000000000000000003fb349a22be82f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2064,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ff36124356df5617dec6e9d40d49b32cc55909d0000000000000000000000004ff36124356df5617dec6e9d40d49b32cc55909d000000000000000000000000000000000000000000000000009ce40a98d8990000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2066,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002daec6744e092a586240e653fc715f9d2cee90270000000000000000000000002daec6744e092a586240e653fc715f9d2cee902700000000000000000000000000000000000000000000000000aa5d21b0199c8d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2068,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001511be1b433b06ab7c01980d45b2939ee500eb940000000000000000000000001511be1b433b06ab7c01980d45b2939ee500eb940000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2069,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5998e60aa4fa846bb7dab5e3522c2c61266bb52000000000000000000000000c5998e60aa4fa846bb7dab5e3522c2c61266bb52000000000000000000000000000000000000000000000000001c4bca86a8d4fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2073,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc4171d7b45b9502ebc1d31c50d9d69a1aa6cd13000000000000000000000000dc4171d7b45b9502ebc1d31c50d9d69a1aa6cd1300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2074,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e4eecdb19d80c61cd1d0f28b17d44df1dfaa1870000000000000000000000004e4eecdb19d80c61cd1d0f28b17d44df1dfaa18700000000000000000000000000000000000000000000000000524597a14884fa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2091,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000494d035d1ad677b3fa5cc537a8cebd0bf2480971000000000000000000000000494d035d1ad677b3fa5cc537a8cebd0bf248097100000000000000000000000000000000000000000000000002c1f9a3cf2f950000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000924ac9910c09a0215b06458653b30471a152022f000000000000000000000000924ac9910c09a0215b06458653b30471a152022f00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000924ac9910c09a0215b06458653b30471a152022f000000000000000000000000924ac9910c09a0215b06458653b30471a152022f00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2096,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a172d783fc38efe8135e6a3aeaab5c4932cf2623000000000000000000000000a172d783fc38efe8135e6a3aeaab5c4932cf26230000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f279d33db640c5ad6a53d0e847f98b65ce845a15000000000000000000000000f279d33db640c5ad6a53d0e847f98b65ce845a15000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2100,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098656b644acaa9faa0d5919d2a2f311582093d1000000000000000000000000098656b644acaa9faa0d5919d2a2f311582093d1000000000000000000000000000000000000000000000000000abac938068210000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2101,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000829f0811319625975292ee7d9d22a3a0b408eed900000000000000000000000000000000000000000000000019485ca897900f89,,,1,true +2103,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000741bc936b183f8bcf807c0204bee62fa68ea561f000000000000000000000000741bc936b183f8bcf807c0204bee62fa68ea561f00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x687b28487c0cab0ca83f0473f24353a60f5871d677fe96dec7e414ee556b3c26,2022-01-02 15:42:12.000 UTC,0,true +2108,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076916bdbd7b84317365fb3bd157e1606550665b900000000000000000000000076916bdbd7b84317365fb3bd157e1606550665b9000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2111,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000298caa03187ba3145bac8749ec258913632e0008000000000000000000000000298caa03187ba3145bac8749ec258913632e000800000000000000000000000000000000000000000000000000122bfa2203f9ed00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2114,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac4bfcd893230a82f9f905f92457378b52a1d706000000000000000000000000ac4bfcd893230a82f9f905f92457378b52a1d7060000000000000000000000000000000000000000000000000160291918f8550000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2116,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009587de586dfa49cf33dd5b30679450f3f6d1fd9a0000000000000000000000009587de586dfa49cf33dd5b30679450f3f6d1fd9a0000000000000000000000000000000000000000000000000054ea9ffaa5944500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2118,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017480555ebf1d3a40341361132c18fbf88fb8aeb00000000000000000000000017480555ebf1d3a40341361132c18fbf88fb8aeb000000000000000000000000000000000000000000000000012305f355f3b77e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2119,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037cc7e32f81f9165f5b09dbaae89c07512e3843300000000000000000000000037cc7e32f81f9165f5b09dbaae89c07512e384330000000000000000000000000000000000000000000000000036ae2cba6a0ccd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000262c5eaaaa8b5632d073d72df6a08ada25cdbb28000000000000000000000000262c5eaaaa8b5632d073d72df6a08ada25cdbb2800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e78f896ce38833a6ae75e7bde08508563802a462000000000000000000000000e78f896ce38833a6ae75e7bde08508563802a46200000000000000000000000000000000000000000000000000336939c9bfc29300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9fbbb3032dfef61a9abf183ab460f4e18ce2dd8000000000000000000000000d9fbbb3032dfef61a9abf183ab460f4e18ce2dd8000000000000000000000000000000000000000000000000003ff2e795f5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000afbe097a650ed9da24994739fe1e8b120d23b550000000000000000000000000afbe097a650ed9da24994739fe1e8b120d23b55000000000000000000000000000000000000000000000000005543df729c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2126,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000980b25f29dcc19f5ea6b723dc0d481774e787570000000000000000000000000980b25f29dcc19f5ea6b723dc0d481774e7875700000000000000000000000000000000000000000000000000021051a7b936f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2128,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000602f49db00e1c594ac1c86970047a7d188334b78000000000000000000000000602f49db00e1c594ac1c86970047a7d188334b7800000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2129,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002387949f5fcfe2c61d32b23fb8be22fbd133f12b0000000000000000000000002387949f5fcfe2c61d32b23fb8be22fbd133f12b00000000000000000000000000000000000000000000000000a985cb89de3f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e34cabba447e536086363094b5cec334ebd8d7b7000000000000000000000000e34cabba447e536086363094b5cec334ebd8d7b700000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000760606741594125796c9da208dd156336e9ff4d2000000000000000000000000760606741594125796c9da208dd156336e9ff4d2000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf3f7fd16849636a132f921438ee593866fd4e24000000000000000000000000cf3f7fd16849636a132f921438ee593866fd4e24000000000000000000000000000000000000000000000000020e4ce871c8c12c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2e8d90533c0b5b91a201738e627aaf353e585df000000000000000000000000e2e8d90533c0b5b91a201738e627aaf353e585df00000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009072063a81bebc2bc246612e8c69891f080bd7f80000000000000000000000009072063a81bebc2bc246612e8c69891f080bd7f800000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2138,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a924c5eff11bcb4d2b00d922e0145510c7459843000000000000000000000000a924c5eff11bcb4d2b00d922e0145510c7459843000000000000000000000000000000000000000000000000001ec8e634ab4dd200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a52715a5cc5efad1be64865195d2ea39c7d98e7f000000000000000000000000a52715a5cc5efad1be64865195d2ea39c7d98e7f000000000000000000000000000000000000000000000000000248f3a02bec8400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2141,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7747b82b79cb793f17fe0faf51b5b77d4c44cf1000000000000000000000000b7747b82b79cb793f17fe0faf51b5b77d4c44cf100000000000000000000000000000000000000000000000000aeb9f91cfd1f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2142,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f3218e0434fbda514552fb8e64c90025a45bd520000000000000000000000002f3218e0434fbda514552fb8e64c90025a45bd520000000000000000000000000000000000000000000000000006db26f299913500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002f3218e0434fbda514552fb8e64c90025a45bd520000000000000000000000002f3218e0434fbda514552fb8e64c90025a45bd520000000000000000000000000000000000000000000000000000000001f9062e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2144,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6bd2eb85c151a3eddd17bb17d0933bb40b06fd3000000000000000000000000d6bd2eb85c151a3eddd17bb17d0933bb40b06fd300000000000000000000000000000000000000000000000001cdda4faccd000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x44f6b55ede28657345deac8f3f158b89e6e9186c9b7073078df3952e5fc5f6ae,2022-05-09 10:28:55.000 UTC,0,true +2151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f85c77731efa8dddc03e6196a838711fa36b81e0000000000000000000000000f85c77731efa8dddc03e6196a838711fa36b81e0000000000000000000000000000000000000000000000000005c5edcbc29000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2162,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a63519e67dae9a551ad34ae679cf0e911a78381a000000000000000000000000a63519e67dae9a551ad34ae679cf0e911a78381a0000000000000000000000000000000000000000000000000589129f32e57c8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2164,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ababf53063ad68050fd4dbe833dfcbe2a5e286becef761352d6698e7dbab9754300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000002fd721500000000000000000000000000000000000000000000000000000000611ef238,,,1,true +2166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000009feb52de6fd4aac6a5b0aa3f35b9c411dc7bf5c50000000000000000000000009feb52de6fd4aac6a5b0aa3f35b9c411dc7bf5c50000000000000000000000000000000000000000000000000000000041da3d6000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2167,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c4fb550fa8f2a6e5178711e56d5b48dedf897e5e000000000000000000000000c4fb550fa8f2a6e5178711e56d5b48dedf897e5e0000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2169,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4803d8c45fc2f82a9c14b7191b29ae896ab3540000000000000000000000000a4803d8c45fc2f82a9c14b7191b29ae896ab354000000000000000000000000000000000000000000000000000a8875554cbc83f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2170,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a4803d8c45fc2f82a9c14b7191b29ae896ab3540000000000000000000000000a4803d8c45fc2f82a9c14b7191b29ae896ab35400000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4803d8c45fc2f82a9c14b7191b29ae896ab3540000000000000000000000000a4803d8c45fc2f82a9c14b7191b29ae896ab354000000000000000000000000000000000000000000000000000587b06aee2736a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2172,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4a54a3c6ef95e8df1365dade09b7061eeca9ef4000000000000000000000000f4a54a3c6ef95e8df1365dade09b7061eeca9ef4000000000000000000000000000000000000000000000000001fcb5822f3e48000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2175,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000046d44471a055f0aa11ff23cb9b120c5612c3902d00000000000000000000000000000000000000000000000376095ccf371c82b6,,,1,true +2181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfdff8796b34ca75a95ebca3a37809b99dda9287000000000000000000000000bfdff8796b34ca75a95ebca3a37809b99dda9287000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2189,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a51d0b0ee843c572f197c63bbb8277a957c04c50000000000000000000000007a51d0b0ee843c572f197c63bbb8277a957c04c5000000000000000000000000000000000000000000000000017ffe2e934ef3ae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b005ed016b926ec8321516ecef995a6f26e1acf0000000000000000000000001b005ed016b926ec8321516ecef995a6f26e1acf000000000000000000000000000000000000000000000000001d0f63876dcf4700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2223,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eda9885b87c565d5570767e9dbd51c87c9c3d55b000000000000000000000000eda9885b87c565d5570767e9dbd51c87c9c3d55b00000000000000000000000000000000000000000000000000a8b5b155656d4100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001c52385216b430ed9a66450faf3a7e6e764b10f00000000000000000000000001c52385216b430ed9a66450faf3a7e6e764b10f000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2247,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000032aa36adfe23c52de8737bdb7c7ebf2db4253e89000000000000000000000000000000000000000000000004c801e112d2aeb229,,,1,true +2248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005523b536390cab22029250ce3e54d6a4b833d8560000000000000000000000005523b536390cab22029250ce3e54d6a4b833d8560000000000000000000000000000000000000000000000000017210de057c27200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f939830659501a06f5cbf54d34f27f4fda7a1d80000000000000000000000002f939830659501a06f5cbf54d34f27f4fda7a1d800000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0009fc3db2db2fe04ba7bd60b141e5fee14a84704713a9f66ae70447f2ca1b95,2021-12-22 17:41:07.000 UTC,0,true +2253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd974c71ae34eb4b1e0fc1c101318525b9588c5e000000000000000000000000fd974c71ae34eb4b1e0fc1c101318525b9588c5e000000000000000000000000000000000000000000000000009893b0d976fa0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2254,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd132f10241105201d1de0c53c5e4a40c53687bc000000000000000000000000bd132f10241105201d1de0c53c5e4a40c53687bc0000000000000000000000000000000000000000000000000160df505bc2780000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2257,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7a46cb435ccc2756758afdd0475419be9648be1000000000000000000000000b7a46cb435ccc2756758afdd0475419be9648be10000000000000000000000000000000000000000000000000006ea7670eec28000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2258,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e17637f59c56d1fbba3c89bd2f59ed09856cb103000000000000000000000000e17637f59c56d1fbba3c89bd2f59ed09856cb1030000000000000000000000000000000000000000000000000142154dfa56894900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2260,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a5e2582c330f89a6bdb96366f93e1985f1097b6ed4de7ed5b70bfe2a3c1b474fd000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000004c6af600000000000000000000000000000000000000000000000000000000611f2c8b,,,1,true +2263,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000aa6411e6f9bf6c7641b1578fb8946142acfa5ce0f2f784f312955adc7a7e69f700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000262ba9e00000000000000000000000000000000000000000000000000000000611fcfb9,,,1,true +2264,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a81144e8a2805832e702f790068d5a026d1aef165cbe8be26e261121d39dba81c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000268b75400000000000000000000000000000000000000000000000000000000611fd453,,,1,true +2266,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000aec42b9bf3364149cb93bd8ddbb83021fce72d25311ef0fe2d9f30dc9d797e05e000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000026543c800000000000000000000000000000000000000000000000000000000611fde1d,,,1,true +2267,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1f9b4f01b04eb991143e719fd11071c1d0858da000000000000000000000000e1f9b4f01b04eb991143e719fd11071c1d0858da000000000000000000000000000000000000000000000000008719b1b195a7f000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078298487706051b52d7e2beb9bea248d71a2973c00000000000000000000000078298487706051b52d7e2beb9bea248d71a2973c0000000000000000000000000000000000000000000000000006e9a94256e60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2269,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a8014f057a49374783a520278262c85d5ac1632ec96da9c8f7665df29ee866f8f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000263925d00000000000000000000000000000000000000000000000000000000611fe76b,,,1,true +2270,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000f7801b408c5e3d352e9d67ee2774ae82800bc2d7000000000000000000000000f7801b408c5e3d352e9d67ee2774ae82800bc2d70000000000000000000000000000000000000000000000000000000041f101bf00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2271,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a35586a5938c614553ca6ca5b9dbec74bfa0faf069624c182d2cfeaf7190c9d4e000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000002de8a700000000000000000000000000000000000000000000000000000000611ff26a,,,1,true +2272,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a4ff42aeeee9e3571108ca7b75914990673291f9ceea74c608cc30a624a1a158b000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000001e8b5000000000000000000000000000000000000000000000000000000000611ff26a,,,1,true +2274,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a874a0917d2cb83658c4b3fd040a33bd7d639666f4869bba21841113ec5810226000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000003d13ef00000000000000000000000000000000000000000000000000000000611ffa9a,,,1,true +2275,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a7b4515fc57cf8f8d8923d3ac33263b75212b72cedc9b775bee020b419ffefce1000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000000001e89f700000000000000000000000000000000000000000000000000000000611ffa9a,,,1,true +2280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007964d88f569d11697493b0f28ffff16187504bc30000000000000000000000007964d88f569d11697493b0f28ffff16187504bc30000000000000000000000000000000000000000000000000060a8464a4a83d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000007b37c58980683179fe841f9b2633ba2fe7bcff4e0000000000000000000000007b37c58980683179fe841f9b2633ba2fe7bcff4e0000000000000000000000000000000000000000000000000000000001e7fdb800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2304,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059f846cfd67af3d403728edc0ebbc978f87fa84f00000000000000000000000059f846cfd67af3d403728edc0ebbc978f87fa84f000000000000000000000000000000000000000000000000016116210fb3440000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d87db52a9d80812f67193cf7ab62a38c930a8542000000000000000000000000d87db52a9d80812f67193cf7ab62a38c930a85420000000000000000000000000000000000000000000000000208c8190b1d5aa800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2320,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac4fbd8ac75bb5ee493c8a9f3d6c94d538f18370000000000000000000000000ac4fbd8ac75bb5ee493c8a9f3d6c94d538f18370000000000000000000000000000000000000000000000000001ee8000d978ec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2321,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012b385a87bb238429ee7ec0ba4554d54a54a6f2c00000000000000000000000012b385a87bb238429ee7ec0ba4554d54a54a6f2c000000000000000000000000000000000000000000000000001eb228ecc3a38000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xaed187d0790d27de4effebe7d4c47f50bad5913d9aab71ebe1b105ecf7974c85,2022-04-28 09:27:57.000 UTC,0,true +2347,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000030048b7d63853bb6439ef75f998a53e803e8929000000000000000000000000000000000000000000000004488a03553e3708d8,0xb412a3a12f61c0d869634e47ba5552f0f393e1eacb0318802a1f49d20556fbfc,2021-12-15 08:47:58.000 UTC,0,true +2364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4a96cde701bec80f26913af8a9ce35610b73470000000000000000000000000d4a96cde701bec80f26913af8a9ce35610b73470000000000000000000000000000000000000000000000000002096a24a68ee0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2366,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003b522b2dd5d57ba9aa6099bf71511640fba4b9fa0000000000000000000000003b522b2dd5d57ba9aa6099bf71511640fba4b9fa00000000000000000000000000000000000000000000001482b5db9d0d29e31900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xb3c832f4ad85b43898ee10552fc91bf1d175cf077c2a5f7ff1bdd4ba644afac6,2022-02-28 07:18:38.000 UTC,0,true +2367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d5ff14a0fbd6868d30db8387f68cf14c660db630000000000000000000000005d5ff14a0fbd6868d30db8387f68cf14c660db63000000000000000000000000000000000000000000000000001032894648458900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7a2c1075e963886f001cbaa3a099fc04de7d170000000000000000000000000c7a2c1075e963886f001cbaa3a099fc04de7d170000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2371,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a19216cead35d27dcb1596d969870b7580cc9840000000000000000000000004a19216cead35d27dcb1596d969870b7580cc9840000000000000000000000000000000000000000000000000152abb7d32a72ac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2376,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e6badf702f28de2d4e3efc92cb659821a9bd8981000000000000000000000000000000000000000000000002d6a97ffb1525d343,,,1,true +2378,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000752d9c212182da8118bffd3574b7c927fb4ff0b5000000000000000000000000000000000000000000000003151cb805af73524f,,,1,true +2379,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d3afcede3d78797e69d48ac7d72cf7b64e64b030000000000000000000000002d3afcede3d78797e69d48ac7d72cf7b64e64b0300000000000000000000000000000000000000000000000000008be4f825530000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2380,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006491c142bb7e892dfe01db2ba567bff2681b62dd0000000000000000000000006491c142bb7e892dfe01db2ba567bff2681b62dd000000000000000000000000000000000000000000000000001f02a391cbaec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000002c84bb38abdf4f92c74704f14df7c61ec70208c30000000000000000000000002c84bb38abdf4f92c74704f14df7c61ec70208c3000000000000000000000000000000000000000000000000000000000003ff1c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000007ffa9e0a5a7e31cf71d9643d4a9a0ae769a03d520000000000000000000000007ffa9e0a5a7e31cf71d9643d4a9a0ae769a03d52000000000000000000000000000000000000000000000000000000000004f5fa00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2385,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e1ba1f108f829f882a469c7c552583a9a93c6660000000000000000000000009e1ba1f108f829f882a469c7c552583a9a93c666000000000000000000000000000000000000000000000000001afabfcaf096a000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057ddccdd5817017493dc12bbfd4899d2dd74d18b00000000000000000000000057ddccdd5817017493dc12bbfd4899d2dd74d18b000000000000000000000000000000000000000000000000000b4378c885e2b200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000f7a03f661f5d411e8abc410d3c446c0fbd141225000000000000000000000000f7a03f661f5d411e8abc410d3c446c0fbd1412250000000000000000000000000000000000000000000000000000000000117ddd00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000da4c9aeaad95dfbcf5e4948a00b7bd92da61c582000000000000000000000000da4c9aeaad95dfbcf5e4948a00b7bd92da61c5820000000000000000000000000000000000000000000000000000000000117da000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2389,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e014aa0649102e07c074f498845f01bcd5203170000000000000000000000005e014aa0649102e07c074f498845f01bcd52031700000000000000000000000000000000000000000000000001058f45980fbda600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd1953899c214fa0e7f3ac86438e2aaf96c2225463e55554d0f8b180ac8702d7f,2022-03-23 15:43:41.000 UTC,0,true +2390,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000153fc0056d2adad8f10f64ab9744acfca5b40c10000000000000000000000000153fc0056d2adad8f10f64ab9744acfca5b40c10000000000000000000000000000000000000000000000000000000000018f24a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2391,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003478b441e07c418bba592e9ca395a056ddbb45010000000000000000000000000000000000000000000000001a53a97e43dc5a63,,,1,true +2392,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000028aa0f4a1877bf8d0a8200655849496455619de000000000000000000000000028aa0f4a1877bf8d0a8200655849496455619de0000000000000000000000000000000000000000000000005f68e8131ecf8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xb4f728821d27575322c4e4ce44203ea942e2b6b236b27d17a550cd8345c63139,2022-03-13 08:28:34.000 UTC,0,true +2394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4d207588ea3593ee5376b22eb61ee2895d8773d000000000000000000000000b4d207588ea3593ee5376b22eb61ee2895d8773d000000000000000000000000000000000000000000000000000024dd1617544000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000007ffa9e0a5a7e31cf71d9643d4a9a0ae769a03d520000000000000000000000007ffa9e0a5a7e31cf71d9643d4a9a0ae769a03d52000000000000000000000000000000000000000000000000000000000011741600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9bd90265b963e6e79fb4e05e1373bd5952975a1000000000000000000000000b9bd90265b963e6e79fb4e05e1373bd5952975a1000000000000000000000000000000000000000000000000001ae124d10f734000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2397,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002c84bb38abdf4f92c74704f14df7c61ec70208c30000000000000000000000002c84bb38abdf4f92c74704f14df7c61ec70208c300000000000000000000000000000000000000000000000004804b94e5d51e5d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2398,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002d3afcede3d78797e69d48ac7d72cf7b64e64b030000000000000000000000002d3afcede3d78797e69d48ac7d72cf7b64e64b030000000000000000000000000000000000000000000000000e649af5f189030300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cdd5d7618713a7a40b2bb46d128c38872aa0a730000000000000000000000005cdd5d7618713a7a40b2bb46d128c38872aa0a730000000000000000000000000000000000000000000000000013eb1b23eecf4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb31d7ac09dab51c9484e71b887da76f72de47ec000000000000000000000000eb31d7ac09dab51c9484e71b887da76f72de47ec00000000000000000000000000000000000000000000000000111c16d8669d2400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001596ebcd5cfac8e21ebc6d28ad5b86b355ee53fc0000000000000000000000001596ebcd5cfac8e21ebc6d28ad5b86b355ee53fc000000000000000000000000000000000000000000000000000ef1ec4b18b1aa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2402,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000656f62ef0c8b808ce950af91ba310ee1982c150e000000000000000000000000656f62ef0c8b808ce950af91ba310ee1982c150e000000000000000000000000000000000000000000000000005d176d8d6319b300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x82f79f1e918d83d7ce006d71669932dab4da57cd055680f142e0b3b6d5b4120b,2022-08-23 19:00:39.000 UTC,0,true +2403,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008e17561ffc5177f35671863c1505b8e9ab307383000000000000000000000000000000000000000000000007cb62fd00a16f5867,0xec64e1a8b03a1ea0521a8c766065bf0268c80b62421799ecb6e07e204e617fc2,2021-11-27 19:16:16.000 UTC,0,true +2404,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000829f0811319625975292ee7d9d22a3a0b408eed900000000000000000000000000000000000000000000000066e97479d5f38001,,,1,true +2406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014ad7074ffce47d8ba842ee6b3af8d44c618211900000000000000000000000014ad7074ffce47d8ba842ee6b3af8d44c618211900000000000000000000000000000000000000000000000000749c1193eddde700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d110a0298fbdb68b9f3b937b3a04cc65b65559b2000000000000000000000000d110a0298fbdb68b9f3b937b3a04cc65b65559b2000000000000000000000000000000000000000000000000006d75356a39401900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bfd83c76641bea157d670e8e0d42a46ac1442980000000000000000000000005bfd83c76641bea157d670e8e0d42a46ac1442980000000000000000000000000000000000000000000000000b939b7f06a5386900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058551816ab840af2310ec3ec157b03829fb1078200000000000000000000000058551816ab840af2310ec3ec157b03829fb1078200000000000000000000000000000000000000000000000001250893774bc81c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9035e9c4cdd6d3b3a3983f7ae739853f7840997000000000000000000000000a9035e9c4cdd6d3b3a3983f7ae739853f784099700000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2413,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000052eebd82826a7b530839424ceab6ca3643eb0ef100000000000000000000000000000000000000000000006282064c36a13dcd09,0xf7efeb4ff5c1b56a7a5b5009231c3de3bba516d89e5b6ba93357b31649fcda57,2022-04-26 17:24:38.000 UTC,0,true +2414,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003e03819123cc6e06de9692c2bd71da5afd777777000000000000000000000000000000000000000000000000016345785d8a0000,,,1,true +2415,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000041f0bdbed2122402d6d61815d558bc7b01000000000000000000000000000000000000000000000000000000013fbe85edc90000,,,1,true +2416,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bd922eae7bffc9bf320ca224784af09422199999000000000000000000000000000000000000000000000000013fbe85edc90000,,,1,true +2417,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b9428f4e0c0c104f89dfd1fd3f4ca89549666666000000000000000000000000000000000000000000000000013fbe85edc90000,,,1,true +2418,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a89102b5e397f753c4fca0b0bcb593b290838888000000000000000000000000000000000000000000000000013fbe85edc90000,,,1,true +2419,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000020a1fef56e50d891475d964ef0f1bb604c355555000000000000000000000000000000000000000000000000013fbe85edc90000,,,1,true +2420,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e28777719299c96fb583a73e77989cd54e044444000000000000000000000000000000000000000000000000013fbe85edc90000,,,1,true +2421,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006df8ee83068463e578ef77ce2dd8673a01f3333300000000000000000000000000000000000000000000000001476414e1ef6090,,,1,true +2422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092f15cbce433fdca0a87fd778e5bbbd0b3d7ee0f00000000000000000000000092f15cbce433fdca0a87fd778e5bbbd0b3d7ee0f0000000000000000000000000000000000000000000000000060517bcadd10bd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2423,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c507d79e987d57e8dc72bc92a5c4a38a93cd222200000000000000000000000000000000000000000000000001490f0d55acec32,,,1,true +2424,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000dc035f2ba5d9aae02c873aa76714a98e6de1111000000000000000000000000000000000000000000000000014c9c2471a5d84c,,,1,true +2426,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000092d044230b5d92222fb8ac72913ac3bafee484e5000000000000000000000000000000000000000000000000917f38c76ea7b4ba,0x7f738e959458da4f239c17ffbaf6b79f885fb7ae3be951d00d4039a01d00c110,2022-01-28 18:04:10.000 UTC,0,true +2428,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000009a0ee0e21f9521e22f4b99c90c2066a38000e49e0000000000000000000000009a0ee0e21f9521e22f4b99c90c2066a38000e49e00000000000000000000000000000000000000000000000137f003f332c7abe800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004220418bc912c76f62ca70ec74c176424d0a9f190000000000000000000000004220418bc912c76f62ca70ec74c176424d0a9f190000000000000000000000000000000000000000000000000057fb0f1f80ca9a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001cf0912a7087c6b2e496414fec70832902b14f4f0000000000000000000000001cf0912a7087c6b2e496414fec70832902b14f4f00000000000000000000000000000000000000000000000000ad4bdaaeaa978200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2437,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001d5340448b8eb32b1fef1e263755c1ca8bf6a05a0000000000000000000000001d5340448b8eb32b1fef1e263755c1ca8bf6a05a000000000000000000000000000000000000000000000002b5e3af16b188000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2438,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1b86b6df3b7129fb346c7c2c4b4d179ba17c882000000000000000000000000d1b86b6df3b7129fb346c7c2c4b4d179ba17c8820000000000000000000000000000000000000000000000000122969ceb81410800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8d9d5b121c9aeb8e630e43068728f17238ac5ca2e9a63a5de5ea7fdccfa93410,2021-12-18 21:13:40.000 UTC,0,true +2440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000260980ff2c01392b8c4f7f04abc2f50c17c9b21f000000000000000000000000260980ff2c01392b8c4f7f04abc2f50c17c9b21f00000000000000000000000000000000000000000000000000e6edc1fbbc812600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2441,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000293f2986b027575fd7fc337465920185a5b9317e000000000000000000000000000000000000000000000000f9c8f7ba1c978724,,,1,true +2442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee5894bb440342457eea42e46d6af75bedb14805000000000000000000000000ee5894bb440342457eea42e46d6af75bedb14805000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fd8563c594cb7480919a5470ebc21efbacdec9b0000000000000000000000001fd8563c594cb7480919a5470ebc21efbacdec9b000000000000000000000000000000000000000000000000000910f54e8f281800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054a0644e689df22accd7357c8e249272e79f5fee00000000000000000000000054a0644e689df22accd7357c8e249272e79f5fee00000000000000000000000000000000000000000000000000acf17d214dd73500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2450,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc14f891346f298e0187720cc744572d3db11ea2000000000000000000000000dc14f891346f298e0187720cc744572d3db11ea20000000000000000000000000000000000000000000000000061aef49888557600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2452,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000009f45fa7845889a3076788e4849b0f5173cc6a76f0000000000000000000000009f45fa7845889a3076788e4849b0f5173cc6a76f00000000000000000000000000000000000000000000000813e1c28d64fd0e8a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xcb403f82501dbce7044e13bfb817fa1b0514499c7edc5c4e01e2e6087032752e,2022-08-04 09:16:07.000 UTC,0,true +2454,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049f47d08ccff91010bfe5978b011c21472b4aee900000000000000000000000049f47d08ccff91010bfe5978b011c21472b4aee90000000000000000000000000000000000000000000000000070bd6228d2908a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2456,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f250345fda1d5e93b4781791556afaf8d696bad70000000000000000000000000000000000000000000000098a1d15c9dc4b24f6,,,1,true +2457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc6b0e0c50837f8a5785a3d03d4323d4cf7d1118000000000000000000000000fc6b0e0c50837f8a5785a3d03d4323d4cf7d111800000000000000000000000000000000000000000000000000052c4d4d7265c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fdd4186383fafd6bd41d0c59ed84708dfde004ff000000000000000000000000fdd4186383fafd6bd41d0c59ed84708dfde004ff000000000000000000000000000000000000000000000000001b67f2f770897c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a64b2820a06a67ee878157a7f48611463d6bd780000000000000000000000004a64b2820a06a67ee878157a7f48611463d6bd7800000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066eeb3fb677bb8945c2750451720b78de421629400000000000000000000000066eeb3fb677bb8945c2750451720b78de42162940000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2468,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e019d4451a14ea686fb24e49b65b75ef4b05d68c000000000000000000000000000000000000000000000016f511cd75944d8bdc,,,1,true +2475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001aedc8c5a2f163685d8ea7b93101d57eab683a840000000000000000000000001aedc8c5a2f163685d8ea7b93101d57eab683a8400000000000000000000000000000000000000000000000000001433a2c977c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2476,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000092a686623d801fb043d19dddc0e034dad0958f8c00000000000000000000000092a686623d801fb043d19dddc0e034dad0958f8c00000000000000000000000000000000000000000000010ce9b9d89bf75e8cd500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2479,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006ceb397b68059ca73049874d0a30c62500ae9877000000000000000000000000000000000000000000000000551cd529f91d12d2,,,1,true +2480,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3d4a6b3bfe187d7e328514f46db9928c569da21000000000000000000000000c3d4a6b3bfe187d7e328514f46db9928c569da2100000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091130ce2218265fe0bb02e25b11d652ee664c6f400000000000000000000000091130ce2218265fe0bb02e25b11d652ee664c6f4000000000000000000000000000000000000000000000000015181ff25a9800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xeda0fd3a7d3e2c7f71848a254f6d0c0d3f92055fb997b9c7a98f1bf500c24e69,2022-03-21 15:39:20.000 UTC,0,true +2483,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001dd3f55682eab3ddbf2d48dfb23a7b6bd80e05150000000000000000000000001dd3f55682eab3ddbf2d48dfb23a7b6bd80e0515000000000000000000000000000000000000000000000000008d8990b0236b1300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000397cb2188ed99663640773f68e6198e65bb6184a000000000000000000000000397cb2188ed99663640773f68e6198e65bb6184a000000000000000000000000000000000000000000000000007baddcd1efdb5c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2493,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e54317d37c4f4231334070e74033fdc37f79e797000000000000000000000000e54317d37c4f4231334070e74033fdc37f79e79700000000000000000000000000000000000000000000000001bce4508f16dd3900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d031dd22e80c2fd76c6563eb99d21d8e27338d80000000000000000000000001d031dd22e80c2fd76c6563eb99d21d8e27338d80000000000000000000000000000000000000000000000000050636955b7c44b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f56b7647799e2c4d2fcf93a62b1b578723718814000000000000000000000000f56b7647799e2c4d2fcf93a62b1b5787237188140000000000000000000000000000000000000000000000000051bae348a043ce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028e6aad8fe8a99deb68b78fa400136bb378c952d00000000000000000000000028e6aad8fe8a99deb68b78fa400136bb378c952d00000000000000000000000000000000000000000000000000665a84908f9a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000304ff03f1526300d5597dfede9a6be316f56569e000000000000000000000000304ff03f1526300d5597dfede9a6be316f56569e000000000000000000000000000000000000000000000000003ff2e795f5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b37c58980683179fe841f9b2633ba2fe7bcff4e0000000000000000000000007b37c58980683179fe841f9b2633ba2fe7bcff4e000000000000000000000000000000000000000000000000000d128f5cfdd1c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fc6d0da9f4078ed1c1badd8dda5fbed257f11df0000000000000000000000007fc6d0da9f4078ed1c1badd8dda5fbed257f11df0000000000000000000000000000000000000000000000000020463c20fa560000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2512,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b521bafffbfd6d865f1e859fbd704a2c040ec5b0000000000000000000000002b521bafffbfd6d865f1e859fbd704a2c040ec5b000000000000000000000000000000000000000000000000001ce3ffc8bea00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2515,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000fb1b20b2b004b3d2022deb478389f40dd1db435c000000000000000000000000fb1b20b2b004b3d2022deb478389f40dd1db435c0000000000000000000000000000000000000000000000072f7c54bcc6334adc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ea24f3cdddf5b88f90b73a2d7df7ad9c0f9bec40000000000000000000000006ea24f3cdddf5b88f90b73a2d7df7ad9c0f9bec400000000000000000000000000000000000000000000000000720a2bc9e3410000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2521,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000683b067b7359ebcb3661336f1d72cd9d5798f524000000000000000000000000683b067b7359ebcb3661336f1d72cd9d5798f524000000000000000000000000000000000000000000000000009fa8d5b647958400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000212a80a5cb63e38511c73bc6f33e454e911ee88d000000000000000000000000212a80a5cb63e38511c73bc6f33e454e911ee88d00000000000000000000000000000000000000000000000000d0cc1001476bff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2530,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069eef3e0f28881385d8d376c5686d10b84e2f21f00000000000000000000000069eef3e0f28881385d8d376c5686d10b84e2f21f00000000000000000000000000000000000000000000000001eda8842809884f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007daedc837b9795e9235fba7204328d81b1de04200000000000000000000000007daedc837b9795e9235fba7204328d81b1de042000000000000000000000000000000000000000000000000000305f1101d60f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037398f95a1ac3ad92c99fc39a7da0b6430d60a5500000000000000000000000037398f95a1ac3ad92c99fc39a7da0b6430d60a5500000000000000000000000000000000000000000000000000fc634dd19c5b7800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc6b154fc804c3b2d38ded27c6ec4991da2ecb14000000000000000000000000cc6b154fc804c3b2d38ded27c6ec4991da2ecb14000000000000000000000000000000000000000000000000001e16049a62fa1a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f867bc59670b6e263c29058caa87709f4aec3dc0000000000000000000000007f867bc59670b6e263c29058caa87709f4aec3dc0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2557,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008db4b9289bcf79e3df14e2ba56f1ae0958f5a52f0000000000000000000000008db4b9289bcf79e3df14e2ba56f1ae0958f5a52f0000000000000000000000000000000000000000000000a79241b61e75ccf0b200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x9e1de8ac418c884ce295dcfb204cf1f67b40eff398fb966ea72a4786afd5b8cb,2021-11-25 14:13:15.000 UTC,0,true +2560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a986b2d01020d4b066a7abebf6163a2b7f350040000000000000000000000001a986b2d01020d4b066a7abebf6163a2b7f350040000000000000000000000000000000000000000000000000005609186d2320000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8c3a3f1eb0a4f845ae1f2115d18db37ab55f51f000000000000000000000000e8c3a3f1eb0a4f845ae1f2115d18db37ab55f51f00000000000000000000000000000000000000000000000000ecaad21edfd39700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2591,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f05181360129ff94ea193298c939a444e87ffbbd000000000000000000000000f05181360129ff94ea193298c939a444e87ffbbd0000000000000000000000000000000000000000000000000061ca19ef459ffe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a670ebdaaa258311a7c33a5bf795f07b97c83430000000000000000000000000a670ebdaaa258311a7c33a5bf795f07b97c834300000000000000000000000000000000000000000000000000008f06e723797c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2600,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003b8d47f77c537842cfe003ffd751cbb8cf8f9f540000000000000000000000003b8d47f77c537842cfe003ffd751cbb8cf8f9f5400000000000000000000000000000000000000000000000361febd299e69eeec00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2606,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f83a8074a017acb923b46464504bdda79c0bd37c000000000000000000000000f83a8074a017acb923b46464504bdda79c0bd37c000000000000000000000000000000000000000000000000009413b666d0c5a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2608,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004f24a6e61b7745b86e45f42c2bf19fe049d1ccdf000000000000000000000000000000000000000000000004bf6658ea430e64a6,0x861e35be6eeffc86a70db162e24a895582c5bd39966df80945321f9861947b38,2021-12-19 05:39:03.000 UTC,0,true +2610,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6b2818aa57e7d4040c6f1b1307c0d904866a330000000000000000000000000b6b2818aa57e7d4040c6f1b1307c0d904866a3300000000000000000000000000000000000000000000000000050bbd77a62da3700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x67cd886e14856a1ed42cdf19b5b635ff4b88c5e6b10b9584626f59df1a43a79a,2022-05-19 05:33:22.000 UTC,0,true +2611,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074077879cb2b9c1ec9a5785a7e0ff9afe50583a800000000000000000000000074077879cb2b9c1ec9a5785a7e0ff9afe50583a800000000000000000000000000000000000000000000000001357d433c53d30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2613,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000062443ff3f8733e31945f6b670f4599f9f00416bc0000000000000000000000000000000000000000000000083d6c7aab63600000,,,1,true +2614,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048b4e85accfb3177a26c6c39f739d867c07485f200000000000000000000000048b4e85accfb3177a26c6c39f739d867c07485f20000000000000000000000000000000000000000000000001cc82a3f025ce2fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2ff323e92f2f0a2801eb8b3c6699b7895b6fd7a52b82ac6949f86c483c2fe4d1,2021-12-10 15:43:21.000 UTC,0,true +2615,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000820edf94cb50e09b0b9d4b945f0bdecd11c321d2000000000000000000000000820edf94cb50e09b0b9d4b945f0bdecd11c321d2000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcc27cbd3f25c680cd51f82c48f01dd31e0a245272da05e48db4f8566b2559f22,2022-05-08 00:05:29.000 UTC,0,true +2616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059f44829ae4f03a6d673399c99bfcb6eb3716d3200000000000000000000000059f44829ae4f03a6d673399c99bfcb6eb3716d32000000000000000000000000000000000000000000000000023212133018d10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017b324d8fdafb249cc218c781adf19752e8749d500000000000000000000000017b324d8fdafb249cc218c781adf19752e8749d5000000000000000000000000000000000000000000000000005b37259ff797d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2624,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000becebaf3ba4b6ed68d82b955cc5faa960f189f80000000000000000000000000becebaf3ba4b6ed68d82b955cc5faa960f189f800000000000000000000000000000000000000000000000002c16019ec11060000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063fdb65cca5a9e66b7f8d925758cb935281b0ad200000000000000000000000063fdb65cca5a9e66b7f8d925758cb935281b0ad200000000000000000000000000000000000000000000000002d057154a75863c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2626,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000a908362a06b3dbf4496f7d4a298060aaf4307a5000000000000000000000000000000000000000000000000600d20f1c6764b4f,,,1,true +2627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078a7b3846f6b0407c051aef02e365a76cef586e000000000000000000000000078a7b3846f6b0407c051aef02e365a76cef586e00000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2633,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000dbf6045e565f0a2ad62bca011b9878c1a4d111b600000000000000000000000000000000000000000000000005a4473c7470b159,,,1,true +2635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea24f605ff7a7faff0ec68859e9d28b21228aea7000000000000000000000000ea24f605ff7a7faff0ec68859e9d28b21228aea700000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2644,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b604b9311ee4a7e30a47388f9c63ef53e97ab53d00000000000000000000000000000000000000000000000235e0d26160b8d13b,,,1,true +2649,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ecd1753bde9a17707f86dc4c0219360ece76ee8b000000000000000000000000ecd1753bde9a17707f86dc4c0219360ece76ee8b000000000000000000000000000000000000000000000000005c5304d5a957c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2650,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa204a1b8d4d8da5577c1eacac9b7e5f3e896c70000000000000000000000000fa204a1b8d4d8da5577c1eacac9b7e5f3e896c700000000000000000000000000000000000000000000000000032673d6532561800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035aa23fdb2454f7bef15f144011093a5a96ac7c900000000000000000000000035aa23fdb2454f7bef15f144011093a5a96ac7c900000000000000000000000000000000000000000000000000a5a68589526d8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f65330d04f5000823d0bc6a4f7048457b4ecd1dd000000000000000000000000f65330d04f5000823d0bc6a4f7048457b4ecd1dd000000000000000000000000000000000000000000000000001881eec4489ca700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022e86ab483084053562ce713e94431c29d1adb8b00000000000000000000000022e86ab483084053562ce713e94431c29d1adb8b000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002380cf674acefbc515891f1e47339f4179dcd1630000000000000000000000002380cf674acefbc515891f1e47339f4179dcd163000000000000000000000000000000000000000000000000001dabea82eee40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2662,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003477823dc687e24147494b910b367cc85298df8c0000000000000000000000003477823dc687e24147494b910b367cc85298df8c000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2666,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ad453a7eded500955784cc1be9b44ef8fbd7aa16000000000000000000000000000000000000000000000000a1dfcd400d8107f1,,,1,true +2668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074cf8b3d122a3cec3c18bbdcd9325aeac42e147000000000000000000000000074cf8b3d122a3cec3c18bbdcd9325aeac42e14700000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c80703c13de15b73b2e367d8aabb1b0db3922dfa000000000000000000000000c80703c13de15b73b2e367d8aabb1b0db3922dfa0000000000000000000000000000000000000000000000000024fb5259efd5f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2675,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d42ccaa658d460b5dfbcee6bbbeaf1b6667a30f10000000000000000000000000000000000000000000000001becba76eb8e61ce,,,1,true +2680,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006c0cf880cb20eefabfb09341fba9e2bd29ad3dfa0000000000000000000000000000000000000000000001f6e605938955c72459,,,1,true +2682,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b01d0063978e8a6f96dbba91d681fc0c571040e9000000000000000000000000b01d0063978e8a6f96dbba91d681fc0c571040e9000000000000000000000000000000000000000000000000039bb49f599a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000201bb4f276c765df7225e5a4153e17edd23a67ec000000000000000000000000201bb4f276c765df7225e5a4153e17edd23a67ec0000000000000000000000000000000000000000000000000008e1bc9bf0400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2689,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000fa13b582b9d25da1949af33946803b265cb3f4fe0000000000000000000000000000000000000000000000048987425fb87d8118,,,1,true +2690,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000042fb05e09f8a477620defe49af76e577cbd791d80000000000000000000000000000000000000000000000017ea782127c5c28f9,,,1,true +2691,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002923be587904f3034ffab36c86c495df3c21bc97000000000000000000000000000000000000000000000000513b21cedaeea1be,,,1,true +2694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c90f88be812349fdd5655c9bad8288c03e7fb230000000000000000000000002c90f88be812349fdd5655c9bad8288c03e7fb23000000000000000000000000000000000000000000000000015b6a4d48065c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2695,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001060a694e21a2a8da7498a187a71969fafa454e40000000000000000000000001060a694e21a2a8da7498a187a71969fafa454e40000000000000000000000000000000000000000000000000054b271c7c30a3a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2696,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d86cb47446eb8ca8147718ef1b48bffc9166c79f000000000000000000000000d86cb47446eb8ca8147718ef1b48bffc9166c79f000000000000000000000000000000000000000000000000007df57f97201ec300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cfe9755269786f6681518c00bd22801f98f9e570000000000000000000000006cfe9755269786f6681518c00bd22801f98f9e5700000000000000000000000000000000000000000000000005866c73ad83c34000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2703,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ef1d4af28130d95e3144f92a47ed6230f3e06ce0000000000000000000000009ef1d4af28130d95e3144f92a47ed6230f3e06ce00000000000000000000000000000000000000000000000000dba9fea1ee8e8400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c90a1f7d2f7a2643e42a1d177505143190b061e0000000000000000000000002c90a1f7d2f7a2643e42a1d177505143190b061e0000000000000000000000000000000000000000000000000055b7cdd04aa64c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf1504ae86758b2f13423a094619ea709f7380c570d6ef87409de8c4658253feb,2022-03-15 06:30:48.000 UTC,0,true +2705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bad9a464a983fb5e0cb20c5e2b897f168749a870000000000000000000000006bad9a464a983fb5e0cb20c5e2b897f168749a870000000000000000000000000000000000000000000000000061ac0c7d99680f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cdbd5046d1ed8ea807ae9f358eb1c1d4fe0dea21000000000000000000000000cdbd5046d1ed8ea807ae9f358eb1c1d4fe0dea2100000000000000000000000000000000000000000000000000a7353341cdfb3f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2710,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000de16bf2560329013156a976064e7e67c1ef58f06000000000000000000000000de16bf2560329013156a976064e7e67c1ef58f06000000000000000000000000000000000000000000000005b58e73b33f8053e400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2711,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000848e40641cb32d03324b8db26f29ecc6dc996209000000000000000000000000848e40641cb32d03324b8db26f29ecc6dc99620900000000000000000000000000000000000000000000000000000000069f713400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f776290d2e599ae0f90e04245d4b7590ac228b35000000000000000000000000f776290d2e599ae0f90e04245d4b7590ac228b3500000000000000000000000000000000000000000000000001aad60affb2629a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb995009bafd7ce77c1fa13b469c6a7cb3d54c23af5b8cf7d1b4e60d21cf1c294,2022-05-24 09:49:49.000 UTC,0,true +2715,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007988e3ae0d19eff3c8bc567ca0438f6df3cb28130000000000000000000000007988e3ae0d19eff3c8bc567ca0438f6df3cb2813000000000000000000000000000000000000000000000000004cfa9da2e1b05b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a030fe052d5269a45e63421e7122226a28941680000000000000000000000002a030fe052d5269a45e63421e7122226a28941680000000000000000000000000000000000000000000000000036721a1286392800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2721,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007cbff01d1f33dc1933292c0b0e00ec7aaeffa2b300000000000000000000000000000000000000000000000a29daa7e2da799cdc,,,1,true +2723,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003b1e3d1ed70d2a17c8eaf7da1a6be9f805a130e20000000000000000000000003b1e3d1ed70d2a17c8eaf7da1a6be9f805a130e2000000000000000000000000000000000000000000000005f47119d59905211b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2724,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008750e44dd494c88799d0fb0c6200d289c91d35ff0000000000000000000000008750e44dd494c88799d0fb0c6200d289c91d35ff000000000000000000000000000000000000000000000005bb5f25c22079947800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096b3a83fe21c7382e6c5b565744af198dc4bba0300000000000000000000000096b3a83fe21c7382e6c5b565744af198dc4bba03000000000000000000000000000000000000000000000000020fd22ff89d93ff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2730,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e1703625848a41f9259e928c8d7ecc67b6885700000000000000000000000005e1703625848a41f9259e928c8d7ecc67b688570000000000000000000000000000000000000000000000000020bcef7d40f9da700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2732,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e5214a481f2c2bbd501c14dfa66254a8a907cf39000000000000000000000000e5214a481f2c2bbd501c14dfa66254a8a907cf3900000000000000000000000000000000000000000000000057d9ec70c115b49000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000927521baeba66f707a77b91910a84ff5ccf3447a000000000000000000000000927521baeba66f707a77b91910a84ff5ccf3447a000000000000000000000000000000000000000000000000015e7ad661da0e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2741,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013869f635f307b12919502a779cec0a8a9bcd27900000000000000000000000013869f635f307b12919502a779cec0a8a9bcd279000000000000000000000000000000000000000000000000015eb9c35a36510000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000d6c2ca9250bb228d7cf676127213f89ed6a147b0000000000000000000000000d6c2ca9250bb228d7cf676127213f89ed6a147b0000000000000000000000000000000000000000000000000000000000c6c2ddd00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa8d4e2fce610e40ffe0708de338f3101faf19dc5e879469d93fbfcda0a867420,2022-05-29 06:35:11.000 UTC,0,true +2743,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ccf5ef7c438b95aea40b320ac03e4c9fceba2c70000000000000000000000005ccf5ef7c438b95aea40b320ac03e4c9fceba2c7000000000000000000000000000000000000000000000000004b74318a8d3f0800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6c2ca9250bb228d7cf676127213f89ed6a147b0000000000000000000000000d6c2ca9250bb228d7cf676127213f89ed6a147b0000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x64e20e946fcee8ca97f19b992bbaaa6361b75c284e059c72dd0102dcfc9938fc,2022-05-29 06:27:34.000 UTC,0,true +2746,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000349ea0b723e3692a2ddcc0ae5cc85640f372ffd1000000000000000000000000349ea0b723e3692a2ddcc0ae5cc85640f372ffd100000000000000000000000000000000000000000000000000000000036c08a500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000485464e51fba9955221a6263edde963dfd302a8b000000000000000000000000485464e51fba9955221a6263edde963dfd302a8b000000000000000000000000000000000000000000000000006b18bc01fe85ac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1c0501bd0d44164955a4ce50a6a753671f4450d000000000000000000000000c1c0501bd0d44164955a4ce50a6a753671f4450d000000000000000000000000000000000000000000000000006e000d68236d9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2753,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022e9a33fb0cc6c1c8c4369b0cd7d042a8845829700000000000000000000000022e9a33fb0cc6c1c8c4369b0cd7d042a884582970000000000000000000000000000000000000000000000000159866b3ad77e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2759,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c5f132b6e83edce850920328818b09e9163fa720000000000000000000000007c5f132b6e83edce850920328818b09e9163fa720000000000000000000000000000000000000000000000000014c80a80b08d5100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2760,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000aa2f9f0798fab1f08cf508b721e3a81dbe007e83000000000000000000000000000000000000000000000001e8c0be52c16a3746,0xf3b7e907903ae6bacc6a126b331b090a8917ffe41f4d748d7d62fe194c9532bc,2022-03-20 08:34:41.000 UTC,0,true +2764,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cddfdeec87b3041efca0367fb030bd302c4ef23b000000000000000000000000cddfdeec87b3041efca0367fb030bd302c4ef23b000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2765,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000528f3840fbad570d84d9b42e00dc3ad0bccd7432000000000000000000000000528f3840fbad570d84d9b42e00dc3ad0bccd7432000000000000000000000000000000000000000000000000001c622f8201330000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2767,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ee49f82e58a1c2b306720d0c68047cbf70c11fb500000000000000000000000000000000000000000000002a0ad5a1bb32740c43,,,1,true +2768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029b9650303f11b3f3b41ea8d6ee4372b460fdef400000000000000000000000029b9650303f11b3f3b41ea8d6ee4372b460fdef40000000000000000000000000000000000000000000000000008c7bd44e0930000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2770,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4a089e9def16a9ba97fc768dd0a5a3e6912c1b0000000000000000000000000d4a089e9def16a9ba97fc768dd0a5a3e6912c1b00000000000000000000000000000000000000000000000000036f88e8c4122e400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0b1bb9824c3715158ea500526bbf6d7cad10b6dd716a964e4fe83b48d386a5b9,2022-03-31 02:53:20.000 UTC,0,true +2772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b8011ebb5e71100f49c7283e44e00d31bdce3920000000000000000000000000b8011ebb5e71100f49c7283e44e00d31bdce39200000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2773,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b75af058d0095f334445e157a0eda61d649438c0000000000000000000000008b75af058d0095f334445e157a0eda61d649438c000000000000000000000000000000000000000000000000001167441342593f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074ab161045a668b624085fd8cb5c22946e74afca00000000000000000000000074ab161045a668b624085fd8cb5c22946e74afca000000000000000000000000000000000000000000000000000e9bf49997757e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c59ae3244f81ec51017943b1ed98cccc2345eaba000000000000000000000000c59ae3244f81ec51017943b1ed98cccc2345eaba000000000000000000000000000000000000000000000000000ffab1e53bf47800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000e31c6a20381739291ee364ccfc0264cb7d3d9a0d000000000000000000000000e31c6a20381739291ee364ccfc0264cb7d3d9a0d0000000000000000000000000000000000000000000000000000000000175fc800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2778,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000006c7409e7fd8ae66d0c5dde1e3b9093fbd0c69d670000000000000000000000006c7409e7fd8ae66d0c5dde1e3b9093fbd0c69d67000000000000000000000000000000000000000000000000000000000010f01d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4e92a22fe7795aec2decf363d8f2e8bcf25105f000000000000000000000000e4e92a22fe7795aec2decf363d8f2e8bcf25105f000000000000000000000000000000000000000000000000000db8581f46825500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2780,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000010217b5aa4704eab4c3224a5b1f3df610aa4aa7000000000000000000000000010217b5aa4704eab4c3224a5b1f3df610aa4aa700000000000000000000000000000000000000000000000000182d74b2f4e09100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004efc2658a6f7e83527ac5d9897bb0f849fc4078a0000000000000000000000004efc2658a6f7e83527ac5d9897bb0f849fc4078a000000000000000000000000000000000000000000000000001772b8fe82566700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2782,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4835ead0fe80bc3dcb4861f4bc14163aae9711f000000000000000000000000e4835ead0fe80bc3dcb4861f4bc14163aae9711f0000000000000000000000000000000000000000000000000018a8a5dd968cec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005696a90261307b12e96228549c71ae507c2895450000000000000000000000005696a90261307b12e96228549c71ae507c28954500000000000000000000000000000000000000000000000000184fe00fb5e8fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2784,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fae2b127c268174afaf3a022b365790096ba6b10000000000000000000000008fae2b127c268174afaf3a022b365790096ba6b100000000000000000000000000000000000000000000000000170c06142a0a6b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2b23a99acb2c5c3cfda13df9bf803d797afc975000000000000000000000000a2b23a99acb2c5c3cfda13df9bf803d797afc9750000000000000000000000000000000000000000000000000015a00e8ac60baf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b0152655d10ac5689247d4a6c2229d01da444a80000000000000000000000005b0152655d10ac5689247d4a6c2229d01da444a8000000000000000000000000000000000000000000000000001530bfd662b83600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2788,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000396ae68e4526f1f46245283a066c912d4d4fd24e000000000000000000000000396ae68e4526f1f46245283a066c912d4d4fd24e000000000000000000000000000000000000000000000000002a5c1dc6ce4e3d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6649002c7dee59a4019b1aa722c351c3a8e2af8000000000000000000000000f6649002c7dee59a4019b1aa722c351c3a8e2af80000000000000000000000000000000000000000000000000000b7a9e8e0cb4400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c797bbeefc7aa6124ec07ea6a0c581d9cb48fa70000000000000000000000005c797bbeefc7aa6124ec07ea6a0c581d9cb48fa700000000000000000000000000000000000000000000000000ae153d89fe800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2793,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000456e580211757f57cb0eefb35db9283b2a969cb8000000000000000000000000456e580211757f57cb0eefb35db9283b2a969cb800000000000000000000000000000000000000000000000315f58f68cba75b2f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa4e209aff277776b5e52d8193c789b03f0a2486d10fe5347648eae33190362b3,2022-03-12 12:08:07.000 UTC,0,true +2796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ae748c5a1358726a5935a658b5c8ddb3fecca6a0000000000000000000000001ae748c5a1358726a5935a658b5c8ddb3fecca6a00000000000000000000000000000000000000000000000000055ad034145b4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2798,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c02fadedc679cec2889bbaf8997caa1a7e06231e000000000000000000000000c02fadedc679cec2889bbaf8997caa1a7e06231e000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2799,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a48ccb8eaaa1e7450fe4a3c0988686ab07ec47d50000000000000000000000000000000000000000000000007a911de7cb73821e,,,1,true +2801,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de64ab675699eadb0abf518d6dbe2d2b90c0641f000000000000000000000000de64ab675699eadb0abf518d6dbe2d2b90c0641f000000000000000000000000000000000000000000000000015b372f422f8a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2805,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004287dc8c78f605812d00c102663ebcec851e1c200000000000000000000000004287dc8c78f605812d00c102663ebcec851e1c2000000000000000000000000000000000000000000000000015b7b6c8aaee60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2807,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c61b1d11cd97842068b40af602a3efb53518124d000000000000000000000000c61b1d11cd97842068b40af602a3efb53518124d0000000000000000000000000000000000000000000000000d7fa27a7bce38ef00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2808,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049f9307536739580deb16f2dae82ba0d25a23b4700000000000000000000000049f9307536739580deb16f2dae82ba0d25a23b47000000000000000000000000000000000000000000000000068609e5f48d0b9900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2809,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d678a8f39dcb33503082220d143a55c58eee15af000000000000000000000000d678a8f39dcb33503082220d143a55c58eee15af00000000000000000000000000000000000000000000000001ecc30c778542f800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a34faa5b9b9e29c191e163a520edeea93a574ba3000000000000000000000000a34faa5b9b9e29c191e163a520edeea93a574ba3000000000000000000000000000000000000000000000000011684a847196e8400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2811,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000740f3065217ff67e3a13e2634600aed26d9a1368000000000000000000000000740f3065217ff67e3a13e2634600aed26d9a1368000000000000000000000000000000000000000000000000000000000381797400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000310a744e293ed94f411f9e20764e50af370190d5000000000000000000000000310a744e293ed94f411f9e20764e50af370190d500000000000000000000000000000000000000000000000000aa19927f459e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2820,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005aa8cd3337559a8f230d2043520474fbc19328b20000000000000000000000005aa8cd3337559a8f230d2043520474fbc19328b200000000000000000000000000000000000000000000000004db73254763000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a08325ad00da971cb66a5e9e04ad3529b8f59ab0000000000000000000000002a08325ad00da971cb66a5e9e04ad3529b8f59ab00000000000000000000000000000000000000000000000000cf4e65ae9c6fc700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2822,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5835487b38fceafb04a4025dd16cecc8b8c70e3000000000000000000000000a5835487b38fceafb04a4025dd16cecc8b8c70e300000000000000000000000000000000000000000000000006ea9a5446b41b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e8166910000000000000000000000004b5f7206945951dc0bcf4c0bc5496dbee692a2c90000000000000000000000004b5f7206945951dc0bcf4c0bc5496dbee692a2c900000000000000000000000000000000000000000000000088fbc15536255e2f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d923afc2fa9c1e04c496a5d5c52a611244f62e0e000000000000000000000000d923afc2fa9c1e04c496a5d5c52a611244f62e0e000000000000000000000000000000000000000000000000006df46b0a5152b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2827,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000eccd7127ed5c291fb1e91ef5aa62113d30769345000000000000000000000000000000000000000000000000bea27ec6e3d26de1,,,1,true +2828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fd34bf29b43d7eedbd91dc664224ecb835a69270000000000000000000000005fd34bf29b43d7eedbd91dc664224ecb835a69270000000000000000000000000000000000000000000000000418c346d46fef0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc7828d0a187f65f16ca3efc2d6d710866b6b4e5fac1fd06683ee587a9aa5ba55,2022-01-12 15:50:56.000 UTC,0,true +2829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088371ada6fc43d0fddc693bdf325b0cd50360dc300000000000000000000000088371ada6fc43d0fddc693bdf325b0cd50360dc3000000000000000000000000000000000000000000000000004e45ceeb63677100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd64a097f72382e6d32a0712cdfdd45cc72b1a03000000000000000000000000fd64a097f72382e6d32a0712cdfdd45cc72b1a03000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d86222e339787a874179a41c598bca46d5d3c9f0000000000000000000000002d86222e339787a874179a41c598bca46d5d3c9f000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3430b686daa829162d2aba22c815ad3b5882f00000000000000000000000000b3430b686daa829162d2aba22c815ad3b5882f0000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2837,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000dc5edfeb777bdfaa851ebda34c102162738290da00000000000000000000000000000000000000000000000104af5f608946e774,,,1,true +2838,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f7712f47bb2527b76a011656947b964c2f5733ba0000000000000000000000000000000000000000000000000fd25b65ebd0b805,,,1,true +2839,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c1df5e5f5ac6112c9e6677550eb5e53e59651b3c000000000000000000000000000000000000000000000027fac89b0704e5bb61,,,1,true +2842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004be3ea1967d4117c93a39048316c058025e237c40000000000000000000000004be3ea1967d4117c93a39048316c058025e237c400000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000004647116a410ca5e80ee2be0077335bbf0db351660000000000000000000000004647116a410ca5e80ee2be0077335bbf0db35166000000000000000000000000000000000000000000000000000000001dcd650000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x420ea7b3d530ee2cde60866f7e6dabc23414239c66f8954b8cacc7dd589b9eb6,2022-03-12 11:55:14.000 UTC,0,true +2845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fa11fbb46e2e09c5e648780e2058d490075374a0000000000000000000000002fa11fbb46e2e09c5e648780e2058d490075374a000000000000000000000000000000000000000000000000002a2f3497df273500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077ca57216b0c71c3497ec7e62d622f559507333100000000000000000000000077ca57216b0c71c3497ec7e62d622f5595073331000000000000000000000000000000000000000000000000058503666c60fd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xabba7e32fabcbc9565be73583a7d5a8c64b3a234f4568ac2096fde18fb768567,2022-01-12 15:07:55.000 UTC,0,true +2847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea45236ceafd11e1771010ee65f3068f7b5d8875000000000000000000000000ea45236ceafd11e1771010ee65f3068f7b5d887500000000000000000000000000000000000000000000000000aa6ce9eee55c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d62966761b3451e272f3498b8f1692b1c5cf6666000000000000000000000000d62966761b3451e272f3498b8f1692b1c5cf6666000000000000000000000000000000000000000000000000015a1e1ddbc6a30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffec51798fef19426dfb32260a0967f9f7e6fd49000000000000000000000000ffec51798fef19426dfb32260a0967f9f7e6fd490000000000000000000000000000000000000000000000000244ac7c10ec94cf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c26936faf3a8377211cf21ad6901c830f5fe960d000000000000000000000000c26936faf3a8377211cf21ad6901c830f5fe960d00000000000000000000000000000000000000000000000001553324fa1908fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd041ba479812a3fb310f9553ce57830cb2e351d000000000000000000000000cd041ba479812a3fb310f9553ce57830cb2e351d0000000000000000000000000000000000000000000000001c4a7575523a3dad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2858,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc1199a5a915a162542ca155d432955151202f0c000000000000000000000000fc1199a5a915a162542ca155d432955151202f0c0000000000000000000000000000000000000000000000000043115f2cedc40900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a8b65faa0017439057d066e1ab0c597f455b2000000000000000000000000002a8b65faa0017439057d066e1ab0c597f455b20000000000000000000000000000000000000000000000000000567030cb69454600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000532cb3e10f461280946d139ccb2bf1bd64ba047a000000000000000000000000532cb3e10f461280946d139ccb2bf1bd64ba047a00000000000000000000000000000000000000000000000000624e9f1e41320000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000003a0fbb2f36271ff92ed8a16ca0343a0f320cfcd50000000000000000000000003a0fbb2f36271ff92ed8a16ca0343a0f320cfcd500000000000000000000000000000000000000000000000000000000058e37e000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1a56693e8bde18b243a243c925fb2c9f411c205000000000000000000000000a1a56693e8bde18b243a243c925fb2c9f411c205000000000000000000000000000000000000000000000000005cbb71417b494900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000662cc488fb749f4ed36396d23cfae84744d692ac000000000000000000000000662cc488fb749f4ed36396d23cfae84744d692ac00000000000000000000000000000000000000000000000004c9bc631c7f16cf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f2204f49157651f314395f4703622e3fdc8df4e0000000000000000000000007f2204f49157651f314395f4703622e3fdc8df4e000000000000000000000000000000000000000000000000015935fda850290000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2889,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000099a78666b72cb7c0e580e8fc77243146c8fddf59000000000000000000000000000000000000000000000000e86af39d60950e42,,,1,true +2890,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000069568f518102ea935ad2076d088243c6ab0d490f00000000000000000000000000000000000000000000000c5f79a53c5e43c96b,0x818d745b274097ace211a8f7bd36e05aa8a670ebcfe147b177abc3386dad9292,2021-11-28 01:39:28.000 UTC,0,true +2896,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c2768e9353bf078ace3c345d279e27d393d5c4870000000000000000000000000000000000000000000000076511ac44d3090000,,,1,true +2902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c82508ef698a893a603d5935305af7c319d61980000000000000000000000000c82508ef698a893a603d5935305af7c319d619800000000000000000000000000000000000000000000000000455d7255ca200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2905,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073d321b0d6639890a13b833777b6fd2b666b16e400000000000000000000000073d321b0d6639890a13b833777b6fd2b666b16e4000000000000000000000000000000000000000000000000001c4442cc2e120000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2908,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f433bdbf45ae8396805f5882c9f395b246e62af8000000000000000000000000f433bdbf45ae8396805f5882c9f395b246e62af800000000000000000000000000000000000000000000000002c4b8a81e45a56700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024f1bb02c7195769acb9fd1d24fdeee6409df62000000000000000000000000024f1bb02c7195769acb9fd1d24fdeee6409df6200000000000000000000000000000000000000000000000000031bced02db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xba87426646b7d517a2f7dedcaa761d0dba7714ac0ae9a71fc683543872c7823d,2022-04-11 11:24:29.000 UTC,0,true +2913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d94c5888ef3ab24ad580e8cd04dbc2e2a847b815000000000000000000000000d94c5888ef3ab24ad580e8cd04dbc2e2a847b81500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2914,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006e401916f9e149f20a1e3137d2897f843b510c64000000000000000000000000000000000000000000000000fd20433c6ed22175,,,1,true +2915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d600fee9e4162c74a59c7ca3973342d8aa491c70000000000000000000000007d600fee9e4162c74a59c7ca3973342d8aa491c70000000000000000000000000000000000000000000000000008f7bf72006d2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9461f543b102000193c3d7438d11f9135121f24000000000000000000000000f9461f543b102000193c3d7438d11f9135121f240000000000000000000000000000000000000000000000000012ae0b321c689100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000731773eb516e29d9fa37710d9e5dcdc25411d5af000000000000000000000000731773eb516e29d9fa37710d9e5dcdc25411d5af0000000000000000000000000000000000000000000000000035deecb7c78e8300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050212068f8968b5ce25acdf662f030635d1aaecb00000000000000000000000050212068f8968b5ce25acdf662f030635d1aaecb000000000000000000000000000000000000000000000000017507f7e547903000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2921,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000052a38af7d4000a763da8e6164286b59aaf11c51d00000000000000000000000052a38af7d4000a763da8e6164286b59aaf11c51d0000000000000000000000000000000000000000000000000000000029f24ffb00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b843de66d048e87d986c6dda826a79e9a724d894000000000000000000000000b843de66d048e87d986c6dda826a79e9a724d8940000000000000000000000000000000000000000000000000086bd4808b2ee8900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045852f7653d50d9178545a024fb8d47840e7ca0800000000000000000000000045852f7653d50d9178545a024fb8d47840e7ca0800000000000000000000000000000000000000000000000008fdde787fc0c10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062183389f5ff91af9eef1c832ef5913bc34656f100000000000000000000000062183389f5ff91af9eef1c832ef5913bc34656f10000000000000000000000000000000000000000000000000048e3db2425d2fc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9674231b5f21ffcbdca38352610cedae60f3b2ba80d05dbec936a68ea54c0a2b,2022-05-22 14:36:08.000 UTC,0,true +2935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b17f6649326e8f8399dacd0ecd69e7251ca92700000000000000000000000009b17f6649326e8f8399dacd0ecd69e7251ca927000000000000000000000000000000000000000000000000000bfb0c17e5571c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3dfba44f5c693315d33d85dd5ca965e09bbcbcb000000000000000000000000c3dfba44f5c693315d33d85dd5ca965e09bbcbcb0000000000000000000000000000000000000000000000000032bae7a20a5dd600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f3d41662bcfbf1ebb14917fcc006ee8ddf3fc7f0000000000000000000000007f3d41662bcfbf1ebb14917fcc006ee8ddf3fc7f000000000000000000000000000000000000000000000000001471362cbd76c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2940,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f7674c70da5241c4f16c33988d6fa879c19072fd00000000000000000000000000000000000000000000000117651c236f3d320f,,,1,true +2943,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000041ceb0d694110b702e2999e54d192c3db4a469760000000000000000000000000000000000000000000000011d744b20a777d1ff,,,1,true +2946,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004c622a5d55c5cf1bfb8d639ffe702f62a5f77af2000000000000000000000000000000000000000000000009b070adf56505f299,,,1,true +2947,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000a13a510a8fe699c3eb703a5796475536b956aff9000000000000000000000000a13a510a8fe699c3eb703a5796475536b956aff900000000000000000000000000000000000000000000000000000000001053b000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2948,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001a4decf9f5756ca8cefc99651527dd207403a9f30000000000000000000000001a4decf9f5756ca8cefc99651527dd207403a9f30000000000000000000000000000000000000000000000000efcee47256c000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2949,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000046354310e7621674983306ab8a5085f27a12747a00000000000000000000000046354310e7621674983306ab8a5085f27a12747a0000000000000000000000000000000000000000000000000f207539952d000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2950,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ec4e39fa0442cbef61f9a9a09e696f599d1e0dfa000000000000000000000000ec4e39fa0442cbef61f9a9a09e696f599d1e0dfa0000000000000000000000000000000000000000000000000f43fc2c04ee000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a30bad98f277222ef1b732ee5d4d442f90c5b035000000000000000000000000a30bad98f277222ef1b732ee5d4d442f90c5b035000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6aae268ffdfd96eb01866c8b7b0b12cbdb73ac4000000000000000000000000f6aae268ffdfd96eb01866c8b7b0b12cbdb73ac400000000000000000000000000000000000000000000000001bc9ca405e4243700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2955,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006e401916f9e149f20a1e3137d2897f843b510c64000000000000000000000000000000000000000000000000045ba9fb820dd512,,,1,true +2960,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f45fe3fc22116eb8cac9467ed992b2ee5b64bfe0000000000000000000000007f45fe3fc22116eb8cac9467ed992b2ee5b64bfe000000000000000000000000000000000000000000000000006b929aa06a9a8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2962,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c2142f5c34a7b0c01ef7cae326d4c16132996e33000000000000000000000000c2142f5c34a7b0c01ef7cae326d4c16132996e3300000000000000000000000000000000000000000000001cb93fe45e8d4bb3cf00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2963,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007bb0185b1ea004cee1e8d006394cc5d85897fe510000000000000000000000007bb0185b1ea004cee1e8d006394cc5d85897fe510000000000000000000000000000000000000000000000140ec80fa7ee88000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x3d84f2dedac8912736dc91bb283a83f3c8b405e230d53fff39dc3b2e28573994,2022-04-24 07:31:07.000 UTC,0,true +2966,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000149762ef3b4ec34b015ee92ed9e64e2f6dfe8f6e000000000000000000000000000000000000000000000000e7255200bb918000,,,1,true +2967,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000149762ef3b4ec34b015ee92ed9e64e2f6dfe8f6e000000000000000000000000149762ef3b4ec34b015ee92ed9e64e2f6dfe8f6e000000000000000000000000000000000000000000000000007bb9a73ac3d40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5a9ee2ba013adfc5bf7412eb186a32d9677ba03000000000000000000000000f5a9ee2ba013adfc5bf7412eb186a32d9677ba030000000000000000000000000000000000000000000000000015ff5a92d0b50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2975,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ad9993d36bb4035bb908d685ad4090e7689d3edb000000000000000000000000ad9993d36bb4035bb908d685ad4090e7689d3edb0000000000000000000000000000000000000000000000000f67831e74af000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +2981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0aaaeb39bd9b06905bfd85f37ab59440aa597d4000000000000000000000000f0aaaeb39bd9b06905bfd85f37ab59440aa597d4000000000000000000000000000000000000000000000000000cc9b30494ad3f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a25ca2d4f30a9ad367910ee528c7ab65b8184e39000000000000000000000000a25ca2d4f30a9ad367910ee528c7ab65b8184e390000000000000000000000000000000000000000000000000005484b203355d100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000569bfce7a6a72439d699a795c54f66826674e138000000000000000000000000569bfce7a6a72439d699a795c54f66826674e13800000000000000000000000000000000000000000000000000188b4bca2fe40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +2993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7c8f980c23dd350ddb52905d5104b3eb6a3d035000000000000000000000000d7c8f980c23dd350ddb52905d5104b3eb6a3d03500000000000000000000000000000000000000000000000000b764ae64a3e8ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8aaa4751c162be82bb9c7bad6ae34eea99c354b4ed83e5bc353982ab76ec70cf,2022-02-06 12:28:02.000 UTC,0,true +3006,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000047eaaed95dc2b665b7c99e2c83e77552a290bc8100000000000000000000000047eaaed95dc2b665b7c99e2c83e77552a290bc810000000000000000000000000000000000000000000000000f8b0a10e470000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3007,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003d8ec20c567180efa4ed40a56463ef7e544ccf470000000000000000000000003d8ec20c567180efa4ed40a56463ef7e544ccf470000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3008,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006e28fd005399e9ea1354fea0374a8d24a67e70610000000000000000000000006e28fd005399e9ea1354fea0374a8d24a67e70610000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3009,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007e273826908f8085a9a8b8e13536cc55a4542c8e0000000000000000000000007e273826908f8085a9a8b8e13536cc55a4542c8e0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3010,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004c3351aa306e945825d8531e4d63787b107c9ac20000000000000000000000004c3351aa306e945825d8531e4d63787b107c9ac20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3011,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000035918cf35b5c97ea1879101c2fdc46296efec18e00000000000000000000000035918cf35b5c97ea1879101c2fdc46296efec18e0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3012,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002ea67afd407445ecffda6b010419da2cb85a8c1e0000000000000000000000002ea67afd407445ecffda6b010419da2cb85a8c1e0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3013,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000b716ac1490cb07340a58cdaee34abf9af7b2d510000000000000000000000000b716ac1490cb07340a58cdaee34abf9af7b2d510000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3014,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006044e2ad9edce0ac262fb8e5048230dc83bffd760000000000000000000000006044e2ad9edce0ac262fb8e5048230dc83bffd760000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3016,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c691644b8095f9c4bb8a002acec957f4ffe368c1000000000000000000000000c691644b8095f9c4bb8a002acec957f4ffe368c1000000000000000000000000000000000000000000000000149b89020e50b7d500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3017,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000891acdefa5f01ab48bf69ff789ce9d3a9997f017000000000000000000000000000000000000000000000003afb087b876900000,,,1,true +3018,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f85c77731efa8dddc03e6196a838711fa36b81e0000000000000000000000000f85c77731efa8dddc03e6196a838711fa36b81e00000000000000000000000000000000000000000000000000033e2c078aaddb900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014e8b481bffa5df52a7513612c65003e6bb8237a00000000000000000000000014e8b481bffa5df52a7513612c65003e6bb8237a0000000000000000000000000000000000000000000000000076682ec4f3f1f900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3026,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000214016af97e9435189d81c57864f6256b86e9c330000000000000000000000000000000000000000000000059351d3b293df6355,,,1,true +3029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038b15bfda512900fcd056ab43b009fa86234cda900000000000000000000000038b15bfda512900fcd056ab43b009fa86234cda90000000000000000000000000000000000000000000000000032c6b789309f6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3039,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f23cd4c0cffc6cebd92c189b961b51bef93bd5f10000000000000000000000000000000000000000000000001dcbf130de84fdd1,,,1,true +3043,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000baac2b4491727d78d2b78815144570b9f2fe88990000000000000000000000008f69ee043d52161fd29137aedf63f5e70cd504d500000000000000000000000023bc95f84bd43c1fcc2bc285fda4cb12f9aee2df00000000000000000000000023bc95f84bd43c1fcc2bc285fda4cb12f9aee2df000000000000000000000000000000000000000000000003bd913e6c1df4000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3044,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b1899d88b4ff0cf5a34651e7ce7164398211c660000000000000000000000005b1899d88b4ff0cf5a34651e7ce7164398211c66000000000000000000000000000000000000000000000000001841922677b8cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a4c18d444dc710828665f2fbfa6301e64412a560000000000000000000000009a4c18d444dc710828665f2fbfa6301e64412a56000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f771cff1d5ffd05e877447c7604c4d0fe03ca884000000000000000000000000f771cff1d5ffd05e877447c7604c4d0fe03ca884000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000367bab5c08fd07956f6f70fa3871e1cbca917569000000000000000000000000367bab5c08fd07956f6f70fa3871e1cbca917569000000000000000000000000000000000000000000000000006a7054713fdb3600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3055,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000046ac0c9c530dc960a4df75b20b594fba243e5b7c00000000000000000000000000000000000000000000000090942a24a68a4cbe,,,1,true +3056,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000fc3551f3b51f27ca60efb25f45ed95d4e80e707100000000000000000000000000000000000000000000000071765f0478a614ed,,,1,true +3057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb9c0e20fa62e08e8f8d4588efbb8d63ed7331d3000000000000000000000000cb9c0e20fa62e08e8f8d4588efbb8d63ed7331d3000000000000000000000000000000000000000000000000027f7d0bdb92000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3058,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000046ac0c9c530dc960a4df75b20b594fba243e5b7c000000000000000000000000000000000000000000000000f869cca7ed0038b7,,,1,true +3059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4fcc2d19ae692a7aeb7d540139a37c7af1205c4000000000000000000000000f4fcc2d19ae692a7aeb7d540139a37c7af1205c40000000000000000000000000000000000000000000000000214e8348c4f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb9b522c09ba76f609698b09c75be96a4dc66fc5b41e59e2dd9e1c01cdf7e3994,2021-11-28 14:32:49.000 UTC,0,true +3060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc89ec35fcecc62273603b6031f93ca692a54414000000000000000000000000cc89ec35fcecc62273603b6031f93ca692a54414000000000000000000000000000000000000000000000000021772c9b190a25800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000384b123866cd169d1bd00c67a2c869cc836022bb000000000000000000000000384b123866cd169d1bd00c67a2c869cc836022bb000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3062,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086e4bf82ce08af2202696cf432211ce782d02fb600000000000000000000000086e4bf82ce08af2202696cf432211ce782d02fb600000000000000000000000000000000000000000000000000ab9d2ba41f654b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3063,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000565fe00d8b1ea73adecd7bb86755866242219a31000000000000000000000000565fe00d8b1ea73adecd7bb86755866242219a310000000000000000000000000000000000000000000000065c74b174e14505d400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3064,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4e6e329e85673be7a15b5ed3c4399a8ba951bc6000000000000000000000000f4e6e329e85673be7a15b5ed3c4399a8ba951bc6000000000000000000000000000000000000000000000000029249fd61b8e1a900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3066,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095b391ce72da4fd408fd5f0e6c9b697db7ce181000000000000000000000000095b391ce72da4fd408fd5f0e6c9b697db7ce1810000000000000000000000000000000000000000000000000002453edde94d66400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3068,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087fbccf395d7637bb4baab7602ba78f3edd1277400000000000000000000000087fbccf395d7637bb4baab7602ba78f3edd1277400000000000000000000000000000000000000000000000014c9889c3328fb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9803cad0b6096136d7f66e08886c960af2fb72eecfb5e4099a50f060b9a1045e,2022-06-17 06:36:16.000 UTC,0,true +3070,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f20872b1517b641bdc0680cc279e0ed33e9b41c0000000000000000000000002f20872b1517b641bdc0680cc279e0ed33e9b41c000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3071,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac4bfcd893230a82f9f905f92457378b52a1d706000000000000000000000000ac4bfcd893230a82f9f905f92457378b52a1d706000000000000000000000000000000000000000000000000006377fc7ef7fc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3074,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f278ac8e97dd418a3ce13307fa1b44ff87a18f7c000000000000000000000000f278ac8e97dd418a3ce13307fa1b44ff87a18f7c000000000000000000000000000000000000000000000000003873329a317a1700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e095d1a7ed1a1173d69d7bd724b2b7c6c81b0e4b000000000000000000000000e095d1a7ed1a1173d69d7bd724b2b7c6c81b0e4b000000000000000000000000000000000000000000000000005cd42e99b2990700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3077,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000315483c35d2c1ea9d5be576b0f795ae8cd0d4de0000000000000000000000000315483c35d2c1ea9d5be576b0f795ae8cd0d4de000000000000000000000000000000000000000000000000003c37bf0ca21f5500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006148c045497f07cda8c2d74a54e510fea4b4ee590000000000000000000000006148c045497f07cda8c2d74a54e510fea4b4ee59000000000000000000000000000000000000000000000000008187f32f0f290000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3080,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006ed916e093ebccc790109f4a2073bff50cf9160e0000000000000000000000000000000000000000000000022b1c8c1227a00000,,,1,true +3081,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000d20fc3c32b213a39b0314ce804ba33aa5c6ed6f000000000000000000000000000000000000000000000004e341d84852aef2c9,,,1,true +3092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000549750e6b5b40e627365bdcf7f7780dbfde113a4000000000000000000000000549750e6b5b40e627365bdcf7f7780dbfde113a4000000000000000000000000000000000000000000000000015bbfa9d32e420000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084f1e7260d927e3d2ea4f5c4ba1f52946420ff0400000000000000000000000084f1e7260d927e3d2ea4f5c4ba1f52946420ff0400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000781cdc81cc8a315433bdc1c581a649c4c0d61ee7000000000000000000000000781cdc81cc8a315433bdc1c581a649c4c0d61ee7000000000000000000000000000000000000000000000000052b4c0a4ee1dbff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3103,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b62832f8b38570909411d32088fa3eb5d5752bed000000000000000000000000b62832f8b38570909411d32088fa3eb5d5752bed00000000000000000000000000000000000000000000000004f924563be6636900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa3c2d7d282de8cdd14e97e61d0887d6ce2edafd000000000000000000000000aa3c2d7d282de8cdd14e97e61d0887d6ce2edafd00000000000000000000000000000000000000000000000001f833f035ec0b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0c3a265d41b13d33f24b2a1611738fafc2be4ad5eb0f9597602b3e37152e5f6d,2021-12-02 23:39:35.000 UTC,0,true +3106,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa1fbe434eb61ca6d7967e7ddc13d93422007892000000000000000000000000aa1fbe434eb61ca6d7967e7ddc13d93422007892000000000000000000000000000000000000000000000000006b4231355963bc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0b0a2b343a6cbfb1a2c4eb70ab06b6829e9db9a000000000000000000000000a0b0a2b343a6cbfb1a2c4eb70ab06b6829e9db9a0000000000000000000000000000000000000000000000000095fa88b4a6a67a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3108,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1de8febdeda64438bdff1ceb70bf6e0820794b1000000000000000000000000a1de8febdeda64438bdff1ceb70bf6e0820794b1000000000000000000000000000000000000000000000000008f2b935ff7c07200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3109,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000fd65af1a0f332c6ee4d3c787a65b0ad674e847ef000000000000000000000000fd65af1a0f332c6ee4d3c787a65b0ad674e847ef00000000000000000000000000000000000000000000000010cac896d239000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3110,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000bb24fdb708e47f85712ab07df417056e4c1438a4000000000000000000000000bb24fdb708e47f85712ab07df417056e4c1438a400000000000000000000000000000000000000000000000010ee4f8941fa000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3111,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e7166fd81bb217a5c05cefb6e1570bda50cfb21f000000000000000000000000e7166fd81bb217a5c05cefb6e1570bda50cfb21f0000000000000000000000000000000000000000000000001111d67bb1bb000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3112,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004d9248bd9809b4acc33fedb4ee6101e27e5adbc50000000000000000000000004d9248bd9809b4acc33fedb4ee6101e27e5adbc500000000000000000000000000000000000000000000000011355d6e217c000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3113,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000dd8836898c60e12c064e9b33f78adbebd54a2d14000000000000000000000000dd8836898c60e12c064e9b33f78adbebd54a2d140000000000000000000000000000000000000000000000001158e460913d000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3114,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b838af0c27e59dd996dd8f4e9a6b758f589a92d7000000000000000000000000b838af0c27e59dd996dd8f4e9a6b758f589a92d7000000000000000000000000000000000000000000000000117c6b5300fe000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3115,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000004d9c2724ae629133e695a6b68b257bb2537263500000000000000000000000004d9c2724ae629133e695a6b68b257bb25372635000000000000000000000000000000000000000000000000119ff24570bf000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3116,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c2f0b9c7da3494c6fe553c48dc103bb8b5b4b27d000000000000000000000000c2f0b9c7da3494c6fe553c48dc103bb8b5b4b27d00000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3117,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007f07fc54c59286b42267f550447b3341ef086c200000000000000000000000007f07fc54c59286b42267f550447b3341ef086c2000000000000000000000000000000000000000000000000011e7002a5041000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3118,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c7cf2ecccece264008aa10dd26fbfcf17b8a1a60000000000000000000000000c7cf2ecccece264008aa10dd26fbfcf17b8a1a60000000000000000000000000000000000000000000000000120a871cc002000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3119,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000596e114e8ff94a75645e67b3d2e3b7fc277cee75000000000000000000000000596e114e8ff94a75645e67b3d2e3b7fc277cee75000000000000000000000000000000000000000000000000122e0e0f2fc3000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3120,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000bd4a8e573a9dd2d20edae1c43c7477e719043296000000000000000000000000bd4a8e573a9dd2d20edae1c43c7477e719043296000000000000000000000000000000000000000000000000125195019f84000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3121,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000dcf71305489604918dc84a42c613104e50a25b4f000000000000000000000000dcf71305489604918dc84a42c613104e50a25b4f00000000000000000000000000000000000000000000000012751bf40f45000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3122,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008ec827c95d55f097365e47c46cdd0e6d178362f70000000000000000000000008ec827c95d55f097365e47c46cdd0e6d178362f70000000000000000000000000000000000000000000000001298a2e67f06000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3123,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c65b964cc64973ec71af5345145a6808117127d0000000000000000000000000c65b964cc64973ec71af5345145a6808117127d000000000000000000000000000000000000000000000000012bc29d8eec7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3124,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000678ddbda74966f453472fa6c56e15b76ccc162e0000000000000000000000000678ddbda74966f453472fa6c56e15b76ccc162e00000000000000000000000000000000000000000000000012dfb0cb5e88000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3125,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000095db6d4e7596331e6a4c433f58414ac8f1d354b000000000000000000000000095db6d4e7596331e6a4c433f58414ac8f1d354b0000000000000000000000000000000000000000000000000130337bdce49000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3126,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000fe87e90e5a93f099faabc86fc2647001f723cd79000000000000000000000000fe87e90e5a93f099faabc86fc2647001f723cd790000000000000000000000000000000000000000000000001326beb03e0a000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3127,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008c351deac0d2fb6ee213f6a460de47feba26fe5e0000000000000000000000008c351deac0d2fb6ee213f6a460de47feba26fe5e000000000000000000000000000000000000000000000000134a45a2adcb000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3128,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000faf24f3eaee54b20f1cb50f9ec27674a3a7f7b51000000000000000000000000faf24f3eaee54b20f1cb50f9ec27674a3a7f7b51000000000000000000000000000000000000000000000000136dcc951d8c000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3129,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d582528b2ced3ea73d247dd6015757c84f83531e000000000000000000000000d582528b2ced3ea73d247dd6015757c84f83531e000000000000000000000000000000000000000000000000139153878d4d000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3130,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000581dcd3c175619057557d9c504578def15f394de000000000000000000000000581dcd3c175619057557d9c504578def15f394de00000000000000000000000000000000000000000000000013b4da79fd0e000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3131,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004f88513b32d2a747355cc98d8eb7c617c91b9f670000000000000000000000004f88513b32d2a747355cc98d8eb7c617c91b9f6700000000000000000000000000000000000000000000000013d8616c6ccf000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3132,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000dee9350fc8e38d1dca06fdf916bffeddeff468d7000000000000000000000000dee9350fc8e38d1dca06fdf916bffeddeff468d700000000000000000000000000000000000000000000000013fbe85edc90000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3133,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000acb1e9a1dc81c64520f300793f076295929d6b19000000000000000000000000acb1e9a1dc81c64520f300793f076295929d6b19000000000000000000000000000000000000000000000000141f6f514c51000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3134,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f953a0f3335574e1f4b2f77c3fb7a7a465fa5f20000000000000000000000000f953a0f3335574e1f4b2f77c3fb7a7a465fa5f200000000000000000000000000000000000000000000000001442f643bc12000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3137,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ae2adf9a0727e69b6f5105d183e684894a75d39a00000000000000000000000000000000000000000000000087f76835c87c8b71,,,1,true +3141,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea3088c92ccf0874c6a13062745fc6b1552a1a87000000000000000000000000ea3088c92ccf0874c6a13062745fc6b1552a1a8700000000000000000000000000000000000000000000000000034b3c6e5f6b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e4e87ef976eab568fda866d23141d37950baf4d9000000000000000000000000e4e87ef976eab568fda866d23141d37950baf4d900000000000000000000000000000000000000000000000000000000da6a919800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cffd91182d94fb37a49fbd626400468197291ccd000000000000000000000000cffd91182d94fb37a49fbd626400468197291ccd0000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3147,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4bc8e08f7ba01043b2088040255036b57edaf91000000000000000000000000a4bc8e08f7ba01043b2088040255036b57edaf9100000000000000000000000000000000000000000000000001e3a602772762cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047f80003f5dfa14c12d25dd52c2bbab9f206504e00000000000000000000000047f80003f5dfa14c12d25dd52c2bbab9f206504e0000000000000000000000000000000000000000000000001b52dc7772062e8a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1344576ad891ac66e5252dba5365b88da1fd99b000000000000000000000000e1344576ad891ac66e5252dba5365b88da1fd99b00000000000000000000000000000000000000000000000000934b72171c0d6b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dba4f369e6fce16c0552bb9cb6e0df6b89a0eed1000000000000000000000000dba4f369e6fce16c0552bb9cb6e0df6b89a0eed100000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c9fd4438cbc2a251bbf67877c4b70e18e74e4530000000000000000000000009c9fd4438cbc2a251bbf67877c4b70e18e74e45300000000000000000000000000000000000000000000000001547251fa85e06f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3155,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081d7d26fbc67b56bebf9c6b1937ff3ebeae6e7bc00000000000000000000000081d7d26fbc67b56bebf9c6b1937ff3ebeae6e7bc0000000000000000000000000000000000000000000000000031a6981644520900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae6686600f0019b56b4c890225ce7526690b83c1000000000000000000000000ae6686600f0019b56b4c890225ce7526690b83c10000000000000000000000000000000000000000000000000a333e9b15e9800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3164,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a80383f17a92b110921c07fb5261798f3a99377f000000000000000000000000a80383f17a92b110921c07fb5261798f3a99377f00000000000000000000000000000000000000000000000000ed877d6e13faae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3effc5393cdbe8779c39c4c8d9a934e6f1f390f000000000000000000000000f3effc5393cdbe8779c39c4c8d9a934e6f1f390f0000000000000000000000000000000000000000000000000dd23cedcb7425e300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000286060cd2e24e0bd0814a83e3621c4ed6d5e2466000000000000000000000000286060cd2e24e0bd0814a83e3621c4ed6d5e2466000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3172,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b3900179e0d9e20712ed41f8bb9ff8cb1e3fc880000000000000000000000006b3900179e0d9e20712ed41f8bb9ff8cb1e3fc8800000000000000000000000000000000000000000000000000a4f4e11115ae0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3173,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000489872f68bd0da1ca97383a97342f0e230c8f24f000000000000000000000000489872f68bd0da1ca97383a97342f0e230c8f24f000000000000000000000000000000000000000000000000015b4cb81b29910000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000c50c8c222c35830f74dcc13200570f1203d987d5000000000000000000000000c50c8c222c35830f74dcc13200570f1203d987d5000000000000000000000000000000000000000000000000000000000af33ed000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x2ac23bd99eb6500e0e5f639cc413adcefd0b70799d5cf007db34d44798ef808d,2022-02-27 08:23:16.000 UTC,0,true +3178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c50c8c222c35830f74dcc13200570f1203d987d5000000000000000000000000c50c8c222c35830f74dcc13200570f1203d987d500000000000000000000000000000000000000000000000000788efe072b90b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb5bfb78296ff2811032f3222adb951b97d365cc6a3fe54ed9b5c443fc411dd66,2022-02-27 08:14:41.000 UTC,0,true +3179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000004599080d9b74316af108884f506ba4a595ea50910000000000000000000000004599080d9b74316af108884f506ba4a595ea5091000000000000000000000000000000000000000000000000000000000ac3030500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa22a7311378aa22c95826245ca7483b0fe0c8a6a9364f01787c6725bbaaf3f15,2022-02-27 08:14:41.000 UTC,0,true +3180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb9950d9400cc1542bad1803a1e5df7ac666e5d5000000000000000000000000bb9950d9400cc1542bad1803a1e5df7ac666e5d500000000000000000000000000000000000000000000000001153f1eabfb52de00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf4701ca4a43d0028c46b67c92ac436ec290e33e000000000000000000000000cf4701ca4a43d0028c46b67c92ac436ec290e33e00000000000000000000000000000000000000000000000000422f08813e73fa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3184,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a0fbb2f36271ff92ed8a16ca0343a0f320cfcd50000000000000000000000003a0fbb2f36271ff92ed8a16ca0343a0f320cfcd50000000000000000000000000000000000000000000000000014e58f1d3045c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b3beffe27430d4ac916b8e9c7715611270d93a90000000000000000000000005b3beffe27430d4ac916b8e9c7715611270d93a900000000000000000000000000000000000000000000000000141a9b3a9f890000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3187,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b65ed9846d774942370620581645c430410f3ab9000000000000000000000000b65ed9846d774942370620581645c430410f3ab900000000000000000000000000000000000000000000000005a853b074c8566600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7c64bbfe4ec9e75c806d01a167416d910a4f8950097663f7c076de27b2d90b0c,2022-02-26 21:41:04.000 UTC,0,true +3190,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0a9de2479f5cd97669b0fbd4d1ee1ef70c99b22000000000000000000000000b0a9de2479f5cd97669b0fbd4d1ee1ef70c99b22000000000000000000000000000000000000000000000000009645dc4d8b334a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3192,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000dc18c785ee9f9d3b797f4b034af8d20bb2ca1e2500000000000000000000000000000000000000000000007d181e3d487f2dd352,,,1,true +3193,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be0f0f1077e5f5ed5e9b1dac16b6873163889381000000000000000000000000be0f0f1077e5f5ed5e9b1dac16b6873163889381000000000000000000000000000000000000000000000000015b6aa4d0fcb20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3195,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000068557e2154013a1c5564175271c1d107c241521000000000000000000000000068557e2154013a1c5564175271c1d107c2415210000000000000000000000000000000000000000000000000016e6fdcb72148000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000cb036c18b9c382d3ff9ab1319e2964a732961080000000000000000000000000cb036c18b9c382d3ff9ab1319e2964a7329610800000000000000000000000000000000000000000000000000a1aeb5ff8297dd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3203,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000321700a6493f8865d7f5a541c7007c1ff07d9370000000000000000000000000321700a6493f8865d7f5a541c7007c1ff07d937000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d12f7211071a20ce76bf9fb8e069036b6fb63c6a000000000000000000000000d12f7211071a20ce76bf9fb8e069036b6fb63c6a000000000000000000000000000000000000000000000000014c872a5b4dbe7b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3205,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c86a39e67d1d64071d443721083839bb16c5273f000000000000000000000000c86a39e67d1d64071d443721083839bb16c5273f0000000000000000000000000000000000000000000000000328d829df31030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000faef04074a99713bb25f1fefd7cbff5d65235265000000000000000000000000faef04074a99713bb25f1fefd7cbff5d6523526500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092c2aa78ae7248f788f14a42e6daba156d3c898100000000000000000000000092c2aa78ae7248f788f14a42e6daba156d3c898100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b45d0c759524ae9ce9d2091a1b2e663b1f5c6a6a000000000000000000000000b45d0c759524ae9ce9d2091a1b2e663b1f5c6a6a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3211,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed374ece52ab111bdbaee9f1013429f474c883ba000000000000000000000000ed374ece52ab111bdbaee9f1013429f474c883ba00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3213,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002babe76345d7eb15f6a1c0cddba04d8ee44491d50000000000000000000000002babe76345d7eb15f6a1c0cddba04d8ee44491d500000000000000000000000000000000000000000000000000014add956eb90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004bbb7ea18ea570ae47d4489991645e4e49bbf3700000000000000000000000004bbb7ea18ea570ae47d4489991645e4e49bbf37000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c00a3fa2eef1afccf044af59ce105b8200272cd0000000000000000000000003c00a3fa2eef1afccf044af59ce105b8200272cd00000000000000000000000000000000000000000000000000074f0df332dd8300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3217,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001040a43093b700d9bfe90346990afaa4d11515080000000000000000000000001040a43093b700d9bfe90346990afaa4d115150800000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8f4d5f35b3d819caa21ff649a1dce9674acd9d1000000000000000000000000a8f4d5f35b3d819caa21ff649a1dce9674acd9d1000000000000000000000000000000000000000000000000002f904483a7ecd300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006916ea1489b98a932f8da3b884864383b00c13090000000000000000000000006916ea1489b98a932f8da3b884864383b00c130900000000000000000000000000000000000000000000000000dad8dfa62a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e58dd42d7908d8924a599e5e28e15f4f58c40750000000000000000000000003e58dd42d7908d8924a599e5e28e15f4f58c407500000000000000000000000000000000000000000000000000b602529f40777c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3223,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec787b619878d0b237bad72f8f7ecfd02716fa07000000000000000000000000ec787b619878d0b237bad72f8f7ecfd02716fa07000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3229,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bb74a933655bd91c14f29c53cde15dcc747fc080000000000000000000000006bb74a933655bd91c14f29c53cde15dcc747fc08000000000000000000000000000000000000000000000000009ed4c2e0726c8600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7da0ebe1069e4070336264ce02eb9d753ce671a43ea53f3a9ab887c4c4f421d9,2022-09-07 08:34:53.000 UTC,0,true +3231,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000afef7e6c7cc8ee1ce7140fdacee481ed5f219113000000000000000000000000afef7e6c7cc8ee1ce7140fdacee481ed5f21911300000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000449833c57904f9d88cd3c26932060a329b93fe94000000000000000000000000449833c57904f9d88cd3c26932060a329b93fe940000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005516a8e92c56017699437689959098d7454669260000000000000000000000005516a8e92c56017699437689959098d74546692600000000000000000000000000000000000000000000000000ce8f2b09b9b90400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf06371c25e66dc83ef6b838bd73c68db17552f18c653fd39e65f5157cec3e02e,2022-06-01 11:26:36.000 UTC,0,true +3235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000400d7004932cbbf9cecdf4adc879f41d6d21446d000000000000000000000000400d7004932cbbf9cecdf4adc879f41d6d21446d00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7c82eb2e8e7ec23e1a172c3195e2113ebfa0a10f5bc610bfdf66e5423bebcfd3,2022-03-13 18:41:26.000 UTC,0,true +3236,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000009d842ea243d72d025d3765e262d65a3d67e3eee50000000000000000000000009d842ea243d72d025d3765e262d65a3d67e3eee500000000000000000000000000000000000000000000000029a2241af62c000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3237,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a80ffb74fc19d8a6d30ecd2cd0fd9402840cbcc0000000000000000000000001a80ffb74fc19d8a6d30ecd2cd0fd9402840cbcc000000000000000000000000000000000000000000000000015abb4a7c76790000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x43d6fa1fd970ed5d5b5ad360e37d3e72a4c066e0667ebee20ed26b5c3d30a36f,2022-03-26 10:00:56.000 UTC,0,true +3238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efa5d5c4816b2fdca66a6cbfb01b7f1767e82176000000000000000000000000efa5d5c4816b2fdca66a6cbfb01b7f1767e8217600000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000495e9ac565e21f89589675d8a93133a54d7d831c000000000000000000000000495e9ac565e21f89589675d8a93133a54d7d831c00000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3243,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000083d420a602b5cd560ac5fa9bbca0d5e91e4cb975000000000000000000000000000000000000000000000002f61d2ac547c71cfe,,,1,true +3244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2a4fe75cca5fce383be6550a87a05bf3653789a000000000000000000000000d2a4fe75cca5fce383be6550a87a05bf3653789a000000000000000000000000000000000000000000000000013ba2bd2330a77300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3247,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d81c7a2ca633703c7f171c460413ee590ff33e40000000000000000000000002d81c7a2ca633703c7f171c460413ee590ff33e4000000000000000000000000000000000000000000000000014e242122773ce700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000187da357c4470445f2cb9476afc445875eefc6e5000000000000000000000000187da357c4470445f2cb9476afc445875eefc6e50000000000000000000000000000000000000000000000000096fd865af4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e5745f3136e1023b7db402f2f20d59ece802f4a0000000000000000000000002e5745f3136e1023b7db402f2f20d59ece802f4a000000000000000000000000000000000000000000000000000ee96c5d2f714800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e5745f3136e1023b7db402f2f20d59ece802f4a0000000000000000000000002e5745f3136e1023b7db402f2f20d59ece802f4a000000000000000000000000000000000000000000000000003d1dca1ae882de00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3254,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc18c785ee9f9d3b797f4b034af8d20bb2ca1e25000000000000000000000000dc18c785ee9f9d3b797f4b034af8d20bb2ca1e250000000000000000000000000000000000000000000000000ee48f826966c94100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088a4b2e09b7c47f0c1434f277c56a5baba0f564400000000000000000000000088a4b2e09b7c47f0c1434f277c56a5baba0f56440000000000000000000000000000000000000000000000000098c445ad57800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a39ab9a6e560dbc803a9f5a4ce733e567d35de8b000000000000000000000000a39ab9a6e560dbc803a9f5a4ce733e567d35de8b00000000000000000000000000000000000000000000000000809b16e8257a8600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3259,0x72209fe68386b37a40d6bca04f78356fd342491f,0xe22d2bedb3eca35e6397e0c6d62857094aa26f52,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000adca2d0e82c65c3c9bde8441a665eb73b95dd5c91230bab3d96eeec005f12e889000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000f446700000000000000000000000000000000000000000000000000000000613bd7fe,,,1,true +3263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f310e3613336773ba176fc7b9f90bdb43f7126c3000000000000000000000000f310e3613336773ba176fc7b9f90bdb43f7126c300000000000000000000000000000000000000000000000000510c5675d24b4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3267,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2c7acc7679eb83585fe171f7f7f5974adf77183000000000000000000000000e2c7acc7679eb83585fe171f7f7f5974adf771830000000000000000000000000000000000000000000000000034b29848cb369f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca5bf99cdeb411d7f4db43a9bc41d5ed0ce9f979000000000000000000000000ca5bf99cdeb411d7f4db43a9bc41d5ed0ce9f9790000000000000000000000000000000000000000000000000009030fa91c68c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3271,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000767d7106ee69d311d0e483d0f1bbbf109b85429c000000000000000000000000767d7106ee69d311d0e483d0f1bbbf109b85429c000000000000000000000000000000000000000000000000029e24cae0ad987000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000211db282704d8b184450c123950c4f45ffa95383000000000000000000000000211db282704d8b184450c123950c4f45ffa95383000000000000000000000000000000000000000000000000001c9515dff3150000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3273,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000282f7783c091b115c96f0de119b0fe104b40813f000000000000000000000000282f7783c091b115c96f0de119b0fe104b40813f00000000000000000000000000000000000000000000000002a1e5ac7c671e8f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091a4f00bac6190d6bcbd10ee83ccee83f094f8a500000000000000000000000091a4f00bac6190d6bcbd10ee83ccee83f094f8a500000000000000000000000000000000000000000000000000753d533d96800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051b0c5368c7efb044efa2e3f39f851e7617db28600000000000000000000000051b0c5368c7efb044efa2e3f39f851e7617db28600000000000000000000000000000000000000000000000002aa19ea93d69c1300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db41304d12e287c1bfd74d6965afb106583839b4000000000000000000000000db41304d12e287c1bfd74d6965afb106583839b400000000000000000000000000000000000000000000000002a1229f3baf469000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3278,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9d9eb50b69be30cde50e1875bb82fb90f1b2695000000000000000000000000f9d9eb50b69be30cde50e1875bb82fb90f1b269500000000000000000000000000000000000000000000000002a3f2a22d254e4200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3279,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000005a98f0a07458621598e591a1255316e6515813e40000000000000000000000005a98f0a07458621598e591a1255316e6515813e400000000000000000000000000000000000000000000000014667d362bd3000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3280,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000093adf2405d5a96e854b35401a3d38673ecdab70800000000000000000000000093adf2405d5a96e854b35401a3d38673ecdab708000000000000000000000000000000000000000000000000148a04289b94000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3281,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004ca8aea046f531bee57a41556ebf948accf8db6b0000000000000000000000004ca8aea046f531bee57a41556ebf948accf8db6b00000000000000000000000000000000000000000000000014ad8b1b0b55000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3282,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004c5cc3eab1f3b9c2c86859721fcb1e9e7920c48d0000000000000000000000004c5cc3eab1f3b9c2c86859721fcb1e9e7920c48d00000000000000000000000000000000000000000000000014d1120d7b16000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3284,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000a4cc2af15be61924bf69a677fc86140534b83320000000000000000000000000a4cc2af15be61924bf69a677fc86140534b833200000000000000000000000000000000000000000000000014f498ffead7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3285,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000dda1beb63aa1e4e3b0b0defeef32d843d99cf02e000000000000000000000000dda1beb63aa1e4e3b0b0defeef32d843d99cf02e00000000000000000000000000000000000000000000000015181ff25a98000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082f6c30e1bd3c41e7d21c4c42fc71836c1e9738700000000000000000000000082f6c30e1bd3c41e7d21c4c42fc71836c1e9738700000000000000000000000000000000000000000000000002a2276d2960fcca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3287,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000314dcaacfceb25363ffb8c3888068de978d64060000000000000000000000000314dcaacfceb25363ffb8c3888068de978d6406000000000000000000000000000000000000000000000000153ba6e4ca59000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3288,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001e63f2bb3abdc22fea164895c756c732d55086d10000000000000000000000001e63f2bb3abdc22fea164895c756c732d55086d1000000000000000000000000000000000000000000000000155f2dd73a1a000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3289,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001494636d65ed41ffb4b614f395b17fc8fa57b3550000000000000000000000001494636d65ed41ffb4b614f395b17fc8fa57b3550000000000000000000000000000000000000000000000001582b4c9a9db000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000c14795b0683e2ba07d4b59d1dc21ac5142116079000000000000000000000000c14795b0683e2ba07d4b59d1dc21ac5142116079000000000000000000000000000000000000000000000000000000000017cdc000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3291,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000012d1c9ce4475201e93fa9a18952efb549dd8273100000000000000000000000012d1c9ce4475201e93fa9a18952efb549dd8273100000000000000000000000000000000000000000000000015c9c2ae895d000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3292,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c00e2fcc125ad1258fe8a0c2d677d56129ad972d000000000000000000000000c00e2fcc125ad1258fe8a0c2d677d56129ad972d00000000000000000000000000000000000000000000000015ed49a0f91e000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3293,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000288da700ec522cf8db1c8b275077c87918d3f09e000000000000000000000000288da700ec522cf8db1c8b275077c87918d3f09e0000000000000000000000000000000000000000000000001610d09368df000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3294,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000ce07fab029d302412d6af25958c7ffa624aa4c30000000000000000000000000ce07fab029d302412d6af25958c7ffa624aa4c300000000000000000000000000000000000000000000000016345785d8a0000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3295,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000dda831e92882db02f5c7a41f81cb1a6686143a09000000000000000000000000dda831e92882db02f5c7a41f81cb1a6686143a090000000000000000000000000000000000000000000000001657de784861000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3296,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000132e62f776a7d4ea7f699dc254cf0183f676bfb4000000000000000000000000132e62f776a7d4ea7f699dc254cf0183f676bfb4000000000000000000000000000000000000000000000000167b656ab822000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3297,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000417990fb7123caf0408ab8e6bf0ce940bcbc1984000000000000000000000000417990fb7123caf0408ab8e6bf0ce940bcbc1984000000000000000000000000000000000000000000000000169eec5d27e3000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051ceb0212c459d33f2abd2ef42aa032148c63ff700000000000000000000000051ceb0212c459d33f2abd2ef42aa032148c63ff7000000000000000000000000000000000000000000000000009fdf42f6e4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3299,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf600a6d8a8afba5f04a98332819aa3a5780c1a000000000000000000000000bdf600a6d8a8afba5f04a98332819aa3a5780c1a000000000000000000000000000000000000000000000000025dd7c56866a34600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3300,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000078375e9e5718166d1bc359a83a70b9f1616d729700000000000000000000000078375e9e5718166d1bc359a83a70b9f1616d729700000000000000000000000000000000000000000000000016c2734f97a4000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3301,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b5e80f61156a718da4e38370e7b05ce996ebe682000000000000000000000000b5e80f61156a718da4e38370e7b05ce996ebe68200000000000000000000000000000000000000000000000016e5fa420765000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3302,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3c983daa3288f2b15bba878a97042dcbf61c698000000000000000000000000a3c983daa3288f2b15bba878a97042dcbf61c6980000000000000000000000000000000000000000000000000023b95a97533e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3303,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002b9f0d9259597fabeeed9c3f24f80804a708f6ac0000000000000000000000002b9f0d9259597fabeeed9c3f24f80804a708f6ac000000000000000000000000000000000000000000000000170981347726000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3304,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ea91b1d966822bed13d43ffe992e98560175a1c0000000000000000000000000ea91b1d966822bed13d43ffe992e98560175a1c0000000000000000000000000000000000000000000000000172d0826e6e7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3305,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b9662f040de73de8ef26ea04bfcdb6ffbb8087c1000000000000000000000000b9662f040de73de8ef26ea04bfcdb6ffbb8087c100000000000000000000000000000000000000000000000017508f1956a8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3306,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000aa164df04a535f6d7db441e5657fb06157132142000000000000000000000000aa164df04a535f6d7db441e5657fb061571321420000000000000000000000000000000000000000000000001774160bc669000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3307,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090ff89c637fd1537e151b8ced1d1d0cb94e31ca600000000000000000000000090ff89c637fd1537e151b8ced1d1d0cb94e31ca6000000000000000000000000000000000000000000000000000ced4c2338705800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3308,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001141c2896cb6b5409181f76b172bea039e85e7030000000000000000000000001141c2896cb6b5409181f76b172bea039e85e70300000000000000000000000000000000000000000000000017979cfe362a000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3309,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000019d3b5a309ca1d80a65db63981b753c292122ab600000000000000000000000019d3b5a309ca1d80a65db63981b753c292122ab600000000000000000000000000000000000000000000000017bb23f0a5eb000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3310,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002b1975dc5ccbcbd9eadb427c3c5e3e16d84585130000000000000000000000002b1975dc5ccbcbd9eadb427c3c5e3e16d845851300000000000000000000000000000000000000000000000017deaae315ac000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3312,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000896efe04e776e61958d955ccf7818813a8854d38000000000000000000000000896efe04e776e61958d955ccf7818813a8854d38000000000000000000000000000000000000000000000000180231d5856d000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3313,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002dcdba685fdb924a4f871f3f898d14a7217db8350000000000000000000000002dcdba685fdb924a4f871f3f898d14a7217db8350000000000000000000000000000000000000000000000001825b8c7f52e000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3314,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf62408b238fd7713c897b976fdabab99acdc978000000000000000000000000bf62408b238fd7713c897b976fdabab99acdc9780000000000000000000000000000000000000000000000000194e6f86a19876b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3316,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000081901a580db0e4cc3f23d7e643486189747d5c7d00000000000000000000000081901a580db0e4cc3f23d7e643486189747d5c7d00000000000000000000000000000000000000000000000018493fba64ef000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026eccf86bc1ebdb8da230611c722e8e39ba0738300000000000000000000000026eccf86bc1ebdb8da230611c722e8e39ba07383000000000000000000000000000000000000000000000000001d1be2de5ffb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3318,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000009c8de489ced4a11e8307cfe405283b0e6c81c6110000000000000000000000009c8de489ced4a11e8307cfe405283b0e6c81c611000000000000000000000000000000000000000000000000186cc6acd4b0000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3320,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000639ebb299c6faa4d1d8e2e6ffed0e8942df2ade9000000000000000000000000639ebb299c6faa4d1d8e2e6ffed0e8942df2ade900000000000000000000000000000000000000000000000018904d9f4471000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3321,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e13cbd05f314c4eeb5882cc6f4e827c6b4269ade000000000000000000000000e13cbd05f314c4eeb5882cc6f4e827c6b4269ade00000000000000000000000000000000000000000000000018b3d491b432000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3322,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004c17d923fd9f18f2399e9589ab80ab62f85b40700000000000000000000000004c17d923fd9f18f2399e9589ab80ab62f85b40700000000000000000000000000000000000000000000000001543e98f74f8b5900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3325,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e103a6e98867f56c35aba038e630700d8a305f1c000000000000000000000000e103a6e98867f56c35aba038e630700d8a305f1c000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3326,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b55348c5b5c44c3912b3e306096f0d69bf85c6e0000000000000000000000001b55348c5b5c44c3912b3e306096f0d69bf85c6e00000000000000000000000000000000000000000000000000a17c436687784400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3327,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9c877f2456fc3eb2e2d398dadc4d5a4b5531896000000000000000000000000f9c877f2456fc3eb2e2d398dadc4d5a4b553189600000000000000000000000000000000000000000000000000621ea9271a850000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eceab9cb452a1912437e43bc96a12a0279803c51000000000000000000000000eceab9cb452a1912437e43bc96a12a0279803c51000000000000000000000000000000000000000000000000005fec5b60ef800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3330,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000200241c7796b3b9dde312d330e847807d087ec4e000000000000000000000000200241c7796b3b9dde312d330e847807d087ec4e00000000000000000000000000000000000000000000000001328743305a80dc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3331,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9c877f2456fc3eb2e2d398dadc4d5a4b5531896000000000000000000000000f9c877f2456fc3eb2e2d398dadc4d5a4b5531896000000000000000000000000000000000000000000000000000073521eb9b70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3332,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cb6eca18d1514300e3f7a49334bcdcc4d7c32730000000000000000000000005cb6eca18d1514300e3f7a49334bcdcc4d7c3273000000000000000000000000000000000000000000000000015e96cdecadba0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3334,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009626de291c92247b1688b829eee73111e1b836a20000000000000000000000009626de291c92247b1688b829eee73111e1b836a200000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8caf3b89edc7aa8ad08654522e6fcfde34252f1c627983783b615769dd5b3669,2021-12-21 10:37:44.000 UTC,0,true +3337,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff4debb853d522d7038197c398385e5dfdbcdd55000000000000000000000000ff4debb853d522d7038197c398385e5dfdbcdd5500000000000000000000000000000000000000000000000002c059c56a59c80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3338,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000090bd35fc5e4375fc1c600e606927bd545696136100000000000000000000000000000000000000000000000098b3c96fdd34784c,,,1,true +3340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f16d8d189b9066ffe94ba9df555c8dcc852b2dcb000000000000000000000000f16d8d189b9066ffe94ba9df555c8dcc852b2dcb000000000000000000000000000000000000000000000000028a17be1b94f10200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3341,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013269e29c6f58bd495fd3c12b94f85b2e22d88f600000000000000000000000013269e29c6f58bd495fd3c12b94f85b2e22d88f6000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3342,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009008d095c9abbeca43e837bc22066be3ba261c4f0000000000000000000000009008d095c9abbeca43e837bc22066be3ba261c4f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3343,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d477f1aabcfc2fc3fc9b802e861c013e0123ad90000000000000000000000004d477f1aabcfc2fc3fc9b802e861c013e0123ad900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3344,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e474e4be5c881f17189fa229b69cee52160384ab000000000000000000000000e474e4be5c881f17189fa229b69cee52160384ab00000000000000000000000000000000000000000000000000b9742ff41970ce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfc7c7d2a8313b72ce2fea977286a0809a8a6dc2000000000000000000000000bfc7c7d2a8313b72ce2fea977286a0809a8a6dc20000000000000000000000000000000000000000000000000152ae9fda35fd0a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3348,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b0f2700b69a59dc6d1a9eb0c0cf86c5530a0d620000000000000000000000003b0f2700b69a59dc6d1a9eb0c0cf86c5530a0d62000000000000000000000000000000000000000000000000007c58508723800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a515be738624462672cc7a4c3e0a3076716d7bee000000000000000000000000a515be738624462672cc7a4c3e0a3076716d7bee00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3350,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008990ed15e254593ce605c7cc4c1b8c836fd615d00000000000000000000000008990ed15e254593ce605c7cc4c1b8c836fd615d000000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d503f029266c7603094dcdca75e8529702a6d700000000000000000000000002d503f029266c7603094dcdca75e8529702a6d70000000000000000000000000000000000000000000000000000d013b1909a80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033cf288a08fac26094289e48b32f9d790642701e00000000000000000000000033cf288a08fac26094289e48b32f9d790642701e000000000000000000000000000000000000000000000000015e833a3eb3280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e3e80d88fd4e3417831b8686db83fc36dbe5fee0000000000000000000000006e3e80d88fd4e3417831b8686db83fc36dbe5fee000000000000000000000000000000000000000000000000015e76ec0bdb240000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3354,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d63d28282eeeace4d4d2c67ebb798f3a2ca782b1000000000000000000000000d63d28282eeeace4d4d2c67ebb798f3a2ca782b1000000000000000000000000000000000000000000000000015e76ec0bdb240000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081077dea57decabfbbeb8648adca22d42d106c8c00000000000000000000000081077dea57decabfbbeb8648adca22d42d106c8c0000000000000000000000000000000000000000000000000081519b6dd3000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3357,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddcc4cf0463838e508014d5f131f38c29171835e000000000000000000000000ddcc4cf0463838e508014d5f131f38c29171835e0000000000000000000000000000000000000000000000000090ffe62823132a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3362,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f76562172ad54453a3e3fab93560cb3aee9750d4000000000000000000000000f76562172ad54453a3e3fab93560cb3aee9750d4000000000000000000000000000000000000000000000000001e32b47897400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059c57d18c14ab828dcfe1fbc212319ed3980448000000000000000000000000059c57d18c14ab828dcfe1fbc212319ed3980448000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000058fce926a96977e4090a021935ec8832e9d1453000000000000000000000000058fce926a96977e4090a021935ec8832e9d1453000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3366,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087a40539b3f0ad7dec878f332ce1ba01f90f815c00000000000000000000000087a40539b3f0ad7dec878f332ce1ba01f90f815c000000000000000000000000000000000000000000000000005fe752f07faa2900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cda2aaaf034bc06efa3c7f0af5ae2a05e4d5cd82000000000000000000000000cda2aaaf034bc06efa3c7f0af5ae2a05e4d5cd8200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000530bdc7b11bd02875fdc9d7a4441478c8ca5ccfd000000000000000000000000530bdc7b11bd02875fdc9d7a4441478c8ca5ccfd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2ddb1f4c1404b9e35ba5c3012119bc0aa4d687e000000000000000000000000b2ddb1f4c1404b9e35ba5c3012119bc0aa4d687e000000000000000000000000000000000000000000000000007ed4f5fa7b400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3371,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f1c7f93771ccbaf028482e843040559b42998430000000000000000000000000f1c7f93771ccbaf028482e843040559b429984300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f8025c35f4ef7e015fbd4becb2d3b9fe7f6683a0000000000000000000000007f8025c35f4ef7e015fbd4becb2d3b9fe7f6683a000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c3c47833c7a277df1e0e5f17deceea1534a75470000000000000000000000009c3c47833c7a277df1e0e5f17deceea1534a75470000000000000000000000000000000000000000000000000036372a332aa84700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3375,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a259ac7276b58b49b9f2dcc8addd19cc31659430000000000000000000000008a259ac7276b58b49b9f2dcc8addd19cc3165943000000000000000000000000000000000000000000000000001d5969dc980f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087a670ea67703d1268d93634eac67cb8549627a600000000000000000000000087a670ea67703d1268d93634eac67cb8549627a6000000000000000000000000000000000000000000000000005987443857000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3378,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043b68fdacc9069a33554ec2964bd21ce5a282d6500000000000000000000000043b68fdacc9069a33554ec2964bd21ce5a282d65000000000000000000000000000000000000000000000000003914c4e7ac523d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3379,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004998b45f0ceebe955ddce8afdab92338945695590000000000000000000000004998b45f0ceebe955ddce8afdab9233894569559000000000000000000000000000000000000000000000000007980b80351800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3381,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d477f1aabcfc2fc3fc9b802e861c013e0123ad90000000000000000000000004d477f1aabcfc2fc3fc9b802e861c013e0123ad900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ed4df7a1795021bc6c6b4767d36dd755f7b5de10000000000000000000000002ed4df7a1795021bc6c6b4767d36dd755f7b5de1000000000000000000000000000000000000000000000000024829b72b2b9acf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3385,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffed310be751fc94780f12884a641a507122cf0e000000000000000000000000ffed310be751fc94780f12884a641a507122cf0e000000000000000000000000000000000000000000000000007d0e36a818000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9dc2911ba911112b4d587a4fc6e9725c565dd45000000000000000000000000f9dc2911ba911112b4d587a4fc6e9725c565dd4500000000000000000000000000000000000000000000000006d82474d9cee7af00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3390,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e3b7571a9cc44eb7a1057ee4a61cc564dd5783e0000000000000000000000002e3b7571a9cc44eb7a1057ee4a61cc564dd5783e0000000000000000000000000000000000000000000000000032fa3ec820da4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027e8769cdc626d0ff052ea52c783176a87fe52ce00000000000000000000000027e8769cdc626d0ff052ea52c783176a87fe52ce00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000def2262aa7c28dea9aeaf43603ac2b6913e19dee000000000000000000000000def2262aa7c28dea9aeaf43603ac2b6913e19dee000000000000000000000000000000000000000000000000007f2fe90af5800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000006d7881358cf903f2c2db94a32d5c6ae9bc611f600000000000000000000000006d7881358cf903f2c2db94a32d5c6ae9bc611f60000000000000000000000000000000000000000000000000000000014cd475200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bfd59fbc137d6d98416679d0d59ed9f0c2438d60000000000000000000000001bfd59fbc137d6d98416679d0d59ed9f0c2438d6000000000000000000000000000000000000000000000000007ef9573445c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3397,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9a1ded45d94ffde63cde4a504bf2d9ca38f53db000000000000000000000000f9a1ded45d94ffde63cde4a504bf2d9ca38f53db000000000000000000000000000000000000000000000000004b12b4a459bd4a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5918d2d19162d2b047f02c89fb27a95e018a409000000000000000000000000b5918d2d19162d2b047f02c89fb27a95e018a409000000000000000000000000000000000000000000000000005a066eacb6303d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060948b99d47b5d6ae1201252ccf5208990bb55a500000000000000000000000060948b99d47b5d6ae1201252ccf5208990bb55a5000000000000000000000000000000000000000000000000007ef9573445c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000620f871707fe81697aa579dce88b49e9c28521aa000000000000000000000000620f871707fe81697aa579dce88b49e9c28521aa000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004365ffda68e2c62bbbf268f14513f94cdca633090000000000000000000000004365ffda68e2c62bbbf268f14513f94cdca63309000000000000000000000000000000000000000000000000002b76b6c924274f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1a021b880c6014292adcc9e034d9590ec85cfaf000000000000000000000000f1a021b880c6014292adcc9e034d9590ec85cfaf0000000000000000000000000000000000000000000000001873eda7cb4225a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a94c1f22649181e825a70e7254e7c5357e908fd6000000000000000000000000a94c1f22649181e825a70e7254e7c5357e908fd600000000000000000000000000000000000000000000000000a93c12ec15560000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007442278f3223f890a450db47fb2f36788457bbb10000000000000000000000007442278f3223f890a450db47fb2f36788457bbb10000000000000000000000000000000000000000000000000dd8951e767c9b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3409,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076911b907a11d18d52a4209265753f4244b9bf3900000000000000000000000076911b907a11d18d52a4209265753f4244b9bf3900000000000000000000000000000000000000000000000000071fc4efab330000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000607b03b3b4b8074142c7aec415e99ebe73a2f21f000000000000000000000000607b03b3b4b8074142c7aec415e99ebe73a2f21f000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3413,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f847e9d51989033b691b8be943f8e9e268f99b9e000000000000000000000000f847e9d51989033b691b8be943f8e9e268f99b9e000000000000000000000000000000000000000000000000003ea82c7f8cbb2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3415,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc72bd8115311209270c453d52a031773372c52f000000000000000000000000dc72bd8115311209270c453d52a031773372c52f000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063bf83c11c50627f44119336a3c2f616b7c6522800000000000000000000000063bf83c11c50627f44119336a3c2f616b7c65228000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000dd2e2c676485fa398cdad7a4e9863edffd32fb70000000000000000000000000dd2e2c676485fa398cdad7a4e9863edffd32fb700000000000000000000000000000000000000000000000000003691d6afc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002497dffc5ed6e49678302c48a29cd930928dc1c80000000000000000000000002497dffc5ed6e49678302c48a29cd930928dc1c8000000000000000000000000000000000000000000000000003838d15b9af90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xce17efe8c27c247493c483522c477c7df6c45ddccd8d1b2efe9bd5c069dad904,2022-04-16 14:03:45.000 UTC,0,true +3422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fefb25be42c402dc5d3e317fd1ba5294e050f5c8000000000000000000000000fefb25be42c402dc5d3e317fd1ba5294e050f5c8000000000000000000000000000000000000000000000000015e4c2d76da800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c01dde207a84c71149cde8b3657c5535c208aa20000000000000000000000000c01dde207a84c71149cde8b3657c5535c208aa200000000000000000000000000000000000000000000000000007313970c7970000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3428,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000f18fc88312cd9b0049668638b84f7d7a48bab650000000000000000000000000f18fc88312cd9b0049668638b84f7d7a48bab65000000000000000000000000000000000000000000000000f922c1c7dc3bfa7800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000363775b4e9dc4ec8e32be7f6a6b64f0f897d36c0000000000000000000000000363775b4e9dc4ec8e32be7f6a6b64f0f897d36c000000000000000000000000000000000000000000000000009b69608ebbbe7300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3e6d6600ce982be43976ec5b8d4cd1a88d5baf4000000000000000000000000a3e6d6600ce982be43976ec5b8d4cd1a88d5baf400000000000000000000000000000000000000000000000000852cb840adf7e600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090f11bcf68f44a7edc142186fced2314da35655d00000000000000000000000090f11bcf68f44a7edc142186fced2314da35655d000000000000000000000000000000000000000000000000004ddac5402fafc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066508ac073baab27706b5f02260e990388a004c800000000000000000000000066508ac073baab27706b5f02260e990388a004c800000000000000000000000000000000000000000000000002b26a53373e1d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3438,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f89fc7c27f885185afa09a38b29daa1bdaf32d4a000000000000000000000000f89fc7c27f885185afa09a38b29daa1bdaf32d4a00000000000000000000000000000000000000000000000014d1120d7b16000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004a42a0eb458b1babdbbb685f7e3e1bb4599fdbf00000000000000000000000004a42a0eb458b1babdbbb685f7e3e1bb4599fdbf000000000000000000000000000000000000000000000000003dbaa514941bcc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3441,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc88b41b71890b64ec34e7af035c1b3b77df467d000000000000000000000000dc88b41b71890b64ec34e7af035c1b3b77df467d000000000000000000000000000000000000000000000000000213d8e824a28000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b0a5aaa86cf5278746e48e09a732b0fc4d3f8590000000000000000000000001b0a5aaa86cf5278746e48e09a732b0fc4d3f859000000000000000000000000000000000000000000000000001daa01bf2cbcd900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031561811d3dd53cfe7850c27dabf9fffe747dca200000000000000000000000031561811d3dd53cfe7850c27dabf9fffe747dca2000000000000000000000000000000000000000000000000002f8e800fc755bc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007eeb48736ca53b10220e8676b832efd4ecd4a90c0000000000000000000000007eeb48736ca53b10220e8676b832efd4ecd4a90c00000000000000000000000000000000000000000000000000341981cfa442a900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000767065ebdd77a964d0cc8eae6998a1821866672c000000000000000000000000767065ebdd77a964d0cc8eae6998a1821866672c000000000000000000000000000000000000000000000000001687e5912bed4e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000893837ee290413f5349f3ce47a665f531df56c72000000000000000000000000893837ee290413f5349f3ce47a665f531df56c7200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3450,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d53b1c352f96986eb065bdb2ef7eaf045c16b756000000000000000000000000d53b1c352f96986eb065bdb2ef7eaf045c16b75600000000000000000000000000000000000000000000000000105df0766168c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dccbfaa8ab8d37757e403b869f43eebfeb96391f000000000000000000000000dccbfaa8ab8d37757e403b869f43eebfeb96391f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3458,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059b02e6738d03f1f501ed74dfb2d9b43fdd9ee4d00000000000000000000000059b02e6738d03f1f501ed74dfb2d9b43fdd9ee4d0000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f997558ae6ab4e5b7df35b6686becf512a50202c000000000000000000000000f997558ae6ab4e5b7df35b6686becf512a50202c00000000000000000000000000000000000000000000000007c585087238000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a23eeff7353c5e6995a6d76957f28e00e3620e20000000000000000000000001a23eeff7353c5e6995a6d76957f28e00e3620e20000000000000000000000000000000000000000000000000015d002442d2f0500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e90737dd2a9ef97ccfbfbdf91756a353d3533a11000000000000000000000000e90737dd2a9ef97ccfbfbdf91756a353d3533a1100000000000000000000000000000000000000000000000000d0720b9aa0063600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000597ddaf79527d46a3d838ed4b06bb37ebba8fc87000000000000000000000000597ddaf79527d46a3d838ed4b06bb37ebba8fc870000000000000000000000000000000000000000000000000853a0d2313c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000533a85eeeabb3e9d7e3ae8d2cc020ab35f19af7f000000000000000000000000533a85eeeabb3e9d7e3ae8d2cc020ab35f19af7f0000000000000000000000000000000000000000000000000037af6899dd9b7300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3478,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e34e61d1ec3de092eac80983fc6480a57dba1cd7000000000000000000000000e34e61d1ec3de092eac80983fc6480a57dba1cd7000000000000000000000000000000000000000000000000013781f240d5721900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xaf2b1bd7538835236b46a645287918976d6834b677dd1c06125a2184964b215f,2022-03-05 02:28:24.000 UTC,0,true +3480,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004cb780fd3286f2d10199b61423d1c804bd2a5d2b0000000000000000000000004cb780fd3286f2d10199b61423d1c804bd2a5d2b00000000000000000000000000000000000000000000001192e7cf4f7885055a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3483,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008166e2bbe05d961287a1097193f9cccf61dd42e40000000000000000000000008166e2bbe05d961287a1097193f9cccf61dd42e4000000000000000000000000000000000000000000000000002e269a6f3ecc1300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3484,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a252234c2359ad3c1908dd564ae8da74b4910250000000000000000000000005a252234c2359ad3c1908dd564ae8da74b4910250000000000000000000000000000000000000000000000000060c372c91c830000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb16dacfbb40bc630298bcd8f3e0bc3d7e1a3631000000000000000000000000bb16dacfbb40bc630298bcd8f3e0bc3d7e1a3631000000000000000000000000000000000000000000000000008ac534ce73625600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3488,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3708b99c1c3cbb4a27e5b8caace1f5a1d9362ac000000000000000000000000a3708b99c1c3cbb4a27e5b8caace1f5a1d9362ac00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c88533351059765f165a3b51f1a5d2b8dfec3c08000000000000000000000000c88533351059765f165a3b51f1a5d2b8dfec3c08000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092c06cc32b45ae9a335be36305e619191ed666fe00000000000000000000000092c06cc32b45ae9a335be36305e619191ed666fe000000000000000000000000000000000000000000000000013e55d22080dcbf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bff9b3ede66c6daf42d6deae4c784c520ce5ac10000000000000000000000004bff9b3ede66c6daf42d6deae4c784c520ce5ac10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3493,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7ca8db84717c98dcf59be2b3a612e75ef5d54b0000000000000000000000000b7ca8db84717c98dcf59be2b3a612e75ef5d54b00000000000000000000000000000000000000000000000000008f0f3d1d6fff400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000300c8115f3bbcba6b11ea660bb6b8ad9b50e5095000000000000000000000000300c8115f3bbcba6b11ea660bb6b8ad9b50e5095000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2b0ada1b72646964b3303c3612f3bfc85139dc8000000000000000000000000c2b0ada1b72646964b3303c3612f3bfc85139dc8000000000000000000000000000000000000000000000000001d0b1b24adc70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3497,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29fedb24a18af65ac769a1c3432882b73e5a3a2000000000000000000000000c29fedb24a18af65ac769a1c3432882b73e5a3a200000000000000000000000000000000000000000000000000000002540be40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022b7d824428d53100c8f841c383d77aa7489a5f400000000000000000000000022b7d824428d53100c8f841c383d77aa7489a5f400000000000000000000000000000000000000000000000001509018d26db98900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e69619a71cdd7696b34c52a5c1709c8a811faab8000000000000000000000000e69619a71cdd7696b34c52a5c1709c8a811faab8000000000000000000000000000000000000000000000000012e017786c1794200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f6e754e84fc4bb7c4ecf296964ad29e5130d8c60000000000000000000000006f6e754e84fc4bb7c4ecf296964ad29e5130d8c6000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3502,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8983d041f4e752032f2964b8e095c1f1c61956b000000000000000000000000b8983d041f4e752032f2964b8e095c1f1c61956b000000000000000000000000000000000000000000000000003890d2358b1a4f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3503,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb8b8a7894a85dce08a79789cd794abfa0109614000000000000000000000000bb8b8a7894a85dce08a79789cd794abfa010961400000000000000000000000000000000000000000000000000ac86ff86e2680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dfc387d937488a300bb73ed805b1e46cdfcf28ae000000000000000000000000dfc387d937488a300bb73ed805b1e46cdfcf28ae00000000000000000000000000000000000000000000000000acb9e5e4d44a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3507,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059d369c01da6e051409489ed9878bb21037095a900000000000000000000000059d369c01da6e051409489ed9878bb21037095a90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f40324ed97badd9079e67e162c83b1fb9168a120000000000000000000000005f40324ed97badd9079e67e162c83b1fb9168a1200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3511,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cca8329feb40eae13b6bbe26ca2dfc8406b64236000000000000000000000000cca8329feb40eae13b6bbe26ca2dfc8406b64236000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3512,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000842fcd1d99c0c3469022a51685dada5afa91a4e2000000000000000000000000842fcd1d99c0c3469022a51685dada5afa91a4e2000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3514,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da0285ff49800536a53cbef7a7188da10a656efe000000000000000000000000da0285ff49800536a53cbef7a7188da10a656efe000000000000000000000000000000000000000000000000015bd2ae504d8e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000445c9da83c4211fa8829672785599dd8180ade7c000000000000000000000000445c9da83c4211fa8829672785599dd8180ade7c000000000000000000000000000000000000000000000000009e1d9bbdca638300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050f7c1a1db6ac509d4a9e684617a191f3b400c0400000000000000000000000050f7c1a1db6ac509d4a9e684617a191f3b400c040000000000000000000000000000000000000000000000000038f83f9bcedbff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079748bfc42a567c58682add44a072f8900a8499800000000000000000000000079748bfc42a567c58682add44a072f8900a84998000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3520,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea7914b48d8ebd203a7721ccaf083b1c3e78586c000000000000000000000000ea7914b48d8ebd203a7721ccaf083b1c3e78586c000000000000000000000000000000000000000000000000000ec458d7e1930000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3522,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046ad16c95afd5946b6810d03d7dff72b75f58f7500000000000000000000000046ad16c95afd5946b6810d03d7dff72b75f58f75000000000000000000000000000000000000000000000000005262f360ddd70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bca75d1512939dd30f91416c02f1454175a0fb00000000000000000000000005bca75d1512939dd30f91416c02f1454175a0fb0000000000000000000000000000000000000000000000000009c1a4e702a255600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c675e0363add2cd4e61abde87a952d5c07492f40000000000000000000000005c675e0363add2cd4e61abde87a952d5c07492f400000000000000000000000000000000000000000000000000017f9dc2d4590000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000393a4fc32b1311c4fa5774d61fa99230670c604b000000000000000000000000393a4fc32b1311c4fa5774d61fa99230670c604b0000000000000000000000000000000000000000000000000076d637f281de0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a11749a0b6b2cc397dc2fcb11b1c6c1478cd4290000000000000000000000003a11749a0b6b2cc397dc2fcb11b1c6c1478cd429000000000000000000000000000000000000000000000000009fc8448c3cc06800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3534,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c162389a94467e4827401afed99b4401c46ade90000000000000000000000000c162389a94467e4827401afed99b4401c46ade900000000000000000000000000000000000000000000000000a02ba903725edb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012afc0c2c09166892cfc167d35e5907c0b2ccb2d00000000000000000000000012afc0c2c09166892cfc167d35e5907c0b2ccb2d00000000000000000000000000000000000000000000000000e66e97a099c54000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a707a440e0a34f11c3c259a20622440cbed19700000000000000000000000005a707a440e0a34f11c3c259a20622440cbed1970000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2555ce66cd0bf76150036d44c313632137622b33f595155bbf80cd4a2b7e88be,2021-12-24 23:28:46.000 UTC,0,true +3538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004579685d695f917e74165177294cfc6924ef8ca10000000000000000000000004579685d695f917e74165177294cfc6924ef8ca1000000000000000000000000000000000000000000000000009df226d114f8ef00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcc9ff4a52a0e972b20f3dd63e88396685a57636000000000000000000000000bcc9ff4a52a0e972b20f3dd63e88396685a57636000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092cae64f9937bc218c8e1737625717f379f9720000000000000000000000000092cae64f9937bc218c8e1737625717f379f9720000000000000000000000000000000000000000000000000000ae787df528efc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a45481a6446a33e283c992ae11feaf9237ff421b000000000000000000000000a45481a6446a33e283c992ae11feaf9237ff421b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcc9ff4a52a0e972b20f3dd63e88396685a57636000000000000000000000000bcc9ff4a52a0e972b20f3dd63e88396685a576360000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3545,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000531c64cc8796d85e79f96a4507652f67a75bbc020000000000000000000000000000000000000000000000002891e41d1d38844c,,,1,true +3547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000863e308c6153eee5fcafcc2728b330e9f86c51b9000000000000000000000000863e308c6153eee5fcafcc2728b330e9f86c51b900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3548,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036fcd9f92d79b45bdcef267e834e276f45f0d27d00000000000000000000000036fcd9f92d79b45bdcef267e834e276f45f0d27d00000000000000000000000000000000000000000000000000fffdf87d4d541e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017187a7d2a7106f7c9d3fe8db1461ece5a70351d00000000000000000000000017187a7d2a7106f7c9d3fe8db1461ece5a70351d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3550,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000264313b93e8073db685a3d24a4d6c7778fd5e964000000000000000000000000264313b93e8073db685a3d24a4d6c7778fd5e96400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000358abb5b95f814c833746a2d0e98bbc227cb6e3c000000000000000000000000358abb5b95f814c833746a2d0e98bbc227cb6e3c000000000000000000000000000000000000000000000000000cca2e5131000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcc9ff4a52a0e972b20f3dd63e88396685a57636000000000000000000000000bcc9ff4a52a0e972b20f3dd63e88396685a576360000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df5ebfaece255f16e8ddb8d51f0d4c7a422a9686000000000000000000000000df5ebfaece255f16e8ddb8d51f0d4c7a422a968600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095a98188d689715f7a194448fc8c2068adbfe6ee00000000000000000000000095a98188d689715f7a194448fc8c2068adbfe6ee00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004f205715aa91275dabc59cf5be7c79eb2a2bd5e00000000000000000000000004f205715aa91275dabc59cf5be7c79eb2a2bd5e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037e49f50da9eec60c16c7632d71de572687da1fb00000000000000000000000037e49f50da9eec60c16c7632d71de572687da1fb00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000555860b9cc8a1d1e9e48538c8c6d8b85300a77c5000000000000000000000000555860b9cc8a1d1e9e48538c8c6d8b85300a77c50000000000000000000000000000000000000000000000000000000001f74d0e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abef0e8cd40ff9ee1023d71357aec1f1ad3acf47000000000000000000000000abef0e8cd40ff9ee1023d71357aec1f1ad3acf4700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000748f61c456fb1317572cfb550dfd0089f2834030000000000000000000000000748f61c456fb1317572cfb550dfd0089f283403000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3562,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b954a49833515c62fcfcddbb0a1f69f9d9923d50000000000000000000000006b954a49833515c62fcfcddbb0a1f69f9d9923d500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c70cd990e0e595fd3df8c8c05aa52cd1cc9d76f6000000000000000000000000c70cd990e0e595fd3df8c8c05aa52cd1cc9d76f600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3565,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c07a4c89d5b82fc5263bac78385fac2ee403aef0000000000000000000000006c07a4c89d5b82fc5263bac78385fac2ee403aef00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2a929a25ad4c77e071376968d4ceb94fee26312000000000000000000000000b2a929a25ad4c77e071376968d4ceb94fee2631200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3568,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c441f84108848fc7f8b8fcb7b27784acc5bece50000000000000000000000001c441f84108848fc7f8b8fcb7b27784acc5bece500000000000000000000000000000000000000000000000001562e03c79f4d1800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3569,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7e757bb7e887b99f14de1f88bfbb42d7df1c65c000000000000000000000000a7e757bb7e887b99f14de1f88bfbb42d7df1c65c00000000000000000000000000000000000000000000000000034ebd179c246500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3570,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076b5eac3af4a09949b99b2fc573e345ec640faa200000000000000000000000076b5eac3af4a09949b99b2fc573e345ec640faa2000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b484c02002f3360cfa3439e260055c41c6df654e000000000000000000000000b484c02002f3360cfa3439e260055c41c6df654e00000000000000000000000000000000000000000000000000a2c1360ac459e500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3575,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000435c52bb29e3a8380ba9045db70910205a4e6eab0000000000000000000000000000000000000000000000000de0b6b3a7640000,,,1,true +3576,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd662e3684770880686264a4bb6632b53244cd9a000000000000000000000000bd662e3684770880686264a4bb6632b53244cd9a000000000000000000000000000000000000000000000000007f4ee741a258e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3581,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd662e3684770880686264a4bb6632b53244cd9a000000000000000000000000bd662e3684770880686264a4bb6632b53244cd9a000000000000000000000000000000000000000000000000003c79b7d3add40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3582,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf70f1d525a3802df885dd4b35176730608729b4000000000000000000000000cf70f1d525a3802df885dd4b35176730608729b4000000000000000000000000000000000000000000000000015e917d9c8aa10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3583,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000281f9fd6d8dfa9a73539c98030d5071c04ab62c1000000000000000000000000281f9fd6d8dfa9a73539c98030d5071c04ab62c100000000000000000000000000000000000000000000000000aca9714815800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000add76744e587bd74ab9c23813f883daa4a92a945000000000000000000000000add76744e587bd74ab9c23813f883daa4a92a94500000000000000000000000000000000000000000000000000a34aab7463239e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3588,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014c963f01f369c96ffbadbd5209f016759f9209300000000000000000000000014c963f01f369c96ffbadbd5209f016759f92093000000000000000000000000000000000000000000000000015c62b0a167aa4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3589,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef665af21a52fe3c9f0c4afe0ebe825975d687cb000000000000000000000000ef665af21a52fe3c9f0c4afe0ebe825975d687cb000000000000000000000000000000000000000000000000014462ff5dac2d8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3592,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae2f175948821430330b2aaed19cea2b60570740000000000000000000000000ae2f175948821430330b2aaed19cea2b60570740000000000000000000000000000000000000000000000000005a322c4cb67adf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3597,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d23e5a77ac2adbddaa1569389581732f2ea09e61000000000000000000000000d23e5a77ac2adbddaa1569389581732f2ea09e6100000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb938cfa703d14262efc7b88b91aca6974b9650d19e9277a1fb6615d35d4d498c,2022-07-10 08:15:37.000 UTC,0,true +3600,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8faa54d01fb06ac8c55d7ac95f5e1cfe7f2a467000000000000000000000000b8faa54d01fb06ac8c55d7ac95f5e1cfe7f2a46700000000000000000000000000000000000000000000000000a6a2d1836f305f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3601,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acdceb490c614fa827c4f20710ee38e6b27d0eb2000000000000000000000000acdceb490c614fa827c4f20710ee38e6b27d0eb200000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3602,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000656e4f4777f0ada62dfc8d2e6e4b860cc2dea7db000000000000000000000000656e4f4777f0ada62dfc8d2e6e4b860cc2dea7db0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3606,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000edac8917d97c61f4160ab0483637823d70083017000000000000000000000000edac8917d97c61f4160ab0483637823d70083017000000000000000000000000000000000000000000000000009e68cd212edbed00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bbca1093f731fb2e4a3625deb1967e6fc9127ffe000000000000000000000000bbca1093f731fb2e4a3625deb1967e6fc9127ffe000000000000000000000000000000000000000000000000004311a84fe1f40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3613,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069a25973f320c8bd0caa634c76f4464a3d2c5d7d00000000000000000000000069a25973f320c8bd0caa634c76f4464a3d2c5d7d00000000000000000000000000000000000000000000000000a407ab19d10adc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003114a7881e41d38f4ca1de432bbe279b2d532db20000000000000000000000003114a7881e41d38f4ca1de432bbe279b2d532db2000000000000000000000000000000000000000000000000004df870439c0d6500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3619,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f02feaa50363d3f42fb122e5d7676fff2b24e2af000000000000000000000000f02feaa50363d3f42fb122e5d7676fff2b24e2af0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000762cfde23d0882729f43eabfe28a50c43a18d2f4000000000000000000000000762cfde23d0882729f43eabfe28a50c43a18d2f40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3624,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000188aaf665b2e0a2f7b6b4dbc1d5004657d104132000000000000000000000000188aaf665b2e0a2f7b6b4dbc1d5004657d104132000000000000000000000000000000000000000000000000000482af5157b7ce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0a6ab30167c35e9e8c4a3f8df7ce7e38c76831c000000000000000000000000f0a6ab30167c35e9e8c4a3f8df7ce7e38c76831c000000000000000000000000000000000000000000000000002e8312683c84e100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000086ae1358fc00fcbc32d48ae831bf90558550181000000000000000000000000086ae1358fc00fcbc32d48ae831bf905585501810000000000000000000000000000000000000000000000000003d6037c20ce5900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6b0fa6750e6e65867431e53e180dd87e365f46e000000000000000000000000e6b0fa6750e6e65867431e53e180dd87e365f46e000000000000000000000000000000000000000000000000010096d7f1fa7e5d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3630,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055d7af293204dda491de0509b44e5d47ae4a3b3300000000000000000000000055d7af293204dda491de0509b44e5d47ae4a3b3300000000000000000000000000000000000000000000000000071924a16ad40f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000711fb130ce68576bf819683598efe46bf5e149fb000000000000000000000000711fb130ce68576bf819683598efe46bf5e149fb0000000000000000000000000000000000000000000000000425d26b34dcb49200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d182f2ff6aa0293a7be976de0018909c9ab1568b000000000000000000000000d182f2ff6aa0293a7be976de0018909c9ab1568b00000000000000000000000000000000000000000000000000004ec14d6625ae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002add3cb18e5a40cf0472eb9aef8248dc99b2ade80000000000000000000000002add3cb18e5a40cf0472eb9aef8248dc99b2ade800000000000000000000000000000000000000000000000000015361c836211a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7dac61d49a6ca90b5ef1b6c84f40c1cc8d8c469000000000000000000000000a7dac61d49a6ca90b5ef1b6c84f40c1cc8d8c4690000000000000000000000000000000000000000000000000e92596fd629000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1bd1d7f4794ded7133ebc607aa9f98182397359000000000000000000000000f1bd1d7f4794ded7133ebc607aa9f98182397359000000000000000000000000000000000000000000000000039bb49f599a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3637,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000770e071e6a2fd30c5ac8ee3c5355760b30744435000000000000000000000000770e071e6a2fd30c5ac8ee3c5355760b30744435000000000000000000000000000000000000000000000000008a2f387187cb9a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002bbb1ac9a6f2cd51a066dded1d0554db7fd51b2f0000000000000000000000002bbb1ac9a6f2cd51a066dded1d0554db7fd51b2f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3639,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062b485d3ac74b876582dcb1c3c65c92b92f32c8300000000000000000000000062b485d3ac74b876582dcb1c3c65c92b92f32c83000000000000000000000000000000000000000000000000009600607c3807fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3640,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009fb7563a1969f034e8feb83e499c967d31538e860000000000000000000000009fb7563a1969f034e8feb83e499c967d31538e860000000000000000000000000000000000000000000000000007e3c47664c0b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bdf630a97936201955b25b279fbe016fe2f04490000000000000000000000005bdf630a97936201955b25b279fbe016fe2f0449000000000000000000000000000000000000000000000000000138232bc379db00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011e9df05c3a5adc42c7bfae4f0360b4e2423f29b00000000000000000000000011e9df05c3a5adc42c7bfae4f0360b4e2423f29b0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000deaef36fa8a391fa09a4b5f8ba67a655435cf07e000000000000000000000000deaef36fa8a391fa09a4b5f8ba67a655435cf07e00000000000000000000000000000000000000000000000000006af3e97ed2c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3644,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062ff2b32c2c1fb42d95cd2b5439c840cfeb1652a00000000000000000000000062ff2b32c2c1fb42d95cd2b5439c840cfeb1652a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3646,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5dcaf4f9edd062d1c8589cf9611253afb982a40000000000000000000000000c5dcaf4f9edd062d1c8589cf9611253afb982a400000000000000000000000000000000000000000000000000101fca146ffb61600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3648,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a16ba1c0084ffdf78849c25d933f2ca49c873f97000000000000000000000000a16ba1c0084ffdf78849c25d933f2ca49c873f9700000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3650,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002036d5417e963825de1299d88cf8a7b5d61b5c8b0000000000000000000000002036d5417e963825de1299d88cf8a7b5d61b5c8b0000000000000000000000000000000000000000000000000083be228e54b68000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000101f4c1944e1f15d3dec809cec589921ed56d006000000000000000000000000101f4c1944e1f15d3dec809cec589921ed56d0060000000000000000000000000000000000000000000000000125754782fc284700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009fada4ec572fdb820a00a5607099f4a5049b89a50000000000000000000000009fada4ec572fdb820a00a5607099f4a5049b89a5000000000000000000000000000000000000000000000000001291046558b1c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3657,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009fada4ec572fdb820a00a5607099f4a5049b89a50000000000000000000000009fada4ec572fdb820a00a5607099f4a5049b89a500000000000000000000000000000000000000000000000000456498511c740f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec4b0aada8d46640b7296df77132e299c40cc2f7000000000000000000000000ec4b0aada8d46640b7296df77132e299c40cc2f70000000000000000000000000000000000000000000000000055ea748820b50400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007834c9a4b652f096a84c364b1c44828bb750924b0000000000000000000000007834c9a4b652f096a84c364b1c44828bb750924b00000000000000000000000000000000000000000000000001cdda4faccd000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3660,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ca64e575083e0a8f9c73ffc214d78027d98fc51b000000000000000000000000ca64e575083e0a8f9c73ffc214d78027d98fc51b0000000000000000000000000000000000000000000000000000000007df1b8e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3661,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000234cf11ffb859f228bef972bac3116375f45c2eb000000000000000000000000234cf11ffb859f228bef972bac3116375f45c2eb000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3662,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd728faf4c65cc9af041a5376791c4699f49f0d2000000000000000000000000fd728faf4c65cc9af041a5376791c4699f49f0d200000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3663,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006caba1b5bf7ffd11e061e652e8040527c1b6dd130000000000000000000000006caba1b5bf7ffd11e061e652e8040527c1b6dd1300000000000000000000000000000000000000000000000000a93485d885250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x96f1dd5e23b91fa9cbbd60ce9fcf5656f1e8b2ba93fb1c817c481417ea78d5fc,2022-05-01 14:05:11.000 UTC,0,true +3664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076ae8013e0271a2bf0b8d434433c9672cdac06e400000000000000000000000076ae8013e0271a2bf0b8d434433c9672cdac06e4000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3666,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a717310f71b2e7809c8941d14e95ef6fba990c16000000000000000000000000a717310f71b2e7809c8941d14e95ef6fba990c16000000000000000000000000000000000000000000000000001c0c9b4ef45d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3667,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c4f717e9fd9c01b68cf68f3e984c3603aecfa1e0000000000000000000000002c4f717e9fd9c01b68cf68f3e984c3603aecfa1e00000000000000000000000000000000000000000000000002adaf74d2984a4100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003074601bb1f3f0fea734c26d684ba9fd2c2871fa0000000000000000000000003074601bb1f3f0fea734c26d684ba9fd2c2871fa00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3669,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003beca87dd176c613db59af20619dd9e0a99c66060000000000000000000000003beca87dd176c613db59af20619dd9e0a99c660600000000000000000000000000000000000000000000000000203092fd43c6e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3670,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005c69e40ed489b88fd694ad7e31776e469859afd00000000000000000000000005c69e40ed489b88fd694ad7e31776e469859afd000000000000000000000000000000000000000000000000007c58508723800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0025d1da6ffd6c3005f710cfd1ef8d9386b8008b39a0008b579625b68855f701,2022-06-20 04:37:06.000 UTC,0,true +3671,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b73a132677af8a3ff0e3e940dde2c89148fa0fe1000000000000000000000000b73a132677af8a3ff0e3e940dde2c89148fa0fe100000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa95ccaff6b6cb4cf3ec479cab22c60d53d508ec000000000000000000000000aa95ccaff6b6cb4cf3ec479cab22c60d53d508ec00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3673,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d36511ef12161df48da2d618e73586f910ecf380000000000000000000000008d36511ef12161df48da2d618e73586f910ecf3800000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3675,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027688f913d6d40f39ae1dfde8a1a82e1496e927800000000000000000000000027688f913d6d40f39ae1dfde8a1a82e1496e927800000000000000000000000000000000000000000000000000b6f92e9456149300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3676,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002aaf8308ecabf4b13475437ae1a311076cbb5a0c0000000000000000000000002aaf8308ecabf4b13475437ae1a311076cbb5a0c00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3677,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d730517b1a6066a5746d7f2dcce47b0713e2ae50000000000000000000000000d730517b1a6066a5746d7f2dcce47b0713e2ae50000000000000000000000000000000000000000000000000003b0dacedbc380000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3678,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b83e28f3fdd1d2fa98e4aeb7a5f063d91261d36b000000000000000000000000b83e28f3fdd1d2fa98e4aeb7a5f063d91261d36b00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023a3b309b616b8d25a6a6c1bf9d95969ad010f8900000000000000000000000023a3b309b616b8d25a6a6c1bf9d95969ad010f890000000000000000000000000000000000000000000000000147f2872ece120700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3680,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d291a341157f6566c3520e5f920089c243a1b9bb000000000000000000000000d291a341157f6566c3520e5f920089c243a1b9bb00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc8d40e13f2738844355aa381dd790f83ae0804f000000000000000000000000cc8d40e13f2738844355aa381dd790f83ae0804f00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3682,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0615906491bad3ecfb38194f32818ffe0590593000000000000000000000000f0615906491bad3ecfb38194f32818ffe05905930000000000000000000000000000000000000000000000000108ad322cac485200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d52251d6f7c7348b3d4d76b22a666f5ce2ee4641000000000000000000000000d52251d6f7c7348b3d4d76b22a666f5ce2ee464100000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f435f8278c740b9d866d87e6b1903d33329398cf000000000000000000000000f435f8278c740b9d866d87e6b1903d33329398cf000000000000000000000000000000000000000000000000000b0c11950e2d3500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3686,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017d0a01c3a3b138363501450e6f2b4c0f1a89acb00000000000000000000000017d0a01c3a3b138363501450e6f2b4c0f1a89acb000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3690,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023c00c3e224fb25f07d7cf445d802c442fe7af5000000000000000000000000023c00c3e224fb25f07d7cf445d802c442fe7af5000000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3691,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000039af6952f2fbe751a10f28a63f9f57d65f64e3fa00000000000000000000000039af6952f2fbe751a10f28a63f9f57d65f64e3fa0000000000000000000000000000000000000000000000000000000002faf08000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3692,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa6c38979931cf3aa631ddcb0cfb664a4674c5fc000000000000000000000000fa6c38979931cf3aa631ddcb0cfb664a4674c5fc00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3693,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e8d3b936f8ffef0d816c489f74ad79cd1c7824e0000000000000000000000009e8d3b936f8ffef0d816c489f74ad79cd1c7824e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007636fcbffc81d543c8a439022902b834073dea3e0000000000000000000000007636fcbffc81d543c8a439022902b834073dea3e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3695,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097b1b4fe3b85ae6cc85323bb91c62ac9f56aa9ad00000000000000000000000097b1b4fe3b85ae6cc85323bb91c62ac9f56aa9ad00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3696,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c544cf87f37d5862bef3c0a89ac6aa94f8d74e7c000000000000000000000000c544cf87f37d5862bef3c0a89ac6aa94f8d74e7c000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ba7a0136cc8e056e8641c8bb006113c8e0caf640000000000000000000000008ba7a0136cc8e056e8641c8bb006113c8e0caf640000000000000000000000000000000000000000000000000054d5fcf923250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008346867972983eca1b7ceb5d3a60bb18f23a96010000000000000000000000008346867972983eca1b7ceb5d3a60bb18f23a960100000000000000000000000000000000000000000000000000932892ecc8224800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x146a7f6bacd30db43ed1a0a6052f91063cce9d1d1e6080563dcbf9ac3bb5ff77,2022-03-04 12:04:17.000 UTC,0,true +3699,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b08b9f29edfd8feed9a6f1c23db3d7ffe9bc89f9000000000000000000000000b08b9f29edfd8feed9a6f1c23db3d7ffe9bc89f900000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3700,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073ce4c69c1e4b26b324f62da4a2439bae8957d3800000000000000000000000073ce4c69c1e4b26b324f62da4a2439bae8957d380000000000000000000000000000000000000000000000000060076ad2445b2e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3701,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000073b1245ec728ae5fc4ffe3287873c89aa057334000000000000000000000000073b1245ec728ae5fc4ffe3287873c89aa05733400000000000000000000000000000000000000000000000001933eb75c39efb200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cf1e827a248123f68de5879687ae9e928e5ff7f0000000000000000000000007cf1e827a248123f68de5879687ae9e928e5ff7f00000000000000000000000000000000000000000000000000ce54e7fb424d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb5e5e296186ad319c7cd221e47febbfebb2555f000000000000000000000000fb5e5e296186ad319c7cd221e47febbfebb2555f000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f986a3e141dc29b77160fd313faa9c7a3cc983a0000000000000000000000006f986a3e141dc29b77160fd313faa9c7a3cc983a0000000000000000000000000000000000000000000000000150cc1904b5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cdf67d66a4958ea1364db82437afaffa6f3295d0000000000000000000000004cdf67d66a4958ea1364db82437afaffa6f3295d000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3709,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6999a8508d9f36c5ee6ad0152b393e145481aa5000000000000000000000000e6999a8508d9f36c5ee6ad0152b393e145481aa5000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3710,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd27ef02c889230ee98465e570fd4a3a2724abd5000000000000000000000000dd27ef02c889230ee98465e570fd4a3a2724abd50000000000000000000000000000000000000000000000000032e12ac200d3a700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3711,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f275599564fd00281c450ee6c50f03214fce8960000000000000000000000007f275599564fd00281c450ee6c50f03214fce896000000000000000000000000000000000000000000000000015af694b741750000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3712,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b4aa4ad0fa6cb4079ead2b0fb2239ae01f464b60000000000000000000000001b4aa4ad0fa6cb4079ead2b0fb2239ae01f464b60000000000000000000000000000000000000000000000000009dd75da31ba0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b25c1a12ace49fe05979041b763b4982e8bdd3e0000000000000000000000005b25c1a12ace49fe05979041b763b4982e8bdd3e00000000000000000000000000000000000000000000000000c8c2ea4839940000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c06efe1b692083d3d823687ffdc3b0e4332d12b0000000000000000000000001c06efe1b692083d3d823687ffdc3b0e4332d12b000000000000000000000000000000000000000000000000033d0e4796df2bd500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x56eb5ddb861a5caad51b6d2083933a95e6b9b73a83580a34a957794e8e6af758,2022-04-21 01:58:31.000 UTC,0,true +3716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1302555eae657335fb9829cc5afdbe878239cf4000000000000000000000000a1302555eae657335fb9829cc5afdbe878239cf400000000000000000000000000000000000000000000000000a8835de65528b200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3722,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000c24679ce898676e0cbecc1e5c216c5619feaa255000000000000000000000000c24679ce898676e0cbecc1e5c216c5619feaa25500000000000000000000000000000000000000000000000000000000254f578b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3726,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7e4ca65590e5d0630f5fde7ca5a0bb880522391000000000000000000000000c7e4ca65590e5d0630f5fde7ca5a0bb8805223910000000000000000000000000000000000000000000000000038abb391a804c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004283e38da7815ab32ded99cd7008fb134b5f3f4b0000000000000000000000004283e38da7815ab32ded99cd7008fb134b5f3f4b000000000000000000000000000000000000000000000000009ad3631d922d7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3730,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041f3e6e3c08ef0800d4e563265f55317932c734200000000000000000000000041f3e6e3c08ef0800d4e563265f55317932c73420000000000000000000000000000000000000000000000000016eabcc00d5ea000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3731,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f275599564fd00281c450ee6c50f03214fce8960000000000000000000000007f275599564fd00281c450ee6c50f03214fce896000000000000000000000000000000000000000000000000036f7e03bc6e180000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3732,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f9175f2cbdf68c1f983db87c41e6d2b7be126c50000000000000000000000000f9175f2cbdf68c1f983db87c41e6d2b7be126c5000000000000000000000000000000000000000000000000001535985d90de0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3734,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000108efaaefa1f2b96928bdb5c78b935458feb8dd5000000000000000000000000108efaaefa1f2b96928bdb5c78b935458feb8dd5000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3736,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009aa405d5ffd65bd6ebbde196170c34bf8e9ae94e0000000000000000000000009aa405d5ffd65bd6ebbde196170c34bf8e9ae94e00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5cfe9f9ff617a274960dc84f82c03e5098b2d53000000000000000000000000e5cfe9f9ff617a274960dc84f82c03e5098b2d53000000000000000000000000000000000000000000000000001a904188826d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071c77a0e30b4c2f3ca4cf2cfbaee0e039b2e7b5900000000000000000000000071c77a0e30b4c2f3ca4cf2cfbaee0e039b2e7b59000000000000000000000000000000000000000000000000025bf6196bd1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b843d5ddf91de2dec8e77dc133aba21a7d013dac000000000000000000000000b843d5ddf91de2dec8e77dc133aba21a7d013dac00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3741,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000bf1751f32bd0cbd8b44d9d3064aadf9df3757349000000000000000000000000bf1751f32bd0cbd8b44d9d3064aadf9df37573490000000000000000000000000000000000000000000000000000000007e8939f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf49bf6e2e975325bbea284d615f0cb3d928a20f000000000000000000000000cf49bf6e2e975325bbea284d615f0cb3d928a20f000000000000000000000000000000000000000000000000001a39d68c2cae0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000078275af1a67c7bb4c88c23601db4066499387c7f00000000000000000000000078275af1a67c7bb4c88c23601db4066499387c7f000000000000000000000000000000000000000000000000000000001b5bc8c000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3746,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022838365403af97f06a287c97441a2f37b70165a00000000000000000000000022838365403af97f06a287c97441a2f37b70165a000000000000000000000000000000000000000000000000001b87344aaba60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e9aab52fbc67240ed8e0df4ac47f9bd8e502b790000000000000000000000009e9aab52fbc67240ed8e0df4ac47f9bd8e502b7900000000000000000000000000000000000000000000000000b3883cecdbec9b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3748,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0667fef209ff1469c334d4de9ee6c78a372b3c2000000000000000000000000c0667fef209ff1469c334d4de9ee6c78a372b3c2000000000000000000000000000000000000000000000000003fff819405230000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3749,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d504f282cd20bff9f0e2b7d006771e3a81f6bdbd000000000000000000000000d504f282cd20bff9f0e2b7d006771e3a81f6bdbd000000000000000000000000000000000000000000000000011c4e0db4e21ba200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3750,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000369378f65bea146234fd290fc1ac59d0ecf921ed000000000000000000000000369378f65bea146234fd290fc1ac59d0ecf921ed00000000000000000000000000000000000000000000000000872dcf7b1423d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3751,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3d2e2a1de238241ae90e098d06e101e2a428d80000000000000000000000000d3d2e2a1de238241ae90e098d06e101e2a428d80000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3a38bb08446a114ba0081aaf55b496f18d9bdcd000000000000000000000000e3a38bb08446a114ba0081aaf55b496f18d9bdcd000000000000000000000000000000000000000000000000000124c7d16723c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3753,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009dd092ead78363e9a86889d70727d1d9037f39f80000000000000000000000009dd092ead78363e9a86889d70727d1d9037f39f8000000000000000000000000000000000000000000000000004559e1a8aed42e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3754,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002c95fef9de755f18144615ea3e93fd23e677f9b00000000000000000000000002c95fef9de755f18144615ea3e93fd23e677f9b000000000000000000000000000000000000000000000000001cee9468fed50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3755,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e0f589d68f839c5b9e92598370e4728a193edfb0000000000000000000000003e0f589d68f839c5b9e92598370e4728a193edfb00000000000000000000000000000000000000000000000000404b938882530000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3756,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b079b3333e2fba074438c42b2c75be2c60a453fe000000000000000000000000b079b3333e2fba074438c42b2c75be2c60a453fe000000000000000000000000000000000000000000000000003ff2e795f5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077d9418d284f2bfd8bfac5428bbf2d7e3372c27e00000000000000000000000077d9418d284f2bfd8bfac5428bbf2d7e3372c27e00000000000000000000000000000000000000000000000000c5f9b15062393d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3759,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d88d5b3dbe8790369799012310c31eb210eeec81000000000000000000000000d88d5b3dbe8790369799012310c31eb210eeec810000000000000000000000000000000000000000000000000af4a5368de1b44000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3761,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd841182e5c586f917015bfb2665bc335267f753000000000000000000000000dd841182e5c586f917015bfb2665bc335267f75300000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3763,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000423f024de8137ecb8396f7f5e657f441f2879dab000000000000000000000000423f024de8137ecb8396f7f5e657f441f2879dab0000000000000000000000000000000000000000000000000031bced02db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3764,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cb0032536cef0e50d670dd72b03eaa004d578400000000000000000000000004cb0032536cef0e50d670dd72b03eaa004d57840000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x86eced8d9a730eb85494b1b3cb8cad3f34a916f875d24f189497024d4b39711e,2022-04-28 15:19:38.000 UTC,0,true +3765,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006548e04bd2303fb34cfb89d6bdbfb96200a7ac980000000000000000000000006548e04bd2303fb34cfb89d6bdbfb96200a7ac98000000000000000000000000000000000000000000000000000b3bdbe270136a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009564d7aed0f3bf0d2ca204fc07a6ec75e969fa8b0000000000000000000000009564d7aed0f3bf0d2ca204fc07a6ec75e969fa8b000000000000000000000000000000000000000000000000000ab565db430b2300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d74c56c55573d810a130599aac4bec2337b4dc3d000000000000000000000000d74c56c55573d810a130599aac4bec2337b4dc3d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3769,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003afff5535509253870fc986483328d7eed93f4050000000000000000000000003afff5535509253870fc986483328d7eed93f40500000000000000000000000000000000000000000000000000a1b3d75693691300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3770,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000750477199971bd75e8d75810cfa8a429d7b55828000000000000000000000000750477199971bd75e8d75810cfa8a429d7b55828000000000000000000000000000000000000000000000000004e83d53989400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3771,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1667baf1bcb5631e45d007d849ecbed61c92537000000000000000000000000b1667baf1bcb5631e45d007d849ecbed61c92537000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095d8c745c7073b981c3cc76f9cf739bac0d532c200000000000000000000000095d8c745c7073b981c3cc76f9cf739bac0d532c2000000000000000000000000000000000000000000000000000a444d64d3956900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000677ec29dbbb8e301e508d4f1bcd59cc0632f66b0000000000000000000000000677ec29dbbb8e301e508d4f1bcd59cc0632f66b00000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058f54129b66adb13dd2ef12537fa51e300363dbd00000000000000000000000058f54129b66adb13dd2ef12537fa51e300363dbd000000000000000000000000000000000000000000000000000b9ce5059e533b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f9ad14de2590813d0788526b22ef112df7286d70000000000000000000000001f9ad14de2590813d0788526b22ef112df7286d700000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000570cf8eb179d6f8293a88fa79ae0b13fca888898000000000000000000000000570cf8eb179d6f8293a88fa79ae0b13fca888898000000000000000000000000000000000000000000000000008f19aed0609d7e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1667baf1bcb5631e45d007d849ecbed61c92537000000000000000000000000b1667baf1bcb5631e45d007d849ecbed61c925370000000000000000000000000000000000000000000000000012795f58d5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3780,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075f1b7ae6e1f307088b2e65a366ec345e717d3f900000000000000000000000075f1b7ae6e1f307088b2e65a366ec345e717d3f9000000000000000000000000000000000000000000000000000d3f3df217770100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3782,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089d11c7c7bd8699ac6e089c79b2faac66509ccbf00000000000000000000000089d11c7c7bd8699ac6e089c79b2faac66509ccbf00000000000000000000000000000000000000000000000000a5b952f4f1ba2a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd519f2206a441738042e7b3af6daacc26b03b0f000000000000000000000000bd519f2206a441738042e7b3af6daacc26b03b0f0000000000000000000000000000000000000000000000000007be578a7f380000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000754d92358e0d4dff0aad19a21c5e989b9411c698000000000000000000000000754d92358e0d4dff0aad19a21c5e989b9411c698000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000516a4adbffa2cd62865effb0bd27a9eb9735d2b0000000000000000000000000516a4adbffa2cd62865effb0bd27a9eb9735d2b000000000000000000000000000000000000000000000000000ad6697411420e400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6b0e93a33e7d1e18199147d4bf6d0ebf8f8500a000000000000000000000000c6b0e93a33e7d1e18199147d4bf6d0ebf8f8500a000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3788,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db415f659a141e3abdf3367d7761066515511163000000000000000000000000db415f659a141e3abdf3367d776106651551116300000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e2dbaacde75dfe48b03260d7f0ff15feef3c4c20000000000000000000000000e2dbaacde75dfe48b03260d7f0ff15feef3c4c2000000000000000000000000000000000000000000000000010eaee42a632fc100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3790,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072c3c76bad4ead8a5d737a006663cc0a491c79b300000000000000000000000072c3c76bad4ead8a5d737a006663cc0a491c79b3000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3791,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000008849ee2e94f6c7437292fdc0c9d85c2577ba69050000000000000000000000008849ee2e94f6c7437292fdc0c9d85c2577ba6905000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d78e07f410cedcc234447881e5574f0cd0583b48000000000000000000000000d78e07f410cedcc234447881e5574f0cd0583b48000000000000000000000000000000000000000000000000007c101ca157a0c200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007e2ab7bd1eb35269d9714dade8ac0302c2146a600000000000000000000000007e2ab7bd1eb35269d9714dade8ac0302c2146a600000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000813407596e7c63cd3958ff081ca078cb31ddbf10000000000000000000000000813407596e7c63cd3958ff081ca078cb31ddbf1000000000000000000000000000000000000000000000000001efd34eb78aa0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e01b7a8262bd737068126769c21c86e57a250f53000000000000000000000000e01b7a8262bd737068126769c21c86e57a250f5300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3799,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096aae12d0d97428bbd24d4e5e43c1db73149bcc400000000000000000000000096aae12d0d97428bbd24d4e5e43c1db73149bcc4000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3800,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9a5f53cc1c4a32ed891d8a3585905db3ced6689000000000000000000000000d9a5f53cc1c4a32ed891d8a3585905db3ced668900000000000000000000000000000000000000000000000001ccc91ae74612a300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3801,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000489a776cbd29e9f986c8a194cddb3527a6e4d8b8000000000000000000000000489a776cbd29e9f986c8a194cddb3527a6e4d8b800000000000000000000000000000000000000000000000000ae153d89fe800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3802,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000315e1a5c796b734585c27e615b774441372fbd08000000000000000000000000315e1a5c796b734585c27e615b774441372fbd0800000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3803,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4fcee82f6c8664d63fa93b90dee3ebf940a907d000000000000000000000000a4fcee82f6c8664d63fa93b90dee3ebf940a907d000000000000000000000000000000000000000000000000001a81d2324aa09800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3804,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f412b5f5faa69082ffbf9497480b2596c5097e63000000000000000000000000f412b5f5faa69082ffbf9497480b2596c5097e630000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3805,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c634aa608ccdba729f540bd4f740d8671aa4ff68000000000000000000000000c634aa608ccdba729f540bd4f740d8671aa4ff680000000000000000000000000000000000000000000000000001902d7bb3800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3806,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a05dfcb3e061675bb1628e26161db7c886f707a0000000000000000000000006a05dfcb3e061675bb1628e26161db7c886f707a0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3807,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078d56686655978326009c884fb12482ea1afd99000000000000000000000000078d56686655978326009c884fb12482ea1afd990000000000000000000000000000000000000000000000000001ce1fe9db92e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3808,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1955833b0786b2f5b725e13f220c3abba9ea89f000000000000000000000000f1955833b0786b2f5b725e13f220c3abba9ea89f00000000000000000000000000000000000000000000000000b5700c4d927dbe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3809,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003fcc251bcc3a519cd4c8b984c6dda0744fcb4ff40000000000000000000000003fcc251bcc3a519cd4c8b984c6dda0744fcb4ff400000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c4f717e9fd9c01b68cf68f3e984c3603aecfa1e0000000000000000000000002c4f717e9fd9c01b68cf68f3e984c3603aecfa1e00000000000000000000000000000000000000000000000001493b5b91df58ff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3811,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000008d2800996df63489bbc72291b5105b47dff7c1db0000000000000000000000008d2800996df63489bbc72291b5105b47dff7c1db000000000000000000000000000000000000000000000000000000000097673200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2f6d20ca538d094bc14f7f5f78dbb59a2dab941000000000000000000000000b2f6d20ca538d094bc14f7f5f78dbb59a2dab941000000000000000000000000000000000000000000000000002da473a405890000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3813,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7ebd39478c6d0f4ff652cb3ad1f268f80fc180b000000000000000000000000a7ebd39478c6d0f4ff652cb3ad1f268f80fc180b00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072f55b96e746075da2932a5518251aa641f79e4d00000000000000000000000072f55b96e746075da2932a5518251aa641f79e4d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3815,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000300c8115f3bbcba6b11ea660bb6b8ad9b50e5095000000000000000000000000300c8115f3bbcba6b11ea660bb6b8ad9b50e509500000000000000000000000000000000000000000000000000be513f2e3b538c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000375004acccfb6c51ece8f8e9d392ac3ee1fc7b50000000000000000000000000375004acccfb6c51ece8f8e9d392ac3ee1fc7b5000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f0a7f7182a7efee4eb6f2284a18fb3db388f4a30000000000000000000000003f0a7f7182a7efee4eb6f2284a18fb3db388f4a3000000000000000000000000000000000000000000000000002ee474461e847400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010611590e8b86fd369ba0053af0d9d94b4d5e2fd00000000000000000000000010611590e8b86fd369ba0053af0d9d94b4d5e2fd000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000281b87fd1c6e9889a640ea433701a50c188353f0000000000000000000000000281b87fd1c6e9889a640ea433701a50c188353f00000000000000000000000000000000000000000000000000341cbace10a9c100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3820,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000491830a07fb1e9a0ad0594350f4ec40dca7221c9000000000000000000000000491830a07fb1e9a0ad0594350f4ec40dca7221c900000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b9fca59517f111b12ed215066c6acb8b047e9f40000000000000000000000006b9fca59517f111b12ed215066c6acb8b047e9f4000000000000000000000000000000000000000000000000003c0a5dfe68008e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3822,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f0641456068a18bf7c650fa8baa10a16a91e9d20000000000000000000000001f0641456068a18bf7c650fa8baa10a16a91e9d200000000000000000000000000000000000000000000000000b1c8c44c27f84d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005974bba5c87c1cbfd49ccfa523d2c43a39effa100000000000000000000000005974bba5c87c1cbfd49ccfa523d2c43a39effa10000000000000000000000000000000000000000000000000003be644b1aeb8200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000771bb178d252a53539bed32a81feed638bece156000000000000000000000000771bb178d252a53539bed32a81feed638bece15600000000000000000000000000000000000000000000000000261b5f5d6ead3c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000043b2dab2c28e6775626f41d2cdfde0cb2b0fee2300000000000000000000000043b2dab2c28e6775626f41d2cdfde0cb2b0fee230000000000000000000000000000000000000000000000000000000000ca027100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006fcb0c131c5648808ed90b651dac3ee52167ab300000000000000000000000006fcb0c131c5648808ed90b651dac3ee52167ab30000000000000000000000000000000000000000000000000009a0d5cd60e1c9700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091a56b8c4203821bf4267e071b42122f5aef99b500000000000000000000000091a56b8c4203821bf4267e071b42122f5aef99b50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039449e70f8c4840d594dc39206ac255250c3de1a00000000000000000000000039449e70f8c4840d594dc39206ac255250c3de1a000000000000000000000000000000000000000000000000014c1782a2b1a85c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000226d4e9559b91a58f5763d11722178a983e8efd6000000000000000000000000226d4e9559b91a58f5763d11722178a983e8efd60000000000000000000000000000000000000000000000000411084ff1221ca900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047896f79d4b3f5e67993c3abdb91554a8be03a1100000000000000000000000047896f79d4b3f5e67993c3abdb91554a8be03a11000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cdf5fa5ddfe6b18c43dfcbf0606a18d03814de62000000000000000000000000cdf5fa5ddfe6b18c43dfcbf0606a18d03814de62000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f127e08fe04acbe8562cdd83bc3cb4911264efc0000000000000000000000009f127e08fe04acbe8562cdd83bc3cb4911264efc000000000000000000000000000000000000000000000000004d00ef8d868e1f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000008408e984be85f93f4b8fdab8c326a300e1299a130000000000000000000000008408e984be85f93f4b8fdab8c326a300e1299a130000000000000000000000000000000000000000000000000000000000fc87b700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0251c065aa6a144d573d2b25d8c0b3c07ad0d44000000000000000000000000e0251c065aa6a144d573d2b25d8c0b3c07ad0d4400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040f97c33ec682c872eabe60e24bba862a2152ae200000000000000000000000040f97c33ec682c872eabe60e24bba862a2152ae20000000000000000000000000000000000000000000000000555ac9c03666ff200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067ba8b7a6cf8b93451422ecbd43152f2c0e101c800000000000000000000000067ba8b7a6cf8b93451422ecbd43152f2c0e101c8000000000000000000000000000000000000000000000000009b4d586152198700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000f4f342ffb2122ec36ddc77ff5825ff8f430991a4000000000000000000000000f4f342ffb2122ec36ddc77ff5825ff8f430991a40000000000000000000000000000000000000000000000000000000002faf08000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3843,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000040b32f1e906fa57b30e2059b29c698c19dd6fe9500000000000000000000000040b32f1e906fa57b30e2059b29c698c19dd6fe95000000000000000000000000000000000000000000000001c9ca0e4f144b148600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004f25877c6ab337aab6898cf70db3ea00bad83a900000000000000000000000004f25877c6ab337aab6898cf70db3ea00bad83a90000000000000000000000000000000000000000000000000009fd6f4d17d2c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007558899d8109d8a2ce457837ade56c3d6ebfe90d0000000000000000000000007558899d8109d8a2ce457837ade56c3d6ebfe90d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000038bdb2f63e6ac5996cec5cea17ed0c6da066978100000000000000000000000038bdb2f63e6ac5996cec5cea17ed0c6da06697810000000000000000000000000000000000000000000000000000000000975ea200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3847,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003b8d47f77c537842cfe003ffd751cbb8cf8f9f540000000000000000000000003b8d47f77c537842cfe003ffd751cbb8cf8f9f5400000000000000000000000000000000000000000000000059f0841efbdff9bd00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000b12fa3e8c3db55cbd103c6f12174c091304eeb1f000000000000000000000000b12fa3e8c3db55cbd103c6f12174c091304eeb1f00000000000000000000000000000000000000000000000000000000007985cd00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3a038cb837ff7cdb038c72d3714951a835e6a36000000000000000000000000c3a038cb837ff7cdb038c72d3714951a835e6a36000000000000000000000000000000000000000000000000008b921b2cf6e9f900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008923b496d365c6de1d694de37e9e11c18627dec20000000000000000000000008923b496d365c6de1d694de37e9e11c18627dec200000000000000000000000000000000000000000000000000307a67ed8bb4ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004012460b81a1b975149071eea32f7391a82e54750000000000000000000000004012460b81a1b975149071eea32f7391a82e5475000000000000000000000000000000000000000000000000009871f15500ad6500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa5b9a2dc716bd732c0633d576db4d9cceb36f55000000000000000000000000fa5b9a2dc716bd732c0633d576db4d9cceb36f55000000000000000000000000000000000000000000000000013e5769b518517600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003159fb204e29c5666780d60bd34bffbd1bb1b9660000000000000000000000003159fb204e29c5666780d60bd34bffbd1bb1b9660000000000000000000000000000000000000000000000000102009878bae82600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3855,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029ab02016fd6a2c6fe199f8a2c28c1dd8735dd8100000000000000000000000029ab02016fd6a2c6fe199f8a2c28c1dd8735dd81000000000000000000000000000000000000000000000000005e63b9ee7bec0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087497f866184d7e32281e5ba09e36ba476ffbbc400000000000000000000000087497f866184d7e32281e5ba09e36ba476ffbbc4000000000000000000000000000000000000000000000000002905749d1ec11900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d3eb1796600fddd8128b4ce284f789a942bd1a80000000000000000000000000d3eb1796600fddd8128b4ce284f789a942bd1a8000000000000000000000000000000000000000000000000000b98c538fe4ab600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3858,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca6a99150fa9a555de0b4cd56a3d3cc7ee74591a000000000000000000000000ca6a99150fa9a555de0b4cd56a3d3cc7ee74591a0000000000000000000000000000000000000000000000001af044837ce2a9f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000bac76b4c06d7c642601e995a68cb5186ee3154e6000000000000000000000000bac76b4c06d7c642601e995a68cb5186ee3154e60000000000000000000000000000000000000000000000000000000006cb41c600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000250c60517a09bfe0ce2614f168482d4cdde54521000000000000000000000000250c60517a09bfe0ce2614f168482d4cdde54521000000000000000000000000000000000000000000000000013ebcaf9702341e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3862,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000e614436af4dce18bb711a46a1eb88c9bd6752f90000000000000000000000000e614436af4dce18bb711a46a1eb88c9bd6752f9000000000000000000000000000000000000000000000000006d013da300ad47200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a699e3109bf34f6b175287b5d87c3b880ecf36b3000000000000000000000000a699e3109bf34f6b175287b5d87c3b880ecf36b300000000000000000000000000000000000000000000000000ae4473db5f92d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000864a269bf59800a7b07c2e543cbcad1339009038000000000000000000000000864a269bf59800a7b07c2e543cbcad1339009038000000000000000000000000000000000000000000000000002bf3c7a7c06a9d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3868,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001eba4156edbc932dbba3ab346df0bc5dad090ca50000000000000000000000001eba4156edbc932dbba3ab346df0bc5dad090ca500000000000000000000000000000000000000000000000000aa2ff221888e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000eb40d183faec21ca7abc4af1a5afe59b1e887149000000000000000000000000eb40d183faec21ca7abc4af1a5afe59b1e8871490000000000000000000000000000000000000000000000000605fb92345780c100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e39d6f3a84ca26c65c941f7de02ea748308781a5000000000000000000000000e39d6f3a84ca26c65c941f7de02ea748308781a5000000000000000000000000000000000000000000000000003fc1fa95cd0f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000865e56dc344831e91e7618201987a9f7ddf6a716000000000000000000000000865e56dc344831e91e7618201987a9f7ddf6a716000000000000000000000000000000000000000000000000019c1d62a9f2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017d8319926eb181225cf3c75dfd91e36a065612d00000000000000000000000017d8319926eb181225cf3c75dfd91e36a065612d0000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c93ffb6ccfa0fbe215de35afb3c7020a76accb4b000000000000000000000000c93ffb6ccfa0fbe215de35afb3c7020a76accb4b0000000000000000000000000000000000000000000000000086279d5758568f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3875,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a8ff6463f2887c4f1b9fc7e6291d38940e43dd80000000000000000000000000a8ff6463f2887c4f1b9fc7e6291d38940e43dd8000000000000000000000000000000000000000000000000000cb8e41403cb4a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000aa76c67ab68fa37df3821d41192f21b275f0beac000000000000000000000000aa76c67ab68fa37df3821d41192f21b275f0beac0000000000000000000000000000000000000000000000000000000011e1a30000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c8460c65f8ecf0e590e0dfeb8ac5a4786370235b000000000000000000000000c8460c65f8ecf0e590e0dfeb8ac5a4786370235b000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a83bbbee6a05eb158371bc888deda2c853958a60000000000000000000000008a83bbbee6a05eb158371bc888deda2c853958a600000000000000000000000000000000000000000000000000f28d969b8644f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc83ece75cdc5f481f2221ca64dc27c7d3a3a360000000000000000000000000fc83ece75cdc5f481f2221ca64dc27c7d3a3a360000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca4410fed843bd3a596b4b9a825b3ee50eed339f000000000000000000000000ca4410fed843bd3a596b4b9a825b3ee50eed339f00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3882,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc83ece75cdc5f481f2221ca64dc27c7d3a3a360000000000000000000000000fc83ece75cdc5f481f2221ca64dc27c7d3a3a360000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e92d661bd5063f7df955d68e123b96d069069e90000000000000000000000003e92d661bd5063f7df955d68e123b96d069069e9000000000000000000000000000000000000000000000000009101098c2958ea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3884,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cdcc0d3d741dd6501ad2f8109cd9d9f5d4784668000000000000000000000000cdcc0d3d741dd6501ad2f8109cd9d9f5d4784668000000000000000000000000000000000000000000000000008fe660daa7ac4d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000d08487457f8c37ef5a021af28280d4f915dd32f6000000000000000000000000d08487457f8c37ef5a021af28280d4f915dd32f600000000000000000000000000000000000000000000000000000000012ea65400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000171814db6dcaa27d2f88b1d31e306abda53e7526000000000000000000000000171814db6dcaa27d2f88b1d31e306abda53e752600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfa6a349a1e9c5f3bf109d5f00232f3855004567000000000000000000000000cfa6a349a1e9c5f3bf109d5f00232f38550045670000000000000000000000000000000000000000000000000093170bbcef3fc700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000c62fb0ed991c19edffedf58136f42d188c3cf200000000000000000000000000c62fb0ed991c19edffedf58136f42d188c3cf2000000000000000000000000000000000000000000000000012ccd9bfd26900200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044bbe4e4ef96278a80637b5f5622faba5e32803400000000000000000000000044bbe4e4ef96278a80637b5f5622faba5e3280340000000000000000000000000000000000000000000000000138d5d18ea5b9e800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd9e3a9ac8741155abfeee31dbe138dd7ad30069000000000000000000000000cd9e3a9ac8741155abfeee31dbe138dd7ad3006900000000000000000000000000000000000000000000000002780cdbd55d803000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9c24db3d1a4b41813e77ecfe12d4397b438791e000000000000000000000000b9c24db3d1a4b41813e77ecfe12d4397b438791e000000000000000000000000000000000000000000000000027002878ae4905b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060913b55ae54c325be3a8960536f1266aa64819700000000000000000000000060913b55ae54c325be3a8960536f1266aa64819700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3894,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b53012acbac544b88a6a2dc881012b1eaad87d00000000000000000000000001b53012acbac544b88a6a2dc881012b1eaad87d000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3895,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5bd323d83b66be9c0b841e9774d9098db30f9f7000000000000000000000000e5bd323d83b66be9c0b841e9774d9098db30f9f700000000000000000000000000000000000000000000000000266e9b03cc378d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046a2eaa65b8090124478813b690514e96411d60600000000000000000000000046a2eaa65b8090124478813b690514e96411d6060000000000000000000000000000000000000000000000000022fe5e75f0f98900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3897,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000005acfbbf0aa370f232e341bc0b1a40e996c960e07000000000000000000000000000000000000000000000003bd913e6c1df40000,,,1,true +3899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2c096bd1e7dec77fd08d5d18792c88a51f85c28000000000000000000000000e2c096bd1e7dec77fd08d5d18792c88a51f85c28000000000000000000000000000000000000000000000000004632ad75f4997100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3900,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca26545fe29370565c2533d39b5294c7b7c89f17000000000000000000000000ca26545fe29370565c2533d39b5294c7b7c89f1700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae1a62bc5e7f80a45fd02d20520359972143c1e4000000000000000000000000ae1a62bc5e7f80a45fd02d20520359972143c1e400000000000000000000000000000000000000000000000000283d179aab4a7100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3903,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005476e4af71ae0ec991986752a30fd57c2425de200000000000000000000000005476e4af71ae0ec991986752a30fd57c2425de200000000000000000000000000000000000000000000000000183da6981b60e200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3904,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000932adf2d3cea3c8238580e81ecfa79c0ad6032b3000000000000000000000000932adf2d3cea3c8238580e81ecfa79c0ad6032b3000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa6dc233b0dbd379e8ebc639fe8ccb7fcd23e5d5aa4381d63d22bf0d34b949767,2022-05-30 08:04:37.000 UTC,0,true +3905,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de213eeb9c3c2a1bf8d95d66a6e025ab97d49de3000000000000000000000000de213eeb9c3c2a1bf8d95d66a6e025ab97d49de300000000000000000000000000000000000000000000000000fd5bfefa9eefc400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000165accdd467426d974d652bde5c714e38f1311fa000000000000000000000000165accdd467426d974d652bde5c714e38f1311fa0000000000000000000000000000000000000000000000000051fc6c6f02fc0c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3908,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001af331dc34dd7c5c62af28b5685328318b61888a0000000000000000000000001af331dc34dd7c5c62af28b5685328318b61888a0000000000000000000000000000000000000000000000000120d7ee01d5206900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bd4b3788f36cfaf2382c7b3727a61adb1dddac70000000000000000000000001bd4b3788f36cfaf2382c7b3727a61adb1dddac70000000000000000000000000000000000000000000000000002c8ec8e7fd28000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000008f3d7c5cf34d33df17627091ca16f129e91395f50000000000000000000000008f3d7c5cf34d33df17627091ca16f129e91395f5000000000000000000000000000000000000000000000000000000000121eac000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3912,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064b449bcd01d8b5c64187e5f42f913e48c4706fa00000000000000000000000064b449bcd01d8b5c64187e5f42f913e48c4706fa00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c59cea94ee8b05bd851af1bf9d243ba585e29620000000000000000000000004c59cea94ee8b05bd851af1bf9d243ba585e29620000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3914,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f53d5e7a853b23e9fe83271e23213fb895492746000000000000000000000000f53d5e7a853b23e9fe83271e23213fb8954927460000000000000000000000000000000000000000000000000031e43dac33400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa0712940ce249c177a00703fa185a9879bccdd8000000000000000000000000aa0712940ce249c177a00703fa185a9879bccdd8000000000000000000000000000000000000000000000000005550edb490ba8700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000712fcde4fbf129bb73582b1e2b82eeea556fdf28000000000000000000000000712fcde4fbf129bb73582b1e2b82eeea556fdf2800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a284fbfb32a2f9be4945aac11b09fd092031f056000000000000000000000000a284fbfb32a2f9be4945aac11b09fd092031f056000000000000000000000000000000000000000000000000002af4b67ab8bc8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3919,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000afabc4dafdf690d69bb02a55678d2e1b8b3feedf000000000000000000000000afabc4dafdf690d69bb02a55678d2e1b8b3feedf000000000000000000000000000000000000000000000000001bdebda8b7f10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6162f7e7cc842566601e8f98de7eff88377a448000000000000000000000000d6162f7e7cc842566601e8f98de7eff88377a4480000000000000000000000000000000000000000000000000052f0e7a9f3ad9400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3921,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046be90355eec9acb93a0063f3ef7243f3cd3bcf400000000000000000000000046be90355eec9acb93a0063f3ef7243f3cd3bcf400000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3922,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e76cd0f7944fc8c8243db331890e57d6fdf854e0000000000000000000000008e76cd0f7944fc8c8243db331890e57d6fdf854e000000000000000000000000000000000000000000000000001a6eb4a7ba996000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000880e38366e241344c32d546f21fafb50d612d857000000000000000000000000880e38366e241344c32d546f21fafb50d612d85700000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c59cea94ee8b05bd851af1bf9d243ba585e29620000000000000000000000004c59cea94ee8b05bd851af1bf9d243ba585e296200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5639057d150e6db16a5b2851e7602633ed5e562000000000000000000000000f5639057d150e6db16a5b2851e7602633ed5e562000000000000000000000000000000000000000000000000001d4812f20a950000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c59cea94ee8b05bd851af1bf9d243ba585e29620000000000000000000000004c59cea94ee8b05bd851af1bf9d243ba585e296200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3928,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000009029057074ab04e98de5e016271100357e7f8d5b0000000000000000000000009029057074ab04e98de5e016271100357e7f8d5b000000000000000000000000000000000000000000000000000000000064643c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3929,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dc8c538004708dc54696fb46f94ea701f0eb9290000000000000000000000002dc8c538004708dc54696fb46f94ea701f0eb92900000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000acb7f456858bc9ff605028bac6f6f2972a5015da000000000000000000000000acb7f456858bc9ff605028bac6f6f2972a5015da000000000000000000000000000000000000000000000000000000000064737400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006edc29b9115b6e5601ed88711f0baac0a38a251e0000000000000000000000006edc29b9115b6e5601ed88711f0baac0a38a251e000000000000000000000000000000000000000000000000001c54f5b2f9a16a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3933,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f68cb6bf5df2d7f0b1a42a814b0939e14f318610000000000000000000000002f68cb6bf5df2d7f0b1a42a814b0939e14f3186100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3934,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009828dd2e0690405617b755ca81e7decac8c9ddfa0000000000000000000000009828dd2e0690405617b755ca81e7decac8c9ddfa000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f55d10ce6dd8315ac022a5f367b776925968b9b0000000000000000000000008f55d10ce6dd8315ac022a5f367b776925968b9b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ccf2677ba63913fbf929aad879236a895e704b4c000000000000000000000000ccf2677ba63913fbf929aad879236a895e704b4c00000000000000000000000000000000000000000000000000064672a2cfb00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3937,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0d07d3fac606bc1693f79aa706f9e7abd934cd7000000000000000000000000a0d07d3fac606bc1693f79aa706f9e7abd934cd7000000000000000000000000000000000000000000000000000d0643d0bf1e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a5c53e3aa62bdc23a9e56ce6e1936435d9cf9430000000000000000000000009a5c53e3aa62bdc23a9e56ce6e1936435d9cf94300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe3baf2e9352fb4d894b005a2923a0711b106dcf000000000000000000000000fe3baf2e9352fb4d894b005a2923a0711b106dcf00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3941,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003fa38d04b6e2bb406842a2950f9ac13b51b2b1620000000000000000000000003fa38d04b6e2bb406842a2950f9ac13b51b2b16200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3942,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008886f10011806825b1bc560ceb6f06dfc49719c30000000000000000000000008886f10011806825b1bc560ceb6f06dfc49719c30000000000000000000000000000000000000000000000000049fd13f05e8e7a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083f4337272794930d596119e04d84dd4e1310fcd00000000000000000000000083f4337272794930d596119e04d84dd4e1310fcd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3944,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5bd323d83b66be9c0b841e9774d9098db30f9f7000000000000000000000000e5bd323d83b66be9c0b841e9774d9098db30f9f70000000000000000000000000000000000000000000000000024ab490f11c53700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3945,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb2c098011513bb2bb8655b3dec65a33e7a09dd5000000000000000000000000eb2c098011513bb2bb8655b3dec65a33e7a09dd500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3946,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d31e04df08efbcaa4d92dd1e3af2ec7dd217d330000000000000000000000008d31e04df08efbcaa4d92dd1e3af2ec7dd217d330000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3947,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000afabc4dafdf690d69bb02a55678d2e1b8b3feedf000000000000000000000000afabc4dafdf690d69bb02a55678d2e1b8b3feedf000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6ef1ad881c35290dd663ad91165876488abf96c000000000000000000000000c6ef1ad881c35290dd663ad91165876488abf96c00000000000000000000000000000000000000000000000000140e7ad104673600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000ac60b8fd10e8fee113676ac25532879b2b5de400000000000000000000000000ac60b8fd10e8fee113676ac25532879b2b5de400000000000000000000000000000000000000000000000000179886821ef82600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3954,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035e70d60d16352a8cbecc3fdac6d1347579a0de200000000000000000000000035e70d60d16352a8cbecc3fdac6d1347579a0de2000000000000000000000000000000000000000000000000001ee3fc16c639e300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3955,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b43310714f0eaf3ef00f59d1cb960b9f0a2864f2000000000000000000000000b43310714f0eaf3ef00f59d1cb960b9f0a2864f2000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3956,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f925a8e3707414ecc334719d34663738b1e8b3fe000000000000000000000000f925a8e3707414ecc334719d34663738b1e8b3fe00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3957,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0113b17a290b7e6275c1140dc2c76c785a662f1000000000000000000000000c0113b17a290b7e6275c1140dc2c76c785a662f1000000000000000000000000000000000000000000000000001f4dbe12c4260000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7acb53b483cdd9ddadbe94458665d3dc5050e73000000000000000000000000e7acb53b483cdd9ddadbe94458665d3dc5050e73000000000000000000000000000000000000000000000000022f372fb5da7fb500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000206403bc57fe7d0b68e81d4bfdddc67bb0567b70000000000000000000000000206403bc57fe7d0b68e81d4bfdddc67bb0567b7000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3960,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000024a26a581ec9018419c0f1f4a096f1862dd70dc000000000000000000000000024a26a581ec9018419c0f1f4a096f1862dd70dc000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0bdfe8fb79376bd51a824d8a7d1438981a9a8fa000000000000000000000000e0bdfe8fb79376bd51a824d8a7d1438981a9a8fa00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9122d0f8ca7811a7a88a36b614ea619bd21622f000000000000000000000000c9122d0f8ca7811a7a88a36b614ea619bd21622f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af4807d083287f205d897e6d00c6fde1bf0a241a000000000000000000000000af4807d083287f205d897e6d00c6fde1bf0a241a000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3964,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f962a4b2692783babab48e4dae6e874dd9f491f1000000000000000000000000f962a4b2692783babab48e4dae6e874dd9f491f100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c1f605b0f4433ebe2670df134c561798caf140c0000000000000000000000009c1f605b0f4433ebe2670df134c561798caf140c00000000000000000000000000000000000000000000000001565ab0e181e9c100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cdc8e4560cf8ab71713eeaa923bb8dd03bb0259a000000000000000000000000cdc8e4560cf8ab71713eeaa923bb8dd03bb0259a000000000000000000000000000000000000000000000000009fa666e34e120700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059dc6b5e1fd34abc2f472960f3519d12a8afa82d00000000000000000000000059dc6b5e1fd34abc2f472960f3519d12a8afa82d000000000000000000000000000000000000000000000000007d5824fc59636000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de64ea282b06ae636263a28ec305bda1d45d6440000000000000000000000000de64ea282b06ae636263a28ec305bda1d45d644000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3970,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007eb1e94d2aa01d39b7c238ec00e51608ff7ef7c70000000000000000000000007eb1e94d2aa01d39b7c238ec00e51608ff7ef7c70000000000000000000000000000000000000000000000000079b7b86b2a203800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000002212f6a413793df232c3dfd8e38bb9acd95097a80000000000000000000000002212f6a413793df232c3dfd8e38bb9acd95097a8000000000000000000000000000000000000000000000000000000000096786e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077e88d310614957a5ff962f0a24390da69f906a000000000000000000000000077e88d310614957a5ff962f0a24390da69f906a000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000045bf2f411439cec318b9593fd4e7c7aac78756e000000000000000000000000045bf2f411439cec318b9593fd4e7c7aac78756e000000000000000000000000000000000000000000000000000e7bccdc1399a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009539e2ed84961b56c6bb275a3e2999e4bfa0a25d0000000000000000000000009539e2ed84961b56c6bb275a3e2999e4bfa0a25d000000000000000000000000000000000000000000000000000da76e9a6e16fa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b760b50c921847aa9a5a47f9903a6600b7995f73000000000000000000000000b760b50c921847aa9a5a47f9903a6600b7995f7300000000000000000000000000000000000000000000000000127398a688d3c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b30367238ac1da91b0cf31bb4b0b4efb777488e5000000000000000000000000b30367238ac1da91b0cf31bb4b0b4efb777488e500000000000000000000000000000000000000000000000003782dace9d9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3979,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da906a6ca40f9eb04b83f0194c1bfe7ac50ae19a000000000000000000000000da906a6ca40f9eb04b83f0194c1bfe7ac50ae19a000000000000000000000000000000000000000000000000002bf2abb2fce4d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3980,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000afe1a3fe7c227d7c0246b50289ea82e99d036c1e000000000000000000000000afe1a3fe7c227d7c0246b50289ea82e99d036c1e000000000000000000000000000000000000000000000000001f8a506ab31b3500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004421de8bfb150486936a4e8da325ce64862f5ac80000000000000000000000004421de8bfb150486936a4e8da325ce64862f5ac8000000000000000000000000000000000000000000000000015aa3408c7b1d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbbc1a332792675522743ac484a78c2ece1224e33dda1dfac793563bf18ee4041,2022-03-15 09:48:33.000 UTC,0,true +3983,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015d9ff71b5ab06626a2ca7fd5aab934323b334ac00000000000000000000000015d9ff71b5ab06626a2ca7fd5aab934323b334ac00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3984,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ffd03ed5bd3d94806730144bcec2fd673b109cd0000000000000000000000009ffd03ed5bd3d94806730144bcec2fd673b109cd0000000000000000000000000000000000000000000000000018020711cb1e6b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e69b1f36a3a7044dfcc56e1a21e2ffee6f429d00000000000000000000000000e69b1f36a3a7044dfcc56e1a21e2ffee6f429d0000000000000000000000000000000000000000000000000001011251bc203bd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d75713b70205d97de79a754853fe944bfd7b6f10000000000000000000000002d75713b70205d97de79a754853fe944bfd7b6f1000000000000000000000000000000000000000000000000009e3f0dcc50f05700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0737564e414efd5c436970014960245f4490bcc000000000000000000000000f0737564e414efd5c436970014960245f4490bcc00000000000000000000000000000000000000000000000000c434b7c0eafdff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3991,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009320563d7619bfc9230f5ac0aec7401c16e3acad0000000000000000000000009320563d7619bfc9230f5ac0aec7401c16e3acad000000000000000000000000000000000000000000000000003072157ef55b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf3d12db8997aed8edfa089e7ad9f7501590f4a17b62e4f7c14b779b511cbe196,2022-03-15 09:28:59.000 UTC,0,true +3992,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a6c1373768e81328372bad188173bf2da5214f90000000000000000000000007a6c1373768e81328372bad188173bf2da5214f900000000000000000000000000000000000000000000000001046d57ddaeae6a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x678d1b4e615ba482e406bf763cb5de43fe75f7640d5171e682d8de97e8a9ef91,2022-03-15 09:52:14.000 UTC,0,true +3993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f7aea0293d5b9b68d119582636315df69513c9a0000000000000000000000005f7aea0293d5b9b68d119582636315df69513c9a0000000000000000000000000000000000000000000000000023bf2ef964c7a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +3994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b347957d6d017f8783a14abd017065d92cf739e8000000000000000000000000b347957d6d017f8783a14abd017065d92cf739e8000000000000000000000000000000000000000000000000010ae192271ffa3000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x59c2dd02e934c297322d2d92d4eb63388d783464e0c7903e1d3fe18d4c7531b1,2022-03-15 10:01:33.000 UTC,0,true +3997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000208693c01c3d711fd41b1b1c183ef6b7747cec37000000000000000000000000208693c01c3d711fd41b1b1c183ef6b7747cec370000000000000000000000000000000000000000000000000000000000644c2500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +3999,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d11494a6d9c10a28edd722eb9f5d4492a321799c000000000000000000000000d11494a6d9c10a28edd722eb9f5d4492a321799c0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4000,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d16ce08f15108d9214eece309f90c119749d29a0000000000000000000000001d16ce08f15108d9214eece309f90c119749d29a000000000000000000000000000000000000000000000000027f7d0bdb92000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094a6ceb8c80b560f28c9048d40b994ea778c453f00000000000000000000000094a6ceb8c80b560f28c9048d40b994ea778c453f0000000000000000000000000000000000000000000000000055e76776d5623e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4005,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec6da4426f0ad6982fdd9b26b5816be8dc077f0a000000000000000000000000ec6da4426f0ad6982fdd9b26b5816be8dc077f0a000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4006,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d688982b60b26d86fcd726c7277b903dc68a4150000000000000000000000005d688982b60b26d86fcd726c7277b903dc68a4150000000000000000000000000000000000000000000000000049afa6dbb9f16400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4007,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd749d32f727122ead72a9de788165bc51950083000000000000000000000000fd749d32f727122ead72a9de788165bc519500830000000000000000000000000000000000000000000000000065788b7685220000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4008,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b161b3e4b117505cd7252c726f5ce431a33ca2b4000000000000000000000000b161b3e4b117505cd7252c726f5ce431a33ca2b4000000000000000000000000000000000000000000000000002edbdee0f1da7400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2df5f33f06375d396c121ff312eb6166503121b000000000000000000000000e2df5f33f06375d396c121ff312eb6166503121b000000000000000000000000000000000000000000000000009881ac573d5dec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4012,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006699c7a0592cccb1d60f5abd52dc824b70baa5700000000000000000000000006699c7a0592cccb1d60f5abd52dc824b70baa57000000000000000000000000000000000000000000000000000a181726f4c932600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1e5ac5cbbc8ea4e154c571a8412d5f601338a52000000000000000000000000a1e5ac5cbbc8ea4e154c571a8412d5f601338a52000000000000000000000000000000000000000000000000005cbfa95b51238900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4014,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e782bdb152e26d2b3dbe701cd5b427b820e0e7b3000000000000000000000000e782bdb152e26d2b3dbe701cd5b427b820e0e7b3000000000000000000000000000000000000000000000000000b5e3084bd603500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4015,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095cb87a1c385ed84414c499220056227e98762c000000000000000000000000095cb87a1c385ed84414c499220056227e98762c00000000000000000000000000000000000000000000000000022302502da081800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4016,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000d07ba7c276533c9061d99830bef0ea5e0f562300000000000000000000000000d07ba7c276533c9061d99830bef0ea5e0f5623000000000000000000000000000000000000000000000000001fec50ad982b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4019,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000011333555f7806f8ea21c55ec933e3151fe3e012600000000000000000000000011333555f7806f8ea21c55ec933e3151fe3e012600000000000000000000000000000000000000000000000000000000118de8b600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f19e9b808eca47db283de76eed94fbbf3e9fdf96000000000000000000000000f19e9b808eca47db283de76eed94fbbf3e9fdf96000000000000000000000000000000000000000000000000002714711487800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e874f4c7e12cccae67e55e08a29588e709b6bc20000000000000000000000004e874f4c7e12cccae67e55e08a29588e709b6bc2000000000000000000000000000000000000000000000000005c5edcbc29000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006b971d297528f8db06c069c644ae9e6e1d1dae100000000000000000000000006b971d297528f8db06c069c644ae9e6e1d1dae1000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2c912039ae856874814150f0b51921cb4ff25a9000000000000000000000000d2c912039ae856874814150f0b51921cb4ff25a9000000000000000000000000000000000000000000000000014858f4a079a6d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051ad4751da4f13974a9e18c27f845f6f3276f11d00000000000000000000000051ad4751da4f13974a9e18c27f845f6f3276f11d000000000000000000000000000000000000000000000000001cd7552d8de26000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004880d1488f8c2aaadb04ff1e742796998b03cc990000000000000000000000004880d1488f8c2aaadb04ff1e742796998b03cc9900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2c6ed80cc5075802ccb59c2466ea61e344fbec5000000000000000000000000b2c6ed80cc5075802ccb59c2466ea61e344fbec5000000000000000000000000000000000000000000000000001fb528a311120200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8aacbfab425fd86e8b8ae0b30745468d32d387a000000000000000000000000b8aacbfab425fd86e8b8ae0b30745468d32d387a000000000000000000000000000000000000000000000000001a063d7436d7c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4036,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f3070e25db6da541f2aa5e1331b2e5a05ffd62d0000000000000000000000006f3070e25db6da541f2aa5e1331b2e5a05ffd62d000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4038,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c88b861f6bc812449574e8640aa975de087f5a8a000000000000000000000000c88b861f6bc812449574e8640aa975de087f5a8a00000000000000000000000000000000000000000000000000a552b49ca2d8c800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4040,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ea98c8218a5e6758f283e51d1516cc52764858e0000000000000000000000006ea98c8218a5e6758f283e51d1516cc52764858e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4041,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c57e3c4af5b1ac13b2895db009cdd7eaccaecf10000000000000000000000008c57e3c4af5b1ac13b2895db009cdd7eaccaecf1000000000000000000000000000000000000000000000000000d33031544fe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe8e3726a57dfcc0f69a6ebdcde8f971d3588e051d358e64933c80d3dc41ca825,2022-06-01 07:48:53.000 UTC,0,true +4042,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012f666cf593b412dc88cb156584198e2f620b8dc00000000000000000000000012f666cf593b412dc88cb156584198e2f620b8dc000000000000000000000000000000000000000000000000007be38dc092442300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4043,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090cb71ca70d3bbd831766fa526242715c2a9656300000000000000000000000090cb71ca70d3bbd831766fa526242715c2a96563000000000000000000000000000000000000000000000000001e05f83cd5ea0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4044,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e5a471e1f75ba6ad49a58bbb8ce4dabbb2c95240000000000000000000000008e5a471e1f75ba6ad49a58bbb8ce4dabbb2c952400000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4045,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e5a471e1f75ba6ad49a58bbb8ce4dabbb2c95240000000000000000000000008e5a471e1f75ba6ad49a58bbb8ce4dabbb2c952400000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4048,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045e5d313030be8e40fceb8f03d55300da6a8799e00000000000000000000000045e5d313030be8e40fceb8f03d55300da6a8799e00000000000000000000000000000000000000000000000001536d68579f343700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc8b4cb035812186ca94af3def98aca690be8a16000000000000000000000000cc8b4cb035812186ca94af3def98aca690be8a160000000000000000000000000000000000000000000000000045c54d8dff0b5f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050e37f8b9f344eed54e2de92aaaba4d7bdeb8a5800000000000000000000000050e37f8b9f344eed54e2de92aaaba4d7bdeb8a5800000000000000000000000000000000000000000000000000345e6c85e2a44a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4052,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ec86b0cfef9a8533197c19663de0b1767fbefe07000000000000000000000000000000000000000000000005218aaa91b104e986,,,1,true +4053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007438b42d2dc59d089e2527d706563dc9b40b913a0000000000000000000000007438b42d2dc59d089e2527d706563dc9b40b913a00000000000000000000000000000000000000000000000000d162dcc8b2910000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbbd72bd4e0a8598e2ea0a9ebf9431a3737050f8000000000000000000000000cbbd72bd4e0a8598e2ea0a9ebf9431a3737050f800000000000000000000000000000000000000000000000000d142241e97120000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4055,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da8639ebade510607414fe396e98171280ee86f1000000000000000000000000da8639ebade510607414fe396e98171280ee86f10000000000000000000000000000000000000000000000000091a94863ca800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x95e4a4c00711e65034f0cad47c5aab4af5257e2854f9ac003b21d6ee1be02883,2022-02-26 09:54:24.000 UTC,0,true +4056,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000012345e6fa44eed2df2443c739e65165861e0842000000000000000000000000012345e6fa44eed2df2443c739e65165861e084200000000000000000000000000000000000000000000000001108d56ccb8064b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca640134967f982dee6754c76b8c386340c8782f000000000000000000000000ca640134967f982dee6754c76b8c386340c8782f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4058,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9ebccface465d13ec8ce1fa8faa482030661abb000000000000000000000000f9ebccface465d13ec8ce1fa8faa482030661abb000000000000000000000000000000000000000000000000001e3361c485458f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4de6e19b30f3efeef30328ea1e46e29db7a56fb000000000000000000000000f4de6e19b30f3efeef30328ea1e46e29db7a56fb000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fff8524d56408a9d26c22475530a595714448191000000000000000000000000fff8524d56408a9d26c22475530a595714448191000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b2ade7b54e4ad80b6899bddd7cbc4547cc6263b0000000000000000000000001b2ade7b54e4ad80b6899bddd7cbc4547cc6263b00000000000000000000000000000000000000000000000000a78db0835c249000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4062,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a611b1251096d59846765297e8af43e74be3c160000000000000000000000002a611b1251096d59846765297e8af43e74be3c16000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4063,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8a2e41ee85551d0afab35373290ed670ab2e191000000000000000000000000e8a2e41ee85551d0afab35373290ed670ab2e191000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4064,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7a15b1514cce1ac722f2b99428cbaa0f453d56a000000000000000000000000f7a15b1514cce1ac722f2b99428cbaa0f453d56a000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e139506d198c1d5e6dec533ce9ba9987466488cc000000000000000000000000e139506d198c1d5e6dec533ce9ba9987466488cc000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4066,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000616cc348b0e5cccc5cd9e8900c151c2f6baf3612000000000000000000000000616cc348b0e5cccc5cd9e8900c151c2f6baf361200000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4067,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acb80c6446f57ebab29983638040859b89590fc2000000000000000000000000acb80c6446f57ebab29983638040859b89590fc2000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4068,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023d5a1d24fef3fe084717babe3c24ce82b4844a400000000000000000000000023d5a1d24fef3fe084717babe3c24ce82b4844a4000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4069,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046dcfb1655036313dac622de7d05337e235a9cf300000000000000000000000046dcfb1655036313dac622de7d05337e235a9cf3000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4070,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000797f0cb60dcfa9a6a6d9cc8f576d763c9407f5c5000000000000000000000000797f0cb60dcfa9a6a6d9cc8f576d763c9407f5c5000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4071,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040b2de9d83eb776d414950a4bdee6a9dd981444c00000000000000000000000040b2de9d83eb776d414950a4bdee6a9dd981444c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4072,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000616cc348b0e5cccc5cd9e8900c151c2f6baf3612000000000000000000000000616cc348b0e5cccc5cd9e8900c151c2f6baf361200000000000000000000000000000000000000000000000010a741a46278000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4073,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a8bb2e8898192852a08e52f504aee6e1378d41510000000000000000000000000000000000000000000000007815743d2f0dbb9c,,,1,true +4074,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bdb54f09b7dbb7a9ac737e91b399e8f5f5eaced0000000000000000000000001bdb54f09b7dbb7a9ac737e91b399e8f5f5eaced000000000000000000000000000000000000000000000000009d06b588ad83a700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be28ff6bf1adf9aa3084873e0aa20838b1910c40000000000000000000000000be28ff6bf1adf9aa3084873e0aa20838b1910c40000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088c0d341a415448a117b7b4723f729a5b9d734a000000000000000000000000088c0d341a415448a117b7b4723f729a5b9d734a0000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0d9cf48ffee0a6bdc49954b5e77058cdafb9532000000000000000000000000b0d9cf48ffee0a6bdc49954b5e77058cdafb9532000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f295da57176a11218f24dd4d95014a89345444f0000000000000000000000006f295da57176a11218f24dd4d95014a89345444f000000000000000000000000000000000000000000000000009efcf7a1c4715e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a1a5d51e81a588f3f65a449fc6c39aa22d39b5b0000000000000000000000004a1a5d51e81a588f3f65a449fc6c39aa22d39b5b000000000000000000000000000000000000000000000000015758987517449400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000990e66466826bc07c5c148c5085e654a2d7a8c23000000000000000000000000990e66466826bc07c5c148c5085e654a2d7a8c2300000000000000000000000000000000000000000000000000386d0130e16ece00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b686dcf9d959ebc90131f1b9e5aed58b60c83a14000000000000000000000000b686dcf9d959ebc90131f1b9e5aed58b60c83a1400000000000000000000000000000000000000000000000000a5b5d9d828cb5d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000945728797887fdebc2d2df277b5b506a43d6435d000000000000000000000000945728797887fdebc2d2df277b5b506a43d6435d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4084,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b95b839bdd5851a8e1655f916743b8229fe40131000000000000000000000000b95b839bdd5851a8e1655f916743b8229fe4013100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4085,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b8abbada1f108e86d04f412b9320d8cfea648170000000000000000000000006b8abbada1f108e86d04f412b9320d8cfea64817000000000000000000000000000000000000000000000000004c6222d6abc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000531c64cc8796d85e79f96a4507652f67a75bbc02000000000000000000000000531c64cc8796d85e79f96a4507652f67a75bbc02000000000000000000000000000000000000000000000000004c2e05f02afd7e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a49571f870108da21bd55b6b9c092a318f316370000000000000000000000005a49571f870108da21bd55b6b9c092a318f316370000000000000000000000000000000000000000000000000020c7e562ae758b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7b338817049f5126c820b6097ff177ea8aa839c000000000000000000000000f7b338817049f5126c820b6097ff177ea8aa839c000000000000000000000000000000000000000000000000031234e30d6ce3bf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4090,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e83906d6c19939dcc3ffcc317556d940c87847ec000000000000000000000000e83906d6c19939dcc3ffcc317556d940c87847ec0000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4092,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006b4c4b4e038f7348812f649136c189ffb75b4cd20000000000000000000000006b4c4b4e038f7348812f649136c189ffb75b4cd2000000000000000000000000000000000000000000000001ef5b6f00001e8bff00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de7f0e2128a1c95b63f6bf48825788a7090bfdb6000000000000000000000000de7f0e2128a1c95b63f6bf48825788a7090bfdb6000000000000000000000000000000000000000000000000006b243f479cca0200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000000f9987b3352802ad6934402da1a215b1ecef13000000000000000000000000000f9987b3352802ad6934402da1a215b1ecef130000000000000000000000000000000000000000000000000043154b0d733b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044b5f2e81bba7b496d91dfbba1487811ed8821eb00000000000000000000000044b5f2e81bba7b496d91dfbba1487811ed8821eb0000000000000000000000000000000000000000000000000024bcb0d03d222000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4096,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a6f55078b4651ca9330d8c7b4e5503e70b0b1520000000000000000000000000a6f55078b4651ca9330d8c7b4e5503e70b0b15200000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000009f914156f4ef42ae375e77270dc452e9b364db4b0000000000000000000000009f914156f4ef42ae375e77270dc452e9b364db4b000000000000000000000000000000000000000000000000000000000064700800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4098,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e83906d6c19939dcc3ffcc317556d940c87847ec0000000000000000000000000000000000000000000000000d0820cad21264aa,,,1,true +4099,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077d25848b2396250df5860ae566f7c341d81efac00000000000000000000000077d25848b2396250df5860ae566f7c341d81efac000000000000000000000000000000000000000000000000009f038e93808b6600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4082c93ffd4d54d96b3a421eaab46b4dab06e9b445856d527fb2d5d77e24520b,2022-02-26 09:42:37.000 UTC,0,true +4100,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9bfcdbf0bab01807bb3908f4abef78013d52042000000000000000000000000e9bfcdbf0bab01807bb3908f4abef78013d5204200000000000000000000000000000000000000000000000001565638bba4cf1d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000dc5c7e9b97149e5d5b9c22f73c5eee23d80c9d4f000000000000000000000000dc5c7e9b97149e5d5b9c22f73c5eee23d80c9d4f00000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4102,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ca3e96fa7fb225776b3bb8140483b7eb4c9233f0000000000000000000000008ca3e96fa7fb225776b3bb8140483b7eb4c9233f000000000000000000000000000000000000000000000000001e612458737c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4104,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3a0a3dd9d954ede6ba93bfcd0c9e70b92e0b266000000000000000000000000c3a0a3dd9d954ede6ba93bfcd0c9e70b92e0b266000000000000000000000000000000000000000000000000001db18086bb073700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000c7d2c67bc38b0e8b15b632c19ef629022fd56543000000000000000000000000c7d2c67bc38b0e8b15b632c19ef629022fd5654300000000000000000000000000000000000000000000000098a7d9b8314c000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xcb8da5b58d3e2723fcb47978eff796c109ec2b176491d6bf43569b05bc20fa73,2022-02-05 10:33:06.000 UTC,0,true +4107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000865437fd0e361e6482876a5b46a0128f36962706000000000000000000000000865437fd0e361e6482876a5b46a0128f3696270600000000000000000000000000000000000000000000000000128da487ff6f3d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4109,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059fafea537e14c7fdfa88eefc5e364c1a51dd64100000000000000000000000059fafea537e14c7fdfa88eefc5e364c1a51dd6410000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4110,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce364bae6274f1b14bfadef0f88e82be96e47814000000000000000000000000ce364bae6274f1b14bfadef0f88e82be96e47814000000000000000000000000000000000000000000000000015dc1f9cec42f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4111,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069f1e4b906e30755c8a0d77399dc81c4346de96f00000000000000000000000069f1e4b906e30755c8a0d77399dc81c4346de96f0000000000000000000000000000000000000000000000000010a9684080034e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4113,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb351047ea888746a827fb0d5645430e2016f39b000000000000000000000000cb351047ea888746a827fb0d5645430e2016f39b0000000000000000000000000000000000000000000000000152b5fc046b12fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4115,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cced1fb5a36d7d8eeab74b893913ebfb2b4c5840000000000000000000000006cced1fb5a36d7d8eeab74b893913ebfb2b4c584000000000000000000000000000000000000000000000000005f5ec4877c873100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4116,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000090f923e1484912285d07f7e643599b8ebf945ce000000000000000000000000090f923e1484912285d07f7e643599b8ebf945ce0000000000000000000000000000000000000000000000000033dd5a937d450100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4117,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ff3637c180274682b9d292389dbff866aa0a1f10000000000000000000000002ff3637c180274682b9d292389dbff866aa0a1f1000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4118,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002422d5d8ee568903f42f2a8a887565970569c1cc0000000000000000000000002422d5d8ee568903f42f2a8a887565970569c1cc00000000000000000000000000000000000000000000000000000000ae7cdf8200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4119,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004cdc20567a5783ac84c1a18655a312b4be2625c00000000000000000000000004cdc20567a5783ac84c1a18655a312b4be2625c00000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000235f5de73d5194e3f0f409639eb5e00662059da0000000000000000000000000235f5de73d5194e3f0f409639eb5e00662059da0000000000000000000000000000000000000000000000000015035c07b3a1bc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002331e097c09c9d8cbc7c75ad35d71368aebfb5ff0000000000000000000000002331e097c09c9d8cbc7c75ad35d71368aebfb5ff000000000000000000000000000000000000000000000000003786d53fba932c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099a2114c99a6e927c9206f30f66e065f5060754500000000000000000000000099a2114c99a6e927c9206f30f66e065f506075450000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c04a91219d7d3c3a59c4b0aedff0ff12953e8dd0000000000000000000000002c04a91219d7d3c3a59c4b0aedff0ff12953e8dd00000000000000000000000000000000000000000000000000878a2202891d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006540d7f11983c01a2e656b944cb0172db311963d0000000000000000000000006540d7f11983c01a2e656b944cb0172db311963d000000000000000000000000000000000000000000000000008cfeb44c7ae68100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4126,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000557007505b53a399a59a93509673fdc5a3dc4540000000000000000000000000557007505b53a399a59a93509673fdc5a3dc45400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4127,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f5411d1da0774fe0f888da5d144faced85a9dc60000000000000000000000008f5411d1da0774fe0f888da5d144faced85a9dc6000000000000000000000000000000000000000000000000005ffaa7d970248000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4128,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000005d55ee935d1aad8cace20528c63b26bc6417b6ce0000000000000000000000005d55ee935d1aad8cace20528c63b26bc6417b6ce000000000000000000000000000000000000000000000000000000000605234000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4129,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b02a522eccc2494f5c2efbc56dba4eace5ba7ff0000000000000000000000002b02a522eccc2494f5c2efbc56dba4eace5ba7ff00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5de1beff4c2b8f959c4b1859bc490c4216d3d29000000000000000000000000c5de1beff4c2b8f959c4b1859bc490c4216d3d290000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005466488073d3dc5a70c885fa41918e654f5027ab0000000000000000000000005466488073d3dc5a70c885fa41918e654f5027ab0000000000000000000000000000000000000000000000000010d13fde21ddfc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000787f640ca8b506e9ed61be2085e95fff78bf5bd3000000000000000000000000787f640ca8b506e9ed61be2085e95fff78bf5bd3000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005830db927c7edfff6a095f65f13ab5009011cbc80000000000000000000000005830db927c7edfff6a095f65f13ab5009011cbc8000000000000000000000000000000000000000000000000014236b9afe4b1e900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0a755e8414806e06090e1f7859ab1379c7ff494000000000000000000000000e0a755e8414806e06090e1f7859ab1379c7ff4940000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5690d11ac1b6133dbb482973de8c712a43c8a75000000000000000000000000e5690d11ac1b6133dbb482973de8c712a43c8a75000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002481e59a934369ce3c86f019b2bd845dd478158e0000000000000000000000002481e59a934369ce3c86f019b2bd845dd478158e00000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4137,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000e8a29e984681002725d547ee8103695283d2e629000000000000000000000000e8a29e984681002725d547ee8103695283d2e62900000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4138,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018e4a65a844a501826e4e9bf24590ba38b33389300000000000000000000000018e4a65a844a501826e4e9bf24590ba38b333893000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4139,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004165114102bfeb40285253581f6b703dbd20a9070000000000000000000000004165114102bfeb40285253581f6b703dbd20a907000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031b33586364621b39da91fa84f18538efa5ad6b700000000000000000000000031b33586364621b39da91fa84f18538efa5ad6b700000000000000000000000000000000000000000000000000405212104eaa2800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4141,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026fe31cd7807297f98f23fbc4d9c7b8deb0c963000000000000000000000000026fe31cd7807297f98f23fbc4d9c7b8deb0c9630000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4142,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b23a7c2525df85f8be881da6bfa7ee0bb902def8000000000000000000000000b23a7c2525df85f8be881da6bfa7ee0bb902def8000000000000000000000000000000000000000000000000001ae9e67883e78a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x418597cd761779cf93b2719475c0c62d71fde7992bf2c652d0f21ee619006f70,2022-11-01 17:26:11.000 UTC,0,true +4143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000923c28cc5a05df0664a7ce74915777e5fc500d95000000000000000000000000923c28cc5a05df0664a7ce74915777e5fc500d95000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4144,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036887cca4fdd9cfffba357de259a7619afd4d28900000000000000000000000036887cca4fdd9cfffba357de259a7619afd4d28900000000000000000000000000000000000000000000000000059b03a6d8ecf700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4145,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5710774fe287539e825769f5d0c28dd0a4f6b8b000000000000000000000000f5710774fe287539e825769f5d0c28dd0a4f6b8b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005af10de36b591901e40677492e209c70fcb48edd0000000000000000000000005af10de36b591901e40677492e209c70fcb48edd000000000000000000000000000000000000000000000000000dae8c3fd439aa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4147,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068e30fdded49610eb349f7c18535a86244a8260100000000000000000000000068e30fdded49610eb349f7c18535a86244a826010000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036a78936c69de7f41773b99652c3f6977c0d7a8300000000000000000000000036a78936c69de7f41773b99652c3f6977c0d7a8300000000000000000000000000000000000000000000000001657e44c152a90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a94025b216890204fd6c882f9399bd23a6591693000000000000000000000000a94025b216890204fd6c882f9399bd23a6591693000000000000000000000000000000000000000000000000008a8b0ebcbfc4e900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5fb0b09bf2dc9b295e1a370c48f9fb07555b7d406b698ccb28a557b03075e96c,2022-11-01 17:38:35.000 UTC,0,true +4150,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000876e96699bb6aad17e05c7adeff46eb969031795000000000000000000000000876e96699bb6aad17e05c7adeff46eb96903179500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c00bf8daad8273c4cc8463f7333b27e952164268000000000000000000000000c00bf8daad8273c4cc8463f7333b27e952164268000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4152,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e53d27c6925a8e9dc103d0749adf9d5b63a847f0000000000000000000000007e53d27c6925a8e9dc103d0749adf9d5b63a847f000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e98281408c920fe8b5182df4bb3feb7324130ed7000000000000000000000000e98281408c920fe8b5182df4bb3feb7324130ed7000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4154,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000857e0e6d38a24c795624415782ed3e937c333c33000000000000000000000000857e0e6d38a24c795624415782ed3e937c333c33000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4155,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098a764931a82c8c71b278d5fc2ecae00440cf23200000000000000000000000098a764931a82c8c71b278d5fc2ecae00440cf232000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063e640294cb0f46859d08ebabcd67fc755c4e14700000000000000000000000063e640294cb0f46859d08ebabcd67fc755c4e147000000000000000000000000000000000000000000000000001aa535d3d0c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4157,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a955d5eeb52232d017bc1793db2db2bb5503a0ef000000000000000000000000a955d5eeb52232d017bc1793db2db2bb5503a0ef000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4158,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023a719a16b5db2ccfdc4650273ee7e9c42af45bf00000000000000000000000023a719a16b5db2ccfdc4650273ee7e9c42af45bf00000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008af8154724d919c3dedb05d7dfd6f011f50f48090000000000000000000000008af8154724d919c3dedb05d7dfd6f011f50f4809000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0ce266aa75ac876f300c13d6f2393c843cd5b3b000000000000000000000000c0ce266aa75ac876f300c13d6f2393c843cd5b3b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4161,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aaa920264671d7fc5ac823e96995edc6bcc5edf3000000000000000000000000aaa920264671d7fc5ac823e96995edc6bcc5edf3000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4162,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dd55c9d6d939da000a630f31a43ddbee2f410cd0000000000000000000000002dd55c9d6d939da000a630f31a43ddbee2f410cd00000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027c041cf26b1b6a092737ae37dca8b121a54867300000000000000000000000027c041cf26b1b6a092737ae37dca8b121a548673000000000000000000000000000000000000000000000000013c0644145d183d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4164,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2dfdcfcb6309546d27423d421874f3827847ebe000000000000000000000000d2dfdcfcb6309546d27423d421874f3827847ebe000000000000000000000000000000000000000000000000003cc1dadfb742c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4165,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7e442ae668656d6dfa51b2e795e701d04442977000000000000000000000000f7e442ae668656d6dfa51b2e795e701d0444297700000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d300517e3b0f205cb538c4bcb084ed0941650a43000000000000000000000000d300517e3b0f205cb538c4bcb084ed0941650a4300000000000000000000000000000000000000000000000000590b92e3c9f77200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4167,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007709b63f77b79bec56033370f5a30fa19823b68d0000000000000000000000007709b63f77b79bec56033370f5a30fa19823b68d000000000000000000000000000000000000000000000000000b222ba17bcb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000faff89949b506dcb0d945779da968d4f996bb68a000000000000000000000000faff89949b506dcb0d945779da968d4f996bb68a000000000000000000000000000000000000000000000000063941678490f39800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4169,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae7b12ea3fd7dfb0e89c48d5bda7c404cdf91ad5000000000000000000000000ae7b12ea3fd7dfb0e89c48d5bda7c404cdf91ad5000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4170,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f1501185fc7ec323d5163fed7ea6d79556b61590000000000000000000000001f1501185fc7ec323d5163fed7ea6d79556b615900000000000000000000000000000000000000000000000000c821f6fa3c533800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4173,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006d7dcf2dc399d4d84fcbf312c20aee71e327b4400000000000000000000000006d7dcf2dc399d4d84fcbf312c20aee71e327b44000000000000000000000000000000000000000000000000005d356d2addf58d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cacd0aeade45ead6badae6bd7830cc65889fca90000000000000000000000006cacd0aeade45ead6badae6bd7830cc65889fca900000000000000000000000000000000000000000000000000cb381eb01b0bc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4175,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d70a0b9e5f1717d2bb09a4aacea03fe4630133e9000000000000000000000000d70a0b9e5f1717d2bb09a4aacea03fe4630133e900000000000000000000000000000000000000000000000000097c9c9a20da4f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c596df4b9eb215bb3057f7241f7997d04332cd12000000000000000000000000c596df4b9eb215bb3057f7241f7997d04332cd12000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026b400eb576a693c77fa2753b540db4218c0412a00000000000000000000000026b400eb576a693c77fa2753b540db4218c0412a00000000000000000000000000000000000000000000000000200fb9e97f531500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c596df4b9eb215bb3057f7241f7997d04332cd12000000000000000000000000c596df4b9eb215bb3057f7241f7997d04332cd12000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c596df4b9eb215bb3057f7241f7997d04332cd12000000000000000000000000c596df4b9eb215bb3057f7241f7997d04332cd12000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f196de1269c81c5c3f8fe0e8836b6f1a54eeac9a000000000000000000000000f196de1269c81c5c3f8fe0e8836b6f1a54eeac9a000000000000000000000000000000000000000000000000012aa896ccf5ebe300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000d884587e95aa4cf73eca390abeab64881826df5d000000000000000000000000d884587e95aa4cf73eca390abeab64881826df5d0000000000000000000000000000000000000000000000000a271178207ab74c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc6657a6e3ee8ec7004dadd99a7a030b975556f8000000000000000000000000dc6657a6e3ee8ec7004dadd99a7a030b975556f80000000000000000000000000000000000000000000000000003fcb22a77bb4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4184,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1cebd3e2e2317b420bbf1808eabda450b20225c000000000000000000000000c1cebd3e2e2317b420bbf1808eabda450b20225c0000000000000000000000000000000000000000000000000020666e25abb17b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4186,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e81669100000000000000000000000088b1950ea550d2425d47ade6c74b427343ce181000000000000000000000000088b1950ea550d2425d47ade6c74b427343ce1810000000000000000000000000000000000000000000000000009d07aa7312800000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4187,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd4fe8beefdabf942c9c3a4c3911991d4391add7000000000000000000000000bd4fe8beefdabf942c9c3a4c3911991d4391add7000000000000000000000000000000000000000000000000011c26f76d8a3bd800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4189,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000665551f558999ee17e09bfef3b678c6f6d399fdf000000000000000000000000665551f558999ee17e09bfef3b678c6f6d399fdf0000000000000000000000000000000000000000000000000064c58e646da20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4190,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fba1905f6d569a1c2d61d1b1fdecc7951aab37bf000000000000000000000000fba1905f6d569a1c2d61d1b1fdecc7951aab37bf00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4191,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9d2ee9ea9ab887b00aef85156f504ba1699ef5f000000000000000000000000b9d2ee9ea9ab887b00aef85156f504ba1699ef5f00000000000000000000000000000000000000000000000001537c55c9c214bd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4192,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052a1ee866213e20123d52a89d03b9aa89315460d00000000000000000000000052a1ee866213e20123d52a89d03b9aa89315460d000000000000000000000000000000000000000000000000001ef948416ddc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4193,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002fd20abab2ad403ce4246b82e9f078ec9e23979b0000000000000000000000002fd20abab2ad403ce4246b82e9f078ec9e23979b0000000000000000000000000000000000000000000000000000000001f4b38100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057b724f412bd00fde73c6113d8ec0ac1b3d79e9700000000000000000000000057b724f412bd00fde73c6113d8ec0ac1b3d79e9700000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4195,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1cf787e28e15423139045047e17cfb17142c5d0000000000000000000000000f1cf787e28e15423139045047e17cfb17142c5d000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4196,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f64ed0d305c8821e3f9d93e0fcec41e3eba9c013000000000000000000000000f64ed0d305c8821e3f9d93e0fcec41e3eba9c0130000000000000000000000000000000000000000000000000060b2b18eedb38300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4197,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d1a05cf8f23e2f6f9b0849c623a8437c410d2df0000000000000000000000005d1a05cf8f23e2f6f9b0849c623a8437c410d2df000000000000000000000000000000000000000000000000003520fef4d449c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4198,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071803170c1a0298c0ab62fcb540ae769949e495800000000000000000000000071803170c1a0298c0ab62fcb540ae769949e495800000000000000000000000000000000000000000000000000854f0f865f180000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4201,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b79ae7d5a9417d83cca3bf7a08a2a1e36600ec10000000000000000000000008b79ae7d5a9417d83cca3bf7a08a2a1e36600ec1000000000000000000000000000000000000000000000000001bc0895a772d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4202,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c046dacf5d6068585eb84720fb89fe6c69e37c20000000000000000000000002c046dacf5d6068585eb84720fb89fe6c69e37c2000000000000000000000000000000000000000000000000009ea8dfa325123f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4203,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057803326193f31bb7b45e5a7a6760476c8e199cb00000000000000000000000057803326193f31bb7b45e5a7a6760476c8e199cb0000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9c7b0c3cbab74892e22054dae909adf05e16e85000000000000000000000000c9c7b0c3cbab74892e22054dae909adf05e16e8500000000000000000000000000000000000000000000000000000002540be40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4205,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000005c9038b998debec6f7545925850c8ed1d55d89410000000000000000000000005c9038b998debec6f7545925850c8ed1d55d89410000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000639e482f52d9f8655e2fd4b3b2244c5ca6eba81c000000000000000000000000639e482f52d9f8655e2fd4b3b2244c5ca6eba81c0000000000000000000000000000000000000000000000000058a628267473e500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c8fec39aa6e80575bafe7e7b9a8b2e15762a7175000000000000000000000000c8fec39aa6e80575bafe7e7b9a8b2e15762a7175000000000000000000000000000000000000000000000000014df48080e3000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb775d1882cd4b4a86b1361e430b5640c9149888000000000000000000000000cb775d1882cd4b4a86b1361e430b5640c91498880000000000000000000000000000000000000000000000000142961e719b000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053db3491c03160d722f039f8361b16e9fcc1765800000000000000000000000053db3491c03160d722f039f8361b16e9fcc176580000000000000000000000000000000000000000000000000006fae9b03d39bb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0a491c43221e065b182659655920fe2fde3c57e000000000000000000000000e0a491c43221e065b182659655920fe2fde3c57e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4211,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015bb7a84eb873d5ea59013187e2f488b4955f7f600000000000000000000000015bb7a84eb873d5ea59013187e2f488b4955f7f6000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4212,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000947acb351394674cc17011c6c662d06ba2a06eee000000000000000000000000947acb351394674cc17011c6c662d06ba2a06eee000000000000000000000000000000000000000000000000003eededd74af18400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4214,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a984cf31de92eb079617338c288265120a56af0c000000000000000000000000a984cf31de92eb079617338c288265120a56af0c00000000000000000000000000000000000000000000000005d1f6ae9bcf1d4800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d682350bfa1e1db407d75e30e9c749dc02ddd110000000000000000000000008d682350bfa1e1db407d75e30e9c749dc02ddd11000000000000000000000000000000000000000000000000003351106247386e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd64b96f5e9a68abbd0cb3d11106c71c3d6abf12000000000000000000000000fd64b96f5e9a68abbd0cb3d11106c71c3d6abf120000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4217,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015bb7a84eb873d5ea59013187e2f488b4955f7f600000000000000000000000015bb7a84eb873d5ea59013187e2f488b4955f7f6000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000391181a69c0e69fad0c4c961c6791b3d5b2d0f6a000000000000000000000000391181a69c0e69fad0c4c961c6791b3d5b2d0f6a0000000000000000000000000000000000000000000000000000000003e9183500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015bb7a84eb873d5ea59013187e2f488b4955f7f600000000000000000000000015bb7a84eb873d5ea59013187e2f488b4955f7f600000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4220,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b06674d798d4d8c8eab9bf7f1ef2d94da5c19640000000000000000000000001b06674d798d4d8c8eab9bf7f1ef2d94da5c1964000000000000000000000000000000000000000000000000006a0d591df4b9ed00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000254fe50f65ce3bc5221ee251226e7f78631cd684000000000000000000000000254fe50f65ce3bc5221ee251226e7f78631cd684000000000000000000000000000000000000000000000000002ada524f275a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093f09282490c9b71c65e559c54be76c8d70a1e3f00000000000000000000000093f09282490c9b71c65e559c54be76c8d70a1e3f00000000000000000000000000000000000000000000000002c05a9c33a2b10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4223,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000003e05ea1732de84ce5122f4bafc2def475176c9200000000000000000000000003e05ea1732de84ce5122f4bafc2def475176c9200000000000000000000000000000000000000000000000000000000005dd48ec00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4224,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b692fe3764a3c7400a7c27732dbc1b0c6f0d07b0000000000000000000000001b692fe3764a3c7400a7c27732dbc1b0c6f0d07b00000000000000000000000000000000000000000000000000a2654c9babb48900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093d154116d1d9bb5080e9f0e919d71e2690ab8a200000000000000000000000093d154116d1d9bb5080e9f0e919d71e2690ab8a200000000000000000000000000000000000000000000000000a36d5a7341990000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4226,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006103169e4ebda70d28a8dc6fa8eced2f6c9b83000000000000000000000000006103169e4ebda70d28a8dc6fa8eced2f6c9b830000000000000000000000000000000000000000000000000000001b48eb57e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4228,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000526fa515c11251ab665040710e2e118ccfa04031000000000000000000000000526fa515c11251ab665040710e2e118ccfa0403100000000000000000000000000000000000000000000000005868377ee1c699d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4229,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a27fb641b4e2aa9ab98f5620ab6ce3de1aa7b870000000000000000000000000a27fb641b4e2aa9ab98f5620ab6ce3de1aa7b8700000000000000000000000000000000000000000000000001475c17bdfd70dd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4230,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000faed754f9108cd26d467e9752f4e30bb49cf4180000000000000000000000000faed754f9108cd26d467e9752f4e30bb49cf418000000000000000000000000000000000000000000000000001a515490262a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000017c0153066f0dfbdd15b3fab9a70890a13e6282000000000000000000000000017c0153066f0dfbdd15b3fab9a70890a13e62820000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb5e81182dcf7040e729ef39c46dffd62e30ea92000000000000000000000000cb5e81182dcf7040e729ef39c46dffd62e30ea9200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ac6074d198de1a36a9733e5c752196c792458b00000000000000000000000009ac6074d198de1a36a9733e5c752196c792458b0000000000000000000000000000000000000000000000000002b0ed62de6e96100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000003700b2cb2b79ef5166d54519b0e91bbe58ec69ed0000000000000000000000003700b2cb2b79ef5166d54519b0e91bbe58ec69ed0000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000190fbeb640480ce706df35c6a6a515543a079b62000000000000000000000000190fbeb640480ce706df35c6a6a515543a079b6200000000000000000000000000000000000000000000000000003691d6afc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f90c4ca068955811f6b57b953c552ed73946ab86000000000000000000000000f90c4ca068955811f6b57b953c552ed73946ab8600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050a92cf3a378ac7b4921e6a11b110b230fe2005500000000000000000000000050a92cf3a378ac7b4921e6a11b110b230fe2005500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f76ae976145fb249d51c6bdb4819cfa445f12501000000000000000000000000f76ae976145fb249d51c6bdb4819cfa445f12501000000000000000000000000000000000000000000000000001b86ecb23e030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd4fe8beefdabf942c9c3a4c3911991d4391add7000000000000000000000000bd4fe8beefdabf942c9c3a4c3911991d4391add70000000000000000000000000000000000000000000000000077d11bf46a114200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4271,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f90c4ca068955811f6b57b953c552ed73946ab86000000000000000000000000f90c4ca068955811f6b57b953c552ed73946ab8600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000941be76b1c8a44401d98b59144055d526586f36f000000000000000000000000941be76b1c8a44401d98b59144055d526586f36f0000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8672f2b380be795e8ac446d5c4e01648e56abed000000000000000000000000a8672f2b380be795e8ac446d5c4e01648e56abed00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061166703a196deb1e9cbbce6b8740b370396f36b00000000000000000000000061166703a196deb1e9cbbce6b8740b370396f36b000000000000000000000000000000000000000000000000038fcff4df133e3600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a305637fe35e193c341b4244218f292fecd0bed0000000000000000000000006a305637fe35e193c341b4244218f292fecd0bed00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4295,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000040ceaf006224a429f8dfeb593b480d34d636bade00000000000000000000000040ceaf006224a429f8dfeb593b480d34d636bade0000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd90f026b0acd019f52e97ccb0cf634b75e933e7000000000000000000000000dd90f026b0acd019f52e97ccb0cf634b75e933e70000000000000000000000000000000000000000000000000038c10f9205a13100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4325,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000928abfcdbef4acd34fc6196830fe193765ee13dd000000000000000000000000928abfcdbef4acd34fc6196830fe193765ee13dd0000000000000000000000000000000000000000000000000016f76d6e3f03d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009b97b677c70297accab2a91e345c121b51372fd00000000000000000000000009b97b677c70297accab2a91e345c121b51372fd000000000000000000000000000000000000000000000000001116fe33e36f5900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4342,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be1e0184b5812569cbb3bd6dcf95719575b03d87000000000000000000000000be1e0184b5812569cbb3bd6dcf95719575b03d87000000000000000000000000000000000000000000000000001072eba779714800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e795eb19b7248757dbe1e43fc77b527f51eb4c37000000000000000000000000e795eb19b7248757dbe1e43fc77b527f51eb4c37000000000000000000000000000000000000000000000000001081c60f02b08b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016b658270ac50c0063940ed287c401b3df7ccf7000000000000000000000000016b658270ac50c0063940ed287c401b3df7ccf7000000000000000000000000000000000000000000000000001515f192daf056e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4348,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d960344674d5386e7577db411172cfd2a242c600000000000000000000000005d960344674d5386e7577db411172cfd2a242c6000000000000000000000000000000000000000000000000000108a611965039000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4350,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067920f8552db96b7eca9ea26545811624f4d091a00000000000000000000000067920f8552db96b7eca9ea26545811624f4d091a00000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000844c6522a9e21ad82fbea22ad68aaf8fd32a5d57000000000000000000000000844c6522a9e21ad82fbea22ad68aaf8fd32a5d5700000000000000000000000000000000000000000000000002a3be74d411c06200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000292eae73323683763a558ec8c42c69b76f247e37000000000000000000000000292eae73323683763a558ec8c42c69b76f247e370000000000000000000000000000000000000000000000000010aa2831f9448100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4359,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6ef132ede48d791ca94b98cd5f5ecc5e55f181f000000000000000000000000c6ef132ede48d791ca94b98cd5f5ecc5e55f181f0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000edf5b6a5194eaa36726fefc8f8c6a4f8e739f54a000000000000000000000000edf5b6a5194eaa36726fefc8f8c6a4f8e739f54a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4362,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004af15e6cef17bd154e1c2b676cfce18fe0811e8e0000000000000000000000004af15e6cef17bd154e1c2b676cfce18fe0811e8e000000000000000000000000000000000000000000000000001118e5646aadf200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db743a2f9f47c615bfae18ddc5a51c59a4a70eef000000000000000000000000db743a2f9f47c615bfae18ddc5a51c59a4a70eef000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000549f890dc98320b1bd7012233178a1bba55a0d7f000000000000000000000000549f890dc98320b1bd7012233178a1bba55a0d7f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f25aba378c7bf5f90f47db14b8056ffa762b7221000000000000000000000000f25aba378c7bf5f90f47db14b8056ffa762b7221000000000000000000000000000000000000000000000000002ba9df9248778600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e341fbf7bbd43e06f4eadab1ad9e41b01b074bdb000000000000000000000000e341fbf7bbd43e06f4eadab1ad9e41b01b074bdb000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4382,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000128bc803a104748db0259c90867fcebfb4877a1d000000000000000000000000128bc803a104748db0259c90867fcebfb4877a1d00000000000000000000000000000000000000000000000000acded07d5c560000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d58045868c84793d378876d31e17d90124c82e05000000000000000000000000d58045868c84793d378876d31e17d90124c82e0500000000000000000000000000000000000000000000000000406fa757c1760000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc64f1b4a1d6854b8c014014621b4e579687fb2c000000000000000000000000fc64f1b4a1d6854b8c014014621b4e579687fb2c00000000000000000000000000000000000000000000000000186f478ebd259700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc132bbcaf8fefd6ed55c05ffa8d1021a222f119000000000000000000000000cc132bbcaf8fefd6ed55c05ffa8d1021a222f1190000000000000000000000000000000000000000000000000061b4a73c15ee2b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d829e171dd8e86279d89dc9a7f5ad7ffbad5a86a000000000000000000000000d829e171dd8e86279d89dc9a7f5ad7ffbad5a86a000000000000000000000000000000000000000000000000004e50d8cf7e02c600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4397,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007daa0065dd5bcc24d8829ed3c6281b846387d6040000000000000000000000007daa0065dd5bcc24d8829ed3c6281b846387d60400000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000135cd9223f46b2287d593afceb278224d9a5da2e000000000000000000000000135cd9223f46b2287d593afceb278224d9a5da2e000000000000000000000000000000000000000000000000001907b66e23721500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf8c84f4fa5861d718271d0a676e53a5d7922c61000000000000000000000000cf8c84f4fa5861d718271d0a676e53a5d7922c6100000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a01ec139b82e3e04fc4430317b442800b747fc09000000000000000000000000a01ec139b82e3e04fc4430317b442800b747fc0900000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da01a63a39c5caaad82c18d5640edc74dd08f016000000000000000000000000da01a63a39c5caaad82c18d5640edc74dd08f01600000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016a2f972d8b163f56830834a994159c268e5a6d000000000000000000000000016a2f972d8b163f56830834a994159c268e5a6d000000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c61edc942bb6a5fca34a207d1d08e2caccbb93c0000000000000000000000002c61edc942bb6a5fca34a207d1d08e2caccbb93c000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000136ba2f844d4a88fba2f961329ee01d8eb217d2b000000000000000000000000136ba2f844d4a88fba2f961329ee01d8eb217d2b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4413,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005346ad8067250f4a579ade87201ff309533640f80000000000000000000000005346ad8067250f4a579ade87201ff309533640f8000000000000000000000000000000000000000000000000001a171a93f43b3600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a3d37e257919ee3f59f7fcb776510e332e3aebf0000000000000000000000001a3d37e257919ee3f59f7fcb776510e332e3aebf00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4423,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002891d57e0d43d01b1e5e4f0fdbf246ebe6ffecd40000000000000000000000002891d57e0d43d01b1e5e4f0fdbf246ebe6ffecd400000000000000000000000000000000000000000000000000a00128ef49310700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4425,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000811a6fdd51dc16ca90beec8cc1575cf55c55a6f8000000000000000000000000811a6fdd51dc16ca90beec8cc1575cf55c55a6f80000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e3cbd67b2e89cb57fd3dc852484136ec768dd680000000000000000000000000e3cbd67b2e89cb57fd3dc852484136ec768dd68000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047e282d7b1737592b034fef7b427cef8f5a820e600000000000000000000000047e282d7b1737592b034fef7b427cef8f5a820e6000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3e66a4e786fcf397c6c33c3a973a1105363eb40000000000000000000000000a3e66a4e786fcf397c6c33c3a973a1105363eb400000000000000000000000000000000000000000000000000003e871b540c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d92b8841178d8a314c845da46276097c37c6c76b000000000000000000000000d92b8841178d8a314c845da46276097c37c6c76b00000000000000000000000000000000000000000000000001485aaad7bb8e5100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4438,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d9f6a085af7acb73e01fe334180c4e9ef5532c80000000000000000000000002d9f6a085af7acb73e01fe334180c4e9ef5532c800000000000000000000000000000000000000000000000000336e152e3e65d500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a93bfb17b9d9edd76539041f563eecf6e0523c9e000000000000000000000000a93bfb17b9d9edd76539041f563eecf6e0523c9e000000000000000000000000000000000000000000000000003c6568f12e800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f5d8ba12af7681206be37cee36d2fbd4ebff3f40000000000000000000000006f5d8ba12af7681206be37cee36d2fbd4ebff3f4000000000000000000000000000000000000000000000000003b858e468fa14200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000982fc54604b391a11211543014711f12b843110a000000000000000000000000982fc54604b391a11211543014711f12b843110a0000000000000000000000000000000000000000000000000060a4609196978e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4455,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002587a07278d72481d1d1d768b4e22abee7c4c8250000000000000000000000002587a07278d72481d1d1d768b4e22abee7c4c82500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aebc6fd1db7c9a882248b1078569b2eb85218363000000000000000000000000aebc6fd1db7c9a882248b1078569b2eb852183630000000000000000000000000000000000000000000000000151970c759ada2600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000e1ac9a2272185c546f8e2f7852a3adfdd91f8300000000000000000000000000e1ac9a2272185c546f8e2f7852a3adfdd91f8300000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ca8339fb523b86526efa90a4b305e1a75068ac15000000000000000000000000ca8339fb523b86526efa90a4b305e1a75068ac15000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029a5c9e2226bc78fccecb4f9ef50bbfc6a86c24200000000000000000000000029a5c9e2226bc78fccecb4f9ef50bbfc6a86c2420000000000000000000000000000000000000000000000000151970c759ada2600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b84604433c16105afb4e33495e7e64c4b71d1824000000000000000000000000b84604433c16105afb4e33495e7e64c4b71d18240000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b569fb627ca1e0b51b0a405c456328005019053f000000000000000000000000b569fb627ca1e0b51b0a405c456328005019053f00000000000000000000000000000000000000000000000000a650caee92393900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4464,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009a6d6640555dbb959466d574402da12fa56fe8f00000000000000000000000009a6d6640555dbb959466d574402da12fa56fe8f000000000000000000000000000000000000000000000000013c2feac60a8c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xed03f507528873b7016df194117900bcb9c2c2fab013051bd38ddf956c5b8ba4,2021-12-12 05:27:46.000 UTC,0,true +4465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075ea7a4301c676b3ef194f00643e40a6ff5c508400000000000000000000000075ea7a4301c676b3ef194f00643e40a6ff5c508400000000000000000000000000000000000000000000000000a6052714bf6f0100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f531b9b9cddb5394f3577e34807220e410809093000000000000000000000000f531b9b9cddb5394f3577e34807220e41080909300000000000000000000000000000000000000000000000000edd0d7cea903bf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004f8ffeed97d56242424b0fabe846fd1627002a600000000000000000000000004f8ffeed97d56242424b0fabe846fd1627002a60000000000000000000000000000000000000000000000000153b0525a28a62300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c6b63b05696bbe015f28f4315e470a98e7c48f40000000000000000000000008c6b63b05696bbe015f28f4315e470a98e7c48f4000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086dac5a07e05a3caadf86c1ad9681bd23ca8221500000000000000000000000086dac5a07e05a3caadf86c1ad9681bd23ca822150000000000000000000000000000000000000000000000000014a8a7dbd9633e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4478,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc7fd26298a95b5a6a305c6330513261a0108597000000000000000000000000cc7fd26298a95b5a6a305c6330513261a0108597000000000000000000000000000000000000000000000000001cb46d7be4c57f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4480,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000255749ce8ab1dd14c09787e7405a15ff17c24459000000000000000000000000255749ce8ab1dd14c09787e7405a15ff17c2445900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a6e21fbf6cf82dcfc804602c6f9857c24c80c590000000000000000000000001a6e21fbf6cf82dcfc804602c6f9857c24c80c590000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000466cfe385d25ddc6ef7ffa1fd16d2fd75362146d000000000000000000000000466cfe385d25ddc6ef7ffa1fd16d2fd75362146d00000000000000000000000000000000000000000000000000597e53f5dce96900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bb006840ec39d2bc8e9c8766aec6cfc0161c2330000000000000000000000001bb006840ec39d2bc8e9c8766aec6cfc0161c233000000000000000000000000000000000000000000000000003445407c807f6b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc57c1cbe7ef62f873d452a2a9f430b2e174f2dabf180758b3fe636dd07504ca8,2022-03-12 12:10:48.000 UTC,0,true +4506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df1c13b1fffa2ac5984516719cbdbfa22240efbb000000000000000000000000df1c13b1fffa2ac5984516719cbdbfa22240efbb000000000000000000000000000000000000000000000000006f96d8ea35f8d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4509,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b1df9010790002f57090902c78292cc7e7d948a0000000000000000000000002b1df9010790002f57090902c78292cc7e7d948a000000000000000000000000000000000000000000000000025bf6196bd1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4511,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000006f398ce76acc1fce97b7cab0eb2a96ba9230c9b00000000000000000000000000000000000000000000000098a7d9b8314c0000,,,1,true +4515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003605c9fe039f3bdacbc2003a33b2586f7bfb67000000000000000000000000003605c9fe039f3bdacbc2003a33b2586f7bfb6700000000000000000000000000000000000000000000000000003972878204a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f3582b06b6697fd64e791ab7ace882fe66bc8350000000000000000000000005f3582b06b6697fd64e791ab7ace882fe66bc83500000000000000000000000000000000000000000000000002b7ea9f4ac5307e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4520,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000952f28087fd8df38251ea862e300dd8260ad0feb000000000000000000000000952f28087fd8df38251ea862e300dd8260ad0feb0000000000000000000000000000000000000000000000000012d763c766a05100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4521,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043469718666fbf0d76d53d1aa5e8adaa51aa03c500000000000000000000000043469718666fbf0d76d53d1aa5e8adaa51aa03c5000000000000000000000000000000000000000000000000004262dd2c37010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4523,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f66c88f9c59a78b3b5435838aeb0465a0805c011000000000000000000000000f66c88f9c59a78b3b5435838aeb0465a0805c01100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4525,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1912c7917b6da214a7118d323c3049229d765b3000000000000000000000000f1912c7917b6da214a7118d323c3049229d765b300000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4526,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d317e99e1d2357c6d61568f7e23f95f31eb132d5000000000000000000000000d317e99e1d2357c6d61568f7e23f95f31eb132d5000000000000000000000000000000000000000000000000005d11f25948917e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4527,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005030a9280a75cb91cc70d0bf3b02c14d3b01d3270000000000000000000000005030a9280a75cb91cc70d0bf3b02c14d3b01d32700000000000000000000000000000000000000000000000000422c5410b3d80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032360705da597f8c77c67e46986818e199f2d44100000000000000000000000032360705da597f8c77c67e46986818e199f2d441000000000000000000000000000000000000000000000000023428a2fc92712300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015591129be9019d57fd6439525b8517d616e8c8f00000000000000000000000015591129be9019d57fd6439525b8517d616e8c8f0000000000000000000000000000000000000000000000000155cd19a78f21d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4530,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b90adc44da6c179c7d2c048d2cffb7c80c1620f9000000000000000000000000b90adc44da6c179c7d2c048d2cffb7c80c1620f900000000000000000000000000000000000000000000000000a5bf634083be5500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe75966551cea0792d65d3b72e4a82918d2675f1000000000000000000000000fe75966551cea0792d65d3b72e4a82918d2675f10000000000000000000000000000000000000000000000000000f85b2a300d7400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4532,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c2b60bcb07410427dc1c6a1328c0dea1d7c9baa0000000000000000000000004c2b60bcb07410427dc1c6a1328c0dea1d7c9baa0000000000000000000000000000000000000000000000000001e7c1d2a2fe9b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d8b8f4ad3e18983e9fe2ca59d03acd8dac9e0000000000000000000000000005d8b8f4ad3e18983e9fe2ca59d03acd8dac9e0000000000000000000000000000000000000000000000000000081b6280f0678bd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4534,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbfc958e0d464459edaf31beea4ebf6fcb9614e7000000000000000000000000fbfc958e0d464459edaf31beea4ebf6fcb9614e7000000000000000000000000000000000000000000000000000e1d7cbe6e507f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000514f2c26d7c56c0857dceb5f84fb875d315f7a09000000000000000000000000514f2c26d7c56c0857dceb5f84fb875d315f7a09000000000000000000000000000000000000000000000000001f91b3c2d5df0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003652f12c39a23dcb0d1e51a98736ec6334f902990000000000000000000000003652f12c39a23dcb0d1e51a98736ec6334f9029900000000000000000000000000000000000000000000000000a5a43afc15541b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbb30c604b349078f2ee48e4649ee682898d0d6f000000000000000000000000cbb30c604b349078f2ee48e4649ee682898d0d6f0000000000000000000000000000000000000000000000000039b387761ee11700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045e508aaf9267855e05f93793c9979b0ffc2975000000000000000000000000045e508aaf9267855e05f93793c9979b0ffc2975000000000000000000000000000000000000000000000000000eaa0e2731f687800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2658d224b9f1ec2cdeb6400730a57dafbba9ac9000000000000000000000000e2658d224b9f1ec2cdeb6400730a57dafbba9ac900000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008615a0536bddc38701560a4b577b4b7c505e4f980000000000000000000000008615a0536bddc38701560a4b577b4b7c505e4f9800000000000000000000000000000000000000000000000001551f8750ba84ed00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4542,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000618ae54643d161d19cd2e2249dd5be383cd44a69000000000000000000000000618ae54643d161d19cd2e2249dd5be383cd44a69000000000000000000000000000000000000000000000000010eb0ee0d6f2a4b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007002f465c7ab3d7433d4b90cb2fac271ae03d34c0000000000000000000000007002f465c7ab3d7433d4b90cb2fac271ae03d34c000000000000000000000000000000000000000000000000010eea438fbffc9600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008595ec582c6dc4aed52f4550f734be56d59967ce0000000000000000000000008595ec582c6dc4aed52f4550f734be56d59967ce00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4545,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f6e4525899f4dd05e8532bc2afff78313840aeb0000000000000000000000002f6e4525899f4dd05e8532bc2afff78313840aeb000000000000000000000000000000000000000000000000010ddf1fad6e152300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4546,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075c328b104580b2bd9153e9dd0037742d006690a00000000000000000000000075c328b104580b2bd9153e9dd0037742d006690a00000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009c653c6683dcaf67db2980041d116ef48ad91b500000000000000000000000009c653c6683dcaf67db2980041d116ef48ad91b5000000000000000000000000000000000000000000000000010cedb6b12901c600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4548,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b4073b13dab3f671e28e3fbcada9a9c5ffc3fc40000000000000000000000001b4073b13dab3f671e28e3fbcada9a9c5ffc3fc40000000000000000000000000000000000000000000000000154394a8595f7fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df1448337af7529a3b2086982e9916c1a0f96c7b000000000000000000000000df1448337af7529a3b2086982e9916c1a0f96c7b00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4550,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a3f01f0d2bbc0cf1f58a5c40aaf8b95d5cf437a0000000000000000000000007a3f01f0d2bbc0cf1f58a5c40aaf8b95d5cf437a000000000000000000000000000000000000000000000000010c51b85b9a9dea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b7b2da7d40db2e07ce7bacdc10eb88a24829c910000000000000000000000005b7b2da7d40db2e07ce7bacdc10eb88a24829c91000000000000000000000000000000000000000000000000010c51b85b9a9dea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003404fad8173217d296883be88c7ff401d12d7a560000000000000000000000003404fad8173217d296883be88c7ff401d12d7a5600000000000000000000000000000000000000000000000000eb3d9deb81370100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3618500c58cc7993e42cc05aea9469fa5458acf000000000000000000000000b3618500c58cc7993e42cc05aea9469fa5458acf00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000340eecc4e7b04a063e31dbf041c5211f7a7fb7b0000000000000000000000000340eecc4e7b04a063e31dbf041c5211f7a7fb7b000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc4af6320db7e65e0ee251e081deaacaae0920f8000000000000000000000000fc4af6320db7e65e0ee251e081deaacaae0920f8000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000340eecc4e7b04a063e31dbf041c5211f7a7fb7b0000000000000000000000000340eecc4e7b04a063e31dbf041c5211f7a7fb7b000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c739d8aafc091735c9996dcb940023eb23528fed000000000000000000000000c739d8aafc091735c9996dcb940023eb23528fed0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013293a9b2d51dc0f82a695d8c2809318df57235500000000000000000000000013293a9b2d51dc0f82a695d8c2809318df57235500000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fca872ffe467c4983d75148f7584f3afd7877927000000000000000000000000fca872ffe467c4983d75148f7584f3afd787792700000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f2076030aab9e7f83c30c210e37af594b10497e0000000000000000000000000f2076030aab9e7f83c30c210e37af594b10497e00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4562,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000340eecc4e7b04a063e31dbf041c5211f7a7fb7b0000000000000000000000000340eecc4e7b04a063e31dbf041c5211f7a7fb7b00000000000000000000000000000000000000000000000000000000000004e2000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5eeb2692bbb03932d7b645aa65fc4f5261e5c52000000000000000000000000d5eeb2692bbb03932d7b645aa65fc4f5261e5c5200000000000000000000000000000000000000000000000000878ee35577f02e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7e7c33cd3bf10a7f60b8b539217d2d9ac42e93b000000000000000000000000d7e7c33cd3bf10a7f60b8b539217d2d9ac42e93b000000000000000000000000000000000000000000000000004b718aa0bc3f6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4565,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055c3a72eff435c46abc1726c7f945050806eabd500000000000000000000000055c3a72eff435c46abc1726c7f945050806eabd500000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4567,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008916fb668334de7548eaaa65f5a9c3c7aaaeda980000000000000000000000008916fb668334de7548eaaa65f5a9c3c7aaaeda98000000000000000000000000000000000000000000000000002fb743c0e0070000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4568,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cff30cb947670f57631fe03e5e29cb5b0dfa1480000000000000000000000005cff30cb947670f57631fe03e5e29cb5b0dfa14800000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4569,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002828b1cd64ce9cd865f6cb8cc1427c5b05d665160000000000000000000000002828b1cd64ce9cd865f6cb8cc1427c5b05d6651600000000000000000000000000000000000000000000000000453d19ac94a68000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4570,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033bd157a226ff92e3184a5955938327b4d0785f400000000000000000000000033bd157a226ff92e3184a5955938327b4d0785f400000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c942a745f881b58891a853d8a41172b30b726967000000000000000000000000c942a745f881b58891a853d8a41172b30b726967000000000000000000000000000000000000000000000000003ac94eecef7c1500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4574,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7676a93a10350518fc2804cd023cf19084920d8000000000000000000000000f7676a93a10350518fc2804cd023cf19084920d800000000000000000000000000000000000000000000000002c19f06e46d490000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4575,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043e4148d51f72f5d01be90632ea4a3bce0834f1700000000000000000000000043e4148d51f72f5d01be90632ea4a3bce0834f170000000000000000000000000000000000000000000000000014f31f314ec1be00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4576,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063ded784c8da63a79ee47f9a53bcb1bad1d9f3e000000000000000000000000063ded784c8da63a79ee47f9a53bcb1bad1d9f3e000000000000000000000000000000000000000000000000000a0a145a3e5e20700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3d1d153fd90347c4e48f9611503524e9162598f000000000000000000000000a3d1d153fd90347c4e48f9611503524e9162598f0000000000000000000000000000000000000000000000000235a164dd2b9e8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2de88aae74121a05b8ecf066eac4e6ec404a92e000000000000000000000000c2de88aae74121a05b8ecf066eac4e6ec404a92e00000000000000000000000000000000000000000000000000230133f16f603f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4579,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f18ff2dc14ead656227349209119c0cc5079f00e000000000000000000000000f18ff2dc14ead656227349209119c0cc5079f00e0000000000000000000000000000000000000000000000000003e1e44a99dc5f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4580,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b43310714f0eaf3ef00f59d1cb960b9f0a2864f2000000000000000000000000b43310714f0eaf3ef00f59d1cb960b9f0a2864f200000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4581,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d01b7ff2b2544529ee092240d406051756607260000000000000000000000000d01b7ff2b2544529ee092240d40605175660726000000000000000000000000000000000000000000000000009bad5fbccb58db00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4582,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004743ed9e06fe530798654e27db3508fa146836710000000000000000000000004743ed9e06fe530798654e27db3508fa1468367100000000000000000000000000000000000000000000000000a9688a982d930000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4584,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022014722f748564486414ec1c73c70f6c6484e3d00000000000000000000000022014722f748564486414ec1c73c70f6c6484e3d000000000000000000000000000000000000000000000000001749b0b45fc33500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a054517dab4695751c5276148a29a245c2163550000000000000000000000000a054517dab4695751c5276148a29a245c2163550000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4587,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085f5b414aaf84ec70cb54cc84682cfe9e69d3c2900000000000000000000000085f5b414aaf84ec70cb54cc84682cfe9e69d3c29000000000000000000000000000000000000000000000000006379da05b6000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4588,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa833a5540c3520582dca433013046a3cb1c3603000000000000000000000000fa833a5540c3520582dca433013046a3cb1c360300000000000000000000000000000000000000000000000000950bff17947ff500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4589,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b9bd441e853d180d9749315619fe1c4786f866ad000000000000000000000000b9bd441e853d180d9749315619fe1c4786f866ad00000000000000000000000000000000000000000000000000000000000001f200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4590,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fd6fa501ec50109c6f0f7d848941df9dae44b4b0000000000000000000000000fd6fa501ec50109c6f0f7d848941df9dae44b4b0000000000000000000000000000000000000000000000000043cc3f67ade4d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4592,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4f6cecae5c1292ccc6e7d5cb99f45275fffa771000000000000000000000000f4f6cecae5c1292ccc6e7d5cb99f45275fffa771000000000000000000000000000000000000000000000000005bbb04035f625500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4593,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000511fb72e1b71eedc17f11b79fd262c66fbe1c235000000000000000000000000511fb72e1b71eedc17f11b79fd262c66fbe1c23500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4595,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f098f3429d43d080ba0c8ec27a1ab7dbcfb85f10000000000000000000000004f098f3429d43d080ba0c8ec27a1ab7dbcfb85f100000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4597,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f098f3429d43d080ba0c8ec27a1ab7dbcfb85f10000000000000000000000004f098f3429d43d080ba0c8ec27a1ab7dbcfb85f100000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4598,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dce620ed8be234b948bcea5694d543d4f7c5438d000000000000000000000000dce620ed8be234b948bcea5694d543d4f7c5438d000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005675e8037a4c0e32ba06124313680bdd3393c90f0000000000000000000000005675e8037a4c0e32ba06124313680bdd3393c90f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4600,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e44fce3fdd9ea80ef3e6242121a76d08dcb31d20000000000000000000000002e44fce3fdd9ea80ef3e6242121a76d08dcb31d2000000000000000000000000000000000000000000000000005e50b7c568840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4601,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093493ee5a1dc42a1ab6581add73dc2a22fa28cb600000000000000000000000093493ee5a1dc42a1ab6581add73dc2a22fa28cb60000000000000000000000000000000000000000000000000156512561d47e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4602,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6991fa0ac2e1276f645a84de8629d3bcf5a451b000000000000000000000000e6991fa0ac2e1276f645a84de8629d3bcf5a451b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4603,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f44f957c6cae5adab9bbdb384e5a9b6175bad3f0000000000000000000000004f44f957c6cae5adab9bbdb384e5a9b6175bad3f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4604,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000881057ff08da8464d044bb839bd914daff95a4a5000000000000000000000000881057ff08da8464d044bb839bd914daff95a4a500000000000000000000000000000000000000000000000722bdd19b6c075b8600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x810bd9369ed5c762dde5876f844ff6cd0e5f27509168be3d6009900a4df994ca,2022-03-20 08:42:00.000 UTC,0,true +4605,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f44f957c6cae5adab9bbdb384e5a9b6175bad3f0000000000000000000000004f44f957c6cae5adab9bbdb384e5a9b6175bad3f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4607,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b55031d7272324ade1960dcbb916ad6fbbe6ca40000000000000000000000003b55031d7272324ade1960dcbb916ad6fbbe6ca40000000000000000000000000000000000000000000000000155de33a9cfcd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4608,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028caead6b34e86e9e37c816e5143c1d072a90f3000000000000000000000000028caead6b34e86e9e37c816e5143c1d072a90f3000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b436f6d8db824a46524610bbf67463f822376390000000000000000000000004b436f6d8db824a46524610bbf67463f8223763900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4610,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f46da3e42ffa142be596d5bd81d464e99edca3d6000000000000000000000000f46da3e42ffa142be596d5bd81d464e99edca3d600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4611,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2c67be3dbe29ce0273b0e6876a00e1e0f52dcf0000000000000000000000000a2c67be3dbe29ce0273b0e6876a00e1e0f52dcf000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4612,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000188632ee3c4e8c7b3e4a7f1315e1b0e1e8db4f00000000000000000000000000188632ee3c4e8c7b3e4a7f1315e1b0e1e8db4f000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4613,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bb84c87410baa2836a3b4271c25cce24ba5119b0000000000000000000000004bb84c87410baa2836a3b4271c25cce24ba5119b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4615,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdd974c9081b38392fc2ea125f933666f0cb25b7000000000000000000000000bdd974c9081b38392fc2ea125f933666f0cb25b700000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea3803125845d12ea9a1e5f882198d7bb796ace8000000000000000000000000ea3803125845d12ea9a1e5f882198d7bb796ace800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4617,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061365358ff2bcc08cf81f22b37d97ab3d8c9924000000000000000000000000061365358ff2bcc08cf81f22b37d97ab3d8c99240000000000000000000000000000000000000000000000000004a2a1962946af400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4618,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000657359a2a5d4ce8cfbca626974c0583d59b072cc000000000000000000000000657359a2a5d4ce8cfbca626974c0583d59b072cc00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a9f489a464a5818f4bcea5b02d149eafa8e6c7d0000000000000000000000005a9f489a464a5818f4bcea5b02d149eafa8e6c7d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xdd3844b58cc9690689eb793943820248680041ad57ac66047f723744d50e8b47,2022-02-05 12:03:31.000 UTC,0,true +4622,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce34e2d460771465ed2632e61fe5c4786c9ab631000000000000000000000000ce34e2d460771465ed2632e61fe5c4786c9ab6310000000000000000000000000000000000000000000000000143fa62d016580a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4624,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df7df9267d415da4f85db9b14c8a7ecb6f093560000000000000000000000000df7df9267d415da4f85db9b14c8a7ecb6f093560000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006dbfea06f4151be174ed028870bf84256d98fd210000000000000000000000006dbfea06f4151be174ed028870bf84256d98fd210000000000000000000000000000000000000000000000000019de62d821790000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6780b375cae098a3bb5c465753e57386d0f7023000000000000000000000000a6780b375cae098a3bb5c465753e57386d0f7023000000000000000000000000000000000000000000000000007fb3ac485c2b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7c31c0279ebe723922f1a5864d8c8a4a0a2810d000000000000000000000000f7c31c0279ebe723922f1a5864d8c8a4a0a2810d0000000000000000000000000000000000000000000000000016884418270b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee7dfb575538c2d33783fdef89dc18de0ffd09e1000000000000000000000000ee7dfb575538c2d33783fdef89dc18de0ffd09e10000000000000000000000000000000000000000000000000016841229ba7e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff0ed05999292f9c586db005e5992aa7289ac2f1000000000000000000000000ff0ed05999292f9c586db005e5992aa7289ac2f10000000000000000000000000000000000000000000000000016841229ba7e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4630,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004826af4b70b248fd9377615ec4409d92cbe5a9fd0000000000000000000000004826af4b70b248fd9377615ec4409d92cbe5a9fd00000000000000000000000000000000000000000000000000084e1796a07e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a13b69bb3cd138757f58c59c16eed00b43cc60f0000000000000000000000006a13b69bb3cd138757f58c59c16eed00b43cc60f0000000000000000000000000000000000000000000000000012f8411785d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cac2ad175c5b87be2b45688c9f64b74ddfa2d1b0000000000000000000000007cac2ad175c5b87be2b45688c9f64b74ddfa2d1b000000000000000000000000000000000000000000000000000bdd43cdf8d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045026d1eb0212a7cf9ff202f7abd0ac06778597800000000000000000000000045026d1eb0212a7cf9ff202f7abd0ac06778597800000000000000000000000000000000000000000000000000034fbb6ccf09e500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d0b2b774a915cb4b1ef7fc433dd48fd186e0d251000000000000000000000000d0b2b774a915cb4b1ef7fc433dd48fd186e0d2510000000000000000000000000000000000000000000000000013a17452a0070000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073b919fbeb9b767466c254b9c438f00c2ace0ff500000000000000000000000073b919fbeb9b767466c254b9c438f00c2ace0ff50000000000000000000000000000000000000000000000000013a17452a0070000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4636,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea0d1c1b2807613c72ea2b8940674ed599b5d724000000000000000000000000ea0d1c1b2807613c72ea2b8940674ed599b5d72400000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e80dc71b16c059edf302e1d5b151a537696e03da000000000000000000000000e80dc71b16c059edf302e1d5b151a537696e03da00000000000000000000000000000000000000000000000000066327c7fe069700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4639,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f521d0b62a19d3227e16acc4a8b93ace6f76132e000000000000000000000000f521d0b62a19d3227e16acc4a8b93ace6f76132e000000000000000000000000000000000000000000000000000a0b38dc6ac8f900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045026d1eb0212a7cf9ff202f7abd0ac06778597800000000000000000000000045026d1eb0212a7cf9ff202f7abd0ac06778597800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b173e192bde6c29bf42b3777b024df38e56663eb000000000000000000000000b173e192bde6c29bf42b3777b024df38e56663eb00000000000000000000000000000000000000000000000000524886156d2a9800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f351d019ba2727168b9b53331216a927b87fb95d000000000000000000000000f351d019ba2727168b9b53331216a927b87fb95d000000000000000000000000000000000000000000000000017f373a83613d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4644,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c81fb1989d329ae0ab48fa69494c26bf244cf50b000000000000000000000000c81fb1989d329ae0ab48fa69494c26bf244cf50b0000000000000000000000000000000000000000000000000098e5d97c95e83a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4645,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c12bbd6f806a33406c33e6ad708bf20162269924000000000000000000000000c12bbd6f806a33406c33e6ad708bf20162269924000000000000000000000000000000000000000000000000000000000000091200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4646,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7cd438311c7919adc2475b50c9aaffd89ec76d9000000000000000000000000f7cd438311c7919adc2475b50c9aaffd89ec76d9000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4647,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dccddb7432b7371745233410c943f4882df07937000000000000000000000000dccddb7432b7371745233410c943f4882df0793700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4648,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e4ebf512413efb8902929fda582a8619928210e8000000000000000000000000e4ebf512413efb8902929fda582a8619928210e8000000000000000000000000000000000000000000000000000000000000065100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4650,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b800cf62d8017003d56aa100359253f478121c54000000000000000000000000b800cf62d8017003d56aa100359253f478121c540000000000000000000000000000000000000000000000000000000000000e4500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4651,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060c8a712ad7995eee20945c174cec13a8228eabc00000000000000000000000060c8a712ad7995eee20945c174cec13a8228eabc000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4652,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a29ea6dea81530b173a29cd3815be9868285e438000000000000000000000000a29ea6dea81530b173a29cd3815be9868285e43800000000000000000000000000000000000000000000000000b91d6c2e956c6800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff9f20367488f3386a97bc3897798b0e8bd1b2da000000000000000000000000ff9f20367488f3386a97bc3897798b0e8bd1b2da000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4655,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004aef5372bf1cc6b50be36dbe09038fa6c34db05c0000000000000000000000004aef5372bf1cc6b50be36dbe09038fa6c34db05c000000000000000000000000000000000000000000000000000000000000049f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2c5b9949add165aa74b784a55b14ab57e8845d5000000000000000000000000f2c5b9949add165aa74b784a55b14ab57e8845d5000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000007da0e97cb78832463914392b5d414c1befa1fb010000000000000000000000007da0e97cb78832463914392b5d414c1befa1fb01000000000000000000000000000000000000000000000000000000000032825100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000491d7f48150522596262d677792306732863b0ef000000000000000000000000491d7f48150522596262d677792306732863b0ef00000000000000000000000000000000000000000000000000998737e2cb495000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4660,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007c9bae1d479858ef7dde063c0cce31f1ec2fbcb00000000000000000000000007c9bae1d479858ef7dde063c0cce31f1ec2fbcb0000000000000000000000000000000000000000000000000051aa3873ec5e9700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4663,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c60d93b1a9bcce3791c53d05d63e41fa7a67aa10000000000000000000000008c60d93b1a9bcce3791c53d05d63e41fa7a67aa1000000000000000000000000000000000000000000000000002bf6299af051dc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff9ddb1f1a0174ff61c935232b2c84c122c4d7d8000000000000000000000000ff9ddb1f1a0174ff61c935232b2c84c122c4d7d800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4666,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003dc2ff9d48cd59085b37cbaae8d56948780373600000000000000000000000003dc2ff9d48cd59085b37cbaae8d56948780373600000000000000000000000000000000000000000000000000524d9e87e7c05700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ae3f69994b090f2531ae452c20c5a573ed8d81e0000000000000000000000004ae3f69994b090f2531ae452c20c5a573ed8d81e00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4669,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063496a256167a704445108df3da25a3e8f1a4de300000000000000000000000063496a256167a704445108df3da25a3e8f1a4de3000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4670,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000100f82b00e6488ae8c2c6cda5f3162c0fc0107da000000000000000000000000100f82b00e6488ae8c2c6cda5f3162c0fc0107da00000000000000000000000000000000000000000000000000a025b14927e11d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x47f8bafbbd4811a8bb6ef5d35f41be99e56befb6aa95f3db93d0b16a8c9b1145,2022-05-07 12:37:46.000 UTC,0,true +4672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc34cb3b39ee317e1f353c71b4542ecbd23357f4000000000000000000000000bc34cb3b39ee317e1f353c71b4542ecbd23357f400000000000000000000000000000000000000000000000001151c96347b000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4673,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d88f2e415698f472b265d45f0bcc65f61c405b80000000000000000000000000d88f2e415698f472b265d45f0bcc65f61c405b8000000000000000000000000000000000000000000000000027f7d0bdb92000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4677,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000416365993481e52e0472e7417656276d4e147a00000000000000000000000000416365993481e52e0472e7417656276d4e147a000000000000000000000000000000000000000000000000000007428a3d7d935900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4678,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037f7ff1864f5d5cba2b63592656049f2d7d06fb400000000000000000000000037f7ff1864f5d5cba2b63592656049f2d7d06fb4000000000000000000000000000000000000000000000000002c0febc3181f9600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b36f1cd4ad753bc4034ef24f45b97606041f7066000000000000000000000000b36f1cd4ad753bc4034ef24f45b97606041f7066000000000000000000000000000000000000000000000000001ec9302bd03c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b89bdb7d7bf95273b0d783ee88980fbfc80a269f000000000000000000000000b89bdb7d7bf95273b0d783ee88980fbfc80a269f000000000000000000000000000000000000000000000000004ce03d590bb81f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4682,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001666859ff3c6e3bfcb6165be7a93141afefa8b6c0000000000000000000000001666859ff3c6e3bfcb6165be7a93141afefa8b6c000000000000000000000000000000000000000000000000001c72680ad8210000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4683,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007870cbe0a8dfd925988cc51a3707378018e96c130000000000000000000000007870cbe0a8dfd925988cc51a3707378018e96c13000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e72d65bfbc2d89662406037c860fa794ea914a50000000000000000000000005e72d65bfbc2d89662406037c860fa794ea914a50000000000000000000000000000000000000000000000000002c544cfdfac3a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4687,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007373f50c13ab510517edae5a632c9896e04ad46e0000000000000000000000007373f50c13ab510517edae5a632c9896e04ad46e0000000000000000000000000000000000000000000000000018e48641d0a88000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cfc429665e84fbe34c73caca17942decbd55bb00000000000000000000000002cfc429665e84fbe34c73caca17942decbd55bb0000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4689,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9de87ee602681da783dcb73bdd43e04a11a6f14000000000000000000000000f9de87ee602681da783dcb73bdd43e04a11a6f1400000000000000000000000000000000000000000000000001f4e4fb104dd60a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4690,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000655efb468c40ac277e2b4605f70c3063bae3f6c0000000000000000000000000655efb468c40ac277e2b4605f70c3063bae3f6c000000000000000000000000000000000000000000000000006d7e3a7f6235ed00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4691,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a928306c20bbe9a3adfda0243b562dad439b7860000000000000000000000007a928306c20bbe9a3adfda0243b562dad439b786000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4692,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027971daeb537ac9597cca37800ad64037fe53bac00000000000000000000000027971daeb537ac9597cca37800ad64037fe53bac000000000000000000000000000000000000000000000000003dfd235cfbf35b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058101605da53b9d7727677d1922ee752dde7fa9f00000000000000000000000058101605da53b9d7727677d1922ee752dde7fa9f00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4699,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ee4bb8cf037a6c88da5fc3e84f5e260984daeb30000000000000000000000005ee4bb8cf037a6c88da5fc3e84f5e260984daeb3000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4700,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089cdd0275599011b4eed9e168149b07aad983b2300000000000000000000000089cdd0275599011b4eed9e168149b07aad983b2300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4701,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c39dc8a181bf7ea6fd59f7883a43e1aa220b7d99000000000000000000000000c39dc8a181bf7ea6fd59f7883a43e1aa220b7d9900000000000000000000000000000000000000000000000001225bdfc6a0575c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd39664cbdafc960e3d022aa0c50ea1ec0c23d60000000000000000000000000fd39664cbdafc960e3d022aa0c50ea1ec0c23d6000000000000000000000000000000000000000000000000000026f1fa8f7e59d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4703,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089cdd0275599011b4eed9e168149b07aad983b2300000000000000000000000089cdd0275599011b4eed9e168149b07aad983b2300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006f4acf78fc4749051e2c3203ca21ed2afa7d39300000000000000000000000006f4acf78fc4749051e2c3203ca21ed2afa7d393000000000000000000000000000000000000000000000000006ac43025170d3600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000faa5d7211dfa5669948434efbf5e701b22625852000000000000000000000000faa5d7211dfa5669948434efbf5e701b22625852000000000000000000000000000000000000000000000000003b1671687d05fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac642a2dd6fbdbe118bf5ae8e5ef5d7f573a07e4000000000000000000000000ac642a2dd6fbdbe118bf5ae8e5ef5d7f573a07e4000000000000000000000000000000000000000000000000001f17df00fba6d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4707,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e84429bcdc2362e8af0c82aa7a02214cbf2b0eaf000000000000000000000000e84429bcdc2362e8af0c82aa7a02214cbf2b0eaf00000000000000000000000000000000000000000000000ad78ebc5ac620000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +4708,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e84429bcdc2362e8af0c82aa7a02214cbf2b0eaf000000000000000000000000e84429bcdc2362e8af0c82aa7a02214cbf2b0eaf0000000000000000000000000000000000000000000000000142a3635c5511c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4710,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c951c03c0f66a9e38110de89857d9d05c972f860000000000000000000000005c951c03c0f66a9e38110de89857d9d05c972f8600000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4711,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013f729864e43ea27ee473fb51ceabf3936f4ccef00000000000000000000000013f729864e43ea27ee473fb51ceabf3936f4ccef00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4712,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003834cd6774ccfcd3c865a39732d1d8b20abdad700000000000000000000000003834cd6774ccfcd3c865a39732d1d8b20abdad70000000000000000000000000000000000000000000000000050708e44eec39c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004743ed9e06fe530798654e27db3508fa146836710000000000000000000000004743ed9e06fe530798654e27db3508fa146836710000000000000000000000000000000000000000000000000045a3f57118602e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036e48e548c8ed0ae685bcba3ca37640870fc9ed100000000000000000000000036e48e548c8ed0ae685bcba3ca37640870fc9ed1000000000000000000000000000000000000000000000000005fe1346ab04c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x109bac4441f95254ad48117cf081251a8e1947959ef78b7b4305dcf14426797f,2022-03-15 08:25:53.000 UTC,0,true +4716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9cd2daac4e0ebcf2da51705a0f02eee13072c3c000000000000000000000000b9cd2daac4e0ebcf2da51705a0f02eee13072c3c00000000000000000000000000000000000000000000000001141c07aace4f4300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e37e33d1325122da5d901292e9b6bda142146000000000000000000000000000e37e33d1325122da5d901292e9b6bda1421460000000000000000000000000000000000000000000000000000220d4ce149553000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4718,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008db8b5cffaf0ab0bcc91906bf5a6739afd9058770000000000000000000000008db8b5cffaf0ab0bcc91906bf5a6739afd90587700000000000000000000000000000000000000000000000000420c32792d715800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4720,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a8f00438d53e09c3c5813d42cabf3c8a912cf700000000000000000000000008a8f00438d53e09c3c5813d42cabf3c8a912cf7000000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4721,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b937a4938eaef8d5525f156defb83a9382c4cc14000000000000000000000000b937a4938eaef8d5525f156defb83a9382c4cc1400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4724,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2a8a73cd8f888da3e8beba1fcacf50ab8be301f000000000000000000000000d2a8a73cd8f888da3e8beba1fcacf50ab8be301f0000000000000000000000000000000000000000000000000003e871b540c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4725,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c2cc945dcb203a4e88639dce34c647337503ae30000000000000000000000002c2cc945dcb203a4e88639dce34c647337503ae3000000000000000000000000000000000000000000000000003e5e2afb21c1ed00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4726,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab5b1148453093aa5d4c6cf6bb7b3a373b4ff620000000000000000000000000ab5b1148453093aa5d4c6cf6bb7b3a373b4ff620000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4727,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089c8121115955831056958861c6800f0298b820a00000000000000000000000089c8121115955831056958861c6800f0298b820a000000000000000000000000000000000000000000000000016799f60ae1ead600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5d3aec761a1bb488b5356307b70f328f0e339112dc367fcc06eb69983e430ff5,2022-04-23 09:43:47.000 UTC,0,true +4729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004454f2128db755031e43f63ed5113f93bfc70f130000000000000000000000004454f2128db755031e43f63ed5113f93bfc70f13000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4730,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4fdaf72796a7cdf40382a12a63b228088d755c2000000000000000000000000b4fdaf72796a7cdf40382a12a63b228088d755c2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4731,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003309ffbc8665d129a0dc3ffe1b1e9976445f60de0000000000000000000000003309ffbc8665d129a0dc3ffe1b1e9976445f60de000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ecd74bb8f8f5cdd94b1f429d03e2d16c31cb1d10000000000000000000000000ecd74bb8f8f5cdd94b1f429d03e2d16c31cb1d1000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4734,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000dbf317122027066b969b847a1e21d0bde4a1ee10000000000000000000000000dbf317122027066b969b847a1e21d0bde4a1ee1000000000000000000000000000000000000000000000000010ee8c900c3f34000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4735,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9f6ba779a33b8e230d5794e9e159b9122f78e08000000000000000000000000c9f6ba779a33b8e230d5794e9e159b9122f78e08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4736,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bb6fa6f73683f145c627ba1f46781b1a56817350000000000000000000000005bb6fa6f73683f145c627ba1f46781b1a5681735000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4737,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3405dc862b8acfca80f06c40a0287e351964557000000000000000000000000f3405dc862b8acfca80f06c40a0287e351964557000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c1ed8c5739c256bc1c7c32887bf4af86f4324f70000000000000000000000005c1ed8c5739c256bc1c7c32887bf4af86f4324f7000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c732272e39a7b9a628465098fda86968d3a7d740000000000000000000000000c732272e39a7b9a628465098fda86968d3a7d740000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4741,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd1ef68bff82f8501ad607567488fc03a4cb594d000000000000000000000000cd1ef68bff82f8501ad607567488fc03a4cb594d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000668689179097d44aa0919d0f2e3a8a9d539ca524000000000000000000000000668689179097d44aa0919d0f2e3a8a9d539ca524000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4743,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a4a8fff4c203387148bcaec54a82da00d4e2cba0000000000000000000000004a4a8fff4c203387148bcaec54a82da00d4e2cba000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4744,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049f5b222888775a0d45dc0ce38e462dcdc9c6f7300000000000000000000000049f5b222888775a0d45dc0ce38e462dcdc9c6f73000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044dd1c77393e95166ef23a0ec525efc6ea1da1a800000000000000000000000044dd1c77393e95166ef23a0ec525efc6ea1da1a8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4746,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c29fd8fb70c7b6bec53164f3e501686df90f67c0000000000000000000000004c29fd8fb70c7b6bec53164f3e501686df90f67c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc852fae19bf05c7b6135afa27a7ff168d8fbcaa000000000000000000000000cc852fae19bf05c7b6135afa27a7ff168d8fbcaa000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4748,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061fea594187504cfe6b148699a3ca5835572f3b900000000000000000000000061fea594187504cfe6b148699a3ca5835572f3b9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4749,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a18c44237322b8a6e2fd749e71817db64e62f9b1000000000000000000000000a18c44237322b8a6e2fd749e71817db64e62f9b1000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4750,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031df8042fee3fd9aafa4002b75d2555e249996a500000000000000000000000031df8042fee3fd9aafa4002b75d2555e249996a5000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4751,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d6bc66c28294abe7b1eec57caf17d1ec9b368220000000000000000000000004d6bc66c28294abe7b1eec57caf17d1ec9b36822000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8dbcde95465f64ab7db516c77f198e83030485c000000000000000000000000a8dbcde95465f64ab7db516c77f198e83030485c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4753,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a2d58ce3df52bd8e6d3f67ce476d034a7f30f0b0000000000000000000000006a2d58ce3df52bd8e6d3f67ce476d034a7f30f0b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4754,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca47c17967c740085df98db42c65fd6897c827ac000000000000000000000000ca47c17967c740085df98db42c65fd6897c827ac000000000000000000000000000000000000000000000000004b98dffd817b3100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4755,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009b15debe0d17473d5cbd655e475567c08bea32400000000000000000000000009b15debe0d17473d5cbd655e475567c08bea324000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4756,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041a40816f4ba5f979aa1249b51220b4f4296205500000000000000000000000041a40816f4ba5f979aa1249b51220b4f42962055000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4757,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efffcf5297bee262fcc9a283ebbf8745939b90b9000000000000000000000000efffcf5297bee262fcc9a283ebbf8745939b90b9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013f550f918df5800619d5eb884beb5bf20b52b3600000000000000000000000013f550f918df5800619d5eb884beb5bf20b52b36000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4759,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078509bedf3de8c803604335951080de8ab35631300000000000000000000000078509bedf3de8c803604335951080de8ab356313000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4760,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a8fa6774d7e952992b26c3949eeab9dedade0990000000000000000000000006a8fa6774d7e952992b26c3949eeab9dedade099000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4761,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075179bc29d0f22268496f0389e89bf18e4a8a16600000000000000000000000075179bc29d0f22268496f0389e89bf18e4a8a166000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054b81b4acfcba29164b43b600d66359ed15d296300000000000000000000000054b81b4acfcba29164b43b600d66359ed15d2963000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4763,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043c213b5cd3229ba96ac096b2f1a3f7aa7637c2300000000000000000000000043c213b5cd3229ba96ac096b2f1a3f7aa7637c23000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4764,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032c15485930203d0ea3a57cd17d2d1fb1d76f0f600000000000000000000000032c15485930203d0ea3a57cd17d2d1fb1d76f0f6000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4765,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096f6acd6573c41accb01f4d391ef8437a1d9d12200000000000000000000000096f6acd6573c41accb01f4d391ef8437a1d9d122000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087ad6c4137d73352937d1e784c51787808a5221400000000000000000000000087ad6c4137d73352937d1e784c51787808a52214000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4767,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000840dcb18ddd75d048f3c0320687017dd7420b638000000000000000000000000840dcb18ddd75d048f3c0320687017dd7420b6380000000000000000000000000000000000000000000000000006f2051af0d67d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d94be38ddce7331e6b393f05060a1089a5c0b73f000000000000000000000000d94be38ddce7331e6b393f05060a1089a5c0b73f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4769,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008eef779818afa953b0652e45438423ebe089f55a0000000000000000000000008eef779818afa953b0652e45438423ebe089f55a0000000000000000000000000000000000000000000000000040555d5f7f9c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4770,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002808f7a3ffb1d1ab93020c662bce8630e82ef5870000000000000000000000002808f7a3ffb1d1ab93020c662bce8630e82ef587000000000000000000000000000000000000000000000000001d1916ea179d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4771,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a102cd7610a51ccf33fd837bc4b51fbe45986766000000000000000000000000a102cd7610a51ccf33fd837bc4b51fbe45986766000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de63c51d5db76e8a6286c8a95cf8bf040630aa12000000000000000000000000de63c51d5db76e8a6286c8a95cf8bf040630aa12000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4773,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000774b8d5187e46b2466d9f93253b043de211d25ee000000000000000000000000774b8d5187e46b2466d9f93253b043de211d25ee000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004934a209bdad5dc81f69344c20e083800062b78b0000000000000000000000004934a209bdad5dc81f69344c20e083800062b78b000000000000000000000000000000000000000000000000009a6a7f0bb4975c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093ae918fee314a1d5f01e153273f4b906a03fb4300000000000000000000000093ae918fee314a1d5f01e153273f4b906a03fb43000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019a10dae9aa55939b48eb5883f058212c2e461de00000000000000000000000019a10dae9aa55939b48eb5883f058212c2e461de000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4778,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da800ea1c982da53a97d2b3648ca06f7073332f1000000000000000000000000da800ea1c982da53a97d2b3648ca06f7073332f1000000000000000000000000000000000000000000000000005fa48c4590b34000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb7c5932a406301b421cfa87bc084c7e4ec50ffb000000000000000000000000fb7c5932a406301b421cfa87bc084c7e4ec50ffb000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cf220738ebca441142a4a9e04f1acc54e33ede70000000000000000000000006cf220738ebca441142a4a9e04f1acc54e33ede7000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4782,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1b2f28da2b5ba4a0cc8810b37050c144eccee4f000000000000000000000000c1b2f28da2b5ba4a0cc8810b37050c144eccee4f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000128be462b4c51a03d24841f13bb76357b946dc30000000000000000000000000128be462b4c51a03d24841f13bb76357b946dc30000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4784,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005dbada3143b4742ea99609f99d467b77bf314c720000000000000000000000005dbada3143b4742ea99609f99d467b77bf314c72000000000000000000000000000000000000000000000000005f78996678460000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd7ab4c287251b191148832008d393bcb070212e8bd6cda7b4f74be61fa9029a5,2022-05-28 10:21:39.000 UTC,0,true +4785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc7d7d83538f554b58021ca5f68c5a8370e6aa85000000000000000000000000bc7d7d83538f554b58021ca5f68c5a8370e6aa85000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003621a4ceca5abceb6edb07261777ca761c06a3180000000000000000000000003621a4ceca5abceb6edb07261777ca761c06a318000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4788,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003cfec638039e8226580b1aa18ef7c81594aab4de0000000000000000000000003cfec638039e8226580b1aa18ef7c81594aab4de000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000565dac8a20c7ba67e2475998ec94891681303bf3000000000000000000000000565dac8a20c7ba67e2475998ec94891681303bf3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4790,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a03a2dbbe963f48d6db2f52654865cced8a55a00000000000000000000000004a03a2dbbe963f48d6db2f52654865cced8a55a0000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4791,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002c7c25035572ac801ae1c1389fbc547e53cefc400000000000000000000000002c7c25035572ac801ae1c1389fbc547e53cefc4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b32969386bf3367efc46f43c847e5f0fbc9e9352000000000000000000000000b32969386bf3367efc46f43c847e5f0fbc9e9352000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4793,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008413db0f5627121d175db1e28a7b9d6a53a057a40000000000000000000000008413db0f5627121d175db1e28a7b9d6a53a057a4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7bd5bfa094427f38edc4e22b968df5bc628d1ba000000000000000000000000e7bd5bfa094427f38edc4e22b968df5bc628d1ba000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4795,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b515572a7dfa96e3bdcf5da8c07f87c78eb481dd000000000000000000000000b515572a7dfa96e3bdcf5da8c07f87c78eb481dd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006704a6ab026013784b12d551910754e6b6d420c80000000000000000000000006704a6ab026013784b12d551910754e6b6d420c80000000000000000000000000000000000000000000000000091cd127707bd5700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4798,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd53a43681d0f7dc8c7365d9e9e967f0ae439733000000000000000000000000dd53a43681d0f7dc8c7365d9e9e967f0ae439733000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4799,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047e82d9eaec31f4af15c4e6cf750ee92d4671f4100000000000000000000000047e82d9eaec31f4af15c4e6cf750ee92d4671f41000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4801,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6c8e08840c4c1cecf72c210a7767a6bc0708ef6000000000000000000000000a6c8e08840c4c1cecf72c210a7767a6bc0708ef6000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4802,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d70efdebd7bf7a18d99dc5743775d2403aedca40000000000000000000000005d70efdebd7bf7a18d99dc5743775d2403aedca4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4803,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f36f8b6f0978f30e3b4ebc40fffb33614a140870000000000000000000000003f36f8b6f0978f30e3b4ebc40fffb33614a14087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4804,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd60788b1e68b1829698de4220935609c20640d9000000000000000000000000bd60788b1e68b1829698de4220935609c20640d9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4805,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d2e5c70cb5be0ac3f98e8541ad5fe8122a77f3f0000000000000000000000001d2e5c70cb5be0ac3f98e8541ad5fe8122a77f3f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4806,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000007e44f3d32c23f44e83bc194ec6811d8ddad507b50000000000000000000000007e44f3d32c23f44e83bc194ec6811d8ddad507b5000000000000000000000000000000000000000000000000000000003a09093600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa859406d75f1e8cecd4a0e11a41b5e6cab2afebb99c5d550639fc81141011d66,2022-04-28 08:43:31.000 UTC,0,true +4807,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005caafbe3b1a065656a7d62cfb527f6dd0983769e0000000000000000000000005caafbe3b1a065656a7d62cfb527f6dd0983769e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4808,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf28c3909d77b08aba6535ba714a0e0f247b7e24000000000000000000000000bf28c3909d77b08aba6535ba714a0e0f247b7e24000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4809,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3f04dd1048b899a604ead8673e877f74382e83f000000000000000000000000d3f04dd1048b899a604ead8673e877f74382e83f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9cd2cd9411b9ab2641a96f7f2308997cc8a7ba8000000000000000000000000e9cd2cd9411b9ab2641a96f7f2308997cc8a7ba8000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4811,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000193030f0925cb2a303f643f47b885f8884bcde51000000000000000000000000193030f0925cb2a303f643f47b885f8884bcde51000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019990c1151ea0d9af1a7f001af99369036c6b37700000000000000000000000019990c1151ea0d9af1a7f001af99369036c6b377000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4813,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf6a1374d4ee577e75ff817fb636d5f7a78df437000000000000000000000000bf6a1374d4ee577e75ff817fb636d5f7a78df437000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000386e85f8041b4c1bb7636187a20d1faf824c7371000000000000000000000000386e85f8041b4c1bb7636187a20d1faf824c7371000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007659f447322b1a7c8a7762d8e887a14036bc79ac0000000000000000000000007659f447322b1a7c8a7762d8e887a14036bc79ac000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a6ad7ded9157b42ac20b12fdeb420a1356024c90000000000000000000000008a6ad7ded9157b42ac20b12fdeb420a1356024c9000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ae8f908ce70b12879af88a94843d1f21bc973630000000000000000000000004ae8f908ce70b12879af88a94843d1f21bc97363000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a38840567ef21e89f5e23b701b0d4be22738dd65000000000000000000000000a38840567ef21e89f5e23b701b0d4be22738dd65000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4820,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eeb9e883dd52bf41d672bf61792d32eec7f7d632000000000000000000000000eeb9e883dd52bf41d672bf61792d32eec7f7d632000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df65527e7d88953234614efe4b72cbe7a848fb8a000000000000000000000000df65527e7d88953234614efe4b72cbe7a848fb8a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4822,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a07b077c585a0789939520706c9e71207f91e78b000000000000000000000000a07b077c585a0789939520706c9e71207f91e78b000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf6ae5bd3f76b1b8a4c8be14e93272ef1c214b77000000000000000000000000bf6ae5bd3f76b1b8a4c8be14e93272ef1c214b77000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d9596218d9f81403c542815dbd56d44ee1e920d0000000000000000000000000d9596218d9f81403c542815dbd56d44ee1e920d0000000000000000000000000000000000000000000000000006656d6d0b7f5e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e9c4103c54cd5d8c9a79d13225031cae4e8b3f50000000000000000000000006e9c4103c54cd5d8c9a79d13225031cae4e8b3f5000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009285d24f30390af0cb8331401d9f609275f7813f0000000000000000000000009285d24f30390af0cb8331401d9f609275f7813f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011089817570a67c42dc6a57a545bd4679c17e07600000000000000000000000011089817570a67c42dc6a57a545bd4679c17e076000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e12fd8f8a438f7c767c4dc3ba2f9d1819f8d3bd0000000000000000000000005e12fd8f8a438f7c767c4dc3ba2f9d1819f8d3bd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2efe33e14541da6ad389f36f21b15fe5d305f30000000000000000000000000d2efe33e14541da6ad389f36f21b15fe5d305f30000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006693b7ef7bcc300dde5830231a3ee0bd972bd85c0000000000000000000000006693b7ef7bcc300dde5830231a3ee0bd972bd85c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4831,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c05e84cd03035a0a6ab98fb5e5b981adebe6733b000000000000000000000000c05e84cd03035a0a6ab98fb5e5b981adebe6733b000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b287ecc518df66f380405563196b80039fbdd89c000000000000000000000000b287ecc518df66f380405563196b80039fbdd89c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003340308bdd50f503d3c5efbd69450551b3e8f81f0000000000000000000000003340308bdd50f503d3c5efbd69450551b3e8f81f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000197d5852e702f4685e370d0c9fd582ec55a531cd000000000000000000000000197d5852e702f4685e370d0c9fd582ec55a531cd000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000de38392adc601037dfd89a3d83354b1beaafc660000000000000000000000000de38392adc601037dfd89a3d83354b1beaafc66000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083b2245cfbe1d0047f30feaeb61e8043595934fc00000000000000000000000083b2245cfbe1d0047f30feaeb61e8043595934fc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033e7609bfdad6117943b00370a5cb49add49c46400000000000000000000000033e7609bfdad6117943b00370a5cb49add49c464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008da9c63c1bcf8598dd44fffbc5dbea53aebd54f60000000000000000000000008da9c63c1bcf8598dd44fffbc5dbea53aebd54f6000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7d1f72101b9ba6ea3bcdd1db1826fbbde182892000000000000000000000000b7d1f72101b9ba6ea3bcdd1db1826fbbde182892000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4840,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001197fe10cedf5bbe3f161e1a13d7f6a56f0e4a0f0000000000000000000000001197fe10cedf5bbe3f161e1a13d7f6a56f0e4a0f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008fef97ccbc5d7dfcfdac1aa992fcfb69633c20000000000000000000000000008fef97ccbc5d7dfcfdac1aa992fcfb69633c200000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c151a1e3123f9eda4f63de7ca6bc461a97f39700000000000000000000000000c151a1e3123f9eda4f63de7ca6bc461a97f39700000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a6302c1fb65827304e77d868a770aafe34bbd580000000000000000000000008a6302c1fb65827304e77d868a770aafe34bbd58000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8dad3f33f7d585ac789447d93cb697ebcaf1ca7000000000000000000000000a8dad3f33f7d585ac789447d93cb697ebcaf1ca7000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa49e30b302dc29ce9f1e96eb5576a70cdfc0542000000000000000000000000fa49e30b302dc29ce9f1e96eb5576a70cdfc0542000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033c5a1eb527d804543c64b1008b61f78dfecf72600000000000000000000000033c5a1eb527d804543c64b1008b61f78dfecf726000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2d2de2f92f297b9a0401a5b815c051c557be376000000000000000000000000a2d2de2f92f297b9a0401a5b815c051c557be376000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007892bf19be53018a032067925e482620ff67ffcf0000000000000000000000007892bf19be53018a032067925e482620ff67ffcf000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcf03bb0dce296dd615d16bc9c338a8a37a020cc000000000000000000000000bcf03bb0dce296dd615d16bc9c338a8a37a020cc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019d1d0e20dd15b0743652f3e0dde9aea0617fd8d00000000000000000000000019d1d0e20dd15b0743652f3e0dde9aea0617fd8d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ce0118d1bfe9a5f0fa5b381d444f187527623200000000000000000000000003ce0118d1bfe9a5f0fa5b381d444f18752762320000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df0644d98fc986d6bd4638489e20063fadf8d7d8000000000000000000000000df0644d98fc986d6bd4638489e20063fadf8d7d8000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f51bc7e52bde3c27e6045d00d3f9c609d305c6b5000000000000000000000000f51bc7e52bde3c27e6045d00d3f9c609d305c6b5000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e960624cd53229d341bf9158255ddf53bad04dac000000000000000000000000e960624cd53229d341bf9158255ddf53bad04dac000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4855,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c9031e178a976f8d3697ef5f644b24db615fd9b0000000000000000000000006c9031e178a976f8d3697ef5f644b24db615fd9b000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000e1a6e86c6a8375d63555127bd8c15436932c8400000000000000000000000000e1a6e86c6a8375d63555127bd8c15436932c84000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b938f823d2da78ec005634a0742b969560d40bc0000000000000000000000000b938f823d2da78ec005634a0742b969560d40bc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4858,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca7278bffaa541f4fff875a93bf4f4ea72ad43af000000000000000000000000ca7278bffaa541f4fff875a93bf4f4ea72ad43af000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010936a472f257dda330bd65bce68dce8b169f69600000000000000000000000010936a472f257dda330bd65bce68dce8b169f696000000000000000000000000000000000000000000000000009e8dff889350b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4862,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6c0d7a92446b508b49c4a044a6571949bb8b62d000000000000000000000000c6c0d7a92446b508b49c4a044a6571949bb8b62d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e34bc9b5dd24f71dfebc45ab46d9f2feeded52b0000000000000000000000006e34bc9b5dd24f71dfebc45ab46d9f2feeded52b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059d7f642c0df533bd32b971a09d4205a1c1444b900000000000000000000000059d7f642c0df533bd32b971a09d4205a1c1444b9000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4865,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034e91cf6b9305f13ef4b92f312168ac98be6160f00000000000000000000000034e91cf6b9305f13ef4b92f312168ac98be6160f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4866,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000907ce6dc4016d472c645906575e59cfaf6db8bee000000000000000000000000907ce6dc4016d472c645906575e59cfaf6db8bee000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010dbf82a8bb191bd1c082de5ef915e998aa5ccd700000000000000000000000010dbf82a8bb191bd1c082de5ef915e998aa5ccd70000000000000000000000000000000000000000000000000207a305eff8d32500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2ee0b98892e2afb067bf39c3a5e17182c14ff6796b1aa27fcb14ef28629d7140,2022-02-02 13:39:28.000 UTC,0,true +4868,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034ce141b83a754705cb36df3f826eba268257dab00000000000000000000000034ce141b83a754705cb36df3f826eba268257dab000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000502e2a36dba47d881458e03e9e2b6ba47f1196e8000000000000000000000000502e2a36dba47d881458e03e9e2b6ba47f1196e8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1014980a9591c59f1d95adc14b56edd171bbf00000000000000000000000000c1014980a9591c59f1d95adc14b56edd171bbf00000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007212b43213e8bd36ad390e86e405867c2adee09e0000000000000000000000007212b43213e8bd36ad390e86e405867c2adee09e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017b3e588a306dd47855aeb1c423cafdacf3a665200000000000000000000000017b3e588a306dd47855aeb1c423cafdacf3a665200000000000000000000000000000000000000000000000000014805e10bf6f300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007ebb7978e5f752d1af50133d677b4ae84474d0100000000000000000000000007ebb7978e5f752d1af50133d677b4ae84474d0100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4874,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043ec54a69923cf55e5d8cfaffd79b5a52b8202bf00000000000000000000000043ec54a69923cf55e5d8cfaffd79b5a52b8202bf000000000000000000000000000000000000000000000000000f45f0e825925500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4875,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006fae1e971bd93a141eef542b4197a3476d03dacd0000000000000000000000006fae1e971bd93a141eef542b4197a3476d03dacd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ee9c1ff90f649a7d02e68bd3dcd7d185d68e5020000000000000000000000007ee9c1ff90f649a7d02e68bd3dcd7d185d68e502000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000591125dbb201bd90635b90e74555f341c4c12196000000000000000000000000591125dbb201bd90635b90e74555f341c4c12196000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2415d4f25c37df7f15b84138f370f55ad4fb434000000000000000000000000f2415d4f25c37df7f15b84138f370f55ad4fb434000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044f2edfaa320b6b7540fbbff4758b925c5f9c7ac00000000000000000000000044f2edfaa320b6b7540fbbff4758b925c5f9c7ac000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c72299609537a857c48a3fae2b06e09318d3f6bb000000000000000000000000c72299609537a857c48a3fae2b06e09318d3f6bb000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c658b02473ae79c2826e770db890c815788788bd000000000000000000000000c658b02473ae79c2826e770db890c815788788bd00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4882,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079e03e5718268fdd2c219807406a231e2fccb2ef00000000000000000000000079e03e5718268fdd2c219807406a231e2fccb2ef000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000527625a238857be593920238ea9dee3fa7ce5433000000000000000000000000527625a238857be593920238ea9dee3fa7ce5433000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4884,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066ac5a53db5349152db5f3c9fab2b93664044a1000000000000000000000000066ac5a53db5349152db5f3c9fab2b93664044a1000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000afdf046b8eb9f7ec6d341ba923a663633ac0d7a2000000000000000000000000afdf046b8eb9f7ec6d341ba923a663633ac0d7a2000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4886,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f7609d42cd0393ba6e8a3168b20096943eb006f0000000000000000000000008f7609d42cd0393ba6e8a3168b20096943eb006f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3fac74d23767ba74ec0842e24ea39708faad1c8000000000000000000000000c3fac74d23767ba74ec0842e24ea39708faad1c8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e987723597050e6d073bc3660df5365b764c651c000000000000000000000000e987723597050e6d073bc3660df5365b764c651c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007aab79eca85f6259f40ef23d140e39e0ee44d75a0000000000000000000000007aab79eca85f6259f40ef23d140e39e0ee44d75a000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016cd17e90d1b5f623505c0796be1e85607defbcb00000000000000000000000016cd17e90d1b5f623505c0796be1e85607defbcb00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000978260921f7a56a98011e752e3b6847387dd9e13000000000000000000000000978260921f7a56a98011e752e3b6847387dd9e13000000000000000000000000000000000000000000000000028d036819b634ba00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b45a7d322136ceeb741f153a2d795eb4696799bb000000000000000000000000b45a7d322136ceeb741f153a2d795eb4696799bb000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b9a1dfc451d7e6233cde79b627e7c5319e0f1bc0000000000000000000000004b9a1dfc451d7e6233cde79b627e7c5319e0f1bc00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4894,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ed22136c186e2f017d872f6c106cfe21991e8e90000000000000000000000003ed22136c186e2f017d872f6c106cfe21991e8e9000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4895,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a4307a69e4adfab939f3d89c9121a391ad146a20000000000000000000000004a4307a69e4adfab939f3d89c9121a391ad146a2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000322ee168f95d3d151105d784fbdcdc8c1ea7d2e2000000000000000000000000322ee168f95d3d151105d784fbdcdc8c1ea7d2e200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078018b3e65ed26601f9c428383d62e037a0ad5bf00000000000000000000000078018b3e65ed26601f9c428383d62e037a0ad5bf000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4898,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000800400391b32df4c5a2c575c1fffaf8a71f9c22e000000000000000000000000800400391b32df4c5a2c575c1fffaf8a71f9c22e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4900,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6256af6d7bf502a25309c7b9017d4c5ea82433b000000000000000000000000e6256af6d7bf502a25309c7b9017d4c5ea82433b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4901,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009cf52a8174c1a841f9e20e629dd420974b587ba40000000000000000000000009cf52a8174c1a841f9e20e629dd420974b587ba400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f2ce4f450d9acf7bedacdf7879f68a2e9308e540000000000000000000000006f2ce4f450d9acf7bedacdf7879f68a2e9308e54000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4903,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a5636e3c10390e6f06482f1336f1973e767d9e60000000000000000000000002a5636e3c10390e6f06482f1336f1973e767d9e6000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4904,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c57578c767d48ba722058dfad80ac83f9a2e4860000000000000000000000000c57578c767d48ba722058dfad80ac83f9a2e48600000000000000000000000000000000000000000000000000109c5e7809757c900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4905,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a813569d4fc9a0d2fb0150c2fdfbd6c1645b5df0000000000000000000000004a813569d4fc9a0d2fb0150c2fdfbd6c1645b5df000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ec4a557a6e430d10a6acaf265610199c49411100000000000000000000000003ec4a557a6e430d10a6acaf265610199c4941110000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4907,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4e67873e7983f8ed98da6f4b5f9d2719b72ffb5000000000000000000000000a4e67873e7983f8ed98da6f4b5f9d2719b72ffb5000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0552d9b83590294ab9e5da073c4fde14359d1dd000000000000000000000000c0552d9b83590294ab9e5da073c4fde14359d1dd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4910,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074a20a756c25d124a4dba853dfd996274c69b4ac00000000000000000000000074a20a756c25d124a4dba853dfd996274c69b4ac000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ff745694113df5ea6317f41fa3b371b0f5d7b350000000000000000000000008ff745694113df5ea6317f41fa3b371b0f5d7b3500000000000000000000000000000000000000000000000000fa61bafa78615500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4912,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017e7989777c7b23ac2d8523816df154d8c47123700000000000000000000000017e7989777c7b23ac2d8523816df154d8c471237000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082919de1450c9884ecd1aa89fe6c5ef03b56f58e00000000000000000000000082919de1450c9884ecd1aa89fe6c5ef03b56f58e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4914,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cef7d2a50cb0e6c5f1be47ee71578c93c6966671000000000000000000000000cef7d2a50cb0e6c5f1be47ee71578c93c6966671000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047f3edb4cf66644514618d98cdc9b813cec77f5c00000000000000000000000047f3edb4cf66644514618d98cdc9b813cec77f5c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de1a86cd877c622a7fc71739f37e9430317616e2000000000000000000000000de1a86cd877c622a7fc71739f37e9430317616e20000000000000000000000000000000000000000000000000101a553643ec30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfc2cf0fc6e6fd3f9c06ea5178426ad2d2e48a06000000000000000000000000bfc2cf0fc6e6fd3f9c06ea5178426ad2d2e48a06000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062a80918dde9b992d32a2b59bc7109ccf08b8b6000000000000000000000000062a80918dde9b992d32a2b59bc7109ccf08b8b60000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4919,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6a7c8869359b4ea34f3069b0d84742d76b1bf3d000000000000000000000000d6a7c8869359b4ea34f3069b0d84742d76b1bf3d000000000000000000000000000000000000000000000000009fb43761e5658e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2772761152a8779bad1004e04a1db547521da6f000000000000000000000000d2772761152a8779bad1004e04a1db547521da6f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4921,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000246846d6ec87e7b415fcdb2899a81294522316c6000000000000000000000000246846d6ec87e7b415fcdb2899a81294522316c600000000000000000000000000000000000000000000000000057b89e890ed2f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4922,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa9a1a93ab327fba20384caf9921491f3917ee6a000000000000000000000000fa9a1a93ab327fba20384caf9921491f3917ee6a00000000000000000000000000000000000000000000000000f618f83096749900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016fc72333f77568b782d386e82aa400999c8c23a00000000000000000000000016fc72333f77568b782d386e82aa400999c8c23a000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a577494f74b5f4e7ec517bd66b4403806e8e0378000000000000000000000000a577494f74b5f4e7ec517bd66b4403806e8e0378000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e6eb978a9cbdb57a02856b3d0b8e6571a2bd6970000000000000000000000004e6eb978a9cbdb57a02856b3d0b8e6571a2bd697000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006051a9863d97addaf708154e3d5ab3c456b0c1250000000000000000000000006051a9863d97addaf708154e3d5ab3c456b0c12500000000000000000000000000000000000000000000000000fc30f8c65df32d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000affc3444310c1df92f35fdeeadf4de5be977df06000000000000000000000000affc3444310c1df92f35fdeeadf4de5be977df06000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4929,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a60eb1065aea0d4b78ce2859b6977ac417d3aab0000000000000000000000001a60eb1065aea0d4b78ce2859b6977ac417d3aab0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008637aa682344f1e70a37f2d7da02ef79024f6bf50000000000000000000000008637aa682344f1e70a37f2d7da02ef79024f6bf50000000000000000000000000000000000000000000000000101cbc7478a774300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac45bde4f7869e45e475028ccaf437e6213c2827000000000000000000000000ac45bde4f7869e45e475028ccaf437e6213c2827000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4932,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5fdafe5b1903ecd1748b109eba3891e6276a0b6000000000000000000000000d5fdafe5b1903ecd1748b109eba3891e6276a0b6000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4933,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf0e864ae108d71db1c710409c7fc5aeb40b43fb000000000000000000000000bf0e864ae108d71db1c710409c7fc5aeb40b43fb000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4934,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b39aec4b84f042677fea1439d1e104326cbc84ac000000000000000000000000b39aec4b84f042677fea1439d1e104326cbc84ac0000000000000000000000000000000000000000000000000060c1c9a353fa4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b58e15c56be04743b84dd60d225085c296de2db0000000000000000000000004b58e15c56be04743b84dd60d225085c296de2db0000000000000000000000000000000000000000000000000104a026b15b2cd500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d78f4935778764a9c64d32a3f590b7da9f5bbb60000000000000000000000000d78f4935778764a9c64d32a3f590b7da9f5bbb60000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4937,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a86d959853519975aba591bc19579682faab1770000000000000000000000003a86d959853519975aba591bc19579682faab177000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfe2e4a14e2b77a2d37fda2bd304feca175ea544000000000000000000000000bfe2e4a14e2b77a2d37fda2bd304feca175ea54400000000000000000000000000000000000000000000000001086c348dd0b7e700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006836cc238567d32a59f6c717e9991e482afbc5bd0000000000000000000000006836cc238567d32a59f6c717e9991e482afbc5bd000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008bde3ad8a20852e04afd2b2f27b5a59fc287789f0000000000000000000000008bde3ad8a20852e04afd2b2f27b5a59fc287789f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4941,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031dc4372b19e2d923813224a31368c88076c29e000000000000000000000000031dc4372b19e2d923813224a31368c88076c29e0000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4942,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a55cfb15941f1692751b2b3a527d94265c7d156e000000000000000000000000a55cfb15941f1692751b2b3a527d94265c7d156e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005e75611ea6c050ca1036ec5df6f609b034a5de700000000000000000000000005e75611ea6c050ca1036ec5df6f609b034a5de7000000000000000000000000000000000000000000000000004149842d60770000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd4bb2c4fd4fb4f7d3956541ea347769fcbf8da4ea4ce43ef228f86068b60ea35,2022-04-17 09:27:29.000 UTC,0,true +4944,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff2e53d6da18e31d607f4399220db033d2931d1f000000000000000000000000ff2e53d6da18e31d607f4399220db033d2931d1f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4945,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ef2ebfb2eba4c63d38c5ad1322104176b165ff40000000000000000000000004ef2ebfb2eba4c63d38c5ad1322104176b165ff4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4946,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030bddda2620a715eb5892810b199218b50ea7fdb00000000000000000000000030bddda2620a715eb5892810b199218b50ea7fdb000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4947,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a95a05410921e8190ca1adbaaa45a8917cddae09000000000000000000000000a95a05410921e8190ca1adbaaa45a8917cddae09000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4948,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2b82e071cfa045d938716e2b2108b022f695df4000000000000000000000000c2b82e071cfa045d938716e2b2108b022f695df4000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4949,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000172b1d027d9f532c8412249c668a87f8f7c328d0000000000000000000000000172b1d027d9f532c8412249c668a87f8f7c328d0000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4950,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f93afebf1e21460e7e9c1ad099c21650e879eedc000000000000000000000000f93afebf1e21460e7e9c1ad099c21650e879eedc000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b47726b44d8e004e11555431035bbb2930ffd9fc000000000000000000000000b47726b44d8e004e11555431035bbb2930ffd9fc000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000819b172906649f91c8bce341f08141e3bcbb6fbc000000000000000000000000819b172906649f91c8bce341f08141e3bcbb6fbc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4954,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8a2c2c3140b1801a4afdbda89db20e02f736ba9000000000000000000000000f8a2c2c3140b1801a4afdbda89db20e02f736ba9000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4955,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008169dfecd99e8a0945068f8d26a80b4396d3820b0000000000000000000000008169dfecd99e8a0945068f8d26a80b4396d3820b000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4956,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c17da57ee13e8a9e7d3f3c6ac2c011d18071723b000000000000000000000000c17da57ee13e8a9e7d3f3c6ac2c011d18071723b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4957,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000951bf925dc5d5d4849c1b2b93e742ef10012b48e000000000000000000000000951bf925dc5d5d4849c1b2b93e742ef10012b48e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003188684ed5b446751851edec8067826d593a76fd0000000000000000000000003188684ed5b446751851edec8067826d593a76fd000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dfdc09776116cbbc3485bb0b53507a0ec0acbf38000000000000000000000000dfdc09776116cbbc3485bb0b53507a0ec0acbf38000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4960,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6e6a4dc851680fd200367021df4b8d84e4764a5000000000000000000000000c6e6a4dc851680fd200367021df4b8d84e4764a5000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043ec54a69923cf55e5d8cfaffd79b5a52b8202bf00000000000000000000000043ec54a69923cf55e5d8cfaffd79b5a52b8202bf0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef575844bfe8c7872a8ccc9fb2af8318c1550fad000000000000000000000000ef575844bfe8c7872a8ccc9fb2af8318c1550fad00000000000000000000000000000000000000000000000000668b929e7ef09700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4964,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000331189161575a5f9cb7637f6544156889fc77a60000000000000000000000000331189161575a5f9cb7637f6544156889fc77a6000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c8e4dd49948dc43443e14d7563623b2669779a71000000000000000000000000c8e4dd49948dc43443e14d7563623b2669779a71000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f15f71188c240c3d7bdfa5a5c44ebe37e30112f0000000000000000000000001f15f71188c240c3d7bdfa5a5c44ebe37e30112f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c939678d75bb552bf3d22aecba8184f0eb9c7ba0000000000000000000000008c939678d75bb552bf3d22aecba8184f0eb9c7ba000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e021990f6142a5d2bdfe2cb1e6535fcd967d221e000000000000000000000000e021990f6142a5d2bdfe2cb1e6535fcd967d221e000000000000000000000000000000000000000000000000000e80d8b437e92900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4970,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086845ebf40b3141e18e1fdbd91d845b51fa1242e00000000000000000000000086845ebf40b3141e18e1fdbd91d845b51fa1242e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ea63889a9eba186ee050d6c42d5580ef388face0000000000000000000000008ea63889a9eba186ee050d6c42d5580ef388face000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4973,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f537cdead4ac51eea305e800692459eeb64f7980000000000000000000000001f537cdead4ac51eea305e800692459eeb64f798000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c6b50f3593ac3ddb5e1e38db6a780456b1e49c70000000000000000000000001c6b50f3593ac3ddb5e1e38db6a780456b1e49c7000000000000000000000000000000000000000000000000002f11349bc4d1e400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043ec54a69923cf55e5d8cfaffd79b5a52b8202bf00000000000000000000000043ec54a69923cf55e5d8cfaffd79b5a52b8202bf0000000000000000000000000000000000000000000000000000088119ffd50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a17cc8fe40175c9ecaa64f07c88f784b4664f805000000000000000000000000a17cc8fe40175c9ecaa64f07c88f784b4664f805000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043ec54a69923cf55e5d8cfaffd79b5a52b8202bf00000000000000000000000043ec54a69923cf55e5d8cfaffd79b5a52b8202bf0000000000000000000000000000000000000000000000000000088119ffd50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4978,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000455f982fe6dfa24c72c304f319de71ea806af223000000000000000000000000455f982fe6dfa24c72c304f319de71ea806af223000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4980,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006eba72cbfa2a136e35056b6451dcc7b412bcc2200000000000000000000000006eba72cbfa2a136e35056b6451dcc7b412bcc2200000000000000000000000000000000000000000000000000732f8e01e8d1bd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a020e94c2377c4f22dd16ce609b20ed7b350e410000000000000000000000008a020e94c2377c4f22dd16ce609b20ed7b350e41000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7575e23b33a2db2937202fd65d9f8be466f4705000000000000000000000000b7575e23b33a2db2937202fd65d9f8be466f4705000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4983,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ea4616d1a8d0e67fbde645cdf8aa29889fa5ff90000000000000000000000000ea4616d1a8d0e67fbde645cdf8aa29889fa5ff9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4984,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e565d1128b56525e69e8acad62fe5d08469581e0000000000000000000000001e565d1128b56525e69e8acad62fe5d08469581e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4986,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d81a7755f7c2fec66f327e4a9b0363943884afb8000000000000000000000000d81a7755f7c2fec66f327e4a9b0363943884afb8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000374c0ca51fba5702c8b087344a12455676c60ee2000000000000000000000000374c0ca51fba5702c8b087344a12455676c60ee200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4988,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094de68e06d7aea8effab7f454850646040daea9300000000000000000000000094de68e06d7aea8effab7f454850646040daea9300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4989,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6a38ffeec8ab6d0ac884c9b3bfebdd901f04241000000000000000000000000e6a38ffeec8ab6d0ac884c9b3bfebdd901f0424100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec8d2c72c00062bdc20e0114fb766470f778a6ac000000000000000000000000ec8d2c72c00062bdc20e0114fb766470f778a6ac000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4991,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e43ba864a61900bd2a23585c6a8d49ba806b8ff0000000000000000000000003e43ba864a61900bd2a23585c6a8d49ba806b8ff00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4992,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcec9538657e734511c93a4e6a6ea1cffd8fda85000000000000000000000000fcec9538657e734511c93a4e6a6ea1cffd8fda8500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c96588b5f9e6fd600f3dcab3b1fd762db8e37cbb000000000000000000000000c96588b5f9e6fd600f3dcab3b1fd762db8e37cbb00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac296e024b243a852e3be0ba06c60768c7673c69000000000000000000000000ac296e024b243a852e3be0ba06c60768c7673c69000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4995,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b575fb20f76844dd7b6f7eee023853ac30929750000000000000000000000000b575fb20f76844dd7b6f7eee023853ac3092975000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4996,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2d61e516e839ac73f28fb1221c10a67228bd45c000000000000000000000000c2d61e516e839ac73f28fb1221c10a67228bd45c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f65ab942c891d416a8769afe0c391d20406b59e0000000000000000000000006f65ab942c891d416a8769afe0c391d20406b59e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4998,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fca21664dc233ff13fc5a495625f7917ff2be070000000000000000000000000fca21664dc233ff13fc5a495625f7917ff2be07000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +4999,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000935d6c2f716a3a0918e8490bf3a4d4e87419df6f000000000000000000000000935d6c2f716a3a0918e8490bf3a4d4e87419df6f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5000,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e243cd3a0155dc19d8a8f32ce74a83d5860e18b9000000000000000000000000e243cd3a0155dc19d8a8f32ce74a83d5860e18b900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5001,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba741874a06713b2bc166671b176773d00f7c6d1000000000000000000000000ba741874a06713b2bc166671b176773d00f7c6d100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5002,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4d6c5e77d31dac186f05528eec0a4746d23c7db000000000000000000000000e4d6c5e77d31dac186f05528eec0a4746d23c7db00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5003,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f006417289e9fa4d389a1af4820d48199fb16480000000000000000000000003f006417289e9fa4d389a1af4820d48199fb164800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af362e53cbc16264fdd94ba3ea18a8cd9b3180f1000000000000000000000000af362e53cbc16264fdd94ba3ea18a8cd9b3180f1000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5005,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c031d60dad0ce9d34206fd69c0b9abc7e13f6830000000000000000000000004c031d60dad0ce9d34206fd69c0b9abc7e13f68300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5006,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2c2dd738f3f7e343eab709ed2d22051073690dd000000000000000000000000c2c2dd738f3f7e343eab709ed2d22051073690dd00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5008,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab4d61d82ceb64a08746ac480eb5167de0c2da08000000000000000000000000ab4d61d82ceb64a08746ac480eb5167de0c2da0800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5009,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5404a3cf7d03bbd89132894c1ac01bcac00ac4d000000000000000000000000a5404a3cf7d03bbd89132894c1ac01bcac00ac4d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5010,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000809a585650f22cff10919f2948f37f0a1d9f33b7000000000000000000000000809a585650f22cff10919f2948f37f0a1d9f33b700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c78d3dfe8f26585a032dd8abf79b365346f33c80000000000000000000000006c78d3dfe8f26585a032dd8abf79b365346f33c800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5012,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb875567a3ed86e74d3737cbee33225b6473a3d5000000000000000000000000fb875567a3ed86e74d3737cbee33225b6473a3d500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000515b96a55c07a19f8746d12007202f277b1dabaa000000000000000000000000515b96a55c07a19f8746d12007202f277b1dabaa00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5014,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7b698ba27395fae0465abd58beba754cc5ae3ca000000000000000000000000b7b698ba27395fae0465abd58beba754cc5ae3ca00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5015,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000855560d275ed022d5b6d45fba80ae67f53051d31000000000000000000000000855560d275ed022d5b6d45fba80ae67f53051d3100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5016,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d8d20beb8f82b5b8d102fa93d8b605f7242105e0000000000000000000000000d8d20beb8f82b5b8d102fa93d8b605f7242105e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5017,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a42ad380770c10cfe312e5ef065074f11a5a8ab7000000000000000000000000a42ad380770c10cfe312e5ef065074f11a5a8ab700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5018,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008bec3f6747c84d8af97a832a6b53030075f703e80000000000000000000000008bec3f6747c84d8af97a832a6b53030075f703e800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5019,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022841f046f9761539534ce93f842943812a2c01a00000000000000000000000022841f046f9761539534ce93f842943812a2c01a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5020,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5404a3cf7d03bbd89132894c1ac01bcac00ac4d000000000000000000000000a5404a3cf7d03bbd89132894c1ac01bcac00ac4d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000474f5e6716658554003ab54b97bba005622293c6000000000000000000000000474f5e6716658554003ab54b97bba005622293c600000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007c3d560e0f7ae4decb435172b85c7bfde30f76100000000000000000000000007c3d560e0f7ae4decb435172b85c7bfde30f76100000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c7a06a1decad2430c0f785520caf40830a58dd70000000000000000000000000c7a06a1decad2430c0f785520caf40830a58dd700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000114d2e9ce76c1adb54327bdee1580101e5b10899000000000000000000000000114d2e9ce76c1adb54327bdee1580101e5b1089900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c6d80a298edb9350611812fb0b6faaab16531d90000000000000000000000006c6d80a298edb9350611812fb0b6faaab16531d900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088aa5837fd33ddc353fb55983d99f19d6dbbc4aa00000000000000000000000088aa5837fd33ddc353fb55983d99f19d6dbbc4aa00000000000000000000000000000000000000000000000000b4d397ecf3a7f800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d94f2fb24978abcd03d6211861624f4762ead476000000000000000000000000d94f2fb24978abcd03d6211861624f4762ead47600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000347f37f4ed042a208f1be1202aa0577b1d5f1a31000000000000000000000000347f37f4ed042a208f1be1202aa0577b1d5f1a3100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000215b9442daa7055c8b732d557ff01cd2ee22cba5000000000000000000000000215b9442daa7055c8b732d557ff01cd2ee22cba500000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5031,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea2903d63ac3cf003a9b7a05084c29c463c89892000000000000000000000000ea2903d63ac3cf003a9b7a05084c29c463c8989200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5032,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000feef8f3abff528358d86294ddb6fbb4ff0e26d8a000000000000000000000000feef8f3abff528358d86294ddb6fbb4ff0e26d8a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000234e5ece80de8d99de5cf12e4a8dabe1ae1c9cde000000000000000000000000234e5ece80de8d99de5cf12e4a8dabe1ae1c9cde00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5034,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a75ff1bad5d7949e80cea17d64af301bdcc74dcb000000000000000000000000a75ff1bad5d7949e80cea17d64af301bdcc74dcb00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fad12de52a35f4c7dc73b89368f20f38efbf406e000000000000000000000000fad12de52a35f4c7dc73b89368f20f38efbf406e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5036,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e895819c3b9a0d2eb84ffbe745a6a9881c2322d1000000000000000000000000e895819c3b9a0d2eb84ffbe745a6a9881c2322d1000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5037,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d28c29828fada742312f92a5c53188c3654666c9000000000000000000000000d28c29828fada742312f92a5c53188c3654666c9000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5038,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb16bc5c386ee0714fde56f78832695e569f5643000000000000000000000000fb16bc5c386ee0714fde56f78832695e569f564300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5039,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f39772b205e4e74b4eb2aefacc4208aca60c23ff000000000000000000000000f39772b205e4e74b4eb2aefacc4208aca60c23ff000000000000000000000000000000000000000000000000006d82c6d4a77f6300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5040,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b63d6fb10663f481a8b6f2be5c4dcbddb8fb12ac000000000000000000000000b63d6fb10663f481a8b6f2be5c4dcbddb8fb12ac00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5041,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002507c70bd624a4e873fb016e45b60e65ceb9e68a0000000000000000000000002507c70bd624a4e873fb016e45b60e65ceb9e68a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5042,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e315d07fd063fc2c6784a1ab0bdc5292402c0564000000000000000000000000e315d07fd063fc2c6784a1ab0bdc5292402c056400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5043,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038e47a84ab5fb6970a50d282bf46db995f1cd6cb00000000000000000000000038e47a84ab5fb6970a50d282bf46db995f1cd6cb000000000000000000000000000000000000000000000000003570ffc60a1c7900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5045,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e5af51bd0edbfa5a622370427331466ad140cc30000000000000000000000007e5af51bd0edbfa5a622370427331466ad140cc300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5048,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acd559d2284cc8c01d0e9bcb0d802f66efb5cd45000000000000000000000000acd559d2284cc8c01d0e9bcb0d802f66efb5cd450000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5049,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9c152cd51f1f4bc34395f0cd8e906bccf9a103b000000000000000000000000d9c152cd51f1f4bc34395f0cd8e906bccf9a103b00000000000000000000000000000000000000000000000000f6d4bf351f523d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006328647e2fadfee689f1bd53d4fd6958e3ae8dc00000000000000000000000006328647e2fadfee689f1bd53d4fd6958e3ae8dc00000000000000000000000000000000000000000000000000022718923b9ce0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020c609472f22804ed2dbc161a6dcc7495e577ff700000000000000000000000020c609472f22804ed2dbc161a6dcc7495e577ff7000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea1705996645f718a575ca7bafee22e27e2faf52000000000000000000000000ea1705996645f718a575ca7bafee22e27e2faf5200000000000000000000000000000000000000000000000000243030f2a131d600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005365471fdc9e4e2423026b4120243b8cd43f44820000000000000000000000005365471fdc9e4e2423026b4120243b8cd43f448200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5055,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000744369c5ca6caae54c50bc8afb2fab3492b4e9b5000000000000000000000000744369c5ca6caae54c50bc8afb2fab3492b4e9b5000000000000000000000000000000000000000000000000001c196b162ad80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5056,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b005d1f62b0ef700b7fecc88c53e725a5e7ef115000000000000000000000000b005d1f62b0ef700b7fecc88c53e725a5e7ef11500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb150564534e5c910bffafac2e114d5766ad523e000000000000000000000000fb150564534e5c910bffafac2e114d5766ad523e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5058,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009672bf43e2e9092b28c9450f0e6cea60245d3f100000000000000000000000009672bf43e2e9092b28c9450f0e6cea60245d3f1000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068ebd81edcf5f1e11c3807c75b98ddee6409513700000000000000000000000068ebd81edcf5f1e11c3807c75b98ddee6409513700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee6b7a44d790a125c0fa574e113dc7d9b0d7722c000000000000000000000000ee6b7a44d790a125c0fa574e113dc7d9b0d7722c0000000000000000000000000000000000000000000000000019000c7ba8480000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008262e1fe3ad8dedae6610b108bd0e17ecbce70320000000000000000000000008262e1fe3ad8dedae6610b108bd0e17ecbce703200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5062,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ac738ef43a130a3f72e600c2719df1889e5c96c0000000000000000000000008ac738ef43a130a3f72e600c2719df1889e5c96c000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5063,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006a77e6b069cecf50bb5b4d4b0359619c91b6b1100000000000000000000000006a77e6b069cecf50bb5b4d4b0359619c91b6b1100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5064,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a74324b8fa2c48c88ccf73bc440e06b92a487800000000000000000000000008a74324b8fa2c48c88ccf73bc440e06b92a4878000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000917b0d7b1ae65924d096a3d726c882b20828ff90000000000000000000000000917b0d7b1ae65924d096a3d726c882b20828ff900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5066,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e2057ac34968dc23e40b8a926531afa4950777b0000000000000000000000000e2057ac34968dc23e40b8a926531afa4950777b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5067,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5c9821a3166b745500dfefbcf75eebe94f3bc31000000000000000000000000c5c9821a3166b745500dfefbcf75eebe94f3bc3100000000000000000000000000000000000000000000000000040b1783e7c30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5068,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001828ea84f0fc021a437f387b09e9efa92da08a0b0000000000000000000000001828ea84f0fc021a437f387b09e9efa92da08a0b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5069,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032f5b4a9cddc363919f0f4a3d558b2fec57c082a00000000000000000000000032f5b4a9cddc363919f0f4a3d558b2fec57c082a00000000000000000000000000000000000000000000000000158d80bd91057200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5070,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2b45fd77c27d30bbbffad298e9c19dd658e179a000000000000000000000000c2b45fd77c27d30bbbffad298e9c19dd658e179a0000000000000000000000000000000000000000000000000061b24946da450000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5071,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000adfed7f23a61f2e7a5f2033f3de64c3c19322c1c000000000000000000000000adfed7f23a61f2e7a5f2033f3de64c3c19322c1c000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5072,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bccd47e23ff721f0f14078c6d6b3dfc8d1250128000000000000000000000000bccd47e23ff721f0f14078c6d6b3dfc8d1250128000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5073,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008174ea753c3625514685426b042f1a590d2b84d60000000000000000000000008174ea753c3625514685426b042f1a590d2b84d6000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5074,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d81fc84e3efa1022809a03d4a43dfd83ad695fbd000000000000000000000000d81fc84e3efa1022809a03d4a43dfd83ad695fbd000000000000000000000000000000000000000000000000002b0583e48f280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ca849c36a41e248bcb1bf3b61d0c1d3a05330160000000000000000000000001ca849c36a41e248bcb1bf3b61d0c1d3a053301600000000000000000000000000000000000000000000000000901471898663ee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2d46ca45812591aac5b3c5720321a653456d820965cb8ddfdf9caec058c4ed97,2022-05-22 09:40:49.000 UTC,0,true +5076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083d553362dfc0c1295e98f879edc98d54a8d885400000000000000000000000083d553362dfc0c1295e98f879edc98d54a8d885400000000000000000000000000000000000000000000000000a8cd9abaead50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5077,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b264a584feeb81978319c84c96aa71fc7fccc652000000000000000000000000b264a584feeb81978319c84c96aa71fc7fccc6520000000000000000000000000000000000000000000000000017969a87065a3900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f964a658db4f29d1942eb07abc7927a0c09f10c8000000000000000000000000f964a658db4f29d1942eb07abc7927a0c09f10c80000000000000000000000000000000000000000000000000048cf7afa779d4c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4b5364b23202aa18bb38c6b82bcc0910ad8eec4000000000000000000000000e4b5364b23202aa18bb38c6b82bcc0910ad8eec400000000000000000000000000000000000000000000000000411de34a91230000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000434a8f647db4b515560a3f9b8d2518550fc351e2000000000000000000000000434a8f647db4b515560a3f9b8d2518550fc351e2000000000000000000000000000000000000000000000000001d96f0dad0230000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003efedddeed8d7eaeb7d2d964f4f365cc66cd9e130000000000000000000000003efedddeed8d7eaeb7d2d964f4f365cc66cd9e1300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000007b8bafdbbfb50a891e627d20508cda2988b817260000000000000000000000007b8bafdbbfb50a891e627d20508cda2988b81726000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090f21c3b410072a886703c1a30f70378c8367bac00000000000000000000000090f21c3b410072a886703c1a30f70378c8367bac00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5084,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d83d580e194ed1d3df1d1315912c905ebb21d26a000000000000000000000000d83d580e194ed1d3df1d1315912c905ebb21d26a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5085,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060a4c36f24e7c8668a5533766d51d50a5331366d00000000000000000000000060a4c36f24e7c8668a5533766d51d50a5331366d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5086,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000005c2930356784c160a667c5673b2ef1996b9d69570000000000000000000000005c2930356784c160a667c5673b2ef1996b9d6957000000000000000000000000000000000000000000000001de2bdb8264d4cb8500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091f886f277cb32c24455b2fb8695dc1a1aad01d600000000000000000000000091f886f277cb32c24455b2fb8695dc1a1aad01d600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b7645f44ab4bd0a4edd00db6a4da9074fb8d8f80000000000000000000000001b7645f44ab4bd0a4edd00db6a4da9074fb8d8f800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000642970fa022ea7e17d4927691f59c3ba46554cb2000000000000000000000000642970fa022ea7e17d4927691f59c3ba46554cb200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5090,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3b9ce7f164a8a7e520ac46ba7eac65ae2394d74000000000000000000000000f3b9ce7f164a8a7e520ac46ba7eac65ae2394d7400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5091,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000363508d7b605b4ef829f16a1b29968b7553733ae000000000000000000000000363508d7b605b4ef829f16a1b29968b7553733ae00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d3b604a8f4cf11588ede649f1bd8f89569198d40000000000000000000000000d3b604a8f4cf11588ede649f1bd8f89569198d400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000375ec6cf33b035b8cf5f68bcdcd4aca8bf92aea1000000000000000000000000375ec6cf33b035b8cf5f68bcdcd4aca8bf92aea100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000877b97d30ab9fdec5e09da78d5caf245ad25e027000000000000000000000000877b97d30ab9fdec5e09da78d5caf245ad25e02700000000000000000000000000000000000000000000000000000000020a0df000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001168a9a9d9bbe07530df288e268f73e704f45c350000000000000000000000001168a9a9d9bbe07530df288e268f73e704f45c3500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5096,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074b56f1c91a2557939db5faf7b0c8df190e653b800000000000000000000000074b56f1c91a2557939db5faf7b0c8df190e653b800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003cf61f00721fddf7ee026c33fdcd5f23d70d5ec50000000000000000000000003cf61f00721fddf7ee026c33fdcd5f23d70d5ec500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5098,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059651d28e14a422e14cac75a1adc07fa8d743afb00000000000000000000000059651d28e14a422e14cac75a1adc07fa8d743afb00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5099,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b1030ddf0fec2b6136550c8195ae99caddf4a680000000000000000000000005b1030ddf0fec2b6136550c8195ae99caddf4a6800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5100,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b6db660ec54b809579f70b901aad272c45834910000000000000000000000001b6db660ec54b809579f70b901aad272c458349100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db23e2c8d54973df91917e22943b65d99b050b78000000000000000000000000db23e2c8d54973df91917e22943b65d99b050b7800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5102,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037a8209e3e658e16ad62361cc1560359324f703400000000000000000000000037a8209e3e658e16ad62361cc1560359324f703400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5103,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000070cf8841372eab5d939ce3f7703f068ac4ea92e000000000000000000000000070cf8841372eab5d939ce3f7703f068ac4ea92e000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5104,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f45f9b40c7a7fa66e2d1eb259a463ed60d0701b0000000000000000000000002f45f9b40c7a7fa66e2d1eb259a463ed60d0701b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003664349a38d509eba3b9477f26b8c9c900bec89b0000000000000000000000003664349a38d509eba3b9477f26b8c9c900bec89b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5106,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042b801dedb7f2c90bff9c787ca7d50be659c925900000000000000000000000042b801dedb7f2c90bff9c787ca7d50be659c925900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ec5b8820356f4b53b6985e7fed01a7911f54d2d0000000000000000000000007ec5b8820356f4b53b6985e7fed01a7911f54d2d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5108,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001125f5d40d3708bf9ba2438d542b125707be24620000000000000000000000001125f5d40d3708bf9ba2438d542b125707be246200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5109,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091db989532cb978665423ad55fd8b9cb0476f5d100000000000000000000000091db989532cb978665423ad55fd8b9cb0476f5d100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5110,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b140f83c7a2502a36f71fca69aef1bea0223e460000000000000000000000006b140f83c7a2502a36f71fca69aef1bea0223e4600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5111,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f77c54df6e8783ebb224695866dea18757cfce1a000000000000000000000000f77c54df6e8783ebb224695866dea18757cfce1a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5112,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd7b0dc4cc48e8748fb3d30be2b4b05ac2dcb32b000000000000000000000000dd7b0dc4cc48e8748fb3d30be2b4b05ac2dcb32b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5115,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a43e62c525531a21620addbac63a1c31f36d1fc6000000000000000000000000a43e62c525531a21620addbac63a1c31f36d1fc600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5116,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ab120e7d26d6aadd2034e7dc8ee9e71b6776c010000000000000000000000006ab120e7d26d6aadd2034e7dc8ee9e71b6776c0100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5117,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4f6c31a81d46725c352889c6b2e12d2f9108d9a000000000000000000000000d4f6c31a81d46725c352889c6b2e12d2f9108d9a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5118,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ac03be125c9dc1ba195a4724246f4e2938191800000000000000000000000009ac03be125c9dc1ba195a4724246f4e29381918000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5119,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007604a95fa996c51ed0c7b79cc932441efe403fe40000000000000000000000007604a95fa996c51ed0c7b79cc932441efe403fe400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b8663965dc40d17aad211936daf6267b5f7a16b0000000000000000000000002b8663965dc40d17aad211936daf6267b5f7a16b000000000000000000000000000000000000000000000000001f1abf669efb5e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000081a473df6d2c7ed704230153ccb8c5d9a505b07000000000000000000000000081a473df6d2c7ed704230153ccb8c5d9a505b0700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045ea183a7daf2b82610a4f8e68f65243c0f360e900000000000000000000000045ea183a7daf2b82610a4f8e68f65243c0f360e9000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c53a9720211ad3370fae5837371462b1eb1de0db000000000000000000000000c53a9720211ad3370fae5837371462b1eb1de0db000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5124,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f55ef9fcad3d864cd08d30d6c92acd61f5ce5f86000000000000000000000000f55ef9fcad3d864cd08d30d6c92acd61f5ce5f8600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000731ae2c51a3f8d765fde66d14e669dcf030a4a4b000000000000000000000000731ae2c51a3f8d765fde66d14e669dcf030a4a4b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5126,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003daa719ad16020634aacfebf13defeceead15f510000000000000000000000003daa719ad16020634aacfebf13defeceead15f510000000000000000000000000000000000000000000000000008a5ec77e6053b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5127,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015c09552494f8e969f1d96b4b83735b72f491db400000000000000000000000015c09552494f8e969f1d96b4b83735b72f491db4000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5128,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c13ffa37fdc78fadd8ed0e9bf9833a435725fd77000000000000000000000000c13ffa37fdc78fadd8ed0e9bf9833a435725fd7700000000000000000000000000000000000000000000000000356e1cd5a0107200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5129,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025caf39455495c39c599700bf7187718d195f49100000000000000000000000025caf39455495c39c599700bf7187718d195f49100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003fde77ca6fab639e4b4d02509b5dab5c6e6fcefe0000000000000000000000003fde77ca6fab639e4b4d02509b5dab5c6e6fcefe00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d17e9a93e0396d0eb5d5e48b9b54782f6d1a8360000000000000000000000001d17e9a93e0396d0eb5d5e48b9b54782f6d1a836000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d4d00d3fc5aa2cba1df644ab6e89df38cb276730000000000000000000000000d4d00d3fc5aa2cba1df644ab6e89df38cb2767300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000534453452c6f72e5bbf7c4afa9e76228c2d0c0a4000000000000000000000000534453452c6f72e5bbf7c4afa9e76228c2d0c0a400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009437cadead20b62e178494105c9023c874ceef9a0000000000000000000000009437cadead20b62e178494105c9023c874ceef9a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046dfac775041c1fa8ca013c25fdb1fb61cd6642000000000000000000000000046dfac775041c1fa8ca013c25fdb1fb61cd6642000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000464cd1b13f62d25226f1d38dc0ecfea2a38e1a10000000000000000000000000464cd1b13f62d25226f1d38dc0ecfea2a38e1a1000000000000000000000000000000000000000000000000001d413fda682e4f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5137,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a8b1567856358e3f0009c90c2075fac8a4019620000000000000000000000003a8b1567856358e3f0009c90c2075fac8a40196200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5138,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071a5f9098e14d527bf9f183a6902fa423f0c5ec800000000000000000000000071a5f9098e14d527bf9f183a6902fa423f0c5ec8000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5139,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006483218c93004f184b20f9a8eba04c408104ca4e0000000000000000000000006483218c93004f184b20f9a8eba04c408104ca4e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c9ecedb72533f58e189c4d1291d87312f1253880000000000000000000000006c9ecedb72533f58e189c4d1291d87312f12538800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5141,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0f8f9ba307045ffd866add6f7c6ddcc99f35cac000000000000000000000000a0f8f9ba307045ffd866add6f7c6ddcc99f35cac00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5142,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d44b22adcbb1be539ade0b45c392996863180ceb000000000000000000000000d44b22adcbb1be539ade0b45c392996863180ceb00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f913066302af3e8872bbc65496872d1d6f270429000000000000000000000000f913066302af3e8872bbc65496872d1d6f27042900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5144,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f579dda8080dd092e891dc6a00622f46d9b4e7b2000000000000000000000000f579dda8080dd092e891dc6a00622f46d9b4e7b200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5145,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041f3e0ff13d91feb6f0cc3f3b5269b8d519aedd200000000000000000000000041f3e0ff13d91feb6f0cc3f3b5269b8d519aedd200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c58bc4a0a869b901644982c99f038b8268c3c9f3000000000000000000000000c58bc4a0a869b901644982c99f038b8268c3c9f300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5147,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004926f61b042442166a2942a3ec46f37cb97ba6f40000000000000000000000004926f61b042442166a2942a3ec46f37cb97ba6f4000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096aa6052c7abf2f9a578008b3435b1cca027e0e900000000000000000000000096aa6052c7abf2f9a578008b3435b1cca027e0e900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efb3e1a1a4a553248f7c4742a4f3ecdeb614b0c7000000000000000000000000efb3e1a1a4a553248f7c4742a4f3ecdeb614b0c7000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5150,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ccd3be5225cb8f7e58202398330d343a8254b8e4000000000000000000000000ccd3be5225cb8f7e58202398330d343a8254b8e400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae2d97a7d5e2923bae593bcec28f950bde7e7623000000000000000000000000ae2d97a7d5e2923bae593bcec28f950bde7e762300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5152,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efb3e1a1a4a553248f7c4742a4f3ecdeb614b0c7000000000000000000000000efb3e1a1a4a553248f7c4742a4f3ecdeb614b0c7000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a11d47eebdca5a10125047259c123ab22716f4f0000000000000000000000000a11d47eebdca5a10125047259c123ab22716f4f0000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5154,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e6ce0ba52556d871edfdef653b2b8c570cc89e80000000000000000000000007e6ce0ba52556d871edfdef653b2b8c570cc89e800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5155,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004637d0439527619e3dc8482c11bbc5a97ef6c4090000000000000000000000004637d0439527619e3dc8482c11bbc5a97ef6c409000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7076b2a73c654a23d73b1007f31e0518fc3dfe4000000000000000000000000a7076b2a73c654a23d73b1007f31e0518fc3dfe4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5157,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000681874d70d2ee3fe858c02c56e96ec722e864c6a000000000000000000000000681874d70d2ee3fe858c02c56e96ec722e864c6a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5158,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6612097eff6defa0f70a20308d98db40f0d8b73000000000000000000000000b6612097eff6defa0f70a20308d98db40f0d8b7300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000003d17633cde823657abce86e514785e4fc19161000000000000000000000000003d17633cde823657abce86e514785e4fc19161000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5161,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d75ffa03684d7b92f50b72833047963a1029f04b000000000000000000000000d75ffa03684d7b92f50b72833047963a1029f04b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5162,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006856b58f89ac4646039b5e2adcddb20fa18b590c0000000000000000000000006856b58f89ac4646039b5e2adcddb20fa18b590c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069e9a4dcb5cfe4776083a2a4f93437ae78e9166900000000000000000000000069e9a4dcb5cfe4776083a2a4f93437ae78e91669000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5164,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037fd65e19beccae404be8f4fb5e65b8ac7dd96fe00000000000000000000000037fd65e19beccae404be8f4fb5e65b8ac7dd96fe000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5165,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004867063da4d6c3717bdc0a5d87a370a022bbb8aa0000000000000000000000004867063da4d6c3717bdc0a5d87a370a022bbb8aa000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c03086a0db933b7e5ffe8430f698a955b25859b0000000000000000000000008c03086a0db933b7e5ffe8430f698a955b25859b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5167,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce3711b0900c00912b8b388ab0c619437e9bf6a9000000000000000000000000ce3711b0900c00912b8b388ab0c619437e9bf6a9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001641669254cb47d614586c0c049b653f247a54a40000000000000000000000001641669254cb47d614586c0c049b653f247a54a4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5169,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000470bd03ead42a683dc30ac39ec136a0c0325fb2b000000000000000000000000470bd03ead42a683dc30ac39ec136a0c0325fb2b000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5170,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054baccf09a47265b1166364dc17f560e58462c2e00000000000000000000000054baccf09a47265b1166364dc17f560e58462c2e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012897bcabbdb34a9761562c59eab49b22b59e8b700000000000000000000000012897bcabbdb34a9761562c59eab49b22b59e8b70000000000000000000000000000000000000000000000000009a0c5a5428f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5172,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004778c3cd7bd498e8c8212775876c95352b6780ab0000000000000000000000004778c3cd7bd498e8c8212775876c95352b6780ab000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5173,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a288945a3524d996265ff3c2ecf5ed329b192f60000000000000000000000009a288945a3524d996265ff3c2ecf5ed329b192f6000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000400b1f85bcac75499ac094d72a2aee0aa88b9236000000000000000000000000400b1f85bcac75499ac094d72a2aee0aa88b923600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5175,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efb3e1a1a4a553248f7c4742a4f3ecdeb614b0c7000000000000000000000000efb3e1a1a4a553248f7c4742a4f3ecdeb614b0c7000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e900fd85cae85971e684dd56b2eee1c542bb08e0000000000000000000000000e900fd85cae85971e684dd56b2eee1c542bb08e000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a55e93fd3cce2cf40d43824b2f18889f404ddf57000000000000000000000000a55e93fd3cce2cf40d43824b2f18889f404ddf57000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001eea4cd714c11cbfa1117325743fab95140c71050000000000000000000000001eea4cd714c11cbfa1117325743fab95140c710500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ec0153679dc5f92de0e593a11a855f68e79263a0000000000000000000000005ec0153679dc5f92de0e593a11a855f68e79263a00000000000000000000000000000000000000000000000001d5c3e8b3145a7200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008212abb29d65e20b5dba67950abc03d8e88af32d0000000000000000000000008212abb29d65e20b5dba67950abc03d8e88af32d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004608a905c141dfd4bd31280bafacdc29d40092c70000000000000000000000004608a905c141dfd4bd31280bafacdc29d40092c7000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034b5b3a130dc7fee0ba9eab67dcfa7bb9342d0b800000000000000000000000034b5b3a130dc7fee0ba9eab67dcfa7bb9342d0b800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057c6fc00ada30222a5d25f48c07692f352d11abd00000000000000000000000057c6fc00ada30222a5d25f48c07692f352d11abd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5184,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cbda63ab9186d62792b6cacb45ce9dcef4faee90000000000000000000000006cbda63ab9186d62792b6cacb45ce9dcef4faee9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d88b64bdea80595c13e0bde5782998a3dc314903000000000000000000000000d88b64bdea80595c13e0bde5782998a3dc31490300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5186,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcd02843e312979e7e07e65725136ab91e0bd460000000000000000000000000fcd02843e312979e7e07e65725136ab91e0bd46000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5187,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a3d0b7a441e85b99b876c72d0d031ed27b307ff0000000000000000000000002a3d0b7a441e85b99b876c72d0d031ed27b307ff00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5188,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a886fb5ae7e8f1d45e9f76e5c8d352f829968726000000000000000000000000a886fb5ae7e8f1d45e9f76e5c8d352f82996872600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5189,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c52971bb63f84c467e38b95e1492d613c9380910000000000000000000000000c52971bb63f84c467e38b95e1492d613c93809100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5190,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006abff89d51064459b897e00a5416aec2c4ce2ea70000000000000000000000006abff89d51064459b897e00a5416aec2c4ce2ea700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5191,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b700bd8e560b63738c7ca36a22ad47b51af3fdd0000000000000000000000008b700bd8e560b63738c7ca36a22ad47b51af3fdd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5192,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f541d31546b4c1cc5f3c78f26515dcb7290d2e63000000000000000000000000f541d31546b4c1cc5f3c78f26515dcb7290d2e6300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b63aba9dd4b07c20d1d21430274e2f1b927cad01000000000000000000000000b63aba9dd4b07c20d1d21430274e2f1b927cad0100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5196,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6e43242bc4eaf2fedd216884524951a296e9883000000000000000000000000d6e43242bc4eaf2fedd216884524951a296e9883000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5197,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c57e133430fc4fc73d9994afc75e9a3e3a2bfdd0000000000000000000000004c57e133430fc4fc73d9994afc75e9a3e3a2bfdd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5198,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6af8f97c444fe8454af14023e4f316815101af2000000000000000000000000f6af8f97c444fe8454af14023e4f316815101af200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5199,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009accc104a0453083c5c6e225c77fef20775c1ddf0000000000000000000000000000000000000000000000172238756f25ef922f,0x1a983c22304ace95fe4f64f7b08a227bfdbe9702ceca7a824aafcd59e4b43b0d,2022-04-17 18:14:58.000 UTC,0,true +5200,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f69269c8bed1981b5532e2aaeadfbab34dc596fe000000000000000000000000f69269c8bed1981b5532e2aaeadfbab34dc596fe000000000000000000000000000000000000000000000000004b98dffd817b3100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5201,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017d2af86b679a934431fb0530f6dec73c572ba2e00000000000000000000000017d2af86b679a934431fb0530f6dec73c572ba2e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5202,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b23e35e554c48005f8fe2dff278ef8518133a02a000000000000000000000000b23e35e554c48005f8fe2dff278ef8518133a02a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5203,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ddf2649e6bc35d8af214da61308bf4e43b0f6b20000000000000000000000004ddf2649e6bc35d8af214da61308bf4e43b0f6b2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000757f2b4dc16549d1171ed9afa9ce79408e07e8c4000000000000000000000000757f2b4dc16549d1171ed9afa9ce79408e07e8c400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5205,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a27a24432421dcbd4a7f62c444ab68277e705420000000000000000000000003a27a24432421dcbd4a7f62c444ab68277e70542000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001febf84fee73d9618f213a201ddad1651fdecc110000000000000000000000001febf84fee73d9618f213a201ddad1651fdecc1100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3e03bf610c2abc4888aa24a15ff225ac9a6df3b000000000000000000000000d3e03bf610c2abc4888aa24a15ff225ac9a6df3b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025edbddad5c8842dfe510b96f0b64a6fe48ba5d900000000000000000000000025edbddad5c8842dfe510b96f0b64a6fe48ba5d9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004043bff29f796ecbb2df2d3527b736436321e1bb0000000000000000000000004043bff29f796ecbb2df2d3527b736436321e1bb00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a875bbb57298590f72ee1659fbd45973cdf7ff30000000000000000000000001a875bbb57298590f72ee1659fbd45973cdf7ff3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5211,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4a4813fb0285d92ec2f66cb4c90491776fd279a000000000000000000000000f4a4813fb0285d92ec2f66cb4c90491776fd279a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5212,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084336491f96883b1c236ce63a3921cfcf6dbadd500000000000000000000000084336491f96883b1c236ce63a3921cfcf6dbadd5000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5213,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f2edd4daae9e807dc607b84c98a919fad8ac2120000000000000000000000006f2edd4daae9e807dc607b84c98a919fad8ac21200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5214,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cb4bb6da78577e18b183f5ec93995b3e42fe4c80000000000000000000000002cb4bb6da78577e18b183f5ec93995b3e42fe4c8000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000136ef350085641008bdc271a4eb19b084d40bc55000000000000000000000000136ef350085641008bdc271a4eb19b084d40bc5500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3f0ecec2511bc9c80f9a22f581bc8ded71b5dac000000000000000000000000c3f0ecec2511bc9c80f9a22f581bc8ded71b5dac00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5217,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d967a67e2f3a87952cb61aa47bee567ed9801d60000000000000000000000001d967a67e2f3a87952cb61aa47bee567ed9801d600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006492af84362e4a176b9672ef3759099bf401051d0000000000000000000000006492af84362e4a176b9672ef3759099bf401051d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee67daf4d0e40af9bb29d0c8a9ef7e88bee4a67a000000000000000000000000ee67daf4d0e40af9bb29d0c8a9ef7e88bee4a67a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5220,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a932e8b317d3193e258a5b47e8932f961f1ad380000000000000000000000005a932e8b317d3193e258a5b47e8932f961f1ad38000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b38857d4c47997ebb95cb6b43c9fcdf212504c11000000000000000000000000b38857d4c47997ebb95cb6b43c9fcdf212504c1100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a192e8015f2e7fc714f7ccafc4a8cc951dae32d0000000000000000000000000a192e8015f2e7fc714f7ccafc4a8cc951dae32d000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5223,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002901e47e5ca1f6b3a1a8fa1dfff88fda27782e0c0000000000000000000000002901e47e5ca1f6b3a1a8fa1dfff88fda27782e0c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5224,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e31fdb4dec937e220b28adeef0cd4c2563f3a5c0000000000000000000000001e31fdb4dec937e220b28adeef0cd4c2563f3a5c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051f7851943420194e50dbbf76abbc60faa5cb24400000000000000000000000051f7851943420194e50dbbf76abbc60faa5cb244000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5226,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a18d51cd028e4cb4fffd44c385dc67144fefcb00000000000000000000000001a18d51cd028e4cb4fffd44c385dc67144fefcb0000000000000000000000000000000000000000000000000004a9b638448800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5227,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004748a7408abac38fcefc62e35da9868eb3b78ebe0000000000000000000000004748a7408abac38fcefc62e35da9868eb3b78ebe000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5228,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d343187fe6ec0578a350c8255bae21ecf2643ca0000000000000000000000000d343187fe6ec0578a350c8255bae21ecf2643ca000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5229,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b43b826750f2e99b722254b860f7235d15c6c736000000000000000000000000b43b826750f2e99b722254b860f7235d15c6c73600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5230,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df0ce34b903c62a5cfb43b620eaeb4dd726b92c8000000000000000000000000df0ce34b903c62a5cfb43b620eaeb4dd726b92c8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5231,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3503c57358b3b792ece9351c0630b3f35721712000000000000000000000000f3503c57358b3b792ece9351c0630b3f35721712000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055a134595ded9987d1ebd6bd39e28c177bbf5cf900000000000000000000000055a134595ded9987d1ebd6bd39e28c177bbf5cf900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c166c81a8dcfd45a44267b10dfd6192a5a27ea3b000000000000000000000000c166c81a8dcfd45a44267b10dfd6192a5a27ea3b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f210e462eef3da98fc1a4ebff0706e74d4f521d0000000000000000000000003f210e462eef3da98fc1a4ebff0706e74d4f521d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039ebb809e994739b83c0d51106af549fbd0fb21f00000000000000000000000039ebb809e994739b83c0d51106af549fbd0fb21f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c78e2adc94900e03fe98cfa7aecfa6d8b32559d0000000000000000000000002c78e2adc94900e03fe98cfa7aecfa6d8b32559d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5237,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f9d95c03776186f58d6021d6cff7eedea4ece030000000000000000000000005f9d95c03776186f58d6021d6cff7eedea4ece03000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c13f93146dd9cf19a1b1a6e99c19dbec4dc10979000000000000000000000000c13f93146dd9cf19a1b1a6e99c19dbec4dc109790000000000000000000000000000000000000000000000000119854e788acd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5d583aa33b9d2970714f37d9a4d3dd4dc39690d000000000000000000000000a5d583aa33b9d2970714f37d9a4d3dd4dc39690d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5241,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6fe9aa605b0aceef8891076489204334d50b7c3000000000000000000000000a6fe9aa605b0aceef8891076489204334d50b7c300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5243,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008210cee4975b26ae67ec7f4e8cc505740924bee60000000000000000000000008210cee4975b26ae67ec7f4e8cc505740924bee60000000000000000000000000000000000000000000000000012094fad0d8ea700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084df5e05e52d377ac45f588e736e37b9c77a6f3100000000000000000000000084df5e05e52d377ac45f588e736e37b9c77a6f31000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5245,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2bcba5310c6a93eb4613e7a5ecce02b25be4a4d000000000000000000000000a2bcba5310c6a93eb4613e7a5ecce02b25be4a4d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000477222d8683f29947c50c67d8c8ba9955aa0269e000000000000000000000000477222d8683f29947c50c67d8c8ba9955aa0269e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5247,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021f23c8bc2875fcec3f9690cdb22a32fd389e89600000000000000000000000021f23c8bc2875fcec3f9690cdb22a32fd389e896000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e92e41395d76c7255c0cc2cafc41ecaa4bc15050000000000000000000000000e92e41395d76c7255c0cc2cafc41ecaa4bc1505000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5249,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a5cac76fbbdcc0f1ef8e1a07ff188f6e42374000000000000000000000000009a5cac76fbbdcc0f1ef8e1a07ff188f6e4237400000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068a180a647b6e1f0ab4d6c3930adf66d06b64d0400000000000000000000000068a180a647b6e1f0ab4d6c3930adf66d06b64d04000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5f879cfbc6ff77b60b063ecc01b92716dbaa1af000000000000000000000000d5f879cfbc6ff77b60b063ecc01b92716dbaa1af00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5252,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef3afb502c56a4a3ce43586d62e6e4c775fc5edc000000000000000000000000ef3afb502c56a4a3ce43586d62e6e4c775fc5edc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5254,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8d0f7cfed9ac546a6261c0c3bd99e005e8d1bc6000000000000000000000000e8d0f7cfed9ac546a6261c0c3bd99e005e8d1bc6000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f10e1ad433711989d1620baa81c0e28aef43eff0000000000000000000000001f10e1ad433711989d1620baa81c0e28aef43eff00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc046ce31027ac1c8ac6333f686f574aa4da5e8e000000000000000000000000fc046ce31027ac1c8ac6333f686f574aa4da5e8e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5257,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042e4229a7aac161fac4bd0e8a8ecc7b26970aaa400000000000000000000000042e4229a7aac161fac4bd0e8a8ecc7b26970aaa4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5258,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004dd9e316a13e69e1a1955e9b080c3eda84c839d00000000000000000000000004dd9e316a13e69e1a1955e9b080c3eda84c839d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008177d61d9ebcf431dea91a44a3de5ad9912761470000000000000000000000008177d61d9ebcf431dea91a44a3de5ad99127614700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5260,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3bf310a2a8f882788dae5bb2266863d6bb35bf8000000000000000000000000e3bf310a2a8f882788dae5bb2266863d6bb35bf8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5261,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eff30cfe706c00caa925bfb6b7a2b3a469dd7587000000000000000000000000eff30cfe706c00caa925bfb6b7a2b3a469dd7587000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5262,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e23ea4f5031a7ff95c35f59be23915548af3ecf2000000000000000000000000e23ea4f5031a7ff95c35f59be23915548af3ecf2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a23c1688d867fa92db4af59f579612128d443b61000000000000000000000000a23c1688d867fa92db4af59f579612128d443b6100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5264,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6ad626bbfe42a100e17881844a4b0a7b5c90ca0000000000000000000000000b6ad626bbfe42a100e17881844a4b0a7b5c90ca0000000000000000000000000000000000000000000000000004bb0cf277174a900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5265,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de4f6dd4723cfa55e0a82cb19fd82e264c2bc395000000000000000000000000de4f6dd4723cfa55e0a82cb19fd82e264c2bc395000000000000000000000000000000000000000000000000006ba0016b980a2600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5266,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004acc7859f692c540a8f18fe63f6aa4f847c076e10000000000000000000000004acc7859f692c540a8f18fe63f6aa4f847c076e100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5267,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027ed73802cbeb0fe1653873dbb80d2ff31f3f52e00000000000000000000000027ed73802cbeb0fe1653873dbb80d2ff31f3f52e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000213d547441446f4a9f27cc9af59bcaac052ee933000000000000000000000000213d547441446f4a9f27cc9af59bcaac052ee93300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a8de74cbe47c1602b64a4d40607761fe1cebca80000000000000000000000003a8de74cbe47c1602b64a4d40607761fe1cebca800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5270,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea20a895f36b7d8c45e2a75efed8b88945b0dfe6000000000000000000000000ea20a895f36b7d8c45e2a75efed8b88945b0dfe600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5271,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000085f5228040a3a56506a3dfdd8ddb110f5fa2532000000000000000000000000085f5228040a3a56506a3dfdd8ddb110f5fa253200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fc2236ac32307df8ab5116024b5c73827c37ceb0000000000000000000000008fc2236ac32307df8ab5116024b5c73827c37ceb0000000000000000000000000000000000000000000000000095dc1de61d34b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5273,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec4738df2cd2e8c5b438720f0cc046d91db5c7d9000000000000000000000000ec4738df2cd2e8c5b438720f0cc046d91db5c7d900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000dcdbc5ef852964945ba5d4772b26dacffcd9f59d000000000000000000000000dcdbc5ef852964945ba5d4772b26dacffcd9f59d0000000000000000000000000000000000000000000000000000000002fc352a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035026c1fd9e765c43e335f5be94d96def205834d00000000000000000000000035026c1fd9e765c43e335f5be94d96def205834d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8d15c8b69d542b37cb046c0381f1d4bccf93b39000000000000000000000000e8d15c8b69d542b37cb046c0381f1d4bccf93b3900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5278,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfbc289e4660ebd611f880c263dd52b81024b041000000000000000000000000cfbc289e4660ebd611f880c263dd52b81024b04100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a49d9c803a500248b8718eaa39a893bf486e6100000000000000000000000001a49d9c803a500248b8718eaa39a893bf486e61000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cd3a4ae02572ee2889511615b0418a5692b6c2c0000000000000000000000004cd3a4ae02572ee2889511615b0418a5692b6c2c000000000000000000000000000000000000000000000000000e86572714a1ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081148ff43841d273b9c0ce73c39758e68a5cedeb00000000000000000000000081148ff43841d273b9c0ce73c39758e68a5cedeb00000000000000000000000000000000000000000000000000b218429a13a4ab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff01ee666547c77061c49b87f613a26c7de81638000000000000000000000000ff01ee666547c77061c49b87f613a26c7de8163800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000033d15d8d7e51a5875640e7e580d86e84dd16ab4000000000000000000000000033d15d8d7e51a5875640e7e580d86e84dd16ab4000000000000000000000000000000000000000000000000001a4358cabc540000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5284,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000699d69f311c745187510aa6130c55f6b79d9e083000000000000000000000000699d69f311c745187510aa6130c55f6b79d9e08300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5285,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f118f2728e205bf589d871cfe7cb8cab937a3ed5000000000000000000000000f118f2728e205bf589d871cfe7cb8cab937a3ed500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff10964bbe2e6accd98c159dc49525c8c8092976000000000000000000000000ff10964bbe2e6accd98c159dc49525c8c809297600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5287,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fab259ec89398d21704b880628c9127c0b813851000000000000000000000000fab259ec89398d21704b880628c9127c0b81385100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5288,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff9f20367488f3386a97bc3897798b0e8bd1b2da000000000000000000000000ff9f20367488f3386a97bc3897798b0e8bd1b2da0000000000000000000000000000000000000000000000000000f9f14221b43b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5289,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f65d674d08d881ed614b5a10384870f5208cdb8a000000000000000000000000f65d674d08d881ed614b5a10384870f5208cdb8a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a94db14a4979e91e573caf7ac710d18514e7c43d000000000000000000000000a94db14a4979e91e573caf7ac710d18514e7c43d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5293,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000033d15d8d7e51a5875640e7e580d86e84dd16ab4000000000000000000000000033d15d8d7e51a5875640e7e580d86e84dd16ab400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa3a931e382151ab19a6f239a88275729139ee5e000000000000000000000000aa3a931e382151ab19a6f239a88275729139ee5e0000000000000000000000000000000000000000000000000005b8883354787400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5295,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000052f11eb31ea2b16d2a38d9e24f32a9c60366742000000000000000000000000052f11eb31ea2b16d2a38d9e24f32a9c6036674200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5296,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0a70396fb43b8ba490060c95aa18edc3fd75499000000000000000000000000c0a70396fb43b8ba490060c95aa18edc3fd7549900000000000000000000000000000000000000000000000001416bb02880d06300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5299,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcabd0beb3322ae01bb0f7a6ddceb7ae08816496000000000000000000000000fcabd0beb3322ae01bb0f7a6ddceb7ae0881649600000000000000000000000000000000000000000000000000153ad037d13f7e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5300,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cf9e4db024bafc59fbae2264b6ab91eb902a8dc0000000000000000000000007cf9e4db024bafc59fbae2264b6ab91eb902a8dc00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e58bdee94a421f967ad93a0c937681e9c75aafc0000000000000000000000006e58bdee94a421f967ad93a0c937681e9c75aafc0000000000000000000000000000000000000000000000000034ecbb6f8b00b700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5302,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ef16fc940c3e88f1bfa1edb3615ca0ae8496a310000000000000000000000008ef16fc940c3e88f1bfa1edb3615ca0ae8496a3100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9442b2a71a85967f59c799c0b45ea048620dad0000000000000000000000000b9442b2a71a85967f59c799c0b45ea048620dad00000000000000000000000000000000000000000000000000015e6f5ac9efb8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5304,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003eeb6da567597f5e61609ea2cd55531f61663b0a0000000000000000000000003eeb6da567597f5e61609ea2cd55531f61663b0a000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5305,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000093907de38066d70109935732757b625d636e47b600000000000000000000000093907de38066d70109935732757b625d636e47b60000000000000000000000000000000000000000000000059569dbfedc46237e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5307,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f785621f8ebf63207559ed2df3a087ef44d9b2c4000000000000000000000000f785621f8ebf63207559ed2df3a087ef44d9b2c4000000000000000000000000000000000000000000000000003654696dc0650000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5308,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de34f7c26fa503a3b8fe80e2df4e62a30d4dc86c000000000000000000000000de34f7c26fa503a3b8fe80e2df4e62a30d4dc86c000000000000000000000000000000000000000000000000008abda7d91f037900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5309,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000255749ce8ab1dd14c09787e7405a15ff17c24459000000000000000000000000255749ce8ab1dd14c09787e7405a15ff17c2445900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5310,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095b3d55ebee4dda802f8b86cf08779a3ef97015b00000000000000000000000095b3d55ebee4dda802f8b86cf08779a3ef97015b000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5311,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b44367a09051fe452f9b2a2955ad97c73ad355bb000000000000000000000000b44367a09051fe452f9b2a2955ad97c73ad355bb0000000000000000000000000000000000000000000000000096e72c32e30acd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5312,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001aa008151d2dd54679a48653b4527bb4ca82e3fe0000000000000000000000001aa008151d2dd54679a48653b4527bb4ca82e3fe000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5313,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b169602074599dea52fff5e89787dca7744f42e7000000000000000000000000b169602074599dea52fff5e89787dca7744f42e70000000000000000000000000000000000000000000000000015aac31bfa817e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5314,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002af3c89625e7679083cd1c48b0b9e54387d5f5390000000000000000000000002af3c89625e7679083cd1c48b0b9e54387d5f539000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5315,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001961b12feffeac651c293277920636d6cdd0e4dc0000000000000000000000001961b12feffeac651c293277920636d6cdd0e4dc000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013bf4152e8b499b15f272fd61eb4dabe88072d9f00000000000000000000000013bf4152e8b499b15f272fd61eb4dabe88072d9f0000000000000000000000000000000000000000000000000096e051387c824c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081178b143737677629d61d47199d76a32b537d9600000000000000000000000081178b143737677629d61d47199d76a32b537d960000000000000000000000000000000000000000000000000107f272d040b65200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf380a24ef40672bcacf8bc5cc2b5f38ef58081293b95ce3eaae1ef3d866b9e96,2022-08-15 20:42:51.000 UTC,0,true +5319,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3bcf7fb3ece89c19e58ea5460dffc28ffd43aa0000000000000000000000000b3bcf7fb3ece89c19e58ea5460dffc28ffd43aa00000000000000000000000000000000000000000000000000099d8f8a5c684c500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5320,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000471f5c9e664827b81f7fc7297f64da33bd8b18b5000000000000000000000000471f5c9e664827b81f7fc7297f64da33bd8b18b5000000000000000000000000000000000000000000000000001c0289df89710000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5321,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c08f3cc0aa473f15113d36fa2398d1532e9feec2000000000000000000000000c08f3cc0aa473f15113d36fa2398d1532e9feec2000000000000000000000000000000000000000000000000004296d3418d05e800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5322,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c29c1c75efe25e27c1d0c9e97c4ac18f24a60a000000000000000000000000b8c29c1c75efe25e27c1d0c9e97c4ac18f24a60a0000000000000000000000000000000000000000000000000033cfd4b9b19bc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009303002f61b7db55fd981e16bb01177a9bcd8bcf0000000000000000000000009303002f61b7db55fd981e16bb01177a9bcd8bcf00000000000000000000000000000000000000000000000000ab4ee308efd40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5324,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8d870c2b7f63e9af2ec1e4690cbe196c05efc7f000000000000000000000000f8d870c2b7f63e9af2ec1e4690cbe196c05efc7f000000000000000000000000000000000000000000000000009affdd6c1757db00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5327,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c01e57d6de118e3384ce41d6cee30627af254de0000000000000000000000004c01e57d6de118e3384ce41d6cee30627af254de000000000000000000000000000000000000000000000000009f9b176b0f4df400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000835283ae92194e867f98c70d6183a5bf4923a6a0000000000000000000000000835283ae92194e867f98c70d6183a5bf4923a6a0000000000000000000000000000000000000000000000000016fc6e43b2600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5331,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008732d8a9fa97537d8c286697e9d9adc0126171750000000000000000000000008732d8a9fa97537d8c286697e9d9adc0126171750000000000000000000000000000000000000000000000000009c63e70e9c81200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5333,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0bc05c307eda344f2a6afb2a228780e8b383af0000000000000000000000000a0bc05c307eda344f2a6afb2a228780e8b383af0000000000000000000000000000000000000000000000000059087b34ce061b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5334,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b995486de4bd894079097717fb1152ee1e6c754f000000000000000000000000b995486de4bd894079097717fb1152ee1e6c754f0000000000000000000000000000000000000000000000000008658a56c19e6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5336,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7596ed9c1d6e76ebeca641b810e6dddbe6ea9c5000000000000000000000000b7596ed9c1d6e76ebeca641b810e6dddbe6ea9c50000000000000000000000000000000000000000000000000042f20e077d010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5337,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001279b4ee0d53a0056ec829fb1051e8a1356c5d9e0000000000000000000000001279b4ee0d53a0056ec829fb1051e8a1356c5d9e0000000000000000000000000000000000000000000000000031bced02db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5338,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f70967c0256c7bb263313058858a2cd5feb65440000000000000000000000005f70967c0256c7bb263313058858a2cd5feb654400000000000000000000000000000000000000000000000000f195a3c4ba000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d8b95a0a595a9c01f1e152c07fbdba6de643472f000000000000000000000000d8b95a0a595a9c01f1e152c07fbdba6de643472f000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5341,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aad7bd9bf8523b6812a262ecb2ca5bef5256a24e000000000000000000000000aad7bd9bf8523b6812a262ecb2ca5bef5256a24e00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5342,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fd11c68f235ed87a4a25e0764ec1aa0c67a631c0000000000000000000000002fd11c68f235ed87a4a25e0764ec1aa0c67a631c000000000000000000000000000000000000000000000000001f8133a1914e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5343,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c977df4bbe96fe101675313874284b7e0561d8de000000000000000000000000c977df4bbe96fe101675313874284b7e0561d8de0000000000000000000000000000000000000000000000000155785e56f36ea400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5344,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007765a840b2a90464d4f4e85ba014ffe170b135be0000000000000000000000007765a840b2a90464d4f4e85ba014ffe170b135be00000000000000000000000000000000000000000000000000aa87bee538000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a308a53d18c8428339a03fe0f44ceb25c32259c0000000000000000000000000a308a53d18c8428339a03fe0f44ceb25c32259c0000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5348,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba6a5d1d74e056fb7ec1263a110f5bd9462df58a000000000000000000000000ba6a5d1d74e056fb7ec1263a110f5bd9462df58a0000000000000000000000000000000000000000000000000073b8c569e24ccb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f507ef3ef4d3d5cef569d72666672bfdd0a5d270000000000000000000000009f507ef3ef4d3d5cef569d72666672bfdd0a5d27000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae57f5971b276289182c02cb0a9886881d3a336d000000000000000000000000ae57f5971b276289182c02cb0a9886881d3a336d00000000000000000000000000000000000000000000000000a24c17255e857f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e89f9a34ab21e7858da997eb17d8dcdd684245b0000000000000000000000005e89f9a34ab21e7858da997eb17d8dcdd684245b000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e6e21237fd68911c9e4f17690ca016aebf58f190000000000000000000000001e6e21237fd68911c9e4f17690ca016aebf58f19000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b23da66d3a9689cde3e694ce0c0b8aafd97e1d10000000000000000000000004b23da66d3a9689cde3e694ce0c0b8aafd97e1d1000000000000000000000000000000000000000000000000009b4b9734ba9fa200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5356,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ecbc7e35d03bfb5310adb50f3208d68e57436f90000000000000000000000005ecbc7e35d03bfb5310adb50f3208d68e57436f9000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5359,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040b41de1e402e42646aa9648a6091d670618435800000000000000000000000040b41de1e402e42646aa9648a6091d6706184358000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5361,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000232e9346eeecac4d51e14c02dde61a0729a204ee000000000000000000000000232e9346eeecac4d51e14c02dde61a0729a204ee00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5363,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006463dbd8ae7dfb08cfe903cdf98ea7558faf36e60000000000000000000000006463dbd8ae7dfb08cfe903cdf98ea7558faf36e600000000000000000000000000000000000000000000016b39d0ac6fafcbb8f600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x6d5aca5fcfc7bc6bff488931e7467a36c2ef502b03f4ab9e779a82d6e65b30b6,2022-03-26 20:16:11.000 UTC,0,true +5364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080565b854b3f9b3697ee45b3e20a8cdadaab746e00000000000000000000000080565b854b3f9b3697ee45b3e20a8cdadaab746e00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e6e21237fd68911c9e4f17690ca016aebf58f190000000000000000000000001e6e21237fd68911c9e4f17690ca016aebf58f19000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f84f89fb1bfc303ac9744fe63a1c4f41b799b57a000000000000000000000000f84f89fb1bfc303ac9744fe63a1c4f41b799b57a00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017b64570484aae779d718e727e21a1b05b975da300000000000000000000000017b64570484aae779d718e727e21a1b05b975da3000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000918fe5fa6304f4bbc548aa64269352b2c7bf9489000000000000000000000000918fe5fa6304f4bbc548aa64269352b2c7bf9489000000000000000000000000000000000000000000000000001e25a45a05747900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000329ddef7737094022baefe6d6a8b258cbdd210d0000000000000000000000000329ddef7737094022baefe6d6a8b258cbdd210d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f0fdeaa067f641bcb5932ef44629e9b4a96f5d60000000000000000000000006f0fdeaa067f641bcb5932ef44629e9b4a96f5d60000000000000000000000000000000000000000000000000093f7eb0f1f106000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5373,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ebe911df04f665f84a5ba93da5090cc4076b3d46000000000000000000000000ebe911df04f665f84a5ba93da5090cc4076b3d460000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b602f5b8e0a87bb91f410bc88012b2a4b54ce360000000000000000000000009b602f5b8e0a87bb91f410bc88012b2a4b54ce36000000000000000000000000000000000000000000000000009536c70891000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087b57ac904dac73e9bc7938f510ec80d70951a0700000000000000000000000087b57ac904dac73e9bc7938f510ec80d70951a07000000000000000000000000000000000000000000000000002e1b55279714e600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e5d38340cb06c770bcff353f4ab90a1c83f1a100000000000000000000000002e5d38340cb06c770bcff353f4ab90a1c83f1a10000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5378,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f31bdf0003f7c6d6747728f6cd9741117619b470000000000000000000000001f31bdf0003f7c6d6747728f6cd9741117619b470000000000000000000000000000000000000000000000000050cbe758eab20b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5379,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e60d9c72c5ec15136b942525407d07527f2df2b7000000000000000000000000e60d9c72c5ec15136b942525407d07527f2df2b7000000000000000000000000000000000000000000000024b777f3586239995c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5380,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097a7415e1a2651f8700006f2111bc575f393773100000000000000000000000097a7415e1a2651f8700006f2111bc575f3937731000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5381,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b1fcf0eaf1e02e7ff9592bac7a42202a5d116d30000000000000000000000001b1fcf0eaf1e02e7ff9592bac7a42202a5d116d3000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5382,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e944fc5ad408665f758ece18b2e5ffe3b8eaedc9000000000000000000000000e944fc5ad408665f758ece18b2e5ffe3b8eaedc9000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096668c69449b38995e6f6fd742f128b221ba0fe400000000000000000000000096668c69449b38995e6f6fd742f128b221ba0fe40000000000000000000000000000000000000000000000000107c57b2e9519d500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5385,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000883c781c07abc91798bd8fd231563a0cc8bd9a1e000000000000000000000000883c781c07abc91798bd8fd231563a0cc8bd9a1e00000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c19f3377cb50b2b8dc4169a6073316e1abb67c20000000000000000000000004c19f3377cb50b2b8dc4169a6073316e1abb67c20000000000000000000000000000000000000000000000000866402d2256033d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001267f79d6988977411338bb494f26678c7f281ba0000000000000000000000001267f79d6988977411338bb494f26678c7f281ba000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5390,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ea0af889357f6ba2caa7e7e0899d518e396f0270000000000000000000000009ea0af889357f6ba2caa7e7e0899d518e396f027000000000000000000000000000000000000000000000000004b9cf364fe91c200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5391,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6bce9a326d67703691dda5cbcc0fa381733e6ae000000000000000000000000f6bce9a326d67703691dda5cbcc0fa381733e6ae000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000007ee17c26699fe707ac1e5f5074f4a4dafc9fa26f0000000000000000000000007ee17c26699fe707ac1e5f5074f4a4dafc9fa26f0000000000000000000000000000000000000000000000000000000007351c2600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e740245d5c4afec7655ade6854b788ec755d24d6000000000000000000000000e740245d5c4afec7655ade6854b788ec755d24d6000000000000000000000000000000000000000000000000014eebc66ccee69000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054c66b94f3b4eef7ae8cc6d95bf5dfbce778a04800000000000000000000000054c66b94f3b4eef7ae8cc6d95bf5dfbce778a048000000000000000000000000000000000000000000000000014e4384ea89f9be00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d25f942adbb4d53a53160f419abcf6b73b0aa4b9000000000000000000000000d25f942adbb4d53a53160f419abcf6b73b0aa4b90000000000000000000000000000000000000000000000000194938cce2b75ca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ba7604330b8eb2933644ba3522855d2a320dad30000000000000000000000003ba7604330b8eb2933644ba3522855d2a320dad3000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5397,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ba5f02bd1e8c6feec3561ebb34cc87f348d458a0000000000000000000000002ba5f02bd1e8c6feec3561ebb34cc87f348d458a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b758a373cb815941ad7e0657d5ff671e4bbf49d7000000000000000000000000b758a373cb815941ad7e0657d5ff671e4bbf49d7000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b885084a6c9f8ebe365ed6cdd12c9c7c9ca2b2cf000000000000000000000000b885084a6c9f8ebe365ed6cdd12c9c7c9ca2b2cf00000000000000000000000000000000000000000000000002239b9a80d42d7d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf41127a9ac8b5d19fbd196b8ad8295b2a2579f5000000000000000000000000bf41127a9ac8b5d19fbd196b8ad8295b2a2579f500000000000000000000000000000000000000000000000002216c1dc011b2db00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072c3c76bad4ead8a5d737a006663cc0a491c79b300000000000000000000000072c3c76bad4ead8a5d737a006663cc0a491c79b3000000000000000000000000000000000000000000000000006379da05b6000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5402,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d122f221d9c56afac72b04ddc48f415e540376eb000000000000000000000000d122f221d9c56afac72b04ddc48f415e540376eb000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006edc318c3103b6ba19b40ff9b009b836ebcf3f4e0000000000000000000000006edc318c3103b6ba19b40ff9b009b836ebcf3f4e000000000000000000000000000000000000000000000000009581ea081c233500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee40e804b25fc915fd2c2f6d8d2f650afbf9709a000000000000000000000000ee40e804b25fc915fd2c2f6d8d2f650afbf9709a000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000634cea5cbe400f8d19bac14b43735bce52f20680000000000000000000000000634cea5cbe400f8d19bac14b43735bce52f206800000000000000000000000000000000000000000000000000138c1e766f5a0b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000660a9d3363178cd677adb15b6acb196507176074000000000000000000000000660a9d3363178cd677adb15b6acb1965071760740000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035e5ac4c7cb20350321459813f42df14f9ffc1fb00000000000000000000000035e5ac4c7cb20350321459813f42df14f9ffc1fb000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be7fee1d7fd765ed350319424dc2b1630a1343e7000000000000000000000000be7fee1d7fd765ed350319424dc2b1630a1343e7000000000000000000000000000000000000000000000000000119f17fe1600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000091816394be18d923a45b3ef57201aef19dfe116000000000000000000000000091816394be18d923a45b3ef57201aef19dfe1160000000000000000000000000000000000000000000000000031bced02db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a97459776e144c6554d03a95868fe258e70d69a8000000000000000000000000a97459776e144c6554d03a95868fe258e70d69a800000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5414,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca2cbf8ab2b4662bf992a9651c03bab54279d16d000000000000000000000000ca2cbf8ab2b4662bf992a9651c03bab54279d16d00000000000000000000000000000000000000000000000000517c11eeac177800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5415,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c8cdb4ef8d93572f8217a157db8ad0a0f7b4c486000000000000000000000000c8cdb4ef8d93572f8217a157db8ad0a0f7b4c48600000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000641ef149db1c2fa150b045b9881c3cc8306439db000000000000000000000000641ef149db1c2fa150b045b9881c3cc8306439db000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d9b7c19cf1a55abd4458634752751840576156c0000000000000000000000000d9b7c19cf1a55abd4458634752751840576156c000000000000000000000000000000000000000000000000009c51c4521e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5418,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3c6d6e24fe8629e2961467fd15144f701154c57000000000000000000000000d3c6d6e24fe8629e2961467fd15144f701154c57000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074845afc929b47d7886cdb266eba8054831b1e5e00000000000000000000000074845afc929b47d7886cdb266eba8054831b1e5e000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0d771006a4578f338f2043c99b74503207a67b1000000000000000000000000c0d771006a4578f338f2043c99b74503207a67b1000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007839c9bc2d4d61296ddf85667aaac421601bb9740000000000000000000000007839c9bc2d4d61296ddf85667aaac421601bb97400000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d38f4411539ce4c0050dc4015bda014eb911178f000000000000000000000000d38f4411539ce4c0050dc4015bda014eb911178f000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df3bdca9ebb45cbe0e9f4205d8107126ab4aacd7000000000000000000000000df3bdca9ebb45cbe0e9f4205d8107126ab4aacd700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5425,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000744eba6f0476d5d57b937b7ad1c44607931955b2000000000000000000000000744eba6f0476d5d57b937b7ad1c44607931955b2000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5426,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b970984bdd183724bd872b1b9b5db5471b125223000000000000000000000000b970984bdd183724bd872b1b9b5db5471b12522300000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5427,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a58171e75565922e0557a940f1f10eb0d897fde9000000000000000000000000a58171e75565922e0557a940f1f10eb0d897fde9000000000000000000000000000000000000000000000000003f13bea2fd620000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000078ad5270b0240d8529f600f35a271fc6e2b2bd8000000000000000000000000078ad5270b0240d8529f600f35a271fc6e2b2bd8000000000000000000000000000000000000000000000000000000000001a87600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7e07c80f79874e6867deb580d63746f6c072bc2000000000000000000000000d7e07c80f79874e6867deb580d63746f6c072bc2000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000071213a9c9504e406d3242436a4bf69c6bfe7446100000000000000000000000071213a9c9504e406d3242436a4bf69c6bfe74461000000000000000000000000000000000000000000000000000000000001980300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079d87b8a6bbaee0b7aa9b0c7da5586406474a0ab00000000000000000000000079d87b8a6bbaee0b7aa9b0c7da5586406474a0ab00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a90a1a41750946246a532224593a48313bb7f983000000000000000000000000a90a1a41750946246a532224593a48313bb7f983000000000000000000000000000000000000000000000000003119d47d228e8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea79e50d57dc3248da486861ec5891f445c45dad000000000000000000000000ea79e50d57dc3248da486861ec5891f445c45dad00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5435,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058192d5eb9c774cf3de1efab41371a1e392f941d00000000000000000000000058192d5eb9c774cf3de1efab41371a1e392f941d0000000000000000000000000000000000000000000000000051bd7bba4832a100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d239ca503f55bdfab65f1c2e22966b4195daacd0000000000000000000000001d239ca503f55bdfab65f1c2e22966b4195daacd00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000920fba25c6e266930ca3fbaf958c0d5145cb6a50000000000000000000000000920fba25c6e266930ca3fbaf958c0d5145cb6a50000000000000000000000000000000000000000000000000001130b0cdf7610000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1e6b7681d1b15a6ed71fe2f0b2b9b6b745f1722abd4e644b3437e8afc872f361,2021-12-27 08:13:55.000 UTC,0,true +5438,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bff987e43331cc5958b982563ff6c6378432f8f0000000000000000000000000bff987e43331cc5958b982563ff6c6378432f8f0000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bff987e43331cc5958b982563ff6c6378432f8f0000000000000000000000000bff987e43331cc5958b982563ff6c6378432f8f0000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000199c92538e4946451c2b2bca3c0f5722e008615f000000000000000000000000199c92538e4946451c2b2bca3c0f5722e008615f0000000000000000000000000000000000000000000000000074bdda7849287500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5441,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062f1cfe35428566baa6e0206b089abe0a6068d4b00000000000000000000000062f1cfe35428566baa6e0206b089abe0a6068d4b000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004768393fbbfce919fcc3fa3e324dd216a4a0b3fd0000000000000000000000004768393fbbfce919fcc3fa3e324dd216a4a0b3fd00000000000000000000000000000000000000000000000003a84c44f042578900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x79c4e88b1bddaed64b3ea0cf05c061f3b90dcb94e99309d941d44b3013a8ea98,2022-05-01 13:45:13.000 UTC,0,true +5443,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d65fa86720661bae0692b7e1fe5637e553494c60000000000000000000000004d65fa86720661bae0692b7e1fe5637e553494c6000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c72b76292f925a5b65289084c0c26305bd313ea8000000000000000000000000c72b76292f925a5b65289084c0c26305bd313ea800000000000000000000000000000000000000000000000000998a9b6a04e50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001cb15998a75f4628a2bdcbd86a632a33d906c1160000000000000000000000001cb15998a75f4628a2bdcbd86a632a33d906c116000000000000000000000000000000000000000000000000014912b611ee8d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c49cadc89a3b8cb6239a37a692ba370c32bdfd30000000000000000000000009c49cadc89a3b8cb6239a37a692ba370c32bdfd30000000000000000000000000000000000000000000000000011e20ada8780fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026b7929ce02124e8ff4aa380da99f92abc45f16700000000000000000000000026b7929ce02124e8ff4aa380da99f92abc45f16700000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067cda0e16f96ab6ec66295159615df54d607661200000000000000000000000067cda0e16f96ab6ec66295159615df54d6076612000000000000000000000000000000000000000000000000001d341429e237ee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x67299c88982db6dd1cc41ced8b97867f62df9d7400dc587d634d99f15cc2ad7a,2022-04-12 19:24:31.000 UTC,0,true +5451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7c1025fc4d558e4fd0f4e072b92a89616ddbb3e000000000000000000000000d7c1025fc4d558e4fd0f4e072b92a89616ddbb3e00000000000000000000000000000000000000000000000000011ada5486700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011a4373cdbe76eb7dda4aa36093bf95f4d41192900000000000000000000000011a4373cdbe76eb7dda4aa36093bf95f4d411929000000000000000000000000000000000000000000000000019c895744a7e16800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5453,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1bd9d66437549cdc30420fa3d5162d49f0fbc8d000000000000000000000000d1bd9d66437549cdc30420fa3d5162d49f0fbc8d0000000000000000000000000000000000000000000000000027aff71ec9300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5454,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5aaab5f12216e049ec43b85e15d1127e79becfd000000000000000000000000a5aaab5f12216e049ec43b85e15d1127e79becfd00000000000000000000000000000000000000000000000000012c221cc6a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da89fc38046b64328da0661108959c5616faa339000000000000000000000000da89fc38046b64328da0661108959c5616faa339000000000000000000000000000000000000000000000000001d137f0186e10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd41b85713a6c2bafedc970e18e6ec9dfc5d1c888f0ae8783a7d566fdc96c1102,2022-05-25 22:10:50.000 UTC,0,true +5457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e2fc870b3350ab8c9973b33ed56a3b2e45d1d180000000000000000000000009e2fc870b3350ab8c9973b33ed56a3b2e45d1d1800000000000000000000000000000000000000000000000002b4c7cb0463ec8d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000855de1c89382ffef9615c5430db23cdc38d36bc9000000000000000000000000855de1c89382ffef9615c5430db23cdc38d36bc900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000409540398e05fe99ff11702d80cc1a249a1f8c50000000000000000000000000409540398e05fe99ff11702d80cc1a249a1f8c5000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5461,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051c2522d728e2f011bb35a96e5aaa2a3e867228200000000000000000000000051c2522d728e2f011bb35a96e5aaa2a3e867228200000000000000000000000000000000000000000000000000011393af5df00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084a7b031d90b7d50f1c49bb0b6379b4306cd8a5100000000000000000000000084a7b031d90b7d50f1c49bb0b6379b4306cd8a5100000000000000000000000000000000000000000000000002e2c15ea55b0d4800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b4bb5d055613bef3bab73a8c75e70eca6e199590000000000000000000000001b4bb5d055613bef3bab73a8c75e70eca6e19959000000000000000000000000000000000000000000000000001168862766400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6d1b80b6cfab7fa7f16402ea9fa6580bb99f7d8000000000000000000000000c6d1b80b6cfab7fa7f16402ea9fa6580bb99f7d8000000000000000000000000000000000000000000000000078cad1e25d0000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b4bb5d055613bef3bab73a8c75e70eca6e199590000000000000000000000001b4bb5d055613bef3bab73a8c75e70eca6e19959000000000000000000000000000000000000000000000000001168862766400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5468,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dccb3b984c89f97afd551bede081f72e5c50c223000000000000000000000000dccb3b984c89f97afd551bede081f72e5c50c22300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3aa7c9b3bd025fe59bbc4e8a1b402c52fd25247000000000000000000000000a3aa7c9b3bd025fe59bbc4e8a1b402c52fd252470000000000000000000000000000000000000000000000000001353a6b39400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007e62aa7fde60ceebfcb72c49018ede750f7353200000000000000000000000007e62aa7fde60ceebfcb72c49018ede750f7353200000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e7ece53974e4914f7448d4dad027ed3cbf69b5e0000000000000000000000009e7ece53974e4914f7448d4dad027ed3cbf69b5e000000000000000000000000000000000000000000000000000fc9e774ed58c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000159764bf0f3aec21b3df78d4f2a8fcf20fdbe864000000000000000000000000159764bf0f3aec21b3df78d4f2a8fcf20fdbe864000000000000000000000000000000000000000000000000013acce631adebf900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6916424ff1361c780e82919abc8c9255d4ff5ff000000000000000000000000d6916424ff1361c780e82919abc8c9255d4ff5ff000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002572742a4017aa0e77771e1288617b7105eb86ee0000000000000000000000002572742a4017aa0e77771e1288617b7105eb86ee00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfa61059504bc913d1e79a01116e7d83cf6248ab000000000000000000000000bfa61059504bc913d1e79a01116e7d83cf6248ab000000000000000000000000000000000000000000000000004996f1be7c9bc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5477,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9241fc168e087fb39c1c864d5975a62e5a29b81000000000000000000000000e9241fc168e087fb39c1c864d5975a62e5a29b81000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5478,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7fdd807d73593b1a09b2ab31e8159c88e50daf3000000000000000000000000d7fdd807d73593b1a09b2ab31e8159c88e50daf300000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5479,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000005acfbbf0aa370f232e341bc0b1a40e996c960e07000000000000000000000000000000000000000000000003cabde168b1bef25c,,,1,true +5480,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000aeb9a479ddb28ac9aa3eddb24290b4d58cf7e9e0000000000000000000000000aeb9a479ddb28ac9aa3eddb24290b4d58cf7e9e000000000000000000000000000000000000000000000000001c32a44932f50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5ae62350336d7cd2e2901cd7698db1cb220b2b10519bb822c75ce3cc67faf96e,2022-05-25 22:14:44.000 UTC,0,true +5484,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006627d5eeaf0d706853cfb41eaa68604c06ab97450000000000000000000000006627d5eeaf0d706853cfb41eaa68604c06ab9745000000000000000000000000000000000000000000000000000119f17fe1600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ad1f20830e3bfd4f81eaa850989e3b1133d90d50000000000000000000000008ad1f20830e3bfd4f81eaa850989e3b1133d90d50000000000000000000000000000000000000000000000000062e55d0d17630000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5486,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047bbf8e3251aed23abda3d13ff75e2471e726aa100000000000000000000000047bbf8e3251aed23abda3d13ff75e2471e726aa10000000000000000000000000000000000000000000000000040a5a33d87200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5488,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020753667309b033d24d11d5ab564b3cab3b52e9f00000000000000000000000020753667309b033d24d11d5ab564b3cab3b52e9f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000967f3fee8ba153c8b05b638d44c6adeb7b0c620d000000000000000000000000967f3fee8ba153c8b05b638d44c6adeb7b0c620d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c784de0eacbe31eb87e0ec7a7f612ca011e33030000000000000000000000000c784de0eacbe31eb87e0ec7a7f612ca011e330300000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004e3499142cb3191ea3ad1ee1eb218539e2b246b00000000000000000000000004e3499142cb3191ea3ad1ee1eb218539e2b246b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e421482ca059264a9179423fceb76b9f2055a8c0000000000000000000000004e421482ca059264a9179423fceb76b9f2055a8c00000000000000000000000000000000000000000000000000100eea8262800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037d1ea02b0ece0fb3dacd345173a8d6b82f41bc000000000000000000000000037d1ea02b0ece0fb3dacd345173a8d6b82f41bc0000000000000000000000000000000000000000000000000000897df5811670300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5497,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021038df6c33b259e3a41c83424b27f9b7a20398700000000000000000000000021038df6c33b259e3a41c83424b27f9b7a2039870000000000000000000000000000000000000000000000000020e5916de78b1100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e248e69ddb1f8164476034da503fe9b19a5780a0000000000000000000000000e248e69ddb1f8164476034da503fe9b19a5780a0000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad2d23dcff6cdbb8a15e71d9acef313690933145000000000000000000000000ad2d23dcff6cdbb8a15e71d9acef313690933145000000000000000000000000000000000000000000000000004e28e2290f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078b1ccc9aa17f8e6bbb39cdb2c0b137ba92e240e00000000000000000000000078b1ccc9aa17f8e6bbb39cdb2c0b137ba92e240e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdac4cf4a0b261c383049dc692aede5360a08752000000000000000000000000bdac4cf4a0b261c383049dc692aede5360a0875200000000000000000000000000000000000000000000000000298656c76b068200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5503,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002477e1fe36b8359432a24ae3a933896a3b6588a00000000000000000000000002477e1fe36b8359432a24ae3a933896a3b6588a000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d493217b1f4bf46bf5b4627663bec9529d6e7f43000000000000000000000000d493217b1f4bf46bf5b4627663bec9529d6e7f4300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000490573336c7733a899f8c3b1b3067d3d42eb26ee000000000000000000000000490573336c7733a899f8c3b1b3067d3d42eb26ee0000000000000000000000000000000000000000000000000093481b808d1dfd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x424d9991ba1fd9057c6d522eb5f6e51badc39f21a73b9be130cfc59279493042,2022-08-09 05:15:19.000 UTC,0,true +5506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000056e1029173d5b6b39943eb5967dde3c6da74351000000000000000000000000056e1029173d5b6b39943eb5967dde3c6da7435100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5507,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000825dbbf50ee12b278139dd03fd88f49e57c7f84d000000000000000000000000825dbbf50ee12b278139dd03fd88f49e57c7f84d000000000000000000000000000000000000000000000000002f4d081e1a867500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb73fd2afd47cd70747bfb6d1245f711533e5901000000000000000000000000eb73fd2afd47cd70747bfb6d1245f711533e590100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5512,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011b5580c708a14bf5c39cba6e84bd07584753ac400000000000000000000000011b5580c708a14bf5c39cba6e84bd07584753ac40000000000000000000000000000000000000000000000000011b85607cd6c5200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5513,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000571965667a29abd76d5d43fa8788c0bc0cfe8088000000000000000000000000000000000000000000000000530548c1ddbdca98,,,1,true +5514,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0e7943a7500ec3d6ee0e6205461c1aaa6850a46000000000000000000000000e0e7943a7500ec3d6ee0e6205461c1aaa6850a460000000000000000000000000000000000000000000000000098ffab3587bdf800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009889e4cc3c754f892c32388c08c9384c7c17a0080000000000000000000000009889e4cc3c754f892c32388c08c9384c7c17a00800000000000000000000000000000000000000000000000000fc4101b654f43500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094f33be325f62b5d584312a65c9a1ae3254360e700000000000000000000000094f33be325f62b5d584312a65c9a1ae3254360e7000000000000000000000000000000000000000000000000010dcbff0e119d1600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000573a35ccea5dd981e7e2adb5d570c50296f91262000000000000000000000000573a35ccea5dd981e7e2adb5d570c50296f91262000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5520,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000949ffe8488aed787de11c95ccd5fc258141b4f28000000000000000000000000949ffe8488aed787de11c95ccd5fc258141b4f2800000000000000000000000000000000000000000000000000d01919a6bc0b9800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5523,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7137da63b53138a6dcdc9d9a010f42f951f1113000000000000000000000000a7137da63b53138a6dcdc9d9a010f42f951f111300000000000000000000000000000000000000000000000000a08787534379d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5524,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008867d4a10a1a5b9cab771deb5dcbb5fb14db28020000000000000000000000008867d4a10a1a5b9cab771deb5dcbb5fb14db2802000000000000000000000000000000000000000000000000009abe8f672939c700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5525,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017eda91a844f303a8184f826e8ffae9924ec978200000000000000000000000017eda91a844f303a8184f826e8ffae9924ec97820000000000000000000000000000000000000000000000000cfb29a034a20b1700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5526,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4054e9d66229d5605946dedfeca96eee6590377000000000000000000000000b4054e9d66229d5605946dedfeca96eee6590377000000000000000000000000000000000000000000000000022750d1b0ee1d8d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5527,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000edca050e06b595616c6365d2630837c63b331cb0000000000000000000000000edca050e06b595616c6365d2630837c63b331cb00000000000000000000000000000000000000000000000000a2e6e27f020dd000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fde45087d5ed774ea077ada40e82cc48a77df5d0000000000000000000000005fde45087d5ed774ea077ada40e82cc48a77df5d00000000000000000000000000000000000000000000000000e56c87d339580200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000178c05cf60526ea3e35bc4ac05d3141027ee15ce000000000000000000000000178c05cf60526ea3e35bc4ac05d3141027ee15ce000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000571965667a29abd76d5d43fa8788c0bc0cfe8088000000000000000000000000571965667a29abd76d5d43fa8788c0bc0cfe8088000000000000000000000000000000000000000000000000001fb59dfa24371d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5534,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000880db1abee87651b667615c24db3a30aa6aaa716000000000000000000000000880db1abee87651b667615c24db3a30aa6aaa716000000000000000000000000000000000000000000000001d44d2f325763eab500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000851807a2cf79c10228d2729e4983072a1b99bf5c000000000000000000000000851807a2cf79c10228d2729e4983072a1b99bf5c000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000063acae9fce2f889e35b703f7b831cc585aabbe0000000000000000000000000063acae9fce2f889e35b703f7b831cc585aabbe00000000000000000000000000000000000000000000000000149841644f10e4700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002ffcbc0ba249219e02e84e4273847f8e7d4ff6e60000000000000000000000002ffcbc0ba249219e02e84e4273847f8e7d4ff6e6000000000000000000000000000000000000000000000000000000000807ddc900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000820d36cb2728dff7625ff66454eb964b3afa7cce000000000000000000000000820d36cb2728dff7625ff66454eb964b3afa7cce0000000000000000000000000000000000000000000000000013cabda263469300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5539,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4701f5ab31d4104c091a9b5504827ec6aacdf39000000000000000000000000d4701f5ab31d4104c091a9b5504827ec6aacdf39000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071d2f08f217e0e81feb1143677850dd872694ee500000000000000000000000071d2f08f217e0e81feb1143677850dd872694ee500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5542,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071d2f08f217e0e81feb1143677850dd872694ee500000000000000000000000071d2f08f217e0e81feb1143677850dd872694ee500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aead1f2626c4ef3b0246ba9a343a310931a7ded5000000000000000000000000aead1f2626c4ef3b0246ba9a343a310931a7ded500000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5545,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2e6466956f9184ccf9f03e8b933239562209b6e000000000000000000000000d2e6466956f9184ccf9f03e8b933239562209b6e00000000000000000000000000000000000000000000000000e7a2505b0c15df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9ce001353e021767264f5ab6102e65bc9cd2023000000000000000000000000a9ce001353e021767264f5ab6102e65bc9cd20230000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5548,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e46eeacefe95efcc1ca54371bc88d7eae261dcbc000000000000000000000000e46eeacefe95efcc1ca54371bc88d7eae261dcbc00000000000000000000000000000000000000000000000000f9bb3890f8b81200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca922b1454c4cbe30a965047d51b0dace5b808d6000000000000000000000000ca922b1454c4cbe30a965047d51b0dace5b808d600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009fc9b76e8c2485c769c899c6c598688c56b0c52c0000000000000000000000009fc9b76e8c2485c769c899c6c598688c56b0c52c00000000000000000000000000000000000000000000000000a3309af71f642500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6e8e8739e98d36fa5dfb8d9c512175fc69db30f000000000000000000000000b6e8e8739e98d36fa5dfb8d9c512175fc69db30f0000000000000000000000000000000000000000000000000029062798b06ca300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029eaa8c7ea07a452b90da24b216f8af5a6f85cee00000000000000000000000029eaa8c7ea07a452b90da24b216f8af5a6f85cee00000000000000000000000000000000000000000000000000219d159b48770f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026a5a22570d8a4408cb21e333486ca04e60dec4d00000000000000000000000026a5a22570d8a4408cb21e333486ca04e60dec4d0000000000000000000000000000000000000000000000000015a6b183d97e9300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a1430ae58cc8ebcc4e47e08fa16bfc78972b39a0000000000000000000000002a1430ae58cc8ebcc4e47e08fa16bfc78972b39a000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e08d5492488d710350408c22d328162af4be8620000000000000000000000002e08d5492488d710350408c22d328162af4be8620000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d54243a81f132ca4db3174194145373490b469c0000000000000000000000004d54243a81f132ca4db3174194145373490b469c00000000000000000000000000000000000000000000000000075ea80fdf005200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078cbd3ac362577935a2421ea4b2ee548b7eb76ba00000000000000000000000078cbd3ac362577935a2421ea4b2ee548b7eb76ba0000000000000000000000000000000000000000000000000004169f662966c400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000620f6600496e0466f3341dff311d43c82fa953a5000000000000000000000000620f6600496e0466f3341dff311d43c82fa953a5000000000000000000000000000000000000000000000000001dd1644c52360000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcfc60c0c0a12408499bdf8ab20955d491e3b178000000000000000000000000bcfc60c0c0a12408499bdf8ab20955d491e3b17800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5562,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d32c1d33bf023aae1d9666e714c5ac3418cdede3000000000000000000000000d32c1d33bf023aae1d9666e714c5ac3418cdede300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2a9aef4bbb101be350b6dcf20de0551b5b628ae000000000000000000000000b2a9aef4bbb101be350b6dcf20de0551b5b628ae000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000edb00e1646b8bf9d9cc3c8b1d364e371bf57ab2b000000000000000000000000edb00e1646b8bf9d9cc3c8b1d364e371bf57ab2b00000000000000000000000000000000000000000000000000ee9a2049a22dc800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5565,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000941169fff3c353be965e3f34823eea63b772219c000000000000000000000000941169fff3c353be965e3f34823eea63b772219c000000000000000000000000000000000000000000000000008b878d12c0b0aa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008da53d90095a3af28a8f7c706c2b08b59ca9a4c50000000000000000000000008da53d90095a3af28a8f7c706c2b08b59ca9a4c50000000000000000000000000000000000000000000000000111a2b2639f5fa200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5567,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fc920c69979da8194875d06f7c6d6ee99d5001f0000000000000000000000004fc920c69979da8194875d06f7c6d6ee99d5001f00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5568,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a48c2dd26e09fd78083df35e5f92ffd7156be402000000000000000000000000a48c2dd26e09fd78083df35e5f92ffd7156be40200000000000000000000000000000000000000000000000000d52b1ac5dc2ced00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5569,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044a999a01cf6fc3de03fc1739f8826d5e46a84fa00000000000000000000000044a999a01cf6fc3de03fc1739f8826d5e46a84fa000000000000000000000000000000000000000000000000010053dea3eceb9700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5571,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000347f715dd0f6f09bf75fc98b4b4f356208ad2fb2000000000000000000000000347f715dd0f6f09bf75fc98b4b4f356208ad2fb2000000000000000000000000000000000000000000000000010041076283b80800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090741e1fdca0e490ccfdec50917f13a9be9cdc7a00000000000000000000000090741e1fdca0e490ccfdec50917f13a9be9cdc7a000000000000000000000000000000000000000000000000001fefd337b19f1400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5573,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0f25775ced2dd9613d588f67765708fb317ac1d000000000000000000000000c0f25775ced2dd9613d588f67765708fb317ac1d00000000000000000000000000000000000000000000000000d54771877a56fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5574,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000500d0f63df0b7daec3155ff7d68e59204e7bcc29000000000000000000000000500d0f63df0b7daec3155ff7d68e59204e7bcc2900000000000000000000000000000000000000000000000000f8438bb2a5ceb900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5575,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f10937d5a4531754449ac0ddbdf23331e1487890000000000000000000000007f10937d5a4531754449ac0ddbdf23331e14878900000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000964a69b94386b95077798ae475d0660975413faa000000000000000000000000964a69b94386b95077798ae475d0660975413faa00000000000000000000000000000000000000000000000000edd01b47f12c2c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6f1459439258798391df7a9d60dcac96b3afa9e000000000000000000000000c6f1459439258798391df7a9d60dcac96b3afa9e00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5579,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014441fac45abfe6fa3c3889a5dde3dbd8977c23600000000000000000000000014441fac45abfe6fa3c3889a5dde3dbd8977c23600000000000000000000000000000000000000000000000000dd6c3d4bf7f81100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5580,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf3a4a0dda2e5d94ef6d30d218cff62252c32cd1000000000000000000000000cf3a4a0dda2e5d94ef6d30d218cff62252c32cd100000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5581,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fe7c5f80aa20b042cbe590f2984c6be98270a850000000000000000000000001fe7c5f80aa20b042cbe590f2984c6be98270a8500000000000000000000000000000000000000000000000000f7f64f7269977600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5582,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4e7abab7389c9c7d5bb49c6e437485676ff9cb3000000000000000000000000b4e7abab7389c9c7d5bb49c6e437485676ff9cb3000000000000000000000000000000000000000000000000002d3e3e5745eb8900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5583,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003597ed66ea2a8d6b93d23b15f2fd30d308bf83180000000000000000000000003597ed66ea2a8d6b93d23b15f2fd30d308bf83180000000000000000000000000000000000000000000000000028079e4d14ab6300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5584,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002847184449afc8f238076ea4d3969121d8adeb460000000000000000000000002847184449afc8f238076ea4d3969121d8adeb4600000000000000000000000000000000000000000000000001b44e9ee2eeb41000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5585,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d328feb7ad9fc26a050cbb0495da38bd3f751e40000000000000000000000000d328feb7ad9fc26a050cbb0495da38bd3f751e4000000000000000000000000000000000000000000000000001e03c17f6ce8c2200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x01bf05ef8043a9452b164a88bee54dec16e896b25ccfb1e8ecfe8e5a23596dd6,2022-05-07 02:34:46.000 UTC,0,true +5586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000629c4565be654c4a5f742da05ced064e16224981000000000000000000000000629c4565be654c4a5f742da05ced064e1622498100000000000000000000000000000000000000000000000000d367e7ee4dacfb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5587,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e0832f9519c3a09fb2e6acb63df7d2b7155c4060000000000000000000000006e0832f9519c3a09fb2e6acb63df7d2b7155c40600000000000000000000000000000000000000000000000001a0a52d5479d54500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5589,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf59e62f6add0b2f0914d47ef0375103cdebcbf9000000000000000000000000bf59e62f6add0b2f0914d47ef0375103cdebcbf900000000000000000000000000000000000000000000000001ac808a831d894500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5590,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000257f99fd962db35704a3ed32523eede0f6b04fa6000000000000000000000000257f99fd962db35704a3ed32523eede0f6b04fa600000000000000000000000000000000000000000000000004db73254763000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5591,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098ec2fec32a8a9e321c6655693868b1d301848ae00000000000000000000000098ec2fec32a8a9e321c6655693868b1d301848ae000000000000000000000000000000000000000000000000019e27971a47a90f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5593,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004645e30cac1df7bfc5752eadfdf37ef331178f570000000000000000000000004645e30cac1df7bfc5752eadfdf37ef331178f570000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5595,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d76ef4e3e749aece088c0d674002fd4234fc6bbb000000000000000000000000d76ef4e3e749aece088c0d674002fd4234fc6bbb00000000000000000000000000000000000000000000000001ba8829041700ba00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5597,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009bbec2d116d4a4986f752907c77f85abab71b9e00000000000000000000000009bbec2d116d4a4986f752907c77f85abab71b9e00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000793745e010dbed0d859d3f83e7dafafb210860b1000000000000000000000000793745e010dbed0d859d3f83e7dafafb210860b100000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5600,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0c76ea5c4bb71f32cd08462bb48d43c0ecf85e2000000000000000000000000c0c76ea5c4bb71f32cd08462bb48d43c0ecf85e2000000000000000000000000000000000000000000000000002779c433836c1300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5602,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000566b56bdc1f5c1bbe388d44479524b07f30f7d60000000000000000000000000566b56bdc1f5c1bbe388d44479524b07f30f7d6000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017eda91a844f303a8184f826e8ffae9924ec978200000000000000000000000017eda91a844f303a8184f826e8ffae9924ec978200000000000000000000000000000000000000000000000001a383abbc60c88800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5610,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1d59d7edce98aa7444b7383f8c27d4ab3e19eb5000000000000000000000000e1d59d7edce98aa7444b7383f8c27d4ab3e19eb5000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5611,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076da8cf045ed1a404f8fc9f8513dac885d1afad000000000000000000000000076da8cf045ed1a404f8fc9f8513dac885d1afad000000000000000000000000000000000000000000000000000a0c42a2513ac7300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5612,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fc920c69979da8194875d06f7c6d6ee99d5001f0000000000000000000000004fc920c69979da8194875d06f7c6d6ee99d5001f00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5613,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004331a6f53f75b215b1a6d6292acaa564bd89464f0000000000000000000000004331a6f53f75b215b1a6d6292acaa564bd89464f00000000000000000000000000000000000000000000000000a3e7cd0d4a035600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5614,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6e0ac20117184fce07470205c27fdd1f01c266f000000000000000000000000a6e0ac20117184fce07470205c27fdd1f01c266f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5615,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000286fe436539b18407b3fd8285c20e5eeb56de5f4000000000000000000000000286fe436539b18407b3fd8285c20e5eeb56de5f4000000000000000000000000000000000000000000000001a055690d9db8060300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033b2c9c2a6050316c2aa96891f47fd43e08c49d200000000000000000000000033b2c9c2a6050316c2aa96891f47fd43e08c49d2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5617,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078777450f3a2a76f21abd549c125849cf5f5006700000000000000000000000078777450f3a2a76f21abd549c125849cf5f5006700000000000000000000000000000000000000000000000000284c96a0dc137500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5618,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000286fe436539b18407b3fd8285c20e5eeb56de5f4000000000000000000000000286fe436539b18407b3fd8285c20e5eeb56de5f4000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5619,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e773c91f242bd1cb26889ff0210f7cf3815ddc99000000000000000000000000e773c91f242bd1cb26889ff0210f7cf3815ddc9900000000000000000000000000000000000000000000000007af31844ced7fdd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5620,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a16d006da707a3286e6ced7931b8259be1604970000000000000000000000007a16d006da707a3286e6ced7931b8259be16049700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004910eff6b570542153f33b6a3404efe27f2f86670000000000000000000000004910eff6b570542153f33b6a3404efe27f2f866700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cca632a308cad16d4396f67a7b312e55edc24061000000000000000000000000cca632a308cad16d4396f67a7b312e55edc240610000000000000000000000000000000000000000000000000098c445ad57800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5624,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043ec54a69923cf55e5d8cfaffd79b5a52b8202bf00000000000000000000000043ec54a69923cf55e5d8cfaffd79b5a52b8202bf0000000000000000000000000000000000000000000000000000008bb2c9700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007472aab4e5e4d993f1ce8f51dc1edfa3724e8ca10000000000000000000000007472aab4e5e4d993f1ce8f51dc1edfa3724e8ca100000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a57e22bf556074dabe4e456792dd71a846ad8d38000000000000000000000000a57e22bf556074dabe4e456792dd71a846ad8d380000000000000000000000000000000000000000000000000017c726144388c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075b995c813da60dd3055d98b73dd1b32f588367f00000000000000000000000075b995c813da60dd3055d98b73dd1b32f588367f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a1130cf808f53492997d68b838306b3d52c101f0000000000000000000000007a1130cf808f53492997d68b838306b3d52c101f0000000000000000000000000000000000000000000000000028f1c0908d7cb800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f598aab7895eba4b86035353f9152a2ee9568550000000000000000000000006f598aab7895eba4b86035353f9152a2ee956855000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1245aa226c025094ff0ce7e7e5a35eec214ac8e000000000000000000000000e1245aa226c025094ff0ce7e7e5a35eec214ac8e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f276c6ae5fe256d5cfcbf02f352fd63b2d41b07b000000000000000000000000f276c6ae5fe256d5cfcbf02f352fd63b2d41b07b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcb48913ffd25a4a3a940600e9b28769785b4467000000000000000000000000fcb48913ffd25a4a3a940600e9b28769785b446700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5636,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a259270e869dd40ddcba90cd82a9f49e41269430000000000000000000000009a259270e869dd40ddcba90cd82a9f49e412694300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5637,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc56dd5f5a70f7dbdb10e7390af65622f78fbfdc000000000000000000000000cc56dd5f5a70f7dbdb10e7390af65622f78fbfdc00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b11e0cb32ddc622f89ad62068758e42bbf973ff4000000000000000000000000b11e0cb32ddc622f89ad62068758e42bbf973ff400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5639,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b5ef088312939b249271bb7f8a61e77749ab5390000000000000000000000007b5ef088312939b249271bb7f8a61e77749ab53900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d0d6bc9ba4d93a8ed8fe0283b48c71b818b48230000000000000000000000006d0d6bc9ba4d93a8ed8fe0283b48c71b818b482300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076a833c76e6238215f9aaca3f6ad2e5e9847e92400000000000000000000000076a833c76e6238215f9aaca3f6ad2e5e9847e92400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006985ae552d11a091b75f446ba38508d7668d7b720000000000000000000000006985ae552d11a091b75f446ba38508d7668d7b720000000000000000000000000000000000000000000000000077c604eccf863000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5645,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000222e79ab40d859e50f0161d48aa4f0c1e8e5ded8000000000000000000000000222e79ab40d859e50f0161d48aa4f0c1e8e5ded800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5646,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091162672cc2feb0e8627f384ff93294c79fbf36100000000000000000000000091162672cc2feb0e8627f384ff93294c79fbf3610000000000000000000000000000000000000000000000000158a60943cc837500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbe8a216bafa7ad4ac4b90f3c2abd57648f8bb25394e874f9ba3e7e37152be61e,2022-04-27 10:57:39.000 UTC,0,true +5649,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082abe0456afbd32abf1f0c5add8c4199dc4a3bc300000000000000000000000082abe0456afbd32abf1f0c5add8c4199dc4a3bc30000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5654,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af2686a65a101ba79971561c128bdfe7fb1157f3000000000000000000000000af2686a65a101ba79971561c128bdfe7fb1157f30000000000000000000000000000000000000000000000000006c1afcaa8fdc400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3d9bc84e30ca21277d0bc7a943f3ad1ea3208d7000000000000000000000000d3d9bc84e30ca21277d0bc7a943f3ad1ea3208d7000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba35b90e51c42e1069bad364b65512c1e7d87f39000000000000000000000000ba35b90e51c42e1069bad364b65512c1e7d87f39000000000000000000000000000000000000000000000000015181ff25a9800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5657,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002aa85a041e7af248ae2e9aee7f5b32daabe133370000000000000000000000002aa85a041e7af248ae2e9aee7f5b32daabe13337000000000000000000000000000000000000000000000000009a8b04ffbac00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000404b7233782034330ed760d56979338789546567000000000000000000000000404b7233782034330ed760d5697933878954656700000000000000000000000000000000000000000000000000174c986cac1b1200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5660,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a1459f5991a9e07a64ec4b49e2292131d3ebd520000000000000000000000004a1459f5991a9e07a64ec4b49e2292131d3ebd5200000000000000000000000000000000000000000000000000a1f64934f6070000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5662,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e6cf371e21e7a1ad36b440b80f8be79526b0bb70000000000000000000000001e6cf371e21e7a1ad36b440b80f8be79526b0bb7000000000000000000000000000000000000000000000000000f55306c71bb1a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5663,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6e0ac20117184fce07470205c27fdd1f01c266f000000000000000000000000a6e0ac20117184fce07470205c27fdd1f01c266f0000000000000000000000000000000000000000000000000145b4bbdedef18000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eaf60507489320623b9f4485b33e112421d4c900000000000000000000000000eaf60507489320623b9f4485b33e112421d4c90000000000000000000000000000000000000000000000000000a0ccb0c32152a000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033cb44260a7564d3cac8da5a6d0fffbcacbfcfea00000000000000000000000033cb44260a7564d3cac8da5a6d0fffbcacbfcfea0000000000000000000000000000000000000000000000000084dcbba72b4cc100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5667,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047075648c0c715e68b49d938b87552fab718a9c800000000000000000000000047075648c0c715e68b49d938b87552fab718a9c8000000000000000000000000000000000000000000000000005543df729c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x90d39395e12172a11c1ceadd655316bb3d20562f4c2f147c924484b4c61a5790,2022-03-12 20:30:31.000 UTC,0,true +5668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b51ae3a0de15387b8f1d602a40704db9e137c5d0000000000000000000000006b51ae3a0de15387b8f1d602a40704db9e137c5d000000000000000000000000000000000000000000000000014d63bc86d98f8f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5669,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017202b62feb408b478d3c247e2001311a48f5f3200000000000000000000000017202b62feb408b478d3c247e2001311a48f5f32000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5670,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c223f476b4f44cf01b296fbeab782daf6b101e81000000000000000000000000c223f476b4f44cf01b296fbeab782daf6b101e8100000000000000000000000000000000000000000000000053444878b2ca5ef400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5674,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095d27c7dcbd1fb45e70585a3a71f2f229229715700000000000000000000000095d27c7dcbd1fb45e70585a3a71f2f229229715700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5677,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000444444cc7fe267251797d8592c3f4d5ee6888d62000000000000000000000000444444cc7fe267251797d8592c3f4d5ee6888d62000000000000000000000000000000000000000000000000014bf403eb5c488000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5678,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084a198db31ea79734b58bc70ac0484b8b23ae9f500000000000000000000000084a198db31ea79734b58bc70ac0484b8b23ae9f500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be9f07d564b0c6f47d56980d055925d798441792000000000000000000000000be9f07d564b0c6f47d56980d055925d79844179200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5680,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023236075c29ab1ddc1731a1271dbf448ffd8688000000000000000000000000023236075c29ab1ddc1731a1271dbf448ffd8688000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071f5280932a10eee4deadbe08898087452f64d0500000000000000000000000071f5280932a10eee4deadbe08898087452f64d0500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5682,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b30919008eabe486fbb04bde517875788dbb3abe000000000000000000000000b30919008eabe486fbb04bde517875788dbb3abe00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5683,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b78d6814d1894edfd0d9e369d024fb47842540d0000000000000000000000002b78d6814d1894edfd0d9e369d024fb47842540d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000738fdd122cf588106832e6b1f73a44aab20066b4000000000000000000000000738fdd122cf588106832e6b1f73a44aab20066b400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac3446f9e80e20f370d9a50d9c85daf216f5afdc000000000000000000000000ac3446f9e80e20f370d9a50d9c85daf216f5afdc00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5686,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1d59d7edce98aa7444b7383f8c27d4ab3e19eb5000000000000000000000000e1d59d7edce98aa7444b7383f8c27d4ab3e19eb500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5687,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fb61a8e5cf37cc1de7c1fe155ee5295c3d023600000000000000000000000000fb61a8e5cf37cc1de7c1fe155ee5295c3d0236000000000000000000000000000000000000000000000000000ab95ec45b78e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1651b690addfc93caa656a2870fcc40487c7bc5000000000000000000000000a1651b690addfc93caa656a2870fcc40487c7bc500000000000000000000000000000000000000000000000000a017d0784e3e1f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5689,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cb508b3d71f5fc3ad9815ac72602e1dadf16c3b0000000000000000000000007cb508b3d71f5fc3ad9815ac72602e1dadf16c3b000000000000000000000000000000000000000000000000005b9cb4431999e600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a4b0316afc04371092a2019158edc213dbb4ffc0000000000000000000000003a4b0316afc04371092a2019158edc213dbb4ffc000000000000000000000000000000000000000000000000001d6b085f932c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5696,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098ff454c5d8a367c5532c057c665410610d409ec00000000000000000000000098ff454c5d8a367c5532c057c665410610d409ec000000000000000000000000000000000000000000000000002614941f8c2b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5699,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001574a47822dc67d7ffd5e9de7b9fa85dbe98ac5f0000000000000000000000000000000000000000000000016f4f2e86035451a9,,,1,true +5702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013b1a8a6770eb031f23af46292df580aa3c2ab0000000000000000000000000013b1a8a6770eb031f23af46292df580aa3c2ab000000000000000000000000000000000000000000000000000055a797c3f443af00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5703,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001cbb4c62da977613636a7a779a3f364dfd6906a40000000000000000000000001cbb4c62da977613636a7a779a3f364dfd6906a400000000000000000000000000000000000000000000000000f6616c3475d18500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ab27b843f3f02d98f072e2ce937eeec0c0b9ce90000000000000000000000004ab27b843f3f02d98f072e2ce937eeec0c0b9ce900000000000000000000000000000000000000000000000000a2e5b5dfb2bb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5706,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c05079e4a384b51df73f2b632d81a92282d4125e000000000000000000000000c05079e4a384b51df73f2b632d81a92282d4125e00000000000000000000000000000000000000000000000ad4cdcc52a321fe0800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c05079e4a384b51df73f2b632d81a92282d4125e000000000000000000000000c05079e4a384b51df73f2b632d81a92282d4125e00000000000000000000000000000000000000000000000001a20fc1d1aa06f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5708,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003411cb2b60694d43f8f242fd8b48e28f2b4cafe90000000000000000000000003411cb2b60694d43f8f242fd8b48e28f2b4cafe90000000000000000000000000000000000000000000000000002279192f8bc2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5709,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011180325b253dad82be5855af67496ea2a7d207200000000000000000000000011180325b253dad82be5855af67496ea2a7d20720000000000000000000000000000000000000000000000000018f255faa0310000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5710,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060e15f715ce1739d00280970aee91ded8644484500000000000000000000000060e15f715ce1739d00280970aee91ded86444845000000000000000000000000000000000000000000000000004263744d3897d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5711,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014189b7286fa5674bc1eda3b9846ba50b527570e00000000000000000000000014189b7286fa5674bc1eda3b9846ba50b527570e0000000000000000000000000000000000000000000000000034ffaf0b84688700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000118b2b107009ef2e874aca0eca4628dac947d64b000000000000000000000000118b2b107009ef2e874aca0eca4628dac947d64b00000000000000000000000000000000000000000000000000ac4c8c1560550000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8e5d2c181ee73458142792c2659cfe3ed10cb02000000000000000000000000e8e5d2c181ee73458142792c2659cfe3ed10cb02000000000000000000000000000000000000000000000000000b50fb934b0d8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008242b4304d70948b53d3a09ae1fc5542c0d4292a0000000000000000000000008242b4304d70948b53d3a09ae1fc5542c0d4292a000000000000000000000000000000000000000000000000015ac1b3b7fced0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5718,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ef90a7c2581b17b8db0980cfed761745ec3f74b0000000000000000000000009ef90a7c2581b17b8db0980cfed761745ec3f74b000000000000000000000000000000000000000000000000002e5ba2cce65ed900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5719,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052509e3d2a165416e14cc5603e99957b9ce83b0f00000000000000000000000052509e3d2a165416e14cc5603e99957b9ce83b0f000000000000000000000000000000000000000000000000003a0b0662d4792300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5720,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e23735c25becc2838e2f053886cd9c983a75449a000000000000000000000000e23735c25becc2838e2f053886cd9c983a75449a000000000000000000000000000000000000000000000000006e2255f409800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5722,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5f55468585ef91cf1a87aa3af4c830fa7ae78de000000000000000000000000e5f55468585ef91cf1a87aa3af4c830fa7ae78de0000000000000000000000000000000000000000000000000063a7f10cdcb4e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5723,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009981e8c28824392eb77396e3fd183c83208b7cc80000000000000000000000009981e8c28824392eb77396e3fd183c83208b7cc8000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5724,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ce822ff7ae1cce0223ff7d44fcde422889c5a230000000000000000000000004ce822ff7ae1cce0223ff7d44fcde422889c5a23000000000000000000000000000000000000000000000000002b72ce23a37d1300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5725,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3ce8c5ef43afebab7e35bcca6b7f363ba14a10b000000000000000000000000d3ce8c5ef43afebab7e35bcca6b7f363ba14a10b000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5726,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f321716db6d2e5318a1cdbc15af80df25f2f8244000000000000000000000000f321716db6d2e5318a1cdbc15af80df25f2f824400000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1031825e9667178167df00c485911847e4f91fe000000000000000000000000e1031825e9667178167df00c485911847e4f91fe000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5730,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000207b113566f3182208a28fb8c8e4f23ab8b0c42a000000000000000000000000207b113566f3182208a28fb8c8e4f23ab8b0c42a00000000000000000000000000000000000000000000000000000000026fd3d700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5731,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa9ccef24415475e88d644d3c33fb4ed1b29ffaf000000000000000000000000aa9ccef24415475e88d644d3c33fb4ed1b29ffaf00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5732,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007af91cc664841f22e00f32efbd08c75da629d0110000000000000000000000007af91cc664841f22e00f32efbd08c75da629d01100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000883c6898713f968dde996467af2a20ff034a2e7b000000000000000000000000883c6898713f968dde996467af2a20ff034a2e7b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5735,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007277e46511d46981b2d63bb2e8304710e85075e70000000000000000000000007277e46511d46981b2d63bb2e8304710e85075e70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5736,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000931e8a21e4714ff99b4514dc891f357bff8e54f8000000000000000000000000931e8a21e4714ff99b4514dc891f357bff8e54f80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5737,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6e56fd011fde843410914e8c58ba005b447a64e000000000000000000000000b6e56fd011fde843410914e8c58ba005b447a64e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c434436ad93c531f47b0a6415dafad6ebfa6d823000000000000000000000000c434436ad93c531f47b0a6415dafad6ebfa6d823000000000000000000000000000000000000000000000000007c58508723800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de50587f77e7cb30c3cceb2bcf19affb12668865000000000000000000000000de50587f77e7cb30c3cceb2bcf19affb126688650000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5741,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000943be0102bdd5eab787e510ff7d578cf1a499a8a000000000000000000000000943be0102bdd5eab787e510ff7d578cf1a499a8a0000000000000000000000000000000000000000000000000000000004f78c7200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5743,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080f534afdb982ef359f3d9de8d82a8d3f3b965c500000000000000000000000080f534afdb982ef359f3d9de8d82a8d3f3b965c50000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5744,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d83abb0e7a9643c9b9040d6ca9238a4b78ab0210000000000000000000000008d83abb0e7a9643c9b9040d6ca9238a4b78ab0210000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000575db8bf64d74df770386196f651f5e920634b72000000000000000000000000575db8bf64d74df770386196f651f5e920634b72000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5746,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098aa52dc061b008f3c11866c1294fb878b34e10d00000000000000000000000098aa52dc061b008f3c11866c1294fb878b34e10d000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060c1b9739000dd2ae75f3bc27d93f4181d77e3d200000000000000000000000060c1b9739000dd2ae75f3bc27d93f4181d77e3d2000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5748,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4d09b441573b8169341be1d0d2e6cb42e2bf721000000000000000000000000b4d09b441573b8169341be1d0d2e6cb42e2bf721000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5749,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6b59759ec807879baa25ca6cc19aabef6191692000000000000000000000000e6b59759ec807879baa25ca6cc19aabef6191692000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5750,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000813407596e7c63cd3958ff081ca078cb31ddbf10000000000000000000000000813407596e7c63cd3958ff081ca078cb31ddbf100000000000000000000000000000000000000000000000000a7fff78c0ecf9200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5751,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1ca2cd95c881800d86a3b3ba6b120b49cd7da03000000000000000000000000a1ca2cd95c881800d86a3b3ba6b120b49cd7da03000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050849ee0e1b4b87ddd43fb3de905ce2783c2ad5000000000000000000000000050849ee0e1b4b87ddd43fb3de905ce2783c2ad50000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5753,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dff97b7634cb8df4d2b29185667b982118f1e620000000000000000000000000dff97b7634cb8df4d2b29185667b982118f1e620000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5754,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047f4ee0ecc560668854ea1b0b0c64742fe778b7500000000000000000000000047f4ee0ecc560668854ea1b0b0c64742fe778b75000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5755,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eca01f7d3efaedadd45786ad4bf6b10f471f0a29000000000000000000000000eca01f7d3efaedadd45786ad4bf6b10f471f0a29000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5757,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f06a88da83f93a4028b3917523d66e409c070b60000000000000000000000007f06a88da83f93a4028b3917523d66e409c070b6000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000f14994ffd06b8c352e12b41113bc0f77fc404200000000000000000000000000f14994ffd06b8c352e12b41113bc0f77fc4042000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5759,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4f9d59a0bc92cfe2103a4862573b58d86be3424000000000000000000000000b4f9d59a0bc92cfe2103a4862573b58d86be342400000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5761,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa9ccef24415475e88d644d3c33fb4ed1b29ffaf000000000000000000000000aa9ccef24415475e88d644d3c33fb4ed1b29ffaf000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a6fd5764581c142213140e17fabef2db70692c40000000000000000000000001a6fd5764581c142213140e17fabef2db70692c4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5764,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f13365f0d9c0470b86817e05a9c0cca4d17c8ae0000000000000000000000009f13365f0d9c0470b86817e05a9c0cca4d17c8ae0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5765,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085a0ae757f88dae8b14f59e86b5f5616ba9de3c200000000000000000000000085a0ae757f88dae8b14f59e86b5f5616ba9de3c2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032d641b2d54a46b9e4448bf35f667e17da2fd14d00000000000000000000000032d641b2d54a46b9e4448bf35f667e17da2fd14d00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5767,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4a08ddb47fb1ab70b5bcc561caa39c3f63827a2000000000000000000000000b4a08ddb47fb1ab70b5bcc561caa39c3f63827a200000000000000000000000000000000000000000000000000499c8322914c6300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d071194f93de2461b545c85d621c730704a02343000000000000000000000000d071194f93de2461b545c85d621c730704a02343000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5770,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d703a8918da1bb6ee7073a481e89ae04581a5342000000000000000000000000d703a8918da1bb6ee7073a481e89ae04581a53420000000000000000000000000000000000000000000000000002433b35bafe4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5771,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c56569af55410b2922e116a233494972b8dc3474000000000000000000000000c56569af55410b2922e116a233494972b8dc34740000000000000000000000000000000000000000000000000031bced02db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000822759d8f48a42b9ff29c040619b5539c31b727b000000000000000000000000822759d8f48a42b9ff29c040619b5539c31b727b000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067e3d581dbfe600510b0aed1a74b2840ef4ea3db00000000000000000000000067e3d581dbfe600510b0aed1a74b2840ef4ea3db000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d10aa04285b5f85d22901b9d01d89d75077a9657000000000000000000000000d10aa04285b5f85d22901b9d01d89d75077a96570000000000000000000000000000000000000000000000000006b88d918b780000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000520d54f75777b58fee71a3074256aabbdb47074c000000000000000000000000520d54f75777b58fee71a3074256aabbdb47074c00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087105752954887b1140b7cea133eacc8ae8607b500000000000000000000000087105752954887b1140b7cea133eacc8ae8607b5000000000000000000000000000000000000000000000000005fec5b60ef800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5778,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035f78a470000c9974aab3e37a6882e374f42566300000000000000000000000035f78a470000c9974aab3e37a6882e374f425663000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000068f180fcce6836688e9084f035309e29bf0a209500000000000000000000000008968309443465c03244c9206052aa20cdbb679700000000000000000000000008968309443465c03244c9206052aa20cdbb6797000000000000000000000000000000000000000000000000000000000ccf22bb00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x45e79fb50a21687be2a39626198e4b64260ee10f3a43ca36c409f2913507eda4,2022-01-11 16:07:02.000 UTC,0,true +5780,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f9f1a9c106cadb1f776cc582d3c78da4043dd510000000000000000000000009f9f1a9c106cadb1f776cc582d3c78da4043dd51000000000000000000000000000000000000000000000000015d7d2d55698d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef101ffdcef941b6fad240226f754e99f84e177c000000000000000000000000ef101ffdcef941b6fad240226f754e99f84e177c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5784,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018a842c315c6a8c54d041c65b0aa2732f50c00da00000000000000000000000018a842c315c6a8c54d041c65b0aa2732f50c00da000000000000000000000000000000000000000000000000003c6568f12e800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e3b749409d240c7f50b483079e0df003c8c181f0000000000000000000000003e3b749409d240c7f50b483079e0df003c8c181f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb55475384aa31c5100986cda2476df2103fc2ee000000000000000000000000cb55475384aa31c5100986cda2476df2103fc2ee000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086d7667cb7b0d33e81300cb6a220b553360b3d3400000000000000000000000086d7667cb7b0d33e81300cb6a220b553360b3d34000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000445bf7bab73ab0bdb84c882f8f7b3ee6bd28a2ba000000000000000000000000445bf7bab73ab0bdb84c882f8f7b3ee6bd28a2ba000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5793,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d565a49e5caa0eb79d5175405283fc0e3326c097000000000000000000000000d565a49e5caa0eb79d5175405283fc0e3326c097000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067a6076958f88b4944c7281b6fc2e67c76bcb9e200000000000000000000000067a6076958f88b4944c7281b6fc2e67c76bcb9e2000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5799,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000187f7311a58baa258855fd190071411110d685f0000000000000000000000000187f7311a58baa258855fd190071411110d685f000000000000000000000000000000000000000000000000001d882cb9b20800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4aa6164a39bbbd80526f575a4715ac329342863884ac948c4c8617a98e25aade,2022-03-04 10:57:07.000 UTC,0,true +5800,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068abe26c2e9fae42c4daeed9d1ac68b3488fc83900000000000000000000000068abe26c2e9fae42c4daeed9d1ac68b3488fc839000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5802,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e124f9182d36cf13c2cc6b4657394080b5807d20000000000000000000000002e124f9182d36cf13c2cc6b4657394080b5807d200000000000000000000000000000000000000000000000000a4c59d670a7f4100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5803,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000dc1d71121c0880e02ea1bad4f8fde0ae2c018f50000000000000000000000000dc1d71121c0880e02ea1bad4f8fde0ae2c018f5000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5804,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7101e2e0680d30623e59de267ec4b2f4ecfd3ce000000000000000000000000d7101e2e0680d30623e59de267ec4b2f4ecfd3ce000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5806,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5e7c5032d203b69da4d8feb7f3c3179fd9cb83b000000000000000000000000c5e7c5032d203b69da4d8feb7f3c3179fd9cb83b00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5808,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000001b6fc127150282b390e255f0772e6f8d806e264d0000000000000000000000001b6fc127150282b390e255f0772e6f8d806e264d00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5809,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000eed8403b6513c80bfcedeb8b616796e4b91d1a0b000000000000000000000000eed8403b6513c80bfcedeb8b616796e4b91d1a0b000000000000000000000000000000000000000000000000000000007735940000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000444c019c90402033ff8246bcea440ceb9468c880000000000000000000000000444c019c90402033ff8246bcea440ceb9468c8800000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5811,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d0d6e0e58fe68bd495b4fd56bff3b19676460272000000000000000000000000d0d6e0e58fe68bd495b4fd56bff3b196764602720000000000000000000000000000000000000000000000000332e7e028cc6b7e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d565a49e5caa0eb79d5175405283fc0e3326c097000000000000000000000000d565a49e5caa0eb79d5175405283fc0e3326c0970000000000000000000000000000000000000000000000000003bde3f4c6630000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5815,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d41b30ea59b8e7fca13ac85172411bd98779fb9d000000000000000000000000d41b30ea59b8e7fca13ac85172411bd98779fb9d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d41b30ea59b8e7fca13ac85172411bd98779fb9d000000000000000000000000d41b30ea59b8e7fca13ac85172411bd98779fb9d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d41b30ea59b8e7fca13ac85172411bd98779fb9d000000000000000000000000d41b30ea59b8e7fca13ac85172411bd98779fb9d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f079c9d3f5b212698f30359d1bea0fe9a037e620000000000000000000000005f079c9d3f5b212698f30359d1bea0fe9a037e62000000000000000000000000000000000000000000000000003fc3a8285ee10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003bb97b97fa7499d688251eabae41ab0810f6dea50000000000000000000000003bb97b97fa7499d688251eabae41ab0810f6dea5000000000000000000000000000000000000000000000000009ee3b65cf3854b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5820,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffea6035d1300c983d2cbbe42e48351a2c1f27b9000000000000000000000000ffea6035d1300c983d2cbbe42e48351a2c1f27b90000000000000000000000000000000000000000000000000040d9ed9a7f6a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5822,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000958f5a41ba65d1eed7aae15a03a6e557c17b91fd000000000000000000000000958f5a41ba65d1eed7aae15a03a6e557c17b91fd00000000000000000000000000000000000000000000000001469b1fe578b62400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039be4b0a0b0486a28eb60bf16061be14f51ef91400000000000000000000000039be4b0a0b0486a28eb60bf16061be14f51ef91400000000000000000000000000000000000000000000000000acc4ce1d881f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b3dab9f937030d14eb25f6f25ce749c68dd57ab0000000000000000000000004b3dab9f937030d14eb25f6f25ce749c68dd57ab00000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000068e70285e515aeda9a99dcea429d0c9dc36a85b000000000000000000000000068e70285e515aeda9a99dcea429d0c9dc36a85b00000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e703b5d3abbfbf7d64c3e164f812b1998f097f47000000000000000000000000e703b5d3abbfbf7d64c3e164f812b1998f097f4700000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba35b90e51c42e1069bad364b65512c1e7d87f39000000000000000000000000ba35b90e51c42e1069bad364b65512c1e7d87f39000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e34076bc4355792c789a46ada9fa8a3e8b57f03b000000000000000000000000e34076bc4355792c789a46ada9fa8a3e8b57f03b00000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5831,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098908c98a27a26189f5f226aa16171c0cb9fdb3600000000000000000000000098908c98a27a26189f5f226aa16171c0cb9fdb3600000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000938780de40be92d05bfe2dac27ecc4c69f4cd6ac000000000000000000000000938780de40be92d05bfe2dac27ecc4c69f4cd6ac00000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000059b254553bb97ca61a99c2bbdbefb594aa94365000000000000000000000000059b254553bb97ca61a99c2bbdbefb594aa94365000000000000000000000000000000000000000000000000001947f6d5c72d4600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4e2be266106268849f75138db3f0ad66d804aad000000000000000000000000a4e2be266106268849f75138db3f0ad66d804aad000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8c650ccdec6078828b30bd52ae82caf31a38aae000000000000000000000000a8c650ccdec6078828b30bd52ae82caf31a38aae00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000913cf0f5d17c595a36c94dfec86f16efaa50f5b1000000000000000000000000913cf0f5d17c595a36c94dfec86f16efaa50f5b10000000000000000000000000000000000000000000000000038d494eb1715d100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cf0931ac79d56ef8ecef6842e0c78f7b3be789f0000000000000000000000005cf0931ac79d56ef8ecef6842e0c78f7b3be789f0000000000000000000000000000000000000000000000000154e7b83e4f34c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099e0ba8e8919d18fad1977208d50bdbabd868b1200000000000000000000000099e0ba8e8919d18fad1977208d50bdbabd868b12000000000000000000000000000000000000000000000000000c6f3b40b6c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5840,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053eb86f6d4d65d0325142844b4dac80ccf92404f00000000000000000000000053eb86f6d4d65d0325142844b4dac80ccf92404f0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067e3d581dbfe600510b0aed1a74b2840ef4ea3db00000000000000000000000067e3d581dbfe600510b0aed1a74b2840ef4ea3db00000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089b2439ed5a0579c9dd1ec0060dca78aa9e0276500000000000000000000000089b2439ed5a0579c9dd1ec0060dca78aa9e0276500000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b41ea083efb19b5a42e548f5b82594688b2a46c7000000000000000000000000b41ea083efb19b5a42e548f5b82594688b2a46c700000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad2df9bc2fe3438f5b67a25ef31557fa63420b0d000000000000000000000000ad2df9bc2fe3438f5b67a25ef31557fa63420b0d00000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081242be4885f8da938bc1795a0fc86b12bc7a01300000000000000000000000081242be4885f8da938bc1795a0fc86b12bc7a01300000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003035a1bbd824041b07f8ab2297a71a81e00127c50000000000000000000000003035a1bbd824041b07f8ab2297a71a81e00127c500000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3e470a3549faf6faad097a10ea574689edfc0ddfee58d7911e408f30905b6326,2021-12-03 08:47:30.000 UTC,0,true +5847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000432c4407683f2a751da658448f14a9fc76bf4887000000000000000000000000432c4407683f2a751da658448f14a9fc76bf488700000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008dbd7d8fad56a6698063c77447cd0d31f59c839f0000000000000000000000008dbd7d8fad56a6698063c77447cd0d31f59c839f00000000000000000000000000000000000000000000000000531d4f1ebe547d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4455961533f9bff3db0ffc51197679e76a044f0000000000000000000000000b4455961533f9bff3db0ffc51197679e76a044f000000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000257989cfdb248c515807d7e5892eeca350518c83000000000000000000000000257989cfdb248c515807d7e5892eeca350518c8300000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000942030d115a5895d1412604e4302dcd674875722000000000000000000000000942030d115a5895d1412604e4302dcd67487572200000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000592d646b32e06cbeb37eca996bc3de09b9284f02000000000000000000000000592d646b32e06cbeb37eca996bc3de09b9284f02000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053eb86f6d4d65d0325142844b4dac80ccf92404f00000000000000000000000053eb86f6d4d65d0325142844b4dac80ccf92404f000000000000000000000000000000000000000000000000058d15e17628000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed79e33546d13ae3e0bc5a295cdd16648bd3d1c7000000000000000000000000ed79e33546d13ae3e0bc5a295cdd16648bd3d1c700000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5855,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a90ee5a3bec0d9313b7992cd94dfc2f495f39041000000000000000000000000a90ee5a3bec0d9313b7992cd94dfc2f495f3904100000000000000000000000000000000000000000000000000638a5e59c50d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000334af0de88370100861140ad7d01d99ac0af1159000000000000000000000000334af0de88370100861140ad7d01d99ac0af1159000000000000000000000000000000000000000000000000001377384c99a6e200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000400d190cc5451e8127b3dd393559a7ed12249123000000000000000000000000400d190cc5451e8127b3dd393559a7ed1224912300000000000000000000000000000000000000000000000000ab856c2472fd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b843de66d048e87d986c6dda826a79e9a724d894000000000000000000000000b843de66d048e87d986c6dda826a79e9a724d89400000000000000000000000000000000000000000000000000013969cc61790000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007453019b806919563eac33870fe5f8e5154fdf380000000000000000000000007453019b806919563eac33870fe5f8e5154fdf3800000000000000000000000000000000000000000000000000c4ea764436a10600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8df0392700003ce47d3e1a40ad85f1a91c215d7d3bb5684c4777db996277a6a5,2022-05-29 05:47:39.000 UTC,0,true +5863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003459566b907c90be7868c2aad3a951b63ad631d90000000000000000000000003459566b907c90be7868c2aad3a951b63ad631d9000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000edadb841ffa02e2eb1f9b61829ad6ac318c38588000000000000000000000000edadb841ffa02e2eb1f9b61829ad6ac318c3858800000000000000000000000000000000000000000000000000406cdb6379180000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5868,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000151b079d1f51ff2dda6a4bcb7077380b0d76d721000000000000000000000000151b079d1f51ff2dda6a4bcb7077380b0d76d7210000000000000000000000000000000000000000000000000000b50c85fa2c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ccc93c66c6e80bf3d68bc63f546cbb42ab4895d6000000000000000000000000ccc93c66c6e80bf3d68bc63f546cbb42ab4895d6000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bd91efda871150bf54d11ee87ef67c2036b52460000000000000000000000001bd91efda871150bf54d11ee87ef67c2036b524600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d21dac3f1a8672d385ab7caeeb3eb31b5eee1947000000000000000000000000d21dac3f1a8672d385ab7caeeb3eb31b5eee194700000000000000000000000000000000000000000000000002c156df45ef030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082fd529006e13beea50f5cf906d268de905ce7f900000000000000000000000082fd529006e13beea50f5cf906d268de905ce7f900000000000000000000000000000000000000000000000000068b14feb6870200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8983d041f4e752032f2964b8e095c1f1c61956b000000000000000000000000b8983d041f4e752032f2964b8e095c1f1c61956b0000000000000000000000000000000000000000000000000375ebcf5a6ba6f900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fa3402befaf74404c531c878f433aac27bad2340000000000000000000000007fa3402befaf74404c531c878f433aac27bad23400000000000000000000000000000000000000000000000000ac12603c4be50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfa3f52d271883e11c0210b1bfd2fa061bf49d8a000000000000000000000000bfa3f52d271883e11c0210b1bfd2fa061bf49d8a00000000000000000000000000000000000000000000000002a0871a679c199a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007841ca40b1ae5e5b19818817ecd784a496f87df00000000000000000000000007841ca40b1ae5e5b19818817ecd784a496f87df00000000000000000000000000000000000000000000000000137ac9eb581b1c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5884,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099f0b621c3cb9149bd653ae5fcb79481764eb5f200000000000000000000000099f0b621c3cb9149bd653ae5fcb79481764eb5f200000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000196aafc8f801c749196062e19774ba747a8ac3c4000000000000000000000000196aafc8f801c749196062e19774ba747a8ac3c4000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb4b776bd8dadbe54b4de754338ac1f07897d3e0000000000000000000000000eb4b776bd8dadbe54b4de754338ac1f07897d3e0000000000000000000000000000000000000000000000000008d539894c0cc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1912c7917b6da214a7118d323c3049229d765b3000000000000000000000000f1912c7917b6da214a7118d323c3049229d765b300000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5894,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036e7f8a7e490f6b10f55c985441bbba13e04f5be00000000000000000000000036e7f8a7e490f6b10f55c985441bbba13e04f5be00000000000000000000000000000000000000000000000000464ac2467aa00700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5895,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007a64826e5798109d75b519010bcc833ee80d99d00000000000000000000000007a64826e5798109d75b519010bcc833ee80d99d000000000000000000000000000000000000000000000000015c9e002fa7730000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000490fcefab0dfbd85aeda3eef8fb4a0628bba2060000000000000000000000000490fcefab0dfbd85aeda3eef8fb4a0628bba206000000000000000000000000000000000000000000000000000443a6bd55edc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5898,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3c92ebf0eaa833207e49183a485c362489640a9000000000000000000000000e3c92ebf0eaa833207e49183a485c362489640a900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b114bd2fd24258a9ba8fe40e0c7081bda923f6aa000000000000000000000000b114bd2fd24258a9ba8fe40e0c7081bda923f6aa00000000000000000000000000000000000000000000000004022a29bd180c3800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5900,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000353b03d97f644bb6c296e07cd347af64083e918b000000000000000000000000353b03d97f644bb6c296e07cd347af64083e918b00000000000000000000000000000000000000000000001814d08819d47036aa00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5901,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce7e5098619f8660aad4bac0de6ac57ef709d8a7000000000000000000000000ce7e5098619f8660aad4bac0de6ac57ef709d8a7000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbab5f03e366b48459110f582953fe81fb88ec30000000000000000000000000cbab5f03e366b48459110f582953fe81fb88ec3000000000000000000000000000000000000000000000000000c29fb5eb32e5c900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5903,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b389b98659d17ec8c264b523064e246bb464e755000000000000000000000000b389b98659d17ec8c264b523064e246bb464e755000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5904,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e08a4b01143443f3beb5768748543d6347360f5b000000000000000000000000e08a4b01143443f3beb5768748543d6347360f5b0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5905,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000410d9cbadd36333d98c2391bc6525f1724d53949000000000000000000000000410d9cbadd36333d98c2391bc6525f1724d539490000000000000000000000000000000000000000000000000000000001e6aa3200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6e0f3c0c361675c8c08afb33eaea33880eaf239000000000000000000000000e6e0f3c0c361675c8c08afb33eaea33880eaf2390000000000000000000000000000000000000000000000000004dc00c864c2c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5907,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000410d9cbadd36333d98c2391bc6525f1724d53949000000000000000000000000410d9cbadd36333d98c2391bc6525f1724d5394900000000000000000000000000000000000000000000000000152cbe698a3f4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5908,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bc6480367e6e572e503b2b6b579031105b3c5c80000000000000000000000004bc6480367e6e572e503b2b6b579031105b3c5c800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ebc1818f2c4803cd8ecfb6dc0ee0da0dd42f31d0000000000000000000000003ebc1818f2c4803cd8ecfb6dc0ee0da0dd42f31d0000000000000000000000000000000000000000000000000008b8b072a6624a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5910,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002875403e0d69641cf631f10e48e63c40e4b27fc30000000000000000000000002875403e0d69641cf631f10e48e63c40e4b27fc3000000000000000000000000000000000000000000000000001becd9a8d38cb500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001778cb9fd8d489c740568a9bf16004d948d9b6bf0000000000000000000000001778cb9fd8d489c740568a9bf16004d948d9b6bf000000000000000000000000000000000000000000000000002d12be6ce4ce0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5912,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006241ad77084b023f13e9ef075610452d1b51725f0000000000000000000000006241ad77084b023f13e9ef075610452d1b51725f000000000000000000000000000000000000000000000000002e72d910156f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005a07d49f109207f5b23c6405a321d14fe8f130c00000000000000000000000005a07d49f109207f5b23c6405a321d14fe8f130c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5914,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000087b1f518ca6bec87d70af81e378fe961012e988200000000000000000000000087b1f518ca6bec87d70af81e378fe961012e98820000000000000000000000000000000000000000000000000000000001853e4500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +5915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb8248ab9b9e4e82beb10c74622975270643ee8d000000000000000000000000bb8248ab9b9e4e82beb10c74622975270643ee8d0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061656eb3ce807894625d4a87510e53e719186af000000000000000000000000061656eb3ce807894625d4a87510e53e719186af000000000000000000000000000000000000000000000000000ea7aa67b2d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007aa3c6a33ec4bbfc6319e3c98333a018efdb1e680000000000000000000000007aa3c6a33ec4bbfc6319e3c98333a018efdb1e6800000000000000000000000000000000000000000000000000a80290b961acc600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5919,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9bb8b1211ed7648982ac37cbaf4f381efb3db32000000000000000000000000a9bb8b1211ed7648982ac37cbaf4f381efb3db32000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9e2b81fd37418a8d2b276e257e9e129a79c1c21000000000000000000000000e9e2b81fd37418a8d2b276e257e9e129a79c1c2100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5922,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5771dd835880fff8cede5a8f5d0f2843ee9869e000000000000000000000000f5771dd835880fff8cede5a8f5d0f2843ee9869e00000000000000000000000000000000000000000000000000069dc7a032cb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000319aeb370f46a08477fa577a9b3567799dbae57d000000000000000000000000319aeb370f46a08477fa577a9b3567799dbae57d0000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006dfb311f0be648cd0b1fe2065b6d0ca41397bd140000000000000000000000006dfb311f0be648cd0b1fe2065b6d0ca41397bd14000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5927,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004d9618239044a2ab2581f0cc954d28873afa4d7b00000000000000000000000000000000000000000000000194755ac36206ac0a,,,1,true +5928,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000275c6cb0d5ce33ae2268438fe40fcf51bbc989bc000000000000000000000000275c6cb0d5ce33ae2268438fe40fcf51bbc989bc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5929,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008cf368d64aabb3996ff23707e9e326e8c707ef400000000000000000000000008cf368d64aabb3996ff23707e9e326e8c707ef40000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c33a2966a7559b41d0f4b1ad85a0d8468c3517c9000000000000000000000000c33a2966a7559b41d0f4b1ad85a0d8468c3517c9000000000000000000000000000000000000000000000000015e9f7961f4770000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e16a7785336f411796bbdd2246e13d506009c590000000000000000000000009e16a7785336f411796bbdd2246e13d506009c590000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5932,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005150fe3c1407fe9ccc2821feb94cf7dd6ca789c80000000000000000000000005150fe3c1407fe9ccc2821feb94cf7dd6ca789c800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5933,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006148cb29b9fadc348ddb3f87900f31bcc2dc645d0000000000000000000000006148cb29b9fadc348ddb3f87900f31bcc2dc645d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5934,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d5b7e62d31fcb77b0765a27b26b29bb76af54a80000000000000000000000004d5b7e62d31fcb77b0765a27b26b29bb76af54a800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5937,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de05d52a6a2f06399511098e408b37b24d1c0923000000000000000000000000de05d52a6a2f06399511098e408b37b24d1c092300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bed34780515bc6d6d4dec9cbc178dc7c3f523730000000000000000000000004bed34780515bc6d6d4dec9cbc178dc7c3f5237300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006dc681ae0d0a0525e302a9e0b26f4ea60015bc9e0000000000000000000000006dc681ae0d0a0525e302a9e0b26f4ea60015bc9e00000000000000000000000000000000000000000000000000169c9eee8f61e500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa81d0ab5fa49f4f0881fc6b8c51b53911c99336000000000000000000000000fa81d0ab5fa49f4f0881fc6b8c51b53911c99336000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5941,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dbbea5db8e58f569ac80cc71a9d8c7e9201d6205000000000000000000000000dbbea5db8e58f569ac80cc71a9d8c7e9201d6205000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5942,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdafef987dfe2e90c68b303d82f84fda268e43dc000000000000000000000000bdafef987dfe2e90c68b303d82f84fda268e43dc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fc9ae9b556a138c30c3bb4b149ebc0ebc419e500000000000000000000000008fc9ae9b556a138c30c3bb4b149ebc0ebc419e5000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5944,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a13f02db8b4f27531ceaeadf341ee69ea731ee4f000000000000000000000000a13f02db8b4f27531ceaeadf341ee69ea731ee4f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5945,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055b07b1efe15bbeff6209045775dc3d3aee1731b00000000000000000000000055b07b1efe15bbeff6209045775dc3d3aee1731b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5946,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af30b0285bb41bdbb732e4a533874901e4943522000000000000000000000000af30b0285bb41bdbb732e4a533874901e4943522000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5947,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054a212e596846a3e59c694f33073e6b4dc9f7d8e00000000000000000000000054a212e596846a3e59c694f33073e6b4dc9f7d8e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5948,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006291a2710471c6689b22acf546cc8c7379011ad00000000000000000000000006291a2710471c6689b22acf546cc8c7379011ad0000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5951,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049caffd56bf1e854ccfe40579a446553ba5f531200000000000000000000000049caffd56bf1e854ccfe40579a446553ba5f53120000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006d74a139d0181056baae5bb64db44e15e74ccbd00000000000000000000000006d74a139d0181056baae5bb64db44e15e74ccbd0000000000000000000000000000000000000000000000000021bb2d6e6cd40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5954,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2206efd4292d7722856670c7acfc8c5a36fbb8c000000000000000000000000b2206efd4292d7722856670c7acfc8c5a36fbb8c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5955,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006291a2710471c6689b22acf546cc8c7379011ad00000000000000000000000006291a2710471c6689b22acf546cc8c7379011ad000000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5956,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000325a250b27c689717327997de95e0d71303729b0000000000000000000000000325a250b27c689717327997de95e0d71303729b000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5957,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5a99d45458fcd9bad227d94190fad98157c565d000000000000000000000000d5a99d45458fcd9bad227d94190fad98157c565d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ed64b84c54763d4ea9ffd645431176e1471034d0000000000000000000000008ed64b84c54763d4ea9ffd645431176e1471034d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5b41c5b4bf57c4fbe4fb638b1106e00b9210b79000000000000000000000000b5b41c5b4bf57c4fbe4fb638b1106e00b9210b7900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5960,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006d71e7ea3a5b4a2f0760a06d0b393a29b4ace7e00000000000000000000000006d71e7ea3a5b4a2f0760a06d0b393a29b4ace7e0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a878215d4cf364777b75b4e35ed8e004fdcde1f0000000000000000000000008a878215d4cf364777b75b4e35ed8e004fdcde1f0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000410d9cbadd36333d98c2391bc6525f1724d53949000000000000000000000000410d9cbadd36333d98c2391bc6525f1724d53949000000000000000000000000000000000000000000000000002d010feed42fc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b82b8a947c5e4c4a5d2a9ca659712d92394135c0000000000000000000000005b82b8a947c5e4c4a5d2a9ca659712d92394135c0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5964,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014f0b038c7d8487a40d05da17d7e0c412b9e712e00000000000000000000000014f0b038c7d8487a40d05da17d7e0c412b9e712e0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffd70adf0fc48fc2f0e3866ef02f893794588d0f000000000000000000000000ffd70adf0fc48fc2f0e3866ef02f893794588d0f00000000000000000000000000000000000000000000000000805bbf5222998700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c9082b3eccbbb7a83a1d54317735f126bf990170000000000000000000000008c9082b3eccbbb7a83a1d54317735f126bf990170000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5967,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0678aff40449aa5d26292558846da4b5e745bfd000000000000000000000000e0678aff40449aa5d26292558846da4b5e745bfd00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6bc3639127cac8e38cefc1670109d8fedfd1ac0000000000000000000000000c6bc3639127cac8e38cefc1670109d8fedfd1ac000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ba2fc93c2306110c6cedc576e7e150c0d32f67b0000000000000000000000001ba2fc93c2306110c6cedc576e7e150c0d32f67b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5970,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be0c773fa345a04f1570fda6859cf6500e437dc6000000000000000000000000be0c773fa345a04f1570fda6859cf6500e437dc600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023a88b6fcb58dbc37d415e654384d9bf7a51a50800000000000000000000000023a88b6fcb58dbc37d415e654384d9bf7a51a5080000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000989111660f5c0872ad46881d56267c186782db22000000000000000000000000989111660f5c0872ad46881d56267c186782db2200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5973,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a738b833927a7ac96e05aa27aa49c5ded511f345000000000000000000000000a738b833927a7ac96e05aa27aa49c5ded511f34500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045d036d3a342248eb2e3880d144079630cccba2800000000000000000000000045d036d3a342248eb2e3880d144079630cccba2800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf0b8850992a8ebd82b2247d9c5d296f26add866000000000000000000000000bf0b8850992a8ebd82b2247d9c5d296f26add86600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ce6d8964996007feab7d718264a0a31791bcc020000000000000000000000008ce6d8964996007feab7d718264a0a31791bcc0200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5978,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000215b32d9c41b217328b9a185fb68e82a43afa3d0000000000000000000000000215b32d9c41b217328b9a185fb68e82a43afa3d000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5979,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008cf6eb2048d61f1d36e33331a20110c42cded27f0000000000000000000000008cf6eb2048d61f1d36e33331a20110c42cded27f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5980,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e796b8b4d0646e7d2717840372020a431b738410000000000000000000000006e796b8b4d0646e7d2717840372020a431b7384100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065a3c7d35b7deb7a76000b9e6118b4ce8a6ce99000000000000000000000000065a3c7d35b7deb7a76000b9e6118b4ce8a6ce9900000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093af239db06c41adea389ab30b3b6a9e69d34a8f00000000000000000000000093af239db06c41adea389ab30b3b6a9e69d34a8f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5983,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ecf30ad77bc17ca2959cadbbf23f791da44c3ca3000000000000000000000000ecf30ad77bc17ca2959cadbbf23f791da44c3ca30000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5984,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e29d74db1f1147cc3717102e64f6e7cfa66c7430000000000000000000000007e29d74db1f1147cc3717102e64f6e7cfa66c74300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000347cc2875d007d2ffd5ccfd2f700538fbb66a0d0000000000000000000000000347cc2875d007d2ffd5ccfd2f700538fbb66a0d00000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5986,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000422a4fa6b254f24718d79bd6f86f6315cf50d139000000000000000000000000422a4fa6b254f24718d79bd6f86f6315cf50d13900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5988,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010d456618cd9ad73e0bbfe060d9b6c92e54b858e00000000000000000000000010d456618cd9ad73e0bbfe060d9b6c92e54b858e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5989,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de0d201cffb9e692ef999bed8aefee0dcc7b2cb4000000000000000000000000de0d201cffb9e692ef999bed8aefee0dcc7b2cb40000000000000000000000000000000000000000000000000081277a09edf8a100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f26286c4b6c7edbeb055405fe653a2c5cec27ae0000000000000000000000001f26286c4b6c7edbeb055405fe653a2c5cec27ae00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5991,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000804d91166fd352e5712482dd1f5c5c329c4d64a8000000000000000000000000804d91166fd352e5712482dd1f5c5c329c4d64a80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5992,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0f0a3f1d464119592504540ca9893f1ecc11539000000000000000000000000a0f0a3f1d464119592504540ca9893f1ecc11539000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092c5d762103ddfca8d2ded96dd503317873afb1e00000000000000000000000092c5d762103ddfca8d2ded96dd503317873afb1e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006111bfff26b60a5b45a2693db6fef1a52897f84c0000000000000000000000006111bfff26b60a5b45a2693db6fef1a52897f84c00000000000000000000000000000000000000000000000000027ca57357c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5995,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000316e0ba8105e8bbf53a9549ceff8cc36f8761e75000000000000000000000000316e0ba8105e8bbf53a9549ceff8cc36f8761e7500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a618250db48aca188d44d3827ed627166a2f7be1000000000000000000000000a618250db48aca188d44d3827ed627166a2f7be100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +5998,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009efbebcc6e7284d8e97a3ccd06d735d25391a9b10000000000000000000000009efbebcc6e7284d8e97a3ccd06d735d25391a9b100000000000000000000000000000000000000000000000002390c216e8f067000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6000,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b2798b32b5006641265f86c823d4938cad329070000000000000000000000007b2798b32b5006641265f86c823d4938cad3290700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6001,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f92305d31299a049387e78992961cffbad0315b5000000000000000000000000f92305d31299a049387e78992961cffbad0315b500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6002,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020ff9ae90bd2751559bdc01bf425cc395831d09100000000000000000000000020ff9ae90bd2751559bdc01bf425cc395831d091000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6003,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000239f09dfa18d501cbd283237f3985c04047b7a57000000000000000000000000239f09dfa18d501cbd283237f3985c04047b7a57000000000000000000000000000000000000000000000000083361c02feb308000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x73837927bca29223e9527991ff947f94b48bd6f7e2939dc77cfdcc2b110c662f,2022-04-28 09:49:33.000 UTC,0,true +6004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000860ecd7df22ec9c7d8535fd9e59faae93b20bb9a000000000000000000000000860ecd7df22ec9c7d8535fd9e59faae93b20bb9a00000000000000000000000000000000000000000000000000a66e480ee9c92300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6005,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c80651d6ddd6d35b380d1c9e7d56d25e400163a4000000000000000000000000c80651d6ddd6d35b380d1c9e7d56d25e400163a400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6006,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e7243c2681857f05891be7e91a6049402dd74060000000000000000000000004e7243c2681857f05891be7e91a6049402dd740600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6007,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084a1830b4ca5c9ec317a380756cf3fd9ea9889f700000000000000000000000084a1830b4ca5c9ec317a380756cf3fd9ea9889f700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6008,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cf60c4bd43defd4e62096e7a82f615b4fe156840000000000000000000000005cf60c4bd43defd4e62096e7a82f615b4fe1568400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6009,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053c0e301d886723f7e76ca2db4b9fd673ff690ab00000000000000000000000053c0e301d886723f7e76ca2db4b9fd673ff690ab00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6010,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a8d1e6a7af3ff1b85f5056af6aed9caa5a670840000000000000000000000001a8d1e6a7af3ff1b85f5056af6aed9caa5a6708400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6012,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f35f15297404e21d832232cca28933dc1ff75bb0000000000000000000000003f35f15297404e21d832232cca28933dc1ff75bb00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c14eaa5467971a22a8d0198f6319595055208c80000000000000000000000002c14eaa5467971a22a8d0198f6319595055208c800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6014,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000100ceb2adcfdbd339a2926ea670298a91ee3d501000000000000000000000000100ceb2adcfdbd339a2926ea670298a91ee3d501000000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6015,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d6d085f6b641799f70e0446fa96c828d66b1bc1d000000000000000000000000d6d085f6b641799f70e0446fa96c828d66b1bc1d0000000000000000000000000000000000000000000000000000000002f6b2da00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +6017,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6d085f6b641799f70e0446fa96c828d66b1bc1d000000000000000000000000d6d085f6b641799f70e0446fa96c828d66b1bc1d0000000000000000000000000000000000000000000000000035b6219134d70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6019,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073da2ab610c2e570740ec6e6aeb857b22240227000000000000000000000000073da2ab610c2e570740ec6e6aeb857b2224022700000000000000000000000000000000000000000000000000036ceeccdf7194000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe59037c08ab16d1757f0f85617051c227a744e969f18cedcc4bf7b61cc4113c7,2022-03-12 06:40:03.000 UTC,0,true +6020,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088a3dd4a42cb8f0655e0807b99969fcf45a2f9f700000000000000000000000088a3dd4a42cb8f0655e0807b99969fcf45a2f9f700000000000000000000000000000000000000000000000000a30ca23cb262b500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aaaca4aae53881cca5f86b9b46f5b04e9ae3b0f2000000000000000000000000aaaca4aae53881cca5f86b9b46f5b04e9ae3b0f2000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e3d993a8d63c25d1db5f7ff8a8d6c59091003b10000000000000000000000007e3d993a8d63c25d1db5f7ff8a8d6c59091003b1000000000000000000000000000000000000000000000000029fb0b4300d0aff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be13517a2b520b2449068d2ec45280992b04047b000000000000000000000000be13517a2b520b2449068d2ec45280992b04047b000000000000000000000000000000000000000000000000007dd601852ed8a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002db35527a753850b4396367a03fa834d13a32f100000000000000000000000002db35527a753850b4396367a03fa834d13a32f10000000000000000000000000000000000000000000000000000a747dcc27c90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da1cb7ea9b5ee288bce3bb4cac2b6642c5421411000000000000000000000000da1cb7ea9b5ee288bce3bb4cac2b6642c5421411000000000000000000000000000000000000000000000000001f0bbd8db1e20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3784cfaf0471b99f37c339db3d302e8a13b1a7a000000000000000000000000d3784cfaf0471b99f37c339db3d302e8a13b1a7a00000000000000000000000000000000000000000000000000a51beaf8f1d45200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce788cacc9211fa93af8747d6c652fb425280d72000000000000000000000000ce788cacc9211fa93af8747d6c652fb425280d72000000000000000000000000000000000000000000000000005d2ac67a8c578000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b919a9fdf4d9f8f812ad64bd8599850e9f810e2c000000000000000000000000b919a9fdf4d9f8f812ad64bd8599850e9f810e2c000000000000000000000000000000000000000000000000003e61535f69a6c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6032,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098f82578da11c79c95459a26fb27baa3ca7f906a00000000000000000000000098f82578da11c79c95459a26fb27baa3ca7f906a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9d4f265d008b0fc42829e80dcf3d5f14835d0b4000000000000000000000000c9d4f265d008b0fc42829e80dcf3d5f14835d0b40000000000000000000000000000000000000000000000000039f6c353d8c44b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6037,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009458c4ad1c97e9f26315a8c904175db628ff9f930000000000000000000000009458c4ad1c97e9f26315a8c904175db628ff9f93000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6038,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000837550f148ebf3e7de481f8778582c429f1e8274000000000000000000000000837550f148ebf3e7de481f8778582c429f1e8274000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6039,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000716ae766ee5c3590b516f2da5921540044fcdd93000000000000000000000000716ae766ee5c3590b516f2da5921540044fcdd93000000000000000000000000000000000000000000000000003d1cf622b4ab8700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6042,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054b7f8fe8d3aaeeb115d2ae1ac9ea5d6b824e2dc00000000000000000000000054b7f8fe8d3aaeeb115d2ae1ac9ea5d6b824e2dc000000000000000000000000000000000000000000000000003da48c1309d78d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6044,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f198c77d9c968840995e0172a003388d4aa02352000000000000000000000000f198c77d9c968840995e0172a003388d4aa023520000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6046,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f7bac92aa3e28351f9e89535ca334e8a44542d00000000000000000000000007f7bac92aa3e28351f9e89535ca334e8a44542d000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6047,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a38b009f9e176f07978c2e75bab2a5b657ca37a0000000000000000000000007a38b009f9e176f07978c2e75bab2a5b657ca37a00000000000000000000000000000000000000000000000000000000006acfc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6049,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f830a902a162874c946bf9e9b11e1388caee3029000000000000000000000000f830a902a162874c946bf9e9b11e1388caee302900000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e220bfb0d093e2b1fdc7d3af08c97f5b22f7f908000000000000000000000000e220bfb0d093e2b1fdc7d3af08c97f5b22f7f908000000000000000000000000000000000000000000000000001cab25204daf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6052,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acc452a494b59a3f536d717f6222d09c5acf20a8000000000000000000000000acc452a494b59a3f536d717f6222d09c5acf20a8000000000000000000000000000000000000000000000000008d3438f6e5930e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d16ef7f37544a3792463a44d0557eab4c21d89a1000000000000000000000000d16ef7f37544a3792463a44d0557eab4c21d89a10000000000000000000000000000000000000000000000000001de405f21460000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2bf6ac67aee061297775043ccd9b613e53413a5000000000000000000000000a2bf6ac67aee061297775043ccd9b613e53413a5000000000000000000000000000000000000000000000000015396a49d67732a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6055,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d89fb7b2953670b03c28f81c77658191b6036c91000000000000000000000000d89fb7b2953670b03c28f81c77658191b6036c9100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6056,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b5f0ceaa46a28dcefa619e14a3536fbd6296f270000000000000000000000009b5f0ceaa46a28dcefa619e14a3536fbd6296f2700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000f3a2fc40c421a320d235e70543a06620e50b5400000000000000000000000000f3a2fc40c421a320d235e70543a06620e50b5400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6058,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da5c938837e5cd21c8e37a2811bb9bda6515955c000000000000000000000000da5c938837e5cd21c8e37a2811bb9bda6515955c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000505d2d3979f41ac084851a89b2ef154a65dd8a0f000000000000000000000000505d2d3979f41ac084851a89b2ef154a65dd8a0f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df60be630e94a957b5f4033c7def69e1c4554bb6000000000000000000000000df60be630e94a957b5f4033c7def69e1c4554bb6000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038e75b73c046372b353c9b4bb3e11ca6f6e7515800000000000000000000000038e75b73c046372b353c9b4bb3e11ca6f6e7515800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6062,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ffdf260bb7dbeac048c593166260a960bf71b7a0000000000000000000000003ffdf260bb7dbeac048c593166260a960bf71b7a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6063,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae966d3bf115eb480ee121dc20dc2b7e8326911d000000000000000000000000ae966d3bf115eb480ee121dc20dc2b7e8326911d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6064,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000535a625fd19e7dafa1bd07f60576f780e50711e0000000000000000000000000535a625fd19e7dafa1bd07f60576f780e50711e000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006177da08f66984b7e116d9f2079b98c5fe6f507e0000000000000000000000006177da08f66984b7e116d9f2079b98c5fe6f507e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6066,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000550305bd6b572fef436002aad6fb5fdec9f3e8b2000000000000000000000000550305bd6b572fef436002aad6fb5fdec9f3e8b200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6067,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3ef731cee95b989fafcf3ee2949dbaa8bd04f3f000000000000000000000000b3ef731cee95b989fafcf3ee2949dbaa8bd04f3f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6068,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bec87160d56dd6d3c41c56613088e0559fabb689000000000000000000000000bec87160d56dd6d3c41c56613088e0559fabb68900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6069,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8f1091949750d217e8fb7aab56269e6595e27e9000000000000000000000000e8f1091949750d217e8fb7aab56269e6595e27e9000000000000000000000000000000000000000000000000005802b8233a3f4900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6070,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a169d8ad32ce1a54c456b446e182aac42420b9d2000000000000000000000000a169d8ad32ce1a54c456b446e182aac42420b9d200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6071,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea5e21ef5ff21d7cb4c83df80620226e19f6cf08000000000000000000000000ea5e21ef5ff21d7cb4c83df80620226e19f6cf0800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6072,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097310815e5fe521d95428ff81034ca1000144cfd00000000000000000000000097310815e5fe521d95428ff81034ca1000144cfd00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6073,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0fdf298d1be0cc74cf50d4be0d2289ce3a6f713000000000000000000000000a0fdf298d1be0cc74cf50d4be0d2289ce3a6f71300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6074,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef5c351763eeb26c2be15d6d649c3bffa5b2e62e000000000000000000000000ef5c351763eeb26c2be15d6d649c3bffa5b2e62e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d0a78bca674769691690edb78890ddd3ac787800000000000000000000000006d0a78bca674769691690edb78890ddd3ac7878000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8a17e27c663954a6b13102dbf1d6e8be11f2a1e000000000000000000000000e8a17e27c663954a6b13102dbf1d6e8be11f2a1e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6077,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de1fa30568693e95411d978f50d61d95583cc41c000000000000000000000000de1fa30568693e95411d978f50d61d95583cc41c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c7004540ad0735906fc803f4d4fad1a1dbd264b0000000000000000000000001c7004540ad0735906fc803f4d4fad1a1dbd264b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b1e1e51b869d5c3098314708243fe6a70e0b73b0000000000000000000000007b1e1e51b869d5c3098314708243fe6a70e0b73b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab881a681a63d6da7eddbea7008355780f84cbcc000000000000000000000000ab881a681a63d6da7eddbea7008355780f84cbcc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072418814ddece4a58be3a8c772b817c5d0985bab00000000000000000000000072418814ddece4a58be3a8c772b817c5d0985bab00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc518a752f63e70ae1d902359c627fc3b16eabf4000000000000000000000000dc518a752f63e70ae1d902359c627fc3b16eabf400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fdbb828d024bca418e7d381f4a51b17943f3ff0f000000000000000000000000fdbb828d024bca418e7d381f4a51b17943f3ff0f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6084,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042ade5caf115cca078731afb4e74da068db7546a00000000000000000000000042ade5caf115cca078731afb4e74da068db7546a00000000000000000000000000000000000000000000000000a639bd2a06204700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6085,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023ac809fab9fcd6845150bb5b60836b0f37b2be300000000000000000000000023ac809fab9fcd6845150bb5b60836b0f37b2be300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2906419014f9bc87a0bad857630716a22e821a1000000000000000000000000f2906419014f9bc87a0bad857630716a22e821a100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034316123517658e803efaa1d01e6c943bfd54a5200000000000000000000000034316123517658e803efaa1d01e6c943bfd54a5200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019563a18135447a1227a415f2464329b76095c2100000000000000000000000019563a18135447a1227a415f2464329b76095c2100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d696bb2a273469e81db818eedf3e55020a69fe49000000000000000000000000d696bb2a273469e81db818eedf3e55020a69fe4900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6090,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abd91342f65fdf85b2803eb2b26b0c5a849ec204000000000000000000000000abd91342f65fdf85b2803eb2b26b0c5a849ec20400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6091,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f5ba92a3f6cd97151be5091add73fb87ebd40650000000000000000000000009f5ba92a3f6cd97151be5091add73fb87ebd406500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3e543f609321e0ecac4e60a322bc833402bccf0000000000000000000000000d3e543f609321e0ecac4e60a322bc833402bccf000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5350d0cfc2947655b08386ae6a257428df6e7b6000000000000000000000000d5350d0cfc2947655b08386ae6a257428df6e7b600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000102d8693ae4f47366b50218e1e6a4752c90a1356000000000000000000000000102d8693ae4f47366b50218e1e6a4752c90a135600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4d43e87d85fec5339e8517fb677b6884c8895c4000000000000000000000000c4d43e87d85fec5339e8517fb677b6884c8895c400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6096,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddacf2b28b3c5f08c9e638bc0c28f1e3d0dde6de000000000000000000000000ddacf2b28b3c5f08c9e638bc0c28f1e3d0dde6de00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e55b4c05d74d84931a513f3c7b37d609a487c0ea000000000000000000000000e55b4c05d74d84931a513f3c7b37d609a487c0ea0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6098,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000265c7ee6c12d5450cf883a8c1d448d5862dd52af000000000000000000000000265c7ee6c12d5450cf883a8c1d448d5862dd52af000000000000000000000000000000000000000000000000005d8d5c28d6173d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6099,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008bb0dbb962e6add906c6fbf8d30620a757074a650000000000000000000000008bb0dbb962e6add906c6fbf8d30620a757074a6500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6100,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000874f15934503cad67c145bed096e03966b2639e6000000000000000000000000874f15934503cad67c145bed096e03966b2639e600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5126ae26d383d2bf95315ae952aa78127b8ac7f000000000000000000000000e5126ae26d383d2bf95315ae952aa78127b8ac7f000000000000000000000000000000000000000000000000004adda27681328d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6102,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007412e63420f327482b0513fb63b8c7ffc04d7a400000000000000000000000007412e63420f327482b0513fb63b8c7ffc04d7a4000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6103,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033a081ac356765e4f084772d4490890567015a8900000000000000000000000033a081ac356765e4f084772d4490890567015a8900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6104,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092cc1672390d00636e107d190222a530b266c41e00000000000000000000000092cc1672390d00636e107d190222a530b266c41e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf61155471f6f338b282c3ec5e65e4f5eeee8354000000000000000000000000bf61155471f6f338b282c3ec5e65e4f5eeee835400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6106,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bba6cd8b55cb2952bb24a987686aa74d2d27d633000000000000000000000000bba6cd8b55cb2952bb24a987686aa74d2d27d63300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ed63aaad9f9e4aec77b06858e2ccb1afadc2d340000000000000000000000000ed63aaad9f9e4aec77b06858e2ccb1afadc2d3400000000000000000000000000000000000000000000000000ab4a21e9a8010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6108,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e401b9bcab9929b0aaabf0ec0d189122084ecf58000000000000000000000000e401b9bcab9929b0aaabf0ec0d189122084ecf580000000000000000000000000000000000000000000000000001794a6c866b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6109,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027099c76408a157c934a1d41e98ec545f5d1d77b00000000000000000000000027099c76408a157c934a1d41e98ec545f5d1d77b00000000000000000000000000000000000000000000000000017777ce9a7aab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6111,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065f4ab2661a4e5c8f5c37e121819db86ee93b2cd00000000000000000000000065f4ab2661a4e5c8f5c37e121819db86ee93b2cd0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6112,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e70d82324cf51b204a875f72a4648c03694043f0000000000000000000000008e70d82324cf51b204a875f72a4648c03694043f0000000000000000000000000000000000000000000000000001ede9b71cee0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6114,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a31723b2e0bdfe317f4e07589436ecf5515622d2000000000000000000000000a31723b2e0bdfe317f4e07589436ecf5515622d20000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6115,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c6d446d4b7ff3a5bd4cfa8b91e2fcdb9af984f90000000000000000000000005c6d446d4b7ff3a5bd4cfa8b91e2fcdb9af984f90000000000000000000000000000000000000000000000000001fc74ad620a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6116,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000754501440645e89d8a06dd698ad55fadd0b4a556000000000000000000000000754501440645e89d8a06dd698ad55fadd0b4a5560000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6117,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2c67e0b55f80738ad264c1a973929362dee3213000000000000000000000000e2c67e0b55f80738ad264c1a973929362dee32130000000000000000000000000000000000000000000000000002c9741f4dc10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6118,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057ade2bed67c61f01176997a2c87c8eb8e4ddd4c00000000000000000000000057ade2bed67c61f01176997a2c87c8eb8e4ddd4c0000000000000000000000000000000000000000000000000002dd96fe23990000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6119,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087db5fff1928edfaa0dcdf531e821e28721b3f1c00000000000000000000000087db5fff1928edfaa0dcdf531e821e28721b3f1c000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aae53a6ead2a4c07e34e49f1e658152355450d7f000000000000000000000000aae53a6ead2a4c07e34e49f1e658152355450d7f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be6b0ef7b49e4bb39a44ed4c629c559c229a6b05000000000000000000000000be6b0ef7b49e4bb39a44ed4c629c559c229a6b050000000000000000000000000000000000000000000000000002dd96fe23990000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000259e397108514b8a2cc910429590a17ceb14f772000000000000000000000000259e397108514b8a2cc910429590a17ceb14f772000000000000000000000000000000000000000000000000000215111312120000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004acddeea281310d00756555e42be3802f9bf771e0000000000000000000000004acddeea281310d00756555e42be3802f9bf771e0000000000000000000000000000000000000000000000000001f4e799d1d90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6124,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000070330e027a3e4327ba69f0c8a1885df4b545837000000000000000000000000070330e027a3e4327ba69f0c8a1885df4b54583700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023b31301bffdc9c7f55661a4db9c0a904d1eb62e00000000000000000000000023b31301bffdc9c7f55661a4db9c0a904d1eb62e0000000000000000000000000000000000000000000000000002e01b59fe540000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6126,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000301feaced087a254b09874551da70d4c58689f04000000000000000000000000301feaced087a254b09874551da70d4c58689f040000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6127,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077edee3b888d9ce54df25b18a4badf9f6340d73300000000000000000000000077edee3b888d9ce54df25b18a4badf9f6340d73300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6128,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006afd0cf9e929bf7c46b8b729233697bc226078880000000000000000000000006afd0cf9e929bf7c46b8b729233697bc2260788800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6129,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b75b8c39c3c42c9dee4b82363606cb28c3d0a2f0000000000000000000000006b75b8c39c3c42c9dee4b82363606cb28c3d0a2f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000131b76b9b89dd3d98147ec3b7e2cb73adf245133000000000000000000000000131b76b9b89dd3d98147ec3b7e2cb73adf24513300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db9718552f6b5a06422d7ce790a0f47241178753000000000000000000000000db9718552f6b5a06422d7ce790a0f4724117875300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000576bf86b5e5f52632b98ac3bdb2a8291cdf79337000000000000000000000000576bf86b5e5f52632b98ac3bdb2a8291cdf793370000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bd78ab5053a84cb285b81024fb10ea2c465b0450000000000000000000000006bd78ab5053a84cb285b81024fb10ea2c465b0450000000000000000000000000000000000000000000000000102a336dba6000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0ad0a7a432e058733cd4819efb1e859bae49b68000000000000000000000000c0ad0a7a432e058733cd4819efb1e859bae49b68000000000000000000000000000000000000000000000000015d576bf398980000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6137,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073ab8be850af291e989039bad78a65a32347286700000000000000000000000073ab8be850af291e989039bad78a65a3234728670000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6138,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3227760f77cd04dc27de314b02efd2850676b66000000000000000000000000f3227760f77cd04dc27de314b02efd2850676b66000000000000000000000000000000000000000000000000015e49a47c439e4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6139,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000001001ed634ff8b495479783a0620fdd71a6151b6c0000000000000000000000001001ed634ff8b495479783a0620fdd71a6151b6c000000000000000000000000000000000000000000000000000000000f4c0c6c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +6140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6536a05bdbbcdaf352ad53382136ebe9d277eb5000000000000000000000000a6536a05bdbbcdaf352ad53382136ebe9d277eb50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6141,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008de42a7b282832b84bfcf7c2e9edb882b99abaac0000000000000000000000008de42a7b282832b84bfcf7c2e9edb882b99abaac00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6142,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000200d4376a05189581fc658c0ffdad4a56861331d000000000000000000000000200d4376a05189581fc658c0ffdad4a56861331d00000000000000000000000000000000000000000000000000bd4a7fa937ec8b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028b4f08d1f1aa9bfe787447dcf75ff3fea1fd4d200000000000000000000000028b4f08d1f1aa9bfe787447dcf75ff3fea1fd4d20000000000000000000000000000000000000000000000000090851ef9cb3c9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000cf7a503b76b63e8c8642f3bf6af64fffe1e8efb0000000000000000000000000cf7a503b76b63e8c8642f3bf6af64fffe1e8efb00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005a71143c2cb2c26d0a94553534ee2059d275ad400000000000000000000000005a71143c2cb2c26d0a94553534ee2059d275ad40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6152,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008613b7748af1126a07d522869cb48a9d0485fe310000000000000000000000008613b7748af1126a07d522869cb48a9d0485fe31000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000680e0e17a8998c5d3221f470706f0d20c66c6a7b000000000000000000000000680e0e17a8998c5d3221f470706f0d20c66c6a7b000000000000000000000000000000000000000000000000014b7db4e94fb01d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6154,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061c33a73354e33e297948d60b3a83fd14b3ca21900000000000000000000000061c33a73354e33e297948d60b3a83fd14b3ca219000000000000000000000000000000000000000000000000003a8321cc8d7c5300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000280b04d23618f2983b8008f8d4b796d1a37ecd21000000000000000000000000280b04d23618f2983b8008f8d4b796d1a37ecd2100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6157,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000489872f68bd0da1ca97383a97342f0e230c8f24f000000000000000000000000489872f68bd0da1ca97383a97342f0e230c8f24f00000000000000000000000000000000000000000000000002c28a7efb0a6d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6158,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043769e73238a7cc8ad08fabc427620a5361ef19900000000000000000000000043769e73238a7cc8ad08fabc427620a5361ef199000000000000000000000000000000000000000000000000003f835535de6f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075db933f690903730724498e1767bd7bbbf5a45c00000000000000000000000075db933f690903730724498e1767bd7bbbf5a45c000000000000000000000000000000000000000000000000009c35bf3ca1488400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6161,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d07ca009d9e507e780fd921d63c90c2bcd1052c0000000000000000000000001d07ca009d9e507e780fd921d63c90c2bcd1052c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6162,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008efcd8400655a9a0887368b13ec631e8bf0a7d540000000000000000000000008efcd8400655a9a0887368b13ec631e8bf0a7d540000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c036c021402451242cd413a6a6b863ff41b8e6ac000000000000000000000000c036c021402451242cd413a6a6b863ff41b8e6ac00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6164,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f98490ed481611ae1945c62274a20480c8cdc400000000000000000000000000f98490ed481611ae1945c62274a20480c8cdc40000000000000000000000000000000000000000000000000008c2864635c488000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5415e9b0b366662bbd8500692460bbf3aba81387e664839dc877bfd7a1672b1c,2021-12-11 12:51:43.000 UTC,0,true +6165,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035164610721ffab73d28e4a16e32607288946af400000000000000000000000035164610721ffab73d28e4a16e32607288946af40000000000000000000000000000000000000000000000000011ca63fd75a5c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056df4482739435c82d8129a98555ac93d1f3f52500000000000000000000000056df4482739435c82d8129a98555ac93d1f3f52500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c43cd6565c758ea8331ffd1fc40dd2eb685cdf40000000000000000000000000c43cd6565c758ea8331ffd1fc40dd2eb685cdf40000000000000000000000000000000000000000000000000015cdb872ddf870000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6169,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007bf37710f7139be98db50b2259051f84e41397f80000000000000000000000007bf37710f7139be98db50b2259051f84e41397f800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a4bdd1484b10c2b77da547bd8c58b05896d18930000000000000000000000004a4bdd1484b10c2b77da547bd8c58b05896d189300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6172,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b60edeab595a8e908e12ee2c11e744883b2d61a0000000000000000000000006b60edeab595a8e908e12ee2c11e744883b2d61a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6173,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827f2155e5d6cc98b176c0d6033cc08849e7a863000000000000000000000000827f2155e5d6cc98b176c0d6033cc08849e7a86300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000495fc90677e398d70b5066f294337f164a996b52000000000000000000000000495fc90677e398d70b5066f294337f164a996b5200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6175,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2460960451ec2482b2ee668c844d59aa7f2f7f1000000000000000000000000a2460960451ec2482b2ee668c844d59aa7f2f7f100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d42ad56aac4b4dd8a5173b440e511d66ef268b93000000000000000000000000d42ad56aac4b4dd8a5173b440e511d66ef268b93000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cf968f202abb9f97063c5ce1a0ed07ff2f3e6280000000000000000000000005cf968f202abb9f97063c5ce1a0ed07ff2f3e628000000000000000000000000000000000000000000000000000179b5479f971c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1ef5b3dffd39b3e40b9b6ccefcb1b9020c49348000000000000000000000000d1ef5b3dffd39b3e40b9b6ccefcb1b9020c49348000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x103d287f08f7487a6e59416c97ae80eb0999027818c090561a200a6e92d948a2,2022-09-11 09:39:19.000 UTC,0,true +6179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba09d569676f00a800144a557ce45729f9067bf7000000000000000000000000ba09d569676f00a800144a557ce45729f9067bf700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd2e96e66c9508029d5520f1f991e8cd8dc6e562000000000000000000000000fd2e96e66c9508029d5520f1f991e8cd8dc6e5620000000000000000000000000000000000000000000000000008d7749523930000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bab442313afd6650d8cf23cf5bdc29255694df2a000000000000000000000000bab442313afd6650d8cf23cf5bdc29255694df2a00000000000000000000000000000000000000000000000000a917e195bb6aac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4f28a98f1f3f45acffc42dea779467516a9c486000000000000000000000000d4f28a98f1f3f45acffc42dea779467516a9c486000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6187,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0901490ea1dbbb439aa472e89945fb2d7a077b7000000000000000000000000c0901490ea1dbbb439aa472e89945fb2d7a077b70000000000000000000000000000000000000000000000000076add99dfcc82600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6188,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d2fc24c8e0a517be44017c363738feacc336f460000000000000000000000003d2fc24c8e0a517be44017c363738feacc336f4600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6190,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003296fb4fb0188d3c4ebbc6ee55ce636ac1ab5b4b0000000000000000000000003296fb4fb0188d3c4ebbc6ee55ce636ac1ab5b4b000000000000000000000000000000000000000000000000009317d79afac68000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6191,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6e8d29a8c5d0fcef149c5641e1eee004582d07e000000000000000000000000b6e8d29a8c5d0fcef149c5641e1eee004582d07e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6192,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067a0fe77d11bb228e4abc8303e11a70221ece23d00000000000000000000000067a0fe77d11bb228e4abc8303e11a70221ece23d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6193,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c40326ea38b5b7ad6f21b6d2725a736320b2b13a000000000000000000000000c40326ea38b5b7ad6f21b6d2725a736320b2b13a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af4c12f61ec66327b8230215ce76bb5d5d87ae41000000000000000000000000af4c12f61ec66327b8230215ce76bb5d5d87ae4100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6195,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f73d8cf6974c675e8fb695180eebb693a0c90f40000000000000000000000002f73d8cf6974c675e8fb695180eebb693a0c90f400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6196,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000594185ad7267edbc4d909660e36dae73642279ac000000000000000000000000594185ad7267edbc4d909660e36dae73642279ac00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6197,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c1828e25724846b84b75fe89d984464da43a3b50000000000000000000000004c1828e25724846b84b75fe89d984464da43a3b500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6198,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017c434152967287d37601a331c998f7569532d5800000000000000000000000017c434152967287d37601a331c998f7569532d5800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a3416da2690142c4d29833c3ccba07ad91fd2e50000000000000000000000004a3416da2690142c4d29833c3ccba07ad91fd2e500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6200,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007485416586bb2c820d8e17dc9f08e13d769dcb900000000000000000000000007485416586bb2c820d8e17dc9f08e13d769dcb9000000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6201,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010a262209be8c3e5293b4d2744c7591180b06fb500000000000000000000000010a262209be8c3e5293b4d2744c7591180b06fb500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6202,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa8c135316894210564b4bd6a62d711efffe6ab3000000000000000000000000aa8c135316894210564b4bd6a62d711efffe6ab300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6203,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c82309fb96679c4a246effb6cae82e4f5a503a90000000000000000000000005c82309fb96679c4a246effb6cae82e4f5a503a900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a3a97e9548c1d7b6b271586c3df7d598401195d0000000000000000000000007a3a97e9548c1d7b6b271586c3df7d598401195d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6205,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c16c6707c225bcfe6cb45d70c2c3b60fa1dd8684000000000000000000000000c16c6707c225bcfe6cb45d70c2c3b60fa1dd868400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000476cf12d3a58803a6396fa9d996b16bd5fd5bc97000000000000000000000000476cf12d3a58803a6396fa9d996b16bd5fd5bc9700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076d70b9f4d57b9a142402a10e6dd66d23434d66300000000000000000000000076d70b9f4d57b9a142402a10e6dd66d23434d66300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001300ad33bb8615e965d9ae24faefd917859c51690000000000000000000000001300ad33bb8615e965d9ae24faefd917859c516900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000534a350439c0d8ef6bd87dbd8ae87a98d7a19fee000000000000000000000000534a350439c0d8ef6bd87dbd8ae87a98d7a19fee00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000779a4fe40cd3d0e522e6acd979355bd13319d4eb000000000000000000000000779a4fe40cd3d0e522e6acd979355bd13319d4eb00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6211,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a259607466a7f8c233a90f8056c7c2b088e44a3b000000000000000000000000a259607466a7f8c233a90f8056c7c2b088e44a3b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6212,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b4074eacf0d93b51da37cf2fdb2b92a29f7a62b0000000000000000000000002b4074eacf0d93b51da37cf2fdb2b92a29f7a62b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6213,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd5743a88dbd7283c7b62969315737d0c09108b9000000000000000000000000cd5743a88dbd7283c7b62969315737d0c09108b900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6214,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c4162902791407e9c97f0d103cc7f18014e05000000000000000000000000006c4162902791407e9c97f0d103cc7f18014e050000000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e1339e1c320fba582437346f5f8f255ccc0298b0000000000000000000000001e1339e1c320fba582437346f5f8f255ccc0298b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6217,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086ab8050fa2dbf473b6b2b835eaeecf79fdb853a00000000000000000000000086ab8050fa2dbf473b6b2b835eaeecf79fdb853a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6e8f993e38a2080bfcf6059e0e53035cc6e4c70000000000000000000000000c6e8f993e38a2080bfcf6059e0e53035cc6e4c7000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5c45509af209bda85bba4eed08b8ee109ccdef7000000000000000000000000e5c45509af209bda85bba4eed08b8ee109ccdef700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6220,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fed459299bd99747cec1f0a5422a930aea38ff66000000000000000000000000fed459299bd99747cec1f0a5422a930aea38ff6600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000315bbdc92a1d5ac1d5cd72fcab68db625932b546000000000000000000000000315bbdc92a1d5ac1d5cd72fcab68db625932b54600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066b3ae9ce70bf1f8adf6164086881a9d3a59f79900000000000000000000000066b3ae9ce70bf1f8adf6164086881a9d3a59f79900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6223,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0b5dd11e6b7a32f72f20354cd28cfd525bf2610000000000000000000000000a0b5dd11e6b7a32f72f20354cd28cfd525bf26100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6224,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a252c6caff320a0a2349ec78f2eed5e5d6958e89000000000000000000000000a252c6caff320a0a2349ec78f2eed5e5d6958e8900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c5b16f1b8eefded06173ca6fce42a5b624043d40000000000000000000000000c5b16f1b8eefded06173ca6fce42a5b624043d400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6226,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbc44dd131bc2ab9e555cc4b43485874e10ec6eb000000000000000000000000cbc44dd131bc2ab9e555cc4b43485874e10ec6eb00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6227,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cefbf484039b2d4ea0bc018c1857170c7b1b481c000000000000000000000000cefbf484039b2d4ea0bc018c1857170c7b1b481c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6228,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aaa9722e144867288e390dee76b2ac90a703d233000000000000000000000000aaa9722e144867288e390dee76b2ac90a703d23300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6229,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049196ccd96632f3c2ed79e7ee02b22ce89860cd800000000000000000000000049196ccd96632f3c2ed79e7ee02b22ce89860cd800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6230,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009595cd099429cbd13327b2add9c9af1ac1495faf0000000000000000000000009595cd099429cbd13327b2add9c9af1ac1495faf00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6231,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082ceb6c9bde6f0d141da7c62374d4b8cfdde321200000000000000000000000082ceb6c9bde6f0d141da7c62374d4b8cfdde3212000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008286d5a11fe8737c80f52436ef58ae880b156db90000000000000000000000008286d5a11fe8737c80f52436ef58ae880b156db900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d78ee648e21f36ac5881b356f57605773efe1950000000000000000000000008d78ee648e21f36ac5881b356f57605773efe19500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003fcaaa3062b75ceb9a9a230310c71250e33835990000000000000000000000003fcaaa3062b75ceb9a9a230310c71250e338359900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f5c1d799431338c9266a20a31ebd7ff8565f9e40000000000000000000000006f5c1d799431338c9266a20a31ebd7ff8565f9e400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1b7bbf015f73bff3c8a8ef105c2d3d857d48186000000000000000000000000d1b7bbf015f73bff3c8a8ef105c2d3d857d4818600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6237,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c42662d950a9b86b37e992737edaf24ae1eefd52000000000000000000000000c42662d950a9b86b37e992737edaf24ae1eefd5200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c28c11326d22dd12cae0bac4442cf339c5b2a7b0000000000000000000000009c28c11326d22dd12cae0bac4442cf339c5b2a7b000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009238516001504cf6228e1e18f6f1d5c6dc3366b70000000000000000000000009238516001504cf6228e1e18f6f1d5c6dc3366b700000000000000000000000000000000000000000000000006e3a298ab351d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6241,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004369e98806b77c31fb8aaaf22fd99392d2ecd1f10000000000000000000000004369e98806b77c31fb8aaaf22fd99392d2ecd1f100000000000000000000000000000000000000000000000000fc4562136c383f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6242,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037c53c4146c9952e806ed05d358c55b6ee13a14d00000000000000000000000037c53c4146c9952e806ed05d358c55b6ee13a14d000000000000000000000000000000000000000000000000007a2f0ddd43fa0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c8af873ccf3379491750835130d1d81beecc9c30000000000000000000000003c8af873ccf3379491750835130d1d81beecc9c300000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e8215ff2db1ac1d023eee2040cb81f73fa4b8fb0000000000000000000000004e8215ff2db1ac1d023eee2040cb81f73fa4b8fb0000000000000000000000000000000000000000000000000005cf3606cecb4c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041f7fc9cd42e9559e1f73aaa2d06653bc815998d00000000000000000000000041f7fc9cd42e9559e1f73aaa2d06653bc815998d0000000000000000000000000000000000000000000000000039c01982d1f9a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6252,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016da895d3b3e77f25e6035c01981a7126f99f9da00000000000000000000000016da895d3b3e77f25e6035c01981a7126f99f9da00000000000000000000000000000000000000000000000000e6ed27d666800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xedefa5bd834783935fa51ac9a850177a1366b3338e4c9d80ad21ed6907d5d68d,2022-02-17 12:06:48.000 UTC,0,true +6253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df5758524fcb5f096a07830bc72a815f5701dbd4000000000000000000000000df5758524fcb5f096a07830bc72a815f5701dbd4000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ed688a91f3a1a466a719dfd933e32cdd69fe92a0000000000000000000000002ed688a91f3a1a466a719dfd933e32cdd69fe92a0000000000000000000000000000000000000000000000000017659cca426ec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6258,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000940214134c5e8d81dbd5e9015908c697dab5e0dd000000000000000000000000940214134c5e8d81dbd5e9015908c697dab5e0dd000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6260,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053a67719f7e50beb47e6cae7fbbb04cf65d2962600000000000000000000000053a67719f7e50beb47e6cae7fbbb04cf65d2962600000000000000000000000000000000000000000000000000babe8103e6a10d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6261,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000055f86e2214dadb7e364fba38c12fe44fff6870d20000000000000000000000000000000000000000000000008cfe9010eb30ec02,,,1,true +6262,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a889b33e317c507fc4a8d116b2a1884a65d6d90a000000000000000000000000a889b33e317c507fc4a8d116b2a1884a65d6d90a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087b61e7e1bf4cc3e9e6b40518ded79439924f9e200000000000000000000000087b61e7e1bf4cc3e9e6b40518ded79439924f9e2000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6264,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c78366cc2aa23ef0409bf13803b5cc6145fba0f5000000000000000000000000c78366cc2aa23ef0409bf13803b5cc6145fba0f5000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6266,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007af27b2ed937f738f6fa81048c8be89cf04991140000000000000000000000007af27b2ed937f738f6fa81048c8be89cf049911400000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020b99860d324741aabc4c208f5464060a08db84a00000000000000000000000020b99860d324741aabc4c208f5464060a08db84a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6270,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e910cc299f45787e5eca168085618fa44148a1e0000000000000000000000004e910cc299f45787e5eca168085618fa44148a1e00000000000000000000000000000000000000000000000001e8a3bbd098939800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6271,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009092164dcde75456862c7ac90c52120fa87094fb0000000000000000000000009092164dcde75456862c7ac90c52120fa87094fb000000000000000000000000000000000000000000000000005f74af10795c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6273,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a61c698fb2b2913c194ba98445a12338e3288440000000000000000000000005a61c698fb2b2913c194ba98445a12338e32884400000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d445d31483882576e8eda27b51491be77cbb69d4000000000000000000000000d445d31483882576e8eda27b51491be77cbb69d400000000000000000000000000000000000000000000000000987b6fea6e1f8b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba6ffaea3206d86e04dc1b2c029efcb99494549e000000000000000000000000ba6ffaea3206d86e04dc1b2c029efcb99494549e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0f770c3de2fff71850e35bee24be4f4ddcc9c59000000000000000000000000b0f770c3de2fff71850e35bee24be4f4ddcc9c5900000000000000000000000000000000000000000000000000628a6d33774ec400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6278,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030d84e2c44d2b66975d02ad194363324cd3dfb9b00000000000000000000000030d84e2c44d2b66975d02ad194363324cd3dfb9b0000000000000000000000000000000000000000000000000032af6a70f4850000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071628a735b74ba74d93fbbb14131c846c13d8eed00000000000000000000000071628a735b74ba74d93fbbb14131c846c13d8eed000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fb02812573f49cf965f1881878fa804ba7c63160000000000000000000000005fb02812573f49cf965f1881878fa804ba7c6316000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6283,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006810dba12317406828d64b07d34ad22338644bb30000000000000000000000006810dba12317406828d64b07d34ad22338644bb300000000000000000000000000000000000000000000000443172f0bfe46b9ee00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x19168165ce2657720a459f6931d9a24a8e86b1431b1401d6fc8d977edab49f68,2022-06-28 11:54:08.000 UTC,0,true +6285,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0552ba5df6da78e609e3af1f5e566e2b96f000b000000000000000000000000b0552ba5df6da78e609e3af1f5e566e2b96f000b000000000000000000000000000000000000000000000000002f82bfd2c5820100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024875e064103cf1f8f1a3f0951d07afb302256ad00000000000000000000000024875e064103cf1f8f1a3f0951d07afb302256ad000000000000000000000000000000000000000000000000015c24e75e36c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1d4e411895fdd35f25bfa0144df50110817a860743eb2d63c345aa5172eb4f42,2022-05-25 10:12:28.000 UTC,0,true +6287,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005678e3d553cc261b690126952ce58828add4b0380000000000000000000000005678e3d553cc261b690126952ce58828add4b038000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6288,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006810dba12317406828d64b07d34ad22338644bb30000000000000000000000006810dba12317406828d64b07d34ad22338644bb3000000000000000000000000000000000000000000000001314fb3706298000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xe8f0bf0df1d0e8b63c9a7cb97af3040fc3ddfa3453b71ac6971369e244ff0b8e,2022-07-23 04:30:41.000 UTC,0,true +6289,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003af22eadb1319617c8ab95c04d2ba96ca6728e050000000000000000000000003af22eadb1319617c8ab95c04d2ba96ca6728e0500000000000000000000000000000000000000000000000000d9b967236676d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f01a4acc32c5834786a3fe20a40dc8697fcb6b20000000000000000000000005f01a4acc32c5834786a3fe20a40dc8697fcb6b2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6292,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f22deebdf3eead96a0609f29c49ef7f9f652ade0000000000000000000000008f22deebdf3eead96a0609f29c49ef7f9f652ade000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d5e388b530864423b27d3394edffc9510bf5ed40000000000000000000000000d5e388b530864423b27d3394edffc9510bf5ed4000000000000000000000000000000000000000000000000009ad0531208b12e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6296,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e3a1d91c232d7e6887ae83bf99ac38e777fbcd90000000000000000000000005e3a1d91c232d7e6887ae83bf99ac38e777fbcd90000000000000000000000000000000000000000000000000040db0b9968f26200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6297,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ce58ec06f621fee629c5ea2e790a39924cc8e210000000000000000000000001ce58ec06f621fee629c5ea2e790a39924cc8e21000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb907d3b1d7db12314279a954dd8b5a86c0e86fc000000000000000000000000bb907d3b1d7db12314279a954dd8b5a86c0e86fc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6300,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000111b58c01afa72d04bc0adb523266aa55749ed92000000000000000000000000111b58c01afa72d04bc0adb523266aa55749ed920000000000000000000000000000000000000000000000000131f7e2cbb633b400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000beb3662c34c8be5172b32ef9d3012e5c7b8680c0000000000000000000000000beb3662c34c8be5172b32ef9d3012e5c7b8680c000000000000000000000000000000000000000000000000007a1fe160277000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6304,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000070b1e584456ad5d8dc8f7ad0b410374984e1e75200000000000000000000000000000000000000000000000039b6204432e90373,,,1,true +6305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f66945895001023cf1cf9ef36a361ad909ca9336000000000000000000000000f66945895001023cf1cf9ef36a361ad909ca9336000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6306,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4627cec6ea1c46963942c076f39746814b7aa9e000000000000000000000000f4627cec6ea1c46963942c076f39746814b7aa9e0000000000000000000000000000000000000000000000000062d2e8a6ebaae100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6308,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000662d9c83c75ec4c2622cb6a45a764eaa6e1be89b000000000000000000000000662d9c83c75ec4c2622cb6a45a764eaa6e1be89b00000000000000000000000000000000000000000000000000497d70d0430b0700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6309,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a64f54ca8af1eafbcb31fec17042fc05c10aa140000000000000000000000005a64f54ca8af1eafbcb31fec17042fc05c10aa140000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6310,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000648b7355aea321b558ed5609570c179e41751e26000000000000000000000000648b7355aea321b558ed5609570c179e41751e2600000000000000000000000000000000000000000000000001a072041bb64a8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x838fa964f5d78315fae8279605f8f5c80feeda481d80d97ef60a4b0b78267126,2021-12-08 16:08:28.000 UTC,0,true +6311,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022d2380f3d396fb9ffb3523f1d570138b404a4e200000000000000000000000022d2380f3d396fb9ffb3523f1d570138b404a4e200000000000000000000000000000000000000000000000000a204c415bec1b500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6312,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000546c35a376735dad1ada63b63550f4528853d32200000000000000000000000000000000000000000000000ad78ebc5ac6200000,,,1,true +6314,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa23be134c9bdfa8bda5ee6034b2083e09d8a4d9000000000000000000000000aa23be134c9bdfa8bda5ee6034b2083e09d8a4d90000000000000000000000000000000000000000000000000152afb15f65af3700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6315,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000700b81ebc4854cc92c0f8726384b8165379101c6000000000000000000000000700b81ebc4854cc92c0f8726384b8165379101c60000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6316,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d466900fea4c92cf0dc3dd354c2013b6037e734d000000000000000000000000d466900fea4c92cf0dc3dd354c2013b6037e734d000000000000000000000000000000000000000000000000004c5ab53cb0cad600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089a23f067054fcec705e64d4f4aac36ff0db6b2c00000000000000000000000089a23f067054fcec705e64d4f4aac36ff0db6b2c00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6322,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2d3c29bcf8b7db513fcb09937bb69de81475e05000000000000000000000000f2d3c29bcf8b7db513fcb09937bb69de81475e0500000000000000000000000000000000000000000000000000a34a257751602a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcf0fd9c42cc8cb2060c4930d2c1d277f18146a5000000000000000000000000bcf0fd9c42cc8cb2060c4930d2c1d277f18146a5000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6325,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060663af31be6fb5f4c89cc2cca07f0bf3b2cfa9400000000000000000000000060663af31be6fb5f4c89cc2cca07f0bf3b2cfa940000000000000000000000000000000000000000000000000042a0642a6f150000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6326,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f8ae64665c750207ac62203a29c70edc7f91784d000000000000000000000000000000000000000000000000226abadc42f80000,,,1,true +6328,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008a6838b8ce1e427892c0069e40c81ac3af1444fe00000000000000000000000000000000000000000000001ae2bf3612bb93a0f5,0x3f2733185c0c9552b8fcdb0096e6ddd4f30bdfbfffa4cf4fb7ede2c531a98adf,2021-11-26 07:02:24.000 UTC,0,true +6329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f34293b6f2617e676a25a6b823396c6e63de7980000000000000000000000002f34293b6f2617e676a25a6b823396c6e63de798000000000000000000000000000000000000000000000000006acf9437f14e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xccc621b60c73dd77808a99cecd16eeacdea0e480d560d0300252974e930f0556,2022-06-05 07:27:45.000 UTC,0,true +6331,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1a5b91957530e1b3e9cfac1543467c60c352f69000000000000000000000000d1a5b91957530e1b3e9cfac1543467c60c352f690000000000000000000000000000000000000000000000000029281dfd38090d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6332,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000aa87daf0dd4ecaa131d68d888a2a636c405393c0000000000000000000000000aa87daf0dd4ecaa131d68d888a2a636c405393c00000000000000000000000000000000000000000000000002ae3331f8143d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4b82c8a1e96caab53f631664ee54109ac953ff4080aff20c749c2b967b8b1fcc,2022-03-02 22:32:22.000 UTC,0,true +6333,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b840dfec84de16e0ad8143ae3536b1d592876228000000000000000000000000b840dfec84de16e0ad8143ae3536b1d59287622800000000000000000000000000000000000000000000000000a6abc3f786f1e600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6334,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8e856fd16c4e38e8ff7643aa1a7f1b5dfa9938c000000000000000000000000e8e856fd16c4e38e8ff7643aa1a7f1b5dfa9938c0000000000000000000000000000000000000000000000000018fc6c600eb19600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6335,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083381ee6b054a70226363aa4a98b8dfd7ce8aee000000000000000000000000083381ee6b054a70226363aa4a98b8dfd7ce8aee00000000000000000000000000000000000000000000000000001370c1483600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6336,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd2ff170381c1299550ddc2e142723c8fca7d685000000000000000000000000bd2ff170381c1299550ddc2e142723c8fca7d6850000000000000000000000000000000000000000000000000001370c1483600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6337,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dfdeb82e4893a7357dc941fcc5cdb8b1a2d08915000000000000000000000000dfdeb82e4893a7357dc941fcc5cdb8b1a2d089150000000000000000000000000000000000000000000000000001373aa571300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6338,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000818c4df073ec43b80fd6e3bdd451382a390d0466000000000000000000000000000000000000000000000000a2a632f9d1e30b3a,,,1,true +6339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052d2ee31368104138d5fe98effd7ce8f5558d37300000000000000000000000052d2ee31368104138d5fe98effd7ce8f5558d3730000000000000000000000000000000000000000000000000001370e688f440000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c641582d9eb6c40b2b07f3848b917e686c3fe49b000000000000000000000000c641582d9eb6c40b2b07f3848b917e686c3fe49b0000000000000000000000000000000000000000000000000001370ea42a0e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6341,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009eb4eb18cf1d8a8451fe062d914d81c5bf9ce1e30000000000000000000000009eb4eb18cf1d8a8451fe062d914d81c5bf9ce1e300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6342,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ba5d980d983164803d1a9f90485f6ef1cebe9480000000000000000000000003ba5d980d983164803d1a9f90485f6ef1cebe9480000000000000000000000000000000000000000000000000001370fce30000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6343,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9dc1ea1b25a752cc4882f7b5fdf3aa53cc32ebe000000000000000000000000f9dc1ea1b25a752cc4882f7b5fdf3aa53cc32ebe00000000000000000000000000000000000000000000000000714a0420d4132200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6344,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c62fedcc778e49daf606416ead602e40a002dec1000000000000000000000000c62fedcc778e49daf606416ead602e40a002dec10000000000000000000000000000000000000000000000000001370eaa1fef0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000824e79aabb599a969d07ef67391c33ceb39ac800000000000000000000000000824e79aabb599a969d07ef67391c33ceb39ac800000000000000000000000000000000000000000000000000044a7d1b245773a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6347,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000923c0d5dbb0be64eac9c79a7781762b4395f17ce000000000000000000000000923c0d5dbb0be64eac9c79a7781762b4395f17ce00000000000000000000000000000000000000000000000000044364c5bb000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6348,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004598a3b9f8e61e5cf6b4f50cda88b0666bba23d40000000000000000000000004598a3b9f8e61e5cf6b4f50cda88b0666bba23d4000000000000000000000000000000000000000000000000000d3c3dbb67010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081069f658da5fac80bbeee0023a21f0531d144dc00000000000000000000000081069f658da5fac80bbeee0023a21f0531d144dc00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6350,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6726399a01376f1dc6e5b81adf6d41c19de0cc1000000000000000000000000c6726399a01376f1dc6e5b81adf6d41c19de0cc10000000000000000000000000000000000000000000000000051b660cdd5800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000001558c24d917026f552dc74dbd7202485795680df0000000000000000000000001558c24d917026f552dc74dbd7202485795680df000000000000000000000000000000000000000000000000000000000100ed7d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +6352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001558c24d917026f552dc74dbd7202485795680df0000000000000000000000001558c24d917026f552dc74dbd7202485795680df000000000000000000000000000000000000000000000000002258044a403e4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2bca9a3911dbdd6968fbf0bdbf22bb750aa4ed7000000000000000000000000a2bca9a3911dbdd6968fbf0bdbf22bb750aa4ed7000000000000000000000000000000000000000000000000000c6f3b40b6c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6354,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bc51aefc2eccc5916825f96bfe0215b7626c1a40000000000000000000000006bc51aefc2eccc5916825f96bfe0215b7626c1a4000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6356,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002bc57482492d63420c29fa88e6654e2b42769f690000000000000000000000002bc57482492d63420c29fa88e6654e2b42769f690000000000000000000000000000000000000000000000000007ec1d64d71ac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6357,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000764b908d96fcff7df8792e66a9c43c0014e3df3e000000000000000000000000764b908d96fcff7df8792e66a9c43c0014e3df3e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6358,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a432b8023270db100a316ebf47871733df263d10000000000000000000000001a432b8023270db100a316ebf47871733df263d10000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6359,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fc4aa1af42db84b5befcdef7a7618a3a59e108e0000000000000000000000004fc4aa1af42db84b5befcdef7a7618a3a59e108e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f198c77d9c968840995e0172a003388d4aa02352000000000000000000000000f198c77d9c968840995e0172a003388d4aa0235200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6361,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f11556dc1c53440c769b33542fd1ca0c373ca28b000000000000000000000000f11556dc1c53440c769b33542fd1ca0c373ca28b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6362,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f1a3f4f7dfacf318a7c7a6a9773add3c9ff82f60000000000000000000000002f1a3f4f7dfacf318a7c7a6a9773add3c9ff82f60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055f0c1e1c64d656bdc369e50a7935eb4417b3eb600000000000000000000000055f0c1e1c64d656bdc369e50a7935eb4417b3eb60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2966908f05b065d7006c25d91f991b3260c9250000000000000000000000000a2966908f05b065d7006c25d91f991b3260c92500000000000000000000000000000000000000000000000000066543a9944a5ba00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6366,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f820c77a87d0c29b2fc0127d4043c3ac12f7a3c3000000000000000000000000f820c77a87d0c29b2fc0127d4043c3ac12f7a3c300000000000000000000000000000000000000000000000000044364c5bb000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af423790163935a517b229019088c0388ad24551000000000000000000000000af423790163935a517b229019088c0388ad245510000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d72dd704147ac65e0ade2a030088329396d27615000000000000000000000000d72dd704147ac65e0ade2a030088329396d276150000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088c7de054c28e03deb4c6feb393b40b08780150100000000000000000000000088c7de054c28e03deb4c6feb393b40b0878015010000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a713b2af2c6a1452c0c87b742f97700560fc6eca000000000000000000000000a713b2af2c6a1452c0c87b742f97700560fc6eca0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6373,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003aa2f6138599a7d22b742881b77c78c07bd549030000000000000000000000003aa2f6138599a7d22b742881b77c78c07bd549030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bd166035bb746ff5c2bc190ed615e5761e2ad310000000000000000000000005bd166035bb746ff5c2bc190ed615e5761e2ad3100000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6375,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2991ccb1dd1d9f10a5d4bcbdade6a97289b5e5e000000000000000000000000e2991ccb1dd1d9f10a5d4bcbdade6a97289b5e5e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4dceb958f0e2472811ab21669712f63ac6e9ee9000000000000000000000000b4dceb958f0e2472811ab21669712f63ac6e9ee90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007030b4b422546c60b4e77896344c781f116c43200000000000000000000000007030b4b422546c60b4e77896344c781f116c43200000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6378,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010e08067623e27fba375b9dabf5e8366da6bc06d00000000000000000000000010e08067623e27fba375b9dabf5e8366da6bc06d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6379,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcacd4ed1f378163d15101d8f20900b1c4d9662e000000000000000000000000fcacd4ed1f378163d15101d8f20900b1c4d9662e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6380,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032cce025af9e68044937c2377d403a72013ea44e00000000000000000000000032cce025af9e68044937c2377d403a72013ea44e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6381,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae60140b46282c9caca0fe3241447b63b884a2f2000000000000000000000000ae60140b46282c9caca0fe3241447b63b884a2f20000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6382,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb446eeb0453d24b012910336dc4170063a8d130000000000000000000000000bb446eeb0453d24b012910336dc4170063a8d1300000000000000000000000000000000000000000000000000020e57016d196eb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6ec2a147ed598ab72d1578f92a400ca99a46260000000000000000000000000b6ec2a147ed598ab72d1578f92a400ca99a46260000000000000000000000000000000000000000000000000013a9396d78af54700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d62865a54e3fc57c43a1c7401e2499f241ba6450000000000000000000000001d62865a54e3fc57c43a1c7401e2499f241ba6450000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6385,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc2b2e250e315c8d024b14cd5503131ae7c8ecc5000000000000000000000000dc2b2e250e315c8d024b14cd5503131ae7c8ecc50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006daf6dc3c8aa3ee860478645205b5f9d6397616d0000000000000000000000006daf6dc3c8aa3ee860478645205b5f9d6397616d00000000000000000000000000000000000000000000000000049e57d635400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008bf8ef0a3cd17245300936ab8069bce536f7d6c60000000000000000000000008bf8ef0a3cd17245300936ab8069bce536f7d6c60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016d3529382e60edd749942589771c579a72c479500000000000000000000000016d3529382e60edd749942589771c579a72c47950000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6389,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a4474516897af9015887f6f784c865b7922cf800000000000000000000000000a4474516897af9015887f6f784c865b7922cf800000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6391,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035b92fd72c499ece40298df93fa9552f08f9373f00000000000000000000000035b92fd72c499ece40298df93fa9552f08f9373f0000000000000000000000000000000000000000000000000019ef4fb2dc400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7e01621c46b43d030949e474348c2b835c3de84000000000000000000000000e7e01621c46b43d030949e474348c2b835c3de840000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a816876f1750d88636c678240c5ab049e851e3b0000000000000000000000002a816876f1750d88636c678240c5ab049e851e3b000000000000000000000000000000000000000000000000003ff2e795f5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001faeb47d071f796dc9ce31b0212efa31fe65ea110000000000000000000000001faeb47d071f796dc9ce31b0212efa31fe65ea110000000000000000000000000000000000000000000000000039ed2ca295c20a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008aa40f0bf095a7974396b55ca8056d2892efda610000000000000000000000008aa40f0bf095a7974396b55ca8056d2892efda6100000000000000000000000000000000000000000000000000063dba24d5de6a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059636a3198c7718037c8f4e47ff476a997611e8000000000000000000000000059636a3198c7718037c8f4e47ff476a997611e80000000000000000000000000000000000000000000000000005ba9e844fff8f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6397,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9373046a064c700f27c878cf881f31dc07ebff2000000000000000000000000f9373046a064c700f27c878cf881f31dc07ebff20000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075de74801c5c9771bec4c5695f917cf3b951ba4100000000000000000000000075de74801c5c9771bec4c5695f917cf3b951ba410000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cf968f202abb9f97063c5ce1a0ed07ff2f3e6280000000000000000000000005cf968f202abb9f97063c5ce1a0ed07ff2f3e6280000000000000000000000000000000000000000000000000013305ca623f00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c57598b68719641dbe3bc5eb9edbf5fcf14193cd000000000000000000000000c57598b68719641dbe3bc5eb9edbf5fcf14193cd00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009cd57ab451145a5705dcd0a0e5608cd309c36ac00000000000000000000000009cd57ab451145a5705dcd0a0e5608cd309c36ac00000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6402,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddddb71d309c54f0838e1d48faeef2634c197fb6000000000000000000000000ddddb71d309c54f0838e1d48faeef2634c197fb6000000000000000000000000000000000000000000000000001ad7b431d3d66900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085046ee159fbde94eed825855638c173b450a11c00000000000000000000000085046ee159fbde94eed825855638c173b450a11c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4d43e87d85fec5339e8517fb677b6884c8895c4000000000000000000000000c4d43e87d85fec5339e8517fb677b6884c8895c40000000000000000000000000000000000000000000000000214e8348c4f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024926a489189fc1475541149d45c1c8872246fef00000000000000000000000024926a489189fc1475541149d45c1c8872246fef000000000000000000000000000000000000000000000000023fc04fe2804a1c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b00d522543e1530dc5f9eccced7e055a877231ae000000000000000000000000b00d522543e1530dc5f9eccced7e055a877231ae0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3d2939eb7e59daaa7e11f1d31057f86164e8b98000000000000000000000000a3d2939eb7e59daaa7e11f1d31057f86164e8b980000000000000000000000000000000000000000000000000021e3d105c88c8e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f1c877774262fc6d467f626d077d2fbb276f9680000000000000000000000000f1c877774262fc6d467f626d077d2fbb276f9680000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003796a49560f4ec38cae0c451fbc8f1ec33649fa10000000000000000000000003796a49560f4ec38cae0c451fbc8f1ec33649fa1000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000414e4df902397f3f459cf59d2ca778e4d6230ab6000000000000000000000000414e4df902397f3f459cf59d2ca778e4d6230ab60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6413,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091f4202fcc0521c745a44c3097650c0757c5291400000000000000000000000091f4202fcc0521c745a44c3097650c0757c529140000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6415,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005adfd3ea26e023098903bbcbe9a0cb3361446e5c0000000000000000000000005adfd3ea26e023098903bbcbe9a0cb3361446e5c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d595547a6cf1d082b0f342f4827c1360125a70c0000000000000000000000008d595547a6cf1d082b0f342f4827c1360125a70c000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3f49f97a71b0dde68e40653c938ed8697fc7841000000000000000000000000c3f49f97a71b0dde68e40653c938ed8697fc78410000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6418,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059a62f8bd4a72417a762fef9104c11e92e1205dc00000000000000000000000059a62f8bd4a72417a762fef9104c11e92e1205dc0000000000000000000000000000000000000000000000000038c0d61369504000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c30bec87bead77c71942e89600d8f669d76a56a7000000000000000000000000c30bec87bead77c71942e89600d8f669d76a56a700000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ff73618c2029909ae2d62e6dc05eec8b64bd39c0000000000000000000000000ff73618c2029909ae2d62e6dc05eec8b64bd39c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059a62f8bd4a72417a762fef9104c11e92e1205dc00000000000000000000000059a62f8bd4a72417a762fef9104c11e92e1205dc0000000000000000000000000000000000000000000000000016e4739dfa5c5a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055ba7f8c5ea45109bfdef64b101c5da25c5ac6a800000000000000000000000055ba7f8c5ea45109bfdef64b101c5da25c5ac6a80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6423,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fdb7bd4f6f301e132e93457943ecb93be79399d0000000000000000000000004fdb7bd4f6f301e132e93457943ecb93be79399d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aaad594018955dee2541465ea2fdda1777026fc7000000000000000000000000aaad594018955dee2541465ea2fdda1777026fc70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6425,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c2d8da83b4cf891db819cbcda16ccf42dbeb9030000000000000000000000001c2d8da83b4cf891db819cbcda16ccf42dbeb9030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6426,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6632c27d31499f4490462bcfe623b24b8dff8db000000000000000000000000b6632c27d31499f4490462bcfe623b24b8dff8db0000000000000000000000000000000000000000000000000099def4160021ee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6427,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000063d937ed6dec82f33141f89026a8d15eb2d6520000000000000000000000000063d937ed6dec82f33141f89026a8d15eb2d6520000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003414b9ce85a5c17c16226c018ffa712b997e27110000000000000000000000003414b9ce85a5c17c16226c018ffa712b997e2711000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e86ffe5ecd8b6da1796d2737dee86d9ad585f76f000000000000000000000000e86ffe5ecd8b6da1796d2737dee86d9ad585f76f0000000000000000000000000000000000000000000000000098a3d1c2ad9e7e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008cefa30ccaddd6228c0bd93aa67e0945546d29540000000000000000000000008cefa30ccaddd6228c0bd93aa67e0945546d29540000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003bc8a01e685eb5277e57f5081f7704f2a061a0a90000000000000000000000003bc8a01e685eb5277e57f5081f7704f2a061a0a90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cccd945857e6f70e9249e6e9509fe8ab3f4d9feb000000000000000000000000cccd945857e6f70e9249e6e9509fe8ab3f4d9feb0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6435,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052b24e9f816f9d0121fa47e545b86e0f74a872ee00000000000000000000000052b24e9f816f9d0121fa47e545b86e0f74a872ee0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006db8a50c879f17da3d6d3c94ab99aec3e21229940000000000000000000000006db8a50c879f17da3d6d3c94ab99aec3e21229940000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b25c6474f6e10e9c9930a36c32fb29e6243c3a19000000000000000000000000b25c6474f6e10e9c9930a36c32fb29e6243c3a190000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6438,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000f5f6eb014093902d9367517e23c4b418d9becd6a000000000000000000000000f5f6eb014093902d9367517e23c4b418d9becd6a0000000000000000000000000000000000000000000000000000000001ee1eb800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +6439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c4a55dbc592555f8c96d520054cb52e90e29bb20000000000000000000000006c4a55dbc592555f8c96d520054cb52e90e29bb20000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086f5ee2ada23227d8b75791c64c32a467b566e5600000000000000000000000086f5ee2ada23227d8b75791c64c32a467b566e560000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6441,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e35ed5fc914da2e02f79dc8ee80f7fce750d0080000000000000000000000006e35ed5fc914da2e02f79dc8ee80f7fce750d008000000000000000000000000000000000000000000000000004a407073ce400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000427c6de41db0619a101dd5323463ed4d82ee822e000000000000000000000000427c6de41db0619a101dd5323463ed4d82ee822e000000000000000000000000000000000000000000000000006740af99069f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000becf8bb57afd39baca320b1177bf23dc53f2fe30000000000000000000000000becf8bb57afd39baca320b1177bf23dc53f2fe3000000000000000000000000000000000000000000000000000deca9399e5875f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e235a100b610f1bbf27f6cf826828bccfdb45e55000000000000000000000000e235a100b610f1bbf27f6cf826828bccfdb45e5500000000000000000000000000000000000000000000000000619f19428d7faf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a273f8eb3f4203e3058b5c6bc4d459dcbc3557c8000000000000000000000000a273f8eb3f4203e3058b5c6bc4d459dcbc3557c8000000000000000000000000000000000000000000000000008bf959f55bae0c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e892622181587805df303338a43759d20ba13500000000000000000000000004e892622181587805df303338a43759d20ba135000000000000000000000000000000000000000000000000000a6c2c0be7808b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7d1323199e48e20c43db56f5f082e4fa88b3ec5000000000000000000000000a7d1323199e48e20c43db56f5f082e4fa88b3ec50000000000000000000000000000000000000000000000000043aaea9a92e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad1e365152589d3501340af5c004bfa1ef0d724a000000000000000000000000ad1e365152589d3501340af5c004bfa1ef0d724a0000000000000000000000000000000000000000000000000354a6ba7a18000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000422fc6d98bfc720be3b9c594a324dbdce79c9967000000000000000000000000422fc6d98bfc720be3b9c594a324dbdce79c9967000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6453,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a51d52ea55af256e2cd323c44839ec4ad7809edd000000000000000000000000a51d52ea55af256e2cd323c44839ec4ad7809edd0000000000000000000000000000000000000000000000000029e0884c47f71d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6455,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c8e8dc76b61d473a59373d05f64e6272ef481420000000000000000000000007c8e8dc76b61d473a59373d05f64e6272ef481420000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b62b3f714036e8d973109f55727e6f9da416513e000000000000000000000000b62b3f714036e8d973109f55727e6f9da416513e0000000000000000000000000000000000000000000000000005455b3469dd6c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047fa565d61fd4d97b93b3d6dd559d97c321fecd800000000000000000000000047fa565d61fd4d97b93b3d6dd559d97c321fecd80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c821da8f59947715030e0a0c301719b77fbe6be9000000000000000000000000c821da8f59947715030e0a0c301719b77fbe6be900000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090e796ca6ab5fda3692eb327038d540f07ded70000000000000000000000000090e796ca6ab5fda3692eb327038d540f07ded7000000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6461,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a030931e0df303c601f743c8b73f12ba15b3bd80000000000000000000000008a030931e0df303c601f743c8b73f12ba15b3bd800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003fbbf87d84733e70c54e93b669d3e4c4716432800000000000000000000000003fbbf87d84733e70c54e93b669d3e4c471643280000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055be352901e49213f5467d55c1383ef888da6bbf00000000000000000000000055be352901e49213f5467d55c1383ef888da6bbf0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dfbc8fea29cec36cad1fee29c2ddf176d4810063000000000000000000000000dfbc8fea29cec36cad1fee29c2ddf176d48100630000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6ce241b44b26286d4c3d7c13b9fece7b4ce159b000000000000000000000000b6ce241b44b26286d4c3d7c13b9fece7b4ce159b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008002323f8b78fb24b65edb5563025278611593fa0000000000000000000000008002323f8b78fb24b65edb5563025278611593fa0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6468,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb390ea6f867bbfe6aa709c05edc7cd948ba5707000000000000000000000000fb390ea6f867bbfe6aa709c05edc7cd948ba57070000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd81320bfa0105241fcf099541802fc4fd396aca000000000000000000000000cd81320bfa0105241fcf099541802fc4fd396aca0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030be19e4887663efa1d153205d7df97b35d81d7900000000000000000000000030be19e4887663efa1d153205d7df97b35d81d790000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4c2444cd28c052b140c94957b19b616335775e2000000000000000000000000f4c2444cd28c052b140c94957b19b616335775e2000000000000000000000000000000000000000000000000001e857fc020420000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064d8a22881fdb8984737f4c4760cd256e126f7ea00000000000000000000000064d8a22881fdb8984737f4c4760cd256e126f7ea000000000000000000000000000000000000000000000000003a585005f155ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000473dff3f18d2b44e98129b7b1ef6f5a7d28b5270000000000000000000000000473dff3f18d2b44e98129b7b1ef6f5a7d28b527000000000000000000000000000000000000000000000000000a24ebf1c816f3b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000cdd02d15521f7a7fbb4e5d6d0cbab90a29463730000000000000000000000000cdd02d15521f7a7fbb4e5d6d0cbab90a2946373000000000000000000000000000000000000000000000000015e421082e9cd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5614db57a4e24bee825e08a03e41af281273fef000000000000000000000000c5614db57a4e24bee825e08a03e41af281273fef000000000000000000000000000000000000000000000000001791157627b6c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec643cc2bd8ee525f1784c6505d60b8d9452bf9b000000000000000000000000ec643cc2bd8ee525f1784c6505d60b8d9452bf9b0000000000000000000000000000000000000000000000000003b0910c86334000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6477,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000381af25e0264eaa2233d0c8d69bdd40cfe60e833000000000000000000000000381af25e0264eaa2233d0c8d69bdd40cfe60e8330000000000000000000000000000000000000000000000000024bd01f873541000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6479,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000039f22efb07a647557c7c5d17854cfd6d489ef30000000000000000000000000039f22efb07a647557c7c5d17854cfd6d489ef300000000000000000000000000000000000000000000000006e7dc258e0028e200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6480,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000063d80caa6d0ea78f9a502c9c2c8b5079a666d60000000000000000000000000063d80caa6d0ea78f9a502c9c2c8b5079a666d600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ecfe3326223df6f99f6527213222af3fabba93e7000000000000000000000000ecfe3326223df6f99f6527213222af3fabba93e70000000000000000000000000000000000000000000000000001599ba503c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6483,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077fab6facc647806593c3e670058fc13699da5da00000000000000000000000077fab6facc647806593c3e670058fc13699da5da000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6484,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000360751b3b6d58a63b24709694de5169136016281000000000000000000000000360751b3b6d58a63b24709694de516913601628100000000000000000000000000000000000000000000000002483e1dcdbe7d1500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b4e927fcef617a7e6c92fae48bc1b3d956bd8c50000000000000000000000008b4e927fcef617a7e6c92fae48bc1b3d956bd8c50000000000000000000000000000000000000000000000000006cbe25efe853400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6486,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055ed55e77fd107829bc3bc3bde78ed2d0598d11e00000000000000000000000055ed55e77fd107829bc3bc3bde78ed2d0598d11e000000000000000000000000000000000000000000000000001a766dacdc374c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6487,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae2ec43d0c061cede6cbeb4157e6a3d67acf780a000000000000000000000000ae2ec43d0c061cede6cbeb4157e6a3d67acf780a00000000000000000000000000000000000000000000000001feb4211821a82900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6488,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0081e6380af5d61da4a4d17e7532c123c70ad38000000000000000000000000c0081e6380af5d61da4a4d17e7532c123c70ad3800000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a72c4275919b54401c9665ae6e4ea070c50c9230000000000000000000000009a72c4275919b54401c9665ae6e4ea070c50c923000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048d540daa0a0da768b6ace1a0981968e179b207b00000000000000000000000048d540daa0a0da768b6ace1a0981968e179b207b0000000000000000000000000000000000000000000000000059f8602e70abb000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000bdab303ff2a5804065970d1b750895d834a57710000000000000000000000000bdab303ff2a5804065970d1b750895d834a577100000000000000000000000000000000000000000000000000068ab7b8087e0100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003997e11f8e25b96e8d4e9d72d2ce1d22dd962bfb0000000000000000000000003997e11f8e25b96e8d4e9d72d2ce1d22dd962bfb0000000000000000000000000000000000000000000000000005a53ceda36b3c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007f9186026deaa14e242a1f209b3f85be99c27d500000000000000000000000007f9186026deaa14e242a1f209b3f85be99c27d500000000000000000000000000000000000000000000000000091100e5f458ce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5db0328428f9980b9d3dad9ee8606dfbaa54085000000000000000000000000d5db0328428f9980b9d3dad9ee8606dfbaa540850000000000000000000000000000000000000000000000000081dd9430b17ee000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6497,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e0619f4301f6b8f013fc603574bc52484296c2b0000000000000000000000003e0619f4301f6b8f013fc603574bc52484296c2b0000000000000000000000000000000000000000000000000470de4df820000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x98d4f947a1855c63c04f83fb96820cc9eb5d2a19de2461450ef4826b5c68d9e3,2022-05-29 05:50:13.000 UTC,0,true +6498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0081e6380af5d61da4a4d17e7532c123c70ad38000000000000000000000000c0081e6380af5d61da4a4d17e7532c123c70ad38000000000000000000000000000000000000000000000000014af4c48c7050fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6500,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a71cabc14966c6fae86c05630a20ba1c90944a1f000000000000000000000000000000000000000000000000cadf5fa1648ec4cb,,,1,true +6502,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc83d4d0356f65da131cad32ddee510ffbe299c9000000000000000000000000bc83d4d0356f65da131cad32ddee510ffbe299c900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6503,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd37d23fb161f96efef5f7463abaf5b63169caa4000000000000000000000000cd37d23fb161f96efef5f7463abaf5b63169caa4000000000000000000000000000000000000000000000000000307269dbf415800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b876ec1045badcb845acfd6f5182f200af6a0861000000000000000000000000b876ec1045badcb845acfd6f5182f200af6a086100000000000000000000000000000000000000000000000000a47e6b89de3d5800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007efcaa576e55449a1645b1f493436fc0959e78c60000000000000000000000007efcaa576e55449a1645b1f493436fc0959e78c600000000000000000000000000000000000000000000000001f69013913835e600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004bbb7ea18ea570ae47d4489991645e4e49bbf3700000000000000000000000004bbb7ea18ea570ae47d4489991645e4e49bbf3700000000000000000000000000000000000000000000000008b41a36c41b5ec800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6507,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9e8029395c758e1359bd6308e8c2b85907658c9000000000000000000000000b9e8029395c758e1359bd6308e8c2b85907658c90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6508,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014150988c18b8ca4b9d91b0b064a228e83b91a4d00000000000000000000000014150988c18b8ca4b9d91b0b064a228e83b91a4d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6509,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000176537296f7b527e00c61f6f303e8ca1b4d34125000000000000000000000000176537296f7b527e00c61f6f303e8ca1b4d341250000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae5defa9e0e94b461029b09c3bd500f9cb1be1ae000000000000000000000000ae5defa9e0e94b461029b09c3bd500f9cb1be1ae0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6511,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8a3eb612c36858955939579c920329c8c93b081000000000000000000000000b8a3eb612c36858955939579c920329c8c93b0810000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6512,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1a3826ea3270facd57ded4aeda05966bb72cc4b000000000000000000000000b1a3826ea3270facd57ded4aeda05966bb72cc4b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6513,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064aec6d32fb6a4bf80347fa7e38fd3504c83cecc00000000000000000000000064aec6d32fb6a4bf80347fa7e38fd3504c83cecc0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6514,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd37ef933d0aa9c260dd4b24bae16d2fe1387fb8000000000000000000000000cd37ef933d0aa9c260dd4b24bae16d2fe1387fb800000000000000000000000000000000000000000000000000499a5fc88afb4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c86628b4170652db03ea1e67762deaa156ec1df6000000000000000000000000c86628b4170652db03ea1e67762deaa156ec1df600000000000000000000000000000000000000000000000000092e6ed2935d5400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045627772199e4a1d89cd345d93ee52763d85bee800000000000000000000000045627772199e4a1d89cd345d93ee52763d85bee80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1166aa914487997a72227ee5f1fc346deb31ad4000000000000000000000000c1166aa914487997a72227ee5f1fc346deb31ad40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6520,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef92dc32c64ac6c96e5bd1d6fd3f2f5bbc6f7552000000000000000000000000ef92dc32c64ac6c96e5bd1d6fd3f2f5bbc6f75520000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6522,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b0f66f556208c7ecce91002b983aa310c87f31f0000000000000000000000003b0f66f556208c7ecce91002b983aa310c87f31f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6523,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ac830c73b295bdc178b0d337db55e7cf141c7850000000000000000000000003ac830c73b295bdc178b0d337db55e7cf141c7850000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6524,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094862c5241d46251f1e3fac1d2c5ea7f93ba0de200000000000000000000000094862c5241d46251f1e3fac1d2c5ea7f93ba0de20000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6525,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa16ad6d01c0a67cfdf933a64f320c221abbcf97000000000000000000000000aa16ad6d01c0a67cfdf933a64f320c221abbcf970000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6526,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9fb3cebf326388bd6f9bc374a035cbd8a4dc000000000000000000000000000e9fb3cebf326388bd6f9bc374a035cbd8a4dc0000000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6527,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078fcc9ed722de1bc459ce108102f3e25b1c3255600000000000000000000000078fcc9ed722de1bc459ce108102f3e25b1c325560000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dce8344556e362016cb5981dd22dfe8021a271e2000000000000000000000000dce8344556e362016cb5981dd22dfe8021a271e200000000000000000000000000000000000000000000000001ff90b365edef2100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b404acbf9a5408f15952497dd596308b646c2cb0000000000000000000000001b404acbf9a5408f15952497dd596308b646c2cb0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6530,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d0511b8785d6f1161d917b1c9057f61a21e753e0000000000000000000000005d0511b8785d6f1161d917b1c9057f61a21e753e000000000000000000000000000000000000000000000000000e864054c2550000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7a8aac126dbbc027c1b6c745e819827b519215b000000000000000000000000d7a8aac126dbbc027c1b6c745e819827b519215b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6532,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048cca6555b1f7119e01f3a534a2ddd7b3d14a9b800000000000000000000000048cca6555b1f7119e01f3a534a2ddd7b3d14a9b80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000208e47293cff4e85dce018ae704948049083a550000000000000000000000000208e47293cff4e85dce018ae704948049083a5500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6534,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000634c994e9f1945016d90d30d540971fade8b26f8000000000000000000000000634c994e9f1945016d90d30d540971fade8b26f8000000000000000000000000000000000000000000000000001fd24e4dc3f40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000208e47293cff4e85dce018ae704948049083a550000000000000000000000000208e47293cff4e85dce018ae704948049083a5500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000446aceb97d5191ba737c48879a70fe8b397a5f58000000000000000000000000446aceb97d5191ba737c48879a70fe8b397a5f580000000000000000000000000000000000000000000000000001f42adc5218b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a281527a3d9521fcb1aba3738ad694c9cb4f17d0000000000000000000000002a281527a3d9521fcb1aba3738ad694c9cb4f17d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008940715d8501f1a29268ed7082fda356aec0f2170000000000000000000000008940715d8501f1a29268ed7082fda356aec0f2170000000000000000000000000000000000000000000000000024be9eb62b880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6539,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c8f98a42499a960c36388c3423b375f9330589f0000000000000000000000007c8f98a42499a960c36388c3423b375f9330589f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000189f88a82cb02a0299f8017cdd23183bb7422a0d000000000000000000000000189f88a82cb02a0299f8017cdd23183bb7422a0d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000211c370b256f83f67f1c95a7a71da623cea02fa9000000000000000000000000211c370b256f83f67f1c95a7a71da623cea02fa9000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6542,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d3c2ededebfabf6b29e2aeba4ce82a4bf99d1082000000000000000000000000d3c2ededebfabf6b29e2aeba4ce82a4bf99d1082000000000000000000000000000000000000000000000000000000000118e01a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +6543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085d2d1d094ffbd688d8bcb7034a336902fcea93400000000000000000000000085d2d1d094ffbd688d8bcb7034a336902fcea9340000000000000000000000000000000000000000000000000003e871b540c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ce827705e7c4f67169dadd925a05f097af35d450000000000000000000000007ce827705e7c4f67169dadd925a05f097af35d4500000000000000000000000000000000000000000000000000753d533d96800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6545,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071231c3aee4a32cd2344f70d5e3ef8245c8a5fcf00000000000000000000000071231c3aee4a32cd2344f70d5e3ef8245c8a5fcf0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6546,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004dbfda2864b5ccdbea5b30419d1778e42bb6cc660000000000000000000000004dbfda2864b5ccdbea5b30419d1778e42bb6cc660000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b1f457238c422d97d231ac10137aafd4b9a37030000000000000000000000001b1f457238c422d97d231ac10137aafd4b9a37030000000000000000000000000000000000000000000000000027a8bb138bdf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6548,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8beec2b0facca7be0f25a2468a06ddea9f9bfe2000000000000000000000000e8beec2b0facca7be0f25a2468a06ddea9f9bfe20000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003883694454d4afa41b30e8bcf2c1810139d7348e0000000000000000000000003883694454d4afa41b30e8bcf2c1810139d7348e0000000000000000000000000000000000000000000000000026b248f4f39b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6550,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000916766e8259e05eb941abcdecb3dc79aa72e16cc000000000000000000000000916766e8259e05eb941abcdecb3dc79aa72e16cc00000000000000000000000000000000000000000000000000234227d524f60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059ba2fd919585cf0620518f7691b044303c0f6df00000000000000000000000059ba2fd919585cf0620518f7691b044303c0f6df0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000846dc401933c01742242a1a515ee2843af41ec8e000000000000000000000000846dc401933c01742242a1a515ee2843af41ec8e000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddd6578efdf7a516dc13487d38720947bb225da6000000000000000000000000ddd6578efdf7a516dc13487d38720947bb225da600000000000000000000000000000000000000000000000000234227d524f60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1a004a8c2a462f057c7e83dcced62fb48eb6fc0000000000000000000000000f1a004a8c2a462f057c7e83dcced62fb48eb6fc00000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d23bc8da7fb9fa49af7d74db3328e7970452a280000000000000000000000007d23bc8da7fb9fa49af7d74db3328e7970452a280000000000000000000000000000000000000000000000000026d10c740fa50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc73d43cd1553d512d631206fc90696651964c4a000000000000000000000000bc73d43cd1553d512d631206fc90696651964c4a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c718d6ee2dad9e27b985e7c34cd2214410316f10000000000000000000000007c718d6ee2dad9e27b985e7c34cd2214410316f10000000000000000000000000000000000000000000000000021b1f2c84ad10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000686d26d709a11f4da840f4fc4b14b94fed5f90c7000000000000000000000000686d26d709a11f4da840f4fc4b14b94fed5f90c700000000000000000000000000000000000000000000000000260572fc481d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009345c48c1dbcf90b73a095a261cd7777aff6d8e50000000000000000000000009345c48c1dbcf90b73a095a261cd7777aff6d8e5000000000000000000000000000000000000000000000000002398f7847cfa0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027b0fc6c4a5a0cf213a570097279a5bde61214d200000000000000000000000027b0fc6c4a5a0cf213a570097279a5bde61214d200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6562,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5a1e201c6c621b1bc4782a89beefbcec833d105000000000000000000000000e5a1e201c6c621b1bc4782a89beefbcec833d1050000000000000000000000000000000000000000000000000030bd984297450000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000098c54e453e5fb273fa6c0cdc22d340bea23ef1b000000000000000000000000098c54e453e5fb273fa6c0cdc22d340bea23ef1b00000000000000000000000000000000000000000000000000049e57d635400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6565,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072500ffa253799327f5963fcc35e34ea6a6880b100000000000000000000000072500ffa253799327f5963fcc35e34ea6a6880b1000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1d10dd665f35dd6f1e595bb42e3924f92aef005000000000000000000000000f1d10dd665f35dd6f1e595bb42e3924f92aef0050000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6567,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055a55bdd1259809061cd677308e385603271ee4900000000000000000000000055a55bdd1259809061cd677308e385603271ee490000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6568,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001edec03eab28cbd0940ad39d684bf1aa3eb131260000000000000000000000001edec03eab28cbd0940ad39d684bf1aa3eb131260000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6571,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae9150e882d17fa39e668ea1f6a0e08ebdd7e562000000000000000000000000ae9150e882d17fa39e668ea1f6a0e08ebdd7e56200000000000000000000000000000000000000000000000000e92e14ceaea0e700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009cc84e44fac29559654fd3b51e7ae2213dfab4fc0000000000000000000000009cc84e44fac29559654fd3b51e7ae2213dfab4fc0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6573,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000887e2120c2d75c75faf422bb856768726d1e8ad6000000000000000000000000887e2120c2d75c75faf422bb856768726d1e8ad600000000000000000000000000000000000000000000000001196180a3f71c1f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6574,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d023313bb4e503a0277ae7a8da0a81f8e887c0b4000000000000000000000000d023313bb4e503a0277ae7a8da0a81f8e887c0b40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6575,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb23b4df2cc272eda72ad7e41e919cf02b164c4b000000000000000000000000cb23b4df2cc272eda72ad7e41e919cf02b164c4b000000000000000000000000000000000000000000000000010d3d79b37e969700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6576,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000440e0140aae0e85344f4c1853697d7159217b70e000000000000000000000000440e0140aae0e85344f4c1853697d7159217b70e0000000000000000000000000000000000000000000000000118d5eb028a708200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c40b49313fb10ec7ca60293168097ed332daee70000000000000000000000004c40b49313fb10ec7ca60293168097ed332daee70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a92ad7e0bd2670c9130edf9534be003b5b06bf92000000000000000000000000a92ad7e0bd2670c9130edf9534be003b5b06bf92000000000000000000000000000000000000000000000000003519d7d9929d8200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6579,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000419a60d57f2dd0a0d332a86de04d3d7c5da95509000000000000000000000000419a60d57f2dd0a0d332a86de04d3d7c5da955090000000000000000000000000000000000000000000000000114b2dbf86435a700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6580,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032243242dbc34c9a80f66f4047848f3bca1ed1ed00000000000000000000000032243242dbc34c9a80f66f4047848f3bca1ed1ed0000000000000000000000000000000000000000000000000110447667c5ac7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6581,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000523fd220eb4172214dc811b7d4e8781df50836b4000000000000000000000000523fd220eb4172214dc811b7d4e8781df50836b40000000000000000000000000000000000000000000000000112ec300c5588a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6582,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004aa706defd337b3c86eb236151223ecfc73c9d3a0000000000000000000000004aa706defd337b3c86eb236151223ecfc73c9d3a000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6583,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f9aa8be086b2343407496f4fe58c5054d040c5a0000000000000000000000005f9aa8be086b2343407496f4fe58c5054d040c5a0000000000000000000000000000000000000000000000000113f36cfbdd1b2200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6584,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2b8624f63a45e445b854c86c0ac028e195b8092000000000000000000000000f2b8624f63a45e445b854c86c0ac028e195b80920000000000000000000000000000000000000000000000000113e0dde14f2c5d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6585,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc0ab9f9e603031fb53d69ff80928b335494c4a2000000000000000000000000cc0ab9f9e603031fb53d69ff80928b335494c4a2000000000000000000000000000000000000000000000000011168da3b1bd49600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006c4865ab16c9c760622f19a313a2e637e2e66a200000000000000000000000006c4865ab16c9c760622f19a313a2e637e2e66a2000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6588,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b0cd7ff30f19ef4b3d031f7c84cb22a63080cd30000000000000000000000009b0cd7ff30f19ef4b3d031f7c84cb22a63080cd300000000000000000000000000000000000000000000000000ad0136ba09a70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6589,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f6ff6ea50edfa7852d194a79b414a5de0891dd90000000000000000000000005f6ff6ea50edfa7852d194a79b414a5de0891dd900000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6590,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008901baea259b7aa8d00da8a109a5bed145b5f5dc0000000000000000000000008901baea259b7aa8d00da8a109a5bed145b5f5dc0000000000000000000000000000000000000000000000000023a48fa834505b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6591,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e095d1a7ed1a1173d69d7bd724b2b7c6c81b0e4b000000000000000000000000e095d1a7ed1a1173d69d7bd724b2b7c6c81b0e4b00000000000000000000000000000000000000000000000000223953dbbfa10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6595,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000623db2c9a0a8e1d3825f57e5cbf1dc8e034e8a48000000000000000000000000623db2c9a0a8e1d3825f57e5cbf1dc8e034e8a4800000000000000000000000000000000000000000000000000a4ee2c2d88cedf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abfdbdfd20440c6495ca4036807e62bd7b38b88a000000000000000000000000abfdbdfd20440c6495ca4036807e62bd7b38b88a000000000000000000000000000000000000000000000000007ca2b347503fcd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6604,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f661216d01f19b7510b2231c9011d36fdc43fb28000000000000000000000000f661216d01f19b7510b2231c9011d36fdc43fb28000000000000000000000000000000000000000000000000005833ccd169b17a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6614,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d0bd436d80ce813267a856167db48f598f2c9dc0000000000000000000000003d0bd436d80ce813267a856167db48f598f2c9dc000000000000000000000000000000000000000000000000009414471f5aa18900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6618,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000015a2c6080f554ad428632a89a0743fcf766eacc000000000000000000000000015a2c6080f554ad428632a89a0743fcf766eacc00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073b877d6f891d3f621571098b537b756cf028fef00000000000000000000000073b877d6f891d3f621571098b537b756cf028fef0000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3e4254aead0870d17a20624d7b2a466de98d216000000000000000000000000a3e4254aead0870d17a20624d7b2a466de98d216000000000000000000000000000000000000000000000000001c3e38a5b399c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1ab8886163021b940362d01e432cd213f74879c000000000000000000000000b1ab8886163021b940362d01e432cd213f74879c000000000000000000000000000000000000000000000000003c6b7e61199c2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dac1e9ceda1b0576585185c289f3544b3f6f3966000000000000000000000000dac1e9ceda1b0576585185c289f3544b3f6f3966000000000000000000000000000000000000000000000000001b689fb847f50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000874ffb0ec913131bd9c26984f1d9d911c4c897cc000000000000000000000000874ffb0ec913131bd9c26984f1d9d911c4c897cc00000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e5af1f11ad9856d8c6e1ab27fe2c0c40b579b370000000000000000000000006e5af1f11ad9856d8c6e1ab27fe2c0c40b579b37000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000874ffb0ec913131bd9c26984f1d9d911c4c897cc000000000000000000000000874ffb0ec913131bd9c26984f1d9d911c4c897cc0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a13594f72403765bbf45270a74375f2e81a3dc8f000000000000000000000000a13594f72403765bbf45270a74375f2e81a3dc8f000000000000000000000000000000000000000000000000001fc0afcac8d70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6636,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000745c0fa858115b9ccc4148fb9b41049e729fdbb5000000000000000000000000745c0fa858115b9ccc4148fb9b41049e729fdbb5000000000000000000000000000000000000000000000000007b52d7d7472ede00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6637,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a8c448e8bbe80b9022bcac1e3a67d9e717e17640000000000000000000000008a8c448e8bbe80b9022bcac1e3a67d9e717e1764000000000000000000000000000000000000000000000000019218a6fffe7f0900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067dbb60cb215f601e33ae776ea7ca40ad62dcde700000000000000000000000067dbb60cb215f601e33ae776ea7ca40ad62dcde700000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6639,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca8f7ddeb3ba7864e71e161d6bfc7ef86b1b275d000000000000000000000000ca8f7ddeb3ba7864e71e161d6bfc7ef86b1b275d000000000000000000000000000000000000000000000000004062f5df3b410c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6640,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069428b8507d725a12a3f367edc79c928a490452b00000000000000000000000069428b8507d725a12a3f367edc79c928a490452b00000000000000000000000000000000000000000000000000aef21da8d16f2400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d19b5de52d139b4d2c683d986830c6a621474292000000000000000000000000d19b5de52d139b4d2c683d986830c6a62147429200000000000000000000000000000000000000000000000000c1fa5c05b7bbfa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb5cf7ecfddca71ee8d88780d1d5c90dd392c64c000000000000000000000000fb5cf7ecfddca71ee8d88780d1d5c90dd392c64c00000000000000000000000000000000000000000000000000603c37d925fb6600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d8b19af2638856b3984d02015b6230d1daadbf20000000000000000000000003d8b19af2638856b3984d02015b6230d1daadbf20000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6644,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ad06f116674a878336914171ade46fd8f8a62490000000000000000000000004ad06f116674a878336914171ade46fd8f8a624900000000000000000000000000000000000000000000000000a87b5ce9b3b08b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6645,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac16c8fd47716cd64161d8c3f1f804cec36861cb000000000000000000000000ac16c8fd47716cd64161d8c3f1f804cec36861cb0000000000000000000000000000000000000000000000000076b27b40522bd800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6646,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029c0ce4cbd333b5c1eca001ae59cd8587c6970c500000000000000000000000029c0ce4cbd333b5c1eca001ae59cd8587c6970c500000000000000000000000000000000000000000000000000a42fd7776d7d2e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6647,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016e868c6d41a1a9d4f4d48a1961130c1538524e400000000000000000000000016e868c6d41a1a9d4f4d48a1961130c1538524e4000000000000000000000000000000000000000000000000015971de36d84d8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6648,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000601496f365423b60fceb676829d8a6598a9d7a0b000000000000000000000000601496f365423b60fceb676829d8a6598a9d7a0b000000000000000000000000000000000000000000000000e54d3e150694144200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +6649,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090d5713068c4c4f889a086b7cec5044ce773963e00000000000000000000000090d5713068c4c4f889a086b7cec5044ce773963e00000000000000000000000000000000000000000000000000097f30723aa68000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6650,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a233deb08bcb3a54b183749398663dad0ec4b55c000000000000000000000000a233deb08bcb3a54b183749398663dad0ec4b55c00000000000000000000000000000000000000000000000000a68b949106aac600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6652,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000508e37a6a77620053b5cdf627dd25b30ebe0d0de000000000000000000000000508e37a6a77620053b5cdf627dd25b30ebe0d0de000000000000000000000000000000000000000000000000001fa8a295f4150000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025b3a312525a5a80da92ccd034d1359bff74eedd00000000000000000000000025b3a312525a5a80da92ccd034d1359bff74eedd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6654,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb974bf9c76290d4216a0d2124a213e1167d087a000000000000000000000000cb974bf9c76290d4216a0d2124a213e1167d087a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c1c0baccc78de4b02e4f3c83209294ccd462c450000000000000000000000008c1c0baccc78de4b02e4f3c83209294ccd462c4500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000267d3062be04e8101e2b0522e949f1369dba38dd000000000000000000000000267d3062be04e8101e2b0522e949f1369dba38dd0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6657,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000867fe52d01283053bd3edac93ec50a70ff47443f000000000000000000000000867fe52d01283053bd3edac93ec50a70ff47443f00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc62c6c6ac36ce092da2110be9cd8b7ce8031173000000000000000000000000fc62c6c6ac36ce092da2110be9cd8b7ce80311730000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6660,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6d5b68f4c928d709182f06b4279c09240d2ad89000000000000000000000000e6d5b68f4c928d709182f06b4279c09240d2ad8900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6661,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6f8157f6e36763ea04af3969ae519f74b202012000000000000000000000000d6f8157f6e36763ea04af3969ae519f74b2020120000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6662,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f62cd4ff9291c5745139043c8882061a8d4b4360000000000000000000000005f62cd4ff9291c5745139043c8882061a8d4b4360000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6663,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000063d80caa6d0ea78f9a502c9c2c8b5079a666d60000000000000000000000000063d80caa6d0ea78f9a502c9c2c8b5079a666d60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff071c783c770c715575fd1c3948ca8808d09ba1000000000000000000000000ff071c783c770c715575fd1c3948ca8808d09ba10000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6d4f52d978252947554a529fe151833c2441988000000000000000000000000f6d4f52d978252947554a529fe151833c244198800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6666,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000286f9209ad18ecb53e655a2b2d67ba4836eca37c000000000000000000000000286f9209ad18ecb53e655a2b2d67ba4836eca37c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6667,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025b3a312525a5a80da92ccd034d1359bff74eedd00000000000000000000000025b3a312525a5a80da92ccd034d1359bff74eedd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7e4efc63d964fb54d158f935da146bc1d110111000000000000000000000000c7e4efc63d964fb54d158f935da146bc1d11011100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6669,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067483bd638e743def96cc6ec22370890e806266700000000000000000000000067483bd638e743def96cc6ec22370890e80626670000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6670,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025ab40e11289f84c7922d6c9701482d2ce71bb3b00000000000000000000000025ab40e11289f84c7922d6c9701482d2ce71bb3b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6671,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc83d4d0356f65da131cad32ddee510ffbe299c9000000000000000000000000bc83d4d0356f65da131cad32ddee510ffbe299c900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd8cbf8346fd11605d3ab90f70119f16c96c36d7000000000000000000000000dd8cbf8346fd11605d3ab90f70119f16c96c36d70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6673,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071ef8f6abd528f29ff6f72fa065e28e029a4333f00000000000000000000000071ef8f6abd528f29ff6f72fa065e28e029a4333f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6674,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3e756bc7166c59a16feaecf6f4ef79809602500000000000000000000000000c3e756bc7166c59a16feaecf6f4ef7980960250000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6675,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e9b8031a39b2d7c75923b7bb008c68aff0857770000000000000000000000001e9b8031a39b2d7c75923b7bb008c68aff08577700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6676,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000718f4656f2ca7651703b8fc4f0f4bdfef6c2f5f4000000000000000000000000718f4656f2ca7651703b8fc4f0f4bdfef6c2f5f40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6677,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d17e59eddd8ece9dee0a080a59ec054f1f088cc0000000000000000000000003d17e59eddd8ece9dee0a080a59ec054f1f088cc00000000000000000000000000000000000000000000000000027ca57357c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6678,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f40ec377e00a8824af15fda1f594f7529a244950000000000000000000000009f40ec377e00a8824af15fda1f594f7529a244950000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e869afc9e11808553dd26cb14e3a6e4d02f81880000000000000000000000003e869afc9e11808553dd26cb14e3a6e4d02f818800000000000000000000000000000000000000000000000000027ca57357c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000effc506ccea7885f1e9b083ca335f5461c825055000000000000000000000000effc506ccea7885f1e9b083ca335f5461c82505500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6682,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057b8aa42c89c1665d5bbf2a905b5e13b88a2c2ca00000000000000000000000057b8aa42c89c1665d5bbf2a905b5e13b88a2c2ca000000000000000000000000000000000000000000000000005bb1030379c58000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6683,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000615dc9211890d374b5e8238aa0a1e1d610dae2a3000000000000000000000000615dc9211890d374b5e8238aa0a1e1d610dae2a30000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015ba2529b499a8d4a1f2023b2cccef67255b223300000000000000000000000015ba2529b499a8d4a1f2023b2cccef67255b223300000000000000000000000000000000000000000000000000027ca57357c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b58dd5de6947a9af979b6319c7764d00d86599ee000000000000000000000000b58dd5de6947a9af979b6319c7764d00d86599ee00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6686,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001533a8bee6a563156b93cd173e0b082aed5977a10000000000000000000000001533a8bee6a563156b93cd173e0b082aed5977a10000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6687,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075334ff3095e21595eeda01a6cf45e3344561abc00000000000000000000000075334ff3095e21595eeda01a6cf45e3344561abc00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a332a063fa84977d9b3e702e82832a4263d63eef000000000000000000000000a332a063fa84977d9b3e702e82832a4263d63eef0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6689,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000096283598b4f1ff22d25938c38e4fd6c20c74bb3300000000000000000000000096283598b4f1ff22d25938c38e4fd6c20c74bb3300000000000000000000000000000000000000000000000000000000003157ed00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +6690,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000284439da6039b2e2fdd4dca08444856b9b7a6b90000000000000000000000000284439da6039b2e2fdd4dca08444856b9b7a6b90000000000000000000000000000000000000000000000000017c917612441de00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6691,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ae2795fbfe8c0f9cd111b7b10ffb7aef69c5d000000000000000000000000005ae2795fbfe8c0f9cd111b7b10ffb7aef69c5d000000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6692,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acf2b39a6fe489cbcbcb34d767f2c1ede152e3ff000000000000000000000000acf2b39a6fe489cbcbcb34d767f2c1ede152e3ff0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6693,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003162d262871948881d5c7829d97ef60945a486540000000000000000000000003162d262871948881d5c7829d97ef60945a486540000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd3beee5318121bd40a84db070da51799df6e42d000000000000000000000000fd3beee5318121bd40a84db070da51799df6e42d00000000000000000000000000000000000000000000000000487fd36235eb2b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6695,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5f7c27187665f1493257f215bab01513d945bd0000000000000000000000000a5f7c27187665f1493257f215bab01513d945bd00000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6696,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9b95c3e7b283df258a8243989d57d234290e7ee000000000000000000000000b9b95c3e7b283df258a8243989d57d234290e7ee0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ce9f98f11357a8cefc00ae30c5bb631d1358f270000000000000000000000005ce9f98f11357a8cefc00ae30c5bb631d1358f270000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008137d0a34a169af74193b378982ec2799beafefa0000000000000000000000008137d0a34a169af74193b378982ec2799beafefa0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6699,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e067258fd4a337568325fe9013bdf5f863556941000000000000000000000000e067258fd4a337568325fe9013bdf5f8635569410000000000000000000000000000000000000000000000000015e886c679eb7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6700,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f33f8b6dde723ad36be008d958418cbef9362f79000000000000000000000000f33f8b6dde723ad36be008d958418cbef9362f79000000000000000000000000000000000000000000000011fe9fb60ff9246d8f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x399ae0fd92433078e23ab91f3dd853fa0ffb6010d68ab5b4af786aba1b5db633,2022-03-08 08:28:26.000 UTC,0,true +6701,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000583ed46aeb355b2ac96e5225ec3d6004077965b0000000000000000000000000583ed46aeb355b2ac96e5225ec3d6004077965b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e780e711a483d291d25f8a6b3e17c71dd71f7860000000000000000000000003e780e711a483d291d25f8a6b3e17c71dd71f78600000000000000000000000000000000000000000000000000019e82c4f47a5f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6703,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da42e741a6c75ef7a644574485d530667b4cc509000000000000000000000000da42e741a6c75ef7a644574485d530667b4cc5090000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096f838cccf3299b4a456f39c393c0d6ec959649000000000000000000000000096f838cccf3299b4a456f39c393c0d6ec95964900000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000989b82ed1e240597c0ead2e1734235784ff865c0000000000000000000000000989b82ed1e240597c0ead2e1734235784ff865c000000000000000000000000000000000000000000000000000985792b17b37c200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9d52c08223533751fea859b8751b10617fea736000000000000000000000000e9d52c08223533751fea859b8751b10617fea7360000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6708,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dae14824041cb79bc4b6b036fc398e6fcd17af36000000000000000000000000dae14824041cb79bc4b6b036fc398e6fcd17af360000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6709,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef8c15fd7476664e3ce5c5dc1bf1a41587eaa9df000000000000000000000000ef8c15fd7476664e3ce5c5dc1bf1a41587eaa9df0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6710,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c0ab71b90e97662bbd2ce0bd50663a3218925f80000000000000000000000005c0ab71b90e97662bbd2ce0bd50663a3218925f80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6711,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb665bba0648c249e6e80d254610d8722cf16e06000000000000000000000000eb665bba0648c249e6e80d254610d8722cf16e06000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d06a071d682387800aa4cfdf4bc041286fae29c0000000000000000000000002d06a071d682387800aa4cfdf4bc041286fae29c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2427fc07cb9eba0524813f81628b40a6e085008000000000000000000000000c2427fc07cb9eba0524813f81628b40a6e085008000000000000000000000000000000000000000000000000005c4d9ced308fbf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6715,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a78ef0a38e4f7e6de8c1188bf1e23be7fde6d163000000000000000000000000a78ef0a38e4f7e6de8c1188bf1e23be7fde6d1630000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000593a39b3049a37b69aa20f76e1ba82cf4dd3d8df000000000000000000000000593a39b3049a37b69aa20f76e1ba82cf4dd3d8df0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068e227245a15aebffb30e2119ac8471b2d585fe700000000000000000000000068e227245a15aebffb30e2119ac8471b2d585fe7000000000000000000000000000000000000000000000000002bf638399c56cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6718,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000743ee42aea17236e6e352291f5af19985340b5ef000000000000000000000000743ee42aea17236e6e352291f5af19985340b5ef0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6719,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a6875bd4551e2ce409735128cc3ea0f679dde450000000000000000000000009a6875bd4551e2ce409735128cc3ea0f679dde450000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6721,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a24ef7cb10bbf9a13f72efee6704dd2ed00a7a37000000000000000000000000a24ef7cb10bbf9a13f72efee6704dd2ed00a7a37000000000000000000000000000000000000000000000000004fea443334973000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6723,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ddc3b986528d899d6e8c83b43854f239a8ce9370000000000000000000000009ddc3b986528d899d6e8c83b43854f239a8ce9370000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6724,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002739490a39ecd9627a4a62c6a09d3cccb7d0cce10000000000000000000000002739490a39ecd9627a4a62c6a09d3cccb7d0cce1000000000000000000000000000000000000000000000000000137ed63e19a9a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6725,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa4efd397ed95854a1aabbd0d3c0f9a22583aca7000000000000000000000000aa4efd397ed95854a1aabbd0d3c0f9a22583aca700000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6726,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfd7b3c53d7e9dff11c8325c3fdad957849de552000000000000000000000000bfd7b3c53d7e9dff11c8325c3fdad957849de5520000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6727,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050eae46b07f2773c9743f393df2a546a0a5bd08e00000000000000000000000050eae46b07f2773c9743f393df2a546a0a5bd08e00000000000000000000000000000000000000000000000000193f6ba6304c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6227a80ffeba38ea32ab6b9713be920289cb3cf000000000000000000000000d6227a80ffeba38ea32ab6b9713be920289cb3cf0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6731,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017ed4599964c08a7e87ac85d5260fac711dcb20800000000000000000000000017ed4599964c08a7e87ac85d5260fac711dcb2080000000000000000000000000000000000000000000000000001064b62f3e60600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6732,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd128dd4f3bc1087003b118f7b605d0acecc87af000000000000000000000000dd128dd4f3bc1087003b118f7b605d0acecc87af0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a86efb65073925ab10a0d7afcd380de728e8a940000000000000000000000001a86efb65073925ab10a0d7afcd380de728e8a9400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6734,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc948a999aa852f1be4059cb9a35c3b0c7d8d5c7000000000000000000000000cc948a999aa852f1be4059cb9a35c3b0c7d8d5c70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6735,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da074a0cea8b865dcd6f29840c7cc43117d7e7cf000000000000000000000000da074a0cea8b865dcd6f29840c7cc43117d7e7cf00000000000000000000000000000000000000000000000000053cd2d6ecc36900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6736,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4ec5cbec873b8b856151707bbc108959b878d60000000000000000000000000b4ec5cbec873b8b856151707bbc108959b878d600000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6737,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d910066ad7695771c59596b7d18a5b17a1e19fa9000000000000000000000000d910066ad7695771c59596b7d18a5b17a1e19fa900000000000000000000000000000000000000000000000000604051253ea9f300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078aa649f3650210370473af4d2e76d0134bad04200000000000000000000000078aa649f3650210370473af4d2e76d0134bad04200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061797bbe124100ed5ccab9563e846d4032e6bddb00000000000000000000000061797bbe124100ed5ccab9563e846d4032e6bddb0000000000000000000000000000000000000000000000000002f31db95900f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d70cb8d1d6f6c5c0103590aaaa89728ef1c71bc0000000000000000000000000d70cb8d1d6f6c5c0103590aaaa89728ef1c71bc0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078aa649f3650210370473af4d2e76d0134bad04200000000000000000000000078aa649f3650210370473af4d2e76d0134bad0420000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6743,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e8b2321803b479333c94415e8d5a6ea62bb7af50000000000000000000000002e8b2321803b479333c94415e8d5a6ea62bb7af50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6744,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068990547d34fc703c923be5ffe823b73005accc800000000000000000000000068990547d34fc703c923be5ffe823b73005accc80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a86efb65073925ab10a0d7afcd380de728e8a940000000000000000000000001a86efb65073925ab10a0d7afcd380de728e8a94000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6746,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000debbca93d481a510ce1b84a6413b8b4b858b17f0000000000000000000000000debbca93d481a510ce1b84a6413b8b4b858b17f0000000000000000000000000000000000000000000000000000427b31cbf515a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cfbcbf4b01eac0631b0a2864f670e829716390b0000000000000000000000005cfbcbf4b01eac0631b0a2864f670e829716390b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6748,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4867a97a644c0ba2cfa01251c5f444247e1d4a9000000000000000000000000f4867a97a644c0ba2cfa01251c5f444247e1d4a90000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6749,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea0cfed9a954ef5058bea5489932759fe433bd25000000000000000000000000ea0cfed9a954ef5058bea5489932759fe433bd250000000000000000000000000000000000000000000000000001bd64e8a389c500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6750,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0f8028a63bee304d331e54a420a581bcff254d0000000000000000000000000a0f8028a63bee304d331e54a420a581bcff254d000000000000000000000000000000000000000000000000002165400ce3800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6751,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc11da00aaf47cde957b20f8e6ba3289b5b12755000000000000000000000000cc11da00aaf47cde957b20f8e6ba3289b5b1275500000000000000000000000000000000000000000000000000ae0cdb8be3fe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd5f81f7a74b48d4d7bc9014ef8bbfe68adff7ef000000000000000000000000cd5f81f7a74b48d4d7bc9014ef8bbfe68adff7ef0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6753,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000255ae1b7ea3e90a693c577116a9a6b9e8ad9d7a0000000000000000000000000255ae1b7ea3e90a693c577116a9a6b9e8ad9d7a00000000000000000000000000000000000000000000000000019de182d7fa29f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6754,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f13e23fca742b91b5dd0ce6dbdbaade23d5a8510000000000000000000000001f13e23fca742b91b5dd0ce6dbdbaade23d5a851000000000000000000000000000000000000000000000000000c1448303c800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6755,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d4e3332ad0148a1f9dc2c3f22962a4ac01fe9380000000000000000000000002d4e3332ad0148a1f9dc2c3f22962a4ac01fe93800000000000000000000000000000000000000000000000000049db5c31bba7c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6756,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd05389364119733c81c11326f2a10c5525674da000000000000000000000000dd05389364119733c81c11326f2a10c5525674da00000000000000000000000000000000000000000000000000320c0d1cca362100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6757,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddd57633ec77f9c4dae0eb10ec3ae92e8bf2b8c7000000000000000000000000ddd57633ec77f9c4dae0eb10ec3ae92e8bf2b8c70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7685b061bcbe69aa0f5805b0f9044fe27c26219000000000000000000000000f7685b061bcbe69aa0f5805b0f9044fe27c2621900000000000000000000000000000000000000000000000000a79e07db20f27000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6759,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ec6295bf707b896efe73fb9f9a8aca0855c22460000000000000000000000006ec6295bf707b896efe73fb9f9a8aca0855c2246000000000000000000000000000000000000000000000000000818ccbc67cec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6760,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f3dec91e024382085c5eb75c53c9e1affcddcda0000000000000000000000007f3dec91e024382085c5eb75c53c9e1affcddcda000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6761,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e85a3e42bcb125c4f002877590783cfe043af38a000000000000000000000000e85a3e42bcb125c4f002877590783cfe043af38a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000382f7e0d466fde37662adab977b43ff3408fbadc000000000000000000000000382f7e0d466fde37662adab977b43ff3408fbadc00000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6763,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061df273850e894883ea2a07abb83412bd3ac7ac300000000000000000000000061df273850e894883ea2a07abb83412bd3ac7ac30000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6764,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002bd7911ad761733ed33e5c3759c11ac8950a9b810000000000000000000000002bd7911ad761733ed33e5c3759c11ac8950a9b8100000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6765,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ec20a48606ed812d4ff83cddff24f056e9567a00000000000000000000000003ec20a48606ed812d4ff83cddff24f056e9567a00000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e04e81d73664ab466181f467d37b065021e78b50000000000000000000000003e04e81d73664ab466181f467d37b065021e78b500000000000000000000000000000000000000000000000001902e262da0e2d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6767,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d752d7f9ac9b31181ad78a8ff650d3bfaa56b3a0000000000000000000000005d752d7f9ac9b31181ad78a8ff650d3bfaa56b3a0000000000000000000000000000000000000000000000000056308a22b602f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000562156551d44f126d4a062c1acf3982191f9e75f000000000000000000000000562156551d44f126d4a062c1acf3982191f9e75f00000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6769,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000338485735554d67e60826cf8a7a0f16168657301000000000000000000000000338485735554d67e60826cf8a7a0f161686573010000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6770,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094c4ddf43ad5caf17155961c427b3bca8fcb5e6700000000000000000000000094c4ddf43ad5caf17155961c427b3bca8fcb5e670000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6771,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dbf1ac97a4174328ed8f72f973f6048e9ea7eef2000000000000000000000000dbf1ac97a4174328ed8f72f973f6048e9ea7eef2000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000661e6111844f9e63c9c9f64ae285fbf771b753a7000000000000000000000000661e6111844f9e63c9c9f64ae285fbf771b753a7000000000000000000000000000000000000000000000000000ec42f934ec70b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6773,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056ee385e4cb6f046cba4bca258888e05d6b2ed3f00000000000000000000000056ee385e4cb6f046cba4bca258888e05d6b2ed3f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c82877142407489d1c287b9477c5dd207fdd3403000000000000000000000000c82877142407489d1c287b9477c5dd207fdd34030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fd31e056c2efaea5c7f2434361675c86aa46b190000000000000000000000000fd31e056c2efaea5c7f2434361675c86aa46b190000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdfa32808e6c14fd1a237271fecc6e4e65332213000000000000000000000000bdfa32808e6c14fd1a237271fecc6e4e653322130000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005455f0d4c30bdf9674e4ab2874e9c35ee56bb1750000000000000000000000005455f0d4c30bdf9674e4ab2874e9c35ee56bb1750000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6778,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092db20ba1eef01e50ee4b77aadc381a13a6e5c9b00000000000000000000000092db20ba1eef01e50ee4b77aadc381a13a6e5c9b0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b070973752ee0d32b297fae01fc949b1f8895458000000000000000000000000b070973752ee0d32b297fae01fc949b1f88954580000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6780,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d20cefb170c77788c958b33c3d3c1df5001c0081000000000000000000000000d20cefb170c77788c958b33c3d3c1df5001c00810000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2df6eb279693cd4df01b3cee95ad7edd6c18a49000000000000000000000000f2df6eb279693cd4df01b3cee95ad7edd6c18a490000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6782,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd6d9d0e7a11eca7be5dc7617901203e8fb90c73000000000000000000000000bd6d9d0e7a11eca7be5dc7617901203e8fb90c730000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f2dd81fc7b7a5d603864c4bbc0b5a0db2b818560000000000000000000000008f2dd81fc7b7a5d603864c4bbc0b5a0db2b818560000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6784,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ffb52199b115b695aa1b0153bb6f167330de7550000000000000000000000005ffb52199b115b695aa1b0153bb6f167330de7550000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005dbbc46e95b9abb77a49296b0baf6e464cefe8da0000000000000000000000005dbbc46e95b9abb77a49296b0baf6e464cefe8da0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009790062ed975a3d3df2926fe677a970d63608b030000000000000000000000009790062ed975a3d3df2926fe677a970d63608b03000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8300f627164a1bfd983b43e7b75825f0ac3d659000000000000000000000000e8300f627164a1bfd983b43e7b75825f0ac3d6590000000000000000000000000000000000000000000000000016932a38a315ff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006743dc6c402b4ec457d243a3fe39b5fd3cbd68a60000000000000000000000006743dc6c402b4ec457d243a3fe39b5fd3cbd68a6000000000000000000000000000000000000000000000000001e82bdbc5dc65c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6790,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fe4c41bdc99fc8c93b443a048fe453fd480263f0000000000000000000000005fe4c41bdc99fc8c93b443a048fe453fd480263f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6791,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9f170e6ce173e753ecc2161676a89a45e413d6d000000000000000000000000f9f170e6ce173e753ecc2161676a89a45e413d6d00000000000000000000000000000000000000000000000000a4928b3a8663a000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f77cec2fcaa9cd0cd57207fff081791433da5420000000000000000000000007f77cec2fcaa9cd0cd57207fff081791433da5420000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6793,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073d5cee28154860b4c74544e97243e24c498eb9400000000000000000000000073d5cee28154860b4c74544e97243e24c498eb940000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3c90e136e0ef3a784a409fd03ebdc441d281bba000000000000000000000000f3c90e136e0ef3a784a409fd03ebdc441d281bba000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6795,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077f957271c6603f5e09f98ae3a832fc807b9f5ba00000000000000000000000077f957271c6603f5e09f98ae3a832fc807b9f5ba0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf494685a64273fd97682572c4d18ac3a8dd8541000000000000000000000000cf494685a64273fd97682572c4d18ac3a8dd8541000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e55b4c05d74d84931a513f3c7b37d609a487c0ea000000000000000000000000e55b4c05d74d84931a513f3c7b37d609a487c0ea0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6798,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026ef3b71bd9fb55cd9e5e78cc00cf47c469e607100000000000000000000000026ef3b71bd9fb55cd9e5e78cc00cf47c469e6071000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6799,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ee2bf824a123cdeaafae3a48d815389346592ff0000000000000000000000003ee2bf824a123cdeaafae3a48d815389346592ff0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6800,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052018495652d3306a488c491cf26814ce2cb0efc00000000000000000000000052018495652d3306a488c491cf26814ce2cb0efc000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6801,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b86f41e27467435e82602009db717f22f7dbb6f0000000000000000000000003b86f41e27467435e82602009db717f22f7dbb6f0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6802,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd6f5a15a452ae14538624da5035fd86d2bdd4e0000000000000000000000000dd6f5a15a452ae14538624da5035fd86d2bdd4e00000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6803,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c00b37353608eaa0602304b68eab325914799310000000000000000000000000c00b37353608eaa0602304b68eab325914799310000000000000000000000000000000000000000000000000072bfc62055f97500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6804,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ea73574617b991c15be1ab57fc018465d29147b0000000000000000000000004ea73574617b991c15be1ab57fc018465d29147b000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6805,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000158e1aa7940735af8edaca168bf60e5707ff91d0000000000000000000000000158e1aa7940735af8edaca168bf60e5707ff91d00000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6807,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d7e9f89c3cf7a6ea7e820ae8737ec624f6586c70000000000000000000000000d7e9f89c3cf7a6ea7e820ae8737ec624f6586c7000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6808,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062df12cc459f484e670845804706849fcc83788500000000000000000000000062df12cc459f484e670845804706849fcc8378850000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6809,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a70d9c59ad7418abec8155ec8154ade6d1a31c50000000000000000000000004a70d9c59ad7418abec8155ec8154ade6d1a31c50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001907037c1acf968cefa05f730ccdc522b94720ad0000000000000000000000001907037c1acf968cefa05f730ccdc522b94720ad0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6811,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5fe3482344526cf9d6234703c074e3880907b8b000000000000000000000000b5fe3482344526cf9d6234703c074e3880907b8b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f97722f8c20461c77da6b696f41b5b908c6cf6b5000000000000000000000000f97722f8c20461c77da6b696f41b5b908c6cf6b50000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6813,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031e9b62825f0ffa39cf95df3eba4e97065fee33700000000000000000000000031e9b62825f0ffa39cf95df3eba4e97065fee3370000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da1c3d4df3281ca6a6b14bde37a509959a096759000000000000000000000000da1c3d4df3281ca6a6b14bde37a509959a096759000000000000000000000000000000000000000000000000008a663c5a4fdf8b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd2c242f68eec50d30940c9d17f2662e138ad8440be1385d24ed142ccb8ed043f,2022-02-04 00:49:13.000 UTC,0,true +6815,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000610dd633fc5d2f573b10b1b614a00c5d6d75b451000000000000000000000000610dd633fc5d2f573b10b1b614a00c5d6d75b4510000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dd057787bd3301549277f7e93b5b5380ec4b5470000000000000000000000002dd057787bd3301549277f7e93b5b5380ec4b5470000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065089bbedf4a46b336c969ae1abdbb79ffe1f60200000000000000000000000065089bbedf4a46b336c969ae1abdbb79ffe1f6020000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cef1526a2e3aacd6a404c69ee7b6a29a3417d3aa000000000000000000000000cef1526a2e3aacd6a404c69ee7b6a29a3417d3aa0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6820,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000684ac097ee23a5cf3a74265d34ad557c17d694a0000000000000000000000000684ac097ee23a5cf3a74265d34ad557c17d694a0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6822,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003cdc7a4c7185d73cffb7c2e4b3c80a95609d95040000000000000000000000003cdc7a4c7185d73cffb7c2e4b3c80a95609d95040000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064986e67ef13776ac665142cfb10f049f93443a600000000000000000000000064986e67ef13776ac665142cfb10f049f93443a6000000000000000000000000000000000000000000000000002eef9496c9af3e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed19639b0bb87b3f5547eaa514e289d4ea79c34c000000000000000000000000ed19639b0bb87b3f5547eaa514e289d4ea79c34c00000000000000000000000000000000000000000000000000a4c0900a5c774600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019f875200b36f910c05d32cc8016132a7cfbdd2900000000000000000000000019f875200b36f910c05d32cc8016132a7cfbdd290000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5a67baeb7c7ddfd5e214739e9a4f737ed7f0556000000000000000000000000f5a67baeb7c7ddfd5e214739e9a4f737ed7f05560000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000073797185afa718066af2927a916a07daee1edae000000000000000000000000073797185afa718066af2927a916a07daee1edae0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5076f22e60df3ab138191b745c5252ed43d5989000000000000000000000000e5076f22e60df3ab138191b745c5252ed43d59890000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa65879e61241800b5c7f89ab6992920f3c08d75000000000000000000000000fa65879e61241800b5c7f89ab6992920f3c08d750000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013be29e577d8d967cd74b4c5c0452bb5a875e49c00000000000000000000000013be29e577d8d967cd74b4c5c0452bb5a875e49c000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6831,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc2101a89696a4f6f94fb526ffc8a1d97714e81d000000000000000000000000fc2101a89696a4f6f94fb526ffc8a1d97714e81d00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e610f8d228a51f3370a4f862234fcbb3ac5cc01b000000000000000000000000e610f8d228a51f3370a4f862234fcbb3ac5cc01b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000518b77149261f06abab57d7bdfcc10b7577c111c000000000000000000000000518b77149261f06abab57d7bdfcc10b7577c111c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b75dad96ff6758f330856f3fdd3a6b873769b2f6000000000000000000000000b75dad96ff6758f330856f3fdd3a6b873769b2f60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3cc830800591174492fb5ee692941dfdb6a6a4b000000000000000000000000a3cc830800591174492fb5ee692941dfdb6a6a4b000000000000000000000000000000000000000000000000006fdf9a7a614d2500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000478c189ac3424841b16a11aff581720913c345f4000000000000000000000000478c189ac3424841b16a11aff581720913c345f40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a898dacad27fb10e1cef7c6a3bb61d08299962c0000000000000000000000009a898dacad27fb10e1cef7c6a3bb61d08299962c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2f89d9e4f8984a5028a9fd7a84e07ac6d5cc430000000000000000000000000d2f89d9e4f8984a5028a9fd7a84e07ac6d5cc4300000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6840,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007525fc2e118d8e931c820d4d0937d42bc42537280000000000000000000000007525fc2e118d8e931c820d4d0937d42bc425372800000000000000000000000000000000000000000000000000a450e30c8be73400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f3c1c2ecc94e7117d29629930393186d998ce1b0000000000000000000000008f3c1c2ecc94e7117d29629930393186d998ce1b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e224e7e9e6084877856f147ce06a33ccb88eeff0000000000000000000000004e224e7e9e6084877856f147ce06a33ccb88eeff000000000000000000000000000000000000000000000000008305a4a951b09000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cf69d546ea33258d7f14303758dda665ab90f640000000000000000000000002cf69d546ea33258d7f14303758dda665ab90f6400000000000000000000000000000000000000000000000000a733bf557b260200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6480446fafda6d13e228cc69eb594ea3a995e74000000000000000000000000f6480446fafda6d13e228cc69eb594ea3a995e74000000000000000000000000000000000000000000000000000bf2e4a1a1868000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2a8a73cd8f888da3e8beba1fcacf50ab8be301f000000000000000000000000d2a8a73cd8f888da3e8beba1fcacf50ab8be301f000000000000000000000000000000000000000000000000002e478127f3b10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d662b686995eca77d59a52228afd1bb7188687e0000000000000000000000003d662b686995eca77d59a52228afd1bb7188687e0000000000000000000000000000000000000000000000000073b4c1c535898200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082932cd9589c1ac167c2a902abd27cd15fcf825000000000000000000000000082932cd9589c1ac167c2a902abd27cd15fcf8250000000000000000000000000000000000000000000000000004ee415767e601900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091af4e20a9610c0ddd99ee81af75161fedcf9d5100000000000000000000000091af4e20a9610c0ddd99ee81af75161fedcf9d5100000000000000000000000000000000000000000000000000a8fe484cb3c02000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92d9d1d611c0efe375e32c0aa41b543dcfabc76000000000000000000000000c92d9d1d611c0efe375e32c0aa41b543dcfabc7600000000000000000000000000000000000000000000000000659c3ae8e2f34000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb84d1fdd67eee26015c46cf938d5f651890e3df000000000000000000000000cb84d1fdd67eee26015c46cf938d5f651890e3df00000000000000000000000000000000000000000000000000a9a4b187e5773c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049b48f5d813301700e22e654501156fb2d58c89800000000000000000000000049b48f5d813301700e22e654501156fb2d58c89800000000000000000000000000000000000000000000000000a3ef86815e8ef000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2ff8196b4ae960e3a1b533857f6f054bffa92fb000000000000000000000000f2ff8196b4ae960e3a1b533857f6f054bffa92fb00000000000000000000000000000000000000000000000001c03f5ff499958d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fc0475cecca273e96152768d9739a1b8b9e7c750000000000000000000000000fc0475cecca273e96152768d9739a1b8b9e7c7500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6855,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005180ba6607473001ae52cef5a9f267eb3a2d22580000000000000000000000005180ba6607473001ae52cef5a9f267eb3a2d2258000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e799e5672106f838dacf3a5f2044a2cc8ae6efb0000000000000000000000007e799e5672106f838dacf3a5f2044a2cc8ae6efb000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e2a20d6298438532e4830cd33350541dc057a7e0000000000000000000000009e2a20d6298438532e4830cd33350541dc057a7e000000000000000000000000000000000000000000000000003771aa6e89f50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6858,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000055605545adaca40212837f988aa6bd1066b873c000000000000000000000000055605545adaca40212837f988aa6bd1066b873c00000000000000000000000000000000000000000000000000a39d153894c6ff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6859,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a08bba2a71665cc607af4124f61bdb0983fa37a0000000000000000000000007a08bba2a71665cc607af4124f61bdb0983fa37a0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000681f284c82eb81054d6696acea2020fdc68f7ca3000000000000000000000000681f284c82eb81054d6696acea2020fdc68f7ca3000000000000000000000000000000000000000000000000004fdc3050a9fb8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf92f12f784cc351b5ce6640e2d0fbe040bdfc91c8fa13fbe2062a6e322af3ef1,2022-05-24 09:00:13.000 UTC,0,true +6861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b13a4dbaa41983319782438646f37eaf2fc1ae5e000000000000000000000000b13a4dbaa41983319782438646f37eaf2fc1ae5e000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6862,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064ab0caf0bd155a5b696ea4b08c68424bcc16a4400000000000000000000000064ab0caf0bd155a5b696ea4b08c68424bcc16a44000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b359d90f2a827afb6a9e9b84a5d2a99064cd4723000000000000000000000000b359d90f2a827afb6a9e9b84a5d2a99064cd4723000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d39bd8ab97f6421fdb43f64e9af444759a5b1bac000000000000000000000000d39bd8ab97f6421fdb43f64e9af444759a5b1bac000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6865,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f07790bf96c6e6d967d89a5c3a9be8d55c36ade3000000000000000000000000f07790bf96c6e6d967d89a5c3a9be8d55c36ade3000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6866,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000397eb4ba465dd51ebfc02a5832cd0d849c629e11000000000000000000000000397eb4ba465dd51ebfc02a5832cd0d849c629e11000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd66a3148866f5bfd68fd324ef4afc3a96301ec4000000000000000000000000bd66a3148866f5bfd68fd324ef4afc3a96301ec400000000000000000000000000000000000000000000000000a7009deb6f608000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6868,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3f68d305ab94fcfd7ee595f217160b9e544f2a9000000000000000000000000a3f68d305ab94fcfd7ee595f217160b9e544f2a900000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d679e36e57535c4c4f220b6404d115afa3dcc060000000000000000000000003d679e36e57535c4c4f220b6404d115afa3dcc0600000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d0c7ff038c90aeaec83327f5fb5ae748df81a389000000000000000000000000d0c7ff038c90aeaec83327f5fb5ae748df81a38900000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096f0ce0e9cc9fdba644341d7c5fb5fad5eb8d3c400000000000000000000000096f0ce0e9cc9fdba644341d7c5fb5fad5eb8d3c400000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060e308ac2a46e528f6f9821e9533f272fdbcc6d300000000000000000000000060e308ac2a46e528f6f9821e9533f272fdbcc6d3000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6874,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e40c1139ff356545caa2ca22b2527be092dfac5e000000000000000000000000e40c1139ff356545caa2ca22b2527be092dfac5e000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6875,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029eb0da916392512919fb2e423d9a23db2bf459000000000000000000000000029eb0da916392512919fb2e423d9a23db2bf45900000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf9a724613095d5704eb3ac79ea61dbc4854957f000000000000000000000000cf9a724613095d5704eb3ac79ea61dbc4854957f000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9d0bb52d740d5b1195468ce9194b82df48465b9000000000000000000000000e9d0bb52d740d5b1195468ce9194b82df48465b9000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4d6b0db4bf5efb57e02bdba258e6978774c2678000000000000000000000000d4d6b0db4bf5efb57e02bdba258e6978774c267800000000000000000000000000000000000000000000000000728a1c936f52ac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcf210ed32285b8a2e3cd4f7ae6c8e252cce93a3000000000000000000000000bcf210ed32285b8a2e3cd4f7ae6c8e252cce93a3000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b27e1f879c4a1061d99682d5cc7680190a48200e000000000000000000000000b27e1f879c4a1061d99682d5cc7680190a48200e000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034361fa5987629afbeeaada70f1aa29bb60c51a400000000000000000000000034361fa5987629afbeeaada70f1aa29bb60c51a4000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6882,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000647dbb5ca567702688ef0e458bd8f1af302e98e600000000000000000000000000000000000000000000000531136396bb290000,,,1,true +6883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1c4806d27ecf6d09a2f14c5edab5a61dcfbe48d000000000000000000000000f1c4806d27ecf6d09a2f14c5edab5a61dcfbe48d000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6884,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d66a7a3d590c0b892db851d2278cb76d1decfbd9000000000000000000000000d66a7a3d590c0b892db851d2278cb76d1decfbd900000000000000000000000000000000000000000000000000a85ba7593fa82000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f69f1bf59fa788f894d5693d75a7250ffcd7f878000000000000000000000000f69f1bf59fa788f894d5693d75a7250ffcd7f87800000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6886,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025a2ebfaa31d4312204ba2be4973cdcf4253587700000000000000000000000025a2ebfaa31d4312204ba2be4973cdcf42535877000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfd1f46ef8eef67e51796e183f4ba00cdbb078f7000000000000000000000000bfd1f46ef8eef67e51796e183f4ba00cdbb078f70000000000000000000000000000000000000000000000000075c2455e1871e900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068662163a2e664f8f81a751463db74864eea752200000000000000000000000068662163a2e664f8f81a751463db74864eea75220000000000000000000000000000000000000000000000000018f5441a31cfec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053bb4a4eafed31b562d766a61c8bc4681caf2ee100000000000000000000000053bb4a4eafed31b562d766a61c8bc4681caf2ee100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e90d5f1d9e1634eefb1849ea6870ad9c615ede24000000000000000000000000e90d5f1d9e1634eefb1849ea6870ad9c615ede240000000000000000000000000000000000000000000000000091a94863ca800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f48e0a83e07541d9b60a29bb249db703574b8c20000000000000000000000001f48e0a83e07541d9b60a29bb249db703574b8c20000000000000000000000000000000000000000000000000053e108c83e5e0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3da7b05bf56a6b090f21b0513316851ddf839a8000000000000000000000000a3da7b05bf56a6b090f21b0513316851ddf839a800000000000000000000000000000000000000000000000000a7b1ac6ee236fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6f0cb5d962d453f05ef628278c544dc2e9b58ff000000000000000000000000e6f0cb5d962d453f05ef628278c544dc2e9b58ff00000000000000000000000000000000000000000000000000c6f3b40b6c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6894,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000140ebfbbd62e51d45c2a4fccf6aa44b10eff32fb000000000000000000000000140ebfbbd62e51d45c2a4fccf6aa44b10eff32fb00000000000000000000000000000000000000000000000001f2a9c76eb8fceb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025c6acc11d1814a3ca59562957cada7d673ae0ac00000000000000000000000025c6acc11d1814a3ca59562957cada7d673ae0ac0000000000000000000000000000000000000000000000000077129cb6e560a100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000417be1be8e825bde060a365c5e1754403ca281b6000000000000000000000000417be1be8e825bde060a365c5e1754403ca281b6000000000000000000000000000000000000000000000000001bff73fec78c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6900,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e5af1f11ad9856d8c6e1ab27fe2c0c40b579b370000000000000000000000006e5af1f11ad9856d8c6e1ab27fe2c0c40b579b3700000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6901,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e7ea7126a10df07b3ed6f425ebf7632d6df15480000000000000000000000008e7ea7126a10df07b3ed6f425ebf7632d6df154800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a46119d6d8faf6a482b14fb7185de29f5a241293000000000000000000000000a46119d6d8faf6a482b14fb7185de29f5a241293000000000000000000000000000000000000000000000000003dc754a067e39f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6904,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078807e8347fd291a22e4e798ac8b2c373abd070f00000000000000000000000078807e8347fd291a22e4e798ac8b2c373abd070f00000000000000000000000000000000000000000000000006e497f4bab19c4900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6905,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005615b91b204e2d5a342972b2aeaafb30ad3d11840000000000000000000000005615b91b204e2d5a342972b2aeaafb30ad3d1184000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c794b210337339ce83f5be21f0f62802c029b332000000000000000000000000c794b210337339ce83f5be21f0f62802c029b332000000000000000000000000000000000000000000000000002043cb9a67fc1900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000953995ac114b527b97f6c5070de898962b8c7ad0000000000000000000000000953995ac114b527b97f6c5070de898962b8c7ad00000000000000000000000000000000000000000000000000a98b0d5f31eb2e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6910,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005842aa91fde70566883c12b07ec700792630e9c50000000000000000000000005842aa91fde70566883c12b07ec700792630e9c500000000000000000000000000000000000000000000000000c86e454d307f3900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc139276ff0be2dd9485d24c8e33e1c0b9d2e2df000000000000000000000000cc139276ff0be2dd9485d24c8e33e1c0b9d2e2df000000000000000000000000000000000000000000000000003bb36eb25045e100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6912,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad5b935a336fa91d049a07071cc80b22625377ad000000000000000000000000ad5b935a336fa91d049a07071cc80b22625377ad000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9b8bc71e8d0a948c90e776db9986f394cc65a23000000000000000000000000c9b8bc71e8d0a948c90e776db9986f394cc65a2300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6914,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000699db59f23d4fc9aeb9dc770eb3f30e84cc5acf1000000000000000000000000699db59f23d4fc9aeb9dc770eb3f30e84cc5acf100000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f79ed2e7846523719875fb10a6b0cd1ea40c05cc000000000000000000000000f79ed2e7846523719875fb10a6b0cd1ea40c05cc0000000000000000000000000000000000000000000000000c81d245ac433fc400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008dd42c713d06633f2bbcc9f7571d0cdb0a20777c0000000000000000000000008dd42c713d06633f2bbcc9f7571d0cdb0a20777c00000000000000000000000000000000000000000000000000489c6d7a469c0b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000eac4899b7ab841ad7d68550b43d877aab93f143b000000000000000000000000eac4899b7ab841ad7d68550b43d877aab93f143b0000000000000000000000000000000000000000000000000000000002faefbc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +6918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ace8be2bbf60b8d8beb956175eff03e49240ee5e000000000000000000000000ace8be2bbf60b8d8beb956175eff03e49240ee5e000000000000000000000000000000000000000000000000010d0beb5dd7a1a000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094dcb38e3901a0d2a6d1bbf8fe232d626632571900000000000000000000000094dcb38e3901a0d2a6d1bbf8fe232d626632571900000000000000000000000000000000000000000000000000833461775ce5b700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6922,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d2dea9c4cdced177021f25a879d3cbf4c89e46d0000000000000000000000004d2dea9c4cdced177021f25a879d3cbf4c89e46d00000000000000000000000000000000000000000000000000000433cd2b250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3907cef128f29a4c20a53ef803039a8ceb3db40000000000000000000000000d3907cef128f29a4c20a53ef803039a8ceb3db40000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d7f3e7477509e5aaef96cc8c45879b6de3414860000000000000000000000001d7f3e7477509e5aaef96cc8c45879b6de34148600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0be25bbaf45c32f1b494ad1428570cda54ffbbb000000000000000000000000e0be25bbaf45c32f1b494ad1428570cda54ffbbb00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000634c994e9f1945016d90d30d540971fade8b26f8000000000000000000000000634c994e9f1945016d90d30d540971fade8b26f8000000000000000000000000000000000000000000000000001e4a70ab4c0c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005113260b89790bcf675083fece6c66ce6ab3b6390000000000000000000000005113260b89790bcf675083fece6c66ce6ab3b63900000000000000000000000000000000000000000000000000a4f784696b1de400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6928,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1240655fe99f9e8f225258bd1d664a030ad46de000000000000000000000000e1240655fe99f9e8f225258bd1d664a030ad46de000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6929,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5ad56a8708f50ba9e0cef123bfaa4684f6c7331000000000000000000000000b5ad56a8708f50ba9e0cef123bfaa4684f6c73310000000000000000000000000000000000000000000000000092ba219539400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013a875ea21c9f2f599f667a02ee90f4758f1c87300000000000000000000000013a875ea21c9f2f599f667a02ee90f4758f1c87300000000000000000000000000000000000000000000000000ba1352924c125800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6932,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040333b174f38dbdc909b7e2763e7764e133fbaf600000000000000000000000040333b174f38dbdc909b7e2763e7764e133fbaf600000000000000000000000000000000000000000000000000a8661a217bcd2200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6933,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdc3a9a543aa7029085dc500d639f0868be7eaea000000000000000000000000bdc3a9a543aa7029085dc500d639f0868be7eaea00000000000000000000000000000000000000000000000000a8660c825a800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbd0fd524ef9c6c721476e31ef9737967588586e6f861991cf0d29ff3047b2a91,2021-12-12 03:23:38.000 UTC,0,true +6936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000685704e8a92c1f57e0c697697738412886ccb6e3000000000000000000000000685704e8a92c1f57e0c697697738412886ccb6e3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6937,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000575ab966f12c09eee2fd0888b63ed81115088269000000000000000000000000575ab966f12c09eee2fd0888b63ed8111508826900000000000000000000000000000000000000000000000000438600020ad40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2654cbb590daa9a2b7dcbdc2e24fc6ac3a46fa0f407f23819944d09be23ac5d3,2022-03-04 10:22:14.000 UTC,0,true +6938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5c1cbb2717cb644b7c84cce6519c58e560ee007000000000000000000000000e5c1cbb2717cb644b7c84cce6519c58e560ee0070000000000000000000000000000000000000000000000000097d9e0ad74360800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043a2ec2991f189cff8c024fb34a3fce9a33c5ae200000000000000000000000043a2ec2991f189cff8c024fb34a3fce9a33c5ae2000000000000000000000000000000000000000000000000003d25828834f8e100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000029fca5052da9b93b2b25809135022ec36735599500000000000000000000000029fca5052da9b93b2b25809135022ec367355995000000000000000000000000000000000000000000000000000000000851572900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +6941,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003de35c78f166828a9723d1b9d29a54bc159b3aa70000000000000000000000003de35c78f166828a9723d1b9d29a54bc159b3aa70000000000000000000000000000000000000000000000000014cabbedd3f80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6942,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004375c14f100c563dd92b34f8fb41e764e7c9f3530000000000000000000000004375c14f100c563dd92b34f8fb41e764e7c9f35300000000000000000000000000000000000000000000000000cd63f6b2e62e4f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000705c7909e5d4b833778cb95fee849c7dff1d0681000000000000000000000000705c7909e5d4b833778cb95fee849c7dff1d068100000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6944,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ef0430c20044bf343e26edfdd992c67807cf64d0000000000000000000000003ef0430c20044bf343e26edfdd992c67807cf64d00000000000000000000000000000000000000000000000000a64fddbdf7280200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6946,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000afa841fab90d5b2f68d04799ed35a458d856d1e5000000000000000000000000afa841fab90d5b2f68d04799ed35a458d856d1e5000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6949,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf207d607ffd7c7174b997a879125e5301c526af000000000000000000000000cf207d607ffd7c7174b997a879125e5301c526af00000000000000000000000000000000000000000000000000350647ebd9f85400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6950,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dccede7fc9210649eb6e593aeb351f89adb92831000000000000000000000000dccede7fc9210649eb6e593aeb351f89adb92831000000000000000000000000000000000000000000000000027f7d0bdb92000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6951,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000cf64a18bc553eb5a8c97ced14799223d2e37e53d000000000000000000000000000000000000000000000000a81ed803516f8775,,,1,true +6952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be13517a2b520b2449068d2ec45280992b04047b000000000000000000000000be13517a2b520b2449068d2ec45280992b04047b000000000000000000000000000000000000000000000000003f37cc711c78e300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1be60a3dd728c15004344ace9039dae426a707b000000000000000000000000a1be60a3dd728c15004344ace9039dae426a707b00000000000000000000000000000000000000000000000000c3c5d5f6376d7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5a8c6a35ba00a69fe63451d4ba267eea1c69d5f70f1659d7dc2b3884e44c5f59,2021-12-15 09:51:43.000 UTC,0,true +6954,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f54c655ac5f39b5f5d9e0f843d3150d9730eb33a000000000000000000000000f54c655ac5f39b5f5d9e0f843d3150d9730eb33a0000000000000000000000000000000000000000000000000a2874de7c7be64f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1cd6cd0b9a28eba0eb249794f1440bf64f35988cd0ddedfa94ecea721719f64a,2021-11-23 07:58:16.000 UTC,0,true +6956,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6ec83200fa6f55a3ada624e074e599d74cffa86000000000000000000000000e6ec83200fa6f55a3ada624e074e599d74cffa8600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006df6f687918352b0a8548e6e4770ae97888c18d80000000000000000000000006df6f687918352b0a8548e6e4770ae97888c18d8000000000000000000000000000000000000000000000000001133316a91286f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003db3065790799c9d8e8c64a2b9148b81f2fa06540000000000000000000000003db3065790799c9d8e8c64a2b9148b81f2fa06540000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a78589943301b0ba9f41a24068cf46531feb37c3000000000000000000000000a78589943301b0ba9f41a24068cf46531feb37c3000000000000000000000000000000000000000000000000003efed42c129d8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000033469566baf1484f2e65b747a4eae1296d33db4000000000000000000000000033469566baf1484f2e65b747a4eae1296d33db4000000000000000000000000000000000000000000000000004293d094d5213500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f9976003c160d52905f143cda321ad4007dbb730000000000000000000000007f9976003c160d52905f143cda321ad4007dbb73000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000070c2fd9fe3d7c927a90b3e28d561d30c6412384800000000000000000000000070c2fd9fe3d7c927a90b3e28d561d30c64123848000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6967,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa1ac469e3868e8852d396d901e4adeeec6560c8000000000000000000000000aa1ac469e3868e8852d396d901e4adeeec6560c800000000000000000000000000000000000000000000000000188c3d9634eb8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075d2bfe4eb037c00cb6797ce803ef6b22e13485d00000000000000000000000075d2bfe4eb037c00cb6797ce803ef6b22e13485d000000000000000000000000000000000000000000000000009d11b489df795300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ae1254db23febf6b70d911ed68051011cf974f00000000000000000000000006ae1254db23febf6b70d911ed68051011cf974f0000000000000000000000000000000000000000000000000010a741a4627800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x98329802bae06e23ca6dd8af45f717b8f8a385f2d7340a2e78d5c1439b8bb361,2022-04-21 09:24:56.000 UTC,0,true +6971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f7028fc52f77cb3a17f8fbca6291197a93be9ee0000000000000000000000004f7028fc52f77cb3a17f8fbca6291197a93be9ee00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4880e59f3d4da1ea2202c71a7440ac3065c1a8d000000000000000000000000d4880e59f3d4da1ea2202c71a7440ac3065c1a8d00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea6887f2b7d9eac0149b13f1a61019cba4b8a512000000000000000000000000ea6887f2b7d9eac0149b13f1a61019cba4b8a51200000000000000000000000000000000000000000000000000193bdc8f3c7ac800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6979,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6edb0a8dec9e7dc90568d3bfe21ecfc7aacf974000000000000000000000000a6edb0a8dec9e7dc90568d3bfe21ecfc7aacf974000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6980,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3f09b35627af530077582052bffadd545123d39000000000000000000000000a3f09b35627af530077582052bffadd545123d39000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa308d5c5ff97708bf1bd5775a46ccfbe5dd027d000000000000000000000000fa308d5c5ff97708bf1bd5775a46ccfbe5dd027d000000000000000000000000000000000000000000000000005acd2d4b7f2f0d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064df66e938ad5cbc8f0de19684ab3e3af958d42400000000000000000000000064df66e938ad5cbc8f0de19684ab3e3af958d424000000000000000000000000000000000000000000000000001f0a0ffb20100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6984,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3d0d1322c8f24ce8d449514e2c9e95acbef9e38000000000000000000000000b3d0d1322c8f24ce8d449514e2c9e95acbef9e38000000000000000000000000000000000000000000000000000c1448303c800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1bc356915a235f748ae37a27a170ffecbc32474000000000000000000000000e1bc356915a235f748ae37a27a170ffecbc32474000000000000000000000000000000000000000000000000001629e6c5c0d65f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6986,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7f95b574bfcbe1a7d809ff628b5514ba8a1ba87000000000000000000000000b7f95b574bfcbe1a7d809ff628b5514ba8a1ba870000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ef15bcedc4886379fbbf27e5f4cd40228cf52ca0000000000000000000000003ef15bcedc4886379fbbf27e5f4cd40228cf52ca0000000000000000000000000000000000000000000000000014d797c6d4018500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6988,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001cd6d041d8881049488c0cd0d83637404abc433c0000000000000000000000001cd6d041d8881049488c0cd0d83637404abc433c000000000000000000000000000000000000000000000000005543df729c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fdddd15ced3b169ac8496ecfad78645c4ca27370000000000000000000000000fdddd15ced3b169ac8496ecfad78645c4ca2737000000000000000000000000000000000000000000000000007ee78a0be8366b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6991,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000678a3d4ce40e13ab864862db6728e38481f83865000000000000000000000000678a3d4ce40e13ab864862db6728e38481f83865000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c16ea242b5b063d7840d99be1c08088a63070280000000000000000000000003c16ea242b5b063d7840d99be1c08088a63070280000000000000000000000000000000000000000000000000009db6a87ff570a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000335396fc4c0ae063015af959c6815387e529fad4000000000000000000000000335396fc4c0ae063015af959c6815387e529fad40000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6995,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047f8f31858cc5e2325241451f7166f625d2ea0db00000000000000000000000047f8f31858cc5e2325241451f7166f625d2ea0db000000000000000000000000000000000000000000000000005b65568c96a4dd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6996,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1ddafb6de9c840c1d769c9a51ca27e65fbbb4df000000000000000000000000e1ddafb6de9c840c1d769c9a51ca27e65fbbb4df0000000000000000000000000000000000000000000000000099033cd65e2b7300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +6997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e42980f6b1c3c3c51833393d3e77082201644490000000000000000000000004e42980f6b1c3c3c51833393d3e7708220164449000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6f52ca45ad92cca6c2c1fac04ad1a141ace76ca0f20a673b12736a47a6cb4b12,2021-12-01 11:44:14.000 UTC,0,true +6999,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ad592ca81266c661717d23d3faa0077f2993bca0000000000000000000000005ad592ca81266c661717d23d3faa0077f2993bca0000000000000000000000000000000000000000000000000002c8e3b880c70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7000,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9a4b682d3a0134e9886ca4acbe02bcc879447fa000000000000000000000000f9a4b682d3a0134e9886ca4acbe02bcc879447fa000000000000000000000000000000000000000000000000003080a0d0b6dc4d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034a8166ce58363440aba38f0bbcddfb99b282c5500000000000000000000000034a8166ce58363440aba38f0bbcddfb99b282c550000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7005,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce5d510ca05f897cd489e03276ce680344005bcd000000000000000000000000ce5d510ca05f897cd489e03276ce680344005bcd00000000000000000000000000000000000000000000000001540b4286588eed00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7008,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000160da53315b0b84317c97b0e400a74f0d0e5476c000000000000000000000000160da53315b0b84317c97b0e400a74f0d0e5476c000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7009,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006db5f521fd5117733f774dd9ee0325ccbf8c1d190000000000000000000000006db5f521fd5117733f774dd9ee0325ccbf8c1d19000000000000000000000000000000000000000000000000004a9b638448800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001db2c763aa6a2951de67f63003c126dede0d56050000000000000000000000001db2c763aa6a2951de67f63003c126dede0d56050000000000000000000000000000000000000000000000000002525078dc830000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7012,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6091be65c67346421fad6b626dc4bedd6f1f21e000000000000000000000000c6091be65c67346421fad6b626dc4bedd6f1f21e0000000000000000000000000000000000000000000000000002075ce615df0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d8586fa8844e678e257cfbed87bd84df2dc49602000000000000000000000000d8586fa8844e678e257cfbed87bd84df2dc496020000000000000000000000000000000000000000000000000007e2d1050b060f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7014,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd0ce2f515c2c0a3e553014ac1ed44843b5515c1000000000000000000000000bd0ce2f515c2c0a3e553014ac1ed44843b5515c1000000000000000000000000000000000000000000000000009d2803a7744f1b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7015,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e05d64b0e6226d31845b01458e405bccaec5b5f0000000000000000000000005e05d64b0e6226d31845b01458e405bccaec5b5f00000000000000000000000000000000000000000000000000017902d418c80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7016,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002bfc44dbbccd59e3cbd85ae8c019ff381e5601ef0000000000000000000000002bfc44dbbccd59e3cbd85ae8c019ff381e5601ef0000000000000000000000000000000000000000000000000001a6e07a55340000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7017,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fde131f300b1b4d142860c919e4f426c2c521389000000000000000000000000fde131f300b1b4d142860c919e4f426c2c5213890000000000000000000000000000000000000000000000000001a6e07a55340000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7018,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ffc746c826cd4386c722773b7bb859d49f5edf30000000000000000000000007ffc746c826cd4386c722773b7bb859d49f5edf30000000000000000000000000000000000000000000000000041a9716845dc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7019,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9e34dbebb9b4f900ac0e763042ea42ea16016e8000000000000000000000000a9e34dbebb9b4f900ac0e763042ea42ea16016e80000000000000000000000000000000000000000000000000001ad0793c1360000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055e6569cf39fba89d321055eb3706fabb715337700000000000000000000000055e6569cf39fba89d321055eb3706fabb7153377000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b39722c490406f5ee58f347d962c2e1db91da570000000000000000000000002b39722c490406f5ee58f347d962c2e1db91da570000000000000000000000000000000000000000000000000005fd1512ce265c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005ebb8027fa5a9faaa289cda2e6ffbdee82cd71000000000000000000000000005ebb8027fa5a9faaa289cda2e6ffbdee82cd710000000000000000000000000000000000000000000000000009a40ffab0f118500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007af8c067719f38f324ecd3fa99431178160ff0230000000000000000000000007af8c067719f38f324ecd3fa99431178160ff0230000000000000000000000000000000000000000000000000001cca1dc26290000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009531246b6beae6ae8f778aa576c477dd214a7c530000000000000000000000009531246b6beae6ae8f778aa576c477dd214a7c5300000000000000000000000000000000000000000000000000000e4790a1f50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001778a453a689e347e623208e46d7365fed31a6fd0000000000000000000000001778a453a689e347e623208e46d7365fed31a6fd000000000000000000000000000000000000000000000000000008f7407edc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b2c36e80f45ab84b11cec92e468cffd79d510bf0000000000000000000000002b2c36e80f45ab84b11cec92e468cffd79d510bf000000000000000000000000000000000000000000000000000178bb3bab250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e025f492e4e635126861039783d960c575905f43000000000000000000000000e025f492e4e635126861039783d960c575905f4300000000000000000000000000000000000000000000000000957ead4d10083f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8f6fb663954aa3229c366307aad2fa4190464aa000000000000000000000000f8f6fb663954aa3229c366307aad2fa4190464aa0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7031,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090fba8deb4857adb55f5f211cb7c8ab6efd8b05900000000000000000000000090fba8deb4857adb55f5f211cb7c8ab6efd8b05900000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7032,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f1a0d5de668ddb632145df59baa81cbbf5767b60000000000000000000000008f1a0d5de668ddb632145df59baa81cbbf5767b600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c953b9ca9cf6dd7a1cb526537f8f7f8d61a01ff0000000000000000000000008c953b9ca9cf6dd7a1cb526537f8f7f8d61a01ff00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7034,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b30367238ac1da91b0cf31bb4b0b4efb777488e5000000000000000000000000b30367238ac1da91b0cf31bb4b0b4efb777488e5000000000000000000000000000000000000000000000000005543df729c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ff598ed5e0a5c1790bfe210d0a61d077f6e83ab0000000000000000000000009ff598ed5e0a5c1790bfe210d0a61d077f6e83ab00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7036,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009453620d6e882a7018a3ee9a4ec2b1fca5d0205c0000000000000000000000009453620d6e882a7018a3ee9a4ec2b1fca5d0205c000000000000000000000000000000000000000000000000008cf5bc9790ca3900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7037,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000336bdf7a8dc958ca317197b764a29eae90c14f7d000000000000000000000000336bdf7a8dc958ca317197b764a29eae90c14f7d000000000000000000000000000000000000000000000000005ac3a30356e6a700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7040,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000dea777f50b238bdb932cde9453ed8a8c2ce34e17000000000000000000000000dea777f50b238bdb932cde9453ed8a8c2ce34e170000000000000000000000000000000000000000000000008af3e5acfad6006800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7041,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000767a60f295aedd958932088f9cd6a4951d8739b6000000000000000000000000767a60f295aedd958932088f9cd6a4951d8739b6000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3186d9e91f3dfd4c6ca5bc5cf928b74bb590ae9a39c28683f6c6f00d9ac09bcd,2022-03-01 09:35:19.000 UTC,0,true +7042,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8c3eb10a717183b6c23bf785bedc147f5296b55000000000000000000000000e8c3eb10a717183b6c23bf785bedc147f5296b55000000000000000000000000000000000000000000000000008fe731254cd5a900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7045,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001085498ad079c5e2ead3a2b4262aa164194c36b00000000000000000000000001085498ad079c5e2ead3a2b4262aa164194c36b00000000000000000000000000000000000000000000000000051f06e54c05ed100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7047,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079b1a68f67de6625433e79665fd00e2ffc7e02c100000000000000000000000079b1a68f67de6625433e79665fd00e2ffc7e02c100000000000000000000000000000000000000000000000001388244fc0fb70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7049,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b30367238ac1da91b0cf31bb4b0b4efb777488e5000000000000000000000000b30367238ac1da91b0cf31bb4b0b4efb777488e5000000000000000000000000000000000000000000000000004a9b638448800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a33a46408c871c0c4d172e8036dfcdcb19e6f226000000000000000000000000a33a46408c871c0c4d172e8036dfcdcb19e6f226000000000000000000000000000000000000000000000000005824934da52a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000448e1bee08d6fab78160762beb05a3672ddea0b2000000000000000000000000448e1bee08d6fab78160762beb05a3672ddea0b200000000000000000000000000000000000000000000000002c5bf8e1616543900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7052,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b03ec0b8ef92c5f7ee5c95c442850eeb0b3cc358000000000000000000000000b03ec0b8ef92c5f7ee5c95c442850eeb0b3cc358000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028011e8364199981caf8c2bad99f9462faa0141700000000000000000000000028011e8364199981caf8c2bad99f9462faa0141700000000000000000000000000000000000000000000000000471b6843f2f94500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f619fc95d58b25b708f36a6452760314bf8bb173000000000000000000000000f619fc95d58b25b708f36a6452760314bf8bb173000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7055,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073c17da35fb211b7c0eef1b474b560b01d9a0a4c00000000000000000000000073c17da35fb211b7c0eef1b474b560b01d9a0a4c0000000000000000000000000000000000000000000000000002c3b3d3f77b9f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7056,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000618aa9d95c4119d623be6a40f6b7f543d12e97e8000000000000000000000000618aa9d95c4119d623be6a40f6b7f543d12e97e80000000000000000000000000000000000000000000000000048d3d165e7bc7400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f33734d47761b1578f20808714adf2a669d23a80000000000000000000000005f33734d47761b1578f20808714adf2a669d23a8000000000000000000000000000000000000000000000000004fefa17b72400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7058,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc41150bbe0c60c40473c2864f0fed89732d311c000000000000000000000000bc41150bbe0c60c40473c2864f0fed89732d311c000000000000000000000000000000000000000000000000023595f03635285f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fee6f809f099b91639a7070b30aaaf3f45d313ca000000000000000000000000fee6f809f099b91639a7070b30aaaf3f45d313ca000000000000000000000000000000000000000000000000000a9d8dbd2e8a4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9a393258d34d4b26bd456d727117900ef38f37c000000000000000000000000e9a393258d34d4b26bd456d727117900ef38f37c0000000000000000000000000000000000000000000000000008e0cd9f2c5d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7062,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011bccb4b866b7a0c46d488d1531f80b9253b7bd200000000000000000000000011bccb4b866b7a0c46d488d1531f80b9253b7bd20000000000000000000000000000000000000000000000000012eaf211246fcb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7063,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000001be549fa377710b9e59d57bbdf593ce1e379ca0000000000000000000000000000000000000000000000006124fee993bc0000,,,1,true +7065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f12bb7b027e51baa96dd0f4c78e2bdf2b24da26a000000000000000000000000f12bb7b027e51baa96dd0f4c78e2bdf2b24da26a000000000000000000000000000000000000000000000000001b0ca02bffdb8100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7068,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000573c78a4a1fe8e77ffd340fb5e42c8b80d6e6009000000000000000000000000000000000000000000000000ea9ab5eafbc77b66,,,1,true +7069,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002746976a56c7778a55ad115fc7c1c87e02d357790000000000000000000000002746976a56c7778a55ad115fc7c1c87e02d35779000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7071,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009cbf67c82ba7b1ebf45731c360582de85a5e9dcb0000000000000000000000009cbf67c82ba7b1ebf45731c360582de85a5e9dcb000000000000000000000000000000000000000000000000001258caf0404f9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7072,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068a6dde19e0f736f0eba178807c1cb8e8e7782d600000000000000000000000068a6dde19e0f736f0eba178807c1cb8e8e7782d60000000000000000000000000000000000000000000000000092073f315d620100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7073,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c94fa7be6e276d699bcd1587a172bf5f32e7657a000000000000000000000000c94fa7be6e276d699bcd1587a172bf5f32e7657a0000000000000000000000000000000000000000000000000052d123f99ab50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7074,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d25e30c27841514e0bf05d7f6f0d0f6d87dde740000000000000000000000002d25e30c27841514e0bf05d7f6f0d0f6d87dde74000000000000000000000000000000000000000000000000006405fb87107b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006fe1911c5bacbc593e558ac33212176f1c12b6590000000000000000000000006fe1911c5bacbc593e558ac33212176f1c12b6590000000000000000000000000000000000000000000000000064590b5e42960000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa2d70ff6fe9ef712f21e182c4590a03a5d9f01b000000000000000000000000aa2d70ff6fe9ef712f21e182c4590a03a5d9f01b0000000000000000000000000000000000000000000000000063e1e7b7d1580000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7077,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c352439a276f26684195a49afeb116e99059fd64000000000000000000000000c352439a276f26684195a49afeb116e99059fd6400000000000000000000000000000000000000000000000000641900042fc70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cfef319625be2d783978a554b2e4a340e64e3a10000000000000000000000004cfef319625be2d783978a554b2e4a340e64e3a100000000000000000000000000000000000000000000000000641900042fc70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e3625b95ffbc956a2ae5573fc446c1a04aa08de0000000000000000000000004e3625b95ffbc956a2ae5573fc446c1a04aa08de00000000000000000000000000000000000000000000000000641900042fc70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b404c6e33fb20f5e576a5530afdbc846edc002f0000000000000000000000002b404c6e33fb20f5e576a5530afdbc846edc002f0000000000000000000000000000000000000000000000000064c47002b7160000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2ff704732987e191cf37918bd32701ca2a5849c000000000000000000000000e2ff704732987e191cf37918bd32701ca2a5849c00000000000000000000000000000000000000000000000000640e17cb7bf20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072bd148bbbb381fc0b248e832ad65db9b6ce20b600000000000000000000000072bd148bbbb381fc0b248e832ad65db9b6ce20b60000000000000000000000000000000000000000000000000063415ff1fdde0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000429f260fe1cdca577c7bd1f811e6931fd018dcd8000000000000000000000000429f260fe1cdca577c7bd1f811e6931fd018dcd800000000000000000000000000000000000000000000000000631459150a5b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7084,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003eeb932003862c0a12a7ace91d427dc254adf1570000000000000000000000003eeb932003862c0a12a7ace91d427dc254adf157000000000000000000000000000000000000000000000000006421ab7976840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7085,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f05ac484206b348b1fbb0094da58739a4ffdaab4000000000000000000000000f05ac484206b348b1fbb0094da58739a4ffdaab4000000000000000000000000000000000000000000000000001b9fce5c4fca0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d9c1715c66cbee0566f509b8db7344095d936220000000000000000000000009d9c1715c66cbee0566f509b8db7344095d936220000000000000000000000000000000000000000000000000038257e49ea5e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e798fa801e25858176c9c3f8586078a681c29c60000000000000000000000000e798fa801e25858176c9c3f8586078a681c29c600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052761ed75d8c14568a6c4b2964d7effed2fb15d400000000000000000000000052761ed75d8c14568a6c4b2964d7effed2fb15d40000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7092,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000073ce4c69c1e4b26b324f62da4a2439bae8957d3800000000000000000000000000000000000000000000000006f05b59d3b20000,,,1,true +7093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b62d985c806e447ebdc1ec9666c0c3462323c240000000000000000000000006b62d985c806e447ebdc1ec9666c0c3462323c24000000000000000000000000000000000000000000000000000e3706c714751b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7098,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d8be8dcc4f78d4ecbdd77e260c113dbc17767a70000000000000000000000004d8be8dcc4f78d4ecbdd77e260c113dbc17767a7000000000000000000000000000000000000000000000000004a9b638448800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7099,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b918d6fab29ffcdbaa5d75e893c78bcdd1f08844000000000000000000000000b918d6fab29ffcdbaa5d75e893c78bcdd1f088440000000000000000000000000000000000000000000000000072be0627831cc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000334bc680d521d64f48bd09b10bd24e598dc0da0d000000000000000000000000334bc680d521d64f48bd09b10bd24e598dc0da0d00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7102,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000014987ba7b4dfdadbde5c4b43089e0c47110cbd970000000000000000000000000000000000000000000000002eef165df63b9e0a,,,1,true +7104,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b1a2d3b948c1dd866c66c986e8637fb715df42a0000000000000000000000006b1a2d3b948c1dd866c66c986e8637fb715df42a00000000000000000000000000000000000000000000000000053c8c8a01dc9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b29607ded2d70f962406685bbb59dc7028dcc2b0000000000000000000000000b29607ded2d70f962406685bbb59dc7028dcc2b000000000000000000000000000000000000000000000000000636fa33c609d500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7106,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf8ed0fae2a2a37b131b7891d525bb992eefa744000000000000000000000000bf8ed0fae2a2a37b131b7891d525bb992eefa7440000000000000000000000000000000000000000000000000007ee5d4a2b1f9c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7111,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f08793c6e14d4d7f8baece3af748094aa2876858000000000000000000000000f08793c6e14d4d7f8baece3af748094aa28768580000000000000000000000000000000000000000000000000041b590c7ec497d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7112,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cabbb8207dd2bfaf3aa2b82ef62d710a2b168157000000000000000000000000cabbb8207dd2bfaf3aa2b82ef62d710a2b168157000000000000000000000000000000000000000000000000005fec5b60ef800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7113,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa1ebb3e079c6d7b516fc5beee64955c15e395f9000000000000000000000000aa1ebb3e079c6d7b516fc5beee64955c15e395f900000000000000000000000000000000000000000000000002de0591183342b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7114,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2fd5efb267cd7f7a0ba2af47fbabf53443fb36f000000000000000000000000d2fd5efb267cd7f7a0ba2af47fbabf53443fb36f00000000000000000000000000000000000000000000000000044364c5bb000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7115,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064a1ca8b4f19571ebc7d92ec8eb8d04fa4d63e1100000000000000000000000064a1ca8b4f19571ebc7d92ec8eb8d04fa4d63e1100000000000000000000000000000000000000000000000000101d87d0ba5fcd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7118,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022bd8c9e6a8485965c39fc99e83ebfd9a5ed5cfb00000000000000000000000022bd8c9e6a8485965c39fc99e83ebfd9a5ed5cfb0000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7119,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005c8ea2b3fbd168a291c59576505fc853d24631200000000000000000000000005c8ea2b3fbd168a291c59576505fc853d24631200000000000000000000000000000000000000000000000000cccaa5e32f811400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009adfe827e504a4cce2df5f5217f0749401e6c5b00000000000000000000000009adfe827e504a4cce2df5f5217f0749401e6c5b0000000000000000000000000000000000000000000000000147efdac48ea80700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000139f9efe062caaf5e967fb6eb9c569f017fe3520000000000000000000000000139f9efe062caaf5e967fb6eb9c569f017fe352000000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4a65de4593362c91579c62d78e3285bdb9115a4000000000000000000000000c4a65de4593362c91579c62d78e3285bdb9115a400000000000000000000000000000000000000000000000000195334b9b7c64000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e97cf541ecf916cde6907addad109e4dc973b98f000000000000000000000000e97cf541ecf916cde6907addad109e4dc973b98f00000000000000000000000000000000000000000000000000681b0bce31f0fa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7124,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d64f4c6d227d1e2c8fc9f90e0dad742ef77e7810000000000000000000000000d64f4c6d227d1e2c8fc9f90e0dad742ef77e78100000000000000000000000000000000000000000000000000eff3ab213357c700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffc6642e1fd5a2eb6853dcaac53bfef845d4daa8000000000000000000000000ffc6642e1fd5a2eb6853dcaac53bfef845d4daa800000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045b381a5b6ed9312926c1fac846696d33ae1c0db00000000000000000000000045b381a5b6ed9312926c1fac846696d33ae1c0db000000000000000000000000000000000000000000000000006e7d490483c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039eb58cd54b082766a99851706744f5b6724677c00000000000000000000000039eb58cd54b082766a99851706744f5b6724677c000000000000000000000000000000000000000000000000013b4cd34a49880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd750f5854ece8252fb7d59d4a8be7864241d50d000000000000000000000000cd750f5854ece8252fb7d59d4a8be7864241d50d00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dca9c88434ba8a6a7e23f2fc3eba2527af825e46000000000000000000000000dca9c88434ba8a6a7e23f2fc3eba2527af825e460000000000000000000000000000000000000000000000000159adf74f1b5c5600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b72c1c7a79b19f927781edacd19e6a9512a3554c000000000000000000000000b72c1c7a79b19f927781edacd19e6a9512a3554c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdc357a38867b05a3355c1345aba9bd3eb5cb935000000000000000000000000bdc357a38867b05a3355c1345aba9bd3eb5cb9350000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7136,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a4127b892653964ffefc9fab4809eabacc5acc77000000000000000000000000a4127b892653964ffefc9fab4809eabacc5acc770000000000000000000000000000000000000000000000da1af5dece48c942fe00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7137,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbb04ee9ed69ae934db51165aa95492fdb018d76000000000000000000000000cbb04ee9ed69ae934db51165aa95492fdb018d76000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7139,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ca1e244c6064993dc7cf86dd0b3375fcebd9d9e0000000000000000000000000ca1e244c6064993dc7cf86dd0b3375fcebd9d9e00000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e07f06b27d051924d918d76bbf10973c9fd5e8be000000000000000000000000e07f06b27d051924d918d76bbf10973c9fd5e8be000000000000000000000000000000000000000000000000018aef634863737900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000882a75525c81e70f1c712e4446287e636958b4e4000000000000000000000000882a75525c81e70f1c712e4446287e636958b4e40000000000000000000000000000000000000000000000000001d5dabedca1f400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7145,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049b48f5d813301700e22e654501156fb2d58c89800000000000000000000000049b48f5d813301700e22e654501156fb2d58c89800000000000000000000000000000000000000000000000000849d237080a93b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2ff8196b4ae960e3a1b533857f6f054bffa92fb000000000000000000000000f2ff8196b4ae960e3a1b533857f6f054bffa92fb00000000000000000000000000000000000000000000000001bb77495794ac5a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7147,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009730e08737d1a3d6364d76dafc4ab334d3f3430e0000000000000000000000009730e08737d1a3d6364d76dafc4ab334d3f3430e0000000000000000000000000000000000000000000000000020b44767ce6c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b30367238ac1da91b0cf31bb4b0b4efb777488e5000000000000000000000000b30367238ac1da91b0cf31bb4b0b4efb777488e5000000000000000000000000000000000000000000000000027f7d0bdb92000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a0a84be18cbe5dbaba7cfbe58d180288c3a08da0000000000000000000000009a0a84be18cbe5dbaba7cfbe58d180288c3a08da00000000000000000000000000000000000000000000000002086dbecadc164800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7150,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023c0bae29b2c92d90ebdf2b78ff86f1cb1bb667d00000000000000000000000023c0bae29b2c92d90ebdf2b78ff86f1cb1bb667d0000000000000000000000000000000000000000000000000b1a2bc2ec50000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc713097f3e7ffcbb4e60e4f4efee4a0ae8af234000000000000000000000000cc713097f3e7ffcbb4e60e4f4efee4a0ae8af234000000000000000000000000000000000000000000000000002511fd7970425500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7152,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc713097f3e7ffcbb4e60e4f4efee4a0ae8af234000000000000000000000000cc713097f3e7ffcbb4e60e4f4efee4a0ae8af2340000000000000000000000000000000000000000000000000073541deb5da5c100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5bd472975dd3e335541d84c0790cb836a70b7a4000000000000000000000000b5bd472975dd3e335541d84c0790cb836a70b7a4000000000000000000000000000000000000000000000000001db2fc28be00c700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7154,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000bee62d215c1bfb54aaa6a554f398b33056a7f120000000000000000000000000bee62d215c1bfb54aaa6a554f398b33056a7f120000000000000000000000000000000000000000000000000002b62809c0d20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7155,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eab112b9a150ab981fb9680ed89f7caaa3a9b7c0000000000000000000000000eab112b9a150ab981fb9680ed89f7caaa3a9b7c0000000000000000000000000000000000000000000000000014393708307005f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002973c156d9e4019bcb7e65e371c4d2755bcb02e40000000000000000000000002973c156d9e4019bcb7e65e371c4d2755bcb02e400000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7158,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f63a25197ae0715db718e9ec2e96620b3ba3f940000000000000000000000007f63a25197ae0715db718e9ec2e96620b3ba3f940000000000000000000000000000000000000000000000000034948586ad000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7460912011c86fc57bc49096f209e482b50cb36000000000000000000000000f7460912011c86fc57bc49096f209e482b50cb3600000000000000000000000000000000000000000000000000049e57d635400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7161,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6ffbf4428b1c4fe6ce1470d307a8ccac7887ce4000000000000000000000000f6ffbf4428b1c4fe6ce1470d307a8ccac7887ce40000000000000000000000000000000000000000000000000031bced02db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7162,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f521800ca503321dbfd319d0cb22693fbafbb161000000000000000000000000f521800ca503321dbfd319d0cb22693fbafbb1610000000000000000000000000000000000000000000000000006dd28a1ee2f4600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000877a891877d98c611e16bcf53fe64fa6a36c1bbb000000000000000000000000877a891877d98c611e16bcf53fe64fa6a36c1bbb000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7165,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000005ed6a87517914eb67cce0930fed72e61ce2d64450000000000000000000000005ed6a87517914eb67cce0930fed72e61ce2d6445000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000651291caa0ea151434c068a02d154f7a6e6fd139000000000000000000000000651291caa0ea151434c068a02d154f7a6e6fd139000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9649565e81d86679c570dc774fa70772cb3814c000000000000000000000000f9649565e81d86679c570dc774fa70772cb3814c000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7169,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b23168f076caca9563d814acd3f584cfc1401fd0000000000000000000000000b23168f076caca9563d814acd3f584cfc1401fd00000000000000000000000000000000000000000000000000031bced02db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7170,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d7ad1f4cf604ea8bf64d10d1d8e2d04076c49cb0000000000000000000000008d7ad1f4cf604ea8bf64d10d1d8e2d04076c49cb000000000000000000000000000000000000000000000000004406ed7f795b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7172,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f52157000356c034bba9e04707acf9a40ebd49a2000000000000000000000000f52157000356c034bba9e04707acf9a40ebd49a2000000000000000000000000000000000000000000000000012a5d84cea55a7f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000dc277d26a32808b9517ec5809164305f38ab2e30000000000000000000000000dc277d26a32808b9517ec5809164305f38ab2e3000000000000000000000000000000000000000000000000001f7dd87c6daa0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7175,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021606ee18fc1c9b398c25f56e98e6035ab43429900000000000000000000000021606ee18fc1c9b398c25f56e98e6035ab43429900000000000000000000000000000000000000000000000000080975a2e3d64700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b53547656127e8a43f686eeebf10d2c4229b3ec6000000000000000000000000b53547656127e8a43f686eeebf10d2c4229b3ec600000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000457787467c2f5600a7b70ac22cb27d206735bad0000000000000000000000000457787467c2f5600a7b70ac22cb27d206735bad0000000000000000000000000000000000000000000000000018649dfd2e6cb100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063baa2dc5597bcce4bbbf60f27901d726c34436c00000000000000000000000063baa2dc5597bcce4bbbf60f27901d726c34436c000000000000000000000000000000000000000000000000001f23832a19010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b777aba39f4194f2f1f43b6e6432252b6976a990000000000000000000000000b777aba39f4194f2f1f43b6e6432252b6976a9900000000000000000000000000000000000000000000000000a3f0f5562e547800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052704f183db6b8f526387dca0fb9f3ca911babc800000000000000000000000052704f183db6b8f526387dca0fb9f3ca911babc8000000000000000000000000000000000000000000000000001f74e56eb94a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7184,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a33a46408c871c0c4d172e8036dfcdcb19e6f226000000000000000000000000a33a46408c871c0c4d172e8036dfcdcb19e6f22600000000000000000000000000000000000000000000000000062db54b8b130000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9d8d43edcd9817db8ba5c4779cf2f2b431e6955000000000000000000000000d9d8d43edcd9817db8ba5c4779cf2f2b431e6955000000000000000000000000000000000000000000000000000c780476f6dc4500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7186,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071cc92c87c43e38bf6039a70ca9fdc39515aace600000000000000000000000071cc92c87c43e38bf6039a70ca9fdc39515aace600000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7188,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017b8042e8254d262fbaa6851be938e94aaec9f0100000000000000000000000017b8042e8254d262fbaa6851be938e94aaec9f0100000000000000000000000000000000000000000000000001472eacccfb4f1100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x24fbca117442e2a0bd805ce5f690f34bb568d44c2b1e6cb42ba451b422c62efc,2022-04-29 10:17:47.000 UTC,0,true +7189,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1eb054e725c69234b9c3ac321756dd3159201b0000000000000000000000000b1eb054e725c69234b9c3ac321756dd3159201b00000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7190,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9557fc2dead39953982973df776734f469ef20b000000000000000000000000b9557fc2dead39953982973df776734f469ef20b0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7192,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c83710dd670126ff42fcfb29a0a42114c8239eaa000000000000000000000000c83710dd670126ff42fcfb29a0a42114c8239eaa00000000000000000000000000000000000000000000000001d5d2c44a992b9300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7193,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095e6ddd5d0483157731629acbaf4df02172c093900000000000000000000000095e6ddd5d0483157731629acbaf4df02172c09390000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a87470c769608bbde6df513a7d1730be3afb8371000000000000000000000000a87470c769608bbde6df513a7d1730be3afb837100000000000000000000000000000000000000000000000000a6be51f94913a100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7196,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000248f4e6c5dcd9ef1892704770a93373bbad93154000000000000000000000000248f4e6c5dcd9ef1892704770a93373bbad931540000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7198,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbfbd5f3ba79c2ef8f121b871ac00ddd5bd19251000000000000000000000000fbfbd5f3ba79c2ef8f121b871ac00ddd5bd1925100000000000000000000000000000000000000000000000000ac2e9f5f8d340000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7200,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc078cb21b5772a12f1cff4e96eba3d13c4d390a000000000000000000000000bc078cb21b5772a12f1cff4e96eba3d13c4d390a0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7201,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069e1d848848c37d72526664535a6bf5a8bf8c63500000000000000000000000069e1d848848c37d72526664535a6bf5a8bf8c6350000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7202,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cebc634afdeb7b151c38561dddbb65d594e074e4000000000000000000000000cebc634afdeb7b151c38561dddbb65d594e074e400000000000000000000000000000000000000000000000000ae6b62cca5340000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7203,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099fbca51e564b974a573a3e49ffadecefe3fcbab00000000000000000000000099fbca51e564b974a573a3e49ffadecefe3fcbab00000000000000000000000000000000000000000000000000670758aa7c800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7205,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000326691f419883359a641ae9488042b1ebce7c9e0000000000000000000000000326691f419883359a641ae9488042b1ebce7c9e0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ee4a248cd7000bb93e60afbc9dcdce485b75fb30000000000000000000000000ee4a248cd7000bb93e60afbc9dcdce485b75fb30000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fff73f5a1f6c01902bde607ffcc9de8f0e64ea2c000000000000000000000000fff73f5a1f6c01902bde607ffcc9de8f0e64ea2c00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009caac316559a88a8dfa585e4b9ac9969248e2fd80000000000000000000000009caac316559a88a8dfa585e4b9ac9969248e2fd8000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa8e079c420d8b950129b5a007bd4374673cae65000000000000000000000000aa8e079c420d8b950129b5a007bd4374673cae65000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7211,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac273a987cd2f8dec4a0eb5be71029f7cb97b769000000000000000000000000ac273a987cd2f8dec4a0eb5be71029f7cb97b76900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7212,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f92d581df7f9396e014d481d44102227d90cd570000000000000000000000002f92d581df7f9396e014d481d44102227d90cd570000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7213,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008eb9cb5ab64d04f1b92dd0b548be4335f34419550000000000000000000000008eb9cb5ab64d04f1b92dd0b548be4335f34419550000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7214,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000259c84808553bb13458703882dd14a8a03639231000000000000000000000000259c84808553bb13458703882dd14a8a0363923100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000259c84808553bb13458703882dd14a8a03639231000000000000000000000000259c84808553bb13458703882dd14a8a0363923100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac273a987cd2f8dec4a0eb5be71029f7cb97b769000000000000000000000000ac273a987cd2f8dec4a0eb5be71029f7cb97b76900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099d218d6de7f4f0b3166c16d4efd46a19aa276a700000000000000000000000099d218d6de7f4f0b3166c16d4efd46a19aa276a7000000000000000000000000000000000000000000000000015e432ee4a0590000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7220,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008460328a53fd608713a12c2b3ea35124a077b9c00000000000000000000000008460328a53fd608713a12c2b3ea35124a077b9c0000000000000000000000000000000000000000000000000001f974bab669b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x659bc230587386912c40fb39a5f9c6c0fa0d6238aec64b0637717eddb37b857a,2022-08-27 06:30:24.000 UTC,0,true +7221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f09ab3dac50e4f2e4dc2f5b9f4dbcd50c27341ed000000000000000000000000f09ab3dac50e4f2e4dc2f5b9f4dbcd50c27341ed00000000000000000000000000000000000000000000000000228ebe2b2312e600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7223,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047de76492cf9fc04a01dbe042c3b39d95709063900000000000000000000000047de76492cf9fc04a01dbe042c3b39d957090639000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7224,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de55ae6ea569f75c955e5f3d551b4682732d5b11000000000000000000000000de55ae6ea569f75c955e5f3d551b4682732d5b11000000000000000000000000000000000000000000000000001fd7e63654b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086250c2ca9aa91e66cf6ec2925278ce89b89fe1a00000000000000000000000086250c2ca9aa91e66cf6ec2925278ce89b89fe1a000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7226,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024acce6cd49ab809deb477bfee50338554a6dbeb00000000000000000000000024acce6cd49ab809deb477bfee50338554a6dbeb000000000000000000000000000000000000000000000000005c5edcbc29000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7229,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000702f776f5943784c4a9040c886cac15a76d22729000000000000000000000000702f776f5943784c4a9040c886cac15a76d22729000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7230,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036410ae136e07af5c99ccf97c8e9398558f82b5400000000000000000000000036410ae136e07af5c99ccf97c8e9398558f82b54000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7231,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f80f38152c9e55ce951fd25bf8a0ac43e0fd29a0000000000000000000000000f80f38152c9e55ce951fd25bf8a0ac43e0fd29a0000000000000000000000000000000000000000000000000086c7ec2f7a958000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be7ae762dc142a1b4a56e36ed86dc90ba3484b44000000000000000000000000be7ae762dc142a1b4a56e36ed86dc90ba3484b4400000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad0610250a14faa0cb46fd65a5e0f69613f2e623000000000000000000000000ad0610250a14faa0cb46fd65a5e0f69613f2e6230000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e4762e9ee58589b0f2cbc5fe2dec55e27086d6c0000000000000000000000004e4762e9ee58589b0f2cbc5fe2dec55e27086d6c00000000000000000000000000000000000000000000000000000a3b5840f40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017fcdf505d90821be2c1cc9defa930153e73e7a700000000000000000000000017fcdf505d90821be2c1cc9defa930153e73e7a700000000000000000000000000000000000000000000000000000b242ce6040000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7237,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001094bbe0bb8cbfa94d549df5ce122020f6add50a0000000000000000000000001094bbe0bb8cbfa94d549df5ce122020f6add50a0000000000000000000000000000000000000000000000000000143c7b58a40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000438bf64cf9c6c23c1b5263dc85100dd3b4fe801a000000000000000000000000438bf64cf9c6c23c1b5263dc85100dd3b4fe801a0000000000000000000000000000000000000000000000000000143c7b58a40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ba2666ee8376a2134551c85e5415cb19c67f8fb0000000000000000000000008ba2666ee8376a2134551c85e5415cb19c67f8fb0000000000000000000000000000000000000000000000000000143c7b58a40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a6d4517c7a00089ee0ea54a6fffd59d4180ef800000000000000000000000001a6d4517c7a00089ee0ea54a6fffd59d4180ef800000000000000000000000000000000000000000000000000063648aa216748000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7241,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c4497fffdcfe9a5ce1de09c1b4b4623fd158c130000000000000000000000003c4497fffdcfe9a5ce1de09c1b4b4623fd158c130000000000000000000000000000000000000000000000000000143c7b58a40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7242,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c5bf796b9ce740d8f7132e5da6ab04aa76467e30000000000000000000000003c5bf796b9ce740d8f7132e5da6ab04aa76467e30000000000000000000000000000000000000000000000000000143c7b58a40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088b1c5da745171d7fca547972d28fa7b0646870000000000000000000000000088b1c5da745171d7fca547972d28fa7b06468700000000000000000000000000000000000000000000000000001818c7d0cdd73800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7245,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b34070951e16b87dce3d6421629dbf9a4a932610000000000000000000000008b34070951e16b87dce3d6421629dbf9a4a9326100000000000000000000000000000000000000000000000000001d54c9cb440000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000103324828119cce56ccb05208079b5462a5904d3000000000000000000000000103324828119cce56ccb05208079b5462a5904d300000000000000000000000000000000000000000000000000001d54c9cb440000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7247,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f45e4a6564ac682461d6389aceb034277a224f80000000000000000000000009f45e4a6564ac682461d6389aceb034277a224f800000000000000000000000000000000000000000000000000001d54c9cb440000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fecdddff12ce2dff360fbc34235867d10212a9c2000000000000000000000000fecdddff12ce2dff360fbc34235867d10212a9c200000000000000000000000000000000000000000000000000001d54c9cb440000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5901d9007c4b4a06151378276822e4bba8839af000000000000000000000000b5901d9007c4b4a06151378276822e4bba8839af00000000000000000000000000000000000000000000000000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099738d3492513ac17750a235544eadadf753e11f00000000000000000000000099738d3492513ac17750a235544eadadf753e11f00000000000000000000000000000000000000000000000000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7252,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa4877ee2154d7b1c3119d15c6f6e12456c360ff000000000000000000000000fa4877ee2154d7b1c3119d15c6f6e12456c360ff00000000000000000000000000000000000000000000000000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082fe7f91b2a685457429a3a15a6153aed4a3d03000000000000000000000000082fe7f91b2a685457429a3a15a6153aed4a3d03000000000000000000000000000000000000000000000000000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7254,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c3ea3451399f27851700d3be86fa131c7c319130000000000000000000000002c3ea3451399f27851700d3be86fa131c7c3191300000000000000000000000000000000000000000000000000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd4fa60bfc1acf77ecc8cbe12cfd8eb99de3fca2000000000000000000000000bd4fa60bfc1acf77ecc8cbe12cfd8eb99de3fca200000000000000000000000000000000000000000000000000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054c98e9bfc80e365630fbc32c730fa14bcea643e00000000000000000000000054c98e9bfc80e365630fbc32c730fa14bcea643e00000000000000000000000000000000000000000000000000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7257,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003198097c3afc75144d36f860b2d85a0c1798d1d20000000000000000000000003198097c3afc75144d36f860b2d85a0c1798d1d200000000000000000000000000000000000000000000000000bbfd820f1b5f3e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008dd42c713d06633f2bbcc9f7571d0cdb0a20777c0000000000000000000000008dd42c713d06633f2bbcc9f7571d0cdb0a20777c000000000000000000000000000000000000000000000000000388b973d44e8600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7260,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000decdae05f91aa2729e1347c09f5877c52c83fa56000000000000000000000000decdae05f91aa2729e1347c09f5877c52c83fa5600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7261,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fca81a8257d78e5c3520e94dc34d6ee9f6937b40000000000000000000000001fca81a8257d78e5c3520e94dc34d6ee9f6937b40000000000000000000000000000000000000000000000000047bf0f79fe991600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7262,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000456ec7f61e3821bd589b0b12f86706f7ad489a6f000000000000000000000000456ec7f61e3821bd589b0b12f86706f7ad489a6f0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1f69449730e70e4f85fa878307d73ed69bd9b16000000000000000000000000c1f69449730e70e4f85fa878307d73ed69bd9b160000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7264,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b00af2f40f5f581a78d93c803e7b90aebc21139b000000000000000000000000b00af2f40f5f581a78d93c803e7b90aebc21139b000000000000000000000000000000000000000000000000004952c17d1caf3a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7265,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002bdf1a400eb0b46bcc9919b712ef231126a9e37e0000000000000000000000002bdf1a400eb0b46bcc9919b712ef231126a9e37e0000000000000000000000000000000000000000000000000059a421015de11d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7266,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096f0ce0e9cc9fdba644341d7c5fb5fad5eb8d3c400000000000000000000000096f0ce0e9cc9fdba644341d7c5fb5fad5eb8d3c400000000000000000000000000000000000000000000000000074464494a4cd600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7267,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015a2adfe8e91a077198d0ecd2614b34c894f6af100000000000000000000000015a2adfe8e91a077198d0ecd2614b34c894f6af1000000000000000000000000000000000000000000000000003ff2e795f5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038333730107be4c1ec0249326b5f5616c151330f00000000000000000000000038333730107be4c1ec0249326b5f5616c151330f0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d3d44ce35875cbe8f9b26b9456c658e8ff019590000000000000000000000004d3d44ce35875cbe8f9b26b9456c658e8ff01959000000000000000000000000000000000000000000000000001429cafd7e831e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7271,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000015635645dca64c04a239c453a10ec5cf4a7e2ad000000000000000000000000015635645dca64c04a239c453a10ec5cf4a7e2ad000000000000000000000000000000000000000000000000003e2c284391c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b93f432baa191c5452d783e473f0b24a2f9631c0000000000000000000000005b93f432baa191c5452d783e473f0b24a2f9631c0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001923ccd42a7ef8cb10898bbdfb927a4db3eb36000000000000000000000000001923ccd42a7ef8cb10898bbdfb927a4db3eb36000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c137489cc02fe09e95d3f98f94d9ad832df67b70000000000000000000000003c137489cc02fe09e95d3f98f94d9ad832df67b700000000000000000000000000000000000000000000000001581cf87716812500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000edd6041b630ae6606296f7d656adae8f8f3037f0000000000000000000000000edd6041b630ae6606296f7d656adae8f8f3037f0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7278,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a068efbc6e7debac6465204b64c2f4f29152364e000000000000000000000000a068efbc6e7debac6465204b64c2f4f29152364e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b4a625a5bda77d9fa03e3cfc0fa9bd1fd86d9760000000000000000000000005b4a625a5bda77d9fa03e3cfc0fa9bd1fd86d976000000000000000000000000000000000000000000000000001f3508b729a2c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b239f10fed415a29ebe3adb3d601d986e8fd3970000000000000000000000002b239f10fed415a29ebe3adb3d601d986e8fd3970000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ebbf71a8c4cf3788e7ae7a9427e9d3a23cdfa6e0000000000000000000000002ebbf71a8c4cf3788e7ae7a9427e9d3a23cdfa6e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da346e4251ea91efed55dd01ee16f9a6d3e3d003000000000000000000000000da346e4251ea91efed55dd01ee16f9a6d3e3d00300000000000000000000000000000000000000000000000000dd206d2524e26100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7285,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e58a6006c66838ef57afb04d9b9bbd1251cd84f0000000000000000000000007e58a6006c66838ef57afb04d9b9bbd1251cd84f000000000000000000000000000000000000000000000000013b3df1ef6a724000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008164e9c410588e97965169f07294e697438b87630000000000000000000000008164e9c410588e97965169f07294e697438b8763000000000000000000000000000000000000000000000000001b466b4b6cbcc200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7287,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058e7e60534251b5ca9a5e48f3aad2621578c1be600000000000000000000000058e7e60534251b5ca9a5e48f3aad2621578c1be60000000000000000000000000000000000000000000000000020d73cd557030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7288,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c415ec56185161339ed545428218426a36dfd44e000000000000000000000000c415ec56185161339ed545428218426a36dfd44e000000000000000000000000000000000000000000000000008d62056256b19f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7289,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfe286b207d067d43733059c906197c611b9e64f000000000000000000000000cfe286b207d067d43733059c906197c611b9e64f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e77c563c2b2f35cd5560828e197e4ec575566870000000000000000000000008e77c563c2b2f35cd5560828e197e4ec57556687000000000000000000000000000000000000000000000000008ca72b909cb64600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5d0df63db77e0067d4f05d69e0dcab8431c232a0f83ba72b4bacf4d41df03fcf,2022-05-29 04:47:41.000 UTC,0,true +7292,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e92d559f99857114c610abef473c31be38e4a08b000000000000000000000000e92d559f99857114c610abef473c31be38e4a08b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7293,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052a3a7d1d84772ba1384ee0385275fe16a8513cc00000000000000000000000052a3a7d1d84772ba1384ee0385275fe16a8513cc000000000000000000000000000000000000000000000000001119b4ae9b03d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f367549ecda1259b749f25b624a98a39190891ab000000000000000000000000f367549ecda1259b749f25b624a98a39190891ab00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7296,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000886f136d699ebf04e06038183c445578e69acc6f000000000000000000000000886f136d699ebf04e06038183c445578e69acc6f000000000000000000000000000000000000000000000000005543df729c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7297,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8ccb62cc5adf1bf23612107e3782f4ced3b9ace000000000000000000000000b8ccb62cc5adf1bf23612107e3782f4ced3b9ace00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0f695742052fd558ca627a4f93feb75fa526f84000000000000000000000000e0f695742052fd558ca627a4f93feb75fa526f84000000000000000000000000000000000000000000000000002d1e952ca5c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7300,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001679665f47ef61552abf555f9c34f826dc6852220000000000000000000000001679665f47ef61552abf555f9c34f826dc685222000000000000000000000000000000000000000000000000002802c58c79514000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1135bce14a1bbe1084d45d35431cc4702e08234000000000000000000000000a1135bce14a1bbe1084d45d35431cc4702e08234000000000000000000000000000000000000000000000000000a46ca0670c95400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7302,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0d3a10267ede65800ac01f6ee40c8353826521c000000000000000000000000f0d3a10267ede65800ac01f6ee40c8353826521c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000639e2ea573935f7dc62effd6314269b82e6fa9a2000000000000000000000000639e2ea573935f7dc62effd6314269b82e6fa9a2000000000000000000000000000000000000000000000000009bc446b8e8c77200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045988c3d7a4ba9b93a0fef23476ad689df7eddb000000000000000000000000045988c3d7a4ba9b93a0fef23476ad689df7eddb000000000000000000000000000000000000000000000000001368685b133398000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7306,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001872c1bbb51c9d1129420f8baa4e6b7ddef79dfb0000000000000000000000001872c1bbb51c9d1129420f8baa4e6b7ddef79dfb000000000000000000000000000000000000000000000000015d1f7cddf1400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7307,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000536aec407c77142c4a19a4978e3d78c2beef81f6000000000000000000000000536aec407c77142c4a19a4978e3d78c2beef81f600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7309,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b860014d1891ed95bf2cde0d47e1b415194c6808000000000000000000000000b860014d1891ed95bf2cde0d47e1b415194c6808000000000000000000000000000000000000000000000000000268ee4cb72f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7310,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000060da990aebdd785f50ea3202ff05bff1d0963dbe0000000000000000000000000000000000000000000000006ada64be50311102,,,1,true +7312,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac57640958516bf078fd52dd48edf11fe418d7a8000000000000000000000000ac57640958516bf078fd52dd48edf11fe418d7a80000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7313,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007306509a72803bc7027d694c71f641943dde27d50000000000000000000000007306509a72803bc7027d694c71f641943dde27d5000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7314,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b8b2a20c8ad6c35eaf670cb8d856da62553bf010000000000000000000000001b8b2a20c8ad6c35eaf670cb8d856da62553bf0100000000000000000000000000000000000000000000000002ed37aee8ecd25c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbd7461df248e52485296296afba396d6ed36225119b99de0bfbd8d4f4f8f486d,2022-02-17 07:15:23.000 UTC,0,true +7315,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a8008c0645bd21f5cef33d2d38b2ba2cc66aedf0000000000000000000000002a8008c0645bd21f5cef33d2d38b2ba2cc66aedf00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e9c94870b662ea4a7f66f95d517866407ed7b2b0000000000000000000000003e9c94870b662ea4a7f66f95d517866407ed7b2b000000000000000000000000000000000000000000000000007d44e2f5015d8200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7320,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056479ace4817c0cd5601e6e70cd2b067275cd02400000000000000000000000056479ace4817c0cd5601e6e70cd2b067275cd02400000000000000000000000000000000000000000000000001364cceb90e4f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7321,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000328bef21aa2f291482250fdab11112a65366061c000000000000000000000000328bef21aa2f291482250fdab11112a65366061c00000000000000000000000000000000000000000000000000369c1af66a4b9500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7322,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d726723da8c4e8ecabd559ea8c8ae22fb2331066000000000000000000000000d726723da8c4e8ecabd559ea8c8ae22fb2331066000000000000000000000000000000000000000000000000000000001349713d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d726723da8c4e8ecabd559ea8c8ae22fb2331066000000000000000000000000d726723da8c4e8ecabd559ea8c8ae22fb23310660000000000000000000000000000000000000000000000000019427f6b585fc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7324,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d0675cd26b17a535fd4e5f21e735d4aabcd2ef30000000000000000000000006d0675cd26b17a535fd4e5f21e735d4aabcd2ef3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7325,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025132de651514b6c417c734558694fc576294d0300000000000000000000000025132de651514b6c417c734558694fc576294d030000000000000000000000000000000000000000000000000732d2641409510400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7326,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009231cdc62e929be11297a1a733d5088c85b7600a0000000000000000000000009231cdc62e929be11297a1a733d5088c85b7600a000000000000000000000000000000000000000000000000013839052419924000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7327,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008451b41b170d8a510cc85c1cf3fd3c82a6b250880000000000000000000000008451b41b170d8a510cc85c1cf3fd3c82a6b2508800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da8f9e5595cf71006ab107c5609bc445a61172f9000000000000000000000000da8f9e5595cf71006ab107c5609bc445a61172f900000000000000000000000000000000000000000000000000a4ff5955bc09e100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7330,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061a4ab28b1b2024d2e087baba8fb7ac8630a9e0300000000000000000000000061a4ab28b1b2024d2e087baba8fb7ac8630a9e030000000000000000000000000000000000000000000000000016b96e7f2f4b9e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7331,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba6745edf8f0f3fab7a58d06a4165620adc0a075000000000000000000000000ba6745edf8f0f3fab7a58d06a4165620adc0a07500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7333,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f475cb1e982f794cde073ac6303fecbc1e95ca4f000000000000000000000000f475cb1e982f794cde073ac6303fecbc1e95ca4f00000000000000000000000000000000000000000000000000618c765856164000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7334,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040d6f0f43a7e31e8e9bfc8c5f3b41b17e3509be200000000000000000000000040d6f0f43a7e31e8e9bfc8c5f3b41b17e3509be200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7337,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a524ee7f9137f208bcc0105f8864c9a5b674b1c0000000000000000000000001a524ee7f9137f208bcc0105f8864c9a5b674b1c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7338,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000208f6a3551ef656325aaab922feb0a3b9888a05f000000000000000000000000208f6a3551ef656325aaab922feb0a3b9888a05f000000000000000000000000000000000000000000000000001db7f11d59450000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003188c2d18e3a0c972ec68d71787d724834c117610000000000000000000000003188c2d18e3a0c972ec68d71787d724834c1176100000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca1cd76832aa9a3ba08efe3625e80ab06217b9b6000000000000000000000000ca1cd76832aa9a3ba08efe3625e80ab06217b9b600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7341,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d24e9e6ff7915f9353e2614050528b776d120ee0000000000000000000000003d24e9e6ff7915f9353e2614050528b776d120ee000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7342,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003188c2d18e3a0c972ec68d71787d724834c117610000000000000000000000003188c2d18e3a0c972ec68d71787d724834c11761000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7343,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000398259c183a1ef12d8f3a900b734b7d2e064cb25000000000000000000000000398259c183a1ef12d8f3a900b734b7d2e064cb250000000000000000000000000000000000000000000000000084f0229ac5918000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7344,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000835f658ec7db45e18e6f7b78a08267d89ca8ac13000000000000000000000000835f658ec7db45e18e6f7b78a08267d89ca8ac13000000000000000000000000000000000000000000000000001bbabc726494c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca1cd76832aa9a3ba08efe3625e80ab06217b9b6000000000000000000000000ca1cd76832aa9a3ba08efe3625e80ab06217b9b600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000902f1f73320c1e25473a5694d954fd96def3afc8000000000000000000000000902f1f73320c1e25473a5694d954fd96def3afc8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7348,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca1cd76832aa9a3ba08efe3625e80ab06217b9b6000000000000000000000000ca1cd76832aa9a3ba08efe3625e80ab06217b9b600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb185d133406df9ae3c1c4bcd73cda595383fff8000000000000000000000000cb185d133406df9ae3c1c4bcd73cda595383fff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7350,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061413ac783df9ccc7690272112f95ff3991a290e00000000000000000000000061413ac783df9ccc7690272112f95ff3991a290e000000000000000000000000000000000000000000000000001f416fdfec220000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084e2834759cc2e6957cb05bf46bbf4a6e71830df00000000000000000000000084e2834759cc2e6957cb05bf46bbf4a6e71830df0000000000000000000000000000000000000000000000000087ad1a6ab5e8c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d756d9f86ea38006b93007e9fe02fe5d697c1b00000000000000000000000007d756d9f86ea38006b93007e9fe02fe5d697c1b0000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020ff0f42101e3638194ed6b442e13f8f5c32b93b00000000000000000000000020ff0f42101e3638194ed6b442e13f8f5c32b93b0000000000000000000000000000000000000000000000000129f5e89b13bf4c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7356,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000eaa5e98b286bd6e4cb13fca6665cb72e0fc93ffc000000000000000000000000eaa5e98b286bd6e4cb13fca6665cb72e0fc93ffc0000000000000000000000000000000000000000000000000000000007effe6f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7357,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000492d61ab91dfbad8d376fca1fca57afc95a03551000000000000000000000000492d61ab91dfbad8d376fca1fca57afc95a035510000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7358,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ec77f3922707e16d7dd12750707f0213175d81f0000000000000000000000009ec77f3922707e16d7dd12750707f0213175d81f0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7359,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000595aedd52e88a1db7041b52b239d0980fd65d621000000000000000000000000595aedd52e88a1db7041b52b239d0980fd65d6210000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085ce3c5a646ab55e5d1bd871cd8b4cde7d7cd16900000000000000000000000085ce3c5a646ab55e5d1bd871cd8b4cde7d7cd169000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7361,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d756d9f86ea38006b93007e9fe02fe5d697c1b00000000000000000000000007d756d9f86ea38006b93007e9fe02fe5d697c1b0000000000000000000000000000000000000000000000000003024a5fa0397d400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7362,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029a9842dd19e154656747ed5bd2f2a1efedc368900000000000000000000000029a9842dd19e154656747ed5bd2f2a1efedc368900000000000000000000000000000000000000000000000001548d75c2e589b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7363,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003188c2d18e3a0c972ec68d71787d724834c117610000000000000000000000003188c2d18e3a0c972ec68d71787d724834c11761000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003188c2d18e3a0c972ec68d71787d724834c117610000000000000000000000003188c2d18e3a0c972ec68d71787d724834c11761000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d540dfe0c05dd8f6b4f204b77b4fafd425a13dcc000000000000000000000000d540dfe0c05dd8f6b4f204b77b4fafd425a13dcc000000000000000000000000000000000000000000000000000000000bee973900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c0f690f3c1539d0951b1131275266a298002fee0000000000000000000000004c0f690f3c1539d0951b1131275266a298002fee00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c32ec10a689cbbcaef9f921ebaff01735b2ac690000000000000000000000008c32ec10a689cbbcaef9f921ebaff01735b2ac690000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fc95b6e4d11bd603bbe7833a53ad0317f8104de0000000000000000000000007fc95b6e4d11bd603bbe7833a53ad0317f8104de0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7371,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd7b789e8815122be16ed246c32922b8e4bab0df000000000000000000000000dd7b789e8815122be16ed246c32922b8e4bab0df0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000083666f9aaca4f97239a1770817c9c3b0dfa9cad000000000000000000000000083666f9aaca4f97239a1770817c9c3b0dfa9cad00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7373,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000981f4663eae659910357daae7b9c66d4261e5140000000000000000000000000981f4663eae659910357daae7b9c66d4261e514000000000000000000000000000000000000000000000000030e5281024d607f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a872b8ae4df25903fcb6f0c7d31a50b29b6d4a50000000000000000000000005a872b8ae4df25903fcb6f0c7d31a50b29b6d4a5000000000000000000000000000000000000000000000000000a7e841d85811c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7375,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001be79610b81df611526351968c2dbb81dc8d36dd0000000000000000000000001be79610b81df611526351968c2dbb81dc8d36dd000000000000000000000000000000000000000000000000000be8ff35ea631500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c64a53627910055b602571b6ea801e78fd52c737000000000000000000000000c64a53627910055b602571b6ea801e78fd52c737000000000000000000000000000000000000000000000000002892efb39b86fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7382,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e3345fe824f8bdbdeea4610c6be5427282f7b890000000000000000000000006e3345fe824f8bdbdeea4610c6be5427282f7b8900000000000000000000000000000000000000000000000000670758aa7c800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ad755be12464f87c7ad1b10bdba9027f1519f750000000000000000000000006ad755be12464f87c7ad1b10bdba9027f1519f750000000000000000000000000000000000000000000000000001fee3518e613000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7385,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026da4f747dd974f873be9422918faf1c3c0049d600000000000000000000000026da4f747dd974f873be9422918faf1c3c0049d6000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9179bf69d9162e09ac3ca5773481946e158cd62000000000000000000000000f9179bf69d9162e09ac3ca5773481946e158cd620000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000373b6285ee0b3053c73c55e0198960842c762eb8000000000000000000000000373b6285ee0b3053c73c55e0198960842c762eb800000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000059150b4dcb622f260ca0882aac487fe8701981e000000000000000000000000059150b4dcb622f260ca0882aac487fe8701981e000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7389,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000897b264586ca7dfe3ccd80505f8bc4844d058a38000000000000000000000000897b264586ca7dfe3ccd80505f8bc4844d058a38000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7390,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f31009532a60709d19e7a2ac09fc2e013394e850000000000000000000000009f31009532a60709d19e7a2ac09fc2e013394e85000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000005aab0dc1817324363ff993d93616346f4f999d240000000000000000000000005aab0dc1817324363ff993d93616346f4f999d2400000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044a4d81102e3cd02a9dfdf1404e8db09826a08ce00000000000000000000000044a4d81102e3cd02a9dfdf1404e8db09826a08ce000000000000000000000000000000000000000000000000002cedda1c3297c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dcc6fec3f5393c453b38e9af061fa5c4285cc363000000000000000000000000dcc6fec3f5393c453b38e9af061fa5c4285cc363000000000000000000000000000000000000000000000000000048351cb39e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048511fa38fed232c7b1b6d40085f5e6ee5a485f200000000000000000000000048511fa38fed232c7b1b6d40085f5e6ee5a485f200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000005a10bb23698ee66aff584523a92c7a2f275c833e0000000000000000000000005a10bb23698ee66aff584523a92c7a2f275c833e00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7397,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c076a075f9a6a79288fb7c2ac782e6b3e9550b6b000000000000000000000000c076a075f9a6a79288fb7c2ac782e6b3e9550b6b000000000000000000000000000000000000000000000000000ad2b92e826f4100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001379b4508d23ee2f661aa49429c38f9cb0d8721f0000000000000000000000001379b4508d23ee2f661aa49429c38f9cb0d8721f00000000000000000000000000000000000000000000000000020645c2f88bc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004dc7e2e195f78a4fed312c3e6eb6a32eada3d8ce0000000000000000000000004dc7e2e195f78a4fed312c3e6eb6a32eada3d8ce00000000000000000000000000000000000000000000000000a07569135bd2dc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076e922dc720a166c61f2121ddd8f20fdf4a7629700000000000000000000000076e922dc720a166c61f2121ddd8f20fdf4a7629700000000000000000000000000000000000000000000000000ae56692486730000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf881401a8455249f030914c10b85378062ccdc7000000000000000000000000cf881401a8455249f030914c10b85378062ccdc700000000000000000000000000000000000000000000000000ae626fbef0d40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7402,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000007212c64b39a1e53a5e79ca826738d0d94e6a9c040000000000000000000000007212c64b39a1e53a5e79ca826738d0d94e6a9c0400000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006704b17cc393cabfa02c376772e613bba9130b820000000000000000000000006704b17cc393cabfa02c376772e613bba9130b8200000000000000000000000000000000000000000000000000ae44caa18b560000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006d390a4f4151d8edc5de04b2087009691c7c1cb00000000000000000000000006d390a4f4151d8edc5de04b2087009691c7c1cb00000000000000000000000000000000000000000000000000ae56692486730000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0cba90d703dad3e7989905a76e717e52b34cca8caea6618631810a6a210601d0,2022-08-29 07:53:30.000 UTC,0,true +7405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010bd0cffbdd0710d5d66f9260be7b4298246d9cc00000000000000000000000010bd0cffbdd0710d5d66f9260be7b4298246d9cc00000000000000000000000000000000000000000000000000addd08baa81d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cb47dc2eec74215fea0ade40ffcd1c4dbf482190000000000000000000000006cb47dc2eec74215fea0ade40ffcd1c4dbf4821900000000000000000000000000000000000000000000000000ae83700179f60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad1dd4267aa78ca8098d12d3a8a6f517c7d1fc69000000000000000000000000ad1dd4267aa78ca8098d12d3a8a6f517c7d1fc6900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dcc6fec3f5393c453b38e9af061fa5c4285cc363000000000000000000000000dcc6fec3f5393c453b38e9af061fa5c4285cc36300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7409,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001cd6219211c5bc7c14dd38e4095db4b2378687c90000000000000000000000001cd6219211c5bc7c14dd38e4095db4b2378687c90000000000000000000000000000000000000000000000000159a1d7760e155200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a62e8ebcbd4026f1cd1829d0617c15ceca863dcc000000000000000000000000a62e8ebcbd4026f1cd1829d0617c15ceca863dcc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a258aca19ea33ea0c21f2d6de8e2a3093acfee40000000000000000000000003a258aca19ea33ea0c21f2d6de8e2a3093acfee400000000000000000000000000000000000000000000000000ade9e61e5b670000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f32c082a5f2ecbcec5c44416646fb44d16b76732000000000000000000000000f32c082a5f2ecbcec5c44416646fb44d16b76732000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7413,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c86b505cad0b39497a9d7420a582a277f7175398000000000000000000000000c86b505cad0b39497a9d7420a582a277f717539800000000000000000000000000000000000000000000000000adc0c99766ce0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7414,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000908dbd31ed8ac9ae70db0228c0ca0df59af8fb56000000000000000000000000908dbd31ed8ac9ae70db0228c0ca0df59af8fb5600000000000000000000000000000000000000000000000166913cbfe1e33c2000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7415,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009fbc667c68f448904962aad8eac3d5b7aa41af750000000000000000000000009fbc667c68f448904962aad8eac3d5b7aa41af7500000000000000000000000000000000000000000000000000adf17331eb980000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000190a8bed2282f4be3ca0263cfb1cc355760185a0000000000000000000000000190a8bed2282f4be3ca0263cfb1cc355760185a0000000000000000000000000000000000000000000000000021f965ffe54c2500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008dfff0573a6f0b40864f874d64122c4815e887dc0000000000000000000000008dfff0573a6f0b40864f874d64122c4815e887dc00000000000000000000000000000000000000000000000000ade68af937c30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7418,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2db46798bebf1a0276b92e88c01f5ae80422784000000000000000000000000c2db46798bebf1a0276b92e88c01f5ae8042278400000000000000000000000000000000000000000000000000ade68af937c30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc2b5939cfbed9bdee0b7fc4d901e070a40713ab000000000000000000000000fc2b5939cfbed9bdee0b7fc4d901e070a40713ab00000000000000000000000000000000000000000000000000ae180b5d05760000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4038e4de3d9f19f24af03a25ba3442606b03c44000000000000000000000000e4038e4de3d9f19f24af03a25ba3442606b03c4400000000000000000000000000000000000000000000000000ae5ecd015f8d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026ed9f944312483a6daeab7fad4184a2ef7f9b2d00000000000000000000000026ed9f944312483a6daeab7fad4184a2ef7f9b2d00000000000000000000000000000000000000000000000000ae36cedc21800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c12886bd97ee471c336275199c2f6f269bf4adc0000000000000000000000001c12886bd97ee471c336275199c2f6f269bf4adc00000000000000000000000000000000000000000000000000ae7ac48c33390000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7423,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f03cff0446685d04434c165d181b696ff36056f9000000000000000000000000f03cff0446685d04434c165d181b696ff36056f900000000000000000000000000000000000000000000000000ae189a8de0bc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005515cc4193b736fb49f1afb0bb5f5c7ea92a3e110000000000000000000000005515cc4193b736fb49f1afb0bb5f5c7ea92a3e1100000000000000000000000000000000000000000000000000ae55d9f3ab2d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7425,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8b044956d8dd77340f71451c509c1d0fdd4d57a000000000000000000000000e8b044956d8dd77340f71451c509c1d0fdd4d57a00000000000000000000000000000000000000000000000000ae24a1284b1d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7426,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7acf65694d468de909d5acbc300fcab9c420a88000000000000000000000000f7acf65694d468de909d5acbc300fcab9c420a8800000000000000000000000000000000000000000000000000ae180b5d05760000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7427,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c21ae590cd1e60786a20df85215b0345ca5114ce000000000000000000000000c21ae590cd1e60786a20df85215b0345ca5114ce00000000000000000000000000000000000000000000000000adab40be6cc70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b2a2bf256b65d151bd1fa53d46317eba8a215c80000000000000000000000001b2a2bf256b65d151bd1fa53d46317eba8a215c800000000000000000000000000000000000000000000000000ad353b79b2150000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf8f553b1cebeb9a6fec9a9fae7486aeb68e2be6000000000000000000000000bf8f553b1cebeb9a6fec9a9fae7486aeb68e2be600000000000000000000000000000000000000000000000000addefde5a7920000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ec0e504fb50a08ae7eebb3e35b097d3b4720bf10000000000000000000000000ec0e504fb50a08ae7eebb3e35b097d3b4720bf1000000000000000000000000000000000000000000000000015905133188f80b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7431,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000082ae721301dda20654fc1fb7a12c660c3bfb461200000000000000000000000082ae721301dda20654fc1fb7a12c660c3bfb46120000000000000000000000000000000000000000000000000de2973d1eaa4da900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c71f9673daa6d65dd389f5bc211295104e8a38d6000000000000000000000000c71f9673daa6d65dd389f5bc211295104e8a38d600000000000000000000000000000000000000000000000000ae4b80ebd29e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6aab2339285450df21ca210ac3c2163e0f07a6e000000000000000000000000f6aab2339285450df21ca210ac3c2163e0f07a6e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7434,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad891e1f33e356ac839657fee01f324d75fe8141000000000000000000000000ad891e1f33e356ac839657fee01f324d75fe8141000000000000000000000000000000000000000000000000000344a034a0670d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7435,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fa44a75162b58198e431a6b5b413b0197a1e0910000000000000000000000005fa44a75162b58198e431a6b5b413b0197a1e091000000000000000000000000000000000000000000000000015635dbfc0f5a2d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efc621666b128e0c64fe5be97d2be33b701e3e64000000000000000000000000efc621666b128e0c64fe5be97d2be33b701e3e6400000000000000000000000000000000000000000000000000ae26ddebb8350000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0f076450b38cf7d41a2e92e95549cb02bcde08c000000000000000000000000c0f076450b38cf7d41a2e92e95549cb02bcde08c0000000000000000000000000000000000000000000000000003f1fd6743cf3800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ecbaa7d2f86f2d78c04f49986ec2c57938752a60000000000000000000000004ecbaa7d2f86f2d78c04f49986ec2c57938752a60000000000000000000000000000000000000000000000000043d525833e050000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c600c447ae7602780a778ac9fac97672af2ec6f0000000000000000000000001c600c447ae7602780a778ac9fac97672af2ec6f00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7441,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e6c30e98c92f9e9d8b60ac043dc6efdaa909a380000000000000000000000002e6c30e98c92f9e9d8b60ac043dc6efdaa909a3800000000000000000000000000000000000000000000000000adc158c842140000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ff0e2ae0042972a39495cce0b669de7bdbe184f0000000000000000000000004ff0e2ae0042972a39495cce0b669de7bdbe184f00000000000000000000000000000000000000000000000000adc9bca51b2e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7443,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000815d234bdb6f1e818c6f80da33d2a285c588b730000000000000000000000000815d234bdb6f1e818c6f80da33d2a285c588b7300000000000000000000000000000000000000000000000000addacbf73b050000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b43d75915742a36307d071dd3fb33e27c08e0e7c000000000000000000000000b43d75915742a36307d071dd3fb33e27c08e0e7c00000000000000000000000000000000000000000000000000ae1c3d4b72030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a6add0031caafa83311e47171a97a54e30f4cff0000000000000000000000004a6add0031caafa83311e47171a97a54e30f4cff00000000000000000000000000000000000000000000000000ae1a4820728e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000566f4717a58a0fbde8952454c715a8ec14ebe774000000000000000000000000566f4717a58a0fbde8952454c715a8ec14ebe77400000000000000000000000000000000000000000000000000ae26ddebb8350000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089445c90cf4d3cfde19861a55691134e3b68abff00000000000000000000000089445c90cf4d3cfde19861a55691134e3b68abff00000000000000000000000000000000000000000000000000ae24e8c0b8c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce59b53303e225dbf581b9eb8aa4ff1ee7f33601000000000000000000000000ce59b53303e225dbf581b9eb8aa4ff1ee7f3360100000000000000000000000000000000000000000000000000ad8c7d3f50bd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7449,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d1b726adc4093c773b934d1223003a43fa0fc914000000000000000000000000d1b726adc4093c773b934d1223003a43fa0fc9140000000000000000000000000000000000000000000000000dcf2679cfee633200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7450,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce9863e4ae1423d644b653db56d95a2017a374d8000000000000000000000000ce9863e4ae1423d644b653db56d95a2017a374d800000000000000000000000000000000000000000000000000ae50420b1a710000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077e2938deee318ddcc320a66cc19c03db50979ce00000000000000000000000077e2938deee318ddcc320a66cc19c03db50979ce00000000000000000000000000000000000000000000000000ba6a198897faf500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000266b41a8c5368df78a5ba327df04c2df6fc5e020000000000000000000000000266b41a8c5368df78a5ba327df04c2df6fc5e0200000000000000000000000000000000000000000000000000ae0cdb8be3fe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7453,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d51a0ac942ea64705b472fb09ab87b98d38d4cd0000000000000000000000008d51a0ac942ea64705b472fb09ab87b98d38d4cd00000000000000000000000000000000000000000000000000ae363fab463a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7454,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ab0a4be35d0a5541ac28b23b4de6d00f7ef8a5e0000000000000000000000007ab0a4be35d0a5541ac28b23b4de6d00f7ef8a5e00000000000000000000000000000000000000000000000000adcb6a37ad000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7455,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1e407b2f39cf536e29d6cd3ff23ee39444efd35000000000000000000000000f1e407b2f39cf536e29d6cd3ff23ee39444efd3500000000000000000000000000000000000000000000000000ad548e29a9650000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fa280ed16803d8338010ddb496d9a4285d0fa0e0000000000000000000000001fa280ed16803d8338010ddb496d9a4285d0fa0e00000000000000000000000000000000000000000000000000a0c97fbcad5b7d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000064a1f73d89381b60de444a15af69caea1dafd25000000000000000000000000064a1f73d89381b60de444a15af69caea1dafd2500000000000000000000000000000000000000000000000000ad8a407be3a50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7458,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dbe9b37777d1d8a62b5d102e7e1bd98db67c3e25000000000000000000000000dbe9b37777d1d8a62b5d102e7e1bd98db67c3e2500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d8610fede62ce73f5badced1fa3b31064358d442000000000000000000000000d8610fede62ce73f5badced1fa3b31064358d44200000000000000000000000000000000000000000000000000ad76f46656b60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001555f1925e30242e6bea7c61535ca37c5b5296e70000000000000000000000001555f1925e30242e6bea7c61535ca37c5b5296e700000000000000000000000000000000000000000000000000ad76f46656b60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7461,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000075b79f415445ad96c502cc40a3207d784aa253d000000000000000000000000075b79f415445ad96c502cc40a3207d784aa253d00000000000000000000000000000000000000000000000000a658094349467d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031e5910ab03575cddf4a8c5e960af53ae8644ea000000000000000000000000031e5910ab03575cddf4a8c5e960af53ae8644ea000000000000000000000000000000000000000000000000000ad3c80f4d4a30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7464,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c11c53143696077d3bbd52d5a229e619069be1c7000000000000000000000000c11c53143696077d3bbd52d5a229e619069be1c700000000000000000000000000000000000000000000000000ade4dd66a5f10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074ef14b3dd4df02cc46a2c0794fb23e63d61a2e000000000000000000000000074ef14b3dd4df02cc46a2c0794fb23e63d61a2e000000000000000000000000000000000000000000000000000adcbb1d01aa30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000564473919343604508a0a629de4358f05b6217e3000000000000000000000000564473919343604508a0a629de4358f05b6217e300000000000000000000000000000000000000000000000000adcbb1d01aa30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a258434cbb2ede8d85fc9793f86c616236ee00db000000000000000000000000a258434cbb2ede8d85fc9793f86c616236ee00db00000000000000000000000000000000000000000000000000adcbb1d01aa30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7468,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000036d00e21a271287f3ba0905f59fdc2954613a92000000000000000000000000036d00e21a271287f3ba0905f59fdc2954613a9200000000000000000000000000000000000000000000000000ad7a4f8b7a5a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f8c2d3c16f7e6d8c34f8e152c15a8689d1296cd0000000000000000000000004f8c2d3c16f7e6d8c34f8e152c15a8689d1296cd00000000000000000000000000000000000000000000000000ad60059338800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7cbd7e623a1622cc16a252e796710c6073a1489000000000000000000000000d7cbd7e623a1622cc16a252e796710c6073a148900000000000000000000000000000000000000000000000000add3867c18770000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051d03118eb9206f5118372ca58ec7397e54655ed00000000000000000000000051d03118eb9206f5118372ca58ec7397e54655ed00000000000000000000000000000000000000000000000000add3867c18770000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fa280ed16803d8338010ddb496d9a4285d0fa0e0000000000000000000000001fa280ed16803d8338010ddb496d9a4285d0fa0e000000000000000000000000000000000000000000000000001dc3ce3c689ab400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f426fadc9ae9ba557887b706e391d766df0f0fa5000000000000000000000000f426fadc9ae9ba557887b706e391d766df0f0fa500000000000000000000000000000000000000000000000000ad4ef64118a90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008aea5dea3876e506eae703509ef214becff891df0000000000000000000000008aea5dea3876e506eae703509ef214becff891df00000000000000000000000000000000000000000000000000adc3065ad3e60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3320052a474497938b9acfb3615918767257758000000000000000000000000f3320052a474497938b9acfb361591876725775800000000000000000000000000000000000000000000000000addd505315c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7477,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d72895f98c83d7528b05329c75b463dc511e22a4000000000000000000000000d72895f98c83d7528b05329c75b463dc511e22a400000000000000000000000000000000000000000000000000adff6ef7556e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7479,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f00ff423a370e6cbbdd08768fc5bf39635f22352000000000000000000000000f00ff423a370e6cbbdd08768fc5bf39635f2235200000000000000000000000000000000000000000000000000ae301891da380000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7481,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000315ff0594cdc932fb91ccdfab5b713d3f86b9b0a000000000000000000000000315ff0594cdc932fb91ccdfab5b713d3f86b9b0a00000000000000000000000000000000000000000000000000ae233b2e26ee0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005668a0a0a359e17e2bb27ac3978400e67fa09c2a0000000000000000000000005668a0a0a359e17e2bb27ac3978400e67fa09c2a00000000000000000000000000000000000000000000000000ae8bd3de53100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7483,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f6e7aad312ec5b59a360091eafb4e2db2be0ce02000000000000000000000000f6e7aad312ec5b59a360091eafb4e2db2be0ce020000000000000000000000000000000000000000000000000dcf877b646fe8a300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7484,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c1df74089df99917816cc2ada2ac3f817520a470000000000000000000000007c1df74089df99917816cc2ada2ac3f817520a4700000000000000000000000000000000000000000000000000ae83700179f60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d13acab6a8e805e1c9d6221cfaa4f07f4e947d0c000000000000000000000000d13acab6a8e805e1c9d6221cfaa4f07f4e947d0c00000000000000000000000000000000000000000000000000aedd7dbb60fc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7486,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b65deb1b5db4699193006f90301f01d3aa62f710000000000000000000000002b65deb1b5db4699193006f90301f01d3aa62f7100000000000000000000000000000000000000000000000000ae894f8278550000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7487,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092f209f5c4ba44273f692f3776e5c2764386c81800000000000000000000000092f209f5c4ba44273f692f3776e5c2764386c81800000000000000000000000000000000000000000000000000ae12bb0ce25d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7488,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003dcb335bb0c288ac15a1bca6002fc074221b1fc00000000000000000000000003dcb335bb0c288ac15a1bca6002fc074221b1fc00000000000000000000000000000000000000000000000000dcb8bddfe72a9df00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7489,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063ee5872e8549acb99f7b24508d5fee5f3ca5ef000000000000000000000000063ee5872e8549acb99f7b24508d5fee5f3ca5ef000000000000000000000000000000000000000000000000000ae6c3995ee1d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000459ce113d1a1cbf4fbf08e951a7336518f6d02d5000000000000000000000000459ce113d1a1cbf4fbf08e951a7336518f6d02d500000000000000000000000000000000000000000000000000ae6c3995ee1d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9f8ccf9e8a020c00d7796d2ecb62886a438a3cb000000000000000000000000c9f8ccf9e8a020c00d7796d2ecb62886a438a3cb00000000000000000000000000000000000000000000000000ae6c3995ee1d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7492,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003768cb4dd86eb023351ed692b7a2914e9bafa6db0000000000000000000000003768cb4dd86eb023351ed692b7a2914e9bafa6db0000000000000000000000000000000000000000000000000dcb76c5bc2565ab00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7493,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079e614793261bb897479ba2695e12e52a917479d00000000000000000000000079e614793261bb897479ba2695e12e52a917479d00000000000000000000000000000000000000000000000000adbb794743b50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000034ac975586e7d8fbd6a9b70531d47de1ebb3b8f000000000000000000000000034ac975586e7d8fbd6a9b70531d47de1ebb3b8f00000000000000000000000000000000000000000000000000adbb794743b50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000639aee9a0395d9bcb76078c6c1da119a2ea83078000000000000000000000000639aee9a0395d9bcb76078c6c1da119a2ea8307800000000000000000000000000000000000000000000000000adbb794743b50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000edc113cb810b4b6fb87770e80376e0947d27e3c7000000000000000000000000edc113cb810b4b6fb87770e80376e0947d27e3c700000000000000000000000000000000000000000000000000adf8b8ad0e260000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7497,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000005f4b6fd9b735438cf5b8a3288497933249cd8ae50000000000000000000000005f4b6fd9b735438cf5b8a3288497933249cd8ae50000000000000000000000000000000000000000000000000dcb5f47ca0cee7d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a891a1ced2d7289a643a92e788a271dcdcabb2eb000000000000000000000000a891a1ced2d7289a643a92e788a271dcdcabb2eb00000000000000000000000000000000000000000000000000adf8b8ad0e260000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7499,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000cb1daeebc6a365c6968ad8fe53f8fccdfa05aba1000000000000000000000000cb1daeebc6a365c6968ad8fe53f8fccdfa05aba10000000000000000000000000000000000000000000000000dc5ef108125f78900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a54a961158f8e4611c544b47af75f8a002ac1eb0000000000000000000000000a54a961158f8e4611c544b47af75f8a002ac1eb0000000000000000000000000000000000000000000000000000784f25631540000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000219929399f860d4598976051288d2e7b224dc301000000000000000000000000219929399f860d4598976051288d2e7b224dc301000000000000000000000000000000000000000000000000003bf846dec395bb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089b559e0286ddd85197694f7b51dcc2d69e2cf3d00000000000000000000000089b559e0286ddd85197694f7b51dcc2d69e2cf3d0000000000000000000000000000000000000000000000000006268f1f360d0600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7507,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060bb17be832944e648c979ab76f40902db27d7df00000000000000000000000060bb17be832944e648c979ab76f40902db27d7df000000000000000000000000000000000000000000000000003d6d04c1f0cb6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7509,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f24b327b0df485a44ff4d7b1289e9e1b4da93fe0000000000000000000000000f24b327b0df485a44ff4d7b1289e9e1b4da93fe000000000000000000000000000000000000000000000000000ae88c0519d0f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f801b192adef546d8da04ae9e8c8d134d0157a90000000000000000000000000f801b192adef546d8da04ae9e8c8d134d0157a900000000000000000000000000000000000000000000000000085f61d330706100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7513,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d37bab7903aa966b9a997e3d32ae8bf64b6044d6000000000000000000000000d37bab7903aa966b9a997e3d32ae8bf64b6044d600000000000000000000000000000000000000000000000000adea7811b1fac700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9fbc98e2b46f938d2f4955fb27b460cb64da110bb6ab43b1c8c8a6d009c314e2,2021-12-13 09:32:28.000 UTC,0,true +7514,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a846a337ad081e78984ca9f2c20504151b66c29b000000000000000000000000a846a337ad081e78984ca9f2c20504151b66c29b00000000000000000000000000000000000000000000000000adcfe3be87300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4961a88513692fd878f1b44986c5c4a639980cc000000000000000000000000d4961a88513692fd878f1b44986c5c4a639980cc00000000000000000000000000000000000000000000000000ae6d9f90124c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004c0186d8bc845ae8e09e707bf5dc3fa03f91bed00000000000000000000000004c0186d8bc845ae8e09e707bf5dc3fa03f91bed00000000000000000000000000000000000000000000000000ae6d9f90124c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7517,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035445c18ff0b5be58fb4397ef6c9072a0b76368500000000000000000000000035445c18ff0b5be58fb4397ef6c9072a0b76368500000000000000000000000000000000000000000000000000ad4ef64118a90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010e66cc24b7b91c26ee80a284d3e85246f8ca2b700000000000000000000000010e66cc24b7b91c26ee80a284d3e85246f8ca2b700000000000000000000000000000000000000000000000000ae30ef5b23210000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057b62746a34614143c48a26d84f95dab0329d11100000000000000000000000057b62746a34614143c48a26d84f95dab0329d111000000000000000000000000000000000000000000000000003c27d8aeefaac900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7520,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009252160105181fbe25dc8aca2e5e4367b2c362f10000000000000000000000009252160105181fbe25dc8aca2e5e4367b2c362f100000000000000000000000000000000000000000000000000ae0e891e75d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7521,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3b87a20fe00b4bb4d62107d7f6aebe2e8dc3aa7000000000000000000000000b3b87a20fe00b4bb4d62107d7f6aebe2e8dc3aa7000000000000000000000000000000000000000000000000001ff2bf5f71d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7522,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000772cc8808e7bbeee498ac01f2cb54684bc9737a6000000000000000000000000772cc8808e7bbeee498ac01f2cb54684bc9737a600000000000000000000000000000000000000000000000000ae0e891e75d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7523,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a876938b4db24735393e0060d2b9ac0998d8e4f0000000000000000000000003a876938b4db24735393e0060d2b9ac0998d8e4f00000000000000000000000000000000000000000000000000ae2be6a36dab0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7524,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009997919e8e35921da36a3296926b9b75e54823f30000000000000000000000009997919e8e35921da36a3296926b9b75e54823f300000000000000000000000000000000000000000000000000ae134a3dbda30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7525,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9a0dc7a3f7216cfbfae6895bc8624575e3aa947000000000000000000000000a9a0dc7a3f7216cfbfae6895bc8624575e3aa94700000000000000000000000000000000000000000000000000ae6d9f90124c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7526,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001567fe56a6eb4b473a4ddde014fe8f1731c951060000000000000000000000000000000000000000000000004d73a39e2b1491f9,,,1,true +7527,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060814e6e0242f07a1ada442fc47918159d0af5fb00000000000000000000000060814e6e0242f07a1ada442fc47918159d0af5fb00000000000000000000000000000000000000000000000000ae5787863cff0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000588235b8980662b2d8aa248c894820c70772d0fe000000000000000000000000588235b8980662b2d8aa248c894820c70772d0fe00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f62a6c144422c49d322ab53ebe94081dcc7e0a70000000000000000000000007f62a6c144422c49d322ab53ebe94081dcc7e0a70000000000000000000000000000000000000000000000000003e8f437904d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7530,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044d0e5b18f58782304750680f5d08df1dc5f2ed100000000000000000000000044d0e5b18f58782304750680f5d08df1dc5f2ed100000000000000000000000000000000000000000000000000ae5787863cff0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ec7de88937299efad9e2d1a252e4dc6da9e043a0000000000000000000000000ec7de88937299efad9e2d1a252e4dc6da9e043a00000000000000000000000000000000000000000000000000aeb4f06547a90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7532,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000492ad0dfa799db64344e97af57249cf921e5ee09000000000000000000000000492ad0dfa799db64344e97af57249cf921e5ee0900000000000000000000000000000000000000000000000000ae8a264bc13e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099829510a9bb0bdb0db43300c1def5be184c399e00000000000000000000000099829510a9bb0bdb0db43300c1def5be184c399e00000000000000000000000000000000000000000000000000aebba6af8ef10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7534,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bada7f9158b13cc63b5ff0a1d4cfc7b4687418c0000000000000000000000005bada7f9158b13cc63b5ff0a1d4cfc7b4687418c00000000000000000000000000000000000000000000000000ae9aee0573720000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad28fc8cccd7a56904f0aac295f46fa5f0e6ce7c000000000000000000000000ad28fc8cccd7a56904f0aac295f46fa5f0e6ce7c00000000000000000000000000000000000000000000000000aeb02f45ffd60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008daf76b646554f9a0b5c12c554653ab7360f200a0000000000000000000000008daf76b646554f9a0b5c12c554653ab7360f200a00000000000000000000000000000000000000000000000000aedc5f59aa700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056472645efa1c71dc206c6caf9424b5cc281e54800000000000000000000000056472645efa1c71dc206c6caf9424b5cc281e54800000000000000000000000000000000000000000000000000ae46309baf850000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000281e5b0130168236f475b0565dd1f03c47c8cf7a000000000000000000000000281e5b0130168236f475b0565dd1f03c47c8cf7a00000000000000000000000000000000000000000000000000aed443153ef90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7539,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b074550f54bb62ca7e770704edcdfb5f285c2a98000000000000000000000000b074550f54bb62ca7e770704edcdfb5f285c2a9800000000000000000000000000000000000000000000000000af1cf9e498850000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5fae7d266f5890110b285d5b732a908e5624339000000000000000000000000c5fae7d266f5890110b285d5b732a908e562433900000000000000000000000000000000000000000000000000aeb26c096cee0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a08382adbebaa283ba7780269c9f7703ea3363e0000000000000000000000009a08382adbebaa283ba7780269c9f7703ea3363e00000000000000000000000000000000000000000000000000aeb26c096cee0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7542,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff9470aa9ab2c0763c5223028df0d160c6ccf018000000000000000000000000ff9470aa9ab2c0763c5223028df0d160c6ccf01800000000000000000000000000000000000000000000000000ae820a0755c70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022532682436ad59a16baf0e986042e1e640f37ca00000000000000000000000022532682436ad59a16baf0e986042e1e640f37ca00000000000000000000000000000000000000000000000000aea783d0b9190000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df04be0d58741743c1152c78fc3d1bc4a33dcd3a000000000000000000000000df04be0d58741743c1152c78fc3d1bc4a33dcd3a00000000000000000000000000000000000000000000000000ae9d2ac8e08a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7545,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f772ce83e0411588bd6318d1a7b6585854b11188000000000000000000000000f772ce83e0411588bd6318d1a7b6585854b1118800000000000000000000000000000000000000000000000000aee002173bb70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7546,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d80a617cd71449abda8585fb9895a0c80b99001d000000000000000000000000d80a617cd71449abda8585fb9895a0c80b99001d00000000000000000000000000000000000000000000000000ae8e9fd29b6e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018d729566ae764c238c2a9bc9cef3a1710cedaad00000000000000000000000018d729566ae764c238c2a9bc9cef3a1710cedaad00000000000000000000000000000000000000000000000000ae8f769be4570000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7548,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014e4be76d2152b25553509459cf20394cf581fef00000000000000000000000014e4be76d2152b25553509459cf20394cf581fef00000000000000000000000000000000000000000000000000ae63d5b915030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ffa47af2bda483d1c94795223020774aeb3d3f30000000000000000000000006ffa47af2bda483d1c94795223020774aeb3d3f300000000000000000000000000000000000000000000000000aec88413423b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7550,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054cbc1c6f27e32abb247ed24931041f545ffcfa900000000000000000000000054cbc1c6f27e32abb247ed24931041f545ffcfa900000000000000000000000000000000000000000000000000ae85acc4e70e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000562cb434b6b0163e78cbcefea6557ceb18ed0d2a000000000000000000000000562cb434b6b0163e78cbcefea6557ceb18ed0d2a00000000000000000000000000000000000000000000000000aeab6e26b8030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ca24558487bb0e0b7d919c10b68bd4766b65ba90000000000000000000000009ca24558487bb0e0b7d919c10b68bd4766b65ba900000000000000000000000000000000000000000000000000ae9aee0573720000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000533c373483ced08185769e8b75c5ae7a0913420e000000000000000000000000533c373483ced08185769e8b75c5ae7a0913420e00000000000000000000000000000000000000000000000000ae9aee0573720000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006960f073f21f08f9e70d92a3829a9639883860160000000000000000000000006960f073f21f08f9e70d92a3829a96398838601600000000000000000000000000000000000000000000000000ae3dccbed66b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004610982bc3942433c50ce6ea228da3d118a467810000000000000000000000004610982bc3942433c50ce6ea228da3d118a4678100000000000000000000000000000000000000000000000000ae3dccbed66b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f30859796a0d2618a1e6dd27a47f27ce03bb210d000000000000000000000000f30859796a0d2618a1e6dd27a47f27ce03bb210d00000000000000000000000000000000000000000000000000add60ad7f3320000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a16a05b1833a0bb47226e35b18f60c6145a4039a000000000000000000000000a16a05b1833a0bb47226e35b18f60c6145a4039a00000000000000000000000000000000000000000000000000ad8bee0e75770000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081f019fb5dbc4123d0273f7fbab06e78f889189800000000000000000000000081f019fb5dbc4123d0273f7fbab06e78f889189800000000000000000000000000000000000000000000000000ad2c00d390120000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c10dbf2acf476b2e64beecefb531cd42ec6c4531000000000000000000000000c10dbf2acf476b2e64beecefb531cd42ec6c453100000000000000000000000000000000000000000000000000ad2c00d390120000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087ac26530ba964e0b63df037adb69c050f42683100000000000000000000000087ac26530ba964e0b63df037adb69c050f42683100000000000000000000000000000000000000000000000000ad9bdefedec20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5b1318c4c0a00d9a6bd2d1a5df78849671d4451000000000000000000000000d5b1318c4c0a00d9a6bd2d1a5df78849671d445100000000000000000000000000000000000000000000000000ad1edbd76f250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7562,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083af5f707e02c7fe0a08e6fe1e680028848e1b6900000000000000000000000083af5f707e02c7fe0a08e6fe1e680028848e1b6900000000000000000000000000000000000000000000000000acf06f0057730000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000599f9850a621ed6f53d4ea55f905b24a6001bada000000000000000000000000599f9850a621ed6f53d4ea55f905b24a6001bada00000000000000000000000000000000000000000000000000ad69cf6a35c90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000209e56d2595d1b2506d73b97e26b09ed01b83649000000000000000000000000209e56d2595d1b2506d73b97e26b09ed01b8364900000000000000000000000000000000000000000000000000adb35d02d83e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c369d580e0edddbc4ae412febd6754db90461aa0000000000000000000000000c369d580e0edddbc4ae412febd6754db90461aa000000000000000000000000000000000000000000000000000adb35d02d83e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7567,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005133ba94f973019f002dbce1a90c250422defa1c0000000000000000000000005133ba94f973019f002dbce1a90c250422defa1c00000000000000000000000000000000000000000000000000addeb64d39ef0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7569,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc9dc3b6dc79e8801e1b5f57f0e255f28b0499bd000000000000000000000000fc9dc3b6dc79e8801e1b5f57f0e255f28b0499bd00000000000000000000000000000000000000000000000000ae4364a767270000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7570,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cffa2bad785cc2d369830692fbbf7ed3d8a0f983000000000000000000000000cffa2bad785cc2d369830692fbbf7ed3d8a0f98300000000000000000000000000000000000000000000000000ae2696534a920000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7571,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040bc79e4558c74168f3c113a9d9a4aad6f29624c00000000000000000000000040bc79e4558c74168f3c113a9d9a4aad6f29624c00000000000000000000000000000000000000000000000000ae2696534a920000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007720064a8dc14750449304ba9307f9567bfad0960000000000000000000000007720064a8dc14750449304ba9307f9567bfad09600000000000000000000000000000000000000000000000000ae25bf8a01a90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7573,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e17b3c19eb8e4ca5eb0af01c2d5c944b73d1eeeb000000000000000000000000e17b3c19eb8e4ca5eb0af01c2d5c944b73d1eeeb00000000000000000000000000000000000000000000000000ae25bf8a01a90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7574,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047d713f03e4520c3949093c90c8e0f40c60ca19000000000000000000000000047d713f03e4520c3949093c90c8e0f40c60ca19000000000000000000000000000000000000000000000000000ae904d652d400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7575,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008582fdfa0003af19f26470ed2f7d18e5aeb000060000000000000000000000008582fdfa0003af19f26470ed2f7d18e5aeb0000600000000000000000000000000000000000000000000000000adc6a918652d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7576,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7fbb67ca1f7db16e798952a7b4e1ef84b247054000000000000000000000000f7fbb67ca1f7db16e798952a7b4e1ef84b24705400000000000000000000000000000000000000000000000000ad995aa304070000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000432e0d86aa20743fc53e361b06975cd34fce2e4f000000000000000000000000432e0d86aa20743fc53e361b06975cd34fce2e4f00000000000000000000000000000000000000000000000000ad884b50e4300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008159bb4c392c0d904a0372933683f60cf3cc4f100000000000000000000000008159bb4c392c0d904a0372933683f60cf3cc4f10000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7579,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5b5dbb678b8b4314384b60d6f9a293ae1b58b8d000000000000000000000000e5b5dbb678b8b4314384b60d6f9a293ae1b58b8d00000000000000000000000000000000000000000000000000adc58ab6aea10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7580,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005cd19361680979905686aaa5870d73991bb362900000000000000000000000005cd19361680979905686aaa5870d73991bb362900000000000000000000000000000000000000000000000000addddf83f1060000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7581,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c89b8dd7e3e137db108575eeae301e52b6c72d9f000000000000000000000000c89b8dd7e3e137db108575eeae301e52b6c72d9f000000000000000000000000000000000000000000000000016a264bacc1280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7582,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000638f308e92240793b35910cb87bf9a580a3fa162000000000000000000000000638f308e92240793b35910cb87bf9a580a3fa16200000000000000000000000000000000000000000000000000adf9d70ec4b20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7583,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3a4cc5bbd5a061575a019f4e2c5f8cb1167be11000000000000000000000000d3a4cc5bbd5a061575a019f4e2c5f8cb1167be1100000000000000000000000000000000000000000000000000ad8803b8768d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7585,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a80f1a7623fd8e04b0e0f4e2a8d393852da63211000000000000000000000000a80f1a7623fd8e04b0e0f4e2a8d393852da6321100000000000000000000000000000000000000000000000000adbcdf4167e40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6b51cf482a0bed3f88614e1fa8484ad9117039e000000000000000000000000c6b51cf482a0bed3f88614e1fa8484ad9117039e00000000000000000000000000000000000000000000000000adbcdf4167e40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7587,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b89defa50227491d7587eeef3e706ce0fcc3b595000000000000000000000000b89defa50227491d7587eeef3e706ce0fcc3b59500000000000000000000000000000000000000000000000000acde414c81100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7588,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eeaa75be33235789287252d238cbe9f2c58ac051000000000000000000000000eeaa75be33235789287252d238cbe9f2c58ac051000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7589,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5036e0c6217193784ba3f50e2cafa5056edfd25000000000000000000000000a5036e0c6217193784ba3f50e2cafa5056edfd2500000000000000000000000000000000000000000000000000ad43c66ff7310000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7590,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3e358543a57a213d4df6cf884570a1b9e0de7ea000000000000000000000000a3e358543a57a213d4df6cf884570a1b9e0de7ea00000000000000000000000000000000000000000000000000adac5f2023530000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7591,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8bbe5d99fe12ad0f5db68ab893f408ebdf4d5d2000000000000000000000000e8bbe5d99fe12ad0f5db68ab893f408ebdf4d5d20000000000000000000000000000000000000000000000000005c5ba7442b96e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7592,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060024087c862f75febe1f249808a54ec6a7da89e00000000000000000000000060024087c862f75febe1f249808a54ec6a7da89e00000000000000000000000000000000000000000000000000ade211725d930000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7593,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008780aa9160d3da8fbb2b1a05278c5dac31ad36720000000000000000000000008780aa9160d3da8fbb2b1a05278c5dac31ad367200000000000000000000000000000000000000000000000000ade211725d930000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7594,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d218950ec60eb78201acf20f2c3b8fd66888da94000000000000000000000000d218950ec60eb78201acf20f2c3b8fd66888da9400000000000000000000000000000000000000000000000000ad5f2ec9ef970000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7595,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2b96cdd902ba47b97dc98d4da4e7b696f5e0f1d000000000000000000000000d2b96cdd902ba47b97dc98d4da4e7b696f5e0f1d00000000000000000000000000000000000000000000000000adde271c5ea90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7597,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001a8a09311d1d558f07f6d05d0e8bc6fd8fe8b8a00000000000000000000000001a8a09311d1d558f07f6d05d0e8bc6fd8fe8b8a00000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7598,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7789cdf5b5ff0cf171b4b389986f35844e502a6000000000000000000000000d7789cdf5b5ff0cf171b4b389986f35844e502a600000000000000000000000000000000000000000000000000adf320c47d6a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a56de955933d795418532eec5b4690c2f7e64350000000000000000000000005a56de955933d795418532eec5b4690c2f7e643500000000000000000000000000000000000000000000000000ae6a8c035c4b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7600,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a4bbd1b7b224c31d62d4042e0c08a032c8d77350000000000000000000000000a4bbd1b7b224c31d62d4042e0c08a032c8d773500000000000000000000000000000000000000000000000000adc9750cad8b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7601,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc289f97fc3446ecdecd30dd19c56960a24ae950000000000000000000000000dc289f97fc3446ecdecd30dd19c56960a24ae95000000000000000000000000000000000000000000000000000ae30ef5b23210000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7602,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038811574db392d15d0827f8cc903283af3ca29ae00000000000000000000000038811574db392d15d0827f8cc903283af3ca29ae00000000000000000000000000000000000000000000000000ae30ef5b23210000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7603,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a428bdcb44eb5306bc7991239bba5179872b30de000000000000000000000000a428bdcb44eb5306bc7991239bba5179872b30de00000000000000000000000000000000000000000000000000ad9b9766711f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7604,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b92df354b82594f63ddbc4cac6eebe2009f155b0000000000000000000000006b92df354b82594f63ddbc4cac6eebe2009f155b00000000000000000000000000000000000000000000000000ad9b9766711f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7605,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a34169af16e1d8a7d6649b0dbfe85ea18d7ce070000000000000000000000007a34169af16e1d8a7d6649b0dbfe85ea18d7ce0700000000000000000000000000000000000000000000000000ae16ecfb4eea0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7606,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9682971028449408ae5e809246d056cabbff3fc000000000000000000000000d9682971028449408ae5e809246d056cabbff3fc00000000000000000000000000000000000000000000000000ad7665357b700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7607,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdb8ed3779a0d42b996fa1d24b2617015450b9a9000000000000000000000000bdb8ed3779a0d42b996fa1d24b2617015450b9a900000000000000000000000000000000000000000000000000adc6f0b0d2d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7608,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b36118ddb7586072b359fda10d90cd39b24fdf42000000000000000000000000b36118ddb7586072b359fda10d90cd39b24fdf4200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022e3bd619ae5c006afec292774d3b6b645dc1c1900000000000000000000000022e3bd619ae5c006afec292774d3b6b645dc1c19000000000000000000000000000000000000000000000000003bade431716b8300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7610,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009260bb6c9b32e04547be20db02f6aaa530fc36080000000000000000000000009260bb6c9b32e04547be20db02f6aaa530fc360800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7611,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004088f2fd285c51de2203db3a0c6014b36c7c4d610000000000000000000000004088f2fd285c51de2203db3a0c6014b36c7c4d6100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7612,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001431a59a078a6cba473c3899b6ad358ad698d2a50000000000000000000000001431a59a078a6cba473c3899b6ad358ad698d2a500000000000000000000000000000000000000000000000000adf6c3820eb10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7613,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059bd3cb9cd4c016f0dbcd93bfbdc56b05063de0f00000000000000000000000059bd3cb9cd4c016f0dbcd93bfbdc56b05063de0f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7614,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000156181484c8a8b3983f5be98a63dce1372eaa7b1000000000000000000000000156181484c8a8b3983f5be98a63dce1372eaa7b100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7615,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a74627ee05cb76db741f66542a1fbcfed29a20f0000000000000000000000007a74627ee05cb76db741f66542a1fbcfed29a20f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054c1349cff8b5fd7cf4124a778f4aa4676d3599f00000000000000000000000054c1349cff8b5fd7cf4124a778f4aa4676d3599f00000000000000000000000000000000000000000000000000043bf0082b4d8800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7618,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000830e7ef90616c0ac756899a26e36fe291a4ea635000000000000000000000000830e7ef90616c0ac756899a26e36fe291a4ea635000000000000000000000000000000000000000000000000004e753cd36cbe0b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7619,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000303e60ea993c8f6bcfd7d0f7d5270a71b458b4c7000000000000000000000000303e60ea993c8f6bcfd7d0f7d5270a71b458b4c700000000000000000000000000000000000000000000000000a56ced518fd7ac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7620,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086d004eb704b385d2c75c8ff70dcd52ba789ab3a00000000000000000000000086d004eb704b385d2c75c8ff70dcd52ba789ab3a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b361ac29c912fb2b9565719dfff901cf6904d310000000000000000000000009b361ac29c912fb2b9565719dfff901cf6904d31000000000000000000000000000000000000000000000000007119e5e0c33f3800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7622,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c35a338756c87b3f9cc2283ed58e6a36d0508b80000000000000000000000002c35a338756c87b3f9cc2283ed58e6a36d0508b80000000000000000000000000000000000000000000000000020ba9e148b17c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000012e0301eb01dd35007cc04e09051834cb22212c000000000000000000000000012e0301eb01dd35007cc04e09051834cb22212c0000000000000000000000000000000000000000000000000030c2a0fa4cbb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7624,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000420e26061672cc8d6bf4e0ac93e71fb8b07b542c000000000000000000000000420e26061672cc8d6bf4e0ac93e71fb8b07b542c0000000000000000000000000000000000000000000000000000000001c9c38000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000376ff58d081d75732730b57dd516462c07c8a7a9000000000000000000000000376ff58d081d75732730b57dd516462c07c8a7a900000000000000000000000000000000000000000000000000a2ca713d68562e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab0da4e336bc4d777364d14de819aa712a4161c7000000000000000000000000ab0da4e336bc4d777364d14de819aa712a4161c700000000000000000000000000000000000000000000000000a3971e86b06ad800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023d208c963d9945695882ba278e1769918a241fd00000000000000000000000023d208c963d9945695882ba278e1769918a241fd00000000000000000000000000000000000000000000000000a43508ab10fe4e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000766c1ee5fe7c684b22becef250e110f61842a01e000000000000000000000000766c1ee5fe7c684b22becef250e110f61842a01e0000000000000000000000000000000000000000000000000039320be8cd412e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7630,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aafcbe22104766f57d1d60e169cc466697b41913000000000000000000000000aafcbe22104766f57d1d60e169cc466697b4191300000000000000000000000000000000000000000000000000a3272993bf0eef00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d199eefa598894d13adafce1ef015c758b0fa06f000000000000000000000000d199eefa598894d13adafce1ef015c758b0fa06f00000000000000000000000000000000000000000000000000a32a7937ca7a0200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f038b3a2adb14326be2c6c011b2b2fe334f1c440000000000000000000000003f038b3a2adb14326be2c6c011b2b2fe334f1c4400000000000000000000000000000000000000000000000000a46d2b2d81b6af00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5a9715581c227dbc3c2c7567121dc5118751a7b000000000000000000000000a5a9715581c227dbc3c2c7567121dc5118751a7b0000000000000000000000000000000000000000000000000047f27f41e4138600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050cf9ddccdeed303f9bc1296bcd09083a62c725f00000000000000000000000050cf9ddccdeed303f9bc1296bcd09083a62c725f0000000000000000000000000000000000000000000000000030b1249eeb127700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000303b464c2b8f94c3f107655e0dfd595fd070f43b000000000000000000000000303b464c2b8f94c3f107655e0dfd595fd070f43b000000000000000000000000000000000000000000000000004e6b8db9ad3a2e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7640,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f14319280aa9757e41bf7c3fcd02af8b87009aec000000000000000000000000f14319280aa9757e41bf7c3fcd02af8b87009aec0000000000000000000000000000000000000000000000000081e7863b3b1be200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x517e438da569f7389f7f7c8703fe1974054cfbe0a835081af811520234f24931,2022-06-09 08:47:55.000 UTC,0,true +7641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006577d0b14abfce382d3912a9eff263b7981fb35b0000000000000000000000006577d0b14abfce382d3912a9eff263b7981fb35b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000adcfb436689d356ad27bfe508adb5b9d3bd5268e000000000000000000000000adcfb436689d356ad27bfe508adb5b9d3bd5268e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf10a9e1380ad7f369898e55491c54ce4baa3d67000000000000000000000000bf10a9e1380ad7f369898e55491c54ce4baa3d6700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7644,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000b4f1ed9aff74e4d0c75e3bb0e3fc637b3c040fca000000000000000000000000b4f1ed9aff74e4d0c75e3bb0e3fc637b3c040fca000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7645,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006686db6ede1acd9d912710debcac2f7ab35fd2e90000000000000000000000006686db6ede1acd9d912710debcac2f7ab35fd2e900000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7646,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000070498fbc17815115d12482f3666415853ef9b70e00000000000000000000000070498fbc17815115d12482f3666415853ef9b70e0000000000000000000000000000000000000000000000000036b67ce1e1629300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7647,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000283141f359a0aa691cb294072924dd449f98b560000000000000000000000000283141f359a0aa691cb294072924dd449f98b5600000000000000000000000000000000000000000000000002be01c867c2dc4200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7649,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006668460ef71721227b6d59a0cd091ce655bc9f7a0000000000000000000000006668460ef71721227b6d59a0cd091ce655bc9f7a000000000000000000000000000000000000000000000000001e87f2bb63444000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7651,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002922804f9d43dd90737c3c2d47eb787ed5d800e20000000000000000000000002922804f9d43dd90737c3c2d47eb787ed5d800e2000000000000000000000000000000000000000000000000008b93a93c26c00200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084e89efbead5707b3665707cd273704d36b3b98a00000000000000000000000084e89efbead5707b3665707cd273704d36b3b98a000000000000000000000000000000000000000000000000018109287ce0030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7654,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d70c7fc7e403b88ef65ea7581dd209314fce6df0000000000000000000000009d70c7fc7e403b88ef65ea7581dd209314fce6df000000000000000000000000000000000000000000000000006341a660658f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000df60be630e94a957b5f4033c7def69e1c4554bb6000000000000000000000000df60be630e94a957b5f4033c7def69e1c4554bb6000000000000000000000000000000000000000000000000000000001330c1f300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7657,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e04e81d73664ab466181f467d37b065021e78b50000000000000000000000003e04e81d73664ab466181f467d37b065021e78b5000000000000000000000000000000000000000000000000003ff2e795f5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5dc13274c280a380fda4490f3cab944338a01ee000000000000000000000000c5dc13274c280a380fda4490f3cab944338a01ee0000000000000000000000000000000000000000000000000050dc7bd9f5ec1500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7660,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006860fe601068c2ed033fdb17ca1bc8351db6a8a80000000000000000000000006860fe601068c2ed033fdb17ca1bc8351db6a8a8000000000000000000000000000000000000000000000000013a73e82249930000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7662,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf39ddbac5cfedc4476b4088904131ce3cad1d14000000000000000000000000bf39ddbac5cfedc4476b4088904131ce3cad1d140000000000000000000000000000000000000000000000000131f9a1516d1cf000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7663,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082a87dc8b036f8542d8373ef194b46b096eb41ad00000000000000000000000082a87dc8b036f8542d8373ef194b46b096eb41ad0000000000000000000000000000000000000000000000000015dfa32da4fb4300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a509ef076b42e1face74c267f454e60f1ce779bd000000000000000000000000a509ef076b42e1face74c267f454e60f1ce779bd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000443571116e56aa45b6bf8408641ef13474708c21000000000000000000000000443571116e56aa45b6bf8408641ef13474708c210000000000000000000000000000000000000000000000000003e871b540c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7666,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af297dec752c909092a117a932a8ca4aaaff9795000000000000000000000000af297dec752c909092a117a932a8ca4aaaff979500000000000000000000000000000000000000000000000002b834d8500c4c8400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa477a8986a9ef854b6a43e97ae05ecd585d39c8eb9a97fa19646fca1ee05704f,2022-08-06 22:25:41.000 UTC,0,true +7671,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b050e6833ae2d750c90183259d45fee366436e34000000000000000000000000b050e6833ae2d750c90183259d45fee366436e34000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045c0b853c382516ff6aa825ea1bb59d1aeafb1de00000000000000000000000045c0b853c382516ff6aa825ea1bb59d1aeafb1de000000000000000000000000000000000000000000000000002977670646daa000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7674,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026462ddd25e757d3f8dae688be7d78e6154a005000000000000000000000000026462ddd25e757d3f8dae688be7d78e6154a005000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7677,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000541f1e027ed075e356d895014c2da8778694ea6a000000000000000000000000541f1e027ed075e356d895014c2da8778694ea6a00000000000000000000000000000000000000000000000000eaaf3737da138400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7678,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b82f413c1efd1a2a6e7639d5c38fbec70ebe7941000000000000000000000000b82f413c1efd1a2a6e7639d5c38fbec70ebe79410000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005d4c5b72a62ca1e2548f1914252d31a9023fec700000000000000000000000005d4c5b72a62ca1e2548f1914252d31a9023fec7000000000000000000000000000000000000000000000000000ab5ea67a7910500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x093d477e04e391668e29a96121574ea4eba65185870fc84935fed4c9a6b61446,2022-04-26 17:44:13.000 UTC,0,true +7681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037824015ff5d2337339c7fde958fcdd2fd99151a00000000000000000000000037824015ff5d2337339c7fde958fcdd2fd99151a000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7682,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f16d205fb2ad682e9c844357194358ee3505706c000000000000000000000000f16d205fb2ad682e9c844357194358ee3505706c00000000000000000000000000000000000000000000000f21518bbffea3386300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7683,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039885aacc9dc0b053131605fc2f43b2f1275014300000000000000000000000039885aacc9dc0b053131605fc2f43b2f12750143000000000000000000000000000000000000000000000000001dd477d908370000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f48fc75f1dfc63d2f0636ca0292dd33918091c30000000000000000000000005f48fc75f1dfc63d2f0636ca0292dd33918091c300000000000000000000000000000000000000000000000000f38f04e566090000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea33cf28ccbf57277428c1c03c70c0a482efda52000000000000000000000000ea33cf28ccbf57277428c1c03c70c0a482efda52000000000000000000000000000000000000000000000000030d98d59a96000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7687,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b32f9141f100ebcc304f78bbd8ef9da730342170000000000000000000000008b32f9141f100ebcc304f78bbd8ef9da73034217000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b32f9141f100ebcc304f78bbd8ef9da730342170000000000000000000000008b32f9141f100ebcc304f78bbd8ef9da73034217000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7692,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043ccda6275973913ec16392afec6b1f547afded300000000000000000000000043ccda6275973913ec16392afec6b1f547afded30000000000000000000000000000000000000000000000000086633e873fdcb600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7693,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6bc866c9110ce7c29c197197d0e76204be1175e000000000000000000000000b6bc866c9110ce7c29c197197d0e76204be1175e000000000000000000000000000000000000000000000000001aaba9e27ad30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019935d31af29c8c7dd7a975b86ea63d712e4270f00000000000000000000000019935d31af29c8c7dd7a975b86ea63d712e4270f000000000000000000000000000000000000000000000000001866704f306e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7695,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007bcbeb74cf9297dc3bff964478bf8637f61c30a60000000000000000000000007bcbeb74cf9297dc3bff964478bf8637f61c30a6000000000000000000000000000000000000000000000000002a81827431cd4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2e81226fad8b5e2ca20145d6d06880e4bd2cf18000000000000000000000000b2e81226fad8b5e2ca20145d6d06880e4bd2cf180000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016217daf5a44a7b610ee836d51c5ee177b0efe7500000000000000000000000016217daf5a44a7b610ee836d51c5ee177b0efe750000000000000000000000000000000000000000000000000041399c31a0119a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7700,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000005bca305df5b8446546224d7e548ef4e681eacfc9000000000000000000000000000000000000000000000000a0c0676b65a05728,0x3ec8b5d5194d2e830f576c3f5cfd981389dcaef4c2a71871172f29eff58e51ca,2022-04-27 06:06:25.000 UTC,0,true +7701,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018361c087e74e742a84dc724dfec5b1565c6005800000000000000000000000018361c087e74e742a84dc724dfec5b1565c60058000000000000000000000000000000000000000000000000001b9241725cf3fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7ce80b7681693de60bc0e1e5d5ad37080523990000000000000000000000000a7ce80b7681693de60bc0e1e5d5ad370805239900000000000000000000000000000000000000000000000000034e06092dd1ac800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7703,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ef449eee029a136bf7d43ba1e1ba2350252b1d40000000000000000000000007ef449eee029a136bf7d43ba1e1ba2350252b1d400000000000000000000000000000000000000000000000000df9cc405d75f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab38b08d03e8011b9badb8472fb2a61d901754e1000000000000000000000000ab38b08d03e8011b9badb8472fb2a61d901754e1000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ff29c355d137c263062bde72a48523893bbd2440000000000000000000000001ff29c355d137c263062bde72a48523893bbd2440000000000000000000000000000000000000000000000000037bc3d8277c3c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002c5220549c03c01b8bc9435efa65a65a946b43300000000000000000000000002c5220549c03c01b8bc9435efa65a65a946b4330000000000000000000000000000000000000000000000000038463680fc668000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049c8eb6dd499473c368b7429f6d5110816bf1bb400000000000000000000000049c8eb6dd499473c368b7429f6d5110816bf1bb400000000000000000000000000000000000000000000000000363f4bcffdf6c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7708,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ceb97387e83c6a6f7d846bb5d8ab4deb2d16bebc000000000000000000000000ceb97387e83c6a6f7d846bb5d8ab4deb2d16bebc00000000000000000000000000000000000000000000000000268d857d475ac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7709,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000350b6bc3134039195e9a35663a5943f52d33734e000000000000000000000000350b6bc3134039195e9a35663a5943f52d33734e000000000000000000000000000000000000000000000000002e4dbe3087798000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7710,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9d90b7a1cc20b181560229e7263b9e1abaf66ee000000000000000000000000d9d90b7a1cc20b181560229e7263b9e1abaf66ee00000000000000000000000000000000000000000000000000263f8ae4d1db0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7711,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bd425a743300559d70490c4bb2c68d4e1bd80cd0000000000000000000000001bd425a743300559d70490c4bb2c68d4e1bd80cd00000000000000000000000000000000000000000000000000265805cff49b8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7712,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061d6edb871b41d0adbf263070c15a2af992e7f9d00000000000000000000000061d6edb871b41d0adbf263070c15a2af992e7f9d0000000000000000000000000000000000000000000000000028bbc836e1144000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6d3d319584ed3e9630f9592c4b51252a3f4c770000000000000000000000000f6d3d319584ed3e9630f9592c4b51252a3f4c770000000000000000000000000000000000000000000000000000a4d88ddd9400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082dd0a466e873367cc171335bf8b699f6045918f00000000000000000000000082dd0a466e873367cc171335bf8b699f6045918f000000000000000000000000000000000000000000000000002e1869fe5f95c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab40f53f84ad9a8dc03ccb2acf192df56236b573000000000000000000000000ab40f53f84ad9a8dc03ccb2acf192df56236b5730000000000000000000000000000000000000000000000000035366a0992e9d500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7718,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1bcdc1594dd5511c7cdeaf0dc149b7cfaf87cf1000000000000000000000000d1bcdc1594dd5511c7cdeaf0dc149b7cfaf87cf100000000000000000000000000000000000000000000000000007f4978ad333600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7720,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097c9b49b19b7f5cad4bec2933a68cfef21f4593900000000000000000000000097c9b49b19b7f5cad4bec2933a68cfef21f459390000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7722,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c76dc52cdc620480c81c8de2c2d71e6fc853a7ff000000000000000000000000c76dc52cdc620480c81c8de2c2d71e6fc853a7ff000000000000000000000000000000000000000000000000000e6506a1faeaad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7723,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e1e28903dab85d87f00feacaea6596fb41ec4e70000000000000000000000006e1e28903dab85d87f00feacaea6596fb41ec4e700000000000000000000000000000000000000000000000000010b8113f0304800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7727,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cb37d07f9314d47e81a8eb4447120e7521f9dea0000000000000000000000006cb37d07f9314d47e81a8eb4447120e7521f9dea000000000000000000000000000000000000000000000000008dc358448a182d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd497fb4a129b54902bf49068784e564d1f0ad56e5c8cc8d31bab028852b23c31,2021-12-12 11:55:52.000 UTC,0,true +7732,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c204f33f3bc17dd8d637d1edeb1b36c4696c64b4000000000000000000000000c204f33f3bc17dd8d637d1edeb1b36c4696c64b4000000000000000000000000000000000000000000000000008ec12ecd2a5fc500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1ddb13c83f96dd45f4db58d76dfbbe0f8c5d5e5000000000000000000000000e1ddb13c83f96dd45f4db58d76dfbbe0f8c5d5e500000000000000000000000000000000000000000000000000ab8bdad64ca20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7734,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b82238511d1e7e28f284c2691823ea971a382a96000000000000000000000000b82238511d1e7e28f284c2691823ea971a382a9600000000000000000000000000000000000000000000000000ab8bdad64ca20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7735,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce1976f7002d827388c76250173a6cbab0c5ad0d000000000000000000000000ce1976f7002d827388c76250173a6cbab0c5ad0d00000000000000000000000000000000000000000000000000a9f57eb0067b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7736,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046f7cd2d49ca9ced4ceb57ed5ef81337c576e30c00000000000000000000000046f7cd2d49ca9ced4ceb57ed5ef81337c576e30c00000000000000000000000000000000000000000000000000a904b30749440000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7737,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc103822d42b9861a0d98ae6506de2fd3e23b1d5000000000000000000000000dc103822d42b9861a0d98ae6506de2fd3e23b1d50000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff7bdbe12a3ad62b2815425c9f0d13d059c729a5000000000000000000000000ff7bdbe12a3ad62b2815425c9f0d13d059c729a500000000000000000000000000000000000000000000000000091fbff51e158000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009db71fb4da06a8cd93efeaf5bb2f685dced691110000000000000000000000009db71fb4da06a8cd93efeaf5bb2f685dced69111000000000000000000000000000000000000000000000000000ca6076d769e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000269a042f10fac5b5cf40d2c09810870150773a23000000000000000000000000269a042f10fac5b5cf40d2c09810870150773a23000000000000000000000000000000000000000000000000000ab70d1c7516c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7741,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000794f8281c1a4eb3c631d89bce6b30d60b9f542b0000000000000000000000000794f8281c1a4eb3c631d89bce6b30d60b9f542b00000000000000000000000000000000000000000000000000009345102f4f84000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc4503e550465fbc3086cf218152ecf9db58144a000000000000000000000000fc4503e550465fbc3086cf218152ecf9db58144a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7743,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab13daf038e0b10544e14638c1de3052b66b0771000000000000000000000000ab13daf038e0b10544e14638c1de3052b66b077100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe1bb644c349dfc485086715c8d80c491a273491000000000000000000000000fe1bb644c349dfc485086715c8d80c491a2734910000000000000000000000000000000000000000000000000011aafcb9c2b6f800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7749,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f815b421839515bf2a277739cc259b16b8e55293000000000000000000000000f815b421839515bf2a277739cc259b16b8e552930000000000000000000000000000000000000000000000000005a207389f7b8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7750,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000472da78b116e06940876819dee6011be15fd85e2000000000000000000000000472da78b116e06940876819dee6011be15fd85e2000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7754,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000618ca00c244fcf86f0f64338a1b480569e312a20000000000000000000000000618ca00c244fcf86f0f64338a1b480569e312a2000000000000000000000000000000000000000000000000020c0fb7f351310000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7755,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa2740d9e5462b4ffe05d15c3d168c99fbcf76f2000000000000000000000000fa2740d9e5462b4ffe05d15c3d168c99fbcf76f200000000000000000000000000000000000000000000000000c2c97a96bc188000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7756,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f361aa96041eb143ec27f65620dbd7a0ea325540000000000000000000000007f361aa96041eb143ec27f65620dbd7a0ea3255400000000000000000000000000000000000000000000000004ac404080f4f44000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000238baa6b4a877a55e18295d3be8ff6ffe4ab73c3000000000000000000000000238baa6b4a877a55e18295d3be8ff6ffe4ab73c3000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7759,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000005a9e51f5796310f633a90a9caf21eb57fb3b48bb0000000000000000000000000000000000000000000000000de0b6b3a7640000,,,1,true +7760,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f5f2223ba5756eb5403d05fd0b9df9fffed253f0000000000000000000000002f5f2223ba5756eb5403d05fd0b9df9fffed253f000000000000000000000000000000000000000000000000009eb4ad0c2c684000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7761,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf70e07186c442055218bf20c50522478235c4a0000000000000000000000000bf70e07186c442055218bf20c50522478235c4a000000000000000000000000000000000000000000000000000c3ab54e9e6533100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4ebde6ebefd2185e27add497979e148f928cf7888da245af8bfec2aaf1007fdc,2022-03-11 19:10:41.000 UTC,0,true +7762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bed6811c6bb261ab1a1059d5c4b779efa5735b40000000000000000000000004bed6811c6bb261ab1a1059d5c4b779efa5735b40000000000000000000000000000000000000000000000000085e7bf41d8950000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7765,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bdee104f077fc445b066c2378559d801fac58a0f000000000000000000000000000000000000000000000002c83956ea49404da0,,,1,true +7766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5b1c6d34ce0060f5b6fd6d23bbafcfce44a8ce5000000000000000000000000f5b1c6d34ce0060f5b6fd6d23bbafcfce44a8ce500000000000000000000000000000000000000000000000000a0e731003d117f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7767,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001cbb4c62da977613636a7a779a3f364dfd6906a40000000000000000000000001cbb4c62da977613636a7a779a3f364dfd6906a4000000000000000000000000000000000000000000000000000075d426888e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d2d56a152a454d8463ebad575fd85de790e28d30000000000000000000000001d2d56a152a454d8463ebad575fd85de790e28d300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006816cb8a561000742f459baf54a355cb38bcb01d0000000000000000000000006816cb8a561000742f459baf54a355cb38bcb01d00000000000000000000000000000000000000000000000000129d5951a94d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082c9c2dd525a4b3d549b4e2df70d3df9b9a738ed00000000000000000000000082c9c2dd525a4b3d549b4e2df70d3df9b9a738ed0000000000000000000000000000000000000000000000000011da09f214e3eb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d10f76a657d52adace28314787450d1753d39f85000000000000000000000000d10f76a657d52adace28314787450d1753d39f8500000000000000000000000000000000000000000000000000968603ec148dfd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a83bbbee6a05eb158371bc888deda2c853958a60000000000000000000000008a83bbbee6a05eb158371bc888deda2c853958a6000000000000000000000000000000000000000000000000000049281764c70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7782,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9034bcd20119ee7563d145dc817820690afd5fb000000000000000000000000e9034bcd20119ee7563d145dc817820690afd5fb000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7785,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000eba34ce0cd07f2df484ce6f04c6f89b18a2a4760000000000000000000000000eba34ce0cd07f2df484ce6f04c6f89b18a2a47600000000000000000000000000000000000000000000000000eb8a4df52fb0f6800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7786,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000bddf8194ccc04be52d3e66d5dfb63edba8735e40000000000000000000000000bddf8194ccc04be52d3e66d5dfb63edba8735e400000000000000000000000000000000000000000000000000de0db79f17ea7d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7787,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f11a600d875f83bf02337622c47d106e45f126d3000000000000000000000000f11a600d875f83bf02337622c47d106e45f126d30000000000000000000000000000000000000000000000000ec2b71761c60c0100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7789,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b42bc255de791f979a4b5ef296e1cff15e60cd55000000000000000000000000b42bc255de791f979a4b5ef296e1cff15e60cd550000000000000000000000000000000000000000000000000ec2b6d32080fd1800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7790,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000009c4665f252378a1c6d1aaa6172be1885b9cf87570000000000000000000000009c4665f252378a1c6d1aaa6172be1885b9cf87570000000000000000000000000000000000000000000000000ec2b52e8a335d8b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7791,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000192755ce697d06f694e3b218d1c462b17e7bac50000000000000000000000000192755ce697d06f694e3b218d1c462b17e7bac500000000000000000000000000000000000000000000000000eb429ad131557bf00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7792,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000088146955a7207a1cee4213c3c92b411993588ae200000000000000000000000088146955a7207a1cee4213c3c92b411993588ae20000000000000000000000000000000000000000000000000eb30827623d65a100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7793,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e11f1b9b2e41e1bdc4ffee660c4414ce10867f1e000000000000000000000000e11f1b9b2e41e1bdc4ffee660c4414ce10867f1e0000000000000000000000000000000000000000000000000eb5d4f036c13ab600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7794,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004ab31beab901c582cbf32d38f041ecb30f4096d80000000000000000000000004ab31beab901c582cbf32d38f041ecb30f4096d80000000000000000000000000000000000000000000000000eb45b0f8da491b600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7795,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ebf2658fae3ddae5e4065c3426066ca5b8eb2218000000000000000000000000ebf2658fae3ddae5e4065c3426066ca5b8eb22180000000000000000000000000000000000000000000000000000000000103c8100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a3c473b5f1d471d7cfc0d0f9b7fb76a8e554ff70000000000000000000000000a3c473b5f1d471d7cfc0d0f9b7fb76a8e554ff7000000000000000000000000000000000000000000000000001675cc77d7210000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000060d5a2efa14e0772ae04e4f31d1ecb6f4dfd03cf00000000000000000000000060d5a2efa14e0772ae04e4f31d1ecb6f4dfd03cf0000000000000000000000000000000000000000000000000000000000103ade00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7798,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000bd4f6a77a34bd6527b915bf7de56dc61b947d924000000000000000000000000bd4f6a77a34bd6527b915bf7de56dc61b947d9240000000000000000000000000000000000000000000000000000000000104f9200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7799,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008ea5804927b508057c7361ece58b9604a79da2800000000000000000000000008ea5804927b508057c7361ece58b9604a79da2800000000000000000000000000000000000000000000000000937007b62dc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x35bde942b8e53ad00ced8db112038bc7eee03b041703c591b05ca2560892a448,2021-12-12 08:20:07.000 UTC,0,true +7800,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000b90b37c007cafda8154d6cf6e1b74924b781f37c000000000000000000000000b90b37c007cafda8154d6cf6e1b74924b781f37c000000000000000000000000000000000000000000000000000000000010529100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7803,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000019c7ff37b882829d6d821733d7a102ee37653df800000000000000000000000019c7ff37b882829d6d821733d7a102ee37653df80000000000000000000000000000000000000000000000000000000001ba814000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7805,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000046d22bcfeedc27c643953b5945d766ae73d4852d0000000000000000000000000000000000000000000000291819341b91c52987,0xe726b47830149d9b59d751af4a4091452eead1d70576d69c7047943920bf81fc,2021-11-26 06:22:09.000 UTC,0,true +7806,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c590ed9c6b18cefb629917280b25e7f08914220d000000000000000000000000c590ed9c6b18cefb629917280b25e7f08914220d000000000000000000000000000000000000000000000000004b52cd32c783ea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7807,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007aff06e2f0e25d0e291b086b92889ec2df3aa2240000000000000000000000007aff06e2f0e25d0e291b086b92889ec2df3aa224000000000000000000000000000000000000000000000000002642bc8e9667fa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7809,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c730b3763297722f73a2eef7bef8939bfa0900ec000000000000000000000000c730b3763297722f73a2eef7bef8939bfa0900ec00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bba1ab4d90cf352c7f4efbaa1a4d782845391a80000000000000000000000001bba1ab4d90cf352c7f4efbaa1a4d782845391a800000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7813,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007ef5cf7ee561ce57250faca9a99e9f85d50705b60000000000000000000000007ef5cf7ee561ce57250faca9a99e9f85d50705b600000000000000000000000000000000000000000000005adcdd4461fb9b7db200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff059d87096d1edf40ab0af9f1bd32efebcfb386000000000000000000000000ff059d87096d1edf40ab0af9f1bd32efebcfb386000000000000000000000000000000000000000000000000016e7333114ebfc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001df9b5a2ad6b5b4611de9cb8a069ff1d200bb8280000000000000000000000001df9b5a2ad6b5b4611de9cb8a069ff1d200bb8280000000000000000000000000000000000000000000000000000befe6f67200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087dc8ee4ce4feef4c4d38a84fda9768d39e51cec00000000000000000000000087dc8ee4ce4feef4c4d38a84fda9768d39e51cec00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000061751119a686def10ee8f60671c670c290f927a000000000000000000000000061751119a686def10ee8f60671c670c290f927a00000000000000000000000000000000000000000000000000313146e991560900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067c1bb9d5408655bacd89773f5534d039bfa765a00000000000000000000000067c1bb9d5408655bacd89773f5534d039bfa765a00000000000000000000000000000000000000000000000001515bc7f76f3e8e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000017c8616c5744bc4b3660238d7c34f1747466c54000000000000000000000000017c8616c5744bc4b3660238d7c34f1747466c54000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7823,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000439ab76ed2369bb987d958a0ee7d1c7c50d7c898000000000000000000000000439ab76ed2369bb987d958a0ee7d1c7c50d7c89800000000000000000000000000000000000000000000021e6f49f35c5e70796600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9346c2cfd24541af4c54c8ef2e5aa6f3d4834c1000000000000000000000000f9346c2cfd24541af4c54c8ef2e5aa6f3d4834c10000000000000000000000000000000000000000000000000027b8e76324600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be7dd3a9bede56136bef4669337b64d8dc463146000000000000000000000000be7dd3a9bede56136bef4669337b64d8dc46314600000000000000000000000000000000000000000000000000ac37da05af370000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000361cf5e2fe3925ff2e7ce5a44bf1a38c12e2fafd000000000000000000000000361cf5e2fe3925ff2e7ce5a44bf1a38c12e2fafd00000000000000000000000000000000000000000000000000abb5868e1c810000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000035e0050e5c244bdf5a1c8e9b68b8ce51df73de4000000000000000000000000035e0050e5c244bdf5a1c8e9b68b8ce51df73de400000000000000000000000000000000000000000000000000aad806faec390000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000dd71c2b33bc97260575c53003ec68c65b9d85e00000000000000000000000000dd71c2b33bc97260575c53003ec68c65b9d85e000000000000000000000000000000000000000000000000000ab66f03dc4960000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c9fd82a2bd26b4cd848e0255b5e77a2f055921b0000000000000000000000003c9fd82a2bd26b4cd848e0255b5e77a2f055921b00000000000000000000000000000000000000000000000000ac17215b93b80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7831,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9ba8d9576c19b61e2ad21963af0dfb9d6d65d7b000000000000000000000000c9ba8d9576c19b61e2ad21963af0dfb9d6d65d7b00000000000000000000000000000000000000000000000000acabea1f6a740000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cc5163b4409c1ad7b0395c5deca0e515020fc300000000000000000000000007cc5163b4409c1ad7b0395c5deca0e515020fc3000000000000000000000000000000000000000000000000000ac10b2a9ba130000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfea3acaaae83da01c21baeb33c261b0e863616c000000000000000000000000cfea3acaaae83da01c21baeb33c261b0e863616c00000000000000000000000000000000000000000000000000ac17215b93b80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae93d722db362e3f146dfc35f4eb0eaec71eae3f000000000000000000000000ae93d722db362e3f146dfc35f4eb0eaec71eae3f00000000000000000000000000000000000000000000000000ac847b2b07ad0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000031bd88e60b7fd952a9b99914de2781b28bf3f35000000000000000000000000031bd88e60b7fd952a9b99914de2781b28bf3f3500000000000000000000000000000000000000000000000000ac847b2b07ad0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d12acade9a3e66e0fb2c9de727bdd28d12655160000000000000000000000000d12acade9a3e66e0fb2c9de727bdd28d1265516000000000000000000000000000000000000000000000000000ab301f89d3ca0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000643207a711f81626d8eb3c605097efa50aa3ef6f000000000000000000000000643207a711f81626d8eb3c605097efa50aa3ef6f00000000000000000000000000000000000000000000000000aae4552dc43d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a82b4429156db6d64ea3977816676b66863309ff000000000000000000000000a82b4429156db6d64ea3977816676b66863309ff00000000000000000000000000000000000000000000000000abc88b0b3bcd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7840,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfd0ae189d1e08df256d4a4f9031f684489ef72a000000000000000000000000cfd0ae189d1e08df256d4a4f9031f684489ef72a00000000000000000000000000000000000000000000000000abf041980c370000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea88074ed8a8ba08fa038a59d3fb8387e1c5268c000000000000000000000000ea88074ed8a8ba08fa038a59d3fb8387e1c5268c00000000000000000000000000000000000000000000000000ab1bb512904f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000139106c7afede02d0957ebc49756e3156c88c7f0000000000000000000000000139106c7afede02d0957ebc49756e3156c88c7f00000000000000000000000000000000000000000000000000ac893c4a4f800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e0badf855e6e92b94ab584bb6a8699add1b985b0000000000000000000000003e0badf855e6e92b94ab584bb6a8699add1b985b00000000000000000000000000000000000000000000000000ac9081c5720e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078699b7ab6ccbc5af1d36cef503045b67c614d6800000000000000000000000078699b7ab6ccbc5af1d36cef503045b67c614d6800000000000000000000000000000000000000000000000000aace84bc5c930000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008fde022fb6c8020c8ba21b890c24d6a9df0fc9100000000000000000000000008fde022fb6c8020c8ba21b890c24d6a9df0fc9100000000000000000000000000000000000000000000000000ac010951be6b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffc1100973a5247afcd0c008e48a8030d3c00bb0000000000000000000000000ffc1100973a5247afcd0c008e48a8030d3c00bb000000000000000000000000000000000000000000000000000ab28da0eb13c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040a5f5b02af3e1d3eb64d28c19e840f56490503f00000000000000000000000040a5f5b02af3e1d3eb64d28c19e840f56490503f00000000000000000000000000000000000000000000000000aa8733e727360000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003054e421b52338d44a1d95e88fc58ba773b0a1120000000000000000000000003054e421b52338d44a1d95e88fc58ba773b0a11200000000000000000000000000000000000000000000000000aa6a1dfa9cfe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5b009d80019070b71c83cd41d79e564418ec4c1000000000000000000000000c5b009d80019070b71c83cd41d79e564418ec4c100000000000000000000000000000000000000000000000000ab8b4ba5715c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000539eb2aee60122d1a9b5b59554b5648eeadd83a8000000000000000000000000539eb2aee60122d1a9b5b59554b5648eeadd83a800000000000000000000000000000000000000000000000000ace10d40c96e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4217061de88bb05f2bac6d8aea3699282db3b9c000000000000000000000000a4217061de88bb05f2bac6d8aea3699282db3b9c00000000000000000000000000000000000000000000000000acebf5797d430000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2c61e450304898b7ebf700db2e3e1c0a58daaee000000000000000000000000f2c61e450304898b7ebf700db2e3e1c0a58daaee00000000000000000000000000000000000000000000000000a3f94729f1e49200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7855,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000499428155f893e88abfa89dbef4d5017ee3b92ff000000000000000000000000499428155f893e88abfa89dbef4d5017ee3b92ff0000000000000000000000000000000000000000000000000005fcdc92d4dbe500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008621bf24c4fe541faa4f3e3d6abf05dbe657b4630000000000000000000000008621bf24c4fe541faa4f3e3d6abf05dbe657b46300000000000000000000000000000000000000000000000000acda56f682260000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000488c0746bbc745ecdf26498499319ec89a2f96fe000000000000000000000000488c0746bbc745ecdf26498499319ec89a2f96fe00000000000000000000000000000000000000000000000000ac53425fa79d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7858,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039c950d42f47d4d29cb4a581c2bfedb824774cf400000000000000000000000039c950d42f47d4d29cb4a581c2bfedb824774cf400000000000000000000000000000000000000000000000000abd32bab81ff0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7859,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000246bce86884439b5de18730ad32c20bd65216417000000000000000000000000246bce86884439b5de18730ad32c20bd6521641700000000000000000000000000000000000000000000000000ac149cffb8fd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b856c3909aa63f205fba6c3c3f18bb90c9b0611a000000000000000000000000b856c3909aa63f205fba6c3c3f18bb90c9b0611a00000000000000000000000000000000000000000000000000abcb0f6716880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ebda3411c77a6a2f6381432f41336d826fe458dd000000000000000000000000ebda3411c77a6a2f6381432f41336d826fe458dd00000000000000000000000000000000000000000000000000ac20eb3291010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7862,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0386d27624ed1b0eceb501b075446a73152619f000000000000000000000000b0386d27624ed1b0eceb501b075446a73152619f00000000000000000000000000000000000000000000000000ac8001a42d7d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6e2ca8299f23ca47493bdf5a03c8cf6d15e1fbb000000000000000000000000d6e2ca8299f23ca47493bdf5a03c8cf6d15e1fbb00000000000000000000000000000000000000000000000000ac8001a42d7d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c5a6123f4fa37f8563d437c13f7a221dfaf19e10000000000000000000000009c5a6123f4fa37f8563d437c13f7a221dfaf19e100000000000000000000000000000000000000000000000000ac2ee6f7fad70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7865,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fa5d33b4ef02758cac386cb12b48f7510e5d7fd0000000000000000000000002fa5d33b4ef02758cac386cb12b48f7510e5d7fd00000000000000000000000000000000000000000000000000abcf415583150000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7866,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fab1a103edc0e7020dcd764c2b621c7da1297e70000000000000000000000001fab1a103edc0e7020dcd764c2b621c7da1297e700000000000000000000000000000000000000000000000000abcf415583150000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e67500000000000000000000000057ab1ec28d129707052df4df418d58a2d46d5f510000000000000000000000008c6f28f2f1a3c87f0f938b96d27520d9751ec8d9000000000000000000000000656fafabbf1b8c42b4f63ab15f9bee8027a25978000000000000000000000000656fafabbf1b8c42b4f63ab15f9bee8027a259780000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7868,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000878bc19bb4c346bd7db6189a2c3733d1844b0b19000000000000000000000000878bc19bb4c346bd7db6189a2c3733d1844b0b1900000000000000000000000000000000000000000000000000aa4dded75baf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095dacc17b990d7f010109ae64765f67b2748b64a00000000000000000000000095dacc17b990d7f010109ae64765f67b2748b64a00000000000000000000000000000000000000000000000000aa8ccbcfb7f20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ba1c716dcbcf2ae512d275752d38b027c9d1ff50000000000000000000000002ba1c716dcbcf2ae512d275752d38b027c9d1ff500000000000000000000000000000000000000000000000000a9e9307d2e770000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1f25c3605a4d6ba7f213e3bcaef2001603b98b0000000000000000000000000d1f25c3605a4d6ba7f213e3bcaef2001603b98b000000000000000000000000000000000000000000000000000aa7a0eeb06490000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032d641b2d54a46b9e4448bf35f667e17da2fd14d00000000000000000000000032d641b2d54a46b9e4448bf35f667e17da2fd14d000000000000000000000000000000000000000000000000026a3bd6fd71075e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c272a7f4cb36058880362dfa5c5fcd330e8084ad000000000000000000000000c272a7f4cb36058880362dfa5c5fcd330e8084ad00000000000000000000000000000000000000000000000000ac0ad328bbb40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7874,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076052b96412a486647a911562f1c395394587dd900000000000000000000000076052b96412a486647a911562f1c395394587dd900000000000000000000000000000000000000000000000000ac5c356d5bfd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7875,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a920cd19f49f14185fba187b6cb45a8f909ea31c000000000000000000000000a920cd19f49f14185fba187b6cb45a8f909ea31c00000000000000000000000000000000000000000000000000ac5c356d5bfd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043d968da7bb8d89a9eae51088bde865fc636cb9400000000000000000000000043d968da7bb8d89a9eae51088bde865fc636cb9400000000000000000000000000000000000000000000000000ac2ee6f7fad70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048d932097ea2e401fab65426a14c7d58b0a0e40700000000000000000000000048d932097ea2e401fab65426a14c7d58b0a0e40700000000000000000000000000000000000000000000000000ac2ee6f7fad70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075e41492b7915ace101d66946f36e61885efe3fc00000000000000000000000075e41492b7915ace101d66946f36e61885efe3fc00000000000000000000000000000000000000000000000000ac2ee6f7fad70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6ab573c00e0c4340bbe89c500d16452e2e203b9000000000000000000000000b6ab573c00e0c4340bbe89c500d16452e2e203b900000000000000000000000000000000000000000000000000aac54a163a900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8d16f7695bb0232619f183f2903854ec33670cc000000000000000000000000f8d16f7695bb0232619f183f2903854ec33670cc00000000000000000000000000000000000000000000000000abece672e8930000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000985abc5fd8d85cc4e0d0c17275535d5d27bf2bd0000000000000000000000000985abc5fd8d85cc4e0d0c17275535d5d27bf2bd000000000000000000000000000000000000000000000000000a7233d69492c2b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba22884e029afd269c42b069cf41df45170ef3da000000000000000000000000ba22884e029afd269c42b069cf41df45170ef3da0000000000000000000000000000000000000000000000000148a6a40063021900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004009526a0679bfca93056822ffef50265ac1c1f50000000000000000000000004009526a0679bfca93056822ffef50265ac1c1f50000000000000000000000000000000000000000000000000159dd434c812bd300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x29c36db02a90d6484f45427336bad3cce0f702829c98687c798e07f218862e0b,2022-03-21 01:19:27.000 UTC,0,true +7886,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003d2a9ff2e85b64fbdc433dc8ffe8f4bf3358999e0000000000000000000000000000000000000000000000a1224e02cddb531aaa,,,1,true +7887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000985ced69658f06727ecb691b16987191a5250634000000000000000000000000985ced69658f06727ecb691b16987191a5250634000000000000000000000000000000000000000000000000005a1e203eae76b400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe18fa79295de47b6602236c7b46b487f6927a30000000000000000000000000fe18fa79295de47b6602236c7b46b487f6927a30000000000000000000000000000000000000000000000000002cd2692658780000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009be5ca1ac018460574933a2e065cb04f675ee6260000000000000000000000009be5ca1ac018460574933a2e065cb04f675ee626000000000000000000000000000000000000000000000000015713afb7ebc07800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd03d5e3cee5945c85d1fede621cafb7543e972dc61183926fb8ba6c1e7a52630,2022-04-13 06:28:11.000 UTC,0,true +7891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000187d7570362140deda52d4ead921b00c3a2efb1f000000000000000000000000187d7570362140deda52d4ead921b00c3a2efb1f000000000000000000000000000000000000000000000000005f74f5e92becaf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5cf553b66ce0dafb2acf1c70e0e8af7232459cf000000000000000000000000e5cf553b66ce0dafb2acf1c70e0e8af7232459cf00000000000000000000000000000000000000000000000000240b882cf9b8df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009039326a3c562bcb02c04db463e4790f0ec79ab30000000000000000000000009039326a3c562bcb02c04db463e4790f0ec79ab3000000000000000000000000000000000000000000000000011338eaf7ccfafd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7894,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ad014a4dd7893447242333dfeed5852d57b72d00000000000000000000000007ad014a4dd7893447242333dfeed5852d57b72d000000000000000000000000000000000000000000000000000442361743b9ed700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc36df9e64431481fd24eac8afe9adafe8f449ec000000000000000000000000cc36df9e64431481fd24eac8afe9adafe8f449ec000000000000000000000000000000000000000000000000005dc919cb8a3a3d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5c34f3bc6e950e1c4756b058ee31a744716a64e000000000000000000000000b5c34f3bc6e950e1c4756b058ee31a744716a64e000000000000000000000000000000000000000000000000004f2764812ae5d800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7898,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4bbec1cee2de29632cfdfddae9b22243afb9c16000000000000000000000000e4bbec1cee2de29632cfdfddae9b22243afb9c1600000000000000000000000000000000000000000000000000a2aa6450d95c4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7901,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000820b0cbe7f4df3b3f186377a2fa9d626062ae98e000000000000000000000000820b0cbe7f4df3b3f186377a2fa9d626062ae98e00000000000000000000000000000000000000000000000000146de3bfcb794000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9f513d12057e23b0719ead57af009e77f23a9d5000000000000000000000000f9f513d12057e23b0719ead57af009e77f23a9d5000000000000000000000000000000000000000000000000001e7e3a44fdb40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7903,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000018695c5660fc0bf3a3f50c5d81477686c2ffa5e000000000000000000000000018695c5660fc0bf3a3f50c5d81477686c2ffa5e000000000000000000000000000000000000000000000000005da6a79d1eaef400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7904,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056498320e99df15093e6e052c956bb188da210af00000000000000000000000056498320e99df15093e6e052c956bb188da210af000000000000000000000000000000000000000000000000006c22ad5047791c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9f88d38960c80ab785d15875de42de9984fa55a19be3febe151a94db9f47c40a,2022-03-10 10:13:02.000 UTC,0,true +7905,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c65c2ee6e87264139139553d5e4266ebc29b4020000000000000000000000000c65c2ee6e87264139139553d5e4266ebc29b40200000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d41cc18d57125fb07e3cd2ebb322c6c4cb4eef3e000000000000000000000000d41cc18d57125fb07e3cd2ebb322c6c4cb4eef3e00000000000000000000000000000000000000000000000000035fc57210514000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7907,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc47bfe4887b82cccf2b1af40d1bf6a6e6708e89000000000000000000000000bc47bfe4887b82cccf2b1af40d1bf6a6e6708e89000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7908,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d907f8a147df1120602818039ee7e0d801e9db0a000000000000000000000000d907f8a147df1120602818039ee7e0d801e9db0a000000000000000000000000000000000000000000000000005ce6301578e68500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c01528c7e09ce05e7734d915f5009ad40e056886000000000000000000000000c01528c7e09ce05e7734d915f5009ad40e05688600000000000000000000000000000000000000000000000000669a34fd1d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1118ad43a3184850475d1fb35080c9c00720885000000000000000000000000b1118ad43a3184850475d1fb35080c9c0072088500000000000000000000000000000000000000000000000000d420dee112365600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7912,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000528db62f1828b284eb2041296aecb4dac9f0515c00000000000000000000000000000000000000000000000059cc6d80cb5ca42c,,,1,true +7914,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000003a58d948bbc6e4ee1cac210f1b4451bc3274c3e00000000000000000000000003a58d948bbc6e4ee1cac210f1b4451bc3274c3e00000000000000000000000000000000000000000000000029a2241af62c070800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000499428155f893e88abfa89dbef4d5017ee3b92ff000000000000000000000000499428155f893e88abfa89dbef4d5017ee3b92ff00000000000000000000000000000000000000000000000000302eb67d7142f800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002edf166a658af79c5c8bb268265a7def157eb62e0000000000000000000000002edf166a658af79c5c8bb268265a7def157eb62e000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035164610721ffab73d28e4a16e32607288946af400000000000000000000000035164610721ffab73d28e4a16e32607288946af40000000000000000000000000000000000000000000000000000b74e279e070000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a12747381fa12208b493f57fe0e28d59a42ce7e0000000000000000000000003a12747381fa12208b493f57fe0e28d59a42ce7e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5a8674e1e244c61a4587849ccb0e66653072a00000000000000000000000000c5a8674e1e244c61a4587849ccb0e66653072a00000000000000000000000000000000000000000000000000003712499b08218000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008659adf49357be438c6337a524c4d08559aa09f20000000000000000000000008659adf49357be438c6337a524c4d08559aa09f2000000000000000000000000000000000000000000000000005a4daa4e80ad7d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2f064a3e85308efbd67ea1fa9f3d58c8f8e8123000000000000000000000000f2f064a3e85308efbd67ea1fa9f3d58c8f8e81230000000000000000000000000000000000000000000000000dc7d83d25f6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdb8e2cb7e7af95ca2e9c327ce255d1f92e19efb000000000000000000000000bdb8e2cb7e7af95ca2e9c327ce255d1f92e19efb000000000000000000000000000000000000000000000000043555f6d2a7705a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7928,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005795b03e97c48c57864c383186921cde539806ef0000000000000000000000005795b03e97c48c57864c383186921cde539806ef00000000000000000000000000000000000000000000000000615a740c351f9200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7929,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7f34f09416de766e03003e50dcf6f27e072ce73000000000000000000000000c7f34f09416de766e03003e50dcf6f27e072ce7300000000000000000000000000000000000000000000000001459ca2ae03484100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x451d9237d699ac260867e39c15c9d9f136d2e79422a0a99b1d9bdc565a081320,2022-01-08 11:00:32.000 UTC,0,true +7930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e11f47e997c19f39b0559d3a2be89501e0615e18000000000000000000000000e11f47e997c19f39b0559d3a2be89501e0615e18000000000000000000000000000000000000000000000000001ea9db27cd080000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7932,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1c6f64a27a3134aac5808e862601747d9bd0bcb000000000000000000000000f1c6f64a27a3134aac5808e862601747d9bd0bcb000000000000000000000000000000000000000000000000057df149cd31822400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x322e9aa1863a8dc85ba7a390f40b7e369f79e487421374cbdec8283b25acc4e7,2021-12-20 09:38:08.000 UTC,0,true +7934,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5475abd39d6b73a3b74fb535e46bc6c9c032b2d000000000000000000000000e5475abd39d6b73a3b74fb535e46bc6c9c032b2d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f5bf901261249bae99c6eaaddf8e9907b756de10000000000000000000000002f5bf901261249bae99c6eaaddf8e9907b756de1000000000000000000000000000000000000000000000000005d6e183917a0b200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009094eff2adf2ad7c22c5419c427042e707fe70160000000000000000000000009094eff2adf2ad7c22c5419c427042e707fe7016000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009094eff2adf2ad7c22c5419c427042e707fe70160000000000000000000000009094eff2adf2ad7c22c5419c427042e707fe70160000000000000000000000000000000000000000000000000003328b944c400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ce09978479907597943dd81dc3c318b0ed5ef6d0000000000000000000000004ce09978479907597943dd81dc3c318b0ed5ef6d00000000000000000000000000000000000000000000000000a4ebc75921a46700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab8e1229e0d1ba185f2940a7f4e3835bcb106acf000000000000000000000000ab8e1229e0d1ba185f2940a7f4e3835bcb106acf0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7941,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000b5e2f50af7be3724198a74f8529ada0b135bb87d000000000000000000000000b5e2f50af7be3724198a74f8529ada0b135bb87d0000000000000000000000000000000000000000000000000000000006d0f46800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x79fa17de86315bdaf90cad35956338624cbc5787a33c97daa21b9a0c486f0a4d,2022-09-07 15:15:32.000 UTC,0,true +7942,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005f4b9a4300cbd45b113f6028f7f6dbd1b5955f800000000000000000000000005f4b9a4300cbd45b113f6028f7f6dbd1b5955f80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f90c4ca068955811f6b57b953c552ed73946ab86000000000000000000000000f90c4ca068955811f6b57b953c552ed73946ab86000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7944,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e83c1c23fe932de2b3e9048623f6ec812c837478000000000000000000000000e83c1c23fe932de2b3e9048623f6ec812c83747800000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7946,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003807865c2b82eb2b41dbfe51a328be275d8433980000000000000000000000003807865c2b82eb2b41dbfe51a328be275d84339800000000000000000000000000000000000000000000000000421878ca4ba30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xac7b225d07d1e53214a66c7a6538388a85239e942afd3cc094876209fb5c5f5c,2022-03-13 09:17:38.000 UTC,0,true +7947,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e4e87ef976eab568fda866d23141d37950baf4d9000000000000000000000000e4e87ef976eab568fda866d23141d37950baf4d9000000000000000000000000000000000000000000000460d5281b496a5f4bc300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +7949,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4e87ef976eab568fda866d23141d37950baf4d9000000000000000000000000e4e87ef976eab568fda866d23141d37950baf4d90000000000000000000000000000000000000000000000000b428ceb6623e85400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7950,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d274079a4157cd9ad7545f0ff7fb3d7b472fb570000000000000000000000005d274079a4157cd9ad7545f0ff7fb3d7b472fb570000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7951,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a509ef076b42e1face74c267f454e60f1ce779bd000000000000000000000000a509ef076b42e1face74c267f454e60f1ce779bd00000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006577d0b14abfce382d3912a9eff263b7981fb35b0000000000000000000000006577d0b14abfce382d3912a9eff263b7981fb35b00000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eeaa75be33235789287252d238cbe9f2c58ac051000000000000000000000000eeaa75be33235789287252d238cbe9f2c58ac05100000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7954,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006577d0b14abfce382d3912a9eff263b7981fb35b0000000000000000000000006577d0b14abfce382d3912a9eff263b7981fb35b00000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7955,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000443571116e56aa45b6bf8408641ef13474708c21000000000000000000000000443571116e56aa45b6bf8408641ef13474708c2100000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7956,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6b9b2568b071e4d06cf740371b7607ba6469fe2000000000000000000000000a6b9b2568b071e4d06cf740371b7607ba6469fe2000000000000000000000000000000000000000000000000001ef6c3e593210000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7957,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfd3ab57c7a6b5a1e8fd18d728123d26373bec66000000000000000000000000bfd3ab57c7a6b5a1e8fd18d728123d26373bec6600000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f78944945b0e0450f5ecde5d8e2004fba5b8a3f4000000000000000000000000f78944945b0e0450f5ecde5d8e2004fba5b8a3f400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b32476579accb1dab72bbb39c843857d92d076b0000000000000000000000002b32476579accb1dab72bbb39c843857d92d076b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002e9a5f06ad0c9b372e696991b4091534cf3e7c200000000000000000000000002e9a5f06ad0c9b372e696991b4091534cf3e7c2000000000000000000000000000000000000000000000000000997a2bce4c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e08cc99723d23b660f7c4aabffae784e2e5aaaee000000000000000000000000e08cc99723d23b660f7c4aabffae784e2e5aaaee00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7964,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9c8c0adb686ba89c18d4b5428223c6111349f68000000000000000000000000e9c8c0adb686ba89c18d4b5428223c6111349f6800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b32476579accb1dab72bbb39c843857d92d076b0000000000000000000000002b32476579accb1dab72bbb39c843857d92d076b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7967,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f784bcac40eb7ba2b3969e8e13227679f62d0c27000000000000000000000000f784bcac40eb7ba2b3969e8e13227679f62d0c2700000000000000000000000000000000000000000000000000051d8e26c99d1c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000826b31fc2badc1cc8724de4b3f69b79201877d61000000000000000000000000826b31fc2badc1cc8724de4b3f69b79201877d61000000000000000000000000000000000000000000000000001f5c90a176e50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7970,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000245f36c27de0d8f371b303cca1239b797802a25e000000000000000000000000245f36c27de0d8f371b303cca1239b797802a25e000000000000000000000000000000000000000000000000000c41c1b879a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004be97ec3f1c6a386d5ddf2c0a72e98463bb107ad0000000000000000000000004be97ec3f1c6a386d5ddf2c0a72e98463bb107ad0000000000000000000000000000000000000000000000000008b53920d0bf8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7973,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fc0e14cf00122df50f0fc8ea599572a0386b1e20000000000000000000000000fc0e14cf00122df50f0fc8ea599572a0386b1e20000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e24f8451461a17aacfbfdd1521cc47f432c8d349000000000000000000000000e24f8451461a17aacfbfdd1521cc47f432c8d349000000000000000000000000000000000000000000000000025205397e0b7a4500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf87933b5e67a59e1825c4a399362b821379e586fc4898365326558164b1fee3f,2022-02-25 15:39:20.000 UTC,0,true +7976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000302e559551f93374ef1a0feaed42e34f36ff72e4000000000000000000000000302e559551f93374ef1a0feaed42e34f36ff72e4000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7913ee1f2a4f307917a7099b6903b5251745d24000000000000000000000000c7913ee1f2a4f307917a7099b6903b5251745d24000000000000000000000000000000000000000000000000001ebb79aac8250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7979,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0c5b14cdf7daeaae92a0313d81322d4f7f92275000000000000000000000000a0c5b14cdf7daeaae92a0313d81322d4f7f922750000000000000000000000000000000000000000000000000044a88afd6c21c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7980,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b5f4db264257d14c84c2cfe4beb8dbe2e93de1a0000000000000000000000006b5f4db264257d14c84c2cfe4beb8dbe2e93de1a000000000000000000000000000000000000000000000000001f36400ecaaa0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e153b3f9fce55abc3ab26d6513a634c5cb5f9213000000000000000000000000e153b3f9fce55abc3ab26d6513a634c5cb5f9213000000000000000000000000000000000000000000000000000b5e620f48000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7983,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e292babb03689c7d55d83a903f9da81b55ec8959000000000000000000000000e292babb03689c7d55d83a903f9da81b55ec89590000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7986,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002370ab10aa4965abad72e08ee40df72aaede124f0000000000000000000000002370ab10aa4965abad72e08ee40df72aaede124f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9feb729a473a46b1939a5b409096f754f97eeb9000000000000000000000000c9feb729a473a46b1939a5b409096f754f97eeb900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7988,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003ba15bf6d3c597d9e7e0eb76ea522fc089ec30200000000000000000000000003ba15bf6d3c597d9e7e0eb76ea522fc089ec30200000000000000000000000000000000000000000000000000b807d3575d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7989,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e5d20108ffcbdcf9bf9be93c0bb0fb0c7fa83130000000000000000000000004e5d20108ffcbdcf9bf9be93c0bb0fb0c7fa831300000000000000000000000000000000000000000000000000201b051d1d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000762009efa840eb7ed893049b2d2b787502879d7c000000000000000000000000762009efa840eb7ed893049b2d2b787502879d7c000000000000000000000000000000000000000000000000001f1c3daef6730000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7991,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021a8394c620a3ed1327f689ccf319aba059aca8e00000000000000000000000021a8394c620a3ed1327f689ccf319aba059aca8e00000000000000000000000000000000000000000000000000ca8132b032800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7992,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5788c5d9a05c7b9b85eef7501a0689451823bc2000000000000000000000000e5788c5d9a05c7b9b85eef7501a0689451823bc200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c353fa34b747faef8035f09c1aa90136eaf5a153000000000000000000000000c353fa34b747faef8035f09c1aa90136eaf5a153000000000000000000000000000000000000000000000000001fa470a787880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000274c3e5dc565a4845fa73acf6536a01f3e43104f000000000000000000000000274c3e5dc565a4845fa73acf6536a01f3e43104f00000000000000000000000000000000000000000000000000a6fa404071800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7995,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d830ee097539cc5602cca64cb67ccab851d08210000000000000000000000000d830ee097539cc5602cca64cb67ccab851d0821000000000000000000000000000000000000000000000000001fa470a787880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7996,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000852390120f80a07537d20a97c94627edbf58adb1000000000000000000000000852390120f80a07537d20a97c94627edbf58adb100000000000000000000000000000000000000000000000000ee08251ff3800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5788c5d9a05c7b9b85eef7501a0689451823bc2000000000000000000000000e5788c5d9a05c7b9b85eef7501a0689451823bc200000000000000000000000000000000000000000000000000a36cc19bab000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7998,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046b6f4f9c11a9fc95c13fc49eb8d16871075aa2200000000000000000000000046b6f4f9c11a9fc95c13fc49eb8d16871075aa22000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +7999,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a04550e15035c1145d8692edcc6f5f8ab7101040000000000000000000000003a04550e15035c1145d8692edcc6f5f8ab710104000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8000,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6cc8af1b4299eb37bee7de464f4c5152ba3137e000000000000000000000000b6cc8af1b4299eb37bee7de464f4c5152ba3137e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8001,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071ea03598702d2fef81cf676d8fa7083c2b58f4300000000000000000000000071ea03598702d2fef81cf676d8fa7083c2b58f43000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8002,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ca9e9cc095b0bc7d863c8f23c40d2bfa81ddec20000000000000000000000001ca9e9cc095b0bc7d863c8f23c40d2bfa81ddec2000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8003,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000595ef74cfca44eac149740e18d6d8c80309c4e1b000000000000000000000000595ef74cfca44eac149740e18d6d8c80309c4e1b0000000000000000000000000000000000000000000000008da7acf4eb27156b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f4213796a6ce2c24bcbc2074ad66b14c94804a40000000000000000000000002f4213796a6ce2c24bcbc2074ad66b14c94804a40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8006,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000602c0269eb2d8a5dbadca05998eb72d9246d850d000000000000000000000000602c0269eb2d8a5dbadca05998eb72d9246d850d00000000000000000000000000000000000000000000000000003f78ce229bc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8007,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000301b15702fafe00394f3ff772bcf97cf18cfc668000000000000000000000000301b15702fafe00394f3ff772bcf97cf18cfc66800000000000000000000000000000000000000000000000002c1a76ac146630000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8008,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b9c1807a853fc1ecc1bf4b86e190835d17cd71b0000000000000000000000007b9c1807a853fc1ecc1bf4b86e190835d17cd71b00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8009,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002237ea9cc8bc70eaa5a9bf898f186c7a0e89c8820000000000000000000000002237ea9cc8bc70eaa5a9bf898f186c7a0e89c88200000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3d8bfee35c6272095db789b6eaa45ac2fb571b1000000000000000000000000b3d8bfee35c6272095db789b6eaa45ac2fb571b10000000000000000000000000000000000000000000000000028b87ee55e9f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cc123eabfd7f93e562e28ab5592d5575536ef240000000000000000000000005cc123eabfd7f93e562e28ab5592d5575536ef240000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8014,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000045ecd61c87bd0df7993da8f2b7b9084429da496c0000000000000000000000000000000000000000000000000de0b6b3a7640000,,,1,true +8017,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054bc0b774feac29bba39fb6b5f88d39cb8ca669800000000000000000000000054bc0b774feac29bba39fb6b5f88d39cb8ca6698000000000000000000000000000000000000000000000000003b0bf3ac14f38a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8018,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000585e9ce05b06a863edd448a7e6b7ff67494b27ab000000000000000000000000585e9ce05b06a863edd448a7e6b7ff67494b27ab00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8020,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ae1220658bf9cd4d02cfd17409c09fb9e8fd9f50000000000000000000000001ae1220658bf9cd4d02cfd17409c09fb9e8fd9f5000000000000000000000000000000000000000000000000002ef7500153378d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b248c1f8f0c8dc709acbcd8b83d8ef58571231b0000000000000000000000000b248c1f8f0c8dc709acbcd8b83d8ef58571231b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3d8720e780ad1db79ee16f08f164dfc688a9135000000000000000000000000e3d8720e780ad1db79ee16f08f164dfc688a9135000000000000000000000000000000000000000000000000001e8eba6642450000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000667cea6cd8665c5de673ce447aaee3ec60c93e22000000000000000000000000667cea6cd8665c5de673ce447aaee3ec60c93e22000000000000000000000000000000000000000000000000001f221d2ff4d20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001eac26a4ef3ab37d79ab27fa2c753fdc1d75d6570000000000000000000000001eac26a4ef3ab37d79ab27fa2c753fdc1d75d657000000000000000000000000000000000000000000000000001aaf45d1055a1200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b34c0cfe54b6249bcb4ae4baca21e44e53199ea7000000000000000000000000b34c0cfe54b6249bcb4ae4baca21e44e53199ea7000000000000000000000000000000000000000000000000001efe50f923520000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec51820b336f661af970527098b8347f4f0938c6000000000000000000000000ec51820b336f661af970527098b8347f4f0938c600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081d7d26fbc67b56bebf9c6b1937ff3ebeae6e7bc00000000000000000000000081d7d26fbc67b56bebf9c6b1937ff3ebeae6e7bc0000000000000000000000000000000000000000000000000001a72724d1c10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f9013b8bff314203b13f6d20fa4af1b1024eeb70000000000000000000000008f9013b8bff314203b13f6d20fa4af1b1024eeb7000000000000000000000000000000000000000000000000001940543d67ad3900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015735d481dadf3dcb8be78f716be048112796ba400000000000000000000000015735d481dadf3dcb8be78f716be048112796ba4000000000000000000000000000000000000000000000000005bebe4aa1aa28a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8032,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba637c7f42470561dcf609ca673550ee6832cf63000000000000000000000000ba637c7f42470561dcf609ca673550ee6832cf630000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063b2eb82073447bad2e02113e615c207c5ee616700000000000000000000000063b2eb82073447bad2e02113e615c207c5ee616700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8034,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041f0bef1b9b6002d2a8826067613e83d41384f5800000000000000000000000041f0bef1b9b6002d2a8826067613e83d41384f5800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab5dd55a7c1632fdca0d3b60c28b5461a62f0aa6000000000000000000000000ab5dd55a7c1632fdca0d3b60c28b5461a62f0aa600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8036,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007014a2c9a116742947faabe727b6eb6242fc38fe0000000000000000000000007014a2c9a116742947faabe727b6eb6242fc38fe00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8037,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf9cedfde652368a9b9bb490b3253583d5763967000000000000000000000000bf9cedfde652368a9b9bb490b3253583d576396700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8038,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fa73bea8e33f6fd4441b60db920b038e979ec7e0000000000000000000000005fa73bea8e33f6fd4441b60db920b038e979ec7e000000000000000000000000000000000000000000000000000b2cf37ea16a4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8039,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6b1ee03c47be152c024a8879edafca28cf9258c000000000000000000000000b6b1ee03c47be152c024a8879edafca28cf9258c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8040,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d0cfc0f638f7496193356c3e4f0bcf9747b55310000000000000000000000007d0cfc0f638f7496193356c3e4f0bcf9747b55310000000000000000000000000000000000000000000000000071314894c8730300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xfcf8e57290a0e647d393a201c25021e755ac92abd3f6b610bf6322cf24d85f3b,2022-05-26 03:57:41.000 UTC,0,true +8042,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c4dc8ced26e8b4714fbe4c9e9e21e517ec29eae0000000000000000000000001c4dc8ced26e8b4714fbe4c9e9e21e517ec29eae00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8043,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032e0aa7d26551ab64d834bb6c19bd4ee38e4979b00000000000000000000000032e0aa7d26551ab64d834bb6c19bd4ee38e4979b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8044,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098b577dbeec67660dceff6eb7d05321a233eec1800000000000000000000000098b577dbeec67660dceff6eb7d05321a233eec1800000000000000000000000000000000000000000000000000026c4c2863d3be00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8045,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000883fbb89b7afeca8f58301a40e579e95c612e540000000000000000000000000883fbb89b7afeca8f58301a40e579e95c612e5400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8046,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f57af0c2231726e584086faa4266bee467109fa2000000000000000000000000f57af0c2231726e584086faa4266bee467109fa200000000000000000000000000000000000000000000000000735356d3f223ce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8047,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3234d4e330ad5e8a7e6a0c6bc458b24bdf7d3bf000000000000000000000000d3234d4e330ad5e8a7e6a0c6bc458b24bdf7d3bf0000000000000000000000000000000000000000000000000002ee06a83ecc0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8048,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001dadf8110a7b5f2dc6d13bcb26599ae255b493000000000000000000000000001dadf8110a7b5f2dc6d13bcb26599ae255b4930000000000000000000000000000000000000000000000000001ea70f3384aa0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000725313887d5651f0f2d676d354334b70cf84ec8a000000000000000000000000725313887d5651f0f2d676d354334b70cf84ec8a00000000000000000000000000000000000000000000000005881b0df04f6bf500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000469b83988610b92aac8c3ec1fdac42d531b9178a000000000000000000000000469b83988610b92aac8c3ec1fdac42d531b9178a0000000000000000000000000000000000000000000000000c7d713b49da000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8052,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e7197e7cca2355b83a33e345bc6a65c722d03630000000000000000000000001e7197e7cca2355b83a33e345bc6a65c722d0363000000000000000000000000000000000000000000000000002718e5c01ed21600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f33856be70bb5fbccb08cbe5753336beab04ba40000000000000000000000003f33856be70bb5fbccb08cbe5753336beab04ba40000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8055,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea22e2411b5c1812aa27724f61178e439f0cc7aa000000000000000000000000ea22e2411b5c1812aa27724f61178e439f0cc7aa00000000000000000000000000000000000000000000000002c1d4719e39e60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f33856be70bb5fbccb08cbe5753336beab04ba40000000000000000000000003f33856be70bb5fbccb08cbe5753336beab04ba40000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8058,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f33856be70bb5fbccb08cbe5753336beab04ba40000000000000000000000003f33856be70bb5fbccb08cbe5753336beab04ba40000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ee3479373e6a31185a5cf9a40a00469814b21420000000000000000000000005ee3479373e6a31185a5cf9a40a00469814b214200000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb7c67585ca996b4b20529f02ff2046c75edcafc000000000000000000000000eb7c67585ca996b4b20529f02ff2046c75edcafc000000000000000000000000000000000000000000000000012e991fb9cbaddf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007525af9498280da3fc2f5498c495e89561b8ee790000000000000000000000007525af9498280da3fc2f5498c495e89561b8ee79000000000000000000000000000000000000000000000000015fb7f9b8c3800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbcc8124d5316c46cfa4f767d04abc2fdf98b78372209179b0ad6fef18392234c,2021-12-08 02:48:38.000 UTC,0,true +8062,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca7c767854b1e7305de07247ab85e30543d1d9c9000000000000000000000000ca7c767854b1e7305de07247ab85e30543d1d9c90000000000000000000000000000000000000000000000000ddc46ae96765a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8063,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003526f94b578c224601d5f198dbb1643910c2f93b0000000000000000000000003526f94b578c224601d5f198dbb1643910c2f93b000000000000000000000000000000000000000000000000002d200865bf880600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000667816ea7e29233aa2c4f5e6d2d17b658156902d000000000000000000000000667816ea7e29233aa2c4f5e6d2d17b658156902d000000000000000000000000000000000000000000000000003c01cb5c59898000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8067,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092eead2ea4b7044692dfdd524008c36c03b632fd00000000000000000000000092eead2ea4b7044692dfdd524008c36c03b632fd0000000000000000000000000000000000000000000000000056f3d8a43ab78400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8069,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d7955d1e697389c6b748ce52cfca7b536fa2ebf0000000000000000000000007d7955d1e697389c6b748ce52cfca7b536fa2ebf00000000000000000000000000000000000000000000000000446b247ef4e48c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8070,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000216e36333cfed41cdfcda3fa2642f6c4b14d4358000000000000000000000000216e36333cfed41cdfcda3fa2642f6c4b14d43580000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8072,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066f742da1ec05f3531c161e1412ac58abed58ba100000000000000000000000066f742da1ec05f3531c161e1412ac58abed58ba100000000000000000000000000000000000000000000000000369c1405ce37be00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8073,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000deaa628859122cb4b570882aa8bc9c786e8a932a000000000000000000000000deaa628859122cb4b570882aa8bc9c786e8a932a000000000000000000000000000000000000000000000000016916718eae33bd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8077,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001b2e7503a3da1f16c11be33d35640e379c80b94a0000000000000000000000000000000000000000000000008963dd8c2c5e0000,,,1,true +8078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004f71a91733f55c82fd29f064b37f7d83b2ee86d00000000000000000000000004f71a91733f55c82fd29f064b37f7d83b2ee86d0000000000000000000000000000000000000000000000000015ae60b7a4110000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac7adda48ffb1b1c756bcacde9dec410927509e5000000000000000000000000ac7adda48ffb1b1c756bcacde9dec410927509e5000000000000000000000000000000000000000000000000005fec5b60ef800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c85d1682a48ae42ed1923b53e7b0e2c4bd72b050000000000000000000000007c85d1682a48ae42ed1923b53e7b0e2c4bd72b050000000000000000000000000000000000000000000000000062eb842683650000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d70327e5620f5b8199f9e83e7281839286870dd7000000000000000000000000d70327e5620f5b8199f9e83e7281839286870dd700000000000000000000000000000000000000000000000007796610160dd14900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000345cec5bb2626e347c02d493950c20dd16f63ad9000000000000000000000000345cec5bb2626e347c02d493950c20dd16f63ad9000000000000000000000000000000000000000000000000000137a9046d8e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8084,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fe62c9735b59c8a1c6b6e10e657b976401a43b00000000000000000000000004fe62c9735b59c8a1c6b6e10e657b976401a43b000000000000000000000000000000000000000000000000006866332e9e57ee800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7c4e5dcb3929603f4cc6148a16f3254c4b5869d1c5fe075eb2cd66a3c8917c1b,2022-03-28 08:39:08.000 UTC,0,true +8085,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad2b87c7b0e86401660c3ba70ab1222556dac987000000000000000000000000ad2b87c7b0e86401660c3ba70ab1222556dac9870000000000000000000000000000000000000000000000003ad855409f5d70d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2a402fbe79d58916a1419619edaea3e530858a0630e20901830bc39bbdd3123d,2021-11-25 11:47:04.000 UTC,0,true +8087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055b1edfe744e4544f9d1668efff6e8ba2290377800000000000000000000000055b1edfe744e4544f9d1668efff6e8ba2290377800000000000000000000000000000000000000000000000000652a3cbe9ada0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba081d2bcf60b2f4d25468daeab35e44227f0aa6000000000000000000000000ba081d2bcf60b2f4d25468daeab35e44227f0aa6000000000000000000000000000000000000000000000000015be4946bb64e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8091,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9ef4b1d2eb0102a5169ea6f2bd7934474e6f7d7000000000000000000000000a9ef4b1d2eb0102a5169ea6f2bd7934474e6f7d7000000000000000000000000000000000000000000000000013083f18a4c970d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea0cd27bf777e480700a083513e605f0bfef3202000000000000000000000000ea0cd27bf777e480700a083513e605f0bfef3202000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7c2a5cc45ba3f68a31c0e17125723aad146508b15fe3a6994c7a7e2dcd4f5aa8,2021-11-25 18:32:37.000 UTC,0,true +8093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072c083ccbb46b6960a541c9850dbedc0257850be00000000000000000000000072c083ccbb46b6960a541c9850dbedc0257850be000000000000000000000000000000000000000000000000003e70577a47010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009da5c4c283c2fe334e2a1081a7fdae45475ceb410000000000000000000000009da5c4c283c2fe334e2a1081a7fdae45475ceb41000000000000000000000000000000000000000000000000001de9b919949b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8096,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e397a17d0f5c554a3fca64bfc99267db286ab155000000000000000000000000e397a17d0f5c554a3fca64bfc99267db286ab15500000000000000000000000000000000000000000000000006b4cb63cde35be600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0490578e0cf6d6c0a5c8417bcc0900f6aeb79b17a1fc2b5360043a95ff4a3d0e,2021-12-08 13:19:35.000 UTC,0,true +8097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018d1d461ce665094821d17b82730f3fd923d435200000000000000000000000018d1d461ce665094821d17b82730f3fd923d435200000000000000000000000000000000000000000000000006be36de3721d26f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9ae57d30b21d1d2535b5cf04fdc2385e989d253bab4d378a5746e35ecbdc9427,2022-02-22 17:52:55.000 UTC,0,true +8098,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb2fabbfa866570768bf6b0439f69b9f2fa72fec000000000000000000000000cb2fabbfa866570768bf6b0439f69b9f2fa72fec000000000000000000000000000000000000000000000000000aa2657d23c78000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8099,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b38638d4e09a66a9ef98ca5d36aa57fcbf12e26f000000000000000000000000b38638d4e09a66a9ef98ca5d36aa57fcbf12e26f00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003cd27bc0c2fe10705578e62fb11c110a14778bcf0000000000000000000000003cd27bc0c2fe10705578e62fb11c110a14778bcf0000000000000000000000000000000000000000000000000002cd042f01d11500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8102,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076744f4fd8ad6627e838bcabec82c25bdb06a9f100000000000000000000000076744f4fd8ad6627e838bcabec82c25bdb06a9f10000000000000000000000000000000000000000000000000002e48981dcc73400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8104,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cdfe073bfdb8d8f9d8db26621d7e33b803a06670000000000000000000000000cdfe073bfdb8d8f9d8db26621d7e33b803a066700000000000000000000000000000000000000000000000000000204f36f1e91500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a62bb8263dcb26d1c5f77f4b747cd8e246fa4fe6000000000000000000000000a62bb8263dcb26d1c5f77f4b747cd8e246fa4fe60000000000000000000000000000000000000000000000000000204f36f1e91500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8106,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072681b6fa7e64d790260831a0c62d640f83789e300000000000000000000000072681b6fa7e64d790260831a0c62d640f83789e3000000000000000000000000000000000000000000000000000101faa271941800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2af0268a8b83b9581dfbf67011b0957ee4c31a0000000000000000000000000f2af0268a8b83b9581dfbf67011b0957ee4c31a0000000000000000000000000000000000000000000000000000101faa271941800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8108,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2af0268a8b83b9581dfbf67011b0957ee4c31a0000000000000000000000000f2af0268a8b83b9581dfbf67011b0957ee4c31a0000000000000000000000000000000000000000000000000000101faa271941800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8109,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e58a15be9b5377e9b457768595af7f5a537cd4dd000000000000000000000000e58a15be9b5377e9b457768595af7f5a537cd4dd000000000000000000000000000000000000000000000000000101faa271941800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8110,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd8eb22b2e8d78982166f66149f258b8ac7a8bc1000000000000000000000000dd8eb22b2e8d78982166f66149f258b8ac7a8bc100000000000000000000000000000000000000000000000000005fc946ddb48000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8111,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000cdac7bca5da93eef2e0d00c337f917d3f6639330000000000000000000000000cdac7bca5da93eef2e0d00c337f917d3f663933000000000000000000000000000000000000000000000000007ac0aeb874bbbd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8118,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a97dbc9baa91707b5bde45c810536c17b8ceb150000000000000000000000009a97dbc9baa91707b5bde45c810536c17b8ceb1500000000000000000000000000000000000000000000000006391f4ea4bf850000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x675e9a22219def7c57e025758944ecaf45c2387e81c3f2d0f2857507786f9689,2022-06-01 10:34:42.000 UTC,0,true +8119,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003c00a3fa2eef1afccf044af59ce105b8200272cd0000000000000000000000003c00a3fa2eef1afccf044af59ce105b8200272cd00000000000000000000000000000000000000000000000057be307ed8b2177300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000324e0b53cefa84cf970833939249880f814557c6000000000000000000000000324e0b53cefa84cf970833939249880f814557c60000000000000000000000000000000000000000000000000dcee9c35fe2020000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017f0cef921129890f57cc660ce7d67b9b17edbf800000000000000000000000017f0cef921129890f57cc660ce7d67b9b17edbf80000000000000000000000000000000000000000000000000026c22c182497cf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a7ac9632080867423f8fb3e922ed212734e0fc10000000000000000000000000a7ac9632080867423f8fb3e922ed212734e0fc1000000000000000000000000000000000000000000000000002dbbc9f5c1aaf700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef09db43283c53b2fe1e56bb46feb42f57a5e3cf000000000000000000000000ef09db43283c53b2fe1e56bb46feb42f57a5e3cf0000000000000000000000000000000000000000000000000dd7d780c41ee90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8124,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000687549b38e7453a88e271404250c659908de7d80000000000000000000000000687549b38e7453a88e271404250c659908de7d80000000000000000000000000000000000000000000000000000cc1d48a81382d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000691819b746a82592d36abbfaac0ed4a1a64e666d000000000000000000000000691819b746a82592d36abbfaac0ed4a1a64e666d0000000000000000000000000000000000000000000000000009d53c5af3a9f600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8126,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014d74016422f9a923c6e995e6576d1539a4f4c1800000000000000000000000014d74016422f9a923c6e995e6576d1539a4f4c18000000000000000000000000000000000000000000000000006067ff15114e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8129,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a679c6154b8d4619af9f83f0bf9a13a680e01ecf000000000000000000000000a679c6154b8d4619af9f83f0bf9a13a680e01ecf000000000000000000000000000000000000000000000000041ccea40f5817c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8130,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000650aede9768d80cbdbfda2d1e2d35250ee0691e0000000000000000000000000650aede9768d80cbdbfda2d1e2d35250ee0691e00000000000000000000000000000000000000000000000e0eea9d435dbffc53b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xaaa4b0a233fa23546c41b141ccb1d775d44de4af0c1575e657e359c7842903e8,2022-02-01 19:25:46.000 UTC,0,true +8131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc13514bc2b74b1886e7aff16645756436f2de82000000000000000000000000cc13514bc2b74b1886e7aff16645756436f2de820000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000216e36333cfed41cdfcda3fa2642f6c4b14d4358000000000000000000000000216e36333cfed41cdfcda3fa2642f6c4b14d435800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000759d669fd65cc5a42c02e9d22c291ec09e066023000000000000000000000000759d669fd65cc5a42c02e9d22c291ec09e0660230000000000000000000000000000000000000000000000000018d2186f66612400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cab3a5c1d3cfea0abaa075d0eeb5fcff08852460000000000000000000000002cab3a5c1d3cfea0abaa075d0eeb5fcff088524600000000000000000000000000000000000000000000000000dfe2af11f8936d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8139,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000858d150df99c308b406b2796d933689d9ac3cffa000000000000000000000000858d150df99c308b406b2796d933689d9ac3cffa000000000000000000000000000000000000000000000000006a0011af4deebf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8142,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c8c6094a3288a5e20dddde2c466edf9b3fdf3d04000000000000000000000000c8c6094a3288a5e20dddde2c466edf9b3fdf3d04000000000000000000000000000000000000000000000000001e3bf2277dcd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041fa51fffe4b6d2d5d5a45fd050531a74cc3fc1300000000000000000000000041fa51fffe4b6d2d5d5a45fd050531a74cc3fc13000000000000000000000000000000000000000000000000001db5fbf259d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8144,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b63101940135b7c85f5f536ce41ccf5818aa2e5b000000000000000000000000b63101940135b7c85f5f536ce41ccf5818aa2e5b000000000000000000000000000000000000000000000000001ed2b01653fe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8145,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c82bdcf970f33866c2b7f73a3628418f8229eb90000000000000000000000007c82bdcf970f33866c2b7f73a3628418f8229eb9000000000000000000000000000000000000000000000000001ed2b01653fe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010590af6d0cdef12d9608c442170c3f76a6fc97600000000000000000000000010590af6d0cdef12d9608c442170c3f76a6fc976000000000000000000000000000000000000000000000000001ed2b01653fe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8147,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc4f1956f7261a120238df9861731b84c1a94066000000000000000000000000dc4f1956f7261a120238df9861731b84c1a94066000000000000000000000000000000000000000000000000001ed2b01653fe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e61c985ac87b493b8bf98fabdff0a86c0bb223a4000000000000000000000000e61c985ac87b493b8bf98fabdff0a86c0bb223a4000000000000000000000000000000000000000000000000001e7d1be347280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d7c09c7ab07424d74e47e1fa1e7eea02933c8e20000000000000000000000006d7c09c7ab07424d74e47e1fa1e7eea02933c8e2000000000000000000000000000000000000000000000000001e7d1be347280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8150,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000bcd328f7bb87399ff5c363d244355094b0614100000000000000000000000000bcd328f7bb87399ff5c363d244355094b06141000000000000000000000000000000000000000000000000001de2bb36dfb00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097b96d3d407257e0602c3b107a169861bb1b0ff900000000000000000000000097b96d3d407257e0602c3b107a169861bb1b0ff9000000000000000000000000000000000000000000000000001de2bb36dfb00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8152,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d3c63dd02af2f8832c8725cfdb15bb445e129120000000000000000000000009d3c63dd02af2f8832c8725cfdb15bb445e12912000000000000000000000000000000000000000000000000001d5803e273e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8153,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000060da990aebdd785f50ea3202ff05bff1d0963dbe000000000000000000000000000000000000000000000000e77c1395f1a6b324,,,1,true +8156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec3b481c482e92850edf554a3ad5bcd89e15c662000000000000000000000000ec3b481c482e92850edf554a3ad5bcd89e15c66200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8157,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008de3c3891268502f77db7e876d727257dec0f8520000000000000000000000008de3c3891268502f77db7e876d727257dec0f852000000000000000000000000000000000000000000000000017199c64bb8c00600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c4402ceee20579a0b3c5cad83883b3d6e2bdb490000000000000000000000000c4402ceee20579a0b3c5cad83883b3d6e2bdb49000000000000000000000000000000000000000000000000001f291b12a9bd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e6b39bffd69557145611c746d5b13cc125972860000000000000000000000006e6b39bffd69557145611c746d5b13cc12597286000000000000000000000000000000000000000000000000001f344ae3cb350000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8161,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1a5161d604d7348d7f5c534517b5404a8edefe4000000000000000000000000f1a5161d604d7348d7f5c534517b5404a8edefe4000000000000000000000000000000000000000000000000016dc800f1af8c9c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2af77dce51511a0663053ea7fa5043e0f4227d5000000000000000000000000c2af77dce51511a0663053ea7fa5043e0f4227d500000000000000000000000000000000000000000000000000056c94fbfa558000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8164,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d19eb5ed5838da9806681688f03ac2b9cbc389e0000000000000000000000007d19eb5ed5838da9806681688f03ac2b9cbc389e00000000000000000000000000000000000000000000000000002a91fd59fc7400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ec83e4768e314cdd88f910e397affcde78a52f92000000000000000000000000ec83e4768e314cdd88f910e397affcde78a52f92000000000000000000000000000000000000000000000000000000001dcd650000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x5f8cc08c8a019ebb5e26286c5de9818c192aef3125dc52ec8d7540ef67df8e01,2022-06-26 01:19:36.000 UTC,0,true +8168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2ae50242c85577be214e5e48120a4012096f751000000000000000000000000e2ae50242c85577be214e5e48120a4012096f7510000000000000000000000000000000000000000000000000004d70254e4d93e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8169,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000003414bc24c60cfe67b3a1ef2720c6677dc1634910000000000000000000000000000000000000000000000001d390c3de779d324,,,1,true +8170,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b813cecf4fa33172f5fedf635e363cb35d7c361b000000000000000000000000b813cecf4fa33172f5fedf635e363cb35d7c361b000000000000000000000000000000000000000000000000004ab72822fd8c7f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8172,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091edb26c6abdfb69e4f3360808157ed100b13b5d00000000000000000000000091edb26c6abdfb69e4f3360808157ed100b13b5d0000000000000000000000000000000000000000000000000030967bf921d7c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000813407596e7c63cd3958ff081ca078cb31ddbf10000000000000000000000000813407596e7c63cd3958ff081ca078cb31ddbf1000000000000000000000000000000000000000000000000008165265da50d4700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000406c00ac4b3d865931c66bcd3f8621c4230af7bb000000000000000000000000406c00ac4b3d865931c66bcd3f8621c4230af7bb0000000000000000000000000000000000000000000000000019396991e7c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8178,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000db326c0f5f60ef7940a319e386db26f9e5810656000000000000000000000000000000000000000000000001da166835f41a135d,,,1,true +8179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db49553ff31e88e5cd561c9b6c1d90ebf165d6bf000000000000000000000000db49553ff31e88e5cd561c9b6c1d90ebf165d6bf0000000000000000000000000000000000000000000000000018ccf5c64c51c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011c4f894cc4cd2d96e87ff90bb30a4a99c97df1b00000000000000000000000011c4f894cc4cd2d96e87ff90bb30a4a99c97df1b0000000000000000000000000000000000000000000000000008d6cd0360cac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1376738101036030b76723154f4db4b0ab3ae33000000000000000000000000e1376738101036030b76723154f4db4b0ab3ae33000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000770464ef67b6e276cd76576100cba00ca91fc02c000000000000000000000000770464ef67b6e276cd76576100cba00ca91fc02c0000000000000000000000000000000000000000000000000089e9069317bc1b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfe33c2a47d74f24ae0c1e434ced836dd78a43eb000000000000000000000000cfe33c2a47d74f24ae0c1e434ced836dd78a43eb00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8184,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041cc4a3fe2227953da7eadecd77e366d2cda886600000000000000000000000041cc4a3fe2227953da7eadecd77e366d2cda8866000000000000000000000000000000000000000000000000010e207120ed966000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4e9abcf9f98cae5088cee01862a43c239ee963c000000000000000000000000b4e9abcf9f98cae5088cee01862a43c239ee963c000000000000000000000000000000000000000000000000002b50be4fe7538200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8186,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000008810a2d251df25b4fbce3c1fcfeb050034e50ff60000000000000000000000008810a2d251df25b4fbce3c1fcfeb050034e50ff600000000000000000000000000000000000000000000000000000000109a305600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8187,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffaa7ee8fe0d828e5844d3fd991fcfd7288390c9000000000000000000000000ffaa7ee8fe0d828e5844d3fd991fcfd7288390c9000000000000000000000000000000000000000000000000002b50be4fe7538200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8188,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000498f39362d1bd31a673fadc57efa53969aefbbea000000000000000000000000498f39362d1bd31a673fadc57efa53969aefbbea000000000000000000000000000000000000000000000000001857214a18e84000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8189,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000273ec095fe4c3c023b6e5d3dcd3642af950ac930000000000000000000000000273ec095fe4c3c023b6e5d3dcd3642af950ac9300000000000000000000000000000000000000000000000000b3b01229605b9dc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8191,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dddf40605bcb1f8346b328e4bd0f873f75d66690000000000000000000000000dddf40605bcb1f8346b328e4bd0f873f75d666900000000000000000000000000000000000000000000000000015684fc149653b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8192,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000dddf40605bcb1f8346b328e4bd0f873f75d66690000000000000000000000000dddf40605bcb1f8346b328e4bd0f873f75d6669000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfe33c2a47d74f24ae0c1e434ced836dd78a43eb000000000000000000000000cfe33c2a47d74f24ae0c1e434ced836dd78a43eb0000000000000000000000000000000000000000000000000056840fa85e791100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8195,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000009fe553de68865f425d8071c81640855a7c9613eb0000000000000000000000009fe553de68865f425d8071c81640855a7c9613eb000000000000000000000000000000000000000000000000000000003a15328200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052905a5e83a83f6a9d0e64ad24e79a37512d35b900000000000000000000000052905a5e83a83f6a9d0e64ad24e79a37512d35b900000000000000000000000000000000000000000000000002af9e74268d935200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8200,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000139c6b1985656a6a2727b714060eb2f0230d8a81000000000000000000000000139c6b1985656a6a2727b714060eb2f0230d8a810000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8201,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f8a10b701c58aa99f9a240208c7be64381c313f0000000000000000000000006f8a10b701c58aa99f9a240208c7be64381c313f000000000000000000000000000000000000000000000000000f873df4294f9b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8202,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067320a4323eb84534cc5dce232c69b57f9a8cf6400000000000000000000000067320a4323eb84534cc5dce232c69b57f9a8cf6400000000000000000000000000000000000000000000000001a20c7aaf8aa44f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8203,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040077ad46d6f11e4d2dc3cc8a09227355c70e45700000000000000000000000040077ad46d6f11e4d2dc3cc8a09227355c70e45700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d88463cc7b5d448f4457614f16556be46060b3d6000000000000000000000000d88463cc7b5d448f4457614f16556be46060b3d6000000000000000000000000000000000000000000000000002867448af4f9f400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8205,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df62defaf89a4f4ff370854a9d521fab2edd1734000000000000000000000000df62defaf89a4f4ff370854a9d521fab2edd1734000000000000000000000000000000000000000000000000009d1b6ecba12eab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008bb1390a642e4dc2a5a6b9b8f32d34f37144fcdc0000000000000000000000008bb1390a642e4dc2a5a6b9b8f32d34f37144fcdc00000000000000000000000000000000000000000000000003c1b483c16e19ec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004568b388342840f2d249873f197ed383da25de7f0000000000000000000000004568b388342840f2d249873f197ed383da25de7f000000000000000000000000000000000000000000000000019878f10f3471a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8210,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000300117c369a7d1b32413a255723ef0cb5c5f95c7000000000000000000000000300117c369a7d1b32413a255723ef0cb5c5f95c700000000000000000000000000000000000000000000000045a40f357504cf0200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8212,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078a90951bc30582fb8f5b1ec218a15463418374400000000000000000000000078a90951bc30582fb8f5b1ec218a15463418374400000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8213,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e42a67f51dce014ae17fe0b0e6a0c692ef5eae60000000000000000000000003e42a67f51dce014ae17fe0b0e6a0c692ef5eae600000000000000000000000000000000000000000000000000a2033cb4ff14b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8214,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000025d64f2d94807613ecfdae56fa9ec7bcdb29da2000000000000000000000000025d64f2d94807613ecfdae56fa9ec7bcdb29da200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060b6eade8258a52bfda3c80df3fde715ef47df7300000000000000000000000060b6eade8258a52bfda3c80df3fde715ef47df7300000000000000000000000000000000000000000000000000b763687f50dd6600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae0f777ccd5cbf23dd99c93d52a8a0f630dc47ae000000000000000000000000ae0f777ccd5cbf23dd99c93d52a8a0f630dc47ae00000000000000000000000000000000000000000000000000522317276c5eb800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8217,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000985cb01e8830aaa1a3dff87151ccdf5ce2ce999b000000000000000000000000985cb01e8830aaa1a3dff87151ccdf5ce2ce999b00000000000000000000000000000000000000000000000000039c95d2925ec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000510bbd7b7408c073e9e6e7f50f46bff1e6f2867f000000000000000000000000510bbd7b7408c073e9e6e7f50f46bff1e6f2867f0000000000000000000000000000000000000000000000000015ec3ee7d893f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9981f4cb68bcc98e7e3ebd28e80cd30661e111c000000000000000000000000f9981f4cb68bcc98e7e3ebd28e80cd30661e111c0000000000000000000000000000000000000000000000000083740cd93a448000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8220,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004324a7c9679dbdf26ea2f98a0c1545cab2a9d9350000000000000000000000004324a7c9679dbdf26ea2f98a0c1545cab2a9d935000000000000000000000000000000000000000000000000004ae7772bffae6900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096e76dacbbcbad74b82bb893bf3e8bf4b7b06c9f00000000000000000000000096e76dacbbcbad74b82bb893bf3e8bf4b7b06c9f000000000000000000000000000000000000000000000000003b57276d8144cb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8227,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d31600bf70eb4d5921247ff3931176ea81566e5d000000000000000000000000d31600bf70eb4d5921247ff3931176ea81566e5d000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8231,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4bcde3ccfe072892aebbba1f0532bcc37043a1a000000000000000000000000b4bcde3ccfe072892aebbba1f0532bcc37043a1a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc713097f3e7ffcbb4e60e4f4efee4a0ae8af234000000000000000000000000cc713097f3e7ffcbb4e60e4f4efee4a0ae8af23400000000000000000000000000000000000000000000000000c502ac76ef29ab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8234,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a00a4135c45a9cce73688b5660b2d018e1aac3d2000000000000000000000000a00a4135c45a9cce73688b5660b2d018e1aac3d2000000000000000000000000000000000000000000000003bea23e9421de4dfc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080f715be0f5516501bb49bfda53975bdcb7e3c1b00000000000000000000000080f715be0f5516501bb49bfda53975bdcb7e3c1b00000000000000000000000000000000000000000000000000c7483ca2561bae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b8625b05db41aff7f66ce7a540745b941078e400000000000000000000000002b8625b05db41aff7f66ce7a540745b941078e40000000000000000000000000000000000000000000000000010a0d78c3b0e76300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8237,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012b81e4275fbd5834320252841949f6973b405f900000000000000000000000012b81e4275fbd5834320252841949f6973b405f9000000000000000000000000000000000000000000000000014979f2c190c7c800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093d154116d1d9bb5080e9f0e919d71e2690ab8a200000000000000000000000093d154116d1d9bb5080e9f0e919d71e2690ab8a200000000000000000000000000000000000000000000000000a2348402c60d4900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080f715be0f5516501bb49bfda53975bdcb7e3c1b00000000000000000000000080f715be0f5516501bb49bfda53975bdcb7e3c1b000000000000000000000000000000000000000000000000003e67e7fee81fe600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000513989e0ab20f597145600e837d05b4aa96b4e8e000000000000000000000000513989e0ab20f597145600e837d05b4aa96b4e8e00000000000000000000000000000000000000000000000000287559223283b300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8241,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000041c1e0d927248d5d3341041c416a6f8fa894faf000000000000000000000000041c1e0d927248d5d3341041c416a6f8fa894faf000000000000000000000000000000000000000000000000014d57d62293301000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8243,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000053858909e782b7af40d7ae8673c140aa0bb4751000000000000000000000000053858909e782b7af40d7ae8673c140aa0bb47510000000000000000000000000000000000000000000000000147a6baa4dbdf4300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000070b0fbd3176d5a0871fae1325dbe5657e1607bb000000000000000000000000070b0fbd3176d5a0871fae1325dbe5657e1607bb0000000000000000000000000000000000000000000000000014b0e141307a6f800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8245,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e969ef6523502ec36917bc925ef1b729c6d4e9c3000000000000000000000000e969ef6523502ec36917bc925ef1b729c6d4e9c3000000000000000000000000000000000000000000000000004902a6f5571b5d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097812657db486589c1b2171b19ef9045e14c69ea00000000000000000000000097812657db486589c1b2171b19ef9045e14c69ea00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8247,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088f6872cf20351bb46a2c3ec7863c9541327774e00000000000000000000000088f6872cf20351bb46a2c3ec7863c9541327774e000000000000000000000000000000000000000000000000014a288c3cf3c35d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2ff32278bd611168c3798682fe90bb20dc825e1000000000000000000000000d2ff32278bd611168c3798682fe90bb20dc825e1000000000000000000000000000000000000000000000000014dccbf9ba71d3900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fe8f8ce0c13f826e1a17383524dba614d4c399e0000000000000000000000000fe8f8ce0c13f826e1a17383524dba614d4c399e000000000000000000000000000000000000000000000000014c088c2d3f986700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8252,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b96a958a82ecabab9e7cf14ae538c38996f2c7b6000000000000000000000000b96a958a82ecabab9e7cf14ae538c38996f2c7b600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009628d07ab4cabe66400f6a627732b4c11ab057500000000000000000000000009628d07ab4cabe66400f6a627732b4c11ab057500000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8254,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ef6c440ca6f7dfe8f87bb9c0df4f7d58112e12b0000000000000000000000002ef6c440ca6f7dfe8f87bb9c0df4f7d58112e12b00000000000000000000000000000000000000000000000001464b9b6dc4bea400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016ea30ba1a15fc03ba3b563bf6312d5813f2e3c200000000000000000000000016ea30ba1a15fc03ba3b563bf6312d5813f2e3c200000000000000000000000000000000000000000000000001421bc5c811427200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000899929b4e35a1e29b940ab41ab278a41a6a4947d000000000000000000000000899929b4e35a1e29b940ab41ab278a41a6a4947d000000000000000000000000000000000000000000000000013d477c079f254600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8257,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6fe2689141ebe625dcb91b7d9be8fad54099d25000000000000000000000000c6fe2689141ebe625dcb91b7d9be8fad54099d2500000000000000000000000000000000000000000000000001419f6dc5b6d03a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8258,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a03a90eb2910debbb3fbda9568e2f5a9e0bbd92f000000000000000000000000a03a90eb2910debbb3fbda9568e2f5a9e0bbd92f000000000000000000000000000000000000000000000000014790098f1baf8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d917e96568ac609a86c7c1578911c31d197bb5f0000000000000000000000003d917e96568ac609a86c7c1578911c31d197bb5f00000000000000000000000000000000000000000000000001450c4554847bc500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8260,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003bab2479b992440e597dc69363b9bec012811a7c0000000000000000000000003bab2479b992440e597dc69363b9bec012811a7c0000000000000000000000000000000000000000000000000149547b2040316c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8261,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bba974083e667ad7a9809cc378ca1fd9c3341eb8000000000000000000000000bba974083e667ad7a9809cc378ca1fd9c3341eb80000000000000000000000000000000000000000000000000148dec4fb08529000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8262,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004eff6050c03742c0ec10bdf483bc1f2ab8479bd20000000000000000000000004eff6050c03742c0ec10bdf483bc1f2ab8479bd200000000000000000000000000000000000000000000000000a8f5875375a84500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c3f445d067442b439056fd1a118a4c1dcc7d7d60000000000000000000000004c3f445d067442b439056fd1a118a4c1dcc7d7d600000000000000000000000000000000000000000000000001f161421c8e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8264,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000570f9e457463d263560c76ecc9e41d16a5a25373000000000000000000000000570f9e457463d263560c76ecc9e41d16a5a25373000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8266,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8c0fe3699db673486c391a4eefa5a18c7cfd4d6000000000000000000000000e8c0fe3699db673486c391a4eefa5a18c7cfd4d600000000000000000000000000000000000000000000000000654d79c491140000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcf1a901e0c9f629cd75c4317121a51cef9f95f25d1c5e852cd44fbb82892849b,2022-03-22 14:43:39.000 UTC,0,true +8267,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac8dec6722d5fe329f93377978c1e661a6c021e8000000000000000000000000ac8dec6722d5fe329f93377978c1e661a6c021e8000000000000000000000000000000000000000000000000023557e4531ba00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000a67ff33dcc411fa327f752cbcd8dd63acb0f6c00000000000000000000000000a67ff33dcc411fa327f752cbcd8dd63acb0f6c000000000000000000000000000000000000000000000000007aa5d83964068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef56c8d320ebf6b79e3cb7e3e098dc01ce186a0d000000000000000000000000ef56c8d320ebf6b79e3cb7e3e098dc01ce186a0d000000000000000000000000000000000000000000000000001a42c745d52a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8270,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007372a7934b86c2015721af1367bbce24e5fa17b20000000000000000000000007372a7934b86c2015721af1367bbce24e5fa17b20000000000000000000000000000000000000000000000000065c916f1dc820000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a017279b02e3b92f252cf7239bdc2a5f7fe6223e000000000000000000000000a017279b02e3b92f252cf7239bdc2a5f7fe6223e000000000000000000000000000000000000000000000000007dcc775f2541df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8273,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d38c3879cb3ddab7cab997f27345bd7aad860680000000000000000000000008d38c3879cb3ddab7cab997f27345bd7aad86068000000000000000000000000000000000000000000000000003aff271232df2600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039338033df3b80ed5fa78780bf4f4ba175f23b2600000000000000000000000039338033df3b80ed5fa78780bf4f4ba175f23b26000000000000000000000000000000000000000000000000003b990c903fa17600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000144c94ad5bb9d7c8b59c60cc5f5b0b984ff71a53000000000000000000000000144c94ad5bb9d7c8b59c60cc5f5b0b984ff71a530000000000000000000000000000000000000000000000000003d092431e650000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008676c970dd185479ae889bcea18b84201bad57ce0000000000000000000000008676c970dd185479ae889bcea18b84201bad57ce00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b18d92b4c88e8e0a718a9ea8d1271e5277e6e100000000000000000000000004b18d92b4c88e8e0a718a9ea8d1271e5277e6e1000000000000000000000000000000000000000000000000001339a771575d18000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d3c85f7d2e8222d4a0f6df4b76a9911f3e4bcdc0000000000000000000000006d3c85f7d2e8222d4a0f6df4b76a9911f3e4bcdc00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021503af4d1c8e71ce2a575e57376e5f60dac152900000000000000000000000021503af4d1c8e71ce2a575e57376e5f60dac15290000000000000000000000000000000000000000000000000001313dd0a5bf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8284,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011ff5d408f6aa0366620f2833b4cd35603c08eeb00000000000000000000000011ff5d408f6aa0366620f2833b4cd35603c08eeb00000000000000000000000000000000000000000000000000128aeb18cb199400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8287,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b0e455abf6736380f6ca69d0ac0d81163ebb8cc0000000000000000000000006b0e455abf6736380f6ca69d0ac0d81163ebb8cc000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8288,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e44b4f50210126d44b5a601f551dc5d6af14e3f0000000000000000000000008e44b4f50210126d44b5a601f551dc5d6af14e3f00000000000000000000000000000000000000000000000000a323b2ad5d677900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8293,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc3b00a6548fbf13293cb47910ded9cd275765b9000000000000000000000000dc3b00a6548fbf13293cb47910ded9cd275765b9000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c3f445d067442b439056fd1a118a4c1dcc7d7d60000000000000000000000004c3f445d067442b439056fd1a118a4c1dcc7d7d6000000000000000000000000000000000000000000000000003f086f2a02f40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8295,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cd75b057dc88ea5c5bd7f9396507712481066b50000000000000000000000002cd75b057dc88ea5c5bd7f9396507712481066b500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cd75b057dc88ea5c5bd7f9396507712481066b50000000000000000000000002cd75b057dc88ea5c5bd7f9396507712481066b5000000000000000000000000000000000000000000000000001bb1391c3365cb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8299,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e67500000000000000000000000057ab1ec28d129707052df4df418d58a2d46d5f510000000000000000000000008c6f28f2f1a3c87f0f938b96d27520d9751ec8d90000000000000000000000000b7c43af43d76f79b6f6cfbafb3a01dde04682250000000000000000000000000b7c43af43d76f79b6f6cfbafb3a01dde04682250000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7f12307ee6002f7fd2aa6c10b9e8cfcc67b0bf9000000000000000000000000c7f12307ee6002f7fd2aa6c10b9e8cfcc67b0bf9000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8304,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef731d11c5076b983857815f99daf612c46f030b000000000000000000000000ef731d11c5076b983857815f99daf612c46f030b0000000000000000000000000000000000000000000000000030ec16cdaa3ef000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1f897e2311bfc2af1f42bf87fe4e1cbfd23e4ac000000000000000000000000c1f897e2311bfc2af1f42bf87fe4e1cbfd23e4ac000000000000000000000000000000000000000000000000000c32db4908686700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8306,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002c7867c3beffdbc1dbaaa15e8a711f183f9d8d900000000000000000000000002c7867c3beffdbc1dbaaa15e8a711f183f9d8d9000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8307,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa3ce4b82cc4dd303104b5c43eecf72871d31632000000000000000000000000fa3ce4b82cc4dd303104b5c43eecf72871d316320000000000000000000000000000000000000000000000000011ca37adaee3b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8308,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007737c517986e8030610c31a9686d04a63f6ef5560000000000000000000000007737c517986e8030610c31a9686d04a63f6ef55600000000000000000000000000000000000000000000000000095a655d3dfb2400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8309,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076766ce199954d2dc52e14577e2434ed00fb4bb000000000000000000000000076766ce199954d2dc52e14577e2434ed00fb4bb000000000000000000000000000000000000000000000000000ebc1a185edce7800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8310,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cf968f202abb9f97063c5ce1a0ed07ff2f3e6280000000000000000000000005cf968f202abb9f97063c5ce1a0ed07ff2f3e628000000000000000000000000000000000000000000000000003fec7cd071f38000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8311,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000192cdfc4edf00fb06c888bc25aae8acbe8d7fa7e000000000000000000000000192cdfc4edf00fb06c888bc25aae8acbe8d7fa7e00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8312,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000781cdc81cc8a315433bdc1c581a649c4c0d61ee7000000000000000000000000781cdc81cc8a315433bdc1c581a649c4c0d61ee700000000000000000000000000000000000000000000000004d7eb18333f255900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8313,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019ca3875c04e64cdc097759225452ad3982fbc4500000000000000000000000019ca3875c04e64cdc097759225452ad3982fbc4500000000000000000000000000000000000000000000000000b6a90f8921696500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8316,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000349ea0b723e3692a2ddcc0ae5cc85640f372ffd1000000000000000000000000349ea0b723e3692a2ddcc0ae5cc85640f372ffd1000000000000000000000000000000000000000000000000003b93918f5c881300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047b2efa18736c6c211505aefd321bec3ac3e877900000000000000000000000047b2efa18736c6c211505aefd321bec3ac3e877900000000000000000000000000000000000000000000000000eaf5fc44be8ae400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x06710b719473e4197fe2bbd00253d172ee3dd13d766cb928e18cd30b1d4914f3,2022-02-06 15:12:38.000 UTC,0,true +8318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004af48abe68f94e32d03dd6dfeb2e73281f479c800000000000000000000000004af48abe68f94e32d03dd6dfeb2e73281f479c80000000000000000000000000000000000000000000000000001f36400ecaaa0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8319,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a353b568cf88770d9627b27082851de0e58347ea000000000000000000000000a353b568cf88770d9627b27082851de0e58347ea0000000000000000000000000000000000000000000000000b405adfc274e1b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8320,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057768da7994d07d56e1f348e48e1bf8fd4b9934500000000000000000000000057768da7994d07d56e1f348e48e1bf8fd4b9934500000000000000000000000000000000000000000000000000a57d470dedb81400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8321,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce2f3600d79ea3608feb1ea0f51a88bfc7d485c7000000000000000000000000ce2f3600d79ea3608feb1ea0f51a88bfc7d485c700000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2e98534267738a3f1cef3a8bdf004004f18dd896883a8cbb90b18e463c4a9995,2022-03-08 15:03:16.000 UTC,0,true +8324,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000000efa5c7ba17a797a867820ffd51b890125bda360000000000000000000000000000000000000000000000003782dace9d900000,,,1,true +8326,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009181256f04ba5fbc3381354832cdab22e60918b50000000000000000000000009181256f04ba5fbc3381354832cdab22e60918b500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8327,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc9a0bcb451329a5c30b4dfbbf96024588521053000000000000000000000000bc9a0bcb451329a5c30b4dfbbf96024588521053000000000000000000000000000000000000000000000000003ff2e795f5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8328,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000383e96959e6c1dc55885f5437e8a01a41f5dc5a9000000000000000000000000383e96959e6c1dc55885f5437e8a01a41f5dc5a900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8330,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049df5d7e42cc8c0bbb6f54f132bc07f8e5e046f700000000000000000000000049df5d7e42cc8c0bbb6f54f132bc07f8e5e046f7000000000000000000000000000000000000000000000000002af758bd01288000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8333,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028e452555f12e461c6b21588efed281b22e7c97f00000000000000000000000028e452555f12e461c6b21588efed281b22e7c97f00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8335,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e67500000000000000000000000003ab458634910aad20ef5f1c8ee96f1d6ac549190000000000000000000000007fb688ccf682d58f86d7e38e03f9d22e7705448b00000000000000000000000083437112034414883ee20b3a2f98d0cd9e53b45b00000000000000000000000083437112034414883ee20b3a2f98d0cd9e53b45b000000000000000000000000000000000000000000000000984a439f1afe227800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8336,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b814bc7e97996e341157f43e711faebe32b81a75000000000000000000000000b814bc7e97996e341157f43e711faebe32b81a750000000000000000000000000000000000000000000000000245168ed4d6df6200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8337,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009086226729f6cc36ab626d8e341cbec912d21b7c0000000000000000000000009086226729f6cc36ab626d8e341cbec912d21b7c00000000000000000000000000000000000000000000000000f88290bacc56e300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8338,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051e6e2df45186fd18e11e76b487552cb80a8de6800000000000000000000000051e6e2df45186fd18e11e76b487552cb80a8de6800000000000000000000000000000000000000000000000000e6b9d33ecfd52d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000616964aa4652812da73a8ca0cd9b1f0fac5b49e5000000000000000000000000616964aa4652812da73a8ca0cd9b1f0fac5b49e5000000000000000000000000000000000000000000000000027f7d0bdb92000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x222a3984e54eec86ae9b7faac0d10cd383b31fd15334cd870c0d30bb7f79bfb5,2021-12-06 15:10:08.000 UTC,0,true +8340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005af12635675427ea85358ac42b8550027b10f4910000000000000000000000005af12635675427ea85358ac42b8550027b10f491000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8342,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008315fa4d626aafb8f170270f7692d685d6646c000000000000000000000000008315fa4d626aafb8f170270f7692d685d6646c0000000000000000000000000000000000000000000000000007b6ff547b2b42e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8343,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079904d39117d5fec74ce78ef08ba0e90e426e8d300000000000000000000000079904d39117d5fec74ce78ef08ba0e90e426e8d300000000000000000000000000000000000000000000000000423ec11d8695a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8347,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000232b26c22d14428b20f9885a1ec0a9567ef9f080000000000000000000000000232b26c22d14428b20f9885a1ec0a9567ef9f080000000000000000000000000000000000000000000000000008998b5b003410b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab04c70d86143193990371d691995325ecbed717000000000000000000000000ab04c70d86143193990371d691995325ecbed7170000000000000000000000000000000000000000000000000082e1056b0a444200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006da3e90a3aeb11353e54c4830a7903947e519bfc0000000000000000000000006da3e90a3aeb11353e54c4830a7903947e519bfc00000000000000000000000000000000000000000000000004011bb1b087312b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8354,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003108f1ffc15716ad537e039d4e33deb221f4982d0000000000000000000000003108f1ffc15716ad537e039d4e33deb221f4982d00000000000000000000000000000000000000000000000000c48541ff0dbe9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd6972254906c2ccd4c325f67dcc1a2ebc80652b000000000000000000000000fd6972254906c2ccd4c325f67dcc1a2ebc80652b00000000000000000000000000000000000000000000000001e0fd0dbcf1660a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8356,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f7de8cd5e0fd700af34c5d5ff214b0aca5c49d70000000000000000000000000f7de8cd5e0fd700af34c5d5ff214b0aca5c49d7000000000000000000000000000000000000000000000000015c31c4c1ea0a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8357,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000083d420a602b5cd560ac5fa9bbca0d5e91e4cb9750000000000000000000000000000000000000000000000036bc7cbd7666adda4,,,1,true +8358,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fb4aaa9c305f9888d1131325259a31378fa36ab0000000000000000000000002fb4aaa9c305f9888d1131325259a31378fa36ab00000000000000000000000000000000000000000000000000d8d7be4dec417300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb6c46c494f6468cfb7b02d708cc17589662ee53000000000000000000000000eb6c46c494f6468cfb7b02d708cc17589662ee53000000000000000000000000000000000000000000000000000d1ea736c19fb400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8362,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d4b09c164cd54aef6c5cbafba305bb162b98c490000000000000000000000006d4b09c164cd54aef6c5cbafba305bb162b98c4900000000000000000000000000000000000000000000000004005e72322d2e8600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8363,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e68055d6d79498ee3f90ebf1a8301094a25a38e0000000000000000000000000e68055d6d79498ee3f90ebf1a8301094a25a38e0000000000000000000000000000000000000000000000000009f678b05d4a6ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8d1b13e56d1a680ee306364628cdc07a4be8072000000000000000000000000b8d1b13e56d1a680ee306364628cdc07a4be8072000000000000000000000000000000000000000000000000009f678b05d4a6ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003777786a1717a93bf950d16d4e6c0faa35995eff0000000000000000000000003777786a1717a93bf950d16d4e6c0faa35995eff000000000000000000000000000000000000000000000000009f678b05d4a6ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8366,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000274fa9f7bbc8a1bb4cd8bf33c6c23e3f36fc2502000000000000000000000000274fa9f7bbc8a1bb4cd8bf33c6c23e3f36fc2502000000000000000000000000000000000000000000000000009f678b05d4a6ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074af1733a7cefdfa34fd028e8b7aee68a1c76c8300000000000000000000000074af1733a7cefdfa34fd028e8b7aee68a1c76c83000000000000000000000000000000000000000000000000009f678b05d4a6ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d89c351b97dff632a38ff10265ee0d74f4573b20000000000000000000000000d89c351b97dff632a38ff10265ee0d74f4573b20000000000000000000000000000000000000000000000000009f678b05d4a6ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c869639d0c999f8cd29a87cd7cc0b93de0c10e88000000000000000000000000c869639d0c999f8cd29a87cd7cc0b93de0c10e88000000000000000000000000000000000000000000000000008afb2401777acb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8371,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000905777492201f8cc36e2b5981df9fc532023b7d7000000000000000000000000905777492201f8cc36e2b5981df9fc532023b7d700000000000000000000000000000000000000000000000000929e8a2a2fb67800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c002ddf1bdd3878c6b1c93c2a215158d24fbfdb0000000000000000000000003c002ddf1bdd3878c6b1c93c2a215158d24fbfdb000000000000000000000000000000000000000000000000008fce5515a65eb600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8373,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a57d88e37658471f64eb906835cd634cb2181e80000000000000000000000004a57d88e37658471f64eb906835cd634cb2181e800000000000000000000000000000000000000000000000000964e3c48c11a1400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8375,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a384da004bba6297921c8d684cfe6102e4737647000000000000000000000000a384da004bba6297921c8d684cfe6102e4737647000000000000000000000000000000000000000000000000009813359878059900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000015438e55fd7558576369c0cab84e6a96b70e430000000000000000000000000015438e55fd7558576369c0cab84e6a96b70e4300000000000000000000000000000000000000000000000000098908391377eea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd31cb624261d7c4626d103c5cee441add892ade000000000000000000000000fd31cb624261d7c4626d103c5cee441add892ade000000000000000000000000000000000000000000000000009b001906f4436e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8378,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006416e7c281a55e76973546c9d3175f69fd4a8aeb0000000000000000000000006416e7c281a55e76973546c9d3175f69fd4a8aeb00000000000000000000000000000000000000000000000000969752b302c9e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8379,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039140487e6b09d073e3c859039a9088a11cf1ae600000000000000000000000039140487e6b09d073e3c859039a9088a11cf1ae600000000000000000000000000000000000000000000000000aba5959db3360000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8380,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ae344fd27bd50cdcd807bccecf747c8218dc30d0000000000000000000000007ae344fd27bd50cdcd807bccecf747c8218dc30d000000000000000000000000000000000000000000000000009c797429c5288800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8381,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000606f62cdb593a03dc158e39fa06c5c1c12c730d9000000000000000000000000606f62cdb593a03dc158e39fa06c5c1c12c730d9000000000000000000000000000000000000000000000000009ccc69c688c73800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8382,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081e11c21016dd61c94c9a9d4251dd9702bbf770300000000000000000000000081e11c21016dd61c94c9a9d4251dd9702bbf770300000000000000000000000000000000000000000000000000975e5e01ff4a7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078a613d8c147e3c1a9b9b103410260d82ec4ca4800000000000000000000000078a613d8c147e3c1a9b9b103410260d82ec4ca48000000000000000000000000000000000000000000000000009d6b7be496935d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046f6abf7566711db611a79162bb587a1d8a319fa00000000000000000000000046f6abf7566711db611a79162bb587a1d8a319fa000000000000000000000000000000000000000000000000009dd76536c8181b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8385,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dcd695bb523fd1ef04f0a17f8cc0f7b270759adf000000000000000000000000dcd695bb523fd1ef04f0a17f8cc0f7b270759adf000000000000000000000000000000000000000000000000009d81db750823f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064176d54674c06414a9e3dffb5d1857ecb97044900000000000000000000000064176d54674c06414a9e3dffb5d1857ecb970449000000000000000000000000000000000000000000000000009d81db750823f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000664d72a63847339b5e7d76a1ffb3656d465042c6000000000000000000000000664d72a63847339b5e7d76a1ffb3656d465042c600000000000000000000000000000000000000000000000000a0aa48e7cc8ab500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f35693a104ba7fad7ac91530cfb0625c9fbae240000000000000000000000000f35693a104ba7fad7ac91530cfb0625c9fbae24000000000000000000000000000000000000000000000000009ed58cf833830c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8389,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007321723c2e19cd27190dcfb888abd44fd6627d4e0000000000000000000000007321723c2e19cd27190dcfb888abd44fd6627d4e000000000000000000000000000000000000000000000000009a83943cf6d01700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8390,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030c4af4fa29e0d3c7b840d55b6db4646d52b23e700000000000000000000000030c4af4fa29e0d3c7b840d55b6db4646d52b23e7000000000000000000000000000000000000000000000000009ccef6c1cfb4ff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8391,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099ae174133946e7ea01cba09555069f0a67b9b6100000000000000000000000099ae174133946e7ea01cba09555069f0a67b9b61000000000000000000000000000000000000000000000000009d8b9b7f575ec800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000863ce1bf06fe1a066310d4e5aea3f11bd2473675000000000000000000000000863ce1bf06fe1a066310d4e5aea3f11bd2473675000000000000000000000000000000000000000000000000009d88419d16bce000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004235dd69859c58fa0ebdd7b5e6df255a24a5bc700000000000000000000000004235dd69859c58fa0ebdd7b5e6df255a24a5bc7000000000000000000000000000000000000000000000000009d7613e49c9c8200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4c03e75b92f7e07a15376850a4cae9f9e1b1803000000000000000000000000e4c03e75b92f7e07a15376850a4cae9f9e1b1803000000000000000000000000000000000000000000000000009e5481dd89aec900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6dde5e70c254c141caa6b1b00f171fc1178c9f6000000000000000000000000c6dde5e70c254c141caa6b1b00f171fc1178c9f6000000000000000000000000000000000000000000000000009e275fd1f575e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd31b1775610896ea9e1dd2ab40ab16c7d03c29b000000000000000000000000bd31b1775610896ea9e1dd2ab40ab16c7d03c29b000000000000000000000000000000000000000000000000009f55b0d202dbda00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8397,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009dc97597e33ffbbf56f7304bcc520f855b49b55d0000000000000000000000009dc97597e33ffbbf56f7304bcc520f855b49b55d00000000000000000000000000000000000000000000000000a1717573d4e32a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022e27e1997a4017643c273e4fa8552f885bd477400000000000000000000000022e27e1997a4017643c273e4fa8552f885bd477400000000000000000000000000000000000000000000000000a28ff7424894e300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a1efd1ce051d9be9f16d3452887c1a44a9b93780000000000000000000000000a1efd1ce051d9be9f16d3452887c1a44a9b937800000000000000000000000000000000000000000000000001978395190a630f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008874803a8040e343d60734d99689c1aa809c58c20000000000000000000000008874803a8040e343d60734d99689c1aa809c58c200000000000000000000000000000000000000000000000000a08a1adae03e7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8402,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f217c58af896247d18150ef76a5112e34a97be60000000000000000000000006f217c58af896247d18150ef76a5112e34a97be60000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c49a331ce7186b1e7294ed3a5a2af1e73b53a921000000000000000000000000c49a331ce7186b1e7294ed3a5a2af1e73b53a92100000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d2537201050756a7e53da2006becfaa02727de50000000000000000000000000d2537201050756a7e53da2006becfaa02727de5000000000000000000000000000000000000000000000000003fe303e8a9fcd400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8337a50441a3e5b2d187961e130b070bc9df09a000000000000000000000000a8337a50441a3e5b2d187961e130b070bc9df09a00000000000000000000000000000000000000000000000000413d86570bd6e400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000783db0d30e2ce47b9ef9eaee9e32a6caef8022f4000000000000000000000000783db0d30e2ce47b9ef9eaee9e32a6caef8022f40000000000000000000000000000000000000000000000000004536a4212a6c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000270815659d4f6ecd770546c161f9b7a929d31877000000000000000000000000270815659d4f6ecd770546c161f9b7a929d318770000000000000000000000000000000000000000000000000013bc3e39ba300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8409,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020344897c84492526169005a77e5c31277362edb00000000000000000000000020344897c84492526169005a77e5c31277362edb000000000000000000000000000000000000000000000000003ee4f362f7cd0d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec3b481c482e92850edf554a3ad5bcd89e15c662000000000000000000000000ec3b481c482e92850edf554a3ad5bcd89e15c66200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a02f48636a3a71d4c9e4377c562fd2e90f9485ae000000000000000000000000a02f48636a3a71d4c9e4377c562fd2e90f9485ae00000000000000000000000000000000000000000000000000028a64b14e777c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abde762e8e7155b766200d291aeefb3cb96b8729000000000000000000000000abde762e8e7155b766200d291aeefb3cb96b87290000000000000000000000000000000000000000000000000002c337218e1ac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8413,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007deff0333176bb6b998dc54f924bdc34f36e2f560000000000000000000000007deff0333176bb6b998dc54f924bdc34f36e2f560000000000000000000000000000000000000000000000000042eba2c376663900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8414,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c18776e78e4a5a295ab99d86912a36d38c11f3ef000000000000000000000000c18776e78e4a5a295ab99d86912a36d38c11f3ef0000000000000000000000000000000000000000000000000015abeaed21400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8415,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000541bbdbdcb20462eab5c0abaeff1f75450223c70000000000000000000000000541bbdbdcb20462eab5c0abaeff1f75450223c7000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc13514bc2b74b1886e7aff16645756436f2de82000000000000000000000000cc13514bc2b74b1886e7aff16645756436f2de8200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc13514bc2b74b1886e7aff16645756436f2de82000000000000000000000000cc13514bc2b74b1886e7aff16645756436f2de8200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8418,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e194ceedda82ca630ff495911683937b6b0c5c48000000000000000000000000e194ceedda82ca630ff495911683937b6b0c5c48000000000000000000000000000000000000000000000000000419103e50cd8600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000765a90ee3610330e76ae4d4010bf8abfef83ba2a000000000000000000000000765a90ee3610330e76ae4d4010bf8abfef83ba2a0000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ee97dbc9491f74f72a3f6e6e84eefd4d5873e8e0000000000000000000000005ee97dbc9491f74f72a3f6e6e84eefd4d5873e8e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b379f5cf09ec93ef91162f79ecd37c32c60fb6d4000000000000000000000000b379f5cf09ec93ef91162f79ecd37c32c60fb6d400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b59543592a4cf2c9cd89ae37a0ddf589b52ab4a1000000000000000000000000b59543592a4cf2c9cd89ae37a0ddf589b52ab4a100000000000000000000000000000000000000000000000000489d562cb25a9b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8423,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ee97dbc9491f74f72a3f6e6e84eefd4d5873e8e0000000000000000000000005ee97dbc9491f74f72a3f6e6e84eefd4d5873e8e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f923918aa540eae6756e8b0be6e84003bbcebfe0000000000000000000000006f923918aa540eae6756e8b0be6e84003bbcebfe00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8425,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a913be969fd81224a9b7022c97ee52aabaa5d1ce000000000000000000000000a913be969fd81224a9b7022c97ee52aabaa5d1ce00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8426,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fce1fbc0b5dec54e400118dc40e6bf4d7c1d7b87000000000000000000000000fce1fbc0b5dec54e400118dc40e6bf4d7c1d7b8700000000000000000000000000000000000000000000000000aa87bee538000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8427,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000156d07be5ce6cffadbe92f8171427c9bf71ffb94000000000000000000000000156d07be5ce6cffadbe92f8171427c9bf71ffb9400000000000000000000000000000000000000000000000000427a5fd37eaf6c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001876ac47bc2bcc8ccc70ff6e25206585e923923e0000000000000000000000001876ac47bc2bcc8ccc70ff6e25206585e923923e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e605e60773ce0ee4f528159d237e80dce064331e000000000000000000000000e605e60773ce0ee4f528159d237e80dce064331e000000000000000000000000000000000000000000000000003c7b6a9e6b595200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe489e78f1d3f8d076544ecc1242aacdb0fb6215000000000000000000000000fe489e78f1d3f8d076544ecc1242aacdb0fb621500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d3f616e9e9179a6e9922b2eeff37dc563981ce90000000000000000000000009d3f616e9e9179a6e9922b2eeff37dc563981ce900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092ca74bdb45f90b87770fbe3e1473df47a51b8d100000000000000000000000092ca74bdb45f90b87770fbe3e1473df47a51b8d100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004dc08221af9352f411d69648d960369d137332f00000000000000000000000004dc08221af9352f411d69648d960369d137332f000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8434,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e0a2d1950a8f9552d91d234bda7df9327e333eb0000000000000000000000000e0a2d1950a8f9552d91d234bda7df9327e333eb00000000000000000000000000000000000000000000000000180fc32d2cb60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8435,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c515d7c837c9896399d0bfeb69e74dbff9e9925c000000000000000000000000c515d7c837c9896399d0bfeb69e74dbff9e9925c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001506942a580e61f3afd004fbdd94136bb4e5fefa0000000000000000000000001506942a580e61f3afd004fbdd94136bb4e5fefa00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a9aab3e6dbafb5c23c174066374778d957b45660000000000000000000000004a9aab3e6dbafb5c23c174066374778d957b456600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8438,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000991f88662a8a9e071b4f963b006d88af5e2631bd000000000000000000000000991f88662a8a9e071b4f963b006d88af5e2631bd00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc0faf8887cef250b2b692ae6cf2a710a79960be000000000000000000000000cc0faf8887cef250b2b692ae6cf2a710a79960be00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002deb9bc20b0ee85156bd1b453f6ace54552c3e100000000000000000000000002deb9bc20b0ee85156bd1b453f6ace54552c3e1000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8441,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002602cda64237b42a8c90c33bd7074edd1f4c07070000000000000000000000000000000000000000000000037c1b86be361fe9bc,0xd619b3b7749864d770ac06fcea4d19d72e6992a498c21bf501d228d8fc3aa08e,2022-02-08 09:49:55.000 UTC,0,true +8442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000068617ba9993be213696b3d2935c042a2a35dfb8000000000000000000000000068617ba9993be213696b3d2935c042a2a35dfb800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8443,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a93fe41bfb59f631b76810caf26ec6c013ed6b43000000000000000000000000a93fe41bfb59f631b76810caf26ec6c013ed6b43000000000000000000000000000000000000000000000000000238cc48d7b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ebcdd05e56182063a0521556d71ba062576ceecc000000000000000000000000ebcdd05e56182063a0521556d71ba062576ceecc0000000000000000000000000000000000000000000000000042a143ee988ecb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067ccdfeac464d9fa9bcafdeee13c928fa223181700000000000000000000000067ccdfeac464d9fa9bcafdeee13c928fa22318170000000000000000000000000000000000000000000000000001acbc5d8c100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000519928fd018de695b5e39d3343404ceea2cf26f8000000000000000000000000519928fd018de695b5e39d3343404ceea2cf26f8000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008db89388fa485c6b85074140b865c946dc23f6520000000000000000000000008db89388fa485c6b85074140b865c946dc23f65200000000000000000000000000000000000000000000000000a23a161324da0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003777ac398a53a27409f8caf284871b6a9dca1d710000000000000000000000003777ac398a53a27409f8caf284871b6a9dca1d71000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8cd49bd45db93e80c995e9eea06106896aaf290000000000000000000000000e8cd49bd45db93e80c995e9eea06106896aaf29000000000000000000000000000000000000000000000000000eb4b34a72b008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bab8e08de34b1c00e07767f865a8b986474d4690000000000000000000000005bab8e08de34b1c00e07767f865a8b986474d4690000000000000000000000000000000000000000000000000049e487ab9a71c800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022f501feb15ef39026cc4eae6863f2423427a64e00000000000000000000000022f501feb15ef39026cc4eae6863f2423427a64e000000000000000000000000000000000000000000000000000252e68625c80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000421cc7b6224accb6c12280e3b697c65d9d60ad70000000000000000000000000421cc7b6224accb6c12280e3b697c65d9d60ad7000000000000000000000000000000000000000000000000000120fca2831e1ec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8460,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d5fae9a76de0bf1063eee5d4ae05be77cb08e68a0000000000000000000000000000000000000000000000001d64e0ffd574af32,,,1,true +8461,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000071d9d738d494d4a8e2de76f3df081c24a096fbe000000000000000000000000071d9d738d494d4a8e2de76f3df081c24a096fbe00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d061cbfcd7749558f635dea77428f83d15455f4f000000000000000000000000d061cbfcd7749558f635dea77428f83d15455f4f00000000000000000000000000000000000000000000000000000000001cfde000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x1c3a1f543319ade8b064fc581d339ea36ae33f9d6942b81e141eab90bfb09492,2022-05-07 05:56:39.000 UTC,0,true +8463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022f501feb15ef39026cc4eae6863f2423427a64e00000000000000000000000022f501feb15ef39026cc4eae6863f2423427a64e00000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8464,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ccec22598f81b2df2060b4803987d734ac79ea00000000000000000000000006ccec22598f81b2df2060b4803987d734ac79ea00000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a515e8879d4e389da004a35aeffdc6fcc0608600000000000000000000000009a515e8879d4e389da004a35aeffdc6fcc06086000000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000184f35026bc65ae1116ce640b1d7751fde0c7cc8000000000000000000000000184f35026bc65ae1116ce640b1d7751fde0c7cc8000000000000000000000000000000000000000000000000000182890607900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a515e8879d4e389da004a35aeffdc6fcc0608600000000000000000000000009a515e8879d4e389da004a35aeffdc6fcc0608600000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8468,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003db125bed35332943fb9b7d74da6ed0dcde16d9f0000000000000000000000003db125bed35332943fb9b7d74da6ed0dcde16d9f0000000000000000000000000000000000000000000000000001d37af36a200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009caf735c8c949e465a4f35c426e5ba50abb7a4870000000000000000000000009caf735c8c949e465a4f35c426e5ba50abb7a4870000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003cf96cad02b1c82087f11aa7c892ff91109a34150000000000000000000000003cf96cad02b1c82087f11aa7c892ff91109a34150000000000000000000000000000000000000000000000000003328b944c400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067f53a7f020b545bb1ec501bd17b30d0202462c500000000000000000000000067f53a7f020b545bb1ec501bd17b30d0202462c5000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053f338161f177268034c5d38f77679b72c1a284c00000000000000000000000053f338161f177268034c5d38f77679b72c1a284c0000000000000000000000000000000000000000000000000001d0d7bdf1d80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001153b404e2d3f0dfaba51a74f89f404977225c9b0000000000000000000000001153b404e2d3f0dfaba51a74f89f404977225c9b000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e62fca375844029c7ecf251a3f6320329b84e4ad000000000000000000000000e62fca375844029c7ecf251a3f6320329b84e4ad00000000000000000000000000000000000000000000000000030b6fdc92900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003475dca1b35e709328e94344882bf56c023db0fc0000000000000000000000003475dca1b35e709328e94344882bf56c023db0fc00000000000000000000000000000000000000000000000002a303fe4b53000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f886192d5c6f3c8e4478b1a0bde79ba3a68bb4f0000000000000000000000009f886192d5c6f3c8e4478b1a0bde79ba3a68bb4f0000000000000000000000000000000000000000000000000001eec3dec2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8477,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d491c4f7291e1d0a60774635218edb35857ff09f000000000000000000000000d491c4f7291e1d0a60774635218edb35857ff09f000000000000000000000000000000000000000000000000000175cd6500b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8479,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000687966bd74782f3585d471442231100abb5a46d8000000000000000000000000687966bd74782f3585d471442231100abb5a46d8000000000000000000000000000000000000000000000000002a59568f9e6f0600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8480,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000877ace1b6e0f421fffb33fe73856ef011de158c9000000000000000000000000877ace1b6e0f421fffb33fe73856ef011de158c90000000000000000000000000000000000000000000000000045314e81f8955d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8481,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9006c3732dde8c2d5c4ce65568179035ace744d000000000000000000000000e9006c3732dde8c2d5c4ce65568179035ace744d00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c032a30d6446d70963a91694693cad2c7fa25ca8000000000000000000000000c032a30d6446d70963a91694693cad2c7fa25ca80000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8483,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fe33afe1109a52d7f6311cc0b8b8388d547ea5c0000000000000000000000007fe33afe1109a52d7f6311cc0b8b8388d547ea5c00000000000000000000000000000000000000000000000000a50aae61d1b86600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000adfd117f7e3fca69a28ac4f415bee1132b2c265c000000000000000000000000adfd117f7e3fca69a28ac4f415bee1132b2c265c0000000000000000000000000000000000000000000000000006484a6b74f72f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8486,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000678970c3f6ed29662a580dc276d40fd1db5412d6000000000000000000000000678970c3f6ed29662a580dc276d40fd1db5412d600000000000000000000000000000000000000000000000000911f41f5b47c9300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8487,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002d885d747c93fc075ffbfe43074a3ebd7c2c21a00000000000000000000000002d885d747c93fc075ffbfe43074a3ebd7c2c21a000000000000000000000000000000000000000000000000000c69b36465b63f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8488,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6c34c40ee88667d145a789516dd3aac6ff66569000000000000000000000000a6c34c40ee88667d145a789516dd3aac6ff665690000000000000000000000000000000000000000000000000016f59fa05cfdd600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8489,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3b9fe8c9cb09360f1b72d91681cdaaf7d9fe575000000000000000000000000c3b9fe8c9cb09360f1b72d91681cdaaf7d9fe575000000000000000000000000000000000000000000000000008845c95fe1680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6c34c40ee88667d145a789516dd3aac6ff66569000000000000000000000000a6c34c40ee88667d145a789516dd3aac6ff66569000000000000000000000000000000000000000000000000001dc1811eddd51e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6c34c40ee88667d145a789516dd3aac6ff66569000000000000000000000000a6c34c40ee88667d145a789516dd3aac6ff665690000000000000000000000000000000000000000000000000000d12c7f080bff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000365a3ec18ea9e4591dbd2e7687cb14f472f4b559000000000000000000000000365a3ec18ea9e4591dbd2e7687cb14f472f4b559000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8493,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050f71937e2ca4cff80e713f188db1a989d76dcae00000000000000000000000050f71937e2ca4cff80e713f188db1a989d76dcae00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dbeab3ac04a0b633bf9c7aaf102330fbc50387dd000000000000000000000000dbeab3ac04a0b633bf9c7aaf102330fbc50387dd000000000000000000000000000000000000000000000000006782b01e18e30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011d26bd5b0cc0762431e5be22ed10317a6440e6b00000000000000000000000011d26bd5b0cc0762431e5be22ed10317a6440e6b000000000000000000000000000000000000000000000000000c23ad62f3ff4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a7a56ab6d5bb974f2d3e35e2ebc2ed261feacb00000000000000000000000008a7a56ab6d5bb974f2d3e35e2ebc2ed261feacb0000000000000000000000000000000000000000000000000002714711487800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000407410d84e15f79642272edaeb437ac65d7298e6000000000000000000000000407410d84e15f79642272edaeb437ac65d7298e60000000000000000000000000000000000000000000000000007d0e36a81800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cb62717bfee56bd65111dc7006afbe53a41e6c90000000000000000000000004cb62717bfee56bd65111dc7006afbe53a41e6c90000000000000000000000000000000000000000000000000077c6985a22e64500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d1870a437031ea33add0d3e1cb9fbbb89cac91c0000000000000000000000001d1870a437031ea33add0d3e1cb9fbbb89cac91c00000000000000000000000000000000000000000000000000c15831e3c6781e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063968e995e962375d3bc514bef7fd9b78aaa550b00000000000000000000000063968e995e962375d3bc514bef7fd9b78aaa550b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8502,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c03cd00d464faa73dd37111358905f3c6c96999f000000000000000000000000c03cd00d464faa73dd37111358905f3c6c96999f0000000000000000000000000000000000000000000000000000d15d9251d44000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8503,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000134342210990c23e58cac9224af88882f455a75c000000000000000000000000134342210990c23e58cac9224af88882f455a75c00000000000000000000000000000000000000000000000000e858af89f5948300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3c31b2075c0ed0d5464c432cc8ced58c31b403630592cdf88dc18ccfb83168d5,2022-05-16 06:55:13.000 UTC,0,true +8504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009682b2878122d178dcf20185c7ad9f5a39a1d0fa0000000000000000000000009682b2878122d178dcf20185c7ad9f5a39a1d0fa00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf42be03d6c9ecabcc98b0b8198c63d5062d078b000000000000000000000000cf42be03d6c9ecabcc98b0b8198c63d5062d078b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8507,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037ee45e654e4d602a5487faa14197a8a2d45e34c00000000000000000000000037ee45e654e4d602a5487faa14197a8a2d45e34c0000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8508,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b30f8c4b4957333f905a8fa1a4cb5fb3876ad37f000000000000000000000000b30f8c4b4957333f905a8fa1a4cb5fb3876ad37f0000000000000000000000000000000000000000000000000001aa1a47315e4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc0920a6a94919c3bba20ee0d53612b9054a013a000000000000000000000000cc0920a6a94919c3bba20ee0d53612b9054a013a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8511,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009dc922ae6cf0b888592a72d32839fac7c43f55870000000000000000000000009dc922ae6cf0b888592a72d32839fac7c43f558700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8514,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004988ec8fa41ac3430611e9abfc453329f26fa3770000000000000000000000004988ec8fa41ac3430611e9abfc453329f26fa3770000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7f8a31c11193b801785993894cbce9af3b23368000000000000000000000000d7f8a31c11193b801785993894cbce9af3b2336800000000000000000000000000000000000000000000000000968f1757353f9e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005167078032728ab3f1915c353badd2441edbc7920000000000000000000000005167078032728ab3f1915c353badd2441edbc792000000000000000000000000000000000000000000000000000414aafc9d368000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8517,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000934c53be5f96f298e55b83763aa9aa84bd2ed438000000000000000000000000934c53be5f96f298e55b83763aa9aa84bd2ed43800000000000000000000000000000000000000000000000000004d4e9ace500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fca6887e8f99f3f40f980a837f487d46224a1d80000000000000000000000001fca6887e8f99f3f40f980a837f487d46224a1d8000000000000000000000000000000000000000000000000000044936e37500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8520,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008e7488075d58158083330e9f37db55056b5edb33000000000000000000000000000000000000000000000002b5e3af16b1880000,0x6533748c005fd3fb6c2b567228a6b32ce60d9f890f6857a60c8c51c6d4ed18ec,2021-12-24 08:12:51.000 UTC,0,true +8521,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091cf62d238d64103ebe29f65e53fe5cbeff60f7f00000000000000000000000091cf62d238d64103ebe29f65e53fe5cbeff60f7f00000000000000000000000000000000000000000000000000005666e940f00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8522,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6d3c16c3f3414ff268efb043f913a4d492e825c000000000000000000000000b6d3c16c3f3414ff268efb043f913a4d492e825c0000000000000000000000000000000000000000000000000000338740c1200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8523,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000197ee44e8749419f4d87ebc9d311b15345137657000000000000000000000000197ee44e8749419f4d87ebc9d311b15345137657000000000000000000000000000000000000000000000000000046f0ca4ae00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8524,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058b02cca85bfe859a9a5f1957bd27d29aacb71f300000000000000000000000058b02cca85bfe859a9a5f1957bd27d29aacb71f30000000000000000000000000000000000000000000000000000327a19c8f80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8525,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000101539495fdb941639fca27c8e17424c7fbe37e6000000000000000000000000101539495fdb941639fca27c8e17424c7fbe37e600000000000000000000000000000000000000000000000000003be191cfe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8526,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000177e6d1beaee7a3331d8dacbd829fdda1a4e8356000000000000000000000000177e6d1beaee7a3331d8dacbd829fdda1a4e835600000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd12c0787a0d9eab016cfd2ef26620f2ae9cbb79000000000000000000000000dd12c0787a0d9eab016cfd2ef26620f2ae9cbb790000000000000000000000000000000000000000000000000000434d77b6a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000685a6447906bd6ffafaa27cc1867abb87ee87c6b000000000000000000000000685a6447906bd6ffafaa27cc1867abb87ee87c6b0000000000000000000000000000000000000000000000000000356328a5f80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8530,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a5ff89a6331e1b7145d9024523ab7bc92f0853c0000000000000000000000005a5ff89a6331e1b7145d9024523ab7bc92f0853c00000000000000000000000000000000000000000000000000001719e5fa300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b05dafc5da73a5c20163568c18c58daa40ab8540000000000000000000000004b05dafc5da73a5c20163568c18c58daa40ab85400000000000000000000000000000000000000000000000000005ac47f8c700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8532,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4ba7e02b90527dbb0cbb5173e42ae486cb8ae89000000000000000000000000e4ba7e02b90527dbb0cbb5173e42ae486cb8ae8900000000000000000000000000000000000000000000000000003291623fe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049fc3f948a2374e5d3d92bfb8dbc2173d27882cc00000000000000000000000049fc3f948a2374e5d3d92bfb8dbc2173d27882cc00000000000000000000000000000000000000000000000000003b7b1fc4b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d90c9f524e9b2c01a043d546456560db4af16130000000000000000000000003d90c9f524e9b2c01a043d546456560db4af161300000000000000000000000000000000000000000000000000008c0feb4ba00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e227b016dd30cdea3d72ff050cf90a5de57c8dc4000000000000000000000000e227b016dd30cdea3d72ff050cf90a5de57c8dc40000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000764c417532dc983b80294a3da65b269da712c564000000000000000000000000764c417532dc983b80294a3da65b269da712c56400000000000000000000000000000000000000000000000000376e4164382e1700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8539,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099c2fd7a0e0820ddcc859ff8567426d28f74557600000000000000000000000099c2fd7a0e0820ddcc859ff8567426d28f74557600000000000000000000000000000000000000000000000000130d551f49d9e700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ae882adb8c6c87f33896069c64f44bdf1f3f1820000000000000000000000008ae882adb8c6c87f33896069c64f44bdf1f3f182000000000000000000000000000000000000000000000000069f9d23bdc3f85600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099c2fd7a0e0820ddcc859ff8567426d28f74557600000000000000000000000099c2fd7a0e0820ddcc859ff8567426d28f745576000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099c2fd7a0e0820ddcc859ff8567426d28f74557600000000000000000000000099c2fd7a0e0820ddcc859ff8567426d28f745576000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cab55b0de19c01cdd284535a3fe8d73a657525bb000000000000000000000000cab55b0de19c01cdd284535a3fe8d73a657525bb0000000000000000000000000000000000000000000000000096193d81d8dd8900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8545,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063e077bf9b0faf76704cafe9f053e415112271c300000000000000000000000063e077bf9b0faf76704cafe9f053e415112271c3000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5ffc23c7fc71d65a5a9e30a161b4fbd3d6a093a000000000000000000000000e5ffc23c7fc71d65a5a9e30a161b4fbd3d6a093a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8548,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078b6849ca39cfb26b1de6742a3349ad54a18e02e00000000000000000000000078b6849ca39cfb26b1de6742a3349ad54a18e02e00000000000000000000000000000000000000000000000000911fbea4781c7a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8550,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008efebae61c2abfd41181dcc04f3c36334cb820a00000000000000000000000008efebae61c2abfd41181dcc04f3c36334cb820a000000000000000000000000000000000000000000000000002039396b5e440000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d06240b68a66fc009cd81ef695b4b4cc31e37bf9000000000000000000000000d06240b68a66fc009cd81ef695b4b4cc31e37bf900000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa692efef3f2d1d0639755299c797c6a3579b25e000000000000000000000000aa692efef3f2d1d0639755299c797c6a3579b25e000000000000000000000000000000000000000000000000009c757ce290c5d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056d662d0e2dbe179dfeee9f8fc4038f3128ccdc600000000000000000000000056d662d0e2dbe179dfeee9f8fc4038f3128ccdc600000000000000000000000000000000000000000000000000168fcc219efbae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005734d110867db331fce3c5e863ddb6a4f0201ed20000000000000000000000005734d110867db331fce3c5e863ddb6a4f0201ed2000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007607ee99410e57e5da56cc9f334235c7663930940000000000000000000000007607ee99410e57e5da56cc9f334235c766393094000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048cf31c151b1a2dfb5d2c9a90552f05c8aeca9cd00000000000000000000000048cf31c151b1a2dfb5d2c9a90552f05c8aeca9cd000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be76ec0c017db75da73254ce30c65fd2c6e7058d000000000000000000000000be76ec0c017db75da73254ce30c65fd2c6e7058d000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2cfb11253c219e8af1623a3b29788717e7b3db2000000000000000000000000e2cfb11253c219e8af1623a3b29788717e7b3db2000000000000000000000000000000000000000000000000006ec714722ede9a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8567,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e64c5aaddfa2f0274aa73367bee6e3879b0f9540000000000000000000000004e64c5aaddfa2f0274aa73367bee6e3879b0f954000000000000000000000000000000000000000000000000004f94ae6af8000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8568,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b255d025a6a1da4e5a707f8501dac148a0be382c000000000000000000000000b255d025a6a1da4e5a707f8501dac148a0be382c000000000000000000000000000000000000000000000000015f271d29aa460000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xffb196ad45f6b6f4b718b043f3a14b1658ac1c037dfaa64a58201e58e39a039f,2021-12-18 11:47:14.000 UTC,0,true +8569,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb62fab8d0e5303310d90ec325fe84f342671b43000000000000000000000000bb62fab8d0e5303310d90ec325fe84f342671b430000000000000000000000000000000000000000000000000138f2f038467b4f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8570,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000775dcdcff29bd88721172ecb35da4e948bcc8667000000000000000000000000775dcdcff29bd88721172ecb35da4e948bcc866700000000000000000000000000000000000000000000000000193223118055fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097a136d6b1ab9fc5e8ae9dbaec812e2d6eb4893e00000000000000000000000097a136d6b1ab9fc5e8ae9dbaec812e2d6eb4893e0000000000000000000000000000000000000000000000000014db79f698080e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8574,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ad268606cec97ef0fa77f74ddbebdcebbbd8d7c4000000000000000000000000ad268606cec97ef0fa77f74ddbebdcebbbd8d7c4000000000000000000000000000000000000000000000000000000000319750000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8575,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcf03727718cccaa55123eb6f21e57a60d972481000000000000000000000000fcf03727718cccaa55123eb6f21e57a60d97248100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8576,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007823ac7dd217d0f7cb5c49410b2c894d052bda760000000000000000000000007823ac7dd217d0f7cb5c49410b2c894d052bda7600000000000000000000000000000000000000000000000000288529f74657ee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcf03727718cccaa55123eb6f21e57a60d972481000000000000000000000000fcf03727718cccaa55123eb6f21e57a60d972481000000000000000000000000000000000000000000000000003af6a58e9e650000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a054517dab4695751c5276148a29a245c2163550000000000000000000000000a054517dab4695751c5276148a29a245c216355000000000000000000000000000000000000000000000000000352526bcc9ee0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8579,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e64c5aaddfa2f0274aa73367bee6e3879b0f9540000000000000000000000004e64c5aaddfa2f0274aa73367bee6e3879b0f95400000000000000000000000000000000000000000000000000399ca53698600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8581,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006972fe17e3b739a9851da27ba3602ad0e76aabb80000000000000000000000006972fe17e3b739a9851da27ba3602ad0e76aabb80000000000000000000000000000000000000000000000000060681d79af9f6c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc887e18fc8be649f4b2a72fc2767d892754572952385ec4fd2eda91d2de64a9d,2022-03-12 07:32:39.000 UTC,0,true +8583,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd925e0bac97cd4b988539620141753d6345969d000000000000000000000000dd925e0bac97cd4b988539620141753d6345969d000000000000000000000000000000000000000000000000002917e64fa5b11a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8584,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000815c971b10315a50ecc1fe77cfcb5ff8093f2493000000000000000000000000815c971b10315a50ecc1fe77cfcb5ff8093f2493000000000000000000000000000000000000000000000000002badafaa018d7200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8585,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091b597ad2ff79cc5266e326ca728adfe44757c5700000000000000000000000091b597ad2ff79cc5266e326ca728adfe44757c570000000000000000000000000000000000000000000000000015c8ac92b21c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005099683a6a18d13f025cfd19a4767d00448176200000000000000000000000005099683a6a18d13f025cfd19a4767d0044817620000000000000000000000000000000000000000000000000002bd91620ecbb8a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8589,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4cfca09d930c6634f074ca6bea7ec69c0625037000000000000000000000000a4cfca09d930c6634f074ca6bea7ec69c06250370000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8590,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8846f368ccb46308a40379c28d85408fa891baf000000000000000000000000e8846f368ccb46308a40379c28d85408fa891baf000000000000000000000000000000000000000000000000001f04307a21b10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8591,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c629a744d5d4641ae11032630432ce48e74971b0000000000000000000000007c629a744d5d4641ae11032630432ce48e74971b00000000000000000000000000000000000000000000000000295d641fda672300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8592,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f119602f96bbcf31604360a46dda1ed10b501b57000000000000000000000000f119602f96bbcf31604360a46dda1ed10b501b570000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8593,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d489f49c614deac1ed8463ebe789555b1e519485000000000000000000000000d489f49c614deac1ed8463ebe789555b1e51948500000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8595,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7a99e49910499eb0f78eff09a422068ea438fa6000000000000000000000000c7a99e49910499eb0f78eff09a422068ea438fa60000000000000000000000000000000000000000000000000031091b06392f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8597,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1da2a98a7d498d6bd18b053359fc11c9d9e079d000000000000000000000000d1da2a98a7d498d6bd18b053359fc11c9d9e079d00000000000000000000000000000000000000000000000000000002540be40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8598,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5ea922bd46a0c1cb6a6699a3b7b5964a4b7f6cc000000000000000000000000b5ea922bd46a0c1cb6a6699a3b7b5964a4b7f6cc000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047a72907b9d6488cb0d164de592b0be0bb95554f00000000000000000000000047a72907b9d6488cb0d164de592b0be0bb95554f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8600,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d4d97dea692f8cb1f3e80dbd1724ae7b3305d180000000000000000000000002d4d97dea692f8cb1f3e80dbd1724ae7b3305d18000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8601,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e085c4425e8a3a7b05fe77e929c6db8779f25f41000000000000000000000000e085c4425e8a3a7b05fe77e929c6db8779f25f41000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8602,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089329fcc52c2e5ad78f32cddc92a75aadb7ad2b600000000000000000000000089329fcc52c2e5ad78f32cddc92a75aadb7ad2b6000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8603,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002055d8ef30cfa3ba2f14d8cc4be8738ae09400d80000000000000000000000002055d8ef30cfa3ba2f14d8cc4be8738ae09400d800000000000000000000000000000000000000000000000000838ff79d0fee6700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8604,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000255af8e20e5ff15268bf4ca81f4679d0abe32102000000000000000000000000255af8e20e5ff15268bf4ca81f4679d0abe32102000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8605,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dae836e608110d6c81d6ff7dafd327d52126e976000000000000000000000000dae836e608110d6c81d6ff7dafd327d52126e976000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8606,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb18a38061a5ed1490dcee7d6941a0a9c2a82b50000000000000000000000000bb18a38061a5ed1490dcee7d6941a0a9c2a82b50000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8607,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001933baa0d5e98fd53e60f237b67e39d40cda19e50000000000000000000000001933baa0d5e98fd53e60f237b67e39d40cda19e5000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8608,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041d5def13c7602b129bbed114c44ee0fec5ef74400000000000000000000000041d5def13c7602b129bbed114c44ee0fec5ef744000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076aa729dc76da61b5a59b06ca678fefec86c332200000000000000000000000076aa729dc76da61b5a59b06ca678fefec86c3322000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8610,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d954013b3866152d5c788eff83eb69704621a497000000000000000000000000d954013b3866152d5c788eff83eb69704621a497000000000000000000000000000000000000000000000000004380663abb800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8611,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c9f580d9062c41f0858f6b19d2491217b76cb9f0000000000000000000000004c9f580d9062c41f0858f6b19d2491217b76cb9f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8612,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009554c02da9113f9cca954405ad401090751178c20000000000000000000000009554c02da9113f9cca954405ad401090751178c2000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8613,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7ab243035c94a87ee3d97d8bbab9b8514e52b86000000000000000000000000e7ab243035c94a87ee3d97d8bbab9b8514e52b86000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8614,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ea49c6dc749d2a34d51f24de63b9ea1fe3605100000000000000000000000007ea49c6dc749d2a34d51f24de63b9ea1fe360510000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8615,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff22a6b7d20a0eacd62b428da07171fa7be6e67a000000000000000000000000ff22a6b7d20a0eacd62b428da07171fa7be6e67a00000000000000000000000000000000000000000000000003fe9ee53deae91c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001eb4b6976d04e9df25d7426fcb409e5d9d99cb6f0000000000000000000000001eb4b6976d04e9df25d7426fcb409e5d9d99cb6f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8618,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005aa07a9d950f1b496b928dd455d6be761ccc0f8d0000000000000000000000005aa07a9d950f1b496b928dd455d6be761ccc0f8d000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8619,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004660a02784d60ad35a50005df3981f1ad40c491f0000000000000000000000004660a02784d60ad35a50005df3981f1ad40c491f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8620,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0b78ccc36a78a6ab0b8ddcc56a00fd292e222d3000000000000000000000000c0b78ccc36a78a6ab0b8ddcc56a00fd292e222d3000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ab6a10692855a79b34644ec47ecbe04071579350000000000000000000000001ab6a10692855a79b34644ec47ecbe0407157935000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8622,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000681df54a8672b76796b29f5402866da2065249c0000000000000000000000000681df54a8672b76796b29f5402866da2065249c0000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004eb1bf3c42fc1c394078c33174479f550c11430f0000000000000000000000004eb1bf3c42fc1c394078c33174479f550c11430f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8624,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021c64d4d94938af244e1c80dc3c52c0d23b2af8f00000000000000000000000021c64d4d94938af244e1c80dc3c52c0d23b2af8f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000926051a979aa8dd87a4cc49fcc40ac3eacc57750000000000000000000000000926051a979aa8dd87a4cc49fcc40ac3eacc5775000000000000000000000000000000000000000000000000005e17bd19b47c4100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d954013b3866152d5c788eff83eb69704621a497000000000000000000000000d954013b3866152d5c788eff83eb69704621a497000000000000000000000000000000000000000000000000000000000112a88000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c981cb893a285cb5276488099023389afa134650000000000000000000000003c981cb893a285cb5276488099023389afa13465000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c3dd65805ed46f78e3665f15899146140c0e30e0000000000000000000000007c3dd65805ed46f78e3665f15899146140c0e30e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8630,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023c63cb0b2fc6925f5ca3bf0fe2bf0a22ba39b6f00000000000000000000000023c63cb0b2fc6925f5ca3bf0fe2bf0a22ba39b6f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e12c11e98b97f5788baa0c8a1034ae68a9662482000000000000000000000000e12c11e98b97f5788baa0c8a1034ae68a9662482000000000000000000000000000000000000000000000000007393ee87573e7d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ccab53eda7efb901cbb4d52454ff382c7a8afb00000000000000000000000006ccab53eda7efb901cbb4d52454ff382c7a8afb0000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6241b99a30554c52c3713026b1d6e485158ea73000000000000000000000000c6241b99a30554c52c3713026b1d6e485158ea73000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098566c84c47c5d9eba54a3931b150e4e2327c72000000000000000000000000098566c84c47c5d9eba54a3931b150e4e2327c720000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b437e238bf5ee4fd2240fc5ff4740691ad440549000000000000000000000000b437e238bf5ee4fd2240fc5ff4740691ad4405490000000000000000000000000000000000000000000000000012202d1274aca800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8636,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067a63f68052d70bdaebb15786d73ca55c8ecae0f00000000000000000000000067a63f68052d70bdaebb15786d73ca55c8ecae0f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8637,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009729e4584afb7ae74aca69d982c43c2c02d03a2b0000000000000000000000009729e4584afb7ae74aca69d982c43c2c02d03a2b000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f81cfeab6217a0d2b0144cb1238dad0b55be6f90000000000000000000000000f81cfeab6217a0d2b0144cb1238dad0b55be6f9000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8639,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e060d80e2e284282a710f08a105db7328110c920000000000000000000000008e060d80e2e284282a710f08a105db7328110c92000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8640,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f3f94b8bae2b195e8efe85d5872ee76602af3f90000000000000000000000005f3f94b8bae2b195e8efe85d5872ee76602af3f9000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a109e8af4af849bf79add6649e67ae07663a284a000000000000000000000000a109e8af4af849bf79add6649e67ae07663a284a000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb008401e9ad8e98b9b1999b45b7a094813930dd000000000000000000000000fb008401e9ad8e98b9b1999b45b7a094813930dd000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8ec9189b9a8e6fff4081b02798229e9667b0ff4000000000000000000000000e8ec9189b9a8e6fff4081b02798229e9667b0ff4000000000000000000000000000000000000000000000000020279e9a77a5afc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7c0d52c0d6984b3fa98313995751521880fe89eb6850bf7438fb119881c88eb4,2021-11-28 07:36:08.000 UTC,0,true +8644,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f29c7278d460b590f8e0ed780c6266837a7e98d7000000000000000000000000f29c7278d460b590f8e0ed780c6266837a7e98d7000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8645,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dfb2546ad9b9e461abb03fe5491bad95250d0f75000000000000000000000000dfb2546ad9b9e461abb03fe5491bad95250d0f75000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8647,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001de786dc3586de4eac8627d2eaf8164dd3fc506d0000000000000000000000001de786dc3586de4eac8627d2eaf8164dd3fc506d000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8648,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e475fb57a19f7acbb16734560c2ba4de8f093b12000000000000000000000000e475fb57a19f7acbb16734560c2ba4de8f093b12000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8649,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ecfc2f7c4f7d98e27b801d78dc58a26217d7707c000000000000000000000000ecfc2f7c4f7d98e27b801d78dc58a26217d7707c000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8650,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bf506ef751596fd72c7346f078232070b253c0e0000000000000000000000005bf506ef751596fd72c7346f078232070b253c0e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8651,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b910ba7e631c642965b58308b1d29b84341c32f8000000000000000000000000b910ba7e631c642965b58308b1d29b84341c32f8000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8652,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055fb49b462a42d5af6078717c77f0ffb28859d7200000000000000000000000055fb49b462a42d5af6078717c77f0ffb28859d72000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca3811070abc940e95643bef8c47a9a108aaa768000000000000000000000000ca3811070abc940e95643bef8c47a9a108aaa768000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8654,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f6b2f2ecebf791768ec0c583d41fd3ffff17a120000000000000000000000002f6b2f2ecebf791768ec0c583d41fd3ffff17a12000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8b3bbe9c82a4e64550f30b0a100d51eff99a618000000000000000000000000e8b3bbe9c82a4e64550f30b0a100d51eff99a61800000000000000000000000000000000000000000000000000100ca6d56a7a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4530ca9327217af710f382c9209973a1e66d04d000000000000000000000000f4530ca9327217af710f382c9209973a1e66d04d000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8657,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005840379db6f88f09492cd090dc6837b09097c5160000000000000000000000005840379db6f88f09492cd090dc6837b09097c516000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000573a7938d10b9b89f01642bd459cb4650c11474b000000000000000000000000573a7938d10b9b89f01642bd459cb4650c11474b000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cb780fd3286f2d10199b61423d1c804bd2a5d2b0000000000000000000000004cb780fd3286f2d10199b61423d1c804bd2a5d2b000000000000000000000000000000000000000000000000001368c8aca8e44000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8663,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000463bb4e552cf87d88319ddb1012fac4682c61b28000000000000000000000000463bb4e552cf87d88319ddb1012fac4682c61b28000000000000000000000000000000000000000000000000001898fa413d2c3700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000076655696e3abcc91f86e6d91c7019f9bae6f014000000000000000000000000076655696e3abcc91f86e6d91c7019f9bae6f014000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b72f0a2e5269951e3bcbeb50e8e35f182043f790000000000000000000000002b72f0a2e5269951e3bcbeb50e8e35f182043f790000000000000000000000000000000000000000000000000014da53dfae255d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8667,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9fbc77427074635331abcf9e57b47dbfdc3edf2000000000000000000000000e9fbc77427074635331abcf9e57b47dbfdc3edf200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8669,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9fbc77427074635331abcf9e57b47dbfdc3edf2000000000000000000000000e9fbc77427074635331abcf9e57b47dbfdc3edf200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8670,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d99d383ff00a24a5af94b64c09570b8d8fb7aa0f000000000000000000000000d99d383ff00a24a5af94b64c09570b8d8fb7aa0f0000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8671,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9f3b9e68ead6179dedbbbc781e3ccca4f7409ad000000000000000000000000e9f3b9e68ead6179dedbbbc781e3ccca4f7409ad000000000000000000000000000000000000000000000000003c6568f12e800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005686633573ceaca844621daf102a0c5dd1b102150000000000000000000000005686633573ceaca844621daf102a0c5dd1b1021500000000000000000000000000000000000000000000000000518f6e506c1c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8673,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1c3e416c5592fdc87f538dd6d7f8f5bc4a908a2000000000000000000000000c1c3e416c5592fdc87f538dd6d7f8f5bc4a908a200000000000000000000000000000000000000000000000000aff92204a3e6ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8674,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000e3cbd67b2e89cb57fd3dc852484136ec768dd680000000000000000000000000000000000000000000000001bc16d674ec80000,,,1,true +8675,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000ad65afa08e18ae282088bbae83526d6f14554b5000000000000000000000000000000000000000000000000140e46e10013c2ab,,,1,true +8676,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a9ee69b6781c18164ee9f7c58f1763bcffc7c510000000000000000000000006a9ee69b6781c18164ee9f7c58f1763bcffc7c510000000000000000000000000000000000000000000000000dc2f6866b062a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045a5549b2baf17dcaa883e1b4f40bc89abce8a2e00000000000000000000000045a5549b2baf17dcaa883e1b4f40bc89abce8a2e000000000000000000000000000000000000000000000000005b4bab14e4329c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x275a3e27205f29d81676da4ef45bea7ea9109e9d0402e9051a937611c9b8f227,2021-12-12 06:26:21.000 UTC,0,true +8680,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6305f5b950f22b1997247017bdab763d9a5e224000000000000000000000000c6305f5b950f22b1997247017bdab763d9a5e22400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a93718595a93c81cc4e34104092eda31e43a9499000000000000000000000000a93718595a93c81cc4e34104092eda31e43a94990000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8683,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b68c9cb7d998c0959ad97d47ec7e6b0f3e93d8be000000000000000000000000b68c9cb7d998c0959ad97d47ec7e6b0f3e93d8be0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1035d8072333180191ad98d7971d9015f6e7b26000000000000000000000000c1035d8072333180191ad98d7971d9015f6e7b26000000000000000000000000000000000000000000000000002714711487800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae3d48ad47ad3a446c0205d3d0f6a94c439bd163000000000000000000000000ae3d48ad47ad3a446c0205d3d0f6a94c439bd163000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8687,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fdbfceecd0df13f8ed2311211eb08f52dea041f0000000000000000000000000fdbfceecd0df13f8ed2311211eb08f52dea041f000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcdf99014248fc287a1dd2747caa7a52035b63b2000000000000000000000000fcdf99014248fc287a1dd2747caa7a52035b63b20000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8689,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f87cc56adf0d44f8e2da7023f5403534bf2c9f80000000000000000000000007f87cc56adf0d44f8e2da7023f5403534bf2c9f8000000000000000000000000000000000000000000000000001e98843d3f8e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8691,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c02230f20dfa84e8ea2102fd1be5f20f22089bc9000000000000000000000000c02230f20dfa84e8ea2102fd1be5f20f22089bc90000000000000000000000000000000000000000000000000055c275c73d221b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8692,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000774058bea27013e38f2182fbcfa8883beb870ec8000000000000000000000000774058bea27013e38f2182fbcfa8883beb870ec8000000000000000000000000000000000000000000000000001af262f25a71b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006665fec3fa3ff6b0d318d6d9348ea0808cfae8be0000000000000000000000006665fec3fa3ff6b0d318d6d9348ea0808cfae8be000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8695,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000716e5d3550948c68ecf9966c39bda74da13c0613000000000000000000000000716e5d3550948c68ecf9966c39bda74da13c061300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8696,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000761634ae1f79ce06d658a9a08f2521c88276b898000000000000000000000000761634ae1f79ce06d658a9a08f2521c88276b898000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c75de1d876334f103f795b7b931a0dba0d627941000000000000000000000000c75de1d876334f103f795b7b931a0dba0d62794100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9be27da8deaa03fdf2a40558e5100e91f39594f000000000000000000000000c9be27da8deaa03fdf2a40558e5100e91f39594f000000000000000000000000000000000000000000000000001bc5fbb89fd37700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8699,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb2ca0d610f449c65ccdc4151200643ffd956e7e000000000000000000000000eb2ca0d610f449c65ccdc4151200643ffd956e7e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8700,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fe6cb581fef51949022a4960b74ff2c2903e77f0000000000000000000000005fe6cb581fef51949022a4960b74ff2c2903e77f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8701,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6a5965a7f8998b5b8e1febddb34d394252f5c13000000000000000000000000a6a5965a7f8998b5b8e1febddb34d394252f5c13000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022e45db423c0974de0f5f2dde836519d1a173e5f00000000000000000000000022e45db423c0974de0f5f2dde836519d1a173e5f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8703,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffb19ed04a94d3cefe20e8a89f7c13085d5e244e000000000000000000000000ffb19ed04a94d3cefe20e8a89f7c13085d5e244e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbe51818354300f2b95f224e584967819260de80000000000000000000000000cbe51818354300f2b95f224e584967819260de80000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068adeb69fe02f191f744dbc8ce53cb5f517e823600000000000000000000000068adeb69fe02f191f744dbc8ce53cb5f517e8236000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e15430ebbc70a4d32bcd8d9f1861c68a68888f60000000000000000000000002e15430ebbc70a4d32bcd8d9f1861c68a68888f600000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b804c290fc1e2d6bbd7c7099e0738d12a0b4437c000000000000000000000000b804c290fc1e2d6bbd7c7099e0738d12a0b4437c0000000000000000000000000000000000000000000000000d9ab6fa344a5bbe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8712,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bacbccda5f670437d2d5473e21d1b41f027dea0d000000000000000000000000bacbccda5f670437d2d5473e21d1b41f027dea0d00000000000000000000000000000000000000000000000000392ec52d5c152500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000495e9ac565e21f89589675d8a93133a54d7d831c000000000000000000000000495e9ac565e21f89589675d8a93133a54d7d831c000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8715,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087df47f57fa337a7deeb12e01220d0a72ef9bf3200000000000000000000000087df47f57fa337a7deeb12e01220d0a72ef9bf32000000000000000000000000000000000000000000000000004221b3706da60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8721,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7aa0e8b7a67d11ec26f6b13a70fc0e510f760bb000000000000000000000000b7aa0e8b7a67d11ec26f6b13a70fc0e510f760bb00000000000000000000000000000000000000000000000000a33fbf40f665f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8722,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4d9529df32208efa4cfc7ef2711c49546ad87b0000000000000000000000000f4d9529df32208efa4cfc7ef2711c49546ad87b0000000000000000000000000000000000000000000000000003882824f5bf77f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8723,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcb830302bc8994d2b518d29e29f53e012a10fe8000000000000000000000000fcb830302bc8994d2b518d29e29f53e012a10fe8000000000000000000000000000000000000000000000000000de5295e13950000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8724,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000434290f0f31723a16e07b705bdd0e8f5e49b6b04000000000000000000000000434290f0f31723a16e07b705bdd0e8f5e49b6b04000000000000000000000000000000000000000000000000000dbf2063d4fd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8727,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f09473bead03711eb34f3efd5e59c369cc11c3aa000000000000000000000000f09473bead03711eb34f3efd5e59c369cc11c3aa000000000000000000000000000000000000000000000000015de891f9de0d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8728,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7c51775505458cd958ae06985d44eb891d07e7a000000000000000000000000e7c51775505458cd958ae06985d44eb891d07e7a000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067d63c52806f9ee874763a3eeca4fe11ebc286be00000000000000000000000067d63c52806f9ee874763a3eeca4fe11ebc286be000000000000000000000000000000000000000000000000005754660fc9c40a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8730,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086d7c37933ab22ee4a744dcdb12ca7c6c57b593100000000000000000000000086d7c37933ab22ee4a744dcdb12ca7c6c57b593100000000000000000000000000000000000000000000000000a5fd5da26c4ddd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8731,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000964ac758e00402b2b590fc5e75cb72c4fc0ebe74000000000000000000000000964ac758e00402b2b590fc5e75cb72c4fc0ebe74000000000000000000000000000000000000000000000000005ec2d61a8591f700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8732,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000702580f7ab23fd4f9d739180b852b8ea7881a1fb000000000000000000000000702580f7ab23fd4f9d739180b852b8ea7881a1fb000000000000000000000000000000000000000000000000003784f42f8ea96a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d51c508f3e3e2e34fb35919a7fe932634b2f1b2f000000000000000000000000d51c508f3e3e2e34fb35919a7fe932634b2f1b2f000000000000000000000000000000000000000000000000009d5aa83ef6c73000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8734,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000311c13e8ccab5b3af959ad4aa95c612920f615c2000000000000000000000000311c13e8ccab5b3af959ad4aa95c612920f615c20000000000000000000000000000000000000000000000000039b46ac9c590af00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x02e05057db4eb8079b3762e7cde25832188c2bb9869c5dfde2268842aee43d46,2022-05-09 05:59:17.000 UTC,0,true +8735,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1a5161d604d7348d7f5c534517b5404a8edefe4000000000000000000000000f1a5161d604d7348d7f5c534517b5404a8edefe400000000000000000000000000000000000000000000000001602849c120640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8737,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042c3f118eae67ff35d7f81d00b15241e02a8378c00000000000000000000000042c3f118eae67ff35d7f81d00b15241e02a8378c000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ee68feb9c2e9619b57ea15c5274fb153e0927f40000000000000000000000005ee68feb9c2e9619b57ea15c5274fb153e0927f40000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081114446302eb82364ebe39b218fb8d4ea52607d00000000000000000000000081114446302eb82364ebe39b218fb8d4ea52607d0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062d2db1dc5376850241cfc3dbc0990632df277e500000000000000000000000062d2db1dc5376850241cfc3dbc0990632df277e50000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8741,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006be86b163524c2e541865547caf732ed831f30120000000000000000000000006be86b163524c2e541865547caf732ed831f30120000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053670d5c5f55355dc72a718ad6b06f1d114ca49500000000000000000000000053670d5c5f55355dc72a718ad6b06f1d114ca4950000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8744,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c83852e1290e2a573d2dc8571d51c1b26fa3f7c9000000000000000000000000c83852e1290e2a573d2dc8571d51c1b26fa3f7c90000000000000000000000000000000000000000000000000060a3dda142a9f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8746,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069f21a1f0328016ae026896957b05e27ec33db9900000000000000000000000069f21a1f0328016ae026896957b05e27ec33db9900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000febd841555eb34de9b082a9f43ae6b12e408de48000000000000000000000000febd841555eb34de9b082a9f43ae6b12e408de480000000000000000000000000000000000000000000000000004ab9bdd3ebec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8749,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009da2ee83b7eac61783c6b60c553cebcad934a4950000000000000000000000009da2ee83b7eac61783c6b60c553cebcad934a49500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8750,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e09a92b75b32f7a9faca607b15823952dcdef354000000000000000000000000e09a92b75b32f7a9faca607b15823952dcdef35400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8755,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7bd5f4d7e13b11b948f7cc90cb4f2128c31c9b2000000000000000000000000d7bd5f4d7e13b11b948f7cc90cb4f2128c31c9b2000000000000000000000000000000000000000000000000003a9ea99ecb400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8756,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae39869ed77d33f4a25aee3e47946249539f21ce000000000000000000000000ae39869ed77d33f4a25aee3e47946249539f21ce000000000000000000000000000000000000000000000000000e8fc29351fb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005150fe3c1407fe9ccc2821feb94cf7dd6ca789c80000000000000000000000005150fe3c1407fe9ccc2821feb94cf7dd6ca789c800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8760,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000682668912cb71471b87733e95a6d51af2d3b1da8000000000000000000000000682668912cb71471b87733e95a6d51af2d3b1da8000000000000000000000000000000000000000000000000005dafbf922d05cf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8767,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009634388afb4ed1aa04be2231866811b01f43a2910000000000000000000000009634388afb4ed1aa04be2231866811b01f43a2910000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000024f36b02608a5129c61f8df54dc7286f9113dee000000000000000000000000024f36b02608a5129c61f8df54dc7286f9113dee00000000000000000000000000000000000000000000000002d9b3d0462f075700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8770,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000555860b9cc8a1d1e9e48538c8c6d8b85300a77c5000000000000000000000000555860b9cc8a1d1e9e48538c8c6d8b85300a77c50000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8771,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000711a1e1cd8da2d5c4f46118c1a1373e9d2610d04000000000000000000000000711a1e1cd8da2d5c4f46118c1a1373e9d2610d04000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8eac5592228f1108fd4a488bd13d2201268cc3f000000000000000000000000a8eac5592228f1108fd4a488bd13d2201268cc3f00000000000000000000000000000000000000000000000000753d533d96800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001071a56413701b104f35fcd0a94822457e5121140000000000000000000000001071a56413701b104f35fcd0a94822457e51211400000000000000000000000000000000000000000000000003bb935379282d1500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a2d82e134fd7b79cb0445a8f5f0afab34760a530000000000000000000000009a2d82e134fd7b79cb0445a8f5f0afab34760a5300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8778,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d637b55735c538072d2da83c7bf154b46cb1ad98000000000000000000000000d637b55735c538072d2da83c7bf154b46cb1ad9800000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1b1eccb05fbe31b5bb02cbba0a6fdc3daee5f09201cbd27344a9020ea479c1fd,2022-02-21 06:33:59.000 UTC,0,true +8779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e06cdcae2113a6a14ca994fff730a6de1b7edca9000000000000000000000000e06cdcae2113a6a14ca994fff730a6de1b7edca9000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8780,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f0d3e8bcf90fc2bd9d5aba1458daf4965f85d0a0000000000000000000000008f0d3e8bcf90fc2bd9d5aba1458daf4965f85d0a0000000000000000000000000000000000000000000000000060a2fcc2e1f6cc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe2bc66479b1a42c75600c0215cb1609ef3813485ecd1053310d29ee5bcfabc40,2022-03-12 07:48:53.000 UTC,0,true +8781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f9cc0aef516e99dd66a6b75bbc719db95d05fc40000000000000000000000007f9cc0aef516e99dd66a6b75bbc719db95d05fc40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8782,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000019cbda26aba474b7367b9a71ab58f9838435c60600000000000000000000000019cbda26aba474b7367b9a71ab58f9838435c60600000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000268a743f3e052a91363dc1ca330e9e772a27bf8a000000000000000000000000268a743f3e052a91363dc1ca330e9e772a27bf8a0000000000000000000000000000000000000000000000000025d7a027526b1d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8784,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfdff69e12c0cc9dcd14188a247dfe4763d0ee56000000000000000000000000bfdff69e12c0cc9dcd14188a247dfe4763d0ee56000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000864fa05ae397ce827b1d7fc70a962b9af3c819ef000000000000000000000000864fa05ae397ce827b1d7fc70a962b9af3c819ef000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020e3dab8c6d71932077eef37da9267aeef3206ab00000000000000000000000020e3dab8c6d71932077eef37da9267aeef3206ab000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c924f2e488fea9e7e1b6243dac0097254a61140f000000000000000000000000c924f2e488fea9e7e1b6243dac0097254a61140f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8788,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091587456d06fbb36a522b7bb4887f8892a30535100000000000000000000000091587456d06fbb36a522b7bb4887f8892a305351000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b62a725a00f98955f81cd0c63f9cc0431b7c597e000000000000000000000000b62a725a00f98955f81cd0c63f9cc0431b7c597e00000000000000000000000000000000000000000000000002c2bd689af9490000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8790,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e28c5ef710db84fd95298abbbb50f07d97bc235a000000000000000000000000e28c5ef710db84fd95298abbbb50f07d97bc235a000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8791,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ba556f042776d8c590b1c6da6122511f36258e80000000000000000000000005ba556f042776d8c590b1c6da6122511f36258e8000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019f6d81ca164ab9b2b9b20a0a854b06ce425621700000000000000000000000019f6d81ca164ab9b2b9b20a0a854b06ce4256217000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8793,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000baacf9486835683a8e7ee0e528bb5117fab98671000000000000000000000000baacf9486835683a8e7ee0e528bb5117fab986710000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a728f11510ec1ec8421f3962ea5ffc936f6650d6000000000000000000000000a728f11510ec1ec8421f3962ea5ffc936f6650d600000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8795,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1db64fc6151f7985c8b9df32503a2b9a4125752000000000000000000000000a1db64fc6151f7985c8b9df32503a2b9a4125752000000000000000000000000000000000000000000000000011dd8269942589100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e50dd0bfc9c4dec6d9206be428414322dc9cabe4000000000000000000000000e50dd0bfc9c4dec6d9206be428414322dc9cabe4000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b035b9678bf874b3cb91c64bdcc9a95b4b3ffb28000000000000000000000000b035b9678bf874b3cb91c64bdcc9a95b4b3ffb28000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8798,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bbb40b4b71d5ff88199f5279df505eac4eab434c000000000000000000000000bbb40b4b71d5ff88199f5279df505eac4eab434c000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8799,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bca46727116c2fbb2284c49bba696f40749cd341000000000000000000000000bca46727116c2fbb2284c49bba696f40749cd341000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8800,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a310038314884dea1f909a13539bcef7f5a06111000000000000000000000000a310038314884dea1f909a13539bcef7f5a06111000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8801,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000031f2a75c0c79dbc7537d2b9687f74e90aa6503a000000000000000000000000031f2a75c0c79dbc7537d2b9687f74e90aa6503a00000000000000000000000000000000000000000000000000000000006d53b9500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8802,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2d755c62aa4d9493808b62d68939b1e095dfb4c000000000000000000000000d2d755c62aa4d9493808b62d68939b1e095dfb4c00000000000000000000000000000000000000000000000000201f184922d81b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8803,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000423db69b9161fb4697d002bce6934682472cf34f000000000000000000000000423db69b9161fb4697d002bce6934682472cf34f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8804,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007276fe1c8f90f47b3c5d63a63f5b28f2b346e1640000000000000000000000007276fe1c8f90f47b3c5d63a63f5b28f2b346e16400000000000000000000000000000000000000000000000000858ce2bb7fcbf400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8805,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004db1c1a03e80b340a230425f598ab0583661ad1d0000000000000000000000004db1c1a03e80b340a230425f598ab0583661ad1d000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8806,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e655016b2183dee463197f0c176eafe14bbfc304000000000000000000000000e655016b2183dee463197f0c176eafe14bbfc3040000000000000000000000000000000000000000000000000000a04e793e018000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8807,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094790546b7e618f86148da978035846d24da670200000000000000000000000094790546b7e618f86148da978035846d24da6702000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8808,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c22c8a0d3027fb01ab0248353b9616446cd40e80000000000000000000000009c22c8a0d3027fb01ab0248353b9616446cd40e8000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8809,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca04f881b6c5524465b4334c0d175ad88d49a555000000000000000000000000ca04f881b6c5524465b4334c0d175ad88d49a55500000000000000000000000000000000000000000000000000a22c59e441574200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014d2eb90a237990132cce5b398d3ce0b382d4f8700000000000000000000000014d2eb90a237990132cce5b398d3ce0b382d4f87000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8811,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f474f2ae653064a1619da919d85a9003151ab5c0000000000000000000000000f474f2ae653064a1619da919d85a9003151ab5c000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000353e21433a5d15774c1689119922b68d0db9ec66000000000000000000000000353e21433a5d15774c1689119922b68d0db9ec66000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8813,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007aad778f6de4d7fda0001ebe559103ad76e1486f0000000000000000000000007aad778f6de4d7fda0001ebe559103ad76e1486f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e98a63a88d50a88ffe83c2d553e1a8b0ece0d035000000000000000000000000e98a63a88d50a88ffe83c2d553e1a8b0ece0d035000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8815,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003878c9ba53af40037271b076411a95e86378f7ed0000000000000000000000003878c9ba53af40037271b076411a95e86378f7ed000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000370645b655fa20f247411b323cc5c7824e1193f3000000000000000000000000370645b655fa20f247411b323cc5c7824e1193f3000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012970106add28486a63ed6deef4f0076ddc50aa200000000000000000000000012970106add28486a63ed6deef4f0076ddc50aa20000000000000000000000000000000000000000000000000069a5be3cf9ec0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000286dcfcd06c5575fa64dd1eb94d2d9587196d4c0000000000000000000000000286dcfcd06c5575fa64dd1eb94d2d9587196d4c0000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c86e28d27f4a5655acf0a94fafcfec394d4fa990000000000000000000000001c86e28d27f4a5655acf0a94fafcfec394d4fa99000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8820,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006df1eaf904462ab2c27ce1290dc9819ea01f52490000000000000000000000006df1eaf904462ab2c27ce1290dc9819ea01f5249000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000126413913ef8735a58d4763613e473cd3320846a000000000000000000000000126413913ef8735a58d4763613e473cd3320846a0000000000000000000000000000000000000000000000000160991de843a70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e67911a7c234e7813f654fdb20a31deb2ad4c415000000000000000000000000e67911a7c234e7813f654fdb20a31deb2ad4c415000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027733dedd8ce55de434a80df65e161aa39d7b73500000000000000000000000027733dedd8ce55de434a80df65e161aa39d7b735000000000000000000000000000000000000000000000000015f9e40d01b840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000911769d523e8e51819525db932f8822174009777000000000000000000000000911769d523e8e51819525db932f88221740097770000000000000000000000000000000000000000000000000063a07fdcffe0cc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006646ad58d4b213f59abf859b85b0ac68c05ec1440000000000000000000000006646ad58d4b213f59abf859b85b0ac68c05ec144000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b90bd5489126d80f5aa021880e30297c35d964a0000000000000000000000006b90bd5489126d80f5aa021880e30297c35d964a000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074a6263578c5b9fd42fa7afeff1ca52d04e90e3600000000000000000000000074a6263578c5b9fd42fa7afeff1ca52d04e90e36000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000365883c5d9ae80760d8b3296d11cb33cfe53ab24000000000000000000000000365883c5d9ae80760d8b3296d11cb33cfe53ab24000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c2095fc42ef164f317a0b93835a052acf03fd3e0000000000000000000000004c2095fc42ef164f317a0b93835a052acf03fd3e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8831,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000daf0910920f4bbc5ccfb70b3e9db797959ba0674000000000000000000000000daf0910920f4bbc5ccfb70b3e9db797959ba0674000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd72ad6175868a55f4508c6973223ea7795f7121000000000000000000000000dd72ad6175868a55f4508c6973223ea7795f7121000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000f1a011fbfb9911ab2bb6bdba208e5892579c8b50000000000000000000000000f1a011fbfb9911ab2bb6bdba208e5892579c8b50000000000000000000000000000000000000000000000000000000059452fa300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044836f9fd50a63a609e88c4d225570f6592509ac00000000000000000000000044836f9fd50a63a609e88c4d225570f6592509ac0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5f5e1a2e17e680476eefff135a7f9ab87c2e9f5000000000000000000000000a5f5e1a2e17e680476eefff135a7f9ab87c2e9f50000000000000000000000000000000000000000000000000057a8d0410268f600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f164b1818c1a1ef344a15124c5dd769071460e90000000000000000000000006f164b1818c1a1ef344a15124c5dd769071460e9000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008999938863f37c05c4ebb1752ab9987aa565b3fd0000000000000000000000008999938863f37c05c4ebb1752ab9987aa565b3fd00000000000000000000000000000000000000000000000000516fb6636c529300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f1a011fbfb9911ab2bb6bdba208e5892579c8b50000000000000000000000000f1a011fbfb9911ab2bb6bdba208e5892579c8b5000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f9654f52b3ed762bc07bdd01c592a95b28d5ba40000000000000000000000003f9654f52b3ed762bc07bdd01c592a95b28d5ba4000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8840,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015d1eba25db9075c87afb1055c84e1259228566c00000000000000000000000015d1eba25db9075c87afb1055c84e1259228566c0000000000000000000000000000000000000000000000000013891ef3f7601200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000249f752c53dbf2486a57678b95f0f200d06a9913000000000000000000000000249f752c53dbf2486a57678b95f0f200d06a9913000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036d5ed41f464e19a48db0559d89eea3f8861916100000000000000000000000036d5ed41f464e19a48db0559d89eea3f88619161000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a72e92738e6a667a063d8c042a9495cb9d732b70000000000000000000000000a72e92738e6a667a063d8c042a9495cb9d732b7000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041926365e4c9ea29d6905932043c1573e4d7cc8600000000000000000000000041926365e4c9ea29d6905932043c1573e4d7cc86000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008854c59ba3416f09c87a26f7a93edc1f756574b40000000000000000000000008854c59ba3416f09c87a26f7a93edc1f756574b40000000000000000000000000000000000000000000000000058191e8324d6f400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9e2cc6ec8cba89ce3231bcc6735afc099fb7e30000000000000000000000000a9e2cc6ec8cba89ce3231bcc6735afc099fb7e30000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f8798c9d86543c8fb222660d1246e4bf83f03d40000000000000000000000006f8798c9d86543c8fb222660d1246e4bf83f03d400000000000000000000000000000000000000000000000000601779a9aecd3a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x01b97acd33224dfa3d9cc03c644d6b2e2bf9730046d7bf54fd2f5963b5056414,2022-03-12 07:57:19.000 UTC,0,true +8850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f38b00150550d4acc65f55c566fab97a7e3aa090000000000000000000000004f38b00150550d4acc65f55c566fab97a7e3aa0900000000000000000000000000000000000000000000000001579f09689b637200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030988a15f85640e1bed9a61bdb85d13fa35d11d300000000000000000000000030988a15f85640e1bed9a61bdb85d13fa35d11d3000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e4e9e3e80144c274c324597ae9cc2f29e99bd610000000000000000000000009e4e9e3e80144c274c324597ae9cc2f29e99bd61000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008be5f5b6428f9cb2d8753881d7f48507684f90510000000000000000000000008be5f5b6428f9cb2d8753881d7f48507684f905100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8855,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a13e0359ceeb8724b620a63c19c21d88ec48cc1a000000000000000000000000a13e0359ceeb8724b620a63c19c21d88ec48cc1a000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3f33164c5a61069f24dc99dc454795be210ff51000000000000000000000000e3f33164c5a61069f24dc99dc454795be210ff51000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a99223e73a879d347ef018f580ac524fcc356690000000000000000000000005a99223e73a879d347ef018f580ac524fcc35669000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8858,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000866b95fc824ba7e0419336cb92e754db15b29a0b000000000000000000000000866b95fc824ba7e0419336cb92e754db15b29a0b0000000000000000000000000000000000000000000000000009e0a2c5d8c76200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8859,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be57fc806770cc832124a18daee0db1c9fd50b37000000000000000000000000be57fc806770cc832124a18daee0db1c9fd50b37000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006af2c7083249beb46d6ced78b52deae781a6fd520000000000000000000000006af2c7083249beb46d6ced78b52deae781a6fd52000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000c344f940332d3aa76e4f20d7352aaf086480111f000000000000000000000000c344f940332d3aa76e4f20d7352aaf086480111f0000000000000000000000000000000000000000000000000000000131cf5b9c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000175099aff5a2c7ce22b2b0884cf53b1cb661525f000000000000000000000000175099aff5a2c7ce22b2b0884cf53b1cb661525f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000322403c2a3281aad788910ff8d8139fc4c790fe5000000000000000000000000322403c2a3281aad788910ff8d8139fc4c790fe5000000000000000000000000000000000000000000000000001142ca2b96b69100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8865,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b231eca44fb2002a24f9579ddaf2d7d263d1f350000000000000000000000005b231eca44fb2002a24f9579ddaf2d7d263d1f35000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8866,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010fce6f17d33dca4eb13cf2447b7dfce7588d68c00000000000000000000000010fce6f17d33dca4eb13cf2447b7dfce7588d68c000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcb0f53f0dfac2de3d050ed8136f20298611e3ee000000000000000000000000bcb0f53f0dfac2de3d050ed8136f20298611e3ee000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8868,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f78da5055cc38971f93918de4760403f9cc80e40000000000000000000000003f78da5055cc38971f93918de4760403f9cc80e4000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ea88468068108c07ccabccf7794c390998c6f8b0000000000000000000000007ea88468068108c07ccabccf7794c390998c6f8b000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000005ed6a87517914eb67cce0930fed72e61ce2d64450000000000000000000000005ed6a87517914eb67cce0930fed72e61ce2d6445000000000000000000000000000000000000000000000000000000000058159c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000196d70d55142d3510a9206501e5c818a6287abcd000000000000000000000000196d70d55142d3510a9206501e5c818a6287abcd000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1d66a314eee0e0ba234b935181c9ce0cc265c93000000000000000000000000e1d66a314eee0e0ba234b935181c9ce0cc265c93000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045fbece740f52641d32b99bd97d2765462ab437d00000000000000000000000045fbece740f52641d32b99bd97d2765462ab437d000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8874,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2489676b3acfd19deb01c01c264db83b789e6c8000000000000000000000000c2489676b3acfd19deb01c01c264db83b789e6c80000000000000000000000000000000000000000000000000059e801176e7b6700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8875,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da3d001988a48a34bdb3c940c83bd420fc187d82000000000000000000000000da3d001988a48a34bdb3c940c83bd420fc187d82000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eaadabcc0c849a514372d4717e87c0a69dd4d571000000000000000000000000eaadabcc0c849a514372d4717e87c0a69dd4d571000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000077f30de8d26c4050f7b158c93472d8900b2d8f4000000000000000000000000077f30de8d26c4050f7b158c93472d8900b2d8f4000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bea93b95f66a229b1760bb5390d7bbe99429893c000000000000000000000000bea93b95f66a229b1760bb5390d7bbe99429893c000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fccaa885bf22d3f343611f28313f900d9e1761d0000000000000000000000007fccaa885bf22d3f343611f28313f900d9e1761d000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f924e374699737ab57e42207a7c4003c09320f64000000000000000000000000f924e374699737ab57e42207a7c4003c09320f640000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8882,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092e0c901a768a4998f45eb746e37fdf75ae80d1400000000000000000000000092e0c901a768a4998f45eb746e37fdf75ae80d14000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8884,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffe48f83372f528dd649c162c28175bb5bebce9c000000000000000000000000ffe48f83372f528dd649c162c28175bb5bebce9c000000000000000000000000000000000000000000000000008526e8978f117900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c04f345d5a50fe433de3235ca88333aba11b90a7000000000000000000000000c04f345d5a50fe433de3235ca88333aba11b90a7000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8886,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fba243e2fd77d4100ca89aacc42b6968db695be2000000000000000000000000fba243e2fd77d4100ca89aacc42b6968db695be2000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf237300b8901169f8729ca0dc46a19d2a452a1b000000000000000000000000bf237300b8901169f8729ca0dc46a19d2a452a1b000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c293b5cd5b02567977497984357394a90ed0f98e000000000000000000000000c293b5cd5b02567977497984357394a90ed0f98e0000000000000000000000000000000000000000000000000002fbcb4c645d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041aacbff90f535abfbae4146a425dc27353a685c00000000000000000000000041aacbff90f535abfbae4146a425dc27353a685c000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa750efd7cd4af96172c906e30c13c535a0d706f000000000000000000000000fa750efd7cd4af96172c906e30c13c535a0d706f000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a810f3441b89d370b36d9eea0dd8c614f102b687000000000000000000000000a810f3441b89d370b36d9eea0dd8c614f102b687000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ea52f410e8374e1e97c5f200c0c2eb11bae49220000000000000000000000008ea52f410e8374e1e97c5f200c0c2eb11bae4922000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9eb8da6832be27b8ae4176f2ee91ed55a86c50d000000000000000000000000e9eb8da6832be27b8ae4176f2ee91ed55a86c50d000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8894,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a59aad96fbcaaa2c04e18c6cf63921b216171c33000000000000000000000000a59aad96fbcaaa2c04e18c6cf63921b216171c33000000000000000000000000000000000000000000000000005fc9e6cf2323ab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5079d84bbf013de8a66ad0cb776045fc62ea09d43b11d654a5cd801ef297f4a6,2022-03-12 08:04:08.000 UTC,0,true +8896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d6a6cefb6505f5c0f68391a15da873a5924a6cc0000000000000000000000005d6a6cefb6505f5c0f68391a15da873a5924a6cc00000000000000000000000000000000000000000000000001600ac3d646900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002119498db925ca740e32f2d8aca72baa05eadef00000000000000000000000002119498db925ca740e32f2d8aca72baa05eadef0000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8898,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093498bf17fa04b8d331d863edc350f596396802900000000000000000000000093498bf17fa04b8d331d863edc350f5963968029000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e12eb4fc9e44180942875aae0599c1c0739a96f0000000000000000000000007e12eb4fc9e44180942875aae0599c1c0739a96f000000000000000000000000000000000000000000000000003ccab5584f19ca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8900,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069a38f5bedf8ef24ccd1a8f7c68b88921d663ecc00000000000000000000000069a38f5bedf8ef24ccd1a8f7c68b88921d663ecc000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8901,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f69191567b0140cdfd3014218d8198fff5ae1d0f000000000000000000000000f69191567b0140cdfd3014218d8198fff5ae1d0f00000000000000000000000000000000000000000000000000ae08a99d77710000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f7c581759cf23f121af82f0415900f38ac243050000000000000000000000008f7c581759cf23f121af82f0415900f38ac243050000000000000000000000000000000000000000000000000021332e4580830200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8903,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7e1852b2fd7598c8588435d56d9f881067955eb000000000000000000000000e7e1852b2fd7598c8588435d56d9f881067955eb0000000000000000000000000000000000000000000000000003c25c0c766f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8904,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062875df71a7a09501db20e97988fe19d052babef00000000000000000000000062875df71a7a09501db20e97988fe19d052babef00000000000000000000000000000000000000000000000000ae7eaee232230000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8905,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000adbe153bda9a214d057ca9b2173130b66329e65d000000000000000000000000adbe153bda9a214d057ca9b2173130b66329e65d000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056c10dfc9b7d713be569bee473653774d6325acd00000000000000000000000056c10dfc9b7d713be569bee473653774d6325acd0000000000000000000000000000000000000000000000000039898d61bb2c2500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066dcd3279dcba7039f4dcc5a6dc5a6c7ff3dbcbf00000000000000000000000066dcd3279dcba7039f4dcc5a6dc5a6c7ff3dbcbf00000000000000000000000000000000000000000000000000601cc915706f9f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8910,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de3a05d226b96b39d1522cfe88fec8596bfde209000000000000000000000000de3a05d226b96b39d1522cfe88fec8596bfde2090000000000000000000000000000000000000000000000000119ff31e53128f300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdafbeb555e9752720f8a72778c1273efa27d97d000000000000000000000000bdafbeb555e9752720f8a72778c1273efa27d97d000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8912,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005af79a5d8f099555380d4ae7b467a6e0cf35014f0000000000000000000000005af79a5d8f099555380d4ae7b467a6e0cf35014f0000000000000000000000000000000000000000000000000060be026755a9ef00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x042bc55478901857d473d69418341216ee5597df3d845b1658b3f0ef80e224e5,2022-03-12 08:00:15.000 UTC,0,true +8913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df4bebb2e9d31d5d3372907d3d59d10ef497449e000000000000000000000000df4bebb2e9d31d5d3372907d3d59d10ef497449e000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8914,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000021dc4d87969d1888adba243240942093c80e0fd000000000000000000000000021dc4d87969d1888adba243240942093c80e0fd000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bc751bc8dcda36b88802727ad1ef0bb97216cc70000000000000000000000005bc751bc8dcda36b88802727ad1ef0bb97216cc700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df7502f3b51b488f38bfacad00a0eab5c238d4ad000000000000000000000000df7502f3b51b488f38bfacad00a0eab5c238d4ad000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000328c209ae03146f5b460f87a637968fff5c279c1000000000000000000000000328c209ae03146f5b460f87a637968fff5c279c10000000000000000000000000000000000000000000000000009e36c0f88e9c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8919,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000034ea897392ee016fadaa50569247b66c5c906b0000000000000000000000000034ea897392ee016fadaa50569247b66c5c906b000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f53159644a7939b5708cc02914553d110e7080c7000000000000000000000000f53159644a7939b5708cc02914553d110e7080c7000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8921,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b88cb83038bd20d370df898af18b2ee21e68e430000000000000000000000002b88cb83038bd20d370df898af18b2ee21e68e43000000000000000000000000000000000000000000000000009fdf42f6e4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8922,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069ea386172228de29c65ccf4d3a8792b1009d14700000000000000000000000069ea386172228de29c65ccf4d3a8792b1009d147000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048a232b662951419b0385240c27908b4e3191cf200000000000000000000000048a232b662951419b0385240c27908b4e3191cf2000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2263baf15778c87a6210c5da74af291b465c021000000000000000000000000f2263baf15778c87a6210c5da74af291b465c021000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1a6dccbfcd05baeba7dfdbda27e56a4100cf93c000000000000000000000000e1a6dccbfcd05baeba7dfdbda27e56a4100cf93c000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f071f182396c342e54c52b6d264c21c23a3218c0000000000000000000000009f071f182396c342e54c52b6d264c21c23a3218c000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc87b155e610adf3505d19f0182db2db3d8af3f1000000000000000000000000bc87b155e610adf3505d19f0182db2db3d8af3f1000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8928,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000069d2ad62ce28b648afa5f9229c15a9ace6611df000000000000000000000000069d2ad62ce28b648afa5f9229c15a9ace6611df000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8929,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069c9e86257e0c9d26639cec3fad8f2ba0a827dae00000000000000000000000069c9e86257e0c9d26639cec3fad8f2ba0a827dae00000000000000000000000000000000000000000000000000042367a912600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000799f328d9bb00045c15d68ab226c18512f67def8000000000000000000000000799f328d9bb00045c15d68ab226c18512f67def8000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000945f09790a3d310004994e23b9c0bc84629d2cf8000000000000000000000000945f09790a3d310004994e23b9c0bc84629d2cf8000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8932,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f325ff7250180548b86b17bce8e18d8aa266c850000000000000000000000007f325ff7250180548b86b17bce8e18d8aa266c85000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8933,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f09b73fb5831b05b1f09b78822034475a1773028000000000000000000000000f09b73fb5831b05b1f09b78822034475a1773028000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8934,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029c81999158c10e54f87ac4e1d30c5aed4bc28ed00000000000000000000000029c81999158c10e54f87ac4e1d30c5aed4bc28ed000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2cdf89e1988e2d2fd31e887a7917be6fde8cb7b000000000000000000000000a2cdf89e1988e2d2fd31e887a7917be6fde8cb7b000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042b7484733a843cc587c43aae0e3aac2b1b03cbb00000000000000000000000042b7484733a843cc587c43aae0e3aac2b1b03cbb000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a8fca9ea97e3d6bd81173757f9824fa2b46e8e60000000000000000000000008a8fca9ea97e3d6bd81173757f9824fa2b46e8e6000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1fc1579e285ced99a8cdb7546d6b6829f9f197e000000000000000000000000f1fc1579e285ced99a8cdb7546d6b6829f9f197e00000000000000000000000000000000000000000000000000aedfba7ece140000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f32c92f838edfe0de82e41d1619ad4b39fd8e61c000000000000000000000000f32c92f838edfe0de82e41d1619ad4b39fd8e61c000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8942,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000162231e6e9616747983113dc4952cbfc5fce440b000000000000000000000000162231e6e9616747983113dc4952cbfc5fce440b000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018e27597614fe3d251d91a3ff2386c8a24c5984600000000000000000000000018e27597614fe3d251d91a3ff2386c8a24c59846000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8944,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011620e95a173280c84f46fa965d5ceb9fbf86e6500000000000000000000000011620e95a173280c84f46fa965d5ceb9fbf86e65000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8945,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a491fc7f3e6d40a17f9c19c4b423fbe643cbe64f000000000000000000000000a491fc7f3e6d40a17f9c19c4b423fbe643cbe64f000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8946,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000105af1dcddb73a25ab4f95299766c36ba36cde06000000000000000000000000105af1dcddb73a25ab4f95299766c36ba36cde06000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8949,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5e9625abea5c2fcb6081d3e4007811c4933cc69000000000000000000000000b5e9625abea5c2fcb6081d3e4007811c4933cc69000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8950,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001279ee81560cd636eed9e97a599c765f2b3b0c900000000000000000000000001279ee81560cd636eed9e97a599c765f2b3b0c90000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8951,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb49735d72ff7747dba184fac99ac53aa441c668000000000000000000000000cb49735d72ff7747dba184fac99ac53aa441c668000000000000000000000000000000000000000000000000003d7642229d400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004eb82de8377a63821940db41ccceabf6d48336600000000000000000000000004eb82de8377a63821940db41ccceabf6d483366000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008aa49c5de68507f98ca4f3ad95dd016cf96a2ac00000000000000000000000008aa49c5de68507f98ca4f3ad95dd016cf96a2ac0000000000000000000000000000000000000000000000000032f0aba6407a1500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8955,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e27558dd3c386c6c3990c7a60ad44efba6376f1c000000000000000000000000e27558dd3c386c6c3990c7a60ad44efba6376f1c000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8957,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000400a63ed396e27b28f1eec510221085d5593e539000000000000000000000000400a63ed396e27b28f1eec510221085d5593e539000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f351bd0a80d2632b2a07d4420062aee1def17193000000000000000000000000f351bd0a80d2632b2a07d4420062aee1def17193000000000000000000000000000000000000000000000000011318133c27860a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074a51448cadd6fe66f1d73694f13fac400062bab00000000000000000000000074a51448cadd6fe66f1d73694f13fac400062bab000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8960,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080fc9e301517ef5cb59da70a9806a8613075619000000000000000000000000080fc9e301517ef5cb59da70a9806a86130756190000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7c3b3cbb9c1dc64333ce8a715472950d096c11f000000000000000000000000c7c3b3cbb9c1dc64333ce8a715472950d096c11f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2df54f12d8c18e801e4cfaed6b20ac38c7073a2000000000000000000000000a2df54f12d8c18e801e4cfaed6b20ac38c7073a2000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0e2808091ea445226d56be85aa5c8356bb6d3af000000000000000000000000e0e2808091ea445226d56be85aa5c8356bb6d3af000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8964,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b88d6d394d74c46a491d36f74f40a76dd32bbe30000000000000000000000001b88d6d394d74c46a491d36f74f40a76dd32bbe3000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f9e53485ac9bfc9d6827ee746d00b3fd5ef2caa0000000000000000000000001f9e53485ac9bfc9d6827ee746d00b3fd5ef2caa000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f158f2b5a046c2c8a7d99629f52fe0317e528ca0000000000000000000000003f158f2b5a046c2c8a7d99629f52fe0317e528ca000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8967,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060c1d1b2e4f018baf3933580642ca5364adf08c800000000000000000000000060c1d1b2e4f018baf3933580642ca5364adf08c8000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000819131ed60022fd60f411f1153c7412a473cbeb0000000000000000000000000819131ed60022fd60f411f1153c7412a473cbeb0000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f76a9cfc41ef3257bb9eba87a312eae1d94cca27000000000000000000000000f76a9cfc41ef3257bb9eba87a312eae1d94cca27000000000000000000000000000000000000000000000000000429472a10bf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8970,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043b7c3c20896476635ab7b35c73a2435de1ad68f00000000000000000000000043b7c3c20896476635ab7b35c73a2435de1ad68f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d78787c47c16bfc36ccd1461f8afb7993badf8a0000000000000000000000009d78787c47c16bfc36ccd1461f8afb7993badf8a0000000000000000000000000000000000000000000000000003a4fe877e940000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c4d43670ff357845a63c8dc62e4aee02da646bf0000000000000000000000003c4d43670ff357845a63c8dc62e4aee02da646bf000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8973,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1ded22ca713eb479bbd50c055714abcca8ca57e000000000000000000000000e1ded22ca713eb479bbd50c055714abcca8ca57e00000000000000000000000000000000000000000000000000357b931622479000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc63f4172d0127c6174a09ec3d0186131be8c1aeb66327b22726f1c0f0430407b,2022-03-13 07:30:48.000 UTC,0,true +8974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ccc6090d602f0c024a0c3331b1bb794659350450000000000000000000000005ccc6090d602f0c024a0c3331b1bb7946593504500000000000000000000000000000000000000000000000000033567f49d870000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd97107587e7dcaccf87e23e68d8101c089e2c6d000000000000000000000000dd97107587e7dcaccf87e23e68d8101c089e2c6d0000000000000000000000000000000000000000000000000160834d76dbfd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000549e2463558389f90b0f6d298d291d7f2ac7127a000000000000000000000000549e2463558389f90b0f6d298d291d7f2ac7127a00000000000000000000000000000000000000000000000000992f268b64e91d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088bdeb67570c6f33d1e938f8760d0fe37570065300000000000000000000000088bdeb67570c6f33d1e938f8760d0fe37570065300000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8978,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017183bc3e7c63eff7aed65d336142beecbb6457c00000000000000000000000017183bc3e7c63eff7aed65d336142beecbb6457c00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8979,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002c1aae9710c09b68f7c51d11a5ff994297d4b3880000000000000000000000002c1aae9710c09b68f7c51d11a5ff994297d4b38800000000000000000000000000000000000000000000000f005f88f8f8c1649800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +8982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e834defdc52a103cb34e0871555dae81e1bcd225000000000000000000000000e834defdc52a103cb34e0871555dae81e1bcd225000000000000000000000000000000000000000000000000003ded7fdd80392800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8983,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f263f99b27e37e97720b9ddaf525b565e18a89c2000000000000000000000000f263f99b27e37e97720b9ddaf525b565e18a89c2000000000000000000000000000000000000000000000000004a9b638448800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8984,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015404b45517abf78cc4b77459c4883f551f105f300000000000000000000000015404b45517abf78cc4b77459c4883f551f105f30000000000000000000000000000000000000000000000000092ea7784b5e79000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020f976206f66ef58cd27d2d11379a0666acd232300000000000000000000000020f976206f66ef58cd27d2d11379a0666acd23230000000000000000000000000000000000000000000000000082a98449da00ce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b8d47f77c537842cfe003ffd751cbb8cf8f9f540000000000000000000000003b8d47f77c537842cfe003ffd751cbb8cf8f9f54000000000000000000000000000000000000000000000000002bce3a03f88d3e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8988,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035ed001589911bf0a465a2bd9eeead1c0143dac900000000000000000000000035ed001589911bf0a465a2bd9eeead1c0143dac9000000000000000000000000000000000000000000000000000aae432e2009c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8989,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000faac26eac65ecff478dcc6f0ab9d9e414cad3bed000000000000000000000000faac26eac65ecff478dcc6f0ab9d9e414cad3bed00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098802c66883bad4e9a66f4093c7e961b4224840600000000000000000000000098802c66883bad4e9a66f4093c7e961b42248406000000000000000000000000000000000000000000000000001813b555e2f00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8991,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032099d8bbab07d71991623f31501e1882265218c00000000000000000000000032099d8bbab07d71991623f31501e1882265218c00000000000000000000000000000000000000000000000000a63312366eaed800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcca3f2d7ec89db253714cfdc857b4bc0b407e4cf740cd43bbeee91938361d0ff,2021-12-11 08:11:16.000 UTC,0,true +8993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010dbf82a8bb191bd1c082de5ef915e998aa5ccd700000000000000000000000010dbf82a8bb191bd1c082de5ef915e998aa5ccd70000000000000000000000000000000000000000000000000002eec68ffbcb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x672bae9275a17505583d1024280179b56747b1133b2ec4854ed300af053794a4,2022-02-02 13:33:59.000 UTC,0,true +8994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da7ab1cd50f3af487cc76b422a3bdd8140c03a32000000000000000000000000da7ab1cd50f3af487cc76b422a3bdd8140c03a3200000000000000000000000000000000000000000000000006ed8aeb8f2c840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2648832248012d645b182736bfa3d092eeb936a42953045e1492b7c45e17d681,2022-03-03 09:13:47.000 UTC,0,true +8995,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004522f131d03f994fe9aa354ebc9e2553deaee05c0000000000000000000000004522f131d03f994fe9aa354ebc9e2553deaee05c00000000000000000000000000000000000000000000000000a9f25e14c5c40f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9381071abc4267d5d30a605ab2dbfcde644b41f000000000000000000000000a9381071abc4267d5d30a605ab2dbfcde644b41f0000000000000000000000000000000000000000000000000158e07dcd53757b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +8998,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078ce14fefa2847cc8672d2850b72d10b1ccb849a00000000000000000000000078ce14fefa2847cc8672d2850b72d10b1ccb849a0000000000000000000000000000000000000000000000000005ac79cf919c4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9000,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000a895f950150145b5b9a646af8ce4c06edcb116cf000000000000000000000000a895f950150145b5b9a646af8ce4c06edcb116cf000000000000000000000000000000000000000000000000000000000484090b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9001,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a895f950150145b5b9a646af8ce4c06edcb116cf000000000000000000000000a895f950150145b5b9a646af8ce4c06edcb116cf000000000000000000000000000000000000000000000000003ee1348978b94000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9003,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013f692432324e050c928ac24699b2a0da6601f7100000000000000000000000013f692432324e050c928ac24699b2a0da6601f7100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c219e9887dfa58a783f9d6270b5eefcc81ba7100000000000000000000000004c219e9887dfa58a783f9d6270b5eefcc81ba710000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9006,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4f31fa1dba138aa9d1c0c40f740bda817f966ee000000000000000000000000c4f31fa1dba138aa9d1c0c40f740bda817f966ee00000000000000000000000000000000000000000000000000a5112ff8aceff900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc81b268f69c061a976a21576ff37acb462cff66576ec0a2dcc99c0221adbae5b,2022-04-16 02:22:35.000 UTC,0,true +9007,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024a13ed318a3e9e64533667178987d8db4787a9400000000000000000000000024a13ed318a3e9e64533667178987d8db4787a94000000000000000000000000000000000000000000000000002307773b11df4100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9008,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009fc6fed9dd777ff731d093491f82e6e5d9b0bea00000000000000000000000009fc6fed9dd777ff731d093491f82e6e5d9b0bea000000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9010,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000050e8e455b2c9db89a5843ed175da060c3a1f1cac000000000000000000000000000000000000000000000000ccb3d3354e1fe433,,,1,true +9011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000632659f18682013ab15da51fd7f7448237421d53000000000000000000000000632659f18682013ab15da51fd7f7448237421d5300000000000000000000000000000000000000000000000001b6c73ade6b779e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9012,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000965ace0642921168f54fc0b84d9e5c20fc2cd3f0000000000000000000000000965ace0642921168f54fc0b84d9e5c20fc2cd3f000000000000000000000000000000000000000000000000000000000001b503000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c460b612054d64df1bb417ffe78c630a85ba270b000000000000000000000000c460b612054d64df1bb417ffe78c630a85ba270b00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9018,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c460b612054d64df1bb417ffe78c630a85ba270b000000000000000000000000c460b612054d64df1bb417ffe78c630a85ba270b0000000000000000000000000000000000000000000000000024a3271e7accfe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ed3909aba279b46a2feb97d878d402a8ea5faea8000000000000000000000000ed3909aba279b46a2feb97d878d402a8ea5faea800000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ccc5cf77d794fc89a610a43e2231c427e8d498d0000000000000000000000009ccc5cf77d794fc89a610a43e2231c427e8d498d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc332d328b8854d52c18023d00b984341dba8968000000000000000000000000fc332d328b8854d52c18023d00b984341dba8968000000000000000000000000000000000000000000000000001d6910d580f2c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc332d328b8854d52c18023d00b984341dba8968000000000000000000000000fc332d328b8854d52c18023d00b984341dba89680000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e37821edeeea8f94cf90472dba3efa2c9010c4a1000000000000000000000000e37821edeeea8f94cf90472dba3efa2c9010c4a10000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6a2361cd991dd31e69c92da7ebf322bb0ce4a2f000000000000000000000000c6a2361cd991dd31e69c92da7ebf322bb0ce4a2f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e34801ea425691b512c384aa000bd3e4f7099f70000000000000000000000001e34801ea425691b512c384aa000bd3e4f7099f7000000000000000000000000000000000000000000000000001b0dc63d8a851a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031452cc486d6decb90ca5effa9868bed982b4b7d00000000000000000000000031452cc486d6decb90ca5effa9868bed982b4b7d000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f934bc0ce2607b4c3b78cf33dd8e16ead186acaf000000000000000000000000f934bc0ce2607b4c3b78cf33dd8e16ead186acaf0000000000000000000000000000000000000000000000000020ff829302b30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d96551879f9d50f1886bfe8ab3ee4d9220a9d180000000000000000000000005d96551879f9d50f1886bfe8ab3ee4d9220a9d180000000000000000000000000000000000000000000000000005691c6372770000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9031,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000420c0cbc0da2c4b85e5aaefe95a9350f217c4882000000000000000000000000420c0cbc0da2c4b85e5aaefe95a9350f217c48820000000000000000000000000000000000000000000000000007d0e36a81800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9032,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007dc4d33e3e28214751260102dc46431a7b9780d00000000000000000000000007dc4d33e3e28214751260102dc46431a7b9780d0000000000000000000000000000000000000000000000000032cb86e6eb0170000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e96114e7bc582cee09edb84af5cb544cacaea1dc000000000000000000000000e96114e7bc582cee09edb84af5cb544cacaea1dc0000000000000000000000000000000000000000000000000026d34a9441830200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9034,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007019e04f5c7a20bbc686ce071f128d85e08bb89a0000000000000000000000007019e04f5c7a20bbc686ce071f128d85e08bb89a000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000882c34e0a3405f713581b8c8c9650f3cc28df488000000000000000000000000882c34e0a3405f713581b8c8c9650f3cc28df488000000000000000000000000000000000000000000000000015fbc751e5c480000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1356ed6e8398eaea48cc66c56428fb2facc2163dbccfd70376fc050bb827ca38,2022-08-04 23:27:48.000 UTC,0,true +9037,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085dc21776b349c07c080b454e27387e32d3a2e6900000000000000000000000085dc21776b349c07c080b454e27387e32d3a2e6900000000000000000000000000000000000000000000000000adcf0cf53e470000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9038,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b033961bd425926c12f622eff02b5a1a1ef807dd000000000000000000000000b033961bd425926c12f622eff02b5a1a1ef807dd000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9039,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e72fb69d6f28bf6b9d171ea5cc4e2bcd5a406f20000000000000000000000008e72fb69d6f28bf6b9d171ea5cc4e2bcd5a406f2000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9040,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d6756e1a072c3edf08451494eba0787c61eebe60000000000000000000000002d6756e1a072c3edf08451494eba0787c61eebe600000000000000000000000000000000000000000000000000394092f7c0780300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9041,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa5a5a0a4ac902522e83eb0c00a0f8bfa0493a5a000000000000000000000000fa5a5a0a4ac902522e83eb0c00a0f8bfa0493a5a0000000000000000000000000000000000000000000000000139d78a1965dc8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9042,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de6bb34a2f8c0465bcc6a0f692b8fa59737e9994000000000000000000000000de6bb34a2f8c0465bcc6a0f692b8fa59737e999400000000000000000000000000000000000000000000000000b8a7eec4f0bb3700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9044,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042c6b48ef77d01203ba920872b6b011f1ed9717600000000000000000000000042c6b48ef77d01203ba920872b6b011f1ed971760000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9045,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056170df5f737bd4578a6785eee0ce9e008aea09e00000000000000000000000056170df5f737bd4578a6785eee0ce9e008aea09e00000000000000000000000000000000000000000000000000569757e3c965a900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9046,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000009d5d5048a937e4ac8beae2ce7cb5cae7545041ec0000000000000000000000009d5d5048a937e4ac8beae2ce7cb5cae7545041ec0000000000000000000000000000000000000000000000000000000000a7d8c000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9047,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000372fa25ea9647da526b5b001bd18361f00f2d408000000000000000000000000372fa25ea9647da526b5b001bd18361f00f2d40800000000000000000000000000000000000000000000000000894ff86091a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9048,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000885477124122b1547df1d1fae946c15bb4149b98000000000000000000000000885477124122b1547df1d1fae946c15bb4149b98000000000000000000000000000000000000000000000000005c07475d6f808300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9049,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000621351604e300f3f4990aafcc17d0bb23f98ff6e000000000000000000000000621351604e300f3f4990aafcc17d0bb23f98ff6e00000000000000000000000000000000000000000000000001608d174dd9460000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e0e76d32ecfee51bad0360245d4cb710abfa1d70000000000000000000000005e0e76d32ecfee51bad0360245d4cb710abfa1d700000000000000000000000000000000000000000000000000003903c0c7ba8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d96551879f9d50f1886bfe8ab3ee4d9220a9d180000000000000000000000005d96551879f9d50f1886bfe8ab3ee4d9220a9d1800000000000000000000000000000000000000000000000000003903c0c7ba8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9052,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000596504bec398f7a1a6542731a461ebb381bc33c8000000000000000000000000596504bec398f7a1a6542731a461ebb381bc33c800000000000000000000000000000000000000000000000000003903c0c7ba8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff54d42aead3ca357ce09cc084845151d47e76de000000000000000000000000ff54d42aead3ca357ce09cc084845151d47e76de000000000000000000000000000000000000000000000000005958f70438be9700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010fedd3a2ecc9abbde294c1d13e1f71eb71f3aad00000000000000000000000010fedd3a2ecc9abbde294c1d13e1f71eb71f3aad000000000000000000000000000000000000000000000000002b898b0971e5a700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1a0f8d5757f3ee04fa9a1c36291d64070a2a2b4c25636496d88b89418c9bb6f0,2022-06-02 23:37:00.000 UTC,0,true +9058,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f543504a1f2076fffcc5892f5511ca08e664f2c0000000000000000000000007f543504a1f2076fffcc5892f5511ca08e664f2c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dec44a6acf386368f6468461b810a5b2d60982f0000000000000000000000002dec44a6acf386368f6468461b810a5b2d60982f000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005530a2bb579402819042c8a4ea06b7020b37fee60000000000000000000000005530a2bb579402819042c8a4ea06b7020b37fee6000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9062,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f21eb9fc6843e8d8816113589d6282bab6369184000000000000000000000000f21eb9fc6843e8d8816113589d6282bab6369184000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9063,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c8af873ccf3379491750835130d1d81beecc9c30000000000000000000000003c8af873ccf3379491750835130d1d81beecc9c3000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9064,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003c8af873ccf3379491750835130d1d81beecc9c30000000000000000000000003c8af873ccf3379491750835130d1d81beecc9c3000000000000000000000000000000000000000000000001158e460913d0000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9066,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000573c78a4a1fe8e77ffd340fb5e42c8b80d6e60090000000000000000000000000000000000000000000000019cb9e11561173021,,,1,true +9067,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee3fbdfac79b7a4ce9f20ef67677a502680f137e000000000000000000000000ee3fbdfac79b7a4ce9f20ef67677a502680f137e00000000000000000000000000000000000000000000000002105d30da002ef800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9068,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e461b332fa92694b8aba65fff93d591bb0b4c840000000000000000000000008e461b332fa92694b8aba65fff93d591bb0b4c840000000000000000000000000000000000000000000000000155501839c6112900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9069,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000c80b51912c089bea4c5dc8accba11cb0e8aaf410000000000000000000000000c80b51912c089bea4c5dc8accba11cb0e8aaf410000000000000000000000000000000000000000000000082339333e0bb16d0300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9071,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f543504a1f2076fffcc5892f5511ca08e664f2c0000000000000000000000007f543504a1f2076fffcc5892f5511ca08e664f2c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000a379b8266faee951aaefecf15a484b438fe59b00000000000000000000000000a379b8266faee951aaefecf15a484b438fe59b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1bcdc1594dd5511c7cdeaf0dc149b7cfaf87cf1000000000000000000000000d1bcdc1594dd5511c7cdeaf0dc149b7cfaf87cf100000000000000000000000000000000000000000000000000c46517a3e56fa900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9077,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1ad95ed4ded15200df4220fde31c8b6b3b7a723000000000000000000000000a1ad95ed4ded15200df4220fde31c8b6b3b7a72300000000000000000000000000000000000000000000000000590c47973fcac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000a379b8266faee951aaefecf15a484b438fe59b00000000000000000000000000a379b8266faee951aaefecf15a484b438fe59b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004372de44f255a78b3a3b89a923fdca35ef4157f60000000000000000000000004372de44f255a78b3a3b89a923fdca35ef4157f60000000000000000000000000000000000000000000000000df83069ad91790b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dfc3914aafa7cbcc897bd9ec5a6d8ec6b63e9a90000000000000000000000000dfc3914aafa7cbcc897bd9ec5a6d8ec6b63e9a900000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ae1bb3c234ce4436133d4c4b6a8665257cc0acb0000000000000000000000005ae1bb3c234ce4436133d4c4b6a8665257cc0acb000000000000000000000000000000000000000000000000006673f7bf888b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9084,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009650f48230a0be8106bab9d978456da25f74189c0000000000000000000000009650f48230a0be8106bab9d978456da25f74189c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000813377240d97bb58aac5f22266a6215e53d7889c000000000000000000000000813377240d97bb58aac5f22266a6215e53d7889c000000000000000000000000000000000000000000000000000a03588723becb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6b69502b58f4ef1186a23345779b32d1b512eb5000000000000000000000000d6b69502b58f4ef1186a23345779b32d1b512eb500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddc2a3c06590b7401c41bbe7f6ff742f2101a946000000000000000000000000ddc2a3c06590b7401c41bbe7f6ff742f2101a9460000000000000000000000000000000000000000000000000008aca26a56b44a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000374cb27a8753520bb153906a0a34cc823cea3c3e000000000000000000000000374cb27a8753520bb153906a0a34cc823cea3c3e000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9091,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000374cb27a8753520bb153906a0a34cc823cea3c3e000000000000000000000000374cb27a8753520bb153906a0a34cc823cea3c3e000000000000000000000000000000000000000000000000003524343e6bd79800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8e4e00aad7a9bcf6f6376662b83bb1e6bdc5212000000000000000000000000b8e4e00aad7a9bcf6f6376662b83bb1e6bdc5212000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e33d600655f808805dd21bfd00b4f56db28f0b40000000000000000000000004e33d600655f808805dd21bfd00b4f56db28f0b4000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000004784ac6aea2d4dff992c46b560d3a94264c740000000000000000000000000004784ac6aea2d4dff992c46b560d3a94264c74000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae805c15ed60aa9cb1b0111f00a9f616b72a546d000000000000000000000000ae805c15ed60aa9cb1b0111f00a9f616b72a546d000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9096,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b31abfef6710675de9e17e053c8466ed3497757d000000000000000000000000b31abfef6710675de9e17e053c8466ed3497757d000000000000000000000000000000000000000000000000002fef9e96bc879100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d2d34366edfb727a704980330e62bd822bac0f50000000000000000000000003d2d34366edfb727a704980330e62bd822bac0f5000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9098,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f93f111beae29fd649d0dae7c26de4fcd2edbdb1000000000000000000000000f93f111beae29fd649d0dae7c26de4fcd2edbdb1000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9099,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081dce610c64f7ad9cdb23db11d3c72eb17ebddb400000000000000000000000081dce610c64f7ad9cdb23db11d3c72eb17ebddb4000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002996fe21cf925d4304ac11ef7c61481e97e739790000000000000000000000002996fe21cf925d4304ac11ef7c61481e97e73979000000000000000000000000000000000000000000000000005dc8924fd150f000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9102,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067e7246bf971318a9d4d7145ef7e9cca7a7190a100000000000000000000000067e7246bf971318a9d4d7145ef7e9cca7a7190a1000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9103,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003cd2d3e932e4e2f567544196b429a628cb9389210000000000000000000000003cd2d3e932e4e2f567544196b429a628cb93892100000000000000000000000000000000000000000000000000a76803fe0d10be00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9104,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fe07a3e5d15f3f6b7d7529253566a5341e59b140000000000000000000000001fe07a3e5d15f3f6b7d7529253566a5341e59b14000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000977093b83bc716507c7952faf8e968fb1a5f3212000000000000000000000000977093b83bc716507c7952faf8e968fb1a5f3212000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9106,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021d13cc7560792aaa19f482d1ee9797e0d06abb900000000000000000000000021d13cc7560792aaa19f482d1ee9797e0d06abb9000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a11f1b016ce50b352bff0e8502b9b8f8c83fa8de000000000000000000000000a11f1b016ce50b352bff0e8502b9b8f8c83fa8de000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9108,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ccc0a27a01d7cad1bef84bf1b8f266e0eeea273b000000000000000000000000ccc0a27a01d7cad1bef84bf1b8f266e0eeea273b000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9109,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027ead2e036bbb1d22092768adf6088de83d9773a00000000000000000000000027ead2e036bbb1d22092768adf6088de83d9773a000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9110,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a2f3ea41324fe1aa34b0ebc97df66beb5597c550000000000000000000000006a2f3ea41324fe1aa34b0ebc97df66beb5597c55000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9111,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001322743e9407421991c9e4d405f166f0c4e5430e0000000000000000000000001322743e9407421991c9e4d405f166f0c4e5430e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9112,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006870fdf5a38791bcc11177cc05d9c3164482dad40000000000000000000000006870fdf5a38791bcc11177cc05d9c3164482dad400000000000000000000000000000000000000000000000000d25b799b90faaa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9113,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000130b9676da337441df79706be0640daa7ccb1a52000000000000000000000000130b9676da337441df79706be0640daa7ccb1a5200000000000000000000000000000000000000000000000000000000009dd21100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9114,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c26f5e1ef92f0001492184c67bcb5219733671af000000000000000000000000c26f5e1ef92f0001492184c67bcb5219733671af000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9115,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6eec7c3c5763fd83631237fd9425bc8b7adad7a000000000000000000000000c6eec7c3c5763fd83631237fd9425bc8b7adad7a000000000000000000000000000000000000000000000000007a69afbb1e4b7200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9116,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6fcb29f0d8b9058882d801522f85a2b2e3ae7ad000000000000000000000000c6fcb29f0d8b9058882d801522f85a2b2e3ae7ad000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9117,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddeb3d70574d4e11330fa69999d0c5cc74b7a1be000000000000000000000000ddeb3d70574d4e11330fa69999d0c5cc74b7a1be0000000000000000000000000000000000000000000000000052e2ec0493eff000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9118,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000326600085aad2407b951bd8dc2ca004e3cb94824000000000000000000000000326600085aad2407b951bd8dc2ca004e3cb94824000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9119,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ca1111888bcd15992f4bab4fe11ed748be9db2e0000000000000000000000003ca1111888bcd15992f4bab4fe11ed748be9db2e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000549f70392f4035ed0b4467e304e65a0c5c0b80f2000000000000000000000000549f70392f4035ed0b4467e304e65a0c5c0b80f2000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed38e91fd9896c95458b7304a47110fcb4c419ea000000000000000000000000ed38e91fd9896c95458b7304a47110fcb4c419ea000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045fde6b2977e251637a2c19759a00d0f2ab7c35000000000000000000000000045fde6b2977e251637a2c19759a00d0f2ab7c350000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9b817a4a54ff7b9bf912cfe6946cd66dd709717000000000000000000000000d9b817a4a54ff7b9bf912cfe6946cd66dd709717000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9124,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a06e36648fe747dbe4fea0fd3cec9da632193a8e000000000000000000000000a06e36648fe747dbe4fea0fd3cec9da632193a8e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d85d934577c027433f4cacb53210b79f1a039470000000000000000000000003d85d934577c027433f4cacb53210b79f1a03947000000000000000000000000000000000000000000000000000b54ef82454e0600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9126,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc0834397ac2147387f71c6097f4e593b3655feb000000000000000000000000fc0834397ac2147387f71c6097f4e593b3655feb000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9127,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a56777fbae59666a2f58bb19cfe02861566c3d8f000000000000000000000000a56777fbae59666a2f58bb19cfe02861566c3d8f000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9128,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000835215ceca121e78263d2ebde6d12fae6bf49d11000000000000000000000000835215ceca121e78263d2ebde6d12fae6bf49d110000000000000000000000000000000000000000000000000002f9646cdeae0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9129,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004570b3d9feebb2f0b033ef7cbfc45d9b5399fd300000000000000000000000004570b3d9feebb2f0b033ef7cbfc45d9b5399fd3000000000000000000000000000000000000000000000000000c0c9dd2640b1300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9130,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000584313319d0bfead2a9d98a7154f5dcb5a62887f000000000000000000000000000000000000000000000001c9f78d2893e40000,,,1,true +9131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008dcff10b76083afa20679ae0203c84479df71c300000000000000000000000008dcff10b76083afa20679ae0203c84479df71c3000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed26122ff39147a40457fe1a7d9443e3dabb7063000000000000000000000000ed26122ff39147a40457fe1a7d9443e3dabb7063000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007319c9390a8e4b9434c8ebc04fce609a72ee2aa00000000000000000000000007319c9390a8e4b9434c8ebc04fce609a72ee2aa0000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f181b16663fd416dcd466591e841ca407d9c6590000000000000000000000003f181b16663fd416dcd466591e841ca407d9c659000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7ea3ffc8e17e4127969b9b05e218c830e317d9d000000000000000000000000d7ea3ffc8e17e4127969b9b05e218c830e317d9d000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e51e885186f384dd7f95f5f39a750059e84f04b2000000000000000000000000e51e885186f384dd7f95f5f39a750059e84f04b2000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9137,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012e016811f2d6244f77ea21a171230d4d787ed5b00000000000000000000000012e016811f2d6244f77ea21a171230d4d787ed5b000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9139,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008163e1014b2aa4e19712707a954c3dcef05910690000000000000000000000008163e1014b2aa4e19712707a954c3dcef0591069000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9054cb84c86fd1a262edce44df65120359cb1ce000000000000000000000000d9054cb84c86fd1a262edce44df65120359cb1ce000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9141,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b60e289b9faa929c6a3211cd9aba95f655b0b381000000000000000000000000b60e289b9faa929c6a3211cd9aba95f655b0b3810000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9142,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090558eb23d1d1183d8a18dd507179e87d66764ef00000000000000000000000090558eb23d1d1183d8a18dd507179e87d66764ef0000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e88d2e687093ce4342ecfb51441ade926320c077000000000000000000000000e88d2e687093ce4342ecfb51441ade926320c0770000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9144,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000692059c9391d9d0d2072867bdb75f4499a70261c000000000000000000000000692059c9391d9d0d2072867bdb75f4499a70261c00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9145,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b1ec19beac9c7542d0055a1527c3bb9c276ecd20000000000000000000000004b1ec19beac9c7542d0055a1527c3bb9c276ecd2000000000000000000000000000000000000000000000000007dac86834637e500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcc6d775dbd9bd34b83854896ad21b2401c4a2c0b57767601469b383be38da36c,2022-05-27 12:36:07.000 UTC,0,true +9146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000025bec8158b13394095aeb6412a5b06ca416eeb5700000000000000000000000025bec8158b13394095aeb6412a5b06ca416eeb570000000000000000000000000000000000000000000000000000000001312d0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9147,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000198286fdf097bc1178c89aee772a7c505afeffcc000000000000000000000000198286fdf097bc1178c89aee772a7c505afeffcc000000000000000000000000000000000000000000000000010fcd70f577a0d400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9e2322e585ad31fb3f126fe4621f60bb5df3c5f000000000000000000000000a9e2322e585ad31fb3f126fe4621f60bb5df3c5f00000000000000000000000000000000000000000000000000c2df8ec054cbbf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e94629793d7cd090bb863f185c29f4316eee0590000000000000000000000000e94629793d7cd090bb863f185c29f4316eee059000000000000000000000000000000000000000000000000001c5d67098290acc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x28fb8b0a43577e9bae1ab1b51f6b6d97518cf3b74396f831ec1af7e464d550de,2021-12-18 19:40:20.000 UTC,0,true +9151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065f6e3f32dca337fd8cea78ac25e0b590906b6fb00000000000000000000000065f6e3f32dca337fd8cea78ac25e0b590906b6fb0000000000000000000000000000000000000000000000000160975da9b4be7a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2e0e3680cadffc19211d6b25b77f2d0167ddb9b8472d53a96893ff44dedbbce2,2022-04-30 05:30:46.000 UTC,0,true +9153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007aa3c6a33ec4bbfc6319e3c98333a018efdb1e680000000000000000000000007aa3c6a33ec4bbfc6319e3c98333a018efdb1e680000000000000000000000000000000000000000000000000152b4421ba4783f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9157,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfa3a0e1d36f51e50d2d8e1318506f52c1a136e3000000000000000000000000bfa3a0e1d36f51e50d2d8e1318506f52c1a136e3000000000000000000000000000000000000000000000000009e0459c803abbe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4f96a548f847ca2c97aa7b801d683b92353fce9000000000000000000000000f4f96a548f847ca2c97aa7b801d683b92353fce900000000000000000000000000000000000000000000000000088cb0ede33ac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce11f7d8a72536aebfd5a7b35ad90cc9d4e31bf8000000000000000000000000ce11f7d8a72536aebfd5a7b35ad90cc9d4e31bf8000000000000000000000000000000000000000000000000015d77956cd8d10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9164,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008376b16bb899cb80e07fe758a7a04dd6ed0b6e580000000000000000000000008376b16bb899cb80e07fe758a7a04dd6ed0b6e580000000000000000000000000000000000000000000000000060fa99e35b5cb400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9165,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009dd8ef100e98f980bd6d79374b9b4c10c8dc52840000000000000000000000009dd8ef100e98f980bd6d79374b9b4c10c8dc5284000000000000000000000000000000000000000000000000004c6e7a7c9214e800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9b98fc6810dc95954e3f9e951118b2f0fc4cf4d000000000000000000000000c9b98fc6810dc95954e3f9e951118b2f0fc4cf4d0000000000000000000000000000000000000000000000000774c9670cf3080000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe73825d2a32056928761d14071907dda8e1e3ae27fdc24a7af9ca36b96abe442,2022-02-03 12:34:24.000 UTC,0,true +9167,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028a4f1c13fc3af4b4ac9ce8dac5eb7de9dd35ca100000000000000000000000028a4f1c13fc3af4b4ac9ce8dac5eb7de9dd35ca1000000000000000000000000000000000000000000000000019b66a1e1470efb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x858b58079605f577b99d9c3875f7ec111d60bb196bd7e48114368fea0fa8595d,2022-02-19 18:39:08.000 UTC,0,true +9170,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007764afa522fcf3f2f9c681d8b987a6b87ba22e790000000000000000000000007764afa522fcf3f2f9c681d8b987a6b87ba22e7900000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c2930356784c160a667c5673b2ef1996b9d69570000000000000000000000005c2930356784c160a667c5673b2ef1996b9d6957000000000000000000000000000000000000000000000000001b2d5f27f999c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9172,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4d6cbe3e704f5f8d18d3b3125b45a4cf82bb5a6000000000000000000000000c4d6cbe3e704f5f8d18d3b3125b45a4cf82bb5a600000000000000000000000000000000000000000000000000f09609c014860000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ed43339d2c883b40519ec49c82b94897db7b1e10000000000000000000000001ed43339d2c883b40519ec49c82b94897db7b1e10000000000000000000000000000000000000000000000000051b660cdd5800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e1173b4410ea8142690d2be8fcf4022ba442a300000000000000000000000001e1173b4410ea8142690d2be8fcf4022ba442a3000000000000000000000000000000000000000000000000001597d1ac0b35f1100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2c80f47ec56c231c484b87a7343ff218072651d9a24eb6c6961f7dd77715276b,2021-12-20 02:27:31.000 UTC,0,true +9177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6ce84fb35db1cd9e17016abef2b06f7630f97b2000000000000000000000000e6ce84fb35db1cd9e17016abef2b06f7630f97b2000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095538e1ab67caaf337e5048c097390af8119f74300000000000000000000000095538e1ab67caaf337e5048c097390af8119f743000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061eaa93248e9b4c317058d223ad59a4b5ae050e700000000000000000000000061eaa93248e9b4c317058d223ad59a4b5ae050e7000000000000000000000000000000000000000000000000000cca2e5131000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffe8b3425cc5c5c5e425ad5565b334f7074778a7000000000000000000000000ffe8b3425cc5c5c5e425ad5565b334f7074778a7000000000000000000000000000000000000000000000000000cca2e5131000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000410d7f8d3d48d7f596f51c89f30ac2be06f2c8a0000000000000000000000000410d7f8d3d48d7f596f51c89f30ac2be06f2c8a0000000000000000000000000000000000000000000000000000cca2e5131000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aec42dae1d9550d83fe147fcb33b138a8084f0bd000000000000000000000000aec42dae1d9550d83fe147fcb33b138a8084f0bd000000000000000000000000000000000000000000000000000cca2e5131000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f708191c907fdb52f4359b169429ec03321036a4000000000000000000000000f708191c907fdb52f4359b169429ec03321036a4000000000000000000000000000000000000000000000000007857bb56be5e8f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9187,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011d89a9b799c54aa3add4af585c929ad22b1f90600000000000000000000000011d89a9b799c54aa3add4af585c929ad22b1f90600000000000000000000000000000000000000000000000000190ca1ad26420000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9188,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027bde5a4806188c84d6d6cbdce01f23cf5d492ac00000000000000000000000027bde5a4806188c84d6d6cbdce01f23cf5d492ac000000000000000000000000000000000000000000000000001bcfeb1a05320000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9189,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c27a8c3090cc5daa057f71cfef75b68ef9d75cfe000000000000000000000000c27a8c3090cc5daa057f71cfef75b68ef9d75cfe00000000000000000000000000000000000000000000000000002a104b02463500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9190,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c27a8c3090cc5daa057f71cfef75b68ef9d75cfe000000000000000000000000c27a8c3090cc5daa057f71cfef75b68ef9d75cfe00000000000000000000000000000000000000000000000000002a104b02463500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9195,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008efe405ed383ca3cdc4d71905f2891caec7f78520000000000000000000000008efe405ed383ca3cdc4d71905f2891caec7f78520000000000000000000000000000000000000000000000000020e4b6da66d86b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9196,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006702db7613fa734d9d59e3ae756c41236ac87a440000000000000000000000006702db7613fa734d9d59e3ae756c41236ac87a440000000000000000000000000000000000000000000000000060f333a3c3c57a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9198,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f603173b7f845e8c05a5c325ecb2bdbe1a1db6c0000000000000000000000009f603173b7f845e8c05a5c325ecb2bdbe1a1db6c00000000000000000000000000000000000000000000000000053b8deab29b8b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b02000c80e381fe5a55b543cdf6abc7aeb44662f000000000000000000000000b02000c80e381fe5a55b543cdf6abc7aeb44662f00000000000000000000000000000000000000000000000000db43a93501972e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9200,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000583e4f6400ca8b7dbb0d9912a6627f80065287eb000000000000000000000000583e4f6400ca8b7dbb0d9912a6627f80065287eb0000000000000000000000000000000000000000000000000035a55eb81bc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054776f34b7d8f92671884a33dba19aa356580a6700000000000000000000000054776f34b7d8f92671884a33dba19aa356580a67000000000000000000000000000000000000000000000000005593560798bfcf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9205,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000020e4c5a2e44250b251e5018ab08e01a8a0990ca100000000000000000000000020e4c5a2e44250b251e5018ab08e01a8a0990ca10000000000000000000000000000000000000000000000000000000002fc1c4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000006ff5c188b977bbfe299244b5c8adab10db3df9360000000000000000000000006ff5c188b977bbfe299244b5c8adab10db3df9360000000000000000000000000000000000000000000000000000000002fb407100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe254efa26aebfd48693e214f30fca97f9ff91b8000000000000000000000000fe254efa26aebfd48693e214f30fca97f9ff91b80000000000000000000000000000000000000000000000000027de1e0462d5ea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000505f6d43864de1d3e10a3615f68f67a39714e5b8000000000000000000000000505f6d43864de1d3e10a3615f68f67a39714e5b80000000000000000000000000000000000000000000000000000000002faf65400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000fd9272d6fd33507356a86f62c0070c1d5652f4df000000000000000000000000fd9272d6fd33507356a86f62c0070c1d5652f4df0000000000000000000000000000000000000000000000000000000002fab22700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9211,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dcedc4a80f03ba8ff3a7fc545fc9f4461b5788be000000000000000000000000dcedc4a80f03ba8ff3a7fc545fc9f4461b5788be00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9212,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc6e9f322c5e694139228cfbfef35b9bfe846e84000000000000000000000000cc6e9f322c5e694139228cfbfef35b9bfe846e84000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9214,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1e33539ac9169415dac3bd2b2a8f63efb602479000000000000000000000000d1e33539ac9169415dac3bd2b2a8f63efb60247900000000000000000000000000000000000000000000000000044bd14142fd8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b34bd1d3ce820b56ab9adc2ebc81b819080a6403000000000000000000000000b34bd1d3ce820b56ab9adc2ebc81b819080a6403000000000000000000000000000000000000000000000000000504d56923008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9217,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e54c2e783e8fde040096404e67688d5744596b3a000000000000000000000000e54c2e783e8fde040096404e67688d5744596b3a00000000000000000000000000000000000000000000000000921c83f1284f0600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000114b88f671c2fcb4b5457cbedf8a1da5a11f9611000000000000000000000000114b88f671c2fcb4b5457cbedf8a1da5a11f961100000000000000000000000000000000000000000000000000962f6229d07a4500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000006539028b70a88f11b853f0b08aa8740ded60c1080000000000000000000000006539028b70a88f11b853f0b08aa8740ded60c108000000000000000000000000000000000000000000000000000000002faf080000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071c04e28317150e78903047407d5253edc15819c00000000000000000000000071c04e28317150e78903047407d5253edc15819c00000000000000000000000000000000000000000000000000672366cf64cdac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9223,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dced0b4ef8c9e236307726c8d18496009b8693d0000000000000000000000000dced0b4ef8c9e236307726c8d18496009b8693d000000000000000000000000000000000000000000000000000254d59e672b70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f09f00cb348571d0f9f03ca1e1efa77f25b3ba43000000000000000000000000f09f00cb348571d0f9f03ca1e1efa77f25b3ba4300000000000000000000000000000000000000000000000003ee63bcd23a8e5c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9229,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044d0b1b261d980fbaedc869d909bc59a9ca1342700000000000000000000000044d0b1b261d980fbaedc869d909bc59a9ca1342700000000000000000000000000000000000000000000000000080cb955bba4ed00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9230,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a23469cf23dc27054610c2b12bbe4d86abeffea0000000000000000000000002a23469cf23dc27054610c2b12bbe4d86abeffea000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9231,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034f4f78e412c6ab52a4c1f58e257f21547584ca500000000000000000000000034f4f78e412c6ab52a4c1f58e257f21547584ca50000000000000000000000000000000000000000000000000022548ecd850d4900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a007b5d85f67a4d882927ef2ca992735a21d5028000000000000000000000000a007b5d85f67a4d882927ef2ca992735a21d50280000000000000000000000000000000000000000000000000060b9ce4961130200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2ce949ccd67d40b5a62a63f2fc3ffcdd2708537a55bd58ed6bbe77c370f06f0a,2022-04-20 10:40:09.000 UTC,0,true +9236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d4e6ac859e207036f0bd1f891a7661122f871980000000000000000000000007d4e6ac859e207036f0bd1f891a7661122f87198000000000000000000000000000000000000000000000000015a4c3ae94033c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf4701ca4a43d0028c46b67c92ac436ec290e33e000000000000000000000000cf4701ca4a43d0028c46b67c92ac436ec290e33e0000000000000000000000000000000000000000000000000098bb42ad93b0a100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9cb3aa3f3fff85918904fa341db511866f9f4fe000000000000000000000000f9cb3aa3f3fff85918904fa341db511866f9f4fe000000000000000000000000000000000000000000000000000665172898800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cb4bb6da78577e18b183f5ec93995b3e42fe4c80000000000000000000000002cb4bb6da78577e18b183f5ec93995b3e42fe4c8000000000000000000000000000000000000000000000000000d0591bf1d3e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9241,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e4230ceea610111f3bd7925aa27dd1de1bfe2a80000000000000000000000002e4230ceea610111f3bd7925aa27dd1de1bfe2a8000000000000000000000000000000000000000000000000001a9def5bd2195700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9242,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ea6838036e80f29f8e06c07e2bd225aa324e9560000000000000000000000005ea6838036e80f29f8e06c07e2bd225aa324e9560000000000000000000000000000000000000000000000000089a62cc5859e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9243,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fd053df2901ec08938aa235e2c48fc3f2a751210000000000000000000000002fd053df2901ec08938aa235e2c48fc3f2a75121000000000000000000000000000000000000000000000000002d3eeba754dfe100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002abcacef500c0a228450a0c605c5fce842ec32890000000000000000000000002abcacef500c0a228450a0c605c5fce842ec3289000000000000000000000000000000000000000000000000000b3810b171c93200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9245,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9dd44ed03ca24ac14f193d3ceb43c89dac7cf9c000000000000000000000000a9dd44ed03ca24ac14f193d3ceb43c89dac7cf9c0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048e5bc4d87bf5878ed75c0755cc6385389752f9200000000000000000000000048e5bc4d87bf5878ed75c0755cc6385389752f92000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9247,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052727488692711bf76b8114b28765733341d99b500000000000000000000000052727488692711bf76b8114b28765733341d99b50000000000000000000000000000000000000000000000000080e71cd4aa600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003fe87af9c27243ab2e70f55daacd990ea4f971280000000000000000000000003fe87af9c27243ab2e70f55daacd990ea4f9712800000000000000000000000000000000000000000000000000197f9c1d453a7200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9249,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff54b8ff7bd8f58295055606b59abdf3ac2eb27a000000000000000000000000ff54b8ff7bd8f58295055606b59abdf3ac2eb27a00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080439db68611029d6e8a46f49b7747242fac203900000000000000000000000080439db68611029d6e8a46f49b7747242fac203900000000000000000000000000000000000000000000000000611298a3f2d57d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd9746d5bd872cccb178099553dccfb9c93f5b79000000000000000000000000cd9746d5bd872cccb178099553dccfb9c93f5b790000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021f14394d1eb6cf83743a1cfb78f1fb1049e7d6c00000000000000000000000021f14394d1eb6cf83743a1cfb78f1fb1049e7d6c000000000000000000000000000000000000000000000000000d726db46be90e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9257,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000599c5c2df0b8c398d151ac2a13ae576bbcecb671000000000000000000000000599c5c2df0b8c398d151ac2a13ae576bbcecb671000000000000000000000000000000000000000000000000001f06e3e2f66cbc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9258,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000042ba2a84c1440290d9d66bea78248db81c160a6400000000000000000000000042ba2a84c1440290d9d66bea78248db81c160a64000000000000000000000000000000000000000000000000e70baa9f4b7f3cc400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008dc804d15747266979f6a1929fb2446301cee87b0000000000000000000000008dc804d15747266979f6a1929fb2446301cee87b0000000000000000000000000000000000000000000000000006c00a3912c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9262,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004285286356a91735d56bf3d072e49b72be370d270000000000000000000000004285286356a91735d56bf3d072e49b72be370d2700000000000000000000000000000000000000000000000056ff03f7d19c214800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xe0f8974f6533fd34f8a403ebf1f027726e411a95404c22b513f38c36745b1660,2021-12-17 05:34:09.000 UTC,0,true +9263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000a87df5f4ff03ac496988b87e25f025415118324c000000000000000000000000a87df5f4ff03ac496988b87e25f025415118324c0000000000000000000000000000000000000000000000000785a4bee73b569b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x1745c8a044007993744768851862593b2e7306086a3a1d99a89404358505c66e,2022-05-28 06:33:45.000 UTC,0,true +9264,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047c5402a052957c9f0f126d956b2bccfb2a33a8400000000000000000000000047c5402a052957c9f0f126d956b2bccfb2a33a84000000000000000000000000000000000000000000000000000dcf6a5b91bfc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9265,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee9dd8df1e32a3299796fd133b0a19fd27d5a78d000000000000000000000000ee9dd8df1e32a3299796fd133b0a19fd27d5a78d0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9268,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000459dabca5ada6670cbc4da49593f8abb1bd849ba0000000000000000000000000000000000000000000000003761758e90ac8000,,,1,true +9271,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf6380c18387dfacbb2a5a6d5c5064c05ceb707d000000000000000000000000bf6380c18387dfacbb2a5a6d5c5064c05ceb707d00000000000000000000000000000000000000000000000000560ec7e179493600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001b3eb2d3e6eccb1b276bf9b3b35ce6f970652b000000000000000000000000001b3eb2d3e6eccb1b276bf9b3b35ce6f970652b000000000000000000000000000000000000000000000000000648924d793154d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034fc0c81594d49caa2da7f218d4232a67fe9f8cd00000000000000000000000034fc0c81594d49caa2da7f218d4232a67fe9f8cd0000000000000000000000000000000000000000000000000032c0e63eb172a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008d0b5f85c1517c94742ceb2b56b36fbb63717d400000000000000000000000008d0b5f85c1517c94742ceb2b56b36fbb63717d400000000000000000000000000000000000000000000000000173b7b514ea77c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca47aaea6120929ce02ada914a46165481ec270f000000000000000000000000ca47aaea6120929ce02ada914a46165481ec270f000000000000000000000000000000000000000000000000001a4747e9aacbb700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7d18ca327701c4ebffc8d7df123fa03eecb65b2000000000000000000000000f7d18ca327701c4ebffc8d7df123fa03eecb65b2000000000000000000000000000000000000000000000000014a236bedf9fb2b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9278,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000196bd4b3c76dec0f12bae6c97c86745880f330dd000000000000000000000000196bd4b3c76dec0f12bae6c97c86745880f330dd000000000000000000000000000000000000000000000000006a8c9930ca629a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d528c1d6e3b5d544f161b5670183da6398e4ea83000000000000000000000000d528c1d6e3b5d544f161b5670183da6398e4ea830000000000000000000000000000000000000000000000000013c9abf30b4d3100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xdfe26960e002b57af9221dd365396a99900f02ef3e898d8c60c4a318eb5f1f0a,2022-03-16 11:26:15.000 UTC,0,true +9280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfa11ee4870d08acd8530056a738e4fec094bb01000000000000000000000000bfa11ee4870d08acd8530056a738e4fec094bb01000000000000000000000000000000000000000000000000001f8f206ee6b05700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006eaab50da15fda48238a463012241b91b92fda140000000000000000000000006eaab50da15fda48238a463012241b91b92fda140000000000000000000000000000000000000000000000000013c285ed92ae7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b54f3fb9731b3486136ed35d2786672793eac37b000000000000000000000000b54f3fb9731b3486136ed35d2786672793eac37b0000000000000000000000000000000000000000000000000023756f5a033f6f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f457c86f33ed9072055e549b0573dd4eec99c600000000000000000000000009f457c86f33ed9072055e549b0573dd4eec99c6000000000000000000000000000000000000000000000000000283161f22cb56900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5e527358bc01b64be29549d446a75dc73051329fb159e4569c589ec10a8e1e48,2022-05-18 14:59:01.000 UTC,0,true +9284,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013c65f9acdf88140bc900e848f383462db39144b00000000000000000000000013c65f9acdf88140bc900e848f383462db39144b0000000000000000000000000000000000000000000000000009f295cd5f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9285,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f46d8d3da0ad193c3830d0c4674d836453c1f730000000000000000000000000f46d8d3da0ad193c3830d0c4674d836453c1f730000000000000000000000000000000000000000000000000000b54452c383c7700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000555d164196c81b8eb43b8222ae54c3d2edf432b5000000000000000000000000555d164196c81b8eb43b8222ae54c3d2edf432b5000000000000000000000000000000000000000000000000002c7648b123bcca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9287,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c3f8214027a3bd2b9f2a3c0b25d6dff3b524be70000000000000000000000004c3f8214027a3bd2b9f2a3c0b25d6dff3b524be700000000000000000000000000000000000000000000000000858ab8ac2a973d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9288,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000511fd147204c6d0ca4559eb6d87c1fe4bd1fa006000000000000000000000000511fd147204c6d0ca4559eb6d87c1fe4bd1fa0060000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9293,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001877a64a37778e58ac2646107ece72a24d07021d0000000000000000000000001877a64a37778e58ac2646107ece72a24d07021d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9295,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be0f0f1077e5f5ed5e9b1dac16b6873163889381000000000000000000000000be0f0f1077e5f5ed5e9b1dac16b687316388938100000000000000000000000000000000000000000000000000215c7330bae20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5d8d3d298cb3a3592f301c75c0a1063535216a71023dcd0b71957e977f367d13,2022-01-09 08:58:25.000 UTC,0,true +9298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002478c895d589c86f8a3b4166bf50532250449c470000000000000000000000002478c895d589c86f8a3b4166bf50532250449c4700000000000000000000000000000000000000000000000000994ac868457a6200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9300,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1f0b017a8a1cf913056bd813c3e1958045feca4000000000000000000000000b1f0b017a8a1cf913056bd813c3e1958045feca400000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a068f207215241f406d01c5b0f767ead62f28f10000000000000000000000002a068f207215241f406d01c5b0f767ead62f28f10000000000000000000000000000000000000000000000000093f87c9f9bd07500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc2e5af446d8b40cd61aecac17e07df8510ae753fd548ea2ea686ebdafd59c58e,2022-05-07 02:43:56.000 UTC,0,true +9302,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b25e559bd09e91f3b28f787c17530b2da5d2b5fe000000000000000000000000b25e559bd09e91f3b28f787c17530b2da5d2b5fe00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b25e559bd09e91f3b28f787c17530b2da5d2b5fe000000000000000000000000b25e559bd09e91f3b28f787c17530b2da5d2b5fe0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f09473bead03711eb34f3efd5e59c369cc11c3aa000000000000000000000000f09473bead03711eb34f3efd5e59c369cc11c3aa00000000000000000000000000000000000000000000000002c0a5566257e60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9306,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e18c444e82ddac4046a55355d97241ec59c7184c000000000000000000000000e18c444e82ddac4046a55355d97241ec59c7184c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9308,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be88f94781de8d77f0af8fb312eae9839e3a6837000000000000000000000000be88f94781de8d77f0af8fb312eae9839e3a6837000000000000000000000000000000000000000000000000015f46284133f30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9310,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ae15032ef0fd26cd64379d1320cd480641c1de9400000000000000000000000000000000000000000000000635963db041b4e000,,,1,true +9311,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037f9349dfb6c8875e40421eb32be9fc1e20f2e4600000000000000000000000037f9349dfb6c8875e40421eb32be9fc1e20f2e4600000000000000000000000000000000000000000000000000178a2ba80d0f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9316,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd2dc5fb8b6222d9f743b3eeec059790c07ca2a4000000000000000000000000bd2dc5fb8b6222d9f743b3eeec059790c07ca2a4000000000000000000000000000000000000000000000000001c3e3054eb723500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0c09d91aa30e491e1a3a20c6fd35838257e2648000000000000000000000000f0c09d91aa30e491e1a3a20c6fd35838257e26480000000000000000000000000000000000000000000000000019519394a8c3ea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a06716d67727dfd6ab1d2ea59be872a9164c17f0000000000000000000000006a06716d67727dfd6ab1d2ea59be872a9164c17f00000000000000000000000000000000000000000000000002b5a9c2fa34d2c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9320,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006a06716d67727dfd6ab1d2ea59be872a9164c17f0000000000000000000000006a06716d67727dfd6ab1d2ea59be872a9164c17f0000000000000000000000000000000000000000000000360af9ae23bb59135800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000655790887ba1125627a35b1402121f85619c4ce9000000000000000000000000655790887ba1125627a35b1402121f85619c4ce90000000000000000000000000000000000000000000000000032e69d7292a58000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9324,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af25f79ffd2fc428c80392f0796ec9c3b2e37fac000000000000000000000000af25f79ffd2fc428c80392f0796ec9c3b2e37fac000000000000000000000000000000000000000000000000036ae123beeec7bb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2573bdff57c0c2aee2eacfe6e8bc1e4d894f5b454ef998458289c88433ce739d,2022-05-07 04:47:34.000 UTC,0,true +9325,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fa7d6b46a2e88ba99c7b3aa150916eedd3401b90000000000000000000000002fa7d6b46a2e88ba99c7b3aa150916eedd3401b9000000000000000000000000000000000000000000000000001e2ad1d57b627500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9332,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003224a28d565ccd730e815affd83772ece93e1760000000000000000000000000000000000000000000000069bb18b4790727b3e4,,,1,true +9334,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002996fe21cf925d4304ac11ef7c61481e97e739790000000000000000000000002996fe21cf925d4304ac11ef7c61481e97e7397900000000000000000000000000000000000000000000000000b4cb58a4efe73900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9335,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000067e056e707834cde7635023da431ba5eb3dff28000000000000000000000000067e056e707834cde7635023da431ba5eb3dff280000000000000000000000000000000000000000000000000153f909e7ca181b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9336,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9686237455fd803f1fafecd58b194569462dc3e000000000000000000000000e9686237455fd803f1fafecd58b194569462dc3e0000000000000000000000000000000000000000000000001796ee934707dd6500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9338,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f6b34da0a9272d9e178345cdc9cdffcaf22e0c50000000000000000000000002f6b34da0a9272d9e178345cdc9cdffcaf22e0c5000000000000000000000000000000000000000000000000001696d36a3aebad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ebd026b41b789b7d6085e42fee4fef5f566bc51e000000000000000000000000ebd026b41b789b7d6085e42fee4fef5f566bc51e0000000000000000000000000000000000000000000000000000169f544d2ca200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000353814d9e14c5b225c53d2405a88b54926a52f19000000000000000000000000353814d9e14c5b225c53d2405a88b54926a52f190000000000000000000000000000000000000000000000000c20b280db71303d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9342,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004993c856bf66dc5fe26f2760b6eb5795d4d1c1b20000000000000000000000004993c856bf66dc5fe26f2760b6eb5795d4d1c1b200000000000000000000000000000000000000000000000000861251576f90d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000837e285fd01be3720b8d39d685721372da434505000000000000000000000000837e285fd01be3720b8d39d685721372da434505000000000000000000000000000000000000000000000000000665172898800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a251df99a88a20a93876205fb7f5faf2e85a4810000000000000000000000000a251df99a88a20a93876205fb7f5faf2e85a481000000000000000000000000000000000000000000000000003c7ad7f46d4b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9347,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004710bd5bf91c3e56be0f8f60a4f70b1eb8fb0a7c0000000000000000000000004710bd5bf91c3e56be0f8f60a4f70b1eb8fb0a7c0000000000000000000000000000000000000000000000000002e78c1604f96300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057f257e58b1831e4e57815026e889203c4338c2200000000000000000000000057f257e58b1831e4e57815026e889203c4338c22000000000000000000000000000000000000000000000000005fec5b60ef800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000137bc42fb993998427f77ea9fa00428b15eb6e9c000000000000000000000000137bc42fb993998427f77ea9fa00428b15eb6e9c000000000000000000000000000000000000000000000000000df91a9fb2d24a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fdc1fdaefc803081705b6828be4dabe657a38b63000000000000000000000000fdc1fdaefc803081705b6828be4dabe657a38b63000000000000000000000000000000000000000000000000000665172898800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9354,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed3657715825bb97462f54a4e9954c0b567a527c000000000000000000000000ed3657715825bb97462f54a4e9954c0b567a527c00000000000000000000000000000000000000000000000000119ecc9f07cd0b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9356,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021efeb91568e267861805964a49b52de13b3214300000000000000000000000021efeb91568e267861805964a49b52de13b32143000000000000000000000000000000000000000000000000000f07fe7fab2c6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9358,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002720c59ec77de3c95bc96f7331094e6d2c424d540000000000000000000000002720c59ec77de3c95bc96f7331094e6d2c424d54000000000000000000000000000000000000000000000000001b27692b42438000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9359,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef3c98e82e07e20b727320c8007cad35cdfcae82000000000000000000000000ef3c98e82e07e20b727320c8007cad35cdfcae820000000000000000000000000000000000000000000000000022ff2c2c5705a000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf5271dfce67df0c4ab7508990a396dac9260fb7000000000000000000000000cf5271dfce67df0c4ab7508990a396dac9260fb70000000000000000000000000000000000000000000000000010cfd7f1d93b6a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be4619bfec05b3f08626e371f683c966fb20c03e000000000000000000000000be4619bfec05b3f08626e371f683c966fb20c03e00000000000000000000000000000000000000000000000000408089599f349100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9366,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000090f0c594f6a091adf6e8a2d5f542c393dda2bcc000000000000000000000000090f0c594f6a091adf6e8a2d5f542c393dda2bcc000000000000000000000000000000000000000000000000002e2c01e24d5b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092e8eb0cc8cb7aa6c315deb3d6901b17e58d063b00000000000000000000000092e8eb0cc8cb7aa6c315deb3d6901b17e58d063b000000000000000000000000000000000000000000000000002b749ddf128ade00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012152e86425e2177951468219474b9ba6b7af02b00000000000000000000000012152e86425e2177951468219474b9ba6b7af02b0000000000000000000000000000000000000000000000000089475dec56c50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f41e7b786ba3dcc794a1798e4b940f83b828b1b0000000000000000000000004f41e7b786ba3dcc794a1798e4b940f83b828b1b00000000000000000000000000000000000000000000000000f234409b70023b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9371,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008be1c270218a2468f720b8d00a7de43eadbc29a00000000000000000000000008be1c270218a2468f720b8d00a7de43eadbc29a000000000000000000000000000000000000000000000000015e99e17963bb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000201dc733562b29eb35f358f401b8cff97297d340000000000000000000000000201dc733562b29eb35f358f401b8cff97297d34000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9373,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab6e6ef4d98a59c76769f7ab4e30bd3895e96005000000000000000000000000ab6e6ef4d98a59c76769f7ab4e30bd3895e9600500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005c49f81bdabbfc584ed69a448df43506a50079000000000000000000000000005c49f81bdabbfc584ed69a448df43506a50079000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9375,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003645219d84c202e86e5a0652d198ab176bd1b18b0000000000000000000000003645219d84c202e86e5a0652d198ab176bd1b18b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084285466b55d6f377e32005bd26848c85cb0020600000000000000000000000084285466b55d6f377e32005bd26848c85cb0020600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9378,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b3c8597032cce4fc2af68cc48783455c2fd7a5c0000000000000000000000000b3c8597032cce4fc2af68cc48783455c2fd7a5c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9379,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025e6fccf1b93555aa9e2c58fea2f469507cf76a500000000000000000000000025e6fccf1b93555aa9e2c58fea2f469507cf76a500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9380,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069612b3c79d214aa9fbbed24e758ea296d373c3600000000000000000000000069612b3c79d214aa9fbbed24e758ea296d373c3600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9381,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000215dc4f0eebb4e57fd0e5827add3403035109704000000000000000000000000215dc4f0eebb4e57fd0e5827add340303510970400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9382,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000781c3d6bacb3417c2c5dae348e35c6cb801a425d000000000000000000000000781c3d6bacb3417c2c5dae348e35c6cb801a425d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000813c36852827c230c3f53dd2ab319d2d59797bcd000000000000000000000000813c36852827c230c3f53dd2ab319d2d59797bcd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1ee081974bd829eb8f88fe283d4cab03099abd6000000000000000000000000f1ee081974bd829eb8f88fe283d4cab03099abd600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9385,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed16299c9f3ad2b85342991fd1c7fb5b7641f28e000000000000000000000000ed16299c9f3ad2b85342991fd1c7fb5b7641f28e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000502b811e4d4e89ab278e3d5edd70c1142d0f7207000000000000000000000000502b811e4d4e89ab278e3d5edd70c1142d0f720700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001810bc0600f9c0c008e0bccc980d40a651f0992a0000000000000000000000001810bc0600f9c0c008e0bccc980d40a651f0992a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074297dba00d452cedde835c6f7c3a8a903104e4e00000000000000000000000074297dba00d452cedde835c6f7c3a8a903104e4e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9389,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071e76dc3bebc994087b736c277fd343df20ec37900000000000000000000000071e76dc3bebc994087b736c277fd343df20ec37900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9390,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000731fd0bee5e6586376a71abb99ff8163564e5940000000000000000000000000731fd0bee5e6586376a71abb99ff8163564e594000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9391,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000e80d4eb607984b26c488f265801c997a259dd80b000000000000000000000000e80d4eb607984b26c488f265801c997a259dd80b000000000000000000000000000000000000000000000000000000003528a93900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d646c61d4588d27491ce4fb3d56301f2a493c280000000000000000000000006d646c61d4588d27491ce4fb3d56301f2a493c28000000000000000000000000000000000000000000000000004d304e1fa4e2c800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef45e94c3e03979ad47d6aeb1170ed86bae00d1e000000000000000000000000ef45e94c3e03979ad47d6aeb1170ed86bae00d1e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000454e08277cf48c2db7e619c921f22db9360494e3000000000000000000000000454e08277cf48c2db7e619c921f22db9360494e300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043dda16a8e5fa5d5bee9f8e442ea812cc5a80c8900000000000000000000000043dda16a8e5fa5d5bee9f8e442ea812cc5a80c8900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d17cf7dbe048807ddc142fe887dc174d9e59ec90000000000000000000000001d17cf7dbe048807ddc142fe887dc174d9e59ec900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9397,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c69b47d4c9ba5f6440183ecff4749f12905933fd000000000000000000000000c69b47d4c9ba5f6440183ecff4749f12905933fd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be41953010251d94ad5de4f4a7c6b970ca7be4d0000000000000000000000000be41953010251d94ad5de4f4a7c6b970ca7be4d000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085704b4b37cdb762a66d15e5fff3096620456d5c00000000000000000000000085704b4b37cdb762a66d15e5fff3096620456d5c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dbae11ccb6b39d2fbda0ccb4712b9d40cbc63d3e000000000000000000000000dbae11ccb6b39d2fbda0ccb4712b9d40cbc63d3e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099e86304a71df6e3181d4dc594e9da2c7b91e72d00000000000000000000000099e86304a71df6e3181d4dc594e9da2c7b91e72d000000000000000000000000000000000000000000000000007ffb96364d9ea300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9402,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072cc613ab9d908cf47ba1eda214f8db5afcef1ce00000000000000000000000072cc613ab9d908cf47ba1eda214f8db5afcef1ce000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030ca51c31a25a8a581903ca37647eee1c827602b00000000000000000000000030ca51c31a25a8a581903ca37647eee1c827602b00000000000000000000000000000000000000000000000000ad3227ecfc140000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f24b98ad804e6e87b1d90ff843f6a46b3feab4e0000000000000000000000005f24b98ad804e6e87b1d90ff843f6a46b3feab4e000000000000000000000000000000000000000000000000000d63f448376b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000070c969b616e0e400d55b5ada2cd544a5d7c160bf00000000000000000000000070c969b616e0e400d55b5ada2cd544a5d7c160bf0000000000000000000000000000000000000000000000000040846d7982345b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003e23505d4c3a701c6ae843a3bd48997a7376fb400000000000000000000000003e23505d4c3a701c6ae843a3bd48997a7376fb40000000000000000000000000000000000000000000000001bb7c64f114bca4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005483d50d366b2c47b16ec6f0f0a66963754c3d030000000000000000000000005483d50d366b2c47b16ec6f0f0a66963754c3d0300000000000000000000000000000000000000000000000000884925af0afe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9409,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e63ddc147253f8d004b14224df49b529de47a665000000000000000000000000e63ddc147253f8d004b14224df49b529de47a6650000000000000000000000000000000000000000000000000080aa1e7c9ee07b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000bfa9f6741056c180a0ac825bac06a665898d44c0000000000000000000000000bfa9f6741056c180a0ac825bac06a665898d44c000000000000000000000000000000000000000000000000005ff3db60039fc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c29696ebd2a47ccf361dc7fb421da4532e897fb0000000000000000000000006c29696ebd2a47ccf361dc7fb421da4532e897fb000000000000000000000000000000000000000000000000006042c8aa21bd4b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097bab1b1353f3717aefab2f9ae319e1f4f614b0100000000000000000000000097bab1b1353f3717aefab2f9ae319e1f4f614b010000000000000000000000000000000000000000000000000042da6f7ae3784e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9413,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce00ca9e1675fe532dda35a8784bef9f276a0165000000000000000000000000ce00ca9e1675fe532dda35a8784bef9f276a016500000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8d64c56ffd31140fc4df58691b76ffb0ea752e34a7b48794506fdb758c63280b,2022-07-04 07:14:28.000 UTC,0,true +9414,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084c57ac9448b9fd931d2b4803716aa4e76c8e82a00000000000000000000000084c57ac9448b9fd931d2b4803716aa4e76c8e82a000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcb9c0343593a2f248d3e41cca83577bb495a1f6f75a660fa1002da21bc938f41,2022-06-11 19:28:32.000 UTC,0,true +9415,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d01df8cde50458831a311cc114f2e2fc262b4573000000000000000000000000d01df8cde50458831a311cc114f2e2fc262b4573000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009119c41ad7a14e53b5882210a4acc31eaf23275e0000000000000000000000009119c41ad7a14e53b5882210a4acc31eaf23275e00000000000000000000000000000000000000000000000000f740b7c15c580200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x71afdbec735c684d14c15ae3716d112438710a2a829ceb0eab4a0faf0804c2fb,2022-03-04 07:22:33.000 UTC,0,true +9417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000843a315006c23eb34b4b0dc6a4284e80c3db86d4000000000000000000000000843a315006c23eb34b4b0dc6a4284e80c3db86d4000000000000000000000000000000000000000000000000013c31d34ed01ae300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xacd3bf31ad1250ae7e92bed70fd588af0d5b25be91c92a0191bf6914033be4d5,2021-12-15 10:01:54.000 UTC,0,true +9420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006722222812d18958a0ee6c2a75ac4ed3f2048ca40000000000000000000000006722222812d18958a0ee6c2a75ac4ed3f2048ca4000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe9cdb03ebf1508f8dae114a7095cee140ed9cf2000000000000000000000000fe9cdb03ebf1508f8dae114a7095cee140ed9cf200000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d01df8cde50458831a311cc114f2e2fc262b4573000000000000000000000000d01df8cde50458831a311cc114f2e2fc262b4573000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9423,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059bd4ae28ac8b6215f722a9a813c7f67fc0e929400000000000000000000000059bd4ae28ac8b6215f722a9a813c7f67fc0e92940000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000172f7bcf2ab7f5066ab4e22c85f366e36a28820a000000000000000000000000172f7bcf2ab7f5066ab4e22c85f366e36a28820a0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9425,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe9cdb03ebf1508f8dae114a7095cee140ed9cf2000000000000000000000000fe9cdb03ebf1508f8dae114a7095cee140ed9cf200000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9426,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe9cdb03ebf1508f8dae114a7095cee140ed9cf2000000000000000000000000fe9cdb03ebf1508f8dae114a7095cee140ed9cf200000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9427,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ed92d98c7204084d9d86c80cf1cecfba64e11cc0000000000000000000000001ed92d98c7204084d9d86c80cf1cecfba64e11cc0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a14d9797878c6592e53ec17b81b6729f3a0c19d6000000000000000000000000a14d9797878c6592e53ec17b81b6729f3a0c19d60000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090450285065bd2aae5539e7dec285c2b909cbbdc00000000000000000000000090450285065bd2aae5539e7dec285c2b909cbbdc000000000000000000000000000000000000000000000000008a271a42f4250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009102ab6f2c92b7fae7d35687a4d9654c2bc309c00000000000000000000000009102ab6f2c92b7fae7d35687a4d9654c2bc309c000000000000000000000000000000000000000000000000005102d67afffd2d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f78c76667750062a28470fa9d17636cf99e7ff60000000000000000000000004f78c76667750062a28470fa9d17636cf99e7ff60000000000000000000000000000000000000000000000000062af5123b128cc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9434,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000867f2c3854a0feb9f0e2fa7da9484831732f302f000000000000000000000000867f2c3854a0feb9f0e2fa7da9484831732f302f00000000000000000000000000000000000000000000000000060a24181e400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9435,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf9d50f495e489f03419c9037d437c3c6122b744000000000000000000000000cf9d50f495e489f03419c9037d437c3c6122b74400000000000000000000000000000000000000000000000000178773a2ba85f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006450da461d027a49c2b30f8cf41bd72798699a6b0000000000000000000000006450da461d027a49c2b30f8cf41bd72798699a6b000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000870b93d72d217d4b85f11d6507896f49d5f08feb000000000000000000000000870b93d72d217d4b85f11d6507896f49d5f08feb000000000000000000000000000000000000000000000000004e7c2c255a26b300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2034241e6ed97b11e5dabba229c968c747a19e5000000000000000000000000a2034241e6ed97b11e5dabba229c968c747a19e5000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e46c821441771cf14f1d07602b27c64ca3341a12000000000000000000000000e46c821441771cf14f1d07602b27c64ca3341a120000000000000000000000000000000000000000000000000a71bf54649d37af00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9441,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000383aca4e21388e32faf89fd941dffac9e3b33ff8000000000000000000000000383aca4e21388e32faf89fd941dffac9e3b33ff80000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ef70c1bb25f298ff9827d522e3b1c2a38fb95e60000000000000000000000007ef70c1bb25f298ff9827d522e3b1c2a38fb95e6000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009923338e76f7e853d93a3a5a4924f046ec7550e00000000000000000000000009923338e76f7e853d93a3a5a4924f046ec7550e000000000000000000000000000000000000000000000000000e1c8942dfa70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee33af102f6fef6c3c155499adaa804ffbd0398f000000000000000000000000ee33af102f6fef6c3c155499adaa804ffbd0398f00000000000000000000000000000000000000000000000000154dcaf4770c3b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063798de1a0e801de233034d57cb9b033f7606d2d00000000000000000000000063798de1a0e801de233034d57cb9b033f7606d2d000000000000000000000000000000000000000000000000001c19fc81eb0fea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f93bee3e6c159f51581e39dcbf97db9727690a6a000000000000000000000000f93bee3e6c159f51581e39dcbf97db9727690a6a000000000000000000000000000000000000000000000000015adf6a8488945e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6cfbb271749cb8eb91e6a2d0dad558cd696f12f8141ca319de956de91328a4b6,2022-02-15 14:00:21.000 UTC,0,true +9449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a45672f14c8272a9443c6255e52ac4eae882bfc0000000000000000000000005a45672f14c8272a9443c6255e52ac4eae882bfc00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9450,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e835af9a97134dd295174ca9ac0718db63b07ad7000000000000000000000000e835af9a97134dd295174ca9ac0718db63b07ad700000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3f982b963a063440cf4a93ee2f2b7262473a2a8000000000000000000000000d3f982b963a063440cf4a93ee2f2b7262473a2a800000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac82d6a9e995b3b8dcc24456218b816e5e5832aa000000000000000000000000ac82d6a9e995b3b8dcc24456218b816e5e5832aa00000000000000000000000000000000000000000000000000ca8132b032800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9453,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3770cef12ca18f738778a65d4ed793af09b05ef000000000000000000000000d3770cef12ca18f738778a65d4ed793af09b05ef0000000000000000000000000000000000000000000000000121e6c485ac000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9454,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b4283d33efa4c509242f33147f0c6ccd20a8d980000000000000000000000000b4283d33efa4c509242f33147f0c6ccd20a8d980000000000000000000000000000000000000000000000000045e1c069e0c49700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9455,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb9a04ec522d4d2de555d3c32032728f44ceac6f000000000000000000000000bb9a04ec522d4d2de555d3c32032728f44ceac6f00000000000000000000000000000000000000000000000000db8ec5c71e800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020b181d2f2afed425eced4cc680f97973a64060500000000000000000000000020b181d2f2afed425eced4cc680f97973a64060500000000000000000000000000000000000000000000000000fc9912c387c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049f44c6df326ac1577bad16b85d902c59196dce100000000000000000000000049f44c6df326ac1577bad16b85d902c59196dce100000000000000000000000000000000000000000000000001c10a77b72d76e600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc8f1177068c454162da1bb1e585517286844ce1963e626a631509c6ca4a46e58,2022-02-14 08:42:28.000 UTC,0,true +9458,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ec53fc9628c449bffebf3aa47c6f57d0608c18e0000000000000000000000004ec53fc9628c449bffebf3aa47c6f57d0608c18e00000000000000000000000000000000000000000000000001478f69584a800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001629052ed55b2198eec166a26a17db252a2e094f0000000000000000000000001629052ed55b2198eec166a26a17db252a2e094f00000000000000000000000000000000000000000000000001207af843c3000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036a656d41bbc80953e1d7aff9b704db5070d940e00000000000000000000000036a656d41bbc80953e1d7aff9b704db5070d940e000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9461,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002032dd3a8779d3fe81809af004b7bfe6ebd612f50000000000000000000000002032dd3a8779d3fe81809af004b7bfe6ebd612f500000000000000000000000000000000000000000000000000ffcb9e57d4000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000edc2fdcc98b72e6e0406e795e485f1665ec8cfc6000000000000000000000000edc2fdcc98b72e6e0406e795e485f1665ec8cfc6000000000000000000000000000000000000000000000000000000003b9224f000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa1554d6712b9c794da107909c2269f16602cfd55f251b748c195b9af0967085b,2022-04-20 10:33:15.000 UTC,0,true +9465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6fcd3e0e93e92d7f26aa0567bb3bb09528cdd79000000000000000000000000b6fcd3e0e93e92d7f26aa0567bb3bb09528cdd79000000000000000000000000000000000000000000000000013150f3779a922700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd5344ac489cad99bac38b6e1a1ad718289e074b000000000000000000000000fd5344ac489cad99bac38b6e1a1ad718289e074b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1833e3a5eb53d3700517e6466a1844c9dfb5bd4000000000000000000000000b1833e3a5eb53d3700517e6466a1844c9dfb5bd400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9468,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000852958a22a290e7dc0702d9bc2f3d60f3bc24f00000000000000000000000000852958a22a290e7dc0702d9bc2f3d60f3bc24f0000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c459fa807062efc84c4d18e032ae05da9e1272cd000000000000000000000000c459fa807062efc84c4d18e032ae05da9e1272cd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000517da7183897730aa3424898c44c8bc0d0206bf2000000000000000000000000517da7183897730aa3424898c44c8bc0d0206bf200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e260ac9ecb4f1e4e19222a6442ce8ce0267e5a30000000000000000000000006e260ac9ecb4f1e4e19222a6442ce8ce0267e5a300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058a4da2ce842e7df975eb1077ec1e4c06a0b866100000000000000000000000058a4da2ce842e7df975eb1077ec1e4c06a0b866100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c7f6a9a32cdf437b6390b713bcd45a779e5492e0000000000000000000000003c7f6a9a32cdf437b6390b713bcd45a779e5492e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d12e0865917014e64e30afea6cf235b6ce830640000000000000000000000007d12e0865917014e64e30afea6cf235b6ce8306400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000395d583fe840c275bc528d285682e81a8e7c6b0d000000000000000000000000395d583fe840c275bc528d285682e81a8e7c6b0d000000000000000000000000000000000000000000000000002a1bb74be714e900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d11a7d1e3f3d1aad17294a513940312347922d40000000000000000000000006d11a7d1e3f3d1aad17294a513940312347922d400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9477,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000440c50687f35f0f251525dbd50f381a3084373ac000000000000000000000000440c50687f35f0f251525dbd50f381a3084373ac00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9478,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076873fb189363a8c4a8d69ba6fba300ac5b1d91600000000000000000000000076873fb189363a8c4a8d69ba6fba300ac5b1d91600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9479,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000473e3eaf7961585fcd80626af4a07882db86a904000000000000000000000000473e3eaf7961585fcd80626af4a07882db86a90400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9480,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002feb6a35b7ba6aac0442364532a06d12409b10900000000000000000000000002feb6a35b7ba6aac0442364532a06d12409b109000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9481,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000053c0068da58dc80de6f3ec50ed67ae9aad3209a000000000000000000000000053c0068da58dc80de6f3ec50ed67ae9aad3209a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051aae740d3b49c91e2b584adc30d50cbb27b798e00000000000000000000000051aae740d3b49c91e2b584adc30d50cbb27b798e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9483,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000719a04e7710a1709d7b30237121c023450da512c000000000000000000000000719a04e7710a1709d7b30237121c023450da512c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9484,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be68697ec3450fecfef189ce70a05f2f289c6e8b000000000000000000000000be68697ec3450fecfef189ce70a05f2f289c6e8b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000256cd210943dc84c9164320a439c3e71c74527d5000000000000000000000000256cd210943dc84c9164320a439c3e71c74527d500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9486,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000079c7df7740e999872277fe97eb3f8c106ee2af4b00000000000000000000000079c7df7740e999872277fe97eb3f8c106ee2af4b000000000000000000000000000000000000000000000010965bef679745935200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9487,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003137f5c744eb1ad89501841aa556c50b02f953d90000000000000000000000003137f5c744eb1ad89501841aa556c50b02f953d900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9488,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd273f64246432fe8d73e88397b6b683b4e39bd1000000000000000000000000bd273f64246432fe8d73e88397b6b683b4e39bd100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9489,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b02dba56bcfa33564826aaf3c2a85b47e9f2c1c4000000000000000000000000b02dba56bcfa33564826aaf3c2a85b47e9f2c1c400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe4d75e540d6706b85d887992187fea4be84de78000000000000000000000000fe4d75e540d6706b85d887992187fea4be84de7800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004da38517372d424636e81632cd991fdf437514170000000000000000000000004da38517372d424636e81632cd991fdf4375141700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006dd20eb7d91144f0fa2b2a001105ae9322db8e990000000000000000000000006dd20eb7d91144f0fa2b2a001105ae9322db8e9900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9493,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005db7f5fce4f251701d4c5dc398177c0318a75efe0000000000000000000000005db7f5fce4f251701d4c5dc398177c0318a75efe00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fdbda741479644440c061f79d3c0e5982086ebb0000000000000000000000005fdbda741479644440c061f79d3c0e5982086ebb00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010cf17d2b35f2acbb348ea89da5d184f3b5d2a9f00000000000000000000000010cf17d2b35f2acbb348ea89da5d184f3b5d2a9f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5654f35da5afc0a9a73021574830f79ad953d6d000000000000000000000000f5654f35da5afc0a9a73021574830f79ad953d6d000000000000000000000000000000000000000000000000014461965063196600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9497,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c427e9e0e014476a6351ed0608fa7c6e433cb550000000000000000000000008c427e9e0e014476a6351ed0608fa7c6e433cb5500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b987ee8e3943b982d2c3e7e162a6ca99dd532210000000000000000000000006b987ee8e3943b982d2c3e7e162a6ca99dd5322100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb5296a3df62e12af6f96ab7f7e83386964535fc000000000000000000000000fb5296a3df62e12af6f96ab7f7e83386964535fc00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5f565848e3bbb1d616dcb1cc80b412e5ff12e45000000000000000000000000c5f565848e3bbb1d616dcb1cc80b412e5ff12e4500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a7fc63c64f4c8769919247d3dfcc16fa408cc3b0000000000000000000000002a7fc63c64f4c8769919247d3dfcc16fa408cc3b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9502,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fdf7681d2f5ec9896df42075d884c6dc03669a30000000000000000000000008fdf7681d2f5ec9896df42075d884c6dc03669a300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9503,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be1bbd830083f371edbc41517781255427c5ea5a000000000000000000000000be1bbd830083f371edbc41517781255427c5ea5a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000026aefab14d61df7a3973160abfcf22145b2ab61000000000000000000000000026aefab14d61df7a3973160abfcf22145b2ab6100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002af88171fe9668210705ea5633ca48a1a8a36efe0000000000000000000000002af88171fe9668210705ea5633ca48a1a8a36efe00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b6284f86b21575aaa4240f6852db428ad5c0d0a0000000000000000000000008b6284f86b21575aaa4240f6852db428ad5c0d0a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9508,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004805c22f5f813fc05c4d825290f33c228bbe8dc20000000000000000000000004805c22f5f813fc05c4d825290f33c228bbe8dc200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9511,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b05e05aa636d41bab5cb58a6c80f7dddd6fc8a90000000000000000000000006b05e05aa636d41bab5cb58a6c80f7dddd6fc8a900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9512,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000493b6750f108726df8e60b082adf9a59472d784d000000000000000000000000493b6750f108726df8e60b082adf9a59472d784d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9513,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080c9f47a8e6be7da9cb8e5076fa3955a7b29873700000000000000000000000080c9f47a8e6be7da9cb8e5076fa3955a7b29873700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000014aa9f6dbfdda9dc79c6f456926ba9f6226381f000000000000000000000000014aa9f6dbfdda9dc79c6f456926ba9f6226381f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e718661eea5cc11fcc4340430dec3b2c11fc4eaf000000000000000000000000e718661eea5cc11fcc4340430dec3b2c11fc4eaf00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9517,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cedf07b70896aa2f08af2828d8f82689d721c19b000000000000000000000000cedf07b70896aa2f08af2828d8f82689d721c19b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5987d44e206af78e9aab666ca76d1cf963f1aa8000000000000000000000000d5987d44e206af78e9aab666ca76d1cf963f1aa800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080fc9e301517ef5cb59da70a9806a8613075619000000000000000000000000080fc9e301517ef5cb59da70a9806a8613075619000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9521,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da5f734c3c9a7c0370f1412a87ba2524e996c399000000000000000000000000da5f734c3c9a7c0370f1412a87ba2524e996c39900000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9522,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001cc25aca4516a33cd3f61515048498823e2391850000000000000000000000001cc25aca4516a33cd3f61515048498823e239185000000000000000000000000000000000000000000000000000a3e7a178476ab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9523,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007165efe18fbf79a3e8fdbf3211927ca32ad86bb50000000000000000000000000000000000000000000000006124fee993bc0000,,,1,true +9524,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f39dd7675baa0ba061659fdc44bafc6ebc14d71f000000000000000000000000f39dd7675baa0ba061659fdc44bafc6ebc14d71f000000000000000000000000000000000000000000000000000a6f5a049ab93f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9525,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb5d817cfed6f47ebcdb8a1b0833552e999351bb000000000000000000000000cb5d817cfed6f47ebcdb8a1b0833552e999351bb0000000000000000000000000000000000000000000000000014a854db45241400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9526,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cbe610551f4e48ceed8056ac217dcc3f4f4ca180000000000000000000000007cbe610551f4e48ceed8056ac217dcc3f4f4ca18000000000000000000000000000000000000000000000000003babaf0d76b5f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9527,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8ddac677012e293b47ca5a00d2e33d6c8988c6e000000000000000000000000e8ddac677012e293b47ca5a00d2e33d6c8988c6e00000000000000000000000000000000000000000000000000cebc36cb66030900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9528,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000af7610346b2da6194780085e1629ca57e53f2b540000000000000000000000000000000000000000000000001feb3dd067660000,,,1,true +9530,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000376236b8277bbd26b7163caf4870691c37e751070000000000000000000000000000000000000000000000056bc75e2d63100000,,,1,true +9531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000051a0e3e0fe5783f7c0d5c1003fc121cb9981183000000000000000000000000051a0e3e0fe5783f7c0d5c1003fc121cb9981183000000000000000000000000000000000000000000000000037318a1b6ea283400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9532,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7e3d2e485520aa0af765aafc54f030d51729bd7000000000000000000000000e7e3d2e485520aa0af765aafc54f030d51729bd700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009d685739feec6d10cef02889957386c876fbd1f00000000000000000000000009d685739feec6d10cef02889957386c876fbd1f0000000000000000000000000000000000000000000000000064b017ae72b8fc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3d8abfbd8069a8fb255b94c9c2ecdb04bd2f210000000000000000000000000d3d8abfbd8069a8fb255b94c9c2ecdb04bd2f21000000000000000000000000000000000000000000000000000815c23343f4d2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x23886566fe0b30b38e015ae68fbc9958d29f46208ee3399c8ea9282907bc1f60,2022-06-10 03:25:18.000 UTC,0,true +9536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af25c239db4533c1958f823665db2e44cbf9c6f7000000000000000000000000af25c239db4533c1958f823665db2e44cbf9c6f700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e75a3c620a1f1a1b8047e1f03083956b8781f715000000000000000000000000e75a3c620a1f1a1b8047e1f03083956b8781f715000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000382d96d6a2f7f32ca6292c35d7175fa6b7ba9da7000000000000000000000000382d96d6a2f7f32ca6292c35d7175fa6b7ba9da700000000000000000000000000000000000000000000000000034d6f1b212e8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9539,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000250249f3f5d3c6860bd880ee4af0a334e0a0cba4000000000000000000000000250249f3f5d3c6860bd880ee4af0a334e0a0cba4000000000000000000000000000000000000000000000000006d53dd79ffaeb600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006f9f5be183eb34f447b39de0ecc55ebba219a2b00000000000000000000000006f9f5be183eb34f447b39de0ecc55ebba219a2b00000000000000000000000000000000000000000000000000254a5bde0f57a700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049214bf0a657c0d6cbc5f20526a563a6dca448f100000000000000000000000049214bf0a657c0d6cbc5f20526a563a6dca448f1000000000000000000000000000000000000000000000000003d909039944b1000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9542,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019f372338364550b5fe17fb1c97852ecb08579ed00000000000000000000000019f372338364550b5fe17fb1c97852ecb08579ed00000000000000000000000000000000000000000000000000336cf0446c67eb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056c8ed6d0e36b639544466381834e404615755d300000000000000000000000056c8ed6d0e36b639544466381834e404615755d3000000000000000000000000000000000000000000000000001cb671da4b663400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a7c6d9ae1371930c0b4856a71811174a6a92daa0000000000000000000000002a7c6d9ae1371930c0b4856a71811174a6a92daa0000000000000000000000000000000000000000000000000027425c7b19781000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9545,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003394a1ae60679c07a4af07c92d674818cb1c2ba60000000000000000000000003394a1ae60679c07a4af07c92d674818cb1c2ba60000000000000000000000000000000000000000000000000023cbdce95776b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9546,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014c963f01f369c96ffbadbd5209f016759f9209300000000000000000000000014c963f01f369c96ffbadbd5209f016759f920930000000000000000000000000000000000000000000000000668d2426581086300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e155396dfd335ef16dccfdc28c159ab92c88058c000000000000000000000000e155396dfd335ef16dccfdc28c159ab92c88058c00000000000000000000000000000000000000000000000000258000fc39382e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9550,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000687624745396900e2c942c4e32f10651615e294a000000000000000000000000687624745396900e2c942c4e32f10651615e294a0000000000000000000000000000000000000000000000000023b62c9bf7d68000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095dc79b0ccb34cc6622df8282d77c03b63e0240700000000000000000000000095dc79b0ccb34cc6622df8282d77c03b63e02407000000000000000000000000000000000000000000000000001d2e1f2650c36000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008cd7b3cfd0dd527e21e491b49568e35dad44d0f30000000000000000000000008cd7b3cfd0dd527e21e491b49568e35dad44d0f3000000000000000000000000000000000000000000000000002300bf9a120a2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5abd30462e816da67b9a954b1961213bb8a2e92000000000000000000000000d5abd30462e816da67b9a954b1961213bb8a2e920000000000000000000000000000000000000000000000000026c8d31e70ab8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0ed794e70d438f2b1fe0d8d2f39152a7b408ba1000000000000000000000000b0ed794e70d438f2b1fe0d8d2f39152a7b408ba100000000000000000000000000000000000000000000000000200be6ef205c4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000f2fc892056888e637cb2d77f0cd03b05676dbd5e000000000000000000000000f2fc892056888e637cb2d77f0cd03b05676dbd5e0000000000000000000000000000000000000000000000000000000000cec93500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2fc892056888e637cb2d77f0cd03b05676dbd5e000000000000000000000000f2fc892056888e637cb2d77f0cd03b05676dbd5e000000000000000000000000000000000000000000000000001e4c716cd16f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000128c3c6d48434c8713ec00358c1ecf252319b4c7000000000000000000000000128c3c6d48434c8713ec00358c1ecf252319b4c7000000000000000000000000000000000000000000000000003d1521a9aab49000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000facf1ead3b42f6855175dd655a65f9ff5a48dc10000000000000000000000000facf1ead3b42f6855175dd655a65f9ff5a48dc10000000000000000000000000000000000000000000000000038ef0e78cab86e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000742cfe2a1fb49ae444c91b696c771a7b2f65e9f4000000000000000000000000742cfe2a1fb49ae444c91b696c771a7b2f65e9f40000000000000000000000000000000000000000000000000003e871b540c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9562,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ccc93c66c6e80bf3d68bc63f546cbb42ab4895d6000000000000000000000000ccc93c66c6e80bf3d68bc63f546cbb42ab4895d600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083df74e7114079b98e69089edcdc8de377fb7cb000000000000000000000000083df74e7114079b98e69089edcdc8de377fb7cb000000000000000000000000000000000000000000000000000fa6ad8a4d4788200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e370c9c93014ca879da928274324f0253cde8490000000000000000000000002e370c9c93014ca879da928274324f0253cde849000000000000000000000000000000000000000000000000007044fb523604ae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1c4ac2986b29b5ec2454a09ead225ca65a949314999f99783e099d37d8249aff,2022-05-20 09:07:52.000 UTC,0,true +9567,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ee11be943141c5073680cbc587aa60c4c8dd78b0000000000000000000000002ee11be943141c5073680cbc587aa60c4c8dd78b0000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9569,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025b99f078903f7702d3f44b1f8a4fe88bc5d103600000000000000000000000025b99f078903f7702d3f44b1f8a4fe88bc5d103600000000000000000000000000000000000000000000000000c9b83e3a31027900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9571,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075e094cee2ddf4ee04f782d9670eb6dce88dcc9800000000000000000000000075e094cee2ddf4ee04f782d9670eb6dce88dcc98000000000000000000000000000000000000000000000000001aa535d3d0c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9573,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e75a3c620a1f1a1b8047e1f03083956b8781f715000000000000000000000000e75a3c620a1f1a1b8047e1f03083956b8781f715000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9576,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e75a3c620a1f1a1b8047e1f03083956b8781f715000000000000000000000000e75a3c620a1f1a1b8047e1f03083956b8781f715000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000728b6672bceee270e92637bae8bacb54a9b32888000000000000000000000000728b6672bceee270e92637bae8bacb54a9b3288800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094054865f83f9df3fae7d4b8e6b08b7ff420b0e200000000000000000000000094054865f83f9df3fae7d4b8e6b08b7ff420b0e2000000000000000000000000000000000000000000000000007c00e7bfc5e7a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9579,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1b3aeb7afd5642b1d20d00636b7c70163c3a15d000000000000000000000000f1b3aeb7afd5642b1d20d00636b7c70163c3a15d000000000000000000000000000000000000000000000000004360a091733e8c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9580,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cad3c3d957bcf6f3a3af9caaaadd2804ab132928000000000000000000000000cad3c3d957bcf6f3a3af9caaaadd2804ab13292800000000000000000000000000000000000000000000000000263d804fb3a83b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9585,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000076b68dc2509a483223256d56877bdc5c3ca4bce000000000000000000000000076b68dc2509a483223256d56877bdc5c3ca4bce000000000000000000000000000000000000000000000000003eb7f2a8b2c89200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9587,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000006bd996abee08d068ea284787a1b66ddf4145072a0000000000000000000000006bd996abee08d068ea284787a1b66ddf4145072a000000000000000000000000000000000000000000000000000000001f40a15b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9588,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ba7a90a128eeb1d74ea2152ec2d808b30ebead13000000000000000000000000ba7a90a128eeb1d74ea2152ec2d808b30ebead1300000000000000000000000000000000000000000000000000000000401d9de500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9589,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000076b68dc2509a483223256d56877bdc5c3ca4bce000000000000000000000000076b68dc2509a483223256d56877bdc5c3ca4bce0000000000000000000000000000000000000000000000000011f86c7b3f8d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9591,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008bde2372200e80d22212dc27b036080e929b779c0000000000000000000000008bde2372200e80d22212dc27b036080e929b779c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa38959380281110ffdab2118246dd993f44573b0a53fe156629d4efe8ab50d32,2021-11-21 04:18:40.000 UTC,0,true +9596,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007934b4344d6308dc7aecd2f8cfe006ed875504220000000000000000000000007934b4344d6308dc7aecd2f8cfe006ed87550422000000000000000000000000000000000000000000000000009c51c4521e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9598,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bac76b4c06d7c642601e995a68cb5186ee3154e6000000000000000000000000bac76b4c06d7c642601e995a68cb5186ee3154e600000000000000000000000000000000000000000000000000e62df32ebf295000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a82446df8eec33acc2a88cf61044f0ce9e561077000000000000000000000000a82446df8eec33acc2a88cf61044f0ce9e56107700000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9600,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086beae41e798b3f1114d6e26e944c5c604c32ac600000000000000000000000086beae41e798b3f1114d6e26e944c5c604c32ac60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9612,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc98abbbe01f19826bdb72953a6ec712b25f0aa3000000000000000000000000bc98abbbe01f19826bdb72953a6ec712b25f0aa300000000000000000000000000000000000000000000000003782dace9d9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dafe428c48841ffa6166e3695f1e0572db988f02000000000000000000000000dafe428c48841ffa6166e3695f1e0572db988f0200000000000000000000000000000000000000000000000000318bb61639880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5bbd1f0b42b1c40e13c83d8918b81616ee4c683000000000000000000000000b5bbd1f0b42b1c40e13c83d8918b81616ee4c683000000000000000000000000000000000000000000000000004c41434dc4336d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9670,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2dac809cc20f01b1933d8a1d9317bfd971f82e1000000000000000000000000b2dac809cc20f01b1933d8a1d9317bfd971f82e1000000000000000000000000000000000000000000000000003c5b1b9cc217c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b619744e17158dc2a53aec56c734f9195007f490000000000000000000000007b619744e17158dc2a53aec56c734f9195007f49000000000000000000000000000000000000000000000000000d415a2ee721c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9696,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000defb5b606ec1a3da6cc145f6498748cc456df21b000000000000000000000000defb5b606ec1a3da6cc145f6498748cc456df21b000000000000000000000000000000000000000000000000004ea69ae416c75d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9700,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c167064cb32f4923ebe2d1c47d621af2c73213fc000000000000000000000000c167064cb32f4923ebe2d1c47d621af2c73213fc000000000000000000000000000000000000000000000000008f7a1fcefbfa7e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f06ed24667f0bb586730c20fb968f9303368fee0000000000000000000000004f06ed24667f0bb586730c20fb968f9303368fee0000000000000000000000000000000000000000000000000046507a8b4360fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9715,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cf9977c3907624da58d69cfdc7f86f5552ddc2b0000000000000000000000007cf9977c3907624da58d69cfdc7f86f5552ddc2b00000000000000000000000000000000000000000000000000daf11b2f3f1f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aab1db5591a190242210b78f8895c9929d0a9efb000000000000000000000000aab1db5591a190242210b78f8895c9929d0a9efb0000000000000000000000000000000000000000000000000049e85e865c176700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9718,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e9d7531e717da3aa7cf6fb2f059a9e7ca4dd1760000000000000000000000009e9d7531e717da3aa7cf6fb2f059a9e7ca4dd176000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9720,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c64263d33d2a07d23976904b9d2dcf83f7270f50000000000000000000000008c64263d33d2a07d23976904b9d2dcf83f7270f500000000000000000000000000000000000000000000000000a798a47c4a6c6b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4afeb4c2cf6e213ee49a5d1c0093b553397821c2b19d67c2a9a2e03af0fd3c94,2021-12-20 09:25:41.000 UTC,0,true +9721,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064f99d8d532e2418a29199b84bc41cf702c6fc3300000000000000000000000064f99d8d532e2418a29199b84bc41cf702c6fc3300000000000000000000000000000000000000000000000000aa5c5f3a544f9100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9722,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5afaa33e1557dd72c2187557c4d6820c4f5467f000000000000000000000000e5afaa33e1557dd72c2187557c4d6820c4f5467f0000000000000000000000000000000000000000000000000039ccd125c9649000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9723,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002b26975022d55b218ef2b29df3f8d3047102c56b0000000000000000000000002b26975022d55b218ef2b29df3f8d3047102c56b0000000000000000000000000000000000000000000000000000000001edbb4100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9724,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000154e0f9554170e39447b72c6f4230dbfdc6afc56000000000000000000000000154e0f9554170e39447b72c6f4230dbfdc6afc5600000000000000000000000000000000000000000000000000200b5bc521d80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000185fdf7b36c6a002d0803c37d2597ca9906b62f5000000000000000000000000185fdf7b36c6a002d0803c37d2597ca9906b62f5000000000000000000000000000000000000000000000000004e465dc6611a8700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9730,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b12cc021009006cc87da206394a4951a1c7d5aef000000000000000000000000b12cc021009006cc87da206394a4951a1c7d5aef00000000000000000000000000000000000000000000000000a754fdef82af6800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9731,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000924b569b23935a0bf7a422594c94a046fa0e3491000000000000000000000000924b569b23935a0bf7a422594c94a046fa0e34910000000000000000000000000000000000000000000000000015b04ff816429000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9732,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fe1636a434d139fa7bc80552b966af6e4b417f40000000000000000000000008fe1636a434d139fa7bc80552b966af6e4b417f400000000000000000000000000000000000000000000000000cfb9c3bdbac10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3229f36fed9ae97be04c873a9c51dab612f6b5ba0f98673c37354789aaeda025,2022-03-24 10:32:12.000 UTC,0,true +9733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c61edc942bb6a5fca34a207d1d08e2caccbb93c0000000000000000000000002c61edc942bb6a5fca34a207d1d08e2caccbb93c000000000000000000000000000000000000000000000000001468190b49c47300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9735,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca84c49bd0f4fa84b5a16a3f30a6754c312d079a000000000000000000000000ca84c49bd0f4fa84b5a16a3f30a6754c312d079a000000000000000000000000000000000000000000000000004e180f2ca67d6a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9737,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079dafd0da626f23a66e63fe06a0f2b97781f819800000000000000000000000079dafd0da626f23a66e63fe06a0f2b97781f81980000000000000000000000000000000000000000000000000018e3a3ee86298000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000452008779b6bd5b2bcdd113d1e3f10c5e27b5cf8000000000000000000000000452008779b6bd5b2bcdd113d1e3f10c5e27b5cf800000000000000000000000000000000000000000000000000721440adfa9b8100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d1b71a98d689ad670a2966837f83740cf5b4d600000000000000000000000007d1b71a98d689ad670a2966837f83740cf5b4d600000000000000000000000000000000000000000000000000045b239dd41825100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca89925c2693cf6e2c37572ee3ceec485ce642fb000000000000000000000000ca89925c2693cf6e2c37572ee3ceec485ce642fb00000000000000000000000000000000000000000000000000a8ccc77fe5b5bc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003742799e12a6850e9ec9f8bf4db4461de958cc920000000000000000000000003742799e12a6850e9ec9f8bf4db4461de958cc9200000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9743,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007018c432bd81a91b3b8deaf5408547efe783548f0000000000000000000000007018c432bd81a91b3b8deaf5408547efe783548f0000000000000000000000000000000000000000000000000050a53a9589dffe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9744,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002abee2293455f0b6803a8326ab6d746c721d78c80000000000000000000000002abee2293455f0b6803a8326ab6d746c721d78c8000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x76c2e173a17edda1ca84e6e1489c5618fef7a84fb08d543b95128ac9889f7247,2022-03-06 10:28:43.000 UTC,0,true +9745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000871f95a4966be1f2dd7d8fb1a32f450b51e74ecb000000000000000000000000871f95a4966be1f2dd7d8fb1a32f450b51e74ecb000000000000000000000000000000000000000000000000000000001265f7df00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e1037ac10790f8514f7540e05ccae6f9d41f2150000000000000000000000000e1037ac10790f8514f7540e05ccae6f9d41f21500000000000000000000000000000000000000000000000002b9c5eeafb4bd0a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xdc657337ce083d3c3602c1dd013c1cf9c696119abe50a64a0249e24d7a98cf18,2022-06-11 20:24:59.000 UTC,0,true +9748,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fd55370391e5e099aa300a587d93c35dd8986b40000000000000000000000002fd55370391e5e099aa300a587d93c35dd8986b4000000000000000000000000000000000000000000000000009c51c4521e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9749,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074a279a3fcfa3b078413277026d82acdf2eac5c700000000000000000000000074a279a3fcfa3b078413277026d82acdf2eac5c7000000000000000000000000000000000000000000000000004c3c5c248591b500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9750,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d126b531e39f1838db27bc88e861a76612b96970000000000000000000000008d126b531e39f1838db27bc88e861a76612b96970000000000000000000000000000000000000000000000000029110738fc7ac200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9751,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053fad1623bc32399dcabcc2164e57e1bc549593d00000000000000000000000053fad1623bc32399dcabcc2164e57e1bc549593d00000000000000000000000000000000000000000000000004c9afac0f82800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb3153798373cf5f13a97e34fc72e1e3170e15d2000000000000000000000000eb3153798373cf5f13a97e34fc72e1e3170e15d2000000000000000000000000000000000000000000000000004cb159054ba2d100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9756,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064b7fcc8c17540139bdd84d00c7261035602cb6600000000000000000000000064b7fcc8c17540139bdd84d00c7261035602cb66000000000000000000000000000000000000000000000000001d24762cb31c6200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9757,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004af78ad4d68ac32bde6ad79849e4356e530879100000000000000000000000004af78ad4d68ac32bde6ad79849e4356e530879100000000000000000000000000000000000000000000000000618c3a423e005200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c0ce17de0c79c59b40ffcc024e56cf6121440ae0000000000000000000000007c0ce17de0c79c59b40ffcc024e56cf6121440ae000000000000000000000000000000000000000000000000004ef46a8345646300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abd8cee5a93265fc7d1f9e45f0169294d01b8802000000000000000000000000abd8cee5a93265fc7d1f9e45f0169294d01b8802000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b4f9e20415833c250e6a64a364e7126b25241b30000000000000000000000004b4f9e20415833c250e6a64a364e7126b25241b300000000000000000000000000000000000000000000000000847a30ee1ce2cf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9770,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dfddc72b4a0b6027282539ed22e6239268c1cfb0000000000000000000000002dfddc72b4a0b6027282539ed22e6239268c1cfb000000000000000000000000000000000000000000000000377a8ecd65cb520000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9771,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aae4b5f8eb2e6aaaf6ee98072e1c58826f75e261000000000000000000000000aae4b5f8eb2e6aaaf6ee98072e1c58826f75e261000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b13a4cf595b46f38ce0090bf84add5acea5ff227000000000000000000000000b13a4cf595b46f38ce0090bf84add5acea5ff22700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xeae9cc2c256947f8f9483ae7ca13026e4026f273c5ddc4e0f20c82d435ac58da,2022-07-30 11:37:12.000 UTC,0,true +9775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063bb1caab997a6b9743e62034d9ccc7fda7359f100000000000000000000000063bb1caab997a6b9743e62034d9ccc7fda7359f100000000000000000000000000000000000000000000000000207e9515942c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6b4a5c74c29dafbf671fd931dfb26fc0a5adf8a000000000000000000000000b6b4a5c74c29dafbf671fd931dfb26fc0a5adf8a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9782,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061a0fc420ae17760e328f5713b87d812dca163c300000000000000000000000061a0fc420ae17760e328f5713b87d812dca163c300000000000000000000000000000000000000000000000000b8882dfd8be03a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008335bff7ce4cdbd37baf0aae5bddbd58ab0f68540000000000000000000000008335bff7ce4cdbd37baf0aae5bddbd58ab0f6854000000000000000000000000000000000000000000000000014941aac1ec2e6f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9784,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a2a343bb1f29a1ef123fa358a9f61c42ab6e4b70000000000000000000000000a2a343bb1f29a1ef123fa358a9f61c42ab6e4b7000000000000000000000000000000000000000000000000003a3d931158076800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d14141da76488f5bb17e54ebb8ed4538fd2b82c8000000000000000000000000d14141da76488f5bb17e54ebb8ed4538fd2b82c80000000000000000000000000000000000000000000000000039925ccdc0a49100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ef9318a615dc080033fb5f51a6ecbba3327ae1b0000000000000000000000004ef9318a615dc080033fb5f51a6ecbba3327ae1b000000000000000000000000000000000000000000000000003b19673e1ba01d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003900971c3ce486b9506303f821d04f7c2b769b530000000000000000000000003900971c3ce486b9506303f821d04f7c2b769b53000000000000000000000000000000000000000000000000003b7504c181ca4200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6919543a40d33a39ddf109372f2128b34b46727000000000000000000000000c6919543a40d33a39ddf109372f2128b34b46727000000000000000000000000000000000000000000000000029d3071634e777500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2a60471747c33d39f7f63c90ef7d4aa6395a1f4f29bc172b8ee4766c71d90e65,2022-02-13 04:59:30.000 UTC,0,true +9790,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000195f61d13576f2ec92c812dc01faafd6433b6af7000000000000000000000000195f61d13576f2ec92c812dc01faafd6433b6af700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058a168e0ad6fb41bee9e89e9d1762fef50d6637c00000000000000000000000058a168e0ad6fb41bee9e89e9d1762fef50d6637c00000000000000000000000000000000000000000000000000ad18258d27dd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9793,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bf3d2c240ff569e11e75dfb2c42b57b7ae8be9d0000000000000000000000006bf3d2c240ff569e11e75dfb2c42b57b7ae8be9d00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x06c49a403db079de4a3e5b741729cbb94e76475333f5fe8b4da017dc81894821,2021-12-09 01:11:52.000 UTC,0,true +9794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d62f72c8d8809325cc94b43d8f5c50f306e8318e000000000000000000000000d62f72c8d8809325cc94b43d8f5c50f306e8318e000000000000000000000000000000000000000000000000003a715e7281d30d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9795,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fdbbfb0fe2986672af97eca0e797d76a0bbf35c9000000000000000000000000fdbbfb0fe2986672af97eca0e797d76a0bbf35c9000000000000000000000000000000000000000000000000145d94a4694b6ff100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9e65ae225f20d29de51ce8d5998d9456f80b9c4000000000000000000000000d9e65ae225f20d29de51ce8d5998d9456f80b9c4000000000000000000000000000000000000000000000000005aba364c1cdc8600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9798,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007ec4ce8860cb6c4516675e494884369ca874ba6c0000000000000000000000007ec4ce8860cb6c4516675e494884369ca874ba6c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9799,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e18d66ffab7ef9a44579288c39854b42f03edab2000000000000000000000000e18d66ffab7ef9a44579288c39854b42f03edab20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9800,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000293761f789b5fa61d0b871cf603ece3a73942ac6000000000000000000000000293761f789b5fa61d0b871cf603ece3a73942ac60000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9801,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008a88ccb818702afdd390b7e7938377d9afb9e3200000000000000000000000008a88ccb818702afdd390b7e7938377d9afb9e32000000000000000000000000000000000000000000000000009b6e64a8ec6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9802,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad9a89e66ba5c1af450a304829401cb5545b92bc000000000000000000000000ad9a89e66ba5c1af450a304829401cb5545b92bc000000000000000000000000000000000000000000000000015ddaddcce1da0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9804,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c101a05d6aea4f14ea0e303c22fe10556f28a205000000000000000000000000c101a05d6aea4f14ea0e303c22fe10556f28a2050000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9806,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000074515748caf5cc74b1b86f5baaa25c2f5652daff00000000000000000000000074515748caf5cc74b1b86f5baaa25c2f5652daff0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9807,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007bdf3a24169303cfa2fcdcac49013f3c06eaad8b0000000000000000000000007bdf3a24169303cfa2fcdcac49013f3c06eaad8b0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9808,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000558fb9800de9453a5f4c7ac2d2398e42d1bc7351000000000000000000000000558fb9800de9453a5f4c7ac2d2398e42d1bc73510000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9809,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a69acd8419e3b3a8a57ccadf69fb65fa21a33fb0000000000000000000000000a69acd8419e3b3a8a57ccadf69fb65fa21a33fb00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9810,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000231d24f024d074cec551e768a17d4ff246575f6b000000000000000000000000231d24f024d074cec551e768a17d4ff246575f6b0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9811,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001059aaed4254afe9a6e88ce5c089683171b59eff0000000000000000000000001059aaed4254afe9a6e88ce5c089683171b59eff0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9812,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000072a7b09495bb6e8309b8e76460a38a425a62354100000000000000000000000072a7b09495bb6e8309b8e76460a38a425a6235410000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9813,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f31364e33ef5b11a69877df8e173e0392e288da2000000000000000000000000f31364e33ef5b11a69877df8e173e0392e288da20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9814,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008a1c15068ef08ea8abcfdc158fb60230f74fdb6c0000000000000000000000008a1c15068ef08ea8abcfdc158fb60230f74fdb6c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9815,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000026f5901547f837f0b987d4f9ae2984560f4ae29b00000000000000000000000026f5901547f837f0b987d4f9ae2984560f4ae29b0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9816,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004e0cc752ca23f5a6c99fd13cb86654396cf0e68e0000000000000000000000004e0cc752ca23f5a6c99fd13cb86654396cf0e68e0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000002c58196a9b8916f888771917cb219dd6eaf801010000000000000000000000002c58196a9b8916f888771917cb219dd6eaf8010100000000000000000000000000000000000000000000000000000000017a818900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb9bc462592676f5911da0bad269bd11a2212b55000000000000000000000000bb9bc462592676f5911da0bad269bd11a2212b5500000000000000000000000000000000000000000000000000413519b61cfc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000918bb2298c60955053f64833b4a804fcdb8f29ed000000000000000000000000918bb2298c60955053f64833b4a804fcdb8f29ed0000000000000000000000000000000000000000000000000000000002a5352f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9822,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b23a7c2525df85f8be881da6bfa7ee0bb902def8000000000000000000000000b23a7c2525df85f8be881da6bfa7ee0bb902def800000000000000000000000000000000000000000000000006d48d9510a7763700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6c8834779362cf17f2a53419a5bda8b0364dd537c07ce50cbc271c5290eff35c,2022-11-01 17:23:11.000 UTC,0,true +9823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000626dcaae150e6240b5b24413cfd6b2aeb8ad443c000000000000000000000000626dcaae150e6240b5b24413cfd6b2aeb8ad443c00000000000000000000000000000000000000000000000000a8c3f5794ec74400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000875d0e316c50b4d167167335e539a8579ddff934000000000000000000000000875d0e316c50b4d167167335e539a8579ddff93400000000000000000000000000000000000000000000000000aa89a370bee2d300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005067823770154868970ce35a50782c35d0a4e76d0000000000000000000000005067823770154868970ce35a50782c35d0a4e76d000000000000000000000000000000000000000000000000006d60881ba3cd3e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000317890de9ee2d5987e30662b3cb640cffce62ce6000000000000000000000000317890de9ee2d5987e30662b3cb640cffce62ce6000000000000000000000000000000000000000000000000002898f52107e04000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d450c85676f20271b773903cf3fec32e94086118000000000000000000000000d450c85676f20271b773903cf3fec32e94086118000000000000000000000000000000000000000000000000001c46c72808cd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f4148dffca80f4c66c65d2a3c0d3342f20a313b0000000000000000000000005f4148dffca80f4c66c65d2a3c0d3342f20a313b000000000000000000000000000000000000000000000000005543df729c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f4148dffca80f4c66c65d2a3c0d3342f20a313b0000000000000000000000005f4148dffca80f4c66c65d2a3c0d3342f20a313b00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000228bf23ca1a080c0cb564bd2a074a8426de15247000000000000000000000000228bf23ca1a080c0cb564bd2a074a8426de15247000000000000000000000000000000000000000000000000000833de5811c0c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9847,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004935d32f454085a3de3766e48b5cf0b85c107531000000000000000000000000000000000000000000000001d6db934fba36c057,,,1,true +9849,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000057bc04ca8608bc33f7d5486edbb6876f88eb700d000000000000000000000000000000000000000000000018c4c62833642554eb,,,1,true +9850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ad5918400a49fe9c2f515800fed7f4bb48bfeee0000000000000000000000008ad5918400a49fe9c2f515800fed7f4bb48bfeee00000000000000000000000000000000000000000000000002bbaeb4363fcb4700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095814996f2d2ab5882debca4c7d37b9f3a53bac800000000000000000000000095814996f2d2ab5882debca4c7d37b9f3a53bac800000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055d36e1644a4db37c57ba133d127a7216b1f19b400000000000000000000000055d36e1644a4db37c57ba133d127a7216b1f19b400000000000000000000000000000000000000000000000000051eef581dc04900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000557007505b53a399a59a93509673fdc5a3dc4540000000000000000000000000557007505b53a399a59a93509673fdc5a3dc454000000000000000000000000000000000000000000000000005e87cb3076bb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d36663aea03c3cdf0d508595659fa0524e2cf5b0000000000000000000000002d36663aea03c3cdf0d508595659fa0524e2cf5b000000000000000000000000000000000000000000000000004d181f37b9773400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8dbbbd889ce1267443056a06fafb779d6785459c09ac9c30a5eccd8de5823ec2,2022-05-20 12:18:01.000 UTC,0,true +9861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c8882b1bfa6cdd7dcc065f6b86450992ce679190000000000000000000000004c8882b1bfa6cdd7dcc065f6b86450992ce6791900000000000000000000000000000000000000000000000003782dace9d9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x69406854f4a0e24ef562734edad82515d5abb36575817f2bc82bf64f3ddcf746,2022-03-15 05:51:00.000 UTC,0,true +9864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062725eac2bd3d2a1f3ac17e41c4f94dfbd47c22c00000000000000000000000062725eac2bd3d2a1f3ac17e41c4f94dfbd47c22c0000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000944f9f9b31f4de729b60e2c0b89de7cbdd5ac878000000000000000000000000944f9f9b31f4de729b60e2c0b89de7cbdd5ac87800000000000000000000000000000000000000000000000015cccfb275f46a8700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf28b5ea051b37a504078d77c13a88086a29aa56f7d1f9a7d98cc40e2ae4fb3c3,2021-12-17 15:10:05.000 UTC,0,true +9871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006df9525658fd2c864fab747274579f5b0c1c11b00000000000000000000000006df9525658fd2c864fab747274579f5b0c1c11b00000000000000000000000000000000000000000000000000297aa4a74e43b2d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0568c83470e77f4c5891d190361e4340f954a0d000000000000000000000000c0568c83470e77f4c5891d190361e4340f954a0d000000000000000000000000000000000000000000000000000730b1113de0e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019ba331d6adfc46e829ea33fa2a24ee87d7a676d00000000000000000000000019ba331d6adfc46e829ea33fa2a24ee87d7a676d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9874,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001ec5eae8306a271e7b2a0054f46455264217c5ba000000000000000000000000000000000000000000000000285d3b2dc5a86e3f,,,1,true +9875,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003132c2259c22cf2b60d104436c90150edca037690000000000000000000000003132c2259c22cf2b60d104436c90150edca037690000000000000000000000000000000000000000000000000051bda6a156a0f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003132c2259c22cf2b60d104436c90150edca037690000000000000000000000003132c2259c22cf2b60d104436c90150edca03769000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fcc8ec856092f49c640ab945d7f842655fc30b50000000000000000000000000fcc8ec856092f49c640ab945d7f842655fc30b50000000000000000000000000000000000000000000000000001ff973cafa80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c943aecd667d9239b7b0ce7f64747fab323f90a2000000000000000000000000c943aecd667d9239b7b0ce7f64747fab323f90a2000000000000000000000000000000000000000000000000003fefe8bb292e4800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9880,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f42cfe525388486554f8fc3c2ea2ba3414c4f16c000000000000000000000000f42cfe525388486554f8fc3c2ea2ba3414c4f16c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ccf7a254f35c89468c0884a31de5eedaf6a5771b000000000000000000000000ccf7a254f35c89468c0884a31de5eedaf6a5771b000000000000000000000000000000000000000000000000004a7f36fee5300700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000698fa8dfa821489cf4b69225347f28a56e3c3129000000000000000000000000698fa8dfa821489cf4b69225347f28a56e3c3129000000000000000000000000000000000000000000000000000e535e8c64602700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004199181f2510ec0486a40611042fab40492548600000000000000000000000004199181f2510ec0486a40611042fab404925486000000000000000000000000000000000000000000000000004559b9ca9423a900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f612dcbca32bb3943de530d21d21970380cd39d0000000000000000000000004f612dcbca32bb3943de530d21d21970380cd39d00000000000000000000000000000000000000000000000000fb58f763584cdf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b67fbf8c8d51253e4b3a943fe6e095468345b39e000000000000000000000000b67fbf8c8d51253e4b3a943fe6e095468345b39e000000000000000000000000000000000000000000000000003577f60f1d244000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ec5eae8306a271e7b2a0054f46455264217c5ba0000000000000000000000001ec5eae8306a271e7b2a0054f46455264217c5ba0000000000000000000000000000000000000000000000000092a9f8908034ce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9895,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be1c5ae29a2eb9548db9a8625f89e762f323a8a6000000000000000000000000be1c5ae29a2eb9548db9a8625f89e762f323a8a600000000000000000000000000000000000000000000000000277a5f981b9c2500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad769178ffff88945f175317b0e57ed9e7a5a680000000000000000000000000ad769178ffff88945f175317b0e57ed9e7a5a6800000000000000000000000000000000000000000000000000038ced1ba29c77600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d09418a23be24ad2f17192920df37f182629d269000000000000000000000000d09418a23be24ad2f17192920df37f182629d269000000000000000000000000000000000000000000000000003b41dae10709f600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000bab67a3e542138f0562b5ce572cd85ad14232ee0000000000000000000000000bab67a3e542138f0562b5ce572cd85ad14232ee0000000000000000000000000000000000000000000000000031e43d1bedb23a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9900,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004dd8a7631842772f42d5a54ac018143757b7790d0000000000000000000000004dd8a7631842772f42d5a54ac018143757b7790d0000000000000000000000000000000000000000000000000006110952cfec8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f70b585acf0030bdd393239f54bffcad1ea14f50000000000000000000000008f70b585acf0030bdd393239f54bffcad1ea14f5000000000000000000000000000000000000000000000000002613554619446000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000734d784f7ce1e164807785e2ba2425fae40c1da6000000000000000000000000734d784f7ce1e164807785e2ba2425fae40c1da600000000000000000000000000000000000000000000000000acbe17d340d70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9908,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a333c62787d3173395fb8bc7fb898cb17063caf0000000000000000000000006a333c62787d3173395fb8bc7fb898cb17063caf00000000000000000000000000000000000000000000000000181db7b8374a6300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9910,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006264e4eab94e93ee2afa9a47e689ce00cecd3f610000000000000000000000006264e4eab94e93ee2afa9a47e689ce00cecd3f61000000000000000000000000000000000000000000000000003d90e31830ab9800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9912,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000783f7a1a160e75d88eb08c44c47144b87a22a3ba000000000000000000000000783f7a1a160e75d88eb08c44c47144b87a22a3ba0000000000000000000000000000000000000000000000000045866f0f6b6ec800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a40eb870dcf533d4dc097c3d87aafe9f64490a10000000000000000000000004a40eb870dcf533d4dc097c3d87aafe9f64490a10000000000000000000000000000000000000000000000000214e8348c4f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9914,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdb8e2cb7e7af95ca2e9c327ce255d1f92e19efb000000000000000000000000bdb8e2cb7e7af95ca2e9c327ce255d1f92e19efb0000000000000000000000000000000000000000000000000100a8ccf26d254f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000092840aee0f4659a089d09572d1b219bcd540850000000000000000000000000092840aee0f4659a089d09572d1b219bcd540850000000000000000000000000000000000000000000000000021d8aa85d3edb4e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee44b8e9c0f7238887220564da32afee8ce92b08000000000000000000000000ee44b8e9c0f7238887220564da32afee8ce92b08000000000000000000000000000000000000000000000000003a89fb6d5a0cee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005937626ef988f82973de5c57bd389b86c113a3c20000000000000000000000005937626ef988f82973de5c57bd389b86c113a3c2000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004484fdb3a9d3973cd6d250b6d22608509b01d7920000000000000000000000004484fdb3a9d3973cd6d250b6d22608509b01d792000000000000000000000000000000000000000000000000001597bcb23bf69400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9919,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a54691936d4330435ed0f388e191df34499e7410000000000000000000000000a54691936d4330435ed0f388e191df34499e74100000000000000000000000000000000000000000000000000170c66cfc69dbd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b67620e8c9e19592b616942f895153e2dcf9ccb6000000000000000000000000b67620e8c9e19592b616942f895153e2dcf9ccb60000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5bedd996786147d19805e9cc6e5501e2e0b2b9c3b5940088a2ea14a6809c8460,2021-12-12 02:10:02.000 UTC,0,true +9921,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1eebc9ad0f4df141ef429bd0d7fdb0de9e4120c000000000000000000000000b1eebc9ad0f4df141ef429bd0d7fdb0de9e4120c000000000000000000000000000000000000000000000000001310c8ba769fc500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e32a1b6a0947b7843b541b0d2ff6c99a41e80b8f000000000000000000000000e32a1b6a0947b7843b541b0d2ff6c99a41e80b8f0000000000000000000000000000000000000000000000000048f46308111e1200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f47f60cb5426f63a8dd3786387742c2c49ad96e3000000000000000000000000f47f60cb5426f63a8dd3786387742c2c49ad96e300000000000000000000000000000000000000000000000000002acc90c1992600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7faec15d7da6f3d67ce27c6fd7236877f0ae95c000000000000000000000000c7faec15d7da6f3d67ce27c6fd7236877f0ae95c0000000000000000000000000000000000000000000000000005ca574c3c7a5000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000429c92eedc46e27bd1a6aa5da61c22255390f6b1000000000000000000000000429c92eedc46e27bd1a6aa5da61c22255390f6b1000000000000000000000000000000000000000000000000005dc15917e7567100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfa4042acf723c60d9e873dd884ae8760fd6b620000000000000000000000000bfa4042acf723c60d9e873dd884ae8760fd6b620000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9928,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007daa0dcf42e969e407449d4c869f862f8d361b270000000000000000000000007daa0dcf42e969e407449d4c869f862f8d361b27000000000000000000000000000000000000000000000000004058d01d56115c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c861d1eeea4b595603621e967fcd9887a72a74a9000000000000000000000000c861d1eeea4b595603621e967fcd9887a72a74a90000000000000000000000000000000000000000000000000017d2e1d192e95600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b8c68e6a69cf500675ae2f6c1f6816bd5a8788f0000000000000000000000005b8c68e6a69cf500675ae2f6c1f6816bd5a8788f000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9932,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b25f162913c84f94f23a9f0e89ed294ef4024871000000000000000000000000b25f162913c84f94f23a9f0e89ed294ef40248710000000000000000000000000000000000000000000000000028683e679e536300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9933,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000ecd428e33ed22b060625e7649ab0ed274bad9200000000000000000000000000ecd428e33ed22b060625e7649ab0ed274bad920000000000000000000000000000000000000000000000000047153bae43ffc600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025a0452f00529d7471ca0941ffc58c52c500d6ce00000000000000000000000025a0452f00529d7471ca0941ffc58c52c500d6ce00000000000000000000000000000000000000000000000000448f0cab58e8ae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080ebc88a66c217ad08ebd62476af0ebb00512bc700000000000000000000000080ebc88a66c217ad08ebd62476af0ebb00512bc7000000000000000000000000000000000000000000000000001c208dc050b2e300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9937,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001d754f2a403bf165aa04aff1940176581263ba300000000000000000000000001d754f2a403bf165aa04aff1940176581263ba30000000000000000000000000000000000000000000000000194df65be4a7ee100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c1a9cf8b192359795361e22ec22a18a1569a2780000000000000000000000009c1a9cf8b192359795361e22ec22a18a1569a27800000000000000000000000000000000000000000000000001a8697b3528344e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddd57e2a98cdd576e73c5e86c56b34e3d94a2158000000000000000000000000ddd57e2a98cdd576e73c5e86c56b34e3d94a21580000000000000000000000000000000000000000000000000045a6be04d433c100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d5a7f961133a8d8b05cde8f113bb7c4f81c70550000000000000000000000008d5a7f961133a8d8b05cde8f113bb7c4f81c705500000000000000000000000000000000000000000000000000497ebb533af40400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9945,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f847e9d51989033b691b8be943f8e9e268f99b9e000000000000000000000000f847e9d51989033b691b8be943f8e9e268f99b9e0000000000000000000000000000000000000000000000000062d734cdb35ec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9948,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b5e58994020fc30836d8506bcd8739385fb5f380000000000000000000000007b5e58994020fc30836d8506bcd8739385fb5f380000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9949,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f216ce5ff7219b7c889e981e02346e7fc2ac6240000000000000000000000009f216ce5ff7219b7c889e981e02346e7fc2ac624000000000000000000000000000000000000000000000000009176d72a784bca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9950,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f133919b60bdf696b0ebfa625ee7b16d92c17e60000000000000000000000000f133919b60bdf696b0ebfa625ee7b16d92c17e6000000000000000000000000000000000000000000000000015aba5bb12af4b400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9957,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005dad2e60516aead381996b18258828ca778b3cc70000000000000000000000005dad2e60516aead381996b18258828ca778b3cc7000000000000000000000000000000000000000000000000051f2bcb226c054f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007de44516f45761ef42e5d654b98c9943a615f8e60000000000000000000000007de44516f45761ef42e5d654b98c9943a615f8e600000000000000000000000000000000000000000000000000034fc4510b208000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000173c39a48c61035a1fedc5e880dc711c3d387814000000000000000000000000173c39a48c61035a1fedc5e880dc711c3d38781400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f73615d9c4ceb2afa641e14a07039eb862802d60000000000000000000000007f73615d9c4ceb2afa641e14a07039eb862802d600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9964,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c2f6f572d847d7c3fa36b2b77b2c118dec6102e0000000000000000000000003c2f6f572d847d7c3fa36b2b77b2c118dec6102e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c2e0172da35a9411b5fd1b873cbbe08dc5a54b40000000000000000000000006c2e0172da35a9411b5fd1b873cbbe08dc5a54b400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cda31aae920b358d6933b05b14f3af183781162e000000000000000000000000cda31aae920b358d6933b05b14f3af183781162e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9967,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cbe5cc94b176619b9ca63f0fe8475d1f64c7fe90000000000000000000000002cbe5cc94b176619b9ca63f0fe8475d1f64c7fe900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1d88743a9b35185e035a903369783f595d2be1d000000000000000000000000f1d88743a9b35185e035a903369783f595d2be1d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c19abd29fc942fbf749a9346f5f21aac3cbfde90000000000000000000000006c19abd29fc942fbf749a9346f5f21aac3cbfde900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9970,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000292410be51ee882d7f1f83f2a953c16e240c122b000000000000000000000000292410be51ee882d7f1f83f2a953c16e240c122b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051b619f48a8e8fe3fff8c6b6149485577e2fc8c000000000000000000000000051b619f48a8e8fe3fff8c6b6149485577e2fc8c000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f74ebcb5750836cc2107e12637c285c21a3f2190000000000000000000000007f74ebcb5750836cc2107e12637c285c21a3f21900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9973,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c69fb9e079efc3dac4f5037f6324e89b4def0c0c000000000000000000000000c69fb9e079efc3dac4f5037f6324e89b4def0c0c00000000000000000000000000000000000000000000000000207aaabf95420000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2240f1d714f6016259edac934c1d61b1cef4110000000000000000000000000b2240f1d714f6016259edac934c1d61b1cef411000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6d7259c494db121d490b07bbb31ba7966d395a0000000000000000000000000b6d7259c494db121d490b07bbb31ba7966d395a000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000adb39595cfe21bb87f0ef1c4ad3f4d85144d2db4000000000000000000000000adb39595cfe21bb87f0ef1c4ad3f4d85144d2db400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004da4ca139ff7868d9e84da98086386ac7a4f42620000000000000000000000004da4ca139ff7868d9e84da98086386ac7a4f426200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9978,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006e401916f9e149f20a1e3137d2897f843b510c6400000000000000000000000000000000000000000000000002b8b22448d7bfcc,,,1,true +9980,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000750ea760b19f87dde87492b69479a5b0a094b018000000000000000000000000750ea760b19f87dde87492b69479a5b0a094b018000000000000000000000000000000000000000000000000001f17c4281c430000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x018d967a923e864744595484b5da8c0744b0a943316d593b6c2763784c230fbf,2022-06-05 10:29:35.000 UTC,0,true +9981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000193a14bd9ec595cb9f17c35926869925ea2d9607000000000000000000000000193a14bd9ec595cb9f17c35926869925ea2d960700000000000000000000000000000000000000000000000000002e60f9a3ce0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e46a5c54225e347e138fffd648362e190948c3ed000000000000000000000000e46a5c54225e347e138fffd648362e190948c3ed000000000000000000000000000000000000000000000000002581c786a9875400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9984,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000fd61d925fed7c3bf871f34f4a73cbcfab06d76790000000000000000000000000000000000000000000000028d5b0d2af6eee3c4,,,1,true +9985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001332f3755f48a9c7f618681ae3bdbe618ddf65d90000000000000000000000001332f3755f48a9c7f618681ae3bdbe618ddf65d900000000000000000000000000000000000000000000000000c4b13afcc00fc500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9986,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001446e8f97318d7115483dfe09a43c2614b2e995d0000000000000000000000001446e8f97318d7115483dfe09a43c2614b2e995d0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000396bff8a62a4c8b3cf4c385d45e77795d9ed6b42000000000000000000000000396bff8a62a4c8b3cf4c385d45e77795d9ed6b4200000000000000000000000000000000000000000000000002b9ab14524493e800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d07dc0e3d1e9e8e85fcb6200816cda57ea027810000000000000000000000003d07dc0e3d1e9e8e85fcb6200816cda57ea0278100000000000000000000000000000000000000000000000000d134ff2276250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9991,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf96c38e87dc3b7734ce61c48f30ea156c29e06f000000000000000000000000bf96c38e87dc3b7734ce61c48f30ea156c29e06f0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9992,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001ab4bea4d7acc413c34bc2c467cec21f9141f0710000000000000000000000001ab4bea4d7acc413c34bc2c467cec21f9141f0710000000000000000000000000000000000000000000000026269b1b5dde1f2bd00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +9993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a226b0069ea5a21a97d2e799c9746f25bd685fb3000000000000000000000000a226b0069ea5a21a97d2e799c9746f25bd685fb3000000000000000000000000000000000000000000000000004c0cf7196af4f600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c29696ebd2a47ccf361dc7fb421da4532e897fb0000000000000000000000006c29696ebd2a47ccf361dc7fb421da4532e897fb000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +9998,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007514ec83c05ae7406eab24ed8ca54fc3710550200000000000000000000000007514ec83c05ae7406eab24ed8ca54fc37105502000000000000000000000000000000000000000000000000005543df729c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10000,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050856959952516c0183c3570fbddcf071a81826a00000000000000000000000050856959952516c0183c3570fbddcf071a81826a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10002,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fdd317f6507556ef5733a7b8c6fa5947a0b6df52000000000000000000000000fdd317f6507556ef5733a7b8c6fa5947a0b6df52000000000000000000000000000000000000000000000000000d6518a764b9e500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10003,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002efdd444da9e1823208e96e138add4d8b8063bf20000000000000000000000002efdd444da9e1823208e96e138add4d8b8063bf20000000000000000000000000000000000000000000000000051b660cdd5800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa4209660e4663f321186a84cd4be739bf405e57000000000000000000000000aa4209660e4663f321186a84cd4be739bf405e57000000000000000000000000000000000000000000000000003ff2e795f5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10005,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a6e9957e9177adaf95ca41f7e1243899687fbdf0000000000000000000000008a6e9957e9177adaf95ca41f7e1243899687fbdf00000000000000000000000000000000000000000000000001c6bf526340000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10007,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004012972309aaff4793885eac13857b6f33851d810000000000000000000000004012972309aaff4793885eac13857b6f33851d810000000000000000000000000000000000000000000000000012e20b65da6d3200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10009,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000086fb865af41659dcdb86410b32b44c7e087ff14000000000000000000000000086fb865af41659dcdb86410b32b44c7e087ff140000000000000000000000000000000000000000000000000022e6ad3a2b4db400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000394f5d7096bc8acc82ff09cb83be4ada8897efbd000000000000000000000000394f5d7096bc8acc82ff09cb83be4ada8897efbd0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10018,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f07c87105d334c4349059513713226d75ed23160000000000000000000000007f07c87105d334c4349059513713226d75ed2316000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10020,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004871c5532d7a56f70f4d9c85dd616595a28d62860000000000000000000000004871c5532d7a56f70f4d9c85dd616595a28d6286000000000000000000000000000000000000000000000000003ff2e795f5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004df622c2d7df728960230ec203e833034cac84610000000000000000000000004df622c2d7df728960230ec203e833034cac846100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007bd3939f47d5e9b001583b795e575aa06cb8e2450000000000000000000000007bd3939f47d5e9b001583b795e575aa06cb8e2450000000000000000000000000000000000000000000000000005bbfa4fb47d4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f3bf62d91baccc69c93c5f944a9eba13bed8ba70000000000000000000000006f3bf62d91baccc69c93c5f944a9eba13bed8ba700000000000000000000000000000000000000000000000000c18efce3b2b4d400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006aa4e37240e5002c086867408cfe6fc5d2708de30000000000000000000000006aa4e37240e5002c086867408cfe6fc5d2708de3000000000000000000000000000000000000000000000000020e831d63b6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000742cfe2a1fb49ae444c91b696c771a7b2f65e9f4000000000000000000000000742cfe2a1fb49ae444c91b696c771a7b2f65e9f4000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003bd13e5254b6d0dee77b7b9cb6328eb59ea058bc0000000000000000000000003bd13e5254b6d0dee77b7b9cb6328eb59ea058bc000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10031,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf09c3560b7176bffe3700d1a1283fb85eaf85f9000000000000000000000000cf09c3560b7176bffe3700d1a1283fb85eaf85f9000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10032,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f999e7c8e06c0128b6d030f80fad725d4da1a8b0000000000000000000000002f999e7c8e06c0128b6d030f80fad725d4da1a8b00000000000000000000000000000000000000000000000000199d19747f280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000582f19a6934a1d5b04592b4b5418022ba1d78941000000000000000000000000582f19a6934a1d5b04592b4b5418022ba1d7894100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10034,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3ddb4aa7af5d73a1c019bedfcc179006d6c7329000000000000000000000000d3ddb4aa7af5d73a1c019bedfcc179006d6c732900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037b2ab0cb7d20646e54463f7453b88756cc6ac5d00000000000000000000000037b2ab0cb7d20646e54463f7453b88756cc6ac5d0000000000000000000000000000000000000000000000000245c4c6c6b1c94000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10036,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040bb18f181938acfbb62bac84cc2812376fe817d00000000000000000000000040bb18f181938acfbb62bac84cc2812376fe817d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10037,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014008f25de5a57c9a6c5c64d8275e99b8001138b00000000000000000000000014008f25de5a57c9a6c5c64d8275e99b8001138b000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10039,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec4839fa846aa47aee6ad551cd6dcc8c9355bf1c000000000000000000000000ec4839fa846aa47aee6ad551cd6dcc8c9355bf1c000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10040,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002e4230ceea610111f3bd7925aa27dd1de1bfe2a80000000000000000000000002e4230ceea610111f3bd7925aa27dd1de1bfe2a80000000000000000000000000000000000000000000000058788cb94b1d8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10041,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec4839fa846aa47aee6ad551cd6dcc8c9355bf1c000000000000000000000000ec4839fa846aa47aee6ad551cd6dcc8c9355bf1c0000000000000000000000000000000000000000000000000003e871b540c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10042,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000030f84f0aa9cad152d1852a8767b3e7ad63e056e100000000000000000000000030f84f0aa9cad152d1852a8767b3e7ad63e056e10000000000000000000000000000000000000000000000264ceed6c7efec4c9800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10047,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000072bf82b40dbe01b1e832042d62b4f794405bb2e900000000000000000000000072bf82b40dbe01b1e832042d62b4f794405bb2e90000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10048,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d6e381035ab5995e06a5b1661ee58e92be755a90000000000000000000000003d6e381035ab5995e06a5b1661ee58e92be755a9000000000000000000000000000000000000000000000000015b36e7a9c1e70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ae488d14ff5622ca5ab1df32a8c26e775d4a7d30000000000000000000000004ae488d14ff5622ca5ab1df32a8c26e775d4a7d3000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10055,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000064e9ea8eeb3ea9a0e68b397db271fb7ac525e330000000000000000000000000000000000000000000000004563918244f40000,,,1,true +10058,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087602bee24cb297397265ef2b47755f6a7858b2000000000000000000000000087602bee24cb297397265ef2b47755f6a7858b20000000000000000000000000000000000000000000000000006d27dfb67fa16d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10059,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c1df5e5f5ac6112c9e6677550eb5e53e59651b3c000000000000000000000000000000000000000000000000ba7f18071c0fd89d,,,1,true +10060,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000062223bb2a4781c9512e5b78cef1655d1d9cd216d0000000000000000000000000000000000000000000000006aefe2c9c540b038,,,1,true +10061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abcbc48537de3b2120feee5f7eafb78cda48f00c000000000000000000000000abcbc48537de3b2120feee5f7eafb78cda48f00c000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cb4f60f5806e2eb260cdc33f81523f93795107a0000000000000000000000006cb4f60f5806e2eb260cdc33f81523f93795107a000000000000000000000000000000000000000000000000002a5a55b037944000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10067,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008823fd46766a52ad9e4587df2b6eb93a6c6922290000000000000000000000008823fd46766a52ad9e4587df2b6eb93a6c6922290000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10071,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000072bf82b40dbe01b1e832042d62b4f794405bb2e900000000000000000000000072bf82b40dbe01b1e832042d62b4f794405bb2e90000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10072,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000072bf82b40dbe01b1e832042d62b4f794405bb2e900000000000000000000000072bf82b40dbe01b1e832042d62b4f794405bb2e90000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10073,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000072bf82b40dbe01b1e832042d62b4f794405bb2e900000000000000000000000072bf82b40dbe01b1e832042d62b4f794405bb2e90000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10074,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075fef9a38b2f816d31077d34802fd2ebcad79ce600000000000000000000000075fef9a38b2f816d31077d34802fd2ebcad79ce600000000000000000000000000000000000000000000000000546bb20e4d690000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000049ed1732cec6d80a8163aa053fa78d35e56a608a00000000000000000000000049ed1732cec6d80a8163aa053fa78d35e56a608a000000000000000000000000000000000000000000000000000000000198ef8000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ca9e9cc095b0bc7d863c8f23c40d2bfa81ddec20000000000000000000000001ca9e9cc095b0bc7d863c8f23c40d2bfa81ddec2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10077,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071ea03598702d2fef81cf676d8fa7083c2b58f4300000000000000000000000071ea03598702d2fef81cf676d8fa7083c2b58f43000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d107fb7d638216a641827517011e54982a8ea1f2000000000000000000000000d107fb7d638216a641827517011e54982a8ea1f2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f038d81d37dc40182742c38f096d3821ba07c190000000000000000000000002f038d81d37dc40182742c38f096d3821ba07c19000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057230c0d93aaea20709c49dc80272a06df0c401200000000000000000000000057230c0d93aaea20709c49dc80272a06df0c4012000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021a86e150450d2751435ab390c026e0cdd12664200000000000000000000000021a86e150450d2751435ab390c026e0cdd126642000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ac2537286e8168df4ae7971a8d56716a3110ab40000000000000000000000008ac2537286e8168df4ae7971a8d56716a3110ab4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10084,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000458af2c1ed0e782bced4ad7c6af87d9a7a6fd790000000000000000000000000458af2c1ed0e782bced4ad7c6af87d9a7a6fd79000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10085,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075c2c8a53eccdf562c6c2f9fb96751f2e2bf970900000000000000000000000075c2c8a53eccdf562c6c2f9fb96751f2e2bf9709000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000518c302322cdc7a2597b2df46be285bc23a74500000000000000000000000000518c302322cdc7a2597b2df46be285bc23a7450000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097db23710a380967fcea208540d4e70be7797f8300000000000000000000000097db23710a380967fcea208540d4e70be7797f83000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d0d0f44e92bc9a9278cf8a4f9e5027d56d68d4f0000000000000000000000007d0d0f44e92bc9a9278cf8a4f9e5027d56d68d4f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003cd66418db4c9a559c8bba52c80e5c328771d5670000000000000000000000003cd66418db4c9a559c8bba52c80e5c328771d567000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10090,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ce685b14e8ba490b37be916982610ce1a984d401000000000000000000000000ce685b14e8ba490b37be916982610ce1a984d4010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10091,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000315c272cfda98d59b0671d5c7736f404b0929f00000000000000000000000000315c272cfda98d59b0671d5c7736f404b0929f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0b152dc2a4dd5700927430c4e2c10c6d1f59d01000000000000000000000000c0b152dc2a4dd5700927430c4e2c10c6d1f59d0100000000000000000000000000000000000000000000000000545dfde151360000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036f5a5c87f44e2cf2bde4976878527f934f7e24b00000000000000000000000036f5a5c87f44e2cf2bde4976878527f934f7e24b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ffaa410e323cb0f594ff2bde976993b3a32cacb0000000000000000000000004ffaa410e323cb0f594ff2bde976993b3a32cacb000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfcfd6875dead16273e3d2c9cbf4e310aa61b8f0000000000000000000000000bfcfd6875dead16273e3d2c9cbf4e310aa61b8f0000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10096,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa0e64bb7405e198912b789f0a034cb406c27ad8000000000000000000000000fa0e64bb7405e198912b789f0a034cb406c27ad8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd2422c3a18c477b455eeca76336299b71a782bd000000000000000000000000bd2422c3a18c477b455eeca76336299b71a782bd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10098,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000085f5aded0b12fefbf87d44106465eef6fd2b8fbc00000000000000000000000085f5aded0b12fefbf87d44106465eef6fd2b8fbc0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10100,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c7e1b198a199c1eaa3d5065c2f14c3710e456ec0000000000000000000000000c7e1b198a199c1eaa3d5065c2f14c3710e456ec00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10101,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b1b749f5325c6b9692093575e519a4191432379f000000000000000000000000b1b749f5325c6b9692093575e519a4191432379f0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10102,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000052b78e734ab4239a31c4df316f515d2a67aa09ad00000000000000000000000052b78e734ab4239a31c4df316f515d2a67aa09ad0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10103,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007f4825c7d1faf7400a500a4da4c356c89f7193880000000000000000000000007f4825c7d1faf7400a500a4da4c356c89f7193880000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10104,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d8e12edc97ca9432dae369a0a9b42c4ed9338e1b000000000000000000000000d8e12edc97ca9432dae369a0a9b42c4ed9338e1b0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10106,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000cdc5a129d5c21f57e0b4030f14dcc0736a6e0fbf000000000000000000000000cdc5a129d5c21f57e0b4030f14dcc0736a6e0fbf0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10107,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002b81cad571025bc0003724602f9f1981aa0e272c0000000000000000000000002b81cad571025bc0003724602f9f1981aa0e272c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10108,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008e081ed1dc015d6c240ce53c1f2ef34f4b494c3f0000000000000000000000008e081ed1dc015d6c240ce53c1f2ef34f4b494c3f0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10109,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000733849262454294011ab8dec5324c94f5cb56286000000000000000000000000733849262454294011ab8dec5324c94f5cb562860000000000000000000000000000000000000000000000000042acb25d47190000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10110,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000454d998f8bb9a7c15f057a65fdf2ece62ed10717000000000000000000000000454d998f8bb9a7c15f057a65fdf2ece62ed107170000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10111,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000005f73e68a8f4e35509cc9489ffc1bace4cdfd39580000000000000000000000005f73e68a8f4e35509cc9489ffc1bace4cdfd39580000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10112,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ba6b247cb6183fd5ad3b1e3381c7832036881f13000000000000000000000000ba6b247cb6183fd5ad3b1e3381c7832036881f130000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10113,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000092f65115b22ca4b1c30eb1f5e884ccec076aff0500000000000000000000000092f65115b22ca4b1c30eb1f5e884ccec076aff050000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10115,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d3303476f4444ae95bd24a17bfc3205f53efe840000000000000000000000000d3303476f4444ae95bd24a17bfc3205f53efe8400000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10116,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000050d569614dd212ac6ac46702696ae8116985a99300000000000000000000000050d569614dd212ac6ac46702696ae8116985a9930000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10117,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e8496213adbaecf2186be49e5bf5e5da3b079da4000000000000000000000000e8496213adbaecf2186be49e5bf5e5da3b079da40000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10118,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c7e441581383460082f3face8021c7aa7d0bf1c0000000000000000000000000c7e441581383460082f3face8021c7aa7d0bf1c00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10119,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000fea4c9731d15337539116d07f61bd6f5b889e6d0000000000000000000000000fea4c9731d15337539116d07f61bd6f5b889e6d00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10120,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004b591f78e5fb4097964a35d3322fdbcde179d2ad0000000000000000000000004b591f78e5fb4097964a35d3322fdbcde179d2ad0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10121,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008ae15e79144fc11428faeb99ec025d0b525dacf40000000000000000000000008ae15e79144fc11428faeb99ec025d0b525dacf40000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10122,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007e44734df1f5270c0f461b3159ef9065769d09c00000000000000000000000007e44734df1f5270c0f461b3159ef9065769d09c00000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9b98b2c4ff722d5a1cdac65725f5d609782b225000000000000000000000000d9b98b2c4ff722d5a1cdac65725f5d609782b2250000000000000000000000000000000000000000000000000076508955cb840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10124,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000081993c552d3a9923acff5f0c74a7fe3714781c8800000000000000000000000081993c552d3a9923acff5f0c74a7fe3714781c880000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10125,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000702b564c22f3c715c3f0a6ced062a3a1c938aaae000000000000000000000000702b564c22f3c715c3f0a6ced062a3a1c938aaae0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10126,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000573207197d089e98ca46ea6d8fa24a1d6ba7cac4000000000000000000000000573207197d089e98ca46ea6d8fa24a1d6ba7cac40000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10127,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006aa459e7eb8d057ece344bccaabfbe37fb2d777b0000000000000000000000006aa459e7eb8d057ece344bccaabfbe37fb2d777b0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10129,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000bddf8194ccc04be52d3e66d5dfb63edba8735e40000000000000000000000000bddf8194ccc04be52d3e66d5dfb63edba8735e400000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000008ccf1bb8e9664863040f9ec000db69a98c01095c0000000000000000000000008ccf1bb8e9664863040f9ec000db69a98c01095c0000000000000000000000000000000000000000000000000000000003adc7e300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b5568579983f59b1bac36926c0cb8ef03883bab0000000000000000000000004b5568579983f59b1bac36926c0cb8ef03883bab000000000000000000000000000000000000000000000000003b64767291b94000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b460d7ffa9d9dc485d73bbb0dcd6086dbe11486e000000000000000000000000b460d7ffa9d9dc485d73bbb0dcd6086dbe11486e000000000000000000000000000000000000000000000000003326139aeb092d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10138,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005121d18eae0be5bb57d6bb7907a9d49d9e5af1ef0000000000000000000000005121d18eae0be5bb57d6bb7907a9d49d9e5af1ef0000000000000000000000000000000000000000000000000031bced02db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x371a90ee0a969e3223f940a0007dde944e478c8b171ee418adf6a4d55667563b,2022-05-29 09:29:12.000 UTC,0,true +10139,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7f06d3ae0aad1d5c1f5602d93c0f44927b91fba000000000000000000000000c7f06d3ae0aad1d5c1f5602d93c0f44927b91fba00000000000000000000000000000000000000000000000000403bf970f702a900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004de67d3e4dbe226f216022c2f1c2ff80311a1d960000000000000000000000004de67d3e4dbe226f216022c2f1c2ff80311a1d9600000000000000000000000000000000000000000000000000ad9b9766711f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0c80e2a3ae845c2d255b9d5f72636cf4679130ecbf1566d77fcf1cf1f64de099,2021-12-26 08:12:45.000 UTC,0,true +10143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa6dc8d75c0be59983207f16da1168068fe816da000000000000000000000000aa6dc8d75c0be59983207f16da1168068fe816da00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10145,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026f0b7289933220d76e9e11257d741454cf3cce000000000000000000000000026f0b7289933220d76e9e11257d741454cf3cce0000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045f425484d66db4f639ba8d17c0b218044323eee00000000000000000000000045f425484d66db4f639ba8d17c0b218044323eee000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10147,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027e52eeb0d7b910dec57fd66833ad1d4ba2d4c7700000000000000000000000027e52eeb0d7b910dec57fd66833ad1d4ba2d4c77000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000197cf41f02f380ca1c135eed92321aa1b663d06d000000000000000000000000197cf41f02f380ca1c135eed92321aa1b663d06d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eaca773f51c4a561ae622a6d7d6b98cc490e929e000000000000000000000000eaca773f51c4a561ae622a6d7d6b98cc490e929e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10150,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5577bb739ac71d1d2af723b29fdd48246622690000000000000000000000000e5577bb739ac71d1d2af723b29fdd48246622690000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10152,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000742f477a2ec86b9ea08769a56a1d1dcdf42808f8000000000000000000000000742f477a2ec86b9ea08769a56a1d1dcdf42808f8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f11913257505b756071462301810a189ec635390000000000000000000000000f11913257505b756071462301810a189ec63539000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10154,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000724d0c36c59e1e8b872e7513242678a90dcc693e000000000000000000000000724d0c36c59e1e8b872e7513242678a90dcc693e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c230098ca60a8805605dcb8162edb7ac2c2ec03a000000000000000000000000c230098ca60a8805605dcb8162edb7ac2c2ec03a000000000000000000000000000000000000000000000000002fddb9c7d4685600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10158,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6c8118a562029638ebb4a268a14aa148e66320a000000000000000000000000a6c8118a562029638ebb4a268a14aa148e66320a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042acc6c41ba0085452b0abc0385b45af73bc030100000000000000000000000042acc6c41ba0085452b0abc0385b45af73bc03010000000000000000000000000000000000000000000000000043306bcefdfe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049c0dce4dd4f830cbf99c9012e556c5032aea3fe00000000000000000000000049c0dce4dd4f830cbf99c9012e556c5032aea3fe00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10162,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000daa201fe714db677be1ce4ddcb1671db58536e9e000000000000000000000000daa201fe714db677be1ce4ddcb1671db58536e9e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0545180d0f14ecff7195fe4dedaec4463aa9477000000000000000000000000a0545180d0f14ecff7195fe4dedaec4463aa947700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10166,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000064409b6f951b944cd474112596918443e949d73a00000000000000000000000000000000000000000000000049b4a92da3d541cc,,,1,true +10167,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c14e3364f5f6e642a4258ef1ec1f4fdcb6192380000000000000000000000004c14e3364f5f6e642a4258ef1ec1f4fdcb6192380000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b6ca557426ef32205cbd3521fcd84df73c023970000000000000000000000002b6ca557426ef32205cbd3521fcd84df73c0239700000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10169,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003fe00711f5bc714bdd9cd02c078212735c752ad20000000000000000000000003fe00711f5bc714bdd9cd02c078212735c752ad20000000000000000000000000000000000000000000000000067fd768e86b7e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6c86df56d0a5c574658bf2831d8dda94e6fee58000000000000000000000000b6c86df56d0a5c574658bf2831d8dda94e6fee580000000000000000000000000000000000000000000000000000f3e017c4d74000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10173,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046f64499d85f2c9c2da909c23ae14171ad497a8000000000000000000000000046f64499d85f2c9c2da909c23ae14171ad497a800000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000940f065eeef9895db3e7f0c6e81285a23999ef62000000000000000000000000940f065eeef9895db3e7f0c6e81285a23999ef62000000000000000000000000000000000000000000000000003f411813d9b51f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10175,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000220b573118f76e07e39378debab10229f81088f3000000000000000000000000220b573118f76e07e39378debab10229f81088f300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d225664800111cb92bfada74d2f7ddb64dbb5fa6000000000000000000000000d225664800111cb92bfada74d2f7ddb64dbb5fa600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d7129923d67697398506754af137c7ed14240f90000000000000000000000009d7129923d67697398506754af137c7ed14240f900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000704e37fad86c7c83c4815705cfc1d05b428fcb16000000000000000000000000704e37fad86c7c83c4815705cfc1d05b428fcb1600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cde9d17ffe865b52abba7f6c24d4ab00dd81ee30000000000000000000000004cde9d17ffe865b52abba7f6c24d4ab00dd81ee300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029347aaf07d8e9d97bb4ca54c17de6f008b0081200000000000000000000000029347aaf07d8e9d97bb4ca54c17de6f008b0081200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a8727c34188323c7de9a2c50965d11e8601a2cc0000000000000000000000005a8727c34188323c7de9a2c50965d11e8601a2cc00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a4e54944bb193f47967df9c872107d7dafe279a0000000000000000000000004a4e54944bb193f47967df9c872107d7dafe279a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10186,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018a468f1001dedb8ae05dca5d565b9717eae214500000000000000000000000018a468f1001dedb8ae05dca5d565b9717eae214500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10188,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8699196330d4f5f336447e714af78f7ddce10f4000000000000000000000000b8699196330d4f5f336447e714af78f7ddce10f400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8fe31643fb7106966f7f6f4022a9089097fd577000000000000000000000000a8fe31643fb7106966f7f6f4022a9089097fd577000000000000000000000000000000000000000000000000015c9f5156085e9c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000008eafda6638457c05c210df7bc7331ce01b8fa3a00000000000000000000000008eafda6638457c05c210df7bc7331ce01b8fa3a000000000000000000000000000000000000000000000000000000004d7c6d0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x2bb6234353e0e6e023d68077c5f57d8e460a84cf89e05921da6df587a9e3c124,2021-12-20 14:30:00.000 UTC,0,true +10235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000f23ca10acd56f752737db7286478dfcf6e5dd700000000000000000000000000f23ca10acd56f752737db7286478dfcf6e5dd700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6fb0f6063e851a21091c12a8e030dfe27caeff0000000000000000000000000f6fb0f6063e851a21091c12a8e030dfe27caeff000000000000000000000000000000000000000000000000000b02bf9db96800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf9f420d42c6c55be64ff4631b6aa1a38934f73c000000000000000000000000cf9f420d42c6c55be64ff4631b6aa1a38934f73c000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10241,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f6000000000000000000000000317854d799bf228f22ae1af441f0e3cededcebae000000000000000000000000317854d799bf228f22ae1af441f0e3cededcebae00000000000000000000000000000000000000000000000000048f83ef278ff000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10242,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d0eb55100cf5e2a70cd8773275dfa50e679270e0000000000000000000000003d0eb55100cf5e2a70cd8773275dfa50e679270e000000000000000000000000000000000000000000000000004521ac7874140000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10243,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005d4c5b72a62ca1e2548f1914252d31a9023fec700000000000000000000000005d4c5b72a62ca1e2548f1914252d31a9023fec700000000000000000000000000000000000000000000000000017c2fa463780000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3ad2bad724109d9d82fb2398e41e50c89660b5e1f02230da8f462c2f9cd4cad7,2022-04-26 17:42:12.000 UTC,0,true +10244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000af8bc4650698b53d8d2cedfe180ddf1f3cba5bf6000000000000000000000000af8bc4650698b53d8d2cedfe180ddf1f3cba5bf6000000000000000000000000000000000000000000000000000000000660b0c000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10245,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000102c13752113c8d60000bf3fbf9205a80ca245e7000000000000000000000000102c13752113c8d60000bf3fbf9205a80ca245e7000000000000000000000000000000000000000000000000005d27d837a977fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b255d025a6a1da4e5a707f8501dac148a0be382c000000000000000000000000b255d025a6a1da4e5a707f8501dac148a0be382c00000000000000000000000000000000000000000000000000000dda5e87f50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10249,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007bd3939f47d5e9b001583b795e575aa06cb8e2450000000000000000000000007bd3939f47d5e9b001583b795e575aa06cb8e245000000000000000000000000000000000000000000000002fe0ba986973593cc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ecb769fb7e68cda5026349c0d0e446105bdce880000000000000000000000007ecb769fb7e68cda5026349c0d0e446105bdce88000000000000000000000000000000000000000000000000006d0d660b17ad2500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063bb1caab997a6b9743e62034d9ccc7fda7359f100000000000000000000000063bb1caab997a6b9743e62034d9ccc7fda7359f1000000000000000000000000000000000000000000000000000974d1c1df000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10252,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a658f95d3b82fcf45a0c4758474c6f3564e4cb9f000000000000000000000000a658f95d3b82fcf45a0c4758474c6f3564e4cb9f000000000000000000000000000000000000000000000000000c60c9cde5ca4d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000086fb865af41659dcdb86410b32b44c7e087ff14000000000000000000000000086fb865af41659dcdb86410b32b44c7e087ff140000000000000000000000000000000000000000000000000000a533b777d90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10254,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000217a347ad2daac7d2e0fc0185df1c57ecd532ad0000000000000000000000000217a347ad2daac7d2e0fc0185df1c57ecd532ad00000000000000000000000000000000000000000000000000000a6e55200be300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1825e8203d05434534756f1c0c639f74792fcd6000000000000000000000000f1825e8203d05434534756f1c0c639f74792fcd60000000000000000000000000000000000000000000000000068894b86ce6f4700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000727d55cd776946e4cad03a26915d5c0f5bb12a63000000000000000000000000727d55cd776946e4cad03a26915d5c0f5bb12a6300000000000000000000000000000000000000000000000000000a6e55200be300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10257,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4f60da1acfa4f0c0897c34a9c830cb16494ed6d000000000000000000000000b4f60da1acfa4f0c0897c34a9c830cb16494ed6d0000000000000000000000000000000000000000000000000000e10adb56387300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10258,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000659e15424b6f24b66e5c3cb0a9e2d591bba93b88000000000000000000000000659e15424b6f24b66e5c3cb0a9e2d591bba93b8800000000000000000000000000000000000000000000000000003240e2cda1a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1eebc9ad0f4df141ef429bd0d7fdb0de9e4120c000000000000000000000000b1eebc9ad0f4df141ef429bd0d7fdb0de9e4120c00000000000000000000000000000000000000000000000000003240e2cda1a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10260,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f70b585acf0030bdd393239f54bffcad1ea14f50000000000000000000000008f70b585acf0030bdd393239f54bffcad1ea14f500000000000000000000000000000000000000000000000000003240e2cda1a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10261,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0568c83470e77f4c5891d190361e4340f954a0d000000000000000000000000c0568c83470e77f4c5891d190361e4340f954a0d00000000000000000000000000000000000000000000000000003240e2cda1a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10262,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005055b56dd5f68a77ce57c6dac3b64f4fc17fab890000000000000000000000005055b56dd5f68a77ce57c6dac3b64f4fc17fab8900000000000000000000000000000000000000000000000000003240e2cda1a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000573e97a089ada31d62d42b61c248cc86be764b99000000000000000000000000573e97a089ada31d62d42b61c248cc86be764b9900000000000000000000000000000000000000000000000000003240e2cda1a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10264,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7faec15d7da6f3d67ce27c6fd7236877f0ae95c000000000000000000000000c7faec15d7da6f3d67ce27c6fd7236877f0ae95c00000000000000000000000000000000000000000000000000003240e2cda1a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10265,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ccf7a254f35c89468c0884a31de5eedaf6a5771b000000000000000000000000ccf7a254f35c89468c0884a31de5eedaf6a5771b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10266,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003132c2259c22cf2b60d104436c90150edca037690000000000000000000000003132c2259c22cf2b60d104436c90150edca037690000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10267,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043ae58171e667dd417db1ef49ee5f18e466f581200000000000000000000000043ae58171e667dd417db1ef49ee5f18e466f581200000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b0ce2f4a9ecc7c94d89f4288efe11dbfc139bce0000000000000000000000000b0ce2f4a9ecc7c94d89f4288efe11dbfc139bce0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000727d55cd776946e4cad03a26915d5c0f5bb12a63000000000000000000000000727d55cd776946e4cad03a26915d5c0f5bb12a630000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10270,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb1b4f5fc05eca6e86e33d0719ae4cab47b9fc6d000000000000000000000000fb1b4f5fc05eca6e86e33d0719ae4cab47b9fc6d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10271,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c915cdd6254a77125280f4e58070229e942f6dff000000000000000000000000c915cdd6254a77125280f4e58070229e942f6dff000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff08f4394a19c5e01b2d16b9faaf905581e2a16e000000000000000000000000ff08f4394a19c5e01b2d16b9faaf905581e2a16e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10273,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007233bc516651ece192db7502b97648bee50488070000000000000000000000007233bc516651ece192db7502b97648bee5048807000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9bea21a2ecd9296f722e91fe806972728d890fd000000000000000000000000f9bea21a2ecd9296f722e91fe806972728d890fd0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4f60da1acfa4f0c0897c34a9c830cb16494ed6d000000000000000000000000b4f60da1acfa4f0c0897c34a9c830cb16494ed6d0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080b0e7dcbe436fa8a614f25c872f43539de1461f00000000000000000000000080b0e7dcbe436fa8a614f25c872f43539de1461f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1f404ef1cea424a35fa4cbe373e74f0154eeb0e000000000000000000000000e1f404ef1cea424a35fa4cbe373e74f0154eeb0e0000000000000000000000000000000000000000000000000003328b944c400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10278,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a0a8017c2af6212a96ce718c12f90b89bee11a60000000000000000000000006a0a8017c2af6212a96ce718c12f90b89bee11a6000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d055c2753009604e1dcbacc648c0b2744aa620ce000000000000000000000000d055c2753009604e1dcbacc648c0b2744aa620ce00000000000000000000000000000000000000000000000000024f2beb1aa00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000169d31b52d8de8d1235e54cb29ab1d1a466f14d9000000000000000000000000169d31b52d8de8d1235e54cb29ab1d1a466f14d900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000212a7f5ea445d92d0d900cffdcf6cac9bffb850b000000000000000000000000212a7f5ea445d92d0d900cffdcf6cac9bffb850b00000000000000000000000000000000000000000000000000027ca57357c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2c07722d72bd0bba8360ed4e91c97df17cfd1cd000000000000000000000000d2c07722d72bd0bba8360ed4e91c97df17cfd1cd000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10284,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c6eab90d841ab91affe69a0409e0b6de14d95070000000000000000000000008c6eab90d841ab91affe69a0409e0b6de14d950700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10285,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000586a911410d6bfc5281b641539f159032b745ea1000000000000000000000000586a911410d6bfc5281b641539f159032b745ea1000000000000000000000000000000000000000000000000001b658611edae0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10289,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3e9b7e2cc8dd20837d97e53359584434bdb177a000000000000000000000000a3e9b7e2cc8dd20837d97e53359584434bdb177a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c01aa6d5c839555c4de1a5b3ecbdf4bc49aded0e000000000000000000000000c01aa6d5c839555c4de1a5b3ecbdf4bc49aded0e00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10291,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007772e14acc07bbc8feac62134450bb96c9b75af50000000000000000000000007772e14acc07bbc8feac62134450bb96c9b75af5000000000000000000000000000000000000000000000000050540d84e58629d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10292,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029958d6de6a7eb94859a1a2f14cc95956497fe9500000000000000000000000029958d6de6a7eb94859a1a2f14cc95956497fe95000000000000000000000000000000000000000000000000008361f8c4e19e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10293,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d62f9f64135eb257d54e3e7bfcd7af5461e038d0000000000000000000000009d62f9f64135eb257d54e3e7bfcd7af5461e038d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013af0bcef44bb79eb362b9fdce618b3d5687251200000000000000000000000013af0bcef44bb79eb362b9fdce618b3d56872512000000000000000000000000000000000000000000000000015741231033621300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10295,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000964ae9de12550092156981ef8e90f1f728b54488000000000000000000000000964ae9de12550092156981ef8e90f1f728b5448800000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10296,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d71f8d6a355196391bd22eb45dd991addec97b3d000000000000000000000000d71f8d6a355196391bd22eb45dd991addec97b3d0000000000000000000000000000000000000000000000000036515138f29c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0fc1db5b578e450291e4f8773213680656e019f3a2f42ff28bae810ce5fae2c0,2022-04-20 10:37:33.000 UTC,0,true +10297,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009cc7285272b1d0561f58002b38fdc62dc4d58c7c0000000000000000000000009cc7285272b1d0561f58002b38fdc62dc4d58c7c000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d13a94dee746792b1d1eb6c5c2dde9abaaf4f410000000000000000000000003d13a94dee746792b1d1eb6c5c2dde9abaaf4f41000000000000000000000000000000000000000000000000003affc7c9cb277c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10299,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa2d5b6b5b1e3955c0d15c0a8973bb40a6445a0b000000000000000000000000aa2d5b6b5b1e3955c0d15c0a8973bb40a6445a0b00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ebbd86806394e54dc5910f643c746c4ea6bc7180000000000000000000000000ebbd86806394e54dc5910f643c746c4ea6bc718000000000000000000000000000000000000000000000000004482431457260000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10304,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071fde05ed1cd7e5f15605f155d568cfc4a11169f00000000000000000000000071fde05ed1cd7e5f15605f155d568cfc4a11169f000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000002556d2ff1766dc2dcfe95c3066745c0eb2d885000000000000000000000000002556d2ff1766dc2dcfe95c3066745c0eb2d88500000000000000000000000000000000000000000000000000394290a8e95a8200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10307,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000073c486d8828778d1113fc251bb0f8051cf4831d100000000000000000000000073c486d8828778d1113fc251bb0f8051cf4831d100000000000000000000000000000000000000000000000000000000853e594400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10310,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002495fbe9664d0cb6fa64ff82ab0c09828c6fec5d0000000000000000000000002495fbe9664d0cb6fa64ff82ab0c09828c6fec5d00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10311,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1e65b35a31bbd0e3be874107077668b890eca71000000000000000000000000f1e65b35a31bbd0e3be874107077668b890eca710000000000000000000000000000000000000000000000000033d1fe15ed120000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10313,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd62ff34e049b1aa707cc2354b284d1d14d05feb000000000000000000000000fd62ff34e049b1aa707cc2354b284d1d14d05feb0000000000000000000000000000000000000000000000000029cee12b25d50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10315,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006adadd07bc925e5b1ee66ab7882cd9123659b3070000000000000000000000006adadd07bc925e5b1ee66ab7882cd9123659b30700000000000000000000000000000000000000000000000000f5fb428d649b1600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10316,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080aaf7d99a2fc604f597b3e4aa5caeb309fb8ff300000000000000000000000080aaf7d99a2fc604f597b3e4aa5caeb309fb8ff3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000075259cc3a74fde232f8219af4c6f11bfb3ae4f7000000000000000000000000075259cc3a74fde232f8219af4c6f11bfb3ae4f7000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad24ff5b503be5b6dd3936f842a252b0843ab808000000000000000000000000ad24ff5b503be5b6dd3936f842a252b0843ab80800000000000000000000000000000000000000000000000000a5c44c2413bc3400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10320,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000012592819286ea4352dc732edd6b65492325d33f000000000000000000000000012592819286ea4352dc732edd6b65492325d33f000000000000000000000000000000000000000000000000000000009411cfd1d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10321,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000009fddfa181c05f23eab8b17f15719dbeffcb060000000000000000000000000009fddfa181c05f23eab8b17f15719dbeffcb06000000000000000000000000000000000000000000000000000000000060905df00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x991d81d23dd63378654c79d88281a9398d8097bfc9c8a29914e79b68c3dd1ac4,2022-08-26 07:10:26.000 UTC,0,true +10322,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000075259cc3a74fde232f8219af4c6f11bfb3ae4f7000000000000000000000000075259cc3a74fde232f8219af4c6f11bfb3ae4f700000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c2b1742dac3d8e05c8f4497a14c8be56834d6320000000000000000000000003c2b1742dac3d8e05c8f4497a14c8be56834d63200000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10324,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000115c5b00726c22797c7dac1e614bc85aecf4d629000000000000000000000000115c5b00726c22797c7dac1e614bc85aecf4d629000000000000000000000000000000000000000000000000000000000666bafb00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x39ccd67a7700b997967bf0bbc08251c796652a75e34a8fd41be387856791a2d3,2022-08-26 07:06:59.000 UTC,0,true +10325,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e3c20cdfb58665c6b5ef73a3c6e3bb915dbe5d10000000000000000000000001e3c20cdfb58665c6b5ef73a3c6e3bb915dbe5d100000000000000000000000000000000000000000000000002eed84182f5f57100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10326,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6c3c3621f42ec1f1cd1207bb1571d93646ab29a000000000000000000000000f6c3c3621f42ec1f1cd1207bb1571d93646ab29a000000000000000000000000000000000000000000000000015ebfea73a2530000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10327,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060a2653f59dedafb8097d2ebb7306faaa396969400000000000000000000000060a2653f59dedafb8097d2ebb7306faaa396969400000000000000000000000000000000000000000000000000255cf559e8911b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10328,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba84c858a959d236b375a969412e3d78dc49d01e000000000000000000000000ba84c858a959d236b375a969412e3d78dc49d01e000000000000000000000000000000000000000000000000007d31275d4edc4100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085e8f7c8a4c0dad2ad621a0452fca994202c924000000000000000000000000085e8f7c8a4c0dad2ad621a0452fca994202c9240000000000000000000000000000000000000000000000000003abbf91aa5519900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10330,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000477c43b4835cfdabbeca1db95ca830b9865a588e000000000000000000000000477c43b4835cfdabbeca1db95ca830b9865a588e00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10333,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000049205e7f66591d3742bdf61b5477dd5579896e9a000000000000000000000000000000000000000000000005f68e8131ecf80000,,,1,true +10334,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000049205e7f66591d3742bdf61b5477dd5579896e9a0000000000000000000000000000000000000000000000000de0b6b3a7640000,,,1,true +10336,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000049205e7f66591d3742bdf61b5477dd5579896e9a0000000000000000000000000000000000000000000000006124fee993bc0000,,,1,true +10337,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000974250fa680bcf173d77c1950f2a9662d80c094b000000000000000000000000974250fa680bcf173d77c1950f2a9662d80c094b000000000000000000000000000000000000000000000000005629e98d33e95000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10338,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7a3cf40a424706362a4e7593826bf7976e8caf2000000000000000000000000c7a3cf40a424706362a4e7593826bf7976e8caf20000000000000000000000000000000000000000000000000000910ffc834bc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eee8def7aff805bd3d34ce2926e55308af6fdea7000000000000000000000000eee8def7aff805bd3d34ce2926e55308af6fdea70000000000000000000000000000000000000000000000000051acebe37b8d8400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3265d44000d2dffe2987b379759f657912c0df7000000000000000000000000a3265d44000d2dffe2987b379759f657912c0df70000000000000000000000000000000000000000000000000038d62a5f060fc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10342,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ef0f60b0de23ef1943545392d9999acc2bf93a90000000000000000000000000ef0f60b0de23ef1943545392d9999acc2bf93a900000000000000000000000000000000000000000000000000524c1560ffebfe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10343,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003027e896eb33338ee957c75c850dfa5675192dd30000000000000000000000003027e896eb33338ee957c75c850dfa5675192dd300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10344,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003027e896eb33338ee957c75c850dfa5675192dd30000000000000000000000003027e896eb33338ee957c75c850dfa5675192dd300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c2d10e462338c73aa623c66d7ab7000e3113d0c0000000000000000000000000c2d10e462338c73aa623c66d7ab7000e3113d0c00000000000000000000000000000000000000000000000000540fc1d5bdc0a200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba1a0bea968df4223863751bb1d38e6598875994000000000000000000000000ba1a0bea968df4223863751bb1d38e6598875994000000000000000000000000000000000000000000000000005755daaa5fc49b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10347,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020d6827df2cb81cc673e2d8aaf1a551ba4a223ef00000000000000000000000020d6827df2cb81cc673e2d8aaf1a551ba4a223ef00000000000000000000000000000000000000000000000000535f100862a1a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005de56eff8cca0aacba2843ea6f4d95bd3f18fb6f0000000000000000000000005de56eff8cca0aacba2843ea6f4d95bd3f18fb6f0000000000000000000000000000000000000000000000000066851c120c91ca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10350,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c9f2f77293528e7d2e8b02e6176d8eef9d35ec30000000000000000000000002c9f2f77293528e7d2e8b02e6176d8eef9d35ec3000000000000000000000000000000000000000000000000000d145bc1e07f6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016d95d23a1c8004791c6054eb44e5ab0247b91d500000000000000000000000016d95d23a1c8004791c6054eb44e5ab0247b91d50000000000000000000000000000000000000000000000000131493891a5f2b200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024efda7b7781f877bd1ea07d50db5f4f39378bd600000000000000000000000024efda7b7781f877bd1ea07d50db5f4f39378bd6000000000000000000000000000000000000000000000000000efca6e002cdc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e81669100000000000000000000000024efda7b7781f877bd1ea07d50db5f4f39378bd600000000000000000000000024efda7b7781f877bd1ea07d50db5f4f39378bd60000000000000000000000000000000000000000000000001e8210322557b37500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10357,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7a0a0b2b1f6a256dcbf6516aaecd6a5c616a020000000000000000000000000b7a0a0b2b1f6a256dcbf6516aaecd6a5c616a02000000000000000000000000000000000000000000000000000845e39c720d1df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10359,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051cfff329f4e823c370b1d210bc52a53c084e7d300000000000000000000000051cfff329f4e823c370b1d210bc52a53c084e7d300000000000000000000000000000000000000000000000000303d2b6931c19b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x73813adc4c0da4fedfce1011fdaa2bba0c66889f2ea5a4663707577d3ff27b32,2022-08-25 00:51:03.000 UTC,0,true +10360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac30912712612e1b8cd3ece688fb1e917ae3d62b000000000000000000000000ac30912712612e1b8cd3ece688fb1e917ae3d62b000000000000000000000000000000000000000000000000000b2d034bb75cfc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10361,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005465b4f4ea1cb0222063fe68812e064688d55fe70000000000000000000000005465b4f4ea1cb0222063fe68812e064688d55fe700000000000000000000000000000000000000000000000000b3a2307b20a3f600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10363,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c0fa5ab1a86cba0321d7b173b751e264fba955b0000000000000000000000007c0fa5ab1a86cba0321d7b173b751e264fba955b000000000000000000000000000000000000000000000000000c4940304217d400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002731d63bd9dcc8954a00ce371ee684f3a80731670000000000000000000000002731d63bd9dcc8954a00ce371ee684f3a80731670000000000000000000000000000000000000000000000000de24152aa6c010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf7d7e75e42294d5c18a1b180f49710329b550cf22bd6039c219dd3d9743664af,2022-01-06 11:09:27.000 UTC,0,true +10365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a751840c88c172fd286ed65d7370e80af88f77a6000000000000000000000000a751840c88c172fd286ed65d7370e80af88f77a6000000000000000000000000000000000000000000000000000ba6331297b7c400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10366,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a72315bf50892d6c75341446b890ec0064b2eec4000000000000000000000000a72315bf50892d6c75341446b890ec0064b2eec4000000000000000000000000000000000000000000000000000b51c38f73e0c900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b9bf228ef7c4fe0f27338944e56babcbe1363540000000000000000000000003b9bf228ef7c4fe0f27338944e56babcbe13635400000000000000000000000000000000000000000000000000d827f523ed588800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a07014c48675e60949a2324400e2a783c4c8e3db000000000000000000000000a07014c48675e60949a2324400e2a783c4c8e3db000000000000000000000000000000000000000000000000001b3ebfdfe218c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029c56a174a6407ded4297fa9b3db40986eeae49200000000000000000000000029c56a174a6407ded4297fa9b3db40986eeae492000000000000000000000000000000000000000000000000000d4c94a4f3c64700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025132bb3a3276d1cb05f975e790f86b5122b34e400000000000000000000000025132bb3a3276d1cb05f975e790f86b5122b34e4000000000000000000000000000000000000000000000000000c6a8a8d77d60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10371,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6310c4d5e6680d891d1ebf25d0783fe60c40520000000000000000000000000d6310c4d5e6680d891d1ebf25d0783fe60c405200000000000000000000000000000000000000000000000000060fb56aab1ee3800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000290ea250ce53f591a3343967683702e43c2b4f3f000000000000000000000000290ea250ce53f591a3343967683702e43c2b4f3f000000000000000000000000000000000000000000000000004705057d8edd7c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10373,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006780f586701c31e08eecef12302fc97c0ae994490000000000000000000000006780f586701c31e08eecef12302fc97c0ae99449000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e988e5332a1bbd17dc7392cc94f391ff27e7e2f0000000000000000000000008e988e5332a1bbd17dc7392cc94f391ff27e7e2f000000000000000000000000000000000000000000000000000d4651ea74c44500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10375,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000edc11c59261bc0df4bfe982aae936f7f213ab260000000000000000000000000edc11c59261bc0df4bfe982aae936f7f213ab26000000000000000000000000000000000000000000000000000d181962a8f39400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8c0fe3699db673486c391a4eefa5a18c7cfd4d6000000000000000000000000e8c0fe3699db673486c391a4eefa5a18c7cfd4d60000000000000000000000000000000000000000000000000059bd223f7c06c200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1e65de2fa611ffe46c6d4df47841ff787a8163af1432b13e5e67e90bbea998d6,2022-03-22 14:28:02.000 UTC,0,true +10380,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002076a89dd5fc291ebd740a83b4ca3e8ea8909e4d0000000000000000000000002076a89dd5fc291ebd740a83b4ca3e8ea8909e4d000000000000000000000000000000000000000000000000000e14ff25ee120200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10381,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076766ce199954d2dc52e14577e2434ed00fb4bb000000000000000000000000076766ce199954d2dc52e14577e2434ed00fb4bb00000000000000000000000000000000000000000000000000001dab777c54d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a31e57d956e539de434d1c7d8685c4971bd6fb80000000000000000000000007a31e57d956e539de434d1c7d8685c4971bd6fb8000000000000000000000000000000000000000000000000001e63e0cca6755900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003bfcfcb32ff59f173d834fa3b354d0bb7c86956f0000000000000000000000003bfcfcb32ff59f173d834fa3b354d0bb7c86956f000000000000000000000000000000000000000000000000000e045c4cff80e500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10389,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e1c63ce6d149b35ed6daba02cc354d34c9faa180000000000000000000000001e1c63ce6d149b35ed6daba02cc354d34c9faa1800000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10391,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f8155e3886a9c97013982d38aec63c2193775d30000000000000000000000001f8155e3886a9c97013982d38aec63c2193775d3000000000000000000000000000000000000000000000000000d105fc1be372400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000459a546e809a0e0c62681c37246e38d95953aa54000000000000000000000000459a546e809a0e0c62681c37246e38d95953aa54000000000000000000000000000000000000000000000000000c15529be51da700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000bdf115e1d046d7349a661eaa251d48608e3f939e000000000000000000000000bdf115e1d046d7349a661eaa251d48608e3f939e0000000000000000000000000000000000000000000000000000000001312d0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc390424dfea40cfd543e587990b2b5f7b4cc915000000000000000000000000bc390424dfea40cfd543e587990b2b5f7b4cc915000000000000000000000000000000000000000000000000000c57c32afd240000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b4aead784c4e59ee9d1b317f82603b769bdba982000000000000000000000000b4aead784c4e59ee9d1b317f82603b769bdba98200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000306499ad40e5bdbe11f9a6d033f007ee20fe345a000000000000000000000000306499ad40e5bdbe11f9a6d033f007ee20fe345a0000000000000000000000000000000000000000000000000033edf34cb4da0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033ef01af8b91f84e1c0c6b08bae0c5c4e65b7fc100000000000000000000000033ef01af8b91f84e1c0c6b08bae0c5c4e65b7fc1000000000000000000000000000000000000000000000000000d1b7004b4446000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fee36c9f72e1da974805789a8b5733653d679b80000000000000000000000002fee36c9f72e1da974805789a8b5733653d679b8000000000000000000000000000000000000000000000000002588b8679d0d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f109367d4ace9ae46031b69edd5412f892d3d1d7000000000000000000000000f109367d4ace9ae46031b69edd5412f892d3d1d70000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001afb2264e1bbbf65f452626328d040eefcb92e0c0000000000000000000000001afb2264e1bbbf65f452626328d040eefcb92e0c000000000000000000000000000000000000000000000000000d380f258d8c0700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5bd1f7a3dac45018d73f1214b87363801af7ede000000000000000000000000a5bd1f7a3dac45018d73f1214b87363801af7ede000000000000000000000000000000000000000000000000000d60bc5d1e387200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10409,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000fe4cc87fe5cbf2fc26bf1884538ec47b5aaf012000000000000000000000000000000000000000000000000004cfb4352ddefe9,0xaa820607003db3ab74700a02f2629c7c02600022c8c0a91416627ab1c8e78d4c,2022-04-27 09:18:18.000 UTC,0,true +10410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc9aefd6d7f074c382f193546a79491eb421a80b000000000000000000000000dc9aefd6d7f074c382f193546a79491eb421a80b00000000000000000000000000000000000000000000000000ae953c13ad3bdb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc6c17eacee54c466f081689975a861c0a7698ff000000000000000000000000dc6c17eacee54c466f081689975a861c0a7698ff00000000000000000000000000000000000000000000000000310658aa6c335b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10413,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095529429a073b6fe1c6b21a6d92ba9879fafbdee00000000000000000000000095529429a073b6fe1c6b21a6d92ba9879fafbdee000000000000000000000000000000000000000000000000007e49daa7c5d10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10414,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000758a1e3e12ef6c74d77b4320ea4ef017ad5a4fc4000000000000000000000000758a1e3e12ef6c74d77b4320ea4ef017ad5a4fc400000000000000000000000000000000000000000000000000473f64cde6048000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10415,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e591a4be7dea045f49159cf671ed41f55191dbb1000000000000000000000000e591a4be7dea045f49159cf671ed41f55191dbb10000000000000000000000000000000000000000000000000021e3293f9efd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000047c4df460eec9929bd791792f018a795b306a2a000000000000000000000000047c4df460eec9929bd791792f018a795b306a2a000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5584e0a5e18c086e20f28eef05dcb6be676c555000000000000000000000000e5584e0a5e18c086e20f28eef05dcb6be676c55500000000000000000000000000000000000000000000000000222fe6fa62056e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7e76789cc5d88a7214c5c32121f4d1e2f0c2f77000000000000000000000000f7e76789cc5d88a7214c5c32121f4d1e2f0c2f77000000000000000000000000000000000000000000000000015b8bc5b8f0535400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x68e3c3c3665281b703e7b7596aed47a0f1601edadba36f038b70a3d8b5671f5b,2021-12-11 11:00:54.000 UTC,0,true +10420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ccf5ef7c438b95aea40b320ac03e4c9fceba2c70000000000000000000000005ccf5ef7c438b95aea40b320ac03e4c9fceba2c700000000000000000000000000000000000000000000000000018b369621c10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10423,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f81ccb8e57b2ed0adcaf8b897c9a0f02a129189c000000000000000000000000f81ccb8e57b2ed0adcaf8b897c9a0f02a129189c000000000000000000000000000000000000000000000000006cfe6cc923b13800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009628f11c8fbf15df1307ad5284398ad7dcdf573c0000000000000000000000009628f11c8fbf15df1307ad5284398ad7dcdf573c000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10426,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072187a33d6f951afc3c1d7755b605f02fa498b2d00000000000000000000000072187a33d6f951afc3c1d7755b605f02fa498b2d0000000000000000000000000000000000000000000000000157ee701579a06400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000efdb6a72c4481baf344d128822e8904f1f9d1720000000000000000000000000efdb6a72c4481baf344d128822e8904f1f9d17200000000000000000000000000000000000000000000000000a7edf0d93cac1300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af7075810810db4f9a248946f5d4cdd165df4a68000000000000000000000000af7075810810db4f9a248946f5d4cdd165df4a6800000000000000000000000000000000000000000000000000599235cec2c53f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000662402017f2b470c0bc3cd2eec7d5aba295e5a80000000000000000000000000662402017f2b470c0bc3cd2eec7d5aba295e5a800000000000000000000000000000000000000000000000000031281ea042f4cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000190145bf14bb40dd7b0ba8ed664c43cd6cbe2a88000000000000000000000000190145bf14bb40dd7b0ba8ed664c43cd6cbe2a88000000000000000000000000000000000000000000000000004546dea969c30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9d67ddaaa7b695c4e10b24950dae1b992addae8000000000000000000000000b9d67ddaaa7b695c4e10b24950dae1b992addae80000000000000000000000000000000000000000000000000045aea0904cfc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ed688a91f3a1a466a719dfd933e32cdd69fe92a0000000000000000000000002ed688a91f3a1a466a719dfd933e32cdd69fe92a000000000000000000000000000000000000000000000000019bf74f7eb51a2d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdefae79ca8c7ee5c7d34e45d4a63453dbc0363c000000000000000000000000bdefae79ca8c7ee5c7d34e45d4a63453dbc0363c000000000000000000000000000000000000000000000000000ecd47e32dcd7c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10438,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006abc41db02e8a2eb9bdd6fc4095325f0b2b721360000000000000000000000006abc41db02e8a2eb9bdd6fc4095325f0b2b7213600000000000000000000000000000000000000000000000000254db1c224400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf1d8a0504262f9f66ffa62beacc4102be4661f8000000000000000000000000bf1d8a0504262f9f66ffa62beacc4102be4661f8000000000000000000000000000000000000000000000000000d0c2e31ae3dfe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e695566c9ac320367556a16af50cd272d577c7f0000000000000000000000009e695566c9ac320367556a16af50cd272d577c7f000000000000000000000000000000000000000000000000015e565549ac8b6700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000feefe20c0f5627ecd1b7b0f6d2a9a5ff0e64d3ab000000000000000000000000feefe20c0f5627ecd1b7b0f6d2a9a5ff0e64d3ab000000000000000000000000000000000000000000000000000e098a21e3f27400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10443,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e7197e7cca2355b83a33e345bc6a65c722d03630000000000000000000000001e7197e7cca2355b83a33e345bc6a65c722d036300000000000000000000000000000000000000000000000000011563f569ae0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001efabc745a24d9b957dc383f2e422203c4f2889f0000000000000000000000001efabc745a24d9b957dc383f2e422203c4f2889f000000000000000000000000000000000000000000000000000abcc4d43595c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c19d05ae498b8143a14463eb78b84a4cd71b7d53000000000000000000000000c19d05ae498b8143a14463eb78b84a4cd71b7d53000000000000000000000000000000000000000000000000000dbc30fd03389900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000256ff537f23af82ad81ab9d9f5af0135a9fc6f29000000000000000000000000256ff537f23af82ad81ab9d9f5af0135a9fc6f290000000000000000000000000000000000000000000000000156b2164c3106df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ebf7b028d7388828c806d6dd79d776fe39e19e3c000000000000000000000000ebf7b028d7388828c806d6dd79d776fe39e19e3c000000000000000000000000000000000000000000000000001f322b984cad2200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d89b1bd184f350fdf7d14e7158b184deb236f999000000000000000000000000d89b1bd184f350fdf7d14e7158b184deb236f999000000000000000000000000000000000000000000000000000dd67a35380b2b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000004df622c2d7df728960230ec203e833034cac84610000000000000000000000004df622c2d7df728960230ec203e833034cac84610000000000000000000000000000000000000000000000000000000002faf08000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10450,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000477693335ab58bbd009b6b796f5bbeb13bd10cd0000000000000000000000000477693335ab58bbd009b6b796f5bbeb13bd10cd0000000000000000000000000000000000000000000000000000e59f15c94493a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc3bd9d13fea7ffff52b7d2e32cd64a8cf1387f3000000000000000000000000bc3bd9d13fea7ffff52b7d2e32cd64a8cf1387f3000000000000000000000000000000000000000000000000000d45234dbafca800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10453,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b684e3800bd805c14b52031467c3c42373ad65f8000000000000000000000000b684e3800bd805c14b52031467c3c42373ad65f80000000000000000000000000000000000000000000000000068de98d2dcf70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab11283c156a1703a4f5e1aa42e9780d52bcf73f000000000000000000000000ab11283c156a1703a4f5e1aa42e9780d52bcf73f000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017680a3936ff75d52535d1e33d3e68c647e48a3300000000000000000000000017680a3936ff75d52535d1e33d3e68c647e48a33000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10458,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2a7262fc073aac863e3e48e3bcb00558093bff3000000000000000000000000a2a7262fc073aac863e3e48e3bcb00558093bff3000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093dde3d39f3154adf86a9ab0ae6397363fc590cd00000000000000000000000093dde3d39f3154adf86a9ab0ae6397363fc590cd000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004156507bf3ade70dfa9e682b4cb1cdd8b24e705a0000000000000000000000004156507bf3ade70dfa9e682b4cb1cdd8b24e705a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10461,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2f56984239bcb2d062bc7788ec5aab25f686fbb000000000000000000000000b2f56984239bcb2d062bc7788ec5aab25f686fbb000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000248f389281687095198ccceb16fd2b92efc8b7bd000000000000000000000000248f389281687095198ccceb16fd2b92efc8b7bd0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000255c391f2c1c64bc135fb394362bf310e09f3328000000000000000000000000255c391f2c1c64bc135fb394362bf310e09f33280000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10464,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000a9a64cb1b4119f8db3ee530702190aa10694c24d000000000000000000000000a9a64cb1b4119f8db3ee530702190aa10694c24d000000000000000000000000000000000000000000000000000000000633d64100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbe9c1b0f02686a8402ec81e347779a564c09c84000000000000000000000000fbe9c1b0f02686a8402ec81e347779a564c09c84000000000000000000000000000000000000000000000000000be4d61616648f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000256aa98410eb7b35bf24ee99e7524024d99a26ad000000000000000000000000256aa98410eb7b35bf24ee99e7524024d99a26ad0000000000000000000000000000000000000000000000000078cd007cd583ae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10468,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019971072299d8b90fdaa3db41ba90fc0025f914000000000000000000000000019971072299d8b90fdaa3db41ba90fc0025f9140000000000000000000000000000000000000000000000000000d56053960c04100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd2dc5fb8b6222d9f743b3eeec059790c07ca2a4000000000000000000000000bd2dc5fb8b6222d9f743b3eeec059790c07ca2a40000000000000000000000000000000000000000000000000005a1e6918c630000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf4b2306c778e05583a70e8292cd8b249d2f8b23000000000000000000000000cf4b2306c778e05583a70e8292cd8b249d2f8b23000000000000000000000000000000000000000000000000000ce808aa26c15400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e17e0015b6ca59718544629173ef950f71b58bf9000000000000000000000000e17e0015b6ca59718544629173ef950f71b58bf9000000000000000000000000000000000000000000000000000cd2b6fc03d92a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8c61ac44459438cc507a374e4d795bf02dd55ba000000000000000000000000a8c61ac44459438cc507a374e4d795bf02dd55ba00000000000000000000000000000000000000000000000001988fe4052b800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021e23a038552857d2c4618b025e62c1a800bf52900000000000000000000000021e23a038552857d2c4618b025e62c1a800bf529000000000000000000000000000000000000000000000000015c2a7b13fd000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000710adece5ee716c3607352ea34736fe0a186b16b000000000000000000000000710adece5ee716c3607352ea34736fe0a186b16b000000000000000000000000000000000000000000000000000c6fc30ab9230b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10477,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003324e3701dbc3143b39ca02e3c72b88d9757cf7b0000000000000000000000003324e3701dbc3143b39ca02e3c72b88d9757cf7b000000000000000000000000000000000000000000000000000dce63a989b4e100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10478,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3be5ba3ada495ee2977e624347db8a2a79a10f7000000000000000000000000a3be5ba3ada495ee2977e624347db8a2a79a10f700000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10481,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037e7262cb909dd674e102ed54d186e27b371c88f00000000000000000000000037e7262cb909dd674e102ed54d186e27b371c88f000000000000000000000000000000000000000000000000005cd319724f977100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7430ed0891ec4564e91ebcddc1ced1ef35ce12087e9d8292a6cd82be3dbdc736,2022-05-15 04:58:05.000 UTC,0,true +10482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e0bb9621fe9260272fa3bb754d6ad2e6d93062d0000000000000000000000004e0bb9621fe9260272fa3bb754d6ad2e6d93062d000000000000000000000000000000000000000000000000000c6fe94b550f2400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10483,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2d9240c737c2db2acacbe96d925d701893bac4d000000000000000000000000a2d9240c737c2db2acacbe96d925d701893bac4d0000000000000000000000000000000000000000000000000038f020adcc529600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10484,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002d66f67924d41f82c5cb76f83bd08511b8c543b10000000000000000000000002d66f67924d41f82c5cb76f83bd08511b8c543b10000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007657b4ea5812f03232e553549ab93f54c2d38c100000000000000000000000007657b4ea5812f03232e553549ab93f54c2d38c1000000000000000000000000000000000000000000000000000c87b79f6e99e700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10487,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051cc2245a1ef254091b081221096ca8df45410a800000000000000000000000051cc2245a1ef254091b081221096ca8df45410a8000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10488,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffd7e2c88dabcdcd2c8525dfb53f133084e64c4a000000000000000000000000ffd7e2c88dabcdcd2c8525dfb53f133084e64c4a000000000000000000000000000000000000000000000000000b386ae4b49d6a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10489,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d06cb12b9c761bb73707b180637f13d08e495b71000000000000000000000000d06cb12b9c761bb73707b180637f13d08e495b71000000000000000000000000000000000000000000000000000c4ea07e3c82c500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f88196d9a8eab8c950d8233271268f9e47a26405000000000000000000000000f88196d9a8eab8c950d8233271268f9e47a26405000000000000000000000000000000000000000000000000000c8858a0eb0aed00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083e91c72cd9fb3ab637c285127a46590cb7d3c9700000000000000000000000083e91c72cd9fb3ab637c285127a46590cb7d3c97000000000000000000000000000000000000000000000000000b8a3f66289b2500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007aaabbafdd47479d9f6a57470b83a65169b9e15b0000000000000000000000007aaabbafdd47479d9f6a57470b83a65169b9e15b000000000000000000000000000000000000000000000000000c36ad0f6c0a6600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10493,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009eb832fcc5bf2d7f29863f508c21d63fb11d1f430000000000000000000000009eb832fcc5bf2d7f29863f508c21d63fb11d1f43000000000000000000000000000000000000000000000000000cf0498673fac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa2500bc101fdadb2226a2e41e597f28cdac39c1000000000000000000000000aa2500bc101fdadb2226a2e41e597f28cdac39c1000000000000000000000000000000000000000000000000000d9a62a278ef6b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000549b8995b9701126dd48b8dc0b46299273714c60000000000000000000000000549b8995b9701126dd48b8dc0b46299273714c600000000000000000000000000000000000000000000000001176a5c84ee058000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e8166910000000000000000000000005c3d205052b1b081b2d31b8a9caad7a7dea6690c0000000000000000000000005c3d205052b1b081b2d31b8a9caad7a7dea6690c00000000000000000000000000000000000000000000000019db110828b7993200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10497,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5860fb66477149695d65c3dbf3483a89853398d000000000000000000000000b5860fb66477149695d65c3dbf3483a89853398d0000000000000000000000000000000000000000000000000098c445ad57800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7ce80b7681693de60bc0e1e5d5ad37080523990000000000000000000000000a7ce80b7681693de60bc0e1e5d5ad3708052399000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000683cb0cfb74d7ae69af0b1b7c747fe916bd51612000000000000000000000000683cb0cfb74d7ae69af0b1b7c747fe916bd51612000000000000000000000000000000000000000000000000003d6c3e0395d93700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10501,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000239884357cdf794825d17433d7e53f2a2dd282f6000000000000000000000000239884357cdf794825d17433d7e53f2a2dd282f60000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xc70d8e9f68f5fbc6675ee7cec19d2a45eb2b2ef83026c388f55e20f3a74e13b0,2022-02-25 11:13:44.000 UTC,0,true +10504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000e8ea1dcaf34ca901b9702d32cf47cc4ad5fad63b000000000000000000000000e8ea1dcaf34ca901b9702d32cf47cc4ad5fad63b000000000000000000000000000000000000000000000000000000004d408f6d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10506,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000884fd3cc1440ab13451fbbab18317b784930e7f2000000000000000000000000884fd3cc1440ab13451fbbab18317b784930e7f20000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10507,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f82e9b159e39dbac277bd3041be6b1e240676fa6000000000000000000000000f82e9b159e39dbac277bd3041be6b1e240676fa60000000000000000000000000000000000000000000000000053d101b53d989000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10508,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000006b77ba93c90918e8183015e1d34ea560849c65d20000000000000000000000006b77ba93c90918e8183015e1d34ea560849c65d200000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10509,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000087e897fe3270ceaf6d6fda5d7244a9656814d4c4000000000000000000000000000000000000000000000000165b2c3acd098ef4,,,1,true +10511,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030a07e234288d0f0da72222f76b9f838d8f35f2d00000000000000000000000030a07e234288d0f0da72222f76b9f838d8f35f2d00000000000000000000000000000000000000000000000000482515a12529b900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10512,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000c0f6e714ea96c4b984e03ef848b50e2ad5c1a450000000000000000000000000c0f6e714ea96c4b984e03ef848b50e2ad5c1a450000000000000000000000000000000000000000000000000000000009740b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xba38e66c9e7f453fd9c074496c2066714d62cfa797149f60880217d696acb3ec,2022-08-25 06:53:31.000 UTC,0,true +10513,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000626a06dfd07e6c74ad68ee1ccad71db0081f7069000000000000000000000000626a06dfd07e6c74ad68ee1ccad71db0081f7069000000000000000000000000000000000000000000000000000000000814c96000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x9e901d5a425313528d890a106cf0b51d487b1a5d55e7e8be17f4344b9df35e37,2022-08-24 06:15:50.000 UTC,0,true +10515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000682057e6e33d5d7beff7d95215273abe218b02b9000000000000000000000000682057e6e33d5d7beff7d95215273abe218b02b900000000000000000000000000000000000000000000000000007c923688bb8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb165605142b60ef97688dc8890cebda3a31b694000000000000000000000000cb165605142b60ef97688dc8890cebda3a31b6940000000000000000000000000000000000000000000000000000a32de099514000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10517,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000004bad03f2cf3e05dcd033b19cfc5da26a05a2d5700000000000000000000000004bad03f2cf3e05dcd033b19cfc5da26a05a2d57000000000000000000000000000000000000000000000000000000000848f8c000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x27cf4d03d91db3520338bb12d1eff2faa381bfa0ba18a518c15a5640d78273e1,2022-08-22 06:07:25.000 UTC,0,true +10518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000073a0afc565454f4618d07732a79471d60486338a00000000000000000000000073a0afc565454f4618d07732a79471d60486338a00000000000000000000000000000000000000000000000000000000081b320000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xfc9bfe03844c563a153037d86c44fc92202695976d2b99e2b502d9db13b48aa9,2022-08-22 07:07:53.000 UTC,0,true +10519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c677d82671ab99fb881d7bd22d597d29c7b5ae60000000000000000000000000c677d82671ab99fb881d7bd22d597d29c7b5ae6000000000000000000000000000000000000000000000000003f3d6c9baf193c300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10520,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000009b9c9bc11ece77edbead7d545eb9d1ca6bd115d00000000000000000000000009b9c9bc11ece77edbead7d545eb9d1ca6bd115d00000000000000000000000000000000000000000000000000000000074096ab00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xdfae0b1dd1347b0aaac615c011664c988e9ba287d9ff18e6695eebdadc120147,2022-08-23 07:02:18.000 UTC,0,true +10521,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e818f9e0023a1a19c0da79a33b8d02dd993006ea000000000000000000000000e818f9e0023a1a19c0da79a33b8d02dd993006ea00000000000000000000000000000000000000000000000000a595b521f57dd400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x18aa0dd5c651a7cc4efa53bd41d487dc73b1260f24eee57734fcfdfcab2c905f,2022-03-09 14:38:36.000 UTC,0,true +10522,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e17c5cec6cb7587c28f2b9a16a93c97e4d93e871000000000000000000000000e17c5cec6cb7587c28f2b9a16a93c97e4d93e8710000000000000000000000000000000000000000000000000032cdc63449c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9b7dc8ee74002073518c84ec070c46d77659d281a9125a4b468e62c9cef2e4ed,2022-06-20 22:48:49.000 UTC,0,true +10523,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0e2e1edbe4029e55bd217f82724420023b90cd4000000000000000000000000b0e2e1edbe4029e55bd217f82724420023b90cd4000000000000000000000000000000000000000000000000004411d696c3ebb200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000912026a2b3c52984830a1848ef5828d1dccc0c0b000000000000000000000000912026a2b3c52984830a1848ef5828d1dccc0c0b0000000000000000000000000000000000000000000000000021f9d07a4f900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb3e80fbfa8bfc01b732523605a5f456dec59f38bf7841ddc57128f9081bfdb77,2022-05-28 21:46:40.000 UTC,0,true +10529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000349ea0b723e3692a2ddcc0ae5cc85640f372ffd1000000000000000000000000349ea0b723e3692a2ddcc0ae5cc85640f372ffd1000000000000000000000000000000000000000000000000005af5a38e20373900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10530,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007394dd6e970ecce75b1c36631c170d66aa172fc60000000000000000000000007394dd6e970ecce75b1c36631c170d66aa172fc60000000000000000000000000000000000000000000000000001c77c45f0ed0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1453c1310846ec5ba080fcb1d3e128e9d124745000000000000000000000000d1453c1310846ec5ba080fcb1d3e128e9d124745000000000000000000000000000000000000000000000000007e6f918cce6e5100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2fc64900dc0591e2bc8d8dcca8f758115bab519000000000000000000000000a2fc64900dc0591e2bc8d8dcca8f758115bab51900000000000000000000000000000000000000000000000000ad0b7ac8eb48f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0070034200f7acf6ef113110b661f31c2f46a5ece2cbbe4b1be864448e7edd0e,2022-04-25 09:07:01.000 UTC,0,true +10536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000b2dd50d400d4e82768c4204bad49cde6186356e5000000000000000000000000b2dd50d400d4e82768c4204bad49cde6186356e5000000000000000000000000000000000000000000000000000000003c0c43f500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x22985cd7f07143938f0b0c1767d52715335bd4c0d2a2cadb87e9a1d751263bb2,2022-04-30 04:55:41.000 UTC,0,true +10537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000001d3476db54dd1058b6d8a5bf8748cf1b8a7813e90000000000000000000000001d3476db54dd1058b6d8a5bf8748cf1b8a7813e90000000000000000000000000000000000000000000000000000000044d7081800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x4fe5f45375db48c4c88b130bf8a0131be183ce0e6d823c43f3e6e88660895d4e,2022-04-29 08:54:00.000 UTC,0,true +10540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000230221cae667969b423a3cf335891f30b1829caa000000000000000000000000230221cae667969b423a3cf335891f30b1829caa00000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d308cc699614de8cf75c89f7ea6c604a59f216c2000000000000000000000000d308cc699614de8cf75c89f7ea6c604a59f216c2000000000000000000000000000000000000000000000000001fcb992932d3a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c184e921d0c51ea0c12194050f2791d23f991f68000000000000000000000000c184e921d0c51ea0c12194050f2791d23f991f680000000000000000000000000000000000000000000000000374fead7ea2e92d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10546,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f275599564fd00281c450ee6c50f03214fce8960000000000000000000000007f275599564fd00281c450ee6c50f03214fce8960000000000000000000000000000000000000000000000000003f53fbd6e500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ca58d8c7635e1f555aaa1bc522e4b9be477a0ed0000000000000000000000004ca58d8c7635e1f555aaa1bc522e4b9be477a0ed00000000000000000000000000000000000000000000000001aa535d3d0c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064e6d480acc5944c90e4c7d04f56f8099f6d317300000000000000000000000064e6d480acc5944c90e4c7d04f56f8099f6d3173000000000000000000000000000000000000000000000000015a31782aad37be00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7d865c7c63d758db991b191e9c80c3867b34b8e000000000000000000000000b7d865c7c63d758db991b191e9c80c3867b34b8e0000000000000000000000000000000000000000000000000033c4d66561629d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085ae5cade318b59742c490fc07490e298a4e6d8400000000000000000000000085ae5cade318b59742c490fc07490e298a4e6d84000000000000000000000000000000000000000000000000001a8e16e89354b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1a3fdae3c2f48f3b943cc2c1234e4b3d77a1d6e000000000000000000000000b1a3fdae3c2f48f3b943cc2c1234e4b3d77a1d6e00000000000000000000000000000000000000000000000000857179ebcc3c4900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ea9b8ba0d889ba42458f657ed27244ad593dfe70000000000000000000000007ea9b8ba0d889ba42458f657ed27244ad593dfe7000000000000000000000000000000000000000000000000004fb3de9058e0db00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000748bef7395e2559d83374e820e598213dd547773000000000000000000000000748bef7395e2559d83374e820e598213dd5477730000000000000000000000000000000000000000000000000066819177a2487d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fddbc85a20014ee4e6cad2fcd1b925ae6cd5f61b000000000000000000000000fddbc85a20014ee4e6cad2fcd1b925ae6cd5f61b00000000000000000000000000000000000000000000000000c6f3b40b6c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bce09efa4d3297e63f4deb685c2cf73af0019617000000000000000000000000bce09efa4d3297e63f4deb685c2cf73af00196170000000000000000000000000000000000000000000000000000dde123eb400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057aa3edb78fea6a5adb99e285597d7a8edcc41f400000000000000000000000057aa3edb78fea6a5adb99e285597d7a8edcc41f4000000000000000000000000000000000000000000000000005f264b590d273c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10568,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000854d7b23d48377b2e658685909668b7683f5d983000000000000000000000000854d7b23d48377b2e658685909668b7683f5d983000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10571,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ec6295bf707b896efe73fb9f9a8aca0855c22460000000000000000000000006ec6295bf707b896efe73fb9f9a8aca0855c22460000000000000000000000000000000000000000000000000070413f59fa067900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d70804c92a0660bc8e6420e6755f87cb96f5bd4e000000000000000000000000d70804c92a0660bc8e6420e6755f87cb96f5bd4e000000000000000000000000000000000000000000000000004214e94911e3b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10591,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8c907430e1ed83797e0a8bf1eda14a8087cac92000000000000000000000000e8c907430e1ed83797e0a8bf1eda14a8087cac92000000000000000000000000000000000000000000000000005905de0ba3703700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10593,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f973582d2966d752285caacd17e153b393914357000000000000000000000000f973582d2966d752285caacd17e153b39391435700000000000000000000000000000000000000000000000000bc4b381d18800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10596,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad5fddadf2507c54115b1d7fca7d1e5885edfaaa000000000000000000000000ad5fddadf2507c54115b1d7fca7d1e5885edfaaa000000000000000000000000000000000000000000000000001f2a397460490000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10597,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d880ec117a107eec557ebb84dfa7e88a69a2377a0000000000000000000000000000000000000000000000391207eb67e7b78540,,,1,true +10599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f436f60887a30a44a1bf4c935dda240121eedaf1000000000000000000000000f436f60887a30a44a1bf4c935dda240121eedaf1000000000000000000000000000000000000000000000000000e8b90a4e56e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10600,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c805ef4eef0b47a7084530603fb41225e24da42f000000000000000000000000c805ef4eef0b47a7084530603fb41225e24da42f000000000000000000000000000000000000000000000000000f1c277a4f9d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10601,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af8ffe93bc58efe850fee556ccca7698927a2112000000000000000000000000af8ffe93bc58efe850fee556ccca7698927a2112000000000000000000000000000000000000000000000000007b43635b4d0f9800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10602,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052bbcd3ebfd6183852ee91b39efd5a07caa0d50000000000000000000000000052bbcd3ebfd6183852ee91b39efd5a07caa0d50000000000000000000000000000000000000000000000000000772a204ba62fee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10604,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003317b15136eaa9e17ffadad0aa911fb8ec37e7690000000000000000000000003317b15136eaa9e17ffadad0aa911fb8ec37e769000000000000000000000000000000000000000000000000004281813a5a123700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10605,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000788600fac3c4e2f72ce0961827442b310b5f4f62000000000000000000000000788600fac3c4e2f72ce0961827442b310b5f4f62000000000000000000000000000000000000000000000000002d5d5dc048abd500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10608,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006fb57707d462679fd44a22a5afeb965f201fefd50000000000000000000000006fb57707d462679fd44a22a5afeb965f201fefd50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a19c369eeae40e88c75cea6583c57962f88f061c000000000000000000000000a19c369eeae40e88c75cea6583c57962f88f061c0000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10610,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007209533bac94838146af34bdc4d97af96e6a42ca0000000000000000000000007209533bac94838146af34bdc4d97af96e6a42ca0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10611,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b1fe2cbc08935d3bc4f4e0f3bcc61296312e5d70000000000000000000000002b1fe2cbc08935d3bc4f4e0f3bcc61296312e5d70000000000000000000000000000000000000000000000000007d0e36a81800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10612,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017549fed7c40297742e14ae86d75e99627c9686100000000000000000000000017549fed7c40297742e14ae86d75e99627c96861000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10613,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f21050d9e3f52eafee77eeccf753d20a0bcbc5ff000000000000000000000000f21050d9e3f52eafee77eeccf753d20a0bcbc5ff0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10614,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae61eefc847e057d08dce23f7a1f7dddbf2f3783000000000000000000000000ae61eefc847e057d08dce23f7a1f7dddbf2f378300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10616,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d15472d58e1bf8fbfa4a9f87c5f3d4108d965b8f000000000000000000000000000000000000000000000017c1f1c18e6c8bc583,0x8553b02a7a241a02994414581bf56cf2dd1b762f5bab83bcd5897412a774edd5,2022-01-29 10:20:17.000 UTC,0,true +10617,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea3088c92ccf0874c6a13062745fc6b1552a1a87000000000000000000000000ea3088c92ccf0874c6a13062745fc6b1552a1a87000000000000000000000000000000000000000000000000000245d5b034760000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10618,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10619,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000206884cad656298f3cb333b4a9afaadd085381e8000000000000000000000000206884cad656298f3cb333b4a9afaadd085381e800000000000000000000000000000000000000000000000000169f974d37920000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10620,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a01760f3a473ef7d917fe48a39a99e648089d2b0000000000000000000000005a01760f3a473ef7d917fe48a39a99e648089d2b00000000000000000000000000000000000000000000000000ab85862f797f1200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ccd71558efe1fcf62ae92c033fb710b626036e00000000000000000000000009ccd71558efe1fcf62ae92c033fb710b626036e000000000000000000000000000000000000000000000000000aae0bbc225b5b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc057389c91718fc4052ad5102e8aad21e33151a234933c7e20259c0218698fe9,2021-12-12 08:54:48.000 UTC,0,true +10622,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008469ad2042364ad39d0318849c6865e435c527230000000000000000000000008469ad2042364ad39d0318849c6865e435c52723000000000000000000000000000000000000000000000000004bd5997de745b400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039626030e577b306a931772d553bbbfc941295bc00000000000000000000000039626030e577b306a931772d553bbbfc941295bc00000000000000000000000000000000000000000000000000228f9def75ef9f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5cee6dd64166899a5fd92d9f2bb6a6c407f3ffb000000000000000000000000a5cee6dd64166899a5fd92d9f2bb6a6c407f3ffb000000000000000000000000000000000000000000000000003707e3732583a200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9fef11e493a712dc9b3b9f9d970bee8a763f177000000000000000000000000c9fef11e493a712dc9b3b9f9d970bee8a763f177000000000000000000000000000000000000000000000000003fae3c9139be3000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f31241fdd27965db448393e80bc8a6cc107c1e70000000000000000000000000f31241fdd27965db448393e80bc8a6cc107c1e700000000000000000000000000000000000000000000000000041a8308b94c50e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fafd58b0f488a6df3d583ee684ca2b77049b0c90000000000000000000000000fafd58b0f488a6df3d583ee684ca2b77049b0c9000000000000000000000000000000000000000000000000003742d4b208a5c900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10630,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b709fba2035eb9941afc53f21acf2c4f78cda8b0000000000000000000000000b709fba2035eb9941afc53f21acf2c4f78cda8b000000000000000000000000000000000000000000000000000ad55b9cef52f0500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072dc02b8168f36d2d51fd40a6b8a553eeb638a8500000000000000000000000072dc02b8168f36d2d51fd40a6b8a553eeb638a8500000000000000000000000000000000000000000000000000290f90fd5169ef00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a26429316a286f629c2833db44f780f3092ee480000000000000000000000002a26429316a286f629c2833db44f780f3092ee480000000000000000000000000000000000000000000000000041084dff6409c900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f8fc4816bbb2c992a149cdacd05f7839663e6ff0000000000000000000000004f8fc4816bbb2c992a149cdacd05f7839663e6ff00000000000000000000000000000000000000000000000001f9e80ba804000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0ae3197635e6f4106515050800feecb61de79b0000000000000000000000000e0ae3197635e6f4106515050800feecb61de79b0000000000000000000000000000000000000000000000000003ff6627eec8ac100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10636,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064e143009e01fc9887779a80256e2b65771e8a1c00000000000000000000000064e143009e01fc9887779a80256e2b65771e8a1c000000000000000000000000000000000000000000000000001bb934ea07b7c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10637,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009bab8a8719351ea0ae583e2c80e869d9926f27830000000000000000000000009bab8a8719351ea0ae583e2c80e869d9926f27830000000000000000000000000000000000000000000000000030071d0b858f8900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000215836ae9dbe97fba1f18bf6ff6a2ebf0f6a98d2000000000000000000000000215836ae9dbe97fba1f18bf6ff6a2ebf0f6a98d20000000000000000000000000000000000000000000000000011c2f60abd428000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10639,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f170020148f41ba8e0e00b43cf6a807090c9f970000000000000000000000002f170020148f41ba8e0e00b43cf6a807090c9f9700000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10640,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000512298d291dc51246db4c7a8fd4079b3e384524d000000000000000000000000512298d291dc51246db4c7a8fd4079b3e384524d00000000000000000000000000000000000000000000000000ab9eeb8fd3645500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xfdf38331b64e54a4ccb4ec7172e6feda3d894b43cda27ef7b2467c4e323dc7b6,2021-12-12 08:58:00.000 UTC,0,true +10641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006f8fb853d9aec922fc467cb09837042a858760100000000000000000000000006f8fb853d9aec922fc467cb09837042a858760100000000000000000000000000000000000000000000000000ba8c309f6f5f4100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052d0fc1cab209eebbff485b93fe7d8d88f6c0d2900000000000000000000000052d0fc1cab209eebbff485b93fe7d8d88f6c0d290000000000000000000000000000000000000000000000000853a0d2313c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x97349f6f704e26d991eb01e711fefbf20e7e225c05a75bb89882b9f2aead1acf,2021-12-13 00:54:06.000 UTC,0,true +10643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a77d40ab6ccfb109291ac584087cee05438b8830000000000000000000000002a77d40ab6ccfb109291ac584087cee05438b883000000000000000000000000000000000000000000000000001172465f55c65800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10645,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2039de34d52fcbc6f7ffcb30c16048af919aaf7000000000000000000000000c2039de34d52fcbc6f7ffcb30c16048af919aaf700000000000000000000000000000000000000000000000000714006c9390b5400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10650,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d03aea34ffefd6af6cc154b3f03501ae083fb920000000000000000000000004d03aea34ffefd6af6cc154b3f03501ae083fb92000000000000000000000000000000000000000000000000136dcc951d8c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10651,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c8289523abfa9e2fecc53a73d041adcbb3bea5ab000000000000000000000000c8289523abfa9e2fecc53a73d041adcbb3bea5ab000000000000000000000000000000000000000000000000015a6ebb4c170d7800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a92959842ceecd4a49a36de06d7fde1050c65fb5000000000000000000000000a92959842ceecd4a49a36de06d7fde1050c65fb500000000000000000000000000000000000000000000000000407858abf690c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000283c3524dca01f348303988d98613e5ad61e6d65000000000000000000000000283c3524dca01f348303988d98613e5ad61e6d6500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a2235e33e7ed5e95a508ba2ca6947aa85af4f620000000000000000000000003a2235e33e7ed5e95a508ba2ca6947aa85af4f62000000000000000000000000000000000000000000000000000894d492e2cd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10660,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000505a194a0c4dbb3915f60aa7f949720800738fb1000000000000000000000000505a194a0c4dbb3915f60aa7f949720800738fb100000000000000000000000000000000000000000000000000080bb781b9234000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10661,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073965314f82945b88132330de1dcad4c89c943de00000000000000000000000073965314f82945b88132330de1dcad4c89c943de0000000000000000000000000000000000000000000000000007f36eedb52b4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10662,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb527a976b904307d62d8230b91bf54d219e029a000000000000000000000000bb527a976b904307d62d8230b91bf54d219e029a0000000000000000000000000000000000000000000000000007a6ed36fd3b4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10663,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006663d8b52d878cdc92e8c63e61f4d8c6d13314d70000000000000000000000006663d8b52d878cdc92e8c63e61f4d8c6d13314d7000000000000000000000000000000000000000000000000009faeaa0ae971c200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007da0047f7801d88cd6d3731c75621a2d03eaf4410000000000000000000000007da0047f7801d88cd6d3731c75621a2d03eaf4410000000000000000000000000000000000000000000000000007fabee30d3b4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d88d6c3e5721099a64674a347f145f6859b671f6000000000000000000000000d88d6c3e5721099a64674a347f145f6859b671f600000000000000000000000000000000000000000000000000080eb99815f64000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10666,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ead2cf05f3e772d3345b1daa24bca46b9f809a52000000000000000000000000ead2cf05f3e772d3345b1daa24bca46b9f809a520000000000000000000000000000000000000000000000000007ff2c30a8fe4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10667,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000513644f432e4ce7fb8578617af90cc072ae1f80b000000000000000000000000513644f432e4ce7fb8578617af90cc072ae1f80b0000000000000000000000000000000000000000000000000007ece44b4cd64000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000803aade81954d851c1d72ae5b7204bfa505031b5000000000000000000000000803aade81954d851c1d72ae5b7204bfa505031b500000000000000000000000000000000000000000000000000094bb191baa7e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10669,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026583cf3a90d69277c8c9d46c0fe3734ec7f5d5c00000000000000000000000026583cf3a90d69277c8c9d46c0fe3734ec7f5d5c0000000000000000000000000000000000000000000000000008650de0f7c64000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10670,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9521819a9de0ba71e802a02304dc3c557af2549000000000000000000000000c9521819a9de0ba71e802a02304dc3c557af2549000000000000000000000000000000000000000000000000004b510eade99eba00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10671,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba8c244aeb70d524ecac46fe2f48d80cb66abc6b000000000000000000000000ba8c244aeb70d524ecac46fe2f48d80cb66abc6b0000000000000000000000000000000000000000000000000008a3ece10cb14000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053834efefba6623225ea7b58fa764e76dfe8912c00000000000000000000000053834efefba6623225ea7b58fa764e76dfe8912c0000000000000000000000000000000000000000000000000003f4c999daf74000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10673,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a81742216906c904e9b94ab9872e50993eae4fe0000000000000000000000006a81742216906c904e9b94ab9872e50993eae4fe00000000000000000000000000000000000000000000000000ab76f2164a1f9500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x551d730adbbb91e5661cf74b5d20a3f2d894bd1157c05c6a9e1f92b575c6342a,2021-12-12 08:46:54.000 UTC,0,true +10674,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb1bcb22ea8a88dcb63a4f7e5a00afe6e859f709000000000000000000000000bb1bcb22ea8a88dcb63a4f7e5a00afe6e859f7090000000000000000000000000000000000000000000000000022c466a2035d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10677,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc8afb40b6f6897b66830a763c2c589dcc97136a000000000000000000000000dc8afb40b6f6897b66830a763c2c589dcc97136a000000000000000000000000000000000000000000000000009fd989cee184d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10678,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e993a1f4b615138114825e4055ad9212d5d08680000000000000000000000007e993a1f4b615138114825e4055ad9212d5d086800000000000000000000000000000000000000000000000001bf192137f5338600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5d08bf1a4071bbee69ee3f6bc5ec69724ecbba985c40a257533958e5e0b94b32,2022-03-06 15:01:30.000 UTC,0,true +10679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e8166910000000000000000000000000fdf96094afc4c1f87b24d793af0ba987c1ab6540000000000000000000000000fdf96094afc4c1f87b24d793af0ba987c1ab654000000000000000000000000000000000000000000000003955a98b826e4a42700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10680,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6be3816ca29e641bd532aa089672a0d306e3012000000000000000000000000f6be3816ca29e641bd532aa089672a0d306e301200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d777ad175dd8aba028101fda9c9ed322e34b221e000000000000000000000000d777ad175dd8aba028101fda9c9ed322e34b221e000000000000000000000000000000000000000000000000005529d1d9744b4800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10683,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c84bc2a90de4e0b95fc40a464f364401e13e53800000000000000000000000000000000000000000000000000dc4afd08074d154,,,1,true +10684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006120719070c7f83592c166a056d2c728fb063e4d0000000000000000000000006120719070c7f83592c166a056d2c728fb063e4d0000000000000000000000000000000000000000000000000021dc72f557b50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10686,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d84c2fdf2f8733a5bbea65eec0bb211947792871000000000000000000000000000000000000000000000003db19d6b436d44c3a,,,1,true +10688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003fa0f53fc06dc5d7df77505dea6e96cdd6e99b050000000000000000000000003fa0f53fc06dc5d7df77505dea6e96cdd6e99b0500000000000000000000000000000000000000000000000001253464d17cd85400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10690,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9e197deb88d82e2d45f29c396dbfd94bc8212ea000000000000000000000000c9e197deb88d82e2d45f29c396dbfd94bc8212ea00000000000000000000000000000000000000000000000000830668df772eb000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x70ec5aeaee850328fb932907675776614c2705cc3d362db8858a9ce890948f40,2022-05-14 21:04:54.000 UTC,0,true +10691,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f436f60887a30a44a1bf4c935dda240121eedaf1000000000000000000000000f436f60887a30a44a1bf4c935dda240121eedaf100000000000000000000000000000000000000000000000000004242a72cb60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10692,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031bae26218f30dbbb1db787233fa71fa7d1b8cc000000000000000000000000031bae26218f30dbbb1db787233fa71fa7d1b8cc0000000000000000000000000000000000000000000000000000fe6a29060990000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10693,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000988b5a5e972fbedcba97968f927ed31054715a81000000000000000000000000988b5a5e972fbedcba97968f927ed31054715a81000000000000000000000000000000000000000000000000001007a2d2e9bb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006503558d76d2672b2870883fdf96d45f698c2e000000000000000000000000006503558d76d2672b2870883fdf96d45f698c2e00000000000000000000000000000000000000000000000000000f96edde52220000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10695,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5b241d83c7244861d642e519bc47fd84b4518cd000000000000000000000000f5b241d83c7244861d642e519bc47fd84b4518cd0000000000000000000000000000000000000000000000000010083203c5010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10696,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000548c25259f8652eb25379c6affbcb5b8091d67f1000000000000000000000000548c25259f8652eb25379c6affbcb5b8091d67f10000000000000000000000000000000000000000000000000010083203c5010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000113b448a88727d28cf4f54f27c9c0acab1990f45000000000000000000000000113b448a88727d28cf4f54f27c9c0acab1990f45000000000000000000000000000000000000000000000000000fb403cadc5a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f8afd5b1a75877af89bcd6e0800ae109078576a0000000000000000000000007f8afd5b1a75877af89bcd6e0800ae109078576a000000000000000000000000000000000000000000000000000fb403cadc5a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10699,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e18f002cfeed23e630ca25007905db0197649420000000000000000000000005e18f002cfeed23e630ca25007905db019764942000000000000000000000000000000000000000000000000000fc0999622010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10700,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a969330b6ce9393a8227153e3f7fe7b90314c9d0000000000000000000000004a969330b6ce9393a8227153e3f7fe7b90314c9d000000000000000000000000000000000000000000000000000f823bcea1040000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10701,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017bce7876ea7a11ee9ebd5c00eff32adb4ccb70800000000000000000000000017bce7876ea7a11ee9ebd5c00eff32adb4ccb7080000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10703,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a83e84a9d7073b7f219fb397cc7d512342def56f000000000000000000000000a83e84a9d7073b7f219fb397cc7d512342def56f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa26023bbc43247722e21af76a5c5821a63ae712000000000000000000000000fa26023bbc43247722e21af76a5c5821a63ae7120000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007812ab25fd042bc7cd1b6cc2a51554c3b6ce28b00000000000000000000000007812ab25fd042bc7cd1b6cc2a51554c3b6ce28b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000faf8a58c781476f9a7be7bc9399c39d22243b2f8000000000000000000000000faf8a58c781476f9a7be7bc9399c39d22243b2f80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10708,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006adb60a1683997c914eca540916d44ece685675c0000000000000000000000006adb60a1683997c914eca540916d44ece685675c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10709,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f967d75fd0e579b7cc68568e47663894206d7ef0000000000000000000000008f967d75fd0e579b7cc68568e47663894206d7ef0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10712,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a3cb5b568529b27e93ae726c7d8aef18cd55162100000000000000000000000000000000000000000000000019d72bb383476094,,,1,true +10713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030548feb73b495391e409866e84cceb5adee973000000000000000000000000030548feb73b495391e409866e84cceb5adee9730000000000000000000000000000000000000000000000000001efc410027c5c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ead5e6e90440e69b5f28fef5942a5b273387c130000000000000000000000009ead5e6e90440e69b5f28fef5942a5b273387c13000000000000000000000000000000000000000000000000015ad327aec96a5a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d45b2e4bad581fe6b43cc6d6532487d8986c6d38000000000000000000000000d45b2e4bad581fe6b43cc6d6532487d8986c6d380000000000000000000000000000000000000000000000000044886a2dc3280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000165e4b9ab6cdf7d6920c8594e5ef63cd62255ca7000000000000000000000000165e4b9ab6cdf7d6920c8594e5ef63cd62255ca70000000000000000000000000000000000000000000000000068b4ed1b0d180000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10719,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9f059459e64d3c1d11fa73381f75f297359de40000000000000000000000000d9f059459e64d3c1d11fa73381f75f297359de40000000000000000000000000000000000000000000000000009ce63668caa2ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10720,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b47fee8ff0436deadbf0cb5d65275165967e2c43000000000000000000000000b47fee8ff0436deadbf0cb5d65275165967e2c4300000000000000000000000000000000000000000000000000a90b94052cc6fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10721,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6304410e1e130f092c6a37c7e10811788e6e10d000000000000000000000000d6304410e1e130f092c6a37c7e10811788e6e10d000000000000000000000000000000000000000000000000005250b6b89f6e8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10725,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a1851237ebd4883376d6bd603eca2d169b6f2b20000000000000000000000005a1851237ebd4883376d6bd603eca2d169b6f2b200000000000000000000000000000000000000000000000000337d0ec07ce08f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10727,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071d8e8b2a0098869d60793a2af743e414da22b4600000000000000000000000071d8e8b2a0098869d60793a2af743e414da22b4600000000000000000000000000000000000000000000000000acfb4c0a1d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10731,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c05bc25eaa52a23476e113b9a139a66e7473b3640000000000000000000000000000000000000000000000011d947904d826cfc0,,,1,true +10732,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb61edc2007b476e44be5bbe81486247425e5f8b000000000000000000000000cb61edc2007b476e44be5bbe81486247425e5f8b0000000000000000000000000000000000000000000000000025c548655c4e3300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10735,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b91b076e014a9b127fe2e5084786c27ecaff8409000000000000000000000000000000000000000000000003777cdc3d984bd92b,0x4a6eaf3e6b9e91a4ad73e1c4b52674062fe57653d5202f2d8a86e77b146e3b3c,2022-03-21 06:12:35.000 UTC,0,true +10736,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092765c4301ae115861a79cc015603bc8ce6510c900000000000000000000000092765c4301ae115861a79cc015603bc8ce6510c90000000000000000000000000000000000000000000000000051ba90f3bec35c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d682c7a14f0821c7bf1bd0349210167d394034c0000000000000000000000005d682c7a14f0821c7bf1bd0349210167d394034c00000000000000000000000000000000000000000000000002bc56b04fbe5d0600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009923338e76f7e853d93a3a5a4924f046ec7550e00000000000000000000000009923338e76f7e853d93a3a5a4924f046ec7550e0000000000000000000000000000000000000000000000000402bbf80416800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060606e92777b6097a2c4d19c79433837f725c5bb00000000000000000000000060606e92777b6097a2c4d19c79433837f725c5bb00000000000000000000000000000000000000000000000000217421dd99360000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10760,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d6b74d149c2ed9a43125891308fea3a223694d80000000000000000000000001d6b74d149c2ed9a43125891308fea3a223694d800000000000000000000000000000000000000000000000000d2b6a9390b2e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10763,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000042ba2a84c1440290d9d66bea78248db81c160a6400000000000000000000000042ba2a84c1440290d9d66bea78248db81c160a6400000000000000000000000000000000000000000000000a687c606904d4433a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042103c5793d4998c8da3203e541c7692c0bcb81700000000000000000000000042103c5793d4998c8da3203e541c7692c0bcb81700000000000000000000000000000000000000000000000001510e804f39ea9400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10767,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000834344cfa5956899997fb1a70fd17f7f87572f8d000000000000000000000000834344cfa5956899997fb1a70fd17f7f87572f8d00000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a2c3596d664f5a0e59580c2bd3000fc9a7d5bb20000000000000000000000004a2c3596d664f5a0e59580c2bd3000fc9a7d5bb200000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10769,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093b514be39415f6c746f57de8d7d50d686d7ae3600000000000000000000000093b514be39415f6c746f57de8d7d50d686d7ae360000000000000000000000000000000000000000000000000083af25b864b23900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007c6b4a3202e1ed3f6fe94c78b12ba261968aaa400000000000000000000000007c6b4a3202e1ed3f6fe94c78b12ba261968aaa400000000000000000000000000000000000000000000000001382a0c1448958000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10773,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfe0b47d3155d85318aecdef21caa8adf80e88dc000000000000000000000000bfe0b47d3155d85318aecdef21caa8adf80e88dc000000000000000000000000000000000000000000000000009a11c329b8931e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7fd65b2c3b9a8224ce2af42f646f251d77a0bc186983fe566dcd91a7c8388a07,2022-06-21 09:55:57.000 UTC,0,true +10774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000384fd7b2211b37fbf8506b3e9b29de1c98b5bef1000000000000000000000000384fd7b2211b37fbf8506b3e9b29de1c98b5bef1000000000000000000000000000000000000000000000000007c58508723800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2b8015779ee7294e31f6570302c6ce794eb41c32705867ac5e828ac5e4158e07,2022-06-07 12:49:08.000 UTC,0,true +10776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0628df86fee0fdb325b813c9c3dd8f0ec67e002000000000000000000000000a0628df86fee0fdb325b813c9c3dd8f0ec67e002000000000000000000000000000000000000000000000000000bab94d478990000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0a4cd57ac7e75b92d8b23881e99d73b24946bd4000000000000000000000000f0a4cd57ac7e75b92d8b23881e99d73b24946bd4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d3b8744600da2e200d2a46f676fd5a29b7bd1bc0000000000000000000000000d3b8744600da2e200d2a46f676fd5a29b7bd1bc00000000000000000000000000000000000000000000000000b4133a718b653200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10780,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001053f4b74a78342ed5708dc96482f37bcab5a8b20000000000000000000000001053f4b74a78342ed5708dc96482f37bcab5a8b200000000000000000000000000000000000000000000000001d4341ca057d33600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8a371dc3b89bbb3653992c5b3bafaed1b13c466000000000000000000000000f8a371dc3b89bbb3653992c5b3bafaed1b13c466000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff902bfb0618b5c0b423a09d7aacf41cf86e4937000000000000000000000000ff902bfb0618b5c0b423a09d7aacf41cf86e4937000000000000000000000000000000000000000000000000001aa73708721f5800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10788,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d0b9e7b1054efcbb7dd090ac10c07046f5811260000000000000000000000009d0b9e7b1054efcbb7dd090ac10c07046f58112600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10789,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000088fa395aa8a7b57cff6572fd37b585e1e8ce3dac000000000000000000000000000000000000000000000000136e0e69f5d8d787,,,1,true +10790,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5d779284f4a319621ec7ff1ca88479a6c1308e7000000000000000000000000a5d779284f4a319621ec7ff1ca88479a6c1308e700000000000000000000000000000000000000000000000001edd63133246eca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10791,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf6a2f8247c439ec0b3c61b2546cb05e49c41644000000000000000000000000bf6a2f8247c439ec0b3c61b2546cb05e49c416440000000000000000000000000000000000000000000000000021608e2f9ea40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10793,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3e5497d22d80be71d34a3eaf191426d0b2bb4ba000000000000000000000000b3e5497d22d80be71d34a3eaf191426d0b2bb4ba000000000000000000000000000000000000000000000000013c31074902800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019edc3bead34b13da9a742127b9fa060fc1169db00000000000000000000000019edc3bead34b13da9a742127b9fa060fc1169db0000000000000000000000000000000000000000000000000021c5cbbaa7220000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007286e7d3afa7c56f52e28263e0df68cc016776ad0000000000000000000000007286e7d3afa7c56f52e28263e0df68cc016776ad00000000000000000000000000000000000000000000000000218f8a37919c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076d010682c309037ffc0af9c24b0f3daeb61cb4c00000000000000000000000076d010682c309037ffc0af9c24b0f3daeb61cb4c000000000000000000000000000000000000000000000000002152033959880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10799,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000192227fa32d81c101ad5f1da4f0219cd967f3e18000000000000000000000000192227fa32d81c101ad5f1da4f0219cd967f3e180000000000000000000000000000000000000000000000000008f47a355a8f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10800,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee8b7d0d4bc1fbb8ed182b10ad174bf7d20ebfaa000000000000000000000000ee8b7d0d4bc1fbb8ed182b10ad174bf7d20ebfaa000000000000000000000000000000000000000000000000000d84873d0dbb4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10801,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b05cb4612f9886a6a604f4c1f416cecb772c3194000000000000000000000000b05cb4612f9886a6a604f4c1f416cecb772c31940000000000000000000000000000000000000000000000000008a09394df8b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10803,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ee8b7d0d4bc1fbb8ed182b10ad174bf7d20ebfaa0000000000000000000000000000000000000000000000003e33aa820173f8ae,,,1,true +10804,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000935cb2f7e86d395d0692d39cf8be5ffb8fcd51fa000000000000000000000000935cb2f7e86d395d0692d39cf8be5ffb8fcd51fa000000000000000000000000000000000000000000000000006196007a15970100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10805,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000099a409fc717ec84acb7d48bff1fd9981190d46ab00000000000000000000000099a409fc717ec84acb7d48bff1fd9981190d46ab000000000000000000000000000000000000000000000000000000000078bdcd00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10806,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052477254b96ceaa05613c078b3fde56a92d6255600000000000000000000000052477254b96ceaa05613c078b3fde56a92d6255600000000000000000000000000000000000000000000000000a4a39f0de54de600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001a8a09311d1d558f07f6d05d0e8bc6fd8fe8b8a00000000000000000000000001a8a09311d1d558f07f6d05d0e8bc6fd8fe8b8a000000000000000000000000000000000000000000000000004042e547153c4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9ecb55ce5b1b38abdf767433f6b35fc89c2ceb0000000000000000000000000e9ecb55ce5b1b38abdf767433f6b35fc89c2ceb0000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10831,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000004240268a3ad66fab234e124c31c9cecc8b457e820000000000000000000000004240268a3ad66fab234e124c31c9cecc8b457e82000000000000000000000000000000000000000000000000000000003d25ab3400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000336bdf7a8dc958ca317197b764a29eae90c14f7d000000000000000000000000336bdf7a8dc958ca317197b764a29eae90c14f7d00000000000000000000000000000000000000000000000000013e10ba23870000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10835,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bebe6acde175848b79606fa0de9b17ab2749d7d20000000000000000000000000000000000000000000000004abc49e16e331046,,,1,true +10838,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d5096b4d21abd25d0d3e0cf9e2ff7a840b202906000000000000000000000000d5096b4d21abd25d0d3e0cf9e2ff7a840b20290600000000000000000000000000000000000000000000007d95f141f7e8b3f91600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e540a58cb58a4ee5c35a980fd030d8a449b52695000000000000000000000000e540a58cb58a4ee5c35a980fd030d8a449b52695000000000000000000000000000000000000000000000000000000000062369400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e07c9b38ef430c9a79b78a505b321084ffd354c3000000000000000000000000e07c9b38ef430c9a79b78a505b321084ffd354c30000000000000000000000000000000000000000000000000000a0761641dc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb61edc2007b476e44be5bbe81486247425e5f8b000000000000000000000000cb61edc2007b476e44be5bbe81486247425e5f8b00000000000000000000000000000000000000000000000000154ff58a9dddd900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000672926d500e20ffc44ec712aa86277a85f72f4c6000000000000000000000000672926d500e20ffc44ec712aa86277a85f72f4c6000000000000000000000000000000000000000000000000003af3ea470a8d9900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e540a58cb58a4ee5c35a980fd030d8a449b52695000000000000000000000000e540a58cb58a4ee5c35a980fd030d8a449b5269500000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f33734d47761b1578f20808714adf2a669d23a80000000000000000000000005f33734d47761b1578f20808714adf2a669d23a800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c330130e49398bf5311b030c620b0d2ba361552e000000000000000000000000c330130e49398bf5311b030c620b0d2ba361552e000000000000000000000000000000000000000000000000002833a4521c1e2400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000474f47707ae222c3a4dd1520de1aceed8d40643a000000000000000000000000474f47707ae222c3a4dd1520de1aceed8d40643a000000000000000000000000000000000000000000000000004ec89c84df33e900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10859,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ba07c823f84bb2aa1cfda61cfa957750f2cf002200000000000000000000000000000000000000000000000dbbd4b593e2dce33c,,,1,true +10860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000037223d721901ec493906ddf800b71dbcb347fa6800000000000000000000000037223d721901ec493906ddf800b71dbcb347fa68000000000000000000000000000000000000000000000000000000000c6eb59600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x40fcb1b68dfd8edf1a14e02116bdb05da8340f1602f6261a18901ad8cf07ab13,2022-03-20 12:24:21.000 UTC,0,true +10861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a81579aab05701838b80c826844e618aa023ed40000000000000000000000002a81579aab05701838b80c826844e618aa023ed4000000000000000000000000000000000000000000000000002e46d65eb68d0d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a163d40de9dc681d7850ed24564d1805414ac468000000000000000000000000a163d40de9dc681d7850ed24564d1805414ac46800000000000000000000000000000000000000000000000002c40dd9e62e420000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10865,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002edf166a658af79c5c8bb268265a7def157eb62e0000000000000000000000002edf166a658af79c5c8bb268265a7def157eb62e0000000000000000000000000000000000000000000000000008e1bc9bf0400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10867,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004e27452b03dbfdbb36e796cd0167a30b242871d20000000000000000000000000000000000000000000000013ef134172978f2e5,,,1,true +10868,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e540a58cb58a4ee5c35a980fd030d8a449b52695000000000000000000000000e540a58cb58a4ee5c35a980fd030d8a449b5269500000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10870,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000443d12a4a89ae225df8460eed40f3dfd3f2ea8a80000000000000000000000000000000000000000000000000de0b6b3a7640000,,,1,true +10871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000223c930c6ad42f7e9cdebf88c68a29c508a616f6000000000000000000000000223c930c6ad42f7e9cdebf88c68a29c508a616f600000000000000000000000000000000000000000000000002869809251f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x946a735ce3e5092ed3b0ef730738a2f45411ba2b56824d72e23e60bba9aedec2,2022-02-27 03:01:16.000 UTC,0,true +10872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000710751fde40475ae92c8b267a1e5738de609156a000000000000000000000000710751fde40475ae92c8b267a1e5738de609156a00000000000000000000000000000000000000000000000000fd107932132a4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc5e0b41320fec3821e6c2e70fd6fd548c9e609a000000000000000000000000cc5e0b41320fec3821e6c2e70fd6fd548c9e609a000000000000000000000000000000000000000000000000017b6435a682fc6900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f28b24d61cabd44aa94142f58e70be3722a23a10000000000000000000000007f28b24d61cabd44aa94142f58e70be3722a23a100000000000000000000000000000000000000000000000000ea0be46dd01b5100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085a61295752440af1f3071abfcd8233491a1621800000000000000000000000085a61295752440af1f3071abfcd8233491a162180000000000000000000000000000000000000000000000000033b35a5f44e12500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10884,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037505d100c98de9d9026f621cb11bb222275af3a00000000000000000000000037505d100c98de9d9026f621cb11bb222275af3a0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7cd0406c712510813a257b19d852c3d1dfb817b000000000000000000000000d7cd0406c712510813a257b19d852c3d1dfb817b000000000000000000000000000000000000000000000000006e0f97cbfa0ebf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10886,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000939fef762c9ba24d802a9def26e2ecf32212072c000000000000000000000000939fef762c9ba24d802a9def26e2ecf32212072c00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d181a7312cad7bdc5208f5bb65368fab933ca260000000000000000000000007d181a7312cad7bdc5208f5bb65368fab933ca26000000000000000000000000000000000000000000000000003dc4ab23255ab500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a6b7cdaef5d67fed5d470c94006c2197924f1c10000000000000000000000003a6b7cdaef5d67fed5d470c94006c2197924f1c100000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003947217dc84e655d42371683a5b80f461903b2940000000000000000000000003947217dc84e655d42371683a5b80f461903b2940000000000000000000000000000000000000000000000000a6b51382b7c992800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6dfc238924705d8663911a909973867febe62b88a8c65eef8918322ac8898792,2022-05-30 09:16:56.000 UTC,0,true +10892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006521f20f2e82dedefbabc0047f6a82acab125d4b0000000000000000000000006521f20f2e82dedefbabc0047f6a82acab125d4b000000000000000000000000000000000000000000000000003ef29626e86a7a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10893,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d073a15d57f958f8098ac87e421a2c9983885ac8000000000000000000000000d073a15d57f958f8098ac87e421a2c9983885ac80000000000000000000000000000000000000000000000022b1c8c1227a0000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +10894,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006bc8e668402f5c1b895aced390aa1871cc6352900000000000000000000000006bc8e668402f5c1b895aced390aa1871cc63529000000000000000000000000000000000000000000000000003fa03caedc0dbe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10895,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c98c0741a5d439ca7ec73e49f2735388a96cf3e2000000000000000000000000c98c0741a5d439ca7ec73e49f2735388a96cf3e2000000000000000000000000000000000000000000000000001c31d9b037a78000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae89056d488eebe4331613daad6a2bace2cb77e7000000000000000000000000ae89056d488eebe4331613daad6a2bace2cb77e70000000000000000000000000000000000000000000000000040e300c85408ba00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9c032b435d1163a7f6c894aab9924d3c0dc1989000000000000000000000000d9c032b435d1163a7f6c894aab9924d3c0dc1989000000000000000000000000000000000000000000000000023043508114400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4e178aded85fe4de0dcf58d9b9fe36987bd2c5a0633e65c918ed1d44c9e274de,2022-02-27 03:07:00.000 UTC,0,true +10903,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b95152d72c9e182f2edd1e6a611a615f3d1a8033000000000000000000000000b95152d72c9e182f2edd1e6a611a615f3d1a8033000000000000000000000000000000000000000000000000002023c960aba00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084d0654d741fc89ab8610ec9c3fed33b68b7694800000000000000000000000084d0654d741fc89ab8610ec9c3fed33b68b7694800000000000000000000000000000000000000000000000000ede3c3e629000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10928,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084d0654d741fc89ab8610ec9c3fed33b68b7694800000000000000000000000084d0654d741fc89ab8610ec9c3fed33b68b76948000000000000000000000000000000000000000000000000004089d9c9f1c73800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10932,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092dd06f1cf1b9d086ce2bae7facdcf7067a35ccf00000000000000000000000092dd06f1cf1b9d086ce2bae7facdcf7067a35ccf000000000000000000000000000000000000000000000000015181ff25a9800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x30fb2fe3044f63668c54bef3b1030e089f51cddf45f80a0dc0b29aa20fa76bd9,2022-02-27 03:15:02.000 UTC,0,true +10957,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b1df9010790002f57090902c78292cc7e7d948a0000000000000000000000002b1df9010790002f57090902c78292cc7e7d948a00000000000000000000000000000000000000000000000000043b30e5b86fab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006b912dc08176500e2a5b2221b9e54ea3fa547f100000000000000000000000006b912dc08176500e2a5b2221b9e54ea3fa547f100000000000000000000000000000000000000000000000000afe19579ab220000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7ac308a24db2c414373c8efdc59a6f4f13c9cd6f7bdc4841d69809ba03b3a46b,2022-03-16 01:10:44.000 UTC,0,true +10959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10960,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000695473b868a5ae578df18ce0e9002a97f0a5eb8f000000000000000000000000695473b868a5ae578df18ce0e9002a97f0a5eb8f000000000000000000000000000000000000000000000000006bc0ba559023fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000191e1b3df06260d8813d8bfe666bbb36851068f5000000000000000000000000191e1b3df06260d8813d8bfe666bbb36851068f500000000000000000000000000000000000000000000000000d0858bd80570c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x32891689d5a48cba308da37d973188a375a98fe5e387a4865315798304ec2f8b,2022-01-05 10:59:11.000 UTC,0,true +10964,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009e1d470604b79d1ed9ba77166928373773b273e00000000000000000000000009e1d470604b79d1ed9ba77166928373773b273e00000000000000000000000000000000000000000000000000408bba061df51900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000866db22cf538fd470db7fe3c8bdb0416f6760874000000000000000000000000866db22cf538fd470db7fe3c8bdb0416f676087400000000000000000000000000000000000000000000000000037fc4e05c771100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10970,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000722246643c7bb3d15ccef7e72fc5f90e53b9f457000000000000000000000000722246643c7bb3d15ccef7e72fc5f90e53b9f4570000000000000000000000000000000000000000000000000093f851baa0c0d600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d65bf5e2843463ad1857cd1f464598d79332d0b6000000000000000000000000d65bf5e2843463ad1857cd1f464598d79332d0b600000000000000000000000000000000000000000000000000db4e8e0ff8bb0200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5dde0bf7ad06d20b0d6a4871bc5b47d731317085efa7c0c93df368b6ed7f56be,2022-04-20 12:55:23.000 UTC,0,true +10974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be7ae762dc142a1b4a56e36ed86dc90ba3484b44000000000000000000000000be7ae762dc142a1b4a56e36ed86dc90ba3484b440000000000000000000000000000000000000000000000000002f0865f34c8c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000365be1502c03306a39a945d3e1f33b0a560c5ecc000000000000000000000000365be1502c03306a39a945d3e1f33b0a560c5ecc000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10978,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a08700000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10980,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10983,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d41aa4577d756c05bff040abfd9b106056479290000000000000000000000000d41aa4577d756c05bff040abfd9b10605647929000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10984,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d741776da5549e31bf419178b0d031e59401f419000000000000000000000000d741776da5549e31bf419178b0d031e59401f419000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000262efc46e2723b4552e5cc3ddbec23141d328092000000000000000000000000262efc46e2723b4552e5cc3ddbec23141d328092000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10986,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050cf6c627b7284f210e3b4fbe791867f4411022700000000000000000000000050cf6c627b7284f210e3b4fbe791867f44110227000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000461460989787016397e1b2c1ecb5f6c306ee577d000000000000000000000000461460989787016397e1b2c1ecb5f6c306ee577d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10988,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071e56c34b9b74fd2f195e545ab4d5d14b78cd88800000000000000000000000071e56c34b9b74fd2f195e545ab4d5d14b78cd888000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10989,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000247680b6a3af46db33680373e8dcc6cc86e6d798000000000000000000000000247680b6a3af46db33680373e8dcc6cc86e6d798000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10992,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001941f0ab39dbbe69855fe819991e6dac2bcc45ed0000000000000000000000001941f0ab39dbbe69855fe819991e6dac2bcc45ed00000000000000000000000000000000000000000000000000d12a5e822ff30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x08e666cfdd1d672aeb4a71f4e947a296b519a2af6bceabebd1927bcfa3eaac98,2021-12-19 07:25:26.000 UTC,0,true +10994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001227b6eeb15510badf14b1683fe41676ffcf2b1d0000000000000000000000001227b6eeb15510badf14b1683fe41676ffcf2b1d00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +10996,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039b370dca90663ffdd30838cd97c93a5042cceaa00000000000000000000000039b370dca90663ffdd30838cd97c93a5042cceaa0000000000000000000000000000000000000000000000000040311dc578c5ee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11009,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bafd5b823eb5b00207e0e1f9ba4ca7a57cc01ce2000000000000000000000000bafd5b823eb5b00207e0e1f9ba4ca7a57cc01ce2000000000000000000000000000000000000000000000000002ed320df92200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000835bdd5f86919022837efd01cd684d5b1e75e19c000000000000000000000000835bdd5f86919022837efd01cd684d5b1e75e19c000000000000000000000000000000000000000000000000009493d3acc111cb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11017,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ba50a11c2b726abb4b4f945b04e11c192cd1d3d0000000000000000000000007ba50a11c2b726abb4b4f945b04e11c192cd1d3d00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11019,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007b488f9e43a834a136147315016593fb6128ae500000000000000000000000007b488f9e43a834a136147315016593fb6128ae5000000000000000000000000000000000000000000000000007c58508723800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11020,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000851064900dcb11351e53a39e5af340e9fc2b7689000000000000000000000000851064900dcb11351e53a39e5af340e9fc2b7689000000000000000000000000000000000000000000000000012ffff40b947e5a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006beb35a80a6e34aed6cc639517856df28cf938850000000000000000000000006beb35a80a6e34aed6cc639517856df28cf93885000000000000000000000000000000000000000000000000003fa5ceaabdb19800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bce3cec9ffebdc48b90cccbe3f568b5b03f31c20000000000000000000000004bce3cec9ffebdc48b90cccbe3f568b5b03f31c2000000000000000000000000000000000000000000000000013c4bd0697f37fa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf8deb7916eac32583f9ec0ed24c75f4407ea1578febc05a05818b6e47fc06fb7,2022-05-22 18:25:07.000 UTC,0,true +11023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008617e81ab3ecf651f8b94b2d472efd37f724c1330000000000000000000000008617e81ab3ecf651f8b94b2d472efd37f724c133000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024c9440ee1add29a03fb2e18d18fc3ec463d357900000000000000000000000024c9440ee1add29a03fb2e18d18fc3ec463d3579000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e90ac62991600ba537d6c8c567f42f0cd4b346c9000000000000000000000000e90ac62991600ba537d6c8c567f42f0cd4b346c9000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbcfa66204895046b47313dd761a981e6a99f33b000000000000000000000000cbcfa66204895046b47313dd761a981e6a99f33b0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000869fd339567356ff41d8e9a6d0fbb7afc679d7b1000000000000000000000000869fd339567356ff41d8e9a6d0fbb7afc679d7b100000000000000000000000000000000000000000000000000138a388a43c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000983ae2cfe680c18300154bc910ca8d117a1ed20f000000000000000000000000983ae2cfe680c18300154bc910ca8d117a1ed20f000000000000000000000000000000000000000000000000000ffcb9e57d400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009eaaf4db9a9ba7b1404877568c7f93356bd1dcf70000000000000000000000009eaaf4db9a9ba7b1404877568c7f93356bd1dcf7000000000000000000000000000000000000000000000000000ffcb9e57d400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9aabc663eb801a970807ea3a0e36d49ab03fc1e000000000000000000000000a9aabc663eb801a970807ea3a0e36d49ab03fc1e000000000000000000000000000000000000000000000000001717b72f0a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11031,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efe8ee8b892b88f2e7acca277e128074ece49b6b000000000000000000000000efe8ee8b892b88f2e7acca277e128074ece49b6b000000000000000000000000000000000000000000000000001aa535d3d0c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11032,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ccf5ce1115395c99feab660911e59f2c1a80684e000000000000000000000000ccf5ce1115395c99feab660911e59f2c1a80684e000000000000000000000000000000000000000000000000001e32b47897400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d572beca83dd4c1a49ad56c6aa6126653678555f000000000000000000000000d572beca83dd4c1a49ad56c6aa6126653678555f00000000000000000000000000000000000000000000000000138a388a43c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11034,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061339e9f27a21bfbd309bb5d9c00dbeb9b88562300000000000000000000000061339e9f27a21bfbd309bb5d9c00dbeb9b88562300000000000000000000000000000000000000000000000000138a388a43c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11036,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc465f297e18bd50befa610d503c5571c56e925a000000000000000000000000fc465f297e18bd50befa610d503c5571c56e925a00000000000000000000000000000000000000000000000000f451e45a9c830000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1127e3f96f2df912d4e830ee7d91559cfe2d6f370a8978a6ae444b08d1cc5397,2022-03-12 06:51:43.000 UTC,0,true +11039,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c3a62f16ea361cdd5c65ac22dfd1ef4cb5560bb0000000000000000000000002c3a62f16ea361cdd5c65ac22dfd1ef4cb5560bb0000000000000000000000000000000000000000000000000034a558ab62380000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11041,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb22ffae8c9205cc3677f16c5b79dffba9479b4a000000000000000000000000bb22ffae8c9205cc3677f16c5b79dffba9479b4a000000000000000000000000000000000000000000000000003776a76816644000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11043,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017d4dac6081d305209c693b702f9a8cf0e4df15100000000000000000000000017d4dac6081d305209c693b702f9a8cf0e4df1510000000000000000000000000000000000000000000000000071afd498d0000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11044,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da485bc95377b68f19721d3c661bcd9c7e0a616f000000000000000000000000da485bc95377b68f19721d3c661bcd9c7e0a616f00000000000000000000000000000000000000000000000002ed182ae759b8d300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11048,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000214013e8e5d8264b27e824077ce9fff49bc20e8e000000000000000000000000214013e8e5d8264b27e824077ce9fff49bc20e8e00000000000000000000000000000000000000000000000000ad9f018e2c600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11049,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ecaf5554b3e7acc936cf5b9f7e9173a7b85cba73000000000000000000000000ecaf5554b3e7acc936cf5b9f7e9173a7b85cba73000000000000000000000000000000000000000000000000015b4dca52666abc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007464c993af64925ba9f38fa36e8e7578c31773540000000000000000000000007464c993af64925ba9f38fa36e8e7578c3177354000000000000000000000000000000000000000000000000007fe5cf2bea000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11052,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f797f8b349b34821d8ec65f3fd754e9c60cfde60000000000000000000000006f797f8b349b34821d8ec65f3fd754e9c60cfde600000000000000000000000000000000000000000000000000249f00b6c89a4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d365821a7a763ca01021ae5ef00bb9ab9ecc553d000000000000000000000000d365821a7a763ca01021ae5ef00bb9ab9ecc553d00000000000000000000000000000000000000000000000000ab73e1d6c5258000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe67ccda1fffc26dd6bba2c3c7530cbbf5c10e3b394390c162103cd583dea0188,2021-12-19 12:20:13.000 UTC,0,true +11054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ceb5591110444504bf02283c05bfaf42d6ea0f07000000000000000000000000ceb5591110444504bf02283c05bfaf42d6ea0f070000000000000000000000000000000000000000000000000000000006e95e1c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11056,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000003296fb4fb0188d3c4ebbc6ee55ce636ac1ab5b4b0000000000000000000000003296fb4fb0188d3c4ebbc6ee55ce636ac1ab5b4b00000000000000000000000000000000000000000000000000000000078b44d900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082b2001c9adfc027ffba3fa37b1e18c11cc5c3e600000000000000000000000082b2001c9adfc027ffba3fa37b1e18c11cc5c3e6000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffc9c646cf9399a3adfde4ad042c5e0c2ffa1210000000000000000000000002ffc9c646cf9399a3adfde4ad042c5e0c2ffa121000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11062,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032255bda08d9dfb5af628818075c78c6ead1336900000000000000000000000032255bda08d9dfb5af628818075c78c6ead1336900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11063,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11064,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f419db6a84d599b5802fe555f6e1c4e4ca71d1c2000000000000000000000000f419db6a84d599b5802fe555f6e1c4e4ca71d1c2000000000000000000000000000000000000000000000000001e75f6d4130fa800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11066,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11067,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11068,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11069,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003880a75cc09b8ccd4adbbce0d29ecd33a77115ec0000000000000000000000003880a75cc09b8ccd4adbbce0d29ecd33a77115ec00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11070,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d41aa4577d756c05bff040abfd9b106056479290000000000000000000000000d41aa4577d756c05bff040abfd9b10605647929000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11071,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a33698d7ce3d595934c3a580e043f48e8c52f3dd000000000000000000000000a33698d7ce3d595934c3a580e043f48e8c52f3dd00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11072,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d741776da5549e31bf419178b0d031e59401f419000000000000000000000000d741776da5549e31bf419178b0d031e59401f419000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11073,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c074be0305e9ee1b5a69c94aaf9e0546e3d70fff000000000000000000000000c074be0305e9ee1b5a69c94aaf9e0546e3d70fff00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11074,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000262efc46e2723b4552e5cc3ddbec23141d328092000000000000000000000000262efc46e2723b4552e5cc3ddbec23141d328092000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004318d15cab26aff5995a3993581dd2264bc81e770000000000000000000000004318d15cab26aff5995a3993581dd2264bc81e7700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050cf6c627b7284f210e3b4fbe791867f4411022700000000000000000000000050cf6c627b7284f210e3b4fbe791867f44110227000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11077,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025e250f4144811f1e7e3aa3b8bff4ce49e06fe6900000000000000000000000025e250f4144811f1e7e3aa3b8bff4ce49e06fe6900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000461460989787016397e1b2c1ecb5f6c306ee577d000000000000000000000000461460989787016397e1b2c1ecb5f6c306ee577d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071e56c34b9b74fd2f195e545ab4d5d14b78cd88800000000000000000000000071e56c34b9b74fd2f195e545ab4d5d14b78cd888000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006099c5863f280a81532be79afe969821ac92feb30000000000000000000000006099c5863f280a81532be79afe969821ac92feb300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a25cf88f762e4a9e75ceab2b6c71138f07a2e6f4000000000000000000000000a25cf88f762e4a9e75ceab2b6c71138f07a2e6f400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef55dd49e4ef9df47669f0e8fd44c26b6ed41a8b000000000000000000000000ef55dd49e4ef9df47669f0e8fd44c26b6ed41a8b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ffb49827cdf0d398970919a37e0218a9f01509c0000000000000000000000000ffb49827cdf0d398970919a37e0218a9f01509c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11084,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a960cd9dd85d6f1dc2ece6f8dff862f81a409483000000000000000000000000a960cd9dd85d6f1dc2ece6f8dff862f81a40948300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11085,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048a99f12ac0bac569b846422a35775f98e59bba600000000000000000000000048a99f12ac0bac569b846422a35775f98e59bba600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6fe30e32cfe1e1e6c0f40a4c7c0ffe77edc2eaa000000000000000000000000c6fe30e32cfe1e1e6c0f40a4c7c0ffe77edc2eaa00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a99ca43db25dee844eb6a55f78b9bfaea0e2d96d000000000000000000000000a99ca43db25dee844eb6a55f78b9bfaea0e2d96d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000247680b6a3af46db33680373e8dcc6cc86e6d798000000000000000000000000247680b6a3af46db33680373e8dcc6cc86e6d798000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000247680b6a3af46db33680373e8dcc6cc86e6d798000000000000000000000000247680b6a3af46db33680373e8dcc6cc86e6d798000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11090,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11091,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca79106a1a187c40e4830eca639b63b2dc0415fb000000000000000000000000ca79106a1a187c40e4830eca639b63b2dc0415fb00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f73f2ad9434cd2e86d298b9f03d3ad135320dd71000000000000000000000000f73f2ad9434cd2e86d298b9f03d3ad135320dd7100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed668c3aacc5411b9116aac58c9e41efdc7e1e12000000000000000000000000ed668c3aacc5411b9116aac58c9e41efdc7e1e1200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8c2efb6a45096afbfc4617b1aa4941d28d3531b000000000000000000000000f8c2efb6a45096afbfc4617b1aa4941d28d3531b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bd8e8275b285fd66a36b66abe6a9021e58be82a0000000000000000000000006bd8e8275b285fd66a36b66abe6a9021e58be82a00000000000000000000000000000000000000000000000003731728748c6d4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11096,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b441a9e5d5581fa859858f35f437790228b956ed000000000000000000000000b441a9e5d5581fa859858f35f437790228b956ed00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4db982a2761cb7abe328f09d5992bd5a79c9e16000000000000000000000000a4db982a2761cb7abe328f09d5992bd5a79c9e1600000000000000000000000000000000000000000000000000220bb695b8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11100,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6c86df56d0a5c574658bf2831d8dda94e6fee58000000000000000000000000b6c86df56d0a5c574658bf2831d8dda94e6fee58000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11103,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f41219828d15fc06786aea5026597fba62471950000000000000000000000001f41219828d15fc06786aea5026597fba6247195000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f21c72dc8c8dca4ee2b60996636cb65f14109452000000000000000000000000f21c72dc8c8dca4ee2b60996636cb65f14109452000000000000000000000000000000000000000000000000002061749153584000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11106,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000babd94d14a221936a4b13f9db96e241a3abddb81000000000000000000000000babd94d14a221936a4b13f9db96e241a3abddb8100000000000000000000000000000000000000000000000000586497ea697d0400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b26975022d55b218ef2b29df3f8d3047102c56b0000000000000000000000002b26975022d55b218ef2b29df3f8d3047102c56b0000000000000000000000000000000000000000000000000085bff4b4b1e4c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11108,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bec9722651a94f1999d22e6895314566b3f54330000000000000000000000004bec9722651a94f1999d22e6895314566b3f543300000000000000000000000000000000000000000000000000207fb87b2d090000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11109,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008619c0c06e1f601ee60dd9a7330f9c4d2c869fbf0000000000000000000000008619c0c06e1f601ee60dd9a7330f9c4d2c869fbf00000000000000000000000000000000000000000000000000c630340eee02d600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11113,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a47e6a0bd3b361ba2784e61be35ae5407502cd82000000000000000000000000a47e6a0bd3b361ba2784e61be35ae5407502cd8200000000000000000000000000000000000000000000000000fba74299a8528000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11114,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000140f0479b7db7e1643e66a1dfad79b1537bca1df000000000000000000000000140f0479b7db7e1643e66a1dfad79b1537bca1df000000000000000000000000000000000000000000000000014a99912ddf556300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11115,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5f3fac8634369bbf50606eee7d49bbb97f3c686000000000000000000000000f5f3fac8634369bbf50606eee7d49bbb97f3c68600000000000000000000000000000000000000000000000000522667f90adf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11116,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048e492c0acc7f277c0f0a8335a35aa33caa0365200000000000000000000000048e492c0acc7f277c0f0a8335a35aa33caa036520000000000000000000000000000000000000000000000000037ed803d38378100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11117,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e366355e53169d030c6af3de0e48b15ad657892f000000000000000000000000000000000000000000000000004dc0da02a8cc12,,,1,true +11119,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de55e26ac20c5aca6dc7d5768631840eb53d6868000000000000000000000000de55e26ac20c5aca6dc7d5768631840eb53d686800000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c60e967fb9ecf571cf69f007971d487ce748528b000000000000000000000000c60e967fb9ecf571cf69f007971d487ce748528b000000000000000000000000000000000000000000000000007a583cd9ad5f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11124,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11126,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11127,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11128,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11129,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000bdf15d94f8e4cd2c8d422225f194755534f63464000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11138,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078c8e648e99c53c5b320d16fae7cf667db3a521300000000000000000000000078c8e648e99c53c5b320d16fae7cf667db3a521300000000000000000000000000000000000000000000000006cc4350c474f01400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2b1aa31ebc9cc1d45571b4a37dd287b99ea8908b1e7fa891c0c4f57c88550959,2022-03-01 15:54:56.000 UTC,0,true +11139,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000064fde70dc6d475fd5482e788b0391a9b1f5a6a6700000000000000000000000064fde70dc6d475fd5482e788b0391a9b1f5a6a67000000000000000000000000000000000000000000000000000000005b3b4d8800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x2b1cae93e5109bba5f5ee06aa9098bc7d44611efd8bf92d80832d6918e5c42e9,2022-06-08 16:42:39.000 UTC,0,true +11147,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b45c64303eee659e573597335473467b6222ea9a000000000000000000000000b45c64303eee659e573597335473467b6222ea9a0000000000000000000000000000000000000000000000000021c10a9b5f4f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0929a7fa093c6219789a592856f8e67ccf0500b000000000000000000000000b0929a7fa093c6219789a592856f8e67ccf0500b00000000000000000000000000000000000000000000000000011f7b0985e5dd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11150,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0929a7fa093c6219789a592856f8e67ccf0500b000000000000000000000000b0929a7fa093c6219789a592856f8e67ccf0500b000000000000000000000000000000000000000000000000015d85436020bf2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000169bc617dfdd54623132f9cc633dfe4d786d5bc0000000000000000000000000169bc617dfdd54623132f9cc633dfe4d786d5bc0000000000000000000000000000000000000000000000000017d0cdfededc11900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11155,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052dd96ce3ad7f658cc0645ed9cb4ac896c1360f900000000000000000000000052dd96ce3ad7f658cc0645ed9cb4ac896c1360f9000000000000000000000000000000000000000000000000016c35d5523e4d1f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0a98e6477003e2e889a774dd5e75cce6e4d8a68000000000000000000000000c0a98e6477003e2e889a774dd5e75cce6e4d8a68000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11157,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d74c56c55573d810a130599aac4bec2337b4dc3d000000000000000000000000d74c56c55573d810a130599aac4bec2337b4dc3d0000000000000000000000000000000000000000000000000137dc155d22ce0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11158,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ad0f834fd587c0f11bdb5654a7c53c4198f70600000000000000000000000003ad0f834fd587c0f11bdb5654a7c53c4198f70600000000000000000000000000000000000000000000000000813adea9b47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x68b7fff14bb9979cc0cc7c9e983b903aef7f837f039586daecfe6b767bdbd48c,2021-11-29 07:33:40.000 UTC,0,true +11167,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11169,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11170,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11172,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11173,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11175,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a18af6843286143afcc833ce9a310cbf8b3c2d2f000000000000000000000000a18af6843286143afcc833ce9a310cbf8b3c2d2f00000000000000000000000000000000000000000000000000aee865f414d10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11184,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b0000000000000000000000006d6dff1f616b9af592fd4092c3df123746a3168b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11186,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11187,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11188,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11189,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11190,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d03d8bd1fd8e208b163a5e7304dff35c10310770000000000000000000000002d03d8bd1fd8e208b163a5e7304dff35c103107700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11191,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11193,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11195,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11196,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083ea9d59eb73d2c7183072fa22efcbf35ef6e55500000000000000000000000083ea9d59eb73d2c7183072fa22efcbf35ef6e5550000000000000000000000000000000000000000000000000037962084227d1100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11197,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11198,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11201,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11202,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11203,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000cbd89600a173f377be4d59d155c9c59e6030fda3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11205,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11211,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11212,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11213,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11214,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11217,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000581edc6ba25b2e56d59a2e82b038caa35b7b1f4d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11220,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11223,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11224,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11226,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11227,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11228,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11229,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11230,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11231,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa930000000000000000000000002ffafb6a09999d2cb2cff49af667c084bf12aa93000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11237,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11242,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11243,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11245,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11247,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11249,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000aeebeab3168ec11d58bddb633fe498f78f2811cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11252,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11254,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11257,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11258,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11260,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11261,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11262,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11264,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d7800000000000000000000000003f298b99f6a38d56df11afdc6b7cb7d351c8d780000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11265,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11266,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11267,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11270,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11271,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11273,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11278,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000888a721ede33cbdc79325843ae786c0ae41a927c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11284,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11285,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11287,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11288,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11289,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11291,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11292,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11293,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff80000000000000000000000007fb50bf1b2dbfc249d5327c01713daa9ff92eff8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11295,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11296,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11297,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11299,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11300,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11302,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11304,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11306,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f300000000000000000000000094d14ebb36a69f621e458f4b06dbdd8c317097f3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11307,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11308,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11309,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11310,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11311,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11312,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11313,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11314,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11315,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11316,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11319,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11320,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11321,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11322,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c83600000000000000000000000000eb5bc0465292f0df1003207cb9cce17707c8360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11324,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbcda62ad56791f9a3f8ab16e0a45ca376cf5c9c000000000000000000000000cbcda62ad56791f9a3f8ab16e0a45ca376cf5c9c000000000000000000000000000000000000000000000000001c063b3bfa60c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11325,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11326,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11327,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11328,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11330,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11331,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11332,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11333,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11334,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11335,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11336,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11337,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11338,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000c92e9fa369fa4e94c462d9fad4a79ad16f54ef08000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11341,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11342,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11343,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11344,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11347,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11348,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11350,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11354,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000f506f4bc57ac62f72e846a781882d037d1dde02b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11357,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11358,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11359,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11361,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11362,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11363,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11366,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11371,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc39849500000000000000000000000005bc0a8aab1923237dd18d5b1b57efcdfc398495000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11373,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c3ba25500e7ad8e7c6d78682b204fb9e59d7473200000000000000000000000000000000000000000000000d0fdd35ab37e456e1,,,1,true +11374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11375,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11378,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11379,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11380,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11381,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000497793742d0774c653fbaa82cde35d1b13252c8e000000000000000000000000497793742d0774c653fbaa82cde35d1b13252c8e00000000000000000000000000000000000000000000000000844acea669563600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1031825e9667178167df00c485911847e4f91fe000000000000000000000000e1031825e9667178167df00c485911847e4f91fe000000000000000000000000000000000000000000000000003c6568f12e800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000009349c8c39dd1d5a6271861ce6f9974b2b76142bc0000000000000000000000009349c8c39dd1d5a6271861ce6f9974b2b76142bc000000000000000000000000000000000000000000000000000000004b7df6f700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11385,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076916bdbd7b84317365fb3bd157e1606550665b900000000000000000000000076916bdbd7b84317365fb3bd157e1606550665b90000000000000000000000000000000000000000000000000056c9d9e93e3db700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071a89164464e2c76693c4675254288eb7006af3b00000000000000000000000071a89164464e2c76693c4675254288eb7006af3b000000000000000000000000000000000000000000000000007fdc9a5c17c36500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca12f90047176053a219a0046091478de20b3e87000000000000000000000000ca12f90047176053a219a0046091478de20b3e870000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7c70dfd9c8a035dcd7c9df7b8e8fe0822ceab6e000000000000000000000000c7c70dfd9c8a035dcd7c9df7b8e8fe0822ceab6e00000000000000000000000000000000000000000000000000a5ccf32cbd974000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x06138a8c1028448831c112fb061c00e4f58d7e393856b8db76afc5fdbf86111d,2022-03-22 06:13:54.000 UTC,0,true +11389,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a8a33b9ce7f931335311ab2add963981ef20e080000000000000000000000001a8a33b9ce7f931335311ab2add963981ef20e0800000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000827123b697289543ccc99d5c41bc5a5a9575a087000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11398,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f18ad2dc771e36426b96163141b9bf25f8edbc0c000000000000000000000000000000000000000000000000470143d205ae4f4e,,,1,true +11399,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d3db1a276dd5571a94863a02c4e02d4513f7aa64000000000000000000000000000000000000000000000007302bd1afcb95c403,,,1,true +11400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11402,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000c29d88b3776aea8abab1d322cf54b05215858ea9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11409,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11413,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11414,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11415,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11418,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000eebc42b3bb20c202f7941a0ce1febf7cbd23e114000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11423,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11425,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11426,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11427,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000b8c3b004f4380b219e220f747661ab7d0f42c10a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d8ae114d43770bea2b50ec7c8ac2fec87a1d872a000000000000000000000000d8ae114d43770bea2b50ec7c8ac2fec87a1d872a0000000000000000000000000000000000000000000000000028d332a8552d6900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11434,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072bb27dec00202d977aa870fdc8487c89939713900000000000000000000000072bb27dec00202d977aa870fdc8487c89939713900000000000000000000000000000000000000000000000000138a388a43c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11435,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052a7160ab9e27d5cf95fc572d93c39d8b0559a5900000000000000000000000052a7160ab9e27d5cf95fc572d93c39d8b0559a59000000000000000000000000000000000000000000000000054ccb1648dfe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077e39267e87fdd02d62d831708b7e1152710397c00000000000000000000000077e39267e87fdd02d62d831708b7e1152710397c0000000000000000000000000000000000000000000000000de0471ef3418b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9f9ffcfb613b16551bfdea64531c1b7e088a5c09180b53c9a4ac63931443751f,2022-01-06 11:04:31.000 UTC,0,true +11437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c57037d4dbbb992ed3984b20a24ed08007475ab0000000000000000000000009c57037d4dbbb992ed3984b20a24ed08007475ab0000000000000000000000000000000000000000000000001bc032473adb080000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11438,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb2879457867f5aa85f6e5a789905ed8c1a83403000000000000000000000000bb2879457867f5aa85f6e5a789905ed8c1a834030000000000000000000000000000000000000000000000000de14438ced6c60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd037f8611717f669076002704fcf28acf3435862da99d0b2dac33c8864502abc,2022-01-06 10:52:38.000 UTC,0,true +11439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9c123d5642e424f1b059e17ea09fc596b6469bb000000000000000000000000f9c123d5642e424f1b059e17ea09fc596b6469bb0000000000000000000000000000000000000000000000000ddda681a139580000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000daaf3d7ce4c025714586c2590c9072a4698fc4b3000000000000000000000000daaf3d7ce4c025714586c2590c9072a4698fc4b30000000000000000000000000000000000000000000000000033ade4f34f250c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11443,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a892bf6aebae2de008edefa9a25eae5e7a9313a0000000000000000000000003a892bf6aebae2de008edefa9a25eae5e7a9313a00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008989eb731524c22e2c76f161a10dfdb7051205040000000000000000000000008989eb731524c22e2c76f161a10dfdb70512050400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bff4062c3029ea1591c13b3ba0574f4d50c66c76000000000000000000000000bff4062c3029ea1591c13b3ba0574f4d50c66c7600000000000000000000000000000000000000000000000000bfab2a59d2aec200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000783da486c76b4f2767605869e2c88d145c307818000000000000000000000000783da486c76b4f2767605869e2c88d145c30781800000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9107317b0ff77ed5b7adea15e50514a3564002b000000000000000000000000f9107317b0ff77ed5b7adea15e50514a3564002b0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c447e511495c761808b76e9d0792a9f45bd145be000000000000000000000000c447e511495c761808b76e9d0792a9f45bd145be00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b16c8220b3a2f31e569f6dda03ec0bf39e9be439000000000000000000000000b16c8220b3a2f31e569f6dda03ec0bf39e9be43900000000000000000000000000000000000000000000000000475fbfa842118d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11454,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007782c1c31f0eed9ebf466d78beec0cb0cd2b51af000000000000000000000000000000000000000000000000976b35e09eb77c1a,,,1,true +11455,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004351884e49eef08ea1bc7528f3e32ad4ef1f4b080000000000000000000000004351884e49eef08ea1bc7528f3e32ad4ef1f4b08000000000000000000000000000000000000000000000000002d49faef92660200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035a07be085ecac45aee8dddd71467b6b45a7aa1200000000000000000000000035a07be085ecac45aee8dddd71467b6b45a7aa12000000000000000000000000000000000000000000000000007c58508723800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080046121d4c997e9affccce59bef6689795c8c0d00000000000000000000000080046121d4c997e9affccce59bef6689795c8c0d00000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000db5d39414fab620dd38e5a477ab58320b10f42c9000000000000000000000000db5d39414fab620dd38e5a477ab58320b10f42c9000000000000000000000000000000000000000000000000000000000073d3cb00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db5d39414fab620dd38e5a477ab58320b10f42c9000000000000000000000000db5d39414fab620dd38e5a477ab58320b10f42c900000000000000000000000000000000000000000000000000a86e9f68f2fac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11464,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9c8863c71377123ba2ea383b8c537d0d683db85000000000000000000000000d9c8863c71377123ba2ea383b8c537d0d683db850000000000000000000000000000000000000000000000000013246c8318a20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072988183250af3ffeeb3ab47731b924a8cc6c16000000000000000000000000072988183250af3ffeeb3ab47731b924a8cc6c16000000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000dc277d26a32808b9517ec5809164305f38ab2e30000000000000000000000000dc277d26a32808b9517ec5809164305f38ab2e3000000000000000000000000000000000000000000000000001314bef78d2f0900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11468,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063baa2dc5597bcce4bbbf60f27901d726c34436c00000000000000000000000063baa2dc5597bcce4bbbf60f27901d726c34436c0000000000000000000000000000000000000000000000000019d820b6a02d4900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c81de614aa8f239c355671ddb21caa46ce3e7e2d000000000000000000000000c81de614aa8f239c355671ddb21caa46ce3e7e2d0000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c81de614aa8f239c355671ddb21caa46ce3e7e2d000000000000000000000000c81de614aa8f239c355671ddb21caa46ce3e7e2d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000246d62740b17059764ae74a8c44de2d85836da8b000000000000000000000000246d62740b17059764ae74a8c44de2d85836da8b0000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000246d62740b17059764ae74a8c44de2d85836da8b000000000000000000000000246d62740b17059764ae74a8c44de2d85836da8b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007e8e46620dfbe263f7a90ac2e3ae5aa5bfe528100000000000000000000000007e8e46620dfbe263f7a90ac2e3ae5aa5bfe52810000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007e8e46620dfbe263f7a90ac2e3ae5aa5bfe528100000000000000000000000007e8e46620dfbe263f7a90ac2e3ae5aa5bfe5281000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008cbdf071dea2ea6fb8d69ddb2b67d7bbdc5f544f0000000000000000000000008cbdf071dea2ea6fb8d69ddb2b67d7bbdc5f544f0000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008cbdf071dea2ea6fb8d69ddb2b67d7bbdc5f544f0000000000000000000000008cbdf071dea2ea6fb8d69ddb2b67d7bbdc5f544f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11477,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000814069653b9538da6d3c78281125c62f38736e20000000000000000000000000814069653b9538da6d3c78281125c62f38736e20000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11478,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000814069653b9538da6d3c78281125c62f38736e20000000000000000000000000814069653b9538da6d3c78281125c62f38736e2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11479,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000205c0c15b6ca60b7388947f9a300423212f514be000000000000000000000000205c0c15b6ca60b7388947f9a300423212f514be0000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11480,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000205c0c15b6ca60b7388947f9a300423212f514be000000000000000000000000205c0c15b6ca60b7388947f9a300423212f514be000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11481,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009bada5a8d176bc93fde52317ae018a411324e1be0000000000000000000000009bada5a8d176bc93fde52317ae018a411324e1be0000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009bada5a8d176bc93fde52317ae018a411324e1be0000000000000000000000009bada5a8d176bc93fde52317ae018a411324e1be000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11483,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2402f982a63800207dd232b6a05f4239173ec76000000000000000000000000b2402f982a63800207dd232b6a05f4239173ec760000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11484,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2402f982a63800207dd232b6a05f4239173ec76000000000000000000000000b2402f982a63800207dd232b6a05f4239173ec76000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0ab5a849eee3e75068333c4b771833f9c828ace000000000000000000000000b0ab5a849eee3e75068333c4b771833f9c828ace0000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11486,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0ab5a849eee3e75068333c4b771833f9c828ace000000000000000000000000b0ab5a849eee3e75068333c4b771833f9c828ace000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11487,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bce4d74a1306acc91ee88ad1eb14844f1e0d9780000000000000000000000006bce4d74a1306acc91ee88ad1eb14844f1e0d9780000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11488,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bce4d74a1306acc91ee88ad1eb14844f1e0d9780000000000000000000000006bce4d74a1306acc91ee88ad1eb14844f1e0d9780000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11489,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bce4d74a1306acc91ee88ad1eb14844f1e0d9780000000000000000000000006bce4d74a1306acc91ee88ad1eb14844f1e0d978000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0f4c9de49d53d84709df1ed8c4947591c571dd2000000000000000000000000a0f4c9de49d53d84709df1ed8c4947591c571dd20000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0f4c9de49d53d84709df1ed8c4947591c571dd2000000000000000000000000a0f4c9de49d53d84709df1ed8c4947591c571dd2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b058cd01a21a907453e201b927f258646ce75175000000000000000000000000b058cd01a21a907453e201b927f258646ce751750000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11493,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b058cd01a21a907453e201b927f258646ce75175000000000000000000000000b058cd01a21a907453e201b927f258646ce75175000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020a85c450eb7c40c89dab5ab61ac43eedd6a211300000000000000000000000020a85c450eb7c40c89dab5ab61ac43eedd6a21130000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020a85c450eb7c40c89dab5ab61ac43eedd6a211300000000000000000000000020a85c450eb7c40c89dab5ab61ac43eedd6a2113000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081e4286ae422fa457cefa1435dd44ae0bb9286ef00000000000000000000000081e4286ae422fa457cefa1435dd44ae0bb9286ef0000000000000000000000000000000000000000000000000078cad1e25d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11497,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081e4286ae422fa457cefa1435dd44ae0bb9286ef00000000000000000000000081e4286ae422fa457cefa1435dd44ae0bb9286ef000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000297b4d91270a60e31336cfe27175168ba37949f0000000000000000000000000297b4d91270a60e31336cfe27175168ba37949f000000000000000000000000000000000000000000000000015cf863e114dd4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d75e5fdf2ffd3453434d89ca32e67b94b9331b70000000000000000000000004d75e5fdf2ffd3453434d89ca32e67b94b9331b7000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000004c411485477522813167cfecc71393ea8b2ca0100000000000000000000000004c411485477522813167cfecc71393ea8b2ca0100000000000000000000000000000000000000000000000000000000034e21d000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11503,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba8180be54f0ba63b522cf0b7aa0c224e8f85e2f000000000000000000000000ba8180be54f0ba63b522cf0b7aa0c224e8f85e2f000000000000000000000000000000000000000000000000001aa71cdf88da3100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d41aa4577d756c05bff040abfd9b106056479290000000000000000000000000d41aa4577d756c05bff040abfd9b10605647929000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d41aa4577d756c05bff040abfd9b106056479290000000000000000000000000d41aa4577d756c05bff040abfd9b10605647929000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d41aa4577d756c05bff040abfd9b106056479290000000000000000000000000d41aa4577d756c05bff040abfd9b10605647929000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11507,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029acac16c2d740838ad2ea70906f7770ff7d61d500000000000000000000000029acac16c2d740838ad2ea70906f7770ff7d61d500000000000000000000000000000000000000000000000002b3b697072410f400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa819870defd32e40a530bba66ce1c2a20587ec83732ec8c4d7e1aa93fcde9fe3,2022-04-21 00:40:19.000 UTC,0,true +11509,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008be11e449bc40d84c94ef7cc4b7fc7e05fda80110000000000000000000000008be11e449bc40d84c94ef7cc4b7fc7e05fda801100000000000000000000000000000000000000000000000000683a6e4f78360000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d52d6970660cf9b5fb02be7c8c9accd14e57de30000000000000000000000000d52d6970660cf9b5fb02be7c8c9accd14e57de300000000000000000000000000000000000000000000000000152451ac8208f8400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11512,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0d941e4ab7ae78b1f287a5df076d88338466460000000000000000000000000a0d941e4ab7ae78b1f287a5df076d8833846646000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11513,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0d941e4ab7ae78b1f287a5df076d88338466460000000000000000000000000a0d941e4ab7ae78b1f287a5df076d8833846646000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11514,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4b5364b23202aa18bb38c6b82bcc0910ad8eec4000000000000000000000000e4b5364b23202aa18bb38c6b82bcc0910ad8eec40000000000000000000000000000000000000000000000000000ffd0a23a250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11515,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000039f6a4c70c582d90b403f2d72d897577830fa45b0000000000000000000000000000000000000000000000002a9046a26e95f6e2,0x92ad0957ac447e4bf29551326dfb8aea7318333b9e7f494395f6f336716e5ee1,2022-05-06 09:32:13.000 UTC,0,true +11516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048618c2aa5367a39d3e5b50c1c73a20c8a526dc600000000000000000000000048618c2aa5367a39d3e5b50c1c73a20c8a526dc600000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe7bce3571c11d9b4643de81b6be89e2114c144a75f01a1c44d33e639557c805f,2022-08-04 12:57:56.000 UTC,0,true +11519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000c42bf74b2994882212034f15342cbe3520ef50d5000000000000000000000000c42bf74b2994882212034f15342cbe3520ef50d5000000000000000000000000000000000000000000000000000000000a31acbd00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11521,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000060a9a65a99fdb184b6d2ba75010a789b725979c600000000000000000000000060a9a65a99fdb184b6d2ba75010a789b725979c60000000000000000000000000000000000000000000000000de433da14b5d66200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11527,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006710f4d73f116f7204629d511dbfff128f6aed290000000000000000000000006710f4d73f116f7204629d511dbfff128f6aed290000000000000000000000000000000000000000000000000f123f3f0213000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e558abb2f5a0dec4192a71ffcce766a2986fc900000000000000000000000004e558abb2f5a0dec4192a71ffcce766a2986fc9000000000000000000000000000000000000000000000000000060a24181e400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057cc8aeb3765b260fa6e058104cf56dbf7cf051300000000000000000000000057cc8aeb3765b260fa6e058104cf56dbf7cf051300000000000000000000000000000000000000000000000000e835dc79935ad100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x085b6dbd607994e4287a09a0020f1c5b1e5ee0b909020acd3ff39836b23ec6e1,2022-04-21 00:43:07.000 UTC,0,true +11530,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2fe5797f43f6e1932b9e78c3aa4599ca8f92e83000000000000000000000000f2fe5797f43f6e1932b9e78c3aa4599ca8f92e830000000000000000000000000000000000000000000000000045a17b942c0f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e760f55753a38ef936aab6c1e6e9b6951afca1f0000000000000000000000000e760f55753a38ef936aab6c1e6e9b6951afca1f00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11532,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000890bf4a988c8c846fdeb8a35aed0f53fb139904c000000000000000000000000890bf4a988c8c846fdeb8a35aed0f53fb139904c000000000000000000000000000000000000000000000000003a96c516ac3b2a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e939d5f4ea6566a1a1f674d16446d83d60dbba40000000000000000000000009e939d5f4ea6566a1a1f674d16446d83d60dbba400000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11534,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d226904f0584d1ed41bacb99d295d41757719330000000000000000000000003d226904f0584d1ed41bacb99d295d41757719330000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11535,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000003d226904f0584d1ed41bacb99d295d41757719330000000000000000000000003d226904f0584d1ed41bacb99d295d41757719330000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004372586e924a21264c5c2ef74aeea85dda9d17b60000000000000000000000004372586e924a21264c5c2ef74aeea85dda9d17b6000000000000000000000000000000000000000000000000011a571a18f6d20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f9ea193a21b446f62264a8f0c354c293447507f0000000000000000000000002f9ea193a21b446f62264a8f0c354c293447507f0000000000000000000000000000000000000000000000000015b83a6a9a5eb600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11542,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000c61f03c27a1df9c5f1967c98f0c33a86db2e5e87000000000000000000000000c61f03c27a1df9c5f1967c98f0c33a86db2e5e870000000000000000000000000000000000000000000000000000000000b71b0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000694580c722c01e65125a2013d3e83a360d78faa0000000000000000000000000694580c722c01e65125a2013d3e83a360d78faa000000000000000000000000000000000000000000000000000000000296baa800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11545,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000694580c722c01e65125a2013d3e83a360d78faa0000000000000000000000000694580c722c01e65125a2013d3e83a360d78faa000000000000000000000000000000000000000000000000001611a9b980b6c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008620262510c86943fd841ec2047dfc2953afaea40000000000000000000000008620262510c86943fd841ec2047dfc2953afaea4000000000000000000000000000000000000000000000000006b6a681ce4941f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e9d2c76cf11bd7720b723743a49a422a41744990000000000000000000000006e9d2c76cf11bd7720b723743a49a422a417449900000000000000000000000000000000000000000000000000012c221cc6a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000158dc5b8d904b089e60f26dc6e46c7eaaa45ab19000000000000000000000000158dc5b8d904b089e60f26dc6e46c7eaaa45ab190000000000000000000000000000000000000000000000000000000001cd048700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ad8c8b5e49ca573b5773d1341f94a0cf4a7f87e0000000000000000000000003ad8c8b5e49ca573b5773d1341f94a0cf4a7f87e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acb7acab4753e146b4b96dba23001a6e4b9641f4000000000000000000000000acb7acab4753e146b4b96dba23001a6e4b9641f40000000000000000000000000000000000000000000000000001267fd9b60f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009adcfbb8130121d16f97f8b3c85577290eada2100000000000000000000000009adcfbb8130121d16f97f8b3c85577290eada2100000000000000000000000000000000000000000000000000015c79c45df20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a74b807ba83d2d8e1eb89c52e7755d71b6997b7e000000000000000000000000a74b807ba83d2d8e1eb89c52e7755d71b6997b7e00000000000000000000000000000000000000000000000000014a047819ec0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000577261ec9ee56d7aba53992a461b5354a93bb18e000000000000000000000000577261ec9ee56d7aba53992a461b5354a93bb18e00000000000000000000000000000000000000000000000000018b75cc50ea0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008a5a39e310735d307bdf5a9d85cd43ea68a763d00000000000000000000000008a5a39e310735d307bdf5a9d85cd43ea68a763d0000000000000000000000000000000000000000000000000001398456d55b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091dfa6495e82f9693d8861df38000c07c45e5c6100000000000000000000000091dfa6495e82f9693d8861df38000c07c45e5c610000000000000000000000000000000000000000000000000001398456d55b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11562,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008774e03db6408f86a0ba2c0efa72785da6aba95e0000000000000000000000008774e03db6408f86a0ba2c0efa72785da6aba95e00000000000000000000000000000000000000000000000000014395c640470000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064811f98714304766366fe5aa4c46113f1045d9700000000000000000000000064811f98714304766366fe5aa4c46113f1045d9700000000000000000000000000000000000000000000000000014395c640470000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6e8bbf21e37a54e03350d535f929e1817cb6efc000000000000000000000000f6e8bbf21e37a54e03350d535f929e1817cb6efc000000000000000000000000000000000000000000000000000104a8cde4040000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11565,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003779a82f00cd8d1aa38f29645553511b8730692b0000000000000000000000003779a82f00cd8d1aa38f29645553511b8730692b000000000000000000000000000000000000000000000000000104a8cde4040000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dcd47ce5f406cc7538a421c6370e9205fd3bc58e000000000000000000000000dcd47ce5f406cc7538a421c6370e9205fd3bc58e000000000000000000000000000000000000000000000000000104a8cde4040000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11567,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0d941e4ab7ae78b1f287a5df076d88338466460000000000000000000000000a0d941e4ab7ae78b1f287a5df076d8833846646000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11568,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbd1532d9e42a011f96a5525ab92ad65e7aa84bb000000000000000000000000fbd1532d9e42a011f96a5525ab92ad65e7aa84bb0000000000000000000000000000000000000000000000000000a118d56d580000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11569,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0d941e4ab7ae78b1f287a5df076d88338466460000000000000000000000000a0d941e4ab7ae78b1f287a5df076d8833846646000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11570,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1b8fe74b07117cd9366efb8b8dac6a297f4c342000000000000000000000000f1b8fe74b07117cd9366efb8b8dac6a297f4c34200000000000000000000000000000000000000000000000000039ccef756f84000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11571,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e73a86165f7af016a226ac479e0bac466014609e000000000000000000000000e73a86165f7af016a226ac479e0bac466014609e0000000000000000000000000000000000000000000000000000a118d56d580000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0d941e4ab7ae78b1f287a5df076d88338466460000000000000000000000000a0d941e4ab7ae78b1f287a5df076d8833846646000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11573,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002abe428abc766f084717edd95719e2db9b43d0300000000000000000000000002abe428abc766f084717edd95719e2db9b43d030000000000000000000000000000000000000000000000000000a118d56d580000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11574,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e8414bc362f1467660f38745dd8bfc0d6e28dbc0000000000000000000000000e8414bc362f1467660f38745dd8bfc0d6e28dbc0000000000000000000000000000000000000000000000000000a118d56d580000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11575,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0b65f3c1f0b85431296df9340e34388a63891c1000000000000000000000000f0b65f3c1f0b85431296df9340e34388a63891c100000000000000000000000000000000000000000000000000001b22a0495b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11576,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008894e730951204b7d64e1f59d49709338545bcc80000000000000000000000008894e730951204b7d64e1f59d49709338545bcc80000000000000000000000000000000000000000000000000000a473fa90fc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008753f2d2c6ae30915ff0f0c2c6dbc4bcb538ffef0000000000000000000000008753f2d2c6ae30915ff0f0c2c6dbc4bcb538ffef0000000000000000000000000000000000000000000000000001002f4709d40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcffb44d92c56976fabcd4de6115cf56a7bc7146000000000000000000000000bcffb44d92c56976fabcd4de6115cf56a7bc714600000000000000000000000000000000000000000000000000006d5bae328d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11579,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8892b736ffc855e4eecf6b3ab947c61a340cb28000000000000000000000000f8892b736ffc855e4eecf6b3ab947c61a340cb2800000000000000000000000000000000000000000000000000006d5bae328d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11580,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030cd54e2a9d82760ba591a51c83cd883974dab5200000000000000000000000030cd54e2a9d82760ba591a51c83cd883974dab5200000000000000000000000000000000000000000000000000006d5bae328d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11581,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c61c0b9ff192b495a1099cbf917c833c8c086190000000000000000000000003c61c0b9ff192b495a1099cbf917c833c8c086190000000000000000000000000000000000000000000000000000c1424ead910000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11582,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bb1d9bd63345e604f020558e9058df365285fc00000000000000000000000006bb1d9bd63345e604f020558e9058df365285fc00000000000000000000000000000000000000000000000000000c1424ead910000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11583,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0d941e4ab7ae78b1f287a5df076d88338466460000000000000000000000000a0d941e4ab7ae78b1f287a5df076d8833846646000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11584,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0d941e4ab7ae78b1f287a5df076d88338466460000000000000000000000000a0d941e4ab7ae78b1f287a5df076d8833846646000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11585,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093e4abd1c5460d06260eca4de43c31ec5264c5af00000000000000000000000093e4abd1c5460d06260eca4de43c31ec5264c5af0000000000000000000000000000000000000000000000000000d5652d83690000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000646131fdebeb2db7a1b3c4cb174b916cd0a319be000000000000000000000000646131fdebeb2db7a1b3c4cb174b916cd0a319be0000000000000000000000000000000000000000000000000000899ad173dc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11587,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb49c0142bb393376f1e7504f159fca9a46e9e44000000000000000000000000cb49c0142bb393376f1e7504f159fca9a46e9e4400000000000000000000000000000000000000000000000000009f6b42db860000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11588,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c94b4d98fe35e7334bfc8cb8415830b9de454f90000000000000000000000003c94b4d98fe35e7334bfc8cb8415830b9de454f900000000000000000000000000000000000000000000000000004320c587680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11589,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000525e1aac73a5d4f5d61dc802fe2246673fea9e92000000000000000000000000525e1aac73a5d4f5d61dc802fe2246673fea9e9200000000000000000000000000000000000000000000000000004320c587680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11590,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007cb7e8fae5ceafa9ef063b54aa3258045c5023000000000000000000000000007cb7e8fae5ceafa9ef063b54aa3258045c5023000000000000000000000000000000000000000000000000000004320c587680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11591,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ab5f2ab0de0455ba06ecea8502da721f005b5330000000000000000000000004ab5f2ab0de0455ba06ecea8502da721f005b53300000000000000000000000000000000000000000000000000004320c587680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11592,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4a6bb16eca4a584cf8ba21dd86fc52da6693c50000000000000000000000000e4a6bb16eca4a584cf8ba21dd86fc52da6693c5000000000000000000000000000000000000000000000000000004320c587680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11593,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003960f374c35d8b13502528b24f55c3037387eca70000000000000000000000003960f374c35d8b13502528b24f55c3037387eca700000000000000000000000000000000000000000000000000004320c587680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11594,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007730fa4b23e5a0f6e01aa058eff275f155dc40030000000000000000000000007730fa4b23e5a0f6e01aa058eff275f155dc400300000000000000000000000000000000000000000000000000002ddf84fb040000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11595,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047a20e747763e82dd6e6339cc4f551c6d94552f200000000000000000000000047a20e747763e82dd6e6339cc4f551c6d94552f200000000000000000000000000000000000000000000000000002ddf84fb040000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11596,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e38452c4571ae2259dd5362df4559bb5c4e0d6f3000000000000000000000000e38452c4571ae2259dd5362df4559bb5c4e0d6f30000000000000000000000000000000000000000000000000000c8cf623dc20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11597,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1b8fe74b07117cd9366efb8b8dac6a297f4c342000000000000000000000000f1b8fe74b07117cd9366efb8b8dac6a297f4c34200000000000000000000000000000000000000000000000000affad2c2a47a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11598,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a2b0cbec59fa79c1239db2668afff910be0fb780000000000000000000000001a2b0cbec59fa79c1239db2668afff910be0fb78000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052870639beb9df97757882384538f8c0d2e056c300000000000000000000000052870639beb9df97757882384538f8c0d2e056c3000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11600,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f12b92d14415f71fb12b6b000e962ecd8a65f1c0000000000000000000000008f12b92d14415f71fb12b6b000e962ecd8a65f1c000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11601,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a00d212fd92b45bd0cc810c93d014916adb6bd4f000000000000000000000000a00d212fd92b45bd0cc810c93d014916adb6bd4f000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11602,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091382e33a385470061c3586d11a4716758257d1800000000000000000000000091382e33a385470061c3586d11a4716758257d18000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11603,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce31f92369461850e7a6824ce8c9c77f2ce4279b000000000000000000000000ce31f92369461850e7a6824ce8c9c77f2ce4279b000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11604,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba67979a4d652ca11c1c545739eec468abbbe122000000000000000000000000ba67979a4d652ca11c1c545739eec468abbbe122000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11605,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061afdca5ab3b32a5b54460a7e57d9f63434a3d5b00000000000000000000000061afdca5ab3b32a5b54460a7e57d9f63434a3d5b000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11606,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006dc8583a625298aaa8671b70eb3ce3b86197a5cb0000000000000000000000006dc8583a625298aaa8671b70eb3ce3b86197a5cb00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11607,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f15c653f85315a36f843f8fb85cbe587171274ca000000000000000000000000f15c653f85315a36f843f8fb85cbe587171274ca000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11608,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007edebd14451fa80394d486602cede9b12d28ca290000000000000000000000007edebd14451fa80394d486602cede9b12d28ca29000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c431698ca9876356e7c323eac9cc35da28182650000000000000000000000007c431698ca9876356e7c323eac9cc35da2818265000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11610,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c536b179274d0e545631200f8c9244fb65bc30c3000000000000000000000000c536b179274d0e545631200f8c9244fb65bc30c300000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11611,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000caee6f7d0562ea2f12964aacab17cb011bfafe9d000000000000000000000000caee6f7d0562ea2f12964aacab17cb011bfafe9d000000000000000000000000000000000000000000000000001e94524ed3010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11612,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b3e1735989bf78a070231aecc6b13166d085a4b0000000000000000000000007b3e1735989bf78a070231aecc6b13166d085a4b00000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11613,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006635fdbdbbeb9df291121aff8cf143ef99f98dfc0000000000000000000000006635fdbdbbeb9df291121aff8cf143ef99f98dfc00000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11614,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aee527ad6aee9243b49ed7dfb6a533bf355b60f4000000000000000000000000aee527ad6aee9243b49ed7dfb6a533bf355b60f400000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11615,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9085ee5e61775c7a88d329d6829e77f6a712c59000000000000000000000000f9085ee5e61775c7a88d329d6829e77f6a712c5900000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dba18812ee9b2f25773ace23bf34ef2db7e79737000000000000000000000000dba18812ee9b2f25773ace23bf34ef2db7e7973700000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11617,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b198861ea2c62ff1c96d3424a441296c4a54fae1000000000000000000000000b198861ea2c62ff1c96d3424a441296c4a54fae100000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11618,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074aa8463874aebb1ae29be8f8ba1adc322a9402d00000000000000000000000074aa8463874aebb1ae29be8f8ba1adc322a9402d000000000000000000000000000000000000000000000000001b7dd8d2d8a67000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11619,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b198861ea2c62ff1c96d3424a441296c4a54fae1000000000000000000000000b198861ea2c62ff1c96d3424a441296c4a54fae1000000000000000000000000000000000000000000000000000c7606fae9420000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11620,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000516f7df8b3ff2787e6086534435e8fea9f14fd29000000000000000000000000516f7df8b3ff2787e6086534435e8fea9f14fd29000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000001c7de0e480812e74f76b83a81cd6453da5bf30000000000000000000000000001c7de0e480812e74f76b83a81cd6453da5bf3000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11622,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084c641b467ba83ea61d68d0bb589a3e47f447c2b00000000000000000000000084c641b467ba83ea61d68d0bb589a3e47f447c2b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6463d3bb34f80da48008eb8610c6a221e782808000000000000000000000000f6463d3bb34f80da48008eb8610c6a221e7828080000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11624,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099f316195d72f7627d22a7994f0abac609af751400000000000000000000000099f316195d72f7627d22a7994f0abac609af75140000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f07780f9a8e3835befaa4bfee05fe1fe60b1f4cb000000000000000000000000f07780f9a8e3835befaa4bfee05fe1fe60b1f4cb0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005956e5e6b032f5b0f34faf2f8f99ec158f278f9c0000000000000000000000005956e5e6b032f5b0f34faf2f8f99ec158f278f9c000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3e5ff75cf6e0f0c90d0baa305b2ce33dbfeced3000000000000000000000000d3e5ff75cf6e0f0c90d0baa305b2ce33dbfeced30000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048ee21533af3087ea90b3efeb94334cc528f512800000000000000000000000048ee21533af3087ea90b3efeb94334cc528f51280000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068d227556054b7bf14ca43a1b9b96387098033e800000000000000000000000068d227556054b7bf14ca43a1b9b96387098033e80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11630,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021617c7270f645e59e9da4a6fd1269b56953199600000000000000000000000021617c7270f645e59e9da4a6fd1269b5695319960000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5bd0596b241e9954ca6da08132de7fea11238d0000000000000000000000000d5bd0596b241e9954ca6da08132de7fea11238d00000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008aa6869c58b6be38dc61c1ca883cff5a59b2d3020000000000000000000000008aa6869c58b6be38dc61c1ca883cff5a59b2d3020000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d43867c2bb79bc362e96b14528c977053aefff6f000000000000000000000000d43867c2bb79bc362e96b14528c977053aefff6f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c40082505b0d4481384b2208c0c61a0ca55ebaa4000000000000000000000000c40082505b0d4481384b2208c0c61a0ca55ebaa40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a0101ede2d003f78d70310379b1d294eba4c4530000000000000000000000000a0101ede2d003f78d70310379b1d294eba4c4530000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11637,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d391e8aeac08f158c789d15de0862b25f5b8f32a000000000000000000000000d391e8aeac08f158c789d15de0862b25f5b8f32a000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000b24adeb0b9fbbca38192c4104120d0065d3d67fe000000000000000000000000b24adeb0b9fbbca38192c4104120d0065d3d67fe0000000000000000000000000000000000000000000000000000000001c8cfaa00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11640,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003c264c1366ebd96542098d3506f0d3be8d25ee380000000000000000000000000000000000000000000000001b56d88fff850000,,,1,true +11642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000a70fe1e31c432658b1903502979a6e01092113ff000000000000000000000000a70fe1e31c432658b1903502979a6e01092113ff0000000000000000000000000000000000000000000000000000000001c9c38000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b18e2769c8f29bb604d517e6f4167869adb88ab0000000000000000000000001b18e2769c8f29bb604d517e6f4167869adb88ab000000000000000000000000000000000000000000000000015418c5f4bc438900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11645,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f804bc24fca7df18e5fee7ceabf553f00c049f90000000000000000000000006f804bc24fca7df18e5fee7ceabf553f00c049f900000000000000000000000000000000000000000000000000044364c5bb000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11646,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b1d10ac24be13ddd7c4186490dacf50727ffff40000000000000000000000008b1d10ac24be13ddd7c4186490dacf50727ffff4000000000000000000000000000000000000000000000000000665172898800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11648,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e695826d245ea190c9414df6c4eae980174bcbb0000000000000000000000003e695826d245ea190c9414df6c4eae980174bcbb000000000000000000000000000000000000000000000000000665172898800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11649,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db7ffb5ef7d6a059f914884fc7c33f7eeb194b5c000000000000000000000000db7ffb5ef7d6a059f914884fc7c33f7eeb194b5c000000000000000000000000000000000000000000000000000665172898800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005dff7f38b4869eac1639e32c0c32e824d3be6cc60000000000000000000000005dff7f38b4869eac1639e32c0c32e824d3be6cc600000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11654,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004adce7bbd76ac682b51a83a2b41562a3c17449900000000000000000000000004adce7bbd76ac682b51a83a2b41562a3c174499000000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b67fff3fb149c9009502e107fd51815ab329b4ea000000000000000000000000b67fff3fb149c9009502e107fd51815ab329b4ea00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000824b83fce26b47e3f362610ea0e24af489ae4fb4000000000000000000000000824b83fce26b47e3f362610ea0e24af489ae4fb400000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11657,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000254be7b39396b1a9fceac3685f57d3b04d717ab2000000000000000000000000254be7b39396b1a9fceac3685f57d3b04d717ab2000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093ea069784ba3580805ca976455201dff1cdc53f00000000000000000000000093ea069784ba3580805ca976455201dff1cdc53f0000000000000000000000000000000000000000000000000010a153a7476cab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4839c439a8646a64c7ce5a7da008a5d0062d4bc000000000000000000000000c4839c439a8646a64c7ce5a7da008a5d0062d4bc00000000000000000000000000000000000000000000000000277ce89ab52ae300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11660,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000aa33d9bcdcebe2db009ac6849aa305f8a7ee5600000000000000000000000000aa33d9bcdcebe2db009ac6849aa305f8a7ee56000000000000000000000000000000000000000000000000009e3a48c03141ce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036c88373b259a8e7947e0a36072adaa733c794b900000000000000000000000036c88373b259a8e7947e0a36072adaa733c794b900000000000000000000000000000000000000000000000000ffd8e1655634b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11666,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e866fb89265ae8f9f9ef5f4b0d30f6f30eb13c84000000000000000000000000e866fb89265ae8f9f9ef5f4b0d30f6f30eb13c8400000000000000000000000000000000000000000000000000e31bfcf8ba820000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11667,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a668818c0e0f43811ed647e49799ba22181d832a000000000000000000000000a668818c0e0f43811ed647e49799ba22181d832a00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11671,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078f4775fb0ad590d7790bcbe460ae4304b06d02b00000000000000000000000078f4775fb0ad590d7790bcbe460ae4304b06d02b0000000000000000000000000000000000000000000000000076097db36b977d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x24f718c2a3349a1230aba5e5d663b3bd4be2b819cb92251fc322f5ed2c30dc80,2022-03-28 06:50:26.000 UTC,0,true +11672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d27cfb08a7e2c32dfddb0ca0496af5a9d1148f30000000000000000000000007d27cfb08a7e2c32dfddb0ca0496af5a9d1148f3000000000000000000000000000000000000000000000000003630fb5e01fdc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11674,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005234ec9b99d1ded2c9bd394cd0e786b1a43806c10000000000000000000000005234ec9b99d1ded2c9bd394cd0e786b1a43806c1000000000000000000000000000000000000000000000000014ed85e68f59fe500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11675,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000403c2d4099179e178a0b9860139f0284a63c8690000000000000000000000000403c2d4099179e178a0b9860139f0284a63c86900000000000000000000000000000000000000000000000000c7d713b49da000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049d2db5f6c17a5a2894f52125048aaa98885000900000000000000000000000049d2db5f6c17a5a2894f52125048aaa98885000900000000000000000000000000000000000000000000000000564e2aaf3b19f600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11683,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ba9e3d69f573c1c79c7d66e8a0d096583b524540000000000000000000000004ba9e3d69f573c1c79c7d66e8a0d096583b5245400000000000000000000000000000000000000000000000006e151cceff9115a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcc34be4cce3c236ccc2e4b9940c874c13d05ed3000000000000000000000000bcc34be4cce3c236ccc2e4b9940c874c13d05ed300000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11687,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c9d9fc19515b544f84b597af87da1f7d60c86460000000000000000000000008c9d9fc19515b544f84b597af87da1f7d60c864600000000000000000000000000000000000000000000000001670911247c87bf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11690,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af884a663e7353d8adf6a2cbea90eb5961296136000000000000000000000000af884a663e7353d8adf6a2cbea90eb596129613600000000000000000000000000000000000000000000000006dd1fce7a1ce40500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2795f799d8095f694b7362dad309550236506b3e91a93d372687353f6b199e48,2022-02-15 10:53:27.000 UTC,0,true +11697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f6510b68c671514190e6c3bc74ec4a316970e0e0000000000000000000000006f6510b68c671514190e6c3bc74ec4a316970e0e00000000000000000000000000000000000000000000000000a5185ce924dbca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11699,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006f6634b2aab01df7f47f615fb4e2b876bd3ae5ea0000000000000000000000000000000000000000000000043b6293db1d233a0e,0x548764f6aceeddd484701201a1dcd73b7898582a84d87550710b9b1afcd5aaed,2021-12-26 23:37:59.000 UTC,0,true +11702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf053cd97db53e930e03ca1e6dab3c7507b6e2fb000000000000000000000000cf053cd97db53e930e03ca1e6dab3c7507b6e2fb000000000000000000000000000000000000000000000000001f467897a1980000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000885fbc6e02db6b1d26de3f73e80ad7f1ddc10021000000000000000000000000885fbc6e02db6b1d26de3f73e80ad7f1ddc1002100000000000000000000000000000000000000000000000000cb7dd7974e1e9100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x658d664b433c9ae3c7b6af92b84de682cce84f0e36ef18f6761d5092df8bdf24,2022-02-13 14:11:20.000 UTC,0,true +11710,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd46396d5a6f7429edde41020601c37fb986f1f0000000000000000000000000fd46396d5a6f7429edde41020601c37fb986f1f0000000000000000000000000000000000000000000000000001b5113435414c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11711,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6a7b804644124978896dc656c886fa4dcd36156000000000000000000000000b6a7b804644124978896dc656c886fa4dcd36156000000000000000000000000000000000000000000000000009d73da8bdfc12700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8d9a32e521b309f01766b00d3b1cdf886025092bcb33165086d696c6f0a38ca5,2022-02-13 14:11:59.000 UTC,0,true +11713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045c1cc34a0981e5d91fb683a6f7756698a643e7b00000000000000000000000045c1cc34a0981e5d91fb683a6f7756698a643e7b000000000000000000000000000000000000000000000000000e7e241056de0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005be10f3434bc1ac6c0a34f86da39ea0095392f210000000000000000000000005be10f3434bc1ac6c0a34f86da39ea0095392f21000000000000000000000000000000000000000000000000003c29d8fcb4790000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11720,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf9ffdfb47332beee87adbd06724459a82cf639f000000000000000000000000cf9ffdfb47332beee87adbd06724459a82cf639f000000000000000000000000000000000000000000000000009b6a90700b6bcf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11722,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e19adc684c906dda7f425eb49763adddcb83f81e000000000000000000000000e19adc684c906dda7f425eb49763adddcb83f81e0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11724,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000467ba81768726359f4a5172e2c548902ff880ef0000000000000000000000000467ba81768726359f4a5172e2c548902ff880ef000000000000000000000000000000000000000000000000000ac48f4bde5d52d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x44207f02f8a62576f7e259d5042ebe5a21d9b13a10d8b85985cfef6015cd26ab,2022-08-01 01:28:30.000 UTC,0,true +11730,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006da005df546294539904fd749a953849db2b45e00000000000000000000000006da005df546294539904fd749a953849db2b45e00000000000000000000000000000000000000000000000000057c7a330b8d60200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x084eed396a65c452d14f68a981a02c59f17387f101a58b3c984696e8c9854f34,2022-03-15 06:39:59.000 UTC,0,true +11733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6c8c9479772775c7577c5fecea9621df7c1175a000000000000000000000000f6c8c9479772775c7577c5fecea9621df7c1175a00000000000000000000000000000000000000000000000000a3fbf3d40a14ca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025950f980176941e146b8a4bf8cdf48b2631463400000000000000000000000025950f980176941e146b8a4bf8cdf48b263146340000000000000000000000000000000000000000000000000080e373da35bd6400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11743,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019601a8469f4e1ff0ecbae0b5be957efe7f7f1e100000000000000000000000019601a8469f4e1ff0ecbae0b5be957efe7f7f1e1000000000000000000000000000000000000000000000000001a51bfc567e1c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11744,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002e50a97212a0c1bef5cea4a5edb0f6309b11a8a90000000000000000000000002e50a97212a0c1bef5cea4a5edb0f6309b11a8a900000000000000000000000000000000000000000000003ed493ca13f1dba7be00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11748,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003755b30ed3f778c526fd8eebd7b8adefce1f62970000000000000000000000003755b30ed3f778c526fd8eebd7b8adefce1f6297000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11751,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dab8c2d612826775ecfeb22c46298bfcdf456649000000000000000000000000dab8c2d612826775ecfeb22c46298bfcdf456649000000000000000000000000000000000000000000000000058d15e17628000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11756,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064364de05b2fa5255e9733e4ef6394a98d5fd16c00000000000000000000000064364de05b2fa5255e9733e4ef6394a98d5fd16c00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fb682dba959981243ee93a73ee81bc38f9983f00000000000000000000000008fb682dba959981243ee93a73ee81bc38f9983f000000000000000000000000000000000000000000000000000595e70acea06f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11761,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a3a9196408d30e8b3809780432d35ee090a31d10000000000000000000000003a3a9196408d30e8b3809780432d35ee090a31d100000000000000000000000000000000000000000000000003782dace9d9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fc6bc21172b32b445c84e07e4d219fcf04756140000000000000000000000000fc6bc21172b32b445c84e07e4d219fcf047561400000000000000000000000000000000000000000000000000c9897e80af132700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9a04f3b03ee261c57149ec9b00031b187bf59207f2cc54cfb87af6ec25400dfd,2022-03-06 04:58:54.000 UTC,0,true +11769,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f459dc2a1dac3cfb64dc5dceba6ab02d8e1fc1c0000000000000000000000004f459dc2a1dac3cfb64dc5dceba6ab02d8e1fc1c0000000000000000000000000000000000000000000000000018a2000fa188c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11771,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001de489664453556166157824d6b853df73cb4e8e0000000000000000000000001de489664453556166157824d6b853df73cb4e8e0000000000000000000000000000000000000000000000000ddac67e2f17319000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da0495efc637cb645d4c81f684bbc5af7d8a3fdc000000000000000000000000da0495efc637cb645d4c81f684bbc5af7d8a3fdc00000000000000000000000000000000000000000000000001988fe4052b800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd737e94b8e5f9530d2450892e46e7c6facaab937f54f96281f57a7eebca3f5a4,2022-02-27 03:23:05.000 UTC,0,true +11779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000528c81bf6af32e5f6a4a39a0990cb01d1a121a49000000000000000000000000528c81bf6af32e5f6a4a39a0990cb01d1a121a4900000000000000000000000000000000000000000000000002a303fe4b53000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbe08285497966bb82f98d899dd5914129caaf3bb6826b1584fa04eb18f39d3a0,2022-02-27 03:19:59.000 UTC,0,true +11783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002282bc8e090439a0195e0c862ae3ffc47bd2edd80000000000000000000000002282bc8e090439a0195e0c862ae3ffc47bd2edd80000000000000000000000000000000000000000000000000020fe64314c270000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029867e23140a908770b750fb4e30f35c619a3b3a00000000000000000000000029867e23140a908770b750fb4e30f35c619a3b3a00000000000000000000000000000000000000000000000000cc5c6677b702f800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f60000000000000000000000007e363fd04efec7050be8e8bb1adfb22f44e7c3e60000000000000000000000007e363fd04efec7050be8e8bb1adfb22f44e7c3e6000000000000000000000000000000000000000000000000ae88baa6de28dbef00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11788,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e81669100000000000000000000000082b7062e1bd9a0e1b6caaf031311fcba585a8fd600000000000000000000000082b7062e1bd9a0e1b6caaf031311fcba585a8fd6000000000000000000000000000000000000000000000000a531b37bb7d66b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000741f0e84e8115dc41a03f27ade25ce8bfca3cd35000000000000000000000000741f0e84e8115dc41a03f27ade25ce8bfca3cd3500000000000000000000000000000000000000000000000001cdda4faccd000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb1f304788f99ac59828b3f4f377032661e60c6dbd33ae8058513e60c580beb6f,2022-05-08 01:15:20.000 UTC,0,true +11790,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000098ae0e9d9b63cbed47db9b456b51e58c7b87328000000000000000000000000098ae0e9d9b63cbed47db9b456b51e58c7b8732800000000000000000000000000000000000000000000000000ac4d594064aa8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11791,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000068f180fcce6836688e9084f035309e29bf0a2095000000000000000000000000bef448d1598e91e37a037fef50993af4a0f827be000000000000000000000000bef448d1598e91e37a037fef50993af4a0f827be000000000000000000000000000000000000000000000000000000000004880100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b77a6d92fc116a6a3e2bd441e9623172e7f0623a000000000000000000000000b77a6d92fc116a6a3e2bd441e9623172e7f0623a0000000000000000000000000000000000000000000000000160eeb21b507d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000968cb804437f8698bd2bcc5481bd56bec96c1a1c000000000000000000000000968cb804437f8698bd2bcc5481bd56bec96c1a1c00000000000000000000000000000000000000000000000000a6f8cd5d2d046700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5d6cd6a575a387eaacb9d27e23c67de82879a9c593ef93a4de2d29c552e204a5,2022-04-17 00:12:45.000 UTC,0,true +11798,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000004defc44cdfd3eee7fae1d5a3901e97b27cd01e3c0000000000000000000000004defc44cdfd3eee7fae1d5a3901e97b27cd01e3c00000000000000000000000000000000000000000000000000000000018b5bc300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11799,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000064c0ff667164e973b2c4d7fbab01cbe41ef84c3e000000000000000000000000000000000000000000000001975567701a9e1179,,,1,true +11800,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002282bc8e090439a0195e0c862ae3ffc47bd2edd80000000000000000000000002282bc8e090439a0195e0c862ae3ffc47bd2edd80000000000000000000000000000000000000000000000000022cd8672976b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11802,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a365df59857437932bd0394775ac957745edce20000000000000000000000006a365df59857437932bd0394775ac957745edce200000000000000000000000000000000000000000000000002fdf30fe18606aa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11805,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e07a438db3505bcec55417096d4361ef9e8f30f0000000000000000000000008e07a438db3505bcec55417096d4361ef9e8f30f0000000000000000000000000000000000000000000000000dcf70ef714dc79900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11808,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000509e427f5b930822094f203a7ea67d22aa32076b000000000000000000000000509e427f5b930822094f203a7ea67d22aa32076b0000000000000000000000000000000000000000000000000dd0565ed3444ca400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5075031f937830a3daf7ae5c3089aeb8fd8a5db1c018e203c59da700fee35dc1,2022-06-01 01:55:47.000 UTC,0,true +11810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044c485a970fc789a64584edacbb32088df5c3ec400000000000000000000000044c485a970fc789a64584edacbb32088df5c3ec4000000000000000000000000000000000000000000000000042e4b861038adec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c9e03c778ec2196c84b0f9281761e5f0c966bd80000000000000000000000002c9e03c778ec2196c84b0f9281761e5f0c966bd800000000000000000000000000000000000000000000000000a8735a5928b5ee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcad1ab53d788e90076a6728de272fdc139f38e9fce25d19bf59a44c16b133e7f,2022-05-19 05:56:09.000 UTC,0,true +11823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb5337c8f4f0ba489a995b863eea29e8c2999664000000000000000000000000bb5337c8f4f0ba489a995b863eea29e8c299966400000000000000000000000000000000000000000000000003e650740306620500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3ddf90e32936b03deb7b035e41b0a761fe764a7cbd27cce15727408c14f2209a,2022-04-13 06:23:46.000 UTC,0,true +11824,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004a9a4e4098dadf71d63b53e1b948b501a56fa9920000000000000000000000004a9a4e4098dadf71d63b53e1b948b501a56fa9920000000000000000000000000000000000000000000000a621f311b9214edc6c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a9a4e4098dadf71d63b53e1b948b501a56fa9920000000000000000000000004a9a4e4098dadf71d63b53e1b948b501a56fa9920000000000000000000000000000000000000000000000000e692456d8b2e4c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f82a06ee5c6ec735a49bb646f6e401b60f464f10000000000000000000000008f82a06ee5c6ec735a49bb646f6e401b60f464f100000000000000000000000000000000000000000000000002be23d896db90f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003a1eeb08c6df9348956414192c16f00d206291f00000000000000000000000003a1eeb08c6df9348956414192c16f00d206291f0000000000000000000000000000000000000000000000000dd00157fd89767700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000055affa6bdc01d0cfa8a738b068ece76e56dad51000000000000000000000000055affa6bdc01d0cfa8a738b068ece76e56dad510000000000000000000000000000000000000000000000000012da295010a75700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a196c9a7d4c5bae6e7f6bec1a5af7ea9a4cac2ef000000000000000000000000a196c9a7d4c5bae6e7f6bec1a5af7ea9a4cac2ef0000000000000000000000000000000000000000000000000017719bc4bfa40100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acecb5340a939ee1b9e7ceb975d9ecef88e25bc6000000000000000000000000acecb5340a939ee1b9e7ceb975d9ecef88e25bc6000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e5ed3d9e994b6e8cbf1e82e303bfbd0d89b3f890000000000000000000000002e5ed3d9e994b6e8cbf1e82e303bfbd0d89b3f890000000000000000000000000000000000000000000000000ad0ef5d88402d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031229af0915aa6b3a0f7badac595f8fc90a6534f00000000000000000000000031229af0915aa6b3a0f7badac595f8fc90a6534f00000000000000000000000000000000000000000000000000689ff372ee570000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9744cd4aa86dd1b338f02e00ae02c3ddfa39d18000000000000000000000000d9744cd4aa86dd1b338f02e00ae02c3ddfa39d18000000000000000000000000000000000000000000000000009801e77f02404800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11838,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bd825705ffe24abed5dc12cd1e3b789253b82e3e00000000000000000000000000000000000000000000000031c9703005a731f1,,,1,true +11840,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9c45b6e9a9c2d58dedc192f3eee627dde5d9a3f000000000000000000000000f9c45b6e9a9c2d58dedc192f3eee627dde5d9a3f000000000000000000000000000000000000000000000000003db6579b2724fa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099c794b7a618f72e89387821b6f184598d75fb4800000000000000000000000099c794b7a618f72e89387821b6f184598d75fb480000000000000000000000000000000000000000000000000160b486423c0d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abdcfd11af016bbd617847a464a87993cc61c050000000000000000000000000abdcfd11af016bbd617847a464a87993cc61c050000000000000000000000000000000000000000000000000060cfbb0a212000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcdb881647ef8144a3583faa156dda9d4ae209f34f1b23aed47b136b5220a2e2c,2022-03-08 04:13:25.000 UTC,0,true +11847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066d9679255db0d846c60aeaa6eb8ffb91e57751b00000000000000000000000066d9679255db0d846c60aeaa6eb8ffb91e57751b0000000000000000000000000000000000000000000000000064c13096283b5e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000588ea768aeb968da685022c5b28760d39937dd9f000000000000000000000000588ea768aeb968da685022c5b28760d39937dd9f00000000000000000000000000000000000000000000000002e86a9cc2020a8a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x57b0ac509a37aac6941d7cc8e820345b6d4705d921b0d1f179fe978a16d9c798,2021-11-28 10:49:01.000 UTC,0,true +11852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000082747972853c8da3d53ad554cf0c3fed8eed4c1000000000000000000000000082747972853c8da3d53ad554cf0c3fed8eed4c100000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000082747972853c8da3d53ad554cf0c3fed8eed4c1000000000000000000000000082747972853c8da3d53ad554cf0c3fed8eed4c1000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000478c1cdd7f51b9ff7e08434363364e9e79784d85000000000000000000000000478c1cdd7f51b9ff7e08434363364e9e79784d8500000000000000000000000000000000000000000000000001546ed86f36746a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d8e211913247a0ec5454137e7a6ed18ed727a2f0000000000000000000000002d8e211913247a0ec5454137e7a6ed18ed727a2f000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11859,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037ef6c69278b5107dfa058d86e13a1c0cb7f54c900000000000000000000000037ef6c69278b5107dfa058d86e13a1c0cb7f54c9000000000000000000000000000000000000000000000000015f0d455ac1e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9b867c876a81d1b82278872cd9fab15462196f1000000000000000000000000a9b867c876a81d1b82278872cd9fab15462196f100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11862,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006316c0c5d19e9c5a957d7e411d2179ec05637d0b0000000000000000000000006316c0c5d19e9c5a957d7e411d2179ec05637d0b00000000000000000000000000000000000000000000000001611502adfcb80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061f3be073bd5c5a6ed11443e51744ce505e27b8500000000000000000000000061f3be073bd5c5a6ed11443e51744ce505e27b85000000000000000000000000000000000000000000000000008142d82123380000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a8f606325d5f74e58575353dcee9993b032b2380000000000000000000000009a8f606325d5f74e58575353dcee9993b032b23800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3925751f682f1dc13310ca2bafb96cd1cf770a7000000000000000000000000d3925751f682f1dc13310ca2bafb96cd1cf770a700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099e5eb0fa8ce36525cfe5c434b3f26befd7f0d6700000000000000000000000099e5eb0fa8ce36525cfe5c434b3f26befd7f0d67000000000000000000000000000000000000000000000000015c4678bd3ebfd500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11874,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcb6b92e6e5460a9f6d759988b04af1fc30d75f6000000000000000000000000fcb6b92e6e5460a9f6d759988b04af1fc30d75f60000000000000000000000000000000000000000000000000373002f2e01edd000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9a796d3cc151556e04fd6e5a6b01de7f5ae343e000000000000000000000000a9a796d3cc151556e04fd6e5a6b01de7f5ae343e00000000000000000000000000000000000000000000000000aef15901c9310000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3aa68cadb8f25ad25b054841df221d234b8b374000000000000000000000000f3aa68cadb8f25ad25b054841df221d234b8b37400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c1757cdde3b690ac887ff89974758f3d07e44480000000000000000000000001c1757cdde3b690ac887ff89974758f3d07e444800000000000000000000000000000000000000000000000000a51544cbd30d9700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe332afd6dea8f0f741462aec785b902f0315d7c000000000000000000000000fe332afd6dea8f0f741462aec785b902f0315d7c000000000000000000000000000000000000000000000000010117756f62d88000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e81669100000000000000000000000099c794b7a618f72e89387821b6f184598d75fb4800000000000000000000000099c794b7a618f72e89387821b6f184598d75fb4800000000000000000000000000000000000000000000000045a7230a2814096f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11882,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000087ebf5038cacde1891683176a802c0a5b6da3cc600000000000000000000000087ebf5038cacde1891683176a802c0a5b6da3cc6000000000000000000000000000000000000000000000002c94c71ca0b6e714b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d633e9a50647707279dc8aa4c20f57959cf4c393000000000000000000000000d633e9a50647707279dc8aa4c20f57959cf4c39300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6b754372dd1c0f47652e989b2405d10783195e7000000000000000000000000d6b754372dd1c0f47652e989b2405d10783195e700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de09b5a841a33ab73099349a7927d7609b5b3cce000000000000000000000000de09b5a841a33ab73099349a7927d7609b5b3cce000000000000000000000000000000000000000000000000004ca599354b265900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d7a199c805650468374e5d76c7dce15ec9a97090000000000000000000000009d7a199c805650468374e5d76c7dce15ec9a9709000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023beea0467685c3e8ce4b31d7306b2d758010f5600000000000000000000000023beea0467685c3e8ce4b31d7306b2d758010f56000000000000000000000000000000000000000000000000002d4d45171035c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0bd01517c0ab68988c54e52b811587a9e744744000000000000000000000000e0bd01517c0ab68988c54e52b811587a9e74474400000000000000000000000000000000000000000000000001152c1292cd408b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000c28fda731c13ccf4f513f187fda345f870fc6392000000000000000000000000c28fda731c13ccf4f513f187fda345f870fc6392000000000000000000000000000000000000000000000000000000000182fd5b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001442f26e93c193e9c2107d3f90f43a841cc0faec0000000000000000000000001442f26e93c193e9c2107d3f90f43a841cc0faec0000000000000000000000000000000000000000000000000125bb1da9c30c8400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11898,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d51afe8c20a429fe6555ca4db037f6b9d26490a4000000000000000000000000d51afe8c20a429fe6555ca4db037f6b9d26490a40000000000000000000000000000000000000000000000000216e633e41b7a0200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x60b5d1c78cdd9a7b7e6a53c6ca260a813ef6da9dba24c004620c644abf8da9a9,2022-06-19 07:00:45.000 UTC,0,true +11899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005df63bf3545acfbeaf608332d767a0ef957021610000000000000000000000005df63bf3545acfbeaf608332d767a0ef9570216100000000000000000000000000000000000000000000000006edb68c71fbd80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11900,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c872cfe1511c0671c3182629d600e2f7be672750000000000000000000000005c872cfe1511c0671c3182629d600e2f7be6727500000000000000000000000000000000000000000000000000af6886b0abf5af00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11901,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d01e2010c7018aa9a10ee81beb8e88f212a12090000000000000000000000001d01e2010c7018aa9a10ee81beb8e88f212a120900000000000000000000000000000000000000000000000002be627611b7797400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x11a9d6784e037282645aec7d4aeff27acae0bce477e49d12bb6e5a927acdee66,2022-01-31 04:22:40.000 UTC,0,true +11903,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ca97ae70e38736a94eea00427d50846bab978dd0000000000000000000000007ca97ae70e38736a94eea00427d50846bab978dd000000000000000000000000000000000000000000000000003bdc7143f8b43d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4f41cfbf4e4647501149e710af3083d8ed0b5807eebd1c37444f26486e351282,2021-12-26 09:09:22.000 UTC,0,true +11904,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084bfbb65c8e7ad4cd835de354ad43a0f0f10e3b600000000000000000000000084bfbb65c8e7ad4cd835de354ad43a0f0f10e3b6000000000000000000000000000000000000000000000000012dfb0cb5e8800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11905,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a218d0ce0693c41a96f58667ba34f5f489e75628000000000000000000000000a218d0ce0693c41a96f58667ba34f5f489e7562800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ae8c2812447c23c8b721011d40fe1448e1e64b90000000000000000000000006ae8c2812447c23c8b721011d40fe1448e1e64b900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11907,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f5bf5011770655c751aa54a8a60839bf8f596ff0000000000000000000000009f5bf5011770655c751aa54a8a60839bf8f596ff00000000000000000000000000000000000000000000000000320dc09fa5168700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11908,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000007c84d134d1ac55126fb215fc35438a3c278f81b20000000000000000000000007c84d134d1ac55126fb215fc35438a3c278f81b20000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +11909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006fabc23baefcd1f1e34a25f6e54ea4d033b9362d0000000000000000000000006fabc23baefcd1f1e34a25f6e54ea4d033b9362d0000000000000000000000000000000000000000000000000087f620e8d2c2ac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3de4ef7f69d53c0ab22ca6d90ef82f9b184720fedcdfaf0a8dd21a70a10094fb,2022-02-28 03:42:38.000 UTC,0,true +11910,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004efeb767b3b0941ccbadd6cb897a391499324fd00000000000000000000000004efeb767b3b0941ccbadd6cb897a391499324fd0000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014f650b3cfbcd901893ae90fcde1b38c7077575c00000000000000000000000014f650b3cfbcd901893ae90fcde1b38c7077575c00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce9ad2ccacb8f5f36d04d1d30c1daa17f7dbb541000000000000000000000000ce9ad2ccacb8f5f36d04d1d30c1daa17f7dbb54100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037ca2fb13f200e3f922d7f07e9bef1fcfa3e8b4a00000000000000000000000037ca2fb13f200e3f922d7f07e9bef1fcfa3e8b4a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000345ebd1b3c20a7c249f9a8f1b6fcde7e531f2985000000000000000000000000345ebd1b3c20a7c249f9a8f1b6fcde7e531f29850000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a651e5c177cc60fb60529631e1b5bdd93a82fb70000000000000000000000002a651e5c177cc60fb60529631e1b5bdd93a82fb7000000000000000000000000000000000000000000000000012dfb0cb5e8800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11919,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007143c902f08212861aa5e9749f019f2feba117540000000000000000000000007143c902f08212861aa5e9749f019f2feba117540000000000000000000000000000000000000000000000000214e8348c4f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d28bf17c6b194a0aa6db97afb5c6781fc96c3fec000000000000000000000000d28bf17c6b194a0aa6db97afb5c6781fc96c3fec00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a9643a822abe24a62d989cba0ef57a8168ba3730000000000000000000000000a9643a822abe24a62d989cba0ef57a8168ba37300000000000000000000000000000000000000000000000000060a24181e400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac32406f31634322662bdc1e9f9d5ea247de7e2a000000000000000000000000ac32406f31634322662bdc1e9f9d5ea247de7e2a00000000000000000000000000000000000000000000000000aa13b7c87c0dd900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073342f619780312b3f6d85af48c64aaf8c32315d00000000000000000000000073342f619780312b3f6d85af48c64aaf8c32315d00000000000000000000000000000000000000000000000000082bd67afbc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c139649763b154b18a3407dbbc7c29c63f8e0e60000000000000000000000001c139649763b154b18a3407dbbc7c29c63f8e0e600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000568c7b10f0b0d87e88401f5167bc6db5934dfcc4000000000000000000000000568c7b10f0b0d87e88401f5167bc6db5934dfcc4000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11933,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079ce1426b21bb2cfae014388ade594666ecef4c000000000000000000000000079ce1426b21bb2cfae014388ade594666ecef4c0000000000000000000000000000000000000000000000000000c6f3b40b6c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d2b49dd577a65bb18208fb7e9be307f4b028a200000000000000000000000005d2b49dd577a65bb18208fb7e9be307f4b028a2000000000000000000000000000000000000000000000000000060a24181e400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11938,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d6129da37dad28b70ba29e542e3a0a074084c6260000000000000000000000000000000000000000000000009d4120c707de5e06,,,1,true +11939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf1967f9ec206f4bbb009eb5947f252db58e10f8000000000000000000000000bf1967f9ec206f4bbb009eb5947f252db58e10f800000000000000000000000000000000000000000000000000060a24181e400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006220c72064620a4aacc99c68677eef8bf36877f70000000000000000000000006220c72064620a4aacc99c68677eef8bf36877f700000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11942,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba139847cd31ac73d2df5862dd1b9a1269b05bf5000000000000000000000000ba139847cd31ac73d2df5862dd1b9a1269b05bf50000000000000000000000000000000000000000000000000dd4892e096c46b900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11945,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000002f67566867a23b5fc56b26a4cbe0d7eb2c76df050000000000000000000000002f67566867a23b5fc56b26a4cbe0d7eb2c76df05000000000000000000000000000000000000000000000000000000001ba2a86d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xde0e617c86199de66b80a053111b1f4ccf97174e5963e0fd6482e42c6e7f43a3,2021-12-12 07:49:39.000 UTC,0,true +11947,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea4e3a392b7a94dde227a5df50645229a69d12f7000000000000000000000000ea4e3a392b7a94dde227a5df50645229a69d12f700000000000000000000000000000000000000000000000000201a32bc25778000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11949,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea4e3a392b7a94dde227a5df50645229a69d12f7000000000000000000000000ea4e3a392b7a94dde227a5df50645229a69d12f7000000000000000000000000000000000000000000000000013a0a79480b4cdf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d28bf17c6b194a0aa6db97afb5c6781fc96c3fec000000000000000000000000d28bf17c6b194a0aa6db97afb5c6781fc96c3fec000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11957,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005558430f593a32be28dd369fab48c291a7ccfb960000000000000000000000005558430f593a32be28dd369fab48c291a7ccfb9600000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000107e60e09c1b9399c2f9c51051051acc2d5db0db000000000000000000000000107e60e09c1b9399c2f9c51051051acc2d5db0db000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac5f837b8c55c0acfef6d900db388533866050f5000000000000000000000000ac5f837b8c55c0acfef6d900db388533866050f500000000000000000000000000000000000000000000000002c06611853df7ef00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8bef80cd7a2214296355ed60b1c79cb30f2efca908004921610993295c920541,2022-03-04 10:35:33.000 UTC,0,true +11962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ab46674dfb8539ab5380173f9c86138df5230b90000000000000000000000002ab46674dfb8539ab5380173f9c86138df5230b9000000000000000000000000000000000000000000000000021e6d1855e43b8e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7c4f4c108efbe0a0ad9c0dc0920e5ecfaa52108000000000000000000000000a7c4f4c108efbe0a0ad9c0dc0920e5ecfaa521080000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11964,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f36a4ccb3b96f1e7718b12cc076506e5c0c602d3000000000000000000000000f36a4ccb3b96f1e7718b12cc076506e5c0c602d3000000000000000000000000000000000000000000000000015c622b4c412bd400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008358672afa934969f986ed644c3a8b8bcc17eec40000000000000000000000008358672afa934969f986ed644c3a8b8bcc17eec400000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001930f414f04adc142aafebf7f6651a31e6a708de0000000000000000000000001930f414f04adc142aafebf7f6651a31e6a708de000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001651106085698f19912753ef131d6a5c9c8024c40000000000000000000000001651106085698f19912753ef131d6a5c9c8024c40000000000000000000000000000000000000000000000000467e10df683db6300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d833a03f32bd62070bfc53f1e02497bb7fbbe720000000000000000000000005d833a03f32bd62070bfc53f1e02497bb7fbbe7200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11973,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050738cf28a47f00537da8cfbd2c51efc384a134a00000000000000000000000050738cf28a47f00537da8cfbd2c51efc384a134a000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000042d9ebf0e126b29824fffeb4fc4ba5393ce1975000000000000000000000000042d9ebf0e126b29824fffeb4fc4ba5393ce197500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009cdd2b751f0f88468348b6ec3f47cc6e818bcf570000000000000000000000009cdd2b751f0f88468348b6ec3f47cc6e818bcf5700000000000000000000000000000000000000000000000000aaf3bce37e735700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055ab119210fc6b44177b5c6ec08ec8289e360ce000000000000000000000000055ab119210fc6b44177b5c6ec08ec8289e360ce0000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11978,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfc2b9c3000ec2ab725b925a83b4d693077f2be1000000000000000000000000cfc2b9c3000ec2ab725b925a83b4d693077f2be100000000000000000000000000000000000000000000000000b7e1fd124360a200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11979,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047dd44a601daf48b7a5dd18fb1eb1cee14be416900000000000000000000000047dd44a601daf48b7a5dd18fb1eb1cee14be416900000000000000000000000000000000000000000000000000aab7a2e9171e0800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d5901ecad0bc8786a9b6fa53a19ce465ccba1990000000000000000000000000d5901ecad0bc8786a9b6fa53a19ce465ccba19900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a842261c0f3c9c3a9c5cb99116a4f2af7d55f8bd000000000000000000000000a842261c0f3c9c3a9c5cb99116a4f2af7d55f8bd000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11984,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c5a05853401bc0631a693ec719ca8725407db190000000000000000000000000c5a05853401bc0631a693ec719ca8725407db19000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030051dc685a3e27bc94928858d02f3b5e8835ae200000000000000000000000030051dc685a3e27bc94928858d02f3b5e8835ae2000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000890a0047f8d573347872cb6c019f86552f2367d6000000000000000000000000890a0047f8d573347872cb6c019f86552f2367d6000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014a90490a5439ae28ed1b2214355d20b5927ef8500000000000000000000000014a90490a5439ae28ed1b2214355d20b5927ef85000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11992,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075ac65073d45d3f53c66fe338827ad13ed362a8800000000000000000000000075ac65073d45d3f53c66fe338827ad13ed362a88000000000000000000000000000000000000000000000000015aeab2d7ff93a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007eff1b48ff4e4c1fad9879eef26670d49347def60000000000000000000000007eff1b48ff4e4c1fad9879eef26670d49347def6000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +11999,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000467dff5627f13b71a10a62c9d79a34be4043ae69000000000000000000000000467dff5627f13b71a10a62c9d79a34be4043ae69000000000000000000000000000000000000000000000000015c2a7b13fd000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12000,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd55c5bad3a6faab9cc7e917d03af0e91ef38f2d000000000000000000000000bd55c5bad3a6faab9cc7e917d03af0e91ef38f2d00000000000000000000000000000000000000000000000001d7aaff0c21cb9700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x357f628ca652889dc3a402959e3956dd07d675d1e62d49334317dfbd8a62bb14,2022-03-11 03:46:32.000 UTC,0,true +12003,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5dc734123047c8c2a85fe9c6c86992b575bda91000000000000000000000000e5dc734123047c8c2a85fe9c6c86992b575bda910000000000000000000000000000000000000000000000000dbd2fc137a3000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bf0d6b03588ce8a00d2c3d7fd9d1933a039c9dc0000000000000000000000004bf0d6b03588ce8a00d2c3d7fd9d1933a039c9dc00000000000000000000000000000000000000000000000001526acb1803a88000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12009,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000929a2d59f6d8f8b63d976f8053d1349032127900000000000000000000000000929a2d59f6d8f8b63d976f8053d1349032127900000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12015,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000989680e560b3374798559a1a9c11ca8eb811c979000000000000000000000000989680e560b3374798559a1a9c11ca8eb811c9790000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12016,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed6c97a0bd5c0bb5e5f3d9fc844a1b031327cb72000000000000000000000000ed6c97a0bd5c0bb5e5f3d9fc844a1b031327cb720000000000000000000000000000000000000000000000000069c84558c6391900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12017,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000487590f027355961c9f9811b602fe29c6f88055a000000000000000000000000487590f027355961c9f9811b602fe29c6f88055a00000000000000000000000000000000000000000000000000a801d1d68ceefd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12018,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2070eddf64822e36b7c57353319e2c531815b2c000000000000000000000000e2070eddf64822e36b7c57353319e2c531815b2c0000000000000000000000000000000000000000000000000289b4ac6fd6a86e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12020,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fdc62e19a5bfdc1b56a7843bf378635eb362e6e0000000000000000000000005fdc62e19a5bfdc1b56a7843bf378635eb362e6e000000000000000000000000000000000000000000000000014c1ce34b1b570400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x274cbd5daae237de00a23a25b96ced81231cd88590e0c9026fbf399cbba5acdc,2021-12-26 09:00:54.000 UTC,0,true +12021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094db391a8298d6de90892d78406551e8987c2c1a00000000000000000000000094db391a8298d6de90892d78406551e8987c2c1a0000000000000000000000000000000000000000000000000000fb90a5bda5b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030ceb5248d27cc826a7563a7abc1ce5ab166c41200000000000000000000000030ceb5248d27cc826a7563a7abc1ce5ab166c412000000000000000000000000000000000000000000000000001c04ce2b08a97500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003eb40255eecc782507c4b98c0ef7944d03a67e5d0000000000000000000000003eb40255eecc782507c4b98c0ef7944d03a67e5d0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014f4785e5f8738eb589eb0bf9edc6a5f8675594400000000000000000000000014f4785e5f8738eb589eb0bf9edc6a5f86755944000000000000000000000000000000000000000000000000001d2190327665e900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029541aa4328e1cb4d820eda83ca84dcb1a1ccd1a00000000000000000000000029541aa4328e1cb4d820eda83ca84dcb1a1ccd1a00000000000000000000000000000000000000000000000003cda88363e920ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1144dd5fce53d2b82cea0da4d97150ee584486db707cfa0cd9bdddb24d2dd635,2022-02-20 20:39:14.000 UTC,0,true +12028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096e0ea298c54f058f73e52ebf1050d0dc2c7368600000000000000000000000096e0ea298c54f058f73e52ebf1050d0dc2c736860000000000000000000000000000000000000000000000000062c446aa696af300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ed6a87517914eb67cce0930fed72e61ce2d64450000000000000000000000005ed6a87517914eb67cce0930fed72e61ce2d6445000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12031,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7ac3c661368cff60e87464b19915eaf9a5d3f8a000000000000000000000000a7ac3c661368cff60e87464b19915eaf9a5d3f8a0000000000000000000000000000000000000000000000000009adbf5e9016e200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12037,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3f2a7d831a35fba958028f4a6ca0b2003390099000000000000000000000000c3f2a7d831a35fba958028f4a6ca0b200339009900000000000000000000000000000000000000000000000003311fc80a57000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12040,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015b2745b585a07a449f4dc1c61fca4c7a446459500000000000000000000000015b2745b585a07a449f4dc1c61fca4c7a4464595000000000000000000000000000000000000000000000000003f84a6338bd6da00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12041,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069279507fc76feb6b3e455b064b52bae5043cb2500000000000000000000000069279507fc76feb6b3e455b064b52bae5043cb2500000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12042,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd2e96e66c9508029d5520f1f991e8cd8dc6e562000000000000000000000000fd2e96e66c9508029d5520f1f991e8cd8dc6e562000000000000000000000000000000000000000000000000000ba9fbe228620000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12043,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b0e303fdac2f18509793aec7e53676540f434c20000000000000000000000005b0e303fdac2f18509793aec7e53676540f434c2000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x11722756f3f34237cfca034c171999466a88d9614d07ba69fb92e593a2a99de8,2022-05-18 08:59:44.000 UTC,0,true +12045,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e39d2fa4c2881445e50ecb9319b9308a0de3b540000000000000000000000002e39d2fa4c2881445e50ecb9319b9308a0de3b5400000000000000000000000000000000000000000000000000995116b48e17a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12046,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e5847c75c961c25ecd81fcae4bb24ed5023da2a0000000000000000000000001e5847c75c961c25ecd81fcae4bb24ed5023da2a000000000000000000000000000000000000000000000000005dc59b98ecc0c100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f726679d42ce2a8e67064e090768fb2468225800000000000000000000000002f726679d42ce2a8e67064e090768fb246822580000000000000000000000000000000000000000000000000014f069a55ca39a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12056,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f75350e9e70c2531345d7b567b742923b2d8ef43000000000000000000000000f75350e9e70c2531345d7b567b742923b2d8ef4300000000000000000000000000000000000000000000000001610d759a6c870000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015097e42b6e80063967b33257d7eae981273c13500000000000000000000000015097e42b6e80063967b33257d7eae981273c1350000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006094d4b6b8d6710dd56682a73c0e6c09b4aa08c60000000000000000000000006094d4b6b8d6710dd56682a73c0e6c09b4aa08c6000000000000000000000000000000000000000000000000036e230927e3378000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fc7ef8128b2a49067783fdd0c5b58c3f8c0a8980000000000000000000000005fc7ef8128b2a49067783fdd0c5b58c3f8c0a89800000000000000000000000000000000000000000000000006e04c673618af5c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xda464806c12b2ebb4d0cfd59e4e4ae43ebee248d5236d95d97af9dcab98fd011,2022-02-16 03:29:43.000 UTC,0,true +12061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000771e53058313a5f0eb388d676cdfcd4d273ce052000000000000000000000000771e53058313a5f0eb388d676cdfcd4d273ce052000000000000000000000000000000000000000000000000000581b77f66e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12064,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba5651e3d4f3d63d19cb6e351147773dbf505095000000000000000000000000ba5651e3d4f3d63d19cb6e351147773dbf50509500000000000000000000000000000000000000000000000000a9124ad2032e2e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093074926da1378296243fc766208b841c61cde6600000000000000000000000093074926da1378296243fc766208b841c61cde66000000000000000000000000000000000000000000000000000581b77f66e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12068,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c18237f4facf817839b229ea67b94ae073be0fa9000000000000000000000000c18237f4facf817839b229ea67b94ae073be0fa9000000000000000000000000000000000000000000000000000581b77f66e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12069,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d0295e32371bc61b0c35cd9b6caf89106ad01ea0000000000000000000000005d0295e32371bc61b0c35cd9b6caf89106ad01ea000000000000000000000000000000000000000000000000001a4a42c356800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12070,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009558882b792bb58c469ad20e072e50f8bdf065cd0000000000000000000000009558882b792bb58c469ad20e072e50f8bdf065cd000000000000000000000000000000000000000000000000000581b77f66e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000268f91e2e132fde501ac194f347ae78cb907f64e000000000000000000000000268f91e2e132fde501ac194f347ae78cb907f64e00000000000000000000000000000000000000000000000000f0150773ea0dcb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2db8529fd4092888fd8137354b50d6c554c1a7daf2f2a8580a9e1c6677f63b35,2021-11-21 13:20:24.000 UTC,0,true +12078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5777aa4045d2fa53b41a2012d5d4fe814537fee000000000000000000000000a5777aa4045d2fa53b41a2012d5d4fe814537fee00000000000000000000000000000000000000000000000003311fc80a57000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9b73a69c1a59de5c89e18574adf3ce6b6d9102b000000000000000000000000b9b73a69c1a59de5c89e18574adf3ce6b6d9102b000000000000000000000000000000000000000000000000003fbc1268ef14bf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c789404d651cfc68f39b2f3dcf2feb0360460ce0000000000000000000000007c789404d651cfc68f39b2f3dcf2feb0360460ce000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6256ddff5264c3a0b3310ca673f36ea34c66945a75aa8e3092edb05a7cde595a,2022-05-18 12:55:50.000 UTC,0,true +12084,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005430c0b289a72895062941368d7ac4a78b9f94c40000000000000000000000005430c0b289a72895062941368d7ac4a78b9f94c400000000000000000000000000000000000000000000000000398b3102235ded00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060590470118e4b4797132c98fb395c18f12aa87a00000000000000000000000060590470118e4b4797132c98fb395c18f12aa87a000000000000000000000000000000000000000000000000015b151fc2d9e5f000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078b8690e940df55554fa1fde360921ee39e6ba2d00000000000000000000000078b8690e940df55554fa1fde360921ee39e6ba2d000000000000000000000000000000000000000000000000004db470adaecf0200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013b65bc0885e7d9f11f6affd0ba44c19ddc12c4100000000000000000000000013b65bc0885e7d9f11f6affd0ba44c19ddc12c41000000000000000000000000000000000000000000000000007f2e335c2e47c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe958a22c1f453c797e341c202c86ba607276c88000000000000000000000000fe958a22c1f453c797e341c202c86ba607276c88000000000000000000000000000000000000000000000000032938a8f5b0e36a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000067ffb0c645f5843ff88a6ff0fc91fd1798974e5700000000000000000000000067ffb0c645f5843ff88a6ff0fc91fd1798974e570000000000000000000000000000000000000000000000000000000000c0641000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000659f7952cf483abcb29111f0e79730328a3ca612000000000000000000000000659f7952cf483abcb29111f0e79730328a3ca61200000000000000000000000000000000000000000000000001c9ec6dfeb0a22c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12102,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca39fdb1ec1d885318e6111f2eef8b600bc33db9000000000000000000000000ca39fdb1ec1d885318e6111f2eef8b600bc33db9000000000000000000000000000000000000000000000000000d42623645a28000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12103,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004defc44cdfd3eee7fae1d5a3901e97b27cd01e3c0000000000000000000000004defc44cdfd3eee7fae1d5a3901e97b27cd01e3c0000000000000000000000000000000000000000000000000043917c6ccd9ac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d19aa0d24e604f77aba4cd250ffbaf6b15819b70000000000000000000000009d19aa0d24e604f77aba4cd250ffbaf6b15819b70000000000000000000000000000000000000000000000000040c67ea3a989b500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000106d5bcd38f25e584150e1915687675c36d28ea8000000000000000000000000106d5bcd38f25e584150e1915687675c36d28ea8000000000000000000000000000000000000000000000000005e489a8390697500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12109,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079a549989e7aecd4c0e40ed0ebb9a30350a870bd00000000000000000000000079a549989e7aecd4c0e40ed0ebb9a30350a870bd0000000000000000000000000000000000000000000000000113d7bbcf92158500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2069a1d6e737681d6dfb154e86e61c6629318116df688f0238d718546306e6da,2022-04-23 17:50:07.000 UTC,0,true +12110,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f167ddd0d854c524d5f8b16a09471a63772a8ffb000000000000000000000000f167ddd0d854c524d5f8b16a09471a63772a8ffb00000000000000000000000000000000000000000000000001596d834ee4efa200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12112,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000764ef8aba8e67af506fa65bad1342bf34571ec3e000000000000000000000000764ef8aba8e67af506fa65bad1342bf34571ec3e0000000000000000000000000000000000000000000000000002e3c65acf830000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12115,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c581081214b403b8aa2fd1098e250e0f82cd4605000000000000000000000000c581081214b403b8aa2fd1098e250e0f82cd4605000000000000000000000000000000000000000000000000020b305717a605f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12116,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e990486968daeac95fdf07ef6722ab71db276c40000000000000000000000003e990486968daeac95fdf07ef6722ab71db276c4000000000000000000000000000000000000000000000000000458d262defd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12117,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000e865637cbc8468ad4214f5055b9a7500a2b96e32000000000000000000000000e865637cbc8468ad4214f5055b9a7500a2b96e3200000000000000000000000000000000000000000000000000000000078a1cb700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x0b4e154ff93557de368a5dd1db67e2daf991a966e4cb4ae99809cc63b8fa8be1,2022-06-01 04:45:12.000 UTC,0,true +12120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b882b087bd80a0258f19d907849c8d64cac3dba1000000000000000000000000b882b087bd80a0258f19d907849c8d64cac3dba10000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a7a1c07b74806800eff667c5de512404810684f0000000000000000000000002a7a1c07b74806800eff667c5de512404810684f00000000000000000000000000000000000000000000000002b9c4e91a857eb800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb3b1918badb67b6e032052dddc7174e8adec6006aa3bf6cea7bd1e8d79ad0471,2022-02-27 18:58:51.000 UTC,0,true +12124,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021bc50129dd6c34162ec0cf715857042cd09ec2300000000000000000000000021bc50129dd6c34162ec0cf715857042cd09ec230000000000000000000000000000000000000000000000000020e96a892d660000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000aa350fb487f75d4f5d6ed920a5ae0923ded06e10000000000000000000000000aa350fb487f75d4f5d6ed920a5ae0923ded06e100000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12126,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000357e6a98da9c3bde7e17f5bcbbbd3e2107d117ba000000000000000000000000357e6a98da9c3bde7e17f5bcbbbd3e2107d117ba00000000000000000000000000000000000000000000000002bb0098c93cc62000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12129,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ca68692fc89e29f7e79cd74aeec92af4ed166460000000000000000000000003ca68692fc89e29f7e79cd74aeec92af4ed166460000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029c7ec5e8ca184ba83b970b4a89a2adb4a083dba00000000000000000000000029c7ec5e8ca184ba83b970b4a89a2adb4a083dba000000000000000000000000000000000000000000000000005286bd43a3730000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcc64593075d713bfc9e927d7161ba7b53a33898000000000000000000000000fcc64593075d713bfc9e927d7161ba7b53a33898000000000000000000000000000000000000000000000000003bc46397c3ddf600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b882b087bd80a0258f19d907849c8d64cac3dba1000000000000000000000000b882b087bd80a0258f19d907849c8d64cac3dba100000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dec44a6acf386368f6468461b810a5b2d60982f0000000000000000000000002dec44a6acf386368f6468461b810a5b2d60982f00000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093433264cccb31c80a62b0eee78e37ebbb0377e300000000000000000000000093433264cccb31c80a62b0eee78e37ebbb0377e30000000000000000000000000000000000000000000000000d77cf52a1946b3c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb7a4c047a5b152b1319b2d7f3a590d5388e78a3000000000000000000000000cb7a4c047a5b152b1319b2d7f3a590d5388e78a3000000000000000000000000000000000000000000000000003c105824cfe10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12145,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf8c7f3aef546992c9f8f42900b4ca245ceb5c88000000000000000000000000cf8c7f3aef546992c9f8f42900b4ca245ceb5c880000000000000000000000000000000000000000000000000139b4b5118bc91100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7083893735f9aa7e9ccc4b41f8a3a0b188e9fda000000000000000000000000c7083893735f9aa7e9ccc4b41f8a3a0b188e9fda00000000000000000000000000000000000000000000000006bb10ee2c10800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b72f0a2e5269951e3bcbeb50e8e35f182043f790000000000000000000000002b72f0a2e5269951e3bcbeb50e8e35f182043f79000000000000000000000000000000000000000000000000003dc64337b204f600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12152,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000492261c62c8f0e1783b6f3e60d5c03e2e532f167000000000000000000000000492261c62c8f0e1783b6f3e60d5c03e2e532f1670000000000000000000000000000000000000000000000000079638a034e2c2500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5c6c1a3acd6b03fb837f15ee8cc60796b2fef4673bd31f7ff5266f33c8b76df9,2022-03-14 06:54:17.000 UTC,0,true +12156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd533307557ac9e1b9ee7fce0256ae909d6aedc8000000000000000000000000dd533307557ac9e1b9ee7fce0256ae909d6aedc800000000000000000000000000000000000000000000000000497384c12aa18000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12157,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd533307557ac9e1b9ee7fce0256ae909d6aedc8000000000000000000000000dd533307557ac9e1b9ee7fce0256ae909d6aedc800000000000000000000000000000000000000000000000000309dbd04fa3e0100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e4038eb6f1e7316a45ed569e94c8cd1706a5ec50000000000000000000000005e4038eb6f1e7316a45ed569e94c8cd1706a5ec50000000000000000000000000000000000000000000000000048c36b4374b7ce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f339fa28e328d783b991bcc6785d1eba0b4fe2d0000000000000000000000003f339fa28e328d783b991bcc6785d1eba0b4fe2d00000000000000000000000000000000000000000000000000411ae864d78fe900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12164,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5a9ca279a99365d83c6c744ca5d3e0b87ec060d000000000000000000000000f5a9ca279a99365d83c6c744ca5d3e0b87ec060d000000000000000000000000000000000000000000000000003f532fbd67641400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12167,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7a3668f8bc40af03579fc00bedc31e4cc662624000000000000000000000000f7a3668f8bc40af03579fc00bedc31e4cc662624000000000000000000000000000000000000000000000000089d0381984f555600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000927fd99fc1cc1d0da4c421149e708a6db193b239000000000000000000000000927fd99fc1cc1d0da4c421149e708a6db193b239000000000000000000000000000000000000000000000000005e920e7547557c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12170,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000099e201231e44ba38af6fea7f54eaa19c90bef80600000000000000000000000099e201231e44ba38af6fea7f54eaa19c90bef80600000000000000000000000000000000000000000000000c18751e446e5e912f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa32478d043bb4df36c41b33eced66255503aee33b2d15c0aa3bddc50bea0b465,2021-11-28 12:52:31.000 UTC,0,true +12183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000edbcf860bee646199b84a351f4a55d7e929a7a36000000000000000000000000edbcf860bee646199b84a351f4a55d7e929a7a36000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12186,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081304f07bb9c9c66cc64100a5d827810e6a6530300000000000000000000000081304f07bb9c9c66cc64100a5d827810e6a653030000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12189,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a9e11c0fe965f551fd21d448a9861d10b9b6c5e0000000000000000000000004a9e11c0fe965f551fd21d448a9861d10b9b6c5e0000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12191,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b2274d48ae08c580e08d316530b64a32fde0fbb0000000000000000000000000b2274d48ae08c580e08d316530b64a32fde0fbb00000000000000000000000000000000000000000000000000002d7272244020000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12193,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d70e9499b2d791b5eb15759b2c2e6f3947ab4980000000000000000000000004d70e9499b2d791b5eb15759b2c2e6f3947ab4980000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a7f769421e4486eb2f8bc3067f8c79a354552930000000000000000000000006a7f769421e4486eb2f8bc3067f8c79a354552930000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12196,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2db6c1cdd02b8bf48c9d30fea6c8ac13eff5a0a000000000000000000000000c2db6c1cdd02b8bf48c9d30fea6c8ac13eff5a0a0000000000000000000000000000000000000000000000000044da35120a0dcd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12197,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d93b019f298b369adb1ce53b72cdf239a9b0b838000000000000000000000000d93b019f298b369adb1ce53b72cdf239a9b0b8380000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a87a104b9601874d981436738546337d94e4be02000000000000000000000000a87a104b9601874d981436738546337d94e4be020000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12203,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000618208c77c81898331ec6880ef5f1ffa758d3915000000000000000000000000618208c77c81898331ec6880ef5f1ffa758d39150000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003170b8bfbe8b8938c9c42006ddd5faec04232bbf0000000000000000000000003170b8bfbe8b8938c9c42006ddd5faec04232bbf0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0196dedba94cb41a9480eb2cc38cbe044ec0496000000000000000000000000b0196dedba94cb41a9480eb2cc38cbe044ec04960000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12214,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf5310fae4d7a0c6df0452bcda09aefa2748ad59000000000000000000000000bf5310fae4d7a0c6df0452bcda09aefa2748ad59000000000000000000000000000000000000000000000000000c6f3b40b6c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e604e03d0b90e8aa058bb8bb6313e749606832c0000000000000000000000002e604e03d0b90e8aa058bb8bb6313e749606832c000000000000000000000000000000000000000000000000002441157bb525dd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000467a755ba59267678e14e414ed214c3cea836498000000000000000000000000467a755ba59267678e14e414ed214c3cea83649800000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12217,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb4413d6ac1b0225523eeb00f1dd4c1d733621dd000000000000000000000000eb4413d6ac1b0225523eeb00f1dd4c1d733621dd00000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000435be2e484393babeaa4a919f8e30bb5dbd808ce000000000000000000000000435be2e484393babeaa4a919f8e30bb5dbd808ce0000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f60000000000000000000000006bc4c6cfd03decb17657e71d5b6eca3cbaf8a4360000000000000000000000006bc4c6cfd03decb17657e71d5b6eca3cbaf8a43600000000000000000000000000000000000000000000000025c838dcff60c4aa00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000322cc309626a170df4385a7a5624dee44d4e5e1f000000000000000000000000322cc309626a170df4385a7a5624dee44d4e5e1f0000000000000000000000000000000000000000000000000067cccce7969e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d7ad2d86beae9f82f35b1f3fa9a246a5e6ff7fc0000000000000000000000009d7ad2d86beae9f82f35b1f3fa9a246a5e6ff7fc000000000000000000000000000000000000000000000000007d7b9c5b6a05d500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12226,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084861b33ba6c7ae0dc01e0e3192e74d133d9a13a00000000000000000000000084861b33ba6c7ae0dc01e0e3192e74d133d9a13a000000000000000000000000000000000000000000000000001bbba96a3612e100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007269f818a33779b8f1f517e0bc1466110ce915050000000000000000000000007269f818a33779b8f1f517e0bc1466110ce91505000000000000000000000000000000000000000000000000001c28cd70b1b70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9cd8427ba55bef4ee8cd22b5f82f88d04f17619000000000000000000000000e9cd8427ba55bef4ee8cd22b5f82f88d04f1761900000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3e11d89b07e738f31de12e8d8cfa0eac7867a37000000000000000000000000f3e11d89b07e738f31de12e8d8cfa0eac7867a37000000000000000000000000000000000000000000000000006416a75da11bf500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x15ebfe79959c1800128378e37a74757f6cc82fefdd9694b4afd79289aaf24606,2021-12-07 02:37:27.000 UTC,0,true +12240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000373622442c34e0c0d9cc1c3cb79a773eb3635ec0000000000000000000000000373622442c34e0c0d9cc1c3cb79a773eb3635ec00000000000000000000000000000000000000000000000000b9630f607e4b4200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12243,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021aa38a4f7943f5088347765b210c7148edbadc000000000000000000000000021aa38a4f7943f5088347765b210c7148edbadc000000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3d4a6b3bfe187d7e328514f46db9928c569da21000000000000000000000000c3d4a6b3bfe187d7e328514f46db9928c569da210000000000000000000000000000000000000000000000001158d61588b2628300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c691ac73cd49e2c0b0e0ea4cae51bae1387f466a000000000000000000000000c691ac73cd49e2c0b0e0ea4cae51bae1387f466a00000000000000000000000000000000000000000000000001e3209cdaef050000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x297264e529b6b2f3d8584cfbf609f6d12046abc7f0a73547873d369a42ad3733,2022-05-23 08:57:25.000 UTC,0,true +12253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054f37eb4e1b42409db572bd4661b003eebaf71d100000000000000000000000054f37eb4e1b42409db572bd4661b003eebaf71d10000000000000000000000000000000000000000000000000009e48b3595f8fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12254,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d06c65961476fc3d5d812e14b9a8dbf995c06f60000000000000000000000005d06c65961476fc3d5d812e14b9a8dbf995c06f60000000000000000000000000000000000000000000000000131867863646f9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc5bc0ccc7ffd05aece6231373844f3d86ccb114000000000000000000000000dc5bc0ccc7ffd05aece6231373844f3d86ccb11400000000000000000000000000000000000000000000000000d52de26bb1250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12258,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033fe1df4c09e4ddd4e880f9cedd0ae638b048ea900000000000000000000000033fe1df4c09e4ddd4e880f9cedd0ae638b048ea9000000000000000000000000000000000000000000000000048b3f9040c9a94600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x84c8c9a97d045abf61a65fdca44f7f8d4f899c0014a1343b694eb53e25b73781,2022-02-23 08:23:23.000 UTC,0,true +12259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef0905745ce28ebe1ded7004146132fbfba548ba000000000000000000000000ef0905745ce28ebe1ded7004146132fbfba548ba000000000000000000000000000000000000000000000000007d5713ea7d4eda00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12260,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095b18b7721ee14714ab9d50f21fd8027d9b9643200000000000000000000000095b18b7721ee14714ab9d50f21fd8027d9b964320000000000000000000000000000000000000000000000000167e9a71ed79d3900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcdf49f180f2cc9270a6925a8c753485348103799362db8589f24ae1434587aef,2022-02-23 08:20:16.000 UTC,0,true +12261,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066da1e3a39516a5e07c7f3e36e683a81393ecd3a00000000000000000000000066da1e3a39516a5e07c7f3e36e683a81393ecd3a0000000000000000000000000000000000000000000000000529ee0633db488000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x31fb299649fb109641f257a5feb83851ce6b6892d261316a17654802430023a1,2022-02-23 08:25:57.000 UTC,0,true +12262,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fae87a37ade1a92d2ec6c5d4a7c29d635a505a91000000000000000000000000fae87a37ade1a92d2ec6c5d4a7c29d635a505a910000000000000000000000000000000000000000000000000092fa0befdd856b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022a4954445046a65fd7054e598f2feb6ed54a61800000000000000000000000022a4954445046a65fd7054e598f2feb6ed54a61800000000000000000000000000000000000000000000000003f6e352c532444d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8973c49612dda1aacc7bc37427dcb5be17183740cbcdbd87fddf3d79cd586fa8,2021-12-19 06:32:36.000 UTC,0,true +12266,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000105c70544b7f806f5b424ccffff34dcabc813a10000000000000000000000000105c70544b7f806f5b424ccffff34dcabc813a1000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12273,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f6000000000000000000000000d5ac6365ae4ce0008789888fd2e03a5db84d2ccb000000000000000000000000d5ac6365ae4ce0008789888fd2e03a5db84d2ccb000000000000000000000000000000000000000000000000891de09c74496f3d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5ac6365ae4ce0008789888fd2e03a5db84d2ccb000000000000000000000000d5ac6365ae4ce0008789888fd2e03a5db84d2ccb000000000000000000000000000000000000000000000000001d75e00d11bf4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c2ea83cb2b21cf11ce1fe19a46c2eaf1668d0880000000000000000000000005c2ea83cb2b21cf11ce1fe19a46c2eaf1668d0880000000000000000000000000000000000000000000000000084a01b0133db3b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12277,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000748010fbe056562ef466901f1d38ce481f11b539000000000000000000000000000000000000000000000001a71b0bfa7d6e59f8,,,1,true +12279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6b78b3717dfa5118ae60263a0b547a8ec43896b000000000000000000000000d6b78b3717dfa5118ae60263a0b547a8ec43896b00000000000000000000000000000000000000000000000000cc74c44c2f77b900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063060f713b377af8d7d50669ec0fdce1d31e3f2800000000000000000000000063060f713b377af8d7d50669ec0fdce1d31e3f2800000000000000000000000000000000000000000000000000dd79dbd3511aa200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac1c9fd0405296598b0b6ca8e290784197198fa7000000000000000000000000ac1c9fd0405296598b0b6ca8e290784197198fa70000000000000000000000000000000000000000000000000032ea2718d4b3f300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a12213d1bba68432be1fb5e9ac8d8169c0e66201000000000000000000000000a12213d1bba68432be1fb5e9ac8d8169c0e6620100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12284,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001906bd0244b749381e2974192fc581fe0da4d3630000000000000000000000001906bd0244b749381e2974192fc581fe0da4d363000000000000000000000000000000000000000000000000008d4f56c175acb500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12288,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002438375ee587b54e0dbcc0704dbe90670265b4cd0000000000000000000000002438375ee587b54e0dbcc0704dbe90670265b4cd0000000000000000000000000000000000000000000000000853a0d2313c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12289,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c05846781c8c0745464d8dc5673ea821b23d4aa3000000000000000000000000c05846781c8c0745464d8dc5673ea821b23d4aa300000000000000000000000000000000000000000000000000c8928211b4fc1300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d606452ee5d7ae5f31ee14a7273265db77a1b7f4000000000000000000000000d606452ee5d7ae5f31ee14a7273265db77a1b7f400000000000000000000000000000000000000000000000000c70ff4a6f52d8800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12291,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081a35224db38747caccbd8e980c875de9e3fc13900000000000000000000000081a35224db38747caccbd8e980c875de9e3fc139000000000000000000000000000000000000000000000000015992133a82fa6e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12292,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6b78b3717dfa5118ae60263a0b547a8ec43896b000000000000000000000000d6b78b3717dfa5118ae60263a0b547a8ec43896b0000000000000000000000000000000000000000000000000147a507e05a2a4e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12294,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000000ea455f073321b662635245e32ef1a488fb093000000000000000000000000000ea455f073321b662635245e32ef1a488fb0930000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12296,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007605fa24b13e9f61a2fc7b636a165b863116f9a20000000000000000000000007605fa24b13e9f61a2fc7b636a165b863116f9a200000000000000000000000000000000000000000000000000660a7865a49fe800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bdbfdf3e82fc9d2be1352e252ab1ce2287fc2122000000000000000000000000bdbfdf3e82fc9d2be1352e252ab1ce2287fc2122000000000000000000000000000000000000000000000000007957fdcb4812a100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7736f636106ec904dc0c6e4157cf33c136114e201c82c71a5dcee5aeee0c528e,2022-02-17 10:41:49.000 UTC,0,true +12300,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b68c0d55d467f901bb1c62950b441f7bfe8ec3ea000000000000000000000000b68c0d55d467f901bb1c62950b441f7bfe8ec3ea0000000000000000000000000000000000000000000000019573086fe285bae500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12302,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000398259c183a1ef12d8f3a900b734b7d2e064cb25000000000000000000000000398259c183a1ef12d8f3a900b734b7d2e064cb2500000000000000000000000000000000000000000000000000883c797cfdb3f900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e56bbbb98982c8476bdabbcc5f27f3d354dff3a8000000000000000000000000e56bbbb98982c8476bdabbcc5f27f3d354dff3a800000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12306,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e56bbbb98982c8476bdabbcc5f27f3d354dff3a8000000000000000000000000e56bbbb98982c8476bdabbcc5f27f3d354dff3a800000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12307,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f60000000000000000000000007599bd674137e9109a4bab48e3d68bf99c39b3190000000000000000000000007599bd674137e9109a4bab48e3d68bf99c39b31900000000000000000000000000000000000000000000000007e0428d85c29dc700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12312,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006399ef7d7be677e0f7afee94a343935ab933cf800000000000000000000000006399ef7d7be677e0f7afee94a343935ab933cf80000000000000000000000000000000000000000000000000016137f81b854f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12316,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f6000000000000000000000000b50e8634486e329a64dfdc2a55ee5b1a05c24751000000000000000000000000b50e8634486e329a64dfdc2a55ee5b1a05c2475100000000000000000000000000000000000000000000000014d1120d7b16000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc5bfdaf66371bcbb2edffac04eee810685e79b9000000000000000000000000dc5bfdaf66371bcbb2edffac04eee810685e79b900000000000000000000000000000000000000000000000000ce6123896dfdf100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f600000000000000000000000032c601a2ba37db9c6a9716f951c893a0ec9002d800000000000000000000000032c601a2ba37db9c6a9716f951c893a0ec9002d8000000000000000000000000000000000000000000000000333027d55fc2178200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa02e2d6eb6d3706ddcd080453aebcbb1e10bcdd3711b9c20a4091fa53b6e53a9,2022-05-29 00:28:04.000 UTC,0,true +12320,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b8b511851a8e11d8e729005dafefdf05e3d3b5f0000000000000000000000004b8b511851a8e11d8e729005dafefdf05e3d3b5f00000000000000000000000000000000000000000000000001a31a834b3025d100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12323,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bfd011afe4b326817db13df58f0dea7188154aac0000000000000000000000000000000000000000000000300d5bcb349b77e5dd,0x09368beafa461833e1b099bd0bb3c6efcd4c539c249e047793d7143390732556,2021-12-13 02:25:47.000 UTC,0,true +12326,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9fcd609bfd554d051de2e1adc413c6443daf7da000000000000000000000000e9fcd609bfd554d051de2e1adc413c6443daf7da000000000000000000000000000000000000000000000000012bd93c902296a900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12327,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e049c3c7736ce67883b19f3d2b50c9d71bc83e10000000000000000000000008e049c3c7736ce67883b19f3d2b50c9d71bc83e10000000000000000000000000000000000000000000000000154eb7e9a230c9200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001dd3479d59950e6f756c2d3fd0ab0647713e09bb0000000000000000000000001dd3479d59950e6f756c2d3fd0ab0647713e09bb00000000000000000000000000000000000000000000000000c95bd3a56e8f3600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12330,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043d13bbdcbdf43f376bc696f7742a9aebb6e0ce700000000000000000000000043d13bbdcbdf43f376bc696f7742a9aebb6e0ce700000000000000000000000000000000000000000000000000a51019dee4457800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12335,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031e7f474d5d02ff11a270218107b8e3ae783205600000000000000000000000031e7f474d5d02ff11a270218107b8e3ae783205600000000000000000000000000000000000000000000000000724a3324654d2100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12336,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000425f76e3cb1ba3b65a9ddba16b31e5454d08a1a1000000000000000000000000425f76e3cb1ba3b65a9ddba16b31e5454d08a1a1000000000000000000000000000000000000000000000000001e6db5d323ca0500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024b25321490839428ea48a456d5d76586eca025d00000000000000000000000024b25321490839428ea48a456d5d76586eca025d00000000000000000000000000000000000000000000000000769285f0c3211f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b805d4dd668758536f210bed08476b58c4142a5e000000000000000000000000b805d4dd668758536f210bed08476b58c4142a5e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12341,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3020016900be232d277743d10893064be7cc7f9000000000000000000000000d3020016900be232d277743d10893064be7cc7f90000000000000000000000000000000000000000000000000354a6ba7a18000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12347,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e68d7feca592cca0ab9a5d0be4b3b22c996430dd000000000000000000000000e68d7feca592cca0ab9a5d0be4b3b22c996430dd0000000000000000000000000000000000000000000000000070b002272d6e4e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000801510553f5b523f75f40d77ce9e476e7f48e192000000000000000000000000801510553f5b523f75f40d77ce9e476e7f48e19200000000000000000000000000000000000000000000000000a6a26335c27f9500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c858345d95f2d8eef33cf31e9f119eb85bc3f660000000000000000000000009c858345d95f2d8eef33cf31e9f119eb85bc3f66000000000000000000000000000000000000000000000000015d7e23c3dc9eb500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9dad802f0febae1fb84c1910e8bb8215ce68ea4000000000000000000000000b9dad802f0febae1fb84c1910e8bb8215ce68ea400000000000000000000000000000000000000000000000000a830cf1a4e138600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fcca7466fb4a3a6c15d5f901ad93aed2c3ada340000000000000000000000001fcca7466fb4a3a6c15d5f901ad93aed2c3ada3400000000000000000000000000000000000000000000000002d36a78013c6da600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12354,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000064e9ea8eeb3ea9a0e68b397db271fb7ac525e33000000000000000000000000064e9ea8eeb3ea9a0e68b397db271fb7ac525e33000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be003db78e91d32fba49a5a93f8ec6f3398d8df6000000000000000000000000be003db78e91d32fba49a5a93f8ec6f3398d8df600000000000000000000000000000000000000000000000000a74186094273b600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12356,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e72ce1ece575f66792f5d35aeb1111a615aebda0000000000000000000000008e72ce1ece575f66792f5d35aeb1111a615aebda0000000000000000000000000000000000000000000000000073528b83edc91d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12357,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5d8f53a36c4bbef078e352ef38cc06132320d3c000000000000000000000000f5d8f53a36c4bbef078e352ef38cc06132320d3c0000000000000000000000000000000000000000000000000ddafe7a671a57ff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc1492a75f1fe47964580f647401b443552eadbde916e7159fa909826cd061e53,2021-11-28 05:21:23.000 UTC,0,true +12358,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4df4d5c7b7cea92d403903c67f5005df3081681000000000000000000000000f4df4d5c7b7cea92d403903c67f5005df308168100000000000000000000000000000000000000000000000000a3b0e21b6a441f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f341472663d4d328c58477d04c27aee530b03e10000000000000000000000009f341472663d4d328c58477d04c27aee530b03e100000000000000000000000000000000000000000000000000a2ec7ed9121eed00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12362,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8584d1552c0e68ef8fc580169456a8806a9ee5f000000000000000000000000e8584d1552c0e68ef8fc580169456a8806a9ee5f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12363,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034222096a91c73ba06bd1dd3eeea16e250dde36a00000000000000000000000034222096a91c73ba06bd1dd3eeea16e250dde36a00000000000000000000000000000000000000000000000000a4ff45ee21769000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000700efd158f49f0958d85cdb0b28e1f24fdfb7db0000000000000000000000000700efd158f49f0958d85cdb0b28e1f24fdfb7db0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030d3f805c896d8b6290d7978d7121ff24ce4ab2200000000000000000000000030d3f805c896d8b6290d7978d7121ff24ce4ab2200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12366,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095dd317732fbc595206928c4974b653da65f59e300000000000000000000000095dd317732fbc595206928c4974b653da65f59e300000000000000000000000000000000000000000000000000cf4d293f509bb400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b778b4616b024c4de5686dc064a9c7de3435cc70000000000000000000000006b778b4616b024c4de5686dc064a9c7de3435cc700000000000000000000000000000000000000000000000000a64c2c9badefdc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac87fbbf35e5504bee8daec50bef75d43ce20d92000000000000000000000000ac87fbbf35e5504bee8daec50bef75d43ce20d920000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0a6fb8ec52aea5b3548eec6463151dca2425a54c07e6f720eb73363b4bfcf93e,2022-03-11 18:12:12.000 UTC,0,true +12369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036b0440e2106edc46b632722c531b6f6d5d4fc6d00000000000000000000000036b0440e2106edc46b632722c531b6f6d5d4fc6d00000000000000000000000000000000000000000000000000a50ce658f7244d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048c84fb52dd6fd66cf4c150224b1d41b5f0729c400000000000000000000000048c84fb52dd6fd66cf4c150224b1d41b5f0729c4000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049fe6d0096ec9a51a59231c2d46f09a339d1629600000000000000000000000049fe6d0096ec9a51a59231c2d46f09a339d162960000000000000000000000000000000000000000000000000088e622139322e700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053be6809662db6de0db5c8d9081b9a6c29b3e0a700000000000000000000000053be6809662db6de0db5c8d9081b9a6c29b3e0a700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa07bab7248dc4e752ab42950ef8a66686c31db1000000000000000000000000aa07bab7248dc4e752ab42950ef8a66686c31db100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12378,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da4bd497c38a6acb9c98d133614faa5d9c8e9598000000000000000000000000da4bd497c38a6acb9c98d133614faa5d9c8e95980000000000000000000000000000000000000000000000000000470fe6c8c98000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12379,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da4bd497c38a6acb9c98d133614faa5d9c8e9598000000000000000000000000da4bd497c38a6acb9c98d133614faa5d9c8e95980000000000000000000000000000000000000000000000000000470fe6c8c98000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12381,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da4bd497c38a6acb9c98d133614faa5d9c8e9598000000000000000000000000da4bd497c38a6acb9c98d133614faa5d9c8e95980000000000000000000000000000000000000000000000000000470fe6c8c98000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12382,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da4bd497c38a6acb9c98d133614faa5d9c8e9598000000000000000000000000da4bd497c38a6acb9c98d133614faa5d9c8e95980000000000000000000000000000000000000000000000000000af7c0fce8c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4272bca6da323391ae38bbcdc9c864345541597000000000000000000000000e4272bca6da323391ae38bbcdc9c8643455415970000000000000000000000000000000000000000000000000040fb8958066f1800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bc467b322875a3abafd99e21edd410e9eacd3390000000000000000000000001bc467b322875a3abafd99e21edd410e9eacd3390000000000000000000000000000000000000000000000000071afd498d0000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12390,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001cb2abfca6f0799526913a6f934b4d43c3d4b7fe0000000000000000000000001cb2abfca6f0799526913a6f934b4d43c3d4b7fe00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12391,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000237d3ee0674782599c6df583f8b7bc62b9850034000000000000000000000000237d3ee0674782599c6df583f8b7bc62b985003400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ecf59234351a4557e62178b07ef83f98d6e86520000000000000000000000009ecf59234351a4557e62178b07ef83f98d6e86520000000000000000000000000000000000000000000000001aec16906a10b11000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000571fc4de243e743ccabf46bfd10d878406f82042000000000000000000000000571fc4de243e743ccabf46bfd10d878406f8204200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8a8cc3939a8c3c148c7d328d8455c3f73703b08000000000000000000000000e8a8cc3939a8c3c148c7d328d8455c3f73703b08000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000597d2d5bba8bb938474b0234450edebabe4b3c1b000000000000000000000000597d2d5bba8bb938474b0234450edebabe4b3c1b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000466f0ac408d52e7eb082aca07f2835a0d5b8d89b000000000000000000000000466f0ac408d52e7eb082aca07f2835a0d5b8d89b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039cc43b3068a208ae87042f927fb53b85586c65400000000000000000000000039cc43b3068a208ae87042f927fb53b85586c65400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc3de6ab97634192cbb2d9d82d2216f33292dc2e000000000000000000000000cc3de6ab97634192cbb2d9d82d2216f33292dc2e0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4d18fc7d98f204e393a3045ee9073e87c137e8b000000000000000000000000c4d18fc7d98f204e393a3045ee9073e87c137e8b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb29cbf4b3d04e003b3c82fbbf45f0c97cab3451000000000000000000000000eb29cbf4b3d04e003b3c82fbbf45f0c97cab345100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000123317f544d620465d938789656edfcf9699330f000000000000000000000000123317f544d620465d938789656edfcf9699330f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001171697a3f96a3790e6c265fd1d9f0c601f08f790000000000000000000000001171697a3f96a3790e6c265fd1d9f0c601f08f7900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f93149d54461a783c1517b23974113b89e382410000000000000000000000000f93149d54461a783c1517b23974113b89e3824100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12409,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d4d36ced9a3096fb1916fc83675bc3785afc9710000000000000000000000005d4d36ced9a3096fb1916fc83675bc3785afc97100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056584ee28735e10b381275b913b934ed656b0e2800000000000000000000000056584ee28735e10b381275b913b934ed656b0e2800000000000000000000000000000000000000000000000001886e2d09d3620900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002f5f4ac52b217828c8fa780a5fe675674bb761700000000000000000000000002f5f4ac52b217828c8fa780a5fe675674bb76170000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002f5f4ac52b217828c8fa780a5fe675674bb761700000000000000000000000002f5f4ac52b217828c8fa780a5fe675674bb76170000000000000000000000000000000000000000000000000000008bb2c9700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a2ea71352fd4a3fdcbf33dc847a7aaf85dd0b040000000000000000000000008a2ea71352fd4a3fdcbf33dc847a7aaf85dd0b0400000000000000000000000000000000000000000000000000060a24181e400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf8445a17f25d149e63ba8662eb602e5103a236b000000000000000000000000cf8445a17f25d149e63ba8662eb602e5103a236b0000000000000000000000000000000000000000000000000dcf39df802b162900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12423,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048a0a3ae50991044e5d797e73394f0dfff92180b00000000000000000000000048a0a3ae50991044e5d797e73394f0dfff92180b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000521d8d1a5c001895a8f735137b4e0fc4aebc91ae000000000000000000000000521d8d1a5c001895a8f735137b4e0fc4aebc91ae00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12425,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0d7561c786b5f5fb702f59f026a5011e25b95f1000000000000000000000000b0d7561c786b5f5fb702f59f026a5011e25b95f100000000000000000000000000000000000000000000000000157f7e818c82c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001eaf2bfccc4f09ea373e0f7cd79b7d6803e1aace0000000000000000000000001eaf2bfccc4f09ea373e0f7cd79b7d6803e1aace00000000000000000000000000000000000000000000000000645f6d065403e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e281add1e87f5aa0fd9c39d8bcfd7c1a6da61fd0000000000000000000000004e281add1e87f5aa0fd9c39d8bcfd7c1a6da61fd0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af435f714502846ca912b6225964ef7a62714564000000000000000000000000af435f714502846ca912b6225964ef7a6271456400000000000000000000000000000000000000000000000000017d2684ae983800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099436be04157c939f548abd8e3cae9ce01c7abca00000000000000000000000099436be04157c939f548abd8e3cae9ce01c7abca000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12435,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d79add81d0b801eaa6e7fc9e1aca731cb28381f7000000000000000000000000d79add81d0b801eaa6e7fc9e1aca731cb28381f7000000000000000000000000000000000000000000000000003b460fb1d669d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000404551724744d0dfc51cda2731f0fd8c62923173000000000000000000000000404551724744d0dfc51cda2731f0fd8c62923173000000000000000000000000000000000000000000000000005af2bab4353fd500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017aab8b3ffe10f1ab840d90dc2a788a3fdef505c00000000000000000000000017aab8b3ffe10f1ab840d90dc2a788a3fdef505c00000000000000000000000000000000000000000000000006ccd46763f1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3f01f6e61c0cedba21b6e22ea5a005e7b5ece03000000000000000000000000c3f01f6e61c0cedba21b6e22ea5a005e7b5ece03000000000000000000000000000000000000000000000000015bb4896242211200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2b6fe0d48498b892992c2e8b018160f21a6e104000000000000000000000000d2b6fe0d48498b892992c2e8b018160f21a6e10400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000078259703c92b0ba6491f1162f4a4b17a2ada0ae000000000000000000000000078259703c92b0ba6491f1162f4a4b17a2ada0ae000000000000000000000000000000000000000000000000015d9f93ef4d8f9a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000443dfb2a4b76693ba596742d6bd2ae52a39ad0c8000000000000000000000000443dfb2a4b76693ba596742d6bd2ae52a39ad0c80000000000000000000000000000000000000000000000000077ed8698a8dcc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12450,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049f63b254ea9043e57678c13e06aef257fab45c100000000000000000000000049f63b254ea9043e57678c13e06aef257fab45c1000000000000000000000000000000000000000000000000015407c84249e36100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x26cfbf229aff2ae8f27a32b7de6e1de00c2828e5e8023076cbbddfca9e238e28,2021-12-20 17:01:31.000 UTC,0,true +12453,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a71504de8712ab1405bb6d007365f56f3886d0f1000000000000000000000000a71504de8712ab1405bb6d007365f56f3886d0f1000000000000000000000000000000000000000000000000004053c8ddc9654500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe3e90cc6793235b8145495d50a8b95bab5895375810a34c53e835e384569eba8,2022-06-28 11:58:41.000 UTC,0,true +12457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000524fddf4a772b34846553c6765fad662f207a090000000000000000000000000524fddf4a772b34846553c6765fad662f207a090000000000000000000000000000000000000000000000000007240e19ff4428700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12458,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027490c1fccfd250cca46d17cf3f35960e1d7863700000000000000000000000027490c1fccfd250cca46d17cf3f35960e1d7863700000000000000000000000000000000000000000000000001157fa250dde2c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000054291d14e7b1c33abe9d59765b065a2f782b202b00000000000000000000000054291d14e7b1c33abe9d59765b065a2f782b202b0000000000000000000000000000000000000000000000000000000022be61e200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x7c6d7058062f078a9675ef7d77a25dd22ac2516576a4ab2a4d8ec16bf127b434,2022-05-21 06:52:31.000 UTC,0,true +12462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ef531802e40883e1867215b66f304412188bcc60000000000000000000000000ef531802e40883e1867215b66f304412188bcc600000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12468,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cd11fae257afe4638141c27cabc2830896f97ed0000000000000000000000005cd11fae257afe4638141c27cabc2830896f97ed000000000000000000000000000000000000000000000000006559cc98e1873c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c5d1cd7ec090a6186164fee2e648001dc7ed3d70000000000000000000000000c5d1cd7ec090a6186164fee2e648001dc7ed3d700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e6ce8f922512551527d6670d6d41861b5128c220000000000000000000000003e6ce8f922512551527d6670d6d41861b5128c220000000000000000000000000000000000000000000000000008e1bc9bf0400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000319fdba64234fcbdc4c884cc7d9db1cc00c429b7000000000000000000000000319fdba64234fcbdc4c884cc7d9db1cc00c429b700000000000000000000000000000000000000000000000001c39f40a0c4092c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000220a6cb04d48ca2c33735e94df78c17f8b0f7c9f000000000000000000000000220a6cb04d48ca2c33735e94df78c17f8b0f7c9f0000000000000000000000000000000000000000000000000008e1bc9bf0400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009fec7a5b0ba8a8dc5e32ab479bc15e13b6577a510000000000000000000000009fec7a5b0ba8a8dc5e32ab479bc15e13b6577a51000000000000000000000000000000000000000000000000002ad25e289cd60900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c60048fd2bccd82da8a1c0d06b3cf1bfd7d740a2000000000000000000000000c60048fd2bccd82da8a1c0d06b3cf1bfd7d740a2000000000000000000000000000000000000000000000000001eb0062ff1fc8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df74afb1a98682d0163000beaa91a40b2fb04b5e000000000000000000000000df74afb1a98682d0163000beaa91a40b2fb04b5e000000000000000000000000000000000000000000000000012f99c1aadd635900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12486,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c93224c75ded80416f0c90d26acf22328e62dede000000000000000000000000c93224c75ded80416f0c90d26acf22328e62dede000000000000000000000000000000000000000000000000002030bafc871f8f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12488,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b5b14f21fa818596414614ddc954e17ded368b90000000000000000000000006b5b14f21fa818596414614ddc954e17ded368b9000000000000000000000000000000000000000000000000000119f17fe1600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e030d0727b116a30b4858cb395a4ee7f0557ef10000000000000000000000000e030d0727b116a30b4858cb395a4ee7f0557ef100000000000000000000000000000000000000000000000000198047866b3072400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12493,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a930c154dfb62b1dddf26d8c78bc93d5e6f17500000000000000000000000009a930c154dfb62b1dddf26d8c78bc93d5e6f175000000000000000000000000000000000000000000000000003dba786ef8f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000069bbeaf77d38a812d448ad92216ecce1228d108100000000000000000000000069bbeaf77d38a812d448ad92216ecce1228d10810000000000000000000000000000000000000000000000000000000041587ec100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x7fbc7e39791ec715851c97a61e8e7d089b6ef61a918d1d75c5f97ebcbabeff6b,2022-04-29 08:54:00.000 UTC,0,true +12495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000fc95af4cfb33dddc2d8144fd36dcdcac2a5e01c0000000000000000000000000fc95af4cfb33dddc2d8144fd36dcdcac2a5e01c000000000000000000000000000000000000000000000000000000004232d52400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xcd6a470db49ca4efca7abb11e3de703b38001f19b7488454675289c2e9d4d7fa,2022-04-30 04:55:41.000 UTC,0,true +12496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000c1daa72eb73b036def6e1287967695e40d197a58000000000000000000000000c1daa72eb73b036def6e1287967695e40d197a580000000000000000000000000000000000000000000000000000000040e7411300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x7971f4f1113227a0b305b6d7617747466a7d36b20cece379276a8b3ea2be17e8,2022-04-30 04:55:41.000 UTC,0,true +12497,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000c1a3b5c321d73065449f25d40fa61a2b4036f9c1000000000000000000000000c1a3b5c321d73065449f25d40fa61a2b4036f9c1000000000000000000000000000000000000000000000000000000004020137900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x9501f92578cc94b7a4327fac5a26550c13d8cf6074cf25d2166bb03ff8c3cea6,2022-04-30 07:47:45.000 UTC,0,true +12498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000046f05604850563c5caf174bd14a7e346f0767e1e00000000000000000000000046f05604850563c5caf174bd14a7e346f0767e1e00000000000000000000000000000000000000000000000000000000484a7f4900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x06a7d5e5deaec3b3858eecc61adf72d62547e082356899afa4f33aef1ca5fc9c,2022-04-30 10:26:47.000 UTC,0,true +12501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a95bc97d8b30795cc5fbadb149fe2e9144912d9c000000000000000000000000a95bc97d8b30795cc5fbadb149fe2e9144912d9c0000000000000000000000000000000000000000000000000090cf211193f56000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12507,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006d6dec719e2acf3480e9478ad368e2eff1368cd00000000000000000000000006d6dec719e2acf3480e9478ad368e2eff1368cd00000000000000000000000000000000000000000000000000520c21fa67c24600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfb786bef16ed161829ba9e4c0eb94d026a338c5000000000000000000000000bfb786bef16ed161829ba9e4c0eb94d026a338c5000000000000000000000000000000000000000000000000005840452088dde600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12512,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e8e651e8c22609d0f86528c98829023165d78560000000000000000000000007e8e651e8c22609d0f86528c98829023165d7856000000000000000000000000000000000000000000000000001a4676d705c1f700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12514,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aec769ae46b7d4baa9215e1775a37c9984656c27000000000000000000000000aec769ae46b7d4baa9215e1775a37c9984656c2700000000000000000000000000000000000000000000000001aa535d3d0c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a79648a1a89219a135e55bc2a8803eeae4b03772000000000000000000000000a79648a1a89219a135e55bc2a8803eeae4b037720000000000000000000000000000000000000000000000000082d85aeff600c800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba715566ebb933102651465b02e8dba50b29dd43000000000000000000000000ba715566ebb933102651465b02e8dba50b29dd43000000000000000000000000000000000000000000000000015d76908fb6b38f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12521,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f6bad66ba1e4bf8d2c328c11653bb47b3f3449f0000000000000000000000004f6bad66ba1e4bf8d2c328c11653bb47b3f3449f000000000000000000000000000000000000000000000000058b1733c2d60e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12524,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb1eaf530ed313103b2450d188012b3f5b03e68b000000000000000000000000eb1eaf530ed313103b2450d188012b3f5b03e68b000000000000000000000000000000000000000000000000058b58ecaf7aaf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d51e9f882465b20a1ea3063e8ac98e720057b240000000000000000000000008d51e9f882465b20a1ea3063e8ac98e720057b24000000000000000000000000000000000000000000000000005e1928929a653d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x52bc0a60508f1a40c9136479c94b47ddbda8551f5982642ef48ca7f0946d2bf0,2021-12-20 08:21:56.000 UTC,0,true +12534,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af61206578fb4e4ad1842efde1dc74fb44b497d3000000000000000000000000af61206578fb4e4ad1842efde1dc74fb44b497d300000000000000000000000000000000000000000000000001564531e6436a0700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd65c5e9d1d4124a4730a9bad9ba5784f9b1d1ec000000000000000000000000dd65c5e9d1d4124a4730a9bad9ba5784f9b1d1ec00000000000000000000000000000000000000000000000000b3ea62ddd50e5800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f93a736784091e6292f7c6bad4d97836ce06a920000000000000000000000004f93a736784091e6292f7c6bad4d97836ce06a92000000000000000000000000000000000000000000000000037189a38ee5571200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12539,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061f4442da3ba5875916073697e96ee44019275fd00000000000000000000000061f4442da3ba5875916073697e96ee44019275fd0000000000000000000000000000000000000000000000000159a42c0d57749f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007db7bf3177b157fe9e8be57915e6bb653423a8e20000000000000000000000007db7bf3177b157fe9e8be57915e6bb653423a8e20000000000000000000000000000000000000000000000000159d9c30fb2bde000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12542,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033853501d457b975eded3398fa3f127f7c30073900000000000000000000000033853501d457b975eded3398fa3f127f7c300739000000000000000000000000000000000000000000000000015803af67d108fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ca2c5e91ef49549819d805a0c38f348d33078cc0000000000000000000000009ca2c5e91ef49549819d805a0c38f348d33078cc000000000000000000000000000000000000000000000000015ca8f3f2cf889b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12545,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2837d50d9c8f48262340ebb953a7525d13e2540000000000000000000000000e2837d50d9c8f48262340ebb953a7525d13e2540000000000000000000000000000000000000000000000000015bc11cf4ea1d1400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12546,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a04d7df825fa6a0c1daddc4285ae41762b92a230000000000000000000000003a04d7df825fa6a0c1daddc4285ae41762b92a2300000000000000000000000000000000000000000000000002bfab037dc4d19500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027d204b561bf99ddfb872c8e1ca023ae468820ca00000000000000000000000027d204b561bf99ddfb872c8e1ca023ae468820ca000000000000000000000000000000000000000000000000015c033cf2411b6d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12548,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c1c6ca180ac3446302bb396ade4ba392c26c7b20000000000000000000000005c1c6ca180ac3446302bb396ade4ba392c26c7b2000000000000000000000000000000000000000000000000015b88480c6f71b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6484a1e627f425aea442482d2ed3a71c3dbf474000000000000000000000000f6484a1e627f425aea442482d2ed3a71c3dbf474000000000000000000000000000000000000000000000000015c22d9bd95664800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12550,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1225cde04c3f5d4b233aa3901eca3bc3fb83f41000000000000000000000000a1225cde04c3f5d4b233aa3901eca3bc3fb83f41000000000000000000000000000000000000000000000000015d74c7223a273f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044be41c7efd167737b78fcaa93eb55bd8bf8165700000000000000000000000044be41c7efd167737b78fcaa93eb55bd8bf81657000000000000000000000000000000000000000000000000015ba4ff9cd40c2d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000061014b6fb0b97646762d2b1e523ed3af0b76f98000000000000000000000000061014b6fb0b97646762d2b1e523ed3af0b76f98000000000000000000000000000000000000000000000000015cee3c4c03f8b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030e17308b734d6f7177fef54018e552c6242b1ba00000000000000000000000030e17308b734d6f7177fef54018e552c6242b1ba00000000000000000000000000000000000000000000000000b504f03d5ad5bf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c13d5f2a4c59b897ebe4f3dc3e4a7893feb322c9000000000000000000000000c13d5f2a4c59b897ebe4f3dc3e4a7893feb322c900000000000000000000000000000000000000000000000000ee08251ff3800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000814390720bf3f2b45c31d3d1dc39cf609e6731e5000000000000000000000000814390720bf3f2b45c31d3d1dc39cf609e6731e500000000000000000000000000000000000000000000000000455c678263ca0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5851a0ad5205d3c49f70c6b8f73a1b1cae259b1000000000000000000000000a5851a0ad5205d3c49f70c6b8f73a1b1cae259b1000000000000000000000000000000000000000000000000012b48797546277200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1d9169f3dd1e7a2e89b1a5e62b7425f6fdb8fe6000000000000000000000000d1d9169f3dd1e7a2e89b1a5e62b7425f6fdb8fe6000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e296113009c902bb372db1d2bb04756c787990a5000000000000000000000000e296113009c902bb372db1d2bb04756c787990a500000000000000000000000000000000000000000000000000216b2ecfe4d60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12562,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0e97deadff3a31601c5a6f92600a5bee2946afb000000000000000000000000f0e97deadff3a31601c5a6f92600a5bee2946afb000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047c0510103840dac5af896a027219231630d40ae00000000000000000000000047c0510103840dac5af896a027219231630d40ae000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001575c7913329e382ccc91afdd2adf735b6686e170000000000000000000000001575c7913329e382ccc91afdd2adf735b6686e17000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12565,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c04bab572576adf321f0002963b70c715a49ec30000000000000000000000000c04bab572576adf321f0002963b70c715a49ec30000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12584,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046e94a8ceb7bf9666ca8da233838fbcd924d466500000000000000000000000046e94a8ceb7bf9666ca8da233838fbcd924d4665000000000000000000000000000000000000000000000000000107c0e2fc200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12605,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a80d3dec587d242f06db92a4398668b66f183c60000000000000000000000005a80d3dec587d242f06db92a4398668b66f183c60000000000000000000000000000000000000000000000001ba6ccee3a25143900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xdc9b7ec5d338c0ec72ade7ba1af0971e433f584d877d5380731e70aabbf90158,2022-02-23 07:54:45.000 UTC,0,true +12606,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b13ca2d6f12407f2430e8da4a30269b22ef07bd0000000000000000000000001b13ca2d6f12407f2430e8da4a30269b22ef07bd000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12607,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068430574da4bdaa97680d7697f2580e46fef559200000000000000000000000068430574da4bdaa97680d7697f2580e46fef5592000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005427190f27b844b71f47aa4ea1028b73e01224250000000000000000000000005427190f27b844b71f47aa4ea1028b73e0122425000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12611,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000159254bf9fe9856e593a23373513548f7ea6c980000000000000000000000000159254bf9fe9856e593a23373513548f7ea6c98000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12612,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3b053a95db2da8ada39f892b17eb7f886216992000000000000000000000000d3b053a95db2da8ada39f892b17eb7f88621699200000000000000000000000000000000000000000000000001a229d893a0c5ea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x93e71a99de387904ec8ccbf0a88a54d45f5ccf7abfeae14da3dd5b8f374cc998,2022-06-28 07:18:45.000 UTC,0,true +12613,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028b273920f12584387bd886175d4f6e0bec446b400000000000000000000000028b273920f12584387bd886175d4f6e0bec446b4000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12614,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b3b7eefd64b11fc3f55fdf36514e591745eef260000000000000000000000005b3b7eefd64b11fc3f55fdf36514e591745eef2600000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12618,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ad6278079874587d7d56b185ae66f54a857670a0000000000000000000000007ad6278079874587d7d56b185ae66f54a857670a000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041c71043ef53a2185523ee0af27ee17a3c7ff03900000000000000000000000041c71043ef53a2185523ee0af27ee17a3c7ff039000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000218c16b3a742a99a4616b76acab015d53c39665e000000000000000000000000218c16b3a742a99a4616b76acab015d53c39665e000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006539dd3f72d798693e4f4b2290d84de3c5115f3d0000000000000000000000006539dd3f72d798693e4f4b2290d84de3c5115f3d000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9edf1c495f910f100a1b3f3eccc9583cb7eefcd000000000000000000000000b9edf1c495f910f100a1b3f3eccc9583cb7eefcd000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d51765816727e250f7a565745d769236b8e2b05f000000000000000000000000d51765816727e250f7a565745d769236b8e2b05f0000000000000000000000000000000000000000000000000032d5013509054000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000139eeb895d86939eb18b52b3347402dddeaad378000000000000000000000000139eeb895d86939eb18b52b3347402dddeaad37800000000000000000000000000000000000000000000000000a73b849db7688f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e342d8cd201ce9d9c14f3a015c8dae0f41e40fa0000000000000000000000001e342d8cd201ce9d9c14f3a015c8dae0f41e40fa00000000000000000000000000000000000000000000000002bdfb72cb4f837300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a946173859026fc1e83341210b919b0b7d60d45d000000000000000000000000a946173859026fc1e83341210b919b0b7d60d45d00000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020b45ffb7bdd01a17c7477acf706ce6781d259f200000000000000000000000020b45ffb7bdd01a17c7477acf706ce6781d259f20000000000000000000000000000000000000000000000000019a46adeaaf1c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe8648813901b86ea9d8ec0a4594c76a6af8dd04000000000000000000000000fe8648813901b86ea9d8ec0a4594c76a6af8dd0400000000000000000000000000000000000000000000000000d52107cdda176600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe93937dfe5ee78b3982fc6260a6a3ca315264dde4b7d375722d89078f0c171dc,2022-03-14 12:02:18.000 UTC,0,true +12645,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061067823763a87b7029e43f1583be9be9658e31000000000000000000000000061067823763a87b7029e43f1583be9be9658e3100000000000000000000000000000000000000000000000000000f5904616e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12648,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4796a49c6a7b316612f7a095ffd33ac2b078953000000000000000000000000e4796a49c6a7b316612f7a095ffd33ac2b078953000000000000000000000000000000000000000000000000002579a693e21fa900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12652,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a99fd459b17ca41258bd85704f6ed8db8ea2e720000000000000000000000008a99fd459b17ca41258bd85704f6ed8db8ea2e72000000000000000000000000000000000000000000000000001c267d3ce0528000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba003e0ac4a61f3ba9d7f60ebdf8c0d76e8f6d7d000000000000000000000000ba003e0ac4a61f3ba9d7f60ebdf8c0d76e8f6d7d000000000000000000000000000000000000000000000000003e8456d93aaad900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12654,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000cfa366350853663ac7d6128217138a02af8af66e000000000000000000000000cfa366350853663ac7d6128217138a02af8af66e0000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087e4c23cc70d2f83d94748709d6337bd7a3a700000000000000000000000000087e4c23cc70d2f83d94748709d6337bd7a3a70000000000000000000000000000000000000000000000000000041647b1a6e853400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12657,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047769fcdfd4a92b858d1fa8b89569fcd5865db1100000000000000000000000047769fcdfd4a92b858d1fa8b89569fcd5865db11000000000000000000000000000000000000000000000000006387ecff04b63100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000191390bf43d7d987684a7fb2a0aacfa509984a2e000000000000000000000000191390bf43d7d987684a7fb2a0aacfa509984a2e000000000000000000000000000000000000000000000000002e4412dc7d513a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc262a30c95ec32fe38ca820660febe4e206cede000000000000000000000000cc262a30c95ec32fe38ca820660febe4e206cede000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12660,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091c0cba20f536cd7e8163f0335ae98f5eb0eeff400000000000000000000000091c0cba20f536cd7e8163f0335ae98f5eb0eeff400000000000000000000000000000000000000000000000000060a24181e400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12661,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abf2eb2b127c8de7e6cc34fa236dedf28a9761ce000000000000000000000000abf2eb2b127c8de7e6cc34fa236dedf28a9761ce00000000000000000000000000000000000000000000000000012309ce54000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12662,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007dbcfb15d9945c0651319982425d4daa4eeea56d0000000000000000000000007dbcfb15d9945c0651319982425d4daa4eeea56d00000000000000000000000000000000000000000000000000060a24181e400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d270c1d351e54520e42a809e3072865cbcb397db000000000000000000000000d270c1d351e54520e42a809e3072865cbcb397db00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024c275c4b6303b2dccb2fe5800c9b3c4fe1ac8c600000000000000000000000024c275c4b6303b2dccb2fe5800c9b3c4fe1ac8c600000000000000000000000000000000000000000000000000a72fc21487ac8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089709569ace26c3202bc29ba1149c77fe9cd1ceb00000000000000000000000089709569ace26c3202bc29ba1149c77fe9cd1ceb00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12669,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e97f96e80e3a324f0564b4b2e806238d9666fc50000000000000000000000003e97f96e80e3a324f0564b4b2e806238d9666fc500000000000000000000000000000000000000000000000000744ca984f499b600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12671,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002108e0845a138c031731e756117e71d5f87671b40000000000000000000000002108e0845a138c031731e756117e71d5f87671b400000000000000000000000000000000000000000000000000002d79883d200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12676,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086d7b8065f85eba4cc25d9476478c033c9a31c8800000000000000000000000086d7b8065f85eba4cc25d9476478c033c9a31c880000000000000000000000000000000000000000000000000dde368945c8410000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12677,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d9450faa3a0d1a68ef7d259db484e9f2b9927d40000000000000000000000000d9450faa3a0d1a68ef7d259db484e9f2b9927d4000000000000000000000000000000000000000000000000005b6ee628b48a1000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075671888fd4090fbe05bd130ab8999e72e21b7c000000000000000000000000075671888fd4090fbe05bd130ab8999e72e21b7c000000000000000000000000000000000000000000000000002066968eba9c63e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c889f649bcf28072c5aaf6e853568e506dee0c6a000000000000000000000000c889f649bcf28072c5aaf6e853568e506dee0c6a00000000000000000000000000000000000000000000000000448704339ef90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b95a4f17e9792afc6d9fc585e57b7f8bab97b1a0000000000000000000000006b95a4f17e9792afc6d9fc585e57b7f8bab97b1a000000000000000000000000000000000000000000000000007819c56fbeb77300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12686,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f514e198143ed375ad99c224059a3bc301766adb000000000000000000000000f514e198143ed375ad99c224059a3bc301766adb0000000000000000000000000000000000000000000000000045c913cd7b328000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b11b6d5eaf7dcc3dc2d65067e585ac814a0e29c0000000000000000000000009b11b6d5eaf7dcc3dc2d65067e585ac814a0e29c000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0d945151be2be0ba1c94fd3ad7441596cfe281d585c54ff465280e6a153d6c2b,2022-03-12 12:04:38.000 UTC,0,true +12689,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003fedefe818aad7901954bae7efe677542c6177f00000000000000000000000003fedefe818aad7901954bae7efe677542c6177f0000000000000000000000000000000000000000000000000005b0d15f0743f0700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12690,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e20337ca0354a7007a0fb1ac4b3bbc6229d8e99d000000000000000000000000e20337ca0354a7007a0fb1ac4b3bbc6229d8e99d00000000000000000000000000000000000000000000000000581ac2ecac5b1900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12692,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8ba35cc5493e2dc4e0780d4e299fd627265baaf000000000000000000000000f8ba35cc5493e2dc4e0780d4e299fd627265baaf0000000000000000000000000000000000000000000000000413c2366c04bd2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fce1466cd1533580d6988fd3f6de2312e7f9b478000000000000000000000000fce1466cd1533580d6988fd3f6de2312e7f9b47800000000000000000000000000000000000000000000000002dcb9be0f6ed76e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12695,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077341b139631a179397692815b6fc3e015244aec00000000000000000000000077341b139631a179397692815b6fc3e015244aec000000000000000000000000000000000000000000000000001f5de40cd14bc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013faff37f9d615514d88c38d5371b74012a159f500000000000000000000000013faff37f9d615514d88c38d5371b74012a159f50000000000000000000000000000000000000000000000000117906885aec5c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a55920c86b7b277aa9e46dd35b5243b7024d4da0000000000000000000000002a55920c86b7b277aa9e46dd35b5243b7024d4da000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12699,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1e192e0c53412eea8ea2e83c4773c5682f615ee000000000000000000000000b1e192e0c53412eea8ea2e83c4773c5682f615ee000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12700,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004b57903f6089e017cb58cf3106685c46ca52f9f00000000000000000000000004b57903f6089e017cb58cf3106685c46ca52f9f000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12701,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a54641040bcb58b095f7e2c1ce7cb9fbd9b89730000000000000000000000008a54641040bcb58b095f7e2c1ce7cb9fbd9b897300000000000000000000000000000000000000000000000000a68329c833fefd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001876761f051f548d5e645a971a235860f8cb07420000000000000000000000001876761f051f548d5e645a971a235860f8cb0742000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a166a2403953146f27f4d3fae975ce2c71f0c85f000000000000000000000000a166a2403953146f27f4d3fae975ce2c71f0c85f000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba18e462a6145c1b45b57642b7116f5e4625945b000000000000000000000000ba18e462a6145c1b45b57642b7116f5e4625945b000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12708,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb50e64a84303861f4ce3cb7ec2c278719f0e736000000000000000000000000fb50e64a84303861f4ce3cb7ec2c278719f0e736000000000000000000000000000000000000000000000000000a3886eaca5c8100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12709,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a961583fa5d5bce5303873f1e03ab47404709b2a000000000000000000000000a961583fa5d5bce5303873f1e03ab47404709b2a000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12710,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b24adeb0b9fbbca38192c4104120d0065d3d67fe000000000000000000000000b24adeb0b9fbbca38192c4104120d0065d3d67fe000000000000000000000000000000000000000000000000001f36d97df45cc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12711,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ae52eedb15f230f5808f7534f9dc7ce714263e30000000000000000000000006ae52eedb15f230f5808f7534f9dc7ce714263e3000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12712,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000130ff3c7481bdda0341a8bf9b49d7576405e2ae5000000000000000000000000130ff3c7481bdda0341a8bf9b49d7576405e2ae5000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aab30cec92a8340dd03f3b53192957beb46ce602000000000000000000000000aab30cec92a8340dd03f3b53192957beb46ce602000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065eda3923fe4a0da4457f7386d0d53160deed0ef00000000000000000000000065eda3923fe4a0da4457f7386d0d53160deed0ef000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12715,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5803ab7d40541c08bba4b604537f8a1ec1ff111000000000000000000000000b5803ab7d40541c08bba4b604537f8a1ec1ff111000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d3a16071fb668aa901f9779d0224fd806f790610000000000000000000000000d3a16071fb668aa901f9779d0224fd806f79061000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c500a923764edb66541d2d73ba7976784f2fc860000000000000000000000004c500a923764edb66541d2d73ba7976784f2fc86000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12718,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058f1449c9ed689d565a44391cae37391e54ed79200000000000000000000000058f1449c9ed689d565a44391cae37391e54ed792000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12719,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009326d59692f9e9b81be83e5bb3dde124ce1929750000000000000000000000009326d59692f9e9b81be83e5bb3dde124ce192975000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12720,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5ec11a3c2d0d16a237962739877eed9fda44444000000000000000000000000a5ec11a3c2d0d16a237962739877eed9fda44444000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12721,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031f87119d2d00f2647494a4b621ca52d228f32e900000000000000000000000031f87119d2d00f2647494a4b621ca52d228f32e9000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12722,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081c2e1491bb91821d847b24312c5ef47c39b73a700000000000000000000000081c2e1491bb91821d847b24312c5ef47c39b73a7000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12723,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a11e87dea51429fa7db5f082dd924adbd69049eb000000000000000000000000a11e87dea51429fa7db5f082dd924adbd69049eb0000000000000000000000000000000000000000000000000d7cb58247ad936c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12724,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fca5d3cbe52d1b6271f4281c42402113ffac582b000000000000000000000000fca5d3cbe52d1b6271f4281c42402113ffac582b000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12725,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f4e9af1249e6ab82ac6d0ec433a97c9107b62470000000000000000000000008f4e9af1249e6ab82ac6d0ec433a97c9107b6247000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12726,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff590b4ccb8c7759cef24e9d808852628d837ddf000000000000000000000000ff590b4ccb8c7759cef24e9d808852628d837ddf000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12727,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e281add1e87f5aa0fd9c39d8bcfd7c1a6da61fd0000000000000000000000004e281add1e87f5aa0fd9c39d8bcfd7c1a6da61fd000000000000000000000000000000000000000000000000002657444e6a800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12728,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfc6b3bd3c6b935f81f5adf4d6f7c2e7775f728a000000000000000000000000cfc6b3bd3c6b935f81f5adf4d6f7c2e7775f728a000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3f319e3d501d5f4dc5d3fd33d18e6ba604d0184000000000000000000000000e3f319e3d501d5f4dc5d3fd33d18e6ba604d0184000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12730,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006fd9ef433f64e6bbd329c97bd4b896c27e209ee70000000000000000000000006fd9ef433f64e6bbd329c97bd4b896c27e209ee7000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12731,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a213f4e26ad5d1e446deb665a36f062d6bd26966000000000000000000000000a213f4e26ad5d1e446deb665a36f062d6bd26966000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12732,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea02854800d8c005f1f66df7ddd8512501ccb6d3000000000000000000000000ea02854800d8c005f1f66df7ddd8512501ccb6d300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a139bff325056bced6728154733a3c6198e5e946000000000000000000000000a139bff325056bced6728154733a3c6198e5e946000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083540f4e22064133f42671ebf6bc8c70dc2d3adc00000000000000000000000083540f4e22064133f42671ebf6bc8c70dc2d3adc000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b15c515b73817cedebf7501735c6e0da8344e3df000000000000000000000000b15c515b73817cedebf7501735c6e0da8344e3df00000000000000000000000000000000000000000000000002bde0a65af2303800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12741,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004a85db7967db16bd82f93f2f426eff3cc9261e7e000000000000000000000000000000000000000000000003f45a2d2e460cf8dc,,,1,true +12742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057424e704d9912129445cadae8c321a3bede349d00000000000000000000000057424e704d9912129445cadae8c321a3bede349d000000000000000000000000000000000000000000000000017e9c164ba03bfb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a492dbab5fdbd910ec4120aca58ac72999eed160000000000000000000000004a492dbab5fdbd910ec4120aca58ac72999eed1600000000000000000000000000000000000000000000000000207c4cf86d1c8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12748,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000755d95d8374e861b970ab341494ab2016555611a000000000000000000000000755d95d8374e861b970ab341494ab2016555611a0000000000000000000000000000000000000000000000000018cee9a1a7627f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d661570546cfceccb801c02bd043248a36cfbc99000000000000000000000000d661570546cfceccb801c02bd043248a36cfbc990000000000000000000000000000000000000000000000000020d0868b0fbb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12753,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000071c1812bb93315c214a3855504dc6cb1f910545000000000000000000000000071c1812bb93315c214a3855504dc6cb1f91054500000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12754,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000158dc5b8d904b089e60f26dc6e46c7eaaa45ab19000000000000000000000000158dc5b8d904b089e60f26dc6e46c7eaaa45ab1900000000000000000000000000000000000000000000000000207d9ea1c3a7c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12756,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1344576ad891ac66e5252dba5365b88da1fd99b000000000000000000000000e1344576ad891ac66e5252dba5365b88da1fd99b000000000000000000000000000000000000000000000000000702eb3368060000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12757,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a492dbab5fdbd910ec4120aca58ac72999eed160000000000000000000000004a492dbab5fdbd910ec4120aca58ac72999eed16000000000000000000000000000000000000000000000000061cc5d8345ac09700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12759,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007461f3b3d064138f1cb963f0d1322c6568c3c0910000000000000000000000000000000000000000000000174dd0001a9d4accf9,,,1,true +12760,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007461f3b3d064138f1cb963f0d1322c6568c3c091000000000000000000000000000000000000000000000051b6477b647f405e12,,,1,true +12762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075586c3a0bc01ca9a0e36a712bee1523a1cc631200000000000000000000000075586c3a0bc01ca9a0e36a712bee1523a1cc63120000000000000000000000000000000000000000000000002980e84cbd48c67d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7a626ddae1b5bb518fc9ecf24c96b772cf5645a0ae662566360bddd439346c56,2021-11-21 08:42:13.000 UTC,0,true +12763,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000705c7909e5d4b833778cb95fee849c7dff1d0681000000000000000000000000705c7909e5d4b833778cb95fee849c7dff1d0681000000000000000000000000000000000000000000000000004cfd3251019af800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3c6beb2f0de8e0d5c88f8dc7a801ad76b93b3ee000000000000000000000000f3c6beb2f0de8e0d5c88f8dc7a801ad76b93b3ee00000000000000000000000000000000000000000000000000062a5fde78d17e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12769,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1116f024b707e3640b2a0f312af3fdcc336d4a7000000000000000000000000c1116f024b707e3640b2a0f312af3fdcc336d4a7000000000000000000000000000000000000000000000000015714a295308f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009bd1f47bf530f5e0eb44dda1236e4c8e817dcd8d0000000000000000000000009bd1f47bf530f5e0eb44dda1236e4c8e817dcd8d00000000000000000000000000000000000000000000000004db73254763000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055d4deb9198118354f9edb1a0d0efd754a3b765b00000000000000000000000055d4deb9198118354f9edb1a0d0efd754a3b765b000000000000000000000000000000000000000000000000005b4b64304f482400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000809505a32511e8d1a04cf40b15ca1ef86929cf4c000000000000000000000000809505a32511e8d1a04cf40b15ca1ef86929cf4c0000000000000000000000000000000000000000000000000117191b3f0fe1c100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x46b423fafd82e1b9314ed49ad3ee97f6f3f369006cf74ecf09434e5e84294872,2022-05-07 06:09:43.000 UTC,0,true +12776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e693edbbfbd115a36c438a02584a23c36c329190000000000000000000000008e693edbbfbd115a36c438a02584a23c36c329190000000000000000000000000000000000000000000000000ddb55e27d5ff42600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xaa1d4f12a955d125b3338ea70941a1e5b099ca720719e009b9e27f5a493d900f,2021-11-29 01:03:57.000 UTC,0,true +12777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fb32aa7933be746a166199eb498114915df22cb0000000000000000000000007fb32aa7933be746a166199eb498114915df22cb000000000000000000000000000000000000000000000000005730e38f31f63c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12780,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c10c675b9aee3cb7dca0c455f4b94d45367ddbf0000000000000000000000008c10c675b9aee3cb7dca0c455f4b94d45367ddbf00000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000719618e0a60a1bed6e136be73533ff057c227148000000000000000000000000719618e0a60a1bed6e136be73533ff057c22714800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091f6a0688c1fcd87edf8dd094b709f0626f5960d00000000000000000000000091f6a0688c1fcd87edf8dd094b709f0626f5960d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12784,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000809505a32511e8d1a04cf40b15ca1ef86929cf4c000000000000000000000000809505a32511e8d1a04cf40b15ca1ef86929cf4c0000000000000000000000000000000000000000000000093ae73131b2ce43ce00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xb57799339a131dd602339412db52c1a302a25a12ddc54d63716561511f0ea4cb,2022-05-07 06:00:02.000 UTC,0,true +12785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005326b539394f053ddbc1277362bb1719ecb0f67f0000000000000000000000005326b539394f053ddbc1277362bb1719ecb0f67f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a629ed28c4d37c5571f70ee756faee46a00ff06a000000000000000000000000a629ed28c4d37c5571f70ee756faee46a00ff06a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12788,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009943bf91aa4b0fc79ff880a62d3b3880b7dd117d0000000000000000000000009943bf91aa4b0fc79ff880a62d3b3880b7dd117d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c085aea011244074edc9a58e8687ade6c4cbc81a000000000000000000000000c085aea011244074edc9a58e8687ade6c4cbc81a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12791,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007bdf143f15b3b7d83d1b49e8ad3d6a496bd3b8300000000000000000000000007bdf143f15b3b7d83d1b49e8ad3d6a496bd3b8300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004dbfaee2a9a1a4b453ff3c8b0fdcb98c10772f6b0000000000000000000000004dbfaee2a9a1a4b453ff3c8b0fdcb98c10772f6b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12793,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f7f14d3a32d1dd3e1c769a8c01b74cc6b927c860000000000000000000000005f7f14d3a32d1dd3e1c769a8c01b74cc6b927c8600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b8d2e8fdcadd8524c25a59c1df7d6fbbf522a170000000000000000000000004b8d2e8fdcadd8524c25a59c1df7d6fbbf522a1700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12795,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab7d26bd08d4cc1274b337609ae50832a5f79953000000000000000000000000ab7d26bd08d4cc1274b337609ae50832a5f7995300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066a67b1bc7304cce366e562617c07ddd0d41f35a00000000000000000000000066a67b1bc7304cce366e562617c07ddd0d41f35a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f71d5ce40059259b0dcc70c62e4bcd1186cafc6e000000000000000000000000f71d5ce40059259b0dcc70c62e4bcd1186cafc6e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12798,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c84758bc4d3e4f3c0412376e904fec06b675f088000000000000000000000000c84758bc4d3e4f3c0412376e904fec06b675f08800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12799,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3f595cf45c5b3bbc9866cd5893ea1a561603538000000000000000000000000f3f595cf45c5b3bbc9866cd5893ea1a56160353800000000000000000000000000000000000000000000000001a65169d00b10ff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12801,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001faa9b8c8eacffbae7c5cd2d5da4642cabfc3bf00000000000000000000000001faa9b8c8eacffbae7c5cd2d5da4642cabfc3bf00000000000000000000000000000000000000000000000000040ef039249039b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12803,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000028bdc7378d6e28e1b7db3578e7553494e609b5060000000000000000000000000000000000000000000000008ac7230489e80000,,,1,true +12804,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008cc4de9142fd56061197a0fc41e77446c5befb260000000000000000000000008cc4de9142fd56061197a0fc41e77446c5befb2600000000000000000000000000000000000000000000000002bcae08e5f95e7400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf3802b74f5e828bc424e869081d2579d6f9a14fa2c82b934fc3b86886231745f,2022-01-31 13:00:57.000 UTC,0,true +12805,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000515c495808d85b1955e9cc99af4bffb59898c458000000000000000000000000515c495808d85b1955e9cc99af4bffb59898c45800000000000000000000000000000000000000000000000009b6de9a817efd3300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006442e7898a122afec3cb6db82519461f8a30e8890000000000000000000000006442e7898a122afec3cb6db82519461f8a30e889000000000000000000000000000000000000000000000000006fdd3b0899f80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12811,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc0274c302e5c90d092a02fd41f0238eba44b72b000000000000000000000000bc0274c302e5c90d092a02fd41f0238eba44b72b0000000000000000000000000000000000000000000000000dd0c7089e4cd75800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000212e676d6252a03f9f2e06ae8de251fa5c9b4a14000000000000000000000000212e676d6252a03f9f2e06ae8de251fa5c9b4a14000000000000000000000000000000000000000000000000006f8e40053fc80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f97c713f909bbee228c76176de971b6ce0a03120000000000000000000000004f97c713f909bbee228c76176de971b6ce0a0312000000000000000000000000000000000000000000000000016901d16999a4e100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb22ffae8c9205cc3677f16c5b79dffba9479b4a000000000000000000000000bb22ffae8c9205cc3677f16c5b79dffba9479b4a00000000000000000000000000000000000000000000000000000573039d050000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12821,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000065d70debbab734a5af4c3c52db9442ae74c211b700000000000000000000000065d70debbab734a5af4c3c52db9442ae74c211b7000000000000000000000000000000000000000000000007a170773c6941199400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12822,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000addb10584f84d8afaaa3151c44104e667cc5f845000000000000000000000000addb10584f84d8afaaa3151c44104e667cc5f845000000000000000000000000000000000000000000000000003b939aff026ad500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021bc50129dd6c34162ec0cf715857042cd09ec2300000000000000000000000021bc50129dd6c34162ec0cf715857042cd09ec2300000000000000000000000000000000000000000000000000252cc852a6358000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd0229dc6b9d2977a6104d2d42e68d6646cba411000000000000000000000000cd0229dc6b9d2977a6104d2d42e68d6646cba411000000000000000000000000000000000000000000000000005d5ff49dd39c3200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000458dc04bcd7e95c5bbbe0a7a997e2a6923add5c8000000000000000000000000458dc04bcd7e95c5bbbe0a7a997e2a6923add5c800000000000000000000000000000000000000000000000006e6d708d296866200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8e143b2b975340b1f3bc9877f0befd03bbf7fece4f2ef7addd4a94bc0a0ba605,2021-12-09 01:22:14.000 UTC,0,true +12826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000746e6c744fe06068a7a929d164537ed5f8b1763a000000000000000000000000746e6c744fe06068a7a929d164537ed5f8b1763a000000000000000000000000000000000000000000000000000000001215b93800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4ef68733ce0bbac45f02c2b183c9ce7c21843dd000000000000000000000000c4ef68733ce0bbac45f02c2b183c9ce7c21843dd00000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12828,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000016b53915280fdbcc205dc90b83f802ec5e3656e100000000000000000000000016b53915280fdbcc205dc90b83f802ec5e3656e100000000000000000000000000000000000000000000002828731523712523ff00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000370b3b4ceefd6778318ff01b7102be801d4fb661000000000000000000000000370b3b4ceefd6778318ff01b7102be801d4fb661000000000000000000000000000000000000000000000000006203718bd0b76300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092a966e56bbfb61f634cbeda33cd54efa068e99300000000000000000000000092a966e56bbfb61f634cbeda33cd54efa068e99300000000000000000000000000000000000000000000000000e6ed27d666800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b751649de24d0c89e1da9146a21d0edb856ab21c000000000000000000000000b751649de24d0c89e1da9146a21d0edb856ab21c00000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12840,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051adc9e994b4fee643906fbf2c25c1dc101191bc00000000000000000000000051adc9e994b4fee643906fbf2c25c1dc101191bc0000000000000000000000000000000000000000000000000022102f217f257f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066eaf73d1608983e349fc2ab7f54bac42f59cf1e00000000000000000000000066eaf73d1608983e349fc2ab7f54bac42f59cf1e00000000000000000000000000000000000000000000000000034ac267addfab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cac3bfe014ee049d2eeec30c7a396a29b1fe1349000000000000000000000000cac3bfe014ee049d2eeec30c7a396a29b1fe13490000000000000000000000000000000000000000000000000001d565e5c2a7f700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a71f0695dacde00ccecc622556f711e2b4d50a00000000000000000000000003a71f0695dacde00ccecc622556f711e2b4d50a0000000000000000000000000000000000000000000000000010402a50fa3095d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5f3eb59805654adf40549be292648881c654a3717d9ea5dd78581b1c62dc797f,2022-08-05 14:59:48.000 UTC,0,true +12844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000915d26fa87d887e165d6573a77461f79a3de37ed000000000000000000000000915d26fa87d887e165d6573a77461f79a3de37ed00000000000000000000000000000000000000000000000006e2029807ce00b600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073b2e83fa1ee3057053350e830ecc3b535672b6200000000000000000000000073b2e83fa1ee3057053350e830ecc3b535672b620000000000000000000000000000000000000000000000000049dabdd8e497f800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd149b57d5e2aacdeeb6c028b7daaa738f78739b107a381c3900e09cc7e14f59a,2022-07-17 11:26:13.000 UTC,0,true +12846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021fb9d4351ec723fae6e643a92b8fdb5aaaf5b4a00000000000000000000000021fb9d4351ec723fae6e643a92b8fdb5aaaf5b4a00000000000000000000000000000000000000000000000000034ac267addfab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000378991fb57ee360b66a106eef83e362dc8ba8c1c000000000000000000000000378991fb57ee360b66a106eef83e362dc8ba8c1c000000000000000000000000000000000000000000000000001c5b2b6a0e93c700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046483f48fdf320b98700c7309270c0ad44f1d24400000000000000000000000046483f48fdf320b98700c7309270c0ad44f1d24400000000000000000000000000000000000000000000000001cdda4faccd000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a9da0a5be8c3fcdf748807186ae25618aa3d0cd0000000000000000000000009a9da0a5be8c3fcdf748807186ae25618aa3d0cd000000000000000000000000000000000000000000000000004c2cb8d197c90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000954b0f9b718d637e3e748718538687a4779afc96000000000000000000000000954b0f9b718d637e3e748718538687a4779afc960000000000000000000000000000000000000000000000000047aad43b28ac7f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd079cc159b66c3a4c64ebbe1555226913c4a1c4000000000000000000000000dd079cc159b66c3a4c64ebbe1555226913c4a1c400000000000000000000000000000000000000000000000008cff922b85f800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x662831a1c7275eedaa8dda8d086f4719d8904838cab7fdb8cc04477a557eb531,2022-11-01 19:49:11.000 UTC,0,true +12861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000828b3b3cb2fa9eb8c631d40db9de6b0809fcaacc000000000000000000000000828b3b3cb2fa9eb8c631d40db9de6b0809fcaacc000000000000000000000000000000000000000000000000004f7948c33f618d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xff8a829554519b0d6b3348dd373d4fa05b7009f961b4f5f97d9401a19d1957e5,2022-08-06 09:46:38.000 UTC,0,true +12864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6e3db3b88c1c9a5f19554df3736e6c5c6630ad0000000000000000000000000b6e3db3b88c1c9a5f19554df3736e6c5c6630ad0000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12865,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2966908f05b065d7006c25d91f991b3260c9250000000000000000000000000a2966908f05b065d7006c25d91f991b3260c92500000000000000000000000000000000000000000000000000001d8865af6030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000659ba0b652fb66bb6c1261f5d0aeaeb30fcfec35000000000000000000000000659ba0b652fb66bb6c1261f5d0aeaeb30fcfec35000000000000000000000000000000000000000000000000005457648effdaec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6fd1ad1419a72cf120586bf741e7292872d91c4000000000000000000000000c6fd1ad1419a72cf120586bf741e7292872d91c4000000000000000000000000000000000000000000000000014af5dad985d03c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e77a8fb60de5f73c610997976e619e4d51d09c98000000000000000000000000e77a8fb60de5f73c610997976e619e4d51d09c98000000000000000000000000000000000000000000000000001e00e95f906c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3f34c80b30ce105704e259a79cacb53fd35e124000000000000000000000000f3f34c80b30ce105704e259a79cacb53fd35e1240000000000000000000000000000000000000000000000002a53c6d724f1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e71c9fc7f58baa5501f8f64c0b7b8fb11b7bdcd9000000000000000000000000e71c9fc7f58baa5501f8f64c0b7b8fb11b7bdcd90000000000000000000000000000000000000000000000000000cd3e077f172200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12882,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9cef4b10b7461fc0db63bc55b01721583b4a620000000000000000000000000e9cef4b10b7461fc0db63bc55b01721583b4a620000000000000000000000000000000000000000000000000001283b363e5361a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df621e4da74bb2249b7bdec7f5db6d00967d52a9000000000000000000000000df621e4da74bb2249b7bdec7f5db6d00967d52a90000000000000000000000000000000000000000000000000043a476d6e1006e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x83d3e95d584cd5c794dbc7b9547838b27fc3ae18af10baf5cc1ac49c9d4ed667,2022-05-17 07:45:36.000 UTC,0,true +12885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea62f4842744fc78400e7a6c7e5ff6b0dd9bea37000000000000000000000000ea62f4842744fc78400e7a6c7e5ff6b0dd9bea37000000000000000000000000000000000000000000000000010121dc0ad067b400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12886,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b4a1e68ec39294ee9d7bc92bcfe66c2cdc47f5dd000000000000000000000000b4a1e68ec39294ee9d7bc92bcfe66c2cdc47f5dd000000000000000000000000000000000000000000000000b9066c620cb5876900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d03635c0adf3501ccfc69e5cefd8ecf88cadd3c0000000000000000000000008d03635c0adf3501ccfc69e5cefd8ecf88cadd3c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008176d3d058a568b3ec428105cd994cc4d7acdaca0000000000000000000000008176d3d058a568b3ec428105cd994cc4d7acdaca000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e4c5a6730f373f43aa11f5c10b1f89bb4cd731f0000000000000000000000004e4c5a6730f373f43aa11f5c10b1f89bb4cd731f000000000000000000000000000000000000000000000000000018f88167808000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e17634a96b2f1a0f9c0cde3d825f7345e2071dd5000000000000000000000000e17634a96b2f1a0f9c0cde3d825f7345e2071dd50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6112bb75d036a4af8d1fae4eb6cb01e9731f703000000000000000000000000d6112bb75d036a4af8d1fae4eb6cb01e9731f7030000000000000000000000000000000000000000000000000021fdbe4608150000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c8b53c62cb8b13993fba7bfcb0be04bec999bd8f000000000000000000000000c8b53c62cb8b13993fba7bfcb0be04bec999bd8f0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e4c5a6730f373f43aa11f5c10b1f89bb4cd731f0000000000000000000000004e4c5a6730f373f43aa11f5c10b1f89bb4cd731f00000000000000000000000000000000000000000000000000044b1bd821019300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d08c941d3d5e36ffcfa0a090a7247ac08b0473f5000000000000000000000000d08c941d3d5e36ffcfa0a090a7247ac08b0473f5000000000000000000000000000000000000000000000000001fb6edc125938000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000befb73c7f61ed9f3c5392a25acc58cfe00cc0554000000000000000000000000befb73c7f61ed9f3c5392a25acc58cfe00cc055400000000000000000000000000000000000000000000000000222eac0340e70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12900,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004046d34aa2748a6d9d252526681b0d7d70ef8a4a0000000000000000000000004046d34aa2748a6d9d252526681b0d7d70ef8a4a00000000000000000000000000000000000000000000000001100d4b270c0a4700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12901,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075aa792a13f651a167ec764915ce19619342190100000000000000000000000075aa792a13f651a167ec764915ce1961934219010000000000000000000000000000000000000000000000000039843e1868fa2700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f600000000000000000000000001687491cb797f011790f349cbf8969dad49fcd300000000000000000000000001687491cb797f011790f349cbf8969dad49fcd30000000000000000000000000000000000000000000000069131912f2c09a6f700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12903,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4701f5ab31d4104c091a9b5504827ec6aacdf39000000000000000000000000d4701f5ab31d4104c091a9b5504827ec6aacdf39000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12907,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009bd8f365fe9e81826ff3069516f01fdc7f7c81cf0000000000000000000000009bd8f365fe9e81826ff3069516f01fdc7f7c81cf0000000000000000000000000000000000000000000000000005f41a4b6b0a4100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12908,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002282bc8e090439a0195e0c862ae3ffc47bd2edd80000000000000000000000002282bc8e090439a0195e0c862ae3ffc47bd2edd8000000000000000000000000000000000000000000000000008220c6a2c11be600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a787a56c43847a3b5a0110d0b5e004e47f57b22e000000000000000000000000a787a56c43847a3b5a0110d0b5e004e47f57b22e00000000000000000000000000000000000000000000000002115892d54d00c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12910,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019e2feb48d91ef9cddcc4efbad34f83d537e056b00000000000000000000000019e2feb48d91ef9cddcc4efbad34f83d537e056b0000000000000000000000000000000000000000000000000004758442a6703f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002921ad97c82508fc9d5ec82d588392c41e707aef0000000000000000000000002921ad97c82508fc9d5ec82d588392c41e707aef00000000000000000000000000000000000000000000000000087910629986b400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12912,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c28be66c952d1cd635323d22bb0ce47aa5e5b4e0000000000000000000000009c28be66c952d1cd635323d22bb0ce47aa5e5b4e0000000000000000000000000000000000000000000000000007c0ccd18b8e8500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aba29c745654aacfe8ffbdc9d41b908d18818dc9000000000000000000000000aba29c745654aacfe8ffbdc9d41b908d18818dc90000000000000000000000000000000000000000000000000009449e9cce5d8a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12914,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e32c81de998997fed27be29e5a09be5202007fa0000000000000000000000007e32c81de998997fed27be29e5a09be5202007fa000000000000000000000000000000000000000000000000003c6568f12e800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000777af6717e781652c513e6e3a90088d4e1d404f4000000000000000000000000777af6717e781652c513e6e3a90088d4e1d404f4000000000000000000000000000000000000000000000000003e0a8a66fedde000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000539b3f56d9e09e59d814ae8d89cd6a0376f1ee8d000000000000000000000000539b3f56d9e09e59d814ae8d89cd6a0376f1ee8d000000000000000000000000000000000000000000000000014f0b69a5d5efae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x93e5b6e3508153f1b6f653574d3d0b61906d3c94a76423690020d306ce860960,2022-04-21 09:27:28.000 UTC,0,true +12920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7913d85f52cf4010b1439c13043918cbedc3fb6000000000000000000000000e7913d85f52cf4010b1439c13043918cbedc3fb600000000000000000000000000000000000000000000000000af4c851d66c30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12921,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004485524d6c604e5bac8b574c3a084da6d870bee90000000000000000000000004485524d6c604e5bac8b574c3a084da6d870bee9000000000000000000000000000000000000000000000000013fb438495583d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12922,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006840046c485f25b355efbcdd68f12b9af94af5e80000000000000000000000006840046c485f25b355efbcdd68f12b9af94af5e80000000000000000000000000000000000000000000000000328761afeaaded700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009071d90ce852d0c5ab0a5fbdd5f79110246cfe8f0000000000000000000000009071d90ce852d0c5ab0a5fbdd5f79110246cfe8f00000000000000000000000000000000000000000000000000653d9290edc77a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d3efc714ec1828967d3d13e65a2709c1639d5110000000000000000000000003d3efc714ec1828967d3d13e65a2709c1639d511000000000000000000000000000000000000000000000000002b208e82668d9500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x971aca1eb95534c05ad2d19d1d1b3261445e1e271d42a888019e1672666569c8,2022-04-19 17:24:24.000 UTC,0,true +12926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000255441d1244e801c4728b87f942e8299ae416400000000000000000000000000255441d1244e801c4728b87f942e8299ae41640000000000000000000000000000000000000000000000000006aa4592d3879100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092d9078f2d1e56d0027ebea225a132966ef199ca00000000000000000000000092d9078f2d1e56d0027ebea225a132966ef199ca0000000000000000000000000000000000000000000000000005dcaa8fe1200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12934,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027ee65c004cbc638b558719ec0b5ca79b7f6570400000000000000000000000027ee65c004cbc638b558719ec0b5ca79b7f657040000000000000000000000000000000000000000000000000c0b749a9b91c0cf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bde9553f80906e869a07ef97e9e1bfce9990659a000000000000000000000000bde9553f80906e869a07ef97e9e1bfce9990659a00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12937,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000426033ec3f5be02d1804d7f13156079fe4e8f375000000000000000000000000426033ec3f5be02d1804d7f13156079fe4e8f375000000000000000000000000000000000000000000000000001dafb87e5ec1bc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038631194260edb73c589184037a4a853487d72dd00000000000000000000000038631194260edb73c589184037a4a853487d72dd00000000000000000000000000000000000000000000000000054ec37a271a3a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005043af16d5d2079310a08fb28ed574fb7791465f0000000000000000000000005043af16d5d2079310a08fb28ed574fb7791465f00000000000000000000000000000000000000000000000000a8ac8d0e25108100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dee8450efd643f7ee615ec6ae8b91bac59c49f1d000000000000000000000000dee8450efd643f7ee615ec6ae8b91bac59c49f1d0000000000000000000000000000000000000000000000000000352bff8879c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12945,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003391b9df7de82946e87f1a0baa92bd962011245d0000000000000000000000003391b9df7de82946e87f1a0baa92bd962011245d00000000000000000000000000000000000000000000000001618fc911ff3d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12947,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b54cb94f64697f723bdd16886de9e13b2fd11831000000000000000000000000b54cb94f64697f723bdd16886de9e13b2fd118310000000000000000000000000000000000000000000000000019105228d7c27d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12949,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd46b0537b49ea212ec86308c20bd0070477d60e000000000000000000000000dd46b0537b49ea212ec86308c20bd0070477d60e00000000000000000000000000000000000000000000000000c2fa3d9bc3d16900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12950,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef20f2b7367028a1adf9d1d0bcb7f9cea6beb0c3000000000000000000000000ef20f2b7367028a1adf9d1d0bcb7f9cea6beb0c30000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077cfb5f69dd4825c0ffd6fce079af786ac13a10800000000000000000000000077cfb5f69dd4825c0ffd6fce079af786ac13a1080000000000000000000000000000000000000000000000000058d15e1762800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007bfeeafd6bdb6a87e9c3d9454311964f4feeec450000000000000000000000007bfeeafd6bdb6a87e9c3d9454311964f4feeec450000000000000000000000000000000000000000000000000001e69beac04f4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12954,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b22f4e0b10b2d3a09f8bddf02988d3ae34f82bf0000000000000000000000007b22f4e0b10b2d3a09f8bddf02988d3ae34f82bf0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12956,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dee8450efd643f7ee615ec6ae8b91bac59c49f1d000000000000000000000000dee8450efd643f7ee615ec6ae8b91bac59c49f1d000000000000000000000000000000000000000000000000000649efc657056400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f532929c0a50b84656394ff58e75c49a95270db0000000000000000000000003f532929c0a50b84656394ff58e75c49a95270db000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12959,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ca4eb9db9d8bc0d7dae95467d51ae72445e0aab1000000000000000000000000000000000000000000000000827b47667778a720,,,1,true +12961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000329934d67e38c93d2e86dff79826649e9bf6462a000000000000000000000000329934d67e38c93d2e86dff79826649e9bf6462a000000000000000000000000000000000000000000000000006681e11de380d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000563ac66ba17d69ea73c0b531556c922c31699474000000000000000000000000563ac66ba17d69ea73c0b531556c922c31699474000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000286e7c578f188cccc123075f7045b183ce85bc05000000000000000000000000286e7c578f188cccc123075f7045b183ce85bc050000000000000000000000000000000000000000000000000061e1da0666727100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12967,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f532929c0a50b84656394ff58e75c49a95270db0000000000000000000000003f532929c0a50b84656394ff58e75c49a95270db000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5277f97e41f39b84b255db419bb2a27936da075000000000000000000000000e5277f97e41f39b84b255db419bb2a27936da075000000000000000000000000000000000000000000000000005b8d2e56074a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c38344d5aeb271938ee11dbb2488a89df4080db1000000000000000000000000c38344d5aeb271938ee11dbb2488a89df4080db10000000000000000000000000000000000000000000000000721f42f9297a84000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x65a1d69c4e12fc7f67ade6a51ebb5a0d3ae97e10bc3d6f29707208bd2818f081,2022-04-27 06:47:33.000 UTC,0,true +12971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d385890bb9beae40d902a890ba04e8d1f87f10cd000000000000000000000000d385890bb9beae40d902a890ba04e8d1f87f10cd00000000000000000000000000000000000000000000000000ad128ddcce0da100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d4326b581615643d70a68f2d2ba0cfdf381c81f0000000000000000000000007d4326b581615643d70a68f2d2ba0cfdf381c81f00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cd387adb134470953881c9a416806d636e7a0150000000000000000000000006cd387adb134470953881c9a416806d636e7a0150000000000000000000000000000000000000000000000000aa51f57014be30d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004c1ecdfae5975ad3c0f91049a7daa0bac20579400000000000000000000000004c1ecdfae5975ad3c0f91049a7daa0bac20579400000000000000000000000000000000000000000000000000432d1c04ec16a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7ce42bf09ad09f696889eb5ea5341946d8fb22f000000000000000000000000b7ce42bf09ad09f696889eb5ea5341946d8fb22f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed20ba69d7977d97a930634beb75424edcceb235000000000000000000000000ed20ba69d7977d97a930634beb75424edcceb23500000000000000000000000000000000000000000000000002c4c8640bd5f30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12978,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e153ba6e7c8d5ff6ce6d5968044ce72cd4ba38fe000000000000000000000000e153ba6e7c8d5ff6ce6d5968044ce72cd4ba38fe00000000000000000000000000000000000000000000000002c1a6acfd69632100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xefe34ced3e361a6bea117829b6dde6f242187114bfce7c061b7dc2b76642e5ed,2021-12-08 09:18:11.000 UTC,0,true +12979,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f84a3d0e725e2712f93e0db9560c603cc645451a000000000000000000000000f84a3d0e725e2712f93e0db9560c603cc645451a000000000000000000000000000000000000000000000000001d598832c7fac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6acaf70c70390dcaab3c5653eac3ac564f0a084000000000000000000000000f6acaf70c70390dcaab3c5653eac3ac564f0a08400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009fb9625e34b3bf2e87e0c45c892fa8299c46422a0000000000000000000000009fb9625e34b3bf2e87e0c45c892fa8299c46422a00000000000000000000000000000000000000000000000003ed6b00276f800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12984,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000333a9bcaa5b9e48d72f43032f99ed54aa572a60d000000000000000000000000333a9bcaa5b9e48d72f43032f99ed54aa572a60d00000000000000000000000000000000000000000000000002bc2042130e102600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xeee240a23618757e9f72e48161344dffea48949a43e2717e25630a80d2eb5483,2021-12-08 09:13:08.000 UTC,0,true +12987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ce1d028626c6a215a4e1619bbe695a564b674aa0000000000000000000000000ce1d028626c6a215a4e1619bbe695a564b674aa00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12988,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008426ff787ecfecaa3754c2034f4c41c87c6ee5600000000000000000000000008426ff787ecfecaa3754c2034f4c41c87c6ee56000000000000000000000000000000000000000000000000001bc1d00fef278100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12989,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c1a54bb8d43d4a3c9f7b034ad673f737b8471c50000000000000000000000001c1a54bb8d43d4a3c9f7b034ad673f737b8471c5000000000000000000000000000000000000000000000000008c1d9439e443d800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9bb8abe860524e9d795e9a793d42ecad9883578433fdcec06f6aa404af765577,2022-06-01 14:38:31.000 UTC,0,true +12992,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000047c5402a052957c9f0f126d956b2bccfb2a33a8400000000000000000000000047c5402a052957c9f0f126d956b2bccfb2a33a840000000000000000000000000000000000000000000000000000000001dfcacd00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +12993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000025b2e51750f4dc6e3fdf0035eab833e50911509000000000000000000000000025b2e51750f4dc6e3fdf0035eab833e509115090000000000000000000000000000000000000000000000000070b3233a814e0400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4f4b95b0977a89402ea0d02cfbb4589fe6bb95b40e9858cb7b1302e68c7d47a9,2021-12-11 19:19:55.000 UTC,0,true +12994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003dde0fd04599c7c0e2a3b25ce6c0beb7804226e40000000000000000000000003dde0fd04599c7c0e2a3b25ce6c0beb7804226e400000000000000000000000000000000000000000000000006ec2af8301ba60300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x074758eed77fa384beb98231576b01fef563828d2f5dd997fd1b0204e3c85fe3,2022-05-09 01:39:54.000 UTC,0,true +12995,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c41bcb170d402c0eb10b29c9f77deeb697d65295000000000000000000000000c41bcb170d402c0eb10b29c9f77deeb697d6529500000000000000000000000000000000000000000000000002c1ded1cbb88c1c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12996,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bb5287127973ea561b6e2ce37eae7e624597a370000000000000000000000004bb5287127973ea561b6e2ce37eae7e624597a37000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +12999,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e3e3320bd3f8c48b334724a037688d9df2e76820000000000000000000000008e3e3320bd3f8c48b334724a037688d9df2e76820000000000000000000000000000000000000000000000000045278bf972730000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13001,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e58ca5494079fb88dd5757af80960a912e753782000000000000000000000000e58ca5494079fb88dd5757af80960a912e753782000000000000000000000000000000000000000000000000007a823029eae10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13003,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f6000000000000000000000000df8979cce6f1534df0a042543a187aaafbdcb671000000000000000000000000df8979cce6f1534df0a042543a187aaafbdcb671000000000000000000000000000000000000000000000000667449c3b49b933400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000820eac4125bace760d0ed89f801887ac0470d1ae000000000000000000000000820eac4125bace760d0ed89f801887ac0470d1ae000000000000000000000000000000000000000000000000004527d391e0160000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13005,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033742965cc48d996b5884dfa574904f35613b2f100000000000000000000000033742965cc48d996b5884dfa574904f35613b2f10000000000000000000000000000000000000000000000000004caa21536dce900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13006,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2ee68b520984c6144ef0ab128ab8e45afc21d8e000000000000000000000000a2ee68b520984c6144ef0ab128ab8e45afc21d8e00000000000000000000000000000000000000000000000000057be319977d2500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13009,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6d8d40e682dd3539a7a4f49f908476cc28516b2000000000000000000000000d6d8d40e682dd3539a7a4f49f908476cc28516b2000000000000000000000000000000000000000000000000001cbbea393d3e8900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dde9eff243e499ad9ba862f30d7ce395cf5fb246000000000000000000000000dde9eff243e499ad9ba862f30d7ce395cf5fb2460000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13012,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092a686623d801fb043d19dddc0e034dad0958f8c00000000000000000000000092a686623d801fb043d19dddc0e034dad0958f8c0000000000000000000000000000000000000000000000000421727f5c881a8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13014,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc150be7d845838183728c8f578b8261044419b6000000000000000000000000bc150be7d845838183728c8f578b8261044419b60000000000000000000000000000000000000000000000000002cb8ed43e748000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13016,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006054c42b96ac2ddfadf3bad28263a6df9411cc190000000000000000000000006054c42b96ac2ddfadf3bad28263a6df9411cc19000000000000000000000000000000000000000000000000016168a1b60a190000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13019,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e392ec084684dcb90fe6912af470ac8b687287a0000000000000000000000004e392ec084684dcb90fe6912af470ac8b687287a000000000000000000000000000000000000000000000000004f6b9f0d6f92b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13020,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7d40515946223afb8e1b241813c36593a609b5c000000000000000000000000b7d40515946223afb8e1b241813c36593a609b5c000000000000000000000000000000000000000000000000002d7e50a571875300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026ce053f2febc4c4c9aafcabfe0b9845e182229300000000000000000000000026ce053f2febc4c4c9aafcabfe0b9845e1822293000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea98b932441cd24f21cc7a633cdb6001208996b5000000000000000000000000ea98b932441cd24f21cc7a633cdb6001208996b5000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c50d3e6cc60a90ab04454efcff722fb4f03077d0000000000000000000000008c50d3e6cc60a90ab04454efcff722fb4f03077d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000bb33da2c8fca1a5d1f5d513a18fb66198759d220000000000000000000000000bb33da2c8fca1a5d1f5d513a18fb66198759d22000000000000000000000000000000000000000000000000000205d10c7cd42c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065d6b31ec9413bf7918bda21ac7db401949fef4e00000000000000000000000065d6b31ec9413bf7918bda21ac7db401949fef4e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6fdf0c64c7f4536fc6776b80a895d770995d1ce000000000000000000000000e6fdf0c64c7f4536fc6776b80a895d770995d1ce000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008916a89d83d9477d774da628e3e7c0b5170c05030000000000000000000000008916a89d83d9477d774da628e3e7c0b5170c0503000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000023ef2693c7792e49ad2cdc5fe3fe910a17ff6c7d00000000000000000000000023ef2693c7792e49ad2cdc5fe3fe910a17ff6c7d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073538c91eff3476c721439eed9c8b4fc239dab9d00000000000000000000000073538c91eff3476c721439eed9c8b4fc239dab9d0000000000000000000000000000000000000000000000000002733276cb110000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13031,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081ba73b26a2d7b22407cd5933607571877d7eb4c00000000000000000000000081ba73b26a2d7b22407cd5933607571877d7eb4c0000000000000000000000000000000000000000000000000004660fd0333ad100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e00ee4f51fcca840afa8e68286127a2a189e8c3a000000000000000000000000e00ee4f51fcca840afa8e68286127a2a189e8c3a000000000000000000000000000000000000000000000000012dfb0cb5e8800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13034,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0c6a569cf9d53dc2af4bab04a7c509afb45b515000000000000000000000000f0c6a569cf9d53dc2af4bab04a7c509afb45b515000000000000000000000000000000000000000000000000000446ae9c00cd3d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3539ed2536160488f3b3b312a137f76550b25b0000000000000000000000000c3539ed2536160488f3b3b312a137f76550b25b00000000000000000000000000000000000000000000000000005c78ee270664900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13036,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000238edb437f8d98c48122964ec6d3ddcbdc3ec217000000000000000000000000238edb437f8d98c48122964ec6d3ddcbdc3ec217000000000000000000000000000000000000000000000000009b00c360c0750000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13037,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d951a35a7b36971e0de44c938c247fa11d053934000000000000000000000000d951a35a7b36971e0de44c938c247fa11d05393400000000000000000000000000000000000000000000000000907a66ef7ccfd700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13038,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e2186f759e919896daec9d2e72d4ccd60141aba0000000000000000000000000e2186f759e919896daec9d2e72d4ccd60141aba0000000000000000000000000000000000000000000000000005f4b5f261f83a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13039,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5f1c2bf387894f4677e8a16b1d526614db4a08f000000000000000000000000d5f1c2bf387894f4677e8a16b1d526614db4a08f00000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13041,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5f1c2bf387894f4677e8a16b1d526614db4a08f000000000000000000000000d5f1c2bf387894f4677e8a16b1d526614db4a08f000000000000000000000000000000000000000000000000001e4e895b60c36c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13044,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cabe296e0cd1e0a12105a8c063a51d54de65cdf0000000000000000000000006cabe296e0cd1e0a12105a8c063a51d54de65cdf000000000000000000000000000000000000000000000000007042553626f42800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13046,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004f47c2887a8f27aeadf4e15e418f311355510bf00000000000000000000000004f47c2887a8f27aeadf4e15e418f311355510bf000000000000000000000000000000000000000000000000005c4af283e97c4800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13047,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c5d969acf5234629fdd4543ef6c43ed557de9830000000000000000000000001c5d969acf5234629fdd4543ef6c43ed557de98300000000000000000000000000000000000000000000000000421499f8d2800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13049,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f91e9f141e252845cfb87dfc98a99dcdd85774f0000000000000000000000003f91e9f141e252845cfb87dfc98a99dcdd85774f0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000133e6693cc630f10cf35c82550b1a11fc450b102000000000000000000000000133e6693cc630f10cf35c82550b1a11fc450b102000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1db96f644be5f64fc090188046e213bb03c8828000000000000000000000000c1db96f644be5f64fc090188046e213bb03c88280000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13052,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006192898cb6e6a6d3c37b0081803a3ede74cf49220000000000000000000000006192898cb6e6a6d3c37b0081803a3ede74cf49220000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7bfe9b78d32469796deb029b2bea3d68773aec4000000000000000000000000e7bfe9b78d32469796deb029b2bea3d68773aec4000000000000000000000000000000000000000000000000058d15e17628000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7f9aaea2c628d508f3a1e63c13b44de19f9c50c1dce090925246f29a5cb58325,2021-11-30 10:45:40.000 UTC,0,true +13054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004344ffd6c8d3188f08671a2ea7eb257afb3137f90000000000000000000000004344ffd6c8d3188f08671a2ea7eb257afb3137f900000000000000000000000000000000000000000000000000036aeabb09bb1200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13055,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b63cd166b1108c7a4ed72d44c4676d46f088e079000000000000000000000000b63cd166b1108c7a4ed72d44c4676d46f088e079000000000000000000000000000000000000000000000000001f7b2e8cfc77db00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13056,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084433ec26d444159c8710858d4eddec0293874ec00000000000000000000000084433ec26d444159c8710858d4eddec0293874ec0000000000000000000000000000000000000000000000000003bbcdfc6248a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2d613d71d32237d9b6d1b979a3efcfd1519b931000000000000000000000000a2d613d71d32237d9b6d1b979a3efcfd1519b93100000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13058,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000646bf56e1d87b353611f456826977a8be2e04f6a000000000000000000000000646bf56e1d87b353611f456826977a8be2e04f6a00000000000000000000000000000000000000000000000000a797e04db537bb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008497daabaafcfb72389a2934e7400d4a8091981a0000000000000000000000008497daabaafcfb72389a2934e7400d4a8091981a0000000000000000000000000000000000000000000000000002602935d6a45b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001139db00d2815f99df958a7fb3a101d7c4bd39280000000000000000000000001139db00d2815f99df958a7fb3a101d7c4bd392800000000000000000000000000000000000000000000000000014fdc3bbb06e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13063,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de98f62c8773ed56c177cc5ecc44f152f040bf9b000000000000000000000000de98f62c8773ed56c177cc5ecc44f152f040bf9b000000000000000000000000000000000000000000000000001ed060be777fc400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13064,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093e0e4c16722a2330c41ed04c1a68490dc730f7500000000000000000000000093e0e4c16722a2330c41ed04c1a68490dc730f7500000000000000000000000000000000000000000000000001600811e33c588000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f35f9e005d2dec0506bf41d618eeeca38c7b1143000000000000000000000000f35f9e005d2dec0506bf41d618eeeca38c7b11430000000000000000000000000000000000000000000000000041b9a6e858400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13068,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ee76180901e2b0edfb0d4b6cfa89b93969c7ad70000000000000000000000005ee76180901e2b0edfb0d4b6cfa89b93969c7ad7000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13071,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000899174e2b29fc08aced0d78c87a42b7b678881b9000000000000000000000000899174e2b29fc08aced0d78c87a42b7b678881b9000000000000000000000000000000000000000000000000000ce6293046a69900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13073,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae4b590b3d79658cd8b304b006011036c18e2f7c000000000000000000000000ae4b590b3d79658cd8b304b006011036c18e2f7c0000000000000000000000000000000000000000000000000071cf06ec4da6be00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x48bec2f0a3c1ba8a94f1d75062ca188db28e6f2deceb3fb7a7325b489cb8ddeb,2022-08-31 20:56:33.000 UTC,0,true +13075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1e95e8fe861230ed8d81235e58e056bde90d18d000000000000000000000000c1e95e8fe861230ed8d81235e58e056bde90d18d000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad268606cec97ef0fa77f74ddbebdcebbbd8d7c4000000000000000000000000ad268606cec97ef0fa77f74ddbebdcebbbd8d7c4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa48407b02024584665e6e1309bf7bc6d71be3e2000000000000000000000000aa48407b02024584665e6e1309bf7bc6d71be3e2000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a50f0dec48d2554d7754c62c2c961198264221b0000000000000000000000002a50f0dec48d2554d7754c62c2c961198264221b00000000000000000000000000000000000000000000000000083de1c644834000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000808a5e3fbee7d2c068140270e4ecb30795b3e282000000000000000000000000808a5e3fbee7d2c068140270e4ecb30795b3e2820000000000000000000000000000000000000000000000000000e0fde331884800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a318ac48a52e44eea6192e3d85dfb832dc3bb9f0000000000000000000000000a318ac48a52e44eea6192e3d85dfb832dc3bb9f00000000000000000000000000000000000000000000000000043bb94c909a8d800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045067be6800ec34b13f2d595d6b1f4efbacd717600000000000000000000000045067be6800ec34b13f2d595d6b1f4efbacd717600000000000000000000000000000000000000000000000000aa72686399513d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13085,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002451b6106d6c1d6ec53a09bab352c9574c82f3210000000000000000000000002451b6106d6c1d6ec53a09bab352c9574c82f321000000000000000000000000000000000000000000000000009a00ea3ae76c7700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ddedd14f66904678b9354af59c6d32639bc45b80000000000000000000000005ddedd14f66904678b9354af59c6d32639bc45b800000000000000000000000000000000000000000000000001f161421c8e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd533307557ac9e1b9ee7fce0256ae909d6aedc8000000000000000000000000dd533307557ac9e1b9ee7fce0256ae909d6aedc800000000000000000000000000000000000000000000000000abe94d2914859f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13091,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4e3642e611553644e6fe0c47f6ed1d8eed66930000000000000000000000000a4e3642e611553644e6fe0c47f6ed1d8eed6693000000000000000000000000000000000000000000000000000254db1c224400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c522fe59a742562da44277d50163488b612458f0000000000000000000000002c522fe59a742562da44277d50163488b612458f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abc0ce4652c76a36a6d79a21a43ab89610d3276f000000000000000000000000abc0ce4652c76a36a6d79a21a43ab89610d3276f00000000000000000000000000000000000000000000000000ab634420f5bb2500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007564a1dff93744ba3f1bfb954fa17d9c81d4b3f30000000000000000000000007564a1dff93744ba3f1bfb954fa17d9c81d4b3f3000000000000000000000000000000000000000000000000006423dea00df34500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb25d1b997cf3cd6e398bce504ef354e9870e3765aa54df1d9de1f2a42cafd7f9,2022-03-20 11:48:25.000 UTC,0,true +13096,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c522fe59a742562da44277d50163488b612458f0000000000000000000000002c522fe59a742562da44277d50163488b612458f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c522fe59a742562da44277d50163488b612458f0000000000000000000000002c522fe59a742562da44277d50163488b612458f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13098,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000764ef8aba8e67af506fa65bad1342bf34571ec3e000000000000000000000000764ef8aba8e67af506fa65bad1342bf34571ec3e0000000000000000000000000000000000000000000000000002df48f6d5b62f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000779e42b6eb275e5f396bb4f47f5dec036281e937000000000000000000000000779e42b6eb275e5f396bb4f47f5dec036281e937000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7a19118187f51f418d5112e72181ae137fa9997000000000000000000000000c7a19118187f51f418d5112e72181ae137fa9997000000000000000000000000000000000000000000000000011493432891830800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13109,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067e77561035265311e6895063926b2f2cec127a200000000000000000000000067e77561035265311e6895063926b2f2cec127a2000000000000000000000000000000000000000000000000042809aa7af3660000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13116,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d38bebf9b178f9c52676ff5f8a44eeecf5f9f1ba000000000000000000000000d38bebf9b178f9c52676ff5f8a44eeecf5f9f1ba0000000000000000000000000000000000000000000000000046cce25e7ff95a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13117,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000495e827e540ca60c93bbac919b4627554211f33f000000000000000000000000495e827e540ca60c93bbac919b4627554211f33f00000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13118,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a20ae6f0e88e6cb7c260d2513c0e337a08f6c52c000000000000000000000000a20ae6f0e88e6cb7c260d2513c0e337a08f6c52c000000000000000000000000000000000000000000000000004486a2393e9d4400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13119,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bffb5c7f47d801ed932539f02f99ffdb9f64ca66000000000000000000000000bffb5c7f47d801ed932539f02f99ffdb9f64ca66000000000000000000000000000000000000000000000000001fc27d2d23028000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbe6790b2221c6bb41af88f398254b9662c01a38000000000000000000000000fbe6790b2221c6bb41af88f398254b9662c01a380000000000000000000000000000000000000000000000000069239bf33e4e2d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df6056a4673eb21fd6c957d84eb390b2a3fc9a6a000000000000000000000000df6056a4673eb21fd6c957d84eb390b2a3fc9a6a000000000000000000000000000000000000000000000000002cc8fdaba2cd0b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d72708e95577f80056fd6a44ec30d644b5a86486000000000000000000000000d72708e95577f80056fd6a44ec30d644b5a86486000000000000000000000000000000000000000000000000112919ff6fb19bb800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa1a5adea3018cdf2198f376d1df8bfcfe84efe35d94e3f6c1d550b2e2cc7a62a,2021-12-12 20:15:36.000 UTC,0,true +13124,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009841d9e166ed96aed9597f879835c6cc15ab46820000000000000000000000009841d9e166ed96aed9597f879835c6cc15ab468200000000000000000000000000000000000000000000000000087502535fa9b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007da37fd05f8a38886fd3d5a2f60474e4d179783e0000000000000000000000007da37fd05f8a38886fd3d5a2f60474e4d179783e00000000000000000000000000000000000000000000000000d96b3c50869d1f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000350a4b5ac6216902e095ef47f3bd5fdc9d387e23000000000000000000000000350a4b5ac6216902e095ef47f3bd5fdc9d387e23000000000000000000000000000000000000000000000000005bea2e85d978aa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d183e645c5f1d36996d03ff730d45cf4bb57ea34000000000000000000000000d183e645c5f1d36996d03ff730d45cf4bb57ea3400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e5745f3136e1023b7db402f2f20d59ece802f4a0000000000000000000000002e5745f3136e1023b7db402f2f20d59ece802f4a000000000000000000000000000000000000000000000000008cb11a91ec792800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13139,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af490b4a10b69d59bad2c95e9bd82223e2fb3386000000000000000000000000af490b4a10b69d59bad2c95e9bd82223e2fb3386000000000000000000000000000000000000000000000000024943f334bf45eb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13141,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef95f81a30b69d18fbc6e44fb33aa37135d0d1d1000000000000000000000000ef95f81a30b69d18fbc6e44fb33aa37135d0d1d1000000000000000000000000000000000000000000000000001739646eabace300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d17fc86bc9d50872df4d2b10d8855e1965a6baca000000000000000000000000d17fc86bc9d50872df4d2b10d8855e1965a6baca000000000000000000000000000000000000000000000000005c5edcbc29000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13150,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001455cf52f007f7e474d3cb7525f4da0ef5313dde0000000000000000000000001455cf52f007f7e474d3cb7525f4da0ef5313dde00000000000000000000000000000000000000000000000000885c14487650c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052a5f7004723e4a6481ef9884ca1120b9c11fcc300000000000000000000000052a5f7004723e4a6481ef9884ca1120b9c11fcc30000000000000000000000000000000000000000000000000166a19531131f6d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13152,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000013f5e3d06576a8aa0b9f72f1b6bf772f1addc80d00000000000000000000000013f5e3d06576a8aa0b9f72f1b6bf772f1addc80d000000000000000000000000000000000000000000000000a9cdbd11830db89b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025366b53f3976bd6f214ece12c2e8b2ad9e392fd00000000000000000000000025366b53f3976bd6f214ece12c2e8b2ad9e392fd0000000000000000000000000000000000000000000000000036eec92749427e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013f5e3d06576a8aa0b9f72f1b6bf772f1addc80d00000000000000000000000013f5e3d06576a8aa0b9f72f1b6bf772f1addc80d000000000000000000000000000000000000000000000000000b2e8714f651a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13158,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ae5edbdd1342ce6acaa48342792315d52e7b0670000000000000000000000003ae5edbdd1342ce6acaa48342792315d52e7b06700000000000000000000000000000000000000000000000003850aba094ccdcd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6a5b8005e342a6a2bca835dbf3808cea6159f0696381359fa3b322ca5c21c7c9,2022-06-28 22:22:51.000 UTC,0,true +13160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010256d931dd2bf74826cfd90b665c836381086be00000000000000000000000010256d931dd2bf74826cfd90b665c836381086be000000000000000000000000000000000000000000000000006138b56748b18b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13161,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000429a748be0acfcf0ddb7d1e7ec4917a4f04f6bbd000000000000000000000000429a748be0acfcf0ddb7d1e7ec4917a4f04f6bbd0000000000000000000000000000000000000000000000000070858df6901aa900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016c4e68b5ea69af57085b5152065100ba24ad71f00000000000000000000000016c4e68b5ea69af57085b5152065100ba24ad71f0000000000000000000000000000000000000000000000000074ab9ade6b130300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x54af3d012d8eb66f5fecb55bc7a9386fe2ff26edce8fcb0e45f9fe66e261b3db,2022-07-20 09:10:13.000 UTC,0,true +13165,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d815e9109f8d9a9f5a21f47351df83134571eb56000000000000000000000000d815e9109f8d9a9f5a21f47351df83134571eb560000000000000000000000000000000000000000000000000061a761a2d89aaa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006fdf6b570a15f4a79f44501a6b56bd2b47ff46100000000000000000000000006fdf6b570a15f4a79f44501a6b56bd2b47ff461000000000000000000000000000000000000000000000000000465d6d4a1c83e300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13167,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055cc224cc1e686304d29ec32fd963c68ea83b17c00000000000000000000000055cc224cc1e686304d29ec32fd963c68ea83b17c00000000000000000000000000000000000000000000000003d2cec7d6b8375300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ddff29c54046bbde55702342a319be7fdb1c5200000000000000000000000002ddff29c54046bbde55702342a319be7fdb1c5200000000000000000000000000000000000000000000000000038b1b12319870000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aed5ef0aa3d1461946257d9198475a8aced910d0000000000000000000000000aed5ef0aa3d1461946257d9198475a8aced910d000000000000000000000000000000000000000000000000001393e20f3158b9a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008bbd6aec68aef08b2d4cdd93b2cffa48b6e103520000000000000000000000008bbd6aec68aef08b2d4cdd93b2cffa48b6e1035200000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035fbea3a80400948e97660cdcc9f82a3f79015a900000000000000000000000035fbea3a80400948e97660cdcc9f82a3f79015a9000000000000000000000000000000000000000000000000001fdb5586bf73df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d4d3fae4d0282fd8a558b5f42ba700974cbfd1a0000000000000000000000005d4d3fae4d0282fd8a558b5f42ba700974cbfd1a0000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13190,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e696871ba5afd8d467755bf698f102cfd08fe777000000000000000000000000e696871ba5afd8d467755bf698f102cfd08fe7770000000000000000000000000000000000000000000000000011d0069b6dd5d300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006766cf760835b6617c77ce6c6caffc5f8af0b1860000000000000000000000006766cf760835b6617c77ce6c6caffc5f8af0b186000000000000000000000000000000000000000000000000002c3fce602f24b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13195,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a40071a4ae125f72522c266b3bf0c300d9ed7aad000000000000000000000000a40071a4ae125f72522c266b3bf0c300d9ed7aad00000000000000000000000000000000000000000000000000417845cfd029a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13198,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2150ec582cb139ef273dc4b62c6a450d0fbd2c6000000000000000000000000d2150ec582cb139ef273dc4b62c6a450d0fbd2c6000000000000000000000000000000000000000000000000006843c0a9e2a2ac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13200,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000facb1846d71b0f8d6e0d142c06380e60d8892d4b000000000000000000000000000000000000000000000024fa1eb1f2433d2ebf,0x2344c02d2893e59b4c8ed76e86c48adbba6412dcb699c08766e776dfa254be4f,2022-03-06 05:00:30.000 UTC,0,true +13201,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5a80e7225c7bf9d3e7002efd6a16398e94d52ed000000000000000000000000a5a80e7225c7bf9d3e7002efd6a16398e94d52ed0000000000000000000000000000000000000000000000000dd279ca89c3169e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004176a257f28ea2ca86c92285b05c9fdde20b59c20000000000000000000000004176a257f28ea2ca86c92285b05c9fdde20b59c20000000000000000000000000000000000000000000000000001526a44e5063900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4354a30064b53382f6653346bd86240d7251555000000000000000000000000a4354a30064b53382f6653346bd86240d72515550000000000000000000000000000000000000000000000000000f9c1fcd0a58300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf84a80e155c35d0bd092b88c4453091447602c6000000000000000000000000cf84a80e155c35d0bd092b88c4453091447602c6000000000000000000000000000000000000000000000000000250d5e5aac18a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001045e946c5469be8763e4127e27dcd1d4778ec600000000000000000000000001045e946c5469be8763e4127e27dcd1d4778ec6000000000000000000000000000000000000000000000000003165699e6ffe9b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000295dbd87c78019fa347ee6a65f2b98b2443550f0000000000000000000000000295dbd87c78019fa347ee6a65f2b98b2443550f0000000000000000000000000000000000000000000000000002b72fb9447f9b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001abe68d9bfc860852a7bb3a5bb67bcf2a248332c0000000000000000000000001abe68d9bfc860852a7bb3a5bb67bcf2a248332c00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13212,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b7c8205c3975497aa9dd464277b94fe33ef26860000000000000000000000006b7c8205c3975497aa9dd464277b94fe33ef26860000000000000000000000000000000000000000000000000022366f192fe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cc150449d10afbc5d2f4b9041afcc8fbebeadf00000000000000000000000006cc150449d10afbc5d2f4b9041afcc8fbebeadf00000000000000000000000000000000000000000000000002a7094858647f89600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4dfd6c05d4387489817c724bf0d80c74374ed173cd8d8e39476c45c9ce84d527,2021-12-11 04:01:30.000 UTC,0,true +13217,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f184492b79f83224d42c29572fb4655d945861e8000000000000000000000000f184492b79f83224d42c29572fb4655d945861e800000000000000000000000000000000000000000000000000d5924624ac300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004694725ca38a50fa08be9852edbaa9c7663f254e0000000000000000000000004694725ca38a50fa08be9852edbaa9c7663f254e000000000000000000000000000000000000000000000000001e5bbfda61238000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13220,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008be55503a932709606c4e8ee242533a6b50894f50000000000000000000000008be55503a932709606c4e8ee242533a6b50894f50000000000000000000000000000000000000000000000000190f7bcee8179a200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ee56188250e9ca6c359c7f636077c699dfc6caa0000000000000000000000003ee56188250e9ca6c359c7f636077c699dfc6caa000000000000000000000000000000000000000000000000000002ba7e218aa000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000940214134c5e8d81dbd5e9015908c697dab5e0dd000000000000000000000000940214134c5e8d81dbd5e9015908c697dab5e0dd00000000000000000000000000000000000000000000000002ea11e32ad5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13224,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000be2849c3a4380af6735bfde32c940554feaa73d40000000000000000000000000000000000000000000000010f4c26725125c637,0xef529bf567756199e8b079dfa523458af5a6e82212fdb13f36c551ffa6bd0168,2022-03-05 13:04:48.000 UTC,0,true +13225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000940214134c5e8d81dbd5e9015908c697dab5e0dd000000000000000000000000940214134c5e8d81dbd5e9015908c697dab5e0dd000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13226,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a0ccc8e62a6b4b689a9031d27ab73157ce851aa8000000000000000000000000a0ccc8e62a6b4b689a9031d27ab73157ce851aa80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13231,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa2cc694b53d6e35d2ac2306ac9a0eb1af546ae0000000000000000000000000fa2cc694b53d6e35d2ac2306ac9a0eb1af546ae00000000000000000000000000000000000000000000000000023e1e5803b400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db743a2f9f47c615bfae18ddc5a51c59a4a70eef000000000000000000000000db743a2f9f47c615bfae18ddc5a51c59a4a70eef00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095078871e27f88b19ee4bfbeb2de5a3e1a0bb19900000000000000000000000095078871e27f88b19ee4bfbeb2de5a3e1a0bb19900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e71bf9d0e63fd3b82c96ed8bfdce4efff53bfdb7000000000000000000000000e71bf9d0e63fd3b82c96ed8bfdce4efff53bfdb7000000000000000000000000000000000000000000000000001cc76f42fbe4c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004900c75345d4e38a47a4b985bdc39f8b3ce919df0000000000000000000000004900c75345d4e38a47a4b985bdc39f8b3ce919df0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b2d18056015fa4d08b8519e201ce741f804ea090000000000000000000000004b2d18056015fa4d08b8519e201ce741f804ea09000000000000000000000000000000000000000000000000008221f07e78fbeb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7e3f0c00fc0e50f9c6d9ffe7c9ee40644fae66b2fd54673221ffaa25f49c9eb6,2022-03-15 05:19:45.000 UTC,0,true +13237,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000891d9211ee72c5c7e188ab5ac9017c3904c54eef000000000000000000000000891d9211ee72c5c7e188ab5ac9017c3904c54eef0000000000000000000000000000000000000000000000000016b2684bf7367000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0ab05f8beba695ea4b724c3a1dc3a290f81a85d000000000000000000000000b0ab05f8beba695ea4b724c3a1dc3a290f81a85d0000000000000000000000000000000000000000000000000c7d713b49da000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13241,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000068f180fcce6836688e9084f035309e29bf0a2095000000000000000000000000c3e5789beec7f018cb983db2a673d603c7168f54000000000000000000000000c3e5789beec7f018cb983db2a673d603c7168f54000000000000000000000000000000000000000000000000000000000009909c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x28cf12971ccaa5515d377eb6a34e08a10038ccab3f60fd1b953cd77a6d9fefb2,2022-02-17 09:06:35.000 UTC,0,true +13245,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007745748f6361a2c3fd37022545e0a484e54c73600000000000000000000000007745748f6361a2c3fd37022545e0a484e54c7360000000000000000000000000000000000000000000000000007c58508723800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x01c00ccd10b24b0ddd804d1fe76962122e4a88cac10b0be7f7021e36d5e2904c,2022-02-05 08:00:59.000 UTC,0,true +13246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001032b93af6dd3d287193bdac7e3e4c70e24c84be0000000000000000000000001032b93af6dd3d287193bdac7e3e4c70e24c84be00000000000000000000000000000000000000000000000000013a5c11ea094100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c179bea549dcac9a6313b2379a4290a8ee281d09000000000000000000000000c179bea549dcac9a6313b2379a4290a8ee281d09000000000000000000000000000000000000000000000000009fdf42f6e4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe90f17cc6428a5d2d940235512472c94c5a5a9d000000000000000000000000fe90f17cc6428a5d2d940235512472c94c5a5a9d0000000000000000000000000000000000000000000000000000a43efab541bc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13252,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d1d093aae2604b2ce57acd3b7355ffac9f081e00000000000000000000000002d1d093aae2604b2ce57acd3b7355ffac9f081e0000000000000000000000000000000000000000000000000000008c9b1046f2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040d8a1d1603d47ff2f3a4b18ff4bbe4b0ad2e7eb00000000000000000000000040d8a1d1603d47ff2f3a4b18ff4bbe4b0ad2e7eb0000000000000000000000000000000000000000000000000000bdf55592d9e500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078f333e5cd98d0eec8257d442151429f013aaa0700000000000000000000000078f333e5cd98d0eec8257d442151429f013aaa070000000000000000000000000000000000000000000000000001d4910d26b84600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13257,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066da918f292d553ed698271e49641d6b1db75b9300000000000000000000000066da918f292d553ed698271e49641d6b1db75b9300000000000000000000000000000000000000000000000000012285861e7c9c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0e61e950e8415fa5f70d8ab2c26654cda80bd30000000000000000000000000a0e61e950e8415fa5f70d8ab2c26654cda80bd30000000000000000000000000000000000000000000000000000147d07f451c0100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13260,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7c2831a3a8d424e8b66f3fbc49d5a68f1a5d724000000000000000000000000b7c2831a3a8d424e8b66f3fbc49d5a68f1a5d724000000000000000000000000000000000000000000000000000035d7bf41739800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13267,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000659ba0b652fb66bb6c1261f5d0aeaeb30fcfec35000000000000000000000000659ba0b652fb66bb6c1261f5d0aeaeb30fcfec35000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004103d6215ed19eb868a16eaff7baabd82dbb9ace0000000000000000000000004103d6215ed19eb868a16eaff7baabd82dbb9ace00000000000000000000000000000000000000000000000006ecb7c503d4cb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d1d2db319ac20113dc1e816c62b38fdb57b72f80000000000000000000000005d1d2db319ac20113dc1e816c62b38fdb57b72f800000000000000000000000000000000000000000000000000018ea8d93cc8c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13271,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e595b6bb4e3bf27ebea22c3c52133126556ad17a000000000000000000000000e595b6bb4e3bf27ebea22c3c52133126556ad17a00000000000000000000000000000000000000000000000000d05f1709d5a57000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000684fb5d8b3611469e72bdf1282860b252e51c1f7000000000000000000000000684fb5d8b3611469e72bdf1282860b252e51c1f700000000000000000000000000000000000000000000000000058453f03244dd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13273,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d0dd373463e787112850e00af51125ec418b4af0000000000000000000000000d0dd373463e787112850e00af51125ec418b4af000000000000000000000000000000000000000000000000000502d630bd9fe800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a7de19aa01cec13a7b3b930d068c03f6ee83ac90000000000000000000000003a7de19aa01cec13a7b3b930d068c03f6ee83ac900000000000000000000000000000000000000000000000000003da0af5fc77600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005faa22b10b055441fdc0fe929d0b3de316a15c1e0000000000000000000000005faa22b10b055441fdc0fe929d0b3de316a15c1e000000000000000000000000000000000000000000000000000000a0fcb6cec800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13278,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000605e552947868d1ffa35188308153da83978d4c9000000000000000000000000605e552947868d1ffa35188308153da83978d4c900000000000000000000000000000000000000000000000000019b396be7c25400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13279,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000088eeb79b0cce7000142bbb474562663b4ab623db00000000000000000000000088eeb79b0cce7000142bbb474562663b4ab623db0000000000000000000000000000000000000000000000003782dace9d9007af00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xf0735a6bd45ce5faad47589ba49edf81989bca306a7a803775c08880a99ddf30,2022-03-12 11:19:28.000 UTC,0,true +13280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efbd2c4355ca73a236062d2650e503ba0f443d5f000000000000000000000000efbd2c4355ca73a236062d2650e503ba0f443d5f000000000000000000000000000000000000000000000000006f01b697f0c1c800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a71d1e79402ef838c626b4ae2d050c356448aa9d000000000000000000000000a71d1e79402ef838c626b4ae2d050c356448aa9d000000000000000000000000000000000000000000000000003c150a981ee5e300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8961caf32692fe14b4b2d0fb89aa7675910ccd4000000000000000000000000b8961caf32692fe14b4b2d0fb89aa7675910ccd4000000000000000000000000000000000000000000000000005e0c51f2c7f9cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13285,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf09dae602adae0c48de9ef743060696132f6a92000000000000000000000000bf09dae602adae0c48de9ef743060696132f6a92000000000000000000000000000000000000000000000000015181ff25a9800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bb550d3cfdb13d5feec42ed3d20e0b46e1994400000000000000000000000006bb550d3cfdb13d5feec42ed3d20e0b46e199440000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x16921de3849672735dcd47b62934718baa593eddc7eb3b421e998fcca7cb8148,2021-12-22 17:00:50.000 UTC,0,true +13291,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bb550d3cfdb13d5feec42ed3d20e0b46e1994400000000000000000000000006bb550d3cfdb13d5feec42ed3d20e0b46e199440000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x712327294533d025b3447e6528aee85388965abf5fc4c5957245599d06ddbf19,2021-12-22 16:57:35.000 UTC,0,true +13292,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007a64826e5798109d75b519010bcc833ee80d99d00000000000000000000000007a64826e5798109d75b519010bcc833ee80d99d0000000000000000000000000000000000000000000000000001a7a3204aee0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13295,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088ec95ad2fd42866af4e2e5cc14a80f5ba2d83c200000000000000000000000088ec95ad2fd42866af4e2e5cc14a80f5ba2d83c2000000000000000000000000000000000000000000000000015492d1e7d5ed4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13298,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f9ca61b2c3938d3c5ec8fa669622240a7a0cb3160000000000000000000000000000000000000000000000070c1cc73b00c80000,0xc38cc1108ec566b0b0c331c890b3d0fae24b384ff76a38f2df2c71a48d8527f1,2021-11-29 01:01:56.000 UTC,0,true +13301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007fc961737ce37fcb682935ccff859abdf009505c0000000000000000000000007fc961737ce37fcb682935ccff859abdf009505c00000000000000000000000000000000000000000000000000014f6bb3ff059700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000b35a8ef31e9f8c2002f5925c6e978e7570bf2d92000000000000000000000000b35a8ef31e9f8c2002f5925c6e978e7570bf2d9200000000000000000000000000000000000000000000000000000000076a3c9100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13304,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de1d2cf646bfb8f3148364b9419cefc0f376226a000000000000000000000000de1d2cf646bfb8f3148364b9419cefc0f376226a0000000000000000000000000000000000000000000000000001afd133fdb00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5b4c2a4d2d0706b61103769faaaf530d57de124000000000000000000000000c5b4c2a4d2d0706b61103769faaaf530d57de12400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13307,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f844c1229095b11c191adf0c545f63a320576d90000000000000000000000000f844c1229095b11c191adf0c545f63a320576d9000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13308,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de54074b547f325b9ea169273ade267192ad88fb000000000000000000000000de54074b547f325b9ea169273ade267192ad88fb00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13311,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8515527652ff795574cb9dc3f506ba336d261d2000000000000000000000000a8515527652ff795574cb9dc3f506ba336d261d200000000000000000000000000000000000000000000000000abb1a0c9385b6f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13312,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000982a1fde980e291e921fad931f2ae73d33d246ae000000000000000000000000982a1fde980e291e921fad931f2ae73d33d246ae00000000000000000000000000000000000000000000000000e7a3620b7690ec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7da93384f145c60be24459761d54b6cf4769b00e88118685ad56f164b45012a6,2022-05-06 09:44:24.000 UTC,0,true +13313,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8b5705547cdd26b9095f04bc431e1e8893e068c000000000000000000000000e8b5705547cdd26b9095f04bc431e1e8893e068c00000000000000000000000000000000000000000000000000abaa0dc6acfacc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13314,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e585b5499586d7dd17f410367a8d17e301dee7ee000000000000000000000000e585b5499586d7dd17f410367a8d17e301dee7ee00000000000000000000000000000000000000000000000000ab3c7440e1b6d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13315,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c07dfc765102bf07b6ade961b47f6ac0cd8461b0000000000000000000000003c07dfc765102bf07b6ade961b47f6ac0cd8461b000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13316,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e449afed04b9609e26609f5126b740f9edee5f00000000000000000000000000e449afed04b9609e26609f5126b740f9edee5f000000000000000000000000000000000000000000000000000aaf5e80a96f90100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de5e235808e2a1b3dd7b9e7c86383f48eda706e1000000000000000000000000de5e235808e2a1b3dd7b9e7c86383f48eda706e100000000000000000000000000000000000000000000000000abc38b40eb68d300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f0229b91244e37161c7974acd35e880ac6323060000000000000000000000002f0229b91244e37161c7974acd35e880ac63230600000000000000000000000000000000000000000000000000ab49ad6dfe92b700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13319,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000648257704c8cc4d76c8bfeb1a900b3683368357a000000000000000000000000648257704c8cc4d76c8bfeb1a900b3683368357a00000000000000000000000000000000000000000000000000aa3520ba15ee7100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13321,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b768b2927175409da5254bf4187f77cba72ecec1000000000000000000000000b768b2927175409da5254bf4187f77cba72ecec10000000000000000000000000000000000000000000000000321b3278859810d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x986a2c16f6b8ccba37cdf8f84e5cac2b2c8c8a4244214ac6ff9448035eac59a0,2022-03-30 13:51:07.000 UTC,0,true +13323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091b4210b7a1cbc503b192a130b10dbe8c4929c7600000000000000000000000091b4210b7a1cbc503b192a130b10dbe8c4929c7600000000000000000000000000000000000000000000000000aa900c7c62133400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13326,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000add8b3a8b51d978b8266326f3b4904e132668403000000000000000000000000add8b3a8b51d978b8266326f3b4904e132668403000000000000000000000000000000000000000000000000000939131c88457f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13327,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009c5cc0954a7de04d108b4571991986c1ce96c94d0000000000000000000000009c5cc0954a7de04d108b4571991986c1ce96c94d00000000000000000000000000000000000000000000000000a20ce2555d97c200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000672b370abce91f9df9c70819a160dff5bea4cfb3000000000000000000000000672b370abce91f9df9c70819a160dff5bea4cfb3000000000000000000000000000000000000000000000000008b1cc6bf538e9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13332,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae8e2b4abb13de393515ef5abad7e35a2b11ba6d000000000000000000000000ae8e2b4abb13de393515ef5abad7e35a2b11ba6d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc0c1d270f3f52c3859f4b14b1367dcec26640bec4e83025a26588c314a719808,2022-05-25 06:34:53.000 UTC,0,true +13333,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028523ae8fc1ef411669a4f284d34f2030434d38a00000000000000000000000028523ae8fc1ef411669a4f284d34f2030434d38a00000000000000000000000000000000000000000000000002b9bb89d5afdb2800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13336,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009658d095406b17b45b3109c7b8b57cfa641a2e150000000000000000000000009658d095406b17b45b3109c7b8b57cfa641a2e1500000000000000000000000000000000000000000000000001586d349ec3667100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13338,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c73567e09e1774f6e9e5f1f9de7fd0c3c4ce94fa000000000000000000000000c73567e09e1774f6e9e5f1f9de7fd0c3c4ce94fa00000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0efeebaef875186d8b250aa69377aa8ccc93283000000000000000000000000b0efeebaef875186d8b250aa69377aa8ccc93283000000000000000000000000000000000000000000000000003feb7a8302056f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4ce5470a3854a2840e970d51de7810e65417b71000000000000000000000000a4ce5470a3854a2840e970d51de7810e65417b71000000000000000000000000000000000000000000000000003b5602554d95c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000366bffc83477dbcdd5670859cb7f59081a53ea4c000000000000000000000000366bffc83477dbcdd5670859cb7f59081a53ea4c0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13347,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000d7c96322a62573b509ee0b1266e7aa713662c130000000000000000000000000000000000000000000000004563918244f40000,,,1,true +13351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002453a37cb6598b02631dbef572bd4848c119c8ed0000000000000000000000002453a37cb6598b02631dbef572bd4848c119c8ed00000000000000000000000000000000000000000000000002a19bad6fcfea7b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000123fb8874214032c05c661677004f36ad5569aa3000000000000000000000000123fb8874214032c05c661677004f36ad5569aa300000000000000000000000000000000000000000000000001518e3a83bf1fbc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003c71ab47ad0263f57f274e1094a50b74c10f93400000000000000000000000003c71ab47ad0263f57f274e1094a50b74c10f93400000000000000000000000000000000000000000000000006df75a00e817cf800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x99deffe6badcadf10238d723b80da24a5323c43a4a1f2ec42a0e10117c695dbf,2022-04-27 01:09:30.000 UTC,0,true +13355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007783b43770587a394d410c5330b25937f311acbd0000000000000000000000007783b43770587a394d410c5330b25937f311acbd00000000000000000000000000000000000000000000000006e5cf238f762f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13356,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0d91a3e9266a25fafa978d29fdf692d5aa79bae000000000000000000000000e0d91a3e9266a25fafa978d29fdf692d5aa79bae00000000000000000000000000000000000000000000000000a54dd2972c6c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13357,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a550215d922af5af685461887190cbe1cb7c807100000000000000000000000000000000000000000000004af91435611c752327,,,1,true +13361,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006740888dad1a16931a1dcdd16538c9edd8c5ade00000000000000000000000006740888dad1a16931a1dcdd16538c9edd8c5ade000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13363,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000041dae192e88ca982f4db6d0fc80a64be74002b8000000000000000000000000041dae192e88ca982f4db6d0fc80a64be74002b80000000000000000000000000000000000000000000000000000000003db974900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13366,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094fa0e817004844f358d5aadaac45b61d444e6cb00000000000000000000000094fa0e817004844f358d5aadaac45b61d444e6cb0000000000000000000000000000000000000000000000000133342fdcd36b7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000000d0eb908e66917e2da851eb837977eca176bf10d0000000000000000000000000d0eb908e66917e2da851eb837977eca176bf10d0000000000000000000000000000000000000000000000000000000001fd9f0400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d0eb908e66917e2da851eb837977eca176bf10d0000000000000000000000000d0eb908e66917e2da851eb837977eca176bf10d000000000000000000000000000000000000000000000000001b75bb22a8a70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b62e0312d6a6790b07f3a87b9ec339f7d8d47a60000000000000000000000002b62e0312d6a6790b07f3a87b9ec339f7d8d47a600000000000000000000000000000000000000000000000000318544ec44921300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000068dcff0b1175b0199f3ca65ace43cd82fb703ce200000000000000000000000068dcff0b1175b0199f3ca65ace43cd82fb703ce200000000000000000000000000000000000000000000000000000000016664b400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13371,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e56e30a76f08e67a72dd9f360e422b9fa48a70c7000000000000000000000000e56e30a76f08e67a72dd9f360e422b9fa48a70c7000000000000000000000000000000000000000000000000002d5596036831ae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13375,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d7c1e4e4de7219a7adfe0a0843b785917411847400000000000000000000000000000000000000000000000038e62046fb1a0000,,,1,true +13376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e65bc9d90619e0f98fdb6bda851aaa19e054355a000000000000000000000000e65bc9d90619e0f98fdb6bda851aaa19e054355a0000000000000000000000000000000000000000000000000003328b944c400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13380,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000083ac17696774768c26e48a98d115b5eccbf81a8600000000000000000000000000000000000000000000000b78c1217cd03784a9,0xbac2fd97ec5d4fd61f6f2eb8f4aaa974dd5ea0ec1936897cb57d2583091b47be,2022-01-07 22:11:22.000 UTC,0,true +13381,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000014bd7ca23817d50faecbd0cc09701a1246cbce8a00000000000000000000000014bd7ca23817d50faecbd0cc09701a1246cbce8a000000000000000000000000000000000000000000000001dd6f3c536656d31a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13382,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014bd7ca23817d50faecbd0cc09701a1246cbce8a00000000000000000000000014bd7ca23817d50faecbd0cc09701a1246cbce8a0000000000000000000000000000000000000000000000000077d19e62dd146e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095dd74037b29fa89d2fbec452579b47e634503db00000000000000000000000095dd74037b29fa89d2fbec452579b47e634503db000000000000000000000000000000000000000000000000005edcd80fb5f5fa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d95e0e2c3b10b361f5c1f624620a26fa2a07d760000000000000000000000000d95e0e2c3b10b361f5c1f624620a26fa2a07d760000000000000000000000000000000000000000000000000002e8ca081fa230000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093f16d737e50c3aa47f9406b3cf79e0293f7b1c400000000000000000000000093f16d737e50c3aa47f9406b3cf79e0293f7b1c4000000000000000000000000000000000000000000000000002e9145b0b3460000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054ec0f31378c8fef5abd9ff0be137f5a1fe765ae00000000000000000000000054ec0f31378c8fef5abd9ff0be137f5a1fe765ae000000000000000000000000000000000000000000000000025bf6196bd1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000706d32a171e4f7b32dbd9dd3d4d726122c6fc3b9000000000000000000000000706d32a171e4f7b32dbd9dd3d4d726122c6fc3b9000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f60000000000000000000000000133d7b8e24d11a9b4c511e31d3ee94ef3c9a0e70000000000000000000000000133d7b8e24d11a9b4c511e31d3ee94ef3c9a0e7000000000000000000000000000000000000000000000000467b75af1884132a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13406,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004257bc72ea94e5f7459190dee12236ee7ee0203c00000000000000000000000000000000000000000000002ac5861dc2e0019aad,0xa02e678afd7c1fc85484a8cf4b61f90e59aa2fee75d2039e8d8234b0e17e6a37,2021-11-29 10:44:43.000 UTC,0,true +13408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f60000000000000000000000002f4cc285bc316ba1ff2f1a71761839629c19d5a20000000000000000000000002f4cc285bc316ba1ff2f1a71761839629c19d5a2000000000000000000000000000000000000000000000000086b8baf635e393e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13414,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e882c4b9d59ab62c212c00db7aa9aefa3634ba30000000000000000000000009e882c4b9d59ab62c212c00db7aa9aefa3634ba300000000000000000000000000000000000000000000000003311fc80a57000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec5b986c5c531d41ec6e2391a0d253fc3588628e000000000000000000000000ec5b986c5c531d41ec6e2391a0d253fc3588628e00000000000000000000000000000000000000000000000000860a11acad7ac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13418,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000085622bc4f29911f6a8cbc2135c7c21e8f32c283000000000000000000000000085622bc4f29911f6a8cbc2135c7c21e8f32c28300000000000000000000000000000000000000000000000001b70fa471e588fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13424,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000060408fd5e5ed4c9824802e290c152c3023bbeaf600000000000000000000000060408fd5e5ed4c9824802e290c152c3023bbeaf60000000000000000000000000000000000000000000000063bf212b431ec000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13427,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ca9212b3b9640dcbe866f86b8601e5beb6666480000000000000000000000007ca9212b3b9640dcbe866f86b8601e5beb666648000000000000000000000000000000000000000000000000002da48aab845c8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13429,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000fa5d04a5058d7f55cfd75487b62278421398f66b000000000000000000000000fa5d04a5058d7f55cfd75487b62278421398f66b000000000000000000000000000000000000000000000003cf40d8656828d2a300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c21a0e64a7b39a3d41dd17942d74e63c0bb6ae12000000000000000000000000c21a0e64a7b39a3d41dd17942d74e63c0bb6ae120000000000000000000000000000000000000000000000000853a0d2313c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6aee6ec5a83010859e350cc07b16210a4641cbd000000000000000000000000e6aee6ec5a83010859e350cc07b16210a4641cbd000000000000000000000000000000000000000000000000002b49c61940db9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a734bf1acceaf44049898315f012fa240489d909000000000000000000000000a734bf1acceaf44049898315f012fa240489d90900000000000000000000000000000000000000000000000002ba2e5c07d9e82e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13434,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d13e1c8b0315fbaa4f385ee44c6444c474c20f00000000000000000000000003d13e1c8b0315fbaa4f385ee44c6444c474c20f0000000000000000000000000000000000000000000000000000df8b16cca2e0b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13436,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c7db50bfb824c4e60d107c2892313b127739b6fd000000000000000000000000c7db50bfb824c4e60d107c2892313b127739b6fd0000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a699720418f612558e2827bf68631686e9d1095e000000000000000000000000a699720418f612558e2827bf68631686e9d1095e000000000000000000000000000000000000000000000000015feb298de19d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7da9b0677d17341ada49902e9c0d5f4f11dfb3e000000000000000000000000d7da9b0677d17341ada49902e9c0d5f4f11dfb3e000000000000000000000000000000000000000000000000003b508d54a33e8200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13441,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f90f56afa1dae825db57fc305b2f8f1ccf337531000000000000000000000000f90f56afa1dae825db57fc305b2f8f1ccf337531000000000000000000000000000000000000000000000000003a43b68e51000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x34f0eaf76174149f8b53a0f9f33ce91cae044fc7f360a576ccafd9ea08836519,2022-05-18 05:42:46.000 UTC,0,true +13442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092c0689fe3c559657e5e3409dcb5eb5eab76f2b800000000000000000000000092c0689fe3c559657e5e3409dcb5eb5eab76f2b8000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13443,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7db50bfb824c4e60d107c2892313b127739b6fd000000000000000000000000c7db50bfb824c4e60d107c2892313b127739b6fd0000000000000000000000000000000000000000000000000008632c28b9737500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c6bee58695595ae32288b5afcbee1d4c030f62e5000000000000000000000000c6bee58695595ae32288b5afcbee1d4c030f62e50000000000000000000000000000000000000000000000000006959dd3aaf74100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9590b6019c8e52718b85e7caa2bb3318be10f44000000000000000000000000d9590b6019c8e52718b85e7caa2bb3318be10f44000000000000000000000000000000000000000000000000000965dbce70760600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089c3d632031e77667bd8d752cea80bb185354df100000000000000000000000089c3d632031e77667bd8d752cea80bb185354df1000000000000000000000000000000000000000000000000000a76577aa35cb400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093ccaa2c29ea8b79899400c5a037f18bb9b2a60700000000000000000000000093ccaa2c29ea8b79899400c5a037f18bb9b2a60700000000000000000000000000000000000000000000000000091b93a4bba8fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007761162e5d5e7143fafca23c76b1e91724f130090000000000000000000000007761162e5d5e7143fafca23c76b1e91724f130090000000000000000000000000000000000000000000000000009ed6c2fc9a8b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13450,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e495b919885d93a2c16fc7ae9439d178377cf94d000000000000000000000000e495b919885d93a2c16fc7ae9439d178377cf94d0000000000000000000000000000000000000000000000000005a5660ff85fc700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000573c5c8d84a892217ecbce14226394beb8329c40000000000000000000000000573c5c8d84a892217ecbce14226394beb8329c4000000000000000000000000000000000000000000000000009bc7c76f30f95100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe3116290c91802b53713f256af60e804f7ed999536c8b4fbc8dab54fb5b986a7,2021-12-26 11:49:23.000 UTC,0,true +13452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7bf83b30acb185654630f04612d71a84786e6cc000000000000000000000000d7bf83b30acb185654630f04612d71a84786e6cc000000000000000000000000000000000000000000000000000aac369e1e001900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028d4bd86a22befc00bfbb4f94950a4ac0b10fd5b00000000000000000000000028d4bd86a22befc00bfbb4f94950a4ac0b10fd5b000000000000000000000000000000000000000000000000000b663933acbf5a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13458,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fbd43b140b9b84cfc05ef7b0afe930a58a1e8f60000000000000000000000005fbd43b140b9b84cfc05ef7b0afe930a58a1e8f600000000000000000000000000000000000000000000000000580a6871ec193100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ebf5049401a882c20690ec3e9dfa78f6ff93cadc000000000000000000000000ebf5049401a882c20690ec3e9dfa78f6ff93cadc000000000000000000000000000000000000000000000000004945df1084304000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000634dc398000d102cd78c8a707bef9f9813464983000000000000000000000000634dc398000d102cd78c8a707bef9f9813464983000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13461,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b30a35bb3b3830626c97f0ea9b123a3d9439c468000000000000000000000000b30a35bb3b3830626c97f0ea9b123a3d9439c4680000000000000000000000000000000000000000000000000d98cc4ff03f280200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f90cae83a037e3e7600b842898f52fa87239d3a2000000000000000000000000f90cae83a037e3e7600b842898f52fa87239d3a20000000000000000000000000000000000000000000000000009dd503a02a7e800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c456f81419a4c0ab25d33677640715f62fe8462e000000000000000000000000c456f81419a4c0ab25d33677640715f62fe8462e0000000000000000000000000000000000000000000000000044e6f16e845e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c83dff7353a75e5489f98a64e08619a10b796081000000000000000000000000c83dff7353a75e5489f98a64e08619a10b796081000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a74e944fba53828d1f63ae3db91fdd966d5ae0d0000000000000000000000002a74e944fba53828d1f63ae3db91fdd966d5ae0d0000000000000000000000000000000000000000000000000009c826fea8c1dd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009418533015471c727d4aa4d8fd1effc1433fa6cd0000000000000000000000009418533015471c727d4aa4d8fd1effc1433fa6cd00000000000000000000000000000000000000000000000000062857ad59620a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d00ab9ca2447832d570014835567392a47fb5568000000000000000000000000d00ab9ca2447832d570014835567392a47fb55680000000000000000000000000000000000000000000000000098f6677f4c2b0d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d0d8bf8e14a6b3237195b8d28a19a07252c68850000000000000000000000007d0d8bf8e14a6b3237195b8d28a19a07252c6885000000000000000000000000000000000000000000000000014ccee5b47dc5c500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000deb0488784f01d0bf118b536e4b7ad48357f8c40000000000000000000000000deb0488784f01d0bf118b536e4b7ad48357f8c400000000000000000000000000000000000000000000000000162fe12eea018a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000726ad4bdaf04ed2eb26c43881f8d8648f7abc047000000000000000000000000726ad4bdaf04ed2eb26c43881f8d8648f7abc047000000000000000000000000000000000000000000000000014f985e39f5fe9200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff3c4e561df2b1573c367707794b5df25425ac6e000000000000000000000000ff3c4e561df2b1573c367707794b5df25425ac6e000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f270fa131fea5d7e1798672f87a9da4e01b399ef000000000000000000000000f270fa131fea5d7e1798672f87a9da4e01b399ef000000000000000000000000000000000000000000000000046d989cbeec002600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000c7d2c67bc38b0e8b15b632c19ef629022fd56543000000000000000000000000c7d2c67bc38b0e8b15b632c19ef629022fd565430000000000000000000000000000000000000000000000001b91f57b06ea36e500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x8117b77e95158c049fd22e71181d8557e1b663279ef08725b305c62e88222462,2022-02-05 09:37:55.000 UTC,0,true +13478,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d696e4aa7fb6e9d828ac804bef9baeee136ed40c000000000000000000000000d696e4aa7fb6e9d828ac804bef9baeee136ed40c00000000000000000000000000000000000000000000000000a31e78e853832400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13479,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b9b5f9c69aa245db149a6de6dadd3427da1fbbf0000000000000000000000005b9b5f9c69aa245db149a6de6dadd3427da1fbbf0000000000000000000000000000000000000000000000000026896f771f09ca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13480,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a13f3599ff620500f360dc6185ad30f625ebfc38000000000000000000000000a13f3599ff620500f360dc6185ad30f625ebfc38000000000000000000000000000000000000000000000000018bc24f13e462d300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13486,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034a79f99185794408d3227bce62fff0adb36dc9600000000000000000000000034a79f99185794408d3227bce62fff0adb36dc9600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13489,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034be96d237998af9ec63986a266a81937ca208c200000000000000000000000034be96d237998af9ec63986a266a81937ca208c200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13490,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009d374d3d5f9ce1f388994c98d7279bd1b4f87b330000000000000000000000000000000000000000000000000de0b6b3a7640000,,,1,true +13491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e34c4cf29f9e06f4186dccd1853c6f0a17b54065000000000000000000000000e34c4cf29f9e06f4186dccd1853c6f0a17b5406500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000463892108a1b2503dfb0c335893af1858bbc8777000000000000000000000000463892108a1b2503dfb0c335893af1858bbc877700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13493,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000554047f6e0120ed3738e994b89d2a06462919e60000000000000000000000000554047f6e0120ed3738e994b89d2a06462919e6000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ede75dbcc5e9896126518a7741650aadb7dbe539000000000000000000000000ede75dbcc5e9896126518a7741650aadb7dbe53900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e4ee46cbecd6d340401d35b72d64b1ac9b63e3c0000000000000000000000002e4ee46cbecd6d340401d35b72d64b1ac9b63e3c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006eec9ed388f1ba3b1c4b08f2737149e4cbe3af4f0000000000000000000000006eec9ed388f1ba3b1c4b08f2737149e4cbe3af4f00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13497,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c620f148d7caec6073691d78f046d72ee099ad00000000000000000000000001c620f148d7caec6073691d78f046d72ee099ad000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a3b89800f47cbad213a496c96791a7ccb05eeb80000000000000000000000005a3b89800f47cbad213a496c96791a7ccb05eeb800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d79d6f19c2c10fa1ad06eba12a72e65905a99c01000000000000000000000000d79d6f19c2c10fa1ad06eba12a72e65905a99c0100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbe6790b2221c6bb41af88f398254b9662c01a38000000000000000000000000fbe6790b2221c6bb41af88f398254b9662c01a38000000000000000000000000000000000000000000000000003f8967058c84e700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b6f6d8131b159ea36fd4eabd6d08ae3f6f0ba190000000000000000000000000b6f6d8131b159ea36fd4eabd6d08ae3f6f0ba1900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13502,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dff53ba0007507ccaaf30264b8212db37a84b6b4000000000000000000000000dff53ba0007507ccaaf30264b8212db37a84b6b400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13503,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095537634202c31521315078bc1b8837e1da7269900000000000000000000000095537634202c31521315078bc1b8837e1da7269900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ce7a5f00f7d83126520cb2916d16489b495169b0000000000000000000000009ce7a5f00f7d83126520cb2916d16489b495169b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000783b4926b83d666d6897b96f3049428b08343890000000000000000000000000783b4926b83d666d6897b96f3049428b083438900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b542568f06eef54ce03203fce472481b7d3cf7b0000000000000000000000001b542568f06eef54ce03203fce472481b7d3cf7b00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13507,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ab56fa34d26f674939b2947ea25d8a6097655970000000000000000000000006ab56fa34d26f674939b2947ea25d8a60976559700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13508,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041a083bab355451b1a4e4b5366a72271ce849c5100000000000000000000000041a083bab355451b1a4e4b5366a72271ce849c5100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13509,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd4c9130c75659bd84ab5cb27fcb0663b78c006c000000000000000000000000bd4c9130c75659bd84ab5cb27fcb0663b78c006c000000000000000000000000000000000000000000000000015c2a7b13fd000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6e315d113a0bb37986d581cc71d663a0e9b69ee000000000000000000000000f6e315d113a0bb37986d581cc71d663a0e9b69ee00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13511,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000c50a6f05500c941b080c56ea3764e6a920ad92f2000000000000000000000000c50a6f05500c941b080c56ea3764e6a920ad92f2000000000000000000000000000000000000000000000000000000001dcd650000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13512,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dde199991ad1a917be29b92618dbb1daa464372e000000000000000000000000dde199991ad1a917be29b92618dbb1daa464372e0000000000000000000000000000000000000000000000000067e0609591300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1425a9f1c6798ccc9ebc51b76b177a118c8bda0c4b5e6d09868d3f91407b4b17,2022-05-21 05:56:16.000 UTC,0,true +13515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc9a5cdeff2d022a9e910c4c1c7c78e6be666a36000000000000000000000000cc9a5cdeff2d022a9e910c4c1c7c78e6be666a360000000000000000000000000000000000000000000000000068f0e3a147fc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa1ddd0810574ab4ac5fa2367fd658f7b25b68671d0cddbf624d78fd81ba0628f,2022-05-22 18:42:06.000 UTC,0,true +13516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003734a41abe1cccbb4519fe361e7c5ce0dfe879f80000000000000000000000003734a41abe1cccbb4519fe361e7c5ce0dfe879f800000000000000000000000000000000000000000000000001f161421c8e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000308eb3dcc77391d02941944909dc85d23af03220000000000000000000000000308eb3dcc77391d02941944909dc85d23af03220000000000000000000000000000000000000000000000000004bfbcf4ff0609700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc3623a2f038be5deae8c09768729ef74acfd36d66a065052f92f5c99326eee63,2022-03-12 17:38:49.000 UTC,0,true +13523,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f030b74371167d3b71cf3214e749b0d1814c0490000000000000000000000006f030b74371167d3b71cf3214e749b0d1814c0490000000000000000000000000000000000000000000000000074fd5dd242dc9400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x12949014e04b39fa458a2d59f92163e811d1d671378ef8a973e5352d0d0ed41e,2021-12-09 00:40:57.000 UTC,0,true +13526,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a30a5c6554fdc4b2a23e7f87150a192786b30b20000000000000000000000005a30a5c6554fdc4b2a23e7f87150a192786b30b200000000000000000000000000000000000000000000000000793a22bb8f020000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13527,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008cc5f52ca537df691f15f5f88a0ae7f95bdd72060000000000000000000000008cc5f52ca537df691f15f5f88a0ae7f95bdd7206000000000000000000000000000000000000000000000000000d7f72f39764c500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df8ce52f7a50c1ba79d778717d48357df4d9150e000000000000000000000000df8ce52f7a50c1ba79d778717d48357df4d9150e0000000000000000000000000000000000000000000000000072924212078b8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13529,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000049a1d052b0b3a5324ddfb4f4d374313edeea0d3700000000000000000000000049a1d052b0b3a5324ddfb4f4d374313edeea0d37000000000000000000000000000000000000000000000003c932de100869e29300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e28d0e01d8f1501600b0f19bc142a6546626d605000000000000000000000000e28d0e01d8f1501600b0f19bc142a6546626d6050000000000000000000000000000000000000000000000000036fc685780307900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13532,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eec03bc36752a1e991d5df6022778a84bab9ac49000000000000000000000000eec03bc36752a1e991d5df6022778a84bab9ac490000000000000000000000000000000000000000000000000022766a152044dd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0c18bf666f37cd37ed471f7db69e0c7fe11ebdfd8441e6a22c61bc682906b83b,2022-03-14 12:33:34.000 UTC,0,true +13533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000521f8c295b140d310bb8aee6bd9e008797953524000000000000000000000000521f8c295b140d310bb8aee6bd9e0087979535240000000000000000000000000000000000000000000000000061b3347238707700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x68284e4de4a9d1aa534b7415aa77c0226cf31012817a9d7c87d6a0d8fbc530ab,2022-08-01 00:37:53.000 UTC,0,true +13535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f119103ae79e98ecc7791e3b4a765f303d7d7da1000000000000000000000000f119103ae79e98ecc7791e3b4a765f303d7d7da1000000000000000000000000000000000000000000000000001fd9db6154250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e874b45764eedd2c76398a57b4d5f2fe0f05a4f2000000000000000000000000e874b45764eedd2c76398a57b4d5f2fe0f05a4f2000000000000000000000000000000000000000000000000000c195119000bd200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13539,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a183a8304c3523d7963096b831c2ae160ce9dac8000000000000000000000000a183a8304c3523d7963096b831c2ae160ce9dac8000000000000000000000000000000000000000000000000000947c655a0c38000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017e555e5f72cd268453ad027666df4e3bad8f4db00000000000000000000000017e555e5f72cd268453ad027666df4e3bad8f4db000000000000000000000000000000000000000000000000000a296ebc7845e300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000376236b8277bbd26b7163caf4870691c37e75107000000000000000000000000376236b8277bbd26b7163caf4870691c37e7510700000000000000000000000000000000000000000000000000c21d4dc767724200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13542,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000052e9ac8200924ef2871208f34ce68ddb0b16e99000000000000000000000000052e9ac8200924ef2871208f34ce68ddb0b16e990000000000000000000000000000000000000000000000000009aae84f480fbc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13543,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000158169a722f85e8dd64fa4692af4ba0ee3ac3f1f000000000000000000000000158169a722f85e8dd64fa4692af4ba0ee3ac3f1f0000000000000000000000000000000000000000000000000081e4625b4b85d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003ec99088cdc87b1927f87831b570995bea0f63500000000000000000000000003ec99088cdc87b1927f87831b570995bea0f635000000000000000000000000000000000000000000000000000b6737c298120a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13546,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003322f34f6be8eb57642df8a768eb12478ffc40a00000000000000000000000003322f34f6be8eb57642df8a768eb12478ffc40a000000000000000000000000000000000000000000000000001116a29b23126a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c4a2c30a7d8150a63cc4268ca86c85c22c461500000000000000000000000006c4a2c30a7d8150a63cc4268ca86c85c22c461500000000000000000000000000000000000000000000000000013f9713c6cec6300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13548,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b01cec888e8f3904966f53852ca95fdeb166a9b0000000000000000000000004b01cec888e8f3904966f53852ca95fdeb166a9b000000000000000000000000000000000000000000000000000e8409dcf9ef6400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d86aae1dcc5d4534dcac0f2d3daf962b4277b200000000000000000000000001d86aae1dcc5d4534dcac0f2d3daf962b4277b20000000000000000000000000000000000000000000000000000cd170a2baf0d300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062ab1cd519eafdb64ad685a686c6f5d67a544ad200000000000000000000000062ab1cd519eafdb64ad685a686c6f5d67a544ad20000000000000000000000000000000000000000000000000067802bc23e280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf6f02a4b061dbb92e4b987d64650b33e0e1d0a89b40ac7acdba4bd84d53d1c82,2022-05-29 09:20:45.000 UTC,0,true +13552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000101d5479a5b33bc7a0720c93df1715612d059a24000000000000000000000000101d5479a5b33bc7a0720c93df1715612d059a2400000000000000000000000000000000000000000000000000101398cd168dc800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006730e06a5d67719c3895c56bcd01740734d411450000000000000000000000006730e06a5d67719c3895c56bcd01740734d41145000000000000000000000000000000000000000000000000000c8feabb3c345a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6732ddbd83c56fddf81d4e71074075b28b4fb9f000000000000000000000000e6732ddbd83c56fddf81d4e71074075b28b4fb9f000000000000000000000000000000000000000000000000000d452216a0b92600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4629261cd1c28c439321567a211c5db9ad81c3f000000000000000000000000c4629261cd1c28c439321567a211c5db9ad81c3f00000000000000000000000000000000000000000000000000082a5e4aaf9a8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011e56f8a14d70896f7daf6695a18e4b2d965637000000000000000000000000011e56f8a14d70896f7daf6695a18e4b2d9656370000000000000000000000000000000000000000000000000012712404f735cb400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092c0689fe3c559657e5e3409dcb5eb5eab76f2b800000000000000000000000092c0689fe3c559657e5e3409dcb5eb5eab76f2b8000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf2144acdab6d0267faf627ae8ce57544df1f23a000000000000000000000000cf2144acdab6d0267faf627ae8ce57544df1f23a00000000000000000000000000000000000000000000000001369453121169f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000095c5a2f8053b5efdf84a640ae03ee5f449870c0000000000000000000000000095c5a2f8053b5efdf84a640ae03ee5f449870c0000000000000000000000000000000000000000000000000002062e8108ccd73e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f30bc3626a28d6d5ce1af949043ccd2fc36440f0000000000000000000000007f30bc3626a28d6d5ce1af949043ccd2fc36440f000000000000000000000000000000000000000000000000015e466b398984cb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ceba1d1c54282179b77e318b4b0561a14af71730000000000000000000000009ceba1d1c54282179b77e318b4b0561a14af7173000000000000000000000000000000000000000000000000000054291bfda50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13564,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c819620fe48cfee437db472eb52b70946409aea2000000000000000000000000000000000000000000000020e0c83d1cad95e150,,,1,true +13567,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000039f85ae146ce38e5f14eef5c90a007420a29f19c00000000000000000000000039f85ae146ce38e5f14eef5c90a007420a29f19c0000000000000000000000000000000000000000000000000000000007361f6c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13568,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c618a50e79eefc2a421e8203f9f70a29e6a48170000000000000000000000003c618a50e79eefc2a421e8203f9f70a29e6a481700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13569,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032280087208adda9d2c5a1108969ea974ff95f4d00000000000000000000000032280087208adda9d2c5a1108969ea974ff95f4d000000000000000000000000000000000000000000000000005c5de18f44e2db00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9f4385e5308efc189f4ee67ce3bd0e117463a16cb60ecace06c6c0e68c45d46c,2022-07-24 05:16:53.000 UTC,0,true +13572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8611af181da9b5283d2bdf4c0799aaff3a278d6000000000000000000000000f8611af181da9b5283d2bdf4c0799aaff3a278d60000000000000000000000000000000000000000000000000009c01bb1eb3d3600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13573,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d89195a9322a9e8f5535512da06cdd165db0bc90000000000000000000000009d89195a9322a9e8f5535512da06cdd165db0bc9000000000000000000000000000000000000000000000000010af2595e3dd8a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c04c7c2efc023731303e7bf81a9b6540e361c76a000000000000000000000000c04c7c2efc023731303e7bf81a9b6540e361c76a000000000000000000000000000000000000000000000000008a234e96f95da100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13581,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eccc3a11a481e992ce4fd4d37e1568f11399b053000000000000000000000000eccc3a11a481e992ce4fd4d37e1568f11399b053000000000000000000000000000000000000000000000000001ccdfe282810c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000958118ab88b764151d6e67e779aae7ebfa064a48000000000000000000000000958118ab88b764151d6e67e779aae7ebfa064a48000000000000000000000000000000000000000000000000002b610a86cdaa0200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13589,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e46b89a906e70786f0ff94a40aaa63ebbf30aee0000000000000000000000000e46b89a906e70786f0ff94a40aaa63ebbf30aee000000000000000000000000000000000000000000000000001f4f6e4da65a63600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13592,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000982ad1aed87c4adf0de68939266c2cfe302567b90000000000000000000000000000000000000000000000013319a67d2993a96f,,,1,true +13596,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b50716974bb074a4d463cdd03152c495a0796ca2000000000000000000000000b50716974bb074a4d463cdd03152c495a0796ca200000000000000000000000000000000000000000000000000a1be53562fccda00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13598,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f6000000000000000000000000d2d070dc9389506ec673938ef2a0c9a0f681d414000000000000000000000000d2d070dc9389506ec673938ef2a0c9a0f681d4140000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006a5510dd227b846595500fea81b8f0761fa0f0a00000000000000000000000006a5510dd227b846595500fea81b8f0761fa0f0a0000000000000000000000000000000000000000000000000006d1e7adaa9c5c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13601,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f7e63da70b47255073cf8528d5ac54fbfb8c3130000000000000000000000000f7e63da70b47255073cf8528d5ac54fbfb8c31300000000000000000000000000000000000000000000000000bfd8b6c1df000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13602,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000068f180fcce6836688e9084f035309e29bf0a20950000000000000000000000009d522c3aee1cbb7743b69a2e3d38f6b7348434920000000000000000000000009d522c3aee1cbb7743b69a2e3d38f6b7348434920000000000000000000000000000000000000000000000000000000000995cd300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x858b1e251ccd26f8fb60fc8abf6d56c1a1b621b23665b09b20cf34bc4ec76e10,2021-12-09 16:16:28.000 UTC,0,true +13603,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b293d010257a41484dbdf0699030a0661f0b3446000000000000000000000000b293d010257a41484dbdf0699030a0661f0b344600000000000000000000000000000000000000000000000000a0f0e25649817b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x01ae15db9c4ebdd6867944922b24df9708d490928b59a2c79ecdaa88f0b21fbe,2022-04-24 09:10:34.000 UTC,0,true +13604,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c73567e09e1774f6e9e5f1f9de7fd0c3c4ce94fa000000000000000000000000c73567e09e1774f6e9e5f1f9de7fd0c3c4ce94fa00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13605,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2d070dc9389506ec673938ef2a0c9a0f681d414000000000000000000000000d2d070dc9389506ec673938ef2a0c9a0f681d41400000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13607,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5a117fdd91052627c75e40f06bf090205f233ff000000000000000000000000e5a117fdd91052627c75e40f06bf090205f233ff000000000000000000000000000000000000000000000000000200fa57fb508c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0f312c1d27e389061b6cbde969f5cf4b6033f04000000000000000000000000e0f312c1d27e389061b6cbde969f5cf4b6033f0400000000000000000000000000000000000000000000000000c3f0635499deda00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13610,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097b8e2856a360e11d8f2b29ec6a1d2d05be4310100000000000000000000000097b8e2856a360e11d8f2b29ec6a1d2d05be4310100000000000000000000000000000000000000000000000000102267eea76ae600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13611,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003aeedcd329e91e352d6c3d42c2b90d4e33a9e7d50000000000000000000000003aeedcd329e91e352d6c3d42c2b90d4e33a9e7d500000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13614,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000891acdefa5f01ab48bf69ff789ce9d3a9997f017000000000000000000000000000000000000000000000002e1b63a18a3938538,,,1,true +13615,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5945b102d58b1c2ee3c6c48be47341307b97023000000000000000000000000a5945b102d58b1c2ee3c6c48be47341307b97023000000000000000000000000000000000000000000000000012a0295d08c170000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bca589eee75761cbe808f9663ec62c1ed474bde5000000000000000000000000bca589eee75761cbe808f9663ec62c1ed474bde5000000000000000000000000000000000000000000000000009c184c7555ca0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13617,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a7bcbae98d2e410240045b6e6f2280e9d1523650000000000000000000000006a7bcbae98d2e410240045b6e6f2280e9d1523650000000000000000000000000000000000000000000000000056bf02012295c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13622,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e26917d01160f51dc28a58be9e1489b52a3eae67000000000000000000000000e26917d01160f51dc28a58be9e1489b52a3eae67000000000000000000000000000000000000000000000000000000000e5c414e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000970128b339a3223ac799af9c5b07ff15f253ed23000000000000000000000000970128b339a3223ac799af9c5b07ff15f253ed230000000000000000000000000000000000000000000000000040bfdcd201598500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c6c2c7d3a716ec100b7e3d1a99dbb7cee236b4e0000000000000000000000008c6c2c7d3a716ec100b7e3d1a99dbb7cee236b4e0000000000000000000000000000000000000000000000000249a5da5d34ac7d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf0b30daecb36a1cd35f409d2f219c2384c881b4000000000000000000000000cf0b30daecb36a1cd35f409d2f219c2384c881b4000000000000000000000000000000000000000000000000016b09e3eca3d03d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000873ec3e237fa0fafece9a1b25c0ad3bc9281adbd000000000000000000000000873ec3e237fa0fafece9a1b25c0ad3bc9281adbd0000000000000000000000000000000000000000000000000005f9a29020782100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b89c7fe5abe5c2a117e60f6222b88fed7d9d03ec000000000000000000000000b89c7fe5abe5c2a117e60f6222b88fed7d9d03ec00000000000000000000000000000000000000000000000000be2cbc77c47bbc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000c7cb3516ac75e8f2deeb86d831b907952f46fa41000000000000000000000000c7cb3516ac75e8f2deeb86d831b907952f46fa4100000000000000000000000000000000000000000000000012903918324c710400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13640,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba4f59ada21c3a8116f1b3fb644378fe1d7b2c95000000000000000000000000ba4f59ada21c3a8116f1b3fb644378fe1d7b2c9500000000000000000000000000000000000000000000000000afd68e3ec472b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df25d35bd400d854006711efeb19a3530570d3cd000000000000000000000000df25d35bd400d854006711efeb19a3530570d3cd000000000000000000000000000000000000000000000000006f45e39ff7b5af00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc9a5cdeff2d022a9e910c4c1c7c78e6be666a36000000000000000000000000cc9a5cdeff2d022a9e910c4c1c7c78e6be666a3600000000000000000000000000000000000000000000000000274d351264fc3e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3c225aa226963fe3567090b3fb558c0dbdf25b30e4939585a92d126418967345,2022-05-22 18:40:31.000 UTC,0,true +13646,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb11a95772ff45df169e8e917eeaeded0c1547d3000000000000000000000000bb11a95772ff45df169e8e917eeaeded0c1547d3000000000000000000000000000000000000000000000000004983bc275496a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13647,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f7cf5cdc5ef913fa0066225a97f23b776d5821a0000000000000000000000007f7cf5cdc5ef913fa0066225a97f23b776d5821a000000000000000000000000000000000000000000000000006815fbd52c765e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13651,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ff393874358530cf9740b5c90f8c9594cc1772ab000000000000000000000000ff393874358530cf9740b5c90f8c9594cc1772ab0000000000000000000000000000000000000000000000000000000009c3428d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13652,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff393874358530cf9740b5c90f8c9594cc1772ab000000000000000000000000ff393874358530cf9740b5c90f8c9594cc1772ab00000000000000000000000000000000000000000000000001aa535d3d0c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051cc2245a1ef254091b081221096ca8df45410a800000000000000000000000051cc2245a1ef254091b081221096ca8df45410a80000000000000000000000000000000000000000000000000005586f1156aeb900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13654,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000937e277649d3af92f1fd1393369994ac10b8ed70000000000000000000000000937e277649d3af92f1fd1393369994ac10b8ed700000000000000000000000000000000000000000000000000bbf505a32aad7200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0635e38a63c11c7f48cc94f473909d069660056000000000000000000000000c0635e38a63c11c7f48cc94f473909d069660056000000000000000000000000000000000000000000000000005c15d97dbca35a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13657,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e468e0188041203f1617e8d08735c8f00b54d352000000000000000000000000e468e0188041203f1617e8d08735c8f00b54d3520000000000000000000000000000000000000000000001276deeec284f81d93500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d346f2eecfab56f4fcc27b34eab78cce7080198a000000000000000000000000d346f2eecfab56f4fcc27b34eab78cce7080198a00000000000000000000000000000000000000000000000000610c079a612f9900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa2764bcab55a73f70427f75d6ae4353e2e81c985758b1c6644d5a0dde4b47d84,2022-03-06 11:13:27.000 UTC,0,true +13660,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d3944d5c30ebacac4b8ad3dc381a1f0ef821e760000000000000000000000005d3944d5c30ebacac4b8ad3dc381a1f0ef821e7600000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13662,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005984000b183c5fc63c0b2e0e86d584ee269cabe00000000000000000000000005984000b183c5fc63c0b2e0e86d584ee269cabe0000000000000000000000000000000000000000000000000032b563be66b5ca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13663,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038388a70999d3563dabdd906505d5dabce6660a200000000000000000000000038388a70999d3563dabdd906505d5dabce6660a2000000000000000000000000000000000000000000000000000d127a2a235e9100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f17dc054461600ea83bf571080cdb20cce4c5a22000000000000000000000000f17dc054461600ea83bf571080cdb20cce4c5a22000000000000000000000000000000000000000000000000000aa54ad79d861f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005314235ba5b766fb8e107c8e8109279264a2308e0000000000000000000000005314235ba5b766fb8e107c8e8109279264a2308e000000000000000000000000000000000000000000000000000c462da7d5ec4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13666,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000866742a1f91f5fdbd473741b23acc42248694b51000000000000000000000000866742a1f91f5fdbd473741b23acc42248694b5100000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13667,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c4e3de7c408f9a45592efaa2829d04dd88a3f720000000000000000000000005c4e3de7c408f9a45592efaa2829d04dd88a3f720000000000000000000000000000000000000000000000000033d79a8506582100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1890d3dd50416293df20b881a1aa75907b64733a2e0be3c72cdc544dd7c1eb66,2021-12-16 14:27:23.000 UTC,0,true +13668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018d8b65f80454a74491a1265736a574973d9c78100000000000000000000000018d8b65f80454a74491a1265736a574973d9c78100000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x15617ccc700ee119b063663d2499c41f26b7afe7822a24a808e1ff897caabf91,2022-04-27 01:05:04.000 UTC,0,true +13669,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfe440c533f6861c00e71ce187f37a1a70b7b7e9000000000000000000000000bfe440c533f6861c00e71ce187f37a1a70b7b7e9000000000000000000000000000000000000000000000000015e02dbf21fe70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9b558d97301783a6e00b27e122fcf4031eb12a6000000000000000000000000d9b558d97301783a6e00b27e122fcf4031eb12a60000000000000000000000000000000000000000000000000012cf779b2516fc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13682,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c033aab89b26650057881dabbc0815146ffc0f20000000000000000000000003c033aab89b26650057881dabbc0815146ffc0f200000000000000000000000000000000000000000000000006db6291970d97b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd61d3c32f39adac31ea52c0efe0074492cda6a8da7d06471be3f854e9dc82ba8,2021-11-24 11:59:22.000 UTC,0,true +13684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025ae391a0f8b3254123a0278f599a43d4c44462700000000000000000000000025ae391a0f8b3254123a0278f599a43d4c4446270000000000000000000000000000000000000000000000000139a82c70392ec800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038720e3787058d56fafa38c0f034a9c94067c28000000000000000000000000038720e3787058d56fafa38c0f034a9c94067c2800000000000000000000000000000000000000000000000000008e1bc9bf0400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13686,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071cc3892dddad179cc6d8c9646ec82d65140f5ee00000000000000000000000071cc3892dddad179cc6d8c9646ec82d65140f5ee00000000000000000000000000000000000000000000000000a18553ee95f38000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13687,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a73bfd196ae9e09925efb1ffb3e35593ab183bb0000000000000000000000004a73bfd196ae9e09925efb1ffb3e35593ab183bb000000000000000000000000000000000000000000000000014a81f9106dfd4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13689,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e7e8336b7023386bdbc7b1f2b000783a463614b40000000000000000000000000000000000000000000000012a21cdfa744d5aa5,,,1,true +13691,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f1ccfa46b1356589ec6361468f3520aff95b21c3000000000000000000000000f1ccfa46b1356589ec6361468f3520aff95b21c300000000000000000000000000000000000000000000001b0da07c7d9262f67700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13692,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002a81579aab05701838b80c826844e618aa023ed4000000000000000000000000000000000000000000000000182fd7d1303545b1,,,1,true +13693,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3f686811c223b701ea913b0ae7018c7ae2bd1c5000000000000000000000000a3f686811c223b701ea913b0ae7018c7ae2bd1c500000000000000000000000000000000000000000000000002b4e97044a834d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b412b96dbe138da98be8e475f632e1a8f0037748000000000000000000000000b412b96dbe138da98be8e475f632e1a8f003774800000000000000000000000000000000000000000000000000082b1cc6bc67c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13696,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ea82a3403fa84dab71ef6146da215dcc5798e8ce00000000000000000000000000000000000000000000000018362ac6c93984b2,,,1,true +13697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080d4d18e9e1407f8b7c6ecee4b7ece6ad847401200000000000000000000000080d4d18e9e1407f8b7c6ecee4b7ece6ad847401200000000000000000000000000000000000000000000000000ac49e2f770474400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xfde3993f48729f1ac7641a629dc64e471cd520651ff43ccb78c576a305dde0a8,2022-03-05 15:20:46.000 UTC,0,true +13698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf8c7f3aef546992c9f8f42900b4ca245ceb5c88000000000000000000000000cf8c7f3aef546992c9f8f42900b4ca245ceb5c880000000000000000000000000000000000000000000000000077040e43ac810000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13699,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b3036b15fcd13d66131f5368c444ffc4cfa9b6db00000000000000000000000000000000000000000000000018368045a0390491,,,1,true +13700,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0387235a4b51d1dfc8a9e4eaf864535e8ded7d8000000000000000000000000b0387235a4b51d1dfc8a9e4eaf864535e8ded7d8000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13701,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000959db0e23993319053d28a5b9a056237a4eb9e8c0000000000000000000000000000000000000000000000001836acd458210044,,,1,true +13703,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000004a9337d7376219f7e2e24732b8096d92a079ad700000000000000000000000000000000000000000000000018363f88e61c7c4d,,,1,true +13704,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a0f9e61bfd61c4f5ecdf7b5c838f402549d6b9ec0000000000000000000000000000000000000000000000001836544b1db1b9f5,,,1,true +13705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039af6952f2fbe751a10f28a63f9f57d65f64e3fa00000000000000000000000039af6952f2fbe751a10f28a63f9f57d65f64e3fa00000000000000000000000000000000000000000000000000487504ba8eba6400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13707,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000043917a8174465dc01522e8e14335eaa2cde33f6f00000000000000000000000000000000000000000000000024b420a32e9e04c7,,,1,true +13708,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000043917a8174465dc01522e8e14335eaa2cde33f6f000000000000000000000000000000000000000000000000bbcda00c7cf990c2,,,1,true +13711,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000064f7939b100932308286400b6289e6d2d4d1b46200000000000000000000000064f7939b100932308286400b6289e6d2d4d1b46200000000000000000000000000000000000000000000001044e573f6f154039a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027b6d3610012461ec0aa3e4bb7155767d77f564f00000000000000000000000027b6d3610012461ec0aa3e4bb7155767d77f564f000000000000000000000000000000000000000000000000004d3a988820a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008947269c4c2ea8e6b91634d2c2f12c7bdfa95a1b0000000000000000000000008947269c4c2ea8e6b91634d2c2f12c7bdfa95a1b000000000000000000000000000000000000000000000000002fad4006ee84e600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13719,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c516ef1165b6f4f478c3a021d4333e2a1e73658a000000000000000000000000c516ef1165b6f4f478c3a021d4333e2a1e73658a000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2d4e4bb39b094f9dce72f67e8980e19551c2732d6a0dda7834cc4022e4ab85dd,2022-06-19 17:02:51.000 UTC,0,true +13721,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000219518e022f219a79900365b06c9c2a1ff51d767000000000000000000000000219518e022f219a79900365b06c9c2a1ff51d76700000000000000000000000000000000000000000000000000135154eaf46d6400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xff936d8d80b15a29becb8b0cf540cccf61715149b5d6207584ff0da92f7e3513,2022-06-04 04:45:59.000 UTC,0,true +13722,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000546911aa23511b9b023d4cfa2d97b82f4d423a710000000000000000000000000000000000000000000000003b84acdf3738d5ca,,,1,true +13723,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aa8532152a2420b253fd775f9ddf482fdbe01061000000000000000000000000aa8532152a2420b253fd775f9ddf482fdbe01061000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13724,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6058d9f92befa23c21a63581daa82a0ade0ec14000000000000000000000000a6058d9f92befa23c21a63581daa82a0ade0ec1400000000000000000000000000000000000000000000000000753d533d96800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13725,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019be4885e21217a78c505713bae6869e3eaa391400000000000000000000000019be4885e21217a78c505713bae6869e3eaa3914000000000000000000000000000000000000000000000000006171551822660000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13732,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008d9793b6bf062146630154b8d59908b470523895000000000000000000000000000000000000000000000000aa487051d17ae4ab,,,1,true +13734,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef28d0039f0ef5e859ee969908c4e96bc73ce91c000000000000000000000000ef28d0039f0ef5e859ee969908c4e96bc73ce91c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13735,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2d070dc9389506ec673938ef2a0c9a0f681d414000000000000000000000000d2d070dc9389506ec673938ef2a0c9a0f681d41400000000000000000000000000000000000000000000000004c5dc152f1e801800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13737,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cae337b0c02f21e3785c84949cccd61b9a0ba996000000000000000000000000cae337b0c02f21e3785c84949cccd61b9a0ba996000000000000000000000000000000000000000000000000003c9561de46cfd400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc3fd391414bf8f902726d465d2286ffdff91794000000000000000000000000cc3fd391414bf8f902726d465d2286ffdff9179400000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f01f75803f329a072a9243b11d7feb1d9ee4ebb0000000000000000000000005f01f75803f329a072a9243b11d7feb1d9ee4ebb000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13743,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3e67de00916aca84260b4c243a89e0f5066333e000000000000000000000000b3e67de00916aca84260b4c243a89e0f5066333e000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13744,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3e67de00916aca84260b4c243a89e0f5066333e000000000000000000000000b3e67de00916aca84260b4c243a89e0f5066333e0000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000081423ad03f559a3a9ff38737c56b4497d6c7416600000000000000000000000081423ad03f559a3a9ff38737c56b4497d6c741660000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13746,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e88c5846b3575eb52fa73b622d34c9a7bcadd5f0000000000000000000000008e88c5846b3575eb52fa73b622d34c9a7bcadd5f0000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d33b32db98cf814f9117b75a7bb950f8a152c872000000000000000000000000d33b32db98cf814f9117b75a7bb950f8a152c8720000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13748,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acac85b03ce497fa43af7f39a40b59c749c7f627000000000000000000000000acac85b03ce497fa43af7f39a40b59c749c7f6270000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13749,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e6bdcfaf5e2d4862ddd85294cc0fa72cb2bfda10000000000000000000000008e6bdcfaf5e2d4862ddd85294cc0fa72cb2bfda10000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13750,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004f90835defacbaa0c9a44fd2528a53377d20e9b00000000000000000000000004f90835defacbaa0c9a44fd2528a53377d20e9b0000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13751,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002127f3ee6080f0b4dbb1b68ad4e1a2bfcf68f31c0000000000000000000000002127f3ee6080f0b4dbb1b68ad4e1a2bfcf68f31c0000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003610fedd465abd506fdddc1a27e599a3e60743890000000000000000000000003610fedd465abd506fdddc1a27e599a3e60743890000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13753,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000579fd38a3456c82074be725f1460458c03d723d1000000000000000000000000579fd38a3456c82074be725f1460458c03d723d10000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13754,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e395cf1acb6ee2815f41485ad1a5ada34180e1e0000000000000000000000001e395cf1acb6ee2815f41485ad1a5ada34180e1e0000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13755,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0877fd8349dea069bbe19945eb3ee2ee1919038000000000000000000000000b0877fd8349dea069bbe19945eb3ee2ee19190380000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13756,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002148db985350559e78e4326dcc63b0ee42fb57e70000000000000000000000002148db985350559e78e4326dcc63b0ee42fb57e70000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13757,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ac1d1b238944e4cc46281899d139e48e36035b00000000000000000000000001ac1d1b238944e4cc46281899d139e48e36035b00000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000063b8e7d341ca2629db6570e5d17bd137e72a601000000000000000000000000063b8e7d341ca2629db6570e5d17bd137e72a6010000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13759,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000198dcf44001d05c04b5576db43ed22ee9510997f000000000000000000000000198dcf44001d05c04b5576db43ed22ee9510997f000000000000000000000000000000000000000000000000001debae4494100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13760,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051e7be9eec7e86198ae475ccdd5f03319f7522aa00000000000000000000000051e7be9eec7e86198ae475ccdd5f03319f7522aa0000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000968774c040cf7ab7dd25657ff172d947cd0259d2000000000000000000000000968774c040cf7ab7dd25657ff172d947cd0259d20000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13763,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dbb1e8d856bffb7d9f28a49106904250ef3f9d80000000000000000000000000dbb1e8d856bffb7d9f28a49106904250ef3f9d800000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13764,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1d6068e3cf2d020c26ed9f56375ac6244efbc48000000000000000000000000c1d6068e3cf2d020c26ed9f56375ac6244efbc480000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13765,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ce9d538cf6f65a62632e4f03811676be17162c68000000000000000000000000ce9d538cf6f65a62632e4f03811676be17162c680000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c87ec6959855718a4c20616d4468445df21c2064000000000000000000000000c87ec6959855718a4c20616d4468445df21c206400000000000000000000000000000000000000000000000000acd54e3eccb00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcac3f812ca41672bafd6d56516aff23e2278a0c620b4b33c47f6b75a699df25f,2022-03-30 08:44:09.000 UTC,0,true +13768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000315db0a3e7db5ba1a7c5cc7f26cf091ef05bd5c4000000000000000000000000315db0a3e7db5ba1a7c5cc7f26cf091ef05bd5c40000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13769,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005575b51eae681fc57565717ef94f1ead2abe229c0000000000000000000000005575b51eae681fc57565717ef94f1ead2abe229c0000000000000000000000000000000000000000000000000000febd88f4840000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13770,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000364fae0eec5d11fa906878500c7edcde1466a92e000000000000000000000000364fae0eec5d11fa906878500c7edcde1466a92e0000000000000000000000000000000000000000000000000000ff62d840c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13771,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cac9ca7914980ea03f30049d7cc34d2dd3aef680000000000000000000000007cac9ca7914980ea03f30049d7cc34d2dd3aef680000000000000000000000000000000000000000000000000000febb34e8a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9f3d4827f881f6c19d4cedfdf7316e7821cef2c000000000000000000000000f9f3d4827f881f6c19d4cedfdf7316e7821cef2c0000000000000000000000000000000000000000000000000000febb34e8a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13773,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4b8a67e9f66f0b01fda8d80d869a539b6bc320e000000000000000000000000c4b8a67e9f66f0b01fda8d80d869a539b6bc320e0000000000000000000000000000000000000000000000000000febb34e8a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6d641b2615db1e054aa3fea7a2e4e6427f4f136000000000000000000000000d6d641b2615db1e054aa3fea7a2e4e6427f4f1360000000000000000000000000000000000000000000000000000febb34e8a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e0b2662e6474c57f48f597cb4454c4d74e94f0c0000000000000000000000009e0b2662e6474c57f48f597cb4454c4d74e94f0c0000000000000000000000000000000000000000000000000000febb34e8a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054483a3074e5b300c9dfd5c291841d34e4a0a3f800000000000000000000000054483a3074e5b300c9dfd5c291841d34e4a0a3f80000000000000000000000000000000000000000000000000000febb34e8a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a8dc224d071ea7c895a38ecdb8d4259de3f07940000000000000000000000003a8dc224d071ea7c895a38ecdb8d4259de3f07940000000000000000000000000000000000000000000000000000febb34e8a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13780,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098bafa71334eae0037d7ce585702d340ece7138300000000000000000000000098bafa71334eae0037d7ce585702d340ece7138300000000000000000000000000000000000000000000000000fa81a83f6d894000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000084ba64ffc799272e5d52a724ff8f02cf0555832000000000000000000000000084ba64ffc799272e5d52a724ff8f02cf0555832000000000000000000000000000000000000000000000000011c68878f6c5d0c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13784,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2805dfd8a541b38493e2ebd5934e22ff106af5f000000000000000000000000a2805dfd8a541b38493e2ebd5934e22ff106af5f00000000000000000000000000000000000000000000000000ac9856716fe20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000676e1705c3550dec29f2e03f6267f893af664d0c000000000000000000000000676e1705c3550dec29f2e03f6267f893af664d0c000000000000000000000000000000000000000000000000000db996be0d158000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000932adf2d3cea3c8238580e81ecfa79c0ad6032b3000000000000000000000000932adf2d3cea3c8238580e81ecfa79c0ad6032b3000000000000000000000000000000000000000000000000014ccbb8a6c358e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000de0004eb5a2dfea5f5789c253da23cfe1c68a9f9000000000000000000000000de0004eb5a2dfea5f5789c253da23cfe1c68a9f90000000000000000000000000000000000000000000000000000000003f4797100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +13797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008aa77780e81dc51f8f90b80210aafa5b44be28010000000000000000000000008aa77780e81dc51f8f90b80210aafa5b44be280100000000000000000000000000000000000000000000000000ce4752812b3ea200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13801,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032181bedfcc11d5a14e23955fe5560b2ac46407600000000000000000000000032181bedfcc11d5a14e23955fe5560b2ac4640760000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13803,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e575233ed38f45c14d18205e6dc4bdbfeca637e4000000000000000000000000e575233ed38f45c14d18205e6dc4bdbfeca637e400000000000000000000000000000000000000000000000001576ce67541b1a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13804,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d861415f6703ab50ce101c7e6f6a80ada1fc2b1c0000000000000000000000000000000000000000000000006c8f76ad9111a6a6,0xe7606f11a82d9e2a5679cba45f79bd2a371104be26201346e9060b9ce7abde76,2022-02-14 01:13:29.000 UTC,0,true +13809,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041337285f9c00a3b2f7224cb2f591313ee1fb0f300000000000000000000000041337285f9c00a3b2f7224cb2f591313ee1fb0f300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003dc29113a1fe2299714c1bbb855fba8bb0b4415c0000000000000000000000003dc29113a1fe2299714c1bbb855fba8bb0b4415c00000000000000000000000000000000000000000000000000502b04164c3e5100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076e2c6d6f961168dd892516438ec807933d0941f00000000000000000000000076e2c6d6f961168dd892516438ec807933d0941f000000000000000000000000000000000000000000000000034623d158f4acf000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2e741cfb75495cb4293eee5a00b5a456c591d58d0fa06660dcc11aa5a37bfe1a,2021-11-27 22:06:02.000 UTC,0,true +13818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f7c16d37a07ffd7e570533015a439c805fcb2c00000000000000000000000008f7c16d37a07ffd7e570533015a439c805fcb2c00000000000000000000000000000000000000000000000000020a41ec34825b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c04d107c3f21d215772ead8af02d3f4f2321fcd4000000000000000000000000c04d107c3f21d215772ead8af02d3f4f2321fcd40000000000000000000000000000000000000000000000000017b0f70c6e41d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e8a40add5f9c5ba0745be38444e96c63d0d9b8b0000000000000000000000002e8a40add5f9c5ba0745be38444e96c63d0d9b8b00000000000000000000000000000000000000000000000002ea11e32ad5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13822,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae60da5f4f1ae7a4f18e5632f389ade1d1a8bcb2000000000000000000000000ae60da5f4f1ae7a4f18e5632f389ade1d1a8bcb200000000000000000000000000000000000000000000000000612d1b3a71de8f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6b30aba25fadd6acc0a7b314004ddc18cb35311000000000000000000000000d6b30aba25fadd6acc0a7b314004ddc18cb35311000000000000000000000000000000000000000000000000004e30757b97b51000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd3858559b8bf543333fbce1af7dde964f0f9461000000000000000000000000dd3858559b8bf543333fbce1af7dde964f0f94610000000000000000000000000000000000000000000000000153e6baf037079d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x346255597474201c3b0e665385377fbe23a924de8a6ec8825de979a46065c31b,2021-11-24 22:47:29.000 UTC,0,true +13825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bece8c246e30d9067c9b0975651429e4d59c8800000000000000000000000001bece8c246e30d9067c9b0975651429e4d59c8800000000000000000000000000000000000000000000000000009edfebeb9a2a200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c46cfa41efdcef6e2f29da3b9303f67534b028b0000000000000000000000002c46cfa41efdcef6e2f29da3b9303f67534b028b000000000000000000000000000000000000000000000000000b0b49e6f8bfcd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038dbb1eb69ba4e66e6c76526a30a537a584e5cc500000000000000000000000038dbb1eb69ba4e66e6c76526a30a537a584e5cc50000000000000000000000000000000000000000000000000009bb6122162f8400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d71da19b58b32781f67a5c22336b200f9c7ddf21000000000000000000000000d71da19b58b32781f67a5c22336b200f9c7ddf21000000000000000000000000000000000000000000000000000c2acd124a86c700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087fa43b5647d4d98c073de139ee4339394f349b200000000000000000000000087fa43b5647d4d98c073de139ee4339394f349b2000000000000000000000000000000000000000000000000000861316f5e3fe500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003510bc6a39ef985c35b1562c610de464e45f025a0000000000000000000000003510bc6a39ef985c35b1562c610de464e45f025a000000000000000000000000000000000000000000000000000b9f7e5c6b7ae200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bb2aff9a50bd3fa0ec4c780198e6cc8f7dd068a0000000000000000000000001bb2aff9a50bd3fa0ec4c780198e6cc8f7dd068a00000000000000000000000000000000000000000000000000136d4d067f418600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027b77419682e8ff5c992c8663e3d3bfe8971256a00000000000000000000000027b77419682e8ff5c992c8663e3d3bfe8971256a0000000000000000000000000000000000000000000000000138757658ff9cca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2de13ed36177ad43cb2a399f8c53de407b13ab9000000000000000000000000e2de13ed36177ad43cb2a399f8c53de407b13ab90000000000000000000000000000000000000000000000000166e6438dabbe6800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000471d854855c9bd2c92ff45c68dfdf35181c97993000000000000000000000000471d854855c9bd2c92ff45c68dfdf35181c9799300000000000000000000000000000000000000000000000000f9825970e4d10a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e4d25d4d44899d53506464a7f8996ae9cc958f10000000000000000000000009e4d25d4d44899d53506464a7f8996ae9cc958f1000000000000000000000000000000000000000000000000000f401378df49cf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ccb308c9f732f66b776e07805ea2109f9b1006e0000000000000000000000009ccb308c9f732f66b776e07805ea2109f9b1006e000000000000000000000000000000000000000000000000001e49d06674695d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a06f48cf3780a5d1cfb243644249840ab459c82e000000000000000000000000a06f48cf3780a5d1cfb243644249840ab459c82e0000000000000000000000000000000000000000000000000016c60d3d244be900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f149bdfbf2d9ae300c8610b192c0faf4ea5dea50000000000000000000000007f149bdfbf2d9ae300c8610b192c0faf4ea5dea50000000000000000000000000000000000000000000000000019baa30756ddc400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009da41a6beaf774ef78aaac226a946a5034aac85f0000000000000000000000009da41a6beaf774ef78aaac226a946a5034aac85f00000000000000000000000000000000000000000000000000198de0adb8596400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068ac76e092bd073864fc908f51199660157b16aa00000000000000000000000068ac76e092bd073864fc908f51199660157b16aa000000000000000000000000000000000000000000000000000928335ad9cb7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004dd1e277bb273ef3b3b7ededb34e39ca90c0844d0000000000000000000000004dd1e277bb273ef3b3b7ededb34e39ca90c0844d0000000000000000000000000000000000000000000000000017ffb6218e529c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000540e17ccb9a4b9ab23cd9eea1f129b1343bbe89e000000000000000000000000540e17ccb9a4b9ab23cd9eea1f129b1343bbe89e00000000000000000000000000000000000000000000000000a41711cab156d100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x14572f42cfe04bdd8774ef2881e449c612b96a7d0304335d1c2d5bd37b3ff0ca,2021-11-29 10:48:38.000 UTC,0,true +13848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062c7bdc15d4c0a02d0a9f7c169c098ef9f44a98100000000000000000000000062c7bdc15d4c0a02d0a9f7c169c098ef9f44a98100000000000000000000000000000000000000000000000000182af521455e1700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d76503e7e454be25378f7a881c3737b2b21c9590000000000000000000000006d76503e7e454be25378f7a881c3737b2b21c959000000000000000000000000000000000000000000000000058d15e17628000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9e52a623a6a19f16bde2cd0aa16df7bc2acc1ee000000000000000000000000c9e52a623a6a19f16bde2cd0aa16df7bc2acc1ee00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f77b1e693cc7ca589de9c75eec759448dc5ee74d000000000000000000000000f77b1e693cc7ca589de9c75eec759448dc5ee74d0000000000000000000000000000000000000000000000000003931a2b1ebf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13866,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f7c14e402fcc3864d6e1ae1c4747ff1805d05120000000000000000000000003f7c14e402fcc3864d6e1ae1c4747ff1805d051200000000000000000000000000000000000000000000000000644d9f94d6221400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x88455eec9c3283bcccbd41feb50e0cfb8b9fa7dd581ee88d8c7094dfda096ebb,2022-07-28 02:22:29.000 UTC,0,true +13869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b0c28517d4f12024c61e8b5a4d09ad44cb876540000000000000000000000004b0c28517d4f12024c61e8b5a4d09ad44cb87654000000000000000000000000000000000000000000000000014a5449159dd40f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000386fc57656d7e2ef7a64d4b2d8586fc76b1a5921000000000000000000000000386fc57656d7e2ef7a64d4b2d8586fc76b1a5921000000000000000000000000000000000000000000000000014a5449159dd40f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acd74381d49863a7d894e65d1a169bad28d4518d000000000000000000000000acd74381d49863a7d894e65d1a169bad28d4518d000000000000000000000000000000000000000000000000009a7270a91f654f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000aa911d5c666ba32641c88f902db24c2072c61c40000000000000000000000000aa911d5c666ba32641c88f902db24c2072c61c4000000000000000000000000000000000000000000000000007d39215ee4bd4700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046aef1f4da528d1fcf08ed3168e6dd0162b0caef00000000000000000000000046aef1f4da528d1fcf08ed3168e6dd0162b0caef00000000000000000000000000000000000000000000000001637522d0bcbf9100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13884,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045eb6f503216a9e790004ff9826a0ccc8354ff3600000000000000000000000045eb6f503216a9e790004ff9826a0ccc8354ff3600000000000000000000000000000000000000000000000000a44f12b27a2a7400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13886,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd884503024358c06d20d286fe7abc99c1ab6fb3000000000000000000000000dd884503024358c06d20d286fe7abc99c1ab6fb30000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c72bc234ee8da7c547fedaffe8fcc3b341594550000000000000000000000006c72bc234ee8da7c547fedaffe8fcc3b341594550000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13888,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000069688011f03577887b75d392d207eb11281bab20000000000000000000000000000000000000000000000001043561a882930000,,,1,true +13889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007571eb1e3a18317a87f8d643aa72b921dc228fad0000000000000000000000007571eb1e3a18317a87f8d643aa72b921dc228fad0000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ca8e720077bdd6066b2a346de9f450357eff1c50000000000000000000000007ca8e720077bdd6066b2a346de9f450357eff1c50000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a70716545fa4557e08f21638da33ef1298840e7f000000000000000000000000a70716545fa4557e08f21638da33ef1298840e7f0000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000657b8bf0f4e281d832766b5943a91740a36b34e0000000000000000000000000657b8bf0f4e281d832766b5943a91740a36b34e00000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13894,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003763f804c7b15159fb1e0a9ab4fb5f552a179dd90000000000000000000000003763f804c7b15159fb1e0a9ab4fb5f552a179dd90000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13895,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037f0311939fa7cd463a576e6c46e0a35fe562b5d00000000000000000000000037f0311939fa7cd463a576e6c46e0a35fe562b5d0000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e6fc4bd7c821d191a210c1fd9a0738c4f73afbc0000000000000000000000000e6fc4bd7c821d191a210c1fd9a0738c4f73afbc0000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2c108451ef9a340ca738e470c874c4cc55b561a000000000000000000000000d2c108451ef9a340ca738e470c874c4cc55b561a0000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13898,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002abf33485edf704511dfa42dfb8afa71a0450a8e000000000000000000000000000000000000000000000000055a2966fa1696f2,,,1,true +13899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007eb0e5d522e3e1e5127bb41712744636b8c5485e0000000000000000000000007eb0e5d522e3e1e5127bb41712744636b8c5485e0000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13900,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002abf33485edf704511dfa42dfb8afa71a0450a8e00000000000000000000000000000000000000000000000008868d4cad4d690e,,,1,true +13902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000926db61b0dc59db81b2030e98a9887442e1ab9e7000000000000000000000000926db61b0dc59db81b2030e98a9887442e1ab9e70000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13903,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008be8b54bf1891e9cf5c7524ee145fdf112ac5da50000000000000000000000008be8b54bf1891e9cf5c7524ee145fdf112ac5da50000000000000000000000000000000000000000000000000000feaae895640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13905,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e583c8c7ec232d3bc00d8667f26c003b5032b6a3000000000000000000000000e583c8c7ec232d3bc00d8667f26c003b5032b6a30000000000000000000000000000000000000000000000000000febb34e8a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e583c8c7ec232d3bc00d8667f26c003b5032b6a3000000000000000000000000e583c8c7ec232d3bc00d8667f26c003b5032b6a30000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13907,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed7bdd301418b06d96c895e4a1e68cf200d34389000000000000000000000000ed7bdd301418b06d96c895e4a1e68cf200d343890000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13908,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fb998faf59b246cd6001772d44a265d16e5c0804000000000000000000000000fb998faf59b246cd6001772d44a265d16e5c08040000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac3cfb3d1ad099597474ec2a663aa3cac0a2c4d5000000000000000000000000ac3cfb3d1ad099597474ec2a663aa3cac0a2c4d50000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038ea73c4299b86c733f7fb11b7ddc4f5bbc46e0b00000000000000000000000038ea73c4299b86c733f7fb11b7ddc4f5bbc46e0b0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13912,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f582a5819feab1c4e50c1da34405dd36f7300228000000000000000000000000f582a5819feab1c4e50c1da34405dd36f73002280000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efabd4c414a7d5a5bafc3328c031e0bbe0b26524000000000000000000000000efabd4c414a7d5a5bafc3328c031e0bbe0b265240000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13914,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000378b280e96d6370dc5b2ba090a9add33d91c86fd000000000000000000000000378b280e96d6370dc5b2ba090a9add33d91c86fd00000000000000000000000000000000000000000000000002385215c8c1209500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1ae8f8565d9e807e12e54b888cc048314c3edd78c84306b8eb697db5b534f8e3,2022-04-09 09:21:29.000 UTC,0,true +13915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea581366ef46df7d2bb6a6b33718e5a2c25bbf41000000000000000000000000ea581366ef46df7d2bb6a6b33718e5a2c25bbf410000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c97aec31eb8cfd2276296b8e4752ba8bf07d1772000000000000000000000000c97aec31eb8cfd2276296b8e4752ba8bf07d17720000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b3e9cb38c3f3b2c9b32ea0b45cb1b84145845480000000000000000000000005b3e9cb38c3f3b2c9b32ea0b45cb1b84145845480000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c778b86a9d91cbabd36277088024c24660de1ccc000000000000000000000000c778b86a9d91cbabd36277088024c24660de1ccc0000000000000000000000000000000000000000000000000061743c7719340d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13919,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b73ecf578f050e9a1355b9c7e568c69660b3c1a3000000000000000000000000b73ecf578f050e9a1355b9c7e568c69660b3c1a30000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094bfc5aae1a892c10387f2f7b45f76522f318ade00000000000000000000000094bfc5aae1a892c10387f2f7b45f76522f318ade0000000000000000000000000000000000000000000000000027385e23e4e40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13921,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a56b43ca0fa370e227e04f892bb1168e32805c47000000000000000000000000a56b43ca0fa370e227e04f892bb1168e32805c470000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13922,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed991ee4ebd2a9fc687faaa9834bb867b0f57d0c000000000000000000000000ed991ee4ebd2a9fc687faaa9834bb867b0f57d0c0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020d0b2841ea0f89a709e0b7c9abce1321edf084200000000000000000000000020d0b2841ea0f89a709e0b7c9abce1321edf08420000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b346d91dfccbd53a43b4003a99f30c729412d15d000000000000000000000000b346d91dfccbd53a43b4003a99f30c729412d15d0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9331396e253c39691ae73ac7da5127048e6a5bc000000000000000000000000e9331396e253c39691ae73ac7da5127048e6a5bc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000089d2fe7fd0bd029d0d1ddad4619a555a46ef4f5000000000000000000000000089d2fe7fd0bd029d0d1ddad4619a555a46ef4f50000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13928,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093806f29ccf0c6d992107913f24c0796cada5d5800000000000000000000000093806f29ccf0c6d992107913f24c0796cada5d58000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13929,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007428573fe900b09aee5d11913e81053cf386029c0000000000000000000000007428573fe900b09aee5d11913e81053cf386029c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f71ade9a6f0e548b4c54fe6333c44acaa0277070000000000000000000000006f71ade9a6f0e548b4c54fe6333c44acaa027707000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b5a2ab94fa6065ec4d66a78b21be36c699d2bb80000000000000000000000008b5a2ab94fa6065ec4d66a78b21be36c699d2bb8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13932,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049ac0a98c73a9da0d722c2d44dc2b6c261cf793600000000000000000000000049ac0a98c73a9da0d722c2d44dc2b6c261cf7936000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13933,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a33defcd8507b606bb1776246e24b9ac81de3e2b000000000000000000000000a33defcd8507b606bb1776246e24b9ac81de3e2b0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13934,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004221eb734ecbbb279f356679edbee5bf21481fae0000000000000000000000004221eb734ecbbb279f356679edbee5bf21481fae000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff1b8bd40f333a3daf9f2f5326e11ae38ca74249000000000000000000000000ff1b8bd40f333a3daf9f2f5326e11ae38ca74249000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13937,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000adbc690ea8138a409cfaf4ad20c4687d437a8b7d000000000000000000000000adbc690ea8138a409cfaf4ad20c4687d437a8b7d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7cd515939a31a2880bf4d98ff01d0c98fe06c89000000000000000000000000d7cd515939a31a2880bf4d98ff01d0c98fe06c89000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9d046134839453197704912587376e4d6fd4173000000000000000000000000b9d046134839453197704912587376e4d6fd4173000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ff1bd9e54a04c1d3a506ce65a310257165cfc1e0000000000000000000000007ff1bd9e54a04c1d3a506ce65a310257165cfc1e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13941,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006be80aa1185f13ad6413892a8cb011fe98607ad20000000000000000000000006be80aa1185f13ad6413892a8cb011fe98607ad2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13942,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007061ff738f5a687391033dfac6a13b319d01853c0000000000000000000000007061ff738f5a687391033dfac6a13b319d01853c0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a7f3bb21c1294ce86363c749d863de828fd8a420000000000000000000000008a7f3bb21c1294ce86363c749d863de828fd8a42000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13944,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b87445dae401ee96d23c1a764df0e51f5c0c7e00000000000000000000000000b87445dae401ee96d23c1a764df0e51f5c0c7e00000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13945,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc619ccbe3767e9879795f503bdc307bf0471cdf000000000000000000000000dc619ccbe3767e9879795f503bdc307bf0471cdf000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13946,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d446d0f677aabc963e45a7e0282794dd382a56cb000000000000000000000000d446d0f677aabc963e45a7e0282794dd382a56cb000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13947,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c65af1aed293190166f140040c519264b82d97d3000000000000000000000000c65af1aed293190166f140040c519264b82d97d3000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13948,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000013738ebdd225434c565d57166e557ce07e49f57a00000000000000000000000013738ebdd225434c565d57166e557ce07e49f57a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13949,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055c74e5d2e12ff0a0aeafd8ddc4cc438b3ec490a00000000000000000000000055c74e5d2e12ff0a0aeafd8ddc4cc438b3ec490a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13950,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003699c0bdeb3d7489ef9123947afa7de57552226b0000000000000000000000003699c0bdeb3d7489ef9123947afa7de57552226b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13951,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea22ec383782641db5112198c11b1f782c1bb0b1000000000000000000000000ea22ec383782641db5112198c11b1f782c1bb0b1000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008760e69e17351123d13d2a9102d3d787bed1206c0000000000000000000000008760e69e17351123d13d2a9102d3d787bed1206c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ce972a8b898a1ec6f6a1f2254065a2e8edc943f0000000000000000000000006ce972a8b898a1ec6f6a1f2254065a2e8edc943f0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13954,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000072cd5ab60d1494759ba1b76d8bbc732ae0e7a52700000000000000000000000072cd5ab60d1494759ba1b76d8bbc732ae0e7a527000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13955,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dcb876ccb0408266f75fe8ce7d19f15a5a25dc68000000000000000000000000dcb876ccb0408266f75fe8ce7d19f15a5a25dc68000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13956,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001905bc213f329050fccfd8688a37f072c0ad522e0000000000000000000000001905bc213f329050fccfd8688a37f072c0ad522e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13957,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008a434cc9e0171d0dffc624268c34bc21fa827fcb0000000000000000000000008a434cc9e0171d0dffc624268c34bc21fa827fcb000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004596fe685ee632aec056a39801c5c7cac7489f2f0000000000000000000000004596fe685ee632aec056a39801c5c7cac7489f2f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043b438a636f6b7b5119caf80d0847f79b9f51b2200000000000000000000000043b438a636f6b7b5119caf80d0847f79b9f51b22000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13960,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a638b0cda2eb11f6481d93f49c9399c19e65ce94000000000000000000000000a638b0cda2eb11f6481d93f49c9399c19e65ce94000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054007de4177bdeb85934fd2d1b58b1082b6fb7bb00000000000000000000000054007de4177bdeb85934fd2d1b58b1082b6fb7bb000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001517de48b5afccc8c676fdd99d0a6c4b1a1506a60000000000000000000000001517de48b5afccc8c676fdd99d0a6c4b1a1506a60000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c10c3d54383c213b87bd41cc78f4a813d8cea24a000000000000000000000000c10c3d54383c213b87bd41cc78f4a813d8cea24a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13964,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e59a8903894d1871765123a8e0e4a9188ce0bdf0000000000000000000000002e59a8903894d1871765123a8e0e4a9188ce0bdf000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0a661b2648b4a39af50ca869ea718e9379df487000000000000000000000000f0a661b2648b4a39af50ca869ea718e9379df487000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d615d68db3b7f5a9ee4223e9cf4e213e56cb5412000000000000000000000000d615d68db3b7f5a9ee4223e9cf4e213e56cb5412000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13967,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ad1c55b19ad189562ab039198bc5259e41598ab0000000000000000000000000ad1c55b19ad189562ab039198bc5259e41598ab000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e431058e8937788e0a2b22a3037dd6c7243ec260000000000000000000000000e431058e8937788e0a2b22a3037dd6c7243ec260000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9cf89096b79fc10ef3f175c5094dba8219dcad4000000000000000000000000a9cf89096b79fc10ef3f175c5094dba8219dcad4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13970,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d72a737be8c884a5f93908b7257d1e5d186ec987000000000000000000000000d72a737be8c884a5f93908b7257d1e5d186ec987000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000070e8e9e531eba77eddd0c6c42080a077254e435400000000000000000000000070e8e9e531eba77eddd0c6c42080a077254e43540000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000910b8e7f2e20e6899ad8d94b20aac648140213fe000000000000000000000000910b8e7f2e20e6899ad8d94b20aac648140213fe0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13973,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000491cdd0df6458128de36676840b9f03e13444d68000000000000000000000000491cdd0df6458128de36676840b9f03e13444d6800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a049828c4c731619b712a85f7206c97654c98588000000000000000000000000a049828c4c731619b712a85f7206c97654c9858800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051352c34e58a430d0e2dd96baea5076b956d543200000000000000000000000051352c34e58a430d0e2dd96baea5076b956d54320000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004950c1b741e7db211c9934dc1c8af912e0af6d010000000000000000000000004950c1b741e7db211c9934dc1c8af912e0af6d010000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b6cf92855c9e36b82babc001dfae0ae00837edf0000000000000000000000003b6cf92855c9e36b82babc001dfae0ae00837edf0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13978,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bb1236ea6dafe4e96e9f89c19e1cfbe080bd26e0000000000000000000000004bb1236ea6dafe4e96e9f89c19e1cfbe080bd26e0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13980,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000731bdb08cdb43b510d5d65e41568325c2122c0b2000000000000000000000000731bdb08cdb43b510d5d65e41568325c2122c0b20000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c43d5475758ae9dc53b5e586b6354cd2787dd603000000000000000000000000c43d5475758ae9dc53b5e586b6354cd2787dd6030000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13983,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc4fca3ce3571bfb598c475a95dedb02bee8feff000000000000000000000000cc4fca3ce3571bfb598c475a95dedb02bee8feff0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13984,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d63559f3fd761efc2eb35bb8bdd2fa95fb5cd446000000000000000000000000d63559f3fd761efc2eb35bb8bdd2fa95fb5cd446000000000000000000000000000000000000000000000000008286015568797400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ad549234d500b79608264ac69ed358f66e244e80000000000000000000000000ad549234d500b79608264ac69ed358f66e244e80000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13986,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038084c3d816529d0909cfcff6c56a4da3f308d0300000000000000000000000038084c3d816529d0909cfcff6c56a4da3f308d030000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5d24542b2538f0c2b3eb291e7cdf0f3d5516a73000000000000000000000000f5d24542b2538f0c2b3eb291e7cdf0f3d5516a730000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13988,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096b09c83e56efb894f9b37483b79d569e143ed1d00000000000000000000000096b09c83e56efb894f9b37483b79d569e143ed1d000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +13989,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc232401ff59c1457123a1b59e2da06c3b0c6102000000000000000000000000dc232401ff59c1457123a1b59e2da06c3b0c610200000000000000000000000000000000000000000000000000a46c1987f592c500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x44718591410e8a6134882fcfabc04a84a4dfe4e9b0bad5472b42e76806550087,2022-02-12 07:14:02.000 UTC,0,true +14011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b30096786fd20835715ddca2b60c0ec5343ca26a000000000000000000000000b30096786fd20835715ddca2b60c0ec5343ca26a000000000000000000000000000000000000000000000000008a7a17d8aa4dcd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14012,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003be5a478c352e786f747dcf2f77048460da198b30000000000000000000000003be5a478c352e786f747dcf2f77048460da198b300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fbea2829b51ff4c5f202beae970075847baaba40000000000000000000000002fbea2829b51ff4c5f202beae970075847baaba400000000000000000000000000000000000000000000000001534c920cb8909400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14015,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000435115b69f6c7377453e7122cce8ce645af30dc5000000000000000000000000435115b69f6c7377453e7122cce8ce645af30dc5000000000000000000000000000000000000000000000000001fb1dd3c16180000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14017,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017738112576aa140e29b3b68d21269ef6bff7a4300000000000000000000000017738112576aa140e29b3b68d21269ef6bff7a430000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14018,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003d60664aec76bb0ad73690f59a299dd0510b4dc00000000000000000000000003d60664aec76bb0ad73690f59a299dd0510b4dc0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14019,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fcecd9bf045f00dd5d826b091a13c8fc516938b0000000000000000000000000fcecd9bf045f00dd5d826b091a13c8fc516938b00000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14020,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae0fc1f7bd56fca484820e28435f060bb1d12d05000000000000000000000000ae0fc1f7bd56fca484820e28435f060bb1d12d050000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006e8ed0e05741f50f71550aa557b0f8deb406d7c00000000000000000000000006e8ed0e05741f50f71550aa557b0f8deb406d7c0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3b97b496d641d2c2123b8f2cd0cb07b4419b0c1000000000000000000000000a3b97b496d641d2c2123b8f2cd0cb07b4419b0c10000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ffabe7d64185bc2d73e53d533d501e21a6877f90000000000000000000000003ffabe7d64185bc2d73e53d533d501e21a6877f90000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a556b2ee089f046d986e61fd6d0facebb3abfd86000000000000000000000000a556b2ee089f046d986e61fd6d0facebb3abfd860000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b833a762c2d7dd4d1c0ef82a182ed892195f5546000000000000000000000000b833a762c2d7dd4d1c0ef82a182ed892195f55460000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080a6e3295723d9497bd9927433a21e8ae6b5d8a800000000000000000000000080a6e3295723d9497bd9927433a21e8ae6b5d8a80000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9c39034b4df95c96fb8c413755a2b6611fec832000000000000000000000000f9c39034b4df95c96fb8c413755a2b6611fec8320000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000423c207e9ca9797fa420f657ee8a68947d9a1fb9000000000000000000000000423c207e9ca9797fa420f657ee8a68947d9a1fb90000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000212ca1bdbeab58d4ece78a6c1fdbe95d23a7bea3000000000000000000000000212ca1bdbeab58d4ece78a6c1fdbe95d23a7bea30000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de0eb11d50dd1a53a10554e9172c7efe6495a113000000000000000000000000de0eb11d50dd1a53a10554e9172c7efe6495a1130000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14031,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b660eb39b1dc18330be9efdb91e4928ebc41d7df000000000000000000000000b660eb39b1dc18330be9efdb91e4928ebc41d7df0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14032,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b5aed04415ebe946cb366d088edf914fc66f0050000000000000000000000003b5aed04415ebe946cb366d088edf914fc66f0050000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc69cd67c58d7349d5648fdd2ea30e1564e20bdf000000000000000000000000bc69cd67c58d7349d5648fdd2ea30e1564e20bdf0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14034,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d27473941c088ffbf1f79dbd784fc64db783b1a6000000000000000000000000d27473941c088ffbf1f79dbd784fc64db783b1a60000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb544a124126a6d9ea07e8e94ac5a5fb0721c955000000000000000000000000eb544a124126a6d9ea07e8e94ac5a5fb0721c9550000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14038,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9054b28d9bf8861a3caba7b1d5160596587cbd5000000000000000000000000e9054b28d9bf8861a3caba7b1d5160596587cbd50000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14039,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ee6119eb22f6f73a8ff42a2f7f591b6a8b332aa0000000000000000000000003ee6119eb22f6f73a8ff42a2f7f591b6a8b332aa0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14040,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000583dc6999c5db47a477143b85a3cdfbd65bf3cc0000000000000000000000000583dc6999c5db47a477143b85a3cdfbd65bf3cc00000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14041,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040aa839408d7c4a0bb7c4d03a8859f8d7c7a586200000000000000000000000040aa839408d7c4a0bb7c4d03a8859f8d7c7a58620000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14042,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1bcbd688e0c9f853f3a0d04654dd769c624848b000000000000000000000000e1bcbd688e0c9f853f3a0d04654dd769c624848b0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14044,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fca4727873be4b050026ecc4e3d555f246f762d0000000000000000000000002fca4727873be4b050026ecc4e3d555f246f762d0000000000000000000000000000000000000000000000000000fed27d5f880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14045,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a88efd6d2014aa6351f03129e233169288688080000000000000000000000002a88efd6d2014aa6351f03129e233169288688080000000000000000000000000000000000000000000000000017db32e1655d8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14046,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e9057e00024172126a37395118f49214dabd7910000000000000000000000009e9057e00024172126a37395118f49214dabd7910000000000000000000000000000000000000000000000000006a9be44aa103d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14048,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0deac064652083d2d39d331a9931218fac6c517000000000000000000000000b0deac064652083d2d39d331a9931218fac6c517000000000000000000000000000000000000000000000000001fd36cd60b4b4300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14049,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000daf896a9888df3827737f29e8f8ba128a4026bce000000000000000000000000daf896a9888df3827737f29e8f8ba128a4026bce000000000000000000000000000000000000000000000002c5da7142cfe0185900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14052,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000068f180fcce6836688e9084f035309e29bf0a2095000000000000000000000000485b29c2ce1e8ab267dfb1f66ae1d79ae65597ab000000000000000000000000485b29c2ce1e8ab267dfb1f66ae1d79ae65597ab000000000000000000000000000000000000000000000000000000000048e3f200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xee72b1d1d7aebcafec0a9913de0243fb5a4fd6f2f2536e257310f3de73a08501,2021-11-25 12:38:06.000 UTC,0,true +14055,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f16247eaec7517320ca3121619702c119039ede5000000000000000000000000f16247eaec7517320ca3121619702c119039ede500000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000292cca8955b726a53c7ad7facea051f42d88f8a5000000000000000000000000292cca8955b726a53c7ad7facea051f42d88f8a5000000000000000000000000000000000000000000000000015e57e0f451770000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14060,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007e9a33df66d96a441f5783ce4bbd002fe14d6a42000000000000000000000000000000000000000000000000056a97255b65b0ec,,,1,true +14061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea24f605ff7a7faff0ec68859e9d28b21228aea7000000000000000000000000ea24f605ff7a7faff0ec68859e9d28b21228aea7000000000000000000000000000000000000000000000000009fdf42f6e4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14064,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b06fabe92cc26f03ecc7d42ebc02201a06bccc0d000000000000000000000000b06fabe92cc26f03ecc7d42ebc02201a06bccc0d0000000000000000000000000000000000000000000000152ad43133965561d300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a8167145a4b67c64c76d1a56ae713abee0a1e8f0000000000000000000000005a8167145a4b67c64c76d1a56ae713abee0a1e8f00000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14068,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076288be212c272dd56dc9a73f1a25d2151dbb2c800000000000000000000000076288be212c272dd56dc9a73f1a25d2151dbb2c8000000000000000000000000000000000000000000000000003a2cee48243e5b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14070,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f8a95c3213f1226385ad0d750a0dd0b73b501930000000000000000000000006f8a95c3213f1226385ad0d750a0dd0b73b501930000000000000000000000000000000000000000000000000036a3ed159101df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14071,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c4ca96d4e63af64fb7896ab41e0aa871a59fabb0000000000000000000000000c4ca96d4e63af64fb7896ab41e0aa871a59fabb000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14072,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8fe303642401cfbb750b435854ceff9aa21fde6000000000000000000000000e8fe303642401cfbb750b435854ceff9aa21fde600000000000000000000000000000000000000000000000000a142b73870b7fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14073,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000124c2c231a8bc7967c78172f51ea419e256fe1a9000000000000000000000000124c2c231a8bc7967c78172f51ea419e256fe1a9000000000000000000000000000000000000000000000000057f74bfda81e90900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e53ade7d9a62adc6e5ec926272d508ce8729f056000000000000000000000000e53ade7d9a62adc6e5ec926272d508ce8729f056000000000000000000000000000000000000000000000000001a662a2d75dd9900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078f28811eaf483a50a2c1776040a6189c3e5b28a00000000000000000000000078f28811eaf483a50a2c1776040a6189c3e5b28a0000000000000000000000000000000000000000000000000161e638c671a18700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5c6ac0f966d2159b20f39d400ecb320b94d52167e9f3359a4eeffb786f03900f,2022-02-20 22:51:55.000 UTC,0,true +14079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c04d107c3f21d215772ead8af02d3f4f2321fcd4000000000000000000000000c04d107c3f21d215772ead8af02d3f4f2321fcd400000000000000000000000000000000000000000000000000009fc776c6100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c04d107c3f21d215772ead8af02d3f4f2321fcd4000000000000000000000000c04d107c3f21d215772ead8af02d3f4f2321fcd400000000000000000000000000000000000000000000000000677dd80f86d73e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000bfe98ba61eb224f657d392333f213f6d75cc6972000000000000000000000000bfe98ba61eb224f657d392333f213f6d75cc6972000000000000000000000000000000000000000000000000000000001d5b950d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000030288b14c84a10ee2c3391da1f680482b6ef1f6a00000000000000000000000030288b14c84a10ee2c3391da1f680482b6ef1f6a000000000000000000000000000000000000000000000000000000001d72bdf600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000009508ef3443ef753e5ccf158bf7a8a6e2f5de56c00000000000000000000000009508ef3443ef753e5ccf158bf7a8a6e2f5de56c0000000000000000000000000000000000000000000000000000000001d79f68200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14084,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000e53ff2dbbc64a45f21c020feeac042f5f15be390000000000000000000000000e53ff2dbbc64a45f21c020feeac042f5f15be39000000000000000000000000000000000000000000000000000000001d798ce800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14085,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000df6526993e056e43241bdc9c8711cd2de2e5cc13000000000000000000000000df6526993e056e43241bdc9c8711cd2de2e5cc13000000000000000000000000000000000000000000000000000000001d6ebc3d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051e6e92e81c9ac173d45390f5f5bf9463ffd3ca000000000000000000000000051e6e92e81c9ac173d45390f5f5bf9463ffd3ca000000000000000000000000000000000000000000000000001419e3759e1976100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000787e5e1f40881ddec138253d9735ac5207659096000000000000000000000000787e5e1f40881ddec138253d9735ac520765909600000000000000000000000000000000000000000000000000046a9a6083205500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f1687c086e7565c96b395f484c42aad406e6c140000000000000000000000000f1687c086e7565c96b395f484c42aad406e6c1400000000000000000000000000000000000000000000000000b5ef79e5c9a0d400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0905e088343a54e7ff334f8fb6bd47293852c499d4bc992fc01202a43b6e60b3,2021-12-25 18:00:46.000 UTC,0,true +14095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d49e5771bea214f10a31ac160e6159717481c432000000000000000000000000d49e5771bea214f10a31ac160e6159717481c432000000000000000000000000000000000000000000000000017fb16d83be000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e95c0a312687e01bd27f62d56d80f2ff71c2cb11000000000000000000000000e95c0a312687e01bd27f62d56d80f2ff71c2cb110000000000000000000000000000000000000000000000000150d6e367d3c8d500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14099,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000009f626dbfc2a3b9e140ee7b6c317ed6b60e0f33bc0000000000000000000000009f626dbfc2a3b9e140ee7b6c317ed6b60e0f33bc000000000000000000000000000000000000000000000000000000001cc1864b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa198d6248a2cb1d7c3a37bc15aed5a29df99e4e4f6782e906d90f2d3b080e247,2022-07-29 23:23:29.000 UTC,0,true +14100,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008aef8de06aa03916eccd39d7552c81bbdf2693490000000000000000000000008aef8de06aa03916eccd39d7552c81bbdf26934900000000000000000000000000000000000000000000000000c73be88a799d5b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066f0b8003010bc8fc592879ef700509d937f542300000000000000000000000066f0b8003010bc8fc592879ef700509d937f54230000000000000000000000000000000000000000000000000083470522a942d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14102,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e81669100000000000000000000000001a145c9338cad4720149cda57d2178d7906829900000000000000000000000001a145c9338cad4720149cda57d2178d7906829900000000000000000000000000000000000000000000000070e0b4640846e11000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14103,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fba1425c65f42f8c3178d6c4738efa55de814d50000000000000000000000004fba1425c65f42f8c3178d6c4738efa55de814d5000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da3d7dbb9fe32ed3b4455ba0507b9c66b4607710000000000000000000000000da3d7dbb9fe32ed3b4455ba0507b9c66b460771000000000000000000000000000000000000000000000000000dfcf68ae79960a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x91bb9cda780df4023f05acb666e3fc1a16b78113c224d399b15de06cb0fd8646,2022-03-05 05:30:07.000 UTC,0,true +14106,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7a7c1cfc1d66ea62b9c06b0a1b05f8e835c76c8000000000000000000000000d7a7c1cfc1d66ea62b9c06b0a1b05f8e835c76c8000000000000000000000000000000000000000000000000003ff2e795f5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd3a4551595e189ca77a59fe73acefd9afbefd4480827485f2a8d43d06aefc4bf,2022-06-28 07:00:56.000 UTC,0,true +14107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c4ca96d4e63af64fb7896ab41e0aa871a59fabb0000000000000000000000000c4ca96d4e63af64fb7896ab41e0aa871a59fabb000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14110,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dce8c8cc21841b1b257c6683fd4778a902c68c69000000000000000000000000dce8c8cc21841b1b257c6683fd4778a902c68c69000000000000000000000000000000000000000000000000001af43b103a96c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14113,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e81669100000000000000000000000051f033a3eaf8e446bacd1b0a0c4f5c1dd783292200000000000000000000000051f033a3eaf8e446bacd1b0a0c4f5c1dd783292200000000000000000000000000000000000000000000000070df7fb51b387ee000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14114,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e60d9c72c5ec15136b942525407d07527f2df2b7000000000000000000000000e60d9c72c5ec15136b942525407d07527f2df2b700000000000000000000000000000000000000000000000e5e5b8a4d481c42b100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14115,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ed78d87d23c6df3c879fa185e4e45f285b756dc0000000000000000000000004ed78d87d23c6df3c879fa185e4e45f285b756dc000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x176fa3118f5eea5b70e943cbe719f8909c3f7e79c9cc95b61027ac376ed8ef13,2022-01-31 19:02:14.000 UTC,0,true +14116,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007362aba7c2667bf2dad14111de0252cf848dc2e60000000000000000000000007362aba7c2667bf2dad14111de0252cf848dc2e600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e1f00ed84b2796bf54c44f7b2a1739005a978788000000000000000000000000e1f00ed84b2796bf54c44f7b2a1739005a978788000000000000000000000000000000000000000000000000019d10b6e1245adc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14123,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000258da40e011acb8e0f6308d6dda4de363c9b604000000000000000000000000000000000000000000000004ef3aacc1f6d7965b,,,1,true +14124,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000258da40e011acb8e0f6308d6dda4de363c9b6040000000000000000000000000258da40e011acb8e0f6308d6dda4de363c9b604000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14127,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a8e7b7197e94d2cb194dbed7a80575c047a75750000000000000000000000007a8e7b7197e94d2cb194dbed7a80575c047a757500000000000000000000000000000000000000000000000003f2cc7a70f7f90f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14128,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004020cfce02de3c10b440ec0f229ee583c456a81e0000000000000000000000004020cfce02de3c10b440ec0f229ee583c456a81e000000000000000000000000000000000000000000000000000073ca600c320000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000175d7ac3844ac969c1d17431e59ff057ad17ee3b000000000000000000000000175d7ac3844ac969c1d17431e59ff057ad17ee3b00000000000000000000000000000000000000000000000000006c71476e403d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a34417c1837171910f4d72ad4876a83e9d3103c9000000000000000000000000a34417c1837171910f4d72ad4876a83e9d3103c9000000000000000000000000000000000000000000000000009eb2a15263458300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056279d1110c8adf39b2cf8e8657356d0854a5bbf00000000000000000000000056279d1110c8adf39b2cf8e8657356d0854a5bbf0000000000000000000000000000000000000000000000000207f5bed76f0adc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d57f561135ea6fd6b2f37627dd836c1d7162ff0b000000000000000000000000d57f561135ea6fd6b2f37627dd836c1d7162ff0b0000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14137,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055e7b3038aa65781ff936221447e2b6caa4a4e8b00000000000000000000000055e7b3038aa65781ff936221447e2b6caa4a4e8b0000000000000000000000000000000000000000000000000019d3c8e9c9c1c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001892ccee554fb70d50f96e42f287c155980bd8800000000000000000000000001892ccee554fb70d50f96e42f287c155980bd88000000000000000000000000000000000000000000000000009a8fc50ef2542600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14142,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032fd820024c3c6aac07b7aa58986961c94fa1f3800000000000000000000000032fd820024c3c6aac07b7aa58986961c94fa1f380000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14144,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9038d842354fd62d5604eefab491ec0a60b3869000000000000000000000000a9038d842354fd62d5604eefab491ec0a60b38690000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098f990ef129d59a3e511fa6471cab60c215cdfeb00000000000000000000000098f990ef129d59a3e511fa6471cab60c215cdfeb00000000000000000000000000000000000000000000000003782dace9d9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x67f9e7a9ce31ab98561f0e49b387c30ea556fbffac0445d5cf56409702ee0cbd,2021-12-26 23:14:47.000 UTC,0,true +14148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f12f8d68c75d4d8852808e1be5cd8cf7776ef2d0000000000000000000000000f12f8d68c75d4d8852808e1be5cd8cf7776ef2d0000000000000000000000000000000000000000000000000004402aaea81858b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000043c7df1186687da64730999e727a7ca668ec719000000000000000000000000043c7df1186687da64730999e727a7ca668ec7190000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039d2d986dd5bfa5afb50a292b681f984591e7ebd00000000000000000000000039d2d986dd5bfa5afb50a292b681f984591e7ebd0000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14152,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f26988ede871862233aed3773572ae22e6195e3b000000000000000000000000f26988ede871862233aed3773572ae22e6195e3b0000000000000000000000000000000000000000000000000046e96616fef20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ea39e9a3cf88258befd321bb747a20ab8a4b33b0000000000000000000000002ea39e9a3cf88258befd321bb747a20ab8a4b33b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14157,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000262dca9b8906e73923736ba7ef71b0ff10f2da7a000000000000000000000000262dca9b8906e73923736ba7ef71b0ff10f2da7a0000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14158,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8c89e3cfe798e7dee53acfd61bc31355cceecb3000000000000000000000000e8c89e3cfe798e7dee53acfd61bc31355cceecb30000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e6a8ca6bf0dfaa5e0c27be2fa32d8f242b3be9f0000000000000000000000006e6a8ca6bf0dfaa5e0c27be2fa32d8f242b3be9f000000000000000000000000000000000000000000000000005b3a0ecd8d9c2e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b39d44640438d2dff075e8046569ef0f8d3510ed000000000000000000000000b39d44640438d2dff075e8046569ef0f8d3510ed0000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14161,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f809a9b799697b4fdd656c29deac20ed55d330b0000000000000000000000006f809a9b799697b4fdd656c29deac20ed55d330b00000000000000000000000000000000000000000000000006ede09beedce60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14162,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc2e7d827c788005ba971599d7f7dc911673a6f5000000000000000000000000bc2e7d827c788005ba971599d7f7dc911673a6f500000000000000000000000000000000000000000000000000901b15612cccd900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007174c6cf7fa9c714feb89575c9431815cd595aa30000000000000000000000007174c6cf7fa9c714feb89575c9431815cd595aa30000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14164,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000986a1de622305f441a3c763036ca06da417ffff40000000000000000000000000000000000000000000000002602dc56002bb0c7,,,1,true +14165,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2c02702ea8f4fe7b8325e9d613a2ba99454f9ff000000000000000000000000d2c02702ea8f4fe7b8325e9d613a2ba99454f9ff0000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b98fc0a7c413db271f93dd03aa828d6359564266000000000000000000000000b98fc0a7c413db271f93dd03aa828d635956426600000000000000000000000000000000000000000000000004d2131d003ea32300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14167,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d344a3e06ef05ffe63ec09472ca8dd9f01d05d00000000000000000000000006d344a3e06ef05ffe63ec09472ca8dd9f01d05d000000000000000000000000000000000000000000000000002c5536b24d12f8300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbfc9275b6bc817d565df2ccb9db4b2d89cc39f509bcd5d2b64e0f96a88c5be17,2021-12-20 08:12:21.000 UTC,0,true +14168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000faec9e70cba0b0f174cbab4b1c19b6cb7cfca25e000000000000000000000000faec9e70cba0b0f174cbab4b1c19b6cb7cfca25e0000000000000000000000000000000000000000000000000063a07b7f306a6d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14169,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee970cd2aee28778c1bd384283c80c50c19f1616000000000000000000000000ee970cd2aee28778c1bd384283c80c50c19f16160000000000000000000000000000000000000000000000002dc84eb27b7fb30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee64532f1b2e2d32a9ed45689e879c04f9e5d648000000000000000000000000ee64532f1b2e2d32a9ed45689e879c04f9e5d64800000000000000000000000000000000000000000000000000730b5bae13705d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14175,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000182527962c891ef2b4cacec7b06618c902314bb3000000000000000000000000182527962c891ef2b4cacec7b06618c902314bb3000000000000000000000000000000000000000000000000004e3c0536bfe1fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005cfaa12bbe1d09f29b4ccf91f795a7386b92b6250000000000000000000000005cfaa12bbe1d09f29b4ccf91f795a7386b92b625000000000000000000000000000000000000000000000000007c20bc202cceb900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009511bab567161d053b43f56f416b113aba3e7c1d0000000000000000000000009511bab567161d053b43f56f416b113aba3e7c1d00000000000000000000000000000000000000000000000000a4391f86a6b2e700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14179,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000755aaa8fe876d7d6c28c8988ad0912150f72abce0000000000000000000000000000000000000000000000001b30390dbc701540,,,1,true +14180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3904f1a245dba803b6c5370da750988d475f4bd000000000000000000000000e3904f1a245dba803b6c5370da750988d475f4bd0000000000000000000000000000000000000000000000000364145bedf2353d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5e1e0fafe09bfe954f33f32fc624f0b2e2caaa3000000000000000000000000d5e1e0fafe09bfe954f33f32fc624f0b2e2caaa300000000000000000000000000000000000000000000000001e165fda8dc549e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c50c278d4f3714919b046a01981698685093b470000000000000000000000006c50c278d4f3714919b046a01981698685093b4700000000000000000000000000000000000000000000000001d9dfebed4fa88400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14187,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001dba9923efb6b28612f3a7ba90ece5657a1941250000000000000000000000000000000000000000000000004563918244f40000,,,1,true +14188,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d3ed789252bac04595ee5903d8a2421c43353030000000000000000000000000d3ed789252bac04595ee5903d8a2421c433530300000000000000000000000000000000000000000000000000399d9f8ade478400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14190,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000095346e29fbee4c60bfa00d4e2d1912d579cdc76f00000000000000000000000095346e29fbee4c60bfa00d4e2d1912d579cdc76f0000000000000000000000000000000000000000000000000000000013d9f78e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14192,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000edba99b8c5c6e1b9c8a9b34fcd00505d8511f913000000000000000000000000edba99b8c5c6e1b9c8a9b34fcd00505d8511f91300000000000000000000000000000000000000000000000000027ca57357c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14193,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033d14308158623a785b6e85a30e64dbb16b4ceed00000000000000000000000033d14308158623a785b6e85a30e64dbb16b4ceed000000000000000000000000000000000000000000000000005e13b8fbe80a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff3883b3b82528bccfce4356cefaa6d7d07e4fc2000000000000000000000000ff3883b3b82528bccfce4356cefaa6d7d07e4fc200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1afea5a1d95982e4ebafa878b93feded22dc374000000000000000000000000f1afea5a1d95982e4ebafa878b93feded22dc374000000000000000000000000000000000000000000000000020ab2b0dcd6910000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcb8de44e72d0049d8008cf758682db09ea3982f4ccc1a1b7aafc4bb87a39bb14,2022-04-27 12:47:38.000 UTC,0,true +14207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ddf13201064ecae004306594c670acc7ac519aa0000000000000000000000004ddf13201064ecae004306594c670acc7ac519aa0000000000000000000000000000000000000000000000000017b341b4c97b2900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e9e0079c3b4003e4cb34b4e3fbd4a9f3482c6d80000000000000000000000007e9e0079c3b4003e4cb34b4e3fbd4a9f3482c6d80000000000000000000000000000000000000000000000000003b1843925e0f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14209,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001d08b5667c9de15b5ab40f882d2bff6deae2c83d000000000000000000000000000000000000000000000000b0723a590433f979,,,1,true +14212,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000639eb289710d1ae2165ac0e76d02b739644883d2000000000000000000000000639eb289710d1ae2165ac0e76d02b739644883d2000000000000000000000000000000000000000000000000004380663abb800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14214,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e81669100000000000000000000000026afa302c9d2f7659ecf800c0c606fd7faea16f300000000000000000000000026afa302c9d2f7659ecf800c0c606fd7faea16f300000000000000000000000000000000000000000000000821ab0d441498000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xbc6a9dc7db85adaf9f19f15e884727fd2e63981fdf80afe775cefbc93de590aa,2022-06-02 02:24:06.000 UTC,0,true +14215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d17fc86bc9d50872df4d2b10d8855e1965a6baca000000000000000000000000d17fc86bc9d50872df4d2b10d8855e1965a6baca00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a63e1239cea6c90107dbd1a8fe127be73efe2582000000000000000000000000a63e1239cea6c90107dbd1a8fe127be73efe258200000000000000000000000000000000000000000000000000810e1660b89f6d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14226,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f530a21ecc87cfaf169ab2be3bf1766bb77a49df000000000000000000000000f530a21ecc87cfaf169ab2be3bf1766bb77a49df000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14229,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0b481823ce1fd808f2196a2af17239f0f458b25000000000000000000000000f0b481823ce1fd808f2196a2af17239f0f458b2500000000000000000000000000000000000000000000000000226519828c8fc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14230,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9cd2daac4e0ebcf2da51705a0f02eee13072c3c000000000000000000000000b9cd2daac4e0ebcf2da51705a0f02eee13072c3c0000000000000000000000000000000000000000000000000003baca8ce3520000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049e1f9a244765bce02d3af4799da414c0256092600000000000000000000000049e1f9a244765bce02d3af4799da414c02560926000000000000000000000000000000000000000000000000012ff7a1125a66f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cbfe5c2219bac8f00b3a4d6220cea26e4f8e14d0000000000000000000000007cbfe5c2219bac8f00b3a4d6220cea26e4f8e14d00000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000007cbfe5c2219bac8f00b3a4d6220cea26e4f8e14d0000000000000000000000007cbfe5c2219bac8f00b3a4d6220cea26e4f8e14d0000000000000000000000000000000000000000000000000000000007dd977500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f560f36da0a8e73467f6561203762cd73f5caf2c000000000000000000000000f560f36da0a8e73467f6561203762cd73f5caf2c00000000000000000000000000000000000000000000000000e0d1ab747abac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a39653495ac64cdd4d63da235750ea7d7d88d553000000000000000000000000a39653495ac64cdd4d63da235750ea7d7d88d5530000000000000000000000000000000000000000000000000000fd38d4e8750000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fbb51d6e0f91c6fac1045a7e4c851d88b8ee5450000000000000000000000008fbb51d6e0f91c6fac1045a7e4c851d88b8ee5450000000000000000000000000000000000000000000000000001e19a5a3ef80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14240,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000093b59660f7aca23ae0371a1cc85ab1f9698895e000000000000000000000000093b59660f7aca23ae0371a1cc85ab1f9698895e000000000000000000000000000000000000000000000000000313f471c7cf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14241,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d89ed93e36f45f2c619aa690732f52e1bdd4aec0000000000000000000000008d89ed93e36f45f2c619aa690732f52e1bdd4aec000000000000000000000000000000000000000000000000000313f471c7cf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14242,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006fab7bc5ebb46220eaa77b88b4a574233f76e1ee0000000000000000000000006fab7bc5ebb46220eaa77b88b4a574233f76e1ee000000000000000000000000000000000000000000000000000313f471c7cf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14243,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ee7f67b307365ccc216311d61e6faad0265090f0000000000000000000000008ee7f67b307365ccc216311d61e6faad0265090f000000000000000000000000000000000000000000000000000313f471c7cf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dbbcf0aee88ef5e75d55b74faaa65fea2eb0be43000000000000000000000000dbbcf0aee88ef5e75d55b74faaa65fea2eb0be4300000000000000000000000000000000000000000000000000032cc657e6760000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14245,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ef6ef03a9f085953ca84b56c440a25dbc86aa4d0000000000000000000000006ef6ef03a9f085953ca84b56c440a25dbc86aa4d0000000000000000000000000000000000000000000000000002fbf1b7288f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f6c94056f2ce538fc150156c328697a7c4aabb10000000000000000000000008f6c94056f2ce538fc150156c328697a7c4aabb1000000000000000000000000000000000000000000000000000356e4c7a2cf0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14247,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dff81dc1364bbfe7a2c9ba48e992cd38d54787f7000000000000000000000000dff81dc1364bbfe7a2c9ba48e992cd38d54787f7000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033f68ebe57cf7d4010a7ca183e9da103791aeee300000000000000000000000033f68ebe57cf7d4010a7ca183e9da103791aeee30000000000000000000000000000000000000000000000000004c2b90fffc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14249,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc8dc4bfbb815b4625e27ab2944b9f34c1da0db8000000000000000000000000cc8dc4bfbb815b4625e27ab2944b9f34c1da0db800000000000000000000000000000000000000000000000004d1d2f32bd0971e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3bd721db7f7a260ab1766d24ae5381485bb78dc000000000000000000000000f3bd721db7f7a260ab1766d24ae5381485bb78dc0000000000000000000000000000000000000000000000000004f032983ce00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14258,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049aa1d51f3b20599921f1f970ffda42361a6e0be00000000000000000000000049aa1d51f3b20599921f1f970ffda42361a6e0be00000000000000000000000000000000000000000000000000739540706ab17d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007196ccdc9ba6214492e165a5dda53e20de5b53520000000000000000000000007196ccdc9ba6214492e165a5dda53e20de5b53520000000000000000000000000000000000000000000000000ddce46a6801760000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14261,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062c42f0479fb731712b3ee290fe4e9178d79143b00000000000000000000000062c42f0479fb731712b3ee290fe4e9178d79143b00000000000000000000000000000000000000000000000000745e03f38b0cfe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14264,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9d498434b722855f14388fb2d734c4bbefaaae1000000000000000000000000e9d498434b722855f14388fb2d734c4bbefaaae100000000000000000000000000000000000000000000000001434f7128416f0a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xdda35a643081731901945991976d454328d82a62d7727e50b3ada41d5c5fe39f,2022-05-23 21:08:52.000 UTC,0,true +14265,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000da21dc5e01ef214adf55124fcc0b310c5832191b000000000000000000000000da21dc5e01ef214adf55124fcc0b310c5832191b000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xebeb558cbf0ed0c082dfe27c58d32155cf03c7b0a5b506fdc1647a518592a35d,2022-08-18 10:11:48.000 UTC,0,true +14268,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e2cb253d7af60c49a3cc906ca3ea38916e1938a0000000000000000000000006e2cb253d7af60c49a3cc906ca3ea38916e1938a000000000000000000000000000000000000000000000000007fc199088c0d5a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002185c428ee0ddbb23003dfb7b849ace5b86c4faa0000000000000000000000002185c428ee0ddbb23003dfb7b849ace5b86c4faa00000000000000000000000000000000000000000000000000000000000f541300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14279,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000169c4f390548ac0d3ed22b0c18e5c2a294b642a9000000000000000000000000169c4f390548ac0d3ed22b0c18e5c2a294b642a90000000000000000000000000000000000000000000000056e47e29fe29c0a3900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be55369bfbfd4bccf13bd197ee7b1165c0b7a4f8000000000000000000000000be55369bfbfd4bccf13bd197ee7b1165c0b7a4f8000000000000000000000000000000000000000000000000000de0a8a7fe51d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002134240c7041ce4a50dcef6c40db82ec158793700000000000000000000000002134240c7041ce4a50dcef6c40db82ec158793700000000000000000000000000000000000000000000000000015fd3edd34ef2100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14287,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084509b4d29d486a55fa5e4c096848d286c7a027a00000000000000000000000084509b4d29d486a55fa5e4c096848d286c7a027a00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000969fba502f1c11d869676739c0a4dcb9a5ad95b2000000000000000000000000969fba502f1c11d869676739c0a4dcb9a5ad95b20000000000000000000000000000000000000000000000000137f806f2b775f600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x704389f2ce140b906e33c94945beffd0e4f65cdf1fdf02df01b6489762bdda44,2022-03-12 07:39:33.000 UTC,0,true +14291,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000003f396735af8b4046d7de08ad8449f4db6f253f600000000000000000000000003f396735af8b4046d7de08ad8449f4db6f253f6000000000000000000000000000000000000000000000010904258cdee9b91c300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x387c89dad0f684d3028029b0a36c0e9d60b99b81dc4a2a3bd8c7679a4d467833,2021-12-21 11:56:19.000 UTC,0,true +14292,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006250900f938cff02c43276af05badc2d06c1da5f0000000000000000000000006250900f938cff02c43276af05badc2d06c1da5f00000000000000000000000000000000000000000000000000807350737cc83a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14293,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000581f900fb75d4c37416f1d3ad86b815b4d07a884000000000000000000000000581f900fb75d4c37416f1d3ad86b815b4d07a8840000000000000000000000000000000000000000000000000093e1ab906375ac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xaf3664e632f72e7a43e49bfd4963965a3c0b7b3824fbf336798bfdb507af7b61,2021-12-16 11:56:03.000 UTC,0,true +14294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012b3e17ee9bcf90763d11b67f3029ce54ea8ff0300000000000000000000000012b3e17ee9bcf90763d11b67f3029ce54ea8ff03000000000000000000000000000000000000000000000000002bab2eedbe86dc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14295,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b389b98659d17ec8c264b523064e246bb464e755000000000000000000000000b389b98659d17ec8c264b523064e246bb464e755000000000000000000000000000000000000000000000000004a9b638448800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14296,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000db5050691e32aaecb39946674737fb87c6230c15000000000000000000000000db5050691e32aaecb39946674737fb87c6230c150000000000000000000000000000000000000000000000000e043da61725000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14298,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d60efe9e4560bf32a785c39923caef1d580a0edd000000000000000000000000d60efe9e4560bf32a785c39923caef1d580a0edd0000000000000000000000000000000000000000000000000e043da61725000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14299,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006710f4d73f116f7204629d511dbfff128f6aed290000000000000000000000006710f4d73f116f7204629d511dbfff128f6aed2900000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14300,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006710f4d73f116f7204629d511dbfff128f6aed290000000000000000000000006710f4d73f116f7204629d511dbfff128f6aed2900000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002185c428ee0ddbb23003dfb7b849ace5b86c4faa0000000000000000000000002185c428ee0ddbb23003dfb7b849ace5b86c4faa0000000000000000000000000000000000000000000000000000246139ca800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14302,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015c3d6298743e3115df3794f6da20ec4079d1eee00000000000000000000000015c3d6298743e3115df3794f6da20ec4079d1eee0000000000000000000000000000000000000000000000000dbd2fc137a3000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db5050691e32aaecb39946674737fb87c6230c15000000000000000000000000db5050691e32aaecb39946674737fb87c6230c1500000000000000000000000000000000000000000000000000001402462f600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14304,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d60efe9e4560bf32a785c39923caef1d580a0edd000000000000000000000000d60efe9e4560bf32a785c39923caef1d580a0edd0000000000000000000000000000000000000000000000000000246139ca800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d60efe9e4560bf32a785c39923caef1d580a0edd000000000000000000000000d60efe9e4560bf32a785c39923caef1d580a0edd0000000000000000000000000000000000000000000000000000246139ca800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14306,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ad4217cb594fe7a49cfa0daeb5556ea61ee45a88000000000000000000000000ad4217cb594fe7a49cfa0daeb5556ea61ee45a880000000000000000000000000000000000000000000000000f43fc2c04ee000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14308,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004cf8c6f3a6653704cfa718b348588fda44f1d57d0000000000000000000000004cf8c6f3a6653704cfa718b348588fda44f1d57d0000000000000000000000000000000000000000000000000f43fc2c04ee000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14309,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028723161c5d1f50a9acb947c1633678f899910f700000000000000000000000028723161c5d1f50a9acb947c1633678f899910f70000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14312,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000071ecf0b8b63ad6498e8adcb893e57173c474c8e900000000000000000000000071ecf0b8b63ad6498e8adcb893e57173c474c8e90000000000000000000000000000000000000000000000000e92596fd629000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14314,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000038d4cdf4b69aa2960974d3dd3d5318524c8c0e2000000000000000000000000038d4cdf4b69aa2960974d3dd3d5318524c8c0e200000000000000000000000000000000000000000000000000e0b58a360b2000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14316,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000dfd5b125b629758c01047752917564521c98afa2000000000000000000000000dfd5b125b629758c01047752917564521c98afa20000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c2ef1173a4b051bbcc4474c407bbb2ac7e02e363000000000000000000000000c2ef1173a4b051bbcc4474c407bbb2ac7e02e3630000000000000000000000000000000000000000000000000095617a016b654000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14318,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f7c200fec2cb4695b87e40bfbf8bd7dc52400635000000000000000000000000f7c200fec2cb4695b87e40bfbf8bd7dc524006350000000000000000000000000000000000000000000000000e6ed27d6668000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14322,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ba07c823f84bb2aa1cfda61cfa957750f2cf0022000000000000000000000000ba07c823f84bb2aa1cfda61cfa957750f2cf002200000000000000000000000000000000000000000000002d72f355c2fca1385e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b700e3039076924b6f801c72893810fe1ea44425000000000000000000000000b700e3039076924b6f801c72893810fe1ea444250000000000000000000000000000000000000000000000000007d10fc719190000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14325,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000382d2640a2838c8757feef06cb233f181a1d1eb9000000000000000000000000382d2640a2838c8757feef06cb233f181a1d1eb900000000000000000000000000000000000000000000000000adf429bd7327f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14327,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f90715df94c96b6b4ede0b4f0731afd6a78b7b80000000000000000000000003f90715df94c96b6b4ede0b4f0731afd6a78b7b80000000000000000000000000000000000000000000000000068607749b6ce0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x20552df6e2ae30ea2ec22d852499e7569cbbeb0bed61e79d4f0666f7fe42dd8c,2022-05-20 12:41:28.000 UTC,0,true +14328,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009995dbde9a62e939b14c4236a9b027e3349bd05e0000000000000000000000009995dbde9a62e939b14c4236a9b027e3349bd05e0000000000000000000000000000000000000000000000000063bbe0ca22e69100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14330,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000108ac19fa07d24a49965dccd53dc505ad3bf5acd000000000000000000000000108ac19fa07d24a49965dccd53dc505ad3bf5acd0000000000000000000000000000000000000000000000000140ddf0477868c900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14331,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1aa11bb98e70000aac020045bc011db35097163000000000000000000000000b1aa11bb98e70000aac020045bc011db3509716300000000000000000000000000000000000000000000000000674cde2405ad0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14332,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c99f3b968b7a8c88414c266c4bd199bb1c7eb86c000000000000000000000000c99f3b968b7a8c88414c266c4bd199bb1c7eb86c000000000000000000000000000000000000000000000000013c53923ac6b94000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14333,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000885541c875019bc0d2dcd7576fe3d531efd5cb48000000000000000000000000885541c875019bc0d2dcd7576fe3d531efd5cb480000000000000000000000000000000000000000000000000dddb122417f8a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14335,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c66cbebd9a8c00be01bde46d3d2d82d5b0630f04000000000000000000000000c66cbebd9a8c00be01bde46d3d2d82d5b0630f04000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14336,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcd522547f34273cb52886f5df5c65cf9381055a000000000000000000000000bcd522547f34273cb52886f5df5c65cf9381055a000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8a09bf413576a2e8b406dae09732aae29a1c8d4000000000000000000000000f8a09bf413576a2e8b406dae09732aae29a1c8d40000000000000000000000000000000000000000000000000020842cfe24e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e6b87ff2168d15794a865d09a6716415e7dbecf0000000000000000000000003e6b87ff2168d15794a865d09a6716415e7dbecf00000000000000000000000000000000000000000000000000212d60393f1f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14341,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f4d0137d8433943cb58c4db97ef81a23eb9170c0000000000000000000000002f4d0137d8433943cb58c4db97ef81a23eb9170c000000000000000000000000000000000000000000000000000000174876e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14343,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e365f00be0d20be799f89555dad65287fbcfb6cb000000000000000000000000e365f00be0d20be799f89555dad65287fbcfb6cb0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14344,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d4875bd28c8fc049b3cd5fb1c62dbf3e954a8be0000000000000000000000007d4875bd28c8fc049b3cd5fb1c62dbf3e954a8be000000000000000000000000000000000000000000000000001c161164ac1aae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f341966266afeb6d6ab89a0e9683ebd108692c20000000000000000000000008f341966266afeb6d6ab89a0e9683ebd108692c20000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14348,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f341966266afeb6d6ab89a0e9683ebd108692c20000000000000000000000008f341966266afeb6d6ab89a0e9683ebd108692c20000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14350,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000907e8fef030bb24d63a6a3ee60e2aeca999540a2000000000000000000000000907e8fef030bb24d63a6a3ee60e2aeca999540a2000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14354,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000676dac4935496dc09d51f3fbe8eab36d02155360000000000000000000000000676dac4935496dc09d51f3fbe8eab36d0215536000000000000000000000000000000000000000000000000003658b282e3d2a4e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3dcc314cc33f56ba4caad3d2885a5c23149923e000000000000000000000000c3dcc314cc33f56ba4caad3d2885a5c23149923e0000000000000000000000000000000000000000000000000037ddc65a30f7b600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14363,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006add6a3a49c1583a3ecb62b3de1dbae9604b1dff0000000000000000000000006add6a3a49c1583a3ecb62b3de1dbae9604b1dff00000000000000000000000000000000000000000000000000670758aa7c800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd0ed299556ffbb495b4fd6a92106bf0b5e36fdeb2dbea6f90da495def0197a3a,2022-05-08 23:47:24.000 UTC,0,true +14364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0ba1356f184df2ec47d79cd69d144d985eaf625000000000000000000000000e0ba1356f184df2ec47d79cd69d144d985eaf62500000000000000000000000000000000000000000000000000c5105aa657689200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fecc81fff6ad516b005ce8b4cdb36d485ac252b4000000000000000000000000fecc81fff6ad516b005ce8b4cdb36d485ac252b40000000000000000000000000000000000000000000000000126789f618167e100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067248f105749b60045d89869c33b8bec986897eb00000000000000000000000067248f105749b60045d89869c33b8bec986897eb00000000000000000000000000000000000000000000000000a64c45d0fc9b2900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5ecb25122e36b7b6816b50c100dda189c1857e8000000000000000000000000a5ecb25122e36b7b6816b50c100dda189c1857e80000000000000000000000000000000000000000000000000001ca39b9894f5b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d657419b9eeb14472a76472d4269d3a9686f065f000000000000000000000000d657419b9eeb14472a76472d4269d3a9686f065f000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000277cb0775eb752862118987414944448b87bc679000000000000000000000000277cb0775eb752862118987414944448b87bc6790000000000000000000000000000000000000000000000000043364b4ffc5d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14373,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c4d9d599a339f292560fa120d71875893d9a2af0000000000000000000000000c4d9d599a339f292560fa120d71875893d9a2af000000000000000000000000000000000000000000000000000000e8d4a5100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000702f25a8c9c090239be779b567e5246ebb7e31cd000000000000000000000000702f25a8c9c090239be779b567e5246ebb7e31cd00000000000000000000000000000000000000000000000003e2c284391c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004103d6215ed19eb868a16eaff7baabd82dbb9ace0000000000000000000000004103d6215ed19eb868a16eaff7baabd82dbb9ace000000000000000000000000000000000000000000000000018d75ff0c716a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef7b11bb7d88d3b42e866fd40d0a974c9ed78188000000000000000000000000ef7b11bb7d88d3b42e866fd40d0a974c9ed781880000000000000000000000000000000000000000000000000182fae4463195cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14378,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003e23505d4c3a701c6ae843a3bd48997a7376fb400000000000000000000000003e23505d4c3a701c6ae843a3bd48997a7376fb40000000000000000000000000000000000000000000000000000f6da1673ef0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14381,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000d0be70667943e357bb9be0f224854561d9909847000000000000000000000000d0be70667943e357bb9be0f224854561d990984700000000000000000000000000000000000000000000000000000000021f597800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed4df5ffa42559caa3905500e9e9e3e0eaf06d12000000000000000000000000ed4df5ffa42559caa3905500e9e9e3e0eaf06d120000000000000000000000000000000000000000000000000a5bc62c2184d68800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14385,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004807cc1ea844f4e600848767bc5ad16a560bcb34000000000000000000000000000000000000000000000000bf5c1cb3f7d9cd3f,,,1,true +14387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9fe2d0c9c90ad3c90cc267c7d1da44bb4e4a4ff000000000000000000000000c9fe2d0c9c90ad3c90cc267c7d1da44bb4e4a4ff00000000000000000000000000000000000000000000000001307539711f6d7d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f058b1f37596d606ac8585cbf197f692720d11b1000000000000000000000000f058b1f37596d606ac8585cbf197f692720d11b1000000000000000000000000000000000000000000000000003817283252a59400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000658555cc8ff249c73ffd823cb1ede7b38c0a7f93000000000000000000000000658555cc8ff249c73ffd823cb1ede7b38c0a7f9300000000000000000000000000000000000000000000000001604f011ec5ec0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acad92fe0f90820b3300f64436be3cbd5d2af725000000000000000000000000acad92fe0f90820b3300f64436be3cbd5d2af72500000000000000000000000000000000000000000000000000c71029e928694500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bd142068e4220649ae629677ff1f073a48733330000000000000000000000004bd142068e4220649ae629677ff1f073a48733330000000000000000000000000000000000000000000000000587bb5d63f4c3d400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6d6533a41f5c5dd4d10cef8a008217b3a6532a2000000000000000000000000d6d6533a41f5c5dd4d10cef8a008217b3a6532a200000000000000000000000000000000000000000000000000675324e54aa50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000956331dc229f59643b2d1ef680f3a8442ba60921000000000000000000000000956331dc229f59643b2d1ef680f3a8442ba6092100000000000000000000000000000000000000000000000000d88da4bdf9e3ee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x71769dae020ed4a2930388f30e8594da2280559e5cb8fc123b0bf718a442750a,2022-06-03 16:08:24.000 UTC,0,true +14403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000eb47fa16f2d2c911cd615124776fe0545f775520000000000000000000000000eb47fa16f2d2c911cd615124776fe0545f775520000000000000000000000000000000000000000000000000000000000c7f923900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d969eec40f3c0497a221a0c0e19313dddfd5e167000000000000000000000000d969eec40f3c0497a221a0c0e19313dddfd5e1670000000000000000000000000000000000000000000000000b79c1e56ceb6a0e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14409,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000017e3c0330d2eaffc8a21acae5db958c50950bc0a00000000000000000000000017e3c0330d2eaffc8a21acae5db958c50950bc0a000000000000000000000000000000000000000000000000000000002c4e64f900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d97e7a71824ae41ae4606762e06885eccb287e80000000000000000000000005d97e7a71824ae41ae4606762e06885eccb287e8000000000000000000000000000000000000000000000000015ac213ac7dd7cc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x929e90cd3813eaf4a27b20d5a65d9095894570f79bea62fef849455537610d0e,2022-08-26 19:36:40.000 UTC,0,true +14413,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032d5802d32ba81b28c85c6ab2d02867bd8c757d700000000000000000000000032d5802d32ba81b28c85c6ab2d02867bd8c757d7000000000000000000000000000000000000000000000000007b446d11c82b8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000047034b82573d3ed0cd16d01dfb70881b3af4d92000000000000000000000000047034b82573d3ed0cd16d01dfb70881b3af4d9200000000000000000000000000000000000000000000000000a00d56eb8b3e0100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f9ec6b671f30ff554bc8ef93b7f111260e1b80a0000000000000000000000009f9ec6b671f30ff554bc8ef93b7f111260e1b80a00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008dc6e176391948aeb4aadf817e081d68dd20a2980000000000000000000000008dc6e176391948aeb4aadf817e081d68dd20a29800000000000000000000000000000000000000000000000000374a7309a7f7bf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c43d79baeba1acb896b4e35f02615eb25c3e4aa0000000000000000000000000c43d79baeba1acb896b4e35f02615eb25c3e4aa000000000000000000000000000000000000000000000000008684f9d2c3d34000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14425,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000311d07b222519bff34bd42c032478ea98b5e6eee000000000000000000000000311d07b222519bff34bd42c032478ea98b5e6eee00000000000000000000000000000000000000000000000000000000a1963f0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047930c76790c865217472f2ddb4d14c640ee450a00000000000000000000000047930c76790c865217472f2ddb4d14c640ee450a0000000000000000000000000000000000000000000000000014e9c5db57b30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009da89e29ab90c95efb8b4aa30825c7bfdbab80b80000000000000000000000009da89e29ab90c95efb8b4aa30825c7bfdbab80b8000000000000000000000000000000000000000000000000036fad342d8c265800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x375d461b39ac7451ae71488c6b2de06db498c9b1c270a93438933a3f45e8cf02,2022-02-22 20:58:51.000 UTC,0,true +14433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3513c1261d7c9470c064bf3c7b80a8cb8a24e86000000000000000000000000f3513c1261d7c9470c064bf3c7b80a8cb8a24e8600000000000000000000000000000000000000000000000000da7f62d85f6af900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x23100f30018e81430c2f95211cddcaf70527253e0d555fab27d9773227309661,2022-05-24 20:22:46.000 UTC,0,true +14434,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009148fcc2b78bb12f960fd5c7bd5421b80d832cce0000000000000000000000009148fcc2b78bb12f960fd5c7bd5421b80d832cce00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x51a55607bd5ee7841f417aa637d6e5f9bf6fd00905627afc8b73f5463a342a16,2022-04-03 20:58:51.000 UTC,0,true +14435,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd14cec791a6e925d482ed1205132bdf1e7ed74e000000000000000000000000bd14cec791a6e925d482ed1205132bdf1e7ed74e000000000000000000000000000000000000000000000000005c7dac57b9783f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14438,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010e75f657fd34d9217e2a87ec30ccbbb23d0b5f300000000000000000000000010e75f657fd34d9217e2a87ec30ccbbb23d0b5f3000000000000000000000000000000000000000000000000003c6675a706db0400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ede97d279dabb60410b8ef0d8884a53a6f33a331000000000000000000000000ede97d279dabb60410b8ef0d8884a53a6f33a331000000000000000000000000000000000000000000000000020e4159b2aface800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x09b5a4735b4178c0eea46c86ae226532c01ea4c380cb357b9632620aa1b697fb,2021-12-19 04:17:46.000 UTC,0,true +14440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d867554fb5e44d0b120b5019dfcd20999fd43690000000000000000000000002d867554fb5e44d0b120b5019dfcd20999fd4369000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14441,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009512b8c1b63c9893258920b5998134a1261db85d0000000000000000000000009512b8c1b63c9893258920b5998134a1261db85d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006f5eea1e20e69c5db953db53267d0ab99b98bb030000000000000000000000006f5eea1e20e69c5db953db53267d0ab99b98bb030000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006141ee2a0f53255c79b629e2830b9ab2617c76a00000000000000000000000006141ee2a0f53255c79b629e2830b9ab2617c76a0000000000000000000000000000000000000000000000000005e6e8b56941fbd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ef5011856fb7a0d837340afc30522459a3899420000000000000000000000006ef5011856fb7a0d837340afc30522459a38994200000000000000000000000000000000000000000000000001787a68c02fd26900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006871f7b5822439d13d37bfbcde61944e10863fe50000000000000000000000006871f7b5822439d13d37bfbcde61944e10863fe500000000000000000000000000000000000000000000000000000002540be40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14449,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f988e0c45ee66006b7d815eeb3dd2c06b28ed1bc00000000000000000000000000000000000000000000000098a7d9b8314c0000,,,1,true +14452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3712bac7a9070647a4f7a0e671bbd1640857418000000000000000000000000a3712bac7a9070647a4f7a0e671bbd1640857418000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14455,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000652330a1285f96e29053964913605a77acea38cb000000000000000000000000652330a1285f96e29053964913605a77acea38cb0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c899506db8549f1a1864e1938e290c90538c9990000000000000000000000000c899506db8549f1a1864e1938e290c90538c99900000000000000000000000000000000000000000000000000232053e3433655700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x96d748df3ed5cd2f16982d60ce28dac62f21b015a42d459077a066847298982a,2021-12-19 04:39:48.000 UTC,0,true +14457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008123b9fc439e224387710d5443e0ba65741758ef0000000000000000000000008123b9fc439e224387710d5443e0ba65741758ef00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14458,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c431c7a0a3b877c5dd2c01280da5f3bbe4054944000000000000000000000000c431c7a0a3b877c5dd2c01280da5f3bbe40549440000000000000000000000000000000000000000000000000cf55d4d7a1aff6300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073b368c00bbbdaa25846d9c4530d32562ddb879200000000000000000000000073b368c00bbbdaa25846d9c4530d32562ddb87920000000000000000000000000000000000000000000000000005543df729c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14461,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000049063afec15f575944003e46ce5d614feeed99e000000000000000000000000049063afec15f575944003e46ce5d614feeed99e00000000000000000000000000000000000000000000000001588df28ad6e11a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000528aa39abab48b2dad03abe397be201a08bba8bf000000000000000000000000528aa39abab48b2dad03abe397be201a08bba8bf0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfff7e57d91cbed35aaaa168fe4bf94bce120393000000000000000000000000cfff7e57d91cbed35aaaa168fe4bf94bce120393000000000000000000000000000000000000000000000000001b3fcd19a0c58000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14464,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb374b5829edc474f2fe713b05342f331b23f17e000000000000000000000000cb374b5829edc474f2fe713b05342f331b23f17e000000000000000000000000000000000000000000000000022f2f6689d416ec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5b0e94a000cafc48f6e8c8353a5f44de015ae8e28f8f3c1fd96da43d9acf682d,2021-12-19 04:44:20.000 UTC,0,true +14465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc58a9eea6360167a0c3e81b13404a9b9b8803f0000000000000000000000000bc58a9eea6360167a0c3e81b13404a9b9b8803f0000000000000000000000000000000000000000000000000001ea533966d99c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002bb524649296a6b8bede1cccf3b327852975e9b50000000000000000000000002bb524649296a6b8bede1cccf3b327852975e9b50000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fab7efa4514a401f212b494c9cc4dfe28a8bd9ad000000000000000000000000fab7efa4514a401f212b494c9cc4dfe28a8bd9ad00000000000000000000000000000000000000000000000003311fc80a57000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3ffdae3a7a1edf932391f02ce22c9bf040402109f8244922015311fd3721ec0e,2021-11-27 02:45:46.000 UTC,0,true +14469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aaade03035337dc4e64c9df724817ff0bf162acd000000000000000000000000aaade03035337dc4e64c9df724817ff0bf162acd0000000000000000000000000000000000000000000000000188c0c5241224a300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9c0420c9b944a003d45b66f17d0c384e35b2139000000000000000000000000e9c0420c9b944a003d45b66f17d0c384e35b2139000000000000000000000000000000000000000000000000005fbdb13b34508900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8808a771cf983d0ef33b2f8d1e34701ef5abf17000000000000000000000000a8808a771cf983d0ef33b2f8d1e34701ef5abf170000000000000000000000000000000000000000000000000200203500f0ea4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b2616fdcb783d326577bcd98c561bcaad16035d0000000000000000000000006b2616fdcb783d326577bcd98c561bcaad16035d00000000000000000000000000000000000000000000000002000632a11cb34000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020b4c93fcc01db24666e7a3b1c1737527a4339fa00000000000000000000000020b4c93fcc01db24666e7a3b1c1737527a4339fa000000000000000000000000000000000000000000000000003de9f054d2417300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be79ced87649ea760589f56829dafc9f2c1cd6f2000000000000000000000000be79ced87649ea760589f56829dafc9f2c1cd6f20000000000000000000000000000000000000000000000000033387f911b4e6200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ac350ec997e3efb3d3253a77ea8a8f3a4eb95c00000000000000000000000006ac350ec997e3efb3d3253a77ea8a8f3a4eb95c000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ab6012234a086b3312100f0299c93cff21c24cd0000000000000000000000004ab6012234a086b3312100f0299c93cff21c24cd00000000000000000000000000000000000000000000000000137a2786dd02cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14477,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e05898253609dc3b63fd71bb9d28243b1767abf0000000000000000000000003e05898253609dc3b63fd71bb9d28243b1767abf00000000000000000000000000000000000000000000000000566674f653250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14478,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f0ac690ae67ee389ef8b521758a4d5c13922c080000000000000000000000008f0ac690ae67ee389ef8b521758a4d5c13922c0800000000000000000000000000000000000000000000000000df6491915ca9c700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14479,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002825ad2da5aa9356aed20d2aa876813d50d4bfd80000000000000000000000002825ad2da5aa9356aed20d2aa876813d50d4bfd80000000000000000000000000000000000000000000000000032ba50559c760000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14481,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003aa44ddc54f9ab8e82c0a457035097f53c8641780000000000000000000000003aa44ddc54f9ab8e82c0a457035097f53c86417800000000000000000000000000000000000000000000000000573ab10f2c220000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b5f7c521eda2259aa12620a25cd71789e6471ca0000000000000000000000003b5f7c521eda2259aa12620a25cd71789e6471ca00000000000000000000000000000000000000000000000000133041c11fff2a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14483,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029bea86ecb22fbf7f5cb764fdfd40f13199302ab00000000000000000000000029bea86ecb22fbf7f5cb764fdfd40f13199302ab0000000000000000000000000000000000000000000000000015c3d5b22cddd400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b32e99470c494256e3683493be6edbd6b943a0ed000000000000000000000000b32e99470c494256e3683493be6edbd6b943a0ed0000000000000000000000000000000000000000000000000016ac5bb2eeb47700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14486,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068d8882ab5b5ac332f5636a02808c8addd94882900000000000000000000000068d8882ab5b5ac332f5636a02808c8addd9488290000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14487,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b7b80c8c25bea60f3d08d73dc7f5be827764ef00000000000000000000000005b7b80c8c25bea60f3d08d73dc7f5be827764ef000000000000000000000000000000000000000000000000000da4bec5dfc2d6400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x01c6b46140a84777df79a4759fb84f2e83d8406965a395c14051560115d86eb9,2022-06-01 02:19:39.000 UTC,0,true +14489,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1812222b05e44b90e0771f3d84387e2bfd981d0000000000000000000000000a1812222b05e44b90e0771f3d84387e2bfd981d00000000000000000000000000000000000000000000000000016ac9c7dcb74f600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f83fc1f2a97e5f014188775e228de9044ce98af6000000000000000000000000f83fc1f2a97e5f014188775e228de9044ce98af600000000000000000000000000000000000000000000000001f08f4e10c456fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000080fc7793deb839d65a0d233d1ba6fec97444fcf000000000000000000000000080fc7793deb839d65a0d233d1ba6fec97444fcf000000000000000000000000000000000000000000000000000012309ce5400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14493,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d683f0f3c665488c2faaf11db87fab24e8ff0c80000000000000000000000004d683f0f3c665488c2faaf11db87fab24e8ff0c8000000000000000000000000000000000000000000000000003744e99d0c8c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c3112778f18924da2c30dd865ab492a44990a190000000000000000000000004c3112778f18924da2c30dd865ab492a44990a190000000000000000000000000000000000000000000000000016d9a1753ee81000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e21c83d1c3af9d1f3aea34863f576e97581e5953000000000000000000000000e21c83d1c3af9d1f3aea34863f576e97581e59530000000000000000000000000000000000000000000000000001476b081e800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e21333b29bad2e7471ec30658a693bda4d65d2ff000000000000000000000000e21333b29bad2e7471ec30658a693bda4d65d2ff00000000000000000000000000000000000000000000000000138113e4944af200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14497,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003daed5bcaaa96264f1da7d092079dab6947dbc8f0000000000000000000000003daed5bcaaa96264f1da7d092079dab6947dbc8f000000000000000000000000000000000000000000000000001083c0ac5ebdad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058863b10a5e7efe698b2546b3e91cbc28c06c81300000000000000000000000058863b10a5e7efe698b2546b3e91cbc28c06c813000000000000000000000000000000000000000000000000006122ac0656ba4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005eae41614a92e9cd5a017494fdb86df65672cb200000000000000000000000005eae41614a92e9cd5a017494fdb86df65672cb2000000000000000000000000000000000000000000000000000afde251fbcfc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5aaf71264632b23af10a95c48a89bcb9d09c6d2000000000000000000000000d5aaf71264632b23af10a95c48a89bcb9d09c6d2000000000000000000000000000000000000000000000000000002ba7def300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14502,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075565fd255dce7d7c7911b38a26c841b850c1ca500000000000000000000000075565fd255dce7d7c7911b38a26c841b850c1ca5000000000000000000000000000000000000000000000000002c160232714b3300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14503,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048e91697f0cbbcafd1f3e53b25af7720c07ca0be00000000000000000000000048e91697f0cbbcafd1f3e53b25af7720c07ca0be0000000000000000000000000000000000000000000000000012645398b7887800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000590ed1d0352a17fe5c7d5fb81d9df5b5e6233a75000000000000000000000000590ed1d0352a17fe5c7d5fb81d9df5b5e6233a75000000000000000000000000000000000000000000000000002ab4384cf51de600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bc5102023fa952e470720983633d74c400d73440000000000000000000000004bc5102023fa952e470720983633d74c400d734400000000000000000000000000000000000000000000000000153a661757f05700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6bf88d7a74498f1bdb76fc917e4b6d259d12419000000000000000000000000e6bf88d7a74498f1bdb76fc917e4b6d259d12419000000000000000000000000000000000000000000000000004773c3d7812f5b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14508,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000862f5898ab9c9574cbdee239fce21cac6fd1c2d0000000000000000000000000862f5898ab9c9574cbdee239fce21cac6fd1c2d000000000000000000000000000000000000000000000000000195b4073dea4f400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14509,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008890799c9a1e9ece844d8271347643843583087f0000000000000000000000008890799c9a1e9ece844d8271347643843583087f0000000000000000000000000000000000000000000000000021b532ce3a560100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a98d86ec1ebdd9122110aeff9ead46deefb09ce0000000000000000000000001a98d86ec1ebdd9122110aeff9ead46deefb09ce0000000000000000000000000000000000000000000000000015efcaa1d4268100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14511,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dfbd3dfa1c72cd64ecc504b97c111926ea3b94d7000000000000000000000000dfbd3dfa1c72cd64ecc504b97c111926ea3b94d70000000000000000000000000000000000000000000000000015ab2c0301005600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14513,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086a7f79b8f6d9c7542dc0c0f26ec52e1be7da90000000000000000000000000086a7f79b8f6d9c7542dc0c0f26ec52e1be7da9000000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14514,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1d94fcdb66dec18ece038bba08f4a465f630449000000000000000000000000b1d94fcdb66dec18ece038bba08f4a465f630449000000000000000000000000000000000000000000000000007e7a4792a6d5d800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009fd1adb1f6d760b020f65940e56a59338cbff54c0000000000000000000000009fd1adb1f6d760b020f65940e56a59338cbff54c00000000000000000000000000000000000000000000000000c547ec8b15161400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000067fc64e8681e590ddd35285c13d1fcb89deeb12000000000000000000000000067fc64e8681e590ddd35285c13d1fcb89deeb12000000000000000000000000000000000000000000000000032f198d4374dd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14517,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002aaf4e90520baeca9cdfed9ea92c5fa71993192a0000000000000000000000002aaf4e90520baeca9cdfed9ea92c5fa71993192a00000000000000000000000000000000000000000000000000153f302b7266a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006dc8583a625298aaa8671b70eb3ce3b86197a5cb0000000000000000000000006dc8583a625298aaa8671b70eb3ce3b86197a5cb000000000000000000000000000000000000000000000000018309b07b25e90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9b80769cc2efa99fbee48904e980523622b09b8c441abfd596d0c2fb33ccc16c,2022-03-04 08:04:03.000 UTC,0,true +14520,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9471b4ec137853a1b5cae871bd6de9a8b08c5cf000000000000000000000000c9471b4ec137853a1b5cae871bd6de9a8b08c5cf0000000000000000000000000000000000000000000000000015b1d1baaea8c100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14521,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc1dcaf774304ff2fa7920836c95400b237f349f000000000000000000000000fc1dcaf774304ff2fa7920836c95400b237f349f000000000000000000000000000000000000000000000000001322c1dea952aa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14523,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041fa8cf2ae231a7e76881b935d374b4237aa998300000000000000000000000041fa8cf2ae231a7e76881b935d374b4237aa998300000000000000000000000000000000000000000000000000a10aa109566b3600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14524,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000181a81e54da038370a88b95f5b6e352c27c5bdac000000000000000000000000181a81e54da038370a88b95f5b6e352c27c5bdac00000000000000000000000000000000000000000000000000a9b12a19f1451100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbe0f8569175eeffdae9592eb9c3ec921bb0f18b227ba2004a76db2426261572b,2022-03-17 06:34:23.000 UTC,0,true +14525,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000302380cf390d95136ea80b5efe6366c11b32cb51000000000000000000000000302380cf390d95136ea80b5efe6366c11b32cb5100000000000000000000000000000000000000000000000000b6c452b8246fd200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14526,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004774978adbd9a017e8f42ef1be55c2c058450fb30000000000000000000000004774978adbd9a017e8f42ef1be55c2c058450fb3000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14527,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002671b78e7cb60779e5409c588c9c11fa2ccbd34c0000000000000000000000002671b78e7cb60779e5409c588c9c11fa2ccbd34c0000000000000000000000000000000000000000000000000012a3e2bbd01c1400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083940789ecf1123ecda5259d180ff4c7637c736c00000000000000000000000083940789ecf1123ecda5259d180ff4c7637c736c0000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b41d08126deb4010da0b031d06dc543653f88329000000000000000000000000b41d08126deb4010da0b031d06dc543653f88329000000000000000000000000000000000000000000000000005ac5ada651f26a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14530,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004dc34ac1247e9d4cded76ce5cdd582804081c8fe0000000000000000000000004dc34ac1247e9d4cded76ce5cdd582804081c8fe00000000000000000000000000000000000000000000000000114ffeff82b12600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14531,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000302380cf390d95136ea80b5efe6366c11b32cb51000000000000000000000000302380cf390d95136ea80b5efe6366c11b32cb51000000000000000000000000000000000000000000000000005fd9e6dc0b553000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14532,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af583fe68440eec623fc223ebfc84d2ba75c9acf000000000000000000000000af583fe68440eec623fc223ebfc84d2ba75c9acf0000000000000000000000000000000000000000000000000015322f9510cad600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000018c0ccd1b42a9781481d97a4b73ba8962b9f4d9000000000000000000000000018c0ccd1b42a9781481d97a4b73ba8962b9f4d900000000000000000000000000000000000000000000000002304d06820ef1d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x01419262a5d4aad4ef96c868a4bbd9da8653fbc8966527ed89e2ed063f30d61f,2021-12-19 04:48:04.000 UTC,0,true +14534,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3f4cf4195b6fc1601b667e524f8b9bca720f996000000000000000000000000b3f4cf4195b6fc1601b667e524f8b9bca720f9960000000000000000000000000000000000000000000000000230d900bc05b1df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xdcd6bb59974c2f284b3ccf7d8a467ec85d4352dec8111bb4d8f1f331977e2c23,2021-12-19 04:51:19.000 UTC,0,true +14535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045f99d8974120001c3300b320a266f40f1601f3900000000000000000000000045f99d8974120001c3300b320a266f40f1601f3900000000000000000000000000000000000000000000000000092456df261c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a01ca6267c599388ccd9049d5c8f69db3baab041000000000000000000000000a01ca6267c599388ccd9049d5c8f69db3baab041000000000000000000000000000000000000000000000000022e718ab8ed6fc600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xca226dca43bf3f8ceb607089e30842511812971157b6ea87103fa0c9c5ce9f63,2021-12-19 05:22:35.000 UTC,0,true +14537,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036a7a9f86189e6e548de91428304f347932e728100000000000000000000000036a7a9f86189e6e548de91428304f347932e7281000000000000000000000000000000000000000000000000001263d320a579d300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047e36a6edbcef05c3f697bab1d7d633c4ba4e49100000000000000000000000047e36a6edbcef05c3f697bab1d7d633c4ba4e49100000000000000000000000000000000000000000000000001dc104a3fe7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4eb63412bc12490d40b03106345accf2fe9dfd6f6178b5ed39996b582d539002,2021-11-28 11:56:41.000 UTC,0,true +14539,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000adfc26b6520a35c37af3ac5af174249737ec612c000000000000000000000000adfc26b6520a35c37af3ac5af174249737ec612c0000000000000000000000000000000000000000000000000082dced6e12d84a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032f83b494fc594f8e57cba39e8a0c33214073f4000000000000000000000000032f83b494fc594f8e57cba39e8a0c33214073f40000000000000000000000000000000000000000000000000022f0fad90899e9100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x009b61c67c41a9654a64f323e64230db3c8f849d332e63634a10859552aa48b7,2021-12-19 05:26:12.000 UTC,0,true +14541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7e7ebf02b8d9727f8406e97cb21ffd02250d57b000000000000000000000000a7e7ebf02b8d9727f8406e97cb21ffd02250d57b0000000000000000000000000000000000000000000000000015e41083cc00b900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14542,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007de6aa8cd9a9654145fd9869ea08816992b59c870000000000000000000000007de6aa8cd9a9654145fd9869ea08816992b59c870000000000000000000000000000000000000000000000000000034630b8a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ad865b57fb72870eb1daf309f92fb7ba327860b0000000000000000000000008ad865b57fb72870eb1daf309f92fb7ba327860b000000000000000000000000000000000000000000000000001138afa2de6fc100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5200f07ad61d09354ba78d1df1e4e1fb6ff5a14413474b6bba423a1b5ea5cae2,2022-07-30 22:41:27.000 UTC,0,true +14545,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000162a9669c0e162d9ef545efe37f70b010f4bed77000000000000000000000000162a9669c0e162d9ef545efe37f70b010f4bed77000000000000000000000000000000000000000000000000008e4030122ae39500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14546,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003df9f33d7caaf1b50cfd16738bdf308468ef0c140000000000000000000000003df9f33d7caaf1b50cfd16738bdf308468ef0c140000000000000000000000000000000000000000000000000016ad8b8140bc0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b06568d5f401012530139ece2667a5de6c85eec2000000000000000000000000b06568d5f401012530139ece2667a5de6c85eec200000000000000000000000000000000000000000000000000180d212006dce700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9c67cb03729a72237ec6205fa5e32b645cc0a6f000000000000000000000000a9c67cb03729a72237ec6205fa5e32b645cc0a6f0000000000000000000000000000000000000000000000000013a2070e82c65c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14550,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dee36b5856df7ebedc8fabcef0f86417547363bb000000000000000000000000dee36b5856df7ebedc8fabcef0f86417547363bb00000000000000000000000000000000000000000000000032cfb69b38ce453d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14551,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057e4b7d3926e8970c94bbea676e4144fcc3866f300000000000000000000000057e4b7d3926e8970c94bbea676e4144fcc3866f30000000000000000000000000000000000000000000000000000034630b8a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abc42b6a90c2a5962c1be78be7344a7d05848ee4000000000000000000000000abc42b6a90c2a5962c1be78be7344a7d05848ee400000000000000000000000000000000000000000000000001569f77dbcf766700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091b56d6bee38057e62b36eb844d793bfcca7d48600000000000000000000000091b56d6bee38057e62b36eb844d793bfcca7d48600000000000000000000000000000000000000000000000000149347a146511700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5e5f687406d072c4bcccda452f426688df7a901000000000000000000000000f5e5f687406d072c4bcccda452f426688df7a9010000000000000000000000000000000000000000000000000010c9818331419a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb57544ac7ea46db54958f8a48af53fa5546c246000000000000000000000000eb57544ac7ea46db54958f8a48af53fa5546c2460000000000000000000000000000000000000000000000000010d850f07ede7400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1007f903a8c583f8f9efa7a693d41eec2ed9bd0000000000000000000000000f1007f903a8c583f8f9efa7a693d41eec2ed9bd0000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007dc6155b6a5ec6bb0096dfc460ba69299bc7f6570000000000000000000000007dc6155b6a5ec6bb0096dfc460ba69299bc7f657000000000000000000000000000000000000000000000000003be4eebd68304000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a32265bcd45c5f7d24db5ccd9051ce6f058e1db0000000000000000000000007a32265bcd45c5f7d24db5ccd9051ce6f058e1db000000000000000000000000000000000000000000000000005e7ab05cb1304500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f26998db738b9f6658d5a47b2666549dd524bb7b000000000000000000000000f26998db738b9f6658d5a47b2666549dd524bb7b000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b8259591efce15da36232c473a83199e780a4110000000000000000000000004b8259591efce15da36232c473a83199e780a41100000000000000000000000000000000000000000000000000112e33b52acd3c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2b1d3508bb2e1d9caa5e91016847e8d73064793000000000000000000000000a2b1d3508bb2e1d9caa5e91016847e8d730647930000000000000000000000000000000000000000000000000010fe4b1ac7f41600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14565,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc9c19d3277012a9c325cf355e5719f3cd3dfcf7000000000000000000000000fc9c19d3277012a9c325cf355e5719f3cd3dfcf700000000000000000000000000000000000000000000000000001b48eb57e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14567,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003be267c19ceff4a3a303faaeee5127cb0947c60e00000000000000000000000000000000000000000000000024f73ba9dcadf3d4,,,1,true +14568,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae8e2b4abb13de393515ef5abad7e35a2b11ba6d000000000000000000000000ae8e2b4abb13de393515ef5abad7e35a2b11ba6d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4e96a73b6eba0022552641aa7f226ef3b0d5ddc63ed2583196700f0646d90f1d,2022-05-25 06:41:00.000 UTC,0,true +14570,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d87e4695d674635795966bd72a545ca54d253140000000000000000000000000d87e4695d674635795966bd72a545ca54d25314000000000000000000000000000000000000000000000000006d3350e05e9b4d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa197cbde91d0b613faac888c7b5a0220e9b0d12ec307f70fa38aff595979e6f4,2022-05-27 06:52:15.000 UTC,0,true +14572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ef01cc68a08dcdc771fcda60a402c0992ad87670000000000000000000000008ef01cc68a08dcdc771fcda60a402c0992ad87670000000000000000000000000000000000000000000000000014c8e4a2f764a100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14574,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d69de8e55e73e0b308b8c6c4424090febea5ced2000000000000000000000000d69de8e55e73e0b308b8c6c4424090febea5ced20000000000000000000000000000000000000000000000000267c26a8c021ea100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14575,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0d715b20c3df8d3859e897dab846453beee2a53000000000000000000000000a0d715b20c3df8d3859e897dab846453beee2a53000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14576,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057005a8c8639a64327ea53c05d0a8f3359adcc8d00000000000000000000000057005a8c8639a64327ea53c05d0a8f3359adcc8d000000000000000000000000000000000000000000000000000001d1a94a200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a9e7432d487cc67eaf5c909fc10f8c1257723ba0000000000000000000000005a9e7432d487cc67eaf5c909fc10f8c1257723ba000000000000000000000000000000000000000000000000013ebc0208e7765700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000442e074b32775ec36d84fe9c137074bc4e97c200000000000000000000000000442e074b32775ec36d84fe9c137074bc4e97c20000000000000000000000000000000000000000000000000001d0ef13cbb0ee6300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14582,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002bab2e743a32a054eae3f26bd921f13116ee4f7a0000000000000000000000002bab2e743a32a054eae3f26bd921f13116ee4f7a00000000000000000000000000000000000000000000000000060a24181e400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14585,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bec5c94c0ce7a6b27e5d43d8b0da2701d6393537000000000000000000000000bec5c94c0ce7a6b27e5d43d8b0da2701d639353700000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5ed8bc55129b31e4a801fda5489b27bb96ded3f000000000000000000000000c5ed8bc55129b31e4a801fda5489b27bb96ded3f0000000000000000000000000000000000000000000000000059a7c3452b4c7c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14587,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d0cd6508fd2a1baee0a0c7f596d63e23676616a0000000000000000000000003d0cd6508fd2a1baee0a0c7f596d63e23676616a000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14590,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008449f8db1a87d8105d7e1e697c3b220193e344700000000000000000000000008449f8db1a87d8105d7e1e697c3b220193e3447000000000000000000000000000000000000000000000000001c7ced19a167c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14593,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8d32f90d8283830145a95aebad1b83c565e045a000000000000000000000000e8d32f90d8283830145a95aebad1b83c565e045a000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14605,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a2f1b8d1e3bfd649811a4944d155cffb6be54260000000000000000000000000a2f1b8d1e3bfd649811a4944d155cffb6be5426000000000000000000000000000000000000000000000000015d6f8b75cbb97500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002932eb2cea773396e242423e401fba74c57ceb1d0000000000000000000000002932eb2cea773396e242423e401fba74c57ceb1d00000000000000000000000000000000000000000000000053444835ec58000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14619,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ed99802e97eb84809c07fa93f91bdddf27c61250000000000000000000000002ed99802e97eb84809c07fa93f91bdddf27c61250000000000000000000000000000000000000000000000000014d280ac5b05d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073a54e1b681dfdba14d74226e2c88090e4c61ca300000000000000000000000073a54e1b681dfdba14d74226e2c88090e4c61ca300000000000000000000000000000000000000000000000000163c0356db051000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14624,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068ed88ea02fbebd2538dadd3ba656d8e76bef5c100000000000000000000000068ed88ea02fbebd2538dadd3ba656d8e76bef5c1000000000000000000000000000000000000000000000000001752b5b30d85a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1598d77786da3748f8f6315494a88f9a190c55c000000000000000000000000b1598d77786da3748f8f6315494a88f9a190c55c0000000000000000000000000000000000000000000000000016145a9607d1ec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d0d6ec6895a73a049bb380a1feb4f58c4003a933000000000000000000000000d0d6ec6895a73a049bb380a1feb4f58c4003a93300000000000000000000000000000000000000000000000000141adddd886a0d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14630,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec83585e2cbb3b178a9b457da006867c5d14a021000000000000000000000000ec83585e2cbb3b178a9b457da006867c5d14a021000000000000000000000000000000000000000000000000001890816ca567ff00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000497eaef16a3b4ac502e0ecef0bf858228b531774000000000000000000000000497eaef16a3b4ac502e0ecef0bf858228b5317740000000000000000000000000000000000000000000000000150ecfa9e882da300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x68f01dd88f03047f6d14497e8cbda9d70d026ba24edcdf9a17dd360bdbb18359,2021-12-13 11:33:41.000 UTC,0,true +14633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff690312a3791db3597148e69ebd411c99975159000000000000000000000000ff690312a3791db3597148e69ebd411c99975159000000000000000000000000000000000000000000000000001601a6db2812d300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c8ef4aae0d0c3f1ee879ee14d2713cfcd3676470000000000000000000000001c8ef4aae0d0c3f1ee879ee14d2713cfcd3676470000000000000000000000000000000000000000000000000062fa5e90a96dc200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9dfd080ace9e813fb42d9e0ca34d07b758c8710000000000000000000000000c9dfd080ace9e813fb42d9e0ca34d07b758c8710000000000000000000000000000000000000000000000000001034fc105682cf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14636,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000555916e2b2a7b353f4d58486122587d57c9a1440000000000000000000000000555916e2b2a7b353f4d58486122587d57c9a1440000000000000000000000000000000000000000000000000011dc3242c55bc800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000748a1bea1a431a0f424dd264af25ef67a0232fce000000000000000000000000748a1bea1a431a0f424dd264af25ef67a0232fce000000000000000000000000000000000000000000000000001316eeeb5a505300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14644,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7030954e5a634bc690acd0ed59da14879bdb50b000000000000000000000000d7030954e5a634bc690acd0ed59da14879bdb50b00000000000000000000000000000000000000000000000001617cc494dff10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14646,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000934124e672e932c0f686954db57cfd3fbd1d4ff0000000000000000000000000934124e672e932c0f686954db57cfd3fbd1d4ff000000000000000000000000000000000000000000000000005deda701dcb2de00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0851f068e16184864bd5ab418791346c3df5fc2778a278e91256ca3c30b5e807,2022-03-24 08:55:09.000 UTC,0,true +14648,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c223b9c56b0433387343fc23728fda353fe50ff0000000000000000000000000c223b9c56b0433387343fc23728fda353fe50ff000000000000000000000000000000000000000000000000000550057fbe2e82a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xacd86f96c1bef309d983ecffee05b28770345f2a88cb1ba34daf8b4715f9f750,2022-04-10 09:25:02.000 UTC,0,true +14652,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c223b9c56b0433387343fc23728fda353fe50ff0000000000000000000000000c223b9c56b0433387343fc23728fda353fe50ff000000000000000000000000000000000000000000000000000508f9e3ae06a8d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9f26cc06c8d5c075d9b98bc625978008383892bf12d4ce9b3cf0d2f4095282e3,2022-04-10 09:01:34.000 UTC,0,true +14653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ea36af93f0ab4c882c9d71a5d9f04dabcdcc4fd0000000000000000000000006ea36af93f0ab4c882c9d71a5d9f04dabcdcc4fd000000000000000000000000000000000000000000000000015e8b43b43e445000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14654,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dcbc955b963534aa09572cfbe644a6f4f8b280f0000000000000000000000002dcbc955b963534aa09572cfbe644a6f4f8b280f0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000632501776bb853b435ecee64b1a99eaa4f5e2ad0000000000000000000000000632501776bb853b435ecee64b1a99eaa4f5e2ad00000000000000000000000000000000000000000000000009182356d327b92800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d8ea2af408ced89a6b09059c1f27aba3b37d1afd000000000000000000000000d8ea2af408ced89a6b09059c1f27aba3b37d1afd000000000000000000000000000000000000000000000000044443c5f165d00200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14666,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001bedb365b833dea1dcfdd2a924874da9d37c80b70000000000000000000000000000000000000000000000040c8aa6e4a42c6083,0x5c0c4ad3e8aebfa7401f18888f851734ffa293d4e730cd97e33db14656f7c5ed,2022-03-15 11:08:08.000 UTC,0,true +14667,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020a97ad799236be3e4971f1fdc9a6a42f5e7f7b900000000000000000000000020a97ad799236be3e4971f1fdc9a6a42f5e7f7b9000000000000000000000000000000000000000000000000001ed5711348e11600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d942e0ac4f140ecf3bfb223421c73ec156dfcf53000000000000000000000000d942e0ac4f140ecf3bfb223421c73ec156dfcf5300000000000000000000000000000000000000000000000000245e3315b427a900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14669,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fb4f6ae091050630bccde15062cbf547ad173720000000000000000000000008fb4f6ae091050630bccde15062cbf547ad173720000000000000000000000000000000000000000000000000173ebc27c68637400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14670,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d5968b303ad5e782c052740e4bea456b90ba3470000000000000000000000001d5968b303ad5e782c052740e4bea456b90ba3470000000000000000000000000000000000000000000000000016f9936bfddefa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a843d8033f630f4c1d43776cebd69a045301e090000000000000000000000005a843d8033f630f4c1d43776cebd69a045301e09000000000000000000000000000000000000000000000000000b5e620f48000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14674,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000009036f17af475c9793dd3baef5f5610a10920b40c0000000000000000000000009036f17af475c9793dd3baef5f5610a10920b40c000000000000000000000000000000000000000000000000000000000608a06700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x005cbf91d16ea2b0f797d8e3d1ee7bc3790bc4e7b5fcf2b2df0fa1591300eaab,2022-02-26 10:21:41.000 UTC,0,true +14675,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000274cab0c9a1795add5e07cb478d8c1c072cc0bc1000000000000000000000000274cab0c9a1795add5e07cb478d8c1c072cc0bc1000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14676,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032996dcc495f32eec85dcbbd79c7467a3217e81600000000000000000000000032996dcc495f32eec85dcbbd79c7467a3217e8160000000000000000000000000000000000000000000000000014cda00a75385600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14677,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c7e5cbabfa66f985f0ef32322c45014e193bd090000000000000000000000007c7e5cbabfa66f985f0ef32322c45014e193bd09000000000000000000000000000000000000000000000000052d93204ae3e08a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14678,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000687c5fba506025a4d633c4f2fcabdd3ff0524238000000000000000000000000687c5fba506025a4d633c4f2fcabdd3ff05242380000000000000000000000000000000000000000000000000012fe61583dbf7f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14680,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0b830fb6b31a3aac77fe37b6e946bb6f5c83744000000000000000000000000f0b830fb6b31a3aac77fe37b6e946bb6f5c83744000000000000000000000000000000000000000000000000020808be2a7b719b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14683,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ff5207e5a1d0d8ccc2787215f8ed51b7daa5f1aa000000000000000000000000ff5207e5a1d0d8ccc2787215f8ed51b7daa5f1aa0000000000000000000000000000000000000000000000000038eb635efb4ab500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ee3479373e6a31185a5cf9a40a00469814b21420000000000000000000000005ee3479373e6a31185a5cf9a40a00469814b21420000000000000000000000000000000000000000000000000086863322a6358000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d6b678a6f8ee90cecf5679d435fd2165b4b1f9b0000000000000000000000004d6b678a6f8ee90cecf5679d435fd2165b4b1f9b0000000000000000000000000000000000000000000000000012fd206edfeb9200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14686,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007afc7f83b1ea7b96c480c3a70d7313ad5c89bca7000000000000000000000000000000000000000000000000947e094f18ae0000,,,1,true +14687,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b420f03437908be1d67ddf9686363f1a08de0f40000000000000000000000005b420f03437908be1d67ddf9686363f1a08de0f40000000000000000000000000000000000000000000000000023b4edfe657a8100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029200feddcb5993f6f59d5e475985c267a9fd87e00000000000000000000000029200feddcb5993f6f59d5e475985c267a9fd87e000000000000000000000000000000000000000000000000000e8764d3e1e9aa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14690,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d18e84b21b6acb69628ecb85f8074fd441478050000000000000000000000000d18e84b21b6acb69628ecb85f8074fd441478050000000000000000000000000000000000000000000000000000e0ea594b3938b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14691,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006dafabb007a3f441a9de9b8ec245ba3fa07187080000000000000000000000006dafabb007a3f441a9de9b8ec245ba3fa071870800000000000000000000000000000000000000000000000009a19552b21f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcc6eefe4261f08a048b5cd48caf57980085d591b578bb0aac4f8cdcf2fd3023e,2022-02-06 14:58:55.000 UTC,0,true +14692,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e20120d84d629e3c15fee39aa4d7c21e7d60f1d0000000000000000000000007e20120d84d629e3c15fee39aa4d7c21e7d60f1d00000000000000000000000000000000000000000000000000a1d467dabab3ae00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14693,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057d6c4efb2ca6703674343d1a7c0492fba49a6f300000000000000000000000057d6c4efb2ca6703674343d1a7c0492fba49a6f300000000000000000000000000000000000000000000000000548401628df7c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001aeea3a2da3a47ed7bcf84448d535285914b02b50000000000000000000000001aeea3a2da3a47ed7bcf84448d535285914b02b5000000000000000000000000000000000000000000000000000bd0fcb09fe67500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14696,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b9d7a43bb331fc2736f617373d60aaf8a5dbf4e0000000000000000000000000b9d7a43bb331fc2736f617373d60aaf8a5dbf4e0000000000000000000000000000000000000000000000003cee13d497943fe6000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084a14f52dcda17356ae54b29891c9f6c0c88703300000000000000000000000084a14f52dcda17356ae54b29891c9f6c0c887033000000000000000000000000000000000000000000000000001597bf3959afa400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14699,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000091104c2f8f25be4ec4eaad392159e51c4e1f1b1000000000000000000000000091104c2f8f25be4ec4eaad392159e51c4e1f1b100000000000000000000000000000000000000000000000004f631a8fb3f21a300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14700,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087c2b4a504b76cf71179ace53654c4e115623af900000000000000000000000087c2b4a504b76cf71179ace53654c4e115623af900000000000000000000000000000000000000000000000000102a56192e2cf600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14701,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039885aacc9dc0b053131605fc2f43b2f1275014300000000000000000000000039885aacc9dc0b053131605fc2f43b2f1275014300000000000000000000000000000000000000000000000000fce30a6d5a97d400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008d3b3152265ed42c1fdfd8bcb553f4de4d4fef600000000000000000000000008d3b3152265ed42c1fdfd8bcb553f4de4d4fef6000000000000000000000000000000000000000000000000000bc69f4f8c70af00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000250e936d39bcdbc0b84c15b248a8356d341f06c7000000000000000000000000250e936d39bcdbc0b84c15b248a8356d341f06c700000000000000000000000000000000000000000000000000000000015c051900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dafb902776a0203d7e4cfecd5eef4e10bc5e48a9000000000000000000000000dafb902776a0203d7e4cfecd5eef4e10bc5e48a9000000000000000000000000000000000000000000000000019424f7e652d89100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007983c62d7ad755343fc57c4a3592f94381da79220000000000000000000000007983c62d7ad755343fc57c4a3592f94381da792200000000000000000000000000000000000000000000000000a7b4b88ea5e1b300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14708,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b2720df9175987bef9e33ded3de06c78487310c0000000000000000000000000b2720df9175987bef9e33ded3de06c78487310c0000000000000000000000000000000000000000000000000019c17c77ad8d5c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14709,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000a2f8e4744fd85e9089a337fed259f05dd864a91e000000000000000000000000a2f8e4744fd85e9089a337fed259f05dd864a91e00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000001c46bda792db342cc8899a0335713dd6980138ea0000000000000000000000001c46bda792db342cc8899a0335713dd6980138ea00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14715,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000016f9a7d7877776b58625937333f9c9666470200900000000000000000000000016f9a7d7877776b58625937333f9c96664702009000000000000000000000000000000000000000000000000de6e8966c5e07d1000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000f57871a2f715f1a0d48965b6556cd14ef1577f33000000000000000000000000f57871a2f715f1a0d48965b6556cd14ef1577f3300000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14719,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000170246b41adf6c859093b17b19548c25c7109f93000000000000000000000000170246b41adf6c859093b17b19548c25c7109f9300000000000000000000000000000000000000000000000010a64c426f4a3cc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x39b4d4f5eb0ffab046b1482cb5dde3c200485fe8ea6b7916cb8886c5dff8e3cd,2021-11-30 09:47:57.000 UTC,0,true +14720,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dccb3b984c89f97afd551bede081f72e5c50c223000000000000000000000000dccb3b984c89f97afd551bede081f72e5c50c223000000000000000000000000000000000000000000000000076470f11aeba9a000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x15f16c287097ae4a5c2ed2199d30d7307ce743f655754d11f0c637fa6f197d70,2021-12-10 22:13:50.000 UTC,0,true +14721,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022edfb7d07ccc3a28cd315c5ad9b9808a867e56300000000000000000000000022edfb7d07ccc3a28cd315c5ad9b9808a867e56300000000000000000000000000000000000000000000000003a492a4feddf97d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x79f5d9d87d6fa5e4a1b05bf442dd15fe8ed3a846d080a79c08eaf699590b930c,2021-12-19 05:40:38.000 UTC,0,true +14730,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e25ff9081a1d09897f255b5c557605c2d0bda77d0000000000000000000000000000000000000000000000007492cb7eb1480000,,,1,true +14732,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5f10840a067045587761f5563bdaf758fa298b9000000000000000000000000c5f10840a067045587761f5563bdaf758fa298b900000000000000000000000000000000000000000000000000ee8e4d8fbfe23600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14736,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9fc7c85de39f5b36f99a9ef5385d3267584ac06000000000000000000000000f9fc7c85de39f5b36f99a9ef5385d3267584ac0600000000000000000000000000000000000000000000000003fae9a875792bec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x67c38d53adff1620bc1ff373a5ca241fa41e8920de6a143a17e03a944d5d766c,2021-12-11 23:33:38.000 UTC,0,true +14738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a95c6b020840f706d036af32143175b7a3d11ee0000000000000000000000006a95c6b020840f706d036af32143175b7a3d11ee000000000000000000000000000000000000000000000000000de307e461f55400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14741,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0f90e81e6c89d7581c55dade471fff8fd3cff60000000000000000000000000c0f90e81e6c89d7581c55dade471fff8fd3cff600000000000000000000000000000000000000000000000000a616e0973fe000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14744,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065890d61f79db0e2b9107107d0a02daa35e123ee00000000000000000000000065890d61f79db0e2b9107107d0a02daa35e123ee000000000000000000000000000000000000000000000000008dd060e5804c6600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f7db26ef8eab61a68df3c285ccc04b9e60102510000000000000000000000007f7db26ef8eab61a68df3c285ccc04b9e6010251000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14746,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1fe1f074b32013a3eefd57d5fb1b853e38522e6000000000000000000000000c1fe1f074b32013a3eefd57d5fb1b853e38522e600000000000000000000000000000000000000000000000004b530b28cee817a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x94c4c137096132aac23ae9d5fbd392d7dc78edbf4b90ceef3f2f4d7735d0081a,2021-11-25 03:41:42.000 UTC,0,true +14747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d819c62dde216ef3b508d348542b59477efd606f000000000000000000000000d819c62dde216ef3b508d348542b59477efd606f0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14751,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000478a4ad6fb7e44c2f0a5af299399a9c797fc98f2000000000000000000000000478a4ad6fb7e44c2f0a5af299399a9c797fc98f200000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000b6365c4670076b90f7958f7d20455c3a8999fed9000000000000000000000000b6365c4670076b90f7958f7d20455c3a8999fed900000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14753,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4ddc5af57f7fa6710346ebe18e5a3ca9e086a5d000000000000000000000000a4ddc5af57f7fa6710346ebe18e5a3ca9e086a5d000000000000000000000000000000000000000000000000020688cb3a02ceb600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14754,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ec64e346fddc63ab96486288294be8b6a346a40d000000000000000000000000ec64e346fddc63ab96486288294be8b6a346a40d00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14760,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000046f1a0b0af9eb44089fec8ee8bbe74f6e58661d300000000000000000000000046f1a0b0af9eb44089fec8ee8bbe74f6e58661d300000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000001646b30f2f5d1d94c58e78f748af25cd5831112f0000000000000000000000001646b30f2f5d1d94c58e78f748af25cd5831112f00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000f33ee8617e5db3e5f7ccf08f9f0159d40b5e7252000000000000000000000000f33ee8617e5db3e5f7ccf08f9f0159d40b5e725200000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14770,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000029396eb0a246fa5321d30dbf01261fddaa16067e00000000000000000000000029396eb0a246fa5321d30dbf01261fddaa16067e00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14771,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddd6ae239a5eaf73608eedd8f47e0eb1fc1474ff000000000000000000000000ddd6ae239a5eaf73608eedd8f47e0eb1fc1474ff00000000000000000000000000000000000000000000000000099931b788348000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000b86777a778b30889765fa9e5230a24f6ffafa94f000000000000000000000000b86777a778b30889765fa9e5230a24f6ffafa94f0000000000000000000000000000000000000000000000000000000001198c7600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000a829116c1430c7431e037c0a71547ec247246a02000000000000000000000000a829116c1430c7431e037c0a71547ec247246a0200000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e44f3d32c23f44e83bc194ec6811d8ddad507b50000000000000000000000007e44f3d32c23f44e83bc194ec6811d8ddad507b500000000000000000000000000000000000000000000000000a9c8df4d443aac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xae9b9ede21e54cddc000adc7e59610c1556cc4efb41474f987de576c258901f1,2022-04-28 08:41:38.000 UTC,0,true +14777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c99aa08febc29634b97100c576e2f0172f32fd60000000000000000000000001c99aa08febc29634b97100c576e2f0172f32fd6000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14778,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008185191ca6bfb4b76214abb3572be413e51d24bc0000000000000000000000008185191ca6bfb4b76214abb3572be413e51d24bc000000000000000000000000000000000000000000000000058d15e17628000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14780,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000b1fd98f016718c905a9a5ce55cb9e4f8e163b9fc000000000000000000000000b1fd98f016718c905a9a5ce55cb9e4f8e163b9fc00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14784,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008185191ca6bfb4b76214abb3572be413e51d24bc0000000000000000000000008185191ca6bfb4b76214abb3572be413e51d24bc000000000000000000000000000000000000000000000000015b73de76859ec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000f7f4352fa9b3fb1a57adcd9f62a11a5f5d40cea6000000000000000000000000f7f4352fa9b3fb1a57adcd9f62a11a5f5d40cea600000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000d7b4b35bc317f731c86757c29a0c86754f15b0cd000000000000000000000000d7b4b35bc317f731c86757c29a0c86754f15b0cd00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000f67bc705466a5480190525436d36bc4e821dd7e2000000000000000000000000f67bc705466a5480190525436d36bc4e821dd7e200000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14788,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000d1d6733de35ed9025fddea264d35b860edce3e25000000000000000000000000d1d6733de35ed9025fddea264d35b860edce3e2500000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000275e096df57fa32aea8be81188ed0dbbe4c3efcf000000000000000000000000275e096df57fa32aea8be81188ed0dbbe4c3efcf00000000000000000000000000000000000000000000000000f98ba97396c6a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14791,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000635c5a713bbd9132617544db8dcdcae549e6f738000000000000000000000000635c5a713bbd9132617544db8dcdcae549e6f73800000000000000000000000000000000000000000000000002dac46a5f7dc84c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d48f76b510197152810bd58b91bb5983020e9510000000000000000000000008d48f76b510197152810bd58b91bb5983020e9510000000000000000000000000000000000000000000000000086942faaf4828600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6c18ef0eb0db380611f07cce8e9573bcee9b636a608169a9528a39bbd6d98ee1,2022-05-24 04:24:07.000 UTC,0,true +14793,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bfd687d8adf6b3ebe53e922b93d2915163ded26800000000000000000000000000000000000000000000000020020b6eaf8d493b,,,1,true +14794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000005d25f77d1704a2c18e406404483aa594c83c23050000000000000000000000005d25f77d1704a2c18e406404483aa594c83c2305000000000000000000000000000000000000000000000000000000000645fa6a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a09f46e3b7165bf38af1ac13d89be34bdf662e7f000000000000000000000000a09f46e3b7165bf38af1ac13d89be34bdf662e7f000000000000000000000000000000000000000000000000001f79f61064fd8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14797,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000e910a91f98ca9b5848b16d5c294645a2c4ba64300000000000000000000000000000000000000000000000698e90d908d162aab,,,1,true +14798,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf53e53ac22160e47675fe7dfc7a9afb3547b0d2000000000000000000000000bf53e53ac22160e47675fe7dfc7a9afb3547b0d200000000000000000000000000000000000000000000000000036ecd0982094000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14804,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cbc7ebafca5f1e33e15e5cccbc24ecfc0c55a3e0000000000000000000000002cbc7ebafca5f1e33e15e5cccbc24ecfc0c55a3e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14805,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053d7043fb8a7d162eba5d9bb374868595d8d203b00000000000000000000000053d7043fb8a7d162eba5d9bb374868595d8d203b000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14806,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7dc00521e64c3146ed4b9a94a0bdadc55d79b01000000000000000000000000e7dc00521e64c3146ed4b9a94a0bdadc55d79b01000000000000000000000000000000000000000000000000020a2aa21cbdf9a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa96bf7fc59635e05a18318f417bf3d69c81b38bf6e85383f60ec211dff1a6a7e,2021-11-23 08:16:28.000 UTC,0,true +14807,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000616ec7d0b66cad90f901e36bac4d91490ac3a99d000000000000000000000000616ec7d0b66cad90f901e36bac4d91490ac3a99d0000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14808,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f16b1691277d60f084a2346c6c6e48393b471450000000000000000000000009f16b1691277d60f084a2346c6c6e48393b471450000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005553729d902df38cff09d3077250af73dc8244440000000000000000000000005553729d902df38cff09d3077250af73dc8244440000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14811,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005553729d902df38cff09d3077250af73dc8244440000000000000000000000005553729d902df38cff09d3077250af73dc8244440000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7c79534b52acb69b5231868dae7b81006689cf9000000000000000000000000a7c79534b52acb69b5231868dae7b81006689cf90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14813,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029d333e2bf6b75d669675ebb9ce0b5a78a6eace500000000000000000000000029d333e2bf6b75d669675ebb9ce0b5a78a6eace50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c8ef161fe4df88be6baf32ac8981d739529cdd70000000000000000000000004c8ef161fe4df88be6baf32ac8981d739529cdd70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14815,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065197fdf8de5ae05c3e622d116a682b01cf748d200000000000000000000000065197fdf8de5ae05c3e622d116a682b01cf748d2000000000000000000000000000000000000000000000000015cfa7c7d19314000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dff855094f0bb1cf1a9f5284b7b095e402b946d5000000000000000000000000dff855094f0bb1cf1a9f5284b7b095e402b946d50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000481f1e27ea5a1c542219677df58638d1135c0238000000000000000000000000481f1e27ea5a1c542219677df58638d1135c02380000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000959c21342d6a7c9f7b8197a7baa004c18eaa12c8000000000000000000000000959c21342d6a7c9f7b8197a7baa004c18eaa12c80000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ca7ad9584ea2316922acc3c108fbb6cbdd8cc9c4000000000000000000000000ca7ad9584ea2316922acc3c108fbb6cbdd8cc9c40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14820,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b786c184fa67e87309f7ead62e193eff8ffa9970000000000000000000000008b786c184fa67e87309f7ead62e193eff8ffa997000000000000000000000000000000000000000000000000007bed343d4b085c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059bae35cee6a074e4945376e65111c7f06cf3f5a00000000000000000000000059bae35cee6a074e4945376e65111c7f06cf3f5a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14822,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c009516ff3a46d0bcb08ae979e55cf0b09e4a43c000000000000000000000000c009516ff3a46d0bcb08ae979e55cf0b09e4a43c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d85b4c4c4f5781a957a1caef0f80934227f73ceb000000000000000000000000d85b4c4c4f5781a957a1caef0f80934227f73ceb0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a5fd3e33d3618432e7a062edd7c850657b2baf60000000000000000000000004a5fd3e33d3618432e7a062edd7c850657b2baf60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e530b61b19a2066d43542a45c4bc3bd428f9fbf7000000000000000000000000e530b61b19a2066d43542a45c4bc3bd428f9fbf7000000000000000000000000000000000000000000000000006488b27145784000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005757ef8da15fb2e01f4a743f12e0ec7d048e3ca50000000000000000000000005757ef8da15fb2e01f4a743f12e0ec7d048e3ca50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005757ef8da15fb2e01f4a743f12e0ec7d048e3ca50000000000000000000000005757ef8da15fb2e01f4a743f12e0ec7d048e3ca50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005757ef8da15fb2e01f4a743f12e0ec7d048e3ca50000000000000000000000005757ef8da15fb2e01f4a743f12e0ec7d048e3ca50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005757ef8da15fb2e01f4a743f12e0ec7d048e3ca50000000000000000000000005757ef8da15fb2e01f4a743f12e0ec7d048e3ca50000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a746a530bdc89096d012bbaefa4bf6dbb185b030000000000000000000000002a746a530bdc89096d012bbaefa4bf6dbb185b030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a746a530bdc89096d012bbaefa4bf6dbb185b030000000000000000000000002a746a530bdc89096d012bbaefa4bf6dbb185b030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a746a530bdc89096d012bbaefa4bf6dbb185b030000000000000000000000002a746a530bdc89096d012bbaefa4bf6dbb185b030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a746a530bdc89096d012bbaefa4bf6dbb185b030000000000000000000000002a746a530bdc89096d012bbaefa4bf6dbb185b030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d1df56799398477b16790eea966927808b8dead0000000000000000000000008d1df56799398477b16790eea966927808b8dead0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d1df56799398477b16790eea966927808b8dead0000000000000000000000008d1df56799398477b16790eea966927808b8dead0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d1df56799398477b16790eea966927808b8dead0000000000000000000000008d1df56799398477b16790eea966927808b8dead0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d1df56799398477b16790eea966927808b8dead0000000000000000000000008d1df56799398477b16790eea966927808b8dead0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14840,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d2ea91ea2ec05d54f01494da98c9739e41c71730000000000000000000000000d2ea91ea2ec05d54f01494da98c9739e41c71730000000000000000000000000000000000000000000000000075d579054f780000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x834cd48c00ac06a4423200ebabe38271d3c844a0832ef3e5a514c4288c58a568,2022-04-24 03:49:58.000 UTC,0,true +14841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d127fbe1408696af0a9ab6c93b7449e33641fd0a000000000000000000000000d127fbe1408696af0a9ab6c93b7449e33641fd0a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d127fbe1408696af0a9ab6c93b7449e33641fd0a000000000000000000000000d127fbe1408696af0a9ab6c93b7449e33641fd0a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d127fbe1408696af0a9ab6c93b7449e33641fd0a000000000000000000000000d127fbe1408696af0a9ab6c93b7449e33641fd0a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d127fbe1408696af0a9ab6c93b7449e33641fd0a000000000000000000000000d127fbe1408696af0a9ab6c93b7449e33641fd0a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d00afd8f1cc62e50ac768f5f2a639070ab2ae7b0000000000000000000000004d00afd8f1cc62e50ac768f5f2a639070ab2ae7b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d00afd8f1cc62e50ac768f5f2a639070ab2ae7b0000000000000000000000004d00afd8f1cc62e50ac768f5f2a639070ab2ae7b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d00afd8f1cc62e50ac768f5f2a639070ab2ae7b0000000000000000000000004d00afd8f1cc62e50ac768f5f2a639070ab2ae7b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d00afd8f1cc62e50ac768f5f2a639070ab2ae7b0000000000000000000000004d00afd8f1cc62e50ac768f5f2a639070ab2ae7b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080b0bcdafbbd39bf74173c48a384e675a37ec74b00000000000000000000000080b0bcdafbbd39bf74173c48a384e675a37ec74b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080b0bcdafbbd39bf74173c48a384e675a37ec74b00000000000000000000000080b0bcdafbbd39bf74173c48a384e675a37ec74b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080b0bcdafbbd39bf74173c48a384e675a37ec74b00000000000000000000000080b0bcdafbbd39bf74173c48a384e675a37ec74b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080b0bcdafbbd39bf74173c48a384e675a37ec74b00000000000000000000000080b0bcdafbbd39bf74173c48a384e675a37ec74b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be3f3d91f54f93aacaa6bb7fb67eaa90b790de72000000000000000000000000be3f3d91f54f93aacaa6bb7fb67eaa90b790de720000000000000000000000000000000000000000000000000dd521f3c75540b500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x36c2c721697b5d10df1a55ae533972abb00bc599d42a0fb7ef58f73fbfbc4a11,2021-11-25 07:59:06.000 UTC,0,true +14854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059bae35cee6a074e4945376e65111c7f06cf3f5a00000000000000000000000059bae35cee6a074e4945376e65111c7f06cf3f5a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14855,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059bae35cee6a074e4945376e65111c7f06cf3f5a00000000000000000000000059bae35cee6a074e4945376e65111c7f06cf3f5a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059bae35cee6a074e4945376e65111c7f06cf3f5a00000000000000000000000059bae35cee6a074e4945376e65111c7f06cf3f5a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14859,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c46bda792db342cc8899a0335713dd6980138ea0000000000000000000000001c46bda792db342cc8899a0335713dd6980138ea0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c46bda792db342cc8899a0335713dd6980138ea0000000000000000000000001c46bda792db342cc8899a0335713dd6980138ea0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c009516ff3a46d0bcb08ae979e55cf0b09e4a43c000000000000000000000000c009516ff3a46d0bcb08ae979e55cf0b09e4a43c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14862,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c009516ff3a46d0bcb08ae979e55cf0b09e4a43c000000000000000000000000c009516ff3a46d0bcb08ae979e55cf0b09e4a43c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14863,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c46bda792db342cc8899a0335713dd6980138ea0000000000000000000000001c46bda792db342cc8899a0335713dd6980138ea0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6365c4670076b90f7958f7d20455c3a8999fed9000000000000000000000000b6365c4670076b90f7958f7d20455c3a8999fed90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14865,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c009516ff3a46d0bcb08ae979e55cf0b09e4a43c000000000000000000000000c009516ff3a46d0bcb08ae979e55cf0b09e4a43c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14866,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6365c4670076b90f7958f7d20455c3a8999fed9000000000000000000000000b6365c4670076b90f7958f7d20455c3a8999fed90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6365c4670076b90f7958f7d20455c3a8999fed9000000000000000000000000b6365c4670076b90f7958f7d20455c3a8999fed90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14868,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d85b4c4c4f5781a957a1caef0f80934227f73ceb000000000000000000000000d85b4c4c4f5781a957a1caef0f80934227f73ceb0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a829116c1430c7431e037c0a71547ec247246a02000000000000000000000000a829116c1430c7431e037c0a71547ec247246a020000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d85b4c4c4f5781a957a1caef0f80934227f73ceb000000000000000000000000d85b4c4c4f5781a957a1caef0f80934227f73ceb0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a829116c1430c7431e037c0a71547ec247246a02000000000000000000000000a829116c1430c7431e037c0a71547ec247246a020000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d85b4c4c4f5781a957a1caef0f80934227f73ceb000000000000000000000000d85b4c4c4f5781a957a1caef0f80934227f73ceb0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a829116c1430c7431e037c0a71547ec247246a02000000000000000000000000a829116c1430c7431e037c0a71547ec247246a020000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14874,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a5fd3e33d3618432e7a062edd7c850657b2baf60000000000000000000000004a5fd3e33d3618432e7a062edd7c850657b2baf60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14875,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7b4b35bc317f731c86757c29a0c86754f15b0cd000000000000000000000000d7b4b35bc317f731c86757c29a0c86754f15b0cd0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7b4b35bc317f731c86757c29a0c86754f15b0cd000000000000000000000000d7b4b35bc317f731c86757c29a0c86754f15b0cd0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7b4b35bc317f731c86757c29a0c86754f15b0cd000000000000000000000000d7b4b35bc317f731c86757c29a0c86754f15b0cd0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f67bc705466a5480190525436d36bc4e821dd7e2000000000000000000000000f67bc705466a5480190525436d36bc4e821dd7e20000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f67bc705466a5480190525436d36bc4e821dd7e2000000000000000000000000f67bc705466a5480190525436d36bc4e821dd7e20000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a5fd3e33d3618432e7a062edd7c850657b2baf60000000000000000000000004a5fd3e33d3618432e7a062edd7c850657b2baf60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a5fd3e33d3618432e7a062edd7c850657b2baf60000000000000000000000004a5fd3e33d3618432e7a062edd7c850657b2baf60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14882,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f67bc705466a5480190525436d36bc4e821dd7e2000000000000000000000000f67bc705466a5480190525436d36bc4e821dd7e20000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1fd98f016718c905a9a5ce55cb9e4f8e163b9fc000000000000000000000000b1fd98f016718c905a9a5ce55cb9e4f8e163b9fc0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14884,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1fd98f016718c905a9a5ce55cb9e4f8e163b9fc000000000000000000000000b1fd98f016718c905a9a5ce55cb9e4f8e163b9fc0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1fd98f016718c905a9a5ce55cb9e4f8e163b9fc000000000000000000000000b1fd98f016718c905a9a5ce55cb9e4f8e163b9fc0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14886,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7f4352fa9b3fb1a57adcd9f62a11a5f5d40cea6000000000000000000000000f7f4352fa9b3fb1a57adcd9f62a11a5f5d40cea60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7f4352fa9b3fb1a57adcd9f62a11a5f5d40cea6000000000000000000000000f7f4352fa9b3fb1a57adcd9f62a11a5f5d40cea60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7f4352fa9b3fb1a57adcd9f62a11a5f5d40cea6000000000000000000000000f7f4352fa9b3fb1a57adcd9f62a11a5f5d40cea60000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1d6733de35ed9025fddea264d35b860edce3e25000000000000000000000000d1d6733de35ed9025fddea264d35b860edce3e250000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1d6733de35ed9025fddea264d35b860edce3e25000000000000000000000000d1d6733de35ed9025fddea264d35b860edce3e250000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1d6733de35ed9025fddea264d35b860edce3e25000000000000000000000000d1d6733de35ed9025fddea264d35b860edce3e250000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000250e936d39bcdbc0b84c15b248a8356d341f06c7000000000000000000000000250e936d39bcdbc0b84c15b248a8356d341f06c70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000250e936d39bcdbc0b84c15b248a8356d341f06c7000000000000000000000000250e936d39bcdbc0b84c15b248a8356d341f06c70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14894,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000250e936d39bcdbc0b84c15b248a8356d341f06c7000000000000000000000000250e936d39bcdbc0b84c15b248a8356d341f06c70000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14895,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057d6c4efb2ca6703674343d1a7c0492fba49a6f300000000000000000000000057d6c4efb2ca6703674343d1a7c0492fba49a6f30000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057d6c4efb2ca6703674343d1a7c0492fba49a6f300000000000000000000000057d6c4efb2ca6703674343d1a7c0492fba49a6f30000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057c6155a0bf0a040dc59021fd32c95f35dc632c000000000000000000000000057c6155a0bf0a040dc59021fd32c95f35dc632c00000000000000000000000000000000000000000000000000142e1355d8a88b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021a38a7ee0675e249fe000a21efe55e4c366247d00000000000000000000000021a38a7ee0675e249fe000a21efe55e4c366247d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14900,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021a38a7ee0675e249fe000a21efe55e4c366247d00000000000000000000000021a38a7ee0675e249fe000a21efe55e4c366247d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14901,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021a38a7ee0675e249fe000a21efe55e4c366247d00000000000000000000000021a38a7ee0675e249fe000a21efe55e4c366247d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021a38a7ee0675e249fe000a21efe55e4c366247d00000000000000000000000021a38a7ee0675e249fe000a21efe55e4c366247d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14903,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021a38a7ee0675e249fe000a21efe55e4c366247d00000000000000000000000021a38a7ee0675e249fe000a21efe55e4c366247d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14904,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7a1e18a6cb3e98b3c01005484108f21cc50bdb4000000000000000000000000f7a1e18a6cb3e98b3c01005484108f21cc50bdb40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14905,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7a1e18a6cb3e98b3c01005484108f21cc50bdb4000000000000000000000000f7a1e18a6cb3e98b3c01005484108f21cc50bdb40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7a1e18a6cb3e98b3c01005484108f21cc50bdb4000000000000000000000000f7a1e18a6cb3e98b3c01005484108f21cc50bdb40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14907,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7a1e18a6cb3e98b3c01005484108f21cc50bdb4000000000000000000000000f7a1e18a6cb3e98b3c01005484108f21cc50bdb40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14908,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039f8b4c776a3baac5bbfafc8f4abcf2a720c4b2100000000000000000000000039f8b4c776a3baac5bbfafc8f4abcf2a720c4b210000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039f8b4c776a3baac5bbfafc8f4abcf2a720c4b2100000000000000000000000039f8b4c776a3baac5bbfafc8f4abcf2a720c4b210000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14910,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039f8b4c776a3baac5bbfafc8f4abcf2a720c4b2100000000000000000000000039f8b4c776a3baac5bbfafc8f4abcf2a720c4b210000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039f8b4c776a3baac5bbfafc8f4abcf2a720c4b2100000000000000000000000039f8b4c776a3baac5bbfafc8f4abcf2a720c4b210000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14912,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000250047cdeadd75c39b44c605a348bc46d8d28f8b000000000000000000000000250047cdeadd75c39b44c605a348bc46d8d28f8b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000250047cdeadd75c39b44c605a348bc46d8d28f8b000000000000000000000000250047cdeadd75c39b44c605a348bc46d8d28f8b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14914,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000250047cdeadd75c39b44c605a348bc46d8d28f8b000000000000000000000000250047cdeadd75c39b44c605a348bc46d8d28f8b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14915,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000250047cdeadd75c39b44c605a348bc46d8d28f8b000000000000000000000000250047cdeadd75c39b44c605a348bc46d8d28f8b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e74fb25f9faafc4d957adc6109a9638150bcf6ed000000000000000000000000e74fb25f9faafc4d957adc6109a9638150bcf6ed0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e74fb25f9faafc4d957adc6109a9638150bcf6ed000000000000000000000000e74fb25f9faafc4d957adc6109a9638150bcf6ed0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e74fb25f9faafc4d957adc6109a9638150bcf6ed000000000000000000000000e74fb25f9faafc4d957adc6109a9638150bcf6ed0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14919,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e74fb25f9faafc4d957adc6109a9638150bcf6ed000000000000000000000000e74fb25f9faafc4d957adc6109a9638150bcf6ed0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c30ff3315038e68b94eca460002da04c72305580000000000000000000000005c30ff3315038e68b94eca460002da04c72305580000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14921,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c30ff3315038e68b94eca460002da04c72305580000000000000000000000005c30ff3315038e68b94eca460002da04c72305580000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14922,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c30ff3315038e68b94eca460002da04c72305580000000000000000000000005c30ff3315038e68b94eca460002da04c72305580000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c30ff3315038e68b94eca460002da04c72305580000000000000000000000005c30ff3315038e68b94eca460002da04c72305580000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf87fd806711400405bfab60c9a78585324eb0b9000000000000000000000000bf87fd806711400405bfab60c9a78585324eb0b90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf87fd806711400405bfab60c9a78585324eb0b9000000000000000000000000bf87fd806711400405bfab60c9a78585324eb0b90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf87fd806711400405bfab60c9a78585324eb0b9000000000000000000000000bf87fd806711400405bfab60c9a78585324eb0b90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14928,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf87fd806711400405bfab60c9a78585324eb0b9000000000000000000000000bf87fd806711400405bfab60c9a78585324eb0b90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14929,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f902c7eada99de8bf3cdaf3fa5bddba6a1ecc70a000000000000000000000000f902c7eada99de8bf3cdaf3fa5bddba6a1ecc70a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f902c7eada99de8bf3cdaf3fa5bddba6a1ecc70a000000000000000000000000f902c7eada99de8bf3cdaf3fa5bddba6a1ecc70a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f902c7eada99de8bf3cdaf3fa5bddba6a1ecc70a000000000000000000000000f902c7eada99de8bf3cdaf3fa5bddba6a1ecc70a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14932,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f902c7eada99de8bf3cdaf3fa5bddba6a1ecc70a000000000000000000000000f902c7eada99de8bf3cdaf3fa5bddba6a1ecc70a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14933,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000081d0a08250e3bb8618ba3d10871fcf001bfd87d000000000000000000000000081d0a08250e3bb8618ba3d10871fcf001bfd87d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14934,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000081d0a08250e3bb8618ba3d10871fcf001bfd87d000000000000000000000000081d0a08250e3bb8618ba3d10871fcf001bfd87d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000081d0a08250e3bb8618ba3d10871fcf001bfd87d000000000000000000000000081d0a08250e3bb8618ba3d10871fcf001bfd87d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000081d0a08250e3bb8618ba3d10871fcf001bfd87d000000000000000000000000081d0a08250e3bb8618ba3d10871fcf001bfd87d0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14937,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011878d39b635e3d9a188dcafe3c7c4e8517674c900000000000000000000000011878d39b635e3d9a188dcafe3c7c4e8517674c90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011878d39b635e3d9a188dcafe3c7c4e8517674c900000000000000000000000011878d39b635e3d9a188dcafe3c7c4e8517674c90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011878d39b635e3d9a188dcafe3c7c4e8517674c900000000000000000000000011878d39b635e3d9a188dcafe3c7c4e8517674c90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14940,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011878d39b635e3d9a188dcafe3c7c4e8517674c900000000000000000000000011878d39b635e3d9a188dcafe3c7c4e8517674c90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14941,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011878d39b635e3d9a188dcafe3c7c4e8517674c900000000000000000000000011878d39b635e3d9a188dcafe3c7c4e8517674c90000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000007a557fff0f0ac24b11bda40650fd873e114ebcae0000000000000000000000007a557fff0f0ac24b11bda40650fd873e114ebcae00000000000000000000000000000000000000000000000000000000dc193bbf00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +14944,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d3335ada4acdc568d4a78e8ec7b402e99b082550000000000000000000000005d3335ada4acdc568d4a78e8ec7b402e99b082550000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14946,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d3335ada4acdc568d4a78e8ec7b402e99b082550000000000000000000000005d3335ada4acdc568d4a78e8ec7b402e99b082550000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14947,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d3335ada4acdc568d4a78e8ec7b402e99b082550000000000000000000000005d3335ada4acdc568d4a78e8ec7b402e99b082550000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14948,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d3335ada4acdc568d4a78e8ec7b402e99b082550000000000000000000000005d3335ada4acdc568d4a78e8ec7b402e99b082550000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e92d33a9709803d1bfdc82143cf7078406ece6b0000000000000000000000000e92d33a9709803d1bfdc82143cf7078406ece6b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e92d33a9709803d1bfdc82143cf7078406ece6b0000000000000000000000000e92d33a9709803d1bfdc82143cf7078406ece6b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14954,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e92d33a9709803d1bfdc82143cf7078406ece6b0000000000000000000000000e92d33a9709803d1bfdc82143cf7078406ece6b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14955,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e92d33a9709803d1bfdc82143cf7078406ece6b0000000000000000000000000e92d33a9709803d1bfdc82143cf7078406ece6b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14956,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e92d33a9709803d1bfdc82143cf7078406ece6b0000000000000000000000000e92d33a9709803d1bfdc82143cf7078406ece6b0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14957,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fae56b193a22404e9414247fedeb1c58f02ad2c4000000000000000000000000fae56b193a22404e9414247fedeb1c58f02ad2c40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fae56b193a22404e9414247fedeb1c58f02ad2c4000000000000000000000000fae56b193a22404e9414247fedeb1c58f02ad2c40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fae56b193a22404e9414247fedeb1c58f02ad2c4000000000000000000000000fae56b193a22404e9414247fedeb1c58f02ad2c40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fae56b193a22404e9414247fedeb1c58f02ad2c4000000000000000000000000fae56b193a22404e9414247fedeb1c58f02ad2c40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fae56b193a22404e9414247fedeb1c58f02ad2c4000000000000000000000000fae56b193a22404e9414247fedeb1c58f02ad2c40000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cab2f322841c850e813ff3c5f4bc827d67a35614000000000000000000000000cab2f322841c850e813ff3c5f4bc827d67a356140000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14964,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cab2f322841c850e813ff3c5f4bc827d67a35614000000000000000000000000cab2f322841c850e813ff3c5f4bc827d67a356140000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cab2f322841c850e813ff3c5f4bc827d67a35614000000000000000000000000cab2f322841c850e813ff3c5f4bc827d67a356140000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14966,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cab2f322841c850e813ff3c5f4bc827d67a35614000000000000000000000000cab2f322841c850e813ff3c5f4bc827d67a356140000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14967,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf1789a59818c9f3fa9261325de902f79aa03264000000000000000000000000cf1789a59818c9f3fa9261325de902f79aa032640000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf1789a59818c9f3fa9261325de902f79aa03264000000000000000000000000cf1789a59818c9f3fa9261325de902f79aa032640000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf1789a59818c9f3fa9261325de902f79aa03264000000000000000000000000cf1789a59818c9f3fa9261325de902f79aa032640000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14970,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf1789a59818c9f3fa9261325de902f79aa03264000000000000000000000000cf1789a59818c9f3fa9261325de902f79aa032640000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000afbc9dd7cee3646e8cff9500ce654b4185cbeabe000000000000000000000000afbc9dd7cee3646e8cff9500ce654b4185cbeabe0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14972,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000afbc9dd7cee3646e8cff9500ce654b4185cbeabe000000000000000000000000afbc9dd7cee3646e8cff9500ce654b4185cbeabe0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14973,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000afbc9dd7cee3646e8cff9500ce654b4185cbeabe000000000000000000000000afbc9dd7cee3646e8cff9500ce654b4185cbeabe0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000afbc9dd7cee3646e8cff9500ce654b4185cbeabe000000000000000000000000afbc9dd7cee3646e8cff9500ce654b4185cbeabe0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000432412ef806641cf51a8276616d28b98c086aef0000000000000000000000000432412ef806641cf51a8276616d28b98c086aef0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14976,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000432412ef806641cf51a8276616d28b98c086aef0000000000000000000000000432412ef806641cf51a8276616d28b98c086aef0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000432412ef806641cf51a8276616d28b98c086aef0000000000000000000000000432412ef806641cf51a8276616d28b98c086aef0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14978,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000432412ef806641cf51a8276616d28b98c086aef0000000000000000000000000432412ef806641cf51a8276616d28b98c086aef0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14979,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037e03168c330d26ee749be0d7ab734ed2459af0300000000000000000000000037e03168c330d26ee749be0d7ab734ed2459af030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14980,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037e03168c330d26ee749be0d7ab734ed2459af0300000000000000000000000037e03168c330d26ee749be0d7ab734ed2459af030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14981,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037e03168c330d26ee749be0d7ab734ed2459af0300000000000000000000000037e03168c330d26ee749be0d7ab734ed2459af030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037e03168c330d26ee749be0d7ab734ed2459af0300000000000000000000000037e03168c330d26ee749be0d7ab734ed2459af030000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14983,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea324dc75c40ab87340c966e21c0ad1f74fe6a6c000000000000000000000000ea324dc75c40ab87340c966e21c0ad1f74fe6a6c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea324dc75c40ab87340c966e21c0ad1f74fe6a6c000000000000000000000000ea324dc75c40ab87340c966e21c0ad1f74fe6a6c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14986,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea324dc75c40ab87340c966e21c0ad1f74fe6a6c000000000000000000000000ea324dc75c40ab87340c966e21c0ad1f74fe6a6c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ea324dc75c40ab87340c966e21c0ad1f74fe6a6c000000000000000000000000ea324dc75c40ab87340c966e21c0ad1f74fe6a6c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14988,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c82153578a508c797d9f47087ff9a049d4a87c000000000000000000000000b8c82153578a508c797d9f47087ff9a049d4a87c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14989,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c82153578a508c797d9f47087ff9a049d4a87c000000000000000000000000b8c82153578a508c797d9f47087ff9a049d4a87c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c82153578a508c797d9f47087ff9a049d4a87c000000000000000000000000b8c82153578a508c797d9f47087ff9a049d4a87c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14991,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8c82153578a508c797d9f47087ff9a049d4a87c000000000000000000000000b8c82153578a508c797d9f47087ff9a049d4a87c0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14992,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5c8069f3e04bc4acef97c499eff3e19b389e13e000000000000000000000000e5c8069f3e04bc4acef97c499eff3e19b389e13e0000000000000000000000000000000000000000000000000184311faa247e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062a2d0f2bdb776da7bd258f076a716b14aef8fce00000000000000000000000062a2d0f2bdb776da7bd258f076a716b14aef8fce00000000000000000000000000000000000000000000000000cceec0fdfe4db900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c033aab89b26650057881dabbc0815146ffc0f20000000000000000000000003c033aab89b26650057881dabbc0815146ffc0f2000000000000000000000000000000000000000000000000026352913376ece400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd789b1aa8f7cfd47d397732924c2c77ab5bf500c7f8a5f8d78dbea72472c7988,2021-11-24 11:57:50.000 UTC,0,true +14995,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005f5a4ecf33fa9eba7f7e52a4bc0c2aab5dcb82b00000000000000000000000005f5a4ecf33fa9eba7f7e52a4bc0c2aab5dcb82b00000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14996,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060e203841ad895952990241374e8599d437dba8e00000000000000000000000060e203841ad895952990241374e8599d437dba8e000000000000000000000000000000000000000000000000005c28b3b3406c6100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +14997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080eadcd56c6ea034331bd9c72a86220c85a815c100000000000000000000000080eadcd56c6ea034331bd9c72a86220c85a815c100000000000000000000000000000000000000000000000000ee6cd6844e843a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x44ba34e68238003db9c84c9ff7fdccc2241ef5a268f8952a8546afcb6ba5117c,2022-02-26 23:01:17.000 UTC,0,true +14998,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001778cb9fd8d489c740568a9bf16004d948d9b6bf0000000000000000000000001778cb9fd8d489c740568a9bf16004d948d9b6bf000000000000000000000000000000000000000000000000004205b433402fc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15000,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f58c3f6331d4acb595f9d1c799b88cc2bcd305b2000000000000000000000000f58c3f6331d4acb595f9d1c799b88cc2bcd305b2000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15001,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fb61a8e5cf37cc1de7c1fe155ee5295c3d023600000000000000000000000000fb61a8e5cf37cc1de7c1fe155ee5295c3d0236000000000000000000000000000000000000000000000000005f7aab8c56b000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15003,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000883758d9d67de6334496552897f31e5e5a2565ab000000000000000000000000883758d9d67de6334496552897f31e5e5a2565ab00000000000000000000000000000000000000000000000000106d10c95fa0f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffb7f2f91fea3212649a68c25f604c128968a2ba000000000000000000000000ffb7f2f91fea3212649a68c25f604c128968a2ba00000000000000000000000000000000000000000000000001a715603d7d9b4900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15007,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039074b2b4434bf3115890094e1360e36d42ecbbd00000000000000000000000039074b2b4434bf3115890094e1360e36d42ecbbd00000000000000000000000000000000000000000000000002587a6eeef4002a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15009,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000081cfc36ef7bffe9a1e95f8fa1bec6bad71e1db7e00000000000000000000000081cfc36ef7bffe9a1e95f8fa1bec6bad71e1db7e000000000000000000000000000000000000000000000000000000000173ad0300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008603c52132af298f90093d9697b954aceefdd1d60000000000000000000000008603c52132af298f90093d9697b954aceefdd1d6000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15015,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb62e25a011acfd4afef3c7e074d44c56a0867d7000000000000000000000000bb62e25a011acfd4afef3c7e074d44c56a0867d7000000000000000000000000000000000000000000000000001ec738acc4e30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15017,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3ec605d078326b0a636ca90d496ebb5eb457a27000000000000000000000000d3ec605d078326b0a636ca90d496ebb5eb457a2700000000000000000000000000000000000000000000000000c9a4aa8882689700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15018,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ecc524bac33f76cc3b5bfcee2aed8b96e2053140000000000000000000000003ecc524bac33f76cc3b5bfcee2aed8b96e205314000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15019,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cd48098cec9db1019b19e232d39787fa58029f60000000000000000000000004cd48098cec9db1019b19e232d39787fa58029f6000000000000000000000000000000000000000000000000003cbc5c89c45d4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f6000000000000000000000000f9629f4d682d5f81b1efc48197cd8f1813c7ff9c000000000000000000000000f9629f4d682d5f81b1efc48197cd8f1813c7ff9c0000000000000000000000000000000000000000000000007681b071ae64322400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057424e704d9912129445cadae8c321a3bede349d00000000000000000000000057424e704d9912129445cadae8c321a3bede349d000000000000000000000000000000000000000000000000003c19beb550e32600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020f9151b1643f660bef88a5aa7c2ff0ba2bebe8200000000000000000000000020f9151b1643f660bef88a5aa7c2ff0ba2bebe820000000000000000000000000000000000000000000000000dcc004ea0ba75be00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x527f5b9ae48cb051a8a8051d1b0b14ebaa446ce741d2009b843471d5e26ef4cb,2022-11-01 15:22:11.000 UTC,0,true +15028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cdb921352f72fbfe5eecf0fa34d1b26a4e0c57ad000000000000000000000000cdb921352f72fbfe5eecf0fa34d1b26a4e0c57ad0000000000000000000000000000000000000000000000000f3162295c4c96c200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x65a4914dbb010ce7002fcb2b8661efe6789d660fec7301acdb886aa9615fc71b,2021-11-21 17:44:44.000 UTC,0,true +15033,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078ee4d78d27b20d97e3e51c0cc917ebe55806b0000000000000000000000000078ee4d78d27b20d97e3e51c0cc917ebe55806b000000000000000000000000000000000000000000000000000159fc5d54628a4800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085ea7c5ee10c3e37865799faf1b0535986f143b300000000000000000000000085ea7c5ee10c3e37865799faf1b0535986f143b300000000000000000000000000000000000000000000000002b2a9b238f4e22900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15038,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a782d8b7cd409ce196a3ef1b9f44de41f4fa5b40000000000000000000000003a782d8b7cd409ce196a3ef1b9f44de41f4fa5b400000000000000000000000000000000000000000000000001eb8b1e1e46c93500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15040,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ac0b447d5d976b1ec7d8a885c937e0efcc7edbe0000000000000000000000000ac0b447d5d976b1ec7d8a885c937e0efcc7edbe00000000000000000000000000000000000000000000000006d9491212756b49600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xd5997f47c09d89f451188e90873bed99ea488108adf95af592c8ed8ada152a9c,2022-07-10 05:17:23.000 UTC,0,true +15042,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c154383b6ce66f0a9981544fc78a71526281ba78000000000000000000000000c154383b6ce66f0a9981544fc78a71526281ba78000000000000000000000000000000000000000000000000003cc7710635bc1c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15044,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a02513b5c1695940b87c835f5cd038ac13c1b53f00000000000000000000000000000000000000000000000037919d20e97e1496,,,1,true +15046,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000033e7a93470ae5b27dbfe27f94ad3c1b1ff7efe5e00000000000000000000000033e7a93470ae5b27dbfe27f94ad3c1b1ff7efe5e000000000000000000000000000000000000000000000000000000000dc445d800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15048,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef4981e9ced215d267ae900c5802c6966efd312a000000000000000000000000ef4981e9ced215d267ae900c5802c6966efd312a000000000000000000000000000000000000000000000000015ed886d9525b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15049,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f278ac8e97dd418a3ce13307fa1b44ff87a18f7c000000000000000000000000f278ac8e97dd418a3ce13307fa1b44ff87a18f7c0000000000000000000000000000000000000000000000000000e5d0016ed90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cd8771ae2d6cb344663b8da7253c944f0801edd8000000000000000000000000cd8771ae2d6cb344663b8da7253c944f0801edd800000000000000000000000000000000000000000000000001833e37b527bb7100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c7121dcbd8e2288cd3e181d2c3b2477527c3e810000000000000000000000002c7121dcbd8e2288cd3e181d2c3b2477527c3e8100000000000000000000000000000000000000000000000000e1eafd8c4f803400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fad545d7391f9c9a93b6f2c6924c7b6aabb13d21000000000000000000000000fad545d7391f9c9a93b6f2c6924c7b6aabb13d2100000000000000000000000000000000000000000000000000e360f9ee45edcf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052ad07a854ff71c27eeb85606a30600646ac84b700000000000000000000000052ad07a854ff71c27eeb85606a30600646ac84b700000000000000000000000000000000000000000000000000e5e5105a17fbca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15056,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000227443f8cb623e4e8e2e4e6505e0c5d20a9ab4e1000000000000000000000000227443f8cb623e4e8e2e4e6505e0c5d20a9ab4e10000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15057,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062009d75c7312dd460f9ac0682e705ac3ca57f1d00000000000000000000000062009d75c7312dd460f9ac0682e705ac3ca57f1d00000000000000000000000000000000000000000000000000e1b0911080971e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15058,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000044cb2d713bda3858001f038645fd05e23e5de03d00000000000000000000000044cb2d713bda3858001f038645fd05e23e5de03d0000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002763347165cdb87d12ac3217cb9ee0d395f0d0070000000000000000000000002763347165cdb87d12ac3217cb9ee0d395f0d00700000000000000000000000000000000000000000000000000148836c082f89b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aed09b2654bee737eead92dfcf451953cf88b448000000000000000000000000aed09b2654bee737eead92dfcf451953cf88b4480000000000000000000000000000000000000000000000000023a75513f2fda700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15064,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be2461207b633ea5da676a0e738ea80b7c95d8a6000000000000000000000000be2461207b633ea5da676a0e738ea80b7c95d8a600000000000000000000000000000000000000000000000002d62bfc5bb0c28000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be2461207b633ea5da676a0e738ea80b7c95d8a6000000000000000000000000be2461207b633ea5da676a0e738ea80b7c95d8a600000000000000000000000000000000000000000000000002e3ba376a62c40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15066,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000917d24f8d2c41a434796d16a53ad51aaaa9ec129000000000000000000000000917d24f8d2c41a434796d16a53ad51aaaa9ec129000000000000000000000000000000000000000000000000009c2d1104d6060000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15068,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006a45c27e47ecb7d51e69839ac949aa69f8f0f15f0000000000000000000000006a45c27e47ecb7d51e69839ac949aa69f8f0f15f00000000000000000000000000000000000000000000001539964beba9db13cf00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x3b789b63d3a38b0a5b76882013f22952f6c5f6ede63fad04e2a2d57b1817fadd,2022-02-13 04:50:20.000 UTC,0,true +15069,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c25c0092307a5b8afd8a4bd01351a92579040951000000000000000000000000c25c0092307a5b8afd8a4bd01351a925790409510000000000000000000000000000000000000000000000001582b4c9a9db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xac5fff10b1e5d6c58731a15ba2dcae4a15dd5151ca95390522f93ad6843694ec,2022-04-05 11:32:34.000 UTC,0,true +15072,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029c80c2690f91a47803445c5922e76597d1dd2b600000000000000000000000029c80c2690f91a47803445c5922e76597d1dd2b6000000000000000000000000000000000000000000000000003a56fcc7cca2e400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d50f52301e5ad3e9e6abbcd645a72b18df914f00000000000000000000000001d50f52301e5ad3e9e6abbcd645a72b18df914f00000000000000000000000000000000000000000000000000153615bda39c1ca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1081f749592fbcc21bcd6dbfbaef31cf2bc06d2b26d1342e5fe5f36ef452f523,2022-08-09 23:34:35.000 UTC,0,true +15077,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008e1083d25ce5c4c48a28f80445e79f27788f54d30000000000000000000000008e1083d25ce5c4c48a28f80445e79f27788f54d30000000000000000000000000000000000000000000000000e043da61725000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15079,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000bcf5411619e85f92ded9f8835f230aefab84e41c000000000000000000000000bcf5411619e85f92ded9f8835f230aefab84e41c0000000000000000000000000000000000000000000000000de444324c2a800000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e25031e37e0c111d6d3b510ea85be0347d375750000000000000000000000003e25031e37e0c111d6d3b510ea85be0347d37575000000000000000000000000000000000000000000000000008b12959b8e430000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ac5e0ff3b00b2bc35b0382e7fcb738f27989fc00000000000000000000000008ac5e0ff3b00b2bc35b0382e7fcb738f27989fc00000000000000000000000000000000000000000000000000078a43b9601ba0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c920d0261ac02532922a4af66168fbcf8b0a8ed0000000000000000000000000c920d0261ac02532922a4af66168fbcf8b0a8ed0000000000000000000000000000000000000000000000000214e8348c4f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3fa725536edce8a7d3a169ef093c6ea17c796f1000000000000000000000000a3fa725536edce8a7d3a169ef093c6ea17c796f10000000000000000000000000000000000000000000000000051b660cdd5800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3fa725536edce8a7d3a169ef093c6ea17c796f1000000000000000000000000a3fa725536edce8a7d3a169ef093c6ea17c796f1000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a3fa725536edce8a7d3a169ef093c6ea17c796f1000000000000000000000000a3fa725536edce8a7d3a169ef093c6ea17c796f1000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15090,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029c2fad45523f97940d8d2e7e0fa6c9081bc4a4f00000000000000000000000029c2fad45523f97940d8d2e7e0fa6c9081bc4a4f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15091,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000679d91865fdb6792c61e7a275012380fc47022d3000000000000000000000000679d91865fdb6792c61e7a275012380fc47022d30000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eabb2157a5fc3cd650a0e3d0e8c9c6894e1b756b000000000000000000000000eabb2157a5fc3cd650a0e3d0e8c9c6894e1b756b000000000000000000000000000000000000000000000000023512699b531c7e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8b3b67bdbcb00e4a2dc80c3c75e54baf51794573d4f731c5f78b73d43d4a9589,2022-08-02 20:47:32.000 UTC,0,true +15093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac5201f9e7d908a9877929807cd878051b7f2d50000000000000000000000000ac5201f9e7d908a9877929807cd878051b7f2d50000000000000000000000000000000000000000000000000104aa4469555649800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001df8da860dd62a439361d1ec0446dd3a440cf1d90000000000000000000000001df8da860dd62a439361d1ec0446dd3a440cf1d900000000000000000000000000000000000000000000000000bc12d0749d289300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000088f96204a47c3bd173b672a49f010149c4bd802c00000000000000000000000088f96204a47c3bd173b672a49f010149c4bd802c000000000000000000000000000000000000000000000000000000005355bab900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc29d61e6915b42f7c46465dfc854d63218a5d1a000000000000000000000000cc29d61e6915b42f7c46465dfc854d63218a5d1a0000000000000000000000000000000000000000000000000158f8c568781f6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e67500000000000000000000000003ab458634910aad20ef5f1c8ee96f1d6ac549190000000000000000000000007fb688ccf682d58f86d7e38e03f9d22e7705448b0000000000000000000000003b71f26ad2e05fee688391929dfa73fd672cb79d0000000000000000000000003b71f26ad2e05fee688391929dfa73fd672cb79d000000000000000000000000000000000000000000000001feb3dd067660000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15106,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d47666e190166383c1623ab7a806cc2b29bdcbd6000000000000000000000000d47666e190166383c1623ab7a806cc2b29bdcbd6000000000000000000000000000000000000000000000000032d0ae6378a94f700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099f9353111fdb15312af41c9646ac810b70980f000000000000000000000000099f9353111fdb15312af41c9646ac810b70980f000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15108,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099f9353111fdb15312af41c9646ac810b70980f000000000000000000000000099f9353111fdb15312af41c9646ac810b70980f000000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15110,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099f9353111fdb15312af41c9646ac810b70980f000000000000000000000000099f9353111fdb15312af41c9646ac810b70980f000000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15112,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e054e91786d9eb097d166027b9c7428a6a96dd10000000000000000000000001e054e91786d9eb097d166027b9c7428a6a96dd10000000000000000000000000000000000000000000000000299543d679a183900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15114,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d242c1aba34d16ddb176aaa329cedb451bce2d00000000000000000000000002d242c1aba34d16ddb176aaa329cedb451bce2d0000000000000000000000000000000000000000000000000053ae705411254fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2bd0ccb4a763f70a29f01e5e9d85992c0801c304469da76c6a17a16a17452476,2022-03-29 20:30:15.000 UTC,0,true +15115,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001028e34f2c628e364084c99f37e6260cf9db18d20000000000000000000000001028e34f2c628e364084c99f37e6260cf9db18d200000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x98683dfb35d314377de7e1ca7aec65df3e1c57cf2e5bc9446a8c5f45d0a43fc7,2021-11-23 08:16:12.000 UTC,0,true +15120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000085dc21776b349c07c080b454e27387e32d3a2e6900000000000000000000000085dc21776b349c07c080b454e27387e32d3a2e6900000000000000000000000000000000000000000000000000757d43dfee47ba00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15121,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033ba2329f4ed833a27e8a52c1999f3ad651b046f00000000000000000000000033ba2329f4ed833a27e8a52c1999f3ad651b046f000000000000000000000000000000000000000000000000016042b2ebede80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe6f3c1e8b2052b2f7b74f312156accd81b2bafd9d7bd7310843e7ba72f7febc2,2021-12-15 06:36:00.000 UTC,0,true +15123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055a62cb69d2ac981b358aee432853f8865e934b100000000000000000000000055a62cb69d2ac981b358aee432853f8865e934b10000000000000000000000000000000000000000000000000089924782ec681f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d4919ff6577f38a75a28d1848a37ebc3f04edaa5000000000000000000000000d4919ff6577f38a75a28d1848a37ebc3f04edaa500000000000000000000000000000000000000000000000000050f044f41a1c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15126,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b26185bd5cf165190cd8ccfe10f45fba1c929380000000000000000000000000b26185bd5cf165190cd8ccfe10f45fba1c9293800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15127,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3991840aa317390b08e021e644945535dc15bcf000000000000000000000000f3991840aa317390b08e021e644945535dc15bcf00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15128,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aec73d60af3340627aff834a7f19742681c5500f000000000000000000000000aec73d60af3340627aff834a7f19742681c5500f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15129,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030de8c2ac674b359680ca58ea9cc52b3783e9f5900000000000000000000000030de8c2ac674b359680ca58ea9cc52b3783e9f5900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9171fe297b8f64f286ede0ca8f70c1ee381deeb000000000000000000000000c9171fe297b8f64f286ede0ca8f70c1ee381deeb00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f3830815e699acf83348213742915e7fb9e23040000000000000000000000008f3830815e699acf83348213742915e7fb9e230400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e676e97391094e95102795457ca9c3a8448ac093000000000000000000000000e676e97391094e95102795457ca9c3a8448ac09300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050b45690c84ba86de44b4cf653639f96cf81304000000000000000000000000050b45690c84ba86de44b4cf653639f96cf81304000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ecccb4ffeaf383a61781544e11a225be4d1170d0000000000000000000000002ecccb4ffeaf383a61781544e11a225be4d1170d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f01f671c66d803f87937e22a152c46936a5756d0000000000000000000000003f01f671c66d803f87937e22a152c46936a5756d00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb298417b4ba252f11d0cf132fdfc35f3b516bac000000000000000000000000eb298417b4ba252f11d0cf132fdfc35f3b516bac00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15137,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000336a06457c655d2ed2407bccf0945a96560f2170000000000000000000000000336a06457c655d2ed2407bccf0945a96560f21700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15138,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000284172e59721939f3fdd1e1306c84f6750140e2c000000000000000000000000284172e59721939f3fdd1e1306c84f6750140e2c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15139,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084b2411605959e7c2e11bfc35de428d582af4cf400000000000000000000000084b2411605959e7c2e11bfc35de428d582af4cf400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7af729ad4f5ba883c796375da406a0e2a4cec87000000000000000000000000e7af729ad4f5ba883c796375da406a0e2a4cec8700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15141,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038fb9ecab5c65c40bea458b02b9df1d9e71a411100000000000000000000000038fb9ecab5c65c40bea458b02b9df1d9e71a411100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15142,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002d8f962f019d32fb136bf4728407fbf951b37f600000000000000000000000002d8f962f019d32fb136bf4728407fbf951b37f600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cd521c85edf64598537ffa8e6eefa16f5fd12db0000000000000000000000004cd521c85edf64598537ffa8e6eefa16f5fd12db00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15144,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021b998c9d12ad8611e3375be5209d734c1e0285c00000000000000000000000021b998c9d12ad8611e3375be5209d734c1e0285c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15145,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e014080fcf47ee8eef764b1531f2fc8dc2d0e40c000000000000000000000000e014080fcf47ee8eef764b1531f2fc8dc2d0e40c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd020a2987273c96bd31a9ac96a1fbd6f62b9318000000000000000000000000dd020a2987273c96bd31a9ac96a1fbd6f62b931800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15147,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098abec5be0b3d45a2ceb96df9e161a0a325660cd00000000000000000000000098abec5be0b3d45a2ceb96df9e161a0a325660cd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9581d747b3a339a0a57b1c47d892461e0261102000000000000000000000000b9581d747b3a339a0a57b1c47d892461e026110200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab9e2cfcfe7a1012bee720b93f84c902a4c87a76000000000000000000000000ab9e2cfcfe7a1012bee720b93f84c902a4c87a7600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15150,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a356eba6ee53d43e227020390b19cc10c70b885c000000000000000000000000a356eba6ee53d43e227020390b19cc10c70b885c00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077f3e03da404d32002616c6d88535b5a8859930800000000000000000000000077f3e03da404d32002616c6d88535b5a8859930800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15152,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d71d32cb5fc0176fb084be646214e038bef21ab0000000000000000000000005d71d32cb5fc0176fb084be646214e038bef21ab00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a3a2f7ff6bc14a9f5a58314aa155123a6db0c090000000000000000000000001a3a2f7ff6bc14a9f5a58314aa155123a6db0c0900000000000000000000000000000000000000000000000000155f8d2f8c44f800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15154,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000677f8e0a8fc7befddba89c6c967f334fd4b8ee45000000000000000000000000677f8e0a8fc7befddba89c6c967f334fd4b8ee4500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15155,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e5c9c95396c7ddff339243873664f6394d9a7e40000000000000000000000002e5c9c95396c7ddff339243873664f6394d9a7e400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000224515d82ef8751da30f54e98c9bcda58dc858b2000000000000000000000000224515d82ef8751da30f54e98c9bcda58dc858b200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15157,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007958121e61a478f6e2a4815ede4498838373a1280000000000000000000000007958121e61a478f6e2a4815ede4498838373a12800000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15158,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed6edeafc994f3f7d41896726c774f8f5d29d5c3000000000000000000000000ed6edeafc994f3f7d41896726c774f8f5d29d5c300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003037cb40171c56cc895e9bd40fc608ff4f775c520000000000000000000000003037cb40171c56cc895e9bd40fc608ff4f775c5200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000070428f51cf940a073b6016c0529e98ff5e6004a200000000000000000000000070428f51cf940a073b6016c0529e98ff5e6004a200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15161,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e61b95d17d60d6c892c65608a5b60ecd26d85375000000000000000000000000e61b95d17d60d6c892c65608a5b60ecd26d8537500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15162,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9f42f7bd627db7bc659805dca56b2f3d04a28f6000000000000000000000000c9f42f7bd627db7bc659805dca56b2f3d04a28f600000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018c70d13cf1da0fa7a7b2d39f6ca8fc81d9a3b3e00000000000000000000000018c70d13cf1da0fa7a7b2d39f6ca8fc81d9a3b3e00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15164,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008eeed9e71389f14a3b23ba34c3857a13202314500000000000000000000000008eeed9e71389f14a3b23ba34c3857a132023145000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15165,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e24821319fd60fad948ddb2587e935a9d2f96ad1000000000000000000000000e24821319fd60fad948ddb2587e935a9d2f96ad100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ce09978479907597943dd81dc3c318b0ed5ef6d0000000000000000000000004ce09978479907597943dd81dc3c318b0ed5ef6d0000000000000000000000000000000000000000000000000000253038b4540000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15167,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009bd157e3d49c683287f132400796bf12b8e84d0d0000000000000000000000009bd157e3d49c683287f132400796bf12b8e84d0d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15170,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000949da94aecf949ea5a468aee1bdcadf60ec6b41d000000000000000000000000949da94aecf949ea5a468aee1bdcadf60ec6b41d00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000f5c44945671f4e9018ff0993e7bf9fdf573d07cb000000000000000000000000f5c44945671f4e9018ff0993e7bf9fdf573d07cb000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15172,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ad8541f86b30ea4c6a2604fd5f8924d704526360000000000000000000000008ad8541f86b30ea4c6a2604fd5f8924d70452636000000000000000000000000000000000000000000000000006649741469d10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009840f29b22a3c3427d8a9b98c6890164b859a1f00000000000000000000000009840f29b22a3c3427d8a9b98c6890164b859a1f0000000000000000000000000000000000000000000000000067f1284f43640000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15175,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003758ff8b7fca3faa76789940eeff8031e3ceeab50000000000000000000000003758ff8b7fca3faa76789940eeff8031e3ceeab500000000000000000000000000000000000000000000000000a4c21295fe77d700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000fb47cc947e5257de494086ee29fe9121bd687078000000000000000000000000fb47cc947e5257de494086ee29fe9121bd687078000000000000000000000000000000000000000000000000000000000df6663700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077388170fd75c3eda4427972a92d757764acc03100000000000000000000000077388170fd75c3eda4427972a92d757764acc031000000000000000000000000000000000000000000000000007f6f60d771bae000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1339235da383a92e18f7081cc1dc9a8bb00157f000000000000000000000000c1339235da383a92e18f7081cc1dc9a8bb00157f00000000000000000000000000000000000000000000000001eb8459891ed02d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab06c07dab7c8a220fda74b54296964c88941bc0000000000000000000000000ab06c07dab7c8a220fda74b54296964c88941bc000000000000000000000000000000000000000000000000000064ac0fdcdd34f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000006554ac8069938943ea3f9acd7edc42c3b68850f70000000000000000000000006554ac8069938943ea3f9acd7edc42c3b68850f7000000000000000000000000000000000000000000000000000000001290d0ed00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7e834d31f953157480ff3533b7f885884ccd441000000000000000000000000d7e834d31f953157480ff3533b7f885884ccd441000000000000000000000000000000000000000000000000008098de11fd423500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006554ac8069938943ea3f9acd7edc42c3b68850f70000000000000000000000006554ac8069938943ea3f9acd7edc42c3b68850f70000000000000000000000000000000000000000000000000011fd6484e15d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15184,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b510fddc194f5f771d45e1ecdff32156c5bb1aea000000000000000000000000b510fddc194f5f771d45e1ecdff32156c5bb1aea000000000000000000000000000000000000000000000000000f065708e7f30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc861260e9501ffa5b042e6ce233a637d98274d2000000000000000000000000fc861260e9501ffa5b042e6ce233a637d98274d200000000000000000000000000000000000000000000000000db3e750bf3a3b400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15197,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e239b011f5ae87a47a075562cca78d0b71706770000000000000000000000004e239b011f5ae87a47a075562cca78d0b71706770000000000000000000000000000000000000000000000000099afdfc683936100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x083d9e5a87211b70eb0b1dc14a825e05b766dbf892e399b73fc2387b6dd98ca0,2022-05-21 14:01:01.000 UTC,0,true +15202,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba8801a8e9f2ed103e89fd5acd605921bfa1cb62000000000000000000000000ba8801a8e9f2ed103e89fd5acd605921bfa1cb620000000000000000000000000000000000000000000000000060ccf3caec17d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15203,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f7b460b8bad09e2d58fb879c8bd1141aaf6f1b90000000000000000000000008f7b460b8bad09e2d58fb879c8bd1141aaf6f1b900000000000000000000000000000000000000000000000000679d894736030000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d11b1dd436fc09d61d7339e0127f92aefc88a2ae000000000000000000000000d11b1dd436fc09d61d7339e0127f92aefc88a2ae00000000000000000000000000000000000000000000000000168b4ad6e7f14000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15205,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000015f490fe47a84a50c75b0cc4c1f4b17b7188306d000000000000000000000000000000000000000000000000316336151813c381,,,1,true +15206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a31395f7ee44b6c5aef70bbd48718aa1b33b7890000000000000000000000001a31395f7ee44b6c5aef70bbd48718aa1b33b78900000000000000000000000000000000000000000000000001389e044d72381b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098e1dc7c0b1b6d55433ccebbfeb7b016070445f200000000000000000000000098e1dc7c0b1b6d55433ccebbfeb7b016070445f20000000000000000000000000000000000000000000000000020041d5496ac2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de02faa2bc5a046a59c23e5667789037a5b776ed000000000000000000000000de02faa2bc5a046a59c23e5667789037a5b776ed000000000000000000000000000000000000000000000000000279cd0dfc2eb200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029552b08d2c5f98a3de6063ea9f7b54bf291889000000000000000000000000029552b08d2c5f98a3de6063ea9f7b54bf2918890000000000000000000000000000000000000000000000000005fec5b60ef800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000042ff60bca5196455c8ae35a9ce6e423388e08c6800000000000000000000000042ff60bca5196455c8ae35a9ce6e423388e08c6800000000000000000000000000000000000000000000000000d21118bb823e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15211,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000150ac2efbb090921d5a6fdf089f9e9d285972430000000000000000000000000150ac2efbb090921d5a6fdf089f9e9d2859724300000000000000000000000000000000000000000000000000ac6256afe909cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000539018e88aa7b5277fd074e3a06bdb025f0d1cf6000000000000000000000000539018e88aa7b5277fd074e3a06bdb025f0d1cf6000000000000000000000000000000000000000000000000000d12c276b88c8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15219,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b79004340f1c6641514f165dce2171e579edd340000000000000000000000007b79004340f1c6641514f165dce2171e579edd340000000000000000000000000000000000000000000000000000fea89489800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15220,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c2ca774cfabb33b7392af0c6ab73e858f3ba6580000000000000000000000004c2ca774cfabb33b7392af0c6ab73e858f3ba65800000000000000000000000000000000000000000000000000c0b0b1cf33b4fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064a73977fe3d49f6d2ed853e0f573b6e6e730a2f00000000000000000000000064a73977fe3d49f6d2ed853e0f573b6e6e730a2f000000000000000000000000000000000000000000000000007ede2e0035011800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15224,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005af9aecb1850fc16181ebdef1f05fae66ad3f0b90000000000000000000000005af9aecb1850fc16181ebdef1f05fae66ad3f0b90000000000000000000000000000000000000000000000000dca416e776f980300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15228,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000089d345e4910b201a4780e0bfe286f56adfad7be000000000000000000000000089d345e4910b201a4780e0bfe286f56adfad7be0000000000000000000000000000000000000000000000000000000000365c04000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15230,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029d4d51dd07220879d014701bb89c03decfa7a9000000000000000000000000029d4d51dd07220879d014701bb89c03decfa7a900000000000000000000000000000000000000000000000000011e92c10b1c60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027f18241002c0d4899c08c76778dbb2229273dd500000000000000000000000027f18241002c0d4899c08c76778dbb2229273dd500000000000000000000000000000000000000000000000006b9c6bca486511600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0bd4b75dc06c7f1860d6f123103404d3f1a1c93000000000000000000000000a0bd4b75dc06c7f1860d6f123103404d3f1a1c93000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f8bd8b491928553da8440ad5b4a3354acc54b87e000000000000000000000000f8bd8b491928553da8440ad5b4a3354acc54b87e00000000000000000000000000000000000000000000000000c04cacfad4b95d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000e9554c002b8e72586e1d87f9c4f9c23b90a3b18b000000000000000000000000e9554c002b8e72586e1d87f9c4f9c23b90a3b18b000000000000000000000000000000000000000000000000000000008d539e8500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x4925811d8a0cab2f3d62b30745a56cbabd910d12b01b036878b92cd3fe0df248,2022-03-07 22:27:11.000 UTC,0,true +15238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b147c4db4e2616c0bacfb29f5c61589bc0de4dc0000000000000000000000008b147c4db4e2616c0bacfb29f5c61589bc0de4dc0000000000000000000000000000000000000000000000000051b660cdd5800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15241,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f082d20cc4abebf31f2a2d0ddae522449d7d45d0000000000000000000000002f082d20cc4abebf31f2a2d0ddae522449d7d45d0000000000000000000000000000000000000000000000000036d7c674c973fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15243,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005309ccead59405eabece0bddfd93e4a981522da70000000000000000000000005309ccead59405eabece0bddfd93e4a981522da7000000000000000000000000000000000000000000000000020f62f87a6eaa0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15244,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ad5d9a0ffa01b99d0120262db629c9c69748ad4d00000000000000000000000000000000000000000000000266f70961288b7028,,,1,true +15247,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c3086dc59a92a5eeee98f28b14ddce5a2da15290000000000000000000000008c3086dc59a92a5eeee98f28b14ddce5a2da152900000000000000000000000000000000000000000000000001550f7dca70000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6128ac5ed7993a17924bd473c98e25e053673f9000000000000000000000000e6128ac5ed7993a17924bd473c98e25e053673f900000000000000000000000000000000000000000000000000564e202910c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b69307de914273bc58d9d1e176336320a9ade464000000000000000000000000b69307de914273bc58d9d1e176336320a9ade464000000000000000000000000000000000000000000000000003e0b768c21a7ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbf16b26bb634027f0ca3b202edf478b2da9d4cf000000000000000000000000cbf16b26bb634027f0ca3b202edf478b2da9d4cf000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15254,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db0c3b9548cd7de42c362ee4d9e66c15271a4efe000000000000000000000000db0c3b9548cd7de42c362ee4d9e66c15271a4efe0000000000000000000000000000000000000000000000000275a759ce8fa17c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000618e79fa928aa226c19b7afe5fef58649a8c59fb000000000000000000000000618e79fa928aa226c19b7afe5fef58649a8c59fb00000000000000000000000000000000000000000000000000032077bc3248ce00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000029bd57d591ad823f98d3cd73da938a56ab4945e400000000000000000000000029bd57d591ad823f98d3cd73da938a56ab4945e4000000000000000000000000000000000000000000000000027f7d0bdb92000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000909fdf2feea01276081253e2486dfbc81ab491d4000000000000000000000000909fdf2feea01276081253e2486dfbc81ab491d40000000000000000000000000000000000000000000000000e1730b663ce940000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15260,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000c32fcbe1aaeccad035af0d371abeb41929efc4ed000000000000000000000000c32fcbe1aaeccad035af0d371abeb41929efc4ed00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15261,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000858804057376dad586029d21fe09b8a4f647781d000000000000000000000000858804057376dad586029d21fe09b8a4f647781d0000000000000000000000000000000000000000000000000051ab9b337db21000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15262,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000cbf16b26bb634027f0ca3b202edf478b2da9d4cf000000000000000000000000cbf16b26bb634027f0ca3b202edf478b2da9d4cf0000000000000000000000000000000000000000000000000000000000ae162b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15264,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005aad5dd01faa0d5e96a80d460560fdef84e3a46a0000000000000000000000005aad5dd01faa0d5e96a80d460560fdef84e3a46a000000000000000000000000000000000000000000000000015228f77c15370000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15265,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007357464a4692ca5466740b8f5ce0b26d6e4b01280000000000000000000000007357464a4692ca5466740b8f5ce0b26d6e4b0128000000000000000000000000000000000000000000000000000d14bd215acc4600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xad82acbd60479dfecbbd8912c1e598636959c5626b726a129716ffbed6f7abaa,2022-03-13 05:35:14.000 UTC,0,true +15266,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000112e05297b5c03a849459868d1b1af7b2b10d68a000000000000000000000000112e05297b5c03a849459868d1b1af7b2b10d68a0000000000000000000000000000000000000000000000000000000003f9755800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002d2b9e1732d729ee11dffa54f4b32a57f9cf7e550000000000000000000000002d2b9e1732d729ee11dffa54f4b32a57f9cf7e5500000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15270,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008cf0354a5175ca1cf9c14dbfc6e66cabd3d224240000000000000000000000000000000000000000000000026c9c34ee2454fdf6,,,1,true +15272,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000568e25f94a97e01865d966e244a65135e2c095c4000000000000000000000000568e25f94a97e01865d966e244a65135e2c095c4000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15274,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9fe40cc7297def42fd3759571e237b414d5c0cf000000000000000000000000f9fe40cc7297def42fd3759571e237b414d5c0cf00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e0b750efa5fb1bfed2a31ac6bb741551bcc98f40000000000000000000000006e0b750efa5fb1bfed2a31ac6bb741551bcc98f40000000000000000000000000000000000000000000000000083734dd0b0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf10001df8d9f436ba0dd3e121474aaad50f6b5a591a1da642c1ff4b5036ba2af,2022-05-21 11:14:43.000 UTC,0,true +15276,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1c7902f266c3360854ad9b6bbaaa82a52273908000000000000000000000000f1c7902f266c3360854ad9b6bbaaa82a52273908000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd6b6f5b2e9527b3420c0751925e56f1bb08a02a000000000000000000000000bd6b6f5b2e9527b3420c0751925e56f1bb08a02a000000000000000000000000000000000000000000000000005cfaf9e3c2a47c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6549effe1390db13e7df687e15add3689d0f86ee58e4e96823c0788a993b417e,2022-07-24 14:26:08.000 UTC,0,true +15279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001308443df8ff1da25bcd1a1b898a56dd66144b050000000000000000000000001308443df8ff1da25bcd1a1b898a56dd66144b05000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000003e957dd41f95c213b3b9b772472dddf7ed3b00960000000000000000000000003e957dd41f95c213b3b9b772472dddf7ed3b009600000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ae18450b90b7b6847b9f26787d6529746bb417e0000000000000000000000006ae18450b90b7b6847b9f26787d6529746bb417e000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f61efd9365cdbfd86c76827f90a1a9ad7b9ada52000000000000000000000000f61efd9365cdbfd86c76827f90a1a9ad7b9ada5200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039d4bd8f3347734c523a6775f7e4edd67baec5da00000000000000000000000039d4bd8f3347734c523a6775f7e4edd67baec5da00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15284,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a94b2a63a069a1fc3e1f730d684e7955f76d6750000000000000000000000003a94b2a63a069a1fc3e1f730d684e7955f76d67500000000000000000000000000000000000000000000000001f68e5744b98f8a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15285,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c556added55593a7da07b340a381af1278851c30000000000000000000000007c556added55593a7da07b340a381af1278851c300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ec383945e14de368782d8e063e9ac179c39f3590000000000000000000000006ec383945e14de368782d8e063e9ac179c39f359000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15287,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009622348f0a2268983c90dd4c37b5a900a23c83900000000000000000000000009622348f0a2268983c90dd4c37b5a900a23c8390000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15289,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddee7dc3288f18bd0ed48255c95f730f146738b3000000000000000000000000ddee7dc3288f18bd0ed48255c95f730f146738b300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000607c3eb4ad13036078fe5e346c092195ac7ddf0c000000000000000000000000607c3eb4ad13036078fe5e346c092195ac7ddf0c00000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15291,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f333193872a0dbbf8ad7c82579626e4c6216d5e3000000000000000000000000f333193872a0dbbf8ad7c82579626e4c6216d5e300000000000000000000000000000000000000000000000000905a3731df5cd200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15292,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053b4b974261c61ce81e433461ba5cd96fee63db100000000000000000000000053b4b974261c61ce81e433461ba5cd96fee63db1000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000008e89d60af020a59aca87767f7440386dbbf6c6300000000000000000000000008e89d60af020a59aca87767f7440386dbbf6c63000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15295,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc29516f75bb6d8e7e76566062cd90f8c3087072000000000000000000000000dc29516f75bb6d8e7e76566062cd90f8c3087072000000000000000000000000000000000000000000000000010b0e2f6b90a4df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15296,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7492674a89623bb0ab5577b658817b89e2e20ca000000000000000000000000c7492674a89623bb0ab5577b658817b89e2e20ca00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15297,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f0e8a28fb6d062c275dd20371c28e741aac880b0000000000000000000000009f0e8a28fb6d062c275dd20371c28e741aac880b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15298,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000035c8bf626c7cd9d8604dbdb6fca693471e5dbb0b0000000000000000000000000000000000000000000000033633b826da50c000,,,1,true +15299,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094fdcf186e122ba9a507c58394a5295402d2dfd000000000000000000000000094fdcf186e122ba9a507c58394a5295402d2dfd000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15300,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035c8bf626c7cd9d8604dbdb6fca693471e5dbb0b00000000000000000000000035c8bf626c7cd9d8604dbdb6fca693471e5dbb0b00000000000000000000000000000000000000000000000000fe2ee4620dcf4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0bd89eaa63dd244ae1d2bcced93d58d72d6d961000000000000000000000000c0bd89eaa63dd244ae1d2bcced93d58d72d6d961000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15302,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4520d07cea9c1915b94c1d2b788256153ecfe27000000000000000000000000f4520d07cea9c1915b94c1d2b788256153ecfe27000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c014d4024ecf998456b226e38a7607991f1aac72000000000000000000000000c014d4024ecf998456b226e38a7607991f1aac7200000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15304,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b80914f7918df483d216198d7e2fb8d4e14af408000000000000000000000000b80914f7918df483d216198d7e2fb8d4e14af40800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d24f83d0eac36cd83eed870f520b1c3caa5d2b07000000000000000000000000d24f83d0eac36cd83eed870f520b1c3caa5d2b0700000000000000000000000000000000000000000000000000000cbba106e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15310,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000058e2d39109fa3a452b229fc03cf9d3b61324cbcd00000000000000000000000058e2d39109fa3a452b229fc03cf9d3b61324cbcd00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15311,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000039ca2a2d5854c613fb1b3f8208e4f241942587b000000000000000000000000039ca2a2d5854c613fb1b3f8208e4f241942587b0000000000000000000000000000000000000000000000000000000000314e2a900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15312,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c84ab5000d34a853231d6ce90a28431106f4ca55000000000000000000000000c84ab5000d34a853231d6ce90a28431106f4ca55000000000000000000000000000000000000000000000000007fe5cf2bea000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15313,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069a263804bc8ea966095ea21aea58b9ea6bf52a700000000000000000000000069a263804bc8ea966095ea21aea58b9ea6bf52a7000000000000000000000000000000000000000000000000000ef3528bc8a70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15315,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3f1abd4fc3435c452b6267c407ec535800b52f0000000000000000000000000e3f1abd4fc3435c452b6267c407ec535800b52f00000000000000000000000000000000000000000000000000026ff85c3b8a9b400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15316,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000122c85f702c56dda52c951f1d855652150a1e067000000000000000000000000122c85f702c56dda52c951f1d855652150a1e067000000000000000000000000000000000000000000000000001f157551dfaac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fa4c5ac56045630bf0c75b42ca8259fda61effe0000000000000000000000004fa4c5ac56045630bf0c75b42ca8259fda61effe0000000000000000000000000000000000000000000000000044e7809f5fa40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000007345344510b1104514666a6f4c0aa85ff8f556360000000000000000000000007345344510b1104514666a6f4c0aa85ff8f5563600000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15319,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dee84d469ea2c8bb4af371ecdc95a71a77322a40000000000000000000000002dee84d469ea2c8bb4af371ecdc95a71a77322a40000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15322,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000b173b9014a0a36aac51ee4957bc8c7e20686d3f0000000000000000000000000000000000000000000000005998fce1a86ecd1b,,,1,true +15323,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ad0e907a3f3c517acbfd9054b43f743e4edbbe9500000000000000000000000000000000000000000000000ef644f9b077d00000,0xcdd420b678eb08cee4c6b481b887daa19d4d870142bcb2d0cdf6d4b29f91bf34,2021-11-30 00:28:36.000 UTC,0,true +15325,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000122c85f702c56dda52c951f1d855652150a1e067000000000000000000000000122c85f702c56dda52c951f1d855652150a1e06700000000000000000000000000000000000000000000000000464a9e5e85a65d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15332,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a708b4d523dca59b28b47e79851a5ca52f9dd78a000000000000000000000000a708b4d523dca59b28b47e79851a5ca52f9dd78a0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15335,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000895c5aa8f7abd95f5b152bb5c7f2052972013fa1000000000000000000000000895c5aa8f7abd95f5b152bb5c7f2052972013fa10000000000000000000000000000000000000000000000000000000002f98f6100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15343,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e4b293c7fda80b545561ec599bd7de5208901fe0000000000000000000000005e4b293c7fda80b545561ec599bd7de5208901fe000000000000000000000000000000000000000000000000015bd15ba65dec8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15344,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a269a9cc18d1fb05ffd567e3b1f6e8bf2d841530000000000000000000000005a269a9cc18d1fb05ffd567e3b1f6e8bf2d841530000000000000000000000000000000000000000000000000020910a61d8320000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c74619e359640019b1c9f53d95ad3489f8b0da60000000000000000000000007c74619e359640019b1c9f53d95ad3489f8b0da600000000000000000000000000000000000000000000000000009836e524090000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac844070b40db6042b99e206b4ed1dbdb5fa676d000000000000000000000000ac844070b40db6042b99e206b4ed1dbdb5fa676d000000000000000000000000000000000000000000000000001f83b7fd6c090000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15347,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066e623994cd56fd05f6ec18f82110a8b6535819d00000000000000000000000066e623994cd56fd05f6ec18f82110a8b6535819d000000000000000000000000000000000000000000000000000ee9159a39984000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f3111165ef850b11f50a5f45074e7becca7cbfd0000000000000000000000002f3111165ef850b11f50a5f45074e7becca7cbfd000000000000000000000000000000000000000000000000000d45786189040000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15350,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eacc381ed43f477e8d74be5f3d87f583db82c89d000000000000000000000000eacc381ed43f477e8d74be5f3d87f583db82c89d000000000000000000000000000000000000000000000000000d40b74241310000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d10248ef4907d54f012af7b2f8ddc2edd611adae000000000000000000000000d10248ef4907d54f012af7b2f8ddc2edd611adae000000000000000000000000000000000000000000000000000d40b74241310000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bca10a7a49d1f56a92a541b91858abf7821f0a10000000000000000000000000bca10a7a49d1f56a92a541b91858abf7821f0a10000000000000000000000000000000000000000000000000000e94cb4b07710000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043e7f3e1583216053f8bdbe300738d46f2dcd71800000000000000000000000043e7f3e1583216053f8bdbe300738d46f2dcd718000000000000000000000000000000000000000000000000000e81c6cde8250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15354,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3aeedd405726b61bfc4c099309b237549b6d78f000000000000000000000000f3aeedd405726b61bfc4c099309b237549b6d78f000000000000000000000000000000000000000000000000000e81c6cde8250000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3aeedd405726b61bfc4c099309b237549b6d78f000000000000000000000000f3aeedd405726b61bfc4c099309b237549b6d78f00000000000000000000000000000000000000000000000000909a26d1c3334000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15356,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb9ef9eea95a4492e3f05973a08c75093d673dc5000000000000000000000000eb9ef9eea95a4492e3f05973a08c75093d673dc5000000000000000000000000000000000000000000000000001cd715640c076f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15359,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4a86fdfb80071d28f385bdc7b7a04811ef4c5eb000000000000000000000000a4a86fdfb80071d28f385bdc7b7a04811ef4c5eb0000000000000000000000000000000000000000000000000017550b48febb8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000000dcea91eb1418949cb112d733fc6c3603829e4d30000000000000000000000000dcea91eb1418949cb112d733fc6c3603829e4d300000000000000000000000000000000000000000000000000000000011b480a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000729aefa54c7825f89c155683a133d60e7167e528000000000000000000000000729aefa54c7825f89c155683a133d60e7167e52800000000000000000000000000000000000000000000000000a87991d1a7208000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc29d61e6915b42f7c46465dfc854d63218a5d1a000000000000000000000000cc29d61e6915b42f7c46465dfc854d63218a5d1a00000000000000000000000000000000000000000000000000403fb64baae07c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15368,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a732b8f964eda419441e969e7a49392360e860f70000000000000000000000000000000000000000000000000cf1a3f4e4b748ee,,,1,true +15369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000054e6e074299b4b32ab7dcbe44952677fccca10f200000000000000000000000054e6e074299b4b32ab7dcbe44952677fccca10f200000000000000000000000000000000000000000000000001b262753631cbcd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xee9ad62e398258937bd32d66faea8869f870f9ef4ed89d5bd2ec03dc09f3a156,2021-12-13 06:44:40.000 UTC,0,true +15372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046ced0e736cdbb8d467b56df1dea1edf7544495800000000000000000000000046ced0e736cdbb8d467b56df1dea1edf7544495800000000000000000000000000000000000000000000000001914a39af30436300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc0b360c8a277a0ed6bc115905983679f68238de71d51593f8e8a8d46636a7a90,2021-12-13 06:57:36.000 UTC,0,true +15374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7518d58aa2a0c05ee28e4589e9ba58165de2df5000000000000000000000000d7518d58aa2a0c05ee28e4589e9ba58165de2df50000000000000000000000000000000000000000000000000c7d713b49da000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xfcc8e39964c3aad6ec6cffba797cca3fdf03901c916b9c8b43683ec8f064fa64,2022-01-17 13:27:45.000 UTC,0,true +15375,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b573b0781ebbff1301e26dfb15edd774f8f4cb85000000000000000000000000b573b0781ebbff1301e26dfb15edd774f8f4cb8500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3b5b2b7c2e97331a606466e88cda86e359e1f61000000000000000000000000d3b5b2b7c2e97331a606466e88cda86e359e1f6100000000000000000000000000000000000000000000000000176b8103bcc08000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15383,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e6436d5c2b8a02cfdb853607418adc44eec38876000000000000000000000000e6436d5c2b8a02cfdb853607418adc44eec38876000000000000000000000000000000000000000000000000012927994b97cfd100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000245a4887c7ca101419d629e447f2de60d8861de4000000000000000000000000245a4887c7ca101419d629e447f2de60d8861de400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1c805676244085838262806ffb92b21421e5b8d000000000000000000000000d1c805676244085838262806ffb92b21421e5b8d00000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059e175bcb48a316b91bdbbaae8cd0758b8a7259500000000000000000000000059e175bcb48a316b91bdbbaae8cd0758b8a7259500000000000000000000000000000000000000000000000000006a439063453300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15388,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065240476b113ee6ea1325b3ebe47d21acfa037f700000000000000000000000065240476b113ee6ea1325b3ebe47d21acfa037f700000000000000000000000000000000000000000000000006df2da4bfb17e5e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15390,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4f80a0d2434fe62bae26627fe4c228c0723f0b2000000000000000000000000f4f80a0d2434fe62bae26627fe4c228c0723f0b200000000000000000000000000000000000000000000000006c7615549cfc0ca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15391,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000566bee2e257a1a606cb7632486f77d8b8b7be075000000000000000000000000566bee2e257a1a606cb7632486f77d8b8b7be075000000000000000000000000000000000000000000000000000287834ea7524800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15392,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf9f99c643b28daec98de3f70a4b84c271c2b404000000000000000000000000cf9f99c643b28daec98de3f70a4b84c271c2b404000000000000000000000000000000000000000000000000006674e8fdee25d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd786d10d0a2e7257ca750317b5fac5ba6b7185cc8aa99bf3ff7ef94a9b635c0e,2022-04-27 10:03:45.000 UTC,0,true +15393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002835720be787d30b58aa7c56aea19c1e3053e10b0000000000000000000000002835720be787d30b58aa7c56aea19c1e3053e10b000000000000000000000000000000000000000000000000000032c09176e4a200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15394,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000431e4b84e3b8a739af3394c3a4463e62a8c721c100000000000000000000000000000000000000000000001d89e11e88b65afb4f,0x023479b94b7eebcb8c1b8e2da3447695bca0b1d0f5d720368e05914f53ace59c,2021-11-22 09:56:35.000 UTC,0,true +15395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1490a127021f5dbeeb92a4156179a93679c76b6000000000000000000000000d1490a127021f5dbeeb92a4156179a93679c76b600000000000000000000000000000000000000000000000005801a3f2da94b3100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7e6214e3dec588af0a92f68f86b55540c5dec5c2f15ae23be2b64953d574c638,2022-01-19 08:35:44.000 UTC,0,true +15398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f98fafa9f99a0e493e4220841a71c7475f5dee76000000000000000000000000f98fafa9f99a0e493e4220841a71c7475f5dee760000000000000000000000000000000000000000000000000017b9d4d0d2660000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000076e2c6d6f961168dd892516438ec807933d0941f00000000000000000000000076e2c6d6f961168dd892516438ec807933d0941f0000000000000000000000000000000000000000000000000042db1dd805406f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x95c3fedec2a0df0305d727e5c9671e74a2a21e7366bd947bd076c2867bc0454f,2021-11-27 22:03:17.000 UTC,0,true +15400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006777fca2ffb7376a6df2844bf684e48250a9ce0e0000000000000000000000006777fca2ffb7376a6df2844bf684e48250a9ce0e00000000000000000000000000000000000000000000000000ae37a5a56a690000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e56d4397e492a5ce2867e30c5547f312c1c25f56000000000000000000000000e56d4397e492a5ce2867e30c5547f312c1c25f5600000000000000000000000000000000000000000000000000215a0028e0dfa500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a1423a1c631711dd2f64b887bceff09917e3ad50000000000000000000000001a1423a1c631711dd2f64b887bceff09917e3ad5000000000000000000000000000000000000000000000000000654c932203d6a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ad68d0af76006c762edfe72aa49b8b088d26f1e0000000000000000000000005ad68d0af76006c762edfe72aa49b8b088d26f1e000000000000000000000000000000000000000000000000000e86a947e29f9700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x50f92acb95d3986dd4944d2f5dd64233022bbf4dd0c0fbeed35e4f6c6347df9d,2022-05-28 22:44:03.000 UTC,0,true +15413,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c114b578dab1e6417afdf3f94f6bd4ced508d392000000000000000000000000c114b578dab1e6417afdf3f94f6bd4ced508d392000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15414,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000303308d5f4fef62ce6c246f00b886a2420a5bc0f000000000000000000000000303308d5f4fef62ce6c246f00b886a2420a5bc0f000000000000000000000000000000000000000000000000002c6b91062aaec300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15415,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a2566b9a398958590b39b9a9013383a71a73a2a0000000000000000000000005a2566b9a398958590b39b9a9013383a71a73a2a00000000000000000000000000000000000000000000000000049e57d635400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033e0f6b6c246fa636fd250a4af6166b83fa8a7e200000000000000000000000033e0f6b6c246fa636fd250a4af6166b83fa8a7e20000000000000000000000000000000000000000000000000000223d9d92e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b9f34a609b6fbc2954d960feb88252a35d0c5c44000000000000000000000000b9f34a609b6fbc2954d960feb88252a35d0c5c440000000000000000000000000000000000000000000000000000ff84259fde0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15418,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6118f12ef110c9c2c3168f08787af5d569cc62c000000000000000000000000b6118f12ef110c9c2c3168f08787af5d569cc62c000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001687491cb797f011790f349cbf8969dad49fcd300000000000000000000000001687491cb797f011790f349cbf8969dad49fcd3000000000000000000000000000000000000000000000000001d55cf064e604000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000374098e411a4aaf574ca9080512125764df217d0000000000000000000000000374098e411a4aaf574ca9080512125764df217d0000000000000000000000000000000000000000000000000001c91b0f23920000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dfc24a11ba5ce6be386444c46b79308189e991cb000000000000000000000000dfc24a11ba5ce6be386444c46b79308189e991cb0000000000000000000000000000000000000000000000000001ddcd1ed4b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e12598b84a6e5e2436e268d403f2f79d1af23807000000000000000000000000e12598b84a6e5e2436e268d403f2f79d1af238070000000000000000000000000000000000000000000000000332555df265d71500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x71b63083278921c32fb30f4ede37688b95df8c7af8df6ba89f6ea27b7d47931c,2021-12-11 09:53:04.000 UTC,0,true +15427,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000c1a1c3bed7bff1418487b6af7f3fb9e13fc51969000000000000000000000000c1a1c3bed7bff1418487b6af7f3fb9e13fc519690000000000000000000000000000000000000000000000000000000000b5946000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000c1a1c3bed7bff1418487b6af7f3fb9e13fc51969000000000000000000000000c1a1c3bed7bff1418487b6af7f3fb9e13fc519690000000000000000000000000000000000000000000000000000000000b5c5b100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4ef68733ce0bbac45f02c2b183c9ce7c21843dd000000000000000000000000c4ef68733ce0bbac45f02c2b183c9ce7c21843dd000000000000000000000000000000000000000000000000005e1edc5305d4ea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000c1a1c3bed7bff1418487b6af7f3fb9e13fc51969000000000000000000000000c1a1c3bed7bff1418487b6af7f3fb9e13fc519690000000000000000000000000000000000000000000000000000000000c6006300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000c1a1c3bed7bff1418487b6af7f3fb9e13fc51969000000000000000000000000c1a1c3bed7bff1418487b6af7f3fb9e13fc519690000000000000000000000000000000000000000000000000000000000bbe60f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000008360cd7c6d87f9f4ad9434dd94b836c0ca61c8530000000000000000000000008360cd7c6d87f9f4ad9434dd94b836c0ca61c85300000000000000000000000000000000000000000000000000000000199f45bf00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15434,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061fac34ed5aba1edc80e1267e830270401bcc89000000000000000000000000061fac34ed5aba1edc80e1267e830270401bcc8900000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15435,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008360cd7c6d87f9f4ad9434dd94b836c0ca61c8530000000000000000000000008360cd7c6d87f9f4ad9434dd94b836c0ca61c853000000000000000000000000000000000000000000000000001bb6282e8b0ec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e62556766debc521c4f745846d275578b7947400000000000000000000000008e62556766debc521c4f745846d275578b7947400000000000000000000000000000000000000000000000000181ed1f85e8911100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae416e324029acb10367349234c13edf44b0ddfd000000000000000000000000ae416e324029acb10367349234c13edf44b0ddfd00000000000000000000000000000000000000000000000002b075761a6f4a5800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15438,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4c458f31f1cd636c221e7e5d6e2f9d3105e4b17000000000000000000000000f4c458f31f1cd636c221e7e5d6e2f9d3105e4b1700000000000000000000000000000000000000000000000000770a91ac13adca00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000007532551bed089a581d17618abb0286b6a93d7e8c0000000000000000000000007532551bed089a581d17618abb0286b6a93d7e8c00000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15440,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd713a96cb3d6f1454ec644e8b017b419a0aa1c6000000000000000000000000dd713a96cb3d6f1454ec644e8b017b419a0aa1c600000000000000000000000000000000000000000000000000ac6c265dc5480000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15441,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000e8b8c88c0c2757f03679e2ef1b43a3ff2e021962000000000000000000000000e8b8c88c0c2757f03679e2ef1b43a3ff2e021962000000000000000000000000000000000000000000000000000000000187a3e500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15442,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000e8b8c88c0c2757f03679e2ef1b43a3ff2e021962000000000000000000000000e8b8c88c0c2757f03679e2ef1b43a3ff2e021962000000000000000000000000000000000000000000000000000000000a8a661700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15443,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000901f007510f776c978cce30df4a59b49e11650c6000000000000000000000000901f007510f776c978cce30df4a59b49e11650c6000000000000000000000000000000000000000000000000005c543dfaa1660000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15444,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000e8b8c88c0c2757f03679e2ef1b43a3ff2e021962000000000000000000000000e8b8c88c0c2757f03679e2ef1b43a3ff2e0219620000000000000000000000000000000000000000000000000000000000bc4e3700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e35e4a4b3db623f5997065068c0eefc6da752b19000000000000000000000000e35e4a4b3db623f5997065068c0eefc6da752b1900000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000079d2f1e855ecbff1e3d24aa2d05bc8bab2dd7b7000000000000000000000000079d2f1e855ecbff1e3d24aa2d05bc8bab2dd7b70000000000000000000000000000000000000000000000000002da05de16ca93500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ecf67f602c23698ee680914271e900175a65a403000000000000000000000000ecf67f602c23698ee680914271e900175a65a4030000000000000000000000000000000000000000000000000000000000cfad0600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15450,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000009aa6d4697057fa85023930c2062410d38adc407d0000000000000000000000009aa6d4697057fa85023930c2062410d38adc407d0000000000000000000000000000000000000000000000000000000002254abf00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b985fc8f4012a2df292da9aa323967b98c289faf000000000000000000000000b985fc8f4012a2df292da9aa323967b98c289faf000000000000000000000000000000000000000000000000001faf0bfd19092f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000d20574d9739f084b67b8a2ad0cebf670284d1c4b000000000000000000000000d20574d9739f084b67b8a2ad0cebf670284d1c4b000000000000000000000000000000000000000000000000000000000113221800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15453,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ecf67f602c23698ee680914271e900175a65a403000000000000000000000000ecf67f602c23698ee680914271e900175a65a4030000000000000000000000000000000000000000000000000000000000b6211d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15454,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ecf67f602c23698ee680914271e900175a65a403000000000000000000000000ecf67f602c23698ee680914271e900175a65a4030000000000000000000000000000000000000000000000000000000000d6cb8300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005eb81691fd7505b796241dcf2f62231928d8f6ec0000000000000000000000005eb81691fd7505b796241dcf2f62231928d8f6ec0000000000000000000000000000000000000000000000000305a7e543d158cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3c21b5d95f52635fab1d0c2a6b84c4f6924e54f000000000000000000000000f3c21b5d95f52635fab1d0c2a6b84c4f6924e54f0000000000000000000000000000000000000000000000000019defba741528000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15463,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000006d8fea199019d796c848ae1d67fc781f61aef1de0000000000000000000000006d8fea199019d796c848ae1d67fc781f61aef1de00000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15464,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a3533bc8606bcdaaa0a2ac6e8b5d81c9c6349940000000000000000000000005a3533bc8606bcdaaa0a2ac6e8b5d81c9c63499400000000000000000000000000000000000000000000000000071afd498d000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b2855918fff918739d96b1d930b1b3e3a0a95000000000000000000000000009b2855918fff918739d96b1d930b1b3e3a0a950000000000000000000000000000000000000000000000000000049e57d635400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000098e640296317a9f5ab7078ebeb7e685da030a19a00000000000000000000000098e640296317a9f5ab7078ebeb7e685da030a19a00000000000000000000000000000000000000000000000000044364c5bb000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ebe4cdef0ccc5c84ab5259501e8ede675ee7cae2000000000000000000000000ebe4cdef0ccc5c84ab5259501e8ede675ee7cae200000000000000000000000000000000000000000000000003ed4e6d5a5ef86a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15468,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000063389e216b926ec5f705d47028765c35c89825be0000000000000000000000000000000000000000000000004563918244f40000,,,1,true +15469,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c308b8857c2621685fbd9f762bea9fdb8bad1fc6000000000000000000000000c308b8857c2621685fbd9f762bea9fdb8bad1fc6000000000000000000000000000000000000000000000000001a85f051976a8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000aa4ddacb7a5bf7613c10404dab72523569e77860000000000000000000000000aa4ddacb7a5bf7613c10404dab72523569e77860000000000000000000000000000000000000000000000000016800d4dde9f4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15484,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d23b036e1e0227631c76aa74b97b1e539661c9d1000000000000000000000000d23b036e1e0227631c76aa74b97b1e539661c9d1000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15486,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e8b8c88c0c2757f03679e2ef1b43a3ff2e021962000000000000000000000000e8b8c88c0c2757f03679e2ef1b43a3ff2e02196200000000000000000000000000000000000000000000000000a7ccba815cb74000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15487,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a928c403af1993eb309451a3559f8946e7d81f7f000000000000000000000000a928c403af1993eb309451a3559f8946e7d81f7f00000000000000000000000000000000000000000000000006d96b07d16e8a9e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c33cf53b8e2b70a101ede8b334169dbf6e9a4ff3000000000000000000000000c33cf53b8e2b70a101ede8b334169dbf6e9a4ff3000000000000000000000000000000000000000000000000013d695097163b1500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa27bcb140e9e2b64d7a54d77b7194052b330311000000000000000000000000fa27bcb140e9e2b64d7a54d77b7194052b33031100000000000000000000000000000000000000000000000003121c0638ace06f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3140bdbc0c880c3ee641ad72cf445d354a59012000000000000000000000000f3140bdbc0c880c3ee641ad72cf445d354a590120000000000000000000000000000000000000000000000000247fe25b1314fa700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9de017b537f3eaa0c360328ffd2f73b8bff5e3fc342aefdcd72af50f61d27a76,2022-06-01 12:25:28.000 UTC,0,true +15495,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008e7488075d58158083330e9f37db55056b5edb330000000000000000000000000000000000000000000000000de0b6b3a7640000,0x9fc9c127408408704529378d2b7b40ea0f214244c41465dee757c2600e75ae90,2022-03-10 11:49:57.000 UTC,0,true +15497,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b9e03299d9449d3add284a1c13ab2566e876d640000000000000000000000002b9e03299d9449d3add284a1c13ab2566e876d64000000000000000000000000000000000000000000000000036ddc7ce2074ad100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2baab833765c964b6caddc27b84dbca79f9028e63a2d9fd3e0a6a4ff39372b78,2021-12-04 12:27:52.000 UTC,0,true +15500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da263667e51f7bdd638abf6d9f67d7327745363d000000000000000000000000da263667e51f7bdd638abf6d9f67d7327745363d000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c2f1004ad19f2ff281de8015c39a23702fc523f0000000000000000000000000c2f1004ad19f2ff281de8015c39a23702fc523f0000000000000000000000000000000000000000000000000b774bdb944a9c7000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x547805a689d5c4da7968db7ebc0c341f3eda99864aab28daacac2af5366ac42d,2022-03-26 13:07:54.000 UTC,0,true +15502,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f600000000000000000000000084c567a704ba44a9166ddbd0cd73c2a7a8ac987f00000000000000000000000084c567a704ba44a9166ddbd0cd73c2a7a8ac987f000000000000000000000000000000000000000000000000f540559538888a9c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15503,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eeeaa0b5efdea861832e2efafc38dc9e8b47c888000000000000000000000000eeeaa0b5efdea861832e2efafc38dc9e8b47c88800000000000000000000000000000000000000000000000005d2a2807f73141800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000621256092aa05304bd2dfb3eb1836a6b259444db000000000000000000000000621256092aa05304bd2dfb3eb1836a6b259444db0000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe939bbfecd67f042dbb6e6f4348931149c6fa19d5006b947dbc257d1104c4dc5,2021-12-15 09:08:57.000 UTC,0,true +15506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d44988f48d651ea649df93ea83fffe2e1f777d20000000000000000000000002d44988f48d651ea649df93ea83fffe2e1f777d2000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b62d4d345cb18372e3375effd5ffaaaa591726b4000000000000000000000000b62d4d345cb18372e3375effd5ffaaaa591726b400000000000000000000000000000000000000000000000001a5578275fbfe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032e2509cbee40743ccdda0af60ba43d5deb62d4700000000000000000000000032e2509cbee40743ccdda0af60ba43d5deb62d4700000000000000000000000000000000000000000000000000ad13ac064dad0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab7b7ff0e3103d0ab5d87aa4f1988789bee3e504000000000000000000000000ab7b7ff0e3103d0ab5d87aa4f1988789bee3e5040000000000000000000000000000000000000000000000000d6212c57779f9f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15517,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005986115f255b23fe5904a62771f2506abda134760000000000000000000000005986115f255b23fe5904a62771f2506abda13476000000000000000000000000000000000000000000000000006f3c4773eae00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ce31bcaa6a0d361635ff3b16f5170bb2c78becb0000000000000000000000004ce31bcaa6a0d361635ff3b16f5170bb2c78becb000000000000000000000000000000000000000000000000006db53246aa000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15520,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045c960d3342f778939bd4e121c0d07bf3692ca2300000000000000000000000045c960d3342f778939bd4e121c0d07bf3692ca2300000000000000000000000000000000000000000000000000a20f19d898305400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x95727129f89214160bfa9106ed4cc49ea1135b5dabd4d714bfdcf56bf2e02d8d,2022-02-21 03:42:32.000 UTC,0,true +15521,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1f7c6a69ea406cad335a94af565d57b66cbaf0d000000000000000000000000f1f7c6a69ea406cad335a94af565d57b66cbaf0d000000000000000000000000000000000000000000000000014e195748e939d800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15525,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0b3f4211808f21331952d18065921c7465efa63000000000000000000000000f0b3f4211808f21331952d18065921c7465efa63000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1f493c549e296586be0c532bdb95a3bdccdd33984ca5c615e1a4f84802539c3e,2022-06-12 07:57:21.000 UTC,0,true +15527,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000480d57dc208fd4c5a2306f0c8614621053b7c643000000000000000000000000480d57dc208fd4c5a2306f0c8614621053b7c6430000000000000000000000000000000000000000000000000091da9d457a0a9100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15528,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004976af020929f31b79218567af8ef7b019f3d7bb0000000000000000000000004976af020929f31b79218567af8ef7b019f3d7bb000000000000000000000000000000000000000000000000008cb1f6f437025b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000657002379861b62b241cdf1e622c76902547cd65000000000000000000000000657002379861b62b241cdf1e622c76902547cd65000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15530,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000086849b0122425c1ba46b0916562b36a6b799794200000000000000000000000000000000000000000000000011772214a1a6fc2e,,,1,true +15534,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f221d4a60e5610c74b017ecb3eaef32ca61730fe000000000000000000000000f221d4a60e5610c74b017ecb3eaef32ca61730fe00000000000000000000000000000000000000000000000000a13e59641a178800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1556c33248015034466923cee1895bef9a405346a6f231d70fc4f15f4eec9729,2022-03-20 10:05:49.000 UTC,0,true +15535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000139eeb895d86939eb18b52b3347402dddeaad378000000000000000000000000139eeb895d86939eb18b52b3347402dddeaad37800000000000000000000000000000000000000000000000000ade5040d7eff0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15538,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009bd1f47bf530f5e0eb44dda1236e4c8e817dcd8d0000000000000000000000009bd1f47bf530f5e0eb44dda1236e4c8e817dcd8d00000000000000000000000000000000000000000000000001f35e87950f7f3200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090eb8081c94b56a8278d016252793fd82c0059e700000000000000000000000090eb8081c94b56a8278d016252793fd82c0059e700000000000000000000000000000000000000000000000000a717b0fe679a3a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x42e4d2a8f70491661b772fd9d0173d43152306f778a70ec1fb7caa73345889a7,2022-08-03 05:13:06.000 UTC,0,true +15541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f61201a26d24891926c4066adbd98685a00f1f70000000000000000000000004f61201a26d24891926c4066adbd98685a00f1f7000000000000000000000000000000000000000000000000014f5d7be772aa5900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15542,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094520e2f86afd790263715f727d0d35f533f2a3600000000000000000000000094520e2f86afd790263715f727d0d35f533f2a360000000000000000000000000000000000000000000000000008d6d09ee0d2d600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000009bbc644ec23f35d62cc09e68bfd9f18ba7a3ba900000000000000000000000009bbc644ec23f35d62cc09e68bfd9f18ba7a3ba90000000000000000000000000000000000000000000000000153ffcf40bc0f1900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15548,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4b6508f51ba37765846a12d4362205acef278e1000000000000000000000000a4b6508f51ba37765846a12d4362205acef278e10000000000000000000000000000000000000000000000000587549450bc780000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd3c3a4d4f82452eda6cead765e4cbb616b1ef207db8bb03801a940684b4eed45,2022-03-10 00:57:43.000 UTC,0,true +15552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000885f1d2f1f29adea24a8f23223f04f154bcc2e4f000000000000000000000000885f1d2f1f29adea24a8f23223f04f154bcc2e4f000000000000000000000000000000000000000000000000002d1fab3e0b9be800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001675d5e5f800b117530d62b7da664dbf8bdc8f190000000000000000000000001675d5e5f800b117530d62b7da664dbf8bdc8f1900000000000000000000000000000000000000000000000000047f6e8d65bc8a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da4bcd3ed7c54bbedca1012bdf9999140b9ec840000000000000000000000000da4bcd3ed7c54bbedca1012bdf9999140b9ec840000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000a5458cdb2608f25c874cf4d20dec1f6edace6b11000000000000000000000000a5458cdb2608f25c874cf4d20dec1f6edace6b1100000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b5a40b8563e721ef298c44ba4a4440f67b5af170000000000000000000000008b5a40b8563e721ef298c44ba4a4440f67b5af170000000000000000000000000000000000000000000000000000886c98b7600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038fa9da35d8905c0367e68ab3c90920be33ed64200000000000000000000000038fa9da35d8905c0367e68ab3c90920be33ed642000000000000000000000000000000000000000000000000002714711487800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000236187c608cfc18f602fe35625533395ecdd2ada000000000000000000000000236187c608cfc18f602fe35625533395ecdd2ada00000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15565,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2f5207b459a3b6fbeaabdbc6ececed7ca878d1a000000000000000000000000f2f5207b459a3b6fbeaabdbc6ececed7ca878d1a00000000000000000000000000000000000000000000000002270128669ac7bb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b5a40b8563e721ef298c44ba4a4440f67b5af170000000000000000000000008b5a40b8563e721ef298c44ba4a4440f67b5af170000000000000000000000000000000000000000000000000000886c98b7600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15570,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e89cf21911a160730d27e62589f52869a1abc5d0000000000000000000000006e89cf21911a160730d27e62589f52869a1abc5d0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15573,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000cfc7a084444c5a41ee0e3df3333a5f203c98f3ee000000000000000000000000000000000000000000000003420e179398fa0000,,,1,true +15574,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fbbac497570e775ae6bb6393b1ef9584ac2262c0000000000000000000000000fbbac497570e775ae6bb6393b1ef9584ac2262c0000000000000000000000000000000000000000000000000ddb6da88a20420000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0a7aade64bface56abb7f5ca2190e9f3c0efdcd000000000000000000000000b0a7aade64bface56abb7f5ca2190e9f3c0efdcd0000000000000000000000000000000000000000000000000000886c98b7600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15580,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006503c34b11527e35a73fbb893bc18468aaee2e780000000000000000000000006503c34b11527e35a73fbb893bc18468aaee2e78000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15582,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000735b2f2a6cfcb2a3306f2b8805ca7f59358ce422000000000000000000000000735b2f2a6cfcb2a3306f2b8805ca7f59358ce4220000000000000000000000000000000000000000000000000018bb6fb4e92d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15583,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000085d33380514aba3ae6cf1c58ad9717a2b1cf0272000000000000000000000000000000000000000000000000d02ab486cedc0000,,,1,true +15584,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000735b2f2a6cfcb2a3306f2b8805ca7f59358ce422000000000000000000000000735b2f2a6cfcb2a3306f2b8805ca7f59358ce422000000000000000000000000000000000000000000000000d3397d48e46a863700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15585,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000735b2f2a6cfcb2a3306f2b8805ca7f59358ce422000000000000000000000000735b2f2a6cfcb2a3306f2b8805ca7f59358ce42200000000000000000000000000000000000000000000000000127c1396adfec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15587,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000080cffdca4d7e05eb25e703a183e98c7a4094eec000000000000000000000000080cffdca4d7e05eb25e703a183e98c7a4094eec000000000000000000000000000000000000000000000000e4d70fcb6dee77fd800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xd3515b1ae756c50ba48a56c7bd4f4f8979bc5910b786346598583bf2082691d7,2022-06-11 07:11:36.000 UTC,0,true +15588,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080cffdca4d7e05eb25e703a183e98c7a4094eec000000000000000000000000080cffdca4d7e05eb25e703a183e98c7a4094eec0000000000000000000000000000000000000000000000000007294135de941c500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x14c37c119b5fcdee1db5d65d8359e2366e66b0f9eea03561bfbf177955071d9b,2022-06-05 07:10:15.000 UTC,0,true +15589,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003181f3cfbe3137612e53f27e249f0e380e0e0ac30000000000000000000000003181f3cfbe3137612e53f27e249f0e380e0e0ac3000000000000000000000000000000000000000000000000003b2a943fceae3800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15590,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000407e41dc7b2b69a97eb05e371b01257ecd68509f000000000000000000000000407e41dc7b2b69a97eb05e371b01257ecd68509f000000000000000000000000000000000000000000000000142f37477334f9c400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15591,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000db706ba75c0882fe5ab49e8369feb9646b7dc99c000000000000000000000000db706ba75c0882fe5ab49e8369feb9646b7dc99c00000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15594,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002cac8830d0a4bb04728ccaf7bbeefead775172130000000000000000000000002cac8830d0a4bb04728ccaf7bbeefead775172130000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x48416e1070fee1598a30d75fea522f744ff59aa3bce28f95f6cc35488ce484d3,2021-12-11 09:01:42.000 UTC,0,true +15595,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000011c0a0a876bfe0aaf5092c5ac03518d67824ec6400000000000000000000000011c0a0a876bfe0aaf5092c5ac03518d67824ec6400000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15596,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1d1280cbe4432f4ba29d1531952b968ce266fcc000000000000000000000000c1d1280cbe4432f4ba29d1531952b968ce266fcc000000000000000000000000000000000000000000000000001fd904980b3c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15598,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007848c04fb28d52fd52a5e63b6bb4a1a2e0528bbf0000000000000000000000007848c04fb28d52fd52a5e63b6bb4a1a2e0528bbf000000000000000000000000000000000000000000000000023b529939be0c3c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf1538fb243c868053b78a23e4a06612b4a45c7a000000000000000000000000bf1538fb243c868053b78a23e4a06612b4a45c7a00000000000000000000000000000000000000000000000001ee6258622bd30d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15600,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c4e58d790453dbb161982657664e1a5b76032790000000000000000000000000c4e58d790453dbb161982657664e1a5b760327900000000000000000000000000000000000000000000000000016bcc41e9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15602,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000009ab3f9a3f33933d17967e95b74d29f5bdb8cb4910000000000000000000000009ab3f9a3f33933d17967e95b74d29f5bdb8cb49100000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15603,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000951ce71f33c24af58c5253612938d107d537b970000000000000000000000000000000000000000000000002cabc97d71c9e09e,,,1,true +15605,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000cd543bebb1ec53e66e6c82694b4b5056c7056590000000000000000000000000cd543bebb1ec53e66e6c82694b4b5056c70565900000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15606,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b829c7dfec0373983e463351af11a96e61668f66000000000000000000000000b829c7dfec0373983e463351af11a96e61668f660000000000000000000000000000000000000000000000000408b73897132e9b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbc266b81ae6b630a854948ab2f222c9f44ff32d000000000000000000000000fbc266b81ae6b630a854948ab2f222c9f44ff32d00000000000000000000000000000000000000000000000000ad1be5e3f6b34000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15613,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005abf14ddcb863e2709201aaf932f826a181cd2e70000000000000000000000005abf14ddcb863e2709201aaf932f826a181cd2e700000000000000000000000000000000000000000000000001609efd6942060000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15615,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000073b968d104cb550f4e28543a52ff7357b20c746800000000000000000000000073b968d104cb550f4e28543a52ff7357b20c7468000000000000000000000000000000000000000000000001bbcdedad1ca7b2b400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044775476a3c87740f9ff7d013b601e8f3857a72600000000000000000000000044775476a3c87740f9ff7d013b601e8f3857a72600000000000000000000000000000000000000000000000000d5df4e3a60eb1900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15617,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000dee96105de27c6f47a610fba6b700b22abb26c040000000000000000000000000000000000000000000000009a2488cb49cce6ff,,,1,true +15619,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001905c1e4278d34920fbd4a479b8f5d51ea065b3d0000000000000000000000001905c1e4278d34920fbd4a479b8f5d51ea065b3d0000000000000000000000000000000000000000000000006c8616e9a737f55a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf94f7ce14399d5a2f5daae532c6aff898ca496ce620e5d0a44874ff3740325ca,2021-11-25 08:06:25.000 UTC,0,true +15621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000620c00e43aaa99ceee1b84bf1bb49c3fbee22b0c000000000000000000000000620c00e43aaa99ceee1b84bf1bb49c3fbee22b0c000000000000000000000000000000000000000000000000074e6602336f04c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15622,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ba03e80342ea3011dfcddeb2d1813d81c05caec0000000000000000000000002ba03e80342ea3011dfcddeb2d1813d81c05caec00000000000000000000000000000000000000000000000000fc5e3dd2ac1d2100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x20124594972827f2e50c99074cc48a212ac61198812795595f2b0f41ccf624c9,2022-04-27 08:40:34.000 UTC,0,true +15623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000881cf1834434084b05fbd2d17d46bdf2ac685ee7000000000000000000000000881cf1834434084b05fbd2d17d46bdf2ac685ee7000000000000000000000000000000000000000000000000019602080c041b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bbcb54119492581766c1256ffbe8f816c13f26e2000000000000000000000000bbcb54119492581766c1256ffbe8f816c13f26e200000000000000000000000000000000000000000000000002b97fa8c894b4ac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef60a333d909f97ca9f6248b831f979bf5e205d3000000000000000000000000ef60a333d909f97ca9f6248b831f979bf5e205d300000000000000000000000000000000000000000000000000034493c1291bb000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d9b70f1b761e529f451898a821840f622794bf90000000000000000000000003d9b70f1b761e529f451898a821840f622794bf9000000000000000000000000000000000000000000000000034843e49e3cac4100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8ac58a40358e5f6456a6012cdcfd4611650206c05e9e4b95de0011c739677a8b,2021-12-12 10:04:19.000 UTC,0,true +15628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef60a333d909f97ca9f6248b831f979bf5e205d3000000000000000000000000ef60a333d909f97ca9f6248b831f979bf5e205d300000000000000000000000000000000000000000000000001340848f100f83b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000feee48a7d7eb20b4f9f3ec8246ab49b9e5e305a5000000000000000000000000feee48a7d7eb20b4f9f3ec8246ab49b9e5e305a50000000000000000000000000000000000000000000000000e82d332f8d3690600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15630,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067be7f6775bf056f9c1d1fd1debff44ef2ad67f000000000000000000000000067be7f6775bf056f9c1d1fd1debff44ef2ad67f0000000000000000000000000000000000000000000000000038edb0938993db000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc8906005439c3886df6e01a7ad91cb43c0b72609e7d2d0d6633dca7d2480fad7,2021-12-18 16:14:46.000 UTC,0,true +15631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002255be730f41cbea4aabda73b17f6b6f511fd6a40000000000000000000000002255be730f41cbea4aabda73b17f6b6f511fd6a40000000000000000000000000000000000000000000000000dd0bda52890241f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000dc5aa4908abaf08a853fd459f35fe7df029fb1e5000000000000000000000000dc5aa4908abaf08a853fd459f35fe7df029fb1e50000000000000000000000000000000000000000000000004dd288cb44a30ccb00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x741757683093055e9b12528b7b2db066310bf0adef1b183829101573f4b7898c,2021-12-11 17:47:14.000 UTC,0,true +15633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bb55c485319b2b770bfb03c08d7ba4c9bea33370000000000000000000000005bb55c485319b2b770bfb03c08d7ba4c9bea33370000000000000000000000000000000000000000000000000366135cf75cb53200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fe879cc3e4089f618cf5b8bbc8edd9a6cecdb60d000000000000000000000000fe879cc3e4089f618cf5b8bbc8edd9a6cecdb60d00000000000000000000000000000000000000000000000000cfb8162b28ef0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xda33481248c65b04c479e3542a286b763589c3be4f7e187413c2fabdb7b3581a,2022-03-10 01:23:36.000 UTC,0,true +15637,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b1d5604b8ad680ceb7147ef9a23237b68a21d73b000000000000000000000000b1d5604b8ad680ceb7147ef9a23237b68a21d73b00000000000000000000000000000000000000000000000002bdde51d99e9bab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016bb0ca466b8cafac10fd9c4325dc19040dec79900000000000000000000000016bb0ca466b8cafac10fd9c4325dc19040dec79900000000000000000000000000000000000000000000000000c079fc799567c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15644,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002849ef9c4f4f8a2ba98279dcb4d61b7a4a982b320000000000000000000000000000000000000000000000001015089496b6027b,,,1,true +15651,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058e5453b2a2a3b0b62e84562384170796167cbd000000000000000000000000058e5453b2a2a3b0b62e84562384170796167cbd000000000000000000000000000000000000000000000000001512a74848fabe100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000930c2db8ee04a798d215ae89ae957db5556917c0000000000000000000000000930c2db8ee04a798d215ae89ae957db5556917c0000000000000000000000000000000000000000000000000007f7666fc5b429300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15654,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000653879c36be0552e44aeddf50bf3e9ab6eb2b895000000000000000000000000653879c36be0552e44aeddf50bf3e9ab6eb2b89500000000000000000000000000000000000000000000000000d0d4193be5c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000216902b0d12e37c1e0a6470f95daa24950bd2cb7000000000000000000000000216902b0d12e37c1e0a6470f95daa24950bd2cb70000000000000000000000000000000000000000000000000b1b464f3280584300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15657,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000216902b0d12e37c1e0a6470f95daa24950bd2cb7000000000000000000000000216902b0d12e37c1e0a6470f95daa24950bd2cb70000000000000000000000000000000000000000000000000c3d49f23532269f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016f1760ed9321eac4788514b1e5cce598ab3c43a00000000000000000000000016f1760ed9321eac4788514b1e5cce598ab3c43a000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15661,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9df1158c6da7e3dee926896a99388810c7c59cb000000000000000000000000c9df1158c6da7e3dee926896a99388810c7c59cb000000000000000000000000000000000000000000000000013d7ec8204b531d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15663,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b917f2001b6143d43d2cdefefd02f8055e862c0e000000000000000000000000b917f2001b6143d43d2cdefefd02f8055e862c0e000000000000000000000000000000000000000000000000012c6cdbf7973df500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dbfe0adaf96f9da1d6f78057f73392894452a5e0000000000000000000000002dbfe0adaf96f9da1d6f78057f73392894452a5e00000000000000000000000000000000000000000000000000a706af3f4c415c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c01d32809bbb33d585b4175d06b5ba7b8f0e96d0000000000000000000000005c01d32809bbb33d585b4175d06b5ba7b8f0e96d000000000000000000000000000000000000000000000000015a61df50f2ed0d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15666,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000003422473b7de8204445edf001e33ef637d6cb60ad0000000000000000000000003422473b7de8204445edf001e33ef637d6cb60ad00000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef4981e9ced215d267ae900c5802c6966efd312a000000000000000000000000ef4981e9ced215d267ae900c5802c6966efd312a00000000000000000000000000000000000000000000000000b08d49cea31a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7d1cfec62aec12320ef42bd59283590f4216151000000000000000000000000e7d1cfec62aec12320ef42bd59283590f421615100000000000000000000000000000000000000000000000000677e328e0f350c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15673,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e25eecf3ebdea654861c59805c074657bd0a3680000000000000000000000008e25eecf3ebdea654861c59805c074657bd0a3680000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15675,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a425fe8b53b1386ed496dd3ee143f2d8c3a624d3000000000000000000000000a425fe8b53b1386ed496dd3ee143f2d8c3a624d30000000000000000000000000000000000000000000000000003b602bac7763500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15678,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000012ef99df0866b69754558cf7ab1650ccb4c04a0c00000000000000000000000012ef99df0866b69754558cf7ab1650ccb4c04a0c0000000000000000000000000000000000000000000000000067c77c9773850000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d3b8ba6e97efd09aca212d79fc3b7ac0e2673100000000000000000000000007d3b8ba6e97efd09aca212d79fc3b7ac0e267310000000000000000000000000000000000000000000000000008f74daf0cdecf500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000239d80a9243e6576be0b3ad7e9e8e5a29a796440000000000000000000000000239d80a9243e6576be0b3ad7e9e8e5a29a796440000000000000000000000000000000000000000000000000045103e79aeb98f800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x70acccad5851f8e4a87a8c7e123e025f9457312d031dc29241f9763fe84190a3,2021-12-25 15:22:17.000 UTC,0,true +15682,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000007de9f19149a86da212b97d30131f4ce1c3f6c7900000000000000000000000007de9f19149a86da212b97d30131f4ce1c3f6c7900000000000000000000000000000000000000000000000000747a04e594281a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe052b3daad4cb6d23eae5032e1ad3e00c5ac5b7e4b2e999ace55b300fda261f1,2022-03-11 12:49:25.000 UTC,0,true +15684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e725c37b2368d71c4976cfe7e3c69ffdc3635bba000000000000000000000000e725c37b2368d71c4976cfe7e3c69ffdc3635bba00000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa53c5f3ff5b61cd85acae0f9fb7adea8c162ce83b2efbdfb12fc92734584e2eb,2022-07-21 05:05:53.000 UTC,0,true +15685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0a29a5ea152da70f70ec9900a08bc55ff59bb01000000000000000000000000a0a29a5ea152da70f70ec9900a08bc55ff59bb01000000000000000000000000000000000000000000000000006258023832c84900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000273ec095fe4c3c023b6e5d3dcd3642af950ac930000000000000000000000000273ec095fe4c3c023b6e5d3dcd3642af950ac930000000000000000000000000000000000000000000000000013ea0665957720700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15689,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043c76b04ed218a881346d8b2b65e5d29f87e985300000000000000000000000043c76b04ed218a881346d8b2b65e5d29f87e9853000000000000000000000000000000000000000000000000015fdd7560e56a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x47e6a8472abe99cff5917c8dbfb7b6fb9137bc17e4396ffe6effd8417d52ea2c,2021-11-28 05:35:26.000 UTC,0,true +15691,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000970e1cbbea26bbbafe4608848f7add9b397343df000000000000000000000000970e1cbbea26bbbafe4608848f7add9b397343df0000000000000000000000000000000000000000000000000267480e976331f700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15693,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd530b6604ad97989c09449a10df892c0206fc96000000000000000000000000dd530b6604ad97989c09449a10df892c0206fc96000000000000000000000000000000000000000000000000004fb641dd2701b800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15694,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc69699b7f25a0311f055880a421abe5eb89f111000000000000000000000000fc69699b7f25a0311f055880a421abe5eb89f1110000000000000000000000000000000000000000000000000f3abe76b684734000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15695,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000070753fc8fcaafaf71df307799243d0152e1e774900000000000000000000000070753fc8fcaafaf71df307799243d0152e1e7749000000000000000000000000000000000000000000000000001b2b764c90d29400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15696,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e36957237b18282b8d08739b98922991759bc771000000000000000000000000e36957237b18282b8d08739b98922991759bc77100000000000000000000000000000000000000000000000002bb1f79f177567a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c512e897ea2e17d49587a15ac8563a19c4514580000000000000000000000002c512e897ea2e17d49587a15ac8563a19c4514580000000000000000000000000000000000000000000000000067d7fcb8b8160000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000018b25c78b356a3247bcef5bf487a1ff0e5e0885200000000000000000000000018b25c78b356a3247bcef5bf487a1ff0e5e08852000000000000000000000000000000000000000000000000009812d0bb55244500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000510b2fd4adee51d4ee6dfc6c15a2af9665a15a7e000000000000000000000000510b2fd4adee51d4ee6dfc6c15a2af9665a15a7e0000000000000000000000000000000000000000000000001b7967daaaa41ddf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15703,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000a5ecbcda96210b6f93f60bb0002d008b2c4aced6000000000000000000000000a5ecbcda96210b6f93f60bb0002d008b2c4aced6000000000000000000000000000000000000000000000000000000000d0b5ade00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x5688c5f6aaafe2bc2fc1e3cbd357c7ebd9bcf3e1deda2b9c387e99985d9f9a52,2021-12-11 09:28:44.000 UTC,0,true +15706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003580e55e0157228f7d648dbb2d1ac8aa8a4f69450000000000000000000000003580e55e0157228f7d648dbb2d1ac8aa8a4f6945000000000000000000000000000000000000000000000000042346f0b63b000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dc2442365fd0389a3312107274adaa865513f0b0000000000000000000000002dc2442365fd0389a3312107274adaa865513f0b000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15708,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003580e55e0157228f7d648dbb2d1ac8aa8a4f694500000000000000000000000000000000000000000000000456a91d69381ae92f,,,1,true +15709,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007036847a2a085df50bd2e5bcd42091eec9f2b9dc0000000000000000000000007036847a2a085df50bd2e5bcd42091eec9f2b9dc000000000000000000000000000000000000000000000000041f6fa3827d608000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15714,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc7f3c5fc1ce22e8d8f2c35029055bcc06ea1dfc000000000000000000000000dc7f3c5fc1ce22e8d8f2c35029055bcc06ea1dfc00000000000000000000000000000000000000000000000001605b96ea0b930000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15717,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000aa2f9f0798fab1f08cf508b721e3a81dbe007e830000000000000000000000000000000000000000000000000aa27c94fbf9aece,,,1,true +15718,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a31cd363cd2867e98fb0102e07e0c226f8346e48000000000000000000000000a31cd363cd2867e98fb0102e07e0c226f8346e48000000000000000000000000000000000000000000000000004f94ae6af8000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe14c739ea867a22d7aab7284f54551735cf2fb463544838fad22930d92f0f5b6,2022-08-21 04:58:51.000 UTC,0,true +15719,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003a01aeaf23caa39d85e8e06b1938f4f1af282fa7000000000000000000000000000000000000000000000000345e5a253e611c58,,,1,true +15720,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f372f8bf76c652b51d293038431f9deb8333e67b000000000000000000000000f372f8bf76c652b51d293038431f9deb8333e67b0000000000000000000000000000000000000000000000000360098d8359634b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4fd5b3a7ab3a585bd9821b0ce7063bf263a14f99d7766d2d02da4a7376a22d10,2021-11-25 22:28:26.000 UTC,0,true +15723,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b9915aa990cea3f67e0af53c05573aafc4206560000000000000000000000005b9915aa990cea3f67e0af53c05573aafc4206560000000000000000000000000000000000000000000000000dd15bc36ce4653a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc5354bdac33b6b07019d1a31e212e1a17a3fab2b56efdffcfca2e6bb91987043,2021-11-21 05:07:32.000 UTC,0,true +15725,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b70ec21d2908fd7f8553a7beab19ba0da4f0204c000000000000000000000000b70ec21d2908fd7f8553a7beab19ba0da4f0204c00000000000000000000000000000000000000000000000000bd1addfe8ee3e600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6e22d8dcc99c9a1be52548d2527eafdf78dcff3cd68b0227837f7048817713a2,2022-03-14 07:31:01.000 UTC,0,true +15727,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019f372338364550b5fe17fb1c97852ecb08579ed00000000000000000000000019f372338364550b5fe17fb1c97852ecb08579ed000000000000000000000000000000000000000000000000006ccc1accd5377500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fae7e1347cc2a5f625dec6d9d4e5d1c86deda380000000000000000000000001fae7e1347cc2a5f625dec6d9d4e5d1c86deda38000000000000000000000000000000000000000000000000003c84d21c65943600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf39d76e8c3f79c3f59fea47b25abb57643fe617bc7b26643265db11a5142bd20,2022-09-04 14:36:59.000 UTC,0,true +15731,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000deb552b4fbd93b65cec9de13c8157e8cd634933e000000000000000000000000deb552b4fbd93b65cec9de13c8157e8cd634933e00000000000000000000000000000000000000000000000002c46afb2ccb490000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15733,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000095b62a3e480f4944ab0949c2da586b6d39d692ef00000000000000000000000000000000000000000000000407ac9401792e5cf2,,,1,true +15734,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000095b62a3e480f4944ab0949c2da586b6d39d692ef000000000000000000000000000000000000000000000003d92f4d976c98551e,,,1,true +15736,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000025c9ca23e7f4a857bf5ce4a343830560776a12ad00000000000000000000000025c9ca23e7f4a857bf5ce4a343830560776a12ad000000000000000000000000000000000000000000000000008a583afeac337200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c4a4734de9278982e0fbad7974615ab2b55f8960000000000000000000000007c4a4734de9278982e0fbad7974615ab2b55f896000000000000000000000000000000000000000000000000015a9e4209d2f35000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15741,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b17bbfbd1cc5faee7976d7f0ee8249ebddf78726000000000000000000000000b17bbfbd1cc5faee7976d7f0ee8249ebddf7872600000000000000000000000000000000000000000000000006e6b6aeff4a122300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x60065690965b034a5591bbf8be6d3274666e34dec788de0db582cca560bd2f18,2021-12-19 08:23:39.000 UTC,0,true +15743,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000005600051d9924b05d7098157ad8d791d48a93185a0000000000000000000000005600051d9924b05d7098157ad8d791d48a93185a0000000000000000000000000000000000000000000000000000000013fc1e2300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac0da3a79a854b99b08ba6fae140617901453ba8000000000000000000000000ac0da3a79a854b99b08ba6fae140617901453ba8000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac0da3a79a854b99b08ba6fae140617901453ba8000000000000000000000000ac0da3a79a854b99b08ba6fae140617901453ba800000000000000000000000000000000000000000000000000431a1baad2e10000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000084411f2f63602504e25206d5b447ce16747cb01000000000000000000000000084411f2f63602504e25206d5b447ce16747cb01000000000000000000000000000000000000000000000000005b668820972f5100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15753,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000079855ef6cf3d3e4ba05fa7466e94c23adc0cc8c6000000000000000000000000000000000000000000000002b5e3af16b1880000,,,1,true +15754,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001217211a1145e5388d45f98c98a6fe5cf29efbdc0000000000000000000000001217211a1145e5388d45f98c98a6fe5cf29efbdc00000000000000000000000000000000000000000000000000f0b0d67fbf11d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15755,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f0935b128abb3b5074850247d615392366fa08a0000000000000000000000002f0935b128abb3b5074850247d615392366fa08a000000000000000000000000000000000000000000000000015175ab2c4528a300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000273455e1d9c8b8f311a65d45e605978e57c88870000000000000000000000000273455e1d9c8b8f311a65d45e605978e57c88870000000000000000000000000000000000000000000000000443bbfe26b7e94000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15761,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a9c49c64a020f19bd6af4f2ee4b2eb9758dd9bf0000000000000000000000006a9c49c64a020f19bd6af4f2ee4b2eb9758dd9bf0000000000000000000000000000000000000000000000000040bba76c20fe0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15762,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000063d1277b25710bfeb1e95085262f365a5cc8dfaf0000000000000000000000000000000000000000000000026d9888752fa0fd68,,,1,true +15763,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fe146b2ffe8b629a524dcb8913a358b386883610000000000000000000000008fe146b2ffe8b629a524dcb8913a358b3868836100000000000000000000000000000000000000000000000000f8d8c19f36e2e000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15764,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034e2389ffc1d198e4aa275b8b2bcc2ef913be71300000000000000000000000034e2389ffc1d198e4aa275b8b2bcc2ef913be71300000000000000000000000000000000000000000000000000af23b02edfcd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069b430d064874597632c3f2a019f0a8f6decc47900000000000000000000000069b430d064874597632c3f2a019f0a8f6decc47900000000000000000000000000000000000000000000000000e661aa24ea50d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf16a1df9771ddaabc00f4eabb3c35ec9d7fc29602329ae047adc42239e10c12f,2021-12-22 08:29:57.000 UTC,0,true +15767,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000a74fb7544d54a1d8f8178b6ae3f2700ebd3a65ba000000000000000000000000a74fb7544d54a1d8f8178b6ae3f2700ebd3a65ba000000000000000000000000000000000000000000000000000000003b6456ea00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000500576d9501fff6fb42280df6d2994b36e7aefc1000000000000000000000000500576d9501fff6fb42280df6d2994b36e7aefc10000000000000000000000000000000000000000000000000000000044c0ae8e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x4ac50a1bc67e2f6214179be701bb0722077c30ad9a8826f8fa2da1ab2a585101,2021-11-21 15:29:16.000 UTC,0,true +15769,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a74fb7544d54a1d8f8178b6ae3f2700ebd3a65ba000000000000000000000000a74fb7544d54a1d8f8178b6ae3f2700ebd3a65ba00000000000000000000000000000000000000000000000000e34759c3ace08200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15776,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000017e3c0330d2eaffc8a21acae5db958c50950bc0a00000000000000000000000017e3c0330d2eaffc8a21acae5db958c50950bc0a000000000000000000000000000000000000000000000000008836b1517e6b4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15779,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002e5745f3136e1023b7db402f2f20d59ece802f4a0000000000000000000000002e5745f3136e1023b7db402f2f20d59ece802f4a00000000000000000000000000000000000000000000000914fce452ed8c2d4c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000934c76f53f7de96b39ab4f9b73f0e8f39ca23be2000000000000000000000000934c76f53f7de96b39ab4f9b73f0e8f39ca23be20000000000000000000000000000000000000000000000000114c7513b35da0d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6560a6314a4600a4590516e92493a8fc322e97c1b35072cf641d4866944c1ad3,2022-03-02 11:24:14.000 UTC,0,true +15783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000999277e47e782a2f1efff2ea234ee7486c5cbb56000000000000000000000000999277e47e782a2f1efff2ea234ee7486c5cbb56000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15785,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ceeb9e598bf6c31f3ca3eb944297c0826048bf2f000000000000000000000000ceeb9e598bf6c31f3ca3eb944297c0826048bf2f0000000000000000000000000000000000000000000000000019e74ca440ea4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b35884498aa02ba3fe3b290c287d8e9fc892e3d0000000000000000000000009b35884498aa02ba3fe3b290c287d8e9fc892e3d000000000000000000000000000000000000000000000000014ffba3b9c3055900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052841db83d2ddcae6afa935783c3d591b313feb500000000000000000000000052841db83d2ddcae6afa935783c3d591b313feb5000000000000000000000000000000000000000000000000021e56460e3a45a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15789,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d0bd81eeee1d3abf0ad446a6f52c847a6904d233000000000000000000000000d0bd81eeee1d3abf0ad446a6f52c847a6904d23300000000000000000000000000000000000000000000003e805fcef407624a8700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xfff2895933b649184626dbe0cd43aec959330a9cb7b27e7503b4f6a0df2c6ca2,2021-12-08 08:43:18.000 UTC,0,true +15790,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d0bd81eeee1d3abf0ad446a6f52c847a6904d233000000000000000000000000d0bd81eeee1d3abf0ad446a6f52c847a6904d2330000000000000000000000000000000000000000000000000031050bda72d3e300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xae95f6afc080c1e2cba52d89ac4e17fd952627d360352ab1b6ba509678a1fadc,2021-12-08 08:41:11.000 UTC,0,true +15793,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000988cab9493ed968b6499e3419844ba3c117fc070000000000000000000000000988cab9493ed968b6499e3419844ba3c117fc07000000000000000000000000000000000000000000000000000d16a69dc42c20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000343131422453b116d55955f99b27286a828bbba3000000000000000000000000343131422453b116d55955f99b27286a828bbba3000000000000000000000000000000000000000000000000023453fbf4c7ba1f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x40ae9a1f748813f53c3192f3e73223453a10cf9b53e0ccb49c8b2ec0f4c9e389,2022-02-16 10:07:03.000 UTC,0,true +15796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c99320096dda3eeba6b3158f8c61bf993ef00e10000000000000000000000004c99320096dda3eeba6b3158f8c61bf993ef00e100000000000000000000000000000000000000000000000001ffa31dcd19f07f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbb3379532e1b9285923808c90c7534afff71024a9c6e7ef909e2f8b06d522caf,2022-02-26 21:57:22.000 UTC,0,true +15799,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000067b5fb289c4701596e28bc3622e1f0021ee3bd24000000000000000000000000000000000000000000000003e51b4799438955e3,,,1,true +15802,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049bc79b5923273b1df30c67be9da6adcb0ad8a2300000000000000000000000049bc79b5923273b1df30c67be9da6adcb0ad8a23000000000000000000000000000000000000000000000000036af0b22bfc4dea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15803,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002911c55725bc15226d69a1799b6d45f18844834a0000000000000000000000000000000000000000000000014ff9cf9b24c2bced,,,1,true +15806,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082a214b23c0119f0c37be360889927d68c2caab600000000000000000000000082a214b23c0119f0c37be360889927d68c2caab6000000000000000000000000000000000000000000000000057cfd7d55fc455e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15811,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000db6c892f2392134524b85105cf4a85559acb82d3000000000000000000000000db6c892f2392134524b85105cf4a85559acb82d300000000000000000000000000000000000000000000000006dc26f5b7c2553a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d92ed5732d385381d00dc22792545086346bb63d000000000000000000000000d92ed5732d385381d00dc22792545086346bb63d000000000000000000000000000000000000000000000000000000006b2e9d2300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15813,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036c448b1eb59f3b6fabbab8d1049548861687a0b00000000000000000000000036c448b1eb59f3b6fabbab8d1049548861687a0b000000000000000000000000000000000000000000000000010675001e50479600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3b661f847e06c2b3bd9d5a356757f3e765a822e000000000000000000000000c3b661f847e06c2b3bd9d5a356757f3e765a822e00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15818,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b3f7ef4c8c6aea014737165a98d41605cae4546e000000000000000000000000b3f7ef4c8c6aea014737165a98d41605cae4546e00000000000000000000000000000000000000000000001ca384754e508fca7600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007d73904f8b3a7fb1cf94d3497a26dc1e18b5543a0000000000000000000000007d73904f8b3a7fb1cf94d3497a26dc1e18b5543a00000000000000000000000000000000000000000000000000f657567032c20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000410b26c4509b9759ffe4ef4cfc418714daf4558a000000000000000000000000410b26c4509b9759ffe4ef4cfc418714daf4558a00000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008959092b77f5b2f531e52041623ae90f8fd13d090000000000000000000000008959092b77f5b2f531e52041623ae90f8fd13d09000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003b887932adda07db3dee4ec3aac0d01230e8ad2f0000000000000000000000003b887932adda07db3dee4ec3aac0d01230e8ad2f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000484f5add96dbc6744aa47052d3c7e46c9f1a0d94000000000000000000000000484f5add96dbc6744aa47052d3c7e46c9f1a0d94000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15826,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec3e067ed83b71d59fa4cbd081c94944baf96734000000000000000000000000ec3e067ed83b71d59fa4cbd081c94944baf96734000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000022e50124549c5265a50dec8dc14f9650b094915c00000000000000000000000022e50124549c5265a50dec8dc14f9650b094915c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b492ae8421dca3f6f5c252fe53544a7b261f6f50000000000000000000000004b492ae8421dca3f6f5c252fe53544a7b261f6f5000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15829,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e2eb70730a90f46f6a5438f77f2fb28c2f110760000000000000000000000007e2eb70730a90f46f6a5438f77f2fb28c2f11076000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f44fbe168e7bbfe8a21e7fcf487c53782cd0ae19000000000000000000000000f44fbe168e7bbfe8a21e7fcf487c53782cd0ae19000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15831,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049e6f5ea02b107af84ebbe00e4998b8f51d51d9500000000000000000000000049e6f5ea02b107af84ebbe00e4998b8f51d51d95000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f2f542b6eaea0badb33bcf31af27636f6b45c830000000000000000000000001f2f542b6eaea0badb33bcf31af27636f6b45c83000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026048c504867a74ebb5cf7e06399f911274ae90100000000000000000000000026048c504867a74ebb5cf7e06399f911274ae901000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bf076cf12d96252ecc7987aae25c165a1861d880000000000000000000000006bf076cf12d96252ecc7987aae25c165a1861d88000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000004f97e52d391a56976317c82e0fef586b77c76b480000000000000000000000004f97e52d391a56976317c82e0fef586b77c76b4800000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f012d13a5857fa5a81fcbed7b2d76fc000f53600000000000000000000000003f012d13a5857fa5a81fcbed7b2d76fc000f5360000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000818e81671d2f1ffbf3cdaf2b9e6e171a3468face000000000000000000000000818e81671d2f1ffbf3cdaf2b9e6e171a3468face000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c194f01f4ceda4e94e76955702a7a5a7100944d0000000000000000000000003c194f01f4ceda4e94e76955702a7a5a7100944d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c58ac50c22389ee0ef7839ec0dd7f2453930a793000000000000000000000000c58ac50c22389ee0ef7839ec0dd7f2453930a793000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15840,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7797c9fcde9c1cf0fc69445873b841f78dbf0a6000000000000000000000000c7797c9fcde9c1cf0fc69445873b841f78dbf0a6000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000089e42b5b59dbc160bd1482ba3f5aefe4576acc6500000000000000000000000089e42b5b59dbc160bd1482ba3f5aefe4576acc65000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15842,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d009413e55d4ec3723ef2e187a0fe2eab355cb57000000000000000000000000d009413e55d4ec3723ef2e187a0fe2eab355cb57000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15843,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000243afda220b03bf3d3f8b8efde80d0acf4eb7918000000000000000000000000243afda220b03bf3d3f8b8efde80d0acf4eb7918000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15844,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d10ebb8f2eb9f42a4601c15d0c5ae0fcaf341338000000000000000000000000d10ebb8f2eb9f42a4601c15d0c5ae0fcaf341338000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15845,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2f3ac06205b33f50d9573fd52a1f245bce87489000000000000000000000000d2f3ac06205b33f50d9573fd52a1f245bce87489000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000199d03d61a91f44111156af6685e66df4b5cc47b000000000000000000000000199d03d61a91f44111156af6685e66df4b5cc47b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007dc04be3f84c761b7143f078dd8fa54b8e03de920000000000000000000000007dc04be3f84c761b7143f078dd8fa54b8e03de92000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096e61138134ad5aa24c00c6ede503614d0292df900000000000000000000000096e61138134ad5aa24c00c6ede503614d0292df9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf0e9234c9450e97b40a489c3911df26c3448ca9000000000000000000000000cf0e9234c9450e97b40a489c3911df26c3448ca9000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eea00ea19d3802ae07516afbc49a8a0a522db8fc000000000000000000000000eea00ea19d3802ae07516afbc49a8a0a522db8fc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dfba4da6ff1c6ef56797914995b88d6d003ce3af000000000000000000000000dfba4da6ff1c6ef56797914995b88d6d003ce3af000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15852,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6f898fab08a131a54b39495c0ef5aba32a66bcc000000000000000000000000a6f898fab08a131a54b39495c0ef5aba32a66bcc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005bcc4977d9de3c95cdd3599dd8821dc826ef7fd00000000000000000000000005bcc4977d9de3c95cdd3599dd8821dc826ef7fd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dbad2c166e00f8b6e73a0956278aca5a80d0fd83000000000000000000000000dbad2c166e00f8b6e73a0956278aca5a80d0fd83000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15855,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046b1162cf45ea72aafdd963c179cb1f9ed5391fe00000000000000000000000046b1162cf45ea72aafdd963c179cb1f9ed5391fe000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15856,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000803c1791bec1f1bba4c78e5e3425f00f15200d2d000000000000000000000000803c1791bec1f1bba4c78e5e3425f00f15200d2d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007670b2f86766c079e411dd64b4f8634cca1030590000000000000000000000007670b2f86766c079e411dd64b4f8634cca103059000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15858,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7d4c3b00bfa97d52087b4c15c0076d3c4a072fe000000000000000000000000c7d4c3b00bfa97d52087b4c15c0076d3c4a072fe000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15859,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037a841d75d87e4250fb5ae2f693bbc98c118975100000000000000000000000037a841d75d87e4250fb5ae2f693bbc98c1189751000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f191e949bb5da90e65c2ced253c7bbc4d709e4fe000000000000000000000000f191e949bb5da90e65c2ced253c7bbc4d709e4fe000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15861,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1d9b182c0541d580e1fc536f6ee3a6e5b9a3bcd000000000000000000000000c1d9b182c0541d580e1fc536f6ee3a6e5b9a3bcd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15862,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aae4513607ef680fab45679d81f47416eb445fac000000000000000000000000aae4513607ef680fab45679d81f47416eb445fac000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d07cda4e8441e11f34124dcddb65ba4e19c6dbb7000000000000000000000000d07cda4e8441e11f34124dcddb65ba4e19c6dbb7000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15865,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed2242ff55ad0dec702c7dbac1cb22d61a42af7a000000000000000000000000ed2242ff55ad0dec702c7dbac1cb22d61a42af7a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15866,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a1f36d8111fd8ad9a6d48f192884851876579bf0000000000000000000000009a1f36d8111fd8ad9a6d48f192884851876579bf000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15867,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000232059053a33df592a159749979667acb54dbd34000000000000000000000000232059053a33df592a159749979667acb54dbd34000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15868,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003389c4b2524b528ec068b1e62975b52a434310330000000000000000000000003389c4b2524b528ec068b1e62975b52a43431033000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae4629ef6d42ecfa16199972ec7ba53a1803ee7b000000000000000000000000ae4629ef6d42ecfa16199972ec7ba53a1803ee7b000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000529c9c42799d2c83ac1999937f36e0bdfecab4cf000000000000000000000000529c9c42799d2c83ac1999937f36e0bdfecab4cf000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd7cdd38ca6354f5c1438c12ed0c2b4eed7dd1c1000000000000000000000000dd7cdd38ca6354f5c1438c12ed0c2b4eed7dd1c1000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000707436e5148045c5b8b468bd28a3ce3c1c709a70000000000000000000000000707436e5148045c5b8b468bd28a3ce3c1c709a70000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e51ab0fe5af399bf1d4954e3b832b61c4bad4d27000000000000000000000000e51ab0fe5af399bf1d4954e3b832b61c4bad4d27000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15874,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004420aea1d680bb28e137a24b06865500bdee48250000000000000000000000004420aea1d680bb28e137a24b06865500bdee4825000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15875,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f42b50e4bf895d12bcc2e0def2de33d87e3f4e84000000000000000000000000f42b50e4bf895d12bcc2e0def2de33d87e3f4e84000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15876,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc873f545dbcbdb12796d3a7b1c5d9f8703460cd000000000000000000000000fc873f545dbcbdb12796d3a7b1c5d9f8703460cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001ae33d484e2f076adf88ae8515500dcda78a35140000000000000000000000001ae33d484e2f076adf88ae8515500dcda78a3514000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038592eef244ea6699b2d05e30235c9483b775efe00000000000000000000000038592eef244ea6699b2d05e30235c9483b775efe000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15879,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000787bb66c3f729bf35e777dfa2078511879ed27f4000000000000000000000000787bb66c3f729bf35e777dfa2078511879ed27f4000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008338190e4886d154b5fb3da346c541899b4d401c0000000000000000000000008338190e4886d154b5fb3da346c541899b4d401c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d7fe0171db5e7faeb4413122322b2ecae7430013000000000000000000000000d7fe0171db5e7faeb4413122322b2ecae7430013000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15882,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003998f7679d637f55b83d14eaf34d2e3969e835240000000000000000000000003998f7679d637f55b83d14eaf34d2e3969e83524000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15883,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d8eec416ff747c2b0adfd93763c8dfc4b12ef8aa000000000000000000000000d8eec416ff747c2b0adfd93763c8dfc4b12ef8aa000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15884,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000159da56108df786465591fdd7d9a702e20d60040000000000000000000000000159da56108df786465591fdd7d9a702e20d60040000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15885,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c24be493aee47664fe9814e1dcefbf5f01e661f0000000000000000000000000c24be493aee47664fe9814e1dcefbf5f01e661f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15886,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003bef62261ac99af57d487981356a52085acee01c0000000000000000000000003bef62261ac99af57d487981356a52085acee01c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000534b386f0cdf96cce3ecdb64cf756dcc0a8ae3de000000000000000000000000534b386f0cdf96cce3ecdb64cf756dcc0a8ae3de000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009dda4fddf4ff734906fb8d5c62f0e8d25bacf6bc0000000000000000000000009dda4fddf4ff734906fb8d5c62f0e8d25bacf6bc000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000021edb0df93524cbe1583e301966ba2a6242e899000000000000000000000000021edb0df93524cbe1583e301966ba2a6242e899000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15890,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f20463f65aa8bc812dc646cea23a9a836aa776c0000000000000000000000008f20463f65aa8bc812dc646cea23a9a836aa776c000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15891,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007dc3237c4493a36f9161b15c6a3b9f9f9508029d0000000000000000000000007dc3237c4493a36f9161b15c6a3b9f9f9508029d000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15892,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fa9bb98ff760943a0cd142db51bb0d3bbcf78870000000000000000000000008fa9bb98ff760943a0cd142db51bb0d3bbcf7887000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052b376dcde73a992a86b1b93e93f71d2e3d06e9a00000000000000000000000052b376dcde73a992a86b1b93e93f71d2e3d06e9a000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15894,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da84d6eeb8247262bcbd5512fd9ce457209a75cd000000000000000000000000da84d6eeb8247262bcbd5512fd9ce457209a75cd000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15895,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000438328b257d6c4c597dccdcb21697fcc638ac797000000000000000000000000438328b257d6c4c597dccdcb21697fcc638ac797000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9ed82fd90560924d9f2f0ac0540ba9111fefe50000000000000000000000000d9ed82fd90560924d9f2f0ac0540ba9111fefe50000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f42bcf8fc4ba23eb5fd2a0d4c34522408df27dfe000000000000000000000000f42bcf8fc4ba23eb5fd2a0d4c34522408df27dfe000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15898,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ca1634f79f523a5a2b20da5d8b60ff8c5d9bf7f0000000000000000000000005ca1634f79f523a5a2b20da5d8b60ff8c5d9bf7f000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15899,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000755a2ae169bc0af03f2184df040793d770592ce9000000000000000000000000755a2ae169bc0af03f2184df040793d770592ce900000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15902,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a333f0f29cab0fdd9c53bce5394e4171bc314c30000000000000000000000009a333f0f29cab0fdd9c53bce5394e4171bc314c300000000000000000000000000000000000000000000000000588e3b09c2b2d300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15904,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b77249d67d9a40cc6a192cd9167e9e7ee8458bb0000000000000000000000005b77249d67d9a40cc6a192cd9167e9e7ee8458bb00000000000000000000000000000000000000000000000000f34fbe4590a6eb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d321da0925318aa4b5d81e01c90e397f9461ea5d000000000000000000000000d321da0925318aa4b5d81e01c90e397f9461ea5d0000000000000000000000000000000000000000000000000082c5aa14df9cac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000066ac5489afafa35b83819c8999b0c610958de00000000000000000000000000066ac5489afafa35b83819c8999b0c610958de000000000000000000000000000000000000000000000000012b8612256e390000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15912,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e142e84c1b6edd4858a81999352d8af9a767521b000000000000000000000000e142e84c1b6edd4858a81999352d8af9a767521b000000000000000000000000000000000000000000000000000ef035c0786dc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ed5ac934bdbe04ea6d7fca1a9bacceb2d23ff1f0000000000000000000000000ed5ac934bdbe04ea6d7fca1a9bacceb2d23ff1f00000000000000000000000000000000000000000000000006e4de8120cdd84f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15914,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055d891fa80809d30d650875d00b903c19e090aa000000000000000000000000055d891fa80809d30d650875d00b903c19e090aa0000000000000000000000000000000000000000000000000001e6e9fc4cdd98000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15916,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005225d258185f2c5dbcdc5ca0eb2bd251941a32fc0000000000000000000000005225d258185f2c5dbcdc5ca0eb2bd251941a32fc0000000000000000000000000000000000000000000000000032184b66b6d73d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15917,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000001acb8d661018ac209fab4c099cabffb37d73b74e0000000000000000000000001acb8d661018ac209fab4c099cabffb37d73b74e00000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15918,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d76d58e63a0c91b8914268902ec3dcd2d7101a32000000000000000000000000d76d58e63a0c91b8914268902ec3dcd2d7101a32000000000000000000000000000000000000000000000000005b7706e42d0b0200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15921,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de2e6020bcba5241ef81a588201713617759d4d1000000000000000000000000de2e6020bcba5241ef81a588201713617759d4d10000000000000000000000000000000000000000000000000052423101ba288e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15923,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000436e4cf5f7e9f10195feec6a427f4821e844941d000000000000000000000000436e4cf5f7e9f10195feec6a427f4821e844941d00000000000000000000000000000000000000000000000000000000000f906000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041cc4a3fe2227953da7eadecd77e366d2cda886600000000000000000000000041cc4a3fe2227953da7eadecd77e366d2cda88660000000000000000000000000000000000000000000000000000aea9bcc9120000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000139dde62bccc5bc1bf1eea7c74b91f44c58f71e0000000000000000000000000139dde62bccc5bc1bf1eea7c74b91f44c58f71e00000000000000000000000000000000000000000000000003b1a228ac46272b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc78c3d6a724909c10a96f5dc414b1a7b3638276d899b7c67319d7ba008ad66cf,2022-05-21 11:35:00.000 UTC,0,true +15926,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002c2b24aa09c427ef9b61a83977832f0c7cb651b90000000000000000000000002c2b24aa09c427ef9b61a83977832f0c7cb651b900000000000000000000000000000000000000000000000000000000000fb77000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000058c58d02323af6659e8d94fe3feb14385503a8f900000000000000000000000058c58d02323af6659e8d94fe3feb14385503a8f90000000000000000000000000000000000000000000000000069666e7b6c0e8a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15928,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000a55e48aab1d2eef88b6ad40c0663654c690c7750000000000000000000000000a55e48aab1d2eef88b6ad40c0663654c690c775000000000000000000000000000000000000000000000000000000000000fb77000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15929,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e673ba53ae04d4d56c13621c60307cf3140fbb20000000000000000000000003e673ba53ae04d4d56c13621c60307cf3140fbb20000000000000000000000000000000000000000000000000159cbb6584cde4e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e3faef6489ed6eb32844ee25514fe11a33f831c0000000000000000000000006e3faef6489ed6eb32844ee25514fe11a33f831c00000000000000000000000000000000000000000000000003af28f55dc0e27600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x50e0d358ea9f1426623fdffdcaa5d0d8e56a08bf90c6c1face5b1a2f510c5ee1,2022-05-21 11:41:16.000 UTC,0,true +15931,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003d1e52920476844c1d4f5b59d2796c535d41d75a0000000000000000000000003d1e52920476844c1d4f5b59d2796c535d41d75a00000000000000000000000000000000000000000000000001c390b7f5f0a89400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe2cb4618fe21af99ae30176093188cecb624e4ac5ecbde8561c5fffb65a1fda0,2022-02-25 11:31:20.000 UTC,0,true +15932,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a06c9cf8608b43c987ccc3a782bfb3ea4d30ce6a000000000000000000000000a06c9cf8608b43c987ccc3a782bfb3ea4d30ce6a000000000000000000000000000000000000000000000020827c8928d04dd03900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x1cebb49b08faf8b6e1c1e134fb43277d7db956d6d92d517e6412b6cb6c1a0a8d,2021-12-15 07:46:14.000 UTC,0,true +15934,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f1ca045e8b77eb2c62b9c0e60708ce6fe54d4a570000000000000000000000000000000000000000000000005d0b7933c847594b,,,1,true +15935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd95878137bba373c2951652fe189190383247d6000000000000000000000000fd95878137bba373c2951652fe189190383247d60000000000000000000000000000000000000000000000000033706af1963b6700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec1f704da3a038bc34371e672ba3ce3c632612fd000000000000000000000000ec1f704da3a038bc34371e672ba3ce3c632612fd00000000000000000000000000000000000000000000000003b96dc2c343076d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xdf63413ff328eb15df265d29ba6e39d7b2f3c14cd8c620bf4e4615d519aa9119,2022-05-21 11:44:56.000 UTC,0,true +15938,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004164e19bf327a773b146cde403755660ad4ac55d000000000000000000000000000000000000000000000000196c0a0c57500f05,,,1,true +15939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cfc810c14b69559f88b1ba82469a78311213fb50000000000000000000000007cfc810c14b69559f88b1ba82469a78311213fb500000000000000000000000000000000000000000000000000cf75edf5b21a4800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb518ca78f0f98553e1b033ac7111a3eb9ebe7d49e1b7ae99d4cc05c779e2e8d4,2022-03-19 06:10:45.000 UTC,0,true +15941,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087cb43594556ff576841b5db05641c895d87545e00000000000000000000000087cb43594556ff576841b5db05641c895d87545e000000000000000000000000000000000000000000000000002781820fbd827000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae8e2b4abb13de393515ef5abad7e35a2b11ba6d000000000000000000000000ae8e2b4abb13de393515ef5abad7e35a2b11ba6d000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0ac02717900528a7cb4863ad38f268437aa0b8b318c48fcec696fba95a9d1bd7,2022-05-25 06:42:26.000 UTC,0,true +15953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e5caa02cd1d0ae5d670625d36b5a50d3e226a260000000000000000000000004e5caa02cd1d0ae5d670625d36b5a50d3e226a260000000000000000000000000000000000000000000000000254bd05bdefe0eb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15957,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000171c1cf42c8e11589381f5e4846ffe4e2c7f6d95000000000000000000000000000000000000000000000000378500fe00f039e5,0x341c156f425e1e839ddafa962d42fc8f8b71e92f264528dfeb3f894df7a0cd11,2022-03-05 10:02:12.000 UTC,0,true +15960,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065fc8c391d7d258d01963825f619e725ac2a335f00000000000000000000000065fc8c391d7d258d01963825f619e725ac2a335f00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15963,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000f6dada0db6430d58c16207a9ba33015cc72635a0000000000000000000000000000000000000000000000027e60d44813f80000,,,1,true +15965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a76d60c6b02f070b9fd631976e8d253b39cb1f56000000000000000000000000a76d60c6b02f070b9fd631976e8d253b39cb1f56000000000000000000000000000000000000000000000000008c065d97869e1900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15968,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8e7d3078ac3020f6a8e597a165f161424c041fe000000000000000000000000a8e7d3078ac3020f6a8e597a165f161424c041fe0000000000000000000000000000000000000000000000000062a06d9f12eb3600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15969,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fdd8fc4d2b5a3ef49af517ef747d9f1c67108910000000000000000000000004fdd8fc4d2b5a3ef49af517ef747d9f1c6710891000000000000000000000000000000000000000000000000036f2ba6cad09d1f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5516482a0bd4f4cd5870d9dc23681aa3a379dad92044d2c0601a0e98e11be69a,2022-05-08 20:39:21.000 UTC,0,true +15971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001098071bad894f3cce4dabc93cff9da3f6464c5e0000000000000000000000001098071bad894f3cce4dabc93cff9da3f6464c5e000000000000000000000000000000000000000000000000002ffccb297ee8d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15972,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c948402983ed80bc79fe5e8c240779582d68d08a000000000000000000000000c948402983ed80bc79fe5e8c240779582d68d08a0000000000000000000000000000000000000000000000019feb44e0c8d2819700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15973,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ff6bb7a7688f2a8b548d13212c65ec50ea918b4d000000000000000000000000ff6bb7a7688f2a8b548d13212c65ec50ea918b4d0000000000000000000000000000000000000000000000000000000000e737e300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a563af28d54d8f2a81c33d5a3e4f8a76ceb1fdc9000000000000000000000000a563af28d54d8f2a81c33d5a3e4f8a76ceb1fdc90000000000000000000000000000000000000000000000000008e1bc9bf0400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15975,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000952ecc0080ed9a0cbd5839a3cc6758b85c3a8350000000000000000000000000952ecc0080ed9a0cbd5839a3cc6758b85c3a835000000000000000000000000000000000000000000000000027536093001bf3c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15976,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c8e4b7b34befdc23007f13925a5c10e1b1c4729d0000000000000000000000000000000000000000000000002f2f39fc6c540000,,,1,true +15977,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc9c451d7d58422c3734508c038bf9e608c214bf000000000000000000000000fc9c451d7d58422c3734508c038bf9e608c214bf0000000000000000000000000000000000000000000000000035de8800dbfb4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15978,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000002f3d886584cc4f9089c579b4877824975f8f217d0000000000000000000000002f3d886584cc4f9089c579b4877824975f8f217d000000000000000000000000000000000000000000000000000000000f735fc100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15979,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000083d9948019e680f3514866e5a5c16f2eaae140a800000000000000000000000083d9948019e680f3514866e5a5c16f2eaae140a800000000000000000000000000000000000000000000000005aa592c6ff8423800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15981,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004e6fdce9b676c44b2c5e8800327e923696ddc62900000000000000000000000000000000000000000000001978b1bf4a3dfda8b2,0x28abf05c2c1b5e5bd886dcbbae773f6f105aea83717366dccc5094ca4497e813,2021-11-22 15:20:13.000 UTC,0,true +15982,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000909c9406808f89b88b277d099c11d36283eb66f9000000000000000000000000909c9406808f89b88b277d099c11d36283eb66f900000000000000000000000000000000000000000000000000350cf6d42889f400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15985,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000001627902c8aa6572894ce678d0703ead3dbf74d5e0000000000000000000000001627902c8aa6572894ce678d0703ead3dbf74d5e00000000000000000000000000000000000000000000000000000000180946bc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x3b51aec0829c0649dbdc4f2a5a9496db858eca943ab1d5c6bdb6ff4cfa51559e,2022-03-25 08:17:06.000 UTC,0,true +15987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c61221b53a52fb48a6d5515681169da0612870d5000000000000000000000000c61221b53a52fb48a6d5515681169da0612870d50000000000000000000000000000000000000000000000000d2df35200f7244300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x42a1eced86b1c51ff542ebcd8238ce67e0f45b9361d8868ad2ea9aad71dedc70,2022-02-13 07:16:05.000 UTC,0,true +15990,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024f99023f6741b27d3bf6189c7f3ae2fa45eed8f00000000000000000000000024f99023f6741b27d3bf6189c7f3ae2fa45eed8f0000000000000000000000000000000000000000000000000d26ee616dc708b700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x03c801b40061d1b451b75488a214616f823e9d30257ad52794a9db1f3ab4ff77,2021-12-10 08:02:27.000 UTC,0,true +15991,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009215f9bb7c38a3013b108099fd5d4494731ce02b0000000000000000000000009215f9bb7c38a3013b108099fd5d4494731ce02b000000000000000000000000000000000000000000000000008493e920868ec800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15992,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a62fdf90dacc91d98de3f72ab4f1f5bef64e48ba000000000000000000000000a62fdf90dacc91d98de3f72ab4f1f5bef64e48ba0000000000000000000000000000000000000000000000000153ec22501c7d8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000082fbf1a9789613c266420d2b5110c9747ad52fcd00000000000000000000000082fbf1a9789613c266420d2b5110c9747ad52fcd0000000000000000000000000000000000000000000000000000000003d675d300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +15994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ae8c7bab2c4861ba5a451dfd4b4a83c06c2a7c80000000000000000000000006ae8c7bab2c4861ba5a451dfd4b4a83c06c2a7c8000000000000000000000000000000000000000000000000003b35a381d3a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc96c00e608ea6d5c2a35b623e8a87c31c7c7ed66e2c74a35e6061651b4b70417,2022-03-13 15:28:23.000 UTC,0,true +15995,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008e841ba5b89142c196af4695ef200c56afd0d0300000000000000000000000008e841ba5b89142c196af4695ef200c56afd0d0300000000000000000000000000000000000000000000000000c7acf39dc6c360000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2171dc8ad3964ffeac86de8c4f5805bbebcb82141cd2ec1ae560633d91bd0d21,2021-12-01 18:08:34.000 UTC,0,true +15996,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000407410d84e15f79642272edaeb437ac65d7298e6000000000000000000000000407410d84e15f79642272edaeb437ac65d7298e6000000000000000000000000000000000000000000000000001370737b15f91700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a221b6a586e11268f2cce4123481e01de48c2b4b000000000000000000000000a221b6a586e11268f2cce4123481e01de48c2b4b000000000000000000000000000000000000000000000000008b18751c8ca20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15998,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000006f4250cb856f928c62743fe6925740e90e6d5c000000000000000000000000006f4250cb856f928c62743fe6925740e90e6d5c00000000000000000000000000000000000000000000000005d38fd67792a5b600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +15999,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008a18a9dcbe1abf8cedd4781c10fb90fc5c28e4a50000000000000000000000000000000000000000000000018696417a3da0ec8b,,,1,true +16001,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac8ad678b3ab523056c4c82f94d466ee778e373b000000000000000000000000ac8ad678b3ab523056c4c82f94d466ee778e373b00000000000000000000000000000000000000000000000000a941ced1366d2300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16003,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000043e4f031f795dcafd662ce097f53b5f908f39dc8000000000000000000000000000000000000000000000001bedafd7d055a9e15,0xca895f5cc0cb74950e32b7c08d55e7ecd6cc83eb7994f9f1961bcf69dae66bfd,2021-12-13 13:07:25.000 UTC,0,true +16006,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024749aedf18208ab74a8110e07e820286bb5acf800000000000000000000000024749aedf18208ab74a8110e07e820286bb5acf8000000000000000000000000000000000000000000000000006478fe5b8808fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7945f9a872671d217fe89785593d745eaa09e432e9b938aa1400e353f775a8a8,2022-05-28 03:24:12.000 UTC,0,true +16007,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063a6b026eff8f1abdab941cc0d18c5bb408e53e400000000000000000000000063a6b026eff8f1abdab941cc0d18c5bb408e53e400000000000000000000000000000000000000000000000000012bf0fe947c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16008,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000073b968d104cb550f4e28543a52ff7357b20c746800000000000000000000000073b968d104cb550f4e28543a52ff7357b20c746800000000000000000000000000000000000000000000000000070aca1038c8c200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16010,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000051c1e9bed89903e924611fa3c557b2827981848f000000000000000000000000000000000000000000000004d92c64a9dc61c669,0x63271b09fa2bd266ccd676d8a7f1b4ab16ac162db6d746de2140b694a001b358,2021-11-29 06:04:58.000 UTC,0,true +16011,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000934c6cbc9e0266dd266e35fa16540a2422fff889000000000000000000000000934c6cbc9e0266dd266e35fa16540a2422fff88900000000000000000000000000000000000000000000000001aa535d3d0c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000880807ca35b45f007854e0e834a605e397354f42000000000000000000000000880807ca35b45f007854e0e834a605e397354f42000000000000000000000000000000000000000000000000037465ffeb24810700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x199c1bc018f391d5ad61d0c35749fae330519a0917e26ea987f89d8072009581,2022-06-28 06:55:24.000 UTC,0,true +16015,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000729b81511ebba7c95f6f43a5e3b778f40772f622000000000000000000000000729b81511ebba7c95f6f43a5e3b778f40772f622000000000000000000000000000000000000000000000000015fcf799b7b940000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16017,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000fec958a68f2f46d67bf708f14badef9ab53c4e9200000000000000000000000000000000000000000000000ae401ad8ec9e75bd6,,,1,true +16018,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d7504409e859e84b126009c1a8a787b1475c8731000000000000000000000000d7504409e859e84b126009c1a8a787b1475c873100000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xb0b919fee3625ba0475d8f38ef9d16a1847abe10dbc97b504cf24849882ff3bf,2021-12-05 13:47:50.000 UTC,0,true +16021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000f4d6635a15f79d00700db4d8a40cc7baa655563d000000000000000000000000f4d6635a15f79d00700db4d8a40cc7baa655563d00000000000000000000000000000000000000000000000000000000b2d05e0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x9a334505fe52575058c1fd5af523035b35e4593c65121ea01267b26af91774e3,2022-02-09 09:13:29.000 UTC,0,true +16022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e538c32d73cc13610cb1fdc7191abc47be08ddd0000000000000000000000004e538c32d73cc13610cb1fdc7191abc47be08ddd000000000000000000000000000000000000000000000000008bf2e12306e90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000784b90d1b653b12deb2352cf9fd18e7c780a9f8c000000000000000000000000784b90d1b653b12deb2352cf9fd18e7c780a9f8c0000000000000000000000000000000000000000000000000069212e2133ac1700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16024,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f1ca045e8b77eb2c62b9c0e60708ce6fe54d4a570000000000000000000000000000000000000000000000000a021fcf4e4701fe,,,1,true +16025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002646fd1cf53139c336db689ff104c6ce3ba9b18b0000000000000000000000002646fd1cf53139c336db689ff104c6ce3ba9b18b0000000000000000000000000000000000000000000000000000000008f7aa0800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a345d187b9f4b68c0b3eedec152e8a1dd808d089000000000000000000000000a345d187b9f4b68c0b3eedec152e8a1dd808d0890000000000000000000000000000000000000000000000000057113f2731960000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e87bfff3c69f58c8bf30f1b29bf11e60605780e1000000000000000000000000e87bfff3c69f58c8bf30f1b29bf11e60605780e1000000000000000000000000000000000000000000000000015d66b74d6909de00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004e0515f80b238b785e8faae48cf0fa36b348b5e90000000000000000000000004e0515f80b238b785e8faae48cf0fa36b348b5e9000000000000000000000000000000000000000000000000001acba70d38060000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d54e90597ec00914fa99c4fd62dda9d1924a2665000000000000000000000000d54e90597ec00914fa99c4fd62dda9d1924a26650000000000000000000000000000000000000000000000000069339071ca280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16031,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6d1a769fa8232fcd858a9b4592d7ae2d6169bca000000000000000000000000a6d1a769fa8232fcd858a9b4592d7ae2d6169bca000000000000000000000000000000000000000000000000004b5e03fc7ccf8400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16032,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009437be78cdca83cc83423fe85e734e49bea511e00000000000000000000000009437be78cdca83cc83423fe85e734e49bea511e00000000000000000000000000000000000000000000000000243c2293decf70e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eaff78bc539dcc9b98e492f4e3bde6506f3ec238000000000000000000000000eaff78bc539dcc9b98e492f4e3bde6506f3ec2380000000000000000000000000000000000000000000000000154ff3827a91c3900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16036,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a0e4eccf02f9b83ee1f270c735751d602e88ea1e000000000000000000000000a0e4eccf02f9b83ee1f270c735751d602e88ea1e000000000000000000000000000000000000000000000007359bcae42b3a1f0400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16041,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f748833f13f24c8872b4b83e14e63607df9ce8d0000000000000000000000003f748833f13f24c8872b4b83e14e63607df9ce8d000000000000000000000000000000000000000000000000057a3548e05c429700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16042,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000004e0122cad4e35c83302a7fc3a402a215935f36070000000000000000000000004e0122cad4e35c83302a7fc3a402a215935f360700000000000000000000000000000000000000000000000000000000000fde8000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16043,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000054656203833a6c6646c66acb3d246d96eb6bc34c00000000000000000000000054656203833a6c6646c66acb3d246d96eb6bc34c00000000000000000000000000000000000000000000000000000000000fc32800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16044,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bbf8d46a69024593fcc0e692f1c0a2f38144ea84000000000000000000000000bbf8d46a69024593fcc0e692f1c0a2f38144ea8400000000000000000000000000000000000000000000000006ea53d65c36cfe300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16045,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ae7bc2ecb4d293105cb0b21500b710eeb7ca83210000000000000000000000000000000000000000000000020abdd9bee328ebaf,,,1,true +16046,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000dbb94c392bd0c21c2e4a1e7005012ee9907a06a0000000000000000000000000000000000000000000000002e95aeb8850ef4265,,,1,true +16047,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046488b2cab4ba1406f6fa1d5827c8d16c1f5fdea00000000000000000000000046488b2cab4ba1406f6fa1d5827c8d16c1f5fdea000000000000000000000000000000000000000000000000001d8313405c0a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16048,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049f63b254ea9043e57678c13e06aef257fab45c100000000000000000000000049f63b254ea9043e57678c13e06aef257fab45c1000000000000000000000000000000000000000000000000018431ef9971044000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6c062bcb5317ff645cee0885db3d30bfcea05a02ffe1628db9fc983a061130be,2021-12-20 17:00:08.000 UTC,0,true +16049,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fe15e3b4e9f695d5712583c591ae52f1af616a10000000000000000000000004fe15e3b4e9f695d5712583c591ae52f1af616a1000000000000000000000000000000000000000000000000016fee38a5d9468900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16050,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000010fd37e98c79529ca2249ca6086971c6e92e549f00000000000000000000000010fd37e98c79529ca2249ca6086971c6e92e549f00000000000000000000000000000000000000000000000000000000000fb77000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16051,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000004e3b5a6c60c3f39d9ee4b8151348fd56aaceda080000000000000000000000004e3b5a6c60c3f39d9ee4b8151348fd56aaceda0800000000000000000000000000000000000000000000000000000000000f906000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16053,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005da70d2a1858a883b42d560edeb5a4ff4e7829fe0000000000000000000000005da70d2a1858a883b42d560edeb5a4ff4e7829fe0000000000000000000000000000000000000000000000000031cf2d28a336e100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16054,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f830726d6750b458bd10326a32bf53e7ffebda74000000000000000000000000f830726d6750b458bd10326a32bf53e7ffebda74000000000000000000000000000000000000000000000000096e2973de7221ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16055,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000065935eeca6a9a5c9d5f3df0bd8341960b2516a5e00000000000000000000000065935eeca6a9a5c9d5f3df0bd8341960b2516a5e000000000000000000000000000000000000000000000000000000000a2b5cbc00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16056,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000cc910f68502b40d2bcdfad952f34db8778426e5e000000000000000000000000cc910f68502b40d2bcdfad952f34db8778426e5e00000000000000000000000000000000000000000000000000000000000fb77000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16058,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ccf27f3dae039a4d2981fe0deb0621346ac9c58c0000000000000000000000000000000000000000000000003edaed08765ae042,,,1,true +16059,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e92a21b89b64de21f920acc875cd0b1e782c33c0000000000000000000000002e92a21b89b64de21f920acc875cd0b1e782c33c00000000000000000000000000000000000000000000000000ae153d89fe800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd392e158fee8aa4ec5de197aa32835f89ec4f8fd5e90ecf0f6d85aef09f647ff,2022-04-17 05:12:53.000 UTC,0,true +16060,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000007bfc1a618783b32f57770d85c682fb04120858e70000000000000000000000007bfc1a618783b32f57770d85c682fb04120858e700000000000000000000000000000000000000000000000000000000000f906000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16061,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dffa4c9d55d7b1a2dc8197718c48b593420b9399000000000000000000000000dffa4c9d55d7b1a2dc8197718c48b593420b939900000000000000000000000000000000000000000000000006de8f1fce81ec6700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16062,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ffe9465c0458fdf8b8ad034aca2040324c3f9f02000000000000000000000000ffe9465c0458fdf8b8ad034aca2040324c3f9f020000000000000000000000000000000000000000000000000000000000102ca000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16063,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045c155d926df6c2e66b0a3db407587d192affff600000000000000000000000045c155d926df6c2e66b0a3db407587d192affff60000000000000000000000000000000000000000000000000010c3b085fd494000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16065,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b49883b3fe2aa3cdfaf9def7f3dba2816a681e16000000000000000000000000b49883b3fe2aa3cdfaf9def7f3dba2816a681e160000000000000000000000000000000000000000000000000032fdb6d4d2e90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16067,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000009a36d5b3a4347a221efe23851ce7cb9745fea6ff0000000000000000000000009a36d5b3a4347a221efe23851ce7cb9745fea6ff0000000000000000000000000000000000000000000000000000000000102ca000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16070,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f516ac25592ab08d6df0e6fdc934f14dad504369000000000000000000000000f516ac25592ab08d6df0e6fdc934f14dad5043690000000000000000000000000000000000000000000000000114809246492b3600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xad4ede185325b2cf2420913e454233d44342f37c74d7b62954bd1a52af177f33,2022-05-21 13:54:23.000 UTC,0,true +16071,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008894993046fa4c42816b3021de0bb1dabd5b0cd80000000000000000000000008894993046fa4c42816b3021de0bb1dabd5b0cd8000000000000000000000000000000000000000000000000014f796df858187200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16072,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000000ba7bdbdbd934320b8401646803ad939a4a9f3c00000000000000000000000000ba7bdbdbd934320b8401646803ad939a4a9f3c000000000000000000000000000000000000000000000000000000000010a1d000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16073,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049ec1574f4e5f03d830bec6a9a4441e10dfed84d00000000000000000000000049ec1574f4e5f03d830bec6a9a4441e10dfed84d0000000000000000000000000000000000000000000000000214e8348c4f000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x28eb1c15c650c6f9d26712fe2ffcf257b3f06138ff867421de20fb20b1c8a4d1,2021-12-21 10:49:55.000 UTC,0,true +16074,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000008325bcbea40dbc59e4e9fe0e9ce41ca781db08880000000000000000000000008325bcbea40dbc59e4e9fe0e9ce41ca781db08880000000000000000000000000000000000000000000000000000000000102ca000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16075,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2b41b28fe1d007bd1008391e517c4c5d27c815c000000000000000000000000a2b41b28fe1d007bd1008391e517c4c5d27c815c00000000000000000000000000000000000000000000000001380f858730dcdd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1be59af70e7ae3cb489c112a2b2c63b4590cd220047dab2ac1dfcabae98b7a61,2021-11-27 10:54:19.000 UTC,0,true +16076,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a083d45dc7b97eaf4532f19b112662bd3adf03a4000000000000000000000000a083d45dc7b97eaf4532f19b112662bd3adf03a40000000000000000000000000000000000000000000000000161714d2b50d60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9c5a8c3df69e7a196933d00fb2154f7ec979812c1394c4826c1bcd2b4871db83,2022-02-17 09:39:59.000 UTC,0,true +16077,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf09dae602adae0c48de9ef743060696132f6a92000000000000000000000000bf09dae602adae0c48de9ef743060696132f6a92000000000000000000000000000000000000000000000000007944dbe91eb54000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16078,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000cb5a1dc8307fc3f9c3fce8765232d42458f3aeb2000000000000000000000000cb5a1dc8307fc3f9c3fce8765232d42458f3aeb20000000000000000000000000000000000000000000000000000000000102ca000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16079,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000392bd4b4d4dfe5a3ab4370e348f90d1d508285bc000000000000000000000000392bd4b4d4dfe5a3ab4370e348f90d1d508285bc00000000000000000000000000000000000000000000000005c70b854a1c884000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16080,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ce6c4777822be44ef0d749ec77028b215b475ba0000000000000000000000008ce6c4777822be44ef0d749ec77028b215b475ba0000000000000000000000000000000000000000000000000079eb3dd4840d7400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa830f8fc1a0db6a671e660593cd9fbd7417a16e7458aade34d3d27f7c83b5bb6,2022-05-21 20:23:11.000 UTC,0,true +16081,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ef89f0bcfe2e3f6440ec2bbf0fe93646a9f6780d000000000000000000000000ef89f0bcfe2e3f6440ec2bbf0fe93646a9f6780d00000000000000000000000000000000000000000000000000000000000fb77000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16082,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000035856a6a5f866ca903c5d33773a96308c5b696bc00000000000000000000000035856a6a5f866ca903c5d33773a96308c5b696bc000000000000000000000000000000000000000000000000000000002e224d8000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16083,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5224abfce9d3a1e6c25fedd61f36c44e1e684c8000000000000000000000000a5224abfce9d3a1e6c25fedd61f36c44e1e684c800000000000000000000000000000000000000000000000000dd55851981c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x61123618741d424d2d6081b7e095df40c5043e5951422c174c4641888f9ee90c,2021-12-10 07:38:36.000 UTC,0,true +16085,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000001e3c45c9920310bc878e843db0ddaba304fa91150000000000000000000000001e3c45c9920310bc878e843db0ddaba304fa911500000000000000000000000000000000000000000000000000000000000f6d9c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16086,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b260669eb9471f8e1cac9f2897ff70e806e21af2000000000000000000000000b260669eb9471f8e1cac9f2897ff70e806e21af2000000000000000000000000000000000000000000000000004daf1126755d5d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16087,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000ab0619d952bf9ac0952c70ada9e62a227c698264000000000000000000000000ab0619d952bf9ac0952c70ada9e62a227c69826400000000000000000000000000000000000000000000000000000000017fbaf200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be862b4d355ecd39bbf23d7f939dc35ab86c4dbd000000000000000000000000be862b4d355ecd39bbf23d7f939dc35ab86c4dbd000000000000000000000000000000000000000000000000069df95c1315dc8300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x45d26aa01728be57493366da858e216f2ddc5b3ebc32362eb5444651eb82fd3a,2022-05-22 15:42:25.000 UTC,0,true +16093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6546c8d9306843350009d09e38705465673428a000000000000000000000000a6546c8d9306843350009d09e38705465673428a00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cae1cf90ec13e60a435e8fa638316ee337c472c0000000000000000000000004cae1cf90ec13e60a435e8fa638316ee337c472c000000000000000000000000000000000000000000000000000221b262dd800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cae1cf90ec13e60a435e8fa638316ee337c472c0000000000000000000000004cae1cf90ec13e60a435e8fa638316ee337c472c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030a515c27534a346be6eb5d1d5bb3d1e50db060a00000000000000000000000030a515c27534a346be6eb5d1d5bb3d1e50db060a0000000000000000000000000000000000000000000000000061a9cf9333ccac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16098,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7846949d13003dbaa2f98d555426a2a3dca5e6f000000000000000000000000e7846949d13003dbaa2f98d555426a2a3dca5e6f000000000000000000000000000000000000000000000000013f1a797dc9c9de00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16099,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f31a41419e2aa2ab3cccd915aaf3585096ed7034000000000000000000000000f31a41419e2aa2ab3cccd915aaf3585096ed7034000000000000000000000000000000000000000000000000005ed4667876741b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9ecd0952704f74692ee4b91849b5cdb552c31389e480c3a927f743added5ab98,2022-05-21 17:25:07.000 UTC,0,true +16101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004f30bb3d4198e6a839576f19a650aef2855e07150000000000000000000000004f30bb3d4198e6a839576f19a650aef2855e0715000000000000000000000000000000000000000000000000000aec234d240d9200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16102,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005af34a3fffc67e7778393ad01f4204354ff889d10000000000000000000000005af34a3fffc67e7778393ad01f4204354ff889d100000000000000000000000000000000000000000000000000ee7994cb49ad6800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16103,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030a98bc74cc6a10a36332802fdad70fee516054100000000000000000000000030a98bc74cc6a10a36332802fdad70fee51605410000000000000000000000000000000000000000000000000487aaf06bc87ca300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4f49f1aca3846ff1cdf682caf641baea09349753acfa7783e794cf3ffc4d02b5,2021-11-28 08:52:38.000 UTC,0,true +16107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5d900cb9631b1195aa53f2a378f4facbc8ec663000000000000000000000000e5d900cb9631b1195aa53f2a378f4facbc8ec663000000000000000000000000000000000000000000000000167b656ab822000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xed7ad251daac4062e107fbd7281fa671df5e19283fee7dff5b6b929a750417a2,2021-11-25 12:48:39.000 UTC,0,true +16111,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000798aafcaf1b9ee461d7d30f034dcab006dc495100000000000000000000000000000000000000000000000743bf75cfd3068a1fc,0xc3b89778850d4353c6be02cfce31dcacf04d23bbd69003ee0c6111330ad8db5f,2021-11-27 16:14:03.000 UTC,0,true +16113,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000002bed6fb507948e637179c175fe427f3205e345850000000000000000000000002bed6fb507948e637179c175fe427f3205e345850000000000000000000000000000000000000000000000000000000008a58a9e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16115,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3058ab3e0fbd58853b7e14eab9041ee849e7a61000000000000000000000000f3058ab3e0fbd58853b7e14eab9041ee849e7a6100000000000000000000000000000000000000000000000002ab76ad0fed1f0d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aabd00507b5df6f20819bc933f74d053ffa44ecd000000000000000000000000aabd00507b5df6f20819bc933f74d053ffa44ecd00000000000000000000000000000000000000000000000000aebc35e06a370000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000776678223fd719582183afa1865b041a18e83ee6000000000000000000000000776678223fd719582183afa1865b041a18e83ee6000000000000000000000000000000000000000000000000001ee13b0c991a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x657788da747086ae376a9ac3b99ef689d5e7d44db7a7c0597bf9850867394eb1,2022-08-28 15:27:53.000 UTC,0,true +16123,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d1516425127856704329b33a39240f1e5405bcad000000000000000000000000d1516425127856704329b33a39240f1e5405bcad000000000000000000000000000000000000000000000a7adbb7f6be0208000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xde97beb72d923c5a9c58196bfef2ab55ab5f20b278f74c711627fa9768023a6b,2021-12-09 12:05:39.000 UTC,0,true +16124,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1516425127856704329b33a39240f1e5405bcad000000000000000000000000d1516425127856704329b33a39240f1e5405bcad0000000000000000000000000000000000000000000000001cdcbf0409c631b700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa1ca8fd4dc2a54cdc4f17fc5a1cc87e97a98c3a4c0477d1bc5701c77d641c4b1,2021-12-09 12:04:29.000 UTC,0,true +16127,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000edb183bda0993b01d95eee08ce74158b671fed76000000000000000000000000edb183bda0993b01d95eee08ce74158b671fed7600000000000000000000000000000000000000000000000001573e4987acd81b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b211a2f3a1d20df7f8c3944e6228467e0abda9f4000000000000000000000000b211a2f3a1d20df7f8c3944e6228467e0abda9f40000000000000000000000000000000000000000000000000016811c7fded0d100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16131,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000070513a081114ed019361d7d6f0e575206da93810000000000000000000000000000000000000000000000028edd5b89ee18edb9d,0x42f2766d35ee0e0ac3199d3cf968998d64d503eada29cfea7871b0beaa69fef8,2021-11-24 14:49:16.000 UTC,0,true +16133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000caf268268ca94f53305c20cc92132fd51165c9a0000000000000000000000000caf268268ca94f53305c20cc92132fd51165c9a0000000000000000000000000000000000000000000000000001cc39dc64b3e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000caf268268ca94f53305c20cc92132fd51165c9a0000000000000000000000000caf268268ca94f53305c20cc92132fd51165c9a0000000000000000000000000000000000000000000000000005a7aff9324fdab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16135,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006167e0e49bb745c4665a77b53306ff4206fe70ff0000000000000000000000006167e0e49bb745c4665a77b53306ff4206fe70ff000000000000000000000000000000000000000000000000001a6adf86d786c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe178944852c30355bd786a756666f2dd8c64d1f67833ec296565f38352c29d1d,2021-12-15 17:39:10.000 UTC,0,true +16138,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d4d3fae4d0282fd8a558b5f42ba700974cbfd1a0000000000000000000000005d4d3fae4d0282fd8a558b5f42ba700974cbfd1a000000000000000000000000000000000000000000000000008093283475add900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16139,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000bb86cd4020dc5120cbe6d443551e32f85980131d000000000000000000000000bb86cd4020dc5120cbe6d443551e32f85980131d000000000000000000000000000000000000000000000001db74bd5ef5d8719200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000113cd2467bc19c16b4ce4a070e57666d35828eb3000000000000000000000000113cd2467bc19c16b4ce4a070e57666d35828eb3000000000000000000000000000000000000000000000000001c74672c9f76c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c512544e8f33fcccfaa1aa3b236da8f4348c14d0000000000000000000000000c512544e8f33fcccfaa1aa3b236da8f4348c14d000000000000000000000000000000000000000000000000005eb6874c1542a200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16144,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010b7a7e9a5d527a821b574e688c71519bdf8a15700000000000000000000000010b7a7e9a5d527a821b574e688c71519bdf8a15700000000000000000000000000000000000000000000000002bc2b9ce43b9d2300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16145,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000509da798f0af5bfd7a93e55d922c9e6795bc9b51000000000000000000000000509da798f0af5bfd7a93e55d922c9e6795bc9b5100000000000000000000000000000000000000000000000002072c08066ffe0200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d7554d0183e613e27cb4eda71622e57fb4150bb0000000000000000000000002d7554d0183e613e27cb4eda71622e57fb4150bb0000000000000000000000000000000000000000000000000158db44e201516b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16147,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f23d209054debaaf0d295c1fa0b22c5eca34706a000000000000000000000000f23d209054debaaf0d295c1fa0b22c5eca34706a00000000000000000000000000000000000000000000000000f5f8c6706f3cdd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16148,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049f4b1eac2a0fed5a7e58cef8af576c77495d6bf00000000000000000000000049f4b1eac2a0fed5a7e58cef8af576c77495d6bf00000000000000000000000000000000000000000000000001560a759083e10400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16149,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000154e41602119aba736ff9d23a17e8a2cb51545b1000000000000000000000000154e41602119aba736ff9d23a17e8a2cb51545b1000000000000000000000000000000000000000000000000001b910ceeba278000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16151,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1dbd6c82ccb233dafb553146e34ebdca59174ca000000000000000000000000a1dbd6c82ccb233dafb553146e34ebdca59174ca000000000000000000000000000000000000000000000000041bd209b3d5bb5300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16152,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a28335f6f1a2fb847821215ae4d32695e040ca60000000000000000000000002a28335f6f1a2fb847821215ae4d32695e040ca6000000000000000000000000000000000000000000000000066c67d86233c15a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x355d14d483bf9cfeb63f39cb386ec0d02b058529d83c864c8dbe3a67966c19b1,2022-01-29 13:07:25.000 UTC,0,true +16153,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f841249c065984ba49c785977b872231c1b44374000000000000000000000000f841249c065984ba49c785977b872231c1b4437400000000000000000000000000000000000000000000000000e983534e74ca9500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16154,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba2c8c57f57593956cfd612f97d9e882c44302f5000000000000000000000000ba2c8c57f57593956cfd612f97d9e882c44302f500000000000000000000000000000000000000000000000000f0807a9bbe232d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16155,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c55cf36f9f16c75e7d4bbd97ddbbcd4e4b0bb959000000000000000000000000c55cf36f9f16c75e7d4bbd97ddbbcd4e4b0bb95900000000000000000000000000000000000000000000000000e8430445faf12c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1ef1058a3b75a914c2f15b42a5e4ee6b19edffe000000000000000000000000d1ef1058a3b75a914c2f15b42a5e4ee6b19edffe0000000000000000000000000000000000000000000000000a07b12e2b997cd100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16158,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000dc4e7b7b9ee70846125d89d7440a184d5ca68b170000000000000000000000000000000000000000000000001b59dbf02698c597,,,1,true +16159,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046c7860fa18ff68e1faf50630546dff7f35d2b2300000000000000000000000046c7860fa18ff68e1faf50630546dff7f35d2b2300000000000000000000000000000000000000000000000006623f9014ae000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6890ba19de422639f7155a4a6c2fc7847d90bde000000000000000000000000f6890ba19de422639f7155a4a6c2fc7847d90bde00000000000000000000000000000000000000000000000001cd8c3e2dbea5ac00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16161,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba067d3c09153aa959072da7516f71686f7a49a9000000000000000000000000ba067d3c09153aa959072da7516f71686f7a49a900000000000000000000000000000000000000000000000000679bdbb4a4310000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16162,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000408e1c415a52cc08abab3ad8b08dffe842a6df8c000000000000000000000000408e1c415a52cc08abab3ad8b08dffe842a6df8c00000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc37fee294548c3cc4556757ad74241dc09ab644000000000000000000000000bc37fee294548c3cc4556757ad74241dc09ab64400000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16164,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d1a9f4e2e1730db50e46aa40c54fa41544092610000000000000000000000001d1a9f4e2e1730db50e46aa40c54fa415440926100000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16166,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a7d79d08c788860136fce0c3d6e82939b1d03a06000000000000000000000000a7d79d08c788860136fce0c3d6e82939b1d03a0600000000000000000000000000000000000000000000000018cb0ab861e24b6300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16167,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000097b04c20ca1cf1e89249b7b7b7462eb382e943e7000000000000000000000000000000000000000000000003456101d6c525df92,,,1,true +16171,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d16c33117e004fa8ea0dace84b942468e6b69798000000000000000000000000d16c33117e004fa8ea0dace84b942468e6b697980000000000000000000000000000000000000000000000000044f1920eca900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16175,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000046ba65479c4c550fb602065c0bb15d67472f78d100000000000000000000000046ba65479c4c550fb602065c0bb15d67472f78d1000000000000000000000000000000000000000000000000008c825996ba8c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000005a4be3634039a27d00f7634aaa5dc687ce4a7a0f0000000000000000000000005a4be3634039a27d00f7634aaa5dc687ce4a7a0f00000000000000000000000000000000000000000000000000000000000f906000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ac7005eb5a78dcee54ac369d345e91eafe9c1f7d000000000000000000000000ac7005eb5a78dcee54ac369d345e91eafe9c1f7d0000000000000000000000000000000000000000000000000000000000109a0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004630483f9edeb8dea6f5339bd8aa6c86fc6046de0000000000000000000000004630483f9edeb8dea6f5339bd8aa6c86fc6046de00000000000000000000000000000000000000000000000000870bb66d33c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0241acb15920c72b50194b4b74ed76be1296252e5beef672ba17a92888134e31,2022-03-19 08:03:51.000 UTC,0,true +16179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000daf3a243e5109d67ad7749121751510a8b54094c000000000000000000000000daf3a243e5109d67ad7749121751510a8b54094c000000000000000000000000000000000000000000000000001e7bfebd2be5c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000001793f656d03108ddbf56b5005a17142dc8fe1c400000000000000000000000001793f656d03108ddbf56b5005a17142dc8fe1c400000000000000000000000000000000000000000000000000000000000102ca000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16183,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f32e2c3394353274573bbcf669afbfcd7402423b000000000000000000000000f32e2c3394353274573bbcf669afbfcd7402423b000000000000000000000000000000000000000000000000046858b5b26e56ea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003bfbdf4a113f267c5001d86cfb1a60c2ebbf425e0000000000000000000000003bfbdf4a113f267c5001d86cfb1a60c2ebbf425e000000000000000000000000000000000000000000000000001e3f3cbfa26bc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16186,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ab232f3e0c775bbe09f6b5df0b0b7a71254f32a5000000000000000000000000ab232f3e0c775bbe09f6b5df0b0b7a71254f32a5000000000000000000000000000000000000000000000000000000000010c8e000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16187,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099f566638eb23d708fba490f4d9798247a402d0f00000000000000000000000099f566638eb23d708fba490f4d9798247a402d0f0000000000000000000000000000000000000000000000002eceba19cfa7359800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd0875f9799e2e44b03736d043f9216f3da56b375caa7dd380691e9828fbc1c62,2021-11-23 07:04:50.000 UTC,0,true +16189,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e47bf5707d521074a09066f77a7586d2f613aae7000000000000000000000000e47bf5707d521074a09066f77a7586d2f613aae7000000000000000000000000000000000000000000000000011b368f0c0c1af600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0a0c6f5bc32b676c63696d87fd1a51623b8d4fdb35056575950381d8bac9a3d7,2021-12-19 13:28:34.000 UTC,0,true +16191,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6e4600760fe4ad9c6a738569873728ff629c474000000000000000000000000d6e4600760fe4ad9c6a738569873728ff629c474000000000000000000000000000000000000000000000000002714711487800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16192,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e0e8ba21dadd65341b098b83bc1d1a5c927baa36000000000000000000000000e0e8ba21dadd65341b098b83bc1d1a5c927baa3600000000000000000000000000000000000000000000000000000000000f695000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005f40324ed97badd9079e67e162c83b1fb9168a120000000000000000000000005f40324ed97badd9079e67e162c83b1fb9168a1200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16195,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b52644ec19cff7e3fd37bd3f6c072724ed066b90000000000000000000000000b52644ec19cff7e3fd37bd3f6c072724ed066b9000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16196,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041adf6dc0bf8d5d85050a9d88a3c4b9b25ae439b00000000000000000000000041adf6dc0bf8d5d85050a9d88a3c4b9b25ae439b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16197,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b38575bd4f8d4e65b304c667526c473ff02fb610000000000000000000000000b38575bd4f8d4e65b304c667526c473ff02fb6100000000000000000000000000000000000000000000000001618e6317db0e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16198,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f6000000000000000000000000714cf7b379e9ccc07a452eea459095a54a60af45000000000000000000000000714cf7b379e9ccc07a452eea459095a54a60af4500000000000000000000000000000000000000000000000185d4175a04c25a1c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x4c5239ae63b7a5311d1af8ceaed7e3e96ea66cf033a81d0c1ea40840f88e0911,2021-11-21 15:27:51.000 UTC,0,true +16199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000741cfe64d81b0929895237a0a858b4628d7adbc9000000000000000000000000741cfe64d81b0929895237a0a858b4628d7adbc900000000000000000000000000000000000000000000000000000000000fcee000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16200,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e2cb253d7af60c49a3cc906ca3ea38916e1938a0000000000000000000000006e2cb253d7af60c49a3cc906ca3ea38916e1938a00000000000000000000000000000000000000000000000000019617d2b1ea0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16201,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3fe811aa9ec8a0a94b48cd81121043cf5cd0513000000000000000000000000f3fe811aa9ec8a0a94b48cd81121043cf5cd051300000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16202,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000312b37ef3e483dad46de413dbf9b421c8c920c31000000000000000000000000312b37ef3e483dad46de413dbf9b421c8c920c3100000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16203,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002f318c8f9d3938372eb49303fb14567d62df28d70000000000000000000000002f318c8f9d3938372eb49303fb14567d62df28d700000000000000000000000000000000000000000000000e831c382ea2498d9e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000272007d3625914bad0e1cc698e6d453f65c62f21000000000000000000000000272007d3625914bad0e1cc698e6d453f65c62f21000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x284ffb2c6e7d5b1708bc9f0c29746922461d4fbc2643d06a361c3bb03fbff69c,2022-04-15 04:45:59.000 UTC,0,true +16207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba0d2c9dde95078e97ad7052235da83b3018b585000000000000000000000000ba0d2c9dde95078e97ad7052235da83b3018b58500000000000000000000000000000000000000000000000004cb0aa27bbea18800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5a87f2febda9f4f1b6721c7972d080c9f4fd7f549a226bd08504b9994fbbf042,2021-12-06 11:35:58.000 UTC,0,true +16208,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dffa86ce7ee3aa3c1dcc6e884aaf4df86005b57e000000000000000000000000dffa86ce7ee3aa3c1dcc6e884aaf4df86005b57e00000000000000000000000000000000000000000000000004c1c7971c0656b700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x04003942d0a7af5d0ee0e704a3bdead2f607e6956714e06859a36dfa8a456a9b,2021-12-06 11:39:31.000 UTC,0,true +16209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050e1c1760db4681fcc6cf6935a27633e4441570700000000000000000000000050e1c1760db4681fcc6cf6935a27633e4441570700000000000000000000000000000000000000000000000004c42cfbaaaff1f700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1299262b3297301230e291537317707a3de6717657906929b3e0e57bd750b58d,2021-12-06 11:41:00.000 UTC,0,true +16210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003263decaa813a870862e32adbc85933060f9c46d0000000000000000000000003263decaa813a870862e32adbc85933060f9c46d00000000000000000000000000000000000000000000000004c4b9812fbff0a000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf6afffd53f1788147ea96bf048ef8944c9427ca59cd224191b4509a978f05fd9,2021-12-06 12:09:12.000 UTC,0,true +16212,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bd81af0236b3c3adcc59982015d1f5dbe337a5fe000000000000000000000000000000000000000000000010fa140f1616eb83ae,0xc8fad02ba353f26fa50bd4b2831e76f92830e703f5d7649b3ffda61dd6175bad,2021-12-10 06:15:19.000 UTC,0,true +16215,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e1c63ce6d149b35ed6daba02cc354d34c9faa180000000000000000000000001e1c63ce6d149b35ed6daba02cc354d34c9faa18000000000000000000000000000000000000000000000000001d5ceb30710cc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000695ac4ba3412e209a248041d4e94f6fec6e26e5c000000000000000000000000695ac4ba3412e209a248041d4e94f6fec6e26e5c00000000000000000000000000000000000000000000000000daa577074afc7400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16217,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000d0652b76639b93ae0e7829d5608e233c8e2eeb62000000000000000000000000d0652b76639b93ae0e7829d5608e233c8e2eeb6200000000000000000000000000000000000000000000000000000000443260af00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x32f7ad76bc4de5474b87355c506d6b70e3b275a00168ca24f16fbdc7b56a9003,2021-12-03 11:19:53.000 UTC,0,true +16218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030c05b9066113696b2f6194e067a21d0a77108e900000000000000000000000030c05b9066113696b2f6194e067a21d0a77108e90000000000000000000000000000000000000000000000000058e3751f8aa28a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16220,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c98ab80d060ca57dd067712d0ed084a58f69c490000000000000000000000007c98ab80d060ca57dd067712d0ed084a58f69c490000000000000000000000000000000000000000000000000026a46679ebdc7700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xca5c91dca869dcab7ef4be90cd89aaba6d5b3268cea8b62db62a992ce43593c8,2022-08-19 05:50:17.000 UTC,0,true +16222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000acbc858d78b2d3332cb96ace137ccfc49405a140000000000000000000000000acbc858d78b2d3332cb96ace137ccfc49405a1400000000000000000000000000000000000000000000000000000000000f906000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16224,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000344ae5a277c4cf1864941cfb35807f28d5241687000000000000000000000000344ae5a277c4cf1864941cfb35807f28d524168700000000000000000000000000000000000000000000000000b92f0e2f5d3f5100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000056325a71d3ff95c8bca8b985903123ab2ab9c10000000000000000000000000056325a71d3ff95c8bca8b985903123ab2ab9c100000000000000000000000000000000000000000000000000cee48c9c29a2da00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1f19706c75bfe926b6cef6a9a8f44dd733d6e9445aef47224abdb0bf4aed772c,2021-12-20 12:58:16.000 UTC,0,true +16226,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f89f28490e4f4a544df6f23782f19b9dc0855db0000000000000000000000001f89f28490e4f4a544df6f23782f19b9dc0855db00000000000000000000000000000000000000000000000000adfa07ba85f60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16227,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000095c8287dc54aab2176a7ba495034e24f315693f500000000000000000000000095c8287dc54aab2176a7ba495034e24f315693f500000000000000000000000000000000000000000000000000000000000fb77000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16231,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004dfd01933c8af1151d208a897b97926a2a47867e0000000000000000000000004dfd01933c8af1151d208a897b97926a2a47867e0000000000000000000000000000000000000000000000000064658521bd409f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ab0e775f87cf8d1c77e617ef050bbd365ae37740000000000000000000000000ab0e775f87cf8d1c77e617ef050bbd365ae3774000000000000000000000000000000000000000000000000000000000000fa7d000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16233,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000843601e30bab716f5128cd3e269ae70ee4d218f0000000000000000000000000843601e30bab716f5128cd3e269ae70ee4d218f00000000000000000000000000000000000000000000000000000000008f0d18000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000601d9a3d680b62e45b75e7d616e1024f1f5a3204000000000000000000000000601d9a3d680b62e45b75e7d616e1024f1f5a32040000000000000000000000000000000000000000000000000000000003df249900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000601d9a3d680b62e45b75e7d616e1024f1f5a3204000000000000000000000000601d9a3d680b62e45b75e7d616e1024f1f5a320400000000000000000000000000000000000000000000000000c234a4cd408fc500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000003a3b5ae8cfe9fee4cc8d783da3b6e89cacca5c080000000000000000000000003a3b5ae8cfe9fee4cc8d783da3b6e89cacca5c0800000000000000000000000000000000000000000000000000000000000fcee000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16237,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e241013cd6b4d4c70466cb1334ff500befaf10fb000000000000000000000000e241013cd6b4d4c70466cb1334ff500befaf10fb00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16238,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e241013cd6b4d4c70466cb1334ff500befaf10fb000000000000000000000000e241013cd6b4d4c70466cb1334ff500befaf10fb00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b05b03e6456d710d906b462f05d3403a0ded1c1b000000000000000000000000b05b03e6456d710d906b462f05d3403a0ded1c1b0000000000000000000000000000000000000000000000000104bcb131f6f11700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16241,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfb4e5c4833ba5258cf5b805d5ddc52d7c0fc2c2000000000000000000000000bfb4e5c4833ba5258cf5b805d5ddc52d7c0fc2c2000000000000000000000000000000000000000000000000013bb448f83570bf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x458689ead127fb0e9103cc5b961645317e5c22f59e08d64e3f6f1fa3219d1daf,2021-12-26 08:10:47.000 UTC,0,true +16243,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000034fca7ba58551dfa89e486c8934a7b35f4d02dd000000000000000000000000034fca7ba58551dfa89e486c8934a7b35f4d02dd000000000000000000000000000000000000000000000000003d49ccf811f1e7100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ab327d86e8a9cdc7bd516582ba3ca199ef431800000000000000000000000007ab327d86e8a9cdc7bd516582ba3ca199ef431800000000000000000000000000000000000000000000000000021f74c1e74d50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16245,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef0000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16246,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef0000000000000000000000000000000000000000000000001248be6158f4765f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16248,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef0000000000000000000000000000000000000000000000000000000000135c6800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16249,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef0000000000000000000000000000000000000000000000000000000000135c6800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16250,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b53672ab0315620662f31c429635bf8b3ac62345000000000000000000000000b53672ab0315620662f31c429635bf8b3ac62345000000000000000000000000000000000000000000000000002020aa16652ec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16251,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d2269145a8ebbe814be80284e1346bb428e49357000000000000000000000000d2269145a8ebbe814be80284e1346bb428e4935700000000000000000000000000000000000000000000000000335155dce04a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16253,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb81746a8af0738dd5a4412970a2224f3309749a000000000000000000000000bb81746a8af0738dd5a4412970a2224f3309749a00000000000000000000000000000000000000000000000000432b3043c3e57000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000048193168a19164c6f50c2fef223ebcd3cce803c900000000000000000000000048193168a19164c6f50c2fef223ebcd3cce803c900000000000000000000000000000000000000000000000000354a6ba7a1800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16256,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f09073676f37b4e8281b1be3b2f6a030fc188b70000000000000000000000002f09073676f37b4e8281b1be3b2f6a030fc188b700000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16258,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b129f1910a9e90a715b69a8dd42e7646a448dbb0000000000000000000000002b129f1910a9e90a715b69a8dd42e7646a448dbb0000000000000000000000000000000000000000000000000093e7bcd3f30a4600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043232604615a225aded5713e41161d82f616467200000000000000000000000043232604615a225aded5713e41161d82f616467200000000000000000000000000000000000000000000000001a91ce9a67b8c3100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16262,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000806375720c42753be3d98109e93f5df192fb0222000000000000000000000000806375720c42753be3d98109e93f5df192fb022200000000000000000000000000000000000000000000000000000000043fa7db00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x29ef5e2db5ee67fb356073458da9b510d79302d1ab73bd1d3a6ab27aab527f4d,2022-03-05 14:33:11.000 UTC,0,true +16263,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000806375720c42753be3d98109e93f5df192fb0222000000000000000000000000806375720c42753be3d98109e93f5df192fb0222000000000000000000000000000000000000000000000000007535f91d618cf500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x43aadccc817072d42d37dcadbd346b77d18f23b102a8b02f6bf29993d7dccbf6,2022-03-05 14:36:55.000 UTC,0,true +16264,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097ca9c21af6b38aa7f8df9b2da2555f9346fb89c00000000000000000000000097ca9c21af6b38aa7f8df9b2da2555f9346fb89c0000000000000000000000000000000000000000000000000012b80f58fefa0200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16266,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec712ce410df07c9a5a38954d1a85520410b8b83000000000000000000000000ec712ce410df07c9a5a38954d1a85520410b8b8300000000000000000000000000000000000000000000000000aaf4b2df7384be00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x77c474eba6526ce4ba403c345af8d4138f1b60125248fd7d0f7c62e8f77ed4c8,2022-01-01 15:20:54.000 UTC,0,true +16267,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e26d88cd8deec6e5762cc5be6e33cb49a01932b0000000000000000000000000e26d88cd8deec6e5762cc5be6e33cb49a01932b00000000000000000000000000000000000000000000000002a0e1730340bfb200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9f902c41ab9c170177b91a4ce6530588ea9ff35f26d47b00a965e8f4f93010b4,2021-12-11 11:00:54.000 UTC,0,true +16268,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000069b1763765443f114212247d6f639427c90e331a0000000000000000000000000000000000000000000000045fbb1781ff7daeab,,,1,true +16269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000daee2a62e9a1a13721bacb3f04d3f80b6a0719a5000000000000000000000000daee2a62e9a1a13721bacb3f04d3f80b6a0719a5000000000000000000000000000000000000000000000000000000000121b23d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16270,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be669d83fe4de792132aceb7cd84eb6479df76e3000000000000000000000000be669d83fe4de792132aceb7cd84eb6479df76e3000000000000000000000000000000000000000000000000030b3a1463b20f1900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16272,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000069b1763765443f114212247d6f639427c90e331a00000000000000000000000000000000000000000000000007f0b765bd31d9cc,,,1,true +16273,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000daee2a62e9a1a13721bacb3f04d3f80b6a0719a5000000000000000000000000daee2a62e9a1a13721bacb3f04d3f80b6a0719a50000000000000000000000000000000000000000000000000028db3066eac00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16275,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000223418ec0b76fa09f430ab36e609c71be901c559000000000000000000000000223418ec0b76fa09f430ab36e609c71be901c55900000000000000000000000000000000000000000000000001f161421c8e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16278,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000a8f515e37b1b074c9f1a41e5013252c607fcd7c000000000000000000000000000000000000000000000000288b24f6824425e8,,,1,true +16279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0c0adc8073b25431117f6d97368f743e3ee30c1000000000000000000000000a0c0adc8073b25431117f6d97368f743e3ee30c100000000000000000000000000000000000000000000000002e77a3ac53fc50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2a1c35503575c16b5b313a6e2f5bca81e336ec38b7ca8290836721e0571d4390,2021-12-31 10:27:32.000 UTC,0,true +16280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049c884014dec517a066438b6b17a3d12862d0b6400000000000000000000000049c884014dec517a066438b6b17a3d12862d0b6400000000000000000000000000000000000000000000000000738f8943a437b600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5f5902901bbe4221c633a4a491a21ab7e4ac091000000000000000000000000d5f5902901bbe4221c633a4a491a21ab7e4ac09100000000000000000000000000000000000000000000000000a0f2e2e18b34cd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b808821a873774589c738a5d7191bf7d498d23c0000000000000000000000005b808821a873774589c738a5d7191bf7d498d23c00000000000000000000000000000000000000000000000000adeb048011f30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e7e5c18aa987d8c8a55e610ff39f3fa48d48dd15000000000000000000000000e7e5c18aa987d8c8a55e610ff39f3fa48d48dd1500000000000000000000000000000000000000000000000000a4762b38ba469b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3acf8b3e836bb75b8ea170a58967db79e54deb7000000000000000000000000c3acf8b3e836bb75b8ea170a58967db79e54deb700000000000000000000000000000000000000000000000000001fad739e454f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16287,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003345deb0e8552220eab98763309bce486efafecf0000000000000000000000003345deb0e8552220eab98763309bce486efafecf0000000000000000000000000000000000000000000000000083edb0cb6cc64700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16288,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000823d0b781d951b22bd72e03a14a4656a4391c742000000000000000000000000823d0b781d951b22bd72e03a14a4656a4391c742000000000000000000000000000000000000000000000000000000001805ea7900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa18cd3a2ce1803231268f83fd62fdc2f9ca141865bf0899a5ba3305c2c17f705,2022-02-26 10:46:02.000 UTC,0,true +16291,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c3acf8b3e836bb75b8ea170a58967db79e54deb7000000000000000000000000c3acf8b3e836bb75b8ea170a58967db79e54deb7000000000000000000000000000000000000000000000000007c85980e88c37700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16292,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ac5201f9e7d908a9877929807cd878051b7f2d50000000000000000000000000ac5201f9e7d908a9877929807cd878051b7f2d5000000000000000000000000000000000000000000000000014ccabc532e581b900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4fcc2d19ae692a7aeb7d540139a37c7af1205c4000000000000000000000000f4fcc2d19ae692a7aeb7d540139a37c7af1205c40000000000000000000000000000000000000000000000001582b4c9a9db000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x143675e019b6041cdc2c9f4e9ccccad2918597bfc3e23f889c606d88dadcaaad,2021-11-28 14:47:52.000 UTC,0,true +16295,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f0ebd71291bf99bf64a87e2094dcd8496f098bb8000000000000000000000000f0ebd71291bf99bf64a87e2094dcd8496f098bb800000000000000000000000000000000000000000000000003ab00f7b6f758d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x29bfda8c8b31eb112c47c22adc4d3ee2c4c9564196effa9ca0428a1e5e43aeb7,2021-11-29 15:47:39.000 UTC,0,true +16297,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000047034b82573d3ed0cd16d01dfb70881b3af4d92000000000000000000000000047034b82573d3ed0cd16d01dfb70881b3af4d920000000000000000000000000000000000000000000000000157318fdf58fdbb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090da0933225115da9df2829e2c16d85069cd7d9700000000000000000000000090da0933225115da9df2829e2c16d85069cd7d9700000000000000000000000000000000000000000000000001161dc8173c796800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16299,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e28f1e1a4bb46e9a6128b59c7550deada8095a40000000000000000000000005e28f1e1a4bb46e9a6128b59c7550deada8095a400000000000000000000000000000000000000000000000001c3d7e86ba821d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4798089e4dbbeb6957442851f3f7bd8089b247ad30e48feabe12c71a2817446b,2021-12-26 19:25:52.000 UTC,0,true +16300,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006365aacc94254318572bcd5fb2a6fe68a23068df0000000000000000000000006365aacc94254318572bcd5fb2a6fe68a23068df0000000000000000000000000000000000000000000000000c9257c7eb3790a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xaf0bc70c6971ea337aa24c89c3cf899fddd791669fa7152b21c4f458a6c770ea,2021-11-21 19:47:40.000 UTC,0,true +16301,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000083ac17696774768c26e48a98d115b5eccbf81a86000000000000000000000000000000000000000000000000200888947fddce22,0xba858621a76b860bee6cdae3a8bac4d4f75d2e4dfe2755cc5b74b66a13c931b2,2022-01-07 22:22:54.000 UTC,0,true +16303,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eb536f050d7ff33eb2d7a822ee4553f75372b72a000000000000000000000000eb536f050d7ff33eb2d7a822ee4553f75372b72a00000000000000000000000000000000000000000000000000205f42659cdc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16304,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ebf1a5ffa9b693a8779aa3331796ab645ddcaf90000000000000000000000004ebf1a5ffa9b693a8779aa3331796ab645ddcaf9000000000000000000000000000000000000000000000000003440a6e228610000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000190522e3c7158e5462e0d4a6152cc00219368e90000000000000000000000000190522e3c7158e5462e0d4a6152cc00219368e900000000000000000000000000000000000000000000000000429d069189e000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd7f4b66eeacc1cfa328bf47ad7bee31b792de0fef024c7317489487d7f4dc93f,2022-01-18 18:27:36.000 UTC,0,true +16306,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000569849661e1163a0ddbfe46f39a43c8ec65c3f81000000000000000000000000569849661e1163a0ddbfe46f39a43c8ec65c3f8100000000000000000000000000000000000000000000000000e6d50a3c2e05fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16307,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd9f75b265dbdcf8460de10175f9f91bcccaf7c8000000000000000000000000bd9f75b265dbdcf8460de10175f9f91bcccaf7c800000000000000000000000000000000000000000000000003d72205ebb7f65b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16308,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000072868c29660f74cda76b23068e3f92075cb93c0000000000000000000000000072868c29660f74cda76b23068e3f92075cb93c0000000000000000000000000000000000000000000000000000e75406123288000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16313,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ba763db587b947ea9bf33348189f6352c970404f000000000000000000000000ba763db587b947ea9bf33348189f6352c970404f00000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16314,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000795080e2fe89afd22edc943b35a676f37d8f2f0a000000000000000000000000795080e2fe89afd22edc943b35a676f37d8f2f0a000000000000000000000000000000000000000000000000107694ca9cd875c300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d07d7fc9d70e703723cc08ee060a5969666934a6000000000000000000000000d07d7fc9d70e703723cc08ee060a5969666934a600000000000000000000000000000000000000000000000004bcfa8ab7807b5100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16324,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000092b3346317eeafba459be28c7ffe38703dca45d800000000000000000000000092b3346317eeafba459be28c7ffe38703dca45d8000000000000000000000000000000000000000000000000001e5380cb3cd30000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16329,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cc5e2bffbd7cfaf1fb68cd7ccbcb74ab2c355590000000000000000000000007cc5e2bffbd7cfaf1fb68cd7ccbcb74ab2c3555900000000000000000000000000000000000000000000000000402b38f1f4d7bf00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16332,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16333,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef000000000000000000000000659db7f3ea1801dde55259fccbb1e8608f8ebdef0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16334,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7031208635987cad84d1ef694019d0bfaff0adb000000000000000000000000c7031208635987cad84d1ef694019d0bfaff0adb000000000000000000000000000000000000000000000000001f6438b6de52c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16335,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000003ed50e3d283191ac4271606094b6a1bf0c8494cc0000000000000000000000003ed50e3d283191ac4271606094b6a1bf0c8494cc00000000000000000000000000000000000000000000000000000000000fb77000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16336,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000065fa6ca0de117ce8cf124e68c3a320539d9975f300000000000000000000000065fa6ca0de117ce8cf124e68c3a320539d9975f3000000000000000000000000000000000000000000000000000000000010385800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16338,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a6f425fc561201c4d5e9170e55ae3837ee9c0e90000000000000000000000000a6f425fc561201c4d5e9170e55ae3837ee9c0e90000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5ea6c1689e725bc6c624277e317778d1ce087c2371bccf8e578f56890f34f627,2022-06-01 08:04:54.000 UTC,0,true +16339,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000009c119e6105b3e97c67a19afe3ca7ad487a129fc70000000000000000000000009c119e6105b3e97c67a19afe3ca7ad487a129fc700000000000000000000000000000000000000000000000000000000000f906000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16340,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009989cc2cc1ec46091ffc41b53b4f10e33744776b0000000000000000000000009989cc2cc1ec46091ffc41b53b4f10e33744776b00000000000000000000000000000000000000000000000000c4d4a33ddd484e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16341,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006af4cde70d344c2623361a9045489c7b3db8c6a50000000000000000000000006af4cde70d344c2623361a9045489c7b3db8c6a50000000000000000000000000000000000000000000000000070d0a3acd47f9f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16342,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8823d3e315a08e32bff594362066fa117420485000000000000000000000000a8823d3e315a08e32bff594362066fa117420485000000000000000000000000000000000000000000000000077e772392b6000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x098e5704a110022e513f27ba67018de3ed61b9ea77bb993dbd47e3e038de43bb,2021-11-21 08:25:45.000 UTC,0,true +16343,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000084b1d109eb5334b79cc9e7572cea5a651bb844c800000000000000000000000084b1d109eb5334b79cc9e7572cea5a651bb844c800000000000000000000000000000000000000000000000000000000000fb77000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000b7909a40025d939d087efedae3c7f95b7897cad9000000000000000000000000b7909a40025d939d087efedae3c7f95b7897cad900000000000000000000000000000000000000000000000000000000000fcee000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16348,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e228f07818bc1dd1b42ad2edc604d1f2c200b1af000000000000000000000000e228f07818bc1dd1b42ad2edc604d1f2c200b1af000000000000000000000000000000000000000000000000000f907f2c787d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a454c64d1ed985303c22135d2eacbadd3dfeb713000000000000000000000000a454c64d1ed985303c22135d2eacbadd3dfeb71300000000000000000000000000000000000000000000000000abff3aff6b46fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16350,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000000de65e4c79b71931592fb489af49fa719d126b500000000000000000000000000de65e4c79b71931592fb489af49fa719d126b500000000000000000000000000000000000000000000000000e16fdeb32e6c9e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa7b99c38f4a30681d39571b2640b11f974b30c20f88269d822ab0a17c194888b,2022-05-30 07:35:09.000 UTC,0,true +16351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f6000000000000000000000000f5a80332ad3652fc285f2ba6f04793d1a1590f46000000000000000000000000f5a80332ad3652fc285f2ba6f04793d1a1590f46000000000000000000000000000000000000000000000000138f54735b52fb4b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000bd2be39bf52a66de061ab2a70b740b6421e41a0d000000000000000000000000bd2be39bf52a66de061ab2a70b740b6421e41a0d000000000000000000000000000000000000000000000000000000000010308800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16353,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a51ccd010b9122fee9a82c3428a9c4815beb34f5000000000000000000000000a51ccd010b9122fee9a82c3428a9c4815beb34f5000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16354,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008681943727aca47a0bdc9cd52be518a0f2d99fd60000000000000000000000008681943727aca47a0bdc9cd52be518a0f2d99fd60000000000000000000000000000000000000000000000000e043da61725000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000447ccb085fb749b73bd15a697ab2bc8fe07057dd000000000000000000000000447ccb085fb749b73bd15a697ab2bc8fe07057dd0000000000000000000000000000000000000000000000000713e24c4373000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3f4b73ffb4a4865e3f5651ca81be96c06aa27e2ac891022f1141e049ede50aec,2021-12-10 00:28:06.000 UTC,0,true +16358,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000004e41002ec04fd598057095026e9d78ef852509000000000000000000000000004e41002ec04fd598057095026e9d78ef85250900000000000000000000000000000000000000000000000000000000000102ca000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16359,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000001636262f0303075118376bb00f77c942bad697940000000000000000000000001636262f0303075118376bb00f77c942bad6979400000000000000000000000000000000000000000000000000000000000fb77000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000cc0fdfa2a9edfc89087e405a4d4b6120ea686fb0000000000000000000000000cc0fdfa2a9edfc89087e405a4d4b6120ea686fb0000000000000000000000000000000000000000000000000711c26648b6032200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xea7845e1cd7ff622e096f04d4c567260e46972b5ab3552bc3417e5aed1edc80e,2021-11-28 06:28:49.000 UTC,0,true +16361,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000eebf675984cd7ac1eb2cb70ac951118306b88288000000000000000000000000eebf675984cd7ac1eb2cb70ac951118306b88288000000000000000000000000000000000000000000000000000000000010059000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16362,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000cd87388d31ccc184050a1afd75c980ccf800c890000000000000000000000000cd87388d31ccc184050a1afd75c980ccf800c89000000000000000000000000000000000000000000000000000000000000f906000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16363,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000b53672ab0315620662f31c429635bf8b3ac62345000000000000000000000000b53672ab0315620662f31c429635bf8b3ac62345000000000000000000000000000000000000000000000000326584266145792d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee39c70efb6af381c15e949c53a2025e0303340d000000000000000000000000ee39c70efb6af381c15e949c53a2025e0303340d000000000000000000000000000000000000000000000000015b2a08b2c0e89300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe71492dee1e3a2b4572beab5a279cef8342e6db552bd3a9cd7c9f19f1efcb4dc,2022-05-21 10:59:50.000 UTC,0,true +16366,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000ceb96ee856fb4a0bd157e5912beb3d7542d10ac9000000000000000000000000ceb96ee856fb4a0bd157e5912beb3d7542d10ac9000000000000000000000000000000000000000000000000000000000010191800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ecd9653829ac3908a73fb43d3a51e0f9b8c27193000000000000000000000000ecd9653829ac3908a73fb43d3a51e0f9b8c27193000000000000000000000000000000000000000000000000001f022da5887e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xfc82b6a6c942bcdd955d7fae5e717e47d95063152fc8a4f58e7773e278d5dac9,2022-06-16 14:58:39.000 UTC,0,true +16370,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a4a52844c02088e9289cb41a4601e1f8b1847384000000000000000000000000a4a52844c02088e9289cb41a4601e1f8b18473840000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065deca52291340ee8af8476e7c2f7adcc869c69700000000000000000000000065deca52291340ee8af8476e7c2f7adcc869c6970000000000000000000000000000000000000000000000000394c6ad41ed318f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16373,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000843c45fb93515cfb6931353aad53cdb0570b326a000000000000000000000000843c45fb93515cfb6931353aad53cdb0570b326a0000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16375,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f787e89c570419bbefc7afea97e9a51e7a21ad2c000000000000000000000000f787e89c570419bbefc7afea97e9a51e7a21ad2c0000000000000000000000000000000000000000000000000329c6a1b533e73f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16376,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000fdee9fbb41c691025682e81534efeaf4723e9d60000000000000000000000000fdee9fbb41c691025682e81534efeaf4723e9d60000000000000000000000000000000000000000000000000394c5515113c70e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16377,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002d98ec3c5be60d9fb6f68c7f95a694b154f6e3b80000000000000000000000002d98ec3c5be60d9fb6f68c7f95a694b154f6e3b80000000000000000000000000000000000000000000000000e326d147539800000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16379,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007fb3507a58f8dd61944eb7d79160b16cf97e9edb0000000000000000000000007fb3507a58f8dd61944eb7d79160b16cf97e9edb0000000000000000000000000000000000000000000000000e609c82d34e000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16381,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a7ce39734d29a717ccacf7e6667de9353f09b75b000000000000000000000000a7ce39734d29a717ccacf7e6667de9353f09b75b0000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16382,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000eb6d85ff965506cf2639a828c3c04fa9f0d091120000000000000000000000000000000000000000000000012fa68ec8e62db52a,0x8d226af4e220c5a6a976c6a2155a054a68e186690c3f7bd45c6c3c4ef8c70511,2022-02-13 11:24:50.000 UTC,0,true +16383,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f60c9808a0205535c6a211f2732c730157f163fc00000000000000000000000000000000000000000000000522938106c0f77572,0x422a579ea26966f4998cbee274231675504064a85d63bca3b0d6588c20cfb2d7,2021-12-12 16:58:44.000 UTC,0,true +16384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f90181c1d7720d63588bf3578af0136082158542000000000000000000000000f90181c1d7720d63588bf3578af013608215854200000000000000000000000000000000000000000000000002bf25bfab1c87b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16385,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5f1fa7a6010b1afb2f08d799012390c178c2aba000000000000000000000000d5f1fa7a6010b1afb2f08d799012390c178c2aba00000000000000000000000000000000000000000000000002bea5b5ae5dd74a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000f69560fd1fe5e89e57616b02540b16169a680ce6000000000000000000000000f69560fd1fe5e89e57616b02540b16169a680ce60000000000000000000000000000000000000000000000000000000000102ca000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16387,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000badb5a9584060b9559be9fd43793bfa233be5d95000000000000000000000000badb5a9584060b9559be9fd43793bfa233be5d95000000000000000000000000000000000000000000000000013654378ef00cb600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb5cce49a142b0adb04d300f56092405ae121f1d7492114ff13bee7b774700168,2022-03-15 12:55:05.000 UTC,0,true +16388,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a174fb1658f1f33ba012fa05d69bc132cca50a3c000000000000000000000000a174fb1658f1f33ba012fa05d69bc132cca50a3c0000000000000000000000000000000000000000000000000e609c82d34e000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16389,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e758f44477e1c2e131f871b061a5ca18beff6bcc000000000000000000000000e758f44477e1c2e131f871b061a5ca18beff6bcc000000000000000000000000000000000000000000000000076c57a76a4da10b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16390,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006365aacc94254318572bcd5fb2a6fe68a23068df0000000000000000000000006365aacc94254318572bcd5fb2a6fe68a23068df000000000000000000000000000000000000000000000000000020894af2460000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16392,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000bf130dd432296f17e7cce406735a48470ec56956000000000000000000000000bf130dd432296f17e7cce406735a48470ec569560000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a5df59adb90608f7906b66eb17d9efa8e5c4ab71000000000000000000000000a5df59adb90608f7906b66eb17d9efa8e5c4ab7100000000000000000000000000000000000000000000000007a01f91c865470000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068a7d4056c98fbffa4f01f6c5496b768ebfab91500000000000000000000000068a7d4056c98fbffa4f01f6c5496b768ebfab91500000000000000000000000000000000000000000000000007661388fd0e54f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9de02a1aeb4390524e68a475fe7d49a2fbeeea33f48dff8f578630e39dd2119c,2021-11-23 08:12:48.000 UTC,0,true +16396,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002e87c017fa0140c482ed9f1dc424c364d555152b0000000000000000000000002e87c017fa0140c482ed9f1dc424c364d555152b0000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16397,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004c6a5ec9677de01b8ee7b271dbd5c0383bf50a030000000000000000000000004c6a5ec9677de01b8ee7b271dbd5c0383bf50a030000000000000000000000000000000000000000000000000774fdabb3b65ccc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4daa8b2c1d63b6df693b4643cae1a0c5f9e1ac35249ed6407a5b3effd6f5911d,2021-11-23 09:07:33.000 UTC,0,true +16398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000986b4eb9604972b9f0fe3e37dc531412bf19d39e000000000000000000000000986b4eb9604972b9f0fe3e37dc531412bf19d39e000000000000000000000000000000000000000000000000076e267049e741f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x29c5c972cf2b1a63a4171db00990d516d20261f1f8337eb5402b2c6b5a6a2973,2021-11-23 09:15:43.000 UTC,0,true +16399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000009337aae58a723ce45f9d4ab24fb85b19ae6b6ee70000000000000000000000009337aae58a723ce45f9d4ab24fb85b19ae6b6ee700000000000000000000000000000000000000000000000000000000093ddc6e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x4a0dedc00bccde5a709816b89690917c53613aa886df789e212271e1935e1118,2022-06-16 12:26:12.000 UTC,0,true +16400,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e1c57826461421f2acffd361673ceafdb71f349f000000000000000000000000e1c57826461421f2acffd361673ceafdb71f349f0000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16401,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a0d53d61037ac768a7e18a86428c3cfd662ed2a0000000000000000000000003a0d53d61037ac768a7e18a86428c3cfd662ed2a00000000000000000000000000000000000000000000000000305aae3e83e6b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16402,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd5b1e1ce2b0284a6b716e15e82420f2b79d5f7b000000000000000000000000fd5b1e1ce2b0284a6b716e15e82420f2b79d5f7b000000000000000000000000000000000000000000000000013a80b2fd5eed2900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045a5549b2baf17dcaa883e1b4f40bc89abce8a2e00000000000000000000000045a5549b2baf17dcaa883e1b4f40bc89abce8a2e0000000000000000000000000000000000000000000000000000ed4d5daec70000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000209e3dcad4a178be4475238fd6cc4e62b7b6ac80000000000000000000000000209e3dcad4a178be4475238fd6cc4e62b7b6ac800000000000000000000000000000000000000000000000000986fd4c05d594c900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16410,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cba87d88699365cd440366719c21ac7f1b790a12000000000000000000000000cba87d88699365cd440366719c21ac7f1b790a120000000000000000000000000000000000000000000000000082b65d343cd14000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x06ba81ec66ee077dabc49e261b4598b3878549bac47dcea0880430fb00db5269,2021-11-21 15:35:06.000 UTC,0,true +16412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ead180ae502757fc6e444e4cf3d861fe27fe0ac0000000000000000000000003ead180ae502757fc6e444e4cf3d861fe27fe0ac0000000000000000000000000000000000000000000000003efe1e383e5e4a0800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xff672c0d2453349ac0f43b52568ed858b09c7b4aacad78cd1713693e4e5bfdb2,2021-11-23 01:57:45.000 UTC,0,true +16414,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbcf84dec4d532881543edfab762844d5dd100dc000000000000000000000000fbcf84dec4d532881543edfab762844d5dd100dc00000000000000000000000000000000000000000000000002dd5af7a414616c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16415,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000677d9c4f92616e96b271af5c07eaf91804be6ac9000000000000000000000000677d9c4f92616e96b271af5c07eaf91804be6ac9000000000000000000000000000000000000000000000000000f6d48f4c67d7500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000052f654faf01d809aba82e645bde093f5037924fb00000000000000000000000052f654faf01d809aba82e645bde093f5037924fb00000000000000000000000000000000000000000000000000000000050524b000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16418,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004d96836b10b3fa48970e7a9929ab5c40d1ab4ec00000000000000000000000004d96836b10b3fa48970e7a9929ab5c40d1ab4ec00000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e5ae85b28b61cd23b9781ea8888352661e7fb5d0000000000000000000000003e5ae85b28b61cd23b9781ea8888352661e7fb5d00000000000000000000000000000000000000000000000001252471e143194700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5bc81829141cc7ae5039cab8ea719798331f6f6000000000000000000000000d5bc81829141cc7ae5039cab8ea719798331f6f600000000000000000000000000000000000000000000000001397d082bc58e1f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x077110c41b2aeea0f25f2a05398cfba1ca64ab8de1c97426c184f60a022c27d0,2021-11-28 05:22:57.000 UTC,0,true +16430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000196e7bcc060303cf386e40095a111277f6c91f3b000000000000000000000000196e7bcc060303cf386e40095a111277f6c91f3b000000000000000000000000000000000000000000000000014efac9a304501300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7cca7d6fbba6459d52f46a2b2e0c25494bfc9ab89cb499930266dc4083bd8e14,2022-05-21 10:10:44.000 UTC,0,true +16431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a26cae39c5d0ffa194f3ac438f4ffcae10da2130000000000000000000000006a26cae39c5d0ffa194f3ac438f4ffcae10da21300000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16432,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a26cae39c5d0ffa194f3ac438f4ffcae10da2130000000000000000000000006a26cae39c5d0ffa194f3ac438f4ffcae10da2130000000000000000000000000000000000000000000000000167a3f9761cf96b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16433,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000009ef9c73d7d8239b93fe48b35a6974292c2ff1e1c0000000000000000000000009ef9c73d7d8239b93fe48b35a6974292c2ff1e1c00000000000000000000000000000000000000000000000000000000200e7e8000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xf909b92d7c3e8ce7cbf767dfe9a4abb80988d8da17fdf076f1b244427829a10d,2021-12-13 11:25:22.000 UTC,0,true +16435,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000005b78f06123ee99dc8b21d4e1ef51afe08059d5ec00000000000000000000000000000000000000000000001003c2a21ecbd2e6b2,0x90885767125bec492a85c382c523a931c0849eb2e5374b1e08043a591a72b6e5,2022-01-24 17:12:09.000 UTC,0,true +16437,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000968c9fd77857295327d6a516d2be3b03ceef3cc0000000000000000000000000968c9fd77857295327d6a516d2be3b03ceef3cc000000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3544edb6389e79875b2cae18b808baa7b3fe34155ba55ad2320bfb66b91753ad,2021-12-27 15:32:51.000 UTC,0,true +16438,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000056a090734d40037545d617a5ef56309b3ed499a400000000000000000000000056a090734d40037545d617a5ef56309b3ed499a40000000000000000000000000000000000000000000000000085f15ef08539c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7653674a547ab3f6cae714170181051a8c7e1c233aea1349c4e00938b431fcea,2022-06-01 08:52:56.000 UTC,0,true +16439,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d705adf785cc44d3b8b0ab42819252633ccdaec0000000000000000000000002d705adf785cc44d3b8b0ab42819252633ccdaec0000000000000000000000000000000000000000000000000109eeec5930d1b600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2afc08446a1342037e6c1194ff69b61966c4d872949cc23711088abe1134a37e,2021-12-27 10:20:30.000 UTC,0,true +16440,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000891acdefa5f01ab48bf69ff789ce9d3a9997f01700000000000000000000000000000000000000000000000440e5988847f53549,,,1,true +16445,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d063eaceaa164db6eb296b6c7011cbb6f5355770000000000000000000000000d063eaceaa164db6eb296b6c7011cbb6f535577000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f256bb63d41a2c1fca4250d6c9a6fb7ff69df7a7000000000000000000000000f256bb63d41a2c1fca4250d6c9a6fb7ff69df7a700000000000000000000000000000000000000000000000001cdda4faccd000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16448,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000beb3662c34c8be5172b32ef9d3012e5c7b8680c0000000000000000000000000beb3662c34c8be5172b32ef9d3012e5c7b8680c00000000000000000000000000000000000000000000000000424ea52507ecb0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16449,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c27581421dcdcdec3d3f916414e117f82e185465000000000000000000000000c27581421dcdcdec3d3f916414e117f82e18546500000000000000000000000000000000000000000000000000ae6a8c035c4b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16450,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffd5e9186f89ce3a22f836dab29115a5afb29992000000000000000000000000ffd5e9186f89ce3a22f836dab29115a5afb29992000000000000000000000000000000000000000000000000001b475ca8c2ad6800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16451,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a67a20dfc73c86f6ba5f4438d8914e3f6780d397000000000000000000000000a67a20dfc73c86f6ba5f4438d8914e3f6780d3970000000000000000000000000000000000000000000000000058aee4087cb95500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16452,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000368f15629684eaeedc064926badd534e535dd79c000000000000000000000000368f15629684eaeedc064926badd534e535dd79c000000000000000000000000000000000000000000000000035c7041ea94814300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16453,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097ce2212e16138c638f90a873872de76aa1f6ec300000000000000000000000097ce2212e16138c638f90a873872de76aa1f6ec3000000000000000000000000000000000000000000000000027258b897331f1d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16455,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e26917d01160f51dc28a58be9e1489b52a3eae67000000000000000000000000e26917d01160f51dc28a58be9e1489b52a3eae6700000000000000000000000000000000000000000000000000194dd5c046bac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f6a82e1452f38fdcb4f15e050ccec895bde84456000000000000000000000000f6a82e1452f38fdcb4f15e050ccec895bde84456000000000000000000000000000000000000000000000000046d29253f5c7ed600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16458,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000386f3f9d3f5bcefaefe962fbeb849ca6c4dadd7c00000000000000000000000000000000000000000000000000005af3107a4000,,,1,true +16459,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbe3e8d699640cfa4cd808a247d0fd2349aef9b5000000000000000000000000fbe3e8d699640cfa4cd808a247d0fd2349aef9b5000000000000000000000000000000000000000000000000000acfec3eec1f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005533f954d78aaf3601b8e0aa1f3ce4140bde23d70000000000000000000000005533f954d78aaf3601b8e0aa1f3ce4140bde23d70000000000000000000000000000000000000000000000000f410cfa414c7a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da445e727b9cfe07b83b4b8fe7fcb3f70e326500000000000000000000000000da445e727b9cfe07b83b4b8fe7fcb3f70e32650000000000000000000000000000000000000000000000000000a8371da2115a8e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16469,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f486d56cce70c481b3455af901fcc4f03fee8107000000000000000000000000000000000000000000000002e68d65f925534e36,,,1,true +16470,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d548894265f1ac957a4a9a6a9f0bbf28317949e0000000000000000000000004d548894265f1ac957a4a9a6a9f0bbf28317949e0000000000000000000000000000000000000000000000000aafd120b1854e5a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7dc6b3af103c6ff2538eac1b54dd11a0134578ab7845e4d0ff1c7fe771385436,2021-12-07 11:21:53.000 UTC,0,true +16472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ee538b3a9c12644a9d3ae20a67437e8d18b91c20000000000000000000000004ee538b3a9c12644a9d3ae20a67437e8d18b91c200000000000000000000000000000000000000000000000006156aea5d1265f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000350a4336c8acf120d23ef732d24969602d7b9b0b000000000000000000000000350a4336c8acf120d23ef732d24969602d7b9b0b00000000000000000000000000000000000000000000000001603a4f0f14ce0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16475,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009c39e0731f467f4875d4938ca4a79502d137d7ad000000000000000000000000000000000000000000000009d300bfe10af7aebb,0xaec781e8f66b48dee3b2eb023a677a14579473964129ae619f8bfed6da2b2fd1,2022-03-21 08:59:51.000 UTC,0,true +16477,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065be5a73d072e8454d88c3ffe1a278d5ff2fff3400000000000000000000000065be5a73d072e8454d88c3ffe1a278d5ff2fff34000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16478,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000decd4b961b1984c44afbadbe2844777a627572aa000000000000000000000000decd4b961b1984c44afbadbe2844777a627572aa0000000000000000000000000000000000000000000000000853a0d2313c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x20020ff990bc70dd94ff094a61208cc6c34a4b98493aa4a49caf7f397f3924b3,2022-01-13 00:24:33.000 UTC,0,true +16480,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a535d27b204d9c2280be5ccb73ae48bf19f52c94000000000000000000000000a535d27b204d9c2280be5ccb73ae48bf19f52c94000000000000000000000000000000000000000000000000001b4cbd353e684000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16481,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000a535d27b204d9c2280be5ccb73ae48bf19f52c94000000000000000000000000a535d27b204d9c2280be5ccb73ae48bf19f52c940000000000000000000000000000000000000000000000000000000023f2241300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16482,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000ab0bdde61532fa3df988646d606326f4c93f6dd0000000000000000000000000ab0bdde61532fa3df988646d606326f4c93f6dd0000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16483,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000da7c9a05cde990986310b4c77a2e92da2db0f542000000000000000000000000da7c9a05cde990986310b4c77a2e92da2db0f5420000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16484,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b41b0b63018085c58b5ac521303e9f23bb2edd14000000000000000000000000b41b0b63018085c58b5ac521303e9f23bb2edd14000000000000000000000000000000000000000000000000013294476f8a944d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16485,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008fb6eb0df60b4b574d4dcd34b330b7c969b986390000000000000000000000008fb6eb0df60b4b574d4dcd34b330b7c969b986390000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16486,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000faeb5539ae06c460aa83e1849a69b9bfd52395d5000000000000000000000000faeb5539ae06c460aa83e1849a69b9bfd52395d50000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16487,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000357d5b3b1527f642da8765b98b4717e907a930ec000000000000000000000000357d5b3b1527f642da8765b98b4717e907a930ec00000000000000000000000000000000000000000000000000f5b658930f605100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1c300505e51683db6eb1722d01ae9758261b6a4b40abb81d6c9bef9993fa4bed,2022-06-02 07:17:18.000 UTC,0,true +16488,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000b5b783402b764ae687386af9a87da28eee027a46000000000000000000000000b5b783402b764ae687386af9a87da28eee027a46000000000000000000000000000000000000000000000000000000000102cefe00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16489,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bb7e284fd7b65a64581d1aa227e79c640899e4b5000000000000000000000000bb7e284fd7b65a64581d1aa227e79c640899e4b500000000000000000000000000000000000000000000000001547e089196b43500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032aa102827efed975456b03f712337511f6b0a1500000000000000000000000032aa102827efed975456b03f712337511f6b0a1500000000000000000000000000000000000000000000000004db73254763000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x34690ffc37d61a32cfc2984f18caee18976957426b0131db667bec35f43d0dca,2021-12-11 06:38:12.000 UTC,0,true +16494,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007e0de437a96a9844dde4e43326aa83b3cc6384f00000000000000000000000007e0de437a96a9844dde4e43326aa83b3cc6384f00000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5fd654ba7c9c9d6b5710fc347c1306e855ec582000000000000000000000000c5fd654ba7c9c9d6b5710fc347c1306e855ec58200000000000000000000000000000000000000000000000001d74d21b9ea085a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9895cb951d6d8d37de3cc3426b1ba05e91a37b2548c3957c4d4c50e6d989d36b,2021-11-27 10:02:08.000 UTC,0,true +16498,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000fcffa243e47f0f9607b426312a3f54daba0d4c93000000000000000000000000fcffa243e47f0f9607b426312a3f54daba0d4c930000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000000761b46d1a9309e449c06215827573143f85d7b60000000000000000000000000761b46d1a9309e449c06215827573143f85d7b6000000000000000000000000000000000000000000000000000000027f6a7e5600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xaf715fefcfcc6c26a2c745dd31f84db82a119134191d0abcb72a91abd114caeb,2021-12-01 10:09:59.000 UTC,0,true +16500,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000761b46d1a9309e449c06215827573143f85d7b60000000000000000000000000761b46d1a9309e449c06215827573143f85d7b60000000000000000000000000000000000000000000000000182fc338fd1361b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe00f3fc44303c7fd3065abf96315e481e722ac4dfe6d3dbbefbf5fbfcb4f399e,2021-12-01 10:06:06.000 UTC,0,true +16501,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000002260cf37fe45c007824d31815d561ed6204befd00000000000000000000000002260cf37fe45c007824d31815d561ed6204befd0000000000000000000000000000000000000000000000000e92596fd629000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16502,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000151997baecc36419f91a03e3cfa79b06ae99669f000000000000000000000000151997baecc36419f91a03e3cfa79b06ae99669f0000000000000000000000000000000000000000000000000e2f957bf167800000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16503,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c8fe1c27d568ee2177e27154d954352877d6899b000000000000000000000000c8fe1c27d568ee2177e27154d954352877d6899b0000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16504,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c674e0feb95a9203f670417a9aa1745e4c509842000000000000000000000000c674e0feb95a9203f670417a9aa1745e4c5098420000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7e36f0a2af61953b20f0da39eb53d9d22b6c07d000000000000000000000000f7e36f0a2af61953b20f0da39eb53d9d22b6c07d00000000000000000000000000000000000000000000000000503b54323d336300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d07f1b97fbd20521e53c69f4fd34de6542cb00b9000000000000000000000000d07f1b97fbd20521e53c69f4fd34de6542cb00b90000000000000000000000000000000000000000000000000000000000102ca000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16507,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b7f08230e88f43df94fb2af78175de42f88e5148000000000000000000000000b7f08230e88f43df94fb2af78175de42f88e51480000000000000000000000000000000000000000000000000e609c82d34e000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16508,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef0171fedb4bdd6f1713d204d5978bb2b138909d000000000000000000000000ef0171fedb4bdd6f1713d204d5978bb2b138909d00000000000000000000000000000000000000000000000000815b7486d3400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3ad2cdd33642ac431389dda238537c66c2c729c163c5b229eaa9736b22e75a76,2022-02-08 11:16:31.000 UTC,0,true +16509,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000da21cd0183af61a6666988364f281092256fe6ab000000000000000000000000da21cd0183af61a6666988364f281092256fe6ab0000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b660807b7208cc17c80f606eed0e7da5f69e7710000000000000000000000007b660807b7208cc17c80f606eed0e7da5f69e771000000000000000000000000000000000000000000000000003f5fcd1968bc0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16511,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000000555c5a397d52b52d5f18f19695e30d2d7fe8cc00000000000000000000000000555c5a397d52b52d5f18f19695e30d2d7fe8cc0000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16512,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000066fda376c00d156e3c14767ae54f3e4b7e8c6d7400000000000000000000000066fda376c00d156e3c14767ae54f3e4b7e8c6d740000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16513,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd15b4342a031bbd032a9bf1d34fbc7515f7933d000000000000000000000000dd15b4342a031bbd032a9bf1d34fbc7515f7933d00000000000000000000000000000000000000000000000001ea818d75fd81f300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16514,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000091104fd56af1e295c626108f49a144e44674e48d00000000000000000000000091104fd56af1e295c626108f49a144e44674e48d0000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16515,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e78cbe52ab6f05dd39dde596b6885d36ece13f41000000000000000000000000e78cbe52ab6f05dd39dde596b6885d36ece13f410000000000000000000000000000000000000000000000000e2edf95d073000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088307d3bd0e4a1908c442d2d05c8651e643333b400000000000000000000000088307d3bd0e4a1908c442d2d05c8651e643333b400000000000000000000000000000000000000000000000000214fc675ec700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16517,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004f904839aa85c581d91d45ab190609f3573275710000000000000000000000004f904839aa85c581d91d45ab190609f3573275710000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16518,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000f51996a94205f0700b0090e5be3db5d08d887cb0000000000000000000000000f51996a94205f0700b0090e5be3db5d08d887cb0000000000000000000000000000000000000000000000000f43fc2c04ee000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16519,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000035afbcc1be94ed3b3c0bb9a71561aeae5d47dc8e00000000000000000000000035afbcc1be94ed3b3c0bb9a71561aeae5d47dc8e0000000000000000000000000000000000000000000000000e40481bf7d9400000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16520,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000623b22606612eff9d107d8acbdbdc54b2691190c000000000000000000000000623b22606612eff9d107d8acbdbdc54b2691190c0000000000000000000000000000000000000000000000000f43fc2c04ee000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16521,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000ca81706c587a64a73e720b2a66894d52c5957b23000000000000000000000000ca81706c587a64a73e720b2a66894d52c5957b230000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16522,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000a3e1b18bdf4311a23894e9fd3a57c0f1ec4c859f000000000000000000000000a3e1b18bdf4311a23894e9fd3a57c0f1ec4c859f0000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16523,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006c8febfce14a32eda3e3a3f1246521d2ceb1701c0000000000000000000000006c8febfce14a32eda3e3a3f1246521d2ceb1701c0000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16524,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000009a1c5911f6bb5481ad63c103569bfd4f186c706b0000000000000000000000009a1c5911f6bb5481ad63c103569bfd4f186c706b0000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16525,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae9b8c92ba9cd153fe5e52cd623caae3f17dedf4000000000000000000000000ae9b8c92ba9cd153fe5e52cd623caae3f17dedf400000000000000000000000000000000000000000000000000a9a5047968430000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16526,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000f240c40f09faf67cb254f7475b01287fd0583514000000000000000000000000f240c40f09faf67cb254f7475b01287fd058351400000000000000000000000000000000000000000000000000000000321d4dcb00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x84b05992479bfd8a13191c83f96ff6eebc2b37e5393d34fc80856edfa4cfcadc,2021-11-26 07:27:39.000 UTC,0,true +16527,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000020ba98f7f2a97af0b6b42e73d6fe905ea4bb475600000000000000000000000020ba98f7f2a97af0b6b42e73d6fe905ea4bb4756000000000000000000000000000000000000000000000000000000003b15b7b200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xba8c1dec7859f5f1cbda37f9c74216f9b0a12ecd074c7b4cb673c70d50c5e2bd,2021-11-26 07:34:33.000 UTC,0,true +16529,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c76fa990f9fc8e2d51647f48fc5b31af5e892b58000000000000000000000000c76fa990f9fc8e2d51647f48fc5b31af5e892b58000000000000000000000000000000000000000000000000031e381d6514f96400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16530,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000072d799a56ea651470e30b8cfdd6ba1be50db1ed100000000000000000000000072d799a56ea651470e30b8cfdd6ba1be50db1ed10000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16533,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000390f824ae0d77b4e510e1e49f4ca4be45909386e000000000000000000000000390f824ae0d77b4e510e1e49f4ca4be45909386e000000000000000000000000000000000000000000000000034270e0333fb71100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16535,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000dbc75c003e387e0503f269d645be9e1469f25ac7000000000000000000000000dbc75c003e387e0503f269d645be9e1469f25ac70000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16536,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000023b76e8cce30575181a1fc3a245422857147279000000000000000000000000023b76e8cce30575181a1fc3a2454228571472790000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16538,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001aa6719c1e9198c9b5499303a3f7dbb81390db960000000000000000000000001aa6719c1e9198c9b5499303a3f7dbb81390db960000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16539,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e1a5cd5bf397c10783dc6f92cf94057dcc345e30000000000000000000000000e1a5cd5bf397c10783dc6f92cf94057dcc345e30000000000000000000000000000000000000000000000000026e8e633ab6e8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x860f64bc92f021eabe6f8e6568d5bf0f30412f0c4a5cd998242e3c217bd32fc9,2022-05-29 02:43:14.000 UTC,0,true +16540,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000093fa220a56f80355a960738dc34101c401d7062800000000000000000000000093fa220a56f80355a960738dc34101c401d706280000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16541,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7790a6880a166f79d44a12a7a91897a895b6420000000000000000000000000c7790a6880a166f79d44a12a7a91897a895b6420000000000000000000000000000000000000000000000000003122fd6e2c40db00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16542,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000009bd5448fe9d544339ef01bde163032ff612c3a570000000000000000000000009bd5448fe9d544339ef01bde163032ff612c3a570000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16543,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000511b820f3c51c529d47e240c36c18ce785b1369700000000000000000000000000000000000000000000000082bbdc0616b49281,,,1,true +16545,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000a2bc88883ccc7e9cfa4af8ca05983336f2903d35000000000000000000000000a2bc88883ccc7e9cfa4af8ca05983336f2903d350000000000000000000000000000000000000000000000000000000015a31c2d00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x40f5e3654544c8d1bed0ea54680a746cfa4300ce1f3c88ad658e1537bc35582e,2022-03-14 01:43:51.000 UTC,0,true +16546,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2bc88883ccc7e9cfa4af8ca05983336f2903d35000000000000000000000000a2bc88883ccc7e9cfa4af8ca05983336f2903d3500000000000000000000000000000000000000000000000000ad1fc8445fe90000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1a4cc4c730fb8421ab066d687a081c1faa0ec2831a7f8a1dc3e18a70a165ab1c,2022-03-14 01:40:21.000 UTC,0,true +16547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035fecc6d7ca3ce53e4eb3fbefda0681d664dd47a00000000000000000000000035fecc6d7ca3ce53e4eb3fbefda0681d664dd47a00000000000000000000000000000000000000000000000000a9a72343ebf07100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16548,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000438e269cef2262b56d936617e0798fc242670316000000000000000000000000438e269cef2262b56d936617e0798fc2426703160000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16549,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000009364c8d6ac5c00a585a0ecff16d0f73c336501cc0000000000000000000000009364c8d6ac5c00a585a0ecff16d0f73c336501cc0000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16550,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ad453a7eded500955784cc1be9b44ef8fbd7aa160000000000000000000000000000000000000000000000000de0b6b3a7640000,,,1,true +16551,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007c19d83f2661a3c5e0d3e175332e51d456a738a40000000000000000000000007c19d83f2661a3c5e0d3e175332e51d456a738a40000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e37b714cffa4e0d7418701fc1ce0f3d11e42dd6a000000000000000000000000e37b714cffa4e0d7418701fc1ce0f3d11e42dd6a000000000000000000000000000000000000000000000000029913d5c397543000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x14e32791a64223040581b3bbe35bbd94f49848944fbf2bf364dc5075dcbd6791,2021-11-21 11:50:59.000 UTC,0,true +16555,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d1e3f3f6673159721f064ddc0030fb1d9d3a464b000000000000000000000000d1e3f3f6673159721f064ddc0030fb1d9d3a464b0000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16557,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000d857dcb55d809cc60b28ccebd6e7f1c02e20b0e0000000000000000000000000d857dcb55d809cc60b28ccebd6e7f1c02e20b0e0000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000074ffa23f2c4e62ce68c4ed591a454472bfb1486200000000000000000000000074ffa23f2c4e62ce68c4ed591a454472bfb14862000000000000000000000000000000000000000000000000003f2f9dad7571a000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16559,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000288346fa5695bcf9fafbd617b2a4becd94da4a11000000000000000000000000288346fa5695bcf9fafbd617b2a4becd94da4a110000000000000000000000000000000000000000000000000e326d147539800000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000d5fd028115fbfcff0d4d546a542f6edff47da8cc000000000000000000000000d5fd028115fbfcff0d4d546a542f6edff47da8cc000000000000000000000000000000000000000000000000000000003b15697800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x45110db0bbf0f2ddc7d21d3d6650dbab2d86271aff34b3958f700a7357e4b20a,2021-11-26 07:42:07.000 UTC,0,true +16561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000027273a090d5e0a3ea65755b4073b53e0326bc76c00000000000000000000000027273a090d5e0a3ea65755b4073b53e0326bc76c000000000000000000000000000000000000000000000000027f56a6fb7be24300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16562,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f641f29fa14d753a2d1a623fd1b6a108bb099c89000000000000000000000000f641f29fa14d753a2d1a623fd1b6a108bb099c890000000000000000000000000000000000000000000000000eb5e06245ea000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000097503816d20243c45be7575b7e8073d563e7407c00000000000000000000000097503816d20243c45be7575b7e8073d563e7407c000000000000000000000000000000000000000000000000027f71d2f1eadaf600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16565,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008fbdc7f65515729a5a5c4f3456811599bf759f260000000000000000000000008fbdc7f65515729a5a5c4f3456811599bf759f2600000000000000000000000000000000000000000000000001a0eb308e6b7f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000004382672867e32f33e71f75689f4c2b5dcd347e000000000000000000000000004382672867e32f33e71f75689f4c2b5dcd347e00000000000000000000000000000000000000000000000002be41224e6017e900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16567,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000005a34e436a32357eb845f9770002958c4202cd0180000000000000000000000005a34e436a32357eb845f9770002958c4202cd018000000000000000000000000000000000000000000000000000000003ba96e0c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x854488f29855f4aed9679675379ad6f475f2b753bb9f3bd4f710a4ec32a435b9,2021-11-26 07:49:12.000 UTC,0,true +16568,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f0eba858b3ac74f1302695f87968acb3d42b6b02000000000000000000000000f0eba858b3ac74f1302695f87968acb3d42b6b020000000000000000000000000000000000000000000000000e92596fd629000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16569,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000022e524662e2bf804654517d40fa8124a8291953e00000000000000000000000022e524662e2bf804654517d40fa8124a8291953e000000000000000000000000000000000000000000000000000000003bc1f37100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x81e670ba95821d87cb427ecfdc26a0d064f6618725710199d5660172dd845a13,2021-11-26 07:57:24.000 UTC,0,true +16570,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000003ddf486383cc45c4074ab41b3c116ad1f9241e660000000000000000000000003ddf486383cc45c4074ab41b3c116ad1f9241e66000000000000000000000000000000000000000000000000000000003bc1639400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xba16561d6575be0d88f573c9de52b9a6b1bcad7889afa6926cf0dcb08cd75ac9,2021-11-26 08:13:09.000 UTC,0,true +16571,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000002b7bf82481f32fb20b0b99e751ba757c76f53dad0000000000000000000000002b7bf82481f32fb20b0b99e751ba757c76f53dad000000000000000000000000000000000000000000000000000000003baf69f600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x14eb889a0a1f061c7a43ffce423e1c812afcca7992ea97683b2e79acbe28b578,2021-11-26 08:17:40.000 UTC,0,true +16572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4cdcd9bfd5c11d0c9e1db05fe8706b99b822f7e000000000000000000000000a4cdcd9bfd5c11d0c9e1db05fe8706b99b822f7e00000000000000000000000000000000000000000000000000aa410173e4774d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16573,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000091b778d58c92cf61325f5dcc4a5e117a6bdc0d8500000000000000000000000091b778d58c92cf61325f5dcc4a5e117a6bdc0d85000000000000000000000000000000000000000000000000000000003bb7c01000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x48ed0caa0ba892a7a34b15f754664b6366cd259c874d63411dd35ea2ec556112,2021-11-26 08:30:30.000 UTC,0,true +16574,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000009867d2c7983aa2a163bb5837c9a9b5eb88d1a37b0000000000000000000000009867d2c7983aa2a163bb5837c9a9b5eb88d1a37b000000000000000000000000000000000000000000000000000000003bb72ba000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xd28b67bebb78ff76226993dfb6e646795a1d43a0c8fd2edef2ef9499e9e7eb56,2021-12-06 06:23:24.000 UTC,0,true +16575,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fe38aba75d5eb1a9b4bef00613ad225d8092d180000000000000000000000001fe38aba75d5eb1a9b4bef00613ad225d8092d18000000000000000000000000000000000000000000000000005d8c53afc1ba3000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16576,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000008a547c228fe1001ce8395d9820ac60d5de8c2bf80000000000000000000000008a547c228fe1001ce8395d9820ac60d5de8c2bf8000000000000000000000000000000000000000000000000000000003b9d2a9800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x2f1bf26c9c0781c6040a57fd49dbfec1432f08b44f8761b04f22fa59930054d7,2021-12-06 06:26:24.000 UTC,0,true +16577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007da91d7c55c818d06a7e405fbd719cea0310c43d0000000000000000000000007da91d7c55c818d06a7e405fbd719cea0310c43d000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16578,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000dd801247f030dcc38e839d04fa9dc82b0ac92c51000000000000000000000000dd801247f030dcc38e839d04fa9dc82b0ac92c51000000000000000000000000000000000000000000000000000000003ba1e13c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa9d809efe4ecd53eb60417ad580b364176d24892013cdb410d59146497d294ba,2021-12-06 06:28:29.000 UTC,0,true +16579,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000080afc7e083e81ce2aeb0ed17c15c6253a11ae49f00000000000000000000000080afc7e083e81ce2aeb0ed17c15c6253a11ae49f0000000000000000000000000000000000000000000000000efcee47256c000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16580,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000000d3a50bac8dd8b3c1b6d6a92a91c79a685a3800e0000000000000000000000000d3a50bac8dd8b3c1b6d6a92a91c79a685a3800e000000000000000000000000000000000000000000000000000000003bbf845800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa3808fe50fef32f956ee9e2ddb05e09ab8885ceef9307de4b49e26baebc857d2,2021-12-06 06:30:25.000 UTC,0,true +16581,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000276eb3c55a80b005432a88de569a8be1bc4b2ad7000000000000000000000000276eb3c55a80b005432a88de569a8be1bc4b2ad7000000000000000000000000000000000000000000000000000000003bb439b800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x6628874dacff3f28c3df69cff586bbb02fc7b3f2a1a81c435ae178743b2e6c14,2021-12-06 06:34:14.000 UTC,0,true +16582,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000004a6aafb11caf7e4c6d591707ffa421b0fbe4f2f20000000000000000000000004a6aafb11caf7e4c6d591707ffa421b0fbe4f2f20000000000000000000000000000000000000000000000000000000035cffbe200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x39e1d529c1d1b3eaa7997eb3376a3050ba182c016c0e10cba51bcc0a34039448,2021-12-06 06:37:12.000 UTC,0,true +16583,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000825dd5f32adc2df67ae4bf503ff3f348299578c2000000000000000000000000825dd5f32adc2df67ae4bf503ff3f348299578c20000000000000000000000000000000000000000000000000e609c82d34e000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16584,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000035c59a6e195dac739a51a74c52d6ae986eb8d27300000000000000000000000035c59a6e195dac739a51a74c52d6ae986eb8d2730000000000000000000000000000000000000000000000000e55f406e4fa800000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16585,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000eba34ce0cd07f2df484ce6f04c6f89b18a2a4760000000000000000000000000eba34ce0cd07f2df484ce6f04c6f89b18a2a476000000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000787c0764bfbb8bb191cc72425e859d7fed4ba050000000000000000000000000787c0764bfbb8bb191cc72425e859d7fed4ba0500000000000000000000000000000000000000000000000000057ef912bbd906f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16587,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000cf5c09df16f1c621f3c90af7d0d7b5d195980c44000000000000000000000000cf5c09df16f1c621f3c90af7d0d7b5d195980c440000000000000000000000000000000000000000000000000e5266884034000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16588,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b448d779599d13d599034ce158d998ecc81ca1ef000000000000000000000000b448d779599d13d599034ce158d998ecc81ca1ef00000000000000000000000000000000000000000000000000aad265f9ebc1a700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16589,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000fb5a64c43128962277cd202310ab6662b72722b2000000000000000000000000fb5a64c43128962277cd202310ab6662b72722b20000000000000000000000000000000000000000000000000e609c82d34e000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16591,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004477db1ec914ab90e20d9071cd760a5da47878f90000000000000000000000000000000000000000000000001a5e27eef13e0000,,,1,true +16593,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094ee763f9930ea718b9c131c58f20f227dc5279500000000000000000000000094ee763f9930ea718b9c131c58f20f227dc527950000000000000000000000000000000000000000000000000060f4dfcdd1285100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16594,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000000db7d61baf85ff477d683377ed140aa3af66039c0000000000000000000000000db7d61baf85ff477d683377ed140aa3af66039c000000000000000000000000000000000000000000000000000000001035464200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16595,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000834bd96881486ae605f3bac3595f7d635c6efd78000000000000000000000000834bd96881486ae605f3bac3595f7d635c6efd7800000000000000000000000000000000000000000000000000aa9fd30073452e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2bc76e4b70144c85578fc3e4f3fb6b7c012fc0acbfc607015134cdcec55dacfe,2021-12-20 13:02:43.000 UTC,0,true +16596,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c1f677a42909cccc0f50b4c85d82977281b0c0c0000000000000000000000001c1f677a42909cccc0f50b4c85d82977281b0c0c00000000000000000000000000000000000000000000000000003f9d3d5e370000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16597,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e81669100000000000000000000000041e8e159b4bc5375827c26ca2be353bae277bb0200000000000000000000000041e8e159b4bc5375827c26ca2be353bae277bb0200000000000000000000000000000000000000000000000021062d3080e719c100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16598,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000041e8e159b4bc5375827c26ca2be353bae277bb0200000000000000000000000041e8e159b4bc5375827c26ca2be353bae277bb02000000000000000000000000000000000000000000000000005347f3036c7fa800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16601,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000690dae9338ba55bffbd6e00e77c42d4fd1e04fe9000000000000000000000000690dae9338ba55bffbd6e00e77c42d4fd1e04fe90000000000000000000000000000000000000000000000000036386afea0910000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16602,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000543b32df9413874e8711fc71a40bd964fb322016000000000000000000000000543b32df9413874e8711fc71a40bd964fb32201600000000000000000000000000000000000000000000000000a90ec8b432590900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000d004846f7676672414f50b39bcfd39c283c870cc000000000000000000000000d004846f7676672414f50b39bcfd39c283c870cc00000000000000000000000000000000000000000000000545a4a94bcaffe19f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xda365c3530d52e127077394ee38c752cf4f9ea6298ec075490954cd012bc6195,2021-12-19 09:03:09.000 UTC,0,true +16611,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000274a18ef14d86d00f4a07e811d1dca3ff8b180a9000000000000000000000000274a18ef14d86d00f4a07e811d1dca3ff8b180a9000000000000000000000000000000000000000000000000000000002217182c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xcd3bc1f7a32a179cc2d70c23fbf7c4904d1e711603d20c7751be4d3ac7efcecc,2021-12-11 13:43:49.000 UTC,0,true +16612,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090066d6807ff44488331e7fa902fa50064c9785300000000000000000000000090066d6807ff44488331e7fa902fa50064c97853000000000000000000000000000000000000000000000000025ca5e83986ac8700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd1fb4cab680c3f30dc2e45b416e0450d0c0e93f000000000000000000000000fd1fb4cab680c3f30dc2e45b416e0450d0c0e93f0000000000000000000000000000000000000000000000000e720e9ec352d79500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x23a84e986640be1a661b81d00a6005c0662aae69363e30526e64c4c87d17f28e,2021-12-09 14:14:54.000 UTC,0,true +16617,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa8083a23e16f78a4b64e154ab76aca50e8a8635000000000000000000000000fa8083a23e16f78a4b64e154ab76aca50e8a8635000000000000000000000000000000000000000000000000002014073a68950000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16618,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a152b8488c89268d0e6f3b8e2217e2cbea87bb43000000000000000000000000a152b8488c89268d0e6f3b8e2217e2cbea87bb4300000000000000000000000000000000000000000000000001f4e9aae366df7400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcff929e2fe7aceb974ad77360a1c16aea57ba2fd7ef4cab04d208f9ba2b9463b,2021-12-18 18:11:48.000 UTC,0,true +16621,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d51e08e9518ef4eadf4df312ddad49e0f0febde0000000000000000000000000d51e08e9518ef4eadf4df312ddad49e0f0febde000000000000000000000000000000000000000000000000001f46daf7ed9f74b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xfa496664a66da62964ad90f49f76bc02947d6b38db01f777c7c50293498ddf25,2022-04-23 15:16:35.000 UTC,0,true +16622,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d812b38e4dffb92b21aba2338b529b72af6378e0000000000000000000000001d812b38e4dffb92b21aba2338b529b72af6378e00000000000000000000000000000000000000000000000002821e82d99220d500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e03a816fd580cbc6956027440d038041918b45b7000000000000000000000000e03a816fd580cbc6956027440d038041918b45b70000000000000000000000000000000000000000000000000005bfa98481f38b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16624,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb4620765165432b84130624e52b15dc209476c4000000000000000000000000cb4620765165432b84130624e52b15dc209476c400000000000000000000000000000000000000000000000000d43a002bb3354500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d8b62078a5b6219532a9a5f68cdb7cffaad07e9f000000000000000000000000d8b62078a5b6219532a9a5f68cdb7cffaad07e9f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ecc3be441d6ac9e977a36079014b4c920eb39585000000000000000000000000ecc3be441d6ac9e977a36079014b4c920eb39585000000000000000000000000000000000000000000000000022ae5ed018153bd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x88729d324d0bac13c16a0cb816088a67fbdfedd5e86fd2ff6459530b76b9475d,2021-12-18 18:11:48.000 UTC,0,true +16627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d42a2fdea3714a15ffdf86ea3873e05d79838500000000000000000000000000d42a2fdea3714a15ffdf86ea3873e05d7983850000000000000000000000000000000000000000000000000024f8b00d610eb0a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x83bd91bccf410ebf8e6f2a50cea3a8169d331bc37ed5883d2e4bcd15156c7beb,2021-12-18 18:10:02.000 UTC,0,true +16628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000088977418747bbf018f1e8b38c94b9d4619e509f800000000000000000000000088977418747bbf018f1e8b38c94b9d4619e509f8000000000000000000000000000000000000000000000000027340ce1a4b8d0200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7bb5d6a7a67d317b070901246920531533376af6121e212a0e7422c59f34792f,2021-12-18 18:07:42.000 UTC,0,true +16629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c9a03e2d7d169bf07e29cd2ee0452f1900099bd0000000000000000000000008c9a03e2d7d169bf07e29cd2ee0452f1900099bd00000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x24a260280e5906e493125926907a89dc5e4ae226915b60879597a1c406ad512b,2021-12-18 18:07:40.000 UTC,0,true +16630,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c9a03e2d7d169bf07e29cd2ee0452f1900099bd0000000000000000000000008c9a03e2d7d169bf07e29cd2ee0452f1900099bd00000000000000000000000000000000000000000000000000669adac7e9720000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xeb85c0720b35459749ef53b6f1f91a74123e848003a6384072531633c2e56a92,2021-12-18 18:05:31.000 UTC,0,true +16631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009376569d21c11cf0b794a1738276fc6af3b26bba0000000000000000000000009376569d21c11cf0b794a1738276fc6af3b26bba00000000000000000000000000000000000000000000000002b9a4538e9ba12900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd97025d06fe7db62d33a6a71c57df47c28b2a2766fc3c55d68a2abdecafdc9ac,2021-12-18 18:01:28.000 UTC,0,true +16632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087e8e70b6651cba5c7ab8a3cc808086437ccfda300000000000000000000000087e8e70b6651cba5c7ab8a3cc808086437ccfda300000000000000000000000000000000000000000000000002d9bb35da8c290c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6c6f9863b25c1d39ad836810bfc0ab17e0535cb05063c4acbd52aed4f17005f9,2021-12-18 18:07:40.000 UTC,0,true +16633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ce440d67394a858a69d8aa720c65d2bb769d5fe0000000000000000000000006ce440d67394a858a69d8aa720c65d2bb769d5fe0000000000000000000000000000000000000000000000000301b1338844df3200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9eb8640f521252e355cad9e347484832015c31a56604c144074eb81ec9064e6e,2021-12-18 18:00:30.000 UTC,0,true +16634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000876c06abb421abda10bdcc11c391e3c9ffa910b6000000000000000000000000876c06abb421abda10bdcc11c391e3c9ffa910b6000000000000000000000000000000000000000000000000032678de5cd749fe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2cc28b524f87886666ffacc61f832bf1ec1bcfdd7165094e954b726bbf4b2a1a,2021-12-18 17:59:41.000 UTC,0,true +16635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b82eb6c935525b961c31cd7ae3974c27b95b6f7f000000000000000000000000b82eb6c935525b961c31cd7ae3974c27b95b6f7f00000000000000000000000000000000000000000000000003016562ba5e289e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8a66141421c78484b401585e18ecd0c5a20a754742b0b14f910ce393cfefa20b,2021-12-18 17:59:06.000 UTC,0,true +16636,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c29f4f7427313ec1faa6a82c972aa93a4e5e719c000000000000000000000000c29f4f7427313ec1faa6a82c972aa93a4e5e719c000000000000000000000000000000000000000000000000036c9e868696ea0d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7e9b3b6d378bc96fc0820330059b6a169dc32878830ec03afce4ecc5ee200473,2021-12-18 17:56:57.000 UTC,0,true +16637,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000832c238cee46cd0e763b48c234f06bfba551335c000000000000000000000000832c238cee46cd0e763b48c234f06bfba551335c0000000000000000000000000000000000000000000000000207444a9afa1a9300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xfb35b38e690f5eec941d1ab6c938829e3be9c7b0803cbc4a40cbb1f5aa19fcee,2021-12-18 17:56:43.000 UTC,0,true +16638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aba877ffb70502dbe16b2241dccb4428b192d1dc000000000000000000000000aba877ffb70502dbe16b2241dccb4428b192d1dc0000000000000000000000000000000000000000000000000048988ef1bd32ba00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3f120134b6e3606d5e414d7b786ac95f61fb50c1e73719010a6a6bade1f099b0,2022-05-18 07:30:56.000 UTC,0,true +16640,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000264ba3fa47bd6c10536b8ef801109a84ab70b6fc000000000000000000000000264ba3fa47bd6c10536b8ef801109a84ab70b6fc000000000000000000000000000000000000000000000000022b54905e57736e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x02de9d87f164c5e2328354a7510abdf09866764de44d48184966917ae3f2143b,2021-12-18 18:04:08.000 UTC,0,true +16641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000567b1c49e7ab1435ccecd62459d8d1c5fa4356c3000000000000000000000000567b1c49e7ab1435ccecd62459d8d1c5fa4356c3000000000000000000000000000000000000000000000000022caf3a77a01da800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0145affcdcac6aeb446a62a23cf60a82b3672646d31a663a5195f19a2caa07b8,2021-12-18 17:57:50.000 UTC,0,true +16642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003aa68ac4765f1112611b598e59b2f3da624fbe600000000000000000000000003aa68ac4765f1112611b598e59b2f3da624fbe6000000000000000000000000000000000000000000000000002526a89d2fb598900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x69e8bb94786c7cae651c52874d57c302f222c2827836752d10b6f89154482c6d,2021-12-18 17:47:55.000 UTC,0,true +16643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ab77f357dcb26fb296bd4f8a757d3ec3f015a410000000000000000000000002ab77f357dcb26fb296bd4f8a757d3ec3f015a410000000000000000000000000000000000000000000000000250c56498eac5f800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6c172c02b0baa2e6cf0e22558fbff6f07e211b48c2c93167e8a1b70688fd72c9,2021-12-18 17:46:36.000 UTC,0,true +16644,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001606cd117e229d2a6c97c0b33382c5a75932b9e30000000000000000000000001606cd117e229d2a6c97c0b33382c5a75932b9e3000000000000000000000000000000000000000000000000022d77876d8909a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3107c8ebcecb27ea7c3c615ef3b20104eb99f17e6592de7721b8373f5a2a91e7,2021-12-18 17:46:26.000 UTC,0,true +16645,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000465dca9995d6c2a81a9be80fbced5a770dee3dae000000000000000000000000465dca9995d6c2a81a9be80fbced5a770dee3dae000000000000000000000000000000000000000000000000035d8b7c89e60d2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16647,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd244e565d07f2247ec8e2ff8bea7d7f5182566a000000000000000000000000bd244e565d07f2247ec8e2ff8bea7d7f5182566a0000000000000000000000000000000000000000000000000273c7a4c0ad1df400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4b5da98a1176d85257d650f0e4878c8530f065d39bc8cdfd6de466009504daf3,2021-12-18 17:46:26.000 UTC,0,true +16648,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000375c42839d55b5c2fb51688e737d7645468c9b95000000000000000000000000375c42839d55b5c2fb51688e737d7645468c9b9500000000000000000000000000000000000000000000000002b8e81fc4627f3b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf448395b5a95893ccd9b6fb97e990cab4136310933903f86a6d50666fe68e558,2021-12-18 17:44:29.000 UTC,0,true +16649,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b167f0c11d6813240099c9fbe32983d9a01078e0000000000000000000000001b167f0c11d6813240099c9fbe32983d9a01078e0000000000000000000000000000000000000000000000000300bc138126f0fc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x27e6088ba4f60ffe4cb5d43143f39fecb14bb70c1589513b5fba5fb0769763a2,2021-12-18 17:39:56.000 UTC,0,true +16650,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008deeaa63b610bd4cf0bb54e11d5b8258d25267660000000000000000000000008deeaa63b610bd4cf0bb54e11d5b8258d252676600000000000000000000000000000000000000000000000001635e52cf283e6700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16651,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003e65612bb2ba3d98e3a4728e22fe4740237da3400000000000000000000000003e65612bb2ba3d98e3a4728e22fe4740237da3400000000000000000000000000000000000000000000000003273d20490ebcd000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x191956bc5cf0f7261f0ccce841d935626d70e50aef3e3b66195fd69de95bb827,2021-12-18 17:38:33.000 UTC,0,true +16652,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000514040cf6b5c0fb7a5e245a0e628867ae675ae25000000000000000000000000514040cf6b5c0fb7a5e245a0e628867ae675ae250000000000000000000000000000000000000000000000000349cda3dabcece700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3bb5ce5ecc4bb2f56c71615682e75bf7cd0b6d163b028e41eb6166ba69e23bcc,2021-12-18 17:37:53.000 UTC,0,true +16653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000584b1c4db87c222bd7ff3b8fdeef337b1e8cf416000000000000000000000000584b1c4db87c222bd7ff3b8fdeef337b1e8cf41600000000000000000000000000000000000000000000000003253e3dbab0721e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x79e32123604dca1506b8a31a77bed15c5d54a18b159ebbd6f1c138654348a7fa,2021-12-18 17:35:00.000 UTC,0,true +16654,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005638fe6b8fb55b2fc9a2ccc25a95404bd6b397350000000000000000000000005638fe6b8fb55b2fc9a2ccc25a95404bd6b3973500000000000000000000000000000000000000000000000003253e3dbab0721e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4b4eba740f3a560c256d63db7f8b55646c68b0581536b13f68ed17addfbcfafe,2021-12-18 17:27:28.000 UTC,0,true +16655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f08a9f930dcf9606facdaf6be404b0f3b11ca520000000000000000000000007f08a9f930dcf9606facdaf6be404b0f3b11ca5200000000000000000000000000000000000000000000000002505abd83c4d5df00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4cb1fa15370bb80179e9ca9412e47efadd49aabbe817f66be6f5381d745b4156,2021-12-18 17:19:20.000 UTC,0,true +16656,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000594cb92be8f6153cf00f6500d6655397d1eefd39000000000000000000000000594cb92be8f6153cf00f6500d6655397d1eefd390000000000000000000000000000000000000000000000000207b2b618424e8300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x12bc6113da5ee90bcca55f4dc6ba76fc93bf41c40f4ef00766145f23e17ba1af,2021-12-18 00:35:49.000 UTC,0,true +16657,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e1061be8f7590a2601ff3db6a16c4e7d41a9bd5c000000000000000000000000e1061be8f7590a2601ff3db6a16c4e7d41a9bd5c000000000000000000000000000000000000000000000303a13bd93eb18ace9a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x3c3be6a741e45538809733683e255200d6c72f4bcff939f11cd70de0f2168ae0,2021-12-17 00:22:04.000 UTC,0,true +16658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbd140bf147bd4a38f6fa1f7bdfc6e35b7df9837000000000000000000000000fbd140bf147bd4a38f6fa1f7bdfc6e35b7df9837000000000000000000000000000000000000000000000000017c17d5472564ea00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8645611523e6b4dfd4218b9172bdd2fe4eb12f5e715493f136a14a00c0195000,2021-12-10 07:45:19.000 UTC,0,true +16659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cc927f4a57dbd8cc29f2cb72c962ef5c5b0f6c20000000000000000000000007cc927f4a57dbd8cc29f2cb72c962ef5c5b0f6c200000000000000000000000000000000000000000000000000a4465becb9f2aa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16661,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063e3213987ebce0517b6c6577534dcfa2e08c76c00000000000000000000000063e3213987ebce0517b6c6577534dcfa2e08c76c0000000000000000000000000000000000000000000000000128f55f405540a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xde2fef190b6b506fc802f3dc007189691272f954eedbf9810abafefb31978ccd,2021-12-10 14:00:49.000 UTC,0,true +16664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069b49d9e84fa10548e432b7bb055e70324502f9a00000000000000000000000069b49d9e84fa10548e432b7bb055e70324502f9a00000000000000000000000000000000000000000000000000e90b3ea9fa84b700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000358c84faa7f860ab41b93edccb7e64f7eb330bb1000000000000000000000000358c84faa7f860ab41b93edccb7e64f7eb330bb100000000000000000000000000000000000000000000000006e5193f899d6d7d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16666,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b4b04564f56f4795ea4e14d566af78da54a9998000000000000000000000000000000000000000000000001b0e86716a08449cff,,,1,true +16667,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8f09b8d61dfa68389990b247c49101c9514d6d6000000000000000000000000b8f09b8d61dfa68389990b247c49101c9514d6d60000000000000000000000000000000000000000000000000049deca74ae260200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000669a5e73ab710b7a2e5e060a3726f046f4e7b491000000000000000000000000669a5e73ab710b7a2e5e060a3726f046f4e7b491000000000000000000000000000000000000000000000000004d1869dbeb8ac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16670,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016957feb799ee6c8c4c97d37da5be553ec0039b600000000000000000000000016957feb799ee6c8c4c97d37da5be553ec0039b60000000000000000000000000000000000000000000000000e682ef66420e24d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3a4f30764421d14d5a18e140588ce6b29be216b6d2e1afe0fa0f823fbb9ab0eb,2022-08-17 10:34:02.000 UTC,0,true +16674,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2e8fee9ac2af4352a0e424650b77da25c36bf80000000000000000000000000e2e8fee9ac2af4352a0e424650b77da25c36bf80000000000000000000000000000000000000000000000000026df4ea282c3c1d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8a95dca20df3911ef75736f1a0ddf539afedd19de01516b3666bd09a192dc60d,2021-12-27 02:07:20.000 UTC,0,true +16675,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021a8529a0180fb36037599c375bb37ac765359bd00000000000000000000000021a8529a0180fb36037599c375bb37ac765359bd0000000000000000000000000000000000000000000000000c0e7d8e6b7007a500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16677,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cbad01980e700fbf6bea01b3c25adcd25c22e4b2000000000000000000000000cbad01980e700fbf6bea01b3c25adcd25c22e4b2000000000000000000000000000000000000000000000000002d87d711a62c0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fdf05e7f3e9cd329fc58a08ed88e641d083d4a9f000000000000000000000000fdf05e7f3e9cd329fc58a08ed88e641d083d4a9f0000000000000000000000000000000000000000000000000ab8ba1861f2d8c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16682,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fd5250977d6d6b48789aea0cff78580796336bf2000000000000000000000000fd5250977d6d6b48789aea0cff78580796336bf2000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x8d774f2fa010aaa5d0ce94bff1e6b70c6a482f91687eed85b257049fb81e5b19,2022-05-30 01:09:16.000 UTC,0,true +16683,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5cb6552fd6561e3e4197020a4c941ebdd6876f6000000000000000000000000e5cb6552fd6561e3e4197020a4c941ebdd6876f600000000000000000000000000000000000000000000000001ff4dbbffde6b6000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000baa738690c4e617f64c00fcbdb2ee69281d5da80000000000000000000000000baa738690c4e617f64c00fcbdb2ee69281d5da80000000000000000000000000000000000000000000000000032ea341ea4a6f0300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a9ce001353e021767264f5ab6102e65bc9cd2023000000000000000000000000a9ce001353e021767264f5ab6102e65bc9cd20230000000000000000000000000000000000000000000000000013d5d5cc2d801200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16688,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000469a04b76f03bbafc5ffc31c9e5a53ebab745fde000000000000000000000000469a04b76f03bbafc5ffc31c9e5a53ebab745fde0000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16689,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000071c3c6df5f834a55e6edd4b5aa768990d2c5034d00000000000000000000000071c3c6df5f834a55e6edd4b5aa768990d2c5034d0000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16690,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007ff9fa40aaadcc91374e69d4222fef34e7d644710000000000000000000000007ff9fa40aaadcc91374e69d4222fef34e7d644710000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16691,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000005ac2371763dfc1b67b009b58e93f4a55779e50dd0000000000000000000000005ac2371763dfc1b67b009b58e93f4a55779e50dd0000000000000000000000000000000000000000000000000e47be0c51e0800000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16692,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000f298f2c578d25f9f59b03c6d0cb3725b42da7070000000000000000000000000f298f2c578d25f9f59b03c6d0cb3725b42da7070000000000000000000000000000000000000000000000000e92596fd629000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16693,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005811bedd2cbde3f040cbf875fd3cd7ef2bc7878f0000000000000000000000005811bedd2cbde3f040cbf875fd3cd7ef2bc7878f00000000000000000000000000000000000000000000000000b3329905396a2200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16694,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e2f37ceaeff9549597fcbdadaf3e3545d1b0e0eb000000000000000000000000e2f37ceaeff9549597fcbdadaf3e3545d1b0e0eb0000000000000000000000000000000000000000000000000e6ed27d6668000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16695,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004770cbf93bb7e113abdfdcf8ab71134f018b5d750000000000000000000000004770cbf93bb7e113abdfdcf8ab71134f018b5d7500000000000000000000000000000000000000000000000001143514dbdef79300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x47e866afa67f7b20b7958a6c82728270c78ed9178f51eec79d2abd8b1449fcbc,2021-11-28 10:08:58.000 UTC,0,true +16696,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000005811bedd2cbde3f040cbf875fd3cd7ef2bc7878f0000000000000000000000005811bedd2cbde3f040cbf875fd3cd7ef2bc7878f000000000000000000000000000000000000000000000000000000000e483be700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fa2ae7a2b9afea302839429a4307effe00f72d55000000000000000000000000fa2ae7a2b9afea302839429a4307effe00f72d550000000000000000000000000000000000000000000000000f0607ad232f864a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000005fb2a7793a08de719b0b750fb2961f1281d893a50000000000000000000000005fb2a7793a08de719b0b750fb2961f1281d893a5000000000000000000000000000000000000000000000000000000002fd6f7fe00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16699,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e0012884cc3b4d6fe361dced4b748f53dc5c6fe0000000000000000000000001e0012884cc3b4d6fe361dced4b748f53dc5c6fe000000000000000000000000000000000000000000000000023fcb98613088fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb3f055c45ee86955b2b659587223f5124dabb1483115ef2bb0293645c40f21f9,2021-12-12 10:07:29.000 UTC,0,true +16700,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9e52a623a6a19f16bde2cd0aa16df7bc2acc1ee000000000000000000000000c9e52a623a6a19f16bde2cd0aa16df7bc2acc1ee00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16701,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9e52a623a6a19f16bde2cd0aa16df7bc2acc1ee000000000000000000000000c9e52a623a6a19f16bde2cd0aa16df7bc2acc1ee00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9e52a623a6a19f16bde2cd0aa16df7bc2acc1ee000000000000000000000000c9e52a623a6a19f16bde2cd0aa16df7bc2acc1ee00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16703,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a13436984309295e093ccda722680befdc2a3de0000000000000000000000009a13436984309295e093ccda722680befdc2a3de00000000000000000000000000000000000000000000000000aa0294bdf7c1f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c9e52a623a6a19f16bde2cd0aa16df7bc2acc1ee000000000000000000000000c9e52a623a6a19f16bde2cd0aa16df7bc2acc1ee00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abf48bbcb7816c4a89362537ae6719b62f8885e4000000000000000000000000abf48bbcb7816c4a89362537ae6719b62f8885e400000000000000000000000000000000000000000000000002fc35846d77e2b100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x51f39d0df7a0d5b43e2befb3862d3fa724a1c0e210de44defb6678c1c4b3894c,2022-01-24 19:51:49.000 UTC,0,true +16709,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000261f1a7031f27e55b8a89bfca26a625eb4036694000000000000000000000000261f1a7031f27e55b8a89bfca26a625eb4036694000000000000000000000000000000000000000000000000013875b27dd1001e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16710,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ddbcb5be8b445a60c15380137e6f7d6ef4689190000000000000000000000007ddbcb5be8b445a60c15380137e6f7d6ef46891900000000000000000000000000000000000000000000000000cc90b4762ac00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16712,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001f4c2e01760fc3dca50aba4b1bdca066592c57af0000000000000000000000001f4c2e01760fc3dca50aba4b1bdca066592c57af0000000000000000000000000000000000000000000000000257af48694d667f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3b5380d46c626a38900680296ed9401e9ba2eb425955f084ceea18f930d3ac51,2021-11-21 07:11:26.000 UTC,0,true +16714,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000001f4c2e01760fc3dca50aba4b1bdca066592c57af0000000000000000000000001f4c2e01760fc3dca50aba4b1bdca066592c57af000000000000000000000000000000000000000000000014574994cdeafbf67000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x171833b83beb73806731096ab04b1af6fe8702254447a816cf4561836bfcedf6,2021-11-21 07:14:35.000 UTC,0,true +16715,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007cea25d6a18abf648ef0bc70ad70c962b87564c40000000000000000000000007cea25d6a18abf648ef0bc70ad70c962b87564c400000000000000000000000000000000000000000000000003d890fa19610fb600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7bcbb0c1e1aeffb9b46c9a244f26f2fd6e1b4ae68c63aae40b7817d07f5783be,2021-11-24 11:52:33.000 UTC,0,true +16717,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a2e7d7abb825e77015a639f9d867117bd43a7c00000000000000000000000000a2e7d7abb825e77015a639f9d867117bd43a7c0000000000000000000000000000000000000000000000000000abe684e8226f2800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16718,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c7996f170cdeeae270f13d58e3e0d0ae1b9f3880000000000000000000000002c7996f170cdeeae270f13d58e3e0d0ae1b9f38800000000000000000000000000000000000000000000000001a2caf43939d9ba00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16719,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0e1a32409cb788797035885d580a9493d346f5d000000000000000000000000c0e1a32409cb788797035885d580a9493d346f5d000000000000000000000000000000000000000000000000007303d28656748b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16720,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000978482015863de289a738cd9fa44ffa9a71156d1000000000000000000000000978482015863de289a738cd9fa44ffa9a71156d100000000000000000000000000000000000000000000000000488dc571d991ad00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16723,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000311febd2efbe8d2b2646d708dfba70a2e6fae030000000000000000000000000311febd2efbe8d2b2646d708dfba70a2e6fae0300000000000000000000000000000000000000000000000000e27c49886e6000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16724,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abfd99a7da59e8b96f1cefa6e35fd03e6831bc10000000000000000000000000abfd99a7da59e8b96f1cefa6e35fd03e6831bc1000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16725,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000008508cabb156b0624b3c3be004709c8890080b56b0000000000000000000000008508cabb156b0624b3c3be004709c8890080b56b0000000000000000000000000000000000000000000000000e043da61725000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16726,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000d2df0d14a20bfa3be92ba9b694de41b0bf3a6287000000000000000000000000d2df0d14a20bfa3be92ba9b694de41b0bf3a62870000000000000000000000000000000000000000000000000e043da61725000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16727,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000002766c7a52e9cdb67372fa8b7139de9da8c63bdd70000000000000000000000002766c7a52e9cdb67372fa8b7139de9da8c63bdd70000000000000000000000000000000000000000000000000e4b4b8af6a7000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3e7e79fdd91565fe0f16303377d87ef2b8e811d000000000000000000000000b3e7e79fdd91565fe0f16303377d87ef2b8e811d00000000000000000000000000000000000000000000000000b05a53b960f50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b00e4bbe8656c98a4d95f18c2f381e86da94243f000000000000000000000000b00e4bbe8656c98a4d95f18c2f381e86da94243f00000000000000000000000000000000000000000000000000a52234d99d98fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x00ebb490ccefd3d2077d287c966e643ac919176837b62ce94c2a4bd9653e80ec,2022-08-14 12:46:07.000 UTC,0,true +16734,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000032d2f9e5f38ac0459cb5a3c22374f1d826b1d7f000000000000000000000000032d2f9e5f38ac0459cb5a3c22374f1d826b1d7f000000000000000000000000000000000000000000000000003305efc166e4ee00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16735,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3f3b7a78410e1d0214e9e704b0fa4d7145ff248000000000000000000000000b3f3b7a78410e1d0214e9e704b0fa4d7145ff24800000000000000000000000000000000000000000000000000ababec6b154e1e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16736,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd41805c022e23daa5703159f7439213ff57d243000000000000000000000000bd41805c022e23daa5703159f7439213ff57d24300000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16737,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000797d27a0a90bf878350f6cb80c50f09598246ab9000000000000000000000000797d27a0a90bf878350f6cb80c50f09598246ab90000000000000000000000000000000000000000000000000006e62275544f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a4f2ade0bc540edee69d3324abfe049655480c91000000000000000000000000a4f2ade0bc540edee69d3324abfe049655480c91000000000000000000000000000000000000000000000000003ccaf32149fcc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xac36c877e38cbb70f346a8984ce6aa2d4ff7d9959d6872efe182753499655ec4,2021-12-11 11:35:47.000 UTC,0,true +16740,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e5c37b43eaad5bcc72e0d5c42cb32a5f3edb048b00000000000000000000000000000000000000000000001c7f25062bfb730903,0xdb01c388f0b6ecee37197800056d31ba9fe494deff3745265f5aace678bd1605,2021-11-24 12:35:42.000 UTC,0,true +16744,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a41ad7e5556125d39fdd17a2846a731ffaa6f5fa000000000000000000000000a41ad7e5556125d39fdd17a2846a731ffaa6f5fa0000000000000000000000000000000000000000000000000024c66e40a11a8800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16745,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003ce5261982fab4890176255b867ae9cdab4bab700000000000000000000000003ce5261982fab4890176255b867ae9cdab4bab7000000000000000000000000000000000000000000000000000552dc947854b0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16746,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000005ec259773b76b215ac0fca91723445e002fa8e360000000000000000000000005ec259773b76b215ac0fca91723445e002fa8e3600000000000000000000000000000000000000000000000000000000020c5f1000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000618e09582b5f03b1fa2785ddce71b7d96b75017c000000000000000000000000618e09582b5f03b1fa2785ddce71b7d96b75017c00000000000000000000000000000000000000000000000002a303fe4b53000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16751,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000021b9d16971a7dee4102689864f8ff9381943458c00000000000000000000000021b9d16971a7dee4102689864f8ff9381943458c000000000000000000000000000000000000000000000000200cec774738658000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x989622b4617cdc88a083e5c8445844f8b1789e71b8c8746c943e6bc8b427add1,2021-11-29 21:37:42.000 UTC,0,true +16752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007bcec44c7486143ee875103de66006047cae8df70000000000000000000000007bcec44c7486143ee875103de66006047cae8df700000000000000000000000000000000000000000000000000a7ef8e0df5851b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16754,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0b6b2e2d7d8e687d06ffded2632160377ee1f68000000000000000000000000b0b6b2e2d7d8e687d06ffded2632160377ee1f680000000000000000000000000000000000000000000000000392cba7145d7bfa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16755,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b47f89c3ffa2adb6d539746589820695046e01b9000000000000000000000000b47f89c3ffa2adb6d539746589820695046e01b9000000000000000000000000000000000000000000000000004e3a828ac8b50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16758,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004778b055dfed8f46a2966619f3d8291cf0c706680000000000000000000000004778b055dfed8f46a2966619f3d8291cf0c70668000000000000000000000000000000000000000000000000005281f0c6e777b600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16759,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a90ed84161e6a7c565de94e825e2b2a874e70e50000000000000000000000000a90ed84161e6a7c565de94e825e2b2a874e70e50000000000000000000000000000000000000000000000000ca99104766880cc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2698cee79c9b71c8e64b68d54423ccbf39d97383b32bbddde82587c05058b4df,2021-11-27 21:39:51.000 UTC,0,true +16760,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3f672982f319f1a141bd9ee91aa186126e43bab000000000000000000000000b3f672982f319f1a141bd9ee91aa186126e43bab0000000000000000000000000000000000000000000000000078292d7ff0f37300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16761,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015f8745b5f315d56403ecba5724cc222b9f271b300000000000000000000000015f8745b5f315d56403ecba5724cc222b9f271b300000000000000000000000000000000000000000000000000010e14d2e3f44000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16762,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000343a7316f1681cff3171438b8c7aa0e0e828b097000000000000000000000000343a7316f1681cff3171438b8c7aa0e0e828b0970000000000000000000000000000000000000000000000000017d6fa4b8c508000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008656eacc5ba829549f005da59d8040f1d73d2df90000000000000000000000008656eacc5ba829549f005da59d8040f1d73d2df9000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab3fcb1dac9e0eae480c49a832914a230d265a3e000000000000000000000000ab3fcb1dac9e0eae480c49a832914a230d265a3e00000000000000000000000000000000000000000000000000574d68931e147700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16771,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000080db58cc6b8a5818bbba36177010330fbf9af62b00000000000000000000000080db58cc6b8a5818bbba36177010330fbf9af62b00000000000000000000000000000000000000000000004737c65fa2b4e96e9a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x9f7adc981bd7c28669fe4b23caf78c2e35924b8f1268c347816636760bbda89d,2022-05-16 01:38:33.000 UTC,0,true +16772,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c73da5668d34972fb210d3bb1fe7592e5716959e000000000000000000000000c73da5668d34972fb210d3bb1fe7592e5716959e0000000000000000000000000000000000000000000000000ccd62399ee926f400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x148c1470a9b40199624f9fe5116bd17849bf493f64774ddc5828f02e8f984335,2021-11-23 10:20:34.000 UTC,0,true +16773,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000659ba0b652fb66bb6c1261f5d0aeaeb30fcfec35000000000000000000000000659ba0b652fb66bb6c1261f5d0aeaeb30fcfec350000000000000000000000000000000000000000000000000855a6b44930182500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16774,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0bd4b75dc06c7f1860d6f123103404d3f1a1c93000000000000000000000000a0bd4b75dc06c7f1860d6f123103404d3f1a1c930000000000000000000000000000000000000000000000000054dad1bb2cf1c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16775,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000077ee282ab43cc815c12a33a18186c4c37e1ef3ea00000000000000000000000077ee282ab43cc815c12a33a18186c4c37e1ef3ea0000000000000000000000000000000000000000000000000000000027ddf1d300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16777,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e0508e801cf6fca1c302495f91d47af582b6f090000000000000000000000000e0508e801cf6fca1c302495f91d47af582b6f0900000000000000000000000000000000000000000000000000947e91965ae5f100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16779,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c4b10eb0af780a6fd3f2b7ee2deca81a2e3befe0000000000000000000000008c4b10eb0af780a6fd3f2b7ee2deca81a2e3befe0000000000000000000000000000000000000000000000000000f5904616e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16780,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ee00c54b0fa1b4eaf41685db0f8dbf95b0d7437d000000000000000000000000ee00c54b0fa1b4eaf41685db0f8dbf95b0d7437d0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16782,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c36909271002ce677ad2f71a68704aeda2d3b3dd000000000000000000000000c36909271002ce677ad2f71a68704aeda2d3b3dd0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16783,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000537449d7e9011ed8ecfefc611850cdcb5d41a3b6000000000000000000000000537449d7e9011ed8ecfefc611850cdcb5d41a3b600000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16784,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099a409fc717ec84acb7d48bff1fd9981190d46ab00000000000000000000000099a409fc717ec84acb7d48bff1fd9981190d46ab0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16786,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b5b89f599b4a8859f4ca3f034e7affda6d08d8b0000000000000000000000000b5b89f599b4a8859f4ca3f034e7affda6d08d8b000000000000000000000000000000000000000000000000008c24a91f423f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16787,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006177c71d568960d87e958c38000350ed3276796b0000000000000000000000006177c71d568960d87e958c38000350ed3276796b000000000000000000000000000000000000000000000000028bc9c6b592c12800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16788,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f763c31379b7a717de8fef568600f84c407c7e00000000000000000000000003f763c31379b7a717de8fef568600f84c407c7e00000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16789,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ff05ce30fe57bff365a03fcc96e401bd42c97900000000000000000000000000ff05ce30fe57bff365a03fcc96e401bd42c97900000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16790,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000040e5a0d553140989460511fe948c38689e791ded00000000000000000000000040e5a0d553140989460511fe948c38689e791ded0000000000000000000000000000000000000000000000000000eaa64e5a200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16791,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000224de5157760bf46ef3981d8eb1beebea73b2114000000000000000000000000224de5157760bf46ef3981d8eb1beebea73b21140000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16792,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000005a513898b701c865091317e855cd8781304b781e0000000000000000000000005a513898b701c865091317e855cd8781304b781e0000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16793,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005a513898b701c865091317e855cd8781304b781e0000000000000000000000005a513898b701c865091317e855cd8781304b781e00000000000000000000000000000000000000000000000000e1b93fb703856100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16794,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001bf97cdadbdd6bc93f8bed9dd9f93d5818780bfa0000000000000000000000001bf97cdadbdd6bc93f8bed9dd9f93d5818780bfa0000000000000000000000000000000000000000000000000000e7ebd06af00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16795,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006a177b1ec0c5e6324a586c3205b598466be5c2aa0000000000000000000000006a177b1ec0c5e6324a586c3205b598466be5c2aa0000000000000000000000000000000000000000000000000000e7ebd06af00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16796,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f8465260550f027511d8552a0f425ae66d055360000000000000000000000007f8465260550f027511d8552a0f425ae66d0553600000000000000000000000000000000000000000000000000a7d2e38172baa500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16797,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061a1353d6ac8cf95918545a63455557a55e5f82400000000000000000000000061a1353d6ac8cf95918545a63455557a55e5f8240000000000000000000000000000000000000000000000000000e8d4a510000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16798,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bcd44ca0238940129f6d4e13af10ce1ba8d6c9b8000000000000000000000000000000000000000000000000b36ae3a8acf1a5f7,,,1,true +16799,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc8a9cb6bdbad13a07d2fe70f2bda8a66a79811d000000000000000000000000bc8a9cb6bdbad13a07d2fe70f2bda8a66a79811d0000000000000000000000000000000000000000000000000000e8d4a510000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16800,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061be9402542ae211ef6b9476e7238d5f3331589f00000000000000000000000061be9402542ae211ef6b9476e7238d5f3331589f00000000000000000000000000000000000000000000000002a5b9a1fddaaf7d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xda58c252833426fbdc6a67a4b603f2b132c825faab15c402c762852841338527,2021-12-13 06:09:17.000 UTC,0,true +16801,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009d70e1c5d4e01c6716565088d36a4e70370c25860000000000000000000000009d70e1c5d4e01c6716565088d36a4e70370c2586000000000000000000000000000000000000000000000000017a728abcb29a2700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16802,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4fb48b7ba32babc400d078c73feda2593434fe3000000000000000000000000c4fb48b7ba32babc400d078c73feda2593434fe300000000000000000000000000000000000000000000000000bd022a386ac7ba00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe9d7b2ae14536c6469ffa2733c5544c633cfad9f32a9e36255e92adb526e1b96,2021-12-10 12:33:19.000 UTC,0,true +16803,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e3ed6938be54c51f2eb65aa8d97994fc881a5b00000000000000000000000003e3ed6938be54c51f2eb65aa8d97994fc881a5b000000000000000000000000000000000000000000000000000870d378f59a23300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x115001e6c22fda0d80a0916547c4005f6b959efa08cca27148c58ea16057e2c1,2022-04-17 01:40:45.000 UTC,0,true +16804,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cab9a59019a7dc9627dfd16f63f20b8adda22b30000000000000000000000000cab9a59019a7dc9627dfd16f63f20b8adda22b30000000000000000000000000000000000000000000000000016865ce43e8972300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7d07b0b57b98a236affee77c71ee5c966cc4b57461e2f42fc8acf9576ccacdba,2021-12-04 05:07:28.000 UTC,0,true +16806,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f5f01c28d2b8b128e60528226576858742ddcdd0000000000000000000000000f5f01c28d2b8b128e60528226576858742ddcdd000000000000000000000000000000000000000000000000000aa2f8bd3f5efb700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16808,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001458f005d3a56626e394fb17acd64dfae42f581c0000000000000000000000001458f005d3a56626e394fb17acd64dfae42f581c0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16809,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aca9e6139683c8d131dd63dded180fb13f45eb6e000000000000000000000000aca9e6139683c8d131dd63dded180fb13f45eb6e0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16810,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006aaeb488295a48f51c08edaa11dce101d5339e2a0000000000000000000000006aaeb488295a48f51c08edaa11dce101d5339e2a0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16811,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b71e07ca52415e7581c20391dd9880accc3abcd0000000000000000000000007b71e07ca52415e7581c20391dd9880accc3abcd0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16812,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000deb7daf37573cca2d722a994ec68048fd185483f000000000000000000000000deb7daf37573cca2d722a994ec68048fd185483f00000000000000000000000000000000000000000000000000a9b86b2fabb00a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16813,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000070675b0fffd9be1739ebfd8d70033a2a0d67727e00000000000000000000000070675b0fffd9be1739ebfd8d70033a2a0d67727e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16814,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b157e467e9af944ea91e10d1ae5ae74d3be7ada0000000000000000000000001b157e467e9af944ea91e10d1ae5ae74d3be7ada0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16815,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000065823e171f037b889c4e1029e8aa34d6b13430700000000000000000000000000000000000000000000011f87220d50ebc1d180,,,1,true +16816,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000037d7f6f6845fce57068f6389283e6c9dd9ed710f00000000000000000000000037d7f6f6845fce57068f6389283e6c9dd9ed710f000000000000000000000000000000000000000000000000055778282dac0a0700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3e087d66c6aa2abc88ce2c92f7ea1c0c37feedc592b48566e7464c08aad267e4,2021-12-08 16:05:46.000 UTC,0,true +16817,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000123dafc6ba0d25aa362f315486cee7bc823f433d000000000000000000000000123dafc6ba0d25aa362f315486cee7bc823f433d0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16818,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc1708fe24383cc91c46f9ee360e61335ade5b1a000000000000000000000000fc1708fe24383cc91c46f9ee360e61335ade5b1a0000000000000000000000000000000000000000000000000041b9a6e858400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16819,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a8d3a8717fa5488a817a5bb33822c07cd63a5abe000000000000000000000000a8d3a8717fa5488a817a5bb33822c07cd63a5abe0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16820,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000016c86b5f07080a6fcbde9b1e09926bea162df46b00000000000000000000000016c86b5f07080a6fcbde9b1e09926bea162df46b0000000000000000000000000000000000000000000000000075438a8a52f67500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16821,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b17a5ff2012ac401880c3e2d4a9fbca50d4baa60000000000000000000000000b17a5ff2012ac401880c3e2d4a9fbca50d4baa600000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16822,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071d314c69bc3167e4e7670f27c8f78e2b072aa4500000000000000000000000071d314c69bc3167e4e7670f27c8f78e2b072aa4500000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16823,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d104b361f416236bd4bcabe11e731dde2b4e0743000000000000000000000000d104b361f416236bd4bcabe11e731dde2b4e07430000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16824,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000306734230a5b02d274cadff38770832ef8630ceb000000000000000000000000306734230a5b02d274cadff38770832ef8630ceb00000000000000000000000000000000000000000000000000507bb88566fea500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16825,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d52e479ced90fb13969e21695bd1d861eb3573b0000000000000000000000005d52e479ced90fb13969e21695bd1d861eb3573b0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16826,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000afad93492b75cdfb3e685c09966aa8ee6ad872c400000000000000000000000000000000000000000000000001f7b325868aac02,,,1,true +16827,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc41f7fdc1d13ad936d3b3f7032ebdad002f1390000000000000000000000000bc41f7fdc1d13ad936d3b3f7032ebdad002f1390000000000000000000000000000000000000000000000000000c3228b294510400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d9698671d792c42afded97b4df08f6b9c585a560000000000000000000000001d9698671d792c42afded97b4df08f6b9c585a56000000000000000000000000000000000000000000000000014dece145ec2c0900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xfef8a83ca1e13494d14d4a5f09ff16758a126f0d046bee7d44d10578ea85097a,2021-12-19 07:56:55.000 UTC,0,true +16830,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cff22f51b57854b8e479d0d2be8c379400e684ad000000000000000000000000cff22f51b57854b8e479d0d2be8c379400e684ad000000000000000000000000000000000000000000000000003d17367d1bd98000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16831,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000096dfa1224bf898d7865ea8fbe077458bbef060f400000000000000000000000096dfa1224bf898d7865ea8fbe077458bbef060f40000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16832,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e464224ad69be6bd28c5bdb8e54087c35d2b2112000000000000000000000000e464224ad69be6bd28c5bdb8e54087c35d2b211200000000000000000000000000000000000000000000000000ac68158a6eb17b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16833,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000622c7344db7c5b64a31e19773e473caa886b4ab3000000000000000000000000622c7344db7c5b64a31e19773e473caa886b4ab30000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16834,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a69d57d1428b65720f0641ec69ef424873588b9b000000000000000000000000a69d57d1428b65720f0641ec69ef424873588b9b000000000000000000000000000000000000000000000000008933289e5a998800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xba53b64802fb1d065e25dd4c9c25b4259855da8c6eada9a24dd42f9a6ce09088,2022-02-06 12:29:34.000 UTC,0,true +16835,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f232b391a27dd36b69f20e814c83eaa6c8370630000000000000000000000000f232b391a27dd36b69f20e814c83eaa6c83706300000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16836,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000041ebf69c471122fbdaa1d543dbb7f15f5083c8e000000000000000000000000041ebf69c471122fbdaa1d543dbb7f15f5083c8e0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16837,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007599f83c36fa93310a5302c138af0001cf7e47830000000000000000000000007599f83c36fa93310a5302c138af0001cf7e4783000000000000000000000000000000000000000000000000040293cdb57c3d8c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3a341ae9f48dc542189a71ab97ae4505e98580ada5b5e172ba03ef027cc6b731,2022-03-12 09:53:46.000 UTC,0,true +16838,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002dfb60fcd21d919b26932d36368a8a7f053aa2ed0000000000000000000000002dfb60fcd21d919b26932d36368a8a7f053aa2ed000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16839,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001630028e5261856e58157e18a2378c68278dc2770000000000000000000000001630028e5261856e58157e18a2378c68278dc2770000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16840,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005450f43f8b1995145f918ee0534452aa691418510000000000000000000000005450f43f8b1995145f918ee0534452aa691418510000000000000000000000000000000000000000000000000152f9d4fdf8291300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16841,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bbdc4b606d1d1d1201f1cf9682143abe7f4a0ece000000000000000000000000bbdc4b606d1d1d1201f1cf9682143abe7f4a0ece0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16846,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007c0ebe534ae135f84a8d0ac08119247923da10a50000000000000000000000007c0ebe534ae135f84a8d0ac08119247923da10a50000000000000000000000000000000000000000000000000007a22f133e7ec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16847,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000417176e00b17a5cc618dbcc36b00ea8e0f0c9985000000000000000000000000417176e00b17a5cc618dbcc36b00ea8e0f0c998500000000000000000000000000000000000000000000000003d7ffc0d600866500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf9cc364326e9e1dac15a83a945c52682c0dbc153ab4c95411545ed8257098927,2022-02-05 18:31:41.000 UTC,0,true +16848,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005c3fcf281d8c867fd867f78496c95addd8ad23910000000000000000000000005c3fcf281d8c867fd867f78496c95addd8ad23910000000000000000000000000000000000000000000000000007a22f133e7ec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16849,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000024409f656e3cdb7fd0b24303898ae6ef4610d64c00000000000000000000000024409f656e3cdb7fd0b24303898ae6ef4610d64c0000000000000000000000000000000000000000000000000011ca20d85fc38000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16850,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e5e494bdeb6c683e425816b44413fc788566618a000000000000000000000000e5e494bdeb6c683e425816b44413fc788566618a00000000000000000000000000000000000000000000000000b030e7f0b32e5600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16851,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004523069170b38d1e3f618b9cf51ce0e05428318e0000000000000000000000004523069170b38d1e3f618b9cf51ce0e05428318e0000000000000000000000000000000000000000000000000034086e9e54af4c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16853,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f1f2dbb03017fe558ae37b92e38c6d0bd22556c9000000000000000000000000f1f2dbb03017fe558ae37b92e38c6d0bd22556c900000000000000000000000000000000000000000000000000150729a82563c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16854,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f83acd92a8c2fe89199389c41e784b7c84e468bc000000000000000000000000f83acd92a8c2fe89199389c41e784b7c84e468bc00000000000000000000000000000000000000000000000000020572709a6ac000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16855,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087b675e9219a3b870df51449268b8c8c2241bf0c00000000000000000000000087b675e9219a3b870df51449268b8c8c2241bf0c000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16857,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec8d98f1b747f00eef3b82f17d3a6fc14ef9fb64000000000000000000000000ec8d98f1b747f00eef3b82f17d3a6fc14ef9fb6400000000000000000000000000000000000000000000000000a372491167e71e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x32b8ecb990fd640b11aec774db2403d1392fb8da393f3bb8ac4a6b109b848ac3,2022-09-04 11:25:25.000 UTC,0,true +16859,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed4292d00c52d1040e0e1f03949be10caa4ba885000000000000000000000000ed4292d00c52d1040e0e1f03949be10caa4ba885000000000000000000000000000000000000000000000000015d6279fd6aad4700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcf083625196e984745dfefd5ba44367b775505290ff5c86e93cd7e3ac7fa2bd4,2021-12-11 09:25:21.000 UTC,0,true +16860,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000000e331b752bc500d8699a183ad9594b95a5fdf5fe0000000000000000000000000e331b752bc500d8699a183ad9594b95a5fdf5fe000000000000000000000000000000000000000000000000000000000610612a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16864,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002ad6be6a50d93a485a82b897991c6cba0879c87b0000000000000000000000002ad6be6a50d93a485a82b897991c6cba0879c87b00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16865,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f60000000000000000000000005ec259773b76b215ac0fca91723445e002fa8e360000000000000000000000005ec259773b76b215ac0fca91723445e002fa8e360000000000000000000000000000000000000000000000002b7e6808fdb629d700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16866,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ec259773b76b215ac0fca91723445e002fa8e360000000000000000000000005ec259773b76b215ac0fca91723445e002fa8e36000000000000000000000000000000000000000000000000004d22ac15e0f74b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16868,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c102dd014ba57c1a5a431d996edc87cdf78b897a00000000000000000000000000000000000000000000002ae698982a47e28e30,,,1,true +16869,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ee41f2aca01759210b36a5361c3ef29e17a2aa40000000000000000000000007ee41f2aca01759210b36a5361c3ef29e17a2aa400000000000000000000000000000000000000000000000000aa2fac3f12909400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16870,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f07e2fc66c75982e7c35149d3d500e37b0e8b0b0000000000000000000000002f07e2fc66c75982e7c35149d3d500e37b0e8b0b0000000000000000000000000000000000000000000000000034c4f04feb6cd200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16871,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000055d69ffabcc1137c4d8a7143d5cfcc03e7710c7000000000000000000000000055d69ffabcc1137c4d8a7143d5cfcc03e7710c700000000000000000000000000000000000000000000000000600d6d79d1d57e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16872,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a5da4e26d99fb53daedae1e947158ecb656c6250000000000000000000000009a5da4e26d99fb53daedae1e947158ecb656c62500000000000000000000000000000000000000000000000000a9d9f7900cc33d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16873,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004bb02c6a86cc516e355bd25ff48ce800355af2b70000000000000000000000004bb02c6a86cc516e355bd25ff48ce800355af2b700000000000000000000000000000000000000000000000000aac186ad1c0e8e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16874,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3e425f2d8369287087fd149df99f108cb3f97d0000000000000000000000000d3e425f2d8369287087fd149df99f108cb3f97d000000000000000000000000000000000000000000000000000188fb4755d74c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16875,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009408cd0da72bff5f87cddc07bdd2e44fd512b71a0000000000000000000000009408cd0da72bff5f87cddc07bdd2e44fd512b71a00000000000000000000000000000000000000000000000000349d2764a870c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16877,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006b601a4bb4e2a09559cfcbbc73d0f3e5cfea262e0000000000000000000000006b601a4bb4e2a09559cfcbbc73d0f3e5cfea262e000000000000000000000000000000000000000000000000009aaeed27425c4d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16878,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039a6afc920eab4722cf217ba84644ebd6adecf1500000000000000000000000039a6afc920eab4722cf217ba84644ebd6adecf1500000000000000000000000000000000000000000000000006edb40816211d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x850e46b9905a7097657368439928a878ea319398ee5ac1805cdc9c1ecdb42f17,2022-07-21 22:38:16.000 UTC,0,true +16880,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ed2d1e71eaebdbc4aec6e04cdc0b07bb0113d889000000000000000000000000ed2d1e71eaebdbc4aec6e04cdc0b07bb0113d8890000000000000000000000000000000000000000000000000028ad1e9502c04000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16881,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000709fea9fac17d22c704042968823f1742226b2d1000000000000000000000000709fea9fac17d22c704042968823f1742226b2d100000000000000000000000000000000000000000000000000609f9eddf9ae8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16884,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bbb06f09101965daf51756b0b59620a245140cc2000000000000000000000000000000000000000000000000244bf69364bd6179,,,1,true +16886,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf9ed12538fcb472f33e2e8bc2d0a4669ac0913c000000000000000000000000cf9ed12538fcb472f33e2e8bc2d0a4669ac0913c000000000000000000000000000000000000000000000000008700cc7577000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16887,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e25fab412cc70cac0104ca99362d2331a7d69b8e000000000000000000000000e25fab412cc70cac0104ca99362d2331a7d69b8e000000000000000000000000000000000000000000000000027fe6abb9a1ec7f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16888,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a8c411e0b012dba8ced3ccbbcf0335739ec75b30000000000000000000000002a8c411e0b012dba8ced3ccbbcf0335739ec75b300000000000000000000000000000000000000000000000000491ae2f89695a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16889,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a57e6e37092062f467fef468e1b714beb2c343f7000000000000000000000000a57e6e37092062f467fef468e1b714beb2c343f7000000000000000000000000000000000000000000000000031d7f9d5caa084c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x109810ad9f7915c35e46118727dfe21a76f3038ed6570aa19de58f8982a15ef8,2022-02-05 08:44:49.000 UTC,0,true +16891,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000025a4cb8b9da1d3218165d6f296f42cf8d049afdd00000000000000000000000000000000000000000000000a21c22fc2e8820000,,,1,true +16893,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000069dd97aee3d665e75ba685a6ad13bac889a9837700000000000000000000000069dd97aee3d665e75ba685a6ad13bac889a983770000000000000000000000000000000000000000000000001b9863cfc665948000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16895,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000365a3ec18ea9e4591dbd2e7687cb14f472f4b559000000000000000000000000365a3ec18ea9e4591dbd2e7687cb14f472f4b55900000000000000000000000000000000000000000000000000013462b8634fb200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16896,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000172b6e023c25a1962129177f18d5b5dce441e8e6000000000000000000000000172b6e023c25a1962129177f18d5b5dce441e8e600000000000000000000000000000000000000000000000000125bc30a984fe100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16898,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000e8ac385ae701d3c431a8f4bef2e1177796110745000000000000000000000000e8ac385ae701d3c431a8f4bef2e11777961107450000000000000000000000000000000000000000000000000000000009e8e18100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16908,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036fb3c8d2174285888a97c6f398a8ba91673eee400000000000000000000000036fb3c8d2174285888a97c6f398a8ba91673eee400000000000000000000000000000000000000000000000003e2c284391c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x642f30f8cf1e35d41d43ae59542aa9add3a2ea0194b3a36a9e53b87874934855,2021-12-11 10:38:15.000 UTC,0,true +16909,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000005d5955fc64d46b33b636c3db72b863be184fe9600000000000000000000000005d5955fc64d46b33b636c3db72b863be184fe9600000000000000000000000000000000000000000000000000000000060f3c2200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x319231b3b32db4fb647a8073a1206b3cc25fbe8464a6d243559adf4b1bc84cdf,2022-05-09 00:19:55.000 UTC,0,true +16910,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000de8878aa52d2eea1f8b83edca567afea71f970db00000000000000000000000000000000000000000000000f29a76a9e5dbbbdb6,0x39320fb3657729da59b38f052ca84cf458ee02007353a4e07a4db0d875709599,2021-11-28 01:15:28.000 UTC,0,true +16911,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047bb57496ae8c10b3b714bc7f064f3ac049b28e000000000000000000000000047bb57496ae8c10b3b714bc7f064f3ac049b28e0000000000000000000000000000000000000000000000000001f52d5ff411f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16913,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009dd0e68ef913df841826450f843233484d418bb30000000000000000000000009dd0e68ef913df841826450f843233484d418bb300000000000000000000000000000000000000000000000000af40c61b6a050000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16915,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000008d088c12e979f2bf94045b7ba092377db7727ba0000000000000000000000000000000000000000000000722b3e304b15017c7a,0x4a851087ec8df25827cfd9faa0850d8ca0aec98e59248ef683d3dc10cdf46604,2022-04-10 16:25:18.000 UTC,0,true +16920,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008840a72627f06d1def290e6de5d1c70e0dd9c44a0000000000000000000000008840a72627f06d1def290e6de5d1c70e0dd9c44a00000000000000000000000000000000000000000000000000aa885991c7666b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16924,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006235489a0c0a6eaafade625766f6f28a760830890000000000000000000000006235489a0c0a6eaafade625766f6f28a76083089000000000000000000000000000000000000000000000000029e68fedb0a328000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16925,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000045b8231073ce8e8c5d88dd451c8a2badbeec05fd00000000000000000000000045b8231073ce8e8c5d88dd451c8a2badbeec05fd00000000000000000000000000000000000000000000000000ab059981404a1600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16926,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d3fb28778630b99d76e4e4a68be58b50c38792a00000000000000000000000000000000000000000000000000de0b6b3a7640000,0xdaf7a9c06912b32f48c3e44a8eeb17c76b02bdbcbf830840f8e6e751a5aad699,2022-05-08 05:21:38.000 UTC,0,true +16927,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007338f56e2f0de5c7664cbe5bd7de30fb923956570000000000000000000000007338f56e2f0de5c7664cbe5bd7de30fb923956570000000000000000000000000000000000000000000000000208e09d545a594800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x190b960c62b38aa32b64b78a0b207f3c08e85c2faabc16fe42207ed5e771eb89,2021-12-24 12:55:46.000 UTC,0,true +16928,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000024f8d92794a283b454d1fc32722f51a4f3bc1ae500000000000000000000000000000000000000000000000765384ce234f5f10b,,,1,true +16929,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c4cb01191ad5bba5a471294bc1977e726c9b8059000000000000000000000000c4cb01191ad5bba5a471294bc1977e726c9b8059000000000000000000000000000000000000000000000000007580fe08bd922900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16930,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a5b711d5db1e50ddae8ce732a1b967a4908ed710000000000000000000000000a5b711d5db1e50ddae8ce732a1b967a4908ed710000000000000000000000000000000000000000000000000dd85bb46e19f28000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x59bf5b45feb1805bdb7f3d5ee2c736f10c0ef93106314e262cc9ff392df6ef1e,2021-11-28 04:12:56.000 UTC,0,true +16932,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006abcf6820ad0386402933117ceb6e831b906e0710000000000000000000000006abcf6820ad0386402933117ceb6e831b906e0710000000000000000000000000000000000000000000000000221576fcd05c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16933,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063e7098e900e28f2d0c22344d42ca8cc5a1a855000000000000000000000000063e7098e900e28f2d0c22344d42ca8cc5a1a855000000000000000000000000000000000000000000000000000ad1071f045b2d800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16934,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ccdde9b51cb5ed1caa7c0f58c8c8be573463ee13000000000000000000000000ccdde9b51cb5ed1caa7c0f58c8c8be573463ee1300000000000000000000000000000000000000000000000000d822416ca3ba5400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x321287d2dae70d3e40852978168148aca3023f19a6809ae407cfd6444f9fcf3b,2021-11-28 09:41:07.000 UTC,0,true +16935,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004a58362d60e81bb5596c546881312c820abb5eda0000000000000000000000004a58362d60e81bb5596c546881312c820abb5eda00000000000000000000000000000000000000000000000000d71519692b45d900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16936,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4e41c26bb48c72d91f73eda93cc19c9f65644b6000000000000000000000000e4e41c26bb48c72d91f73eda93cc19c9f65644b60000000000000000000000000000000000000000000000000021b2380cac900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf508012f63b9a8e77d2eac216ba49fcabc2d2fccf3f7b5cad7110415cab63340,2022-07-01 07:20:08.000 UTC,0,true +16937,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e656a9f107cb5fbe26d3fe349b123da2d4e463d0000000000000000000000005e656a9f107cb5fbe26d3fe349b123da2d4e463d000000000000000000000000000000000000000000000000003823e693f3ccd700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16938,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000093c9a74f211c44c2ebc5d90aa43ab6ec2d896e4600000000000000000000000093c9a74f211c44c2ebc5d90aa43ab6ec2d896e4600000000000000000000000000000000000000000000000000ac55d7738339e900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16939,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000294631547727b128bff92f7d1b996bad0edfbe68000000000000000000000000294631547727b128bff92f7d1b996bad0edfbe680000000000000000000000000000000000000000000000000dcebed3a4a2103200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf1053732d488c89742c50c26bebefe75dfbe9977591dc71e7db749e422adbc05,2021-11-24 21:21:56.000 UTC,0,true +16941,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b1cd4eeaa0f0574f7bd243b69099cd6da033bbf0000000000000000000000005b1cd4eeaa0f0574f7bd243b69099cd6da033bbf000000000000000000000000000000000000000000000000002913d138b1040200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16943,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dca75c930758cd0a4c64ead527e21e3d61174073000000000000000000000000dca75c930758cd0a4c64ead527e21e3d611740730000000000000000000000000000000000000000000000000186cc6acd4b000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16946,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e724a5756406b6ec652b2fd82704456efa540e54000000000000000000000000e724a5756406b6ec652b2fd82704456efa540e5400000000000000000000000000000000000000000000000000d27db1fb26a62000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16947,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000062486ae25f0b44bb4b51e11fc7208fbcd375a7a000000000000000000000000062486ae25f0b44bb4b51e11fc7208fbcd375a7a0000000000000000000000000000000000000000000000000007e3e8e7eefc1000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16948,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000002df67caf0dd06d05c867b5a72bd2d6726ae7ac7e0000000000000000000000002df67caf0dd06d05c867b5a72bd2d6726ae7ac7e000000000000000000000000000000000000000000000000000000000b44290300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16949,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004ee4e1147f0138ce606cbc9dc8e94b602963a844000000000000000000000000000000000000000000000000cb63480e47622769,,,1,true +16950,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d11beeac6eea20f48145b86ea14abcab3d8f9f9b0000000000000000000000000000000000000000000000003ba8d1d19e14f82d,,,1,true +16951,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d11beeac6eea20f48145b86ea14abcab3d8f9f9b0000000000000000000000000000000000000000000000008a85226f8dab360d,,,1,true +16952,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d9ba778b7f121e58e5d3bb6aef514e035a7c7f50000000000000000000000004d9ba778b7f121e58e5d3bb6aef514e035a7c7f500000000000000000000000000000000000000000000000000a7e4f0794ac00900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16953,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064816835a84d48f1de570d07f007b110315a93b300000000000000000000000064816835a84d48f1de570d07f007b110315a93b300000000000000000000000000000000000000000000000001517903d615863e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x7207d22251f7fe734b07120d2bdad35c01dbbe2ae62a26082f49bd2f6ad6b648,2022-03-27 07:38:42.000 UTC,0,true +16954,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000077c5d343e226e7e152246780be2bca2af91631e000000000000000000000000077c5d343e226e7e152246780be2bca2af91631e000000000000000000000000000000000000000000000000004502e4b3bf7bd400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe94e3e04b4641e7e686bcdb17cfac62af2cfa41c0c4ccfeff05ca0aee7bf5796,2022-03-10 16:43:11.000 UTC,0,true +16956,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e87bf6541249102772516185156e59b649b7bcb9000000000000000000000000e87bf6541249102772516185156e59b649b7bcb900000000000000000000000000000000000000000000000000457a9bd0a48e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16958,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a29012a376716fbd163ae8693974422eaf4b194c000000000000000000000000a29012a376716fbd163ae8693974422eaf4b194c000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x695253567b6c9c4439711d413b111a755f7b8291f549f018ba0c941fd934c89c,2022-09-07 10:58:25.000 UTC,0,true +16959,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007053d9262b7a6aea8ca0eb172d9fb2f3f09a35c70000000000000000000000007053d9262b7a6aea8ca0eb172d9fb2f3f09a35c7000000000000000000000000000000000000000000000000018faa3dce5a857500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16960,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d56460e9b6235b59ef881cd5f7adc137ed0b2f13000000000000000000000000d56460e9b6235b59ef881cd5f7adc137ed0b2f13000000000000000000000000000000000000000000000000018f0833d64c78cc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16961,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004d3da6d4ff825d0f97f96b423c06f14a6d0c92780000000000000000000000004d3da6d4ff825d0f97f96b423c06f14a6d0c9278000000000000000000000000000000000000000000000000018f0833d64c78cc00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16962,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b699fafba3d0ad9ed0583ef2aed0dd88fee4652f000000000000000000000000b699fafba3d0ad9ed0583ef2aed0dd88fee4652f000000000000000000000000000000000000000000000000018e86c5204966f200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16963,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c019f390abe0e94885ce3eecffe5e2b3875be8ea000000000000000000000000c019f390abe0e94885ce3eecffe5e2b3875be8ea00000000000000000000000000000000000000000000000000456af278a8e60000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16965,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002bd99c2680f9dacf898dd4088187323f5149323a0000000000000000000000002bd99c2680f9dacf898dd4088187323f5149323a000000000000000000000000000000000000000000000000002d59bdceff818900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16966,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000004a64b2820a06a67ee878157a7f48611463d6bd780000000000000000000000004a64b2820a06a67ee878157a7f48611463d6bd7800000000000000000000000000000000000000000000002acdcab48e97bb8f4c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16967,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000e69b3e9e744219ecd5f40fa392f73f2c98762690000000000000000000000000e69b3e9e744219ecd5f40fa392f73f2c98762690000000000000000000000000000000000000000000000000b5e45ca13dd4ee000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16970,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000fe4cc87fe5cbf2fc26bf1884538ec47b5aaf0120000000000000000000000000000000000000000000000003dc6ca52ebeb99d5,,,1,true +16971,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000c1a1182d98f146be42927a4a78db8ac75296acf0000000000000000000000000c1a1182d98f146be42927a4a78db8ac75296acf000000000000000000000000000000000000000000000000000000000d372843600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +16974,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009e319d9ae1f0c493bc047f8a6ca6541a09e2c86a0000000000000000000000009e319d9ae1f0c493bc047f8a6ca6541a09e2c86a000000000000000000000000000000000000000000000000020dcd3742c2000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16979,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f5c839627849e20f7e67313e1598c7fd33924860000000000000000000000002f5c839627849e20f7e67313e1598c7fd339248600000000000000000000000000000000000000000000000000af56968cd1af0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16982,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f1915aba3c55ba20258e6ad98760eece256eff28000000000000000000000000000000000000000000000000107cf03b0591cc48,,,1,true +16983,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000731ca97a11a7e0c1be91a979c37ec0ac811293fd000000000000000000000000731ca97a11a7e0c1be91a979c37ec0ac811293fd0000000000000000000000000000000000000000000000000240bff3b0484b2900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16987,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b325ecd1463ca55c399765061956377b3f47b1ea000000000000000000000000b325ecd1463ca55c399765061956377b3f47b1ea0000000000000000000000000000000000000000000000000001b400ce5e590000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16988,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000085e645fe242a8ceae70f517dd5a773f1129be3170000000000000000000000000000000000000000000000027b40c5e5c2b486a2,,,1,true +16989,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ac1c1c174c0177bd7ec4b1067a2fc4563d398540000000000000000000000000ac1c1c174c0177bd7ec4b1067a2fc4563d39854000000000000000000000000000000000000000000000000000c78293794838000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16993,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002c3adf438022b055b069cda225ed522d2391fd840000000000000000000000002c3adf438022b055b069cda225ed522d2391fd840000000000000000000000000000000000000000000000001c8351a4fa3e5ceb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x014b6286d400bdb9ae76008a18483fdb696ac4d9bd7be65d209d6a7dd18c4fdb,2021-11-28 14:32:49.000 UTC,0,true +16994,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b724845049cbf7e09f98f673c1bec7208db39a37000000000000000000000000b724845049cbf7e09f98f673c1bec7208db39a37000000000000000000000000000000000000000000000000004d4bfbf5c6cc1f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +16995,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006cd8401984a8dd15382dcbb44d87dd249472fd8b0000000000000000000000006cd8401984a8dd15382dcbb44d87dd249472fd8b0000000000000000000000000000000000000000000000000130eee4c84fc3a200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3cfb8b6a90cf09e495444d79279e10a86c2a4240022f1805d0201547ef44a0ea,2022-03-08 08:26:51.000 UTC,0,true +16996,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006cd8401984a8dd15382dcbb44d87dd249472fd8b0000000000000000000000006cd8401984a8dd15382dcbb44d87dd249472fd8b000000000000000000000000000000000000000000000010bf4e3f542e674be700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x6f80afaad6e8765cbe4e2c7e0a118d72ebd681b03c19c2e0e10af93ba6cf221e,2022-03-08 08:25:06.000 UTC,0,true +16997,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000553ef84376c68008f665473268d4a6fb9abf11fe000000000000000000000000553ef84376c68008f665473268d4a6fb9abf11fe000000000000000000000000000000000000000000000000002e9519b911fe3500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x596c0f02788f0a3e0680b9da4d4f704f5e2cebe8140cf0d567812f7c307ba3c4,2022-05-29 15:11:43.000 UTC,0,true +16999,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be659018e3e8afe7838e6c786996d663a5699813000000000000000000000000be659018e3e8afe7838e6c786996d663a569981300000000000000000000000000000000000000000000000000a5a74df156adb800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17000,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d937b707737b81d1da49a0995f93f77cdf0e4608000000000000000000000000d937b707737b81d1da49a0995f93f77cdf0e4608000000000000000000000000000000000000000000000000025d0f870b6cbcab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd8329c41b10bc93f9619a144abb12eacd372a195dd82ef1e8c2da676334254c3,2021-12-12 07:16:05.000 UTC,0,true +17001,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003bf3077256842bd9409b3645797855e721ab22f40000000000000000000000003bf3077256842bd9409b3645797855e721ab22f4000000000000000000000000000000000000000000000000003b7918dd0b9e1800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17002,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078e7d7d4b454ab02904477ea71e6f15270bbb71600000000000000000000000078e7d7d4b454ab02904477ea71e6f15270bbb71600000000000000000000000000000000000000000000000002e689b6b4f0310000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb1f3290022081453ac401163418c71fed9babf6463df38723a845d07b3673a7b,2021-11-28 01:41:16.000 UTC,0,true +17003,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e71da5f8f6e90fa92f794963ba90f5c1cd16a6a6000000000000000000000000e71da5f8f6e90fa92f794963ba90f5c1cd16a6a600000000000000000000000000000000000000000000000000aa87bee538000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd1861440fb71d7f90fee5df06b1e8f21008f9ea9a63ab9451fe9ac2507566fb7,2022-06-17 20:05:45.000 UTC,0,true +17004,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009141e07491347467855e16a2d973bf84c6ecd8de0000000000000000000000009141e07491347467855e16a2d973bf84c6ecd8de000000000000000000000000000000000000000000000000012790550d6e43d100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17007,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb1d07354fc52380ca0adc16d781ad7be0a0064a000000000000000000000000cb1d07354fc52380ca0adc16d781ad7be0a0064a000000000000000000000000000000000000000000000000003e331efcbe1a6d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17012,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000aa9ccef24415475e88d644d3c33fb4ed1b29ffaf000000000000000000000000aa9ccef24415475e88d644d3c33fb4ed1b29ffaf00000000000000000000000000000000000000000000004b4c3f4cc33994000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x5e12a29a2624037467c67d82c193b048159aca9bb736776d9e4bbf2edd25c1ac,2021-11-23 12:11:31.000 UTC,0,true +17013,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3c42dff9c595f6c1538d9e98396b9220d304b80000000000000000000000000e3c42dff9c595f6c1538d9e98396b9220d304b80000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x717f916573dd54a48e0908bcf3eb14008f6f8776476c607ac382f009f417a466,2021-12-03 11:39:02.000 UTC,0,true +17014,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094fce1ba7ba586f1fbc14b6970e7c1cb6a04402e00000000000000000000000094fce1ba7ba586f1fbc14b6970e7c1cb6a04402e000000000000000000000000000000000000000000000000020c408c4e4641d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf7d5937d41ee8c81d1406e68e42fd2a906d68cf4e645ba5fc93c1623105a93c5,2021-12-25 09:29:02.000 UTC,0,true +17016,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000222c006c2e1956383caf63b761d73e804cb47118000000000000000000000000222c006c2e1956383caf63b761d73e804cb471180000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17017,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000027b1f8343c5509fd0b5d63a7fdd920507c7e0da700000000000000000000000000000000000000000000000238fd42c5cf040000,0x2df01c8b7252b0c16ec199867972b5f959b6b7bfd1f13a7db415b4e47d3104e1,2022-03-13 06:13:31.000 UTC,0,true +17020,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000678e1e7a4c55b5bc3735df2355c4c1240c079846000000000000000000000000678e1e7a4c55b5bc3735df2355c4c1240c0798460000000000000000000000000000000000000000000000000035b77aed2c399200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17021,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003774afdd53d42f21c106f9fa1abf66a9acf4ff970000000000000000000000003774afdd53d42f21c106f9fa1abf66a9acf4ff970000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17022,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001be5f9df988c06400780d53df143c1bbff2988b50000000000000000000000001be5f9df988c06400780d53df143c1bbff2988b5000000000000000000000000000000000000000000000000015eee5c95bdfaa300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17023,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010f53b57c6a6f07c9d9684e774cd77a4d29ceb3a00000000000000000000000010f53b57c6a6f07c9d9684e774cd77a4d29ceb3a00000000000000000000000000000000000000000000000001033b9e8a203b9900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17024,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f13d1861f0f26ecd8700a021cc1767a59c1ff3c2000000000000000000000000f13d1861f0f26ecd8700a021cc1767a59c1ff3c20000000000000000000000000000000000000000000000000000e4487dd6b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17025,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ffdebb7ea3ab60bbc1e2ca9d7b4997f2e5f601bb000000000000000000000000ffdebb7ea3ab60bbc1e2ca9d7b4997f2e5f601bb0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17026,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d50521ca9abc795148cb881ce3ee4fd739bf2c0f000000000000000000000000d50521ca9abc795148cb881ce3ee4fd739bf2c0f0000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17027,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4be26f5cd223b61f9fc1bd22241646e02fef5bd000000000000000000000000f4be26f5cd223b61f9fc1bd22241646e02fef5bd0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17028,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000094d297963f98aeef31211e442ece6d7f620039b500000000000000000000000094d297963f98aeef31211e442ece6d7f620039b50000000000000000000000000000000000000000000000000000ec77f7a4400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17029,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b67ca567bed1a234c4938a7e89d91e86ad4fbc50000000000000000000000008b67ca567bed1a234c4938a7e89d91e86ad4fbc50000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17030,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002a5a819afa55000bbc9b9e909613189eb92c37390000000000000000000000002a5a819afa55000bbc9b9e909613189eb92c37390000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17031,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004cc76a4e7036fad1a348249c73b922c2715a6c730000000000000000000000004cc76a4e7036fad1a348249c73b922c2715a6c730000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17032,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009aeda209c979408798397336277c690f72b521540000000000000000000000009aeda209c979408798397336277c690f72b521540000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17034,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f7627169b4c1b0dddf40daaa2dca03f0ca6037a0000000000000000000000007f7627169b4c1b0dddf40daaa2dca03f0ca6037a0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17035,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005df004d8653297117319d015168238d47b21d2d70000000000000000000000005df004d8653297117319d015168238d47b21d2d70000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17043,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cdcf64bcd5ecc4990798110bd4ad8ed3c5dc6f1e000000000000000000000000cdcf64bcd5ecc4990798110bd4ad8ed3c5dc6f1e0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17052,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002975d61c9884eb506886d7ecc60ef86d019c818a0000000000000000000000002975d61c9884eb506886d7ecc60ef86d019c818a0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17088,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e816691000000000000000000000000bc3b0fa064869296faea0467f97984ab60ddec3d000000000000000000000000bc3b0fa064869296faea0467f97984ab60ddec3d0000000000000000000000000000000000000000000000000c47b6c66e3ae6a900000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17089,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f2d822fc64381b44a036295bcaa1ead4848f8ecf000000000000000000000000f2d822fc64381b44a036295bcaa1ead4848f8ecf0000000000000000000000000000000000000000000000000023ea88fe4109c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17090,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c2768e9353bf078ace3c345d279e27d393d5c4870000000000000000000000000000000000000000000000121e9814442075020b,,,1,true +17091,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000fae86fa6eb0d21e198c74956217dec00842adc99000000000000000000000000fae86fa6eb0d21e198c74956217dec00842adc990000000000000000000000000000000000000000000000000000000015f2a14c00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17092,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000aae301463fbb85789b888661f113c18a35e623b4000000000000000000000000aae301463fbb85789b888661f113c18a35e623b40000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17093,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfcdfe2b8c5fd921f0cb1554deef92e8595f6c9b000000000000000000000000cfcdfe2b8c5fd921f0cb1554deef92e8595f6c9b0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17094,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c8cf7ece3065aa6117ae2dde3c5f311b56bf430b000000000000000000000000c8cf7ece3065aa6117ae2dde3c5f311b56bf430b0000000000000000000000000000000000000000000000000000e18dffe7800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17095,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000002f779cd8d2d37f719dd6f14563ba3fde845625500000000000000000000000002f779cd8d2d37f719dd6f14563ba3fde84562550000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17096,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001482974cb66f425c1c2d3fc580a5c7d4b3bdedf70000000000000000000000001482974cb66f425c1c2d3fc580a5c7d4b3bdedf7000000000000000000000000000000000000000000000000033fd2a64598263600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xd30778c18102533bb41852514ac1ca0849f403edaa6aa7a79364b7710005079d,2022-04-24 03:53:15.000 UTC,0,true +17097,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007bae9ff328da5530501e2f05d07b1f79acf321ec0000000000000000000000007bae9ff328da5530501e2f05d07b1f79acf321ec0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17098,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005436d1b90693655eaf8eb656fb69136d9c37c58a0000000000000000000000005436d1b90693655eaf8eb656fb69136d9c37c58a0000000000000000000000000000000000000000000000000000ded381f8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17099,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000595f4f65072917c337cd31afce860777ad0e2261000000000000000000000000595f4f65072917c337cd31afce860777ad0e22610000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17100,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b8aa49debb429ce54df296520b68331d669cdce0000000000000000000000007b8aa49debb429ce54df296520b68331d669cdce0000000000000000000000000000000000000000000000000000e18dffe7800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17101,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b9e41122be54a08999b1100ebf9221d5246d50b0000000000000000000000007b9e41122be54a08999b1100ebf9221d5246d50b0000000000000000000000000000000000000000000000000000ded381f8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17102,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e885198c6c34ee90bf65c4958794ba65f4da0d90000000000000000000000005e885198c6c34ee90bf65c4958794ba65f4da0d90000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17103,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b4ef2441c53360d3aacd06c95bdbba51c791b790000000000000000000000004b4ef2441c53360d3aacd06c95bdbba51c791b790000000000000000000000000000000000000000000000000147b8d4fe413d5600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17104,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e6f3bf96e9bce7da411920e5e7e118ef3cdd1a00000000000000000000000001e6f3bf96e9bce7da411920e5e7e118ef3cdd1a00000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17105,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e2c056c3f1c9eeb3315321b8dd83b7e8aea05ea0000000000000000000000002e2c056c3f1c9eeb3315321b8dd83b7e8aea05ea0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17107,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004999c3a36f8ed0ae7ad33abd828cac81a6d7af230000000000000000000000004999c3a36f8ed0ae7ad33abd828cac81a6d7af230000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17108,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000917bcd9ed06da0c81eca88dd2dee9ca8df6e4522000000000000000000000000917bcd9ed06da0c81eca88dd2dee9ca8df6e45220000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17112,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c8b02b5b18e7c6ae87876cb94e1d273a04fbfe90000000000000000000000003c8b02b5b18e7c6ae87876cb94e1d273a04fbfe900000000000000000000000000000000000000000000000000ab4e26016b7ffa00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x82e990794cfba8a8120792e4a5f311066316bcc020f187853d90b92dbd4114f3,2021-12-16 12:18:43.000 UTC,0,true +17117,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000480ccf469f7f2d65baad9c97413c64a9b9ff6ff2000000000000000000000000480ccf469f7f2d65baad9c97413c64a9b9ff6ff2000000000000000000000000000000000000000000000000037c90b1541a67d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17118,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000030eeff183dce51bd0738e931f6d7b73e2323886800000000000000000000000030eeff183dce51bd0738e931f6d7b73e232388680000000000000000000000000000000000000000000000001c7a552b0a49ac3300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcb22a7eacf81eabc4b97d66c5d3e2de185e98df259e257ff18aa0037279d61d5,2021-11-24 10:13:43.000 UTC,0,true +17120,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b965034eb2256079d7dc8e5b0bba5ed030fffd10000000000000000000000001b965034eb2256079d7dc8e5b0bba5ed030fffd10000000000000000000000000000000000000000000000000049db11f5bd992900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9bd1d2765f49efdddc8eb6199d20421f58c6cd2bc9200b3c90d74da4dc0235c2,2022-02-17 16:33:19.000 UTC,0,true +17122,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065ac569e966648cf629d8b0e5e15ce644b3a01a900000000000000000000000065ac569e966648cf629d8b0e5e15ce644b3a01a9000000000000000000000000000000000000000000000000003ed5f6b1da8a4500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17123,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f9897fd1163dc6995acbfe3db1e35c2821281550000000000000000000000000f9897fd1163dc6995acbfe3db1e35c282128155000000000000000000000000000000000000000000000000009d0aedce82bc0900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbe364e60a5477c74aa5fc573314489cc1f3e9acead60a36904b0713c8534f9db,2021-12-17 11:22:20.000 UTC,0,true +17125,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009f8e08c542fac3ffdc450c6dcf92deb2863a9efb0000000000000000000000009f8e08c542fac3ffdc450c6dcf92deb2863a9efb000000000000000000000000000000000000000000000000010cbfe83185d21200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3a983ea4e5c5cc810ee6c427456634830763bf611ba336a671eab210be84fadd,2021-12-02 04:14:08.000 UTC,0,true +17126,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d8f43fba05d633a71bdfcd536c3fc836fe23558a000000000000000000000000d8f43fba05d633a71bdfcd536c3fc836fe23558a000000000000000000000000000000000000000000000000010d5a306e041dec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x57aa9493eb62973a0991121537bb06c36d70ecdc8fe990e9ec4e49dbf2d37fc4,2021-12-02 04:20:10.000 UTC,0,true +17127,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7f7d8fce54c53ad964e4dc3538cbf4b0e3b1395000000000000000000000000b7f7d8fce54c53ad964e4dc3538cbf4b0e3b1395000000000000000000000000000000000000000000000000010ea2ad9cb3d82400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x21ba2bba5ac12ae4b46b00eee102783a37f23e6235261f0177cf1b2c4919dcb7,2021-12-02 04:23:34.000 UTC,0,true +17128,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c62bec5f0a750260f98bea79b820e9f18d5bad44000000000000000000000000c62bec5f0a750260f98bea79b820e9f18d5bad4400000000000000000000000000000000000000000000000001103c993c03b81700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe263e12580fedbb647a1c6a90d3ae6f2d42c981af44231fa084873aa29d63009,2021-12-02 04:27:41.000 UTC,0,true +17129,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000075f6a7d7c8aaa0db29e9cd4c49b17df5b829e31e00000000000000000000000075f6a7d7c8aaa0db29e9cd4c49b17df5b829e31e000000000000000000000000000000000000000000000000010edd0dce74daf000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x69f5800e38cf4269850e250d329d6f8472712fedfc22eff216fe95b5c91bf282,2021-12-02 04:30:15.000 UTC,0,true +17130,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cc969c8fe6299fcdc4785153540ea2da4efd3834000000000000000000000000cc969c8fe6299fcdc4785153540ea2da4efd3834000000000000000000000000000000000000000000000000010ce032ce88b72300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa24e98697ea53c5d42b97d63107e167e8d4205028809d7439b9f2700d10dacb2,2021-12-02 04:34:47.000 UTC,0,true +17131,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099a288b8cc9c581af9aa2deed29a4f73c7c199f600000000000000000000000099a288b8cc9c581af9aa2deed29a4f73c7c199f6000000000000000000000000000000000000000000000000010eb0a78bc61bf500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x328f336e9b35b1b5cd44475ebd65972d38ce0a01bcd296d344b0184081ae2533,2021-12-02 04:42:40.000 UTC,0,true +17132,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005e5e48f3f09748a8854103981a836a964b816c420000000000000000000000005e5e48f3f09748a8854103981a836a964b816c42000000000000000000000000000000000000000000000000010f989f9451aca300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5da816a4c8db071f3e23e19c40b0da171d70d04778f9ff6e2cc683c6eb8a2126,2021-12-02 04:47:26.000 UTC,0,true +17133,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a240707caeb1fcc72404f964d697f78a1239d07a000000000000000000000000a240707caeb1fcc72404f964d697f78a1239d07a00000000000000000000000000000000000000000000000001109a1009d3a73100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17134,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028f8f8ab489f65cac52b1aeec9a213e424a9853100000000000000000000000028f8f8ab489f65cac52b1aeec9a213e424a98531000000000000000000000000000000000000000000000000010f30d203d6dbd100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x626edf0e93ee5023050a523a8b94a04f79a340397cde559a48407665452f6ebd,2021-12-02 04:55:55.000 UTC,0,true +17135,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f99b31f3dc3b05975cf6924988d4a0b4813505f4000000000000000000000000000000000000000000000002b613371e38c86589,,,1,true +17136,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053ed1cb341d105673d85763ec7889469455b46f000000000000000000000000053ed1cb341d105673d85763ec7889469455b46f000000000000000000000000000000000000000000000000000c749178a0c1ad200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17137,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ad539ef1257f61fe15e878b9b7d5d1abe2156678000000000000000000000000ad539ef1257f61fe15e878b9b7d5d1abe215667800000000000000000000000000000000000000000000000000c8a38b9472673e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x001c0efc3bb5a70874db95ae06ff053e9334ba43a2fc772bac97bfef8a6e272c,2022-02-26 12:51:54.000 UTC,0,true +17139,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047a80f9d951d4fcfc34a7c04e671a2d663760a1900000000000000000000000047a80f9d951d4fcfc34a7c04e671a2d663760a1900000000000000000000000000000000000000000000000001587a9c76d8129400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17140,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f6000000000000000000000000078ec322eef36f157600bf3ce43211e28adbc07b000000000000000000000000078ec322eef36f157600bf3ce43211e28adbc07b000000000000000000000000000000000000000000000000ca9071965e4fe06100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17142,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e25ba8ec283a86a3dbfb471ec262e26dd8137c59000000000000000000000000e25ba8ec283a86a3dbfb471ec262e26dd8137c59000000000000000000000000000000000000000000000000000bc72f2ebe6c9400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17143,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000566e62982f0318616977dac873e83d1d0c825ddb000000000000000000000000566e62982f0318616977dac873e83d1d0c825ddb000000000000000000000000000000000000000000000000004576847595350700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17144,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000090157efaaa8dc6006434d98e60231a7ae81162e10000000000000000000000000000000000000000000000061317e7748a8f234f,,,1,true +17145,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001830dbb1d9054ff82d8c2efa4c2107a1e28305a40000000000000000000000001830dbb1d9054ff82d8c2efa4c2107a1e28305a400000000000000000000000000000000000000000000000001aa535d3d0c000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17146,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000abdcfd11af016bbd617847a464a87993cc61c050000000000000000000000000abdcfd11af016bbd617847a464a87993cc61c05000000000000000000000000000000000000000000000000000d1dd398444537800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17150,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090a247279b94f4609481d0ca8459b68aa79959ea00000000000000000000000090a247279b94f4609481d0ca8459b68aa79959ea00000000000000000000000000000000000000000000000002cda5ee04a1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17153,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a61443cdf751dcb8d95f24633522562fb93f512400000000000000000000000000000000000000000000000c5d4c6b0cb78097fe,0x6988598a4aeaaa2efe660ce979c881e61c11af78a3eb8c2c013b6e3d8a61b947,2021-11-26 07:16:58.000 UTC,0,true +17154,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae08eba835fc6c2b9726b31c7e248171457cc44a000000000000000000000000ae08eba835fc6c2b9726b31c7e248171457cc44a00000000000000000000000000000000000000000000000000561117f211d76800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17156,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f85385347f56819c316939434d427d0c9537eddc000000000000000000000000f85385347f56819c316939434d427d0c9537eddc000000000000000000000000000000000000000000000000a6ef525ab4e2c51b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17157,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000324cac984d3f7f40bc00ba9621d341769c90a97a00000000000000000000000000000000000000000000010f611e8b1b85461d44,0x5fb95d43b8f10d3e637f527cd66826fdfad712ce5f478d0aa9c4c0096e961fed,2021-12-02 00:32:48.000 UTC,0,true +17158,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000df938d253a6fb2845eb4b96f27cf8b3d61216b93000000000000000000000000000000000000000000000007372a8dcc56ab11b1,,,1,true +17160,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fc7f0fd2a353b7694deb8da43684f3d50c928130000000000000000000000004fc7f0fd2a353b7694deb8da43684f3d50c92813000000000000000000000000000000000000000000000000004aae626c506aa300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17161,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000312761d81670c5906e487620cec73b1556add74d000000000000000000000000312761d81670c5906e487620cec73b1556add74d0000000000000000000000000000000000000000000000000000ded381f8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17162,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007b0105344845232f19100471c24ca4c320ebf2e00000000000000000000000007b0105344845232f19100471c24ca4c320ebf2e000000000000000000000000000000000000000000000000000798387ee84f0fd00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17163,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038bba1f6d1e9a703744774beadad5a477cc3a9cf00000000000000000000000038bba1f6d1e9a703744774beadad5a477cc3a9cf0000000000000000000000000000000000000000000000000000ddeaad53400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17165,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003598143d676dc58eb7a2a159326d26f3c09363fb0000000000000000000000003598143d676dc58eb7a2a159326d26f3c09363fb000000000000000000000000000000000000000000000000019571e36245517b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x39bd2797798b0569bab2f6f0d70ba973662f59b65fd0c2ce1eaead94596fbb2a,2022-03-22 10:27:58.000 UTC,0,true +17168,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059d12abaefdf2233380f08f2ab9f7944aaba165600000000000000000000000059d12abaefdf2233380f08f2ab9f7944aaba16560000000000000000000000000000000000000000000000000000ded381f8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17169,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b7c484d9eca2fd5a9b670c25b33f45daf7d9b85f0000000000000000000000000000000000000000000000121f57872c129ce2f5,,,1,true +17172,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c7231008f957439294ff4f5bf10a7b373dfbbfa0000000000000000000000008c7231008f957439294ff4f5bf10a7b373dfbbfa00000000000000000000000000000000000000000000000002b154638f62987700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb8cf97d1bb6ed6136ddc942ad6bb99fd81d20cc3d1c60dc6cbac2c646468e8cf,2021-12-01 08:33:50.000 UTC,0,true +17173,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5459faea42aa128423cb494a7fa29bbb41f5d42000000000000000000000000c5459faea42aa128423cb494a7fa29bbb41f5d4200000000000000000000000000000000000000000000000000caddd9c68c876800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17174,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a6e7e18314f36cf2ef4f0bd0035fdd1b126f84e0000000000000000000000003a6e7e18314f36cf2ef4f0bd0035fdd1b126f84e0000000000000000000000000000000000000000000000000000ddeaad53400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17175,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055cd6f4a80d0e62e5557ef266d0fa00372fd9a9300000000000000000000000055cd6f4a80d0e62e5557ef266d0fa00372fd9a93000000000000000000000000000000000000000000000000003c6fb31adc483f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17176,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f998e2ff04e6b1c367837da0d4f42c4aa764f08d000000000000000000000000f998e2ff04e6b1c367837da0d4f42c4aa764f08d0000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17177,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2567fde0415f238fa424e5be49b11b64b253de7000000000000000000000000e2567fde0415f238fa424e5be49b11b64b253de70000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17178,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000019e80654656af3fa27ea3b8f68b04e070de1423700000000000000000000000019e80654656af3fa27ea3b8f68b04e070de1423700000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17179,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f4adcaafc1769c8cb34ea6b128beb777a58a6bc0000000000000000000000008f4adcaafc1769c8cb34ea6b128beb777a58a6bc000000000000000000000000000000000000000000000000002ea7a052fb556900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17180,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d734dcc789e84a61cb154b1812af6e3d02d09dad000000000000000000000000d734dcc789e84a61cb154b1812af6e3d02d09dad0000000000000000000000000000000000000000000000000000dc190409200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17181,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bd7ac85da56c0bfb3373380e2396d453d094970a000000000000000000000000bd7ac85da56c0bfb3373380e2396d453d094970a0000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17182,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0b044e0dfa39199fb5cbcf466762b8b80c2d85d000000000000000000000000b0b044e0dfa39199fb5cbcf466762b8b80c2d85d000000000000000000000000000000000000000000000000009e21a698b1baeb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17183,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008bcf9320497028119da1c99525d19a9f0d86f92a0000000000000000000000000000000000000000000000000bbab876113c2ca8,,,1,true +17184,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc65c103438b426f02940a351415f52e11431f98000000000000000000000000fc65c103438b426f02940a351415f52e11431f980000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17185,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b8c72154b9766f4b05895738ef217914c9be6b90000000000000000000000001b8c72154b9766f4b05895738ef217914c9be6b90000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17186,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e8d9f46f1526d8f5640000c83a81b92578bb3800000000000000000000000001e8d9f46f1526d8f5640000c83a81b92578bb38000000000000000000000000000000000000000000000000001c2d7d3874b8d2b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17188,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b4916641c4975ebf23585b3d6845955d01d504e0000000000000000000000001b4916641c4975ebf23585b3d6845955d01d504e0000000000000000000000000000000000000000000000000000dc190409200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17190,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000699053f19f64217206d2d1cb34006b355180718b000000000000000000000000699053f19f64217206d2d1cb34006b355180718b000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17192,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000117266cdd328d8c59b85c68cb4d4ae6c71a78c5e000000000000000000000000117266cdd328d8c59b85c68cb4d4ae6c71a78c5e000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17193,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e71bc1a0c50b7356ec5ff9e54088e55ef63e1a80000000000000000000000006e71bc1a0c50b7356ec5ff9e54088e55ef63e1a8000000000000000000000000000000000000000000000000057d1dfe9ad1083d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xaedd13fdc63313981afa909c3c248bc116fe4704212fdd487c14fcedf2deb79e,2021-12-14 10:54:18.000 UTC,0,true +17194,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da5dfd2d4807741fe0eb6ee1fd88a04000c88e5c000000000000000000000000da5dfd2d4807741fe0eb6ee1fd88a04000c88e5c000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17195,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000077e1105c4782493ab490d7151b6ce690ee2bb7a400000000000000000000000077e1105c4782493ab490d7151b6ce690ee2bb7a4000000000000000000000000000000000000000000000000000110d9316ec00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17198,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004421de8bfb150486936a4e8da325ce64862f5ac80000000000000000000000004421de8bfb150486936a4e8da325ce64862f5ac800000000000000000000000000000000000000000000000000003aa41d43570000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1689aee63e65f7d827c41621f9ee17654b0c6891120a3b9f1d4fef5fa3e1044d,2022-03-15 09:34:39.000 UTC,0,true +17199,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000bc9522834584aee4502d999b0f0cb71e1fa5fac0000000000000000000000000bc9522834584aee4502d999b0f0cb71e1fa5fac00000000000000000000000000000000000000000000000000af1b04b999100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17200,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064509cdbda147bd7ccad34ff0c9ac8d59f7cedb900000000000000000000000064509cdbda147bd7ccad34ff0c9ac8d59f7cedb90000000000000000000000000000000000000000000000000033e3f2e5d0c3a800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17201,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000471b9a239acbdcfed92b754ca76273e57aae507d000000000000000000000000471b9a239acbdcfed92b754ca76273e57aae507d00000000000000000000000000000000000000000000000004002afa86cbdc4900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17202,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000973b78c7d8ab8f92bed18ee594baeea5bdaa4052000000000000000000000000973b78c7d8ab8f92bed18ee594baeea5bdaa40520000000000000000000000000000000000000000000000000000dc190409200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17204,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0fc3bc1ca1e4346b1c4cb71db3b9e1d9c5454dd000000000000000000000000a0fc3bc1ca1e4346b1c4cb71db3b9e1d9c5454dd000000000000000000000000000000000000000000000000013d0f3b9c4de24900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17205,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c272244c7c0dda6017402d8bc357e5b283930030000000000000000000000006c272244c7c0dda6017402d8bc357e5b283930030000000000000000000000000000000000000000000000000000db302f64100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17206,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000214cf6b080aa5c7371eeb0e2a15f28fe25fddaa8000000000000000000000000214cf6b080aa5c7371eeb0e2a15f28fe25fddaa800000000000000000000000000000000000000000000000001e0f90eea632b9300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17207,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000382d14d295ecbcb67fd834bc31e894e420529a4a000000000000000000000000382d14d295ecbcb67fd834bc31e894e420529a4a0000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17209,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef8622b58fb925b3819cadce537b0ffafa0a1a6b000000000000000000000000ef8622b58fb925b3819cadce537b0ffafa0a1a6b000000000000000000000000000000000000000000000000003cb99a17b7f8d200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17210,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f277720138dd910a8f27a5a624f297fec4c1f8c1000000000000000000000000f277720138dd910a8f27a5a624f297fec4c1f8c1000000000000000000000000000000000000000000000000015a105b4412380000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17211,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f1e2c281f699cd0773cf4489ea1d569329258da0000000000000000000000003f1e2c281f699cd0773cf4489ea1d569329258da0000000000000000000000000000000000000000000000000000db302f64100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17212,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae69dac9e28bdf65480e0d88a4c46d1c702fa506000000000000000000000000ae69dac9e28bdf65480e0d88a4c46d1c702fa506000000000000000000000000000000000000000000000000047c3adae4fe8b5d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17214,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000528869eb2d3b35597a32779cb1b9c2d62cca923d00000000000000000000000000000000000000000000000523fb2972e2fa1566,,,1,true +17216,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091a7c920007e1db566f88eb8eb99f5dc7ed7223800000000000000000000000091a7c920007e1db566f88eb8eb99f5dc7ed722380000000000000000000000000000000000000000000000000000db302f64100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17218,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be9e50182ea6e23362a003a131a6173e884f259c000000000000000000000000be9e50182ea6e23362a003a131a6173e884f259c0000000000000000000000000000000000000000000000000195c8074677ce2200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x955269866c0ae81bf9f302cf427fc6a7b3cb26b0774499e36d4068662028d8f0,2022-02-02 09:00:29.000 UTC,0,true +17220,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df7e033a2c8b167f857184971493f70326d200be000000000000000000000000df7e033a2c8b167f857184971493f70326d200be00000000000000000000000000000000000000000000000001cb9e644f8a3dbe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x0281355da0285f38e8bb99c53ea09c9f5e69605f36a9841274969f67acae9c5e,2022-02-02 09:05:33.000 UTC,0,true +17221,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000068ba19fb87380b86f6bd2462da0fbc83f4b5b1ee00000000000000000000000068ba19fb87380b86f6bd2462da0fbc83f4b5b1ee000000000000000000000000000000000000000000000000017412dec23b2e4c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xc9de0b497e2955e924e1c613dcb51c0144c609931b8e7a652eb2e2fcb13027a6,2022-02-02 09:16:29.000 UTC,0,true +17222,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e0ea7fb67036150b7797727235a0e6b2166456f5000000000000000000000000e0ea7fb67036150b7797727235a0e6b2166456f500000000000000000000000000000000000000000000000001da18fad1d259c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x588cd9b975eea69daf76cd6649474fc3abbb4af1c8b596ebffb0e6df8b1af4f9,2022-02-02 09:22:13.000 UTC,0,true +17223,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dbdc7394909d893eb0c99a0a56d177728314fd9c000000000000000000000000dbdc7394909d893eb0c99a0a56d177728314fd9c00000000000000000000000000000000000000000000000001af101fee19806f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5554dbde96339e753baaaae6b071cbbf634281fa5d54a04fca8acb214f88e2fa,2022-02-02 09:26:43.000 UTC,0,true +17224,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000628ec392726fddc854ad574f06d24a772d21fa53000000000000000000000000628ec392726fddc854ad574f06d24a772d21fa5300000000000000000000000000000000000000000000000001fd38a657ce100200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x20b20973112ac567f379abba0bfc85b639c809169012e648b8df2b86160c67fb,2022-02-02 09:30:25.000 UTC,0,true +17225,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000005f601a092974b52853ffbbef763d19186b8e6ad00000000000000000000000005f601a092974b52853ffbbef763d19186b8e6ad0000000000000000000000000000000000000000000000000171224de43c04d600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x3d206fa7971978461111103fae60d00c00d9a10538b8e2c9ac857fff6bb8562f,2022-02-02 09:35:54.000 UTC,0,true +17226,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f7b2229beee1de8cf84973fd59b641efc9a894c6000000000000000000000000f7b2229beee1de8cf84973fd59b641efc9a894c60000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17227,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086ec96ff8d423910b26dab62dfe30720fc47605f00000000000000000000000086ec96ff8d423910b26dab62dfe30720fc47605f0000000000000000000000000000000000000000000000000161a99fcd89b35800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x632bac6537b7b6a121faf970ef7c17b9c32a855d9816b26f4a9cacf16f1238ed,2022-02-02 09:42:20.000 UTC,0,true +17228,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b6b624a91d3b98c38ad619e6c3f27d291c617385000000000000000000000000b6b624a91d3b98c38ad619e6c3f27d291c6173850000000000000000000000000000000000000000000000000000db302f64100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17230,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002fb733c3239a1e807d380fa0845b9101ee54c69300000000000000000000000000000000000000000000004bdef0437ede6cbc80,0x28f4f35f05a365617ee7a35be46994154fe8c92e34479cfd1422c778330ec538,2022-04-02 07:17:52.000 UTC,0,true +17231,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000e1da16be636a5775f0c7eac9eab670b6db17b707000000000000000000000000e1da16be636a5775f0c7eac9eab670b6db17b707000000000000000000000000000000000000000000000001c4e1db48bab19bd800000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x5623442e7c7f03441aacd60ee0e6dab3ccae50db855ae62c150d4fbc022fc4c3,2022-05-28 09:51:44.000 UTC,0,true +17232,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1c2d0860a213c630c7e285eb5b8b1ebdfa205b1000000000000000000000000c1c2d0860a213c630c7e285eb5b8b1ebdfa205b100000000000000000000000000000000000000000000000000992e501987f2e800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x784d2629e7bbed5abc12e45ef5ab5a0389c50d40c1c7c98841db07bfed29d910,2021-12-03 12:25:56.000 UTC,0,true +17234,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000061a275fca0242363c658edbdb0527bfc1ee140d100000000000000000000000061a275fca0242363c658edbdb0527bfc1ee140d10000000000000000000000000000000000000000000000000049d8bef8f3f00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17235,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fc7f0fd2a353b7694deb8da43684f3d50c928130000000000000000000000004fc7f0fd2a353b7694deb8da43684f3d50c92813000000000000000000000000000000000000000000000000008ce1f4c272d59500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17236,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df82ee79e40bbe3d088fc8620feedd6793283c8f000000000000000000000000df82ee79e40bbe3d088fc8620feedd6793283c8f00000000000000000000000000000000000000000000000000cbb0bc63e0fb4b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17237,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f600000000000000000000000046d54bf2c77d02f1b19b54e6fac2bcd5a05a980200000000000000000000000046d54bf2c77d02f1b19b54e6fac2bcd5a05a98020000000000000000000000000000000000000000000000004442dd683b34ee7500000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17239,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4c86cf4302deb8c4757a6a46359fee49438dbc2000000000000000000000000e4c86cf4302deb8c4757a6a46359fee49438dbc2000000000000000000000000000000000000000000000000013f3cee05096dfe00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17242,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4493623399fbf0a622eb87f52210c20f13054c4000000000000000000000000e4493623399fbf0a622eb87f52210c20f13054c40000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17243,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dd31937ededa450105a75e28b0a3246b22ebf030000000000000000000000000dd31937ededa450105a75e28b0a3246b22ebf030000000000000000000000000000000000000000000000000009fdf42f6e4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17244,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000006515ac8eab778dd6a533e60e4cda41e0a8e4fcf00000000000000000000000006515ac8eab778dd6a533e60e4cda41e0a8e4fcf0000000000000000000000000000000000000000000000000e84ab227b66cc5100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x4f472721804924e7afd67d66c4ae13f2f2ee3c76ed95191785ac817703ea7e5d,2021-11-25 17:54:52.000 UTC,0,true +17246,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e580000000000000000000000001296d4a9fa924a289c270c4fa09e5332484c489c0000000000000000000000001296d4a9fa924a289c270c4fa09e5332484c489c000000000000000000000000000000000000000000000000000000001442189100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xa3dc89e032969457169147ece203c0fd34bd2c98cb5ce98fb23fde186356a947,2021-11-26 14:54:54.000 UTC,0,true +17247,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4039e492374dd1008322dd7536fbe7f43cfd33e000000000000000000000000f4039e492374dd1008322dd7536fbe7f43cfd33e0000000000000000000000000000000000000000000000003ada84007264841300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17249,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000005f56e5ade609d0869351bd43b768568bc690c6f900000000000000000000000000000000000000000000010193e476a20d4b0000,0xe9a507eb120ba34c6c0ecf1324e2feb63786fecf8fc0236c1a4da0b34326ed01,2021-11-24 07:13:25.000 UTC,0,true +17252,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001744e87f864eed8ff1e87ff83cc203a7dc44bd100000000000000000000000001744e87f864eed8ff1e87ff83cc203a7dc44bd1000000000000000000000000000000000000000000000000002fde6cbdd649f500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17253,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000070513a081114ed019361d7d6f0e575206da938100000000000000000000000000000000000000000000000000f65120188a664cb,,,1,true +17254,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000482d685a17c90d7bb3e0c753f72c870f76aaa850000000000000000000000000482d685a17c90d7bb3e0c753f72c870f76aaa8500000000000000000000000000000000000000000000000126342bb15d57e905100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xbba597349f6230600b0f587b505de6c0e5c721c996fc545222aafc2cb116de19,2021-12-02 12:21:01.000 UTC,0,true +17255,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000917e4e563701e9d94b8d00775dcbd4ab86efd479000000000000000000000000917e4e563701e9d94b8d00775dcbd4ab86efd47900000000000000000000000000000000000000000000000000131bfd304bb72b00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17257,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003210cc31ba9c6788eebddc3f5de02b9cedde2c6f0000000000000000000000003210cc31ba9c6788eebddc3f5de02b9cedde2c6f00000000000000000000000000000000000000000000000006d33393818bde9900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17258,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000522afb5d3bae59b08fa6114dcc043a88aff12fe0000000000000000000000000522afb5d3bae59b08fa6114dcc043a88aff12fe00000000000000000000000000000000000000000000000000045c7a1ea8ff4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17259,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000acd003ed939fb8f80b2f4fe33769d13bc04e5847000000000000000000000000acd003ed939fb8f80b2f4fe33769d13bc04e58470000000000000000000000000000000000000000000000000000000008c45ef400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17260,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000acd003ed939fb8f80b2f4fe33769d13bc04e5847000000000000000000000000acd003ed939fb8f80b2f4fe33769d13bc04e5847000000000000000000000000000000000000000000000000005f4f2bcc07ed6f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17262,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c15175feef26f9d8e9ea44e1dded1c493a7948d7000000000000000000000000c15175feef26f9d8e9ea44e1dded1c493a7948d70000000000000000000000000000000000000000000000000139f8c47bd7114e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17263,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007d279221e3c6b88f550f0056a4a8506dd1999841000000000000000000000000000000000000000000000000120a871cc0020000,,,1,true +17264,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000038619ab48fa7be0550646024513b198e00349fb3000000000000000000000000000000000000000000000007551800ed3c149eb8,0x6241acf9fa459615207017ddef3bc306a831c9aac39e65ba51a8abc954f9169a,2022-04-14 15:23:50.000 UTC,0,true +17265,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000b6ed7644c69416d67b522e20bc294a9a9b405b31000000000000000000000000e0bb0d3de8c10976511e5030ca403dbf4c25165b000000000000000000000000034f5590a08c2ca060494ef0b424b5620cc5ddce000000000000000000000000034f5590a08c2ca060494ef0b424b5620cc5ddce000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17269,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000251d14ea6929fc5163db5de098f82bed3710bb32000000000000000000000000251d14ea6929fc5163db5de098f82bed3710bb320000000000000000000000000000000000000000000000000038366020c30c7900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17270,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000172d9a724ce598bdfcaf5617d920cae6969e1070000000000000000000000000172d9a724ce598bdfcaf5617d920cae6969e1070000000000000000000000000000000000000000000000000dd0fbf75d11c2b200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17271,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008013ccf525b4b9cabf6f19846d409c9d8bc820b50000000000000000000000008013ccf525b4b9cabf6f19846d409c9d8bc820b500000000000000000000000000000000000000000000000000a43ba9fb96730100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17272,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000545a605a6b0c42bb5bd01f918e17d7347095acc0000000000000000000000000000000000000000000000000dacd0ae5481d68f,,,1,true +17277,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d106794a34e67744a71cf9ecd1e7ec2089c557db000000000000000000000000d106794a34e67744a71cf9ecd1e7ec2089c557db000000000000000000000000000000000000000000000000004b0041de31fec000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17278,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002f833b4a48395ce96c6fa26ee834fef6e5a421270000000000000000000000002f833b4a48395ce96c6fa26ee834fef6e5a421270000000000000000000000000000000000000000000000000000dc190409200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17279,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b7398a7aecac2c18e2dd25f38666900be73c09eb000000000000000000000000b7398a7aecac2c18e2dd25f38666900be73c09eb0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17280,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000240f6e31e1f4c7afd30000d779a3e64bf183c19a000000000000000000000000240f6e31e1f4c7afd30000d779a3e64bf183c19a00000000000000000000000000000000000000000000000001876cc9adc581b000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17281,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007e73fa7e1ca276ded206fcb1e4ca7d500e426dde0000000000000000000000007e73fa7e1ca276ded206fcb1e4ca7d500e426dde0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17282,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000909402b195b28065ff1ae4d44214eb9a84934c5c000000000000000000000000909402b195b28065ff1ae4d44214eb9a84934c5c0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17283,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000258aa64c04c29835115ef539263b44d407d1865f000000000000000000000000258aa64c04c29835115ef539263b44d407d1865f000000000000000000000000000000000000000000000000019f0cb4d7b3c93200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xcbd1aa34320cda82a8b4702a7920826e91115bb75d4cfbc2c4accda707774707,2022-08-14 19:02:55.000 UTC,0,true +17284,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000724a6685ce532eaa6d7e50fc190121ba0e125fdb000000000000000000000000724a6685ce532eaa6d7e50fc190121ba0e125fdb0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17285,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000052981b61cec2ec625d543a917c06b26c2b2a647600000000000000000000000052981b61cec2ec625d543a917c06b26c2b2a64760000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17286,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001d7729531091e66190f59690ea3aa661dbd0e1ba0000000000000000000000001d7729531091e66190f59690ea3aa661dbd0e1ba0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17288,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009239e943376c9a700b8c3232d1754fd88cdd20870000000000000000000000009239e943376c9a700b8c3232d1754fd88cdd20870000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17289,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000666cdb303b6ce4c27995570e06273a66d8c4bb63000000000000000000000000666cdb303b6ce4c27995570e06273a66d8c4bb630000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17290,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039652d24da8893e7d3316046f531649dc0764f9a00000000000000000000000039652d24da8893e7d3316046f531649dc0764f9a0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17291,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000a251df99a88a20a93876205fb7f5faf2e85a4810000000000000000000000000a251df99a88a20a93876205fb7f5faf2e85a481000000000000000000000000000000000000000000000000008b0d39f93e954600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17292,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002173d6e48199512a24ef95a9293f1ed5d46f5f2e0000000000000000000000002173d6e48199512a24ef95a9293f1ed5d46f5f2e0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17293,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000060ca0cff985910b8f2d582f766ffa920b50ecc8f00000000000000000000000060ca0cff985910b8f2d582f766ffa920b50ecc8f0000000000000000000000000000000000000000000000000000dc190409200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17294,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3fe5596e7d3a1845ea032ae9062527a91e56fcd000000000000000000000000f3fe5596e7d3a1845ea032ae9062527a91e56fcd0000000000000000000000000000000000000000000000000000ded381f8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17296,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000049da81cea71f4290f637f1a62be5876d25c4ca6000000000000000000000000049da81cea71f4290f637f1a62be5876d25c4ca600000000000000000000000000000000000000000000000000000ded381f8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17298,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a5269423a6cb778237a276d7209f746f9664f060000000000000000000000003a5269423a6cb778237a276d7209f746f9664f060000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17299,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a70973471f8a71ffefe0fda91e905fc730926a60000000000000000000000007a70973471f8a71ffefe0fda91e905fc730926a60000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17300,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000698d4cf17ee2bbd49afd287328b74e36d5666654000000000000000000000000698d4cf17ee2bbd49afd287328b74e36d56666540000000000000000000000000000000000000000000000000000e531527bc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17301,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9991995a403b33f9059bacb85666d0e43afb28c000000000000000000000000e9991995a403b33f9059bacb85666d0e43afb28c0000000000000000000000000000000000000000000000000000e61a2720d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17302,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ac45e7f57912beae2535fb6d941eb64c6feb13f0000000000000000000000006ac45e7f57912beae2535fb6d941eb64c6feb13f0000000000000000000000000000000000000000000000000000e61a2720d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17304,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c0d561bcb3bb59fda309c26b037079f2ecbb2cf0000000000000000000000000c0d561bcb3bb59fda309c26b037079f2ecbb2cf00000000000000000000000000000000000000000000000000000e702fbc5e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17305,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000084437d9084fbf39acae49ca7faff9946131b433000000000000000000000000084437d9084fbf39acae49ca7faff9946131b4330000000000000000000000000000000000000000000000000000e702fbc5e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17306,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031ab4b11c342d2dde0d087fb2d7d8d7b12275fe500000000000000000000000031ab4b11c342d2dde0d087fb2d7d8d7b12275fe50000000000000000000000000000000000000000000000000000e61a2720d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17308,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004fa4d4524502998372716acda9e639af84d3e0310000000000000000000000004fa4d4524502998372716acda9e639af84d3e0310000000000000000000000000000000000000000000000000000e61a2720d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17309,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000033668616f8a8ce314afbe27b250be6ce45d361cb00000000000000000000000033668616f8a8ce314afbe27b250be6ce45d361cb0000000000000000000000000000000000000000000000000000e61a2720d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17310,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001177e92fc87372f1df6f478d538ccf19436df2430000000000000000000000001177e92fc87372f1df6f478d538ccf19436df2430000000000000000000000000000000000000000000000000000e61a2720d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17311,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000084356ffcaeb364f4e5bcbe71862a67c97842a16b0000000000000000000000000000000000000000000000000a55b1b272983993,,,1,true +17312,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007f6dfddb6a056fd03951d17ef45dd5e1612093e10000000000000000000000007f6dfddb6a056fd03951d17ef45dd5e1612093e1000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17313,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec17a12cad66bd5758d4887008440435a5ac4062000000000000000000000000ec17a12cad66bd5758d4887008440435a5ac4062000000000000000000000000000000000000000000000000001081872a8fb67f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17314,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f9840000000000000000000000006fd9d7ad17242c41f7131d257212c54a0e8166910000000000000000000000007ecd9a6364fe493f5ea902851243f24622a3078b0000000000000000000000007ecd9a6364fe493f5ea902851243f24622a3078b00000000000000000000000000000000000000000000000034695e07c333932f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17315,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ecd9a6364fe493f5ea902851243f24622a3078b0000000000000000000000007ecd9a6364fe493f5ea902851243f24622a3078b0000000000000000000000000000000000000000000000000017c4d83647cbc000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17316,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b11c46a0601b0329d2e069900a675da75d1df6dd000000000000000000000000b11c46a0601b0329d2e069900a675da75d1df6dd00000000000000000000000000000000000000000000000897bf32e4714b14e600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17317,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b11c46a0601b0329d2e069900a675da75d1df6dd000000000000000000000000b11c46a0601b0329d2e069900a675da75d1df6dd00000000000000000000000000000000000000000000000000a5c0111d5efe4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17318,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000882ce9e1307cd42e3daf573bdb76055cc89a4df8000000000000000000000000882ce9e1307cd42e3daf573bdb76055cc89a4df800000000000000000000000000000000000000000000000004059597f8e7969500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17321,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006d49e448194f5425ae1120e5fac54bb0ec67631a0000000000000000000000000000000000000000000000021d3bd55e803c0000,,,1,true +17323,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005533f954d78aaf3601b8e0aa1f3ce4140bde23d70000000000000000000000005533f954d78aaf3601b8e0aa1f3ce4140bde23d700000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17324,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004682f0ccc7bd7cd668bc319fce8497a6b35277e300000000000000000000000000000000000000000000002d14378f3944f4bef7,0x4c169aceba4439b62cce13af459090f859554accb539d5d80882d63d14de8648,2021-12-01 17:04:39.000 UTC,0,true +17328,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000070f52b922e9eabf97c8d39828a045f8f81eb467b00000000000000000000000070f52b922e9eabf97c8d39828a045f8f81eb467b000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17329,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000005faa51f65e1dc92ab7c18faadb1435f90ac5fa9c00000000000000000000000000000000000000000000000b02acf2e392709e8e,0x9f9888a69077b73863794f7773d0689ef61ab7eebbca5323853c0a618eb08a1f,2021-11-28 12:10:47.000 UTC,0,true +17331,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051679136e1a3407912f8fa131bc5f611c52d9fee00000000000000000000000051679136e1a3407912f8fa131bc5f611c52d9fee00000000000000000000000000000000000000000000000001425dbf8daff34200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17332,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000308a2a13f0cfe9d6f17d3b15da7278b70b85523c000000000000000000000000308a2a13f0cfe9d6f17d3b15da7278b70b85523c000000000000000000000000000000000000000000000000000d1e38e721ea8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17333,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001a91c0df156a5f38aec0813d055aa0184fc478260000000000000000000000000000000000000000000000005d7aaebc1a055d58,,,1,true +17334,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001a91c0df156a5f38aec0813d055aa0184fc478260000000000000000000000000000000000000000000000000001ae50b2a26b62,,,1,true +17337,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009a72c4275919b54401c9665ae6e4ea070c50c9230000000000000000000000009a72c4275919b54401c9665ae6e4ea070c50c9230000000000000000000000000000000000000000000000000137e11559abad0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17338,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000675d5f9f18afd31aed61b28cf69f55ab12030b05000000000000000000000000675d5f9f18afd31aed61b28cf69f55ab12030b0500000000000000000000000000000000000000000000000001d7cbf31616e64a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17340,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009c07990bc8e0ae119edb60ae751c5b1a21ab271600000000000000000000000000000000000000000000000eef75e630a873f30b,0x1c2eedc66fcc722cd6cc72ec097b21ebe0382115b164a502520cf1f020703967,2021-11-23 21:51:31.000 UTC,0,true +17341,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000baa882d68fc5325fc3899de264f24b5981523a5c00000000000000000000000000000000000000000000001236efcbcbb3400000,0x1f23044a56e431b0f1a8ebda55ebb2d09410ae6703df3fe051e7c63e2742ff2b,2021-12-15 04:08:25.000 UTC,0,true +17344,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000471bd4de7f8f26558cfe3256c8cf8e239abaede6000000000000000000000000471bd4de7f8f26558cfe3256c8cf8e239abaede60000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17345,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fb17d612f277ea6689f2500ff9534c4784cea020000000000000000000000002fb17d612f277ea6689f2500ff9534c4784cea020000000000000000000000000000000000000000000000000000e61a2720d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17346,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc7bf974d38e52a66d5259feaa9552432f7dc0ca000000000000000000000000dc7bf974d38e52a66d5259feaa9552432f7dc0ca00000000000000000000000000000000000000000000000000cbe4d1ac5b4ec800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17347,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009aedae918f56d8df08f2a5ea473d2aaff7c4ddc90000000000000000000000009aedae918f56d8df08f2a5ea473d2aaff7c4ddc90000000000000000000000000000000000000000000000000000e61a2720d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17348,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000059d69238caad27f2353075065bbd4a3f91dc005100000000000000000000000059d69238caad27f2353075065bbd4a3f91dc00510000000000000000000000000000000000000000000000000000e531527bc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17349,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e137d025bbf8284cdc906bfe8a59bc26e7a6cf5d000000000000000000000000e137d025bbf8284cdc906bfe8a59bc26e7a6cf5d0000000000000000000000000000000000000000000000000000e61a2720d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17350,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000065e2d45920eb747a4895f3040aaa6277372c0c1800000000000000000000000065e2d45920eb747a4895f3040aaa6277372c0c180000000000000000000000000000000000000000000000000000e531527bc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17351,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067b6a6cd8f7815369abe49f8fb397a6349ba524400000000000000000000000067b6a6cd8f7815369abe49f8fb397a6349ba52440000000000000000000000000000000000000000000000000000e531527bc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17352,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d42f9c063ca6d8d21b78a12ae3ffb62d3b64f949000000000000000000000000d42f9c063ca6d8d21b78a12ae3ffb62d3b64f9490000000000000000000000000000000000000000000000000000e531527bc00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17353,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000013a32aa268ca78d82a7c3ce5e59d78dbe72a5a17000000000000000000000000000000000000000000000066f8f181aef1472327,0xf2ca490457e211260dd21a54817fa99e1eabfe3dc11bfca153a5e7fdcd5a32b3,2021-12-05 03:37:46.000 UTC,0,true +17354,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ddabad84d46a65e58be5f29a16225d6d8e1fc97f000000000000000000000000ddabad84d46a65e58be5f29a16225d6d8e1fc97f0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17355,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001fb90ec242c3da509cacb8a0b6415903f53f5dd60000000000000000000000001fb90ec242c3da509cacb8a0b6415903f53f5dd60000000000000000000000000000000000000000000000000000e18dffe7800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17359,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bce5cfdbcff2d53fa30d654813c09f0ac23b6dd0000000000000000000000005bce5cfdbcff2d53fa30d654813c09f0ac23b6dd0000000000000000000000000000000000000000000000000000e0a52b42700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17360,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009ea9569ebfe156e1548c6bc6795fcfc6b63b18410000000000000000000000009ea9569ebfe156e1548c6bc6795fcfc6b63b18410000000000000000000000000000000000000000000000000000e0a52b42700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17361,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000640d148193fbd62e0057cd39c7400ef1816371d2000000000000000000000000640d148193fbd62e0057cd39c7400ef1816371d20000000000000000000000000000000000000000000000000000dfbc569d600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17362,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000367694c570581a87dc14fff5b1a032955678b7dc000000000000000000000000367694c570581a87dc14fff5b1a032955678b7dc0000000000000000000000000000000000000000000000000000e276d48c900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17363,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e6980a436e36c3543872f3e496c2466a01f14c850000000000000000000000000000000000000000000000012e7de6058bcd726e,,,1,true +17364,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000090eb33aedd32d1610e8d7defe1cc7230faa8b1e800000000000000000000000090eb33aedd32d1610e8d7defe1cc7230faa8b1e80000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17365,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c74abd2cf12ed34f5b88eda5f35558d899465670000000000000000000000008c74abd2cf12ed34f5b88eda5f35558d899465670000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17367,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b80058c3100c0d2a2ed35295f139ea75a58faf90000000000000000000000002b80058c3100c0d2a2ed35295f139ea75a58faf9000000000000000000000000000000000000000000000000003e55adb7164f9800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1b9257c5d4f5ec727461491ed4d391800c63c68004b8ef84c7d8ea2b0705df3a,2022-06-12 12:42:46.000 UTC,0,true +17368,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e27993c8571f321b94aed638c91be186178eb826000000000000000000000000e27993c8571f321b94aed638c91be186178eb8260000000000000000000000000000000000000000000000000000e276d48c900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17369,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001852fc454ee9c176e847c77ba63841ef122ff9300000000000000000000000001852fc454ee9c176e847c77ba63841ef122ff930000000000000000000000000000000000000000000000000000e18dffe7800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17370,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f3ac722d2302758bd5f331324e4b9d8cd4fb33d2000000000000000000000000f3ac722d2302758bd5f331324e4b9d8cd4fb33d20000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17371,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000656e9642ae9e3a9edbe4d53927aa58c68428094b000000000000000000000000656e9642ae9e3a9edbe4d53927aa58c68428094b0000000000000000000000000000000000000000000000000000e18dffe7800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17372,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f065362c176bac34aa0ff34aec08928c28175ee5000000000000000000000000f065362c176bac34aa0ff34aec08928c28175ee5000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17374,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d657c543723c8563daba902ed078bc28ea9e5597000000000000000000000000d657c543723c8563daba902ed078bc28ea9e559700000000000000000000000000000000000000000000000001456dab70e7390000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17377,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000053f66041bfe3b65ce1dbd03694c2be84cba78b2100000000000000000000000053f66041bfe3b65ce1dbd03694c2be84cba78b2100000000000000000000000000000000000000000000000000abc238bdbedd6c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17379,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d07c8b9eaf17b6d31abd4125e28c7c6a5e1e9870000000000000000000000000d07c8b9eaf17b6d31abd4125e28c7c6a5e1e98700000000000000000000000000000000000000000000000000b8a248c2b320e8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17380,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f15d4b322a88213674431814fe249d561abf465b000000000000000000000000f15d4b322a88213674431814fe249d561abf465b000000000000000000000000000000000000000000000000015181ff25a9800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17381,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d7be06fed116c75c4b0e2d766f5b69ee741e15e200000000000000000000000000000000000000000000000029a2241af62c0000,,,1,true +17383,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000079a98a9f41051e119cad1b9ffefe523cd0be65f000000000000000000000000000000000000000000000004507116808705714f8,0x60eeb170ba2affe996b6933aa2d818c9ec291fad97d4fc92634be852f2ffc126,2022-02-03 06:22:16.000 UTC,0,true +17384,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004b4781df451642f490de17b0f58354e426f632230000000000000000000000004b4781df451642f490de17b0f58354e426f632230000000000000000000000000000000000000000000000000138763e61a5560000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17386,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006664bbd4748c7678766caf2d591fdb6ee2cb15470000000000000000000000006664bbd4748c7678766caf2d591fdb6ee2cb1547000000000000000000000000000000000000000000000000014f24787b57766700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17388,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009251d5835f4a68d1e3603735b43409941c24434300000000000000000000000000000000000000000000001f9127525004faafba,,,1,true +17389,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000873676c1b5ef9b387b3cc99dabe73c804f90f972000000000000000000000000873676c1b5ef9b387b3cc99dabe73c804f90f972000000000000000000000000000000000000000000000000007f16a28481e9fb00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17390,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009c07990bc8e0ae119edb60ae751c5b1a21ab271600000000000000000000000000000000000000000000002244482d97e8bf33f1,0xe7569ef3a4dfd363b6a57514f448eb092d5bcaa673b961ba8b8b83e2f52f7be1,2021-11-23 21:53:51.000 UTC,0,true +17391,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ff85c6208ee8a3bc484f73a9b8f2d55b9b01c000000000000000000000000006ff85c6208ee8a3bc484f73a9b8f2d55b9b01c0000000000000000000000000000000000000000000000000001b335624357578000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17393,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000eecf245ae681a55ba5dcbf2b4ba8b08cb4a92451000000000000000000000000eecf245ae681a55ba5dcbf2b4ba8b08cb4a924510000000000000000000000000000000000000000000000000000dc190409200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17394,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044e02bed8aa1c18fee0283ca262a05df7b1cbc4100000000000000000000000044e02bed8aa1c18fee0283ca262a05df7b1cbc410000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17395,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000036cdf46b4fd4381f5d79e009f01400b92b8ce6d400000000000000000000000036cdf46b4fd4381f5d79e009f01400b92b8ce6d40000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17396,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c4066642fe89232369d0adb6b6e125ee29197cd0000000000000000000000003c4066642fe89232369d0adb6b6e125ee29197cd0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17398,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000028180c4b1852333a258ce261b479fb99e1d5d72d00000000000000000000000028180c4b1852333a258ce261b479fb99e1d5d72d0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17399,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003e3dea41bb540288ffd6ae03c4c849c24dc58a6e0000000000000000000000003e3dea41bb540288ffd6ae03c4c849c24dc58a6e0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17400,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008b97baab653bd6424d7f9f1826476115c24da4220000000000000000000000008b97baab653bd6424d7f9f1826476115c24da4220000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17403,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000290bd8f5e770d500763004cef3f09a245cc64733000000000000000000000000290bd8f5e770d500763004cef3f09a245cc647330000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17404,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ec5d524582b8d3f921631ec233262edcbbed008f000000000000000000000000ec5d524582b8d3f921631ec233262edcbbed008f0000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17405,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b633ea40f49b4bf8e00b938bbe48d1438630e6ac000000000000000000000000b633ea40f49b4bf8e00b938bbe48d1438630e6ac0000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17406,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000de3521ed8529fbcf3c3e3de1fde0dc60afb51239000000000000000000000000de3521ed8529fbcf3c3e3de1fde0dc60afb512390000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17407,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005d6dd6b50585e107167285851efa5cfa0cac54f50000000000000000000000005d6dd6b50585e107167285851efa5cfa0cac54f50000000000000000000000000000000000000000000000000000d78cdccfd00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17408,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d438da20a82a9b131a2b53880a30214f353a32a5000000000000000000000000d438da20a82a9b131a2b53880a30214f353a32a50000000000000000000000000000000000000000000000000000db302f64100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17409,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003328df0d9924308e257cdd19e40df4bcae8e81190000000000000000000000003328df0d9924308e257cdd19e40df4bcae8e81190000000000000000000000000000000000000000000000000000ded381f8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17411,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006e8a0f43b7eec5c77a9d4aac28570b0a0b5b19670000000000000000000000006e8a0f43b7eec5c77a9d4aac28570b0a0b5b19670000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17412,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001a28d5b9e40762bde62b39ed3227a0dbb42417110000000000000000000000001a28d5b9e40762bde62b39ed3227a0dbb42417110000000000000000000000000000000000000000000000000000d5bb3385b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17414,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c7b9b1a605bdec44664e61603eb7e061ab94864a000000000000000000000000c7b9b1a605bdec44664e61603eb7e061ab94864a000000000000000000000000000000000000000000000000057661692ea0016700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x1613f3f53325f08439dc254dcdac99d9319633c13c10e3edb190b5c69ddc369c,2022-06-01 08:36:32.000 UTC,0,true +17415,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000c625e0541656cbdde921cc6179cb920633f5408c000000000000000000000000c625e0541656cbdde921cc6179cb920633f5408c00000000000000000000000000000000000000000000001418216a02f7f181ef00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0xe6e33def00c5a0630b300f51090912049f46fa08cb8430162d543c08d8518c9c,2021-12-09 16:26:31.000 UTC,0,true +17416,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000014f0f90fa59e3bd60aa7e1097abda932f2f1640500000000000000000000000014f0f90fa59e3bd60aa7e1097abda932f2f16405000000000000000000000000000000000000000000000000013fbe85edc9000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x59cfb83a88b1d49724ea96c9327d4bfe351b5e4463fdb1bc34918fb18ef652a9,2022-08-09 09:33:28.000 UTC,0,true +17417,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a05c33f8e7d9e600f5f61abdade4537320196030000000000000000000000003a05c33f8e7d9e600f5f61abdade4537320196030000000000000000000000000000000000000000000000000000d5bb3385b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17419,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a199b0bfbd246994738ea545eac381aac73503ae000000000000000000000000a199b0bfbd246994738ea545eac381aac73503ae0000000000000000000000000000000000000000000000000000d5bb3385b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17420,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a22d38ac19d95792dac606674201aa306e8498e2000000000000000000000000a22d38ac19d95792dac606674201aa306e8498e20000000000000000000000000000000000000000000000000000d4d25ee0a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17421,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cedf43079f72894103b5817b467ab361496c2ac4000000000000000000000000cedf43079f72894103b5817b467ab361496c2ac40000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17422,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000885a3810e1fca74faac070af24c0de8378323e92000000000000000000000000885a3810e1fca74faac070af24c0de8378323e920000000000000000000000000000000000000000000000000000d78cdccfd00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17423,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fbcda728abb86d3fa38d0263cc5c831eb06bc1e0000000000000000000000000fbcda728abb86d3fa38d0263cc5c831eb06bc1e00000000000000000000000000000000000000000000000000000d5bb3385b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17424,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003519ef2ca968712388ce7d39f1523d5b2dfdd8d90000000000000000000000003519ef2ca968712388ce7d39f1523d5b2dfdd8d90000000000000000000000000000000000000000000000000000d217e0f1700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17425,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c67df5fbad50979f0ea2bb7111f84df1366c85a5000000000000000000000000c67df5fbad50979f0ea2bb7111f84df1366c85a50000000000000000000000000000000000000000000000000000d5bb3385b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17426,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc79e4fe5d61076bb91fe2aab0446c522b274aee000000000000000000000000bc79e4fe5d61076bb91fe2aab0446c522b274aee0000000000000000000000000000000000000000000000000000d5bb3385b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17428,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009bf90bcff11df8dbbd22e2efb082b2fcaddb86d30000000000000000000000009bf90bcff11df8dbbd22e2efb082b2fcaddb86d30000000000000000000000000000000000000000000000000000d6a4082ac00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17429,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000064373326129e926f4425ddfd294ae22075eb2aba00000000000000000000000064373326129e926f4425ddfd294ae22075eb2aba000000000000000000000000000000000000000000000000006651d91b48dd0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17430,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bcb1c9373b1214ce96ce847160e33660aa293fc8000000000000000000000000bcb1c9373b1214ce96ce847160e33660aa293fc8000000000000000000000000000000000000000000000000004f157eec24340000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17431,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000822f9725ef111647863fc4035d13761efdb7e488000000000000000000000000822f9725ef111647863fc4035d13761efdb7e488000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17433,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000258da40e011acb8e0f6308d6dda4de363c9b604000000000000000000000000000000000000000000000000053906430e9d7cd5,,,1,true +17436,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000902c915d3a062aa72a4e3c9fbdf193e19025cdd4000000000000000000000000902c915d3a062aa72a4e3c9fbdf193e19025cdd4000000000000000000000000000000000000000000000000132fe40ca22df40900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x6d44845d9179ef5580559db92926b78426e3e69ef23c20758f86593a962327e2,2021-11-27 22:39:52.000 UTC,0,true +17445,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000edcb53f0ea600b3c15eb2351f9aee65660d383de000000000000000000000000000000000000000000000000114631114ba8c6dd,,,1,true +17446,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ab8887950986fb6502c93af7611cf4c9d60b4070000000000000000000000006ab8887950986fb6502c93af7611cf4c9d60b4070000000000000000000000000000000000000000000000000051b660cdd5800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17447,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ab8887950986fb6502c93af7611cf4c9d60b4070000000000000000000000006ab8887950986fb6502c93af7611cf4c9d60b407000000000000000000000000000000000000000000000000001517ab8808100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17452,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006c00fd260ce525f7945f6bd91bcad5e8d57ef6d10000000000000000000000000000000000000000000000694cc0c717efb7cec4,0xa6fcf19d464743cbcfa062069cf563735d49b4018d876fbf2416c78d3b640d24,2021-12-19 10:29:34.000 UTC,0,true +17455,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ab17ffe29ef29439e6e0236bf70afdec20dec594000000000000000000000000ab17ffe29ef29439e6e0236bf70afdec20dec594000000000000000000000000000000000000000000000000020eb9304f74215900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xa3141397c090dc22de6008affaa9e6ea6462c35b1390a11a37f4782d5da68c20,2022-07-24 06:34:07.000 UTC,0,true +17456,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000020b45ffb7bdd01a17c7477acf706ce6781d259f200000000000000000000000020b45ffb7bdd01a17c7477acf706ce6781d259f200000000000000000000000000000000000000000000000001a66d2afb0ec50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17457,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000078613721f001003c83d17930a470140edb3df5d900000000000000000000000078613721f001003c83d17930a470140edb3df5d90000000000000000000000000000000000000000000000000233bd216610160000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xb4614ad7e3928afc2d5cac3d2ba465c47a9181fed7ba3081ed885b24167beafc,2022-11-01 08:39:23.000 UTC,0,true +17460,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000350a791bfc2c21f9ed5d10980dad2e2638ffa7f6000000000000000000000000b3b49304c663cd70c0a3fa15cf29de426b6d109d000000000000000000000000b3b49304c663cd70c0a3fa15cf29de426b6d109d00000000000000000000000000000000000000000000000b14b5c9374c17f6b300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17461,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038eef87a7123c61d37e140c1e6e15f917acddcfb00000000000000000000000038eef87a7123c61d37e140c1e6e15f917acddcfb00000000000000000000000000000000000000000000000000cff00540d0470000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17462,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032753fc346c1479271490fbab8aa2faf88f3135500000000000000000000000032753fc346c1479271490fbab8aa2faf88f31355000000000000000000000000000000000000000000000000002a01021fd1e8c400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17463,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000cc3c15da0f598711cea394460653540ef97ff99e00000000000000000000000000000000000000000000000d8449a0f0a7e60000,,,1,true +17464,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007599635c81550d076fae4b6971716e983ef86d3e0000000000000000000000007599635c81550d076fae4b6971716e983ef86d3e000000000000000000000000000000000000000000000000001cae2868c7633400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17465,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bfd457de4cbc3b930b34a893cc0463dc095c6d90000000000000000000000000bfd457de4cbc3b930b34a893cc0463dc095c6d90000000000000000000000000000000000000000000000000001bf8c7d4d0c30800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17466,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d9884ed4cd8e44cc7fe50f9dc23587b8a9c7904e000000000000000000000000d9884ed4cd8e44cc7fe50f9dc23587b8a9c7904e000000000000000000000000000000000000000000000000002ef590bac57e1f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17467,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d1b02eba530e7248102a455200a41dae58058cd0000000000000000000000006d1b02eba530e7248102a455200a41dae58058cd0000000000000000000000000000000000000000000000000624a42eeb32504400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x2c4985004b213ea2f601668cb8400b466d526e3b7bff293a19ab54fe29194da8,2021-11-23 23:11:21.000 UTC,0,true +17471,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d867583eebd7f82f79d12836d15c512b54e7c2c4000000000000000000000000d867583eebd7f82f79d12836d15c512b54e7c2c40000000000000000000000000000000000000000000000000000d4d25ee0a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17472,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007414e97e91645d0ebbd6b4ec354b3617741a6b4c0000000000000000000000007414e97e91645d0ebbd6b4ec354b3617741a6b4c0000000000000000000000000000000000000000000000000000d3e98a3b900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17473,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000066f4594eed3ddbc6eae99b5116bb0e2f4d4a71b900000000000000000000000066f4594eed3ddbc6eae99b5116bb0e2f4d4a71b90000000000000000000000000000000000000000000000000000d12f0c4c600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17474,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a01be7266be4d0d63802691b576491af7055e018000000000000000000000000a01be7266be4d0d63802691b576491af7055e0180000000000000000000000000000000000000000000000000000d217e0f1700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17475,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071cc934d93ae3cdd597d3a7017a05293b3a862fe00000000000000000000000071cc934d93ae3cdd597d3a7017a05293b3a862fe0000000000000000000000000000000000000000000000000000d95e8619f00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17476,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000050f56bd03c9fb317ec2c6bac998b1e773e12df8800000000000000000000000050f56bd03c9fb317ec2c6bac998b1e773e12df880000000000000000000000000000000000000000000000000000d217e0f1700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17477,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005143e1e81c9ba050499fff2212a13a14a4be5fd80000000000000000000000005143e1e81c9ba050499fff2212a13a14a4be5fd80000000000000000000000000000000000000000000000000000d300b596800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17478,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003f3382b354835151c7e2f8d61f7318d4f118efd20000000000000000000000003f3382b354835151c7e2f8d61f7318d4f118efd20000000000000000000000000000000000000000000000000000d300b596800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17479,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b01a5802f354e19a2f42b68ebe9cfe6d9d0bb430000000000000000000000000b01a5802f354e19a2f42b68ebe9cfe6d9d0bb430000000000000000000000000000000000000000000000000000d3e98a3b900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17480,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d845d5f143f1401a1650c2b70e2ea3350b1d50b3000000000000000000000000d845d5f143f1401a1650c2b70e2ea3350b1d50b30000000000000000000000000000000000000000000000000000d4d25ee0a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17481,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001728f815456c6d7f516584d354fb1b80346ffb9a0000000000000000000000001728f815456c6d7f516584d354fb1b80346ffb9a0000000000000000000000000000000000000000000000000000d3e98a3b900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17482,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ee16d8f098d61a5a8504f3775c508e25b7675640000000000000000000000006ee16d8f098d61a5a8504f3775c508e25b7675640000000000000000000000000000000000000000000000000000d3e98a3b900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17483,0x10e6593cdda8c58a1d0f14c5164b376352a55f2f,0x467194771dae2967aef3ecbedd3bf9a310c76c65,0xa9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000005b513ea36823a094a66a291d3ab88eda2298943c0000000000000000000000005b513ea36823a094a66a291d3ab88eda2298943c00000000000000000000000000000000000000000000000b0ae9a14e42ad355a00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17484,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005b513ea36823a094a66a291d3ab88eda2298943c0000000000000000000000005b513ea36823a094a66a291d3ab88eda2298943c00000000000000000000000000000000000000000000000000776cdf5c35dbd100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17485,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000755192487edda64e5114f8a94ded82d7b5a03aa1000000000000000000000000755192487edda64e5114f8a94ded82d7b5a03aa10000000000000000000000000000000000000000000000000000d3e98a3b900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17486,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000203f6b4778864ea089c1711f2574031f9e8b5f17000000000000000000000000203f6b4778864ea089c1711f2574031f9e8b5f170000000000000000000000000000000000000000000000000000d3e98a3b900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17487,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002f6be2184972c7786ef1c5cc2d92f11c55c33d080000000000000000000000000000000000000000000000015e10b080ac027e3e,,,1,true +17488,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004315d7cd76c83bac4e27cd1e4664ea610d1100770000000000000000000000004315d7cd76c83bac4e27cd1e4664ea610d1100770000000000000000000000000000000000000000000000000000d300b596800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17489,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000091f9b7b15458972f78af36e602876122bee8995400000000000000000000000091f9b7b15458972f78af36e602876122bee899540000000000000000000000000000000000000000000000000000d4d25ee0a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17490,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000950453ac097411e04f2a2fa745ca37887909bec4000000000000000000000000950453ac097411e04f2a2fa745ca37887909bec40000000000000000000000000000000000000000000000000000d4d25ee0a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17491,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ed521bd887f427cf79cbcf0fb3d3eaa68f7146f0000000000000000000000006ed521bd887f427cf79cbcf0fb3d3eaa68f7146f0000000000000000000000000000000000000000000000000000d6a4082ac00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17492,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ae1e2c000ce7463d641f995f42a6eee2e0b48b00000000000000000000000006ae1e2c000ce7463d641f995f42a6eee2e0b48b00000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17493,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c8e9b24afee116a08387414f6b6a8e8823f00fa300000000000000000000000000000000000000000000000df027c9ea9f82f5fc,,,1,true +17494,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f9eb56be6042802ce130d5149c25dbec0ca9be1e000000000000000000000000f9eb56be6042802ce130d5149c25dbec0ca9be1e0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17495,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000efe6649c303e0032fe3afaccb4488391ef8943f6000000000000000000000000efe6649c303e0032fe3afaccb4488391ef8943f600000000000000000000000000000000000000000000000001548f3e29018f4e00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xf559761853a0f2abdda5bd05a174aa2ae07fe195329e569cc60f0a479604a294,2021-12-20 11:59:49.000 UTC,0,true +17496,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000dfd2df5b5a5305f69f499e06ef4b0442767aebf0000000000000000000000000dfd2df5b5a5305f69f499e06ef4b0442767aebf0000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17497,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000042a14ec383551dec3cacc62ad58ab7413e5518a0000000000000000000000000000000000000000000000007ca94f93b5c5c7fac,0x7e45531ecb144662a57857b41230113ba3cacd36878d9c8f8d26b7ee189bb76d,2022-02-01 21:37:21.000 UTC,0,true +17498,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002178367ea01a093caf1cd6ab7608a82b9521ab410000000000000000000000002178367ea01a093caf1cd6ab7608a82b9521ab41000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17499,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002b21bbe1b1c7097a5402ad4ad9860f19e07badb00000000000000000000000002b21bbe1b1c7097a5402ad4ad9860f19e07badb00000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17501,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000034e100ae67f93d9ccb9c0cf11a34e56dbdc09ad000000000000000000000000034e100ae67f93d9ccb9c0cf11a34e56dbdc09ad0000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17502,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000f1b630493180996c769539ec5e402153eb7f5af0000000000000000000000000f1b630493180996c769539ec5e402153eb7f5af0000000000000000000000000000000000000000000000000000d95e8619f00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17503,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001e69ef2d9be1ad7468d6a305ad01d347f12f6d40000000000000000000000000000000000000000000000001f823602dad852d29,,,1,true +17504,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000189d1e4299dbf518e54e507e05e57c0e350daf68000000000000000000000000189d1e4299dbf518e54e507e05e57c0e350daf680000000000000000000000000000000000000000000000000000d78cdccfd00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17505,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a7742c55a5361de00e9b91be6faad46cabd12eb0000000000000000000000007a7742c55a5361de00e9b91be6faad46cabd12eb0000000000000000000000000000000000000000000000000000d92ff52c200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17506,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000744d5875fc81af39adb0826a3b4c4b84e0448655000000000000000000000000744d5875fc81af39adb0826a3b4c4b84e04486550000000000000000000000000000000000000000000000000000d92ff52c200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17507,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d9c48c0d99140f3db0e8b12c6c7b2147da67ccd0000000000000000000000006d9c48c0d99140f3db0e8b12c6c7b2147da67ccd0000000000000000000000000000000000000000000000000000da301248180000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17508,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001303a8a5fb974c2d7df6157010b1b27f55924ce00000000000000000000000001303a8a5fb974c2d7df6157010b1b27f55924ce00000000000000000000000000000000000000000000000000000d82fd810280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17509,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a35425dc344212c23d6d3f3cce76a5d64f218ad5000000000000000000000000a35425dc344212c23d6d3f3cce76a5d64f218ad50000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17510,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000752bfefb7857685849929b1f5c5de653e5443f68000000000000000000000000752bfefb7857685849929b1f5c5de653e5443f680000000000000000000000000000000000000000000000000000d95e8619f00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17511,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051fd2af043bb40f68cd9d69ec07262834649a57600000000000000000000000051fd2af043bb40f68cd9d69ec07262834649a5760000000000000000000000000000000000000000000000000000d918acb5380000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17512,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000086bccfa5549e4127b3f140dc203762ae29ed925000000000000000000000000086bccfa5549e4127b3f140dc203762ae29ed9250000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17513,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038664ea95a6464e5d70496e12b559a86e9fcc33400000000000000000000000038664ea95a6464e5d70496e12b559a86e9fcc3340000000000000000000000000000000000000000000000000000d78cdccfd00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17515,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b67eebe86182a234aae9001ee449b2bdaae1e3b6000000000000000000000000b67eebe86182a234aae9001ee449b2bdaae1e3b6000000000000000000000000000000000000000000000000002b15ec1c3092ef00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17516,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001556927ca1dd8b2e80112105d83fa6c5d7ea39550000000000000000000000001556927ca1dd8b2e80112105d83fa6c5d7ea39550000000000000000000000000000000000000000000000000000d78cdccfd00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17518,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000086cd2f687a86b3a7dca6c01a71a9b9e2f6e4a2eb00000000000000000000000086cd2f687a86b3a7dca6c01a71a9b9e2f6e4a2eb0000000000000000000000000000000000000000000000000000d7759458e80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17519,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008941471a1520bdd3208aa1d85fe9e989e0bef59e0000000000000000000000008941471a1520bdd3208aa1d85fe9e989e0bef59e0000000000000000000000000000000000000000000000000000d95e8619f00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17520,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000242743c00659e6a7f566de17ab7c47735bf9041f000000000000000000000000242743c00659e6a7f566de17ab7c47735bf9041f0000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17521,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fc55a58d67a5b8ff5a0be3a5029ff4ec93a7cb09000000000000000000000000fc55a58d67a5b8ff5a0be3a5029ff4ec93a7cb090000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17522,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000be5eb30e34716ae8b9ef8b712f6afeacd6b0e70d000000000000000000000000be5eb30e34716ae8b9ef8b712f6afeacd6b0e70d0000000000000000000000000000000000000000000000000000da301248180000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17523,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6f0f886028e694f6c6cc98a78d2576cdaac4269000000000000000000000000d6f0f886028e694f6c6cc98a78d2576cdaac4269000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17526,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003040ea8303133a1b063ac967c72c1604e1642bfb0000000000000000000000003040ea8303133a1b063ac967c72c1604e1642bfb0000000000000000000000000000000000000000000000000dd9f8050df59a0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x79a8272fe2873b6658dcd01733f63d4f9c41da91c24db2b6d02dc0ae02f37c0e,2021-11-23 05:51:28.000 UTC,0,true +17531,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d3b468d28e942bbc25570029a50aa102e0f2c18900000000000000000000000000000000000000000000000ae3192e2183dd3e32,0x5a31b61bec6e5c400fb6a7bc1914dd747b08263e825723648ba6b568bd6cea1c,2021-11-25 12:19:26.000 UTC,0,true +17534,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006fa39574ab01aa1d8e21f6f9f12a4ba80a788b020000000000000000000000006fa39574ab01aa1d8e21f6f9f12a4ba80a788b020000000000000000000000000000000000000000000000000206618aecb98a6700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x693bfd1669523560750b192d3d06e35016d7a5dd7e8629f65631b033ccdd226b,2021-12-26 00:44:17.000 UTC,0,true +17535,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009263de705ba26acd1fc0820ad85235c400f9cadf0000000000000000000000009263de705ba26acd1fc0820ad85235c400f9cadf0000000000000000000000000000000000000000000000000203a3f2c472980f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xe09261901c3a21362cb05901c1069c7113d88e52ab1ad2f02f2d7098626d3e02,2021-12-26 01:00:29.000 UTC,0,true +17536,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000067861906c5e9e8d6a8b2f523f5a2d5991524fe0000000000000000000000000067861906c5e9e8d6a8b2f523f5a2d5991524fe0000000000000000000000000000000000000000000000000002019f8f34c21fab00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x15b3716a07a918d1123774977659f2660637fa5796a4ec424e1185303941a624,2021-12-26 01:16:26.000 UTC,0,true +17540,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062accbf874fe1b42d3c473819c9053b663dc3c4900000000000000000000000062accbf874fe1b42d3c473819c9053b663dc3c4900000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17541,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e8fe9295cdd4fd2a6edd0cd47eafb6d61d8e50e10000000000000000000000000000000000000000000000047a045b29c30d0d36,,,1,true +17544,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0ac49961698a8c6ad87ecaf91f3b148a6c5571c000000000000000000000000a0ac49961698a8c6ad87ecaf91f3b148a6c5571c00000000000000000000000000000000000000000000000000422437cc48610000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17546,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d67507850ec643e33e4ee494c3e226fb62bcea12000000000000000000000000d67507850ec643e33e4ee494c3e226fb62bcea120000000000000000000000000000000000000000000000000000ded381f8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17547,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc7d9fe33903376798d63bfc39e9db8a1db7c887000000000000000000000000dc7d9fe33903376798d63bfc39e9db8a1db7c8870000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17548,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c10654f7479f68284f3a0415b7240d13912d7d50000000000000000000000006c10654f7479f68284f3a0415b7240d13912d7d50000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17549,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032a818fb907f2ef5e40138638d1f200a4456340200000000000000000000000032a818fb907f2ef5e40138638d1f200a445634020000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17551,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000df4c99f93c3130e3287384ad5fad660891abe4660000000000000000000000000000000000000000000000056bc75e2d63100000,0x65b862ecf2f4e490265e53e34a0a0a8d563eadb17863b136810c02fc92b7ee30,2021-11-23 08:02:09.000 UTC,0,true +17552,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cdeaad6d0c8c8ceb60cd286bf76a60e26961bb52000000000000000000000000cdeaad6d0c8c8ceb60cd286bf76a60e26961bb520000000000000000000000000000000000000000000000000000ded381f8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17553,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bc820741956b6315287004667aceddf3d15ea1bd000000000000000000000000bc820741956b6315287004667aceddf3d15ea1bd0000000000000000000000000000000000000000000000000000e702fbc5e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17554,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e2f47cbd9594d2eea0c00af354d9c325cdb7392c000000000000000000000000e2f47cbd9594d2eea0c00af354d9c325cdb7392c0000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17555,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000001dc4b7cd57245e46c6c93d1bf89f6fa9355640600000000000000000000000001dc4b7cd57245e46c6c93d1bf89f6fa935564060000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17556,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f66f75b42277a3a262b681b35329f45d725261bf000000000000000000000000f66f75b42277a3a262b681b35329f45d725261bf0000000000000000000000000000000000000000000000000000e61a2720d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17557,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000df642259ef722c58775ad4e2535d31fff4d75ad4000000000000000000000000df642259ef722c58775ad4e2535d31fff4d75ad40000000000000000000000000000000000000000000000000000ded381f8500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17558,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000413d1b2573237f0dad55851a93b0b376ab1607af000000000000000000000000413d1b2573237f0dad55851a93b0b376ab1607af0000000000000000000000000000000000000000000000000000dd01d8ae300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17559,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c1dc563d39a785ed7f0c2301b4d00245e33c53b0000000000000000000000000c1dc563d39a785ed7f0c2301b4d00245e33c53b0000000000000000000000000000000000000000000000000000db302f64100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17560,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002895b5b2616960f9d0cc324630ab0c6b1ab456880000000000000000000000002895b5b2616960f9d0cc324630ab0c6b1ab456880000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17561,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004ccefa8e656308fa7fdd7acf9509467266edf84d0000000000000000000000004ccefa8e656308fa7fdd7acf9509467266edf84d0000000000000000000000000000000000000000000000000000d95e8619f00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17562,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cef59e634b5536823037c15db7a9548ea996be4c000000000000000000000000cef59e634b5536823037c15db7a9548ea996be4c0000000000000000000000000000000000000000000000000000d92ff52c200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17563,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008ac4ad1976120b8b15da77e52d74932bd3184b940000000000000000000000008ac4ad1976120b8b15da77e52d74932bd3184b940000000000000000000000000000000000000000000000000000d8472087100000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17564,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000747c475abc7f6cd5bc273f989021d5a1e558e074000000000000000000000000747c475abc7f6cd5bc273f989021d5a1e558e0740000000000000000000000000000000000000000000000000000d5bb3385b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17565,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001c24eab3ca4e1feb7f7b43b152e7b7531bab21c70000000000000000000000001c24eab3ca4e1feb7f7b43b152e7b7531bab21c70000000000000000000000000000000000000000000000000000d4d25ee0a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17566,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008c0753dcdc2437febe0825ecad86ff65b0ac08850000000000000000000000008c0753dcdc2437febe0825ecad86ff65b0ac08850000000000000000000000000000000000000000000000000000d4d25ee0a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17567,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000291587abf4830f230001520c36dda1db6623deb4000000000000000000000000291587abf4830f230001520c36dda1db6623deb40000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17568,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ce40f28da9869bcaed42fa651cc6f58db0163c80000000000000000000000007ce40f28da9869bcaed42fa651cc6f58db0163c80000000000000000000000000000000000000000000000000000d95e8619f00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17569,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f65859f45f7f8e992adc3ba2481ec0e70333c756000000000000000000000000f65859f45f7f8e992adc3ba2481ec0e70333c7560000000000000000000000000000000000000000000000000000d875b174e00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17570,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c366cadd0773c6ff55b5916f19f382284ca30bcb000000000000000000000000c366cadd0773c6ff55b5916f19f382284ca30bcb0000000000000000000000000000000000000000000000000000d78cdccfd00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17571,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000caa0418a77461540be251b4ecf28cee88b5520a8000000000000000000000000caa0418a77461540be251b4ecf28cee88b5520a80000000000000000000000000000000000000000000000000000d72fbaf4300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17572,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000099301e83a0bf5429769a87850b1863ecb60f4f7e00000000000000000000000099301e83a0bf5429769a87850b1863ecb60f4f7e0000000000000000000000000000000000000000000000000000d718727d480000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17573,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f894e177535e411334889f0676671a24b14e6a5f0000000000000000000000000000000000000000000000007572edb17e893720,,,1,true +17574,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007f43909414ff1b9e8fcc531e87212378e4a3f9e4000000000000000000000000000000000000000000000025f59b68038128a1fc,0xa7f9d1f0188dd2cfce78e9596367bfbc9957ce2eee9d20f4602af4086ce4d711,2021-12-10 08:40:46.000 UTC,0,true +17575,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ebd39421e3ad3fbe2b1bf0f58366147536a07fc3000000000000000000000000ebd39421e3ad3fbe2b1bf0f58366147536a07fc30000000000000000000000000000000000000000000000000000d901643e500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17576,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f80bbbc1cbdc2db0f913d1b371e9d4eacba688d9000000000000000000000000f80bbbc1cbdc2db0f913d1b371e9d4eacba688d90000000000000000000000000000000000000000000000000000d546c933280000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17577,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007ff548c4858a9e9be5710f3cdeeeccdb6dc02fad0000000000000000000000007ff548c4858a9e9be5710f3cdeeeccdb6dc02fad00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17578,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d6129da37dad28b70ba29e542e3a0a074084c626000000000000000000000000000000000000000000000000210af52b11a048b2,,,1,true +17579,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ce2a930b5dc8357f25bed4970602ba49761b28c0000000000000000000000000ce2a930b5dc8357f25bed4970602ba49761b28c00000000000000000000000000000000000000000000000001589efb0c7d8c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17580,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cdc285f782cbab70d667dc04e50e21bb7de96437000000000000000000000000cdc285f782cbab70d667dc04e50e21bb7de9643700000000000000000000000000000000000000000000000000426ee3c6a1620000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17581,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000063aa434f9695989de6318e4e6bda9c2acc2075a900000000000000000000000063aa434f9695989de6318e4e6bda9c2acc2075a900000000000000000000000000000000000000000000000000425fc99f81000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17582,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000995a2db38b88571b9f9409a34ef0aed87a6fde56000000000000000000000000995a2db38b88571b9f9409a34ef0aed87a6fde56000000000000000000000000000000000000000000000000004307de78e4ab0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17583,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000208847658adf83d0ca5bf0503d80d6cb2694a760000000000000000000000000208847658adf83d0ca5bf0503d80d6cb2694a760000000000000000000000000000000000000000000000000004307de78e4ab0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17584,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000039b08619351aa6fd183b20841d86896c7f310ffb00000000000000000000000039b08619351aa6fd183b20841d86896c7f310ffb00000000000000000000000000000000000000000000000000430512849c4d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17586,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae9155be72fd213dbf5ad46308c7eafc63a71b16000000000000000000000000ae9155be72fd213dbf5ad46308c7eafc63a71b1600000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17587,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cfa9d627e4fe03dd1dd1de7dbb9fc352c555a6a1000000000000000000000000cfa9d627e4fe03dd1dd1de7dbb9fc352c555a6a10000000000000000000000000000000000000000000000000043512479197d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17588,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a0805d693ec6a4f0b12ad03482d41be896224a19000000000000000000000000a0805d693ec6a4f0b12ad03482d41be896224a19000000000000000000000000000000000000000000000000004281e843c0ae0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17589,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cddc9c5fa645bbb7d90e215c71e6902dea5c2e26000000000000000000000000cddc9c5fa645bbb7d90e215c71e6902dea5c2e260000000000000000000000000000000000000000000000000041e6b0ce104d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17590,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000adb5373a8bc60681ce12ca48c95d4ccf858bca8d000000000000000000000000adb5373a8bc60681ce12ca48c95d4ccf858bca8d0000000000000000000000000000000000000000000000000041d4cab2a78d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17591,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e63baca99ea0e6eb8b1da27b61a9e30c91d029a7000000000000000000000000e63baca99ea0e6eb8b1da27b61a9e30c91d029a7000000000000000000000000000000000000000000000000004297711cbab50000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17592,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000438ef5a483a2cd7bd4fb75475c361f2bc328f0af000000000000000000000000438ef5a483a2cd7bd4fb75475c361f2bc328f0af00000000000000000000000000000000000000000000000000426f72f77ca80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17593,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d954c95680b7070ddb196658acfdbf80491a55c9000000000000000000000000d954c95680b7070ddb196658acfdbf80491a55c90000000000000000000000000000000000000000000000000042f20e077d010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17594,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da5d39dcbb8ff4652d1d8c05dc3e648487036cef000000000000000000000000da5d39dcbb8ff4652d1d8c05dc3e648487036cef0000000000000000000000000000000000000000000000000041a929cfd8390000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17595,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000038190a55151d3a55446c2d69dd35c006de3f76fa00000000000000000000000038190a55151d3a55446c2d69dd35c006de3f76fa00000000000000000000000000000000000000000000000000422005dddbd40000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17596,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000035979754a0e1d42fd5fbe396689555f87a76f38e00000000000000000000000035979754a0e1d42fd5fbe396689555f87a76f38e00000000000000000000000000000000000000000000000000430b399e084f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17597,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a38f35b89cced1b3b94e6f46e58097f95a9d01fa000000000000000000000000a38f35b89cced1b3b94e6f46e58097f95a9d01fa0000000000000000000000000000000000000000000000000042ab93fb908d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17598,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000047ce2fb44be7188ff1d7ccc25b2c10934a1804af00000000000000000000000047ce2fb44be7188ff1d7ccc25b2c10934a1804af0000000000000000000000000000000000000000000000000042ab93fb908d0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17599,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000c9b9ff0acb9d5a621a16363b05fd82d47daa94b0000000000000000000000000c9b9ff0acb9d5a621a16363b05fd82d47daa94b0000000000000000000000000000000000000000000000000042fa2a4be8780000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17600,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000dae7939b5cf4f49eb8a041177c3ba95a2196d7c200000000000000000000000000000000000000000000000568f35e2631342b3e,,,1,true +17601,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f60c9808a0205535c6a211f2732c730157f163fc00000000000000000000000000000000000000000000000533082720db044846,0x06e384e7f7fd7271ce6788a0bb320cdef2b92f8ff112ac7689bafa0d19be91a8,2021-12-12 17:03:36.000 UTC,0,true +17603,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d5ae8b3d65d676e11a132b84a3ecbd1c5d4db97f000000000000000000000000d5ae8b3d65d676e11a132b84a3ecbd1c5d4db97f0000000000000000000000000000000000000000000000011125ff51c76f588d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x230dcfe2af2ddc08040fa00b95c199c45352b4298bc7b7cbc78ab4cd1466f3f3,2021-11-21 09:06:49.000 UTC,0,true +17604,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cae6223e0c70633b4f4afdef76ae9fa72e2cb545000000000000000000000000cae6223e0c70633b4f4afdef76ae9fa72e2cb545000000000000000000000000000000000000000000000000001ec425200ee20000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17608,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000647a8646a70c9e1f038fdc9fa2a190d5ead3ffe6000000000000000000000000000000000000000000000008b270d02c69b64356,0x743936c0cb629ce06f16e16e0d99b30c60ed1fde858cbc569d3350a50f109bf5,2021-11-23 20:06:39.000 UTC,0,true +17609,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082cea2d73bdd35fd7980ed975020fb5a565ea26e00000000000000000000000082cea2d73bdd35fd7980ed975020fb5a565ea26e000000000000000000000000000000000000000000000000004b1c6c6736f5c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17610,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001e52e505b4dd582a17fb7697026a6296fd33f7b00000000000000000000000001e52e505b4dd582a17fb7697026a6296fd33f7b0000000000000000000000000000000000000000000000000003de9158c1633b200000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9e2870c950e5e77e532719e7a488c35e76687747054a62b60eb2d41e21d60828,2022-04-23 11:03:39.000 UTC,0,true +17616,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008252f2300d09319fe4100bdfd8ad624adff3d05f0000000000000000000000008252f2300d09319fe4100bdfd8ad624adff3d05f00000000000000000000000000000000000000000000000006ddfccf25d88c4500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x35542b5be56e7eaecd328270942643d4c11d92afd19e09cf9dc62e6ff75b7b13,2021-12-15 01:08:27.000 UTC,0,true +17617,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009cec4f45144c8a594f634c586545af0ca51f47890000000000000000000000009cec4f45144c8a594f634c586545af0ca51f478900000000000000000000000000000000000000000000000000127bf889ee664000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17619,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006177c71d568960d87e958c38000350ed3276796b0000000000000000000000006177c71d568960d87e958c38000350ed3276796b00000000000000000000000000000000000000000000000000ec0d07dabbbd4f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17620,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006bba96d2fcf9e4730014b0f7f3f0f89f96a5d9240000000000000000000000006bba96d2fcf9e4730014b0f7f3f0f89f96a5d92400000000000000000000000000000000000000000000000007f8ec9de9a21b5800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17623,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000994317196b32c1d73a38e0fcfee08db0f624e325000000000000000000000000994317196b32c1d73a38e0fcfee08db0f624e3250000000000000000000000000000000000000000000000000000d6a4082ac00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17624,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000b73db6bd2539258d380daa13d9937fefc543b700000000000000000000000000b73db6bd2539258d380daa13d9937fefc543b7000000000000000000000000000000000000000000000000002a8dd53dfe7dc8c00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17625,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c16dfe34d78246ae49f4098630cfbc90c78df161000000000000000000000000c16dfe34d78246ae49f4098630cfbc90c78df16100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17626,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f57c86041a7c5eedf5478d324292fcb08e427a26000000000000000000000000f57c86041a7c5eedf5478d324292fcb08e427a260000000000000000000000000000000000000000000000000000d5bb3385b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17627,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008be625b3a8e6d6a4ad226a53790248fc3ca703a40000000000000000000000008be625b3a8e6d6a4ad226a53790248fc3ca703a400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17628,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006acb872f1eb512c9df43306e6e80f4ea5398a8660000000000000000000000006acb872f1eb512c9df43306e6e80f4ea5398a86600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17629,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000901d13f8b0ddfcc460a095ca75f998e5640e4471000000000000000000000000901d13f8b0ddfcc460a095ca75f998e5640e44710000000000000000000000000000000000000000000000000000d6a4082ac00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17630,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000087d617dbb2d58119a5be94aedd7f858d27f5bba700000000000000000000000087d617dbb2d58119a5be94aedd7f858d27f5bba70000000000000000000000000000000000000000000000000e4e36646bcb664d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x9fd9883797c1fc70edc643f69b76a7b466db59d6a60c6db6912208fbef019fd2,2021-11-25 20:27:48.000 UTC,0,true +17631,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c84ed7674a9d57db75d4deb938c0396f97aa3cbd000000000000000000000000c84ed7674a9d57db75d4deb938c0396f97aa3cbd00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17632,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dfe70bbe4ddf055de55ca27ad1625c2d4cc11b48000000000000000000000000dfe70bbe4ddf055de55ca27ad1625c2d4cc11b4800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17633,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c5f2cd0780c0f6a45928870347a21993c1575d51000000000000000000000000c5f2cd0780c0f6a45928870347a21993c1575d5100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17634,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000833838849c09b66fe1951b526e15b2d530d69b5e000000000000000000000000833838849c09b66fe1951b526e15b2d530d69b5e0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17635,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000071b55d92acbe7afac302f639b090f9b99262418200000000000000000000000071b55d92acbe7afac302f639b090f9b9926241820000000000000000000000000000000000000000000000000000640b5eece00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17636,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010fe0a48058551d3db4fd064e085a106d2d4d83200000000000000000000000010fe0a48058551d3db4fd064e085a106d2d4d83200000000000000000000000000000000000000000000000000006d23ad5f800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17637,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d1059b4bc5c4816c0db0c86c9995d3b6b1d274f1000000000000000000000000d1059b4bc5c4816c0db0c86c9995d3b6b1d274f10000000000000000000000000000000000000000000000000000640b5eece00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17638,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d3bae088a07a1d2cf608c332b40eafaa42a7863b000000000000000000000000d3bae088a07a1d2cf608c332b40eafaa42a7863b0000000000000000000000000000000000000000000000000000763bfbd2200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17639,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e9176aaa4a4b13a4405213a652616a41e405179f000000000000000000000000e9176aaa4a4b13a4405213a652616a41e405179f00000000000000000000000000000000000000000000000000005f7f37b3900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17640,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e37232d5a120f8d7d32fc8281f4c95e6442ce4a0000000000000000000000000e37232d5a120f8d7d32fc8281f4c95e6442ce4a000000000000000000000000000000000000000000000000000005dad8e69700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17641,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006589098a35aef96eaa06ecaed3a47410e7e4594f0000000000000000000000006589098a35aef96eaa06ecaed3a47410e7e4594f00000000000000000000000000000000000000000000000000005e96630e800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17642,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ef61e9ea2f9ebb5d102b00dca72391817539bb23000000000000000000000000ef61e9ea2f9ebb5d102b00dca72391817539bb2300000000000000000000000000000000000000000000000000005cc4b9c4600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17643,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ce903173d0096ac33f351b142606edbddfc03410000000000000000000000005ce903173d0096ac33f351b142606edbddfc03410000000000000000000000000000000000000000000000000000640b5eece00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17644,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000591564d8a2f1f09f0dc25ba3af8ffc1fa9aa6686000000000000000000000000591564d8a2f1f09f0dc25ba3af8ffc1fa9aa668600000000000000000000000000000000000000000000000000005cc4b9c4600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17645,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ee02ab46e6d8df72ebe5d81fdc8780f932465430000000000000000000000006ee02ab46e6d8df72ebe5d81fdc8780f9324654300000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17646,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ebfef2cc9ba3465b69a05e67a1ea51e3037be94f000000000000000000000000ebfef2cc9ba3465b69a05e67a1ea51e3037be94f00000000000000000000000000000000000000000000000000005f7f37b3900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17647,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000508a0453ab8e74ef700ef9b36e3ebd108ce19214000000000000000000000000508a0453ab8e74ef700ef9b36e3ebd108ce1921400000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17648,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004eb23a048fca4b24bbbd646feb36abbb870d0a0a0000000000000000000000004eb23a048fca4b24bbbd646feb36abbb870d0a0a000000000000000000000000000000000000000000000000000060680c58a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x50eaafb1aa1334bbb7dc1edd29f9f927601944bef915cb7b9a5609fa4b4c5f31,2021-11-21 13:20:15.000 UTC,0,true +17649,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b039029da896c6e27dcd61350de3bacbca68049d000000000000000000000000b039029da896c6e27dcd61350de3bacbca68049d00000000000000000000000000000000000000000000000000005dad8e69700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17650,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f49a5879c87e37cb3f5b79aea04d85ee7c46ee53000000000000000000000000f49a5879c87e37cb3f5b79aea04d85ee7c46ee530000000000000000000000000000000000000000000000000000d78cdccfd00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17651,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006802b763e09fc2a32132b41763d65573671a59c90000000000000000000000006802b763e09fc2a32132b41763d65573671a59c90000000000000000000000000000000000000000000000000000d5bb3385b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17652,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006c7298aa9ae1d86a00fe1af854173899839956de0000000000000000000000006c7298aa9ae1d86a00fe1af854173899839956de0000000000000000000000000000000000000000000000000000d5e9c473800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17653,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000bf70ff80e909e9c1714f25acf87c0f2efc472a44000000000000000000000000bf70ff80e909e9c1714f25acf87c0f2efc472a440000000000000000000000000000000000000000000000000000d5e9c473800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17654,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ee00b658f24281a7c829ba8071bf8672cff148f0000000000000000000000006ee00b658f24281a7c829ba8071bf8672cff148f0000000000000000000000000000000000000000000000000000d6010cea680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17655,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005287d3237af69a73c026128b71de866743d606cb0000000000000000000000005287d3237af69a73c026128b71de866743d606cb0000000000000000000000000000000000000000000000000000d5a3eb0ec80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17657,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002fd77c4db86278bcc62a3e62184ebaa901de85170000000000000000000000002fd77c4db86278bcc62a3e62184ebaa901de85170000000000000000000000000000000000000000000000000000d5bd8791940000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17658,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006d903a8e1e6bb1b41bb09cd683c415b49c003a090000000000000000000000006d903a8e1e6bb1b41bb09cd683c415b49c003a0900000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17659,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000007a7ffb798f9c883bc1f1867183422d096e1929d50000000000000000000000007a7ffb798f9c883bc1f1867183422d096e1929d500000000000000000000000000000000000000000000000000005f7f37b3900000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17660,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b393d37d67c21e9a3e56baa82c297de0636c7f3e000000000000000000000000b393d37d67c21e9a3e56baa82c297de0636c7f3e00000000000000000000000000000000000000000000000000006d23ad5f800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17661,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010343e645d7bad425466d47a0eb138f7c734d2aa00000000000000000000000010343e645d7bad425466d47a0eb138f7c734d2aa0000000000000000000000000000000000000000000000000000640b5eece00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17662,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b70dd5dfbfdb5fbeb635f5ded1732d0a04f4c03b000000000000000000000000b70dd5dfbfdb5fbeb635f5ded1732d0a04f4c03b00000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17663,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006239bd9e155037c2df077146a02d563158d50bfa0000000000000000000000006239bd9e155037c2df077146a02d563158d50bfa00000000000000000000000000000000000000000000000000005cc4b9c4600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17664,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002d5f17408bf60b9ead22abc40cefb6302c816ec40000000000000000000000002d5f17408bf60b9ead22abc40cefb6302c816ec40000000000000000000000000000000000000000000000000000d4e9a757880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17665,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000af0586105adc69145f0b82e03a4ece3a26b76bd7000000000000000000000000af0586105adc69145f0b82e03a4ece3a26b76bd7000000000000000000000000000000000000000000000000000060680c58a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17666,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000d6b168747c39db417c54e187e415965ae0353a0c000000000000000000000000d6b168747c39db417c54e187e415965ae0353a0c00000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17668,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005956ad429bc34e333616924642d192a876ca15ce0000000000000000000000005956ad429bc34e333616924642d192a876ca15ce0000000000000000000000000000000000000000000000000000d4d25ee0a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17669,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c16872483ce63168d61d5f192a6969ad1e3a9867000000000000000000000000c16872483ce63168d61d5f192a6969ad1e3a986700000000000000000000000000000000000000000000000000005e96630e800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17670,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e4c51ae64abb97b0d10329d04d873fd15992d00b000000000000000000000000e4c51ae64abb97b0d10329d04d873fd15992d00b00000000000000000000000000000000000000000000000000006239b5a2c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17671,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000593988afd7905c358aba6f59357e7f7c5b6a19b6000000000000000000000000593988afd7905c358aba6f59357e7f7c5b6a19b60000000000000000000000000000000000000000000000000000d646e64f200000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17672,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000288478fec717c0bab68140afaf1e9cc8b2be3f74000000000000000000000000288478fec717c0bab68140afaf1e9cc8b2be3f7400000000000000000000000000000000000000000000000000006150e0fdb00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17673,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005fcf5a55f97bca62601f68c6f79e3515cb8b9f8f0000000000000000000000005fcf5a55f97bca62601f68c6f79e3515cb8b9f8f00000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17674,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e920476bdd6c73a250ee0b8ed68ca8e24125bbda000000000000000000000000e920476bdd6c73a250ee0b8ed68ca8e24125bbda000000000000000000000000000000000000000000000000000063228a47d00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17675,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011cdb59e1f91948a261d2e8926621acf54d53f1300000000000000000000000011cdb59e1f91948a261d2e8926621acf54d53f1300000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17676,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b5bf8de51dc8adb18622edef0a1ce6f443eda841000000000000000000000000b5bf8de51dc8adb18622edef0a1ce6f443eda8410000000000000000000000000000000000000000000000000000640b5eece00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17677,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cf595ac2e61987f2b22146be5f6ef702078703dc000000000000000000000000cf595ac2e61987f2b22146be5f6ef702078703dc00000000000000000000000000000000000000000000000000005dad8e69700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17678,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005417828ee95a0f5a2d32ad97e88701a936de307d0000000000000000000000005417828ee95a0f5a2d32ad97e88701a936de307d0000000000000000000000000000000000000000000000000000da475abf000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17679,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000055d0df9f252ec80062ffc326092b3f5892a5ae3300000000000000000000000055d0df9f252ec80062ffc326092b3f5892a5ae3300000000000000000000000000000000000000000000000000005cc4b9c4600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17680,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000096bb7ead27b65e3f4d449d0430169d69304631f000000000000000000000000096bb7ead27b65e3f4d449d0430169d69304631f00000000000000000000000000000000000000000000000000006150e0fdb00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17681,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000dc2919189be897058e49572a4c9a6d327cb9b9bf000000000000000000000000dc2919189be897058e49572a4c9a6d327cb9b9bf0000000000000000000000000000000000000000000000000000640b5eece00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17682,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000010607c953c0e84ea4deea9c9716d39e6f1a801ee00000000000000000000000010607c953c0e84ea4deea9c9716d39e6f1a801ee00000000000000000000000000000000000000000000000000006239b5a2c00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17683,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a83b5cd66634f717e6e1737e703e273ee9296813000000000000000000000000a83b5cd66634f717e6e1737e703e273ee92968130000000000000000000000000000000000000000000000000000d4e9a757880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17684,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000144457a28850f5802161308179bd22523a9f2e6b000000000000000000000000144457a28850f5802161308179bd22523a9f2e6b00000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17685,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006ea35561e6b432f182b8b9ce7ea8361def921b940000000000000000000000006ea35561e6b432f182b8b9ce7ea8361def921b9400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17686,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000f4209c9460d8ce4c56ccb558d0c14d8d39dd63c6000000000000000000000000f4209c9460d8ce4c56ccb558d0c14d8d39dd63c600000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17687,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001682eb55f4a712c9145fc4c1cca6d59e41493b510000000000000000000000001682eb55f4a712c9145fc4c1cca6d59e41493b51000000000000000000000000000000000000000000000000000060680c58a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17688,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000011a9a257bd5294e4bae1633210e1636ab145547100000000000000000000000011a9a257bd5294e4bae1633210e1636ab145547100000000000000000000000000000000000000000000000000005dad8e69700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17689,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000689fcd7f101d31237c489b6e423716b72b6ef64a000000000000000000000000689fcd7f101d31237c489b6e423716b72b6ef64a00000000000000000000000000000000000000000000000000005cc4b9c4600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17690,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000084081666479f10be36c5f4c41fa6706e02f3fa0c00000000000000000000000084081666479f10be36c5f4c41fa6706e02f3fa0c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17691,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000057a4cde8e7672372eb02f9f51a2fe2325f5a052300000000000000000000000057a4cde8e7672372eb02f9f51a2fe2325f5a05230000000000000000000000000000000000000000000000000000d5d27bfc980000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17692,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000e3bccd993bf5debafb948a6259f61a67715b4657000000000000000000000000e3bccd993bf5debafb948a6259f61a67715b465700000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17693,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000747f475a83a68d32ba92c6337460f95cd5a74d60000000000000000000000000747f475a83a68d32ba92c6337460f95cd5a74d6000000000000000000000000000000000000000000000000000a3614784bc32c900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17694,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000e910a91f98ca9b5848b16d5c294645a2c4ba64300000000000000000000000000000000000000000000000a650e6d0a8be6f50e,0x6afa7b3deeead4c9b2a8631daf687946a3824e91f8b20e3755109c7680c3fad9,2021-11-23 09:04:42.000 UTC,0,true +17695,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005776cc5782c4ca0a659f7385c14d0f52492ea5490000000000000000000000005776cc5782c4ca0a659f7385c14d0f52492ea54900000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17696,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3f1a4128d164cc1500587aabdc32d7131f3703d000000000000000000000000b3f1a4128d164cc1500587aabdc32d7131f3703d00000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17697,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000c1361c64d69117b4058b71e344557e5e0d0cd276000000000000000000000000c1361c64d69117b4058b71e344557e5e0d0cd276000000000000000000000000000000000000000000000000000060680c58a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17698,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000979bdc6c454b2038fe33abe90b999124ee588258000000000000000000000000979bdc6c454b2038fe33abe90b999124ee58825800000000000000000000000000000000000000000000000000005cc4b9c4600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17699,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005bbe723821532eabb68e76dc12a7ca4332f609a20000000000000000000000005bbe723821532eabb68e76dc12a7ca4332f609a20000000000000000000000000000000000000000000000000000640b5eece00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17700,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000003bdde7e7eb133a322ef4a39ef663098bc4d9bb100000000000000000000000003bdde7e7eb133a322ef4a39ef663098bc4d9bb100000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17701,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000026233240d673eb9953fe38001464a1d273b786e800000000000000000000000026233240d673eb9953fe38001464a1d273b786e80000000000000000000000000000000000000000000000000000d5755a20f80000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17702,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000082558ce1f4e88934990f82aba844898644d3fdb800000000000000000000000082558ce1f4e88934990f82aba844898644d3fdb8000000000000000000000000000000000000000000000000015d7f228069020000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17703,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051b7ee88658b7d0d2a41d6d73c920ec85f444aff00000000000000000000000051b7ee88658b7d0d2a41d6d73c920ec85f444aff0000000000000000000000000000000000000000000000000000d217e0f1700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17704,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000004a6938047817a26df223fc4aac88fe14ce3488c00000000000000000000000004a6938047817a26df223fc4aac88fe14ce3488c0000000000000000000000000000000000000000000000000000d300b596800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17705,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000fac62c8aeac063bed226a7cfc278c126056d7c82000000000000000000000000fac62c8aeac063bed226a7cfc278c126056d7c8200000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17706,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008d5a9bbdf1ee8e974000dec395c73d3ce8a205b20000000000000000000000008d5a9bbdf1ee8e974000dec395c73d3ce8a205b2000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17707,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000005ac368c62141a4acbd5a48302cae2a56052730530000000000000000000000005ac368c62141a4acbd5a48302cae2a56052730530000000000000000000000000000000000000000000000000000d3468efb380000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17708,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000ae1b882c3455be57d40067930b6a2d9233d9330c000000000000000000000000ae1b882c3455be57d40067930b6a2d9233d9330c00000000000000000000000000000000000000000000000004064976a8dd000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17709,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000caf207c77249f768cbf59af0b26b7a39ccc0ec9c000000000000000000000000caf207c77249f768cbf59af0b26b7a39ccc0ec9c0000000000000000000000000000000000000000000000000000d42f63a0480000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17710,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000006fb9878c67cade394e00c8a7e3195f05c4f3ba700000000000000000000000006fb9878c67cade394e00c8a7e3195f05c4f3ba700000000000000000000000000000000000000000000000000000d217e0f1700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17711,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003c3248a43eef8f341e6a3549354ed05024f1e6ea0000000000000000000000003c3248a43eef8f341e6a3549354ed05024f1e6ea0000000000000000000000000000000000000000000000000000d15d9d3a300000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17712,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ec39e27bed0d40c5bfdd8203665c0e85f18e11fb000000000000000000000000000000000000000000000000967f37f7dc333359,0x98cea5dcd4fa997186086fadedebacd4d0537bf07932fc5110e76f2a598de405,2022-02-15 11:24:39.000 UTC,0,true +17713,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e675000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000017acd2acc73685ee4a4bc28682f64965cb865c3a00000000000000000000000017acd2acc73685ee4a4bc28682f64965cb865c3a00000000000000000000000000000000000000000000000000000000306a2ccd00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,0x279af99476cac91cf33770e39522b24727a324f03eb05bb6c659b6c653723ca8,2021-11-26 01:39:13.000 UTC,0,true +17715,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b3bc73d79d21a97ae50a35af976ce4b9eb87b6f7000000000000000000000000b3bc73d79d21a97ae50a35af976ce4b9eb87b6f700000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17716,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b8551df8f9e8029d8a951fc549c90718b4ea8248000000000000000000000000b8551df8f9e8029d8a951fc549c90718b4ea824800000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17722,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0381dc10bb93f63b236a9f8e3dc409fcd39d810000000000000000000000000b0381dc10bb93f63b236a9f8e3dc409fcd39d810000000000000000000000000000000000000000000000000003e8e98e5eca34300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17724,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0xa9f9e6750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000068f180fcce6836688e9084f035309e29bf0a2095000000000000000000000000c1c0db07907fa2eca68e9f62fac22a4fff7b8782000000000000000000000000c1c0db07907fa2eca68e9f62fac22a4fff7b8782000000000000000000000000000000000000000000000000000000000012557700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000,,,1,true +17728,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000080017970f4e68348b560c9acc4a0f8322decf5b900000000000000000000000080017970f4e68348b560c9acc4a0f8322decf5b900000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17729,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000da917846074acdf397e213daa701f9556a4f5618000000000000000000000000da917846074acdf397e213daa701f9556a4f561800000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17730,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000044e9d9473fd2cefae44e06e7b4b0c4a42024341300000000000000000000000044e9d9473fd2cefae44e06e7b4b0c4a42024341300000000000000000000000000000000000000000000000000005cc4b9c4600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17731,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000062addcc4091ea31b7d9b6f91e23a791aa1add17500000000000000000000000062addcc4091ea31b7d9b6f91e23a791aa1add17500000000000000000000000000000000000000000000000000005dad8e69700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17732,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000032713864132d941be23f3f6fe41441a87a80d07600000000000000000000000032713864132d941be23f3f6fe41441a87a80d07600000000000000000000000000000000000000000000000000005e96630e800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17733,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000ed7a5f34d0ed6a513bec66675bd789123ef4fa80000000000000000000000000ed7a5f34d0ed6a513bec66675bd789123ef4fa800000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17734,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001867aa355db059d649ab84cedd7f0403d11d6a37000000000000000000000000000000000000000000000030940660a8bc5a7589,,,1,true +17735,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000002e2de0ef24d9f2d067fb49dd180dd305889691e50000000000000000000000002e2de0ef24d9f2d067fb49dd180dd305889691e500000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17736,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000d20fc3c32b213a39b0314ce804ba33aa5c6ed6f00000000000000000000000000000000000000000000000010ad87b3960ea127,,,1,true +17737,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000722154a260198d161abde4598b9bb9f711483ea1000000000000000000000000722154a260198d161abde4598b9bb9f711483ea100000000000000000000000000000000000000000000000000005cc4b9c4600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17738,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b51e532ca2399f1d0acbc83b78768fb33a9fa50d000000000000000000000000b51e532ca2399f1d0acbc83b78768fb33a9fa50d00000000000000000000000000000000000000000000000000006150e0fdb00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17739,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000015d3b70b2021603716340038d096526000caad9000000000000000000000000015d3b70b2021603716340038d096526000caad9000000000000000000000000000000000000000000000000000005cc4b9c4600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17740,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a1649324e76f33a91a9d09dcc8f1c2764bebaf6a000000000000000000000000a1649324e76f33a91a9d09dcc8f1c2764bebaf6a00000000000000000000000000000000000000000000000000005bdbe51f500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17741,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000001b526248ba302e9a1ab4a29261aec7cc7317a9440000000000000000000000001b526248ba302e9a1ab4a29261aec7cc7317a94400000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17742,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000008f4db9b455e10895108e941232ed7281419b4dad0000000000000000000000008f4db9b455e10895108e941232ed7281419b4dad000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17743,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000820a2b3993308fd2590f7c3d0cb25a885a7be0f6000000000000000000000000820a2b3993308fd2590f7c3d0cb25a885a7be0f60000000000000000000000000000000000000000000000000000092f96e9880000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17744,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000cb060cfc1662d1ff1df9299c63baaf3e7fb5515f000000000000000000000000cb060cfc1662d1ff1df9299c63baaf3e7fb5515f00000000000000000000000000000000000000000000000000000946df60700000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17747,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a000d1947e1fa6fa9f3442bb5c2a365216bb0f22000000000000000000000000a000d1947e1fa6fa9f3442bb5c2a365216bb0f22000000000000000000000000000000000000000000000000001e9b97c9f58f0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x5fb9aefb66c1eb8117bfd0dd8db6091fc31ca359c68c4f38aec29c7c9288d846,2021-11-26 04:15:18.000 UTC,0,true +17748,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007b3d4f79b24d19d992f36d019a0c0e9de22afa0200000000000000000000000000000000000000000000000678c82ea01d5f4436,,,1,true +17749,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000a98d2867de6b1dff44fe4b355dea098e81d06aeb000000000000000000000000a98d2867de6b1dff44fe4b355dea098e81d06aeb00000000000000000000000000000000000000000000000003961cfdebfe570000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17750,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000043548d5f1c42ea85f4cbd9d03030a3eb56e6f9a600000000000000000000000043548d5f1c42ea85f4cbd9d03030a3eb56e6f9a6000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17752,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000388d73beb86e297e420a5bdc6aeb43e787d02338000000000000000000000000388d73beb86e297e420a5bdc6aeb43e787d02338000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17753,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000370e104682930977667999c7af343ed04b77c923000000000000000000000000370e104682930977667999c7af343ed04b77c92300000000000000000000000000000000000000000000000001b778519606153800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x27128ff82784f78d3230891cc2d7a8e9ab00ec2c85b3cab4c24c09212f0acf01,2021-12-14 14:22:10.000 UTC,0,true +17756,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007ff916da10365f3456174e8250021f27b66cf9300000000000000000000000000000000000000000000000006097753aa83830bf,,,1,true +17757,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000048c3ce879d2ba290aa9dc1dcab243edad3b143050000000000000000000000000000000000000000000000001967fe394e1292d3,,,1,true +17758,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000057fb6c359c8cf9caf0ec8beac0c8b944cb63d9b80000000000000000000000000000000000000000000002bfa18b4ac514af2400,0x4f7317c1422bb0976f14e8c5b572e8ea40add2c1a2a27a849c72a68fef518bb2,2021-11-22 01:43:33.000 UTC,0,true +17759,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f1d80f08df95f254cb7e6e075ad7265a5b85b92a000000000000000000000000000000000000000000000004a594fefcda61d57c,0xaa67680d66db50865ed3facc5a38b428c2fd190c0178a64c00fe245e9843890c,2022-03-30 20:37:07.000 UTC,0,true +17760,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000035c610124f469593469a025d712adc13f819fa5400000000000000000000000000000000000000000000000be8060f61577b3236,,,1,true +17763,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000051004a19e236fd098ba15888b8eb6a050a3fde4000000000000000000000000051004a19e236fd098ba15888b8eb6a050a3fde40000000000000000000000000000000000000000000000000020623adcc644c7d00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x35630d101d2fc72a46a2d2d3ae58fa4b028b413a708ff6617f8fb19e46fda121,2021-12-30 09:38:18.000 UTC,0,true +17766,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000003a3cfb013e07ca672329ec3e96da5eba2f780d7c0000000000000000000000003a3cfb013e07ca672329ec3e96da5eba2f780d7c0000000000000000000000000000000000000000000000000000d12f0c4c600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17767,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000000d87d1de05588fb27c71c9d267c15c4afa51d92b0000000000000000000000000d87d1de05588fb27c71c9d267c15c4afa51d92b0000000000000000000000000000000000000000000000000000d12f0c4c600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17768,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000009b73de47db0e52bc9951cef9dc3bedb1696f7c570000000000000000000000009b73de47db0e52bc9951cef9dc3bedb1696f7c570000000000000000000000000000000000000000000000000000d04637a7500000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17769,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000364d9fb3c4bb5e3b8c4f91e37fc1bb290013dfd8000000000000000000000000364d9fb3c4bb5e3b8c4f91e37fc1bb290013dfd800000000000000000000000000000000000000000000000001332da4e18a600000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17773,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b8972e9db4c65a681312b85b12827d0426b655f4000000000000000000000000000000000000000000000000052afb1baf876dfb,,,1,true +17775,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000063ff748023fbdf4dcae4ea3d11668784f176bbfb00000000000000000000000000000000000000000000000f90739fd376670000,0x6353cc64508bfa0f60146e485a2f9850d957bb9e7d912da194cd2cd6673fb7f6,2021-12-03 06:20:17.000 UTC,0,true +17776,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b462fb0098f104e88837a46e5f4fdfb5ebff7d96000000000000000000000000000000000000000000000014998f32ac78700000,0x56e4c807e24095a15f8744dc52ca8dfd7fb428da81a76c372cd6aa892483343a,2021-12-19 21:34:31.000 UTC,0,true +17780,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007267168be3688b533b4e815fb8c38389b33e34b500000000000000000000000000000000000000000000000054ab228d2989a16a,,,1,true +17781,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec3400000000000000000000000031a41cd29d962f56be639f35a14a6c99faf1bcb800000000000000000000000031a41cd29d962f56be639f35a14a6c99faf1bcb800000000000000000000000000000000000000000000000000ac1ef607918c0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17782,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000048c3ce879d2ba290aa9dc1dcab243edad3b14305000000000000000000000000000000000000000000000000ce175f96a5f14b9b,,,1,true +17783,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000043d16ccd581e1d6a8d51768f75ddf09b79f4f8560000000000000000000000000000000000000000000000001ff2f8f1b68c6529,,,1,true +17785,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000098a3da6293e56674d250fa9ada4c684dc34e4e0b00000000000000000000000000000000000000000000006eaad5974a3b2bac1c,0x4ce0094158a2bf9eded0bf7b92ff70f8dc73c8c036cdfb876327f61992e02c21,2021-12-02 07:51:12.000 UTC,0,true +17786,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000dc899fb367312f3a3a0532b8b31a0744de11968200000000000000000000000000000000000000000000000053d7c06e75ba2572,,,1,true +17787,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001e69ef2d9be1ad7468d6a305ad01d347f12f6d400000000000000000000000000000000000000000000000002a0dd9d1b77d683e,,,1,true +17788,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000864121c7335bcd61b545b81e19757e2d7ad4263f0000000000000000000000000000000000000000000000000a219e89d25c2fac,,,1,true +17790,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f0692d3344987619906f9299c4e0f8f43312db160000000000000000000000000000000000000000000000457bd4d3bb19d2383f,0x604d89243b4e0a0becaa5f2e3a97e047c348356734895ab67205a8253fc6ebea,2022-04-01 00:03:33.000 UTC,0,true +17791,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000056bcfe33f5c6dfa62b6d3d3cf5a957429828bb0000000000000000000000000000000000000000000000922d9e006f3c329c3c,,,1,true +17792,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000022510fe99f63ae03ba792c21a29ec10fd87cae0800000000000000000000000000000000000000000000003d8eb4f7fe10a1d963,0x7f66c55dcef9d6264a6c3f30d182d1605037897b3af10035bc52c3a35d41f20b,2021-11-21 08:15:33.000 UTC,0,true +17794,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007c95d0cd038e06c4152a37325d48aed406006fe300000000000000000000000000000000000000000000001eca955e9b65e00000,0x537c10e6364176e4b6616eb8d63f2e9cec3d26e807e50bc0c0b2de5689848607,2021-12-06 13:38:54.000 UTC,0,true +17795,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000fc830cd343857a3befc4dc53828846ce97ca13a900000000000000000000000000000000000000000000001ae9841c04024c8182,0x18de24dcbea5428dc53fba4a843f0bec556b4935184198e2f2a3b5bd25416b55,2022-01-04 14:10:11.000 UTC,0,true +17796,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a0ac9d14049246430921aa9c23f12a20a1b88edf77c3dc89f68795c5cdf32fc8b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000373ea25ad2ca66b780000000000000000000000000000000000000000000000000000000061840df0,,,1,true +17797,0x3d4cc8a61c7528fd86c55cfe061a78dcba48edd1,0x7191061d5d4c60f598214cc6913502184baddf18,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a1d198484f8ebf55f2ba49dcd64b24031069cddb5e09776f57be566394d69f817000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000013a29300b6604b6951da0000000000000000000000000000000000000000000000000000000061841b96,,,1,true +17798,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008705e42eb5cbf3581fc1716dffebb88f20dc6626000000000000000000000000000000000000000000000008751aac59e6aafcf1,0xf58ee4737252966e691115c589a87533daf6bd75207e4b56150b173d10fbbe09,2021-11-27 19:21:56.000 UTC,0,true +17799,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ae002060bf60efcba93cc32236e45da2b1067d640c3a9f43eb2b0a982eadcd71e00000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000000000003531e8b22d0000000000000000000000000000000000000000000000000000000061846454,,,1,true +17800,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000142a39c156f814aa0c5d54f4636c4e5fec708b8700000000000000000000000000000000000000000000002a54bf87c5ff470000,0x9d46d96587ea4323fc6417afa72c27efe145ce76b932620b181166aae5f082c1,2021-11-23 05:51:28.000 UTC,0,true +17801,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a8df3be8957a6b70db6353c4e1ddf58f05d089a02d80b7009e7088718913ffbd9000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000023145bc97697a33700000000000000000000000000000000000000000000000000000000061848206,,,1,true +17802,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000000efa5c7ba17a797a867820ffd51b890125bda3600000000000000000000000000000000000000000000002870d46785c9680000,0x61f0a5c9956e24989160fc7df5156de1e3c98f278ac15ea043fb05b2d592cc19,2022-02-13 20:28:36.000 UTC,0,true +17803,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000028a2106e8005336adddf006d790608e2a8853d740000000000000000000000000000000000000000000000410f9c5fdf48a2ba37,0x6237f01973017cf8aadf2fb45d98f42f1cdb7e6d3ccee2dd62029be725c6802c,2021-11-21 11:59:42.000 UTC,0,true +17804,0x3d4cc8a61c7528fd86c55cfe061a78dcba48edd1,0x7191061d5d4c60f598214cc6913502184baddf18,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ac4264f89b9a32664405896f8b1b8347b308b8db97e69ba770e86368f4ea15fe8000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000211b73c4314ee2afff3e000000000000000000000000000000000000000000000000000000006184c052,,,1,true +17805,0x3e4a3a4796d16c0cd582c382691998f7c06420b6,0x46ae9bab8cea96610807a275ebd36f8e916b5c61,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ad45d93738601e54d2bd02b758c72598ea20b84ed6da07f981dc26a4978a91c7a000000000000000000000000000000000000000000000000000000000000a4b100000000000000000000000000000000000000000000000000000018a2c377dd0000000000000000000000000000000000000000000000000000000061850694,,,1,true +17806,0x3e4a3a4796d16c0cd582c382691998f7c06420b6,0x46ae9bab8cea96610807a275ebd36f8e916b5c61,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a1a793500fe911e8d9320f1c9c3885fa913d0534c54d018d08c0c626a3e3bfb28000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000000000002e77151a100000000000000000000000000000000000000000000000000000000061851dfb,,,1,true +17807,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a4c26d3e35f39b7e73a2d05cf72b13546de5d2afb0ba62844d85b182d1c8065440000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002bf58d12bbbd03ae10000000000000000000000000000000000000000000000000000000061853d13,,,1,true +17808,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ad0b0c39d7fd65a0b0d4abdd57e19513597c5444061f5656b700a3adf56bcf951000000000000000000000000000000000000000000000000000000000000a4b100000000000000000000000000000000000000000000000000000011b7065f8d0000000000000000000000000000000000000000000000000000000061854b35,,,1,true +17809,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a84cc5c71c7112454b9d18daf1e2c5b6795e9fef5dc4df77a2dd9e29a0e503776000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000022e4f17db638f34020000000000000000000000000000000000000000000000000000000061856f10,,,1,true +17810,0x3e4a3a4796d16c0cd582c382691998f7c06420b6,0x46ae9bab8cea96610807a275ebd36f8e916b5c61,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ae4a1d9ddfe3222aa7784a2018ef387dcb271cb5031fa285e212d8dc2e4232016000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000000000001721aba46500000000000000000000000000000000000000000000000000000000618577e1,,,1,true +17811,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b35e598fc643037facde62dba4343e99f62949580000000000000000000000000000000000000000000000208b536eef913758d6,0x44ffc9898569234d8ee9f7062301e1da06d865cbe5782785be0f511198e48315,2021-11-23 18:52:46.000 UTC,0,true +17812,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a1d35ba3ccc771fc403862804eec055082a21374e2b73af3f38a88906648e5ab1000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000013d3ee1214000000000000000000000000000000000000000000000000000000006185a677,,,1,true +17813,0x3e4a3a4796d16c0cd582c382691998f7c06420b6,0x46ae9bab8cea96610807a275ebd36f8e916b5c61,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a563f1e3292bbbc3b115206e4dd509e06ca76af5e1b90cde69f5c85fd4aac3ead00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000004546a23e3f000000000000000000000000000000000000000000000000000000006185af5a,,,1,true +17814,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000af542914015967cff7bfbf3f44c18697e82487667b3e021c1601d72fff30ce5420000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002ba1762468901801c000000000000000000000000000000000000000000000000000000006185c7d5,,,1,true +17815,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ab01bbcff132c8c3cf591da6f138837df4fed064337d94a9bcc1fa974138a4b8e000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000000000002c4e59dde90000000000000000000000000000000000000000000000000000000061861e6a,,,1,true +17816,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d63154abc9c6655626f16f0aed41c2e9584107240000000000000000000000000000000000000000000000079ca3466dcc4e60ce,0x31c236a106a92cb9df085b4317bd485e09f0fe94893389869597bf667707c2d9,2021-11-23 07:53:08.000 UTC,0,true +17817,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d63154abc9c6655626f16f0aed41c2e95841072400000000000000000000000000000000000000000000000a4ad21867b32d494d,0x9c8b2798285122b1b3d4795bbc410209806f5caf5372e47f6c35b866e6b055c0,2021-11-23 07:58:16.000 UTC,0,true +17818,0x3d4cc8a61c7528fd86c55cfe061a78dcba48edd1,0x7191061d5d4c60f598214cc6913502184baddf18,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ad58f678b4b4baa90c95bb49e72c75b1bfba2b27a26f76df8e0d9445e080ec4fb00000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000014bb4b00945ec5e500850000000000000000000000000000000000000000000000000000000061864541,,,1,true +17819,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f1d80f08df95f254cb7e6e075ad7265a5b85b92a000000000000000000000000000000000000000000000003ceb4ffbba54b5e64,0x5f8a75dcd0448f90ec776cfc61bb63a076f0559f0c075fa8ba77c15644712c36,2022-03-30 20:31:55.000 UTC,0,true +17820,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f1d80f08df95f254cb7e6e075ad7265a5b85b92a0000000000000000000000000000000000000000000000001878e9d03ee7add6,0x74da62aab0a5b96997c52e12e008dab59344d6a9159e85161ef7d0e2ea0345d6,2022-03-20 18:50:51.000 UTC,0,true +17821,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000afb2e085915aed02d3299de33edc28e5a1b62e0f0000000000000000000000000000000000000000000000234448c0b680431ab4,0xbf5ea6c90c4be16b61eb1193378eb01fc8b648d4b5d00a3851b32b631b39c8a5,2021-11-23 12:22:27.000 UTC,0,true +17822,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a9acffbe77f99d488b20e48d6ecfe9cfcd287a9cf55dcee377c3986d35bd8d63b0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002ff327d126540c2620000000000000000000000000000000000000000000000000000000061868a50,,,1,true +17823,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000aab2915687e6d20c40470c2a3720887fd0150129950c471525a4cf291ce73787e000000000000000000000000000000000000000000000000000000000000a4b100000000000000000000000000000000000000000000000077c1ef3185dcb479000000000000000000000000000000000000000000000000000000006186a2b7,,,1,true +17824,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a827f20e17d9a86460f19637daa2f01032e625ba1691c378f711866595c01e06f00000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000026d199654bf01a78e000000000000000000000000000000000000000000000000000000006186b5ea,,,1,true +17825,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007a0c7c84ec066b14f83d127bff2b7f46094b62260000000000000000000000000000000000000000000000001215d6c864e1cf35,,,1,true +17826,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000051bc9862ad17023fa88435f51fcaa6e677b2ca97000000000000000000000000000000000000000000000001566c010a90e7a32a,,,1,true +17827,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000afcf398abc919194b05082fcee0c697dda2072bb882e80eeaff6ca689b91d3442000000000000000000000000000000000000000000000000000000000000a4b100000000000000000000000000000000000000000000000000000018eaedf4c0000000000000000000000000000000000000000000000000000000006186d948,,,1,true +17828,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004200000000000000000000000000000000000011000000000000000000000000391716d440c151c42cdf1c95c1d83a5427bca52c000000000000000000000000000000000000000000000006aea892f4972ac98000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0xff844a28eb2b787a114128783b1fcb038f19305d8cd2d10c0b7240c7c24dc012,2021-11-23 18:38:24.000 UTC,0,true +17829,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a83f064178cc8ba6c1c9e58de3614c0fa0d0dee3792f1c649b32d781f4af35ab60000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002ba70c91dd3dacfcd000000000000000000000000000000000000000000000000000000006186fb47,,,1,true +17830,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a3da1da846925d85e1c17eca3d8ecdbda21bbdcba4e03d2bdfbbbff858e2098fa000000000000000000000000000000000000000000000000000000000000a4b1000000000000000000000000000000000000000000000000000000179bc8f65c00000000000000000000000000000000000000000000000000000000618719d8,,,1,true +17831,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002d83fa3eff5c3a397b2ba6ae62d1563dda1db3e500000000000000000000000000000000000000000000016eabbe7d3411ed8286,0xa8b8b8c6f8c083332c371848b03e8c45ce1a2efb4b503e88a5b08b539fdd5095,2021-11-25 01:59:54.000 UTC,0,true +17832,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003a15459851b5346677bf9f7d3f8b2a8233eadaad0000000000000000000000000000000000000000000000894b0cf091a4e30000,0xaed8b92a88a536dbc4aa89be6738cd2f9453f39a3573750eb62e55d389fb4b31,2022-01-21 02:53:56.000 UTC,0,true +17833,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d519060280a35c8cc069f9656edf60ae9cfad2e500000000000000000000000000000000000000000000000df39ca58b84abc1f6,0xf47604aa713be97816d529b42dc897b9e5babe7f0419283c5b3fd4cb13fd6ab9,2021-12-07 04:40:48.000 UTC,0,true +17834,0x3d4cc8a61c7528fd86c55cfe061a78dcba48edd1,0x7191061d5d4c60f598214cc6913502184baddf18,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a9d57315ac7326d8cc06a91979683505e101cf005d98a4ce663ad6fc390034af50000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000001d1ba6f6bae94b549c320000000000000000000000000000000000000000000000000000000061877949,,,1,true +17835,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006cd28541d19ff437df6edd4555443d9e92d911960000000000000000000000000000000000000000000000000708672312b02628,,,1,true +17836,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ac0e238c1b55c0e1e6e4fc08ca2a697e8f29a4532a2a85d050ecba3265794d1b80000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002b73a1947c9b4ab7f000000000000000000000000000000000000000000000000000000006187932e,,,1,true +17837,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a4f8569080387e7fcd050a74eb2682693b16a2236cfbffdd94eeb504151f10bbe00000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000000000002e62ccbb5900000000000000000000000000000000000000000000000000000000618797ae,,,1,true +17838,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a012c5c5e44a7beadb8a2a42701707a61e507d324374bd12dfbef74862a659291000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000020ffc6a92a000000000000000000000000000000000000000000000000000000006187c933,,,1,true +17839,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000bf3e7b8049d880ed408589db5221419a4680afa6000000000000000000000000000000000000000000000000023afbb33ae9c72d,,,1,true +17840,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000081a93e9494925347241a8966278fceb4167d9b0c00000000000000000000000000000000000000000000000086df1e119ba4a8bd,,,1,true +17841,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000abecb0f669c30161318fc60d3d2fe9e857f305e38bd6d1ae486a1ab78452e28840000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002bbba967a8cbd4cf5000000000000000000000000000000000000000000000000000000006188190f,,,1,true +17842,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000003f01940c87f09a351d422022d61bca0b682755c800000000000000000000000000000000000000000000001d049745e72ce36dce,0x1a20d6e6b8c2bc701e4b557bbb191da955cd63487d5cc82a8dfd02c7fadc45c8,2021-11-23 15:55:49.000 UTC,0,true +17843,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000005163d2109ac93b447828789b8df537bc9fa3bf1900000000000000000000000000000000000000000000000c48400cb7b99010a4,0x21a27e066f54f21127e9c5ec46df304a3dd87e205d9aec941b96394ef260aefa,2021-11-28 16:24:04.000 UTC,0,true +17844,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004d4902bd7e080159964f46b10feeb6482d148e5a00000000000000000000000000000000000000000000066a58bb42696e41be42,0xac82fbc035aa320792efab3ddea869819bcf3bb45c4172a62a7128ad3600cae2,2021-11-26 14:47:28.000 UTC,0,true +17845,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000df91e8eb4208ab196bdcf2dcf4c669951528e6d10000000000000000000000000000000000000000000000007863ca89b2838000,,,1,true +17846,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ea16545cf2e4c30b38b156cda0972be63ce71d500000000000000000000000000000000000000000000000059690f85313498eb2,,,1,true +17847,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a96914168f96bb7f9d19796c60b4a0bd2914a09ee31ee36be9e83dbfff75a8a920000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000002314f6592167acab70000000000000000000000000000000000000000000000000000000061887932,,,1,true +17848,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000b0c7ad67ab0ce69a370973f6248713ab2e7878490000000000000000000000000000000000000000000000590f2f832549c71c36,,,1,true +17849,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f43f2416f41b0b58086ff06040115b9522dfbe8c0000000000000000000000000000000000000000000000456bdcdeaf07022ce2,0xe906d20e0fa3b5cb64b836e89e55e3835a4841c2626734eb7f11937e215ebc05,2021-12-30 03:46:04.000 UTC,0,true +17850,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000928efa31db4d805dc355945a5ab3c8c7a8db2fe200000000000000000000000000000000000000000000000d8192d01d51a05905,0x067d050acc8813f7b3c42a34456d1d74d2e6c126120e27b7a345fa5594d5dcdb,2021-11-29 18:34:56.000 UTC,0,true +17851,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a1bfb01220659328f9379ef2dab7356c98889c3f0db57920aa7ee491cd8d3ad60000000000000000000000000000000000000000000000000000000000000a4b100000000000000000000000000000000000000000000000242923cdb2cf6116c000000000000000000000000000000000000000000000000000000006188b515,,,1,true +17852,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a2330e9c4571636eb0ef16681c993d7b64b97b44be71b8ffb89543fe23b27e3070000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002ecdfd973ea65a76a000000000000000000000000000000000000000000000000000000006188ebcb,,,1,true +17853,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000cb016db66774bd5dd798fc3ac9c3bfcc06d68c8400000000000000000000000000000000000000000000001dd0c885f9a0d80000,0x6ed08fd1e8ab3aeef3631e02c30f1e48a33278a4db584689f2608266d328e5d8,2021-11-24 10:30:22.000 UTC,0,true +17854,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000208b82b04449cd51803fae4b1561450ba13d951000000000000000000000000000000000000000000000002adc029a4462c50129,0x8fd14221691ba604ac3c39f6d861d26c1907de44350c4a6c1dfc6f3671e8d31f,2021-11-22 14:00:36.000 UTC,0,true +17855,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000461b4b406d7a366a965bfd455c013de70aa12a6b00000000000000000000000000000000000000000000003d9a6be04c94691f18,0x09e70d427f693e8c07516c18a314bd1d4f58d03403400fad4d8259087e936c7e,2021-11-22 14:05:51.000 UTC,0,true +17856,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000d5096b4d21abd25d0d3e0cf9e2ff7a840b20290600000000000000000000000000000000000000000000001d5aa492a3db56cb66,,,1,true +17857,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000001a9b6546a6c01c7cd4f7bcba968335382815a730000000000000000000000000000000000000000000000000471a0a73866cf2e4,,,1,true +17858,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000cc02538fdaee643a36a87adefa7286fef154a1c30000000000000000000000000000000000000000000000003012bc3cb7a62990,,,1,true +17859,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000af1f81936c6900d7c94c021d6aea7be8c85cf33b6afc81a8ef684549c372e7a8000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000001d82667b6f0000000000000000000000000000000000000000000000000000000061893532,,,1,true +17860,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a729bc3f5620b63c15b2fad19828b5f87f6c28f221068939043405b2b04c29626000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000029cd62f02cb6f96bb0000000000000000000000000000000000000000000000000000000061893b54,,,1,true +17861,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a423fe4cfb811e9cf6a61a02e80e372c0970d4b000000000000000000000000000000000000000000000005a4b9fb8fd64e3db19,,,1,true +17862,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ae829c81a24c014d17d529ab69309481d3c57784a146d31994552022330ff34b7000000000000000000000000000000000000000000000000000000000000a4b1000000000000000000000000000000000000000000000000d46e7aced2e3e5f800000000000000000000000000000000000000000000000000000000618976e2,0xf474168ff02289064f265af1a1cb0b8804b644f50adaf9d860c6ab241fad77fc,2022-01-08 16:52:48.000 UTC,0,true +17863,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a3af969e3fe25f4b37a38371091bfc69cf139299bf795714ee636c8ce4fa6f5b40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002c2ec03fa86dc613300000000000000000000000000000000000000000000000000000000618995e2,,,1,true +17864,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000007f5a1afefe061395bdad9256251d16b70ea27733000000000000000000000000000000000000000000000004953262f17bed1f25,,,1,true +17865,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a07cb3b4d0246d68af81e5ba78d3714726679116137b4c426be9695730daff61a000000000000000000000000000000000000000000000000000000000000a4b100000000000000000000000000000000000000000000000116e4d62043338d71000000000000000000000000000000000000000000000000000000006189a89e,,,1,true +17866,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a4a9bfe4f60a922fce15d8883e655eaa618635eeae982eaa452cf4476ec7fae030000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000ca4355eb5a024687000000000000000000000000000000000000000000000000000000006189af88,,,1,true +17867,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ae6d07c9338010f34bbf389ab4e62d1ba22f3fa829ecafad905ab9625510058bb0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000072f8d6cb5000000000000000000000000000000000000000000000000000000006189bbde,,,1,true +17868,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ac37401063bfbfe6eae98b8c81a4eb032e1e1d23494a4992d0da23dfe9611c9a300000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000000000001203b771d100000000000000000000000000000000000000000000000000000000618a053e,,,1,true +17869,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a088b33a098c33e7ee5f34505b75193bd404876d736c0c30914f2d408054ced23000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000022d239e62fda3978f00000000000000000000000000000000000000000000000000000000618a1c0f,,,1,true +17870,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000074d47619ce2245b65b0309e637e1144f2ae1053400000000000000000000000000000000000000000000000110bd8a4336cfe0c4,,,1,true +17871,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000005db06883736a244cb14dbd51eeb3c6ac3d207b8d00000000000000000000000000000000000000000000000779e3395d14db9dfe,,,1,true +17872,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000fbb33eddaa987f05ade310fac4d1289e17dbdc240000000000000000000000000000000000000000000000031ed5b59bb21dfd6a,,,1,true +17873,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a70d65979ad41c41b2ccf277895e9d9aa52c3fb93de804547b31a2828fe4b4b09000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000009b4ca9af41ac873100000000000000000000000000000000000000000000000000000000618a6812,0x55c7e56bc6a991108b79b5abae884a976ed2268f34b75c75b1362facecc60424,2022-05-27 11:05:23.000 UTC,0,true +17874,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a00000000000000000000000031d9ff6340798f1479e511d35071b76f62f1cc43000000000000000000000000000000000000000000000001de313f0708365881,0xaad5d6c383337a4200768be95822992e85a9b1c5da27c0b637dc1ef9fd0d12f6,2022-03-12 12:01:26.000 UTC,0,true +17875,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a2ae7edb530bf5fcdbc806e7ea59fe997e25239363001c50dd08eca3bb910d6970000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002bff64007c87572e700000000000000000000000000000000000000000000000000000000618a74cf,,,1,true +17876,0x3e4a3a4796d16c0cd582c382691998f7c06420b6,0x46ae9bab8cea96610807a275ebd36f8e916b5c61,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a8456eb2a500dba23484f977e70f53e9034943847a0e01288099df9a3a93af731000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000011801319f700000000000000000000000000000000000000000000000000000000618a7cb4,,,1,true +17877,0x3d4cc8a61c7528fd86c55cfe061a78dcba48edd1,0x7191061d5d4c60f598214cc6913502184baddf18,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a32b03dadfe5a73405fd38ac3842d33aa306a502471184d9a378c86747e5c2dfb000000000000000000000000000000000000000000000000000000000000a4b1000000000000000000000000000000000000000000001c080f6e2781566911f400000000000000000000000000000000000000000000000000000000618aa431,,,1,true +17878,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a70550ec1e2f1a4301d38047ed3ddd9700948fb3d5b92eb9c63032f2cb5626a6b000000000000000000000000000000000000000000000000000000000000a4b1000000000000000000000000000000000000000000000000000000246069028100000000000000000000000000000000000000000000000000000000618aa6eb,,,1,true +17879,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ab072bf7f4f839e71c11379960133b99d92cbd13c3da29ba6a81878a588437e9300000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000013b3ca5ac63a4dbd400000000000000000000000000000000000000000000000000000000618aa8a0,,,1,true +17880,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000af64d0094f9fcc615afec9007fcd9b978e9cfcb69824a8134eac162d541104c84000000000000000000000000000000000000000000000000000000000000a4b100000000000000000000000000000000000000000000000152e6a8e98c66933400000000000000000000000000000000000000000000000000000000618ac403,,,1,true +17881,0x3d4cc8a61c7528fd86c55cfe061a78dcba48edd1,0x7191061d5d4c60f598214cc6913502184baddf18,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a6df854bfb1030b22cc89fe36f7c4950124e463118eedd1af43d45c43fbe376b10000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000001103c727e6cebe07aed900000000000000000000000000000000000000000000000000000000618ac516,,,1,true +17882,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ad6d8e36135e6669027f8547a8d3d9023cfab0f31c9720fb6a893bf9799d7df05000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000028dbeefcfda93a30e00000000000000000000000000000000000000000000000000000000618ae727,,,1,true +17883,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a77e2d7331c148cce2cc1e60e5a999f3a11ac7ec970e334a81c37d338bb209b2f000000000000000000000000000000000000000000000000000000000000a4b1000000000000000000000000000000000000000000000002c150b7c16f56dda000000000000000000000000000000000000000000000000000000000618af6bd,,,1,true +17884,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a65bbcaa6e0e2ff8104bb76a6ec13a57c4d6065c68816e4a1b908068a94c3f23800000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000000000001f4f77800700000000000000000000000000000000000000000000000000000000618b3629,,,1,true +17885,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000e10b628bdd00896912677470b771a381640fc17600000000000000000000000000000000000000000000005b95d07c6bc11b5ba1,0x7799204f4ffc53616e165bb08b7b0ee391b58a23c1cbab9db4010f9d5b83470a,2021-11-27 21:29:55.000 UTC,0,true +17886,0x3e4a3a4796d16c0cd582c382691998f7c06420b6,0x46ae9bab8cea96610807a275ebd36f8e916b5c61,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a4272c01a9343c39baa571248efe2ec835aed1bd871ca4f6f37892f338e29593400000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000000000001287a756c800000000000000000000000000000000000000000000000000000000618b44f0,,,1,true +17887,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000aa67b01a7f1114c17ca6ac7c6079a8a8c934319f936e3ad108e146f9685147041000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000023e8e97e9f3d6b7ed00000000000000000000000000000000000000000000000000000000618b4e49,,,1,true +17888,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a3c3d2d5646dcdd6c890f32991bdf75adadee42b6d9c3d8ad241c75e81c9868cc000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000133627e06e26f218700000000000000000000000000000000000000000000000000000000618b5660,,,1,true +17889,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f3b06391631c69609d7ab0cd435b38e44312623800000000000000000000000000000000000000000000007a9a6bd65ee6b30000,0x1956e52cf6356dba403907d3d90a3f1b0aab93818d4046254464960e7b7ddf01,2021-12-08 02:20:56.000 UTC,0,true +17890,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a681393cb757efd511d4ff69219b35b546585feb8e986d8f176e2b27979bb0501000000000000000000000000000000000000000000000000000000000000a4b100000000000000000000000000000000000000000000000000000018509e23fd00000000000000000000000000000000000000000000000000000000618b67ad,,,1,true +17891,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009d414882fc618720fa8b850184f846422f422bd10000000000000000000000000000000000000000000000e3d5fafa9d203d4606,0x2c58fba734337a898ebd57218592440b8c6632d788c73114bbdc856663f30db4,2021-12-01 09:25:11.000 UTC,0,true +17892,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009f917290249608f66cbf666596bf71d9d1632d9a000000000000000000000000000000000000000000000000a5254af37b260000,,,1,true +17893,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a9dfbd28d936bb70b05a8f81fc676ccafe9f6acb702b8506f4fd9705c000f9fc8000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000023bbee2a9000000000000000000000000000000000000000000000000000000000618bb22f,,,1,true +17894,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000553de6c52ca165f63196b5dd80817f8636d029ac0000000000000000000000000000000000000000000003ac2dedffbcfce3c325,0x6594d1d7dc28a2d581a431a2b0967dec29052f3347e31158fe2830496ef3dfc8,2022-02-08 11:52:23.000 UTC,0,true +17895,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ac512792df647c70f0f1ba2c015002b7e09ee9099a562cdfd1e5ecc8c634b310e000000000000000000000000000000000000000000000000000000000000a4b1000000000000000000000000000000000000000000000001f21b453db51832e900000000000000000000000000000000000000000000000000000000618bb696,,,1,true +17896,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000afb9240d6494a59093b3fb57f78cc1df1ee1295b1bdf951f119c40d651955e13f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002b8927e83bfb7aae700000000000000000000000000000000000000000000000000000000618bb73f,,,1,true +17897,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec34000000000000000000000000b0df4a06d6aa6b81dee3ee489b4d9693a2040d82000000000000000000000000b0df4a06d6aa6b81dee3ee489b4d9693a2040d8200000000000000000000000000000000000000000000000000191b6628a0b00000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,,,1,true +17898,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000ccec342967170b4f3cda502e6c12c059fb86f6f00000000000000000000000000000000000000000000000246ddf979766800000,0xb52b3e0444717488cc64a307ab98ba0b49529ebcac6ae194c6c1372afb12f60c,2021-12-03 23:28:46.000 UTC,0,true +17899,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f1d80f08df95f254cb7e6e075ad7265a5b85b92a00000000000000000000000000000000000000000000000133dd238c6c975e4a,0x9ae664ee25b2429a62ecedb67e1dd535d5bab8d2315bbc0bc687e8a88c03097b,2021-12-21 09:19:20.000 UTC,0,true +17900,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000657becb53fbc3be121224d929040db06de383533000000000000000000000000000000000000000000000057f0dc60716d13c31b,0x40868226c27a5a50ad0c67ee29e28c7e06f962f59e1533e22e299e8f4b078622,2021-11-22 15:34:07.000 UTC,0,true +17901,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000903a6df07b4f4d6f6f6846c8b3b3f9dab5a2bdb5000000000000000000000000000000000000000000000012c48d433c07fd6911,0x84f96f171fb08022ed37e2350fe5b1faee7becfdbfae3678f8a582c517b9de5a,2021-12-14 14:43:26.000 UTC,0,true +17902,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000002fb1bc1c4d93df699ff96fd8ca7f999333f7480900000000000000000000000000000000000000000000000135096791ea012ae8,,,1,true +17903,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000000b43549a2e758d96eebe15af586a972135225ab3000000000000000000000000000000000000000000000002aaa5fc6155770000,0x19ab3ee2dda745bd8880aa150fcd95d49b83de5058b5d38a0c1b1d228ff2fc95,2021-12-19 10:55:55.000 UTC,0,true +17904,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a4845904728a0676c0edd849c961f17c7775b91855d0a8e97fe9365da8bf06e1300000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000007baff13e1b06fe3c00000000000000000000000000000000000000000000000000000000618c245b,,,1,true +17905,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000af1f87619ce2021939ff8ca2327b1812541bfbf8416e3510514990253dbcb2fb2000000000000000000000000000000000000000000000000000000000000a4b10000000000000000000000000000000000000000000000022f48f1058e23fa9700000000000000000000000000000000000000000000000000000000618c290b,,,1,true +17906,0x99c9fc46f92e8a1c0dec1b1747d010903e884be1,0x4200000000000000000000000000000000000010,0x1532ec340000000000000000000000004200000000000000000000000000000000000011000000000000000000000000391716d440c151c42cdf1c95c1d83a5427bca52c000000000000000000000000000000000000000000000007ba3c86846e187b4000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000,0x82f86b195a1c14575016b79702ba3f3cadc555b8b8ce7c6251f4455999866237,2021-11-23 18:41:00.000 UTC,0,true +17907,0x3e4a3a4796d16c0cd582c382691998f7c06420b6,0x46ae9bab8cea96610807a275ebd36f8e916b5c61,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a0f8e6b2e001bfaf605388008a58cc04d58d0fedbdf0751d8568a41c1458c4954000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000012931c4e3b00000000000000000000000000000000000000000000000000000000618c5b01,,,1,true +17908,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000c5225364e93709c3a53f5938b92517c3fbe17d840000000000000000000000000000000000000000000000468d281b0f47ffdb59,,,1,true +17909,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000af5393cdd34e47ae881a76266297b5ab293baf7df7fe34d39606a5f09afe3c26a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002ca4dfd6b78c2ecde00000000000000000000000000000000000000000000000000000000618c6570,,,1,true +17910,0x3d4cc8a61c7528fd86c55cfe061a78dcba48edd1,0x7191061d5d4c60f598214cc6913502184baddf18,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a2abd27ac4ab063916a1df5f91d76841c84918f8a70eecdd1408713b973a52375000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000103cb804346a8d12a6bd00000000000000000000000000000000000000000000000000000000618ca44e,,,1,true +17911,0x3e4a3a4796d16c0cd582c382691998f7c06420b6,0x46ae9bab8cea96610807a275ebd36f8e916b5c61,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ae10628a506a1af3c886c28c801d90258e09c90f7b9530c7ccebbd879aef0cd950000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000123b434ffc00000000000000000000000000000000000000000000000000000000618ca52c,,,1,true +17912,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000009f3a593a2984d5d9a7008df32d7e2d7da4db0ff4000000000000000000000000000000000000000000000003cfe4350f9a6ce293,,,1,true +17913,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f6792da267b264a24da725c584337c84103fe2b10000000000000000000000000000000000000000000000010ec721391f0640e6,,,1,true +17914,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000f6792da267b264a24da725c584337c84103fe2b100000000000000000000000000000000000000000000000165019814569d8a95,,,1,true +17915,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000004dde2cb805fff76e2deb661725c1e41e0adf7f6500000000000000000000000000000000000000000000015c1b85291880d34174,0x85a9432bc4e5b541b32d8a33c1dec7c12162eec2cc9d496838f2a62de89b694f,2021-11-23 07:05:21.000 UTC,0,true +17916,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000008ce47ca78fc1d3066a19ae004cd1760fcbb5644e0000000000000000000000000000000000000000000000137683fc1fff4d5a16,,,1,true +17917,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a962a1c8b2847ac00838330cac53d97b4247686c67c6b8db9083149686972056d000000000000000000000000000000000000000000000000000000000000a4b1000000000000000000000000000000000000000000000001df43df4a1d36ae6200000000000000000000000000000000000000000000000000000000618ce314,,,1,true +17918,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a97dc8ddd4cdd54c0d4de3b44ee2bb4a1172c926f85cdfd39144b45afb19f1008000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000000012a964e5db00000000000000000000000000000000000000000000000000000000618ce58e,,,1,true +17919,0x3666f603cc164936c1b87e207f36beba4ac5f18a,0xa81d244a1814468c734e5b4101f7b9c0c577a8fc,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a7ecddf0913debebd1369304bb913ee9b8d092b30442b2507b5bc8167c4023cdf00000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000000000001bd99958df00000000000000000000000000000000000000000000000000000000618cf492,,,1,true +17920,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a000000000000000000000000a969475b7fffdb97f29df047118dfdcaa11220090000000000000000000000000000000000000000000001b1ae4d6e2ef5000000,0x06671082257b083c7b35ae813c8b31aebd675f079c72f6eb55478ba547fcb825,2021-11-22 13:44:28.000 UTC,0,true +17921,0x3e4a3a4796d16c0cd582c382691998f7c06420b6,0x46ae9bab8cea96610807a275ebd36f8e916b5c61,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000a04772dcc5a12e6df2f000f2aaac0d205189975db617be22102b4329322e184450000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000128066fb4700000000000000000000000000000000000000000000000000000000618d153d,,,1,true +17922,0xb8901acb165ed027e32754e0ffe830802919727f,0x83f6244bd87662118d96d9a6d44f09dfff14b30e,0xef6ebe5e000000000000000000000000000000000000000000000000000000000000000ae321c402a022865093f366bd41c1ddeb5efd4d374327da4e57f58c8f198efa960000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000002b8a99afb7236564900000000000000000000000000000000000000000000000000000000618d1bf5,,,1,true +17923,0xcd9d4988c0ae61887b075ba77f08cbfad2b65068,0x3f87ff1de58128ef8fcb4c807efd776e1ac72e51,0xf4f7b41a0000000000000000000000006643fbb25018ffc27f2df9335eb5aa94dc3db35400000000000000000000000000000000000000000000000617726fa362a50000,,,1,true diff --git a/indexer/processors/bridge/ovm1/skipped_hashes.go b/indexer/processors/bridge/ovm1/skipped_hashes.go new file mode 100644 index 000000000000..35fffc5dd27a --- /dev/null +++ b/indexer/processors/bridge/ovm1/skipped_hashes.go @@ -0,0 +1,21816 @@ +package ovm1 + +import ( + "github.com/ethereum/go-ethereum/common" +) + +var PortalWithdrawalTransactions = map[common.Hash]bool{ + common.HexToHash("0xba6348e51701c2637723ea761561794442861e78c471282b3a982a59cadccfc5"): true, + common.HexToHash("0xc3f516a82467644d93722e108397c09f4ed78a66e87c0a82072df712543bae31"): true, + common.HexToHash("0x554cadef5a6220504524adbb4063d53a8d25817de6e0358130c496083268d758"): true, + common.HexToHash("0x36824f8662cc0dcd4cc561e0b78df4fdddaa0efc843060335af1b1b0a0d6198f"): true, + common.HexToHash("0x452330502d122dd783957a48070718a229c0bd886aaf147832546307c02f9560"): true, + common.HexToHash("0x865463c2132f70bcf31dd7c1603a5af98fe8843ee3f3f4c8258ddd7b566b0e43"): true, + common.HexToHash("0x736d788a73e92faa9cf9afc25aaf4572813e3aeaf9a552f371ecc9ebb1453d76"): true, + common.HexToHash("0xb545a6d66f2df216706a94948453fc434b0398a26698a479e8628b6e1c5a30ca"): true, + common.HexToHash("0xe3b088b19936636dd5f447148447aa206f204ddd5a6358e8dcb41eafc2cb86be"): true, + common.HexToHash("0xbe3f7e812eba97d74ed55eac2716535c2937eb090ee2d4877aa056049ff52c9f"): true, + common.HexToHash("0x85f648ed3452f6effe11a84c5cbfe5ea7c92c05774677746f6a06ff1a982266d"): true, + common.HexToHash("0x8a65bcf92027d5a658d8285fe5e912e2e2305f5b89c8d95735a1be722675d084"): true, + common.HexToHash("0x130b1fff5d8fb0688a4aef40c102e6718115af4bfe6ab1438d1cfd44c3e53903"): true, + common.HexToHash("0x05c6edc87da53dad0cdcdb620f6cb9778e775cef8f94c9b8ca33b736b2e0c366"): true, + common.HexToHash("0x50551172151a8001d1a358044d734176e432cd60a95735939e3287ffc5d031cf"): true, + common.HexToHash("0xbf0230e7d6fa0a2f097b331b0e21bc3b9377f724693911839e2a42f80255cd1b"): true, + common.HexToHash("0x2bf242473d6e0475736115a29e3a6891e97c1c204097d55548ad3cfa4cbc5ff9"): true, + common.HexToHash("0x2128aa0be113ac23b56596c707f2ef66e839e2aba18f4d568f1cf83234a03a49"): true, + common.HexToHash("0x16192e56741d45f8447f0991d488f8a35d5aaa0884e7b94e586fff960ef394c5"): true, + common.HexToHash("0x3c05005265f00262e89ff76a2eb7554c37e23a66ec54df83e74f21137c8f6119"): true, + common.HexToHash("0x976a00f6473a3950ef91fd58b139fb20d4cd638a4de8116986ab15eb8f30b008"): true, + common.HexToHash("0x187b30621c2c33f6399c3922b6e18377207b6dad861f30ccc7addf9c28b2f5b6"): true, + common.HexToHash("0x7dee1040883e4e8d923aa0b23e3fd990f6dc2eb48bb7092dbf6c7fc284ac8fa5"): true, + common.HexToHash("0x283fd2ad543dd42b96057f87164a85e099e2c1b7bba464fdbcb816e31fb8607b"): true, + common.HexToHash("0xf89297104ef3528415cdc3854757639e71cc2aec428d6c9a2ea47cafed2f411c"): true, + common.HexToHash("0x25e6c02603449519df98b8c38456dd1ef58ab34adfbf86325b4d8adf6194b574"): true, + common.HexToHash("0x2756f5d616ec1b075fde8edd3193b30eb241bed644e61e94f1a968faf6b435da"): true, + common.HexToHash("0x14d3e01f06802805aeeb578466fc4f82d433cd68b15bd1e13c05e09930fe47f7"): true, + common.HexToHash("0xeb973323eb1c8fcadfd48cccd7adf83bf64c42fade938e6c02f47ff2db295219"): true, + common.HexToHash("0x38b331dfc302a7957a02b22e49158284b2448670d496e33a28f159d368545f90"): true, + common.HexToHash("0x2b616fc62deb8076da6457ff0343bbfa99fcdb0b09c79d9724c80a36d17754a3"): true, + common.HexToHash("0xf7b7e2dfdf8e53232f426901df3a0215b027e07945b08b95d171219ea60e2d6d"): true, + common.HexToHash("0x4d5f743e45d24083b6800cd17b3db2e672890d209943d77e1312e0c0bce489d4"): true, + common.HexToHash("0xaf447ce0563022b4bff87240bee82267f224052b7de9bfa8edcdc5499e2bf18b"): true, + common.HexToHash("0x706dd401f78d74dd4ac9a93fccfbdbb25e89fb3d2aeaf7ec7a56a34b4498faf9"): true, + common.HexToHash("0xb6c5445ff133433f37b8a91ff5bcdb90c0555bb011ac1cf766e52b96220b76c7"): true, + common.HexToHash("0x2b2e28851eef0322f23e7d14cf5e1b0bb854b323fd085a8953be25dcebca3bbd"): true, + common.HexToHash("0x2f34921a0bfb64feaa4c81b2d054c528c3d54dda8e348f35ef0ffa36154cc1b7"): true, + common.HexToHash("0xbe78fa474f60e721344eba82d73ffeaab11ea0d4e0d0cf6c702b407f58a93d8b"): true, + common.HexToHash("0xef0c880d329bc06df4a522a2a33d0e1ee9bfd9b0394221a4687340e5a63ab2b2"): true, + common.HexToHash("0xfdc5dcc0c32eb685b799b3cb081c61e4f3f646172fbf2af0f33feb674bbfd7c2"): true, + common.HexToHash("0xe1a761da9cc12c2a31ce732e23e21a22267c1fb29ab13c657550fa8b1f03ed0c"): true, + common.HexToHash("0xc330c1b9b45e81417079323c278235513ad5d9ad13f8bae7d0bbc505c7430f3a"): true, + common.HexToHash("0xc921539ce5e82bee4e40d226880e922a3a4c33fc1afd6c8b11682fc91bbcc042"): true, + common.HexToHash("0xea43a25d8c1a4e6eea642b1e7e4ca1283dd6a346b7ffe93e2e78b4a083f4ab59"): true, + common.HexToHash("0x786330136729c99160a4dc1102934d6046f3c33bd7a8ec50c710f5ce9bcded3b"): true, + common.HexToHash("0x8ffc1a2e80f94d39b80b2382c97551eaab9d7b7560f5d9d8fc4c09d92e57fa0b"): true, + common.HexToHash("0xd9ad4da475518b4a85b8a2d55ed445dd7d93ee611f97e2ed326f2795d8a419ba"): true, + common.HexToHash("0x0cf3b305c2648924cdb26f38cb6d9a6fc954cad49090dd3670601591df6ca032"): true, + common.HexToHash("0x3a91a7c6ce28650075b80036c88060ae44c1d0554208fb82ef8132a1dcd5dc43"): true, + common.HexToHash("0x689e21e2dc035148263b3ac494fc755cfd31326126e66b127e87e41acd84a695"): true, + common.HexToHash("0x6c6d1cf7edbe6ec5f57a55abc6fb4ef483b4f1cc5373730d4d6cd8b751efc8ad"): true, + common.HexToHash("0x721768e7afd355b3b04a55ab90b2e86d47843155a17e9ec9d45580ad2cff4217"): true, + common.HexToHash("0xfb41af2f155042ee9ef821dc224bcae60d50efd6437d85b3e88a589d31ce2030"): true, + common.HexToHash("0x88c1757641598e1f4f3c48e56e45d34feeeb3fed59816c4f4d0d47b9c3905d0a"): true, + common.HexToHash("0x8e57408b7b12bfc65cfd26d5493ae6b10ce70e5d675f9312455601fdadf6a311"): true, + common.HexToHash("0xd0a46cec82b0a2c05b2e672ef3a7d5ed9ab00ea332ca492b0ec78dcfa4228042"): true, + common.HexToHash("0xff83f831a8f6a7f501f06f1ddc5d6ebbb1d4be7de6f7a587d218c4710bcb4a65"): true, + common.HexToHash("0x6b52fa9d1e6710b86d979d8c29dcaf58542c7676c5590af33013a572193e2957"): true, + common.HexToHash("0x0f30ece1ade99c46b288064a727b1e1f5706e553ffc94a9056e6ee0ae5d18fa2"): true, + common.HexToHash("0xb5b37c57bbc0997cfc966632e3108ff2f8075bc01861748e36934ff0077d65a3"): true, + common.HexToHash("0xdaea2d65d2b9f3a14b23fd0d18575624763a488936b5f1aef85a3339682c17ea"): true, + common.HexToHash("0xd5652f83fabc34c205669b894d47081c5e75492c702b5b9a4843481eee8234cd"): true, + common.HexToHash("0xf9d260601b95f211c3560cdc4e4ada531fa7ee15bab9103cdb11c77c7039f985"): true, + common.HexToHash("0xc0ca4fed68e1ef6e37d0c7f2c0156939f2dcb86662dc6d6cfb9d18a913ceaee0"): true, + common.HexToHash("0x3b20481d80b025a70b0a61b89d013ab24b9105bc4f423bc8ee225c68e2536665"): true, + common.HexToHash("0xf2036cd8773d25a91418db3d3b60ace385f8090026cd55cef4cc822b5ddedc07"): true, + common.HexToHash("0x96dcd1befb244b0465f69daea98441d1b66411600224af41df5cd49f7b441dd2"): true, + common.HexToHash("0xb0daa45e6cd5fe877ea0cafaf09b8dce83a4bd0790402cee0db8f4450af6e246"): true, + common.HexToHash("0x2762569b2624db0151c4724d030809227da242a4aaaba28d17c1d2f5ef5977f4"): true, + common.HexToHash("0xfec4a22983b256cd123014e5f166bdaf38f14ca8d87c5ea351ad352bbef54ef1"): true, + common.HexToHash("0xb337cf83aebb0b5e04033b729be0e3e85dbc12fde1b93f3448ac394f023b5539"): true, + common.HexToHash("0x86faf3ccacea5cc48d94775da9dd01140678783e3b11bf676c6d2313fd25dc5b"): true, + common.HexToHash("0xfc5a6e587bed9f3d8cb62e123d15fe6c3dc4e02796c6f0f8f4ae700d9bb57b10"): true, + common.HexToHash("0x243770004306f6c6cad7f610fb6d1939f0fc847138b1981848177dc448627f00"): true, + common.HexToHash("0x2cad7175f2cbed874b1a25e30a14644c1c4ca07a900ba17310af3aba2b2f0193"): true, + common.HexToHash("0xab84cd7588b3cb6c94a9cf67be71870141ab9065e4b49d3db8e431663f9c3ad5"): true, + common.HexToHash("0x4f08477a325053210d054e0dd55703e48f3630a308a1308134f54512f83dca84"): true, + common.HexToHash("0x527c82286f0e841577d79c9e98f7e3d52a52aa42959e12c53112e7765df3c611"): true, + common.HexToHash("0x51ff65b000a613ea4e78c34534c31f0a1b6c17d2320b1839a902f53833c1f0d3"): true, + common.HexToHash("0x5ab9415c538254b3a43550d34efcc47ac5f445f7373ac471b0e6f721416feb6c"): true, + common.HexToHash("0x3e15b576481ac7fdf6fcac9588556b8151974525da4c118f86cc3fce75b2c4b6"): true, + common.HexToHash("0x12906d94cbe5d33906b8b5bc6eaf6d096e67c85e0e71ef366099de192e8577ca"): true, + common.HexToHash("0xc2cc96faa76537182c76f38839804d0b6b22de550c38f5e60424af0e8a06eb30"): true, + common.HexToHash("0xe43f091346824bd17576fb7e8f158af5ad95f4d180df2f5466a069859a4169f5"): true, + common.HexToHash("0xe04e7354292260d3c7237c76c8f16359182ea1e43dff6ee17e189222ef7bbeb4"): true, + common.HexToHash("0x0462f0c5cf97e79356d07b1d66834feba148aeac50bfefec945d3e5c47076d43"): true, + common.HexToHash("0xd3dba6185eb88ee02c9ff466c18c3c2b17a0c77fd5086322baebaca0614049a9"): true, + common.HexToHash("0x7e0b6d35efa3b453cbe7fea9f843a51aeb91683a1e3e121eee26e1ecd875c125"): true, + common.HexToHash("0x4f79da7a590170e88cb218bb21e9f48e5b72fa06072978ad8df47fd766a0dccf"): true, + common.HexToHash("0x1be6972d5fa44a21764aca595c7a747bc0bc6385315c66a4bf9cde1a6e6eae40"): true, + common.HexToHash("0x08f77dbe9f1a5ffa6f6d5e9d796f22b55b67727c28f2bc663f56aa2618d5a8eb"): true, + common.HexToHash("0x388daf4dead6ea350de1ccc8387643792bef09b2af5f23b7a9575e68ee68884e"): true, + common.HexToHash("0xeebbaaa6f924bff879859e1fb1f70c3377c247bf1c5e2c93bc54cc4a02412066"): true, + common.HexToHash("0x9abf55ce56c96ec2560b09947aafccb3d0cf36daea83f6d910903ce3598cb047"): true, + common.HexToHash("0x42029765b8b241a4d7bf025d37986a24ecb8d9dcc8667f113b4ccfb15c6303da"): true, + common.HexToHash("0x96f81d0f9236f080f95b003953258355260f8c748619e0c85c75152385c08a28"): true, + common.HexToHash("0x2c9d5a453d7f34d2e1f6d80fb27aa7c4a22dcb98905759ed7fcb67036a34e8f2"): true, + common.HexToHash("0x7738252c9122d4a211287bbb1e5a70d194817a908e3230f1bc1cce4ad1b964c6"): true, + common.HexToHash("0x0de53fe987765bafe1aaffe0f8126df60b23f1c52d5a8c9d86949de922286da1"): true, + common.HexToHash("0x927826c238f450064d0050b49ccee2f67a9cdf8842f6e9ef6cbe2fcc6808a9ce"): true, + common.HexToHash("0xa152e12858d9071daa058023f6ea8ee03e8d397f95bbca609b74cc6ef363dfff"): true, + common.HexToHash("0x8b2d5f6d5e02fe3dc7c74c7b2bd1b09d4b66e3a8f216497bb80bfadb5ee55c82"): true, + common.HexToHash("0x34f0f7430722f2b0867422e03dc832d4c979b20f9fec78a2fbd93fb04c8bb9fe"): true, + common.HexToHash("0x08796d774f6c7cbf751b66bbf954e8783b842bfd936169738082b7c9c51064c9"): true, + common.HexToHash("0x966534c95334e1609b28306ea1f430060296d1d145ba31d37f3f19afb8964842"): true, + common.HexToHash("0xa73764741fed17d63b7a4c5648bbb7bd1d1bca0dfbfd6e9166729cc08a532d2b"): true, + common.HexToHash("0x34264669e9061930ee091addcb8df276f577a19929a58fe0cde4d7ce91eb90fe"): true, + common.HexToHash("0x8894f697b605c268422955f13baea93cd5082ea0e34b1826bc12bc98994847b8"): true, + common.HexToHash("0xf6a8806ae5470ac4f3bc87b8114b8eda8c46ae522656ea28e5a3ff4e9c364246"): true, + common.HexToHash("0xe8e7293083cd8827d82819b3284f93b5cfad4c0b5128b3da24404744e9c072d5"): true, + common.HexToHash("0x4a802a52acbb7a8b36f90cc16708c103b51772d53e74bf10368d482cd6043c70"): true, + common.HexToHash("0x4dd7a20c6fd05d601c66b22a0c56d9640e0bf43b78467f113719ddf7721213e1"): true, + common.HexToHash("0x788bb0b0cbec9946277483bb399fafcc322277e563559c32842e567207df277b"): true, + common.HexToHash("0x787d461e071dd134e55727d9f582ecf147a3ca2f36d924c0abaaab51cc6bb653"): true, + common.HexToHash("0x11e513bb8eaa14e35f8dfdc433a26d24d610bab5262cd506fdd1df222ad15c47"): true, + common.HexToHash("0x06eeece757a16cf87e73c4ed36c03619208cd7fbb34ca82b87032a2d505e0071"): true, + common.HexToHash("0x25931fd94ab65e6f371dc2ad082d2789c047c6cb67041066a8454e2b863fb358"): true, + common.HexToHash("0xafc6d1beaf5b954a115ba9a0d8c641a2a96fd38e388ae63bae1cfd779b96df74"): true, + common.HexToHash("0x405be1abea6da192eebeacc371f3dd8a4a617f71bbfede0647184eaedb5c57fc"): true, + common.HexToHash("0xf0208a3825d42c6e4cd3a4a06ff3827ee0871cf1f92894a8be5fb43f3a298897"): true, + common.HexToHash("0x912ccc4a9d1234263e8147b0888cd85f7d2fb5c4e1cf42c1317af4bad7accbee"): true, + common.HexToHash("0xc03156bcc0101b1c58d668f64f763cdd694c9274e5766b4ecddbed8af5574c5f"): true, + common.HexToHash("0x250f37693ba474cdf10814f850b89fd5347736145d40a3369d86f2b8f7069d5c"): true, + common.HexToHash("0x6b52b2ab258580ad20aeb0c981aeb4056446481766fc034896812bfd832efd64"): true, + common.HexToHash("0x1231544a8d752dcaac16f3c113ebe6be0f28712775e1a69b1720008a78b7d561"): true, + common.HexToHash("0x42fea02c7e4db4a4f8338cf8ff7cbe5fd39f6ea6cb372eed147e5bb5430e2aaf"): true, + common.HexToHash("0x79d3947dbdd1cb041a536976a698287917bca6b4b13357d9ac5f5915f2670bb9"): true, + common.HexToHash("0x97ba1275ce8fc9707db86887ccaf6c5a80d138c99aac9e65c9a89c2ac540c79f"): true, + common.HexToHash("0x5af3fec9c57d41e8fcaaf9e95cdb6a5bfcef66d021d8358e29b01044a2026aa6"): true, + common.HexToHash("0xe9b139a2411c6afc3868f7a4c69ab3d20ac91030f836252ade92657d1983e685"): true, + common.HexToHash("0xcc183935f076b4c7ef037b17d1c0c988243c52c25e51d65992cf59db123d68c5"): true, + common.HexToHash("0xb00ad5834e8e65351c95520dc8208dd089f1b26772ecb4ea82ed7923f42089a6"): true, + common.HexToHash("0x138ab9b60015f8854681385110c4decf90324475b817e6c8da7f108ec3a7cf3f"): true, + common.HexToHash("0x8e66944b2af0dbe6de24f6b6ea2b99e707b8747d633fd66376f9ce374f3e71f4"): true, + common.HexToHash("0xc3ef459dc9e7ade0b3eed368bc0ac1da62f5180af61aa9872c1f710358dc797c"): true, + common.HexToHash("0x88f1277fb9e0e165d5c91d885e4787d34b2f225f7fa2571dc87691c3e8a7fc32"): true, + common.HexToHash("0x1b61e0405105575997a229fa4aa3c9f9a7db6db73b6891609f48432bb68ec7e2"): true, + common.HexToHash("0xcaf2edccfa9ffeeb7dc04506635219034f8a949d336cd6d52d08af76d24e30bf"): true, + common.HexToHash("0xa2126448dc2aa307b5e8bdef52ba3baaaa45157718cc3220f24604fad49bde3d"): true, + common.HexToHash("0x2b64aabb4a1c5fce585622099f256fa283baf1632537f7d1f44761d97d5189f4"): true, + common.HexToHash("0x4a5b2ec6b6c37476678d9b538f968837eec505859b71cee302071294897dbfe4"): true, + common.HexToHash("0xdfcaeaeed3ddcd9e822fd18fd46e3428eb4ab546ef0b41bf6fe7a74c90517afc"): true, + common.HexToHash("0x7949d1e7c01868563306e15fe947667c2d6516ccfd139945283373f19c540c43"): true, + common.HexToHash("0xfeb9293ebdf86054e2ad486fe434aae1fac62e6b602776f23c9a6b2606b68995"): true, + common.HexToHash("0x8025b79c2ddf506347fb59a308cb35398ef23f0e67e8e8482783358d3264484f"): true, + common.HexToHash("0x2cfc9952ded3bcdd3eccc124595e55619ddb4ac8efc87028278159987dee519e"): true, + common.HexToHash("0x0fab2e09e17e6d7fdb6d97b4e08392274bb1b12e25b5cbcf262f90d68d3f3780"): true, + common.HexToHash("0x65f658059b5798375e1cccc9113c5e46ba44d9cfa41999ea9ba2ceeee8c911f8"): true, + common.HexToHash("0xb436d11eed16e66839442bb7813cef4ca2ab660ed046d019381f9643fcaf84ac"): true, + common.HexToHash("0xd9bc4ffa1e6b2e6161edf86bd47386c3fcbc4c71a1baf78ab1c632f2b84866a9"): true, + common.HexToHash("0xbc36a665c160df8bc2a55b67d4a2577f7e6c1a70f697ab1d093ce10921dbeff1"): true, + common.HexToHash("0x63953b5e0c649b841bdaa238b7f718b94d9cedf591c1a137dd192157fd7d1036"): true, + common.HexToHash("0x0a64e5abd6c3dd159f3f40a3c9e146c2f7362d8f492f4f0899eba97a5a510d8b"): true, + common.HexToHash("0x8dfbe330c2587421b8a7a2ba7b6161057d74558f626b5cf9d154e5dc27f25761"): true, + common.HexToHash("0x76c92c87a2f4f0194c8328bd24684908b246efed97c9ea37b3e0a27ff1ea7b20"): true, + common.HexToHash("0x6a18cdb325c3f89b3a68d31d18633c9fbb51208ee947a14de5cf58b8a427eb40"): true, + common.HexToHash("0x8736f947067803d366bef08ec2a2b218cd1d978c399a16f231ea9710eee26613"): true, + common.HexToHash("0x81fc172851c585f7dfa7cb19d2e39beff25211437604f82d71c29d82c29c7660"): true, + common.HexToHash("0xb7e079a096a480949f3031b8a9b7b9aa0503b1076e76bb78c444531cb93d53a9"): true, + common.HexToHash("0x57ed8176b865053e3e6a51acd1963da48e0123f0273db78d663ff9221e789253"): true, + common.HexToHash("0xcaa3ae0217cac9aaf769927f8ea2a2bb6fc750b683158227ca4c9b8043f04543"): true, + common.HexToHash("0x343779257a771080217b3a734130b34951bf52d32413fcd7fa77c69139abe2cf"): true, + common.HexToHash("0xd4f4eb054cb9fa08a3b75fe0ef8e09048d02af5633d317decdb73f15733d0be7"): true, + common.HexToHash("0x312a1c0b2b43cf702d570791e99f4aa15199da499f24a92fc0e2dd7e55553e89"): true, + common.HexToHash("0xaff1b857ba8590854c8ef7eb9653d96234384382d44f25320a7fbdc050d8d767"): true, + common.HexToHash("0xdfb9d95ab64faa780ae74d5b0371e5226ab136a45fc26a8f29149b524321f560"): true, + common.HexToHash("0x466551a20e3c6905ec3473d2afb49e540505aa15613492b53e4847f433beae78"): true, + common.HexToHash("0xf912744c182c384579b4abf96b815bc0ae755d136ab61d0e8d9e12ac544fc243"): true, + common.HexToHash("0x2866177d0ca4ce281eeae714d18a153ef8774e6cbfc6ec0451997be6106ee166"): true, + common.HexToHash("0x91657a03563ee1e4ae368f979a3868df376a67545786b7cdb4cc9a0e4c54ca2a"): true, + common.HexToHash("0x3db769277039c7658dd1e9f8715771ba0a2e03ff232035a49025a44ae1c0d9ba"): true, + common.HexToHash("0x48c5c8030211d6701328ebdab0f3fb95fececea917df39fb8d13f4843cc395ff"): true, + common.HexToHash("0x32a1fc4ae50247d2520b9f8f0ab93dee6178cebadb2b307d7c55806df96bac4b"): true, + common.HexToHash("0x0822d28aee2188fe36afdba9977cceecb56d761277bcc4a9a325acc549de81bb"): true, + common.HexToHash("0xb9e36b272c252866a14cfd21cb12fc53af5639fdb9e4708d1ba2f5f88917168c"): true, + common.HexToHash("0x038a7646dacf52d0c9d6a0571b33629d130aa50e6e8706fe3e280ff22fb6968b"): true, + common.HexToHash("0xd9389e7f2f387cd6c683d5dfe2f0137f094e7c957fddfd3f2895cb9817e3f4ad"): true, + common.HexToHash("0x7c286a747cb7122e6f0aa3e5aa88e32a1d6b068c2535c4d07aa85a2625bfa024"): true, + common.HexToHash("0xef9a71c64d5f618e533cd065a51f8581f9f259e9d5ebaa971b41f7c9763651cc"): true, + common.HexToHash("0x0aca5890d8905d572a67771e79927942ef3431ddffd4ada62982ef7311d800a1"): true, + common.HexToHash("0xe23744034352cd3044b316109e3d1617ffdfe6264122d3b287b73f4840b06ae3"): true, + common.HexToHash("0x4a3d8c631f643d3716b32f09b789fd1d7287ab66de0593008ad6871bc9dd5698"): true, + common.HexToHash("0x5dcf2935a5759627605c2502e2c54a94d1bd8e8f2c5d2a235778f13cd3afc520"): true, + common.HexToHash("0x421127802ea308388b2eb351cf37750ce9c2eef74f2ef764fb6208318a28bac9"): true, + common.HexToHash("0x4019ed34b3efc99e490e90dee5503a3ab7316a2a0b3db8adfad7339ab28692f7"): true, + common.HexToHash("0x68454c03b41c2c27b9d4965ee7178530ec6968b7677db23c79e6870708bdd7e2"): true, + common.HexToHash("0x55860ae969b5757255205452613abb026148899955867e2934e049ddc4087f72"): true, + common.HexToHash("0x21f240168d6fb972300931703cc2ce9899c647cf6370ef1ffe3890b841b3a8c6"): true, + common.HexToHash("0xcfe5eebf2ab33b02d36c211d46279034ed3cf932eebed67bf9c3d2a23d021a0a"): true, + common.HexToHash("0xd867da96e83083f299bd2c7ee141a4ecfd69cf23aca0b90fcf8e196ff662f5a5"): true, + common.HexToHash("0x50813588aa71c0ac827c2e05ad67d09369693f086a7b08fff4a5e32dec90d29f"): true, + common.HexToHash("0x652c8b03cc6bcae4cb4a6d3e1c9817e01655dbedf26927b224c28f4a4a2baa2d"): true, + common.HexToHash("0x00049a3bdea34141cca41721100232f46a21151c1b4458d36e515b488f215c31"): true, + common.HexToHash("0xb3f7d6e776242647130670f8cb454b6e5ded30cb47c84fa9550fdfb2e3ccb119"): true, + common.HexToHash("0x25bb65b6e5a4743b0cf4f02104a72a4995ff9ad1066f55363c9e8fa137f990f1"): true, + common.HexToHash("0xaba5487f97e1d566445d07166272436b73b7593420b9c747e879677ac62ab05a"): true, + common.HexToHash("0x728e5defafc2556f63598d3b9d4a2d16b01ff1933aaeb0bfb76c2dc1fdfa847b"): true, + common.HexToHash("0x6202bb3a3eaa37e39b04169c7f7956f936f1aeff5477c87cbb7213f510674766"): true, + common.HexToHash("0x169f33ea18b6b123cdda37fe0cd87b8b64b9c7fede9898c33964449f03749cbf"): true, + common.HexToHash("0x086b289d05a6afbbd5dd60261c7710d7c6508d2fad5dc0f8c7195fa88ef804fc"): true, + common.HexToHash("0x6e15a53cc43c01ee647e6015b6f64b06e6845fea913508aafec565614b09cb19"): true, + common.HexToHash("0xa4e8ee7fd7bf051c9c2db92ea240c493ccf1711c86c14f73efad6ed9778fdc45"): true, + common.HexToHash("0x92c1b71f6dbc5245ec8fc7a8390e2801786284e6a3276b83a70ad1da35440442"): true, + common.HexToHash("0xd08a7a221dbac23e849e184a47f5499495ca243a025b6f2fc766e0f7fa49fdff"): true, + common.HexToHash("0xf2bd1408b16b81c70bb2758e5b8b29798a06971317573eca9c77f9ef1be72ffb"): true, + common.HexToHash("0x9eaaf38ac737ad92a19252b749fbc049113a0400b69a218ca5ca4a4b8af01d64"): true, + common.HexToHash("0xcb6e09e834880244b6a8a41c132ec215607b387d1bbdbb509da30b6abee8c335"): true, + common.HexToHash("0xbf591d35d4d75a3f020ff970c66ac1d86e79ecfcb25cd49411052310e8e2c2b5"): true, + common.HexToHash("0x9619450dc88d831e2931546293f268e1c02be612f3c9b9ce8989702a4401565e"): true, + common.HexToHash("0x60eea1985c351421958aae683060f7b28405351406235cb9385dc2b71705b476"): true, + common.HexToHash("0xcf35a47f4d733e6515d048ed43fd200af17c8375b056774e2a90afdf247f27b8"): true, + common.HexToHash("0x85dc8d522eeef55018aaea9112b3f6236f55568e0132cab80b80eab192dda7c4"): true, + common.HexToHash("0xf375fcc8e2d6ccc4694c36ce85d610bb4a01b8776add658125ccb3b2047ee18a"): true, + common.HexToHash("0x583b7e0c8f83fcda3ed601bc15d2914519c5bde8022e892a961908f997a17402"): true, + common.HexToHash("0xd6a4001f65d9488a01d80fdc4f0564baaee7b6a5447bede7cb38758a2ba40a2b"): true, + common.HexToHash("0x947620b5f5292b958c345f59d402afd93fa47e52e554b429d0ed4e1def9c13c2"): true, + common.HexToHash("0x66359583c47264914658e6db19cd8481443a3f2a509130920e0d12bf83591d11"): true, + common.HexToHash("0x183e50218a9efffcbae23fcdea39d86338d5b20011634d2518fff4d0506a7dbb"): true, + common.HexToHash("0xb6c6a2c290f1536467b79d8dda604b7f56bdca04fecf3d35bab586b082243aeb"): true, + common.HexToHash("0xe58fc5a1871fa22456597ff4565cf140dc3f5b6a4d4206662ec2506d103bd3a7"): true, + common.HexToHash("0xfe5575087faa79668c2e55dea03b248e704bd1476a29d54a2be7af6d83653022"): true, + common.HexToHash("0x99087265bdcb465234684daef17cbef310a45b507009d365097a56500509f545"): true, + common.HexToHash("0xa93dab49e22e8c286f5f28426e40b51372c2b703e3307caa6b1e9045305b9ce8"): true, + common.HexToHash("0x7a7739e24e15bdea5d2425f11036548129afb1f31a84a00abc1575c2edc1420c"): true, + common.HexToHash("0x6db272fc1f757346a8bf10b94863917ae476f2b01dc0479009e4a6d31a474ab9"): true, + common.HexToHash("0x11eb78893c446f3a28333a31723665360936fbd06c99788c8ae206f4e8e945a5"): true, + common.HexToHash("0xc216c8e902c5d1d38aa4653e40ac7bdb86e4afd430727ccbb38c62da3bae0fce"): true, + common.HexToHash("0x96c2d023f9274c3766087d7bf202071877ddf611fb9ee1a2cc733f6f9e0b65dd"): true, + common.HexToHash("0x21c576952d16c085a2885e7c19875081653e145dcf6d74774369d9a6e1482179"): true, + common.HexToHash("0x573d0e0813179651a24fa9a16cb39951894ab80d97d2810c2b1e4fdc01a56390"): true, + common.HexToHash("0xcc259040864f82194283785cedaecb618956d3aeed1cb1d9af404cf07052a19f"): true, + common.HexToHash("0x1daa12c5080e5cb227bdd9b6671ba54b7e86ef15221d814964ca58d267fdc0a1"): true, + common.HexToHash("0xb1569d4e13452047b312f03df64929ed5fe5d86d2117f237de434c3846f854b2"): true, + common.HexToHash("0x857aa63465836d9e4f6f69188bdaee99b9f66b60497999f235461ba02c38fd5f"): true, + common.HexToHash("0x82cc288ac854755281e3e0d6b071c916f9b7f18728790fa87a431b261f13956a"): true, + common.HexToHash("0x5d9f5e4b2e18af20407dfebf868ca0bc3a8f6faf612a86039e08fa83103d30e3"): true, + common.HexToHash("0xadae3f0ad57bc669f2551f371e52668b43a4ffa228659b275d4c06c491f13600"): true, + common.HexToHash("0xbb2c8107831b57d4355866abe69252a8613f90c9f500338e05a96817364cbc37"): true, + common.HexToHash("0x393e3e99e647982451b3f0c4bb331529f419042861db12221a3bf7208d8650c9"): true, + common.HexToHash("0x508b71c2d85afd712993e35a882841833c1c65db2949a178992fa3e9d783db81"): true, + common.HexToHash("0xab6deb0008d2ebe53dada4323cf09dca298a2b3ebbb8bfdb67e86b9cb4fee31e"): true, + common.HexToHash("0x3fb11041ed4d98ebbbfbca91c32675d8e1d6dbcc59ce1f3cc9436940fa42af88"): true, + common.HexToHash("0xc05b65a3081e33e8fb0c5ce31a0671d211b1c792f13c8156abdf995e26e6401c"): true, + common.HexToHash("0x092acedadc417ce4ebcaa9ce1669f7a50002abcb64a85fddfd38039186911c13"): true, + common.HexToHash("0x7e6e958a10c96b370d24e971bb08c135cf548872a76927f11867257766f22844"): true, + common.HexToHash("0xdb7a37d79ad25883b97e49790284f3e2225723b9634f4ba12788ed25c5815a9e"): true, + common.HexToHash("0x8798e280df97388e344c56ad4a834abf2760b4bc8f863fe5dd6b6e66e89d78ee"): true, + common.HexToHash("0xf933c5e17f09163365b03297767096c7bbd358a8acbdc914cbed750dd26ee326"): true, + common.HexToHash("0x8be73ef1062ddf8fb41c8d71e81512533f4b6de6f9901752fce82caebab5daff"): true, + common.HexToHash("0x3ff9b593f14da762b8446be289a40eea329b0cdafb087b36675816c9bc7c4e8b"): true, + common.HexToHash("0xf3b459782419cb03dcca2b5e599dc655bdb921c5303049987fa1a668b50c7345"): true, + common.HexToHash("0xe1f1083fe10186c96f781ccacbaf612febce8e5d31b5f34172c9c443905e4e17"): true, + common.HexToHash("0xc6ea9af446e6e5347c4ce0db44f77b54aa662c91e000881aca6953c8638a08bc"): true, + common.HexToHash("0xa75adc863227cd6bb20d984148c2a78bd2055afbf2418f22d78949c792028862"): true, + common.HexToHash("0x46155b7fd62da11c13bbed3aaf60175105b2014bb9c4283183e95f459745bf94"): true, + common.HexToHash("0xf29f4ab1580de1a676f59289de66bd042b5a2cee29d9401b741bc4515cb35240"): true, + common.HexToHash("0x76084a42a2736d7f111b52a9c241bb7fc2c87276e84cae7093f0ea64e5004551"): true, + common.HexToHash("0x53de5451df2a82592c715d0d898c77457cf47fe8b9ffdaab233f2142193c5bf0"): true, + common.HexToHash("0xc3c46eecd1627d72acc9c40dda762c89bb59cbc4ff4cfa8cd450684c914c894c"): true, + common.HexToHash("0x12a53d7f5b9472eab3321a2acd3c20a54b4a8d9e158793bdbd446eae4f62cd51"): true, + common.HexToHash("0xf200b2ba370c41b3c833c956918b2269b4cbeba274c7b1e166ae9e053bef0a2f"): true, + common.HexToHash("0x0e26b017ac2e1c7dac2bf71b217ff0c2a2591b98c340102f2e4b963223f50174"): true, + common.HexToHash("0xe36d5e21791a9474f2e3ba54e014f648adf9c481cfd1dfe31f57181df2905b6c"): true, + common.HexToHash("0xd46adc38f98bd2006dd9837a04bc12818180fd7f542cc9a99f1f378a01f95ce4"): true, + common.HexToHash("0x06a302b5037a901fa4e09faf598c134a34c6a2ec164877b27491cc78ab54cf05"): true, + common.HexToHash("0xeba46e1e7731d5d8507c01c2f0311bc8b2d7bc04f7c55dac0487a9ee4b067569"): true, + common.HexToHash("0x1ba464d0d8b1381db36181308fb1c884f3b9e0db7dfd7d12d54cac2d90c62737"): true, + common.HexToHash("0xf8fb7558c18ade95e6b371ba262148c888a142890027ccf7c66516f18ffd42e7"): true, + common.HexToHash("0x30e198f5a604b6f5821746f0fca7264e10b6edcf8a33f223d0d45ced23ed5989"): true, + common.HexToHash("0x75e9263b742eba31499200fd38073180f3d4a6c1772f7142d465825fdba64f56"): true, + common.HexToHash("0x42427e6c8d3de1f85838b0e091af2c08bd2ff5461b19af8ed3da86758a3ce150"): true, + common.HexToHash("0xd79f0e6065e51dba0cda56929421523dab9988e96dcfee752d776d046c7e5119"): true, + common.HexToHash("0x9c722e2f3e7b9518632c2aa709077364536eb26c960226d1821387e2bc870d9d"): true, + common.HexToHash("0x17eea224e7ad407b20b657860d01c2fbeaa29d88c9d7d3d5ed65546d10e98ee1"): true, + common.HexToHash("0x75f8dafef26a8cf6648f158b4feb7f8f2700620adbb976b912cc1995425350d8"): true, + common.HexToHash("0x1f29cd352de505e2b932966f5ed08cb78264a275ada7b7541423fc068335c369"): true, + common.HexToHash("0x47f2050d8dd3d4a21db1854417489483ceab530b74f0f75d2c5a1a9568f6540c"): true, + common.HexToHash("0x888da0085c3c04dcaa8797ad308a5ae03c4122926833b430c6b1649302337aba"): true, + common.HexToHash("0xb662210543c8ff913f7e1265906cf615896272806678190b491697f5d94cb9b7"): true, + common.HexToHash("0x793f8b5efa653d2dfeebfa424f4cffe704c8f6eff6019de52915d0d4161ad959"): true, + common.HexToHash("0xd3117530a0e70796e3c561a914697408717a25956e6355e72fe608359be34d8c"): true, + common.HexToHash("0x94e7a46061578fa33e11d8bf186300ef1a67943084fac0973870c61cdbd945f4"): true, + common.HexToHash("0xd0801dab7412fcb772fe331125169a264c57dd7e61dd089c7bf483cdc9c43a53"): true, + common.HexToHash("0x28ecbd85a4e79e1c6c6012462db18ae50f9ee26d83ac901c33869f9cb8333a38"): true, + common.HexToHash("0x5d22115b8603c8045f887eb5c3319c2755f42845db87becf9ea724143881a598"): true, + common.HexToHash("0xffb27ac51783887ea96244d8d1f01aa26cd4ed029999f9b148420ce98f31154c"): true, + common.HexToHash("0x433faeb878ec3acef832013e68dc7f96e5dacd327c2022fbb6324468abe372e6"): true, + common.HexToHash("0xf429d9b0ed80e7aee71779bfac0b544f35f5809ed5bfb7b0536b82143dd236e2"): true, + common.HexToHash("0xc636b79317b11874fbd1487438fbf7119c409327fc9ab21335296d37d730d3ca"): true, + common.HexToHash("0xebb892f78c0ad8d6cd5030ef38294f8884625554bbad814c7a0821b92cef01bd"): true, + common.HexToHash("0x234f6dd123397e807fd9578813e0111b0b5a45e3634fe31b1c22b7e9e2b069ec"): true, + common.HexToHash("0x4b3996e2892a25c2919a45111ec455d57b790ec0a59ce261626e6b65093be68c"): true, + common.HexToHash("0x118a63c9edb4cd8e89c5ae5aa589b40820d946c88b5499d0a1cd5a4d3b38df14"): true, + common.HexToHash("0x71c2eeb1f5c95addc51684b3b7e623775dd7fdf93d54160841d5d1aadd402f07"): true, + common.HexToHash("0x9afacfc6b4a34f4093b119370c5203daad662491c77058795e905393ccd1518b"): true, + common.HexToHash("0x8a7f2819b8328e99cef4f7fc0788d1a3ceaecac8cd0fde8f696c15c3b5fda06f"): true, + common.HexToHash("0x37c192fd5bf2161362e4706be093f9382b4539beceb6984a789bc68b2df23434"): true, + common.HexToHash("0x888b786e52abaee9be6c8019b6d7a0ab71d3a83ef809f9f946dbcd2acaa55fd3"): true, + common.HexToHash("0x4634c3cb6d693d19545b6f40988c8789bc8e205cfa843d19bb01a5f7c4ab8337"): true, + common.HexToHash("0xe163420e42d0b3adb1e887220560001d8a981dd3aa9f5b7f732fb35c9afc4159"): true, + common.HexToHash("0xde16ca4253f0b42473e06894b5afbab345c4c5dd2eb07aaf255c17bdede0041c"): true, + common.HexToHash("0x7e0c257052b02f59c12644c0db512950aa8a3309c0a3b80109907f8ed11ac8f0"): true, + common.HexToHash("0xa21834b5993d748ade0a32e37bbceb05ea1f963bb2569e28507fc02139d7988d"): true, + common.HexToHash("0x106cb6f4bda0afb8428939b8acfa00f5c7180281a2689f2eb91edae15ca15962"): true, + common.HexToHash("0x045980c9cf6344e704f807fcdad5313ff2d4ce6c355d419c2acbef13f8630a75"): true, + common.HexToHash("0xd05f25aa6bd31b9f730b8f810dacf08d7fe27611b5881886a456d887b13bfe13"): true, + common.HexToHash("0x07ca837ee22fe16f5ef2fbbaced39e5554a3d80c276333f72ee653ff0e86096a"): true, + common.HexToHash("0x30f4498959133ae725aa628012bfc97b8ec357676b56b4749ea453d4c83e411c"): true, + common.HexToHash("0x358cc0e8095dc4fa8854346bf8237033db2dd85f57468fbc30f54cd58daa13aa"): true, + common.HexToHash("0x35a1846366b9c3cb7e6aedd708eb4b44e44c32cf96960c4972d1597d12ce0705"): true, + common.HexToHash("0x520b873792b3976f90038cc9369948e3ee4f124e9d5a947f0171cb590b269332"): true, + common.HexToHash("0x48f105401e4152ea5bf20c9e213e57cc731df73990fdba0489e1b5a7ec745433"): true, + common.HexToHash("0x567355ea2c63be39e14d71dd133ce2bfea8ea9ed21f06297bff474344445c72f"): true, + common.HexToHash("0xca8298b39ec1410d910b8e40ec8eb18b5f1f192b2d82f42d4086a18be10afcc1"): true, + common.HexToHash("0x1cdc3a5ea15fe9879a8e8ec05d56944e3efbaa4f460690da50b559e3dc41f90b"): true, + common.HexToHash("0xfa2f917eacc0d44fa14ac8ea0e92ed92b02f8c78ccedb0776e6ce9d5f9f95dcb"): true, + common.HexToHash("0x132cc44ad8ea8409231d878132fd30c1dd7d7f44e02653f1d1a35002f457313b"): true, + common.HexToHash("0x0952cbea84ac30eaac28bcbee3da375d50090f37d145368bf64e7eafeddcc901"): true, + common.HexToHash("0x0d3c2fc0f39ff0ea3a63ee47b9da932df968e5e82422e038e2462d4d7cc4163a"): true, + common.HexToHash("0xc700557f7f5576a9ef625e39320943d934d76fdbe84c657eb7695b4156255a99"): true, + common.HexToHash("0x0e1cda6ba1919c3373bcd7b7e11de34177fe448c513601f2b6aa7e7183e0b47f"): true, + common.HexToHash("0x55b9b41af3e1df842b352123dcd1c4762a2953ff91632c9b6fcf150fc1e66f59"): true, + common.HexToHash("0x0349d7f31a1b91e253bffb037489a536129727f0d779346d3cfba8baac6d537f"): true, + common.HexToHash("0x951b8ea0ba872a9319f0250d16101127aeb68b325d62c0e3724b5cbac655b5f3"): true, + common.HexToHash("0x4d510815935154783deb9dc60428e9b7e4712cb1ec7b6fdf77e1bdcd093dcc97"): true, + common.HexToHash("0x0e489cf0f77f4357d5cd5f8dce771dd787e92db397ef9585f6486099f7feb161"): true, + common.HexToHash("0x33db90873529cee7bb4017adb585bf5f7bc0d38b6bf9b3def5840132314346ca"): true, + common.HexToHash("0x4be837f2f3ae253f6bab7de2c243865b300ff61fe8505f3b4929b0da318fbfbe"): true, + common.HexToHash("0x802bd9892667958047be01256ab4b78f7354721abae7162c7f19bc1501fb9eaa"): true, + common.HexToHash("0x62cbacf895f3be1184528e431974572ed49dd0596df7e3de5b8e78723accad7a"): true, + common.HexToHash("0xc5ee8809dfec576ff81921b3911d5f54cb4ac690ec05678a4f1a3138359f94e4"): true, + common.HexToHash("0x20752eb4b6b47a023ebc0d83547a9e5ba4cba89b5e1b653a896a325d65950d07"): true, + common.HexToHash("0xf38edff71152678941d044815b72f00db0b58f999e4253cde2d71d6ba131a22a"): true, + common.HexToHash("0x1d135d2f71742747348c7988303767fc9bb7cb93c6e831955acb4ce8f71e4203"): true, + common.HexToHash("0x2068a6a228599002ac5378046363e54e70d0ca5c60f1c20fa13000bb2a23c95f"): true, + common.HexToHash("0x04622baffacc173192bf85c3ffd1f03594d62a57440d52de11c3ffc545efce48"): true, + common.HexToHash("0xc99ff576ff47047ed4fbc89d4d43fcc51a0eec12db23e4014a7fc78f5ae2b79c"): true, + common.HexToHash("0xd159a8b1974cc4f60a5dc0184f6357305f73bec4e85e1dfa065cff276b569162"): true, + common.HexToHash("0xc0ecda30be34ace5297d2988fb9f6c1db293f40265da60fa22cdd6832dd974a3"): true, + common.HexToHash("0x587dd3044233ad298f53ce72890b06a3d738945b8f01a84afcf02727b5a29643"): true, + common.HexToHash("0xc39af18d0f84a1c286583f1889649f66f7407f8dc05e35c920f510c0f60bb466"): true, + common.HexToHash("0xe449fb9146956d37d93d84728c12d93b471a54edae884fec655fb5b6da4d083b"): true, + common.HexToHash("0xc5711585c1b349aef8f803b4565697811856ae863cc050918bc5aeb3e66120f3"): true, + common.HexToHash("0x31bdf470e5023dcf50f3720cedde8a1fb7955be0e4751d8fe8eb2ce110f4e158"): true, + common.HexToHash("0xe9a9a15131364f6f9ba10abbe3963cfaf3a9909e63b772c431340ef2b856f6b7"): true, + common.HexToHash("0x5cc68b9979e0b2db34cb3e1538300fea5a7085e548922014d4726801aa68eee2"): true, + common.HexToHash("0x548084c30983bc0636d51ed58fa4a46507d84704996bf500ec2394e6848d5104"): true, + common.HexToHash("0x2686199b8185be4bdbf644ede6e9b3c7faaef4711702a6aeb3ec16632da3eee6"): true, + common.HexToHash("0x178cba6928ad52fc4116efa567b3dbed85127fabf13e7194350308db6fffa614"): true, + common.HexToHash("0xa820a076821b4bc53bb0e5f85474cb60a4519cdeb41b1d6aa6ab12ddf91a7011"): true, + common.HexToHash("0x8be85fb47a559de9c5f727b63cc7b535bcb3292e1a0cba0001693e87c387a390"): true, + common.HexToHash("0xb72d863d65484e2da8629f7a3673e8b645c08abb578502b3a914d5d9c8396985"): true, + common.HexToHash("0x6deb18e37297407ee613e03d9e9850032b00f83909dfb97530d4c1371dbfb8fc"): true, + common.HexToHash("0xb563458848049f23a5177b7ba2a36d2fa203a2bdd37749454eebb40eddada253"): true, + common.HexToHash("0x67f9a86270ba9da086fcda25c03697f53ac9c6d625fa1694af2f82d9b3290f0f"): true, + common.HexToHash("0x18c2779e4ece2a7bbb2c2c7f00dbacf2d749148bbc9d0834893aa1c147474077"): true, + common.HexToHash("0x03610164bdb16f6448556ffb81582089137e76ff1d5e51e97db676cc96ef6c46"): true, + common.HexToHash("0x090131119faeda2fc1bd83819d8ee2b90bf0c1655d1b4e59c65d290c4b96740e"): true, + common.HexToHash("0xbedfa77e89bc70f9101bcb2d276029bb7bd9c19119f617e7ebf67423fa4319c7"): true, + common.HexToHash("0x54091cc3786ada7ed88e06de76c47fe3361ed784bf26b6a5781f9a2d86a64ad9"): true, + common.HexToHash("0x5a52e6a8d5ec73ccbd70d5afef9f00c3de42ff2509f07acf566d615bd2220bc0"): true, + common.HexToHash("0xc67171fc28b058ee03632909daa98dc085e42c20244d2798a3eca02b56ca007a"): true, + common.HexToHash("0x6876384e3bd3eb29f7e98ad3d90c4ec6eb168110592972a6c01e58548eb211f2"): true, + common.HexToHash("0xbfd3255d7be5f9e89eec4ddc9bf1b5aafe1962414bd9092f0fded9f86988b5e5"): true, + common.HexToHash("0x6649daf825949a9a446436c0b8ce18f365b85e5b1cff6f507ecb641614442d43"): true, + common.HexToHash("0x1c1ac90ce52548b6b83f137cbf19fdc08b9e557bd93c33276c2e696a5f14954e"): true, + common.HexToHash("0xb7f9e461177bd7979cde786f58a04b7cee6aea6465d7019e52b231032c2c5a43"): true, + common.HexToHash("0x31ee5582d5b672d0364f06d84808b0006abae6507ea75a37020c7a8a9c1e9f1c"): true, + common.HexToHash("0x06f95223928adb5fab877c35422729d7b01b49a94df5282c4496423c578e7385"): true, + common.HexToHash("0x76796847deb19cad8a0f70f49c064f8e65e5dd386f979c9e35ced470fae07654"): true, + common.HexToHash("0x88a98ce8818eb10ac492c89512bad7b3f021be34467ae423ee0004ed31f20a87"): true, + common.HexToHash("0xdcf76b5b51d56b65a69bbe44ba50d323ae2c69cc75cf917886513b874298659a"): true, + common.HexToHash("0x48d656799f451fa599e2f33b199467d1de181a07436e95c1110da225ffda61df"): true, + common.HexToHash("0x2927686db59b04e30658140352d6a18c8d4fd7fe907bde1ddf85388488e5a0e5"): true, + common.HexToHash("0xbcd0958890b48e7fe80ba9ddd03b76358ccd3e5b96f562b0180fc07da3c21931"): true, + common.HexToHash("0x55aef1171188d3160cfaaed5b498717ac260197bfefd849dbb93c64a1d614a22"): true, + common.HexToHash("0x5fbe100e8bb85f49bf23ef4cacf3379fa6fe0e234734c6c2641f2e038670424f"): true, + common.HexToHash("0x7a144a3f15d10a8e1e74f6ef7a3208ddf647b5eaa20570e86eb116c630330dbc"): true, + common.HexToHash("0x3015aa83080617f2023c781b9f3bb18508d835730373831ac81991d6290193fc"): true, + common.HexToHash("0x7d6d23ab51b5031281270118ede575642c6d0693e736c462896cbecfcb407f97"): true, + common.HexToHash("0x69cdb6f5fae07810137d65b87be839ec6295e500c2880eee2f6278e6823c58ba"): true, + common.HexToHash("0x3bb550ffb475b60f48a09798f73f7d8528c793b4bac01d471d29c33f2d57fa07"): true, + common.HexToHash("0xc3b2260b0126e4cad0a53941eea65280a35c1d0fa8a88d29cef4ed11ef3a5d46"): true, + common.HexToHash("0x53f91c5eea3579e5d41de95349707df9b579122002ae6fb559f3c2f35e4b1d52"): true, + common.HexToHash("0x3c44701a0c903afd053cdcb93db4e3e4e7399fc9faf3ac299316b2f74e21902a"): true, + common.HexToHash("0xce85bf78e977e7fbc1bba9004715cf6991bac6988ae3e4f88a960963dda397c3"): true, + common.HexToHash("0xe074792566155c6a850e286bd95d2ef4a37421e99f15471792c8e451896123b4"): true, + common.HexToHash("0x4c80cc51a37332dd827413f62847bdee514776ce6971c926529b4b80ea723090"): true, + common.HexToHash("0x752a45bbcb5cb85563715155baa9f311e7fe0d44a6b6c1c254e3b90b7fc2b1fd"): true, + common.HexToHash("0xf9e58af07082a151d7c934b94a7ec97b79ee8cf1c6879525a9ca9f9637c564fb"): true, + common.HexToHash("0xe0e932be990b6c6875d48750636eeef59da6b18167b0039c8a3bed63a03c6f07"): true, + common.HexToHash("0x9828776edcaf16be6f0b63713093ac02c5039cff4dcb3e7f7867f75a7e2e99ed"): true, + common.HexToHash("0x77a11132c1b0c25c5265ccfc7c460d452a501a3ab2ea4d5485a46d2a6b63af56"): true, + common.HexToHash("0x75254f5b9c421f1271e2441316318c947249ec9fbda972c447382ac097662e95"): true, + common.HexToHash("0xa9add731db0bfe8b29423bc1785fccc96c7f774218c7c7c55eef7bad1ac04f4c"): true, + common.HexToHash("0x93f2a0eea938302513458c16cef6df14dd9e264e27ead8df46f809ee967e57a1"): true, + common.HexToHash("0x958c1b4be6492755f7d6e47220957ac4a5c492cae7687ff964d6093ebf018383"): true, + common.HexToHash("0x9e9fddf90064d7de8ece28a08781364f806042dbf6e19c3e330ef666d9fe53eb"): true, + common.HexToHash("0xb8160eeb5562455c8f42adf5e8cebf647873fa2f6f0b44b39e0e2c9eb57f9380"): true, + common.HexToHash("0xffe662d26b12e0246eeeaa0bf6444a4d701ad5b1ce2dc50c01ae0e8e8dd6dbe0"): true, + common.HexToHash("0x11af44deb7c8bc6200bbe22832aa9e7e0b92a393fa95e7297f678e10dc56b65a"): true, + common.HexToHash("0xc10c076029840f7d2f0c4422fe8dad06f1fc47f73a1a0a1ff3247089a7e5234e"): true, + common.HexToHash("0xaf6ad8e5b79dfae28eec76eed6b2ba3d85abb4eb3d9e5f7969b045a92ac724cc"): true, + common.HexToHash("0x57e5ae6d973d901a0901325ae567f114b4b1800bf69b767d4c8b42310701fc02"): true, + common.HexToHash("0xeddc92e3dc1b3b72ccd0331a8611dd34016073a08658a2909663346fd2df1724"): true, + common.HexToHash("0xdd2bedae8887a6f8c7f0a785d0a368c586940df573636d82a1f471dafa5bf138"): true, + common.HexToHash("0xa5e7697136ab0737ed02e9799df703c9a19ac95b979de6382b696d03da062621"): true, + common.HexToHash("0x282c4b7b06ba4a55f4fa32f1a8609d48b34b86ac7a81a5bdf559fb099935ab43"): true, + common.HexToHash("0x6573cf1609d66650061076c29ddc76210ccc74faf815c318f87360690da1bad4"): true, + common.HexToHash("0x4383d85fcb8d934b29f28ee9557f4676020255def426cf7667520d990d4641e6"): true, + common.HexToHash("0x1af0664f2b20ba08bd58050e1d47b534339ea9706524d5411c6283aca33a7c1b"): true, + common.HexToHash("0x35eaccf2ed51c2aa350b925b79b0adf851b7914db213db97acc8bbf8d59a97ad"): true, + common.HexToHash("0xfb833580b4c4445a7a2ab4ef0cb3095b3aada375b046da14139f42dc1b3d6025"): true, + common.HexToHash("0xf158d9b5bd36ab55c52ac3fa47a67ad89dae22aa63d615d8c9a7d5ef85e518e8"): true, + common.HexToHash("0xf76e2921bebcd60b5ff79ac65dadc37eebc6dcf7a5f7bc02652dbdc0f8edd928"): true, + common.HexToHash("0x76827180d2e483605f57fe6a91f37c16433cf0526e5d8108c77c799aff6c3944"): true, + common.HexToHash("0x5291ca2702d3cb2e6dbbdddd60242ba136ab7b250c39a74356ed0dfaa00e48ee"): true, + common.HexToHash("0x522957188c33654cf6ff7c187614ffc2fa00e05fe7caeb4010f9dabcf533963a"): true, + common.HexToHash("0x00842234e56a8aee269a65bedc99196e4013792ee750e1af6ba3cace6911f400"): true, + common.HexToHash("0x8770d277622e5661bcb102ff3a99543353c99ef04afe5a59fe53b27bdbe81313"): true, + common.HexToHash("0xafd8c79a5193d89c58f48cc99c219dd72267c06f83d2722ced5745d63a0d2357"): true, + common.HexToHash("0xb4ebc03e5657f64fb8674fb646775bd61814a998373b1da31ac3304571de3a3b"): true, + common.HexToHash("0xb4df772e90d95ad40ca23f55fa3726348dcddb21d74650ab2f5d2625b4e13be7"): true, + common.HexToHash("0x93c104110d47178628a40d864e80ee463551280788bf3b23d4562238b7b006b8"): true, + common.HexToHash("0xed33a39fa900589a3e3f0ef0784632b9be228081657d0a27c8f3a9af8cb34d49"): true, + common.HexToHash("0x0506ab60d4eeb6e0115fad5846c8aec0a9ab431a3dd864a710d0c78e0893eb41"): true, + common.HexToHash("0xae8b4fb2f700d05da0c1456088e16cc6048e1f99d71aa478d91be365a82533eb"): true, + common.HexToHash("0xd4e80d6a3b956d7eb34562a4fda6168fa88db784740b432c9a380812c297c8a5"): true, + common.HexToHash("0x0e183336b0e23087cb78a3b27859eb718cab8463c4a8ae748134ae1584f369b7"): true, + common.HexToHash("0x10120a6ed8b569c089163c6e9dcd79acbbf3ee5b17fefb4468884a6f06e9bb4d"): true, + common.HexToHash("0x73932cab08017ba036873b84aba412e876623531eae1ceda80057dbb26032003"): true, + common.HexToHash("0xce40d77bacb0ebc636bed398ae1051e88310c6c5eecedffbd013be52e16c8b1e"): true, + common.HexToHash("0xb57c97b9c545a844f43c9bea8ac3f586632bf04b88834be7e02e91d925b2c50d"): true, + common.HexToHash("0xf96069274fc87e50688d3b3f0a8326c0afdccd38acb8f447b8900146e49f4b22"): true, + common.HexToHash("0x27b1eb1cf140690f3e297cade6ac71e6a97390bbf6b8b15f86ba9a5ef20c4116"): true, + common.HexToHash("0x965333b136c755ba1fbb16aab643fe4875319dafd70d4163bd504799f95e9d99"): true, + common.HexToHash("0x73c45e904c308a42cdd04b4a2f3031696bcc75fb27f2e7d4d52947f8b5b471ae"): true, + common.HexToHash("0x62196856f6dcb3fb6c71e68c0d68b8ce23169e0e5d818869e837961a331538ff"): true, + common.HexToHash("0xaace57e883bce848bbac1ed7931aa4bb49756a51f350773caf0aab5bf0492611"): true, + common.HexToHash("0x315ac16d8cf785d69ac189d53e978c7053e0d41ed0c9d8f7d117760cffb767be"): true, + common.HexToHash("0xcacf8aea85f002e50f05b337c74cbee3af7e2615874692ccd682f65176fbee42"): true, + common.HexToHash("0xaa4d959c587cefa976efa44d57faf0b78ccbfc8c23718fcfd5589d040f2d65ec"): true, + common.HexToHash("0x59f496e0fb21563125e905749d3eb96043c8a9bb30a9f373e5eadc3b3a042116"): true, + common.HexToHash("0xbf52a5148fbbb9ee2a79004b1ee437363b7e680f23ede30b026a75695257e8b2"): true, + common.HexToHash("0x67fdcc17e6a90ed16325cd864d4e09bacf4bda6863b04585807763cb0466e877"): true, + common.HexToHash("0xaa1682f524504bf42dd7181686c31d45cc828e6aa7f37a61ec3d187582d35543"): true, + common.HexToHash("0xf0c12436e7a684d2edf1142d250412b1fe435b8b8788803a0c0a334fdb611cb7"): true, + common.HexToHash("0x4f3f57a6eab57d883e4fb3939f3e4df0a9b900dfc00ea9db648fc7090240c6fd"): true, + common.HexToHash("0xabf6c99728ee59a7c2e356fe735ba9aea2c48fc6e3d5cebf4c8618ccee2decb9"): true, + common.HexToHash("0xc767732013db412f9f34134b9e1a6b7fc00cf2f75be427b3fcf2f066263278ac"): true, + common.HexToHash("0x15482b72cb5aa349b2f638d3c5dacc94c82306c478fb7b5ada260640d9c4d3dd"): true, + common.HexToHash("0x66e5b023c5f9a9b66eadccda989e1687accbec33b24c043b18675f5765d3b3e8"): true, + common.HexToHash("0x3529301da91b66a0c341c80688043ecb872cf43f50a744e9f6f139284cc38dcd"): true, + common.HexToHash("0xbe6c9b67129b5b72d8ef40d4a2a58487846f271be29b961fb78f8e4d9b51bbfe"): true, + common.HexToHash("0xb7fb5d1cf6aa7ab6ccab01500ccf7508f2a51e091feaa0f579521f5d8626633b"): true, + common.HexToHash("0xd55938461abdaf3db12114cab476003c5e06b1d8daa38b96f42c40e551c22e34"): true, + common.HexToHash("0x9746cc1062aba92d4e6b19e53b260238986de6a4fb8e846cb02efdb98628cf8e"): true, + common.HexToHash("0xabbd7e00eb9bda4313aa822af33a60776015af173354299c420947f5610b824c"): true, + common.HexToHash("0xff5a84d64ddb7251d23ac001c45ec619bc817d80c971a003878005a8e51b759c"): true, + common.HexToHash("0xf85eb8cedd6582b8d5b8ea708f562660b673d7bfaf3d7cc78558234e367ed30e"): true, + common.HexToHash("0xf79339e813f815d5e477547c4605cec457e9b8c993d9949d31f27569056a93fa"): true, + common.HexToHash("0x7c074c526ff3725b90c23ea6117de25d79abd3638db0aeaec5935ef818767119"): true, + common.HexToHash("0xdf176302c9c793660b8a03c4060fc4d7b8b0148e38bc1cd80f9573ca6bc0a103"): true, + common.HexToHash("0x6155fa23c55f535f15f5f2dc75196df8f87a86a93aec13c8cf6d6c50a0761d3c"): true, + common.HexToHash("0x91818cbc86a2e6f90c49cf00cee85f3f2a11500b6cdd7cfdee70f83a663eea58"): true, + common.HexToHash("0xb734e55cb8c108f2c182ad356f097c0c9aa836c69071ba904be9c571d36175a4"): true, + common.HexToHash("0x859d245e441802eae94f605864a0e6296234a7ed4c3a1f99418f54427a94c243"): true, + common.HexToHash("0x3ad2789dabc347f52a513c03f485d4875a63b5350d0a400974a1566d024a3fa4"): true, + common.HexToHash("0x1ead49b66da006a1f373e0810e06a4b5ab3d404446fe162820e4ba026643e3d6"): true, + common.HexToHash("0x9654bb616e3ac20ac16bb24cc8b33b900a7096269dcf9a8a1036ced0cfa3b3c7"): true, + common.HexToHash("0xef2e539e9d70bd775f3ea666cf8a34ba34fb5eda56da5297be424ba8731ce778"): true, + common.HexToHash("0x6a7019119e4e38510fcbc8d348b0566e37106500aeb45bc8c3418e1cf6282b1a"): true, + common.HexToHash("0x4bdff5402a12294448ee2ccbef44d7712e74abb96b4ddc897ed823117f244346"): true, + common.HexToHash("0x25ab16642de05a71fe81cbd9574bd240c6e57b4376a8f61ce561759a234d5e02"): true, + common.HexToHash("0x4bfd3404ae4214c5f8a9c51185d5e3a250473e0c0bee7a20076f54066e5eed4d"): true, + common.HexToHash("0x0a58f3ae76267ae69db9a06916cdbc728eb0af28d51142ba63f04e25b983dc48"): true, + common.HexToHash("0x04e63cb5fbbca95eada7e79aa756c6de21878260d3d43c6a3e9cf84cf5477d38"): true, + common.HexToHash("0x07f7c0a6686c8897502eba98b6fb6356111a30475f78896f58c5e3dd77bf9d72"): true, + common.HexToHash("0xf40e024fec3ce4c701f6a435a8706d280a2718bd62a629c6db4c3518d540f433"): true, + common.HexToHash("0x6aba632d0fd841f911bbc9399bcb8f83c41b65dfb611b0357662459b4d9bd74a"): true, + common.HexToHash("0x1ac8a66f853f0ee3e840c5da3f42b7b9e3e806f201e2891cd09e6d97dd5deea9"): true, + common.HexToHash("0x2eafe5bfb7999ed034bcc483e0d319cbc12c3b22c4f38d90d4723e2e359b7192"): true, + common.HexToHash("0x5c9d1c9dff44fbe55317ce8294b9dff39adcd5cdabed1aad282d72ce1b874510"): true, + common.HexToHash("0x890b3f1a6970d8109c94fe3efbea8b84d578a275bc2bf94a2fed793524a51768"): true, + common.HexToHash("0x7f7133cef26d5b99d82efaf66aa59b51161bdc3ff3aca000ad208946f691a9fb"): true, + common.HexToHash("0x07b640483d47da243834e01e40f5ae4c0f81c2e97c91a8c470cf2ea31bf65379"): true, + common.HexToHash("0xeec384a8fd47b0276b39e44930351015fbe316b2f29a003f5c590552f32e469b"): true, + common.HexToHash("0x283f25831cd3a6d94d0d0a7301aed99c8643c7dd0fed572d41ed8788f0d00e4e"): true, + common.HexToHash("0x70c42fb30ad6c6cce3d6a126436e9a8b0b9599a2739b26ca83df562d75be9843"): true, + common.HexToHash("0x1d4a66125bc738a61fd30db833b7ac874f52a10ae25f7fe179319d4c159fd198"): true, + common.HexToHash("0x8dd0f4a1f2b994f5b4988374276dc3c94dc10aedf0f308c1a0a4f22dedb0f897"): true, + common.HexToHash("0xefb8fdb03bddb7cc4355fdc7d7e0ad5fac08ea0804d2fc60c9bede8cbe3be73c"): true, + common.HexToHash("0x25b2bf98719c1204f69d1dd8de562e8f43f582a647dacd56be2170d5bd20a106"): true, + common.HexToHash("0x4673d948e01500b15321961c8acb37157a5f59e6f6d951fda8de5f018af8d8eb"): true, + common.HexToHash("0x427580211d47bd1a6a77859c215f1b8d32bc5f8b6de97be5c416ddcb1b65dfb4"): true, + common.HexToHash("0x89cc0e8088e990acdc65d08e07c92437c3db9e68ed73118b31ec422fbd0ad1f0"): true, + common.HexToHash("0x09379124a1e42defa8144585b20e7a53de8750e83f11eb3c8a6a2dd2e02b32bc"): true, + common.HexToHash("0x365aa110ba3f4b21d4c2dda61189aed59626d844f3b118204c719708fc5f31ee"): true, + common.HexToHash("0x5707885e4bdce12cdc00c96e2e0de30289223f14380b8defa6d726c6fac9d539"): true, + common.HexToHash("0x683f3f9b0f525e330b6aa167acba456c340f123e3b36c259f011a30cb65a45b7"): true, + common.HexToHash("0x6cb9351173968049a7b3e85feeac53447cda210a6b505bf9bb87c3c4c497ed65"): true, + common.HexToHash("0xb749f1321602b19b0286857ed2c802f1b5427dc9e948793c874f524b7add9200"): true, + common.HexToHash("0x6d0a3176717b3c5a9e4faff3195f2af8284774c307002e160639e9163eb9e767"): true, + common.HexToHash("0x095df1fa4d67b9220b9dfe6a1a6ea832d8bf63ad47b6c2589571a7efb4859d63"): true, + common.HexToHash("0xb612808ba182314ad2c5eb3100bbc4fe27a875cc112a37d01cf1c002e2a01fd8"): true, + common.HexToHash("0x4253c1c9060f17d0d3a509912efe42763094b5c6da52273f56558dab963a4067"): true, + common.HexToHash("0x4b6ba4b10cd199492821f0768ab0e73ddba7cb87b5dd89c0f00c2868a6f91498"): true, + common.HexToHash("0x6195516ad7649f47a1ec0fb37790d9886c7ffcd5c801e5bba92a4f41fa6c8787"): true, + common.HexToHash("0x57cd97b0370a64630e6fa79bc0d490ddc982fa5a30b34477e00ed2d63d9c98bb"): true, + common.HexToHash("0xe2967f92c2a10c503cbb0374317d8c066ec05a0058c8613dffc36a73c8322c86"): true, + common.HexToHash("0xa61830add4738de6b3c43ddf409ea9dc189443b3a66738d178ad7812a7740c05"): true, + common.HexToHash("0x145ad0ff920bf60855c42f72e3c945a30783c5d4837fa737de8f0a4289adf5ba"): true, + common.HexToHash("0x2dd4be67d2d24641984886b6a03638bab882a9976b296dafce5f14dbf1bd30e4"): true, + common.HexToHash("0x3fbc8ca4d97419bb309f84de6e13f22be5d296c13c73b821bc77e6da25a6bed8"): true, + common.HexToHash("0xe99266c37c891982bf79d292523a9f9d15d110e223dae393dac9bed93fe8a4db"): true, + common.HexToHash("0x80414f43625303e2ed6b2366ac35217f3e4793d4d82c20d1156ed84c58039996"): true, + common.HexToHash("0xbed57eea995e70e8895fc74089f5b95be1c9a7052514abb436cbfc52733af258"): true, + common.HexToHash("0xe11fa435a23d415df5a5a9ffdf39ea8e0e061b5d3e6908fc4f6169a4bba6f102"): true, + common.HexToHash("0xcaa39ead55ac4f124782b97c3d643825f8b2fba67fd4866970adc0066f638f1d"): true, + common.HexToHash("0x6c2bac650e7b2f76087cd91dbc4c91e7db369e96b3f583065b6f5f1ecb95ecf2"): true, + common.HexToHash("0xf227cfa4dc5959297712986b6c09d7685d6ab7a77fca5525f4de0272241e66c3"): true, + common.HexToHash("0x9719b6f243cd5f25778ebeccd6b42673664a6452c1b6fbbef5da4a54705f6e11"): true, + common.HexToHash("0x05bc51041dcace928b916e66ba72589a5a26e8ce4605b9f29bb791f496d1041d"): true, + common.HexToHash("0x1a18f26549029d81d4a00fc155380dbca74692c64cdc3d057b46cc95ed74df40"): true, + common.HexToHash("0xcc67575d02a56e9508ce02bdaf9c5f5cea2342a9560f45fbf6d5f929f60f0b6f"): true, + common.HexToHash("0xde202a07bdc960bd5677b1386cab86a36f12489ab33f7a3c3c3935371ddf5f46"): true, + common.HexToHash("0x608409bb3a66ca98b29ab9c9b7d5deee1e163bba502e20c2ba8b0cb8d261b20e"): true, + common.HexToHash("0xe7684f5ab76eb6ceb457be6c681c98c77377bfee1c8f182926cb92f8a6e9270a"): true, + common.HexToHash("0x946f94492d7e2a786469c3d4948b3c6dcb5354ccc15f693de641c19e97fad453"): true, + common.HexToHash("0x67648a1215aaf58e011a19dfd015a41bf80b348cc88f0e232ca295dfc127026e"): true, + common.HexToHash("0x1f2e15521336552de702cf432422b2e8769cf53967b102b93fe38bf4d8075a93"): true, + common.HexToHash("0x12798dd933f7b483fd13a9b7f6c7f3a14c046eb2b56514d718e199905528cd11"): true, + common.HexToHash("0xb389436b932633dd9a184257cbabc6c9c61008df5c58f325e15f89bac5cc6e9f"): true, + common.HexToHash("0x60605354568d5e033b5813af20bdbc856ef1d1de78075e52597c938f75ba8935"): true, + common.HexToHash("0x9f6eb8b6a3e892e6f900ac26f5f0e2d21633a6370485b3d020576ab3739feff5"): true, + common.HexToHash("0x9921927d08ec7e61856afb718ba58854e11785943ccf2c7e8de253068cbf9b1a"): true, + common.HexToHash("0x357ed2732dd7f9cf5cc6d396b1e3656fe372326dfa50759bc31c0adb3b37c94b"): true, + common.HexToHash("0xb4f153ee6a4632a156f355e2a0ca809f65e7eba3984b5ccba2df375bcec17df8"): true, + common.HexToHash("0x609d5f8a7a662d73ec2e332b2b4b2d3a0e19e6a67c027ad7c96f8d37a561db60"): true, + common.HexToHash("0xd690d87eb56afe578deefa74ab643932844d1f583d532712a1632552b6cf5dd4"): true, + common.HexToHash("0x1059f9a93b6f81fc9ac3865cd425228bc179ac74648e2b78829cfd477b05928d"): true, + common.HexToHash("0xdc70d966ccd7983d872ced54b4d285a92876f8edbdb628629724103a4467cf25"): true, + common.HexToHash("0x714475b4f4ec4ccb355f9fa68dae6beb25d7267eda242460f8b30dec4aeea63d"): true, + common.HexToHash("0xb6ac437c8e6dad348afdcac06942665e7c7ec7a904adb26e2a93cffdeafbe134"): true, + common.HexToHash("0x7226c91fe6e3b05799738d04c18b714c69a170a5e94ade73e908acf5556b8acc"): true, + common.HexToHash("0xb7d937676cd249e29065eec2fc6c7a7ebc93a61afbdcf5e76ef9bf28d681f7e4"): true, + common.HexToHash("0x3f26f2954dbdc187352a516c2ca22bd64771594f233de5e91ac923635a1ac250"): true, + common.HexToHash("0xed137afe048cd79f98b555d931cbef01735d09c12c004032b861f3e24d58ca4e"): true, + common.HexToHash("0xe040c033373f26075c44346a35198455b5a6e89536eebc750625a24fb65b4db7"): true, + common.HexToHash("0x96ebc9ec15864435f9dc1c0bf01278ca607a87a56480cbdbd98da03f380867a9"): true, + common.HexToHash("0xf53fefab7b7286d7919ed043651e8aa1bdb6157b4d256729dbe387b5684d66b9"): true, + common.HexToHash("0x9057c76d08f16e11a1e1a9d03472a4713a2bf6a2f5099e78635a5febf42ddb92"): true, + common.HexToHash("0xb83270996ed5778f7ec83784d591b69f1306bf16ace51b1b90574dd39593dbaf"): true, + common.HexToHash("0x61233527e8868b4b95a6ea1535f63e64bf26f71d86cd42479c0e32930d44c942"): true, + common.HexToHash("0x7e6c2beb3fc3f6929d70eb0ee66416f596475d2ee28e65dfdeed7584574b0d35"): true, + common.HexToHash("0x60182162e6c4f5968e063e8e5d1d333b82a1c577a162856c8c6549e592822f24"): true, + common.HexToHash("0x9277b07f948a1510a155bc5604a48edec633a19121613a6f6cd917cb3b6b04a9"): true, + common.HexToHash("0x85f52c146229caef4328917a71f2b0be6d011036476c475bbb41dd366bb90bbf"): true, + common.HexToHash("0xa200902f1dd4259653fa65666bb6b9da78218372c023ecc389439fd93f8f9cc2"): true, + common.HexToHash("0x4eb35c71d588b97f6a460b30f9a6621af0037fe6de022f81c4769f72ca56c9ea"): true, + common.HexToHash("0x1d6809fd5a1f7af1664ac725690f3dabae8b9d66bc5163bda6aabc9086c8795f"): true, + common.HexToHash("0x3aa9b7e8ec3d5cd64c1cb3a29a57161000f5dc837ef28d34efdfc2b0264a6b8d"): true, + common.HexToHash("0x6de27a58ace98d7e4eef3724fc248aecd625c3dd8abccc1a07467a32dcf1394d"): true, + common.HexToHash("0x9d9b7760c8dd8c5420517544574ef98b92e48480748b34af222a1cedf9466dbf"): true, + common.HexToHash("0xe79e984a8040d5b877850edc97832568b9973564819f0ad1236815808889ba0b"): true, + common.HexToHash("0x396b68fc27ac80bc7aa0251b7c2f32f7d2ea2d545a5017b7ed12c86be707c392"): true, + common.HexToHash("0x9636126f6c2ffef77867eb92252dac40201f39ba3f7525a3139a088113d25274"): true, + common.HexToHash("0xdc934835b3d5d3fc7b7ba309e755f9352289b41c67febb3ab3ede1ed2eece9f6"): true, + common.HexToHash("0x45dda47d4904001aaf154242d6025dc0cf21b8d25f9088d0dcce05fa9c9c6c22"): true, + common.HexToHash("0x82302d918f9983a9619734fb3e4925accd50411f40bca576c6102dfa00c21870"): true, + common.HexToHash("0xb53eca1c12b04cb2fe697d21a57d08f66d399bd8cc8632ec0e3f29b0c90f47c5"): true, + common.HexToHash("0x7a889f565081677b083a5d5fa18f551d364f2f8b7b13db9df624c0846f1351de"): true, + common.HexToHash("0x9c40c05a2b8df54c31209cd938318292f0573243286f3148e1931d5631b87895"): true, + common.HexToHash("0x60358591bd6b8702cc6f7fb67f8369e85fc293285f37f6f3412f63fd884d6f1c"): true, + common.HexToHash("0x5aacfe39a582d1d1679c1dbfbc789453d9dc35504e2dddb344cc7396ef7c8d44"): true, + common.HexToHash("0x1a5d7c78cde41758809f0f88ceb3aa5326d811bc00b7dd8d39e512c0bc18efd5"): true, + common.HexToHash("0xd1f9a6e9c52e7e565499d873025c3c2d57d05b27233e2f7db560c3921625d22b"): true, + common.HexToHash("0xb71cfd9f2d3a2f8d5d5e05f7c066568b403c6070fe7d93e3d72d9616c057b434"): true, + common.HexToHash("0x60bb7c7a624419c06affe6d4964dc771d271852ddbbf40be2e126f2e9e452d21"): true, + common.HexToHash("0xc2257da34fd404e474b7f4a9c2840bd60c3c9f454270c655d5081d4a199c60af"): true, + common.HexToHash("0x74fad5d78fe091313d3e21d97d937c7485ea8ff8a8488db99c759165931960f0"): true, + common.HexToHash("0x5af353b7b51fd582f24f72e57bfe2854b48790c21923581e47549b137cec9383"): true, + common.HexToHash("0xf64e22514bba51ee2e04bd713db07f75e322a57eec594418df7068edf3df28d5"): true, + common.HexToHash("0xf7d3779697b65700f65f0b6611e976f41c32d3f380e11a73da3f37a8ab187689"): true, + common.HexToHash("0x2816ee21d9b0a1a81b4d910f56497f23b6909265cd68bbc5c3c1515b077770f4"): true, + common.HexToHash("0x7b4832885af2dced89f31505943c95432ee4ae786311752c543ace48ef16c785"): true, + common.HexToHash("0xc0de727c0760293118eb3b6ee232201538672fba929881992f5e8cf8f94983fa"): true, + common.HexToHash("0xe281421f2ed2b221d1695b5170e78c482f75c70a4e71d9357e41034837860a2a"): true, + common.HexToHash("0xc03a228c66884e7b716d95d13c2b53eb118260a1e11d2c048793f9a3da8b89ab"): true, + common.HexToHash("0x9166661035a4d6bc104d5ffa75cac9e4f8ba0bf357572d5ac77b827a14dc1213"): true, + common.HexToHash("0x3b32884150869ef741d57ed2c39665db943c846be0414b9b85bb49bbd682ac8f"): true, + common.HexToHash("0x3541fee6a3199a68261d0a56eb72301c5e4e26b8cb611f3ee14873f920622be2"): true, + common.HexToHash("0x17ccdb936412412df12dec612eb1da50270809d43a97f67d8f5428aa04124bbd"): true, + common.HexToHash("0x5d3a6d9c473e9ee3ceb21667076d0d1a1203810227f454b6b8360e0264550dbc"): true, + common.HexToHash("0xf0d026c00ed8f177b86d0cb0a0ffe161a1c22d3f5ac2d9ec66bc012dc526e063"): true, + common.HexToHash("0x8dcce2574dfa46fa6e38353d763a85008c0ba0d5f1a6c92108a7b00f33405019"): true, + common.HexToHash("0xe98bf5bd4f1f3b8d9559cff2e0064a6a4c432aeb7bd459bf266999456d08d29e"): true, + common.HexToHash("0x469ebd3722dce869c04f4363ef2be926b8ea81237288f18355a5a718e97d1c54"): true, + common.HexToHash("0x5e1bd7a496f702a63d250017143e5ae8bca035372debbab76d5c854a20008acb"): true, + common.HexToHash("0x962cdfe5e4741cd68f36163b2ada9329f80d82e2679a7bd06227a111f45b7b88"): true, + common.HexToHash("0xceaf962608f172590b0e5eb128ace208b86e4a2e42b582d0b115eef88e1995e7"): true, + common.HexToHash("0xa17c94a7c6b139383285d1c9b0fe8d1a6c144a1eb21327d6b488a85ea4492665"): true, + common.HexToHash("0xdb30042751b6c590ad2c7dbb745a611caba8108346be1d54fda2ccee10f6bbb7"): true, + common.HexToHash("0x86c74c469f5f2cbe50ba63decd71989375acc5aedb458de2ca99fedd91bc1e46"): true, + common.HexToHash("0x56d6b48e28a7a03a712660ad46abf6014c642fac1635a23c4373c190c7122cb9"): true, + common.HexToHash("0x916061d350aecf3e1c2e5c98f88bef983942f558cc5a51d80a683f2795d5dae7"): true, + common.HexToHash("0x43606dbe2b0c6583247c8b041c51f16481f663dce8384e7188a32a5fcf9c4da0"): true, + common.HexToHash("0x3e21ea6e174b33bf7171ed7070f935a46cc9b5e3cf4db17cb6cee8fcaaad0270"): true, + common.HexToHash("0x1d8228190aac64e0804e8d9903ca0f6bb9781411171a6ca2c090e17beb4b8688"): true, + common.HexToHash("0x4993ae4cc4692837b722d1992146d667f019a69febaa8b7c1b9f450e0376f9f5"): true, + common.HexToHash("0xa724640a7f7aa0dca0817ccc88f7d63a9d1c83761d26d0a958fd64235f6ea751"): true, + common.HexToHash("0xed5405efa7a93214626718f0cd94e693faafec31225bf2d11a6047971872f65d"): true, + common.HexToHash("0x547ce12c56ee25156cdcba1ed9676ee458d829e1e1893abb9ec0e068620732fe"): true, + common.HexToHash("0xd6470582d2957727c9939d284c1caa4bbb45bb0834d3948d2152e3b85473c8ba"): true, + common.HexToHash("0xe8664cb2608a4eb02b98bf5118153e4af81100686f6ed2885de2f74f30f8dc0d"): true, + common.HexToHash("0xebb005b227d293bf84dc3d86ea6ba376071d45c1db4b19b9389c826c390bed0c"): true, + common.HexToHash("0x923bfe8f3a2959a79f475a46890e03e4eb259a04e3b9344ff8e5654ebc8efb23"): true, + common.HexToHash("0x47330f743aadb77b589ce783bb9cecd5c437f5e2f3fbe41bbcec4716f8117528"): true, + common.HexToHash("0x736ef67947f642aa0bf7fdc3189ee188060eb8f9c02bbb51acd6a03812dd2394"): true, + common.HexToHash("0xb6d0f8a7dd76ff78ac8845094b0e583ee825a7a32e86fc34566ffd7204d05f21"): true, + common.HexToHash("0xe6f8c56fb5d257b5c15cfeb61e09c2a49cc9c4813fc67afb9da4a21ec5242f72"): true, + common.HexToHash("0x713ee6fa5046348a79e0b9725d40530118dcb6c1fc4ddb61eb794ea99bd92c33"): true, + common.HexToHash("0x324f878ec13c8926b40ec138c1118a909701c12ddb51f7df37d46ea8a7af3404"): true, + common.HexToHash("0xd519e64bac315564a05f1912b401e3bb4b28132a341abc7333acd7c4309b9642"): true, + common.HexToHash("0xa2e6c501352a82298d2fa6e3ce729297e94dfa0443bdb907c7de1c9f64f13c59"): true, + common.HexToHash("0xec2843d0bc8d558f2172d0fbc2269fbd49fa81c76066eb125b67b7265634d1ba"): true, + common.HexToHash("0xb8bb002ed2dda3de7df4198f86ebf335f833c70eb75eebc65718a4286e8d97bd"): true, + common.HexToHash("0x40389d7a731bfb9a8bae633b946fe9b22661af4b7ab77daddcb90fc318b26db9"): true, + common.HexToHash("0xc82afca76ec0f4f66247e91723448754960d672849e9c69f17b92922607dee22"): true, + common.HexToHash("0x61bfe85a5c1c97401bb4305afbf4850cd13e9d248219040c06483d6579350ea6"): true, + common.HexToHash("0x3b0932e7f0f110edeaa24fccf651b599847aba463cfc2040d8eccfec848256ca"): true, + common.HexToHash("0xf2271304ac342098f4b9e58512ad957150154995bfcb2bc387c218bf4ff135e2"): true, + common.HexToHash("0xa1d45d6a0f7f282db0f1309933b65e25700095ef4d88c803686f58ef7e8e17d3"): true, + common.HexToHash("0x32d236d9918db3169ac48b69749c3cf858d93fb062e9f179c5b92c19655f08ab"): true, + common.HexToHash("0xdc3fa2b9d6c12ba1abca1d6ee5e620767b4fb3b0161c6821243005fa2ba6b867"): true, + common.HexToHash("0xa5ad3e05f343d004a95061a26c88e6bb7d7b4d37f6b9c695c5e817038fd2b5df"): true, + common.HexToHash("0xd99a8b3e5499a3c22d0179ca2185f78e91b9d8873faa0a223ea94eee6313fe39"): true, + common.HexToHash("0xf1d5a47a875f66c204533bd7e331cd7bb0d0e98f9b9bd6755a2ef54c55176d20"): true, + common.HexToHash("0x9f1dae1f89c7fdc5dc3d6ae9484b15744841fc77a1546082eba88da52481979a"): true, + common.HexToHash("0x20a793ce9a60e83dd910233d42dd72a8dd601a04db8f7c6d02a8d1c25f0761cc"): true, + common.HexToHash("0xc477d387767dfc1912609d8deb8778253a58e5341aa7bff66b906856946d6bd0"): true, + common.HexToHash("0xa58b03ac78df9b57d33bb6afcabdbb8dde00a4e837ee773768f40f3f26301857"): true, + common.HexToHash("0x887b92fb3385cb53d48085b0aed29e44bbfc698fa707353c408c108761ab518d"): true, + common.HexToHash("0x950df5ed138ee0273ce9c2d9c18400eade1596dbf905d4e9eef24223b159c9af"): true, + common.HexToHash("0xdec4f689a0a319fbb74fb3a9cc8583fde0c5d08e3e321041477ffe4f4b2c0bb1"): true, + common.HexToHash("0x63884e2d8a3695f9df78ddd543df8ac778265c8da677a7ea6282dc786aa12c96"): true, + common.HexToHash("0x6e943217be35556204c5db71d140b3448dbc316f9210578b036956415ff04dd5"): true, + common.HexToHash("0x827ee87d745f322cf09a1423c3193bffd29f49839256d318555a2deab435b483"): true, + common.HexToHash("0xca7ae48b7cdf818ef781731105bdecfbac58005dcff74392eeb3527b7ee9d053"): true, + common.HexToHash("0x421565891f68f14d957564e941e043663a5a4260c7c395b31a538725716172cb"): true, + common.HexToHash("0x76a88977a3d1e823b3e0d841aba9761a7245a8b4900091ce1834c0a620a049e0"): true, + common.HexToHash("0x9d06030d9e80dbd90a98d400ec2126860372eeece19614294172c1ab2badeecc"): true, + common.HexToHash("0x2ca9595e7c84607a7294fe7acf82a429cb40c083f383d9b08210889d214f4e1b"): true, + common.HexToHash("0x0a02207d9140c9b5f4d24bc1ab148cc2a3cb65ed9c71ba868bd1975b4f23af7e"): true, + common.HexToHash("0xa2e42dbfed81e23058210fa329d107c7d65707add6ca2aa899ee8eaed56d061e"): true, + common.HexToHash("0xc12cfc4ee3d474f3d947283394c261659365983d96b59a72592dc00beef7cc76"): true, + common.HexToHash("0x537d29cefe7278b39d465cb2dfa049ce3ac54f955c408ed0eb33180bb4bba2a6"): true, + common.HexToHash("0x3cb3d533ceb60eeab3ebaad099348771357630faebd40abbd24a0a23ec0e09f5"): true, + common.HexToHash("0x9f314eb81e3a1fb5b04d247f8ad13ff07ea973396eb7a5a29e35d95337038f8a"): true, + common.HexToHash("0x181064c56951a2b7393c685d00618e8b5ce40bcadb2589044d9fe5eecd41ea06"): true, + common.HexToHash("0x4c1da5174bcfe05e141a99f6df76308919d385c748c9cb99eaf01d999951dba6"): true, + common.HexToHash("0xace50a1a5cfa9b2fa6838c613e323334a2709229e274c9417499b29a72d3bf09"): true, + common.HexToHash("0x4293e6bc863de497a154fc7152790b98be23efb4b560c4094956948c6543f10c"): true, + common.HexToHash("0x7276541a091a809b1c473fb476bb49346243dd3f8d42ea5a1d1237bedd0499a4"): true, + common.HexToHash("0x4b916afa09388165ddd5f28357624bb80c540470f67d10578230de4b0cc1820d"): true, + common.HexToHash("0x49f0b91a1a0a9e60f6f32bbd0aa14575d321567c421e20ec272049502347c8f9"): true, + common.HexToHash("0xb03833724d698a0f880e476c8afa10f4b61bc27f8e56dfae4e6eb80d1744323f"): true, + common.HexToHash("0x45ad70e5adc767b4ca07c3d609f971b12a4674eb69dd144842afe01689466ed5"): true, + common.HexToHash("0xc3a9fe6c635dd21025b72bf3a1fcffea7665c6e809ce52b007c90d4085730e46"): true, + common.HexToHash("0x3d16cd2c88e0301333ae2c6ade5f8b596819db8ccfb0d6b6c6885bc5092fe0bb"): true, + common.HexToHash("0xecfdd0b351cc806805b69f6ae8660ce46c0f14979efba293e7d2a5822abd49ab"): true, + common.HexToHash("0x5209ec9b34bb5727a1bf3693a98a640a59e92276db5c572f48b95ea8b6ba93cf"): true, + common.HexToHash("0x27cbbb4d8bfc7629e0aba5441ea2d4698985052ef432c0e3e3e2822914fb866a"): true, + common.HexToHash("0x44751ec3bba7972e936c0983f7f1d49330c6573ad30017f28de69967ba2c5bf6"): true, + common.HexToHash("0x996322ec3f558fd69fcac34af08a6ebac2ad040454025ce11f1c0f21bfdd2ac7"): true, + common.HexToHash("0x5d14ac257ee0eb5b97930e5db96ce890e363f7aecec0a6e03ca600793fbf05db"): true, + common.HexToHash("0x3e31f88225d7785d6548b5b346d695c7928fbf091d0cc709232736548873029d"): true, + common.HexToHash("0x603f09b2e5b2ba6978847e36cf7a58ce392df45a7775aecb09efea71774de8bb"): true, + common.HexToHash("0xdc92b3e218b3e140abea3f8fbd2c3d50e393a92b55e15fdc83de96440de62ca6"): true, + common.HexToHash("0x0978446fbe919cc287f9322ad12b10e8dd6488a80d6af89d46f1270103bf2732"): true, + common.HexToHash("0x4e00581686dc50eefa029e292ebbecbfb5ebbf2a27abe1fc445b8666fd690b95"): true, + common.HexToHash("0xd433136e3a32aed5767636c49e11c7c1ac109ea4a13f8a4e428bbbeb88c46dda"): true, + common.HexToHash("0x14b2ba713a5e948220889d5c9df988bf267c3a989a26268c8b8cd484268dc244"): true, + common.HexToHash("0x90897cba1cc2238e7e75634cf84be91e2708dcbf52787fc0fd4ad92a5328cd36"): true, + common.HexToHash("0x68dedfd4f8d0a2756c711524efc55ab53c5ff8db7772006fcb1fb80f73686646"): true, + common.HexToHash("0x6912c0861eb6fe627f8737d27d92f0d329179dc0a9b07dd0462f0a301353a5f9"): true, + common.HexToHash("0x61efd66b910c83914e9a20c2cdd052dde41ec6b0ac88e53eb105e30a679dbe2b"): true, + common.HexToHash("0xc7d73de5c2b59f04d587b8479ffcd1a0dbe8c67315eab44187d83f91f7f4cd20"): true, + common.HexToHash("0xdd74973daa6c97a87484b5b87749a449236f1156aa8821239dad145d2cba79a6"): true, + common.HexToHash("0xe53dd8cc1ce3fefdc6ee1eb5ce79de375346455ee4e0fe11f109efa577a41692"): true, + common.HexToHash("0xbaae346c3129d485913e0583841adba069c206428a97fcb34cb0aebcc0d1a25a"): true, + common.HexToHash("0xda7c87c524c3c18be297f26703bcf5d54470412d9897cd4d8e4c6a1504e6d3e0"): true, + common.HexToHash("0xb18dcbfa18db6f48ab2b81475ee804617e42699ab6f01978dc92f3de421ddf4a"): true, + common.HexToHash("0x1344d8c6b0cd927ffa21e20545a265def23c486fa823f0d3ce0fda62cffb3a39"): true, + common.HexToHash("0x4e9c799bc28bb9ad67eaf3659c7ac667490e372d3462f8cf21a620ff0bf29508"): true, + common.HexToHash("0xc962863e2f94b423e7d2979118c26452f3d67e96dcd1808940bcce35f5dd6575"): true, + common.HexToHash("0x43c12b3264532c5c588eeefa3e35a1b5c7b3356655a45b063eab48662fbeedc4"): true, + common.HexToHash("0x0844b4570ec8780c2e89981366effc36560529068143003e85f3cc6d2aafa40c"): true, + common.HexToHash("0x77aaadf03d7cda976fbde7500da9388bb9f3f17425030dee87781e19d64c1fdb"): true, + common.HexToHash("0xe7801f5132b37b54f4d2ca7a264500a7859ac6742770076c7a3ff618c0790105"): true, + common.HexToHash("0x512ecec711018c3a19ec0ff2da92f8142b03797251fa4c204f765b9b404e35d0"): true, + common.HexToHash("0xdf6a81803ad63618cdb48a317af3699f5dcd3ce8656dcfdbdcfe168c39642014"): true, + common.HexToHash("0x3f3e69c731a052fd12efbc124e65e3a053074a8c32f903d2066121bef37a3f07"): true, + common.HexToHash("0x5a8e4ba0f0cd4c4151d14fcd75c9025f13ebf91b2ded3fd358c5b007b7bec006"): true, + common.HexToHash("0xae2d88e4826060834832c750f3dd889ffd24e6312ff9a30ab01e3ad1368752ec"): true, + common.HexToHash("0x4f52a9694343703a3c33db08c1db71886e4482dd08164d533b4653c0ec8430d1"): true, + common.HexToHash("0x3c1b1bf73fef739ddcde0bb12b24d27b2705cc876bd0df2a354b512244e283db"): true, + common.HexToHash("0x99a76f45dac4664cf2e9cbbdfce921ab2dc315d6f69bf1eb13e414e4e093332e"): true, + common.HexToHash("0xc350d3be72d894fe7de7ceff01d5992dad0e26e87ce3a6dd0fd80affbae0d6ed"): true, + common.HexToHash("0xb015aefae93b86ef5345e9b41ad82cf0a53e31764d85c726b005f676fd5c0178"): true, + common.HexToHash("0xbf7e7aa5ff5ff3027c74f1af02152417aeb253f8974d2119f8b2dc8225364d51"): true, + common.HexToHash("0xec2b79e376d9a4f76f87a6dcf68a0f28af4806387bbd041432fe0b2e92b211fe"): true, + common.HexToHash("0x6ef801d918f91097278a27ee680b14483620ae7013980acea804c6091c995c1b"): true, + common.HexToHash("0x55985d6024f0e06a6eb749beea8d434ae258c47f96cd1d46cfca669144ca5717"): true, + common.HexToHash("0x7e4d3e7ca94be8fda51892e8f2f86b349b36fff0a0de09d39353801218cdc439"): true, + common.HexToHash("0x0aa92f3b1969d0708a3ba0e65aac8ca1c31d5e07f9ea37ed8f5df5ba64c15d98"): true, + common.HexToHash("0xa4d19e67a8906327146e71a4b0af44fdf30340ce248256cdb2e9c05a578c68a1"): true, + common.HexToHash("0xa900054fa8425ab34074198645158dee673ffcdc4fde4704c906113b9b9a3169"): true, + common.HexToHash("0x60b2f4e11b942c57751f0f229b88e1389df21717d5e7c410059dcee1433c01a2"): true, + common.HexToHash("0x2fb85412b234c3cbe0c350fd1d3abc519cbc618b6154d8d76934c8a2d1b16190"): true, + common.HexToHash("0x3a7b534e7f66c9256b8dc5aaea77e89e3f87f50eef7fb2bb90fb5a4a5cf420fc"): true, + common.HexToHash("0x940e75a4ef2a4fdfb9ef6a731951644b8a522c72453ba1755dd62b535f87e2c9"): true, + common.HexToHash("0xf207667b5523e4955f65b5df10d3c3a20c019030a0903f89e1f2540a08ea3833"): true, + common.HexToHash("0x43426eed13f47fcfe7338db83b334762c86c2bed52e11454da7fe61ea463e127"): true, + common.HexToHash("0x70a96a9bf9bb616fb279d9def5966c2cb92df2feb78f5eba80fa2b01b8ebc7f6"): true, + common.HexToHash("0x00066a56add0748584b142faae548cf49c0de8b1713aa7282559a1e08cc2271f"): true, + common.HexToHash("0x33febc4f0193ce915795b77b25aa4e58cd8c94f9f471a99b2c00668402afb9e9"): true, + common.HexToHash("0xad94b7f54a3dbf9588da6ae3067911e71ae336dc7d0bfd72846fa4bf74bafeb3"): true, + common.HexToHash("0x325d2d4435dc369aff299257e8d19091b6ffc6caee446b5e50711c4b8f0bca52"): true, + common.HexToHash("0x02f255a3072fef83d167730393452d711e9a4cd9f10d03723ea56428c071269e"): true, + common.HexToHash("0x8e5d30884ee16e1bcfdb98844c3904b410cbda10e5d141245c08b5eba577b817"): true, + common.HexToHash("0x8e375f0700ac14d972810333bd7492e45f2d464fd5a4124dce0a415e9b2057af"): true, + common.HexToHash("0x1eae3f1116e499a3e382fc682c8ffcd5c902b2796121c29bd47d70a4af5c7d60"): true, + common.HexToHash("0xb942cb2e1db128444eb99a1d00aece957d48c774320404e04701fe3316f118f0"): true, + common.HexToHash("0x87158b3f8d1a009a5d1d02b7db0e464db7de408e913b4ec0c6ff6611f1b66fe2"): true, + common.HexToHash("0xcb3a9a4ad5dad0b4962a0a3e3c95054bcb57d6c156f5e8419e86061e02c5105d"): true, + common.HexToHash("0x4854cdc8945cf9ba4895c5e6d19810524ccbeaa51983535d80d9c9a5c772300a"): true, + common.HexToHash("0xad3b28e745b8c8482768c1fb250091907b0fe4536ad14333d052d154043de0a3"): true, + common.HexToHash("0x4ae7bdfe8908c3712449a7ab406706a171ab0d380c54d6b00e03ffcd68128b37"): true, + common.HexToHash("0x2867d0587a45a4720a00f07795228c5e7d6bbf5097676a91685f5e7c7d0c99cf"): true, + common.HexToHash("0xe817e6f4702b9bcc554b0556763d6e8103713bab594c3b1a9546a70e4fdfd49c"): true, + common.HexToHash("0x6d5f8073549fd7a50997861c84c0b3a49ff425639484ab41178f18ecb665f1be"): true, + common.HexToHash("0x73e4acbc201eb9226175b6d78f40dc8f4abd29f1018733468c56cbc8549c4eb8"): true, + common.HexToHash("0x65c41f15fb5161d4f7badf2e6f6e56cd8824812abe17d59107da7e5c1bada25d"): true, + common.HexToHash("0x6812aff5fa4d2830d60cc104cad1e5657e988ea40587f161391d51dd316dd21d"): true, + common.HexToHash("0xe38f0cedaf4a0e13bbd7c9a0a8d13763ca2a4c0ce31beaf4722ca7f1f9721e91"): true, + common.HexToHash("0x99647b84b60f2abd81760bf27b67409dba97b4d7411caeb0c05e73ede83f6b0b"): true, + common.HexToHash("0xae4f6ca822dac045edb6a67826f4d23e301d8e9d6021ffe586caed7961edabf1"): true, + common.HexToHash("0x2986413ff9caefcc5f984a8953640e6d795ac9206dad1989539fc05cddf6e5b4"): true, + common.HexToHash("0xe289b7de95591f2bb919dcc696e6d5febd4e3a62675c2d1de49fcd0ca94cccee"): true, + common.HexToHash("0xae4af8979e4787cf17d942bab081fd3d48b7c5304eaf62d39abfa69751426993"): true, + common.HexToHash("0x06a908549560d82d8f37bf26bb6fdadf10c8012bfc74acbc080c8af130c7c617"): true, + common.HexToHash("0xa05c473afc24a64602f9a3883f05bf42037f3a14e3d91e960d66508a1b535306"): true, + common.HexToHash("0x17ae21b04b5ed377fdcddd05cc16b1f392e7cd43e0edc4f929ea06d1884f3689"): true, + common.HexToHash("0xf0e22247f67885e99cfc1d4c34b4608a8c272999fb07703bd6151a9646b2b950"): true, + common.HexToHash("0x8d87a8b4dde83b47e77b09602ebde4a29a2082195169e84845ca7c3894ba4518"): true, + common.HexToHash("0x23aaa1f4f2f5c73d5f0a8696f65a0f9aba95073dd38acd1414997b59fb3ae2f4"): true, + common.HexToHash("0x5035ef27db9c2751d0f25da879e760da33ae10610dcd0ddbe9b2ae97fc8afdb7"): true, + common.HexToHash("0x7285c470368d41b8764737fb383a7e0ebc5cf6477d8eaf159e0fb4984dd39b3b"): true, + common.HexToHash("0x76d7a771e4b1680ce00cecc910d0525f5d78f595c141cf0df55776afef20a406"): true, + common.HexToHash("0xdf8441acbcb3ac7d06981bf2afd0e5e5b62e10ec922d7a7729eaaeadb775e500"): true, + common.HexToHash("0x6bfdb660725de47b2e1a35ae1260850c5e2c3d814a65c730835c71f45ba1a058"): true, + common.HexToHash("0xeaaea8e6a9a0b630cfa67d55174584a3461d32266e6c318ad5e3d68c37f9ba7b"): true, + common.HexToHash("0xa2d33d91e8f1afc43be5dd6dc6ff8bd8cfd505d0f80d90cd7b92fd4b77ece09d"): true, + common.HexToHash("0xea79bc00a21f1d0dfd06abcdb5347dfe1f8c6356550d440e94cbbce6a3882e35"): true, + common.HexToHash("0xde8c610008507205f84c68e957e604d7afbdbc0c79382251f07cff43ffea5f6e"): true, + common.HexToHash("0x8a7134953d2273b5bb894ec962aaaa965a73429e671e88df2d6695cf9a040e62"): true, + common.HexToHash("0x79844a896438e88b02da6700d2be81081feee7a3fdee06ce99a3ea7d10c6860e"): true, + common.HexToHash("0xe3d2a128464cb4a079f2ae789279209bfdf5ee1b4e6747e7b88d51b5a7a25ef4"): true, + common.HexToHash("0xfd3b6251b912d20ef333a086ffda2cd4fecb985a79360ca5835d1c61be12f0c5"): true, + common.HexToHash("0x52d949d8fd583d6c768549f674457ced00e6044f772eb6e187272f8a016255dd"): true, + common.HexToHash("0x0fd4b9e0f8e1da7465b4714e3e09cfed7ce7a0d2e44496e8c2f4a12b5e0ecf5f"): true, + common.HexToHash("0xc9288251a045457a75643c2f42202ddc83e078ebb8047f37effcb6e9f438cf61"): true, + common.HexToHash("0xa8ac0dfdf2b690c37bd7d1282023071bf0d9e49e1dd0867a65bf6c3b792f9c3f"): true, + common.HexToHash("0x1b7986a2aa3f3b2e76b8b0c939645e6b35667330c292c851adeed86109766571"): true, + common.HexToHash("0xcfbbe0afcaefd29eef78900cd4aa8fbd0806971c20c6ced110250409f6e15463"): true, + common.HexToHash("0xdd604794ab00f88feed2a19a8c5198c12f49bed8764e94d456d88b8a9831184b"): true, + common.HexToHash("0xec3989d7f4e9eb54ede4f252b0b86306bcd3ca5fd91424f410921e2125a30640"): true, + common.HexToHash("0xb6643d7411537008faccf010451d01a6745a574a88d9cc76f0e4a34087baac94"): true, + common.HexToHash("0xd99231e3127a18728b82f2fc5d075801eee10cbe3a3b846e0f2597a8e5272e53"): true, + common.HexToHash("0xe22e30098603d77d087ad9216121725e9907c17430b14da84961335ca5d26907"): true, + common.HexToHash("0x3ca237f49db983d7d391e08a84db52c51d90d118f0db5f8fc4aa3bbe091e830d"): true, + common.HexToHash("0xb4a58454b29ca42b1e5b882e1bc476c435720266bbef88a4786396514efbee36"): true, + common.HexToHash("0x7cc40aee57d5ddc910c328d9186ac9fc5ac38c06a54247dee5b1aa7f2ea94a99"): true, + common.HexToHash("0xb6d5d581166040d86f2397c8db546148f2b72bba050b7d2b1dcc93588dd4afa2"): true, + common.HexToHash("0x7b4fad86882535986526d48cec2ffe1fffa06668b0d9c6fa08955b9d26c4547d"): true, + common.HexToHash("0x3048699a4b46d40633e9521e06896876b6befb388366e56a982ad9de0f365505"): true, + common.HexToHash("0xd34b22e226071e20cc5a74381b9a8919bed728be200149a71cda4781c08df2f2"): true, + common.HexToHash("0xc5f7cb591da8792a5275e9f6f75e4e031d1fdec422bf117b62771618ac947026"): true, + common.HexToHash("0x83bc03e9c17b33c175cbcffb74aedcc601cbc71bdf546fbe3033b051e6b57207"): true, + common.HexToHash("0x01ab06963d82f9b563560726017c584d6febb7d2583655deb52c9548b03e8e39"): true, + common.HexToHash("0x7309416b59dda0272e8e710ce276ae462555fcb207bbe4a0a87c1cde1296c9f6"): true, + common.HexToHash("0xb10da8a8ac94184fa9c44817347ed29f452f68287bc90b9493eb85e2266d317b"): true, + common.HexToHash("0xd21866b44d990ba06e121cc781b98e4524f8548b07d91ee41a10fcce274358c0"): true, + common.HexToHash("0xceb490a77232e3d99aa666e716d619748fcbffb534b5ae0f9bcedea6331b66bf"): true, + common.HexToHash("0x51214f2f161bdbd40828b8e9db9108ca949976497ed181acf690ae7f858fcfff"): true, + common.HexToHash("0xc6bfb5cbf49d9be05bd5b9d86b3ebcd8ce657466a5e5b36bf7f6ba13f15980d7"): true, + common.HexToHash("0x4b8d271eb1eb20761052d994edb5fb4f4b2daa6758b7d42fa4a7361f132d7a1f"): true, + common.HexToHash("0x5281db7cc752643813a61571dd1cc2d6adac48918c6f951732519d6b4913a64c"): true, + common.HexToHash("0xb46890a23b10962f166129ff7d4627615b4ced51300e66b014234fb7168aaa5e"): true, + common.HexToHash("0x0c0a5096a4472246ebec3af6be3377d001c1616d6653bf17d12680bdfb00ea46"): true, + common.HexToHash("0xe3e9625b10dc1ee69804270ca7967e17b4e396b657068a4480de542c44584b22"): true, + common.HexToHash("0xf39457330c806a6270c4dbe7f5d9c8c259c1ae89d456988c0731f5b9b40a2b93"): true, + common.HexToHash("0x197085b35bac28995f9fd804c1ea879dc7841513874ae40dd1630fb42ed9a1eb"): true, + common.HexToHash("0xc3b074f29cbea86eb1489f378b5381c6223ae17513e41ace391a5da9957c5593"): true, + common.HexToHash("0xa1cc8722837e99f48ac6eac37dba202d90421999e0b6eda93dd944b38c8b092e"): true, + common.HexToHash("0x5eb58f48090aae02d3b00fbe8e1c01bfdec912ac60c649df05ca23206f30bd31"): true, + common.HexToHash("0x39d1a2834da50b1cbac9ed6274f0c0cabaa195887ab8ce98353ee7df7014dcd4"): true, + common.HexToHash("0xfca7461be8e9f731fdbb1a4149a30bfef3bd7fa614295a763114274903c6968c"): true, + common.HexToHash("0xd71711a3fe8eb81bdd0f92593d97a2611f1f3be9624693631e1192cc82bb70bc"): true, + common.HexToHash("0x4a60a6874bab322ebcfce7ea563efe46916a4674ef0146d7004f5b5092d8f316"): true, + common.HexToHash("0xdb6cc45d3f1830e1e4373a332dce14fab5d9c72c7680b65558de5d9addbe3c91"): true, + common.HexToHash("0x4c27b6e0c26d832960fea4408ddc20cc4959f36188f3b2a64beae1cfe1b6e9e9"): true, + common.HexToHash("0x26370aae71d04280287950052f06cac81b510a2ddcacccf8d64d0c3885c79eee"): true, + common.HexToHash("0xd0dec9436141d1509f1ca259979dfd2d508bce992be34a954d2770167d8dac22"): true, + common.HexToHash("0xb148720560e11fcea6f5e39b0d0056be1ef97d14aa9310a028defaebf4b75a38"): true, + common.HexToHash("0x18a301265c7ea7a6a0070ddf34b9f4aa5dd96bd612c1869e3428a62980cba78f"): true, + common.HexToHash("0xe4d832b8761cca9e2120446c02592f9da702c959067c9a33a545016e504c4dc1"): true, + common.HexToHash("0xdc825be02cd90b5620013b4b4c40c060a4419ac11f12af65df0c49b7d42dc870"): true, + common.HexToHash("0x5b4caee7e0a0273a236d39bc4197d180027cc0b27456485c7bfb3b6253502653"): true, + common.HexToHash("0xf45e07761023d26685dfb44deb901aa17ec3f4f3284fdbda8fff08352f065641"): true, + common.HexToHash("0xd3465fea1a2a12bd205daede15acdde1511b4d46d4226f6180c315d5001b2d77"): true, + common.HexToHash("0xb03820b29201222db9d5b8384009ba5ad0aaf090c5305d221c9743d5cafa344b"): true, + common.HexToHash("0x1f6ac502c56beff19e67d101dc38f355e9729a758ba5921967b81191c62a8ccc"): true, + common.HexToHash("0xc949d159151940213e31d2547797e6db9bb10c4bda51668034702c7f68c2a749"): true, + common.HexToHash("0x2bd392f9c731f1c978fdb9c00f64c227d79493a846ddf504567d533d9b1f2417"): true, + common.HexToHash("0xe8a642a8449f87ddadada2214cbff05e0adc7a19056f69c937d14ef7ac11bab3"): true, + common.HexToHash("0x7ab6184c8e3524a00c62ba13eeeb4e5b20cc452aebf6c33800479948acf66802"): true, + common.HexToHash("0x984f842e2ec7ae6e7a7165d6079939f99f559716d5c4ab8c26fe1f134dd1e12e"): true, + common.HexToHash("0x740045d29237f388494536e1eb12f6bd79a6172a36430968eca2b0b5ba8d2752"): true, + common.HexToHash("0x85ae41d2329aa3574bbaee12363a263bdfe4b97d180406ab9ee5ad90ec0d2748"): true, + common.HexToHash("0x63fafd10371366a39d623af4eaf354a180e75fc9692e4c763c5b36a5b45263e6"): true, + common.HexToHash("0x3c46192b6833a2505e86c02bf78a86a7b8f14e82b9be93ebde5bc3c370ae7cf5"): true, + common.HexToHash("0xcca76d2713ccbac834f87907af32788c4125e5718b413ec6d20068322a4c62af"): true, + common.HexToHash("0x004278ac29f59c6655253bd54a901b47557759dcf3f7b3d45bf971cefc4dc1f0"): true, + common.HexToHash("0xb2f38524829d17be6f98ac720bab7398e83a76a7151a21e34e41883cd03488ab"): true, + common.HexToHash("0x8ee54ac209c50cd2f8981d5b7b5a475d0a936a45c625b2f6cbc18aab5892577f"): true, + common.HexToHash("0x183a227c6bb7c5a84591fbebb9627f37f7d4faa9124257b88e62b0066fa3b012"): true, + common.HexToHash("0xd8cde2d0302cf932a567b70788b2b961a054b164aa923795d0317121f2df0e8c"): true, + common.HexToHash("0xe8eed22b4d0d7ec4fee31a5a9098c5a43a2754eb9fc21c0184af09d3c29a67c9"): true, + common.HexToHash("0x635e4fef60717b0e684c5fcee9ec6c8686ed50c0dc92303bed8223162de6a52a"): true, + common.HexToHash("0x156f58dfec76619d33c0116ca158423987a05450dc7da93152a6f3fe298f9fa2"): true, + common.HexToHash("0x36f82ea67d06e795c86cd5acef8d727647f21db9b2e5691269f3bca9b51be5d9"): true, + common.HexToHash("0xd396f0c761d042761bd68e745400aa95e86eeca4f7337b5bd1395ab04b2a39b8"): true, + common.HexToHash("0x52382c87c99240089462360407d49f58a8efcddfb307d86e8dc63a2fa9b21160"): true, + common.HexToHash("0x420d40cfe72125dfb2195363bce76f075c0edac4b5e28fb2da3307f7783db366"): true, + common.HexToHash("0x534d654be26e158ce0a8c0ce7cb262978fc461573653f7d39894df5ed5dafb65"): true, + common.HexToHash("0x2816773cd55ed3695d98b6edcbabf476d9949caf41a05fbf5314b3555c1768ff"): true, + common.HexToHash("0x7c5b08999e80dd415f859e672e4fc9c5b6c67debfc19d2ba72f4dc19ccdd30e2"): true, + common.HexToHash("0x6ab037313ed193ed7cf648b12d76dcbec790116f8f6e7d64040b7721a398e731"): true, + common.HexToHash("0x7b96099ad25a095b55b245d4365ef6e34213f07b47298848f7a8563ff74cb6c3"): true, + common.HexToHash("0x38856dadec9afd427f8310b26faa8e895f2009b00f1847e82a06ea5fe5f532fc"): true, + common.HexToHash("0x67daa79caaee33562a4d3f26f505b4d03e7125247e8bd3ff9b3e00d6b806ed79"): true, + common.HexToHash("0xa78b852fae15f8d7c18e35127d2da25b037805a474685da39a2ce5d77e2eddff"): true, + common.HexToHash("0xf99a8728eb6ecfc554a07d17ab3679be292a51d2e3c4f0ef4677738f4c333030"): true, + common.HexToHash("0x2d89a0353fad8a4cd233c0a7abe669049a302457a37d1f833e23ed0ffff491ab"): true, + common.HexToHash("0xbe1f6103cec29bc8178bab0b001b67171c6786e9008c50d24e28ab6a86f8eb24"): true, + common.HexToHash("0x30cb11760fa90f7e6aa1a9c218eb90fb58d71de22d695fa65e609c24ab085922"): true, + common.HexToHash("0xd90977c569dbe8c770347d350bb884271d7226c6086785823ffa72fe4fb64016"): true, + common.HexToHash("0x95cf9e3155ecfec023e05cd695a31555ffc1dba0eb904141729fbbd1806d9e39"): true, + common.HexToHash("0x80fd681d3a9f74997b483fe267f13496ca7af9b97c976ed78b5155ce8345047e"): true, + common.HexToHash("0xd912ed604e843437b7aa2d8718e7e5ec24a05f29935448704acc8daffdc1e217"): true, + common.HexToHash("0x04211c4f674f0ea66e854b2c467b95123f3b9a42d0174fc3ae423fea619af482"): true, + common.HexToHash("0xd4d4620fbe200436afe7c6b8df339d24c06514ffca0d0c546e5c7a4ac60e4575"): true, + common.HexToHash("0x70ed9b2a0f0a98c1bd2b6544d1dba2728f09d8bcddd89234721147cd93e53a4b"): true, + common.HexToHash("0x60fbdf38a33b2730f2552d8c86802476315cd74ed514c256a29f7dae225be0f1"): true, + common.HexToHash("0xdedbe9df269c077217cde73299d137f8c9e15896431ba5a0e18e3b85e7d2dc52"): true, + common.HexToHash("0xf691f2789bd0f61b31399fe6bd700484f03b031de15af2f0b94d9f3edee867b5"): true, + common.HexToHash("0xe1ffbefd7fd80a119188ded18ea71fc99cee64827a875b88a618a4e485768d41"): true, + common.HexToHash("0x06a1e3862996e54bbe21d23a353531fa9e7af070abafde0b6f01340de07763e1"): true, + common.HexToHash("0xae368296d825c2d1c5b4d61547a85cdb7c8941c21d57c9d4d786bff5897db1bd"): true, + common.HexToHash("0x3fdedc2bfda5f7ae29dc491dfab433754c5ee1453682ab741cb780d0a3026889"): true, + common.HexToHash("0xe1a9bb3cbde8c8aec0cdb5be8da5ae75a61901215fcead8504fdade73fbf2de1"): true, + common.HexToHash("0xa778f231768e9af735caa9f9d80ad2d066f285f36f2cfae8fce78eb7f980f96a"): true, + common.HexToHash("0xf3f563cc34ffe5361be490a7872122f7265ad07219613dbb236af2bcf43ddeb8"): true, + common.HexToHash("0x91404790d9835d69632ad4cf610eb578e8d927488e569fb03865c17e3038819d"): true, + common.HexToHash("0xebc4deb30ebfa1e95212d741e894d218ed00a03052da89d432dc68a9f57ea7ba"): true, + common.HexToHash("0xa853c053aaebc4f41acce9bf05ceeff787b6876b11f5d50f23b517d2fc2b16a5"): true, + common.HexToHash("0x1314db21e128b3dcb30aff38c29217a8c42e3cae6032946f7d8878c8c1d991b9"): true, + common.HexToHash("0x616093ccda3eeb337556622ff565318ba19a5801cabada1d60c55c4bbbf51225"): true, + common.HexToHash("0x4b64fc44ea4ca2714b791ba8b9a709454fa089fe73baab7b40eee651dc7c0edb"): true, + common.HexToHash("0x1082efc3b5fb31240a379f106af634f130484ef7aa5cecdbf3eabdad11b576f4"): true, + common.HexToHash("0x9172a4d1536adbbd50f37286eb61d68ecf43287b50562c5ccc9f117d7bedf0c6"): true, + common.HexToHash("0xd03178888aae93dbe922f7c372b56598f70022fa3c9c1d87d6d2715c100e9fbb"): true, + common.HexToHash("0x8112390107a6bd427592b33101787c07989ea707de06d833e4fcf8b2ebaf89d3"): true, + common.HexToHash("0xd8fb6e5bd0071e32c2071c84a0da9129fa1e85a8e612ea3069dfba0c77376d5b"): true, + common.HexToHash("0x0ef6a0a00faa677ab66f5825dadef154061f06c21a1211afb910776b42b201e4"): true, + common.HexToHash("0xe2b87a76b680943ebbddcd1db90af7db05aaa7a840d59b820a56891f5c099c8e"): true, + common.HexToHash("0xafafef049ee646b902fba8c9d1a4dcb448c82a6e848be8919e956ba3cd2371eb"): true, + common.HexToHash("0xee1e0851741f06563930adbdbc5a0bfa5f746ad3423be7a117dc02b8f8cb29d6"): true, + common.HexToHash("0xc7f963fad1e8f37d08a7e6ca03516528907a2fa1c48b42216b8b146346baae73"): true, + common.HexToHash("0x0f3d14d83cf58b9a926558afc9cb6bee7ffc036616ce3b0383edcaee23c45b98"): true, + common.HexToHash("0x521752db9a1a540a727b9e05a6028cdda24b737c44ac8201d24613432b993d77"): true, + common.HexToHash("0x3d764f5ef0e5fdc7e838ab36578dc24d1684b31a38dea6e1403dee8cd0febb90"): true, + common.HexToHash("0xbf24f7e954938d69f33065758085d7f28eb2d13034cfdbcc3861b67204b471dc"): true, + common.HexToHash("0xe51ee3e22323daaa1c409674a65cd1702b15e694bae8bec1802252e4585da486"): true, + common.HexToHash("0x334eda947c487676287c1df5bdd35af97f85424e16c7182ff09b3764042f1e1c"): true, + common.HexToHash("0x7b4e90d3802b56cdaf91682a27454094667c0c902fab2f3c4e478cd5a103b25d"): true, + common.HexToHash("0xd43e59c5db0dd450722faf91824ab02cc13c87ce2dbc981bb33327a4b4aac3c8"): true, + common.HexToHash("0x6febdfb6a8414625174b52801003f56a3f3ebb1c55d0cae675e8a7a8d784dd30"): true, + common.HexToHash("0x0a5a1e12b5d4facc412b293cd8909098115ff5e6e191cc6d812bf45928b45ff7"): true, + common.HexToHash("0xb356da34c596c2bc9670c527a4e6662f6ab4a697bafafd4f76a5785fe57daf78"): true, + common.HexToHash("0x404afb25c6e30efbcd69b450f819cad7db30ca2c119778a7267be0c0e752b081"): true, + common.HexToHash("0xa635c1afbc6607cddb7f51592d9e42928224b6d439879239e6566fe3c010f97e"): true, + common.HexToHash("0x87d686e3e87510092e2438fde005e21c696a4c40596281c52da45c303cc8d39b"): true, + common.HexToHash("0xea949f0932d41ca8f56a86816471e95658abec6f9c45ab8949f93fd9079f43f6"): true, + common.HexToHash("0xe788f368aa0fd387cfac057804395cbed9f50a733460d721971b0fc95c9aa942"): true, + common.HexToHash("0x6ecef0303677d4766df7b8f5621e298f4c4d7d7f4a89f93349a98247fc41af0e"): true, + common.HexToHash("0xc4b99f4c6112a41ebb4ceedf9983a69d0299a5be2d83706ac21ae037109921d0"): true, + common.HexToHash("0x367e8682e540ae30c95360bc61e3fc0b82cbc9015ad7f4601ad7834421079238"): true, + common.HexToHash("0xb0bf43e00e982dee687a0d14c72fc842d3c21bd67d82d4bbf70a5045a4b25d46"): true, + common.HexToHash("0x06574ccaf1a9991b46db032be52191bc361c20c6047e9819b7139de22cd9df42"): true, + common.HexToHash("0x13b4d178cf59645bde1a8053dab37059d235ee25f67dcb4e6bff93c183f4d551"): true, + common.HexToHash("0xfa8e2134859247ee387bcfd0e11256992cf0fca901e9499d53ab9725fe169671"): true, + common.HexToHash("0xad133e9527d547f283619c844437bda3b4df35422b601c3291e82d12c871606a"): true, + common.HexToHash("0x434cd3ca552669d092246562e8e0bd13636e10ddee7f6a53370f6fa869896e18"): true, + common.HexToHash("0x356042daa4577072ce3af40fbb4e32a68c91a363cef60dafa7a5f829437c7240"): true, + common.HexToHash("0xad90cf4431179a7d1a5a90ee6717d572d294554df095c013e849c25661655e0d"): true, + common.HexToHash("0xade98a5e17c94cefeba7f3315404bf5cc51cd9c255c0ecfe2721c24d798b5a9f"): true, + common.HexToHash("0x7d6ee9a733e1e49d8a2a4c325eee3d41eaf4af519c67afe064f0fe8285a0f1bb"): true, + common.HexToHash("0xb4709065f9ecfd3d442b62ed4636f9459da92b9464e2246a7aa58dab0d1e880e"): true, + common.HexToHash("0x3844700a98151d0ef575a3b4b0a8112a5c7554ccbfa0c2eaa5c14eb6060154da"): true, + common.HexToHash("0xf15b5a3b84b3211cb98767fa3c2a1be663515319d0dc115b242e3084782bb4ca"): true, + common.HexToHash("0x6154b9a1aa5b9c28a1cffa65b262b011f8fef8e5072c66a021d68200505aa1f1"): true, + common.HexToHash("0x07abac3dcf64353f3d8a22a1d29c3c25e64994dcd0c94be2c3f616a91dca5d8a"): true, + common.HexToHash("0x91ff9bee4b823a214521a7db71e9ca2f50817ae5d8f9c54ce68f258e2b019b17"): true, + common.HexToHash("0x73b3605bd6d37cc3f17491264d8582bdc7d605e969beca42db90f7a733da0c30"): true, + common.HexToHash("0x36ca8d6e4a193997f720a09c489a2d4c6fc3769459c167c8d7c4c9755df3ccca"): true, + common.HexToHash("0x11b897e9555bd852ba614e2aaeaea015774b5412fc68c134cd0058703d64f3f6"): true, + common.HexToHash("0xa504dacf9824579c385f6f5a6107f4e8d04297efcd4cb961b233f49371d2397a"): true, + common.HexToHash("0xcd112de24009ecdf2c30f2c016779cc2742d65f1f807c20dd07f50322a6d5cad"): true, + common.HexToHash("0x1ad653fa2919bf0ab791c37aef18344e6874b92ba730c434c211c2ef769e1757"): true, + common.HexToHash("0x4aa825beac6e2a4a65e4d401cf4ed0b23069e13a4ef3717231d1faf35c24614e"): true, + common.HexToHash("0xc0a1af0fecf88d6a84c782a07f6d3676a99d81b57e2a04752a66cd5614e7b8a2"): true, + common.HexToHash("0x7438ef44314bc9b94abe782ec0ca0f200955e92ac202f20a965f60e3f9a0515b"): true, + common.HexToHash("0x738bbdbfe83d531b8e97a005304e5664fa0ed32f7e9b687b9ef4883df9378667"): true, + common.HexToHash("0x60e96e154a3a9f1daa6a396e00b06f5d1d612867685c63ebd7732416e25ee009"): true, + common.HexToHash("0x73b03dfcb5b37bf01bdacf3063b298b1c5853bdef350b6a010592a79bc0de7cb"): true, + common.HexToHash("0xe7dce39653880fd7a0be6defbe589559f4e72841a55075ff69d53f53aef725f0"): true, + common.HexToHash("0x6c51eca4b9b6e81e431d97743aeb87852deace5aa8761688d90dd92529a8ca14"): true, + common.HexToHash("0x1decf00406ef541daa2a1639ecc9d802926c2028eacdabe438c3f7a0e56c3a1d"): true, + common.HexToHash("0x338f60e995c087e3b460f43ff275ebbd9c494814f9026f579220e123103ea958"): true, + common.HexToHash("0xe742450816882fb72197c512b374b19e70ba788804318aa85fef54e9ba6a9822"): true, + common.HexToHash("0xd55a94f43a62677ea4a60b98566fd4e14284842f314c9ab50286920af979cd5e"): true, + common.HexToHash("0x69e568bb2585cbf3f00039f22caabe23fa5c75513a4fd9ef00666bfe0b47ed85"): true, + common.HexToHash("0x885ea74be363b8a95143dfa9ae67591e607cf61c4374e31f770f6236c1e3c193"): true, + common.HexToHash("0x2495c544fb3e1b0e0e9febb09e537a4905c15df79823d06cae767ac257f06368"): true, + common.HexToHash("0xa7b167608812f7771fc31cabd375354be006e2f3d3672700a517117681640944"): true, + common.HexToHash("0x2464116b9a261cbbd81e7125d5acc9ebd23577d0d19b1324c69ee2520471fe2f"): true, + common.HexToHash("0x01cf6a5529aae825706b1aa5d73d87d596bda4c48bef8f68fcfa9b1a0f1e7fdb"): true, + common.HexToHash("0xbf63d59ab4e4767bc8d7829f2607fb9f73d62587e33c2b915a11cfa3f1479d64"): true, + common.HexToHash("0xeb97ca74bca21c34efc6b77ee148b71d29ea79f7012998297f044c0942fe8243"): true, + common.HexToHash("0xe84115c380d74c5455e88cc731e7bc6f4239428f48b02c70a3cffa33135dd89a"): true, + common.HexToHash("0x3b0285d952adbfaabd81f5d855908d9bdf5ff57f2e7a67039f90190eb1bd492c"): true, + common.HexToHash("0xa90068ebdd5e2f1d2c19717037d2c5167317527d6c48ec7530763db2ab42b9ca"): true, + common.HexToHash("0xb8db51f1be1371d1e3bd32692f894e90d5a165ddebba3284c13bb43aa0c0b954"): true, + common.HexToHash("0xecb96e5e72b259af36f7275685148d64c5061fe1d5f0f09e6cb1f6468d428724"): true, + common.HexToHash("0x53a8eb84defcf844dc3211250f116f77fe2b233be913397085bbfa2ce8e62739"): true, + common.HexToHash("0x063d995d54b3a5720eccc142a58c5d0db0622d5b21e57dfb850964f023bd6a67"): true, + common.HexToHash("0x647886ff94172eea94eb70d26bfbf7b21aaf13c725ff8cc83fa8f40835d9c96a"): true, + common.HexToHash("0x57633da59be76a6cd16848cef7e2b244a3b1bc57922b092222eeab9c74ca27e5"): true, + common.HexToHash("0x57ed9e6fb0aef76c4b5bcbefa58c62b2452440ab2116d75c88a99bed5b59b381"): true, + common.HexToHash("0x64f55339b628f7b47ce6f8e5bc15af2bd9319e746a58eb85afcb387ef98efd65"): true, + common.HexToHash("0x693d7f471466645ab0710cb07facd983295a8706d206b4d943b1624b7babb9cf"): true, + common.HexToHash("0x7955263ee21c1bacb33b4d841fcb90946b2fb493cbbf0930d312ea3019f63b7b"): true, + common.HexToHash("0x6331903f91cf8c55b4c560cd7609bb8b7b44ffe478d6f2e1eab53b8ca336ac04"): true, + common.HexToHash("0xa9930b0a0dde8ba1fb460092993f7d5e51755687417dbe345586685c105c5134"): true, + common.HexToHash("0x3a22b7e7f8a39af68992ab20ecb2939ee010d5a49791ff0c58055d705f58b9a5"): true, + common.HexToHash("0x92c1f355bd31247c001668347309eae74ac0560eb962256d040dc6fa61471b2f"): true, + common.HexToHash("0xc84a3cf3746539020a2a242ea009e38d4b6fb1be8dda903be7b041ebdb7f00b2"): true, + common.HexToHash("0x500b9aeb17ef60cd7c7ac74df42cb30df8678f999590310588d09fa3105ccd44"): true, + common.HexToHash("0x26a4a5cc9037a737a58b71e4cb3c1d71709bf874d6066ae2ea9b070bef6a7855"): true, + common.HexToHash("0xf03203a34a8ac1c793b5b7871343ea0a96465d2c5c8b93e93d6c9a30b88e27ba"): true, + common.HexToHash("0xeaf74731373cef9e27bd07c6097ce497972fbf0d35f351a4f1cbd6bbece635c5"): true, + common.HexToHash("0x588fd40c607728c035e87a488dce588fb9b205632aaf5ddd1f9d8bf2fd30412d"): true, + common.HexToHash("0x6f6ba9628dedb88635b1f0b7f3780e513caab000d1c055d38d67f76f03620b85"): true, + common.HexToHash("0xff88241567ffd87b2076982bce0fa51880f50a75255519d805c235d8fd500230"): true, + common.HexToHash("0xa681d9ea1548f393dc3d29248d652972a761afdd398ba8d40d74eee4769b7ae4"): true, + common.HexToHash("0xd617f36ef6325c84411a3ef23c459eff1907396913e17c3122f5c855c3a79d0b"): true, + common.HexToHash("0x0229d501ad73a5f0f2a03cd10b85cd2fda99ed26c5628092d45340a2dd7e5146"): true, + common.HexToHash("0xc5a322ab703f8d04b6697cf7ab963063847991283a94b9b2beb7ba6361ea78bb"): true, + common.HexToHash("0xf135818b84274d54fa06187ee96c13a750377895522e6e687843244744904006"): true, + common.HexToHash("0xe473de334ce31a33106544e8d5f5d583efa17c384842fd4d977e4aaa13253013"): true, + common.HexToHash("0xa1c1dabc617f1ba707dba95bc3b9b2fe6d28519d1af3c925ce511c0841f178cd"): true, + common.HexToHash("0x22fea511133992df7a5cb0d8fbc4ab9943d3daf2b760be0bc77f50d0d1df47c8"): true, + common.HexToHash("0x9d4d5370df8763f96c20ba7c0e08bfe8d5059cd6760b1e67b2cb5590ea09a046"): true, + common.HexToHash("0x868bca039757fd5243b6bf6c427eb09bb9345cc50c60029c7c0e1b127eabf23c"): true, + common.HexToHash("0x515ce889256e8b5308af31ca91e582717d9c4f4ba4db77cf171267cf5e08225b"): true, + common.HexToHash("0xc36daad332a36d7defe7deab511619e816e2ef7eadcefae70814256968f51968"): true, + common.HexToHash("0x96a81ed54046616ad1971a292ea683ea3e8c18d499b1bdeef29dbefa4f6e669b"): true, + common.HexToHash("0x4d473c441802e0e5a504f61c72ac6a4d4491e61b752722da7b29b3458c0ef16b"): true, + common.HexToHash("0x2149f8dcd4719fd889e7be14750615079bc25277a4ccc83240b4f2f1b5d1d1f0"): true, + common.HexToHash("0xdff68df5fb5539deaf28524157ff81601d3eaed7043fed7a82cccf71fb644803"): true, + common.HexToHash("0x684fd5d4b6d0547cd896ed4db360956e02ec20b77880fa47034868726a98b437"): true, + common.HexToHash("0x851e7fdeb955f721299cb58b48976201ad62473aecbc2fd030443ab6fbe9fed5"): true, + common.HexToHash("0x201342a5a89937af411aac38f1f5e85bbc4b200cb2854b0775d771c4e8271f0d"): true, + common.HexToHash("0x2779a192bc1cfd084db77d1315b50eb07e925a854d472becaf2db5c7617c121f"): true, + common.HexToHash("0x8f04d25a1d9b33563d302562c1b1f46dfed36977d05cdf02015b89bebf11b8fe"): true, + common.HexToHash("0xca98e1bc78147d8b2f77b588cfe04fda5a729ab124656e921c4456954feacaa4"): true, + common.HexToHash("0xb80e16812c8fcdc7d5c27551158c9a07353c511b2d60c4d782631a82f1ed5e5b"): true, + common.HexToHash("0x8189f2a962438ac74d5628fa894fcd92ded03871f393c45113fdab12cf93a091"): true, + common.HexToHash("0xfc6a90e1f36a334fcdd73d53fb55d15a0e2871e2d281771db6ce1aaa7482d362"): true, + common.HexToHash("0xd4d78027cf8fa965b66655c044dec819a3f14e119d44b0aa0e13fea45b59384d"): true, + common.HexToHash("0x8aaae34a8dd33f7f1fbfff13d8e97be5e615b1fe73b1867a3e29e171e71df783"): true, + common.HexToHash("0xc78b84ba6e8054a2be5478397d699ceba5d89bc9917f759daea733dce6a36e25"): true, + common.HexToHash("0x4a97d2664dcb7808bb55e5627c539fb0448d95541054cd88e13c0f202ad08002"): true, + common.HexToHash("0x8537afb74a49b47b3f5f87d68a77400f5175c3f5362c8cdbff05b1f77128d40f"): true, + common.HexToHash("0x5b6f4defbdc180e62da2e55e4fdc42c91492d63c2bb37b63ccaab327ed24d8f6"): true, + common.HexToHash("0xdc71d24db2886fba9176f9616b685e1ddcf44e62844bd1b8408709920d17c10c"): true, + common.HexToHash("0xe5d47b01245210356a4814f7f7a4d323455a55ccc5eee6a9332d8722b33ef35c"): true, + common.HexToHash("0x1877338b2b58189616a13e83f8138ee27b5ef7a9fdb7bd7f9950407fb965e6ee"): true, + common.HexToHash("0x4bb69c6450b97d3cc850c5c988bf904a0de251cf0da77ed8ec7bcb0cb0c562a9"): true, + common.HexToHash("0xfd8a73dcde65b9e01aaaa44cd53ab18c74d8eeef00b7639f4f4b82753608c64f"): true, + common.HexToHash("0x23efb1ecc6af11440306073dfdeae65da78a626b8d5069618e639d96bd70a2d9"): true, + common.HexToHash("0xe8cf25670ba0aa7cd7399b45b0817941cbcb4fee0fab8d5f326879c42f06375b"): true, + common.HexToHash("0xca09de17a03aa1d532f19eea7eb8262cccfecec472bca9531c4f7fd7225c5769"): true, + common.HexToHash("0x95b4ff37f95f83036d15c21475e408cba3fd07e1f4c25028079ec176009cce02"): true, + common.HexToHash("0xf281788e49c9c2817457605262fdb7796a9093ca3347f6828ff56c3d3ac0c165"): true, + common.HexToHash("0x41613458aa21444df5828d066d520b56137b64736fd610339e283d3b7345c160"): true, + common.HexToHash("0xce4278838ce6853eb5c627d0a95595fbd63935e5643c12f7c773a16fc9e28ea4"): true, + common.HexToHash("0x3dd0c9433b6922cf287a0081197a642dd9c8116c9e1192335774db76ea0735e2"): true, + common.HexToHash("0xf96e77ace2c382ec9e555e7ff3c164816371ff4b9c680ec66f6c52f80a554729"): true, + common.HexToHash("0x9c5a5ac7049975efb2fff5978a695eefdeccdc7a5281ef86c223a7fc64ee486b"): true, + common.HexToHash("0x464ab6aec82cf3bcb1d13adf58f4464c9a45a7a561dcb8a41ee9c928ab3a9d9e"): true, + common.HexToHash("0xe1a65fc28a4b0d59ed470f74d9da120cacf353b8c90ac209baf5267d17be5b97"): true, + common.HexToHash("0x784110c25a63d467e98687394f49ba5a50912d09668e24fc3b360abc70063cd7"): true, + common.HexToHash("0x8cb574c36ea374d5bfd8337421b0774f4a137339db256fed80a43d32ac68fb4a"): true, + common.HexToHash("0xbceef1c9c1132cbf3441fa50128cced33ae354d0a9ae12ad3cdf4fca1941c543"): true, + common.HexToHash("0xc4470ea49aa36398c61a425d6b8cbb3bcbe0404c697d6cb3f52b0b23443826ba"): true, + common.HexToHash("0xa4b176637e995ead16acdd42171bba029b8761f568b35e6bd681f28b8f9108c7"): true, + common.HexToHash("0x8ecab0f0e59bda31921c09e68372bc0ebc119d1e4b0d62b9b458736a804a2c73"): true, + common.HexToHash("0x7bd0c815dc4019e17c29bd1371ab4709ec881bddbad6e3856dd67bcfa4bf94db"): true, + common.HexToHash("0x3fda25b4d1a44f3b459d0b9cf11daa88349bd63fda5a59234ddce2a8781ada07"): true, + common.HexToHash("0x33dd087ba62ea279ad9e90c3622b3c2a0bd1bc545115b3c2bbd43260a5306365"): true, + common.HexToHash("0x2d37b1f90d68b5078a541ec9e4f480aba289dae0a4d31d8f2787e4f140bb747c"): true, + common.HexToHash("0x7200912af494513122cdcdc9b1389c4d6ad49a8727ebd5562b577d0f6d111659"): true, + common.HexToHash("0x52ca4d7f12006c10bde06e8dd18e77d06c39047acb6052158a1f0db4baf16139"): true, + common.HexToHash("0x04d1b521c98119e3d8d5c40021d004afdb54c96e94f826beb82ad0d780ea3f97"): true, + common.HexToHash("0xe1a473ca0e57b39ce5ada9e2a9454cbacecaad2df6d8568b97a2adaacc63818e"): true, + common.HexToHash("0x21c031bac75de4089bd161d775d94ca6e496c49395c110ae7d4ba422e0d4acc0"): true, + common.HexToHash("0x38423d29f39d2a018182acb056a21c904718a050015b37bd2d436c100446e57f"): true, + common.HexToHash("0xa0b1b5ab419be58ecb68372affb9b7e61cec5c535ac1557226ef7ee52f8a1b55"): true, + common.HexToHash("0x2e469b719996f13e963a1ac655776eec8f1e4e302746f928688c9dd8abfde4b8"): true, + common.HexToHash("0xc1f2a501d51adf63e51de567bcdc3afcb29c137ac6b3254d3816f572bab80658"): true, + common.HexToHash("0x038f8ec356b4453fe3fdc27e270734c06694ad17f49fbef4db809227fd410875"): true, + common.HexToHash("0x5cfba3e4c7c866a8b3071847ba3a45e43e32b3b67a6a798955aebe933ca8528f"): true, + common.HexToHash("0x1f6ed551606113241aae6212f86bdc37364aae62c611bb75b1f4c88ff12e73bc"): true, + common.HexToHash("0x2ecce0f4c50ac42a2d4e4b98427802612099be5b8df92e9d0613ab706cb70469"): true, + common.HexToHash("0x590e49a6aee8a43317c724611f795afd5617afccb71e92c767e63425ec732047"): true, + common.HexToHash("0x8b2890c175cfe3b4e8abfb10975c96bb62cd554ce7b83d57d9130d6520db2764"): true, + common.HexToHash("0x0ff9d107645f252738ebbe62ee2e5f070e4519cdd22a4ca0ecf3933dd7756339"): true, + common.HexToHash("0x0898fe2ce7df3fe1203bcde4a21415aeac4459558d1c40313a377caa35d55960"): true, + common.HexToHash("0xf3e29089aeea08eb14d2406338f418f89c0742c234440b4168f04932e3660197"): true, + common.HexToHash("0xf31476a5861ab4b6c6e66f7d0fbb5de5428aed42b55445bfa3414a9707308d56"): true, + common.HexToHash("0x069a6138aa26d9056b311d53fdbed6630c706910e1b0c365a9a2ea6ef8972c6d"): true, + common.HexToHash("0x80d6cfdc7defe9d89f202dba6e72aec5daffb774d53c3d772bdabef3d2d2bbb6"): true, + common.HexToHash("0x73df17e823aa288fe202a0a2d15f1c6c4746dbb14440c3c2c221307abc41d449"): true, + common.HexToHash("0x62ecb6dcbf488fe7e5c0820cc486a70d966ccdd1ada29bdd6ebd416b0a029dd5"): true, + common.HexToHash("0x06a61f88f1b82b13607351e8192a0d550138c72169628da90e8217b88f949037"): true, + common.HexToHash("0x2fab2328933b82ad580534b3216d2237a96b3ca2d5bfd073f88d9eb4633cdc02"): true, + common.HexToHash("0x1d7a1f995f8fd2b02bf031842207ccd4d00d0769bce6e158ab86b9ace5cde19f"): true, + common.HexToHash("0x95efd4b5308d7893368255ecac3cda2e86fa86e7ce11d78b1d97ce5593f7fd96"): true, + common.HexToHash("0xb41c220e468c9995a0f2f4618627ac3151384d6a384c00d20cb8e8c11f39231f"): true, + common.HexToHash("0xa13366c0e8d52b586f1e6261c70fb7d1900158533684f6a06c704eb473f960bc"): true, + common.HexToHash("0x975883e08431253a64ae34802039f402a61bccf0fe9fbcdcd753484487be8b80"): true, + common.HexToHash("0xf73a04615c40a123f701f9a19a964e6eeee0406529dede32ae5ad65d3426cfa0"): true, + common.HexToHash("0x476dcfac0275c10dd08b8203df8a3792d0454cd1941441088f2f711c23156da2"): true, + common.HexToHash("0x150ff062fd8aced9b70a0f65fd84e979b38aa5b20f3c60f9b60b7fc18604fdf5"): true, + common.HexToHash("0xced8ed23825e99fe4f9f1c6402c679f0bbdc86c3e3087bb72ae1b739eeed110e"): true, + common.HexToHash("0x38d87938634df9015907096b5fb30d60b569624060ba7fd5c946ad9f30cab610"): true, + common.HexToHash("0x922a3a18f67ac773dc588a7183944fecac92f32af63025ac117fc9162c0cfb38"): true, + common.HexToHash("0x02af1a9668b34acfef0d24c782594c9fed0957863f9b5c40566ea73c4e509506"): true, + common.HexToHash("0xa6687356eb3f3ed096a88ffd5089eef6266b4cdf59af57e823e62abb0705091c"): true, + common.HexToHash("0x88a58a1a3d841c5d9586e88a52c5abef6d718cfd36fc4dee656aff02f42b943a"): true, + common.HexToHash("0xd4cfb8011758281841f71f8679f12282083a18f83502b1049cd9a711aeb5c2ec"): true, + common.HexToHash("0x096930415147e4018559a89a11870726b5cdb460b4be7a306eaefab25723746b"): true, + common.HexToHash("0x5a9a633edb95bf5e20991d87291ccfd7c619010dddba3f2258423f7d2451dacc"): true, + common.HexToHash("0xbb3f4b51d9309b3de2f274e18c3eb84e1cd100334c6292d7d8a1223906c3d036"): true, + common.HexToHash("0x257bbd879be4c17c3a4875741678588f1e81db839fbc5b98a59cca4fdd682b33"): true, + common.HexToHash("0xe3767a03c1c022d492a3bfe9d8563fe2d04cf4b3d8335130b3c1a997c45feaab"): true, + common.HexToHash("0x946ca4cb5c7aa54482c583e7c7b37e9e1bfe0d781e0a75d454cfa7c92e3f256b"): true, + common.HexToHash("0x7e56ae184227e44f41bfdd8789439d423dc3a03a52c8b43bc6d150cb3655d991"): true, + common.HexToHash("0x30484cca843d49b2b024b89f7e5bfd8fed81eab131775c5bc78860ebab8117ad"): true, + common.HexToHash("0xae872ef23c92d9fb2d4d8495c317b4cad1949f43657dbe7d2dda559e3f046160"): true, + common.HexToHash("0x64869dd5ac94a88cb922725ed10bcf52ce5a0947e5d14ae8995390048adf095f"): true, + common.HexToHash("0x8c18f768c6aff2aa9b37cf6d6c792d6b9fce17ba9566075409c9d6a7a6ba0684"): true, + common.HexToHash("0xb863a1ae9a1551cb53227164da08afc1f6dc09403cb4e334e8647fc7fb2c5368"): true, + common.HexToHash("0xc6c7a2df6959138435b8dd5085c54df23b26c5329d7f19012be997e205cbdb54"): true, + common.HexToHash("0xbf39bcff87ecacbc0c36764c54d7ca513970bb13e33d1e4b215f676ce31cd066"): true, + common.HexToHash("0xfdc1c32e6db6ec5167c0ea804e458207a59994be847be61c1d3982d234db83f0"): true, + common.HexToHash("0x24eb581624bccb395e202e4391195e0fcf9b67e42d96a274d4e294af55deea33"): true, + common.HexToHash("0x3b2788bd86e3cec86cd43dbd569aee75940d03a1bcd24d4ddf52509060a9a4fc"): true, + common.HexToHash("0x9b65abba531d195eabaf9709488e62e1090fcecf5282f648d0ff8a0dc90a4611"): true, + common.HexToHash("0x787a73fb8eb4dfe461f33f27aa6aa4530fe786f2af6b0459866fe02588d2a6b7"): true, + common.HexToHash("0x5423a8f54812fe1ce82bcd6a0d25a5a5c02a1af26b45479f3700c7d5cc75523f"): true, + common.HexToHash("0x54dfc7e0ee88b92b694e6e68c26d8c78ed3ff7134c25bbf65b973d7dbe928352"): true, + common.HexToHash("0x91d7e5266bc9db3037cd7d06d583655fba3888a3cca402e19fee82a2512a5ffa"): true, + common.HexToHash("0x3dcd1655bfe8f0c5257ae9ee978f08ce5e5a1ee80c0e044cd6b0c130766e58cc"): true, + common.HexToHash("0xcdf08f748c9298c94425e27bbec916b306e1297f8821c2203146232ecf022d9c"): true, + common.HexToHash("0x913f512a50dbecdcb64543205aede62e2a58ad405bc597dacf33bfa44b541491"): true, + common.HexToHash("0x7e8410927ed83930d092d81aced6e9dd2e0abf43ae3ca1721382239080677b01"): true, + common.HexToHash("0x2d876b1b09687a71140c4d3958ece24259cd1be14fe5a3ff5b9081effdefd61a"): true, + common.HexToHash("0xeb2ad33a1c7d24536c1e10e73d7c6a189bd4a627e4f4d80b1f89dc6b96576352"): true, + common.HexToHash("0x50a75839f9c9ae53ade8964c82dcc50de4b2539f8d8e0425fd022edbe7ef3c72"): true, + common.HexToHash("0xaf8791a4423230f10c2768a4f66058db4fe8748d2347b91b3131968b36bce57d"): true, + common.HexToHash("0x499df08f7f62f6eb3c828f6dba8e841aed54922ecd4746f5d304bbd32106c55a"): true, + common.HexToHash("0xe471fe44440cf81e4af8f2dfb7346920028917a0699d9dec93607f5f46d8d64e"): true, + common.HexToHash("0x098186f2dc9270df8144c4edfa9c219af02aea0107f5376c8f1bd83fec208b24"): true, + common.HexToHash("0xacac62a1cbcf470dba180a465b25ed4aff22cdf2f52275a0fad6cf9bea6fbc46"): true, + common.HexToHash("0xaee3c3d7d1f14044f993b57699b2edd2eb362c5920c76f5aa5eb83f3c71189e4"): true, + common.HexToHash("0x422d8e09471f1a8181366e0229e6a272a36350f0fe068d4731488a065a6ced7b"): true, + common.HexToHash("0xf28380cac9209e5f0033e4f358e72e95fd9db68bc80ac2620e7fd2d09f70ccba"): true, + common.HexToHash("0x1b382449f90c7fecf5b09483417636f382aef44da3ac1f19856d1c53ef559fa7"): true, + common.HexToHash("0x391dd8ec31fa376ec3eeeb63521a7879821a2163c04282058426e00940690af0"): true, + common.HexToHash("0x04a95eccf26093e7d329401548959e5db1d44f3e8ea15be1dd25b8791692a693"): true, + common.HexToHash("0x444b35d09f8bbcfec862e0df23886179d598915e7d5f2bd23f1809728e1e73ff"): true, + common.HexToHash("0xd4ca005451898b4db3ead9b608383d256d7a82bf3271c9ac9199efa2f21bb877"): true, + common.HexToHash("0x769cbdfdcf8b8f1ac5f745099030e641ba96092be72abbd344a27679aebdfbfd"): true, + common.HexToHash("0x2abb69a2f641bc09a2310177a6ad9eb1214a099e10e5c2d23f463e49b38c0142"): true, + common.HexToHash("0xf6725efd5e2da9e67bf68c03d2478617cea353348ffca32069580b3ea24cd221"): true, + common.HexToHash("0x98554a4712e9751b562ad8c739c41613674b2c57ba242c1864bd5c22cb27de5d"): true, + common.HexToHash("0xea28a22a7812f6bf6ddaf0d66296eef4c01cb3c5ea1c7011b9dd59d50cc06bc3"): true, + common.HexToHash("0x870f20d66e3694b0a0f0930799a968f7ed55cbd178ecc522bfc5dcc3f4508d3a"): true, + common.HexToHash("0x886413ae6f4ea53a2f05b5c17ec58a696b24effde43d94ec81f76f3f2b067c04"): true, + common.HexToHash("0x04b2a44edcf54cb952f4161fbb21f2908e7159e3c680836fbefe6ac98e4fa021"): true, + common.HexToHash("0xb2c7f3f0b51b5696a3f158c2363913e6d3042c31539ef1393fcbf2b516bc9c4f"): true, + common.HexToHash("0x9298c8b8cfda7028d182bb7d786d55463eb91bf0b001f5ef832a14857c371298"): true, + common.HexToHash("0x8ce337daa9db05a540ae6972d9f44d003c2cdaee905ef7fa6366a2253570d0d9"): true, + common.HexToHash("0x43a6c22f6376263a00783d573a555cee864d3ec6001e609a89740fad6ed33217"): true, + common.HexToHash("0xcee4665d6da082450c2bbdef745dbc36cbaac27bd3a30516c10ebc2b3d96c9cd"): true, + common.HexToHash("0x52d81c4cae9d79fe44e07e00de92ed03d11a1913bbfa3824c89011f4cc509693"): true, + common.HexToHash("0x94160317d896b3cca80d8b562614ca0198b00314dedc09746f28f8016f5021f7"): true, + common.HexToHash("0xef6760893a3867afdb71226cc2313876a65a28d09b9876ebba37521c911e8b3a"): true, + common.HexToHash("0x49050bb3ea0b6e8ea0a8146ffd597d6fa11afed5f9e0b62fa9ae438b702811e1"): true, + common.HexToHash("0x1dd129dc415ec260b01ff2e3293ca4b2064f24ed19c807e9dee6834e2d44a7fa"): true, + common.HexToHash("0x14ba6efd8c37595ea33666b8f66680e1598c2de9fe509c3c43f3a47ba2631291"): true, + common.HexToHash("0xedeaccd54145f70a1bf34355e24cc7985132f71044b8d44a0a7c5d5f7e340b31"): true, + common.HexToHash("0x19f02122c28401877d5d1b678600b28ebbdfea95be53f2f3d0263fa64ed6eab7"): true, + common.HexToHash("0x9c103e7b82ceff6109a02642bec08bb5cd33952076559b80e784d33675f0ebd5"): true, + common.HexToHash("0x13d1d3b6de8e11587c2c0774ce2143e49eb52cb5a326ee0518d35a020c5c62a1"): true, + common.HexToHash("0xee97a3a16bf84ad0df60e120b0cf7c65d902ea263141c301ec0168e71704a99c"): true, + common.HexToHash("0x820e51f62036e736ca1193efe024de1380df9f07c151f8780e4c6426e69faafc"): true, + common.HexToHash("0x46736bbe276deb34f040f691176c63bf547a0cfbebc754c5c8e075b888524f7b"): true, + common.HexToHash("0xc2df113d44eab1b1fa2ea5b9d95f929938bc4f01de5c69cfffb41f7e24856a07"): true, + common.HexToHash("0x3a1e86f9ce160fbdc9f3ebe1e2aa8ff811c1dd123cd2d9b237b103b7d00708a9"): true, + common.HexToHash("0x8502c45ef4d6c07aa05032bf7b07c2bf3d1a4978e9d43e2321305b72b1b52f25"): true, + common.HexToHash("0xad67c044a896378a4582c01f09dd604c636679ae3dabb9dfba44206478675556"): true, + common.HexToHash("0x787f6411c05bd715faf938089848d7a81f507c23290925bfe9461ab07cb0b0a7"): true, + common.HexToHash("0x3cc84fc40662173797fc86ca88c2a2b6a7ed17045ec7a09217c1d0a295af293c"): true, + common.HexToHash("0x379083d1db03660adfa1a306ca0e046aa294e7a4854a8c867c6157bfc0ed4424"): true, + common.HexToHash("0xbd6dc8210b56d0c2a9e84ba945fbfcd8dc5c50a16bb69596937d1d470ba832da"): true, + common.HexToHash("0x6ffa66e9f3b9a7115221f87ca5fa2c36ff008c7c66d00e0f8ecaa610cc2b3090"): true, + common.HexToHash("0xe1725a1af660adb6c4314efebd69a46eb0a05e8597468de88148fd8489985fb1"): true, + common.HexToHash("0xc022b903696e0ec2364eb2268eacb7b73b24bacea25c9304bb1161b4b4f78c0c"): true, + common.HexToHash("0x7dd51a32f44b54363b49adaaf949f989a13ddb319dfe80184c4ac59cbcfc16a1"): true, + common.HexToHash("0x0f7ce3d906705374d7fdb458007b80112b6ff2dde8eb30fd1ffdd140fb742666"): true, + common.HexToHash("0x2e6d36a0b852dd231b6f3f1a34190e14c63412d6073f2c7cdea4138bcc654545"): true, + common.HexToHash("0xcf009944fceb01d4e3b79d83a51a803b525a9befbea857f2a4f66f9d736f0cc7"): true, + common.HexToHash("0x3e7ca9f9c7d26eb84eb9e18ac67b0e4a37dab051436e7e6f7df31b290c43c741"): true, + common.HexToHash("0x9ea9c5333865153709100dfeb9e9a9e956d0d2453abd81104b9d78b9625eacf3"): true, + common.HexToHash("0xa7bb521ec8b7473e93c4ddaf0e27b0c73fb74b33f5c7817f2a0415d3c03253dd"): true, + common.HexToHash("0x8f0b2f9352f5c9c1feb69816e0cb07c0af76a02865d4a02e08cfc96d5a9dafdf"): true, + common.HexToHash("0x70fe3cd5bd090a9975d9985e5552bb7e79e60ab67e8ee23434759bad96bdf46f"): true, + common.HexToHash("0x85a767c494245165e6af30f9cd1f3fd7abef61234a2fec23c14c3602095053f8"): true, + common.HexToHash("0xa7bddeefddae54f9cb04b1242d009efa69bbdc646cff2f1e2879feb0e163e462"): true, + common.HexToHash("0x2202d2d21a73ae668d1493bfeb8cc7b7ac59d26b314ae9aa78c5df04c7b1a499"): true, + common.HexToHash("0xbb03ee8daec3ff855e2bae3536774c0949b17c220cd3f2ff43b9f1cdbea950ae"): true, + common.HexToHash("0x3379f0226648c7333f49b19875bff75fe5a5a1f22a0fff7bcfea3a3eea06a10f"): true, + common.HexToHash("0xbebfe5c81ae8e4195764f65a30fae2497fa8eb3e0d174dc6928e2b4207fddd42"): true, + common.HexToHash("0xbf4d2d89de605d187b0cdc3f8cdd544f841e654d4a55ac657dafcc38b6b74f81"): true, + common.HexToHash("0x00bf066c35e1f69c9074aaafcd4e19908b1ae67605943fa4d89e7167fd7a53cd"): true, + common.HexToHash("0x0303a9d2e44d2f59e6775bd823b72b9cefc4c994e99f0b560b9c0cb1d7cfb50b"): true, + common.HexToHash("0x0035111eb6b2da1499fe1e3edb1837e0125241ba31dd78ba3ce1e4f49855f5bd"): true, + common.HexToHash("0xe4381444e527c1886c20cabd058bd2e2928673344f0070a2fefc3f45b6abcc78"): true, + common.HexToHash("0x6fcc9c7430d5706ab6bda9211ecf87441889fb6be56fad09041910284d991d40"): true, + common.HexToHash("0x306873217213b20438c013c58b7af10f51a72e4216e93f454ff1fcc02efce0ea"): true, + common.HexToHash("0x334720bb0159460b1c6746231fcf50dff46380bee78460debe94c9d1b8234999"): true, + common.HexToHash("0x8ba42c90a6659c66338a74dcc8cdc6f64b7ce3987ad66b78ce85cb4227ce2c93"): true, + common.HexToHash("0xa8ed42f707cf58a5d60247f993a221dbff35a9fe75a47884cc1e39aca00eabd9"): true, + common.HexToHash("0xaac8685b4ec6d4246fb9d84810d1bb7207b43cb5dc76d39eaeca875e80a1a62f"): true, + common.HexToHash("0x474e0f55ecad234e3fa3d63ae2714eac9a1869ac3613090ca439aa4fffe997aa"): true, + common.HexToHash("0x80aff4ec107dba768d183cfa6e095d3f7c2b918d27571cd74aae437a3ab39e05"): true, + common.HexToHash("0x322f1f76d638a419da895b02f7dc570a94a27432c8f836b08af965c57ed3d805"): true, + common.HexToHash("0x8166878c70e1b91fdca4675fe7d87b0e30fce2b1017644462a7de711eab8fbbd"): true, + common.HexToHash("0x2f6642ed0af20682351570b5970313e2343a33fb126c0b8e52a2fd682a8d96ef"): true, + common.HexToHash("0x573ea3870ff740c93c9508bf7d27e16bf986c853fcca10fac386be46fb020763"): true, + common.HexToHash("0x6d614d92769d9c9cf4b030fdb9f0ee9dc98c728eab1c4454e39769295f132a86"): true, + common.HexToHash("0xdb00777932a5bfeb0287818da228fb5a92a67849e9dd39d072fe908e36ab25de"): true, + common.HexToHash("0x94004f726f210fb1cf21a7f5f45949912537ca3b382062635b65ee827f05c387"): true, + common.HexToHash("0xe56cd558b714b3da2e806022f33a0fefd86cdee2a974315a3c24a27be6d426a5"): true, + common.HexToHash("0xe6a20f8b0b8f9de073e2fc9acb6d8bacb2e368cd7d389880c02d6d50358a3d1b"): true, + common.HexToHash("0x9883cfd286fbd201314837575699a90786b7f1a76c6c76b95d4c66c9a2af07cb"): true, + common.HexToHash("0xf1bd50017c016103f2120ce278d79bc0728f0495cc9127898589d72921c9e0e1"): true, + common.HexToHash("0x81240bbe600aaa38532fa29f5c4ebe5d6948d2d5774a298a0da10c43240ce93b"): true, + common.HexToHash("0xf2f36d0677a7774e21d0605b7cc6c0dee973338533fe1564a5eb3c923783cf13"): true, + common.HexToHash("0x3eb741a8071b5b231331e940044f8249c3c819593a68fc849596684068dd9c82"): true, + common.HexToHash("0xb4b7cb9090f6c8c962b315deefc484d0e07c772e108fc22e39813b8441fea73c"): true, + common.HexToHash("0x5feb95b9f560b7fadb516f4d01602ccfa3d5edeaa433a22a70f712cbe20d0146"): true, + common.HexToHash("0xd88cd184e153bb9d7fe1fe615da09ac31e65eb1ebc0edc3aaa3c7d19f57431de"): true, + common.HexToHash("0xd7774c74eb514eda6e7d0e2ada8d90ce86dcd9aab2a2ed2f75febe18c69616a8"): true, + common.HexToHash("0xc78d4c3e8e397dbb3df426e88696ddd32b92677575a455f3af9b75b02d20ded0"): true, + common.HexToHash("0x1c450b1687e2d71e365e193b469e5a142d476fd891084ff9888d22111ed7540d"): true, + common.HexToHash("0x715d514f4e840f39ca9fd782ef0166afc4c02a8e9d74ede7a35cd7d6919fd52f"): true, + common.HexToHash("0x83b11a19953d68472017bdf9ce6e8a49a810c361d52067bb8dbf476633739fdd"): true, + common.HexToHash("0xfe9230d525830d3023673def7582c43157c351812afe49c84b92e63d1a0d05b9"): true, + common.HexToHash("0xd493c186e6b02239b5a95e9abac510c864bc3f5540fbe887ab76b8d3535c295c"): true, + common.HexToHash("0x1ea2c0143faa8fd387992f79136ca62a5edf82711dbcbb9cd917b275b84ef602"): true, + common.HexToHash("0x2cbdc73adea075af21f7afca590aaa09e5b50377fd3704c2e30e25ac8478813e"): true, + common.HexToHash("0x3c64f7cb2b8cd41abfa767b3a89b72e712483ab0d1a291ae816f74484724a023"): true, + common.HexToHash("0x1935c9762ce8c270611f9ab0a4f05790a3d0c0dc920e18f202d0ad1e74501815"): true, + common.HexToHash("0x1dc39d64142f27e09e4b36a2ae5248b570dd1a9106d850efba4d7284512bf9ad"): true, + common.HexToHash("0xb0635e3fa8a1c9810d1b8bd032c4fd249b9b45fd38985a8f599274d6a13f6627"): true, + common.HexToHash("0x71ca6396592f6dcad36d0835933ef9b0405c736bb54323dbbea2bf603192d691"): true, + common.HexToHash("0x122fe7db8d9ad7fc7964d343acb307e86d01c09ab28feba0735b57d17904163e"): true, + common.HexToHash("0x3f7950feb20c7f834f1b3df6da057de708527a7a24bfd78f60437f5303e8f34b"): true, + common.HexToHash("0x06320ba307c1bc5028d88b11f4e68ec4ed725502271680d4e85b859950e55c78"): true, + common.HexToHash("0xcc4a990a6d5e149100d2af98320c4bdd38e027e9e007d20ef030a7373ec1aa6a"): true, + common.HexToHash("0x95ad5ebb8103f38e149ed2fd8c6976297b3f938ee0e5ab46efdd1a1fbf74e1aa"): true, + common.HexToHash("0x360d5978362d368a43a2168b6033b0cb6018dea88838b3516972da32b730f47f"): true, + common.HexToHash("0x857d7b327703c4a30c8209b7ca07b85767dd38e79fe3327170608ccb0a85477f"): true, + common.HexToHash("0xea44900af7659c2103d4d07db02433389181c2828d370ed34db3a8b9dd9b599c"): true, + common.HexToHash("0x155a14206e76a174ac9828bbe17f54ed0de54202b6ffc7fe6ccc2aa0be449c0a"): true, + common.HexToHash("0x1e92b5124fb3f6f33d504c223e9f9996c486a83d22e8f66ff7210d4a60802c44"): true, + common.HexToHash("0x6df80b903489f93014c169d739a8dd6dbbeeee65fc4ee2014d7859a4ab6e43df"): true, + common.HexToHash("0x51579ab1a9b2e1377b5158c1a86bece833ed5971427f4d0a3af219f6cee16b07"): true, + common.HexToHash("0x561d7bf8111a4f4384cf0685969752c8dfd7c8cded53982a5c3365f1a981c2f3"): true, + common.HexToHash("0x2637e04975048c48bd56b15d3fea471881b47354489b1862ad329279d4f66f34"): true, + common.HexToHash("0x6797f82275850f4d8f175e6a9d04c80d48bf13f983155e7edb48d71c000d517b"): true, + common.HexToHash("0x033d9fb9b95b00de34e2f802608d0a52dfbbdc612a17ea8e20630a2902f820bc"): true, + common.HexToHash("0x80da80a5eb8d60fcbd85d58347a9a79bf36ce0fa59acca2c967debab7450b411"): true, + common.HexToHash("0x23078fcca60640027688ab62c05c0f5063aeb40c058e6a7d5d18d8a46c2aa1f2"): true, + common.HexToHash("0xdfcc138251d3639ccf7f1887ab8c220aca5fb4060284950e759b6f81207dbb4a"): true, + common.HexToHash("0x01c22f3159eb35efcd49edcb992c3c4efd9765523d5ead0006946c12787e243b"): true, + common.HexToHash("0x9526b28ede93a8fdcd31c6fdabc78aee952f42e339b33bccc148f1fe46cb5173"): true, + common.HexToHash("0xe72ff1940c28cab2089aaacb6dbe9644134ea8d4058b613c3950ee37de75382e"): true, + common.HexToHash("0xeb7683c347feaab15e2711fe375a93879d0d302a6ee0850ed6e7003a5414bd18"): true, + common.HexToHash("0xf0ec75b61d8ade7399da86b74ecf96ae8cda72f2a5768120908d7b357aba5c46"): true, + common.HexToHash("0xe6d3122ec043c801b99bf187e2302b5586b7648ec013eed412b713b18dce80b4"): true, + common.HexToHash("0x59ef5e5625255f2b1a874028178e093dcf26071917170b794b7ece52a8e02f68"): true, + common.HexToHash("0x5012532fc49813ce9b81acd3eeab69a8899225b982a2ec7d0bfe2cb64a992fb8"): true, + common.HexToHash("0x74e74ed996437304e28f6ca8597765247c8ca49c40ce61ec8b84775af026bd6d"): true, + common.HexToHash("0x1fdd69e387899479b893ae717c227d62f0f22ca4fc9bc8bc985e21c222c8173e"): true, + common.HexToHash("0x306afb51c1b907b723673a167259f3ca4343a9fd70d9f6ff65165d5f217a77a5"): true, + common.HexToHash("0x1ece253b969e1ad3d33ea59794a4d77f2c176d264a28deabba72eb7fe7df8435"): true, + common.HexToHash("0xa6bcc95c83dc9283972ff67fb316cfce049ce14935dc53d4936c39d86d226276"): true, + common.HexToHash("0xd410c332e1539124cfe7eb88a3ed27b58b0ddeeb6414a7f7b19bf488ec95a2cf"): true, + common.HexToHash("0x8cbfe5aa69096148622b37e2e70feda7bbde2674b5ddebd24394c7f9a8eb9d16"): true, + common.HexToHash("0x155417e42cce058c52a3335c39637990f779c819e000ca45c70c12afed4a09f3"): true, + common.HexToHash("0x05baa82c6698c9a767f1b0abea02b39f334f2992d34de80ae2026464007e7638"): true, + common.HexToHash("0x5b7c6ade1864ddf40c0c59cdd79dc99966ed7a9c84eba72d7820e22a22de3826"): true, + common.HexToHash("0xdb08afb70cb3a2711a3743815cc2dc377eef850f24e5fe3a6ef3fc7f606aee4f"): true, + common.HexToHash("0x168ff3fdb0401899ddfca7ac93629fa1cec61a06d5ac3d47fcc75362a30aafd7"): true, + common.HexToHash("0x3ae40b7db70eb8834f4f6086a8c4b977516509d50ae068c508fa052523a114c8"): true, + common.HexToHash("0x557696cfbeb3f885dcda85d2478b75f8cae206ba66d3fbd8e2af459155f74cad"): true, + common.HexToHash("0xeb6b0ea2f46ea41754fc1d05db36fe71eead48f2a09148604649541951857523"): true, + common.HexToHash("0x14124a7e79364df57829e00b8f7870b487302a30d2a982336f92eab359f7c5d0"): true, + common.HexToHash("0x10ba17398b449f7f2cc54d4201f5a2bb6734325a41a2cb7a3a38a61b4b98863a"): true, + common.HexToHash("0x3fffeb423871c94a159163d23e1ae8863928994951662efe62898cbd6e73a4d1"): true, + common.HexToHash("0x52a7b70a0dc72cfe89c90af3d1a2b9273c9e98fa0df3448542a9adf635392f73"): true, + common.HexToHash("0xebb9e3fe67ea8281ed28a59642d9399d329d6c40fb07ee3014fd1bfab4dd120e"): true, + common.HexToHash("0xb790549bf939087ce5cb82f0d7ee9deb970c033af1b58a572f3eb6dbefb278db"): true, + common.HexToHash("0x87fe5cda5af1d53ee72a9792ad1046c270948609df3c59b014ff335c0d4c6899"): true, + common.HexToHash("0xf59c19a7884f8a2dde690be9bc298d6bd94013f14e85705ac956af69822bb677"): true, + common.HexToHash("0x7ac429bd7cb745fb350177c974a83909794803aa754ff467ef300f1309775c1c"): true, + common.HexToHash("0x46fb8c7f8223800cf3281b69f84111d24093ac59ed531cf59c14b03f9fbe7337"): true, + common.HexToHash("0x6b6de4f2756afc28f17992bc179674ca90d5b380f476495376fb5f678a7fe96d"): true, + common.HexToHash("0x4445bba9cbe81f22df471640552fbdc84027544af82908bbce0a30bc2850295a"): true, + common.HexToHash("0xb2b457d6689c124b32e483192ecb002ff72572551743c029fe64461826dced1f"): true, + common.HexToHash("0x49ec0e85916eee7f907bd5524a82a1f851115466aa1bccbf138fb99f0d29d82d"): true, + common.HexToHash("0x4fe28e5c93efd22dd1d020cce92bcff36895d5732e8be04bd940812ff77cd8af"): true, + common.HexToHash("0x7e071ed2f4e04731dd11ed1486ace20918b3b3839eadbda0bffab76a0234768c"): true, + common.HexToHash("0x0af9fad4336460795a71f21f5588f50519cb04c825882c2b37845de0d24125b9"): true, + common.HexToHash("0xf8c68413a806bd17f9fbbe9def525c03bf2d0ca1ecd4cd64ca6787ee2e1b2fb9"): true, + common.HexToHash("0x4c25b2ded67d03a7c1b9b55b535a8cfaf670b83c1d835efa557d347a7f3ec6d6"): true, + common.HexToHash("0x5526dd2579d9f61a4a4be4613915a84cbf36ee2d004a59923746d9a9994d7623"): true, + common.HexToHash("0x7a04924323df974301fce64dd016d33149259b1226ed80e96399ccf834fb84ee"): true, + common.HexToHash("0xeb23ffe8b036fa63a645a972f2b6711b71db948136c998d2b638f73c59a8f9a5"): true, + common.HexToHash("0x306395e83d3da6be314dbcb902efc2d61a416601937982ab26ac084d8d9c662c"): true, + common.HexToHash("0x1194be4dcbcd71fbf65572ab58eb17161417034dfadb8fd333b9468926a10707"): true, + common.HexToHash("0x934ac2095f5457930d30dc4d594559b7b83f2cc74a9ffc2ce49c877ac15fdf33"): true, + common.HexToHash("0x43a7058a5ccd1388f5e8ff9c213bd0a3f250aa4a48ee7b496f7e789dd8c2ce00"): true, + common.HexToHash("0xed193a03d8557986e19fd15de46e8d65098689f58564c7141cfd0c50a251b510"): true, + common.HexToHash("0x9f3d881fe082228f217d85e6eeae658adf8f6e8d6567db3bc45cfe3ccbeb2de3"): true, + common.HexToHash("0xa83af841f0ad5782806e04aaf2563dd8a7a42473e5c00baadcfd6f7f6effb225"): true, + common.HexToHash("0x6f01f2c54c0c27a2fce9d77824ed5075d56cfd4b3d7b4ef1f0efa75fc3229ada"): true, + common.HexToHash("0xe8331f9bbcebb02e2ac6d21d10c1917a808ba66d06bf2130107c6f6ff82e7f85"): true, + common.HexToHash("0x073c290d9d4fcdc409af414985c8438f70a5b400a61b5667cc827f742dfe1fc7"): true, + common.HexToHash("0x58ad245b89ee1eb7c6184b39533e7cfb448355c35889f77341b99c242bf7b48d"): true, + common.HexToHash("0x8e45377eedbcf7a27c3d3837e32d35d16c5d026aafcb186d901773c0756750a5"): true, + common.HexToHash("0x6cc7e30986ca6ecefe680beda165ce8b00b858604feeb9763f422624f496e1cd"): true, + common.HexToHash("0xcc8aafb999fcfc6e66f20042b554ddf81be51fa0e19833b5d4b85cbb5d07ac9a"): true, + common.HexToHash("0x1bc375c927c1116df38276ed7b32df2f81e6023e5b00a1be7911632d8df1fd5d"): true, + common.HexToHash("0x5be040c9f716561f3e8b5b05ff06a52e2c768d7315b81634c2a68b3dd8bb1d4b"): true, + common.HexToHash("0x395d73cb7ba6c006d8ea7d4f302d33b48e62c1b89bad3949cb4d79ee85257dbd"): true, + common.HexToHash("0x7ec4747482b0cc9937eb75c7fc6dd0aa7d7cc0a61e934f18749f858e0a4bf6d7"): true, + common.HexToHash("0x2439957d1beb5e9b6278293c53046a328b0ec4de538dcb648c73cceb62fa4528"): true, + common.HexToHash("0xb932201ab148dbd14e9ef17ee8be2dc074057dc8193720449daed7aaf52510a0"): true, + common.HexToHash("0x79f4977f8289a084bbc001f1fc085cadff558d10b1ee928da66399bf59820778"): true, + common.HexToHash("0x99df13ab3c8d19c781c534d60dd69a85aad63f4f9359fcf134752cb86322e73b"): true, + common.HexToHash("0xc5882032220ed8c908f555fe99e80661cb934a7ef7f242118aacbd58f5461a4e"): true, + common.HexToHash("0xdc98faf4dadc02a575f7b8b6f3b8513817726ee1ded28e97d7fe6f143676e6ff"): true, + common.HexToHash("0x979194b07a39a145bee0ee5994f830cb988b3cb813917d264705a349434d00a9"): true, + common.HexToHash("0xd88a803b31da82252e4fd39c7a2961ae12166160a87da2aa1c735d60f982846c"): true, + common.HexToHash("0x82dec7a0f363e9b28e0eaf29562bb90b944fc572e7e8257731d52a7c518f6609"): true, + common.HexToHash("0xa374d138336db256866d124de4772e0195fe3d310f24f31457aa6a586fcf066e"): true, + common.HexToHash("0x79cc94d0a9fc9c3b2a5c9db0795f981ad0bf99ef43bcee2bc6f3f6c1b8ff69e5"): true, + common.HexToHash("0x499dabde7b0bad9e2040969c5dba2d488f6ba4b80e47800c490a30b7e2618178"): true, + common.HexToHash("0xb20237d2d46e1da37e345855625ebd21f99d3347a6af578f9340c4ff2f84045f"): true, + common.HexToHash("0xa77189172e9c8af65b74aa76952c83bea596504090477339c182d30640e7afd9"): true, + common.HexToHash("0x22f7966f454028e06af8fe5e8307d8f6baadc22275187521ed58d50720af25af"): true, + common.HexToHash("0xd2b41e6e616bc4efb5580d271219c3cff7bcb35bb5e77c85c9d1f6cf5d24cea7"): true, + common.HexToHash("0xd863513de9d6d9838fdc8dd540e495f2683ad6767f006a8106089cfc7c02059e"): true, + common.HexToHash("0x7876a0887f0c2071b6f48fbbf65515e8529557d8296fae09b7dceca09d1f3b25"): true, + common.HexToHash("0xa08efc8a4fb6ed99fe88fc4ae688c50667e5ee609dcdd62e48aa9d298e72f14f"): true, + common.HexToHash("0x4979c2672ecb880f61f62c465365dd9a95c4b33c5a65d83c9277f4d2e3711080"): true, + common.HexToHash("0xdd38507ea921a2d81577674cd6b8f30cfb04a8e6efe7df4783c22ff069c32701"): true, + common.HexToHash("0x380197596f265b6f114f6e4213bdf5bb29b64f373a35820f62b83fefdc2f48bb"): true, + common.HexToHash("0x2ee381a4614b8bd6bd555447375ff9043d231b460745667d40979d0cc80de036"): true, + common.HexToHash("0x44949e61a61ab3a3fb0fbea70a89bbc8ac26397358752d2f7ed8fe57be2411eb"): true, + common.HexToHash("0x1eda933f2b3042519e0c8aa58cf9bc2621342174e0c267d2728c83ef87f55dd9"): true, + common.HexToHash("0x4d4d11dd57986d953678e6275c04fa19c6305f355027f57e6441376061d76b57"): true, + common.HexToHash("0x2621c209d0672f63c34a7465973a7bc3ccdf5de33937d4e35502334dff263bb1"): true, + common.HexToHash("0x8350c49b720452dc4baf946d1b83a75aec3989c771fe71aaccdeac9ce7e41904"): true, + common.HexToHash("0x0270ca54001742698574727279f2ac544cd9cf87b977b459d7ba078261097f1d"): true, + common.HexToHash("0xde2d38ba9c77bb844fe1b6880643f7cb181ae7262bd0265c158d109d6069c9e5"): true, + common.HexToHash("0x66be9bf60f7cded87263ab26bd45549f2484446f18f69b42262bc7bd749726c0"): true, + common.HexToHash("0xe3582d2d7eef28b69d07d07bc8cb42d98adcca58c2a375a06cf510a3c94f2469"): true, + common.HexToHash("0x488259545b94b9382e2c4e834d02984443f7806e754cfff007a5a59cd6f35ad4"): true, + common.HexToHash("0x8798d5b41d3888ae5ee8e1ce72afe2e95d5ecfcfaa5767a941e18222c4cbe54a"): true, + common.HexToHash("0x8cc53dbb6bbb00dd4c0dad2854e8962b7b8286a40621be241faefd6481e62838"): true, + common.HexToHash("0x484ed41fcfd85084562fc666358aad4c6464b1c316f4af03b8a1467894043a84"): true, + common.HexToHash("0x05b4adefac187856204f9d34b2c4f633471b58b6e33a4beda6028cf8e7344d1c"): true, + common.HexToHash("0x6dd3c42de76709bf5e5b61b1e372f0a69a60c15fbf74fd614548d652d2504af5"): true, + common.HexToHash("0xfb25b436156266fbb72d66154dc69bfdcbb3e6097e7eff60cbaa66ed0a2b41b6"): true, + common.HexToHash("0x22f68a8bf1ec9b2c5ea2f9ae94a9de559655c462d9c846cfbb391779416a687a"): true, + common.HexToHash("0x553e8206cd4db003baf4237ef180d16e047cf6a77aeb8f3aa94644805fd34071"): true, + common.HexToHash("0x6bd6570c17e762006640c950885771b9de009dd093f2562c1cd51cccb5c49144"): true, + common.HexToHash("0xf7eeac9d0b642eb38e0f7d83f09183c8520db48e2f270c3e7e241d3300f84223"): true, + common.HexToHash("0x402dfad2a75066180ae0e2d93865dba6cfb18a23f4e20ef0c706169834e5b2e9"): true, + common.HexToHash("0xaa84ea0d482d4572dadb81fecfb261b1db61ca74ee32c420fdc690a9ff432419"): true, + common.HexToHash("0x7776627594ad6c52c836c2261d5c85bbb8d7cd664c1c7a37f7927e42e4b13699"): true, + common.HexToHash("0x2466efc00b88e484abb7ddd3a9cf3d4e215a88be978806de13d1c0396100c97f"): true, + common.HexToHash("0x530184ef89f6e95b631e633d821605e99a5fe9426e2706c6124d3af5de9a1271"): true, + common.HexToHash("0x015966b2cde3f30458e45c71bc8ac00fa50f24534f2ca0d859ec9c5c05583c3d"): true, + common.HexToHash("0xae2b821d169b63722bbb1dfdc9569fd415b83d6e7e1259882cb582b62ebeb08d"): true, + common.HexToHash("0x113967102c293ff478a28e66e35341d9374f842786ef640409a9b9a43e1da685"): true, + common.HexToHash("0x1aad19e9993b8ff9482d7b26acd11bd203bd67cffbb91212b2ec794c64c20fd0"): true, + common.HexToHash("0xd75d7284c32cff6af4ecbf127db143a1704f21d52f2bc51154377427adabd21c"): true, + common.HexToHash("0xe7d698bdc4094848de2bf530af63648f39326da7bc00047651248e94b105d136"): true, + common.HexToHash("0x396b231b517dde196060f7139efeac7908046c0587ff9b559175205de7d11252"): true, + common.HexToHash("0x5cca6d77c0625b7a5dcd12d17782237bc4662db74d90a21e139d055b52fd7d08"): true, + common.HexToHash("0x35c22c893788f76f3d3acf2e9fa3d8aa6fd3a3aee8c7fa68fc85b4876b6e0f8d"): true, + common.HexToHash("0xc5f1d174f3d0e7e439a6c803dc36a828c81ff9059d11d99fc2da4105f24a76bc"): true, + common.HexToHash("0x7748d9ecb5cb2a9692b26e16d0bc2c3eb1fd95fa8f21f50bb9aca9a475338b97"): true, + common.HexToHash("0xfbc2a4b7b44f64d854fa56df41be1ec1d5d7abd8042187e41ac89c94a5a326bc"): true, + common.HexToHash("0x7ae0cc9a13aa882a2300f0310c52c827bd694c0801ed18b587e68f76f129095e"): true, + common.HexToHash("0x19eae511503684ff048281058dd9c0e32f7c9761f318b11279370839f7558694"): true, + common.HexToHash("0x22834c983ba8dce2fb0c51288de2ae1859fba6d699710d746510553b90de2867"): true, + common.HexToHash("0x860d6192f665b072d6b7d0e8c6d18d430e7f3f44490dc8b0e6abcb530a7eb2a0"): true, + common.HexToHash("0x54b22f6646a3385e0112ba4d0c6617eaaab753bd29c6eb4d2623f07ad4d486d3"): true, + common.HexToHash("0x4411139d069bf441c7a4565916d6eb341cd0d7d655659ddcff5c6a9c9f24561b"): true, + common.HexToHash("0xff310c33347d6f3625ad61cd31c9a8e3dee5ceba28bfb638c49a500f11d87f0d"): true, + common.HexToHash("0x345a9b4de09b964af151cdef9ee1623fc391a0b455f9937fd619adf342b7d84e"): true, + common.HexToHash("0x7e26c3c7fdae650a87b816f3a7c1fea8313bc043be49f457318e64a70893f801"): true, + common.HexToHash("0xd59494ba9b61bf183e920fa59e7a8ee6a52c6fa443740f35801580e7f958c200"): true, + common.HexToHash("0x2fba70e8c504b2c0f5555beb79725c3b39f44f30cb42c63ccf489cdefcb9fd4c"): true, + common.HexToHash("0x97c632a1ab274340b18f41d382f0891ada606ea75fe98c645a46147eef4d5ce4"): true, + common.HexToHash("0xfc7d5f03a3dd32ef4d8997b1f8b48693637e7077ccc1f74e195698c9215230a9"): true, + common.HexToHash("0xe83a2bc1534934eca140cd271e614876d533a7ff624c8047cff7a2bd8de7c60b"): true, + common.HexToHash("0x953269a3e350822e62972b7a9ae7f3102d5586a47085f1e85239d99227ab8b94"): true, + common.HexToHash("0x5e799060e916306e5ad1111a15c1610eb49b84d9f26272b6eba5ada1c61e49eb"): true, + common.HexToHash("0x96b03f916e8d9e2d1764c2bcf8520ce668c3a7b53acd59a217a79b50df6158ee"): true, + common.HexToHash("0xb8b5b6fa97e5ab8aff5b9c4d4131eea49698c04f224cce7e7ae08e3dbcb89bf7"): true, + common.HexToHash("0x7c7f0e8683d33feea1c716f534a757527fb96e1c1d0d28d86d93e287d67eee9c"): true, + common.HexToHash("0xa8ee918baa54817b4a238209dfa5dd655b51cc6a2683ab3442c7e66f0bd9592f"): true, + common.HexToHash("0xb157ac60fb696f326c17aa2ca3d791897c2b2a4b27c64c793e92249b5d7b6a7b"): true, + common.HexToHash("0x17f9d2c4b9f88905eb7f52194d19dad8c8210aa47a3b943699c5abf0e499a57d"): true, + common.HexToHash("0x4c7d8e556bdcc360594f5697d3b5f936bb13954dac86e0a90e5796d024ac8b41"): true, + common.HexToHash("0x172558ffd4c9a390dea49a2d97e167fc58a70618c5774aa0949ac6c2a08412a9"): true, + common.HexToHash("0x4e00122a1e5c288178bb50e823042f0bbf2c87aa8cead583772def784fec4cae"): true, + common.HexToHash("0x89941b01cea97fb3dd0483e14a109c94729bd73f830a44b8807018dc93033c49"): true, + common.HexToHash("0xa30c88742159215f39fb9a3db3c9ecd721d0fdd8fd273294652334c014447e58"): true, + common.HexToHash("0xe40633b2568c19dd9c95d12885257a6e9486101a2fe54bb963ab2c4e16ad5da3"): true, + common.HexToHash("0xe82b99518f4d10ef5328b6baefc442dbc273337cc5329357fbd6516ad99208de"): true, + common.HexToHash("0x02122c289ffc6afa9e6468f984e1c14342b8cfe8a05b1c02a6ece01693f6df26"): true, + common.HexToHash("0xe5c03467c06ecc94ba32f8096ad6a351ad49481193f9153eb039fe1ad988c7ac"): true, + common.HexToHash("0x66b05f627b257c11a9347ca552b22b0cff78f9ab6de34ea09274c01467b4d5b3"): true, + common.HexToHash("0x7cb9daf904f65624552e2ff2b7227763e2f62574a84596ed00155e08fee0a357"): true, + common.HexToHash("0x94ed6e86c9984d0524e87a36addb666f009c37014c8557fe78ea05d4b2e032ad"): true, + common.HexToHash("0x8dcac351a8309f457a83b3e4c359d1f3ddaf2fe8a5d0f98db26b5bf5eb9866c2"): true, + common.HexToHash("0xa0b1e39718b37c36692dfc932a3d235783cd1a8c94f713273f7224d4df2aa826"): true, + common.HexToHash("0x7d1c84367630dbfb40876b139ae15bf295e66fff596f6b1022dabdbc8976287d"): true, + common.HexToHash("0xf2dd5bafa16b0be4b3a9c0c6d217132cdba5fd7bbce8cc37561cf6d512e3618d"): true, + common.HexToHash("0x4ee0e15e4ae7f65ac17f436d90c798d629e93e389089e0dfa64d464f020a893c"): true, + common.HexToHash("0x7f909ee9013ace141c2541662441d5d29ec6bb0505624b5a2ee1e6beac8a8543"): true, + common.HexToHash("0xabece3e0f91035c4946ff2cb56e2986e80518f0e829a6692f9c74802f282ffa8"): true, + common.HexToHash("0x9aba72d435cd5fbcdc4b03c9cb28b616345a1f763179d6d58a1c7c4351d6ec9c"): true, + common.HexToHash("0x0bc17f1ca1ea5abaa9ccb2b6441def9652e92ca6d62846073c1293a96a94a73b"): true, + common.HexToHash("0x66a8c08dd424ed5d30f72d5761c866addf352f7f424295695ece5beb5799ab16"): true, + common.HexToHash("0x2fb9ea8b6c89939f57ca70061504f7279c1012f36aad6df90b9eb3b1c58f5752"): true, + common.HexToHash("0xc1e31d1aac7e88c1566c4ac07e7c0005ab3d93870d12d93b9d1e42a900faeff2"): true, + common.HexToHash("0x2fa6f200cee9e2d0401c2c7cd2fe8e583ae1af18f6deb947d16d72685bfc76f8"): true, + common.HexToHash("0x83151d071e0157fd9d5329ae96031236a369dd9006578ae45f96aaca55c0f816"): true, + common.HexToHash("0x52f096d1d6307ed7741e7c276f2cc0ad62480026c1331fe4eea43709eefcb640"): true, + common.HexToHash("0xdd3b2d19d06bc34c0ab7610ace6c31b808e86e4881cf086c0c24df239a62d27d"): true, + common.HexToHash("0x00742455e794fce7b6f0b0357a10b0dc5fba3f0b0182a9478f8f703d6d8c482f"): true, + common.HexToHash("0x97477d413a40c27f9aadc771d517535fe9a3695174d0106e1e9a361ef2c4229a"): true, + common.HexToHash("0xf33a382a845a8d43be81b7434d5af248f4deb76c37441651e5cc99b1fdfe62b1"): true, + common.HexToHash("0xa7c86b9176a79919d8158d32370a2a21b1dcdd558a2f5d9810c0f2158d8df664"): true, + common.HexToHash("0x3580570ee8c57c17f63f3b246c4606f5d90e9f3ad0725318cb6f379ef11fdb14"): true, + common.HexToHash("0xde65f11f6bf4542b9293b08a9cc6a1b490b4cc58d630ca06f477a54067ef6b33"): true, + common.HexToHash("0x97a3e8d1e302dc021ac44584ae40b34540db52fb10e9a78c8302d767d2e06a18"): true, + common.HexToHash("0xa9fb1f48fe2f1c0e9a7322818d7f2c2ddcebc3d6b08c82b570b0495811825ab8"): true, + common.HexToHash("0x7581d118f434cb40ca66708c141ff4e07b30c1ce25ce6f0f63d2226964a85bd9"): true, + common.HexToHash("0x413e76f8713025a2e252c4f5253d6e552aece8fe677c89f265704ac40d95ec7c"): true, + common.HexToHash("0x84a8f5d8351613a1e28a7f5ced814bce08fa4719453b97e80b00964ed9a1e7b8"): true, + common.HexToHash("0x28053543d1b49d991f90fde4625f563bec59a90bccd24a6271109a34bf3ddef2"): true, + common.HexToHash("0xf889fb3588783fa07871afe57602a566694ef43edcfd2359c98d76e490d5fb82"): true, + common.HexToHash("0x63b8b62a9a1f4bb4c53dac54cf061c76a20a8170f41908c93789c81ea045740f"): true, + common.HexToHash("0xd0892fb6f8632fccc8deeb454c1ea05a4371f1196b385e5e94cc683b6ca82abc"): true, + common.HexToHash("0xfbff680c9efcfbbb8b1089a28e20c7c79412a8bb68a9257c76b6d91df6c8856e"): true, + common.HexToHash("0xca1dd02ed8a4217607c19b8c84de8d7d2655b87a0fc6e43053e45d412ddf0f64"): true, + common.HexToHash("0x0141908c09aca98d65b53c70b27f900416492927288d7bda94232f538c037cc0"): true, + common.HexToHash("0xfcc04366c543f3e8582deea09eb126bd6ba79df678831fd586bf9e4bc7fa4e90"): true, + common.HexToHash("0x162827dc7225995a9713fa4f1b23b35739227631dbd6fbb336e09106077a79e3"): true, + common.HexToHash("0xac8c651d957529f72ca5551861411d43051f9072f56a007fda614bd7fcc1dae1"): true, + common.HexToHash("0x2b492b718cc4e0cfb7420f9631ffdcb332e9f2c49c00efaf2137543eb691401a"): true, + common.HexToHash("0x9764972d2577770d201db489bf24adb6e408648976a49f66fe89258fe01b4e51"): true, + common.HexToHash("0x10c81d46d32feb60c2e3818a403ca638cd491fbd33f389581a04cec4108aeae0"): true, + common.HexToHash("0xecf25dbee8cb8ac3e935e6567337cc7380954dd5bb38c1b8e6b14678cc061781"): true, + common.HexToHash("0x3bc5463e82254c32c02e2d56e2ebc208109c7aaa2b6e949b385ff965d1bc9e68"): true, + common.HexToHash("0x8b065d5b7604878f7e43681260b49cdb7b1200faa16550c7963f3ce8e30a8a4d"): true, + common.HexToHash("0x78e93deda6c2a1cb1ac793bfd2af22e8c08b03c5866b90c2fe3c3ef62f4f834d"): true, + common.HexToHash("0xea7f953f229655ffd7fb62419536761650033965d3579ef73280adbbc1094af3"): true, + common.HexToHash("0xcac1bd8cbe4a662b365d047142fb0106bb9c99b9e740f7eed8982b1c6af61ac5"): true, + common.HexToHash("0x835bb7903d3924e00bb82b52dd164d2d22e03afaa3809c55bc352df745044691"): true, + common.HexToHash("0xc0ede4f803fff513d0c51381d5494913592e5688ad553df15a49795d6c5acc41"): true, + common.HexToHash("0x2927a3f6c9d81d8565c4764778395b30f8e05a7148fd086d09f0627a7727f0b4"): true, + common.HexToHash("0x33bc43b87b5e7c88832fc89a362ede1e3672ffd6d775c205ef5eb16e8ebce86a"): true, + common.HexToHash("0xb20658f66fe7d2f86c93c68bd16919301ebaa3837744ef0b4e9b9393417877a8"): true, + common.HexToHash("0x1e1330cbc87cb17e45b03df13e70241b143fea27d0f7cddf7f32dc41e05b65c1"): true, + common.HexToHash("0x1ccc0dd5f703bd01e17fab2fa7846a228f1e1af72cb95298aa8338ebd94bfe53"): true, + common.HexToHash("0x42d32da6bb34a311538c2d896e78bf0502892c5e948618656f37621fa4093bb6"): true, + common.HexToHash("0xa73602fb1322e4e831940696517940ef925a71defeb07ea24051cda9bc10e58b"): true, + common.HexToHash("0x048ebf50f4c5d69b76e76677a6b666ac4dd83739e0f8abe6ab9daf7bb0e519de"): true, + common.HexToHash("0x6497a252a4f309fb4211412cfefde9a849beb5984f532ba7310e825fd882bed9"): true, + common.HexToHash("0x30ce4d04fe0995851172b541fca340e5dde663a7e167f4b7463fd25e91b2ed53"): true, + common.HexToHash("0x384c32f10b202a8da6dffd8428246102f5ac45bc03eebf2ea9440966cd9daff6"): true, + common.HexToHash("0x567ae49a01aa6cb8f862af7e499ea4467e0806d3da24b2c67df58e1525e12372"): true, + common.HexToHash("0x5a4f9a406996cc36e68530137e400b89a870e7556c5d64af8d5916522f55823e"): true, + common.HexToHash("0xdef3f54147bcb18f8f0a9286754b29396b8eac54d94055088238ec1dc8050994"): true, + common.HexToHash("0x935df7753c02e43891c049896ab842262e8b9d1f18e309d9343fedceb641cdd6"): true, + common.HexToHash("0xd2b3eae478111dab4d5ca62b6265e895797c573a7c7c55f47e17a70882822efc"): true, + common.HexToHash("0xdfb40a7a40e78b89ae00232b31d7fc6cea32f35ca7b48f1d744e6b551fef9a88"): true, + common.HexToHash("0x8fd513da273144c3b09d31f36c2350b16633404e2f48433cdc80e12476e7746c"): true, + common.HexToHash("0x38dc0a12be6235a604cab0caaa9773133302fb5b9d399a13b18c50cce7b92d57"): true, + common.HexToHash("0x21dccdfe2881d6425106dedcbee99f5018d32d1cba344147e41a2d9c33677060"): true, + common.HexToHash("0x887f2478e78ec9fc8f3a97173153fada87bf1d4a8fe7395ccce7ddaddaf43a69"): true, + common.HexToHash("0x5091b34f42bf17aeda7d4a1893d9ab15bb06880a783d0e5d44e8bd77733bd4f7"): true, + common.HexToHash("0x172e3d5170f5d63a497a4d69c3310589432ddd832fb19d65654803ee4e900412"): true, + common.HexToHash("0x4ab677b29c0239f8197487ff64157e4911517613f10dce3b946a72fe8e3e7361"): true, + common.HexToHash("0xd4831ef3baff2eac83c52d769c8632263b678e60c84ad8a9e0e119e70b1a278d"): true, + common.HexToHash("0x3e7f5caa58554450559d32eacea8fb6212eac35240f440518d283cb7439d1732"): true, + common.HexToHash("0x4211713d7f233fea3f75990d4f6412610658779df59d0704d080a58447fe7de3"): true, + common.HexToHash("0xec85a57e6df0cad358e4685ed63a0c3c6de1c9d70ac6328b7167e05fb084a216"): true, + common.HexToHash("0x23787500cdb303ec77ff9a98120bd28d2d6dacb5444ae42b98e3ebc78033dd12"): true, + common.HexToHash("0x2ddf398edc963ab80d681317141b9fb9b96b48af178e72f83d6d2aa04b174986"): true, + common.HexToHash("0x85d533db41371bb1418ed71458b69029aa4e1b760133e1deeac472fc6cca0fed"): true, + common.HexToHash("0xee87c0ac4578bb67e9cea9dc74c1190cda74b1362fd19c79a2552bcb1cb81f0b"): true, + common.HexToHash("0x772d3c6b6f1d00d1a373edd3cc6c45d0783a4b41439c606279912eae42df05b1"): true, + common.HexToHash("0x8fbd910e841b3008a9acf1f16fe39572ac223b62f9b56a0b8113b57cf90d00e4"): true, + common.HexToHash("0xa2c3aa766866dfa4b748e3c154904023d2ad61fab128226707dd197445b9ff86"): true, + common.HexToHash("0xca057732d064899a2869b370248aeea6ef26ed5d2fb71338d85f875b3445535b"): true, + common.HexToHash("0xbfe5519ed57702c86962511e12e3ae5bfcd253101b4d538373c75100c897d429"): true, + common.HexToHash("0xeaa79aa5e5329d2b16177bfc8fcb1c932b15441e766c33db33277ecc6f016236"): true, + common.HexToHash("0x1b11d8a51f21adfbbdc79cb4cf3fbb718e92de4cab4b8bfe8819b0b2f86d3468"): true, + common.HexToHash("0x76de1f4e736c35fd70add1b3c6d069b81a7d31a847f767cfd39f58bc9f91bce7"): true, + common.HexToHash("0x20c7583851f3c130f2204bbf6238c6ed54e9648058b28971487e527c23f85a2b"): true, + common.HexToHash("0xd9207c691e998de901521f9e14d5f3257b1e728debb722c2e5ea0098de6f2e75"): true, + common.HexToHash("0xdcd4d8b4bd8687c5b9dfbf0c1beaed82dd551994680460c8ef08a35809b8d239"): true, + common.HexToHash("0xc7d4e50d21b8600bbcc6f58fdbea69db02b0d4133f3dc4e916c4023682a62d74"): true, + common.HexToHash("0xfb4748476f38ab66809d8ea170715fe4e747d42dc6ade7a804020904294acea9"): true, + common.HexToHash("0xb8c3f5457a547ab92ef23ac35052eca631a3f98d501b951ad1862749fb2568b7"): true, + common.HexToHash("0x83cb8f1287a7da98fabd646454673d6186deab8459a5cafb85787752881a475a"): true, + common.HexToHash("0x165a8210164d90c1a94cf8e55bde0ecb0c0528a5781ad3caf985f1f0a95d607d"): true, + common.HexToHash("0x2fa0520a724f8003be52152df100d942fcb280ba1a135eac3d6b57cfdf8c58e8"): true, + common.HexToHash("0xa55417daf7df63b87003d1edef747d5699700c3a246fc959196b906d4245f870"): true, + common.HexToHash("0x552fe3c20da36298c7554bab1a967340e358fb844a84f880d6b3db1b508af7a7"): true, + common.HexToHash("0x2a828ef0746cd7209bf2b71a396c83fb60bfc53bba2f1bf2abd9cf5ea8ba31ee"): true, + common.HexToHash("0x019f1438ec22b9cddd98ea379f1c03758fd84a1c300477f32337278cfe68d3a3"): true, + common.HexToHash("0xcb48439665591031a4e1bff571fb15775fa5072ab4dbf2351437beb5c387975b"): true, + common.HexToHash("0x4feaf1d16fa340b89dee620db76fc4c4e8ba17ed735625b96bcf02a607e153c4"): true, + common.HexToHash("0x52fb69fb0126c30a16dddb6d4acef1bc84ea5e75cf0ce42a5f6ddf3f5dafb987"): true, + common.HexToHash("0x3cbe67828ed46f5ca7576f3e59c4a8004f47227c98fbbb293f85f0565504eadc"): true, + common.HexToHash("0x33a0d8d4fec3c456525d401325febcb02f7d1ea669330800b0f56f4287cf9b24"): true, + common.HexToHash("0x95b34497be1a96b3a5be5f37f2ebf3353a98475af48a914cb0ccc10aedcfd94c"): true, + common.HexToHash("0x45b84a6c8806fe6aa76d292aaf64327add2619ec98bcf896996a797efdcb22ec"): true, + common.HexToHash("0x4dc6757ab3a8eacad6a4b0286a3c68f3d5d13c05f485f6b751339a5fdcee66ef"): true, + common.HexToHash("0x781a34e88dfeb1c4db683763dc5d979707bff5eeba0baf77d3ffca178a2f4403"): true, + common.HexToHash("0xb05b972a07344d994b39c04d99a521f94c39098be03e7be02829bc68a4c0fbfa"): true, + common.HexToHash("0x98b5cf0dde756da3bcfc8de10117e96d9f7048aa27f4e46472385b3c8d355c3e"): true, + common.HexToHash("0x6ec1ecec8d1e6ea8cdb2ae1e388f2a24db61e35ae29136b21a923bdc59bf9c5c"): true, + common.HexToHash("0x019f969356405a37efe764574073e137fe685ea269fdc1982dd925e25b7d2fd8"): true, + common.HexToHash("0x0eed219e98ad9221bbfee8fc87108afa2a266a1c75f65cfb34133e7f846f6b1a"): true, + common.HexToHash("0x42fd1addbf3d1c70d6777148e02a40378b63ac52d2a582d2df123b80b5324f04"): true, + common.HexToHash("0x3ce147d4a2f33d58dbf82eab930b256d6db8d61f93aba525d6be4d6e73e621ce"): true, + common.HexToHash("0x8197bd15fb196eb2455f16468e4a9a3270cf0569452d3bf066246c8ddfe9ebc6"): true, + common.HexToHash("0x616a891ccea35e0cc9792dce09f354da117b5063d320dc563930070220fdb55e"): true, + common.HexToHash("0x45eb69ff95c400d9883cbc32643d71aa4f23c201854e508e982019823ac37ce6"): true, + common.HexToHash("0xb594429ae2090c1a00a1d3672aa12c7310f4af5be90e9f55917205c13d421566"): true, + common.HexToHash("0x9c6b5ecf761e10e93fc4794619696aa8d9d51f79b5f6d0550aa8ec5e8655b9e5"): true, + common.HexToHash("0xdc9b61360c39988fd99bc9f165a5251b06f2c2cd7add866c5a7530d3799077d9"): true, + common.HexToHash("0x6307dc2971a9514cd2e3330ee300d3fc4b4ea0f3e4a7c3862ce740652ac4a558"): true, + common.HexToHash("0x737ac23da92d3eef0096589b266463e4a0140c99eb4ea7099d6092235bc7f012"): true, + common.HexToHash("0xed3f3f6bcb9b4ceded7c7e86f041d72bd30fcdb31d7f1b9041b1a89d366642e6"): true, + common.HexToHash("0x16d498c0253890f713288bddf7d874986ca5b6e4bc739939796fc5f80a6fb397"): true, + common.HexToHash("0x6560f8f79a73aa2b2a6f21b0b92208f99d81f19a2e2b3527de8b16feb4847268"): true, + common.HexToHash("0x514323baa1bac53a0f6cd012ee8a224daf1c6b7d47ed874ba6143ffbf7102f73"): true, + common.HexToHash("0xdf9cf814a3ed1dfb9fa905eaaface7a42fa15d5c26639394155bc9973f8e1309"): true, + common.HexToHash("0xd5b539e6b6f33ab845371410efcdccc374f1e20acafdbfee175638cf1ed7f4f9"): true, + common.HexToHash("0x6a5c1e69a344c07e834fb30fffdc385f693faf1acaaf1460d6ea822d0a89e6f4"): true, + common.HexToHash("0xf87137ae599074001abde034ffe13e2ba2bcb8ae5794a2f4ff16ab85a3b4d918"): true, + common.HexToHash("0x5f68453e26aefd0480acb7bf050877c28255a473cb187fcf75173c9d6b84db83"): true, + common.HexToHash("0x25996af27bfa134cf8929a72a8ec5e70d8e96e2c069716b97f64b49d6fbdf836"): true, + common.HexToHash("0x26891739342fd7d894c7e3698975a40ee532f4b13a56c01bdfaaf172ff47843e"): true, + common.HexToHash("0x9334739ed9fb3ca424d5a0ba5304248143d89403332c66e1fb043aa006cc17bb"): true, + common.HexToHash("0xf14fbd85e5f5481b03af805dafdafb973dfd26d68d6b306d6d43a8dcf41f230d"): true, + common.HexToHash("0xb50f002094b6af7559076f4b3fed58592c96da1e7ba16a69b81401a6af8254d7"): true, + common.HexToHash("0x43d1170565620cf8b94a3627823e6d3027100f7406f2ec111b18abf959bc3b01"): true, + common.HexToHash("0x104e78dfd9e2117325f7c1dbdf7a0029077b9ac6ca88ea4584c21da34a55402d"): true, + common.HexToHash("0xf5738a6aaa83afec3b2f06c653a9071e2af516fd1fbdbc060c38f3557d8f4333"): true, + common.HexToHash("0xe657d73f7453eb9abda324113daa30381f1b550b9387d708a032708618b20f1d"): true, + common.HexToHash("0x2c2f730da29f66187777b233d514bbb54b567eea2e7ced9a2cb49907cf6a25d9"): true, + common.HexToHash("0x2cf03f4c9300251a4fd62368d55e6144756abe4641cf65434b8304d268e0354c"): true, + common.HexToHash("0x1cbcc20af5e8e47cb8e15b9e7c31ee67847b39c0d885560a5c02f23fe82709b1"): true, + common.HexToHash("0xc1d85d56d29a70d7fcf6e4ee7ca677d9f676576bde2a998523b742cb9c9125d9"): true, + common.HexToHash("0xf2ed100144c3c4878fe3d5dcdb8c31d8f973af7681c1078ae8b009968b01f87e"): true, + common.HexToHash("0xc8b7c24ef4b25560e1d68a1e16d4e709455bcc67f6022e2a6254b6feaff0a7bb"): true, + common.HexToHash("0xff38678c761f2e54c536e2e18f88af29dcbcafb58bb7e853091cbbc07da2de62"): true, + common.HexToHash("0x1ad296ac8d8ef66588788a80a2f67da4fdcbda29f254748f4d54acd51f165e34"): true, + common.HexToHash("0x16a6db6395f4042dab6507c2d7e22eb7cc2ea0039f85bad1ca8415a20740084e"): true, + common.HexToHash("0xbed7f673490b4d6850ce64afae30388cbe1eae285a19f3997316828e6f2e2f90"): true, + common.HexToHash("0x7d9dc582e7c3ece9e32a179338073bb12b9e885496ca4661d2ad41af8474c8b8"): true, + common.HexToHash("0xe8dfbafa76f7d490bd1f52854e627cb65e0860c4431a22b93b8b1d6bb1efdb60"): true, + common.HexToHash("0xe710ac832ac530ddfa3214eb4ddd97d02bd8aa4bf756fb03d548c10773a93baf"): true, + common.HexToHash("0xc41538da5c78c67d64fea643db6c9351e70051fe278f04720ae2f60512af7f56"): true, + common.HexToHash("0x83b897bfe7ec10f45277e14b8e0c108c067f80127b7005b4d73e93f9be8462ca"): true, + common.HexToHash("0xa0b2f8ba38428b0e03049a7597c61a540057b6ef2fdcf0a8f280eace5a82e43a"): true, + common.HexToHash("0x77f50e001737b9a173526ccdfad6d9130ac89e2f8ea04c416c747c71e892653f"): true, + common.HexToHash("0x6a2725366a76563771027e0198b6f42531d25fa818d2368057a14a6289a67ba5"): true, + common.HexToHash("0x02fa63db341d5f5bb051d1b89b2aaee97fe200fc71725f6c80632dc41d77ce5f"): true, + common.HexToHash("0x4157317cc7fc873cd6c7056222524991aef9389b431c2820ecd67fea1989d08f"): true, + common.HexToHash("0x479068ca7862faecdf85a21a29320b888950418c06494b328197a0b10b0783ad"): true, + common.HexToHash("0x160b8b8d968098ef5dc41269bd0abebe64f12a738257be5fb032af9557628c28"): true, + common.HexToHash("0xbd34ab6c86492ced0e832ccd283488d5db2ccc0a29b4108c54ed1466eb7832e8"): true, + common.HexToHash("0x42b7bcaff345f87993d238085ac23b04d382b8452b38c46f4a0fa6fd4f3a87b6"): true, + common.HexToHash("0xbf49031db50ddb942ee7e1405922f6a8d3f4945d891865283e49480b9dc95a7a"): true, + common.HexToHash("0x90693283e47564d4cc74f5a7956874273fd1566510eb6fd4d28f6b26ec18d976"): true, + common.HexToHash("0xcf4eaaf19e016f5098d4684a1bb8ccee7ba11b71d77df0fe315c87ea9825c04a"): true, + common.HexToHash("0x56178663575d66388c8b21ccc80daf1a020c001cea8e3bed2da6fdffebe4b802"): true, + common.HexToHash("0x98c3ead9d23c22b1c9aef2290fd0b89d65f87cff318f558ce612428c44592971"): true, + common.HexToHash("0xa3611cb9f00fd474232b44ce5096e30d805daef512b8b6ed7005849c283aebb3"): true, + common.HexToHash("0xa1e08a7035719fa04407d6a3beb27f9a1852c5aad4662bd757e4eb5c57540e05"): true, + common.HexToHash("0x1a6b825111bdba03d99b312525177fead6e0b70a6c5652bb053007df972dd73c"): true, + common.HexToHash("0xe38dfacca850be2937b268f236eadaef59d2ab8774f347739506622f10ee7b05"): true, + common.HexToHash("0x6963e5b536399a46c3283ab674c595b741a3aa10769733c7647a56c155a371ad"): true, + common.HexToHash("0x28af56a8ca92646c87e793258a3393116f654aa3e03508f5ab901c22882851e2"): true, + common.HexToHash("0x6f60444c19ce97030494c9d4fe983486f170db436e640b42e0a92dd321e589da"): true, + common.HexToHash("0xcb224d3825a86a2d257a0d1464e285d158e0f3adff2e2d07339aa7f954d1f0c8"): true, + common.HexToHash("0x4644018c4df9b6507dcad47f1301e8e65a879616db95c1909991038bddc5bc39"): true, + common.HexToHash("0x533ddd3e3e1e2c9a50c4594d20e364ce874312a4d4ccc34c3b1eac50b1e890f7"): true, + common.HexToHash("0x7219e883f91605af2d661b513c993025b9de44cc97515e71e22e75684170d634"): true, + common.HexToHash("0x43cf170a06d7d8063a69e001976be57bbdbd58b9d604083a77448f01a2ee4a58"): true, + common.HexToHash("0x9a68521cf44bcb61879b4239bba301e00adc00cd3c846c696aa9804e2e227a8d"): true, + common.HexToHash("0xbd3b77223191a2f1b6acb6f92aecdae336ec3f689805259d4f3120115972e8e4"): true, + common.HexToHash("0x57efbf7925454885ed2907d0d9dc6a022732c3756212366442ad5d2193653810"): true, + common.HexToHash("0x89cb7afa9aafef0c3659f24d0eb5d2e7042248acf9d45633789977a78d0da0c7"): true, + common.HexToHash("0xbf3dda581c117ceb9474a3cda106a3e7460e976a8a94e83153b5f31b0ed34577"): true, + common.HexToHash("0xdb2ad1de397895c1a1bb6f4d738d95dcc194f2a5443aa8a8bcf73825d0317ad0"): true, + common.HexToHash("0x41c0e204ebb37ad75c4ac8f54220521e23588e93d3fbb19108cbcaca749dd19e"): true, + common.HexToHash("0xfe387a112a57b72d423cb295983b7f8a4e2b5fa6349dbc5f1fe7c54cf2eb8295"): true, + common.HexToHash("0x3eb1ea5be0bca4a17c4ab58d5eb7e1efb85d9c1adef710ef71a23cd63fef588f"): true, + common.HexToHash("0x0a4017b02df20d1ce4b9e37e664b7d586270990630430fe9d75c7b925aee61e4"): true, + common.HexToHash("0x2e010c92cc9b9011f508a9eafce7c2c6d34a0ccacd54bd498a7a0610deecd5a1"): true, + common.HexToHash("0x4e2464cd7b53e39d298e8456f635ad2e6d66e58f10fe7a049506dd23909f2f69"): true, + common.HexToHash("0xdada6e038baa2faf8787b83b62ebe4c05ef1a93fa54b4913d13d75b30ceac021"): true, + common.HexToHash("0x98377e5e067651ce26e5de2532e4bea7f527fbb6b1a641f71ccb29010dad383c"): true, + common.HexToHash("0x16fda65f98859f18ac81dca5c0f8d791dff79ddb65f3304bc5e391cc12cb8f3e"): true, + common.HexToHash("0x56d0cc51edd37ff5f1ca8f66925c8b17d4af31e0e39a2d727a62f420dc676c87"): true, + common.HexToHash("0xe26868d1f0935af5b8b3da8f053c75f20d2d5c4385e0dd84bc16bc8936548e3c"): true, + common.HexToHash("0x3a126acdf8f7afb16ad4febe2201be8d6dd1db3996ec2cdf59e1b9b38d654c45"): true, + common.HexToHash("0xc3f3f8853510f6470ddbd9ce2671585e12d3e1fe68024847391393ef62fe9d45"): true, + common.HexToHash("0x04f88d37cc9f7583bb1b9940c0479953d3441c2719f256ddd3798ba12c19163f"): true, + common.HexToHash("0x9ad7dfb099fecdb4580fd6d702acacda0dde082c5ee25ca9ea1b59964dee2fbc"): true, + common.HexToHash("0x0cfe1432f88e986907a3c4060b48eeafc7694caa13ff29a8087a9981b413f4f9"): true, + common.HexToHash("0xed1d546a0d480a2609e452f275f334a86d93ca15a0d595815bd76e3bb2b0af9e"): true, + common.HexToHash("0xf38e467c64df532f1ed93678c01ba996063e659c5d0d5b5c1b66de06ac2f4fe7"): true, + common.HexToHash("0x7020b3fd7bcc56b1ddd15af28bd7ef7f95432f8b3413bb69367ff03c8949d2a1"): true, + common.HexToHash("0x4bd812b41b95000d9925c4e20ee2eaaecd61721ddb75de84af3d60f1790b5dd3"): true, + common.HexToHash("0xebd62b2d6e746311ccbced3bb7051167ef7626a7cc284ec3750d0f1f549bfbb1"): true, + common.HexToHash("0x2073b7a3d6588ee22d82992b1e13a6553895f643d502d3e06e5a7f5f1cd413d1"): true, + common.HexToHash("0x4f6e6877dd4d473d7e2cbd34296aad99e4185dd6b89b6972b602658302b32a18"): true, + common.HexToHash("0xc6b1e3ca1114902b88686b860b94c1664db43bbe53da97c375935bc12f7d7566"): true, + common.HexToHash("0x13eb8f73c8414df274c90f67cc4ca5b97fa90dd52f32d7727eee7dacbe2c1f8b"): true, + common.HexToHash("0x222b0fef91052920a319344c126e5e9b1ef6babf5556d9e0b1209adce784c358"): true, + common.HexToHash("0x7f63bec9becd134e011a02fe320b4fe00507a34615f2ea1a833a519d2d21db69"): true, + common.HexToHash("0x3cd5f50ecd653d679813cf8dd8b7f30b49f12df4b8c21881b920f6860c3d6bed"): true, + common.HexToHash("0x3943f4576e1e90e79189069f9447b08680cfd0d3b4c2c3213f546866b21b1c70"): true, + common.HexToHash("0xf74cd349f5ea9b73838b7f8b408adf671523c174d8b563f38dde371be09c6ad1"): true, + common.HexToHash("0x9770bf96b2b6aac186f06ea4f76ef9f74403f06b21876a6073538f58571980da"): true, + common.HexToHash("0x657438e320dba9ad2e38879c1fb2480bae9b05b3adbbb711e54648f16cb17fcc"): true, + common.HexToHash("0x6d6f0354eca5a32ea4955e4fe48d4746aaaa44319263766323dcc1a5cae3fd56"): true, + common.HexToHash("0x36bb34125460058b4d7130125d8258edb62a5dc68290060d392dd44312b1b5b0"): true, + common.HexToHash("0x7f0eb7071af68cd2dbb780deae1964d7226e524f1e01ac22c864847339e03f9d"): true, + common.HexToHash("0x44db26b01303bc224351cd6204bdacc66b68b4ab8df64f5af7d9877c8f5ebf48"): true, + common.HexToHash("0xd286249fe89671a8bd9edf9b8cc1757cb2eff62b77b89b5e09df5434db69b965"): true, + common.HexToHash("0x505e9003143395a60b3106bcd612a27fc4f5d5155f9b55628ea572543094cf7d"): true, + common.HexToHash("0xe4257e88d3b468efd290b7b634a685575ef170dcb4d19bb9897184add6fe0303"): true, + common.HexToHash("0x3c19c59d2bdf06f6eb134d395041913b38dce58cdd26334c9cc484a2b2218fc1"): true, + common.HexToHash("0x6f21753f95cec8c981472d2b148f73293e758bc57d1c9119e8ca1d42419ea36f"): true, + common.HexToHash("0xa44a6d600284c8313a470e7d2c766f3aacbe6a07d8cab084083e28401d168196"): true, + common.HexToHash("0xe0ea506809586757b1558ef45d8b6df5edd56f27650e18709cf041bb6e190376"): true, + common.HexToHash("0xede5daf53aeacc9a17a9f24dee24c1998f43563c0ee523567bf45df63684a665"): true, + common.HexToHash("0xae02aa5cf11105855b7e3f6126ffe58961adc6ea535a208b074d8c4cca32a9cf"): true, + common.HexToHash("0xf12f41fd72dae3381409bb6f43b3cd47649a24a32966a0c4743511c4ac9c940e"): true, + common.HexToHash("0xcb5a56e95e95112c621077971ba21c09507bbaa8c34a5077722c583b747383b2"): true, + common.HexToHash("0x93b7a384c5f61efc9756f48eed188e1053a7d8f5e9a90acbdb3e821bd1f83cdc"): true, + common.HexToHash("0xfe0bb83f7c0f1e12b87ee787c0263d025a26a0d2657b594c49dd0afc6bfc1ee4"): true, + common.HexToHash("0xf91d1bfaff1e8ebd6340e17c726742c52f005f80777582b15b8e19e136b58103"): true, + common.HexToHash("0x57a4da122f2697652292fd2fd6247cd0e080590e8fa5d740f81d0b5a4f87bb47"): true, + common.HexToHash("0x0e43a901869fd76fe9a41fbdee7add69005ae89a782820a5edd6f868ecf4a27f"): true, + common.HexToHash("0xc33b3ac97c36ca154bea0761664bc1c6ff145097e5f49d445e701d212a3b0462"): true, + common.HexToHash("0x6d3c81ae9df096221b856579275c71b045263f0f81123cf1791fa76c0e236030"): true, + common.HexToHash("0xb52a5d0be8bf726dcfa474ffca9ae1c5da9f68074ae353bab5be15633f776279"): true, + common.HexToHash("0x7ceb48c320112ee615ffbe60a05401cf351b7a622b2a5b2a01cfa16b658d9e40"): true, + common.HexToHash("0x1f80c9e6caf850ca08a612ee14e4e7db3fe60a733e430f343571fe77310e6371"): true, + common.HexToHash("0xc66dfb925730aedcbc462c9df67b34abfcc2da293ffa6ef08d0e1607313fbb18"): true, + common.HexToHash("0x0e2aa7ea8e9a2e48579c21af383a2879599bb013ca09020bccf4267f00e8eedd"): true, + common.HexToHash("0x50de7bb5ca1d0b15cd687c444f0cba50a1e90aa5770288e3e41857da91111937"): true, + common.HexToHash("0x077743eac705809f595040cd62e9aa4249e1c0b438e65392d16786b6f1dcf383"): true, + common.HexToHash("0x540e7ca1b9d9c10872e20a69943943e5bd08b6cafa56ff595e0906a0e3a8a871"): true, + common.HexToHash("0x61e78a2664997be6da8995abdf984ddd4a7d7a28c751824301ea3b35e1e9d826"): true, + common.HexToHash("0x803105b517a364d4689bf4629fb0c51a58cd63c927e10a539bbbf27336f4f606"): true, + common.HexToHash("0xa174d75b45a7c7a136db3e42d42ac77f07a0ef81eb76678732e7ba6d35c9c596"): true, + common.HexToHash("0x434851dad862801da932d6297bbbf8216e536479555719803d548dfe2ae8becc"): true, + common.HexToHash("0x5e10160e98c755583727de9fda42ab7c9add66e24d2167bdf90cbf03ecdac9c7"): true, + common.HexToHash("0xab9e24c7815404523a7eb16bca76dfd5efdb4a3d8fd2110e82421ce6cf6ae2d8"): true, + common.HexToHash("0x2ab2c1733b2054dd89258a5924ef7a94936adf6a9c5b367666e7b6eb87a0ea3e"): true, + common.HexToHash("0x2625b636b133dddb85f932e7536b062543359717550160c7ec8579f5d3ad38e2"): true, + common.HexToHash("0xaacdf6d60d7d25669f8fca6986eeb39befe96eeda628a63ed7a8a858f4f2e00c"): true, + common.HexToHash("0xe7b34e2ff3d5148a274d2271d2b4d5c48de0174e26314c57fff9eca97b78f5aa"): true, + common.HexToHash("0xff0decf268fdd5b35dcfcb45f7af40a895d0b7416965adedf6de51222ef027e5"): true, + common.HexToHash("0x21296efb7e5bf7550cd75391947f131079b4ba8fc5a02e6a613c13f2b1b4ed78"): true, + common.HexToHash("0x4149fc0e8a6c8f8d03447545f0423d5d005b9384dacb1723aba93893f37a9273"): true, + common.HexToHash("0xec07a9624d1de578ba53f731e8891d1b125fa10b67ebd5b9b314577c6aa0d2ee"): true, + common.HexToHash("0xab0af09f8c7181728097a8b8f8aecefe5b04a65ae2ac05049d8d8d37088fd513"): true, + common.HexToHash("0x33d4e9c67fe43d5e3c98f005440a34c2107e536d006a82a3f3aa69faa60243ce"): true, + common.HexToHash("0x10ca839114ddddd16035f22c71b420634a54d09b372cbb495b835e0bdd571b92"): true, + common.HexToHash("0x9ecb6b5b9c47eb76e6e049b986d23ef7f48b6a4149926848f497a903b30077c7"): true, + common.HexToHash("0xf661b3b285afa0f540113efc7394821d52618565253524b3b90d64968bc8e47a"): true, + common.HexToHash("0x76254b0e22f92f70bd62825cc3d748257bad206d440f1fef5b6c3c361215bfcd"): true, + common.HexToHash("0x1495edf6746cf521f73762d131cfd814f1a718937dd84467293caba9d22120c5"): true, + common.HexToHash("0x64ebe584e91fd7839127afeca9820a53bb7f3956b322ddd67ee0b093a8c25673"): true, + common.HexToHash("0x2a65dc25faa4ee668f10e3fdf896b4da6c61aebd713a9e66b022b88829fa603d"): true, + common.HexToHash("0x6d0684c8bd2d3e59cfadbf6901bf138d5c9e43b99a070bce4554416e8c49cdb6"): true, + common.HexToHash("0x681225c7a0b25a169bbcca3e6f17f4ca7a752a68c7512757bf0cbffc2ccd7513"): true, + common.HexToHash("0x32fda2ffcf9c5aa68de2fa065a7066dfe30c3773a01da2e508b383819520e18f"): true, + common.HexToHash("0x2b196bd9b2b10f3fe43541cc5e341389f28919fadee0c6af6353ae2e17865bcc"): true, + common.HexToHash("0x243bf5304c7c92ea86b0eb1cda3ba5f26e758cc11f045c4bd7e2554507c6723d"): true, + common.HexToHash("0x6a5e7c00d9a97841352b0b86a1ce1dc93e6e7847ba69057b37d940ce5f4dceb6"): true, + common.HexToHash("0xb9fe1634ec8fb70b8b87d00fb1df63ad7a029ce3843121b3d03f902ccd0c755e"): true, + common.HexToHash("0x18699cca9fe93d7199ce2dec625bb7862a7cf49b1a8ee485753cbb0c0fa70fa7"): true, + common.HexToHash("0xd6a81479987917136f5920f9cd4b206ae7f5259ed9fb92ab1859a0da44978955"): true, + common.HexToHash("0xc889e710d33386fb54e5405dd48c9cc9566c5b07d4d9f22989086049645e89a0"): true, + common.HexToHash("0x2749cac0fec504d0e1df4e0a81cc0588d69bbeffc5b9b6a0bd514df3e5434e10"): true, + common.HexToHash("0x6bfe9ed2858749cb82f632982aead659d3fcd92278fd90780f6890f3db02f694"): true, + common.HexToHash("0x356bba35ea02b90aeabdf9f6e2b666cadf03e65c600484f9dd51ca98ac2a5dca"): true, + common.HexToHash("0x0b7e4f00f50526b44732044fd1d775c7f4b35955aef3a0ca4d88f35f52c058b4"): true, + common.HexToHash("0x8f957074511a20e90e6316699e35cf94d17110375dd038d47ae701750194fa8c"): true, + common.HexToHash("0x3ac13e4fb9927aa3c8b8a7f220407d610af00f989e68972567d171ee73633257"): true, + common.HexToHash("0x9f10826c7530525b70cb0f2006f708e9273db0ad9e4ec382ec68229f8494c98b"): true, + common.HexToHash("0xe5bf072288f466ba08eeb3a81b0862efbf1548109db20d54d0fc9a9a9e8397c4"): true, + common.HexToHash("0x1444300f3df49252155a5f0ceb2d5338dc0a8ace3160fca4b83b4f9aaa5d2467"): true, + common.HexToHash("0xf8dbb7761c705d9d4d543a2cb314fa25c1d55f33a951975156094e8e623a0a30"): true, + common.HexToHash("0xb6d94d2139504c77a81987c70879c4c0f230e444ee9b45c3d54ebb885f0baf50"): true, + common.HexToHash("0xb4d6c0be04f560d60cfd7e2d34636a7e4028343980fb40504b81e0650297d1ea"): true, + common.HexToHash("0x7e3817341fba172916c25d5a2e4568a7552cd34b85f9e34031e9373ea5763497"): true, + common.HexToHash("0x08dc5f4fd3eb445849ad6b3f4bd04372fe2a2a1d01a2f211a43b5e9f62bed9b5"): true, + common.HexToHash("0x276fa74cb03cafd0e3224abb2b5056369a10ef75b719a5c4f88fcdab2efea283"): true, + common.HexToHash("0x82d660958fce08ae28b8e63119e9bddb1f7b55d41d9c19ce719e2fd96483d442"): true, + common.HexToHash("0x55cf780da098f730260a5509b50473eb54da55ee4fb38a9bf644edecf25e76f1"): true, + common.HexToHash("0x62cb93706e0fb1501ee7bfdf4ffbb19b2e229f37afa23b85cee8a4fe5b9e59e9"): true, + common.HexToHash("0xc462996582b9ebca662da4c91f77f78cf725aacdb6dc6a0f5a8767f6fb475b33"): true, + common.HexToHash("0xc66946c9a3b65835be67a83369c464d88ffaaa0234cd43e3ef455b4bb7a0c305"): true, + common.HexToHash("0x164b5499ea8b936ae2eb16d93844bc17deff5566d064ddc624f68d161e34b972"): true, + common.HexToHash("0xede7ae1463117e450fd01c5fe695ee11ed37c21ab7df70474ad156f5d1cd130e"): true, + common.HexToHash("0xf3b7835b4ff10b5092947cee6c5af71f46b6df90c05901226d6bc140379f0e9f"): true, + common.HexToHash("0xccd41d46c507ac0d2583f651a48b2113d2116f71861afc03e2615732ae6cc74c"): true, + common.HexToHash("0x6a93c6a937fa8d0d4148fc0b06cf9f6c7bd0edae9d631363b88f7814ce9257cc"): true, + common.HexToHash("0xbfccc99ebd546b0b1aad51807f80a8c3908d861b3d9dd6b51e1387b5812e90b3"): true, + common.HexToHash("0x3ad36be4fb2319960a8e3be3ef43096f27edafe8b03494e8ae46510ffec8d84f"): true, + common.HexToHash("0x05e2b432d9160e71269863194b743aa94b1401b2cc5aa211268fe3517d111c75"): true, + common.HexToHash("0xef0aad43155194d9c10ad3ecb6a18faa731a8711d6450c9b01740fec32cb9e30"): true, + common.HexToHash("0x9647f207feab09858a264c4dee1a3cf151c9289d0ef7ae5963badac93a3faad5"): true, + common.HexToHash("0x6b09a5205a2aa95b95f9da0e58ec5d2a3c7704757edf4ea0692c330011bbc292"): true, + common.HexToHash("0xdb44a66e2aa2118925db5d34d625b0506c7974d094b9c6b2489f50c449eb22f0"): true, + common.HexToHash("0x1c5b46d77b2b2f06676a83cb31b8264c06c05f5a13e789d177dc98b6968634e1"): true, + common.HexToHash("0x5a00c01e6b95926f68dfb3daa4ff3cbb4ecad43440f7d60eb7bbaa9761e576f0"): true, + common.HexToHash("0x5f6ddbfaeb2f67163364c242d76f5c3c5b4aad98f811c8c853871b678c12abca"): true, + common.HexToHash("0x5009fa52f2586a6e030573f8b1b3bd9e64178438cabe9b5c7ab838496ed92859"): true, + common.HexToHash("0x682d901ebd0f967f83d39e8c7f34e197d900ab644f650aa9e55382f00a8b3964"): true, + common.HexToHash("0xd7d9cc1b8c1f4ed2c2024ae5918cf91e5c28120f29af1d51530bb5c39be07e83"): true, + common.HexToHash("0xb5d0b01b36be10167bb64441aeca792c6f46230e2f0b8437efcb56ab2461b46b"): true, + common.HexToHash("0x5bb873af95639846c1787278b66b9a5db19bf416bd52393e496ed9ea99a79501"): true, + common.HexToHash("0x4034de8dcad53ae0cfbaebde8c3fb845d207044148386e1d4adefa98b01efe1f"): true, + common.HexToHash("0x1e33c3d72aa874e7302526a2843ce43af0cf90d74f79b830d21063219d0883eb"): true, + common.HexToHash("0x522e3e6f26d96ef6364b16c1537b173f310ebd8ca4d6af61aaa46450e1b63230"): true, + common.HexToHash("0xd811eda05df28d9331ea2aa346a23a7feba07c64d3937b59cd3b2d41e793b5a0"): true, + common.HexToHash("0xbb01df465980ba3a4c0d2003a5a54a601c83491e9a0482b51e789c95ff2e20e9"): true, + common.HexToHash("0x9dbc226d884f14541188aa1ce7dc191ed2670b0b761b0d23453286e5ae78eca8"): true, + common.HexToHash("0xccaa3dd31494c5232c0e75abe13c8f496f3091a3caa8ba20f5be2889a1c10446"): true, + common.HexToHash("0x83d94b69a6e0c5977eee2e4ed78edce6d95db60eec5d7b017ebc30aff487ce6a"): true, + common.HexToHash("0xa27a92299da4980dacab1c5c107b16bd887dc0cc90287d31b8fa0192e193a84b"): true, + common.HexToHash("0x2086117e47131ac464339ec3b2da737d8405a977a722cddf53030410bc4f0d54"): true, + common.HexToHash("0x9c5b9b1fd7349f0819a3ca392f3de694a01f6a334495faba48368c1fd76e8e13"): true, + common.HexToHash("0x0dc8271e6ad57bf66d76de3086a61e72436cb65f9e143f6fa20b9157293fee22"): true, + common.HexToHash("0x9080e30cf52920a4686ed636adbe93db18b9ec4b12919309b41f91baf3d7cc87"): true, + common.HexToHash("0x39a0e8a224820aa40bb6c2c19c064e6d8fd04d9120a003e71164e3052523ec3a"): true, + common.HexToHash("0xab30fc63b026578d153dcef885f52da4a315305e4a6fecee7994e9d5abb27cac"): true, + common.HexToHash("0x6857a13d184c378056902e57ba99bd2a73de10fc3eec54429a3506ae4d10683b"): true, + common.HexToHash("0x14a6830bb9187a6cc2808afaa040781d18d76f83b030f844b7cf75a7e572868c"): true, + common.HexToHash("0x1952bc30f3084d19c37240e85761fd7b6e91c1225e16c21b65e67af2f942bc1d"): true, + common.HexToHash("0xa69adf754191edac000b6fc8bdf19f7091a2c9aa1ba56bafc296e3bc4b49079a"): true, + common.HexToHash("0x2951c7261f4c11fc70fe1af3f6d3d5504156365c356aeba5c8de419affaad46e"): true, + common.HexToHash("0xae5feab9fcb9b72b694553ce668c971138589e9435d58cebaac85a2cd25a0b85"): true, + common.HexToHash("0x6127425842272b48a67a8be78c2fda4e74fd71123d36ea68dfd14ca46c9c6561"): true, + common.HexToHash("0xa6d494b8b2519a9b4e79299e84f59109e10043ca187d62d5dc8db0f85e278c2f"): true, + common.HexToHash("0x37f8b1e5d731253ec4c403777d2195efbdfe6cdc1847ca2cf29a013b46b16907"): true, + common.HexToHash("0x3382930ab330692c1c9d6e8ac06c3deb46ed766cf520af2d579b609309c719d0"): true, + common.HexToHash("0x65de58f3a0d4265a3077b7a471fc866e4851d497903f009e070d826bf6a7996d"): true, + common.HexToHash("0x07d53054b9e9f587157a8dcafc4db866c6d9b61b18ba786c14376f892b5f5eb5"): true, + common.HexToHash("0xdd07ef40542d321b87ff59e62cbbd2607bdda53a7d7f477c3e226c42b9c6bcdb"): true, + common.HexToHash("0xcc2285f464e4e9a116c9af370286d55ba9a89699ca33637a442287512fdcfd66"): true, + common.HexToHash("0x9e8bb157664b9a6152a74b632296651bdf03d50048a97656c2b1f514dc54229f"): true, + common.HexToHash("0x8d215bfa85f6aaf56412421c39b87cc45819b7ac19bbccb15ba07aa7a0b79805"): true, + common.HexToHash("0x06b07d10a64094d3c81344d11bc9a2aff25a65d865c150022d632d0dea54ff5b"): true, + common.HexToHash("0x29fd9aeb7251b27f21eb40f84271a4cbb8579ba79434d19e3c41d37ca9f8d0fb"): true, + common.HexToHash("0x641a5de3fec03ae57f6013de9f874a7ca95457f057d95121eff82abda5916af7"): true, + common.HexToHash("0x5ca4a219577aad1d3e5c0f523ce4c459f66ac71568158bec8fa3c9bcf0d73e3e"): true, + common.HexToHash("0x6fb7f1bc99e40ee5df6c066635f5fbadc8c8942b7c9e8759d1cf1fedd99c0beb"): true, + common.HexToHash("0x25a95992b2a1162785292c3b2348e4fc040b5d7ae2c5b047af9a744a245f8607"): true, + common.HexToHash("0x8ea66b6aed3940ebef0b563adee4918e32850bfde879efbbdba50fc93d41f9c2"): true, + common.HexToHash("0x35f5ae62e3b5a2a0c89a221e3115bf916071b66b56624fa7d2a27f1740f703f9"): true, + common.HexToHash("0x2b63639d12999b0012ddb24aa8ed3f00884a2c9012f1f31fe00d44237e229a82"): true, + common.HexToHash("0xa552767fde50e15a240e0236cf887de7387f88e7712ea60efa2dad877517474c"): true, + common.HexToHash("0xc95eb005865f5f945084058c5546c0edf43e702b1103e45849686ac6a2d3398e"): true, + common.HexToHash("0xbf7eed0ee3f3eb57592ded3a43e244409def23c2b32bf71ce065c5d99c0506c3"): true, + common.HexToHash("0xe774c25d1c035cb208ec1ec7830b7347c4771d9236dd8cc57f7b5948e0f0d7ae"): true, + common.HexToHash("0x0f0689536f27ddab1aaff99dba0d898a4bedc8f51bb2d2958248ccc93b61f0df"): true, + common.HexToHash("0x89be1a669ba1a14d3c55eb0cc78f24a9af51ff5e689771696a314f997fcf620c"): true, + common.HexToHash("0x7ea9d805f2a8d7fac9eb944aa2e2239b4ead138c7d95812000f75f6357a82745"): true, + common.HexToHash("0x03d3302e1a4ea691942f1898b12624242159985082354f8e0c98e96d7dfe5ce6"): true, + common.HexToHash("0x5cf80ca90c62b08a90d972693633133110999706a9e4c7a94084ded33fbc6f22"): true, + common.HexToHash("0xa5ccbc97d7364965d2df89a66d6fbc8e1f960803c9473ef8c16d8a0e9e4a390f"): true, + common.HexToHash("0x1ae14a098195f1fc83016a6a60c418709e2a85a0b23a47a502bf77542ab808bf"): true, + common.HexToHash("0xd3b4ec989d68102f37f4c371688c70618f38abbe6e5685b9ecb8f63523f4bd9e"): true, + common.HexToHash("0xc8022129381f8c27e6da1bd0cda2f059dde503b90e18dbde5dbbe0053d99d801"): true, + common.HexToHash("0x566cd51da9fcf71c7bf035ed8b64aed58354a081aa3e8ce544e29e7dc97496c7"): true, + common.HexToHash("0x54c242b87a1fcb5579b0587932759c9037e3b765a6b914373fae6a7c1a7c37cc"): true, + common.HexToHash("0x5153fab51026be1cb7ef55bc7cbe8b9a937456d2b9885fb57e0e725626a6fa52"): true, + common.HexToHash("0x4e5a95eee082291ee824a6067893bc2bd7b90adbb758eb31674c1602c259d568"): true, + common.HexToHash("0xa1cab11fd38488b94b567abc5255b52c447317badd4bb9f752c726a7a65b73e9"): true, + common.HexToHash("0x71ec0844ac48c26d8f6255b0900bae97f3f2c810c70b4eec8ba46db39513a9c2"): true, + common.HexToHash("0x420ed4d807f395652e30473c965089817a84876a54d9eed2c85190862f1f60f0"): true, + common.HexToHash("0x8c099d9fecf63b980f252da271988ed8ac6a75efc244e694543e98173f08e6ce"): true, + common.HexToHash("0x7c6820afb1bf35d4c67572c1b83c9f14a205eedbabd483623a36fd86cd0d6100"): true, + common.HexToHash("0x04a7f14f8fecd66ee97f1b8a1311bc1c79a8a635a5b3d8a02a057d0fbea8728a"): true, + common.HexToHash("0xf820ea58d8cf5ecefe4dc371d6a559278f782d9b235f2e235954bb806272d9a0"): true, + common.HexToHash("0xd452f178c9c96923b0a5cdfc92108a0f14b7a3b079554ef8632177ff49115279"): true, + common.HexToHash("0x6e9a82b0901ce7566ec394579681166b1eee5d0f12fd85067106d3db288f303f"): true, + common.HexToHash("0x5eb4b56a7542d1e672b755be4099dc84eaf5bc8756c12057b08efd7706a5d7b3"): true, + common.HexToHash("0xd67a118955a1739285ba5c223ca295c5e13683a9b5551d5ee2a8637b2ee7a320"): true, + common.HexToHash("0x8d42643a107be64f7dddc3a893c643356926a1fa524ff7f1890412390ba5473f"): true, + common.HexToHash("0x6ba33dd115d1bb32283a505cb371e55a6bdde67d50eb19dfad7d3323b5750d84"): true, + common.HexToHash("0x2b89b2e3f9e71822f0de0e7b89e25fb838d352154a45e173cfd3b637664f3be1"): true, + common.HexToHash("0x59443b10af668949c0f156f081034b15cc3a0b83bb740f2830f1e8ca9df44a77"): true, + common.HexToHash("0x9a57e6a6fceab6e9eac85302536d1fd1cd79a0a2aae0e54337358090c1d08a20"): true, + common.HexToHash("0x9d9ee9aa0e8d2a9227cb531e564c626d2ad71315a2bd2d2ee420568490487bc3"): true, + common.HexToHash("0xd9995cffc9d1951a184e847322e47d11aebc141764232f6193d1d01702f3bf3b"): true, + common.HexToHash("0xcb409c327dc2b70ee7622e10c83177fd2fff2db8b8e6225d6b54f09cbb61264c"): true, + common.HexToHash("0xa247ffc39ec2e220a9d4a5a9074a91399ecc495e0f03e9f33e670e7623f153bf"): true, + common.HexToHash("0xc6dd3a017daa99e73126e75724c9bfdd1eda74a339115d20e0a9da94e9b6cd77"): true, + common.HexToHash("0xcb63c599adcfdc4554df78e497630906a41c50fd4d7cf3c444097ad51528db19"): true, + common.HexToHash("0x630b8191fec921d1a987b90c6739bab8359f8b1a337a30eb449dd696cfcd9c4e"): true, + common.HexToHash("0xd9fca3053d7e34a36b0da1c43bed371b0c6c33794d41f9414001a3cbe9165f63"): true, + common.HexToHash("0x19d0c5d1cc4fc18393db901873db99224789f13c5c6be4bcb1e3fe60102a6ef6"): true, + common.HexToHash("0xaaf9ae5a19b4752aecea568ae15e52e8672fd3232df469b0efe6ae3517dc1a9c"): true, + common.HexToHash("0x964ff1df43da6aa79e2a6499ee25d225e865f2123deb506eea43d57e373ec516"): true, + common.HexToHash("0x499600f6206d5e95f4518a59afe979d02f51fa0654f15648416d918066e6ea9e"): true, + common.HexToHash("0x3ef2659b39c593405c9d3f5046b218a05041b47fc3b6ca2090d0b57c178eb525"): true, + common.HexToHash("0xb038ce5e94c3f34542fb22d453b0243f15676f083e4b76d8ab7899c7cf9d3357"): true, + common.HexToHash("0xda13d26ad42d78330a43a9db5726e4720f61f6779948a186303630d73d543d7f"): true, + common.HexToHash("0x4b38d655ab423fe573b8337c53f875a438c1f14b236c3c33be1b2d88e1da024d"): true, + common.HexToHash("0x5b1ab9dfe2d25adda06d96e2ad6f9bee13a615a2b7007224cb6539ce889fc29e"): true, + common.HexToHash("0x007d3d07bfe5be13c863863400ab48f4eb318cbdc4242b718e9fc6962f729ad9"): true, + common.HexToHash("0x3f4254c4d14e41ba6921c020d48e50b40f1348767940851dfb5bdf40cb83b4a1"): true, + common.HexToHash("0xd02acf02d5e1c66d77022b10c9d594c12501ec213b1f58a03ceb14e1fe16d750"): true, + common.HexToHash("0x1ab63acc37ecd316a63435a4aaa7856b80c5b2769e09b6a8816b9d32aafd5f35"): true, + common.HexToHash("0xe4c2fdaf14dc0d1d433d93bb22698258c87d0c08d5861e79d438ddb59490af2d"): true, + common.HexToHash("0x06ce26923f69d8a6ee7a61683cc65ac14dc191f7dd90eb025739d0d9f4840c82"): true, + common.HexToHash("0x480d45d9d0cb6faff60d9cabd2e5ec71f81336321fd12513faa3347e5a72ae55"): true, + common.HexToHash("0xad4aa79f1b6e8349548bf6bbc93504ad2cb07cd885f95cf2a2fa5f423f9a30b5"): true, + common.HexToHash("0x5731f237f67ba994e10a4063fd5af92f0b1ed6cde096d2ffc3965f253a52ea13"): true, + common.HexToHash("0x55078a838ad72e44bf3d9af9ee6a85c5086322ec66042b443acec4e13ef94885"): true, + common.HexToHash("0x0a8cc29f9ac624e1e5196f66e47db3878d2e5dc96b06973d77ea11c55af0a830"): true, + common.HexToHash("0xd3cebb129a67e4d88c892b06bbb1b8150ae9e6333018242e17c52c6a6654596e"): true, + common.HexToHash("0x1d4232a2e3db0c3148bb8a64c2cfebe5c5c380ce9f83a80401a46afaae7c26bf"): true, + common.HexToHash("0x127f8fe1e8d9cb277bbe6026387d6246443811bf9342cbf2bbe07780b21a7442"): true, + common.HexToHash("0x093ea8fac664830c981604c38815456a053a5f38fbaa1eed399564e0b08ca91b"): true, + common.HexToHash("0xf51248daae118fe87ad035fce9ea75ad19559b4d83ff97940db1d88d5411b3fc"): true, + common.HexToHash("0xc014df97da60497073fb0835133af2413795d055423321072ae6ac190cc0a15e"): true, + common.HexToHash("0xf400f540ba901a71e427da324907b076167df7b8000afd5dd7ba94d948ac1947"): true, + common.HexToHash("0x9e3d9eb8b9b81faa7e638c791370af6b18e8fdfdb8e8ea57624f0c2297b7172d"): true, + common.HexToHash("0xc9d7bcd8094496aff4b1591ca2b0140f92e98ee48fd6b5d5fd0bf81865eb38a6"): true, + common.HexToHash("0xfd452ac3f82d595351a99e36ee5056b0e44b51c8819e0fc8d5dce7288c36b35c"): true, + common.HexToHash("0xd90851f0242ada81dc03f55421d828ba47fd0969e10b962857e19f0c8a9f4c37"): true, + common.HexToHash("0x0ad729832f336dde6d94e920850bf9342162d60e618cff800dc8ce2b81a42c0a"): true, + common.HexToHash("0xf4c5123585de956ef151775531d0b019f5deafc3c16f09db297e4c35ded17db0"): true, + common.HexToHash("0xfc736e84f02dfae27ee6b101cbb65cd2161e77d7fd33ca71f11f97a40aeb6863"): true, + common.HexToHash("0x13d05500d47b71d8f75de3e9542f9b3e5dcc50ea31c6c687d553611efcb8048a"): true, + common.HexToHash("0xd8c0df694cb077ee526e112411d39391cabf92917805e365d1c109d5627752b2"): true, + common.HexToHash("0x98dd149a3b1bb40b1b45c32b6cbdc078541bb92c2557c3485098c35668ac66c3"): true, + common.HexToHash("0x283ab9dff58e8b2b446bcb99ea6c2ea2de822cd2e1dee9d5b40ec9533a22981a"): true, + common.HexToHash("0x04fe8bed3f2b499188d89789b35627cc1a6c51f3692c94c604a19d6694f009c9"): true, + common.HexToHash("0x00971d452dbb8d14c4e931cbdfe9023778456ca936ddc948e62c17a434d58612"): true, + common.HexToHash("0xc890304b70fdfc8bad1581933952b56a98de0bd913447d2c84424d8546e63036"): true, + common.HexToHash("0xcc5d3d5b0798b62ba3f70d223baecf357ce4d0b848f8b95ccd24513abc705ba0"): true, + common.HexToHash("0xf8ad2fb11859a442933976b68c3f5969a3a0300dd63f0be17dad2f48044a95c8"): true, + common.HexToHash("0x6c679f2734e74bc6ca5d2f1916a7300b367e46b7bba5729400eace0dafbeb358"): true, + common.HexToHash("0xfbb3a7b282be832d401aa354a8e1a0be1764a234fa731d77eb1cdd6a24a36ee5"): true, + common.HexToHash("0x7c9bad7a860e783c4af9ade9ee9358aad62f7dfafa5a5cd64018a132821c6e6a"): true, + common.HexToHash("0xed53905e5b27402666a9346be4fb5998ee4a8005e64edba987a6934f1939041b"): true, + common.HexToHash("0x985706d1a2be4ec97b953024a1d2d2d62747d3421795a9f69fd7f356ebbf318b"): true, + common.HexToHash("0xf2d313bf1369e8b36e733fbc0d83f097fad19b1ea70ec672c2adc0a6382e005a"): true, + common.HexToHash("0x1b6b59ca80bd3ea2d7024dbfa1e90e0890090a32e55cbb23fca252c113f8055f"): true, + common.HexToHash("0x8e2d939195118bc5f91dd1492b3a02aacc0d5590dddd29a1b7359e358a87546e"): true, + common.HexToHash("0x85c714644ffe7d908081b09c514e60fb8492e866c2cc7438a95e9feb3738bbd5"): true, + common.HexToHash("0xa1fedd246fd07f827ab3f500e33e72086257a59e34ba4bb8b38800923c182cd8"): true, + common.HexToHash("0x17399da0505b6f5589fea888e8b0df6a69004a9e62c10faa110d01335a5e067a"): true, + common.HexToHash("0xeafcc783002ca4ecbeb3bbd57d9933038fd262fdbb0aa3f45c344bae6155919b"): true, + common.HexToHash("0xf3c3d8562cb790676cbc19e929713b44099d35acdb034aee7f16edbc2d96feaf"): true, + common.HexToHash("0x7a2821f2faec9b4c110f591e7d9e6c1910f5445e22a3c1300d5f48531ecaf97d"): true, + common.HexToHash("0xa08c27a81b33b2bba69930ab1af32de1909e66f1b632616821d0861cb2056a56"): true, + common.HexToHash("0x5f9c5c94a486e2e35e20ede3e3f80ddeb905fadf98f5e5cc937097d7db7c7c4d"): true, + common.HexToHash("0xb4b172bb9b45373edbd6ac63209d2ac0f44e517814955e65f2d48bbce6392081"): true, + common.HexToHash("0x9702e9161e586940ad83306d3c81614088c83dc84aa2514a2433dca37d309c2e"): true, + common.HexToHash("0xc9b4576f1abdf46293382838f6cb5f95fc8b7c2aa7f4bd17b5ba619a5783f776"): true, + common.HexToHash("0x2cc73585108283d07707948d5947679a7d4119679b994b69f2a01aa67893302f"): true, + common.HexToHash("0xc504edda2bd71df7d603443c69bba00722fb90ea868815102c151ceb295c3640"): true, + common.HexToHash("0x8bbd448ddb2a4640119aacf1035bec4f7f4007e3d5a130cafef3c307252988c7"): true, + common.HexToHash("0x275046f1270461177fd2d9735ff4faafca1b568c84ab86535eca099ae976931b"): true, + common.HexToHash("0x4d0ade7b4e2afc7edec1fead492b951b136efe51a81a54a63a1bd5958000fa90"): true, + common.HexToHash("0xa9b0b73562bcc8f7f947e1aac5083157d9a7dd7fc425ec8fbc2f0d9dfbf60862"): true, + common.HexToHash("0x6b5db95cc840e68213f4616fe8d69097cf4e107f5595c53f33f5719b6d8cc569"): true, + common.HexToHash("0x039450ffd5892dd1961e138845615ec8a7dc1d55afa6ac362280a8d611f0624f"): true, + common.HexToHash("0xdd33af4e6fe42d134e2608322131a78efa77e2dc5d7d4a62f73f1b70cc4412dd"): true, + common.HexToHash("0x27228f8d011e63cc1db3520c0f33a83f3b00a9a9d181841087a7beb53311c010"): true, + common.HexToHash("0x1578237eae41ff500e7ee8c0f668591f9360daddc81aa50dbea8df8f3cb11f0b"): true, + common.HexToHash("0xef7cd93c5386949910539154db1cce00d5ec07d82d40c6b59bd5c24a9b962c8a"): true, + common.HexToHash("0x04699d2a1c10b0911ed5da34e29c758c16a51dac7dd16ac8b1aa02f3b99b37f3"): true, + common.HexToHash("0x28a95e5aeaf34fa9214b9e03c9c4a90a8676cf280d84ece9b6be997753d172ed"): true, + common.HexToHash("0xe284e6ac71803cb79a3d37b612d74f36226a7c54d3a6e6f69306aa3eb963eb6a"): true, + common.HexToHash("0xc7af1ab831695b65a9adee1fa7507306f8a97618c3299e4a2529dd3e1e7bdce8"): true, + common.HexToHash("0xb102e34cbcad74a1856c7547d148c0af606d56cf7ed6eae9ea3c69ec723af465"): true, + common.HexToHash("0x04986745953dd3bc3cc5018e528d59152dc629e659ea7266665e47c56e2aa1ef"): true, + common.HexToHash("0x1ad47156c130cb457e09c05d695c11e916ef2596f9b82c510e52d55ee4479c58"): true, + common.HexToHash("0x45d89dfd4163a3eaafaae1300af66d9e812624a5bf77482cfd18e98744100719"): true, + common.HexToHash("0x1eb73ccb8829d460e4bf09924a7e6771477dc33d5cbb30a7cb3c5296f6e0e456"): true, + common.HexToHash("0x6727b8e162ece465ab5b83be9d29b6a281680dab5d2e4b6f63934a5c65e06a1f"): true, + common.HexToHash("0x235961b2929b344a14ffb89f4a3762cb7d4550fb53a82640f4fc4ff767c73b16"): true, + common.HexToHash("0xd6de63ef54c464f97838b00345890567b37bebc31cf913a222f3e4c449a5bd5b"): true, + common.HexToHash("0xd47c5180e489ab2bc6de6bc28504f0c55d469c25483c77396bb7f083401dd258"): true, + common.HexToHash("0x37b4eb32ef7a80ee88562e0277963a83832cd3cc04cdb99a0f86a175caa977a7"): true, + common.HexToHash("0xda442585290941fdb96aeb651ad1ceca9eeae5d0b0006e59d4aa800176f59e54"): true, + common.HexToHash("0x77c7caa71b1a209203667c06fd0280011deea0cb130bac750caac5fc09cfe040"): true, + common.HexToHash("0x8527776af3a16d6a9e428102dc396c32f6985863ea81c4b274fcb3743cd680aa"): true, + common.HexToHash("0xdd63054d87619d577b87f54f84080daa101a46e913e01124f4658aa0ad2ee54c"): true, + common.HexToHash("0xfd6c21718a968f0028e43bbd64b8a13b41bde762ad95174d859ad7a7fdfa5aef"): true, + common.HexToHash("0x09e9affa4d722225507b4034055d4aff881cb28875d9b8b9375ff00cd5c50201"): true, + common.HexToHash("0x0c9040f230e4d5e7bdfc0deeda0ddbae66a8c4ed5297bcb9c7689afabcdc419a"): true, + common.HexToHash("0xbf502cbe29ef5843d84bf47713eb07f0be21e39e9a3c75402666a7ccab5c7e43"): true, + common.HexToHash("0xc7a5c038229ec5b784b3974999069b67ade4eaa46e904a50021a9bcc5063f4db"): true, + common.HexToHash("0xf15180eb66c584a4821f1a92c1628123b04c31753ce49c2b1952a3b1672fdb75"): true, + common.HexToHash("0xecb191cb77a8850464962e50f9f1bd68f1d88df89164ee90887957049d718c06"): true, + common.HexToHash("0xa216d803077476f27226036164b4d166102920d07ec5d51a7f9b22627b311644"): true, + common.HexToHash("0xc38fbb8a520f6a3c13c78573c2694053909ca210783da5af86dc7923e09c9bd4"): true, + common.HexToHash("0x941a67410404b38fdcdc708f7d73265babdc633ef7d53cbfa3ed25531b471cf2"): true, + common.HexToHash("0xeb206c4548801ca806c6d52ac25774d6a8722bae9f04ec5ef8d6136f727c50a0"): true, + common.HexToHash("0xc371441eb283afc2032370d5ac97eaa082e845f6fc7ab1378381406ae6b01204"): true, + common.HexToHash("0xa056edf067dc450fe8ba1534eb96d441455a7d10a0235baf0d89b552b1b34995"): true, + common.HexToHash("0xa3ac20c93192058cdcc6925d0824f336e3e05f7431bbd5c4e1c738f853df6fff"): true, + common.HexToHash("0xf8ad1790d3b6f2ea145b423459a8b3e6c8fce85c2d97d22050eebb3f4222303f"): true, + common.HexToHash("0x273cee12d01f5a82bf7067c89693bce08ed21c8d6aeede240fcf5299d432f8fe"): true, + common.HexToHash("0x6287d02b6ddbed47d44bccfc61705cef3eccc3f3556908cc79e2df1cd2d86363"): true, + common.HexToHash("0x75428c44acc15fd58b251fdce4c122908069ac705662ee62d48865bd52922752"): true, + common.HexToHash("0x1d6b013091aebd7d8c00079033abc7c46f12ac2ecd7f9c41dd07c33d25b493e0"): true, + common.HexToHash("0x2e65ec627c3c68b68bf29ec88a91f487a473de991d1e467848ae428cf15a2939"): true, + common.HexToHash("0xa8990d542ed3685b24e2fcb03c20326ab3bcba670676d815b57dcbea52bfb89a"): true, + common.HexToHash("0x054d913c95c4d6ead035f051d5da7087cfadf5225e299e37c00145b802960b94"): true, + common.HexToHash("0x9849c36d310ecd2a052c5a93045efe66b904ec8495bddb80fbac525f2fcb84c0"): true, + common.HexToHash("0x6cdffcc64d5d155572934e35ec6b5790e168e42a40f0f8eb1df276a97c111126"): true, + common.HexToHash("0xfc64673d861d32a5b45ed98e1b15cf675e888294b0641567074a6fc63afaa27f"): true, + common.HexToHash("0x45e13e2b303ce7e5b77557c6250847921be3b1939d1b7310273940c8176045ac"): true, + common.HexToHash("0xa28a3219fba0404c367726018d5aaf9ace5ae86ee05a4fe2c2fa4b522690264b"): true, + common.HexToHash("0x7f4ec996eeffe6bbdd801dd58958f34e4336eb62a62ec78a10f43003c69a38e9"): true, + common.HexToHash("0x7d95b9dbd43ec60746a93906c9399c9e172f94af63722532070a69f80a234818"): true, + common.HexToHash("0xa91ec9a28d858b891c4c51340bc6eb1466bd816640b7879be1a24d0b77491b5b"): true, + common.HexToHash("0xefae1c774974a9715bde56ede4ad6a581f6b7eb14cab6720f855775fc853242d"): true, + common.HexToHash("0x8732c07b20adfa06864bb83f0e5971ceb4826d1d731fddcb884699f38bcc6278"): true, + common.HexToHash("0x2122254e2c6e7194b9aaea9567c9824db8cfb095d59941e7567979827c4289a2"): true, + common.HexToHash("0x84f3e7d56f664252326562fe39f9852ea1d39984c2ab9fbffeda54ee313a72b7"): true, + common.HexToHash("0x3dcac6c5305eca3ded6f84916e66f266ab253b7bfe7898fd6c79462bd3f18b5c"): true, + common.HexToHash("0x9fb65ea2696a18113e0cbaf5059da53e3b28743088e603f573db28815854474b"): true, + common.HexToHash("0x8a55ec641f945378d7660b53a09cc452c5ef9d0979060d3e1dc1a923074a803d"): true, + common.HexToHash("0xbbb7711c530d5b7b6d058a65f52b97968c7b8d2830a508526bb78fbdb3ef250f"): true, + common.HexToHash("0x7e6a24ea8f86041f75df58f00b3097a9c77abbdb6fda6ad794453ace3206075d"): true, + common.HexToHash("0xa261e637d4942fc340317f905a218f6fdaf71943e3008ea1adf41923d12f6c82"): true, + common.HexToHash("0x1789c888d9e7004133aeb0d7ea71213adfb78ebf34b6a01a9b147c99db81ab68"): true, + common.HexToHash("0x114f0d49b18104070e0f8e4b257198cde7fecb550074f33a0c222f3894b485d4"): true, + common.HexToHash("0xc7133df2199acf713d35babc815d55ac09b57f893af9163bace2289abde1a88f"): true, + common.HexToHash("0x627ea04fa1370310f3ba5abae9fdf2c8cada8d78443e153884fe67b8ae65cce5"): true, + common.HexToHash("0xb936804aeb03f1f856899a53ac2ed6ac8e2877b2a824ea38462114d6b89e311a"): true, + common.HexToHash("0xa7e08c0d3c3da17731ed4905eb5579648e3ba81f2ce36c5b2ef3b8ec3019c4f9"): true, + common.HexToHash("0xd665be9cb92d007d0ae7db0f218b138106899a5553193b4e07d64a0f3abb7655"): true, + common.HexToHash("0xa6bff052280bdc3ba6979bd071397852e58195ae6bf543eb6552cabea44b94db"): true, + common.HexToHash("0xfd2afa13d495351c1ce013827bfb96dd55498fef683477dc0be7c285f28fc509"): true, + common.HexToHash("0x5d0da4a21ec4d7519c33833b6f5ab0128b929bb767f82a3585bae0f27437ad65"): true, + common.HexToHash("0x65307729d30513f64ca69e1b7b0217bc584eee7186064a03b975ba4065944afb"): true, + common.HexToHash("0x4c64e6a9d2fa09b55af711d6834198463c701ecc4cb6deb993c5f76a34e1ce1f"): true, + common.HexToHash("0x5eb6ca251c79981d9f40779401a4f11105a02af589327e2dddecf4b044f426f5"): true, + common.HexToHash("0xbd317fb51afdaf351077c0aec39f2c5081bcb99f9addc38fa3ee048b625f57b8"): true, + common.HexToHash("0xbef2d8d0727560e96e2fb2dd32f829631c3d84cac2d11894d653f1d57a412d4f"): true, + common.HexToHash("0x5a9900e2cca6b5ccff1f590f94f6454ab44c694ccb29d05c5a2431c7e0bc1206"): true, + common.HexToHash("0x020571d505263926c3e6e5b1f558632be2e9c5d8ce1ec7d8e03e0fbbb01730dc"): true, + common.HexToHash("0x380f1869e240fcaf3a061f7c0e06bed2019cc26d4a73c0e1336c4ab96f96e66d"): true, + common.HexToHash("0x7e0d8bfa50defd380a21395cd61c75f2ca552ac32d6ab800b46dab3602fed271"): true, + common.HexToHash("0x680110a2169c94cdfe25850bae35242b98986d0a0c81af33c4bf69e6eb29081a"): true, + common.HexToHash("0x2d958d255d1a659afff16be15de4cd0b5a0fb10ad8cdc6d83ed8216644cd3482"): true, + common.HexToHash("0xea9d6425ecb68b568039c5479607a830a2e11e2ddd8811842360e40e3d20696d"): true, + common.HexToHash("0x3be402be1c48d9bcd4d1abcc1691750c8e01536723046cdfc397fcd176580945"): true, + common.HexToHash("0x4c5630caf449ca69bf7ee57b8274b2d448b4ee61a47df734feff8a96e55d044b"): true, + common.HexToHash("0x1ce7496a022421ba6e3883514d94d19788ca81b80b4241197154d21271cb14a8"): true, + common.HexToHash("0x279c96420319b26c614394b4859a2f7deb7131404d2d1f5c329becb2aa36a823"): true, + common.HexToHash("0xbc1a6236aa5185af5b73fd21cba892e2024e9290d2ef06a8613acb0d92074957"): true, + common.HexToHash("0x201a8dbc682379d983faaf076f0b2cf317b00ce17c7ba9b6378193794cee302c"): true, + common.HexToHash("0x110f83d8ac7a8d3875c8ba41bf96b3eb17e7c60a13c9dc51d5864fb291b6cb77"): true, + common.HexToHash("0x43813052094a5c4a52a3a6f41d1f43015902f69a0f11394ab957f13b6d3e08bc"): true, + common.HexToHash("0x652dbe1d6ab3c697e1f2edaeed712f876e3ce05f2cb3a86c00d8e3b16ceddb83"): true, + common.HexToHash("0x491800940b738759d3e795e904e3c4a59dc249f0995a32aba223b62a9c5c2afe"): true, + common.HexToHash("0x91e2a05f05eab3b0712e625d939bdba7d8ed30cbd5e4cb9694160a3d292ad3a4"): true, + common.HexToHash("0x0de77c7c461ec501e7b32afd0a20e712aa5768a36f2c99d4bfe506ae8533fe0f"): true, + common.HexToHash("0xdea652c7b012b8323bee57428219212dcfddae06ccd876ca2498a52bcf88d3af"): true, + common.HexToHash("0xe53472880f292a5abf29ccc4c533c24cb76de2345ed59a9b74f58d68f1305116"): true, + common.HexToHash("0xf8afe90e594ed89c27fe60f679965fe5d46a437815976242024b18f28691b9b6"): true, + common.HexToHash("0x818fb102ef7939a6180eccd8f30a13b92f9c3a9f83e160ad27b37c0265b2e1c4"): true, + common.HexToHash("0x42fcac662be53986c2c9de80470320647ef240728fea10f9d2d303329984ee31"): true, + common.HexToHash("0x0d202b48bfa6ad05fb34e9a7306e3b116cbcc1131c72b180970632105e6237d8"): true, + common.HexToHash("0x35083ad01dbcc26f0f56f77f86e32e765b64469920c7bb34a762bc0c6ca30378"): true, + common.HexToHash("0xa8063a15389739b46a0cbbbb4e6a24da958531f9bb5bce2a4ef7715a2299ec3f"): true, + common.HexToHash("0x6f6221efba74d8e4dd579047e511c8aa54850ce4a8be3c2042fc7651e7090a38"): true, + common.HexToHash("0xd5d8392ae3585ed892b795256fd4db58d5e767fa82f5532cb01bd8ebf9e61f8e"): true, + common.HexToHash("0x3a77aa5dff8c50fe75b3bb9b31224ccda807adb50545c7501c003b5c1c814f56"): true, + common.HexToHash("0x111934676135b980398aed222c6c775ff6f33e8f6999e6637449be8c191983f9"): true, + common.HexToHash("0x2d320b3fe8054f82ed1987093691c25644411b7be20e8ec4fc75f3a971787f9d"): true, + common.HexToHash("0x90cc2a247fb8a7b08533993a5e37f0f77505c14c5bf66e6b18b35e6d4b583cbd"): true, + common.HexToHash("0x9537a4db186846d63fb90555a02225becee5cdb0734c38ca6a84e4266d2f01b6"): true, + common.HexToHash("0x145eb91f9ac0e3449807e30f75dc43be16f833185b09876e36b734c7c3efd24d"): true, + common.HexToHash("0x2abedeefb0bc95d602343304e4fd30300fe3564222c8a889850791c6fe5ec2c2"): true, + common.HexToHash("0x297a6d7532aa17f0df5ce159185ab9a78309ee1f560fc556e042aaee7fcbe61c"): true, + common.HexToHash("0x210017a258793a6feddc0a487dfb526d7ec9fb6fa2d3f07d48f008a9ab29c0ae"): true, + common.HexToHash("0xd65f7753cc94712b7180322298150a30b7e7f671884e0c1f9ca5553987ece3d5"): true, + common.HexToHash("0xc02d5f8f48a8ae3103deff3c31f4e0d723decbc758ff0a07b354c175e39fa760"): true, + common.HexToHash("0x8a0d1d977ade35ff8dde2899f07b3e27d1cb0a450772feaf7ae1321caed94587"): true, + common.HexToHash("0x0e7b8ab2073b1fd3b0369b127297a38d4e544fb0913f4a423ef772551936aa87"): true, + common.HexToHash("0xd9e5bce3748d58b362e513c401d2f89710453999330a6a5fc42f2859a9923fb2"): true, + common.HexToHash("0x024c049023db527c5192477f99a47f9bdb2119fd937ca318a1169f07f3d52b8b"): true, + common.HexToHash("0x5b4a6b1a5bbc5cb5b8477bc714f1d66dbf038e5af2ef047115a54f748b2372fd"): true, + common.HexToHash("0x15527ed81cc6f9c18c81b5b2d0d9256a169d5abca7744bdd0d3a15aba69be881"): true, + common.HexToHash("0xdc11cce64a780a5e0f222b3adc7db71ae096d4ad71cb2f5ce5d383e7361b61a4"): true, + common.HexToHash("0x3de948a02fb3a65475b9824885ecac7f1a96e9f0de03991e3784798ed26bdc6d"): true, + common.HexToHash("0x7134cb5df3c033fd1b7b87a78dd6265b5aee9bfad39fc54b149581c1d4b7cfc1"): true, + common.HexToHash("0xd449a8671f5bc91cfc4cf3598a2a1560ce35ae783cc7add60221538dcb9a239f"): true, + common.HexToHash("0xaa0075e6bbc1cffa66ca4bb8f6361800cb753b11fa844d867acd0aee86e7de1e"): true, + common.HexToHash("0x0db802e86f19039266671730ada68a47736ca944ed97a60c60e82cf5ae8f2f77"): true, + common.HexToHash("0x119d9bd897c1edc6aedb3dd2d2244d482a9ffdb3f3e002e72e218ac752961a13"): true, + common.HexToHash("0x2239962d36a1cf135b6e23de2cae3fbd0af40b24c70a22c656ff17690fa5fd0b"): true, + common.HexToHash("0x7175f9f04f825f3c4ea028d4959cbdfb782e54b1f0bc73a74370d8c6b580cdfa"): true, + common.HexToHash("0xca8720f000c9fd1a7bbbd450828d5de8b7aff06b38c55ad6f89f664f88bba4b3"): true, + common.HexToHash("0xa80bb90425daaf0705d31fb98c46aa2d7ae58438f26cc1dfb6b58d4ceb2c1ac8"): true, + common.HexToHash("0xf007028e0ca438b655f949386363c589d583c9ad64e11c7677a3828ec02cbf33"): true, + common.HexToHash("0xf39e89f57250b31df0b9b8693e11ebbfb5fddaa20f657460f1686b073cebc221"): true, + common.HexToHash("0xbbe146cb980b3f6f180eede08a7a2046e890c4298ce1a6d1e9f4c4f04c29f640"): true, + common.HexToHash("0x678e39432a5a5c9fc39a2342f3c56ecabb7625d93916af781092448b1b37ba62"): true, + common.HexToHash("0xf8abffb9ac9e55f4802c90fc94313f691df6dc29974da3d13e36d448a0229c11"): true, + common.HexToHash("0xd6c6033de50bf4a40beb6d714c9f51bcb74ff505384f16a32f45153c8c013275"): true, + common.HexToHash("0x6c25397337922ca1982df39fb1edd8f568dcb081e3ebaef6e70e8d89b1c63c4e"): true, + common.HexToHash("0xaeaeafffb0eda48c9f14ff508f766ba73dbcb800bcabafef10058e4539b54d63"): true, + common.HexToHash("0xff05dff5ca845bb0fcab663cf1155f25eff04f590a5e0bca4d2a3a5e9facb10e"): true, + common.HexToHash("0xe064a44229a696c24beff253892a033d125bb0f7904b19f28bf840e29788659a"): true, + common.HexToHash("0x26ac8fd3efe6007d68db9e960551b82e1bb36ed518969376c3dc3698be64d3bf"): true, + common.HexToHash("0x02929ce7f6f48a96667edfb1a50f0772820635cfde4d0431d6b24bb64b731e90"): true, + common.HexToHash("0x037daea47ecaae67e367cdd48fb1b1e8d9e792a9a35c998e96892b3921255196"): true, + common.HexToHash("0xefcf35833d1f17ff3d237164da6633c18281b4025d937e4747f4af8d8bf4a09e"): true, + common.HexToHash("0xc1a52af429d59991261001c6f23371de60b8d16f9b97e259b331a0b10aef05bc"): true, + common.HexToHash("0xc49a7e23b19d30ad307ab89fb546c4b4fef8eb269bc7fdb613f3289c5f4508da"): true, + common.HexToHash("0x6160b31f95f06bc929b5aef2ca1fa5cd1dddecb97ae0053c992a5c7f86f995aa"): true, + common.HexToHash("0x0f370f3c76310b681addb811f656131f8c8c2b625543b623fae6154458f2ea83"): true, + common.HexToHash("0xc865999b16260e8382dee9070001a330b83f58aad7f26c6ef9bf01ebe49f3008"): true, + common.HexToHash("0x0705721f93b95248cac0a0706ee9265269037eb8908009addd1ed1036e1e7341"): true, + common.HexToHash("0x7af8af6e4fb2a7817c729b1f47e6fbd33302166376ff6884d04cf3ec2b2c7458"): true, + common.HexToHash("0x12246eb14e56bb3d6e997f06bbf825980a837184c9327bf7828a6e3d4a7e9901"): true, + common.HexToHash("0xed0d162cddef46009d338242b39f706598cf8d8d8fcb2b1a8ea5f350bfc41a41"): true, + common.HexToHash("0x119b6422b6cf18ad16ead390c91092cf4b55559391188154f9da48858412c90a"): true, + common.HexToHash("0xfd1a92fac399b9baab9c578710c77d7fb2d27559ebd916e157495ffb8d708cad"): true, + common.HexToHash("0xa5e5ab000c031aa62145a4267ea0c2e8072f1be724824bdf77196c8b8498bdc0"): true, + common.HexToHash("0x7c710bda1c8628e3a3e5d636a3b1761b6960cedb7a1d71885177d83489fd7177"): true, + common.HexToHash("0x9eb6e0bcdb8afbe50405ecdd712e0625c58018ed88389c61f33ed1c755844d92"): true, + common.HexToHash("0x35f0753adb3f754b52fc0bb6c3b33b2f1bdbe81ec550af72759efc10964cd05f"): true, + common.HexToHash("0x38215550f5d1a96a712e33dc93a414e8ef7d4fb2238b5c19f87effa1bd9767ab"): true, + common.HexToHash("0x2bac0f207ffd42c5609d003afcc7543a6a1f85b87b410a58e1e92732c7d0c980"): true, + common.HexToHash("0x01bd10ffc40353261fe9daca5bdfe60c9b4f28b39bf2cb4da6cd6e4a26aafc55"): true, + common.HexToHash("0x1176ffa098708417dbbd8c90d381633b1beb744e510a8562a5a77d658508242e"): true, + common.HexToHash("0x660fd660df132b6c0460633b57fa7e907076189b9fe3b4ef4fbe6cae828fbc9c"): true, + common.HexToHash("0x5b7fae7ee6053809e6742ec58e0d8d4d57da1911977ed4a2f5f85ad6a6f9972c"): true, + common.HexToHash("0x40acb92e1029d3c5338fdf94b296842f5a1f09133f131784c1f4511198b6eb0b"): true, + common.HexToHash("0x9dd97b4f2ea2a4ba72409410c4d06bc1fa87e73046a4ea435a84a070a4a98832"): true, + common.HexToHash("0xef6b2c1fda47ddd511fdc446c9b6881068c961c14139186f23ce3596f767bf74"): true, + common.HexToHash("0xa9b92316737853756e2fa57733e87fbfcedfde722b37efcb82dbfe2394833b97"): true, + common.HexToHash("0x44ec05cf790f92b9451d5d3bfd310e93b699d29baa8c4f66064cdd99a8a8b6bc"): true, + common.HexToHash("0x12a3e8109d9541ae2c574a4fed06a6e35bc31a8eff56711376e564bd5853525c"): true, + common.HexToHash("0xf4ce53619371ccc6f0ca3cae52d2d866eeec2dd4cafa6fa6cf34a6d81b1f8bf2"): true, + common.HexToHash("0x8fad2a5317d1896eebdeb181350a51c068c237954f31270ef58872ac11a35b8b"): true, + common.HexToHash("0x3cb230d9bb2f8ea2c4f18055bd659a4d95d31a15b5fbaf07fb8f83d9a8279a9e"): true, + common.HexToHash("0xa8b85b00620fbb0343c0ad809d7767f36ade281522961a9ffee32027ba2b7a93"): true, + common.HexToHash("0xfd30fdce3f74c4610cb1c7ce95d0c99fb11cab0e9bf2cdcb6904fb953ecf5c5b"): true, + common.HexToHash("0xbcd5a236c1cb950ae7f848269ed8567b2f314b7ed8ae71597da6076f8e24849c"): true, + common.HexToHash("0xee623dc7e66368b203de8aed9830991899d85e279e9c900b29f1f85985adf53a"): true, + common.HexToHash("0x0958df97c472fc8c5c74f3a1dddb4dc78ee89fac6541da582d98d28010a5dc00"): true, + common.HexToHash("0x43748b37489ab457df1e2a421a01b8725a5e0aa35a342fb8ba7d74fa84684565"): true, + common.HexToHash("0x4342e841111619091b8b309254194965019e29fbcd96e3cf4bd0090b6917c1ad"): true, + common.HexToHash("0x1022ad682397fb3e1c8de5b17099319a805636db105b7af1850b19af403b1ef8"): true, + common.HexToHash("0x030c4a5465b9075aaf6f870ba64630d90027f1a76581ab4a84851cbb91480466"): true, + common.HexToHash("0xac8c44ade338309fb2e6e35a410b2fc48001d92d114d644fb8c96b9da672dc0c"): true, + common.HexToHash("0x4920aa35a371fc0cfe50bbfe953e52a621d0880bb8ed20e654e8bed561beb9d5"): true, + common.HexToHash("0x78d69d3d8b97399dce9836961371d7f8b106f4b9447167f106987a46ed433fb6"): true, + common.HexToHash("0x9f5ee432fbb14437670a5005d1bd313dfbfc502762721690f8fb70e70aab7e0f"): true, + common.HexToHash("0x6dc8ead8f8ef59ce1a1ac039a5dd9607604305f885709b33f912b38b49b24c3f"): true, + common.HexToHash("0xb341010e092f66009eed1ecf6d7e3071ea1f39b1ce02c449255df0c25cf3a8cd"): true, + common.HexToHash("0x25b3f44a23692ff09cadeeeb76473f8eed8178be17039947224453d4a6e60910"): true, + common.HexToHash("0xce76180e2922fb9bbf208bb1006f1992f3afcd38fc75ad312d2719ddda807f85"): true, + common.HexToHash("0x53b6b5cf006502f0e36e15875d8cc2aca83444ff8b949f67a0fbf2d81a3d2090"): true, + common.HexToHash("0x9c91e42dc37ae42deee3d5222061b9d14dffed8fc1d2d97567b6506123c1cadb"): true, + common.HexToHash("0x105e31d70aa4b8c13fb4524ea8e682deac16c63690adeee2d13d9428c5393099"): true, + common.HexToHash("0xacf67963dfcf6ece67fa6c4f368c4d27620b14e61c1798814faa1340fcc13097"): true, + common.HexToHash("0x90f8445cc534dd986df6be2acd3f477f244b5ddc4077b4a60676f9ee765a86ec"): true, + common.HexToHash("0x49477b428067e9c8817285d943577225a3b038b34f680b0bd457c0b85df55171"): true, + common.HexToHash("0x4e7a164212f48a84d33937769dac6013a54bb6232b061defb777e148f8a21dfd"): true, + common.HexToHash("0x47c00374d4de35f31e2fa5cc06519c4514badd05b627c33b56b7c19b4e129111"): true, + common.HexToHash("0x38f98a77e81a7de5605daf2b51ea0fcb56c01644d3c368de20e3d85cbcf64d62"): true, + common.HexToHash("0xc2eda685917767a4cf50e1271953463a79b2dacde05c9ac27c5c0f03c106b713"): true, + common.HexToHash("0x2e83b84f93ec8470f734b5fc8b78f9046c29edd0a4f491952ce6218b8181bf4c"): true, + common.HexToHash("0x6959d0f109c7f68b2097e33b06da11a88440a56a5511a16256e8e323e32cdbab"): true, + common.HexToHash("0x608d21f5213a3d5d089567750a1e171f56d632f4c49f90d302fb0f508f8bf2c5"): true, + common.HexToHash("0x7a6a2013847fe5b247ce76596024015075d73d97fd731482ae4ddffe9c22f5ac"): true, + common.HexToHash("0x0d8ddcdac4887a0ecf8cc4925db350f98394f7357af43f541d19676d36183418"): true, + common.HexToHash("0x90bc2cdaa1b85ee4432860ab87c35ddb761b19d5b5063268cefef5b5d4879acc"): true, + common.HexToHash("0x81d9ad88cab11b7cca09efaef9e2db59d0520a6178d20f1c5ba9b7a297e89a01"): true, + common.HexToHash("0x89fddd5bb736c96a3e1040a8fd0503260ac5d69736044f0c08cb4714f261af8a"): true, + common.HexToHash("0x4ffbfe6d5d9cd38d28388411b7e63141c1a1ef202fe7307af739a42c9e3d1ddb"): true, + common.HexToHash("0xe2afcc7e8cee3390e0ca15109833a43b27fffc745f60de981d7043870d9b6ffc"): true, + common.HexToHash("0xf84dc609892e6f2e18ce83dc746ef5c4c4147baf82c2bbdf82635892a770e954"): true, + common.HexToHash("0x33ef91c13a2033f02fda720938cbbb09e860496ef9e914b26bd6e25a8ba8e931"): true, + common.HexToHash("0xf81fdf154559ba3e26c1731aba6f873ff95adf219c0006e49463cdfe1c2fab73"): true, + common.HexToHash("0x0bf00fa18ac27aa529af4cd749c0e0255ebe7c2516605c25cb5e99a817a2f0b3"): true, + common.HexToHash("0xf62af6a97219a9f9ccd111c76611ed5d7e4c8296de7e211420f420e3ae23aa7d"): true, + common.HexToHash("0x024b2897ac6632b9c71253267392992d703d8c6773a6a1b3e280f0f960d402a4"): true, + common.HexToHash("0x20152219adc41ccd9e11f1edeb06234e44b7a2520e2d0aa515344ed046c833ce"): true, + common.HexToHash("0x22b19139eabf24dcd7683413cacec59633aeb22e2f4df9771f25e7de7ec881b0"): true, + common.HexToHash("0xab457fcab6982f84f19a9518f5218dfce8cc8e667992f4f3062f5faf5418785a"): true, + common.HexToHash("0x97432bc0b53e6f580c3b9e6b4b3010a54f6c356b84cbe0a6bfd011ca26d677a7"): true, + common.HexToHash("0xc6d15c5405df21b97d0ea1830dc12d773a4fa17385c65da74fbfa7186d8d94ac"): true, + common.HexToHash("0xc3ce63ebe08a8d82c2999e6cc2eb39f819e30179db12a5ca61c8abff81a9e003"): true, + common.HexToHash("0x2ca21702341977f668568ae37ae44b62736447289e727c1acb1f6615a0b9e8ed"): true, + common.HexToHash("0xc02ccf1229bb8324902f32d2da16bd46c6833b4991044385682823479bcb6a96"): true, + common.HexToHash("0xb2be390203c7ba4cd19610d662b4d87778a4cd3a219917b6701c6a73796e2c65"): true, + common.HexToHash("0x4d8272192fc599ee8503f84074458202f55aa2dbc8768c591de2bd565cd5ae8c"): true, + common.HexToHash("0x0fc14371ef865461cb6b3c1d0aa3b13e301427bff5aad67a5c59bd7faf0b6a78"): true, + common.HexToHash("0xea2153f70c94461a3c1f6cca11a9a0c1678afca52fb406aa4cef98ecdbbe44f7"): true, + common.HexToHash("0x6e1a09547e3c2380f8bc8dee9b1167b75c8f421f2c5cbe8bf8bdb7e105dfd355"): true, + common.HexToHash("0xb1a419b0233b6567f2ff3afa37297a4e8a0dfe9a51d8cfe03a94eee658bc5c6c"): true, + common.HexToHash("0x24daeebbc0edbed424a4b1d64668123b32eb1c4209457efdd6ac26e654c354dc"): true, + common.HexToHash("0x03472f44a3ef95b8af64cef9305994dd8edc6029d235b9e91c5c3c92b5714af2"): true, + common.HexToHash("0x9afb023d7c9c33c2d71560b2c942d7e5e2fa7f730d90069e3dafc6654670f363"): true, + common.HexToHash("0xcc54567c058c2bc4da311eb4e233cf7f6c480b231751c4f6e2685fd6d56807a3"): true, + common.HexToHash("0xed9723d9d9de8d79ce1ddbacc6f8aad0c32b308bc1b532d855727a790c5bd0d1"): true, + common.HexToHash("0xb60109a2e3ad8d455e5a155088ae4ded0239389015d6c97d448fb62f2d889119"): true, + common.HexToHash("0xf9a7a5a045a7bff0ce9ddbed789d7a152837d92645c8db25ccaf11c10844f5e8"): true, + common.HexToHash("0xe43947e9722aa08682eba9dcf6cf7a3c06aa771cf517febe697b8e29386ed349"): true, + common.HexToHash("0x505877e3ef2e1dba45cc9b2bfd69737b7c61bc1968b1a9e99531a605de4d1f72"): true, + common.HexToHash("0xd882ea1bede4f013c2cf8a99b07b68c1f83aa25890dea4b43b99477a35a3f4ea"): true, + common.HexToHash("0xba4d5d966e90b9fed08211b5399dc6a3a2dbf0cc498481a520afc06ff4d94d40"): true, + common.HexToHash("0xa89ab75fc1ede5c38f3de90420d3c3f6e82fea219775322eef3ee6d29699dafb"): true, + common.HexToHash("0xcd765471441a6488b07cd8c71604fccd19d511180f63aa8010805d0122530ad7"): true, + common.HexToHash("0x37fb75fe670d0d101c9458da48e891dae3875b3d8c46de50c06312e96a23e742"): true, + common.HexToHash("0xd9d8b44e517f826728e424e2d68ea6be26e1f196662dead1d2e6ab306df1ba9f"): true, + common.HexToHash("0x91ef010163061be79b939bde9c9b7509baf079549797e5c082244d70a44d7829"): true, + common.HexToHash("0x14428ea71dfa0af39327b47d822b8ff7d8f76f9057510a224df1966616217c14"): true, + common.HexToHash("0x65460e53e8f12d08ee68eed9aa340a4702ca8d87b12513248e6a46dcaae3febf"): true, + common.HexToHash("0x70bf0d7554d4540e65ea7a659eeac60b731cc0a1003fd218fed03159fd2c3478"): true, + common.HexToHash("0x27ba8e5f497b17768bd8007d90a7cc4c5f13d82fc3149253de4baf9eb7996ab7"): true, + common.HexToHash("0x3867296a08840adfcb715d6aaba049d72130615e4e2bbb3a1a606c4588475fac"): true, + common.HexToHash("0x33935d311f9dd947b3f30898f2e2dcb00311b0b0de15a62f0beda1a0b14d79d2"): true, + common.HexToHash("0x3dfd7cf52cfc7eb821afb56ceb0edda7df3043bbe2ebcbd7bd0f011e08264822"): true, + common.HexToHash("0xc5552cb93d77c2df417286e1407b0006557e93077df1f93260b3bf888d2b55c7"): true, + common.HexToHash("0x621e7ba2a4b9451d2609cec4b55fa6fcaea7e6f3a4bf63db2a8cd09ca51b571c"): true, + common.HexToHash("0x997c7c4c2cc5287b86803f719a2890fd809486f16a9e3918b3d0b3a655f3575e"): true, + common.HexToHash("0xd76c2f0e92d0fbb7558779525316d171207227944a9a7ef1dbc625444b324a97"): true, + common.HexToHash("0x283125af6148d145bd7b800b12d1d8e06b7409982e54daa1adad04e12dc382e9"): true, + common.HexToHash("0xe36a8e071379af2436415c6232bacb53bf3698b43e5787f236b3b0b51c92ff14"): true, + common.HexToHash("0x8457b7f62eab14423d3dacb3fa4a16967370a81f7f7da59e1cdfe4c910f5c561"): true, + common.HexToHash("0xf17bb10124ca91ed5f1d2975805975b4dd1d2aac21d699c578be56edb4cc0a7f"): true, + common.HexToHash("0x07ea07ce7d0b37b38ea44bc5ee1dbe95b781d433be58005ef352418a10e76b62"): true, + common.HexToHash("0x3f5ded92357b0546d409427a78508cf2df81115a486897b1c48955ad9e134c67"): true, + common.HexToHash("0x7874b452826e84f3d44d47dc85ea59f3cd88ba3dd26a6f6a89dc6cd6edd0ef81"): true, + common.HexToHash("0xf457b52e1d2d35002427fdf56acd9dd8e4e64dde1e94564caa743248e58bab39"): true, + common.HexToHash("0x75b6394d96d93cbab55b28e08d648b18a76331f47c7974588dc25fb90e9428ec"): true, + common.HexToHash("0x739ad8ff8014e6b11a3752fb94f22f8fbba10616e9da2f3bd4f0d723113e1f35"): true, + common.HexToHash("0xe179e4a906623c5b0bd19047b0eb3594ac2bcc8fcec5cc394a3b387bd95ec8a5"): true, + common.HexToHash("0x3a133278ee92f7bbc1de303ec80844161fd84e6b698d8d478be423637c4aa32a"): true, + common.HexToHash("0x958e695b943dd23ea76b51433d66acb2286accd3c45df01ddd8478d0e074118a"): true, + common.HexToHash("0x7d05716bd5d4f4280940e3bc60fad902c7173c744867c74a37bcb20151179efe"): true, + common.HexToHash("0xbb2fd3b435d5d33a68c84118da01669ef16747a76c975538a78d564d5ea22d61"): true, + common.HexToHash("0x75f1530c56cb3ffc9df159fbbbcef48e784b187c2a89615f3fbd0eff050c4b37"): true, + common.HexToHash("0xc8d53954255538d08b6494c67b74e72c889bcb98e6b2c3367f49591d330217d8"): true, + common.HexToHash("0xfd25edd8ffe9cbd89c118ad76ecf18f5f6d9247d719b66fe71ef17dab3e99f53"): true, + common.HexToHash("0x23add7997f498fbd5997f0490406dbece8920e069c8dceb3c786be8e6a919dc0"): true, + common.HexToHash("0x78a424e73097195b3c5a421bd3070534157c1ded37047fef01aab29d8fcce28b"): true, + common.HexToHash("0xb722f214fd057aba3c8fba959c43b35ecdd59df99b1c82b44e038f693ed3386c"): true, + common.HexToHash("0xaba2e5de8574882b7e563633d856ce7fb733bd530455dae02a287620da8510d2"): true, + common.HexToHash("0x5f7bc802fd4e10bad5ce1b5ffe50e573f1ee266cc0d855570602e52a13c99f5d"): true, + common.HexToHash("0x891d0996e5e19ccb15a094939c5cbf77d6454a70dffe31c299a97820a0bd19f8"): true, + common.HexToHash("0x67b04d8e93e6af4db2bb1f4c4fa5ce51662ad32a4ab734b14ce800006c1b1e0a"): true, + common.HexToHash("0x1fce4231b80b8196b93094ddeb0e03d789dcc8ccb40502395905089808c0fcef"): true, + common.HexToHash("0x067720959f6d7f65bc0480bdbb005d6b57210b330b1577870f91cf83f8aa3fb6"): true, + common.HexToHash("0xf0e13d3b8ba9e7b7d8ca06471dacb14155b74006171ee569d12d5bf3cdbb413f"): true, + common.HexToHash("0x2344114bba3ca8feb7de710ed2d1a199029da7d7756921c1f40638382215b817"): true, + common.HexToHash("0x4e09ae721847744775ecfca9f9449320827abf087e62d9e12500de5344c322ca"): true, + common.HexToHash("0xd749349ba91576d5337a521c2400e2d92210531d3d011788ec33f7d539816885"): true, + common.HexToHash("0x47057440c79a7f39b90062f74311431e5e544cc2b26cc367748653c629335e72"): true, + common.HexToHash("0x4840b7a102b1c29e563ae944af35ef3262c329b895e3f997e5928c16c91e6264"): true, + common.HexToHash("0xedb679812903fa2a20acd282f6e72f637d062dcb04929a34de4a7a6b791091a4"): true, + common.HexToHash("0x9e7e8c582e263dc1bf5022d70088f78a7074b72ff2fc70802586870967549824"): true, + common.HexToHash("0x767cecd300411c98d8d610823b94a9dc4e1717b1f8712d62236adc9b2ba731d3"): true, + common.HexToHash("0x806a384b10ec948358f45f469bcc93b3d9ab05aee3759172377b930104a03028"): true, + common.HexToHash("0xb60c8a46dac7f2836a2f445dc67f95ab824effff3c62158ec9ce0130772aaf94"): true, + common.HexToHash("0xcd3b1dcbfe131a3fb27b7a64e6035ea2e0263f4c8a3a605a60a4589cb169872f"): true, + common.HexToHash("0x0baef754422233cda2536e9c55ccdce89ec62ff93a198142ca30200191540d61"): true, + common.HexToHash("0x3c16d733e42d30edb86de6018b952942e57738ed7c407dac1d0ee0511598cd02"): true, + common.HexToHash("0xbb445af6aa4fc5c5579e7ad672ff787a460978ecfe6f3cc190785fa516186efb"): true, + common.HexToHash("0x2b6d3696d4c951d2aadf2e5b5286eb0baed7e469c13b5ffc6552e313a9ef30f5"): true, + common.HexToHash("0x917799cde37f824348dbc4795198df87cc6068c8fd46f7aae137d1c29403234e"): true, + common.HexToHash("0xd59d5dd3790436c66ada9d5071e5a5bd3712f2432a3a5e677d072d0a51f4dc89"): true, + common.HexToHash("0xd0be1476be3ecd3a11c4421d897b801e32ae0ba24935946ff187848d30bdaba1"): true, + common.HexToHash("0x84c98e710f206019459e4ca0a6211f9a9fe432c3e9147aede3ba3abcd833dff8"): true, + common.HexToHash("0xfb72e363b811677abf1912fce1d458394c506c1e5a074a3ef4b5253007d7cc66"): true, + common.HexToHash("0x333819bf5c37f095c43dd28218e326f8a901f4e61f5e9357d213178e863587a1"): true, + common.HexToHash("0xc5f9bbea346673c457b5c97a55bed75797effc8e0b77bbadf429eb590a54356d"): true, + common.HexToHash("0x7cdea8f81270a5671c4c49b845d05731d1674d1fa6e92117a5053ab13fc37558"): true, + common.HexToHash("0x2f2b640b8cbb72f31c41e2fa828313810198d7c8239c0ca41228b141bf3946ce"): true, + common.HexToHash("0x37973d3be1592f9732424c08143261b5f516946b75793b70bdf90b0c468640cd"): true, + common.HexToHash("0x529f3b8e0efbadce22aa2e185c4825b5d911c25786a2e732e091f3aa5f08805b"): true, + common.HexToHash("0xbe8a077dcaa409ae129ac469d7263ffa4b062e9cfb89796eb4c9599015d06e55"): true, + common.HexToHash("0xbb9520773c1b621cb7bb68dd4ccfe469b64090be5a855b0f4a4ed276d65e8607"): true, + common.HexToHash("0xb3d15497e90e5643a42a462b01bb2e89d0adbfa83eecf2fbde0c4cea372f8023"): true, + common.HexToHash("0x1a454a5546fb07980b53d798098e4f6cd44eb354a48740490ec50d70c51260e8"): true, + common.HexToHash("0x40e923dd36aedd603d6348d513b100655bebd3ed263813533492941dc4abe47d"): true, + common.HexToHash("0x45aa7b27763be5967af32e997997694bb02bc913daba683e79c6b2f809c4a777"): true, + common.HexToHash("0x70c870fbdb9b8a879c0f6abf52e18d36bc8cea9ade3ad045bfff63a446d78e49"): true, + common.HexToHash("0x7022c81c2c3d434b84dc0cd133befbc4d07ecf0741b5ebe957a82c3675c3768e"): true, + common.HexToHash("0xeda60bfc1d9da1a6e468f82df6c36b01b484df77b10c3440bc458a40be6d2442"): true, + common.HexToHash("0x2bc12f7aee33e381da3989e35f9eeaba843ef3ae5ebd67e484d132950d0b5fe5"): true, + common.HexToHash("0x8ee6a907eaa6696b25dc4ec88c420b51092b6713be7e647a1c8fb0b714194a7e"): true, + common.HexToHash("0x43afdc77933ee5274ae10df2dff29a4ab6ced66254fc4d3d3a957b2affb991e3"): true, + common.HexToHash("0x980a3abaf14527a1cf2ade97123c9140f890fc0a009f673d2b44d6eb0be8942d"): true, + common.HexToHash("0x20b9dc6efbc6551c92d0aba2e0536fd338aca573f939fc198a35879b59fd3a09"): true, + common.HexToHash("0x4f55682fd58058df41c1818a2b912b09f7f7c3c1ebf75397559053408b388730"): true, + common.HexToHash("0x0ed34bdf1d01ea2dccab7a5c56208c2882d57a7159f06e1a0a967f8da97e4d7d"): true, + common.HexToHash("0x2461cbb150c2f51bc03971b18c1dcef8d1ea494a29386ecb7d25186bb245e04d"): true, + common.HexToHash("0x5b0d5a7d3f34bd97bfe83f83ca04ba40e471ea03d09e5ed8a499d74e9033f901"): true, + common.HexToHash("0x53748ceed2588a0deee487cf71591ffdc97df8c10f566d603c3dae275a217b6e"): true, + common.HexToHash("0x69ab757f1d2d85125d627e1f96b8e627ea0bca6d7975bb4d402dd3dd05b62eff"): true, + common.HexToHash("0x70ce9db50ae60589c042eccd94e155f4521c80503159debc84b95952589ac36c"): true, + common.HexToHash("0x43d750d577ce26598a972acec27bcc35d2398b429df9535449a6d1e2b8063afe"): true, + common.HexToHash("0xc56cb6a70d6c76a39a116c5af5f3b92707e04c65fdfe340e72e4dcb92d13cae7"): true, + common.HexToHash("0xe8dd567e690e3896bc39dea6151d1dc59233b7aaa30f4a283d7cd87c5bc9ae95"): true, + common.HexToHash("0xde977aa5b17e4a49837a6efb68588d2e74f4ce5a179c39499dbbc2f2d33308f7"): true, + common.HexToHash("0x1ac148aa6a080c39d85177c4aa9edf642bed834600dfa9ccab9a3791a5ebd4a7"): true, + common.HexToHash("0xb83cad377d828c86cc49ec5d91230009dce359a2e2c42d925c38093cb3abda18"): true, + common.HexToHash("0x6e86afdb0efa61d944893f74621368363d7792ad5763ed6391830828f535c11e"): true, + common.HexToHash("0x02daba2fc0f4982a7039fc3d186f06d86ef1b0fe5b37e05c1f8aac508c05518b"): true, + common.HexToHash("0x9347021aea441906b59aa3b735c96b583813b72aede5836ee5da4a502dbf68e4"): true, + common.HexToHash("0x25a3aa1810281254a870491408001ed1d227f808eb01d26ecd377fe3b15671af"): true, + common.HexToHash("0x241b1bd351230065034de439a9450293158f30359d64065b5081bab0953e548e"): true, + common.HexToHash("0xe1b035513aeec23287ac929a67d22cedb4fe026436597e7ed20d63906544b360"): true, + common.HexToHash("0x7771d7cfc1428db485b4541dae2f8c0424266c64a627f911e7f7403a2aaf867e"): true, + common.HexToHash("0x6a2639f4d4ade16c4363764797c9741cba7eedf1ff0dffe29c2a6973905161ee"): true, + common.HexToHash("0x377100e14b18b85aec8ee700b8add663bb1268eace23d6aa0b55801fdd0aa3db"): true, + common.HexToHash("0x9485aaf2f8c754f616f61c302518f2ba1fa9233ed685df9d9f228663a0b19a44"): true, + common.HexToHash("0xf1af576eb9b8c4b602a59773bb0e7fd55e52fc69315b837086fbb3973d9b39a4"): true, + common.HexToHash("0xa6438e53843ac1a9021c1b0c5b2fc67f3afd3342e621f1e6dcbc676d0b541b2d"): true, + common.HexToHash("0x2ba966131085cd1c92a43c9a803e35b2b229ebb447a7fa4d13058132f7420b0d"): true, + common.HexToHash("0xc30b34aed3079cbe6b2055dd04c44f3e5297e4fc797f8eac153c6833f67fe6ca"): true, + common.HexToHash("0x5dd37db7bde37fbcb68b18daa1ae6e2cedb1a455c24304c90beee27d59e99b11"): true, + common.HexToHash("0xc3c704c5097d2c16381d423b561ecf2e7334fb4912d1071dd94a4a861bf17c13"): true, + common.HexToHash("0xbc7e79f7a47ceb7a9c640d4c742a89d25becc4a92e7bffa02b69ddc68f6170ac"): true, + common.HexToHash("0x06d6c1f1769b989e1739bf80f9db2d612af2656d3958895664eec5d69daa063a"): true, + common.HexToHash("0x95793967f6554f1664f5545926391b8e2667f30544438d313425a746ab2b62c2"): true, + common.HexToHash("0xd3cab1c41e622edec3c8416e777dcecc92c6bcaadd6568c93191f005b842f297"): true, + common.HexToHash("0x767bdd1011ba8002465f5fee6c41abcc34a6125635e0851c55b6d71b437f2be9"): true, + common.HexToHash("0xac9983ce4e25ac708ee5a3de3442215cb3bbe71a17808122a057d1373e75acf5"): true, + common.HexToHash("0xd1f96bc0d85be0a6ba91201cefbff8408e300b0c89b7c03532d7f6b3675b0127"): true, + common.HexToHash("0xb06e22d298ebc1fdc7237a6725389c0bafac87b34d06922091900349d8d41568"): true, + common.HexToHash("0x9302641ec30af466418c8815ce8747ebaf1b3cb0a2a9c7ad5fd3e3cc750f4202"): true, + common.HexToHash("0x5b072d96c5d2d05c4c5984ab162a76972ea374210f0420ad0fcf336fd106527e"): true, + common.HexToHash("0x050f0a852b97663cd0912e30cc293ed21cf238261e5e2bf35a763e730dbf2494"): true, + common.HexToHash("0x9b3293719f4190132ed522ac46aea320c82625474091b3d9e3a96dbeb5e4a8ed"): true, + common.HexToHash("0x3e37515398e432350f585bf1d6163c21e26958b27d34136a745fd998bda91ad5"): true, + common.HexToHash("0x89cd6bcc7751155de2132e82e252f6cf83f14d05f64bfaff71858b55cbdd7e97"): true, + common.HexToHash("0xd8929971029d2bec0514ef85c8c3f9996a1e9a39ac39983bce2a2007bccc181a"): true, + common.HexToHash("0xeaea8f3a4fb1757aa3230097762d7263557aa6948818961bd486a437dbaedd3f"): true, + common.HexToHash("0xff7fdc1b72bc6edbff0a202df1e8818e4b1a65a45938b0ce019981b9b357f552"): true, + common.HexToHash("0x2bead9f3f27abb749aaa1ed0b984103220e21c9c8d0ada2e14f181dc8c771c95"): true, + common.HexToHash("0x24be211f50a74c8683f93bedd315bcd4736e893e088cc216ec30058a3f277230"): true, + common.HexToHash("0xec3dc1d4c92eb3d2b824429f3d191a918176ccd1457da7d14752242a0e752b15"): true, + common.HexToHash("0xbc10f9104a2dd62dfd88db8d74fa57e950d57c06df8cd5ef217494e0752a00b4"): true, + common.HexToHash("0x1fb73198e02ba1e06ed26e3297d05fa909cf115bbb52f6da598f10f255b8b2f0"): true, + common.HexToHash("0x1e5cdbc2af684dd0f6694ed74fbf18de65309d5361f128033b545411485363b9"): true, + common.HexToHash("0x5c53353e040683ab005ad15522d8fe7943e4efaf788596e995d7dffdb877825d"): true, + common.HexToHash("0x53221163f185e71f15848570ef5350ed50e4becbfff27e7110586e0a1a02e4ce"): true, + common.HexToHash("0x1008b8c75475404187cc162200a910d85049a43166ccedb860434cb10fc0b814"): true, + common.HexToHash("0x080ad06d1996cbdcfdc8e43fed036d46258bc0862471e8a1377c11a36d644792"): true, + common.HexToHash("0xd5ae52f7349ef9023e84324c9fb23b29043ec5447c8e24e5ec4a3f0dad57c5ef"): true, + common.HexToHash("0x86cc72de8d5c5c60af1901a8a7ceb339b9e0353e75f17434809c24d29fd30509"): true, + common.HexToHash("0xfb3ca6ff7be7c2068f3630d6bd0329783f7951db18107ad1fa2cda8ca49d0276"): true, + common.HexToHash("0x34863303066e6a6df19165a8076a9e9d3a3ea6163f86f13f7337ea13c43dcc9b"): true, + common.HexToHash("0x43d00552f0116be181e153835f3306e311d95680f8cdb8ffd1e9b41981f462dd"): true, + common.HexToHash("0xa473c074060bc7114c6a6f479547d779547145c4fe3b6d31ed65f71d53f47238"): true, + common.HexToHash("0x70c1a4065918704e30115fad7c43f4b6b7aee2e41febc8152e3799d24480d2e1"): true, + common.HexToHash("0x2edd80b314b61cd06814f534ebdd0f8633861b104502ee73946482ead3e80574"): true, + common.HexToHash("0xdcd8ffe8e533b38528bd6a0febc9a4a8878f4184382028d6507005ea9613ba64"): true, + common.HexToHash("0x9feafc92bcaa8d0a0f9ff9395726776ea912bc57e83810ed34c9b35994c2881d"): true, + common.HexToHash("0x1d16a1b18b6d68315f022c50fbb206abce1a06c1e6fd1a9f4f9fa49680609b6c"): true, + common.HexToHash("0x9afaa88c059b1cbc95c7e8b42417fdb0584866ac6290d3b201aeb7d1cc5966d0"): true, + common.HexToHash("0xb52a7b732dd35fa837f00278b9f1e3218e394d8bc14c62da88eae28bac84cf77"): true, + common.HexToHash("0xb339140c46c118700c8d46f4010d4c08f1882d0a2e3d6a4993722aa283416a97"): true, + common.HexToHash("0x0a98e56e15f2ce7437a0f32a12e62b34b10f84966e341f86cee40356faca3399"): true, + common.HexToHash("0xf40e383ecaf820293f8432cafd72892d667c1f016640cbfca8e7ffad350da246"): true, + common.HexToHash("0xc2d70fe9f4addee9f819a7b8dd49f5f9fc09ccf7c58921ed4ee75196e8770740"): true, + common.HexToHash("0x51ab40e122dda58ef38a0e8a1a449bf5551eee848c6318863ab24adfa2772235"): true, + common.HexToHash("0x2829cfb8cb17ebfa244c8731857f48e2242786e18ea5475dec9bb9bc6f19223f"): true, + common.HexToHash("0xc7e8d30d19cd83d45ad269011850d5e97ac73d33276a0d059b313579767e81c4"): true, + common.HexToHash("0x576b6293d1e3c40fbfb6e7a37785f787fdeeb61146ef1f5aaec096807813a92f"): true, + common.HexToHash("0x05eb568780347a0cc4daf71ecec6dc4b6706aa22dfc6fe17eb9076a8f08437b9"): true, + common.HexToHash("0x2dd1968cd64022b77d59115cd93fd4a9349f31a2435d5d165bf0e97abecc0ef6"): true, + common.HexToHash("0x7f21cd30c7ed44c82cae7ef0ba5872808b7d4dab9e6b46011680730fe62131a0"): true, + common.HexToHash("0x9629370dcc4f095b0b8398fa4bf68f42a2bcd74c10485eef93b6bf09c2c2d1f9"): true, + common.HexToHash("0x7f988bb1baad35e1b4a75bad72bea5e94a83c9afc2c09aa44ce3c34b1f624e3f"): true, + common.HexToHash("0xdd3f67be3a876e3c5b1526473b51d3585f1e941832c6e6c7dcab9340943899dd"): true, + common.HexToHash("0x81b51ad53e226cc14682effe2b97b2733f90c45c92b73a633667ef2e44ce3108"): true, + common.HexToHash("0x82ef29fcd79c9187bd0c352d682dbbb9e4b226a5a43ee59f15cca78e667ee18a"): true, + common.HexToHash("0x5ca59d302321e31afcf096de58503d465944e6c18445e9f527f78b25a66e1572"): true, + common.HexToHash("0xf95a7f55190342b79b476a2377829d3a9b50f69d0029546d5060051f678872fa"): true, + common.HexToHash("0xb276291ebf89d6b3048ce8b9f34f845fbacb16b703282ad392e8adf602fc0938"): true, + common.HexToHash("0x76305d968a17b81974259ecfe1448217cc2c98d922ace4e44120abadf2a11850"): true, + common.HexToHash("0x8072021e631401f9cbb8bc0f928ad78947d1100f5ef09298415c138c912bda9c"): true, + common.HexToHash("0xed560daae262b8912b3e0b5a5a38a0ec45a501c5398cc33fec1f6907dfb81c35"): true, + common.HexToHash("0x2719d79337df02e8459d2f6f6325708090bf35c1409fec9ed8d2facf2a782ac6"): true, + common.HexToHash("0x69faa464d1953b70b8dced245f15763ef197cfa22f9f1ec68778086b02460cbb"): true, + common.HexToHash("0x7cb714d5de884c2035ec7c97ebae58093f1af34f5f293961fa9f8115b39651d1"): true, + common.HexToHash("0xf876e4dd198ede37d00bc14ff5a8ac905f3e31db1f7a9ec1e2808b72b7fd6126"): true, + common.HexToHash("0x893c89dbe2bfbddcd4f024356bf31c69ff34cf18de1d5201bca5539fb539fe93"): true, + common.HexToHash("0x3c26adc38ec73279558ae1b4f07b4ac1c0d96e4ffbf9e53cda4bbdbf61623965"): true, + common.HexToHash("0xa9056081eabbff6336e71c93c99e708e98fd5329fd3cf04da06785ef2f5f8cb8"): true, + common.HexToHash("0x2389a94b41c86d4767768d54be95fe03a28cc4ef8f55508cfe905ba203653b7c"): true, + common.HexToHash("0x8b9f24aeae961abc8800976b0e98d81cd535c7b1896f6710bccf696f95cf2bfa"): true, + common.HexToHash("0x0efef021d4057cb3853cd269d2a03307398242f3278db8429d19cf5cf05de487"): true, + common.HexToHash("0xcce47bad5cafe9ba477c68377bce5aa8d3f5e505595a616f9eecec88816e7190"): true, + common.HexToHash("0x0791b91715b674ac779e5fc054a72f666ca486503f324c664230fd5d77506817"): true, + common.HexToHash("0xfef2d9fded1af31643d2d6ea5f67ea424d9eca1d4e34c32a47463466b8a4ded4"): true, + common.HexToHash("0x5fd3662dbf147e2f1399c47e6fd73657a522e2bf37c1cfcde8f319a9db8d639c"): true, + common.HexToHash("0xe444b15963dd51d10cfdd0f2295a68752d5f0a3642d1ab7782d556910cb484be"): true, + common.HexToHash("0xcc4044e6942615a6f4ecbb045755bae1d6552628f88d3c5dde9215f5a6835b0c"): true, + common.HexToHash("0xadfa1cdde12a58ca137698103014035f04f25e7d12ace773e21b640e31f63055"): true, + common.HexToHash("0x94b467e96c5f490454c62e6afead6e7334f927ba0601253c7ea5444c7d623668"): true, + common.HexToHash("0xf548e0fbe7f73d96c64e83bae44dd79806232b7ac33ab2863b96252ae10027fd"): true, + common.HexToHash("0x2387eec3784e151ee4561b6e760f88fa67ae86e53ae6892cba8781d63a83971d"): true, + common.HexToHash("0x8e17803f7402c87eb2ea7277c57256950784479202a6bcf9b6cee2b53794bc1f"): true, + common.HexToHash("0x1ea7182268a11015873ee378abcf3aa08dda9611013cbd55396bf85da9831156"): true, + common.HexToHash("0xca598137f4c1a0fe9f0ee4e7d6d1b72ee499343300cea1b64daae0935ffff765"): true, + common.HexToHash("0xf7a0aed8f2be52e88732404b83a86716a0ecc770f8a475ca666663467a61d41d"): true, + common.HexToHash("0xfa61180a07edda2f32f392ad8f7c10ada2af07688bbf596da522a9ca4637c1b3"): true, + common.HexToHash("0x9c318367bed85d2c1594d8ba37c4a9ffed2e763d5a4cee5f1f79a2bb775c7e36"): true, + common.HexToHash("0x9bf6f4ced6af5fed5d54ffa641e5807647689e4cc593629601e22b03dd1fcc76"): true, + common.HexToHash("0x8d5cacd117a4885b90cc73fe78613dae7d36f7534776369efe78be02b9ea7217"): true, + common.HexToHash("0x7b9a448a3a39aa75ffe10b3a568bdd222e3d585a98400b04a8e51cf870e2f138"): true, + common.HexToHash("0xe016f7dfd1dbca81e8cce2759fda21c8a08c6dcc8a0814f01a2935b9e6953bbd"): true, + common.HexToHash("0x252ee599231139ef8b329cc612aa8b09d4dab97b1b5fd028407b11d6d68efb2b"): true, + common.HexToHash("0x886c98e51e893be91f6757257b19a600c8fb827d9b31e41d5dc070a115af896e"): true, + common.HexToHash("0x5513d81852e7361e350c8b8508eafbcb5728bf8be89bbe2b82e8cdb68cf0f772"): true, + common.HexToHash("0xff5cd97eec57c87caeba403cf8594d6eaeb4ce974df5c741b63b67108bca6ef4"): true, + common.HexToHash("0x256e5e58e78f9dec17283ef22685674c8114c4102428331cf7f4d9ebede8a41e"): true, + common.HexToHash("0x70704a8b557dbffde8ae65f75f4e02f718fa07b7007d4c09fad3e7140fd0f3dd"): true, + common.HexToHash("0xb2de811709a1258effdd3a650d3b6138039e76a180da476228ca90ba8b78f489"): true, + common.HexToHash("0x8dc95c439ca82d6e8d4a807749bb18772a924a1164a35e4a1f8a4f936b0e73b1"): true, + common.HexToHash("0xc35b7660bed159d331506c05356065cd9a205f21eb1facb1e9556e702782b24c"): true, + common.HexToHash("0x98cf82fbadb59e2de558ca6c0b4f1b559924a0364ddd0f3d54e75d01b336eab3"): true, + common.HexToHash("0x1c3abc9d56b324e429624a3f009dfafb2f4de00baebd827ed85bef7d7467e33a"): true, + common.HexToHash("0x81a02d69cc9a54f6115b293440289e3a72feea177cc47fc1adaa3350b3dc59c4"): true, + common.HexToHash("0x7759ede496bd23e518d636c65ebea13a032ed9ff3a7c510bffccc9316cd35fc3"): true, + common.HexToHash("0x8fb2c682b349133761f1c680a6404263ffee97d32e67465c613ccaec9645b565"): true, + common.HexToHash("0x6f64287eafbe616991edf1a458f5c422119621b4da1cd2fa4ec2cfbe891053fa"): true, + common.HexToHash("0xbe8b0d6790fd461a68748e7e13a3380d611fd7d4c8b15594c7422eedf25b8ca2"): true, + common.HexToHash("0x7e379a9b2da42f1be6ef1ec437b0d54e114ba833cfbfb7818e065173880e0dcc"): true, + common.HexToHash("0x5a4f3eda846bc75f3776c918a5df7d84424a4335a9c5f147247b9a4902123fc5"): true, + common.HexToHash("0x9a8ab653a10122f1bc81b0b952e9a0900f63c8529e38278c744daa5362eb468f"): true, + common.HexToHash("0xd3dc7b311906b021cd09f5ba2845a3dacb01dddf63ab8a88e7db68b1dd1e562e"): true, + common.HexToHash("0xeac67c9553baf5afe70058c05954a6f14be3f31b4591a35269656c50ac9596ec"): true, + common.HexToHash("0x548fbc513552beece17ac291b0428ad3d164cc5200c44cd710e70efddb48795f"): true, + common.HexToHash("0x4ed65bc08f875bac0b1e631e7197413df9fa2d9ca1ff4ce486932c6892d9d8d5"): true, + common.HexToHash("0xdfa4304bda3c8f23e1f8180a814d1565624f818234ec7f7ab8aaa830ecd93af4"): true, + common.HexToHash("0xff4365765e86f45f4d18225c78a2ab661c2bf7cc7ff4b88f04b6e72d95c6a4cd"): true, + common.HexToHash("0x47bdc261bcaf10374e01c7df683121c1f685e5c87ac31ef4249ffe19820ca2ee"): true, + common.HexToHash("0x3ade8c4fff811d8a9e80f29632578df670709bf087c72e98fe626d24ec6575ef"): true, + common.HexToHash("0x389d84e85312e7151c405038365434914251f2a706b954cb16bd38842703d8b0"): true, + common.HexToHash("0x43ffa27a80ba3142b40a38eff636812aadf5bd7c599b3e23f4225c7e6ba02608"): true, + common.HexToHash("0xadedae2d950f9f25c0fe026907a33fe7d2f0c557bcfbc9ba5a146e3b8b9b131d"): true, + common.HexToHash("0xbf08affa34f2479ee15ae343f192ab57ff57f538b22166edfbd2c973943567cf"): true, + common.HexToHash("0xc06337409ac0b1a6caa149ba2ba470e8b2d773730584b809cfb1a33ef3810f1d"): true, + common.HexToHash("0xd23f5996bff4833c240a583e940c74b0db1e9cee7902f760e9de27b46d3dc8dd"): true, + common.HexToHash("0x829b13d65658b1e1ebc0bee404c4b1bf042c2d0b434b5c58b7986a1a16887bac"): true, + common.HexToHash("0x7f3dbb55b3f8409f99419d961bd53bb575184a7325705e4700507fc3f50f8767"): true, + common.HexToHash("0x6dff8d635ecf031b0666be861512926c8fae52ba4d1b044b2c9733d21e5f2bff"): true, + common.HexToHash("0x563b70fb3cb0c9d91358b9524b8eee47550a269659d3b874f403c288cae645d7"): true, + common.HexToHash("0x89bcf824a83b3b05f5e4a287e27f959a7e86a9439318ca9a87c1db106a65ef36"): true, + common.HexToHash("0x458f0bc30ce2855eb32e5e2a7bc2dca341be0c29dbc08c9b51ea546c53c0124f"): true, + common.HexToHash("0x53f62954d22b92c84531cccbd70f9ef8d6c2721c0ed81b05dab2e4f0f3bb2b91"): true, + common.HexToHash("0x3fed4885ce508f1bf6ff4cd7635e9151248bc667eaf5c3b9cfffdca5b3fdb767"): true, + common.HexToHash("0x6278b953708519e383f8a01eb37fc145fe29921e13121140cb3f838937236b55"): true, + common.HexToHash("0xd64e4c06f0fb72f749dc9fb3c6c3c5b926334841b6cf7e36164256c8191abe8d"): true, + common.HexToHash("0x371f1ef81eb9940bb1061f3515152a4ae14a69ab2d72f34b59071b66d96b991b"): true, + common.HexToHash("0xc06a61d61d6fbfb7109b64bbc82a3c1b8eeea515ba2718c5e8a3a5f1ab2bd5ba"): true, + common.HexToHash("0x80fc0207c1a9758afcc9b9df9cc5610a0d40e7c9ae1328becfa86ca21002baf2"): true, + common.HexToHash("0x04c35da3dcfdad401f40b2152b66e0bcfa26f566cebee663e788fb1074c914bd"): true, + common.HexToHash("0x5d67dfe5786b7fc87d59a4493d9b53d563a1420916d0b5e5a2bb4abc73270f4c"): true, + common.HexToHash("0x821d0e9cb0ab8ad3a649ac775c00214a61b210a568b76861b9bf478f5acd3dc0"): true, + common.HexToHash("0xe4c93ce741a4de0aedc64a3f08502653712d4ca6d6eb10f0731014e031c7cece"): true, + common.HexToHash("0x8da42ed11e8549ec9ce422cfdfa1e4c9d612640d8405e79ed034765fcbeaf3ae"): true, + common.HexToHash("0xea98925760b43d0452d87e6277e4b679351af44eec70950a02b3ebf99a7b2bee"): true, + common.HexToHash("0x9c68a0960b79492403eb4b3face3db0e1f13cb665d0b7df483c126ba837aa275"): true, + common.HexToHash("0xccba8479b51b3ae40f03f761c1479a6aadf244630cc6c3f35c5fba7380923281"): true, + common.HexToHash("0x883d3ec23f9b616e7b395124ed204735174fde6d0913507903f3b77f67207504"): true, + common.HexToHash("0x11d2223694074ceaf6874c22dee762b6cffdadbe5065b0eab6f0175a9fefb2c6"): true, + common.HexToHash("0x64f56f423a0e68a32c36d821b672ce7231641999d42267ae4ea5fc3e5db3a6ce"): true, + common.HexToHash("0xe7fdc045b2808e6854780d9c82f60b0e24a9d7464f9912ef10aa5ca5a27ba2c1"): true, + common.HexToHash("0xa3af8082cd877113c6a7ba46af4061273d47ebb54f23fec1de861107889e1777"): true, + common.HexToHash("0xc2eb0d41e1c4628a8c3b196022804ebfc3cc3948c9282ad7dec627e9a42e116f"): true, + common.HexToHash("0xfe4805b4d11aba6e1ba999882381e8b2991793faf815a0a15a45c174d89f7005"): true, + common.HexToHash("0x567d8800367ba43d3f275b794f7895a9e5b522d99e101cf1d3580ffbafdd7cd1"): true, + common.HexToHash("0x1c49bba7b481f7345f3fc3be2adef5c2343a8103cbe8b02b0081f70629fbe0f6"): true, + common.HexToHash("0xb41ce213d48cec526953fe0ec0900df16baa897a72da9c3c32a74cc9f75f9f51"): true, + common.HexToHash("0x5c0b24fa526122e54187e2a744f9d3a1c176f2d3cd41266787532fe5f34f1c74"): true, + common.HexToHash("0x0c6f4366b3f76109d9ce97e4e9e41320bcfcd85bc3af4b1688d9ffd405e2536a"): true, + common.HexToHash("0xfecdb44e454f85f1cac60a628df0fcd60f3fe84054f506d2cf88547c0b32ddb2"): true, + common.HexToHash("0x23aab9544b88027f3028b1313b0e3c03099a04b7305ada99ca5d44e88896a913"): true, + common.HexToHash("0xc23c2257defd7599030e9252ec2d9e16697620a72ffd65a2f68af7c9b13a9a39"): true, + common.HexToHash("0x902be7918bcbb525ad2af33977cadbbfc055fdd8ef9fb6749b86a6d261adc6e1"): true, + common.HexToHash("0x6c175882ad403fcbf197e738a4115ac0e388c485254d3da005dde344d7562acc"): true, + common.HexToHash("0x5f5806b0f6ac52aea6699ed70660d52410480b99767acadd85eb055d0294f8af"): true, + common.HexToHash("0x9139ca94f157ab6cd496d4051e11940b953a49d48262c61dd0610931f2ce60a1"): true, + common.HexToHash("0xcebe7c386fcdda66528e2c9ef7aae2e457285631bd31b5ca490d3f29306925fe"): true, + common.HexToHash("0xc7e6dae6b76b6a24e11e4545d1a3a23e848d253ac01987079a9b95522771b97e"): true, + common.HexToHash("0x44cedb44be6519b93fb62473563bc25a79941dee1e2257564b85160afe1342bf"): true, + common.HexToHash("0xff432a3bbdf926152d69b02dcb38b82925260b65d56a8cd4ee8e513686aeb92e"): true, + common.HexToHash("0xe6c09978e2ba453ff36571a43c6a6fab7ac7b31973767cf6b23348f00a1ae397"): true, + common.HexToHash("0xcd98b0007b8ef8fdea869ef8af172d52d4ab158f58c9404ca5658fa64fd31bbb"): true, + common.HexToHash("0x3a79fc173ef8759f5bc661cf0a5ce9ae574c83df7c19d83ba85acd95eee71e62"): true, + common.HexToHash("0xc64d6c8ff49277b0bc51f47e1956a2f84648eba3a17be9752247e5d53a5104ec"): true, + common.HexToHash("0x4fdb3dd87a4114bf25995b18be5587539579631413c8e04cc534d76abf840f9b"): true, + common.HexToHash("0x57ae8fc63525c4fcf2f2bfd3ba44aa66539ab9265c688717f23e0edddd29f1a4"): true, + common.HexToHash("0x4f5f9fb5fb49d4f6246eba74cc96cf715688922c9984882e57f139d9fde2b905"): true, + common.HexToHash("0xa3524c4e671860d068852375326b55c63436cf647fd5b07245ff3c4b74d41186"): true, + common.HexToHash("0x96b5c86a59765fcfebd47e34cdd9c6528bcc5c6865393b2f55b3c18a0b3e0bf2"): true, + common.HexToHash("0x6b8021f82f8eb0114beed25b5a79282e019c9bd59e01ef3dcdea0416fd92a493"): true, + common.HexToHash("0x9d9b79467b9b5c97b296d17f46cce788aeefced7be841258f360109694d54b23"): true, + common.HexToHash("0x399505f74e2794ede4971bc158f28717ea5562da01862aed983f60b15575e6ea"): true, + common.HexToHash("0x6affc03a216b904fedefda4531f9c5a64a91d41fe0d58cfd25b547cc6b6da40a"): true, + common.HexToHash("0x70d0e06db9ebc5685770d3a9648d60fa932a98fb8b22e1aa28349ef5c63b2962"): true, + common.HexToHash("0xced0976ee727e0ec6394af04a5a0a5fec476ab1c2898c378edd25a57b8c62c92"): true, + common.HexToHash("0x701e49f99b0862252b0c6c51e7c42db5a389a50fb6eb65f522ec5b726a065f3f"): true, + common.HexToHash("0xb592a5c3708c6204334c9db107f9c971c8b4e2a5e1bcebd48f6360f9cb876872"): true, + common.HexToHash("0xf00802b16f0acddf64c122d8f480a9b48ef0babf6a262a0df0bb3ee019db4398"): true, + common.HexToHash("0x9b622153c0e2b8d5a2384cebefe331d7d7fc98cb14e06cd2e3abcfdf7ae41a79"): true, + common.HexToHash("0x1fd891d0f9256e18810d08822bfddfb4e3db40a585869da156226562625c1bf4"): true, + common.HexToHash("0xa33880ddbeda9ab42b9ceb471c13eccce4bb295cf742a9360c466da93db94d99"): true, + common.HexToHash("0xfac59a22457717e47d951413070de16abb5bdb98bad7d17c4aa8e12a2b2077de"): true, + common.HexToHash("0xb25a34aec02232cf53be637126db80d83672a1c092fe62790b447b62ae6fc0ac"): true, + common.HexToHash("0x18a431b22e5565036f0c5e0153755419c96f217fc1e18102f0fb1d19779ea919"): true, + common.HexToHash("0x2edbd4237829c50763d680f68e63113e5e7e24f00d803aa14ecb1f80e6e4bd85"): true, + common.HexToHash("0x0cebaa7f2c6f17a42527e7b174ae5a5f1f34b09724b2a6b17c538317ff1ad716"): true, + common.HexToHash("0x0cbc716c14247eccaeb204c00ec20af375aab8747397eaabe92fcde952978c3d"): true, + common.HexToHash("0x30635fd80ee9db3c1096ec53e89dad304ed37f5f22cc31a37fa992a26e780a47"): true, + common.HexToHash("0xe5cbfce5d6b610270a81cc8bf0ab330b6f5dca0c727f6a5f58f661bb2889ca42"): true, + common.HexToHash("0xfd5404cdcf51e073b525c0904e4312572ab049508ca28bcedb77ca2b06981d1b"): true, + common.HexToHash("0xabcad4dd968d0258c8bdc1acc3dbb6af26f826b2f8c82e7dcd74a1aef09c50c5"): true, + common.HexToHash("0x64d7a7e0819b54074b4fb9b59b58c65aaf74f7ba31d590f605d4c5ace365883f"): true, + common.HexToHash("0xf3368178443de05881d550d5f4488bb568f615d982491d76494300682d670aca"): true, + common.HexToHash("0x00ed0e2abdc2da9163fe133a8307c954143ea7d164dd6ecc638935e6e506f4e8"): true, + common.HexToHash("0xe814515cc3b49533877c230a259fc9bfeb7e16a6fb5d38a6e66a22076c5fcf5c"): true, + common.HexToHash("0x29d9e9ac9e4e9893e496ac105ae6cc1ceb792cdf28b1802b952ecd907943269c"): true, + common.HexToHash("0x64eed66f74a9a483e81874f1ae1f818f3735553737934d09ad52c88b80bfd4ec"): true, + common.HexToHash("0x2367e6b628ec2012d459c6b84a7f3ea6e2dd4183f48c9c5a15226755f7e06532"): true, + common.HexToHash("0xe98df49e79bf3a70e564dddb7c0cdfd429357a45af062ec204d6c94f6ef631c8"): true, + common.HexToHash("0x9137906a705f3462a8b799bdaff8e649e8c0733e5c2ee5f46e90387bdd6d0554"): true, + common.HexToHash("0x53ee4bb385c0414455b99a766195503a76fa1d6af7522c65415a38d5a39c32e4"): true, + common.HexToHash("0x37ab9f581c762410b9868ec26fad1a7a84ccb74889394cb7d6a89daf318f15a4"): true, + common.HexToHash("0xb93d137d14523d626c4d61ba16fd7f0d21f9b580af83d158dcb07382f0503e53"): true, + common.HexToHash("0x8895c28cfd2dae8ca02fe14e0f376d7230fa948b8f859a67c5bfa1feaa8e7367"): true, + common.HexToHash("0xd919dfe6867d0ededf7fe3fe18afd2cdd48d8811d013e456a140caabc411fde8"): true, + common.HexToHash("0xf9b2520329cd1f8d6ce9cdff3b6acfbb43da7995a9641d61455a64c4f837b08f"): true, + common.HexToHash("0xe39a7585e76889a351539770861c4c7a695a9a392e6e1b4bfca3fa51f512b952"): true, + common.HexToHash("0xb9f5b67f63edc9b5ceaa4dc097d9a06100e9d397d918bcc8b52dc971bf2dcffc"): true, + common.HexToHash("0x6bb1bf89c554f3d51e66c1ae7bc9e0d481e43fe26f89fcf7d6353e109a3ce27a"): true, + common.HexToHash("0x4389a6eec9df1ea1effbd6d6de82c4b71281c2bee537933236210322b108e269"): true, + common.HexToHash("0x1283d5d06b50fe56ce587bdd4e13e5799b881f41aae2256e4e0ee8b1b7567843"): true, + common.HexToHash("0x5e5af92b04cbcc6e800b5c5e9062efd437e66245002b116f2ed8c09c8e95893a"): true, + common.HexToHash("0xa3e59af9ca7d84cd56e1bf7f05ad8be654782010bc747b3836400aef0dfeb157"): true, + common.HexToHash("0x472d5b66c638f1799f3b86e593d9fe8faec71249f68057c93b55635d2cbca8fc"): true, + common.HexToHash("0x72b01a481bd18a3ddd03f72ac2d50c03a53786815193b00999abd790c7f6236b"): true, + common.HexToHash("0xb4105e626b70365f8d16988e0a8ce00ab22f70112f3c3d1be2677bcab8974241"): true, + common.HexToHash("0x0641bbfc5704218b2a0f8a61405699d2d4cdb244dd49e8fef17febe7fd2275ba"): true, + common.HexToHash("0x5bf8f7657753eaac0cda1f44e9aacfd9a6d7b794977aed031b4c4be55720f706"): true, + common.HexToHash("0x26ddf60d6d84da4c064e173b64b9e7cbad1d27b5d096fe2563651a5eac2f2894"): true, + common.HexToHash("0xc111300d196947f3bf99ff4fd1c1fc367b8a887ea94112b2b70442128d432224"): true, + common.HexToHash("0xea9421903fd82665695f9c987a4e73caba1234ffe90aeabb5aeb954b6d8ba726"): true, + common.HexToHash("0xb034483479122d0d98eda0d672933c8c7d77553da90d6c444f74a1e03248f55a"): true, + common.HexToHash("0xdc421a044c2744aeddda04be82bd8eac6e8da1436359cb95b1d4f21e8c154059"): true, + common.HexToHash("0xbe7f40220164ae46139ac5ea197f1fc0f130ef937dc4d89fcf20469b8842a1b3"): true, + common.HexToHash("0x2ff0f750965ad53ea27f0da56c1480aa7ec6b523fb5ab6bb8d7c4117af362db2"): true, + common.HexToHash("0x14989823eda844bb39576b3ba23178c8e2ba7e74b839a1846c2e8b441423d71c"): true, + common.HexToHash("0x1afe13f3ed80998d3e1e82897bf8a7252f19cb826035a59c74ffd18dc6f95ac1"): true, + common.HexToHash("0xd832ecab185a28ab22b13e9056ae7fbed7973a666b24865aef008f21eb4cc7bb"): true, + common.HexToHash("0xc2a40aa2699acd4749e45b3cc203cc75168b848453ba47b311cfebf21c797bc2"): true, + common.HexToHash("0x1f4557b98bbd09026b730672364ff26af0f56bacd5fb5958ec4fef6d9b719521"): true, + common.HexToHash("0xa06d5238c06814b9ae9ef02b81e604c611947459c89205b48cdd94bb398655cc"): true, + common.HexToHash("0x1e3db54ca5f04c42219ecf774050f2f4d3386da45548e405bf2d8d766ac0e77b"): true, + common.HexToHash("0x7d3fa9da53c8cea885b646c0f5c98713643e29361821ce15bb07b27bd17f2bfd"): true, + common.HexToHash("0xc06b2f1ca0e728603cd84e7eaf5cd2e5474fbb1b571d1c93d5dd3f8c9347b500"): true, + common.HexToHash("0xe343bccd5d3412d24b9c415607bd3ce30f6176ef9ec129fac3953f0fcbb76a87"): true, + common.HexToHash("0x6c40421587e5564da7bd2aa9fc68087f3b15aeb274300a74f3245ded29752a4a"): true, + common.HexToHash("0xdd2e5abe2175ca5d8ca364eabeca31a9efa91a69e691becd58615344ca871dbf"): true, + common.HexToHash("0xe6518a37b5ebdf362327a79a1002e2dce62c50061e6ecda1d92fff1f2987cc41"): true, + common.HexToHash("0xbf559f2d918520bc955695e9cf29a16ee5e13ea8c6bd7c0b5678f5d9521418f1"): true, + common.HexToHash("0x0aa9e9239307dfcbe06196d8a3d47c062664b175754e86029c0e6b7522d7f755"): true, + common.HexToHash("0x2a17d489bded117b25e0d78a59ac3afe0808cb3eea7399cd687cdabb528a42eb"): true, + common.HexToHash("0x7c6e1518a0cab2caddef092bfa2dacb2ac0786bf171d2fa392c004e57e9ca8ff"): true, + common.HexToHash("0xeb889095b4c9e0bb34179839b974dfcddaea2ef7d5171022a2f47e4b3f97fd8a"): true, + common.HexToHash("0x62c60b279e47e062fe33f72870dfb3f909847b61261fb3376d1381432ccefbf5"): true, + common.HexToHash("0xfca3624a1138d1cae836ac7931cc884c37b844685e09aa259537a09c75b691b9"): true, + common.HexToHash("0xf6f270702595df748ee3c97233ac8635f69645f05112428b6622b68b1fe91f84"): true, + common.HexToHash("0xf8a63f592143d60056086d67b4774d34c25647aaf3e268f8a5f25ff0cbb6a000"): true, + common.HexToHash("0xd34e181d7a93238a031a46b2ab1e0f7060b75f39a2334a5d930fa7b63ab95ded"): true, + common.HexToHash("0xff35921073d9c8da37d85da1312179017dc61d314bf05fa7b02f0ad4a5f80b92"): true, + common.HexToHash("0x795790cfe150f5d2a4b4cc43657d604162b732432f9a1ce89b032ddc1fa3d118"): true, + common.HexToHash("0xd1d75317c8ee6a0d298c339db3fabf0444dc8b196ec8e3e4bae0e95dd2d16694"): true, + common.HexToHash("0x9f2955fb9a5003d2e580ade92ada4e28e424a612bc5053f97f233b1dd88fbc04"): true, + common.HexToHash("0xe46a98127430d22e3c34a8c0155bb18b264c58af8a345acb1b9b914a1eb3d4f5"): true, + common.HexToHash("0x202e0f17d0fd110f64f9414b600356ce575b8b75d76f0fa1c185c06c8c1f72aa"): true, + common.HexToHash("0x51d51fd17f84670edd1e0f82fda9559b98af0b9ba99b88f86e1436a8a668851d"): true, + common.HexToHash("0x8c48ce4e37a9746f3798210ecfcafd3aa4cebbaf887bcbef2aebabbd92b6d3e3"): true, + common.HexToHash("0xc66c391924648386e42ea114f8ff6f5acb526868d8c6e69adb220c271223027d"): true, + common.HexToHash("0xbf7e94ddc6dbeea5529f323c85fff8739ce42f70a83d8727955c46fad566f00d"): true, + common.HexToHash("0x70d6cdb3804273ea4161e14676546434566b14803a6eeb86cc7c3969618018b1"): true, + common.HexToHash("0x2dc9ff6ab1ed0670dfa9838dd0e628c3de485a2ea00edff8b69444a71e9d6e4e"): true, + common.HexToHash("0x2448e20f5bb6ebb2a04f848fb64dd53476f426b0d91de52139e061f6e2b84f67"): true, + common.HexToHash("0xc6cf325e485e98ddefedd11cd1a199b4df8a1680fcfe17d9ee0550ad9d600814"): true, + common.HexToHash("0x476926e25640f3a1add491f3d56b9f691eece0fe4219186b75c1afa47d2abd0d"): true, + common.HexToHash("0x0acc36f8de492c924f132b9edacf4479585ae0fb30c368d539e3c43d71a9db17"): true, + common.HexToHash("0x2e1c4b127f46e50a195f73a65b3d27dafbac744e99bd359ebb2c826050f387dc"): true, + common.HexToHash("0x84f9a887784a95c79d01e17f184e8c386d827302c7c15537c37f33d9eb9913c4"): true, + common.HexToHash("0x8b1af8312bc75c7f30d34ffd47e55d9d5f5f62c7a9e33246d8d379d85c2076ec"): true, + common.HexToHash("0x06baddd0e6656942ec7c5cf4a478b840709c262e45918548dd9ebca0c31ec6cd"): true, + common.HexToHash("0xa3beb67bad66e2110837d9ec913e02b086a502c7bc7f90e8a1932854ef4810a8"): true, + common.HexToHash("0x9197fa05cb87fb4faf333003a098f1371bf7606df672ee43f8a4b8b5752282ad"): true, + common.HexToHash("0x3d6abe856e1bc15ee3d69a51e2149e5e7a51fce8e2ec08b164e47983f7800aa4"): true, + common.HexToHash("0x9bd6b29149ebe0399e66bcf27d1978168a1cf401b9f4baba1ae4cacae9931a2b"): true, + common.HexToHash("0x218fd4a2b66a3c23b9935b32a084f9e5f596055a953cdd9521dd157842329b8e"): true, + common.HexToHash("0x2d51bd136ac52459bceaf1c045aef5532f81573435882d9065825838c375e347"): true, + common.HexToHash("0x6bca106e57ff178e3f62e15229455377ac912dd3ec034d0850aa6bd340c2ead9"): true, + common.HexToHash("0xb77edbfc5452d90fde01a354c1664eb216fdf933bcb1521ec9dec390d1fa2b28"): true, + common.HexToHash("0x57186e969e91071d6a2574d217f3b631b2409254db319f029a8f193d955797e1"): true, + common.HexToHash("0xbb5ba68eaef3df75b2d21d188109326442ab38453ec7b3bfd1367ae03b64cf8b"): true, + common.HexToHash("0x9648e061ec9493af091478e41ce90baae2da137b8fd259dc902154952e52c29c"): true, + common.HexToHash("0x3dde8ab78fdebb58eaf98be11c6c894fc7d5abd291fe454fbc6cd16bd7c541d1"): true, + common.HexToHash("0xab1faa3ecd1831cf672a166ac5d13d51293c3c9a0c804bc618b830da82a67ec3"): true, + common.HexToHash("0x38a569291c50077816e8d4fba7279d5e4e239041eb2113093f50a08606ae7831"): true, + common.HexToHash("0x3799483d03a64b5a3259cb788df516a90208fb5c39d79acc2484cece11f1c2ae"): true, + common.HexToHash("0x1039db07664cbbe274462cb9a432a107a18f870abcf6f2f1adf0e043e26d0eb8"): true, + common.HexToHash("0xbd28948f10d1dee320c899fb64d21d96bc418b226d7d6af82491deab6465e35b"): true, + common.HexToHash("0x6deebb671b8a3b0539dd4024e8268dfc4097789a177b7a83cb0b1e68f4fe0612"): true, + common.HexToHash("0xb21ee737fcd9f6d96615b05f576186e0d4f86725b7693050d56bbbe4c42ea394"): true, + common.HexToHash("0xfd540aba32eee627a85b6aa601551923cb4c7f1e02e6bf6f6f5bb36e3ce25c76"): true, + common.HexToHash("0x89a9794b23fcd79c8136f87be772d9647af8ccbb97f8673f2248b34419693114"): true, + common.HexToHash("0x5a9e39072f82b85d039110e998abd4ee331c794269eeeb9b888352e087163ced"): true, + common.HexToHash("0x64e084bb86977033020e59ece1139020862bf68145590baf50b6f2271a47ebf4"): true, + common.HexToHash("0x5665d08b9fbb6df2828fdeeddb7ae59fd42d5ef45da5c550cbe514c7944c084a"): true, + common.HexToHash("0xdd981791a096decb56c6ff5693bc7fb76f98939fba89d27ac26fa15dcffbbf9f"): true, + common.HexToHash("0x86e81cf32a87353e399e156e04f01decfcc30744c89f94a67b8e45178257ee83"): true, + common.HexToHash("0x833f976ecf967791c6a2dede0cdd4c1cc3dc5c46f9f8af69ad6c2a99997d121b"): true, + common.HexToHash("0xef27ff203e331b237b9b3b5d42f63fd84d6b94f382e1020cda0a4136978b527d"): true, + common.HexToHash("0x86a388555115b5fb186765f486e9d1b00089ae8ca472fedd6ad7aad036162494"): true, + common.HexToHash("0x0dc81436d0d3465fe33baf8b866da4a324cfa173cb9b4d61480ec21f19dc411f"): true, + common.HexToHash("0x4ce71d50d9f61e1e78a92555c1fc463e3dc1ae691c17dc31ada230a7c6ebd473"): true, + common.HexToHash("0xeb0ae932a704f3aca44053fc449cf7fade882f7d06605e2b3e8cb730eb1ec6e5"): true, + common.HexToHash("0x7e66c1b7ad8cafae3cfce545ed37e83b0264c842b7d1e24d04f58ab3cd4db22a"): true, + common.HexToHash("0x77e66f78aa11ea2373bc53ac6275706fdad8f751b3b1f043573975127df97bb3"): true, + common.HexToHash("0xc5831fffbe7a50936171242f643994a0c8544ad2977bdc03ac6aa9cc0a06a1bf"): true, + common.HexToHash("0x23aada2e925870931648b26111212b175f50a95646ca205897c10ac33fc02f17"): true, + common.HexToHash("0x032603dff2307df361786204d5999a49291e1780efcd34c7109b3481f32257d7"): true, + common.HexToHash("0xaab18e51e51abb24e24aeb5739a26329e1c161427646c4b9cc105fec5ab55b33"): true, + common.HexToHash("0x31e0e3b539aa3595bb757769805289262cf2bedc1a4aff662452642bf0076e84"): true, + common.HexToHash("0x0c57d0d16717e89ea366469d2c90ae5fcec0b256fead1a25850e37487e86a487"): true, + common.HexToHash("0x01c23d5d1e72e564451f5e88a8250dccc49f463d429a3a9781a98ab74928b229"): true, + common.HexToHash("0x3bb4eb008aef67e233ae0b6fd537fab01cd5bf88425fac6741ea8874d6e1112e"): true, + common.HexToHash("0x071895479e342bda9134d6019eeed71750cb03fa619d157021b72440d667e899"): true, + common.HexToHash("0xc118fd611f1f0b15c3cb1f3bec5099586dbb555ccafed44bbcb6b89be1239ffd"): true, + common.HexToHash("0x174cd8f843ad5d7ec20910ea0c7e97da1739661b7abbb9276fc45402626cd250"): true, + common.HexToHash("0x6522da2062ff56207da56b59e15e6161a428e6c0831d669062ce16481429fe23"): true, + common.HexToHash("0xa6510fe2abfc4835e17d96ed4bab929451307fe19059a6b4de0e5b6d0af76a36"): true, + common.HexToHash("0x087a7f99247a7ea90e5ef376c2d0d7b819c86c3a7f238bf6ea5e832b7edaa795"): true, + common.HexToHash("0xd445c3997a2813e2ce0487acdfdc5eaa05032165bb17a236c36cffd179001454"): true, + common.HexToHash("0xfc49dcf767ee1e8eadb950f19f15160b72e1f7fcaf0cd642bc64226c603e63cb"): true, + common.HexToHash("0xf462b603b0cf629058bbbc24891ae52e8cea0d44b8536835eeeb0ba51af15cc4"): true, + common.HexToHash("0xa334b309a20077068fc6f0cd38a076411cd88b7b9bc90cb9e5ca85127b9c9688"): true, + common.HexToHash("0x672045397e6b58c846847c665eb64aab94881da68bfdcfb5fa5e62a49360e3bd"): true, + common.HexToHash("0x3175190243ba7651b80ea47493bccf3696186fe9ee89cf9c1a54aa88ebcb74c6"): true, + common.HexToHash("0xb4b334913b83d553487f4b56eb8598734c3af051c8935566f02e2820c57acd1f"): true, + common.HexToHash("0xbf3b7bdfef91c9882351a28aa1c7eadcc0e60d6cfc5584cb734d47fa0b12c799"): true, + common.HexToHash("0xbeff4225991c5b40f9b0c098176c712830825cd97acbf10cb581414d9f4aaca2"): true, + common.HexToHash("0xfefb1858318d87c54cd68fbf41d27e84dd2116757a3a93825d54620968bc3a48"): true, + common.HexToHash("0x9bda8b8ce7a09ce8028fcb11e7a17681cb182577701622c0afc28da150cbc6c3"): true, + common.HexToHash("0x1ee39c462ef434dcc5a411808660b99d6506c2d9a4c545b622b88770fada6c41"): true, + common.HexToHash("0x0a51e75a2cf6a711be64f246d918c200c14e3643c1d8b1b75b532a121556d0e2"): true, + common.HexToHash("0xcdc83c565896b36c3c8f9746d2b9433ab0b54e87154261b7319dcec94fac6641"): true, + common.HexToHash("0x17ee8ade804bee3473516bfde6ecb275d0bc2dfa150f992a4a56c5515b469b4a"): true, + common.HexToHash("0xcc42c9d80a62c8e2e6f10489713b8a0e5f0d10ddb8643f62ba46b8b22b9e0e72"): true, + common.HexToHash("0xf9570b100f46ede5c49cf25dda500bd8879fe7e7daeea919c35fb25eab58e7f7"): true, + common.HexToHash("0x693a1e746655326213882b3a384d0f57026a35cc2b4b8357aaacf08de9e0e32b"): true, + common.HexToHash("0x68de82be3b275a59d6d68af2629cfa2648b46dbd9db7e3ffaa48437cba8ff72a"): true, + common.HexToHash("0x31f2151962150f8e42963d894f8618c62608aa981e472e7ad6fe7376bbdada89"): true, + common.HexToHash("0xa509ea710d2f24670ba557859d2e253e65412cdbe289a7533bac7f25880530ea"): true, + common.HexToHash("0x5ba4abebca7430ec18ecd44685942b5e657f82487105f055391d6c127405acf9"): true, + common.HexToHash("0x3068cc93a7ed11c974c785f9103b5c8dd8810b1f331054ddf5dc8e59fee31311"): true, + common.HexToHash("0xf087a8326e434548eb4e561fa2c7c204271664784f87912365150ebf13608da5"): true, + common.HexToHash("0x0be8e256351f68219591aa3a9239b6afb17e3bd12201ce27075cd4db899c36cc"): true, + common.HexToHash("0x248c7a65c28d3286b29accca4cc0d71dde5f6c486a2bd9cf9098596b710c4d1a"): true, + common.HexToHash("0x431fb6fc9da0277f5492ddad2d843b917321c2b9af51f56d8b0bacd633596379"): true, + common.HexToHash("0x5d8a8f475938d7ecc23d9e9c0257d0cde27b2dce7a66482e9167613a9cba4cee"): true, + common.HexToHash("0x5ca03c7ab890f9e12430638ff656ea5b9cb8fef11605ed7b09099520593a8d29"): true, + common.HexToHash("0xc659dc44d5351a6fb97184a5d6b3f4d9c8781dff85a151f1ed8f45ebba832d8f"): true, + common.HexToHash("0x8345eaa15008776bcc362149b9859d122febe0ac163844def97897a554e81d8d"): true, + common.HexToHash("0xfeb13546ae735cd01623c91cfad280b4ab9bd4e91de47d75538ea4a1071dd4f1"): true, + common.HexToHash("0x685b83e1bcb8d00c5d96fe7de9ceaabfb89b624c2acfa38c6bc8b321fed3e5c4"): true, + common.HexToHash("0x56cb45ddc59dee150e4bd0442e3a58c670b38560f7c0f319121c7b0fbd3a0db6"): true, + common.HexToHash("0xbd9f01c327cef2ac5393fa04025d7b480effaa465d351dc586195d4ca5ae544d"): true, + common.HexToHash("0x40f64597dd5f47a5e3e98a4adcb26c06073d3e7f78167ca4327b596024c0828d"): true, + common.HexToHash("0x9e575a597e3bd63c7f55402cb2336efef30c6a298d55e9a0605642326aca77d2"): true, + common.HexToHash("0x0b31a45ae4c5e73507571cd7f23fba78809f7eeb4744181f52f3e5347aa28138"): true, + common.HexToHash("0x9715dd731f00be808ff60fca103d020789410e5dc0864a0ede6cc5d3949da181"): true, + common.HexToHash("0xa60b26507e40982b245b68abbab9a201432ce01ad3bf7613d421c45cf2821f0c"): true, + common.HexToHash("0xae3d1d4e701580e01b17d4b6ba7256d322439f416d3f3f24cad7b28e737c8d06"): true, + common.HexToHash("0x85a49df99a44ce37a3a02560fc07b3574393e30e99103735ed5f5f014bbe1395"): true, + common.HexToHash("0x2c3df506a801816b8c8c8c239b7a63941bb6efa5d320ea79990c5725ed7bd77f"): true, + common.HexToHash("0x7cc29e5faedd1b57e9c8ea3795845e5665411761b43f13af548a5fa05aa9408c"): true, + common.HexToHash("0xedb4ceb21b6a03cb62ce340202f32632111ca68574910b162bc2ad4609e5d867"): true, + common.HexToHash("0xd02f37807abf2455760edd6b505b958e5cce820a4061421a3ff0626901a60d19"): true, + common.HexToHash("0x5d551cc04785ff340400337380d96ce0e6e43583c6220e5ac11a05c1c71f5b15"): true, + common.HexToHash("0xbb251ae6e48e8667e32261acccda6bd715d685bcb02b6e25ef1ba07301c4dd66"): true, + common.HexToHash("0x189b62a6530eee4aad46b1be692f45681ead406d24a9ae249decbf3ce38dfd16"): true, + common.HexToHash("0x3c98b32b744c447f1d627a81e7e6ae48d00bef4789928ad19e4536e259dff3c7"): true, + common.HexToHash("0x32f3f74f116e2f6d1f9c1f46c93b2242c5f18664ded7ef9f12e11bdf49d1c549"): true, + common.HexToHash("0x32cc0087026c764d9d8d1128a05d829c84048a2ede472da40ee697ac4b7dd0b1"): true, + common.HexToHash("0x5bbb0822fa521fb90559af63007c17ae7a525b2da4c7d2cce0beb362cada2ea3"): true, + common.HexToHash("0xd3ba08b2dd0c3b69b550e37c50bff4822e22144906b378246e3849f7a2817d99"): true, + common.HexToHash("0xc6dc2dd72d410d11dee11f324e11fb53b15b7fc7a6fc4248f1ca8a81b38c1a77"): true, + common.HexToHash("0x35226d84a81193b1d15c898e8bd50190424022f45daa76cdf57185583c6ff719"): true, + common.HexToHash("0xf0db13001783e8876f45c30c8a7b658503fffe157bdc06e0218ae92be8ec87d7"): true, + common.HexToHash("0xdf60fbf03da411587824bde37f4752ea6d3d3a074920fba8d346a13b5351ebbc"): true, + common.HexToHash("0x866c168f1fed936e4d28201736dd7b3746b7be40da7bb196469ddc307572e081"): true, + common.HexToHash("0x890314e66e5deb718bef0f86f90d5bef17f6e0d39c3d0297a35f2af81ce9e3ae"): true, + common.HexToHash("0xbb35c65abed7d8f65cbf9e2f3c8463fbc248948857fc16e1bd0223a8c80cacfb"): true, + common.HexToHash("0x713f31cd2c04d85f72ddbf09c700da3185bd681437aba64becfbb9673f962162"): true, + common.HexToHash("0xda4f577d3d8f68d8c1525893256bc06a691f2cf74731b7d184b8d306a133fc46"): true, + common.HexToHash("0x8cbb759a10455a65dc56a14d9bd0074ffaddfc56b9a605e8427a3f16c0022c3b"): true, + common.HexToHash("0xb25f0732a922db61e5adacedc0f26229927d98111f4998c5099eab12b8fb55a3"): true, + common.HexToHash("0xeacf910323ad0d8370e353846e339036f6652bb6392d9ae58c5341806e8c12c0"): true, + common.HexToHash("0x0cf9bc7cd94fae8f53e70df47db16ad98aadfd1f236401de187612733cb94513"): true, + common.HexToHash("0x4a08bcd09d7efdcc6e0c0ef9846c162e2434943f57ba9e4befa1f9cac0aac465"): true, + common.HexToHash("0xe36bc55cd9221178495cbf5d812e4d01a7b6a69dbe13a053a17006558b7706d3"): true, + common.HexToHash("0x88c5f9edb1c330a58ae6f296b8bd3338bdf64ed8e2cdbee07a1c85b38ff4d7dc"): true, + common.HexToHash("0xed2a2b6c1b3cc1ceae1db9793ff10d29df94042379cb80067fba745b8ad71841"): true, + common.HexToHash("0xfa8bb00f7071cdd95b9e28733bd7d9a0da618629f0d3ee245dc2408687283244"): true, + common.HexToHash("0xbdd0201bef0391a6e8622c1401c6b4d4ce243b289298996ff5a6530cb92e7c47"): true, + common.HexToHash("0xa0d74a06da8ff9bd605b0822fd5dce24cd78b518a6953b6a9a6292dcd936df41"): true, + common.HexToHash("0xa1615037d3e920081fcdd13906c2e547c84e22f2ff869a15f4daf89bd71b200e"): true, + common.HexToHash("0xbc0f95a8918f6d1e0bffe5e36df26ec290e3079b428d78b04197f0b896e4668f"): true, + common.HexToHash("0xc8252e625c4f7208c964fb0d9725f272b760a2e5ec2ecfe2a90de500562ae2ce"): true, + common.HexToHash("0x8760b3412060deb3bf030cfe5cfcb365d6538ac0233ce12cb01e4a9a4f287ddb"): true, + common.HexToHash("0x44ad8a93ba7208ce1eae5f8a484dce1f97bb6abc3fa025f578f238f1998b6c8a"): true, + common.HexToHash("0x973ccb6d6edbf2f453c7c9fe4a4ad88d46e724383452c48564dacdf60bd714b7"): true, + common.HexToHash("0xcc49dc3d4c554fc68103216fe29d3d8330a871d6f30f970475f3fc66666ed99e"): true, + common.HexToHash("0x63174bc2e8942831c0c7e7f5cb48469508391efdcadf5dc25f93e23566d6d329"): true, + common.HexToHash("0x065ababe1b996b35569a466b65466478a4b9b0d728b8a6ca89885194788bef12"): true, + common.HexToHash("0xfde870229b44248d858062d89ad13ac76b9798ccf6c99fd7e1f6613311d6da64"): true, + common.HexToHash("0xea85c0fa555d45d8056974d52aafc1ac179d0394b96fa94ade16e0c3b3910b63"): true, + common.HexToHash("0x714be357df05154b4c6a38db07de44edd6c6915ec038fef13ca040ee321d8901"): true, + common.HexToHash("0xe059b7ad1440c26e852a5343c101c159c69f99aad5d1f2e7daeb3c40023a0a62"): true, + common.HexToHash("0xb5c26d83bbb966388022b70e0c628f7d5b4c38ce48e42e524e887d6205d0bfc0"): true, + common.HexToHash("0x9930c3a4efd8deefcf34943cd5de66b20292de1f7b56c2aa8d53b85130b1c555"): true, + common.HexToHash("0xd1f4536becd7d9b3d580ffe209017c2c435f003f72d0673788bc90e85fad4ff8"): true, + common.HexToHash("0x44f72c8fb4dd56d546ce2b222eb9bc6722409c33bd970630f486ec0d691cd5a9"): true, + common.HexToHash("0x3d7400fda01524d20d64ed0d0324930d58d0bacf1cbb93c543fd51e4d23940e1"): true, + common.HexToHash("0x16d8fd2100805529eca1ecab09f438715988e67f6c1156c6583784605c7c4e84"): true, + common.HexToHash("0x77f1731e84bdffe76e3e763b208904f7b96fc90ba88af464bce1d57e7980c968"): true, + common.HexToHash("0x7926726d3a69e38390e51785c3142cdeb541cff1e375b35b74fe5f02760a661b"): true, + common.HexToHash("0xa9162b8332e98390a8da2346708d59a81e3cfced37e5dbeb54f1eb9b2cbefd60"): true, + common.HexToHash("0x24066bd8966be2f894361a0176f867a6d2f4438d3ce1e538ef5db77126ee04f7"): true, + common.HexToHash("0xa1b463839a1d0ef693d15c71dc229715a3745e8566a0e565ae78b2f157d2fed6"): true, + common.HexToHash("0x3fff35551c802770812550c711ff0173f805cc143b0f9d0015dc74953fcd85c1"): true, + common.HexToHash("0xb1d2d46ab58a8b044d9c940e8a472234b80d3c1e003581fc5e5d6107b552036e"): true, + common.HexToHash("0xf96869053835961058b5eb03928eca5cf3d3b6feb084c5e6e72dcc82b3e25010"): true, + common.HexToHash("0xdfe87ad82949c870edfefe95e1c32168a59ee4f7bd5cbb2131fd5d7bd57a0a84"): true, + common.HexToHash("0xf1413718a36a9849e6d9f823bdea3b0c457439a0107855bf50c8aad523a193a0"): true, + common.HexToHash("0x5890e361214cf1f19018b14659a5fb248851fa0503c6c119950401c848a96b75"): true, + common.HexToHash("0x01bd14bfd0568c4dd538116b791b5ba4fd86e4404cfff25d779baed866c5e869"): true, + common.HexToHash("0x33d68e497b1d7928f10788b0867890a4516cc484b82a129ee365aaa99df64b5e"): true, + common.HexToHash("0x6dc4257f252300c1361bcb1fc969b8084f2f4683fcce011eb7b4fc3dac2909eb"): true, + common.HexToHash("0x7845b8ce99d6baab4025d41918dfc81728fd6ef87bf5973d1c629d3b915c27ab"): true, + common.HexToHash("0x8f1537f87dc15777126eb394634a5fd9a13902eaff04de371b57be57b74eb473"): true, + common.HexToHash("0xff813fae980d7f2758376ad576d1aeeaee3c9a1304e4e10aa47f3dd45d594ab7"): true, + common.HexToHash("0xcba0b59bb99cab99e140e28882ccdf6b6ccfc0d65fe7f41790dc4eb09b89a72f"): true, + common.HexToHash("0x8cbd44967c89fec285cb49522610cc444f63785b9e22354b10f7eef59a2fed7d"): true, + common.HexToHash("0x68f6dc7b24d7a98faccc55a04e52e082b232576d63e152435d1cd1a93ff06308"): true, + common.HexToHash("0x3ee65cd39f66160546aa433958cb1a4420de8955f70127ce22eadb085c159785"): true, + common.HexToHash("0x5861fc546c0919e08897cb4c3e0d207414ccffb72f45a198ed661f41f3777678"): true, + common.HexToHash("0x70364b6890b506cb47623abb143f7afee161bf5aede583a923c0a53a2f9dd8a2"): true, + common.HexToHash("0xbfc8fa56842721994f3747eaa78e98e9d790b294ceff58bf65425700c6677518"): true, + common.HexToHash("0xa7e26a4cf860bc6a36e3489705d809ceb33dbe80903ab6ceabb87ecaf75d7b78"): true, + common.HexToHash("0x825148bf6465bb56e722084934d8032480d7e1e48d540e23f372e5f5acf99895"): true, + common.HexToHash("0x2cc0d05bac83b3dfac8ae7116db0e7ffb3d5881fbc74f8effaf8a828dd81ad30"): true, + common.HexToHash("0x8cb41be765aad88541902225ef43d4ae23551490fad8084563e24835e0fcac8d"): true, + common.HexToHash("0x60ae5455e9027d89d3f3975eafb39f2a7daf1587d0d15ad7b61410b8db5fa2e8"): true, + common.HexToHash("0x72882eb9ee1d6d32b8922bc84525a56cae19856e7dd4f1c5a5dc052016b92215"): true, + common.HexToHash("0x8864c9d1c518bb75d7c32b7c960ba01dfe373d05c64560e7ff48f621bafe7b7b"): true, + common.HexToHash("0xa678ff637927f1d076193b84f7b30c030a066ad67d7212be4e09da78062a1cbf"): true, + common.HexToHash("0xaf46e7f1c6e4f76568932407873bec9f89f693deeb781d7c062999510381322d"): true, + common.HexToHash("0x33dd44503ea313fc3127bf96678bec0dcf809f843c09fc71824d32dc49ca34ca"): true, + common.HexToHash("0xe1096a30a2c53bd98b4afb9f9aead22424d4cafcaef2ba8b0a3a8131d6ced464"): true, + common.HexToHash("0xcb399bf0ccac55bb6784b31b87cb2f3e864d15449c94eecb10ac4b1b5977edcb"): true, + common.HexToHash("0xc0628ba045994f1ff2d454b0b53af61c1b7051fbeda019dc9c8d1764a3f977ee"): true, + common.HexToHash("0x60f9cae6bac7dfa971db5246957557e33954f2047e6f505ef3dd3bdd97aa9ed8"): true, + common.HexToHash("0x9fb7e85b73c5c7e88b303e46f49186c714273764e42940b8fdde405d6d33d35f"): true, + common.HexToHash("0x5cd44c8ffb34f3dfd7febaa3d1afb7e53b2dbf66dd37b1093f612d6d50ff5e0c"): true, + common.HexToHash("0x3c65f4180c619eab1e5f0a745b72a16fade0748594c06d35bdfb0778714bb009"): true, + common.HexToHash("0x9435affff99367a67676619b9fbc68b5bf763ba700cf78e5bcf5d2115a9ac171"): true, + common.HexToHash("0x539a1eedcda3458d01b99c14a1e453ab2303068f8a36b46fbe9dfe853a57b772"): true, + common.HexToHash("0x701f1c17bbf4715fa11be2fa4d181b94aeba969b972b4f7bad9f0c10c992bb2a"): true, + common.HexToHash("0x9ed3048fa52bcb7ae2a6412921f47644c3af34179be36bc78e5dffe0c2fbf358"): true, + common.HexToHash("0x19c17d90050a5adb8078bfdd0b677af6aa9a10d3bb922ccc26e639b5cce7c362"): true, + common.HexToHash("0x4bc0c026f3c892c65d217f8d69ed588b1b02fb86603f4512e865c14aa59b758e"): true, + common.HexToHash("0xe4f63ee6dd6dbe94338d77ae6b2b2563d57a7ddbb3cbe055838b5f7479924069"): true, + common.HexToHash("0x0ec05cfa61ba97cc2998a055cbca1b6493fbea714b49db9e22dc1aaba961a2c0"): true, + common.HexToHash("0x1489483642f87405f0e7d59c23657979e6ae78da4f1164a92d132dc90e73842e"): true, + common.HexToHash("0x016f348790097d967bf7e53200703aa20c25bce8415dcf82de657a5e6a901991"): true, + common.HexToHash("0xff84f29d16a9712ded30f2838e3fc91e6c7dbcf7047bad61d61393fe2f5bf710"): true, + common.HexToHash("0xfd6c4d69450f711802ad41c48ba8e1bced5d6de7e78e1876d31c57242dff6318"): true, + common.HexToHash("0x069dd4d34ceb8fa9c8f9c129a3789bbb4dff4f0d5a1c09f31335bea573f94b60"): true, + common.HexToHash("0x9290d9cb6a09689edd8765d8f09d6807070e93b88f80b48fd62c1ae8c249e3d2"): true, + common.HexToHash("0x09cef4acadaa9c8ddc864d11342d76dc6b9e152611993f49cbf6e385f5e6bb24"): true, + common.HexToHash("0x0165d289147c5f992e75ae0fb18c96d057e57ffaed44faf20486def18a068ab6"): true, + common.HexToHash("0x8dd3201a455f94b9b6a63d2905bcd5cf2c3e9004a8fc96de1effb0c63dbcf015"): true, + common.HexToHash("0x5f30120cb81c906cc81c030b3a2d33d26cddea91e92406d6d007c59b1f5bdc2c"): true, + common.HexToHash("0xe286d533258758e20489cd8c0aeec3b93ef1f1cf5dc53dc1f584466f17681017"): true, + common.HexToHash("0xce819eed816372b4d2f66c7dd29ced7730a18482a46b11017149cbb61395009b"): true, + common.HexToHash("0xb34026526e3b026fdf0bd3aceebf8668b54d0e351a5c2924dab6e0182cca4cdd"): true, + common.HexToHash("0xfc7923dd831d1a44836ff01d58cc13fb64bf61a41c40a51707211597fb432fc5"): true, + common.HexToHash("0xa66274b85ad876e04de5eac91873f8c8fdfe3d8d7790badc9f184da30a970a19"): true, + common.HexToHash("0x17472e47bb616833bd7938af091211eaab15d0b3001d0dbdbe457bae8100d7d2"): true, + common.HexToHash("0xa4e0f283d5d870b34cea058b43545bc18ee7a9d8f30b83e5c7f985e2295421fb"): true, + common.HexToHash("0x0ef31005d5f217c181ded7af387a1defbbdfe1b4f7314ab01be3d05944b91fef"): true, + common.HexToHash("0x27615eb9e01354fae85e9f4e7d134c4c2df08f105547ac33a360ca82fdf3d511"): true, + common.HexToHash("0x9c64417e260accc6201968947c1d14b78e68a59d32a9115cf4571d69fadb3df0"): true, + common.HexToHash("0xccbd87f6c7194996a6f281c5909ac0f88976f7df75d935f6028f4b7601891d90"): true, + common.HexToHash("0x32a55fc069b2494e4ef19e49f4e7204523267d26cc2c15e81baf25cfaeaf44c8"): true, + common.HexToHash("0x485371c967b44ccedc9ca2cabae2bab3cdf6169ee8085503fc2881469425483a"): true, + common.HexToHash("0xe8203b1902d5fd6a46999abf8d51114f295961847342de655ed369c6386f9275"): true, + common.HexToHash("0xc5a8f6ea3458f7ab821dc0dfef076fe4597c427666b54981331300daccc7cd9c"): true, + common.HexToHash("0xcb5a35ce984f5af6e958490ea2edc9731998635b51893dd520de7692093f813b"): true, + common.HexToHash("0xa3741946fe2cb4eeb0589330858d759288410d149117f2e0c03b465fcc394861"): true, + common.HexToHash("0xfe6c7143230fa7fe0471e9af230f3308d2c7ca04fa128d69040d635d4b55c589"): true, + common.HexToHash("0x5048c7c404b08874e3eddab80bebd9ae1198f57ec4d81d8ac34e119b2ab4be4a"): true, + common.HexToHash("0x57ddbca8933b9dabd17ad761938ed7a5b69bfe8b98a19e82a373b27d468fb379"): true, + common.HexToHash("0x851a4ce969dee3db27923f66ec90bd3db051d5f7c308038c4587a2224d40f3fd"): true, + common.HexToHash("0xc337f523f82f12b75c3c0e4b02d47f635530b21b723060d6f4e0c9b6ba8770f3"): true, + common.HexToHash("0x8562e2faaa6c1a0f2a7056386ad48ba7155382fb97bbe04c713768e2ac4dd348"): true, + common.HexToHash("0x52cabd2073e80c87fdf9c121dd4d4aa3a8c63cb469f7b1e34f532fc253bd53ae"): true, + common.HexToHash("0xef9642d519ca561da12e9ac5084e32ca5c0ee18a00c2db22170948dee1eb55f3"): true, + common.HexToHash("0xef0b99959e2659d193fb5a8a7693a8e7eaf1882c39d9be79f9eeb4f763d78c60"): true, + common.HexToHash("0x0709ec9f6060c3e3c5128f8a11849056dfb5ba3d9efe25a38503bcb295cbcb89"): true, + common.HexToHash("0x882838bc1727012b8f56ec9bbd3297cefb879924e13cf7a51876a873acdebb31"): true, + common.HexToHash("0xc0ac776dd5e6e6b942f779121cb5edd98d9ce113837da6d36ad3ae97a8f706a0"): true, + common.HexToHash("0xdb42622847b5a83b0a34dcff316d00cd21f0a2eee9e4e2ed7aa7fb097db8fb37"): true, + common.HexToHash("0x44e948b3f4b246ef78bd5cebedd2d6241d811e11267886611303113b036d50d5"): true, + common.HexToHash("0x4124e3f954634d8039dfc13bbc6e3494d26b03a04ddd15a6f778ed1c08e250e6"): true, + common.HexToHash("0xf5aad0103f9ba8dd1a91229e46cc85b85fd1264fa1d39514cb93588042392b42"): true, + common.HexToHash("0x60b51fcfa36c7a55f59db2a6cc89bc56605012019bad40d8e4234d5474f26951"): true, + common.HexToHash("0x30aba54c4c8458301702b3e459297d4de3b659a00719ff6c699bbd647a8dbebc"): true, + common.HexToHash("0x2352ef23ba250ccbdd8cded88be9a153accb53baec4bb357a6fe6691a091cf4f"): true, + common.HexToHash("0xf7c07e98f7f2f58d09c4448799d4bce0c2fb62445145c3b55386c9e85aeb4716"): true, + common.HexToHash("0x8345e3ab546a01e10904133aa6ef516e9e574fc78f05363813668cb3bd27723e"): true, + common.HexToHash("0xa166d18c7fb171fdd857619548fecd11b41e08b8350cc89ab98c78aaf7c74089"): true, + common.HexToHash("0x7a65330dae942963934f7ae8d9849d2c780b838837b66e572f097065b18cee4c"): true, + common.HexToHash("0x1ea1fea4852e506df5e5085e67302f227980660ce3434795cb4d9190ebd980af"): true, + common.HexToHash("0x2c0b9bbacf6f19549b98e481bc9e860315c596889d20e61955829ff06bd55b73"): true, + common.HexToHash("0x1e822431c7e1810054f048f2d1d033aac77fef516b4974d122ea590f5538085e"): true, + common.HexToHash("0x11502bf955cb7da345570b97bcaa6c60ae4c0d5e3a0f24232fc23832200f7494"): true, + common.HexToHash("0xed9a91b386b5b2238f6d84bae83c3f95727316ab6f427cea6ff7fd2c68c0ea10"): true, + common.HexToHash("0x41a9e31e2388fdf44727e3fa60d3cbae4fe49529f245d5f8a4069e30db6fbdea"): true, + common.HexToHash("0xb9b8c146ae543e1ff13d34743a3d2050bb6ae226e5913fdf4ba7739012f433b9"): true, + common.HexToHash("0xae7421cc0400848c15d699daf946ec174e81dc0fa413302f4a8d6e2d92fe9948"): true, + common.HexToHash("0x7d35cab46ca5b7ea0c45583aacc1563c0acf05a2e5d849b2a06a03e5c5ed8c6c"): true, + common.HexToHash("0x56b387e217dd581385a72d62138372e241ce70093d73581ffb5de0d6a6793362"): true, + common.HexToHash("0x3cf7d79065e07fc80729498cf7f983d5c611eac04d5ff72fbbab50c75d33e313"): true, + common.HexToHash("0x321e8ff332751704863978569f670a892dfcaec8c62bb0827726707d13568035"): true, + common.HexToHash("0xbc54f11ae009da98eadcd573a06dcd506ab362e0227f94cd7a9406f0577a5cff"): true, + common.HexToHash("0x44cce24628fdb8469f01b57d5eadfef4866f1796f7fb28f9f972669f0f045696"): true, + common.HexToHash("0xc805b3629a4bc11ab59b1bb9a2b1e33052b8baae35b85d8897d52dea9d96303d"): true, + common.HexToHash("0xc716073fb838ed86fbce04a5ef583489670bf489574100ecb65a9983c44cca05"): true, + common.HexToHash("0x71b7507a561e32aacb7d707a4b7b08416577a1195e685925b2f9d8eeed3508d2"): true, + common.HexToHash("0x4f4c3c6326ed4f86a1252e9624141b65ab1ed4b6951fbb9a92ae9e8fdb88ade8"): true, + common.HexToHash("0xad43fa6cbab5b97aa800ae6819aa7d16b7baa3de35fabdbd12ebd9c1ccc9b0e7"): true, + common.HexToHash("0xf0edbf2fa2c182b7c4e625fddf76060d7e1a467b8812984bf6ea6f0e4ff5e0ab"): true, + common.HexToHash("0x0961d3999e64f70a63f00c079d9d6737fa3827d90cf08cebea514eaaae2d8c02"): true, + common.HexToHash("0xf41ac12563bf3cfbf6f1f326214dc22787fc86754ec5caa2072fe5654061d6fb"): true, + common.HexToHash("0x5bbaca16df5a4e2c304f093388f722af93267c9add52bb297a61bdeef01daae5"): true, + common.HexToHash("0x21fb7b1bea90908f7eb0fd6da53419d428f70e1451b28ed54fc16359649d9549"): true, + common.HexToHash("0x36d60dccd3255a6d7c1e3cc2af033581bad4c929c329784f106f2d4774b58cc6"): true, + common.HexToHash("0x0521c616bf6be6d14b7f07bbfdacc709711772b651e723db553ab10b86b42e8b"): true, + common.HexToHash("0xb610af4539350c98df1fdd1c25697072a6314d440f11f30ce9dd151bcb613341"): true, + common.HexToHash("0xd8bc56130ba0e9d29a4188bcc90b627af86e53e7ec79a3792bb13cfc58483d7b"): true, + common.HexToHash("0xd4e45e7847a2d8bbde6eabe01b052b48d85d75ab13a27fd6203e0e6e7bc52ee7"): true, + common.HexToHash("0x28d60bfedbfbb7d77527f164d81c70f76b95c9f8ad099088127e097ce9a7a163"): true, + common.HexToHash("0xaaabadfe05a2d86f137d4ac88ffb66a3bf45df4c348b49ba07ddfa4c98806f36"): true, + common.HexToHash("0x67f24b45346bd70cef60aa063e3a8f54a29f8c459c098599b0679ef89c85ecf5"): true, + common.HexToHash("0xe7cbc4edcc5a6ebef7e3352bf53cccc53f7a73185f91a6bf05b1a5441186f54e"): true, + common.HexToHash("0x86edb167220f7e9f6faadb2b97a249dba96f4e2d28c349bd65aa7b42d42d0b2f"): true, + common.HexToHash("0x807b7dc771f2429406d291645f0f1914039d7198e45c378ffdc4ead32da89cbb"): true, + common.HexToHash("0x09257b160d2c5dd2eca971d4a3220d67ecd8bfcc678762fbd8e8ce2ed893fb27"): true, + common.HexToHash("0x10ed277c36c49a87a86600b8d6f43f669b3baa117d0d3c517a29fd65c0041027"): true, + common.HexToHash("0x7e9e2639ac0a0a141b44fa8b9b60a210c18acde141d4153336c2fb30da8ff5f2"): true, + common.HexToHash("0x6444a2b941bd3cf23fbdc8a658d85f00069bc2e4bd30719b7409975b8bf0a55e"): true, + common.HexToHash("0x5eadf3f933c9ea6b71c05a1427eefc98c97eabd6af1cf4e5b02eeb48ba5ae653"): true, + common.HexToHash("0x4d5b282f4039ff6afd5b59a3c5658f6e088909d34cc5df8702af1c4dd4a96293"): true, + common.HexToHash("0x864e3c5c4bb04eaa3d0e8dec06542e65789f10a51bf88cbb0d1b7050471b82c1"): true, + common.HexToHash("0x8d8d52912940dec0aeb61802d49b7a89ab5d5176c831134be9135627d3ba6fd1"): true, + common.HexToHash("0x5aee4a713dde6322335ed9db17292a36afc5e2d55eb1d972d09dde9407f8da7c"): true, + common.HexToHash("0x00945ebcf70dd689cb98ca46e977f4fa4b52b1c1fcecf3793dba679d520a3047"): true, + common.HexToHash("0x6b7fcbfbaf6439ffac902f14d7964256e3ae46afb6d643d8d2b4164ef81297d2"): true, + common.HexToHash("0x516d3cca3b355fd54bceab34fb056c3313ae71cec91a63fc89ffc65ff63633a8"): true, + common.HexToHash("0x2dfc99969f81cd77f6f1a54db44c301e05de8b8dfd74880dec5379cf6f45bdb3"): true, + common.HexToHash("0xc0b134b97dea315fa08b869cb53b83a85ddbc8a09c632d6e3500c54efa6d0fc8"): true, + common.HexToHash("0xe6b5db359970abd3ec5069779a99775365ca5925448abb5377be10e07fbd972c"): true, + common.HexToHash("0x06d5ebbea1730618b595a67eb939dd3537b4e3a67dee2e2b198062b0c5af968d"): true, + common.HexToHash("0x35705874e8d173abb98ec19c28be2ed2c0e4d82e1e1993b2b3eab95e437daccf"): true, + common.HexToHash("0x46c181fbd3dbaf01c45c8ac69969a9d30c74305798dcd789f3efa5f42e6db6d7"): true, + common.HexToHash("0xc43bccdedad12e6776320b5d5bf2714828968916c55b5a918c676e1833da1c69"): true, + common.HexToHash("0x5db9f13f9339820419a661dbe815b0a96fde274d2706fca0c05f77644be34371"): true, + common.HexToHash("0xe68af631162afdd2112d791ba5ed7b60d1eb74bf57dca8fb7e151932ec904a59"): true, + common.HexToHash("0xed937a3d0949f624feb9a1d09dfcda5d94cb54cda51bf94d5bf7446bb73dfcca"): true, + common.HexToHash("0xaaf5be5c8943dfc677b766b9bae4729efd12253ff40e8f18999532ece4a94352"): true, + common.HexToHash("0xede7bfbc9073c32d8aec4a3a5fb335c6950828709c5c3a6e9ed0400fa427a9e2"): true, + common.HexToHash("0xf4ca5bfb29b5a799c6f5baca603dd21690c28fab0e4820056a7a8f3392c0df92"): true, + common.HexToHash("0x8cb59d18e0ae7fb65147589bb5bc55825cb9beafc3b1f121b940166bfb68e595"): true, + common.HexToHash("0xdbb347dee60ba27ce3e758338183111ea2bfcb1cbd5aac97731f70f331ce2b54"): true, + common.HexToHash("0xfa3f0f154b2175042a6a4665712bacbb8170d0ffe729674a203e3b1a637627e9"): true, + common.HexToHash("0x26f3040451fb7db6095ee0c1031ca1da65b4369f00f7c01344d0b6be55a82e16"): true, + common.HexToHash("0x8ec7cae4abde7effdbc1bcf98f8853b0d5f21642917add2639e9d042db277786"): true, + common.HexToHash("0x81777e7c92488432ad4a98ff6c8e2145cf21c96531ac5bd39ada695b6c383622"): true, + common.HexToHash("0x9cc8a40569bc2cd2dc5159c169ebae55eee570a59daff9f2e08597dc7ee66e35"): true, + common.HexToHash("0x2a22e6c4fcd2b1c59d3110e970acd5edfe4870fc3d0a3f540e01fbb71245bdf1"): true, + common.HexToHash("0x1ef2fc8d5cd60aa7b47aab30d54e09ce7d095eb7e741bb4ab7049317fba0a904"): true, + common.HexToHash("0x3c2ef64ae0f005c7a70bffcda0ec30f5925ebb6141076b503944145dc37ab230"): true, + common.HexToHash("0x7426a6a8295160e0cef528e4a52afc04c6772fd9217b0dbfa5a37e89a3b4b1d1"): true, + common.HexToHash("0x48bb9ee6e485981d55aebd4e07282830cbb9b2b99e12e864a563f602a3effde2"): true, + common.HexToHash("0xd7c2b50124a20029dd57e53df2b17214445b505508892b8c3c0ba012dc0618b0"): true, + common.HexToHash("0xd0bf7148c709c7e0d998121ae302ab61999746733efdf304018caa54d4493cd5"): true, + common.HexToHash("0xe038e8690cf1cf9c71e63bde04dfb79cbef33700a586296bcf10e01428aaf11a"): true, + common.HexToHash("0x241064a91d55825327bb67b49fbdeab8f5e955897910a1c8a0e25577a9b33be8"): true, + common.HexToHash("0xd2e5a347db37625692c002f0897b2c4ed6a3fc839ac9b5a407e52bc8c835af12"): true, + common.HexToHash("0x0ced97454a176f9e2faa98aba80b79bd320cc1e25d96ac4ecd14b9f8eab18552"): true, + common.HexToHash("0xa5e08e276619e8fe43a893c7b6373d57bc92be7938f4095ce21368ab1ee48167"): true, + common.HexToHash("0x9a5c8510603abec5b716bd4c03804f65c630e26e7022f7c238293e75baee826e"): true, + common.HexToHash("0x6ddcbdb3b5bf0545afb8353ed6e4758eb500d421b6e3d79e513ed55e630fa19b"): true, + common.HexToHash("0x33c43bbd4c2cb29d4b7540562b8d6c3fa820031b965844aa557be31a13026146"): true, + common.HexToHash("0x2d7f10d34b6cb9b5f14ff9c7fe886b5447755c0b3b50d53a4237907a545b798b"): true, + common.HexToHash("0x956240bc9612cdccf3ddd10b4fc2d37e1eb352c0f92a9e4e08dc73568dbcd185"): true, + common.HexToHash("0x8d42b7f675b8886b976e77e15f8e8dbef0547515e695ad2f3e7d8c95a25ac022"): true, + common.HexToHash("0x5d790d1c2974aa6d8803a5b7caa29c9fc5dd91804f6de66fef22c51b4ba35d0a"): true, + common.HexToHash("0xae9a23db3eb701d243b4d9b1a45d75e1bf7f501ea1727f13c6b4976bd5be4b72"): true, + common.HexToHash("0x74c243ebe178d42df9c1d9916209972f125f5a2ac25d3e5963bb389dfc78caf2"): true, + common.HexToHash("0xbfec8a4620d9f0ba322865f8826236f1faa428647093d69ec7b0b9308ae4ca55"): true, + common.HexToHash("0x28d2caf91d78c58aee3bbef40132c0b36d913b320e93326d75523b62c199203e"): true, + common.HexToHash("0x623a2da5cfc07e6a7345cd08692b6f4f2b15a59b7afd84a3dec3a7734fb8a8fa"): true, + common.HexToHash("0x05810fbcfdb86c94b14acb297e5ae2f7ba6b73134d28791dc53fa2542dddf326"): true, + common.HexToHash("0xbdfe182aad93124df06efd89dbb05d01b7c48a21a87964d9b71f583913117f0e"): true, + common.HexToHash("0xe2350d863fa935c182ad87fab340f8dbbe3e7540af0a643fe960d876948f6fbc"): true, + common.HexToHash("0x4a0cc768a8f62713390d5c319284cc0c32e7158669f0a63bf37107f77eccb477"): true, + common.HexToHash("0x1d678a25085792897b68aeee004f4695ae6621bbcd7d9c390cacc982f059073f"): true, + common.HexToHash("0x2f7d5d7a1a5aafa318fa442f119414f27c5f6bd93a33685c62c54a32931e0a5a"): true, + common.HexToHash("0x5b6c20fbd05760f8d1f3c0caa0cf45442c368b34ef0e309e309cf263ecb5f99a"): true, + common.HexToHash("0xa5377f8062d163930fb3daf92e2a3c4031e50bfc34230c0a0b4fe72c7466fd8c"): true, + common.HexToHash("0x46e8b3a06a6538614071ad6e2fb0f3b4619c5134dcfce1403ebca7c7fc80544d"): true, + common.HexToHash("0xf1e81d0c2b0fb154784d2ea561d691ecc9d278bc25b7dc99ae82172ff568e363"): true, + common.HexToHash("0x02e42966103f8ce8118200844accc687c6f0aa10b62d867cb24577bd8256c18b"): true, + common.HexToHash("0xbb68f53523500affe92f9b1ac8596e2cdbe7b2800335da09bd3e6c2179d48168"): true, + common.HexToHash("0x46e461c99a0ef8c94f48e0863f5e05af4a7264402b61a6ae97bcb2cefda2c9df"): true, + common.HexToHash("0xb2ffdfd03dba145029dc8af029de2e3b2240fb3238033502a2c58f396e68117a"): true, + common.HexToHash("0x5e23ab25b50828aaf5f231b5d0be840d4221f48baf017326ac43c580242953f9"): true, + common.HexToHash("0x62f71716b2711eeeb30351329fadf75fb314bd33ce7f8c03b17ff4568b416e5d"): true, + common.HexToHash("0xa71291163e5c215ec5219742871b7e429b8dcfce04e89d42844d8b968bd914e0"): true, + common.HexToHash("0xa35a0866d00bb71d689b9b42ff52a3e5f2e5ae2a67453fdf3eee3527e0944b13"): true, + common.HexToHash("0xd059193fd7aeb43f15762058e7d1452572a902d78557b4d5944c61eeaa899fa8"): true, + common.HexToHash("0xcdfcb863e78a4f8609ed428629da5c6a6ec794c77d8d9cf49d2bb2daf3b2365f"): true, + common.HexToHash("0x6b382bc4b16562ad156564211f5d7bce47c1c0e7f2f5fd73ccd60d94905327f7"): true, + common.HexToHash("0xcf15cc17a95062a7be3945a302e4623d1749c0f9b3fba2504798c2bf139b2203"): true, + common.HexToHash("0x878cd83729593ef2191c2cf13ccc12cc2b7bb5f31659959346cc7feb3be6792c"): true, + common.HexToHash("0xc5d8a1b680969e66ec85cd00ddfa6efa5e1d2be2ca0f8088f2dbb9123975c7e9"): true, + common.HexToHash("0x778aaf617b1196d160708b6b425cd91b1b4d5b8bc74f1be9ee80eb8d2c0538ad"): true, + common.HexToHash("0x1960065c878ee8c4a2b37a381ba09a2b82f6179d357ff22376235cc9439ea3db"): true, + common.HexToHash("0xd8c34c6c7c4dd211b737428d3e48a713609ed419781fb71f3fc41314be627bb7"): true, + common.HexToHash("0x660d001155ec3f0a442eb5b6d03b0b6bdca1de0f13e0636b3838639edbba159a"): true, + common.HexToHash("0x6f552e916ae896216ec08b408236a76d4cc6ae13a4baea375dc82ee2f213e183"): true, + common.HexToHash("0x0d57e0b7a88b0e768e5f97226e24450cc34b15e67ca922c1b10dc998307cb018"): true, + common.HexToHash("0xe31c3564bd51a07c7c65fe621ef50c0f3adc5f8a7ab6bf32e5ecf03e5164427d"): true, + common.HexToHash("0x27c9bb9c319e4190ede562cfb68d9e34dc7e9bd727e48b750bf6881b7b77c865"): true, + common.HexToHash("0x3307c30c51377c49fa3737387156e33d31a2c149720cbf12a8b14f8535e5c640"): true, + common.HexToHash("0xdb75896efb19d916bc753e22182f68c9a46461cf7d5ec934ec696035b51c4f90"): true, + common.HexToHash("0xaf357ed652cf38933e751ba268fe26778502e04b3d007010b7808098103c4032"): true, + common.HexToHash("0x7dcb1225e046be8d2fdfab9ec1cf068538316f0186f258fd5501e3b9298e3a7a"): true, + common.HexToHash("0xed05b512d82ab0fb15c37dd8d630cf6610fa6aca909e34a615729577cf9baf7b"): true, + common.HexToHash("0x5172a0423628096b34c5dc4bb87faa030dd79e6ac3c84b10cc46b1159d4d1fc3"): true, + common.HexToHash("0x3b1fd0afbf1787a716f5438c40d3ee85503dbb18874565307fe3090a0351dbf0"): true, + common.HexToHash("0x9e5ce75e46851253efdb0017809e8b3a03d94ce02e42c3335c018946acae6697"): true, + common.HexToHash("0x375cf2ff09ecb0894ee31b19f1ba30f57b736fa3defaeecf1e6370bd379bdc91"): true, + common.HexToHash("0x67aa81d40b23fb6f824be8785797f3e0e8402887002912f65d541e3c9e576fea"): true, + common.HexToHash("0x8597f66a9dce378153ccfd8c4f102d8a1c8e228a935b144c6c8e90a023ed9e26"): true, + common.HexToHash("0x4c54aa5213a3e496ace463d254932b1e0cbee264856c45ec02414a7baeed1207"): true, + common.HexToHash("0x35b350d32eb8c667af0adbe303707d5706a665b0b2197b46416600329248a49b"): true, + common.HexToHash("0xcd1ade2596858c32c1f06b56d4fbd5d54c38edad67fe3fbda5a5cd345d14fa8d"): true, + common.HexToHash("0x57ff68a87ca8c69989112b7c2883f34480ed699dbca433d6086255e3b881ee3b"): true, + common.HexToHash("0x4987b8506e5687007993490bc20cb4b775a6db7a2a65dc11d776a55498e9b888"): true, + common.HexToHash("0xa9e8d65bc6edbdaf8d825e42b536b0949c6a7429c7930f93ec20dd882d528768"): true, + common.HexToHash("0x9585ed83fa529962975407136b1fee6070cf3c0f74f7ef72607be8f4e8efcfde"): true, + common.HexToHash("0xc3694e1a5f924579a02549ad9c91adf13ad3cba70b3f323827bba2e28d40a855"): true, + common.HexToHash("0x2b4fcb8483ab17899c9c401ff5948afd70995045d2fb18d8d314f353aba6277a"): true, + common.HexToHash("0x59ac068eec79f8d3eb45625d2ae4103234e6ad9c26cb7453657c48cba0844bf3"): true, + common.HexToHash("0xb5234623f12a9bb059eb7394b4b346ae30f0e8d66c46eed74daaf1584a20e577"): true, + common.HexToHash("0x5877c201b683a943f5f7a25d3b0b69d85f120169c61e4167ca37ecfcabae0745"): true, + common.HexToHash("0x77282a90d6a51333820c80bfda358b3321653e63d1a229b493773b4d1b28954b"): true, + common.HexToHash("0x763b3666c25d58d785490e8f72bd4e4f79df1ba02154f0befb11ea52228fd5ec"): true, + common.HexToHash("0x02d14f7d04f85f6630f2a30bee7f5ec3b6fa232cabec0013d22f812bd661ebba"): true, + common.HexToHash("0x04bec3bc3295834130658885846ad986b972063aa40a0c346522a984bc428a0f"): true, + common.HexToHash("0xe6a736a399a24bf71a7436d73a77ba87b20efc91e2b3b6a0d9aa817159693fdf"): true, + common.HexToHash("0x62f0be412b1e45566593a974dd80e733df0257bc96cd23ecc161100b1d077ed8"): true, + common.HexToHash("0xa90bd881680550c053610da261ec5ecf6f480f8753e0f8223b7a8d5b8d53891a"): true, + common.HexToHash("0x06b1bc13a9053376b5b0b25b434f7c76c08577f9b36f707e8368c20603d82139"): true, + common.HexToHash("0x1646dc6b6a4549eeff5b55eef3052f40e3c593fd121f8927ae413cc8f1815640"): true, + common.HexToHash("0x778b8e65e659c590ee6f97eef32bfd3412c324c38c5309ae28d80823d405eab7"): true, + common.HexToHash("0x55b0d0d99f0d449e37149921d5f747ec5e5f27b729d0a45c3738cdd57b3a7a7a"): true, + common.HexToHash("0x653c77735d6ae757abcef472ab198b628c2c23789ee69a818a3383c783b4491b"): true, + common.HexToHash("0xa8132a96964c0f76a749f3afd91289afd48d39cfdcc85e598c80cf44e08ba728"): true, + common.HexToHash("0xaf0ba122ca822609b6a4c79d36403a567e3b2fc421a58e011c6a4074f275a947"): true, + common.HexToHash("0x7182bcdaf3ae22272912352c9d829f5be8fc75d2eaacdd3ab1459b55a9d3981e"): true, + common.HexToHash("0x1058152b66730c6c669d8f1dc6c66ff33e5ef9f9f19893a6215ea77704ff77b5"): true, + common.HexToHash("0xa43f05c957b5c236b5e8eaf556cb5910d408b8fc475532846ee77690034c9337"): true, + common.HexToHash("0x8c538b484bfa1d72bc846cd12a4d792aa06ef0393dc7114661d470be0bfe2563"): true, + common.HexToHash("0x11b203aa376a39bbf5c39230662491e762d6f3432adec12904bb87b019563f38"): true, + common.HexToHash("0x6a0dc907dfc39b10113c9e60920a68daf7b8f2bf53636edbeaa91de59db241a6"): true, + common.HexToHash("0x9124302cb0e0793873bbc00e4b0badf62aefe1fbb3b792a8c6290e8b4e8b9c8c"): true, + common.HexToHash("0x99301208b1548964ef1b92aa5b1fd459f101a15683a70cb6583309ea347a23d0"): true, + common.HexToHash("0xd5f3df5078e76f2e9d9526ba8a9ed05a7141d1eda11e98db0e0da7adafe8ea23"): true, + common.HexToHash("0x6005b202c5a607c611d16a0e29b2e2449dbaafd1a764f4f9df5f9de462fc235e"): true, + common.HexToHash("0xd78b5ce12869f41841ba061243a171451446b6d8808407aada52de7916834643"): true, + common.HexToHash("0xdcfb49fad0fc3b7eab3bf4d8125aa06a4d3a79615784d25aba335f9dd6e73903"): true, + common.HexToHash("0x8fa89355c9302922de9081b52f5547c43cff09f80055fd082515656a89bfa686"): true, + common.HexToHash("0x95cf358d9482f2da8e34eaf5789751142c547e2f2e76b2e0f53ba73820c71bdc"): true, + common.HexToHash("0xd66beed64b5cc96dff3cc4afb8215a071960be05de0719679823c928c2ce3d7b"): true, + common.HexToHash("0x7b20bb743eb89ea289ef14d6799d2623a5cad50c24b4a80fb8ef459b40b985b5"): true, + common.HexToHash("0xec73333cf7b326cc9b68bbeac3769ad5bafe5bfece9d12327403b4a65b6f4992"): true, + common.HexToHash("0xbca61fdba239980320dfeb74536e7d3d4e29cc4a8b1441d7d5df7b83fadc2847"): true, + common.HexToHash("0x0ae6023c9a21507c2042a686d5b9a7dce14161d7956fb1ce66cc89c57623257e"): true, + common.HexToHash("0x296441a609485b6c5dacd7e34fb44db404c259063035aad508557775da182eba"): true, + common.HexToHash("0xf01939b191106289aa9fcb8a5f169e4f9a80917e1bc3d2496e9ec645f4f80c39"): true, + common.HexToHash("0x57e2019a68b752ace95446d291f491379deec13b592fffb5d7b727b6d3f060ef"): true, + common.HexToHash("0xa16ed6c64af53327edd6e15f8496ae13c377e75cd6afc753394337db92bec350"): true, + common.HexToHash("0xd6ef2746f6537a90c4e249cb5507501aba9a789f1a263ceb52c790faf22897c9"): true, + common.HexToHash("0x82245a21bc1b638b7e875eaa193b678daa105f896f3a54500fe725375fd9a4e8"): true, + common.HexToHash("0xc8e653adddb389696f64b2a17ddfe9e589a5c4faf0a3a7a3cdb780372db0f2a8"): true, + common.HexToHash("0x0c34e3f8a181cc38187524635e2f47091f5668fe267d0ea030478dcf9ac259c0"): true, + common.HexToHash("0x4e9e5fb779e6cc41ddc9a4a5ec63ed1fe042a8249cb48ce19655842a3e8534a2"): true, + common.HexToHash("0x213046d3060cb446cf34e726531f23c6413eda8e45ab44aba1c9912305506419"): true, + common.HexToHash("0x285668b5d3c0232021dd755aef51ba79d97601f13b8ae2e470ba21e67222d996"): true, + common.HexToHash("0x412f7710621249426d3d92871818ff1835397bda2a3f10d6396b8ee7fa68b4aa"): true, + common.HexToHash("0xe21d58eb0450b41aa8b8869837d26078b09c57853fa09b8e847ff637666d9c07"): true, + common.HexToHash("0x8b957c9bcb782609f19a2dd9caaf90cdb5cdfdd0cd292515013adc97f73e6727"): true, + common.HexToHash("0xb89563f99793f6fd203cfe2ed4242f9ee30eefb6238bb804d2632f51da65e807"): true, + common.HexToHash("0x4c19a7103c55cab53b5dd828db032849b577ef92507bee18c8761160293a7e2b"): true, + common.HexToHash("0x8fd8b1c4982a5094adff253022081a54d8fb8d66929cdf73f4b5def9665cf916"): true, + common.HexToHash("0x7a99a7d94ec18f7fb10043836d515245382bfbe4699cde22739e4c1e76ef7470"): true, + common.HexToHash("0x5df159621e3b13a98da9e2749cc374abcecfc7639b89cde02563a234a6b65bb4"): true, + common.HexToHash("0x8687fb1a2a372cf04c64cf21d788c133f17f60a18c8b58546295c76d3bce916e"): true, + common.HexToHash("0x582d33e4531c0cfa8365b881b1ca4b0b5f6bb90b983e9691e50f6742bde28e45"): true, + common.HexToHash("0xae42675e8c1c2dffcd89708f658d1317efdc0df276c10396f5867b7214f7fd3c"): true, + common.HexToHash("0x30938a179ab90751b8d5a34fe09cfae09d6cb86d572519a6b78f6d2018cee29d"): true, + common.HexToHash("0xe553eddb8a5b510071d105d5510c4b1a690ee78a2f4f65150662918e818a5b1f"): true, + common.HexToHash("0xc3f67df7798dadac0d6056b6eb74fc6c69230ee858fd42aa8a3c0e5fd92458e1"): true, + common.HexToHash("0xb35a42d84b4f2d8cb4a61ad4223151c0e5d0758e08cd0d89fa94346eac5755a4"): true, + common.HexToHash("0x339f02c63f8e1356d324d9e5ce51eb22e05443a60f511f7f18c90ec0a88bbc88"): true, + common.HexToHash("0x803875bb7ba9c0a2d92c42b0c57b4626a4bd1e8369b7d5ad3e59bc6a6d6e4cf2"): true, + common.HexToHash("0xa2e4a09ac964303fb7772ec5d30c387e39a7775521e6a7725bfc46ca77dd741d"): true, + common.HexToHash("0x0a4bbfd082c046e181001fa4370dec50c064aa7baa9c1323915b55475b979d48"): true, + common.HexToHash("0x71388d8afad2ca772c5476a21c73487a6d216c7c8a01132b0c45b28a8a0a6aad"): true, + common.HexToHash("0x1b7e09165392c7ee80b507429c7f97c3ff987cae3b14462af7eebb17751ed17f"): true, + common.HexToHash("0x8c127958c4e670626ccbb879815e551538b8c189f3bf3da6895be4e8606724a4"): true, + common.HexToHash("0x598ba30b90b3f8996ef8cb4424bdc5faa704da85e9c517dd9ccf839867841a82"): true, + common.HexToHash("0x34a108ead7dc32e83e34b1cd51d53393f4cd50db9262c1150f3bc58bae9b647c"): true, + common.HexToHash("0xe94544987ed72d12ecb25a02cede401cbe0e32882fb2144245753c760ef8284d"): true, + common.HexToHash("0x8629944ab1e873e0170c87d91656c3b6f19af0c2556f683275240738c1244cea"): true, + common.HexToHash("0x6b34ed5bbea55ff7e9c06221f6dd5acc3653d5430007d256d1a287469dedd055"): true, + common.HexToHash("0x2f2ca4e594d0f834c9edf30f079bb6fd3f0bda0ce61d86163b7f2b1df8aeaad8"): true, + common.HexToHash("0xb93efbb657110e6ac64445790e9e683cd9b4e49473f4362402c5334464cdd29b"): true, + common.HexToHash("0xcb577c62fffc61057d1cc2d1d5d95f80c79bd80a3abb63ed922bb3855c67eb76"): true, + common.HexToHash("0x24b64cdb6771815089799a228303edee959c0819396b3f74c6cab5c5770f64ba"): true, + common.HexToHash("0x8b669974ac29864411302263665d5cddbd6f0ce145f63f23f876e600793b8ec0"): true, + common.HexToHash("0x3aad6beb413a74350e8502531bea7bf42e123e87ddc11eecffc8c20018b34bb7"): true, + common.HexToHash("0xd8091c9b2bc633a4b55cf10f84549d9685a701317c000a5912e4af08270988c5"): true, + common.HexToHash("0xf12853bb7c934a91e91897bf9cb1839cf8a2cf49b6ef04c09d62769af9602882"): true, + common.HexToHash("0x5c8f902e6711f5b4cda6d459540f00f3f6e0f32d5e63e7c2537068865fe52b3f"): true, + common.HexToHash("0x436d12b39cab4a71cf854a2f215f59ef103bc3f66e0867f764e7f9a6b55d693b"): true, + common.HexToHash("0x049f8c94f121ad1ac69d9cd03497ffec6ccc381a4957e4764bdfe4bed1b46794"): true, + common.HexToHash("0xd0dac6a148895c594279bf079dcb1a7f9b7909eaa77796a756466ef2c8e532fb"): true, + common.HexToHash("0xcf5fea24b84d855e8556a00c74a7e25802c07a24178a68f1c2f7613d00ecd756"): true, + common.HexToHash("0x2d4f220ef36d43c766d2259b89168a802c1c600d3965abbdbe720f0dd6a17d9a"): true, + common.HexToHash("0xdbc52c59a0472b459b39d72eeb8b8721ea8b44dc7087609a32bbc5104d171d15"): true, + common.HexToHash("0x268c9d1943a195da35c6146068f600372db80c3f15d11e4d208f51561881bc8d"): true, + common.HexToHash("0x35603980ac7cbd2eee882d8b0099f4fd24754cb129aee71f313dbae4af979f14"): true, + common.HexToHash("0x576aa81d6ab1d689697e7078b63e1acc509acd0d0cb7882c779cd2453054ae82"): true, + common.HexToHash("0x61aab7893b2fd16ae4810ed321eb1444ff706d1806769aa1ddef4e5511326e59"): true, + common.HexToHash("0xd7d643362e04b02e7cd33791b5c724692d7d7ef335378d8eb38d049aa3cf971e"): true, + common.HexToHash("0x097ea9c844e3920a16e8abf8061b185ca8067b7df86b501d9347e3d9f37b0dde"): true, + common.HexToHash("0x39b1a67f34896b0bdf6068607cbd838159fb7b1d7e78b3fc72735ca76ad86334"): true, + common.HexToHash("0x03c295d15bbb0408fc12444ab20a5e46124de66bfd7f9874bd10a8ada2ce2643"): true, + common.HexToHash("0x5c2aabd4ff210d95ec437240932f651b717898e35785fe5c16845372d7016bea"): true, + common.HexToHash("0xb152fdf265c9a0aab2cbab7b8342d021b275dea9400976e0a0f573bd06e0379c"): true, + common.HexToHash("0x7cc451cf56a0af964c826a0a0901c3253265f5f73170a832ce50783f451a4c2e"): true, + common.HexToHash("0x49043ed2a30380906a2e2d6e0a4cb19e4ecae16680ab98af520d200e47f9bbdf"): true, + common.HexToHash("0xb64a39dfc4e2b1a24a2d8f0534ed32d0d554af834770f7b45767bea135535c17"): true, + common.HexToHash("0xe398f3bc69ce6c4af7ab1d1de29f199e797402cd7cd94c79f591136f59d44c2e"): true, + common.HexToHash("0xf44b87ccc1765084e0ebee0bea518538d534786d38b996227b2590baf3a5e551"): true, + common.HexToHash("0x353912f02848f8e6a53c5f10ac1190f15c0beee66e4668d825316bd258e3a3fa"): true, + common.HexToHash("0x5a3ccf8c0715c953468cbdef0f27cea111910c1ec1c97dc4d7b647fbb16339ae"): true, + common.HexToHash("0x09cd0e1384857ff5a2cf4841b4ea736342b6c80928e812c8dfb0cd621bbbe306"): true, + common.HexToHash("0xee63b94202489aaa46262c3d7bb360221c86ae056f8743dcedd7465d4fcb3544"): true, + common.HexToHash("0x28fe2d1a88acf98d8887fba5b99b08047f0a3ac073973eeb98ae30d3d2345110"): true, + common.HexToHash("0x0d19b1de83cfe1c90d2d57037092970cb070040ff2f14a7f68f3e4705247a062"): true, + common.HexToHash("0x7e1873987f7c1a43cb3152ac39584b14ca8b0a3e0586fda4702314310db1672b"): true, + common.HexToHash("0x60add8041d699923647554ba02a29357b789f8d256914f1954d907fa3d49eb44"): true, + common.HexToHash("0x78f0aae47130458301a04a2556fd6d785ae047c9a523fcbf7a1d8d767b48ced4"): true, + common.HexToHash("0x6b7217a3786461348a64ceaeba78fb5f3ccdcfd49d6e91aad1b3ad4623fc913c"): true, + common.HexToHash("0x2d008817572a9e168f9b54ad78af38e320dd8c0db46e93d2a4b84471d03ec0ab"): true, + common.HexToHash("0xa85c011b3e988da1befa272636bd3757a3d8b4b90afae4a26397a6f891d5551b"): true, + common.HexToHash("0x9090006f0f790d86d4b6b7bd1dc61023a63e827d31409ce00f777c4596b03495"): true, + common.HexToHash("0x8924fff54d09a8f88346e7ab640cc559dd4f5455cb5fdc3a3eb24f68daca7e44"): true, + common.HexToHash("0x4987aac3e72e270c27e75885cfff6b8e325c16d2b65b76b6cfc5aadde5c9043d"): true, + common.HexToHash("0x976cedd2baa1cfd7d95e5ddb2b15465df8c2bf5a1fb794b0c9bf68cde9e83fe0"): true, + common.HexToHash("0xde65651b51ad91e75ab4b044d3fa9911b832c3c8528ef07f305e8b83ebb67671"): true, + common.HexToHash("0xa86129690e394219d26bcca756a0f20e63612672da875b81831d75cf899f12bd"): true, + common.HexToHash("0x1535172ac4ca14f972a6c1a2f86beb8888f4795f1499f7a03dc8e7fc944b4645"): true, + common.HexToHash("0x01b0ad9ecd7c10e5ce497db9d97e3019fe998af4bab8b0261718463c9ced4061"): true, + common.HexToHash("0xdb3675502ee9702a57b61fd34e24c12d988f3873ddc131762915cfb7832f0af1"): true, + common.HexToHash("0x92d01884c4b42260ad367c4edac27c60808fa70329c2a2d09902b3260eefa7fe"): true, + common.HexToHash("0xc5135d8886971edb7732f0f8f8a7c4c59c83599e54afa80b6754e1cf9abcccb7"): true, + common.HexToHash("0x559d352f789d958bf23ad23f623d794d12469404081a822031c77bc6e104828f"): true, + common.HexToHash("0x97446496ab010d137b64b7b8d3e887d6543925ffcda84987f96637b471baaca6"): true, + common.HexToHash("0x2df984affe2e30b4c06e7e1ed225d1244d92a063e3fe7c749a2903ed4e27c783"): true, + common.HexToHash("0x221be0f09cb6a76ff61abb0682bb7606e36830b64a2ba3936341359de74ce6dc"): true, + common.HexToHash("0xe3cb2bb98097f3e6f3864d8b15283b27ed3555591dc3074c81e5e9e160e8d37d"): true, + common.HexToHash("0x0129b5d141ab351b9c9e10f1d39ecf9dd7d7082b9ae5859188744b749ec982c4"): true, + common.HexToHash("0xbf2eae74c7522e0a56fa7ac29d336c3fff438b2b375d53275673b01f3c276212"): true, + common.HexToHash("0x0ad2e496c0c302cb3f613e05d70a519c37d2b3b7245c25d737c3e237eec5e8bb"): true, + common.HexToHash("0x65bae1f933ee5646dc1da953bee2358dc98c06f5995661d56cb3e982f591d6a1"): true, + common.HexToHash("0xde6ab43dd2d0dc9fef181e100fd49cbda79654561f6bf09540c1781af41e2bab"): true, + common.HexToHash("0x678f2ecd51220803e479232360c7f5875cb7a1ad5b8e698e36deb642e5a80458"): true, + common.HexToHash("0xdeb8316b76c8bfb717442195510a51212a787e293634bf74d9020d5632671226"): true, + common.HexToHash("0x140e19af7042bacf2f130cd95e9bbfd899098b04359aee345ad989a801d84a6a"): true, + common.HexToHash("0x9152789bac9624ccecfac0b4df2328e74a6e205c710095121640a65fa2c85b4a"): true, + common.HexToHash("0xaa4dbc5c774b8fd43b4d47432c5dc3938ee06f96a3fa8e9c30a4b95314144332"): true, + common.HexToHash("0x10130326d3475419d2d5e9a9d6b24bd596de32b84874c357d4eec8cb4767a110"): true, + common.HexToHash("0xdd70d41aaf8ff8b10c9c7e5580da5ec4d4adc7a6bf1ccabcecbffbb3777c79c3"): true, + common.HexToHash("0x1898ece6bd58da4237abd319202941fe4300fb0224764609cc5b5eb95149d20c"): true, + common.HexToHash("0xae3fe2311ffca22dc42244b58279e402316e99dd02c1cae1a0b92cf4b1d93c2d"): true, + common.HexToHash("0x0b562978f3b4ce9f78cbfe651f0533c254123da01fef351a5729de9095262cb2"): true, + common.HexToHash("0xe3518ff78efb1afa66c1b052abcbbcb48ea1e1386ce0b33be03e2f87f323917d"): true, + common.HexToHash("0x044e97bf74caf83013cf14190474005d28d9d9eccf902bfa6b85cf9cb1e96ac4"): true, + common.HexToHash("0xa7558b78b75ed49b33d88de0558c15eeb1c3fa2197e5bfbc7343048d3bf49cbb"): true, + common.HexToHash("0xebef9cdddffc8f359a533865f88ce7fca2c08552ced75eca5f1875607c49feb7"): true, + common.HexToHash("0x66db70dfcbffef66c11b67d11ac3536cec642f666a6d5e939e2d317d065a6ecb"): true, + common.HexToHash("0xef4825d5e5207b4478cc120054cc92334b43582860bc55307691d37121d78e55"): true, + common.HexToHash("0x3355bea255db60c49565bb4626d5009e31db63aa750d3d8d4f162e80ab8ed718"): true, + common.HexToHash("0x13fd5087439b1dfdfd6b64dac81069f17ccdcbf1e8b18684aa01ad58f5555c97"): true, + common.HexToHash("0x6309fdba087349e0c9c59b776de060172c406fa5fb7b85a4187b0ab8e0b2e423"): true, + common.HexToHash("0x3084eba593d1307a77e01510128d8755520b8688293eaba94b98d41cd3291a1f"): true, + common.HexToHash("0x909756afc03c274942d2dfc245abc6c87dd3cbe446c36c72682205e01ba0683b"): true, + common.HexToHash("0x195596e7a7c9e23bd8b915c6d5180c4756e0ba27feb0c2ee5cee9f7b1a44502f"): true, + common.HexToHash("0x7a403ac31d225419fb675ba0e0300ee6e17c79148ce3bd9abdae4dd632f2ea6d"): true, + common.HexToHash("0xfaa79ce79e2be4dbb19b89921db465cff198472a9010326f1015b5041495a60b"): true, + common.HexToHash("0x4a9799da391f77281c5742cd14f13133311aec72dffb6457096fea2db25b3636"): true, + common.HexToHash("0x985038146108f48d929ae2cd212ee9824faa388969161f9a681c923e65ce6886"): true, + common.HexToHash("0x1d07031f587f20f258b70a68507bc75ffc00ddb06298a6461d0256ea3629e40a"): true, + common.HexToHash("0x967743871dd3f736210a1b8070a9233212714a90206c2b907336196888178f82"): true, + common.HexToHash("0x1a9ce8ff1a69d551baf35afff1adc7a96aee4c0e5e114b995db8802ae5e19b95"): true, + common.HexToHash("0x3740e3914391a3e199209b770456dac73e3a584fba4048702acdf0f04af240ca"): true, + common.HexToHash("0xccdb2fa5cb051e060c0be8df1b2ea7fda46d7a6ad67e4841bfe574068e2ea4f8"): true, + common.HexToHash("0x4199fb44eac1addc3b57fe9ed82b8e9d9c92522ed5b07bd2e7022fce05d1b802"): true, + common.HexToHash("0xeb2dbc7d7264f3372f8e10bb3300efa2a9e652014788e5700ee118c505bdc7d9"): true, + common.HexToHash("0x2bf3839f2803b811f7517b545c39d4c87f1c895b3f6207ba5f8b827ca42864d3"): true, + common.HexToHash("0x1a4021532bbb6cb4076fd78e55dadef3c4dd71cd79b16032eb85f7805f0dbe47"): true, + common.HexToHash("0xe38ce98192649d5be6b8df228973c9e5f827cbcf9f440c4f2efd917f895ebfaf"): true, + common.HexToHash("0x36bf0b42f387adb00c0992c69f7a49a1ed8f1908ac0b7f9b8d8bac3c5296f8ec"): true, + common.HexToHash("0xc2239e20dc40d31e3fcc3da15edac74178e81b54684b573df132294da76d215f"): true, + common.HexToHash("0xab6f8610d1dc5dcef6bd609ba00073569739d6b5448aa446c6eb51c2226dc101"): true, + common.HexToHash("0xcd6e25bcc1899ee213f5bad24de75952ec73aad008b7be64322a1b3521a5a483"): true, + common.HexToHash("0x5907e5903d96d21d5c582627ea63b56dbbe308bc5681937f16a9798834f8f373"): true, + common.HexToHash("0x943bb34ad916c353f9ca2f94d4585ed8aa078f4a90c8529ececf293307ace026"): true, + common.HexToHash("0x3356ca2610645f232214a5d285d81fb3afa6bbc925004dadc4061271982029ee"): true, + common.HexToHash("0xe032c831a3194af81ff7faa7e4da86be501f009c2cbaf45c2ff7ebf1b3cf6322"): true, + common.HexToHash("0xd0b30cf0114140a908ce4247c7be3afa49e53c4004c65b455ffb141c1dd3fe74"): true, + common.HexToHash("0x391547307fdd13568c49c185e3e55aa42b132140ae2bcd3823eb5c58de1fe9f6"): true, + common.HexToHash("0x6ad38f5fdad23b9b4acddaf5464504520494691b7410fbd8f9a633359e2f9c21"): true, + common.HexToHash("0x2e823c83fe8a3fcc23b1fde2439c0f07f029b2562a82a141c2950c963b2507e5"): true, + common.HexToHash("0x7ef085aaee129accd9f9d3111c9cdd39290473e67bf30653a19bf86877fbe177"): true, + common.HexToHash("0x99c6e501278cf434fbc72a51f91f91779c7395529618cf3d31d837ccced9c105"): true, + common.HexToHash("0x69009040100143f292b70a6620c14468139db36d6fba6051eeae2842aafeb659"): true, + common.HexToHash("0xe8d3aede1c0f4a18d15d8ea5b1773a3aa2c1efc36d49814774776c88e2626b7a"): true, + common.HexToHash("0x92c02a71545246e69277d5dbdb1f0c6f49eec1396ca6b9aacc5c942a11cdabed"): true, + common.HexToHash("0x6df51dce97e365ea026af46a59e169d3bc199a3884129228f41a7a85a5f7f3e8"): true, + common.HexToHash("0xacf4c857e95a89722bd0325404afe848c6ac9a708bf9319575583b8e8aa50cab"): true, + common.HexToHash("0x42cea7c58c6768f6f933a2d192e16b5a6af3e05cf6397adf6c55de261ec4574e"): true, + common.HexToHash("0x369f6a226b303b6d8ed6fd99f6bc3562c5d783b8d287608dbaceb00ba9187c34"): true, + common.HexToHash("0xc1f93fbe164bfb005a504a9e36f21d0e4383e8a5f7dd47f7afa530ddd43f6c7c"): true, + common.HexToHash("0xb9992ae7c52b3a48209f98a08d507f840d04e13413c3449c36d51de931e8b516"): true, + common.HexToHash("0x3fc56f6b63db5fb98b3270a892ead813cb590da3533c0c85d64d60f3c9033269"): true, + common.HexToHash("0x19ed33375d2e7619a40ddf08f662e9a40c0ca52a7ff391fcc227d17625d4cbed"): true, + common.HexToHash("0x640a6eab5512832d23ff6c365afd2752798a8e4c91ee5ea0d8240ab8b7765169"): true, + common.HexToHash("0xec4e6e70b3b03a07c2b9c9f11e90fb073c4b0902607ed8240ccc99853e99da8d"): true, + common.HexToHash("0x0147f3ec7720976ab484e3e7a0f6d1cefb1884b9a83b719992e0525fa3d0fffe"): true, + common.HexToHash("0xbb8856e796c417d8ddd4edff8e39e1cec9987b421ff36063260030742c279e1c"): true, + common.HexToHash("0x27d644d487490278f6b9efbb6e56b26b9ebb475e022a4c7459db1085d02bce6e"): true, + common.HexToHash("0xfc853ac06616d6d39a297844e3c15a5f9de4e1ad9fcc71ff35924791afa27437"): true, + common.HexToHash("0xd5b36262593ef679125bd1a4fe20290bd8dc25194da1c70aee9fd2cc69048c67"): true, + common.HexToHash("0xfb889e9a873e0c010c69111fd34d4ecfc888ab0f458984259ec11dad04e936fc"): true, + common.HexToHash("0x11db4c4adb9fa2f81dd4b87e74266029f24e313cb5090df3112544c0643b9617"): true, + common.HexToHash("0xaa6c9b21307b33439db4dca2f61a7c8ceee1685a746c4b60adba54d9b71a5ebb"): true, + common.HexToHash("0xfa6f46d512212b875495e16654513b83a14f0f689a1e04eb968e449ec4ece4b3"): true, + common.HexToHash("0x158c672c2918c73b2ee88e2b6f76fda0aa093d9098c5cc410c3982bcd3d9b882"): true, + common.HexToHash("0x5971a63de3bebcac284542dae482ed48cdeff95b493d5d4efb26bda84fd9281c"): true, + common.HexToHash("0x28a032ac6e58bcbe8a86470af96537a2e129c397a116a2a0bc095f497e6f6c35"): true, + common.HexToHash("0x9026c4d9f8d24fd415759b25562d0b72f18fa754e759eee716adece19e3d7364"): true, + common.HexToHash("0x16cbd43a5aa9c8be6f29f68f93eb6dd22d3dac9fe5d63703d03f35f6be054f7a"): true, + common.HexToHash("0x432dea776b83e0cb4bf2509e75526f835ec36516f1ec8cecf95e882b2d8a2f3b"): true, + common.HexToHash("0xff2ab2728ed4bf2428bef39817f982048bb4d9e578dcc83b63047b6bff1818ef"): true, + common.HexToHash("0xdfc8c04d7509f3c82386b1a357ee859b2e6cae595dc6d8ace8817c3a3fa0f02b"): true, + common.HexToHash("0x14efc2eff7740c3674c5ebe62804e5a4b29cf830c686345b6a31ee755a3179ca"): true, + common.HexToHash("0x7473432d924ec22e430f04c576cf5fa34be67bd464f4841c5dac642fa2a33792"): true, + common.HexToHash("0x4470d56749e75939f8ac6b3c39511aa5ff595759a044b1430f4f9413f54268b5"): true, + common.HexToHash("0xf78c19f30752fee732a2de16afa62b14129894e0a638dbd2660add4a1fb2958f"): true, + common.HexToHash("0x3ed5ce33043fb521c13b1eb9bc08a9b110a569f085c29e000207ab138a3679ff"): true, + common.HexToHash("0x52c91a0a9b2da7624e003bf7640f3d331a50a2eaf0d23c277850cb3c59e2fd7e"): true, + common.HexToHash("0xfbe592bfa6c39df1ccca47382e170f3cf7e0fbbc1ffc9423563f9da9926a1d79"): true, + common.HexToHash("0x7a084384e2aa1f94aee617dc0345c86604e659c7cb1ae0e06f8867ca83cc0c46"): true, + common.HexToHash("0x66e0bddf0e2697ce8586878f2ee050f231b5fa704c4b8dfe0bfb42ad8aaa4de3"): true, + common.HexToHash("0x59da4d3c3bb9e537f92e2af8c65aaf57f8b7e7bb849998593e2a109b3f508910"): true, + common.HexToHash("0x7b6769893aceed9ef3c0552ac1b20a91eb3daa63246f044507999f7f0a18c96f"): true, + common.HexToHash("0x44ce324d1af807fb8d69216863429fd13eaf329080bb998c75e492a85f998f41"): true, + common.HexToHash("0x07b3d37b5df525a932564e44f3dca094beb9cdfe8d6944a058b722ef1fadc718"): true, + common.HexToHash("0x0b714890050aef413a7cd52002cacaecb7d91636ba65407a305458c231729b5f"): true, + common.HexToHash("0x5de819c5329d5348eb6bccc6aacc560173c837dd265151795e9ef5b0b5b6c8f9"): true, + common.HexToHash("0xf23ede6368d599d586368d2c1623065f0733709fdeea9cfd04b450055b6747ef"): true, + common.HexToHash("0x70134e7363aa2b546b88faee95d04ab13a2bfc5f5be5d4b66a27e1b769099dbc"): true, + common.HexToHash("0x6c0d8d66e1d530b30ac765a2c72c8b226b82302ed32182d0a2dbfc760c2f0b42"): true, + common.HexToHash("0x451bacb21d1c02d76c077c28a0f0856994a04bd77c286625eeef5ed3b6aa04bb"): true, + common.HexToHash("0x73bac124f21183b44cd324864e94e34d26f9b5d93f6efafe4b4e288b410cf090"): true, + common.HexToHash("0x4d4ba124cdd757a39807b75e3e2c2b7325234ff16d4746e2b350891e865713be"): true, + common.HexToHash("0x8c56c13bd6a02eefb7d289454d0695f40c6bb6bbfe18c585701dc161d4898cfd"): true, + common.HexToHash("0x6890b2c2f5f39c7bf1105337c167739b3d73b7e1f55ed380f2dd44e0470df043"): true, + common.HexToHash("0x8625a39451fa5c24e0d90d4494293aa204e10f8af6cf309e4945e876ff94d17e"): true, + common.HexToHash("0x00393a2eb89a12f8c530f93312c9a58ad6698cad4282b2721493629d99cc523d"): true, + common.HexToHash("0xb2940140d46954522a4556d15ae172160ce38892059540477d7973a86e7d68bb"): true, + common.HexToHash("0x28ddffee219de23bb2f663e75a27877cee2037745e5820d314aa8446c34abc1d"): true, + common.HexToHash("0x0aed7a236fcebad0cc5b419234be9ec95cdf9970dd32fdacf057be8f55f279e2"): true, + common.HexToHash("0x7156e545e549b35c0b7d12bc9d60deac990672ddacd2a3b5b64bb3e5a9f0702f"): true, + common.HexToHash("0xe4a5b1b9d1c854ca36ca7d3d6be73e81254aced490c958e598d4818a50183df5"): true, + common.HexToHash("0x3b12cfbb9c84e12d9974beb5cd7dfb441d168a0812241aa2340af0d195381601"): true, + common.HexToHash("0xfda4a1c1e5091540db7de6f34085e4079bb57b4e30d9d3e473b2585b7c95d8d0"): true, + common.HexToHash("0x9a0cd4efaeffd86a69abf4735449f05806edfce6416bea8dc219f4d68436a7a8"): true, + common.HexToHash("0x84f4b80ab5ed5a359aef1ada905d68aaeb33ddd4eb187d6bf29d7ee66c1f6102"): true, + common.HexToHash("0x03f9b4fac006f4fe2a08a546f5d44c3a53c0c2645200a1ef44f1843dc59bee3b"): true, + common.HexToHash("0x49f8649901517694aa56a92cdf98655e9aec5b0d751fa03bdcd34b924b2dfcae"): true, + common.HexToHash("0xf936bacb6c68aea4d781b9d4b2ad1c2b3851fef35fc8b1184040b248e97369d5"): true, + common.HexToHash("0x3b7479238d9e304864475fc0b6f8da8c3f00b954618bdd69318f3ad885d56f75"): true, + common.HexToHash("0x338ba2f434b26a118872974660cf9ef008f084f28e4b637072a597d89cc18b42"): true, + common.HexToHash("0x6ecca98ec5ae235c0d6de2700d1ce7d4294c43eb91129a6f0371e29509a16a62"): true, + common.HexToHash("0x6934b821dfa4653a71145e4e37a70cf1287cb06e63591d0403ed086047d76692"): true, + common.HexToHash("0x7fbf9d08109722902bffe2a4b52b877e96b6e3cbb1b688f977996be4344254ef"): true, + common.HexToHash("0x0f70508e6637aa4aee80033311dc64b53af7a911ebbc9b0f7932f4e991182077"): true, + common.HexToHash("0xc2255904cc728b9bd7e33f384ec4a8328a0a670b8eaa84d140072645cc65c801"): true, + common.HexToHash("0xad4c89a25c656d2e993f9a1debc3470add074bd067d72a2703f61f02fd3e2330"): true, + common.HexToHash("0xae57bf7abf122f3b1f59393cdba184ea90b211dc0bf2fef82cf5461f8a84eae5"): true, + common.HexToHash("0x5caf61379c38d311db1d4844cb8a69cde1426ce11d95ca4e7056eee6dc2fe21c"): true, + common.HexToHash("0x7439b6c2d0f38668856db619e0275f9df056a34507a9f4135fffd2e5d1d5cc6b"): true, + common.HexToHash("0x62b9c3222745d1872bd10e1bc0eb8876a81bdba04cdb642a181a28458b05fff2"): true, + common.HexToHash("0xfff6b0156de4ff51cc9436e262d0ee890ec6138ab8fdfc35dcbeae2244dcca4e"): true, + common.HexToHash("0x80347df03ca499e4aea89e7df6d79fdc2f564a2ffae325880cb94edbc0d4cdcd"): true, + common.HexToHash("0x5fb66a5c9e59936f0ffd4f89b4cef9679d38ae0c2fd07e48249431a2df8e331b"): true, + common.HexToHash("0xc3ee58aa8e9fe04f9b62243886bf38f7b95a5f164b6d5c96380f7a8bc19d0900"): true, + common.HexToHash("0xdd57acb500cb28a1c78981165d2e2c9b3690e43b687e8fe2f0a5f5646ab09788"): true, + common.HexToHash("0x96ade93155baac7dc88c415819ef324183b0756ecbbeecda91f2a20417939de4"): true, + common.HexToHash("0xbe7066246bc649e29a58b48300cd991a389ad91321ccc9aa970e32d896717999"): true, + common.HexToHash("0xa8c233fd8d855acad2d5cb44fc45eb77bda28e7f56a22e55ef5bba7842703d3c"): true, + common.HexToHash("0xa58bfd752f060dbbb26f8301247e1fc4586950c75ecd24e61b71de483729b106"): true, + common.HexToHash("0x9c1d135f107a7161d8448425c66f755d10d073b5efd02175fcd806ab545d7dd2"): true, + common.HexToHash("0x553ec768b2f41cbf513225e643c614fc52a482ee65f67120494fdf516b692882"): true, + common.HexToHash("0x6fe5e85dd39ebcdc1634f4f4c06fa55a80595fdab408199ef1a44f337e673d92"): true, + common.HexToHash("0xb6badd4bd47f24c7aa182c5dadbc2e058c9967fa598c52477075686f67619627"): true, + common.HexToHash("0x71a7223918acb7c96856ea93a2cef5ebc8a51b833f86a925ee62ea1bb0153711"): true, + common.HexToHash("0x04df70816e19137e306e21f807106343755a28efcfe156ed0d185015fea86989"): true, + common.HexToHash("0xaf7515eaa6b766b6dbfbb2790734888835531e8605a5d762497d7ef203bd01b0"): true, + common.HexToHash("0x37f410f46e8179224225431e8bdd42b83dfa5ea559afad6e797d0931dd8ba375"): true, + common.HexToHash("0xaa799a081ee503cbdc1a92d801b65f0a1753162ce3d69764e84b4ce5446bc4d0"): true, + common.HexToHash("0x26210621acbb309c64c89fa872771b125deba57f77e458d44b67ab8ae154a27a"): true, + common.HexToHash("0x8e3bd1f219ecf7c216ca9b614acabff251b6989ef5aa1f6cea8f7086dfe5886b"): true, + common.HexToHash("0x3c10e5e75cd95e2c08728f039d024d88f05d5e03123240dcb4cd1dcafdf9a00f"): true, + common.HexToHash("0xc6f9969cfca3fea6ce1452f4d3bdf07cbf9e5136f68cf835a4d3f50bc5c00ce6"): true, + common.HexToHash("0xa00b83b6d211298db28490623085eb3cbaa21e8d5e2916c34c0cc7e6ade36257"): true, + common.HexToHash("0xac847a7a1732b434f4d665e11f763908e2ba323328772f1d31fa4ef8fc1d7571"): true, + common.HexToHash("0x17249025c33b6e8feb9be4f0b8e48ca678eb052c1a5c96f550016788320b2784"): true, + common.HexToHash("0x1085bf9180610d9e386527e00ad3ace0db67962df4eb79b39e856c5d8dae59be"): true, + common.HexToHash("0xeb093274d3bc321cbc55f9869e30ebe2b006f9ca53e9fb8b900bc5db6815cbf8"): true, + common.HexToHash("0x299ba9044c17e79b604b82e9be6625ac5066ea42f7162bad8c1796d3011e9923"): true, + common.HexToHash("0x38804d1448d903338d5d1e74c5cfd0b21bfc73c7a876a6e9829f822c1e26355f"): true, + common.HexToHash("0xe7ab5c174e2fc3e314f0dd2dba6717eb60f2295669420d60c8533c741b8e6662"): true, + common.HexToHash("0x512ced3109a24fd0b0a005d6ae25d7f69cff987149b07c342ec253e1ef35b67a"): true, + common.HexToHash("0xec5eb4d0fd2f79ebc1d6c38385921243d7db5196d2d70a18c6c02f1a2e665ade"): true, + common.HexToHash("0xb4b71a9dac766b368c2d2414af49ec256dca244f13f62e2edb6c7ae6364a1acd"): true, + common.HexToHash("0xdbf5a5e5cf82a943ef0152518fa7d12140bf15f61899cb50a08f17e2ae5206dc"): true, + common.HexToHash("0xeeb4b8dd6074684ae8250cb3fb33a654df24eb407a5d989605989e49075456f5"): true, + common.HexToHash("0xafb70182ba4be8a48e89a17c5fd3c19706045d57dd51f3986a171bc125a2078f"): true, + common.HexToHash("0xfa02542961ddd1fd545bf06d56df1bcbc2b657af9acb2db8cef7cbd342f23a17"): true, + common.HexToHash("0x6a585be83401b018569997e8e905e2dad22b206d6058ea116ee1d3ab8b12ab1b"): true, + common.HexToHash("0x27a4edfc3a3590df5419023662f17a2f200a18c0095d8c052ab1137dde034187"): true, + common.HexToHash("0xb84cad2a56c10d9ceca328b9bdf8f5ed89aaa2f893589593915aef06b25f3688"): true, + common.HexToHash("0x7bcf06974a43b97ba187d355d97118f5b049c57516c6dfba04afe650cab98a76"): true, + common.HexToHash("0xd120f26d51714431d91b99ca59251bd89709fbcb0cfb64301918ceae5d9e3baa"): true, + common.HexToHash("0xf886d0cb9926b8461edb6cc41e62aee045744bfc46ec0b02cc17ffbbf2fe7a55"): true, + common.HexToHash("0x575a89cbdcc21058e8896ba09f7b4a965f6021f7d4f2470d379363d1f7c2f1e2"): true, + common.HexToHash("0xdccbf0c857db26ded59cf02103caeea56904c1c8d4ab97fa5dd2480904648ad4"): true, + common.HexToHash("0xee164812d6ac5619cc9dbdefca658240ee4bd3c3cd08d757f58be694706db2a9"): true, + common.HexToHash("0xb815fb3050889779bfe822b67dcaaf2ca309796272bfdda5aac460570e3d2681"): true, + common.HexToHash("0x6cc8f0e79629743593c347ac490ea38aff56515c57ab3e40742cf0fe1aadb199"): true, + common.HexToHash("0xdc860422feeea0b48df3b788063304abd9a211b760fee74d836745ace8d2f894"): true, + common.HexToHash("0x2dd209e8265dc08b91723d18939c14b00c0e9e604ca950c89127b32fbbd99e87"): true, + common.HexToHash("0x333fb6dd91ddc2dc2a67c0e5cc30dc7e4d585061f409cc7e07ff1a7afa5d0729"): true, + common.HexToHash("0xda41016164924ff7015d8017a06300eae8e1b0a026e3ccb77e0119169f77326e"): true, + common.HexToHash("0x7b9e72814f5f3a2c776acdd665c06ddb3f6f584e4afab36371266bcf4fc456c9"): true, + common.HexToHash("0xdd9bcb657347a4f7cd230393ccfb1d617a9419f3fd7f2a052280cfabf0514499"): true, + common.HexToHash("0x83831e77d1cd6f4c16464b7f001956fc312317d6af96eb952047701f7b36b503"): true, + common.HexToHash("0xa51d7f8d041f0e93f62a8799da41c82afa5d9c171f3c9a7ace36836422a05703"): true, + common.HexToHash("0x61b7c403441bfe3bc819c272a58c8aa4a699a794ac21415be9095b2fd48affdb"): true, + common.HexToHash("0xdc7792b49390d154d3e7681c8e705275d57203d6fc6668fdd48d4acfd9cfebf2"): true, + common.HexToHash("0x487bd04070d56e6a2092f56da8f254f7298233e27fb38ca215132d5f2059d161"): true, + common.HexToHash("0x1b19612a272000f3989256060c49f033fa5aded7ff5e368932f168dabda189a4"): true, + common.HexToHash("0x6572fdeb50f08d2cd51e616938cec1145be9e92c6b92e8272948f7a2022cad56"): true, + common.HexToHash("0xcc126834491dc2f656fe9a76bfdfb0692b8b27ad090ba6456fbab411cad873a6"): true, + common.HexToHash("0x922fa5c17a2b2509d616b836aa3f64b35fde6cb8702570b9c56ee42526be8e5d"): true, + common.HexToHash("0xc76723c8a156fbfaa94d7b6937be8be01071f31485fde2cac8cd454b3f8ce141"): true, + common.HexToHash("0xfeb12c23d4cbbd8e289f2e97ca79db018ac6f8ce96120759b9707fabadd70d74"): true, + common.HexToHash("0xdfeab294d007873f208d001a2618873cd8d78de6597ad4392367caeb1a988f9a"): true, + common.HexToHash("0xbeffa0ed8586fb50125f8dec2db16f5de98bed553cd348220424a0cc10ed94fd"): true, + common.HexToHash("0xa5995a7845207f5583875c0b6b65f5bdaf671490bc3bc180c46eff6cf94576f3"): true, + common.HexToHash("0x89b9dcfb31df7f62df2ca7ac9c0b50a8ddce28edfc347820efc7543299c81787"): true, + common.HexToHash("0xfd60eb99161da73dfc2f65044d5512f05b4fa33fb222f2e7d279602e1e0c5244"): true, + common.HexToHash("0x3816d8b833dc827efe1f72f927eade82d85a38637789313aad8bc7cd6046a2b5"): true, + common.HexToHash("0x0024f0f6aba2c884448f0fdac1de09f0b4ad24c1f5392663187d07fb2ead8ef1"): true, + common.HexToHash("0x4f79e5b3c82648b70b1c85dfee924ea925fdb5e91780f06564df0c2cea250881"): true, + common.HexToHash("0x7bdcde11b367c5720e309bf63e711764fcf34b04575f6999ab9abb56dcbb545d"): true, + common.HexToHash("0xb494f71b174dd79e21601d6f6d3b0a1441c38857ef016b0871e8204870761c66"): true, + common.HexToHash("0xd6b8715490d6d83e742c0e64a1f42897a1e9e4fb14e0d68ff310a9487d5f4bc4"): true, + common.HexToHash("0x23c10123790db1700cb2caf4a4959de59da38fcbb5b9939d18c6547320d08b60"): true, + common.HexToHash("0xc9ed0b5e6d952cba3b78252cf8828d502347fac7c004bb1cb05a283e8a56ea7f"): true, + common.HexToHash("0x391d431aa143fda86bbec8157a419769b6bbf472384dae6aa633d5e12f89467c"): true, + common.HexToHash("0x0d2767ae082200211524402f9fe0591b6f77dec9fd5cfe4288f83be3762de262"): true, + common.HexToHash("0x059bc8c09b1690a35ff51630c3aa0e328d22279c0e2fd7e42e2fe3d45af684d0"): true, + common.HexToHash("0xf8d64e7271a8088a7b31b54717cedcb7ccaae43f5fbf61448805bb352972b678"): true, + common.HexToHash("0x972cb7d0367d48863a9514af449fde6cd2ecd3ecfdbc4ac6d1dd56689409432b"): true, + common.HexToHash("0x1222b65603a1d8910ff41b0b38db03b01713f9042d3a51dbd73650acd568a74a"): true, + common.HexToHash("0xb8e540350eb05190aa53c1fa52aca3ebcc8b157f078fc0af5dea2e0967682a9a"): true, + common.HexToHash("0xd838ec67878d2651d87b0cb8cf04829ef28b1d6c55310b92a21103cd489c507f"): true, + common.HexToHash("0x696a1cd8fce1124c64310cdf045224a15ce7810649d1809d9edcb267ec827218"): true, + common.HexToHash("0x221c12aed660df471ab1dbb1f9ce4b072fc3896ad5cdc919e724169987fe32d5"): true, + common.HexToHash("0xb3c6281dbdbdbc86d38e8a438b257da652088199f490a06744fe0aa66d53a9bd"): true, + common.HexToHash("0xbb1b6528ceb997c01ad469d6c8c61b656bd70b9ecd10dc6d91fc630ad02782c9"): true, + common.HexToHash("0x5d2e9cbbc948a1a33f3516783054b5db6f0717d75c605a13bf399553eb391d5e"): true, + common.HexToHash("0x6afdfeac81e9a3998833a387cf7e1f29d996d1d4d421127ec1fbdf4a91c00976"): true, + common.HexToHash("0x73e3afca48e98524fe6926fb0f42b8ee7b8186b235c9a49a0726a5d52a2538c0"): true, + common.HexToHash("0xe865323118477dbf00549ecee8e0b6aca6faa5d74d4d000fcd05e715cb77697a"): true, + common.HexToHash("0x3ea9ca02389fe619d6237ab47a80742b70a845306c84d76d3fc54dc87f6af4e4"): true, + common.HexToHash("0x4f39282d7884b8da92892a0c9aa93b7cccc27231a69b6488582769ea09166e12"): true, + common.HexToHash("0x09d02e4d117aac77dae5872c9b66549229fa899989c4da63458aa7d600087a33"): true, + common.HexToHash("0x246aa3f7fca806d265330ecae35a56e9cf7d8ff9539485306169dd38f0f42bc9"): true, + common.HexToHash("0xeb79bd979e384974df2b046c0ea816bf1ad1937aaf1f3fb5a31d2322d189785e"): true, + common.HexToHash("0xba9950c0eb88bb4243cc925517250e44c74d39a746749a3f8780acdc000000ea"): true, + common.HexToHash("0x6eef2864c9bb8a92b50f711cda610d41941950e1987891a1877f60343a651986"): true, + common.HexToHash("0x5727edfb3f071878c7f3a95af56e060f9a49a04f80a30be4adf26b1b86abdad0"): true, + common.HexToHash("0x6d455594292eeb367303feeac4229d8cc0ba8c1927dc75a154f6ce44c70e2487"): true, + common.HexToHash("0x47e542e7e63783451a7a6fe7393b8ee9699b2bfbc1af1d9693c368f45c8e643c"): true, + common.HexToHash("0xaad3a6af1f6a4773e580fe59b977442eea25c35b7b87a3ffb2e1246ba0bd2135"): true, + common.HexToHash("0xf2bcd1e1e1ab69d51fdc6090ccb3526767a17a0dcc25bca997d9b6866bb46b9f"): true, + common.HexToHash("0x11142c69c85eb7851f4886d82bc87faa0f656419bf86810ec251e1f41a4cf753"): true, + common.HexToHash("0x7db8a33fd4f1da761d4c0d5bd440f4d40701b16833b0ffe1fb2b979316f46874"): true, + common.HexToHash("0x724b9db4ae30458d49d1bc00734828e9442e5e7361016e76c0acdab0a0c743d2"): true, + common.HexToHash("0xda5403b320988d57fbf961205c49769e378b1ac5e8d6d051d6b5d43babef640d"): true, + common.HexToHash("0x041c30b4f4afda8e5a17bd55b4a4d2f657121444f9dc764b7455977707ab6743"): true, + common.HexToHash("0x30fa5999c31174d937f5e347a1c3431b069880e744330a8eaf7067f9df3aee7a"): true, + common.HexToHash("0xc78a78d1fcf39d204bc5dceec3b6d580ec047c02d5ceb05b20396d8dde968f10"): true, + common.HexToHash("0x1b0641df30a7749bf83977571f4ee65543e608d89d80b86419b98e545d21c915"): true, + common.HexToHash("0xb5bbe66f4fdce980aee76418b0f7ba671532117fc70e9db1a29ac5bbef6bb606"): true, + common.HexToHash("0xa63e4190d2e3c48c064e81ed9fd0b151644ca6f50166918910df47c2fe5dcd9b"): true, + common.HexToHash("0xd891d36a0e0681c970fe0d3279e5ab6669fc933e13165f5b576a8cb8651585b1"): true, + common.HexToHash("0x9b5eea49817bf63ad0d01387514a5e8b21bbb7702e1e3965552663608bdcb1c7"): true, + common.HexToHash("0xeffab31303c1171d54428ec69c6473a23825c31ed0daddb1c24801bf02d8ae50"): true, + common.HexToHash("0xa17089a774cfa183841c63980a57f1bec3ac465d247d991cc47235410e07fd48"): true, + common.HexToHash("0x7cf14f34e53eda59f704bb8ab9f660d04b424b10e638bfac0c27642517ef5127"): true, + common.HexToHash("0x974af38809280d57adb8cdde5a8c8c5518f33b97c9dfdc028c509de28d0b972e"): true, + common.HexToHash("0x868db0499812a0427b5175f86c01f9a231d8e20051b61915d2af0cee6d021b7c"): true, + common.HexToHash("0x297c4a46a3afc23682f71dbeb227a393af111d261b5c5f576f93416e20ada070"): true, + common.HexToHash("0xa58c417048dff3ef1e00ecdb04c4c77bd74381cbceb9298af4a6d47791feb35c"): true, + common.HexToHash("0xb4d159776aaaf9c23eaaba18dac44a94575bf87516d4f90406d57ea75e62be2d"): true, + common.HexToHash("0x7d2c67a959db136f8a8d733f3bf9dd89e5acc0e40664722e565ad7d52dcedbb7"): true, + common.HexToHash("0xe2d203d9368ede8f7ffe4b5228a83cac3233662978aee2101a553583a7fac565"): true, + common.HexToHash("0xc1d196b59ef735eca769c57c8f4b9da64f309c88deb496b3b75ceb06f9db0c83"): true, + common.HexToHash("0x982974a6214d38de9f316b0be0defd9b64bb6aad6cf73aea9867dc4a2405a27e"): true, + common.HexToHash("0xeb49edf63da6d240502723048c19072a86bd62617414aeb69128a981d7ede481"): true, + common.HexToHash("0xd7007ca16431db426f59b135e0b702571f3ea5985ce2d7909ac018f839bb69f0"): true, + common.HexToHash("0x024b9c135c925c20db2a90a1ba0a63e042ba07dacec760f74930371a62ac38ee"): true, + common.HexToHash("0x8d1edc0b9370e7626912446bcfaf82c95617e996b69043199495f253f7f0d9d5"): true, + common.HexToHash("0xb84252c00be2f06a0362d756b47c1a22121592f8352d209fc9f447ba84a0ef1a"): true, + common.HexToHash("0x759a8b68724c2eedb8274991520f882cf242fc924ac873c206f88fa5c4f7b17c"): true, + common.HexToHash("0xf427aeea87a4870415fe888f76759723be2c837bbab152b55b20308aa87f5736"): true, + common.HexToHash("0x192a9249ac0a576d2765c758e5bbfcfb2e11f2b2005c3323839f399150209802"): true, + common.HexToHash("0xbee73f4a85a4e4d83ea1bd24861fec2748178aa068cbb6ecb0218d16fb0110c5"): true, + common.HexToHash("0x2dcb63cf965723bcffca31416e1d23f0e09e3d445e7f24f7d5d7bf526cd5e0e5"): true, + common.HexToHash("0x1dea15f0cdc02a12a8a5565d436ddf6d091cb635adeaafdca6ceb6a67608cb75"): true, + common.HexToHash("0x77ac5419eb5b8b7be01dfa6e801a3aa8f740a83f1c582e1a425115d0c515153e"): true, + common.HexToHash("0x6c4754396fe2f5046fab17504273f5c59e77f50237bd117eb69a7a25ecc2461e"): true, + common.HexToHash("0x711331718c057c6dcea0c831bb0b2560425dbf24a44ac758cb6043f796105aef"): true, + common.HexToHash("0x5785b16c79d32b52df6c351585c3ee1d7112af28ff016347344ae96a5a58dfdb"): true, + common.HexToHash("0xa5f48ea7aa731e4f51357806fa581529fb569293cd2dd7e7b75189551c24149a"): true, + common.HexToHash("0x6f8c4dfa0af34435210db6028dc839a723415809ece103288fef677d181f8657"): true, + common.HexToHash("0xca30cd460c6454f8870cd4a3df1de4ca5236edff21168ebc8fedec385317bade"): true, + common.HexToHash("0x45f72ab8e5fef11cc3210e39e715e6271ed453107290db978767f5615078c01a"): true, + common.HexToHash("0xe616c113557634c0114729abec7b8be66e3c298d8bfca06f74da5182efe658bd"): true, + common.HexToHash("0x1c691a6d391769a481f93546ca90ad4a166cf45fc5683c7c6786877a9b9f33a3"): true, + common.HexToHash("0xcc8f526e6fe12b4d3346766682851f2f9a88d280393df1e4c174fb339e746b27"): true, + common.HexToHash("0x1a15eb5b410420130b842618e5905ebf8c9d09ca1271b6b0be7fc93cdb073794"): true, + common.HexToHash("0x8a013d0e912edd4c605e21bd1c87e1b7bcded39355153a1300973d341351578a"): true, + common.HexToHash("0xc0bacdbe1748970442f8e34a5990d268991d51a20f6b1b73c16c209f360a74bf"): true, + common.HexToHash("0x33f1a13622a26c73a41b90d777b06f1657bcd61534962cc511bc99df7d4939b8"): true, + common.HexToHash("0x22a55900eadc7e48c1da8f8f83853897d3fad73771fdeb9e7434578551858b24"): true, + common.HexToHash("0xe723f489d3a1e6a140657ab51fcc28f5b23aff63e8ef685a05071037286bec6c"): true, + common.HexToHash("0x790aa08be9dd50203b3083affcdb0d5a354988c2f6cb4b775c62ed23d6d0072e"): true, + common.HexToHash("0x5e581cb8cd192f3b5a7b505886f7558d4e3b912171cd0835162cdd8e814493ac"): true, + common.HexToHash("0xb163fcb6d420e5933f5e4bb3ee1f35a20c6539853e848c72ed1207e1ac58d6a8"): true, + common.HexToHash("0x67c0ca7527d85d40d0c3d7c1eb32eef968db9741877d15d7a85cbf4a04105ca5"): true, + common.HexToHash("0x617d5b1c1b015c9b22bd82a5f1e8b50cfd94f7e9e4468211a5d8639d56dd0145"): true, + common.HexToHash("0xf176026487d9917949bee9d058cf759a92c56d9e398f02b37d04511d0d63d071"): true, + common.HexToHash("0x1952c52139dcb8df909791ba887953a24730dae08ab2d4148c1610ae2df02fd8"): true, + common.HexToHash("0x9c55db68a2c0da19da9288cf0a1a6c9ac38ddffa05a5ecd9494ff444d9fa339c"): true, + common.HexToHash("0xb3e49f9c4beee0d8c624a808086a70bd629b4b8340edb871938e991fbbed0eb3"): true, + common.HexToHash("0x029cde931f441324b6d4b37df3249517ab0e2e9430e49986e88146768204a509"): true, + common.HexToHash("0x9f7b0cd0f63b41d24d6e2dd6018b4e588b7364dcccd14e76cfd160c248f6fb80"): true, + common.HexToHash("0x64381ebffc3da66088552ef76de0abcaf3a224356279f4bae96313a7697be26a"): true, + common.HexToHash("0x32d91ce3108b14d6becb0d2ef396dac2623e79c3d4220d953d4bd2a7c1ac71f5"): true, + common.HexToHash("0x6198dce9ad611d847f95f09b0c01cde678104e836c7be4d0d44ca49797c787eb"): true, + common.HexToHash("0x235bb372c5b34557e719ec47bc9d56f3754b37f2c9785f19003d4168441a5520"): true, + common.HexToHash("0x2def11aeba97566f1bc097214ed8e82d82d3b673d8938e7c0e8e777f5bf2f93c"): true, + common.HexToHash("0xed71d4bdcdda392ec9bb1a5de51bf88fc5644b97179e9cad025378c8d5ee61b8"): true, + common.HexToHash("0x6f7526eb5664d360a702774e14837ab75a7020673f38242e8529dde57251edb6"): true, + common.HexToHash("0xf0d4a19e13995c5685a9559a22610c600a11c796c2673dcc536547024300b670"): true, + common.HexToHash("0x031555b26ed1142e385ee8b233e5460b943febfc30276d9b1e72a0aca7e89786"): true, + common.HexToHash("0xbf196f4cd900fe941b8283e37772cdb8c63695421ff67bb1191541cca171ed6b"): true, + common.HexToHash("0x940f4c07154e3fc9bd60a171540b16dafaf0a7271f5aaf5d3e464af66e5bee15"): true, + common.HexToHash("0xbb201bb0cfe307fc23a348f5ffab86dec9964753d066d2ff9d84ff1ce0e5bbc6"): true, + common.HexToHash("0x8d25e7ac66d9247ae3bbf8594532a7e8b476aec1ccb206fe82edb3fc77fba604"): true, + common.HexToHash("0x695e7257fe93a65f58bc4275e24d9a54d75b23ee4417dc2293697a9af052e15c"): true, + common.HexToHash("0x81d11276260040c7af1d29bde5256aef323bd027c99b23fe943439f0ef8602e8"): true, + common.HexToHash("0x09528e7c5ba2bfb3ef2a8f42681adb3fe3974d49d980b75175047a8d51bd79c7"): true, + common.HexToHash("0xbc19a5842d5142735dba44e1e604a2cc6cde6dae48ccf45041e24768e8c10d37"): true, + common.HexToHash("0x1d033fa93708122fae0d6801ed3d0676f4ac220f5de8cc5258c943da88672c7f"): true, + common.HexToHash("0x958dfbd4c5846ba919d8414a669f676dbba6f428237656b5e12d8a0d4c2a8873"): true, + common.HexToHash("0x7848886724f915dc7d0dbadb8947046b432eaee50959fea29690762dbb1af5c1"): true, + common.HexToHash("0xc5490104d53c1e87368713aafa26325609d4eaad70b4029c5d5badb8e5b90162"): true, + common.HexToHash("0x57ee37fb595da7aab7b4fd3f9974079311ef7e02b03da66965c4301afeb700c4"): true, + common.HexToHash("0xc7e05ea4bccbc7f879d0301425852e4561f5b8432246b1d97776cbe63c788a09"): true, + common.HexToHash("0x77ec19ac23a5865d437f60045ab5e0145868bf8d69f4c992d0abaae469e49ae7"): true, + common.HexToHash("0x34ae5cf65866061e7bfde5d5a1882b53ba0a8b3598988a631c8fd332894b53ec"): true, + common.HexToHash("0x9e27fbc2f14de9dd681d4f54af0d796d6b8e06657532e56f424605d30611f36b"): true, + common.HexToHash("0x56c3de609a93040970ea0f05f84b2049b8d78be289fd436cd870f639d6251ec8"): true, + common.HexToHash("0x0a6ac01ce1454c05b02a370a494e82ce6a366418a177b67610402ccd78533ba8"): true, + common.HexToHash("0x325702a48257e617a5e5ba3e2a6e3e13a0ce297a2905edf7c750bc7069e0fa66"): true, + common.HexToHash("0xfd58a15263ddf7783b81c7640ac86e720139e581f542748ee734fa55f4767331"): true, + common.HexToHash("0xc0ce7376efd893301a8717d3abcce4c17bfe50c829a308d3182bca97a3cf6b7d"): true, + common.HexToHash("0x3dae6c58d7f039ab2f41be9a06cd81516064314d5717c70bfa44026dd77daa98"): true, + common.HexToHash("0xf90cc66c2bbaa3a9581c75920b044a9a534057e57130415c144034c472128f97"): true, + common.HexToHash("0x0d37c04f572e5ffc5355e764b808494782c6860ba1195293758d352d12f01d38"): true, + common.HexToHash("0xc785313ae8023204c1c0c9ef6fcb8f45f40f6d231f299056a2e75ed025fc0688"): true, + common.HexToHash("0x6ebadc5a396522dd7bfd5b56ea64a3e42cb7fb24ee6bd53f02e7ab92b71bcc74"): true, + common.HexToHash("0xdd8e78f0eb743eb57f703578118c90c6e3195f08fa9d1915c38c5dbef5f1a781"): true, + common.HexToHash("0xa71f71b357003a8212fa518d04353cf4db4ec14e532ed7bec9ac0f7423895bc6"): true, + common.HexToHash("0x542901f14163de24de5cfb00c6ed4a1bf2d9874c79520dcdba181422e3623b24"): true, + common.HexToHash("0xcfad0e9108edc69814107992253039c7bd6506c6c5e71cb2f3504c7e8aeb5ea5"): true, + common.HexToHash("0x7873b6d252a6d0383b1d72ce7ececf9c6b202a00d75e58626b29de81559b9742"): true, + common.HexToHash("0xaa761df4b9d10a8889c97a2ea0cc2882e0537bb23e00ca86a012e4658662a211"): true, + common.HexToHash("0x2aa19582d25ffebdba7176c8bc69ffc02d37ab2c76a911623b890d6760adac2e"): true, + common.HexToHash("0xc42c8a523dc3afffecebff79f523777e58bb9945964cba1eace29c7cfa3b2ef5"): true, + common.HexToHash("0x5b3fd629e4f92ea12c949e9a14ea5dee55679094b448a6ea4b89e0e578660f3b"): true, + common.HexToHash("0x5b11020e7c4d91c8e9acb184f03f612bc8d95e5f49e9a77ad50fd3bbd6bae719"): true, + common.HexToHash("0x6c9b5f06b0c3eaf9411c9251834eced981a345dfecf6507e16aeaaa900dddf74"): true, + common.HexToHash("0x665503d454e26506f69e49c08fd09dde8515baeaa0c6bba98b41ac6dd3c0982f"): true, + common.HexToHash("0x7d56ea1d5613f5fed12adbb97723650f231ef63299c46e893b3492b707385c53"): true, + common.HexToHash("0x81bf2996d377278228f179ee9e147475a4d5655c4c7a0a48ada71b9ec0058087"): true, + common.HexToHash("0x1983bbab9761e65f3c7c1290b18085e46f1d7cf822078481fe776df26632bdd6"): true, + common.HexToHash("0x2d3d3fa7527f53a2f890ac46fd816cca70aa53f6a86617c489d45880d1e0e9f8"): true, + common.HexToHash("0x5a3ab0e3adb875e8646f8f87c924326f73921dba6f2435c7d7ed9ad0fd0e97dc"): true, + common.HexToHash("0x21c642b1b2275b2f750161e8f8b19e35e897c5d187481316bcbc6d26ce1173d8"): true, + common.HexToHash("0xad7788bdb8e477716a28de1a8b2b6197a6c1f165db7e519a27525f90b8c5a2f0"): true, + common.HexToHash("0xe33e65bdc3d05ea9aaa8d79e20766ad113c419acba57267f123bcd5c8ee91478"): true, + common.HexToHash("0xd671fc75b70a367c5c5904c9e13a5537dcd90e193fe710c44476fca2f396e534"): true, + common.HexToHash("0x75a8a5e56ba5147c0eae9736b549af50051f4340aae80e8a717a6b6821c83dbb"): true, + common.HexToHash("0x4799b1b30e7f43b99b7e5abf49a565c8610230448da5f75c3cefc917da362b35"): true, + common.HexToHash("0x5053b8087b27d598285aeedb2936fe661c593bd20223ab5adb52811ef8a87b9a"): true, + common.HexToHash("0xe94818fa05f25502cd91cf766a782e5af83ac22d550d3a00d0e2d9a2de409627"): true, + common.HexToHash("0x6acd4f5726b3bf7b38614212926e1bf7ed2b573525e2bd8187396a85b24614a8"): true, + common.HexToHash("0x449c7a555d7117f496e4c4e661b403f559ad3a1650cde0cecfb9619ed1eb5aaf"): true, + common.HexToHash("0x6f164f06cc80ff2876a99f5746d39d0bd6a76b00597e7d613cee87aa67c1e61c"): true, + common.HexToHash("0x11d6a6bd3ecf48ddd68ff9ff8167f413487c8b52e87152ed28998f228953cc38"): true, + common.HexToHash("0xb8cf907915844cc9022e58f779580e8373fc12174f257576e470b9089ac4e9da"): true, + common.HexToHash("0xe1b576d1126e5c38daf675949c7422f9b625bb5d134c66cdf3bd29049264154f"): true, + common.HexToHash("0x38c0af22a3cac54045002ac61c85324e8d5132637b0c1cc757562223a67c185d"): true, + common.HexToHash("0x3e938264194f5bf4c8a43d5d9f41f3add2508a5c7e8b22944b26f1257e78a516"): true, + common.HexToHash("0x55ab90fff0d5f869360e4d283d5fd058b7d02e4751ac8ddd45660e67cb21f3e4"): true, + common.HexToHash("0xb2d5f2d762dc240351cd63e46d91a5d3d5f180931e140d338313439e615ad77c"): true, + common.HexToHash("0xe02df8861c0a107f18fad833c66eaaa1f340d31efb1555a4351cc781889ddabc"): true, + common.HexToHash("0xa468e6d0102e92d16a653918a8e2334c8248c46eea6ee9bc32e7078a6a3e431f"): true, + common.HexToHash("0x49e3c69b16fae060d9db400df177975f0fd7bdc9b87252e79614d976ac5e74a3"): true, + common.HexToHash("0xfc6dce2e6b150d9cb63772784892f69a189813f8c3c93473dff048197614f645"): true, + common.HexToHash("0x2eedf22cc3aebcc625c97e5023069fcc8b9800f8146157f826e9df5ee83acb9d"): true, + common.HexToHash("0x1b6c74506644f5c3acb2d976370ba61032d85d6d142ebe9e931b0c8c0a0562b9"): true, + common.HexToHash("0xcac6d3a18486a3a15f25170dd04b1402ccfe3df5e3910826ee9d4f963ec68bc9"): true, + common.HexToHash("0xf65c035eefb0c63ad60e66cb6ba78110cf956a898b10ca587dc42ae8cbf2bf0c"): true, + common.HexToHash("0xa31a5bff8c86a868c46d5973069e2d270a38b630ac4193e7713f31c22c4b84f1"): true, + common.HexToHash("0xc35ea896ace8f0ef1c6dba752b24ff8ff67320b49baa86322b87d44170b92b5e"): true, + common.HexToHash("0xa1bb67b7960c5f2bf2b588b17954ba1b1b99a15209dcfd8fd3cf4e2ce00c9188"): true, + common.HexToHash("0x706d7e37fd764ba72caffabf07ddec81dcfc701064f08d5ad3f6e51a75afbe8e"): true, + common.HexToHash("0xb6a877fe8fc7fd24ddcc5fd3c327fbae7fb004731338a4f01ddc3afb6c9f9eea"): true, + common.HexToHash("0x98d079ff9332dbb1717dd6827411083af2c588b5c2a87278c2889dd7b5652c17"): true, + common.HexToHash("0x87cd8c7c89af491d93665a65d0f3183f06a7fa9cab1ff903dbee8fad776ad83f"): true, + common.HexToHash("0xd985e0ea7d79752349e125f08d26cd698da1f758027209bae80565be579a0342"): true, + common.HexToHash("0xd7c4c92a7745ffae3a2e37434f1a375f0a38e28fb01ed4bf47425aa657e1f347"): true, + common.HexToHash("0x6137b0912f4d2b670940baf01999c470aa73a3195007fb55b17d081e4e077028"): true, + common.HexToHash("0x689d1167f8ab05216e4ff02dd1f7c1ef960fd4ebe9401ca608a638d3a187718c"): true, + common.HexToHash("0x306cdd1b9bfb97dbce1a8fa1d0ab7168d711c96db01e43a3ded99a7ab663b429"): true, + common.HexToHash("0x23f09d46c79df443107e56b7a09ad6c3efded23b958617a5c1f956acb705a61e"): true, + common.HexToHash("0xcc67a6a36c2c84f8362facb887ed33f970373752b0c32a0ff04576c65746f952"): true, + common.HexToHash("0x7b52139110e90f0e324723afc669edc2f60e39126def18a98d862b674a29c2d1"): true, + common.HexToHash("0x051d81c0c2f4d7ea94966de2730b0b108001e738b657162788737df8878fe366"): true, + common.HexToHash("0x8c716ab2c6f16c2c5f7792e57e75ca0dae0213febc2440473daa9e38edf327d0"): true, + common.HexToHash("0x06b4dd5d7f3c33bac9fa3c08323cab4d87bddb1144c930834849fc45dd8703eb"): true, + common.HexToHash("0x85557978ac8981d6f548048a43f3dfc8b2fac2ccdd8bc815269614efa31372d6"): true, + common.HexToHash("0xa288a2848aa27c805a3e62421529de2566ac330a1ca476d3e2c0bdd3b0a6bd3e"): true, + common.HexToHash("0x03c5cd77bec7478b61241510e40dd88726886633d2d91ff7b251bec81c5f81f6"): true, + common.HexToHash("0x22cd03bcab832486a5c24286f64c2eba4e86b9f6437c3805742fa8cc790e5db8"): true, + common.HexToHash("0x0714bae85f73e5394781ec08b517ce632fc4e1d939b3ff2d20219e7b7354c643"): true, + common.HexToHash("0x0aaa2b3899701a97a87ecff9a77161d2f89c4f58418ea8af5f66f3f5a7e17722"): true, + common.HexToHash("0xc5fd5d43c288404ca2a6d05c50375241f0ab05feae00e8097b339f1d80c02f28"): true, + common.HexToHash("0x58e72dccfb77671b45c55f24503de3ab6604c8c388ab30a8d1e4f62a784dd5ed"): true, + common.HexToHash("0xc74eef3fcf6191dfabe1734ca59d1099de48aaf72de26efba6ef614dfaf199d5"): true, + common.HexToHash("0xb5e07f2e88078331e36f97a3d18dec2b07a8a4b1c9cb0abc3ddc64e2ffdf0111"): true, + common.HexToHash("0xf00820e3955f519adebcf60528cb5441d99967b9dad22dd73289701c97824886"): true, + common.HexToHash("0x252575a110298a9bfb678b3c3d44e2211c5fcb76ec43587ad66f7eb9efe7bb62"): true, + common.HexToHash("0x62f1e456c9f5afe36de4a607b5bfcff9e91f586d0392ced74d9566a2eef86b01"): true, + common.HexToHash("0xc43c7b83946429d55309372588fa1cf976ff2310025904b5e3085e40da411a39"): true, + common.HexToHash("0x5eee563bde59d59f33a6a91ed5d1e9d3342a68bdd940e262cd06566841321b65"): true, + common.HexToHash("0xa337d3045a83d32623de3b44c6339cbfc02a336ecae2e41ced5dfd59ee6a1462"): true, + common.HexToHash("0xfe99f23580fc5a47b48fda27b1b52438c4844581dcbc993c0b432de1cef9e321"): true, + common.HexToHash("0x053a12df7dcfbbd9489f84c61abb488ef784ab1adaeb092899631c4708b8e2ce"): true, + common.HexToHash("0xa5bb5e705cc5e15ba7f089e0ef7233c394856712eb1378280f7036b818a074a5"): true, + common.HexToHash("0xb6f6da1922267781f6acd5ad04379c36c22936117eaeb87be394f355a52c6daa"): true, + common.HexToHash("0xe1491f221f3ac191d2f26bc00f0775ff6aaa069b98d2771dffb9003c3f92f535"): true, + common.HexToHash("0xc7604ad68963b1803421ec035df479e419d8e971e85690ce01357079b9c4ee3c"): true, + common.HexToHash("0xceae7909ee5a36e09044138b12aff29a81c68eb3971e182157b0b54540c0f201"): true, + common.HexToHash("0x275ded20074f31b90d91c98962f9bc2210c13f5f89b8139868706cc1cf32e8f1"): true, + common.HexToHash("0xa89f8bee47e5be7c4e8dc7e31e4e5ff1c628056188f7c941ec1a20f0bcc3dfc0"): true, + common.HexToHash("0x4d9d07e2beccf99046857986922390782fe06cd3ff95aa3238536040a7f61cff"): true, + common.HexToHash("0xc9b6ef5b4b553183228120ed5ae6955480e45c8da857333e640275e4766d0145"): true, + common.HexToHash("0xdbb2309b78313326ada38e657229e989f4156f63eff2917dc00aad5b292be299"): true, + common.HexToHash("0xa3fed212dafa0cddde65c28cfa61cd1e6b39d5dac3dd9da58e18aa4e3aabd86c"): true, + common.HexToHash("0x5f570d16851b67a059f80bffb6af79ee44953116ac1a76e76eef5c0c1fd0a174"): true, + common.HexToHash("0x739c7c003fd87277440d26373a84ef9bc17cc6ab36385548f50646d0938cfa21"): true, + common.HexToHash("0xa87f990f7d678b4461c0ae2b18a6aee5d03c625340217f30b42d551bc296d43f"): true, + common.HexToHash("0xf71f1c4161dd401cf6532024c7ee539667154b3eb3459439d7fc5b2743fc5e8e"): true, + common.HexToHash("0xf1168a2b077be11ab55880c4b4a05b130703dbd42e9b7bd4911ba3acaa2acaf3"): true, + common.HexToHash("0x87111459cdb28c18f67ccfa0da53aa73a8e3104f1a3d391a0f17988e5182eba9"): true, + common.HexToHash("0x41e16dd05b245152585fe0c073c2cc388b3c35c638d34f62840ec115ec7fc3f9"): true, + common.HexToHash("0xd58d6c84e06472c958e487a50df5447a5e0d2101948b3498ef6f96dba3d7e488"): true, + common.HexToHash("0xef5abd63e6328e75d12c00a1ade1226af9a7839322d5d3452ae6c4e606fae3e2"): true, + common.HexToHash("0x412b84dcb5806886f93d175dd5492dc18a40cf71ce447da617200f5550308723"): true, + common.HexToHash("0x01df9aa21d17b8535b28282ccb9eaa3736616664f6f79ade568cc59741b89e8a"): true, + common.HexToHash("0x66d37773c4156a88fa0517474aa2af595b8892aa1a0c55520f19d3cc0fc4f4c2"): true, + common.HexToHash("0x16f8968934cd220704ba8bc39f60fb3df1ca0aabfaa975455734d9c21a908369"): true, + common.HexToHash("0xa92f587ba16a803d14c73e1817d8f402a4b51aff76bdb5fda256f79bf47f2535"): true, + common.HexToHash("0xfea81d9e24b4ffc4c964fa90d8bda2a85da0b4e8c32c2771be9860471dc2735e"): true, + common.HexToHash("0xd7f8d02ecd0e02bdfcb9e6d04aca51994b395740c89c8030e243ec4024f40d30"): true, + common.HexToHash("0x921d91051d8c2d2d2b5c002d18990b1cbf99150dac5f102563e444f9778739bc"): true, + common.HexToHash("0x3267e5587c0bcc93e9795abba64280a6480a6bdb25e67dd7c56ea5578f5c96fc"): true, + common.HexToHash("0x18bddd6b447748652f64836b9f91a1b1131341a534d886c8938bf34782abac0d"): true, + common.HexToHash("0x7875686a1c10647ee804115d334b0536c1f30fcf0d6699bf8aa6e5c8d8ab9491"): true, + common.HexToHash("0xcc69d806910b5199f58bcd98a2fa9464563e0093581e14148fed7602088c0629"): true, + common.HexToHash("0xf21b8e40dc006c8d1727dd07744f3d2610f235e4022e705aa1d70cf28c6c460d"): true, + common.HexToHash("0x4b357259fec36d3499d1c06ab21b7861283efa03032da34cf7c41c2d4d650fab"): true, + common.HexToHash("0x17e34ae787e3821e096b665d3a23b6d2e6e5e1a5dcc5db3b0629a056422a288d"): true, + common.HexToHash("0x40de6c98db6319443e710a234f6268e992f38aa71dc63a6901e2da12a5a6ddd5"): true, + common.HexToHash("0x57cfbc9a0ac9bb2e5e88ffe018eb3d3e04a9982244ff8ec2f9ea236e639b0e8f"): true, + common.HexToHash("0x9cc0590a5998f4ac833bbdc38fbf2d307851fd2d18c41778a64577692164a6c6"): true, + common.HexToHash("0x7d4e82b32edc95256b7ad30f6681ea9fd9e255909e71c254b124ea359de403bd"): true, + common.HexToHash("0x21b20e2797e04ac4ab93090370e0f870ef3b87eaec854d2ec6f2a99500b15a3f"): true, + common.HexToHash("0x746333ee7c7c587868c4d1027608c1bce349aa44b79519ab9636a7be235ed64e"): true, + common.HexToHash("0x9fbecc1168aff48079fbca130e1dc5fd9eeac887df6c9d9eff9fcd77f666651c"): true, + common.HexToHash("0x83ab5bb99b2b7408578bb1e73dd3208ecb8b2ff3ed7f87ad0759490efebf046b"): true, + common.HexToHash("0x145be1c5b8a436bef5e2e2e9873dd6ef9a994e8273250a87b62dfd69d14fde64"): true, + common.HexToHash("0xff8e7550e1542b15ffa02c33a288c753e16dfda2cc3ca0c34e8423b416953b89"): true, + common.HexToHash("0xfdf75cb3b2b984c31e8e515eae3e5104005903234de61d064f5f5c647a519a03"): true, + common.HexToHash("0xa31df5592bd6a431ccdba57ea5c4f1e7442babd73aa56b828461511c517d2364"): true, + common.HexToHash("0x4e3258bf453817d9af54fbaacec7e8e8ed37889974e76f2ca71b5985299ce0d1"): true, + common.HexToHash("0x6e8cbcfe2e0542497c4c59cb15f6d83772898638b55cac820d09cb670bd42863"): true, + common.HexToHash("0x8a5e2306c706526537b99ca0211b3e97e401a39d0d0567ccc4e4d10c04880861"): true, + common.HexToHash("0x78ee533767a465ec75ab46651df1c3cf214c38077e8cc651ffe64eb324de2b0d"): true, + common.HexToHash("0xb0b140896f3871f09576e60b9e089fe38783f89284c3cf1339fb1952ee809b42"): true, + common.HexToHash("0x79764d36fc999ff2873de2b5aa5f0e816bb38e59c60c2c882757cf792250f7f6"): true, + common.HexToHash("0x41fcc3d1e75ef4c1a57585006b0e02c6b61f7e52aff2972a7fdf12547b6a4d0b"): true, + common.HexToHash("0xde861724546a652822d0bb97921cb4989ac671a52c2e78bb6bc89da9bb983616"): true, + common.HexToHash("0x9a4ec344c0ffd0b0f77674447390116bc38ea1211beb647f2a13f6e4c8a05c32"): true, + common.HexToHash("0x67306ad0661487ac0ed6eb2f091f421153e118ee1fe9a05858f83cc7834eef99"): true, + common.HexToHash("0x33ee603e0dbc828061464bbca06f302e35704403d5bb506571b212f9196fc669"): true, + common.HexToHash("0x2d260447ab3fc14335594de1b6a7bde26d9c8f5cefeb5f27fd14dc29737e9d10"): true, + common.HexToHash("0xab06118d62929dc5543e3c3a1a00d87d195e7ce02ebc63731aa08a7701fe6f5f"): true, + common.HexToHash("0x8b854ac6b9a1d4f3929ff60bf615fb0cd732628496c1ab631281ecaa3634fa3d"): true, + common.HexToHash("0x1c99ac67a22072df78c360f8c991149ebb3465a483942b927d2bc1a5f1b0e5c0"): true, + common.HexToHash("0xb7a358062d6c757af6d9f8689543457026636806941da4a8566fabc0ae1df294"): true, + common.HexToHash("0x6d7fdef26e902014fdec38dad993bb48af076ebc6c75ad7cf119d04c0d805a4b"): true, + common.HexToHash("0x89fcb438e685e30d939595e2a1efa5e222b2349baf8202bcb2e3071cf75ac735"): true, + common.HexToHash("0xccf5416bea0d1b23074c093d937d49c1d54d792927f9e13d5800282b3b064e6f"): true, + common.HexToHash("0x1c47d18e70ea5be89eed7cb9fd843321e7d851a4959c1abf11304c61baf2dff6"): true, + common.HexToHash("0xc08423e5f572756a498c5b212be09e00958060e760a2c0d4ae5dffb9c1ecba8a"): true, + common.HexToHash("0x8f5ec292f1f4cf7cc157840b3309ab74366f9357dc47cb3d4bc1324d2d7e7d90"): true, + common.HexToHash("0xa8b01b4e8d04bb4efa716b208eac2d2fab624827af229b0f3ee421d2ea96f058"): true, + common.HexToHash("0x200ffcc3702f8723874ec860578850e6da09ab0d08264bb4023d85d64de06807"): true, + common.HexToHash("0x8468e88846ac8f5a2bf8450597d8df21df4ee10affa71141dc63efbbd382dd96"): true, + common.HexToHash("0x9296452e9776150ad026a08fe7e37bbe25e25f1eaa77be397cea387dd94e660e"): true, + common.HexToHash("0x6d56e13cedc695f565d1a9e2269deeccd3ea16658c90dc137cee6e583b0c77af"): true, + common.HexToHash("0x3d46b695d975fd90bc3a82e628c3d1f9591878e6dcc8ae40dcca001102875611"): true, + common.HexToHash("0x1adda0fc30386d227e354b3b271751ca9c046fb445c79f89aa7b56a090e238cb"): true, + common.HexToHash("0x16dcab5b0b5dd68793a7cc17827ecf35edace9d5bd87cd21c3defa3946ad85c3"): true, + common.HexToHash("0x0a936c14d152381f88a94ca2724d85a53b6e7a9157132b33295755d0c5b15a34"): true, + common.HexToHash("0xa1d142c32b4c507570001839cefd4296a2e1851edbb01d48e4592d38af6f7de0"): true, + common.HexToHash("0x7b50f24a816864c307d1ee6456c7b646eed9a4506ccd4e5f67a1250ee9ffb17c"): true, + common.HexToHash("0x657d458ef4f2dd59e08fd01adefc2ce8bc8f09f7b739f126418e655cc0949f85"): true, + common.HexToHash("0x67e98b1c7b8aac4b9cd0f70d21da2ce3f1da453c8d19f65f88b46ab960bbd6d5"): true, + common.HexToHash("0x08acc704be9f55b42b206a46b3a9773b7a74d482b8b044149c6ffb61f25c8391"): true, + common.HexToHash("0x2c8a86d54b3511e45956a45e099c5e041a1e5ba00b7886b97c8839eacf64b159"): true, + common.HexToHash("0x11886d691a6596236f295eb7c1b98c81a21a85fff83dd015a9234881393fd9fb"): true, + common.HexToHash("0x0489fec9dacb4bccc72011e29aecdfb646b821f4d0cd8b77dbf5d8c4e6a9e479"): true, + common.HexToHash("0x7d855fe51a3bdf3826fabf41f1bf04a659367136a4ba4b01d9074aa316ed1197"): true, + common.HexToHash("0x436ed0a3c84bdb34e705920edd2dc3b0df87800124e8ce41060085b0564d60eb"): true, + common.HexToHash("0x9718fc1d5ab133fe52084e1e408358b5ee5db213d5b9cd66eb83d88efc468e6f"): true, + common.HexToHash("0x53ef24b81aeacc80a91b1ad21491707faa0fa1e4f3089a229fb852e73dc0885b"): true, + common.HexToHash("0x05b4a07de0ae1e8e07e7a3475a0631b21e4300d9e9f87b9b24fc070bca37c6b5"): true, + common.HexToHash("0x39a8f1621a9b04b3b89d3b93ffb0c4cfec2a4da666084c63d4aa477f3fd0bdee"): true, + common.HexToHash("0x3f2beac75ab594cbabf54d557e850c77d87174229ac0f1761f25369bb230d1dc"): true, + common.HexToHash("0x5c7ea3e4cb43f5dc268eae887ada87c9c57c33b541e551b3ba5260975bee6f96"): true, + common.HexToHash("0x39b64fec9e22301f191b697327b80a0448e163f74bb0856991aede0b0626380d"): true, + common.HexToHash("0x9167fa1f49eb89f5ca127906e39226676294165daf617bee17c83f980ef2ca31"): true, + common.HexToHash("0x1ac666b1d52b5647af5c66174dd0f6a82d0ca8754c1923cd4d3606fe5f404903"): true, + common.HexToHash("0x84caaba488d149fd28002ac7c3d39cee1d3c04b71e7087bafa827a0c36e8ac77"): true, + common.HexToHash("0x4bce43a749496661e994f74569e43fc07d8ac3624f75e61b09ddef421313ccb9"): true, + common.HexToHash("0x081367daaeeae3569108b719c0389e69b30d0554a6639138211fe63079e2cd8e"): true, + common.HexToHash("0x29517dce1bd08f6e5211b44c3feb414bb12965ce9d4090c0ee91432092df947f"): true, + common.HexToHash("0x7f6db4a5420c1f5cd81589b6e56edce219aa38f09fa107afa8f0536a74616613"): true, + common.HexToHash("0x06fd8050a348c26c999c926df854e5fcb7beec9805922a4017a877d6eff8bea9"): true, + common.HexToHash("0xf92ddc32cd331816a3d5f220d588cc054c42d54d629b77b2f9749ddde4f804a7"): true, + common.HexToHash("0xfc465581d070ffdc43cd57339fb8070d9a7146d1a4668060d2964eb796acd05a"): true, + common.HexToHash("0x46df199d5662ea80062f624fb7d25bef50ddb2e4b50b0cf8fa820694a2194c55"): true, + common.HexToHash("0x5268a1d10bbfeb68e1e1aeb97a50360e369b4bc4d66b958d44d26cbecc3ad36e"): true, + common.HexToHash("0xcc49f390ec2f9d36efb6f70682c43634d9fbb56a1990e32bd315b1433cef7718"): true, + common.HexToHash("0xfb13c0f955335642d34ca444030dfa0090641ce5a7885248daf9759a6276e94f"): true, + common.HexToHash("0x92251c6d3fe070b41f83ef1e661db36d2514d93c7d16b0490d6e87acdd0a5ae6"): true, + common.HexToHash("0x43b9f1284428d63b35f091e7e080c15e8b1602946bad19b055391680baf7819f"): true, + common.HexToHash("0x8839fe30058d15094ac76a47842d0d632eb317e7e3f35df3dd7a8fb658d20452"): true, + common.HexToHash("0xb2b456c22c57b49eb9e477610e383c291f50a0cf7022e4e001bf59a01271f247"): true, + common.HexToHash("0x11c908a8d6c36f87670f8b015bde9d6a05df606811d219ded05504e9f4720736"): true, + common.HexToHash("0x3d16e8e4d9a1aa7c2dff880ab74aeff19cf3579f36b0ed7da7b91e4fd61a916f"): true, + common.HexToHash("0x7132e1225291af6c043f7d68a6051314697f43f67b560fc82e3e6169318d0147"): true, + common.HexToHash("0x58b087e54171f6e480aa7b38e288bee92d418fd4016262308570d4f2a23a7672"): true, + common.HexToHash("0xe6f1e55eac4c137536e1d09111808de22825459eb6ac84843109e652e667c246"): true, + common.HexToHash("0x072f55f6c4dbbd80b30891015d5f6595b431b52cb515e84cd441dcba2562b49e"): true, + common.HexToHash("0x6ed0919ad319f4dac574b36d06077ca7c2a1b510ea5117e2d1398d7ff18da18c"): true, + common.HexToHash("0x4846cc4bac2131ed1de074022068341d35fd5e44740054d67b296eed823eeba9"): true, + common.HexToHash("0x7e7e83b85f09c367eca758806b14ea2a67342aa50a77aa557f41d9302a6f09b4"): true, + common.HexToHash("0xaf5a4792f8d8d6b9e345cf0c19f2861058c2b04c97eb5ec0392a9639262005a1"): true, + common.HexToHash("0x279a695a60753e711acd1233cabee22e2abdfb4102baf23bf69eb05f2f990d5e"): true, + common.HexToHash("0x95d15572dde6eea9ca73d69a50a996f249463a841c197b54d20d20fcc108c30c"): true, + common.HexToHash("0x23e0074851599d1c93b69ffa5c9db6eded1c2f6f7a3ff1cc5568c0866a32711e"): true, + common.HexToHash("0x30b370a6bf917d43c27f482a10a00235b35aa1c8a3aab63732f36375deadd7b6"): true, + common.HexToHash("0x378f2152981ae1034ce20bd0a4fce631f2e634295a7c5047fdb4be6d35fc4789"): true, + common.HexToHash("0x641324f355b8638776805711b6ed09eaaa4e04de9292eba640fa922e10e3e3d8"): true, + common.HexToHash("0x782766aa34463a09eb9b562aa60c3032a0be9b902739729378f104a5a79744da"): true, + common.HexToHash("0x1c408373e6f7b2f59444216755bd4c6ca1e1c0d3dbf6c41e98a49f5bf88a7487"): true, + common.HexToHash("0x4ca03455827ee95b6f4ed869d155a7e6ac18845c4e542bad2a1c69034ad08a18"): true, + common.HexToHash("0x82438b3006ae9dfabcf060efbf29ac23a3373e8ac6ce9bcf501a26eecf13bcb1"): true, + common.HexToHash("0xb235be032999c05cbc32cc29a7b7044ef7d4e4764673a132e746e754ec18473a"): true, + common.HexToHash("0x03d26435a8fcbddc1163fc27ba1fe281b32018ac3e431b754c2cabffb5fb98dc"): true, + common.HexToHash("0xc8d2c42f1f03610cb58f07e987e197d95d90916d04df716324e7296a4def6e9d"): true, + common.HexToHash("0xfe7b09068cc6f2457f1b24a18d17cd3dea22a2b8dd0630ff87e2eb43bfe87f0c"): true, + common.HexToHash("0x908c88758bb6ef1252dda2de671d8d70fcc6e25681d7f08040e0c682e52451a6"): true, + common.HexToHash("0x0fe1cface8dd279b1dfe6f33eed5b34256863ec645b76928553310cf1f72bd63"): true, + common.HexToHash("0x0f80675ca5ce0377bf4dc87a1781dc3f7be3d676b1c7cca53ec16cd67cafbc0b"): true, + common.HexToHash("0x883546f66e1f4ca7995258593d95d151f1b74026b7fb5c67900be4639ca9e00a"): true, + common.HexToHash("0xfdd62d2434cb1af7f017f7ed9ace2bec2dcb333138a06058d45ec37dc9f6e71d"): true, + common.HexToHash("0x688181cddb90ad6321df398e86666c2eec291bff6e1445ec254d4eaabf277b3e"): true, + common.HexToHash("0x7de4b098b3c87c2a385a75a215ef5c903fc0d299381817402b067ca435322705"): true, + common.HexToHash("0xb066cb3ff898aba8f2e201352c113facfc64199dc705d0110a5e00a8cd9d27d5"): true, + common.HexToHash("0x1810c879269a518f6710b6db0152c5e3646993ffbaa0e61e3377bb81a87c09b0"): true, + common.HexToHash("0x5024b43c16d8a6281cf04273e35571e0d153023d3aa733fd190c1b235900fb41"): true, + common.HexToHash("0x6eb98e8353395abb720e89bb0ca3c08e8de4b72996b912a81c94831a74329620"): true, + common.HexToHash("0xfe784060ba63e86cd8dba1a627e145692cdd5c80bc809fd7021089c9cf3fae0b"): true, + common.HexToHash("0x5981b40a1d41e90938a5ea5040e5f33a105d3178d0234bba37d4cba938cd7257"): true, + common.HexToHash("0x2f2507ff534269e3fdaecfc692f72c54ac34ddd539572a16d59fd8e880b36e55"): true, + common.HexToHash("0xd17cef42bd7f203645fb73fa119be5c2be4a77e340721cf32eea11f5276e5a6f"): true, + common.HexToHash("0x5705fc652e742226079f7d9c91a5bf4d4753b165550f5aa0d71b1a489a039670"): true, + common.HexToHash("0xb25d8312e9f629cc2b3eafc87b414edd4868d6d14bcc8c6cde0130885d616a69"): true, + common.HexToHash("0xbb2ac2e2bb0536134e346dfaf8ee607c4834f86bb87456b278d79a61249c8e23"): true, + common.HexToHash("0xe053d1faba0c5d2ce665108644437220a81579798a31d566e5b0c1b9a0580f6b"): true, + common.HexToHash("0x28d24fe34e1a2799ac1d54f41b61781156901e1a97c4cf651e39b4b4a3a6cca8"): true, + common.HexToHash("0xb45bcd9e3eed3aac3727672544688f414530da36a4a32e802991aeaffd58ac02"): true, + common.HexToHash("0x0cd3f239eb872945e1b5c9a4159d3884f9428d3ad08c9db9a15895193b0f506c"): true, + common.HexToHash("0x3e0d1234ac58bcc58cb2add2f4ba5fdb6e870b7611946bff3fb5e7a30b97ee1e"): true, + common.HexToHash("0x10166a95e4fafbca1a37477cd99b72461f27580389bffe3bdff922b88ef07e4b"): true, + common.HexToHash("0x78b330f0e1796534fba2949fce6a6d1cd390fc50d0c5f8be77b4a1c076d33398"): true, + common.HexToHash("0x3de3dd5ee3cc378dc638cc2745e12f3983bdae79c6974bfcfbb4246b3305470c"): true, + common.HexToHash("0x865b2a6eabb7ee88d86e7528fa82a66052ea9610e9948dd4382ca4ee9f71ecc8"): true, + common.HexToHash("0xea71e14a190785041bdb312c5014c50f856acd87c3d1c32fccc840bdc67dd132"): true, + common.HexToHash("0xc3c1536be6c4be5ae2379a28f516b735fecc97e937bf4a5b607203a3007144e2"): true, + common.HexToHash("0x0e37cd1db46f8ce7a125f4c58626789cba471e2aa01381023661926e5741e102"): true, + common.HexToHash("0xa4b91236b1347a1ca126c5ff5f3bb2aa7065780262026730b884ee509f20fcfd"): true, + common.HexToHash("0xc4b91306f2f12e4543b3221e3ca288d0c89d5ff73dd24f9405cb807577c87360"): true, + common.HexToHash("0x0a8bc79e84709b45a87b9810c18632391068c0263c50b10aa8f065ae8f2c1024"): true, + common.HexToHash("0xb36fea45b0ddc3c29a4d62e1c7175786551fb4ebc0a18fc7ecec4775d13cdff3"): true, + common.HexToHash("0xdfeb048630441262ede291b379ba63a5031590ccd928441cf6b0e589606dce23"): true, + common.HexToHash("0x266a456ddf61dba26f38dd761f526c049fa9acf2370ce4833180075ff1c32989"): true, + common.HexToHash("0x37772e5f1c7d01967dad81599e6df274759ab4c0ffe059604ffde37775cf4dd7"): true, + common.HexToHash("0x0db615883fd025e5be6c46339713e4d1bbda3a807faa01755f671617752aaaad"): true, + common.HexToHash("0x81944b54e02a1534300a3681d6fe5e031112e9dcfac15735b32eb974e08d4ae2"): true, + common.HexToHash("0x9396a5e8c45dd25ce8597ad13ea5f56e42242bdf92bbef12bf9540c9a36610cc"): true, + common.HexToHash("0xe1f4eb29274dc8fbc41c1582af7eb16fa1331e8ca396d7b44db49d8fee36c4b2"): true, + common.HexToHash("0x4ccc5fc0affeba2b557f25491fcc0d4ccec3bc2dd238119754351b0f6ba577eb"): true, + common.HexToHash("0x11120099eee4ae7a19ecad75a4726fa0983f477303602204ee9d384061904593"): true, + common.HexToHash("0x6aec215247c55325f5c6ce5d242d369ef44bb557f6a9f1169a9058f64c596e13"): true, + common.HexToHash("0xbaf1e4cfc5a0d7ac235e9da8ce6c06c8ffd7dfb8033808998c0987b6506d9a4b"): true, + common.HexToHash("0x875d4cebf5362358c8b2f9547b536eb26916b475fb32cdb5e9998dda53bb735f"): true, + common.HexToHash("0xba53721b7d13275506328d4c5d63656f2d00b4142c777035b4d50431034d20c5"): true, + common.HexToHash("0x8d6a705a0e42ad5b387ddb0ad3ce4c14fca4bd1083f3f5edac92f8e8c47661dd"): true, + common.HexToHash("0xd5422a4cd4266219654af6ce313ce6b360455425c171a378186ec81999b4436a"): true, + common.HexToHash("0x49021d91727d9dead8a3d8e5e4bc15fcf4cd9f3595a3309158604079f09a16ac"): true, + common.HexToHash("0xea3ba91e1f31082d0c1244f214140662cb352a46afcee5f9b875b8013f5e9b0a"): true, + common.HexToHash("0xbe06480e62b723eac783ac6037a3e964ab25a2333d9c5570bffeda867b66abab"): true, + common.HexToHash("0x85232bcb246b3289c3c3917be44e9e9705bb3713c256ebcc0814b6cc379e749f"): true, + common.HexToHash("0x1ea53df362aa6053a4ff147deb266952d9b5853834634e0cb858573fd916aa02"): true, + common.HexToHash("0xc4d303fd3b725ee57a727380fe65fd28b5167d1d79aae50ad3a08d0ed91b2222"): true, + common.HexToHash("0xac7d64751b64502ed4e1287f04a61849bb4fafa5e3f14f6f2998be2c1fc6ccc4"): true, + common.HexToHash("0xa13930f693d96439a48ce11b2651d98e40d86995e439042b704333618d3e0d39"): true, + common.HexToHash("0xc00ae2645e4582b1698839fbb44a7203e4b60dd1161a99b1af9b7e4af9eb18d3"): true, + common.HexToHash("0x112ba43ea2935c33af85d5c756d440b83cba8e020427515d0df81846b6efe0ff"): true, + common.HexToHash("0x292ecce6cc786af4c2b1e1f4f4c45f078bc60a7e6e68506f907565b5187f2c28"): true, + common.HexToHash("0x454d6a322ae92250afa9d20784d5cc88dfe6085c93c9519b4120c76793984200"): true, + common.HexToHash("0x2c27caa33b953b8e6e972cc995b64560e124d9b8098fc4ccb65be7942b280e5b"): true, + common.HexToHash("0xc600c2f10ec1e1a24ff6fa0005f46fe355dc7cf835398a84409f1e65b9119725"): true, + common.HexToHash("0x6e06dd9f0d771c90b61b10fb8f2660ee5489a48ee646ce1f8a2829c9461472f5"): true, + common.HexToHash("0x731bf2cd46d02b9134ae05ff99c3dc441168a236cb0fc9027b84148289db5704"): true, + common.HexToHash("0x1cfa7207da62c3730a6353b7b85425dff23fbb66caa61c1aafb7c6ae62ccd34a"): true, + common.HexToHash("0x00c49c96663effafa1bd9687cf3ab04f06c7ca8490b359224ac038a7b92803fa"): true, + common.HexToHash("0x34dcb0db6f7de77f0fb7368244e3c4b99ac9d377a73116722d2da8162ffb9f3e"): true, + common.HexToHash("0xcdfa2dac9e92465732392e816ff0e8c87b9c956793b242e2753c32d239dc6277"): true, + common.HexToHash("0x3d2fd118d770f26aa4c3d4f2ddbf2b0f4e14f8f21b4bf902b07e87977e7060df"): true, + common.HexToHash("0xe0df99558d20aea3cb66f69c82018e7b643ce049eebd24eb8dbcb95e9b707b06"): true, + common.HexToHash("0x4659c1a197b1f585ce3c869fba679ce4228ec78656433816eb71cb998820885f"): true, + common.HexToHash("0xe3b6ce57f9797edb043cfa27cd6a9d661ddcd85a5e9fb589f9d9d739f0eec5e8"): true, + common.HexToHash("0xe296665fa96241069bcc65ea6fac461c802340016a4bed51888876c38e9638ae"): true, + common.HexToHash("0xb317a28530ef927c22e6df50b433371d817e76317a87ede37ee239aafbc1e793"): true, + common.HexToHash("0xfe5a300cc59de2d757296cd986e8184c1dd7ea77f286d54cb6b20ba86d6ae8ec"): true, + common.HexToHash("0xc3ae20f5307fadff0d47e19a9ea90e6ac231d2df48335a8d3f690bf3f76113a2"): true, + common.HexToHash("0xbf9833339579bb330d6a9307c10ef99c58603cc8ff18da4ef24a03e0310587e1"): true, + common.HexToHash("0x900d4b4821d04315602a77768cc7f2c2828de8e9c9c569bd5086c087b33a5441"): true, + common.HexToHash("0xddcdbb5fa10a0119c16e70ab81a5891cb390377ed1bfdcc17f8f0d32207d5e11"): true, + common.HexToHash("0x5abebe4fbd08e4d85894b07496c0a9b8ca715eabf9555358cb16ded5049ed4d9"): true, + common.HexToHash("0xcc225bcdd9e3e10cc8ec9f1be026a39227cfd4d4b4aa8333c2bc40e6b39b8c34"): true, + common.HexToHash("0x5d440b3a9a868356f1e42b4b0812e288ed6661263fe1703f09e33e49fab76362"): true, + common.HexToHash("0x8ad423feb7fdaaaf785c9ab948f2f404313fd38e5dc1a0a4e11dbc1cf71cdb6a"): true, + common.HexToHash("0x0661ecc6c7bf840a8c46373137540d6abc94fae46127e38c4dc8817861ec388b"): true, + common.HexToHash("0x82186e1ccdde041d49d2bc757a9de0ee296f6e2ef5e34e3b2c6dcfd952a9efe0"): true, + common.HexToHash("0x344f9a9f393cd2707968f6ae5e7f1d1efe32ad0d15abf03e2e5e1a11707139c5"): true, + common.HexToHash("0x14a3bb61661353524acb534fed098fdada2007947277e0763420731a7e449a44"): true, + common.HexToHash("0x07552bf5a8db2a12fa31bf4f94ab2df85d3cad921fe27af033245e3b004f24ac"): true, + common.HexToHash("0x9806a77d6c9a7c424bb5e0d3492d062c6c82b26ad4b88f3b7e09bdba3e561c58"): true, + common.HexToHash("0x9539eb54101a556ff7c946d1205d6ccd554f235e119a5b7d3801e3071cbc0edf"): true, + common.HexToHash("0x5ea6c75105779829dc3b86ad489fb01b3984f7f414b6eaa9625f6886635f3a8c"): true, + common.HexToHash("0xd902b0a0b9dfe8978a1932b08419b161a6d59f41bbbe5b0c6ce3992182ec4cd1"): true, + common.HexToHash("0x28dc7aa9c519ddf5614fe1bfab1365a14f5678c77a3bb69685e8250bda40b78d"): true, + common.HexToHash("0x2d7f3b2e59136949efe93a1447c79c2317213ebd9ae92c48f03d558dfd8eb796"): true, + common.HexToHash("0x53e8bda2209a96ac8723d561e48a4d77c432d5675a8077f7915708f7d3302624"): true, + common.HexToHash("0xb45e6e0ffb093ea1a95c4be33a39aa8489e93ed448c6dc3fd7df8f4f96d39694"): true, + common.HexToHash("0x2d8ee988f718158d10d8774f8377614dcede80756e30637210b2263a7c1a4d54"): true, + common.HexToHash("0x13c625c0ac3df59650950ed0ebbfdff8c215120d18672f53601625773b371ca4"): true, + common.HexToHash("0xf776d0f0845d3349f5b262cee4d782176043fce45a146ac9b09a0b505134247a"): true, + common.HexToHash("0x3491ed0193a9dbfd4816dc85638354b9f437667b482e5dc1fabb9eabb0c18a30"): true, + common.HexToHash("0x69eacf076dc376a855fb8dd220259478de5109632d32147632d413e6ab133751"): true, + common.HexToHash("0xe086be26b36f2652d9899c2cbf266821d2ba0129e7964e053f4783a45dd33d1b"): true, + common.HexToHash("0xb089031d132c65c17e73ca86a30a1b6d888b7f5ff26fd57cbc0fec93f62c4d9d"): true, + common.HexToHash("0x8d053313ab6467908061ab4e12e1ee25902ab8bd9da9c9c59d508af70743ba08"): true, + common.HexToHash("0xb3ce2e62d9c624513a144a7bcd44c283eeaac80d29fc2817b55f89183c6cf419"): true, + common.HexToHash("0x48e4ac9b369ca874517d34a55c70c354f1615c1d135ef6d01cb52f4b7f1c1cc6"): true, + common.HexToHash("0xa4091b2ff7632a057f9318e5aa86c261453f2ef787ae4a3f8017be3087c1c04d"): true, + common.HexToHash("0xfe5f5445370f7d0af75206d53bc8e83a7b082746a28ea1dee8119672d586c7e5"): true, + common.HexToHash("0x12e117c5403866be5e741dfaf5c3b1dacdaf1534df76f5c22fcbf2b2f5329753"): true, + common.HexToHash("0xd920f4c977011d9fe855d55bb9f5de1d3e876ea594ab388fe084f11f33c6d12e"): true, + common.HexToHash("0x88dd23a07f8a2b38f79a79f613032d2ee2592753d6d793c08bfd2d281ed45547"): true, + common.HexToHash("0x45c6d915954b865dd9d22b136f2eb182eafe283c430ada47a640d9d871654557"): true, + common.HexToHash("0xf62739835eb7dfdb4c10b66174cf80c420a4a249ea9f9aea319c2b836683fd0c"): true, + common.HexToHash("0x7de5e1b752622d68c55b2ef95fc077f049c02342e7c412ceb622c33199045264"): true, + common.HexToHash("0x04f91caebdba84167c11f6b7eb9c9d32036b56a691e9cee700e4278f40a25ed0"): true, + common.HexToHash("0x81f9c415f3a0312da98b477e1e487cd3169021d0d440360a2d1cf5a1333b3935"): true, + common.HexToHash("0x2371c7228fe40530ac68702c5cef08b7b9933d6c360b9c9a8f11f270d8771eb7"): true, + common.HexToHash("0x0619ff6d6c01a809c1e664e9dda5ab7f13e58e2dc6d8c54e1efd801680fbf202"): true, + common.HexToHash("0xff741346cbfee2194fd6429281188a5b599822213a6c1e5b8b7a169ef270c292"): true, + common.HexToHash("0xf8bcb24c57e550f81cb09f6bcf8773868dabf5b5681e04c010a76ac8d47a542f"): true, + common.HexToHash("0x17269b60261b33c27c5aca75f8efca05e118e59f012921127db5330c78b22f36"): true, + common.HexToHash("0x60f21b424d4162a1056efea4de1bbd0a4dae0dd41204eab4fb81cfb053753321"): true, + common.HexToHash("0x5eeaee4e57dd92e63f4c6bc205af95af604804f64ef9343b5b7c3e889e1acffd"): true, + common.HexToHash("0x3778b4b4af386673f6ba4362bdfb7860e82642f9c26cb86b7c114887136ce6de"): true, + common.HexToHash("0x8141aabc4f1a05fc521c8e6f308440fcb29882117e5785c651fa3f1f19d2d69e"): true, + common.HexToHash("0xbcd6f8244a61ce360f8883be5c2e85b97087ae3ac728ef5318fd0d97cc7d2245"): true, + common.HexToHash("0xf98eb81521a594b10b536108f6bcadcd39263a3237b3cb9375f6b7381ad52dfd"): true, + common.HexToHash("0x5b603e3831eccd65b75fbe41d06e9b4d4129d80437cb0d8d54d5184dc0532c51"): true, + common.HexToHash("0xabe407a4f41ec1e8f4a141517652f408d6f581cd23fbd2d712a97404f5e80a47"): true, + common.HexToHash("0xba62cbdac69be57584e6033b72036306f2149b225fb7bd2654d11ed96a0ecfad"): true, + common.HexToHash("0xffae049f3e037b06db415e37d98f835b4a50f9c94a09b0632f3aeef3db1da888"): true, + common.HexToHash("0x86f7010f6d7614201c89b3b8fb9f5f1e749ee77c6082868025652c091b841ad3"): true, + common.HexToHash("0xfdc9024d5136309b7d60cf7518f3e2adfe99f9f6207058f1145975f8f096b3c2"): true, + common.HexToHash("0xebb81ba7d0d27943d4aabcdf975fb282f27870377174d807d3f78b7e0ea97443"): true, + common.HexToHash("0x21bfc6cbd3f1dd34ac08a733da302ad7abaaa94b559d19cd2e4480852f04874f"): true, + common.HexToHash("0x859cddf5e54b1e2a846982c373af934ef0af69e9e0d4f3028384916f32b55b6d"): true, + common.HexToHash("0xaee811213ea539981330dac62d01fd50df79630be2379da0e19d5387c0b0007b"): true, + common.HexToHash("0xfc94b19b57629a7419d7bd23d620fd70947b702bf06709f18b0d7cb865b9554a"): true, + common.HexToHash("0xd11ba987c221f2fd1ffc870cfedf7c1cb1bedcc1f1ecc96e3e52a3f7f475a4dd"): true, + common.HexToHash("0x13e052dae3e53c53b0ea014114cdd5080b2eda1e2eba956da7ca4001878b5b42"): true, + common.HexToHash("0xea3db6061a0a26d974ba281658b4e8d4ad58feae8d648d8c51deccd2f6f90f5f"): true, + common.HexToHash("0xf25f0ec3e1e179ed33942f30ddf678801276cf08498d1b7b651d45688ac018ee"): true, + common.HexToHash("0x14763be2f0d9e2ee10799c7588d8b09718f253d0de182a209776998f15e8dc9d"): true, + common.HexToHash("0x0e5d0312dd1ab59470c658d76f406f17b7f88d61441c1cc9ec8c3562723fb5bb"): true, + common.HexToHash("0xf48f327d0d77cd5d77608881321f7a8d6d40b787cfbb4aa31849ba6aa3444453"): true, + common.HexToHash("0x37944fccb8af9087b21ae42f5267404f934593b0f2621e037c5aa2e5d805adff"): true, + common.HexToHash("0x305a8917cf33dac1c32888bce3a5385de40d444b0e1decab03afe88e694dc70a"): true, + common.HexToHash("0xc37a59f32c9ef2e790e96200c54306224dd907e28d3dffb342d3dee647debe31"): true, + common.HexToHash("0x89c17fae71c6530fbdcb19fa567a9507bffe4edd10e8cb9d5631e773fb26879c"): true, + common.HexToHash("0x897635bf625f736f59a1a649520100436185bd19e9acf41ee91e446f8515c224"): true, + common.HexToHash("0x1d9e69577d62fbc34fc2297107062c805bcad1e254e4c9cf060538e8f8cccfc4"): true, + common.HexToHash("0x864548ceb51d3ce3f167d2eb8acc8907df8aea4b1c35795e302e28e57e3195db"): true, + common.HexToHash("0xb0b88443c593ec17dcee14b462b5a13470f3a7d32ed577fc744330942bc7b161"): true, + common.HexToHash("0xce59f10fe2d9943f8bf5c4754009396af45b7c4e0ca4ee5ff14aed1ea304d28a"): true, + common.HexToHash("0x1106e8781a47eaf9f009b8834f89373df132f369b9976a0b89203dbcbf8da1c6"): true, + common.HexToHash("0x4c2e2c87aeef0fbaa1cae4584f3a478412f7cd6ee4c4e21fa10205f8760e3353"): true, + common.HexToHash("0x95ec187ceb23e914b8e0e1659b555a09730363a5f38bae71ce49bd3ef2614856"): true, + common.HexToHash("0xcb8da03bc8db703ddba9e7ca1099c25cee1c3bfb6c595ef8b7f5f650fd60f2d8"): true, + common.HexToHash("0xfbca65a11172ebc11c5f5c3930a389cd1b9fcd674309c2d8f066efbab32e0f3d"): true, + common.HexToHash("0x8b61b7ce32928dd9838afa792b03f40118b09182e87b7d4a1a2d65624ae3504f"): true, + common.HexToHash("0xe424b7da725152497124a19728ad855ada14cc094a5a937187c45d39d00f8b78"): true, + common.HexToHash("0x8b737e2aafb4160c7535b5bea11b770240c31740e48e4f830079293e216658af"): true, + common.HexToHash("0xb8cae2610616e3ba76767ca235ddd0bfe179c36504eda81cda6f37ca9e7cbfb5"): true, + common.HexToHash("0x05111f455be73041dd1473943188d1997821dec929110232be3cd51f6d362f70"): true, + common.HexToHash("0xe8f19bf8ac46ea64e90dbac7878a20891e752e3f8911cd24aa94d7a41716b5f3"): true, + common.HexToHash("0xf369e545f6172cfe1c813d96c8997af33574f660a0052886c3268cb86cd8eb68"): true, + common.HexToHash("0x5cf6340867ef08b4f316d4fc072b99fa143806629a14c58f7765fd75c2623a93"): true, + common.HexToHash("0x9d78c1622ac8ddb03082a7403db1aac6f23f34a2369bc431bff6e09dd41ff7f4"): true, + common.HexToHash("0x4efb46bb9db78c5e6361a7eb80c18165c4150329259ef593000ad1086b57e362"): true, + common.HexToHash("0xfad0a6bae4deb0e8f15e18125fca391dfc6c2785b5b6fd8ed34370188c4416ce"): true, + common.HexToHash("0x659391328c91c5dccd66cb3a19cc7136fae268d3972117de0d4c485a20fd99cb"): true, + common.HexToHash("0xa9894ad66e8c2a8fd7f4e82d6428150d41a673ca45da9a75fe65e5542ef96d11"): true, + common.HexToHash("0x4a4123505c9a4914eb6491cf0db9adac0d12ee6d0d2ea8d85111d8e72d0e887f"): true, + common.HexToHash("0x3a200e16055da3b84e23ac62610f6a77773b295dbfa11bd666a393ed5fabe24e"): true, + common.HexToHash("0x51435891a93a0a087f59831fca9fd2b378e30e568d27a1e346fdb255a5bb3be6"): true, + common.HexToHash("0x7b5b67313abb38f9fec5308f6d58f73d646715aceac405a6613c458e581f3c2f"): true, + common.HexToHash("0x40b17096ab41f28e85ff2f701c6c9e59da10685a74aa06e99866ffedd0d87ffc"): true, + common.HexToHash("0xaba8e5717dd35f085926d1d67f33457bfdc306ce5805d7ea934702287e42ef27"): true, + common.HexToHash("0xcfcf35f40991fa9fc9f39d9d667a5b96ae6ab1644aee0f13d4e4400db93658fc"): true, + common.HexToHash("0xd44388e1fdd4c5954fbffbc7398af75243f307ded4468d981ef1c746d58afaea"): true, + common.HexToHash("0xde455f9134b1d61d30f845bd54840b2e425066298e0b8e8ac44928394e4b7dc5"): true, + common.HexToHash("0x65cee43019287da50aed74002a848c552d2cfd8ddd71e4f91ee7ad10d8c4bf3c"): true, + common.HexToHash("0xffa3222b7139339865fceea19941c89b43f98e1dc20dbfe14e95abf61ec61bbf"): true, + common.HexToHash("0xf79d1c3ba332f91055e9b4e41abad01cbbab02140b6e623ec227a1e643b5079c"): true, + common.HexToHash("0xf0b185f36a482195ab0817c05d345f3b33014e19add263257a22007a616183f8"): true, + common.HexToHash("0x2d56f4ce8063a369e7cdf3edea1dcda56b00599073b53270ad662d35cd05a92d"): true, + common.HexToHash("0xd3e4ac7f624d0490a0a3b05567f4c7cbabff592f61f560c5d220386362fae7b4"): true, + common.HexToHash("0xc0acbf62cc561f533d11680f522afd2af59908a781ab9ef40cfc37074b9510f5"): true, + common.HexToHash("0x5d111d44c2c9eb980a742385bd1cb8c34b313109e9c7502eaa69bc75d4cc512e"): true, + common.HexToHash("0x1e789670f92121f2de8d3e5028417873a9c0185339f355a6812d0ecc24d69d30"): true, + common.HexToHash("0x93ba45c7a018ec926b2cee3540e77cf67a8c4cc042218618c0bd298a2ff4ddd9"): true, + common.HexToHash("0x23067fded6ef04bdec469d3cb5d2445077b5a9bf12e45df61345f87f3b305d89"): true, + common.HexToHash("0x6152b5155184d0dde4ba76fb17d724c31de8a5e6a04bb8033340a1aef5a12910"): true, + common.HexToHash("0x62ba90991047c316cbaacc5fa0b286c735f24e774a470f30f321940fdfa89a65"): true, + common.HexToHash("0xe31483f25c67a20ba6cbf460713ba2bb2fe2bb798e0d014408b3805ed6a1ac4f"): true, + common.HexToHash("0xd1bb3c7f53fee198a8d0979d50a56b86d7588be2ccbd01189be556ded0d570d2"): true, + common.HexToHash("0x154377096b368ecb6135e9b7330c2331add92f0720b6eb09bd1df2546a416f43"): true, + common.HexToHash("0x883d7e392e71dd42fbc504d1135d95f8508c139b75e6c79e4eb9d9d067b9aa71"): true, + common.HexToHash("0x894d9a0c73c6432c66788e20b15cb77842eda03304afab3f0b77cc51cb3e899e"): true, + common.HexToHash("0x824888e3e62f65ebbd911c9cf0a770cc6562f280eeafa9580fc6942537bf26d8"): true, + common.HexToHash("0x944594672a9f0421866cecfbb330069961f404e1a78e99115eb94d192fe252a1"): true, + common.HexToHash("0xda3fb6fa131a0145f0402ed18fce0376928ff9d73a8406655bda8b433ee938fd"): true, + common.HexToHash("0xffedbe8120f9f601f65af06d112a108eb8732cb544f0a6e9460abb8e4e0bbdea"): true, + common.HexToHash("0xc5420cadf3d1b7943cb6d6c79ffcc185a3dd16081a16adf30b0f7af866f9175a"): true, + common.HexToHash("0xe54944f949744e5f2bae13c901bdcf0fcc1c2ba69e70e44fb78e6c918df50c1a"): true, + common.HexToHash("0x6c5691b3f0604ee548c094f97e4aa00e4cbd0016e150b292bf27aadf664ef593"): true, + common.HexToHash("0x37dcd42785c8cff90dee88b4ce657ef40ac320701665e9568396e7a7b51649b2"): true, + common.HexToHash("0x35ba6508babb2b8672ab153b8c8747680cf27b912a7bdec6ec7d4974afefa80e"): true, + common.HexToHash("0xdcdefd08077d5c7105d634b496a74bff1f307622a3a66236ea8eb815e4c62ea2"): true, + common.HexToHash("0xc0126e0e0b5f7bce643cfd1621ff1833aba6419e4b9d759dc3bcd2318f7aab2e"): true, + common.HexToHash("0x0413aa5c117868671aab97ed9a5f6a94a8a5f5ca9f0815975090a5cfc2af8ce8"): true, + common.HexToHash("0x567d6ea6b06a822162ce22eeb16a1a0e59d4669316e2e78cb65bc6ca4de06c7a"): true, + common.HexToHash("0x53707c0e7814c7af4b140dce7fd3032725a78c467a890c32bc2f5c9c4795e8d6"): true, + common.HexToHash("0x9b4d46491341b6f0b0b00124139c3c96cf7623e01cc526e9919525caa77e0bee"): true, + common.HexToHash("0x728e8a28a5aaa40cc2952b34697275c55e764663c742170ab6f0a368892ff00b"): true, + common.HexToHash("0xbedc940e29dc9cd1c8a08d57cc358d116df8e735ae3da0b6ad92023f109f4bfe"): true, + common.HexToHash("0x09b2fe68b4774a773af753937fc83c434287d0c6d14e5af8816b75180cea0df5"): true, + common.HexToHash("0x00c64dcfa28ac5e249b784eb4cba4c30c1bf07974bdd72ada0e0c0687a8d66ee"): true, + common.HexToHash("0x051048d6a9376352c1496bc4b3a7b67aaa3eb33fa67c4e3273df96618cdcdd45"): true, + common.HexToHash("0x1df1568a9ed65ea1677104b1264911a1fb13b9ff94010e6bc711e50e12c9c982"): true, + common.HexToHash("0x12ed644540ea8e781b384ffda2db76fb8804ab345a7a21cbb57cf69d3ab8d291"): true, + common.HexToHash("0x9d2f1527247c40a89ed99c3b895249d1cca7837eb9863b033ff9ed1649fd9da9"): true, + common.HexToHash("0x62582b6e777b006bbfb8e47d71bea94474a4a3b3cfb6761fc10914a501663a8e"): true, + common.HexToHash("0x41763c12963585c72ef4dec631ae17d449a0f115e47aa97f3243c248242558c5"): true, + common.HexToHash("0xc9e85b21f5eaab5f0963fe4b386add9ceed117a8d21cdc27e80d4c839f77dd79"): true, + common.HexToHash("0x1666ba428cd8956f56ea1acdb5867936c919089415d14d160b7441c0bfbe151a"): true, + common.HexToHash("0x2c3aaad54147f6b795092d276d2c0fd0d6a2c87c4c3c287b8d34f05f79d81f15"): true, + common.HexToHash("0xb88c5b5140c7d39e22b0c443c197762cfbc184f6d18cc48ddd9429d9f1859ac5"): true, + common.HexToHash("0x137c51833ef2e732b8f456b2e5bf148c930f36d87cf409020dd2bbc7f4c0ace9"): true, + common.HexToHash("0xeb4b179d67679c02a1fb761765bc94f0d63df8525042f07478661de3d63c05c0"): true, + common.HexToHash("0x0c4e8d28500b20770bcfac9752bc07a3c602e2d3470e74f54f071605a481f61e"): true, + common.HexToHash("0x40e590719cccf96f59d13ae1a195f92caf58ef4ebe7a28b0f2b555e030d0df54"): true, + common.HexToHash("0xa53a2f9dba6e073d252d78fdfd96fcf53753e0f4c4761d0b37fd532f0ed2246d"): true, + common.HexToHash("0x79a080c0455f8ef1b3f6d774c96b06998743f9160d83a4eea422e90c40f3f277"): true, + common.HexToHash("0xe40194401ad5b4c2f38a445143fcf5ad53cb5e1b37fd093909d11db1be2e1a01"): true, + common.HexToHash("0xdd534b47a362adc57ad47558f7057f0f8ca601ee3f6c33aa01a28d46e7870a8b"): true, + common.HexToHash("0xfd77af253100902c7bae7edc7823dc62a237671ce785a8cd7e4ae259ca34d0ac"): true, + common.HexToHash("0x26848e3be6abb1cbb8b8a731e19efd5b549f98dcb414bcafa25225c38b23ccb0"): true, + common.HexToHash("0x7464f6e601299b95d4fd72de5e41d32de2c394244fe8669c6eee48c80e295f07"): true, + common.HexToHash("0xff9818230005e22020de87fdd98cc1196b80844694f61161146f9cbdf60e9bc2"): true, + common.HexToHash("0xab85cf516d371e512596826087b32ea2fdb05a589375664576ca2cc93122dac1"): true, + common.HexToHash("0x3df8ea01c0ff9ff68793dbcd4fd5a5165c4321537240d261a3293b1287df5763"): true, + common.HexToHash("0x8568c88d288dc325b84a122abdd29a00b544731f2cd2f000c4124cfff6ece37f"): true, + common.HexToHash("0x46a64aaa1fb1bd77d0e78e507742045705f24ca2702445f11addcf220140db24"): true, + common.HexToHash("0x076e5753c28a163d6fa343aecc71105b5b0c712e74565b70bc6fbc283d518c1b"): true, + common.HexToHash("0xf5e358d5204639a96b9fa37d237c29b0ed58156ad9b22af911bb67f77b57290b"): true, + common.HexToHash("0x2651a9c3138bc55efd21eaf9c29a434429b8b53451994eab4ba7225441831db1"): true, + common.HexToHash("0x2eff4e095e5906a836898ac409476e05428d8593cbfa5baebd970b96dd440bb0"): true, + common.HexToHash("0x4dcd58d120aa39332e47e5cce2f48793fc57ca70b0a4f1907d576fbf137c0a22"): true, + common.HexToHash("0xb0b2936cd9f9fcdb9e44f27e98a436cf1a71d8a680e2102b5babf798d215548a"): true, + common.HexToHash("0x2d628c65493c4b33c54969e84a2560c2c6b0f6bc07c0a79b1cb30eac93c0ab26"): true, + common.HexToHash("0xc4ae06439c3c7dd434cad7746ee75feca652ec6150d060d16a758610964165e7"): true, + common.HexToHash("0x15340253b133989494602f0e7094a1a84a9e2e4957fb350177300ca2921cb31f"): true, + common.HexToHash("0x9220e4a1ce9da13b2c093b380e3dc914ad3b022224146e5d24e754f5d1f1b098"): true, + common.HexToHash("0xe872699669c1817193cb7e4e31bc99dc4c270661ebe0cca7b29f11588cf58c78"): true, + common.HexToHash("0x0a0718763ec02acc7d8e5adaca5e39d6d460edd5f025c6ab7b4ef61b3c53e466"): true, + common.HexToHash("0x7aff2347ef39f35a7784c33898cb75621338e1ad3c663074bdc9fb2412fef6ca"): true, + common.HexToHash("0x23956bd0e82fa0a8e08ddc41d66ca11b44f56350b1136d1b59e727f1cb1b78a6"): true, + common.HexToHash("0xa6782fe068efe45a45db3f932db66877dec7660ee8f3f784a092a87ea89da7ef"): true, + common.HexToHash("0x3fdfae51b524c2cac5a5c2497c2552867f546dc3161b8964e756ea4442b2dafe"): true, + common.HexToHash("0x0e102e3f2060680210be9aa04ca630d53e9c70d779a5dc20e7f86dd18f955256"): true, + common.HexToHash("0xd1d584163a8566838af02b8ce0e18f6ee0a146d5f778bd303590c4053e262e78"): true, + common.HexToHash("0x615e88f532483b565df3c2991ec94de2a3ac908f8ae64b849b3ca633af0c58a3"): true, + common.HexToHash("0xab2e20efe23c28553b635f0a62a0cef83085538710dccaef2a40a4d6033d0779"): true, + common.HexToHash("0x3604c12f955428f7a7c868f371ddec64ef1b96dc65c4d73c5e0e967c5c4c23b1"): true, + common.HexToHash("0x72e56b514b240725d12766045a0c85430d76aa72186bc9300d26246cfdfcb760"): true, + common.HexToHash("0x2a307a63af6b0d9960012d8316eac525a4ac83636d9d23a87166807c3658b2d0"): true, + common.HexToHash("0xa0364caadef201c4f015d5153f5cfd8155cb3a02e49c325c55537edc361c57f9"): true, + common.HexToHash("0x29ce9b46fe87a96baac16dfe1bb19bb69fd642f8758fb7a1b089a4756883e054"): true, + common.HexToHash("0x5ef8c7c97f29509112aa63aa860ddda0361effd7842c2c61427b7039428a90a6"): true, + common.HexToHash("0x39a8460315360d29f9eac7b4b8010af05db1fd8e793369a9daad56384c879133"): true, + common.HexToHash("0x488356dbd2cae899ef356df1d36962d664d5d94e2330706a341ceaccda674eeb"): true, + common.HexToHash("0xea479312e713c09d6453905dde01ccf94e6868c90dafcdb7da4ba734ebb62321"): true, + common.HexToHash("0x5beacdd6bbc4659345853593e3487e4bbd2bb73db790ea83b0e5a7103eb04d9c"): true, + common.HexToHash("0x860c675171a49a6ee2e13797b10d3981a3b2770f61e12a20d644dd089235c913"): true, + common.HexToHash("0xaf07ff7d2ce60e79df52f3c1250a04e32f295ab0e712766ba62fb95f5370dddb"): true, + common.HexToHash("0x2731676c82e952d0d520a6d3f6e0c9ac10f2ffc146378fd97c2822708dc1d480"): true, + common.HexToHash("0x4717acc97b05b55d447022415246835ad14c926d1f38291f40956a7a2ba43738"): true, + common.HexToHash("0x503aa5e310a690d1b7049aaca7b5a65361b7d4649d08d9f38cc2edf5aa89473b"): true, + common.HexToHash("0x5db8fc54b494f4da76d1b67e469fa4067938790042d8274f978d9af4363e7a2d"): true, + common.HexToHash("0x2535f66f77265a78a41c492c26f7cee94e1f9e1137bbc1ae6594689d7966effc"): true, + common.HexToHash("0x6252b7b64492fd15eba64add48b2f4607ce3c161610caa491fea0386a9194999"): true, + common.HexToHash("0x73455387a23401bb42790356e003a2664bf2d85636f43039e2f3c7b9d4145edc"): true, + common.HexToHash("0xb2f2f4e76b40dbf01276dbb479ed9b63a625fd8946e25f7e4135fce8571be08d"): true, + common.HexToHash("0x4e2589a4d2fe10e1b5157cd91cf6d04e3df41501f827f3c6eb3e9cdfded49073"): true, + common.HexToHash("0x3ddaaf72c57b286dadd0eaa333c280722cc7542bf8234149bc85bdfff59ee2e1"): true, + common.HexToHash("0x55b55e93315334943a755097cbb1bbc854dabfef4b75dd8f534d23be5c9e8ca8"): true, + common.HexToHash("0x44d304e10d76dd49104bd695cf44bc35bdacf15cc08c3efc3001f9929257b460"): true, + common.HexToHash("0x07fa83f2845be2a91f24551d8439b484bfed9733cb0a98a5c741abacc69a0c88"): true, + common.HexToHash("0x2216a7b0f645f9968097f1c7d77d8904b6f38710d2dc32caf406898188bd497b"): true, + common.HexToHash("0x5b7c4d73cc663ad4373f146419bab0ce8f783bbb2cdeb8d68ec1be4da8f357bb"): true, + common.HexToHash("0x875d8d5c5dda3e805d5171ec5f7ccc5b4fe96b9dae945cdc1b02eccd81308b68"): true, + common.HexToHash("0xc7ffda58318d9628ee0f2d4add8894d788088de2f5d463e56c709ed41abf1cc2"): true, + common.HexToHash("0xeadc9a7eea6cc1f84dbe19cf11ee4d34f59e9e4aa5211efc8a813d76ffbc86d4"): true, + common.HexToHash("0x5c7f91c34182f67d03479babf017ab1ab72dada3234c77e5fade8b4796ad0517"): true, + common.HexToHash("0xe75e889bdee4b2e35ea1d65a96d2dfc03758a09a13f6b93c5b6bcb4f5e467e42"): true, + common.HexToHash("0x25b89ecd8f1eb28ec0da1112a66b560c32fe86911c8d146642ab009c8ce0d5b7"): true, + common.HexToHash("0x19a9dbc66afc75d571c9be894fbf557387fa59365166e9f26a4001e05182315b"): true, + common.HexToHash("0xd4ea40169ded166e6a6fecaa36515461aed0d1b90f5d1070baa67946d6ad9daf"): true, + common.HexToHash("0x49d83ce5192daa70421b25373e17235ca80ca3626055d062c2cd2c8f5d530877"): true, + common.HexToHash("0x82c1c2569749008f20bb313f3e869a74333f03526fb81792bd1b36e4416e45aa"): true, + common.HexToHash("0x6dd1b851d2118337453273871ef64cabd2ccc376efad88502ea6f518cb3f91a2"): true, + common.HexToHash("0x79535c74b19caac00521fd5884c24dca0df1864e3f38b49acdfab5756bbdda8e"): true, + common.HexToHash("0xd657dc38f4d3e2d3308f114bf0b91004f6656a716bc3e1d21d7a1d72d680b4b2"): true, + common.HexToHash("0xb16d87a03abcc7c445515221881c40d5762b419ffc7e0681220557878628c167"): true, + common.HexToHash("0x624ae3d4da008f4d5d65c5a946fb2dc134ece88cf8f0bbf957bf293e402c5125"): true, + common.HexToHash("0xf1db67e1b6f5c596b21a559946c8f7e13d6a24b5ed63594756fc4e18bfdaf323"): true, + common.HexToHash("0x4b5604e06b6f66649cd9c9e9f3a43b2608107f5aab48488b5bfe37bc5b611886"): true, + common.HexToHash("0xa3b96863da08d000398d8abab11cbc35f923d10ac47d258024b1ab02883711b6"): true, + common.HexToHash("0x48511da849590834f457e83d1b02485546544a430164cba8b1c61be8e9ac4cdd"): true, + common.HexToHash("0x45a429cc0bb6fefedd4667222450291408a8650579e95977f2f90acd48df8727"): true, + common.HexToHash("0xcd1a725146e594c61ff7aef36c857f68e51c13589a4ddde894adbef52c20b37f"): true, + common.HexToHash("0x0d97d8cb66f9fb5362ffebdfd44219a63853ad026022634369bc3e78761382cd"): true, + common.HexToHash("0x33e5a2ca7f2666e60f66fd51decd919bbe614f53ca51487f125d060bddd0120f"): true, + common.HexToHash("0x53c020baeb6b3803fad756fa83e8e6d7d15fc68fd6f8b1c96f4be8c8bb141b90"): true, + common.HexToHash("0xdedcfa116c82c55429ea428f2e4e4da6d15627b6eaf90a96a750c83bee15b073"): true, + common.HexToHash("0x89ae98ec4c520388e12611adf7a62f538b8bd2d9f0eddc5a7afe0d138ad10a75"): true, + common.HexToHash("0xc98b32d9559094c5472267a109d2124a29bbe73f498df3af4636f55fd9a965ab"): true, + common.HexToHash("0x9c5b66cacbfefd6d8b15368e2f535d7e1f126255b43d6aed619a9b271b203a70"): true, + common.HexToHash("0x1c3331f8d00c5f0234724558e672c02f8b6e37d692099fc6b3bfaf4a30c0e014"): true, + common.HexToHash("0x9ac49d45eba860b00454c5368307fe5e1888f9c78fd7d3c1f2d99e7e09ddb909"): true, + common.HexToHash("0x82aa0b8651f18331e745283707e43a72eeb93a602179219ffb39c12c93e88acc"): true, + common.HexToHash("0x29da36e6d5af3b439d34118f962ad8ba9ac11732dc1a9565d151d2621f397efe"): true, + common.HexToHash("0x729528a68fba7be4002c3cfcc6721b6cda732c9c6f0b66044a1ea4c3fed88c70"): true, + common.HexToHash("0xca8ecd4b7dcaea56ae4c84ae656e4ac292297f74f08fa41109a34df9397fa751"): true, + common.HexToHash("0x3790f64d4b57b998eb413a1b8a28eecd37a869e964a236b86866b4d35839ef38"): true, + common.HexToHash("0x59a1528ebb76765c225088004111e35bf9c741fe7c14ee27f8fb8b59db0ddaba"): true, + common.HexToHash("0x60403c3fde3c145a6f7c15ffafe12c9627ce00540cbaa27d2e3aea022af724b8"): true, + common.HexToHash("0x07e40e811d8710e65534b24332c22a0aeeda487e2484efd37cf5339734039dca"): true, + common.HexToHash("0xabd732e8f340596bb3155b577f8f9a961d30ad4a6deb368bcbc96672c1779f34"): true, + common.HexToHash("0x65e56a4c70c062000d46661dbb4e593f577deec43a9a0029a81f9ab87803d350"): true, + common.HexToHash("0x0d1d85521e469d49b37563bf47fd2ccac9a4aa02179fda136034701fd9ea887c"): true, + common.HexToHash("0xe92c7e4c40af23ffceffc04d4facdf4e6c610e16843e42a68719cbde96dbb0fb"): true, + common.HexToHash("0x4cdf85eefcebb4587ad1463774e183a2c83eebe9a98318da0339932cdf85dce4"): true, + common.HexToHash("0x0b51db903635bd88ce73e1532fa2d463a095c72a249a0d52529951b0b0a96697"): true, + common.HexToHash("0x06bfa550ee11e87782efe97831e15e7dbe6973442670b0650e196da1943d3f43"): true, + common.HexToHash("0xa65d0fae836b96d58f3a13f4895f754d71794b89b29bba219b69ecf083b44e5f"): true, + common.HexToHash("0xbd795d214ef6246698219e8e972ef1cf52002eebbb1ea38907b47bcf640b0518"): true, + common.HexToHash("0xa1961dbb210334bd99e3d6f01c4d76162883ceae9bd01b28d9c5e79dabfb835f"): true, + common.HexToHash("0x860e3bf7d993f0d1413f966297797b77fa74a01df25ef972d072b5faaacb3627"): true, + common.HexToHash("0x363f989b1ed763a74255718f192ad8fd47cc7bed2b7355730b96eab4b247b329"): true, + common.HexToHash("0xb3a4f1c3a3d97355633a380665cb9305e3a144a63b193001ef6ddcd7392b8c6e"): true, + common.HexToHash("0x9fdee3700c90d5e2763505ebbc557090f208ad92d3d513d7ece0d8ac526ead02"): true, + common.HexToHash("0x4b352601e630b211fa6db9beac955497bf3899ac39989c753f8ccbe02eff059a"): true, + common.HexToHash("0x4472e73916bc6f9de4991015f032be061f1718bf96e79d88d6ee8a1225bb3fae"): true, + common.HexToHash("0x53be955835b2e36d8a33c31985779d9fce5da711eb4dd541d0cc6a03c6c83e10"): true, + common.HexToHash("0x21dbe86ecad560dff204b4d4ac49e97a3f6b8e511f5d089d4ede7278a020e939"): true, + common.HexToHash("0xa46b38431988522aa10889bdf47b8104e67d731216d4c4edbb394aebc8cc0445"): true, + common.HexToHash("0x5e27e440efab57f6d5b0dd617186280395b1ac4b006d2f470b43af83ffc25abb"): true, + common.HexToHash("0x029af43197758c599cbedbed50b7144f574379253aaea3fbe1afc4f6aaf02c0e"): true, + common.HexToHash("0x74700ae5467765d5ce96daaa3680b9a74862fd1629fc154ace9626ba9532500a"): true, + common.HexToHash("0x46ab003a298a25d9a4e994e1b0d879d9e4f020abae408998b0eee9063315b20c"): true, + common.HexToHash("0xd67d7188ddc422000ae01644a5d3b1dfbfc884ddafff71751bc3fe225873ce2f"): true, + common.HexToHash("0xb407b136e33212a01fbeb448899948e349c9880b6626e158938243cc1f011df0"): true, + common.HexToHash("0x833c9f60276d9a1a4e28c10079dec24c6a61473d1ff27da3145b40ebef30025c"): true, + common.HexToHash("0x1f167ff3f5d4448fb63a69a04e273615438de57a561137839c0edc3e5613ed64"): true, + common.HexToHash("0x3ddf20e93bfaf7f22c209e5b4a05d4d0a470b5f5628db4ee76a8a6bc80c05dec"): true, + common.HexToHash("0x11afdc33e4b485ddb6af22af61be22ebf41493826679bf5114c92163a4332af3"): true, + common.HexToHash("0x87a58361e459e317484be38f4e8c88474ebacc7da7cc92b25a0932e4b3d8584e"): true, + common.HexToHash("0x7c9eba87867725a3988f18acd36fdd9702c07d8d41132a9b3fef55bd1605c114"): true, + common.HexToHash("0x091a9659cb1826c9bb9a8ea02599ec0934e111c74da8a0181b938ca03ea0b01b"): true, + common.HexToHash("0xbb773e602cb41fd09a47856589e930bb3ed74a11d54272b8e56b95b69e85d247"): true, + common.HexToHash("0x5d5314a8cc8ec9a691ab454184573bfdd62029b45059228111fbcbd1e30da16d"): true, + common.HexToHash("0xf75ec8fa8d6eec8997f0a4d032f9d2a57c69d65a453317d3b1177bec525df027"): true, + common.HexToHash("0x1ffee440727bb523011f17cae7fe9ca28d14976717101650568f20b4f1b2d074"): true, + common.HexToHash("0xc0a8d3ef7245d4bb4a241abe996f0ada3bd3f31501e94501b7bf9e9363becaf7"): true, + common.HexToHash("0x352353de72fc57c5740ab1b90603c92d3fc1a3f6eb932239a87a55121c1de518"): true, + common.HexToHash("0xaacd06cc8ec9d05aed899e62611decaf67d55017789410aa49698fff3cf2b0a2"): true, + common.HexToHash("0x1844af4b7d138b9b36d8c5e8136d219e8e244a67bba9928a4090b6affc1737e5"): true, + common.HexToHash("0x52a4b86193e325df6025c889135731d2673932030cb847e93b88f41eb0745341"): true, + common.HexToHash("0xcd25ef035674859db27f06b491a65b73b0c65357e0a46b0469515e86fb85c5b8"): true, + common.HexToHash("0x7b835ed274f0f9ec5637d7fdb946a099570ec81f27697846791aaa5fc94c1d39"): true, + common.HexToHash("0xf92a8407f9348573ec4ec0509030d1b15c985b5ccf6b5997bece92f252773e1e"): true, + common.HexToHash("0x425c00891a7b06fafea3c2c86f46c7064ca386215d0be6fdd89324bb62de7746"): true, + common.HexToHash("0x8dc9c32d0d6aa695ff33007e3047e48a840d015fe58b64513ab4aa2d254c3741"): true, + common.HexToHash("0x5aa92b43dcace612da5d1e9c3d3151bdeed3aa64d94bc4592d4819ddfb156c89"): true, + common.HexToHash("0x7e189010e8437eaccac5377e67fca173db423ff026bed9de2320ee74d4719151"): true, + common.HexToHash("0x2cf981be3f18d5e09c653de3f9599afbe8ed5f28cf0fd8acb55075d15e01e92d"): true, + common.HexToHash("0xbb8e8ceb703627f507471c784749b09f5d39d416e2abdcab4b07f8b142e21bea"): true, + common.HexToHash("0x92ee7c9818d6b1e8c02d93539b0593a989a2ddc1d145f86e2a72690a3f16b9e3"): true, + common.HexToHash("0x85d8d1e1d516d630504da4a448aff4eb6fe1f58d2c6695887754f95202df57a2"): true, + common.HexToHash("0x4c8709639eba670c0e3372102dd1c05f2e3a5f1d2533e265360728e21c351978"): true, + common.HexToHash("0xdaf185d386d717171ec019c60dab7e99aed4f1fdac1c77fa5dae502d6ec14dcd"): true, + common.HexToHash("0x68ce2ce2f20b401a1c782ace4d4edf1518b1765da5362a6a5727565534361ccc"): true, + common.HexToHash("0xc47ae2f87ada2af975a2e523dd275c18ab70a315e87a150deae9292f7bc741b2"): true, + common.HexToHash("0x2d5cd019bac839bbed3aee067a9bc5650c698376aacda67f91a3067088292ad6"): true, + common.HexToHash("0x814da135223e86d1da38fcdbad80b9a474629f7bdfa189a75c094ed8ab116e98"): true, + common.HexToHash("0xe0d0aa4814612dbd1211d34014d270f2e12e629c7c6ee4f4ee28e9c64586ea1f"): true, + common.HexToHash("0x49c18731ddadd15dac5e6015879828d0ed28edc1abceaba1eddd20661c2b4b20"): true, + common.HexToHash("0x1847c1322266a2b77c077f43d96bb2d055809b7f497b6812eb3b18701e97f0d7"): true, + common.HexToHash("0x7d6fe3a8322b9a0a1beac702a8492480d4230450a3c78a37c21650bdac78be2e"): true, + common.HexToHash("0x6103ff146de2723949f15d186b83e3fbab0e04e3965254a3b6d92807251b20fd"): true, + common.HexToHash("0xcb824e1656373791e72df5f6683f84fbf195b89fe3835e2d7c3d7df30a248fe4"): true, + common.HexToHash("0x61a77402a00414dccbd2422d8d91851183aa12d4d6d87a2a5be374acfb47f10f"): true, + common.HexToHash("0x230b17eec3ca6be69210cac8492615ab3d6a9ad8be8210e0877d6e68a461f66b"): true, + common.HexToHash("0x5687dd2c3089f9f9f8f797a54a82ae08f51617af44234a9676badf55d20272b4"): true, + common.HexToHash("0xa40b74c35d4d4067439d41a24a41ad738be7e5b8c2914273c1e879a7e4f3fd03"): true, + common.HexToHash("0x2ab2d76c24b1accc1d27ad1a2389a4805fb22fa13e7d27a4ff24c456bc620094"): true, + common.HexToHash("0x8c61f762e320a63906e33fd08c904134e36395954b3a604c044117fd6fca75e4"): true, + common.HexToHash("0x55b69a7d3bd49dd2b82203f5c0b12861768f689531565680ba0f33c9cf1a5d48"): true, + common.HexToHash("0xb925816cea4c0183753aeaf84c4c4ece096b61d6f05d670764a46e6fb7a4e772"): true, + common.HexToHash("0x04125e7800dfacb6beeba82a5601bf928fcdaa71dec3aba25077a1a8789af7f2"): true, + common.HexToHash("0x5cb86c5b9ad134bf87b26d6668e477c5cd9031b870afbb406c94d44875a63b41"): true, + common.HexToHash("0x947c62eaec96635c6412efb4d0ed4958329a5b5cf3d197b378253e4ebddbccd3"): true, + common.HexToHash("0xec6cc34813c651a27e82cb6ef20c698484d4d29cf8a2503db5fa620cec52b367"): true, + common.HexToHash("0x5826b1d4bcf7d2dc3875e36d5cfa7a818a353b383282c3f64b3e94614bd15303"): true, + common.HexToHash("0xf6dd665b2d7ab4a29f2e87929e3553e8a83e5fd33d7d2ff59fb3d530d2bcbf53"): true, + common.HexToHash("0xf5f55e2e043ae3885c61f35da23bedeaba11cd5de1d7fa13995c3c1b37e15a3d"): true, + common.HexToHash("0x60c5ef9969d50cd549a91d27a61f90d4d98beb6972abc0f87429dc7d74d46ba8"): true, + common.HexToHash("0x6a049758040e3f75f58470103f551e89a8a49c51917bd52487add8cbe1602dba"): true, + common.HexToHash("0x44575bbcbe2290bc1a3d8874f9895a4bcb8a0277ed9b0447fd553ba438f0b6e2"): true, + common.HexToHash("0xa78b0a382f9740cecb620924555bdc72643991d3a6214a66e694c2a91b80e75b"): true, + common.HexToHash("0x9e68afb61a2ce1f88767c12af638336d553fc37aa3dc122fa6db1f0d90f1f698"): true, + common.HexToHash("0x06a1a7675e4eb8129cdc2a5330d32dab50b04b61310817ed916e8a4d2a929a1e"): true, + common.HexToHash("0xd4cc35e491a7a15477fdddf05bd81a1485129bb0fba74085f6149cbaad97f840"): true, + common.HexToHash("0x1a49d2b25b231a90dc99be7b193b85ea26d04963bd00bdfcb9e5ceaa05873b85"): true, + common.HexToHash("0x6b2143973922204d9654dbc73d47a27cb77c029185e6d5b6a929fded8360e9a1"): true, + common.HexToHash("0x6e546149df48c5da31d640834c0c66f9ace688605ff04395ba99fcae0d944703"): true, + common.HexToHash("0x88fc59fb856187c6bb8fb67b8ece018845826ef313716eabe91890658d141436"): true, + common.HexToHash("0xcdd561c6657e279ab7e71c9851b8d7019b2aea9320c41d74bc8572db4bee934f"): true, + common.HexToHash("0x49cb4df1368b441496c578e9dc370a36aeac0dabfcb7a6fb00d2bf3655eafc03"): true, + common.HexToHash("0xe298780df0f7b099657d37e38aecc02bcd2509c98bc9682adee775dd5ebca4be"): true, + common.HexToHash("0x2c7e17357377c6a188ad688d9034c50db4593cef1e38d9ccd3e2c9348d04b6c0"): true, + common.HexToHash("0x113670b2cf17d8e7821aaf72452dd38a226f6778e876215d8c18165fe131ca6b"): true, + common.HexToHash("0xdac7201223c6ebb9399a265b1c65deea2258a63db5cdc80279c93b3d404e13c9"): true, + common.HexToHash("0x456c64215a7063a800029a019a954cd4c297ea0df99503393be238b6a1efab2b"): true, + common.HexToHash("0xe924eff0c3b3659773c4ab8b14bbf730a4031900220f22d387229311c3b231cf"): true, + common.HexToHash("0x6e8140c7253a45d38fc4e4400ddde0ea6e7a944501be5d340f7a5d431dc6e638"): true, + common.HexToHash("0xd99b03d736ab213eed1f2ce10aa4ac873fb15a1a27e9ed56b6eb0ab71f643c86"): true, + common.HexToHash("0xc6a9a8feaa2014440e4646b9f001732e67b15ad8d2ce79c57ec36e4d7fb87482"): true, + common.HexToHash("0x67a2737dbce0ab55e62bd61874901f9bcdb67d8d425e0cb540f31b6362e8074b"): true, + common.HexToHash("0x34c78febe14fdcf3f4cba00186cd0cccada3250b47ebe6a67da0641fd044e5be"): true, + common.HexToHash("0x6a064959b550df9f34bde76e7c2b74d773afe70b8bad1f5af2f19e2363e797c0"): true, + common.HexToHash("0x08402e0cf77812cb0bb40a3577d12feec5b7ceaed3455011be133633f03616f8"): true, + common.HexToHash("0x0ec057651e8978c710f9bd74ac890cac881aecae9ff3fb70cede241cd6a3db13"): true, + common.HexToHash("0x0e8ce95f5b7cc5325e14c2587d8c7c496c61979365d3feeacd483c3b7d96ed86"): true, + common.HexToHash("0xcab05566c776ebf02491ce8fb1d0f3e14ba8da123b7db5d18fb8d4e92fb45fe9"): true, + common.HexToHash("0x2d8262194b1fecdc7bdbf7cdb59da261864136503f750840520c05929d4bf260"): true, + common.HexToHash("0x68ccfffd87974ceb7d55f4146a272349e4afa3d139d44b92cd46ebe2d477010d"): true, + common.HexToHash("0x8e9e3d3f05870c84c91656f3a985f7a451cfc7a02d69d81cee317f9b2b57934d"): true, + common.HexToHash("0xfd3a6a2d43bf8c9d7bc948bbeb75be696bd3ab13b3e5e62a7935edd1643a18b2"): true, + common.HexToHash("0x0bfc3223f899686bb9b91050446c8a2a966cb074e464d92e92979e0288f0408f"): true, + common.HexToHash("0x7cb95f1e4c190602c5fd966e65c8e1ce6386fc4e85ac45095ec8ddee994ca21a"): true, + common.HexToHash("0x13670aea7703404488960e1842f59df74304ea26a6ed5c051aee966b334ff2fe"): true, + common.HexToHash("0xe28d3374d1f193c68cb3da9e9b78c508dd09126d6be50132b617cabb042ffb7b"): true, + common.HexToHash("0x327e5e75d6d612d27a4ce3a32fcf409d6d1ecd39dfabae723663d86affef7670"): true, + common.HexToHash("0x5fe9be410b4b128a8bd0f6e95dbda7c725cb846e1cb25e1d1caf100ad1a90450"): true, + common.HexToHash("0x47d466c46bfc8e7cbf70160a3cef7dcd2a577e308d2b16f3fa5d4c88aa16e40e"): true, + common.HexToHash("0x97e38332bc933716d02aacb9d924f7f9678b8f75c140814cddc22ec87570f226"): true, + common.HexToHash("0xbfd1a1e42a02d248608f3852b01a7cbdbb87a4c86db6100770c13df525ad1d05"): true, + common.HexToHash("0x2b13d3afb5a4e2a5fb400313ea77cf2e94495e0d543b3e3404f827f027be891b"): true, + common.HexToHash("0x84ec3a2420e07a7d7db771a88fc4e5013a6bfbe9fdab3a9d846bf413621da0ba"): true, + common.HexToHash("0xc5b0f2ab91a2f2dcd5fe60074fa5246a46c580eb7c05a20647619aac48355a06"): true, + common.HexToHash("0xd35148c4e6ea2ea0e057c75a92f71d5725f27623a1b163ce766a903c562360db"): true, + common.HexToHash("0xd5bd9f1ef80ac4f0e5cab4c5076860045b5a523ac33a8a6416036d04f83ee55b"): true, + common.HexToHash("0xa8a6f62eeb2b82771047339bb0b89a8cfdb160bfe645a7ec5ef2e818b35bc9d6"): true, + common.HexToHash("0xf9587feb9235d1f1c52092e6c8a67d038212ad235a7411fb0e76919ffd44a903"): true, + common.HexToHash("0x91b1fdb9191925719335648b575fbad1d303e6acd18b52b15a9dc539388afd09"): true, + common.HexToHash("0xd01d43d23983f609951159932dd926a62f183524a8f5e0947262caca4313912c"): true, + common.HexToHash("0x667c854ab53260633f761a7ccbc2f97d53dba0223db8a7667d0e11f3764dca96"): true, + common.HexToHash("0xd5541e8c7cae08791f8ff571c09eed75618a84c61c63883c8c0380fadddf2e06"): true, + common.HexToHash("0x3f9e742fec9262c5039a615991f4da42d913aec1c31763e6671a969c11fe2296"): true, + common.HexToHash("0x5506e963f41b41e2bae3b45922e98f2a139f776a1610d81f837d8230186f1853"): true, + common.HexToHash("0xb417f87e13a6b3252c6589b4f02be32fe5ce26fe1c33192402bd8e934e352639"): true, + common.HexToHash("0x659b4d596b16a85bcdc40812c191b2e652c7bf289c33d63638da88437b3cd8fd"): true, + common.HexToHash("0xe1ae464974b481593f50dba2e2a35afad47b8cd5c07da6fdea55dd5003556e7a"): true, + common.HexToHash("0x5b7302e8f92ba707f856af4520d68438fb9437460b5a15a9523272acf3f24acf"): true, + common.HexToHash("0x872b5fc3ea580baab3cec8957fd2e07295c5a34d79a77fe4ce2a262401b29947"): true, + common.HexToHash("0x99f5acb18a60a1e23f099e1fab00053e850146c34680dd57319f8581ef9a2db4"): true, + common.HexToHash("0xe9e75f9832c9d5530f2c5f8022a868b3a9b386ec2e917939c77ffb56ab1d14b4"): true, + common.HexToHash("0x36ac706f045963fc93a898c646cb6e67372533ab108f06861acee1e4e606074f"): true, + common.HexToHash("0x08877a9e930848241857958653517d71f1ae121a1fd2b59ff055d715bcceb1c9"): true, + common.HexToHash("0xa13635d1cf7a26c15198c884aedd125491ce7fa6794940b93cc85ce7c8d5e20b"): true, + common.HexToHash("0xf34410395575d0ec748c6e934d674e500721a93ec9e967bc72008a746a155f64"): true, + common.HexToHash("0x89717a8f111d50c9387a7f8ee552096fac737d650801cd8cfbf25ea13c3fc273"): true, + common.HexToHash("0x0c45bccde9a1d9c101055c597f98610f621522995b2ca986307aeb03866472c4"): true, + common.HexToHash("0x6181e521e11e5d369bd00af51d0fc9ee4ca21208555c4684d22ecfd78c27c32f"): true, + common.HexToHash("0x6914df76134c5df58f7809ee1c2afaaa4a436eafc0734991d56c87027bc33b38"): true, + common.HexToHash("0xaeafb7fe8dc1d3392d3459b508be1638b84ea5ba24957f2238337631c6709b73"): true, + common.HexToHash("0x15a11bffb51552682d3efbbd05793d40da1c3f8236d05f1fdd3ad1aa73bc4982"): true, + common.HexToHash("0xec2aa8546a598ed9607c666f7c1e3eaef1c6cff26e3fff38e0cea4014f283eac"): true, + common.HexToHash("0x30a48897f539c4a1fbf16a3240643683c1427755c7e7e5689590e8831c5c8246"): true, + common.HexToHash("0xd23a8e2bce83d3a070ba2be1e9ad2afc030f8447bbb9ee68a15b7c58e485a45d"): true, + common.HexToHash("0xa0b60ba459cbf2a49a6079514b46218ce550591daffab8924daf91865ffdc44f"): true, + common.HexToHash("0x70cd633806e01a6793c60cb163b1a4d1f8334319e9da5f89a289802ee1acefe6"): true, + common.HexToHash("0x592f267326e766d44f903a37d2711a96e0c86bd6f921405667be827e2f07daf1"): true, + common.HexToHash("0x65c22b1b7c7955c03e8a291f27d6d1bca8d9d7f61a3923cf52e6d5887670557e"): true, + common.HexToHash("0xbad2c93f6b0ea84c2e707ae1cd135e3c34ca29ffd39e4b31752f3b4883ed11ee"): true, + common.HexToHash("0x5611184e7317a4f7542d366333fe5a41a70653e8ab40997430d52416c881417e"): true, + common.HexToHash("0xa82353e065f1b1296338d7adac9c99305cf0defe7007b9fc15b4efa79d32efc8"): true, + common.HexToHash("0x15332169a9c9ed64c85ba7cbe59f0c4f67cd982eec3b987d806399eb5f084ce2"): true, + common.HexToHash("0x366d7cd9edc1b8d79aa69f22b52adffbb9e6f20f971bf7be788aeaeda88744b3"): true, + common.HexToHash("0xcd08770254d22a26d23860d7bac9505b4bd867018e87764148e12ddf1bc10bdc"): true, + common.HexToHash("0x67d60283f9410d74476b7e6e51c22e6706d14c69c0119fbcd17024ecec01d3f5"): true, + common.HexToHash("0x3ebd72275968d6f283f12ade1c83122ae546ed5ab419b86b05fbb27646f08c44"): true, + common.HexToHash("0x833b5d9b96e0191b37cf20445d7bf93b33de0f224ee2d9691afaec934a769980"): true, + common.HexToHash("0x86dd4ec15fdf4621c7b1b4b06fa3f7dd80a8aaf16babb9f20cdccff7c4d627c3"): true, + common.HexToHash("0x053ea2a73caf9a9b1f951fe164b10bc4d0f4cc37560a58467e6cf257b4beffc6"): true, + common.HexToHash("0xb3bd5a494fa445515fd28dc96d4c9a16ace99dc53243f4f282c74a1414242689"): true, + common.HexToHash("0xb4253af6ac9a630dbda8fd53594710c4028d1d4ab50961b151607130d2966dab"): true, + common.HexToHash("0x833d79b3ce1a5e22ab61b3000473c4b348cc86c4ad47701fd00aa93998c88206"): true, + common.HexToHash("0xf15c2197f6fab1157bde8491959f53bd90f5437afff4c9509d2567ffb5f95590"): true, + common.HexToHash("0x8f6efd73767dc84451c8dfa43aa54a7fea3ed30b342ff65d0eef1441fe6948e7"): true, + common.HexToHash("0x7ee89282535e13e62486f6f8449877a9411c847cd467134f3b0990c4bf462070"): true, + common.HexToHash("0x15aea7865fd290dec991e0e3aceb80cc023233dc376ebcc654c5cdbdea26bbeb"): true, + common.HexToHash("0x6c4981f2b1c317e44c6861bf7ad93312359911ee0a1a90f1055c7d719b52099c"): true, + common.HexToHash("0xc4675053ad7137cae7137605ab0ab66129ca1699fc2be6577f6d607cec343dd8"): true, + common.HexToHash("0x4dfa439943f66f9e4ad9c94bb180e606975497f813128a99780dfd4da0daf9ab"): true, + common.HexToHash("0x653332fa082b574419db1abffb25f3e516b8bfb8a4548648dfb9c053982cfa17"): true, + common.HexToHash("0xcd185482f496e949021476f9f09826393feca24ce90f3954d103078c2fdc4607"): true, + common.HexToHash("0xf126fe94d66b892a83ba8304c9111f3b0f267d7599db881db91892d185e5cce7"): true, + common.HexToHash("0xba96691d71f154cd1564b2eea3fa374cc239b6e7c587159dcc8290b774bd789f"): true, + common.HexToHash("0x2fe8f3b2c824747bc0b0ac6e7148202a877b911e210ac9caefbdd8844697f078"): true, + common.HexToHash("0xa48c8852e1eb4c57ce1bf0ccb0af04deef2fe3671e1bf8a877adc3bc3b646979"): true, + common.HexToHash("0x5ef3253244d58b496a071e94d2bec87d20dc9ae535d66636bf89fb9e6e4e3a5d"): true, + common.HexToHash("0xb20aed4b7f17222f69bbe241643ea97b399f5dceea52e144ca7bf7e2a3cb6a8a"): true, + common.HexToHash("0x3d2e314b334a3ac614838fbdc6a9dc0d3f6e14b4657c8f958b576879e3be08fe"): true, + common.HexToHash("0xef99d845a0b260c900eae51d2d23062b5d323468887b8bfeb2f810d24014860c"): true, + common.HexToHash("0xfb3e572cc96bed008b64dbe1c30756834efbabed6ec1f2e3c32cf2ba66bbf0fb"): true, + common.HexToHash("0xb0c9be3a3e2a5f1805506d7fd40619f48dd1ca82606f9514d21439c9cc6fc3e1"): true, + common.HexToHash("0x9995e2095d5e6801b6502d871f416e6dc301f2b814415d85f7e24c5d25fa09c8"): true, + common.HexToHash("0xab8b4059b65b5cfcaf4df57cf04bebee0f73965ea4e9a56a6bcaee4cec06e303"): true, + common.HexToHash("0x398320d8ecc57f11451c8f589d25dfc97e74b03b2fcdedd1c2ed953913bab3af"): true, + common.HexToHash("0x44344e656763eebff2c854168c102fb897c36e95dff727174539e834b407ee1e"): true, + common.HexToHash("0x483bdcbf02d29feb5925172a6b552828746e293a19d23493d15415daa5bb5f50"): true, + common.HexToHash("0x005f8d31141d63ba75e3ced268fc96bdc4ebe6261ad29c513c2e2a17adcd3099"): true, + common.HexToHash("0xc25c14679ae8fca4b191bc308a1364d7d5745c408fec657b773d04b8dc6bcf69"): true, + common.HexToHash("0x718f06415f030bc6b4d9c5482586448a22fc84fe52867823b24678822dff09ed"): true, + common.HexToHash("0xf02495ca72d54d8ced0e1e4c2573bb00d443e2ffa1149350e870542796f13bbe"): true, + common.HexToHash("0xec8f4f0b8540deeea913a1047a51c9585757a02d99bfb005d5b164048e0b1130"): true, + common.HexToHash("0xa0af7e22828c902892504dab7720f6fcf2cae3ecfa7c316dd63789e4950ad4b8"): true, + common.HexToHash("0x15acfe68f268205265c36feae60eb3023ab6a9f1806939cf1cca9096f5ec8b00"): true, + common.HexToHash("0x20b9c5096258fc86ae61f811a106899f6f75792cd13111ca54e31da98b3e05d8"): true, + common.HexToHash("0x1f58ab1a26052c72fdf69ca93c1fcead4e1f34869ef15e76ae3b94ba55eec643"): true, + common.HexToHash("0xbc983657435f118e164b5e59a3920fe980c1364918451066a39c7005f6189065"): true, + common.HexToHash("0x203e34a745852e630cda993556098f2aec1bcdbe3a9b18cfc7aec05d7c8adb47"): true, + common.HexToHash("0xa7af52329fb12f238c75907031f1be872b36c74b86edefbb4a140442f376a61d"): true, + common.HexToHash("0xea3a1f7c4dfaa92a9ff70546f46d198f8dc1dd44fbe962e8d6ac3f1648a0a8d1"): true, + common.HexToHash("0xb77cbc6bc1f637dc810a90965712c5ac29e305d64faa342a317ee73db627a7f2"): true, + common.HexToHash("0xad760d229686c58c97cb35c9f66027cedea954f2c80e2876aa61526c4dcbf87c"): true, + common.HexToHash("0x59e78963f11179572ff134797ab420a8538c68db8b01a147e8b0cede249ddcd7"): true, + common.HexToHash("0x31f9fe3d1419eb059c0e35690c866dc154de85547c701bf44d2d7c2c84573b23"): true, + common.HexToHash("0xd6b606dcd4e29a60416ae417dbd0fd3c9161f8adee815f707f7868f6734e9081"): true, + common.HexToHash("0x45064c301f7250330d237572fd3962b71b6ef3bf4e469b957a249df15a99a32a"): true, + common.HexToHash("0xfcff439e01c2cf2c93d5c0cb549234029a65d3c6bba27ae250a76bab60429920"): true, + common.HexToHash("0x933274456ed2be6602ca13947a99765eed2f091ff8cb238f787afd4b7e23f251"): true, + common.HexToHash("0x20a84c670dbeb11dab962c6fd48540ec149465fed6e762dc408f3eed3635b3cd"): true, + common.HexToHash("0xf00cefb5cad07d9b7f257ba89ab06c9d2001f32003b2556aec9a3ad4d95a57f6"): true, + common.HexToHash("0x2e97bbcdae73382a2c6112f5c8806f251fae25ae3ef168e350b7533cc2c35349"): true, + common.HexToHash("0x8d3b0378d2737ebb7f35001b8cad52fff7119f02d14c30657c7a6c0b0bea9e18"): true, + common.HexToHash("0xf5a799ea020e41f83e6fd247ca3f1c9eed569198eb4bdf4e55a41f8abd0828bf"): true, + common.HexToHash("0x62acb240816ff011576887ac817a4b426c14411df803660dd857fad092729493"): true, + common.HexToHash("0x305caa07f251babae55f070d8bd4e05cf2d4b562c22bcd8fd87392e198d013c5"): true, + common.HexToHash("0x00bafee82daa443033c8dacfc341f2ea22ebfc81373cab2506a5c72603db8c89"): true, + common.HexToHash("0x893964e67f862e82aa8ae4a6f9a2d1a384cbb1c6e0eeb8583d39feafd8feeda2"): true, + common.HexToHash("0xd57fe1d0288d33c6094703e466865262668cc4a77eb97002fca9d4af852bd826"): true, + common.HexToHash("0xb52431ace4be9d3e2a5a8d5647671888b61689e46ccda71fadde15558795618d"): true, + common.HexToHash("0x542e56ae6d0615e86aa3bf52ab8787b66a40e21826b391ab2e0c671d4d01da70"): true, + common.HexToHash("0x647de671eef2af259e0c7d43f5304f8b3baf6daf20e2a33db140f11bae9afbd8"): true, + common.HexToHash("0xbacf730a7d763ed63a5cd95617cc005b986b6cd1bec3f1a27247027545f74003"): true, + common.HexToHash("0x2a9a74590b968f1c55b0456eff4bc3fd4fc195eea9d461912dc48ed69424a390"): true, + common.HexToHash("0x609a9bf275d1a6783d74a7bd37888b157e81641740ccd77cdad826ac2724b8cc"): true, + common.HexToHash("0x4443ec56d1616bc4c8b74605cf2b677d3bb2ddf2a0b4e3d9c70136befa92db04"): true, + common.HexToHash("0x9224ccf0843ef458a6fe960486cf04cbce1492eb3f17c3b5ffdbb8d090353782"): true, + common.HexToHash("0xda9cd19a9e9473391abf8ca4f049a42b3d7f6813a4be863057b0480d42d99c01"): true, + common.HexToHash("0x47c6e7d67543f1dfb7eb3ac9fde6ab4af446756c841c702bb3673d96bc39a354"): true, + common.HexToHash("0xdc04f6f9efdf37860ae647b1d5096c29ab67a62e8010dd2c2603411ddc9e1821"): true, + common.HexToHash("0xae1cca9682e73ad416b5cd5bcb45fcd682ede7fb2b2c81236097b0d6f79d1802"): true, + common.HexToHash("0x8b4dfd20f85948e67c4cde5aae519dd4ce0689ee4e6be494b8c5482f77e63fa7"): true, + common.HexToHash("0x44b516e2bcffc6a0c899bd686143faaded252e80ee6b6ddeb8af804c12299e54"): true, + common.HexToHash("0x4c90eb9c887b404c6bc354386fe0feceb05edd7a249d23aac4d1953bcf0c31d8"): true, + common.HexToHash("0x4deaca93db9032737f16bdad4f3c4992f1a441d4ac78bfccdc028a875ffcae27"): true, + common.HexToHash("0x9eba1a07086362fd2776f3dd069ae8c695a806590fd175e3da01d9cb3932e59e"): true, + common.HexToHash("0x06a95f88584ad268135bd9996ccbe81dd986f42d3e97e02ad94953945db0e71c"): true, + common.HexToHash("0xe61a94b40072c9cf73fec6c93684de558e8a98a7c34deec1938f1fb6ef16170d"): true, + common.HexToHash("0x9277d1c291afdf5723c8a971eee10c008f15213e5a5153f33bb61ffc7db954f4"): true, + common.HexToHash("0x24fcee5fb59601dbb25fed1364edeeda3e43ea5fdccb6ab6c2b6d426b3da9952"): true, + common.HexToHash("0x2b608198905e3fae25444572d4f7854963bd9d5e80b825b5468947d81b484211"): true, + common.HexToHash("0x552cda670c0434531ba02efe0d54bd17ea68bd0635a5713d7c91c271567a3a42"): true, + common.HexToHash("0xcf8eb7673e40cec55b45be736532a347bce4f9869bda2706874fd8d1935b38f8"): true, + common.HexToHash("0xeabb141155fc720c526e835bc344333643291a9bbaaacca9fc6796015ddf10c5"): true, + common.HexToHash("0x02ab97ce9d6f019c9686b76a0042a6dd657eb78cf6c8a1a12293836c3d2e3178"): true, + common.HexToHash("0x106d5de1d546bcb47b7f9f59960abf466cdfec065a9c76655fc740c05c5ee2bb"): true, + common.HexToHash("0xfa597d0cdf99e20069a205b31c2eb950e8461f91973f970e32ff95d5486f9ec0"): true, + common.HexToHash("0x40d7af367be88d00edb4bb69b20599fc09f8ed4911210d0925bcb032eba772dd"): true, + common.HexToHash("0x2163315e44e5f4da87bcc287ca6180441acee57b1b31edd5350a398d429cb56b"): true, + common.HexToHash("0x44287f64d422a25139cb13eb8ffd993582dd056db84849ee9e4fd58ae0146902"): true, + common.HexToHash("0xb5595965ac81eb4a8092f41c6ca10b98cafae652f13cd0486cdaa2915ddbc662"): true, + common.HexToHash("0x1f57bcecb96ed2b413d4c7b7e8720d4d8be6add619998cba758b210b09445024"): true, + common.HexToHash("0xb24d3f388df75af286cd4d39ff8b75e44fbe1e201ccef66eabfcfef71efc0219"): true, + common.HexToHash("0x991fe55ca9e38e0f6ac01036dec8d793225edc844071874223941c3599105062"): true, + common.HexToHash("0xfd2034fed00911af6da7638de915b7268645466f3c380f7a354b3621ad5eba29"): true, + common.HexToHash("0xb9bbe714af522a6e86667db48421a1635c60b24a00ad96b9865f8bb0d40981f6"): true, + common.HexToHash("0x14223cf3471a2bb535543e048c94a80c6972fd37ff4ee71a2ec6755dd6c9c5a1"): true, + common.HexToHash("0xc7765f46f82a44f31815027b71ffe5a80fa65da31e527a0b46974c46d0992c7b"): true, + common.HexToHash("0x0fe984174f72d210fde048bbf86d3534a372b31ee3cd66cf8b73bb2780c7c6ff"): true, + common.HexToHash("0x020a73e331ecc0764d831c68a1db1180fe0d1153b67e7fae39b606685e33ce7e"): true, + common.HexToHash("0xa3329e6173016dca67125d66f022aeaf3df6a3ebd0c01da540271aad18fa1882"): true, + common.HexToHash("0xba888fa7826f0088a735ed6d37bdec774daa11dad84f7d0b8f2688d022fb5644"): true, + common.HexToHash("0xf059bd4aec4d6d53eeec75f03e2a0b16d7d931276a986d7635a8e74614b9063a"): true, + common.HexToHash("0x9fdd42803716b9e68de6ffc7c600aaebe9b21f2c211e6be816097d213d6eab98"): true, + common.HexToHash("0x52fecef881cdada9dac4223d413d78f529d641bdb19adc36f6921ad6327ee84b"): true, + common.HexToHash("0xe3175c8637c28b5d316475944d8308b0fba814e6821d18d09c80daf38b223e4a"): true, + common.HexToHash("0x0b93b4e6723396693eb92622e21ad690248519c4b2d4ab47225b7c540b0694f5"): true, + common.HexToHash("0x5b6b1a85da83bf93d2f859014d9221628993fc5494da4e426cfd45d78af0bc4b"): true, + common.HexToHash("0x84353042baf4a3ce32529a962d0e8074655f817a8fce421b50f4bc2223f65778"): true, + common.HexToHash("0xf20ecc7b3dd779a88e015ce510c16043cdc44f769bd67a93ba32b4aeea6102af"): true, + common.HexToHash("0x126730d4a785a904d49f10fd71c46d89eb36bd04bf1a439c489747a8e0537e05"): true, + common.HexToHash("0x0f0526191a812c64e5822fbe3b6896ffedaff46dab7f206928e32d42d5b991de"): true, + common.HexToHash("0x95050b7f8fb2e052347aaecbf03949b918444c35ea3c8251234516b2703d1538"): true, + common.HexToHash("0xdd267585804903cb4831b02c32b0614a2ac08716641f3c51ef6236687126047d"): true, + common.HexToHash("0x1d7bd97ab4aecc5ca9511d66e998d76a8a795ada880ca068a8c50b42176636b2"): true, + common.HexToHash("0x6517ebda072a08ff5df34d8ed393d81bce50e6e781265f0fe8226aac2cd91ce4"): true, + common.HexToHash("0x19788b85e9d35f43637a2ddb448288587e47e3ad4debc024e56e0024ec4c71cc"): true, + common.HexToHash("0xfbbddb3cb336371749f46c6a1138b8273424c04aada3c0b79fadf47f836c8113"): true, + common.HexToHash("0xde22333584cc922fbc36029e981263b54b4abadbc46bb0802f57cdd5ef5da20a"): true, + common.HexToHash("0x64275603289ff3e491fcb07450ea5f48b01e63de9f96c35063afa60a8b50666c"): true, + common.HexToHash("0xa791276c25186f63db188176b02fb0774567a2fd0fd4e75a83193eeada5e3238"): true, + common.HexToHash("0xb9d6e6d7f452a2cf3b86c3d969f5a0a8879e41b6ce9367b50be24836a70e08a6"): true, + common.HexToHash("0x31a120da41d2fc32907ad7cc975787bec1f7899e2aab713b8404113b986b507a"): true, + common.HexToHash("0x767b6015c8ef490983b2ff0f2b29f154423e856402c9697e6c83e3db4a3d2318"): true, + common.HexToHash("0x8507d4bb57569dc735f5f10205726ef7676422a3eb90eaf5db458e48f9a8b320"): true, + common.HexToHash("0xbccc17f618f3b6d5edfaf64faa64207b66fa8245e64e866080d66f95a5694273"): true, + common.HexToHash("0xbb472e461a5d58ffae5fb1405701247360eadfdf0e6844624a36db0b24309988"): true, + common.HexToHash("0x153207c1feba56c9bd492c3e14ff857962eeb1237ccbbb591910819399c8fdab"): true, + common.HexToHash("0x34a810033374dd866e2901f9c5dcfccfce96773fe0ad00bc2e7d13299aa30cf4"): true, + common.HexToHash("0xc652b62719fb3e75cff31fbfdbf3588e6eea2bbd0a755fa3f9657c68acf5aaf0"): true, + common.HexToHash("0xe0dd399c69781e0089b2da5c93328e5674b066600cece1b346818d6b2321efe3"): true, + common.HexToHash("0x67b56be70651c4ff62cdaa7660719e25eb629e8419ecedbda6eed0dcc614f6ca"): true, + common.HexToHash("0x9ba2e2d7221d0ca7b5115dda66aa7e99cec9d7bba0518702af8c2ac622cc5da0"): true, + common.HexToHash("0x05c14cd85ab2d546e3e3d29b86977fb03814c4f58dca43a12de1f7719b61bcfe"): true, + common.HexToHash("0x6f1f136ef01bc28fbb2f7ef59951590c5fe0e55bb9dcbb6ea8e70a1e53fe29a2"): true, + common.HexToHash("0x9dfdca7189b5602f0bd7d243bc386645e19ae2085f81b9a39aa5442c386c6009"): true, + common.HexToHash("0xea2a887bd9ee4437801ee6f51b8cea50fb077f3db8f7da71c234683a2e7c87dc"): true, + common.HexToHash("0x7e756f6aab3d55a49cdfffbe3e7c0f8554ffc1d4fdf8f41c2274afaa78fec5d2"): true, + common.HexToHash("0x69af633da8a01af402c8343728c50ac970a22afd67fc4070a81378d8d0fbdbed"): true, + common.HexToHash("0xb2052490ca896d1bf0467d5c739d3b2b9e5824c0804e2c081a4bf59a1fca0628"): true, + common.HexToHash("0x978df8a24af47939e5d601ea38bfd33eaf747b697754f27de0975988413fe11d"): true, + common.HexToHash("0x40fa6f2df11110f719f36cf2a8dddc25dbd58f390bfaba75d630a05484e5cc64"): true, + common.HexToHash("0x36cc84c1d4751bb2f2f528e0c751f4b8597e7fb738377594dcab05c78ea80327"): true, + common.HexToHash("0xcef8f28f0db60e7057b15150d11140f25cd37fe04da5de4037a7154ab59e4fc4"): true, + common.HexToHash("0x68593b1ebfde0cd84f8260e78b3b33fa88dfa8c1a31a0ce87ce1248f00052f62"): true, + common.HexToHash("0x0f8262404732aaa98a7bc4d3ce61de39723a740f55be51c599a35eddb6438f1e"): true, + common.HexToHash("0x31eff5c499c93f69825902bd669134c470219742a7158ba6739f8665cb3852b2"): true, + common.HexToHash("0x9dfda524338513e2a4dbcaf4ac7ca817310e50ad56ddf3867c4bdd1677ddf122"): true, + common.HexToHash("0x84f1801272c6813f15e4b8acb2eb251e8e9b39c7d7a89bc2e5d2870d261cf9f5"): true, + common.HexToHash("0xbfa790ddf8928388fa4a8847626b3c0f5305c65e00f4c8cdf1bbc58d6730cf96"): true, + common.HexToHash("0xc93dea000fc544df01280a29301cc2d9ffd0e3731b84ff76f847e5369fb827f8"): true, + common.HexToHash("0xfe57d1a2a48747608b0c240421658b93b745a6de8e4e5dedaeedff9c22ff637f"): true, + common.HexToHash("0x041497608c065bc398846409af30dd8ae6ba2f7eb3ad0514ad2e1f9378ea891a"): true, + common.HexToHash("0x417b553f4ecf1fef72f2ebc8ada29a9fb0a7ba4ee153cb5edf2b32d2e2e10144"): true, + common.HexToHash("0x1e8e6db20a677ab2f17bda1a3d44f49840e38ff3deb8dc9c270aa78702f37d3b"): true, + common.HexToHash("0xdd1786debcaa99cb635edeb49b4705f43426b8b36cd507685e661d4c647f2b27"): true, + common.HexToHash("0xfca3516029eb376bb91ba3b7c0f13f34eb6d200b75fae9b79c92d4f0df3a8aa1"): true, + common.HexToHash("0x209860d4a0ee5d1ec8b5e79d87a7f20fa9aea2214e25b5c357417d6c9d57b2e7"): true, + common.HexToHash("0x5323553968cbc636174772594c0000fa1d2e25829d500946bc2d3fdeb631a04a"): true, + common.HexToHash("0xbf68ce0efc789a3cc538afa14795c5023086bb1373dbfc4562728273a78856f6"): true, + common.HexToHash("0x7e5d720a82c67204650bc8a2702d88b30503eb2617c9fa552f3eed753d56c8ea"): true, + common.HexToHash("0x946eb84d85d167bc7fc8d48a3e8748b2e1df2cbf090b825e25817e87cd831cfb"): true, + common.HexToHash("0xf94a4f08ddfd4b86b84a9edbecd1c2c8ce7aa36605ac285c40b7620adc8212e3"): true, + common.HexToHash("0xb4932ce759c167d016ad0a65b88b75156b6a0f0d18c6e544843095af080ee222"): true, + common.HexToHash("0x40618e4540f37347b96fb7314bf446c2c9fff01384506ca1b1659ad0d8719dfc"): true, + common.HexToHash("0xc42e676a696f9138d7d42ebeb632dfe5c71413f0d83efd3d5ea11e45b5dc9242"): true, + common.HexToHash("0xcaa1a977850553c5cab444558f073787dbb6476a1165955e3c92e2929ac83001"): true, + common.HexToHash("0xa8f9e22007e415d009402836b5192a7bb928c55ae721db99b741714b7e929c49"): true, + common.HexToHash("0x50601024d81049af1036bd5544664a6ad57eb7925fbf78b71065b4b8e483360a"): true, + common.HexToHash("0x278beefe7123f25e030dc25aed1b2e982b235e03d8921babc16ad76f5260f4b5"): true, + common.HexToHash("0xb22cf5217f38ba611fab8779338792e8cc37db386b9e38fa709c2adb40533558"): true, + common.HexToHash("0x76a4c553a50d4c81fa8af40a68702b58a3861f24d05a761c38302c45f90f0446"): true, + common.HexToHash("0x5d63f2fd27a744406f66761cf526d19610fbb8480649b9f8a40f390de01a8efe"): true, + common.HexToHash("0x848c2a93d74ad3cd63d9780ec332d975927a004b9073422956cbebd8b1fb8403"): true, + common.HexToHash("0x90f3e6cc99f6d73eff93165642f2028cc8d6111b0319f36bf78f76c5662f9a30"): true, + common.HexToHash("0xa12c2304fd9fae5a49198c1677aa63961a83c84f2ce7fb57549a43804ba27e92"): true, + common.HexToHash("0x6fad07dabdc86870a32fae9d5e3f43de44631ffdd057f1b7c1732f146df16fe8"): true, + common.HexToHash("0x76789825be37a359860e5d9f08b494cb004f05ea6f01fc07b3364cd5dc4e487e"): true, + common.HexToHash("0x5c04c3a168ef070903c4629ca9d0a7527a500c76e7eca02073f11b03f90da6d8"): true, + common.HexToHash("0x52cee676470d5487ae9eeaf645a8bf2763dd5feb799608f5f478a773d3b821d1"): true, + common.HexToHash("0xd7d9370026a43c591d8f5fd7756d396339dbbca226cd5e70ac4de8df4d806103"): true, + common.HexToHash("0x00607028d4b98bda59d2b55968494f389d25a34da490d6149e0afca0ad68f098"): true, + common.HexToHash("0x2bd8442e590f3c2441a6692b748662fb190b666d119521fc5990b8f4f350b0e2"): true, + common.HexToHash("0x931439206666515bee057b9f9a57bea3da45167c0945abacb402e7cae3f19c2d"): true, + common.HexToHash("0xcdcaa44fd37956ff9746e5b784fd0c897c37dcd62b5006f78837cb41d8eeca4f"): true, + common.HexToHash("0xa9dbefc76fe2ae82e08370ff02b1b672d8e5f695d2d05a1f1552321493859891"): true, + common.HexToHash("0x74b62c970ded25c9ed8aa06bbc53dcf9dc8f9df304b8bdfa8cf5e2d88f3b798b"): true, + common.HexToHash("0x8216d5280feaf68c248280cf88f241d37ad606a74ade724f84f4998628faab8c"): true, + common.HexToHash("0xbb9b27a99aaed29231878766bfd4b58428c3de2d3a67d9088e210b1742881351"): true, + common.HexToHash("0x986355e6142b12addf3636e45123afb73ba869b08dda5343ef7223faded94d9b"): true, + common.HexToHash("0x946a23803b0fc0a47b3e303f08ce4b1fc6bcb422dd49442680d62bd14001f37d"): true, + common.HexToHash("0x159aedfe4328eb76572811451f16fa4c6586991222f1c3d51c8121c719251d86"): true, + common.HexToHash("0xc9fedf83928f69769a9c8c841e8bb8c2881b04d3b0d6443f80e1b8e75df38c97"): true, + common.HexToHash("0x2ccd3c8e6a89083a66c6e08593728e27f74a917c9876ce1fa5f3cdc92cdfdb6d"): true, + common.HexToHash("0xfce9edb97176d672dc11fa4c92e7a7ad865d5808d81287be8e63d977cd9a1ecd"): true, + common.HexToHash("0x1f5b526814ecccfc90c332453294e17670cc1f0770bb1f4150f44bb13931dc01"): true, + common.HexToHash("0x8c98a073fd69db6373aab143cf101b75502c1d335986c7e82034fcdac29884dd"): true, + common.HexToHash("0xf65bd612bfdf65ab92f70a0e195e7f497221e675482ee2d7e08295b17ed2ce79"): true, + common.HexToHash("0xf89377eb834d79207a14f6f86c7b62f5a408fbb8fba8f50454593a91a726d701"): true, + common.HexToHash("0x74a9a26d63c8bb71d4792d8ba78ac72686a6316a0429de36ceb414938332f21b"): true, + common.HexToHash("0xa8b00ab9cc2d19390fd7b078f4f941667e0215fa5351079179b29b0932bf22ec"): true, + common.HexToHash("0xb67164a526a77762a4f67e4995ac692e2a2165d7cf7ac62817997e6e9bd3c70c"): true, + common.HexToHash("0x76aea6945fa02183936fba8ede7866f4d7d3672e266aef38689550df84117527"): true, + common.HexToHash("0xa1d550fb3380d00d689a9867c8cbac81c3ee8035b015051742367989020f6ec1"): true, + common.HexToHash("0xc8a172abb3a1e43d62c98d5092e5eecf24f72126d30985593ca206f74f8dfce1"): true, + common.HexToHash("0xf2c2c2fbcd116105df3c17d5d74dd6dfa9937a932282a3d5f352e286bc609f6c"): true, + common.HexToHash("0xb695ccac12a76ca26669a67b2c7bf29eef94ca8e60130220b046e8d1569b056d"): true, + common.HexToHash("0xb158bba6da57acd1cff1dfbf3d2c109df513bd89aa9512e54e911bcafaef42bc"): true, + common.HexToHash("0xf4dd88260cdc8ca1384b988964b63b0875d79b7fd5003da30f2e8b0b5a246777"): true, + common.HexToHash("0xab9b02729cc34f1bb7af87a093c125828c68d6822062cbe4e6ac18199399fc0d"): true, + common.HexToHash("0x1f016d7f2eb35acb07ffe3cbf9c4ddb101a519e238712b040ebf2428971fde4e"): true, + common.HexToHash("0x133a94071ac096b96188bdd9dea2c9bb078a5938418a4722a7edaae990051791"): true, + common.HexToHash("0x34ec60c632e32a009ba619477b64566de7b72d9f477b35d646ec15985c4f8acd"): true, + common.HexToHash("0x37064964c7e40808f5d86de6c6480369058b9785c4db3f0cd55dbf17f0085e40"): true, + common.HexToHash("0x329cffa313ce54c3dcb00e95ac95ff812f5475a8ed213f6858c3162c89f54f97"): true, + common.HexToHash("0x62b43031825cb8ddd35ac4f1b370c8d2a9d5e24a0eb9446d7f86328405c251c2"): true, + common.HexToHash("0xa9bf880832b613f8a7240411c84745aee1b8703de7851cf6154d2bec5f7d186c"): true, + common.HexToHash("0x4fbf727b538e70c371261541e951ce9ab8ce703150078d97cfcf8bc3d75ac182"): true, + common.HexToHash("0xa0eede2a011d62c0ec6e11dbdd12167db759e5287a0876b6d264ac85eab5b485"): true, + common.HexToHash("0x0ad011ba74754d3b6d190661fc26a065ad8fc74fcd663aa98929ffab06bc2835"): true, + common.HexToHash("0x4bcc0fa913da8ee7e51499c5ef7c76969f6d52ea02660ba9762b8beb3199858b"): true, + common.HexToHash("0xf21a8ce19689eb48a2a491833a1ed246c9f1cd35495e28411a249fe739e21e14"): true, + common.HexToHash("0x1bc71a07f4e1f5d52fbb4b92bfdda2778bbf10c6833322501965142f121823b0"): true, + common.HexToHash("0x708b03cd5272cb361d6b3f6292adb91f78c0d5641a2ed3d38004d5958f761f00"): true, + common.HexToHash("0x0d82d04f1528af6510be76c74f62e594d898196a4cacfe008050fd8f238f65ec"): true, + common.HexToHash("0xae70d5b12983c8b1cd249604bcac78a0e402edc953268601df4151cef137459b"): true, + common.HexToHash("0xebd7bf1bbec513381311b133fd2dec0ad5aaba2b085b7748a8cb718beb541a1d"): true, + common.HexToHash("0xf8ee0765f726ac66678fdf584d8559e5d3e9fbe9a5b9bd8d9ab72d6bafdda969"): true, + common.HexToHash("0x70ad814e8bbd1ffc301c4eb87123fda10e93de5f61d0e3e9931bc9e4b4366ba0"): true, + common.HexToHash("0xe9ab57f84676db012f9321b0e0c6b4d1bdf6e4d7f6c2e0f096ee9ad2e5066063"): true, + common.HexToHash("0xf8754b39a02eea273d615fc392ba186bb9701be55d4acdeb0af4d8b4e2cad2ef"): true, + common.HexToHash("0x335abe5c3129e1cf46cc3277b6babbf3fbed2519a00fb42c130e3d9b1e55de76"): true, + common.HexToHash("0x7fe4909cd90e2f40614d322105ea3b4784b3ec88bf9b76bb57631eecf0346d84"): true, + common.HexToHash("0x5b4352a2b4bdb187b14a71b825f29eb1209b9571ce35fc40f762936239cbb02e"): true, + common.HexToHash("0x693f83acf6d0a1ebf9386cac94540264c477c8777d88fd54e26c865fc7d54755"): true, + common.HexToHash("0x91bdb9482d37f81f274cbc31d93ad6c16c795d796be0bf4ad259216d87133b3b"): true, + common.HexToHash("0x660d3f0028013889d55e7510e1616d96feea17631cddc69bfd22b1ac55411120"): true, + common.HexToHash("0xbc1d7b374c2a4da9faa95c24174ae8fced907938dc49d1beeebe033caa780ab7"): true, + common.HexToHash("0xa3b36a1436e69a8e2b8a8cd7078b6d1401c9b84d088796f1c1c0717bd88516ef"): true, + common.HexToHash("0x117452ad6b42354353c00047c1c78404a3b0daf99797d00f8deede51c568d9c6"): true, + common.HexToHash("0xd477e6c0731e957ceccd2527ce60c568c847cbecc57980bdb4bdd9d86e218672"): true, + common.HexToHash("0x4c3c7ca50890dd31eec04c34cfd18277f49c908a1a00284d99e7cc0d6d935478"): true, + common.HexToHash("0xbd83e467b813928927f22bbc9a35512127de4be6358bfe244c3c1db2c2582f50"): true, + common.HexToHash("0xfe531b19466b15156685695fdfc9eb2efacc73199779e6d3a892c9e4ba28df0f"): true, + common.HexToHash("0x971ddee8d10dd751a9d1a374793ea87cb1789a0d19d9b22925df23b347fb260a"): true, + common.HexToHash("0x85130f570c5791b0a2bd561de6c57c1a8fed09abc302651035b89011ac2d2cd3"): true, + common.HexToHash("0x1054c2ee7a42f53d2b335cd7f5589707aa6196aada15725f8a955b77dcdd4217"): true, + common.HexToHash("0x2504fb6f9dc774119145b2b2e3ee1000b7ab91d8f34d5bf2e4eab28760276ccd"): true, + common.HexToHash("0xd7242fe9b87683396fed370ce1660072a8a1899dd8782419c95cdfdcb064332f"): true, + common.HexToHash("0xa5479b716a9509ad81bc23b7fe6a8486abf3db53d9b879ae364696ac27afbd75"): true, + common.HexToHash("0x6266d0426c931c3e3a2fa6c75ad67b866b071ca76f1b5fbeb63e279b130251fb"): true, + common.HexToHash("0xbaf2e7d250e1a316a8bdd40e85b2f959bfeab21fddd12240528f6826704ba657"): true, + common.HexToHash("0x720cd543f8e368ec533cef879f0e3748e5a260c6ece9c7fcf48a22700937cf6c"): true, + common.HexToHash("0x522aa5365bf0af9d35ddcc2e77ac1528b8e022901c56db71d61b5297ecf81ac2"): true, + common.HexToHash("0x8e7e38017d6c8427754f4372e521972e836c748a345cf8e9c5620aaaa33a8bf0"): true, + common.HexToHash("0xd6d515da53781d123ad06ba94c34b7c97c948418a58b88800e00b15c0befafce"): true, + common.HexToHash("0x22baa42d78239b793b928eb70a40b23a1c958ee4d01cc2b5d6cd931c3c0840d3"): true, + common.HexToHash("0xf09ec35eeb39f2624b63ce0ff48da11a0c03c8f038df381addbadd2aae9c6ed6"): true, + common.HexToHash("0x19e819df073f7f19b826539cf9f9ff3d72e88707bfb3c0303567f5c99e6927a5"): true, + common.HexToHash("0x6e6ae3f7ed0fb8e793d58128076fa22940e7851c8017c3ed80f969fe89e1fd21"): true, + common.HexToHash("0xc113467d677e409af1accf9c120a7b90561915132ea17b9b4c8c59cd2122beeb"): true, + common.HexToHash("0x5730c36d99b986268947773524a8b4a9e83fdf36ef8fdfd69172faca335a6d79"): true, + common.HexToHash("0x44278e7b5efd48f99ec18adab5763907eac6da5cb020b1c870922255858e12a1"): true, + common.HexToHash("0x6b3d10302a6c27b3117399e97abe790288ecd9963c0162c61385032217f3f237"): true, + common.HexToHash("0x4ea302e5a9b9d465965a0c376caf9482e4b57d8148b1350b595e8bc7ae3c6c10"): true, + common.HexToHash("0x0f6c3c5ca2bb7da5b387508df2bce0cb65d94f504f73c17e33f9c12ee12ac1fd"): true, + common.HexToHash("0x5d74b618dc9219c03a4ec2efad0bcb26556b4b7791cb434101e6dc5fd8405a6f"): true, + common.HexToHash("0x6caf6c99fa66a87dd0824509e65a4982c2842170d52bea0f8f438be86aaa419c"): true, + common.HexToHash("0x549c8f1221cbee1db6935af397e4248ecc5e2a3627a8f2527089b0cfb7ce34e1"): true, + common.HexToHash("0x8427911e7762c68f4073c2be007b8ab3cc2c64a987b54bb88c7f4b3dc621d5d0"): true, + common.HexToHash("0xabfdd7b80fbdf11295fabaff12126aab78758034156f32095de95146630c65fc"): true, + common.HexToHash("0xc2e98e8cb81c2760d17089dedb844147ba491b542424c7a5e23a73d22966911e"): true, + common.HexToHash("0x9abc5c5da15d8e522d00ddbb595fa6ded4a750301f5f85b598fa0ae303cd5fbd"): true, + common.HexToHash("0x11541458bd653f06d9c64750b5329e8d66b7276943c6cb1816b3f1901d9e01cd"): true, + common.HexToHash("0x32de903f02ba098749baf2ccad6dba66f8de0a6777adaec2faa57d8b6c15067f"): true, + common.HexToHash("0xe4bb75e174fd1c67e45daed8bec742f89f71ffea48a213545bcd7344a411e097"): true, + common.HexToHash("0x23e08c442cc6f2f3a94b83ce1790f6973b7adeeaaef63ae72394c5798d3dc6b5"): true, + common.HexToHash("0xaf5ac5ed374f253a1550af5684e0ac4358c73c2801419b30665ec285800d8ce6"): true, + common.HexToHash("0xb4162442f056f97241a8a98d264736903d424d7f030453ceed770ba05912330f"): true, + common.HexToHash("0x87bd815a8a03cf52b3855c3dff2138ae2a2502bea115963cd7cfbfeb93be70a6"): true, + common.HexToHash("0x36ff18a69695c7e43377d3d2bd9c4191424d5cd4fffd4dd84261f0d331de55b0"): true, + common.HexToHash("0x74852b523fba58ee1a939c8af5f519c9c2bfa05045db71928eccf9a9b3678efb"): true, + common.HexToHash("0xbcbbbe691346e5a6bfbfbc0755aba877ef01cb1902d1cdb45c39c75668597233"): true, + common.HexToHash("0x54e52f12c6b52433bc786101728c57b56dc53ce31a89b76d8d3386145724b9f7"): true, + common.HexToHash("0xd5fa8aaf75bc44164859ce7ac37d3331091b9da91a53d8bcd8097ec321f66fed"): true, + common.HexToHash("0x98a91363ce7c1d8627f2a8c95b3f6a542c21a82738640a0114a2d095a6143fd0"): true, + common.HexToHash("0xec299cdd1d81f290316ebd3da217d21f8b498457938d9561df56014b5e966f73"): true, + common.HexToHash("0x2608e5f3e87e98c3a357621a4760cc02949532d3751e33722e6ac52bea2310e9"): true, + common.HexToHash("0x9028e859cf6687b99ad0c4ecda5be0a566cdff8b62d20bb25af1c4206e6901e6"): true, + common.HexToHash("0x8cce4b3011c848745e0eac3eea42b107d8d51ed191280d8e46ddde957c81a029"): true, + common.HexToHash("0xd40e65ef365ab7ad65c3c88f014196dcf2cc22b337ffba45b5450a011e463573"): true, + common.HexToHash("0x3d9171c367d80003e5b32058b8af38db5a7699b4a2a3159265973815ccffe912"): true, + common.HexToHash("0x99c49c74d96c151954b85494862c4f64626175f37a25686180c33861306110b3"): true, + common.HexToHash("0xd8c2b3fd4743c15ac5e6d3f578844d7e8e6ac615e35fca5a5963b02c8198d323"): true, + common.HexToHash("0x81c5beafa56cfa1cf9fef99a8ede814584853aa26767b31271bf304df5146d08"): true, + common.HexToHash("0x87f05a695d06c3991cdc524dac95888bf4cf218f890ca8e70dad9df7a3f811bb"): true, + common.HexToHash("0x388030e54eaea6e6d890b7a7bf289afd60ecdf834f359499ccacd24f8edd73af"): true, + common.HexToHash("0x6c03ca7d27dd6a85c0772560aad3c35db6b5374e8388931db7e6c2e8f1a739cf"): true, + common.HexToHash("0xbf14f8ad649fc22819902427f4b4c768b81756fd333c64f739f62ff1bced7deb"): true, + common.HexToHash("0xda534b43fb1d26923072f7dec225464c4fb7bc48214f42b015e66d66da86e5a4"): true, + common.HexToHash("0x718043c25a5d853f75298674bf088de495d74fef0f91734792040f6ad6463cfc"): true, + common.HexToHash("0xc25cee72ef14a238e4c3adc3451f603fb3a9368793628afee86b5ab218cbd766"): true, + common.HexToHash("0xb0cd3bc6a271d960de33ee04890280d867ae44ab09791acac26acc3441d77bee"): true, + common.HexToHash("0x6ff37521756dc2b13505af38cc1cf9063c047db10ad7abc841bc9a4833e17bbe"): true, + common.HexToHash("0xeb838cec6f8d5e1a2e2626d9650e320f1308a284c09c6652e2bcc9325a5dca15"): true, + common.HexToHash("0x698e8abb560fcc08f1c00ed1b6f7ff64396464ae40de401daeb42f7692b153b1"): true, + common.HexToHash("0xe2bb67045048a59011c4a2928107d4d034b875f973c6157e2ffa0881b2a3ee6c"): true, + common.HexToHash("0x2dd43fac8490b212a8760001548b7b54ad47861b8d30b4f0c23e260ab0f5bc1c"): true, + common.HexToHash("0xdb52d6dc839526b900339fa1209d2a11a56051e8d41549cc7008b98193ca5245"): true, + common.HexToHash("0x3cd6564dc89bc0d25e1625a637bcdab54c452f837167ce0c6bbf8901f6b9fdac"): true, + common.HexToHash("0xc925a6e3884fb917d99b5a5242abea242bf3bee2ca4e9965d8e11a1edcddcf28"): true, + common.HexToHash("0xc824c487f87a54d2a2923f41ecaf5217e971cb28a2c96c29eae43d387f5e9789"): true, + common.HexToHash("0xd6d282910be0b1ee30f33d62f3736cc7f6f55345437e007a29538a0016de1a2b"): true, + common.HexToHash("0xfdfc3f8c0c9008ec4e309c57e9090a4a0df0546c866fc83ca34d6f09965db3e2"): true, + common.HexToHash("0x4a7e17f09e048105f7c99e6da2b89d45cdeb89ef0ea7df793faa641d535c75c0"): true, + common.HexToHash("0x73dfc15b57a6d5f0bc999b612308c5700bd7ebc9c4fbf58a07145bba67e4a63d"): true, + common.HexToHash("0xdb344e109ed6ce3706b94f59c0ba9c4faa5a872494aa833338e205e6381cea7e"): true, + common.HexToHash("0xc0130183343c147d160b1d3a979394d5e7c07a8f2e16b20b4eb69ab9d0d707c1"): true, + common.HexToHash("0xea55195d8f86d790c036379c930dd872fa7bbe503b409e6f4bbd36f6e1d1a435"): true, + common.HexToHash("0x5a533615fc29dc4f5e25fa7deb4da0aa43f3560b4da423ea7d6ccbb958dcdf89"): true, + common.HexToHash("0xed4a53524ac6bc63e133ddcbf866ffb4ee4921cb7666093f830316a3e020c10e"): true, + common.HexToHash("0x852d150913cce3ed1b6045e9f798efd3ac244589ae12ff4dde28eeb7af516f1b"): true, + common.HexToHash("0x44792662c84ea0afcec400512adbe55424b9c8cfa30e3df2613e06a7a7558320"): true, + common.HexToHash("0x3fc84b62aa9a95c15ecec25447be4afb36eeca8949fb7dfa07302340b7d5d4b5"): true, + common.HexToHash("0x858f6af733d883b260ab0903223593e0a56c9239f41f77ab163f9df8935e19ed"): true, + common.HexToHash("0xffc939cd57fbd3c36b1ea0dc79e1cff9a2dcfd188be1632957b9e18f9e4d3ca2"): true, + common.HexToHash("0x53387a15344e273449d77d4173f70467e7906d9e1d30854403c605fc7db1fecd"): true, + common.HexToHash("0xc9a6cb5434fa4797682779b3fd186c139a4c3a5a6055a100c5b0d9987eaf76fe"): true, + common.HexToHash("0xd58e5b4fea3d03b6379a5dd0d990b9a77818c182e138946243790b9121519986"): true, + common.HexToHash("0x2ea2399dbda19916e87cbd55c652bdb560dd67b5c3ae60bf91a86d4cb59c3253"): true, + common.HexToHash("0x1c516ba96fcb8d766ccaa70cb17ee020e6acece246d8d0df5418bda2a0cb26ca"): true, + common.HexToHash("0x6c59fdceb385dd2c0b5d1373c81907842c53ea888a3487c35d1bc68e518c97b8"): true, + common.HexToHash("0x18a293c6c90a60371aeabfce82bdc2da852bce0fb3051d74557b67427db726d3"): true, + common.HexToHash("0xdb0265f2fe2e33593e5ed867f722b62c40d9ce040a12c7bd1c130841159a5e2a"): true, + common.HexToHash("0x106084d12c77ac42d6bb98d400cd0e9744007883379d3e6905bfb2e60f5abcf5"): true, + common.HexToHash("0x42c32c17a7c0a7f100e0223a7e6d77a93a77c3183a16f001abc0528a2219f9c0"): true, + common.HexToHash("0xf5d440526c60c5fa8b1f88dd4e4f2e47e345cb2aa80b463c35ff7ade56673c04"): true, + common.HexToHash("0x35ab05e6b89be7619bb9002171670b899c3dee28f9f9bafccf98fcc0e416aa3a"): true, + common.HexToHash("0x2e24f6138d530aff6aa62b778d018cc39987662cf7a722dafab3a6f74b249793"): true, + common.HexToHash("0x7e822c287ee750a94d7512c0affeab11d3b3c66b6fbbd543ff41fe4c07c956cd"): true, + common.HexToHash("0x83858a50a8cc36af5af5edf574082d40645aa55adeff9e4a1a411cea49ae8107"): true, + common.HexToHash("0xe4607470b9fb21893b214545e000626aab5f4debbc5605d5f3e80dedd73aeacc"): true, + common.HexToHash("0x939ee52e64e7be9b8a33c120e6fe40df66f99c43f83027b2d87027ede04ed3b7"): true, + common.HexToHash("0x040df84d91fc938a4b16e3992d0c9a1060c26933c1cf69a5b8e363b883ff1856"): true, + common.HexToHash("0x17ea0d762134074931e04de045b85812104e57b64f08e0ffe968099cd4e3e493"): true, + common.HexToHash("0x6dd3fe680cdc94ac2a14811f8554bcf78e41d3ad443a893f2bb886d41861d775"): true, + common.HexToHash("0xd8e6f8a019aa5c35cb665bc9a731e88e4f24442600de0fe7474f29b2d5f9a8f9"): true, + common.HexToHash("0x32b582853820e837568d20fbdfad7c250f9210313aa10666d4f5a66624264866"): true, + common.HexToHash("0xc59138fbb0cebdf231f833228be153ff027eac5a97e161b1c2045c4d8a7d9fcb"): true, + common.HexToHash("0xec37d891b6603f74fde316a030f374f27bb1e8e893dc47fa1811f83cc37bc0e4"): true, + common.HexToHash("0xb8b240f4d57f6f08363f147b47213a8b8ebe1167b11122eefd917ddd396eed99"): true, + common.HexToHash("0xfacd80802863f229bef30df09359f21f99183138a74aaeb10393713b0cc1317b"): true, + common.HexToHash("0x66b330f51b8b04dffba1d341b5bd1c70d976ae5ad07a0b2bf828aa923711ebaa"): true, + common.HexToHash("0xefeb0fa40ecdab1a1e086401317da10d6c906a2853a51dff9dc124c37148088c"): true, + common.HexToHash("0x04a7e127334e0b1b6a8bc519495eeff0d56fec0e9b1a4a6eadd142445a622e04"): true, + common.HexToHash("0x1ac2364bcc74b06c7e6eecdd43801133e61fa577d7c7f994a801a44cb736745d"): true, + common.HexToHash("0x8897462824c22418f950593308617e755cc95deae61767e429a1c6b02a28bcbf"): true, + common.HexToHash("0xc52e1ffcbe1cc9a83534936d7aeaadef7af7fb596bd62419ad9357794976c4d4"): true, + common.HexToHash("0xcaf175c14e29d917bde1afa1deba0b4fb5af0e495f40a5545e950017f48af7a5"): true, + common.HexToHash("0xc7e02b3ed50de95ce4d85aa913ef6e4455241a619fd92bfc42497b72da7ec706"): true, + common.HexToHash("0x2cf4a1c6c554f3d03c5b32389ec2e4e3b3e5e1202768be522cf3b4c4c50f15aa"): true, + common.HexToHash("0x3a0252cde4fdd0969dae2bead43f7f39abb57bf1557d647043e8cc4fa6908827"): true, + common.HexToHash("0x90fb8bebfdfaa590a196b20e4516b289de959628cabd143c16bbe33cc3a1b627"): true, + common.HexToHash("0x515f433d2e2ab580da2435d7d514b113a3f71a89b6dd5606ef31d9652c0bca07"): true, + common.HexToHash("0x383f089be63c10326e95d9db58bd80de501c28ce2d68b8fc4730e423c306fc24"): true, + common.HexToHash("0x05d302a7206fd6652612ec97be8fa8956db20145aa5dc53004feb693932ef29b"): true, + common.HexToHash("0x942122dd48a06671c60819b7727f27b2fa76b86600811c22787de5a9446e7104"): true, + common.HexToHash("0x3d1941a3a568118fe01b61f4b74db733cdab1574845d7dec128d6c063da82452"): true, + common.HexToHash("0xd7e83c79b2fb395b743dfe394c0ac874f38389d727afdd008b3920e7a93ceb50"): true, + common.HexToHash("0xdc1de97a91409069763e45cce23c3f0683177c08b6f5580ed7aa92f6f051b665"): true, + common.HexToHash("0xbe2ee8fc133b27b6c672c72f67842e227f3aa4b54e3104bce3bf5075a34b04cb"): true, + common.HexToHash("0x50e634725470d84c146ee6c5ae4db369fde8a1f7e3accfbe9f99d970f92b4753"): true, + common.HexToHash("0x11fb5af7f8fc59a54dbf72eb079e16d4b5de8857bcebfe50647769bdca4c48a9"): true, + common.HexToHash("0x0db5a5bf1e322cba43240f160ede0096798377c74cedc2977f7d40b859382953"): true, + common.HexToHash("0xc29b05b4f63ae3c8702475208d0e28a5bca2e8bd9f5cb786d9f9cfea6bdd5199"): true, + common.HexToHash("0x7850aafa9072979bbd56a6e95100babb78da2488debeca69f061889ee1e887e3"): true, + common.HexToHash("0x03708967d8c7829e2a849c584832476266e6fc1ef9312447b9627aafa9eed709"): true, + common.HexToHash("0x0f8a4b288e3a2c3bba5fb3cc0bce95d7ed45c55e47266aaf1f699e1e5ddb74ce"): true, + common.HexToHash("0xe73adfbb23c344bb9e8d1612539a1509a3ef8f006ba840999218206bb3db7558"): true, + common.HexToHash("0xf77b3ead43cf6232f7f7f118bcd2b24d8e2721ee4600f258e6aa3c9b674a8a13"): true, + common.HexToHash("0xe37634c710455af08604f774c58e1eab91aa38ccafd16fd6eabb1b6440928f32"): true, + common.HexToHash("0xef17bbc018715dfda8218dcae0cd77f096679675ea0b44ebc091413af431d43a"): true, + common.HexToHash("0x6268e7c6e630e295825e6e7e4fe044e4f744f8ed0f4dcb8e10df691183228e12"): true, + common.HexToHash("0x5b1f1833a0ea3f2619ddf6dfca735c027886bdee8cad507314e5ca3eb39b620d"): true, + common.HexToHash("0xa60515e3cad34c914dda67dd504742c61264b2a2e03bffd1010dfaa89c96c863"): true, + common.HexToHash("0x6c088214caea42dd79705c21db0433894a161f250022b984ae6b5d47c01d11e5"): true, + common.HexToHash("0x20439e5bf8c2644aee0f1aab35533c69fd588bd61441549a2784644b658071e8"): true, + common.HexToHash("0xddb41e0446b2f9969b08eaaed595ca73bb1ff3b761a7ef77a0dc3bc0f3f2cbc7"): true, + common.HexToHash("0xa5966cf3eabdf51dfcb27fb5752a37381f4d3d16393ff245e99b0a32a542ce04"): true, + common.HexToHash("0x4d02695882e806750f93784ae3e4e720023ae22e97e9613980876a4f73c3fcf0"): true, + common.HexToHash("0xc5d52fa4860ffcd22d26873a869c48841a579589af0cab5e85472840dbc54bdc"): true, + common.HexToHash("0x36b03f646f1c00f2cc0f66d9a01a70f9bc326fb6bd527805fb0d8a174db88605"): true, + common.HexToHash("0x8ef96146dfac00e8b77a4193196f3b07aad5f8acfc62a8b3219f56d72cd919b0"): true, + common.HexToHash("0x832f54d6c3ae9b21fc017ebc00dc390b648c9e7524354a8c6103d51e9676dbdf"): true, + common.HexToHash("0x51166f73f5bf23d89025da418b6d78f7b2e7787ccc67a38c6b2022909b419567"): true, + common.HexToHash("0x7476fef2311a62058ff16c98c6069afe95d60ce42b39a25882e8ec04d220518c"): true, + common.HexToHash("0x36ca69de325d3729c40397123527e2bede8b36deb46b3c0a3040d0c045cc5be3"): true, + common.HexToHash("0x543d82b092a3d5dcba94316e2f59003e641bb4b44f37068f93890cdb22cde7ec"): true, + common.HexToHash("0x900bbb850c96372d2170bc496bb6f1fc108e4a8d8766f9823ba99ddd775586d1"): true, + common.HexToHash("0x3e5bfeb6b1122b8741c5bbff8e7d1962a8fe58bbe1eb42ecf9c870e367d7dad9"): true, + common.HexToHash("0x8dfb28ef82e135c5f860689ea4abad0a5c2854a45e4baf4766976516ef51aada"): true, + common.HexToHash("0xc6db2435c9c34074ede1aa87a9abb5f0cf49b86f573baf29a0d5837111b29947"): true, + common.HexToHash("0xb193a2cd878aaa79ee63ad5420b8a143c61e1bf3d43237fd7b571dee1b54d1ef"): true, + common.HexToHash("0xddf68f8137718bd3da1a6de4b0c56f5eaf7d3f9bb005dc4622730bb999d554ed"): true, + common.HexToHash("0x5715cd14ddda607e6f432ce36e7dd5df87b5b8b1fba419a9052eecc12b5a3f8f"): true, + common.HexToHash("0x50ba47387e3e2f6f2e61970abd336ed7efe1cc34412d7528974dc27a605c1188"): true, + common.HexToHash("0xa50d53308858682553ef6478897fa093a303c2a3ef8e1ec1952ebf29abd80f7e"): true, + common.HexToHash("0xff1b3ba928a367a36c88775ef45e665faf20249578decfae633a5e805d115df5"): true, + common.HexToHash("0xddf6a2d6c257b33c9c8bc00e63ea691ce997cad2e33e424fbd3f8c477bfb914e"): true, + common.HexToHash("0x4ef308a4d64161cafadd61fd6719355e35c0eae8b6e4835f230cb9f6dd83a456"): true, + common.HexToHash("0x8920e2322952df8a854ac283c7d41a2c15caf47f4421800f3f5d3e624edbc78d"): true, + common.HexToHash("0x2cec36d6267740f70b69e69eafd850b104b63fbad4fbf43b649f98a069a05182"): true, + common.HexToHash("0xdcbf9c573e30da8ba1d7ebf0972b559d6cff8fd024e875ade1dbd30905642e77"): true, + common.HexToHash("0x9bb35f5d3277059fc2981534fcf848ba56006351add753496a0169c49b6cc1af"): true, + common.HexToHash("0xd7ff74182c52c5032eef115730d1156adbf4cc5acfd1f405b6d35c22085b4741"): true, + common.HexToHash("0x955c0ea62892d3d038ec3815a33ad5f8597bb95cef02ef7d32a85bc906f3d3b3"): true, + common.HexToHash("0x9ad245b19ef959659bfa0d22f60cf2d729fb4fef729bdbacbe0e2f9eb47542bc"): true, + common.HexToHash("0xb7193e0276aff1bded644ef40e34750096352aea05defb5b5c6da325e6611689"): true, + common.HexToHash("0x8f5903247be931b9ee2d2d698f009ef23c73d7ea1cd25c46538f6bc08086c257"): true, + common.HexToHash("0xc7db5b29c7d0f3cbec770ac880d40e5a96a7879ea8931282b5125916652eb087"): true, + common.HexToHash("0xc77b73b5fb14885b91160de719a9a2369c3d5ae69a1185c0d01df7a2b9e523fd"): true, + common.HexToHash("0x5c8a311334d559f85578e2adb743e4223dd76aff379fdd81b4b2eacb55c39e8b"): true, + common.HexToHash("0x14467bb89bfcb81a1cbdd0930307f6b50641d9d8fa8ca5f3efe6e2a0638c20cd"): true, + common.HexToHash("0xc8dd487accc5e52be15ec09534c938a6d577b8b5d0bce79ba06cfad756d35de0"): true, + common.HexToHash("0xf8f8b74298720994a72b4e0268e23238937942be1cbb1444053ad098a590ae5b"): true, + common.HexToHash("0xb4469959268fd1532aaefc043a394a91fee79726fa798237e9ca2b481dc2ec5e"): true, + common.HexToHash("0x6d3562430f9dbcce20de39b41b4905578d6f9496b2fcd26ca72a0dfe2354a053"): true, + common.HexToHash("0x86338be9bcbba5b5f08f46e75faadaa89c3055254882e4e5059a4fb16391a0dc"): true, + common.HexToHash("0xf49de2850cecb0bf7c9275f9c99b9afdfdc2eacdb3770f504a9d027cf5cf6752"): true, + common.HexToHash("0x58e6c78dd3565309abdd4924a4c77f64324726c75e91a9e36b9750456d93288d"): true, + common.HexToHash("0x78007631e440ca1dcff94dbb48558e4f4de19f303ae7b0aaf147269081083164"): true, + common.HexToHash("0x311bd2776d911b11b75535ac8ac50961731c8ea8f1428c329d7291654f9c88dc"): true, + common.HexToHash("0x45608b2f127a3bce98cba5d91b8e6744de7c25303a96359427a4ff73cd9485b7"): true, + common.HexToHash("0xcedb46261f976c0593daa8f29c286e42786f3c151f29df5a6f38cbbcf836e76a"): true, + common.HexToHash("0x5f196019430c98191e63129600dd702b33c94adb0e4d5f82d161d126277e32cc"): true, + common.HexToHash("0x464cbf70c90171c8756011a9269f5df7900d283f9b2995ce5d8be25454e45ddc"): true, + common.HexToHash("0xca46a3c79720efa30e32c0f80243c0afbf8d69ce7755487c6a68c95e30995704"): true, + common.HexToHash("0x6c27f9c27b03f66b1df3860ab82c1c6ed716e68a0c40e8e9147d6664e36c9b22"): true, + common.HexToHash("0x87e51906d1e0a8c2f18406cf0ba141e6b36e0c72ed39a5812b07a0a6a56f06d7"): true, + common.HexToHash("0x6506e3b4c591ec02e90fc82aa3ff370ff578537728e4d59c105f41a344a0e6f2"): true, + common.HexToHash("0xf408a13dcb149ccdbf3168f87aabf557e92d776cdfa1482a3051e33e7590e6f0"): true, + common.HexToHash("0xf51b1fe2048b639b3aa215b5c4d1ac007de54bc700ce9e432f938b1354967091"): true, + common.HexToHash("0xa6f3aa93fac989b79a2e870f40217d5f4f0d162ad6982b7f3d0a445b621825a5"): true, + common.HexToHash("0x138e89e3541908410c9a2d26266f065e8c09814c9aff1447bf159fb26a16ed09"): true, + common.HexToHash("0x695f1800aa70d4cf08f9d44dafec1f356386a83e726c4aca7637fd91fc50ee7c"): true, + common.HexToHash("0x33efe63b18316f2e7f3d6838c4c7fcb388266837f44b1688ed913a89f9d31548"): true, + common.HexToHash("0x03e3098fb3592c61cf2250b0729d02dd259ed85ce0893010a4d186f5c89cc764"): true, + common.HexToHash("0x92bfa510e7283988455f573a451b3422f0f0c7136976dc9be249f2af887c6217"): true, + common.HexToHash("0xd8cd4cc4a330f1a8874a1fcb3a3ece6c4d46d1ecf7028e997bf64efc9ef32bf2"): true, + common.HexToHash("0xf7507f8f3ccd1ac674f04c1676728a7a08876a7f97089e5564a7c2c76407cdb9"): true, + common.HexToHash("0xd5f57edf7a1c934d8f71a076acad0832ab17d72cfd95c98fccff34a9aaf052c4"): true, + common.HexToHash("0x6edd2999197b0531dce508c78840651c48e61f5610e5b92b97f7ad379493e68a"): true, + common.HexToHash("0x175696484ebbc9290f09bbf02c647eb94ce7681a48335d78724b32181fd7eb18"): true, + common.HexToHash("0xf0307603ce94a2b0adeb3b97383d0d89484281bf0ead50d878cda71c48466d16"): true, + common.HexToHash("0x9803f5696595d3c260f1f617dbe7569158103a52169ce3255db7b41db950c4b7"): true, + common.HexToHash("0x780a886d5e11fffb99c55ab3bee31d93f209e59d794178a06b39d04f7135eaa9"): true, + common.HexToHash("0x44e505c42810f1c4eba808867ced0d4703d8151ed95464154c8b15e6e56355df"): true, + common.HexToHash("0xde23dbf26347e81a73ca6a157e7cbd86a4a48048b1bc498b19c46d8824922b27"): true, + common.HexToHash("0x287643a92852cbc780eacf78a209a28b0c1976b55b887f2ddbbbdb71216414e4"): true, + common.HexToHash("0x86354ba567e784b097531901c13c6ac23671f7f4ec01fe9fff006c6e614fa7a9"): true, + common.HexToHash("0x62b763c96ca7987f5d117194dc3a2264ae8bf5f87cef15cb31c22dfc47924d57"): true, + common.HexToHash("0x9b586cbaf90b7dd792d0772542a55bca9aa217ce9ebb24abc509b38345209d36"): true, + common.HexToHash("0xf876039035641144176dda5d19ab7a131ac15b28e23e1c0e4b54f4385c832916"): true, + common.HexToHash("0xfd70793e8fdc107cbde7d77e396f5c93b4968062447dbc6d5e2c9fda3b442b00"): true, + common.HexToHash("0x6e080d41a2c2bcfab5570a6e34430817dcd384822e0f93c80b729bf63b6d5e0f"): true, + common.HexToHash("0x173ad2285015f699855e7c2280fb1f1c8039df9189f3ac8cce3aab255f28502e"): true, + common.HexToHash("0x297fa1e08fa02496b01eb836eea1b9da64b248f99d8d7708b9cb352e5b395d06"): true, + common.HexToHash("0xfb8e9a7f8c330029f9f5446b99582941ac9a575db314040e71053e23aac099b4"): true, + common.HexToHash("0x3b4025ce6815decb16709979435492f37adb41235d9e1085e6183d4629438647"): true, + common.HexToHash("0x3356b208bc1f5449de18fea9a04379e880311ccdda3a769b372c0ab326a3cfef"): true, + common.HexToHash("0x24a0f03b00cf0ead7c6a399384402ed48ae65ae51de3205ebe01e4c34fa62435"): true, + common.HexToHash("0x59af60f63f6caf5b16c2a64c5351181ff9e82c6d8bd4df9ecf6e01b1ad7bef27"): true, + common.HexToHash("0xa8a40939946e5a90fe2567653db7ed7d773776add97e53323eda7f1a62d2a3ec"): true, + common.HexToHash("0x2078580945866331a8dfe396b7496ffb34c6ed52278a3ec8c430e455c4ad604e"): true, + common.HexToHash("0x6471c866ada5e769e41c9571d9d3a22b8c1f424253a8856d84216d7cf242de3a"): true, + common.HexToHash("0xeab422092beb9c1a25748e20e70378dbe88dc891c7df29ff64385f8c48a71654"): true, + common.HexToHash("0xdb6c6ec93e544f7d61a0dd7e9b213513a045cbd7544bbcc0067e01503458d6ac"): true, + common.HexToHash("0x8ee5baedf15ede1dfabe560bc72ce0ac475aa9d7e70b3af43a071c5debfa392b"): true, + common.HexToHash("0x00f37255de599ed7750f6b810a2c662be7babb05589b0e7718de878c8cbe5638"): true, + common.HexToHash("0xef0f3796d717caeb64a5356cad60ab186582682e5535a1ec4a71ab575d31519e"): true, + common.HexToHash("0x8f0a8ce57d92ac96a7da0a5cd8e506882513156e45b07fa3d810ac80b7537a2f"): true, + common.HexToHash("0xdef0a8117f00c40a7739fe5333839c42467397d2a5a5c93d87789e934165e47d"): true, + common.HexToHash("0x70635d96090791abb0cfd0a53c09dfaa4a294cf765c9315bbf272f3b46e21527"): true, + common.HexToHash("0xadfbd856ae0c1fbbf4b9ab8d9da6438da0d0c91866dd6db62f4960f8123af50d"): true, + common.HexToHash("0x22650ad3035a263654bcd580096186f13e2cc1a80390aa69e46ec36231ed9a23"): true, + common.HexToHash("0x9e5b5f43ef59332c194a42b6988d5cc3ca3b0ef5b638a139fb4338dbbb000556"): true, + common.HexToHash("0xd845e0a9431dbe7362fd61c66338dbbf496f6a0c3f664f5462d34de9a8b0c55b"): true, + common.HexToHash("0x9bc647792b6040c5f422f93eda4d11b4a45935a2b84ea639dfb71d885471dcf0"): true, + common.HexToHash("0xb197a69d3a4b484e7e4f28a6f2d0dc47c18525b504018a639878922166886908"): true, + common.HexToHash("0x63c4aaa54af693e38260f07ff197053f41f9e46a2569c4772d72728f80feff1a"): true, + common.HexToHash("0x9d8e8769c5b14c1862b06d5189d5e0aa73968fcb420427a216f8d88bd20b2cc1"): true, + common.HexToHash("0x61c59420538a5ccf3865ea2450fa68ef34a705311d67078f855fcc232e95f140"): true, + common.HexToHash("0x9d365e1e4b0f12b30f99ad5ace8e7bb807b5d0e3d2c67c14db7df8566275d9ee"): true, + common.HexToHash("0x70b48f7fd264ff8ec72d7a5fe13db90d0989d6b5a6b39f5420f29d209dab13f4"): true, + common.HexToHash("0x3bfdd0509f5031370226bb8efb8e5646a8f104976b6127c4e98a5bf9f2643a7f"): true, + common.HexToHash("0xa8e1dd484ca787a30f7c3f5c71ad4cd7a6ba181c86a21e96ad0d12715fdb86f6"): true, + common.HexToHash("0x6c3b34504a340feb9e506f4103433d5e60bcac949cda9ea980f1c4b365c8a3f9"): true, + common.HexToHash("0x1b449bacfcb5281a58310d39788397d6b1853c63a8a1cb381a62f9ad1b3785ec"): true, + common.HexToHash("0x42ba31f761b1baa3c89bca8070e462615c496b7976fd01694b5f753bcf083e46"): true, + common.HexToHash("0x53a002eda5f5563b0412a399f7d4369f6fa968859f0deb89f2b2651609cb73c8"): true, + common.HexToHash("0x3390fdaf7cc6474d65966859fbda316364f0a13fe692b055c0821e353af05637"): true, + common.HexToHash("0xf61b8322f48193f8ac89caf9dc88c1a863a3bdbd0f6393bcb50b5a47fb6a4b49"): true, + common.HexToHash("0x4960d2e3728ade9b9a75f336e2f6296f979bf336c211e36a64b4cf83285307d7"): true, + common.HexToHash("0xe3ecab0079644e238423ba12f989071c5252e23fa8c2fbcf99eb0cbebfdf1d8b"): true, + common.HexToHash("0x4c12513cbf1aef21d946ec33b0e8614037d9cae3d5f4e6bd8ec99560548f3d2a"): true, + common.HexToHash("0x376bdcf7a16011c3b571e8f2b8d3a520404cb7541b8ee59862db877edb583ed0"): true, + common.HexToHash("0x1f8ef7d3c0cd9beca8b06b33aee27f1c6bde380fc9fe4689f70a14fd8d68248a"): true, + common.HexToHash("0x0bac50f7532752ebbf38af4faeb8b5aa75e8ab14f8818af128f6af8fb1141dc4"): true, + common.HexToHash("0x267394acd89a3ede39fff0ff70fad6174cf0c05f693b7ffa0ff41a8fb8e3247b"): true, + common.HexToHash("0xbc3ef8553fe1131bcd90d7e130884619dad416b2db6968d237c623387c13e8bf"): true, + common.HexToHash("0x4a27abfd1fc48d42dab7bd93889642928e67fe186eb1e4ec3e59f07d6c962612"): true, + common.HexToHash("0xbe40e1262112964750244360f1d6f65b8358ea7654a43eec07741733b3eae3ba"): true, + common.HexToHash("0x711d03b558aa647d448f3bba5ee0c6910aad72c472be6864da5aebfcbde68eea"): true, + common.HexToHash("0xb0d041c3fc51458c4f4b1c608d9b9e24db1430edccb9318492504e059892eb3c"): true, + common.HexToHash("0xf88ec691e78957ccfd72bb30b5d0c85b8ce4a3bb7f59e96b1a81e030ebe7ff40"): true, + common.HexToHash("0x7aff19e793da085b1ca91a84070241782954ffdff6eac923a4ccc906fbf86c07"): true, + common.HexToHash("0x5227d8c91058acf238858c2920c0049ec09fb9594af66c51f8572422adc5b269"): true, + common.HexToHash("0x4ec0875a937ab20767ec604dbb52e1b138b699cadee5f921b596bea3f42f418e"): true, + common.HexToHash("0x45aacea6ffaa150919a49b1b9c4c3aa1dfdda574c76d38b9d01bd2838ead2c11"): true, + common.HexToHash("0x0edcd30cbc57ccd87bd2a042b343abf9b68683a25244a7952a4662c131552108"): true, + common.HexToHash("0xd1c9c263331c37dfb0160d5c6fe82d66007e7d99a2f48d6e843e346b1baa2445"): true, + common.HexToHash("0x32f9e81eacfcd0f773cbb2978725dc6e8f0ca14e9dd7e11deaf686472e2252ab"): true, + common.HexToHash("0xdf014b13eb84594408579cfc084b492b4bd7dc41d586d574f71b548e2c19ea67"): true, + common.HexToHash("0x6802508030d6f50eec0e83ee81f1e7d6a151752cc99b3d9e9a8b48a0a79fed40"): true, + common.HexToHash("0x3ccdff26e2ac3e1079da519ab79f3a0a05521fc858126bf526bf94d4fb6cc179"): true, + common.HexToHash("0x1e14f192be005203cd0e3c2846c2bb35356393228f6f026fd88e0509e6534e64"): true, + common.HexToHash("0x4bbbfe287af1a656469fb8224274d49708bcf6124b25f74a8aebc237f17b9164"): true, + common.HexToHash("0xda82bd3ea3b1cb4d450bf0703c35c8126f6602407b7fed69dba79f60bfc590d7"): true, + common.HexToHash("0x51987949cb7efd99efb72680a69616d6dec73dcad1ac13469de83ac9cec77048"): true, + common.HexToHash("0x5fdb8a60c0739bd4e54161c2786d770c826c5c0a7679b3371f05d2f5cf17dc4b"): true, + common.HexToHash("0x6b506f2a4da407b271f6b974077cfb3b29b3e3b5a5d854da145eec230823cbe7"): true, + common.HexToHash("0xa8805a2644f5748ff38857a60f95efb6b424c7b13a23131648f3c101ff26a3c0"): true, + common.HexToHash("0x0ccf15139b3fe6d20dbc94171f68553428d845e1b18cf93bb157a181274b7c95"): true, + common.HexToHash("0x542733f8b192d9567582242946d1be986bf2e927fe32c494e225cc0b8a68de72"): true, + common.HexToHash("0x8d888f670fbefef0502ef2e8ea14520647a35c6ba6b22360dd87586a2c4d1ef3"): true, + common.HexToHash("0xb3c4d34faa909e2b67e462908b98f5ee2134dd2367d8dc64bb4bb8af63dbcc16"): true, + common.HexToHash("0x47551f500c632e2254cae990586055feb7ef7521bb914adfcfd827b983e7342a"): true, + common.HexToHash("0x30c0c18069e5a1bc58fb8d1a4875ca9f43984148d70a444eb50916afde5544ce"): true, + common.HexToHash("0xd74d4f167d7676e415ca7ad3dc68512ba7da1539110cca35238a73b8dcf4da2f"): true, + common.HexToHash("0x4860794979fc8aac5dd122fc2d37c14f38372a8967b73e01579e2a4185ea252d"): true, + common.HexToHash("0xf2c26d26cdd337dae1eb61590b8e99d7a4bd6f4c5aa2eb4a27349181786afad0"): true, + common.HexToHash("0xdd315a59ef40277a37edde1ded648af7093ae8cacd4ab3092dfb77c46d4ae1ae"): true, + common.HexToHash("0xc1fe1858a377b3014b1595b8a12d58cbf17b780f2daeb9188d9961c48e732d25"): true, + common.HexToHash("0x0d9ced154b5359c04173aa2164da4351b4e2cfd3e30c100c818a1f014d74b485"): true, + common.HexToHash("0xf76e30251fdbd15af8544a73a93d300fce1e06fa798f34084e0e41922652dad0"): true, + common.HexToHash("0x63bda8bce2b3cb49fe3548f420c56aa5a56e5e68ed99261a0a8077982f0a45f3"): true, + common.HexToHash("0x5494449cfef2bef91e41af13207504436ad92a693a3bdca4f46ec70bac27b044"): true, + common.HexToHash("0x29a79c5889668814c907110c5a45bb09a0c5ed46f50d919c4ebee9ce12235e7a"): true, + common.HexToHash("0xb951c4aa6e4277c8a7f4a43090e1139e3f8bb22e22dd805dd1bcd6161a587635"): true, + common.HexToHash("0xe781a1166f53c7e9e824fa35be904c91bf8d161aecc7bd1ee874ca0a6edd3d90"): true, + common.HexToHash("0x76ca09f8452477f63bf950e4b36b1dcb38a185e18228ff4bab321541d6584afd"): true, + common.HexToHash("0x5c15f32d8218d20c34a178f6eb400d2bb35a9bafae63a2e981ed30eed0b1767c"): true, + common.HexToHash("0xbe422bd388f1083e0e9b07cc2bd13aa2937e3bc534d9c099ce2bd8ac7ecd8d28"): true, + common.HexToHash("0xdff20638a2bab9b5fb46e6eb3242bd02be6b3f6694dd76b1ba835d7cfa5488f7"): true, + common.HexToHash("0x5809ca22aebaf11b31a04c4665390d56b4e1f46839244ef7d60bdd5380cc92be"): true, + common.HexToHash("0x87a93f867a0cd947bb370499bde881c4f98115de92469f07e9eb156a8b73314c"): true, + common.HexToHash("0x55cf56672c307a856d7aac612646d07c5d2877b461ec68c6161f185e188b0fc1"): true, + common.HexToHash("0xb74bcd144cc57496b646ddbfbde2be5becbd58587fe7ac6e74ab8e5dc77eb912"): true, + common.HexToHash("0x85d3502299760149719338b36c1434d925b3c4e29ef24da93e35284a81c95f5b"): true, + common.HexToHash("0xb964671da20dde2e4a033aaaab4469c7f6b66dddfdc96ed78c9ef8223edafb90"): true, + common.HexToHash("0x884585c65457b5ea0c169eca5357c9d3da4f8425e82614c6b3de8264860af089"): true, + common.HexToHash("0x3cd7d16b9740654aa2497f726ac6e52191da9693f4f9c074dea990bd4dcf05b3"): true, + common.HexToHash("0x8e4fe586cce4ceb3070fccd33dac3f344369bfdd660170e2c61965581ea4c2f9"): true, + common.HexToHash("0xff873dd7e783dfa9c9a52cfdd33cbc92f60d1a90f47f4f235046872e3a1349bd"): true, + common.HexToHash("0xb32211d924e2d8546961cbb7c336f87b6c2adefdcb1762eb61d2362f976b72fa"): true, + common.HexToHash("0xc5c5bb6f5afba43ad11dc0a5548e68f8d430e9e1b9509f88b59e827b6148838d"): true, + common.HexToHash("0x5854427d53cbaebc1d17ca0724d37cf34d7c0b6fff0e2cecd1f93a69b87c1c23"): true, + common.HexToHash("0x48a8836fbd398e9f4640305fb2b3ca01ae1df26e036ed82512b7267b6f250645"): true, + common.HexToHash("0xb8babca7ed419594d3dfaece1b68afb3dd8bbb455da10fb0997519641a38a292"): true, + common.HexToHash("0x1ea40adb0157768e74c8818671db46c2b7e85d69f313152e42c4f7bc850bc78c"): true, + common.HexToHash("0x36935245c50a422d93c009248b0ffbaee12e2418d97e86ba71ad01b5d4c6df3f"): true, + common.HexToHash("0x7831e178c3641ef16e2171028b38f9bbe9902ae105d73ee2daf34c94f2cafc74"): true, + common.HexToHash("0xa16e5a37abd180169675ba1e82aa2b38b799d31d30ceb826392ae5849bf9fd97"): true, + common.HexToHash("0x52f192b870505d0dac39ae611ccd38bc054a891bf933fcc65da113e603038dac"): true, + common.HexToHash("0xdb0dfaf2548fc317bbaaae4681100a6538746cab52c5e7e71bb459ff3cb6ea46"): true, + common.HexToHash("0x6010dea4ad42b77b27fe04057af62be8a954676601c6b05c425f979cd4dd5a3b"): true, + common.HexToHash("0xc6647820d45b9a423d7b0277f4f0045b1273bd009e8f8b6810af713d6a2b30ca"): true, + common.HexToHash("0x9c9521ae90b5522245986df891ec5ef70e66a4f1b440085bbc66b70ddf31e8d1"): true, + common.HexToHash("0xc35fa6d7f5198ed3c1c6549c854592280790a2e6333726d26e27c59a002d6e6d"): true, + common.HexToHash("0xb08a1c4a4b6e04042b4f6c0af1ad43c6a0b900812a3be2a0a62223d6e36bf0bc"): true, + common.HexToHash("0x7ad2f8140992825efb1dc8a901f8341214a50b622329748dd2d0eed6482b875f"): true, + common.HexToHash("0xe1c46864979ccc97c4711dc5c7cfc7ec189804eb0dc46d43e3d526a864f6c44b"): true, + common.HexToHash("0x58784aeb23d5a1956c593051a8ebcd45446ec3e980379bef8ebd9f428be56ae3"): true, + common.HexToHash("0x9cd7c50ad7e86abd0bbbe869980a668cce814c6ee951cd81ec5b1f36d8842ec7"): true, + common.HexToHash("0x38cdde781792f698785fcd68ca3bccb91b03521e64323f331b5bc01d4642afe0"): true, + common.HexToHash("0x7277913049c16dbca8fbd92fff721da26bcd73aadc89ebcfa760b5713e071a1c"): true, + common.HexToHash("0x1fdcc01ab096df85e7acfc7c820bb365c6fa536f5e50f9a349e374da9f3e8d9c"): true, + common.HexToHash("0xd45ba98a5bba6b12362726acd430cf11d0cc2776645c125864a99876c9b5858e"): true, + common.HexToHash("0xf24c68e6210325aa79bc1cb46b348a121e8e3afb98b4b36a06a72ce836168a1a"): true, + common.HexToHash("0xd55bbbfff6a22565073116ca6e3c7af61a700419163a66aae0d8878eded10ff0"): true, + common.HexToHash("0xd8d3d05d3e265fcb1e474c07ae41c2f8cd54976d2a9ece390c6ace8751a31754"): true, + common.HexToHash("0x5f486d5ead4562bb6942a68514b3f0a86a0c0f496722657f276991bad7edef16"): true, + common.HexToHash("0xddcb0a9da4cc228330602a1ce850cb4941cd1d8f41f206a7df8baa9a543cbdf2"): true, + common.HexToHash("0x6ef94d3c76fed69b32c13862c09d9809de279627366c8de834efd3c7987d5b6d"): true, + common.HexToHash("0x77ebda28011d3989d0433819f125541a8f84d67dd291e813c1f9f257b72a7a6d"): true, + common.HexToHash("0x9a9bd5c070535a7b9802878413e2e009df19e85a4d45aea3aec6091ae84454ed"): true, + common.HexToHash("0x35592d22de5fccc92d7a38d5c7553496c9ef1e64dccb642983ae4668670916cd"): true, + common.HexToHash("0x1ba86fcae0fa3b5f428424e131e23c5b8d1306f13af15da934a756908eaa2415"): true, + common.HexToHash("0xf72143f46ef4deac3c46ffe807dd89d4d57cc51f7ff9eb459872613f228e28aa"): true, + common.HexToHash("0xeea42ba1e8084278bc5e9b57f2ece83965b84effa24cc4eaad30e521a5c323f6"): true, + common.HexToHash("0x9b70cfa122157d8aa864e23f40d07200f8d3dc9f34270fc545f5e619befbaf43"): true, + common.HexToHash("0xbb6d0078adf7e48c9ec7c8001e6a0b4e9d2732b1c33f37f71f9bbc361677a18c"): true, + common.HexToHash("0x989faadf4d1fcd822b1200861e5d3447b04cafecc34c9a5e629808b193ab0a73"): true, + common.HexToHash("0xc7862854ff0540abdabb549c6046b5ca555eacc9a00ec3f130030c139272cb6e"): true, + common.HexToHash("0x702095f6e8ba88ca7e57cba01070ee6fbe826a1c324968383899b90de51efb65"): true, + common.HexToHash("0x2becd542156b12c9f1f961d7806e449b14db61ffea72bdd54d047c596d233602"): true, + common.HexToHash("0x9cf05a9ca086575243147621272bf7d1412ba03d2dd19ef3d35f62ded2aea08e"): true, + common.HexToHash("0xdce7b9b8d316fc600c79bad68f9030f92662eb6f023a348d5b398f6e32eb2555"): true, + common.HexToHash("0xa56c01c2161bdbe99d0be3c9beb73dbbb5392f254d01d29f1b0205271d64a3b7"): true, + common.HexToHash("0xb29c9c788effaf4cfd35ad6723c673977c305a653e7bbf8b52a0d7151077733f"): true, + common.HexToHash("0x352c03889c2e511357bc4cd565ef36b028085053ddf8fd8656712042ee442eab"): true, + common.HexToHash("0x394210f8c675ee74b6dadc365ed24bdbcc462d990f7e6950f8d14459f65d812d"): true, + common.HexToHash("0x137449c2e654f9128d5dacaed090245269e3b5fef3d64af4e2650aa25d46bc9b"): true, + common.HexToHash("0x51e5631ba39f41b934c2733194c311f09c8e89d3d05165feba708b7420b289af"): true, + common.HexToHash("0xd5301ffd62ac34aed8bd1aa2f67d72aec3870bf787eff8e20c1ea023e89f366c"): true, + common.HexToHash("0x2cf3b8cf34697e12af30efc79dc11a4c1adb830ad5b742ffaf5110bee6ad62bb"): true, + common.HexToHash("0x408ee6785df4020f3445d1731e6dbf78fceb9444cf5ee7500159f99dabcaa9ec"): true, + common.HexToHash("0xb7d3b1ab54057f2e42d204be055dbd3704ba78326cdb81bb58a42ea2b8f15cb4"): true, + common.HexToHash("0xb1a464d493c6d3a1955a365030fe9e261af1436abccfc3d9dbb4f12222cb2f08"): true, + common.HexToHash("0xb57663a63e100b80cb024f518453410b3528c14d5d8f8a59a40f4873d2c02ac7"): true, + common.HexToHash("0xadeed7aff9a0c151514e42c4930ef36d5c25d455d4ca55b7fe14b0f5cf271e3b"): true, + common.HexToHash("0xc0e2d94409d2e1094063a3671696f4a46eccb1566f3be78b0688539f2e7e739b"): true, + common.HexToHash("0x4124e4c290d805240180f107f4d41b419e00e805d3df1a05cbe3df403265b510"): true, + common.HexToHash("0xb3ebe3d8dc069c998c2ffb4b281c8f387c7ce165a327a66e4b46b785c0628dc1"): true, + common.HexToHash("0x0a0a0d32d371bdfae9621b172465ffe2bb1ab9e5bb59469fd9fc2b98d213924a"): true, + common.HexToHash("0xe93c4dc4c4e7b7db6b998285d4fd5763733f81d968ac58471545e05612a540d5"): true, + common.HexToHash("0x8ea1475fe25571d29e3f921c45caaa8e0cb47faa25b22db62594adf2d4e0e972"): true, + common.HexToHash("0xd59cf0c25219d12488f30ca3f25c4de64b56a42a386e370dd08d05d13831163a"): true, + common.HexToHash("0x01eafa2f977c1019eca314c1ca627ef0c84f6c51a8e9c340c54351a02211c3b8"): true, + common.HexToHash("0xa3d3f28c260ab3cd16499dcc15b3c019b64e17e2bf335b679dcd2bc0d4b106b8"): true, + common.HexToHash("0xc947c41fe678fd31c92cc5102f3e7918b269f34c353c6cad11585691afcfe83d"): true, + common.HexToHash("0x98a91d6431e826068f61334b1d76836f46ae9d761e13391a384963d0f71371dd"): true, + common.HexToHash("0xcf4acc18df33df0b96897b7bb0e38f4722363c9ac8d35df8605a95e5add28776"): true, + common.HexToHash("0xaeca211678859c5c06f60ed85cae13c76f20b4a86e93f2f90abc43a79e948eb6"): true, + common.HexToHash("0x688e160d2abfceab6e1e66dec629e2f187f1ba198fbed77691f7a7da9cc9c7b0"): true, + common.HexToHash("0xa0e11ad9c0e5ac3e23fc342bcad362a88d1b02adf799ac88ca5af4525a11d2bf"): true, + common.HexToHash("0xc0e4cbaa139b1599af43b0907bf8eaeb9cad035348c09bcedca13c1365689bdd"): true, + common.HexToHash("0x14328eb26b1b1164813159d11b86c57db95eb894e9777b640d0c7c960c1b6e8f"): true, + common.HexToHash("0xd249e38f22f5e7203ac0566bdc52ffb79092798736202fb54594c81a609fdf61"): true, + common.HexToHash("0x5cb18bbc69a83777cb23bc426962546892022aa2d06d962692b4f0c65e2cab45"): true, + common.HexToHash("0xd59982b15837a0bfd090f1092c65d512621f647751ce97f67401d30742d53814"): true, + common.HexToHash("0x43901c8637daceadb6fe04eae39ae8323128d1afced8ab7632498bbcf5da74bd"): true, + common.HexToHash("0xfaf918c2ba867f5cc93dee2197ee9b52aadeab43c796dedce67e125dacb36000"): true, + common.HexToHash("0xfba470d3ec99823bfc733172f155911e5d3a5b630299cf03b886e69725685943"): true, + common.HexToHash("0x032a371564f3df89242f958b97a96fbc1af6d9438800c6ef0a77bde806ec5953"): true, + common.HexToHash("0x94dfb8513fcc98ae0ac2d4bdf53b34b96026ca126b5eb25cd369787896e6b7c5"): true, + common.HexToHash("0x691f82ef4793d1a8ad2f1992942e4436161de5f80a2e865048e39b9ec9bbaccb"): true, + common.HexToHash("0x8686e468df99f8ffcd89b7a7e784dc81a8787bea7b7744272e1d746989fc656a"): true, + common.HexToHash("0x2e10093c1ea6ad1a4e67d3d1ad804c5a0655bd39697e3bde4eb27b3f241ad7e3"): true, + common.HexToHash("0x2778cf8c3293ad774672674140759914dd1e662b845f4ede47619c214a6448d1"): true, + common.HexToHash("0x52b239ce3914d78e22345245e2741cade99ea458e7e75ae5b415952673d82cf8"): true, + common.HexToHash("0xe2a08453cc124ec469cb72e80bb49b42baf5df51a2a1dc994c5d0f5554748082"): true, + common.HexToHash("0x96927837c4efd81f84a02817e1a056952608acf0f75b388d5187a091f8d46eb9"): true, + common.HexToHash("0x3904ff794622ed5792ac7d5b6d9658049bc7dadecd248469e814743cc59d7b6c"): true, + common.HexToHash("0x21a0d582c180c8b2d86bc3bbd75e67737539d67ac9aefb7f397d57a8bbb790bd"): true, + common.HexToHash("0x5837d617f4a6664b34ba9fff7def1f4b9a5de20956918bfb365b3fe447e6eb53"): true, + common.HexToHash("0x8318e4fe568e23eb40cf1c905b95c5497f9b1933029a23a1ab08a210400f81aa"): true, + common.HexToHash("0xf78fb6f8c3f350a4f69c6ac3c356454cb4a6b730c89551800a73fba6451d3571"): true, + common.HexToHash("0xbefb233f30587465e59785dbe903feae07151e5793963a4f6409376b7beeafdd"): true, + common.HexToHash("0xebab6d085551f844094bf67b940a1516eff2e92379fa0f78701f7af5e23a08d9"): true, + common.HexToHash("0x44f05a99c776f1e0a72ec90697fc4071cf193e4b6a2f22919db332834ef71267"): true, + common.HexToHash("0xc70a0a2f0dfb73ebfeba768e0d78d5e59484edb87abbc8a88a321da0ba66e8ad"): true, + common.HexToHash("0xf836bccd91591c14dcad494616c6a5d863695dd3da6a44f2f4803f1ae1f615c8"): true, + common.HexToHash("0x1f6e2aa8f6c142a787c5e7bc3644b38cd2c118dd5aee131e919a4cf24c715089"): true, + common.HexToHash("0x310568878ed12670398d9d779fc3e81f49b78f8d6be3b94b404e0da9e55b0d5d"): true, + common.HexToHash("0x4c4c2088b37f9b91107981a578a69d05512b5f387bdd31f4fd428f6a594706ed"): true, + common.HexToHash("0xb7ea65b6685afb31ae09084c090b581c0fd03521751dd7ecf7f57714a0df6eaa"): true, + common.HexToHash("0x584ca12eb6de7d28cb3d3fff371f913bff36dd7ff182599ea6021788bba618da"): true, + common.HexToHash("0xb8b221732f24dbbf9e00653c34cc57a08202471b6db498b0fe9b494276d274ef"): true, + common.HexToHash("0xe6669e2e62da0c794ac48cd69577e6406ac32ecd63dfe65b8b385e24965f18e9"): true, + common.HexToHash("0xa784dc693a059cf106b79f1e0f5f97601723adf05ae46a747b36c05cfe463ae7"): true, + common.HexToHash("0x245f3550728643b24d797b61b859e48c390885d931f97c42f12839d9606d0382"): true, + common.HexToHash("0x17de6238cef02dff4de280cd9ba07900901e378e16ae1154060a1ea42804e3b7"): true, + common.HexToHash("0xb32ea4b70b166054edbd571bbac0025b78ba5fe773c9b6d07aeac451cc9eda1d"): true, + common.HexToHash("0xf29e389f9ad9c9fb2e13b73b0b6e1b4994d6e4bb44e03120d1fb914c171ff399"): true, + common.HexToHash("0x6d7b28852a18fe1101280bab80f10fc225df3b8f0a025779a33dba2da8144230"): true, + common.HexToHash("0x7d08a6774922d88143decefca8064d2796414333cac11eecb29c86aa97616b55"): true, + common.HexToHash("0xfc00b22f37c4a33254afb7d49f3c467dcd966d654028b2b912f181c16f79d878"): true, + common.HexToHash("0x8b2017f4a1205b555428759667ce5d90fd9d9b6d4608a533a261b7fd38fc3bdc"): true, + common.HexToHash("0xd109ba2e5ace530ae92c01fa847a81814edb5a8d3685a84717a53e1a6e79c789"): true, + common.HexToHash("0x8922e1989abca06232f34f58eba64e428b64e3fad2dd849f06bcef4dd5ee86da"): true, + common.HexToHash("0x248118d7e4d316c7b5a6dd93c4a2376cef671aee2f9ae220160e14b6c04f61c4"): true, + common.HexToHash("0xdb2d166d1aaaad666ffccee0f647d7c746716967c9b47691574128864502a785"): true, + common.HexToHash("0x4f57263f15d381601f5ae7a2b3ed3488321b98c370abe212a73d7998deb5e6e9"): true, + common.HexToHash("0x687ce1c637d9ac4bd514657d8689780249660a2e793f00088a4fecf93737c233"): true, + common.HexToHash("0x09b33b71f28e87c867fee90ad2aa10d6f77e3808f8ee174e6e342f3dd8d58341"): true, + common.HexToHash("0x9e01516897daf0b0628e265daeee0ef15ec10f1b7d04eea928fbb3dbf33a3397"): true, + common.HexToHash("0x4b369194cb11b4230d76bd8b3464ff3982590f68a5b06aff312aca070c6d40ee"): true, + common.HexToHash("0x794a1b70c22e36a392e3ea34d24eae43b1ecb8b9d5f5f72961a44811fe45993b"): true, + common.HexToHash("0x585e213b3fb74d279b1dbc7a5be37d8257861fae8a39da3f3b3c956e2402f88c"): true, + common.HexToHash("0xbb478faed13dbb030447fe6f342e53fb86eb362e4d34cb7c8456e277c531d373"): true, + common.HexToHash("0xfa97733886c19ac61020e9a7aa2e71949e05ed8ac768b96c6eefc02b1a23772b"): true, + common.HexToHash("0x891a378c67b91346488210aa221fef6244a8ed56721b2919dfd29a47fd864966"): true, + common.HexToHash("0x1d7ab3ec3a8510d2b63bb1d8a2ccb0669836664220d4432ae0053fe36972e5cd"): true, + common.HexToHash("0x3cf519f67c4f2f22a1a4b92beaf5e5b8465a17a97f4252ee29dc42a20b4c688e"): true, + common.HexToHash("0x1c2e04592984f82d543805bbed53eb23bc131fd0d4b3f2b352b68b515b57e5b5"): true, + common.HexToHash("0x36ab30cde8b3ea5895bb88b913dccbb142c33fb9fab1fc8a60bc56cc9605b240"): true, + common.HexToHash("0x323471e9390d37dc320fe9fcaf5d7d4f996af8b160b83ca491eb5b1d0bbbe972"): true, + common.HexToHash("0x587899368303871d6d0109c7bc1bfa7c1a2d1bd3a22453da8621c2293a4fa53f"): true, + common.HexToHash("0xe7d7cf6ce567b4f04be6724c02f81e8f1f4c012242c84c7c32d355f15b4efb78"): true, + common.HexToHash("0x4e6cc33746ccd88de0f2496260380bfc8b2f3a0ac9ba5cb8684ed87141d68de0"): true, + common.HexToHash("0x2b5add88318977b0973c02528e39d4295b813d3371a4f80e66f6f80138203635"): true, + common.HexToHash("0x81a214053f2ef10d0cc72dc264036b09ce28c5482c1a1b80ce146f9bb7afb6b7"): true, + common.HexToHash("0x14d3240bd2faf52a45ce4ca6add00ac5e92a68e410f8dce1446489da122c8fe1"): true, + common.HexToHash("0x3f2ec6d17cf415976369fdfbca60c15e9b3f2859894ddbc354fb186fbc051366"): true, + common.HexToHash("0x2b04759a79b8bb6055b39f3ef84558c73b078b1a1983efa1337fbc00bc25dc70"): true, + common.HexToHash("0x3001347805817796373df5ea4604a31f5d232f86100cef63715cfd9e1091ce4e"): true, + common.HexToHash("0x9a6ebef3c3dc4b7c6fdbfe275f756df3dcfcfa392f018ff74f652b9755111210"): true, + common.HexToHash("0xee3574c53e26465affe9bfe7a019ad84a5b302de7a89ba14a1d7e7a61db24854"): true, + common.HexToHash("0x7557581935b007f465c1df66a0e5a4344c63072c97c0449090e27b06fc6c4621"): true, + common.HexToHash("0xa8ea9897f5964e38bb5f18982dbf1a22936cf944f7837b0273818088a1d6336c"): true, + common.HexToHash("0x68b536fa5a1d2218cdb099f3a301f7e659bc42728695645fe8b844def67810d2"): true, + common.HexToHash("0x5584ebc6dacee6d8f4a9fa563f86bde32ab6730c2aa6d4dad76bc0c14bb77915"): true, + common.HexToHash("0x7913c0429cbaf33a885906ee9e1fee650abafd4fb317482082c5f03ca852955e"): true, + common.HexToHash("0xb2cf1b1f2b83237607d7fed5c43f3b27a1df6d1ee3e45eb678689bec5f21298d"): true, + common.HexToHash("0xd261aaf0a4d066bc0aa2aefc947f2ecb9b232840b9266fba0a113023da442915"): true, + common.HexToHash("0xb360522ed91ee016dfffc6cd7a5b4a72dfc67bcab0bfbb5fa61d7338b6e1aecb"): true, + common.HexToHash("0x949823604c2ea2d9881c5627c1177d4473e6feae855f6b30a877abc1472d65ae"): true, + common.HexToHash("0x60dbbb19d432fc2c201b3c31141b657bb8ef13fc43caee24286a03f30a27c839"): true, + common.HexToHash("0x1efb2f5835afd2e85b9333a1da14226247db9e2d8c6c3a51fca4e7af0cc563bc"): true, + common.HexToHash("0x00ee479ee037648fb49741a56e52c0fe3d8e414fde83d073ce5e177cd20a8fe8"): true, + common.HexToHash("0xf73be5ca95940e4eb998a2d25214bd7c257a1f3279be708a9fe3032b4af6bf5c"): true, + common.HexToHash("0x9dd0699cd488bc8a93dbf063066ac8df23b435333d32227081a9bfa115d8ba61"): true, + common.HexToHash("0xa7c61eb620c31ef17686edb161908e9597f9d938ef9bd4644340dc3b2b17b495"): true, + common.HexToHash("0xc2beff0cf4c2b2aafd11e44bb3d187ea1ea9d0e5d2ecd486a7b1650cb71cb670"): true, + common.HexToHash("0x7bb443a127785a5b8d0d0d9d844b9fed80f185b2c3cf725beae9c79b9140f409"): true, + common.HexToHash("0x6a137f2114b3352ab7917a4e4b3305e2d0f1a339057811fdc04f36ab1f173d37"): true, + common.HexToHash("0x7b61ca455bd78448c2bc847ce7b2afaa2d56de2b83e2cf6ed4b2a218c21f91a2"): true, + common.HexToHash("0x83b69484ecd064b4c0c70754049e66394acfb953837c764fc050b9cdd69ebbf2"): true, + common.HexToHash("0x9f8f9ab2bd61157c3d3367016a5f3633d9291c4b122aa203f557cd659bb81c86"): true, + common.HexToHash("0xfdb78df24d20cc309fca77415902bcb752d5dba754c4767a8103dfba439635b6"): true, + common.HexToHash("0xb13ea1d1d49679e1ee95c405eb4a7a902ba5e17b65b65f3f129ded072f2c6c75"): true, + common.HexToHash("0x1e5abb7e5707a1e3648c7f81d928e67d5445c6fc3021e8368a6b7b65b8d2873b"): true, + common.HexToHash("0xf4bc77bbb0ded49f8003900f34d0f648485a5514aa1fc3cceae0dacb9ef3e816"): true, + common.HexToHash("0xd0bbf1fcc2ca723fb722a5dc32e9f88686e51464c1c26b37882c02fa7746dd2f"): true, + common.HexToHash("0x58c4de5ff88b42c640576a4ed0b008dd04d27a9901735613c93468236671a117"): true, + common.HexToHash("0xcab7417a34accbf54422e39241d210123094f4923fcaa363d40242c6c9530531"): true, + common.HexToHash("0x64a63c9037de06ff378be151df093fce11b6e2da7356ec08e3c921a7a79e1028"): true, + common.HexToHash("0xa0e315fe64b662c362a69d28a7f7f5472bf701e4bed8ce40f884b2c84cbe58d5"): true, + common.HexToHash("0xbfa7232411630812828135635d20d373ae254e2f000908a81cc16c83ea813144"): true, + common.HexToHash("0xa0db0c2beb52d6a3a48b5b37c9f0a55e0f4d2f20bd9af07731be75587989ed37"): true, + common.HexToHash("0x269c6737917dda5013a59cf05445d91b600f08fdbb571e9a1295a9915e369f8d"): true, + common.HexToHash("0xbc7564220fa992f3d214f781933111d242ed4bebc51f21f0030c94a7b902f7d3"): true, + common.HexToHash("0xa84dc213f2872cf988b2ed25f9e3e397c3f100ef04914f51be1efb6397490de3"): true, + common.HexToHash("0xa7045e78e21e35265f7ffe9ed40709ca8a82836a141f5ac471baf018d11a0c5b"): true, + common.HexToHash("0x20ba5c350f44e130e55911836c2303fa8d871fe44a8605be4fbe70094f56aa13"): true, + common.HexToHash("0xd560f02f2d9012490124c7cf728344def93126963007b21010f3933660973c28"): true, + common.HexToHash("0xeba4f8c51b40a86c79311bf16ad0d92fe8bf23284ec78735804a121970090cd1"): true, + common.HexToHash("0xec3f7ed9cf451d4553cb2485348589d3ab7b0684d7a1af37ac73dc88bced7b9c"): true, + common.HexToHash("0xfaafb471305d191cebd787efafe467eaea5be64c23299e83d02b0188358e6251"): true, + common.HexToHash("0x1ff7c297e6f9d4cf6a5550059bb3c342c5f46257e93fc75880359cb72dde2ab2"): true, + common.HexToHash("0xe19067f47a70311e70abac8ed394977ebed6773cf146db8895423f442cb3ae1f"): true, + common.HexToHash("0x6b88d70809490e39c250d67dbe8f55335b765a37fc0a888659b06fa8d8e7cf9c"): true, + common.HexToHash("0x03e7588895d36cd74be69b4e3521af8222ee910e8d22cf15d90da9b4e2fd87d0"): true, + common.HexToHash("0x9dc5f534c5ad1e379803809898e6b6119bc4be47c3fd2a89af0c26f43c038b0d"): true, + common.HexToHash("0x1e8f19ad4c712e75ca0d3c40b11dea1cfa88a4abb2e63a08e97637c5ba7c1b6e"): true, + common.HexToHash("0x5d5b3cc75fb153a162606f0315bb062198161d225bebe290f70133133403b9ab"): true, + common.HexToHash("0xd05fcbbd381e1c948adddd45b21e0771b7cd3a2e3a547de6f5e2cefef5dca722"): true, + common.HexToHash("0x7c821f3aff6f30077d83ab6725d1beb2a8fe7751c5af419bb93768b8012c8b7b"): true, + common.HexToHash("0xb653a43d92246ec4e8e79f09ee78a1ad9a85bd5786625e3662272086113c8f43"): true, + common.HexToHash("0x5940ff76c6b168bf036fc7ad04048cebfcba2c408c3fe4e23da7852bd13d6b92"): true, + common.HexToHash("0x65cfeb4cc4f156f2b51192f7d5c7a0b59746550ec05e530785e1bb9239c0b93a"): true, + common.HexToHash("0x1b0d75dfa0f4d7174d2a7d9bc4819c6f13b4c50d2001163d831d0e8dcc29b34a"): true, + common.HexToHash("0x560d1379d5658ebbb69f5ef38c3cc6760460fa4ab9d1ed2cc6337c8a3162f90f"): true, + common.HexToHash("0xb58a1e9cd13290e5fe38f47abc20953b0ddf1ba08cda7280e5e4d5518c73f177"): true, + common.HexToHash("0x73d7b0e12cc6c3a204f7e79dd3fd38f7128cd130e1b0976e63d3b6ee47f587a7"): true, + common.HexToHash("0xd656160c2e7b9e9a08623fcb90ca05488fb41e97ff81d55ccbc6b7eb8c55e1df"): true, + common.HexToHash("0xc1e0c1aaea56c261929e1c9cbcb6b9c6c9b314f7f17e79d392dec759a70ccd4f"): true, + common.HexToHash("0x9a589ec63e01c3d66317e09ce9b2aef3970b3773b89e3b19db6fbe367d127d04"): true, + common.HexToHash("0x0af4da2f71c9e376659627530c9910418e423252dbba1ed3a1b205754bf9ca4d"): true, + common.HexToHash("0xcbdcfbdbf567664039fd49252ee7f7cc7dae8ddf84b08bb4c44843308168fbb9"): true, + common.HexToHash("0x1796da961d09c71825eaa1a86025486232cfa13c7ac4eeae7c977529b456a6f2"): true, + common.HexToHash("0x9979a5ad14dea37ed37325246a1345cbce9eff0860b5fcafec5a9c5c6f6651ce"): true, + common.HexToHash("0x35b059fa074a9fafd796ad2593a74de06cf53ef204680b64489fcbd9766a5ec2"): true, + common.HexToHash("0xf4c5a15fa7924e3f565ffe5da3f5106d709b376754d41d6b0b40a9cf9ac9ab3c"): true, + common.HexToHash("0xe0ad563b8befda71c153ef206ba49ab6e6d8d863f1fffb2e87ca1852d51314d4"): true, + common.HexToHash("0x2a415f2b25c37492096ba9267a675aa75ff0d082e6ee0d8e469da22005b69051"): true, + common.HexToHash("0xb96e615e29981750d2366c95275068524c49be289ea3147dd138d8d14783efe9"): true, + common.HexToHash("0xaf4effca5548f44a0cdb7c39d2883ca4005c2040f74526a82abf23aa59804514"): true, + common.HexToHash("0xc12fa15564b8dee4e979e08ce021cf387a8423c3bc7cc52d5c12316ad704fd62"): true, + common.HexToHash("0x802a5bfb2af254add4d36ca5dc975071a8e2a8df3c1bff81f9e6b03667b567d2"): true, + common.HexToHash("0xb7f1c1e8686392dfb74402b6ac3c0054f8bb42643f58b1efcb7c8dbe6f2034e1"): true, + common.HexToHash("0xfebf924cf06fba5f28ac3e51badef2696cb7c87b5592c7766410fb24cf10f6ae"): true, + common.HexToHash("0xc37073c4b7ed4610ccba321a72705ebde0d4376984e5035114f7bb8e30d85134"): true, + common.HexToHash("0x858e28a76bff36c89004926a89417619f67393ecd78111df8eb4897619e334bf"): true, + common.HexToHash("0x16a18b7f98a8a5ef288650ddd36bcb858b3972d28a700759fa46ee1ab96e5e4a"): true, + common.HexToHash("0x5ce6bff3ca5c11b39843f4945308ac4466cd710b2a9539b27edc811e44534377"): true, + common.HexToHash("0xe3d2ef44500c7355d8c728759ac6a3f233f42531ecfcb3060f911d643b363caa"): true, + common.HexToHash("0xeacd87e82d9befdd295f97cb324fac7957305e8583f00d8c94cc2ecb7602fdac"): true, + common.HexToHash("0x97d518180744404d6b811e664bf7035504181838275053d416aa64296078112e"): true, + common.HexToHash("0xfc953ff61f519f4ae9490dcc026dcab53f12976d3be8b78be801b059a19a6147"): true, + common.HexToHash("0x3137b603c4abc1f78fd792b118b7c4e8df2cf020a4e3b69cc585053edc77f15a"): true, + common.HexToHash("0x5ca1912a5c20ecb7f1bfe1587de518ac354d852a7e9aaf76c7a93d9614b69018"): true, + common.HexToHash("0xb9408583968b060f87b70ff980d40afffcd40d4f471a9464fcf2501ee74f59ee"): true, + common.HexToHash("0xb650740b6530d05a01f42a97063cf427b02dd994b6372cd73bc1c3aae032be5b"): true, + common.HexToHash("0xfcb0b8c897705b797bff68dc34afc9acf95f18b11f9c94f4cd785dfce168f1bb"): true, + common.HexToHash("0x216847040a1e3b768eeea13012d707fe7cb66ec9fbe15a2d2f18d36db5c86d1c"): true, + common.HexToHash("0x8afe4833e5eb53ccd5a16257a95d02b169a742e4c465742659a54ee53c4d9602"): true, + common.HexToHash("0x9eaeb93a95cb534a3cb20928894c10edb88ed3f84fc5fdc8ade224a926d6766f"): true, + common.HexToHash("0x927064b6af6988da3486b9b44d355f9d61859d9f555d5067b3a4c7cf7f3063ea"): true, + common.HexToHash("0xa76ab03935c45132e5281782e96f60df4e44302d55976605722ef76b76cbfc55"): true, + common.HexToHash("0x2a8e73fdf3fb6da37802cbb1438fdadbf10f7d9c8a5654f1ab344360b8dfb482"): true, + common.HexToHash("0x74ee4a9bc4092f818fb1e3cd3fdcedb86fc6e285e618afb1264f3ea5a0f07d0d"): true, + common.HexToHash("0xf3cb16cec501ac6240a62047b245d63d61fd75b9d5a1bf89b455309c181cf7ee"): true, + common.HexToHash("0xde8a04fc722af93237d082544575ad0ad6bfd87207b1d64f1ac8aa0748cc6515"): true, + common.HexToHash("0xb7fd635ce2fc12951fdbf9ef7145e7f0c2f9ad120bc14f5ef80b504d94c2153c"): true, + common.HexToHash("0x25ed12fca7b4857a448b518cc7412acb4947e94e95ba9fb7364aa5821d1a5cda"): true, + common.HexToHash("0x33e7ef3011c069b6ba4e76a58c7a0d2990394e58905e4d0d9d0f672c1934e8f2"): true, + common.HexToHash("0xc390796961f1c74ce2085a6be8c52535153a160f7bed270f984ec36b1cb4f97c"): true, + common.HexToHash("0x363c5d37e9a91c8665e71efdc71848fc75a12b9b375e2c4072b3114c5d69750e"): true, + common.HexToHash("0x8c799d64022065367034d8b83827b0d5af5d1ddfb4185932a82dd3997ae85f6d"): true, + common.HexToHash("0xfee75f0608dffbd9402d0620ef4e5ee0ffbbfe95197bba038e337a583f872761"): true, + common.HexToHash("0xc8a97e35ff70ed417865ea44434a6a2469c9ece81e077c73886485b202312a23"): true, + common.HexToHash("0xe432b36bbc57c0238f825351a523926235f7187406bfe69308fa4f8e10483b03"): true, + common.HexToHash("0x81e3cac6c4877df6163a1f7049151e51b3823abd26901837131b2f8d5a864948"): true, + common.HexToHash("0x1a4eae6997dcb6dfbe127300603f83bbe7c2fc71b892df9b6f8f8b988d144d70"): true, + common.HexToHash("0x6b68973e0200bafc5712c7bfea08ab22c304b1c9c0aa480ad2524b8298e53850"): true, + common.HexToHash("0x8ae57292e09826d93ca23501efbf1028c06cd3c88521e56b7dbfe36c9c6320ff"): true, + common.HexToHash("0xc99c38bfee2cdf818f110ecbe28c75801c688b5c68cb732f45400a2fa8c90abe"): true, + common.HexToHash("0xcc148843086560dac25661b10af3b7dd85f5db228d1fed7b6eee38e76bddafef"): true, + common.HexToHash("0x488b4a431b70242964c3ac0487d9c8b31306fd91501574a87c2bbb0838bee081"): true, + common.HexToHash("0xa2cb8a3750a690b35f98dfc81ad35c6439c39aa3a2745da04718eb9236ae75b4"): true, + common.HexToHash("0x5a73053d64b668596d0e77679b1e91d68a9ff2d8ec57a241b7943d2ab6667762"): true, + common.HexToHash("0xf644be1ce0fc375ffd1c06b11c4576bbe1b6edd195dea09de861a46d8933f78f"): true, + common.HexToHash("0x59bc46476dfaad03e45522cfd26c17f8dadae9d690ab0d42e99e8e2e22dd17a9"): true, + common.HexToHash("0x7b39ff95100765fb861f5411a95f33b06e6c157d86fbb6723f9d5c2e9d77837f"): true, + common.HexToHash("0x3bb978c8b8d8d1a742494536bedf35d8078753c7a9e06962faaac444ad82a72f"): true, + common.HexToHash("0x14f53a84f1201f07ae1cf1bb5709e1835e2956df692302b759d5b26b81326884"): true, + common.HexToHash("0x2d682fbe2a766689ad67d1b5bd86ca986f7cd82471a623d85bd4dc5fbcebeb4c"): true, + common.HexToHash("0xa50e6d8bbc4dcf3f1101d7f8ea0491805251656e787c5005d53232497fed26df"): true, + common.HexToHash("0xadc8c14381fb6764cc36d72e05733326cdc300400839382c903dfbd014f848ed"): true, + common.HexToHash("0x3c4df3c5208228609a35211ce357f7b1add77c730037ed9de15a4ea9c3b662cd"): true, + common.HexToHash("0xbbbab8954050839a95ed26430fa27c957a14bc7928508beb72d461af8a7f2a77"): true, + common.HexToHash("0xa5dc5d7b5da1592c04d09b34862ecd71c907784e26c9c1ac6fd3f6b6e64e604d"): true, + common.HexToHash("0x659377f3fe9185609d61527b4d8fca0a5187fe8ae9cc8fc76efadf28bb27c810"): true, + common.HexToHash("0x634467cdc08cdd0ba8e9c39600306f7537f207b1cdb0f187b18f66b22dbe7dbb"): true, + common.HexToHash("0x46de12cfcbc9566b4ed07dacfc7d63ebe46b88e60321d9f1afd2e532597c213b"): true, + common.HexToHash("0x6ee6c0cf2f4a9189bae0f995740ec2dffe0b78f8510906de81d0d78d0cf65dc3"): true, + common.HexToHash("0xa7ce77f8ea2d1e87412a8a6c77c1351ea3ea985a7a409a398425c6a4af765b14"): true, + common.HexToHash("0x2bc8f75e417d6bdd15776c543471dfef747ea64d7880d626dfaf97614e51f5c6"): true, + common.HexToHash("0xc9124af474d12ebd45e3765120a1bdaee23ef72ac3c1cf4aa533808c90d6a4a4"): true, + common.HexToHash("0xfcd2576ada71a722b646bfbd36ec2a3089b2989b978f95f22742daea60e0051f"): true, + common.HexToHash("0x43e42639b01dafc83feb3afcc275d37213875cf9ea6a1cb08c0a6811d5318c02"): true, + common.HexToHash("0xf71f2a2f0fb56cf53930663335295fdeee16fff3b0f814cce0bf4f55cbe731ab"): true, + common.HexToHash("0x4fbf841bfcc7c432c5dd92720423e9ad45f9bc8d53edcbde218c35969f9c6a3e"): true, + common.HexToHash("0xa280e7438852c1ef21ab971f65f04e7b6de6df11de6d57156a7828ef13449801"): true, + common.HexToHash("0x325d389a56306518091607cab0568ee86b4f6bc8e5b4bfda5cf96ae14397d2f3"): true, + common.HexToHash("0x8a13610ff577758a681b825404505981b229893606122d038befd0fdb89c320a"): true, + common.HexToHash("0x129ff72923e54f0b7fecef084fdc0445e19df89aaefd8c373080f9fc897d63cb"): true, + common.HexToHash("0xb0b6ac09d5349af38e4994434c9b5d90f2a8196c0ac2ccdd4638fc9d4cd8d89d"): true, + common.HexToHash("0xf6c48b89c54a213c9547d497d5d62a70efbafdd2f23c3c2f9c9712b167a68a21"): true, + common.HexToHash("0x0ce71c5cad6d5b6b61250a3e5b4fa15564339b19169431bcac6894e17c0163ec"): true, + common.HexToHash("0x06a9ce8d8fb01491d5f21d47aa16a5266379dfe1bf32801ab4dbed3652f76c7b"): true, + common.HexToHash("0x1d32b52a44e281f20936ed128a51f57222f3d0a4f0b586ccc6efd2f090142754"): true, + common.HexToHash("0x5b45916cd82a9d3069e200afdd413d137d50b7e60f0f81d4874a12fd9b073713"): true, + common.HexToHash("0xeb518a82e24999a3ed9a02ee6a44867e8f0425a835e50945506578bc35fc32f6"): true, + common.HexToHash("0xb7cb0a1bce6e60d3910ac5571b08ac7a2fd274030a12cf5365e6b389394fd4e1"): true, + common.HexToHash("0x138dd534ac5572ed5ad90ad788d797c89db647e5b42fcf19cc07086c7223bbd2"): true, + common.HexToHash("0x35578f729ef7cea3bce68d484fb4543b43f1039cfc6a10675e1f0919fe8c7566"): true, + common.HexToHash("0x516a6abdd29d8a8b3e89875b95510d2e74b9da206ed2a05a3ad199dd1858f3db"): true, + common.HexToHash("0xd20a19e5bd8f3b3eecc576c70b9ad60558997e34131c0639c84c16f42c403800"): true, + common.HexToHash("0xc6abd2fb13752e24b7656a6936ee325be82b0c89eed00a61888ebf1456679575"): true, + common.HexToHash("0xdaddbd52f9a9353af52fb720294328e45e679d63fe99f4b4583fba417108f18d"): true, + common.HexToHash("0x4a118aa331d24254b8a64effc427571928ae43b01f689c08ce43d7dcebbe91f0"): true, + common.HexToHash("0x5ea45a3ad7968871e09bea2955888e1f72f81d7754f380dc0d43054614ab82b2"): true, + common.HexToHash("0x29efa27ee0e25f7c4c3f208dac5126e6429d232d5dec56bf06514ee349ec482f"): true, + common.HexToHash("0xe27f08ce85e7e05f391fc8321a36020f109604c8a0bdefb911bd100c35fa31cc"): true, + common.HexToHash("0xe9e27755f41f831e79e98df0fba3bd0e8e1ae0fd8d92facd3ebea47925b281d2"): true, + common.HexToHash("0x753ab1058d6697536dc1fc80c8c1aea9a2e8b34122f5e823aefb40c71aa14f7f"): true, + common.HexToHash("0x928e89c7359130d8897a9450a04941f76e5f44efcfabbc5a92144516cbae9635"): true, + common.HexToHash("0x19886220df06b8395a53a177fc01bb718f6e8970debfcd694b5f009e2e864db7"): true, + common.HexToHash("0x07f4883dfcdbce9304b2a7cd2ec95fb3cc535013792673ed7c0afcdb1545b01f"): true, + common.HexToHash("0x87e1610a489a8b52da6fb2afa18f98932fe62be67b254a139d22115c080fcf52"): true, + common.HexToHash("0xfe8b27a254fb0dfb019095ef2ce5782b5e55c18023b5c9231a0182da64b4733c"): true, + common.HexToHash("0xa0419aa1375c38bd48dbe67f1871ab96fc057a71f837fab16f7d9844f8f729ba"): true, + common.HexToHash("0xfd0ac4cc2a2889a5516273daf4289d63cadd4081ad975fe45807eade625f6ea1"): true, + common.HexToHash("0x969ac6a28035029b861efac40ef43e934097542d4aa6459cb329c1aa8c268a41"): true, + common.HexToHash("0xd6caf3058a0e6d22ea3fae1ef8816bf3f482f84531f0cc4cb055cca9a996b079"): true, + common.HexToHash("0x4bb925d4eb20d8aa4d0a8b624cb15a4c248de7d5612630456adb12f07ad7fc3c"): true, + common.HexToHash("0xdc5e27165d58e6cea61d1d663384a0a046c6d9692ce7ae6a6a79abfad55c8fed"): true, + common.HexToHash("0xb754c417782863a02135021e1492e71a47fd930990daf0dd53acaed53ab957dc"): true, + common.HexToHash("0xda35c71aaa2749d60305bf3815175d18c05c560692a093d5b2f863a0c8059318"): true, + common.HexToHash("0xbdfd60da5ef5dd74aeae4d14d352c7a1b7d5c637c2204c8d286c2e52a5909566"): true, + common.HexToHash("0x634116eb21010cc3ede96f61cb430617120484e02d0d9d0207c07193cfa4cfe4"): true, + common.HexToHash("0xa51a0797bad821113b315693e4092be2aa8533a08e9a1bd8c6c1ea4c459639ed"): true, + common.HexToHash("0x9301dfc7c43ba66c302e9b02902a367732a04c8004a81684b41498417c542986"): true, + common.HexToHash("0xc73151c3149df1bf7ab7b2ed98a26853cc4ce6c6210577ed87e7561a10e6225d"): true, + common.HexToHash("0x1be6138a5234cc0d45806f3c64c1d8d65fb786ce7d5ac9d7cdd636b8e0bbf611"): true, + common.HexToHash("0xbdb450a6fc19819fcaeee5e41f21b75a872c81c224f48ea342effec27f4bed2d"): true, + common.HexToHash("0x0fbbf9d2222365d3aab74e898155ab57967de8fe21a09a300218903539512d59"): true, + common.HexToHash("0xb95660b55be62877d6ed498b7b1e3a86d1a26df51e00999f100312f39e527bae"): true, + common.HexToHash("0x8f61bfa3224ba75b10b64341be25db09d8f7adf447c1e64f25e51bd72244eac8"): true, + common.HexToHash("0x52c07aeea0aea5fa49c934ae092d6a117b26e34753367c9eed3f7d5213de3bfb"): true, + common.HexToHash("0x6f0a8ec333da34fe57cbb23f375b4e375779e603f7d48a6c9477f5d101532a09"): true, + common.HexToHash("0xc5f2f29a5c9cba2ce1c7785d0c2a48ddaa1624dbc4d2fa2d903657218e24f32a"): true, + common.HexToHash("0x44a6d077d6ddfeb1c884b68de4d5080a7e5826fdbc7d0963075d39d65e0db73d"): true, + common.HexToHash("0xced5fefcf30e6f9b6a64d52684b6163a82d5e44b76af6580b81cdfe703bcf020"): true, + common.HexToHash("0xcc77c8ef3989e3c1afb1c519e68361988fd2bf40621dd732e23a95e4e87dfd87"): true, + common.HexToHash("0x142ed43e9eb9af4eff8a2d099bb0fc4f071fb5dac35861190e423431de00d57e"): true, + common.HexToHash("0x3186dde55b2280cf339e509fae5782dfb15a094053132e54af0db865c8b6312d"): true, + common.HexToHash("0x38df54e167b3a14fff6da7b1a944b4545c609741cc54122d7eafa0cc797b2a08"): true, + common.HexToHash("0xc729adf566932b7383a5aefee109681e03367ef0a854a4a7c7687c57e7b42c41"): true, + common.HexToHash("0xd957da451e13d85b2fcc4a31eeda9d8acdb2e667c6a28514d69744395d9c5ebc"): true, + common.HexToHash("0x6a3b58a3280a321677ce4da349c6691d8129f6932207667edcbfad911345cc60"): true, + common.HexToHash("0x9f2dda7911401a66ab4119495c931a471ceec4b7d5013efd9eb51f62cdc04bea"): true, + common.HexToHash("0x0d6837aa1e7ca02c395dcc9386bf1c66d7a2a6439d8135bf9e5f89006096271f"): true, + common.HexToHash("0x3a84fec98f27ec80175dff3c73ea33b5ec9bfa4d9a20f15cb72c0a79a2218a77"): true, + common.HexToHash("0x6080dc4c3ac9d227150fc0cf094b40b7a5393ab7c258880b93f6103acea51df5"): true, + common.HexToHash("0x160ac263637a6a346dc84245368b5ac5b5d3bc5621b8839b4d004b153f429d72"): true, + common.HexToHash("0x9a2d6c37c095eaf96e1b96b6020d7dd192c1365d8139ce1b8570636a8c1b43ba"): true, + common.HexToHash("0xa7717780dd0d3dcf51b5ac99b083d71058ddf6ea63e7f10a1886d8f20b1a9111"): true, + common.HexToHash("0x56aace619e32ac0fab4c02584ce18f36931056c0d912bedf4559150114c04d17"): true, + common.HexToHash("0x6766617e6f147aa2e12ad87e6c0d1bcb3e190e3e42ebdbc2b7e870a923ce7b9d"): true, + common.HexToHash("0x772457dce5d64c3ada972a8c564abb451f9b35889a5dfcee358fc6210209ea5b"): true, + common.HexToHash("0xdb55501d70565fc2ae665c69c061bae07d3578467f760b69bb5bd26af6b58701"): true, + common.HexToHash("0x098ffac8f01d98b1f17bdfb56c1c00e07d0d208ea58978025f39f810df3f1849"): true, + common.HexToHash("0x8ed3c47b378926bff871531baefc1c29fbbcde505e113505333aa36a509d24e1"): true, + common.HexToHash("0x4dbaa0b3b11ce7cb87d5155ca87d47103a79b0e90f12cdf08facc1e2f5118584"): true, + common.HexToHash("0x0e8c8bb18982c04ef518f57a1c2d56fce7ca7b72c1af2971e07b6717a844c105"): true, + common.HexToHash("0x251b1092146a96e3192901b3f8079e306b089c70802eb7d8f65b97335a6f8d54"): true, + common.HexToHash("0x9a9c41c8032a6b2e77e25894782f219bffec67d2d6db850dfa413489b3560cb2"): true, + common.HexToHash("0x8013550509d610d2130fb269de7563e334588ca87285ff1d4780620dd848a919"): true, + common.HexToHash("0x204dab3c63325e5e2f7f25a457faaf6de5227be6714cc984a11507612f5e233e"): true, + common.HexToHash("0x75c9fc829c23f30c28086c28aa751c364905e6647ff5ec4fdbba95669781ef7c"): true, + common.HexToHash("0x792ea8f37b715e2f2090ed32bd8c940e0976bbeca65ea6641345b3b7ff380c0d"): true, + common.HexToHash("0x855d097289f1736d9fc337778c567d7109cee40e4c24043d9f828c69cd2267ec"): true, + common.HexToHash("0xa454cff96b5e4ca57b0f9da6842505083146014a431c617e711ee83704ffc99c"): true, + common.HexToHash("0x4b29339ae4164ab744021952b329426810fd2c38b0d0d0b708065f58aa46f92e"): true, + common.HexToHash("0x967af9acec4879676be3142154c161d6088278139ddf046f3003963cbc718f87"): true, + common.HexToHash("0x24649d158f6146e1514f4ec9273858f271261f14d620f38c6b14701d4328aa11"): true, + common.HexToHash("0xf77b4c3a9a10046fc23b8bfda3a1e50f67c0e73ea4be7997f49e847249dfe41c"): true, + common.HexToHash("0xd12095ebdd673b4fce9e64f43291dd193c4794557ed0b254c438c5878af0f779"): true, + common.HexToHash("0x8d184f6c6e4d64052a61de20281a56bed3a9ab999f2fe3a105193a96a9e111b2"): true, + common.HexToHash("0xec29a74a3c1d448e99b6c21e0eebe4a4f89b0b924fe948c09975588174f56e9f"): true, + common.HexToHash("0xb8a9f4f9ec5e178f1a8ccc6fd064846502ee1293db19393158da88f326e542de"): true, + common.HexToHash("0x88a3e14b5443b8da825bed6c041f6dc1077c317308dbd380817c77b61f6d0a72"): true, + common.HexToHash("0x8774d7166058105c25e74e09fd3a4dc29fed33c3ad22d2c00b64791c5a46b827"): true, + common.HexToHash("0x6fcc8a85e1ef5fbd03258fd05125a35ff815e11089e2f7ac8a4a206c01885d7c"): true, + common.HexToHash("0x0092778fe421eeedfe95af8301f2d6f17e3724f4c196376de1d662978d02dae9"): true, + common.HexToHash("0xaebc0e0251edf2826308876cbf84a66fce4e25744d0d8ceb212551ff1e3d4885"): true, + common.HexToHash("0x04536aa81f688774be52a295ffda0267d7cbbe1d717a330bd61670f0b2d7e0e5"): true, + common.HexToHash("0xf2727c1ac965a86566ae4b71c4a5b16fab7e13a2a9720e89a7ca6437b246d17e"): true, + common.HexToHash("0x086dc5643163b3043ba64ad71fffe093231b861b4029221a6c4944eb7d4b18aa"): true, + common.HexToHash("0x6c23c40e492d82f87b18dcbe5104e4be02c9274e527e2cad59a3fcaaa05be775"): true, + common.HexToHash("0x5d6281e13b92e67c31ff0d35fca5eba8d7eee8c3d813f857dcfda7031f9656a6"): true, + common.HexToHash("0xb7bea42b49ac6401a8837c21e86d941345dd2fbb79aca881d6f38e681aa5dab4"): true, + common.HexToHash("0x267c2ab4dd2dc8c82bd248a41c08545c44d0e3f0234e25beb5e895d06dc576c5"): true, + common.HexToHash("0x0c554c3d6a3e5e7bf349db0132790ec9b131b8788ac00cd506bb1908a1e614e1"): true, + common.HexToHash("0x75b0dd11f6dbed9385b4c1d8386a22c753c4912c6badbca7ec5c4c50014fe0a4"): true, + common.HexToHash("0xc4d8e480678d97a43cb70efbdf658a9e88ae2366be048aa2c5c749239e0c2ce0"): true, + common.HexToHash("0xac692b514b7f101855e3b37be141789b031ae21fab80412c71a9a13e95cccbb8"): true, + common.HexToHash("0xed2f57ae2455c48502afbd4244f41c7f8c84f490be28250f2861d536234fa786"): true, + common.HexToHash("0xb4ea26c13ce080d7bcb888c8fce350cbefaf4ccc0a3c7577dc126519f445e394"): true, + common.HexToHash("0x894bd041da9375b2f68b51d06fdf5a1b04dcd7b82c98aa125338e80f6e6bf46e"): true, + common.HexToHash("0x20d3e6c0710ec15425255ffb22aaa9487af3632ee07a8979616ce641d62026c2"): true, + common.HexToHash("0xdfb03d66953eeed5e223e49054018420904109b74f7e1391729687483838d3ba"): true, + common.HexToHash("0x089d7bddb059b7642878f8d2e5286830214fe9329fe0c20d4863a697cf7ae67b"): true, + common.HexToHash("0x0b499287a7d1ea88d91d4a6df3e71109ae601cfa06816fb927770a7df5c945af"): true, + common.HexToHash("0xea1e828a4cc42d05f2ef63cbd7e80bca9f2ae4ccdb890046582e283313009f2d"): true, + common.HexToHash("0x822b9a46a43a7b3ec56135ce4ff5c726b461b101a3b7742f5c041527bc501216"): true, + common.HexToHash("0x89f44c188f71cdab314e247138e5c6dce00cc9c1febe41f94342e84d29a33989"): true, + common.HexToHash("0x75e058cf33d4e1b946c9376b0389d9dac79ba19e5857707b8af92dfe02e94d61"): true, + common.HexToHash("0x6eec1b675b0dec8f34f903e597e8bedf73723aaf51ab9cc19971f6ad4971a276"): true, + common.HexToHash("0xec9999dfe3829e28e94646ac679d9be878d5f6a17f19c5f9ac3c5126c9836436"): true, + common.HexToHash("0x1208b85bc0ce19c4a16a0e12f876a9e254e242340a7b7d61de53608c2e403bec"): true, + common.HexToHash("0xae26b38de5f5f180f6a5284f8ee10edde1cd180a479c916acf12d7184b25060e"): true, + common.HexToHash("0x4ba8c91d86e1e9b9b411b25f6618935dcfcc42312455c5e84cdbec99f30d89b9"): true, + common.HexToHash("0x50a34be5a1e0798645d016801510704edd6ad925999ce64faeaacbf02446fa00"): true, + common.HexToHash("0x923763d088e21348c5c024dfeef8afef8a9940a274fa0626671af913bd740903"): true, + common.HexToHash("0x77baba5d6097f24d78529704d2657ab064b587364a7a0c6934f67adfbc02a050"): true, + common.HexToHash("0x3225fc440f4dd276aff94adff01073418491ec92b5b70265cac8b66c16239ca8"): true, + common.HexToHash("0xc62c42fac3ad711ac046b44ad2659d4de7492b940992b8ef9540c74dd6c03269"): true, + common.HexToHash("0x144932d1716e62c1450298713102d7c3b882a390072de9c715e381f9e8d0ea15"): true, + common.HexToHash("0x8047330554ad89e58053cec83ab639076b69d01af9056e21bc8cd431a3bf3b56"): true, + common.HexToHash("0xfa88bcade9749c84b95c0b6a6665039d79417cecbf7c6f29503c0f26ddb10336"): true, + common.HexToHash("0x3c19c9f8f332bdb251e145fc21602a70b9a8aad993206b26abcfe76bdd9f9ff4"): true, + common.HexToHash("0x297e9384f657b4cceb7b011b241d4d895ca3547373eda962613808bce1253c6b"): true, + common.HexToHash("0xb712be3cab11d3609fbeb9a8ff5956d2a6425385674e1aa770ce55f855cd8907"): true, + common.HexToHash("0xe97fb84fcd7db4bfbfe84f1b84242fbbd0123b0058277fbd446e856d12458dda"): true, + common.HexToHash("0x88232de24380fa4fa96375a5150b37c332b89e515a4831d200574eabd00fa295"): true, + common.HexToHash("0x2f618c2c7ab31a8a450598d317da1f927813b4065de15802de7ce135d61aad6c"): true, + common.HexToHash("0x4012ef719db4bb881e0f9f522a390096e50205ca9e7fe6e22e58d41c10b97dc5"): true, + common.HexToHash("0x470f4c13e3f31b73b3761f95aefb1db2c30c721276065036e91556ba1c27d84d"): true, + common.HexToHash("0xb75ef4f549193e55055421870f1361bf48e87833543f83fc1a9042f4555ee6c9"): true, + common.HexToHash("0x1b3e7b6870de47e7fca76ad3d145bfe6cbc10d5e4a37200654a7c303c19f950e"): true, + common.HexToHash("0x1516d4b8b7d02ff4201a169dd05e37fc13793479b82ef03a461f16e3b3dd78f5"): true, + common.HexToHash("0xf432b74e961541e204c19a6c1cc837ef37d38509a49eb7aee7fff1388e7aaf35"): true, + common.HexToHash("0x49e62d32d358d684651a957874b8df85dc1f25be5b3a3a7418e772ef2a65e4ce"): true, + common.HexToHash("0xe6357a557ca864bbd07142f970b58d21d1c023b55504f94a51435f456f373f90"): true, + common.HexToHash("0x94e4bf676b03a1c8421dc35f866e2aa09882529d72e08f35c0d505616701ed5b"): true, + common.HexToHash("0x83735216e48a797a05b9fe73c075cf861cec3bb8e347a571f8f77a91ded13e8c"): true, + common.HexToHash("0x79675e8d5b3c906f9a4c93826104de138212621eeedd6c0792bf154009d05b20"): true, + common.HexToHash("0xf5d08c624572f59fef9a1f9b9e5fdcf6a8840a1ab112c383df4458a3dde2132e"): true, + common.HexToHash("0xe9b7087cb8df4a8394e365b9eba3866c6f7d9b50bf2bc065af8fc2566fd096e8"): true, + common.HexToHash("0x9a2e097a12c2f48344d28c6012f8137ac7a8c23e885a092abe918b9299447b43"): true, + common.HexToHash("0xad957cf904cd1affda9d2b4cbb03efbe5fbb87c35a01e98c9c78a676efc7473e"): true, + common.HexToHash("0x16044adc447999f6602c93c1f969b7ad88cddac232a015355f7c66ae364fd18b"): true, + common.HexToHash("0xcc0d026574cc1e0d00b53afe60d521753ab9ada10d4b2aca11a7035079d0b68e"): true, + common.HexToHash("0xe523ee477b815e6ee4e68d5e0b7c2058749934ee48d7e769e959850fffe82b38"): true, + common.HexToHash("0x6a154f1d92fe1c85ef95c4e75ce2161ad32bb3bb091fb1a96a1e4220a0fc5387"): true, + common.HexToHash("0x0ecc5d35c9ed216cebf12afa5b344556504ac4a0b5a225d752f871bda7d1f8db"): true, + common.HexToHash("0xb0b73ad0123b79c18888baa91a180e2bcb20ca3af378be1a59715705464ea5ad"): true, + common.HexToHash("0xd6afee1b47897459fff119943bf0992c57d62ab0404295722ec7e46fc01fff75"): true, + common.HexToHash("0xaabcbf1db68018ef7e4516fb7db895b461e5028e86e1e9bd24f33c62861576d6"): true, + common.HexToHash("0x8b695331bc1fa30639323016b72a51b03f81061dad1bbeb7d30827f9087eb16c"): true, + common.HexToHash("0x17a65cfe44c35561fc463a8d14fb5a584cdaad8078cd9f9083d5cfc394feb49c"): true, + common.HexToHash("0xca8c4c00996bf053f67fc8fec0f6efd023511f93503423473bddf11604983e3c"): true, + common.HexToHash("0x2babcee2073c5bef8e8d72b39aea407823ac702d047572306be02ac9d992add4"): true, + common.HexToHash("0x95c00410786b5097a94761e8c9634577283bbec3e39ef399ba4634fd805caa65"): true, + common.HexToHash("0xd46446024b61be03d595da2fc99cafd99d0eabbb380240a5d4fbec0d9b07bad0"): true, + common.HexToHash("0x14db9ea4ab585d0d3d6b8fbf5e6d3d7b7409e43a5f3546a7a6aacf61785d7e02"): true, + common.HexToHash("0x9d9bd36b98757200ab6f7c911c66ffb306e690e155a20aa911c22c67055afe0a"): true, + common.HexToHash("0x533b7dbe9a405181d5231ae39a494e50c3050dbab27a52db6572ba78b6913e9b"): true, + common.HexToHash("0x5da2dec14436dd2f252dce90a49c97bada98bbdf24f7871700434945cb73bb47"): true, + common.HexToHash("0x3672d5a879fa40a174c01390296e48af5335ff56b3cecfba05ea95a3874f6a9c"): true, + common.HexToHash("0xac7058c047028d875fdd1f2be114c8cf20c0cf5000f699b5fc254ee16c820953"): true, + common.HexToHash("0x5339881d3663c916f2bf2e7ce3603044d16ef917fd4e9c449ce9634947619042"): true, + common.HexToHash("0x83012d45246de55d6a9efa07621fd966758f4db306a6ca7a48aa4d6c332df321"): true, + common.HexToHash("0x5f10874d3ab4e81e0b9bfc1332294277a99364091384f24e8a40fc0374e9557c"): true, + common.HexToHash("0x19b246e8a4ae72ae7a8e5c8e8b33dcdae49364b421acfe6d7b332b53f6ae6f87"): true, + common.HexToHash("0x3f1bfa70334fa2eebe50ba6e44d245aa3038e3c4c07dffba06d3b956524ccc99"): true, + common.HexToHash("0x32e976cd5591755930246d322acf0a78ce6f5cee2fc25c13851c0cc2a75cf7ac"): true, + common.HexToHash("0x3cbd0dbc4e773b6eb47732967836da0de35a9ffb25486430f44be6825b5d5d97"): true, + common.HexToHash("0xdcea96ce0ea59bf9be13c67cfb6cbacaad548360b0efd29d69291df44ba0870e"): true, + common.HexToHash("0x235fc84e74b3e6471a6eaf163c79bdccc4698cc9f30f1eab23e83b70dbf435f4"): true, + common.HexToHash("0x721c91969c935b101b72e2e4d0c29135239fd4211acd51e5fb928b84f943b22f"): true, + common.HexToHash("0x9ff8700fb4479147ec6103d7b3934783089eecf5ba51b47590649af2c1668b9c"): true, + common.HexToHash("0x2eaf090b4529d7c810a0cc1bee34332a56b3448155c995f0ef4add25d0f7e54d"): true, + common.HexToHash("0x45a4b48c2e9841c8de7eb2e41b434d73552e33b5fe55ccc657eed1200c9ecc69"): true, + common.HexToHash("0x1810749c44869c326636892446a2d14b3289e37baa425696c3b4e4843fc84400"): true, + common.HexToHash("0x4bb54fc92b95ff9cf63998e6c59c824ca6aaec1db72e3ac4ed40ce905dd298a1"): true, + common.HexToHash("0x737e3be8aea49d7bb01b8fb53bf3b6bf04985936891fb9d8abb16b62d3fb1ed3"): true, + common.HexToHash("0xe224d29929657fe92ce8c2e577d1aecd7e29a2c18c64a3763d9106186183e78b"): true, + common.HexToHash("0x148e3755706a77fcc6eb6f7621ca1b2814ad3078ad77af2a3791bf0c539d34b3"): true, + common.HexToHash("0x42f1f5c5658757dd22dc2112ad602b148a9c1d42a0b21fd3ae315989919e1d4d"): true, + common.HexToHash("0xa861896376a658493716e4e532441c529e68ac425feede0da22c154af7facae7"): true, + common.HexToHash("0xb461321da2136b49a1a79034ac2eab30f1089709e4356b9502f12b697617ab88"): true, + common.HexToHash("0x245b9d1bfd49afb65f22f8cca10ea1f180d46f51f7600562c6639d7bc064b214"): true, + common.HexToHash("0x4d4631fa72f5a12943769f4b1c91654a931ebbce6c4b3dd8f259b92d0b420ad6"): true, + common.HexToHash("0x9b021967a8f640bcdf673c131aa69375f239a11f5b453fb21bd0336baccc9abb"): true, + common.HexToHash("0x94bb9371c38ea4fb0d9c90281e0ceea74b916e3f391879d41c7fb1c313a11f9b"): true, + common.HexToHash("0xe71a1b3501a2d1a1659722893beb07a0a2e8286ce2505b3292d1dea6f74d567c"): true, + common.HexToHash("0xefc27700b89e419d3806879990f25ad4cffbbdffa6b116622e2245b31a90913d"): true, + common.HexToHash("0x9aed389ae4385eb1367f3e8db9491ca8efb826f7bf7846ac6520b6579b0d5658"): true, + common.HexToHash("0xb18c44e04a6bb7988562b28ae813c841d7fd3f836a7db589af0fa5b273f554d1"): true, + common.HexToHash("0xdebf52d2ccf9efbc507986c6d94c07336de38680e3e751fe1df13b628ed10470"): true, + common.HexToHash("0x972e2a5118068a4aedb23869bd40c18aae70b9119f81fcbfcd932cdc3c5288bb"): true, + common.HexToHash("0xf27c3e3fdf116088fc9ea113216ee35dc732fa95ca3b47cb67abd2e578f94f0e"): true, + common.HexToHash("0xaa72a21ec295f04a2f5872a96caf39583503649a35e52e1865a4279facd9f5a6"): true, + common.HexToHash("0x09c70010a500a30a51ecb470382d953a17432728e05e0ae65e57cbe85f260cd7"): true, + common.HexToHash("0xd11a46f74ccf7e5d81663afa16a67ef910cba648fb53385a5491e760b7200e81"): true, + common.HexToHash("0xae57abd17efa824e4ef0b54eae586e1f3ac7ae2dbecd76b0d3a81fe39906e8c0"): true, + common.HexToHash("0x6e58e3b2dd0e657f570474794cbe0c587ee4bcee166fb4d9f97ceffd21a2767a"): true, + common.HexToHash("0x64b361231642c7e488ca287f93c4588c10aaae14990dc055a055314600ebfa8d"): true, + common.HexToHash("0xbb9d0f577e95a788549506dd691151213014b2600a1ce3d0a14da1ff88ca0e61"): true, + common.HexToHash("0x7cc538b0f6e977a095e18874a6e03a7e574f684626103d1cf0ea86cb1fd57354"): true, + common.HexToHash("0x4406653cca985b2a535c58e1e28298bf4d6ca279d64916752c1863689c9072eb"): true, + common.HexToHash("0xdda6bf02d38e91c49434de434447ba0b0ecf12eb4528d7290c033ef3346cc67f"): true, + common.HexToHash("0xc8f5973f5e643dafbfab857337ba052e121d1fecc67c6bec3fce409d22ed1901"): true, + common.HexToHash("0x4baf62623dd54fe2221294f5d990aea45d10d6c54f06b154c2adeeea3285326d"): true, + common.HexToHash("0x4555fd3fb3292fe3e08969765d5670fecaa3de0b4e4ad5bb47bff1dcba192755"): true, + common.HexToHash("0x7f7e559b9f0a1a971886940b3587826da4dc9afa76b993d32585437e84d198c7"): true, + common.HexToHash("0x115740075b0aeeccb3b7539436c85a758267e55a48ea53bd7dbb71bda730b414"): true, + common.HexToHash("0xea37c68d79fd717259b2963706b2d8e69107119a247cfb4c509200fb0f302758"): true, + common.HexToHash("0xd3dbee2d8100ef87b73b51eab37f5adb895f4370571946f6a4b20203832aced9"): true, + common.HexToHash("0x4d776029780bee92eb27d8ade285fa420e8133e9bf4c8fc525cea64161f24b0f"): true, + common.HexToHash("0x0e7354593e57c1776295aca0130166d93fca3a3e1cb23ba05c4b6daf01ea2f21"): true, + common.HexToHash("0xcac0ce65936f5d3544bd2bac5a5dea293824f540d280c71acf319d122b25d0d0"): true, + common.HexToHash("0xf820f348c9ddb20fb1d9515ac5fdfa4132f963dfaa36deb82da6f6b48f67cc2c"): true, + common.HexToHash("0x1981a3f4108a60e3a0ceb8e2ff06512203a96498538dabae79306f9411426331"): true, + common.HexToHash("0x4ca30870f2754c7ffca2ba8395f67afed59bb0577f05d5b81f36132d82cdb8c0"): true, + common.HexToHash("0x075e00e23c8de423e9dd6f72d045d447f7a48b236e34cb5cfc237c4690616d01"): true, + common.HexToHash("0xa1a6fad70559a721161ee4ea71373f73559fd4c77e27d8a8a9bf43d6ee1c74d3"): true, + common.HexToHash("0x265c50d96ab68cbcbe3c53f27ec26567102f404808d6ad8bd4c9307f75842060"): true, + common.HexToHash("0x6416eec9979bbfc447e2b05ef8a4b89e330d5e7132e6de90cd85b63ed37a560b"): true, + common.HexToHash("0x8d2d65dc9819e085c5c3825250311e0d509538364b71d08de31e564b2ac4cf23"): true, + common.HexToHash("0xbe83e5d234a32228eb4d002da2e7d63f4c4cb1a9d1b132301ee5f6ba581c18da"): true, + common.HexToHash("0xa443e5ae1bc3d100c53b21315b04a6dbc0575759cfbb6598541fdcfb105f4bf1"): true, + common.HexToHash("0x3a1f0147840e998c3c377560ba590e6c7f97d35473de4e0f3991a182baa23756"): true, + common.HexToHash("0x1735f067a02c16d3da09adc64a50bdabce3fcd245b9cbc930fb5d44a8637e5ca"): true, + common.HexToHash("0x8f23f004bd21e59d7b61b96ab7c38ef08907a1550536030a91e2e66d007ecaf6"): true, + common.HexToHash("0xecfaf3816c8c9d4df53705aba5ab604b63ff58329a0c8045020a8891e5c31f61"): true, + common.HexToHash("0x7f2fb650782272ee8f3bf14686fbf1628d996a8c2ccad693f637055a60dc4cc5"): true, + common.HexToHash("0x4fe03eb0ea5bb14aed06f7b3e84b3dc8bc928322c68cc5368df69bae07c28915"): true, + common.HexToHash("0x1d21a249cd3dc6fc7daad7c6a76701d74b288ba39127201b98dea889411e81c6"): true, + common.HexToHash("0xcff2b696296993c42f20259ad4e5f3cb34f5f0d4c8e9da6eb4faef553387879f"): true, + common.HexToHash("0x523f02ca286f1a09bfa3dd1080b3545ec726e2e5d1142f5ec0409a996cff47ee"): true, + common.HexToHash("0xc3c6c8f5b2c5588986f1603110bb9664a7fcf3f0765d842dd0f811385f584206"): true, + common.HexToHash("0x918afd8654bee4d971ef8462bebdb88038d20884769b9eb579ac22a83a7bb182"): true, + common.HexToHash("0x81f260ac25a3f8833975f94948aa0e236e8e45a690ef732146f611bba302b72b"): true, + common.HexToHash("0xb8b95255188054819c1285729546eb42aab549c4d87f6936bc9f20ff2b804bee"): true, + common.HexToHash("0x1cc2e5f06a03d879d11a3f1a1eea4c3641ca4613a66c174b7af499adb58383f6"): true, + common.HexToHash("0x69bd97961af6169e8e661fa565274b40a31a3fe22a33d03da75df76146d02285"): true, + common.HexToHash("0xe7605356c21effbf89a3ec4b57bb8a604729981f4be690ec82ed0c81ef9568fa"): true, + common.HexToHash("0xcbe1312e18ea87bdef7f64578bcb2ff0780729298167de10202d7842f479ff55"): true, + common.HexToHash("0x9f4c05a5efde94a745f4e0dd8df3707b985ac691cef716831828571c3193718e"): true, + common.HexToHash("0xc45e7d1c98fb410754e135dba05cbf0c88721349ba6ec52293a33293de0cad05"): true, + common.HexToHash("0x4cdfb6da0710d42a923b38ae8bd2e12a798f91345af8e98f6233ae953c44edce"): true, + common.HexToHash("0x06ed6af0cc8b99e926c52146d38ec6b085f641250c6dd477f0f7d4b9047c9dda"): true, + common.HexToHash("0x453eb64a827888152483d53f39af27147483412af3653814b07079149ba7877c"): true, + common.HexToHash("0x362ffbb689541a8dbc0952537f41582e2bcad89d31149f69a40823f34c101fec"): true, + common.HexToHash("0x53c8da3f8918cb10e98cf5977eb723a48044fe171269a80eed892e3856da376a"): true, + common.HexToHash("0xbde8576af087361819e0b0c1ce934791c77ec89390596e683e7f971280fa26e1"): true, + common.HexToHash("0x510f40c82c93b18e96935fb2c55798506579d6f587d1b10ed3b2e0f16baf6789"): true, + common.HexToHash("0x82c655a68878d94c49daddcbead50e5fcb729ee400e3859f232120e6dde2269d"): true, + common.HexToHash("0x09f74ce68e8039fa66d48a87faf18bcbf8b78b5b26caf550b1f3b5b50e14f9b6"): true, + common.HexToHash("0x37ffcfc27f6d753d2481e17f41fd182147505c9a58576971123786f65cef04d8"): true, + common.HexToHash("0xc2e66b0b243db41e88c58d7559b0174fe9c77f741621b7e8f34b6318f9af61b2"): true, + common.HexToHash("0xabfa5428d6d5d585b965362005bbd75594146f82b0a8df08b8db8436089695eb"): true, + common.HexToHash("0x092a8e5e03f15e949f721b043607ab2cf97a9bc8cbf2631360414a3d091594d2"): true, + common.HexToHash("0x4a27e79d5bfbaecb7014f5a13ed087f7fb2e3b30513d32a83cd27c5002e9c684"): true, + common.HexToHash("0xb7feac35b09ad8347386617c51f539e105358b8da1e56170f5ef311125eddfde"): true, + common.HexToHash("0xd81cf85a34147ee89ace37a76d6ff457f15c6ac1b4f0ea3895818a26c62b13ba"): true, + common.HexToHash("0xc877757e8fc392c0b72b7a649431c5388bad61e510e885ed81c11ab86c8c67d7"): true, + common.HexToHash("0xb27f4cdead4a4e4ca8791aa9499968e35d1da78b3000d3e062aedeb79fc6e42b"): true, + common.HexToHash("0x4ad42a9d57e7344b6686c804854b8400a40d3cfe42736d60c86d62ed10812614"): true, + common.HexToHash("0x65565970637642499fe9cf12b263db0585e78b56e18541760b5b9c058325d4c7"): true, + common.HexToHash("0xe5c3b61cc4097e2ba827d96ef99a94fa7c2d07af3fe22a77d21e82e1e1bb82de"): true, + common.HexToHash("0xb1d3887eaf6fb75a5fab527c278e8d8320b142cebb456186a1addcfa738748ae"): true, + common.HexToHash("0xf6cb6062f99d0e0153971c0f1e47bdf23cfcac007cbb1458db7d11e12b1ebafd"): true, + common.HexToHash("0xb3d75b794db28ca255f3d0fa3bce0c3cd2987746e4d49672f8455bb09d76290b"): true, + common.HexToHash("0x84ad83cce220c084ebc26b7dea8a824647b307ebd79276b145fadfb6c8ceb81f"): true, + common.HexToHash("0xa9f52cd9368aefc06160a26e5a761d653343c2b0434f236d316f682a705fb379"): true, + common.HexToHash("0xfca2843ffe811c626154ee8a9cd494c66589957371ce3eb6387ae9831e9aecaa"): true, + common.HexToHash("0x992ece33ab4e26db4782cddd53a5d48ee654f9cd39b057c64a516735a8165a56"): true, + common.HexToHash("0x2850bd587dd0267f0f590baece7bb89425b612537d724470339a8a5484eb4c28"): true, + common.HexToHash("0xf884b0fdce549490e50b531aa31c58bd0a2e1b3322fe3c13e8d38bedb7825733"): true, + common.HexToHash("0x270573077dcf1f7bc1e155823818c21d86697a0360d493b52e84dd67a1ef7cd9"): true, + common.HexToHash("0x7bcf47b0cb058512b40b69302b4d3b9f615cd28e6792172e0c09d918604b8a81"): true, + common.HexToHash("0x9361eaeef2b0bfe1764a7399cefaa1ee82c39da52cb9235162a6f5251afc59a2"): true, + common.HexToHash("0xf2c0ab72559bc38fdd21503784ed29bc851f124d2d7d1c225b757faefb037e76"): true, + common.HexToHash("0x41f76522173d9986a4c686cd795e9ed6a82723f154340373ba8679421c3754bd"): true, + common.HexToHash("0x4c3fe471e005366923c51c5d1063aebfe56beee5a0475fee84808a18fb61e88e"): true, + common.HexToHash("0xbc9bd2c7dcea7c0ae9584681664b8f9a0420aaffc6ad9817022acb8ed0179c9b"): true, + common.HexToHash("0x7944729f1f20e41855f23eb7b63ba878ac1ce8c3ee24d589a6a3edbb106aed79"): true, + common.HexToHash("0xae198f2277192dd24543ff26570d55a41d664066a40d000e96af8da2e3bc4fc7"): true, + common.HexToHash("0x6b0af8cc89c3068384f5bba5b7c60c234b9df8992ef973c61adadd2e24d1b4dd"): true, + common.HexToHash("0x85a112167a77c1908e82d94f9792c15bbfac625cffd088ecaf36bc17b3f7f5a5"): true, + common.HexToHash("0xcfe3ff0bce996d3a28cb310fc6eb2f2c568af54d1174dedc95996b663625254b"): true, + common.HexToHash("0xb3d06844c6daa8e63b86bd6bd30a36cc55ba5f579c2f28c22b5884a644eea858"): true, + common.HexToHash("0xc39b86ffe66888b8cc388fc7e197d75e18cd276bbcc613d15c1b8346bbbfe875"): true, + common.HexToHash("0x7489a750c9f208a1237a2308b453f16a21f3d1b54181e4bbff1fba6a87fc682d"): true, + common.HexToHash("0x0d98a6ff5da19c7ba25dc7cc014b329f97599376f9196b79134e73bc7b5e0a63"): true, + common.HexToHash("0x43e29ad0a418107cb9cd9cc7b914897f20bb0a5ca19eae10d1e4d0d279359ab5"): true, + common.HexToHash("0x8f70373a17ff4326c1d2b3d03a40f73288f006371369dd7edbd123dd4ccbd166"): true, + common.HexToHash("0x85e0d5cea38bef2b5495f617e890800cfee2ca1b14df1eeba1bb741079dcafd1"): true, + common.HexToHash("0x389bf45d5b694a9035f16b17ff34761126a5256fb8a29968612ee897cf9e4495"): true, + common.HexToHash("0x91b2514c0e48c6942b45ae8a8f986afefef3f23a5b04ba9a183a037be524cb7a"): true, + common.HexToHash("0x1c17fb3ff564e81dfa76928236415395c5ca377eee3bdae1f4e0af00d5b9b45e"): true, + common.HexToHash("0xb1097ec490bc20d6425b524f7a45f882df8fc757e2ec06a8bf3d73b0ee70e9d1"): true, + common.HexToHash("0x1ec08b8dbb120a5c950af39565c0dceec6bcf36cd1d4ab509356bb48ac6ef24c"): true, + common.HexToHash("0x7a74a58b5f37e917ae71ceb06a9d60d0ebd8e268de04f4e6e4dc9c733dc0bbb6"): true, + common.HexToHash("0xa8047bed8ec55762a40ba56343868f4ad760208c11e51125ff157c8389ba10f9"): true, + common.HexToHash("0x85f65cc6920b48f3e7a6fc5e44c2cfc2d557ac101658b9b8615eede6778d45aa"): true, + common.HexToHash("0xa61769977d0cc097f25f538665f55309eedb833849e22dc07c763afa34f9cb84"): true, + common.HexToHash("0x469317ec5497f27d488bb96be799da6c7a3bb30b35ae32657c568633ab1ec8a0"): true, + common.HexToHash("0xdb2618634dc8e5d22b795f39cd1ac8fddad8d964720013f357ea05e08cea2357"): true, + common.HexToHash("0xf5289a69286343cbe0b2852e2d34694b8d69918fe6d4648315ff2010056b2097"): true, + common.HexToHash("0xb7b2c66e2a2d9b51c610ed04ed69e21e55fdf0fb32cb9f0d336fd8a56112cf8d"): true, + common.HexToHash("0x85b33b43afe2661d9a47ae8bd0f4896c2d5ea0ddd90c65b50f735fd19febec55"): true, + common.HexToHash("0xe71df636265854ecf77227f9a80079072be09871807af592ce2ba54f1f109301"): true, + common.HexToHash("0xe0e087356f2bffd8c96aa34f08eb135cc86ac5bd73db553cc8ab9452c2d57bad"): true, + common.HexToHash("0x73656319d992f674b9e4305c7b245d3458077ac6c4e1c15ba8557cea6d23eb2e"): true, + common.HexToHash("0xd75352aaf43e07fecdb6530838619b7ec5aca05aea4f223153c8e05b8761aa3b"): true, + common.HexToHash("0x6e1b6627e869f42146a342a346108f4fc7cce886e866f05f8c2df8aa6683248f"): true, + common.HexToHash("0x9a65b2c13601e46af120e20ba2e6bfa9b2baf5451253530922fb52f3714ed197"): true, + common.HexToHash("0x135e7851a8444c1e2b0b69b8556ac21c4a942232eae24163972ffde51fb672e9"): true, + common.HexToHash("0xa2c26ea2d6776c5a88e5d1556dda9e0b028f24d24b19cf5a03d60a79ed626f68"): true, + common.HexToHash("0x26117195484e61d1d3c09458b0b14bbd42b29212cc4c85247410a010803c987f"): true, + common.HexToHash("0x7720822f670f3753f73b70c50e392e8a7a97535de81bd8df77748edf95018e0c"): true, + common.HexToHash("0xc3cfd880cfb906eae739766c075bd7fce2144bf2650629ab77c7c9b9cde03486"): true, + common.HexToHash("0x5decfe096e25cdc840fca23f3a88ba2055c2e9b74330f435bd311650b5c428ca"): true, + common.HexToHash("0xfdb5305238e862d3b023d67172d72e17498aca43f5f05b802765a460a02bfc05"): true, + common.HexToHash("0xc17229d0ec4e4cfadd7126c4475eb278a78d0302722c14d27ddf49ef56750b1e"): true, + common.HexToHash("0xe81bbd08d4309806fca357f95c7abebeba566e073b75a4ccb72bc55218892719"): true, + common.HexToHash("0xecaf0ba188648247549dada640d9d216f22ce86583fe5e3f585867c0a3f1da68"): true, + common.HexToHash("0xd6d42d37faad240d2e631b208459e9780bdc00501c795551c2aea7b774804baa"): true, + common.HexToHash("0x45272b469b932330b439c43060fb68c5ee54007520cf0360c450bc9d8db54bd1"): true, + common.HexToHash("0x61403542e28827a4667fe210769129735ccb6b27a35c6bd7a28e65f7ae09e7e2"): true, + common.HexToHash("0x47a2595e730df81d7b52f46284ef429138bf688214970ddcbe6ef5e1bbf3b389"): true, + common.HexToHash("0x37b7c9d67477919ed0e1284970ff4be8a517ac71a543e04da8d2d4740959550e"): true, + common.HexToHash("0x9568c1b3d324a766f7445077b82019bc5ed0d794cba7b3a072da9def77e6b51d"): true, + common.HexToHash("0x56976c59ea237922f05e0eaf3cf92bd6f79aa77927438bac597c9a51a6361252"): true, + common.HexToHash("0x4de283e10e26aa0d33287857c634691360c8d48e2dfa25677f53c6da64a5fa42"): true, + common.HexToHash("0x74b1325862bcdfa56e37c422366fcd4c493fb6095a1d2208c54e82441a64d59e"): true, + common.HexToHash("0xba30c20ef966c6fbc99cf818c6b9462edefb96079adc896e82f5dbdd81676f02"): true, + common.HexToHash("0x3af898333edf38f9c4205e98da8015ddbbb89698fcbd34b461521b70427196aa"): true, + common.HexToHash("0x8230a01f3a52a206dd3e40663e2d2be7d10d7041e246b9431dec2c99c5080431"): true, + common.HexToHash("0x6bff8faf2490e6c7c966a2c1dc2854a2f91a3bfab4d27bd59c080c7673ea4710"): true, + common.HexToHash("0xa8f0149dec0113207a9d4cfc4a226e0f6428721f655e69d25de34933510ae500"): true, + common.HexToHash("0x754e150aa240f1427cf17d2494d8f84543ea3ad896dd09c3f812f3607f33aa49"): true, + common.HexToHash("0x5dd041d9ee016d6c3745b98807a4e3ca4a41aa0ad46c68cb43d46f8c8411ca70"): true, + common.HexToHash("0x4a80ba90ba1314214bd307a4a66e7c41b92592372dec92bb607eb504fe8eccbd"): true, + common.HexToHash("0x1d2c374cae0a5f442f7b5705642227a656ab4eb7af968c7cb7c7a3bba8291404"): true, + common.HexToHash("0xb39841d402bda0dc730c2e873b93a74d0869ba008c92843a22222b6a5483ebc0"): true, + common.HexToHash("0x86a5eb4ee4570d307f452baf4509cf441ddbb139520b65b11912faea94b613bf"): true, + common.HexToHash("0x1c0e638988a2f79a6f76b0a161e3e3f68092882703ba7e214ad6c64b6f585501"): true, + common.HexToHash("0x4d0ba215964dbbdced79bb13e74c57b6a6af32d3315501a8177221f1889fad4e"): true, + common.HexToHash("0x3311ea8029617399a367a2c23320308a1e88c3f0e56ed53cd3286070f30e2a51"): true, + common.HexToHash("0x6f130f13e7b892741b610d713ff58b6868348770bdf981f9028654e4e1984d14"): true, + common.HexToHash("0xc8b3b9a5026c796ddd919059cff45d430efdaf2252463dcd55ab3368ab333ea7"): true, + common.HexToHash("0xfd4a93281fe0e2a7988991a07d5b0bfb468ce06a78ef54eb90db7b5a829783df"): true, + common.HexToHash("0x004e2e34b2146304d97f79d4338ca010df73d89f7d032fa865d7e52d1981ce0a"): true, + common.HexToHash("0x747ebd39008a6bb9b07f7b63aaf127353641e8b1ae00f80090d7c5c4e928dd57"): true, + common.HexToHash("0x33e1f84d64fc5cb1e7205abd2ef74320f28a49225cead3d105650352bb4bb5f0"): true, + common.HexToHash("0xb6c415dfb794a4fc18abb1f30749fc5516658dac953098c0d5d268e9f6df30cc"): true, + common.HexToHash("0x57d9c333fd9cc066998610bdfa7dfc35d01f5df8be717e7efa1502a455781be9"): true, + common.HexToHash("0x0dd7302159861b43eb69f83a4081c05ddf4ee35fc1522184d35e43a65bf17dbe"): true, + common.HexToHash("0x2d1c5c9b14caa535eb86d91a55f2af2e1a8263f32db628d0614e86156254480e"): true, + common.HexToHash("0xa69bac8f73cfba3fa252f3353dbded8e8d86ea7eece6f9e00613fe366aec76ae"): true, + common.HexToHash("0xc03ca9ded3477d51db07535e3e1123bcfd54d41e2568aed445e4763f6651fa55"): true, + common.HexToHash("0x09a2871eca35a6c5997c457e2b170ee1bd40c0aadd8c1d4e7c5de99b7b0dd853"): true, + common.HexToHash("0xceb988d910266e49debfca652fd858cde9680dfc6e11a82b793b4b9cbf4c6945"): true, + common.HexToHash("0x0c584b1d7003cd9a24bf2144caf2145665402b6b9586468afb2a5219fac4c2a8"): true, + common.HexToHash("0xf6bc85e077c5ac57438b1542a37d98a13bfcb583a66ff22febb6d5dc3da18cdf"): true, + common.HexToHash("0x0175443e4a62738eefec8520bb6be672f8980769759e8fc310e72c8f48ae46dc"): true, + common.HexToHash("0x9ec68b659a85d0442856165310725d69cdc956dac5b0c2e7b5bb79bec239a037"): true, + common.HexToHash("0x57b5cf5d52d9c9f6d777f65646f13f08a106fbe6bf66648f08b170d2e1f720d9"): true, + common.HexToHash("0x8cd995440509bc6a0a7791b671164741c9450aca814e71c380574eb954bd7f2e"): true, + common.HexToHash("0x1c130e95df1e026db15175b85ebf01755a72a5ed7f35edee9c5916d8e27ae1bc"): true, + common.HexToHash("0xd9fba5ed218445493f5f6b9ac3503ee7313a764e10e832326b5c5681456b5765"): true, + common.HexToHash("0x1500fb0752f4bed7a6be1fc2149d4ca219eb1ac52832e998cc0efc28272ab5d0"): true, + common.HexToHash("0xa6f4f625ed0305be28f40181abaae9540cc2c4b3102e0767ed946af1b69fc0ca"): true, + common.HexToHash("0xb6630815302cacbb91f12aefdc017f503144b3f56d0dd9b0d9d51a6b891745d3"): true, + common.HexToHash("0x90b42cf08d01c6191057ba45910830837e55f1f59a1687d288a14603b5aef238"): true, + common.HexToHash("0xe37d6ecdf60bf00ed7c30d9b97a3ba43a38876147b7d47f6c753eaaa4dc11413"): true, + common.HexToHash("0x2b345534d2d2ba71d2525f11eff148e9293a4807e3d3427fa078ca09e209cd63"): true, + common.HexToHash("0xfbdcec9d1c4d7851809317da57e7ff1456d7baff4fc6a99001b7560d061e1574"): true, + common.HexToHash("0x9708a361806e3e1cb38d4165c5293d525c98bafaffcd0b76bee04b5f48cf1c14"): true, + common.HexToHash("0x43d96e69f39fa8af4309a5bca582fc2409fcb8140104b02439eab23e3a08875d"): true, + common.HexToHash("0x32f200bf95455ed29dc4b9ff27d04957d3c5faa3a75601740bf75e11388ffb03"): true, + common.HexToHash("0xcce03a5c703fec6a4719e9eccdeb4a6ba66a5e71f928c5f6842f0b099fa906b0"): true, + common.HexToHash("0xf7295f5c3a27b6c5e1e40a0ff6e7264e073c929b4fdf5fd9f135247a77de2031"): true, + common.HexToHash("0x569e2d35712c05709b32e043279e9f0ff76bcfbfaaef16ae45944a90d0383ed9"): true, + common.HexToHash("0x17b622b863b13c9c07a646ba9e7389505c9d68d597118a295681ae73fc8c894f"): true, + common.HexToHash("0x12a8ae11126a68afc056cbabadc80273057e4190dc41e915febc88e7f488f451"): true, + common.HexToHash("0x5df3f7f6f04e7d1253e54c84b9b04cb31786d9715e350361c032b85d0f140fd3"): true, + common.HexToHash("0x513005de98835d60fdd55aa60d66752dcfe4b2607ce70e2564e97829f3ebc06a"): true, + common.HexToHash("0xb49d82cf8573f155868893464f415797712f927c602748f5f52ff179c218cbee"): true, + common.HexToHash("0xc43a4ba8ea4bb122f028b3a1be6ce0881d1302e701723bcb5876b3650144a32d"): true, + common.HexToHash("0x9c0aee77443f2a662cc9adcc740e22e582ff4e835e494877f86b9e6d4066f980"): true, + common.HexToHash("0x981e250209bcef5383103a7422954a9bf4053363c1f066457113ab45783ca667"): true, + common.HexToHash("0x8a55b28cff2654fdb99b263f75a591db566f0e5e7ede818f3e83b0df64a6b776"): true, + common.HexToHash("0xc8146bad90561b4fa743382aa3479ac1b743bc4c62153eba8a939efcc8ca4af8"): true, + common.HexToHash("0xcdceeba27d90d3a9c731bed783c39eb7e99fd38da223d274e2778465ed14864b"): true, + common.HexToHash("0xaf113d357b9247a78f5a3ee5715dc21c7cbca5f386076458f123a19c0c2839a8"): true, + common.HexToHash("0x9776cf3718d8c972e5509b8d5524ec67706b5fc01759edc529f7fbe1455bec45"): true, + common.HexToHash("0x9b1e3c8dce03af8b1cb1037b5ceea4c498f3ec43b9029a047057305f58970690"): true, + common.HexToHash("0xb6a82a23d43c909d4fee24fbf948b1930382f13f4e7e851809e1f5549f8947f0"): true, + common.HexToHash("0xaa8443e012cadfab190150e7ce059dee7a1ad6c2a1b0a44c89f762856147692d"): true, + common.HexToHash("0x93f956fea4305a2e69c02406111d7f5d1f5bb82332f1e7608f9dfc379d6d7892"): true, + common.HexToHash("0xad359645e86301053cfe7ff9472b82b517530cd4900847f10cd8c5c312a74742"): true, + common.HexToHash("0x0990314503384473aa568cf2ac90d79006d6b417534e6dc9b5e0dcfca82fffa8"): true, + common.HexToHash("0x5ee9be518a130193322b92cdc39096f7006892df5afc619d2258c9f4ad83df3c"): true, + common.HexToHash("0x73ab73fb14078b4c7aae9d81e609c837956c3bdfd5e3649c47df32d7903b4647"): true, + common.HexToHash("0xe64602bd6979d50a9ed9bddc54cb44141df3bb69aec0c2398882e0f8a7677b86"): true, + common.HexToHash("0x92d5c0b8e47b10cd9d8420fa6cbcb2c4e064f64d15074aaec678c04661864396"): true, + common.HexToHash("0x16e206432aaa90f67ef81d0edfd63022fe602b2e63a20032d9a21c4d5b1a1531"): true, + common.HexToHash("0xcc081cb6ef4333c37f90a286e51be342b40fabf52668c5bb4933c53ece10136e"): true, + common.HexToHash("0x18dfa978eff65ddd4e2eb7da6075bc4d53d6cab395e5bb0ed69be9f1a8cdf885"): true, + common.HexToHash("0x8fce1866dd5cf92ad2647d03843c7591490e765d8f2355a2faa229f113c99887"): true, + common.HexToHash("0x94b819859035de6192715c24443baa1ec33566d245c5ad4aea554e36cf391307"): true, + common.HexToHash("0x6edef1666d728b2156062d7c2a35cb1002683b6d53c29b60a111983273835d05"): true, + common.HexToHash("0xc9dfb5798cfd0232a90266985e44703cab6a2936274d018a8c932cc804ccf7bd"): true, + common.HexToHash("0x4dbcd86f67a84b3307a6f16e350a58ef53a92c3054ab225ae630e00bd0ed57cf"): true, + common.HexToHash("0xe563e1b39aad9b3ac05566fbe43f66220fccf09fb88f1cf9e4c790195b7e7fbd"): true, + common.HexToHash("0x76ee1692c5050a0ee8eb27217b001eb50f6b9b412fbf2d4777e8e4a2f3b9cdc0"): true, + common.HexToHash("0x376c335dabf11481455e715c571f6b344cd15df2297ca2e479a92dff8e83e680"): true, + common.HexToHash("0xfbae8f8804053f9e18bb8d5328dd7b06916817f8d22a910b22bfb05432a66be1"): true, + common.HexToHash("0x908597683ed2e55ac2dcfa3f3a68dc9d0b1717cf4bfb98dc9c450b2ea91a02d9"): true, + common.HexToHash("0x18649986fdc59d495b703f88c3fd38dbf819169a1d3f87959039edc290dd4050"): true, + common.HexToHash("0x44d7b1d1fe17abe55c6bb906367186418127e77a05c310407e2293e9968571d1"): true, + common.HexToHash("0x0d257df3aa3efc9f5015abb6015ee042b67d5449c008bad79aed0a4031a97b0e"): true, + common.HexToHash("0x583beb32a6ed231f23edf3ab17530cddb1da7c05976f60dd8ea34a1f73c49da6"): true, + common.HexToHash("0xd77fa795a3cd09b8131f192636639921df6a629d03a0432107a46c6e2d47e2af"): true, + common.HexToHash("0xcb1301bf38a6a956710aa2a8c1a6482a96701a7432a36c07a8a59c21d6783594"): true, + common.HexToHash("0xc1bbf20b6c1b544abb33b41f5972f06760359b55f73438cfc9999513d6b2d618"): true, + common.HexToHash("0x34a7bdadc7e83fc7c47c7448779c0191df9b5c65bc8b4f8021859643091cf6e7"): true, + common.HexToHash("0x7911995f3f635d43356eb6842fc00f51bc703ff2278f607d13d405db404d09c7"): true, + common.HexToHash("0x199efe80f908c0b2deb6542c8ad351e6384802349d4e257564627f261aa1467c"): true, + common.HexToHash("0x77670d09186aa0ffb92dd118d0cf5b33e0f695b4fea02fcd035e7ba982436eca"): true, + common.HexToHash("0xa38151c711ee7d97e90b5b8ab811e309133627e4fb740faec9e79aa4cc59cd8d"): true, + common.HexToHash("0xcd52a8353e6e292b267209036f87f23b22d42ca8daf030427b1b9aa8ba7bbeb5"): true, + common.HexToHash("0x9cc114aac3e4082fb7cd1fa12d8bd2e247cf9fb5853537c1a52eebabcc496caa"): true, + common.HexToHash("0xef5dbf6d22773d84b2d71a255b34200d25fa8d49c98bd7270d637e07a25bae68"): true, + common.HexToHash("0xa13c1a654f73f7c29db60b192447d6caa31961846b2fcdeeaab6b403fe705dfb"): true, + common.HexToHash("0x1d062315a997b0bbe2647545ef7611cc567ca3390e08a9a600110fcb2a01ae25"): true, + common.HexToHash("0xdf9fe3c2476cf05cea57d1e8990315f83aa36e079bb4bebb8180c685346eb4da"): true, + common.HexToHash("0x3d95b54b820a13f684497754b8d95be1684bc2d3f7e8acec9c2a60a3fb9b970e"): true, + common.HexToHash("0xe26fcee2f1a6369f2486168a05c7f9dde2d262c697bf840fd40439f63f8b140f"): true, + common.HexToHash("0x934cc38493964a170ff3a28313e87fb670d139e49fe9d5242326b9e5e7d7966e"): true, + common.HexToHash("0xa7254da83314f06ccc3a9d5adf0170e96672da3af5e1a1b38a8b67ced0a4f398"): true, + common.HexToHash("0xebcf68797b1a1631d837636f827da5ed3edaa8b76e531fb467a0c50ec4832a96"): true, + common.HexToHash("0xfcbb94c253fe83a98b7e34c505e398fe3fde4e155946190240a6fb4903f7b48f"): true, + common.HexToHash("0x23ed18dfadd9b6afa7480ed409fe882554d3e04f02e1ec0838d663865f164ae3"): true, + common.HexToHash("0xe12864e28eaacd8f20afabe81ad436aa38e4f32a07d35c445e793f590b8f4266"): true, + common.HexToHash("0x11ebbc30241a79a7cc2ec5c203af6b1b9d100b2e739e00d3ab96505b13b823cf"): true, + common.HexToHash("0x58c0ddf9710b8bd26dbd532edf41e56c9cd787b32ffe33c430c35501efec012b"): true, + common.HexToHash("0x9199b63053532475d94c71b5c1a9d0a49ac797f4ef5825a28dd576accd2686fe"): true, + common.HexToHash("0x9bf52106588fdcaa69e325e4445716a6de5cc3476bb964d56979003a75b883dc"): true, + common.HexToHash("0xe1a1687ccb00a977309aa04befc0253db09feefec07ab9be4b63f80ac787b144"): true, + common.HexToHash("0xcf10e29cf4b4d0a3d76128a500889fe4096fc5cf29c38ef6c552e87b6cf74669"): true, + common.HexToHash("0x0f3be221b3355f48f5eec0e6a120861495416af47e61f6e82aeb918e24af95b8"): true, + common.HexToHash("0x7b6f94c4aefc31ade63eb2dcd020a51936adf99296efcbac745292454dbfa017"): true, + common.HexToHash("0xd732e775a3b7c78d200946138c5036c1f644dfd72de54a4d5f44c53bf2eba9fd"): true, + common.HexToHash("0x5f12226951a72135d7d86cdde37f2d0802bdf1148c31ab56000e300e96d02cd6"): true, + common.HexToHash("0x663e51fd3159c21919388ef7695f316034cbf2a1e6aaff3e6078d240c512b9fa"): true, + common.HexToHash("0x7180592f04e2e07bf22c18ccafab34ed4138c898052c8d1552103d9ff35ad8e0"): true, + common.HexToHash("0x78d3d53ef19cadcb78004e1daf48abb027cf717dcb952f8cef31e53eaea09e73"): true, + common.HexToHash("0x8ad61f6ce70accb8cc2d8890a8fe1388806790d73e35e937374b619e6effeb1a"): true, + common.HexToHash("0xcaf1e20f730b069cc1d4607ce6cfc73bf2adf6b79e85574dd247e674caceeecd"): true, + common.HexToHash("0x5a84501460d3de3331cdf80df9eadca9063e8b95eacadfcdbd4005d37bfa7bbe"): true, + common.HexToHash("0xdfc47d0d1ed761a3b069033fcc58bf76d852bdfcda39cb867d31406083f3c78d"): true, + common.HexToHash("0x5c433537f9743cb1f186c8d6c493888b3c2a58b9a1d0a2d121642a4590d7459e"): true, + common.HexToHash("0x62316a3d883bfcf73ed11d2dfa41bec15cdfc14011505d83d115402eeac8c583"): true, + common.HexToHash("0xd948fca863cede02bfc3a3648e1fed6afd08068d0375132ec6db3809b3b6d170"): true, + common.HexToHash("0x0768c4bf7a59b92d85235fef0b4d293795c1f0c5656ec07354d06e03fec4df86"): true, + common.HexToHash("0xe6da8518befb1d33f1f6d8b72e30228f8d1f321c117ab28b84c23a2b847e52c1"): true, + common.HexToHash("0x9084e236c45736fd2f4eb1e8aa2fc3c8a5903fc7f6460b993c475ec73a429879"): true, + common.HexToHash("0xd6128e0b6914382c045752c818e89ad33234d82a5c2be16730fd241d1563583a"): true, + common.HexToHash("0x371edf49a8a7b7be33da8b9aefaee59cc53b6a2484f1380edc825904de0f0d8a"): true, + common.HexToHash("0x244af6124aabc6cfca03edb37e22097b87cdcf1fea9c8d0de3c326230ef7f3aa"): true, + common.HexToHash("0x353046dd2ea54934dc4bdcdb332bfc4bffd89350cebf2eee53a2836c253be8e6"): true, + common.HexToHash("0x4dff198008dda8d08553794ebe14fe5888aa9d4bc937897cd271bfbd7950fe80"): true, + common.HexToHash("0xfe2987df0e3c20ae34dc509e0f390e7ee74a6dd9258c41d8c68957e03a84702d"): true, + common.HexToHash("0x46c05861fa3d2c0d57aa885cd1d397203c58cedb85719c34e4c61a8fd5ebe4e4"): true, + common.HexToHash("0x744d8819f4a8f252eaa820ecf45c8fd1ed6f72c30cfdf3aa673129e178f3787b"): true, + common.HexToHash("0x85a3c99f566c676721307f4cfaad782c91a67ee6680ae9b39e2ea4c56101a262"): true, + common.HexToHash("0xd396068f4a6fc868f9c20440bc28cb01a063a4458acdcd7e6d16612405829ba9"): true, + common.HexToHash("0x5271a7bfbe74b96b44941244c34bb8c691469644da621270462bdc97a6a7cac4"): true, + common.HexToHash("0xaf737f488844732905d3c57b668c21c67482db55b7b1eb4b8e7642b678369519"): true, + common.HexToHash("0x56731cf609d77b6e046730dac2bac51eeaf0c4ee8f459713f64db692046b8a4a"): true, + common.HexToHash("0x7821532169b19681982360948adab7e2d7eaed226d0fcd2e007ebfe2e4ddb1c0"): true, + common.HexToHash("0x7b945445c7470215ac6a365c8ca586bce4525d670914ad61f26c98073db9481c"): true, + common.HexToHash("0x054e8e397e9e6019220ae69d505cb0f3103adc0605ae8050d08fd0b46961c6d7"): true, + common.HexToHash("0xa6db64197841f343b4415d92e80de37340145cc86d808fc797d54e360ea3db90"): true, + common.HexToHash("0x894b39c351ef27e9cc5d2ff12fa68d07814d00ca8b7a41bf37053423d054955b"): true, + common.HexToHash("0x9e1e4678623f3b612df5c7fb67e078b10fccba9c62729ca8a8ac931397d4e337"): true, + common.HexToHash("0xf59d37775ec35b6cdbdc35dd063b34df820015798e2da38267625402754316f3"): true, + common.HexToHash("0x1f40fc40204fa105860686550be8a78cf590dfe7898b489a81a0589e02b65180"): true, + common.HexToHash("0x0790a14f5a8df320f3e28bc204ab53d6ffe1149caeeaf377494c07a6c9e677ef"): true, + common.HexToHash("0xcfc3941b1bf438a7e5d559e442771239dce5b16b163f27a10afe95ffdeca3cf0"): true, + common.HexToHash("0x2fc8bb00d795fe7140ced7b518ef17a10198edf453b515e51d76186d762bd520"): true, + common.HexToHash("0xc3a51bc3642e7ecfb905c383e828b8abb7a8c469addeb514573c9b4e4c32d871"): true, + common.HexToHash("0xcfb3d3ddc6660f36c6929433c2cdaf208dc1dc696195a01ddb00ec9c94b172d3"): true, + common.HexToHash("0xa1f2bcaf780f1e3a4d507b088690e673cb6a9eb091166c81d5780322a1136f99"): true, + common.HexToHash("0x327d52b9acde7528efc245d676896515499c67dae772b37647aae93e85fdae94"): true, + common.HexToHash("0xde32b02bf72d7525e7467685db48be1db38252678f4551bdf20f5ce136737945"): true, + common.HexToHash("0x136e188f4e4888657da2100d5b82c2241a2435e67a0fef89d9cb92b3b45970e0"): true, + common.HexToHash("0xed4e1c4ddb134b0c543fea241b1ed15f23d75073d79d3a4d432bd2a790bf06a8"): true, + common.HexToHash("0x0ad954729743f2167fecdb45e2c6f145054303379eb00614d4242ad884f7a8b6"): true, + common.HexToHash("0xc78d6b2f736f9848942f2bc7d88aa9f3113f7ba978708dca7d35ba5e1bdc91b7"): true, + common.HexToHash("0xcf3c14bed1cac9a116dffb5ec23e2bff1a9fb53289bf0bc3c0157efca284273d"): true, + common.HexToHash("0x0c9701737a76e13240b9c78e72366b9a52e55dd58bd9512951c80f8b944b2371"): true, + common.HexToHash("0xed1b8ec1863d46465786099004e46f3e8fddf37eb5c6607fabf07dec5804f968"): true, + common.HexToHash("0x6dc72c349abc0ae869e937065fa91fac09c5909d8b46a58f00a6bc23b3e7afda"): true, + common.HexToHash("0x7cf8d06df6a69b8778677c45eb4557733290f6c67ad1d63d3668db6fb90cc71e"): true, + common.HexToHash("0x577fafd6ce00206640772c8f92002bf1ae4ab9639b8a30b10ff4a2ee5c08cd15"): true, + common.HexToHash("0xe9c571fedf0c6f0a16f6e26e8e96e1beebe9410d4d0934834fab7686674a38a9"): true, + common.HexToHash("0x51abd5265d19fc9967cccdb788844dbd4aa99d354b53668ee9476bf2846920e3"): true, + common.HexToHash("0xafe6e0dc9ccebf8451a5eaf862447f13a0ff1db7c3d13d4d3a07161db4a5f5f8"): true, + common.HexToHash("0x23a9b219bfd06590eeffbc4c88ae3725442d71141f3bc592d18a6d2a21c1a948"): true, + common.HexToHash("0xae7677da1acf6fbae42a50bee8378873b7b31faeb521444487fe3ce8803edf2f"): true, + common.HexToHash("0x9e355e44da19a84cfccdabfb6bc4305295ae1ebef7647ab637f6ed826f4d49d5"): true, + common.HexToHash("0xa1362638039493983a6181baff57399813d25f6522d28e54565fe5be47d11a16"): true, + common.HexToHash("0xa3549b3bea8ade7ce1c3551de197303dc1d468a6603b6c227610d71545a95582"): true, + common.HexToHash("0x2575d08357d079089ecd8c29ea8814e5d3b0e47ae8d0deb69f377ce6f9873886"): true, + common.HexToHash("0x248f434be52b3117917d0d3273e10ca08d05cd7da72153c4ba760fa96b5d89e8"): true, + common.HexToHash("0x6d997612221933494189959c8b4fd450d733ee2ba4003451aec082f0110b44bb"): true, + common.HexToHash("0xa8410d2b9728c26cc6107cf485b90d9cac9c18982f4a224fb519b3406882d8e4"): true, + common.HexToHash("0xf34975e8080b48cc7a834395ae11703862743fe5255e5b62dbd3885f2c792a9a"): true, + common.HexToHash("0x4977bcbc9bea5495975e9553b8d3a2d28e229911fa898c57301e00942a76fad5"): true, + common.HexToHash("0x1e45150a651aa031c080f87389a7f2d1786051cad623773cce32185280359da5"): true, + common.HexToHash("0xbfe52b9393ce1d1fdefbe6567ec8a9223f13a8e4e3196d5cfba1262e24f63e1e"): true, + common.HexToHash("0x7f4651b120f8f46aa9c63c2cb2028c49403039f207228e21a654e9c79c2ecbf3"): true, + common.HexToHash("0x586719bc23d40a7ec43eeb81266ec784d2dc4df9151a154f88836ff285c8ebce"): true, + common.HexToHash("0xe60469631203b2e17662e5709fccaf08b927b6a3515b109de362fd97ffdb3637"): true, + common.HexToHash("0x4135dc76c2612d150b72a20d24a3e0b0982ec955fef1f68116f021cfbb027b2c"): true, + common.HexToHash("0xac040ec018a93858145792d7bc03bf0b9f78403409fe633ec337f096d92b94c4"): true, + common.HexToHash("0x40f152c95318efe4549ff51588976f9b8c6030b23a67172899a19b16e1fac972"): true, + common.HexToHash("0x979b1c2e39d5afecee20e0e0c49a9d2e2e993359ad07ef28cc9529972968af69"): true, + common.HexToHash("0x0f721ae468fb24bd13fd11f980ebe0b9c24a0d019eb210277fef0dd6e98a3e05"): true, + common.HexToHash("0x7d88dfc784185dbfeb11da4e8693aa0a6090f1d129bf472c48abda960de3c2c0"): true, + common.HexToHash("0x914eea684492b9c5692f47ade58836f7fa5bcca541afdb02f113b2a3ceb55b12"): true, + common.HexToHash("0xcaac9c9b58fcc0e0baffe7c4104228c1f74e086d630df7a25e236399c470634f"): true, + common.HexToHash("0x8a62033985ceb18b6f4c33d0e76444187df0c9bf96756854fd96883a5aa31370"): true, + common.HexToHash("0x79b0584f3fa349171714f5a34c8a886e15fee44f537e4075c6fc116a29c2e97c"): true, + common.HexToHash("0x5321a8948ae26ea99b559fe4f29a381e4962e50916db16de235e310333838275"): true, + common.HexToHash("0xac37676bfa3d0165bee708ed76efa5b20aa5f4546ae22a5f6a5a3bc940e1adb7"): true, + common.HexToHash("0x6dfbcfd913a4460e64395a492ec86ec5407009ed7b1a71371c3fc6c7e9effb9f"): true, + common.HexToHash("0x17c2b879f8b69c0f2bb34a59ed3fcfc0ea8d1a7e853bc142b3cb9b84166969e9"): true, + common.HexToHash("0x02f5602119f6e436c49dd40c42915692cd2a319774281cbe80e9ccb03e39ec95"): true, + common.HexToHash("0xd1749ce893a51a5cb654c67c58a0bd247e9dcf4b2bbe745291e1e3c941c6468d"): true, + common.HexToHash("0xfbc582fe11451001ae4ed85269cf2072179babfd348d030cf81b9000c8b67c22"): true, + common.HexToHash("0xcf05a4cad7c29eb082655f5b1209a74bbabfcc66fe1878c94824a36689beab6a"): true, + common.HexToHash("0x228e12c331f648c95db6c80c96080a7c399009da8670f286601d1a5f7f284bb6"): true, + common.HexToHash("0xfd097d1048606b836968d2f8b84c253411422efa69958314b33bc504601f6609"): true, + common.HexToHash("0xb0b7829d9eff00ba90533703eadd6114815a13b91029a562451475fd29d701c5"): true, + common.HexToHash("0x686a1bc62b2b6ba7cd17f6a304fe5816493f5b6bf1693c84c3aad166ce33199d"): true, + common.HexToHash("0x36734754be4f622033749997a51695ffacb47c65c5b35273f573ab296b5427f3"): true, + common.HexToHash("0xa04a55e3df329620abc504e151760dfc6a5f70f121d034023ad9af234d68a24d"): true, + common.HexToHash("0xf35984a8b7332bfc3b3c2ce0437f30453ad5167d90233c5390c0d43a97e28ae6"): true, + common.HexToHash("0x0c4a5b0302da018df6dbf50c59c2d7ce4e403da01caa73618a49cb587e3d7528"): true, + common.HexToHash("0x22389f32eda1c327e87ac7bd24630b2d686393094711b7b928eaece209e28e1b"): true, + common.HexToHash("0x6111db646a09809ac151762fd78b3e94d5e5ccbc5a14231c119d98154ca68fad"): true, + common.HexToHash("0x1e842bc8a20e02dde7183ecc95a378668da306d0d459bb3c0c8d02fac6b9baaa"): true, + common.HexToHash("0x0668c3b9e6a4eefe4988e213caad1e4bd9539f11e07b0cc24a62ded0b67c4f54"): true, + common.HexToHash("0x4fc985437b7e6cfc7bffa54d2c2d91f0250474ed2ceb4c8a64a44c79e5c52a55"): true, + common.HexToHash("0x7535427a6f33d7aa12492dec9a3e1ab0adad55521c83572f976bb4d506f97b7e"): true, + common.HexToHash("0xbc5d03de047d159605de5ca712de6fdad4179ef3a0bdb48a648b822bcef66cd8"): true, + common.HexToHash("0x634f9f9812b4b8bf6cc9a607af969c30853cdf243df8315f2a5be498a27b683d"): true, + common.HexToHash("0x2f0cc566fd5d28387890815863c0eeb8b1da3a18bb73b520dd390beda2466730"): true, + common.HexToHash("0x43464104216619be9cef32550ca15f495615202209bb29f595439446f479c441"): true, + common.HexToHash("0xd1068dff171dc9be6dff401e22d106f6feaad050892ee4b0975dd804d792757e"): true, + common.HexToHash("0xcb93eb09e9e092426d9e217884326c441ebe2c9407c636f62fc2cb26c1437fa9"): true, + common.HexToHash("0x41b33f12958dcab5f2267e29f3b50e605fe9f6d5e7ee1d6496cbcd60394f0508"): true, + common.HexToHash("0xc5e34c722673a25b3da252de4924a78744f2afc70f158a4fc31673d2b534b272"): true, + common.HexToHash("0x1b9b4e46a00bbd5b29d3b5d5c659e27c701e693e6f9f028225f2e87792d83369"): true, + common.HexToHash("0xfdd5eefd074ec3d9744a403ccc61343eeff515a8c5d72f9599b78d3f191f7f5a"): true, + common.HexToHash("0x608f3394aa8f821273baaa680276a2ff7c05dfdd5ed60cb2d3ac876c6b60c920"): true, + common.HexToHash("0xd9d836296fc6245850fdb3f798db7868fc2adc07b99c6f0692854cb164d64629"): true, + common.HexToHash("0x572ba0aed1a3cc167fc6bfe4cfcc16a2e50017d58295592e06ea25fc345ec448"): true, + common.HexToHash("0x093024cabe583aeda32fc83eefef8972bb87a36d4f17e0297c4e6ada510115e7"): true, + common.HexToHash("0x35c5fc4e61f3fdf78abe173d668b7a108c075fb313b43ff5b461d4438fe1b2b1"): true, + common.HexToHash("0xf67bcb6f464fb9d7d735deb1e32b002aa13d22784c944327929cf90c48a7166f"): true, + common.HexToHash("0x93aa1f89d74e87241a6b171cf062faed91014a59763d4e878359abf3b540b0d0"): true, + common.HexToHash("0xf9a1e384a7608fcbae2f1db796b8783f388f23492e1bc4d0665317afb8253c6b"): true, + common.HexToHash("0x9c1a9768148644bb21d0ecbd077106aef984fb24684cdf171479b9bdda8f64e5"): true, + common.HexToHash("0x074e9bfee542d27488377ecea662a02f339c480255e58c8c2033dce77ef36afe"): true, + common.HexToHash("0x0d2611f5601113232a2788f3ab78eeb400f8a18d2c52ef6ab449f15b9a06fa3b"): true, + common.HexToHash("0xed45cac776eda1fccad548df5f6b1675d01a8083d5add3b2f44039831eb2c9c7"): true, + common.HexToHash("0x3f5af6389cf76dbaf31c79742724f339f86e8481cf57b2d00e29c558189e59f1"): true, + common.HexToHash("0x2987d12dc028898fbff0f5a67c014cc8800961d49a67cce6fe71c27a43d3c0a1"): true, + common.HexToHash("0x68e7ebda8b297808cdefaa9cb2a358736175198259610c1bed8cddb741902a73"): true, + common.HexToHash("0xad5c8d02b8fe1bebdcc3a726e656db71e99e236fe140cc623350b847f0ac6d19"): true, + common.HexToHash("0x3d5b98e1e1fc3a0ca50b0b5bdee561edcf084e2dca7f236170ad890baccade65"): true, + common.HexToHash("0xa768871b5e283902805a358e780288e8bf0ef7c84bdef395ed26838820b25bb7"): true, + common.HexToHash("0x624751ade74d051fb8c07d1b9dffe64daa46c26efa80d739c46892da6c123ed9"): true, + common.HexToHash("0xb305f5af137703c12d3d4e0a60a54199423729bc5be61f8a62605dbb355de9f9"): true, + common.HexToHash("0x2e1620d81120e6c0d18c1b28738cbee7636eacd70a2d24fe584bede7a69dab01"): true, + common.HexToHash("0xbe609767009edae5ec1ff86625d45920d43740376fad925ab3a50af483c15239"): true, + common.HexToHash("0x8a1965d9ec2831d77adffbc0484ba86021b340dcae25bf37a689c3039f9b3482"): true, + common.HexToHash("0x356fb3b98a30f069a20cf5b5ad3f11f1b4652a81cc98db867d9ddf6aeecdd574"): true, + common.HexToHash("0xfa2ac9507eb0ad2ae5acad6ec7bebc77967b1724d99a25a54e7506e440217ffe"): true, + common.HexToHash("0x1093716d1791a3e8c7f874b7e1d089108f47e180f01d83d595cd89adfc04a17d"): true, + common.HexToHash("0x448cd82427662f3e0dc06677858dc37b4e46a658227fb017309e666244bbdf0f"): true, + common.HexToHash("0x03ed97a056b7c0556bb41885a0490b2e9310b93e18eff28c1d9be33082a6fa05"): true, + common.HexToHash("0xcdc1a45a8e2ee414dd5e72b3236fa46dbd04eda98a055cc01cc0c88a2ae05c06"): true, + common.HexToHash("0x101f977c056ae1396516d4af396860f51c1a14ec3a6658efe8dc02aafa572d09"): true, + common.HexToHash("0xfe7e355d31a8eb30782c25c52cd1829751a2aeeb024691f4807f1d87c2606c1b"): true, + common.HexToHash("0x7fc111b12643b4d87ccb8ce256c51ede4a7dd0ff0c244d2e35c97d17dca44f32"): true, + common.HexToHash("0x9d4b14233e2c001d018c948ab0b12df376d21a32a35cb9b5b8b5d000acd2d12d"): true, + common.HexToHash("0x430ef8fa062746f41e7f6804f0fb908c9451f9bcd53aaa414ed73a39e1be2a3f"): true, + common.HexToHash("0x021d5f2ee1bcccb8d93e3b2ffb1361d7187ab554561393467241d3bae7c86e5d"): true, + common.HexToHash("0xc9606522bb4f4beddf0fc9fbcdb274dfeae9c688fc804ada1fa75e777e79609a"): true, + common.HexToHash("0x5102acdf28f2d843bf93c8f10e1bcb75bf98094b8bf9ce305bc5dd28a185304c"): true, + common.HexToHash("0xbac1f6cd5c6cb605a7e5a8cf7cf76d38d24536b637ae11a9c4b40d830563c76c"): true, + common.HexToHash("0x4185b8602e57e6f6cc146e88b67a303753867b0c3b2953e72575b24db5e112f9"): true, + common.HexToHash("0x09ac6c716125d3081acf71cf36dd97852a237740a91ece5b3c769a579cac43a6"): true, + common.HexToHash("0x0ca37c89eca46ef1ab5661404e674a7b83025de68b6c57e7fd725ad73da1fede"): true, + common.HexToHash("0x13044680396cefeec88853cf74cd4dd05579aff33c2d091d502cc7fbf0404d12"): true, + common.HexToHash("0xeeb19d4df0b859b0dcf5873ce0133ebf0c91574ff802833acdf11723747861b3"): true, + common.HexToHash("0x39cd810d5c793c97f6d726224ddf4bfcd7868431aff51b09051b09678c0a382d"): true, + common.HexToHash("0x0df5d74c6ef919b2c7341f08b0c80182695ffcd64b59435f514e0fca0c4a4621"): true, + common.HexToHash("0xcb7534e98699f885c791da533704b9e8360cbe3b182dde2f57f25dad0e531e61"): true, + common.HexToHash("0xc739a0e4d03d334f4d03228bd03afe4948aaa4b5c41999e7eec70f645de451b3"): true, + common.HexToHash("0x6cc0d1566fca669c27186c923fd07657f47e2715889028db6ef9ed2f920b790c"): true, + common.HexToHash("0xdef610f83a1876061a529694b0081e412141c0d1af4013d2ee699f636bf20a06"): true, + common.HexToHash("0x33f0964e0642ae09debf680f21811fa4ad7bfcab30ab80ad8ce32c5fb1c6906c"): true, + common.HexToHash("0xd8df45e6c01c40dbcf2c14e222ec233d633ada541a2ffac1c186be5acdf29cff"): true, + common.HexToHash("0xd73d95118954bee55d68fecf99cc089089f1d39e8158be3b5170f8184e885bcc"): true, + common.HexToHash("0x89fa4985606a37888eb2bcf56679e5722912d62ea895e2b2dbc930ad25680372"): true, + common.HexToHash("0x0f848d62eee251737ca688299c37c32c60c029db26bf53b81e29b4f8e9d0142e"): true, + common.HexToHash("0x820b95c71af1f6166ee335c59936118850b16e80618f70737999f6bb9d276282"): true, + common.HexToHash("0xa1a4a75c8e11116369b9a92bf9fecf38dbd8772287ce85e1a6d4d172898696b3"): true, + common.HexToHash("0x6f7a7ff45713c5956b8f7075026f0f1bc1c8726125b54ca6ae4c6bc33652ba23"): true, + common.HexToHash("0x4309ad4c115f0ec8073ef52a36ec1195b26ab082b8a53a0cfbee6540be3c02e3"): true, + common.HexToHash("0x26e1c4a48271ce8321f051e0d5eb9122d956e8be378765017da96922b3ae1410"): true, + common.HexToHash("0x24f647b1d03edeaac86a50939190bc0224eeac36f7f74f6f4d8b2501b6ea222c"): true, + common.HexToHash("0x2d33096225884c72536dfd5056b1945b29079f9462ca0ac15e5770fd7ffbe55e"): true, + common.HexToHash("0x79bfb23542490baa41d069876b11ba93ec1edc2187891057a8b0799dfd874441"): true, + common.HexToHash("0xc83624773e1071288072ad590abfaf219ee173a3b4110ee2230f95948cd24442"): true, + common.HexToHash("0xfc2bd0d940736165c49b6e7c2eeac14b1b5599a86683beb4a17dfb1c7b104789"): true, + common.HexToHash("0xad9e2217e6fdf3c0fb9003556f6e02ad9105ff6a6a94bba3e22c85dd4863a051"): true, + common.HexToHash("0x314715400f358b3d50405a1bcda348a057809613d3ef3d5a2ba9831a135f8065"): true, + common.HexToHash("0xf8add3ca2e953b7ff39dd96602119fbacfe1f095c2e4d05f39c233ca883bd0a4"): true, + common.HexToHash("0x86bcccb4b8863e3be0e60a862600a81468181974254a0071d733f5ea38c3c3a2"): true, + common.HexToHash("0xb6c9748c1b779d4dda75b2600d06e4bab8bbe8322f0cecb0e2e881b4beb4468b"): true, + common.HexToHash("0xe209b7b37eb0ef6624ef8b96d0637e08f33edf3a2bd5811ee490af5222468e6f"): true, + common.HexToHash("0x2388ad71715ce97052606e6a1a43bab78737dd2b7a1f9fa4bd8340b406db278c"): true, + common.HexToHash("0xc99348201e7100587406e8d439a5f929cf5e8895128ba0646d8c821502f6b5f6"): true, + common.HexToHash("0x6bb4b3fbd785017c657375c055b446ef6de6f60fa881ec387fe00f691663a0c0"): true, + common.HexToHash("0xd10e49e21f7ab66e4d3bbeabfa4c2abb8b4bd8137b084cc1f84c3f9896c0223e"): true, + common.HexToHash("0xd7a8a534150191c7d031028f31d6da512bc7c30822c0696632a2bfa195f7fb92"): true, + common.HexToHash("0xaec4c035b225d96df41339815580681773e0942d6a88a9ec889605035b52fec2"): true, + common.HexToHash("0xd89f0e8b40f9a2a0f047e548b10c40f5815696e3124e59dce1c82bdc3fcea4c0"): true, + common.HexToHash("0x6f1f0089202563824ef0e6e359348a6e121267b386170e8b93b484a4b7cd14d7"): true, + common.HexToHash("0x27bee997e5f31f9c66c90545127318bb0f98f4fa24b619b251e6d70d05d01755"): true, + common.HexToHash("0x7591570ef3203f7227df10594cc537b9a0ad9ad71529e90caad18244d0368937"): true, + common.HexToHash("0xe4366bd925f4952a926d49bc3a80c7e7fa67d481c36215272f480b13dfacd3d1"): true, + common.HexToHash("0x5765f6f3b8470daa14b868d99fd1c83c6c4a2d8a35165ac847a1c942b181f970"): true, + common.HexToHash("0x59d3d2ab3644a99e8d29ad01b2992f11b8df02efa8077bd4779148942dfbf659"): true, + common.HexToHash("0x1ddca1d1f0eb8bebbdf51adf97b84c8ecc6d70ee86422637a091bd3ba926b92e"): true, + common.HexToHash("0xcdbe49c7c1d31bfd96675022352052280b9e1299c2b74a8594955903381aa43a"): true, + common.HexToHash("0xeb2c0c443f4de44e7d386aa5ceaece19d329506411e260b2f8e03ee37e3e40e5"): true, + common.HexToHash("0x19d9fbdaa4c49186e571f19aaa27a97890a26861d030500110d7f36dd45b8c87"): true, + common.HexToHash("0xbf654ed28a84173c48a8124e8c4b9d4fe0b47079e8dc53306edee14e085327ef"): true, + common.HexToHash("0x508c37561cadc78db6076f8d7cf1973143e12d156855771b48798ee869724a97"): true, + common.HexToHash("0x27d9aa18cb476d4b53294e730037fdfd7580d43b762d9488ad65042e360f4a81"): true, + common.HexToHash("0xba6be72c04000f935a86ef5815817da1e9d79b6e1de0facb187291d52fdc5edf"): true, + common.HexToHash("0xcd4a557823dc15e419d154301e6fddb5e24481cddd3b429c54404e65a5ca5e7a"): true, + common.HexToHash("0xb71646a31ec385d0373c0117633a3a5f8920eab4f664684188f04460cc0c9d4d"): true, + common.HexToHash("0xc61f0acd67369f44dc7133e0746bcba992048c153b5a6318d79e56142fd4efe9"): true, + common.HexToHash("0x2881039d20a40ede7cbbe61dc74416da3e9889713339adc031f4d435cf85bdde"): true, + common.HexToHash("0x6842347fc5898d9f716d53ce9b063beb33b394f731fbebc946a395d795f7c28f"): true, + common.HexToHash("0xc2fd1474813d5931c915c61d5051111fc4832effb7ac8fff03206e64cdaad9d3"): true, + common.HexToHash("0x1f8614a9a4e780f748201e5ea70b0ff0c11eeee46e0eff58ca10e1e09cce83ec"): true, + common.HexToHash("0x98f8e59077e01517dedc6d9ed8627517748e3f1079fee68a18f7907214f8414c"): true, + common.HexToHash("0x2663c4009905a4c163a1e8d4bdada2fd6b2a45b0cb0369b9fb46b7c4f1a5412c"): true, + common.HexToHash("0x075401dd2da20369f89f8c91d2050447e78a50dca211ec269fe3b8be973ca1f9"): true, + common.HexToHash("0xb7ff0ff04f42b0f43c1210b6465c0fdbe0bbb354c776be589c063a55d6ca88c3"): true, + common.HexToHash("0xd4db8166f12c69959cf0f745c7ff528c60ef6c5a754b1cf511f289568aed1d24"): true, + common.HexToHash("0x07884556f2c4d9a17f4f36cfec21877904f0f3b7b745777165f772dec1def4fd"): true, + common.HexToHash("0xf1c40c38d2a32a4ace26ef01f7c3683dccd08b1c1ea10be8970a339b49aab544"): true, + common.HexToHash("0x108801190d3af71d68480bce4ec11f383678f84c6fed8b81ab61d7f94e5f4057"): true, + common.HexToHash("0x20665f0a9e4f11585ca3d8afc16c185589e6c1b8ec77068ad738600136e13d8e"): true, + common.HexToHash("0xbd3df993b6dcd0bc00a382c72278beb76ff95832bdd40c7dbe021c17aabadf25"): true, + common.HexToHash("0xe8468d7119d03195546c09e79c0088c3a95fdca64e8353bc095d283724d47ab2"): true, + common.HexToHash("0x09a3fe952eafae34421d25c1e73e662a4866d7af8aed3c7e2cec31574d49ac63"): true, + common.HexToHash("0xaf450baa632a455c1f70d785b89aa017fa92b7d1decb40103be54e6cc3d60884"): true, + common.HexToHash("0xd53edc787caf31742211a2c593b2f1e78668b807dd63c2a56094aa8ea81f5160"): true, + common.HexToHash("0xcc1c9642360acbd56b03e29ebe3a26fac7a1560ea2bc5a9380358bc015ccb3c2"): true, + common.HexToHash("0x8c3d7facdb4217208041ffcb234563de68cf549af8bde366d4e07c4e46bb10ab"): true, + common.HexToHash("0x5f585b114aa50264e1a9d1b581978e4960bf2b0726bfba052b38c71800f31b53"): true, + common.HexToHash("0xa50c281b2cd0b3f81954731d91fc10e47e84b5bf7e48650cf9a47ede91e8f1de"): true, + common.HexToHash("0x45b6960f3e3c2106f46538e357c2a6ef73067bf5f4d84244722af352f21035f2"): true, + common.HexToHash("0x0e9782c0c5ab02cd7c4f6d2b86451908928ba861fedd62964ed0a46eaf301d43"): true, + common.HexToHash("0xb5db62e2d67e85135a84b3d774e473ceeac3fd87e51a11275e43ce977b038335"): true, + common.HexToHash("0x11134151fa754db722a4434f2fa46aea591c28abc6a2c2dad68e79b40cae5df3"): true, + common.HexToHash("0x0f42b189eb1503fdf31ab601d52ddd8fea0089fb899d7da61b9ae51b0dbbd84b"): true, + common.HexToHash("0x745b5a241a91e83542769d80373604d407506259c68666852fcf8d6577298058"): true, + common.HexToHash("0xc602c49b42408976b7055ca119b95539c36497fe02d4197094ac8c0edb1f27a3"): true, + common.HexToHash("0x99ff3773df68f6fb3b033ab2760877d0aba3c9e45f145faa2e908d5e6632c1f0"): true, + common.HexToHash("0x7e0ad5e916a0da7f2882fcf3528d5adece9f827cb619323012abc0eb4622ed26"): true, + common.HexToHash("0x023f2922a3f0585bfa97d25a105607d64b6b8224d1c200075a3411268b514656"): true, + common.HexToHash("0xa04658d8d7ee063c4d146ec10f7d8a9c9431c32e402c5872d163e24d53b72362"): true, + common.HexToHash("0x30846addd34de9151c84cfb53753f5d782a136e0d6f1ce4dac04bf01b690e56f"): true, + common.HexToHash("0x83965f5daf07fc4d833324069afbef9db3f450ef1f7b02d46846be7deaa758af"): true, + common.HexToHash("0x0567b7a753ba1c6e8c232c0a62d269457d12c11835d75847d66dd2af68871bdb"): true, + common.HexToHash("0xf0c5d5ba117727760c50b55b2b33294813e1bd029098b61ca72366626e34c208"): true, + common.HexToHash("0xad6973bd996d8bbfffe95ae879b13e191392be5428b49204eb89dde4d7c505d9"): true, + common.HexToHash("0x58e18d23758862f79c27035fa4e7dcf6b7cfc32f555072966073f4aed562b952"): true, + common.HexToHash("0x6682a0bcb1bea9973271a97153979d3174781024239f579c1ccd74cb40d40510"): true, + common.HexToHash("0xb939bac596bc16e4986ab80e931ee941e097ac018352fd938f39d322bff8d26d"): true, + common.HexToHash("0x650fef356dfea9ad88253b77195144194a26de364cfd0f1e76522b492ce53ce5"): true, + common.HexToHash("0xd6d327bbebe5f2aee3bc83b12f1502c34a764a1172095a417907baf26e6bcc59"): true, + common.HexToHash("0x49f39162d6a6c2df78aef54c433f035703e2876b7af782a819ec8662db240abc"): true, + common.HexToHash("0xdab616851a9c5e6132bfff7d4db6cdd77104156b70b2b261583b71837d9a5128"): true, + common.HexToHash("0x35fc40165b72bcd491420ad148e3c38a38ea7d9f43ff1aa071ed35a33496c6f1"): true, + common.HexToHash("0x0ae5bd5c88cd78487936793b100fdcef081948fc969db64ac7303b4cecf60a71"): true, + common.HexToHash("0xe59fa6f8477abeaa87a9903f4acca270fb9395ae01689033039ed5a2a56f8d4a"): true, + common.HexToHash("0x8b346cbb6c4436f5137c68a39bf39e0b19478e75eeb3ab6b0ca5a9ecdf255660"): true, + common.HexToHash("0x4950cd31cd585768de2e795a10e8c7b2fd58da95ead15a0ddf8e29cc5f68c10f"): true, + common.HexToHash("0x2e62c47e71fb62254e98fb64da4408000137f966463ab2e0cfc9448c26388dcb"): true, + common.HexToHash("0x9a808b7e03542cd70992e10da287ab20d64c59212782bfefe0567e4733f3ac1a"): true, + common.HexToHash("0xaadc8a67bc20931a449e9a7e6207c71724898ad7862ce8026630f216a1172107"): true, + common.HexToHash("0x93100eccbf684c2fbfec824dfea57cd75b1aed284c90bfc944f7827243385eb1"): true, + common.HexToHash("0xef5c34fd35c9e28fbc5827eaaa24a267c815c633620f32dcc61195ce4cb5f4c2"): true, + common.HexToHash("0xdc29cbc3774acddad351431b7f3d5ea07af9f109b3295a331d9482c45e2703e2"): true, + common.HexToHash("0x7a1c6eb0699812fe7cf6c404b395b6a4f4e65328c981eccde40ab61744829e87"): true, + common.HexToHash("0xc048550af52149ccf73cbe71c8144af1aac6604fde9e197f8e83a9c4ffcf967b"): true, + common.HexToHash("0x65153a828e4ea6d5d3378c8fb75f4c03c4acd10d48b98d144a343aafa51e018e"): true, + common.HexToHash("0xb8aefe13e6ae54958b5891cf665a2f29a098ebdec25efdee38026d39c351be1f"): true, + common.HexToHash("0x821f9000aac3d9301549ba08eebdf8132be434fa322130b3856260b7e7306bba"): true, + common.HexToHash("0x9b6f56821e7b33a247766cfc9b7a61acc38f04969c3e986fe30b26f1f5e1f8c2"): true, + common.HexToHash("0x851cf63d313e38c5f7bc9c8745ded272e588beed9591b0fca1bbfe63258c1918"): true, + common.HexToHash("0x4a5bd4719ba5d39a42ca70f9f8c53dec3e5009b3157117cd9b4c52c3c45eed8d"): true, + common.HexToHash("0x935bc78c24aa4ad915e00dc670a2ae3bcdabb38425f0fd7c9725c03b70db25e9"): true, + common.HexToHash("0xdc8cafe2bf52378a18036c6f8e80d3c3dad9f92192781d8cd385d6661040126b"): true, + common.HexToHash("0x913525c0ae1002b69341c8bb20f9857cd63fce9210ddfca8616f8e6c2edc2172"): true, + common.HexToHash("0xd5914c7d07303e84f17a07196a86b81370927b13d3324ab8db66bbe9afa01a47"): true, + common.HexToHash("0x548630c8ab6219121faa2ecf24f00e33984ed02c1a9223f09744487b4b898383"): true, + common.HexToHash("0x9973dc40d52b0e432a58fa4e415eeea69a8a1dc90fd28d17aee80e9acd04f4e4"): true, + common.HexToHash("0x270ef2399d09cbb2f6282220990a46b08c3faa9e2f3bb7d0f4d06ff3cec9ac2a"): true, + common.HexToHash("0x22c0998e202a68e6d896e2a9a1f5ffef9c1c4783db22153135d49852b4a8043f"): true, + common.HexToHash("0x46a0018af0b989b41ca09e2827140d614be61d699f75757856f58029431e3e57"): true, + common.HexToHash("0x2d36ce6ee8a52347f26778c6e6c71c764b8d2ba7aa7baa9c00bd9b2aa824ccfc"): true, + common.HexToHash("0xf1b95fece8f8cd569ca6c2b18fdaa46d62d24bdbefedbc0e09e7f15d6b2f4e25"): true, + common.HexToHash("0x78291332ff996e0e063f515dfff2a3002d8f9be102ac43500535bce8df4f89c5"): true, + common.HexToHash("0x8b1f336d89750fe052250e160f635dae7046bc17d75739c19f9a5651a838f384"): true, + common.HexToHash("0x831d61c3c5a8cc5764ce8ba1063b6b294582cafb74c5e67b95efa096e0e2515b"): true, + common.HexToHash("0x15360a44db0faa2f447eef7d9df3fc0e12c0d5d1fd65b0289445f6bad424194f"): true, + common.HexToHash("0x8ae3524a3fe69d23ea1307286d70f1e0de8641f1eb448f1ac3dedd9b188ef596"): true, + common.HexToHash("0x01255107ddb8be7699d4b9fba38d89cb580d085e71328c954995252889b8971c"): true, + common.HexToHash("0x1522ea1a1052e3a96ed8640975008d8253f1f2f6ffb818cc8532359d3435c386"): true, + common.HexToHash("0x6d57a9104707eb7017e720835ac5363a45a063cb334f70b21ca2463e4952838e"): true, + common.HexToHash("0x21a08eb53e03b21f2294a9c08ff3c5d03a68fd8439306f70cb37c5a6becb8d2f"): true, + common.HexToHash("0xfa632e9c0d13e1e5b4c784781a96153188983173f2e5278a6138e3d0c6df2ba9"): true, + common.HexToHash("0x66d6adb2525546eab3c9d6f19cae8899a7dc35d7e47d0946ff52bf0877ebb5f1"): true, + common.HexToHash("0x1589ea3d7c54183c8c2c6fee4242ac26f226e931e27544fc2d06b24d9b7d18a8"): true, + common.HexToHash("0x5901172ed4f4fe41cc76be64e509313f3dc05c53fd3407cf0ed5f61530506091"): true, + common.HexToHash("0x7a69407f985802a657327e91a19b30cd1f187558f985e7e445912270fb8e7c14"): true, + common.HexToHash("0xc8346e19e871506750c09a9bf9be881c0cb4591207c3bbddfdeddedf71b0b03e"): true, + common.HexToHash("0x0a7ff5f70c3c00af521768a499a69cf28e3995bc611ee82c7a41777fe40208e7"): true, + common.HexToHash("0xef9d2f53998abcdce539ddfea41e69f9e7ad795556c214637bed72a81b079346"): true, + common.HexToHash("0x95b2df40d57332e4f95a02644be181ad716b9864e97b35ef6a3ea29154f6e0e4"): true, + common.HexToHash("0xc467e68e4baed1e56cb34a3499b784e2895c8afc6862d9b6f142fceffb230c55"): true, + common.HexToHash("0x77807c58d9e27ff22d00a181900bf98020164b07ef1d27b3c355071fb21fa91d"): true, + common.HexToHash("0x3adc43f921c1f4e56f04bce2a19a6c9b5c29e1c95d6eb0e830b4859ca59eeb2d"): true, + common.HexToHash("0xdd3936fa5d37ef459921d4275550c76a9418ff96efff231788ddd891073b7762"): true, + common.HexToHash("0x221e2db7b0fdb16c4ba79640fc37350dbb2f83eda56922bc6dcb1af3f3e15b22"): true, + common.HexToHash("0x7a4ddefc73c07d337311f83ee8c60d98d9a65d94c7432e49cd98008fa96b531c"): true, + common.HexToHash("0xa79bc599e389757764b16a262a9ad9d4b2e4fb476996a5d9d272c42ceba53593"): true, + common.HexToHash("0x0ece6f6491f5c97e515d32391a9a4fc195baed1d4fcc938e4653451bc783c607"): true, + common.HexToHash("0x6378a0bb25e9da659305e4ef036513c8294dcbc81176dacbf4b0aaa28697321f"): true, + common.HexToHash("0x9d0ba5f5afe50c7210b357df866ca8ff6bb223024fa0b042520f0d9bd0f49774"): true, + common.HexToHash("0xff4f7174f66b07fb832509744b31a6b61d0f8ad22d527607f0ff63dd5f111fe3"): true, + common.HexToHash("0x72f0b0e572e41ee6913748b90c67ea8321d68202d87c561b38044f57ca972c85"): true, + common.HexToHash("0xc0a26160dc88f6f8398d455f7a5512526f3dc7f1ee6663e35b063172a2c10f16"): true, + common.HexToHash("0x479dcf950b9999c6e885b43aed02497091145f7a5819d658d456b75342455f13"): true, + common.HexToHash("0xec432223f7d8622bd249d3497c29e16149f6865633b0cfc68c7ab22101bf5bb3"): true, + common.HexToHash("0x96e76993de2d2600df273278159290648c6aa3ee79d1e31ebe9abb91ae9f0e08"): true, + common.HexToHash("0xb54c5ed2a06c0e18a182f1d1c16ce6bbcf01c05c2be56737fbee76827aa2996c"): true, + common.HexToHash("0xbdbf6301f9d59c2632287a93fc46cf5de38a43f54bb27d35eca064df2a508a96"): true, + common.HexToHash("0x17135a2f3eba9b2d3ee48971dcf2cb6e9a406779a46273e1b29a016d6f66a3e9"): true, + common.HexToHash("0xdf60968d885934d77647e93d1a4a6048b1ce58fd63921a05161e41184f9aa17f"): true, + common.HexToHash("0x621ae0d85256944b7e6bc320c7ab5fc08c942d56f7a4328a41eab2ad56ed7b95"): true, + common.HexToHash("0xb2bc841d554acdf57445471fbb9b5793b75d71421978f6b9a1fbe8f4b6f4e179"): true, + common.HexToHash("0x1e0ad5c6bbc5d406fdd98eff05e96a64a3869ee9b4729b36a7a1f2b8b842ddf9"): true, + common.HexToHash("0xd9169b41e9a614eb1b6dea163ad113b67096a3bcb695b1e869137c2bd36bcf4a"): true, + common.HexToHash("0x420812eeaf9bcd78c0d3d00938c2dfc61ff6f5523b159ed7e9202951d2d1d8fc"): true, + common.HexToHash("0xbbc99a4e3ea8ed416c9774fc196724afd233879d6c4db18f6f17394bc5a2587f"): true, + common.HexToHash("0xd6d20599784a8271e93dfd7b3ffcbb32f3ea156355177a8b9faf26579138ff3c"): true, + common.HexToHash("0xaf21832b1f3580f337a0f69249f91fd7cacd32b95ea0187da9566c0c0101c60a"): true, + common.HexToHash("0x3b1da42f13e301dd0d997109166e4fbb7cd37a7429031d5f2be6e13047c9e7ba"): true, + common.HexToHash("0x9017c5f83e503901a9c65967551d4cf7eb36b95a9c46c76c396fb2807e9576ac"): true, + common.HexToHash("0x46b9347b13ee900c3b24f2f5b9b74d5a77256ecf8575cb6fb9a8e6317740720d"): true, + common.HexToHash("0x681037bfc23a9aa4eaac483e4629ddf95bcffe84d77e15c3ca2a11540bf4d222"): true, + common.HexToHash("0x1888ec569bcce62a8fa6d7438403ac1135a8feec9697e54abe2fd353d912d849"): true, + common.HexToHash("0xee5c4301093f259e5136850eafd29737db04845d4f653f3bc156beb9de3bfd44"): true, + common.HexToHash("0x2805e956f220700002b3b199325ba7c45eab59594a18132b2c9e91bfac2e1cbf"): true, + common.HexToHash("0x5947c333cb3ca1d60ffc30b944af362476b86e354bf24d6b1277771eea48e4b0"): true, + common.HexToHash("0x71bc44d87ad718803a142e6b950b8fc693b22df05ddff5891c1c89f4d54ca8db"): true, + common.HexToHash("0x0fdf7494b7dd146f5332781599540f5310db51fc0bc9e9f36720cd276afd55b1"): true, + common.HexToHash("0xa7289c110537c80073f36c4146837dfd3dd9160862cd54aba2261f8c004be106"): true, + common.HexToHash("0xfe9535d908f2f31dd0081aab1f80c2538e1a03e00b1c9775c28287d8cee7a24f"): true, + common.HexToHash("0x059dfa84ecd9cbbc1f5fa8212233b5da25865448e13053e3f029068db45d6711"): true, + common.HexToHash("0x644752c043c277c03538f90b46b1b5438724f93a490b4b337607891ffb707b2d"): true, + common.HexToHash("0x7da06b41b433f568fce22adf8a2f597491bc7b7a6676ecd7ae36e43faae5aefb"): true, + common.HexToHash("0x25e917a1a7945e9c12434a393dddccb0add238af16296d21956c537553bbe36e"): true, + common.HexToHash("0xcd04b26d4f0b67a05b27e2dd5e6487ec2bbc3a434032709c60023c461fd0f47a"): true, + common.HexToHash("0x1655f4b9cec8626aff578b324756e416e96e48a9d4c5061851f669ab2d377ad8"): true, + common.HexToHash("0xa3680f7a814c1f5f7ed5fd07e1ed5e19fb1f536d91548a81519a0e5ca177cfa6"): true, + common.HexToHash("0xecd1c3194063e0a62be8ec3185f4a98c3bc3c98ef441e855bb4406a278fb811f"): true, + common.HexToHash("0x03f6dc8f027fc524303a326b1c7b159ceab871edb02ea31a888660feb54ffaf3"): true, + common.HexToHash("0x8132e4900b7afbc860cb93f855e36e830bf2d8040a7bcdac148ee7d35b8ed891"): true, + common.HexToHash("0x5421d1a854aab4fc39a9971a0ffc4aba202c37cfd5ff757a0c7a2d5ab38e83ed"): true, + common.HexToHash("0xaf630b3f7e81c7805eec40d6085447a16332553092cee030f424fa4c88fab99f"): true, + common.HexToHash("0x7ae31e842566f35242996f15295731411197981f58abe770b507e968b1fa290a"): true, + common.HexToHash("0xf821503a2bdc98101904d3cdfef67e5138f65958473523d701ab2aabe6860b48"): true, + common.HexToHash("0x6c7a05ec81750c8c5ab1f4db22812c5c8613bf7c5849ed57c0ed224d5e9493a0"): true, + common.HexToHash("0x91f47fc96edab1abd974181321570eed97331bab3711f5769c176c3aa7d58ffa"): true, + common.HexToHash("0x534cd5a2bbb817d87aa8b1d601f914503ae4bf24dc01459612d87a7d06e2024a"): true, + common.HexToHash("0x94955f1219aa05b1f9855dd1f265542ae738755e14770d864dff61219df9c072"): true, + common.HexToHash("0x7fbc2fc373551f900466dec6925021cdf81789d3911da2b3f0e847416f4f930a"): true, + common.HexToHash("0x7c71addc826d59cd4c919806b05d97f793d5ae34d69112cd9ec7a92df24d8b1f"): true, + common.HexToHash("0x300e5d9064fbd2843e65d24bf8051dacdbeb59845d019bae69b13502e060452e"): true, + common.HexToHash("0xe145b8538945cab3af830e3bb080923882f4f69f97fbcdad65a089331cb9e87c"): true, + common.HexToHash("0x682b1340553d31e418d9b80fb9eb2225a5332b2a358e3e34bb69c1b525297f25"): true, + common.HexToHash("0x8d6909cb7f59251c157581de99a9faffc974ee6f8b5eb1d3c108005456181625"): true, + common.HexToHash("0xabc5424d02013583ec06c3b83fce1d1df82a6d49f9de17448bcfebdead83119a"): true, + common.HexToHash("0x83a112dc792fa95eb2854d2a4094fdf77da8ea50491708764e243eea1ae1c042"): true, + common.HexToHash("0x4a20b8a341783604f20f8505ba7bb923ff7f382c43fc4b72846fbe045a6ad7bc"): true, + common.HexToHash("0x727893c136f0d3cecb52194f00c0cc663802ce3de05fb491414328e0627b4508"): true, + common.HexToHash("0x54a50e828854c87dd80f20ef492446ecb669e6ed497bb8c076dbac616bfbab85"): true, + common.HexToHash("0x9f3361201f5bb49f17d9aefbe81f9099c8f9ff84d9614032a15dcf6490ee6285"): true, + common.HexToHash("0xa33c36d542a33ceacf5d2ca11fbd3d9f6e6fb570d1ee020a519dac495d2e8b6f"): true, + common.HexToHash("0x47c487b19de3047605927dee21512cc02e254d1bdd1b0bf80b75ef8d1eb54012"): true, + common.HexToHash("0xf221f5e6a0a518fcaf1249c44e5a42aa4758c1cfc1ab626bf8e985ba396941e3"): true, + common.HexToHash("0x26b032e0d667dba076e7c948870b246f1177c7cd161946bae4846e5ed227e1fe"): true, + common.HexToHash("0x95937bdc81b6c87ee6073f56288be5bb5f2ded21948ea4f825a0eceb95bdfd3b"): true, + common.HexToHash("0xed77ea455f4e70f38b042e69717bab8c40642dd2902290b61d138deb9fee09bf"): true, + common.HexToHash("0x8a4b4e46c9672688a81c241c574268a0e6aa91f33c874c06451dc7075758e722"): true, + common.HexToHash("0x8efa4d46408d20b3f6184cc97231e1d670c72687609a06a7862bff58ba0bd8b3"): true, + common.HexToHash("0x381848f6e4264c989112b19ac7eb306cb3e0ed5df144c7118f7bc4f8caf13ec5"): true, + common.HexToHash("0xc052a62ec7508682a8aacc5e217b0f85d508fbbc4644c23f1a82a7dadb98b830"): true, + common.HexToHash("0xaf4e34a0bb5bc38345a571ef9ea61aee784bd38825fc11af80b3a41dd2d6da2a"): true, + common.HexToHash("0xa28d88193f478781de4b942ccb2800fd511a445b6aa3d4aab9caa7005fcf9d0a"): true, + common.HexToHash("0x84c7ee70b5e1c0239f953543bbf98e39074b3e7999d110d040edbb7d9e83dcb3"): true, + common.HexToHash("0x0ee3a772f5e8bb36dcbfb3fe3193dc7e03aab37434262f95b9bbc4b875830929"): true, + common.HexToHash("0x0b0f7426a0ebb92ccffd6c77ba010af61f41f63e0803c287d02f43ce1d3491d7"): true, + common.HexToHash("0xb1d72a2f4663778cdf3198904ffd816c731e6e7ebe338f085c479548d1ec0e54"): true, + common.HexToHash("0xb9d78c93342263de4914b3d1ac4eadfbcac28565f8723da24c0e0c4726a4107b"): true, + common.HexToHash("0x4484ad1bff1f235d90724e118cb7e8913ce6bbcb37ac0666a077a3025fdea624"): true, + common.HexToHash("0x5bdd6e925d47cd7e1cceae04928aedec6a42ba7e9e6dea1262d27be4119af71f"): true, + common.HexToHash("0x0ea568c1314265537c7465625fd6ad1c966d6cc93e88cfca8c94028af3a4cabe"): true, + common.HexToHash("0x7242c630f61cc83212061428aa709a10703efcd6f1eb99773cdb9bb74a6a365b"): true, + common.HexToHash("0xce8cf34fa4946aa37b881f16caf1573cc8918981c7cab4c77685639bf6ffb44e"): true, + common.HexToHash("0x01a91b017c4fe4834108813fa769b45f1522fbf441b78caa9128392b54141187"): true, + common.HexToHash("0xb7e145278a65be3e19e4995660dba9bfbd23c14f2e8402ef27a38b3cd2a35cd4"): true, + common.HexToHash("0xcda11023e47e2e97224e521f24447321b75260c433503e4cb75ecc81da94305e"): true, + common.HexToHash("0x838416619698a84bf9c4490b1451c57405d87127e5a27c7cd4d516fd1033eb7e"): true, + common.HexToHash("0x64eb2d2e8257e49875998dec389bd59bd1e92a4fc0be11098528efd9278a7e8a"): true, + common.HexToHash("0xf7f49e751ca290f046d4cdd7b02896dbc9f6f67d3fed5da0c6644330f58585fb"): true, + common.HexToHash("0x35c60642d4ba3f4f7c1ecc998aa5c0c6b4506e03c3ed48f06c4ba1ea0afaf8d5"): true, + common.HexToHash("0x4643c7aaed226794e36aed85eef8f5a7ff361257a2e5d8a45ec5362d203e2dd2"): true, + common.HexToHash("0xbcfd6c933a1f89ed2c5f168ae0769db0bc06f79ffe313ef1909438b4ca6c603f"): true, + common.HexToHash("0x94f8906b4f154260bd8a670d54b3fbea239023ad91492b18e18e1c8c0ae43232"): true, + common.HexToHash("0x93aef02179a165ea24b7eb10a90179af0df4eecb6cb2b80ec5a503830368be99"): true, + common.HexToHash("0xc4334af3762945bd8a57b278dbea32e351ec28ead0332f223e5799c4c67f1a3a"): true, + common.HexToHash("0x545ff008ad65f7a0669ede6cf4cc06ece3bff104edec6893a4c97355892addde"): true, + common.HexToHash("0x2df0300c96197f79bd9fe16d06021fb10865d445b97c90099d495816f58b357a"): true, + common.HexToHash("0x086d8e44d5567cb88e1c8b45aad19dbfab5843b9818c5ccc897a91049e1cf060"): true, + common.HexToHash("0xffa43b4940b0bde4462825a49ce247a45630c6562396ed129c801f63b9e87194"): true, + common.HexToHash("0x5a54a643e022df123afcf3b4564ac9c8b107d468a7b9e3a84d101305410e9026"): true, + common.HexToHash("0x02c9dcd9ccbae0df134f1693553ff74eb790cf245f1fe0286e8f77171be6449f"): true, + common.HexToHash("0x5b02bd195dfee95907c948b3158e6a9e414123a6343a98d2071d94a8d01f8329"): true, + common.HexToHash("0xdce706227ba225da9e5bbeff49b4ad39afa85ad03872dccedb53b5ddcb10231d"): true, + common.HexToHash("0x04d4ce9aaa4b0fb9f1844922e50d5071e1bcbd44b0a4d98e12804c7e53acc026"): true, + common.HexToHash("0xe5c170a65528a9e931795b5a4575669197c55e400d8450d0cd1eae096d0761c6"): true, + common.HexToHash("0xefac924040b53d538eea49db1b8402989c7d3bff4ccb1ddf02254c580ec9e3eb"): true, + common.HexToHash("0x12becb5bb66b899526f6d3c42d4af4ae87e6124c1e9c4b531bccb10deb2c3d36"): true, + common.HexToHash("0xc7551e1ea50f6ff22a9d162e8cd48a5cef8b672ca9b79faaaaa05cdff1a8b092"): true, + common.HexToHash("0xb5e80858bb5f9cbee4c3d58b50d05d0afd07429111f169e0bf431bb402743016"): true, + common.HexToHash("0xd6a2ec942c20bbdf6cba822060596f4d6728f8c186cfcaca90eb30c4b9ab6e4a"): true, + common.HexToHash("0x0826c8b3829ad9dc58de25502b3bbb7324366449baefc75980801fa344b7ea39"): true, + common.HexToHash("0x1a1a360b124632c2d6b16bef9efcae7aeef7c37fd8b4abbd28f0a305cd4f7d5c"): true, + common.HexToHash("0x6824a02de199092be7d9c229c92d167dd455172c2f6c712d56d0fbe84c5cc697"): true, + common.HexToHash("0x7b34a09adcae28c15052b72fdbcac674374911e07399735d3789f4178b15a68c"): true, + common.HexToHash("0xd9a13a3934a77ada5c4c3ff44fc495994782ad90b2524eda75d48213e1e659f1"): true, + common.HexToHash("0x10d0c06f5e59633082f7ddb8b33c245ab06d54baac23f430b9758e5f95bfa9c8"): true, + common.HexToHash("0x23c269150b5b603d1228398e68e26460385c8b7cf2fdd7c1937a3851bbef9dac"): true, + common.HexToHash("0x11c3609581d349e1f2368b24333db7550eeb2855f8a35d74de87b6117da2e370"): true, + common.HexToHash("0xf2fd6479ce8361cbd410961dc60d1f9cec2ea923a128b3b45e02df65c1174a46"): true, + common.HexToHash("0x6d791b73dce6d3429f3a8f2007b4bff02daa18315a593313b6cc55506b06c39c"): true, + common.HexToHash("0xbb3b409635339d9d532bd25aa62658a439ffdfdeab1b5f3f3c93c472be584f78"): true, + common.HexToHash("0x84ac71810db4a3eb68275450885769572216b7f2945957b08774656420aed982"): true, + common.HexToHash("0xed24077d878987bd8fa6c9c3ccbbf0d96880a8014f41a99ad92e227eadccd02d"): true, + common.HexToHash("0xe5f0244535435de21403c8d284c42a792dd340d0c2def77f9820c1aa5979a2b8"): true, + common.HexToHash("0x189bdfbc3d77573df93949bc3ff1b0edd2331b8bc0f193a1f3ff565efd1b1721"): true, + common.HexToHash("0xed4bc1c0b2a64de194821ae8d3d2a8e936d8b5fc22578b584ab76003958fc495"): true, + common.HexToHash("0x7670e54b48fec2cd5256c46610e98ecba8b385c64612ce6309c37e3fa2e788d0"): true, + common.HexToHash("0xd305513a8d04c968308b9d831e9f3d03e92979751af4420cd2450142d3ffeddd"): true, + common.HexToHash("0x2ccd1d4cd6a69e6b2b6d1752d1ae1454dedd7fed9679038782f0b8c1c2dd2a16"): true, + common.HexToHash("0x77a0eb2d147b1fc3631d9e0f11229512606a101bbf61b6e22da4f06850b7ff6c"): true, + common.HexToHash("0x6c595a5d21469220da1de3176297c05390f017c4455ea18c49123573f8f9a3a4"): true, + common.HexToHash("0x571d19614a3a7817461febf984aab1785c0cabacbcf6dc25b83568fa1af98990"): true, + common.HexToHash("0x1781bb9f2bc5213bbcd5b53d1ae9d131fb1eba11d92d5f7f55f0e30ecd52eeb8"): true, + common.HexToHash("0xa121d533de6cf5e7b44b1d50f1fc1ea60fbfb4d01eb36da76e3802c857389466"): true, + common.HexToHash("0xa47397e25f24548326ed1ba02ff4b4e759b94295a1c6242c52ddd9ea5190143e"): true, + common.HexToHash("0xf3cd6acc474f6a1b3d436243b4b6f63f2ee9b002aa23af3024a5b08bfcb3acd0"): true, + common.HexToHash("0x70c342873c1aa60b067b13f8019a14841be8eea5d27f98cc5a0dcca609fce3c6"): true, + common.HexToHash("0xc14cc34a9e0b0a1444362e30593eb099bef14becc4f5fe25b4e0f42b60d0f611"): true, + common.HexToHash("0xaac044e7d11fb1e8518d0fa80fc7024620848e43fe48986ee53edb99bd0763ef"): true, + common.HexToHash("0x146a442d2f637fce7e9da3071900bc345349091fb7c3e5cfee5139caeda784ce"): true, + common.HexToHash("0xe59e1dff5046bb98fcd3f500feddbfc14e4e4fa5325db340caae6ae31322e324"): true, + common.HexToHash("0x760431dddf4ee8333a9729d57a9ec3575539b697138466e3225a61811aa7a109"): true, + common.HexToHash("0xdab8a06aa581750cf3bb82bc7553e881253408b88a68fa722d3f6ec32e3e268b"): true, + common.HexToHash("0xdbc9abc2658bc57bf2c192d11e28010d24b72acb9c8976a8117a0cef01cc9c57"): true, + common.HexToHash("0xb9df3f5e3fa74749b1cf9e851bb482afc256bc74c9bfaf72a3edee94b72b144c"): true, + common.HexToHash("0x00dcf44449a821db89d33342d9715d811beb9cb16b014139a3df82333f0b5eae"): true, + common.HexToHash("0xa7d76d8d6b33d96f232034736567bdbbf11f91635a99f45e239fb19adf1d5a39"): true, + common.HexToHash("0xd69064ad7cdecb9708e5ae3bd5d89b5c90e7de31d9f7f71b5a7b248149e76ab9"): true, + common.HexToHash("0x95090d7a4b00c79a3b13f4bb4f22117a152e73e7048217f7cbaafeacd3516d00"): true, + common.HexToHash("0x95d5848cc6874b89a0de3b60cb20be49833d066eb5451a77d4453f6fb0beee6b"): true, + common.HexToHash("0x7dfaed7fa4b36b813819440cade70a7122cabd6eb0dcfba6bcf4304ee7ea1d19"): true, + common.HexToHash("0x1e494c35c9195463ba4448e17b197099070fd36c9215a25ab556f06e4445d8a2"): true, + common.HexToHash("0x7d90e2745ee1599b9420f0fc8a81246370e4949889d934169d21977ba637a1c9"): true, + common.HexToHash("0xefee0c16ce0c1c6defe0f4a573deb4f149e9a63eb757a5ece17dd05e0daba060"): true, + common.HexToHash("0xd3b02a54d724ee3d2f6c9e232e619ddeee7a8b55d735d69e3cc06f9122842ff9"): true, + common.HexToHash("0x06deb91fef1975972de40b9731bf837d2c1e6e922536c3688b085a5ccd0d5b01"): true, + common.HexToHash("0xae3256e54c3aead997b955b24abc89ebbbabe21083614a27270d4ccc8651bfa0"): true, + common.HexToHash("0xbd85b250a3bf23033d96f864ae2192f57dcfb6563d3e21c80bf6fe626104945d"): true, + common.HexToHash("0x57221148757b0c0f929877f0d294887439d55289fad3f16755f6b8f49af9280d"): true, + common.HexToHash("0xd283c745ab2190d2f515a031ca9f29a0cc99cfcd19d63956cf901c6f2d07afeb"): true, + common.HexToHash("0xd777cb06aa1d2542e9a7e3800d0c6d19487bff23c2ddd03088425e38355f8a0e"): true, + common.HexToHash("0xc7b20704def6480c1461d6577a5f751c5e42755cc7a52f3fc56c5d70bf545a6e"): true, + common.HexToHash("0x2643f8d748ffda1cfec373cbf9b2f0dc4c8d52dce0b5945c35e00d85cf779051"): true, + common.HexToHash("0x5ddd23347903fb46b95e2d38a060fe5bc5a2f4645ee47830b93979bbbe3e4db2"): true, + common.HexToHash("0x68bcd6122e002860e82ad5514408cd2d051e2df3e5d8545e3cfec3c3c1daeca4"): true, + common.HexToHash("0x98b20c47955cc4a153c06a779429511049b19773a5c01e0626ebc592805657b9"): true, + common.HexToHash("0xa2ad0b1c55b4e62389076c4ac340bff7c28291743fa67901d456e0afb14bc4dc"): true, + common.HexToHash("0x0fb9ad81a08c9a6b80b83d46b87df6d6823646ce67d41a64c9bad00d32d5b427"): true, + common.HexToHash("0xbb043eee257368f84b79d1d7b4c028e31e53b5b0ec607c8902e115185ac04758"): true, + common.HexToHash("0x044dfd560773e25442bd1bef27084a9dbd9abf3df8a490a62988fb98f89721ed"): true, + common.HexToHash("0x23fe01a90771591cb848d2506635d62e2a67fbb423ab96ab01a431544a513278"): true, + common.HexToHash("0xa08d19a7e46be60aaf7433cbaafd04e8e6ed18ff14abc058f70dc1d6e9ec7cc9"): true, + common.HexToHash("0xc15ad4573eeaa7220527f790d195f5726131e09798d574dd5dd1ab59e8771d3d"): true, + common.HexToHash("0x941bdb34d0de2985e3b2bbe2ba9e170a8421a42067a1725c89f17b5b7a3cd69a"): true, + common.HexToHash("0xec3d356902227c3813e7de1cdfbee09e7f75172dfa1449aa903671c96be433d3"): true, + common.HexToHash("0x850b3dec21d3d897927012b36821330035674b06ca733fddb1f0cc9d95af8610"): true, + common.HexToHash("0xe4defbf48ed98a310d0a5d8c03d9f9544944beeef04fc75ad497253facde61c2"): true, + common.HexToHash("0x9c20d498d8e0d548a5f16239cd301b7bda9ede6be3f08f635d0e07e283319ccf"): true, + common.HexToHash("0x6577e52f074745a21a41d5839c14258bd752b791b4bc37b459bc84deee2c51bf"): true, + common.HexToHash("0x56768f0cfee23515c068abf4dd9a6654fac6829c53d4f116d5df51bf018d5c5b"): true, + common.HexToHash("0x92bfd2d732b6fd275875e7c115770a9d82fdc0fe13f183325a24596ca861baf5"): true, + common.HexToHash("0xf63368c579f29d381b06420900d6f88a2d6f1ca0b95533e6f65812031bc593d3"): true, + common.HexToHash("0x116ce56823f70b7dbfbc6c7b12f7d318e8a22e05712233d6c4b2525ca8603f45"): true, + common.HexToHash("0x276dbcd8cdce2ea433a9d0e37c037cb1e10b2eba1e2a600db8d6f7b43710f9cb"): true, + common.HexToHash("0xb2c7134e1fdb6b6f21f96c18ff41cbe3d799591393145ed3fdedbd643bae4294"): true, + common.HexToHash("0x0e6128eb1d3d133c1c8ca40903a84d04aca94480916c07763e0eafb7c13301f4"): true, + common.HexToHash("0x15dec2878e96611417d2259c2091f45320038d957f0eb5bf4837f70e68ebec07"): true, + common.HexToHash("0x582173a9a1fde2b1e49394cfcf6d77b52120a4218b00fea7e92524b25489b643"): true, + common.HexToHash("0x388411923cde1a61cfc93c38591cdc05179ad40b95833a4c49dfd8a1c55eb933"): true, + common.HexToHash("0xe8398532b1dbe545a3d66f14f0dcbc7d20d1084541cf0fd0eb4dfae61068cbfc"): true, + common.HexToHash("0xa6d4170db06e38396ab30b4ef99e64a4ea315c9723db482405abf61a916aef9d"): true, + common.HexToHash("0x141b68a5263e6760aa9bf6ccf48cb8d290305f74ec6c97affbf9375559b49070"): true, + common.HexToHash("0xa7b3075a62f5e6537762583bf2af6e1e63d4b6cb7acbd50d3ec63b68da48ebf2"): true, + common.HexToHash("0xf770f3bdb7fa450c24a5307206df029a4e1cfe234f3f1f45e9b14818d02209f8"): true, + common.HexToHash("0xa5791bba7077589b92c5f2cd6dff7ef08d4fe770f23a2cfd224389fea167dc30"): true, + common.HexToHash("0x469c579916899b436fba0dba36ef054725d29420e209695d62f21f91eb073fe8"): true, + common.HexToHash("0xc9f235b5f6f89fb27ba1eb72f9bb245bb13168442e41c4607ccefe2289cf0e35"): true, + common.HexToHash("0x56b43606bb58881e93952a3f8a7488be526a0009b45ccf7875fde8b61f37a3c0"): true, + common.HexToHash("0x9760c4b4b3a693b7505aa91b1c42499cbb5092a838f32492a3c017afa5cb24fc"): true, + common.HexToHash("0xd7f5d225a88eb213e6d26c29c6b8cd4b8bec04d782fe5ca69d770eaa59d7503e"): true, + common.HexToHash("0xb7afd5c1bf912061b126bc0f3f7e610fa7bc451588a669fc388d8710d74365a2"): true, + common.HexToHash("0x9fb54e973303d9b1bd79f7e4526c8935ba86c4536804eec6c6fe64d8dd4dfe0a"): true, + common.HexToHash("0x7b3199fd65e4c1862914ee5205471216d96bd6428ec675cc84f8d0cdf481d791"): true, + common.HexToHash("0x84aee519a05aafcceee2040ca9da6f3f5600af3bb13e4af203451775e0622fb3"): true, + common.HexToHash("0x3c74e6063f556c2e14c03fd3b931a33580dc85028089052f8f902b388e349af6"): true, + common.HexToHash("0x620b8dc5623d1ab41a74c3adb974a3a7e67135e2a53143d75d7779a8d77efb24"): true, + common.HexToHash("0x5d3fb0b963da0a33c0dafcd12d2f87f60ba1c363e14550f42541e52a66b75fc2"): true, + common.HexToHash("0x9809e649ddcc7cdb12f11ef5d962cf0e5f4c198af0a358c735873193d726996e"): true, + common.HexToHash("0x6770309b4826952ff326fa2f7447d9a787a094d231cb538e851c13ab13e536b7"): true, + common.HexToHash("0x477f6e659dec91fbe5359932b79840df5638d48d627bb6dacf0cb7374e4926ba"): true, + common.HexToHash("0x32e884d0aaceeaaa40c8c764e176e5f8b38b836f1e1a78f02906d50ea60116da"): true, + common.HexToHash("0xd1357f46ec15034ada3e42cc2fb495960e2ffa97cb2491cdbaf80b206adcec04"): true, + common.HexToHash("0xf209d73fddb9b6d7b1d63eb6997e099bf88df72c8a7ea2265561bad65acd5f40"): true, + common.HexToHash("0x3b31db777c2ac41fffe618f18fd7678a779dfe25e9bd575d776b8467164d07a5"): true, + common.HexToHash("0x8f719f28ce94709d317c3c3b8e2006c05c84154a9bff5c1acd80ea7bac5e6add"): true, + common.HexToHash("0x2c3d72a36beaade24c99cdeb09086f25cc785d7fc87e34f23183f6cdcf538381"): true, + common.HexToHash("0x49c8c7535b5550138754c345c8347dbd9124b7a216e16241afeab71c2d5d3d8b"): true, + common.HexToHash("0x7eb7abd3e20680c2ca31ce0c76faeff30ef733ac7d992e88751b7ae886ccd5bf"): true, + common.HexToHash("0xfdd84cdc22c154ecb8337d20d6b3cad96585743c8c425a0dbebcdecd4a0f6855"): true, + common.HexToHash("0x5f8c3c84f665cdc1facdc4770c492c36b1f50ebdc8ba1fb1c02e70e854013c64"): true, + common.HexToHash("0xce954d7f6efc89daf8128b6bc1591dca837694e3abe841bbbb870a36797b8c34"): true, + common.HexToHash("0xce344d40000714b001a38d884d6d2694a55dbf4c945d50b456238f6d178587e6"): true, + common.HexToHash("0xccd212b4fd8e4f85cd687854925ff835e966c2689609ae00293be306f9e8c149"): true, + common.HexToHash("0x33c83baa5a98566a8ee9ab83133fab35d8a8f8dd0373903f6dbbe95deddf3642"): true, + common.HexToHash("0x02f19e4db983e83471e6c77a7b2c1c54b7b20199b4746d35756559957dd90117"): true, + common.HexToHash("0xa643f407b530cfef0c59ece2d5cf07189c5f6aeb754afc2e3f0ef4708f02aaac"): true, + common.HexToHash("0x0bd4f656ab2f3ad6c0435fe12cd3aba9346212c9f32ced37cb66b6f030b02d3f"): true, + common.HexToHash("0x7dc8fc45fed9ad35c551c6ec3258e378c83c20f2dacd46494ec3150a9cff03d1"): true, + common.HexToHash("0x6825e1c5cee45e3a33f76139edef0861dba890c2988c6350918eda37e3838db9"): true, + common.HexToHash("0xa0ec2daa0f8edf7f5cce24156370c320e0db03ac6084d5a814d31788bf9c0a68"): true, + common.HexToHash("0x53ea9df663012029c2f3f99e7b341d3e276e1f8d1de6c5b006571f88bac28bdd"): true, + common.HexToHash("0xbc76043c7ad270a2a582d287594f4c96a11f18a9fffe7e9cad44c84bad96fa99"): true, + common.HexToHash("0x8dbd33862741b6aaf467ef55a8fad1ab98b58576eeae779cc75173ded1a1494c"): true, + common.HexToHash("0xc968cff4da4b2630b3f1bbf4db3157abdc84b9ae83bd94c0f0d1c1593490bb7a"): true, + common.HexToHash("0xc01919073e08da6abe3a46f7b39c5289cab98a139b9f19dcde9d8626e9b537c0"): true, + common.HexToHash("0x4ff546ca65aae0afe4af744c516338189b2075048127905526ca69837f5dafc2"): true, + common.HexToHash("0xf72c2edee2e0938f18274264e5460b520f9517adc33ce0d8e26a7a3f1a0dec47"): true, + common.HexToHash("0x050c9fd3a11c5d4094c32f2268a7fd2e67e551bbd122a4da863c06d50e0da86e"): true, + common.HexToHash("0x9e49abe74c43c12925f7ce14dc353a283f64bc971a9d353f7eb64e4e3be47b7f"): true, + common.HexToHash("0xe7dad56b8bb42805c5457ff4d880fdc9a10abf3cb5d6acfa99ab62b6df22e3f8"): true, + common.HexToHash("0x232bc1dc06d254f99fce746cc3ddf85a574073dec78652213027e52a7b34f706"): true, + common.HexToHash("0x6162499270fd6d1e95a0e30ac2e0bca690d7606671c697e24446783e37c0f214"): true, + common.HexToHash("0x0328d9a86f6bb13609aea9bc5cb873c3394546b05a83e6ffb24c594a77980f34"): true, + common.HexToHash("0xa8d568bd0b4bdd8aec8ff09e9d5a3c4e58381b02bb97f50badd7487e249c6c51"): true, + common.HexToHash("0x52a152cc871a08dc140ee281be300c4b7af06ef34a03b104a7c49cb878aff017"): true, + common.HexToHash("0x3deb85998b04b14d9de20fc8dbad7cc167dc4a16b148818f9b0de37f01bcca57"): true, + common.HexToHash("0x2939c0195d624ddca272455c59052916c0c40b43e337452bb20d706fb8dba8d8"): true, + common.HexToHash("0x25a5592b567c5515f01fcb4bf47a0428cbbbc679713e4b0b24c40ba7cf462dca"): true, + common.HexToHash("0xdf44a903dbc591a83e9d35ffb4f8160a03e17c00b948c1574bcfc00c872313f9"): true, + common.HexToHash("0x1a4906116e4e88f87534ab97c4d6d07ce572cce6cd57116a68dc17508a39b066"): true, + common.HexToHash("0x20203a119f1bd46e0ecc30e3b4f042823b0f7db6b367b9a6cd6f05cdb26f073c"): true, + common.HexToHash("0x96b7954f6638adc85b1a306eb1f6c346fc44d015685ad674b8f9b803d2a4e87a"): true, + common.HexToHash("0x9a8b07da5ce685dc9d71ed37c808ff43b21a560f4b056e7602c81f5a12aa7794"): true, + common.HexToHash("0x3226a878e6c71bb5f0c008a038cbedb46b5dd705b06070b016d7c5ab20e0a299"): true, + common.HexToHash("0x58e1b36b1007076e6d7f3d0dc7c8c6dc333b2d2441a628d73e4beab0a0f60a75"): true, + common.HexToHash("0x95c333665dcb3e7f8c9beda22b9e96f6b12786ca7cb841d27f840bf1829803f7"): true, + common.HexToHash("0x219e25391c5742d062300f7872b28f237e54f45ac9ebdeb550334924d39723ab"): true, + common.HexToHash("0x7eac5f5e2c4ccdb5a0cdec178f70871860458297f08d94a812c8131fa3100000"): true, + common.HexToHash("0xf785731d0c27ce181516cff244bb08c4f8595b92d13b2d8304fa4e0f64150fb2"): true, + common.HexToHash("0x92666ab58d4587876da3b58567b6724bce797fa8814acea921b51ce13a3c9f4a"): true, + common.HexToHash("0x331587f900f24f8dd8a98a86f18e8ec6694b6aae01b13093c0e80de75f0af7be"): true, + common.HexToHash("0xda8f7798910a4093ee85ba8b8cfa7801b20ee5d75e26729abe3900ba4c0a6cdf"): true, + common.HexToHash("0xed9b4d15a71ce1ec0d27b4753610f8e97ce70ef0e7525e23c89c5b7b2b666ae5"): true, + common.HexToHash("0x1fbbc5254ce4b89be1b920eadc1811d6fbeb2b7cafd21bb316cb0aadc96a2113"): true, + common.HexToHash("0xb4c9553b2ed671eddd4ccb9fb616f3741bfe18370c7b024c6ca9b888dbbc7e6c"): true, + common.HexToHash("0x9f99fac4fb3f010aa3ea8427fa639d5ea2445e21b7780abd1626d1d59bad1b32"): true, + common.HexToHash("0xbe24d6e3160959b0641d77cab6b64d60ff6b207b35c4c58c1cab4b5376fd051f"): true, + common.HexToHash("0x3e73bdd2a71fdbc72d71e67f1255ea69720acaa4c4e69ba5c87ee641dad72532"): true, + common.HexToHash("0x9237ba16d134c1debaa0f20afe5d8d9a77a32d276af2531a509c679b2671ea35"): true, + common.HexToHash("0xa965c6999f4689e0022ad48494545ac3aaca0ccc8553ef8f90ca6d291e572791"): true, + common.HexToHash("0xe018759f58ab3916703bde7311a1fc7699a6691b7ffcde594a6d6e1ad8c15527"): true, + common.HexToHash("0x3e4c47896ca3df14075b69a806c1a6793b308d7e6d3dd91a228377a4b494bde0"): true, + common.HexToHash("0xbfd742c3952c3b13789eb13016d9c1a9f9cda6e4dc917a7fc903ac9e744afe6b"): true, + common.HexToHash("0xaa4200a9ec183684b5007f0aff0b5cff88d68dc5bfbb75dab04a9621f9553252"): true, + common.HexToHash("0xa31ce348adef03420f9be75fd67c66ddaad8a75aa17f25e3ad0f543bc2ac6a0d"): true, + common.HexToHash("0x200c172921b5093fe45852ebee026c16a7e6dbb51ecb32c39530d4c99bc4c959"): true, + common.HexToHash("0x8e6b3d0f7db9f55f779eee7070bfc36e287916ccf53809c60bd6cd0c10c19bb7"): true, + common.HexToHash("0x726107ecdd7cb39bb36cf92381473fffeab6c58a283892651b945103e736c271"): true, + common.HexToHash("0x9028b9dca10be4efdc6471e428e70ded8784ef18b4429659165ad630ec53e689"): true, + common.HexToHash("0x2ec64e33f129bcbff1231da4ccb059e6f9864d2d8461cb15a306e5f018620fa5"): true, + common.HexToHash("0xabb2f35c2cdb700c083f6524ee2aca84b9218dbf9e18c5563cbbed3523d37bc6"): true, + common.HexToHash("0xb7dbf27e033c62df67201bc65f167d055bce2e31a33e974ee4f57b49b0c1eb7b"): true, + common.HexToHash("0x6352252c3e02f7d370bf7a4e2aef92376991cf125e5fe13dccc0d4a62f782121"): true, + common.HexToHash("0xcd9506352f2e7b5026172c54321e231a829b48ced1aba7daff02580b31b6ec89"): true, + common.HexToHash("0x806fe5b45837427f86a0c1859cd3b86cf70d4696e97eeafd068de91b7a9493b7"): true, + common.HexToHash("0x76566bf1e7a72f3ac872ba0262c6e842c1d8288ac5e9f9e4f2ff0bf0323544e4"): true, + common.HexToHash("0x37aa1b69b36ce3159f284e92de597c7a09f4c5b2e7f876c9e18d395447c8c9d3"): true, + common.HexToHash("0x244849a69a2cd9427fa170b3b4f26dce998bca0c4075497a7b5b8aebf29b7d77"): true, + common.HexToHash("0x863beafacaac7e87bbae35d65ba4048562088f8a2f2ed5fa07aef9aa622dc05c"): true, + common.HexToHash("0xf357b02dd69d013ca9c9fc6d5eec8e3bdb3c324c094e0d3e73946c32153a1472"): true, + common.HexToHash("0xa6bd708d407d560c61761f3e7a9c67e58ddb251616d92cf51277282ddf453b28"): true, + common.HexToHash("0xc9e9e1549d5b358f8b8ffb30047fa79a2572ed5953f3c0416dde60c167814749"): true, + common.HexToHash("0xe06bed9258383b7fbf7712dad9dfea86803e776bcf2e73b6609a3f5f977bd1c7"): true, + common.HexToHash("0xdb294d3394bfbc0ea5715b06b36e706464bfaf3b072d4dc0b8602bef6c4f7ab3"): true, + common.HexToHash("0x47b34fe04d7fcfd648151b30478f7598a3cb0d0f9a19b429f6b7606aa21c7848"): true, + common.HexToHash("0x32dfe2f981b26073dfb90ef2b2722d64be253895055d2828631dfcd761ceb885"): true, + common.HexToHash("0x0986f10e912df70b1660b12d04ea3c96468ebdc159e2cb659a959d7bc4b6a8ba"): true, + common.HexToHash("0xda47642caf763ed5d96a80fd447b702c380bb0e9eaba5a1d7edb53bd748971f7"): true, + common.HexToHash("0x73f1071af70152d89ade311fdd9e3c0d11972d828196bcf975590ae29f7fd65b"): true, + common.HexToHash("0x9e09c1e886251a2d1898cf4f8ae8facd55e7b9b0304d7849381b81abf2649f77"): true, + common.HexToHash("0x5802935924d8ccba1ef1459b6015e702d2de31a47457fb4915893fa3b575db76"): true, + common.HexToHash("0xa2b6fb0fcd7fa47f37e30129151fe5af643bafd0986209db5fc4c74c5348adde"): true, + common.HexToHash("0x2cf4ec7576359c6d3f506ab5d8d738a7d334481642f6cc0d722d6dafc7576f27"): true, + common.HexToHash("0x70fcaec40a1c954e88f7bba1d4f76feee032c5891f3f5ed439a29c7931e414f2"): true, + common.HexToHash("0x1f9a7c5093e497e4d121d96e5abfb750fdf6a45955e1f729998ca9d90f72d109"): true, + common.HexToHash("0x0347225c6e7b933fce84274b29175ab007b5a0bbf29852bbb86bcd0d39fdeb3d"): true, + common.HexToHash("0x96373dc439c434b4f8ddb8edaacf0ce22c3ec2e06cbb111ec699dc80d56b1af8"): true, + common.HexToHash("0x8b99dd2d78bc1bda6d858e39bee52dd90fbf1e219bcd076d9983332bbc577957"): true, + common.HexToHash("0x5597bf971ed420763e74c1baaafeec60616b94d36796cb0fd82769181e69b0be"): true, + common.HexToHash("0xddae7858200892bfcdc1814dd26061d4278ffdd3ee39110d68de5b9241d22c4d"): true, + common.HexToHash("0xe189e0884feaf93ef8b7d66977aaa006e127c13d87d05066019d15dc503784a9"): true, + common.HexToHash("0x66cdc9984dee4d0f57b9a2d41bd30eefbea6bab4758b4832a146757e8422f7fe"): true, + common.HexToHash("0x0bb3996a1e734ae3fe3f56657a8887583c22ce37b15a5339894a296367186cb0"): true, + common.HexToHash("0x87ec088a2b63e61d632c00bdb4e3a474cde96a93545a589205ac661033acb18c"): true, + common.HexToHash("0x7f49af48ccb1e379ab9f1c236fb3de416c34b7b6b4a8d2492d79286027e0779d"): true, + common.HexToHash("0x9d81822c8796bd08ac3b4188668fe34efec031f25a4edc6b9e0cf7b2c7b2048e"): true, + common.HexToHash("0x5446c5b10a33d95a30131956b97cd009da74e50f38c379d2a1e2784e8fa93fcd"): true, + common.HexToHash("0x12aafe76d9a3e9495f8504c9c6c3efedac1a51b59513c52779fb60fe62d888e5"): true, + common.HexToHash("0xe9f59aeb429940d4d8209f19f93d643d6906ed7e49189c376fdc2ae5576f257e"): true, + common.HexToHash("0xb9f8c1461078b48a805b446d3e9ed46e1d8ea7f2a0ad21c03d529bfbb6fe2d52"): true, + common.HexToHash("0xea6d98faf7d84138c421f9dddb2142c10c05dd636edb567e5c7dd6cb46947e2a"): true, + common.HexToHash("0x62a9af03898dcaf8cbadfcb38b46d9698147f32917b4f4e8afe03e6dc908c5c8"): true, + common.HexToHash("0xffe59d4ada1a4f8f2bc8b2795e85bcc65dd2c07f9aab2e26fea35b49e8888ea3"): true, + common.HexToHash("0x89946c502bffd1e4191614a85f00bf8c61c3bf2e36d6db651ca3d07a85c8e931"): true, + common.HexToHash("0x7fb63e8acf62699bdc7784b5ddd6f6fb19e99e21de350b9583342276315dd746"): true, + common.HexToHash("0xa816997c83a8d11075f2e4642e620724d44516346aabc7d6495b2c47fc020f17"): true, + common.HexToHash("0xe372c4d3dc170e2d29f27ab150bece46560958910fd4db24498211414dde4a29"): true, + common.HexToHash("0x559499a6da9285026309fe73430783f0543ca97eb5e6a4c7790edca36c419886"): true, + common.HexToHash("0xf4801a941a6b32d64c19aa5c3c7e4e83dda0dda533b93e341a9ab50eacea0c6e"): true, + common.HexToHash("0x241c493662a8f74cbbc35c68b02e1902ec5446038aca9acf09873ccf02c86543"): true, + common.HexToHash("0xb8cc30d618b5e7c4de0d5c0e14b28c2c92efe98ff7cee37dd44d7b3397a88117"): true, + common.HexToHash("0x1b728b8fa0252d2fc581c9b11aab615420c1a956fcddeb0ceeaeaa44d4578ff1"): true, + common.HexToHash("0xf1f173677e465ab8b8d508b4b6feb02144ab9ddabc16c121359dafa77f35e640"): true, + common.HexToHash("0x6b74209c1009af5fba6f6b26b9c8ca7794aba3b9f103c3f0120dcc7637fe878c"): true, + common.HexToHash("0x44539d472128d052ecdfb1b9a9c595343be3325147dff18ba9c3b8ae13672b8a"): true, + common.HexToHash("0x886778dac8b76d8b59fcf4ce122266bda427f3ed8627aeb441360d25b17b5c58"): true, + common.HexToHash("0x8d7be1c2f7ce80d689c90202786acf267eb6f7e2c8b54ad47277026aa2c01c80"): true, + common.HexToHash("0x7b08bae17fd59f3c462e72f06e4d76de5e33b114b84659656d1667189bbf74bf"): true, + common.HexToHash("0x85f750fce2be408ffc5ca762e47f29367a2210b45f10ab21e5589a3cef0c05f4"): true, + common.HexToHash("0xf96796b862f0d70b719a1f64659c7e476eda4369ea3eaeeb448c8600d0664ece"): true, + common.HexToHash("0x5cb7aaf532b563789a61f34bf11f3fcbb843d2f8183907e38f4afb1d8f3f2951"): true, + common.HexToHash("0xd38ae6031c5a2c53ab7e9fc210205cda07ca9222fb82b2c5aba7db191abf9945"): true, + common.HexToHash("0x8da36a256d7123ada1356ca077b0cb94ebf7c9a59830e4266e8a2309167cb892"): true, + common.HexToHash("0x4db79cb147961dd03a5258f5e174c3345b6a4fc11740c6dd591f2064c0dd4da9"): true, + common.HexToHash("0xfb018c863588236ba96ecb6b65252378e60f7aeb4002a40b3528d448773deb02"): true, + common.HexToHash("0x2560ca2a8c44c951797ddbeb64080b67dca75a14f299262917497482f416cc44"): true, + common.HexToHash("0x042366ddff7d1614444564b1f327dcb07efdfd95fd9904099947e916a9a23300"): true, + common.HexToHash("0x886f61f95893402bfeeff08c253c8ccc31170933db94ae27812473c16e566e8a"): true, + common.HexToHash("0x357847f01be226b7e2d07283f0a4a167f20fb23c01709b6a32ae3813b603154b"): true, + common.HexToHash("0xaea9de6fe0bcb9894aef4957b2389e1fe6b030619c66f1dcf344fd4de3598eb4"): true, + common.HexToHash("0x49299492642bf40731738ceb26ab98cc8108fbda671c2777edb4211f847946aa"): true, + common.HexToHash("0x5b878ec43c3a67109d5d6a87a0c97bc65d451ee7e86a791044031135c02e6918"): true, + common.HexToHash("0x28dee1b9ed41a721ff35c338648a1f640f3d70451e879c50d5654e2da8a17c77"): true, + common.HexToHash("0x1b7e7084646bd8f6018005ed5390c8b5751406b1a8fe85dc6b100e60cc6de19b"): true, + common.HexToHash("0xe53b35125f87aa5241b481a484c201cc225d29b11eb095e5023f8ffba95b7393"): true, + common.HexToHash("0x21764ba4176a6616f502f2060e1d7b3ad48e534a073cc0607f97f5b1e05c94fe"): true, + common.HexToHash("0x1d792e2be48c4f7bbb96f9d9fe3d6b85f02141eb684f1afd6d87284c7a8d8e96"): true, + common.HexToHash("0xc9780f514770caf59acef153d8f61bd6725645395ed85d5feab26f74394ec04b"): true, + common.HexToHash("0x5ff3fce2e046f522623e1332ecae2c670401d59392acab74798e63f59cf0fafd"): true, + common.HexToHash("0x78c80a3c747cf413e9369cdeface857d1c5936654231cfbf3d36b6a7215a9598"): true, + common.HexToHash("0xc49f68aaf42dcab0d1cd8150ce92eb37ba77914f225628045cc532525cb9a91f"): true, + common.HexToHash("0x3a6abbb2c57102197fd6af4de605f45e6f46e2db1b8652ad0f230b2067ccb687"): true, + common.HexToHash("0xe0794ab2ae7d694dfce8950c85e429459a1be428c8583d6743946eb8247877e1"): true, + common.HexToHash("0xa2e96ce8209458d4e028e002ef494b8772282673806ce38616ba92c4096e0eb7"): true, + common.HexToHash("0x1c235ef0ed61c0f2d15913746ea08b4a76b4b4aae8fed859a296cb6d075e30da"): true, + common.HexToHash("0x51a24434fc6d2e5a052964d47e30cf738290ecc7e526ef5c301b62d54a6b67d6"): true, + common.HexToHash("0xaccc9b11ead907e19fb168f0d1d4adf7b59f375b1b7519d207e7eda3bfd164fc"): true, + common.HexToHash("0x15353b48cd895a63258e54a0ae74e5752bbf73a820b887c6dc0d729c87c4a9bf"): true, + common.HexToHash("0x7465d3c26cfe986534f7118a89542cc21bf606ea8f9efc0e7a84d1f0546c6e28"): true, + common.HexToHash("0x4697f98acf123951c31296d32c0639774d4bf1fcef24709b13bffa60344807f2"): true, + common.HexToHash("0x4f98583985c7803128bfd3241e696fd8a2b047701c56bf8776efe2ae3e1635e0"): true, + common.HexToHash("0x88bca7bfcf9d1fbf080b81cea9ca46c1def0a7702e418e2323e7e83e0d768b48"): true, + common.HexToHash("0x9de2c7a157c31965586030a85bcb8735c80a8daa256f450ac5fe190c3aa1bdb2"): true, + common.HexToHash("0x3ece6b59b7e9c5154204e77d3a464e3a1c8f5476867af52655798ba9ee36631c"): true, + common.HexToHash("0xc42655d7d24fe01c8930b27fdc5dd323f4ca7ad6e06a5f33f1de0f5c2fccfa26"): true, + common.HexToHash("0xf313543dafdb0a7694441fa3fe74edff6adfb8f224899964b445192b2dac86e9"): true, + common.HexToHash("0xaa226442f24140c4e09c1d180955f6685dfcae5dfbada255965e761805cecab8"): true, + common.HexToHash("0x875e8db848af7b6a05d22c13176f29d6c8862a64da9df8eb1e48225a65f43d3d"): true, + common.HexToHash("0x2d4eb50499394dceb3fb3f8b08897f6604bed65414fb59102ae67cab9b275a94"): true, + common.HexToHash("0xc7dfafecf93a254a9d49439f91e5c8d53e5fc6052b319175eac4e6f8d6e94115"): true, + common.HexToHash("0x26e1377a32efcbd538719174843a1c22fd88f3454e25bc72b4666ee449974262"): true, + common.HexToHash("0xc58b4ffd53dd86c908adb58210a5420c33af0aa6c28f37c045ee2c70919e450c"): true, + common.HexToHash("0x2ea4ead79f638e717e8e2f2f06925e735f7a9f09db95f441ebd567f9b2579c4e"): true, + common.HexToHash("0x0f066384cb016a2a548ff934df2f2aff45e4ff23afe32fd1291162be917547cf"): true, + common.HexToHash("0x18bd2ae0561a3411660fef4087f3324118578df11c5f0dbe4546abce37f10865"): true, + common.HexToHash("0x0baac09b1c7193e7c90c6ef6553f92aa755b49302879c183f7edce21d4039d0c"): true, + common.HexToHash("0x04a632f211d73bfa013fb5eef912a6ac70cf6438374caeadc8f61fb7b8bfb1a3"): true, + common.HexToHash("0x10a0b69248bfe8daa59ab3fba5bd74f46a29552989199557b98793b81199415c"): true, + common.HexToHash("0x1139732d13c75babbb0d9b178d54a5da7fb64879de0ec504386c456aa36c3617"): true, + common.HexToHash("0xf60104b0dd2f3505ab8d502d2848013e83edf403dc617dac09e7c9c367b72d17"): true, + common.HexToHash("0xbd1fe8d6da71b8d5d8368c29470db4b747a92c5dbd9524ffa6395d9d7d807dc6"): true, + common.HexToHash("0xf1f51849e656453c36395806d945ff8eef2786a6e09aff6d8b00c71bb733d732"): true, + common.HexToHash("0x1f3bc9b06e1d6b7573ec76dec4b3b351264a7b674a7b832d10e9ec3e797e4c07"): true, + common.HexToHash("0x8963ecca93a06ddf4f58518b1ad1e984d07c9bed08227dacfa2ceb2664d2335d"): true, + common.HexToHash("0x96ec872759934ae2162d41290a76f1d81a0035bd9e27d8b0ef2e76884ad0c253"): true, + common.HexToHash("0x0d9437b22c4efb03362f1e3815acbe33e4bf941406bf0e2ef79759b08309d934"): true, + common.HexToHash("0x1eb4acf9deebded26de94b17ede285cbd5a0a0e5dba4f2f13ca94a3ef2608598"): true, + common.HexToHash("0x93aa683cdf0da08387227f0eda5e0a0f87e0bbe912e2afc218c89854e3be108c"): true, + common.HexToHash("0xa283f2dbf8dc7c70ca436da1b9764795996d7853d1a87f23df05564e16ef6e2d"): true, + common.HexToHash("0xb915c938779a8baf37b7ad90c295a68eb1d1706eece45798e75a2d9985e6d0bc"): true, + common.HexToHash("0x02dab0b2364da882312f0b9458cd8cfba9d74f54b14b8b3d43f901bfdd72d81c"): true, + common.HexToHash("0x2bde4edb26d6ab52c51c144fa7726ab469ef820505a0ef6c466499e759aa75d9"): true, + common.HexToHash("0x0dc4163788646b39bf8204c3acb2198305e151836fc96519ab435e0e82f3e172"): true, + common.HexToHash("0x1b3d5332bacca5380a1cac1fb8b3eb81e8a09065dbaa1df2e14c484e75946c6f"): true, + common.HexToHash("0x81c979ad3fe7557fdc7968f5fb2b578ed901f7663bf003b75d45ed0098de3c3a"): true, + common.HexToHash("0x7dada2b150610e1c51f54b5a28846d02569ae058c320c032c009cef32f8904ea"): true, + common.HexToHash("0x23cc9650b3b588a106deb611913d472b36e87460f846f516d7f55f3c62e41695"): true, + common.HexToHash("0x541aaa5f0741d14e10e65643676e293c7c014f14a008a03207f20b929c71e81d"): true, + common.HexToHash("0x820447db9ba661dd230ddac2b532919759ad17f99e41d89e40efaa4dc0cdd6a2"): true, + common.HexToHash("0x7c6872be09481e707cc57ccedd9ce3abd0cf63bd2224214ef9f0c3a4bf2c0a8d"): true, + common.HexToHash("0x7e464cac45f6412d6b470e77fc1995fc1cc79451918c7fd920de7431c34bd221"): true, + common.HexToHash("0x6bff8e2d3962f263f64fc218de5cd414649671df1b0fff074caf2d8ba3066b88"): true, + common.HexToHash("0xdac07bb308f2739967082c436b5d879910b6f1951f48553e69b5e8af3f0797ad"): true, + common.HexToHash("0xbeed61f3dc426c7d0e480b91adb27e81d62e9667ab390a22cf1215d60864ab45"): true, + common.HexToHash("0xb7f61be8b8876d55fe74d224436a1d4e04133540543711ef3cc1e795d997c394"): true, + common.HexToHash("0xfaecfc53405465984b8865ec7674a7f57b1b582575b3e31fdaaa7e344235f5bc"): true, + common.HexToHash("0x56a6e59283e9bea6d794a4fe24caaa0bdd0a099cf43852cb14ce005e3a632f6d"): true, + common.HexToHash("0xbaaa8d02bc81bd62fb83c8dfc493418284e8a5b45029d2764ae709e336cae5db"): true, + common.HexToHash("0x3b7b206a366d5d3ba8d6838ede001b0bdb2d5e7d1365c3afd35939cf472a3486"): true, + common.HexToHash("0x9e6198bff45a4943bbfcc16e2902f3a0f7e2cd005b1cd99321ba9220630e275e"): true, + common.HexToHash("0xb788eb70c99238adea02ec8c4cf0b9d984f4e6c6df4038983ad3716ea64ce793"): true, + common.HexToHash("0xb51b0b5c747ba34b9ab9552e57475b6afb9db3ef002419b27873f1c6218d0af5"): true, + common.HexToHash("0xb8ca3d57971f0b95091a09ac00650c4807dfade1e189786d389d0a2bf2fc2990"): true, + common.HexToHash("0xf491034ce86325a5a1fccd2d92833ff08bdfa97cd184ae42c496bc11c058fa2b"): true, + common.HexToHash("0x1c19d95682bd740d8bbd3fa1dace3289e1839d0cad977686a32dcea397fe772d"): true, + common.HexToHash("0xf896ddce3242cc1a30e9ace9a0ea91fa04e0497fb4b6b54735fe50ef780bab08"): true, + common.HexToHash("0xe46e78940220a56819b9dee1822ae91c1299ef07c801d0b8af2d912e7de112d9"): true, + common.HexToHash("0x0cb0e214e225d32606f44acd6e2d9ccc34e0eed8b19fb56188bcfe32bc0a9191"): true, + common.HexToHash("0x4aa27ea70f692736369afa4a4837e29a7ec87512dd554388b8e7e86272fb6f80"): true, + common.HexToHash("0x0ca211ccfa8caa23ad17b107b6120cea78092e2388e759e11abbf4c1f3be507f"): true, + common.HexToHash("0xf00ca444c751fbce2fe552486de11170cc0c908ba2db3fa30e5508fd67411cdb"): true, + common.HexToHash("0xa239c0b23cf219b700843a77f26e4db2ef78679dda03e42b20d3e507f7cb8fed"): true, + common.HexToHash("0x709df30085afb2c5ed6ee396dc12e6fc01100a5d478dfda9b13f69d58793c702"): true, + common.HexToHash("0x324d4dc45a69741796745dac2c1fcd73ab7562147c15d2fb41ed192acd890729"): true, + common.HexToHash("0x7695c61224dedce27e51f6d2af0aa4b775758a0674dd64512805ea09bbc10b5c"): true, + common.HexToHash("0x5a4580abb2a47717a2198871fcd0ae639f0af16b5157cdf235440181626b077a"): true, + common.HexToHash("0x23e1377979cf91be36db935ff85ee206c268dd287eceb8aaab9afe125731be54"): true, + common.HexToHash("0x2eb8c86a155a000e29488ebccc5cfafd3e6289fff0806d1fad581eb8e477c3dc"): true, + common.HexToHash("0xcd8dfec9a10411b495fecbbd15748a4b55351b72671a7ce61a7b67759eafdd46"): true, + common.HexToHash("0xff4eab1458bbc774183082237e668d1c0406fe147caf9a54698e92220bf4de34"): true, + common.HexToHash("0xe2d1c6747f2e98bfe09d213f2032ee61f57ec6d1208aaeddb1570689a771047b"): true, + common.HexToHash("0xcf4474d465538d73840d94a2a70df7204e942e4ddf7d0c0ef4c836321b0e6d39"): true, + common.HexToHash("0xaf670c8aba387f4a15c8333bea04dc337bb9fb2a70415752197cb1051af69a4a"): true, + common.HexToHash("0x0055877e3a3b63fb2f5981991305714c740253dd6735df91f66fb54ed88bc7b7"): true, + common.HexToHash("0x0bd863e94918a3681b0d6c22da865241bc2f004876ecd545bc46db84eac52e4c"): true, + common.HexToHash("0x1d86ab895be70f7b804a7ce6e63cc2453984887f703e914152590a2c99cd3dd7"): true, + common.HexToHash("0x0e3ea0cc262ca864ee9bca0634c6ce0394ac0d0fef78185a4214bc4a50845289"): true, + common.HexToHash("0x0c0a1dc0658ab905eec1e92a3e8495d3b551f32761a5cfdfce3e5b64b05885c0"): true, + common.HexToHash("0x2130e29f2b16ee0803f38f2e97f278ae63d4f2b071ef3614cf2b137b1e68e2b3"): true, + common.HexToHash("0xa35792c1bd02098729999279503984046acf8e75d6d8b64bfef66696368cc9b4"): true, + common.HexToHash("0xfcae3d8a9760eaf1a78d47333a68812a1303ccc6728949c99f7c5d1b01009782"): true, + common.HexToHash("0xc979abae2fb24d14db5bdaeca333dbe5884a20fb6bdeab85f8eefe99ae1f6f5f"): true, + common.HexToHash("0xff72c74e6e2ebb695cf0b815183136180f0088171e4a6d57482f380bde29fb34"): true, + common.HexToHash("0x549d2f7705424a62c755112c08ea070a98591d84d819f143827a764171ddb57f"): true, + common.HexToHash("0x08ef9a942b80a2fdf8bca060df2686b3706ad78be1da7bd60304f32df1aac1ff"): true, + common.HexToHash("0xac219324ca29c767317cfea9de2b55195ad4a720fbbf2befcf9aa674a40fb3f6"): true, + common.HexToHash("0x04495b9c4c145e7aa4aab9908be2b7931a0d8beb91265ff2e7df8393c3acfdbf"): true, + common.HexToHash("0xe21d2adf90e2bfcc6a32ba60b582fa5bd1b46cb0567360a03cf25be3c9ca9e32"): true, + common.HexToHash("0x019999dc1491b0bea7afa454065c773159fcd8045d57f095cbeb18d87bfecf33"): true, + common.HexToHash("0x552e368418c18e3bb173fa7b9d8d27adc9ffa8d02f98d525d0b96c8f6ffcb3f2"): true, + common.HexToHash("0x96bba0118dc7587ca0be5109801210a37b74f89a27243828661a7f0b129cbca9"): true, + common.HexToHash("0x02728b9cca6ff0fd28d60464c5334d93b5b604713bcc25713de41b48cd606b96"): true, + common.HexToHash("0x047b1406fdd79197b28ca1d0764b7acf3938515efe52a5b860a4573067474360"): true, + common.HexToHash("0x6f2dfd7d82e67ea743fb57a07175bff7c307e2d548be91282a3e89d42e0ff16a"): true, + common.HexToHash("0x3ce9eb66c50cec7170ebc5e2a260f6bbf59d98fc5c3107d9c650dd2cc843e66d"): true, + common.HexToHash("0x865d38d3a0ae2b2678e41ce19d5ce4378fcc8d57c1c5be3ef5c6d1b883635b9b"): true, + common.HexToHash("0x435754d523158fbdf4cf025f0d36315f4e2041718cf0aabc916135a96a40b79b"): true, + common.HexToHash("0x483d9bc3d1311cca8975ec09a6b8a9738b0e70977322f4a6342ffbdcea076fdb"): true, + common.HexToHash("0x0faea770bbacf84d9513d57cb9166a9bf1a1ffe7f9ed8640ba38eb20bc243856"): true, + common.HexToHash("0xe2424a4c02769d961e332a89557151c6709f4aa2692349adc06cf192a1fe7eed"): true, + common.HexToHash("0xef9c6f7842c7db05dcf4e318a479cc2200f37d1ed505bda935dd692118e9d980"): true, + common.HexToHash("0xc77e463bc09f718c79fec3aa8edf0af6bc33cb7d617d82aa95647402fc87fec6"): true, + common.HexToHash("0x5fe979a29cb561a8fbb07d0bf726d8ce436b55958b536b372ba266b1f7831114"): true, + common.HexToHash("0x0d404f68ff280153cc696a38bc4ddc9e821b4277927b4f18c644cc7f7bbd7446"): true, + common.HexToHash("0xc6095e5b6bf2532a197ba494179eb53016178a4bcee2f650f68604799376f03b"): true, + common.HexToHash("0xfe847789286755183ffa352ad5bf9fe62639ef4e15f99163658500a88f99e609"): true, + common.HexToHash("0x9f513e2bb6552494dd85c8ce855b86192efbff101c0b88e5789b79b606f6ea74"): true, + common.HexToHash("0x30eec58bdff4c746f67358c11a59c8590fd840220329a5e2dea03551e121d037"): true, + common.HexToHash("0x6c5215d896f2ea47985de79a8dbb29820112ea1c8f7cb27ed8c4883929aef1b2"): true, + common.HexToHash("0xb370a580f3c79bcfe18722896ceccedc091c446478ae7c4930096bec0e4a1048"): true, + common.HexToHash("0x92aff6ea0f687de696a75c4b77e2029860e5c5f1ea4633af8fea9f9d6eee046f"): true, + common.HexToHash("0x464424378775721089f0eb6a21f52ffb90fa1c1d933b5f78ab662dc52b2d9415"): true, + common.HexToHash("0x84ece4840113dc399a60220e5e74e27188d85401cb470d166774e5acb7857c8e"): true, + common.HexToHash("0x611c744c429c3cd8f3ac63e5345c1ed40bab341a179ad470e5c52732fc7f969f"): true, + common.HexToHash("0x645e16b7988308a790aaceb2eeb71f9081a98e9038b8981740f61312cef28b78"): true, + common.HexToHash("0x60659ffd3013bec44d6d18ccf3b3740288b1de098df656a1cacc8a35bc526eea"): true, + common.HexToHash("0x739fb3c773af366bb5dde8a6cf46b1b32025d4f5fa18f185d6342788a53c303f"): true, + common.HexToHash("0xf4e82ce05482f870fe51bf6d8aa2b69c0d02a5e58f136baf49dfb834ea21b3e0"): true, + common.HexToHash("0x56b91c2a101ca8cca720a37121b319a65608a54d8680445e547bc84bcb932d74"): true, + common.HexToHash("0xe0cd9ed2e7be59508e6752c7089bbf6ad300943db647517f3e7b387171b6c464"): true, + common.HexToHash("0x96aa2619918cc639feadd9d1e3d39260ea94171c3322115ec0d490392867df58"): true, + common.HexToHash("0x15081b80c4f7b0165051d1aeb8fce38acb65060cb40cb18c5bbeedda3b9f4a69"): true, + common.HexToHash("0x1784d16964f05f0617b11d50c20c187410fddc22b6fe608ddc097a42bf4c6433"): true, + common.HexToHash("0x91b06a8fb35aa8817bb20fdfd43cc135486ec3e3a42124b0ccc14f1c2b338af1"): true, + common.HexToHash("0x0e26d9c045a3e8b16a70ccffdab6b5815217b5a1d301877cf01bdccc42da9691"): true, + common.HexToHash("0x58179ca5d70caf29d9d6c473e4d0265547e926850cbdfe6be51a7748d7551098"): true, + common.HexToHash("0x56c1ecd5fdb9ce622afc962e182915d73fced88eca5b58f3293bdcd29a8c736b"): true, + common.HexToHash("0x99da6b54dd12143d0f6998e140b7c276ddc287909a4edc60c8f7f7b9606751d6"): true, + common.HexToHash("0x3fd3271921961d5d75d70232cbcdf058e21ac0554c6eaa86e5898cf395fc4ff7"): true, + common.HexToHash("0xe62ed5d7bc79b84122f928535bbd2e56e92e952db13aaf7d4bade7291e56201a"): true, + common.HexToHash("0x918896296820cd42d0e3a03187df159da4d9a5e0e05c5232f3eb7b34ca1b286a"): true, + common.HexToHash("0xb00deab537e7f14fc9cbcf1f35ac446c7b29d9e89072201c8fd38b34585e5f64"): true, + common.HexToHash("0x96c971e06ce04ddb60a5a075ae9162301e38cc1371c05942217c6cdde7e828a0"): true, + common.HexToHash("0x25ac963f0fc24cc0a07965a9383908ac180db5dc085ec12cf3943538afc7e178"): true, + common.HexToHash("0x5e235705a1528f2f88f0a3e972b920e934fd9a015b1419ee89e8958ab0f979f3"): true, + common.HexToHash("0xbc076a2c39d8c382e7560ea56af79f339a0d51ef4df42a45cf71ced0755fb82c"): true, + common.HexToHash("0x7eb83924468e2777b597efe71559cd9877d29992851b96ecc19712596c421f96"): true, + common.HexToHash("0x505ca2d0c56f04cc6382faff58e014f7d551cbea16080c8026121487eaa1eaa9"): true, + common.HexToHash("0x9923f82f546073d94185f564eb261f654ea38c8b04f58274d19e86c19306a43b"): true, + common.HexToHash("0xd8b7e039af70f053dc30480ad4e36409700311fe784ec6721ab4dca8d9741688"): true, + common.HexToHash("0x80c7051783b616dd2c24c9655c861258bd6bef4808d70dc3dff3f29c04cd47ae"): true, + common.HexToHash("0xc4a39cb28b1f23f72be99ae105b3c185241b43d1fcbdd0f3e597fa4f3387fdae"): true, + common.HexToHash("0xea49902ea93178f95d4a4cdd704f7af3005e5faad15aa5e60c3733e20f714004"): true, + common.HexToHash("0x0573a2aa8fdfbde2e33d4c95d938c6ae56c578e15c02ab82083532c1c235ee83"): true, + common.HexToHash("0x2c9f4b28da0830632510a6a19681425ee64f54061f5869dee7d3b946662dc5c4"): true, + common.HexToHash("0x33cbe2a048e4b3cf3c95b625c17aa41e3a0703820b6ee50b14abb7a2dc9d3ea1"): true, + common.HexToHash("0xa615ba38e3b3b60d2629d8990f769dee43fe6cccbdda4e0ab1afe140d67e3f47"): true, + common.HexToHash("0xdc2f70d54e609d0725e68c63355e01a0c099725d2bcb2a093fe296aced7a9278"): true, + common.HexToHash("0x4d682d94e5796705baac56041352bf38ecfe854469d36650e7c488ae8dfaf0fa"): true, + common.HexToHash("0x1fa79fd5a0e1112788fe77512463abbb7c1a9388a3a598467009b7bb1f9c0b62"): true, + common.HexToHash("0x3cb430a22aadf29832fc550df277fc6b471092430903d3a3e01e5cc636ee939e"): true, + common.HexToHash("0x3ee86d00e85953303ac85fc52be39587ba04066184b199c44d21636568dece90"): true, + common.HexToHash("0x938453947092f76a622b862d5261203208dfad12000d6973bf3e3a89e419b38a"): true, + common.HexToHash("0x2a5e5f9fc61d1b2c2a8ac8b247c7b7feb29dd17897034706d9dc05266927bbbc"): true, + common.HexToHash("0x742702625e384274d7c0c6c11ae30a5e6d6e29a21eca61bd9e7f4642f486f3bf"): true, + common.HexToHash("0x0da02c5f969acf80aa66faab8ca7539ecf3ce43bc58d9fe068576b4fd2cede98"): true, + common.HexToHash("0xb5a1b68ba061092ca4cac938e0dc3deae9d753798d09744957707fc384fb26e5"): true, + common.HexToHash("0x97cfbb0af7bb7b7898d56056ccfcd0b5202facc3430e6b767d58ddd913f0722b"): true, + common.HexToHash("0xc42e1930c274c7f7035021076acff9625fcafbbd2962e3af38a72eac1dcec23d"): true, + common.HexToHash("0xb19efd0bcb67da214e0935980312a3aeb0c0c54590feb82613790785c3593103"): true, + common.HexToHash("0xd5c9d8e233e2c4d11ea4e365f83ba8addd0700543aea412e4ab0d729c8ff304c"): true, + common.HexToHash("0x026007954e9bd54e467dfe770d608a5a44874cfc4728d09cf2ca45504b49cdcd"): true, + common.HexToHash("0x81f3fe3ff1a2bc99dce62bbe97e45b44e69d90b15592e3669aefd309eaa8fece"): true, + common.HexToHash("0x75f7ddbd3dd02fe8bb4d7a9faa40231128b5edf4063fd710b63c39c83583fe8a"): true, + common.HexToHash("0x26ae5348ee9b425d3417aa8808aec1f8f51213b5f52c7ac0b43e98125cca565d"): true, + common.HexToHash("0x38e4d1b920ccdcb61b6305856848d576b6d42e92fe1d839e38153317105abed1"): true, + common.HexToHash("0xe4593ca7e82276fdef9885bd0484acd4080e16d9ee67091a34b8b4cc1bb9dafb"): true, + common.HexToHash("0x6ea5be2bce41c0bab9c0c0bade8607a3d95a8c86421a9695f699017aa7f32655"): true, + common.HexToHash("0x22579b858bc32edb5fe18314a58a692f613d1411596dc672ef9879e1d005c16b"): true, + common.HexToHash("0x97ec30529c86260847d0196abeea42be01fa3993e5932f72aa036869c335b37c"): true, + common.HexToHash("0x3c8739bae40b0c775e738b99ec67a23339905ad1dfdc8ef81fc619c1c4c7380f"): true, + common.HexToHash("0x755de4c804c2c989bee01464f45fbb99610f4705d33fe7c59aae4d975d1eeb8a"): true, + common.HexToHash("0x580a1d1d2d90503a9f2bf7bcee44d9fe375182fa84797e568a172c082e502531"): true, + common.HexToHash("0xdc621294913359d6a170315172635f2169cf175fc47dd6940db69c36380a61b6"): true, + common.HexToHash("0x0674b7ace1fdc6fd865065b371d7d10874cc3e6f8b0345e2d6daa767d4766165"): true, + common.HexToHash("0x5c98934acae651f6fa2826ff1cb61404323c697e5b7e6912e2644f8ef000a082"): true, + common.HexToHash("0x20eec612ba9a8cdbcffa49a33769219449172cd022f09f1eade7f73757a84799"): true, + common.HexToHash("0x413bd060330c87a098a5ec52fbe6f2213abcd24905cc5e0bf348179eb42807d5"): true, + common.HexToHash("0x52222dbddb0ffaee6139915a673c44ac613726202a697b2eb80d4913b2389bbe"): true, + common.HexToHash("0x44983ae29fdf62297e60b2bf04caa3d88893e352cafd656a6f590f4a9866b5e1"): true, + common.HexToHash("0x35e1b14d95b9085302ca37b9a5e47e4fd5f0e859518728019099175929dabef0"): true, + common.HexToHash("0xd022f603fed9efadd94a30f9126107c6605a3484c9aab884ca33cc4e756ad1f0"): true, + common.HexToHash("0x33a379cb4096a6aeb3dc0362f23bdcd07340eb49c32089497501c156a4e74057"): true, + common.HexToHash("0xdeaf711b86ee8b0575e929f015598f3dc2ba6b29827058cd2eccc5fb6e633fe9"): true, + common.HexToHash("0x5cc25630afe87d2b4483381f77ea455881edbd5b648254f323ba70e8c0516413"): true, + common.HexToHash("0x40ad59c5b41c3efcb803489d10215f4c498325a299f5646957e6ad5a360f5f85"): true, + common.HexToHash("0x6f323cdc09c48b535709fa04a1f7ea17e56ea4872e916b90d951a8cceb109cba"): true, + common.HexToHash("0x327037ee96740496d4df247ef36890020ee54ecaced201525d535dbbadf8567a"): true, + common.HexToHash("0x6fbb496d4965430cab5b7495f761930ac41fb54237bc9e486f1fd01caa784a6d"): true, + common.HexToHash("0xd9e79493d139e478c0b52f2afccf5fd9a35da3540cc7a29581d8740346a75914"): true, + common.HexToHash("0xa5d615a980918931947276dee43c514da179006326072c457eb75e3aed2bb2ca"): true, + common.HexToHash("0xe97621f8d88fa54a7350463e780a0006007828b78a37b7921c5a4db99729ef67"): true, + common.HexToHash("0x9cb02b0fde3ffb78d7ebf75b0a5296f96ca602f52f1f5faa17ac29bb201f02b3"): true, + common.HexToHash("0xb07663b057613d088472a722a7ba63ead754a93d1882f1b185594df08e4fd361"): true, + common.HexToHash("0xf93a7f6a91afcfab97cd8750866903dc1302c15fbebacb01e5c844545c42f782"): true, + common.HexToHash("0x0f3b76a6cb475c2401fc84b1102d84f3728bc8ba5d9b009276f78e2c98896e7b"): true, + common.HexToHash("0x3d353715f4fdaa660403ddad1ef66ec6b1d493ba66d1ad18490e94c90f322a80"): true, + common.HexToHash("0x5a11b307bd7c335c54a23175f7af54e09d1be376074be235b771701a14fedb72"): true, + common.HexToHash("0x3e99746b16c7353cbc980f183a5a3402be5f2224c5f9d9bdfc84947a75445e34"): true, + common.HexToHash("0xca67b80aee1a8b6dfcbc3579316b740f62ca0d802ada39e998b26216a6e1a3ee"): true, + common.HexToHash("0x7949c6e44f721c550d67628e0ef8eacaf93d2b705f8717af8003aa4005d58d3a"): true, + common.HexToHash("0x3f6647969e093de150d80b6cf664ff46b6ee0032dedc1d19d276f1ff62819af8"): true, + common.HexToHash("0xf95ce940e94f1270f7ed6906e94bb0f261af7244abe4b72182187de4f8f1e7a2"): true, + common.HexToHash("0x698d0d9229e60e6e4029be22b5ec0f5a9d5753c2dd0deb48e3ee66e4471a5b65"): true, + common.HexToHash("0x5e1c6ec0cdcc0ee877086ddf809d5196d719ddf7e4e2a43dc67870577cf72de3"): true, + common.HexToHash("0x3f13378daa32c03ebbc469916f0c65b0e6b8552bb0f19c3a4bccc4c9cc5d3661"): true, + common.HexToHash("0xb24e82ac95db6544d6c14c7d17d80d456b7f9b899644e8a2427fd418fb3452ff"): true, + common.HexToHash("0x6dca6cb03572cc4f983c63a1efdfc64458c8dd9fe0e18b9b7d4182c8e047fff4"): true, + common.HexToHash("0x12275055c71387720c06c61c6deda779d37b0866a43a134716314f5ad7307d7d"): true, + common.HexToHash("0xa1107c869d8371caaf64bb2eb6624167a9b5cbc2ec396ddafb820d82d065a373"): true, + common.HexToHash("0x5f55c961040280ea98c1a927b17d1d77de611c0931f11dbea3bc1ee96bb1d2e9"): true, + common.HexToHash("0xfe904a988f5c26e6553b99319c70dbda4020da34e917a17de6ce3697a522c2c4"): true, + common.HexToHash("0xb76334065cf84ecc6cd987be87e40307826e8a612fa09f3e4072055e920cb3ac"): true, + common.HexToHash("0x18e583b11d5ca29b61430e64406eea10f2686035e0e7242124dcda374761859e"): true, + common.HexToHash("0xf14a156b63ca3ae3383a94996d546efcedd4b756126c4d90590584de087ec859"): true, + common.HexToHash("0x70b4e5a232ed41fe7265e005c4e98910f4520fd0a629b3940a79a2750bbd782b"): true, + common.HexToHash("0xf3d7ad54746f697ffcec6c4bc66e23b2c5865f83757267a88b895d3b7705f944"): true, + common.HexToHash("0x195d0f173e9d5929ab377825725868e815c335bd9fa26e31d0e4045e971b5b61"): true, + common.HexToHash("0x20f85f112af0b0ea07e287f97659a1ad053f874a0103b69b2b2159a29e401fb8"): true, + common.HexToHash("0xf2c544ee602f25a850b854d3f3a1e5129ceba41c173ddf34a1441f33d4c762fd"): true, + common.HexToHash("0x1033243b02018a702e724a434eed260d94688d702ea6ca817cb87b02d6174355"): true, + common.HexToHash("0x5a972f51e35cc09667a266ce72ed24d5e80a0c01097d67b0a1a3d89745a19a48"): true, + common.HexToHash("0x5ba5a86ba7370c6e394f1b7261f7819812ee3ece774c48a915161724bf5ca2ea"): true, + common.HexToHash("0x9afa9baa5fa7ae7c94243321534a5603dbc173bf0cb4f416313054eca84eb5e9"): true, + common.HexToHash("0x2493c36934be32892f694f65544b1665e646655aec00bd37649904c454c8542d"): true, + common.HexToHash("0xcc59021919c53ef1ca9d6065737122dbd5af77c39f045ed49a936f08165c7b64"): true, + common.HexToHash("0x9d0a0aebce6b80c83773aa6beef7fc53ae0c1056fbb1777add238ec051ddde14"): true, + common.HexToHash("0xeea86fe869c13721298eb91eca92e689bc0151af9a6d44bef77f1cf1157267ac"): true, + common.HexToHash("0xecef6f4f8787c0c64717695347c28ea54b268a12bf1a0f0dd832469f2d59e12c"): true, + common.HexToHash("0x89fe90772890dfda41273fc8ea04155367832e721af90ad42e0cd5ac9f34ced7"): true, + common.HexToHash("0xe180fee49a7b2a83b5a2ea936da09a96f42d76aa31bd7b119d8721da79ec175a"): true, + common.HexToHash("0x7fd28592032657a4e834a6946158d22516feae0fee6df69fc91ab314120c1707"): true, + common.HexToHash("0x3900d5a0c573a52ed9fc717f2e711380a3af926a4c156b3a10403085811c8c21"): true, + common.HexToHash("0xa69dde5a590fdb618a56a919da9d9fa34d9a82473a783af83f1ac2d95fbf111a"): true, + common.HexToHash("0xa0c6cbec0876e6e98430543e47b2512a5ecb680cc329dd37ea6fac4bf700b24f"): true, + common.HexToHash("0xb091c1d89d54360fdf6b9a68f8414df89965e20819d58c0f743ce8e5e7d94741"): true, + common.HexToHash("0x0a6a108143c586dfdd2f5deaf986e641c2a0a51ac7b59d6aa4e0765d23a83660"): true, + common.HexToHash("0x3765adf6d8ce9710c512e555b03e5a42a61ac8250e3727742223505a1828ebf5"): true, + common.HexToHash("0x123973699df17b0acccf5bae545ca5714527069f94d2ad40c65fccbec58b8752"): true, + common.HexToHash("0xcab3f976dca019e29813d8734a8eac06f1da778eb0b8e47c087bf4567d23e81a"): true, + common.HexToHash("0xeb06ba6c1831ba98ca4a8a756879f8fa643fe12f5922a1917f1f899348c7fd86"): true, + common.HexToHash("0xb7e9de366bf6ef470b282c67660b70b04b945f0608ce90f22480209e74ad844e"): true, + common.HexToHash("0x05237000b1003cb3144048345dbe48a7b8d533150e34b02cdf70858eb88fb526"): true, + common.HexToHash("0xf6ee3a6a3a5158e2273a5e0ce2cd0b687c045b8e49fe97b9c0b420cff4a9124e"): true, + common.HexToHash("0x744516296a42f8dd02b970844d467e21ef483fffa19d13c4909a83232f94f633"): true, + common.HexToHash("0xd13d9cae4a241b49716cfeb432dcd926e1e63cd582e8a8a376d1d582af4a1b1a"): true, + common.HexToHash("0x1e3da0715a16365b867819080dc3ecc7bec6386268e56054019766dcd50c9934"): true, + common.HexToHash("0xe69eab2dd7e27f5fbc288a1c44e4a4116a56e5f827a48d39e860bb8d3482494c"): true, + common.HexToHash("0x87302915f05b15c5d658a05021fd328e34389431e55095250ccc3b5fc87b7d95"): true, + common.HexToHash("0x532d31f2a6ebab47a37280ffc60aa05f4dfdaa389fce65834e325b8d574a7637"): true, + common.HexToHash("0xc511d02bcb3fbef977142fbf617bc0ee7de27a7f409ad3a0919e340feb21c6ec"): true, + common.HexToHash("0xe6c3c8925a496a0fac0f55519eab02069d313c71767cc9dfbacc5fe87bae0d28"): true, + common.HexToHash("0xa2abc364c0436bb71fa78be4dc3f2e38a985eb0b6513fa6712acbdd59e2b9c62"): true, + common.HexToHash("0x680494494cb13797f2067a8a2c8214c14c8ce251f0780707be93cf25740505ce"): true, + common.HexToHash("0xb7233bb929bee3e73aed59a3e9f88c55f99764cb11408510566b8a29e2307746"): true, + common.HexToHash("0x6fdd1fb069f0c587a75254f23c7485cdf2a3a90d7f9b8b4cc9e8c705e2f8affe"): true, + common.HexToHash("0x6bfb734ded373378e7adbeb0166330d541041a2a2120b40d0eda1ceda188a649"): true, + common.HexToHash("0xb8ef7670acbac972ab7f1c95252afdb97fa9b8a64af83f056c8c430a2bf56aa5"): true, + common.HexToHash("0x947418e6e91cbda802b119b2e0b6f1c4b1de8ae2f9eee0947112a7a4ce976291"): true, + common.HexToHash("0xc8a27d88873c95ebc3036979cc495cd1159beb0df1c4caf5bb0318cf91c25c06"): true, + common.HexToHash("0x304c7c47cafa49966f0895c04e36fc8cd0cd37df28d1320e58b568d5c2004dc2"): true, + common.HexToHash("0x79f97ad9bc910509bf6d034a892c428ffa00387accdcf0f42974768312c0d499"): true, + common.HexToHash("0xbdb7d40e45542927d1f2b312b82d553df9f6f4d82f12a824cba9644c9c605e5d"): true, + common.HexToHash("0x00a6b31e73e873a18f67e8a0ca262b9fa43f40a98aaefc91a8c84e89f74f2cac"): true, + common.HexToHash("0x3ca7f055b4b46f76910bea0dab680b44ea5e0a40887b06d5cf38d80e6a364076"): true, + common.HexToHash("0x3870595a885e6ca8976fe19742c3668421b9e0ce86369046074b1c19fd37d6f8"): true, + common.HexToHash("0x6706baa70839a3c566653ebfd1513798f191a77a350f25589c550b0e1cdaac4b"): true, + common.HexToHash("0x2684d70a1fa0a2f184c1f407f93ad9eb7dbe19f251267885129ec7776f46775f"): true, + common.HexToHash("0x7fec6b3d21d0adc9585a0c4ddd04a27bf3c63b96ed23a36dd25ce05c5534269d"): true, + common.HexToHash("0x240bb43e37f99529f300444e1c28578bd91c767d2f41c4f86bccf1ebd4b66f49"): true, + common.HexToHash("0x700acd62172122e896ea4bde8de7662195a79bf006391ec206cb948b3f64f761"): true, + common.HexToHash("0x4e9ec1726b70d5f7a292b0d109109ac9e535f1c9ce44334011eb804803dccc5e"): true, + common.HexToHash("0x02acf4711162881e6e3839e6bf8e51df25f8bb6537816352efb5b19529218b9b"): true, + common.HexToHash("0xfe6728d971c56f74fa022ec7e94bde324df7d2c6a979e714089a35c67e850c3a"): true, + common.HexToHash("0x804345cf9498a692ed2a16dc1483a1a29a5e04c9965de8a88ca6e653de54603b"): true, + common.HexToHash("0x65b6cdb8b99b217d80f43db41b134b0877337ffd9b709a60c36938c67088ca20"): true, + common.HexToHash("0x1f3f6434718cc86a763a13143c36d3cdb13e22ce49124ad58c11fc01e343f55f"): true, + common.HexToHash("0x5b978ba28abba37b91589bd0e076748c650182658eca98b26a8b1e00e9a3ab41"): true, + common.HexToHash("0x8fe57dee2f60474c1ff82943ed6c524c11a49c007c99cb04b46f00d7d9bf1242"): true, + common.HexToHash("0x786e16ea4d146e39979169012a7c3bf1a128d53f0851e5bf6062786cea5675ca"): true, + common.HexToHash("0xc67654a5cd316bb8d3418771b7cb1f828002c2029c4e187a2dd995d80dadeb94"): true, + common.HexToHash("0xb716310022d10daf032a950dc5145caf3aa7153aa38cc8332daff381f0bb016d"): true, + common.HexToHash("0xa3dd51a9a055ca14ae30d887fdc6ba9515d9493ce81a97cb39292d3e7c2bec90"): true, + common.HexToHash("0xbfb8799fae7f407cc23a68525ddcc6bbe2ace7a4dea49479ef97b25ae1bc8c43"): true, + common.HexToHash("0xcd403bf4f023eb603b377c04153ef45e03d4cb88e42905bd4690993dd9710fe0"): true, + common.HexToHash("0x9f43d8c093f22030c42cdd173d54e14900b42244892d1a318be94f11438a4287"): true, + common.HexToHash("0xf85426c76c4197ca01d499c5e86cea05d94a5acae464f5823fd6dfec4c2c84c6"): true, + common.HexToHash("0x995b86f039979b1eef94fe4359003b8706fcd6eaaf97afc8269ab920c0329769"): true, + common.HexToHash("0x9e1cbbeeabc1f9e70b48dd6481b9cfa666ca0c439ed6e6769ab844ddae721f69"): true, + common.HexToHash("0x110649b37d7ee690c114a3ff1fc146ca02bac03e145abe27681a215313477af1"): true, + common.HexToHash("0xaf644b507381d4f570e10df98beb499f59b3d39ce9ab415d5c4001e436d77347"): true, + common.HexToHash("0xdd6a264ea2e81dcd6019e344e535de6deb44130b25f4d985313b7d5f1719d07a"): true, + common.HexToHash("0x38fb82c58927029f22eb59869b7bcc3630a684695c2ab97e4a5c3d9bf12fe0c2"): true, + common.HexToHash("0x04f976beef19c734eda2a4006bbcf2075afb58a59afd12f1b4181c3f9c240016"): true, + common.HexToHash("0xd8363a13cd24f71476c9a30fab8be316a111397473d91af54b47bc48f0743cf0"): true, + common.HexToHash("0xabe510d1aa958b3a45f7fbcce3f35876c7fb87cf8c2e5465dc44d1c9bd869f7e"): true, + common.HexToHash("0xb67ea86a983c2e9f416b79ceeb998324ae9f72fc673e59ceb85e81bd39add1e9"): true, + common.HexToHash("0x69504f7783db7ba392948d738131d3b9b6c8f9f873baea318399d7ecda83db6d"): true, + common.HexToHash("0x7d93f634115ff1815dab6b5f595b2533bbd1d0aa0ae7fb63c5778b6c8b3e7174"): true, + common.HexToHash("0x6482951b0fafc7bbb21f9516e46f53b3a80ffe5a3003bab548cc5c982a9b3dd5"): true, + common.HexToHash("0x9cb5ad0daabf4d6a7c77021cb6c35a227a9f89ee34753eb8ff801e56f98de30b"): true, + common.HexToHash("0x6cfdf5bf322fc8ab472225321ccc35c3dd692f2b15603b0516254f7397639fa8"): true, + common.HexToHash("0xd18fe97e69b6f21b15246d674dd3acf5e2f47e6a2d657b35ec4de5a51607fc8b"): true, + common.HexToHash("0xbcb8f368db258915630d4f04d333f2c4288637a7680327f303defe4e146c3861"): true, + common.HexToHash("0x6ebec2459e3673ce588a35e8e927df5eb21efa0a9225e2f912f72a24f24fc844"): true, + common.HexToHash("0x11d137a1ab5f6e7ec2eeb07d1ba97f825077b45d7701a256e1738a9b9c7c9b24"): true, + common.HexToHash("0xefbfa6e5c18b3ef041d034e75bf09bcef3b5b78a0a9c121a382f230267b8a869"): true, + common.HexToHash("0xc2b1b5a136ea9906c57f2caf492895c03739bc4c0a4e951cc45b0b1409714ecb"): true, + common.HexToHash("0xb3475b434e4e2fc8bbdc0efde714bd50e7382a576783fd965eabe8014c2071ca"): true, + common.HexToHash("0x0a8e7303f7463307e63927fe4f737dfd3ab9e463b4e838a58bbd1dce3594d56c"): true, + common.HexToHash("0x115bc0c71b4283b18dbb2d17fb53cefd1da33f060d05666239583443e2465dba"): true, + common.HexToHash("0xf73edfa43649d949cec59ce1269ef877f6beff671bbbac6823691444d6b7f347"): true, + common.HexToHash("0x6414c18610bd048752527bc1a7ece22b1715f2dcd479c6d0535840abc839707d"): true, + common.HexToHash("0x140a8fdc62d70f8f520716b9f791380e6b45ed8b38bf6578d277da596f753e8a"): true, + common.HexToHash("0x36a0006fddc88609e83c4680b312f740c03fa3ed118095f0454f39e658deaac5"): true, + common.HexToHash("0x8ed426d39d258ba45dd373f4dc3cda31bb7ed62d829535a2855567d2b6314375"): true, + common.HexToHash("0x1558648237f96d968fb540756149435022bdcbe0c34c1faaac184b8e3abd6a0a"): true, + common.HexToHash("0xca2ad7f6eea909d6d5dd6dc92959fad0288ba4b1941c23adc82f2debb2811a80"): true, + common.HexToHash("0xe87cb7720c9d016b91bd75572933a32b5e57bdbefaa01cb26716b10592bbab67"): true, + common.HexToHash("0xcb42fa52924b9ec38916a0acc7a56d58c41a0fa8e2aa38a5b370615482a63fb4"): true, + common.HexToHash("0xda9e61ea7b0288b8a0e6f0bf7857aad463c9a1402b5df23572afd5781b919ef6"): true, + common.HexToHash("0xb4e828837fbee42966e4961fb6a7c42aeedd2f628d4a53be78c773265fe9dff5"): true, + common.HexToHash("0x211e53083e5b16d9c7899173bda69048f5f198dfc621d89a50cfd298a7fb40b7"): true, + common.HexToHash("0x6b91fbfc6f7bc2e3256a0cdd865620243dccff4754f5854fd3f32bcd2ace56f3"): true, + common.HexToHash("0xd5ae60e3072363ef7a10580ddc68a5556bc775f3b8acd11b9f29c42304f94ff7"): true, + common.HexToHash("0xc8fb9c160f72a369bdc9c20f545a5934518d935e9306ff083a9ebc69f712a585"): true, + common.HexToHash("0xd96d4d54f12275dcd3ee9db5f24c184a2826f1f2b0272ba2f5efcbc46d4ad94b"): true, + common.HexToHash("0xeba0ceb7089e1ca394f85951fb91f72f372d0e3a6a60bbefb514cabb84da4ac2"): true, + common.HexToHash("0xdeac4deaf24a4bc03e3734c94fe3ede2d19210f6d402d93189270ab93c57772e"): true, + common.HexToHash("0x880e18c4f53f767a2c5944a08b482a424e410c9a2a1aa5a9903d89f9ec34c926"): true, + common.HexToHash("0xb478982d977862239db82a80fb16bcc17e4ac631ab669859c9e8f97f116334b0"): true, + common.HexToHash("0x1ff5ed208280a58ccf67e84a055b820f669098787c6d2877dc788111e1d43b06"): true, + common.HexToHash("0xed33df41753b61128e27789734e2756e237c4215760f0b05d5b4d87a6bee3682"): true, + common.HexToHash("0xf1ad1757ca62e1ede5262502958db3fd647c1550237c9f3de1fa4ade2d0915ea"): true, + common.HexToHash("0xcb4509977305c6299f964bb41c97e5fb5ee347b06d2b0e4eccfa33a6147f1db6"): true, + common.HexToHash("0x1b7d121eee8c52da258c4fa143e3054ea60c10d59b40996aa668787305a061e4"): true, + common.HexToHash("0x92890fde9a4729535608997a2922a7d32e3240ad237ad5ea3671bc6580413c6d"): true, + common.HexToHash("0xe1baffe39a371ac39b561583491335a3fce588b5ebd1560b8103a7138ec26bbf"): true, + common.HexToHash("0x0d709b536ade47061a83fd006808f55261241ee1ec16ca3e4d4b25bb126bb322"): true, + common.HexToHash("0x76ee4eeffc386d653120d2c1e89f22bbaef4873351cf1433cdaaa8a174b7d05e"): true, + common.HexToHash("0xceec2dee498c5b25bab094fb0a5835f4a4cdfcda20b8b1e709643034d36ddca9"): true, + common.HexToHash("0xe3cb7ff9c6b463d666b155229d6a54af6f5b6523ba552a9f1b4b77e4283d92ba"): true, + common.HexToHash("0x646415e02481519c358e7b9c55159348e4b4b940347337e34e844fb4c0fb2ae6"): true, + common.HexToHash("0xd79f13d8b48390b7da8597321bc3112bed34e53a3641572e760d99dbe8a8bb09"): true, + common.HexToHash("0x420305daeb40ed3a052356fd33f4b9467485f324defbe9e05446ccc9d0047578"): true, + common.HexToHash("0x3dd47f07a3361e937ce64f49325910dc7991559391329ea31cc5400da5c05543"): true, + common.HexToHash("0x016b8f8eaa99d83a8c81e28f10495376ccf89c02cc64efe9498eeced8d3db833"): true, + common.HexToHash("0xeb59967516cf84c8a8a94ecdb7233f8d414cfc4229d368012508afd03460f87e"): true, + common.HexToHash("0x121a66e62d9f996e372f7ca91cb074878c13cd4373f4ddfd592b25b162f24515"): true, + common.HexToHash("0x59384b63f44ba35f180353a30b366d47f0bf93200873f937eb6ada47379880fa"): true, + common.HexToHash("0xe53bca31edf4093e3b69a34daa0a327b09f3fcc1b033f908c6b3904885a8e0af"): true, + common.HexToHash("0x0d4b2316d0026e95bb3a98702bff08258f898b1c5591905a485774e86ad8fe36"): true, + common.HexToHash("0xfeacc6fdd721a80bbd977274bc098d76a948f1d3213321bc7b54945d9f2e61dd"): true, + common.HexToHash("0xcae1a585068e9a28f70cb7cec634521e21f2fb0a22d933a2cd4ad3f9c5e379ce"): true, + common.HexToHash("0x378b9939d8770b8423628baa76e521b3127d8cbed4a5b52b7e404dbdc747b5c0"): true, + common.HexToHash("0x4702e81c0354973e6ba2c6a50ec2935aa95b9e098f84699a173aecea47326a78"): true, + common.HexToHash("0x7089d9eaf58b52019e4cd9194802bee1aee583db5afc2f151847faaa9c2283c4"): true, + common.HexToHash("0xb6103b9b95bd7ce045bc42a8f82d9a8a92ed2ff77af4a80eb178c4c01da4adb4"): true, + common.HexToHash("0x648bb51997ac4515172205b2bdd95c20823d2cb1ce9ebe11d266414875fe3909"): true, + common.HexToHash("0xd37c5f21a78fedf447bf6efdfa69029f491599e454815101f78eabf4b86efecd"): true, + common.HexToHash("0xa9c2b3c84b7e389250e2f41d003c8adc36175e166726333ee3dd580356fc9d8c"): true, + common.HexToHash("0x47e3b6b2c001b52732369df324b911daa384add3fd2e9b1f4efdd07a042da01c"): true, + common.HexToHash("0x59317f4ccb4c5a36b6bfb5006b2c73667428fddd6c05f832b325f602893f43a6"): true, + common.HexToHash("0x22b1cede5e3430ac6b570a018e6658a362e7e59c258e0203941a0330cbc81827"): true, + common.HexToHash("0xef4d232bf06f7e1b3f94d3d73191fffd0900881cae29e4af9b72c6d371d18c03"): true, + common.HexToHash("0x680531c9790c0b24fa9d424d7aeaabcf6a08ccdbb3bdd48300b7c8ff7a4f8139"): true, + common.HexToHash("0xee30cec176ca42fb5d615cfcc0cf360a5e05ec57002ec348bd06ea5b718bf63d"): true, + common.HexToHash("0xea6c1d41b399cb40ff9f0087ef4b32a905ac12520b539847cc25eabd4854680e"): true, + common.HexToHash("0x96f3b2c2a54fac99e7f235060d9876c0290e2fdbf3413c14df97312916046243"): true, + common.HexToHash("0x02866444aff9b00face6a74ac8b24d3f59f6a54aa844f9ad43a3323a3a729625"): true, + common.HexToHash("0x195187a6825fd84ce7bd49f1c97faee217c39ba75aff3514e995ded9d465fcd4"): true, + common.HexToHash("0xcbb36ce0ebe861740bd1f5c5ff8801a3d464778d652873f3f6aafa9867b7fa4b"): true, + common.HexToHash("0xd35f5b960e95ff95d78f7240d5df2d834996782d68c935edc501f0aae894ac5f"): true, + common.HexToHash("0xe86b4801b2c86c39746b76c6f618434926b7b134e6895561f2c1822605a2e8fd"): true, + common.HexToHash("0x6baf349632ca3110c90ee368aad786cbf97445a820f168ec9b9f863ba3b67d11"): true, + common.HexToHash("0x594a833917b6618f59de78ec48bdf7a155c9f87949fb772e16a966e83e924994"): true, + common.HexToHash("0x555176e5b9f2738788b34838b529c18cf59a1bc6f84ac00f68a06defdae12e21"): true, + common.HexToHash("0x11506011c5eb6a271671d2483858837d652e39beae8caf2d9901afa9e6fcdf17"): true, + common.HexToHash("0xfda6a0accbbd14992507f636c7c5c2e49ec38c9a3c532c456b9130e1ebd26853"): true, + common.HexToHash("0x7118bbb04c31b92d701a1bfb00ff1695aadabea5117af102bb502440cb9f136f"): true, + common.HexToHash("0xf4f356c47940c72dff2b06836989720ceeb0e9ee22d4f36871b3c675f11a1cea"): true, + common.HexToHash("0x25844fe586cb590f72b7ec22a088775197112c9bfc3691f16bbc58e775c4f112"): true, + common.HexToHash("0xc1369437d583399947993809753ffa6ef6d146787917841327dda326e16eb110"): true, + common.HexToHash("0x83a6a6fbdd019fd62758ad73b369433cfd99f9f4adf54be5261bfc3b09d3c9a4"): true, + common.HexToHash("0x588a222a875795b5a3e53e406412fc59ee461ad569db89791fb8e96c26f750c9"): true, + common.HexToHash("0x5459af1e45d8e37d7b50a2785733080a67b150a57b7cf8ab5f9ddf321030f9ec"): true, + common.HexToHash("0xc126fcff8fbb858c88d6514b5663e9938e23d7ba320d22be88cb365d87430dc5"): true, + common.HexToHash("0x367350b53fa60266e9b1694c6a21aad61aaedab5e6caa664797d71ab21b301cd"): true, + common.HexToHash("0x0c9a8658001a6641e5bf14786a10e4eb1d3f0a3d32a73f2ddc1096af1666b361"): true, + common.HexToHash("0xb4f464aff4f17bf520117e002f782b2491f4ee901031dfa51e45020274f80056"): true, + common.HexToHash("0xde02f9022b52bb692df3c33a76772c2371f2dd8b1aa16b5f37d98863e8629078"): true, + common.HexToHash("0xd19627200bba23c0938a4c560f0b2d3884fa0dd4ac35f665d0e162a43588fc66"): true, + common.HexToHash("0xdc959f3ea579b847abbd0a76fce0b180f2af8b3b6c42e6ba22a8c5e76395f5ee"): true, + common.HexToHash("0x5d3c2643b28898fae9725da31ebd7453c6e9c22fea5de4334fc57246193a984e"): true, + common.HexToHash("0x0426949179539b8c0b2a69c28aed51f77d91735630f992ed9a328114570be963"): true, + common.HexToHash("0x1471fe520d3218c1c2126fa46d981c1567ee3b23c001b2170549007bdf67483e"): true, + common.HexToHash("0x1caefad0ed6fc0400276e26a0bbb76524ecd6dda0bf73672bed3216fbb448875"): true, + common.HexToHash("0xacc7e305239e58337b6aaed007c26e911660e73c5d35cef65afdeb5e8686e9cd"): true, + common.HexToHash("0x336de8e132b9369e06e79f8c6383c51580bfbb78fa702023b292046bc3465d07"): true, + common.HexToHash("0x2806b7bc2efd4e93b97ec34e7771a3fe8831c22680cd4a3adb72d11758ca1a1d"): true, + common.HexToHash("0xd72c69f04fdb7e67a0622b66ef01e53f137ad20462e49ef8a1f13e1d247ce764"): true, + common.HexToHash("0x9144c0f3ccdea396215d5634c756707bde90b3eb04ae313f324de169cc8793ae"): true, + common.HexToHash("0xe7f7ffd63725628d5d07a726996023e7fe0a407bc204f456d5a1d207e1492654"): true, + common.HexToHash("0x2b6bf222d81b31f21506f551b34d080a4e73dcc640608991050feb05b4554d05"): true, + common.HexToHash("0xcf26a5ccecf9d1cba9377f7a010766042752b7a17cc6744f5095234e911a5fc8"): true, + common.HexToHash("0xfc86e666e25ad91f1b3db9bfafc473f335058a5117f275caf7045e00e48d882e"): true, + common.HexToHash("0x84d8fb0ea395e5e13b79c213536f00b6b89e406b7569b6240e39ae0ef2f555a6"): true, + common.HexToHash("0xd0c2f7a7bca65bb08d75b03c8918ea6678e39516ded52a1a5cbf7976679b6266"): true, + common.HexToHash("0x557b67b0aab4270657d4b06e6fc4573c21b60097629c3e84f40a4b73f16b1ea3"): true, + common.HexToHash("0xc3a4bf988cca22d096aa073b513e5c1b2c13d544f96908613ee0b446f5271b05"): true, + common.HexToHash("0x0c79995b22b200aa5be4f3a38197b99b376a5f5cc3c6403df540bc49c9e8c131"): true, + common.HexToHash("0x2d1f9b56bc3f4aa5ba35fd4239687040364e8664390d6824a433e897a7dae3d0"): true, + common.HexToHash("0xe08a63ea0245a17ccd3b86fab72a71a7696a7fc1ec7081f5a90326e700e7af79"): true, + common.HexToHash("0xb9773324a9c2b430fa691af6aa17867e753791a245adf326d4b2dbab42ae3209"): true, + common.HexToHash("0xaba1dca51d2501487860b4c297091ba22aace0aa557d9e74d9f3d5d73fd63fc7"): true, + common.HexToHash("0x8d08148f1cc761d6be4bafdc92a3e24b31762b7996f8b99439b77c099b020406"): true, + common.HexToHash("0x49c51936b1047d5fd0362c8918b95e30f870cf77d647c961d2f89c7a75a2f081"): true, + common.HexToHash("0x5a2acb86924ab2b6903dc87904c8b7bd7a1bebf07478c3b7b7f6aa9d058c6be0"): true, + common.HexToHash("0x8ef2c4c19b7643e425293dc4fc3a5cf69f24ba342a0f121885195b9e7dc34b83"): true, + common.HexToHash("0x2a3cdcd5435162fc7174b7225caae03bae19a65d77bbf56832b7b7cf3cae4de3"): true, + common.HexToHash("0x2dc4463abbbc2b6a6a861264bca2d1899585c252e30be4a73a82a21fdd6cd2f1"): true, + common.HexToHash("0x243e8b593d9a1214d8c1dbef2afde70c80337b593b187e672b3c35d7204af7af"): true, + common.HexToHash("0x54ca37ac35ced21e60fbfe161083da1c5a988e5fed0d282ea850b4fa93fb9947"): true, + common.HexToHash("0xc07021a5bd5135945abe3e758c1a3985863b1da7d65043faa8f36151288202e2"): true, + common.HexToHash("0x92efa2bdf737e35fb33a9006b1ef8cf97d77ef6ab2beffb10cbf81dbbedd7678"): true, + common.HexToHash("0xb23455cc24b681205b09cf6a9252716943088f656508781632bdfc4afb4ed2ea"): true, + common.HexToHash("0x51637072758cc4c05ecbf729c30202db1695b5fbdbf6362ef0d0dde0e30c77a4"): true, + common.HexToHash("0x6ea3f914350d25f50d6b940125f748d894222c1d3351483957bec8e7b6c87e87"): true, + common.HexToHash("0x21c93bf337aab449ad5b58a8b010c0c174794dce1aaa4c6ae4628c915fae9d36"): true, + common.HexToHash("0xd708e032eb136fc675b8097da414adced4eea40d1568c7668aa8543df20c7398"): true, + common.HexToHash("0x8edd88b61e46cc92c709517a33c9fc16f202b0beec0c880b0a209391184333b6"): true, + common.HexToHash("0xa6c547a5dac9666251c14c77fb4d9ab4591506cbc4404ae17daa9d8b2f880fb8"): true, + common.HexToHash("0x748e079135807648c3225b5091c91a21896364e46b5124f7f83d905005addac2"): true, + common.HexToHash("0xd35d746e79e77e602d595a4aaebcca464f53e7661e4744706031e35be24bda5e"): true, + common.HexToHash("0x2da8b2413314d2a12fced3ff31f2ee59426c493130db5145d1c8427f1c0dd7fc"): true, + common.HexToHash("0x243c0e996db012869eb6e7c1abc99114b5742bae5fe76ad3ccea212de4cf1d1a"): true, + common.HexToHash("0x4a311946c6c3d5765538155e39169a1f04ff717c84e18d8f83582d4fcf0ab10c"): true, + common.HexToHash("0xb7cf9a8203c3c1d2f21c905b545937b0093f1c9b6005af7a39b8d70ff0e16727"): true, + common.HexToHash("0x4b03c6ededa56cbdf87ee852a23ead23957c889c6144b160d2099d3d0b4353f2"): true, + common.HexToHash("0x4c8ef26e8f1fc2ea72d37d3facebb5af9b5017f1bb176f14787d88ec411b0adc"): true, + common.HexToHash("0xc11f070380de3f5d038dfbb1e3dde1ff585ebb065ed7fc9d6fa712a7e28df7b6"): true, + common.HexToHash("0x6a841149c078721bcfdcc8a0edc1fa593145605543c4bcee7aaa80caf3ff305f"): true, + common.HexToHash("0x5c378d72225879b489f78c6bb4edf33d41ccc176eb5a61d4873214519593f854"): true, + common.HexToHash("0xf323bdbc6e2a86a0dc6f4e6d4011839d3b52f110ee34310aeae8a9949e2a562d"): true, + common.HexToHash("0x20efd7b6845ef3793accd400a42595dd3f0ac178e30508a435daf2656872542b"): true, + common.HexToHash("0xfe4e5795b316eb8046f23af65f28a05ca8a4759ac8306376ff02a23da86c32a9"): true, + common.HexToHash("0x0ffaba3ffe6d4daac6361b55605114b76e2c3e19de76f95be36e125cbc342c03"): true, + common.HexToHash("0xf914aad46ce1630468ea7bfba4f46282833ff514830a0bec3c9f7e8a5e56b7c7"): true, + common.HexToHash("0xf070b884f19e50573fa388e399b5045abd5dadf00d0b68714505e2365e16a158"): true, + common.HexToHash("0x307b4d6888506e5c20149d9f54dbea47094d6c1a49a933e06d8a988c7a705240"): true, + common.HexToHash("0xcd58cd2d9da4693414cf084990f683a687728c26bf522a2a238d8a0b2afefbe5"): true, + common.HexToHash("0x66bc6bcbc07dd47de57a68b97837967e356f5dc4cc0a3866700f0cb8981894ce"): true, + common.HexToHash("0x0d5297344f29c3cb804865710d20de8d406c5eac8537332992427163b2fed750"): true, + common.HexToHash("0xa7d487519df690889995578a65fb80ddf02731a587ec619a81638fd44dc1cc88"): true, + common.HexToHash("0x46ca5c2fca51b914198844e29761eae00698079c4fd223d17c8008d725dc5d24"): true, + common.HexToHash("0x3f4d25b4e2114acac92d4bd1ca6dad03a1384ea977b3d5e76106e2d269cc2a07"): true, + common.HexToHash("0x9259d7457b2683414f253ef0a4990a454f250829362c60258e39c7860476e57b"): true, + common.HexToHash("0x56624b550c6ed0826e98c5615bb71a990827d625fe3e82bbc1b2f71b59c50644"): true, + common.HexToHash("0x67b5faf425b034169dcab0ceed16cb54d17b32691fd235d3035ee785d54e0b25"): true, + common.HexToHash("0x4abc3e0be240ee7d0e23698ea1f054b8e716f9d91351889ea7abd4721faa1ac6"): true, + common.HexToHash("0xbc8e0ede13ffc68402b21b148df5433c8ab095a2675fb5e3c04a8aa8640b65f9"): true, + common.HexToHash("0x5cc4e39679fc238adca4846f284e3258f93690d530615932ae6f9b7471e27de3"): true, + common.HexToHash("0xd4c46b1e03f58a035ce4ff29554dad0512ae0e60e9c98b2ed4044f2b94dd2935"): true, + common.HexToHash("0xb0a34cd71e24c34aaff16d0d544b34ca508284cc0611c3506234945ce39f950b"): true, + common.HexToHash("0x7e9e774950440f2ac048823444272739d54cae4a8588c1979b12cf457bc31c76"): true, + common.HexToHash("0x12fc061a240074bcca555b154bf71db6a1c4f54e2a89ee2b672e096dc45397bb"): true, + common.HexToHash("0x12973c447532130e58201d08a8fb1c393d1835828f6ec06dd1febf37cf56bfa4"): true, + common.HexToHash("0x87b12294d72b569716d887f4981551bc93069d0ec2c62939d0a03cbfbff15c98"): true, + common.HexToHash("0x67ce8ad593cce09b96bf656ca4fe29ce8dc3a2bcea36b05c8dff46fe7add1d74"): true, + common.HexToHash("0xf04edb7eae158ca9c580cfffb0b282f4882334e044e8aea096c06d4eb6a2337f"): true, + common.HexToHash("0x34b5bc0c92defff28190208cf3ac6f5c4496a5e996e40c0d26341c8a562abaa9"): true, + common.HexToHash("0x6f585f28b363daa9250499c64d2fb56b524f39e0657c1e8a6999b1d1894b7996"): true, + common.HexToHash("0xa321c80c483c9982ab3345708437af819792394a7f8201b6e22f079b1e7f7c77"): true, + common.HexToHash("0x57520957f76ababf6b1ef7606ee8f4315c3c7baf0bd82350a606ebe8c55bacc0"): true, + common.HexToHash("0x4c7e90175a180ade39765cc078c0bc813a8cff4f1060a1d0b520edaea3657065"): true, + common.HexToHash("0x96c0761536c65ce72bc986c703c1f0c28de9f19ffa4239c90f9543d465cf47c2"): true, + common.HexToHash("0x8d53e482c008687f5748eb6b8fb37285f56aa9555076d3e416ea071b4f3f5219"): true, + common.HexToHash("0x016522eef40ca3c86e7db1b166452e10e915bac9d9abd79f7dd39f5e364292ec"): true, + common.HexToHash("0x75406513d2d451bb24c5face5836f72b60666ec855f85e9cabd360c5884d4adf"): true, + common.HexToHash("0x20b70cf75871198be2a90e9bdbbe326da91dcf6a6ed207496f4143a659d52934"): true, + common.HexToHash("0x5c91ef7c9dfdb020dd390f54d181dab1f01a4a7466635714a20371abf3768a68"): true, + common.HexToHash("0x1e547f4e4826a841d713dd739794b774c2afe7abf1be20f87510c2fd65c0f40d"): true, + common.HexToHash("0x747bdd9c257c84f9efe3584da885819cdd8a2d626802f28ceac81bb10513749b"): true, + common.HexToHash("0x9601f93d12185679233aeb641ffe40099653f23229f7094a62634481639763ce"): true, + common.HexToHash("0xa93f8f6bed2e520f4002e5ef162d3f665f32b547ac569aa4b7681570e9ecbd0c"): true, + common.HexToHash("0x17231d5babb5cc23e70120100a4b4f3dceba4e3804d5b3f98dec98a151a2e027"): true, + common.HexToHash("0x8b607a07f4b41c4a4aa0fc99e8cd15f758bfa608dd23a40f16eccf30f17808ee"): true, + common.HexToHash("0x60fc78dff2b2eaa39ccd01055c7ddad2a916e54c8789580c72ee09cfa4fdc8d2"): true, + common.HexToHash("0x26769b7bb3c7eb37f523fc73b4ed512eedc522ece34c5711f080363b5568f683"): true, + common.HexToHash("0x91bd4b2d62fc4503cf00c4e0e5e5fa7fbf0d6e1a3ea20ec8e150a043fcb6f8d2"): true, + common.HexToHash("0x6ed7cec2cf9c422c66efe7129d6a11f89b22cfb2d6c53bfba2c8afb2d2496cab"): true, + common.HexToHash("0xebd03a5b79dda05301af3a5e2450f9a61fd02fadd9b0dae8449c04657da777cd"): true, + common.HexToHash("0xd330ecdf437d7a57cb2eb8c184978b5214c7d89c317649e02fee518ef7693685"): true, + common.HexToHash("0xbc4167d7c8a7dda5aa1b370ca778e8f0397c6ff6e361d0eed91d0e25fcf78dd5"): true, + common.HexToHash("0x1c6305578646bf35f74dca17e34537b67941f30dcf4259dc9792d1baee7cd4e4"): true, + common.HexToHash("0x6aaf514d38245416f8c75b380e24778e2b0f0a8f6152515ac43ed56a82f527aa"): true, + common.HexToHash("0x6d66c3ae44781d3b9f9013da76965cae98889b1dd6a408bcfabe17296fd5e152"): true, + common.HexToHash("0xee9f80348916164653384a38dc6a2787495fca54ba90851b28b4d6a835a8b0a7"): true, + common.HexToHash("0x41796f6d045be27c84dc3dbf2dd509fda4bf08c0203cd3cae5dc3d3460cde44c"): true, + common.HexToHash("0xa12b917468d28a806b42018cb8eccd133e1e1c4ae573b1d1aa190e599fe607e9"): true, + common.HexToHash("0xe5ea977ce3b7b0c7a5258606b43748a8f00fca91ca741afb00215b66a5265dc5"): true, + common.HexToHash("0x0410ffe2436d9e833d026e9f1f0418044236fea987253b857465c03860630ece"): true, + common.HexToHash("0x0da8e7f667d9d5a96de0ad5a05cf8d7dabf6687ae5843dfdd5eeb1f8aeaa98ae"): true, + common.HexToHash("0x9d3be9be38ad499ec2212cfd4d6cb2c9728c5abd1c0621dead0aee3ad98125d6"): true, + common.HexToHash("0xd22f618cee012264bc82535d537ca877a3491e1ab8a7e894648bd0e4198da746"): true, + common.HexToHash("0x27010febabd463ca7f97ab3483a43bfae80934a156732052c8bf669c5aa6ad94"): true, + common.HexToHash("0xdea555f173f55b02dc4a73a7c363cd75066374090db58a5c26d2015b06e49393"): true, + common.HexToHash("0x4198cfd9e16ee2b147b9b3a71f58a9af4c3691f6ccda8421cb5baf49fe17b309"): true, + common.HexToHash("0xbe732f3807b0ec6f35375c4f4bf8f8b15c1f85a2d1c54c7948293d4935d49c43"): true, + common.HexToHash("0x93b1e8d2d484475bc36b835983456b4357e08c608449249deb114329b0a392d7"): true, + common.HexToHash("0xf074c5e55dbce28355e94087fc375b45fb8870d8b7086bd281dffa4ef68262f0"): true, + common.HexToHash("0x9db172fa6bd5a85315f0cbd10fd2671e9269818790246dfef01df396e6d85d83"): true, + common.HexToHash("0x5b5a0639c01d9b514b957a02ad69b0edf0c204a543133d796d83e8bc2e2ec16f"): true, + common.HexToHash("0x129193c8b1df5757f54e4bb4aa3bf3b929de9df1763c878385a1d5c636d1d839"): true, + common.HexToHash("0xd48985e5ea0444b9376fb42871204accf41705917848d4fbabadb16c7ebfc040"): true, + common.HexToHash("0x5f75a1fbc5eda6e5f9dfadfb181ce3510a281212ab4b448dcfb40be5d9afe9d4"): true, + common.HexToHash("0x00ca59ecdaa7493dd9528aeced1585373fb6eb2c401cdb281ec16fe8392a1e88"): true, + common.HexToHash("0x8039e0e17df229f9c3f4516f7e62ce2961966d4f06ff5047b4a9e1d85b0a1522"): true, + common.HexToHash("0x7e7e44ff628dd66f611a16fdac599ed5201f52cef6423c0333b077bd2e66d5df"): true, + common.HexToHash("0xa92caa7d8f6fdcb525e7aaf3a83bd2ff5496565c4cf3f8f6a0e4475f1e16f5ef"): true, + common.HexToHash("0x212fd2ad9a26ba82160367462c5c77f615073f8284909f228e4a7fb96de8b3b1"): true, + common.HexToHash("0x94692e6034ba474da82841eac83152d9e11d310a9ada42b9d7d2505e8c332a43"): true, + common.HexToHash("0x1d9b0bdb4a8b5392553a98190d2a790e739fc31b32b58851623d272e8da73834"): true, + common.HexToHash("0x5ec7bfb04a599ee50f2ce7e7a8db75aa84468744b74ed3875edcf7fcc44208c8"): true, + common.HexToHash("0xc47430c563fd0c9926ae1ae44519c153d8e3b5117d8c0c93cb5631795a9e3986"): true, + common.HexToHash("0x53f64288cd9de8a3eaa810d1e7fba70f37fb30bb46e832a7e2ea60df83034aa2"): true, + common.HexToHash("0xd4e080535fc0165742030a56cd92e5f3ae8f305da7c4b10c784930738410eb96"): true, + common.HexToHash("0x2228fcedd831eda47cfc5edaf0bbc9c70308451130671da902247339001c8233"): true, + common.HexToHash("0x396f1d1404b0ba4cbc99b402666bbcfa3b3eeb25f62e556b7d5102cb99559a75"): true, + common.HexToHash("0xce7de092415a0381bc912e8a30d2b2e9a5ce52c8176efdace974c68505e9cabe"): true, + common.HexToHash("0x5f890663b042eae0c46b660547d241450b5f5d2be59865382ff669785942945b"): true, + common.HexToHash("0x2e713fd2b40ecef0394ab25a135c20596da5c9c073642ddc04b88d01953a3d14"): true, + common.HexToHash("0x8eef13505da3dadae48b55a3dc2d81f05995599e845d14651539c88a1649d01e"): true, + common.HexToHash("0x32a9903ed1bf30a6a98b7fc5a5401a868cfc365447394c41382db290000af725"): true, + common.HexToHash("0xaa6b24739c1497cf5f640d4d3f4d73a52db77f02addaf82f79c288619acbe43a"): true, + common.HexToHash("0x4b8db1c558b97303f1bf0c25030ddffd95464d4bf2e339b3d386ce89852e07f8"): true, + common.HexToHash("0xf3f562d270868f148ad279de53b32e7a21203e837f13d59dede56afb428bf1f9"): true, + common.HexToHash("0x5e725d81bfa8ac79ca6e16ea8dc29f59587b52730ab877b174a1beecca8549f2"): true, + common.HexToHash("0x8768077e4591bcfc11459fdb073855ecf774c45268ee77c891a02095c830a88b"): true, + common.HexToHash("0xcb31ebe467d934659d5929e96a1d876ebeb52fca44294d7a2395e7f56c52da4c"): true, + common.HexToHash("0x53acd2feffcc39bb76d7c70d792b848d4fd14abf9cb283a4524187a87aaaf242"): true, + common.HexToHash("0x46bce98cd88bbb4970104dc8653d1fec9bb5a775d5b3797be38cf93b5e9243fc"): true, + common.HexToHash("0xc397106b72fb76f3549026b960a0caa88279850af040715ba1fd5a2b32a8d7bb"): true, + common.HexToHash("0x0c580374a57b163d2d700f782fc2fe64cbe33200fba40ad9dd396daf91839f47"): true, + common.HexToHash("0xb0be2cf2164401b931aa8601713487d9bf44b68a98397c423709a22c7d1760e3"): true, + common.HexToHash("0xf1a6abe82fdff47cd8c61c6a7491319e82c23d02513e45615340ee0277da3f42"): true, + common.HexToHash("0x6a35e94cf5b1cd360261f3ae91a075c4c002662e4e0ab3d3e5732d5a52fed635"): true, + common.HexToHash("0xcea4b937097b8091b5b71bdf03fba18fe63f6bb8345381ff5d4c6ff851cda8a0"): true, + common.HexToHash("0xc0f83793c5bd6c2d17862fcd5846985c4226e90b349d17f7f5eae1f86de93bd9"): true, + common.HexToHash("0xcfdeef7a85f4945aea40dc46c8e6b1fbc6c922de96b9bbf8ade6c769e469d262"): true, + common.HexToHash("0x36e36a8e73a1d791106e91f95cfb33984c526da49ed272569ec7879a57fc77e8"): true, + common.HexToHash("0xc84df0870c849bbfa85b4f53de10eedf675c3130ea0c86143a2a683f192e7985"): true, + common.HexToHash("0xb9c2f620e22e87d8b8192219ce428caa1ef28fb95cc2e375aa0187c2ab060b69"): true, + common.HexToHash("0xfee796a40c4b26dd951bc8df75f1e6b963e9e9e4d950ad1a60ed98d8a6ceaa16"): true, + common.HexToHash("0x88e616cff6b5fa4652e48d52124afc9549b7a0fc797371ec8517abcdebeb0025"): true, + common.HexToHash("0x3ddbb9cb392cd8ebbd2d7d37542f164385c28cbcab8d982389cf64bd9309ee4d"): true, + common.HexToHash("0xd30ea5de62c464ddd8ac3d56230b327f0f731339f33e1ef9cd6b1170de614b17"): true, + common.HexToHash("0xbb610421d8b34019916622198436e5899b0eb8bbea23fda178db73009b16fb04"): true, + common.HexToHash("0x478cbcd3d5654be497df8da2100c0eafc3de48813746a8cac3b62ef8deb77141"): true, + common.HexToHash("0xe1db54d224e6411403362cb8a85e54a46593bb99f993928f362105604a2af082"): true, + common.HexToHash("0x95db2df5e3ffa2fb9629b55bf80f52287af64badc324175d10c07fea277b2f3d"): true, + common.HexToHash("0x806b8455d8bd138792380df81f0c7bf5c1a82ab0e339bb088dce04784c92dc77"): true, + common.HexToHash("0x88ac8091ad80f49d9292647e0bda61df9303e1bef1366b4a03649f691ebeb582"): true, + common.HexToHash("0x92d5a5bed1669468964cf952837c538cb4e7ed3c36b486443ceafcbe63262a37"): true, + common.HexToHash("0x83b9c83c51bbb67e16682402efa60ce45245720559df607c870d5c3202411d15"): true, + common.HexToHash("0x7b09a1ae4f27a796b4a65c683b9167159e46c05670ed7f88c76b9edf570a5628"): true, + common.HexToHash("0x0edafd58c5192554de2e4d83a42e8310a14e5fc805ae0c7a7a81c624e7187d74"): true, + common.HexToHash("0xa6f7a564df04b50acc59ded1e816ab015041fb476ea47baf90fcaf8915076661"): true, + common.HexToHash("0xfe96bbbb8c1afa7fd2f5c0cb8d8ba8508fcb80a761e8e1eba8396c688361eb80"): true, + common.HexToHash("0x70cc6936d9ec581dc68ba8f8a59467ccc1e52842c4f987e084272ad2d382e41f"): true, + common.HexToHash("0x223ef36fdd77c9c5a9bca36124fe7439b8249af148632c65dfda13f85b19d627"): true, + common.HexToHash("0x14ddda1aeddba78d7d87999532100f2e3e8bc309b5a33dfda415ce595186b7e4"): true, + common.HexToHash("0x72e1d276cddc99fb349dd99eef2de4bec6a61a546c37a037004478d65e3c4fb3"): true, + common.HexToHash("0x187003ae55e9bf94a2e9cd007e0a309140249e1c1a715d32dcc05f016ce68eb7"): true, + common.HexToHash("0x9c6c8b81b1705db5176ed9c1962e0a92efb34511f9df20a973c33766bc5b16b6"): true, + common.HexToHash("0x286a42970b3468b35cdfc4c038b1c14f1b63de90907fb1f6d5d2a1e1d4c3b584"): true, + common.HexToHash("0x769267fd5ca281f60b5109aabc4069418fc9a7d9af04ff6bb01b6efec717e820"): true, + common.HexToHash("0x126b8467e6a42cd642d2a5e12ebcad28577429e223cfe02edcb3d9ef94bc88a6"): true, + common.HexToHash("0x79ab6091c6058653f38b21bfce010cabbac2e7055db559f4202f28029b466468"): true, + common.HexToHash("0x6d088d876d4e79c7b7739851a5b94a86ef2a6b1b8563c8bcfd4db086f79cc3e9"): true, + common.HexToHash("0x76a93228ac954ae3ee7d3d0eec32d6a6ad086c156bee7d76fd6a36dfebe27935"): true, + common.HexToHash("0xd99e4a169acc5d47e19e99a097378ba3c9285641a89e09ed05a86fe371c2034e"): true, + common.HexToHash("0xbc89541bbeb89f7b4fea08a8b0f8a8217610a47b94329155223d3fa4ec618f5f"): true, + common.HexToHash("0x50220fcec94e19430e7dd9c924a774acd53f8f6886737402253e3bad7bee920f"): true, + common.HexToHash("0x74195329610ecb37da90a4b2a8bb3cb1568043a9fd5e0a00cadf44b8a4f013b4"): true, + common.HexToHash("0xa047558c287d7cf8cf149fdc302bf8874f93670e8f5674311e813933d0958940"): true, + common.HexToHash("0x90fc3326289a18e7a63731753ce0ef4d430e2283cc4913512dff9659d9564b51"): true, + common.HexToHash("0x97425100b3782547fa3cb8b0215f6dd307cde2167720a05ef41e52e68aacd5a0"): true, + common.HexToHash("0x54616d0b2fd393b97a7f85191eeeab5c0f0e1a78bca971cbb00cdf471de3614d"): true, + common.HexToHash("0x0e034fdb3e7934688930e57d2f152fab193da939e1a68bfc1cde3c6be5667dcb"): true, + common.HexToHash("0x8fcf65dd6af01de393fccc6caa677487b3092718393c6e401cbdcff3300d64e2"): true, + common.HexToHash("0xb7d4ab26013f562a5b2c961defc684e3a8ac13fb837d55dd60d314bf29a60c41"): true, + common.HexToHash("0x28e8602f614a5de429fcd518bf1fe3d824d840ecde061075582f692b4d000422"): true, + common.HexToHash("0x7355c8e089d7d19bd3b61d863a32c1a671e016f17e270d36ebd20ae04322f10e"): true, + common.HexToHash("0xe976b0204d66ee6cf8b4d347b8f03c32082fce91a5728448f8af07a79501ef8e"): true, + common.HexToHash("0x821e597878c328a8a5adf80606541712d0f43d4edc2b78b50dc9190b57cea2f2"): true, + common.HexToHash("0x1bb716a48e5b0ba15620f2aed14755d5f6cad6b93a42e4414698291de0eec3a2"): true, + common.HexToHash("0x6ee1bc7c667d14d3f6fb25c6f30bfc631659ef80b1d730afddc5695662654773"): true, + common.HexToHash("0xf3f73dee4699d80eda4032a303ff5effd3cae248ff2946a42ebd586519ab0db1"): true, + common.HexToHash("0x20981b7709fad3fe431b3aa21331676c8ab8766ebae4d441a7b0d7a5b2eea185"): true, + common.HexToHash("0x3a9a41d1da507ecd4a59a96607c1b653117f39d7e2a70ea201a2b0e625909dc6"): true, + common.HexToHash("0xcfee56c19bd1bc12f8e3e9a68784137c93d01f7c1e33632446eb4058765a45c0"): true, + common.HexToHash("0x4a4611c60ec6d7bbf20bd34a5472d5b1b1d86e1ff314f45dad9bcf10a70b4615"): true, + common.HexToHash("0x31439520f7a7d3a632b4533b6eb7d31859654f2dfa2ca6016208064592b7c0ef"): true, + common.HexToHash("0xed28fc559d0638cab96f9e8d8b2047ad5c313d203e864aebe7adcf0f7c992a7d"): true, + common.HexToHash("0xba3159cb361dbdccfc78a660f97a5334c9b80b6c191c46c359925ef9e0c6f85c"): true, + common.HexToHash("0x51014ae4a33554b8caf4989ed035a55953a4e6e37da5dd2f894e6439def2ec88"): true, + common.HexToHash("0x8f302611e57058b79d5c990c1ec058b5cdebbedc11053611e045b12d30bca2a0"): true, + common.HexToHash("0x4c6998bb3fdc729dd357d7491ced0598208492e829514eaef56810d0dec8f16e"): true, + common.HexToHash("0xa51a3f6448f22dd80f78b2d1c12873142c6a6fcfebf7b2776b505772772711ed"): true, + common.HexToHash("0x891c71f682c482da924ea9d155b2e7eef8bccad21a95c4da5b24e3f99d36a438"): true, + common.HexToHash("0x9ed3e507dd5ce614186ec3f472450957a85195120cbd8a52506e9ca9d2560530"): true, + common.HexToHash("0xb8e900430f824e82bd5c5bc2a91b73dd348264301dd7d496bd13a8336c9e43a9"): true, + common.HexToHash("0x6adc155ecc3b68173f44ad108e95d57a6008c5a0689603888caf159990d434e9"): true, + common.HexToHash("0xd488d8add01fe898b4855ed20113a2dac7025d975feb2b7c5b1cab1deed35daa"): true, + common.HexToHash("0x0fe9e2841fdd33a6dd8b1758877cdda131b69e0b391ce11adab359ddef8e9349"): true, + common.HexToHash("0x9c7b32c82efd2bd88590bce7e42c8d0ac2de6b00db91bc7a3f612bf0df71b403"): true, + common.HexToHash("0x3402b47781c5570b766c661fe8e8235695b70dd577216a6408eb464ac72899ec"): true, + common.HexToHash("0xc11cf782f696409ade056a44c1ab7da0347891c222facd3d8d5a414babc0b913"): true, + common.HexToHash("0x9009a8310232c6f8fe7fedf3c1a1aab080c3e2429be16078aaaaacc4cb87fe46"): true, + common.HexToHash("0xab737808bb5eb9e5278e2ed038dea7f738a5b7add4006f2d3883a9a66b70ced3"): true, + common.HexToHash("0xc7b3f6bc90ea1bda310523ab4bdba7705cdd34bcf6b141df8ceb014bc65a9e3f"): true, + common.HexToHash("0x90a64441d71c7dcd34422d65faf1c0c910ce17a945270e950eab1c3429e035b7"): true, + common.HexToHash("0xc5d63034a7f83484c24f7a6768ed2a242007525bdb640ddf89f6e0868e11ebc0"): true, + common.HexToHash("0xf8ab75575f27af50ffc102be34c3df0ff8bb0c08ddb2e0505cef96f38279fe4e"): true, + common.HexToHash("0x9adc899245f8d08f83a278083fe635ed120b94f8a078f319c93df9435cc981b3"): true, + common.HexToHash("0x9fe304c55bd5376dddac312bd5ef5b9bff6e7f40cd36c271239308e1f541e3b8"): true, + common.HexToHash("0xb23d35c1f09a2aadfb3f02dca87f07d57028038e8e336c71d259e48aceaae091"): true, + common.HexToHash("0x460eab7ced85b08928f12d79164f47b38d40255a7095a81ef966dbaf6298a9b1"): true, + common.HexToHash("0xcd20f1a159f46fffb76057e7e5e42bb2aabe9b6cdaadf304ff29bea7bd1f24cd"): true, + common.HexToHash("0x4e60f2c8e29121fc12cffe1a3867eeab2b0cb1a70388fd42e4b157ff5192dad1"): true, + common.HexToHash("0xa542068a3e4f3bd58c814dc9309dfe98e52c730e030c4fddf2b9104b1c713777"): true, + common.HexToHash("0x2896b3b4cd9922480550b02af7727ef17c444f904d35ddf4e504a061788684af"): true, + common.HexToHash("0x2a8bb1164daaaa6de1ef6b66e0196327704b4389f7138fc2e74e0bc680b1a6f8"): true, + common.HexToHash("0x57a339463e23f82a3d89ffbb544c6275d68d3b48e5ab8b5e89d1e63547900875"): true, + common.HexToHash("0x7b3a3635acbdbb3ad3f10ec7d2dc5c25e613616aa7a7e3fe4acc214557c6c6ae"): true, + common.HexToHash("0xca9097a84c429ba2f8c5ac58ef58d884a7aae06c115509d9f0449fdb74dbbbbd"): true, + common.HexToHash("0x0850802a1255789d6c11b87a2303d2f57674a16fb2af3d0a293f2e18669eb664"): true, + common.HexToHash("0x3e39e0c943d6e6588d4c604d0b902df65c62ab6fa2b8d4982808080a739cbc77"): true, + common.HexToHash("0xf40cd696e41b78d11780d77caeb5a8f4483c3fc330d042c453e74d339ad0f57d"): true, + common.HexToHash("0xa2348ab942fc67075dbb807ba2d1fd1d870dc948f5407c275970dbf30fd62121"): true, + common.HexToHash("0xbfa557097edf85763290872f8af2418683badcad6cee9ab62de6597d4a450b99"): true, + common.HexToHash("0x8c15d422e5ae7763d6cd7207d665dd75a4d87b73bbc6726f628211594d362716"): true, + common.HexToHash("0xad2c118af257cd22e15a5501c40fc61a278ee27ff1db01acbf2b56c81a8bc727"): true, + common.HexToHash("0x73b011c142f2969dfb26cd397b425df6b9c86d988bd5c6cb2111965e311d42d0"): true, + common.HexToHash("0x96313ddc6ff237bfd4f144a8801b0543839d03736b631f33d1ffd50a75a50f2c"): true, + common.HexToHash("0xa629e77500df9af71280f054f2169a60368c206ad9685e781dbfc0e3fe18b64f"): true, + common.HexToHash("0x872431e2d163a93abd4513e9acbb2a921c70fe6a9e5cca1921fafa185c50dfad"): true, + common.HexToHash("0x8aac358e4f24fc6ec04bae55d2bd2b297f4d1d755d698d25342c10ba5d87f4ae"): true, + common.HexToHash("0xf66edd792da92d43b13b6be991bae2f65d96bfa3f849eae9708ca50754acd840"): true, + common.HexToHash("0x31896e9a57a6234a63b6132c36199789dfc7138a4f49378192e6e466929b6e44"): true, + common.HexToHash("0x7f75a12ae77a20de456b9ee0a163d20fd87b92a2696141e834ebcbe2ffe4d7e6"): true, + common.HexToHash("0x23cc8be2b6a0cfb3ced6b2937371be727b3230860137ed097ee6218773193180"): true, + common.HexToHash("0x041a955d56650f945c52e3a9b166182d3b420a39784e2ad1c30d3f15de3e8ace"): true, + common.HexToHash("0x6d6d29d534481bb927fbcf9abb9206685a56a28abf10eef410976cfca0b50ea3"): true, + common.HexToHash("0xc546c7a60558058e763910d009cd7d9368c67eb58214b6172c01657e182e4ad9"): true, + common.HexToHash("0x128c30bf6be94389d217145cdac77d717b58931d79e670fe6447957d6e8d1237"): true, + common.HexToHash("0xebca697f7254fa57a0c77bc1a0f2e76857e099327a8798c6371e9a5ffc2eb9cc"): true, + common.HexToHash("0x19654b89756b499f2f9691e0739fa03e6569b6597b068237e2fc1b6855821a99"): true, + common.HexToHash("0x524d32db70a62a6f5e93af4cd6297236ec0bdc5d707128be0c368d7036d4e218"): true, + common.HexToHash("0xe94ac9e371c98e7c7ee9796e0be1da7df46130c5eed0dec19945b68abd23cc6b"): true, + common.HexToHash("0xa86a29954624d608d9423a38e1c645b320da7b122da6bf814579cba254257c46"): true, + common.HexToHash("0xca441e41e32238c21b01c1f1dbe54cadf6b062342b0abb36a2d98e96123c2e33"): true, + common.HexToHash("0x675484b54f02296c13ea8af7e2d7553532f9172e8e5e09823f65b757e4af885d"): true, + common.HexToHash("0x1e73240459a3c4e80e36f867a9f76ae5f770863c495ce6e6b0e79f76131c0c13"): true, + common.HexToHash("0x2e533fa59482cb21ae87b56e25bb002fefe54f1936cc001d8a9b7b29f8214949"): true, + common.HexToHash("0xcde665a44de4723a6f9bb40150dc7ca20d21733fdda9c57d780b94e177806bde"): true, + common.HexToHash("0x822f14526c7c9710376787bb5e5cab0a1cb477280606065729f3c273cd6e1d5b"): true, + common.HexToHash("0x889f071de5c91f031902e64123b74ea6e90f94ee833e3712d709309749d21f18"): true, + common.HexToHash("0x156a33c5b36292751bc34819a12120bf8e5a2d1d34118eeed0e0fce0b374d04e"): true, + common.HexToHash("0x963077489ec72eddf747827e0bb70c8eb9c2a2bd10a310b16ed995b6ea72274d"): true, + common.HexToHash("0x71ecbc48052b2389f7cd686e46fc713362c03a1344f9da2a380980e87a4e1383"): true, + common.HexToHash("0xae3706ebfd839e7d3bc9a4dec1d12342e9921c129a88032eeb6b0084b7664145"): true, + common.HexToHash("0x0b86a364ac9cac32c676146ec12f195cedce8c7c11a804e18b25ff4e5b97cdb9"): true, + common.HexToHash("0xcf14af1c61a53798783ef549dc9d80b59986f49db0e57718bad5aaffe4b0097f"): true, + common.HexToHash("0x09f0dd02af6e6f526884fdfb7c8ecedd87b31e008b638d6e8812b2596e26da53"): true, + common.HexToHash("0xfaf099e86ea0f37b37f857d506c2b779eb3437d8ddde22ab609631ffe4b6b13a"): true, + common.HexToHash("0x4e8a2cc719c47fd6a07bdca3e698b109fa4c9a5b10808a743e715af159c9f321"): true, + common.HexToHash("0xc67aacd0e9aa10545b58affa5b33b304d96d1a21c27a4c45d1867380e051bded"): true, + common.HexToHash("0x722121823bbf56e14104724c40aac6baeb0478d6ba153409eccb4445fafbb532"): true, + common.HexToHash("0x2fdf7a87991b5c47e9f16ef78ee8dab529bf9efef230357e7e346b96e5aa4db4"): true, + common.HexToHash("0x4eb22621835e985655a403f4a0ccc976ff03905505efda707fcdbe0c9892a00e"): true, + common.HexToHash("0x06091c8ab8a6d1030dbd55103334116c927997d6ac4c5fe2d869d5eab5ffb8e7"): true, + common.HexToHash("0x0ae63c594506c847ca2bc4da1633aafc38471bc72f0783e95791a16811ddfb81"): true, + common.HexToHash("0xdab84d00ad691ca10d35c0e1e4b288737c8be2c95e2eeb40c4103534d584d198"): true, + common.HexToHash("0xc8cbd2aeff706fe77fbb9441f9e01e6d5b87b881e04bc85ebf46710c95912dfe"): true, + common.HexToHash("0x98caa7bb29c69df62d94d3d80760948d1d9b44fb64e4e0bcb0d14a0d23d3a2b1"): true, + common.HexToHash("0x1b479d0b195fec9ba2401ae3e22fe9de8fe1cc07f1481c18c9b83de9f18bd237"): true, + common.HexToHash("0xb8648a220fe447c4e0b1c2ac7388cae70cb7c08e0d38b39595931feee86fa738"): true, + common.HexToHash("0xa46ae0986c2e232c32403a9a684ec94133b7c7a29198d2391d6e31754303edf0"): true, + common.HexToHash("0x3192e9b277f707797cb98c1e89e2ef06f3e63429b48218ec969ff64891b89f33"): true, + common.HexToHash("0x6d248399503ff0228ef1dd553dd7e111fafa79f4fd233715b72fa48df1bfd777"): true, + common.HexToHash("0x5b620933c0c83a6276967c7f2bddf4772a7f67d31d97e2925f2c009e6b474894"): true, + common.HexToHash("0xa4465319e24db26d6e35cd8948f85e1953b7a1e7d667ca3509f2976b1c9acff6"): true, + common.HexToHash("0x703caccd574fa5d82f023cef71174a45ca6d8aa1b35f7583787c59adaba8a157"): true, + common.HexToHash("0x042b03d5b64a66204f7190721bf4a23f08614b6e772e0c8f786a6d27f545841b"): true, + common.HexToHash("0xdeea17b41f0cf3d6f8215117a196b54ac8dcd3501081fb3508c0c3e098844ee9"): true, + common.HexToHash("0xbabdcca24e8abb0537a88edf0af7b2157ab733dc79d194e6ad8c7ac2f5050a76"): true, + common.HexToHash("0x29393b0eaa35f01754f7b1b75c299bda23651b08776d97a5deba2cd656ef3525"): true, + common.HexToHash("0x280cfddeefc8bfc3f4de6350017cb2abb467e835115a9c02ca2e0dfed78f1d8a"): true, + common.HexToHash("0x02ac71a9dce50e8639b75e4bf2d9dc701c60edc18e6079f1e09092fdc72bf758"): true, + common.HexToHash("0x87d7eed68c03a9fd5b37625d894cdafec31e5d0429c62ba389a1114b1213b33f"): true, + common.HexToHash("0xd845218a62b331538966289213f15fdf4e6f44812c422c0bf523163b7835c4d4"): true, + common.HexToHash("0xeff26c0d60098ae9dc2b6dd14332219fdd11816560cacd4bb6d5c823048ee7b1"): true, + common.HexToHash("0xd8b8e0e238b5e456b3a5b4f046d5306cba4aa149c858d70cf6877e777e67fe50"): true, + common.HexToHash("0x73ff7849f4cae30759ec926425159d7d66df32356b79e3955ae20cfd27166f20"): true, + common.HexToHash("0x713a5f84a1bab733a7e8eeb9368822776f4ef583fe4a0e292720bf50580f1bf8"): true, + common.HexToHash("0x6db38d61733124bfa6b2003bc81ff16f00548da0a1ffdd46ef95557337ef4364"): true, + common.HexToHash("0x82a7960a463415f0a11e91593620904d901233064c89eb32d05c9997bfd2c3c2"): true, + common.HexToHash("0xbb0708967897c9e6d6cfef187c8a845f5fab0290c0b70eff9b4bedb29f506a78"): true, + common.HexToHash("0x516f4ab1b0ac1adcd30acc83a5589f808af1ea8510f29704ca183b7b3531f583"): true, + common.HexToHash("0xfaabfe52672f6adb3d706bb9cebb0c6000e55e2f43ae90ca1d19955eefdac98d"): true, + common.HexToHash("0x3d73faee86c20571f3c30f35fad59d25bf6e84e4a87cc085f5330466d640422a"): true, + common.HexToHash("0x0c75729f7dc5df557a17c1fbb7cc8a8396f46eb67d995c77d5eadef49d461414"): true, + common.HexToHash("0xdcee7debeb2a5a88bc5cf94aa306b619789314731033b07271f1584929be1f86"): true, + common.HexToHash("0x50519af0b6436d125d525fb5408eb1c0a22965e406e623251963a6d0a89406ff"): true, + common.HexToHash("0xcf989a9042f77c9052510c19cc39d947b662127c07ed4056c403b6de1148b998"): true, + common.HexToHash("0x97b18f532f28aac94d56c023dc790bf1469e32375e661e22e4427045a11688d8"): true, + common.HexToHash("0xd4392a357317a9fe2a2b1e1351317aa0a3585dc5d8e1eac3afd24c653766e006"): true, + common.HexToHash("0x61d2f981fa935a869c9082ad3ec5cad09a757e39226c28fc112045e2f8f8d7e4"): true, + common.HexToHash("0xf8d405be855fec405dca9d527bf41baf3b12a7ae5c0c940f34246dd2d76a1ab7"): true, + common.HexToHash("0xf1cc73911afcdf4c0c4a4b2e8cd0144d8e480a9762192e29417f66ce4ff991f7"): true, + common.HexToHash("0x921069a27cb16fa2ec6ca236fee0614ab8ab2d8e85a14e7525f73d1204275424"): true, + common.HexToHash("0xbd1dade6793523292656aa31afd71afdf205b6b81ede6d512cb5ae62fe089082"): true, + common.HexToHash("0x4f946066b72e4a93c4499683c2e94791d1463bf61d63a51142cb29fb2065daab"): true, + common.HexToHash("0x786e5e4b494499d4b8992de77002509a39f683b28cb589fc055d21400e6d4b13"): true, + common.HexToHash("0x6e292233f50c56dd904bff5c6f8bc3396dfe32510a5b969068710a7cab658649"): true, + common.HexToHash("0x406e13262d9b8d5cd3d5efbd02e01c1957e99abd4fb960cf696ef187af2183ae"): true, + common.HexToHash("0xbbc9d7032a1a19811f94f925ce67635411a112f680a0fbebe9a2b06abdb582d3"): true, + common.HexToHash("0x6524cf96e5dc557b5d354442724ebc23ea61c7ac2720c2f9b25aad245dfe4c94"): true, + common.HexToHash("0x18ec710c1fdb0a54851dbda7dc817e36db59b5b92aa5a571ef89952dd6c6b5da"): true, + common.HexToHash("0x02f1503085137dd387b9cbbbb50ba7a78ff4c53c1a4ebfe78a4d7855012e4ca1"): true, + common.HexToHash("0x3a5d1885cad7052f66e69aa7f41e92f63077b759af72428c00200f477828f3d4"): true, + common.HexToHash("0xad18b1ccc31c17632b977c759e369369601edd4c4111241de481a2a423b1416f"): true, + common.HexToHash("0xe28d829f72da22eff401d536361ef1df2d385c6a7f1bfdccb9402e045d4fabe0"): true, + common.HexToHash("0x768852d1a0a0b0cd9582c879c5cf137a5ba49a21d8ce709409d0be9ba33c6602"): true, + common.HexToHash("0x5a34768f9f1642b60e4884261bf85d4fae0dd139441fbb371f686f87c73d0d55"): true, + common.HexToHash("0x1de6d4a1cb36523be48214ac588498a937cf6f1d7bac125fec4fe6b79b273ba9"): true, + common.HexToHash("0xd19aabfaf14cb0c92d01e80698ac3bab3ca832b7bcfc2ea44130da422a9a6522"): true, + common.HexToHash("0xc2c305bce1a88b47d233cfa3f67a4704ed2aa0cb3eccb6c7c3765d1762cb4baa"): true, + common.HexToHash("0x907b680a61a4d46ebf0b20597b8415de0135fd9ee3bc5780b9fc6ca4bce6839f"): true, + common.HexToHash("0x634ae21fa92f322f3833fc2a656377b144937f572948faa0ea94ec59ddb555c6"): true, + common.HexToHash("0x6b319aec254c6314c93612410fbd8b3e5ea1a6b193ef372435631faf6486e4ad"): true, + common.HexToHash("0xe32e25521b56707a62e388a18fb04021c5bec34dff4f3db40169954e76dbdef1"): true, + common.HexToHash("0x7021a73a1389a2e4b3a7875bb8d49a95312a1cb22d7c1615c615ee8db4266ea1"): true, + common.HexToHash("0xe665294d812c0b8ef77e5e465606b79b25f5206b21796e35a4c4c6fa9b81a766"): true, + common.HexToHash("0xbdba5da145d6e1d927f925089b9c646a2798023fd75af14f0ad6580dfa3b2b6c"): true, + common.HexToHash("0xb515afcd2752b99bc667f647384cdb43f8a2db63fbaae0c62d021466a3f2fbec"): true, + common.HexToHash("0xc700fd153de986dd56ad0bc5c382c1935249f3a22bb7f96a43cdd31af361cfe0"): true, + common.HexToHash("0x4168a0e12b8a8ff19c95a30f3a2c6630c352bc11860588f7a476d92136bf3ecb"): true, + common.HexToHash("0xc97619fb04ee2fc53530e72df24c8ea2664eb36c8fe8bbcbf8b96771d596d29c"): true, + common.HexToHash("0x156a39769d281c42f0d803e536f32bdd482da6cd251a5f829feb8d65a3a20ecd"): true, + common.HexToHash("0x811b37fa1c2ecb3a6964e4ad88d149a662d1f18ffcddca704989356c8b413a02"): true, + common.HexToHash("0x784a83ea88d3c1177b9f1657a2fdbf4c30f4ae0167cd22f524c7faae6d394ffa"): true, + common.HexToHash("0xcd2a03224f4c4670fdcd4274a6f59657a84fd0472c454ba82df920c68dae9265"): true, + common.HexToHash("0x893feeff55fbf9ef8da9f415c1cfe7891f7e882877ad98fd8e32b1ccf9939e5e"): true, + common.HexToHash("0x79f9c80d4859bfa0a9d52a4aade77f695576163026d2ef5bdb150e7cd0ccb888"): true, + common.HexToHash("0xf1eb1f711d8ad99801dd463906f42739cb4728bfea73c13e65b0dc36d4c149e3"): true, + common.HexToHash("0xd5099a26aa58f6a4703c36b9ba487c249851119fb820be0d778f1da6e42dca84"): true, + common.HexToHash("0x2c2cf4f3671531f5ada25d3945b694d2ca369b0be8b9f7c52f8a589e35d5d81e"): true, + common.HexToHash("0x725ba293a1c23725838c1340e1eba2acbdcdae0a03b432234612899958c2fcc6"): true, + common.HexToHash("0x9dfc13f52bbd6a1f0ae6fea0b859f2fcee4727eeedb9fc5df1d5c9e821154aef"): true, + common.HexToHash("0x1a1d2b25641a43b710024aea761c635dcfad6e961edc54b4b71de9d7d8759b1f"): true, + common.HexToHash("0x0bd4369dac27c2dadbded2b03793d1e6f1201139cd355509c40a76b13212a321"): true, + common.HexToHash("0x7e8d09f03f2c67f6c6a57e9790cebb3f0dbf0e0ba33c61f7d120d068ba202c83"): true, + common.HexToHash("0x7dfd4fc6f6c8626090c6d35eb3edb741897a2814c085493a634ccf47c6b6ca60"): true, + common.HexToHash("0xb9f0a5afab78741d4db7c165a5d469bc1ce287917e8ab1f7e83a71b595074f1e"): true, + common.HexToHash("0x0304f81e14337421061384fa2634489099b745b443e947fedcae80ce0e877a9c"): true, + common.HexToHash("0x98b48e25db87d1e906e56505c60d6290ea37bcca41c4241ff342eb415d755814"): true, + common.HexToHash("0x8997798347ffa5c750a067133e9e4b76ffe6dd227f5ca33f4018527bc833c158"): true, + common.HexToHash("0x45f2698e37f93d287fadc2e3c5c13272a4f41276cd7b6ae3028c902e69c8dffb"): true, + common.HexToHash("0x44ec8a510162c727775bea1a54b2dbc5da4be9aa5ab448cc9b8531b6c5cd0b24"): true, + common.HexToHash("0x22a943e157c07a5084f13ef5a0db3709be0275e652947f8329f517fb21ab58f7"): true, + common.HexToHash("0x4cb4d847519f80ff5e2a567cabb5add300f95c2bcb6c614ff96cd038a6e7a6ad"): true, + common.HexToHash("0x312e0cf86bed4e032b3076e7d17633792015647c6116197a2ddba0381f0f3173"): true, + common.HexToHash("0xa7256f63b482a7c24bf7dc11040c88d9031e5ab4205c533d0587455dfecd3e0d"): true, + common.HexToHash("0x5adc6f351c9515ef5bf998dbbaf6d47598d5846eb322f1b2787904ae52f3f04a"): true, + common.HexToHash("0x1570af73341dd8d608d05e1fca3536844a0d4fa49fe3f9c1840e4d28c1ceee70"): true, + common.HexToHash("0xf1ca88e3a74e4aa6aec358b06c86cc8d36f1cabd8d3714da3b90183d8b7d62a8"): true, + common.HexToHash("0x84db4c62082867014a58920b42e48836ccfff9674d0315e935c12a13d9a19241"): true, + common.HexToHash("0x3b6c900e696f09afd0e85fbe4316782a8bf23ed4e2e6a1169b256c27a333b126"): true, + common.HexToHash("0x62795933d1005c63c96fbcf3c2f33838dee4261f9504fbc2ca47efbc1aec23f8"): true, + common.HexToHash("0x49dc7e614c39e6805b49195760ec08dc83a4f3907db289bf936d76284b57c4f8"): true, + common.HexToHash("0xdab8127bc7bde0af7214a57e63bde8ef388ac143f63f4e7116614833b75d7a35"): true, + common.HexToHash("0x338c586f1734fa269bb41911767abf70d160b00864248a08b32ee975570dcc33"): true, + common.HexToHash("0xd4ddf71f8ba5558fb7946eebb7520b4ed0f22fa2db540003d2260e183242c969"): true, + common.HexToHash("0x4d2db5eea9839a2b5d4ae752cb7432b97cbda3457d4bc3fcd96d3965f118e7d8"): true, + common.HexToHash("0xbe1fe5722a34cf32086fd62a45e466634bf5ce677d892b9b0e10e85e6b1230d7"): true, + common.HexToHash("0xee1101a789096a2f35092606ec9a73538512217ad5ac22055899b1a7be1c07d7"): true, + common.HexToHash("0xe27b44efb96d2e0bd640d8116e7be3cbf2b9256ca571546d5f68d50b8bbad8aa"): true, + common.HexToHash("0xfc8ea507980851a078ec1fd69789582f21804efa71623029fd8f548a8eaebc6c"): true, + common.HexToHash("0x9d383384a15816af40665d5b4ad8d750d9606aaee9b706d79aa9b998d564372a"): true, + common.HexToHash("0xb5f35871d85312834ce5008af176e53b0ba692a6c1d459005fe929f78ca95ddc"): true, + common.HexToHash("0xda6b6e187f96386cd04cc15bb2bf0c140a220775d92408f755c0f8a9b8de38ae"): true, + common.HexToHash("0xc05a68fbb9db8f9d4d56849bf159b694fe145ee3f52ffbc05aa119b7b90270a9"): true, + common.HexToHash("0xe5b2572916cf241adafe8965d380528417bb401fdf2387b2ea1682498e715329"): true, + common.HexToHash("0x2a487ca7563800e1c74f7a379d868ec8c48dcf3a949e7cab553f73efc650a94d"): true, + common.HexToHash("0x319234735d50a10511c55ea8cfbacd38b4d49108b3683126a48e1cd67b384c27"): true, + common.HexToHash("0x41bf535fdbf088ef4375917be8d1f4a43768c259114d3ef0e62a07ce7cb67124"): true, + common.HexToHash("0x158d6bf11a53c797d0fc3badaa316faa406acfc86f272cae20a2a549270e5e25"): true, + common.HexToHash("0x0f3b938cc6f186c34fcf9e289638d533766e5a6f141841dfebdeff1fb7010537"): true, + common.HexToHash("0xf6da0a8e47703617122044a016d3c67d1e3aed4ffab00352040cf885dfd37703"): true, + common.HexToHash("0xecb54e404a5df6f0de5fd4b5b3d61a83f316dbd89f83fa38128a5aba61524289"): true, + common.HexToHash("0x5831cccd4729b6779f51e494e840b733d277aa0f387ebc3d84fa94856a7b88c1"): true, + common.HexToHash("0x5e72786a28bf3c4cbb2b54be879d106c6dd6ebb082305b32f754a4d2d847c07b"): true, + common.HexToHash("0x3ce0b803c5e928e93bab2bd926e1be8b3b402d0999e793fa53308e999befb66a"): true, + common.HexToHash("0xc27bed6e8836a54906aa4128beb477bc646611632677f86555215c8fb2c2ff0a"): true, + common.HexToHash("0xd6138363a22edd7a2da5f2844c856dbb93698f47345657e4beb66a3710884644"): true, + common.HexToHash("0x77c9e4ca5566ba474d8e2b7d1cb4d1949a63824f9fa5da839e5cafdaa1cc126a"): true, + common.HexToHash("0x10dbfb4c94e333cd82e60b0b7e8837f19054dc40dfb5d77eae0427782f50d0fe"): true, + common.HexToHash("0xa4380d5c3f552f3ee1edf88fd768c7f53e97c82f172d124cadd8d37f2eff227d"): true, + common.HexToHash("0x66a9d2a68d4765db2b36c7ed9b93e106918d822840998233261ba5c28c053c9c"): true, + common.HexToHash("0x09d2577034486ba0baa3f0c80d28760ee743b015cb93f380b9269ac28a5070fa"): true, + common.HexToHash("0xf73e10d75a9aa9d91e741346180644e12600a0752d14502c8764b7e5e3f2662c"): true, + common.HexToHash("0xfc7fb2661f7af334989e999ba872b3ea17b0807e24fc9a6492a3e03854be997e"): true, + common.HexToHash("0x5e9a8919b3bb45421503942f306cda7f3a43e94a9c4565dab1c239172e5edfd9"): true, + common.HexToHash("0x27f8e08a1ec99e3b2de414b0d3c165c01402c4359e59b21c3f2d7d8f0c07941e"): true, + common.HexToHash("0x89ffb5fa5daba4d11cf53c0f65a9f0d95d87250913a2cb159c2cb0e09688bd3a"): true, + common.HexToHash("0x8eb8689423748853442a494a4544f0f1300c54e41669e037814f0b151c921035"): true, + common.HexToHash("0xc783f50936a1f8299b75ab3a21faeac2552298b7d707d9ee1045402ffd28702b"): true, + common.HexToHash("0x555f6c72dcffa24be8c2be35c0c10a01227fbc50cf89cd768a1b8d09b98e2a0c"): true, + common.HexToHash("0x41e91328043b4f0ce7bcbfb85299f605c95973c60aba4881f51560d584a9edc5"): true, + common.HexToHash("0x919c38aa69e35ed214f3cddb800891e37d23e827609fc50be3724e75ad7e8d7e"): true, + common.HexToHash("0x06635b03949f669aea0abdf9d47a21e9824130017de76c4209a63fd8a07c43d3"): true, + common.HexToHash("0x8e7e671cf034b1e611d6295f25c042ae0c132c483be5eee449153e5653830179"): true, + common.HexToHash("0x4de231cf6a9d4165049e86244c40423fe5cbdd38e3c3e729804f7a03f868b3f0"): true, + common.HexToHash("0x05763b197d9659d406575ca96b1ec87c07d641eddff17647fc5ab55a8fef3a4c"): true, + common.HexToHash("0xa70b65066c97ed87f409c81df2ffd01b16a698a15490218dd9bd954fdab7286d"): true, + common.HexToHash("0xfc975300d4f2a52c5397f9f16b2bb3b072654801a0d33450c70690a002fda04f"): true, + common.HexToHash("0x489abcc25bcd85b3581bce078970b67ba68359a9f8b619d190c8f5827f778486"): true, + common.HexToHash("0x05d791e89991634e64eaeb676208ea35f9a73e65823d25e6ec8d2f7ab8709806"): true, + common.HexToHash("0xfdae37e4661f1e3ddca369fd5e38805e986abea591e304dd67e8f9af620aeb52"): true, + common.HexToHash("0x57ef4dd8f4b6cbaeb89824b56a4ddb4bd5ab56ad8bf2ee4d8ae09389c68c762e"): true, + common.HexToHash("0xeb71dbbcdbf257d75e3155069a18d72873c0bf0dc0c2bf10574f20341e6a3717"): true, + common.HexToHash("0x51f61c9ad3358aef07ad726ef90accd997044232dbfe246d8adec33b3be0d6d6"): true, + common.HexToHash("0x4cc562819110912e18b559edc6d28b9ef2e002203d5cf47cd45dd8a53de45d00"): true, + common.HexToHash("0x6680a219a93e20f0998782eba7b531b9111abd6c00eaed3d3da27d464f9d4279"): true, + common.HexToHash("0xb568e8db1e2d72c12729d6ce3a55ea9bcb42118e1eaddcd634eaa47d53e24f95"): true, + common.HexToHash("0xdb02d39d5a6eab5a5fbc076070738311ffd0f31590ac2565aaa269a6d052119c"): true, + common.HexToHash("0x74939f564978bbe4d175ef0bb4e075e0b6c463c0ca046ccaa68b901a237a6948"): true, + common.HexToHash("0x82d4f69e57d78f619fa9ed6f03d164ecba88ab4071a0d900f04a757d1b4541cd"): true, + common.HexToHash("0xa30ba1c1f3096a6f118e8ce4ae494b4c9a2013da85818a6d38f313e77a1d9fc8"): true, + common.HexToHash("0x965329c9c9ff2c28fbf8db97a56acc0fb3f3a44978d1f746dce7c127ffe1331b"): true, + common.HexToHash("0x2f182594e12e078ff44df98483f43122894d82918628f29ac1209d351353a7ee"): true, + common.HexToHash("0x37b2062e016aa0878bd502550dfad93dfc57b00f1e8550783d03dbeaafe3aecd"): true, + common.HexToHash("0x4ed865211711dc0b4d7884059046be1fb3d87c703694067edb71d029314b043d"): true, + common.HexToHash("0x41d320f76ed724c9fac0d1810f478d88fd845d4b02f0d22a97dfad6b64fc4f69"): true, + common.HexToHash("0x3af24e057da6d4b3c8df04aec2957d7d8868871b0c88d8c36b76852d00c2f02c"): true, + common.HexToHash("0x8acbaef3ef7204f2c707d3133bb3c5fd5e1d188e8b0fa665d63256fdd6119b2b"): true, + common.HexToHash("0xc998faa19fd049985f3ea8f837563f9ec20b07f25af42a026809a2c778d96599"): true, + common.HexToHash("0xaca52811b29d00683bd2d06faae3e984456ef452e18b964e2e1168c2647f5e9f"): true, + common.HexToHash("0x357f39f083f40828d315359165e88f674f82cab0ae7b821f5a52e1f63987168e"): true, + common.HexToHash("0x3677b73fbd038a61efba68aed01a9fdb2eaf17aba697e0d9aaab26440b8565fc"): true, + common.HexToHash("0x07a012a6ef48db600305bb14b0480c462dcf91530c55835e050ca01fe7c4e194"): true, + common.HexToHash("0x00a787cba3a25d06f3b0f562895e5ca8c6fc3dec15a613f450a54800ef3995cf"): true, + common.HexToHash("0x86eed7bd085b9163a97c017a6e1b1e9398a9dc7a421b1fa3682a406ed7d3d007"): true, + common.HexToHash("0x85327357ecf0bddcc3dfb81e1b20fecb8f989441a1b35facb0419dc00179f817"): true, + common.HexToHash("0xba4266ae1bc464d19a59559507400ae09ccdc9bd425d80f89e55e6e62a15e696"): true, + common.HexToHash("0xb6bfbab3a03775823c778e02f2516e004059bca485fedae580b15315855238ee"): true, + common.HexToHash("0x4385f31f2f423b3c28de244042fcc973450e956d291cda225cfb49fd42b6a01d"): true, + common.HexToHash("0x383d2b718b5d5a8ce9f02982180d0ce33d73d71662747afadd3d87719e0a97ff"): true, + common.HexToHash("0xd86834f5631db0df6eacee15e6084be55e5c3cd328f5e29fdc66c72c8700b70f"): true, + common.HexToHash("0x619f6735cbe0727a34b7de2ca178441a0a671db7ab922faf3e654c52aed399d5"): true, + common.HexToHash("0xa8187048afbaec376a9a4c50237349d9e80066db35293dbbd1bf6c5221ec0995"): true, + common.HexToHash("0x38c5586e2ca1bae44c185a709f335ccb93db7717dcc9a2cb73520a00ec16a7d0"): true, + common.HexToHash("0x38aeff39def9101f42230b283f890b129b2cd24c24bf59f7626d55e34e3b0416"): true, + common.HexToHash("0x90601f42d76804c5826ed4d3d55793695c727151fa774bd0746b8e975ad3be65"): true, + common.HexToHash("0x101174a9a6c6a8fc36f5c42415a15f85a762f1a737ed41fad7b22c0dc8d5ad40"): true, + common.HexToHash("0xf5db6be27d1e92ba0cec3a9f1a7eeea0dd35b0624623ef6fc803cfad48c24924"): true, + common.HexToHash("0x1eea70dc801eb62780d82da84ff3d8900a218c936c347f88f784359133fe8c42"): true, + common.HexToHash("0x25ecb0285b5a64772a5fcfe8bd9a082fad6d220820a938802074d44b766bea64"): true, + common.HexToHash("0x49d9c1f5775c0f8f64e9dd9ce3c5e16f014ee653d8477de91b1f4f7962e45888"): true, + common.HexToHash("0xee0b0176edd39b9f3d7d831bfb457d4bdcf207b5fd4e9b72d02d5a1409221f2a"): true, + common.HexToHash("0x6ae4e9e03252033e12ea1acdf456b1881ec5985807c391c9dcee74ea57e10aaf"): true, + common.HexToHash("0xb08a0be4db6cce4199ec36a5d02a5895ef0936eb155b718aaef3e3570dee6cb8"): true, + common.HexToHash("0x73fd661e7a8ca075259d5fb0105d051aef015f419178d0f31ba50d396892d815"): true, + common.HexToHash("0x6f0474cf5c074717e08d70c5e0386688ef2fcc697c5002923cfb6d6c5f391601"): true, + common.HexToHash("0xd7d68bc37c5f4bab9f8efdff81d39e8a16d83d91efaace66e6bfec6aab5bd95c"): true, + common.HexToHash("0xc61b5bf555528b5aced413bdf17ff9b122bd681e619c49052efdc81106131f91"): true, + common.HexToHash("0xf5ef310f117c215225c93081388f5b7b8382949f36437effc7d6a2cb251f8005"): true, + common.HexToHash("0xcb988e61b26edc7b9582c8277a2004f39eaca7dfee5e132f96ea1436b95c15b8"): true, + common.HexToHash("0xbe3203f8d167588ac4851dba4e54780a06b26127d4b46107be0073f38cf2906a"): true, + common.HexToHash("0x06145d9f5d30dfca0e02ed20fb5206c161c4e57550c0c026d509c9786c4f57bf"): true, + common.HexToHash("0x7ba6c475a5a3018889649fe2b6fd387d91885c3ffca5e11e62a1308952b08ebe"): true, + common.HexToHash("0x3ca7fc61238fa6d6439781f77276e2ab7ab7102d3fbcbe408734075e93f27f80"): true, + common.HexToHash("0xdbca617b23c91c4598c26034a06f72c2b73c30c22d2f1aca0ab488e72f6d9d54"): true, + common.HexToHash("0x0d9d5669b6bb06ae49e44166ce4b69498eacf1137dab6adc7a7dd3a650e11bb9"): true, + common.HexToHash("0xf5ce5202532b63ebd17b997b1bcd357376922463a002d09b236d3a18ea48e259"): true, + common.HexToHash("0x3cfacdd0a788f03713bd58a3ce876c5e6db3c84bf1b5205fe17223239923832f"): true, + common.HexToHash("0x8a5e7659d10fc2a59c06a5010bf41947bc3c8e34c65a40ab1a82bc0d5abf09f9"): true, + common.HexToHash("0x081fe4697b8cc3f616c5b70e82f2c67a3ac4f70cea5e1ec1c2baf22a4103a215"): true, + common.HexToHash("0x6385eb5f3d3a84e89d57150a42f47d26d0b3e6bde0bbdf79e373f0ed9d06b564"): true, + common.HexToHash("0xed348dbd99d42e57ed9b051172fd07eb6d7f9bc13432d9f34aa2c190b460c23a"): true, + common.HexToHash("0x27056d17be2230f114c54cff9b6c0e0ffbaa5f3b60887732c8201cace145d4a1"): true, + common.HexToHash("0x14d7ad63d53f62a1356f77b8ff2ff3b60122d8bed46f0726f7e2d3956bb9748e"): true, + common.HexToHash("0x3de1bdae2ec41ca4beb5cc6403d08e23197228fe155538a0ff49a0ee67c60d5d"): true, + common.HexToHash("0x1b75f133ccb808d0ac6ca9f8c13fc36c4797f4516f7661b9cabd16455b6f4b2f"): true, + common.HexToHash("0x6f68e93539aa52d761cc17d38f254a70668f3dd592d33b22cb0a453bd58129ab"): true, + common.HexToHash("0x94133db621e446636b88d8cfe4b3d5b32e674eb73bdb367f508ec1fa3d9a0641"): true, + common.HexToHash("0x975b18da0085073a966f1eaa5871d9717a85d4317c545bf547092277441a44f3"): true, + common.HexToHash("0x2f753478d5efa8f9adbacaa12aa8095fe9bf05945eac358922e2f874c170cb13"): true, + common.HexToHash("0x6f2867ded768b51b8f571fbe8efc11a9a5f24014e7e78a3f33fcaa590676e623"): true, + common.HexToHash("0x7a769e31d64a05d38ddeea364dbed70fb1e78d7e46c0b8695b63e1a9c8433cf6"): true, + common.HexToHash("0x9f959d5925c363d07ecc8e25ee396447624d3a0d5e1d8c08efffff72021962ff"): true, + common.HexToHash("0xbf61566b2258772d2536b6f6b9aed6036a59ade97eb52a3e44314566086fb824"): true, + common.HexToHash("0x9f62513d3889d95aba00085bd8f22db6a38106307c2b232ffe7e0272ca25dc7e"): true, + common.HexToHash("0x85f7adca9e0372399cf67cfff088012999790133d1d3f66081fd4bca85fd2d13"): true, + common.HexToHash("0xedc8a14bbdcb5d412856bd3c5c1ac76691e57c3190674d04451d6e12a1eabd69"): true, + common.HexToHash("0x68d207b7021aa8e1d3b488c4caaa33b7b1a29603216b29b158b3d58c0941de3c"): true, + common.HexToHash("0x87b1549365f56299ae5321b7ce469d788c65cbd51599720b0576d7fa5cb716b0"): true, + common.HexToHash("0x2b1cde010d1336c2a6884a823f5c1e33f326e2c499a75ac50b6f3d1f9929d7b3"): true, + common.HexToHash("0x9757531e576a8a784ab9e820ea7e928b0b11a7adb97b161f2e993874029e9663"): true, + common.HexToHash("0x8eedefa05b954da090c02fb515e5b07a429e3d3e97cd3472be582e66bb4a1acd"): true, + common.HexToHash("0x30a6033e53557c093886b521e5e4508f2835752ba1f694123f3855eeb2531bbc"): true, + common.HexToHash("0x95e4b7ef42ad25c5f23362e657afcec135f89ab93c993df054e62fff41e48d55"): true, + common.HexToHash("0xe303c0173512252dc2004e9a6a5f9cb5f59bb5855e89ca64769df18ec4f63089"): true, + common.HexToHash("0xac42b19bf8913600f5df5c95363ae2487049d390c95ea91aa1d09609de45b384"): true, + common.HexToHash("0xb3571027c253d182e45353ca6c7519e9b9a72225d3f64c81f77d5530fc966735"): true, + common.HexToHash("0x0a6a0e2536fe33510cc1446907fb7b9d425735ad1f99a044e5d3aa6c60bede38"): true, + common.HexToHash("0xa662812bfbe4d7ca89e235f58e1f145b7eaecff75f21092530c62a4a81832272"): true, + common.HexToHash("0xf613a5babfef7a176b4d355993e8a787aa0666182dd823241429a70fd9fa272b"): true, + common.HexToHash("0xdbbaf3a995fbccc7586a471a9e540669d737603fd67670295183368e88832c4b"): true, + common.HexToHash("0x9a5ddc3f60739b36b6c13a5714fa3f68539b839bdef4512f70320b99c4309f44"): true, + common.HexToHash("0x9d78342d8dee0b16a5628005bbed9554a04f5f9447b6e04a013ef99d8aaf0dc2"): true, + common.HexToHash("0x66c2b08527c2bf88db8beb14f45a6ab5ed9060dd169bce41ca715bcbf0869d75"): true, + common.HexToHash("0x846344d861497907c2458384f9c8f130290e858582f144557991428dfec44331"): true, + common.HexToHash("0x2a0f2960eede6ffc5b334ebe463035c18cf017488390fae0c657c3f858fd786e"): true, + common.HexToHash("0x9e486ea81f54b8a46ddb00c2a79b147d453c95ed1265047ce32dd0975087a7e3"): true, + common.HexToHash("0x46271634821b7f512d12268c7b472487bee0d7f655bafacd2f438e4994ee0ad3"): true, + common.HexToHash("0xda8e2e5d4e8eafe9d5ebbedf5176fd1ba99ce3d110a83f38dd995196d43d1f86"): true, + common.HexToHash("0x9172aa92b0381ffc1737e5eda6785bd123951f1680c474b9a78080ca745a7137"): true, + common.HexToHash("0x65e8e0f69a6b381e6885141f06f755edaaf773ad5947b9b93035217b68f02ace"): true, + common.HexToHash("0xa7b4389cf5787ef08b724bce2e46d85b2ffef3c87516563b322636543edf05c6"): true, + common.HexToHash("0x42dc633900c73c2c499e1b6b78271ab372a3da1363a22c3ebc9e05b38f548c3e"): true, + common.HexToHash("0xbaa12dd76660652a5669a0d5466cb94c398af26321887e227d89fa54b7ca6ed2"): true, + common.HexToHash("0x60157b57e0feff662220c1ce21e4c3d9505d152cff36f07a9a64b34ae23db7f7"): true, + common.HexToHash("0x6572ddf085e774bf538f2f96802956d4201abbe4b5ed1bfee1dbc02d8f248361"): true, + common.HexToHash("0x2a65c0b40bcc92f34dd632be6e84175836792c0eae9c515971ce6cddf53447f8"): true, + common.HexToHash("0x158d09a0682da518fd88ff2e7d0a04f43062dfadeb2cacb68a0c66c86f541688"): true, + common.HexToHash("0x858cfb5ecc87aa8f7bd6622bfb8deeb1d97743f1bb9f4fd7728e756a10d473f2"): true, + common.HexToHash("0x7db87cf8ef1e6219be17fce895ec033150cc140371cec47fb47c2f6b23aec20f"): true, + common.HexToHash("0xa0a700e84fc596adc5ed4315391ce943170c6c12d2a1a4c822067a067e3828ae"): true, + common.HexToHash("0xb73da0413468e394e1f0bcc36f81031faf5a8b664fa6a7d3bbb77e55b0e94c23"): true, + common.HexToHash("0x8a3fdb8c0ba0a4a3f3307fb379aa55a57aaa45ae0ec6201f8e0058a13eb819ce"): true, + common.HexToHash("0x500e44ce79e78452c4509bc481e5e64968f6fdfc9b2c389cb1f76c13dd38b921"): true, + common.HexToHash("0xf2a3796c09a2b82cc370fa5b3f866725ef9e72b02fd278c44ba82a961fb1b5f3"): true, + common.HexToHash("0x315a2873d67f8166382e8abaa83c3329c89db0e7d8ae27af570ebb73a53b92a0"): true, + common.HexToHash("0x12ef64a2f5c2a6afec910eaee75c0d4c5a482fe9d1d28043c4d921ab9b2de390"): true, + common.HexToHash("0x87c8693501364c646e492d910dc9c7e6a4fe8310bfd9ab8b54a0fe0a7010bacf"): true, + common.HexToHash("0x0dd2ed8391466ef61db84dcd8a466181461a4db1806cbb667207b252eaae8b9d"): true, + common.HexToHash("0x4640f454b0cc84bc79559e409da0ab927db26c704c708a5095b692b5f8caa1cd"): true, + common.HexToHash("0x459a6afd5867cb72a704a5aa31784685cd06f41dbfed0ed154e9c57aab3291da"): true, + common.HexToHash("0xf5b4b03d684b502529973839b912cd890d36ad405d7ee1ea20a9539d9a1c2679"): true, + common.HexToHash("0x2d00fde3120e8c273d25ad2c770a8f51c4f61776aa2c06329b3ccf67f2c82db8"): true, + common.HexToHash("0x885d9a51170b4a51e2e3495cd285fb66f3ac5e5fb8fe12c26e64a4b38a4b0d70"): true, + common.HexToHash("0x17c0be05c5b1159fd2f54366e71de6be4b740a10441ed94eb2ae7ecc873bf087"): true, + common.HexToHash("0x3fd969c9ac44d7ea32d16a54359563eaa42dabf5faba9961fa00ecca16626ec6"): true, + common.HexToHash("0xc0043a987388e69e8b7cf617c98cae77be448e51b4998332a83dd86ab1af282d"): true, + common.HexToHash("0x16b03f2e073fc12f16ddb7aa3bb0c2a3258aa04807875381edd19ba0733f5027"): true, + common.HexToHash("0x4912fd6c6d0ba5b81b266b27cb819281d3c6eea2c8f0cac09dde67befa3e1379"): true, + common.HexToHash("0xbd83d691729b086b185bd75760477789f2eb9806a9b8b6ccc50c8b20d97ce269"): true, + common.HexToHash("0x81f74d0915f2d186ae51ad307829fe79dc3199d4131f6ce5c59c3c4b12bb81d8"): true, + common.HexToHash("0x93adbef57c024b1341d23eda5e8eb2535114fec7a2bedf4fbd231250258695f3"): true, + common.HexToHash("0x23053a33aa3385bf59a99d3558cc3e671b2041b723091719a22163acb0599a25"): true, + common.HexToHash("0xf68e88aab3bb67e24d0d17388bac49c9d6cbb6867a8054cb881e5050ed707b2d"): true, + common.HexToHash("0xbf1840bec044af22e64cb61a50b4042690574357f7258e55e850a6c555e24755"): true, + common.HexToHash("0x449a22fa516a322f0df4d0ce1db8b16d25d8285fb763b9aaa82755715901ac4a"): true, + common.HexToHash("0xc6c2091b79f1b60b30ecd89799c98c9dbc0ed1fd686275729a1259ff82a836ac"): true, + common.HexToHash("0xe0f3ca4697ed441b8c2e05b0587711b5d929684df5ab1ae8147ff97e31c15b3f"): true, + common.HexToHash("0xdfac656be12fd56678bc01168e4e49a1694839f7f1490f28971a89d7cbbac56e"): true, + common.HexToHash("0x55d58f4adeba864fe19482260b8ff20bc31c9874b7c90f28652d88a65bca7db9"): true, + common.HexToHash("0xa35bdfcaf34d24563fd81ebdd7ab199433f45a8abd5a3fc824a29c9c7cffc49b"): true, + common.HexToHash("0x9d713c84940ec201711ac0f2d77edef6009547da82ecd95154e0cb6549b7c34e"): true, + common.HexToHash("0xbc01906d4962195a5587977edf1313acd7891967c37ee3e75d2ebb2fcbffe332"): true, + common.HexToHash("0x9c1dea6cd0cf2fccdb58bd6abb57b4e39194091ddf7ca51423bc7a73a6015a6e"): true, + common.HexToHash("0xda0d680bbdb36e097072cc301f6ed4da88e5a98d822e09d0394e4df3d1ed02d9"): true, + common.HexToHash("0xa504ecffa2f2c84a57b69ba839282e73e8a40165cec54aca9e498fb21a3e9acf"): true, + common.HexToHash("0xd594b77de7290f66385905957982857ceba29e615501ab59b28c35690b869976"): true, + common.HexToHash("0xca3de49cf1a50b562b700091fbb26baaf8051e7c39ddfa38a9783483e835c065"): true, + common.HexToHash("0x2fface469782c21e4513a55928ac600bf1cc33537f250ed1618f58911193aa6f"): true, + common.HexToHash("0x763769fd2842895dcf9ad496602e855140c827f0e96afc7e25113e365b777950"): true, + common.HexToHash("0x184f2040b02293ded69b9667cef4d0a50574d9983510d7cf9e5837a803e934ec"): true, + common.HexToHash("0x435e5bc828727f42884cdc1b55fa9e3c7e0a502414a1003ce3bbcf46e1eb9e52"): true, + common.HexToHash("0x0259f48e2a21d4acabed543421e283ba0d06c62beac2f3bb13da892e338e8585"): true, + common.HexToHash("0x7dd46812b9500e3e841f642b90f677dd0f1e7595474356a7c48dcfe91650cd89"): true, + common.HexToHash("0x691a8c7d5dc80e889a33ccba5a3eb0ce3a3bd4548fd7367f3acb5c4de7646097"): true, + common.HexToHash("0x9b0703ab75ed8d165219a56349902d4938661c2ac714588fae6ee651681223fc"): true, + common.HexToHash("0x802b59179b7f16bbb7a90bb22987f4a15c26487c21f9dc26b65d43c8e84d14e1"): true, + common.HexToHash("0x074e7feee8bc521646c196db2634ce5d0c1597cb9daeb99309bf2cc6151635f3"): true, + common.HexToHash("0x240c95bb4f62619b0fd09dc652090284b104054040ce8028e0b83273bcce1af0"): true, + common.HexToHash("0x70461996116b36bd0bf6e75859d6ff47a4a4a42a618636264e119b08de41484d"): true, + common.HexToHash("0xaf245b6b5eb6c0ab921e3681c9817b0d10de009552b4ddf31bfe72ca51bc8eb2"): true, + common.HexToHash("0x8af3b4b6fcc805d9146cb9b9b6cdd042514d434f84625ef4af8f50948fcdd157"): true, + common.HexToHash("0x219c28a212788f0b406162636ca7f75f5744f7e58272673182cd6fa432f30b32"): true, + common.HexToHash("0x4e8098eadd5bd003e80484d9b643a2f995eee0a8388df56ffa8be74bedf750d7"): true, + common.HexToHash("0x9763796cf20c82fcab58672709d9b62ed07baaedd0dcd68e0f5154955d9458fb"): true, + common.HexToHash("0x59affb49eeb1658e0f3149a15efcdc2e76764c5bb4b253bac0a40aabb63c220e"): true, + common.HexToHash("0xf2c658cb8fb90de56644e29a118fb4386174b2262bd7aa2d75f1d52413fce8ac"): true, + common.HexToHash("0x29cd7d58ea07d7f189d5a57b71c7253893490cc3eefb72afb50c1dcf66819fcc"): true, + common.HexToHash("0x206d179939ecd2dc57b290d848dad5d1ca92daebac0f949637398fd9c9ddbb86"): true, + common.HexToHash("0xa8f599324bae28a344ad9d5ac5f7b80ca155c0576700346f93678884a9f9b0b3"): true, + common.HexToHash("0xdfb43004a2cb02d6ab3494e1e18f8355acd48a54e2cf00a47837d34f24b3956e"): true, + common.HexToHash("0xa75e9fdabf6b98823e0baefbf8d5cba83830461b547cf5cfae8e8860d1f49db2"): true, + common.HexToHash("0x992d775a6be1b17cb6a199edbc782deab931797d84482a5ea4b15c8d7e386545"): true, + common.HexToHash("0xaf6ea5ff7b49ec03a8cd9c48eab500e21bf97887b2253ea4abc8c169d653c4aa"): true, + common.HexToHash("0x022a973e1f524f90e75adb3717ef0f0e250332501dd3262379f2b883c1ebec54"): true, + common.HexToHash("0x725400986d50e7eb1847f36bdebc33d703c7e2fa229452bbaf7936991b0c27ec"): true, + common.HexToHash("0xe342737429b1af731e4e9b11a12b5ed9867ae7a8c577cc75c60a4cd1ff40dbf7"): true, + common.HexToHash("0x9fabe27619036a87d7087bee03034d4464f50bc0ba588d70c20359c6910e39a7"): true, + common.HexToHash("0x4424beca014937a6c14a269446ccaf142c90ebd046d840e0d1878811ce5752bf"): true, + common.HexToHash("0x334db4d2d7231828c4b2b0c8902d219b5fe8d98ee4976fcb27453dacc66a8884"): true, + common.HexToHash("0x2f556fa67f639d2421f0d27f24fc8189637e86bfe5e1ecc814a871caf0f2c7e1"): true, + common.HexToHash("0xabb582072f0a908be4fefec0ed3b2984eeb3ad8e55a1b4e9c051b252ffc26229"): true, + common.HexToHash("0xec0ef68d99cd03e3cba044a8785b3f586fb2dfbf280e1b62309ea53292e17dea"): true, + common.HexToHash("0xb1cb9c1de6a6594ec9e949f10705385ee42aec871650ff2d09f3aa590ee70b6e"): true, + common.HexToHash("0x6271431576a1e4b821ccce20755631b0ff63d3917357340d7a36771cc17c7078"): true, + common.HexToHash("0x2fcf99325ff7cc2f7d62b722922e62ba93b1db8a8f1a238c2e130b1e2e509d09"): true, + common.HexToHash("0x999fcbe2ec56e2a62420669b9697450eecedde50b4433c43a3e4155c8b1c9852"): true, + common.HexToHash("0xa2f8122c1015b1b19dd8013c40731831ecd5923e7b1914a35e7803fcb4886cb4"): true, + common.HexToHash("0x5dd193af17fdab6999932ce6163ddd2bc217479948ebdd516710610b1e61b6c8"): true, + common.HexToHash("0x56ecedf095775a21608cc8ea392bf564c67f97849f9646e98f17f3f368bc82ad"): true, + common.HexToHash("0x3a4e136edd66a2f29245fe201a65990b478925dc82dc6f6bab98e26fc1d04cea"): true, + common.HexToHash("0x1a6ae54a6595ee087f5a3c970077a51c4fa48b967f592485b80e2a077ff18fee"): true, + common.HexToHash("0x30edbf8f4ec6168d00f934223ccb8a9ea12ad0e810d4bee0ecbd7c2511ebffad"): true, + common.HexToHash("0xd46c164ee03a5c37774030c1f380a8348547b4de741dca55d0821d2889b7d692"): true, + common.HexToHash("0xa3ab6ffaa73c20b53508da94a7ab6ff8a323bd8c165e198a38256e90a6251c1e"): true, + common.HexToHash("0x0cb2af05d3b45d1aa4340cf32bf787cf57525d10a3bd2741b3468711d149456e"): true, + common.HexToHash("0x6ac1f1024b81dd605b21e0687e8b97d0e01013042d491a4b14b69ce9a86c8289"): true, + common.HexToHash("0x23d2bbfd6727b76f5e9b36870c21fcfcc3567fb60936f5bf07af788dc275ce94"): true, + common.HexToHash("0xb15c6973dce233cba0da383ca49b1e1e60b4c3d065a4cee89a0b4ff6a141fb69"): true, + common.HexToHash("0x66ce4acdde669ad4af29440d07feb7cce97d9261f90564bd66adbabc68948749"): true, + common.HexToHash("0x5e192e6374908be16cef4b69b0583694b319aeb90d79d68de1065c07271f1af3"): true, + common.HexToHash("0x1b5388943300dcdf7cbbc2d4cd40e411e238cea461a4fbc9fb0c8f1775d09a7e"): true, + common.HexToHash("0x8fb39fb7bc92304ca3b75d061f61fd2002a91d2527e9791f72cd680a864087be"): true, + common.HexToHash("0x09d4cb6cd53c3e5a9f85cf6e4e78cfc43adcdc4e7af7817e5bbcc049f442f8df"): true, + common.HexToHash("0x32fb9225f06cbed8a7477664c3279cd22de688e71bf2575cdfdc0daf900a1017"): true, + common.HexToHash("0x83fac89163e1e9319b8f015f2c8c17b69969df5d8dabb7a668d09bbd101b760a"): true, + common.HexToHash("0x557fda6d458441ec13c3def4f0091f514303c7f6f020320f7c6f53a24543207b"): true, + common.HexToHash("0xe814c5a97251fc8e5bc68b350bf293b6012f331e785404f7763ea6bdac82e9b0"): true, + common.HexToHash("0xd08f05df9b4ff889976a7beb5cc19f6311b16ab4fbe3d875d5ccb4bd5c0bd054"): true, + common.HexToHash("0xa900025aec1986ae30b58b321b5f3cbc0ee10cb6fc3eb18ce941da6711d9b018"): true, + common.HexToHash("0x7d927c12dabfddf51cc6c83f6290ba5ed03a3baab14e55471f932a963f7f1bff"): true, + common.HexToHash("0x1f6c203cbc64f7ba1f729f19c2c03d54f109ae7ce9ead6da0a8fbbf8482fc27c"): true, + common.HexToHash("0xedc78593924e3c6173b7f3851d0fa339a2d51db6bc4a99f40e5a58827bd970fc"): true, + common.HexToHash("0x9f3ddf09e73da8d4b5a4b4388a9f04a2449b8c09cbfe845a4bc4c6a663486f05"): true, + common.HexToHash("0xc12d96064255482567ec04cd8326972d9fe017d2055c480694f121f61079c889"): true, + common.HexToHash("0x8848f34351b61e017679d291983cfbb3dab4d937bcb34c3f60da3f9779ae63fc"): true, + common.HexToHash("0x36f97cc279f85d298ee85c80b64b6c697f90a9b971ad0b8706406ed8b9aab767"): true, + common.HexToHash("0xe2e70f7cbeff425c2fc298395e3921913d11a762d4fa8be4431755540a8f6aa5"): true, + common.HexToHash("0x285023c546c0f675f9396da2f2a2d1a540d31a9c9433790fd8872a342828785f"): true, + common.HexToHash("0xa0aa27cab3f6da948d466ac5f87153a372c574e1c400c8d992782b2270be4787"): true, + common.HexToHash("0x83ec835c21209553d79250a7715298110c1666007211290d699669acc4490ab4"): true, + common.HexToHash("0xe19a058196f3a3cc0905b5a1325324db3af6658de7ac7700d644027cf57d2900"): true, + common.HexToHash("0x536a53df103c5ad8ae071f7275c88219e303714a994465cc73403c7e852c1329"): true, + common.HexToHash("0xbb1acbfa93de3b7f07437caf5a66777644c26aefff88c1750e907874ac69be6e"): true, + common.HexToHash("0x785d3ba659b67f866a86b7b8c9036e2868a84f055084f84d190b5117adbbf53b"): true, + common.HexToHash("0xc06254e58037223a565574104d0840c5ed1981b33e339d1aa13e3b380076482b"): true, + common.HexToHash("0x3317dfc10ab01d3f8dbc424ef8b5fb5c52a7642c1dd390687214b4656ba5d3bd"): true, + common.HexToHash("0x7a478450e751e7ef4897af48b40ab53ed3626a9f0a145df6576d68fadebcb702"): true, + common.HexToHash("0xd974b50cfb2acefe5be729a46dd87dfe438f9ea3d39e30f5d81630c90e7c11f2"): true, + common.HexToHash("0xa55bc5e6ec71ff5af549226ab75560ab74d83114546f5ba227277162f58f3e02"): true, + common.HexToHash("0x223d80a0cfcd466c751963357224280505ad7d672bf3697ed365d095439851b3"): true, + common.HexToHash("0x6c8d7e6920bf506108c4842f2c44852bb7cafc822b6f9a0e06da5668a2aec363"): true, + common.HexToHash("0x60a2136d6ecd44a4856fbac3cd2996815df227fc752ee716be33f7ac557377c3"): true, + common.HexToHash("0xcdd961dc7423487ce436260381b21c06f7941594da720404e95686256671ccec"): true, + common.HexToHash("0x53c38ece8d55882840ea0a64048bf0e21b27c7e4c9596a61bb936792de9bfd16"): true, + common.HexToHash("0x37bf0d668c9cfb51554717bad73f93de883dd6963cc30fb283b137a23544607e"): true, + common.HexToHash("0xb2a9492b89ffbfeaf5dee31080d80281cc15a7287a418b049385a6bb2a8a419f"): true, + common.HexToHash("0x3cdc56ceb503a1749bb87a4ecb8a361958f549b987cf7d399b916f171d6cb69b"): true, + common.HexToHash("0x3801b6f70b7592b50590a503acea100bcf0f2ddb3f97795e3fab1dc911bf9e1c"): true, + common.HexToHash("0x7480e990e89f974baf1c89cedc471f9c257098546480093431f3eca825f856ce"): true, + common.HexToHash("0x950615d9bef4301a6ecc98467c2ceee8f2601db698b48d27749f6bd4e46ab238"): true, + common.HexToHash("0x27d34ce49c64ecb25624e571b0f5db99ea45006e50dd412f13519ad9d61a7e41"): true, + common.HexToHash("0x37116b48ec2cefc5f0448e0d73547f158fcb3d289cac2d68d730fc86419ed0eb"): true, + common.HexToHash("0x2cda5662b94960ef37b340ca1b92d4d604529a7403fc57434cf9957cfb0d319e"): true, + common.HexToHash("0xecc9a0286c972f1d86682182728f70c46438b5a3297de5d9152bd7ab4c5fdb43"): true, + common.HexToHash("0x903ba6d8d93a95fc60a5064573aa06296796edb24c620caa7c4f1a3db41be5ed"): true, + common.HexToHash("0x8df79b28400f9c6eff755b015199cf5eda266e210116ed90c33728b65c5b6a8a"): true, + common.HexToHash("0xa41c571362bcbe8bb1f50b3259ed1b4ae1ea09265e36f73fbf30a340ce4d582e"): true, + common.HexToHash("0xdd14170370e63931be1859e627d95244984609fbf684016986ec039b26b1e63b"): true, + common.HexToHash("0x0cac2c0409bfed659248daa21a9d5c1008691a818b16f16e6c89821f06f8968c"): true, + common.HexToHash("0xf5b29d27921a4e07cfe7d5511d1b386cd663aa64a53f3033aceddae3725399f3"): true, + common.HexToHash("0x00ba58333478cef883b48dd9737279a041fc02863b56e048ed0e50cb12769729"): true, + common.HexToHash("0xe9e3474632344997ea0b8698b85dd6f7131ebc28c243e03837e04a42796cc99f"): true, + common.HexToHash("0xd9b21c13386fa0ad7f921c091c845da4ded270a63dc80c0051fa285923042c55"): true, + common.HexToHash("0x84b334a0118ae35aefcb35138452fee5e842c34b7d253a8e39acceb5ba408752"): true, + common.HexToHash("0xe977c5b5c1eeb92c3cf350e11ed40a3788f26e642264e84447df94fc03c60ac8"): true, + common.HexToHash("0x24f9fd0c552297e5c042f22209f68b20992f93ca2efd61d8385ee7e80b69fba8"): true, + common.HexToHash("0x556fcd90d8b661fe67ee3ac65cdef4a76bd979b69b5d13a2fd24393c93494079"): true, + common.HexToHash("0x10c4c9b8392f44f7823155a18aab51cf23b5b4b0ec099350e96743879edf0998"): true, + common.HexToHash("0xd03e35fb490f29d9f31b5c70bee823827473e0b2b36f7c807bd631b35e0eecdc"): true, + common.HexToHash("0xc66909d0578af6ef16855136a0ad9b6d1b162e254e6bb8db34fc6db0facd8387"): true, + common.HexToHash("0x2970f34995bb500e1dcfeb0586013a073fab33bcad9b6d564a643e55fca1d425"): true, + common.HexToHash("0x8e76b080bfbe8ce8a508ef0a77342e6b721b89a2eebe687e793a068495e9e8e1"): true, + common.HexToHash("0x72c8de56056136f0ac11050c2027b442c197968fb478d4811dadfb4f0696fa50"): true, + common.HexToHash("0x334a7bc05d99cd14280780fc668fa54e14201d359dc5e916fa91f153d4f49c03"): true, + common.HexToHash("0xa42e1201bd1cd7895d6fc363d334287f0d7e033d671b8efbce4617de5bc795e7"): true, + common.HexToHash("0x3f09ea0415b5db3836673e4e24284506a03e6fbe901360836736febcd269a7cd"): true, + common.HexToHash("0xf3cc28d956be68dc298747f44a9b0e52b884817fe37078d379011c211e1b3ee8"): true, + common.HexToHash("0xaa866baf1d7956b3bdba9f0345cf862ee73cb27d31b734512db53b72e2e36236"): true, + common.HexToHash("0x9589986b22c2b5694c76b29b7863a018378afb40ea951c41f966a195212d1579"): true, + common.HexToHash("0xb51d96401286e92590ad5b181db9890bcf0d9720213d89553e075b14d464513e"): true, + common.HexToHash("0x373b7acc999eeae784d50911550e5107e5d1dbaf1cfa8d195ee5ffc214a28fb6"): true, + common.HexToHash("0xd725aa21e5d29adf65cf8a60bdcb493f2588080f0cfad654b268a85da8c1782d"): true, + common.HexToHash("0x5eca8fec5d75616571afea638b6ca031a6108753a6541c7a5cbd63d16aa8f81a"): true, + common.HexToHash("0x4ae0b3c0870cf2dbe34c33ff9155d3f231d509cd00e4f0c92bcce8e05ca9e4f1"): true, + common.HexToHash("0x5f269e85734774160b9ef17142e2ea22dfc516a9dd9fa730faf750767e8ea896"): true, + common.HexToHash("0x39e6a17db6050c5fbb39f8f70e4ae059bda9196dc88d33d9c15662a66eede507"): true, + common.HexToHash("0x5f599c2336bd9f157ab66f13e472ed28dbd32edc105e6226fea8d8ebe96864a6"): true, + common.HexToHash("0x0f3ff2e5cb17719d2e2241a33c2f53548735ef4c229df52100089f87c65a01f8"): true, + common.HexToHash("0xc67bf502d5a0292c63ddd01ccb77dfa2254ea4e82cf8cd474a7c451c0df0b5cb"): true, + common.HexToHash("0xf7e655bf9fd50899539e225a318df833403f6bfa23f685c8037475b2de330517"): true, + common.HexToHash("0x12842fa71c116a4739eda95ce7d9af689e08b97f0327e7b37c20e319772aed02"): true, + common.HexToHash("0x7da551e8d63d788b5df95675cefbaee1295bfb5dbd5b673e162e26dbfbd371fd"): true, + common.HexToHash("0x417c60633ddcc09603124aee9f99391a4ff620e5e47ec78bbf0b73993a7096e1"): true, + common.HexToHash("0x537e93415e0b141685f9459dc437b67719aaf4baffccd19bd60fdea18b1207b6"): true, + common.HexToHash("0x8d306eee409cff3e3f17b13f0df0570f0044a9beb804fe88d0efe653592dbbe8"): true, + common.HexToHash("0x2c77540c18581c46a86941a63caaadeeb1a774ac18bed407fa506a04320ec1b3"): true, + common.HexToHash("0x61f674b711a7d784143958586754ae21f31850750137cbfc5506cbc1df69d54e"): true, + common.HexToHash("0x1161a2dc246f7f4294184837385effbffed5a2969ef578fe3a9c0a2e38ad1e91"): true, + common.HexToHash("0x18a2ea69c47ff8d12b206d7694f8c8b7ebf5b269cf0a089bc593a5b8d8f8d2df"): true, + common.HexToHash("0x06456732ff3692a68b2ef0fd3efea785c866f8954e92dbbe4e25f7106b75972f"): true, + common.HexToHash("0x80e6213be930acf257cc7464fcdc931b7c4e87523c2b312b7e4b4b9a81088432"): true, + common.HexToHash("0xe9e7bc1e318b195f201872b6ce1cd92e2fa2706dee3931fd62a628f6aedd9671"): true, + common.HexToHash("0x7b4144a32ac88ada47a5e521745c41f7420c4422d721262051e6facc43a5f5d6"): true, + common.HexToHash("0xfa9db496759bef95ba5df7195dc6b75bfc082324e83ebbd3a69d7f07f91710cb"): true, + common.HexToHash("0x77fd2d37bd4befe9b7270457e01464dd6ade4afb25b55489193577729d60905c"): true, + common.HexToHash("0x84fb14ecfb502236c39bc8b325e5095595d9a5d6c3b6256ba40c98386adfc6ea"): true, + common.HexToHash("0xaf112c0eca792508dbb66b138c69e7c7d6139c33f21a5d862a027144d3ed6158"): true, + common.HexToHash("0x0caff1c32dcc67c4181d68a1c3ab49f22cd8ffb894f32036065ecd608fc4cc49"): true, + common.HexToHash("0x649036e860783cd35ca40adfe833b88e177bacb8e73c1d2154f653d52aa11eed"): true, + common.HexToHash("0x31683a1663d713be976732c78761744b5da850e99089d7f9d51d90894ca65e0a"): true, + common.HexToHash("0x43388ba66b143470e3ebc42443d72cf53b50509b704286d3b80e0146fd324eca"): true, + common.HexToHash("0x9f42ffada9d7f5d253a27e2cf45cd21dcc4c74efff10a9b3e86edee7fe0be7f1"): true, + common.HexToHash("0x4675f9af627930449492a2530ef6dc11a6135d48137dbc3b477f02a22d85a943"): true, + common.HexToHash("0x0fdeae1c6d3deb7b40b9cdedac3202436093e36257ad861ec2d31cfa1f90bed3"): true, + common.HexToHash("0x3a4bc06f31a43206d24b9441d5b6bdbb0e8bab5fd4894124b6e1ad98f536d7ad"): true, + common.HexToHash("0x11ac2c62c154c10649ece939ae08968d8dc3f6b82d9130a36252711fa2f22294"): true, + common.HexToHash("0x0a88d346cea3a30ea1103db0492e74b759eeb416f2dd3cdee131d8b50275399d"): true, + common.HexToHash("0xc8b11fb3aa99bec0fcb38e9592159d6cb8213b0ad42b3d24960d739619e24bf6"): true, + common.HexToHash("0xa2620d68ad838ebb48c155ccc52e53f0af03e5384658377fcd1a3fc558e517f0"): true, + common.HexToHash("0x1bd9821087969cf3d47ebb080b4036acbb696b090dc3c0aee5504c8c5690d06f"): true, + common.HexToHash("0x5113c7aa57da34e5ee151f87d03788ec225a12a82d21a297650ed3b6d568b9a8"): true, + common.HexToHash("0xd0723e48ebe4c61133816e40b40d8c8635aa16a4a59ca37599e175d3e9db8669"): true, + common.HexToHash("0xc416cb6f3257d88a08eaa4d386c256a04e2f0166cc2564961675efdfc2af47a2"): true, + common.HexToHash("0x94cfb995ad8d3ebaa75b068c2715c4ca3a72f9b449767856e012c78696f440b0"): true, + common.HexToHash("0x9632c04f0ca1d3d598c6eacfa7d7066668928b83c71579c0e161151076bd84d5"): true, + common.HexToHash("0x91d6d740b99cd444e76aecbb30bfbca136c51f48e767a68aa9e769e47eac986e"): true, + common.HexToHash("0x9efac6606d8bc153816a442e9d79067bf3310d17be6a42a8b933d027aea2c13c"): true, + common.HexToHash("0x8434394eb0a11ac63bc434c8d5ae1018a0db875c47af2ea469912dc244300bb4"): true, + common.HexToHash("0xa71ad5f76ae3bd88371af9876bced44efcbc14fa944e01f519c1a6eac005e335"): true, + common.HexToHash("0x19991e160b8340902e37ab05be457d7f54baf5e18d73c0fb682ad5a0aab39705"): true, + common.HexToHash("0xfbd8b7cb90798660b705ce62c7d825ca34cbc59d5ac5f55b90d47620a6fd2119"): true, + common.HexToHash("0x9ba6b6a520c702f767433a94fa68bd200503cff0344280e574e7bdfa6207be64"): true, + common.HexToHash("0x1e65f2000c405050fc80d00e0a4f835c3baa0405dc68087ce8e13506a6e139fc"): true, + common.HexToHash("0xf4d4f5d3c582c634448a08a868baa6e48dffcfae1245611166ede12359b4b831"): true, + common.HexToHash("0xc6e74d4fa00cbe0a1c259eab6522b9aed6008b465ab6b66e98aaeb2e50e6cf24"): true, + common.HexToHash("0xb5a9b42f355e13c1ed36dca1c806c331e50a53ec896045dc94460c655fec870e"): true, + common.HexToHash("0xf01ac805232bf99f699187b5189dab5ae066242bf2f3568122ca579781be9340"): true, + common.HexToHash("0xb5bcaad884100e55d9d0165060fe8b59249c92e03c354300df25bfeea46c735b"): true, + common.HexToHash("0xfe2b7a9db1d234d0b97eca6f1800d42aa5ec8db03274c7d999bbfabb4ce18ce3"): true, + common.HexToHash("0xca83d0d609f24c7dd5e4dde364f9bd7e3b30c909531344aa7bab20e3723c5f88"): true, + common.HexToHash("0xd581131d99997b635b11fcf6b86b2afa35273550f6e870d70dc00d79be3b5c77"): true, + common.HexToHash("0xb417da01483c7dab0018ea84935fb831332f76f6bdaa3cf660a4c418c6b7de7b"): true, + common.HexToHash("0x8f9da3b545877c8d849197b8b884af857f51f27313669dbcfbb84da78a7f6fba"): true, + common.HexToHash("0xa285c8670abccfc390c78618b9c65aa061c303d038d1f9a26cc2d48ad2d1d23e"): true, + common.HexToHash("0x9823ffe090922b15e2c3b6221edcd4cb7cf7cf000d8b059127929d93b92a6dbb"): true, + common.HexToHash("0x4abf96f139f75cdaffa749b696b87ecd1f458304f64cfe194641429144976c5c"): true, + common.HexToHash("0xd285a32ff1fc8abce72ff4a7071e21048e218e0c5570d60e7134b8f25175e2de"): true, + common.HexToHash("0xa188d0423d3e5ac59690219ba50e5497dd172eed55f2bcfd5ae24e51cf632c83"): true, + common.HexToHash("0x018765884f07be666791749b6569dfd08440d5883bde2d8ada6a62ca072062e6"): true, + common.HexToHash("0xb5539925e129f9ff22d34f979da98827aaf6e5af015c7b227058fc22b3c8e251"): true, + common.HexToHash("0x5f7795216a094c3c09104f2efd839bbeb426454807b28515a7afb959898d7784"): true, + common.HexToHash("0xf7eaffb3873c9574359fae089c963ca5d60b7d527e5ed427b977fd00afc68be2"): true, + common.HexToHash("0xc91118a888d0b20c4472be0171251537d3460d8994a00b83dc4fb0e4ce81e8cb"): true, + common.HexToHash("0xd5ea85a036f75e844c036c7393280c22d229af75e003907d88aecec53221df2a"): true, + common.HexToHash("0x7607a2120ee050fe1b7a8f54243319c7ae1ddda58c71dc1a4b14a4d43395ec42"): true, + common.HexToHash("0xd92624bb04a30f8be5c49d48f5154d7876173037e9cbc373311422680426adf9"): true, + common.HexToHash("0xb7d8eecf46112b7be45efd760036033531f72df59126b96db7cd6796c6c8fa8f"): true, + common.HexToHash("0x4272a0a1b462d44fc5cd955f7b5d65cc86aa47aceed9e90ed14eac58abbe3ea9"): true, + common.HexToHash("0x87e6f24e52c4e03f5a0eea9cfe6e45476b56131ae815f742b8422db5880d0f7c"): true, + common.HexToHash("0x9994e3be2fecdfc3b3ddb099c9e60e6416e15eaae7f1cfc540cb5c7d02f79655"): true, + common.HexToHash("0x4b7a9384c6630e9feca04ce78791fce3240ff2789c0cfa2b727b0d53edeb9a0a"): true, + common.HexToHash("0xe98faea4294811b16b6006dfe1bc8452fc503a9333dbf96bfdd26938c1314e81"): true, + common.HexToHash("0x131df18bf101a6a66fbe6ee9bf02032a7b73ed871d3e0b5b4e5337d0c7247728"): true, + common.HexToHash("0x4b3dbc8b3ada37f947047e5c7d0aac3b53e0da5c864c73b34a2de5b486234489"): true, + common.HexToHash("0x4eb1abbc0aa213eabe7a2df5e200d383e78fe4cf6b8453bc59f71559bf57bc1a"): true, + common.HexToHash("0x083b61259cfc92f7d111b75ec9dcfdfd1437a5844cc8fe689187ad070736a73c"): true, + common.HexToHash("0xa1be9c0a0556a97c5e926e2ec53f2527c9f9b1a7079355f0c867693ec8edb4f0"): true, + common.HexToHash("0xe3d68b0ff2b9890982e7aafd8462987cd17804d30f23c2bff5b81ccdbfb9c333"): true, + common.HexToHash("0xfd430818e02cbee8f5e5aefb9b9e6b4376e589ca36708898c669267c26eda6b9"): true, + common.HexToHash("0xc5db1eabfab6fa471fa161b99cf9319ee9ff8e2b3cfec1842ac1d3880d203b8b"): true, + common.HexToHash("0x3c60ef0ee53bcc53aa2fd69ed32fb21376aa753342bf981330bb16d8b1b0df5f"): true, + common.HexToHash("0x620b5e0787d813601a878ff49199e61aa801a9b8d5e7cdc9d031c45ed091080c"): true, + common.HexToHash("0x103111f4048ed8df4191795b3c7d3716e14408eb0a9fcbd994473d678914cdcf"): true, + common.HexToHash("0x7f3f0999dd631adbc605f50a5ffe61b9c41c0a117f3cdfdfa79082675d3989a1"): true, + common.HexToHash("0x33c0f93cff75d3014cb98c201430674b36e56337f135298c6ef51cc14ef6177e"): true, + common.HexToHash("0x45bd5fd97c9a99340205aa83b33e72e45e97872fd6c91bddf7bb8f9efef6e6b6"): true, + common.HexToHash("0xb81d5325f14d156ba987521752ce1c812f80a6992a746d9ca9757822bddc166c"): true, + common.HexToHash("0x599f5a4c2223c8efcb3dfd929cb30d840857db8a9dba63e0f18e207f5b1cf6e1"): true, + common.HexToHash("0xb83b2cb6dd053fb353665e63fd3607850e9f61ad01ac9a9ae631e2218ae2aeb5"): true, + common.HexToHash("0x564f1ea738f1c6fca0cdae1daa934af54eecb9812ebd0532481c74c8d9829903"): true, + common.HexToHash("0xfad622a9cc5eb451c15e64ade9ea57f9b55f7121a138b97055ed238ea1f7639a"): true, + common.HexToHash("0xce8a019b177a3b390cac9f2dd3dbb2aef7b54a4890d3f95af280285f469cda38"): true, + common.HexToHash("0x8855407ae3a9c50e1de94f1ad688cea483cf3f6a58fa1b85386e83fd87a366d9"): true, + common.HexToHash("0xc2011c516a026922389017ac341bac29ac555a15863b763b002160af0e5f2712"): true, + common.HexToHash("0xe65c6963e78e0273bea39237c9d30f6c0348ca30a5e78a10e131b40defef3879"): true, + common.HexToHash("0x4eeb4ed0abe32024462b804a68b11b282fee19c438ed32e43c2399de6f24dfb0"): true, + common.HexToHash("0x85db36a0e7fae5d4b18e0c851c3792c1f70ec310b4bd92f9ff13b633318dda46"): true, + common.HexToHash("0x4b34c88df7908540befaa48d424bb3de0bdd634bfb8099aae376247a42aaf63e"): true, + common.HexToHash("0xafa65f0565e3225ebff3e2edf563ddfc55b64f736cf86d66de42df543d88b66e"): true, + common.HexToHash("0x5a97a7e513deb6c8bb24786ab1576c8fe13492234c8ab23e134baa364c90371e"): true, + common.HexToHash("0xe9d67ef48b30f7a2c9806b8f73a8ebeeccc15698c454b531f9eff62755b91bcb"): true, + common.HexToHash("0xa791c5deeb418f05b3ad870dda7a20719d279c19e81842f4ca083af9861a1bdb"): true, + common.HexToHash("0x01a10c888c486f7f953c95db5b37cc3c150a16dac15e1d75d3ab9c61c7c4d24d"): true, + common.HexToHash("0x1c5f4f02985a858b872eee41b84788e54a71815daa62abdc378967e55679f257"): true, + common.HexToHash("0x53bea36a8b85e6923dfc99186a14a921829fa010930198a049d82a33c2794d30"): true, + common.HexToHash("0x16a8a95b0c38402df1f9a0fb720e599914d0aeab323da35f4741f0d36d7ba45a"): true, + common.HexToHash("0x624b2f325a6d00b28ab547321ea88d472f910f1304e1f8a5b52af9e6299978a1"): true, + common.HexToHash("0x2d81394ef682cbd7c01a5f81e731a54ac1722277d1a51eddd46328d3553b6fae"): true, + common.HexToHash("0x8a9777b5d618524d047eae527f10def9d393586a008775561b4f8658eafe03aa"): true, + common.HexToHash("0x84d1cab45e22f205d9c52a7afff8cc80c8aeb76a62899ffde667dd11fb92053a"): true, + common.HexToHash("0x730f3a11dc1b4b7d219a08a5f212a1a04e64e7a3e90b4f3ef24da185b876021f"): true, + common.HexToHash("0x1d865f3915293aeb2bf2b402c4fe9c69cbe970e054578da489d0ae20d8e6b39b"): true, + common.HexToHash("0x4e1da06486f164ef3fbd7b4fda7f621fba2132ed330450739f87cfbe43b61065"): true, + common.HexToHash("0x18e5bcd04292bbbbc638e7959fb15c439514a6c47657ddcd9860865f96c4e0df"): true, + common.HexToHash("0x5cb888c820b939c51a2d5cf0ce57b3891557a78b39d720ca425769e4b02ee6c2"): true, + common.HexToHash("0xbcbb07e464490e57a98ce6653c6bc9e36837ec957f227a739666e7c6bd6e032b"): true, + common.HexToHash("0xee076af06df5c681b5b8ca31d356290975130d76b02066255f3b1e65572b1e2b"): true, + common.HexToHash("0x35dc89add630115da3d18b1f40ef3287bf10aaac68d346bef168093307f24e6c"): true, + common.HexToHash("0xaa7be7fde2b4108609a7b6e91195a7cb6f8e6f4c548dfe8169b7400f5c61c960"): true, + common.HexToHash("0x165659163296702ff66726d35b917d9906724e09413185b0b8e3efc4ea864a19"): true, + common.HexToHash("0x6b181013a9813cd9459f57033230d52430a9a81e999617f0c67ec2dc6a51ea29"): true, + common.HexToHash("0x4c25f8bb98fab21a37742a9da20d377d506c36123e6f78bd1c91b724687a4d85"): true, + common.HexToHash("0xd6827d997da01675ab810a8d442bff3b551ad09c7413ecfb01daaceb8d5e4655"): true, + common.HexToHash("0x2ded121f38fb4c6da173dfb2a60f99d27e282806b2cbfac47ca3cef6077d1ca9"): true, + common.HexToHash("0x96029aaa47163be1f7b3b607c81edb2dd767fb338b25d82efdfdf5e08110ff2a"): true, + common.HexToHash("0xd21729ff790d5b4722116ed3e89a684a2a57ddbe70b1646c397304bb8c3c70d7"): true, + common.HexToHash("0xfcc9eb190cadeb977284fd6426bf4fd9c09ce3d4f44c7271b2443ba76ee3fa5b"): true, + common.HexToHash("0xfa1535ef48d3d9b72b3ad3059a4042e20f9d8515f93dd68f43f2ee110a537c2d"): true, + common.HexToHash("0xacf2369512bfa76093473a41520ba5368228e6823df7813d59ff53431aa26fbc"): true, + common.HexToHash("0x3e03413bb2e2708a411d130712b9b94c622f6c7e2a72b62c87966cda29c6a00e"): true, + common.HexToHash("0x1a415d4de4715742885c3fe84d49e703add1638ac860fd64d24ccb18577964bc"): true, + common.HexToHash("0x4aae0013ff2198d4f1011b0f200661358db6fea5f9a9cb0268b196448bcccea6"): true, + common.HexToHash("0x976175d8f8900ee7f9d2305e081ad268065172addbd12ca716c790cea15c01e9"): true, + common.HexToHash("0x93480d3b11e4cdf9c05dc4f32ed44acffda3cc9a21b5c6fd3168fd5731c8462f"): true, + common.HexToHash("0x1ced0e5c336e08e669e3feeae10e81e0fa7e909ae9ce222bc46216a057ed7e5c"): true, + common.HexToHash("0x73b3d5f9c4bc10ab8e1d4d629689f8c03c88bc319bd9a66d35dc3a53c6f48f6f"): true, + common.HexToHash("0xaee434f076a637adc4fd5cc83a8de2e6fb3cfcc4ab00d1b5fab5f1a1efd797ec"): true, + common.HexToHash("0xee7cfe5d3e98225c9321147ac86d2d7c100bad8413ec6e67f179d4eb11234696"): true, + common.HexToHash("0x7a0e485e6754a69ec6434b7dcb0d54273ad9c1481b3c7835de4c435a418eda33"): true, + common.HexToHash("0x8b1e4c95c04ddf30f34647052176fabe3b68112f3b7020e2d279040321599724"): true, + common.HexToHash("0x5224b303ba2e506974bb2f95adbc8164635c6012126bd99d6d4f41f172b38db7"): true, + common.HexToHash("0xf7ab6f24efb68f4b41a76e658c623385426185e24244612c259346231e359bfe"): true, + common.HexToHash("0xaffdc9f3732992492cd7340b7b02251265747539185d1fa9aed069b81ce0b212"): true, + common.HexToHash("0x340236f0bcd69ad68b671c234ccc7745014a23e8838fbf44df1a81580de19443"): true, + common.HexToHash("0xa67f4a3c9236a1c03a0618b0b0797daab67dc5d5391805792da01b3547bea193"): true, + common.HexToHash("0x05500beacb71e1c16a8485c5bcb68945bfaef845cbb1452a6274a35aab901151"): true, + common.HexToHash("0xb2d5aabd51e0a62ba9ad2fe8d9fce5973b02ddba58984e59aeb6cd1c9072d95f"): true, + common.HexToHash("0x50d8a8ec3c715947defe052866ece9acb7d74252d55d25cc0f2c1eef2727e9cc"): true, + common.HexToHash("0xacbef6a08b933e54c5a3f835f1bae0290817c819f71b92c8d43b2bfaf3b3ad3c"): true, + common.HexToHash("0x892a7b11ab73792906e62e7d6b7bdadf9be9fa45e9445e15b7c7220e18b8ab4e"): true, + common.HexToHash("0x777f33e124da040e6cb47154f2769dc966980d93747c15899c32367c6bf4eede"): true, + common.HexToHash("0x4b2ff0fb1981fad2a07dcce83e8df9c3492d37da7d493e81f9b0cb6b3d30dd5c"): true, + common.HexToHash("0xa4795ef7efa7e1e9441b19d2cc52dfbffef6eba467d53bf5e9aaa860d4a30633"): true, + common.HexToHash("0x38ec2227cec02c24871e285fb8ead6ed38751ab9e34e92daa9318e95edb3691e"): true, + common.HexToHash("0x05d5d07e8fdfcd1320867c8a170509f017a0e70537a4017f88028755eec49484"): true, + common.HexToHash("0x633ee5b7d0611f27d1992ba881e20cdb62ec0a633651a97a37c26a2cc67f1711"): true, + common.HexToHash("0xd7d5065dfaf1a2594930e62d58cb8194f13cadaefebf25a2fa1a0860a374f550"): true, + common.HexToHash("0x9e2ed445d13d275c66e523f83939c0b76bcb94242d1b42360e3b8f2961bd7616"): true, + common.HexToHash("0x73df154d7f189559a98d2b30102d1f005d3bc2ad56fe44a0514bca54213f307b"): true, + common.HexToHash("0x5f08e944c0c76813ffbdc7974a735c5c300869e401c5f9aee2fa2134befe011f"): true, + common.HexToHash("0x99c4357e355c5de1be71d0650f50147f570d2f98641905226cfa9bd501c04c79"): true, + common.HexToHash("0x17a7f106435359e4142da2cd2dbfb554f62e68d3c77f790ed16774e7c5dc8aee"): true, + common.HexToHash("0x928a606a50f190be1a3910b22d0f1b4bf15ef4726719455dd084461c6687fcfc"): true, + common.HexToHash("0xdaf4d06b04e890efde2740d10003536f4a977e53693ee19e6d3d4bd3a9642743"): true, + common.HexToHash("0xdf5f37ac0d597bf550bbf9babdd6c22e9bf57b25e2d3ebc8e5572b155ef1673d"): true, + common.HexToHash("0xe9e95fb42953d63811757c33972ef7195a6afcbb54d8e7b06e97263beab87d4e"): true, + common.HexToHash("0xd1ecb7b37f9bf145e8565ace3ba4b2494f1e8fedf5ddac992e54706fda7bc289"): true, + common.HexToHash("0xdf0fcfbe97747579e888063c8da12c3097be0c11b9f085ca119186651d5f029c"): true, + common.HexToHash("0xca7330b0c85f9b80048aca5fb37fe1d99de39b610ea529117175428de66b32fa"): true, + common.HexToHash("0xb56d56ebbdd258b0b06c83fb7679df5bf48c82ae6978359c109b405ae61ee7b9"): true, + common.HexToHash("0x8440bd77eb9ccabeaa2026020f5a16b3eb4ea342a99854f572a4f878d774b3e8"): true, + common.HexToHash("0x7606b756409f965c520150a100f8e0926997d2acae5df7c7f57f5a8f354674e7"): true, + common.HexToHash("0x72ca2a33d342c0615307b4e0450738c1f01f36bf9912ca6da9b01b8ca3b5c566"): true, + common.HexToHash("0x8de311e22ee665bbe13bd2be62654b55d34b43ebbdfa368965b4fed7316ee099"): true, + common.HexToHash("0x99a2ef8800ccb1ab970c38baee7c5bd3465b26e9baeac1d6cd47318d3799da16"): true, + common.HexToHash("0xe5e742d9bbfbb60a34c5f4c0c67b3d397ac99b0557b390b44398af7c54610813"): true, + common.HexToHash("0xf74c335bcd280647921c0d3e293f85b8c6fac771915fc6f9393e732cb1d7a208"): true, + common.HexToHash("0xd8014ff1db70186f50c75cadafcb3f03ccbcf9adf480b1c891a3f06cfd5c22ba"): true, + common.HexToHash("0xfc66c529938fbf9c6fa54b2a6c15abd6b7c6e16726982edd29700a771cc6a64d"): true, + common.HexToHash("0x88fc38fcbcad0d9e149ac9b9728aae8ffb0cd30c0d3f102bc67b255c96899204"): true, + common.HexToHash("0x14e4badf5e7c0640a2733381ef6f857406655ae765e8475113cbd0314002dc00"): true, + common.HexToHash("0x7845e2a9715ed0b7978006a00067d55788fcb89e511893b6cd6974297ec30e65"): true, + common.HexToHash("0x3450e934c198f1be9053e39079f8128f31e06a47f595d52788a62e9434afd8ef"): true, + common.HexToHash("0xdd02476a59d0a7ba6bc40e637c0768ce155dc90b2c7a7ed8a94b1015e06b2184"): true, + common.HexToHash("0x68f9a369810341323ce033d742342275b9446a3a80d2afbd1e595d77ad203304"): true, + common.HexToHash("0xf7348289f8faff050ce9f8b197218b18c96cee4222d60d66edb3a5e39cceedb0"): true, + common.HexToHash("0xf1678dd2775c3c32c9b1a1e5d8f99a05c51eb9a9d484b265665d073cc607995c"): true, + common.HexToHash("0x26ad8891804efe9f073945fd34f96f669579a18368b355015873deb2dc21e578"): true, + common.HexToHash("0x8c8408bf618aa68b1cc6166d45f8166d1db3d282f33c82994f22c50e8bebcc56"): true, + common.HexToHash("0x5970364e8ed733849994791caf2cbddc84205969b1895f5d17add81822bd3bf0"): true, + common.HexToHash("0x50fc1710f6d413f2bb527abb39f3c4d434c4f80537d581fd21858f0968573492"): true, + common.HexToHash("0x66e7dc6fac0b54109fdf696c633741931a8f310181aedc534135a0fbd32dc4c8"): true, + common.HexToHash("0x945a26ed98d603368d4528594dc71ca26ff2eb0823d7b523865b1ecc10182298"): true, + common.HexToHash("0x9c9965328d65a9310d5fa84ddd8a9db4eaa65562a8b6c2d18c6225c3db53230c"): true, + common.HexToHash("0x66f18d4d5f8d80fb458093fd7967160a4c80241bac8f4177246b3466ace50826"): true, + common.HexToHash("0xc051f0925d956dcf992e43520523c67abc1919d4a67db29d8a566d9bd3a0d8cf"): true, + common.HexToHash("0x1aed5799cd5655f8b3bd09ef4cef4d8820cfbe2e2c2fbbb37a27929cef8637d0"): true, + common.HexToHash("0xd40f14c13c113d241b727f3cc2ad7f4b2ebcf46ea3f9bee0721dc29ce488d167"): true, + common.HexToHash("0x9e180b58c67a189d4bef850184df8a19311ceb29937803f90fb0452e983d7cf5"): true, + common.HexToHash("0xb4633d697c4c51cab4446a47383102205b2b31ca4993108ed7658ed34710034b"): true, + common.HexToHash("0x919b1f4e0ca0b38f8f4450b955f29c0e60908965ab3df7fb3399300917ac8be1"): true, + common.HexToHash("0xc15f66c091a2ee0318e89e25a2323676a9f8504d31c65e6df8c64ce1a7d51197"): true, + common.HexToHash("0xfbd97a0b3e949630d6e885e7bf7f0c21a1f45753c3ed9bd594d6c782ce39c7db"): true, + common.HexToHash("0x8a14da08f2b2ce0b8cdc2604f395a6295cab0495d938cf033ebd5969a1fde7a7"): true, + common.HexToHash("0x4ad85e32cf7acd812611c8e00ed4565637190f7edfd3753b0c6123c7b41d613c"): true, + common.HexToHash("0xb30bc1662a24e740c87d0573ab3e1d4ce82246274116f6555a0da71a34e15c1c"): true, + common.HexToHash("0xd8875d19ee3543143d1b54b395d64c721d881ae5b37c3395fa3fe43c888ef042"): true, + common.HexToHash("0x7a0123066a901538f11dbef795abc559225f499e9acf25fa7600016c32af1233"): true, + common.HexToHash("0xe26bfb18d27274a020fe484d888dcc5868527fd67f1e251fc08e9fd5a9598f34"): true, + common.HexToHash("0x5c9f9f0daa4d71fff2b23d8fc630818bd5c00f5a17dc1fead7076b0167295505"): true, + common.HexToHash("0x11f4aa63c457f0f71537193c9ef4f7bbaf29315717b6bbf808d4c5d5c7f1ddbe"): true, + common.HexToHash("0x1461d5474919e00382457badb02ab6860b1f2c97346e413479c326506bf68c44"): true, + common.HexToHash("0x33277a2da07ad4530388e7279b449e2bc7adec9b3ac19c058795af289430fa05"): true, + common.HexToHash("0xdb9f14197112ec93b371f5765424e0f67dde09d259211fca759b2f4a5a06d09b"): true, + common.HexToHash("0x8f8e7513ceb682785597d94133dd149e726387089b97609746350eee71633943"): true, + common.HexToHash("0xca4e1dd63d929bcfe1e3894ec23432f0aff9f1aaa7be4af84bf1a26ff629283a"): true, + common.HexToHash("0xbc9383f2fb013f11e25158ee1bcc95cf670173fb7036afee0c0e4edd5bcfbb83"): true, + common.HexToHash("0xc011cb9f4d36e9787dceccfea80b514f68e9f59731e68dedd681395194527b87"): true, + common.HexToHash("0x0fbcb76091d0b1567860444aa00a4b1c650228dea86f6985ad47ad0cdfe401ad"): true, + common.HexToHash("0xa20ac10d7338c14bdcede685dab04c37129601146a2da6e60051cd2b1ccac819"): true, + common.HexToHash("0xa7772921c9c6c1ed9647ec5be4a49b07cd332a5070e3b815a5e913384fb7baae"): true, + common.HexToHash("0x3321c5bb52007146f2ebd9d1af7b8ecf09d4566f629908b15017ed3d526f2e98"): true, + common.HexToHash("0xb3f27bab79de5eb5ac9d2d73005b530fdaa15321c0851532bfc2779dfe2aac8b"): true, + common.HexToHash("0x45fa9cd52896e0e710c50c6bf609471341f932b01d97686d57ca6464a70395b2"): true, + common.HexToHash("0x5aa42f46f4b1358673be4328ce37587b59d18f7a66c0f55da6046ba7282a56c4"): true, + common.HexToHash("0xf22c46d8186ab6fab3d03a986419f287807ad10110abb9214db9d14c2167808c"): true, + common.HexToHash("0x7aedd09880e94ee287bfc9399dac048af289423d89137e4c68b427ea110bf0db"): true, + common.HexToHash("0x4b71f238a01a7961c9ccb9613377d15461a15faeb158745620518e9295bfd5e0"): true, + common.HexToHash("0x256894c21988e9c425a8998df76ea0393007ca0580e2c5d266682f74a43c5439"): true, + common.HexToHash("0x6ed10363a8ec5b03376f14b86249e7087d07fc1297371f3f63f4a2813d3e130f"): true, + common.HexToHash("0xbc84d86ca8815c05699998437ae3346b4eab36fd798db209d125a838f36e87b8"): true, + common.HexToHash("0x35ec10906d5de47aef9ed2345a497ab66b43f6cde66143b096d8a4742d0b0a82"): true, + common.HexToHash("0xf59a075118cd2bd3656fca2e09fc9a3bfdeb77c2a163bc38e19e6d4899ea1645"): true, + common.HexToHash("0x7956924e700f2b222dd7ac37a62072f28f63fcaa1e1013eb52858269c1d79430"): true, + common.HexToHash("0xc78da3f3078737aaba7e9334dc2467a37ba0451018f79b70f92679a19b1e7b1c"): true, + common.HexToHash("0x10e40c9a35f3bdd96490eade4fda07629811be44437cb06c01b0c50cd22d3a8e"): true, + common.HexToHash("0x76c9081590bddec4317a89bba9278af1a07da00e8cd10c3e09868beb670d5f57"): true, + common.HexToHash("0x5d3981dd24efe1b0374635f169fa104962070762d12b9833a6138fb6437cd22b"): true, + common.HexToHash("0x7eef7e1b5e70e6fba8a030292bc5df805637697d9c5165fe06460c56df71a175"): true, + common.HexToHash("0x9fc30fed7868b1420fb5a919e5146cd758dc403c0fb462f1f538e47e783fd71b"): true, + common.HexToHash("0xe7849ca65cd9b7155bc105c22ab9ca94485ecb844f84e21ef152556233cea0a1"): true, + common.HexToHash("0xc8df6b759d22523488191aedb3c07b1dda510db76c7b872e597b40670921f056"): true, + common.HexToHash("0x72eada5715a98a38482c8ccff83bde1cfd6e2422162b14484185b6a4e09a9648"): true, + common.HexToHash("0xd6f87ffae7cc4fe201a7b25e8811ab8e7d9bc6ca9a48a7d6a041f7070b28f7ca"): true, + common.HexToHash("0x11a39686952d49c12a667516585f3fb353b62ad89801b11f75d777107083185b"): true, + common.HexToHash("0xe3175811dbf3d6af124d8a4b9a68bfe4f7fffdaddc69938f2d034aa94db01490"): true, + common.HexToHash("0xd84c8f3dd0f0d313cee68bb498fd918cea569089995f4b3dd3b2a727bbaf6ca6"): true, + common.HexToHash("0x44e34e7eccda2cf06adb6d2681e2ef35510cd8f0e47341513cc3e2037ada4137"): true, + common.HexToHash("0xc18167aebef5e6e266e202a37ce11cc5c09597f1ebba71a38d84c6ed1ef311af"): true, + common.HexToHash("0x36ff3b2c45180ad547131d20112c72817354706d8536bd02767c30b1e10a7ca5"): true, + common.HexToHash("0x287ae693225c0a8a3162a1e96ad50ffcc149617448c13e65774cbaef1338edaf"): true, + common.HexToHash("0x3749e0f141b2a9bd8fcfe76ea5a115f160e20aaf008f01ea33cc0fbc1bdfa616"): true, + common.HexToHash("0xf46f8a184ea64733e4d475bbe245e64bc9cf91394e3fa433d6339b2804df82c2"): true, + common.HexToHash("0xe167f11f769c3aaac525c5410d308f79aa0e36d9f56e153dc352d4aed7709037"): true, + common.HexToHash("0x730240a108529b4b6895d3af36e2fc17aa11bdfca60374d20be1f0968508c852"): true, + common.HexToHash("0xa503f833a06554f030d25b3511554446f57fef0f8c92e0dcb5d95cd979e2b63f"): true, + common.HexToHash("0xd7979d4ec9cf37783cdb2ae264615fff1c241cc845a36fc4e4a82521beec1473"): true, + common.HexToHash("0x44b5c06b5301ddb2a93d2625a000faa2b306be7e399dbcb29aee39320c45e8a4"): true, + common.HexToHash("0xfd49e333d82c3a3a085a7204a18339695f50ad9fee16505eb5eb1904c1778e8e"): true, + common.HexToHash("0xeb2f493685127a7000418c06b6ab447f974c6ef93e62f63a0cea12814355fe66"): true, + common.HexToHash("0x905ea371a151c6d2ea12cbb5f27b5caf5f753d4aa968d67465d9b51aa027f8f1"): true, + common.HexToHash("0x9cb51927d3c99146786c6c97671bd9f663bf0262d8507aa721fa1ff275fdb924"): true, + common.HexToHash("0xad63ec31210aa1259a0ab6b38741aa8dcff4b6a2295f2c2fd9777b25fdc73c50"): true, + common.HexToHash("0x197854b1fef93c37859b07a4671a10456d8c9837fea9ffef618c2a251d686335"): true, + common.HexToHash("0xe2996484ac284909050dab5eaa7371fb62213641c86a3768af347f7e38d09106"): true, + common.HexToHash("0xbc2507532688e378320f04a54048d77d0eb929b2e07113964c5a7d63b69d9cab"): true, + common.HexToHash("0x31d6a76aa9afe3addbc11313d1343ab31ba652690c2cf30cf9067c08eaf01b4c"): true, + common.HexToHash("0x7985c6d1d368b7b667ddbf7b265c66c72b5ab2c3d209900e58c8516f007c4860"): true, + common.HexToHash("0x14d623ab73f1bceed5447f15a210bdfd012b75fde0bf0d8ccbf648af86309f43"): true, + common.HexToHash("0x80fb5304577c641094bdafbb8574a4a2a1a36c343d9e504515289a81b349aa85"): true, + common.HexToHash("0x7e67f14c7cfc7cfc6436ce6c22e89f6ea3284a2e3df1c07a221450cb0d880977"): true, + common.HexToHash("0x120cad8bfd9469cd150392571e51989b3c7a6f33d0c5e45ae0f4d6ffee664473"): true, + common.HexToHash("0x5755c47bf15ab83f05889dedc9a0df69af47d3dcb9415fc20c4add2e38712153"): true, + common.HexToHash("0xf491f7ed1ac2786694a93cac2b3c6f5f9d472a6f0ff9a5724281f3107f21a74d"): true, + common.HexToHash("0x34640a5042d37c08f86164475ce21dbf8c25b3de6132f2e43ebe422346919867"): true, + common.HexToHash("0x2d11dd936e081cdff73aca8a34b921f342384189379066b515b3e92837f3f3fa"): true, + common.HexToHash("0xe4e014963a8c4c331a907c226d9f8cd0f342457a457c824bf301d7c2ea0b36fb"): true, + common.HexToHash("0x0cac4c1ae829f3da7f3765bc52ca61d560df9df6dafe2d524cdb073ff63b1422"): true, + common.HexToHash("0xd21d8333a05e2f2f762afe66576cdff323a6fd5e96637f0df9d731e82533d7e1"): true, + common.HexToHash("0x00188eed7a5cae18ef4015d514d69aa8c29aad714d3f067ac72abe1deafd29b9"): true, + common.HexToHash("0x2861269d57210a74e5041e3f241dbf212ec1f503ead44f4ce2f32e0c00e2def8"): true, + common.HexToHash("0xd0e599f21b227f654c5108dbc5d930a388aa92f952e31bfaee8dc6c1ef8a038e"): true, + common.HexToHash("0x9f1bbee5ae1647cce935707343a4103b5d6d8b137913bad6820490309fbf88fe"): true, + common.HexToHash("0xfe91e9a13ae436d83a6b2e135b22711b7be880174c8bd10d465bdcc0b71e6e79"): true, + common.HexToHash("0x6f012006a8e1ffe2dafff62a053212163e6bc37765d75e6656c99e2ead8886aa"): true, + common.HexToHash("0x13ffbeb8de67e279e131b6a790dbc7060cb5555b59807e12f0ccfc211ea8f2af"): true, + common.HexToHash("0xa9adde41ca86ad269a2ef68cd84a674e77ec6e1a1bf463273005d405da13bd9b"): true, + common.HexToHash("0x3e4bdf5dcbae51468c606ca7195a644973383ceb33504fa202d448eb19abd684"): true, + common.HexToHash("0x0e5ebf7e6cc4a9eed1b8e7ed1db19f362824ffad59be472c99c58d6f33c4c581"): true, + common.HexToHash("0x3eac61058f737daacd496e7b88305737742e2ff25f8bfe44f0a6325332c77de0"): true, + common.HexToHash("0xb73cbbf659a9d9ef41cc8753012f9783aa14a952011456dcf8883b5a3e1bb14a"): true, + common.HexToHash("0x959b435245aa1be945e0cdf6a1ade8e5b839fefbdaf101d2d1318f5728ad6914"): true, + common.HexToHash("0x5daed8f71863c883ece03fc67628917ee3bfdcd22c9c42b93191214c0ad24549"): true, + common.HexToHash("0x8f24daf66c7ee64842e866c43b5844a491d8365856dd1f36b3dee4a08111a4a6"): true, + common.HexToHash("0x4faf4c1a513a93017d60814f25959dfdd0a09b38045c259449eadfdc9e21845d"): true, + common.HexToHash("0x5c7f177faed3f7c33f3307242eeb5669c966100ce007256ac21dc8d6f08ac7f7"): true, + common.HexToHash("0xb3df66512aff63ac7d2f510c2da6d24f3b9ea0e3d827156710f792e74705a82e"): true, + common.HexToHash("0x8c3dc3de6bf7285b17e380b804dffbaff9aa96f787640a256959c4be70c59f29"): true, + common.HexToHash("0xa46ad9aef315319019856474e1acffadf5086c52eb2687d57f0d40e1796eeed1"): true, + common.HexToHash("0x9ebbc5138703550e959980257a8878bb89557108cd78b458425b3ce12c36aaf1"): true, + common.HexToHash("0xa36d2ce67333b376b3a16eb03e093159004ecf71408a5e974fc132c010465ce1"): true, + common.HexToHash("0x94559ec0b58885c1c44630e3e93e26da8109345468311125c2342a3441451d56"): true, + common.HexToHash("0xed57a2a8cd51af66fabd75c217e44411c5abd6d1903de7e7846399d13c911661"): true, + common.HexToHash("0x86c2446c6dbd7ed0abd285aa0b877d87400518b05ab3f452033d9d435fa99614"): true, + common.HexToHash("0x5418c794493e8b859cb0d536b829ab960de7d67a383f9013ced7f6f85569f451"): true, + common.HexToHash("0x9a3f8a48d159f883d04555a1ce1b79c106c59d3e4bf15c21753c3d3325f49c17"): true, + common.HexToHash("0xe82e0a86aff33b4a646b158e0df3aadfa8a103cda835d74c481a2317aa0f8ff3"): true, + common.HexToHash("0xd325839b6c822341bc373c5c5ec31d90fb35e1cbaf4dad9a53885a4c0669818a"): true, + common.HexToHash("0x4ea8498f51a12f6fa3e19498e80d90c0dadbe9bbfa7d9c9decafdfca56be4bf4"): true, + common.HexToHash("0x55cb3efc402b849757679c771b673fd5c1c425e01e411ca9c69e3357d7c7adc2"): true, + common.HexToHash("0x04098aa6f9034290e49d017c2a4649a38fcee8c1cf143fead3f4764472a0d7f4"): true, + common.HexToHash("0xbb25c507aef3946d4d95f94e5c60c7ce20276e9747c2ed27ebb4ca9aed4b583c"): true, + common.HexToHash("0x1577624f78d55e24cccce5bf444ee0fe08c67c0d3277321b3c827d3ecb23c32f"): true, + common.HexToHash("0x73fa499491119300d239c6675d93729bcd750a7963bd98e006082f6ba1c4312a"): true, + common.HexToHash("0x3fec66ee3b795a7c760d721617b5934f0c5909a497c3489a95ace6c8c5790334"): true, + common.HexToHash("0x47e4a67bb9abce6e440afb5a472cfa343adab5700f0bfeb20ec0f99e19e86c42"): true, + common.HexToHash("0x5148e8081cb25a8f449724ba0efea33addf5abb62498552d72874bf4e3c30af0"): true, + common.HexToHash("0xe2b9b0502795a5326ef6dff545e4aab2df4ac22fbf3628540891fd5aba77de08"): true, + common.HexToHash("0xb531ab6d8798c36e668ca5e207bb4d972f7b3e14616b60d9836950e7354c9389"): true, + common.HexToHash("0x4af8ad8cc3b7693cc825b51441a8d11cc397c389eac3c6afe66e826a237f3d29"): true, + common.HexToHash("0xb49b1e9274aaf750b4857a398f805776d660a0203a739156e5754670f188438d"): true, + common.HexToHash("0xa4ce4ad062c95df815d15a89a22970252fbef142107535fa1f957a371f1dac5e"): true, + common.HexToHash("0x5a237ddac3ad5b2523f5488b994385b186f49696e5450c9cbd10509ced53e46a"): true, + common.HexToHash("0xbb74bdfa8cdd1431dff2116c236a58e262ca5755a1ee8e809a26072bf1c30051"): true, + common.HexToHash("0x8779ce21fe3ba998d647c0d167d669ad83e4105ec0066ac96f8ae68cef3ad60c"): true, + common.HexToHash("0xcaa1c67cc4fdddf73f71d0562ed43a1a74a57f60df4db37e10e8a493e3d38c42"): true, + common.HexToHash("0xf7b64ae9c49fef79c1bd9b3987c68b976add47e0f6f0a9f0626cf6f9f7fe2425"): true, + common.HexToHash("0xb9e805c7615e0b843ce925e87733113e73da1e78f6c28253c0dde3873e998345"): true, + common.HexToHash("0x5c7dd3b1fbaea9a8d697b47d8760b87bc174b9195afc326e46ba0032ee14c709"): true, + common.HexToHash("0xc7bbd4cb6f49e3deb51a05431af052ad337cafd7610cbd53e116aaad44757eb7"): true, + common.HexToHash("0x364e44011a029246491ac830fed04b4d37b5b4edb11f0289be27bf32d4d1cce3"): true, + common.HexToHash("0xa6f492972a2bd45232165534aa9536a80f5c530b9413182ad617c156060b1df6"): true, + common.HexToHash("0xdc7b30b23f6eed9d4c13aa1a38b260ab5c883948c89ab2dbce23b01bc810f9f9"): true, + common.HexToHash("0xc5dd7306738ce96009aadf520932a4586145002e99c0e48bcf30d245cb880df4"): true, + common.HexToHash("0x8de2d6d868da6a10daca368159c3cebb2e552d125086be069bd63cb2ad5ed143"): true, + common.HexToHash("0xa679e84f365ee8152b14ec6f3f07f25e4f3795dc5d2159d70a4b9a78c871520e"): true, + common.HexToHash("0x135016eaa6878fc208ba301717a954620fa2c1f320ec0ea345dd0a4c96359c1e"): true, + common.HexToHash("0x8f789d4d9778c2b25c58d0514fd5c9f7b220cd801bf961f01716b24959bd5319"): true, + common.HexToHash("0xf79dbac601ad6f0e726ac18412e096196dc9e354781d8a48de61353b6b33d2e2"): true, + common.HexToHash("0x116d7f29421078dcd94868612eb75a42210b2a290667b2c8c778378e0c28a597"): true, + common.HexToHash("0x6c88500a58cb3aa9b83a17734b9aa24f845fda1a2c019004057ec579e9bc0bba"): true, + common.HexToHash("0xf434a986eeff3fa95f5907edb10351dc48a1d1d4d3768dcf12a85daad861675e"): true, + common.HexToHash("0x96d564f77ff085c60b5e9c0c7764792cb3a3a4bb4cf6504b61f3a019402aebaf"): true, + common.HexToHash("0xc74b10f6419efc8d58821358b81f580a77a4bda6ede13e356156aea6acde2b93"): true, + common.HexToHash("0x558d31ca9bf9c8877f1eed5e11b9a992cfb24b99c238b4425a94e3835de4193a"): true, + common.HexToHash("0x0921b7083179c9ae436004370a2365a029c19346ad5c5024cff3c944543010d9"): true, + common.HexToHash("0xc2c166a2c018c39f7f7d1409e082f866f601128af1fdb7b87139a9e5cb1c5e81"): true, + common.HexToHash("0xf60c10f80618f77a81b21dc7a327f03c1ba7f91ed36191c3079de23d5363c79e"): true, + common.HexToHash("0x22fe04999a0d6d9715015f7e18c67bbac970bcf35900d39e615d5adf55266c3a"): true, + common.HexToHash("0x8323f82f008b432b8118fcdc21c8754ec73417862153f83a7c1777d528f331cb"): true, + common.HexToHash("0x403628e60ed693977f97e8d5d1c14a60be3a246485a9b170f5f9a2cca432a29e"): true, + common.HexToHash("0xe13b1796d2f396aec33eac5a854b2f694eb9e8687b1be4ce5ad5c652aa334681"): true, + common.HexToHash("0x29390095decdb37960596df6747e08339ee8c809656702d153152f5858feed71"): true, + common.HexToHash("0xf48feebadf94da5ad08d45b92a13fd986295738378f2dbb27c9fb9df930a5162"): true, + common.HexToHash("0xa7e6892f75013028ef80bf1b91900249cd4fc46afefbee7159618136b1dd900e"): true, + common.HexToHash("0x32a5a1b9634d5d8d2a16f9b5613769280a49b3aea46a669df5b265db8af53fa7"): true, + common.HexToHash("0x87caee3e8283494d3db50aac1e2d6429b1e7c1428baa7174ddc9af44deb1e578"): true, + common.HexToHash("0x9c2cc59aefef78dc8e6a62ae74d324a3e25eba42fe020c383fd7fdf48455995c"): true, + common.HexToHash("0xa3e5a36c48d7b2a1377d66c934d27aeb618c0d853273fcb9c08971c081ebf766"): true, + common.HexToHash("0x9f226089aef74432623450a265e230b0d4beca6b55b9870227e66e34ec235283"): true, + common.HexToHash("0x0b158d9d13bc26b19aef473c935a37b72105d19aa878a43194f6cfd0f40194f9"): true, + common.HexToHash("0x27b585d30df4b9d67eddfa9424a7a1969a02b94cb7f234b97537dcaaf407dba5"): true, + common.HexToHash("0xcc3bd14905665fe3a048e92feb210077f57d431ee044e8b4e24a5bd3a2db6ca2"): true, + common.HexToHash("0x1ca9c73ea0d816b048d7d0364c5b5ba02fa6ebeb3e9e5e4fdf9debbe2457cb4e"): true, + common.HexToHash("0xa3098ceeb25e42bc828e7813a75655f6502334edf1c1396430d7cce90467765e"): true, + common.HexToHash("0xdb1c1c8415da6a53715dbeca302e52d326775753e2d48950dd44d3c176bb2053"): true, + common.HexToHash("0xab22a9f0e4a13fff66d4be4a78fcf02833bbc75decca7534402b12a1bedc6588"): true, + common.HexToHash("0xddb0859995dd1d51d7bd41fcad6cc15dc2f0fcad4a7c9ab3c5356d307ed4d1d6"): true, + common.HexToHash("0xcb597e1b3d8cee8745c984d75e2d20af5aa7324700426b4aa46f53ef8f455725"): true, + common.HexToHash("0x2cc249c41395f2b91c451e87871fab94cf33f4077d235b0f56f3bb9aefb346d0"): true, + common.HexToHash("0x4b9afabb30bb650e3e165f785d1cabc38f3f68dc442b62b5934143f711ea7155"): true, + common.HexToHash("0x5ae04878ce079d976216604547f8a8e6c96d5c321a5516dd703bc93d6aa6ddf7"): true, + common.HexToHash("0x54a97ff2ea37a1632a0b04e70c77c50f20c3a0fe18d8ec32a9f22747f635cfa5"): true, + common.HexToHash("0x664658c0a3adceb545183d44e89bfcc904f4f2308be596eff2b07c0ee99c1137"): true, + common.HexToHash("0x7be325731b76197abe22d8f4738f2763f334744158e9037f67887dab9bfb070e"): true, + common.HexToHash("0x644809888157d878754794d9fa7b8a27578ac9b68077a9380c90646465b45946"): true, + common.HexToHash("0x24f766e44d3c0f0a323595836c3a6268a262d9918da7d0588a33c517c0afbf5e"): true, + common.HexToHash("0xbb8096a0a5e858decb45c3f512a5232b0360d5a1170fdc3c4801c29ad86cdcbf"): true, + common.HexToHash("0x0307d2c94d42dfa74d95c3039cb49d1bd85b93cf26476d1201ad344dffcbfe01"): true, + common.HexToHash("0x58fee32c81d5ec37d200b0a43ade28f8cf0c94a69765195f7a2bdacff9eb43d4"): true, + common.HexToHash("0x7c13e6b17e186f737681cb008f3c171c2e4fcde00475ecdb11138666fa80946e"): true, + common.HexToHash("0x019d30292b864eb0dae9b828424bc1ce5f2a869886e5b85d6d293d16de52ed3b"): true, + common.HexToHash("0x74d8f953841d55829b9bcc80a4adab4c86d0f50b26e756ed6f41a8a46f7584ff"): true, + common.HexToHash("0x9322af3a7e40a11015c05178bf550a09844770cf497ed6d184f5b1be65c4f563"): true, + common.HexToHash("0xf225a84da6f7dcb125e3444d2f804f75b1e19ef438636a55c4b99a87334524ab"): true, + common.HexToHash("0x3b32b55627b2a707b72483f3cda2c99d67f2f87e5cb792c3617e5c731965c68f"): true, + common.HexToHash("0x3d984d678e350372987b45794302c35660b2608ff4e92a614bca627143f4063a"): true, + common.HexToHash("0x1ea48685bd838b6d59a63a7471daa5639edb69a5f46a221f9fdb1c5e8c4ed577"): true, + common.HexToHash("0x68e829bd08f7add5503157a8b4038887ab9dd7484c4ba50e2d93b1eb80a621db"): true, + common.HexToHash("0x0c9add4cf3c10b45025de160a9d086367325142ac9e5c753ece8f0f600db372c"): true, + common.HexToHash("0xf3558027453c4cb20bce11b0b8a4de9c768ede0c9173dbbe77662384b31c2aac"): true, + common.HexToHash("0x43817ef2a6a094a56bd7adcc4b375993792b5ae351eacaa015a2ff10a6f97911"): true, + common.HexToHash("0xaa4e621b5068a7c2f44f0bd8dd0dabed71bfa032e27a2115319bda977d90ae66"): true, + common.HexToHash("0x4591abce59c6d798c0c732c7724c50ddaae403e98128c253a571bc9e4fa010ac"): true, + common.HexToHash("0x4045a6aee00730b321ff296d4716300b1382c7274ea9046b757157c42fc22b62"): true, + common.HexToHash("0x98aa924414121ba1cda33e694c6a03ebf8ca0d2fd9563dcf15fe0a631d392f75"): true, + common.HexToHash("0xaecb23bcef41da6c0b2fccdb01a4dae992bbe34847997258dc21ccdf0604325b"): true, + common.HexToHash("0xf10ec1850bb750ab09b8a650c0b72105329f778a08db6d9b8a957290ea3dbcf2"): true, + common.HexToHash("0xb89c2ce69cc6ff0be43bbcf48c70f57521311936f64d7f343eb0b09e940e5941"): true, + common.HexToHash("0x679b6c1aaeb1d38ffa9c83f36e80c9ef3297c84ccdfe9267dacefc0636389e11"): true, + common.HexToHash("0xa4b400a8ad13334b109db6efebb8342cdb321e85c7388a708cd361e996b9ee30"): true, + common.HexToHash("0x2da1d9125b1001f0ce4dc2b070552f99c7cf8a2a686cf2ae1a67aa4dff746a61"): true, + common.HexToHash("0x2651fdeb80c9591d4877cb5c0c5d3e0259e3c5c32475cb7d8b5f6235bc9f02da"): true, + common.HexToHash("0x580ca2b4f2e848052f3c85a28ba265621a92066e08557aaa1c78be58cb6e182e"): true, + common.HexToHash("0xb96f3c286f755780d6104c8e8bd98d976c7d1aeacf46b16b90c9ff691d092504"): true, + common.HexToHash("0x2dc6856c8bd27abb560529d7bcef98c98012dffbb1f55a06fc634d07b5b180de"): true, + common.HexToHash("0xd6928904a59a055a657f7acdcbde4673764e0cfbaad4a30e4d517c7ebbd951d2"): true, + common.HexToHash("0xa088533f71cc59d05fb9cce09880518a0ea2a7f330784cf5bbdafaa8f9afaab5"): true, + common.HexToHash("0x7fdffb81898938133e6a305ffd71aeef90c4885f180f04d1ae5d4c6161c9aaf7"): true, + common.HexToHash("0xec8b7e75a569072d8f8c6a805595a8f5370e724159bf57f0863cf252d83a4a14"): true, + common.HexToHash("0x7774168918bb42147ef08981a7df827784293c616e95967d31db685c6900dcfe"): true, + common.HexToHash("0xb8f775bbfe881bc96102d61a95453aea29fec7d1214996b14496d11a5225ada3"): true, + common.HexToHash("0xe1b8b988bdb5507634c362d95831b8d0270a98062668bab2e96d5af4e303763e"): true, + common.HexToHash("0x64447ab904426d6e390bbe2fd164a380df5136216c128248d16e06be02aaf450"): true, + common.HexToHash("0x4e4578299b654e80242bdf759e023b5ac2ae0977059ea8473d453ed09858d74f"): true, + common.HexToHash("0x992dd4d430f62382a90f4984ec6511bf6df67fe8004c5e22356eeb47aa55e16c"): true, + common.HexToHash("0xf961e5bc9d6ba88718b8635d0df92ed3671fb178de30cacad475be59ca003f53"): true, + common.HexToHash("0x2ba2dec5ce91965da2a6caafc8a5684a1ce0df2e65e87e935041c7c7f19222db"): true, + common.HexToHash("0x2e015ab0d44a1c190c54cc7bf34a29b5d539dbee9bfda4d199c4cfad57808b66"): true, + common.HexToHash("0x17b2336d75b78dd71837bf5ba5d676104895cbd5f40bd504842d7fee80016522"): true, + common.HexToHash("0x33acdc429a67222fcc4894093b49e5365f63fc37801c9a64c634048b0df4a90a"): true, + common.HexToHash("0xae833798ee78830b7d3f84fa16fa3abdaf7a41a90dd409e5ddc109fa1f0ea860"): true, + common.HexToHash("0x35904fbc4a16b127d89945aedd593a0bf9adf93c4a045624b7ec5f55c67f1da0"): true, + common.HexToHash("0x4b19166a54e22db46b71227a4ab279f4542c4f70b22e69352f10fd0081b94b2a"): true, + common.HexToHash("0xa32eb02e282160f2bc1a5a2f33139557d752192bfd190a2c174c62c0982910a1"): true, + common.HexToHash("0x9261755bf0a8dd7dc7e6556aaa80f261608797e8a6b627db1c5b5114a4448744"): true, + common.HexToHash("0xabcac8ccd3068316d81bb10f77c5be28bbec5a1fdbe436ad54d4318079ebb32f"): true, + common.HexToHash("0xdefa69ffdf9f0d3489d00f6fe4306027a5bc170c7ef847317a8d2a31966f685e"): true, + common.HexToHash("0x0174c0efa366c77d5792804bf7b8dc5d638d7e0dcc4a7967be6f4f0ae8d35d2c"): true, + common.HexToHash("0x79e1c4e99578ee69bbe4aa85ac0644712c56fc94c9fc14c49a98cf9982b8505c"): true, + common.HexToHash("0x13d24118a21908a2306bbae26a9f4f4aa144c45faa297b9c3344855e38b0f70b"): true, + common.HexToHash("0x466c7cb102eecaaada5a9819f42ec3c9dc06680dc8e8d1a1da0c199592ae91e9"): true, + common.HexToHash("0x9b3fc7b674e243d6e54efc524692be1835319410e3fdcde232bf0bec4d8f6dc6"): true, + common.HexToHash("0xfa45aed7b12c102058c8377c2c0a9255054d1919e798b0130249bc36fe58bf1a"): true, + common.HexToHash("0xc73b06f4b84e1b0a8dca5a115e811a44656124dbd7336871c1447887ee726c08"): true, + common.HexToHash("0xec38073ee5801225505a3827e3e2f7bf006384b1a92ebb2376e37d92e800d74c"): true, + common.HexToHash("0x3736d7044abbf290365e01ffafe11cdf2fcc41d45e419a47e212c706c5e477d4"): true, + common.HexToHash("0xacda8d7a57f98dfab41783a6a34eea5c6afbb6d99700c1969fe75ea731698cb4"): true, + common.HexToHash("0x7f7aa348e82b01acfb6ba40466b076cf916b3809769c5efde65fc7092fb3739c"): true, + common.HexToHash("0x6a77df91f75c3eceb339e79673da046212bd877d2bae6474ecae0f9e5c45eee2"): true, + common.HexToHash("0xd108777b4670f99f7016a7608868d7d21fbe4cab148f172a0430f51bf685fe07"): true, + common.HexToHash("0xe3bf74b6214f59aee5131682206c7926f689accaa5b77547da667d4e13d9d1ad"): true, + common.HexToHash("0x41436d990f69217de9e98b33bd04d0e743ed8772e4b59cfefa46e3e763e029e1"): true, + common.HexToHash("0x9d73179fc13e229dcaaa44d859a26d82ea29108d1f586bdbc46a99f1276cf27c"): true, + common.HexToHash("0x40494b9b8c1af4adda88cebef5649c366ae9cd143280dbcfe86a9000acabd50d"): true, + common.HexToHash("0xca101006d02f6b0c9c2a80249f8550ca3e2b26ae779275c78ddafa0112f58c00"): true, + common.HexToHash("0x492dd41d8cb7d0fbc4190c984fe4c82f6ab4c1354fa7044bb4cf84aefe52cc8b"): true, + common.HexToHash("0xbf3e4777e0db66ce35df005983f8292fc44b7c99f13649641b6defa77152cced"): true, + common.HexToHash("0x7610e9de9a2cbcc908b9309c8d1a01704af10951f25e5aff62b2048799f730dd"): true, + common.HexToHash("0xd15c50dbfbdbb75310eb975237dd55874e1f300474f1f4ea71632d248280547c"): true, + common.HexToHash("0xd1dbd8ba5c88a80b8c89bcc9a1da619d17fdb79b85031739bea09da198ec3ca3"): true, + common.HexToHash("0x59ea85a9f876daee9b51b78a790fa0ff8f34edf321e0325db8b4be2415f5c5c8"): true, + common.HexToHash("0x682ff0313b13e8ad25d3dd0c1a5be010c0471ccd0b62ce4d14b6dcf7a4a5fd56"): true, + common.HexToHash("0x1c2eb8a331f714e1aa6efe49113062a29bcb7fb559d262a893b614c07ac4d61b"): true, + common.HexToHash("0x137a8e6d3c071a8e288fbf4130c9bd86d1730efb6a9eb728c2addafe9b56985e"): true, + common.HexToHash("0x1a513c4936c6fcb84f70c16f5e602163af9743c7d4d40da579b8ebfe5852806d"): true, + common.HexToHash("0x0c2a25df72dab56915a0ad9c06de60a367990f740eb05b657d8a354a11a77e1d"): true, + common.HexToHash("0x40c480e83db0786f8cebeeeaca21fee8ea49117f5d443d89b38171db51846b93"): true, + common.HexToHash("0x9d931cf2c993e0fd8b44c30dd9cc769a83e2fb927d15412da05756b457bcfc98"): true, + common.HexToHash("0xebad9d2137b55bd665b368cb4a23e81a1f9dc6bcd3e0b84a52a33e9b6b6e356e"): true, + common.HexToHash("0x6fc219c0ad2f1d08851140aed96b09de38fda461b51190726876b821887b29c9"): true, + common.HexToHash("0xbceb384ac4449cbc8cb33bd2b9c507550dfb570ae6fbbb82a73e152ef0221aef"): true, + common.HexToHash("0x30a55fede68984355bed18ff06850ac61e849b8e24f30fc95af25a3d9958b421"): true, + common.HexToHash("0x18366000b11f9fd3abb83d1e830de34478894dda619b3f8bd9f6796d49ded005"): true, + common.HexToHash("0x673f07c909811f596d87e7a747a3dac46abb04ad1d878e37e615e603d0b0befd"): true, + common.HexToHash("0x12374667ebf3ae9d57175dd8dac2224367b3fc0bf66431ed25bd9065eb12a79f"): true, + common.HexToHash("0x274c6dac3e86a5780ce280a7b634877fdfa98c165a289796c428947708776273"): true, + common.HexToHash("0x18838f979670d8277226e7329125c2d1d183b89280f89715150389aceb627904"): true, + common.HexToHash("0x75d308a8a1eee71154b59f91fe7a101a57c87e7d3c449a409660f3f1742d3832"): true, + common.HexToHash("0x1ad457dad409fe2c58ad0d46169e406a9105961a2fed2e44076e36a5b5566424"): true, + common.HexToHash("0x93637510b94f57bf57f7012d9adb5faaf263bdf2e62275d8bd0409ab2681ade4"): true, + common.HexToHash("0x51748a64a2d370847630a453f70f681c884c6fe8f031d44e44b0054742955797"): true, + common.HexToHash("0x88ddfee90d3fedb92238b650cfb2d4104ed0ac7fb29ba9617cfd1d696054206f"): true, + common.HexToHash("0xe085e4386d6957a54fbb3f3d91375376b91e380e716750b83d008690187fe277"): true, + common.HexToHash("0xe184e77ad4fa633fd0c956f9155a49ffd142613dee1edd063007d5b16cd857da"): true, + common.HexToHash("0xc8b1c649704b6386456250d488389bf9585134336a86d300b5005115a0bc1af0"): true, + common.HexToHash("0xb9554ac0896e61b11056471e38638b2311d302e621b27866bb4925186562a8bd"): true, + common.HexToHash("0x0caf059eba43e9d66475ca20e48ff0ee626df61916355883be8dba1eb1424cd9"): true, + common.HexToHash("0x9aa4cc9a40454a900172cc04ef64a0ee4ceb63a5aa3130e66a61a19ea0bb632f"): true, + common.HexToHash("0x88ca029580fefad40a2d66ff9e7212d6f4dfece41725e6ce584a7fccbf3a6373"): true, + common.HexToHash("0xb1eb5ec13bcf3ef29c07bdf3d3c8bb2ba2c486e5f6b140093d919693ed09d1c0"): true, + common.HexToHash("0xb85334016c3d7ae006d6b1f9a2eb1f2736294aee09d074154c5f77e6da27312b"): true, + common.HexToHash("0x7f261e2c185c41b31836ff5a0643713b2fd9573a19110d70cdc4fbf1b2b68ff4"): true, + common.HexToHash("0x24e9a9a79ca8469f1b044ee5ff37df9972d9ecea0974527ff3aab9ceb3ed8250"): true, + common.HexToHash("0xc85d5617c1f22a732a403a426fceb3d24d025c057d72cc78a68a7cf85e9708ff"): true, + common.HexToHash("0xbbc3a64e3d077e784e95cafcefbc4c291bc05f3dbc49d546e42f767555dd29c4"): true, + common.HexToHash("0x24b38ce7a2216bcb417f4b8488f6c9d560b469a25b7f704f86142eed098ee2a5"): true, + common.HexToHash("0x669dbbb16979137d68e4c73407c7394f122de75726de3531b014a1ff5a0ccd6f"): true, + common.HexToHash("0x8865855bff7d9a45ac2426d79f1ac2410a5b6151e6576c8628d2d1e4b6aacb49"): true, + common.HexToHash("0x6e011a01761084e1d4a33a6bd620d5c6f91f301bd013eabbce6e97cb2a10a8d7"): true, + common.HexToHash("0x935f3549df487235fb47f011caf2b3cfe99a6b8b077fcb58f5d786c962e9bc57"): true, + common.HexToHash("0xa11501ea0e5dc389db2c35f774b23eeebf9af50de2122d6e47273c292ecfabeb"): true, + common.HexToHash("0xf346a17955aaa507413ee621d48d9b21048354961e6941db9f8e6f537e33c99c"): true, + common.HexToHash("0xaa08ad8679a428fdca5883158394d9f7796d1689b94e3185e50f62cde1e7b34f"): true, + common.HexToHash("0x37dc8d2451d0722a85e129e647a4d0217df529d566f04c2dd15997f2dbbbbf2e"): true, + common.HexToHash("0xf019b8bef96efe249e072c1cbb47b42a6a0659462af617fdedd66b365cf0f959"): true, + common.HexToHash("0x1644d860df7a14fb2c1d2656c6dd5c562333127cbcbbaee8dca77f0ea485a34b"): true, + common.HexToHash("0xfd437cd9b3edfbe49c5dde39f6bd05cf78bb5756a208f43211d39414f5c837b3"): true, + common.HexToHash("0x80b162b84231d409cc6f3b88f3a211b1f1cbc9fef35b7139bcb2769b753c354e"): true, + common.HexToHash("0xee12387f4bdaeb4cc816a4012b315e501ea8f4797f2a6f2c8227c6e6d79d039c"): true, + common.HexToHash("0x02f99036ce286e90d720def1a6680ab89abb6abb6f6d94bb73d427643ad6a353"): true, + common.HexToHash("0x9d652628d11d620196515e1c2e857c3124b6ca7a570331998ccd747d9d9a131e"): true, + common.HexToHash("0x662f9dcdd312ddac36a8217ed6cd742de2e525f7c99c269f17b12cc5d53bc446"): true, + common.HexToHash("0x49459a81f33f5947f1b52b958fc04a132eec7af5391a98ba15aa3d86711fdfa2"): true, + common.HexToHash("0x450d162d15418279ed2dedc6909ea55446e7e9a10d20c94a9961436f4cf09592"): true, + common.HexToHash("0x89a38dc0f68914a242a044f95f8d421f1b20e2e2299d3ae171fb1e2aecaf9006"): true, + common.HexToHash("0xf75c78540bdd2541fb8f028d3e04cde6d84201f48c8ada0ed783c15ff7ab1157"): true, + common.HexToHash("0x6196db3a74c50a86db8913f433e246bdcc2423e6d378a2a8e85a3a9ce6af54bd"): true, + common.HexToHash("0xfecc689ea45a5e4a693cdc431e510fefab9ece8c97d8806c81a316d0a64ed10d"): true, + common.HexToHash("0xebfc53937476d7ce62768bb9307f01730896858bddd48510a21510d951b2a472"): true, + common.HexToHash("0xe5e07e0d87adba8c5991a869d0653232c347509ac129cd943d51d89d915e3a9f"): true, + common.HexToHash("0xee25646265b580fa83b07722733cb70ef103a1e4d34fca97d03454dbdbbe3d55"): true, + common.HexToHash("0xfa8e587f146d3f4e16467022d34125b9616466ac920dc4389ad5c8a1d84ea2f2"): true, + common.HexToHash("0xca475ba4ddd3a6a8dd6dcea96d59a1f2981f4d281362d18f93ad4c5928dc7d16"): true, + common.HexToHash("0x272de2f53d4911dbcdbcc3d978464cc6bd4e151966dc678efd9a52ac98096218"): true, + common.HexToHash("0x6ebf770d61ea66b9e81c4edc7624fed096625ffdf2577fdafe133666c5d85672"): true, + common.HexToHash("0x3a2d8be92b85706332713b9278c8741c5707abc853a5c88136dd090365ac5ec4"): true, + common.HexToHash("0x0362027bf0328b91d644fc6da020f405ff8eb8008efeb7f06a390704d00504df"): true, + common.HexToHash("0x2ed4b1ad97f73e921e39e56ed4fdc4ad6c6b1851b535b12eec03d6b7002f34bf"): true, + common.HexToHash("0x62e492d9891491c42b3ad48b2f42d3b40708b0229b59d853e59bd2e80348878d"): true, + common.HexToHash("0x35983bcb1b5583bac9f9afc6ef729f595a21b0c7b619627f44b6b2436759794a"): true, + common.HexToHash("0xccacad508a79ac31c8899486d47fad96bd62dbfd26f0a1ae500cb0daed077b47"): true, + common.HexToHash("0x02ad02d5090dbc6717cab5510f9cd2935211d9ba1f203ad893d05f3198f7d850"): true, + common.HexToHash("0x5727a710605e72602b457c8ccff360396c3d6c0e7d965cbb114f88b394f45dc0"): true, + common.HexToHash("0xa5db2da0709cbb044213c13beda8872d39489afb1eda4f658cfa1de8f1e51026"): true, + common.HexToHash("0x53a65fc73e4e71e1795eacaefc1627f37565642dba2302f4bde47fb376e8a15c"): true, + common.HexToHash("0x80bbcad0a1eb0574cebcb91ed1bcb6da462775c76b9ed3eaca536d0f20c5ad0d"): true, + common.HexToHash("0xd73953ff37a916eba5a4e91953a3121fd9fd0c537e9fb32a8c9ae5a03aa08868"): true, + common.HexToHash("0xe0029bc05e2bf4b568c80ba3d3ba035dee458f510506e0e61265ee2b9616cdb8"): true, + common.HexToHash("0x776fcc370d1d81feff43a1328f55ea12c7f710af4e63256b0747fde0c1bec0a8"): true, + common.HexToHash("0xe010fdc6f78c87aa9e1042e0923b6bd5ce29b9295b945c360e54b0a654c3e85e"): true, + common.HexToHash("0x8cf7aa3e00a8e4f3d5e8282129d35ef1c63c02cbbed5d96140e110768fa768e3"): true, + common.HexToHash("0x47a055774e93a2cec3e721d312fa6204c9708e678b177c18e7063e388e48b573"): true, + common.HexToHash("0x257f5cec2b78d3252f19ead7839463ff23cf7e00ba522b0ab6b6656dd240185b"): true, + common.HexToHash("0xa8bb24ce4ddde075904c012c235e19abdaf3edb44809b3df0a396b984ed0e1a5"): true, + common.HexToHash("0x50d758cdf4fd6052f09fc45e9ac255344af0887f82c169eec37a48647860fcd0"): true, + common.HexToHash("0xeb2ac1fc4a4eae109bead0f834f5afa6f305252a94704ec596d158b152c50515"): true, + common.HexToHash("0xa68eed2ea1ac7b5e8d34502e6fb2f17d4343cf12ceeb76264997d61b76fb183c"): true, + common.HexToHash("0x4c7e998c8242a3a9d262ad3f64b15f471c9e5811d817b383c5f158bd8e17d879"): true, + common.HexToHash("0x053648f06374927b8a7376977682dcee47139597a697bf143eb024b551a4e53b"): true, + common.HexToHash("0x461bf3cd22b1b8699071461dd1558275560e14e6cfac383c27d56e019524bbbf"): true, + common.HexToHash("0x2ec5de9d644144e406226b941c8426b7f2e6621006d2e356dabaa1dd09f10b69"): true, + common.HexToHash("0x49484c7351991de35289526648e1b06e0cd1b51d0eb98a09006d5353ed6901bf"): true, + common.HexToHash("0x1bbe480eabd19758acf28797c144264ef76755ecdf259d35fee025009b525104"): true, + common.HexToHash("0xb812c6823746b86196fa3bd0636542ec2f94c36a010a5dbb001fb6a05e9b44dc"): true, + common.HexToHash("0x5e121242b106f51e15ba3cd2e980c57f459b3a5f45ad10d72033e9a224faaf44"): true, + common.HexToHash("0x92d357f86738b4533b225274b4b6fffce621337c6536802c2c079efcaffae5e8"): true, + common.HexToHash("0x35f1ad7ed12629a217b3ca68e4ba806dbcd502a1cf7373915f36b61e9a984085"): true, + common.HexToHash("0x4431e670d8bcb3bb65d3df436f1bd0ad54cfde220bcfb912eb04f4366e107324"): true, + common.HexToHash("0x4bd99c628b3fcbbc55ca1fd5be5af4e7c4b52e42c974b0a1a7b2e65408cb570f"): true, + common.HexToHash("0xb1d749d3b815fb24dff14c45832df10789a89d1f13cfff8056b0331be92aea91"): true, + common.HexToHash("0xc4674021d84d854748115a7b54fad4367c41b6210ecbec1421a7646fdcaff133"): true, + common.HexToHash("0x411dbc03c30b63c656654e178c90e61355cda13928f11d26775ca276d643065e"): true, + common.HexToHash("0x79e8bfec6b18ce9fea97fe6eb4e8496857b97314c86248b731bc0b6b62335674"): true, + common.HexToHash("0x60442c129708a0f8ea4e28f18847e5cd018b0ebd749cadc0d14601894910fff6"): true, + common.HexToHash("0xe12b9c16fe509b7900d429e01cb43548fbfbc85e9534fabcd8947812e8fcb990"): true, + common.HexToHash("0x2c04147530633f87b997e4225c9165daf991473400aaf1b4e3d53e533fc9563c"): true, + common.HexToHash("0x11f5d3b6daf9b2a09963d72e0943be9cdeb8f69a5aec70cad2d7a5825950e688"): true, + common.HexToHash("0xac0711c68acb066b2638a921891f1fea0e31202def15e69a6f1d1c05a0be3141"): true, + common.HexToHash("0xce1a0772f43c2ca83e4a5fe8f03960dc7a7be60cf558cd5e8970f050b1879df2"): true, + common.HexToHash("0x5155083378cd5d9aa5ba0440589d74a9c37260d86706a0a02d93b209690562da"): true, + common.HexToHash("0xf0a79d8ee5e566edf0ec81e3970cf09f481491b35d0ea0810ff94f81a26b1f91"): true, + common.HexToHash("0xe0b34d695b791f31a6479ef3841284fc9d6e4acb03e86ef4efa821258a760da0"): true, + common.HexToHash("0x5c81962e46fb903d2f2ac3f61b7fad6ca2659e96251932c27b328ed74527817f"): true, + common.HexToHash("0xa5f036e86b6c5d8e5808919f1c0a5b7d1e27b042732c1116a0da9d72282ba6bf"): true, + common.HexToHash("0xedd1d538664b2cf5fb2379f2dd2a51c11ae39b6c0929284ec3a8c12f37c660e2"): true, + common.HexToHash("0xa8faa348ae43c8f9e393b91e6ed666301bbb56bb176f4ce4df178325545dd779"): true, + common.HexToHash("0x30dd97d4946827a22c8dd35cfeb1234a46e2deb0531acfd0cf8a9dfc6c7ba52f"): true, + common.HexToHash("0xf73f9eb3ddb31df5eda6a8cd921ba13346bf10aec720a51f6e67978c89a84e27"): true, + common.HexToHash("0xe467c2766b7e63fca4f231848d9d809815db6c008cc2183a6317e32fc79b3546"): true, + common.HexToHash("0x923638c4b60ec8c22479464e98c87edcc9ea90f2665812e7dd247f154105cc03"): true, + common.HexToHash("0xeebfd036dc2698411bca6daaa6f5f924bb8de48cc6622238dcbf1c14e2c36f30"): true, + common.HexToHash("0x96436842303bf488a17aafc0dd7d4ef730a36973b4316d88f3b3b41788597fe6"): true, + common.HexToHash("0x0e7f6a80c2e34e2eb2af987e10cc8283fc4e4c0ef0e46a65ef73fd6b622db405"): true, + common.HexToHash("0xca7cd4cc52fd7b2eec27e925ad974197686c691f0b354fe686e03aa75f70755b"): true, + common.HexToHash("0xe4b6880c9afef3a795d77d8bc8a1f00baddcc207a2e0314e34b98b71fdcbcdf1"): true, + common.HexToHash("0xe086e1ff190e8b861d174409d30cce1575a5a67ddd6caf795e65188d2ca7e284"): true, + common.HexToHash("0xc7a438a6b00b0f503c1c193dc30b32095159302991ddad2e0d7b4f485f70a560"): true, + common.HexToHash("0x67c4d3573afa51d5922200cd9bb1611fb861db6cf0afc961dc31ebbf0ba11508"): true, + common.HexToHash("0x7d4ac5a49b6c0a6d35ee93f61458ee907c7a00c5d76140af92d7501d0ccabe1b"): true, + common.HexToHash("0x3ab4704c4f2fa7e613e054407c8efb359457a747e771501fc041f961ea21740b"): true, + common.HexToHash("0xdd2c9934a338812cbdd9c30015acd45c7b04d836a6d64bf443ab81f0432526de"): true, + common.HexToHash("0xbc8bd5d5e4e6b78b204ea99fdbf08dc4130abb2de0e9e4a014d14491a919b2aa"): true, + common.HexToHash("0x946ee7202078c7fbff5e7fba245aff144bcf06050191970b905758ea63e27509"): true, + common.HexToHash("0xd829e38fb890ac7ae5cf11f2fe2d09a244ff95c120bb3ee206f7d33ec7ba991f"): true, + common.HexToHash("0xd3946c50d2ae1980aaec0ffa9d63a1657671b0c7cec65d064be296ffbf40cf89"): true, + common.HexToHash("0xefa9dd053a39f8b29ebe1167e14751858c739c8c0158745b0000ed4a34de6296"): true, + common.HexToHash("0xaa224e93922384301555ac9dad3dcfc523e5dedc3eb697e3c49a3e21f539d17b"): true, + common.HexToHash("0xa5c45aba259e25b3d7bf9eed67970edf986999e9705529338bc2c7e0426b7418"): true, + common.HexToHash("0x98d6111e90fa0ac8da016f1804f15cb8a2f7309341811f676e76eaa8fc0a6a00"): true, + common.HexToHash("0x6a9cb5fd84ad327d2f0fefb3703eacce1e4ab1309333af1aeeaf9186b2d37479"): true, + common.HexToHash("0x9f74db9f73e1c3f14bf0baac76a884c8f091671fcaf4512a13d7f8517c09f16c"): true, + common.HexToHash("0x94402db84da5ad0730fe0844ebe62ea39fa00d057847725e8998781272daec53"): true, + common.HexToHash("0x621f0819af062d02d2d6a83507d7833e9e61d88b9b133fda9f8217af79563d1e"): true, + common.HexToHash("0x1a391a2e027d111b9e7126736d53485b26ea4e20150e2885616df4f789fbdf82"): true, + common.HexToHash("0x3ebd785fcbd60629f6b693b3a3e64cefda87fe2881362a0bafc5e505bcd54d6b"): true, + common.HexToHash("0xd9179d9a0dfc466884cd598da97c40186739b4e3f367156c137dcffaab68d09f"): true, + common.HexToHash("0xf4abebb5dd36943b5cdbff98b86dbfd86a65bf8bfeabd9f33adc689f2e4e3aa2"): true, + common.HexToHash("0x977e95ebfc408f17b2da60b4eba07314a7907b668b9be85997f43f3737f629e7"): true, + common.HexToHash("0xc01a05c016abe2f99c9dd44493123b857ee32993a57c91e71b67b0238d576abb"): true, + common.HexToHash("0x5ca81a7688da349ef1da7e0d571d9c068f7d372f1155ada5fc5f10c0e2d656fc"): true, + common.HexToHash("0x9c3fe5d72f6d7f9559aca0bb7d6b3bcf4b1544bf19cda59810bda91ea05f0b56"): true, + common.HexToHash("0x18d4c98bbacf0e0b0a3c159e67ff94ff95a545a4893668f46facac2cd41b315c"): true, + common.HexToHash("0x8b56a0687a2aaeaec5490af49721aa8fd33c45081da6238481eecf9cbcfbaff5"): true, + common.HexToHash("0x8645676a58d3ebc856acaf1c520aab1d5425f407d1a06f16920cc3ace1c80122"): true, + common.HexToHash("0xb36cea1d1efdb720e71feb75c33fb0c561d769e9c65db94e2d097ecff990dcf4"): true, + common.HexToHash("0x31f075e6f0123b86af5e7a9710e1aeb8faa696e37a634240729ffd79a80d51a6"): true, + common.HexToHash("0xc85b764083ec8998c2acf7e66ab1bae9b3c3d2b9fa9275540445bc9eb50592cc"): true, + common.HexToHash("0xbc650c1e2b7469f2f97c12a3ee30271a0fc1dadb37a630ff183b523559020abc"): true, + common.HexToHash("0xb3d8f9e494c7b3c7967a2e92dbd860768cba33dab2b7fc2fccae89fb305ecb5a"): true, + common.HexToHash("0x31665ae02eb30698139f75362bb73ed8435615d082befa18b156970f87ab2715"): true, + common.HexToHash("0xf3586b1ea5867f8b9581f967c550ce647f6dc8ad66692454718acf7d2882011b"): true, + common.HexToHash("0x1915ca90fb8e9048c709c6a17dba7d7ffc36a0d6a1d8652a54209c2a7cd0f2ed"): true, + common.HexToHash("0xbe2ff59c003b9048e6d34b8cf0ee57c097fb06c293396bd9e0fec672d48c6271"): true, + common.HexToHash("0xda8b36fdf128268c3fc458c81e7ba1384be4e942550553b40e0c715a5f51d85d"): true, + common.HexToHash("0x67af6f46b11d4e6db9e128885390e944770f278744963e909080a4d596253cd6"): true, + common.HexToHash("0x289e1943d1bbd18eec37cf219492dd0a657815778f19e76b4640506df78b3cfe"): true, + common.HexToHash("0xc3134ae92c67bc4e0b113a6331f46a3a86e7de79d7503d904c02689146efb142"): true, + common.HexToHash("0x3170991f8eda9e6b7364278f41e3cec2dc731a5a370da8c3e89f016abff95b19"): true, + common.HexToHash("0xc1daadd6d0aa0268440335822b6a040fc64d6e39cfde6f301af77af72d2e8aea"): true, + common.HexToHash("0x60c0c94d9ef45305cbd9d9151b86d28675a7b190a408ceda98f741cb1c7157a3"): true, + common.HexToHash("0x556f194b9ab824f9641110d530ce1efb4adb8d3fca7b13b482fd3a2685127839"): true, + common.HexToHash("0xb018c482f8d724054744363fbca4a93cc29e7200577a93431819375b23f81dfa"): true, + common.HexToHash("0xd37c4cd0fd80095dc7029a1e3c85d57a872599ab83843350a03b6f578097dd40"): true, + common.HexToHash("0x9ed579fdc603fc5e5cbee24682d4a3821d9beb0738a564be9198b65418712d88"): true, + common.HexToHash("0x443102f53e2e40b827edce24838bfec3a337537f59d81bd1da12f094daf549d7"): true, + common.HexToHash("0xc5e17f376e627d682d49eb1eff7f69f94e6d545317e4b743600bc9705da957ca"): true, + common.HexToHash("0x31b73cf7500a979aa85ce67427495e8361c99b95e74dd985cff116fb124c3e22"): true, + common.HexToHash("0x5237e7a7a28c212f63eb25f2fc96fb4b3473f9014c767520c53849d975ff8408"): true, + common.HexToHash("0x29b91d06fde7fe55975b19b61c493f5b6812915f895ec1ccef913fd5f4328754"): true, + common.HexToHash("0xb8c8f9d54069b5dd73864449965305b353c34e214f15a27899a5d9b8503c114b"): true, + common.HexToHash("0xbda1a815ed5b9fa90d17e8748a9ee8046828bd3ba7d16427e20fe609d28adf23"): true, + common.HexToHash("0x1dbb2c3ce68825c89cff2ffe7e4d1fee5a129555ac3a66292632149519591475"): true, + common.HexToHash("0x6338adfa710a587fc342fe9d8f5650de4f272a857cd853c0876d89c0a088a590"): true, + common.HexToHash("0x8bad6c53e7ad42ad4560d421a2016019c12e0e2167d69b6edf054d022b1950fd"): true, + common.HexToHash("0x296cfd3101fbd71bd29a67a79e3264d63aaab9aac2d0ac9bfb58e8f4aa64e264"): true, + common.HexToHash("0x592c5d48c6b070d098354337d145dc1483e68b65602af77bb7f7735140e6c7a7"): true, + common.HexToHash("0x0e867e456f3c18480576eb7518f998388c6238579f33d653c690c1ad497aeaaa"): true, + common.HexToHash("0x6b128dbdd3c6c7f6cf710b2c6d1c0a73c12f8a4679a6507089bb999a9e21c1ed"): true, + common.HexToHash("0xbd900329ac45ad001b4f6e8da5954d8265bebb63f5fb1b194b4c8bb0e659a374"): true, + common.HexToHash("0x57ea89ace950cca35b1ba47b0522b1fe392045035e579c283d3ceac7bb2a4289"): true, + common.HexToHash("0x8e69da1056362bf82f573b7e5965b2a48999896ddc2c6eb8ac9b49e513b94567"): true, + common.HexToHash("0x8c56e885eaa9f637026af71dddadef8f91400201e25610de286482df647497d7"): true, + common.HexToHash("0x0bd35a2b0042e37202cb010d496f6faa0fd1d05a823cfb95adb121cd94f67837"): true, + common.HexToHash("0x1a97783a0fb1dc49eea2bf9855cee7b6b0094e761e1ef404369d66a9f2a0e2ef"): true, + common.HexToHash("0x87d9ed5dbc4d233d5049b914ddba0661065515c6edac10322c6992679b42f304"): true, + common.HexToHash("0x34897ac8c1ccf7146339bdd9feafb5b53067d87da2d5bc11561c8dae5f6bdbac"): true, + common.HexToHash("0xa1ae0b4af5ed3221fdce3f70f1cee03e3cf07ae27ceabc6c8b2866f25bb954cb"): true, + common.HexToHash("0x925c5baa94ac1fdf112860e2aa7a98cb51d5b6b003b640308fdbd3a750373577"): true, + common.HexToHash("0xc3c1890477de680aee79c782f93786fb0c04a6b27bafbd3a3754509398af2930"): true, + common.HexToHash("0xf0db018238930edd63e97509454113a1a982d87cfc5ecbb4ae5892cb32d68058"): true, + common.HexToHash("0x8982ef24ceb833589ac6a2029053f750e6ce644efc82e0beb6c9a0cf47de7582"): true, + common.HexToHash("0x4ddba336c77a822471bde0e1fd5d4a4ee8eebcb45ad102d34c57ff9447d695d4"): true, + common.HexToHash("0x9b98621ebca966f7687a7c7eb7db5ef611fc58a6eedb48b540c76b7f15c5c45e"): true, + common.HexToHash("0xdf280f239f4e129ef5600c9c9f126dc0f47f396a5b6920d33c2f302e8b7b502a"): true, + common.HexToHash("0x4e31be0c67fe3bdb3ccaba6d765ae9bc2770ba56e911e69999df38724461d3c0"): true, + common.HexToHash("0xb53ca42fa4732a18ed988778d158dc8ec40779b9d21f7dbab7e4a68ade794364"): true, + common.HexToHash("0xed968eca1a42d9db71a0876815ddee49850713b683c94f9bba759c7982063359"): true, + common.HexToHash("0xb24c093f60abcb45b59252457a2b5913d31f95fe0a6910ac9b0bbb174f0c9a58"): true, + common.HexToHash("0xa038a5179114d1a84b8ef8e00692eef33b3d580ec8cf525fc934ea0416aa776b"): true, + common.HexToHash("0x699365680458a7d0edaf9ec16f9c5bcc69c6351cac2dacbda6df59ca6f631ceb"): true, + common.HexToHash("0xa954967d3be54cf3560c2937c71f876c89f2a5bb1824c8c613ce13ee769703e6"): true, + common.HexToHash("0x2fd15f229404d3bd8b3d08b923a1dca52f27ae793c7a5eb51d8f597682bc9564"): true, + common.HexToHash("0xf8515f8357f7de9075b215645dca16dc4aad5be808a59bf92e6c131d0787e5ee"): true, + common.HexToHash("0x9422579aca9c62c82b7c65d2e38088fa3f6a4c926ccbfdddb7f5681cdb1b31a9"): true, + common.HexToHash("0xad308e3bff7f2e7750a8f406ffd1d94154af8f1d8237f41c5a0949280a478f67"): true, + common.HexToHash("0x1edbb3438a5dc7bda7a264df44338422044ec05eebbc7d84fb064115f324af53"): true, + common.HexToHash("0xc6102722b91e31652bacfa12b68f07067956f076f52d4df6d8bea6ea4c862b5a"): true, + common.HexToHash("0xf1394fe1adeb68759f5aeaa0cc08a34e1e28a56e247d3088687afc80d87e65e6"): true, + common.HexToHash("0xa72049795d18f14a18887f70af47a8d8478ff17d94dc82a70bb3be0c8be524aa"): true, + common.HexToHash("0x50082c07637ec5fcde968e6c7e3ee86f1ef9dcbd5e2584a1f275c50082cf9f85"): true, + common.HexToHash("0xbff3f757ac2e8b8f767671c7ff54af2a8ea3e8695d8148b0a2ee9fefb339ba9b"): true, + common.HexToHash("0xdb89a0fc00a66130c901ff6f2a04d70687e11ed5221e1f94201467ea171d3451"): true, + common.HexToHash("0x45bc02c28e19b87499ca812e0ed7e28039ff1cffd1a27f77ee229b33cdbba1ac"): true, + common.HexToHash("0x9cb9672d8c10ccb11a99bd63383ef7065a6b8d3c04b088e38912756cd398541b"): true, + common.HexToHash("0x87a236c452e00257e127df2dca7504d96f02583fd196bc79b8f0ccfed69dc1c6"): true, + common.HexToHash("0x1ffa4cf512d7670c576040e3438bf32002d178e1c1ea34695701c2016a8fa1c1"): true, + common.HexToHash("0xab1ee2daa8a93c5e427bad65bc56c73f21831bf5a3ae681449e71355f63899be"): true, + common.HexToHash("0x2628a734efb54186306e587a299e5b9cc14466eb388bd08bfb786ba1a272e549"): true, + common.HexToHash("0xa6d236b74031bcba00ec46ed24c772206f608d4d36573d925d7c1df4cc0306a3"): true, + common.HexToHash("0xdd5f64746e3460cfafc044f38ec6dcbad95e7468911884f9baec4b26544b17d1"): true, + common.HexToHash("0xbcb9db0fbbb9f6cb404f7ec387e43b7a7bc224e31019f8704c08e992edc94260"): true, + common.HexToHash("0xd5b252c5dfc587d66f3c5f258a7e7742c71edf5037c0344f590812e9749c2283"): true, + common.HexToHash("0x3494be77d67e8789909d76bd241a88973f31842bc59dc7c2282d34a228849135"): true, + common.HexToHash("0x12094b0d3a3a13eaeabac622972229ebaedda2a7fa0db11e95a26f1e2f9d395a"): true, + common.HexToHash("0x1c8fedfd390a46bbfc61cbe866726cf4c08265473dd9f1642bcd493f2e1b0d9c"): true, + common.HexToHash("0x42f19c0559e76a0ab8c361a64367230244be63991345c01d8db4971ac52d4921"): true, + common.HexToHash("0x3da92c830b12c8ed955aab0e6dd81175e8c48150d85e44ce0acb287c387adfc6"): true, + common.HexToHash("0x2c91f2310235ced0ea84cf224fafa3515d7ee309313808dcb399a4b546c0135b"): true, + common.HexToHash("0x13ff58a797e34ab4db1431a43962fde2323f74ffb05cf0cd0f300519e48b3511"): true, + common.HexToHash("0x1b256719af5491e13dd2ca55b1bc30cc33415865d222bfe79d714c4a080bf17b"): true, + common.HexToHash("0x6c4e1cc91400de874786c6aeeeb5d9f88a923b970c45db4a244d4ef35d51c435"): true, + common.HexToHash("0x9d5a4e00b4da31937967c14c9c2cc20a347289f970275a85a6aca7df7c46689d"): true, + common.HexToHash("0xd92648e8fe7d0a64288fd71f2b10954cf52106569a8ab913dd2fda56970ecaed"): true, + common.HexToHash("0x2da577bb2cb5c7f0a418934eb9d4bdff2bd321bcc17a671e4099a5ec3007fa1a"): true, + common.HexToHash("0x91c47668c1df5376c59e753f61c2cc06124a95c4dbd5939d2c94d5b173e83203"): true, + common.HexToHash("0x63984af27259107edf2120a86b1e1f8fab40d1d0471337277b60af3449239f83"): true, + common.HexToHash("0x45e6d5841ec5c0de80afc9afcc7f7cbb150acc31b41f59eb51481833d92f9181"): true, + common.HexToHash("0x32d54a615a082a3d2478059a84ef48f1dbddc03038fba59f8e219babe8b4afe4"): true, + common.HexToHash("0xacdc893bbf7c977dbb3d2216e3e91d0bb647effe368e944c179c760340564d39"): true, + common.HexToHash("0x990040fbb516bcd2c542c9d1b626fbaab4e5270bd3804e8da1fc0d97949aab50"): true, + common.HexToHash("0xcc2d5145fb0425339af19450dacd55d507435a86625675fbbd15bc5594949979"): true, + common.HexToHash("0x7e3ebeb4acb6ef5591faa6bcb123ff91bc4cb7ab8f155bc9a8aa77f2d9c335af"): true, + common.HexToHash("0xf03a4f323324db413fadd7e5139828fca4fcb614ddfa4821f2848cdf958c92a7"): true, + common.HexToHash("0x4d7d3ccf9696e81436f1851d6e12f1bd8f999c5e44a182a6170a7a0227d35140"): true, + common.HexToHash("0x165af69b38d18725b27960ee7888e93024d4b8ec47c06fc6cb1316a5c0f87b70"): true, + common.HexToHash("0xa7fbc9a8b39d7a0dfab42497e76cc0ba5a1b445e77ba9ae433b40d456bbc0d01"): true, + common.HexToHash("0x6559e8156bdac3b1ae74e2d608d8e0ff301462eabfb0203b68f2710523b623c0"): true, + common.HexToHash("0xd60e2a9447395e5e3278f3e518380f97cfe47a991f41df3ff99eabdc6b11bb67"): true, + common.HexToHash("0x69731933bd261b262808265075e2a363261aac12d25466c812427ba5f5ccf26a"): true, + common.HexToHash("0xe51a662c25fcfe20ae697dbee1e765f856ec73ab274667cee9ededf3baa34f34"): true, + common.HexToHash("0xa4b439930e19caa30a66dc38bf74a9b8811962b0748a85ccece57f893aa65dbd"): true, + common.HexToHash("0x65a2f1f331c4c61ee4c71cc186a0464eaf0587ccee4ffa72b462a68ba8e4d26b"): true, + common.HexToHash("0x79d4e51822f01ebbb0699b7912b34ad2ec24e09e5eea20da0f5250b14adc6517"): true, + common.HexToHash("0x4e273f47a1896c0d6200fae748a66a87f08cd0416192d6d18096520f643409b0"): true, + common.HexToHash("0x48855881ed4146d3c8d3b95aa11085ec1149f74b003f3303dd36abb007baa60a"): true, + common.HexToHash("0x8e73fe5004bd48d4e9d8c033f0c7a508113db6e489d9562975ac1b298f419799"): true, + common.HexToHash("0x5894c873065c4e33a6d697ebc04886e40a0e7cd78e564163c29871223e32bb5a"): true, + common.HexToHash("0xfee7591e03cf813c381fb860897eb335eb442b9ac381eab79b4c7cdd71e4dffa"): true, + common.HexToHash("0x3f613e6ef0c014a3f44bbe135d9829be1115bcc5a7ffd8cf1caf095cd06da088"): true, + common.HexToHash("0xcb89e77cfc5a5ef8ac994851a1a682f195416c95f1defcb2788e19f6511fb719"): true, + common.HexToHash("0xd16e0dfa5125e4e140d177660a1e66a984bfcc66f9e242be22cf88cf0c1f1d00"): true, + common.HexToHash("0x9659e680f284aae1ccf1e75cf8d32b08b290b9c2d846e3bea9cdd292a534e4bb"): true, + common.HexToHash("0x973bdbc384b4847657116a681a75585e60246ceea6e6bc1c753c8a7ad01c824f"): true, + common.HexToHash("0x02999e5c0bc8d4f00273fc973e535c5968b9d1c07820251f68042f071eebb8e2"): true, + common.HexToHash("0x59586b2c8cf2596d89bf87af860c84c27129a76ded5b3f2ef5c47a10ab06a8df"): true, + common.HexToHash("0x2daf34e8552aedf9140fd66d74f1833a9922d0f908f453eb2822119ff4625125"): true, + common.HexToHash("0x912e971fd051f117bcc14f9318b652ac8126c28b803a2ea6f05d33605b8030d7"): true, + common.HexToHash("0x4ee367ec208b64b0c5e19bcb321d337c776c253f26887ad471f2b99beb086643"): true, + common.HexToHash("0xee18f1e7d17e2a45591d6ba17d265680a0c074ec7b478ae784287ca91640fb82"): true, + common.HexToHash("0x5b03c6134b43eedfa283475a7e6cc49941c667edfab8acf9a283863f3b71d950"): true, + common.HexToHash("0x0163ddeb2b26dc3828b3e27ffe31f233980c97b63c4d057e965581b717a7af76"): true, + common.HexToHash("0x102588f8b7010e2bdf7a29f7fa7d1f65a6e0af3717c53376bb4f773c19c45b11"): true, + common.HexToHash("0x441c3999b4db1bc293d18708e86304360d2e7a68dfab427c426aa07e0fc6eaf6"): true, + common.HexToHash("0x9df26a44d5c1d569ceba6bbeeb5692cf66a2d558ebcad53c3b21c7db90fdf6df"): true, + common.HexToHash("0x67814878199def00c11900460e93da16e40ac7c71004c20a99dc4259764b9911"): true, + common.HexToHash("0x697bdcb89292b1c063d5b5ef394bb936c2a0100115c08c4be5a6c0131421d330"): true, + common.HexToHash("0xf1a25dd830f72059aa8320c1b690fcf55b6b6819769d475e15dae9b9da89670a"): true, + common.HexToHash("0x60c9e8992cb135f7970575202e0ae61cb632ea4e0db132f82c1b1ebcf2077894"): true, + common.HexToHash("0x7e47b3deffa1a96276ec5f8c1f552af6849dc63491d31682febfd5199990f7af"): true, + common.HexToHash("0x9147d68a34c46884b00cea8d978ee07b038ad9acbbe32c5751ccf56a6a23b2ba"): true, + common.HexToHash("0x3822c005a009f0a0e77ed30fd2b755e36bb9172db140c634d80b5a90585feb3b"): true, + common.HexToHash("0x6c49c530afd706501b50b0d143a801097567ba8d78487c24e038f12ed3ba8f60"): true, + common.HexToHash("0xb7b0068b93a9f6abf6e7addaa6d250a9afb127bd56284d6da12601494a987a61"): true, + common.HexToHash("0xd998743eb256193c3bee94c0ad1fa484ebfdbb5b92804083c0318a3dd007f8af"): true, + common.HexToHash("0xcd62f99b191011edd6bb6d6cb24501e6ae1b59916fee266a080ca46eb19684ac"): true, + common.HexToHash("0x0494b44c5aceeccc0bf2ac422575d9c5e0f080cef9a49bab10574039f14d9202"): true, + common.HexToHash("0x4c6d30325b47e26817723348c87fa0a53866ef44bdd2921619b739e5c93bf691"): true, + common.HexToHash("0xee8fb70483373faccbe058f85bf597a456ce19eeb2a533bb65390ad4fd8c82c1"): true, + common.HexToHash("0x4eb6bce5ad34cc4abc948c158ff3d7147a4ca607fd2c630613a8ee4f2ebdebd3"): true, + common.HexToHash("0x0a13186f3ab5193cdf3bdf9f667a38257bd55fd0df516c1de6b09fbd5340db97"): true, + common.HexToHash("0x25f7edf2758bb2d4111b3d38801b5ed7ebe78d4599795cc68f0ebd9ce1b359f4"): true, + common.HexToHash("0x77e2e50251ed30d568ee469a7a0e5c88c84ef3fcb8d94ed65ead4e0a9e903436"): true, + common.HexToHash("0xfaf3e42ce322d423c47d8c08da57fecb7b08cfa91ca3950da607618d85a4a121"): true, + common.HexToHash("0xb37e9a493c757cb4fdcd3e987c0e36554c8250930782b483c15293ee963e330d"): true, + common.HexToHash("0xaeb7908299061e8540354ed5d471ae00daef058b80ce95fcc50927c63161d6de"): true, + common.HexToHash("0xf3b6783ae8b57e66bb5943f6f5693f7dd91075a77113284b058d0560d2dbead2"): true, + common.HexToHash("0x730727702509745c8a35311cdaee49e2054690ee2aa0bdb95dfd4f488e63dbd3"): true, + common.HexToHash("0x14577f126252598ae4a318921f60b7eaceacec72c5ce8566eb020ce45a524231"): true, + common.HexToHash("0xd0293e2eaf88fad355edbd876fe70b80e43b3a1683b12a191a8108fd809546be"): true, + common.HexToHash("0x6c7363dee1b5a25171f98e95e79b692b6895c60ea8fb15e17843ef61e2bc5430"): true, + common.HexToHash("0x56fafea4526d08ac68077c2571cd95390b9ff5c8b77ae6d1ebb3c2e7b3a6b569"): true, + common.HexToHash("0x87bc824d4c9c9ce45379f87bb30a67796109ad0a6b6976d284bd3ec23bb0ae01"): true, + common.HexToHash("0x7e12d1bfa74c62cb5543d065ef668f175b5cfb98e1cfb4b37bfc77c5c4eb193d"): true, + common.HexToHash("0x909b5945857b555407c94d71aadf9c7ce69f29992f59a7ce0846acb1fc4cbe79"): true, + common.HexToHash("0x8386132f3110e6af6ed75303841cb60077e3e2693fb61c776eb2e9664cc3d289"): true, + common.HexToHash("0xad9d8620714ed0e6858bc67f2280dc6b42fee9901aad4b643617928f89f9fdc2"): true, + common.HexToHash("0x5d548f2dac52fd343e3e6cd17b7d7e29edae37a1cf3351773e4beee152e6e908"): true, + common.HexToHash("0xced3fdb36ad0ecc4dc58edc07ded38ceb74e19b60c8fafb802c9a69f1ec9bc53"): true, + common.HexToHash("0x5626b945a2fb2e82cb72517e0990b3ea7b1ec9ed7938f561d551c7eb2d46302b"): true, + common.HexToHash("0xeacca450416a1f7b2fb81f10175c9046aded8739eb907934b96c0106cd5adc74"): true, + common.HexToHash("0x00884e8b372de993d55b66b3e5d8a33b00918504141679fd6ce67abb839ee168"): true, + common.HexToHash("0x70d396a4903642783adb4c704bd9aeb9a02ee33e631b1c7a5bc0821c475423db"): true, + common.HexToHash("0xa5a9533deb012c048d5c42803062af3f162d6c318b510f6b40f903334a05245f"): true, + common.HexToHash("0xf090f118a02773f5cca93cbecbdca5272fd4b9e5e889134e05fd80f292d27879"): true, + common.HexToHash("0xbb5de1a59a16f25a0b6a8393c250d2b1a4020307d6f9b5e08d988b76501d9d23"): true, + common.HexToHash("0x0986d4c98d40ce61093fd3516b61e48072ace53b89e622b45bf1b6db7c7639f7"): true, + common.HexToHash("0x0aceb9182961fca510f5a724a5f92faa56c3c0999d210c6c0a04d8ab9b5a96be"): true, + common.HexToHash("0xa618950ae496c47ed202fa3014f35964a99e4a7d6e881b169b4db8aa41023f0f"): true, + common.HexToHash("0x7b5086c02b1ca3fbfedd48a503ba269027c49de8cf11ba4edf3882629d02e787"): true, + common.HexToHash("0xdf8b1c9c7ebd860a5109e99e16e925499fb8f51a21c3ae391988be7f473a2e98"): true, + common.HexToHash("0x91c2d819812e09fdf2db8d8e157fbbb9bdc2a292819bbc66bbec151b3d08e8fe"): true, + common.HexToHash("0x4c499d87e38921f58016e32e0bf4b5dc87e3df74cdde71e0eb288eb2db053256"): true, + common.HexToHash("0x044d5a348899896fffa73bfb31539c1a9c33462bddfa7de9a513639b17dc056d"): true, + common.HexToHash("0xdd678bb47030f6fc484f204dd91746d27cb87fe30dc6bd6d3bb436d4ee4ee2a8"): true, + common.HexToHash("0xc67097f67dc21bc2fbb4c8218f4e57a5aa5c194b8ba4e833e4b968bc7560362e"): true, + common.HexToHash("0x830f42e7afe71ac1949b234495b56afa8784505eee8e646eebf336f974bf0b2d"): true, + common.HexToHash("0x17186b91aa7f8b8f5935f9d15599598f677cac876230e772e04de1ec3bc693b5"): true, + common.HexToHash("0xeccae326242bec7fe985a2a80818caeab3484da043e892a7ad82a87879c7f223"): true, + common.HexToHash("0x137948f3481f0b9eb311dc209bd4ace1cd3f35a35f5e0c29ccc024c72c1b5e6e"): true, + common.HexToHash("0xcc7b8431e25b110bae56f8d9966a761d1dcfc13b24b551fc15ce981aae365817"): true, + common.HexToHash("0x5313f3125eb9a4a12dad20af63453ddf70bfbacb638f8264ffe021e39b9df1a1"): true, + common.HexToHash("0x07925e3bd7003ea6201b1a0cd5fba85d8de0d3a5824ad3c75e2f7fa9c8ac8598"): true, + common.HexToHash("0x1972d9ae72a9b1b2f4be9c2f7f3c030e02dcc76ab539bb6f290a3178f9a76c01"): true, + common.HexToHash("0xeaa3a44b98be1d7c69761a8b14908455944daa2d85e909a03d2cad9afa299d3b"): true, + common.HexToHash("0xce7615b987cd213f3c0799bff066f5368f7b0702cb80e06e85f7ee1b7d8b0f21"): true, + common.HexToHash("0x4132142b23134c2a128ea2745eb6094af74d0a1509c51ce823039cafdb5e079c"): true, + common.HexToHash("0x1189233d0700f175035afc2ab9c0f93a5e0bf911a83707fff5c86732c0196154"): true, + common.HexToHash("0xa1926e4a2a16601cdbb0d3918ca24ecef1e42e706d88964d66c67e829ea9ed5e"): true, + common.HexToHash("0x201e534370e49c53f7135bc230ed095d7ae0a097f6614c77f5609da6aa45fe5d"): true, + common.HexToHash("0x581a6d3b5fd089e764830d83b4385f9955aa5ded8ce1a26399f71f8fcb78b4da"): true, + common.HexToHash("0x0d012d65365dfecb1ed59d8f1c8d3aee80a1ce7020e4b68c005db2ee90b09f89"): true, + common.HexToHash("0x2520228e5e1f32566b497dd3fbefa644e8469582a20b6e5f30f03c19b152c78e"): true, + common.HexToHash("0x1cf972dce74b5c72bcb8ddbff80147f191c4708290e35fec8c6bbbfed4225649"): true, + common.HexToHash("0x36eb359bf4fbb0a4eae7a28e929ce951148ec5197fb0275a3fe2accb42e4a52c"): true, + common.HexToHash("0xfd0c0e7efafe6cc87682199a6c12979b66ac33bc22530051379d68178d82685e"): true, + common.HexToHash("0xf1c00572123429fbb0a583dacd5f64c7ddab57f522c5bb91b69067401a938c57"): true, + common.HexToHash("0x103f63cc776817513d4a4ba61b74529b14a7033bb11545d831b90db49db651b1"): true, + common.HexToHash("0x963322acdac9b8a9023f24a246d252bc0e6fb0274c55dd680d400b93701f9ff7"): true, + common.HexToHash("0x551906ffe9d94efb316d7ac52800e62948ecb84a7c2331ebbec1f7410b4b2e82"): true, + common.HexToHash("0x8fba2d1d3bec1bfd7997182d98e61aeea878890600f0ee832291bb42a238ca5d"): true, + common.HexToHash("0xe435db532d7843984b6bc9d7a55bb89864df6500fe3a5596e4e6549d948bbca3"): true, + common.HexToHash("0x06a135d129abc710e7819bf8903e116563d897d06485ba73d3f2587e7c70083c"): true, + common.HexToHash("0x87b19c3687ede6213b7ffe46754919da1682d7b05646e527287363c8df88f3bf"): true, + common.HexToHash("0x2942a2a66d691996d7c85ce8cdf2a1d44e7e7ec61fcf476420e6784e7f2af29e"): true, + common.HexToHash("0x35dd9ceba3e27bee2cfb43c255b872db85cbae8dab0c4bd4b7e03ed525424d77"): true, + common.HexToHash("0x28aa7b1d1ea0ffa2a8d9c46f86514e6480593e9556b55d806bab952905254cff"): true, + common.HexToHash("0xdf40d3e99944f1ab25097ac1a990aa2647075d663bfaa480355926e784af1fb9"): true, + common.HexToHash("0x4fa324bf00b67fdf1cd3c92b7be346fbf303b6fb361facd3d5bad3ec89ea708f"): true, + common.HexToHash("0xf3f8c5033a3409447e6c1e258cf8cfdaf1d0db761aa82a49c21a8b8c697f7666"): true, + common.HexToHash("0x2a91fb8777e85d0cac1e7d1367acbc495cb802e6ff631a0b418ee415f81c5df5"): true, + common.HexToHash("0x18b64e0f7a14da313c26924c208b12aa5a9cc4bca07f3aaf3d62f53703c5440a"): true, + common.HexToHash("0x18deb854f9cbbd0b92e32d4ecd139e9c640b453601afe52716c1b1dc7227ad54"): true, + common.HexToHash("0xcbc36a8a0f28d097eded5702540f8c7801561c8693ca133abe7b8937217538de"): true, + common.HexToHash("0xd285785ebcf8cf1340d2c1d1c9f960afdb438dc3cda53a7c657140369cfeba33"): true, + common.HexToHash("0x0b404935874ad1fc10223034f91c20031a5016a155369f7167fff185cb10b98b"): true, + common.HexToHash("0xc5627a9c8a6c98ce834e3e0b37a147af17fdf6b3e46f20a0894ee4381e449c61"): true, + common.HexToHash("0x55dfa8422a3e63456255128ef5cf634ecc49390b5ef2d21092756f5c94756d23"): true, + common.HexToHash("0x178829a719a6903e633b0030de6cdbaa9bd18ed56ee9f8b56f79984ae1419ff4"): true, + common.HexToHash("0x8b16b3671c515bb0df48fcd2487a6bed90aa140048138ac5d934b246eee0ac8f"): true, + common.HexToHash("0x8d34010a12b0675c1ac91f0978b83095fe103f84df6ebcf75acf6ab6c18cd8d9"): true, + common.HexToHash("0x78cd3301e130f79c514aa76ea0005666e3021ddea5ee7432d3643d9fb373757d"): true, + common.HexToHash("0x2b2d9bd1da9f2f9dd05b05c8bff8041622a8ebd13c74a34c289a8b7f7278d073"): true, + common.HexToHash("0x8547e2e4f7388345a881b85068af6cb56fca728d1077f3d20598765b4fbfb7ce"): true, + common.HexToHash("0xc57b279ad0048d7f7225b8196f37e43c3a6059917ed45e758c9ffa4f48691520"): true, + common.HexToHash("0x2e5ba213073cf4b2c16426a777089c55adf81a4add39e0213081da8818af40a8"): true, + common.HexToHash("0x5714c5516ec05bc62dde7ccdb8cd33ce60b4a44eb19aaacea62dcaf60c262852"): true, + common.HexToHash("0x136956bd47aadfc10340208a06aecca10a38fd9d9b0f3faa2fd738bc1e67440a"): true, + common.HexToHash("0x58d06cfc4df135c9914f2bc1e69e0fa4163d74b5a618f21c63fa116bc23bd61a"): true, + common.HexToHash("0x0ccc2b47358951fa097fc65c9ac27d97148c005bc633ae6c564b980ffcadba0d"): true, + common.HexToHash("0x7bdf515a116c172dae7a8d62eccd8de9f090d1b77bd5f39419640d4c8d3b7f7d"): true, + common.HexToHash("0x957bc6f841734a1cd52b8aa6d8cd6440364a03d3ca2e7cfe7f8dc479bd9ed5cf"): true, + common.HexToHash("0xa25ffb78610ee5a744c0605e6bfb5180def794d863307601fd5e93362cbcf883"): true, + common.HexToHash("0x73e2358a6bcaa15bb65a0f96d47ccc1a15711d1b8a95e4cdf5ce102dab613ebe"): true, + common.HexToHash("0x52330a9af41355ba443f5bab5415e2460923978ff70e7d505807d41a774339c5"): true, + common.HexToHash("0x6cf799cc5fcb79f0ad291538360d219a2db057fb18ca2e37051f790ebf1548e7"): true, + common.HexToHash("0xca3f4dc1b40ed862cf701fe6fab13688a85926bf3018213c3992acc58d613635"): true, + common.HexToHash("0x0b471f1ec1ce05a9cedd0178a77f72147839fe585758b3def30482298e5ef3d8"): true, + common.HexToHash("0x58a4f0031754c701a759ed33ba8a7349cfdd5a5e9be31fbd192841b41a80f2ed"): true, + common.HexToHash("0x82dd7ab5937db3b4ffd9eee71905fbf678cc20191c2d8adba694da0d1df60e8c"): true, + common.HexToHash("0xf7ea1eaabdd0a999f9bd24d16eb362be644a3b40e4d946b8596e0108e7f90872"): true, + common.HexToHash("0x8c3e9833dfc5898aeeca3d3499ee8a511c9850e1366e9b67a082a7489bbd8058"): true, + common.HexToHash("0x53c34d0a317143ae8994ab4b91ba632a2ed75564dba842340aeda1cab66d88b5"): true, + common.HexToHash("0x3e23f3612d051601b2096c54057305a96fbf2cb339d71eb28aaccca5189e8ef6"): true, + common.HexToHash("0x3f0c508b59d58d83dbeb931567cd68cadc9f73cf92292c1e5e1ee10e3d23161a"): true, + common.HexToHash("0xb08ace1201292bc97a40c26a1905a7dd098beea8b35462838177898f07d0d8ea"): true, + common.HexToHash("0xc1ef02f5015f02ea3f9afc82c6dbb86b9b2337014f12beb948ef10d2346fc4d3"): true, + common.HexToHash("0x885f2cca46b03aee2cab36600f4c08cf327e2d7b9922d0aeef2567ca6b158a98"): true, + common.HexToHash("0x7c96413b2bcf551346b30e67b499fd9205a57a3ed0a6a6ee10bc3a2898ceb301"): true, + common.HexToHash("0x211585c94ebb350755b3fce8ed206aad66fc85333434a44ebc7ada8e8e04087a"): true, + common.HexToHash("0xee6c6ce2524631a4a4ee0d79c5ef68a8604056b50ae2eea875fa6dafa1bb26ab"): true, + common.HexToHash("0xb075d4ed22ceabdbeed5596337b2d3895256bf6516a0cb762fdf304f72d1299c"): true, + common.HexToHash("0x06e923072a3bf4087a7bda876b534d561f6b264b04148ea269d81d987ceddf6e"): true, + common.HexToHash("0x97cdd1e1c5f8744f0593403d284e6795a79b8f34a625aedeca01bc3ef154a19a"): true, + common.HexToHash("0xcb328c8460305ce81640fb71a643a535b112ac3ecd39f0fc45bafe239627962a"): true, + common.HexToHash("0x23c02fb00e078d8d3def6eb2c0a9d04841ebb144771db5a6a81060771e0b658d"): true, + common.HexToHash("0xcee4e3540160574f2c9df0ef2245f3bcdd9b04d11f561639152c99f8e5920149"): true, + common.HexToHash("0xaeb5513828084a7f289958ca185b9410fe394037a6b4583e2447a80f5ca6a692"): true, + common.HexToHash("0xc6df2c1dc07e365e1abb4ade0f9cc3ace02edf226822437e59768ab7e6fa6be5"): true, + common.HexToHash("0x64e45aac901fe8b6bd59c7d28d7e7253d6a0d5d082b825c7bfc7cccdcda00bdc"): true, + common.HexToHash("0x1509e2dca30eea4ff81deba5d29ce0c6cf0f5eafdf72e2795a3c13122611a038"): true, + common.HexToHash("0x8bbbf30111f47047ce467853cc03d2f4987571a919b27a6a79dd03242931f11f"): true, + common.HexToHash("0x9698da8da6008ccff5f3464b5b97002c95eccd8d87b57070d19eac6d16e7b910"): true, + common.HexToHash("0xfb4812df8ce38d5aa87d27b4d7f77af4f10b65cbaf3576ad8798a4ff29378db6"): true, + common.HexToHash("0x0758c5c2e9fb2efb1ba675ffdf60ff64a545a6cfccbc58e60221f5fec502786f"): true, + common.HexToHash("0x192860fd129add7e340fb162e52eeea93755c9a857fc8319545739be680a2196"): true, + common.HexToHash("0xdf714daf49ca51eb2f6b235fbd09d0895b683dee9ac778f3b0a1c1865b1c7151"): true, + common.HexToHash("0x928d41600fd408a5a6939c3d05d92006d02888f8fc5d0c3c84a780db6b5dd6c6"): true, + common.HexToHash("0xb6e2de6f6d3c19101aea5459983bc3006647550ad6f58e26e534ef3a628a3604"): true, + common.HexToHash("0xe26dfe1694bd5d5d840a6f051049d016fe506e648b89f72fef460025b534010b"): true, + common.HexToHash("0xdea1ff563a938c03bef3a4603cf3be5879b0722f8744aff99c6d0db4f8942d2e"): true, + common.HexToHash("0x931ee50e5b71fecb0b432b4344195b5fc5fa8f4b398c848111a132da0e806396"): true, + common.HexToHash("0x50a67340d32b6f9c014f230230ead0c6d190812aa2cfe296e0a6bbb215836ecc"): true, + common.HexToHash("0xcc9b5bbb63d71f338557864eb465bb857a363b4eec7bec44a01e4418ec6748f8"): true, + common.HexToHash("0xfa55a0799daba5fbfe3832da22a824182e510326f87cc1775d222c06733c81a9"): true, + common.HexToHash("0x2341d858d261b0ada3d89520d83201760ee23aa32075d5e44afbe6bae20dee11"): true, + common.HexToHash("0xc4a182171b8b0509cfb02fe3f605608da67c58e904b1d0eb9c56078b1f12678d"): true, + common.HexToHash("0xd523e56f58ca4dcd9791eadaf4a0c9b4a3f4c32adf2ed225b8e36176a2348923"): true, + common.HexToHash("0x8ba45e0e7dcf91e02e8ad407612a5ca8994304579302495afd089dc84222e640"): true, + common.HexToHash("0x9668a202a78152b4c3bc5da3f4d738961065e49163359f2274f1c76d8045f342"): true, + common.HexToHash("0x6c19740dcca335ce19c214a4e975b7d432856a0a0320d95b7d39ed905a61f07f"): true, + common.HexToHash("0x58a40df256429e74315cf61cffeb21ccc3d49597b9e34fe9d1bd751d00d7a6b6"): true, + common.HexToHash("0x1bdacc1cec185fe2ae4819dac631c96679c80981b904f7993a2eb495520496cd"): true, + common.HexToHash("0x46e61515139dca760bf24aec530d1b5f13ed9034cfd123d07fd4f86cad4419ad"): true, + common.HexToHash("0x424eeb08028bdb9588584227c76816c0d74b0f7d783257f36492ccca256f3e7c"): true, + common.HexToHash("0x9d461f85952f95be1758c916700d19ce1ac9153db96e3d0a65c583ac19869a86"): true, + common.HexToHash("0xdacc54bb226f3e0424e89f401b43d24c6e08ea7d788456c9b40d619cf22b9e7b"): true, + common.HexToHash("0xbeda077ebadfaaaa32e3110ffed33f82f36b8238df4c9111be9900867b842146"): true, + common.HexToHash("0x6a42a1fdc64e46ec9e748cafb41cc407744d9c3ae6131d5d81baa3738c402eb4"): true, + common.HexToHash("0xfa931f9278d8607a4d118aad692db8b47b13380ca5a19151f111cd0d401533b3"): true, + common.HexToHash("0xdcc8752c4a55d2a39d020b978313527bc8504d5e77aa8f6d4cdcc3d2c9fdd525"): true, + common.HexToHash("0xe59da24ae377a07ad72e89cdb3d31a963f0a4deab470fe45feb29069fe35900c"): true, + common.HexToHash("0x41677486c66c99d8b7284b41ef880c29df7ced872eda1c969f658e8ef0ea1255"): true, + common.HexToHash("0x8dac33e2585f24cd22002119f7c62f3d8db0935330636b8cb6e6ff9bbeb3d2b8"): true, + common.HexToHash("0x1293dd08aaf3e54f9e92b806b745e4fe1d4695ccc99d4de18f1d5c814f1fecdc"): true, + common.HexToHash("0x103f6f591d46238afeb331ec4640da72a4a076055d0fb4758f0892f192e0458b"): true, + common.HexToHash("0x7d1487f68c98d7673e0be75149c0bde0d868fbcf446d9758e8fb2f2d1be4f652"): true, + common.HexToHash("0x5decfb9b3ec380a8f85663074e1794e6994b7bf800ea8d5333c24c099a357f07"): true, + common.HexToHash("0xe34b1175033aab1348a5aae186632f103e12d467f1f692ef867328790ae1cba8"): true, + common.HexToHash("0x243143301ab81dcc4325a11b7ecd4f7b9104a6fca0fda6e8a6259a196ad8cb7d"): true, + common.HexToHash("0x73fbb90e33f739bc95a1f323edb0a3d58b5db05c4bb0df6ae73303bd4b732052"): true, + common.HexToHash("0x755234e3c1a8a1ba9d34316a84877a3055eea14c62c7f72a3871108596cdbdce"): true, + common.HexToHash("0x601e85c1b67b46ca7bbc914a7b0208749912b217df983c346a6c439869c07021"): true, + common.HexToHash("0x3ae8df448d3e36c24877cc6e8a6b8f7c4a94a938d26e744a17293ea72a5af0e8"): true, + common.HexToHash("0xc2a28ddd8a32982bc13c837683fd1e1ec6301801d6f419143db4827c714bb9eb"): true, + common.HexToHash("0x9b98d36ff83b4825caf6a8a380d2c1613fe423f9695c1f509dfbed7238284353"): true, + common.HexToHash("0x4d5086de73d1ec2e4b2ec62e5dbfc89cc400c8697d4bd6cbfe26fbe61bbe125e"): true, + common.HexToHash("0x5178d40079d51b03d66eb0f6cd75e1bf8cadcb791cc82ac75b10d88428b2fac0"): true, + common.HexToHash("0xea4a82bbdab4661f4036ada42a73eae31efe2db8f6d2e2f4c2f8da832f4cebb2"): true, + common.HexToHash("0x6252830321c788d2ee4bc5ec331c3070471d13d0b3ebe3c4c27024081e7c1806"): true, + common.HexToHash("0x0a2c68e056d4c4177e3f9bf3bb6657d4e9ea8acf3275160a82a852d53d1cfafb"): true, + common.HexToHash("0xed11fbd17ccb9f906265b14ae28b2eea00ebfe2103e4e0d26fb64e2ea594da6d"): true, + common.HexToHash("0x3fe73501dd1e5dca40cf3c2a7a078db652deb1c669d39b19db3a72fa56258c34"): true, + common.HexToHash("0xa4c7b8d461a4b62404b3bb3cf0ca197de1fc0d71cbde1dc75622cdc6342185cb"): true, + common.HexToHash("0x86f7991e69c0799b5642f3593994b7bfe2b303a123d66978187e65204d6d6fb4"): true, + common.HexToHash("0x2eb84df8785d9e4bbbcbcaa6d00b27c26db62deedab810266cd11e42335434ab"): true, + common.HexToHash("0xb567458650717fa8be85e0b575286eeabd7ccbdaf69dd69f209a20f86ac0f8b5"): true, + common.HexToHash("0xd899caf22de6d91be5c90a4db4b5ff44f3453f7be8cef756be16163f0dfbdfc1"): true, + common.HexToHash("0xae306bb2ccba36193fe045a532268e755603bf2d85644fc1293dfdbc305dd4e8"): true, + common.HexToHash("0xab56efc67822c1daa6f964e4e1bdb99b047e7e5e3e1b92402a55e67b296d84a0"): true, + common.HexToHash("0xd4bb4a663c1c6a570c699f6ce6facd213cc9a36a5fb90bcdca9dff01ea1e20a8"): true, + common.HexToHash("0x3529a8e39addc2e2551b571e097db794194adb12a151f60015bdcf612724b7c2"): true, + common.HexToHash("0x18606ef06f0c738f42fd8ab6f3e4193f32dc3d829ab242256041ebead94a8dfc"): true, + common.HexToHash("0x236352a66c6d5018dc7ee851399fdaf3e5648f09969baf87821d854818035972"): true, + common.HexToHash("0x2d4e0bc45fa94ce542b481e055c90242f5a99db14b97e054fcbb9f05181ea913"): true, + common.HexToHash("0xc9991da4789834a56bd0683c5bb983ab4b5912614934c2e5fc8f68cc1feeddea"): true, + common.HexToHash("0xbbe1b54c3636c277ddbe0caa4db5f4ff94e63e78af77503208d586d8b1471b7d"): true, + common.HexToHash("0xde2770e7eeb0e555b5ac17c96a721c317d6dd3c1bb7366bc142dfc11d6df3179"): true, + common.HexToHash("0x468afd1d322e29e46a2b81674e1fee37d32fea34821d9589de650a80942c7a4f"): true, + common.HexToHash("0xb22e48ede2d5bc78282694609799aa9c83676af9f4c74ce3579a24b935d5e278"): true, + common.HexToHash("0x83633fb4ca93551608aa516869c58deb06cd4f7c1e675d4bf85ae1d86aeae4da"): true, + common.HexToHash("0xf0bf1c796b89e05e645261e88b46708671a0950b3402a07f7db6f0333cc631a6"): true, + common.HexToHash("0x3a9984c0d7165702dcb71643b17496cdd087bd723066908060dc2005bca56536"): true, + common.HexToHash("0x5d8778b31afb8167d2b18e87fff327e521cf4e2e8681880a9f361c6aab2538b6"): true, + common.HexToHash("0x5153f26a5c252c01ab4a5b60ba8e674269178e0f98d2fcef3250ef5786e93fc8"): true, + common.HexToHash("0x2dc50729cc67f9ce83e77ddd5cfb5255191b2d217c293ce9ab13b9242f22be59"): true, + common.HexToHash("0xe1002c59e400bdd92c1958a1742a15a9ec7fe1790089f397294cfe5c54804a06"): true, + common.HexToHash("0xabf54dd1dc55c3441ec06045fed070f69722f5efb8dc5d9eae2dd54c7fe01a05"): true, + common.HexToHash("0xa69a91c6b6010a21660cd18ccfa047ea68d770ec976bc7ceffd27496869d3bcd"): true, + common.HexToHash("0x5531cf349270aed0c7dbc002176ee62b24176f0f6020226430012c7d2106f535"): true, + common.HexToHash("0xc80cb6e3adc96e330a82197da622bac609f089e3226e290ac39fbde5527645e7"): true, + common.HexToHash("0xcb8ded37b5030d9a20f3c345da2b70a49db8dbf5093b4c1b13a0d01f4c5cbcbb"): true, + common.HexToHash("0xcfd5dae484cf9a1fe1165acb5ac0e5b1ee9c3ca77d27f53782e704ac2b24987d"): true, + common.HexToHash("0x52a19fe047e32d55bc09eea25546d23fe65a6ac628d07e6afff3ce38fe0b4980"): true, + common.HexToHash("0x1fbd7f610d8a99f66a096a25a2ebf009d6073959839e35a7c8da895e5376a083"): true, + common.HexToHash("0x61ffc433769ef9d38cf870f94d2eaf26591818085581be8e2f1b95566c540e9d"): true, + common.HexToHash("0x10a97511f33dd140424957348852fa5c4e7738e1b2c971ef7394e246794ce3a3"): true, + common.HexToHash("0xd3e38dba8e931cc5e0ed8373fd651fc6302c9d394545aa20e33dca4bfa7d3034"): true, + common.HexToHash("0x7c51f687a1096541719625f245866bb604b72ac3b0a764bc4a7562e6f107a57a"): true, + common.HexToHash("0x09305eac19e3b8faa32be8c517aa7cc53ee2cc61e0965c928ed75c6bfe3c4c57"): true, + common.HexToHash("0x0b6579a4e240e27fba2eba812bca06eda9cae054916b7a7032ba7ac5eaaa1a46"): true, + common.HexToHash("0xa1c1f378205377d38a2b7822e1315be1b90a12be1e783c36f7333e056a687777"): true, + common.HexToHash("0x805d858207bd53ac553f298f6ce43ad644bbdd7832bb6048f2a0562edacf6286"): true, + common.HexToHash("0x56317264c17d89371ed3539025988581f04dc30526c71a82898f817761dd7740"): true, + common.HexToHash("0x17f16300d278b2b3538b4ef236c80994e260f9544db13d8dc2799ffea380e2d9"): true, + common.HexToHash("0xb70d07cd849b2cefebd1a2272fd6c7f4d469ac16ee5d2d85d2fc08e5fab35592"): true, + common.HexToHash("0x1954f504d39f1ac9bd55678c3f7561d53f98c9d49d68d0f29a2ef4922e182c26"): true, + common.HexToHash("0xbe7f06f81ef18ce65df86fc054e6e2af90ea587865b403ac0fc95bef5a034540"): true, + common.HexToHash("0x3ea604416f7f73280501e7600417883912037e576828f2b7b05a8e323d7470e6"): true, + common.HexToHash("0x512bd4e807631a60474189f11d955b63566dd82f89df00baaecad9fedae759f3"): true, + common.HexToHash("0x99570b4e073e5afd513220a84ca75fe8b01b572c482eecef7971828acd632906"): true, + common.HexToHash("0x86dc242e7470036eac6934b6c95e89cd64cb168b7e85497a84999b6b976648f2"): true, + common.HexToHash("0x42f5fd3317ae1345a91b8b83df395a81e93ec1a1c7d409562eedbd3e73b0de7b"): true, + common.HexToHash("0xc053fd15391805afcd7a512de781f2a435e94c939ac2ef4fb71ca71b874663b9"): true, + common.HexToHash("0x8c5fe540323ebfc71c094d50116d6d56cbfdce135369871acf22f5c5d9b8f17c"): true, + common.HexToHash("0x7603f5291f9257a77322338dc06cc350c24d2d8f8633116e8442385981c20d16"): true, + common.HexToHash("0x07b7b1b51fb7b2435f9787a7525c3daf7187ce8dc8ffe6b047e2d09669e7a5c1"): true, + common.HexToHash("0x103a0f5da2bd39e6de9854f1798d79c7a98b6622144faa0d3de6615fd168610a"): true, + common.HexToHash("0xdeaadcab6c46822942454d4b1d4b3835dcb5cd01ef68d864b9d67f8e8c5d3d46"): true, + common.HexToHash("0x714b30678c0e3187504d7f473f76ad17741c4c94f4ef001d096b89655eb335c1"): true, + common.HexToHash("0xd7eb07eb1fa022c5461f2288a416276ab977dd532e0fbfb0d816daa7e4cb5344"): true, + common.HexToHash("0xe6f860774eda6b5d855f6f889ed0d6dd8be83ae80e10fcc986d19d4897f4ec86"): true, + common.HexToHash("0xbda93d998bfe6c68d2d29d1c9529ee6e82bcd446ec47661e5ccb74b16a507be0"): true, + common.HexToHash("0xde272a22e3f06c118a188d868d1613e56d5447b7c2505c709069d1c9ae4cd149"): true, + common.HexToHash("0x9e70ff2bf867d19330b06b73e094a76ab0be43f16bc3c7d3f67f8bf747aa80b2"): true, + common.HexToHash("0x9291fb545b6833ca2e5014e267ffcbec61b67503449300ed5705e8aeb16f9cfd"): true, + common.HexToHash("0x6e2b66f46ae200fdfa84e9794e0231386834d91ad3cba7a5e53143aa62dca9b4"): true, + common.HexToHash("0x05d0871f6c9642ed3be45a44521c9a1337d37260ef5f55eba060d55ce0445077"): true, + common.HexToHash("0x567821dafc9e69d9c4e86292d027c1c3f7bc5d2cd5c53b50858053f2a37bc468"): true, + common.HexToHash("0xdf58ece6edb2e15fd89f3f8b1781ecd3ce89e24d9cb8bc0b014d0155a8455bb8"): true, + common.HexToHash("0xe70372d5b9fbda59f948b65b8bbd27191edd3d11b9b39086d141ac143dedd0d8"): true, + common.HexToHash("0xf8420abe629f2b49590fb1f6e47da2948fd5eae94bfd64ca9ae37c703772230f"): true, + common.HexToHash("0xd62bece2bad21359ff7f3401f23effa85887941d04f746e2b08d920c75e2fe4b"): true, + common.HexToHash("0xea35bea6266f04b9d81dae60c4d7aae44f058469d2ce35670e107799c1e86fca"): true, + common.HexToHash("0x167314f5aae1116dd178256a7717d2fa07b118fbef5319dc57489785f54f609f"): true, + common.HexToHash("0xc96d1f43bcc61ecf1a7b42c58839d82247c470f04c4cbebd86d0fdbcec38daca"): true, + common.HexToHash("0xb1ade113724c958c2916d5961d34eb7586a1b8aa67cbb7394b116ccde1486427"): true, + common.HexToHash("0x54d365d861417d22dfcab20dcd641d510eeb3f58da2ab7b1088eeb98f1001b0f"): true, + common.HexToHash("0x90aa2a807657308c7641d5b5eecb21530e86c63e5d12ba33fdc3ab469148a91c"): true, + common.HexToHash("0xae21f428305d93c3e9f6e78d713f7e89cfd37685c73959ee7261fc4284718cc0"): true, + common.HexToHash("0xcca0f480c26cd18b0ba97364dae78fc76c2a0a5e4879836e3a112df89f626c4b"): true, + common.HexToHash("0x46eaa11dc8531e7a5a0e56035207ec7e35029f1f2ebc567c1bdba404be117501"): true, + common.HexToHash("0xc95f9e6376afc88021a6a657d70af066e1ea3ed58f869aeb33265ae333655e84"): true, + common.HexToHash("0x87880eb35fd2b711fcd9338e1c189efbbaafbc1998bd004771add452b0c42269"): true, + common.HexToHash("0x5195f0687cc638aef74f555da1fed9b2da6e6d3d3e5ab6e765dfd93470994886"): true, + common.HexToHash("0x80811e3efb6b32739d1400180539fbfaf8c2437267472a460644b10c08c39bfe"): true, + common.HexToHash("0x94a7d08b7fd180efa21a70445dc5313ce83c185c3359260313046696e683d0b0"): true, + common.HexToHash("0x832d0274aa6d5a922a9c37b35aea6d64df330a9d0fd46fb80c21e003c8a81c1f"): true, + common.HexToHash("0x9f5310806f65b032bdd6695bf98f46f04b19fd5715f52037b112ac0967f57dca"): true, + common.HexToHash("0xf45c8e4b2716605b3806f7da6356057c13ce02f87491cde85cc2c43a45925527"): true, + common.HexToHash("0x80e68ca5abd3c1d40d3a0d5b3a711ac4266cc45aee85131efacff8535a1efcd1"): true, + common.HexToHash("0xe07d5165267093c0962004fca4717d7115c3c2ce55598286a1f4e7b95fd4f10c"): true, + common.HexToHash("0x63116b0096c21a780cad2d015838bf1fafdf95b87de51ff032694343abc7f17f"): true, + common.HexToHash("0xf01b207c3b3bf5e858a1fba79f5f630671a647846368640c374caf962921195a"): true, + common.HexToHash("0xfbdf87ef499ca933fe80ba507f18668410d3c72617bded8bab30243c2b5c9fda"): true, + common.HexToHash("0x01c4cc8f116b6fd891f021d45c358c8b2486627b4c473e71d1a5eba12eaa0d21"): true, + common.HexToHash("0xd1888dcfb6abf68f1299a62b6fcd6bda86b3281a49de41ff95ac0230913bfe69"): true, + common.HexToHash("0x1da3aa97fa3569d4772039ca5a3e440451fb7812f26eb17e258029d25f80faf7"): true, + common.HexToHash("0xcec416324fc085227dc8f42f69442a9821cfd1ea8f7846846ae4af282c5d1859"): true, + common.HexToHash("0xf2c554bd5b67accf815c540c37ba77af879f8e35965460b9491b6a456ee73b3c"): true, + common.HexToHash("0x970d7e94de908476f440d9412ea2a7c63ae3511e198f571ad909c32b90dcfab4"): true, + common.HexToHash("0x2ed09cffe2ac10504638b93a4562df28cff7bb3bb1b6b2ebe3220d917b661450"): true, + common.HexToHash("0x20672c8419ac6d6e6dd8cda33a20cf5354a3e617327f0ac73955fa8c191fc4bc"): true, + common.HexToHash("0xb9ffa0040150ef04a0e8222d3efcf0e35a2582a490ec5d68cdb3ed13db02da35"): true, + common.HexToHash("0x134b070897703f34489322c2e68b2c0e850eb002d80eecf7688c1f502b819751"): true, + common.HexToHash("0x95abd0240a404e85a5f0b26dd666762f319c5acf01591eef9adfe279b789b82d"): true, + common.HexToHash("0x1de24f6e21d71baa230d055613791ba9f755abe2b30fc95a93f58b2c2037118a"): true, + common.HexToHash("0x2b02e97c61bd87ac0341152cbe44d5e89214184c9d89eb3c895406afe7ec8c9d"): true, + common.HexToHash("0x7cb8db721ac7845d1cfa84fa86266cb817ffe52c0d45877c02271448dc33c817"): true, + common.HexToHash("0x2ce60436d4c2ad4cbd88a1253fcdd3284028198eac2e9587323d044486d536aa"): true, + common.HexToHash("0x883d1149357d3c1c992bf544ff8f6f8240e2470593eea486c3eb5297356f7195"): true, + common.HexToHash("0x29991826ccc1d78af5dacc2e515d15a7ab59a1c6e5bed9147197d2578271a3e6"): true, + common.HexToHash("0xb24f4709a82496e0a0bd478c01fbae7e585e66bbbb01969984b3af24fc07d2fe"): true, + common.HexToHash("0x7ada67b8494305f2be7200840db9f8539cf26668b7cb0375f81ab102864429d3"): true, + common.HexToHash("0xa018aaf2c1e7ec59bed8a12c9a7a8ff496be8abce1194ff8ee798945439d87e6"): true, + common.HexToHash("0xc7975a137c230c442209561623521764deef68e25ed745c0b785935b1342ed4b"): true, + common.HexToHash("0xd308303aa6f0930d3f67bb1097f5fd140af99ae76d19b01716b24c82ae7feac6"): true, + common.HexToHash("0x4a00b5a7083869853ee7285d6548fefd8f5f67d7630b223b847e2f626fc36d69"): true, + common.HexToHash("0x79ab7d16e5fd01cd6ed8cf9d6cf483f915bca95c9957e695cee33fa3b45f95b1"): true, + common.HexToHash("0x6eac2acc64916951432efd14ec9899af27d84ae4a120cb0e22524389f6e42693"): true, + common.HexToHash("0x672ddf6ce0528b0391b9a2331f105efb3b2982b300485c42a4d4cebb6114578c"): true, + common.HexToHash("0x4089e72d9259834c9e599de96f06a25baa43cbb462c1d46df94129b15989d28a"): true, + common.HexToHash("0x116cc32c2e0ad7ad0814f4ad8045593ce75a6a078e12002cdb9242db6b1ee753"): true, + common.HexToHash("0xed4a3261f7c5424c767e8e943961fb8642406c1798af0a13e09e58ca99457f1c"): true, + common.HexToHash("0xcc775e19455999c2d4019aaafb0ddb740e2c1dfcd62338854f7afab579cdac15"): true, + common.HexToHash("0xe51d09addb63e2a0e88aba12924fc2ee0ceee2b63ed21f2d47821ca2b6ee4d48"): true, + common.HexToHash("0x923d0870252f5921c1c8477c1d62bdf5cc1d27c14df2d2b36c5a621f10f8b8b9"): true, + common.HexToHash("0xdab8ca96b4decbb735d1eb07100cda7051c72ad1e2203be3a3d00451ba58de32"): true, + common.HexToHash("0x54e441bc16e7a82c92a64e2e11f914107bbfb8e22ecbe2e29c80ede3eb599936"): true, + common.HexToHash("0x684071776c0b47f6b81e3ec1eebcdef8fb6fe03d25acf8b035b3411e6e68bbbc"): true, + common.HexToHash("0x427e906eea6e111640ea110cef6a07155c3fb851a390dea4199bc0a068f0c989"): true, + common.HexToHash("0x4851c5fd76748a84af602043b14485922f229f423e41e4829f4455f3f90d8b2a"): true, + common.HexToHash("0xa0ce3f07335fdb070318d16aef492356c290c717306a5787e9f086079ce131b8"): true, + common.HexToHash("0x5dd3a30c547a4036add1085da7e284894214e2f5d3e5ad33dfe7c87a5fb8a9e2"): true, + common.HexToHash("0xfee8b92bbf30bd93299fe208cefd4f635a945a56f0e24c26088d2898138feb36"): true, + common.HexToHash("0x44a23b5e2b0847d7031db2b6f5427a2c40efc91d33132256dee2db11786efa27"): true, + common.HexToHash("0xce23d630dc554e4b9f02eae3db6674ab895b0cdf36cee3e8e46191cf2bcad080"): true, + common.HexToHash("0xe6f59e3f4a3b264c905e4812127770432a8f6f1b1b442b678404363527266aa6"): true, + common.HexToHash("0xd74a7d7c702eb97b1e10a15f97a19e6e5d0eebf223ecb383aceb504055349237"): true, + common.HexToHash("0xb6ec5d91c7836b88d0652d9da13690f80fe343148a22ff3ec118e2c6d9e7d474"): true, + common.HexToHash("0xd1f51e4b144e82579d2e1c96fe2601c21a311faf81db2aae4c878ff7eb3fbbe4"): true, + common.HexToHash("0x5c37d24e991a97c16496103ce0266b2012b9d56767a3246364ffbffa90300435"): true, + common.HexToHash("0xc31df009f313e0fe879c163fcc4d9e7f26428e83399da10ab87b7b28aaff1124"): true, + common.HexToHash("0x56ae1a7135661ca41ac83c37b9222541c197f27d06feda56614d4473bbaf79b3"): true, + common.HexToHash("0x6c20d39c5c3297b9b68fb1c25f467c87711f944d5728c64d7231cdbd3d5b0de0"): true, + common.HexToHash("0xc96c0bff2155a010d2767685cb1647963f2913124d173408b54cfe0fe0f4e31e"): true, + common.HexToHash("0x1e54013a80476ff06e0871e04149d7daa31b41cb80a6436dba99d3e13b84f773"): true, + common.HexToHash("0x8b0d5baff90cc8f4c641c5548ba25ab32e6648e21f5875ac9c732ea5d22f9a18"): true, + common.HexToHash("0x0f31ec0347d6f0e569906330d14f00db2abfd66b9417e0d09658f9578d674bfc"): true, + common.HexToHash("0x1639cc3bb9b996cc922ab8ac3ddd1413ed386d3fafe03e2a0e6077a171d319cf"): true, + common.HexToHash("0x846fe0f25325655fbefbc6c4ae645ae61bad013b7e323be6102ad3bcd81f6f69"): true, + common.HexToHash("0x44dcfbf20e872a0290e2ae7f7801850d81506c41578b40af3129de604ec81017"): true, + common.HexToHash("0xb6a9dc3cf2f4ee991bcc2a424adea81b43e32e72621ce1481975b1a9d515e89f"): true, + common.HexToHash("0xb94aac07289ac8db40593f9949d0b3c1621cade7c3da815177c4c926bbe89b3b"): true, + common.HexToHash("0x69556e2cc7eb22b1acd33c65bfcbfaecd45312f481b848da46d21a14f8e5963c"): true, + common.HexToHash("0x3f1cb83b34006442a7c004e8e8c882c77baa84073130bdc0ca3a1361d614778f"): true, + common.HexToHash("0xd37e4f5409d0d6ac7c399b8bccee7f84fd650aa5a7c29c8244fd7adea7d9d8e5"): true, + common.HexToHash("0xdea32bc8241f06a8373e400351dbdb6ef88ccde4ca0ddaef3e5e40bcb6af27c5"): true, + common.HexToHash("0xf006bc2e2537e2c37085e3a73b4074db3bb2db4a09a95fc50941978f1dc877b3"): true, + common.HexToHash("0x2088242effe64601105fac96b16b90dfca55b4228d8574a1dfd39d5e130c0f60"): true, + common.HexToHash("0xdf5685ca88a0fafc127e25d74c7a94e9e7146b00a0de0679af75f1f44305dcbc"): true, + common.HexToHash("0x66acefe8fff7fc804848be484d99d5b153285ccbaae09642b07a4bd8d693f14d"): true, + common.HexToHash("0x7947fab11099057407f91d60d393b220d49512ffda05c522b0687c053db7ac25"): true, + common.HexToHash("0x3bbb4591268f04b8c95271a6e59ee63e4aca9530f4e80d5c94108d31a91d2251"): true, + common.HexToHash("0x6bc426d9f3c6c3c6b76f2cc1c55957be9eb982a8afc31a2456d8b0e2164b33ff"): true, + common.HexToHash("0x32dfb9329bfd0723498368433a10550359bf6f5c7b0497d9a8641154d245d28d"): true, + common.HexToHash("0xc2cc6dfa5bedfa02d389c32105da0d8d41863884dbc431196954a64bc5e0ab78"): true, + common.HexToHash("0x525b49bae9ff79597199b91afd255f4cd1347c74b44815e9a919c2b8525e52b2"): true, + common.HexToHash("0x13f363ee5c0e504b429e006fc8ee7abbb5cbf57cfe1c5230c7a5f4506ce30dbe"): true, + common.HexToHash("0xc62b913b130c1d0aa94b75c022ae253f381d47e2ea228fd86cb32c92c24f9f50"): true, + common.HexToHash("0xc12becac6845fcf048d0824a3ca37c78029809d5b6cd047689cb61ede95137e2"): true, + common.HexToHash("0xbc3a81b1045705471c1007df4291a4b34d58668477ca2e082d1304c40a46601f"): true, + common.HexToHash("0xa09c7cc36fb418821674eaface2a82b66d73c180faf8799f39f6f394dc4b8e7c"): true, + common.HexToHash("0xf438fa473d9ec4f62aa9234182f2803ed5b8d8c1564cac2730d7ba921033237b"): true, + common.HexToHash("0x1244a1926c98600a9a36912422f0e6e4e14fbabd549255ac7e3e9fab7394a9fe"): true, + common.HexToHash("0x42db51a28981610206b3fd2b4281abacf10f6990ce16e4d3555ffe5285a9d8b8"): true, + common.HexToHash("0xb30d0ce4cfcd704533d0098d2c6a446418469792c506f35e50aedf62d2adc3ab"): true, + common.HexToHash("0x03a72c320cebb392c6d3f979bd8b0f5ac6cbc9d051ddeb0f69f0b993f4bd7bad"): true, + common.HexToHash("0xbc22d350abf25349741c944f5bce3bafe251385e67087863e447ff56abdd3c3f"): true, + common.HexToHash("0x17d7ae643e912930e2de09dc45280e0035cb9c89b369da56891da3f4a1c94883"): true, + common.HexToHash("0x0def6b029629b785bfd7c3be4cc472ad95e23fddb71191023915ae83ae488351"): true, + common.HexToHash("0x4f46e97e7e1ca210643808280d776883557bff5fffdd7e60707e9160165d5e0f"): true, + common.HexToHash("0xf210b314e441c6d8f5a7c24bbea9a8cb8016af32b4f47812256ff9213fd80e06"): true, + common.HexToHash("0x53b9534b87138b3bd54341d3c31dc359271db482cc1418b35e1132b70dcb2cdd"): true, + common.HexToHash("0x3f39fc6197ac3f30d4540b6d9dfb85dd28fb1de54a3e00e5b965589297dddfa0"): true, + common.HexToHash("0x95dfcba7e67824a413520200da3dbcbb948ac0ad09907699a146877f6326faf5"): true, + common.HexToHash("0x8b29bc3136e138f91246e79bf3d049153849fdd021d374aa7778751f2f215406"): true, + common.HexToHash("0xcbffef93fb9bd13e7b682cb5be03d6f269155c8c44a1a1a5e3520986ce5868f5"): true, + common.HexToHash("0x32ad07e373cb97844d5d825e38636e7c29e0264a367d2eed65b530a1efc2f415"): true, + common.HexToHash("0x973a10b52913f3c62109a39340b4db4a141a582d6714a08d674f066238ee967a"): true, + common.HexToHash("0x9882790b03f49279d31e847e108f20477c807e4ed4f0e376f646aa2510d2999e"): true, + common.HexToHash("0x3b64b24d26d0a92e3b1f3a7bbd259984438a383aa9e77ae1dae635bf30705938"): true, + common.HexToHash("0xa2b73b02e713eefd44d9e2079b5c6584bd5d7414be40c5bcef454fb691c04939"): true, + common.HexToHash("0x3c9568691188721fd07ca4c6c37f2b67a1cfd753edf26bd8374154409957ed03"): true, + common.HexToHash("0x2e6d5f944b310f49e35580689d6df4703334ede0052f4f2b493dda2dd8220654"): true, + common.HexToHash("0x209cad37f8f54df01311daec5d3d86231c2568f8e4f2c666f00e033e6e8845e2"): true, + common.HexToHash("0x014a72e73c05a6ee0e22b6b52d1e0de9004c7c642faa4d596af14cb4b23884d6"): true, + common.HexToHash("0xb431bb9ea28ea143b5493da72baad1e6da7e2f6b713b7bede856e1737b352384"): true, + common.HexToHash("0x666a5b2963a21ff1cc73e0903c097f8cb895fd6a912eef89597ef147320607cf"): true, + common.HexToHash("0x1e6d2137b2c816993343e5e5a7ce0423cc11d6452fd85933a2662376a66790b4"): true, + common.HexToHash("0xa93a7713e0efd98544ae2a8fbd3322277f9ba282e1be2a3680deb18f6329a742"): true, + common.HexToHash("0x4309a4b949343dab725d71c201130cc16f52c825cf9181407d64e9c5612b9048"): true, + common.HexToHash("0xc69d6b0e9d5509b4f3dfa4921caf7456a1a9e9e35ce47f82cd4aa41f47d19531"): true, + common.HexToHash("0x265984c1ec353b013c9d9b73e3bd1f6cf725a3e0d63e258947143d408fb3c7f0"): true, + common.HexToHash("0x07dd24042c9d522fcef47ba5ea99d93360d02eb91a3fb516eb20fe3d003bfa56"): true, + common.HexToHash("0xe4eac1fc3874b4b45429e2ea2be35102a18c6327c6feae83ca6868630e021022"): true, + common.HexToHash("0x4a326cefae1df7e9a79ee2827b59388324113bbbb86b77f30c91cc8b2359e745"): true, + common.HexToHash("0xb0f05ceb482eaf5a67431bdd1e6b3cb8a04dffd773229309ba2dbd73ad5c6746"): true, + common.HexToHash("0x1199a00d58131e940968bb1aba4a11475d045f6403d101b6d6f5baff471c3a5f"): true, + common.HexToHash("0xbb46c5ab59858971dbe0e7e06f79756336bae90afbe076d18615a91e9826a742"): true, + common.HexToHash("0x0320efb787e3680fc8f007e32d0b582ecc1c0bfd73bfc8aef47b8c75d8b8276f"): true, + common.HexToHash("0x298eda0cc6580e85c61b15736925607c96a621cc772c91f742d86552f1dde776"): true, + common.HexToHash("0x39bce8eb56ec09c7859e5176b436de537ff8736c632ab0836586aa9da4e39d94"): true, + common.HexToHash("0x92fec70924fe504c82693790769737c1a73c40c873a078050c040f8bf6217ad2"): true, + common.HexToHash("0xe2416a9ac7db59459e73dff20b3ce313475070812d4a9d50451a20436a66073d"): true, + common.HexToHash("0xde8c215b6cf4aa474937d4456bfb1bdf1db18d7976a4cdf994759425ad519cba"): true, + common.HexToHash("0x847b5e4719a36aa1a859dd9946f320106d772d5b955cd9ad536d65280413d80f"): true, + common.HexToHash("0x35752f8e4a2e2c6ca0cec9f33e36b5025f259b0fc0fd43fc92ea877e56dd4205"): true, + common.HexToHash("0x680db918cc1a3612646846d0745fe6bc9fe145e07a574660cfc6fd1df3974ac8"): true, + common.HexToHash("0x6057faf4320bb7a8685a492dc0f7e4344c55cecc1284d6a7e7bc92a3f1c96f53"): true, + common.HexToHash("0x88aa956518df43ccd69a90533a3bb631d014bc69ec6c9a47c9d295f5fa1549ee"): true, + common.HexToHash("0x9f262ae6c2e8996c960c8c4f781873b268a2a57cb4f2d81434f884039274dc99"): true, + common.HexToHash("0xdd6cf02c52bc25caaf57d3d31a83b4dbe5656078474eec949bcd8e1a51def041"): true, + common.HexToHash("0x37066e8f2ea0637e473d39907410e8f7ae25a844202ab4ef4da1debc3647f002"): true, + common.HexToHash("0xe07901c8ada6adb503a77a33e327a70e994ffaa91fa3ebb75b35586d0504acd0"): true, + common.HexToHash("0x0dcef4b8e64d7cf47e3606d5fe0bf473d603891f82f256db6e283e51e53677d9"): true, + common.HexToHash("0x6f61caad9ecd2cba2a75aa5e56f9bd36c5e282ef6e34f6fea366c1692f6ee07a"): true, + common.HexToHash("0xdda67656bec695dfa558339daa1a1841541abe6b256857c24ba5875e242082b9"): true, + common.HexToHash("0x755275b78a2b43f1f8f721a7091e761b88047946e8f77f70066fc85a0cab9e85"): true, + common.HexToHash("0xe7da87d3a387e6053b2c08b2cbef29ff4eee2abda7af23c898336bf362f6a471"): true, + common.HexToHash("0xc07ae78c0f8c232a0eb3525186f6302c960725a3a79f10c126f6965e82ad866c"): true, + common.HexToHash("0x45164e9423a735eaeeb317a87e0a440bda2d6e03e8ee34860ebabceedb904d55"): true, + common.HexToHash("0x24c84aaa66a5681f996d8225a1b7832dd9fd02544bb4541cf023d1d5b4abdddb"): true, + common.HexToHash("0xa92f1fcb9503b745484b46f8fa29aa23407cbdee138e14dd60886b166a2a9e96"): true, + common.HexToHash("0x0ee6e934654f0fe8a39d66dd0c0dd36b6927f58d58d31e84d446b9c90e94a5d9"): true, + common.HexToHash("0xe4654835ff9055e842d235d96a1b56de31ed901afe6928e84748cca4c0f2d274"): true, + common.HexToHash("0xd111d3d2e68b96a1e34f767bff47c81d54b3a559bb650f58d82150d40c1e6f99"): true, + common.HexToHash("0x9a499492b7dd4f556f2677415f2c0b737437bcaaa09219be91d97fb961895cd7"): true, + common.HexToHash("0x8f86457d64313ba74ec9e7bcf63739d93359f8ba4eb395d83086d38a1787ed46"): true, + common.HexToHash("0x699745a107bc6a9432d8ae3f4442219008344c611d9e06062d4201e043094e5c"): true, + common.HexToHash("0xff4a1bb18a9717b3cc6014e4d0071793d2c0a84d634da17036cec08780c559f9"): true, + common.HexToHash("0xb6dd08d7c7e1ef34fffd705c637a9fbbb0774b2d18435a4c32915893a484f4b3"): true, + common.HexToHash("0xd5d0a27a757df57e91c97213e21101c43f1d7c1e95960c6fcd25241454720664"): true, + common.HexToHash("0xc44f6e248be89d3380f820c9f3dfddd02c76a145e69cd20d127e9d2367669163"): true, + common.HexToHash("0xb2b811fd7579f7d4f89e7ef622efac3234bea23d4ca69526c7db21fddff0e867"): true, + common.HexToHash("0x051cb3d15fbda4d2e4c724a66cf48788b192f97ae90cc5291a1d34f90d5591dc"): true, + common.HexToHash("0x28afee82cfc260c5ab4ef2b450c61fb2d57eacd01451f61dfde6582a8ccc5e5e"): true, + common.HexToHash("0xdd60883edbf6e0e73ef84dbf273cd9a88403f0a44362977a72e8cce88b0840f8"): true, + common.HexToHash("0xe10047463d3bdb9da4585338cc7ce06a970f8d4cd84884f0a8545fd84c2ae598"): true, + common.HexToHash("0x5cc8fbd5600deedb2f08f9d5ad6ae40b1a1751f3ab1c58d2e18faaf7c82139dc"): true, + common.HexToHash("0x9e71f0fd097afaa4210a82ee7980c993f906050a0b85eba93f8a4d6530894b97"): true, + common.HexToHash("0x9434604b45cd588153949b3df50832b1092a4f5e4b7a5d57af8b1b616cc6550d"): true, + common.HexToHash("0xcfd5c37f6b05227d11afb620439564f3c4c8b01db7387006c49a1289e8509953"): true, + common.HexToHash("0x149a887d9646bea218af8e17dc5c09086207b9b4208b189ae74b669f8d05df5d"): true, + common.HexToHash("0x484c55f303cd4f3fa06ca8897d81fae41bfb992412533414c7a107b16bd7e51e"): true, + common.HexToHash("0xf74e38505bc93b43c81be1766d8ac183ca6ecff7b6a7d68119e70817811c0d76"): true, + common.HexToHash("0x4c013c6fccea1b9894bd7d3160a704411d1c18006b6625d7d9cd093de68f3fe7"): true, + common.HexToHash("0x581203f055797a41161435c28edf5acf42615e95f6c2cce8ccaa2f2eda108488"): true, + common.HexToHash("0xc94ca904267ed84d0975ee5409f724ccf2e927976dfd82902760594dc1e0ce26"): true, + common.HexToHash("0x10866420f7b62ab8a5ff083b559ee5427838c64fd4d320c0ec5f8621fe1ddc58"): true, + common.HexToHash("0x263abf8b830964349467b9ada8ec9650c4170d6ad12dd75a33206738226bc9eb"): true, + common.HexToHash("0xa3a5a003fa0b7d73b0ca4beb27315714b9a15edcdeeca6eb99ca63746686a6a4"): true, + common.HexToHash("0x030bf5622001f53dd1f826eaee8c43a9a952c00d8d5bcaeab2d09df5c129d94a"): true, + common.HexToHash("0x7c8448100c2c8fde15a0eea0fb11a04d997a696b03b916dba92663e17ce7aa27"): true, + common.HexToHash("0x79a89c7417298879c18ba78b5fcbf424455f29d99153e9e996c37b09e7233ed9"): true, + common.HexToHash("0x437383fc89c04f96f1de85f838f0a34c3495a4bbbcfd95c3a2e10ceaca3f752a"): true, + common.HexToHash("0xee19470012b7890abc519d7b9b9351557388abbcd0a132d50d8f7774b30076ce"): true, + common.HexToHash("0xaf8dcec896e9c7d32f7892e9f26fb7c8f26dcb95c4c0007fcc7837f8f39660c3"): true, + common.HexToHash("0x7c53977b78f33d78e7d0317fbe42219b1d43d58237547bc55701a8d508a536e9"): true, + common.HexToHash("0xbe44f66ceea068c96f30bca5b17ac0dbd3811aed294c164568d582884ae187cf"): true, + common.HexToHash("0x736edd758b635e77b5d8a358a30695565dd80e547b6bef270f4717fb5d67c8af"): true, + common.HexToHash("0x0bff7c182c3df7921a64eeb032c9b90be80fb0c1ccfe4a8850741ce1e6e532de"): true, + common.HexToHash("0xcd8f74f70db25ee865f6d0714713de3e16be0300ad3208b01d5ae872ef3202aa"): true, + common.HexToHash("0x793fbaa19822ee0b21b0aa73f4f1fb3a1077928da401745b627f4b6ed1df646c"): true, + common.HexToHash("0xddd5325c2b5050d239eb660048b6937b19951019703246f3c84b4655ec34a21c"): true, + common.HexToHash("0xf7faad54740015d74b8dca5a357d411f75c5e3061fe90e547239f2de13037edf"): true, + common.HexToHash("0x038f2375cd971018422131f74061a776820bb00f1472ddd76301d345c407c19c"): true, + common.HexToHash("0x1a438e3fa593cb105a98d831a968ad072ab7a68f3117dbbadc6f0f2fd230a097"): true, + common.HexToHash("0xab847d0de5d866c3946b4b0340c64bcebbc1cb96528fd89a9b713b4a9e07eefb"): true, + common.HexToHash("0xe980aff25ef53a9447e7e9cded1932d74996b1c194f3756266d83ec11fa4b8df"): true, + common.HexToHash("0x0836ab2da7f2fdd79cacb744922023ec7b3d2c7c6d1b1be0562d8a2d651be53d"): true, + common.HexToHash("0xf3591d1e6cf16a8121a86b3f30f81f452fb5d0790c3f3b197abf6d8bb754bb89"): true, + common.HexToHash("0xa52a3f7d4a8107616f93e1eca2fd2fae069e54866fa3d78eb9c5db21deef1faa"): true, + common.HexToHash("0xf8ea402d8625894db2fd3980b1989ba3be01794f713e0a95eedf005c6c25a69a"): true, + common.HexToHash("0xeb132a150172ef420fb043f0b2ea296e276efc897bf83cd36ddac8be6937ece4"): true, + common.HexToHash("0xca6c49093fec53463ef62487733060b5ed68fb7dcf54e5bf1c5737da9ad09ccd"): true, + common.HexToHash("0x566daffd55401002a7d85cb176f28273df661e0b7fe61328ba44cd3fb30e01d8"): true, + common.HexToHash("0xe9bd3553375e4604a8fe3511e09a824ebfed7ecad2d42d59c6134e45f5b83130"): true, + common.HexToHash("0x117fccfdcb98160bd8f5edfef51a155b9d43b6bfda070461dc8b4dec17fe928b"): true, + common.HexToHash("0xfd559ee683496a0e15a26d2f6ad69de902c04c5b88b32448397321a463145f92"): true, + common.HexToHash("0x32b6a76917d0cd13e64a2b74f45df87bec5f0fbba9a83371d3e04093a310931a"): true, + common.HexToHash("0x563ce028233fc8837227ede889e0f0764fc76a7881a9c350e77222c16e741991"): true, + common.HexToHash("0x02cea56b990d5e321484ccf587472725ff8996a149a81bab8c447ceb7cf21d9f"): true, + common.HexToHash("0x3f31f4924744ad77852eee0219d55f0fa7adf4bdd7683a82817c32da4c6e095b"): true, + common.HexToHash("0x9ed6a0f1d88f1b4dfb912befa43ea9d6b7b1713e813b049c238f8821c76f2370"): true, + common.HexToHash("0x3008a40de3b2a323f993414f7226c0e85d1050e9abb78442cf2aaba205b92ab6"): true, + common.HexToHash("0x433092414f0c6cc989e5e2723e6ba039e0bc9b71046adf408e0e6d8f26377853"): true, + common.HexToHash("0x6d9a7c36d41fe290bd4474f1f4d73d36a71f96cf6bae049c7f91c498ff5ea3b7"): true, + common.HexToHash("0xb731b2e80ef95d33a22d28f7a182dbf7f7a470a627b235c2d47938a15f1d7b78"): true, + common.HexToHash("0x02ca3349b81aa63da0dac9f190cb405d67593600c661ae1e8ea6371ae90b6327"): true, + common.HexToHash("0x777afc6688d3ed8e80de00dd1bd03bddb68a29e511aa645ab8728fcba3fbf322"): true, + common.HexToHash("0x45ee04ce585d7ac622adf39e148c997864358a11ea58e027957aa43ed27a3688"): true, + common.HexToHash("0x92404f68c56ec9ffa69a4d4375102d073fe775eb481f686349d6bb96c4c7e390"): true, + common.HexToHash("0xa0b797e50b7250f66b962de1f7f21a21625fb8ba5f8e61b997e28c22ab53ce37"): true, + common.HexToHash("0x13550dcf297a3b29b828738c38cfb1c925924d03f887dff09b1777e860d834a7"): true, + common.HexToHash("0x492d2feefd537abc29c47e8b3bfb3b8184dd6044320e21353e8a57260ad016b7"): true, + common.HexToHash("0x639bca5e52bbd649376eff22b76f50058f1c543fb041637d764d175dbdaa4bae"): true, + common.HexToHash("0x9fe217565287bbb56c7fc223605fa65f6763b32cf861d4e76cf4a2d5545d1649"): true, + common.HexToHash("0x8f27a766b67dd0f12ccb12c15d1c5ee643068b6bd33387bc67a518de7c856f3a"): true, + common.HexToHash("0xe378d15870a4fcd5e8c3c37838c753c1d753888d1c8b87362df83e2bcaa273d0"): true, + common.HexToHash("0x461308079c91e6ab0a567e215dc4c62e3d9b4f97a06a41ac7b410a807f7b4a08"): true, + common.HexToHash("0x96f54eb76117ba7ead3e33cb5ff0751aebc7aeaa251af0e9dcdc38b8e5068a75"): true, + common.HexToHash("0x327aeb2e4024a5831b2fc0e021033e1ee36b6aa80a948272b2b205afbf47982c"): true, + common.HexToHash("0x8b3ad9bdef576b916516c7f7e9477fc72d67b659694118ceff2fc22d5345d427"): true, + common.HexToHash("0xd7b17dc25af0b65a2f638d4ab1e070005b59ed2ee863b70ea29252271486025b"): true, + common.HexToHash("0x56195e570c3aedebe2c88fd99e73ccdee3c1bf2201f5e91de7c8604d7c148691"): true, + common.HexToHash("0x629834705bddfcae699defcfd23e09eac6a90123caf7025a766552771bf6321b"): true, + common.HexToHash("0x566fcf355fbdcd908c25ed630fff68efa686861093c618a22ff125d41f068b22"): true, + common.HexToHash("0x2b1f6097c14aa302a31eee47977bf25d503d5429a4cfc71702ee66041f439a94"): true, + common.HexToHash("0x5a8058423e57b4a1170f0f208ed7ea52c5e396452baaccd564f13581c831389f"): true, + common.HexToHash("0x0083618aa0382e445cd4aac55ff37c42de9c8e08e5c9d1ac18084ee08e869916"): true, + common.HexToHash("0x5389311a4cc61899165eefeee4f16c9b1dbef5bff97e964accf40b34a7fb934f"): true, + common.HexToHash("0xfd87b8fe79b79fd27eb03ada4de3eac0ddf1e645e8e4230d20c31db048cb3604"): true, + common.HexToHash("0x853d26e63ca2d762b38ce33f76558b6d7f425b74f840b33163042bcb7d70db49"): true, + common.HexToHash("0xbe7245b323ed213c9f19c686549fea683afb971011984b2679b49512c5001ece"): true, + common.HexToHash("0x133b9844dd3cba9811d5630f088e92797c9fb800bc978f7d9258f887fcdf1b1c"): true, + common.HexToHash("0x9d6a069f2180238c7c39257b2e50a90805bf6255a7157a90191a6364e2a40e18"): true, + common.HexToHash("0x82af2b9c4c085f3e1984748618669e0d7c43888a4ab9be7150142ce3900d8ed3"): true, + common.HexToHash("0x85da051da407fb417d6b83e67ba45afad408016644e585e89825997975f9b49f"): true, + common.HexToHash("0x01049a6490dcbda4726f7460d46e6b42ac6e54ff73ecd5021310c6167dbb5b67"): true, + common.HexToHash("0x1975803a06a6ec19a81f65f1299ae2ca7f200a92c7539ddef548cbf0b0eb6684"): true, + common.HexToHash("0x335a753bfbff39a61f1ffd114fe546de44b999cb4db96ae44d870a53ff9e32e6"): true, + common.HexToHash("0x5571c656810ba4107987fe16004c13b479816287e1fdfd9cff0e1f2a4cd6f357"): true, + common.HexToHash("0x05f12bffbd02619d106edb36815590207777523050f4905c4ada0198bbf5f636"): true, + common.HexToHash("0x68e88f15d5cf1c1b045b6d2c1dbcbe834262e26ff0472476e53b1f8cf0ad7ea2"): true, + common.HexToHash("0x879c726c1a0f8283895a25099c3eb353e11b1f2771e50dcb9652c95004644a4e"): true, + common.HexToHash("0xfaa7b04ae07fc743fd56f4dacd2d1b0610576b138bbcd291d5523eb3dd87f5e6"): true, + common.HexToHash("0xd1a5fb0ac113c0487d1d293c790df66358a3b028c8d615003ffcc79ce734067a"): true, + common.HexToHash("0xec142b6b076669e971c46dc6c507379b9dcdba022d2d64a72e1c7c43c7439c83"): true, + common.HexToHash("0x0969915f17bcb6db53e9ee21c5c88d85037a0838490c767e8ba219d9be41e6da"): true, + common.HexToHash("0x40d21c37c0813ae2d15d4ccde7cab6603befc8e80ba4b8ad2f44a3bb8e6e2368"): true, + common.HexToHash("0xf1640ae1ff1262e475ad22e5779b76a44306dc3fe753e48059bccb502dbed157"): true, + common.HexToHash("0xa15b9e5ce74578d6cf19174763c01463d34f489245f4408db128c5c6bd1a5d30"): true, + common.HexToHash("0xa1b2ea48f13e837247292cf188fb1547112bd35b4dbd8b5bc5ce4ffd9a0e55d1"): true, + common.HexToHash("0x8307af65eb86517d5f0cfdd824e9b013e863ed380e709d7ac78c2fd055b6ccf9"): true, + common.HexToHash("0x4f13bc51ca32e65778a2a8fd13b47e18cc5de792f66604ec8f36fb674fd08f2a"): true, + common.HexToHash("0x6ff8ccdfcfad0593edaa01fa4af937e854e384648632602e6504dc6b0a5817ae"): true, + common.HexToHash("0x599cd48ee0f9490b87848b53253699e2a22b59105d28c6e15b8a88452fad3db9"): true, + common.HexToHash("0xd79406371a3af3490a74bf91f39305066ca54b1f0af72fc2e4c0d9f42ab80032"): true, + common.HexToHash("0x81c35c89eb263945d946cd800f160be7ca87509eb08ea7fa101a298ee9250ffb"): true, + common.HexToHash("0x9f4bfe8cce2cd1ff058bec27a9fe1d6d3d524b71a3e9855d1aeb4b76c2dc761e"): true, + common.HexToHash("0x2de7098750d5e68dddf456b28c77fe81f4ce352751499618c242d13507c6d81c"): true, + common.HexToHash("0xe9141bc238028e01070cede1c289914853c4efe807aafdda582e1f05182f58cc"): true, + common.HexToHash("0xd93c0a7708c682610cbd31c6adce911f1f1fee542a1b1c45f6e54bb9546468fd"): true, + common.HexToHash("0xac976aef7a31e39a3f6b3225e181e79ea19a98a81464804f1a2d79672e25c9ee"): true, + common.HexToHash("0xb8fb017c8640c3efd329786de14334e5603a5e243ef7eaa452f7fb8aa62e2df5"): true, + common.HexToHash("0xbc8450fec1e069166cc2c07ec3f9facb55576b30b680887d9a4b2f12ad6b2c7d"): true, + common.HexToHash("0xdd14ff5344a0a5cb0d94942359a9531dc2dc3e976f86aa490ae3a0ff9b788b62"): true, + common.HexToHash("0xd5988fac07c59e23dfc8ae083aa82415125f244cae6e73ea0895ba07564d7b77"): true, + common.HexToHash("0xa2819419a04322f645a839b759d8da62aa37e0f31727031b44b5436ca899e330"): true, + common.HexToHash("0x5549c6d90a684d3684ac287c95b0126e865f54d20707ddaba951f72133a785b1"): true, + common.HexToHash("0x29fa2c4752ff57eef7cce72324159fef963f21c016486cccaa4c8ec952569f51"): true, + common.HexToHash("0xe4d5d7467172bd3d94112dbde20f8ebd0636da490fbb1c5bcca851a59cf1fc4d"): true, + common.HexToHash("0x449665d8c7355f491b9585e45728bf1a9e6e3af9b38d2b6665be41a1d51c320b"): true, + common.HexToHash("0xa6d6408e27e0df31ba618706417384352b4df4bfa8d16ea3d491306cd877ecd6"): true, + common.HexToHash("0xaaa02609e08623639b395f47845d7841267347cd811f160a8135a97218b1e423"): true, + common.HexToHash("0xf1c9872eb167722c5595adbf2243290fd050300e17b01d4dece2670f56a05603"): true, + common.HexToHash("0x35beab3fedd5afbc73d3b206caf47c5808b3f5dc1db8f33df51eceffd0fe1a2d"): true, + common.HexToHash("0xe185791a8c58ff88ef7c1c490b3d6f2561cd3b6b2516236797fedd7084041a16"): true, + common.HexToHash("0xb1caabc6fa200ac0c7efe397b743f191e5914688acb8e6c133ea75dda9f28d97"): true, + common.HexToHash("0xaf53562f96c07a2765783511c75bb4966fded812c0c1c962087f2b60c3ae9489"): true, + common.HexToHash("0xc14421f0ce0d2b16f37fba43dc08454833fbe5d090ba6cf8bb33cea7eef84445"): true, + common.HexToHash("0xa83693cd2467d76aa861f02055a680b36a585bf25f673b95710f0f7202faf76a"): true, + common.HexToHash("0xa41260e2f28d8562a3ded3a60f3d404440c94e666d2745fb8d6ac7df00ca5773"): true, + common.HexToHash("0x20e3764b9b1efa39663657dd436bc4989ac723374b926e55342881b28cb770ab"): true, + common.HexToHash("0x17cacf4b3091a125eb6a26b4131c1db7ba96f1bc66418b3eb9eb123aad8b62f8"): true, + common.HexToHash("0x65125d5fbdb278187dd507668a62c749f331fa2e208d539b8db0d09af23f1caa"): true, + common.HexToHash("0x18869916adf8a0440732ca1a2a1ae7f037c922633328918c21557574c9b4bc3f"): true, + common.HexToHash("0x0161b484ac21988219da40e0468bf5b8cfcd6890a5eea2b15163d3c752a68d73"): true, + common.HexToHash("0x01ea23585f6a99d04740c9c4d18a0d64209b59f5b47e52382f7b7b8981a6f5f1"): true, + common.HexToHash("0xae26b49adebe48a95f2ff29993eba4b3bd3c4cf1886d8fa6efdc07c375ec5ac2"): true, + common.HexToHash("0x288f29fd63266e3d9309a645b0ddbbb04933cee5e1b645177d534dc628e3bc34"): true, + common.HexToHash("0x8f0f136b8eec7e6a661e16fbfc1a21b88a65c36f833354eeca079781497f0ac5"): true, + common.HexToHash("0x3177f4a53abe5ddffea60c4b296772368776fd3fa08c520b02b5c9b3a2a88366"): true, + common.HexToHash("0xd01a0341b5206762a5bc732eed5ac462849cb98da682b08ee43e976cf927fe80"): true, + common.HexToHash("0xefc4aa743f4c9d4faa38e7d3eb499107497b9635ec5427d1165bc8b8e40dcd55"): true, + common.HexToHash("0x5975cd087358978876a80b70cc45b70c0c1df033fe180725fb830116b13c88c0"): true, + common.HexToHash("0xfb6fb708c7ad7d3a3438a6385bb86e0712abf9da7e2fa0aab9519a2705bd843c"): true, + common.HexToHash("0x00ff9273f8e4785138d83b1ca0b6b7e20f35965c8754b42cfc98dea57396d9a5"): true, + common.HexToHash("0x6438a7e521c640e4c4cd600e4934f7069678bc38a9eaaa2cda605c4281207265"): true, + common.HexToHash("0x7c1c0d23c9113380c7e440e5c8a12854b1006903f7ff47c09e7636a784877fc5"): true, + common.HexToHash("0xc6811b751f7e3237399f07b72e6d762539ac3c25e6067ddb0bab177ab712fd6b"): true, + common.HexToHash("0x32eb35ce313662bba0688b322acdaaa5551f59a068ffc0f4dcfc8a6f5afe63ec"): true, + common.HexToHash("0x241d966577ff9b8ed85f4d1a897ed8ea7df31cb601405684e05757b78b0cca48"): true, + common.HexToHash("0xfb868f0f15b4f7c26f9b0c6d29ed42adeb1da9778f5d37f59fbbac7414aabae5"): true, + common.HexToHash("0x4d257c9f76dd7d72091bd0ded9e16039dbbf8f33f95de960332e1defd7579b53"): true, + common.HexToHash("0xb2eb882795ff4d5118a8a4bb7e151dddd912bea6687b15e35952545744b916d5"): true, + common.HexToHash("0xa1bd761580d2a629136789d1ccefb33a77d2b53bb36a147a7b613c4a6d3ec6e4"): true, + common.HexToHash("0xd508e231521c4b7dc3d066d88708f0c8e82dce2da2c6cd8c488916bacd69b42c"): true, + common.HexToHash("0x7c2b24c26bb8da984a8c9ed509c461fb3da0579be5701cee9315f78e8dd1cf1e"): true, + common.HexToHash("0xe978ad5718d88a4d7ec858b7f7a411697bccd99e8c73d505864f15d2132516ff"): true, + common.HexToHash("0x048a2d29a350a1d6ebc1be07d4e940b6a737eaa2574aa5260c21ffec54df0b23"): true, + common.HexToHash("0x0bcae4772e9cab25b257376f434ee694c0582b9dfc59e52e5f77a23aef47dfd1"): true, + common.HexToHash("0xd15b096e2479237fcb124f370163f0222393d1af072f0cb9d7bdf22e2db5e137"): true, + common.HexToHash("0x0c7da14157da6eadeadc53203a11ae668ddf4667483f3a458faa5ddd561cffc4"): true, + common.HexToHash("0x25a22b8d552da9a46221b0a62695491ce9c5e67c98f4a6acefbba7e931c46402"): true, + common.HexToHash("0x76b73a5b8b40e3021e82fd1dfe008d8742d18be296b42e8cd8068888231842cf"): true, + common.HexToHash("0xc9496e1248b2c709b0f13c67c17e4c7c2f3ed2e6c922a80ef3478637f7fcf8ff"): true, + common.HexToHash("0xaa7d3f023a831db1230bbeeed43d695e817a80e6775464ac6be17b40eb0008f9"): true, + common.HexToHash("0xf357d0bc3bd16260e4739a45a18580be247bdaaa78deff4eebeac3b08e323781"): true, + common.HexToHash("0x01a51ae4012bb7a306c0b4eec3cf7047209919d9fb048f59bc0810d1a6f5bba7"): true, + common.HexToHash("0x497c186f7356097d644435d30d941ce9f5ac8df06b27c8a866c3e8a9b66a0438"): true, + common.HexToHash("0xee83cb37efa7507d45a5ea916c34a9df7551755751980701974fd73b5174c59c"): true, + common.HexToHash("0xf91eec7f682d437a1196d7e54e4a76485c0dfd94a16af49cd7633ee7432278bc"): true, + common.HexToHash("0x5cbe04177616f91ac85dd9f8b9d219f594e21d1f180486d29d6c0b7691a388f7"): true, + common.HexToHash("0x74d84bd79f7b82e4d1d84a00d0d9b2c2e2ec0ad94e833613587a1eafbc6c87ec"): true, + common.HexToHash("0x8e6965d50c964e6cef5cac053b3a933e1209bbd43b47b9c1b5387c7032e0f89f"): true, + common.HexToHash("0xf8da5e4f73f88e06f3dcbee768f217217a28938f67e0aff2395820ff867fd523"): true, + common.HexToHash("0x00b799c2e15047173afab10c57b30fe5b4997ae6381dfbb49b4c14b84cdf97e5"): true, + common.HexToHash("0x20e4bab6b32760cff4216d551879ef827cd4bb9f87a53d382cbac8b3cb8df1b7"): true, + common.HexToHash("0x84f148ffb11f0e8e06ff6368272cf01ee6fc5d42a1f3720f6f2421840fa97353"): true, + common.HexToHash("0xda084343d3e4279be7e455e3902331a12133b8eea08b94a9daf332fbfd5ec66e"): true, + common.HexToHash("0xa8a67697e5bdd12010c16d14c047026d61c4bc41b3ad2785f7d0212d05f10756"): true, + common.HexToHash("0xf8ca0e50647e5ae63b491dce8cca5be9ecf308d43074ca020f733d6667009a20"): true, + common.HexToHash("0xe9ceb8abafbbc42ed1e9cb83a193d41429c34d5d9f238911aaab61ca01c5e122"): true, + common.HexToHash("0x6449f8cfb52dfc4747989d147fab745fc97d0616913379e8f84f63e93cf4a314"): true, + common.HexToHash("0x4e51217aa1b5f76c59303a68c2fd2f3db8bc6e7bf3373096cbbd6f3345ad4b07"): true, + common.HexToHash("0xe42d74aabe14afea3221672a4ff9c7216c15ad7c35cc96ad409990460120e518"): true, + common.HexToHash("0xde11728284c5b589a49f77ff2a13e54ec51113955ba8a8a9a94fcac06091705f"): true, + common.HexToHash("0x46bd4e8f6e3cf471853152e27118cb6dc874a064b7623561528d067aaa565199"): true, + common.HexToHash("0x2223e9883685bbf69790170ed94014bccd456d081db04ce2f5583e93f6e78139"): true, + common.HexToHash("0x94ed7e1afef10ac0cb5ac8fd548fe5dbe014590c5f073e4b169f57584495e026"): true, + common.HexToHash("0xbeb3cb05f771f0112e8167f9db996465c5b99817dad8f4df1de4326178a24f96"): true, + common.HexToHash("0x225ed703d723e1c1903bca8787417125594991f801114e8dab699ec862b0d1fb"): true, + common.HexToHash("0xf8e268fddc5c55c1e436e5a4fc4e295757c84b74b953d217a05baadf12011c46"): true, + common.HexToHash("0xe53ae12954425bc8fd1364279e2d17fed2d5a674ce466baf44ae33931bf0a67c"): true, + common.HexToHash("0x6d72da9f5a07ed5b0768b0eb86052919735746a7a0f7445848f470435d2c6bf5"): true, + common.HexToHash("0x7e5cacfad0fd08125a75ae002d86289ea65895a7f5f863656ef70c3b5dd6329b"): true, + common.HexToHash("0xd0bd24f1f45f702fca509bdeb4b0867c9051f75e0cd594ae36de4dca071e9489"): true, + common.HexToHash("0xfd8efbb69d27b29876cf5cbaffed3e2eccf2ad94f9b897cc5d7ed3f86700f20e"): true, + common.HexToHash("0x1374008b7f979ffdeef9697f11339b75d27dc16a4e2622b2dc51fece2065e869"): true, + common.HexToHash("0x1815a298fca8e83484a5875e9b162f413f264834d9b26c7396e13d25ef82c453"): true, + common.HexToHash("0x040cb987adce206e98d70ff503996497ad019c7a74408b8708bdc02c768dd906"): true, + common.HexToHash("0x3027ab0259109b6bcd4a598beca35fb9000588a7991c12b0e4066cf2c9401c27"): true, + common.HexToHash("0x98bff82cbbde07a61689c86c98e72e755785caf8a1df457ec7717555a9c32c77"): true, + common.HexToHash("0x655a5940a2d48495d83b30a4ef0a21ca772b7aaad27762487a3cd0dea5b6044e"): true, + common.HexToHash("0xa83c157ddb59b86c9dbfaae6dd2d8c7bafddb132250e61fb70406615f3736ac3"): true, + common.HexToHash("0x60fad3882cab845d5e8d22f0d718a98c79aeba7933d12d3583044330d6120f38"): true, + common.HexToHash("0x2db2970b82a1c20aaecd44c9f6d116c66b91730eaab4841732e0a4b610d655cd"): true, + common.HexToHash("0x7b7ee6ee2c05547c9b5c9b041c9b1bd2df1ffb4aa1079a87faca71ccabae291f"): true, + common.HexToHash("0x07408d5e6300435f37f6810e785a641b7752ac84460fed08fb524d6955687bf1"): true, + common.HexToHash("0xa25a9f1a4c86322bff972f9cd3f1f4b6e5fd1394f11263ea59da5d4c1ddffc7c"): true, + common.HexToHash("0x8380979281976e598d97ed38cb5aaf37728424feb3fe50b652498eb4358e98fc"): true, + common.HexToHash("0x13f123c65a5ca9d20e08a123b94da728b4bab3bb159b4b019e3f88e5a73f990d"): true, + common.HexToHash("0x970cba4f07a5562d82cb0cfeaedd5ba9afa66442814267fbc569a3f954e0ebaa"): true, + common.HexToHash("0x8feb863c06ed0f340811b006e457f508cc91ce3ea9106704de7dd36619871cad"): true, + common.HexToHash("0x6ed9d02a9192f9574172b6c6ca37f3cf0e09e9d0d300e3a0af4d02988de5fbc7"): true, + common.HexToHash("0x05e2ad96d844bb1c88d470005b8ad28ce974d42fc5d2247c19b46fd7ad269c4b"): true, + common.HexToHash("0x2f14143ac539e66cf60b68e5b76051e9f7a59a9fd7049712774a7b86467540f9"): true, + common.HexToHash("0x4e4163c94cefc2dae5d408c42e36a0fbafcf8df69028cedf6c465063eeae8f84"): true, + common.HexToHash("0x37964973e3f1527b1d5b51ea7218ae0d0bc9512094bbf12a9ac48fac400f2cab"): true, + common.HexToHash("0x2b9ed5a49c2e127504c2bc96d35f241d0cfd04cb7afbaca44d144a7bcb7d1155"): true, + common.HexToHash("0x8518ccc77171df03cd2e2772d41e555adbaa7379296b59321ddb6affce976a3c"): true, + common.HexToHash("0x2fcb42536425cb940a4d19b3556ae6310a5f56a9658ed54b27f61d4df5648384"): true, + common.HexToHash("0x2696acd672b6a589323963a10952304bd2e7b53819ddbb073f158b03004f5384"): true, + common.HexToHash("0xfb5ef3b4a417115a5af2827dd401eef848898bd93abc4b2a7ebd7835aa9af922"): true, + common.HexToHash("0x1f4cb23ca499fb1dac0b56f657688953a8ffc77c59f6c6ba4387e1030cce2d13"): true, + common.HexToHash("0x6d45ed4ab2506d01d847f4874e5e6886c4510022e46764159b5613e146667bab"): true, + common.HexToHash("0x9c9dfd50acf375048d36b6fa7f56d3639012feb7eba910ab0ce98844932db5da"): true, + common.HexToHash("0x81f64ba040fd453ac8f45fe8d880e834a2a4aea7a1f51e19a8a4dd72fc559fe4"): true, + common.HexToHash("0x5e2ac859b62dace72fe31ec64134b9aea68567ef2cbfaab5fef844c8ab24b665"): true, + common.HexToHash("0xa63fc0be485a9327e7038cd67698d122373f4d8d586f8cd041df2f7e0b120e92"): true, + common.HexToHash("0x602a300d7fb3965355f1a7afcaf7e9d811a350005ec4657b3403b9df3a5e9ed8"): true, + common.HexToHash("0x48feea529eb2c5b5b5f1270811bca550fd54eb462798a2eeee44a45c29025cd8"): true, + common.HexToHash("0x5f69e530c56e515c6cb65176411b9d760fa8d775a573cb9cbdb3843a5ea92bd2"): true, + common.HexToHash("0xe178dc6361b031d07d7a33e350a4a3b38519d52a554a5c69a8182e7595d11f72"): true, + common.HexToHash("0xb705c0ebc661fc1bcaa7a06df0c978263fe5c76632ad1a3e790402ff21290791"): true, + common.HexToHash("0xbdef188ecf024e2831f4130f4613f63041e736ae3042489234a44a460b8f4ae5"): true, + common.HexToHash("0xcbc9a9704ed8283ebee997952e7f021460ed1106c98a7aae97f0bb7c7fbaddfd"): true, + common.HexToHash("0xc588e801ebe2e2f6074f221750208eb6871ecc91b6beaa7b6deeeefb135e579e"): true, + common.HexToHash("0x4218ec35eebdacc6476c4cbadecd7f4af9dd72d9164c4830903af9078864f8f3"): true, + common.HexToHash("0x12f298ba0023b83665d85c1471cac60203d84489407bd45723bd9c30ac549954"): true, + common.HexToHash("0xaec20bb9d8f39328e005c75c97f2e5ecaec67e32aa50e1b3efbb83e4df195685"): true, + common.HexToHash("0x4b1c486137b4c31cca2258fc96ad02250419ab73d67e4de6fb36be0e63dde409"): true, + common.HexToHash("0xd18e2f7173f1a05a5e2c1476dfa5449f26d0280f024009bfc93b37585164fe6f"): true, + common.HexToHash("0x9c6eb58fbc99d2376f831da37cb48b59b631c609cbd014615854c842cee29aa5"): true, + common.HexToHash("0x7a35754e42c243f64d30a1848ab868e9db227c4a17caee6540cbc58cec4bfb20"): true, + common.HexToHash("0xd9fe639ddf7c86e4e382c6eab27b5ddf47001a4496413a010f40c4121034f849"): true, + common.HexToHash("0x860f90745f0061e78bf1d2673376e4541b3f27e240ef966a159517987abcf664"): true, + common.HexToHash("0xa09343270df781aaca6174588dbacf08f20d9d1bb85864edc5dc31e347f185c3"): true, + common.HexToHash("0xa30cc9acc6f2866d140566d99c7c492589e4978a258642947a17bea47a756160"): true, + common.HexToHash("0x8990600c7a3bb35ba47ad14c6b54d1f48a366de9f9d2d80b7e8777307410bde0"): true, + common.HexToHash("0xbeb21028cc60a5e68185c5d81de37325560fac2c4e0d714b575d704515dd5da8"): true, + common.HexToHash("0x759d165c88b28f0301cac42e06ddfaf3c56819e7821d62db1583d5463d9949e0"): true, + common.HexToHash("0x779c95f954af8779a42065054e2e17a0239507489016b388ded8da1f92db0907"): true, + common.HexToHash("0x1e172fb3c6689fec2ee07a927933ea04966c0805e83a85d533156855e4a5ac17"): true, + common.HexToHash("0x35ed683a33a70ceb2a7da36d3df0f595b122e6ab2169ce734dbd77dfc228dc8e"): true, + common.HexToHash("0x75ea80ba6d2a7cb3fbd7f6ceea1d278630b392cf4c86c7f53661c81d534bf0c0"): true, + common.HexToHash("0x508b46a36654a953d31bba2d9f7c9d81b428f29d1ba1c546422e6622a65077b4"): true, + common.HexToHash("0xc39c3ce79b45c5f4daccfd3e58b10dd4a4707d7ad53b4e1a0ff55eab711b5b8e"): true, + common.HexToHash("0x63d692c4173ccd7b8cc9913d7cb3e811f430e297bfb4502ea32cdf49d880dbd0"): true, + common.HexToHash("0x1218decb6f57f38f1efcf656e246ef6f06c9635786f9b50352e785623217b891"): true, + common.HexToHash("0x2302566879a4ee87288a593bd26e23fac7a3b97f2206a6013f6e1203ecbd3052"): true, + common.HexToHash("0x3d733153102ed003dec1a5681b10312e16dc6008518ce0fb6c0f92c2cebd2d5d"): true, + common.HexToHash("0x748049f840a5edfd765e91af7e16a45025c0a662f87533183ed021775d1688f9"): true, + common.HexToHash("0xe4832d381cac2b3a8c72641cfc5cb71dfd57cac01c15aebd7f17d0101a086aec"): true, + common.HexToHash("0x67be40207d01e43b6af0ddb3fdb7a4949a343309673700e3ffb6fb822608ca2a"): true, + common.HexToHash("0x9c08806a85a67d19c0b3b108d5d247b5477bf40c492d457ff00aee544c55bb0c"): true, + common.HexToHash("0xf81a1444379006a28bcb142f089e57ab431e4f956f1fa625f5bc367d1388d204"): true, + common.HexToHash("0xa915e05a5207c73f767f7bb4dd03c3121ce476519806703c272381c97fcfe1d9"): true, + common.HexToHash("0x8ef64f8a325c1e355c2c464efb221d991b81bbfdf1a8a72d1c14ef3e24a6cdfa"): true, + common.HexToHash("0x59efe1baeaf43c157a580a5b9c0290f637a669db1ec21174da4e15933500ef6e"): true, + common.HexToHash("0x9531a1f5513d3f681d0b0aa0e6cc02ed94a83cbba7e029dfbae0bfd62bdcaa98"): true, + common.HexToHash("0x821fd118000649cd80e5dcf7cd2922c4ef9a3f32021fa1854d4fe83c60c026e0"): true, + common.HexToHash("0x82f631abfe5912d00af96dffa8e26f18b224fdd92437e1a62fe1a5d174822813"): true, + common.HexToHash("0x215c28cfac2b43d0781b8ec3f74219b8f8b1dd52258e1ee092a15c7cf217ec26"): true, + common.HexToHash("0xaeb6b9321ad8d1f6f3f8fe816623e168be6f68a02759137666728bc71d9c5366"): true, + common.HexToHash("0xbd3540f6d53cc26b1d10478ab933c91f1df734d336b099e1f817bb64d54994e5"): true, + common.HexToHash("0x0c5fa4e7bdecf589847b6fba1e9936639f3e42a5a978279a31b7edda9e11531a"): true, + common.HexToHash("0x081c535e59f399dd0b0097de4673870878a569d079c16e19ceb4841394568a30"): true, + common.HexToHash("0xb09f15a20763bc171d8d501f2674f9dd3b9fc69699ded5ccbae99cde6c234017"): true, + common.HexToHash("0x0abbf8412e013eccaa9c4e42b270bff980845c56d96b210f22003225adc16617"): true, + common.HexToHash("0xfa6d7cd9d95d1a44a1b83035726d28a96e7d3579c8fc4f2c01eb633bea9bdb88"): true, + common.HexToHash("0x3a289003ed833bca3e38451ac1bcde5821d4107d800ceea499bfe356fd61efcb"): true, + common.HexToHash("0x8b367e6d5704675982ebce8b83bb122171ab789a0bb00bd80b6d1c566357bf0c"): true, + common.HexToHash("0x4ea61e6848d058e23e8411445167e7268180a82999ba97e7280bfdcebb909534"): true, + common.HexToHash("0x26a24aedb55db524106e711d9d48b1b1fa8cf002d066baf6ca8b2801b6e45e52"): true, + common.HexToHash("0xd5174689eb78ed27325dc71dddfb4d08c4e4be2aa1426d7dd8fcf1b3cceb4ba3"): true, + common.HexToHash("0xa1e1baa3c1cc918949bb8f5e18882b6b2f376b0ae8acaca025365038f0e81c9c"): true, + common.HexToHash("0xcc45106d7cdb530b1908817e1275c56ec584131bf83486973ffd4ada7f71fe6b"): true, + common.HexToHash("0x2014975d5e4b1a365ab49ffb24f644c64181c4ceeec656e1e43b7c1e1a9a44fd"): true, + common.HexToHash("0x07ee87a443c9204e269ed981ea681e84963195f1085a2d9f00c8caf151af5c64"): true, + common.HexToHash("0x51723207e59ea9bf2649c912e837b84d1ed7fc89c1c0b0e403348005d34dbb63"): true, + common.HexToHash("0xf998a7c7fcd99b972ad7856a300970e6bd62bfc640cb7ee00bf8314c3bf359dc"): true, + common.HexToHash("0x29b94bdf85e90028921b86dd243a0905c69d36a84fe0a2dae1c186679a9fae9e"): true, + common.HexToHash("0x7cf3e76cf5c3dd6c77ea36d5a3a780c1bd28ceee03c6313c5f4913aa1cf8689a"): true, + common.HexToHash("0x31fd6839cf457a363ac17d7a887c0b556a4dcc825246f058c3b83e98a7d9b2cb"): true, + common.HexToHash("0x60bf22126c5c02d20a8c3c2e73b4985f6e2083ee88b0a8d96980803b39f099c3"): true, + common.HexToHash("0xc04e800a84618ad53ba78e8f6c0473be1cce4e47f69e55dbaa4f031478aa6eef"): true, + common.HexToHash("0x875113fefa5504fe15a89132078c5bf8885b450c0bf99d2552f515ccbe43751f"): true, + common.HexToHash("0xa226f86b12ef8dcf133e911bdf5e54bcf2c932f991f1ddc64bb212c784db861f"): true, + common.HexToHash("0x15fb16b939b90ed7c3684449a23c0d9c2728ade55b278b65aa539cd570b93215"): true, + common.HexToHash("0xb5d5a987ac09d9cf95056be9aed89e7034c3047803f3976c90f74200ea206d60"): true, + common.HexToHash("0x38a1cee11557d419ade029f4ef9d0866e1b123494561453ea5464d8646f966da"): true, + common.HexToHash("0x17162da179ee4c1e7a9219be74bfcc5049b39d2dc0ee0a3e9cb757fa5f0e4cd4"): true, + common.HexToHash("0xb258a931bf096fe72c57ede08b8635503d631f3fafdd1c95e69aecfe8d144378"): true, + common.HexToHash("0x06facaf5228dcf9b314433efb3b4b5649f3e5b4d1287336d6bb1a449b49e7f02"): true, + common.HexToHash("0xd4adbc59b602951c62d339348dbeea78dd796a926218c7b33754d3565b8e0e0f"): true, + common.HexToHash("0x78e24228a7c5582413190431f4004fa05cc1648fe767b5c6f24969388525b6ee"): true, + common.HexToHash("0x6af7dbfd59ead51000a98adee99a87203569748b39d3bfcdae797651d836b006"): true, + common.HexToHash("0x3e84f2bbe9faf4fe1177cf8ff6e80a50b107971e6f73a547fb04f519249bbf28"): true, + common.HexToHash("0x8d98d2899e8a99c7ade6553cd92dd7ccf26b7d38a1d3223e5fcf642de801ba7f"): true, + common.HexToHash("0xd237dc693a309304b3d04f3cfd4323689b4a2c90cc01f2eb69145f1b4c8d2bd4"): true, + common.HexToHash("0xf7345049a258728e007108061289de30fdaa497e2059c9b665a6bc687cdcaecd"): true, + common.HexToHash("0x6db7165117ebab2aa5753fbb3d98bde3bbe56cbc419c699cb3316c1b758dff09"): true, + common.HexToHash("0x384801c1d96a7d1d8cc2d7566d0d4b464bd29638c1fd3080c6942b6fb678110f"): true, + common.HexToHash("0x74573e27aa0a13de993fb3f7f6d861129b41a9bbc107650c7f749e7ee68b8c1a"): true, + common.HexToHash("0x25b82245283981be3d60ca6d4e78c27bd95a43ccde3683af640ae639069b4387"): true, + common.HexToHash("0x4ce02dd0bafb3a6ac486d0ea1a8b556768e69e06d262c18d732388fd30fd1fda"): true, + common.HexToHash("0xe84785a49475e39692a600b0435d4a4b4e7cce27a98fab12f912233e0561d54d"): true, + common.HexToHash("0xa79b14ca11ffe1795e451c6f2c8bd1c9e1e59b16052c12d40bee964ba0622ca9"): true, + common.HexToHash("0x1b73aa8c05f3af5e8b0b2f4c1106580d68bdef6dbfe9b2a19c69a0e69bf6f8e7"): true, + common.HexToHash("0x6242a315b4316ccebd3c77cdd3984f4d0ec0269e43fd7737081dc8e769469c59"): true, + common.HexToHash("0x1b4f77e142c9ae76757ae51d13c728879aa8f9ea2d1b7ec646f9c881fc0351fb"): true, + common.HexToHash("0x65f15b775fe38e175fe0ed713f8c378924da857a62e26df5316cbb7c78ebc153"): true, + common.HexToHash("0x28f87e6c0c4acb195b28886b39d0bc35df6bee0c1f7289140bd9ea77c99ac529"): true, + common.HexToHash("0x221a4371b566005fde62fb98366a54e2fe2de7be1f4a2523c3f2a82048811ee0"): true, + common.HexToHash("0xe3e15da7e8ff0f788d0ea65777aabc855dadbc287db2e097baeb8c27b355a0f2"): true, + common.HexToHash("0x9f990e2a0448760c91397d5739c0522e505fd03541fb97c633bc38d04d0a9ba9"): true, + common.HexToHash("0xe72ddd493f3538ecbae9c848c3a451a2c37b09fe46875e87d418a21ca0bea9d6"): true, + common.HexToHash("0x049ef49227adbde5e52ee923395d257bb37e66d2e201689005fdce5329ded400"): true, + common.HexToHash("0x05d2dd6a451a4112a89f0d150a931f3005d90843c9d65ced46fba6047c959220"): true, + common.HexToHash("0xadef27a478b2ae7756a7013aed88d6fb4b0915fd2d41e54c6cc81f5113935758"): true, + common.HexToHash("0x4f404e6ed0c986f7dd75bcb85dedfe2e0fa7cab9032bcb0f3ae99967b8cd4417"): true, + common.HexToHash("0x332f99ac27acf376ac37d8e8bd606d49126ce77cfa360cedbb5e468c84b36535"): true, + common.HexToHash("0x45e0866af41108217163ac39c93a8b60b16cf714546d240ca63a8cf6abe422e7"): true, + common.HexToHash("0x1e155e6cde25e82be13f763400f421837bb7b5d867710779d94a115ce29ef4d4"): true, + common.HexToHash("0x6823d049faa7db07f7f65aae5af78d9dcc5e1d66a8871af976c8e254f8a1f327"): true, + common.HexToHash("0xfc9c344a9ed49b0ff30e6e3eeebe58859f8fba76666baab234642138335ad56e"): true, + common.HexToHash("0x5b3d506b5eb2029854e50887ca062c0900f723217d9c0002d5a594aeea58be83"): true, + common.HexToHash("0xe072128e417d2077b6566c526da393ac5bec638750b3b8c6bbb183fba76a6c1f"): true, + common.HexToHash("0x07ae27135de30b6b4788b5c2c52148023bcca1ec80efad8f7f6b3144fef26724"): true, + common.HexToHash("0xa6dfe664f62cfae5a61587dac111d43641d829c4a89119b9ba9cd4cdbf792578"): true, + common.HexToHash("0x03924ef9bb13e1340f6a66079ac23b79247479eb7920a0988d362fc1413b7a97"): true, + common.HexToHash("0xd57937c72069ea8452e71105a0fa6e3abfe2182d8e20f722a1cd695db11f9a6e"): true, + common.HexToHash("0xb2e911ca5cfa2806f4600f31bd7e599a75ef54c5ae062d960a76b006636a3c89"): true, + common.HexToHash("0xdf869ccd963e5badb9f08632fb53a19fcc1f0db8dae56b03966d3e730881d6f5"): true, + common.HexToHash("0xf2304a2eeda93f986351b9b948beecc55d8f8315be955f9ac35e8098a47d2576"): true, + common.HexToHash("0x8473152afb905cddcf5837c3ed9e22a7dd9cab9942e22c916419e05df8316974"): true, + common.HexToHash("0xbb2138fa75e7a15df031dc3dac40774403a8e9e4162d4d45612433e13b81b82a"): true, + common.HexToHash("0x3c7fc02fdbed1767d8ae26f46c511cd8ddecd43a9ccb7f91d11b5e2c30b3445f"): true, + common.HexToHash("0x9700e9fb02ddee907b188ff85a6b1e948a315085502875c98926710f10f40446"): true, + common.HexToHash("0xe7b7cb1fd2ee66d0f837d994bb2fc8ad9fda5e9902455bbbb78d70c633c9e1b3"): true, + common.HexToHash("0x3f8c795ce4300c1d4c87d258a9389f094db79d003cc22ddf7e73f9310bc720b5"): true, + common.HexToHash("0xc0a20fa77d1bff325a3766e3e209478d2ff424a80e20fc48b1d45c5615c2c390"): true, + common.HexToHash("0x72f4baae35f6eaab071b4332701aed9f6d68c065ca35377deb1ccf552ae300f9"): true, + common.HexToHash("0x6b38b5c333594d02eac97404b4ed650772b639e827e5ffe090b9002cd6ec8531"): true, + common.HexToHash("0xad7525e471a0b086a61bb3608fb7a07252671eb300ae9714702056421f0115e2"): true, + common.HexToHash("0xc617186a00a5d07d64a3f30e6faa939c07a71088001dbc4cf3f97ea5a3dc7d23"): true, + common.HexToHash("0xa28db6e22ddc5a1288fa07fc9ad60eb3864d782b70d19754cbe48d96d1b9777a"): true, + common.HexToHash("0x83a40beed40922bfe4ffafb68864294e891a7fa953f6822d4d35c7812c4df8b5"): true, + common.HexToHash("0x22363d075b32aa287d48a82c590ac81e239a08f472aec177939252f812f015ce"): true, + common.HexToHash("0xf31a2cf7a0f4d29e73963101a3b9ef21f7f8d6ee3b7fac7313a56bf2b473151b"): true, + common.HexToHash("0xacf678b287810756b44a59b94f66f39d2510bf74124fa5415bf14d75452bb3df"): true, + common.HexToHash("0xd811640f30cd48e4f897ae3db6708411ed1ed0728ff38368017cca80755f557a"): true, + common.HexToHash("0x6eaf9ef23c276af56c7482a844957fb16f6f66e3dd8d108c41959ca556c4bf4b"): true, + common.HexToHash("0xc0ab1767f0bfb6c452ee4de46690cab75fd593ad7f22aeefe1b5177d6a6f5d84"): true, + common.HexToHash("0x80ca7d8f2484eb8839cb58978606e3c9cf29a9ae7cbdded930954cd2cbd498b9"): true, + common.HexToHash("0x7a6d2f874316fc32868e2b4c45d4ffa31a71f8fb397ea980635cc4cc579f6460"): true, + common.HexToHash("0x2f2f723948ee6880cec7e5c6d891aa422ddda926f0c4be121eaf77092a08cb5d"): true, + common.HexToHash("0xf92fd1251409604410550bb3977da550052b7788e51d54efd8812c9dcd2e720b"): true, + common.HexToHash("0x3e5960ccd908981ce35209a7493a91c0820627c0b21cd0cf5e75ed1049f9f880"): true, + common.HexToHash("0x01f6f6cfcb857123c461d0cbad02030abe779432a49b269f48672f1198bb324b"): true, + common.HexToHash("0x665a76716351b8fae493f8c366d4b0dfeedd0e1bea724db290fd7ba34ab1b06f"): true, + common.HexToHash("0x1be1119cf0d85c2d0a32cbbaae5d62736866609586be60709fe6db6da9750fd1"): true, + common.HexToHash("0x4b1a13e7b5f6226bf8c41fbe370f2511b20ba865297f385461d6deb2dc4f0023"): true, + common.HexToHash("0x18fcc84aa9ddef07986554108412dfd85dc3059625bcb05679d6b6901218198a"): true, + common.HexToHash("0x0f40f650d2a2a514eecea81cc897ebdf36220d57d1062ef84f71ed4c179545c4"): true, + common.HexToHash("0x2fc766abe2e4e833646437e27d375edac6c5213d10b8f865f6d798e9c2528f10"): true, + common.HexToHash("0x98ee520a1b52c490ac1afb81ea52d88770126ef26de7d58337fa017c3b1d5c9a"): true, + common.HexToHash("0x5a7845f46100f57987a7fc297e6e5b89a9a8dfe062fbf276d2d8f1201ea9f996"): true, + common.HexToHash("0x6a6799f1ce21830888178b7e1d9b291aa7086305a08aba3211a197eab5258f80"): true, + common.HexToHash("0x7ce2f060afc922c7257f6f97151882be5ba1464fb33dc7266cb1d9353075aaec"): true, + common.HexToHash("0xb10786a3e9232877486fca108624b073539b1159d990d0a73eb61dcd9d40d652"): true, + common.HexToHash("0x2f2d6d5d4f965d053bca5c815fa556af0b17586d1a7f375c633d618887a8b6d8"): true, + common.HexToHash("0x13c668a6dbcad77f53569e225f3f253f86100d5d4e325cf38c977b1f03df6d13"): true, + common.HexToHash("0x7546f544d4b9ec103e68aed527ea5ce79033ea38efd5b17e2be8b92db76e5bf9"): true, + common.HexToHash("0xdc68ec18a1176f9321fbc973281d3b5082a204656205a5a80ace9d5f30ce86ab"): true, + common.HexToHash("0x48f131bb1087821735fb718da58ae76da47815da2b164dc100e2f96d7b7503fb"): true, + common.HexToHash("0x1fa10df83be6b4163b810a7523a97aab85cbb23e35bf2cfdeba5eca0ec35af27"): true, + common.HexToHash("0x6403af1afde143b27f7b5101383dfe39474f1d999936bc08093e2adb35bb4b32"): true, + common.HexToHash("0xc5bb3274e96d6f460cbc704944594ca4c6fa3c7c3883f74588db6d8c1487c836"): true, + common.HexToHash("0x1f3437b2d81190d0223cde403512282a9c59feebee68717edf46881a74313032"): true, + common.HexToHash("0x4bb3e185277ab65b399ae837946575b22efed510d98afa1a5954b6d2d8c677f3"): true, + common.HexToHash("0xb685c25d29a36d5a2f1d77b68bd3611b76e2a78a0dde7ffea9d9dee1861c4cf0"): true, + common.HexToHash("0x03c7573047f5abe69a6e5aff608a6e287e68f0f126265546bfdebf68b7b72e1e"): true, + common.HexToHash("0xd49a7736d53cce667e229e7ecdfbf4c187a665202c4e6caff0cc1e006b48b8d5"): true, + common.HexToHash("0xb7b31f2598db58077ed9f97fe63bd0f4cc901f7c849eb5cc3767fbfbd7d77fb5"): true, + common.HexToHash("0xf4d37e1db9b1f3090ccc16479612c9295564c771c7d16d89f3eced9772227666"): true, + common.HexToHash("0x8b18384dc532902f4fb771792a87f2d2f9fd89db9783d8df5a0f9b2d7206a1fa"): true, + common.HexToHash("0xac752561cad40e3fa7c40c76a8150fa66fd40748d04c13ea034a992939e227be"): true, + common.HexToHash("0xa81e7ac4c7b2dbfce547be1638ad475e4cc4cc8be462a7c701c77ba6abaf2fe3"): true, + common.HexToHash("0xfb4acbb803251fb9457e077e2d81b9d450890e3d38d5399946b6c36ed86da82c"): true, + common.HexToHash("0x0a2d1bb46210d19992bd48e05950211672cd5286b060f4a9a7bdb482497f354f"): true, + common.HexToHash("0x95704fbb2cb7b202882b3aad04f242ed32c2dfb10bcc5b1d6fd9ee124f6487e0"): true, + common.HexToHash("0x7bdda4cc2fcd78dc2de80c0337e3a37733613f5bf5237d9002d047a73cc1730f"): true, + common.HexToHash("0x60a1f3906549c51011e232dc161072a6a39699b612190b9d5aed22154868904f"): true, + common.HexToHash("0x11e2f25233ed7344ddd6fd0db1aca060ceb669b08cee6214d4e6a94864499ca7"): true, + common.HexToHash("0x3846902e156fb5be913676707beae4492040f6fb2ed278ba23790b74a118c5a8"): true, + common.HexToHash("0xc061aabc2517f08c0453f0797895b8d57c0cce93345506e800cd94e782593e74"): true, + common.HexToHash("0x6347a019be4adc25683f7d4a4e9e92b1f0cd3116a4e56f2e12caf91645318335"): true, + common.HexToHash("0x17d199ad419a43273f08af395b818d43a93441d1e96e79c01b57746fc4739c12"): true, + common.HexToHash("0x84ed7b047ed036d964d0137f41623421d35ebd9ef50dbfecb079a44234ed865a"): true, + common.HexToHash("0xa2cf1213aee457084788270a5c398d235944eb501e6848f61d422708cc2c5262"): true, + common.HexToHash("0x049844b18802ebd7b57aac385e00c27e8d8ef86b4eb16b89f74b8ec8ef7c64da"): true, + common.HexToHash("0x3b6cfde05f85cb53da565bc719cb921f33f0053a548c4cd6c0e73ec396d96c46"): true, + common.HexToHash("0x36aa8cd1822c2a1b879dbbec0946bda0f5205c204bf6625f1dd10633482cde62"): true, + common.HexToHash("0x9e0df3d519143c54062f0049c245f8f1ade433a35930e80e76106984004e91a4"): true, + common.HexToHash("0x66368bd0e09b0a7b595e47733a44ade32e2f8cbd6203548c143d116eed39261e"): true, + common.HexToHash("0xa674dc515dbd427ee00ecef4093d698af590178b356e1ebe0b6d0d696d64ae19"): true, + common.HexToHash("0xa9c162bac4dc80763e880a13cb61bb5c2bfcb727a6807ba92d5c84a0536c1c21"): true, + common.HexToHash("0xead9d611a91cbc56b770dc84325445024d32bd4bc89931e5671e09b1db0fd71f"): true, + common.HexToHash("0x8b45ee663c704c08eef8b52c430a91666eaa9924ef27db324e6cc67bfaa9b7ab"): true, + common.HexToHash("0xf86c3f8889df59b4510cd7634cfcf23f1dda3170a83c1b2ac25fe1a664d6a638"): true, + common.HexToHash("0xc38c19697375438adf98348c761eb547460084ddcc2d0314d1686c05e828a2f9"): true, + common.HexToHash("0x983550da9435836812f6d842e789e2e0687df8153342c62c9c4b77b8fe51d4ce"): true, + common.HexToHash("0x6245b40a442bc00647363e8bdd829074336a52ac1f6170aa776c3763b984f493"): true, + common.HexToHash("0x035ede25a335e373a85cd4731bb4efe7a30dba7fb374379cf06e2bfe46478aa1"): true, + common.HexToHash("0x583041edb5576a40ed3002b93143571804deb5b4c28b58d4843820a07ce6c80b"): true, + common.HexToHash("0x2c752611efb74edd230fa78b548fc9203ddccd50a1afbfcf2460ef610844bbd2"): true, + common.HexToHash("0x062d8245474d6fcd1d4670a4d7fe3951de40cb67dc2a0b59c4ddf94e035f11b0"): true, + common.HexToHash("0x611d10fa4fcfeac29d817bcc5330149907490c55fde782da36438f7ac571404d"): true, + common.HexToHash("0x368a86e9e91bd433a325da75e9079b0c595feb4a5365b8046f623ab430d66c26"): true, + common.HexToHash("0xadd7078f48ab0cde3b4a50f69576c508e153747937ad827e2881f28da633c737"): true, + common.HexToHash("0x947e3e1aa61ff1b30c4992e680ad639beee9a6058834c95e2fd4743373563ed5"): true, + common.HexToHash("0x2d23d3daef697276fe00fa8b48dc4a57767346442b86452fb4cbd6123b9b518d"): true, + common.HexToHash("0x1b870bcb68ae250bfdd5acca09f1657e15ffcd5ef7e6c40f09d8352c0e1f44d7"): true, + common.HexToHash("0x8805179ded760532deb7da8326b58550ef0489247d7b611bf1d51996cdad59ae"): true, + common.HexToHash("0x106111392450abdd25c661df90d04c20374ca362bf1be172db202a1fe19b2fcb"): true, + common.HexToHash("0xbfae6474103255c121422760fed5f5a228c68e1d91250b9b0cffb6af87b4f10b"): true, + common.HexToHash("0xd6b3188fe69efb59066ad0158ce74bc09573b201b9fb1ce0d9f59f4865e29dc5"): true, + common.HexToHash("0x56cff9b5f70f53b401a8d8c1eb3541b1e4db54ecb3dc2fe901279a676b4f3497"): true, + common.HexToHash("0x6c450523b8df3ebb176b26eb634fdb25098963a13e8e58c65d820b664174ce2d"): true, + common.HexToHash("0x51e66edee5d9243746e25f28ea8e23bcbda6364323d0eeea1e8035c030a19475"): true, + common.HexToHash("0x355817f2bd5c219b0c1086838476f530943a2e24c6e3dd86ccd687d9ceaa5acc"): true, + common.HexToHash("0x47a0b1dfde5d71e53785b917080f1e5bff7c29693e2ddfedf9bea5e475be7469"): true, + common.HexToHash("0xa89077e9238451cdb03a0491ca483db5b4cb2c2ee7a419c262c87a0d2db54e07"): true, + common.HexToHash("0x97f3d7998219aee4bf4469dc620b366845c4312c928a505141e57563c6570415"): true, + common.HexToHash("0x15748a9d6ba0ca76c2f1a05ec6d19cfe927351737e06cf8e7f32e7fee762a451"): true, + common.HexToHash("0x8e184532a124336a036926ace6e9efa92ab0b23066790f6eeca80cde17916497"): true, + common.HexToHash("0xf666c9284b7189033ce02c48b6f16b34f185330246a8376b52101e31c3bd725e"): true, + common.HexToHash("0xba83ebc542bb9d69da50f0205ad568d9ca3dbd22f7f07c0928c9d1b82abd2be3"): true, + common.HexToHash("0x5d39cecb85ad797ce0dac7a80d76488e2a1e6223b732060613d65541b9f75a0d"): true, + common.HexToHash("0xb2c60357f7323cf76517334b3db90306e3d00a3cd85a5b4f86cc76d0181b92d7"): true, + common.HexToHash("0x8493c5f60ce2e0b442015cfcb99838d6a32d71d683752ae5eb195fea5f87a394"): true, + common.HexToHash("0x67c7a8addb080577803882dca413e27ddd8cda31162124efb228905ed5c4e892"): true, + common.HexToHash("0xa5c0471e8da5b54a2589425c9111bb4891ef27b2784172d4bac95f93c1eebdde"): true, + common.HexToHash("0xda2f5bc33d7d81741cdfa92d2b05d0052549474b92d2ea5c85ed23fcd9181cbd"): true, + common.HexToHash("0x3e84d1eaa7c76b29d913f06cc96a1a5ec7fa1f9d4610f58ba4749421f4d93a25"): true, + common.HexToHash("0x0b7f9f486d8b528bd260067654647731e86ddd21f4a56b96d5a6845ccc04db48"): true, + common.HexToHash("0x1e93481d09c85cdb7f7cfcf56cf12785e3fff42237fc7053fa7f678773409e1d"): true, + common.HexToHash("0x744fba82f983ed6eb5ce3a3e15767523988a60baf04a64ed00325728cd20f553"): true, + common.HexToHash("0x9cc1f0a8c18bec9711817cccf77fe5889600c70dcea93196286d3951b3669a02"): true, + common.HexToHash("0xd1a066ed89dffb7b85ae0d5cc1e744b1cd132a366bac107f0265804419a847b8"): true, + common.HexToHash("0x052241c3752f7c80d09d2701c90608e97807ceb8dfa2248cb27de054aabf11ad"): true, + common.HexToHash("0xf979310be5327f162991fc41b9fb945b73a248337cfe5ff67e20df4077e41297"): true, + common.HexToHash("0xc0793f0827a0df9f0b2b3cc3d3b9dc8ee39d50e1923a5a9664ede998e202b839"): true, + common.HexToHash("0xf513f8514a54941779d4da6d211d2c19462d07649c2cf2fee35532d407b1265b"): true, + common.HexToHash("0x319b1f4659792465e593a823a24a9b23a838c8b0aba06dfc951051851462610f"): true, + common.HexToHash("0x917d7da423f596e49478359902e9e5151ba36c678915d9b232c6d18ec39ba3e6"): true, + common.HexToHash("0x2011fa8c6b574e43a930018f25eb6a3da69a61c5ad8a70bc8aebb715e13dc007"): true, + common.HexToHash("0xc608ead620b10883df6fe6794d77dd9698b70b9f6d54d7cf9d1b43d9afc98395"): true, + common.HexToHash("0xd1059fcafb157d4ef74d8e5639d0afa72a6e65235e3a2de05a4a989ae2b5eca6"): true, + common.HexToHash("0xd1e3e37533b2f81f7699db37a11707abdcfca8524164e21c20a15799baa14ad0"): true, + common.HexToHash("0xe47ad283bf19a22a760de282e9424266d09a3b12e8ee16502e3f347ce25e35f4"): true, + common.HexToHash("0xd47ec94f82a764adc59235ab2d0c5ecd7de00d742908679277e2a0c566d52bc1"): true, + common.HexToHash("0x7e4e702cf5b3c79f068e3c2e112578d153a4b5c4e447eefe809dec125ca79a85"): true, + common.HexToHash("0x24a18b3018aee97d89d0dab10d9685430917ab866cdf31bfec1453dd4e4d2afc"): true, + common.HexToHash("0xb66d684026828a6de760a508058afd54ad4e1f35f2d38745454548990069aef7"): true, + common.HexToHash("0x6081f6401864dd1d4559309eb1f376c784950dc16c758f0b17c2285fa3d50ae0"): true, + common.HexToHash("0x8d6a68396ea4c772ea0988d8c00980f87fc5088942d006083c50cb21f7ad3b54"): true, + common.HexToHash("0x3e547be9472d8ff9a42e40a9f08f39f64029c25509d5f40ba11e1c3de1d831d6"): true, + common.HexToHash("0x9499e99fa09dbc618035f7a8ed7cc854fd692b193b62cb7e516bbc12fe97ff3b"): true, + common.HexToHash("0xb4df5eb0d2750d1894b672b69bc8a4bbca4e54c6340bd1e0fcf4dbbe9bb6e99b"): true, + common.HexToHash("0x5e0fc0b6fa7bfab06134aa40c92dd4347c62e8809a452089fa77831c8350fd05"): true, + common.HexToHash("0xe98894e7e6be657ef39bfc3d1e933d80417f84dc876df2304ec32b92ed910dfb"): true, + common.HexToHash("0x4463d8582699f1c51950a4bef7dee9bb55c417a150fdfc6b16507393d3fd5537"): true, + common.HexToHash("0xbdaaa06dc690062843e21ee28070d32b20a4126a0c4cff4e9574d670c17ecd69"): true, + common.HexToHash("0x825206500e06a77e9f87597fda29f6f1ac0229bc7f4bc4913d7fd9848f760daa"): true, + common.HexToHash("0x484b6c49a11f01325065ca57256487e608addce93da5f92b141846ce58f7df3d"): true, + common.HexToHash("0xcb62887ad6f43b55e127736cc3b88924bbedf584592221a54e5bf3a89f319a24"): true, + common.HexToHash("0x1dd5f5b3a9c65a02ffd4dc3b4743427e8f1535a38541f5d8146c762d50c69891"): true, + common.HexToHash("0xade2da269b5c1f1ddb21c1aa4899801bf79daf19b33f94fb1706206b8726a032"): true, + common.HexToHash("0x43ae1959b1f3b0752357a3041eb0b80753d7576ba6f270e8b26260464051df71"): true, + common.HexToHash("0x2f839b36247a5c44907b186ac5dcc2eb47ad45aea13aa061e5271d89f2fdcc85"): true, + common.HexToHash("0x46957e83c62de6fb38f1201de369f1d08d1dfb92ce3c0d42ba4cd5e15f0cb62b"): true, + common.HexToHash("0x18f54e691514f72be5edc34f24ec8aa5bd0a5b5a674c47c0dd5d291c3939d424"): true, + common.HexToHash("0x6e3bec1c43cf44f49dc0ed6dbf0f48f1d16dffda5d33aceacb2096eec1c3105a"): true, + common.HexToHash("0x6322e191d1198ef87c0c1657c84323a11024bf34f1dfc221a7fde00ac0c0766d"): true, + common.HexToHash("0x1a941e5fc8b5743bfef022197bfe3eb35cf402042300be9f9f8ac35068776333"): true, + common.HexToHash("0xe4bf6e167af9dfdceeb80be62c13e884003dea5092f1daf2104883242acd2773"): true, + common.HexToHash("0x55e3b6be87d9ec75f46d40cbb2d6a842820fd91f3241782a2dd6c17b3df756c4"): true, + common.HexToHash("0x1d50d83b04a8dfde87c5b73e6c9b6e59d3d9af9e3b22a8c887af4d0bfe5e3f32"): true, + common.HexToHash("0xc970f72fdad7f3927b0d4fe843c7e20600d6b31581d96c1fc68ff989ad9e2825"): true, + common.HexToHash("0x1abbbe2f766e2db67b9e0701e4d21f260509f9129461ceb0568bdf4795855f61"): true, + common.HexToHash("0xc0fed8edd27649e4710e0023ab16206885fbec24f09e9a012e95637de9e76d54"): true, + common.HexToHash("0x80d527585ec0bd1128d29f56ba3d580b109be47b2567da01d7d3f090c1adcb8d"): true, + common.HexToHash("0xbaf4cf337f52de0dfffb4cf74949d4d3fc6c4b64ce61fbd2651df7295d12056e"): true, + common.HexToHash("0x52dfbc968306cda2951493fc9cd1cd3ec9f0a454fc8ede0aa81b70b221d1f506"): true, + common.HexToHash("0x99f7257af590ad6c6e5cde58e1fae41ca66a66aa8eebffce9660cf5d2a5ff85b"): true, + common.HexToHash("0x7a657b9af7bc1478681a185f2cc5940011f1fbbad386961ee6aee1e558f35ce1"): true, + common.HexToHash("0x32a2ee7c8309459ce71a72aa2f2e306bfe67bb44fb7526572531298af739fec0"): true, + common.HexToHash("0x2fb395d61c481ad655aaa66b49ed482bdc700e09124e87dc3d34dfcb4baf3c3a"): true, + common.HexToHash("0xdf587ead143e20701d8b580fbf53e33d4a332c7671b41375fce9194cb3f5a868"): true, + common.HexToHash("0x10c79490f30a3c76542fdfd338f1958d9d95be3ae54a58f024865213dacf3a81"): true, + common.HexToHash("0xc88907c7edc804047de5ca06b359ce0456c53b2f4c353a71207504b22b83b6a5"): true, + common.HexToHash("0x8062c557af9cab2a87f41370a61794206c953cd119970f07805a8d8cabe4caf7"): true, + common.HexToHash("0xe6be804fa765971be0ee09b64d22eed8a2a28d0a91bfb3edd1228ce0337d35de"): true, + common.HexToHash("0xf80593373186a8ae14ea8bc573cd342d5322f6f2eb0c65a39daa6697cc70c9b2"): true, + common.HexToHash("0xcf32045628380d8087096506f8a038b16f8e63bf6b01bd64c0f27a5690164e42"): true, + common.HexToHash("0x07bd7b1ca6e04cab3857bc824200c666ec442d336348bebbe3409a26438dc514"): true, + common.HexToHash("0x3b585094633a947c80b113ecd92bea03b37d47bd938feacf62fe5f6982216561"): true, + common.HexToHash("0xddcb4841c5ac0f38056b732e6ece73b6a925090d098b69b3807835659c90f2d7"): true, + common.HexToHash("0x2e99d34e6869a3be8149dfee3e77f29df5755f514961864068f89e2219147a59"): true, + common.HexToHash("0x42ae450f29b90d42ba64972c11e4e7978575ee4f2ccd681cc9803e56fab0c56e"): true, + common.HexToHash("0x28244a333bd5aca16512b4858cf73a13ba82e27f5f04f41993f5cc822374789e"): true, + common.HexToHash("0x58185bb3c3a21237aa03da9f67195ddfaa7440b63564831cf89d5c3ff614bd50"): true, + common.HexToHash("0x8bfaaa5bef006d06c7f6462d0c223ea189fdd1beab8001a20620846386a6494e"): true, + common.HexToHash("0xffe907fb192c60a367c2d3044dbabfedc343a2bb1477ecac7642795e0a31c02f"): true, + common.HexToHash("0xb10ff27be26f8af4ab64b9b6a5bfb8de71e21a0294d2984075175c5c1de71415"): true, + common.HexToHash("0xa63d7bfb8076d00cbc2fa38c9ef8a6d1991abfb383baf7fe638714af34b3687a"): true, + common.HexToHash("0xc19c0714b6ec0b2883b0b0c7b26ccb07ffc5f6a22fb3bd974f5f204fdf469436"): true, + common.HexToHash("0x853dcc36b39675e798737db50696c4c4bc6c3954504aef2f725f187e00d3d04b"): true, + common.HexToHash("0xeaf066cc6d843ab4a62800cea3c74c9c6577dcc9e64a75525d1ae0acaa5ec5e4"): true, + common.HexToHash("0x037a14acf87c3d3f5160e28966fb223f018b4fa311b035a219ef4b32bc9ca2be"): true, + common.HexToHash("0x46b082d0e8977b30b37fbaef572eb652e399e7024f3fed9f616497f3c5d2a755"): true, + common.HexToHash("0xc071299fc6c42425a93c0f0fe90b837df3a9b396faad5a317ff91c7e802c3a1e"): true, + common.HexToHash("0x90ba923ca85a441200c08833b9f86aef31b17f7fa6442e5b9b778c177314e68b"): true, + common.HexToHash("0xc42f7e9b8bc5ff795ba71a305c82ddbf92b56ea4da837896a1fd4818e965037a"): true, + common.HexToHash("0x60f918dade1bd7c5bd214ca9a3d46313d8122c034c61e65bd7e767a7d0a7e72d"): true, + common.HexToHash("0x02fad160494a118ac99c82cc88da4810373c3cdc88402f3776f370224ccf4591"): true, + common.HexToHash("0xb152cc9113ce4f76ac10a1d35ca696c4cfc3aa634e47df481067ce26b4c0aa99"): true, + common.HexToHash("0x6250f721e634df31236d4825217582dc33105afa04167463d8423ad052248968"): true, + common.HexToHash("0x5bf97d8779483e8a940e4571f614ac95e951010053df02869881bc0a39115c9c"): true, + common.HexToHash("0xabccb023b1b48f7fe94e5931b55a7b3f980ab1fee4916aba97dc81468ad99299"): true, + common.HexToHash("0x05ed5be3f8322ffdd920d3b3eca67335200627223cdf65d595884f1605f449c2"): true, + common.HexToHash("0x85c0f21864f8b1b68abf4f22db3ad46496e52174c9a8123b654336591094d70c"): true, + common.HexToHash("0x9a4ffd2832346bc9e65bc26ff349575e4824dcb1dabb98df539a6fcb406c4f99"): true, + common.HexToHash("0xd06c4d9c0592e6a3b3a35c8eb13f1ea1222330f5893fc40e6316421448974c69"): true, + common.HexToHash("0xe2960eb44d83946ccd20358564d4bdeb8dc6fc29ae9f555e5f5c94580de0ce43"): true, + common.HexToHash("0xf3b98329dd8e5b4090b7cbda80d9b78e6af07991d78bdf90afacfe5a46dd8f70"): true, + common.HexToHash("0xad3f459532840caa8aacf82195daf9164c6b12dd22d817277e197738753ebff1"): true, + common.HexToHash("0x732beb7cbf5d7661ce19375977bdbffb112b45c2114b612117f32fc0d0d0679c"): true, + common.HexToHash("0x3deb87bbff42acaaa4357b3bce9e5987d5410088bbf9b673198c6c98c9a81e5b"): true, + common.HexToHash("0x1e1df82d2634c015f57bc928872f6aef64c74b74261050c1efcba1999fb1911d"): true, + common.HexToHash("0xc975c66f763efbab1bf5b8c5f2e5c07bfbea02a18315459c15633198d3ea7ddc"): true, + common.HexToHash("0x0a97db4f86f1672e829f543e63c5a097097e7395abe3b438f0fd59405ca7d040"): true, + common.HexToHash("0x0b405345f11599e8bc8276ac064be82ff2156c025d96850b20be7bbcd6663aa3"): true, + common.HexToHash("0x06e62b5509c44df9fc89370ee01fde4c71c48695c49ff48a41da943a1e3d0408"): true, + common.HexToHash("0xb486eff69914c7a087989764e36360a588ac265d9bf0bd47e576587bf12bec51"): true, + common.HexToHash("0xceca0b1ee2161f9b1541c92bf312285d0a2d4d6112b29bb23f36d18c8b205fe4"): true, + common.HexToHash("0xd27dc186c064651d235cdf6a36b695fad578ccc71801a972e10d9cd5868c7e69"): true, + common.HexToHash("0x0079d3ffd5aa39265c13ab27d0b53af15a91fdad45ee037897383daff477a0e0"): true, + common.HexToHash("0x0bffbdf8566ba5616bc44dbce766d2e0482147a86c0622c25b4bbb6d53b1cfc9"): true, + common.HexToHash("0x9a84525f9153d333dbcb1ea47bce5d88e8f9d463463000b64a72c333534c3825"): true, + common.HexToHash("0x26a72f1298b39181b9fb708e4ca284c08a4a2e434cd14a570ab159b568c23d82"): true, + common.HexToHash("0xfe4bb3b83e2089c3224b79bf4ea2135a4f498b13744e620cb8f1692bf77699a7"): true, + common.HexToHash("0x0aa71d5e56f880ea397e460f9138b943c2f42dafa8b132aaf348e0db8b7721c4"): true, + common.HexToHash("0xc23c96481ce478544bf29fb1a240f6d1507476fb20a552253c5ab67d1b07aaa4"): true, + common.HexToHash("0xfec9e227b98d0b25ffa0d2515a706eef8db160454c9353a57fc74d71d532ea1c"): true, + common.HexToHash("0xb30767c64b880c19a4c190f277c6cbc553da31508ea2278b13808dcdc14f09a5"): true, + common.HexToHash("0xbf8309b20c2279ebeb3ba208ea6657a9dcf1f78ea15c4a8bc956df2e7fb8a42b"): true, + common.HexToHash("0x6bd6eabd9b5757d6ddba2f41d1ab00ff234362e5df077acda45a17bab38a3c28"): true, + common.HexToHash("0x3693ab56c233f571a7e83374286d02d7295db7ad6a733cfbb799194311e49fd2"): true, + common.HexToHash("0x012bb68fd7f0db8c07beb62848d25b9c04ed139d31b07c7edf2941039810b777"): true, + common.HexToHash("0x8d14fae6967a845d4a53a19bd3c78b5de21044f63c675e903584a1619dcf2c2d"): true, + common.HexToHash("0xb00610a045fb82b92f1242fff82d9abc53828b3c1897fe80289d4fe1bf6c15e9"): true, + common.HexToHash("0x12b93218df06fc9b8c4d10f5ebafa64a64a1a5078725b523ee222989370b6ad5"): true, + common.HexToHash("0xf19bedab39dea878941f35b7a0765e22a36f6632e81c92fff448b750d94cd548"): true, + common.HexToHash("0xa7849498bbba8f5f7a3cbafcc77c738a0c1bb7009a92a19d6a8ea73882dad121"): true, + common.HexToHash("0x18f4648aec6152eb33a910c65c707243bf4bce0963e2a34d57c8986b8244747f"): true, + common.HexToHash("0xc1decc89cbe1cc20d5e62b5a15b57476b296b9122631fd28dcf24b4d43b6cf21"): true, + common.HexToHash("0x5f40bfadcae43580c3ed23d245e0d39b3098f37125689d24aff72559726740a8"): true, + common.HexToHash("0x102e3382115a0709f6f7b0acea5e82af65289e5c488aa1fe1ba90fdc55c408bf"): true, + common.HexToHash("0xd957e7c702a053a08067310688f939cec5980c675912e29c9d582ff2e3aad747"): true, + common.HexToHash("0x90838d3fd9a9a49977881f332434e17ac1a43e2ec697439a4afc19c13a71737e"): true, + common.HexToHash("0x2b37729e7ffff97a74be89dce709e3bb6c589d8ff88c7055f222fca87fc81759"): true, + common.HexToHash("0xc7055ff6946630b969dc3246e0f4aee0623aa00fb168da893c38ad0ccc0ef0bb"): true, + common.HexToHash("0xbd0a31dc7e173aca6b11129926d9e47e62a66d7d0e9a43fe64309f88620d51bb"): true, + common.HexToHash("0x5ac856eb52d72ae9c7ec187305cac12b28c7a462bf61737d19615eedb59e76cf"): true, + common.HexToHash("0x66c763cd51121c21e51d21a1d5add0f40a7c05826ce97f0f1366d32c46380c3e"): true, + common.HexToHash("0xa3b2f68ac49f236fcac4d38b5071cff272ea160a7d48de931c5ae71ab0911dc5"): true, + common.HexToHash("0x943dd2d0a70bc063b196c078133b35329fa528877cef2d4d20ad40331d7c5637"): true, + common.HexToHash("0x602850db0cc3370333a594ee5d061cd54988dd5372c04a527613055f2f88001f"): true, + common.HexToHash("0xf43709079331d02d5370680c23970b6f60e04a3799e71920117026c2a14fdabc"): true, + common.HexToHash("0xb71ff0859deed7a1dc9f3debd7a9d081ea2f7070f1a180488acda5ec0b5ea9a8"): true, + common.HexToHash("0xc91e301117bf50a9f5ebe8fdd14101fc1f58972702bafc2f4ba10f996db3c6c3"): true, + common.HexToHash("0xf9414adf03b9df0678ba2f9434ee5e771baa8eafad66ec7b879e168fb51027c8"): true, + common.HexToHash("0xed86a6264facfbd7fb9bb8598fd9d3a58a3608f3eae4377de91f3512de489ae1"): true, + common.HexToHash("0xdf80e3343b91700c754478bee91fd2921e4a749606b69ef567d6dd98afb20984"): true, + common.HexToHash("0xcade8b1ecf38024e948e4c364de9080043b9ec38a0c5cb8da36dd45512692201"): true, + common.HexToHash("0x773cc9ac32ae6145840fe37442db87d62e608b12ab28bea92ac83a2f00bc14ab"): true, + common.HexToHash("0x442f94d932e1e4734a71b387f3ffc90764c823c9e9774269cc67869dc21916e3"): true, + common.HexToHash("0x91128443b8dfe5868f5a6c4b8042d5a2193576bf101a301d50558eba56fb5fc3"): true, + common.HexToHash("0x4e14185b34b45eaa44b993a12265a20036ca2bcdbb39bdf9e8cb4ac984f97eea"): true, + common.HexToHash("0xa016c270044b6fb5a840a8dc353d52b452ef761ec91fc76421e3cb0a13f30d3c"): true, + common.HexToHash("0xb414c5843c0dd1bb922cb4a0abda74d69cfa77efac3a3bae6af2f0ba90b57e1f"): true, + common.HexToHash("0x7046a14db80485b3d77074bcb0ecede7696ca8cc6f56eb69bab6948450583679"): true, + common.HexToHash("0x2c0a8cf3ae10fc25540dbef4391d3e9250eb7eb69a352f6668b81f82896caa51"): true, + common.HexToHash("0xb4b93a867dfbd1bd979120a87a368b55335e88712d808b369d73a791e699a0d8"): true, + common.HexToHash("0x81fdaa0afbfc907d941316bc5bc47797c80559df9d890348f68634bc9cda3091"): true, + common.HexToHash("0xd861ab0afa4305af383e0f7773e445fdbd6179c98accf4dfc4424e7a438a02b1"): true, + common.HexToHash("0x098230976413d41cec87be1d2529c84ff53fa0a83e9f04d8baf034ec77bef02b"): true, + common.HexToHash("0xcc3f6eed7c457d9d727860896337dff4011190851797ed5b9ee4ac0036bae707"): true, + common.HexToHash("0x85c0e8d3b1d3555135183e77356dca7d3acf64840734470fe1fad8cfceec8189"): true, + common.HexToHash("0xe9f34adb69a9b432722b197bf31b398638815f021ff82537c68f3aa9eb449594"): true, + common.HexToHash("0xc806d720b3c795d0382da8365fc636b7d25067fc8948c8a08cc7aa9e46cff5da"): true, + common.HexToHash("0xbed1ae64248570034df31414cc48df345d8a2c1d5b57f22314fdfee2f81541b6"): true, + common.HexToHash("0x7d7ce8b8597f177f709fd3852c3a02830dbcbfde3a4cc41f5781859bd20fc360"): true, + common.HexToHash("0x1f98fe0e07fb255f403b6e20b33d957ede77e4417f8ff455d1dac1002ebd2e29"): true, + common.HexToHash("0x9fe313c11e7d30569fc1955272a9c4016b4fe391b020cc8ed79ffa203af84319"): true, + common.HexToHash("0x6a4b1e0a1b178be02253acf03085f18f1810a675c2d1db17e5c7ffcb0304e0b1"): true, + common.HexToHash("0xed4f1ffc7afbe66d4912b8f600536c29fd9d2801aa48029e327f33023b51a83a"): true, + common.HexToHash("0xbb31866d5b7afee3ccedf50aab3e4fa893cba77df52ac7080654b2090875b937"): true, + common.HexToHash("0xe3075ff688195e4e4f855b986643730fd95e2e6f36442a3f7447a81ef72b580f"): true, + common.HexToHash("0x6b700fb02ea5f619902e3c104c750869345126f6b00a36d37789d3bd92a68f86"): true, + common.HexToHash("0x4a311f9b2b4c82b818635f33c74da05ede58eeab07403a067d8e58fb472df0f3"): true, + common.HexToHash("0xcd971e803787f364f773157a765e7d6ff0cdf91f85c0212b3ba19a5b079314b8"): true, + common.HexToHash("0x3e7be9ac94607e9e91250fd161a00f25fbcdede81d72793716cd801075c885dc"): true, + common.HexToHash("0xfe4b2d6aa6c095bde300c20add4f6e39427c88b163a76885b20639722c5256e1"): true, + common.HexToHash("0x6512b1932d9eea9dd62c0b86b195941b0cb1acf0271853ca16387dc48c478868"): true, + common.HexToHash("0xfce2190cbd1fa28b4051aba426c2cdfe49a16ba38b69eee22aa5fcb1f8098a84"): true, + common.HexToHash("0x5ad6e6c6b230e62c588e42f969834f28558236037e2331d88a2e5f316d2aa848"): true, + common.HexToHash("0x260f6f660dd02012bbd1d599a8ffab4203de44fb8147ba0a5c0f122cb501b095"): true, + common.HexToHash("0x0dabcfbffd69bcb9020a258e26f3a81cc85fe768e3566205d7f2965f857ab89d"): true, + common.HexToHash("0x49045511a8cd7ce81b9f9485e21ef2112fc29d0d6b2085f195f045f72bf9536f"): true, + common.HexToHash("0xbe76a67b75c04368cf4761646e32789ce73c5ef323bfd7b220b8c7c659e2aea9"): true, + common.HexToHash("0x90703a23ba454b3d3a698452f5e3b9f5a7dfa3790ab34f119e1515a867c734ec"): true, + common.HexToHash("0x8e3b5e0169dd6fd1a30e5023bcfbb43a5dd2cedaf04732e68732018c0c41b874"): true, + common.HexToHash("0xdcf2c0e31a09de54e35cde68e3865c8dfa1fc5d1381a608bfa3661180836e77d"): true, + common.HexToHash("0x1b0a55a201e36e40bbdf3b2eedf538a55d7e95587d3e1796dfa447a400dca4da"): true, + common.HexToHash("0x3e8e4056167dcd78668042e1d8dd792872d94aabc08501d3c9cb29ae75b727e7"): true, + common.HexToHash("0xf7797481a92e462604556d3468f9e8413a6094b838d76e7b966fb5f5f898ebd1"): true, + common.HexToHash("0xf606acd282eb15d70da3daf791a793f5ab254cad9ba070946d2d373ee60e512c"): true, + common.HexToHash("0x4089f2c2e21ab0824af40ce15461aa065b05569140832d13a3e3698af6d6d86b"): true, + common.HexToHash("0x91dbd6d84905463a2e75caa9d665d5ce6c4bd0489820f636240d50afeabdadb0"): true, + common.HexToHash("0x6882b7e93e5b0b898768ed0a5115b9e7ac1f8b74ae8688fb0b3c115a8062f2c2"): true, + common.HexToHash("0x18a4a724f87945c817020d3672acd0fd518e4758cb1c5c6c6924d6fb47bcd1c2"): true, + common.HexToHash("0x67f1cba2ed9dffb2c4967a2ce581af6c98f296637e110de8d26b361f9fa44791"): true, + common.HexToHash("0x3b66730b5d3de9422e53b521d67b1c479a40bf169b2435c288aa5c1af63f34fb"): true, + common.HexToHash("0xa3358eeedd11201d2f05fbed47b81059f66e447141bd6f5de6d85b5f2e48c0ef"): true, + common.HexToHash("0x7f2dafecc7103eaf711ffc8cc48deb3c486e503709af7f0e9136b9fd4fd1c3bb"): true, + common.HexToHash("0x3ada4ef9b7dd2569e926b4bf35e7ffa637de7ff5a1558e3f1dbe15640d7c09ab"): true, + common.HexToHash("0xe7f79fabdd3b60b859e10789533352d196843008ebb6dba03f50c2a3904a3f12"): true, + common.HexToHash("0x493d2584eccab12eaf430322fa5ba5f42f4c1f720ba39df098469a50a6c9b35e"): true, + common.HexToHash("0x1ca7b67ac4f26b3e70d6898fa5b2941a2f5736ec84a1dc58cf3ac3782179febf"): true, + common.HexToHash("0x1d8b87f45e7815a24ec862a1e16bd92d46bb5b84a8a4e27dc9eeb63dfbd98cb7"): true, + common.HexToHash("0xf610297d5ca5cc6ade53a5cbaa43350893120c492958fd7755c9649acb97d672"): true, + common.HexToHash("0xd6b334692ce9c1571a06a7e1f90b958796d0779934491be48b35f11cd50d779f"): true, + common.HexToHash("0x0feba223d57e3566f0803ab91a50f925f1ac06064a51a9a1e5ed5e29ae9ca839"): true, + common.HexToHash("0x4625985b62dd6fec2d8faa0a4cb7bb37ad28e41ce668c95a84149ca246d8541d"): true, + common.HexToHash("0xb9f7666076d7b21dc9638bda8682ce9684a610a2a6c49773bc87cdb3e7fb315a"): true, + common.HexToHash("0xe87fe77d6f505462be8b4191e1a334a8e5294f4331c7783bf43e98fd95fa3cee"): true, + common.HexToHash("0x9a6f5bb25c50567d168956303faaaeeed776965acafca5599ed306d873199673"): true, + common.HexToHash("0x1e9c0776de4c0c72dc17d038ca9750d571ca9fa6d99335afcd56c52d8fbe87f8"): true, + common.HexToHash("0xe5e54adbfeef5e9ff1a2849f130376a51efa8aca63e5c54f0e972d15a00fa700"): true, + common.HexToHash("0x92acc51767e925a9cc5d6fed43fe5c5c18e6813fbe5950743ac8d3a81a40b774"): true, + common.HexToHash("0xf47195565bab31e559261ef2ceeb9078acaddb7457709b426b92424908148700"): true, + common.HexToHash("0x0fad2de84d4aeb9ebb30027fa5e924ba84d6b3ee6401518f42978bd3d07a4df8"): true, + common.HexToHash("0x1672b02ed756d67898ca3043efcad1e8cbcb52dced0707bc4adde4cb32d2daad"): true, + common.HexToHash("0x01c722837e51a53636c594d25030e94fd3c533f2abd267c8dd1cda587e598d31"): true, + common.HexToHash("0x68e9b32274b30e1d2cd8480d9ee1b75c57d81b9982674d2088328de283fbeb26"): true, + common.HexToHash("0xbfc039ab17c9b0e3264c8e067c3b85098a7090942ff3c14b97eee3b04fbfeca6"): true, + common.HexToHash("0x11a855760a243ba597d45ed7d8e807f84cd48eca495fade505875170781b62f4"): true, + common.HexToHash("0xc870be7bcfb8d6692acbe5546e852fb7856f0c2dabfb32c6b000f2f7f3b96006"): true, + common.HexToHash("0x5bdf8df356fdd9e4029618b7ceea39b000a01e1d4008a73ebfdccb3f3a8bde32"): true, + common.HexToHash("0x2249a9475148a2bc5fc4f439350a9039321b13e13e03fa632dc36194721e4d56"): true, + common.HexToHash("0xfc0937881d096aa30610bdf9c3063360d727494da9221dad81f6c0677f99c322"): true, + common.HexToHash("0x7123aa1b3db83aaf6ac029ed37fe4649d2ec08bf96c14d217a821224e9d1d4df"): true, + common.HexToHash("0x7dbc7090be652dcdf93c9aac553700c03c3602e690d7b4c4ed726fe6a45dc1e0"): true, + common.HexToHash("0x870ef6a08814d6588fd2fee17fea5303ea43f54d611207de72b8d875debb5a79"): true, + common.HexToHash("0x67def45ac716e72843ff3d3ca1e6a505774ce97f264b9b27932f6bce4288a2cb"): true, + common.HexToHash("0xb2130b025033a08039b24111a28913f1b784ce18702ee161b96d06946bfaa870"): true, + common.HexToHash("0xd110783ab58e1154d561fc9bcfa01633f2f5b3b85090f0a7313d9280768c5f36"): true, + common.HexToHash("0x86721af56b15dc5a2d90816c60df810d84453684c19c9dd45d65c4be8dc71c6c"): true, + common.HexToHash("0xf9bdd860be9eaa63c0f11c26daa5cedbd91a937501527c7ee00b11308c71ed88"): true, + common.HexToHash("0x9a1ebebb24f8188def63fed7a480afb0014da0687ce799de3fa3c7143d22bd9c"): true, + common.HexToHash("0x65153b420840f521088919b9bded8f8f169f30da2df48edc1074f74153733298"): true, + common.HexToHash("0x410511e66a15a395cf2729aad5f7dd3fceefe015b77b33f5d803a923f7fe532b"): true, + common.HexToHash("0xeb688aba2a4fddc005554b727231f94c3e31d233120fe097f3d720730b351109"): true, + common.HexToHash("0xf30d482c334950e90eb758494ac2a71c3848589cf38a2c1489c9a5d8b9ec3c37"): true, + common.HexToHash("0x989b9f0ce4f5c81842440cdd426139cd7570fd2ebcc67097da6d4e31e2534b7e"): true, + common.HexToHash("0xcffc550c42d26a194979864b947785732dee48b21fc4de06e2bf04efe3c68a84"): true, + common.HexToHash("0x4fa11719371a5cbb799f0688524204e054d35685632cfccca15dbe57d62b933a"): true, + common.HexToHash("0xd8d904ae0efb0987c5a048c9914257e61cb3f3675c7d31eac6bd62b2e4c288d5"): true, + common.HexToHash("0x6876b46aff202c71efd9306edf480732790f28e4e3099f7511f32492792e46ce"): true, + common.HexToHash("0xa5ab837c1fda725eaf5518c6bb814ba6a03eeb39cc72c67450365194a732be8a"): true, + common.HexToHash("0x992d4f7dab7e37f9de12256bd8cacf3f84d635eb29883fdd95bd346d18adaaf2"): true, + common.HexToHash("0xb0eb083700863d8925003ca7b650c5733e0333a2c7e6594beddbacdc0ba5f948"): true, + common.HexToHash("0x40df9b56bc4081c25eb1a49fcc23de20baae2db1d82d312b238d2fdda8f6e766"): true, + common.HexToHash("0x0e125d233ac6c12c772f1029d66032be0a45b34f7771f3e3b2a2333c660adca0"): true, + common.HexToHash("0x53c002d80e4f168cf7a7d9af00f60b4b464880e286545c1a5cb81be391845543"): true, + common.HexToHash("0xb3609bc2fd3aac2ad3d70780c64e6b59e310185942a56a2c38c4e446e58434f2"): true, + common.HexToHash("0x2ca92d3ce8573f80a9418286dfcb53e7890483a5bfa6530af84875a9ba502485"): true, + common.HexToHash("0xcf9248d718d5acb27ed2c8fe77ff4ff74438492a3587e8f2791e5c6bd656991c"): true, + common.HexToHash("0x60b2907071214f19bb3c5f9ca9e46eb5e127ded7df16b083cde780c5d45786b3"): true, + common.HexToHash("0xddf99011112d40922d6bed12f716e8fe83fe1349116127ca39f28f425b39bcb6"): true, + common.HexToHash("0x90fd2de39e37c9e86ef0695fd211e7eeeb4554ea65b49b913ae6a552278fa731"): true, + common.HexToHash("0xa3d477b3f98b211a04ff7c53779c23a784d34922362367126da406a66bee888f"): true, + common.HexToHash("0x9b1ed0feda68b634bd5c28b179324ca4d5357b9397da60fe6d5aa5853e976627"): true, + common.HexToHash("0x1fe72f06f356de5b7aabb9fef8bee3915a4895e97ad394a8546c40ffe4735896"): true, + common.HexToHash("0x399707275e97ba2153ddfdfd7662bf5572badef91f4d3ab9fd1df3f671ec4f00"): true, + common.HexToHash("0xa448b9ed6ec25b8dbcbc57de086c9efdfe10ea88681cc3492e39590bc0c8a208"): true, + common.HexToHash("0x1acb69effa3ceb117f13c74ca893a96e7d4265f5a5b0b5925f3f34bf21864b54"): true, + common.HexToHash("0xe92685af3e80d3b73384763b033e8cbc08c3ba6bf89bd9f3a94d4cf2843af4ad"): true, + common.HexToHash("0x8928183886c0d9508f3af21f4e0089dd63aee554f637e050a8894d7a1d322e38"): true, + common.HexToHash("0x28728d4070bcefda5f8e861b85b5a084e2ece3b5ada831b65ebfff63031d67c8"): true, + common.HexToHash("0x468cc3595a72e9678e71ecdd2bc94e4b0c20c35818f32fc38843f9d03311a93d"): true, + common.HexToHash("0xea926ee320df23c8720e068916fe9680ca75864fbf377ca5dea40b68583d62c8"): true, + common.HexToHash("0x453c77a4365104fbffd269da557d9296f6a8a5ce50006ff3e529836bf98502c9"): true, + common.HexToHash("0x0f52714258b1496e067efe3622912c54634a60339816a018b1739c31669ed8f8"): true, + common.HexToHash("0xc16982e01e890cb1dfc0eeb0084b9b87b77479a2d46fa07f5d320af2500d5d6a"): true, + common.HexToHash("0x2537742c658387288f34c60617bea39c6d4ecb740bf9d7436fa47c52d1fb713b"): true, + common.HexToHash("0x677f7901f2113b26a7e0db9237c6e46b533f8a8327988a2c6e77d66dec1d4bd1"): true, + common.HexToHash("0x41abe19921b473cda20b4a915acddfedfb756da2ff8e7d6e8c1ad8095bac6d41"): true, + common.HexToHash("0xbba491a1b89cc1701d0e254f2e611efed77039f481716ef90fbb9726ee57811d"): true, + common.HexToHash("0x56124c4615d4ad7791504aaa3f9fb6d1f4696d7d9b74c948675dc286551dd8f3"): true, + common.HexToHash("0xf452dfcf1fd910cf7aa6ac423492e7ab1ef218567500b1d68a540cb01057e1b2"): true, + common.HexToHash("0x3ead5e08e994346a1b82b4d10f463970bb704fe93d371ad890b96d82dcfa0882"): true, + common.HexToHash("0x6b24eeadd90d18704e0f83f7db5b4a9a5bf2f619505bda91a8e18ae4d0fa2700"): true, + common.HexToHash("0x4dab77d3d02818ca74b54266eeb6af721928e384d2395c80a676942cfbc4cb25"): true, + common.HexToHash("0x4cd3b4d9aba39b7b4efea9c5e0f3e07e723c2388447d5d2ab1c8afc1fd9ac14a"): true, + common.HexToHash("0xc0010b158b4fd0af66008a5f84c267ce027104fc64f928973511344ca71dd595"): true, + common.HexToHash("0x07ef969c5280b17a1d00f98368519c0f9d4b75b6ca139258a5ad453cd617b884"): true, + common.HexToHash("0x5034fc7000d6a684bdcabdd1995c87b36e3bfa68b51c61c80426a957dcff585c"): true, + common.HexToHash("0xe370cc294ce48451dbb4262d98875e43830a479e4b91038921ba062c5d42ac89"): true, + common.HexToHash("0x4181e024f339b9dae0909042a0ee209123ebc37b01551937cafe5b9866d341fb"): true, + common.HexToHash("0x73f2ecb554a4bf64ce1a8009eab16f03b14a13cc71d0908ad8b1632f5ad2b21e"): true, + common.HexToHash("0x69047c62ec3850af4d4515a8660e5e64d65e3d451088ed6b096ada42527d3024"): true, + common.HexToHash("0xa446e3a81ddeaf3b33fa816a5d939aed079ddf1d8f01cda87ff4f207514da5cf"): true, + common.HexToHash("0x4cdc6c2025f739919e4ad7820defc7a141806cf430031527569c6edf3005692e"): true, + common.HexToHash("0xe45341ac776355397d5c9fd438d795c007c6f10d4dceff4cfcb3651221fdced1"): true, + common.HexToHash("0x8754ed0c8442afbeb2bb2127d0f2b30a938bec60dde74cdb2ac51cf11f4cbd30"): true, + common.HexToHash("0x64234f8298dcacc9641f5d985cd017130ba154a8f6a035ac7ac8d361cdaef980"): true, + common.HexToHash("0x33dfa8984b962bac5e4a17f065389f2eba65f0b1434273d2edc20287d5860241"): true, + common.HexToHash("0x01d1954c120d611d7edd1088e65ff8f43050cead04d4976b50bdc983565389a5"): true, + common.HexToHash("0xddea45ca90b955fba9a46aff66689b7b853fbd8fcf648798c1f4054612ea9964"): true, + common.HexToHash("0xc04db740c1738198ce30fe57d375bc7a5b6ddca6db2e9875837e14483aabf6b5"): true, + common.HexToHash("0x1fef17080bcea396c9d3d366b2151c5d3571950107c7b931cbf99affa809fc34"): true, + common.HexToHash("0x3938e8cb0f0ae9cc81e93c05682e11d169e75682f34dea7dca27c1a4b07d519e"): true, + common.HexToHash("0xcd90c9e6eb6940d31f15732dd4ab9c038ed631813ee0cc470cfb5f6989e1bfbe"): true, + common.HexToHash("0x9381dd8ccdb25b59a1d5ca18471c9abbd624feeaa654eb5f65494dbdb1cc73d1"): true, + common.HexToHash("0x0da761c369598f1b2771fb41e8862332ad641592949d779386e63f0bdb6985fc"): true, + common.HexToHash("0xd8d63f59afef3fba94732e0914c50e5ba7c51e11c49be9c8770b2780b57e42a4"): true, + common.HexToHash("0xc19dae29d17d2ed42cc4545517264c46567df2e9e02c9b027630939b6be13c28"): true, + common.HexToHash("0x369fb18be9cf44d6ba929634ab1e23a950fe9fe09955711ded0a12c943d5c75e"): true, + common.HexToHash("0x7179f84ac71dee934f3f7765e1a6a6640c08869fb3efc4ba29cf28fb4fc1b1a0"): true, + common.HexToHash("0x941e7fd5ddedebf5933358f6a7d15861c3f24ca45bc13decc6599b38d46082fa"): true, + common.HexToHash("0x0649026cea10128770d236c9ca4d6f353a4b99d7ff37995b14d51d8199e82785"): true, + common.HexToHash("0x3b75e4d6efb05fd9ec4c92adc96dde4a9483419c0418a83d42ef865b1c4d9014"): true, + common.HexToHash("0x597dec1af7c6b1d4b40858ee1cdc90f56e7fa1cf0dd21058ecc5220f33d852da"): true, + common.HexToHash("0x7d4c3b1b140172a51c4c5ccc7d27debc7e57bc98e29196600e62d5e6b71e111a"): true, + common.HexToHash("0x818d754b5b30ff442f2be2c554080f39ecd696c8c6e269310854ccc56ebda843"): true, + common.HexToHash("0x5749852cd6b578cb6af85c357aa95a642ff5fa29ef71fdece0a3718062476091"): true, + common.HexToHash("0xe0d4d9708385621ff3a252b74e0615025cd66267f2d4c00737ba359faf4e27a3"): true, + common.HexToHash("0xb1b68bc91a9cbf19e3c1f9e01c3f8df362e682f92d96bce80b022c3b84830827"): true, + common.HexToHash("0x2d8183591b99da420801ab7f1c202422bd8a924ebb853eb0d40ea2900909accd"): true, + common.HexToHash("0xd1338b21e76500b5d49dbd2a59c9273cfc9b835a4426ffefe7d80b3c2ed06b64"): true, + common.HexToHash("0x77db20acf557890ae53ca3ba5cecf274b5cc1cb2ab2711a7460bdf181c18c437"): true, + common.HexToHash("0x1595ad2467ec4fde165c83fdbdcee1a3b8b9491ff389a98b91a32caa4d08d5f0"): true, + common.HexToHash("0x507205925a4e2c7f72dee7a082ba0f0e47b9d67b97025c4acffd574500056c3d"): true, + common.HexToHash("0x13a11d812f92fdfe8c0c7c93ef5c3da544d0179c66fc21039086f6c96802531e"): true, + common.HexToHash("0x1c9a07eb22240ff863d36b28220c23560742c0d228b3fac0e991167ad3ae7070"): true, + common.HexToHash("0x7f8dd1412f30a119b7d60de190c59ff5b4d65e9e785d93039ee2ddbeb2870062"): true, + common.HexToHash("0x538170924790403657d8feafd148c4bd2546b1f8d08bef378e3b98ab61337bb2"): true, + common.HexToHash("0x882c0003cd9133ae405ff21a5dc479d753f89a0acdf6412b9ba1fa992f28d075"): true, + common.HexToHash("0xa8a13314d9ee7403ff4ccff8ff98480f166c48ec5807cd6cc1c1bfdfdd91b4ac"): true, + common.HexToHash("0xe9ead699fc4723c5718804bb8ed87a9dea221663cc27a52535c83c7e1d505342"): true, + common.HexToHash("0x41bc72e934bac32aa9f28cf865a9ae5f1dfbe591ac281e430b1003eb05d207fb"): true, + common.HexToHash("0xe3de77f8e105dda325d59e21964e4a32edfbc163e495e2ce1096a89d514e79d2"): true, + common.HexToHash("0xd03265cda3034668d4bcb5a0c0eed824002d515b5d414806489189fb8f99a879"): true, + common.HexToHash("0xeeb9c89803acefddb806f74167b0e3c57cd1d3bc4a58153a4bb296888f412369"): true, + common.HexToHash("0x44d7d8b68d83ad478029da24b4eb69b3edb213e4994538227e94ad18cf11398a"): true, + common.HexToHash("0x48adac52a80c447730d71274002d522c4aeaf4ee50ee608e330a867eebb3f189"): true, + common.HexToHash("0x5f1b221016ec8227ffdd64e84a00c7b281fca13c2ba6a6eb072ce483de2073df"): true, + common.HexToHash("0x911d12b86c06625ee631599f4e8558844b36a0a6d4c46e977f41d6d62a5a5e80"): true, + common.HexToHash("0x79ce41b9359c82c24d0f3e79c15309c8f0c8ca6d48c6ff82a5bb137b1bb82354"): true, + common.HexToHash("0xd6c51c3403a05860506d390b6cb59eab5e6000da5211e87acbe4062b259aead3"): true, + common.HexToHash("0xb4c1b637bacad4e6f3ff186b57ee262d1d508f1570e7262c6e2d508eaa369e54"): true, + common.HexToHash("0x73555567f764992d258ab1cfa3c74279adea842927d6f45383ac48960ae266d6"): true, + common.HexToHash("0x795918c208f9a27d08a71d9a4d3a29a3445e92394725a5344fff0b74158aaa13"): true, + common.HexToHash("0x37c8d6250bc625a38a96da764f56ed5533b4c5cfbae7e99937471bacaed0d8ab"): true, + common.HexToHash("0xa21066beecdf6623e58e2f8d71dc66bfd050b5847354a28e20ffdab2314f1c93"): true, + common.HexToHash("0x5bb113e87b0f66f6db3a62cb3d74ff8ed2797176760c3c2c5b491a81a1152062"): true, + common.HexToHash("0x30e726208f3a8266f768ed86109b04a22ff8b390e508315822cc4e1e939e5e02"): true, + common.HexToHash("0x5037c92c5b6ff295be2d83a8a7f05ef1e7d40b3d0fbcafad749529d2dd2e5fa8"): true, + common.HexToHash("0x6675c5b8c160dedfb6439a20bf74a532a7cdd6c2befe766f7d11dfe8bd84a0f2"): true, + common.HexToHash("0xf6d02c8daebd183b11fd58e9df28c9c04b2419f1e88f81b877a132668361c6a8"): true, + common.HexToHash("0x24c4587fb9a5a8ec66cb112e1162ebe483ff7d44f84c7461252f8eda7165ca74"): true, + common.HexToHash("0x8fcee3dbf3076880c49d916fab2b9aba43a0401d59b1c274384d29277fe33e04"): true, + common.HexToHash("0x2d13e8ee71d88bd0fb237e67c4754648fd3c01e49cba5cac83f530b7c54333a0"): true, + common.HexToHash("0xfb772291809fd35690d42dc813ef73b934bac6825da05f63e74f28211ddc34d9"): true, + common.HexToHash("0x741313b3f5aa05930fef726a5902ccd79af59a65bfcb8e47e424960e39cc6fb3"): true, + common.HexToHash("0xb7e384b2ecf372b2870d23859eef5b808528d8460f2b83c24b64f85d6a413162"): true, + common.HexToHash("0x38a6f57844b716ed5fae2571014d1b35c08a04a7b175524b53b348e60f3739b8"): true, + common.HexToHash("0x220aaae8bf020a3ac963e944f3c5d4684aedab74f782a8bb2181fd060de4ef5b"): true, + common.HexToHash("0xb3b9817a7352cb3d6fbcee8453c99c3aae3c4cd9721a13810514efa570fde9fa"): true, + common.HexToHash("0x41d95f539c505ae2769bc05593023d7d9c44760b6a5185fc56768791041e430f"): true, + common.HexToHash("0xbaa817fb822569dc8cd5851cf87f85a45f82119509053b9c0558d08f29306647"): true, + common.HexToHash("0xb8a57691cdf5c6cb7b27ac033d88e1368bfe9dad784e1335838266b14294d1d5"): true, + common.HexToHash("0x524329d11ddc6fa43a66fc55ec2602d6d123de0c9a99b4c9c756db86be3a5a6b"): true, + common.HexToHash("0xc6b704efc499a92e32aad191957bc35d66295b43b33c6af26500c554f42e0b06"): true, + common.HexToHash("0x2441b3a0b4a38ff20566bc6a980fc1ba4e5335e268f21637361649cce5ece21b"): true, + common.HexToHash("0xcafeaa73edd48b53c3b5c632e3763f305c8a584eddd0b38fd26e18c87b148290"): true, + common.HexToHash("0x21b635d79a078dd3c9d0b66746370f221666f44dcf3a49a96e31147d96fcb294"): true, + common.HexToHash("0xc48c5ed1ef272617f74be838e1f779b93bca6be1883ca5ab9c87acef31995df6"): true, + common.HexToHash("0xb443a87801ec8dc3e8c1ae9202cb2ed96ddd36d15ba178a245a42667ad4cf67d"): true, + common.HexToHash("0xd0fd62b9bc3776e3584c3c8978e5d3541951aa2410842a018741882ed0f91530"): true, + common.HexToHash("0x39c8fd919fe95b4979165719dac34ef9a591db248b711b6d27c1b50f4aa52679"): true, + common.HexToHash("0x95c861b60e29061e46134b9ec5718fcd79470f59b5e0981100e174450dab6b4d"): true, + common.HexToHash("0xfbb8957fb8e9b9b796ae1c7660eddb262b6f971cea8d272c9e4c4ada9dc59de0"): true, + common.HexToHash("0x963d43a706ecff40ab4322430b45bfb36efe160ceb12a453146e0c5e582c133c"): true, + common.HexToHash("0x057e6022d0aa28e838a4a9bb3941b5ec7373c73f4718ab1fb25fdf30bffeb2c5"): true, + common.HexToHash("0xe124a22b94e826a7c72e551b2550507730dd07b772def8bb42524391d3ec63c7"): true, + common.HexToHash("0xff1d5f0a4a323153d3a7230cf63811e8f89102824078c9cc61e2b05d482c1a4b"): true, + common.HexToHash("0x088921e91238b6d721ac4d7afc15ae21511add87b69f7e98e29f1f142c8248e1"): true, + common.HexToHash("0xe14500a282f58d6f62f2f6086b765240389d4c58b7d350c46f7e21ed9d516866"): true, + common.HexToHash("0x73619e3c4c5ab113a52cb8bc12c1059b3611dbd5d407ae68418bfb6581ed1908"): true, + common.HexToHash("0x0b497ffe6f863941bea54002206b9a10185455738ec71eb12857294dca3b5e4c"): true, + common.HexToHash("0xebacef6cf07663400a0a597ebc2ad2b404affb2799e55df8e1f88711dc5cd9ff"): true, + common.HexToHash("0x010696d4dead58e2870fa5b09ed517ea99d3753fe8afe4594467a6a9c206b172"): true, + common.HexToHash("0xa10914122865d7a64c723fd611f9547687fcbd8234269f4e51e2ae65fd0d27a8"): true, + common.HexToHash("0xdab6f3d8f2a3f3cdc5d7ccd12b6a7d6c9523b1bff108c86c197f28513fe9cd49"): true, + common.HexToHash("0x3bcab219cff77796d0a4016c08a285d045092bbc6f6ac7ec9792a9c86696fdbc"): true, + common.HexToHash("0x2c91d4f367764c54b76fbef3a0408f033b3ebb18cbdd15d200fd6ce3448cf021"): true, + common.HexToHash("0xf236b867a5d12a9548c9d869198cab832b84a2e5102e4110889ceea1ccce51e0"): true, + common.HexToHash("0x96b0298d0e3daaad4a0c0ab878d7908cff71033b56b9dd22d9cb931f5715a190"): true, + common.HexToHash("0x68e4c667b0efbd36857ddab98c8401f76f595ffcc2b5198dae8eedde26db400e"): true, + common.HexToHash("0xd72658fde6c0f01a375440510ef704ab1854b61b162ce0f39fa1342e23deb48d"): true, + common.HexToHash("0xa91f1374d94424b1af7c67b36ffe509c88d0b3cc3cec3ace8e3d5d2e5f069802"): true, + common.HexToHash("0x9a1874ea29fd6f109aa80b2c77a744727948b05b02402de7da5de860fed4b4a3"): true, + common.HexToHash("0xe87a1b809532fdb74306952d4509d17ffc6acb75219c9acb38097f1e3a2b0da7"): true, + common.HexToHash("0x5ff1c76a28f53a5bb34d8decec4219e39c4631e7aea6ebde55d4331cf0cd6741"): true, + common.HexToHash("0xf341c38a0e9eb1e9a98bc45269af0aea0e9202eb221cf1885fc6dfc812a0666b"): true, + common.HexToHash("0xa1a9bea545e348554505eabbb31deee1c78316fd0e1be5164309b54f291ffcfd"): true, + common.HexToHash("0xcc14ff2a268bbeda96b3ec5cf4f24efe57368128ba440ddf390bc22d85ce31ff"): true, + common.HexToHash("0x14d9c15c024fcf06ceec23d3c7af22706e3e9bf211324934a922e8ed5eeea7ac"): true, + common.HexToHash("0xd66a018b80aed70ff7fe9db064f71c9bbed7b564442685f4e603f84b52c0b64f"): true, + common.HexToHash("0xe791793191914a7e684a74c7f16f14b82e4a85382e4c46d8989b2aa4cedf4b36"): true, + common.HexToHash("0xeadb6a65bfd14c106fa8fc6887a7013e1a4f7f7aa2bcbeae356c02ec5039a43e"): true, + common.HexToHash("0x3cf056c536c054d8031392e7472dcc545ec98c700fa453364ba77589403d9a30"): true, + common.HexToHash("0xf2d92285b3eae95506c05f6fcfffdd9adda0cb4b8336651e76b4c3d87f8cac48"): true, + common.HexToHash("0xa9f648d9e193a37e56d8f6a72c2634d9ae11baa1b8c910c2e19bb1acac5fb1d9"): true, + common.HexToHash("0x91ecb2aade2c602839f8a845279b0394695eb203c7f0945560e1c6a81c685473"): true, + common.HexToHash("0x49db3b9354af7a1aa20e3a238c63310f05e032cf4684eb000a926d909e4d5653"): true, + common.HexToHash("0x409f61ca9c890ba3c7f5210d4c874111d9fabde218dcb03be5480a16ff66e4d4"): true, + common.HexToHash("0x0bbb90ee763eeb46dacb0bb06b8a9bcb3ed12827f8345ccd19b83098d43c996c"): true, + common.HexToHash("0xd118d27fbea0abab81c0f929c6f228c789a3be0972fe1cf2124c3fbcefaeec24"): true, + common.HexToHash("0x5bd81b8bbfe0d9d47ee036947db017cb16b3f765eb8acfb287ee298263aa1754"): true, + common.HexToHash("0x88bd2b561e277e367f19b9a1f26cd1e23b6bfb84a4c6cad817173ecc206236c3"): true, + common.HexToHash("0xfb906d0bb5f4a39700eb95f88c0ee4b5425e5e5df5fd110594e7a8bb3d448cd4"): true, + common.HexToHash("0x6260f695b3cfa2405c5b38b56bc90824fb32582ef64dadb5b01d847815fdc2c7"): true, + common.HexToHash("0x127cb6532e67c4a81cdb41fb53d525b5308617863db69c70cbcd3ec4a1363043"): true, + common.HexToHash("0xfa6993b37dd7c4704914e36ce8d972181dbca16b3ea17cca359c43010be3f51f"): true, + common.HexToHash("0x9f240fb321f8ab9ca2d927e5dc441f73ec96976f5b5096390b969a52825c2bc2"): true, + common.HexToHash("0x3561a1cd66629fe2afb06a4980dfd9c89956880a32af88e4d5881ba0c3725b00"): true, + common.HexToHash("0xa66fd92cf33b850920a99c4eece5fe9a6da3854c839b60eac828e82e96a2acc4"): true, + common.HexToHash("0x96dd9268322fca6132c6ba4cc3055835f08f8be27982a96aab754fa1b0065f3f"): true, + common.HexToHash("0x9fdc48513292379234bc9c24a59efeb0dabc729d73242b8bb282b6789b3c14e9"): true, + common.HexToHash("0x245427c21ff288a8d315e6d89ed6dca4a68f0cd33b885afacc890be67f902e05"): true, + common.HexToHash("0x625a9278bba0d2888d09da9541a42d9651ae77abfd15f5bfba3e5f42e158948c"): true, + common.HexToHash("0x23440f913c8db17ddabff4cf9135da6e17d611de6bfdabc84ba93265fca36927"): true, + common.HexToHash("0x5ef40dcb910b3f0e1de989edbefcbe3da56efb350e3beca0a2ec54ff1e2797ef"): true, + common.HexToHash("0x515c71578c50a4690a3bd7e89cda0fafb6b94ca10becdfc0f34e65140d888d8e"): true, + common.HexToHash("0xe0809c58013c425565e9183d030e982124e90b7fab2783e0ce6b1e9da271791d"): true, + common.HexToHash("0xa93ed73776be6f4598947634e490e3aa6e79d16ac35050bf21d6c56a36bc8aa1"): true, + common.HexToHash("0x3557a1de959d5d4629929632ef83c5d7099d7c776220a0928e73d3b6c57d5c61"): true, + common.HexToHash("0x3ea7a83719eb1db686f5afad381b1e6dd4cc79e51315f1561171e0330158f4d9"): true, + common.HexToHash("0xd055ebc5231fed90b8e037acf846805bafb723bf124882c4406553a41c7968b9"): true, + common.HexToHash("0x21167756e5e0c6c3c5edb0d1552058f0124dab4223ea0937264213a500fbd4cb"): true, + common.HexToHash("0xf9db56e513204f147414c67484a1e7bd2e00813d5f8b7290b9dad4f31f779156"): true, + common.HexToHash("0xd10d52060f83992776c5dadad1ccd081903d155d6530a064b7f93a1ffae49771"): true, + common.HexToHash("0x4787cd4ae73072558b6110253619adaa6dadd5b6ec99b2674a85f2a2ae8db7e3"): true, + common.HexToHash("0xb75c8283ee92455017c26be8ed174b937ca0ac638e4d2a370f12c50fe31275ac"): true, + common.HexToHash("0x85c5254e6887e7391800894dd5f24c9e9fecd2c66bba7bb58320d75f1555dfe3"): true, + common.HexToHash("0xa874cee9b60ca4d1ed2da909a48e8513803be780c8e97b733e1a007c83a33d11"): true, + common.HexToHash("0xd003ceac886500db13428356fe005f267fb1b6891d2b48f4b90938d043fdc9e3"): true, + common.HexToHash("0x4cf1e0511a80eb3dd6f68a59aab9ac8629e55a38a3cff57df96305a665520f6d"): true, + common.HexToHash("0x12963e19647be0d316fc1e3730e4c29d12c8d3a4aeaf9d7db17d39255e6b8eb9"): true, + common.HexToHash("0x6613dc65fd673e05eeb7e82afeaf1e30927156a34d56a996921745e01073d0bd"): true, + common.HexToHash("0x3d2e752aea441594a5b2b32b54ab88cb45ffb15a2b7c36d9c0e762ca4adca7ef"): true, + common.HexToHash("0xef61dda40bbe42230b7cf4e69ae6dd9778d6174fe60795d109bed1339f9a2276"): true, + common.HexToHash("0xc9901161190a0f72b074a92d7f07f3072deed809507b885d795b8a6978f8fec6"): true, + common.HexToHash("0x8c352be6ccf2e784c7727fe8d954bcb136d405bf9ab5ed64c3359b723b4c45f5"): true, + common.HexToHash("0x3561f6463cae6eabf0b0ce68b35a25646c4b83a067959854718f7a2ea5ae9497"): true, + common.HexToHash("0x47c7a3f1b99c7885127f43c0b20f342688c03f632b21d8c86cb3f1103e12d854"): true, + common.HexToHash("0x62cf0a480175428ad8eb436ffbcd053b088dbb4f1e3af97232bc71185586b485"): true, + common.HexToHash("0x8145b15e5c91c3d34a193cbcae0dedc528b4524d7bd63b27582295f94c5f84be"): true, + common.HexToHash("0x4c6d8b52a16e12404966f6c6275c87fa5a65097c362977bfa1022d0dc0105c0f"): true, + common.HexToHash("0x67944ff309d29734f09ad39afb09556dbdc6d05385ae615b85b16ad2978f0723"): true, + common.HexToHash("0x4fa47abd37f5259e385b7745b80c64427bec162df0983c8fce19a24a6baa317b"): true, + common.HexToHash("0x22f023a8168e9f6384d7b1bbacab1d68c6eeed927e417a731999d1f63347281a"): true, + common.HexToHash("0x11b73ce67295edc8f1f3464177cd8f64b867d552075933ec47ed11000311aaab"): true, + common.HexToHash("0x928f26bc66eb4122a660ff63b2403ce962cf3a7c24750594cf4f6df99b69fae2"): true, + common.HexToHash("0x1c44cc20665f7d6d09db16a505bbbfd22401802465e006b68bd480b3444af3f7"): true, + common.HexToHash("0x0b8421ef049ffcda73ba8dafc818a5f72fecc93bb5843d33bd65b3bd3e3bce93"): true, + common.HexToHash("0x9c1cda9ddde09548449b2c256ab407e48d64485d4537cbbf74a3fdc09846cb8f"): true, + common.HexToHash("0x7124b49cd3100a81ca69a50f2f9c7c306a7c30b75d7bbbda3f87f9c14bc185ed"): true, + common.HexToHash("0x86b051393f94201c13bd91810587d38357965b35e408d0812dd3fbbf8a348649"): true, + common.HexToHash("0xee2dc6bd362c873567faa413ecbf1d6548c7a807dd20a438ab680af079803934"): true, + common.HexToHash("0xbcb35c8d40d51eff7d5d4b085a3948b1e60075891b2bede437b54524a6b48b68"): true, + common.HexToHash("0x97bc541c6d3f0f752ff5cfb16486bb2f1c86567629926806708a4605b361ff66"): true, + common.HexToHash("0x2e0ed54dfbc23ba9239fae57bcb9caea1323c8c91df63f8437ba3cdcdf00ef96"): true, + common.HexToHash("0xd89e4f8b10165082ece792eb6894535b841922ac1aba445e5e8a409ada6e73eb"): true, + common.HexToHash("0xc5ae5e31e3c46a61c0ed9a01b8c28810631f390c587f7afb7558d02360a95bed"): true, + common.HexToHash("0x5859a6698fbaf85e9eebbcc3ae6d4a9ea37df4e8bf14ab0fa4ad89d4eb82b701"): true, + common.HexToHash("0x404160bdeba678b90f232497ad7f1307b610e008a80485a4dabdde6f6ea678b0"): true, + common.HexToHash("0x2528b0e144e2ee2ef84d0b6492066396dc3d52b949a5412b23b5a885f5e7cc4b"): true, + common.HexToHash("0x7a10a296e31522feea6618ef28adfc972d53a5955746216a19b6b53d64868b52"): true, + common.HexToHash("0xe998dc49239622672ef4163912ffef8bf6849d7b7ddc5410557f4155879d5cdc"): true, + common.HexToHash("0x2b5a5747f4e8de7b1391bca3d8c36f880db7f3f10ef45617ac34badf1c54aa9f"): true, + common.HexToHash("0xcf3949d2d6aed5da6a232233691c43287835dd95caa62aba1d242b7d49c3e00e"): true, + common.HexToHash("0x74f6bece4f1afe4ca7e9a02755f00a1c0b58ad97ad1f824fc6f90c34fb72caa8"): true, + common.HexToHash("0x5fcde60c93ddd4139f76c6b38e87f6039bbd2816d4ede17f61742016c9f3d062"): true, + common.HexToHash("0x0f0aba3344e8c4742efa5e5b94afdcccc62fcc6c909a977605f4d9e523ad86de"): true, + common.HexToHash("0xf10bee5a921b0e46813d8cc68deaebcb3b6972fbc8ab35561c680f53c2ea5992"): true, + common.HexToHash("0xdc3131c5df2d1af6519b2ec4878bb8acd245620e124afaabcabe793293721c36"): true, + common.HexToHash("0xc7afa045db50eee45d0f7eda19842e9170e4befba9ac703e4f02d46c89932500"): true, + common.HexToHash("0x787a9bb0565f294aee26b4fa6814d4affc72060583d4f72baaf70ef997ea014e"): true, + common.HexToHash("0x92b7cc72c231f33ba57877c31533dba7445feae807dd41735417eb95bda5fd19"): true, + common.HexToHash("0xd2f8f5f4f0cb9e51040a56f60fb65b8520e26e47ade3f7c2509f00f92257bae5"): true, + common.HexToHash("0x8aec3ecc2ca4fb80a21ef9fe9392c104fcedcee0159a714ba238948e14cc6f1c"): true, + common.HexToHash("0x1e5d34388d7f7d285bdda913e92e7606188175179d85bde0be98faf46706f216"): true, + common.HexToHash("0xcdb39b8aeb903df8b7b183bb7036dbc44b4fbf6f5512b332e067974ba135f918"): true, + common.HexToHash("0x930ab7a48a8d98f4f7f9c04b1eeae43cf9b5f118c939eb6720e8cdf5f89c2bd5"): true, + common.HexToHash("0x38c36c9050e977569d3e3d79e78d285a094043eb5560b5c36e6cd6c70d4708e6"): true, + common.HexToHash("0x696516d218cc36e875886ccd2e3af5686ac0725349955f1b0c8b06ea5d5ea5c9"): true, + common.HexToHash("0x11f1e7b96b93f3723b41eb978db0e277fc94c95caf255b35a09bd1f8d3b481cc"): true, + common.HexToHash("0x8092d17967356f1213062cfcfe041203782f2787006571e872727f1fc3f387c1"): true, + common.HexToHash("0xa06f0819d0312dbb1c7159d603bf79cdce5d7780bcbd75f1cf596407c0f1b588"): true, + common.HexToHash("0xf80b75ea527d6e0781434a0d7b7c297160a04faa8d3f1f9754cda415fffa2022"): true, + common.HexToHash("0x45ba6f9e100ae94d7270472f23f2361838fe01900c6a09119c72313bd060a642"): true, + common.HexToHash("0x99728456a328639a902a70934fc07cd214ccfbadd7c392ef7f271ee0747195a7"): true, + common.HexToHash("0xd8876763cf14bf5e7ed86f892f841f452ef1a7ed809e333e837340930488e97a"): true, + common.HexToHash("0xdbc6674afb1531e7f8eebc24e3c1990e71a55d8bcf49465e1d431b58670584cb"): true, + common.HexToHash("0x530a29ea6bfba4a3547dbc152dfa2a6b6db6e51d0bf577a4babd169eafc5b44b"): true, + common.HexToHash("0xebb339131d70a6ee8e202e90028a4bf638182f7bb2368e21ee714fb7d9956ba4"): true, + common.HexToHash("0xe42240f4e898bdc5b6dd518eddb864293c00510bd4ae06cabebd413ee72f0d9a"): true, + common.HexToHash("0xee98d1d0e126a07e13e7ed2a527c7e757c0a99d1a283e0c9f9e3805906a226d4"): true, + common.HexToHash("0xea0de62990609bf35c8dc52a6dd71c4598f8987148ae9d56e41cf59d84b27210"): true, + common.HexToHash("0xc593e952975c3ceae0724f2c47aab7f62147a50bfe9599334b0b90e0bbd9f6c6"): true, + common.HexToHash("0x7b74fb48397a01bc29094b8da41c6e6bf5dc2d1be47a257972f2b1e177f9270b"): true, + common.HexToHash("0x7d354c781d61dda9f5ab1afbecc6b31c4d27378696f0aefe50312c281ad8f031"): true, + common.HexToHash("0x339385c0852056d5b3d04455ec1497fd1a3140532dbed8d7c13b777dd092e933"): true, + common.HexToHash("0x745b305723162aeec5e41038abd51286a069dfe41951ce303fe8a5697e6965b1"): true, + common.HexToHash("0x5b53bbbe7b69703c0a70c148bb6fa3b0dda74fce5efe1e64106deab1d8749055"): true, + common.HexToHash("0x3320066c63059a2f9d9a9a81ccb36fb84e7a687c7bbd66042b348f078a8ec8ab"): true, + common.HexToHash("0xbf7e57b188af6c0cca4debaccb85bff3fa1dc6152e51be142b74d2feeff3c5f9"): true, + common.HexToHash("0x2188c644c3f090a2a724dd20fa7d904aab59cf616953f05a0fda9b7f3099d9d6"): true, + common.HexToHash("0xc2a9d7abe9d884f5e982a91d65e5bc1c36ccfba52f936a30fbcce03ef44f052a"): true, + common.HexToHash("0x89542b52928e849c29ab6998facc50df634e1b9e81ce21a4352c28df48631a5e"): true, + common.HexToHash("0x9525736bd0c8c9ecd00f6819c4a3fe73f957ed64975c9e46e924525d8bfac66b"): true, + common.HexToHash("0xf0b13f4d4afb4a58badaf2b29c9c2e503eee99e1f6b9872004d3fa66e7e9ff0a"): true, + common.HexToHash("0xc4ba7391e12f2526305c35a7bd9fd1a4997193a522c7f0f06dbb983b77e50e8c"): true, + common.HexToHash("0xeb63e43dbb4f4a6f9399486ef0b407d8ffbf1626e5d47b05fb0cd069af59c36a"): true, + common.HexToHash("0x3705f6eb80c7445905addd15b875268ebe15278b53e58c9e3410732e85e96711"): true, + common.HexToHash("0x92a27df6d4d678fbedd03e75e73da0dd1a2493ae3c35948e3eccb77541fe8495"): true, + common.HexToHash("0xdac9096da9950b774ee6ab08ceaa549121f0106ecad5eaeae3a73db4ac136cdf"): true, + common.HexToHash("0x288ff0bc05b3be7f9128a5cf1de6e6b775723e568b7ee73b500936bf3f12388f"): true, + common.HexToHash("0x7593ae0f90b32f0b41507ea18635dc35c0c40f059a97016aede91ef78f253bb4"): true, + common.HexToHash("0x6ac60dec2f2a73935c9c52992fd8b24c2ba079a5db41009b71bbd03e9449e9c7"): true, + common.HexToHash("0xf93d5dc591435ed081d53bf9ad323569404c863f12736b8fe359dd2c1ede46bb"): true, + common.HexToHash("0xabc695898277d359316b239e8a7e0b59371de49b10ff41c8ea5158e653292352"): true, + common.HexToHash("0x2ebc89e0bde9b0b25eddaf489f3c805ca1d06ff2446e8d3e2c407157f7d46a52"): true, + common.HexToHash("0xd332277330c35ed0fee1577c2550abc06e2d72c7da6afe765cdd8941f2512f92"): true, + common.HexToHash("0x1b089a21765cc705f12b5d35957556906de663f5e710fd185a4fdbad432b3d45"): true, + common.HexToHash("0x69a28638667b471ec621964ef31a3dd1c5e5f4a80ad170c28d152b9151a52548"): true, + common.HexToHash("0x7c2a466d6ba30a24491236a982ee2122474eb241858a3a12f37452aa1589cbbd"): true, + common.HexToHash("0x90b5b461d324a49dc6e5b776fdcfa0d141d2056f3c44f241f6706e4e3208ecbd"): true, + common.HexToHash("0x67ede0249fae95544aa3d3bf7b77569b714e559b6701ea39db3b88925eec492b"): true, + common.HexToHash("0x2370f6782f60d7a9f3abf869b57b2a7efa4f42e2065cb7bfb0cd09d99bfd3ff3"): true, + common.HexToHash("0xf67e02d4fca435e35765574f120e30f8d3efdcdaf755e6127d97fc1e84f04f91"): true, + common.HexToHash("0x8878df70f23bf8fb61a1bb6753745ad6fbb407ab1320c2224017d531792a9715"): true, + common.HexToHash("0xfad5a37f1f6742044791e02d1b6edac984005903f665a68b7e95fdfe0ddf2226"): true, + common.HexToHash("0x701f5b2f0afc7150e4709ae809a7c5231639a8bc4c76d696db22c146d9113c68"): true, + common.HexToHash("0x07f33700615180ca178e07de11a3d61e60f6b3db6a7d9cf536047589aa97d649"): true, + common.HexToHash("0xb6ad246dd7d66eb45b8a003f6be218520c15105b6ae060a629c830c29cccd218"): true, + common.HexToHash("0xc9dfc9a196cea717bf96680f0a15f670d844a5d5a0759110c6cb7bda2f9eb8fc"): true, + common.HexToHash("0x1d913925323b053ea5b21720a398254c09fdadf28ce8b8ba691ef962943f5408"): true, + common.HexToHash("0xbe7e87a1e0bd0e1eefa1f5b17200f6e59e05e506d1df43fe96ac6d550d96893a"): true, + common.HexToHash("0x6af7a5eebb34facc25a974f558e485c2b887dde8f8b9ec5aaf91e2efdd9252dd"): true, + common.HexToHash("0x1fe7a137f675b1c3b88b990aa4532575a84553e2689a60be83cd2d369f007f23"): true, + common.HexToHash("0x67f65c81e7031d97e9c3ff4b296c0ca4fc8c1c63f10d16cffe5d8940f43c544f"): true, + common.HexToHash("0x5912b4c838c94292d93a756a6e9ea706a89995c3859bc324a64d5514bffd59cd"): true, + common.HexToHash("0x7ee96e3e206c317ea898667262bd95a24df349208d67c064ada94286e6683e18"): true, + common.HexToHash("0x134420480ba4aa3d87652d89f0863f618e86870c2bca36dccdab128edcd4793d"): true, + common.HexToHash("0x21129cc924a2cd34ced1cdbf76296b5310e46609ccba03e108fe0e3b2c99aab3"): true, + common.HexToHash("0x86dff65647a2b2fc0632a3e0eb0e6bf30dde093e09130c3eb4dc4c58db1f8d35"): true, + common.HexToHash("0x1b586dcbab9f6216a5d3bba39e1a517859b020f4d0fc34d0d1fd4ae5c09929b3"): true, + common.HexToHash("0x31dc1533cba4c5f7409a09877438aefc77f3fdfe7d2d26286393f66ed144a6e2"): true, + common.HexToHash("0xf9de8d9231dfb2d9945eede8df16df6f87e4c014733c5a73a2f5fa5317d98739"): true, + common.HexToHash("0xe7dc4ed031fedfdf97f4d42d7c7ffbaeff9b934ce74cee177ff30e7b7c7a3364"): true, + common.HexToHash("0xf7f1b416341ecc46aba65311a2f03b4fb7e5714c06d94cec89556a9994cd040a"): true, + common.HexToHash("0x60d50b6a302b9a98bd599927762d066ad3d3cc683faa717179899f1db49e70ab"): true, + common.HexToHash("0xce4f2673418c8330955d46e15f23aeb210fc24e7cd80133830759f9944bfc830"): true, + common.HexToHash("0xfb947422ff1bd8c96dc600aed1d6f16e6ea553c76baa2f6ff378ba7b732787c5"): true, + common.HexToHash("0x3787aa301ddbf1dc0368ad8aa25149214edb9cbaeac84c04bbc4d1170e78bbeb"): true, + common.HexToHash("0x345145e2882277ae07cde6799e89d36a773c75cbcdcaa90114f7b31d503d11a6"): true, + common.HexToHash("0x276d9c9da18c12dc1a45c819c849ad8d082b08c1ee3b43d8beb5eccabebd26bf"): true, + common.HexToHash("0x303417dd8a6453f5d4c259e287a34beeb274c16ec1339867a224a0dedce8d747"): true, + common.HexToHash("0x72da04f4f83ee5a37b5c6dc7c50f7b185dce6027a275261c6d6b09a273685cd1"): true, + common.HexToHash("0x1d3aaf896669908bb1e9419c44a0d050fd09e5e158752f8a84db04ccd42a6eb6"): true, + common.HexToHash("0xf2f7948f85a9ae278b32eedbe6230de7bd92b2a3faffbfd3c8a9806a6a208681"): true, + common.HexToHash("0x4de59890e8be5563c9678dbcb8068b51bfda3463915f6028c35403f6528928e1"): true, + common.HexToHash("0xf22be3eae78a9e0ed9508e316c6cd0883aacc9b8df24155e5b0f2097ab38e148"): true, + common.HexToHash("0xe2a948d685367eeef6979269bddb82adb271d82e625bf08d27ecbfb85e9b731a"): true, + common.HexToHash("0xdf5cb6756ded57313c21b65dd35008c3ab73fb15e942facee32b53593868d3e0"): true, + common.HexToHash("0x35c2e023b326a1dd3fba076c96d6ffc01ffcc98b3c7a03f1005da39560ee049a"): true, + common.HexToHash("0x6935706cafcf9ee4d2489404b81a6f8425f789743046d16c8706f0884827ba23"): true, + common.HexToHash("0xc0876cff2cdb69cad3ae4327df4f16ae41e14cd9627aa4188c9dc22d393b514d"): true, + common.HexToHash("0xaa26238ae309e3eecf45873ff335c07ea1ffddd127869f6b6e9cd6e4d3cd1407"): true, + common.HexToHash("0xa0bc8eea70938ad4d4ef9fdea2582d09e1172c9e4ad876cd855e6ffce8547e96"): true, + common.HexToHash("0x37508b3fd586e2a6727efd86abe28c94c31bac692fab84525f2ebf82470396f5"): true, + common.HexToHash("0x07ef4a3bd63999064b15720fe1a8d1a5b46059923425d4f9ed199d15ce263640"): true, + common.HexToHash("0xd9cac77c638529a7c78e2b1c252c180736698cb65a4f4caeabf6be49b1d18601"): true, + common.HexToHash("0x8277113e753f6d3703eb707053286b4c2b8818e39c8eb6b8472c0051c19b95dd"): true, + common.HexToHash("0xc99c0b57484a767142fcc37d488d24ba54e0fc9bd6bf6e6a806e4010d8567fe8"): true, + common.HexToHash("0x69a691ba67592e1852c7db684f957649ed3f2e96670ac527f9003d1cef0b96c8"): true, + common.HexToHash("0x30cbb4a9f2af2e5972d7ea21199dfc77f704f968cc01561ba579a9d6fe346bf9"): true, + common.HexToHash("0xac4ff68a21ddd4772a29003266142e78c9124ca143ad2e47ebbe36ecba923c5e"): true, + common.HexToHash("0x48f498095b81b3b072b583950d28e4bd08be1dc1f525704e28f900e8222f6dc5"): true, + common.HexToHash("0xd8f2bf9905f7c6151d29f7502a2580c4e439279a2d5ae418c2cbc0eb09415910"): true, + common.HexToHash("0x37e3d185c4045d67a6c8acda62698cb0ae82e7a46f366cfbdcc8131c80a436aa"): true, + common.HexToHash("0x56ef679286d9a296f6a54266175576e482af2999d0d812cccdc3df55da26ec29"): true, + common.HexToHash("0x515b96701e4281445e81f4fdd84748d9e5a498ffcb8ef04a4a539df062169efb"): true, + common.HexToHash("0x0ad7d79e8c98f1ec6f23e1f3ffd5f48ab4f364c69adcf127d27931345db8fe54"): true, + common.HexToHash("0x55d0d3903b0a8586026adc8241bfabd73dfe683c0a7ad2a31abb5b289b37ceed"): true, + common.HexToHash("0x64f981c54be9484148627328cd4997f816c56a8ee4d5ac4bf9bd4ebb9f41d6ca"): true, + common.HexToHash("0x8bba746ba8d52a42ef54458d5353e98cafcd0bb1a893b0cc5b95a2840b14f0fe"): true, + common.HexToHash("0xe573536eb9218919d7bd783ffcd6b4dce42e1cb3023ea024a01eaff1c8991a0a"): true, + common.HexToHash("0x70099d9b658891b682de2c2c6030c531ec5b12b29798069b143023a432c2cf1d"): true, + common.HexToHash("0x87883e05ddafb66765717e4b943f4920e1d0c1c7733061075ab8af63085452c1"): true, + common.HexToHash("0x5822f838ad49b57779320dec459ccda6e5bde872a99e88f892160727f340459a"): true, + common.HexToHash("0xde0a14f71468eeb567e0f782c8001683bfdbb7c84451f53fcb0bd59b00d8fc28"): true, + common.HexToHash("0x916d39fc66427a29aaa89847f192f0360fe7dbcaa94265dad6f2a6f7f95b4df7"): true, + common.HexToHash("0x22befe65287e888b76cbd5c4bb3cb24ac124cb47da7f9929c88162d17125ffeb"): true, + common.HexToHash("0xac5deb642ba8446c83d748e09712137a60a5f075f91350bb9b4010182373d4e6"): true, + common.HexToHash("0x3270cde72d445a5c31aae96bb8e431dc6a1bc15214522e1ba286e25f3d287c5e"): true, + common.HexToHash("0xc12995fe287383d43db11fb276e47733028f8913fb6b6fec1ea10491ac8737f5"): true, + common.HexToHash("0x12ed23cb7aa8fbe4ff46929a999a74b33eb095c7218a0cf53e601c1bce11d701"): true, + common.HexToHash("0x1ed6eb53a46ffcf40f12f9bcc672075c498fbf61bb90c5a17cb9a023b3baa6a4"): true, + common.HexToHash("0xcc63963ecc4981c08e8c25ce6d61394ea15fed27564ec71a6cf134119078537e"): true, + common.HexToHash("0x9f52d165c942fc0415b2f0afc6e32065c15920588b5b5faab69ae3aabb348426"): true, + common.HexToHash("0x6a5da50b1f9054bf31cd77de1c345f6392e9b687413551c03f8ee2584ad48d44"): true, + common.HexToHash("0xecd7e819696044c641814036d70fb7b86dec26d92d1bd2e13f65268c30473338"): true, + common.HexToHash("0xbfa3f765fa247ea7860ee2595c07743d1501700fc3372a58d7c087062c2dc691"): true, + common.HexToHash("0x567ed9e8540ebcc088b133daeec3891d837ed2567b18f2db7020d715c4765e4e"): true, + common.HexToHash("0x4ef27be2a9d0ed3979b40ecf93851eeb2dd18c504746e5a91c048dd982218338"): true, + common.HexToHash("0xa41ba180d85869330eed6497f010bb83b143d6daf19960de6c824e9392dc6179"): true, + common.HexToHash("0x6ae329e94b2f5b101ce92705a195171f5f0409121d1463e57127f9e3a43cb152"): true, + common.HexToHash("0xa041b7b1848409d7c9644b038986cf21873b19293552ba0e8b62555e1d48775c"): true, + common.HexToHash("0xd78c59f43b54aadc6a18ce59c9c96b0211e24a49d394b28866a4ecffc715cce4"): true, + common.HexToHash("0x685a84eebae8ca9ee4e018138a5f66430e97c131c0af68caa8505a77971d22c9"): true, + common.HexToHash("0x1d2d212422f41426dd28a913606793b647627bbb75d7581e4c6ea4ded8db37df"): true, + common.HexToHash("0x21a846d3e22e729a3849bfcd2dff73a9449c5fbb766bcad4d60409dce5569144"): true, + common.HexToHash("0x267d8e02a1b8c25907eacfdd40a3bb246aa58b175085f08eb1a9dfb256643a50"): true, + common.HexToHash("0xe5cc2ffa8887fc7da1c0a0c80a09a770a5076d4f68557eccb0221673c0f836e2"): true, + common.HexToHash("0x7ec31300f3bfe60b5ea5c2c6b9f23ecfe7dc9971ffd6ca3b612a918b5f4c7162"): true, + common.HexToHash("0x97bb6eba5c300a995fcbce3aa1553f7bcbe80eea30ba5ae1885db2728068741e"): true, + common.HexToHash("0x0ad55de2e3beb31d563c366fd2f35da4d11c221df0c9ef965668254fc96db4aa"): true, + common.HexToHash("0x0d124530448e20d87c777234eba9a10df9b74e765ffc66fd1c8c663e0f975947"): true, + common.HexToHash("0xf7078c6c9546573e6158f38f0ae37704bfa55f650f3a98c59fbd929d6ac88092"): true, + common.HexToHash("0x0fd74777c3288c8537bf777143bd66287c2eea79af2faa1fe8767f239cf5b178"): true, + common.HexToHash("0x0ca5e07adb511f7560495ac7f58f31be8ddf8eeb38c82e2484d6e33059166369"): true, + common.HexToHash("0xdb5ed6ae78c046b2b0530cfb066b85b2241ef4c63e5815f0974bf3fc29fe84af"): true, + common.HexToHash("0x2ee7a20875e41e05f8b5f223f99047b2023d0b9d2002fe6fb0afab99f2202203"): true, + common.HexToHash("0xb8dab575ae67894953f5611093940f5b245e4ba674b5625c3170cc48f125954e"): true, + common.HexToHash("0x488a03c9088013299019938f9bc7aea58d35b74adb6c096d864f818a287a6280"): true, + common.HexToHash("0x817548805c24fbab7ca709bd0417394dd9449920716a794257f5ac433341d179"): true, + common.HexToHash("0x30ad42a9a68cdc97c07cba18db1182ae0de16d425fe21599d01ffb0f132c1136"): true, + common.HexToHash("0x8fdc4b44b25555e7e274556283c77d7c3d5f16ac73b0caf75bd503dc501c14d4"): true, + common.HexToHash("0x9ca028380742f817605341d3acb6c20e899ee83506568a4e5e7581e3b1d08506"): true, + common.HexToHash("0xb39fcf85789417d9e30e7a3b5345ee540d276061f445be17bc82c8d7fd6c5985"): true, + common.HexToHash("0x84b122dbba941438959e5aab9b4a5d561cc3ef8f8e52c347ee2b5972eac918c7"): true, + common.HexToHash("0xb2ca5c339f471ab3cb1efc16b3ced941ba8dd79896901f7c59225a1c311764bf"): true, + common.HexToHash("0x9dcbfe0011cd04b74d37f5ff5154067de194c90dfc86b364d1f6a52d3f503127"): true, + common.HexToHash("0x7326c5ef1dfdbd10654b5379b74431854dab0a42cf95df603f5ddab8ed8532df"): true, + common.HexToHash("0x75c75ec13cdfb932d27d8fe0a54298030e79ec7932cf12ead0cc55efcb6586fa"): true, + common.HexToHash("0x81a75653a2af2dd8bd99cfc05b4417a53fa201cb5a6cdbed38e34b44db7a851b"): true, + common.HexToHash("0x39759248d84a30389122fc51ae2835b53fdcc3c732a586a1c8cab43c3768f459"): true, + common.HexToHash("0x6148218e4c4c08764dc8c284ce75e54685ae3faaabbbd94487fb85a29bef4b0a"): true, + common.HexToHash("0x3fdc5fa52378a5857ac117052f01e617623802bab84d7339a2f2df937f033be4"): true, + common.HexToHash("0x2e310441a6b4b2da40403284fbde7bc2d32368d32f2ea658ba1ad7936cc8751c"): true, + common.HexToHash("0x756a70046f56a00d485a6cdf48cfd16949579d6e6e55c6e1ce5adcc0b81487e7"): true, + common.HexToHash("0x541fde4506addf3226813ae99fa4eb34b3bf4a9f4642156cbb7bc8bbed0bf9d9"): true, + common.HexToHash("0xc16102d611a7d65de39642fe3f771ba19ac6559d21b478676c355d5eb9c62863"): true, + common.HexToHash("0xc99da59ca55a38e4edb06125dbd465f47612e9a112cefee30f8309853e17e4d4"): true, + common.HexToHash("0x8edd8066abe55ad68efc07f35c2ef2ed86b9506f504704d7dee6fcd368b57cdc"): true, + common.HexToHash("0x9c8772d0210f363a3c1b5ccbdd0fb0d1beee93259306a382c7a556c62cc0592a"): true, + common.HexToHash("0x0bd9c4a3b0b8ca4f8f903904bc33c53aaedd90a5778ac97036210588e3cf4cfc"): true, + common.HexToHash("0x9bfd8d5de567291c0b5ac0ca7539ad45b16085234a10df09212638d7994d88a0"): true, + common.HexToHash("0x5705d1e0459cd5cedfc64cd8e780ef9db507f584a9ac1bd07b3960c49793aa12"): true, + common.HexToHash("0x76a32babc5988b1f5ce69e1edde1e379cc7cf589402aaa138f34960fa77c5f2c"): true, + common.HexToHash("0xc43078604517d24d9aff964c2b9a49b84de063f84128b544955d6b5584065f90"): true, + common.HexToHash("0x5753f01805528c11e67ef68e542ab34c30746346fc955472d8312588a1ed3fe8"): true, + common.HexToHash("0x96ea78d3cefd2e1aee1b7912e89ec02ad67c30588fa64e261e8390c9fd657977"): true, + common.HexToHash("0x0ac99eeab1ece3bc4ed2d3335eeea63c4a88b4af1e7e29d4761ff9c5bfee192c"): true, + common.HexToHash("0xa681ea9bf92504150f37aa99e50af73ed4927f228cb361c4123465c25b73835f"): true, + common.HexToHash("0xbf1064e6f0e95973b70693833b00a1a7d9111c36fedec10aeb529ed453ae08a7"): true, + common.HexToHash("0xed029590ea2092e524c90f1fbc1f3c28ba8c5b171ca4b8349935e62a652defb8"): true, + common.HexToHash("0x8aad4cf3550056f33b5ca6559020304a20e12c2c05bbaccccdba22084a2cebc5"): true, + common.HexToHash("0x307ae23560cf59d4ccc6f87d4f1d7a72af19f95a438b90aaac26e0dbeb6f8004"): true, + common.HexToHash("0xda1101ff0da010145c565ebb57f1da82af6d3627dbe0ac1d2240d276b0a26e6f"): true, + common.HexToHash("0x4a2533924896e9974a18b87be5a0a49f58bfd7aa5a5088bdbaecd65431f83822"): true, + common.HexToHash("0x870e77a7868cd7c5e2167d28c751a5e1c1f7cdbf0b08e4f4138fd4bb7efc104a"): true, + common.HexToHash("0x0c62ee8b17be9487d1956c517520f0733176869513b23d67cea31642fc68e5da"): true, + common.HexToHash("0x24c53525fae27a79d069ac53f3fb062b2ff41eb0570ffa5a7e4109d5f58c8051"): true, + common.HexToHash("0x2495422ee2930307f15bbae63bbb6d93298ea85980d1a1fc7e5e29b9c7e78d4c"): true, + common.HexToHash("0xadd9cdf43cd6874338f2b88488f97e8de60c67735793a7f0e201417f928b43d6"): true, + common.HexToHash("0x6c5857b6f92a3b9750503f9534be5ee913000f93d78b8056a62903fe861b1161"): true, + common.HexToHash("0xa1abb872f83de8e4dee0b70f1bc910d0b7581630ee4e2b8b50585ce2a8938a67"): true, + common.HexToHash("0xf0e643cebbeb91b694dad12f7ebcb95c5bd2ce4aa17e0cd3059c5679a5c6ef60"): true, + common.HexToHash("0xd211ad87a799028996dfef0023c8fc32aecb443fdc57bbe8cd8dcfc76bc3a742"): true, + common.HexToHash("0xe932b77cdfdf22387369076e8c65255447b5526608cf1e07329780f083eabc61"): true, + common.HexToHash("0xb68924b7b5bdf7ac8090bc2d05b27d4034ee0501021140f355f11214e78af9f7"): true, + common.HexToHash("0x5ebf68e99690cf102e3f68275719b9287887a8a9d2b70f9b04ec96b1ee657bff"): true, + common.HexToHash("0x0ad566076d522198011ed8652963dd583ff59d60072e5d8b8d64a979c1c6c5b4"): true, + common.HexToHash("0xcfbb23d1d4e0caab215897bffe40908a49fa1fbb1df13d647ea3abe09bdb3133"): true, + common.HexToHash("0x179b027bbc2e75494b8fe6edcdcdf58a2721b0adb69e0b6557cb5e559d5eadac"): true, + common.HexToHash("0xbaeb3e8416e0141a1f6465af292a742ffe2baaa046491e7a35795b5b7d034dd0"): true, + common.HexToHash("0xdf22f2c23499315f5f116b013e7c48a0b2eb10d6c6ec291ddb2a3145ca2517b9"): true, + common.HexToHash("0xf01edf3e05ee488517a62381e095dc87b2d47ac3f84915bfa3575c978837206b"): true, + common.HexToHash("0xc5a692f7b4f8dcc1ee5f617973365ec2ec2c8bcdc7c307a52d00862c85d9add1"): true, + common.HexToHash("0x69640e8c47946a2456d7a367437a0d320bbd2c004d2e69cd1445e02b11fa3a5f"): true, + common.HexToHash("0x55bb8300052d1dc0790499ae983fa22d2a44e4d6376527344e953fa659354d8f"): true, + common.HexToHash("0x3c7c43db452c3c32014ceb1f583f1aea6ee71ad54cf001585d049df93f5f93e7"): true, + common.HexToHash("0x9730970917905e5c7392b98b75e1a66f1d7f4dff31aef66ec63530450241e959"): true, + common.HexToHash("0xf94220315e286241e7ea59112ffe087d79e33642c9890c8297fdfd7a34532887"): true, + common.HexToHash("0x5bef60a72c53d8d264d00e2145dd7321ab5b1d8608261ce7aa91ba44ee854399"): true, + common.HexToHash("0x925e73ed7a3b6c2291fa266c71913ea8d98660a465261cd9092caaa3a44ae841"): true, + common.HexToHash("0x0408eb4cd85d7b2d1ea19cbdb7dddc740d1f96619cb6cdb453c627288e513738"): true, + common.HexToHash("0x59efea46bd367fca38f6cb2cb590dc66481c1e4e37b4e33aa18faf2cbb7a1f7e"): true, + common.HexToHash("0x0ea5bd6ad380a1ab4dfd607a7e84c656b2b62bfed3fed28d262b7380342a3144"): true, + common.HexToHash("0x3a96f9b2b1c59ce0802ef7f49140a78fbc1f222d6541996c9b15ebe60ea2b854"): true, + common.HexToHash("0xe1b1c259ce0d68399c7917ccad436a15dc7f77e77bd57bd44edc37841ff67c2e"): true, + common.HexToHash("0xa160a0f5433fd145339bd2dc5fdfb118ad0a054ab24b5bf12350b5459a90e626"): true, + common.HexToHash("0x9c14245b621f7b163f23c358b9b350b09f6a874b0add5e224dcc526a5cbfe02c"): true, + common.HexToHash("0xa4265e3f24fdfac6d9fdea71c46dcde5ce2d1cf042d824f84e6570cee6e44364"): true, + common.HexToHash("0xaf6cd9ef0733ba26cb5522479e3bc2bf688485f76a078eae864bdcbe5a38c9cc"): true, + common.HexToHash("0x1dd98418416d26cc95f0eb25d0370f79f44a56b5381d98bbf9d75a0dfc81df9c"): true, + common.HexToHash("0x89ff370686fec1c7ce7e02b11d780e22928c3aaaec87acd44e0555613d954b3a"): true, + common.HexToHash("0x67c8a096a3abd9a4775703c566685f166b032352ef556d9a150f97b00a3c15a5"): true, + common.HexToHash("0x914e83dfa8a140414c4331350d192e458edea9e2c8cc63b9a1edc745b2c621ad"): true, + common.HexToHash("0x4334583b6a30f034fc7b9bb777f739c2b76821de06eeb1664f6d5e20c06a0075"): true, + common.HexToHash("0xa989045cdff00045523e22244f955b474a4a61f715dafb7fa8cfc60a98bf6a02"): true, + common.HexToHash("0x66b3e288e23642fc168612a44400ac79219850bc286ae5483204c091fd470036"): true, + common.HexToHash("0x6d82e1406cb48b94adb2be943d26e9f72b93314a1e97c1d81a89d01a9a4aac26"): true, + common.HexToHash("0x7b473973e7a2c2e90511bbb3c008178beeca569b8e677c6946075c018612a345"): true, + common.HexToHash("0xcecb731e917930fa85615dd639896213c30b8630b4735e5eeef545b5af0abea3"): true, + common.HexToHash("0x6aad6cab4f8bced4e597c3e3f0c3b2085447ee91b68f5662be455cb3670f9720"): true, + common.HexToHash("0x9656c242e32bf89ab91d411d41c2f3ca05a4b2205a2063d4dcf6c565c3a61904"): true, + common.HexToHash("0x9e2303b15df61d54cc5229e88bbf482a30d351b5f8baeb39115d65fe85b147e2"): true, + common.HexToHash("0xb42a446d0a6567f7314e638c2767dab4fe6c7b86445f4474c2479ea96c83b432"): true, + common.HexToHash("0x22077c926c6e785f8bcacc5d9fd42ee688662c0bfe640e564a641149e99190b6"): true, + common.HexToHash("0xa7c177164c62aa7fd328309799bb60d6ff3720e27fed1897ff12912b596bb731"): true, + common.HexToHash("0xbff0c643aec3a656cda6c2777473928573a67e4705155192f40b7b6687820266"): true, + common.HexToHash("0xb9ddf988be4e8f51a9c92334abccd06a8593b98fd56565b695541fdb70f277de"): true, + common.HexToHash("0x3d4dba73de57f45d6dc256f2e617bc8ae4d4219eb1e50a7ae0bde54dee1ae842"): true, + common.HexToHash("0x689f85b29e738044362cceb5d5b57687f4ce7015a87343b9b77b54c4b9452bab"): true, + common.HexToHash("0xb4fd1123ca0de71ef47945b5ce30b3a6d7a68579ae4002858c9f2d616e812a47"): true, + common.HexToHash("0x31486396c1088dc52507a17b33c08fe1fbef5e99df0d3672a4d19a183dcbe8e0"): true, + common.HexToHash("0x0416a59668673fd0d58c514992549644b77d5922ec4d629577756370751291a5"): true, + common.HexToHash("0xd0e665b6af39865b543dae614725a01c2a0b6be19897e98f154ce6eb7b86cc7b"): true, + common.HexToHash("0x75aa91fe427bd5c6559510b9246c299663f6dd7841972e00da873ce13629ce21"): true, + common.HexToHash("0x78f13bcf45cf158fa2b6c47339b369046fb61461b74a1d7cd4f6f713fb09542f"): true, + common.HexToHash("0x719b947d1ef3b97d407c0c9a43e14565ad248939e956562e2873b280258d0dae"): true, + common.HexToHash("0x578bc2a7b4b238488047e72de7c9b4ba4a4d2eff383066d470a9dbfdf2ea53d6"): true, + common.HexToHash("0xb0637be533d502f6f455db1cb8016fb5fa45d511d3fd85b69c486131361a87c9"): true, + common.HexToHash("0x0c8db999a8a2858a3c7d5bbab2cf2a942114fd1fdd738d5c1dc69bf4465e3e7e"): true, + common.HexToHash("0xbf399d8768c5186dfc181836b9600bccb9719fb69a9891f3a560f0d37d833a6c"): true, + common.HexToHash("0x47c9a9696cb8618c5e61963c34729334e0783269218735761ec2089e5bf46052"): true, + common.HexToHash("0x7cfd5e05b8def3960f8df5517b977a3f6dd41a8546bc0b3148881b16f21ca927"): true, + common.HexToHash("0x52e2abef0658f2f95c3f86c06aca1d1d0175666ec142da6a610c9c22a1b7820e"): true, + common.HexToHash("0xa46d5f53f5aae5b562309879c1af56aaafa2c3216a0f6ee41c7e85071d6beb03"): true, + common.HexToHash("0x65b51c0bbe52c8b04f9cd3151b0e24c09fd03f7b47345bf622ab7ee707ed7755"): true, + common.HexToHash("0x6e683d36ce9c085a60ac3f44369907de625510d854940cec6793b7bfc87e7c41"): true, + common.HexToHash("0x11b18b8416687c9f8d18395e0270ef7bfaa1b8d538f9b1029aa90a4f351df442"): true, + common.HexToHash("0x81fd4edc941f4975136faf6ae5530c521af334a36b99b4d2998b35fd3f411401"): true, + common.HexToHash("0xf8743628c64366b2bb35fd60caa548757cfe3c52cfe507aeec7dc28845a32f83"): true, + common.HexToHash("0xe879abc25ee0e3a1e6cc814322d8c1115f8b18e88275130158940f902d71339d"): true, + common.HexToHash("0xf821694a0fa29231e4872b5ecddb74eadd50751e54f7c774f9771c7761a3a314"): true, + common.HexToHash("0x50892b0b091f4d086eefc2416b91f3ae82114cb5584e94b944ce60d9e75662b7"): true, + common.HexToHash("0x2693895267af657359b7b4dc09f577d45fd9e6c1db3d5d62fdda9b71686065ea"): true, + common.HexToHash("0xd87728f8497aa80037f5ac0b1a4c06ffc526177fd851c658ab332884f48b35d5"): true, + common.HexToHash("0x2b9c79eb9b75ca282769247a255c9aa57c93cb5b35f796f0d4a9a3f9e9c571c9"): true, + common.HexToHash("0x323d2378e29fe4a2a6443d763aa53877894bbc5b39fc462fa417f38b7bbfb696"): true, + common.HexToHash("0x57a1e0d5ed83132e27462560fa8b113411604a46c2bda7aa3a5dc1fd30305e89"): true, + common.HexToHash("0x4cbe7fd06b117acce460972d025e16d6e7f551324db6d180af0e9a2e69532467"): true, + common.HexToHash("0xabd3193af98f31f0378c40212956aa27271a674586137b5b4fe750900d65c31f"): true, + common.HexToHash("0x0820d0d01270bb1fbddae5a46e8a31cc719b2e9be14c11dfcef9e7536058cda5"): true, + common.HexToHash("0xeaf2a9738ddcd2b22a3a59e2b2ea891ce32de8bcb7ca2b5980ef9beef05494a9"): true, + common.HexToHash("0x929baaec53f60c4d97c809d09ba720b439118ba59ea44156ec19c5fb2596710e"): true, + common.HexToHash("0x14b4133b123efe08a458f78be6afbbb30802711fb541b3370618f7723ecc55c9"): true, + common.HexToHash("0x92297da9135f73e2269b9fb7cf15f4bfb732de30f4c6a552fcfc4206acca8987"): true, + common.HexToHash("0xb09b0e03f759bca8ef0b03d369e7522a3bd051e404d1ebfb3d8798f27b41e8f9"): true, + common.HexToHash("0x5fb1a8670be3483a7c0ab76aabb10b72d181df8a3e52d84a42903c99aada3849"): true, + common.HexToHash("0xfe08e4b1688e0024841aa49f865a3003a7c7854a41844c9f1ebcff3ab6e3cf8a"): true, + common.HexToHash("0x8dc1928936ed197156c5a254e6e44f0fa407febb23eb919ee3d608a301da036b"): true, + common.HexToHash("0x1ea5646a403f485a0535fdf61e27443a86e6547abf13a4f230fa64a4e652da10"): true, + common.HexToHash("0xf53dbc21288ba29edfe9994fad9578392f8725ca636b7f7a2384d95e82caaccf"): true, + common.HexToHash("0xd40e5888a5bf41ffa421ddde06fd1dc637a44960e44e8168b5688b1e1031a8f1"): true, + common.HexToHash("0x772b8c11a76f41de9652b514484bff754656ded099ad5be57ff5251d6a50a3da"): true, + common.HexToHash("0xafc034a027dfdb9b400a4f90cbbb087e54ceb6a4d9015ce0e971db8c66fc2800"): true, + common.HexToHash("0x50274de83816652920ed038e02c3a7fd9af7eac0086fbb1a034057de8a55f87c"): true, + common.HexToHash("0xb7fe14973371ef1ccc39422260d2b13ce984aebcf05d0a3d91b07b0de9b1231f"): true, + common.HexToHash("0x2c30e258f06058cc88960bf0bc55e2733c2817a5cd0804fd686fc975e9ffc90a"): true, + common.HexToHash("0x716020fbb56fed4479207f517825a6d79fdae481c881e4bcba11dafa6dea8756"): true, + common.HexToHash("0xe455ecef267c68a53ddb2ba51bbc947e3735afae2fa0a46c22b038bbd77bcc0a"): true, + common.HexToHash("0x4a53aed7ed0ae8c774fc68d405ab995e54e9fb63a609b124215e21b245bd951a"): true, + common.HexToHash("0x2de8e7170aa292a205e2c15d8781a4075788b09932c00aa557be12897481f756"): true, + common.HexToHash("0x323da0c7e61e48a660ef4305c1c8f180ff9b6489f2492254d368643e581d1d09"): true, + common.HexToHash("0xc8249583dccb539cf4d5552586f62fa439e347c77ff01848397ea5e325ed7213"): true, + common.HexToHash("0x56f578f7662243098b0420aee1b677af9abafa23f1a529e838104e7a2528ca47"): true, + common.HexToHash("0x797fd01a4ec624c7e9aa4f9a1c11e6f5ef4269e426dd7b6a70a191e04cabe609"): true, + common.HexToHash("0xe0c9d0bba63668c58f6acb30d5b19719ca816b6cb4991a5ff411cfc45e50df42"): true, + common.HexToHash("0x66328f613ff1aa58a8d9c32d80ceeed63425103311507ec52a4964a4e7fa121c"): true, + common.HexToHash("0x59a6f2c2f05bfee04e61ac598b4ca27e14ff979cc6d1187248155fdf68d97706"): true, + common.HexToHash("0xb1069dffdb5782fdc5d550ebd36e0a59773bbaf2057c7a51d5c5b5eed6d8c790"): true, + common.HexToHash("0x804dfc47731847327726468b25391d1875b0c684287a8e1b9314e9f0b7de8f51"): true, + common.HexToHash("0x5a64e4c787de3bf1e16883d15b019f84e15f498c1416dcae24cf39188cf93348"): true, + common.HexToHash("0x126f12e36ff6431b99a44a6efe7c85640975b6f7dee00f6ba3067c5c665f3578"): true, + common.HexToHash("0xeb318236b1bc2a9dbbaf5047fb2f024ee8712342f20d7ac113480e23911e4667"): true, + common.HexToHash("0x9cb4bbbca341a0971e159c491f9909623076472051cde30844d70c9f24f6f4b0"): true, + common.HexToHash("0xa7796a5af689e5a8e3fbfd416065918330cf6a2035fff5f2c502bd27e9480789"): true, + common.HexToHash("0x2b3cb763c797736d4e822d0a57e455d730d32b1d7ba2d281df02587067052568"): true, + common.HexToHash("0x675e022d2591e6436e4012b7675462d570812e282055e91bdbea7668f9f32165"): true, + common.HexToHash("0xc7b6a9d0041d06ead7165d42306531579fca5f8dccde5a868fae12e48a32954e"): true, + common.HexToHash("0x5995f2fbebe2d5931650de13ef428d6edd38aafe5e6c34e8ab79b82471d0b950"): true, + common.HexToHash("0x3d654d9eb7e54084b026064b461796c47b4a20327c81a066d4639f81acd2aa84"): true, + common.HexToHash("0xce321537a3a9d1a26cbc4a367c040807b536fb64610aa31e6581e34bff32d81e"): true, + common.HexToHash("0x01ce383cb28613dc65464caf5c0f698d9589de86573ed7fe39abc6268c2b9590"): true, + common.HexToHash("0x6112b438d8f950cf2176586491abc4808823fd98438e27f753edc917570093c0"): true, + common.HexToHash("0x073779fd44a3a85c8f2aa9894709a9f1174bd73e6e546821056899b9435f2d1a"): true, + common.HexToHash("0x39bd8f183ee4b80369d4bcd56e3b2c2bac7e8ebd878a91316c34e41ffdee4bd8"): true, + common.HexToHash("0xc8ecc21f69b6e4c749040d3511d3b252e93f9fd01aa88915324965ead7132860"): true, + common.HexToHash("0xdf56dc52e9508e78435073033dc3657e5f5e3981d9edd48ac736adbf3c222998"): true, + common.HexToHash("0xfa3312148c80c1fe408f8b7d37459dd222b4c726aa173b8f80f2792de73b0a58"): true, + common.HexToHash("0xa8e6bee8f9db2ae22faeadb899ea43d1dd0e5fda66ef71c375122586512e9d0c"): true, + common.HexToHash("0x942c0645bfb110392c2d55c5241eca6dc96736d238255cd20fa6b874eed8b01f"): true, + common.HexToHash("0xcdef84a3643e06a4ad858f1ce6ef69f21fc5d6e08f2d98c091ba759c3db60968"): true, + common.HexToHash("0x60cff7bb549044b962a8e38dbb66765b96adf2549a857cc06069e58a6f027655"): true, + common.HexToHash("0xf8b80f44a3a1db62f4f0997ada4af04e4c7980ea2d1186facc9b502ce4a723a2"): true, + common.HexToHash("0x74a5b562172f889cfdf4521ba8f855ae7695ebb3424452b55f6979457ec1544e"): true, + common.HexToHash("0x9ee538b07312dd60fb13b47cb5d8e677ef5d3f0b54960f76445662b32961d2a2"): true, + common.HexToHash("0x57efd2ebf1b6b37636472d107c4eb0aa2821f4f215cfb2a224e5ff4619fe69ec"): true, + common.HexToHash("0x53c6d4fb43ef633826f10999f9da31a7ccd6d08c18c47e6a898ca9313ac0a1a0"): true, + common.HexToHash("0x99db3b2555f3cbbcd1862e41e6c828ff58a08c42c47d5e15f3846c9703930a0d"): true, + common.HexToHash("0x98e6125f3a2a5204a6a11a3651cf760e5a6c67fd7b24341476cc690327ffd2b1"): true, + common.HexToHash("0x5a5d2cb01bf371452c51283376980e91d64ea1ba98fc63fd63298acc48c5bbd0"): true, + common.HexToHash("0x0d355b3873ca7695e3405a615201de9cb7b5d40d5793f78399df26bf6506d229"): true, + common.HexToHash("0x58e67728773daaf4948b944fcf8757efd11b13efd86bda6d8568aace75e02230"): true, + common.HexToHash("0xf71478f0bb112d126b09f4977e4cfb2d00710aacd297263b0abffefad9420920"): true, + common.HexToHash("0xe769640f2e77095fa3abcd42031caa9094c29cd0530d7eb406f3ecdbc7c15ef5"): true, + common.HexToHash("0xa2ba4ef76c986b90529e61f47ecc409d596b0c35a29813042a612608337901a3"): true, + common.HexToHash("0x07b73802b3699f8a51ee5401bdf07bfb75f25b375b889f309bf7cd41c8d2d502"): true, + common.HexToHash("0x16e6d23d1b27320678240e8fb08820e9b86812e88afa8a71b4ff7a412817e81a"): true, + common.HexToHash("0xcc1d4a4c356123938c11cb0dd8752ff7f5856ca8016f7770e170b80aadb45487"): true, + common.HexToHash("0x30c3d9a05c7e67ea13a03e85ff42d8b17522a9154d06bd3ac293c4dffa97422e"): true, + common.HexToHash("0x6c2b2fbc2150dbde4ec55166f41c5861ad3b0c933d4f111113ddc0544f4e5af7"): true, + common.HexToHash("0x753890460d731427a93a69c0eb3df56730ecd073ab38e8e5e400fa08e096c2e3"): true, + common.HexToHash("0x50f50c8848cf867dd741ade8e011ede9589b35661c37e2f157bf9971d4d02de2"): true, + common.HexToHash("0xe6dfc38207cf94eaad68959982859c864d7b520ef8e4da70d83223d63b77cf53"): true, + common.HexToHash("0xad8e47924f2a7ce9700d66276c6ea10fdae233b62c7ccafc53007e9aa7d595ad"): true, + common.HexToHash("0x651dc397846cfe28dede9ef48323800be720c740acaf61c3f2667977fc016722"): true, + common.HexToHash("0xcb969d37556722231479c113a0c1e45433a5b8eb4aa17e7760810c97df74a17b"): true, + common.HexToHash("0x881a20293fe08ef7aabfec7464cfe20fe7f230d02bb046002d148e5d9efe6362"): true, + common.HexToHash("0x28d072f8d32b61cc4425c867a1dc7bb5b4f6212dda4e9890ff4d06c59e02be75"): true, + common.HexToHash("0x41b7286da46fb1d44368986f862822c3af986e4e0093d61946c9e428662fafe5"): true, + common.HexToHash("0xc13068a73b9c7896b8daf4829fd2a6acb25423f26e7de5e62813445dd267f7d5"): true, + common.HexToHash("0x21596588edec0186cb2ac7b28e5abf5d902551d11e98081162f7c45b1ef9dbc2"): true, + common.HexToHash("0xfff99ae49492974a371c9f1ec705e28515e1c2d7ca65072bac06e9fc8d416a0e"): true, + common.HexToHash("0x98d74d13e4fa6b77134aa232d812aac3ff6c1583035c7b2117b7b063b6c7ea17"): true, + common.HexToHash("0x09ab1ecc97a5743040bc5157e34a2076a64d4d9e6c4b0130de130ce20251b4b1"): true, + common.HexToHash("0xc0648df912a02056d694e6892c8f53bfaf92b966edaf00cb499c61fb0aa24b48"): true, + common.HexToHash("0xea092a3c0070cc93d82706be3b908d6c02f5c8677b110b8d1b249e1678cc8461"): true, + common.HexToHash("0xd4e70333fe2c26c4017486bb8cacb874be2040a656282715a492cf17758865c1"): true, + common.HexToHash("0xaa3f1fb15e34e574fa907eb6b69d92a22c9af17154a9484dc5141138bdb1858a"): true, + common.HexToHash("0x61939a311385456e0005ca90c72ae64cefffea9934cd753a5e5b7bb243e14518"): true, + common.HexToHash("0xb380774e6fc10f516359448ccd2c29ec517ad2c39abc8c044533baa6e12db4a6"): true, + common.HexToHash("0x87c7c6a19f79c8f498faa0448d92a641830b3775f57761a9eed4c3c073a421a3"): true, + common.HexToHash("0x7110d06cdbece8dd6bf431248eb28e1f8c553c81c0cf1efa31999de33e167e93"): true, + common.HexToHash("0x6591ea7bf330fb87e81291c0d33c4680caf9f501e1fc0406d1b832c00420bd7f"): true, + common.HexToHash("0x6ce5a523cfa8092f96a80a63c3bc43a20bc1cf4b3f83b63baf97e47517c8587a"): true, + common.HexToHash("0x94a04dc1007bf88f9a314d05beffb0f0ba6444a2491ff6812c8ff4dce0ea2a1e"): true, + common.HexToHash("0x743081fd0f5c4c66bb87d625d516a70ef3f5c875a632345d1c5b397fa6d9127b"): true, + common.HexToHash("0x0d1e38513c89f374052ea61f0138efc403b236728e8c139de4ef89ccb43acbe8"): true, + common.HexToHash("0xc7283c6a922c8a5f03d858655062d4e47276de63e639ea9bd110bbee04c19ee7"): true, + common.HexToHash("0x2cdce99c3bc50b913bda33670b4c11ca3563d52e3334e5c5ae20db25be1871af"): true, + common.HexToHash("0x5b48dfcd483197a7eab8d9939a22f80438aa46312aab3cf95de1f5565f9f88f3"): true, + common.HexToHash("0x9a6935174469e1d86f74cea938735c5182ca04fa41f2f52b0e7ca99e5b02bdc5"): true, + common.HexToHash("0x2ce0f06d139e14e7b878792c74f2371caefd3fd23a81d050ea81e75944d9bdd4"): true, + common.HexToHash("0x82404c724865bda698a2f0d6e4e7f3e64ae7e5b48ab4b3607d9518349cf7b9c4"): true, + common.HexToHash("0x4024d499eff72d27ff72359e0303c66333e247a3ed0c129518457b7924e7e91b"): true, + common.HexToHash("0x41ac27f98ed76aa9798228364401bf5719bdba6c85d611c614fb4b5fbc1e9018"): true, + common.HexToHash("0x0bc59be559ae3c56fd742b6229602dc71d01dad8a781260f3e6cdaa1857f54bf"): true, + common.HexToHash("0x037a2d94a6fc103bfa2f06d122980d8e2dcb55124ae7c34224c98f8146040db6"): true, + common.HexToHash("0xabc18158e261e195365a18dce450ffe91ca0696c942d942f92407b02dfae164b"): true, + common.HexToHash("0xcfc0e953f037d65795372a4527cb1d8fd9530bdae05274bcc9093fb53bb85058"): true, + common.HexToHash("0xe100c4c9537e334361c5d5b04e03b37d74bbccf98836308c83bf4af572787a6f"): true, + common.HexToHash("0x0de7914076cd70f212778bf4204630263e6e052c0f7fbbae38efc64b6a9450bb"): true, + common.HexToHash("0x91af26fc72cd6ca3facbfcac79589c9ae9a90de3d46017bdd5ebfef11def0e72"): true, + common.HexToHash("0x5a198d726deaf0a6bcc447cd2c8910aa95545177b254c23d4c3b63686f6ef3ee"): true, + common.HexToHash("0xec2fa25ca33cd4e5d363cabcc64a14d14786cfa08c932d979eed3a3ca1eb0afe"): true, + common.HexToHash("0xb34f9a93b21aa5922469b5322dda19898bb713e986e5435dfd4147dcedf61cb6"): true, + common.HexToHash("0x8cf54e92eebc99d2dc90efc8de137d5e3d28991fe8e481e6a10cd90956fd04bb"): true, + common.HexToHash("0xf425441254206e1ba337f63f1d966c159d8d9fda77284cf88e1d040de7b8cb8c"): true, + common.HexToHash("0xe3e5fa41610ba3bfdfd8e4a465081060bcb312d4b75245b23e8c07322935db69"): true, + common.HexToHash("0x8ad7173b874e268837d3a38a3c172313497275d1260c6bebe9b825266dabc6b7"): true, + common.HexToHash("0x06d6488a1e7e0d5e4b136c62b9c4b54c1eabbcd5fa9db2dbbe6fb9ef3e2158c5"): true, + common.HexToHash("0xa1d798f5e38ee380a5f426830c264abd19e2b0e62e2b807dc36f8cb1274c6d0d"): true, + common.HexToHash("0x74e4c82e25f059b859837f29748d8bb5788e27a02df4ea660acab13cfc670b3f"): true, + common.HexToHash("0xd277513f2f2c60e92c847550ee746b1a91fe6b364d9d5a9dbbb010219388efe0"): true, + common.HexToHash("0x1d778b09d153ccec450b9cc07abd891eb4af8197799ceb47c536fee4ab7a53cf"): true, + common.HexToHash("0xf99ade2081fbc037831ddf02eeb50cbe0a71017703a1d006c0d2babc2651684f"): true, + common.HexToHash("0xb270cd1d9fc0af4def5140d6f04786ad2d4351d28b671ff8ecae25c3b6df6cfc"): true, + common.HexToHash("0xa87be1bf9f88c593402912491c44f48e40eb4a47ab463eb057d0aeb993ac1abd"): true, + common.HexToHash("0x2630554f2c3671e73022e8bdeffb0db2d77d529bbb69e676484992ee37cc672d"): true, + common.HexToHash("0x4b223032ff5dbcbd90c30c553421a2313092dc55956eb36a6e622da2dc1f2796"): true, + common.HexToHash("0x22228c3ea897fcb6a56942a79450868e5dc769e3f00ad159c10d78ca04952eca"): true, + common.HexToHash("0x656398f85e7bda79434f221f49022812d51db51897046377c203c03f9a1beee1"): true, + common.HexToHash("0x37d8b6365e32536fcde04e281b668074904b02e50f6cdcab874c4c896cdeb684"): true, + common.HexToHash("0xf4aec0c30d2adb81fb191320531b5f8fe28f84bcb36c52ed2c8bf69f65cda016"): true, + common.HexToHash("0xbcf1dbc862208cb39040aaac2ea07ecfdb9df9464946af0cb7884b082cf7cfd1"): true, + common.HexToHash("0x1e2d41cc46de96de6aefc99ea6fba89e860239c59fc4bf6c7530af3e2404736f"): true, + common.HexToHash("0xd78f8d05934de8a8b9e28573f0f5776a795321bbf09732143aa3dd9fd5083d6c"): true, + common.HexToHash("0x431be637c326993f8455c6ca91698d7ff84ee7554cc5b303578a66f957be0360"): true, + common.HexToHash("0x368384050e0384c754720542c039ba553cb5076529d6d8b4f260c9aca6edc6e9"): true, + common.HexToHash("0x4d2a6d3b5e1ad7dc2482b050e828a1bc5344856abbab95428ca2a2957b6b273e"): true, + common.HexToHash("0xefac7ea19864d172fea320f270bdd99ef198ac5aea68687d2054f61d4a6641e7"): true, + common.HexToHash("0xfb5decd915a57ae32c43d50df8d839bd854bca44b1cf587ff543006d1473328c"): true, + common.HexToHash("0x838e7d464a6339897e35f6d2464f6249a729c3629d85cc630ef561d09cde3fd4"): true, + common.HexToHash("0x98025b35ce2b2faa5b8c733cac46f61715ea9af5f3b1858707c13e4842dbd908"): true, + common.HexToHash("0xd7ececef3f02deb59bc2ad012cd58c4083a5026deeada4726c6fede079b191b6"): true, + common.HexToHash("0xc909195126262fda0e7988c37bc1263dc29815e373af768dce14c21784f9daf1"): true, + common.HexToHash("0x2d15ee7131e282374270814d8f751efe341078b66e6a75a1270329979e024687"): true, + common.HexToHash("0x54b4d5221db5e8e87bbf04270a2ab2da7a0d6ee75534b9f5da64b88d7ed2b59a"): true, + common.HexToHash("0x0abb09008a95216e7c5c15058e629a8f15568fd8dfc0460a3298da6c0fdd8c3e"): true, + common.HexToHash("0x499d04587f8522d167d2d30e94bfc8fca84d58981825db2c893025969b74cefa"): true, + common.HexToHash("0x1ee1f9b10e2f6920ff2439fd9eb1353299bab11583e9e0528267c665b0550683"): true, + common.HexToHash("0x129da334518c0391e95e0ce0368045798a8031f3b31c7a8a2df114ba0fe9b54a"): true, + common.HexToHash("0x4eb731ac36614c53e08da44df12357e3ed89facf15cc2a434e3a2d341250f593"): true, + common.HexToHash("0x3a347eff17ae269a2c4443eb8e1e82aec0921c3569407d2efcb6c28db5daed5e"): true, + common.HexToHash("0x5a2554b200e4a20d3d3789c82e7908d37b27fb6bbafdf2b50ebd63ee69d7e116"): true, + common.HexToHash("0x2adfa3b0d88e966f30b4c4725e2b280f40df79fe639e7a4cd48d59556d73d1e1"): true, + common.HexToHash("0xb346ccd5d50e1097f1ff7fbc88a6ac86ff753e2ea241b6f1c9030036d649a42e"): true, + common.HexToHash("0x8c23f6bea506b8082b80f6773088b95e0d7f7e461a630f2798a949b475b5b9db"): true, + common.HexToHash("0x47e516b1fe7a552444fdb85457a5d91bfc528af2dc4ad02175638ec72a2960bb"): true, + common.HexToHash("0x18d3700ccef129ad7e0f2c145949537a4c7003b90b94c215c1ca82e7529c2b7b"): true, + common.HexToHash("0xa87fb30b0656299578080224127708ec2a555c7dda1bcc9210804ccb69daaa1e"): true, + common.HexToHash("0x7ea2f48ae3c968268f47d444c0cdbeb1eb8013d942effc6341ff5d4f8a4816f2"): true, + common.HexToHash("0x3c47ee42a1457321d73e116a781fd8ab50453cbd2760788cb18d13d1748805d5"): true, + common.HexToHash("0xdd91898d48fa01b59a04a4ff4085a56a8a26145dd1153c6abed35a628b971744"): true, + common.HexToHash("0x87efde8ee487ffc46ecd7fd2100dc4b0021fb68cd63b27f2e25810dd62a58628"): true, + common.HexToHash("0xfa3e05bba28ee292e6784636fb4256c36dfbcc1e32f5a0316e34fd8de2470c9a"): true, + common.HexToHash("0x14f8e10a4ac1ecc45f32ae89b4c4f502f362c4da80d70b16c3ee1d06dbe944a5"): true, + common.HexToHash("0x636eb165726e64480bf58773bd7a7d48aeeb96c70b4bd8bfdc0aeaaf4a5b36eb"): true, + common.HexToHash("0x1489c4b0d5b52eb7df998b6a14e64213f5ebfd91ac96b52c6833a75937113e6b"): true, + common.HexToHash("0x8e6bee03e54170e30615f752a71e7a4f229e333cd6ed8c998753e4398d7a3b52"): true, + common.HexToHash("0xcf03c3bfd866c47ed6e28748706a2f9203ffe89a2bd8b80a08c477b464e9b365"): true, + common.HexToHash("0xa790a978f75527c7abcaa4cb039d137bdb1793f3e5e02eb9993a51815c89bbd2"): true, + common.HexToHash("0xef9cc2cd9d3f89f0ab727d178a15e79c0eeb8b12a3ace762c93fdf796e2ca5e2"): true, + common.HexToHash("0xafdbc5dc6fb86641210181b761121884053fcf6d06744627a2ff82b42637f8b2"): true, + common.HexToHash("0x2771f67e2c61592c833056e578b17cb9f7c37132f2b234ef5a660ff9ebb34d57"): true, + common.HexToHash("0x5db35097e2318e906706f2aa25dff6228deaff3ba92c7aa1c34cd81d386a2ad3"): true, + common.HexToHash("0x5574b2410ac467a9600b936eedcd8b243428102ad0927b53b631acd4250df0ac"): true, + common.HexToHash("0x49126f9d1f2d0ae56dea2b679f38fc4ddc3775966a46a4b1d50a0cbc63c21c90"): true, + common.HexToHash("0x24332bd7d1dbc4276003fd339ba4ea2684d63853fde4e70f20388372d579596e"): true, + common.HexToHash("0x5eeb9e6d1a99fa9f55a61726a3a5481fddd835a256ee3891b3d755cdc826c09e"): true, + common.HexToHash("0x55a5bd94cd9e2009816adc5dd582e502eee3d78e992b18df8804dda4b9d9bf5a"): true, + common.HexToHash("0x7e4031ab4f33bdb0b175306959e8eb589af7918fb050addca1976b78c36ad1ee"): true, + common.HexToHash("0x9d67baa3ee3a0a57000723575683513930254668f84163f261e852bf1be48e58"): true, + common.HexToHash("0xbc2ff246d6eb39bcc6006d1b780a508060723253d165e008c7d43ad5fce6aad9"): true, + common.HexToHash("0x23004ca7eafa66e911fa17dafdb919c7dc77cab7e15d79748eee327da3591310"): true, + common.HexToHash("0x8c9854b1b032512ce030364c3dd69d390281cd5b0b3c334b1828875e671ec1ce"): true, + common.HexToHash("0x21b11ed6840f02b6d0473a84f2f658eb7141d256bec157e2559a3ca0159f6bb5"): true, + common.HexToHash("0x4544b07a2458649d4b539a210cc83b848d8a0d99e9913819041f57c6ee99cef9"): true, + common.HexToHash("0x67fe0a1e6e8d95643e90e15450912530d584478c7a316144a5396361d51a6338"): true, + common.HexToHash("0x86528743fb0b0c8613c31a9b491b5e6a44c7bfd8ea3ebed3457b5ab0167a5d41"): true, + common.HexToHash("0x9af7b41d49c90c1e299db9d2eb04ca5dfa643e0f8e9a85dcd81f366175fed7d3"): true, + common.HexToHash("0x0f0c2154ee7e115c14efedd93650f3e729214d780e5b5f9a9b77627bbde681d3"): true, + common.HexToHash("0x872cd21a2e102fd4837228b8b196bb5048eb07cf948504a52f35cc2267d0d311"): true, + common.HexToHash("0x9d3307f2b549eb5972072c391774411356b1799c4ea4a9b729f567f77c5731cc"): true, + common.HexToHash("0xde67ddd8f5b6565a015e2ed889f62be8b543a6f772a8046ab18473ea66f7022d"): true, + common.HexToHash("0xe3a997639743400d856374c0e38976c39545d890a332443bfaf3fb025c6aac75"): true, + common.HexToHash("0x77cbe3a63299dd9eafd45b6085d7f7b655058e40e651fe7c72fa35d0d04676ac"): true, + common.HexToHash("0x53102633d07968a1c87d925bf40d9458d9b3f5a39479e870a09577f2aa792608"): true, + common.HexToHash("0x9d73c0ca6e8106dcee3c91e228db1aaafab5d8ebdd61ecb50dac8628fb50cf97"): true, + common.HexToHash("0x9c2cb716a98748fb9bdcbe9c3816760ef02fb83408b54e278ae29b0e0f117465"): true, + common.HexToHash("0x730779cb988335cbae0b43972d4df2bab92f125c83449ba401db669fbce9520d"): true, + common.HexToHash("0xacfb0290831cac7329d6a5a357b076431f9b0b6093ba270441bc25c4122a77d9"): true, + common.HexToHash("0x3bf1f6eed08dad95fd9a176852148816ae93372b41235d21715fb4a003227b33"): true, + common.HexToHash("0xdb062bdf1b8a3b87864e861ec75af1d149eecb8a710e7b64dc86db675700ec89"): true, + common.HexToHash("0xb8c0b33a874348f3c1635d1666f2f5ca09b1c94e3a7fa4f6f4255765457bfbdc"): true, + common.HexToHash("0x6c5b0f4ed35f9874bab89d00141f43187eed606a847f1c5ce1b9d39789e7e213"): true, + common.HexToHash("0xca5aa6cc3cb25f26c062676c9d23a76e0ab1eeb80a511b32873d8162a7139aab"): true, + common.HexToHash("0x1d390c3d4ed75d13fb61659d376b84249f5162b5cae821092c2156f19f204777"): true, + common.HexToHash("0xf45d6a9a39d9668ea7cd83f12fc4b46b40d6b3a60f91239bf7d65a96b0da2b85"): true, + common.HexToHash("0x2d0a017f35ac1593fb86505b27d662c111f0cb1e5dd0a9de881fa7f80f6fc230"): true, + common.HexToHash("0xb1620be1a63742a1affe7a2ff6dc1705a16c4865db45382a35c8ec5eac71e4ee"): true, + common.HexToHash("0xfda14fc35b3538eb46469fd305ca3c006f7a61f5d7d96db78d405ac0d1408d16"): true, + common.HexToHash("0x30a611cdecc60757c7514489fac707dc7e3065939c84ece30e1f29ddcc5f3d08"): true, + common.HexToHash("0xea36c3ce3b8eff5ac5dbf1bdaaff25d5a7f89bf4f73968c1b9751799279e9d34"): true, + common.HexToHash("0x77d83571a4e27e7a6160e5f49dab52c0949f4e5b1490e1fc192d4de195dae0c9"): true, + common.HexToHash("0xa792e49e43ee23fce2faf6b375c482ecce6d3fc63ed90b136b78c813d6bd74fd"): true, + common.HexToHash("0x9905004f8285ad3e352270cb272b63b3739d8d6daf8f46c7a7a5a1166f4db7e0"): true, + common.HexToHash("0xea5e5a74ac931f58de0f424a26cf6b530041729e06f375cee6347c34e50dced0"): true, + common.HexToHash("0xb9f67393d22606b35678f09e9ad9a718e9e20151bfa0b8b0a7b0b059865f4b5c"): true, + common.HexToHash("0x11da9bad7a13de3778b6c20ecf6e2ca62fde90e29f249efde7a9300d33020f61"): true, + common.HexToHash("0x97fb2ff84add02d5973d0c84bf3fc31c55fe5a6cf073fbe13d6ed596909f4f04"): true, + common.HexToHash("0x8f129e8a9b72b58fbdbc8e4a1695e42b26aa733f0a6f23cedbac9b5e2a24f096"): true, + common.HexToHash("0xea7c580a0d6295e906456475574acd031f14a2c77fcaa3edfc7374fa6e8cea91"): true, + common.HexToHash("0x47c469deae283fedcfbb6827d7cbf874ef24c01e4e7e31a7422ec65b9f1a21ee"): true, + common.HexToHash("0x1ab702839c3646eb71ffa6b5fbcb8972d6c73e6fadd5faa656289e74d15b9ddf"): true, + common.HexToHash("0x21fb27550cbead03d807438728ff5dae2e3dbd2256bce8f9fd324dc50dbc15ff"): true, + common.HexToHash("0x0026d04ff1b5b1d5b050bfb7e027ad83bdddbec08a31d7e2319102d85ef2657c"): true, + common.HexToHash("0xa528514d0daa22c469a7717f911020ffd609ccad5b3c45b7ac3ef362e468f84b"): true, + common.HexToHash("0x6f97b4f68d6ffdd9008a7d979f7a36536e42960ba4cfacb90c30eb45c9429ae5"): true, + common.HexToHash("0x889d28c5b7bffd1aa9b83eeb7ce84a8098923f176f4e15089253f81a2dbbb4b8"): true, + common.HexToHash("0xc22c0f78c0667e84589aa28170c262c340ac00fe708806054ac8c08baf9be3b5"): true, + common.HexToHash("0x9837dc4abb2d5bdf467e35d2e59ce0d4a53312900addf4384f5c122b8c85e314"): true, + common.HexToHash("0x1b7351163dbcfd2a0dd6844eb1c21606164f7c5cca74dde7f57236d23bec1704"): true, + common.HexToHash("0xda07e620a44ffa32dec4b1a7ad8b9c2dff8c2bb64a125de7c4637b3480d36810"): true, + common.HexToHash("0xe92209298f451d0902ae7b3841aaea14b3b559735a8ccd4bf706af61a714333a"): true, + common.HexToHash("0x3f5b935a1e536b2be5027494b04145bc0d7645f42e4884234b5823c95450368d"): true, + common.HexToHash("0xa50ff8879ce29ea6979688626956d77aff8cf2a811478c2c693fc69e0f164a55"): true, + common.HexToHash("0xe44c0197ad878a0dadb88aa673b929d37666518edec85b3b19a15acdfb669c70"): true, + common.HexToHash("0x7bf9c5ec30168079940c7220721535493ef7abeac6f8426be150412db244cdbb"): true, + common.HexToHash("0xbeaede97f340df1928799d999b0e9f757ec2762ba1a4c27cebf4176c9d9677ec"): true, + common.HexToHash("0x576b785d3cf581d534a0507ef70b62d39446d1ed5f99bec1f10117cb4cfffe2a"): true, + common.HexToHash("0x91c1e81f750057578f8468fc53a436cc3c69a81db50d504f9e9f4aad9d7afe4d"): true, + common.HexToHash("0xb667501f328cc15d940f1572dd164301e300baa66c6c4adcca38238fb19201d5"): true, + common.HexToHash("0x5cc9525fff6416b0d3f4ba5fdf2edd8288db631b95faeda808281a4f23ad2f2b"): true, + common.HexToHash("0xd2a1ff6e351a7a65a921aa98ef62519930c458f81a9f9206d9f49377e23a0d84"): true, + common.HexToHash("0x16e3eeac6cc46a4b706426019762ddfdb2ffc9181cec40f8c93ed300f31ab70c"): true, + common.HexToHash("0xe1c93e8b2b808a81d613e2aaf4b2a081687e88884e22f867466f021e0500b0c3"): true, + common.HexToHash("0xfa55f9e9ca131e82c5829ab467093e0b742797d52539eddc4372d203d524737d"): true, + common.HexToHash("0xfe50cd1c1f220dbab4fa84105a75b71dd7e88ccdac4b79d324e4a5470919ca19"): true, + common.HexToHash("0x8fc33db8c4866de31b62fba8962399a9690fb743fe246e23b93175950be23157"): true, + common.HexToHash("0x202a5e62fd0343d68c752f80b21922234f13727d5d461be7f7dcda27edd8fc9c"): true, + common.HexToHash("0x72964c9737bb39a8fa2d677cf2d2368b70858224b48530c14440f874909ab23c"): true, + common.HexToHash("0x925c4fa54932818da9564fc28a06529e94560b9ac15c34931b95d5fee4352271"): true, + common.HexToHash("0x8762865681f20c68b9fb0d1ef23d89491f357d77f77fbffd7eaef186e9e1a4bd"): true, + common.HexToHash("0x78e8508626a40773ec58bfb55e2ac5fb2e66bf2a4cf15d537fa6ad30a6dae32d"): true, + common.HexToHash("0x6eeb7f3607c60433c5c99d98c574cf8f77b1fd93f647f0c08a7a6a47f110961c"): true, + common.HexToHash("0xff07ca95b7a48f3879f3155ba2b8956661f5001117630110a6921c08f8212f19"): true, + common.HexToHash("0x529d84c8a1dc1df589e5a15f0ab0e55dd100ca1f88498ada25ae171701a81ab9"): true, + common.HexToHash("0x0cc52154825329e2b1e325f94d19dcd1b4947c8d67b31d0dbebf3fcd2c1c3996"): true, + common.HexToHash("0xb1c5194f5f71285571f604eea45ad09dcf5ecf9c34761500f99500a2c63c4f6d"): true, + common.HexToHash("0x91c6d99a3e214a97cfada5e26b55c1dc1f9fc49ed8d5eb4e1cc875ecfc23a621"): true, + common.HexToHash("0x1f6409ee0a2341cdfe8c8b69546d2f2710b677879f1f23168c0532c2805f33a4"): true, + common.HexToHash("0xea4562e358d832783f7d1151950fc7abdbfa9da891d5bb1c686a4cc27d7a386a"): true, + common.HexToHash("0x50e7b90d03c30917111b891729346957759c8a204ca2bee367498da80439eb46"): true, + common.HexToHash("0xb61aa4e2f82e2889c0a2867a69aaae4199462d160e12a5ccc5b571d08128e2e3"): true, + common.HexToHash("0xbf65d54877721b8829830fd3eb7c6d09895421a8f3b9e7567782a30949691924"): true, + common.HexToHash("0x4456d6169fcdd29a829fa0ff23650a968ae18d619c8a73bc6d2fd29b0eb0ea4c"): true, + common.HexToHash("0xd64e7ad91c48c9ca0f53b22cce4bbca604ce612399d0e7f3b3c115d3808a1707"): true, + common.HexToHash("0x67bd6ff3abdbde4aad2a427ca0f17a8660b36a7a1c0cd078815c59c12b1bda9c"): true, + common.HexToHash("0x0d2ddde17873de37fd1da5de447f654151b84c451c610a15cf5d076f504031c9"): true, + common.HexToHash("0xca20c9d934f205bafd37347eb387cfd5266c3a4757ca6d2384b8f37d43016eb9"): true, + common.HexToHash("0x53ec2ca7697271e230ff0e6adec0948d567b7053f349dc2359b48f935689c2ed"): true, + common.HexToHash("0x125c2448221d4ef1159d4a5539d6f5f6ef218174521bc0bfdd8b5f82d9eb0b00"): true, + common.HexToHash("0x544f9575f26b0e830a43c99456bf892a0e33d5f00e26835d515e2edc3b88aa7d"): true, + common.HexToHash("0x974d6d563c5a0cd732e8743998cba92ccfbe03374828a453489d4076f46bab03"): true, + common.HexToHash("0xb5aa3bccd13998ff0dd14b7f6504fc1b6753816688995af466f2e0256e0db331"): true, + common.HexToHash("0x66d8671a4c5aa8ca6d2a005555abb1479b2aef0720fbc64a2040bcb501ac7fbf"): true, + common.HexToHash("0x21a1baa77fa7d017441826047f6bf02adac35f0f9678b55f701b9d075453e1e5"): true, + common.HexToHash("0x32f09b96b94ff707e21c9e7452e02f7f3d33a740601c822da64b8f249a0f1382"): true, + common.HexToHash("0x1fe789d8f0e05fc84af1207321558c91b7be6d31556a178b4a9eb7d94bca97cb"): true, + common.HexToHash("0x59f5284d2ddaf5d7078baabfce0f06c0c9ac1518d3231e3b9fa9dbae1b4f56ec"): true, + common.HexToHash("0xa84ed52f97d392086315475ea289b9224bb414c6f51971e89ea988a5f756e7e5"): true, + common.HexToHash("0xa9412a334a0e5ef54da9459cbe5e374f90205f4cc48656fd256b96170106dc42"): true, + common.HexToHash("0xea0621dfc90853f030ab29e4358470605f426d33b03c187ae6326a8a217f27ab"): true, + common.HexToHash("0x9328bcb1b5ddb26fb0fd1bb6e668db8642968298097b787a28c6ec311522b187"): true, + common.HexToHash("0x62f7ac4d29400b9ca5e46027ac9c963836274c3c62ba057f1bc0ce4bda8b9142"): true, + common.HexToHash("0xc4cc3b5d2e2249457b5677f6105b791431d075e426d9df5666334ed648864107"): true, + common.HexToHash("0x4952b206e3da6d12622517c3a121a523996941e43a1d7803d35841b8661d304b"): true, + common.HexToHash("0xcaf6f1bc0e8e0291241906a088dff3a1e6bd6bb0b96b1db2d71d7e5234f6d933"): true, + common.HexToHash("0xcc7122b9e533c6abc8501826ee71dee7f7501c5780a8163d1d7e13fb20879956"): true, + common.HexToHash("0xeea25f84ef5d10b2740d7698af4c72447617f7a4504e907fdd8ae0baa2c0a2fa"): true, + common.HexToHash("0xcbc3a1b31b6c6ce1b7eb08e322aafb32c78adb602fc711476816b730f1eb59b8"): true, + common.HexToHash("0x99727ed23435a7e3ee977132a79c235d6ffdcf79868b70951b1fc321dd1f1797"): true, + common.HexToHash("0x70759a5150a5ce3d63d1102f4b43629bf062cbd5ac30c60d2729ab1cb52d2cb1"): true, + common.HexToHash("0x2426b4229248acba13455bf2c940af0112a1091ee4ae4c87599037d2bb5b62af"): true, + common.HexToHash("0x687ad3ef03286ec8f9f86cb4ecf11abf185ce69e67d8be4e12648d83b5b0f1c3"): true, + common.HexToHash("0xa25c93fe2ee59c757cef0a7192bee208042569e588196ff023d9dd854e926e09"): true, + common.HexToHash("0xbab90dc28378b1dc5cc1ed0678a5e1799cd9b721e7d409ef1fd4ce88a81794b7"): true, + common.HexToHash("0xadafb1512fb386151edc281f98285388763a70318437fcab2a8dab274f325dc4"): true, + common.HexToHash("0x02e9160fab0d73a7d7df024e640c3785d0dcf72621f9d3560165a365ee01b2f6"): true, + common.HexToHash("0xf5b4a48a4af99fc887d559c0c0cc090c8c43a5417cd975d25de95e04b5f0d696"): true, + common.HexToHash("0x3d51c814a5be2afbb7675c3d6955db1b0a6645d5fabe0355b15d601b4db0cbfc"): true, + common.HexToHash("0xab73cffe4d4f226de31f2b761eb8f47d66513f84a72a811b51601d8501b052cf"): true, + common.HexToHash("0x5f8e271e6d340a6c08c851e2e9bc106613792aea4ec8c1f3788542c4f3d1144e"): true, + common.HexToHash("0x2fc2ccd4fc2f1cf88658397a869f501224ed93945864677334aae39dcd09b26e"): true, + common.HexToHash("0x43d3fa83dfb3e0b95a3378f88ba6910b65bfa8d20db852aba8d4cd167f35a18d"): true, + common.HexToHash("0x8cb8e0accd6371684c41d05a1f40991e8bb4682e9e1ce044c4d7b6993b7baf95"): true, + common.HexToHash("0x44a22ed50c6ce8e535e1e0e5dc3aa2b2f1820c685a124885d6b80b70607e8ea9"): true, + common.HexToHash("0x49ee17f8bf2bf9a70c79ac12574b8a0f14738fa57aa58b86b08df490af7a8c4d"): true, + common.HexToHash("0x741740b656ea5bf385fad93cac9d6ba02b6eb2292ac829c23f7438c4f8c6cc11"): true, + common.HexToHash("0xb1065d8016aca632fd7265ddbbfd82b95293808552a26ae703b2bcf236663665"): true, + common.HexToHash("0x46a1f68f8da872f1b9167866ff93e70461e3edee792a9b52362ec83335811aa6"): true, + common.HexToHash("0x32705ab6b251cd0ec32adc5d1a8c4a85759389ddb7ea78f5e96125d631b943a1"): true, + common.HexToHash("0xebc488762f0998dab2b686c9ac35bc32aa1f69951e5689946c19c3414b594987"): true, + common.HexToHash("0x6b53ef923a483ffdfd188eaaba4b2c79d7d6a2f35b5c999b992b8afa76c86cd6"): true, + common.HexToHash("0x399f8d2ba94c5fdc3ca800b87c11c96002fc4a9dd569c5c5eaa5daacb8a30499"): true, + common.HexToHash("0x94316fe1639d5b123d9759fa633ad6a01514a25371deb903f0d681c1bc657444"): true, + common.HexToHash("0x421e7def7302b60bc3f4a8c53ea422dcd5aca1a7ed013069fe9e787570318723"): true, + common.HexToHash("0xdabd3917c6b67bb28e434726a2c70df9f117b478f8a7cc3038ad8c3cda4568c3"): true, + common.HexToHash("0xa3aed060b325f5045eb23d0c5989c572e06bf042df163f8f0b10e77fb547c99a"): true, + common.HexToHash("0xd6ab484bfd0e61181561f452a4b3bad2f016a1d65d05c385a6b8ce4bd221467b"): true, + common.HexToHash("0x18b4662bda5540bc1fec7bb6097127af7e32b260d55f29ece3f12680517a9199"): true, + common.HexToHash("0xce09b0579b99af8b1ef7443c062c07ff7c4f6fb8114fc5eaa6b3bbb2d1cf6391"): true, + common.HexToHash("0x4b747027f9b63bfd0add785264d9372bc9760e407ccce97c51c81a894af1cd8e"): true, + common.HexToHash("0xd5a0f9534ae92f1ab0cec700b071b95661e4702e852828b2817d76bef18bee9b"): true, + common.HexToHash("0x09e54d0ec064ace14c7d62ccb9199104265494c59616a95ba17f165490ea2a60"): true, + common.HexToHash("0xf8533e3c0e90d797ebaed0bdb2071f51c507b386c3f504c1c2e8f166dfc6680f"): true, + common.HexToHash("0xf6744ab6657c5aeac277406da0142f72d3a8b1aff293dac81a423960fb66e6e9"): true, + common.HexToHash("0xbe5978fdc94c165f9717c2ba0bf5c898a6dfd25d7819fe11bfb596b72c83e9ec"): true, + common.HexToHash("0xb98d4562f11f5b62fffb1178b6e9a00ac9477c2b994673c1ae8a7e2a2bf686fb"): true, + common.HexToHash("0x86e275bef5d7c0079399d9f62594ad30401355d4c6d220a8e3e5c62bfabd5f9f"): true, + common.HexToHash("0x3c47b6517dcd7975c3382942fbd7e39c9506f8223c0111b115916a6b071e50fe"): true, + common.HexToHash("0x2ab7a9c6fe09dd5a4ea9c5d279f98933568a8cbc7ba0962f5556f5f0a0b5feac"): true, + common.HexToHash("0x3460a8df03dee771f5ac0f7b3e0ad05cf78a6fa43263e72998d139f1909367cd"): true, + common.HexToHash("0x8757f7f1715d6842f396b9382db02f5ef853b483373f2e81e4021463169b088a"): true, + common.HexToHash("0x1358c96c08bd798603dba608b9fbd461182062d58cc4457194a61cdd61b1b672"): true, + common.HexToHash("0x70d888679c56c1f418354f3a12c656032026443355d642b21e4a2510b1ca9a4b"): true, + common.HexToHash("0x957499ecb00bb90013f0f0e48b0a090135d191f2eb2c7359eeefb0c826b54137"): true, + common.HexToHash("0x2212993aa3be217c2063fdd847d48c9de22e8d6be1f1b103d8d1e0dcf547c598"): true, + common.HexToHash("0x0ef767b5857a6d0aabdcefe925a07de4b6732f402c12d220837562a998d93506"): true, + common.HexToHash("0xb9f0a1a75e41dd193e84c0538645e97b00ec32948945606881786d31337f8266"): true, + common.HexToHash("0x929f616f2a7e725cc18a401ba3ad0df7586c1035773bc3da92b86d8b93ed7041"): true, + common.HexToHash("0x2218b2df6bbb10198388539d55e00f611be1454676a34a754598246cfc3156e2"): true, + common.HexToHash("0x149af9d53fd907e1533249b1100e3df6362ee801c0ea3a98a744ab885516a290"): true, + common.HexToHash("0x92ec0d079f7fde09423f4243d122cef4c41107c4dea97cf73b8ab2a7be061690"): true, + common.HexToHash("0xd8ca8e0d539ed2547ebe7b562333032d3fd765c4d0b5ca52a49c0232a0a4e999"): true, + common.HexToHash("0x20e40f174faef1babc276acd60096e02646f6600bdd1ef16fdd65f20a2970bf5"): true, + common.HexToHash("0xde5cf87e999e9dfb8c163d516148ff4c121871b2c775f4082d47e2d07d0190df"): true, + common.HexToHash("0xaf518d3aae4a55f7015255a61cf52f07d0965c04b549f2065619fade0f2f0ac0"): true, + common.HexToHash("0x6cf3d83b3315e390f2c57d61153148f8b733ea7c4cb30390f40b5e1baf106e90"): true, + common.HexToHash("0x167a7f3c8959daabc97de4ae1e8e10fd51acdeb46726d3c4ca495cd5ea1de68c"): true, + common.HexToHash("0x384310b8c23047724a62c871789fc409c41b2375d3f954b6a5d7479ce197a367"): true, + common.HexToHash("0xb7847b77664be800fda52a04a58126ab70efe8c6e5f0d6da3848e987840cd1b0"): true, + common.HexToHash("0xa7c5f1c7451949db60973c4b665a4f8f2d614c572bd2f7700169c675b36f284a"): true, + common.HexToHash("0xc417b1adbbf3bf8bbe5a9e07e4a402ae413ca02fe13c8209bbf2703fafd49206"): true, + common.HexToHash("0x1cd5700f7b8d7eeb5885e39afb9a558c4a90b6315e9ec0d1cb3e0d49b7c22816"): true, + common.HexToHash("0xe101457bfcab8da2b6659da560d6c064719019943e8b33f523ef2b48c02dce3a"): true, + common.HexToHash("0x06652e0f1cae19148e997034d0a1efb58c6e2f3cbde1be5259af51a2a0d8bdfb"): true, + common.HexToHash("0xaa8cf49251a503af0b15553f1f220aef8bfd007b064d7c20fe3bec1e210955a0"): true, + common.HexToHash("0x33b479ae8834495bf08dedf3749fb0fd6608f6bbdce139c69094a277b652b0ab"): true, + common.HexToHash("0x2bfac542e9b9fbdce1806adec945e37339564287bc49fe2e4771991fff8f11bf"): true, + common.HexToHash("0x693591e674543f2ff6a4edb03705383c7f111fda75c223154e6e1b757c67851b"): true, + common.HexToHash("0x294722e16d94f3abb746ef776699c656f0dedf34452dbf9dfe5d838d33df5600"): true, + common.HexToHash("0x17fd910aa322f00838b163f8cecc1808d3df406b11569cca7d83f720fd6635bc"): true, + common.HexToHash("0x680695999be4472de06e2c4d53e4f242bdb508a112d3008d6798cea68e6fee3d"): true, + common.HexToHash("0xdfefaf210609290cfc30cb7d9f2d1540443384f5ef8ee561e017bb7dfb147b94"): true, + common.HexToHash("0x78909329b599366d4b1d4a8c4f63508491e4430eade131a770363f78d79277ab"): true, + common.HexToHash("0xcc394c3279d25e0b6ddda5f733e84f5617337b69d59903e5ca819712da944225"): true, + common.HexToHash("0xbabb0453426647e7f0a557958559079471732f1cd0c34f01e5b1a1d5eb5b826f"): true, + common.HexToHash("0x9c02a599fa73b0c6554cb902f644c2e809f03bb2442d4102d718627e13fe58d6"): true, + common.HexToHash("0xd3c283e130df65d386a865cce695473f25e2fff42805e00f0f9f6f7f332bf800"): true, + common.HexToHash("0xffb7f2ebbc85415b3e53b3291375932bffd9a4893223bc9cb5027a10e6da0ed9"): true, + common.HexToHash("0x3ccbc96583cae682761d31ee4046e887f17b07c9dca37a2f8cd72f450d76b1a3"): true, + common.HexToHash("0x3422f7f4ad8c20d555005f0d76fd45dc6b882e493eff988622a04ad931dbfbda"): true, + common.HexToHash("0xbe1126bbc12f8257154f953f5ce77c8a59d2b07f736bcf9bcea5c1abc495b1c8"): true, + common.HexToHash("0x9917c646915e4f18d6c09dc3a825ff98d0826a165f8a2ebb9edd5eceec9dc7da"): true, + common.HexToHash("0x45bd79d212beaf95b390bc9a8cef5c078a126b0195e59d56749cf88165b508da"): true, + common.HexToHash("0xeb043420e88b9f0f25cc6eea4c7ca56d241c7fe763bd4521548f62350f750f2e"): true, + common.HexToHash("0xee75861010f7d78b06fcd765171be76a34d96433b67e81b615c9c454dccd77b2"): true, + common.HexToHash("0xc1400e9f20fc2084504de96603b7b03053f704e702c2e92202bacfd1eba098da"): true, + common.HexToHash("0xd20f88dbdaf20bc629da08a1edbb96caea7f8044b8fb4f4f1051049938617642"): true, + common.HexToHash("0xe1557874f1669c9e607c2fcb062615dbd5046e075d4069e1645d75f5fdd353b3"): true, + common.HexToHash("0xda0b9a2135e71a9851f22dc3bba9b9a1e28f46b46c7d70a0c6c75ea8a0f440ad"): true, + common.HexToHash("0xed82cad522780888ee3b227f7467209397330427741f1d1e01fb2fda5e4f84ea"): true, + common.HexToHash("0x15ce699ce456125914c257ee2191fefa82c22af0cbf6ad4ab87b6f1274ce15e1"): true, + common.HexToHash("0x4fa69efd1fe8cfbec6f73d6445204e8994576593b174a0283fd6c03e114157d4"): true, + common.HexToHash("0x5da748e143c3189504aa89e6c8d9e1c8ce0c85e39ce871d7c6b553a1af48dedb"): true, + common.HexToHash("0x96ce1d6c743e29f9cb73624cf7a0561f27ecb1ef6399ce12044ebc9a09e2db21"): true, + common.HexToHash("0x2cab3e6bc51fea5daa4732e63add548f22dd97979d28f6067a924a24bc5029de"): true, + common.HexToHash("0x7386c58587c9fc09edd81f5c90024b2dd7babfb52a848ad01ec489695044dace"): true, + common.HexToHash("0xc3a1cfe80af7da5441e5126e8d18e709c28aae825b6e291b7eb68d8cff473693"): true, + common.HexToHash("0x1af14025a2fb7547821b88169a7609d953579bcfa378d9264832e6d3e2b78219"): true, + common.HexToHash("0x26fd559aca183c70f76cd59c5fd2d137e846347b63bf12abcf66cedcc5c4f051"): true, + common.HexToHash("0x2407e0b257aa481a8c5744143d3ab74e69d767a809fd5d28efe31e0d5234d9b8"): true, + common.HexToHash("0xd2a80c8ce099337bf390abf3a925c4c76bdce8c6e5efcbcb8874070f64b42d75"): true, + common.HexToHash("0x5cb53fc763df72668f838fd01d38770348da5461b4093ebbfc70fc39538626bc"): true, + common.HexToHash("0x7a6e0cc8ca5ee9f482f97b89d96b6dedfe040c017b9a1aeda8576f004c186d99"): true, + common.HexToHash("0x0baca4b4e53cb45381e1db46995226e63268616180a460e9cf09c31261509d92"): true, + common.HexToHash("0xfb7a652bc83f1fa98e2e3c323d45ef1c510f4a890806dbd2d3582c28e06f6863"): true, + common.HexToHash("0xb1a874b01dbcff905a679d657bf080cd8af78a25cb55d961836a97febcee0278"): true, + common.HexToHash("0xebecbf7142c766cbc7433e42fbe08a58f30bc3d6ca1ccc34d4f1733dee1f2c4a"): true, + common.HexToHash("0x24f187eecd01d248683cbefe1503432b03622b47944bc8d24a7209be19462a57"): true, + common.HexToHash("0x408f93e793d666e74edd3a20f846d64a7324954ea9d10197da0c7532be8961ef"): true, + common.HexToHash("0xf6798fd85ad2b91d97683727ab1375fc57accc157bc49736ea7812ad7b30acf4"): true, + common.HexToHash("0x0290d7ad1f07de29ad3e0986bd33bc8a15b06150145419e3838343de2cf35956"): true, + common.HexToHash("0x9928a33ca4ddbafbff4e582221b41fac8ba3c684ad19ef2c587904d016519fbc"): true, + common.HexToHash("0x92dc8ea4afdb731adde2f389af2b1f0218c68256f4e64fc7375ddb2b474ddc98"): true, + common.HexToHash("0xd1a57fedf082149c5de55f8d0b1a3e2870a0db2f078af55a05d00a945df320eb"): true, + common.HexToHash("0xff7ae6c1cf3a51adfaa954dd7d47375307bc27f55816907cea002c9bf741cba7"): true, + common.HexToHash("0x70d8b0fa33b152f337475ae09ec98701f569dc05e9143865f329c9079f09b9f1"): true, + common.HexToHash("0x800df45db86cdf6a3da55f6e4edfe9b8de208d6c318ac1851fcdb2dd79163103"): true, + common.HexToHash("0xf267db8e38e8439c5a3e330e0e81e3652831a5c3989c451ab3bf07529b590677"): true, + common.HexToHash("0x9208c7a8b9522097d93f4bed6e1f19c660ec4525ad49a792efe0e12361303aee"): true, + common.HexToHash("0xbc8b7aba78ff8b0b97c0f7d79d690995c2334b99a79b6f1963603f132637f008"): true, + common.HexToHash("0x924c6b922dc0dc0df3ce43db552ab1fa618f24b49569f82e6e0856e98c2acf1a"): true, + common.HexToHash("0x323251e5bf0d566d706cb393f831dd66792740636b9f71f432a846ffaf54337c"): true, + common.HexToHash("0x45e7e0c0bc83d0e558e6b0fe46259c62d52e024ecb680ab006f848353fa14260"): true, + common.HexToHash("0xae0364d2eb4eadb8fdcba1c322dec6515965c47ce97836febdad6a565bc89d1d"): true, + common.HexToHash("0x5700851ca0a7e82ed1a68054edd8379f46a7b87f2e11515a1f51284954067864"): true, + common.HexToHash("0xe9a7e15845348b0cc892728a8c937f1e40e62473617f6191a7a7a08ad2e3f878"): true, + common.HexToHash("0xbe9a71e8fb5e1376637a29792623c35bdee05aa5f765174b4f310962b33adcdd"): true, + common.HexToHash("0xc6279ac2c7b60bddca184b2d02584021c064bbdceb7acd83d0485e0cb66964b8"): true, + common.HexToHash("0x2f9e5dc81749e79f7c1d3cd5f2401f62bf08f008a112f28056f228425ee891c0"): true, + common.HexToHash("0x7305b20f68049cefa74a07b880e4014afe8478c9a2aeda3c860cb4a0ae08edf2"): true, + common.HexToHash("0x9fb6beecb0c04126df1b4f33dfd668a9e196a9b5f6187f3229fed04d80421cd3"): true, + common.HexToHash("0xa17faee2ae5bdb733ba4930af53439bc2d05cbc9efa370ade01a15074df45377"): true, + common.HexToHash("0x8f3e0b9bd45a1cefb197dd782a692b5b76755e0d50d3f2928028daf9525b4730"): true, + common.HexToHash("0x1badff38b17570f88008414e946f5d17528999d48c3abd3977afa9c9ddc312d0"): true, + common.HexToHash("0x1a4698d4ecf65e3f0ed8c587135ab0ff22162dd481952aed3770272e2e8780f7"): true, + common.HexToHash("0x7a75ed3781b886b1af10aa94c1702320560c5e95f673b483272632664265689e"): true, + common.HexToHash("0xe2fd9af6ed063a38a8f93ecca36bb96698b132801d00f4183fa2271e03d9088d"): true, + common.HexToHash("0x5fe5aebc465b8db27c946701bce91d6eda0a273e9031b19d8fe2394a1c894271"): true, + common.HexToHash("0xc91a44b776461ba656a7c6e618adadd29592f5a2e46ad13406fb1888c799a8ef"): true, + common.HexToHash("0xc3bcaa37edb0c5a64f4dd5fe1a0585c0c45acd46728bf1f7f8c54edb1a9a2e50"): true, + common.HexToHash("0xfa82adbcb2d680c0790939d2132af44f2f28fab795ff69146b54dabaeb378d30"): true, + common.HexToHash("0xada4aa168dd02ec050c8a2e5cca0198db918f46f6a2e8e3d4d57f43386830a27"): true, + common.HexToHash("0x0907a7816fd1d11dab193fa3dd5d7c0888790a7b3a0e8f0a5d6a7ac8ab249e6a"): true, + common.HexToHash("0xf422204816e4202120ddac4a09786d7047fd05ffddf96078f70056476d414f4d"): true, + common.HexToHash("0x120f0244cce8400611b10d5a2cb59f113734e91c9bfa01a0d418611474f15ac6"): true, + common.HexToHash("0x98d3d7ceb55651671404c435e0d2aa428d659a39e8a87ec8d8972bea706e1fb8"): true, + common.HexToHash("0x9be9cdf7b6e21ecdb1f5c85087435a88a3b618a8625bf1ca53499ee23de8cc93"): true, + common.HexToHash("0xa24a3dda929992de5a20b5d29cb275b8f1be5e2f1e0a85634a79d2bb352222af"): true, + common.HexToHash("0x835b10698925d0a5473b7c18600c79d245c4a1e3f28136decb2ab88ed892108c"): true, + common.HexToHash("0xe5182278231081c6ac7c95c1b154e667a41f5af7453d735a11cb37cb01d286f6"): true, + common.HexToHash("0x79a364542f9d9713ef6475dc10105d30d35d488ee2d71677802b60f45970c134"): true, + common.HexToHash("0x5331b9316b0b3f22da68e6f0c4343a62febd74143b2401a1182b91252b1c818c"): true, + common.HexToHash("0xf4ce13d5aa186cfb736a485f430e99f5954d5246ec81231654a8760485054055"): true, + common.HexToHash("0x9a798c8125dc5494f1a73f8957396934edb883ead19d1eae3a55b2e7b0df6660"): true, + common.HexToHash("0xdb45414e2f0f2ee1d7b8089c74e9aadbf10401dd91ff50574ba2dd6f52ffd507"): true, + common.HexToHash("0x57f57efef0e12f84de34d3f33ea9115e0993075beee367234a649b73bf9d115d"): true, + common.HexToHash("0x6b856af5068e15d54b0a65c6610e760ea872f20c9dc64b97e9d7ed2306b0dced"): true, + common.HexToHash("0x1c3e6571e5e2e85cf3ba50c971f5540ebe4cba18d4be1bd5393be4a57cc43d31"): true, + common.HexToHash("0x2383445031a652fb9de7f656256674d1650f0d76ea937883af6131614e1fa2ec"): true, + common.HexToHash("0x3e228255fc888b7c1b5f5d2c882a66de92d1bd77e12617fc5a7256f973f851ce"): true, + common.HexToHash("0xc13780ce7041295c856a1a01ec8a9b86c362ae1d929e537df5cd19ed859c0961"): true, + common.HexToHash("0x5bd1e49fa7755597b6aab43a86f3a6a2fa4c7597f7ed1c405b93f4436797976c"): true, + common.HexToHash("0x8e8530329df9da3c19b613be1883e5c6db7444db3d38f3b5a174507492c2a74f"): true, + common.HexToHash("0x5a61af54d84eaae46babc23b1d5cc4b4489635923652ca60da5b99d41ef8a515"): true, + common.HexToHash("0x1de72e6955e60567d48b200258f4c52e522bbc6abfe801af5cb68e6c8ecd0c4c"): true, + common.HexToHash("0xd76f499d3aaca60109415b7d0614942136ed1eb4a34ebe315c97f774e352b162"): true, + common.HexToHash("0xf6d7c06c6b93251375aacc7cb6522776ac3f13719e34fdf1e6a52de89eb498d7"): true, + common.HexToHash("0x77931cd6eca3e7cae94683cd8560fcc3f8046fe0a81cbea79ad62019836c80d6"): true, + common.HexToHash("0x571e8946823f2b7de0746f0e9de46a9745c00a8099946d800318f9ca5a97ec36"): true, + common.HexToHash("0x6a60eae2cce628c568c963f1df54520755b2c02765eb4d305ed88918b1554858"): true, + common.HexToHash("0xbf221a16be6d3aabedfa9cd970ac86f62be2f33827400c272a54ceb49fe21dc0"): true, + common.HexToHash("0x509105fcbebd89603c1d70bcb35df157f7843d8f83ebaccc6ae4015f0c6728d6"): true, + common.HexToHash("0x9473dfe95c29a5e8150e4c7bad32a9b6520f0345eb2c0858bf2bc6c578554a86"): true, + common.HexToHash("0x7a2c700c9b0fb019d8c5b086b950ee22d656f75e9544624c102b53ae9f536b29"): true, + common.HexToHash("0xce158ada44c2fafe3badc5c433e2ff837627217e9eb8c5fe48c2559398c618a7"): true, + common.HexToHash("0x67877b9d0625d30aa515307e76e42f9f26014cf3ccc08dd5520eecc7d3f7a428"): true, + common.HexToHash("0x3f0a40bae5ac14d8c1fb9e37a223557fae9bf8d94908daa829cfd7077a676fd5"): true, + common.HexToHash("0x410ec8d74f35371e826db5d0477ea9cd24487604462c7dc59bc87529806ef5b8"): true, + common.HexToHash("0x3c580003a457cd3bfdb1fc42b23fa85ae2ecc4cfd4b91644f742faa267e349b6"): true, + common.HexToHash("0xb95da8cb652216d7520c325a20d5ee2b9a805a91b4b7a7ee634d5588efe9cd4d"): true, + common.HexToHash("0xe8cf50ca87d93d534fa485d93355c98fb2afa99c4578813005f0e611d8619ee2"): true, + common.HexToHash("0x28ec01f3c938e20f1707f01228fc2fe143bac2886bb9e395bae92c3d240fef40"): true, + common.HexToHash("0xa93b2c554d011da6b1045dfc38e2778ebed45994e705cc0d407499e04e1303f3"): true, + common.HexToHash("0x8a94d3f11710595a9d316d1dad616ee192dd243a79e5390811b4199a6e53e565"): true, + common.HexToHash("0xf2ea318c9e7361358f8688d6a3109029aa9a05729fb5c44a6196623506182fc0"): true, + common.HexToHash("0x1d1cae40814a931f1220d337851d43667f3b9a9368a89e5fa7618f84241c48b8"): true, + common.HexToHash("0x2c8162448f880d76ff7a877bb1357c4cd3309db7bd5e371c4115a9775de382ab"): true, + common.HexToHash("0x2f6bf59dbde590fa0d2a59ab38aa84e073a6570cf8818fbfac93567e56b1a7e8"): true, + common.HexToHash("0x32f9aaa240cccb4de64d9d00dc5d2460381504747fd5e578e7e4486b71376701"): true, + common.HexToHash("0xf8ad6bbc81c79ee3124264f27d01287ee6988d17ba12cc6ca3b5cf7c43ae72df"): true, + common.HexToHash("0xe65bc05fea1203f586e4932ebf762d7b56fa36b8a4441fd822e82d9941218e19"): true, + common.HexToHash("0xdc87e1e24aad5c7807e3ef4a11e5e55454d92e14e60681bb58a011d0552e97b8"): true, + common.HexToHash("0xe76354a54e5110cf0bab1d2e05f3fff04b550680c0fd1ccc89308b8c871d7b1f"): true, + common.HexToHash("0xa133a9a66c11879887684789d52fa835ab43d195ff5db198d902ec4b88d207cc"): true, + common.HexToHash("0x4a21863bc4f1b1b5d5098e9d11aca412c124bf79d33a06b9593175685869efd7"): true, + common.HexToHash("0x3f547181c1c328cebd4387c2c95e4717116875eb1bce4d54804af8587def59d2"): true, + common.HexToHash("0x09408a524ab6bdfa7de033a8325ddd799bef48be3f37731440457256c8ce3985"): true, + common.HexToHash("0x038dca969c5d76947bea40ee7b32abff8ad87737662e8f36cc73947aad989e12"): true, + common.HexToHash("0x77d726ffd6531463eeaec52681e8fe84fbeab6a115e610412ba93f528cf43f62"): true, + common.HexToHash("0x8343508aca497a8eb2d7a236ea24d8e2a6ca80f536413d0c1745abd17c465954"): true, + common.HexToHash("0xa1258e9696247cec2849ebe5c6c18396000cc4720aef2970966ec947e3736528"): true, + common.HexToHash("0x4fa9bd4ba3a39c0b560b9fff692e7ef4b03c8d388e0f1096b65a611b4e267566"): true, + common.HexToHash("0xb5c691c8f676a7ccef8dc3e3eaa9fe65299b6b227b1b1e7815c4988888e3b939"): true, + common.HexToHash("0xf1179e8c04b8402f99acb2b0d63678f759e90155881a55364ddca4cd6ac72fc4"): true, + common.HexToHash("0xb7e765449247d764633db1286c7bfc1af9a2f49f8ddf63a52c9aa3196a28225d"): true, + common.HexToHash("0x7fa2140a5002d9cd1687a605c41d8d85ccd6942c509271bdae96ef0b33d3d571"): true, + common.HexToHash("0xfef1796abc0a1cfe7b5868b5dfc78e3a023df277e1978f0b7678f8e4870d0be3"): true, + common.HexToHash("0x6b0160a7825c884d60bbc048d4d479ad229086c862678250d28653dcad4507a2"): true, + common.HexToHash("0x520f43bcf1715a0a40f118d3fc493795abc4c8146eb26ca7bc36ff439dbd029a"): true, + common.HexToHash("0x7b652b1b76a953e9ca30f1ae617905bd8eb2363973981bd24800243ec6c9cf2a"): true, + common.HexToHash("0x147b493834798c086d5922ade15f9df9b8cb86aa3ab8c92edd59e9b9c49b765c"): true, + common.HexToHash("0x3ddb03868963564b6433cec490c853ea95efdcea6da2d938373e7199b682ef4a"): true, + common.HexToHash("0x270f76c69681083335e61d800f3ce0e193b155b8a7749bbb45337221c8333a01"): true, + common.HexToHash("0xbc5b3e8891994629c53494e0a0d7c4f6286afee9ac5e1748c7424cc9a89feba7"): true, + common.HexToHash("0x9f569d6b3e721391a14cb30a5632f5eca6cb51e444791839a025d42ba486722f"): true, + common.HexToHash("0x2344764b48fd63a0caa9807e4db5c65f9d84855ff817c3c5488bee3914a11b39"): true, + common.HexToHash("0x34b4bba29823eeea24a4a162a44bdde86ff10fce492d4d6a8b9239e2564b10c0"): true, + common.HexToHash("0xb9816e268a1114088ecfe01bc4e5ead47d7a2c5432cb03b9ff1eaf80e92d6e69"): true, + common.HexToHash("0xfb29c5ca5df49a6d537c2918e156edc730b98dc08386442a074933811ccfcc0a"): true, + common.HexToHash("0x541932a76f607227a6692f039133207a24b6aa8e2cae4559977fe13768340e1e"): true, + common.HexToHash("0xc8b7665d748ee4fd873b1c89f435592497670485d000a1f407244c458379c1b0"): true, + common.HexToHash("0x4c00349836ea9c1e6387367761bc333f94919a9a8ed27caeb481d18a01068a39"): true, + common.HexToHash("0x3f86bb9372674ccc5cf13669f9ad1165bdb8c77fb34085a4dc276b7cbf527c46"): true, + common.HexToHash("0x26b9f2f747af656e729e170816848a9eab803a30cdbba0fd1f18b62628120912"): true, + common.HexToHash("0x4a7782213641ac422002ac8924e249dd03b54ab022af7b49a1c1031f421bfe8b"): true, + common.HexToHash("0x6404a9f92e51a41c41c3aa6084298e08e1b448f099af26fab558dc9ee0de5af0"): true, + common.HexToHash("0xedea1189d696997e61a9795f06feb507c8b8c798e3926fc64bd6ff212540dfc0"): true, + common.HexToHash("0x70febddc6e956e2faabff09f08f23405c9efbe958e31bb7864533bbb918c4eb4"): true, + common.HexToHash("0x5d28aacb1d65757ffab86bbfb1ef91b43d16f2314126d9bbabdfd7f3a63ee2e5"): true, + common.HexToHash("0x1606fcdc09079630162ee909dc479f8ebd7e4719b82fcab24f53f36c25cd1de0"): true, + common.HexToHash("0x1d9e656bd52325aa474190baeaecdd920d59f9aafdb8b676e0cfd304ba7b878a"): true, + common.HexToHash("0x53bc5eda5953275d869bf298aa32aaa9a778fd84672bfcedf30ced2544ad2ddc"): true, + common.HexToHash("0x6c7fd6ea3b3233f883ba012150ab0bef693b61317e07f2375006c568021d25da"): true, + common.HexToHash("0xd733471db32590968f79dfa49970b314a327b872b1ded9a1a8c8726e676d58ab"): true, + common.HexToHash("0xf9edcf7a0448e9dd510b99ac7a56a503898661273eb76b549dc63d378fe0ee00"): true, + common.HexToHash("0xf63798bc22dbb0788116f1db3b7e31c0ef3fe8995bfd2c3b139eb7be367a8f07"): true, + common.HexToHash("0x9204125cf631349668954526753e2056a536991a9d4a99358e77e55ff515b447"): true, + common.HexToHash("0xbf3daf382a5585b9596bcd0d7663fe76e3f5a843fbe7cecf1c6dcb50823c954b"): true, + common.HexToHash("0x0628adfbbc85c1212b77b4af07223b8af297f5f2ae54601c3e51c7df6bac32ed"): true, + common.HexToHash("0x4ac27a375754f7ed283cf2628190e5dec5efebf6f9f85d9aaa3e9ac529b469e2"): true, + common.HexToHash("0x9b9a1d220b37b1521d8a3942b4a52c44dc5a4758ec4a605ecd7c0679d4bee516"): true, + common.HexToHash("0x846cf4fa72f3e3a71faf7e5a514088641da766426318a53f24abd8609f5383d5"): true, + common.HexToHash("0x66ce5839548a816abe06823830a23b44ab30765462356f6ee34e1d47d56e15ac"): true, + common.HexToHash("0xf46838cda004155001da6fb87eb85eb6710c326617983139dd379a809c496c8e"): true, + common.HexToHash("0x3e0b72131cf81a9d076b8dff68e89061dd653ba360a372120833b7da9b5f87c7"): true, + common.HexToHash("0x081b03158f0f52a22b28c4f7dad9fb6d9e7aa211a6ff91b710f3cc23666ca98c"): true, + common.HexToHash("0x6a0521ca3765cf112bada89960e108b87c40ddb3fff413f97d946fe97239b3f3"): true, + common.HexToHash("0x53692668c56afcca4e8794261854225adb3a00f1c994518bf92a8db0e80b83e6"): true, + common.HexToHash("0x63ff400f70e2a61d9ebd719ca8b184cfad923135dfd2b0a61bcd01e037c59a53"): true, + common.HexToHash("0x3da55fc2c13789563bf95f9b599cdea2cad4ea5ce46ab5071c0bfeae51e19044"): true, + common.HexToHash("0xe016f35ee5f8ac5e7215da68d59ff1abe959a7f23ebddef3a00485067c065585"): true, + common.HexToHash("0x5515dbdd43589a73cd326a1c80856512e0a23d6bac7aef06af6c259c18bd0fb7"): true, + common.HexToHash("0x283d937d8cb8623b5513691cef02776695963d97278310f8c22bd36341b490fe"): true, + common.HexToHash("0x16e2a69dec6c2a5ff2197611169f76c09162b48d297767b0b8683aaaa8af4d19"): true, + common.HexToHash("0x8de4b68f1506b2131a09dac4e2846ef0b31a58b8e02c9ace613431483814bb80"): true, + common.HexToHash("0x10d5d897520477af195c36dbed120771ffa557eb260bf2b0f2a81c2151f15d87"): true, + common.HexToHash("0xdddc1ecda1dd5aca9d0ed825811474e214e3893710cb40212500d5c797fde191"): true, + common.HexToHash("0x08bbea0c7781be6df59026ab3b97734f3bb9b39e63e2bd4ebc09ac122c1bc3fc"): true, + common.HexToHash("0xc7aa8fdb42c3e5fa9dff0bcad2cbe946e669b9ca8379ff6262fc8bccdd18cf70"): true, + common.HexToHash("0xef9ddcdd97d1d82893e2aaa7736722bcf8cd63232f1cef8a223594da21a888f9"): true, + common.HexToHash("0x824ec7ff5d45a1a0e3d407807a0dd458387075f7a5184896d704cbd83cf1846c"): true, + common.HexToHash("0x32e1ec8604cac27a8ebc15ac8d1c4b7cc572ca5032521de4e13d044372967937"): true, + common.HexToHash("0xbbf2fc5a667524327268835226a79d3ce85ee53d9341023ac1a5a0929fd60a53"): true, + common.HexToHash("0x7a8b935d77ee0988143be9e150ad64e5666dfafaa602818b4956d2327924e86e"): true, + common.HexToHash("0xd5c2cd6e4f7f9763da7c3e2aec3c2ae71369298e7fb6a83dfa98f32056c389f9"): true, + common.HexToHash("0x86a7ccef11cd34b880e6e92c9ebac7ca1e98a56a46372f1621308846a6ea4476"): true, + common.HexToHash("0xa5705d5db032bc5e8d995b65afe8a610e39c8f8a3900fc256e087b58c3bbc18d"): true, + common.HexToHash("0xcb8f1669c7b23371aef3a479197bdf73255d73b8258645b0c117fe9875bc25e3"): true, + common.HexToHash("0x8d36a45740d745e2bfd8655aa46685771a2e0eca03c2547b28ad01356fa22a75"): true, + common.HexToHash("0x2fb3a7d32c323c267bf1150aa1d0292efc67c272441953e6187d394dca891887"): true, + common.HexToHash("0x967e3ad8cb692e04a1e02a692c371478a53e4598af89af3dead3fcd3a6b0092d"): true, + common.HexToHash("0xdae6da10345a3db5c558e9c47661ef25b922fd7e5dde73873e78fd583b8a1698"): true, + common.HexToHash("0x50ce24a8200d0df1869b842a2ad140b526ad59d983188c7a9d01b3db6120b164"): true, + common.HexToHash("0x75f834d289eb1588e8d88c46374ab757a825efcacbb98cdb7b035383ce90039e"): true, + common.HexToHash("0xbc0a4445118fd3c908b711e66f95b63b355b7aa52995ce9565d2f58de1fa7d32"): true, + common.HexToHash("0x334a666ebc2774f3a66b3b958a99805472039cd298624aeb3d67a7d0cbe3520b"): true, + common.HexToHash("0x2fba637f662df9387552d65b052d607f8be8ef323dea1d0f9ac0f776f3471c72"): true, + common.HexToHash("0x10cd86bf177c917e00d6b5105a2befd52518ef7992978b87397626e45c1a0a21"): true, + common.HexToHash("0x11fdc3582f094512953e9f25a27fbd5efa00b2ce4d8bbbecaa5a40f79d032e61"): true, + common.HexToHash("0xd03f615468ca10e1fadc05cc91b04a4f6c9ae462d24b8188bb9b2dbcfbea51d3"): true, + common.HexToHash("0x546d72a11937bdbe1d7ed5c0331e671d92c5572b38d605935f26f42a6276ac9c"): true, + common.HexToHash("0x9de14a965eb7d3e33dbef82f8982e38544a30f30deb88c30da29761b62f422a3"): true, + common.HexToHash("0x33ec984c05fccbfb8f70aa225d8a333c35a8c89d242f3a3143669ec9489b73f8"): true, + common.HexToHash("0xfdcbc1a26b008ef366beecaa32d62d3e147500c9f77e5f132917dc39d2d82d17"): true, + common.HexToHash("0x7284a683b9ff457053aa902ed1a79e618e570662acade8c162409b3879ce692c"): true, + common.HexToHash("0x1599a8a0f847690f9fb58d742c19fcffb381321d4d1333ae295cfd200200150a"): true, + common.HexToHash("0x69be8ac8d9436c77514e76b3b93c3ba5334ba76a16d3210b4abf96420d5c3b41"): true, + common.HexToHash("0x67a8218ad67e2f0df72620100c6ce86f48ddb055cb8f253d927dfab0a290a611"): true, + common.HexToHash("0x774dd0f5dbaf4c2aeb35b899a715ab599dc87150aa65392b3e9d4d690be6637a"): true, + common.HexToHash("0x732a46c1b4d3ee01aa49cedd83a154e1a022d73a410f0704525df19ce0a65430"): true, + common.HexToHash("0x0ca1f82f0ec041081f73d96c5e026242cbf117f14f12bec97661d87c5c791100"): true, + common.HexToHash("0x6c4b2f2878be32653fae84fd8953419ec46106231b384688e9afd97a8dbda69e"): true, + common.HexToHash("0x817305544aeb51babbf9a484908d097f13e9163559e83fa75d5d78c2c8f20265"): true, + common.HexToHash("0x683fdcaa4e37fc7fe2bd16c487f71e88bf7e2849014ee1f9bd7729cb081a732b"): true, + common.HexToHash("0xea31afec73e00c8f781e4ce0cf840b634879debca9e2adaa67950e6d219ca9bc"): true, + common.HexToHash("0x7b2623a83bb8d328fbe345eb0232cc21c68fcaa561873b1dc3cf20de59483f8e"): true, + common.HexToHash("0x58d0bc5daccfea0715132d8459041cf9ee01aca4d718b567315645043d8d0422"): true, + common.HexToHash("0x8d76db673e48fa27ad714b342b6e6d30628819affac4bfa632ae42b6e175ce82"): true, + common.HexToHash("0x579811ff7adde3136f571a75f70eaa0d1d8d7b425cd6b0826ce70a31610b76b0"): true, + common.HexToHash("0xaae3e650ef23b3c0ba5bad973e3c39a60add4fd73841d417e1d80dac44bc239e"): true, + common.HexToHash("0x834d034a2f584e3006e739db0c632c9bbe77433b2b45c5e41ec40874ce9db3b7"): true, + common.HexToHash("0x66ca74e0b0b5f8cbae712fa3ed4e52105ce88688f3100c3c539906d328919e1f"): true, + common.HexToHash("0xd7fbf46fb23970dd3b04386b93fc1d0c1645fdc8b30c67344a86816a49438079"): true, + common.HexToHash("0xffd083aa95f907bab28594fb850edd81c41a9ba7cd27d2fab16e69bb33d8312d"): true, + common.HexToHash("0xaed049046200c2f715dcf884a6022f3d1904990bbb689481846426f1b2611239"): true, + common.HexToHash("0xfb858ac8ebbebbcb39631d3af0b863d9f7f2a26b6cd211c2301e7e20ce817dbe"): true, + common.HexToHash("0x258960ede3e17d69becf186db938467836f3e756ab07b5e03231ed07f9002432"): true, + common.HexToHash("0x5d9abe83ba8479308533271219784e2f98af9ec88fab9845be8a8f37e8b640c0"): true, + common.HexToHash("0xc6121576a64aa93009d3426b6584d6b6a0a5e235ed4702e9b974756f110ac227"): true, + common.HexToHash("0xf746a8074ec7938b033d98df3438ea4ef817d288ab1b8997704f252e64bedecd"): true, + common.HexToHash("0xeae2522bfc0dedb30942e2ce02dd8a7aaf730f4f9c83257a538deb5b60905db1"): true, + common.HexToHash("0xf7a1b48e6b81622062c394e4eec0404c84449e6ea7099947e9949e80173f44d4"): true, + common.HexToHash("0xd404d82906356fdfc1ba261a428b7036eb9dd4a0e87b11dbe579645743c5fb4b"): true, + common.HexToHash("0xa2287f1acc61c742d27c7fbe2da77a28127391c202bb4a298b9a32c0e3ec08f2"): true, + common.HexToHash("0xbc529d2f57ae41cc61cb538c6726b74492c6262610f41f788bf0e56369efe875"): true, + common.HexToHash("0x1417f0840df6c9c8bb7d8981a56ea349613a0bf1b475c55b4dece69e9bf99a77"): true, + common.HexToHash("0x2582fe1610ddca5856ccf6f11eca11342beafafb3fea6d5c051d38a577413bc3"): true, + common.HexToHash("0x90e66a0b0538084d69cf9e3a2142a92f155449672f3b27a2ffd1bf98c17292fa"): true, + common.HexToHash("0x2cc11f2dc1fb7a7940f2d7af237c81b34a689c3655a483ac8a796009cfb7ee88"): true, + common.HexToHash("0xd68d406b26ca5f649b9f6157bdb5d6004c76ec7929f9372a83e08091a8fa6f98"): true, + common.HexToHash("0x524ddbb6c0c21723bb38afe37aedc5ef57227b85becbcc88ebd7017a747883fe"): true, + common.HexToHash("0x736ac59abad6b81a453e28a46f9b3741983895fbea09fc88ab59920d71ee295a"): true, + common.HexToHash("0x318a7474da5879823bda79d75d6e1b985ffdd438b6de47b387b3643268dcd58a"): true, + common.HexToHash("0x566c58449e6c2943206fc649d62d917d2c3ebdacae2861e31f0aaabc0e0cd99b"): true, + common.HexToHash("0x893dbbe60364705e9d510acbf2e6742f53e4e6c45661b9bb1a7c6a2f35a01d30"): true, + common.HexToHash("0xf39255913f3008eb769115ea35ee2df28fd2110491943e0e1810cb9c8634f221"): true, + common.HexToHash("0xf565a1fe10ffbc5afac51c2c17c201b0a70dd777653a042c70336e3fe9577f89"): true, + common.HexToHash("0x56b92c8b788266505f07b4dd927afaa2c6ebd5f36584c10e809fcfd6e354b31b"): true, + common.HexToHash("0x00617b3f9417c8c26ac011a8d27599d5af16293457540f390d418e8cb3ed5f40"): true, + common.HexToHash("0xa70eb3b104d813a2a53abaaa386ab2d9e977dc49d939f4cb00c14cc87e5a983c"): true, + common.HexToHash("0x66932f3b7092ef958f4f1a50f87d456444cec1c8f6c060f4b4cb033146e8dba9"): true, + common.HexToHash("0x5e85ae3a4f3d4700c163f4abe2e1294ba350915d2a3379039ea5842e370279c1"): true, + common.HexToHash("0x494203b63ec21f4d5df9a111ff158baf4ca91d57bbea12eebdb7e898b125da82"): true, + common.HexToHash("0x3f77ce15feacbdd3d00ce2bcc1929fb4d3302ee0f14392a78d6a6d72babf8831"): true, + common.HexToHash("0x745709379ef80a7ccba5850b48196e3f9b94b415b890a3854812653629eb413c"): true, + common.HexToHash("0x350835896d625732d6ba3c8ff83582527bbe5c6997ba1a4e9d87793f086908f4"): true, + common.HexToHash("0x6c499af6abd643bd4b56d2f18c82b44344b58d22b91861d20db750676a5c54eb"): true, + common.HexToHash("0x8a1ee019bc4db355190acdcd1269cd8b27748f181b6f1b891ca8e3a6b51bb7a0"): true, + common.HexToHash("0x79cb42a45d4ed174fdbb0b9cf105be1cf322619e751c1b01d393a8627abaf519"): true, + common.HexToHash("0x378a486e415627c8d05d8e2ac2dc32b654c73aa6f331040118e47e3d418c66a8"): true, + common.HexToHash("0xebc0365c4a85aac5e794a9f5ae32a5fe96dfe9a6dfe3fe581859accaaa865c3d"): true, + common.HexToHash("0x90eb1377e0a0e6cbec092df9d3e5c8cf4fe1b55cf0106d0890b65e4e484de147"): true, + common.HexToHash("0x6361b9c313d0e3ce87efe8b6763dc84453278bf091741e88f3ada2637c9cb754"): true, + common.HexToHash("0x190014c0e0381a49c011da7535cd2bd4845e333a3c41ae34a4ab8d7e1a9e9be8"): true, + common.HexToHash("0x8016af4bbde2693e5b30d27ff32dce59dc3bcf1b977b8249310eba83c3cfeb44"): true, + common.HexToHash("0x9a6e42878f9e805194fd2f4c997e9a360e1bc389182ba4f75aa8422c24fcf8a2"): true, + common.HexToHash("0x87c2b839ee8e5263dc8cf1bc074fcc4d822d170f1aa36d6e1bbab2a521e0466a"): true, + common.HexToHash("0x1e2a88affb213e1cd58356c87d2a8f09d4834f3b8f9b9aeca8288f94aebb8517"): true, + common.HexToHash("0x60c651d228a646086602f51c8e538b41e46841114e10f3e23d1f985f8c671542"): true, + common.HexToHash("0x038298187e6c22231901b54393cbcae7fab840ef1e896b0b2196dbedb259a9bc"): true, + common.HexToHash("0x6a5247c4d12065a9a3631b952d2d028f8991122e9453ed098142ce44e0254029"): true, + common.HexToHash("0x2dbea1bb0f52d64ce71624762bd7c1481057394d2ccda800f0df84bc7f359cd4"): true, + common.HexToHash("0x68db2d9294a3e1827888c646786ff046ba8b17fe2c6ff968c6a3188ddfcd1772"): true, + common.HexToHash("0xa1009195f5dd3541d89bdf399bc8dcea16fb267ea0cef3c1e20ba58c5209a636"): true, + common.HexToHash("0xbded9e89de51ac7885ac0c0075f0898d9c0925a6ff3a26477d050ebcd89117bc"): true, + common.HexToHash("0xad8e3f3d027c3b77d8382380e349e73a110a08cf1b8935f1044f55b86e80a1fd"): true, + common.HexToHash("0x812feff4c30238d662ed13410cc7ed85acddeecdefac168809234c52fcd8beb9"): true, + common.HexToHash("0xceee99ee42f533e1e11fbbb9d8dc0662deeb8de35288f9c92893f86d59456b2c"): true, + common.HexToHash("0xb439f142f6e9eccd15a083e68589248e58b97d844d24241f5226cef0d73539a4"): true, + common.HexToHash("0xfa9150a99ce1e81e2862209fe3e1e3ec017840d02a493f6291473f13b486e5b5"): true, + common.HexToHash("0x4662f37eb06885be7e5539ca25e7f10e51fd4b895f80536d69330557aa54d6e6"): true, + common.HexToHash("0x302e4a2ad2595f3894b7f0b7ae84723d7a3b46c36592ee8111e334562ff45243"): true, + common.HexToHash("0xda49ffa166be0215813310ab5419943e6ac59f672073ae6e3fd4651e580e6a0f"): true, + common.HexToHash("0x5c7ed8d04255e29d790fbc0c789198b6638467012e85794630ffec7ed0b1ce06"): true, + common.HexToHash("0xbc2a57ba2074c13b6b3e1c96cf555d7bfac21bb6c1edc3d18c3d9da71ca56a15"): true, + common.HexToHash("0x51e67c970d82f4e308b0134308a548024417a99e2f57dc35613981c3b76b0966"): true, + common.HexToHash("0xe11c0ac75a6c404fa77eb9cf8169e3d3f66d314c5127ae4b8f76c3f819fd3907"): true, + common.HexToHash("0xa1d8df10fdcc46ae7e698ac8c88083fb0aa682a92162b001ede9664eef4622ed"): true, + common.HexToHash("0xb97091f2ff9eada509bd40fd8fa09bb5fadf1ce3501ed052ba3d260426f347e6"): true, + common.HexToHash("0xa55e8a6209d8ac518c4d4c141a504e0c7e7f9ee54b30786d8a6fb706d17aea64"): true, + common.HexToHash("0x6fe6cff22678c593bf8d802732335768dd6a8cca2ce2c7e7c5e7fda5cd6f9772"): true, + common.HexToHash("0x6e91593a240b81861d3ef92e92db651cd79a84e63bbfef8c4dfd6411eaafd5ec"): true, + common.HexToHash("0x9606cfd6956b7c02e7572e5a6618e9c84772a956d51b2e7b16a8e3360f8a514d"): true, + common.HexToHash("0x5f0c1029490a71cf280e621228456650963fcba55e5e51458366bc8bb3ce38b1"): true, + common.HexToHash("0x1677973dd7eb890cec3af018e7f6e029bb8c437ef83166a56217cae048ce4901"): true, + common.HexToHash("0xfd180db3add7355e5861fd103e0c7cfb2af45833ac6d307633b886136eb7f3de"): true, + common.HexToHash("0xa7c920c73249df89e9931dc5160339259cea5032dfbbb12d87b39a544c97a151"): true, + common.HexToHash("0x3926986ff4efd6ab9aef8ee8e0157d2b271561b57c95e16f0926bd5a117c9e73"): true, + common.HexToHash("0x71dda1a573ea743a8bef8456b27b25132bf74e09e67442f57d12a5bc759e5fa4"): true, + common.HexToHash("0x1b34a4c3b08a141ab40eb9841c6223dd8a3feb8405fd33fbb146018b02b0f5fa"): true, + common.HexToHash("0x33f1b59d9edddbd24dd9fe39ebea7df68d7d6f722d32827bef5fcac4fe84acca"): true, + common.HexToHash("0x0583b939fe81e5ea3041ebe0bc78d628b020ddc3ca06be24d59e3ce1fb06aeb8"): true, + common.HexToHash("0x918b916415cb257914bc8aca7b8aaa27625bb6035467f051825b83ad6e3ea049"): true, + common.HexToHash("0x45c339376fc2a02d95fd755bdb112fc07fd4817bdeeafc95520501809c092996"): true, + common.HexToHash("0x1382338adeee56a7be98479c3b5d8d81af8b23f2462f564c56c5dbc9df4acaf0"): true, + common.HexToHash("0xab0f3cb375fe0a337aba6ae925a2e4dd8d1ba71451979cda9fb97ffeba92fe44"): true, + common.HexToHash("0xed00bcf13c78912c1c32ba18b22aff526f24af8da0aad44e9a44ce4d28b6f53d"): true, + common.HexToHash("0xfe6e606765b6d22f54c7200fa458a7d20943e3b6b7c426a5bc210463a2ecf5cb"): true, + common.HexToHash("0xb6c99afb3cc25756877e27ee4b4b79d1d798a36ec25b5e642151050e26581611"): true, + common.HexToHash("0xe559776a2ef71acc2e9fe2c0ea12273f3a89527e702d5f57351df61c5de194b1"): true, + common.HexToHash("0xe48d80e2c28733b35b65cf16054dfbbb78c34174f02742f1447bea823dc6f31c"): true, + common.HexToHash("0xdc73bac538c8a2b2bc4f06768abb683ea19c74df1a39e8dd750d53d490c5b440"): true, + common.HexToHash("0xf81eaee541a19dd5aba88d9a0d8d76a8f0e9ee0afe09a350f28bc53c2f7163b3"): true, + common.HexToHash("0x6c902ad6e0603e67ba83f459011852ec5e45bb37d048729a43ce72c2e70f1d49"): true, + common.HexToHash("0xfb95885bcffc3798abcdbb235d34b157058f50c792a4ae6dfbfc396ca2458320"): true, + common.HexToHash("0x3645eedb686fa13d73dbdd3e953dc4126e8d4ee151d7f8ca30c5c89a3f9a9187"): true, + common.HexToHash("0x5a3e6e62c21dfa39e6ee7b472390bad505d6bce46833e4ad698e41cadcc83c74"): true, + common.HexToHash("0x3c55ed19c731833199db3b5eeda55429fb632af8713bd74230d5a6b0ee4f3596"): true, + common.HexToHash("0x9d24c8ec367481ed11009d1d58131229203d33941699595a551e681e0d1bc2eb"): true, + common.HexToHash("0xcd4a79a151c3daa9f4ae5fd68824bd6f8dad130b6f23bc1afe71e92d133de9f7"): true, + common.HexToHash("0x34287870b16da1bc8b27bd451499b7a682c8ea359ea93dc666007e3baae7c2d2"): true, + common.HexToHash("0x0c27800f5b86b04061b6e7946b2540d90df2f97b03af7ab631341b73c5d286b0"): true, + common.HexToHash("0x7ce2c550735a8919749d22973da38ef776b490bc4783ea7ecc3230632ff72f64"): true, + common.HexToHash("0x86f7088c58074c0bb9aab9637c01f67c231b34df474a461eb66039bfe86872e3"): true, + common.HexToHash("0x5cb664433f2d843414a1c4d8fda976a8fcffc534ab40ce7f9bbff1810944391d"): true, + common.HexToHash("0xefc7dbf44ce9799c88f49b1c8b3c35796a15c995db0e8b6ca05dda0975d446a1"): true, + common.HexToHash("0xa6abc43c4e785a5a4e8a5dbb49a8365303b218ad5be3b72ec0075c1d20d33960"): true, + common.HexToHash("0x8a1667b939ae713a72ef0c730b3781c8b22480e0334cd8563cff23e05c55274f"): true, + common.HexToHash("0xef6da354a8ff6a524344be928bb31d58d464b8755d4815ff457f1c3465bd7c8b"): true, + common.HexToHash("0x8c21128965aac98d3db5a84cafbccf2c1f714063e4f69e91bca5ffcc09f33250"): true, + common.HexToHash("0x96a189b7ef67112f05b9e513f088f09985ef149c86b81848ebfa665f59813854"): true, + common.HexToHash("0x20713b348f5bbf5c770424ae6717c9a774b3441954c22e3ec45b05ad57feb412"): true, + common.HexToHash("0x689a6172c3571800742a4953406fac4c5fe62dfb6ac656b3ab739f55cc18508d"): true, + common.HexToHash("0x59bb349dfc131f44559ed41a0b0f876395efb2d9755e4c85f6bc6d6d1cda2751"): true, + common.HexToHash("0xc04aa9cc33f86c8fa035014b61eeb4f33e7b67098dafed06aebad08aa917dde0"): true, + common.HexToHash("0xe609ce08944fe5c238e438a488f2dfb3a63915e9cd4af84825119f95c71915f8"): true, + common.HexToHash("0x916fe55035005fa2d1629ff26bd4ecbec16257585ff5c4dc1510716bfcc03200"): true, + common.HexToHash("0x4bc1e0b4dfae80dbe797616b3ab3404c1e7906c7bf5fbe821c7f6302b5736e39"): true, + common.HexToHash("0x01a4dcc5bf28f5c666a126393ae150d1b67f76965d1e42402f8b387699d01745"): true, + common.HexToHash("0x340a6312989da5e3ec2c9057c285efd762b6ff76dcbbda237f57f023244af03a"): true, + common.HexToHash("0xdc09935d5208383f5b3ba311fec31670cf21d582e8c69866156f64189492a10f"): true, + common.HexToHash("0xad4294d6e5aae992a8cf543bb0b600190bd4d30d50cb2b7618c53be82a997bed"): true, + common.HexToHash("0x2bb21893becacd4d1f9fa092d450946dbb6d0c37ea58331c79596378fbcf1585"): true, + common.HexToHash("0xf469ec963d8adfe41b7443dade93ca937e8f84e08074bff71d7dfcfcf7e69660"): true, + common.HexToHash("0x81b3485998f72c8239244006a654648d6b67e7b083c3e4d55599eea015e94c1e"): true, + common.HexToHash("0x178b3f87bb5bf19e59ca445c2a456b440cc51adb5cbae3724fc91c34da9c8412"): true, + common.HexToHash("0x6c45eca2443a660ff6855446703e6cae45308cc6696d5c0ee519a8865e1a60d5"): true, + common.HexToHash("0x3a3034cca0aef062199ac7ab4e429a43b73b45e5c02d9cc5dc9241279a10958a"): true, + common.HexToHash("0xeff293812a6e60700016f31222780b9ae08f6ef16c339c3d8c302e19cba7eb61"): true, + common.HexToHash("0x37edd720ef5fce879116e83ee4ca84118381bd6d5a15102ea6aab251b4090b98"): true, + common.HexToHash("0x4e19aec2a14264dd95e06cca7d584226141758b271c8518c66e953b59b2aa289"): true, + common.HexToHash("0x976c8dd4a22b862104e07ce91520a1a00c8beed368997f7920bf698ede1a0ec1"): true, + common.HexToHash("0xd114bc37c66fe6b52edb1e81171d9a709f23489051d287fcf808c8ca87a7d670"): true, + common.HexToHash("0x1898dde719bc349a22e6d0f2aa5d7872bc0156b1e221280ca00c96efbc6ce1c0"): true, + common.HexToHash("0xb60127d6e17bb3ee87fae88f88c213204281de4e00e88fc5d54d5e83d7756f99"): true, + common.HexToHash("0x34e7f9dcf9d97ba73f9b4d384e7bb3bcacf6255c7b7c1185e1ece0e109f29ed0"): true, + common.HexToHash("0xba4c4dd76af3a1db6d691eeb345c8eaf5a005e9263fda52a87fe16c6df0056cd"): true, + common.HexToHash("0x3d2a8dc3f0627b3f8eadc476cb483a0111042443bb18aff9278cc3b9f641f933"): true, + common.HexToHash("0xe4eda5bdc852ec734b0eda8b851438beb51af85d70be776db616caaf5c5a661d"): true, + common.HexToHash("0xe1c6b9286328e7ad464e07a87579f6638e3722184e8ca9d79632b59e629ed33b"): true, + common.HexToHash("0xfacef02fb6a1d10c6ca6bb65e32d16f527efaa010f61d29cd1b4bfc26d59ebc1"): true, + common.HexToHash("0xe52f3b0212c03354833df77ee962c37d19b17eb96414cec3c131bec84a8fcfb2"): true, + common.HexToHash("0x6648952c89bdd4914f08006afaf78f155da87a19b0d01794b68c08749cbcc950"): true, + common.HexToHash("0x69976887e5c9046e2b49955c5a9722397df33b8934ea76ab055122342460263e"): true, + common.HexToHash("0x63926c19300dd4049d2262f56ba4b73d7835caeeb4e20b19c4abbb439d3d4945"): true, + common.HexToHash("0xf45682b60a04942f31ca493159ba5e0f69717d3b4ef3538d3a8688fbfbbc044a"): true, + common.HexToHash("0x60a0677eae19c24d5c621836c3ff85f18f342dde1ba4e790d2e4648c1706183f"): true, + common.HexToHash("0xda21119599611d86f13552371c6914faa992c4c26e9c05a2593a59d6d4db3d93"): true, + common.HexToHash("0x78cc2893cb2b7951e38fe3fe24b9a76394bec58c9b74442962111d16bcbfa4c8"): true, + common.HexToHash("0xbc00bb87dc5258312513be35202050cdfcd33b911b40b4596679b216f6452bcb"): true, + common.HexToHash("0x56dfc929488171d58f7d57fa85e972e5e0e89dcb824d090fe12634529bbe963d"): true, + common.HexToHash("0xdb0a522d7f2a4a727a5a141303cd2c5ec25a3fc1287da2e8800e16f887404dc3"): true, + common.HexToHash("0xe1108838a6c8c50bfa3c227e2b11a24d40b32b2374beb01394b2cd8e27292500"): true, + common.HexToHash("0xa18380207dcf4123f4bd17d073a3cf154fc492d78d9f7ce3a46f41f02c436e06"): true, + common.HexToHash("0x0a103daa199c3b0f29647e015c8cb6f74d51319454f0243d94c1f1eb67755e56"): true, + common.HexToHash("0xf0434397323833fc0122a33e2e0902977ba7099ab271aca412614f25da850ebc"): true, + common.HexToHash("0x0c1e78273d175bac325badefff94c6b1f4f42c575490657ac1bb2ae13e609561"): true, + common.HexToHash("0x62e21296cc98c5645fe54b4341b7de183a63bd127115099ab0cc0a2486e2cb05"): true, + common.HexToHash("0xaf4f190f525f1d7098cfa3c77b12794f75d4493eae4a53dc446c235be6801cb8"): true, + common.HexToHash("0x416713c23712a833bea96a1e318a1d6290d067139ef27f89b661a3916aeafe7b"): true, + common.HexToHash("0xc0f88f31ad105448b8e81796ca5391d351f4819f7b08eee6e7557f08ec68d51c"): true, + common.HexToHash("0xc0f95b5787894814b9fce0eec952ae92eb12ea1aecc1652b8cbaa65358a19820"): true, + common.HexToHash("0x5a01eef4acf087cd9e950ddaffe42e4c402dce2f33207646a11e4e49233d7d27"): true, + common.HexToHash("0x75c8874af3d218ce162ff7dedbfc5444e5f8f19e4b1dd8096f19c28817294d12"): true, + common.HexToHash("0xfaf4a06b1e9c36b9e1fb87f3e03d09a28a32da74666b165c672081f6ca106407"): true, + common.HexToHash("0x7a0fcbaa2b11df7d0cbe042e5c63dce6fa081315e110cdfe465879075bc762fa"): true, + common.HexToHash("0x78f99e389d3214cfce262355ae43c0a969af62c91632cc80b516293e81ff68dc"): true, + common.HexToHash("0x2417b10fe5bccbecd7c9e238fe3d26c558058adbb74c0c465e754173cccbcc10"): true, + common.HexToHash("0xccc40181e9e47bf6ba11da910f32903646ab28f89e060e89b6c2eefb891a23e8"): true, + common.HexToHash("0xc8d6756442cac1d5d9627904e495ffc7f60e67cbe0a081d2625077d35f8b6e10"): true, + common.HexToHash("0xd13fa533df8015562f5b426cd8b2712bb262cde0318c1b10f38f1d2478db5963"): true, + common.HexToHash("0x9a5be9e16cba849df5922e6ba385ed15fdf6870e628eb281786a6a46193dc5a2"): true, + common.HexToHash("0xa526322cfb263847cd76569cdc4eac7927f6224fa0bccee485e3fad12507f898"): true, + common.HexToHash("0x92d946f6bbaf0e144d4080221e9165e04ac11247a679de2c0299f132538b6d9a"): true, + common.HexToHash("0x3245321ef3544b68e8a633038561b03bedd5afb0fa1667f7815875bbad3d5a2e"): true, + common.HexToHash("0xdb7e83010d41b7d2bbba2592d9af355a2ca1d04b7173249c27e0f52b6f924bca"): true, + common.HexToHash("0x53b790b16bf652d8118c1b2a0b22ba462151729502a12093c821655d67bc28bb"): true, + common.HexToHash("0x29833dfde11a5361b4a07795842a5a92262302c3d30b3f336ac92d755e3b9e7c"): true, + common.HexToHash("0x231780d450f5237b5af96e6ac430c32895b7207a6df7ad8ca49a9fd2e88fa5e0"): true, + common.HexToHash("0x53c1259e791082c2a1af57489adeaeb9b16c0ae1b642d14aae5a6bf68cbaf56b"): true, + common.HexToHash("0xac783400241b0f815bd01769b973504c6ba34bc123ada2ed9e84ebb1f8a0014d"): true, + common.HexToHash("0x08d7f54430e734a7033f3e96d4e2ba93420275f3f0cc0bf953b8a8e9c07eaaa8"): true, + common.HexToHash("0xb43506668e7fd5282ed1a4436ff606504efa7d52939bfca6ff8188fe61fc88d9"): true, + common.HexToHash("0xa691e9c3f9a9d9a55b2052c37b35c4209d9b3a48b6150e59a67763c5fdeeabf7"): true, + common.HexToHash("0xf3cdf9e6ed32d3302098d6049fa5d2648ad30dc734b237ed977c17afbda281ef"): true, + common.HexToHash("0xa837757cebf358fbbaee000a7bf90debe2db9e567d14bd5b208a35ec81b514be"): true, + common.HexToHash("0x34cd6d92af76eac28a11c785e01dc6e587838c2780e8b54aa6920f9654d6aa09"): true, + common.HexToHash("0x47ea684aad1e98d6f82efd2897cdbc0870652acd57ab8b6d6a53443d73aa511a"): true, + common.HexToHash("0xb4361099182a57633294c67879dc14140fc12291027de721f17ee49f1ac41061"): true, + common.HexToHash("0x140467e092d85e0c77e9079dc80f2590f7969ad7fb59faa88dad32a26d659b02"): true, + common.HexToHash("0x5a944b5164d0b5f5b25a410a83674c0ad0ebf6ea3051eec43afa5594a4967711"): true, + common.HexToHash("0x7c7497651d1e6ee2aa350dbd090a377a726ff9632e98cadf1f9ca0e284a647a5"): true, + common.HexToHash("0xb345f3716dc2edc14dadaba74604694da44d0c42cb2a701191147185a9a982f4"): true, + common.HexToHash("0x2a93234b8c0bfad049b95d52dc121a1b32e659056c1d2b2f2f53c30533312661"): true, + common.HexToHash("0x8345f4ff8b9a77182b2ec8b440ee38175670ee51fdbadae40fba0d091afe33f9"): true, + common.HexToHash("0xb6f9c42c87228ef31880c3968aa3b4b899db3eaa76f16777f7d6e6eca9cf2fdf"): true, + common.HexToHash("0xf35619a1f0172f7c6e9f7e055becd2e63647ae9521d4fb751bfd8528d86b0641"): true, + common.HexToHash("0xaa2f890657229f590888f5a1b9a866e02ebb194ae6155c4a907e6ac1a1c4f93a"): true, + common.HexToHash("0x75445fe130488cbc929efbdc8b52c5301adf493e57af716331eb216a97f17742"): true, + common.HexToHash("0xe71088a96a1eb665481d95a0a5a697432dba07358022641324d8da623cd30547"): true, + common.HexToHash("0x15741357107ebca7e3ee157d53addbd2d08765eff3b1c2fc7dccd324bf8e1b1a"): true, + common.HexToHash("0xab08c68f6b490bb328940a797aa6fa3aabdcee6889b5e17942f0481202249858"): true, + common.HexToHash("0x5f37901f00bfa25fde4d1ab02df6f816f642bfa4ef258aea80643c2694de6108"): true, + common.HexToHash("0x566cea3c9255586c57c937da90438f970aebc9a17652ed710e7b3bc3835f1d67"): true, + common.HexToHash("0x5f6029e97fb95fe48f866948b719048c15bd6992cb6f0a8a2a3f0026312b3e2c"): true, + common.HexToHash("0x27ea8853242707ee1f815ec90b3990c0a87ca0fdc041b994deaeec702ab6503b"): true, + common.HexToHash("0x4bc212280c7bc1e18c1cf4bb6a26b36f3541a91f8977217fc4be72d96ce836e2"): true, + common.HexToHash("0x000f83a3c9e2e679274b6b91f2bcec62c5dc208d8cec7260bc75d790e8b64905"): true, + common.HexToHash("0xadfb984e8494638c4abb541be4938640b42c95e6090ed328f18111e0d09c69ba"): true, + common.HexToHash("0xa1805053f25a451e930ded984091e6eca9231483c50654655efa45774159d1a2"): true, + common.HexToHash("0x30e23857f2e73f13f82de901266fe81bb5ee9738cb19828ffd41e6fa38f87d95"): true, + common.HexToHash("0x9c97b45d1fc62a00defa99c877e2bc2ebd10b4e57bff27f1331082d6b98de664"): true, + common.HexToHash("0xeb0b1687cb19388e0d3e79fd26c575b64734c519e166cf5c6811ee1599d79146"): true, + common.HexToHash("0xdfb8bd06a1950f132a992737c57c3e3c9b8419a084a275110962923253d404cb"): true, + common.HexToHash("0x04cdc3d66a76dc334acdcc128cee163ce003d4d5336b7f74b63f24d70fe8adfe"): true, + common.HexToHash("0xd57404dca873209bbf38097b0178f3d69f2b2c18268533cce88d472ed2a3beb0"): true, + common.HexToHash("0x2438ffab8c5b527af3bd8cca0da6e0bcb3b3add30680d03b35b98c9b61b062de"): true, + common.HexToHash("0xf3cd1678c116955ccc0ec4667193bf56fec226938a7bbe71d9a52ba779b5e62c"): true, + common.HexToHash("0xa98af8b4df1423c790659a0500ab548c7d494de5cc8116b8e6ee0a45fb8bcf0f"): true, + common.HexToHash("0x434e89f8e77cc59e6f192630c1f0a2aa8f201de46cc60d1ae2bbd1f0fab639d6"): true, + common.HexToHash("0xa1bfeb4326737d7fca5e2f218a9c4facf957479652fcb0bb22d7983acaf666c8"): true, + common.HexToHash("0x13a2ea93c901dbe598bcbeb33db42eedbdce65b9f5313555fe271416aa7e501e"): true, + common.HexToHash("0x2932405aa0fd2fe0a657de2fbe889f836c7996507d43192d34757adcdb7d0920"): true, + common.HexToHash("0x25f8a5f9bcaddc09c10025cba719243c3ddfc732577c1e682695c77c865b9bf1"): true, + common.HexToHash("0xbbec8222e0f8b17c5569bd192329b987f21c04ce0b2d755ecedc8dba5158c620"): true, + common.HexToHash("0x6d822cf3af3e7f918fc5713285cd114db0106164444a8f920436a8779dd88750"): true, + common.HexToHash("0xc030cb32ea01fe3eb6e8f516854e356035789cdcf804b9e18192728f76a81210"): true, + common.HexToHash("0x5cfeb78e073a7b3a8b01daeb86e7fea264a28891738cc4ed3c33c8058e2e60a4"): true, + common.HexToHash("0x91f9d7d24708c98d6406bb7abe2e47495df6d56db366561c302b730a3507be7e"): true, + common.HexToHash("0x0db7eed85f9595e59dd6cf0752a1563e7297d745b19f1d8265cb0cf4f416e4f0"): true, + common.HexToHash("0x93d1cb3db82d9ff974848b016305de5101270204c98bf4b976c4f0acabd18502"): true, + common.HexToHash("0x01c13fce47792024149585f8007585eb91a0a94f44c730177309fc73a698e427"): true, + common.HexToHash("0x4a3cefb63bceb91af291f84e94e92f28e2e61a7c55269a7774361ff9fcf837bf"): true, + common.HexToHash("0xe71ab3e8dbd02079dccb8e5adc65e5336974b487691c4a6e58fd03ce554ee0f1"): true, + common.HexToHash("0x296a66c27b950da0f8024fb910be6d20ce5d8fd1ad9e3f3af870708e05783522"): true, + common.HexToHash("0x9916b8664fe5d3b38f80a49434ec8c65fedc4eb42c33b6a230fc8e298e651c65"): true, + common.HexToHash("0x7a340ab714da798f66d66cd53d4e85627cbcf3065f4d014d1e224d969e3c2f63"): true, + common.HexToHash("0x613f1832348e09e4155dc5ee3e84e77643877e02275915883f14ba129bbb2b91"): true, + common.HexToHash("0x721477870e4e6ad9eadc0ef90928bad480370eb756caf83e151f504b29f772ee"): true, + common.HexToHash("0xc7a9a037f89779f705921960de15db30553782651fff558b6a2872a8ecc5f6a1"): true, + common.HexToHash("0xd7345c1818be156126e8570e5634b1019c66b9a86f4264ff2050d3cb1f664b53"): true, + common.HexToHash("0x6d224087457c7887379d43e680bd7befd7ccab57c44085de010a58286d9e8cc9"): true, + common.HexToHash("0x3d777e085411ebea84c716277ad3f1fdcb0afb63f84ca7023a5845ada4598336"): true, + common.HexToHash("0x10161a9e7f966fb966dc001f3680c2786c4b281fc3596485081436b4830db7ad"): true, + common.HexToHash("0x584d9a672ec4a0709979ff6dd932179b458943dc81a4419251c5fd4a2bdcf051"): true, + common.HexToHash("0x52beb58338ce5131645f713c30c157f29196e91b039d373fbcce9dbd54120395"): true, + common.HexToHash("0x1e8909f2a2f5d9b6dc3bd9e97a836b7d705353cf49732d4998a472a1fa65fd8b"): true, + common.HexToHash("0x3e7a9fe50978b89a8dfdd075e83bfecee82d95cb8df625a9880441a12616a9ef"): true, + common.HexToHash("0xbc8ab6fcb1657a96ece83722fad4e5bf20ebc2648d3938a7492d94c4f47eb257"): true, + common.HexToHash("0xa5a7a87153b1d7af3cb6ea6063d4c2d8d9c3992d02927bf2749e6db02a81e6fe"): true, + common.HexToHash("0x76017c75abcf0543a3e905a0cb7d6c2e6c91d108edbf9446115eea98a40b03e8"): true, + common.HexToHash("0x5978b634c8d7d4f232689d55547b2a0aa7a91f2de61082ad6d0fa1755a84a330"): true, + common.HexToHash("0xf1683f936bed7fa16cb54aa54d1daa34fced9092a06c9bddc596b7ca51b979f8"): true, + common.HexToHash("0x89b23575b6689abee67033ab59a50a2796b9bfe2d07061e0a9f7e25b319c2655"): true, + common.HexToHash("0x791d096c3523307629b2495cfffed0798bd0c395747f311c0141c0534751e443"): true, + common.HexToHash("0x0f174f906ec9834bef32a9816a4ee4e44f5b7a92c30b9e33a4564770a9dede45"): true, + common.HexToHash("0xe5c54b870ef05ebba7079e62e6a287c6a073dc813b2ceb452b6b6eb31e9262bc"): true, + common.HexToHash("0x6873e5fc934149a813778c0fdcb5767e27e696e2f309c080079329fafed555b3"): true, + common.HexToHash("0x8d8f32533ce85b1e9afe10e19ae23abd5dddcf7c17ae1f4ed0bccf0d678539d3"): true, + common.HexToHash("0xd27c4e5a62402100728ccaa09c1f9f8904687993d0b4763de0969c4b8881be72"): true, + common.HexToHash("0xf36db3edba06715b2bb7eee7991cf3589ff352150df46531429f37cf460e1686"): true, + common.HexToHash("0x21f15f5a572d196bbee6b159403089ff1a4bfbd3a3c57b0f81105d939460ee0c"): true, + common.HexToHash("0xdfaa5a038deac2a08fa38deb1fb9b9b5b3b8a162521efae0a5bd31243263b9ac"): true, + common.HexToHash("0x94a5f13a97e78fb7a713d019bfab4b9c69f21326ccd2aa45f46563f242b896a8"): true, + common.HexToHash("0x7df91b39332d9c241b3af4a995edfae6d90f0b077b9f07749b80250f2a499079"): true, + common.HexToHash("0xfe63a0002755ea4c699d704c09898f0a01fc3e357c808844a5b353363783dd66"): true, + common.HexToHash("0xb7be53e0cdeea33c196df9e4689700da9581eff0bfdece4c41fe1830893abeb0"): true, + common.HexToHash("0x2bd50c07a0be9cdb75402822cd3ed9308189ff402d0e1c032cacf1df829fe9f6"): true, + common.HexToHash("0xe8e6d410ac8840485ecdba1d41133cfb4af47542abc0b31906ca0c4ccbdb11f3"): true, + common.HexToHash("0x63318b0823c6e1290bdd18fe9773a4d8b28556f86a2db92101e1bb87374a70de"): true, + common.HexToHash("0xba488f79efde94e0f6d0533d8a29b9c0addf99c0d394f2ba329fc517eed2a64b"): true, + common.HexToHash("0x2d575c93f3c548136441bbee805b4f1dddc4b5aa534465c83fa55528f71bae82"): true, + common.HexToHash("0x4ff20ffde6b1a91bb8ef3bac4e0a2fddb26c9d5ff9fa30bf6f022baff15fc27b"): true, + common.HexToHash("0xc5fdc7af8395b4c5831c46add9cccb88a4906f5c4816a9dcff09b7a81c432502"): true, + common.HexToHash("0xa46b66836ba7daaae8006fc06484b6d8eafe39a739f42886e37e7a54f3f40898"): true, + common.HexToHash("0x114259116f79cabcab932a722688ab33f64f0baf826aa09e1211effc71c4e297"): true, + common.HexToHash("0x5519cde20c47366ae62a5feb381f2467437f8c5f8e24f672dfdec5ff53448c4f"): true, + common.HexToHash("0xb0b0718da00b801413e4bc168cec45d42874e34cc89e3e10c23b6e8008c49628"): true, + common.HexToHash("0x52e14fd4fd75deb0fbabf4e74a9b9a423ab6d24ddadd495c9edb14f8f7406e9e"): true, + common.HexToHash("0xd11ad9d7bc1249f65a5acea6d299381f44a29ad302a096ca6db42a984f611490"): true, + common.HexToHash("0x4702ca0c8bd180ae75216e016d67022c540a52d291dd99e22fcae1be9a74ee10"): true, + common.HexToHash("0xb91ab30cdd49ddf1a62c83458fe20ae66e9e6f2f6adb0149866da966ae09bd4d"): true, + common.HexToHash("0x90e27c148ae3cf3538e4a4550050ae6a3c63e7ed0123d8096e2922bb78b60011"): true, + common.HexToHash("0x35c8b0a3cc00ccdccc5d4693d443432f14b3dfb1a732a6a0ba0c0f0b8c65929b"): true, + common.HexToHash("0x1674d263f8932215e0959bc2fd034d3d1c8002004e88356b1401416608e71577"): true, + common.HexToHash("0xaaf473f7f05f090239a344afae211fc7b0e62930b83aa8a61036f3dca488315e"): true, + common.HexToHash("0xd6c9b115a9f888632d551e566b435f5164ee87ed3cc969de3dc98fc6ddc3d6bf"): true, + common.HexToHash("0x5d1a31220159e8ef91711612037825ffe5489f544d46ec1e05fec11712a14525"): true, + common.HexToHash("0x56c0ad208047ecedf5edec7477acd9ae255014aeda4d7f08b263b90e5b5ee5eb"): true, + common.HexToHash("0x2514c7dd44ca649d8fe41831364fa5d591bb2946f8fbc7186de2ff07a24abc3b"): true, + common.HexToHash("0x34c8b0f6e9fcd3b63a980e4b4601a6f4a59a9f93111f8d19b500ccd1f0ce93ed"): true, + common.HexToHash("0xc3bb6183eecd02b4b6e369f9961b2fb7820bbb62bcd4b6ed4de71036d4b38257"): true, + common.HexToHash("0x837ddc48b0e78462fc527eae891c8b503f21c274ed89236ff13382f03aa241ee"): true, +} + +var L1RelayedMessages = map[common.Hash]bool{ + common.HexToHash("0xde6a3c949709d252d23d940fefc976373acb2de4ed2de64bf1f8430ec2cc222a"): true, + common.HexToHash("0xe6c4417da24449cbd3b65bb145834307a3293271843546e5e8d457b0ad13f025"): true, + common.HexToHash("0x9aef302327aade2fc4442c927d54f424453c072fd327cc0ba95968d42c94f7f6"): true, + common.HexToHash("0x1e48b76301e322f342476be21fe84ac3b339ad16a061299c8ad193dd06cf64d0"): true, + common.HexToHash("0x50fb4703ba2a7f8f788dd057f4508b98659f1cc17ffb397b73c03d783cae80f6"): true, + common.HexToHash("0x01d5f14626d5f1b986f5ce7efc99d402e476ef7227b47af55a44021a455022ce"): true, + common.HexToHash("0xc349c7ed9e1a0283e04315c44713fb6864d3f4db20ea21760e6ff1173623c785"): true, + common.HexToHash("0xfffb272f44276e9dca31d0a34cfdeecde1fd3daa497348e049fc43a6cdc6297b"): true, + common.HexToHash("0x526bb4dd97a7f64bdb34d6cdd1f7bcd5323d245f9fa7695f27864725f970bca8"): true, + common.HexToHash("0xcd0b7755757727fdd9a3bb00ed2f8d37d6cf4878e2b893c2da90a56d2837b038"): true, + common.HexToHash("0x122e4df2144762086814619c63d9b1ca3bbdc958148d11de8d1eb7b9bc158121"): true, + common.HexToHash("0xf00a9bd715b15cf854b593aa280b462cb12441bc587bc507dd9b5572f7eee819"): true, + common.HexToHash("0xfec902255769b1f37cd3650cc5bd79a2db47f9e57a87271294f14cc269d97979"): true, + common.HexToHash("0x7cbb6a4230c73511d7255ece623dce57fed2057f711ed4e669bcf10611854d96"): true, + common.HexToHash("0x8459345e61e3e17cd09984d6be6dc4d552d32fd4d2d0beeb5eee676053f99152"): true, + common.HexToHash("0xfea17bd65cd499f6a5415c57002bf5221ba0f8ecc1fb67c0adafacd5c639a0b7"): true, + common.HexToHash("0xcb3561a469edb8b95d938ee7e7bbe87992f014e97e83c7a9bfd2893a67bfe728"): true, + common.HexToHash("0x35d720218271c347ca9e63d104a72f5ea6ca1402cd2564bff06741e26f22678e"): true, + common.HexToHash("0x845c15bf1159a4ed95ace57bdf324c30a848fee83fcbeb8e685b0d905f4a0cd1"): true, + common.HexToHash("0xed459a6d21e45f3f01b4bf65dc8e459b9af8420e00acd65490e7ab508af83b58"): true, + common.HexToHash("0xcdf51eeea22373176380782891fc9ed707be6e63d6efa828a57d607934327c32"): true, + common.HexToHash("0x001f84fe533076e10e5df74ec76bb851e2e5e66ad96b06dc9d575a94c61dee7e"): true, + common.HexToHash("0x4b8b05278215519958f9eb2bd85fc97c8ec72781b0bc4fcd9867e55dd2414f5e"): true, + common.HexToHash("0x7123049b7c8ca2546ea900e20842d9b558b917004a2c29374c8b6214663357ab"): true, + common.HexToHash("0x96ad9876f213911f462c2de004e22bba1be6938b0ac43ba24e2a520efbd6ff9e"): true, + common.HexToHash("0x4b83a3528961906af57e6551976c155cc622724fafac13a61accee750d37a1ac"): true, + common.HexToHash("0x6b0dfcea0f4cf28f6df10aafc8a4db3b1e86c8ffe586ea878b6fe375d4a0b666"): true, + common.HexToHash("0xd16f181eee50f57cbe474de76cf8388a21b91e53d9ec8bf127f568b267804d18"): true, + common.HexToHash("0x10fced87b3973c4555a9f5de852e20e8a96d0bda66985ca8ead563b90b07e6d9"): true, + common.HexToHash("0x2b326792e5100b1f9083406b57eaafdc547100450a814a44a84882abab763e9c"): true, + common.HexToHash("0x9ee83e5b781c25e0baa7a1c1df9cf48acd876126740b57a99b5c6004369d4d07"): true, + common.HexToHash("0xde61b0a624303b1b2c1c804bbafee66072cf01e5c84c38b53c617be1d3a6c12b"): true, + common.HexToHash("0x36aaa8618e834e385e35417f0fcae97d8b25dfa95f6ed0d251f31b5e016f4aa7"): true, + common.HexToHash("0xa05d338a6115ccacaa95490a83231c3dc94186b188d8a119c4fb4ae27b928e34"): true, + common.HexToHash("0xb3a60115002be2b079d2fd99bb6f297811b2f88d4543ccd5d937ce408005f051"): true, + common.HexToHash("0xd8d4c2d5329fbbe0c9ff6f872431a6d7266ea189c7124614df3f8506ff6cdfbc"): true, + common.HexToHash("0xa5c8b136cbfda9f3bfdc7cc39c56d7ca61e8f9fff13d3828d67e9b32cf8473a9"): true, + common.HexToHash("0xb7c5e112a7a3667bcce43c2d14b3d74a52fb1166374359e868c0dfdf86e79a20"): true, + common.HexToHash("0x1e6048736e3ce4b95dd30087aaf39f54d6a4e5a6da9f27637de977a2c0cb20dd"): true, + common.HexToHash("0xe8d5b597cd766a7793bddeb98e41df262c1e0c318f1a974c355371974b2c37cd"): true, + common.HexToHash("0x9baea56db3c7d0d8634ccc44966db1362c1b06da11b2de3d12cd315d2141aeb8"): true, + common.HexToHash("0xa541fc47fd6a331347173245001c078658b94cb1bc440c0f6cfe5e2a34564683"): true, + common.HexToHash("0xfc7515dc0b5950ded466f786869b7902ed68212ec03359ecea22dd9a65eb7434"): true, + common.HexToHash("0xc55be4198a543b5b4e3912a25acbb34f180d52b34cac9881a38b4487ced8b332"): true, + common.HexToHash("0x914e8b5f88989a1c1017757d390143a5daf075f74388f60d9d511ed8a33e43b2"): true, + common.HexToHash("0xe418d2969aff06f45edea0c676a1d396413e33ff12cd215f0bede10d2749e1d3"): true, + common.HexToHash("0x9b9672091f9ab8e229031f9005095f62a27bad680f3db919f480903d3b884f33"): true, + common.HexToHash("0xa22b78a59da8c43050209c2a8118d43fb3394cd41688af20a03eb76a7ca00f4b"): true, + common.HexToHash("0xb0c1e114cb6b3185ed7da1b552313327436c9849a32140aa1482ba396eb24992"): true, + common.HexToHash("0xe1916294a2c3efa61aecdbbe580e4cc3ea7aafedae6dc13d2604304b7ae89fcd"): true, + common.HexToHash("0x86ddb1e5edc35769a301fa526341a126085a45b2777a57b0800c445c604ad15f"): true, + common.HexToHash("0xeed386aa4e8dc784c3e08e55b68f60f729515cf257b46fd00eba8aed3598da8c"): true, + common.HexToHash("0xa667dc1656bd4aad1de271a7b2c203a8e92f786c215fa6911adc007185e66a7c"): true, + common.HexToHash("0x81a26c96d4f5957d6a2618dc5fb578196f4424dc9171865d2bb6f90fdc4d2398"): true, + common.HexToHash("0x8c2af0c2094a4b2f69579161b932005c1c296aff4037a3d7a7fd4f3438739b09"): true, + common.HexToHash("0xddfa67731c8379ace27fd38f85209ba2bb727a351217e3c260c4ae2194f1e598"): true, + common.HexToHash("0x874bbca7608847563eb8ec8c6367ebf466a25392645009793697bd9314e5767b"): true, + common.HexToHash("0x686c65a8e352b0e0b62a46746ee037f12d6fccd457bb9691aaacb8745945981f"): true, + common.HexToHash("0x29d78f8a230f5b5c5762667256af5408556340ca5d86d0d710a64f5e6ae4a953"): true, + common.HexToHash("0x968b39c3115a0b54778180978d63d2189e6a2bb3a9ff3a065d3bcd7997e327bc"): true, + common.HexToHash("0x1fd7f9e95ace5db7b30b6153b7e9e4ef808f4ad5e70858ef4be4e79903b7feb2"): true, + common.HexToHash("0x497dff70f7eb3eb5d6b93e1b77eb5b02fb8478d0c109b65707551a451c811d14"): true, + common.HexToHash("0xaf2a0e4e20b2d520e91a10921e689f4b15eae8f6a8d74cb0d0c2b633b35d00e3"): true, + common.HexToHash("0x313d6b6b0f133344e43aca2ebedd71d9e6a7e7cd04b47b560d84b98a6fcde78f"): true, + common.HexToHash("0x2daa3175e45770eebcc685db392739bebc7452aef2fb2dce6db9a8e10434f3fd"): true, + common.HexToHash("0x2ecd1fb5a4dcc649b9e72b1ca216248b69538761b7635b5e612c5a2ea20ea7db"): true, + common.HexToHash("0xa0f22fe0d39df6b6a2ac87a362946be7588b4830a8854bd22933f14e1d814aeb"): true, + common.HexToHash("0x420098ad5e00eab75f9f14e858c2e9c65f0035c39e85746242681a295b53c503"): true, + common.HexToHash("0x2039fdf7f8929216a8ff4546e0103585b47d1aefad7f0bb271201d1b5b740b27"): true, + common.HexToHash("0xc93fe286eb06b292138f9bb1278634bd53a0d1b76142286b99fb8b3386d70957"): true, + common.HexToHash("0x8a9c22252bbbf413e84c60d0794c3bfb716715375899b81b5fe4b78081feb64e"): true, + common.HexToHash("0x1695385ad347c6fba93830e4aa0c4e17362a47784739e7acedcdba564ea17ef3"): true, + common.HexToHash("0x524f8c81e6be67cde77a89292cbac8fff4213e4999865e45828fc12f108495d0"): true, + common.HexToHash("0xd460ebe14560e59fa7ab4cee98dc88230a412287cba258c0533339bfc1206f97"): true, + common.HexToHash("0xc995efe9a2057f36ebc74063d41fae40720f28e7e98ad8656dab3599e3cb01ee"): true, + common.HexToHash("0x57b080fbdabbc8096e5732f59ac9ca17c89c4892459580ce92d45f1760939edd"): true, + common.HexToHash("0xe32c9d630dd7cc53d691e88843d6dcf704362f70c9dfdd2e2c2ef77860584ec1"): true, + common.HexToHash("0xbf9116f244d79d286d1b0e4ef9b2e8d098f6e9fe885fc1825d6134d58c738234"): true, + common.HexToHash("0x671afb2667a2ba43c71ef2582e404c8ceff682731231e59ed3f136b53c1b432d"): true, + common.HexToHash("0x2915ff008f20c9a7d4ac2be8a114da23c402812e0f1ff0f8ae0dcd6c71ee7ab6"): true, + common.HexToHash("0x1b48e081f4622f106e26bdfd0bc345b6d459e3da253c7738846ed2e0800ebd11"): true, + common.HexToHash("0x523b9a712f352171de6580bc9070cd56b0bfe3f0e904614b0805ca4e89e259ba"): true, + common.HexToHash("0x0cdb5b80d2ec130ebe42644b4d578d5b42e71ba3598f858aa21efd879f19f852"): true, + common.HexToHash("0xbe005e0fc46a0fc9bb7d1b6f6c6b94937699f873bfc9ce945fa4daa63d328b89"): true, + common.HexToHash("0x640b2a5e74fde3357b13f9e3bb078b71e2193967a9458b0a08af81e663687b56"): true, + common.HexToHash("0x97dcee77c5c7192dd8306ba0a0c9b1720b4ce30b018163ca7f4ccb751629cab5"): true, + common.HexToHash("0x6ede6eb5318ef834ce44047894f86a78dccc989533db3f175f2567cbdacfe6f3"): true, + common.HexToHash("0xa74579ed5a8fd3046c5b73b3f07fe31e30b1bbe354337cec42aaf8e1ee53dd0f"): true, + common.HexToHash("0xd9c230fa0a26c195cc814984bf3d0ebb9e510e7c9564f8b62aa1fd785ae6b43a"): true, + common.HexToHash("0xd03d36bcc141e45c9dd9bf1debd19ff932c4f5e521cf582eb5d72f8e33df1dd7"): true, + common.HexToHash("0xef3a0645f4dc3daef2ac53dad7006871909f8862c4c41f4ac990fa76e5a4ead8"): true, + common.HexToHash("0xb98a8a3d2a6928fc6a2111d3dec18f97e016d159b417b2dcee454cdf7f4e4628"): true, + common.HexToHash("0xe9ef195f7b9c120fbe95c61da007c6a95e9938cf30c5d6f8a5afc3867af830c1"): true, + common.HexToHash("0xe4a77711f4bd179b301f07c1b04700a8e0b9018600c36e379de2e233a44c169b"): true, + common.HexToHash("0xceed50a03fb5da4ecbf29215ca410244f042c324dbe1ce266682a26a56c3242a"): true, + common.HexToHash("0x07676fd50bd8a2476dcba8f81f02031cc241f5288648726ceed9e58b1ceffd39"): true, + common.HexToHash("0x395a224a9dc3b924845fb2d35c30a7e390eb5aabd01918bf25cfffbf533952f8"): true, + common.HexToHash("0x6d867e206d876c9bc396324bdf7debf74089472deffb8275663cd06afe3ae7d3"): true, + common.HexToHash("0x6da4a6a200ffc64b0665a3865e93caeb35aac47258e24e3ddc9c438f62d8201d"): true, + common.HexToHash("0x740f301f84be28dc359d7c767aa8e5a2d8883a684f3056b440fb1fd05ed074f8"): true, + common.HexToHash("0xfbfa95a70e1f2d00cbe86172b1e58b004d47838f23fba7b8c534c333b4130889"): true, + common.HexToHash("0xc0f5fea30f7f78386197bd820146782544312bbd6200f7728ad30efa430f43d0"): true, + common.HexToHash("0x924790d71561e2427dbe625e494ff1735fe1277f8154fb3ad530c5edb8bcd712"): true, + common.HexToHash("0x96de893a6a262cdcc65fce1b3d5e7c598eecde29f1aa60ccde03e3058f48880e"): true, + common.HexToHash("0x561626d79be9bb0f72be2b7e5dab488b23ec7c0b14f414c72bf59b250d3d1888"): true, + common.HexToHash("0xb4731594c5a1ee5aaedf7ec0e5f7402a45ea2b99d1c462fa202175720a00e97f"): true, + common.HexToHash("0xe86dd3de01e3968c2434c9f324c93b3129e2a188675f814b27a110455f426109"): true, + common.HexToHash("0x7fcc20cfcd9bfcb7d4600cf860423fa45d05450e9c0ece4efc70c929aa9884ab"): true, + common.HexToHash("0x5057226052d5c39b663c0e0ea1c4650aa8e66cce4357a760e661ac2a21f594a0"): true, + common.HexToHash("0xcf0e7b581e7bf62f6ab6d07d2bf39641df1ef835d74d739920b3346110211367"): true, + common.HexToHash("0xb25d26dedcb8c5c23c26ecf2ee4db6e3560313af0cd754665d5c3c831352caf6"): true, + common.HexToHash("0x28f106418285bf6809a606cf7d67b804b731e10140fa831916b4cd1f4cf58c10"): true, + common.HexToHash("0x359b64fddf2ef31a1a5cee9cfaff4b2510ef96631b4de91a225f9328d3633825"): true, + common.HexToHash("0xd42c191b80094c420dd74468f173ab1d90910ff881ab95f92a7abcb98aef5674"): true, + common.HexToHash("0xfb400d36f487849baa2588d5c45106ddc5cb51f92de4c607473afe11d3e18806"): true, + common.HexToHash("0x786b3c5ea538062fa3300efcb7730c092b38c216db6906f616c3974d1fa5a2ae"): true, + common.HexToHash("0x0ae1ca8258f2b393e09a13e12bc4bdb81c86dd65dce49f538d0c95e9588b9b81"): true, + common.HexToHash("0x666d52eba38936351c238955d6a3f69b6e960b05f9d227ae67859a1cd27f5e73"): true, + common.HexToHash("0x63c27b5f48dd69bb96dd18d39f7fecbf0a4ef7ad468c8155b377f4b669d565f9"): true, + common.HexToHash("0xc42862488730870826160250ce85b3ad5115e21fb186e5d7a65994ad7cd0e1c4"): true, + common.HexToHash("0x9b7e2782db71e2546eb12437c67345b7c0e3113fb216dbbd3b94925a20538fb2"): true, + common.HexToHash("0x0c0f8f97a318a2e12e723a17f650226a69e1c802e7c0bc809a4e1495d1496165"): true, + common.HexToHash("0xed1d5744a84cbe3dc168d013b8baa4014a5f2ecddbad3f9eccb01e62b7f67c09"): true, + common.HexToHash("0x9ba6c56bb343bb793c5c004e6fe879a858c4285f0335d3bf0ff7c17f6b1c1234"): true, + common.HexToHash("0x0d179bb0a0bd11afc5f373a3c755521f0cf3aea3c1799397be722d9ce7f1e2cf"): true, + common.HexToHash("0x2bdae770f82539cb5e190a46f3f4485be7349251e6ac97d655c21c8dcca9be7c"): true, + common.HexToHash("0xbc72d6d465ead85fefff2efcf981bfca3442e05d06762c647af9d9fc5732aaf5"): true, + common.HexToHash("0xaf1edf943c05f5558c1ddf0196b998b028824077e7332289d8508196958cd591"): true, + common.HexToHash("0x4c17761eb32c76595c2c9f213fda12428208e0cc4004de65f42e519e634a7c63"): true, + common.HexToHash("0xc76db4b60924bae2b5fce7b3df25df65089862cab41766e7243a810267c82c9d"): true, + common.HexToHash("0xd9fd389f04b68d6f2382854ab7204ddc918ba63fb4d451166c81065faef47df0"): true, + common.HexToHash("0x4095914d2aaf365f103a807aaeaa34947fa7b6cd645cd8819b5cd00e77166005"): true, + common.HexToHash("0x24a47de0a2557784236f76abb9fecacc932be8e065f9333b75922380dae3bda1"): true, + common.HexToHash("0xa66ae0264d6b6e26003cdfba1b45000004c8c6c907bcc29b8c37d33eaa3dc414"): true, + common.HexToHash("0x23bba356d17e608ed45b156ce413bf7af3a5bc35db3ea8fcef82b3afd90a256c"): true, + common.HexToHash("0xdeaff6fa06bf91ce956631470d903b42e6ed61ac36dfcd11810216fe4617a63d"): true, + common.HexToHash("0xa3298e9b280749daf92560f5e7a4505bec50dceff676de36adbff33b0d78f8b6"): true, + common.HexToHash("0x40ecdd36a847d6800f6377954ffa4638c0d105da5b1aea735682e29c97839ea8"): true, + common.HexToHash("0xcdbd7738c6108472f6c8aad7ebe81636d73471bb58646835ff006342803faeee"): true, + common.HexToHash("0xa9ca415b7b9e50b1c294872a2332e24ce8062611475244e7780f0dcff5a2afc6"): true, + common.HexToHash("0x6291733abfedfbd2833fc729d416a991e990e725f3ba9438f7ed3ce9ada6b3ac"): true, + common.HexToHash("0x5a2f448152460d02ad0fbbcfbe3e729619e81d14b0e7e0458184e6168b6ff318"): true, + common.HexToHash("0x2070db4e1785ae9365a2ff0beccb5b8c78e4ec407e759562585518499da6627e"): true, + common.HexToHash("0x8b30c95deceaa8b74d4b590c26deaf58d895c62ae706e6877bbcbb8b958f72bf"): true, + common.HexToHash("0x65a93546001b08c5c892b9c32830abf7485c6c079656810b273eee2cc5ac17fa"): true, + common.HexToHash("0x1a2b9309ff5215267b384857033d9031cc693179de256235512fe94baa671a61"): true, + common.HexToHash("0x5aea27ccf417f897751e827917551cdce70a375cd77b37e5fb603ccf2b84e049"): true, + common.HexToHash("0xbcd684ac888655a9f5dadfd10b76ff968c7488414ac9e5055b6f92bf8806cd35"): true, + common.HexToHash("0x2b2876fa3f297861edf23342af7c1adc772e7eba2695225e79bbf928b848b6a8"): true, + common.HexToHash("0xee55e19a2760a9ff19910b90f2b25e694b8465144ffbeddd101cff98611addb3"): true, + common.HexToHash("0x4852fab21475e01a623f347224004c3eeb30e2a65bf16df30a9f48f86afd4ee2"): true, + common.HexToHash("0x8ff4206f776cb8068d1f0c32db43e820e4d8ffcda0bc9e2bafe2420f88caa5de"): true, + common.HexToHash("0xbde62da29bf1651d5c15192ed3d213e2ff061d390852c2976fc213b4c8452276"): true, + common.HexToHash("0xdd33665372f58f74499a88a3bb81b673f79a45b40e82ea1c7602263cc86d9e40"): true, + common.HexToHash("0xaf1da6436b550baa9f2e439b6835173806f304c61140e1ec41ab4c9d6bf5552e"): true, + common.HexToHash("0x06d1674a2b6767cc8fd4654cfdaf6e4844a0df6f1453fd379d71b74c5f85d197"): true, + common.HexToHash("0x6f313c71b7254c31a75c18147dfbf322eff47aabbb557410f4397312b877db16"): true, + common.HexToHash("0x619e6bc966bf5285b169b25e6c7b884b4d2837b1dd90ede7f0752204a03eaf73"): true, + common.HexToHash("0xd3cdaea61df1283028b8fd5109030497c9bd40a4b99a637c44af1aa5d8baa94b"): true, + common.HexToHash("0xbcde687ecc01c6afe1ccbfe20d9a976fdaf1e2c6ea1c9384a3f3915abd266811"): true, + common.HexToHash("0x01309a0a29fdea7fb3307bd621a6e7a64e2d9570881fe9ee7b2a275298f56fc2"): true, + common.HexToHash("0xa4eee232f8102f07f743a85bfedbaeda80e56fbe512b9deaa3b137387a0c7438"): true, + common.HexToHash("0x58a760928460b8a744c8d1830b900d5e5f82ee8aee079005c064c6f4d2652e60"): true, + common.HexToHash("0x83ecd72088f11fd7572958e1d84935075f89c720ebccbbdea6c321cd4feaf6cf"): true, + common.HexToHash("0x1ae98d358ffff19dc8a901b3583c237470a6025aabe74d4e5b25f798e44c2f38"): true, + common.HexToHash("0xd1266bfd364a20c553dc0a1f2340246cc214a1a87cd45651ab1962512a89dfc3"): true, + common.HexToHash("0x263682cf1115cd062b8b8422d1fd79d1b24f28d9c843778e6896c2f82a388f9c"): true, + common.HexToHash("0x076600b0ac3e737e0c3f565be0522af42a40291a47fe5612592ede3c9b56bf17"): true, + common.HexToHash("0x4ec13b8bcc64f89413b4bbc3e0ba66e187bc218b7682ca3109f8f37cbf368b2d"): true, + common.HexToHash("0xf23b73197e0d9065ed5c551a7aa2ec1dc7be73cf0839642c0e1380afac9f7d7a"): true, + common.HexToHash("0x32e0e37fd58dc228b08a0fad6e3e1714b4bbea995928ea00a002956c501b6ebc"): true, + common.HexToHash("0x7d43f5b6fac58627ee0413e8110bee39bc42177cbd00130c4172d9d14f79a6a5"): true, + common.HexToHash("0x52207bc555b41186c868d993e94f17697a961d5915a43938ffd34162f23b17e4"): true, + common.HexToHash("0x5e0bc199799d4192d7fcef52538d0bad31b4514387a57877f40b6521d06826d1"): true, + common.HexToHash("0xd9f8a0640f83b84ec6ead5bda1bdf0cf4b32c200145e1cb380525e4e28f7f17c"): true, + common.HexToHash("0x78467ef812e267e961a50bac86276ccf990bb5ba58c20f5a8d83b5039961891a"): true, + common.HexToHash("0xccf17c198fe920897de03f992be8253ac9aa9b13aec7c669c4c3f0cb9348dfb5"): true, + common.HexToHash("0x1107ed7cc62234b6c8b17354001f2cc7e358e945e38fcb2c1127280a7e286fb4"): true, + common.HexToHash("0xeca1354cb40cedd003d4857073c5e8f590787c7a390ba05abd1ecd9bfc75520d"): true, + common.HexToHash("0x813545cc928ccd2c212cc5773624317a69aa495dde06ee99a35df2edda1e60e1"): true, + common.HexToHash("0x6a944004b6a5da74bd2582dac3a7d9eeef995debf09e23afc17c2126874aa7b7"): true, + common.HexToHash("0x373e721d2ed21e58d730f86270eb222c83d5f8eee713835293a0ab84ad016781"): true, + common.HexToHash("0xa0f3a9b6c89066223cfc3240d081c8d61ca2ec94c5c1b9ecf5a222a0e2defe6c"): true, + common.HexToHash("0xf4c43fa306f38041a99511a5e8e39767f42d0366031a407a5c03e69bd66af030"): true, + common.HexToHash("0x484feb1b2505b2c0fb9bfe72f0c446258bc26ac1f17adfad0cd7edd9524a3da4"): true, + common.HexToHash("0x7392bb704172b2cb3f75db214186ffcda4c674f5cc632701ae272812e19be05a"): true, + common.HexToHash("0xe0d6d3c76b5a0574c2f120c5d420831a7840c97cd6719dc708dcc0cfb4fd3338"): true, + common.HexToHash("0x78e746f8734d9bef0817a8f519ffd1307bcca0916eb89f99321e2ba09c1a5036"): true, + common.HexToHash("0x06783226eb4208a069134aa9a7d7f850d9689653f74263c925d77317dc15968f"): true, + common.HexToHash("0xd9769f073b07ecd4fdef2694e28a8731221e278a3bef1298af3951e9e3ad1e8e"): true, + common.HexToHash("0xd23c0720563c6fb9b847f97ba1ecad4a9a7ac53f714c5d3787c9449f905f4951"): true, + common.HexToHash("0x9b2fcbe63eb319304e3ff10bacacf41266810a977edceee2b81359dac407dcbc"): true, + common.HexToHash("0x9e4dcde9d47479e401ee50f326ced649278bb5209a507b2f4076c977f9a32440"): true, + common.HexToHash("0x67b13b5ae715b8e720f52dccd75995a3fad7bea21ff9e47c91a0829adcf4915a"): true, + common.HexToHash("0x079983f148701a0135cdf74171cddc322fd528fa88d3f09c0b591c719ab0c7ec"): true, + common.HexToHash("0xce5a53b9d6b23ae2e57525a2e8e737d3f5e949b1c1e471a03129288a70d51a88"): true, + common.HexToHash("0x4cb29498c722c6fead6e290dfdade1c6d7d6b2c1e7a6bace03957be07b9bd208"): true, + common.HexToHash("0x825634deaab3ea71350722cb9eff0ad53a167b60bd6f0c2f89be7f32f1167753"): true, + common.HexToHash("0xce73d2e07d635eb52c2fd34a19f4d671ced8d753a3b6f0272c2984e68a3b32e1"): true, + common.HexToHash("0x66867baa80799662ba4c7659a0f52f0ed77278060239b588a3a2baeaece0635c"): true, + common.HexToHash("0xa3dc1e2a05605a4e70dae014217e0d7e2964d9bc1a0b7e8233b510c3ab07e260"): true, + common.HexToHash("0x7720f39527a6b69895938fde2a726194a7f6499e7e4bf1d6a3df244557c09243"): true, + common.HexToHash("0x1d5bc016bfd305b7e167395b0b1b50c78e7ae9e22bf7966d680a75344a01687f"): true, + common.HexToHash("0xb260e505d1fc72c621a1e3d5c26b1f765260c97c02e46bb78a8799dc895e6346"): true, + common.HexToHash("0xe6a1dd0edda0ee5e22f287a13e7c3db785a3f0c7db4a5f3a73dfd57ef6784010"): true, + common.HexToHash("0x7da448a546802d1805417de1f7eb2fb473266cc199143f645568962902c448c2"): true, + common.HexToHash("0xb75c3ed5064206ba522b6a46523fba6d3a83d0820a0be860d63117e1321f1dbb"): true, + common.HexToHash("0xf06736529e16031387f1a5e865eb2ef65cc606ce6c9c265d305e642533d9f3c1"): true, + common.HexToHash("0xb80646754566de0fd159935e7ac6db708297db2fa8772fef6cd42e8c776cf21b"): true, + common.HexToHash("0x9160c1db814f1fd7a02f0bd76505b359f21b95d70629bf8a335ffe08b02928f0"): true, + common.HexToHash("0xeccefb106f8d1882e44b2552dd919e2939e3a505216027ec97d548f99fc3051f"): true, + common.HexToHash("0x09e7aaee3d238ebb194a11319a34359cb3f5e598706f5a162fdfc615dc2c02fb"): true, + common.HexToHash("0x8636089e29e80b110f8288ea79da0f2768b7e8bef2c169c207b256be10b49d6c"): true, + common.HexToHash("0x51a417998d8c86432c413c300dc7085842c2b5ad834198f711b3f66c8e972876"): true, + common.HexToHash("0x2710044b0197586142b1c77dff571b03840fe0e7998d96847b129c141df9f85f"): true, + common.HexToHash("0xc1992e9cfe1cc61ef605a88b96d81f13f9719c7f0e9b689e257148b597b3cf11"): true, + common.HexToHash("0xf784e1fb7fbc0c5d86a75971a56c0abeb64b981b84607792c87b5730ca485669"): true, + common.HexToHash("0x44399cf438b68d0391997c63017899dac423a246ebdf5568da728a053006224c"): true, + common.HexToHash("0xe604409880c62def003fb80ca397ac27216831e75bc3186e5880c10feb480182"): true, + common.HexToHash("0x7f600c507168215c79be86861238376e75f2a0b72ab7b68ac0abfe720615c460"): true, + common.HexToHash("0x7aa227cba5b19f10bde233a48dfa1b17099a3139d6befe488775ac12e0927354"): true, + common.HexToHash("0x3d538c878bcfdf9b998780f8004a678bd6698c6003cb56e24286d7259bd1fb2c"): true, + common.HexToHash("0x3a512ce604ad7e2770c95d9e4355afc65bf0985f2718a03cb4a0bb4aa69ade48"): true, + common.HexToHash("0x2afaf827908e5e965f1fb410bf1a023edf436cd053714e5591f62df938490c36"): true, + common.HexToHash("0x0798987ee8d62077c6059ffc27137ae3b8487b1f784472121d28f6274cc41c72"): true, + common.HexToHash("0x2980d5acbfa6e155a533c56b97815e6b50272a26dbc25682f5080a0c72cd82c9"): true, + common.HexToHash("0xdbe09e19c1d40f4799fa94dfe8202bd3043ea559564a951a9ad555fc3083850d"): true, + common.HexToHash("0xbf38e9c7dfdf0b778ff5026673a006855f62b1e3a3b074a1c390319d62be36e0"): true, + common.HexToHash("0xc7056f68483b3677c524b5c8d1ffadc6ea349d1dc61200c5fbb49631311dcf55"): true, + common.HexToHash("0x226cde166e800d0a089b13af1267251cc01832fb8520beef476ad0982d68f8af"): true, + common.HexToHash("0x2791a49275974c8d97cebd5386eabf7f1c9872ffcc620ede02a641fafea353ea"): true, + common.HexToHash("0xcd0b1321cdebe319755d4fd940ee781000daece465b480baf0305cae01817f25"): true, + common.HexToHash("0xc260ccb1b03e53070de5317bd5234cbafae9a8d33c678da6cf2eec0a963422b6"): true, + common.HexToHash("0x755218249731d9e26ab454d9e0d4dc39a925e0b8bf5c8eda9c1e18c8429a2c90"): true, + common.HexToHash("0xc4bde28be40e90aa25a45c36b3e2add416718573aad6a065a7e26879a21bd162"): true, + common.HexToHash("0x90d029d4e2d67123bea7f578a1649d1a4e3b6716b1e7d4491f180b01027217f6"): true, + common.HexToHash("0xf9c0d2380e840d51a3657f2e651800e60906d8fee2ba07d4d47d9b65725b511d"): true, + common.HexToHash("0xe5336923b08acce1d29f8f8e47360cd61b0eabf52f4e69fea9fab4ccc0117d56"): true, + common.HexToHash("0x0fe596ae3c94f3baa27b409ccfb11c444f0e3074188009d2633d1f24d42e0fb6"): true, + common.HexToHash("0x74b5e1a5d48acd5283648256584d7e882ca399e1b211bf641aa81f6abe1b44bd"): true, + common.HexToHash("0xfc0b846c7d2acd2a8247aa45e3203be358be68c821d011d8608e952d74cd73c1"): true, + common.HexToHash("0x5b889befaaf6723d5cb8cb2569aba14e4080406096ed632a0402a037630b5494"): true, + common.HexToHash("0x22e7f61827e812c37bba1701f99bbf0158044a8d8954e14c811dd9528b5d8d66"): true, + common.HexToHash("0x6d4ec62ec69fe9db6a5a80b895016ca76194ae748cbe17d3aed1c00082f17397"): true, + common.HexToHash("0x8bd3b8f0ac50df51d40ad65567fca61703802a4836b991e81a5d48b375158c69"): true, + common.HexToHash("0x23a6b9cc7d47ca8e09a0811c9154c97ead1954b83f370e98b7842e9fdc078b72"): true, + common.HexToHash("0xaa77912c3c8d9560673b16cddccbf46828df191f223a70d99d07817920a689b7"): true, + common.HexToHash("0x7024b9e813abbb786914fd6849811cd52289aaab9da1090115594669a4492c69"): true, + common.HexToHash("0x0ea8f0780d3482a378f2b4fce1461dfe2124b1f595dea253ccd5d823d15529ff"): true, + common.HexToHash("0x5076e9e9f5dab50e00ddfbd636a23cfeee15cdef145930bc5c573666df1333c0"): true, + common.HexToHash("0x43ef79c5d0b9c8718986a3e3bd003654ce31f22d1761d318465db4d3b0a5a645"): true, + common.HexToHash("0xa44774beca66c5ec71966db2bcae4d4039f9b8eac22ac18e74c936780a4b1c6a"): true, + common.HexToHash("0x85447f629bb17a6fa8fb26ac41605ee87b64a502ed433036fd3ca9f51cd09d49"): true, + common.HexToHash("0x1bd5f9f5144d2535d67a69a21337cc2db81d9f1a41d66142b3a39c501089873c"): true, + common.HexToHash("0xd80c5f20f70eb90640eebf03717efc38c672ccc1f9d8378d277d4a7cf5d18edb"): true, + common.HexToHash("0xaddab81d6309fe6824566cfbbbb32c52a0ddf8f5d7989e914d1f5f26bd783aef"): true, + common.HexToHash("0x41ce06addc1e15735e66603540a1634716628dd93a1598280f1a2e9c34804db0"): true, + common.HexToHash("0x8fe08c77043743f5fafd37dff53242f984ca4b2bdf1f2c89826bf16b8e8a3fe6"): true, + common.HexToHash("0xfee4064c890c2a71e91a45e7f90bba23a6997a27ce0406608169a480fdcc1f1d"): true, + common.HexToHash("0xb6f8629951ad3dc8aaa67e94ecfb16fc9b03058ecea56aff79eefbf25cf0c727"): true, + common.HexToHash("0x986a1f0152118ea5adc15016ad5ddff49bbe9a91b8f95529b9870e645ee28ab4"): true, + common.HexToHash("0x33d3d7c272b30c65a46ab8df9db600cece064784eaf7f0d1212ea9bcf1c67a79"): true, + common.HexToHash("0x7ec31957775088456be5293f2317b5227e4b25315ef212be9b7ce24d6f52bdcf"): true, + common.HexToHash("0x4313bd670adaef74f13209be344cd136bfb2d115d1d1b6d6ec229994918f8299"): true, + common.HexToHash("0x26204511e490175dca26a2659a6994ae92ca8d123c9bf49e654478dfba0a962e"): true, + common.HexToHash("0xb36a5da4ce1ec816a89a2f92d7f320ad06fdbd3038226b8de61c4e5f092e5b54"): true, + common.HexToHash("0xdf1ee6e3abfe16f43b47b86659cd0d1d61c85234cf50feb912a501cdb61b362c"): true, + common.HexToHash("0xb4aeece9d190a37079206de87a57481e62449b281f3dcc998dd280b293489638"): true, + common.HexToHash("0xbb2f522334aa40f6fe2d9e45e4f382978bb4613f794979b83ad56b7faae39419"): true, + common.HexToHash("0xc9e751b636e04568f1521adbe63141bc2069b5b9177179365607017443139841"): true, + common.HexToHash("0xc213a234e72fa0d6d5b482e0c349838cf267989c42a8656c5c03a2b420d19247"): true, + common.HexToHash("0x4ee568f5eabeef62a9134079ba823a17f9d08c7fc0501f0c2f1c11d789ef0f41"): true, + common.HexToHash("0x46a607d9f8fa3ba80f6cae193058a285617e112caa1766f65b22817e60c6572c"): true, + common.HexToHash("0x2c5403e92663ff298a4f033cb0e505f53a879744c7f2dd637d1de26b7fb7d9a5"): true, + common.HexToHash("0xd0cf6a64fba03412980be39273493069ef6838373b5eb0da68cb7f64bcf42403"): true, + common.HexToHash("0xa012d0b70742a3a4660813bacbaea38de46ead66bf9427d1734a3f81a02d61f9"): true, + common.HexToHash("0x354b6ad9456f53999c95d7f6b451c09047b432d7094cdc3ecb117565e9d0ecc7"): true, + common.HexToHash("0x2e9a0493e858b8222a5a50de5ced229ebc5c93b6e760204a1edab580aa2f9800"): true, + common.HexToHash("0x72e2f17d9ecb527d2c38f55dc98fcadb428b10c6a0518affa116f702a39ad9b4"): true, + common.HexToHash("0x30aa88b593aeec56da6efa5fdeec9320f0fd4ede6938fcdc37360bd8cdafb445"): true, + common.HexToHash("0x94dd8427b0cbc5088314f07c47bbfc9ffda9e8507f51d1d38cb9872369280e09"): true, + common.HexToHash("0xba716aeff5f36a49e626b22aa7a57488f753e27da8f7caa9fbee3e70ca1c79d6"): true, + common.HexToHash("0xecc76e6ef9f013735e1fa9e1a5ca408076bdfae9401fbfe3339846eec4e0dc62"): true, + common.HexToHash("0x867aeb6188e86fcfca0b3dda71e1e953cbc4298b12cf2300e5d771805894d9db"): true, + common.HexToHash("0x03d0d0ea8ffcabce110256578f3c07e1dfbe106e2160e805312189459af3e828"): true, + common.HexToHash("0xa8d7ae672b36124166826b36e7f5ef36be3ee08647047021788c26956915ba9c"): true, + common.HexToHash("0x70e2d0c8b5e4805ec2bc4b2a97a587a7f715836b4b2cf759cdb7d001e6b7f801"): true, + common.HexToHash("0x13882704805ea1aeffdedccfa2fb8ef01d3f6120f9fcc9f211baa0657a496c6b"): true, + common.HexToHash("0xaa564582c50105a16aaff3c3496280968fe1d6486680dc062ae49abd855e2416"): true, + common.HexToHash("0x3d329fa4eda63febe38e3910c146d3cfaae5ff440c7d6d7ee529473095e6a180"): true, + common.HexToHash("0x5413a5f8467eaa3be78f490209c9fe82a17771050aee7da7b63a01dfbcacb069"): true, + common.HexToHash("0xe643cdc9e6c087efe244f37abb783b83474057b23b5a1a2a57b56facded43c6a"): true, + common.HexToHash("0x1a6c97f09c2f3c57ab2f2aba3c0aa209a719ef8f840a07aab98444dfb3d8f18b"): true, + common.HexToHash("0x82737bc7d72e09fbdb8ec3818c598e92371f76e7fb8adf7382df206613949f16"): true, + common.HexToHash("0x29e875a3bd9ff43f7996d08f961d5e53683c685b542187b6c20d032bd5f36af1"): true, + common.HexToHash("0xc378e57f9b0e8fe97e7e67f2a289bc4372ffc5de145643236a6097bcb4b623d7"): true, + common.HexToHash("0xfd68ae6e81be7e72765c92c3734e5121de64508c2f6add5dce3167e5d79f1a68"): true, + common.HexToHash("0xa42b5ee3441c4fce0d3838b6b9f989f2f345bff82a33a62f3b01b6c9f1aba0be"): true, + common.HexToHash("0x7a4685fdd92f8844174e4b571095faedded9f810f5d6765833bfa07201b28c5c"): true, + common.HexToHash("0x722da74e52afe6acce5ea5f2d30e2621e873cf6801044f9c0eaa41bb25e17314"): true, + common.HexToHash("0xb83063b07b1f62fcf548e8e2dea76f7f3d934214cc7876ccb0538635b587f558"): true, + common.HexToHash("0x15e1a47a0ca58929d4b29e28f270b88ba8446733a51f4f6a9f61717ced63a20d"): true, + common.HexToHash("0x54e4ebac6a8d648117a0996de46732325827bad42f8d076a597aa41cf275a259"): true, + common.HexToHash("0x3637fcd14570e2baad010d0a0f535a90a5492f6f525ccd9ed492e0b5bfc26a2d"): true, + common.HexToHash("0x56f819dd3b2b5b716f474dd140819714fa6fbb8daa34ba5ef20cc7be887d9d00"): true, + common.HexToHash("0x01aebedabc732bd82991e75ef6b20fce103dfd09f64477e637fa8c22dcf4bd22"): true, + common.HexToHash("0xe91f9037815cb95ebf04e0a0ed07ab8adaaff1ab97236e280ea397770136a21d"): true, + common.HexToHash("0xbf9788392966afd059f4a19ff5fdea34e421b33e8f4acf5697f5ff63e71d2e43"): true, + common.HexToHash("0x2232aa9afa619507179a9e540b15564a3069808fa7677bae5a40243497ac018c"): true, + common.HexToHash("0xf936da7baa800d2befc6ae7d71168e8a7f640af4d20bd600ff0c3bd624eb4b6a"): true, + common.HexToHash("0x75a5a3aa1c29aa4ff15ad2afa37aa9b20b8a1a1d798cfaf5c16e12957df40563"): true, + common.HexToHash("0x0e3b22ed9ff18ea850bf7d1c6e771393362e70bc75c34c61397c68ba264b1e53"): true, + common.HexToHash("0x276867bbdf7651ee11e56660d11cb2fa24f95d62bc933e80fc7ec42303c24f98"): true, + common.HexToHash("0x53613a564cccf7d3cbe99f255028efb60e38d09bfe7f3a4ec50df2d8e414bb82"): true, + common.HexToHash("0xd51d0891af1170c97a0fb53ca81ece91814b53572661bc32a185c5892ff363c3"): true, + common.HexToHash("0x3e90f22776f8970b2e48fe3085559d721dc4b2080994f806e1f313988f3d4ce1"): true, + common.HexToHash("0x86a41c1f1ade006f1e5a74bd319bdf9bbdbb6dea42cee79a91dcb127cc988344"): true, + common.HexToHash("0x355be97f54ac8b65e54a0ef6bde8aa3668523ec5bad72cf5b1e90896a70315ac"): true, + common.HexToHash("0x69eb209876811b6a0730bcf753c218f91fa2080bc8bc8b771aaf8e72b7b87254"): true, + common.HexToHash("0x0a090c74812e2e1d60eda38f9cb911f686dbd32d80b0e056a063305dc38965ce"): true, + common.HexToHash("0x482f9b896a59e9dbb115f3b300c81608f8eac641af06676fc0a866b016dc3b24"): true, + common.HexToHash("0x442615744e3545c086bf7331ca39830b013dc167b83f2d896dbd05d995ef6d46"): true, + common.HexToHash("0x97cfefc507b3708f4c777a29484ad23644834e3936ccf9f5d2b67a0dd3ec3e9b"): true, + common.HexToHash("0xa344d5c48674c02f8faeb91386987d623fc41db0470c3dd54b6334cd13bec3ab"): true, + common.HexToHash("0x61c5e33b01f5498a8d95efbb7871fb0acfbf2aed144dc36c0a1d952d12bca243"): true, + common.HexToHash("0xf0f0182891029dc3e8a5e5dde31d0492e9233e596d53af293a3c6aae8472c0f3"): true, + common.HexToHash("0x366b6891cf6aa7170611398ad2ff9113055c486bc556bf6c8591d2b8224f902b"): true, + common.HexToHash("0x5d47d35e0dfcf4540d8c67ff956912a7334eb5cf0a5283ab783cc93875778818"): true, + common.HexToHash("0xb117b5021288f5e798f992119ad19ce2c7474383513d4e0346141c5227c58d34"): true, + common.HexToHash("0xfd2679926a161118713db56c145616d041bbf542b231fcd196061e6e15a73d66"): true, + common.HexToHash("0x018883e069c9e0765c04afd5dbdc8e4252515ba1488b0602b421017259262185"): true, + common.HexToHash("0x242d676c672af6ef316c1aa53f0456f1a339d13394113de3eb289724d14fe7f1"): true, + common.HexToHash("0xa385a438611b0f122ac7eec49206e7ca06393cfb70c1eda43a2958814ba4e887"): true, + common.HexToHash("0xd931c618d9f5eb6ee63e26f9465c56751ba7223dc4b1783a91ff7cf82ef3622f"): true, + common.HexToHash("0xb881cf89721b9f7a9d52d3a25a552a20f83a92c310c6a3bd91424eac180b3514"): true, + common.HexToHash("0xd66e74dbc08d946c2e64ba916fa0d26d85c0749f1932b90f06b41e658c054564"): true, + common.HexToHash("0x930200ba3e0079e11628fed46e10f615c35ef5d0ac1ac58b4eaeae894797f497"): true, + common.HexToHash("0x757631f405f2c8679cbf6b1ca7966cf9385421538605cf8d95240680755c21a3"): true, + common.HexToHash("0x24e653163cb078b8ce09c67d4849b400b30128cda264371a6494c8ccdb7c8868"): true, + common.HexToHash("0xfbf71bc2ecf8b82beb51297a94465bf3eecb1bee5df685049cb5fc2ecdc76935"): true, + common.HexToHash("0x5925c7f8b4c3c2866e43258bf2e6ecdcd3fe8c1e7979c36985e7c8f7baeee1d6"): true, + common.HexToHash("0xdfad26f8cc75a87213c467f4bde23902761bdc1a7f620a2066b04e9b92735671"): true, + common.HexToHash("0x8f076de441ca6ce3a3c58fd6f2afa562251301f2b0bbe774bb59a99827d3907c"): true, + common.HexToHash("0x349928aa86ddac0c0c774963f869f4952af571a8210914e39d17d0430a2427d7"): true, + common.HexToHash("0xfa31bca9762b8f38788683ffc2445ea579f28ca630d1da8222b84ae82c258738"): true, + common.HexToHash("0xf1c8f530f3fc8a09b14ca2b82c2a0ae4dbdb7ca87258f5af4c3612cfdcedb7a4"): true, + common.HexToHash("0xdc8bb3329747a7ae63f114d8487460318cf06e6db21d29301db63ed4c53335ec"): true, + common.HexToHash("0xc6cbacf78e302a64d647032d799326f2595a8a48a1e3729eb045662b3e8bd7d8"): true, + common.HexToHash("0x4726cbc792f8dad662aa59e5f826ecb72741b560ab2b420bd3aca907f079ae9a"): true, + common.HexToHash("0x41f405fc6b92930de002e9fb3a8813a1457560015e93aae58fbe2bc32fba4cb4"): true, + common.HexToHash("0x57676595f7fb6cccb7dfec47112c67944ff0eef28eb58d1ce26a4c8f16835704"): true, + common.HexToHash("0x95ead7e0a47bc01ba91966a15c7dc0c71c553f1bce69d5501aaa4ce546db5782"): true, + common.HexToHash("0x15fbd9afdaa2e3c8bd5f27b2f5810c20069cf7dd6da9398b2582060216a74f83"): true, + common.HexToHash("0x378535abaa8bf2d6012a4bba59453833ef84d216f8bd4f8a921f1b38412e517e"): true, + common.HexToHash("0xaa7e90441fccfaf091e4324254b2826e98240051ec1e430ad5da397a435c174f"): true, + common.HexToHash("0x17b2bd88241cd8fa7ab092ff97d6b06f297613c4cc32c0c8472588f3d25a2c5e"): true, + common.HexToHash("0x68a8bc4056e030388c1b31239a2540692448ea161f84c7f6f3d935fed82ada01"): true, + common.HexToHash("0x679c8b35e84f0fe2f9c94b8d1cc019b8f457e738ceddf6fdddca37d92758e40a"): true, + common.HexToHash("0x2643421d96744d4419eb24d9a3f81cb63867c0d3547fecba2aea48d4baa5ce16"): true, + common.HexToHash("0xaf3469e2f6b1b713aa6b79bca2f968d336e2d961afefaeaa750198b82649fab3"): true, + common.HexToHash("0x59da2fee0c0189cf6533e1fd84c247ddfa59f7c3e170bc4263c2bd06528e6029"): true, + common.HexToHash("0xd52fd09062cb9b1b4d6672aa1b61478f988273ca65e728a54f6beb171341e425"): true, + common.HexToHash("0x9d40f2e24d8b68cd5194ddb6d730fdf3c2e05ff9849b2c4a6e4e1d11ee60aa06"): true, + common.HexToHash("0xd83e0de482bf601e4404aa888137e9a64e0880d5a582131fba96265df347c7bf"): true, + common.HexToHash("0x57acf431344aa65a46e49ac6ce08002cc34a4348cccf7240df6c8bc42f324446"): true, + common.HexToHash("0xf212e273a1f474c78384826c73b9eb04950c4a6c1a7d398a2ed738c2d105dcdd"): true, + common.HexToHash("0xaf6f80275564bf0d987e4215b43745a52e1bcd152ff4e6c348b5e3a1df656e56"): true, + common.HexToHash("0x122061d0b25eb571108271c40f4d060514bfad66f57c3106cf3e932a2b143e71"): true, + common.HexToHash("0x560eb7789abf38a0e72b44d0c89fd0f07b0f65390b4118886be350226a0433bc"): true, + common.HexToHash("0xf9ba9bf0a93f13611101cb701842e2f803c07b0f1f17a04e2e14fd5606958d12"): true, + common.HexToHash("0x2fa12b4bea2d6fa64c0a1336dcf810c126d1234e539329afd88eb37ffc1563eb"): true, + common.HexToHash("0x4bb25d0f6675fbe00436248cb130c25044ef7995b57f0067fccf38b8167abbb1"): true, + common.HexToHash("0xd9c0a4317a8167df23fb6dae39383e60f85a9dc693875bbb510dda6a3a8c55fe"): true, + common.HexToHash("0xe87cb132aae852d2d2fff549d49731aa709f8d82a7960c6c833e91c9cea53fe5"): true, + common.HexToHash("0xecc55d677815d5ba009c33bd8f83caa95f2aded33c29602840fd828fa12121b9"): true, + common.HexToHash("0x665faebc6d33c47c4e2c7e87dcd848401c0ee71ec9e3161aec5e9662d0632170"): true, + common.HexToHash("0xe32e4990d3fc66c4fdd86d8a0ae49577be2edc50cd3f45961d07af8382efe49e"): true, + common.HexToHash("0xcb23021c51d430098ad76689c0b7d58198deaad85fbea1891a05e9903e5630fd"): true, + common.HexToHash("0x751de7830fa31381165054e97a5e3bc6cc8959c3cd83c3ff8a3014d468e2270a"): true, + common.HexToHash("0xbe5de8a895a9a5d43efb61d1955000d44e05db0ddf8b0f1fdfc2e05b94a7e59e"): true, + common.HexToHash("0x60d082f4d3a5516e54c078afabdf32fad588c87a8d7d684704c4bd622a5a153d"): true, + common.HexToHash("0xb79e410c8ea9cfc33eba43b7177e87f0beba1fef6b9c362d2ca56b9a75cfce98"): true, + common.HexToHash("0x7a4f3fae7610940f7ac2830f7404ca5849d2242bc7c5984ea42b0d9cd8316188"): true, + common.HexToHash("0x0a1e4a112ac6ed58da58378dba156a22c55cd23eb2ec8587d8bbd91d2c542c40"): true, + common.HexToHash("0x3c05d0b3ee8d16b2e7c1ebb55281bb17a662598666d3f06a760d8b27f77d16de"): true, + common.HexToHash("0x188f08ea1214041af1c63e64cf563a19d9d6b03d9e1b1f9176fa8e55b387cee1"): true, + common.HexToHash("0x5a2ed3a1703817e3d37fd94e8bea0c0b3c116a83d281b1b87e114812b169a56a"): true, + common.HexToHash("0x841db7ffcd00acf0f5e075b95eda6907e0594456a741305939dccab6652f7502"): true, + common.HexToHash("0x330396a842568c2b827d63996a276c80224c4f6092f132272f1c86eb021ebe16"): true, + common.HexToHash("0xb239255914aabf3ea2befe180597df96366ecf499d596089d82da274be576b6a"): true, + common.HexToHash("0x841a9a6d6a446cf2ace15c0d5a780f374093ea6a5292d1d8f83f5a77afaf817f"): true, + common.HexToHash("0xe3850c58e198f3a50192410ccdaf66b939b1602d670e761584dbcec6779db7ed"): true, + common.HexToHash("0x22a9bfabc4dd469c33d4b41bc4ae852bb0738a769ef4a52fc52f1ee90077fc62"): true, + common.HexToHash("0x1a849ca0ae1235e89256bfed3947db7c6630a69ae7f94b06bac564ba5486a088"): true, + common.HexToHash("0xb29b8848a33bd90a0881885a8f51d07c3f8a28f396f19b58e04acd38c6f1d0a5"): true, + common.HexToHash("0x362a18e6313c38a132f50ff6961fc1cadad0fe8f39aa50a8c20ab27087c30a57"): true, + common.HexToHash("0xa3cf75cf7de7238f13717718034fccd3ede32c84866ee465e0c304323ec02d70"): true, + common.HexToHash("0x9571134be51a014b73664de407f62ceb6677ca7172e13e77ce5e64e585c5e5cb"): true, + common.HexToHash("0xcc1107b26bf17615de9e1c49207654765f5b2a37a39cd9d7763b97356cbefab9"): true, + common.HexToHash("0x527471468488cdf4114ec465c36ffa094cd611c06e4a9e7bf149fc13aa1f05b2"): true, + common.HexToHash("0x1f06ee257f715d3d137fa3d8b16f788126a1210dd46d4aa9b406f28ea91b65dd"): true, + common.HexToHash("0xe3a1e498355d310df24ba714ab2a3fa1ffeefee48e2accbf450bf2f2d718f6c5"): true, + common.HexToHash("0x996f1b915ca4e51673e48a93c44d2fb9407fa7ab9c034da76aedf50fe406761a"): true, + common.HexToHash("0x6df7d4f5037136c610a093552c44b4bc9de8a96894dcd67ad94694fec3f08d7f"): true, + common.HexToHash("0x55f575f86b750218002084622b3bcba39cf1ae4987958db8c5318c42d3778ecf"): true, + common.HexToHash("0x2172b602ecb1550cd2d5816c5da8f5e1cec962f9c3f7fa7582bc0e9f348ce465"): true, + common.HexToHash("0xdc745a1f5fb5461bb1120c52e93c76cb7321fe92f5addf2d0d84dd2b21e32e4b"): true, + common.HexToHash("0x915477b0c2141975ef5b7550d82247f0989d25c1c0d02c061a13ed2ff95d8b4d"): true, + common.HexToHash("0x7d412331501be99be0fd2039e83052c97304f007a7fc7280b963e98a90e50c34"): true, + common.HexToHash("0x984b6148891b14636087a248383334edc3ee8c0ed9da7d6ee17bb6c869a0784a"): true, + common.HexToHash("0x315c82cf7aedf0fe2b1ac2841fce91b2f21558ad6456d1d8d2836a57a5cfd230"): true, + common.HexToHash("0x26f0d739ca477e077e4522d5adde9901734a2dffcb86893bdec112081fed56a1"): true, + common.HexToHash("0xd26cfa6c063dfa5c7a6f4f0228d113829594afc01ecfcc97ed7f6d97e6c0f899"): true, + common.HexToHash("0x709760dfa2639939472484953b28c098cfb6691c5df425c8b26eebf3c43f26fb"): true, + common.HexToHash("0x84de4150d3a2a26920f45af8d9fb41f94633dbbec9a6c26c8824537c8761730c"): true, + common.HexToHash("0x01c2278637f606a74b138af70f4585b6ca4590fda36ad1103addf8d68246185a"): true, + common.HexToHash("0x951276cb2d2532c14fec89a8ea030da13a8ee9ed77039080f6f4f193d857d472"): true, + common.HexToHash("0xd13fe0e344eaa4f1193a99200e2d18a6ef92aa8b3c975e2b5279b9c2a7ff9579"): true, + common.HexToHash("0x04ec0e0b916a05f8f444a43d4710ed63b4a714c76653ad976998a50dc48dfcac"): true, + common.HexToHash("0x9bb3ea37108308cb7c5eeb797ab1abc2c5c1f1ca09c878176d7789edfe9b95e4"): true, + common.HexToHash("0xdb26e9c3618064752c1bdd2ffc6a2fc76ebabbb047dc02df1f10e9ac983a3337"): true, + common.HexToHash("0x3bdec2ae0758dcb0d7429c7fb635e8fd7087b4ea91d8617f23f955485684ee0d"): true, + common.HexToHash("0x7359facde0f245a8c2003acde673fb1069dd2296870da13b2454ccd1abb8f68e"): true, + common.HexToHash("0xf807184c7b0a4297ce09360d12acb7e637e1d3dcb74fd023ca7fbd4ae9c9f48d"): true, + common.HexToHash("0x0941e5557c3f2608c689de9f034e89089b70a8b0dd51b2d1a67944a6deef81bb"): true, + common.HexToHash("0x476f363d9e92c13b223c04c17dd753280330159d951581cf9ae1bfc2f70c1bb1"): true, + common.HexToHash("0xf4959cce54965d1f6a8dc77aa4d47a1c3d2c4e0dab43688e262145bfb264179c"): true, + common.HexToHash("0x12cf06495111e300c2b6903b0cfb970e531d84c6b37aad1ecdc4f57b21d539fe"): true, + common.HexToHash("0xa9c345a62c65c3e79d49380900d8d4c82af5ab8e587daef911a72639f6412e95"): true, + common.HexToHash("0x985196c1c6712d31bcf5555cf86f8243cf4158f29b8b8f7d1efdffb9a41322f2"): true, + common.HexToHash("0xd0f7a95737f583d7f15a19c85b51adeb1a7ab162db87d612fe7af76c44469924"): true, + common.HexToHash("0x78883e5b2acb91cf03d1c154c3119479d6ca3412de5945fa3cf26f67cb02d334"): true, + common.HexToHash("0xb0aa884cfd153ce6bdf27c4ad767cff287772dd7ee48cbe254f3430888396c91"): true, + common.HexToHash("0xd91deacff2f8e6be50c0498f970701e507f2bbd9e0facbb63543a323b872e88e"): true, + common.HexToHash("0x1413bc931b885ea9efa4f2c47eb2d76a41c9593f0774a355a4b949aacb01a66f"): true, + common.HexToHash("0xd2618945071a9a091c730841bb269ce1bf3a8cbe5a49e0bcf1d4cdfb4f0367f6"): true, + common.HexToHash("0x53d4891dfa874794eb7bfdd02b389a9f02cdaacea014ef5c67c41f1fc49ecb96"): true, + common.HexToHash("0x9891205972fcbe9425d3289a38bde370759c58ad9c2c4625f72d5ec25729c0d5"): true, + common.HexToHash("0x8fb3f1c32ddd0e7489686cef2cd91c616b57420b47b45761a5671e9a612838b8"): true, + common.HexToHash("0x1759edfb22df37d62186a835915f88173584fc8d7f7cfbd156919489ca4e0ab8"): true, + common.HexToHash("0x73fee87b6717fc30450a2994359ed4b5609ab0fe8b96b6483d539d100c6873ba"): true, + common.HexToHash("0xa01b1d19e9acb9e369d41c22eefd7a382acae5fe960c411305935caadf08065b"): true, + common.HexToHash("0x4730004d034fd329f61ace9ffad9abd7cfc86d028934c2038f6305105fbb0091"): true, + common.HexToHash("0xfd899af3dfb4d0c86ef1a3a8f05cb5441b12976b9fc53f1e3584ef57df6d8828"): true, + common.HexToHash("0x543bc322279299e15ca4f17aeb600c628d90c41ff913a0b92eae5af82f32ede7"): true, + common.HexToHash("0x387cb323c2e6058bf76555e350a24728ce07d2f96364f374d0d670a9619081f7"): true, + common.HexToHash("0xa6cdd1ad7374ade4c7bd8e7d1d12d8e26e0fccef95bb18577b462e552a05680a"): true, + common.HexToHash("0x4ff7b1e89f28610aef635abaff3a4a7ed0e37990f1c39d8a31ea0046308f1e5b"): true, + common.HexToHash("0x095f9f3595e81a7bb66e99b338560696a9301da2986f3ed48e0ad0ca6dd09609"): true, + common.HexToHash("0x9ed0781853f1159e8bd93d948b326fefd8de2a89baa545b96b50ab6521e38b18"): true, + common.HexToHash("0xedee5d7b53cf8816ce689f52447e8d5387b3f244fd4802178cd3de8918f052bc"): true, + common.HexToHash("0xdaf6d02a78c15bfb72274afe0f4077e4ad91cf1e619805364577286ca40433d7"): true, + common.HexToHash("0x86b68d0d4d3216442ffc831665e6426be37400b6b73198f475831c7cb4413517"): true, + common.HexToHash("0x5397f0b85bc19dacab3c24367e96f6f5cabc6034b2c53eced6ea88ba3048cff7"): true, + common.HexToHash("0x941fbc50e57edc0b032876a70f88e9c00e35e82115b5457db5f9f68924cbadef"): true, + common.HexToHash("0x81f5b4a487465e097bde1ffe03b48dc3df3a6506c8019e4e9ca98d3355615267"): true, + common.HexToHash("0xa80dbb5f1eccb0c3111b1ced4ec28795c81f41bb23e70499100fb4fc6ac36332"): true, + common.HexToHash("0x47fb6da4e4d5625002ae6c477cb4ee363446eba63e56aa35396cb7c235ff373c"): true, + common.HexToHash("0xd983ff95cc96df1ab26bcb2242dd8db63fa8de20e4dbbf6d83872eddff67cb57"): true, + common.HexToHash("0xadc45830be98ad6cb8f1ff26e7ee69b556f914919b8ba30c7f767da4d9b517c5"): true, + common.HexToHash("0xe9807ca2a03014f678ce561462d8c41e8411e8ae205d9851ba00d07a3d459c7a"): true, + common.HexToHash("0xf3569691bdee3e7db53ce1702fcd80c78e4f15421fbcba1aa0308c78f156f4d8"): true, + common.HexToHash("0xfdaa657ec58814ded71afccab5ea923432315bd84cfc20e22b6301949eb54a69"): true, + common.HexToHash("0xae58b3e6eb9589449cd145568c807645f217a0bbc3d49f087c08603e2898d185"): true, + common.HexToHash("0xf8291d09d4d423b52fe8d7ab09df5af8d59255f3575e4f6ee6744337d63d84bf"): true, + common.HexToHash("0x4301e6acce4433f10da768e3b6233f75816c501141713fe0bb33390a212bd047"): true, + common.HexToHash("0x7781aaa02dc9e9a636ff4a3ad345f401b9a3cdcb109b68fe6929f82fb980abb9"): true, + common.HexToHash("0xe5bb4d91d918a38cfd74e2145265475c71e9d0a166031bb9cbccf5720a7680ea"): true, + common.HexToHash("0xc5d0a0ca0e158999cab8ccd939c88df1848e836453759dc1cf52fa3f500bd3e5"): true, + common.HexToHash("0x0695cbc8ad05206a17712db0116dc46ff28514f5c5c35b90a2c64e728854ba3a"): true, + common.HexToHash("0x9b8d7a6b1df67590d3283d10f36f6036a9b9b0c246b0f927681b22d44917e1a0"): true, + common.HexToHash("0xcf2731cf5b927260d6d882f040eef64f4ac5b18da266b0a5efe4563fba76764f"): true, + common.HexToHash("0x67e5756641d8f313c07e81205b430b20e4c5abb81e71745871928cbd77874a63"): true, + common.HexToHash("0x79776477e34cf851752bd50dffd3e29611561072703e2f3e08c8d1c233356e54"): true, + common.HexToHash("0x9f809e1a0c5a3f0cc77b8d0ff3d3a205c088a4ee119d093b25a3388542a8ee66"): true, + common.HexToHash("0x8709d34a36022edea5d5477fbdd057e8714d76d2994ecbf7f9646eda14fe8773"): true, + common.HexToHash("0x7a1b253fa850d4d95f204430152ae96f716a92378e1a5bbb2219b13d6a11ae56"): true, + common.HexToHash("0xdbfc76fc3bc8f81d20127c8afde6e14a8e8aee14a953181948cf22736de5675b"): true, + common.HexToHash("0xa397e7eb0136a535510021d1fe5892b0b34a63cf470de390b5c18cc47feeff44"): true, + common.HexToHash("0xb4b593069fc772a3dce810513a04418682d1a3a66af159afac851a3efd490c12"): true, + common.HexToHash("0xc84e90842e4bfbd7d56cc4b8c73413911601648f04c74acbd34ad1b7f9053286"): true, + common.HexToHash("0x86f2fb1d790a909d3514b2d9e0a2dc55777944eaf998dd15aa2c12c755881bb0"): true, + common.HexToHash("0x462317c59094975253fe953847cb2cc8a5c936007ea1d04697cd6904e0023baa"): true, + common.HexToHash("0x953fe9ea654ae982f021fe205a6cbe4abee88d5d1c557d032506d08a1167766c"): true, + common.HexToHash("0xa388540f3aabf598ce76bc02d9764b327dac78ccd0f5b6d6119a8d4348c48f59"): true, + common.HexToHash("0x0caed4489628cfef0bb348acb92bbde5ec150b0bf7118b7d59c35d7c7762587e"): true, + common.HexToHash("0x97c7d77ae16fcb3c47b3510393596ecab6d5858b78e8b9a0b17aedcda9ad3629"): true, + common.HexToHash("0xfcca55489a4ebedb7de9ea15ab202687a5980bce5e13c58d8521aa237dd8548d"): true, + common.HexToHash("0x3a12a9ce41df360d4ed7ed0054330ba52fd9bd2724a0ec8674f4e53ea08d0da3"): true, + common.HexToHash("0x806e3c12c56d5291516633d1304e988e97c143b6b52555f989dfbdf060d9cb8b"): true, + common.HexToHash("0xa87e70a182ff09611c1815d350cd757257cf926d26aefb00975cce91e208d3e9"): true, + common.HexToHash("0x2df0dc1578f7014d0935ac0c9fc14120af3c7ab6974b0bad440eb5fa42047769"): true, + common.HexToHash("0xcbd9d9bd34e01e3108e7c7c40f11b813d335a9f00a2be9b8cc8f476718ca61a4"): true, + common.HexToHash("0xd95e034bc09528e731eca6b53401eda03a93ca6be76c1d886f7cb3eb74b7dc2f"): true, + common.HexToHash("0x8f3102b6bd3f3503de6bf213e3c2ac7dddda13064aaa4ca2ddd33c895912b411"): true, + common.HexToHash("0x809c248b7e06b20750291ec6848eb2b0bd6813ac44c9fbf129fbfd7ba676eb50"): true, + common.HexToHash("0xeb561531530017cd6ef26ce9d36e78c6483b6f0f5bf386ef04beaa6b45cb54e1"): true, + common.HexToHash("0x65475202c15391bddff3a8415f6cd272d76b793765839db95cbbef641efff756"): true, + common.HexToHash("0x2e29addd2f94cf5b72f773b939742146818f5049c09151b962f58277b0425b07"): true, + common.HexToHash("0x507f797a5a0241aae79efa3c75f66b027f8259c44bb40054f461fe8b35d2aff9"): true, + common.HexToHash("0x88b618eb78cd297dea3d1841a7c54422b6e985a3a3906d5ada83229bc3db1c28"): true, + common.HexToHash("0x07c21ac0ba4dfb48aad9e245d18d2fb8196e8114e5ba820d891048c7d7f5a04d"): true, + common.HexToHash("0xc164edbc9dce3f96ec511d0a0cc3625533941140067d805d1f4dbe9b590ad90e"): true, + common.HexToHash("0x0b01480b483b1f84e72b1aa0e278abc6fa6dfc8515bcf2b82dbbed3432d3b887"): true, + common.HexToHash("0xf04f934fb60aa619f28af790b67edf0c957a17d95a6bd85c2c3cbdecc887af74"): true, + common.HexToHash("0x023477b55f2221e54549676797a52450d28981bdd821e0e9988a90832ffb148f"): true, + common.HexToHash("0x680a8bfee228865c25976c033424cba1ff658159e7e2c3d4ba95d044e40c07d6"): true, + common.HexToHash("0xf8580e0cbf970313c6f878b015a7f68bb3a191ed4679f31c96707a778764b29a"): true, + common.HexToHash("0xc63131ecdb6d20e497c89ad2a8dacd73845718436d5c3e1482432a3601e686db"): true, + common.HexToHash("0xfdfa11a1e35c6d6d851f922a3d471db45bd6b0d300de11d0467843905ce8e6ea"): true, + common.HexToHash("0xe63376237e76e93332a60e913359f87b4980505a8dd8f7eb6e17a7080a22ce51"): true, + common.HexToHash("0xb424ae2ea1752d8dd01bd67d0ab592bc4b357100accd9cc5ea776d778a014801"): true, + common.HexToHash("0x9e01e32ef6d65e18cb67c4e0cdbf006dacf9d8a09bb6f29ee7b0ac42379b6541"): true, + common.HexToHash("0x85a81be0261c8649c8c8c95a93f9750af10de59688f2e92746881449a4476458"): true, + common.HexToHash("0x1b2e51ba61f6963daa8f6676310dc02aadf3bb61a7dfe17dd5a834b184097349"): true, + common.HexToHash("0xc32f81e09adfb6466e67d412f8bc6efde6c3e2934ed219027a4aea6a58d6d3b2"): true, + common.HexToHash("0xbd998f21616aa2292e0755d0e39d460b00353b54e875a35025fd82db2151a2e3"): true, + common.HexToHash("0xd7827725ce17738a9dfa88a70d5b36273a0625cb497e8b9270225d2c0456284c"): true, + common.HexToHash("0x0e956dc9a74b595256220bbca0449887dc9065f097ed365f60e5cf4893ab9374"): true, + common.HexToHash("0x3471b0bf1c6b14741766b8a6b0fc60ade6d8b2d3003284525749f9cda250abce"): true, + common.HexToHash("0x004282d6f25f00033f2574a7a6c9d010ffeeb9b4d2f31468fcf40969bd328501"): true, + common.HexToHash("0x5632b1e8adf1a9425db6d9e2eda0b56b4e882920f1c26a0d2557d6ac911bf3c4"): true, + common.HexToHash("0xadfc3645ed8f97bf72907f3a534be5668e0a71ea22c5b1539230d3817856c878"): true, + common.HexToHash("0x7d1838da0326c08e1c158febcc781634658790ff2f32939b84653eb09c24977b"): true, + common.HexToHash("0x755b17b1a6108106ff84a47055d7932d5aa8646e208b32fd1c9995d2e478a4a4"): true, + common.HexToHash("0x2b1b4b323d88c370f7ef0269851f564d2b5efc8265e0b4ee6719a5f60f6fa549"): true, + common.HexToHash("0xcd26ff3943c0adf6f2c47cb1bb5065bcead643af201275459d49ae47dac9b161"): true, + common.HexToHash("0xc7305d529707cca4870f13e6aa51c2a352ff1625f77825e2a034532776d1aa02"): true, + common.HexToHash("0xd2cdc58715d2e088f14265682dc5db3ba42c34f6f6ed1d75bceeed81f7c735cd"): true, + common.HexToHash("0xdfce24730ce78960c693222e4f4e7a400a901a3cd5533c279a24a33e7feb704e"): true, + common.HexToHash("0xa67020205de4d5c31d0bd5caf6f316572479050f5936804d566d2c345f849d58"): true, + common.HexToHash("0x84f073e589c6a68cd7fd9bc49c1c609a54ecf034eec06fedb74ef192653b50b5"): true, + common.HexToHash("0x35805954189d6dab6a7926f69d2c8a4238f9e34d25a5b7014ede771b088146d0"): true, + common.HexToHash("0x859375ae7d2c64e624e895e8950ed6074a1989b73c0d49ad25276fd26eeeafb6"): true, + common.HexToHash("0x29db63b3cd6881f9c2cf30582d7d7e06be48e071b10a13607abd25316f96b6a3"): true, + common.HexToHash("0x406afcb86da414d56a216344a1809af19b64fe712ea9300b99ba317e5701bf0c"): true, + common.HexToHash("0x77866f561647be2e06dd5a10dabe4871d7e173f880d7e8267a7264c398e99dca"): true, + common.HexToHash("0xc1b79da5e3fbd33cca2dd10e087c2b15989aaa9a0657d143b12141e4e30f0f00"): true, + common.HexToHash("0x3217d05e53712662ef9fcd4adab9d2f7556d63a1b2c303585eebf94187ce27d3"): true, + common.HexToHash("0xb6d69cfae2c524defffa23b2a732f095195a366e3a74b039830582b1ae44a63b"): true, + common.HexToHash("0x1b4a37ceb090099e1830d172eefa55d3b92da5d3a761f3e7b32a814560e59fea"): true, + common.HexToHash("0xda4be59fe85feace1d880b1b8cfaa67416e13eaa6c12d07653bbb9a6cf34b4c0"): true, + common.HexToHash("0x2f648046d56969e02d1af40aec0be0785f4ffd6ad28a3f234e59436dcccc7b36"): true, + common.HexToHash("0x4f5fd5310197c296a4d2394ba852cc3eae288e5e5f382a65db01e5e7aadc6d46"): true, + common.HexToHash("0x6539e25a6a6270437dd5764f42c122575c3c35c2ea89ead2b749933f8fba47f2"): true, + common.HexToHash("0xc8bdf93808fc0abba56e2188b57e80fbce71e5f18b1e051ac70fe43d7769ac6e"): true, + common.HexToHash("0xa02fb0efaf89990aef17671f5afe5e742144789da041321eb7dec16d07b88f57"): true, + common.HexToHash("0x72e6dc054cd1d1a5f5e6dcb5a13a93cdcfc5c536ae8278733d5d515215ae826d"): true, + common.HexToHash("0xd37fcbc456a9806f349562267fc7b42fc1118e4b349b679a77890dfdaa620a8a"): true, + common.HexToHash("0xc7237b98a0e986f0dd90ee4761f6b14d80323015fadc725c3478faa4d4ce2acc"): true, + common.HexToHash("0xb60d605bab398d7f0299d425cd8883a0d0f6ace6881959eca1d08c15b1176cf2"): true, + common.HexToHash("0x05d7a1b8f7e3d48a53a810d9bc1bd1803149bf0bbec3c0dd1f1a7cf54f89b712"): true, + common.HexToHash("0x2f2c3e7dd45a8d78b3cded15dbc369e2ce99244ba2887476524c4b1495b271a1"): true, + common.HexToHash("0xd91510427b33f2e0ddd4b72b9278cd8dabfd8ed29398f745d70d6b2c8abe16b7"): true, + common.HexToHash("0xe573a4f968a2ba23e5dd9b5a40a6fee5f74831f4874a35fb0a0e519f40c64cc7"): true, + common.HexToHash("0xace7fb403b3769a497cc26bf8856b7dcbb7fc757382681458acc386a463047c3"): true, + common.HexToHash("0x9980084decfc8fe450b84fd43c31fbd5a367cb208bb215f66cb15462a877af44"): true, + common.HexToHash("0x473e57e8babbf3bc4ab7f543f16ea34fe69ca75ae267602516ce07cda4d65bea"): true, + common.HexToHash("0xbc013c91e89024e52fe9e9104bb1a31ddf186b8397745745f5ab250d0986a4e7"): true, + common.HexToHash("0x577180d28127d6c8e123cc5829525a70d18afda977ab6181fb1f9178dc57f21b"): true, + common.HexToHash("0x000cf7d6585ad32a8db02ef2869dc67914f745a3061a3c40cac6e604f6eee9dc"): true, + common.HexToHash("0x9c5ac60da61b31bebb5307223006214297fe6ad5a8eb7744e3ee31b5f974aa3b"): true, + common.HexToHash("0xd511db9b964583dec6cc46f8f6166a2764113f008f0d70e67a50427928398c90"): true, + common.HexToHash("0xc06b9f2f7f2298dc878f914a22861346053802979d4f37b20e0f7f8a369ff87a"): true, + common.HexToHash("0xff26dc697b6bf976960cedfe1d013512532a73254a498ada7eda5bb483d874d4"): true, + common.HexToHash("0x96ca1773d3d7ad6a1843a0ff73711b3d78167ead405a3395f20f600e6c1d4533"): true, + common.HexToHash("0x8e9ab710f4e5a22db424fcf59b1a3fcd3a678b739834ee2c9408df638cdedd06"): true, + common.HexToHash("0x29bd4d9fc48a142bb1832cbf0a0fcdf445d0f602e442235fb925159dee92b446"): true, + common.HexToHash("0xd2e687bd670a9c78fc7541bc901c71f8ff9d54c0f79e8adb8adea42d812ea69c"): true, + common.HexToHash("0x7dbf7a8d5352e2ff9230833df214d3e61257b19c9e7402f8e5ae44afbc026daf"): true, + common.HexToHash("0x100d1827eb16346dff4479f04038e04d2ddbeae7c75835e92a522f3b238789be"): true, + common.HexToHash("0x1c99b305447fc4a8e85a10566ad0071b88c6086b1eb45322c2124d2fb690a50b"): true, + common.HexToHash("0xfd4ddd4544af3801ea2739601aadbea08018fecc678c7a704c0316b5b3d60672"): true, + common.HexToHash("0x1e9c72a81952933892b4b3e3ac8f43c4d645e7caf7c31f14815187600d39c9a2"): true, + common.HexToHash("0x35bd95d8a39416bf1e8fb42b9c10e38d38c46c8fadc5075f8d2c6d9c17551078"): true, + common.HexToHash("0xfecc0b072dd4ceb2afb35dec752e4f72445cb0b848038230b4020514b3124259"): true, + common.HexToHash("0x6db747ee8905c9493b983a744f60b5fcaaca16223cf0cfbc07642262fd43a509"): true, + common.HexToHash("0x0eb790b6eb8cc2cf7a25bd04b6d05a0f22c780f5981efb5f077d096ba1d41894"): true, + common.HexToHash("0x03c5284021433b36444a95f4118e0a8d49a898004dd1b41409ec14ea4cb7f89b"): true, + common.HexToHash("0x523b13ef04e2f7889e42b2d3b22bd102404d6dee2f52928158d7990b9d92dda6"): true, + common.HexToHash("0x24b32b14998f2446bcaff305da38f667266a7f30e2ebb4b562bb57f954c20ff0"): true, + common.HexToHash("0xa9bdd3e1d6dc54a3132f35b9ed69d3cbf84895086ef6d6f44867da3bbfd35ff0"): true, + common.HexToHash("0x5010229ec3bd2e4eef8562a75ae0d5673e80e0e80d192f8e7d5d54faa9d6915f"): true, + common.HexToHash("0xa741bfa9b2743242847c53a96a6baa65bc9161ec9da9c4afa3070a07db020941"): true, + common.HexToHash("0xc3b282d6a18d8e9d7ff72abafda4c8d2ba8664e17c322a7efd293d12e2b39b06"): true, + common.HexToHash("0x5234ac098c08c641629ca3edf91d42a8c4ebd60952c25844004599f48476f041"): true, + common.HexToHash("0x5690d6ce3a3e198048638c65719ea3012cb8caa85d3532030228e6ff78abc5ec"): true, + common.HexToHash("0x2f043cac0a6924dc142ef2d9fd7d3cbf6e71f28cf861af67d08aada0335700d4"): true, + common.HexToHash("0x8eb2ed6d0e9991da91d2e3d844602efeeb0c11faabd0a7d20af97a44bc6c6d3a"): true, + common.HexToHash("0xaf6042fc391064bc34e59b352f526ac0db86592893367a823e51f319e2c6d090"): true, + common.HexToHash("0x802ab4c771ee677cdf23fc6544d4239d97eee9fcf8b939c10b20b33b8a78883c"): true, + common.HexToHash("0xa26b67c68c5727f2747995cc4b16055d442a9375d58a4094df9b9b48f8485e80"): true, + common.HexToHash("0x09f6d6280372bdd8796c135dd5d74fd3002cdfb56da8ed4bbc70e911b8130186"): true, + common.HexToHash("0x4a288470b30ba9e851d9d9ae347eaff996eee7209f3e6db6b042be501c3af5bf"): true, + common.HexToHash("0x8ef8e709b18a84b550da15423a78dc43eb4f5a12c2722b61f5f38ed1c7b0a3e2"): true, + common.HexToHash("0xea399e9981698d1c76738ed4fb74e16f022908719a55d89bd50a4bc0cb4c08b8"): true, + common.HexToHash("0xb05e6e0f900bebfc4c292ca13b12b4840cd2a54008a2e569650a667571623d81"): true, + common.HexToHash("0x26dc7cb035cf36a5a5f6edfe91a26706b15d794f646a5e5abe9c2b7761b6b620"): true, + common.HexToHash("0x652cac6900f2a4855131c4ad6d93355bed8f08745c7401ce9536c7a616a17d2d"): true, + common.HexToHash("0x2edf511075bd8152ecec09612927d90e5e8f88b9794f279dcc0ec5e492d73abd"): true, + common.HexToHash("0x05217168554130bfafd3ca86e8d22450bf7b769d59c2f17effaaf29b00826d0a"): true, + common.HexToHash("0x627097a07f5cfdaa9062d211d9a095648eb583c79cf8f707575a9c7315559d8f"): true, + common.HexToHash("0xe153c3851a435f405fe43ae255a7e9ebd4c25503c0c9f65b45019c2be24bc624"): true, + common.HexToHash("0x7e9dec971726b5c00d6a1b7bd122dd61c473fcc0f9b132e84833afb97655f7ea"): true, + common.HexToHash("0xbb1425b1b1697b248cb32cee757108a43261e4d06d5ac81b0e1e4f445947f314"): true, + common.HexToHash("0xf93323c2db911337465226088ae52e74bd1c2b90bccb27466f29f96fe99f445a"): true, + common.HexToHash("0xdc6c51e3923b385176e255a88e2eb3c0b95b2ecc59224a99e67cd055d6861122"): true, + common.HexToHash("0x056e84811a377be51fbea98faf3938ab74f3deb6e4ddaa01344dbb90fe632fde"): true, + common.HexToHash("0xa90587720a9f44923e4aa24bd0b29086e9ba0ba58aea1bb060feb0322bb87b08"): true, + common.HexToHash("0xd6ff15c842bde6e21505276edd9b9c2e66b63a6d26ae267ced1a07a6148a7c33"): true, + common.HexToHash("0xaaeb275147e64f8a4963f41f6223bad488ef89e8895fd82471ad54a9ed5088d8"): true, + common.HexToHash("0xac0ada9250bec445cfe082cc6bc0159f4572f5b4d388a508e1dda9d175151d5c"): true, + common.HexToHash("0x8d4767bb154199a6dfc610a558f86a3a5d82fa11caeac9903b445d87e9a94558"): true, + common.HexToHash("0x2e40322fd5d17ab15b53e7ca9f7ca3fb2640213a99bde680ae9fd5e7c8490e22"): true, + common.HexToHash("0xda4b0eb3e9571970477fc98620549cafde1fd9e3c8b01420702b279ec2c4f3d7"): true, + common.HexToHash("0x09b425a912d5f1273ce6aef4c0161b11eb17c524a290e9196fc6dc00723b3a6b"): true, + common.HexToHash("0x603c96761d16c1b2dd8dc5d7c3caa103c8ff07cd692e2df95f5be9cabc7e3b61"): true, + common.HexToHash("0x989633f533f764f772f6f49c29487a542ee7a84240b6099c1768d30c5565946c"): true, + common.HexToHash("0x1dd62903786360a68b5868f187fa2f48780c94ed00d9e80989bdacbc8a55291f"): true, + common.HexToHash("0xcef8ec18539b3d9c5b9db925f54d06e01d99e3d139c0615bade3db7eada86976"): true, + common.HexToHash("0xb385beb2c5882094efad817bfdb291af378a16366a249b2ffb17ee2c82f8224c"): true, + common.HexToHash("0x000cc1623e8a91f5925c5f0cd1525e75dd803a749760574e843db11d97d566d1"): true, + common.HexToHash("0x9ea89f98029e5913c7a947d29509ff20c915636b0e6f260df4ba32f213604f81"): true, + common.HexToHash("0xaf9bcb77c196cd477b7587868cce1b880e9ec2500df39ed583a992dc28bab29d"): true, + common.HexToHash("0xd2cf6b8d7dd91a12a34a7e604e1e0ce189ae144e7324750e6c4f12c23944dfe8"): true, + common.HexToHash("0x1916a21ec56640121c665acac138b0e44c4fdb60f022e005fe74ae1ec23d2639"): true, + common.HexToHash("0x087e85bb9d85f05e5c657f71f99e75c4c1f544ab8f3f6d40015dea8c8f3bffb8"): true, + common.HexToHash("0x45115a131ded66db3b665315d11f5f092df958676a903a263113be189ac5693c"): true, + common.HexToHash("0x83605785e2bef6ff716d09ac77b6fa02aefa336ec1e025ef6845684cd6f36091"): true, + common.HexToHash("0x175ee005165152af2e7e4cc4c8e1f41ed74d960416c4467e8646d11c0a914d8e"): true, + common.HexToHash("0xdaea97bc42fb2d8f6b232eed49cf75ed903f0ff34f9a09327cb3e76d84eca212"): true, + common.HexToHash("0x3bfe9bb22272752470f6a5b05c993a608c0f38bc335e7ee89a638d11ef976c2a"): true, + common.HexToHash("0xd254ab28f38431cec740105678310ad75f31193d18e79b699f8c68ab187254b3"): true, + common.HexToHash("0x1e477894f56bcc6a7ae12b097f0e0d470d237af87bcbb742a8ce40d0e7c510a9"): true, + common.HexToHash("0x3006d54eec05354125d06c4c102386ec330ef88cbd38183010e75f30a02659c5"): true, + common.HexToHash("0x531cb33b4592c8f4a752943b527070139f4b3c753f32a523fba12ee11b11bcde"): true, + common.HexToHash("0x08fd42c3160e5fabf1ec6c6162cbcdcbda193527f3e91a0fd01bf93e188cde9d"): true, + common.HexToHash("0xd235f09c355b979beb85b392d8a37fb745f7f8d68270c9ed40dfe516410a9131"): true, + common.HexToHash("0xaf102a4204a6f556c0bf2b940f245c26b27a71ebd00eec7bf2ddbba2dc730442"): true, + common.HexToHash("0x015d1eedc6bbaee82bd9715ae96d00ec1f71efaa45ba74c4c55f1d99715539d2"): true, + common.HexToHash("0xec5df676f2054d8532dca88cd3a4af7b553c23c6704cc2f93bc289cdf54ebbc5"): true, + common.HexToHash("0x2645e43ff48f3efea2fb7d3aef159798d56b243639ee99ff53fad0da44865def"): true, + common.HexToHash("0x354a493b8a4c9fed18f2c99ee836ba881eb327d16d07b28dc24adca4d364e366"): true, + common.HexToHash("0xc4464d30a3705110435b3fad73c9abb4233cf34f240d5022719e0d5b818cdd24"): true, + common.HexToHash("0xca9f1235614e37a14fe168cbf6dfc4fc24740a4b45f164c342600b51c126f1e3"): true, + common.HexToHash("0xf3f6038882906fa48af23b28b8b150f51d2443ff338fabe99304d5e6b9aa0b5b"): true, + common.HexToHash("0xd35b9a534b221e7f066448b2712cd8bc448b55f33528c150ea1eec9ed89c8fcc"): true, + common.HexToHash("0x16f4b59f995541ad3d21cabd9f2a8bbcf95a2963df5838e0b58c3b7b013645ed"): true, + common.HexToHash("0xa80114500a7718b29a4bdc7281a90f5a5189442daaba0bb657e773293c47ee63"): true, + common.HexToHash("0x3fbaadabccf2c86537b57dc7b0247b8790778d9342147ac9c1537360d4c6244f"): true, + common.HexToHash("0x059496d56846ff6e84d1277431992d97f9a2aaf8088064005275a198fc90b12d"): true, + common.HexToHash("0xc8f63b292108bf195eeec139c9bb88f7237db73e8b16a5d0618b0a18657bbdab"): true, + common.HexToHash("0xb995a615cfa39d423f0fc218a90da045dbbceebe8ac0deb0ebe59f409d9870f5"): true, + common.HexToHash("0x3de63ce158811de64850d2b92f02637fa17962a9d0d43d3b210a645d15736b2f"): true, + common.HexToHash("0x156fa1784d955d2e1e2214f3d4deef8ff17e6ab4792cc9593813fd1abcffbcb3"): true, + common.HexToHash("0xa6838b9f4115fd6d64024f6ecde2ae20bbbe6ce18b6bde54d7598dfd7b10b4d7"): true, + common.HexToHash("0x045c2a96c3dce12447f17562d0a5fe38b336a19109d83d6dc2af2d63c8c29803"): true, + common.HexToHash("0x5f9c50ca28a4c1d9bc1236c4b94675ad11b1469415c575b4b17527e7ff8a7684"): true, + common.HexToHash("0xd088ba1921b16a45224552973f9fb455e7f66e838b50261c8aa051db5f40359d"): true, + common.HexToHash("0x68cdeee78557d68a5567625e92939d6adfe43d3cb70245fb680561a18b5d0b08"): true, + common.HexToHash("0x4d1d6162a08a50b61bfc826d6ddeb530382c56435a237e4a2025acf43869e286"): true, + common.HexToHash("0x8647f190987b2ff97980dd90452dc8174d666d635756fd41abf1d1aec639bb2d"): true, + common.HexToHash("0x92ee69c01906454b00c40309a6b094197e7e759aec3628c51eca810901ea7256"): true, + common.HexToHash("0x20506e7e8ede9ac89d847ad3935abf1f5bf2a21f792e34a14f96ee24bc0cf731"): true, + common.HexToHash("0x3df8fe2a4300872cb811b798012c4a2ca61e7f77c5f13bd8333244e8cd0f6eff"): true, + common.HexToHash("0x2d84d2550cdcb8042cfe69ce27167543269ce65f1d56f0cb71d36d23341eb3d2"): true, + common.HexToHash("0x44f17dd10c610a7cda82110ce3cb255514c87de8c29f13396c50cdeeea99f431"): true, + common.HexToHash("0x15613cfbbbe4efdf9f0ce61a67f81142461dc63055e4fd4ebe587497c2cced00"): true, + common.HexToHash("0x35734a33443d44c3203ab39d5ced86c6ce513e71e8a7c493a6b928e1d122b184"): true, + common.HexToHash("0x37005438ef2f3d088521dce78636468c3970e31ec07cb738efbde0e91305c048"): true, + common.HexToHash("0x4ac6e6752fc9fe5b22146eb3396bb2aa288a509e709f2cdfa5bd7c9968ae9aee"): true, + common.HexToHash("0x0f6c95e26c77a876c52cc5260807623d8bbc1f686c74fce73f1154e1a14a959a"): true, + common.HexToHash("0xd3bf6a3d5848180caaa9ee4ed9a93f8b00bf40e2401be80137f3c7e916218243"): true, + common.HexToHash("0x9c3ae06776a232e3fabf6069a66c0907b1c7627a4bbc5ee6a23074c3a842c6b7"): true, + common.HexToHash("0x96015b113da43173066bd5e742d1a27dd1e24aef33eacac165b0c96d6086f4f2"): true, + common.HexToHash("0x5f3dac93a1aba8d961b3d01a7ac5b13fee1b8044b05a9a61dc5631d648aa02b8"): true, + common.HexToHash("0x9c483129e965b084593b48436c89d2318abe7b718e9e6842c831b3426521f9c4"): true, + common.HexToHash("0xaaf725ef83335d7a72d9337c92119fca83cf3654c01f58c85a07dff30d66f7fc"): true, + common.HexToHash("0xe00c5758f221de0c9beadafe7abb74ae8e8f55a166506ef468bbc668449fbdcf"): true, + common.HexToHash("0x32088e03218ff68c99ba9f731f889aadc044a17b930136b4110c3f1a49d78ade"): true, + common.HexToHash("0xc427f2a980029b951a967ad0a5b3d1372b7f01bf18e34e659469dab58e4ce069"): true, + common.HexToHash("0x8963d73988720fc60aea6b1b296076643016ff20f61df4cf0324a14bd48b1cbc"): true, + common.HexToHash("0xb18ab77d59e7c5bc2d46f4331b9e95a5b940b0a4a0fe32b50846e7d502d0986b"): true, + common.HexToHash("0x2ac0a7c76bfd4c900180ae116930879ce2ba3f9817a72371aa01618e389f7a1e"): true, + common.HexToHash("0x4e2ca069439cd565b37e8fb58fd6af516eb50d7ae540e047c6588422d98cef1f"): true, + common.HexToHash("0xf5d77a4fc418ab249a4cd61183e14c08e2425fa9adabe6a87439b53972a2908d"): true, + common.HexToHash("0x5e63044dd430018524ce2ca0208815294bc3cff0d12088b6acd9ece4725e2ee9"): true, + common.HexToHash("0x1135415e815d3dec34022883d6f8e7f836d9e77945121432fd4e67cca82e7ca8"): true, + common.HexToHash("0x382901b061cd662e240faddcfb4abbff19b6f54819adfc9344d9aca758cfa7b9"): true, + common.HexToHash("0x3404b3d2c98b4ed69f2b98b3d73c8e9765b323068ce355c0aa73adb975c1c49b"): true, + common.HexToHash("0x678be222c165e2b672e91000c4cc50cac1c555a14aaada630b9134e64a7a768d"): true, + common.HexToHash("0x198a6c7e09aa03f498f68b5750e1e8dcf6565f640b2bfeed91424857a70ab805"): true, + common.HexToHash("0x1b18c2abd53dfbdea6696513363ce26adda3c06cf7f0a27870933ea8b0e7fb78"): true, + common.HexToHash("0xab182cbd7db8d3496a75ad91d7b025253f48941b54e31097ab0af5b8e65915fa"): true, + common.HexToHash("0x96a2a20ac2eef3b135d9ab90086ce017956cc00413c567dd46a68ad363470132"): true, + common.HexToHash("0xa899686dd158f4950ece28ac7ac405d6399c1e8cda3d5572d52767ef133853ed"): true, + common.HexToHash("0x994e8c716a041bfc88bb71c92b16acd1ddf3ec5683f0db614313f5a93068e6da"): true, + common.HexToHash("0x3a0a93e9ed3b128911d28f20fecd372c733d9e0ee1547b3c5d3b3ca1a797bafe"): true, + common.HexToHash("0xf709f0d297d1cff10c47b3a3c9a298ac14c12b8ca47de736845e524a93c9e318"): true, + common.HexToHash("0x2b168c2e7a7eaf03fab8c4d689c0d18ccd617b3cca8689e4533826cc1e1d5ba4"): true, + common.HexToHash("0xe8b43d98733b7faac6e52651ca0d9eb0e663705640d513c59cbdd77cd5abd417"): true, + common.HexToHash("0x0889553a67016ba2463783e13577e440f3e33be65f6dd4ed5379a46e517be7c6"): true, + common.HexToHash("0x78e370c4e49f28c4da626ef03ed561f3fa677ad9392b24226a1795b73dfd45c9"): true, + common.HexToHash("0xca8740225db897dd06d4e2c95b5c2fc7c332052df44d5371035d548764b02aac"): true, + common.HexToHash("0x9a0cf515316dc9b6f41afc971e49b5aa45054c9f23abb7f7a4f0e6e8b57c28d1"): true, + common.HexToHash("0x66582f180039151029030e85088d31c5efa2bde1688834083daca97b38bb3665"): true, + common.HexToHash("0x18482d5486e56a0079699e38eeba2c2919bf6ed0e4b22776b26f621b403ebace"): true, + common.HexToHash("0x090cc58ba9e86353fa378383d4658dbb9dc661100acd5ad7579bc24fb4626c33"): true, + common.HexToHash("0x182136ec59f8a6a325fc87cb53e1f9abfc2de407e69d7054cf0bc4ba6747a67b"): true, + common.HexToHash("0x5faf4ddc240f3413c05abb361647d9ffc1f53bdd777f550b7caf6dc3a9e17852"): true, + common.HexToHash("0x5d9fe438d967ff6794d31d3ace55a22aec548cdc4fe1d1840e30412b0012d970"): true, + common.HexToHash("0xdec1888f593af9799c2848f9e8e0b32fb5adfc9e65b4e8f0a76c027864d512b1"): true, + common.HexToHash("0xc3578b2adba479fa38d3dbbb547f84081816a95a96882061e4c882906ab6b228"): true, + common.HexToHash("0x9e3b65710f178dbdb1a12c65a40e8df3a4579917526cefe6910e67f946a18417"): true, + common.HexToHash("0xefdc6f4192273e3d784965fc4a3881bdac2885049252451868376b27ea503b9a"): true, + common.HexToHash("0x99888f37d21feee8dec61a5954873fece1f59824eb2e07cc01f1b55ffcf0cad6"): true, + common.HexToHash("0x227f7d7208c3a3f48ff24a2da46ae321c68b67879aa23ea14ac5fe1df767e5a3"): true, + common.HexToHash("0x57d7d568e2b47e9fcfa1a16c02dd644168d5ca01e04e935d0037c873071ba08f"): true, + common.HexToHash("0x03fc9c7923ecba72877828b8d65da5a4758725f3c17cb819c9b009ce11a6884e"): true, + common.HexToHash("0x2e7fdd85c41d99e7702f675c769c0656864ae2003a3dc561ec1dfaa9f3448cb8"): true, + common.HexToHash("0x8432034e8dcbb8fee446eb865253b97d2e201191a2283a0bb29cae85ad127ee3"): true, + common.HexToHash("0xbd12802983d465293a28b2484f8fd17f516e3258ad7acd4c2e58109870419781"): true, + common.HexToHash("0xe71818c1737d53c0ff762461a0d4a11fbbdbbd681e11ec36473e05cb8e22faa3"): true, + common.HexToHash("0x0fddb9c73c21b1ed0f3f54b4fc2a0c6cd4c2704285824556cc4615fa75ad18a5"): true, + common.HexToHash("0xf501117b6e660da6b7813903dd2c3e64b73e80bcbeb6561df9cff1a96562fcba"): true, + common.HexToHash("0xde32477eebff0aa143140ad3078bba4bf0475aec3f1338b6b048a0c9690239c2"): true, + common.HexToHash("0x697943fb3b0d485450f2f005e5cce1df3fe95522bacc9de41fb5a1474411861c"): true, + common.HexToHash("0x622d03bbb11559fc1cb4ff96ba8e044832949b4641c2062df72c1d6354f869e1"): true, + common.HexToHash("0xdc302ebaeed46aee16674b717c6d8316df47840d6e5c9eadeb0427b83ca053cc"): true, + common.HexToHash("0x8c51db96b29fc68ba6d203a01bcb3f3c6285797fb08dd10262919437116ea5c9"): true, + common.HexToHash("0xda219d8139b7c4faf4ce29dbd398abc1b5015d86f3f8194c4f635ce232c2625a"): true, + common.HexToHash("0x6108d2f822cab1f0a39425322b646dd05c46d0d1b9f2ffb4b766945209b0d15b"): true, + common.HexToHash("0x53cc637748834d2dfabac8f6fca982b612a9a7d4501110d02527b7aceadd1446"): true, + common.HexToHash("0xf2384bbc9e2043432cc9756453f4b4f2d53b7bcb458228391d1fcb28f4867566"): true, + common.HexToHash("0x92c5b28e878ac275b35ce41d77412e117ec38004939296ff5b0e285a91fe2d5a"): true, + common.HexToHash("0x26f94640f7cda7ee88fb1925652452f54b54e3ed430c4894f288f8663cb399c1"): true, + common.HexToHash("0x9bca36b48973e747cd4fabf60020bfc032be9f3eae68d19cdb112febff7c78b9"): true, + common.HexToHash("0xa442f6b24dda5e7b0583e9ad8d9efd4826171a4522bfd471a68e2e72081b3092"): true, + common.HexToHash("0x2533c6fa107a41596452f64094b6d795181856d2b68928c712cf3b4390477fef"): true, + common.HexToHash("0xd0a3f18c1d9940fc0b728521b3d22dd33ead99845471723120171a95c3b325a5"): true, + common.HexToHash("0xac83bf70881a062c7a83ad500a37e28f73739c043d55d31b0668e452a8bd5f62"): true, + common.HexToHash("0x34825ad0e03070a6f7023c5ef71a86b1fd53d9f2febb9fb5ce31deae58da5765"): true, + common.HexToHash("0x05763eb0f902226e9c9155b8c9a09d14a71b270e068b942241d2272c6272a429"): true, + common.HexToHash("0x0fe2060a70a05e6e22d6bdd02fbc7ce5a8cfb37f4e43a4e54bd8f0a93ea979d9"): true, + common.HexToHash("0x90be79f1d4184559173e002b348bdcb0ed2bd9a3034ce675fb683d8941a898ac"): true, + common.HexToHash("0xfdb74ef62d717b4cab72be4202bffbb4bcfd90c53f30b317626d6a61dd104530"): true, + common.HexToHash("0x3677657b4effb5f4908269d6dced31a08817bb48725e3212f04d3223e480b39e"): true, + common.HexToHash("0x0e9600816bd16599ae9dfcf75329057f0d9a06f72f152bdf3185d82d49a4647d"): true, + common.HexToHash("0x3878f9399561e39dc27decbd50fcfbff9ea08f4eb512025604b8c006b9afbade"): true, + common.HexToHash("0x3bbb3562c32954e5ff952e0749c202aaa581b8d1f21c532e654ff73f91b49088"): true, + common.HexToHash("0xd09b28727f40a6421ecc0a798cf3d54379220768e5d242961288b220619e2e60"): true, + common.HexToHash("0xcc6387c279f055c331cf3aaa0483a6090669e3270d0985d2ff9dcf2035f25d41"): true, + common.HexToHash("0x0ef272d6cd98e2bbf4e6a5a3270568ca880f4c33b8055bfc828441dfe71b16b5"): true, + common.HexToHash("0x653c2ad2ba7b3c58770e8a5a37847d7794698de031541218b2c9151bcda35e98"): true, + common.HexToHash("0x9903d9d3f91c2adaf703264fe7caeaffc2394660a5eaf597599a41ad76bca37a"): true, + common.HexToHash("0x92a9b61b773c71f0d634cc141eaf0a757be7fb4e749ec91a7b1b062cb2e695b1"): true, + common.HexToHash("0x2f211613a523a7282a04195ebb3a3b57b29fda8d8562e48bb7e912bc309226b3"): true, + common.HexToHash("0x9f1d669fe741240a58bbe6229d0aef46c62e8a57acbefd009ed70067681829c5"): true, + common.HexToHash("0x1fce2b7b376d61ca2e7b20472d07048211ace43b82b232e58d34f1e530d4911c"): true, + common.HexToHash("0xb37b2b1c5b0f5257813e0c1ca9783284ca186689e6ae27b7d5b9e111d05c8bfe"): true, + common.HexToHash("0xa12ba898662ded14f5693897f485ab03c96443a1b0d2da9f5de061e1c2e5124f"): true, + common.HexToHash("0x104bf97f79f6ecef64deb9b81db4456ba73f2f828656df95a6eba09b90ae0a45"): true, + common.HexToHash("0x43c8e876b9b1919ae8bb8e897d60fc202d127cb953a3a055e80e9ef396472a40"): true, + common.HexToHash("0x9892ccf455f7ac167d3eee8aa34de3b91641899992a0157e369217f90d691861"): true, + common.HexToHash("0x76ecb5c98ca2d03335e3fca7ba4671fd0b8a15093356cdb4e45ca16f2bff95c0"): true, + common.HexToHash("0xfc4c3f4e5ecb9be463c01dbc1752ffedc3a356159a624590e8156472fd9615aa"): true, + common.HexToHash("0x273ada0a6045a2c3eb33cf7c6a27532f2dbaea1dbc146c359d58dba7c5029f07"): true, + common.HexToHash("0x36387e01aed171853f6cd93b7849083e89c0cbfc016872432aff05f0dcbd3483"): true, + common.HexToHash("0x650443706212d93cb0e5d33b4dcc1c98fe10ec530a0dce13bf215e5bb9c0c506"): true, + common.HexToHash("0x544b184b4b4ea1dd2a31dec5a786ea3afe0dafde07cb2b06ccb7e182b18bbe99"): true, + common.HexToHash("0x0651a42a30ecbd52aed6813e5a7dd5825f5e23ca7c2b4be705c7ed17229343ac"): true, + common.HexToHash("0x5768b4b5c6e27ec04836ae7914f3827ad788dc0276eb2c33875335e8dd51cf7d"): true, + common.HexToHash("0x995ffb16ea75519f88da1fb0bc5d83d369c14c82f5187bf4800f8373b5770c30"): true, + common.HexToHash("0xef42ccffb402b4b6bd3bacbcc8a5fe9488aa2181c9cef3e29e0cb0476d50068e"): true, + common.HexToHash("0xbf9eac593140f0d9f2d99380ea3f03e62d61a5791f0d826e2c43c7249d7ebab2"): true, + common.HexToHash("0xdd5eef457c02d8365024c4ec48d90b36d729abc591229d0538cda7946f7da181"): true, + common.HexToHash("0xded053c002f3a12f01397b389177aa318f3e489fea3f138fce58e18c22646bdd"): true, + common.HexToHash("0xa7aac1fffb6a123cf46d95306efd430e539e4e8653e7f9b625a4ded50a1ceee8"): true, + common.HexToHash("0xe12760aa460ead6a42dd622a7996900249bd893785648e536a332a33a48f1703"): true, + common.HexToHash("0x52e32cabc5cee2660871c73e767c549781908ccbf52fa20a0a4bbe2efc97eead"): true, + common.HexToHash("0x6992145b5337b00e28974974bbe3687690eca5a4d17c66b334938b5ddc47f1c2"): true, + common.HexToHash("0xc6a15c04f6d01c00e14a8f3e6ec62853c19b57900de23c332105afb6a227fbc9"): true, + common.HexToHash("0x1df3b9581fb521aa84a1007b4a0c29821af0d82ccd6eee633b027241680bbc8e"): true, + common.HexToHash("0x2f37d13c81a49e9cfa751f149eac6f82e8651ade86ef4b1d8e87e2a62fb5291b"): true, + common.HexToHash("0x43ad4aaaf5e176d488ded0915c03460788b558010f0fd6e83219c1860b5c9e60"): true, + common.HexToHash("0x1340f2480f4038c63b10d1543980d4d950a5ffb499ec603d9c020ce02a812d6f"): true, + common.HexToHash("0xa6108530395e61c8a4d30a172292fc516f5251eedca91e9f4bc3c89e0e5b8c64"): true, + common.HexToHash("0xc0f402f2d0ab531b4160cf28722e45ecfa4a8ceb627701d6ed540234f00e42b6"): true, + common.HexToHash("0x879bfa30c0a40df0d7cc77952a920f3512d0ca51d0f17fe2e06eb622a78b6c8d"): true, + common.HexToHash("0x644cb542c4cb5800142007e8711a5ae89a6defd0f849b4ef261329065e485007"): true, + common.HexToHash("0xd06fa776b618d7b15f410b307122797dc44abd3b9a65f5997cb2825e09945547"): true, + common.HexToHash("0x245031efacda95254f74dfec15d150218e5e7b38148d0660e26dc6ca87bf6bd5"): true, + common.HexToHash("0xd72e0404ff965e63e1fecd3d974759c520aff4e3f27d64426167afa74d11b1c9"): true, + common.HexToHash("0x77ca60130ec9418a3881d16bf2b2b89de7216c4ea60787206f848b66a08a89ff"): true, + common.HexToHash("0xcfdc57320cfd8addef7d9124d59197be31a993c09ace8214067d2ec7d376d0fb"): true, + common.HexToHash("0xba072a8056346e2d7f8b5a3910267c0bcd4b39497f9b44c7db025285dbdeb510"): true, + common.HexToHash("0x889a74160f49e2720e96c4283a201483e54c0ab368c6da4238c027ae375e4421"): true, + common.HexToHash("0x1bc9c65af348a42f60c42a39b9251c0d75b3aae0efe3af3541da92e74a5f0713"): true, + common.HexToHash("0x72e49b3e9933f1e57454cb4cff75c37949145d9bfd14449b4a44fd5d215a7710"): true, + common.HexToHash("0xc012da74aef8d97e40a763f3a678412cced4527e6c8e9c992f88abce3e91eff0"): true, + common.HexToHash("0x198f002813f33ce8f9a236ea0eee6ce53be799ef44d4218e95d617ab4e676b0d"): true, + common.HexToHash("0xdcc6f24c756ae0e4473b01017d4dd38d5f99367921877f45d33fe0c17252bf42"): true, + common.HexToHash("0xdfddc60337796a867c15a3a9518915c5259305fa477a2499b3884eedab413450"): true, + common.HexToHash("0x3cbad129ab09dabca715f4d5802896e17adbfa46681d34b6f90913cf814254ee"): true, + common.HexToHash("0x44e3e3ee9386305f5669177df7d49f276aecea939253026fb803cb144da47582"): true, + common.HexToHash("0x1e414c2a1087f936a22c68cbce38fefdbfbd74e39cfb72624f0913ac0c5b37ef"): true, + common.HexToHash("0xafcce68f5cccc97e9fac886fba10a165411f02a0f16ce2909951c9394f46c1a9"): true, + common.HexToHash("0x0f2b42e92af0ae4b5a6a6f7d2f09ea7210ba334b11fcafcc1ea52c32766e9d22"): true, + common.HexToHash("0xc5f1249b4148961b7c5c8268ef30e2eb96ee0ef586857783bb779d635cbefee2"): true, + common.HexToHash("0x8804afa76ca66972d80cf1a7e87a81df61250e21a62e9d7b9bf37f258020cd39"): true, + common.HexToHash("0x4798b35521947383e56d01503e309771a199bc5b052d0a5d9ce691d46d292ab4"): true, + common.HexToHash("0xf2d6ccaf5de3170375a2203fd4b23bca066e80137e292019a9f44b7cb8fe23fc"): true, + common.HexToHash("0x09006ed5321e245f2e9135b334abe7270831bc98047e2ce2b82745f315545762"): true, + common.HexToHash("0x16f9518b1adbc885fdfcf20d5754961eac39c66044fdc7f0623fce16bbb08366"): true, + common.HexToHash("0x5f453ab8750c76648ce56b7d7d2ab3ead821bca846b0a6b94fa07876a6f40b01"): true, + common.HexToHash("0xaaf8a9321a510bd0fe0ea78c016337ed70db5866f346dcd8dd0da9d87a32aa26"): true, + common.HexToHash("0x23e4de8f375b67ec3d1a028770f375c9c5ab7ec7c196a907e20ca6adae5b23dd"): true, + common.HexToHash("0xaf6af5b95ec795c30da5c004ffe4cd29944e043054ae314323e52dc147639749"): true, + common.HexToHash("0x6602fb639b34b4badd2b45263cabb1350a936a339e4fd3ddbff5e526154bfa95"): true, + common.HexToHash("0xbf2ba9e42e69e46881f02b5c337901b568f1c46d98e21cdc040dd4e948927ef0"): true, + common.HexToHash("0xcb49f97f4cc53bb86819f2b535a17f63d1d539bb7b33e9a2d13dadfc74b186c2"): true, + common.HexToHash("0xc0da6d6f96e70e01f5c4d4ce4773a3dcbdae6489be5e2ed09ca5a0b7de5c8273"): true, + common.HexToHash("0x4cbd9cb60df8e8eff71a6302587f47f613fe7f71999c2ab156cf6b0e1e74466a"): true, + common.HexToHash("0x7cfb24456747dc3f1652894f1564093fe03ad3f8f58174ff0f86c08645ee8985"): true, + common.HexToHash("0xfc2be95cd9bef61b212b526388e750fdf1d020bd50cc60391520f26c8f21e841"): true, + common.HexToHash("0xa6d8260d3899af937c7c0ec479353cbae0b32bdabe7b62391610982e56a423f9"): true, + common.HexToHash("0x4d0492e552938615b0bf77fe6c6c8e3f23e0e40218234909213d2d1add62d251"): true, + common.HexToHash("0xbc1a053aded0b8c44f38f06a6fec6f80ebf6e459a62c4b39058c6015782591dd"): true, + common.HexToHash("0xabf54dd40202dc750f1eb1145e0de92be8e528333554b299f9423960b6dbc9c6"): true, + common.HexToHash("0x2d44e824c0bd85827a60c5b8b6c08a412e58d97305540bec135662d9b86c8e63"): true, + common.HexToHash("0xc00b882bd29518d2baadf07869c100db7e57aaf54f3053130154278d8c2bd202"): true, + common.HexToHash("0xa62d8a4e9386e2097a4467b351d07936017dbc8679c58acaead886e552a23ea8"): true, + common.HexToHash("0xdedd0445bddce4acc944c16522eca13af4c800a9bb70cbb7722a8c0d0d9b0172"): true, + common.HexToHash("0x5a62a727605f49e3cc685dccbfa99751d87bd164e36c29738881e52c3fea2e01"): true, + common.HexToHash("0xa7a9dbaa4efbc94acd34386451c8862af0a4b1c18e768372710ec2b95017f2a3"): true, + common.HexToHash("0x8c39a2d3314251edc71b18a731637b888d94b051d18a28b427efdc57e3ab2041"): true, + common.HexToHash("0xf28567ea001aa8a9da1410d2f71bca19d178b91f1cbe68363ef2c17c8ba753d7"): true, + common.HexToHash("0x5629ad57a56683b17018f5fe823d32f821ea96a055e0aaec867835cd54c1069f"): true, + common.HexToHash("0x92eca5346699397a3bb5cd4dafb6652f6d3bb1e1d8069b508394771df2b64bb7"): true, + common.HexToHash("0xd1e4c72facbf18dc7cd209133cbb56b4d35e8e1b202058ef8d48005b502137da"): true, + common.HexToHash("0x539f8a72947296d69c394c677284fd283646401c343eda3772b2813f4baf6083"): true, + common.HexToHash("0x2841509985f03d3d1a60d66aeaa26f3139b3cc7e0ce4dfe6a4ed5f1f1882d9ad"): true, + common.HexToHash("0x4b1ba07f38f926b3ce86e557e825d95bbcaa0725a9eb5be5fee0759e057d72b7"): true, + common.HexToHash("0xd872bd7b1d6e0741009b35680325762368c843f4c19699eaca9393b2a45f7b89"): true, + common.HexToHash("0x75ae0fb4be4b4149b531b2ac50ce3b6d381f06a6f53f1a27dc1dbe42cce79ed5"): true, + common.HexToHash("0x750303e591f76029006c3a658ba8690e0da80327bcd593f87b3c5690669bcd91"): true, + common.HexToHash("0x9dae87cb452e95d22d128e1af9d9bdae608c31201b7fcdecd9a2a47ac86b85ec"): true, + common.HexToHash("0xca3f7429508c123c4a105c148b64f51890debe671ba4c082c5b47a6883695d5f"): true, + common.HexToHash("0x26920a7ded8c05b3cef00501a4bd98f29a3109c295013caec11da04f8018ecdf"): true, + common.HexToHash("0xbdf56b4147bc6555a1c28199405c03e7d7a61a877efb9d72748c488063dfacba"): true, + common.HexToHash("0x9652eeb06d1a45d6805b8b37b58a80f82b3a760d7efa064f7747dcb024d20a38"): true, + common.HexToHash("0xafe42edcfad11a80d3fccdb1e839ec68a2d2c50c8ce6c5d76b1aa48605fdc000"): true, + common.HexToHash("0x76b69878b4dc0c6e115fc93527a457516c88d9a0e2949d7daa014686a68211ce"): true, + common.HexToHash("0xc21cb6aff45ef4fb7a731f77dcae72c466113669a8ce09863a6709376566c916"): true, + common.HexToHash("0x0fde3383c61f1c0345a48f70ed35dab9426b66fdd440635130ac82eec07fbf67"): true, + common.HexToHash("0x3fec6708d980636ff573f3e2320ba7f3006ce086a4c1d2ef9678caa91f7add3a"): true, + common.HexToHash("0x4fa06a131ef28331a3907e1212eb0cd64f0f5f75870b694b6ccfc783ad5951b0"): true, + common.HexToHash("0x972d075e0c3e9507b97395bd60b1da569655f454941d8ab5864ac98f3bbcbe9a"): true, + common.HexToHash("0x68827877a2dfc9b43d7c41c9d9c0b8c336e00ecd8056d61cf115f71539c687f2"): true, + common.HexToHash("0xb8d47bfd48b22f39cd05b2f8393039d3f533dc74a4a5eae63206535d3c4a12bb"): true, + common.HexToHash("0x67efb964c0127ad896f3348b4991dd21fafd07ee82026b7adf1c8be432ed94e2"): true, + common.HexToHash("0xbd2ec1981c13ec90632f6aab8e9c7b72d02b3ba5e14c11e8df4506cbab83eba7"): true, + common.HexToHash("0xa034695917a0d51a8aa275ec34e22aa57fb98f4c3a1e9169d96304e7167fc11b"): true, + common.HexToHash("0xc8da01841612357eae941afe2daee2b1da9b3cd134317047b8317aab253a1ee5"): true, + common.HexToHash("0x659dea8aa18dcc1517c645af6ec89a9a97cc5445636bfe649802675ca46c8938"): true, + common.HexToHash("0x5ad7c585fc70f31c303dc1a2054462e9c21cdb349034c371f6b55399175269a5"): true, + common.HexToHash("0x41e000fb5ca648e89c31ebb8adae604c769029c6b1f078eead5162d4dc89c49d"): true, + common.HexToHash("0x9d52facb666951a734e1bc2034b071608d3f1b25900e74a3241e39dff13b2632"): true, + common.HexToHash("0xaa1f570af9c3cc4f7696b126c85119386b60c6656e07ebbef1a18e7e1a658c46"): true, + common.HexToHash("0x3b9829ffc4bdf9af252c1a539456c22d7763dbf1ead7ff316281c5d67857b7bf"): true, + common.HexToHash("0xc048ef4eb48295ed1b0c79e58c02bf72de59b3d75c5ea876465d2943a00eb25d"): true, + common.HexToHash("0xfc55665cc0f0f841ad3598ce88e832e4c5672d8355fe3efab3297393cc34b59d"): true, + common.HexToHash("0xfdd9eb9d765c6f7228bda97894f93d6b8fdd3163372fdce3d387cc23c01cb594"): true, + common.HexToHash("0xba8bd7e716f7565bc517d06456a1cabcd8da9714524bb8691aed276efedc3884"): true, + common.HexToHash("0x7458413f8c63fc62e0258d52d3710aa9cc972b6ad812ca88ecc1211221389d59"): true, + common.HexToHash("0x08b65275503fad5a52eda2b5a0d9a326f060cef507461a92fb757f23b059f913"): true, + common.HexToHash("0x5d22646dbe793305077ba0339675acf7b135294e02f3b28d95940492aea0de8e"): true, + common.HexToHash("0x231d43dea11485a24fa8e3a1e28eb44906774432abe62703669ff67aa54340e5"): true, + common.HexToHash("0xc5c046101d1fa160d0cab1e1ac40576d9273434dd429f2d5ae5be2d552fb405c"): true, + common.HexToHash("0xa9886a15f5970b6873adecbf20a85d8fd9e55c7ca97b0dbb554f0ca33f34036d"): true, + common.HexToHash("0x7d3e03233dc371202de9613ed94d36067e758abd1ddc48af53356826bbc2d069"): true, + common.HexToHash("0x9ca7c095c96c7af7f1293caeaf099027f136df00b4b8e30709121a861b3cecd4"): true, + common.HexToHash("0xb313eb7267da402b2847fccab58c16460686e8d13f4918ca3639c1bb32eed079"): true, + common.HexToHash("0x50ac923a9ec0ffe2bd3595b6c384b2687b8a426d99033d18180663f290548b21"): true, + common.HexToHash("0x846c78cc08abc35c5069ae05e3e939b73e3e610fe17042c4938a31be4a6083fd"): true, + common.HexToHash("0xca64623d4ccb753b198fa78a7cffa00937d23c65c7d82c91da3a3ac6a9eb143b"): true, + common.HexToHash("0x41deed3b657c5b92e6da7b1557c10f0e2bdce23af98a2049bce176d6bbd3ff41"): true, + common.HexToHash("0xbbcf1c8fe350e2bc5cf91fe3b1fa4138c3855ef865ab06a5a49194fd766c8932"): true, + common.HexToHash("0x2f0fd42c664fc9c5ac6e5d8ba8a5912e5eab5621a7728c37fa46f90e90e25c88"): true, + common.HexToHash("0x993537044ddefdfd7b6460fbc6fb4f12a8501398f3696708c1e68def24ce7bff"): true, + common.HexToHash("0x29e5dea2d5adebfe8657f69d66c45d08f1b3023c978397ae48ffb9f11356e793"): true, + common.HexToHash("0x8fd729150f669bf1847456bfa94798929f7c3c487d7ff875242a0df9233db154"): true, + common.HexToHash("0x346a35e7ddbe28a276621ab7c9ab7c530d7035c6f2e62da6c46b2f45a99e7073"): true, + common.HexToHash("0x90a8ac4e78da5daed5696f7efa40cd66a3d601e8bbc641d84c743adba74781de"): true, + common.HexToHash("0x84d80b6b070be4d20763e65bd61c2f45a07d1953781d2a06ce7f34dcc9955337"): true, + common.HexToHash("0x39b7a72275a4396d7296253df5f677eb6b5a5efd55a089f2a5cd74e03b599719"): true, + common.HexToHash("0x76bfd80c4c7999b178ff2fef9879e6b884f1d75f8c20397d73a830b7bfb7fb59"): true, + common.HexToHash("0xa88aebc9f9dbd4ef94f37201341d9a0c8de5706b910569c64292bd5ba876dca6"): true, + common.HexToHash("0xf68833bd2a00ae84998f1d0769ecf7edb607304783c1175e36d65b88395d1749"): true, + common.HexToHash("0xc8505a57aac98b31fc0b0734e52a8e0b4200e9e7bb5c6ec52adbae9793ce3348"): true, + common.HexToHash("0x9f636c540f4ebf8b6a6e55ce6787b400c30a1b21c63ac5f6065def6fb7d22836"): true, + common.HexToHash("0x83c02e96807e12c202d109707c44b023d32db0ef2a271946ac683dc182ee391d"): true, + common.HexToHash("0xec7801e93eec232cb0153e6754c0c454fb269212c69948254691d9e2c0fd2b6b"): true, + common.HexToHash("0xb58829e012abdd5eb1b981a19bc81221e80e9f7793fd1d3877b766801ef83ffe"): true, + common.HexToHash("0x0eaacf3ee63ef4b2cdbcbb2b913a20678ca6402a6aaa9dda5fbe617ec37e630c"): true, + common.HexToHash("0xa20cf9a747b8a10aeef34c06ac5fb218dcb052dc93f9820804a22e8150511ecb"): true, + common.HexToHash("0x6d10a7dacce9625464e5b7d78aa0695738bfa8df2e5c261f8f1e9a53557b6a1c"): true, + common.HexToHash("0x7ec744c82f53b475fbf4f68db0079221f39136eeaf8d44023034abf59bc48362"): true, + common.HexToHash("0x7241332a2b1c02879ddf42e50072e337e1e40e76d40e1db5202f397406d7c4a8"): true, + common.HexToHash("0x04401ccdfa041fa7e078210e62aa09cd2d56c0aa0f7916f59774dee931999b0b"): true, + common.HexToHash("0x3a7ab42be0fa3c2c52f3fece5f7173c1ba94b30eb75a59c115be6c11740c45a7"): true, + common.HexToHash("0xe255a450b02c945f58fa1d653dbbccffb4851a982970ec4844277808f294873c"): true, + common.HexToHash("0x568ce45965dc600c6ac5be29e7f31b826c83a9fb51258c14ca7e150b7c17f8a3"): true, + common.HexToHash("0x29994a335eed01a160cd838787cdd403b889ae5ab92fdbe91132819a5cb5e56a"): true, + common.HexToHash("0xd131f3e125f52e80917d24c536084f33425c1cdaacad9c0e5179dec934aa6d2a"): true, + common.HexToHash("0x0e0dd620c0f8351eac09bea8701b68c7523f53c3412ddd0b8cc3d419034a29c1"): true, + common.HexToHash("0x68d919c78709ac5420a6181964c089859d4802f17d18004d9b8709ed84b9bd2c"): true, + common.HexToHash("0x51812a7d0f437a8889f9488cf929612d5861c9cce178db1901dac6f3df04d7e3"): true, + common.HexToHash("0x4bd6fe15bfda88e4afe6369b3734468e98eab95713197bd1d4c23d6153c04bb3"): true, + common.HexToHash("0xbd9ae9ae4f506f764469362b07048d58af2b7092a0c37fa02eccb97bfbdd17e1"): true, + common.HexToHash("0x352be401f4024d99741556783ed9052faa21bb0382df7f0773588f37f316abc7"): true, + common.HexToHash("0xd29d9b3158f4629c56ee06bb9796af93716c4b1256c706b0c6025cb3721447c3"): true, + common.HexToHash("0x60b8b572a5a555b3db6fbe9c67a65788a4a35bb8e1fc5b8ad9802dd22f5cc2d0"): true, + common.HexToHash("0x1ed3e006bc1c05c8ebce4624063e524ca0d23bd41a520169f80778dbb9261f4c"): true, + common.HexToHash("0x8a38c9891d7f54260e4dd6eceac8ac1b9c8cf9eab00b8c86cb6488c232468df2"): true, + common.HexToHash("0x9ec06ff630bf418eab96fb3160e4a42dc442e9a10c0c1763ecd63cf970420af9"): true, + common.HexToHash("0x69703a4e0723876973de938ee97b5de24c4d5d4193e5d77b1cfe31755a40f7c6"): true, + common.HexToHash("0x49a16f87a719de349851a256c02c700cfd5616a5600c5e8cb80f17b9dcf3a4c0"): true, + common.HexToHash("0x8f3703237cf77ac50fac5b5e3bdfe468bf21703cefa7e2719b2416fc0a0a9997"): true, + common.HexToHash("0xad04879888a4fe632de2a4fc22284a055e138ec4e0b6e735a75ac72ec2f0ddc7"): true, + common.HexToHash("0xf82379e72bf05585e8e0153fcfa796bfd08d513a6f9d7464894c713aa226f798"): true, + common.HexToHash("0x03adee21ac8e809959f3424e985b9e6b656590a66374ec90025c65adf5146acc"): true, + common.HexToHash("0x6fee1428ee743fb0300c66c105b16db6ec0b81b612b55850c45f8ec9c88d36bf"): true, + common.HexToHash("0x3225f1bf2eb97dd5c0825024340ef7cf09b560f0b4dc249bb298f3f14a594d2d"): true, + common.HexToHash("0xf42a71202a3fd81b2c9d3239042e7298f9a969d0247c423513c6d915333f8d19"): true, + common.HexToHash("0x2c92fc290e7b81a1efb807a86ce5939fc04ff228fb54e2d5cf19759536464e10"): true, + common.HexToHash("0x3425d3e248b895a526e0b12f422c1c2818967649d985d1558674e65e0ee73b64"): true, + common.HexToHash("0xbdcad3ea07bf0e1479a6c793ea4304fa0dad613687159f809cc9382ef7ca4814"): true, + common.HexToHash("0xec9b3c1477b60a6931e02e746aab86d0fa12ccecb2c1843a12d5b1956d89fe72"): true, + common.HexToHash("0xc9aad5c3b3f50589fb930b6c6641d014fb5d1cf534da0031bdfc6bc9e439eec5"): true, + common.HexToHash("0x003d5251aaeebdae8d19d037a400dcbba0b5d5d4a1f35c09b7718d91557f9e58"): true, + common.HexToHash("0xda6da700fbe09afb82f93370cb137ade6a0919bf585081c0cac871e4a1c0dbe6"): true, + common.HexToHash("0xb2b198d1a9102f77f00b93223a192cc951ef783f023d24805381022cc5943bd7"): true, + common.HexToHash("0xe9fb8bf7aec5e5e9dd23078e8c09eeeaa9cd2980c66f11285d7fd9ef0d36e547"): true, + common.HexToHash("0x4db04983324baa0472bfe9522383f4e3ae4a327cbf2dc040ba14101fe739d0fb"): true, + common.HexToHash("0xe245ae4be9423305b96f938fb72a87555f86c6aa427e68ab12db1c8735de00f2"): true, + common.HexToHash("0x38eb0015ab5d877fdeca0bb4e3989649d6a6d4a1c4da089c9cd93d65e8fdcddb"): true, + common.HexToHash("0x77cd070b5c38b53de767ab16a2f6859087d762f5f93b0e3627290e278dbe0962"): true, + common.HexToHash("0x398351f46266e1741cd9909b47499f6984d64873d59153edd506447aaa720b38"): true, + common.HexToHash("0x4e3c573125494657c75c7fb2dd9237026807f5a9c9e71bb676cd78379cc068da"): true, + common.HexToHash("0x413e08641650f5c79848c25cc4e2fd99ab49ea88b32fdfcd9176dfb9152d5335"): true, + common.HexToHash("0x8e1d0efb7e6e093ac07dbcea3c4256d553f5ac4086fb416346454b9be40c0d64"): true, + common.HexToHash("0x22ef4e2e5baa6700ca33718d0bf2004e2d58a5839cefc7dcfa77ee512a70d140"): true, + common.HexToHash("0xa85bcf6cf49520f9550913b6f70530f63b0866cb11dd34684ed2141cf757eebb"): true, + common.HexToHash("0xfe6b6b9512a3fb1b8fe602908b5e4a3bb3b1928ffdc622b4d9405cb495540224"): true, + common.HexToHash("0xcec9496d46216b91f2e5c25721f0d40b4b2a19ef16aec3d46a4d25b6f9fc1fb1"): true, + common.HexToHash("0x20b007f6298c6ee935f4a9fd70626e580fbb7124e05677f3217782d2ad061a03"): true, + common.HexToHash("0x02af7cdb7498c4e1f36e0d5d75bd19dde0b647eff33afafa89c50dea6fe0c8a2"): true, + common.HexToHash("0x9ce9cbd617a436c60ed6f175cf5be63a39d81a376b736d26203d889196ae55d5"): true, + common.HexToHash("0x7d703637209ff1deb3ef1a2edace9d10551219cb848f6ade23710f285be6babc"): true, + common.HexToHash("0xe68740d385b24e3212127e9b24dd22867adfcaaa14798f07b0bcfe5ed84fa9de"): true, + common.HexToHash("0x949c019db4493efcde59ecec4c870c8aa95dcc7162a2a41a3dbebd538702dc68"): true, + common.HexToHash("0xcf1e4ef75651f2d6d672802842acf1e48c61e0c17fe4821a84e150c1737af736"): true, + common.HexToHash("0x22a96dda7edbf51099dcf8c91bec18b46feab40fa52e0f02ba37667f8be613ba"): true, + common.HexToHash("0xdf105dfc50280023f7ecdc0bb5e59a385095048989acba41d86ea7fff7fe3877"): true, + common.HexToHash("0x9c065d167328776ab79b8a063f063c7e7c942a52de099b2ec6a618029d489795"): true, + common.HexToHash("0xffd8cfe7f0ec77094a7eba0964ba720feb0b3910b670bc65bb07f7d44138f3af"): true, + common.HexToHash("0x65b563e5eb08add1c2c8c0e582910d3a417ab1e587994152b0c7edb493f2ed0b"): true, + common.HexToHash("0x747123348d373223e613424ec532058d05d5caad01a78e53f68641092e88e1b7"): true, + common.HexToHash("0x62f15e8c1cba16fce5ea8b88fb610ff0e8185eaeb40938c049851489f9cb845d"): true, + common.HexToHash("0xab9b1e05552d1312fc8a63475d2a3b0445a717d3d8f33ca118d1be87f7f377ca"): true, + common.HexToHash("0x1539ee51383ce0b0ca827636943eedfb648d0d466d5e92bf7739571fc3afc433"): true, + common.HexToHash("0x117f714128693c93aef29e3608f84606707f75c28ec7c07368391dd0f06b526b"): true, + common.HexToHash("0xed7a795eb480a66f4f7dc3236c817c7b067f9f8ebb48989dc54c38d7b622911d"): true, + common.HexToHash("0x0a6dda76dfc4043883480f66db438ff2428d5a609a117e45f1a38f2eb67dca1e"): true, + common.HexToHash("0x3bd8c9f6d9ea18159b40a2eebf7b0debc05cecf24c2d1a879ee162d8ab389c4f"): true, + common.HexToHash("0x4dccb29aab172899dc8f4102e0ca3e8f92b4fa8ac365b106cd7ce57e39195499"): true, + common.HexToHash("0xfd0deace6d6a21f57e72fdefb4be79d00a71fdd3845879fb4b8db285bd3d9823"): true, + common.HexToHash("0xe4cd1ac65fb2667277a33dd954d7d390bb50d9310aa0e8c2a099ad60d74936da"): true, + common.HexToHash("0xc387cf727dd718bebb7cde6451c28fab44b3acaa97450fabe1430bb5ed144558"): true, + common.HexToHash("0x482f3e72d2db576851c8ada2e784ad8d1d3dfbec373bd064b5bc9266922acb49"): true, + common.HexToHash("0xcd597525e020d67831e10144d3270133d4a1decab3d6b7cbaf06d5de3d5a45f7"): true, + common.HexToHash("0x041de2fbb5062a92981cd3608b699795a1563982e3aebef3f77aeac699314797"): true, + common.HexToHash("0x9b1d8f88a0611df24ae1fd3712547c6dc663cf190e74fb3a91a72900a022b506"): true, + common.HexToHash("0x2d81bd1173c15931a582eb371fb458464492b19d3c1b85e6f5eaa9df04507b64"): true, + common.HexToHash("0x4d8214ef95b7680ca54382539b9e67d2de3fd1d7b6ebc6d998a3c146d914a528"): true, + common.HexToHash("0x6dd159ab05198d30d699db224502ecfcf0ef2d2761183cea16b302bbdc7f815e"): true, + common.HexToHash("0xa9f32d5d8c3a592f3d54a649de53907b7dc5ba071d4701a06580cfcf18bcc5f5"): true, + common.HexToHash("0x9081bb382ebd3be0969eef99d98a603242125b6feb25ccc4643fb0beff3890e6"): true, + common.HexToHash("0xe8dd24c51238726d995b88ec4fa7137eec90fcaaa4d56f762858c16f10cf1525"): true, + common.HexToHash("0xc526fb6b16566f0b7d1302592144245cebed7ca2bfcdbb6961b5831cf47d762d"): true, + common.HexToHash("0xaf11b656e0f3d4d1131c28a18f26c0fd9c9326734b6410c5afd2d900937a8fb1"): true, + common.HexToHash("0x8da17bf5806047c488ea1f91a6f0b93a628a375764b3210d56a7ffb40b712826"): true, + common.HexToHash("0x1e7e15fa8b813c3b8e3bccc3aea817cee3c1be25fe2d7a0a66ccccaa93ad4345"): true, + common.HexToHash("0x7a4142bdbdf51dcdb2652d7ee7b41b2094ed8919437ff871d1ef31a5c2170978"): true, + common.HexToHash("0x520edb442b440995a9baa0b599566c5ef9040ecad1f5327930a71d6f8d2c543e"): true, + common.HexToHash("0x924da5a0ec69898a6f171ebf522968c8a0ec5625725aff1661e9da13e3214968"): true, + common.HexToHash("0xd444662a1cebc0f8647b4087ca1b33ea3b6ea5303f745a0280afd960faea8d80"): true, + common.HexToHash("0x2f8d81f2cb64a1f1bdf4f6086ef5a6b4f403d12b8b691868c9fc0c7747ea9835"): true, + common.HexToHash("0xba8bcf9b692d197654f5a84b3e30680b22b41b315b69c9e88e92e041e6ba7096"): true, + common.HexToHash("0xcf7a3dce5d2c5a25c1c593b23825fa6bedd3c2ca99b0ba3fc19eb2b3baa2d7e2"): true, + common.HexToHash("0x6d89073629f6572b45e4c110ff88551184f586cb7631e56602fe7495effca378"): true, + common.HexToHash("0x4cd997fc53dc87834c1c450caa713fd68560fb5e1220983391a188d2449b5371"): true, + common.HexToHash("0x1db0eccf49d56033f91e956774187ff19762f41e57493a24b8d721fb0ccc0b76"): true, + common.HexToHash("0xaa9903327700ed432b6bb40a91e086cf6edf531d8572844ae074febf7de77b86"): true, + common.HexToHash("0xd22d320e627e112186bd7d8a1ad65d8aebe4fb9abd969d38e2341ab5ee4e9155"): true, + common.HexToHash("0x39fffcb4041b659342c67f8dbbfe78fbff77a9025fa1d6cd2b87db16dfb8a94f"): true, + common.HexToHash("0x03c91a04d21914177bbde519158f199f4425709885e75d296a4415de092f08d2"): true, + common.HexToHash("0xf3f057edf7b2754b0baf172418fd7775fdc6727aa9a4385c6514057844de496c"): true, + common.HexToHash("0x3d72077911a5d8007bbe9570cbac017fba661f4e73eb1fbbb9ce41a32251883e"): true, + common.HexToHash("0x55e56977208fd69396c3f19bfbd5bb0a97d183b0ca6068cb63b505863977888e"): true, + common.HexToHash("0xab7c823dad43818a52648a5e99c07425014644756cd446fbec17604033e9abc5"): true, + common.HexToHash("0x26a9d39b94e84fd97feb8a3c153160d30e85cf92547017e6fc00401781821009"): true, + common.HexToHash("0x1882b0fd1ab3c7a361e505b76a5efff1caa9f483a129329ee2981cdb8990ba74"): true, + common.HexToHash("0x05ae735284b649fbcd9fe39b29b765e3b1495bb631404a1ff40ab39abfa68bfa"): true, + common.HexToHash("0x03544129445cf90b65aa21b28a16bf0b798db88b3241fc8f074341c13df1c4d0"): true, + common.HexToHash("0x74a4f570e2cb0c5173d3a0c2cc22e7f1af58eef8188038114055356c4ef1fb48"): true, + common.HexToHash("0xa6b43aa7bf724fc1179f37e9988cb386e89a90e213fe8c0423fc4c3c8becc914"): true, + common.HexToHash("0x20af7b215a240ed4bdf57af27145a9d85e4c379449ccddbdf16c6472e160ebc9"): true, + common.HexToHash("0x2b18c2a4e9f52e2b7ee6a3e79308a7ff3183fa5efd7a85d1ee8e51bfffea7396"): true, + common.HexToHash("0xb000f8ee1489997757c6cb4469fc094b021bcf3c201ae1c265de8b6f44b20c1d"): true, + common.HexToHash("0xb8788f0d6726a6b7ab192084bc999b396babe4ae4b07dff355b431cf788c8520"): true, + common.HexToHash("0xd195093f1ce7962896cfc9e4fa69a5aa0a83b5ee278e72b85c9b476a1b494d16"): true, + common.HexToHash("0x59c78b5049a612042fc83ffc87a9193dfc4a99de7cdb39c241b95cd1a39e209e"): true, + common.HexToHash("0xb116a405518718de1bbba7f66db865e8a23057e7fd0e66feae52cc390fe054a2"): true, + common.HexToHash("0x102c38eb12c3647b46f83a668c3131e395ee56ccba8689e67e15283b1b4094fd"): true, + common.HexToHash("0x345b3ee946fde9e7b56ef4db7364f4c5c596569a70e5da2c0fd0dca0c5014452"): true, + common.HexToHash("0xd8cced29310aa1fca902b002b7e9fede959b37f5c7ec32dd9077c13e1e0823a4"): true, + common.HexToHash("0x75cad00b6c53a3fa2abbff5da6adcaab64a0188a4cb22cf9916ca8a9f062c31a"): true, + common.HexToHash("0xab713f69a1a81a8adef4167200298eb497ed73be7e3fa031047668ff9675b53e"): true, + common.HexToHash("0x3cf687f729c3dadf58d56e5e140b493fef342b47de78be3e7b835fc07e42eaf3"): true, + common.HexToHash("0x01e249f2d967185fd095d135ec26141a50f0738a8291873b7c4d7846389ea14e"): true, + common.HexToHash("0x938f9c01046764b4f76d6bcfafb3f25f8d210370902ca6a6159776efaeb48f77"): true, + common.HexToHash("0x60b21064d4dfaff04dd8140a863ea1f8b71483086e75eb9c35bef0e8abb637e3"): true, + common.HexToHash("0xa631a57cf2e4317e29b1077c9678f901cbad5db0920b62059d5fc3bc46a88a7b"): true, + common.HexToHash("0x05dc5945bbf5c4ae491d89478266c111d9465acbf1e3e5044e1da3bed2d63005"): true, + common.HexToHash("0x9a995873dc7126c2503088cd5ab8c47542611d099065bea407373670dbb63cf4"): true, + common.HexToHash("0x15910f426062dec3b92979b527861640ef2e4d62813984de7b7cc10e9f8da99c"): true, + common.HexToHash("0xf77e6b0c5830a8c425e725c615ecf507c8227dc8224f0e0da41254242af0140a"): true, + common.HexToHash("0x3afc8346ea4ca50b82745af9613e0c340baebe1844f073d89f7f89f84359428c"): true, + common.HexToHash("0xa81ae3952cd72b96eee2d6da447079f79a29be1ba0e23f32d104c2c76342466b"): true, + common.HexToHash("0x7ee256dd547119abebacbede5f6f2e7b47788fc4a34ebd03b604acd7de198c60"): true, + common.HexToHash("0x58f8a187d0d0cef75a2a5f1a3c4a394e138715229a5b43ee62af7e721c3ebeeb"): true, + common.HexToHash("0xeae91c8c48a41f208d29374787566550b81c8e281fcb54fdbcdd74cab5706169"): true, + common.HexToHash("0x11def55109a39db91acb4a01a99098b8de198a682f40bd585cdcbb704a2483a3"): true, + common.HexToHash("0x4de05c093dc710da1104aac40fd7fc15d020281b5f064db70112296cee58d734"): true, + common.HexToHash("0x8de28d3f0681985e656f7d9b524e3bf0028b19f357bc461cd774b202ab0a32cc"): true, + common.HexToHash("0x2fe9f165e1e9b27202d4dc485a5ee2b04db5caa3bd7dd5194b136aec45e17466"): true, + common.HexToHash("0x5d0bbb06277b7e9483b27598453f437afbee49e2fb80542ce8263d755aa9e0e3"): true, + common.HexToHash("0xb114ccce15d039fea41f5292f6a87b8812a7ffdf23d2ffc320001e9316a33b2c"): true, + common.HexToHash("0xbeab07f3d33d9cde4f976c44e2382e769e00c47d112484c2cfba63da0d565936"): true, + common.HexToHash("0xfc894a93443ee5c4d71673f4abab84ea670e8a6366d6e5c6bbe8c39176dc0b63"): true, + common.HexToHash("0xe883488a4874a4c28ce5cb3bce2f95147d2b28486529c7d837da4f9cbf918450"): true, + common.HexToHash("0x4a78f72352f53440d8e4df5c753119e78eb3d53713c4ae28e2ff7d4f1b1bfd95"): true, + common.HexToHash("0x507420f07e120ec2d5d0479d220d72fd8af39766d35d20ecb0373f37b110daaa"): true, + common.HexToHash("0x8dae9bb8e1e1b2880fbad6d82fd874b69ba9c2d5e99e0fbd66f833623fe17d09"): true, + common.HexToHash("0xa97315c6b35ab9dfb9d4338471eb311cdf0e24bc61e4994a14835682f43731d1"): true, + common.HexToHash("0xf7f6ebc6d98aef4ea0f9ca360c47ce51053c89e1ecc9bb6e3242fe9216429fd8"): true, + common.HexToHash("0xc7339699cd73b9777138b42d948ce2dbc3eb6dfd9ed15158c3fd75027fbd1dd7"): true, + common.HexToHash("0xf59bca46398b8c5b220737cb12e802ca496c81d047fa1d51b883e9601b45abdc"): true, + common.HexToHash("0x094d3e756e26e3488b36b92a0b5c19e9515afe3dc3613c88ad43a28995d22b81"): true, + common.HexToHash("0xe273050b58560bd8e4fbd8931ce7f80f80ca0f5574095d7397a872f37c059d94"): true, + common.HexToHash("0x8e4b66376d0690b0a1c030e4b97dbb71bb91d6538d92d891a666760e78414b8a"): true, + common.HexToHash("0x86b2785519ea5882dcf8caac6ac445c0bedd976afb8a53a5681a3fede51d22ae"): true, + common.HexToHash("0xb01d0c89de23199ea488411e3a4047acae6cf6ccd64bd02069af926ce2b3f419"): true, + common.HexToHash("0x365d5449a6b635a6ded3965eaa9baa53b51d9cf64d1c5feb5549597b84acd663"): true, + common.HexToHash("0x47b1f0d07f0ab64588fee58a82265795ef023f9c3d1e774089f9351dc401129e"): true, + common.HexToHash("0x60cbe69b0e4b646ba7da071302586e0f33c579b78b0a4ee82f97170a0a370c30"): true, + common.HexToHash("0x548a9e5516bd5e3a5e90ff0e6c2e214f9754c5e64e287b89261df95860ed6a09"): true, + common.HexToHash("0xd734cbc802d60739a8e580071928f928c50d20af6ed763cd4e5b82a55777f358"): true, + common.HexToHash("0x2258e5026c45f69127de73e2112e519f93aadff91ab93338b01f4262b09326d4"): true, + common.HexToHash("0x616281a1e9aea18448e23b89439e2d19c4c266fe152b9df1f75731df0caa8829"): true, + common.HexToHash("0xcd10bfe572f054e4782fd2cb70602a26e5e55fd17cf625db6d30753b8b4300dd"): true, + common.HexToHash("0xd25518667d708b3f2e3049c97af43803279614e0305e510747b367dbc0ed46bb"): true, + common.HexToHash("0x5fa7d36fe30f1ba6fa523091eede410e6c04307788ab279c083417a86b0f2652"): true, + common.HexToHash("0xf1949b995c4ff5e7af11b077e5cfdfcfbe09ad2b1a5e953324d07e983f2becb7"): true, + common.HexToHash("0xb744724e312e0f078e3b2f414091507278ce17c0d62243b721db56970de7a827"): true, + common.HexToHash("0x823965dcfd656826216588ec7a4ea7e4cc82a21e1e9acf214e27dd1b383102fb"): true, + common.HexToHash("0x729a30c730211ef12741dbdbbd1f40a36a9cd88470f2a53289d410088fe1ea66"): true, + common.HexToHash("0x64c925279cf78da92d279d072818dc7b2a72eec32782902d7c7dc620cd494379"): true, + common.HexToHash("0xd0d90447c35c79f77fbc07368f38ccc9bbf481e503e13afe8698896443075a20"): true, + common.HexToHash("0x3fa2e7416f2ec4d9f18e27dc51e012c2ddd504070e771f5c814a8cf481376441"): true, + common.HexToHash("0xbbc32bb541efee54b4954933a723c495ac455734232c7de3e57d8d1e701b908d"): true, + common.HexToHash("0xf5de61c11d4e5662d5101124f522e548770f8ae3311edb0c54ec4124f0bc4188"): true, + common.HexToHash("0xa05e38592206710c4e89966a699631fff65761454240c5a450849b29187ace93"): true, + common.HexToHash("0x5dbdc72de20cc785a829dde9b834e99f8b0d9fa12faeaa4ae6b2a404f29e68da"): true, + common.HexToHash("0x43e72b8b135646b7db69450b4e35af4b60a8369a55805f70035e1a406887ad98"): true, + common.HexToHash("0xbd26a1f6bc007ce091a936587d6d64663a03733232b30a5ce4672ad2635fd4fe"): true, + common.HexToHash("0xd0db32276c6e2184342dd4024d6df568f3fd9b1caa74cc0d5ed9cd2803d912a1"): true, + common.HexToHash("0x898284bfbae08739a42a66431a40192eb74f7412db1db76102a237f199a51706"): true, + common.HexToHash("0x6bc28b8a795a8dcbfde21297cd5a83f186a67b0096e7106f79385030efb0fa97"): true, + common.HexToHash("0x1577f3116efcffe265970f3ce73cc4099b8c1820039f8da43c1d80d3ab769312"): true, + common.HexToHash("0x2c17fb323669a122384ad60bd0ec227dc8ca512e0ceb5a32e7183f88f8a95c13"): true, + common.HexToHash("0x1b45e544cc227a2861f6bed89049cdf38c6ab987ed86a35d0e63e34cfab10bb5"): true, + common.HexToHash("0x018725906c72d4f81d91de77786572edce59c770063494f049cd608bc6527921"): true, + common.HexToHash("0x70a9e00423ed6bfe09b0534c8dd69cb9f642daff16f3b823ba66a8f55d44be30"): true, + common.HexToHash("0xd7e4e7aa96857c20328ce8711188ef28c219690ce52c76a28b61210d9ef3769b"): true, + common.HexToHash("0xb9e8db05ff18e2bc9b36021191216cbb5cbef52335246c843312302f0ef3e17b"): true, + common.HexToHash("0xf8e1f38e87792c734e9541e1d99fdf065ca4ceae93e3f83bf425020ea54a6c8f"): true, + common.HexToHash("0xa7d1e48a6d0cfd2af21f69a2eaea3611caeefa04cebee65b9847784123d56318"): true, + common.HexToHash("0xfa973a015304316c8321789e5c0bc252a9092cd8094b9ff1a129b2e1e4cf43ba"): true, + common.HexToHash("0x35fc339e6dd0793338f06fc11637b499f99672d9b96fbd3f75046a94b531f9c0"): true, + common.HexToHash("0x2ae776c28cb645a5575b3f645264ac23f52d7b77a055e927859a9e3479ff7299"): true, + common.HexToHash("0x797aae626d425c145804eb3a9ed974b2584fe70ea7086b92c927589265b9288b"): true, + common.HexToHash("0xa7eecaa0e2edcebd2cd2f5df716c7311c521ce10a8dd2a79f07266df56bf8b29"): true, + common.HexToHash("0x3f462ae5ddd8746798c2e959ae4e52dde7880d23a73f7fc888c476719277a615"): true, + common.HexToHash("0x29da7e567b7e5728d7f49283ecd0a1523901df6a6d3a462a1b82fad3797d16cd"): true, + common.HexToHash("0x286a1145e207283c8dffafd290d7366e59ed9a790acbfd57a41e850341b9f54c"): true, + common.HexToHash("0x84b1d4816aedc3e1976504c9078af5248394a34bd9ada63a51375ed308cb9355"): true, + common.HexToHash("0xf809bddd0488cffe57f1a2cc2233c8eb5b16a1ac019f66dc317c59ef724d161c"): true, + common.HexToHash("0x9605eb6141cc01357800dc45e1c094653de88db888fe0c8197d3b7a1364bd0f5"): true, + common.HexToHash("0x89038f49211be5eb67408173d6970ad33104a0740cae0bbfeaf03b637c5c3ced"): true, + common.HexToHash("0x76586b51569ea0c0d9cdb27689d1e3bc37676c23c19a605b734a70b2a953be3a"): true, + common.HexToHash("0x28779863cf8998c6bea8d147d24ec517636cc28f8123adb832daf1f481f44544"): true, + common.HexToHash("0xc2dfa547dfb5c9f267477098835ffa73b061f9035ddd1a0e9b9df720791670ca"): true, + common.HexToHash("0x130088097ef96d76ba92c99d8ccb23e014ed2ae0b4ae5d11575707d62d0664ad"): true, + common.HexToHash("0xce98cf3109e95aed6ed9af84cc3c755d4cc3b1f75f1080b5a9ba682959abf5b6"): true, + common.HexToHash("0xdda6e31df673f5aed609a51d879b63568b4211a5d5b54dad4013499ad119aacb"): true, + common.HexToHash("0x04109cc3e57670ec2f7a97a71c3b4c927745103077c66d34b614073d657df5b5"): true, + common.HexToHash("0x6c6332501a832c7e168da87d2f20baae0827dc722e11db95c9c766e486e8215c"): true, + common.HexToHash("0x88e8dc14dde85f6b1325dd75bec6149678ba44c35b58504d550ca3e2a0bc4d6c"): true, + common.HexToHash("0x5e805ee1d5296e14b292a1e8cca635125920891beba4a3990117e2a8b91dfc9b"): true, + common.HexToHash("0xacf14919cecbd3d7e9dfc7636ffe38164e0d5440d074b9dadfa3c2aa69772164"): true, + common.HexToHash("0x81022add7cf5bca21f9f40d70722f8981e2e858dd706d47bde4081129abf06b0"): true, + common.HexToHash("0xb4cd68d262fe1b32817ea2f73c56e1c780f898893d229fea5f2b3877cb89a62d"): true, + common.HexToHash("0x7513b43210d2b663048216b43a762f285d58bd00dc918c3ad335c0a90d3055f3"): true, + common.HexToHash("0xa076a659c34951b1b6d7e23c44703cd4fe2aa669211a8e79851087822b8f438c"): true, + common.HexToHash("0x1d14ac9d5806f21aef29269d5156cabf2a76faf457d8d48c7d9ed002fcd80cab"): true, + common.HexToHash("0xd029b6898d21257cf83df74913d7eecc3cd7d5932515663be6e1f1f6d02d4e84"): true, + common.HexToHash("0xf25f9741b8b016a990f4c87e96c3a0c6af505e17d3c0b7472b984b59cee61953"): true, + common.HexToHash("0x4f56acf99a6af583b88b4cabe83f933a6da57bdb2a5f96b0e8617e80b6f22fd7"): true, + common.HexToHash("0x6b36543b62115e62ad5b137140f5f8ad276532a3eb5011762e2e7984a8d4bde4"): true, + common.HexToHash("0x14afcc08a88bae8156a8b98316450eb8cfe2756fcc6909ff80d9d79a3f3c6d79"): true, + common.HexToHash("0x5f1f138c6dc027044a5c34a3d8a2b557d2ec8c340e4b26802fce8921759ba10f"): true, + common.HexToHash("0x9b067dd0292b0df88d556db393c667c63dddb8ca560267cf3f67763aa8653bca"): true, + common.HexToHash("0xfb8f0cb3ae6ee199ab374d361ddb34f2e64408ba9619e5617bca1ba71919b111"): true, + common.HexToHash("0x9a41aabb2b9e44d7007d0a28e94144b0cbda63cbb334db71e876544d5361df17"): true, + common.HexToHash("0x1efd35760c4c2955607ff842f1a486c09f29c709bfb2a2b232e591712b8fa5a8"): true, + common.HexToHash("0xcb08174c40c548e49279ff73aebb6253ee5a21ecfd94463def88d814a43a975a"): true, + common.HexToHash("0xe8a39a4963348d59420f9b6a338b7a03dfaf7d082f8fc5481a0010bf6a146557"): true, + common.HexToHash("0xd6214f92eb48ee78b3f2cc3ad73467d7f0bd0c70a582d174f00e85d03142ff17"): true, + common.HexToHash("0xd6a43ecd553bca6a358e5221a962382fb90de026650cd9fba4db721f9ed22a62"): true, + common.HexToHash("0x77a3de256a126218a72128d8aa897b79b7db11975534df81f175d2d5b8136535"): true, + common.HexToHash("0xdaf8d27246e1ef793016d458475317ec87ca93eb738a40657f5052b9c88a5b13"): true, + common.HexToHash("0x1c239ead45e66a83ac93c2dfb9d0e7e0ad54690c1a494bbaa08066cc8c01f4d7"): true, + common.HexToHash("0xc505b55865c4d20f4aeb200a6878ef1686fe7a4fc84e35d894ca0e7655acb4c1"): true, + common.HexToHash("0xba7965873f8423a9328e92b02ac2b54435e69456d3969a6d8d254a91fdcfe1bb"): true, + common.HexToHash("0xc1435c609a9bb555ce68b5559bea91ef823ad1f3211bc79a369e99f87045a436"): true, + common.HexToHash("0x4121719d160d4b90c96a03043a616cb615b0b095f02c0a7f02be650057cfd905"): true, + common.HexToHash("0xc93a45e25f002bc58aca03b97412134d516c249a9c445b206ffaf5e6060573e2"): true, + common.HexToHash("0x2303eec208c3147165d5454486ed05067a7c4a697dcab4da5bb1f4ddbb9c68d7"): true, + common.HexToHash("0xc000780f3a1e63e11b84e13a7deef1e07c3322edd661d1a27ff28ed2ffc137a3"): true, + common.HexToHash("0xfd7adbc7b87579d9dc4bc568023dcd6e6562849c0bcf81fb2671f1a2347962bd"): true, + common.HexToHash("0xd10a690cacbc106dcff103b664c8878af501d5c0eaf62a9bc0b21e4c4b5b5cfc"): true, + common.HexToHash("0x9f870078576de5c17175ac363fb82809082c0c607078b45f792cb33a8c727cdd"): true, + common.HexToHash("0xcfb5798469ca47625c6da60af0864dd5ea298a09ea773c1fecfe0d7a3ee0e63a"): true, + common.HexToHash("0x2e21cb009ddbcc97f74b2f76371e9a42f7d3f6bad14da550399c376ac944d7de"): true, + common.HexToHash("0x7a0f8c201be46b8b1ad1c4333940d11024ff1275c7831c13d7eceb34040b26d8"): true, + common.HexToHash("0xdf97b270057de2f7a10e23026d4f50cfe465ee3b42553269d30b0e26ccaea9ab"): true, + common.HexToHash("0xa35964e12b5c5f4516c33d42136ad7d2e2facc075535b696256b94fefae1cc7d"): true, + common.HexToHash("0x6b0a9fb9dcd0e4164ee0f1008046430e5d1d825319e6897aac2d13ac4c76c1d0"): true, + common.HexToHash("0xe26a9147717e3f73d3883621921a285f44bad735d67626de2f7d8909e65a84af"): true, + common.HexToHash("0x85f082165778f4ea3bb146b62d0ecaae1c4971b8b4c7d4ef853f77a5d6ec7939"): true, + common.HexToHash("0x8cb175b09147a705a69a1dbd75b6ac4cf93c9b638a54dedee9b43b11a6c88934"): true, + common.HexToHash("0x644c0e7e55945ea7771530ac697cf5ce6c9115b5d1dda3560b4fc46a5b3eb9fb"): true, + common.HexToHash("0xee1793314e4e3438f2772b528a75ca34fc5ff0a162e39d2182710b3e6ed44261"): true, + common.HexToHash("0x5fe5217811f6f0296435583a1dd5ef74991e84eedffe92964a7caac5afd239f4"): true, + common.HexToHash("0x3c1c6c27c26ec06de6b937b6e8ad7bc031243e4ba4e3ec3bc77b774b5edb8d0d"): true, + common.HexToHash("0x822de514307e981fbd1fbb50070fdac5c34d640a7cc94297f6cc2f43b832f2e1"): true, + common.HexToHash("0xa5510c3a0773fd2409e5e090a036146702b0cb2fb731c1aaba42b2465799d7a9"): true, + common.HexToHash("0xf2c1ddf85ca6f164686e9d38578533c6d9c674d8c2772011db07934dd6ed8407"): true, + common.HexToHash("0xe594b3da17bec71b2ed657a958a2c116c56f4a78896702a47ae00f85362a231e"): true, + common.HexToHash("0xf55c8bbc416dd443ae45317db022c42f0884b9b2358b454f0405819484bc1a67"): true, + common.HexToHash("0xdf8502791ed031a169470a5ac0a7a937eaec8ba0b68f2685d188639e26f6898a"): true, + common.HexToHash("0xc011cf30f3eaf5ab8d6e1d8ee08d3b6f839a3956d5ac0296ff4d2da0bd0464c6"): true, + common.HexToHash("0x67d352c083a572c67e44127a68eaef621c7f59cba5f49eac73ba09f42b6d12a1"): true, + common.HexToHash("0xc18571243ef70f49ef3bb8f18ddaa37e0902ce534e530536b3b6e28a3930611d"): true, + common.HexToHash("0x4162e1bfdf805109ab94a9da36d2197ec827c92f4e3c23b363ba40d604eaa2b8"): true, + common.HexToHash("0x87c28cde99c4a54d25d30bb7e6e74726e477009d06de324571b0c9b10d883f3b"): true, + common.HexToHash("0x17d1312ec71905a2306e2e21c9a664bda325ac997c27b08af8cef57fefbbdefe"): true, + common.HexToHash("0x3d4e2e788e2e3f2bcf7fdaac55d634ec1a0f036713f531107ddcb8ac400e77e4"): true, + common.HexToHash("0x0b85a0ea4649ecb7c7e00da6269c6d2113184fd96c3d3da42dd373fe2eb5adcc"): true, + common.HexToHash("0x1bb8a5466fe2ce980823d83a3c42c09d4908bb93864e1e88f96b7f052e33dc11"): true, + common.HexToHash("0x1e553c3c949230351bbca3bf8c9509b718d312075657cd57e390b3071f36c1aa"): true, + common.HexToHash("0x3e39dd1bd4f5eadcd44c7d4058e03303830efdd5243d94f7f3cbfff5cc387b47"): true, + common.HexToHash("0xe29d0d868948ca1c5f421c8ffb6c378e61d01c355645a4af421e0f82653c449a"): true, + common.HexToHash("0x071f3be13650fcf4a3c3b63cc94d3da4dd43caf121e90ce48788e79ff11c3ca0"): true, + common.HexToHash("0x8ef4e5138cc32afc54f886e7a6c4da2950e3ee9e17d7135229f8a1e6c154f331"): true, + common.HexToHash("0x3dfec7150fea3e851b6f980359f58430f8d299bde083cddeb36b155562ae81ae"): true, + common.HexToHash("0xb3bafd3397764c23c35ad4964b7d1e1c01355de99a73684fbf83838d7e33b15e"): true, + common.HexToHash("0xabc52ef48b3e24f453b8eada3c98dfe99c95eeed2c9ba18c7ce432c6295a11e7"): true, + common.HexToHash("0xc1cdcea201d98346cdbd6eb49e3b1ce169d25e1cf92e7cc7c4f283a4055e0da3"): true, + common.HexToHash("0xc9f6463c116ca8898d3c460f36d9e3461d40900d51ed58c3961613dedb64ccfe"): true, + common.HexToHash("0xa003d2da1bbd4f1540a08faca3a31c14e276ec40d5f813f1375ca58581befce5"): true, + common.HexToHash("0x4be5493eaaa43314dd8da723f817f89165a8bdd363b7bd7d0707ec37cbceaa81"): true, + common.HexToHash("0x171999ab3770e03c8a61de01274b734f686ee5211bea873ac1508885d9e2d419"): true, + common.HexToHash("0x1e88a4a25e8f5ac671d1115a2e798532dc79820556a69ed8c85704ecad2858fb"): true, + common.HexToHash("0xc1a148601038f7f53d329380bd44a793b6b907dbfe53b41729cacdf36a8d3dcf"): true, + common.HexToHash("0xb324fddcbf8c79e72f10c3cc68a3eec84eeb1878d2d54fc42b8ab7b5a0e42d57"): true, + common.HexToHash("0x41abd419b82d33448cc47cead86c4aa0a82bf564fc1bca181f5692cbe6e35926"): true, + common.HexToHash("0x7c5bbe0dfab63632edc8fa1f4bd5efd46e8c4fabd0355fd38729342b030ad85b"): true, + common.HexToHash("0xdc3d7bcebfc6bdaeb772e5d8464c430662cb849983758c324ac40b5cf63cb66f"): true, + common.HexToHash("0xa2eb2393bed04af00dab83ed389b5e383880fbd2d996fc04fd945bd12970abcf"): true, + common.HexToHash("0xa58b40cdeb46001b663b390ea7c839f818e3706b7fb462e9c91cb20a0d38aa7e"): true, + common.HexToHash("0x99a3162c963dd45f59f437b5094b3c6f3a5df2ca8683e4057caa7089ad6bdab6"): true, + common.HexToHash("0xbb657509e49c8926940eebc1847d83460d4f684c212ef96ef84705964c6d5bec"): true, + common.HexToHash("0xef9846ab6a27cc3f5f13719456f47cb322fb128b1ca8166d8a1b2358edf378b7"): true, + common.HexToHash("0xfe310d77703ebcef1d3f4d430216d4d415c063e4f543ca30797c1398b54e533f"): true, + common.HexToHash("0x66d0082557b3949f7858d6ae806efef27736011d9d64880123613c9ddc29bc28"): true, + common.HexToHash("0x5ee85aaf026c2c9235ce3c39c473ff1719f23a5d2862bfeb482e08596dec306c"): true, + common.HexToHash("0xbc4693267683acd34ef9d3fb2c0ecb37c11734ef4749177bc44f121cfd83ee86"): true, + common.HexToHash("0x0d7d5ade0e5fa82defd927050055afd7b10c46e615ef1b03818d710040058939"): true, + common.HexToHash("0xc5937645dc669ef1eaf287f429116a87056804ba395ca9df13f64e58067a3299"): true, + common.HexToHash("0xc4e4a56905f3cd9c3654f8726158dfa885f86e1d0c523653d94f0975d2f6153b"): true, + common.HexToHash("0xdb4557eadc006ea247140769e3a1a277c9d2acb79f2b5590f10c0bdbe768b739"): true, + common.HexToHash("0x9831f726a7d40b62fea80fcab2a2c8a86235fbad5f6ccfe67f26e9e310c015d7"): true, + common.HexToHash("0xb73dd213246f01d75e209d9ab3d7e3720de6dc99a017a3221976df4b46c448d3"): true, + common.HexToHash("0x7cb07a8ceae857f2abec633f0c3ac2b5384b4551d91b54104ad286b05efc89ad"): true, + common.HexToHash("0x4871b2c464f8815a8594e183f3a4041daa77cff9177740d1b2aca3a93afdada9"): true, + common.HexToHash("0xbd469f9a8935167d1b05bd911a5e0bb01adfbce1f97ba327049cdf3730cfb32f"): true, + common.HexToHash("0x68ea9c18d0376de17e02826079aee993dbef4fd981c379f47c83884e464abb57"): true, + common.HexToHash("0x5261e75d0d8f6a49fa53eb94c4573951ee248ffe49456fab287210d9ad81dca8"): true, + common.HexToHash("0x5e25e94942128443eb20bca3080eddb888a94a5a1721d8c115a79ce8b9f3b408"): true, + common.HexToHash("0x839973d8312338bc9dd624dc16f219f542e915a414f8a86b3776046fcbf9d3bc"): true, + common.HexToHash("0x9e4ea739d1f50aa7b6b84534d33752990a062e19bea4202a630d82da646f88ad"): true, + common.HexToHash("0x2074bfd66e7ecdeb944a9ab91a3aab9224e8e6e3fbc34cc3714613f7d3a25939"): true, + common.HexToHash("0xa13fb4ff5678a73f44bb97124f6b0129f33b35277f5e9f8f20f3419232a897da"): true, + common.HexToHash("0x4dbd5dc68899a0767b11a02f87fdcb1fb8620160a7074894f76abc987de337e3"): true, + common.HexToHash("0xaebec93ac9b74af95ba24cf3091d2769b4b892acd6a7eac4863d7f94b197ea75"): true, + common.HexToHash("0x419eb6ff4c6df089b64d6e0bdac16a20584424c1c7aeb675850cfe9ec117e72a"): true, + common.HexToHash("0xdf75a1944f681a26d2f20d7c88f33572f5b66fbba51d814b4bd2b72ed17af740"): true, + common.HexToHash("0x33b3b8b979e2e19c1ec8b83d908c32809a93e86bcbf5272ada2607160c1653a7"): true, + common.HexToHash("0xa9b0846ae017bb607329590a3d658e7eef879b02dde69c6b39235f62d15b91dd"): true, + common.HexToHash("0xa78760525ec56562f401dc06d8a67a7c5ebea99023f87f670e290c70a7ddcb48"): true, + common.HexToHash("0x8fe5d51752863a71fbbfe12fdf6f5167f5274a0f18e8681ad976186c34ce3e00"): true, + common.HexToHash("0xe0efc41d2c07070544c5291fca128fc4be47947ba91b6bf81027641f20b7ba96"): true, + common.HexToHash("0x054d1ab59f0078c04aa91ae6ebf86c350e37da8eddafa0f03addb8e5d3e33ebb"): true, + common.HexToHash("0xb10828fc1f42672d1f4dcc3c1b58554a6fb888d69f3a97a679bcd27441609c20"): true, + common.HexToHash("0x4c48b79e386085deb50982bc93ffbd83b4a4bcbdb6b2cb87bf005e74337d569f"): true, + common.HexToHash("0xe1e3caeb6e2f6c535d59731095fed0d065dab5d05493e46c79af3ff776f38554"): true, + common.HexToHash("0xc1ed913d3ba008f6773c9ee11b4e4dd366a647305a8a55acba1bff97b6614a03"): true, + common.HexToHash("0xee815a60ac6df7c48f96beaee205e9e9f8891bde24255425f5967cefb90dc913"): true, + common.HexToHash("0xdd25b7971dcd5f1e25fce8997e62f5793ba6fdc2abea680f3099a53792c6f1dd"): true, + common.HexToHash("0x8b633590b92ee06e64eb2a094638fc1eb41030fadf57f1045e3c4b8e7c5cd861"): true, + common.HexToHash("0x510694ef55ee0844082fbc1dac802256d44cac7c4c78877d10d5be33d1196df6"): true, + common.HexToHash("0xf66d36a56b085721265afe24b71708bde2163936008fd2dbbe5471b1da222f3d"): true, + common.HexToHash("0x69a04070722cb3313f031a6228c8dabf13410d0d38d7ce54e06d57504d4730d6"): true, + common.HexToHash("0x396975532e4e9881038da54bcfa964d3539ad8c6b2c54ada6c181d9675018f26"): true, + common.HexToHash("0x11e703ee4750430eb8b608f6a83405c8e44434c104a53a5d37c8867f17395bc2"): true, + common.HexToHash("0x3e4741a396b3d797f533fd584a7b510bcb9473fd895df089979801327ae89eea"): true, + common.HexToHash("0xfc5e74571b33ff73eb55e0d50d7fdaa523de49ad8f1ade7736b39d15b063afbb"): true, + common.HexToHash("0x70997b3ec9f1c9d8346880f3062e8beb3e0b96f40e24fbe33a09a54fd5f7cc9d"): true, + common.HexToHash("0x6322b008465efada47545344f7e578b5b5cfef331f1ddb432bd56869cc599fbd"): true, + common.HexToHash("0xbc52e0d9f8187854526da66fdc19595af5f552ac309a39c3da5cd7d182e5e681"): true, + common.HexToHash("0x734e0360ffc3229c07050c1423390cf0ebbce3b1311f00f80a1743ef86170077"): true, + common.HexToHash("0xbb61de71ede3c7b1faf7d45118b6d47549fa4a6032694f352abcfdd8deed8af5"): true, + common.HexToHash("0xdba31a0e1ff63ba4d194a13d11e17005856e1bf9ad9f60df56c5b1a13665dd81"): true, + common.HexToHash("0x45a4a7ac39f3e9f70f6d606a8ec5599d76c198c95c563349c8ef951bafbc4a52"): true, + common.HexToHash("0x783a4cb7e7cebd95651e797fd5a960f8a49e1cc53d39d2b49d9cfd47f2330bb7"): true, + common.HexToHash("0x2c2af0ee212c011b342718bd6658ab2216c4d6acb1928ad6abc46672103ffdab"): true, + common.HexToHash("0x277bc3ad45b521ff7704b882a2e36d30f7084319031e6336b61ce9a773546d83"): true, + common.HexToHash("0xcbd9e94246fb4adb9cd4ec5f706e7a1b36844b45902e3a1dbb5c27c70f48fc86"): true, + common.HexToHash("0x7fdb911cca7139bf1a3195eccc83850d26379a5d90b7ef629b0357c7adb40602"): true, + common.HexToHash("0xeaf7ba4015c4ead595627fd8d9f2893dbcbac9c3dc28f69553d6e06adc6e84c7"): true, + common.HexToHash("0xd1af9b69c903636f8b92e7e620f7340e27d9a63c8869198bf71da9a83d9d5d83"): true, + common.HexToHash("0x2ddbe84b50e8eba49c55c19810ee07ab3dcd385dd6bbd9fd3cc610cec768b115"): true, + common.HexToHash("0x8a0fcc603a22d3c1483d7ef435d314d18247b9bcba4b151597ebab25ad5c4596"): true, + common.HexToHash("0xc9674427c5f3ccdc0fc80845940cd46f62bb98e0812a186ea6d213160bcdf87a"): true, + common.HexToHash("0xf39a09db47122e46ccde07cf6e0cda124e3f099640640de515d51c4cbae6532e"): true, + common.HexToHash("0xee44ff6078a92c51ef8e6fc62861071cbd19937c986af1de35c645774ab9ea6e"): true, + common.HexToHash("0x7a6b110a5fed00dbcbf9204e16186604eb1cea7627388fea484304b69d208760"): true, + common.HexToHash("0x6d80b0868ed39790a1e8ce533f920bf4431c5efb463283fb1e6e3db483aa3a5b"): true, + common.HexToHash("0x898728adfeb635b1b2c228829fad94f9d08e14ded11fa52e6c5f0279155e80ae"): true, + common.HexToHash("0xa720e1edad89cf97c4b96f92cb9385ee89ccac600f541e608c34eca7ef21ffe6"): true, + common.HexToHash("0x1c3549cfb4d6e261511cd33c5897b782d3e7b9d4fe8246bb5cb3bfe20bf7ad87"): true, + common.HexToHash("0x7d30066f67cd062e479eb6dc0daef05f3bc2b4ff39cc141ec6360c29a129b249"): true, + common.HexToHash("0x4f0a75936032da1e560bc6502f0d908e9e97a093396c8d8fe06a21fffe1169ad"): true, + common.HexToHash("0x1371b38e04ed3b73d736cd42540f4a6544d48ab1166e8a23bf2ebbb35176f3fb"): true, + common.HexToHash("0x6796e6d6235b1d01994379f07045f3f67c3a768ef3082e8c719a5027b4ccb546"): true, + common.HexToHash("0x660c61f3313daae83cc46d7f781faee2ff02ca230f4b8900583517e9675eed05"): true, + common.HexToHash("0x2e04a4d6dc7e78d5914d474065274b43b0a3ed9c540edf157b8310713c08999f"): true, + common.HexToHash("0xb8cc6aa7b230df1f910b2fbb0f2699223a81d536f9c6de8dc43297ed26e7c7ae"): true, + common.HexToHash("0x262727f692405ca9d440ed747a8da4e5923b7bc13df36da87d785f8b0e4d89c5"): true, + common.HexToHash("0x7da2b3c27b527882f2ee65d300268178c61611f2c20dcdf5b504b6d8a577a6a7"): true, + common.HexToHash("0x1a4848207f0805ba3b040aa94352881bfdcf783f42d5230b11c8ee616191cf62"): true, + common.HexToHash("0x8815956417c912c0a9e8ab90a8df58f79aeb3de23c3534c43864b75ae2c109fe"): true, + common.HexToHash("0xff2804fa04a6032eebc5b3800d7a08a743d9bf2b2a6716e255c3efaea1248a65"): true, + common.HexToHash("0xa75e47050eedab570f7c9538a8b581a8056ed393f5b1ee29e038fa9749a835f9"): true, + common.HexToHash("0x15dff80109db19f12a92afc6c1e9b85156c910e35c20f49f1e181aecc8cc8dd6"): true, + common.HexToHash("0x8ffc6c3d8bfecc14bdab28639d005f2895f6720a400d992611f85ab88bfb3508"): true, + common.HexToHash("0x0928a96bb167d3f54af596dec6b9f67231749d20fdbbf322c8afda46b3ed36de"): true, + common.HexToHash("0x68180b1c90cade6b28554f3acd60b05b10c84c62f5faab6098343d8e85ef4949"): true, + common.HexToHash("0xd3461143aa7ec0152c78788bbdd06ea845e9aaa520ab07343c7478db7b6baab2"): true, + common.HexToHash("0x49b8e8e2e4110fc38070997f774703792a03010a7ce07ef211b1b1ac0c38e0ab"): true, + common.HexToHash("0x8cc23eb198ee1cb8d2ae27be4ffeed3ff60158ba33b7ca93a0fbcdf9fdd0c415"): true, + common.HexToHash("0xbbbbc06bb3f608434cc11538deebd78754aba8068ad37edf4d0cd7325380693a"): true, + common.HexToHash("0x22fccab8457bb65b214e4ba6054309eace3bbd01981275f5dcbd6409bdffc8ec"): true, + common.HexToHash("0x7d2c7d1363beee70babdb92f4b6c1779bdaf34bff0297bc54af198e4f2f09f01"): true, + common.HexToHash("0x50195d3318b2aef28fb432df450c990d33fa15918a9918260df9a1c5de3d6f19"): true, + common.HexToHash("0xbed833c958482d9ab4a2afd4100c2b33b407b110ec0e123e2c14f08146365d78"): true, + common.HexToHash("0x3a73c03322fa02cf33095157246b5cda427b8cb54f3eb221b886f2980e3d7917"): true, + common.HexToHash("0xf974be5b2e2c493a0e8a57a156a19b99e652f8d15c981d4a2b9e2a9a6b5f4b27"): true, + common.HexToHash("0x88f6c0a720b6ee4f9489ab30bb28a94624485372bf8798fb3eb5798320699e05"): true, + common.HexToHash("0xeeaf84da422b7456666cc60b63c21e3a592dcc14bfd28d8136aa26f23a4749f3"): true, + common.HexToHash("0x2b9d3d965e8f3bd0db272a420ff9a70a19ab883576bf6a406869a9dae8d4b18d"): true, + common.HexToHash("0x2bdde15702114648c9f7fbbe3a316bdda46eb652f94e0c9bf34bb93c22480044"): true, + common.HexToHash("0xdb3df111aa232067562faab8c8c5b88b08a6391419442a3f6056dcf129955f93"): true, + common.HexToHash("0x82f1100488a731f251efc7d281ff1a7ff44a8971a85ed930d9ecb863ce4520eb"): true, + common.HexToHash("0x48abc4a53cd740bf79fefc62f9eb0e54fcefeba17fd61f80f1f443cdbb2263f8"): true, + common.HexToHash("0x4327780c516940ee1e2b03db13a534e6fbeabc4c14de977adbda4e61364e7a14"): true, + common.HexToHash("0xc6931a86254b1226a1af0368959c59d1346b81b243c14687370374253dfb8dd7"): true, + common.HexToHash("0xf05d2579c3fe8fd2b6bc563cd6ec6c882d373c6edf48f03f857e15c8a2b5f4ff"): true, + common.HexToHash("0x3d2f1079227ee57217d9ff2459866a9b7ebbd585fe68eccb5e0d35427bcb6d22"): true, + common.HexToHash("0x2ef025900adfbe5e571875fb8d9c68e7282a697afa317002579e63429cf7b4bb"): true, + common.HexToHash("0xab73a5bdab85fcd1c5a0ef55e1bfb8a0a1f7e9462ddc960f5bb42a4abe564e6f"): true, + common.HexToHash("0x55c1552f8c6c3a7219b61975d9d3f3cdd1f62f8f9e96058edd22816e7c87d555"): true, + common.HexToHash("0x8bf30177801ea6e41120ccbe9735872067738bc492866430c9a65d85f389a16f"): true, + common.HexToHash("0x78a8ab819a392083e9680c33fabf3ccef2dee174c534455ff59050192861d487"): true, + common.HexToHash("0x2ba904799d897512afaaadcd85c2e11b3675b8dcf6e6414733e3a3378167f2ce"): true, + common.HexToHash("0x6fabe802d290ef68e711caa00018a228b9587191966489a1f3ab9b1e6d67d7f0"): true, + common.HexToHash("0x79436fed2fe0373eee9b2795893e7f1e68144dcb381413ca561b2cc7efda15e0"): true, + common.HexToHash("0xd29f95616da2586ba3e9e4988fc7e341dad67b4a0398a8750b25ea32cbb93234"): true, + common.HexToHash("0x61508f6efe648f4faf57b05bb82b041cbb6389b06f480cb203571288b690c002"): true, + common.HexToHash("0xfbc5d879d69b83bec8e287c0f78048c5e7c015cda6f4011f4f5e024a1aef7c8a"): true, + common.HexToHash("0x4e1d026d7475ec79bc2933c73027bfaac0eb082fa43586247b6feb180a2a4f23"): true, + common.HexToHash("0x23bea8b608b66268b1140a6fce1bee3e54abee55128365b4988e73feaf9ba71a"): true, + common.HexToHash("0xee6a2e30441f26b6c5e9c7cf2fb9b7b56da9794acc2fd8caef346f36b7552052"): true, + common.HexToHash("0x1b0e4c7d5cfbc876828e4bf007966f32e69cc6369ede75dbeebc914cbf96d164"): true, + common.HexToHash("0xed31a6bd1fe765e4f6324c29b2e310a237537eb7d7bbdc6d2e10fa3119e44732"): true, + common.HexToHash("0x77f51e859611835ff2ca4adfe4b945924ff4d3b20884135e2c4ddb282fcb7029"): true, + common.HexToHash("0x7e7d78fa3c75cd4b1a9e267c01a3c04bd3b99c09f237ff85fee28e4c6c1a7f42"): true, + common.HexToHash("0xaf4e302af74f190c81f188e184d1347ceaff52b01a91b634c81ab596e733bb17"): true, + common.HexToHash("0x3a14c10d07bd3480685e4d0c186571ce8553a317ff1978d406122aa6992c19e1"): true, + common.HexToHash("0xc02cfaa823e41b2e0f0186c0eae9f15726b0aa8c66dcb862cc6ca597895c64fd"): true, + common.HexToHash("0xa2904a3b8b1f45f5a99315fcd47bef304beeec4af439010b702beaac0cfcab64"): true, + common.HexToHash("0xffc034e56c3f0eab661a113df6c8ffd61101c9c9b165998cd6992191d3df88e1"): true, + common.HexToHash("0x1714d60762bcf2f29fe1cfc2acc7979aa704cfd3aab910ff14444f1d7203ef82"): true, + common.HexToHash("0x2b3316589a474f2e1421c0206a7bb262aaa20db56dc4c23ff78ae7755569257b"): true, + common.HexToHash("0xac78aa3a765d1e066917eb2690abcff01a89c5e0f726b59c6fa382f57907b26b"): true, + common.HexToHash("0x415b3e3e83f082d0107c29c9651d71bf8df9447121eac5447f2e516a043c80ab"): true, + common.HexToHash("0x067bda44d850ac6fbcc8d1edd0605010ef44046cce00bf019d830e19a82b31a0"): true, + common.HexToHash("0xdc30cc93286884b92f493b253b85e2342f5e335483eb9e8b59d1b6924d0bea01"): true, + common.HexToHash("0xaa4e995922f19cad662eae466ba8b3ef0d817c5058b018c9b349b66156a9070c"): true, + common.HexToHash("0x84376ce4bb38b7f37816b0c6e4574b581c685872d163e3d2bd298b14282113b3"): true, + common.HexToHash("0xd65320145fc56afef8e4066bf9d20ad1586b359666ef690f06594912e4be4ffd"): true, + common.HexToHash("0x61a085cc482fc9bbf11eff935f25b8b190eb82fbeae46d04a1d61430e1ce4aaa"): true, + common.HexToHash("0xdf33497e25ee86b0da5bcfd324a22c6fca70d94b7f99ae569c21509dfc5e9874"): true, + common.HexToHash("0x837b4633fae98e8efd308c579a7a35d9926a66e51eb9e58daa12edb8998bd434"): true, + common.HexToHash("0x2448742e41ddb9b0cd9e3ea2472f08c64074f47696ed94e749d6029c3b450d12"): true, + common.HexToHash("0x2540f12c2b0b73d920c5a1b0df5f0b26791e06eb6e2687fb095b03ad320fc25a"): true, + common.HexToHash("0xb6b5be6873607e1eb05d377d3e03d5074a9f93a375be729c09f414c08be65f63"): true, + common.HexToHash("0x30852cd085b355d18d4bdf61a4aa20a6c9d2af5018d9c095a694cd9382155ee7"): true, + common.HexToHash("0x764ce52459c57d95160ffbc802c0346f4a7fc6a206f4ffd6709669bf99e34c1f"): true, + common.HexToHash("0xb08666a203a127e10019bf3a58ca6442274543b4f81be1c790fd47c870ec10a4"): true, + common.HexToHash("0xa625a1f5386504315a3833f1d4a45e3b968aa62122190144911152bb25a16af1"): true, + common.HexToHash("0x82c4a4cb71eac2b6fa4251a63ec4daff1e31ce0763fe34e22a67bbf66bececcd"): true, + common.HexToHash("0xa5e19ccfc7232ff8ef331ba9e5711e04395657764e861d71868656c2f47dba4b"): true, + common.HexToHash("0x713e4a420202037bbb11b5fbb7178a996618b7898032db58e935399fe7c8c858"): true, + common.HexToHash("0x95f8a370c2bb219c8196fc4567df62e64e3045f9b40aedbab7e3861b30f4b9df"): true, + common.HexToHash("0x28c0b39e3665b2108ab7cdaa0dde73642ff353e7384e99204853ec3ead54153c"): true, + common.HexToHash("0x66b158dd3a3337009231cf23ad3c41d119b0cb5092ab2f5ae21f81b82bc74501"): true, + common.HexToHash("0xc7f518911474b247f970a7625b427d625f989e0ab80ea3fe1a1d4f89ea1aa5e7"): true, + common.HexToHash("0x397e1250137333554c8a6974883b214b2c4531caf5d8163255aaf5f819281d4c"): true, + common.HexToHash("0x3784163652b1c2f11549956cab648365c9242dc7f72d20c20bef76de13ebfdc3"): true, + common.HexToHash("0x91d9817013a0950ad2c5f35932753d4eeb109f3bc578dde6959a0d1f6f07d07d"): true, + common.HexToHash("0x306e25f3fae8174d9ca1a46c87d38bd15a71a42f701ca1bd154372dfa48a23fc"): true, + common.HexToHash("0x637338f23673f35b4c1b365a8bb182c36dfe1fde1007ded58d3b26bf160c5e28"): true, + common.HexToHash("0x04aa70d07a397b0c7b316caf994c9759bfc47666752337a89bbfcc5c7b83e9ab"): true, + common.HexToHash("0x6c5b198c62d6a9374305321dedff55de448f5891cb9611ccd643ca40f87a1323"): true, + common.HexToHash("0x0abf92a4ef432f51701b92855bdc12932714be1360bbbac59d7eb9dbb8db3a45"): true, + common.HexToHash("0x5cf2beac534164333a73af7ea538d55a2a16e48a6bef139bbb55ef20b07aa4c4"): true, + common.HexToHash("0xb74cbc037987a006c25cd8eeb8a5eccd2a75e7dd25644d733b6d673bdee747e3"): true, + common.HexToHash("0xb75b5db95833619c04c3251ac3b0574b5fff89b1d98b96cda41e54100d477d35"): true, + common.HexToHash("0x4f936c8325f2a2cc5be6ecb1b3fa230911a5e4b334ea0175beb20bc93ab2f862"): true, + common.HexToHash("0xe52a456afad03383b171a490a33cfd254ab8442bccd83baaa775c1972b54269e"): true, + common.HexToHash("0xda214b18bb413953aaa47081ccc4f5e1ce34fe6f82aba18e2101d4ac5d64d09b"): true, + common.HexToHash("0x965782117b08c697fd0ba299a0385212656f34ba4759de1100291b5781f8b80d"): true, + common.HexToHash("0x4b97856306798f94d0a999177f65e9146d10009449981b28b071e038e6ff32a7"): true, + common.HexToHash("0x3700d8f3404b041df56c84d7257477b422c3ab497df8e34a0c3bfda2ec047ac8"): true, + common.HexToHash("0x9fd64313366b3cecfdaa2b45bd2072ca0698d68ed9c471f20e87b57db19f3824"): true, + common.HexToHash("0x411f7810b14f95aa05d40da1de28d1c5d71a56a35c8b0324368a04c20da50b87"): true, + common.HexToHash("0xba6942a4a735d57826326885571d72f47d18544051cc8c1c4a0ddee6add94266"): true, + common.HexToHash("0x0c814de4549761fc5b479583287a6179ef7199c3b5ece045caae21623b22e7d7"): true, + common.HexToHash("0xc7003b287606dd2f57ebc652a3654a16fa26783b1d99b7a7642c87f28b1b22a8"): true, + common.HexToHash("0x85bc9b56151983ef16d3409c09b8ca61fdfd6c26f1e3f0bb6d285cb0120cbc23"): true, + common.HexToHash("0xffa7d3e16c3a3983bd221384e8a772f4ceb9b5cb284164e5d1c0b418e1b58d3b"): true, + common.HexToHash("0xe78a9e1f8e368e35616fe9ffdc8517a9120b7c5c8582ea6b8bda2c7fa79307f5"): true, + common.HexToHash("0xfe4cb25bf3a58f7bd8dc1a8817baad3923f12c7fd1075c6b4eaea2fd922981d6"): true, + common.HexToHash("0x3d0b76d3972c530bbf9d71d72ed33197bf5154531c7d94bef779b5d3b9ca84fc"): true, + common.HexToHash("0x011d3b49fe83eeae1bca3247679bf3ca9e811ca03296c9ecd1696497172bf578"): true, + common.HexToHash("0x10af6c7f89e5bfc24deb697e090751aaf489a1b37d7c7d9a0fabd01f59baacde"): true, + common.HexToHash("0xa87b9d4be651cb16f2703640cae8e8ae979c0f0afd6898c7ef5a2223960ce794"): true, + common.HexToHash("0x8d25c2031e8f3ff51548bd0fdb88f81a0d3436d11751f4dcfce776574d4ffe3e"): true, + common.HexToHash("0x096f7c5ef28fa8f2606b9460a067f8af43fbe2a2b59634355a950b4f894ee967"): true, + common.HexToHash("0x91d6adb439ea2fbf863939ca2c5547c1e0e5cab7e2743648ee57082d3b6a4930"): true, + common.HexToHash("0x17c17dcce06abec883930ec81e13c342291dea37f881a6e2ee653945e3443d83"): true, + common.HexToHash("0x57cd0e29e42cba892c5131c360468d057a7b1ed14a961b7a1a929783e1478d49"): true, + common.HexToHash("0xfc6ebf8eacd35e91acc4e75fd80d386d05a6cd54226c547b1d69047ef8b114e7"): true, + common.HexToHash("0xb87d48762101425130e72a16e749eba52d90746fa6d6690cf69c672d41de627f"): true, + common.HexToHash("0xa5a98884d55abbe99bcfd4f6d6b0610dc871f50cd9d235854979c026973ea7b9"): true, + common.HexToHash("0xfe7203d54a214ad9eb67b869e3f3f011f391b53f8e423d5312f29c32bf7fc3a6"): true, + common.HexToHash("0xd57e7d69314344bb74337db1fee6bf4ce517fe1b3aa4dc58e5a925bfcf2e9bc1"): true, + common.HexToHash("0x5fd6ed365dcbdba9539afaa0279262850486ddae72fa5d4e35788a4a823f9cad"): true, + common.HexToHash("0x97e3bc578802ea8991010551af8ef084d3d25fbecf51741469c399758ed0d6b4"): true, + common.HexToHash("0x23638a8e07213f8cd85f31ffc591623fb223a03a4958d8d3f97814d632cb6f64"): true, + common.HexToHash("0x560c0646ccd436b6544ba30dddb2437296e9021740ebb51501c27caf3f765628"): true, + common.HexToHash("0x8016cccf7c1445398b70cff74ffde1865433927f5e576b0a971a5b8518f4bf48"): true, + common.HexToHash("0x9375e7f5bd53513362eea3e2d3be54f79df31213a8bdd05be9bb545b7df34fec"): true, + common.HexToHash("0x2437406686fda2e0f43c08dbe3ac139aebbce281da17023fe6dde759763c6243"): true, + common.HexToHash("0x55ee0cf82fba56d686c9d6934474ef5d667d236467e9202ce5d3b71271a47e79"): true, + common.HexToHash("0x8b08df4cf4b74000bc2c86c5178fa37b7def874a41e2c3de973c53501bafce61"): true, + common.HexToHash("0x479110e811004c158fae8b35e856cb3745191fa065d262eb3958ef8c2684c1f5"): true, + common.HexToHash("0x13fa44072c313465670ca7e188229e844f1fb64b1cb80b2b1072d8d3508dfcce"): true, + common.HexToHash("0x98136db79faeac93bc9c13d7b4b0ebb0cb95e2854ec3096911d921ed4f0d6c62"): true, + common.HexToHash("0x6f2d062c324b7919b46bfdf9e1b48e73ef50ba91e0283acd1a74cf895b228d99"): true, + common.HexToHash("0x6c9ba57b8ec04b773babbb5f212823efbacd6a987e9a8c8fd99a08abc8e5c47b"): true, + common.HexToHash("0x79f45bb907b325497d2ef07e08751594c036416d5cd546972c012aeae1148c0d"): true, + common.HexToHash("0x47b9200af3b3e1b2d985cf70be81d64fd473e215ff4f919ca6c1a5f8a9a565c5"): true, + common.HexToHash("0x5ead621c4f6052d7e05f66df8faef9db9baaa1140873f78d3574c58875d151b2"): true, + common.HexToHash("0x374a9f7b4dfe5f7cafecee73cfdbdd8b494adbd35e266bccdaaf8032cf4ad7d7"): true, + common.HexToHash("0xa973fa2fc0172aae14d498902b330e596886cfcade5abeac99c41318e2e0dd3c"): true, + common.HexToHash("0x5e6c5ac1396d7da45ab9257f872c6b5be8cbb1a3b4288b6350ce21efc6a83e0a"): true, + common.HexToHash("0x65ac37b153126e62f20d48f13f66c2e43436d7df1e692cdcf1625b61557e5af2"): true, + common.HexToHash("0xadfc8460d61591b2794c0034099fea0d1951eac43d31e504ccdc0d56faef38bc"): true, + common.HexToHash("0xa2edefde6ffc578f647787b2765612965ebc7f2e7f5ffbe32fe0829d535af902"): true, + common.HexToHash("0x6959bedc577eee28a84436cd86853c122d16dd7ed02e7e3e87967e4f6533425f"): true, + common.HexToHash("0xc49ff9685864c39b73448b18ce020a5a0df499a8e0243687f6b841feab25c776"): true, + common.HexToHash("0x53397119b4d98cc7d877dd6e5575ecf725fc15de21cd68e52bc524b88ea60b56"): true, + common.HexToHash("0xb6c80d673d36825d6553ac92118d10a720b7125f9782d485357d00faae86e121"): true, + common.HexToHash("0xf93e3ad7f66f822e15379aa025791cd30e79e78ffb5eeb30e89f9398971eb886"): true, + common.HexToHash("0xafee3f37cb5c7a5cf8493538ad4dd4484c6d66eac3a2caa035c4b01421055302"): true, + common.HexToHash("0xe70e21d3b89bbac62ab7a35c128bfd953019f2c797c696ef7788401137cab07e"): true, + common.HexToHash("0x7757d19b39ab8e0c9c1c04089d9a189151e52885d88bb477f1d1ca705de2aced"): true, + common.HexToHash("0x222f675fca2605791a3ee5c0bb4d51336d38fca1abd3ee0fa451e9522ad087f5"): true, + common.HexToHash("0x3e487a7a0cfe19f471a30101a3ca25dc116a057466f400aa54418db8ebabd062"): true, + common.HexToHash("0xaaa046b7755351ee3ce4a8174b888ceb66e18e5603275c76df550a016c631c6f"): true, + common.HexToHash("0x94565b298c39009b9581798332b170d5f453d837386aef53c0a6e257e9f6397e"): true, + common.HexToHash("0x89e6e938eed64568f01649929b3a23bee5e420d3c6f188c2e886815f77cbe8c3"): true, + common.HexToHash("0xfbcc734f47c87527ceb2fe823f25f25fd5c475881ff1dc145f1cd058295b026e"): true, + common.HexToHash("0xfe23733578302ec746d59d7c414228706804346b80ff472fbb38495178544645"): true, + common.HexToHash("0xde067cf611d8052abe7a3576d3717cf4acd60e07d82bb40ca2da4f611466d1ee"): true, + common.HexToHash("0xc16f9e6ff6ade909b6bc7fa53275d27d57068ebac8caade9ab09fa98bf4f033a"): true, + common.HexToHash("0x5bb73b8a6a829bf678ecbca6efb9eda3bf20a3290e5574877231528ae1e4fc6b"): true, + common.HexToHash("0x4acb8174dfcbc25082b288bb77fb9d1c27ae472df67115aa9823959eeda0aee2"): true, + common.HexToHash("0xbd22699f33b083919658b0257a71d8624137410e6c572abf7b1d8b4f92ae573f"): true, + common.HexToHash("0xf673e3a1999d5c7b4dedb743117ef5f2e3f08b2651e09c3ae1a1dcee4a0cd388"): true, + common.HexToHash("0x73dc0f1728cded570940b8adb2c223b6dd6b409a36b83a24c5bc799dffd67eab"): true, + common.HexToHash("0x196396ca948d2c2ebc8ee185de26dcb9bcffff840bd321efa7bf9f7de23a634a"): true, + common.HexToHash("0x72b31b1ef325d903b6ad77e1a4065843fa180f6b1bcac5b987dd835afa54e27e"): true, + common.HexToHash("0xbdc9affe19441b6477482768877a33a283a1315e4e2a44f9f68bad1a181d0f3d"): true, + common.HexToHash("0x9a09518fd1fb88178f09778670abc99b657d97f1d58185e19bc2f6f61c37c041"): true, + common.HexToHash("0xebfd94b7a8962ff1f782f5aa0a479a7d90301a7e9d775763af8e803458fefde3"): true, + common.HexToHash("0x63f8c7d8cb3ff85512012d79b82c7dd02bfe8631c901d29a400302bf74d64a1d"): true, + common.HexToHash("0x015711d6237032fc6d57a85f080da630077eb50c779399ca1795aef7df50d954"): true, + common.HexToHash("0x6b27dfdc0dc8879f9d020dd2aaf436d5d33b7517fe7400c0451c4d2eea953e0f"): true, + common.HexToHash("0xbb2f6ef6e7ef9120ff93d6cd7ed00ac3de5ad4ea982f44b131ec0b043b9ec38c"): true, + common.HexToHash("0x9dbaa0f60c5641acfebe91d3308fd17d9519fce78e50663837937e2a058de347"): true, + common.HexToHash("0xf18c0712b9b0deed0c482111961d0e22953a513e47ab2c2336e6004e071dc430"): true, + common.HexToHash("0x7b4913fe846f00f551480ec579eaa7889e9940a9e86b2b54a05bfa1ade35239b"): true, + common.HexToHash("0x3e81bd7e60800d987330a2901634c032ad74a32607ab1c7c86a9131934e7c5de"): true, + common.HexToHash("0x4d19b1cc282a1989b0f7754f1919c5de6b646937958b820159d09e04b2ec3715"): true, + common.HexToHash("0x2b4c453cf4006390f0e627498b2ec2136f82940da5fee624efb3b328d06f3b92"): true, + common.HexToHash("0x3684212c333f58d6cc227a4d844b8fc105328de2dc52e7f74dc99b341cce64ab"): true, + common.HexToHash("0x4dea4d61bd325cb9460bafa791b3902816719b4dd1d8c34ee16c0a6a280258ab"): true, + common.HexToHash("0x24e2af3cf8e97165e34c8be12280dfbed00b939627dc6f921c54c0a61154eff9"): true, + common.HexToHash("0xda60df90faca51101462d3f2c1762b9cf3bdd859cb175725871bf9c37c34e0b3"): true, + common.HexToHash("0xc9cbc5eb2bd8fb61bc63c6b437ab28ac20b3d45c566b2219f6c241eb98283c06"): true, + common.HexToHash("0xe073508d2f6f89dc49208d2200d0a5c0cc8990e95e34d43fb234829cacdc789b"): true, + common.HexToHash("0xe992d3826ad40828dc92345aea6bfdeeb19dd7f63106884c4e7a15b764ffef80"): true, + common.HexToHash("0xd3e3789b5fec0263577772ecd5c7d85138cb06dd049328ec3df9dd59815ae545"): true, + common.HexToHash("0x3dbe2ad0468603096f2448a4fadfe792c03ad04321fd66b7a95e7be631f36815"): true, + common.HexToHash("0x79cf3a8cfeb37dfc69cb6c04243cc2ba75008bc621b3438555bb1d035202bf0b"): true, + common.HexToHash("0x2cefef9f44feef5cf289751bf8f95a573b1ce88b652da6f00dd996e8212dde0b"): true, + common.HexToHash("0xf7d307a1e6876bf26aedb03d1e289cf4a1d463fb4ffc102c5e268be345e30e21"): true, + common.HexToHash("0xf6f23588c4abf07d896d24c15c7e438faed126c9304fe3ded48ed8dac573ca2a"): true, + common.HexToHash("0xcc56f7e9341c80c00da272d4ad7ed0f25349f273b635bdee9e93acd57a3ed1bd"): true, + common.HexToHash("0xbb6bab2008851a7b465b2d293c6810c4a6f345863d5f15fee7baca78b91299b2"): true, + common.HexToHash("0xc4e33496cbab3adcaa7f6fb997cd60d0d5d4e362c6c8f59b460f57aa56d358dc"): true, + common.HexToHash("0xe15295a53d6653f1f39aaa2640851f513512f5f8c8be26cdcbc126d1e54c78dc"): true, + common.HexToHash("0xf34f434afe1dfe623af8aef3f02f572121d46d902934f2f1be26ddb2425584e5"): true, + common.HexToHash("0x53c51474d9346ac8235771d2c76840e9dff9f4bbea9ecd1b16808d5436e31fe6"): true, + common.HexToHash("0xdab8c8a3299623825ecde97dcbce841c7a545e5d109dccfd56bbb0d540dffa44"): true, + common.HexToHash("0xf46c94255db2eec3e7155511600b646d967b5f959feec9fcfcdc7ddc6e0c8fc9"): true, + common.HexToHash("0xd5ce592422584e205215ac29d3db9dffef3e39e3e54ecb83b7496484f8743085"): true, + common.HexToHash("0x4af26d830ed7745669cfb1dd785b45cfd49ac363f0c8d829798b5cd713e8c33b"): true, + common.HexToHash("0xc6104c706c66697ffe82801ca9ddc3c4e9aedf3da1a20e6952f864a97d84b599"): true, + common.HexToHash("0x5422378c3268bdd46894dd04419715391689d62e4c6ae6052cfd4de4e0b4d83e"): true, + common.HexToHash("0xe7428f6b680d999e0b4d65282a4103519a067dca8651d575898a1b975d5ba45e"): true, + common.HexToHash("0x80f36a4c4b1a9addb2a3b20c9a10de77579ae1d09ef13eb8fa37ee9db34ffb43"): true, + common.HexToHash("0x9740ec382b3775c259c3e35e7f6f31383baddf36b5dae94c9f74a714308a0473"): true, + common.HexToHash("0xc0f11dc8b6afbd5129cb01a31f6dd06050bf0aae5660644be2c7e7ed24f88918"): true, + common.HexToHash("0x9839aa47aac33f1478052ad9acac4f4be8f3a75860fdade78a59114e281e0a32"): true, + common.HexToHash("0x70d74500fa202644511e572d8b040b23988e16c846333d88d3796f39754c6511"): true, + common.HexToHash("0x0d9138afd7df810b002b55e2609a34334759e89fdea55af42b2ac4c6a258574b"): true, + common.HexToHash("0xc287c48ae2bdc21995febd84e9bb90d641e36528091eb1d46fa92d35138e220b"): true, + common.HexToHash("0x0c8c813038449f50c5000f1a7e2426c66e689a8cec03b1e723ed992f542b7cb9"): true, + common.HexToHash("0x6817020df8b49708edb8299501b4e21efeec88dc50d59ba43df40d041bb8c2f0"): true, + common.HexToHash("0x34c58961b0ec0b537713736b83af3de06f92239997b868cbce0a44a6b0bb22a6"): true, + common.HexToHash("0xbd6171572d7e2ca338e2dd67e48f7932cdb1482dda2920c5c7b011e7f3592e9f"): true, + common.HexToHash("0x56368e2df1d1e875bc6cddb15b1fbb1e534bdfdb1ab0738dbf2837dfaaa3cd62"): true, + common.HexToHash("0x9040df7c0dc98f6d4f92891ff66812b24ad2788e80801f4ad85457eaa54ac280"): true, + common.HexToHash("0xb41eecbf5f15aab217e04c268473e5448c72f59a997714195638dc7982c45bc2"): true, + common.HexToHash("0x6293ce4275d1956481f451dfe9a91529a343ad8cc5c436bede1b8d8179fed22e"): true, + common.HexToHash("0x6b7f695184961341eb61f758e5b8b0fbba960f4ae3b9d301e731c435d6e8e597"): true, + common.HexToHash("0x99bbb53d74e970d8da6c8deb74ebb1f6922eedd81eec293ce857ee699c06d201"): true, + common.HexToHash("0xae94468bc57ef3fb18e31943687d6240a66cba016b2f42698202fb90cb4fabc9"): true, + common.HexToHash("0x037ea1ab177555d0a17ca152b8d633d621e73a1da3b1a01f1e8ddef813cfa52e"): true, + common.HexToHash("0x70fc68f1d4fcf6091458f7cf821b496012cd6f135236db2fc2985687430cc4d3"): true, + common.HexToHash("0xa1a87b2f2152f7a063e49c9ca3a54f40f6dcc59ad03e651d59ac97d72692ea4e"): true, + common.HexToHash("0xf7ca7cbbf00baa8ed6bab4f6969fc9b598588555120fbeb658d1a48e7213604c"): true, + common.HexToHash("0xb5c65a68da4ddaf9ecf7cf8da2a8876cd5476baa3fc5dfbc8947c656da4f9eac"): true, + common.HexToHash("0xed3975555575afc2bd90f19f276c033d3e12e8d9a54239ba1fb4fc7afefcc2ac"): true, + common.HexToHash("0x75051c3278d67bcf1a6104432200fa926e3027ba0487a4cde6562becc7cd248e"): true, + common.HexToHash("0xccb28dc6fa01fb970277279aa3e4ec7f77ba56552183245353a6ac3d85972ea9"): true, + common.HexToHash("0xf1ec13bd54f7964ef24000647efceee3add2622b7a711bf48c31bd66df0dc0d3"): true, + common.HexToHash("0xacf70b1bfdbe45410bd9ed9a08d4e00c07bca299163ce6ae697748e50774296f"): true, + common.HexToHash("0x72e02662fdeec517e4683c103cefd84090c92928b58405106069ac486178c2ad"): true, + common.HexToHash("0xe58ee418cb0cd4aab862f429bac34985ec3f3374d686cbe5476b4426fd081cbd"): true, + common.HexToHash("0x30555e8641263fab2e0cf9416c9b1a3e01b7fb90a33ff3d79a55673402c58804"): true, + common.HexToHash("0xaba4e0578d3f7c4affe811f7e39d7cd556ba0d2dabbfa7ba2a61e813cb0f1afa"): true, + common.HexToHash("0x01cb3b289623a7de7a57a7db2c39278f8610ed3c5c74469f84081c78b2844677"): true, + common.HexToHash("0xe80a2285a925751203d4151871e300850509162e09a6815d7feb2597e6ddbd3e"): true, + common.HexToHash("0xde043c6b7a505d572b1ae990a095d58aa41e34e07c8d885eba2d37568dd116a4"): true, + common.HexToHash("0xbc814d7b79a41f18d6fdf0447154fc19262fa7c1d8af12b6c228abe26f37adbf"): true, + common.HexToHash("0x23001c3091e8cf410fb6151bd6bae7fb4945698a34fb3dfb672e903221d1e9af"): true, + common.HexToHash("0xad1db7cbfb8d9421eec3358ac4e1be1d5c0663cb1f41581b19cbf391cdaebc8a"): true, + common.HexToHash("0x7142e2643a496eac6b326049d9671702e3989050ecd6620c99259d9c8199d776"): true, + common.HexToHash("0xb2ee78716ee08a7a79ad1ccdcfe41f1bdc9c5d986e4c35aeddf87ca12405104d"): true, + common.HexToHash("0x3ac7259b284d0a705420112dea4512827585404e612c91800388f148286914ed"): true, + common.HexToHash("0x7de9e50266c9c701f36a758cc2178d6882a2018654862a78e3b01e04fdb83604"): true, + common.HexToHash("0x45ede993d127c5ff7fb1574b7821914c2fa210ad27511478eeca78a664b44477"): true, + common.HexToHash("0x9291dfc9fb1b0f53b256a2e16af586c1257a0e22de8587c8f9854289b99f5923"): true, + common.HexToHash("0xd70080134b65850e8c7b940c91b32370d8e4c6614f8f9a3847fea767fe53190d"): true, + common.HexToHash("0x2c22a096d4349ed7c42feba2625915767d9a2f4f2454631011d767c00492c24e"): true, + common.HexToHash("0xae14db947c57864dca03b5d809b3b3ee83f66836775aa74f10e33b148d5868d7"): true, + common.HexToHash("0x61d276032e30679c0fc68b47240aabc915de4f482644ead6b70b5e24ff1bea0e"): true, + common.HexToHash("0x47e968ad7c55eccd344a227f84e2c99b1419c9b731797f3e4e5d86df5da1e64c"): true, + common.HexToHash("0x18b7ad286b49210b0b233554fdfbc0858f402967ff73fd1cd5e0b6fe72ea9e27"): true, + common.HexToHash("0x3ae27678a02dd0369d7aad6de6f0d0d517bf935faf73f1a3d99dbada2c8fbd77"): true, + common.HexToHash("0xc818b302cb8f447f7c996759fe5422845e24915f8313bf187326fe15d32b228b"): true, + common.HexToHash("0xe169b03d637734de82d9ffc2612bcfbc39ce91b281ce68739f52ce8632688cc4"): true, + common.HexToHash("0x61eeb67c978367386141810b649ca7ae3af5c3cfebe3d6237aa31d68b68be1f4"): true, + common.HexToHash("0x4fd79f807b56dbc73c3c3bd011942d585f345efebb0cac4764801ae9040001cc"): true, + common.HexToHash("0x86f7b7e2d1cef7cb964622af5fc198316328ef7cad4b59e17cbccb074b47537b"): true, + common.HexToHash("0x3c52079d804a2eb68452f4d9817d119ff83b52efd1021a6dc96da1346ae5f995"): true, + common.HexToHash("0xd3cd8a3412a7bb0ec759aa3725ff3da32d20bc121a7fab765762776a3b6f7b93"): true, + common.HexToHash("0x52c63c8f8d33d9e413119d4eb5ea45f43cb09e8a17aec8106663668b07064ff7"): true, + common.HexToHash("0x1a8bbe7724978b1fbaa5479bb1908875a07c8491081f6dff0efae9a4d6a51e6f"): true, + common.HexToHash("0xddeadc024aa385432cf06717cc5dcf08d6bfeebfefec06d3309736ec1cbbc31b"): true, + common.HexToHash("0xb37b608b57a27721566267fadbf2fa00e3f1b0f487c8cc7ba27a354d8a356aaf"): true, + common.HexToHash("0x0d2db844f65cf6b258d8fa871361985320da553898e535a0d329d554aa1a67b1"): true, + common.HexToHash("0x256311fa181dabee50512b68d61dea6d76fe2e989955f315ebde9e33d985cbba"): true, + common.HexToHash("0x8cd4844739205f2f0f9662f2cb2e95b19f214bedcf496ec9bf5d4ee29d7a6425"): true, + common.HexToHash("0xe645e8ed1443496a02a58dc967aec2b87437cf20c18b8a1799a456c64ec0912d"): true, + common.HexToHash("0xb7d5ccae7939901d3ce7852794e7eb1564b8ae5c3455383540fc81746321ef86"): true, + common.HexToHash("0x3b18845b9349a6a5629fb7f64dd4ccdf01b8f239c65cde103b932c5167b4c6df"): true, + common.HexToHash("0xaeddc995a64427df2b5aa2848d1809dacfc8af9be510512a6d86964df7b54e4b"): true, + common.HexToHash("0x2626fe494a78ed5fcc52954b8a4714f76b30d28874fa96426c3b0ad4165bfdc6"): true, + common.HexToHash("0x2e11c6eb58adf56518af390ae20fc240a48f9a2ece2deb5ac521d2ee4f2f6146"): true, + common.HexToHash("0x09ca36d5a4658c3b7fdab8d0bb5486b575c0809861671fa6b0e297b7e3cac607"): true, + common.HexToHash("0x3ae694a1011e835284ac580de7b95fd8d4724f87fd6ae92d8255d45b9d3d8872"): true, + common.HexToHash("0x5c66e2cd2b3632e56ddd201c692b1c2ea40322e9f66183bcd0f3c820236ad410"): true, + common.HexToHash("0xed9867a95f52d15c95cb9554a5aff858f5ee8f52793525a5fc3c424d15418105"): true, + common.HexToHash("0xd620b5cc48aa241f4ea9948b1d504a6b128525fecc9718ad09354ffbd57a9785"): true, + common.HexToHash("0xd8c463135f7b4fd7ebc21093f4629e714b85fec07a117dce66b0adb9145fff4a"): true, + common.HexToHash("0x21675e1aa4cd50b8300bcbef964ff6511d2de1adcf666f6225f7f8fbfff65e16"): true, + common.HexToHash("0x9d7bfaed292f95cfb03f6dc034de5e75d5ce5f068f7f6c70b9d0663821efe9af"): true, + common.HexToHash("0x8a4d876a17011263c77d838c0c55caea9dcb7fece14a1f3c26b720a536721226"): true, + common.HexToHash("0xce510cdf32bb7ca3f2f93244fbbce260d2ec8ad14a957902b195430197932e8c"): true, + common.HexToHash("0xfc9ca226cb0dbdb121431e15ebe23a887e70811014fca5811eaab4669efe9dc1"): true, + common.HexToHash("0xfd752e016b1cca39da990ba5345da3153de0fc88870aa8fab340363065b90d85"): true, + common.HexToHash("0xac61f87114d15a34dfdd339b1fd3c42209a94191fa0c8b6fe8015ab99e750743"): true, + common.HexToHash("0xd0c5ce0edea16500c18c096d4ec1801e2ef77818d4e1952be54e8036f3a1b0c0"): true, + common.HexToHash("0x87793261ecfa3d797ee8163147ed36a38dd481c33ca1a5485266f34405c7d376"): true, + common.HexToHash("0x135d7dfb1fa281463f1a00717e85013a174c4b2d391219da1778c2dee22dc62c"): true, + common.HexToHash("0x21f0d166df908a7fe0ec1b31f7f0aadcaa16db1b18ed040c59843eded799033e"): true, + common.HexToHash("0xdf0977e92d851089e1d50e4db05e227a3dd923974fb2c1b07a1e74e3a9e0cee5"): true, + common.HexToHash("0xf963d805f71dd671424b53b497daebae583ba149d6ce33b9937a449551f34ce9"): true, + common.HexToHash("0x1f65d40f55da432b877dd1a781ae0165143b8efd2570bb7afb48850cd11ba4ef"): true, + common.HexToHash("0xce116ba3b476928836cbfd72f6a42b4ddc492451d01695bea055b6d3e501d377"): true, + common.HexToHash("0xf73f5a9140f76259acba5a9055edd29bf3aa5f28c842f81ef344db53ed5b11a6"): true, + common.HexToHash("0x0184d70380170ebb54e79d324a8f60e52ba2fa55a07a3fa040c077ffb5d2804d"): true, + common.HexToHash("0x295a3071a7408d53a0079ca9607c5f081b595787b6ccc408cb46480bcc509af6"): true, + common.HexToHash("0xdd10c02246e49d13bfcdcfdf62d9c0928693f4d233d7883c58869ee0d9811900"): true, + common.HexToHash("0x6118db0d7ddcb165ea8c16cb389f07ef27e26a90cfe68c8e0c84cf08518b7ca8"): true, + common.HexToHash("0x4e553e04de7c93f09c0e338518f880b45561cd2e948e305f0e244d2fa8d27736"): true, + common.HexToHash("0x962667e25199317f6600d09b1614361fd789cdffb415bfd14a9f248ea80404f6"): true, + common.HexToHash("0x3a25db8e1341a3b2edccdd1be5cb69d709c8149c3621d65fee3172b71274dd9b"): true, + common.HexToHash("0x5f4f88ebf082c55b66696d870968e1a85cd8cc7def8d62564ae4a38fcd8c2a66"): true, + common.HexToHash("0xea79592ad35e8b6a269ee7dfd1e2e50e2a08a2f784ca606237cd50809583d2d3"): true, + common.HexToHash("0x0e79756cd41a150c0bfe614289c3231f9496c22ec07181a5fb5426e05d81a068"): true, + common.HexToHash("0x736c00eb2697b7aad560124479a9e0efa50b8fec6e93690cbcd209f0369d18d9"): true, + common.HexToHash("0x9402549c35021dfe2ec686312331e290c3dbed1d63e5c43ff71ad9168119686b"): true, + common.HexToHash("0x1a7b81f8f962704955d6b7fb9fe0fb7b0b50eea42db84ff69e92ee7d60688d7b"): true, + common.HexToHash("0x25f12dc3caebfe7b75847a27729ec1cc6d6a389d2d52dbc396733492e1cd43b6"): true, + common.HexToHash("0x36b1b69a2c1a92738cdd712548263ea5e08fc5e5c26a6502988ea8823b54df41"): true, + common.HexToHash("0xd215eedeb8f74a0d30736ccf573824e35cd6a20654b359784649b52b30edfe51"): true, + common.HexToHash("0x2afe5c8606f805eb2316180ac701343fe03821925ff98530d9d199e0d03a6c08"): true, + common.HexToHash("0x7b6c4383738bf874c7c4f24aca2ab40b40f125eef432b5a83ce144d4dbf1ffac"): true, + common.HexToHash("0x29a9febed6006507b24042c31a88c3be16f779d661f2d8d9d75c655b55525d70"): true, + common.HexToHash("0xba7af688c88cdc41e499a56a5439d1a3d8c11704aeb5e17753c550f7370a3eb6"): true, + common.HexToHash("0xbbc3965413f8b2be346a11b8dac5fff4221a47c09f703bec61187b5ea03903ab"): true, + common.HexToHash("0x0a2669a6b7ca1876b987bcc8d2e6e8e997d1afe288ae891643ce86d0c3e86928"): true, + common.HexToHash("0x35f67fd3ee14c9823d2be6453d9c18d721830d3601c9d54a0a9f75e2fc4cdd64"): true, + common.HexToHash("0xe340da82c20f6936182efdb9fc208d3b3afc74faa4bd4214ea5dd7cfb6fbb879"): true, + common.HexToHash("0x92c5b4545a4437155a50936fa9c589d3563690183980038ab0b1361a591e5113"): true, + common.HexToHash("0x17d350f9f185bdf55151209da9b0f85912d101951814afe094b40b9aecc0b51b"): true, + common.HexToHash("0x05985c61186733e9fda2924a7a59a0350e6fbccdc7126d87b4219aa7f72200b5"): true, + common.HexToHash("0x75397c90092912ae11400d4cc23e1551a3529bf2eb4f1463d335f8922bce319d"): true, + common.HexToHash("0x20f6fd298b09a422daebb6df5f1660093d40e431d08f5bbc1357ee9733925182"): true, + common.HexToHash("0xbc9ab8da59436c3b0fa17244c144120e89558d213ff02fb6e7df840b7b11b350"): true, + common.HexToHash("0x09807bbb54eda123a774a0b4b120743d6b1332e2ad3ad21bb00fa84fdb4b4eae"): true, + common.HexToHash("0xb08da634d0b32853d3aab70a03a19f8168656205916af2a6b370b2e043ae4941"): true, + common.HexToHash("0x8f6039c1ea778bb092c21ed7230b06e5d3b3692336e2a44e19e7ab2d7f93fd0c"): true, + common.HexToHash("0x2af4aadb4171644d68652ceb9b22685efc4e7c72537b5d8fc1cd7b89994056c2"): true, + common.HexToHash("0x6953b8149a6a221d9da50909ca80080a58c8b04535d11eaef13fc3874cbd5654"): true, + common.HexToHash("0xac7ca7db89c9466aea21f26f142663d883589652b21147cd0caac5ea8fc69eb2"): true, + common.HexToHash("0x4d2f71a4c521bfbe90d45037dd6e34228a0b5358c7eef112f30ccef60099b8a0"): true, + common.HexToHash("0xbd53ec9d828e221cf9f617cc5aca4b6e33d8d1c87807acc9a596854964429342"): true, + common.HexToHash("0x51b2a238e7283ae52cca469fe6a24320a87e90b2587ca882372992e45279e9e7"): true, + common.HexToHash("0x3813e0ee55dc7c1a9d5b63762f623e79cb86f2327c118344f14cb13ee8bd8b2e"): true, + common.HexToHash("0xefbe528a68a49817da00840f996fc3ec4c98d5aa450701f9e8466435a1ce488a"): true, + common.HexToHash("0xd5be1d1fdc75ac9e714a6f2f1dfcaf0707004d1d538a7def51ab7e6e21285ab2"): true, + common.HexToHash("0xbeee1c79bfea811aaa344c8a8e48e7c316073db049c03bb0bd03139d52dc1323"): true, + common.HexToHash("0xc87bd845d11461f4cbb5e8946927f06bcbbad0d04592770cf17feb6a230bf965"): true, + common.HexToHash("0x21ce248ca06bed29b5d9c23e6bf3e621e436e6c0f51a130696d7410450495700"): true, + common.HexToHash("0xd3018869cf553e7143ebaa05b0b6e595ec3fce09309a3c6aa7ef569bab926b0b"): true, + common.HexToHash("0x3c3be31f83a2c9d4a364c6a13ca899c72afe2ae1289ab412031aa6d9f376b696"): true, + common.HexToHash("0x78be7ce90a5681fa038ba064a298aaad6a88b084596d3ebb3eccec36cf72a0e5"): true, + common.HexToHash("0xff848eba8c6180a3fe207b41c878faec6ac539e9298c19749eed737867564af6"): true, + common.HexToHash("0x35170018b47693a1e91f3ee146c09aca974306e94cfd77a353256d8ad5a1854d"): true, + common.HexToHash("0xf1339bc6f89f71d5c1d5711c7c5b2c53081122bb1dc16eefdaa33071bb519bfa"): true, + common.HexToHash("0x90c00570cf2c7fbb31595420dc524ed57f94c2a8d2cf7b4b6a440fcb1752bf1a"): true, + common.HexToHash("0xc70c9d394239c92a72f5862b745f48c53e56d762dab7c8113d46cd68406c6fbf"): true, + common.HexToHash("0x3ecf119fbc05857b4f84990730d88d84146f717d31377e8e18e0255987c96e56"): true, + common.HexToHash("0xa20c2f30622025e947a902a9afd53b18aaba37297c63b519d6073bddf1feba85"): true, + common.HexToHash("0x135e8e6e421f6c28b4bd2cb1c030bac3b6723b91bb1d770f3cea9f33e73eb688"): true, + common.HexToHash("0xc221f192490d244cea426a2ad7d34f84618b883aa3d2c59554a48eefb205b77b"): true, + common.HexToHash("0xa4999bcb694641afa349fed40ac5df0af2544e8d2b3d8f86f24dbbfea696ef4b"): true, + common.HexToHash("0x6af8eae3fb993dfa84db39aee5436f950e75f2c06f72e8c17ddfeab7f9025629"): true, + common.HexToHash("0x4f91145738ad08332c292f8f7c4465237e5bb2eb567758f961d8ef9597992eef"): true, + common.HexToHash("0x9ec2deb4263d80ad83704ffa0f8ffb3c23a54fd9c4a42063a84f27260cca858d"): true, + common.HexToHash("0xf5bd3529350f576ec1b8f19a5bf6df2207e2cde3e34d3bc5b071096a66486f72"): true, + common.HexToHash("0x04563b93ebdb50e6630ee108e5726faa36b4e674c819e689dfe020fce8dc3dcd"): true, + common.HexToHash("0xe884442d2496616df395b0b41c7f3623e073b134d5c6c6e7972270f2b124845f"): true, + common.HexToHash("0xb888e8ff7394649bea8e4fe1c1756db172ef748ee21cbb662a9b00addad78aa1"): true, + common.HexToHash("0x67a5ad8afd3bca9c1458b491e610ffa9782b5f143e1eec2f09d2e893913c4aa9"): true, + common.HexToHash("0xda85ab0f298845430891365e241e553c4a53790eedeadad12aee7045a4027df9"): true, + common.HexToHash("0x845294f18c12eeac733d9d53115b2c84c6d425ffabd2c26cd87d8b6635feb31f"): true, + common.HexToHash("0x1066806a076d84f8b20a8852f50b8e2b14c02e43fd5e9ce7247a0971e6f58959"): true, + common.HexToHash("0xa34416e8640f0d54169ba3684bf2d6a5844152bccd2230cb45a44bb2803dda58"): true, + common.HexToHash("0x5d5441de837c4a8be41ffe46fb204181cb9a4a8bee9cb491329f0044d708720c"): true, + common.HexToHash("0xce587efe529df2c40fbefad0e9683034ccf7473ca8f5a660a22140baf9fd0a78"): true, + common.HexToHash("0xb55bacabd4233616819d94220113e0136ab9374e2069e9e729d3844d2c04c154"): true, + common.HexToHash("0x45a5abea58cab6ae39e9989d1e36f1c2f3480c76c52f2ea890887193d512ba69"): true, + common.HexToHash("0xdcab222e3db757bd59995f76aa1641eed224408335878909afdab606b4f3bb6d"): true, + common.HexToHash("0xc36d5d92add7998b3e5af5299b7933c0aa7c69f743ae985a315fd142487e27d4"): true, + common.HexToHash("0x07ce4b8dee995c5013599b85eff27acc37ad6cbe74d5f280d8b84e25c11b9113"): true, + common.HexToHash("0xbbfe93c7cdb0d0edf8e7be7d17005090a969d418b1792b4e7710815d104f8b20"): true, + common.HexToHash("0xc8a1fdbc3fe79b6257eaa5d3471e7ad23ddd755b66cea0b281157196c92795b9"): true, + common.HexToHash("0xb6bb6869a7394b3e67cabe5034f98f4895a1d0b1f0deabb791cb8c82a2a12513"): true, + common.HexToHash("0xf64b1a7b2cb14aa5094e9f97ddd5f4c83b7e045d4c68b048470ad0423180eb54"): true, + common.HexToHash("0xbf3330119140120d98531f16677c751fc9d900793f0e89b813c23c73ad65ccc2"): true, + common.HexToHash("0x13a73c7e88ddcd4279796912f3837555e859ee2ab2dad9f0d57bdeb9162662c4"): true, + common.HexToHash("0x409247afdbcf2ab587bbcba5ed42efddf7ba906328f9be58ee4052d555680349"): true, + common.HexToHash("0x7c53b81d7fb5c4e787f1902b9702d0881d992a1f3a369e9fe05fc2c95d73e153"): true, + common.HexToHash("0x96b22cfb503c818e9bc648c1f891b97ff46548d20f382bea7d962b05de13de10"): true, + common.HexToHash("0x99b1c472d4d2cdeb008e6ba804f15690d24de94dbe8c16f62e0c894946693cac"): true, + common.HexToHash("0x29478405a54ebf3d1e30bad7f3c913b19f3cfe42ee0b18dd6bc741ff44e53fdd"): true, + common.HexToHash("0x783d4b81ae4d515c5e77af7b544e2958e6f4c2f88c344984e13bd74c5c990cd0"): true, + common.HexToHash("0x5c3701eeef06d45325961da639677da63c8a2b2f36033e7a14e0fbadfa02d3a4"): true, + common.HexToHash("0x6f3d3499013c65dd2411dc8aabc1f913efd30cc12b40ff4005cf039d14671037"): true, + common.HexToHash("0x9772a1f29dc7d6f20c1d31565995ad5370c3ca072a8eec1b6facd44539bdcbb6"): true, + common.HexToHash("0xdae68fc2726d7969720ded8f994d60093d4b7ac77456a9ba4c8dce47c861cb49"): true, + common.HexToHash("0xc9815f2da210419cd0d857cbca57733aaa29760e3033f5bf257abfbca27c142a"): true, + common.HexToHash("0x4aee6495a8f4076b95270f2895fffb521e3580cd48d402340604c9d0934e5898"): true, + common.HexToHash("0x5dff0f445af100b700220057606d25a6cf7e5211ae5a65878fda64600539114e"): true, + common.HexToHash("0xd568d0274f515c5da6a3e68549c149269f29745b81f7bcb41cd9984390fe7da8"): true, + common.HexToHash("0x7604db968d2f83686e0636d5f41e3e8faffd6ac1d90c81a80c9dd33202f2af51"): true, + common.HexToHash("0xe7c7c51f47a3401c33fb7e7d901ab469a362e4b6a87efaa4d1f2be934e9d2c45"): true, + common.HexToHash("0x5c80bf560bd61c6eb9858857d9a60eb0b5f90bbe9cf1822e3a37aa7b2f1fbe23"): true, + common.HexToHash("0xec43e0481eced99a6fda151eb111cec09d0e802f7850d90b182e511629b4e183"): true, + common.HexToHash("0xdd6fc7bc39b261f47583ad95a6658771373407f8d357928c4a73fe5546a19fa3"): true, + common.HexToHash("0x0b62ede11064c1b48b6695fd854ba6e2890bf6dbfc7b63e874ddb181360f886e"): true, + common.HexToHash("0x53a5bb9fccdfe7f8597cde291e49616112fbf92b09d9d4c441ea51231f28b0da"): true, + common.HexToHash("0x8f8048d3057c78809d65e7082a83a2c11f0ab1e0779000a039477a3e43041d37"): true, + common.HexToHash("0xd470f837171296e9b3c94a78286881d9566a59f793829207afc084e0564041e4"): true, + common.HexToHash("0xd52eef957eabae07e798c356cf920eb6114cabeb76a4d214a209593212d9d9bc"): true, + common.HexToHash("0x92668830e74e14c2479be505325a31dc906d3ca252eeee1b0a2a89c9d7facf74"): true, + common.HexToHash("0xc361f0001bda4068339f1f2fca9c5dc83ba06f8d83efe3f8e562722b966f66b7"): true, + common.HexToHash("0xf9987c22f323b120e9d2b3605c530e9f10ffa67d1aaaced5d7defaa59eaac991"): true, + common.HexToHash("0x2dfaa8ce915f31720df3b26fb31e35367ae718f693415f1c74b510c996079bfa"): true, + common.HexToHash("0x262b9929089f5982a484f9ae7209153febfb1675637f883af12ba93f6d52afc0"): true, + common.HexToHash("0x6b5d92222e2a3fb80a7ff0e2db3ee8d30545f395c98621d4101ffa7115185305"): true, + common.HexToHash("0x8f9e7541cc7de70c21bd9d60cc566683a03ab33ac76c36769ab750fa12fbe143"): true, + common.HexToHash("0xc7fb033248734e9954d3931dd30ae3e41aba4d847fd83ed27d922ead60c4623c"): true, + common.HexToHash("0xc0853d66b7b7584c5e7042c65b4f8f5174ad0d79b05b83cb2c32609e7fb28945"): true, + common.HexToHash("0x6e28548233f1ce3c9de662a9ba5fe675c6174393599f791d13bf3d94774187d9"): true, + common.HexToHash("0xf6b136e56398694545cadd59ebae7542acc9795d3f8de6e4ebb3d1cfb59713e1"): true, + common.HexToHash("0x0fed83f076a522888df9221351117a4d6e0639ef2268edc295fd80b7580fc1bd"): true, + common.HexToHash("0xf1e94513cfcf13851f6c56f82a3fa93150ace1a13e4e00eb6803cc7c51d64b5d"): true, + common.HexToHash("0xe3049dfb449f32f480054540bf1a3162ac76c3d87b39129b3be76341da44ad6c"): true, + common.HexToHash("0x727623eb2064f63ac7a24284674dc2d584edf48405b04b1486e4cc0fe4a3475c"): true, + common.HexToHash("0xf1937d8e3ddff00e3b98b36a0b5f6ad392c1ab25b78b21b62d29e9b9ba60b62f"): true, + common.HexToHash("0x05f5fbce54030d3f4215bcae304b9ed578c7168deed9ecb7e858b49ebc94cadd"): true, + common.HexToHash("0xf8e946bad5936cc5dafbd13fe322f253518362e747e730540b079359f5b0fe73"): true, + common.HexToHash("0x5eb166e4e304603cbddcc4301906600ef952284b6ef382c47ce73756a2b0014b"): true, + common.HexToHash("0x8e36c10d6ab09b1eb43cc0053c8df4118e8311ad1cf9f3a79576ce710fdc4022"): true, + common.HexToHash("0x4e0f9691962234ff7326acadecc2b99464e3b9387ea988058a0630b1f076a026"): true, + common.HexToHash("0xace777d21c2dc91385d2b1f3a0d30908fc1c16e13287669638d2983182433912"): true, + common.HexToHash("0xc28bc19379d8e8a878fd95ee95cbac26c2f5c69a6ac549ea8f23ac4786551b7f"): true, + common.HexToHash("0x0cc7abc58e237dddd861e887a06adf4e7aa4d4ff6c0d0ff212d6c088267f2250"): true, + common.HexToHash("0x248c8b372d84a3dfb4ff04b1748fd87541267b3ebcd71b2f5ecc9d3fd9c480eb"): true, + common.HexToHash("0xda5c82ce06244a552a67a3b10e849156f78837b3cc0083dacca866766767a3e5"): true, + common.HexToHash("0x16a86e1f68930da9860d993d5e5ee43f5e9466710afcffcbc35e1aa5879dc63a"): true, + common.HexToHash("0x171372a24aecda70c7c2b29bcca8f368f051b7cf65a8cc37d16e0d1797086e63"): true, + common.HexToHash("0xc7e603da861d4c702b9d18df00403e274410bcb027e7d72e4a954c0c2679b373"): true, + common.HexToHash("0x235ee83c0699d935b9b686cfd1c820b93251cc2a2f0f61f3395f6ecd1dc7abcb"): true, + common.HexToHash("0xf3a7415571f265222fe2a727f010f4d806ba429328db7cbab966b34271bd2c6d"): true, + common.HexToHash("0x2295a9f9260c719c9ba20e9f0883644b6561951bc0486e1eb7252dc3e58e6da4"): true, + common.HexToHash("0x171948f68971870dce4c06a143bef9efb9260b69102e556c6a92463ae04c4a39"): true, + common.HexToHash("0xe157e9f8129ffd17ce172eda31e6ab669f122cc82ed10ef6f9b268b7f2601c17"): true, + common.HexToHash("0xe25f1207ff100b82e27001a0e7a45e5b083c95bb6b376c3549308a9a0eed4666"): true, + common.HexToHash("0x9327a97baa5ee63858cb16eac6b88159f4840698bed5a0c84ef8fbe64a167ffb"): true, + common.HexToHash("0x989fc137af8176ed043af82005d9c2c422eba150447fe7d8f771482ec87b9d29"): true, + common.HexToHash("0xa1377a81aa01d02f81ad5f6721f5b845e8f5545b306a599963060dbac0d73734"): true, + common.HexToHash("0x7cb2dba8711745da4d986a896278359fee2a971e14ab1f7dcabb8a76e69a4250"): true, + common.HexToHash("0x68dd5c01b769c3c21f385bd89f8be0f7fc181f548c82ba7b0bfcb35b7de5d92d"): true, + common.HexToHash("0x88a8381a38053ed9923ab270bacae17191e2cbde14ec6d8174a421136f767415"): true, + common.HexToHash("0x040635b42f3c94338b143a5909287bb43212a3a7049d6208850755918bf3db8d"): true, + common.HexToHash("0x8cd2c6c14a075baad89512bafabeb63d9cd1bd5ba997e94e980378e158ad0efc"): true, + common.HexToHash("0x308b6a2a5a5ee415de99f451578e5e563e6e10c33db20ead2a4c6ca97eff6439"): true, + common.HexToHash("0xa9cd0021ddb5405df31f9bc7465880e106bc4e051812a5673b1ab99f45972b6a"): true, + common.HexToHash("0xb389f5e6aef69e25ba91e36cfa287b199cda8f1b698befadceb0c598ef1ccf4c"): true, + common.HexToHash("0xe8d8b4c973967185fb9c139327b4c9dbc04e84b11be07c37e7c6290b1519f652"): true, + common.HexToHash("0x73043a71b61657d281e02c7146d8e65493e9c28d8b7ce271412acb4bce59c358"): true, + common.HexToHash("0x3a9f6ea09fdbcbd762f4451b2b398bd2445404996f215ff4cb57a62f5f15d25c"): true, + common.HexToHash("0x28c3a0964968393f7cabef8f15a44c18ed8c87f15b07334bffde530397e4c418"): true, + common.HexToHash("0x7efa0e3ddae6631046a8e64aadcc627bc02fd09e03f8862450b475fa98d084be"): true, + common.HexToHash("0xd834eb4504558639d3933f78f4aeafab357046313fd1bf265d6998b2c7ded922"): true, + common.HexToHash("0xe26c39561d317deaf67f1d87ed143e33f3719dda6643752d0768b411fefe2c01"): true, + common.HexToHash("0xa3cd29546066bb4d9c5ffef47c99cfdb4af481a6a46f7686ef5621b0a88b5dec"): true, + common.HexToHash("0xb0d6a84284fb3dfb68105be0f1b929793d547fc40257af6d78f1deaf0b570c01"): true, + common.HexToHash("0x13fd6da405bac4ac98af83cd3580320083ea1b0175303380904d4c4b0d460de3"): true, + common.HexToHash("0x2e92c77f61fe2c245dd25aa6e0ebd87cb63d9c8486d7c8f8904a43b9efe237eb"): true, + common.HexToHash("0x08c5aeb3d0f6b85940e7af30a5c6d2fbb812a7a9db0499a50b8708a72775881d"): true, + common.HexToHash("0x426e0730d4e80ef4293adc332c78bcaa2d45308356969193629d087455bfb587"): true, + common.HexToHash("0x464f6de43d116fde05d8c8b36946060182a12ae0bbaa0b67f4bd6ebe8e5593d8"): true, + common.HexToHash("0x9e47d5ace28137a6ea77a8e8ef9e5ba0eba4fc13ae70168cd6f3b3a240ee929d"): true, + common.HexToHash("0x764ed053dc71f217294c26b65337b0c43134a86d86a571e843088ffca94ba697"): true, + common.HexToHash("0x89d3ae872f4b7b40695f4d626d5ae86f81dfbda6b7cbc7c26b04eef9900c2a25"): true, + common.HexToHash("0xa1f056858469f1857013f572cd9544634553267051940a0498221f6afe4a235e"): true, + common.HexToHash("0x360d4c78c1c53b845d43d4be3b0533e7ec08aba5c3a88fe20542be312bb4281f"): true, + common.HexToHash("0x50ad919e7b5937b558f8f8628279fb0fd5740ab2762eb415869643e0c8b79727"): true, + common.HexToHash("0xc4915714af08ec50e9024a0e64039043fbb6a5f80b86e9e6fff1b8d1f8a67531"): true, + common.HexToHash("0x2630976d60a181493b8018dc6e462fcc276f0de02c03e58b66208ec4c4e8135b"): true, + common.HexToHash("0xf9b707d3d5915f08a953a9c5f22b1922fd06989db481167ddeb9f42d987bfb67"): true, + common.HexToHash("0x2b50f787d683591edbe5cd723f64cc446f4d449077b0989fef4b8e5ca890d09d"): true, + common.HexToHash("0x9af741d3deddfaab75f8838512de9e3d94727341ba6bd72b10fb41424d56de05"): true, + common.HexToHash("0x76918d3e36bc220c2c3adb9efc726fa8eb743ec68e0bf17e2c7e72cd672670c0"): true, + common.HexToHash("0x2c5a15430c33e65290f2a4830e57ce52858671630bfd8a75f8b22f1cd654fb01"): true, + common.HexToHash("0x9a8d581aba6794abb6fc7cf53121293f296d37ce70f9f974bce35d0c3c6c07e1"): true, + common.HexToHash("0xf7c14e0496ff07a72efc6732eb32a002bdcfffbbd2ce731426b33dfb55bbee0c"): true, + common.HexToHash("0xf78ab2e079d2a50dcdceb4a9d52c9b32de0bf480b9c1c1f03c2f3c732ce517a7"): true, + common.HexToHash("0x8798f17a0dd9f40d8bf5a67181f8d6ee023c0c6172bde3b8f9ece60203da800b"): true, + common.HexToHash("0xdae99797c4f34f5008a58ccfa3dcf2bb1ebaa77996a941e0614466f724d35560"): true, + common.HexToHash("0x942894b744d4e48dd57e572fee8529b57f353faced96e701f8ca7a191b620d53"): true, + common.HexToHash("0xff8696721dcd185a24708f96b9510912f2c97d6626c26fe41583860b8fae6fa7"): true, + common.HexToHash("0xcbf0a59a06017eb769a1a9de2eb3418a226b37b5a1750e8225a961cf1b3848cc"): true, + common.HexToHash("0x0a4e73741e5897fbbcedea134faa36ac9365e4f2779b9acde7ca410890c8d5df"): true, + common.HexToHash("0xdb40bbf3643030391865d1dbc530337e81a106d7a2d5a6a5757dfef37a810d03"): true, + common.HexToHash("0x45f7ef7dcae3bc664af96c1caf40a2998cddcb090019b083917bf9f18102d222"): true, + common.HexToHash("0x4f59d7d421250626b0cf813ef519f3a939d6c27ea4751cf5810d7f3e60b84c74"): true, + common.HexToHash("0x7ee0f58524c848050ddeaf98c1063271a7939aa3c68f51463580358406daca91"): true, + common.HexToHash("0x3e23df18a755d43ea30ebe114c94e00c8b33fa1d8e367aa8bf42d50ba022c565"): true, + common.HexToHash("0x500685b112dffe2944a0ed1e9363a36bbb3877f45085b51f5a096130781ff407"): true, + common.HexToHash("0x4a92612a83100c9cfdf5b9545d15e65a31fb6fc891033991f0cccb984d926538"): true, + common.HexToHash("0x497dddd609605109106c7d930bd53f8ff0325fcf3fcd339afab9ce09f962dfd8"): true, + common.HexToHash("0x43ff230817659c9d1161a3cc08c9d5b2f2987076272b95c60a4119e97a026efb"): true, + common.HexToHash("0xd10453dcaabdcf6d13660fd2a04c7cf281dad7837596e31e9390c2543ea8bf9c"): true, + common.HexToHash("0xcfa8279c213b2eff3a29341422fd7d39fb4183d0990cb434b65784660809223f"): true, + common.HexToHash("0xdea0c3247c17caccca3cce5560733c6dc92f4092a78fc148a1e87998f2582984"): true, + common.HexToHash("0x4b5deee3ff3de99f9ced825878e672e7fe9203ceb45530f3ee32157d5fca4d36"): true, + common.HexToHash("0x68f924d383e60fc25968772594b14512f1e01caba1fad02f45a60b818ba51b51"): true, + common.HexToHash("0x0dfaf9756b5c1b7e90b1c93d27a9e6e6ca207a53ee47adedcbd8f230f38b5aa0"): true, + common.HexToHash("0x5abc2667bfcdb782ceddd26fe2c19e2b9339842eb5f79af9b7dd1cedb2249def"): true, + common.HexToHash("0x22ca1c9131a7af6a7563edb5aa4ebf033a78c8f966e492e29d64d28633061162"): true, + common.HexToHash("0x2a118109ecac7e9f662896218e748283c9b85c7a780213f5db603f838a8f89bb"): true, + common.HexToHash("0x8ad3c2faa0a3d03db49c49f11b8de174f6dcbb470b2385b8be143ac20020dce2"): true, + common.HexToHash("0xde5993b75a54c8380f3d687aa0ded9c47544694fa179b6fd877afd81665b8bb7"): true, + common.HexToHash("0x2e7364addcc5e0228af281ed8fc8393f6e7f11fa9aeb6a82bd998d38d5501eec"): true, + common.HexToHash("0x03a4a384efca64924e087404e1a3a1bcda0959161c7672bf61be5adbda14c8ee"): true, + common.HexToHash("0x703b7030922356cbd8d2c2fb4259bf8424c000ecfff7c26bfa6944eabb8c5995"): true, + common.HexToHash("0x1d280501233344dfcce587a24f0b882a39d5b58deb0e73052438c94301356859"): true, + common.HexToHash("0xd20fc728bc083fa551d6d6bdc82c892e82042593900931c3208888f637e93409"): true, + common.HexToHash("0x9c07030144e33be7e4c3c846940d41b9726cc86d79dcd4c89d06c5cc13770adf"): true, + common.HexToHash("0xaa92bedb246372831befda8de8ff662cf5b426302b1d4c42d9e71074721ee28c"): true, + common.HexToHash("0x377cfea9201b3340a297e7d41a2b3119a2ce9911871384822d4dad0700ec1955"): true, + common.HexToHash("0x852cee3697a918bfb62f1c4219e38514110aa91211ded95fd007bf449bf9b6d9"): true, + common.HexToHash("0x525d581cf6ca994ea2a540662adb2e2284a3ffda46669564f7888ad095e9a08d"): true, + common.HexToHash("0x02a7a83cbfea5fc012ce3549d213eb30336d98c59e5ac4ccd9fdc01ab21f9e36"): true, + common.HexToHash("0x516d2e039322905b4a13aec8f034d4ae2c504c4b47739cce31cb402caf6e1025"): true, + common.HexToHash("0x73b4d85b9ff0a35fbb97337ab8800e4fd825f4bc59bd12bc6ea6aef5a2a4e94d"): true, + common.HexToHash("0x96a1464885d45c21953eb8f1a3cad3533b713ce9c8cdf1f599240f8ad3f17f55"): true, + common.HexToHash("0x2e02bb8b634d98944318c6fa82cf2598dc44c2258754dd0008fc3a785b004334"): true, + common.HexToHash("0x331a59df548e42300a664eb1c6251ff7aaa432e37be5d3dd4bb24d601ade8a7f"): true, + common.HexToHash("0x0f3a24ce8f05c1631eefa83a0b9622cbd40e404c736e01a21c2e97a844c724f0"): true, + common.HexToHash("0x50546b714692b0625eaa51535e8e3bd88d48e1fcac4fd23dbfcbfe6fbce8cd05"): true, + common.HexToHash("0x8bbb3df23ff79ff707ace0fc34fa45e84e4c55755cadb0e17e4a6a38252e2c95"): true, + common.HexToHash("0x5efd0e8f73ca343a07cd9ffe53d762ebceb83130563e3d5b7c09c01e79104f64"): true, + common.HexToHash("0xee93f5c42fd08b5baf8f09eb07c637654ca1dd4e17f76598b2e3c8ee8bbc0f2d"): true, + common.HexToHash("0x6795f8ef899abcaffdf19e60386baf5fde124fb5ebc2c98b822adb4221651236"): true, + common.HexToHash("0xd145fb0cdf2ea5a62fe8e709813e4bf7a62fd20d027e1abbc138a1eae1ab53e5"): true, + common.HexToHash("0x0528c30a132396aa7985a9961d769d4a46a7b5be1c0dbede9cf046fdd0e95863"): true, + common.HexToHash("0x1e9fac1cb1e07a17ed8255b85da87204f1d73816925a43ddf00155632029204e"): true, + common.HexToHash("0xd64698b61a3cad67d5fc0ba3545767388d5c4f4a450a5574981edb63f5fd8ff8"): true, + common.HexToHash("0xbca17bc99696c2a24e50deed64a35040136f2973d6cd3849ef87844ebdee559d"): true, + common.HexToHash("0xe044e73ee452f21860903ba0d0d7d0ed2b1707a2da766f136f5d8c7508374dc0"): true, + common.HexToHash("0xbadfd9421da84ac41865079fcb54ecb6583d984a9a7640ed20132110a0b1827e"): true, + common.HexToHash("0xd92af254f202cd9bebc91ba411e5da33d0a4e0598dc22383b4bb546f5050c330"): true, + common.HexToHash("0x42e401ba211eb1fb4d6c90a2ae0e4e4c04bdc537e3caf380619a4f8639f37b5c"): true, + common.HexToHash("0x4884e42e23ed507c6dda8355db280e00b873c744101b882092d98f2e838e85c4"): true, + common.HexToHash("0xe489c252e634421ed2a2c3a1f392da562587f3a1d2aaf7446ea0adc8634ef248"): true, + common.HexToHash("0x7639df24ec6ccfd1112edd79e9a2b29a43bbb9ac71dded1d979561350ea70cbc"): true, + common.HexToHash("0x175f62df83df5a8d13f89dce62f3b342a96b2a77ef4c25c99adf37e4ca28585d"): true, + common.HexToHash("0x187b484966d7b6a689037e22deedd859d6fa0943aff3e6a21c9aeaae87d3aadc"): true, + common.HexToHash("0x0091014e32207fe4ba7d2858440cbb63e065d1dc254c7c1cd839043e3c6ec9f5"): true, + common.HexToHash("0xa572483904b82f32554be8fb681f216ea01a12d3c8481eb95e0dd95b37ff28a7"): true, + common.HexToHash("0xe8c330477bca48f64e389b85fefde5a621ae6a51233160aa33f2920aa5315352"): true, + common.HexToHash("0x2c8aa23f440b2cf140b6f54891558e1a23cf2d29c3ba524a675b1285a0f8fb54"): true, + common.HexToHash("0x93bbc144049e140df20853ea0182e6942c357935e2975af76610c2121b4c4c82"): true, + common.HexToHash("0x4d996e4dd5d1a7d4fb4c6e1507e7ea1a40444acd968e08a5e97186c1b028ee62"): true, + common.HexToHash("0x5f28b0c17bff6daa3bdf6c185929f5140c24548978ed537a792fc2b70437addd"): true, + common.HexToHash("0xd66672cea86c3b63d10585549df03c0e3676b06bd628d25c2d31f66a2926c327"): true, + common.HexToHash("0xa5a06327cd9544a11c8195ea55216184223be6adf57bedc59b9c0d0f48262ad1"): true, + common.HexToHash("0xec7f3d084a94a3be04ed1da599eb66cad98161c995dca06abc71249c7619d4f4"): true, + common.HexToHash("0x4b2b79d4c001e538e9cf1a474c537259c25140c73eba3291c0b21830559a1cb7"): true, + common.HexToHash("0xb434d7f63322aa616c75bbbe5e37e3be0354fe5a1b1d2d25db9caa8e1724da27"): true, + common.HexToHash("0x66655ee1f47f1a7d1dce1184f103f355d2062f8ea37a451583b21d9ec69328eb"): true, + common.HexToHash("0x9543a1a4a0ae0abd65e47629c1b37eafe31d7a93a174fee192c7106d71ed8d9d"): true, + common.HexToHash("0x933da4fb495637d83646bca18a8edba5514b26888d0c825ff98238875abaa377"): true, + common.HexToHash("0x2ed962422328930662ead3f4db9f4d39e78cf17791bbf53bfe78091d6319adcb"): true, + common.HexToHash("0xf8b6dc6db84691dbccd9c6d67a880e40096c937cb465088aa5c69e60208d040d"): true, + common.HexToHash("0x33bb90acc55fa1f25078a443b4533b1be8a8c5662f9a079d31eb9cdb2bee03db"): true, + common.HexToHash("0x4846c40809fa5ff73ce742d1963f9a6f5294e537bdb1dacade511952e1b3b93b"): true, + common.HexToHash("0xfab15eac4bc4cfbb90c357b472dd75dc93d2d0eae73f46c41468e6b68118c7f3"): true, + common.HexToHash("0x3241342cce171eaefd2155bcd0b29382951a7b121e7f0956a5d713dfa05ff401"): true, + common.HexToHash("0x34719e074c069b4dff169a1a72e69dbb3eb9ebbec7758dec8f63de2608c781ae"): true, + common.HexToHash("0xe11fdd2491e70e012531fbda2dfe0d2f50d138262d38f4cc57addf78566d6ed9"): true, + common.HexToHash("0x16ef666e54260d33edb1a1f7ef6b0d9920555f66649374dbcc7d820b6641c81f"): true, + common.HexToHash("0x27416d4930a66651235759acfd8b22b9ef375fdf2e34fdb618f55b903a39202e"): true, + common.HexToHash("0x01c2280683a6fcd17bee4e9649d5392a1b80906bd9c51b8bfb5bc2c680ae3ace"): true, + common.HexToHash("0x83e9b5e70456cf54d966cde62dfda49f4de2fa24ae12a397ddc62405345ca3da"): true, + common.HexToHash("0x25a7af8ec69a5e1b5330a87600815eaa76210a13a156ccb8b22ca67e92da2634"): true, + common.HexToHash("0x1e4b94909fd75a75d5e656b4eb11c251554a234a66edde87a95075b74fa5a7de"): true, + common.HexToHash("0x0564fb3191ea7a9b6e68b6846d2c29d68d5ce111af8591a5a687dd16fd51c40e"): true, + common.HexToHash("0x2c74333d7b801b6239d191768eb4717ddb9b5504018eb1cdfb8dd86d951a2c99"): true, + common.HexToHash("0xe9ca25f682a8c1cd66862b8123e4ed2b210bc3dd465f2691ca1f25530a89b7fb"): true, + common.HexToHash("0x77deef114ef85fea2421f20395d636069885bac4c929b398ff4cd4f3b2e32144"): true, + common.HexToHash("0xec36280f8d14d3b71682f75a068f5d24876616cd97e647d7678d426822f0a650"): true, + common.HexToHash("0xd9464cba242b8b40381d3e7c2309b897c42a9142d0e9ce1e81aa8a182f698454"): true, + common.HexToHash("0xdd57d7c600ac38f513012a745098cc20968caf8beb476bc9e0f42918577f08ac"): true, + common.HexToHash("0x161ddd19da01f175a5341c5d2db01aa1c4be6742df43455a32e7bcc0e7d070f0"): true, + common.HexToHash("0xac72cea3de6836285a5719378756c32ce299aed9196414fe8cd2cf0081b9a831"): true, + common.HexToHash("0xe09466c72e6a58fbe252d7827baa43c4c1fcb4518b702c81e81b05f909706942"): true, + common.HexToHash("0x3460403078638875dbefb0bf5695d96bf9939530b7fcce3f06e5ce1276af22f3"): true, + common.HexToHash("0xfb5d6cdd8c3d6733295196676dbf1e91c84f05a5c6dff596077671027fa97d2d"): true, + common.HexToHash("0xc70392db51a2c93e9fdf133f6fcbfc68df2ed5a6fccb748c8d1ccc400cddba47"): true, + common.HexToHash("0x3f8b45430e2f724b01e0dd2a46df72e68411bd6114508622e84b077aa7e51f72"): true, + common.HexToHash("0x1f11d5f4a99529efbc2959239b326c6bd0a6f6b63c373c076c1d9f51a37df4a9"): true, + common.HexToHash("0x6e94c656e5d640b88fd7e1220bccf77231a02fc33093e3db51965a71a6ead329"): true, + common.HexToHash("0xac4801219a92fb006f1af52816ceeb70424d2f56147640817688a360712a6b19"): true, + common.HexToHash("0x6a455c71bee69c95764d0b039fb92d92c2266c4d16cbd522c22d9ece2d7c9072"): true, + common.HexToHash("0x105328654067d51bb25e0c8cd6e53baea0b0ec413b35c6288b3eccbfbff56148"): true, + common.HexToHash("0x5d1f3e8c0c4f3abbc5a4a3673c2b8d611c2478a4132591aea8a1f9f665eba234"): true, + common.HexToHash("0xb2f9d310dfb414005fe455911e9aedf2f1ee40c0f381e03ecd71ccdc92edafd5"): true, + common.HexToHash("0xf10c3a1c5cee6e1e37df059129cc5fbde35923221b73eee34862d4c2a5833c39"): true, + common.HexToHash("0xa06f24e4a41a9d1876ef1744bfcf9945ed1528f7532f39e0d683a86984a5f140"): true, + common.HexToHash("0x78765441eee391ce5417832c104b4733c25f59457be51a6c2552127ace8e5d96"): true, + common.HexToHash("0x23e96f25c1a94d11184a7655003960f6bd1ccc05bbc43c6c4084386007146c4b"): true, + common.HexToHash("0xc41c05a99d7e25778c16e2dce8ae1a415709ba63e46e01697288a37fc49b4c10"): true, + common.HexToHash("0xe92e9fcfed252eaafb51b98c7ff156478c2376a0d3eeeb7307868f6bfb3c40d3"): true, + common.HexToHash("0x5ab61601e91717f6b21a00a75e9af5b0c4a5d0d7412a1aa63c0aa94a2e9edbd8"): true, + common.HexToHash("0x290eeb347264ba1162463de0bd54cac13cf93a0ef613218947565c93a5359c34"): true, + common.HexToHash("0x6e35146bd8c318d59c3d6ea2ae817012f620a7b44b3104a760956b65ad8ae664"): true, + common.HexToHash("0x9c3795c3ef9b31ce0289eda49f858f8a47c4815b85ce13cc6952bf3a3ddf66d0"): true, + common.HexToHash("0x40b203257641f9367b85c765947721f16b1e226daaf0fc0108fa5f7273b5b482"): true, + common.HexToHash("0x598489a0ec69e48db312862103a98335099772dbcf7c1b23a2f7a00807f2c3e6"): true, + common.HexToHash("0x640e66cb7d6040093d72d5d391d5d58cea9d5009903129db9b45363434e94d94"): true, + common.HexToHash("0x19b2084ef8c93ca75b4cdb7854096c324e2a0bfd644fdf73211a76f2a95d4b7a"): true, + common.HexToHash("0xaa2e90152684ae4bec09b0f910b8a3509a4774bfcf0990ae977cfebfdc61cdad"): true, + common.HexToHash("0x77dfc6e4846cb6f3ffef67d54396cb811d840b2ef13814fe0caed4ae39a9d93c"): true, + common.HexToHash("0x6ba58626851c081e0967c34a309e070e18274cc9f2005736e1984afed8381fd5"): true, + common.HexToHash("0x8637d472d77d6de93a651a03b48e580ac0374cf53371367341ee4935a1879ee3"): true, + common.HexToHash("0xc05496392920a48a8168ff9792e65cb09bc913af95e73b26af4384cbc3550173"): true, + common.HexToHash("0xec71c4e55e3908555f7d1510693d149d4a0b25f51bdf1b5602c9ac00ab3f04e8"): true, + common.HexToHash("0x4106487ae7188df15535e3fbe9f6a354d079ab42c90fe0b841d18ab2cbd9ff01"): true, + common.HexToHash("0x89f7de47a43afb7b19d664d25070acba15ec887c3c1c4f45e3f555b57d03ec2f"): true, + common.HexToHash("0x743639e355cd7f337486075cf782eeb7add07bd5974d06cda945ae34e84a4b5e"): true, + common.HexToHash("0x7feadc416a72b30ae9e432a1970f7aa39b8b90d384155bc8d38966f215e4d0e3"): true, + common.HexToHash("0x05c40b44d619f776d5c759263b57c01ac1a817df9c4d0cdd214afe95c9e4484a"): true, + common.HexToHash("0x2be715c140d1a7d3c7a25494ff22f12b80e049162e592dad51b6b808c1194f80"): true, + common.HexToHash("0x472cfa1b45c21619dfa22fe2d3ff70f694aca5cced32ccd869d6d5c64a666254"): true, + common.HexToHash("0x41bf8a6f2edee0de996db540283ec84677efa5f6aaa90db3622d62debaee6e3b"): true, + common.HexToHash("0x87c91c16cc148bde4e31b6c4f434c7ed1f91fbe9f21437be0569479366ea9b9a"): true, + common.HexToHash("0x18490c7748f13b22348fe1de699a84a9e34f494ad88ccfdb0e1ac0f2547348ae"): true, + common.HexToHash("0x726c62c84bfdefa21c65f91a043eebc2746dee5642fe8ab1884ce3a8fe396445"): true, + common.HexToHash("0x1e77d821421f2ba3b68756fec7d058a9eccd56cee8a4a52b8f3c06c9213d95aa"): true, + common.HexToHash("0xe1dbac772b1e05210f484a8bfa72da74e03995f8be087f80ca30f23bdd2ab0d8"): true, + common.HexToHash("0x49fe5d91644a536220d72e28e206e8e974935a3ca3667e22c32ee460d22b0933"): true, + common.HexToHash("0x6b1dbe1fe555496de9ee14601df93426485fc8675050b2e6f4c6ba57e74fd692"): true, + common.HexToHash("0x4dde07dc8ad2dc83205c07c6b0648353f19fd6b4578c9bf5df52c6480a76df98"): true, + common.HexToHash("0xf0ccdf2adbe27b8db303d3ab52652fdcce7b6ce9fc89f789036c3043e990d3e0"): true, + common.HexToHash("0xba731e314ae80bf92361802954c17441112c4356cdab2019f19e8048ede1d695"): true, + common.HexToHash("0x0440011c3512e5f2cae5f188bf5d43ffc1768c6b5263f7ced5ed38722e73bbbd"): true, + common.HexToHash("0x8ab7c38df77859b10f63538d0964cc4d6d2bc1b64a0bbeec28760405d48af883"): true, + common.HexToHash("0xe93654361e3bda0d9346e8b7d91ea148e24dd0fa4bd59fedee20a2e2f4e3074a"): true, + common.HexToHash("0x527bb714dda246324bbc494c6a26167d717114bda75be7b458e7b1aec18566f8"): true, + common.HexToHash("0xb548bb4189bcae7cbf4b342c9d7614d6670793243b049fc5af8004e39b23c6b5"): true, + common.HexToHash("0x5a3cf7e6e4a9dc8fd1870b6d37e490774947708571f8a112394e36f9999cd35a"): true, + common.HexToHash("0x03c4215cca4f116dc012ae2043938592768bc44c273ac76d4efb5273a62de72f"): true, + common.HexToHash("0xb3eb517213e9b4cd75935a3d5cc4b1c07fc7d2bc5c54ea421416f8eedea77cfd"): true, + common.HexToHash("0xa3e7b70fb550f23514fdcc817d8e3af1839102f5386b89de65469dae15e9f558"): true, + common.HexToHash("0x1fdf4a477c3aaf8b46241493876cf4f9583d381b30b8e98cf799bf52ef3e8b9c"): true, + common.HexToHash("0x9d9e15e02c2bb0d6b3f505e6ba457464fd8a2a41c1d16c89d38e8e0998d5e489"): true, + common.HexToHash("0x70e326b061e45c9593203342950d1f4e5421674ca0cf16f798035351da67cba1"): true, + common.HexToHash("0x804291fd3a893c74da323d9a5aac7e35458d3907b50597aa100f4c3387767f27"): true, + common.HexToHash("0x36c79527e465281ea3978a1ab679a5c5f718d7b56e0399bc20f47f5d2b4a88a7"): true, + common.HexToHash("0xe16399d2906cdc0ef53f8d62a8bbb376cba9cb3e8f724c56f230eef3871f82ca"): true, + common.HexToHash("0xd5d41f660b5f063fef01285da43020f67235534fb73847464820328ce5adb744"): true, + common.HexToHash("0xdff42a332bf5c049900bd81c5e9cdfa7b435781d2f1d657fcaad27d5f8e4a40f"): true, + common.HexToHash("0x5d0c79e961b40d2cc0a70b00a15fb2d85409f02d241a3fea3e86ef3c852ddcc4"): true, + common.HexToHash("0x41022a25f0613b714b258244cb041f3476e62cb4aa94f9aaee2dd0cef44d3134"): true, + common.HexToHash("0x9bc1b0bf8cd1aed4b85f4ba3b506036c997bc139469052f0c1017cb188b1a253"): true, + common.HexToHash("0xb74d5442cb4ede890165c4a66198afdbc6d8e7b3fb80c2ad68091cc4fd93f45f"): true, + common.HexToHash("0x1c5e10ac124167c7dc3bc8ab11799d297ea88c28cfc0bc972c8d9dc0ded2727f"): true, + common.HexToHash("0xd3edda3a17d8ed962af80a3bc5c7a1af78fddea83f2e55bb49a4c6d772d5c512"): true, + common.HexToHash("0x95020f5e57119ddd2f83c396746f1a627adebe5cf959eab4bc1288c9930ce758"): true, + common.HexToHash("0xeba64a0ac9a4e5c0cd01ce2c67b4038f2272dbb9d9a959d2401c2e4eb087f43a"): true, + common.HexToHash("0x3ad623f3454f788d3f24dbc30bd63d01ef9d73af190a8194a8dc39ee29ddb636"): true, + common.HexToHash("0x65362543443760dc9e9aa1234fbbc9fbe14e6526100f4557502d255e74345ffd"): true, + common.HexToHash("0xabfd0bc2c7c1dfbe0bddc8c17d628cb26832fccdde6fa02a9d14b00eca24d9ac"): true, + common.HexToHash("0xb45a81499a585cf8857d213cd4e9e55a91a990c126d2b97a88e84ca669e6dffe"): true, + common.HexToHash("0x2d3746c2721cd7ebe0e2fd0ce8107e288f1accd0b907ca27a101a78f8f325ea4"): true, + common.HexToHash("0x6acb1259adcf522a6a2d53f3f8bc5e73eefbd9d6824ed26622cf3062e0d03def"): true, + common.HexToHash("0x6ea2f483a6580c301c52976e2cea19acaea258d54af20482e26fd3bd92f7dffe"): true, + common.HexToHash("0x99c7885b5bb63c6aa8cbe5c3b6058f2d572081a4c4d94734acee7fc745f9c079"): true, + common.HexToHash("0xd2b836b92579c90b0e52f641336422646717a53b47e202b47830e5aa4929eb00"): true, + common.HexToHash("0x4c8508103d16fb0f37eade503819c6f9146130c60091edeb9c87e4defbe5eaf7"): true, + common.HexToHash("0x59e531e8ab01fb338fb95e39b2cb552411aadc395986b2c6139d772951314f56"): true, + common.HexToHash("0x1408f9137420b7ec8cff71f2ba285b629403d32399e2d7dc1aff9547bdbd194f"): true, + common.HexToHash("0xf3ea55d581e0dd3f5710e0d42a61724569a0567335cf253327f1cd899e70c090"): true, + common.HexToHash("0x7d67addca069079b1b53400199494442a9ad8caf5cd0c8f264fdbaf3e66e4c6f"): true, + common.HexToHash("0x64146c74ed97bf245771688ab62fa4bc64588d38c988cb0897d1676b20ca9086"): true, + common.HexToHash("0x54c7ef64faae72fa685d22dcf973facb69f3a0998a7608c83bfb61446ce96be8"): true, + common.HexToHash("0x38f962aeb4dc8358b9dfbf1e93541f549bb4a9c8765df107e1876173d9850395"): true, + common.HexToHash("0xcd7990635d3a7f8398e268c2b7fb8fb82ae97563242dcd640c7ced1d1bb023dd"): true, + common.HexToHash("0x8f1862bdaddd88f4f4bcdca0aa1614177a654d465a8b59c538b70af36e182122"): true, + common.HexToHash("0x47598d36df15d6a5f2338aab3c594271b07bd1c0b67ffce4689b0ac2cdee997c"): true, + common.HexToHash("0x10894720efcd37944c10474aa1d2a608be4afa96b580fdf363c5f4d4fa7c869d"): true, + common.HexToHash("0xfbb1dc514a27e520a2429ab0e5bb7ff9012841b817d547853fb2d0ad1cd8312f"): true, + common.HexToHash("0x513dda216d2cfcb0e443556cd11972ee61801f81aa056948f706f6235810b88c"): true, + common.HexToHash("0x42fb52b11ffed1f4eaf8d0c07384492f776f0db43e0bfa8a6e41f918b1b9f4e3"): true, + common.HexToHash("0x54a62c9babf098a8e546ea3e9693114b397730198cf745b4c59e63815db23dd2"): true, + common.HexToHash("0xc5c3502a7dd44c9496005349c9b94274df91ccaa02a3263592dff00a9c28137d"): true, + common.HexToHash("0x2f610d4137066e6763f156cddad0cdf86b5b453f34ed327ca57f2c138451b679"): true, + common.HexToHash("0xa7ecbf297f834994dcebcc4eb483b5361cef5e25eb0473d6c883c5667f28483b"): true, + common.HexToHash("0x8414efdd5f1569ce5c6d2ce2a659c4f107fad4a31d65880ea45b0ebba398448f"): true, + common.HexToHash("0x534618a354e7e6d7454260bf507491c227051f44e5f473d8ec98788875dcce8d"): true, + common.HexToHash("0xb8aa6d4fb0a1a501f4a6202150d54af6e403df52bc1bf9a26dceb305af8123b7"): true, + common.HexToHash("0x3fa351f134926d3fa869cce3c56ec0c14720267b2a47d1a47cfed162500e321a"): true, + common.HexToHash("0x91abdc64372c9d7f63d83a438b7d4c9a7277b95903b09eaae11ecc41c063121f"): true, + common.HexToHash("0x553d1961e32cf24b85020c5f2ba0280dc5967433ef6d5b94ace238a87b93cb75"): true, + common.HexToHash("0x4c6216f436ae7fc75536cd75ed6e5dbb45f9f25ae937dfec343cd579037510d5"): true, + common.HexToHash("0xc9ade3951446a27bf8dbd8aa786ea34ff0d5f78902bd6850e0dc813b1b87f6f5"): true, + common.HexToHash("0xf7e2a30603751962cdba2252a2d7298e8ad14f9cbeab35e7b68d3b253b75de6d"): true, + common.HexToHash("0x645c2c948994086966bd45ebc4da76bb47a3aa30685cceb6046ebe5245be9318"): true, + common.HexToHash("0xceadbb06db4c2726ec1405403fb5506482d1b6f1c4c9fef646000a325be74841"): true, + common.HexToHash("0xd66d37ce6531d097f2304c63ffe7141abdd90117e69ab67c9d83d3af293010cd"): true, + common.HexToHash("0x0d633a9572269a43bc65dd5496d549fc0819316bf11f84492e51d5aa7604ab7d"): true, + common.HexToHash("0x97f54af2689b30184d2cfef7017adacafd0a3f0c9536c9e5ff7a8f1031dbf705"): true, + common.HexToHash("0x9b12d8eaf6d2c722551c53b3fc0730dff747ab17835a25de859d4c0259632aae"): true, + common.HexToHash("0x2b1e70bd773ba6aa5d98bcb1e504094310985080d422114b2a14da6e1fdd7931"): true, + common.HexToHash("0x9180eb9da2a1c389b1bb244aa4c5683c53672a39608aac067899cca7f0ac6ea8"): true, + common.HexToHash("0x7a4e3f6ae6ecea88ae450bdbb2aeb9415acfca24849137f0ceabd2d7ad414b5c"): true, + common.HexToHash("0x84f7dd5fada1c4667944c5cc3148ad977cf5d4a450c9064ba8309133f211f515"): true, + common.HexToHash("0x18d09d2f390552fa74536d152eba61666b582f4270637457c4b1a4704690fbf5"): true, + common.HexToHash("0xf02e090ca8a38f868bdae03ba16705dfe13f59f9a093c26247d8eef845f4d668"): true, + common.HexToHash("0x71adea9626887a061390028ba9d8e743d1daebf5275049cb98cb7e442788a2f6"): true, + common.HexToHash("0xf9d02c50c8afbeefc32133109f24acc28269ec4e5959fe874d47190f472ba3bb"): true, + common.HexToHash("0x9896b9b3170abd86c5ef2d253d5513dc874bf05fa04427eee79ef2812a54c60f"): true, + common.HexToHash("0xd67d517bf8251162c83da6d8754a23c13f888bf94d86178aba204619199f6fe2"): true, + common.HexToHash("0x772ff5b45ff9d6ba8126e8990e4e0ce20e755ca596bda7aa42e56e4d2adfaf5d"): true, + common.HexToHash("0x4dff4e6a045a035a55656980195c34521ebaa25902cae32ab8bbe04beb5bf7bb"): true, + common.HexToHash("0xf63a5e2fd7ae40868ef6dfa5fa60d3c85cad282e2c59496afe6d5319c5537921"): true, + common.HexToHash("0xc941f8bc55f123b511b6cbc96b26ad064eea877b2c1cd2485f9fc8e068f68892"): true, + common.HexToHash("0x83d5661d492e2bc8e0efc6e85a608afda466203504b0c709e7872965c9a2d647"): true, + common.HexToHash("0x6469325538a81c8db9d6e8b758fad074602e0d40790260f1b51b2aa167e61f3c"): true, + common.HexToHash("0x9853c05a1e7db92565b773dbbbd9dec15c985cb4a68c6cbbb33b316ea8a49abf"): true, + common.HexToHash("0x3d133c48636032101aef5c27cd77acf7b4449f044e4640452d95347bc8611481"): true, + common.HexToHash("0xd45924b501e65ebc74bceddc0382effd76055885aec62d704e1b81a34efa66fe"): true, + common.HexToHash("0x0d89bc67cc4d416378acccf19531e7da9424c820d2c1667b196508a903264e0b"): true, + common.HexToHash("0x7da98a0fff863c0dac633435e29683ed2e61d8dd5f4be0e5e8acb65b506b7071"): true, + common.HexToHash("0xe251416e837d556865b6cece05dac515948600774e052176704effdbc3f7b1dc"): true, + common.HexToHash("0xc2b543e8b9cbf619af05f659ba0ba7c65cf20ccd40fac3d76722931ab7d98168"): true, + common.HexToHash("0x5465d66f1738653cd7b4406f7a078b9998f69fe912fac81079703dcb1ddaa546"): true, + common.HexToHash("0xb41daabe0667f3ba303b93d319a2437e088398e36f60346ac7bcba0b1b0ce6b3"): true, + common.HexToHash("0x3e3ae000f4dc205cd9ad3fd9f9d38565d271ba20e4bb3ed1c3f94bd9a982b665"): true, + common.HexToHash("0x1b65c3d2a383f90d494131b338243ec698d4bbd7c664e59247e4ed03bc35ab94"): true, + common.HexToHash("0xf80f028261b3ef4293b45d4dda3cadfde0f7444d235e897208601fe86239d6b7"): true, + common.HexToHash("0xb1ecde30c6e3b3cd698bb1b446dd5421009ded49be36ce0e9bf402407dbec4ee"): true, + common.HexToHash("0xc47712e40750b4f86e1490a0c8497739f7703fd390b78614d12bf12f3de262fc"): true, + common.HexToHash("0x87da30f5e594f08abf6a37a4ce3b719f500f4e9ebe4d1e0114152c16df2a3c17"): true, + common.HexToHash("0x0a01a4c755fe6d1c2f85d7b824273d63e7a21087f26bc88cf7e2958fb11a6d1f"): true, + common.HexToHash("0x2be7979f7290b4a344d56dac559013bd2ac9f38d1ba86b33dbeb54f1bb1b3665"): true, + common.HexToHash("0xbddea4c156b2b7316ea00dc5e34de4f700b3b2cfb033299b046c24862a81af5f"): true, + common.HexToHash("0xfd8e34e01dd070a1cee3530c4f3313aa33671ad34b188ab13614d8f51c2fb340"): true, + common.HexToHash("0xb23e74a18e9c997c87a6ac53fe2e9cfb97c57260e4ef915d2f86aa830163eed4"): true, + common.HexToHash("0x03a5c062df64ba29b7f7168990ce7418dd24aed5edcbf05712d643d545c95090"): true, + common.HexToHash("0x9624df3261f13e4960630fb36c96e80d5b9dd4e1c5d38835a81dba259b913eb5"): true, + common.HexToHash("0x71e8c513c05da38ffc21f4fa27b443734dfd7aae100ef0d94122d87487c6e363"): true, + common.HexToHash("0x3d790e4cd1782e5df73eb1212bc9c989fba6cb013c18cdfc9c4fb50661d0edf1"): true, + common.HexToHash("0x509a04fe66c8821a153331d79a1715b614e120a819bde99e3f092eb73d81e3df"): true, + common.HexToHash("0x7740aa08ca2f83ec68b151218e2848fd75db08df819bce87af8017be63025467"): true, + common.HexToHash("0x9b26f3f51f676178e845cf2c501701d8e9ce46dd728697ef75719b330c846b7b"): true, + common.HexToHash("0x9d47c20ad664c70559cae1ee1286bd7905b2a1fcc6d26cfa145856c17fb75789"): true, + common.HexToHash("0xc9c86164b1dbc9b198d812819f51c063714977cc657db14b83abbbbf2aa6b0d8"): true, + common.HexToHash("0x215334dffc3bbf7ff4e1a8d6946622b68a636a6f3666c6c28faf7b55be61c9e2"): true, + common.HexToHash("0xe948529e1df07c31273a0d7d52a0610e400f24b2e7725270dc5b2e9418d8242d"): true, + common.HexToHash("0x7e5fbbfa5e2b9f9d89fe5b7964b0d66fdc69e71871dc49b4cb7adf853e4d8673"): true, + common.HexToHash("0x1be5f9149ffda4bdffb20dffb3587142a16481205586cd0cd8c1cffe41106410"): true, + common.HexToHash("0x2deaf93597cc6ca71e0b8f0cfe1dcb7d9725bbf4d54fd47a17ade18abf33cd4e"): true, + common.HexToHash("0x6389e281b2b2f0a1d998bbea6e2a5cb3930b64c2b2153aaa8a00404f20e44f53"): true, + common.HexToHash("0x5f223a29575aaa2d348275479f108d47e86a1dc813a9a0cb96feb545d3144e5a"): true, + common.HexToHash("0x0428d75cb1e769ff2c975aac72ae604df5bcae351f57d77dcc905b68b161f858"): true, + common.HexToHash("0x82e07ff98b711371c3e065ae63db73244cb8fcc68e2a1162db3a770b913258fa"): true, + common.HexToHash("0xe2d7e2d8db64467fd7fa54361ae056d81d185c1118f758e1aeeda595d3177009"): true, + common.HexToHash("0x8fdf3f57efb1eef51255bc2bddc6accaf246c0482a0104c0307b10fabd20bd5d"): true, + common.HexToHash("0x4a236741b76306798c68ec43ea2d7c01615a183a91797f466cdd55a8f2895bc2"): true, + common.HexToHash("0x3e5319b185954d73ce1df7f3ffd9fb640fa70fe75f7e9032a95e2b1f3e402af5"): true, + common.HexToHash("0x1465e5093bccd8c51838b0fcf3bc7e6c4b2e8c7f7be911ba5f57980b385046f9"): true, + common.HexToHash("0x30a6bce401a2390b2e71431ba7fff18f0c0553ec74cf40d9e35e84763927527d"): true, + common.HexToHash("0xe9e6507412e80d99cd3302e627cb11c200806c242c7861b959914874c4fd806b"): true, + common.HexToHash("0x87b51c479a007c9601510918efee47c376741e6436a00512249c82de712ddc86"): true, + common.HexToHash("0x0036964b0ecacc7af96a4a27e9acfb49d0b31969dd7d602996e5d2f5f5880b89"): true, + common.HexToHash("0x7c3ea8b1b54063dc17812dc1a56398c1157da325ab3b12c0a1af32ae24d877f5"): true, + common.HexToHash("0x3eba7740c17bdc6cd941a4b3ec2a2a3abe230ca6069c37907d76e4ff07d6cdf3"): true, + common.HexToHash("0x54ea3d14e44eee30dc42b990fdff1ed05559f726e94559c57fe66a53c5d6e095"): true, + common.HexToHash("0x8b4654130e23849970999a0620c1a973570688ed3bc6ce37e0dcc633a08a3292"): true, + common.HexToHash("0xa977bc9beacb464c83d813ec8022a5e5ce7750c36c1a37d7a59cf3146e3f8268"): true, + common.HexToHash("0x5f9e28e8335595c82051caa1fd15642466b4caf4326d3db2335f4c25b75ba19f"): true, + common.HexToHash("0x50f4d190e77f1754cc711969a92b363957bf5d350d255133317df3068e06e218"): true, + common.HexToHash("0x3054ef690212d320a4a5fa49eea1d7a8abfe2f7930535ea148f6b96004ce2b80"): true, + common.HexToHash("0xe62401a44330cb611885f29c6e522bd131a8e0b6b4797d8372d23136a33bbf19"): true, + common.HexToHash("0xc85e6c93756c3cd01e0aa6a12172763fa7229c4f005f1d67f22808ac0f267fd1"): true, + common.HexToHash("0x44b37809d6c1a0eb13754b87346539f6034030c38bfe75b96f44d9f4094af720"): true, + common.HexToHash("0x7d8c3295cd631272148d448a3be674437a6a042fed1b22609d7538697d837757"): true, + common.HexToHash("0x765c160b84ac34c85a612443803f9160168babcda4b1f0042b4b2395b869013f"): true, + common.HexToHash("0x9eddb21ba87ca7822750e4f30efc3a94e6fd687c0dd25cdd164d24bfb73c61b2"): true, + common.HexToHash("0x5e319b7ddadbb898bc15ebab4928e8815106d0208a44cba3a59897d3eb14a4e6"): true, + common.HexToHash("0x09e595e9ff3e263587513509df7f9de4ca635bc3b9eb85ba02d2af2ee28b0e31"): true, + common.HexToHash("0x52c4ab5725415c438a6b5279cea89a58c2bd3e692d59cebfe547c6b7330d85da"): true, + common.HexToHash("0x4218c0663d8a33fdcd94f407e9ac0ffcfb597a42f5a3d27e2f85f908e150367e"): true, + common.HexToHash("0x4a92ddb8ea23094d1819b08287e5f469b9b5d83ae23e1a0545d955e18364b622"): true, + common.HexToHash("0xa85490ffe08b1249b762b2e78d1381b98cf78f6b54d207d153e22949b228c12d"): true, + common.HexToHash("0x0cd4aaeb3c51b0d48f5bdf0b93d5d7a5afbea3defaf0d56ba061d0bc7a9f893c"): true, + common.HexToHash("0x0a37b9367cf042f80a13b9ab035aeb338738b29810da81c9da11a48cdb1e0e14"): true, + common.HexToHash("0xa2a467c6bdc72c377ddb3dbbb11dfc7e1fa386df011bf44299adddff308d8154"): true, + common.HexToHash("0x3e78630e7b84e3084a6c035b47db05848960cba1357c2c6e114410f23842f437"): true, + common.HexToHash("0x2480d1d25a34d67bc5efe8ded4ef939a58e19d515cc264239c54880151a98697"): true, + common.HexToHash("0x5e44336fefb010fbe49940864484fb203c1c1ffb473bed492776d9c5ec1f5016"): true, + common.HexToHash("0xca764660595d8f2f6c391aa7cf37d192b8cc1bd4d523ed7880aab07956f0af26"): true, + common.HexToHash("0x195ee74a054df30b628b124c4ba28e415200ccc53d247315ffc0b8da009c54db"): true, + common.HexToHash("0xba8d7a7c27071da17723f44f64d6806617b2ec60a666a1caee6478ea6621e1ad"): true, + common.HexToHash("0x404859eb461c6b8f29e21009b62263e60a285196d267708b0c7bc82bdda04147"): true, + common.HexToHash("0xc2636bf9a2ff4cf89f16bdb4418e9521b53695f8ae6cb080a2ff38d6279810b9"): true, + common.HexToHash("0x5d17b147508ce27a00abe687f348db0fd18a97c7737f225e0d7d4446b584623e"): true, + common.HexToHash("0x162b55096dc0b22e89112ad6433bc7879df14078eba0a680e9f3b6a56ecc8720"): true, + common.HexToHash("0x708f44d4b51b4c2498ee83b73b4ea29ae27df1850c8e7a2a7a9acc569b2e0939"): true, + common.HexToHash("0x93125a778679666b2bd96961c2ddaafc62aaa8342b0d6e83d1195ca07d047e65"): true, + common.HexToHash("0xc7501e542d7edbb54af0f69a2e9268f6870a579570bc6ea18a1645a1be8d8a22"): true, + common.HexToHash("0x79c3264f253e787f3d4a69aa6d8074faef3f334635d02f117316e7c3aaf5594a"): true, + common.HexToHash("0x46f2e92a0c95082b4f24d006d919c23663f44b90033a28b0272dfcd201655b36"): true, + common.HexToHash("0x206b82506fccab9bea77d19d357593d01300e51b0862f5ed95a50e9c6a864b9e"): true, + common.HexToHash("0xb42901c082242e06664f60594b06f68c39ba1711d66ddc725f45a6090a954f3f"): true, + common.HexToHash("0xc943f029e87d465355d2c256e6788291034eb05f929eeacd500fce8e775724f9"): true, + common.HexToHash("0x579a2736735173bd1c4e380be8cb2c8197d0c1e43515e3e20d434febe7abd98f"): true, + common.HexToHash("0x210c78c6894c90e1eb10675a74702f71e1250af109a17b42e68231d401e1c6a3"): true, + common.HexToHash("0x05d92904f5520aa6e9aec9c257c724fa037a4bc2aa37cd4ecde16f0eee79195e"): true, + common.HexToHash("0xb535953ef4715f4822df09339e58fa1dbb7a45cc7dc44664e23fb75e6ed5a71b"): true, + common.HexToHash("0x976ebfbed1d3f68cd4bc4840ae2d6f7f1b6420eb8bfff6f2eb7af0b484dcbf32"): true, + common.HexToHash("0x44d325f6dc308c5af708eaf2700061945a158d0c9d055ef7940ace8a758158ea"): true, + common.HexToHash("0x31583ace39e01555e9f64e34914d1e0a720483a81927be08763b03143a31d9ca"): true, + common.HexToHash("0xd7c96d64c66672b2b19529ca88b3e1ffcb30ada6ab0355eea7366fe572a01431"): true, + common.HexToHash("0x9b938f1c5c14515e719dd65f28014914bb3131e6fc505b6e893778f46a642b92"): true, + common.HexToHash("0x89963406892afbbdb6d705ca86c24e86632ea421ad260f68192c6c312400a55b"): true, + common.HexToHash("0xe4bcc07db4fc614b8f40d1bb8c1a1c63ed85cf1f6f39995c856fce4e1364182f"): true, + common.HexToHash("0x3b924e7ce7ff2f6879a9b2814bc3b42fa3ebdb851c885bb2de3fc590badd56d7"): true, + common.HexToHash("0xcb24b90d5b3b40453bd9bb435efd1b6e849128e7b81ce86e7887689348fd80de"): true, + common.HexToHash("0xf041ff9479f9bbce8d9962e72cd526aa5179c1c8b66207167adf2aa51b8c5798"): true, + common.HexToHash("0x1e640d3bee955ac0a8c3768368795da1de202c0487312da1df465e6e3816f5d7"): true, + common.HexToHash("0xd779c2a3e944a9d3122622dfc7e1e21dcd1082c6296d33290d7de86fd87b380b"): true, + common.HexToHash("0x3c045420499c664fab5d863a4a3e29fd8821a46599271727a80b926f5e958c46"): true, + common.HexToHash("0xb7db538afeb768c87cdf70c18e83fed71470cc1860b38ec6304919fbf3d5f403"): true, + common.HexToHash("0xc7bb0b93b54b533b35a9c59c2fb15fc83b9e9cf2abbd825923ceeb80f84c0f9c"): true, + common.HexToHash("0x8dec80dea20e6fe8feffc63059506400cd221d1498ad698ec6ff0932a68d7211"): true, + common.HexToHash("0x3dcc5664204b88e8fcc615a3fe9ceb13f6efc546584e939cd7499e073ce1d380"): true, + common.HexToHash("0x93b600c85f1e55f258df1ccd6547636d05300f832bd6dd4ba7d7e8e395e69ea0"): true, + common.HexToHash("0x3b9d574f4c33b9cc49a783fc81ca38ea2459af51da7c6bbbd8a5ba5cce770174"): true, + common.HexToHash("0x694e3d9ee557d17831b9a34cbcf684791e5f569359b75b900429c99721bbd1ba"): true, + common.HexToHash("0xad500b84e3accbb4a4643ff68fb8cae8f4a89ae6c15017b3a4b6a5bd30024a30"): true, + common.HexToHash("0x063bd6ab6f0cda757b96779d3e0db48a555543a3777d98ab9c9d4c86c9b236a0"): true, + common.HexToHash("0xcd29e93560dd8b367f699ab9de1f514b435c8e40cd6cdf4213c790d56eeb43b1"): true, + common.HexToHash("0x4be5470bdb2a74f7482ff2ab3cc343ee58d0636d1a2ccd65945f7f14234ab661"): true, + common.HexToHash("0x3fd9f036b3c2aa9a75900fbd00702b4fcade86bdf5b7c518fdbf3ca7b300f216"): true, + common.HexToHash("0xf01853f0419b47884a4fb292247425247f90e6b6da7aee18bccc8d183cfa051c"): true, + common.HexToHash("0x9967f9aa627aa49be1dd1a55121a2e180292191216fd46887ab3c7358c61dad4"): true, + common.HexToHash("0x30eddb22f21061a25326900c48ae15bc8c4843451959c25041e1c18531e11915"): true, + common.HexToHash("0x14265511daa1056858414db9090c5242dfa952db7d0a90045661cdf5e9dbba07"): true, + common.HexToHash("0xd6e396d4e9527141a0719bd306ef43a9dc5a7b9560c5569787bf58af8818b3a0"): true, + common.HexToHash("0xdaf25a3409a36c641a5e50f25c39a889f95a95fed4ec447c1c930f050a7c528b"): true, + common.HexToHash("0x6ba35c8f3305199cf952a70b90c35891e7d7e3946dcbb772d22b46cc451834c8"): true, + common.HexToHash("0x108637f3c73b90f25c7105d96eacbe3d1a11eefe1f26e5854d207b40d644d8e5"): true, + common.HexToHash("0xdc8e77601ab7763582cbcf90beaa96a583e68efacef071f2da2fe0fcdfe945d5"): true, + common.HexToHash("0x77555f6437b640ecd5ee3e4aca5cf4acebf998cea0fb44b2134dcb8a719d220f"): true, + common.HexToHash("0xfc0a21bcbde0f4fab13df58c1877ed84d623e218b40ccc97e739578d747594f5"): true, + common.HexToHash("0x4e482d98ce3177b479f87697cd581d63cfd4bb7959bf9dd969b6ee1cbba805f7"): true, + common.HexToHash("0xe657a147e776528a86c9db8c72169e836c8c699a0048dbe012cb133a815ed399"): true, + common.HexToHash("0x32f5ba0cd2a82d7e5c44b1017d178fbe96795cc641e7797ac3d32010d457d293"): true, + common.HexToHash("0xba4a7d9f0f3b344fda156ce70fca543f61f6bcfa0cb56a5f27c9386b983f9edd"): true, + common.HexToHash("0x3cea68118690441853e87f43657a7dc78d2ab9ee6dbc014b9b8cd38cd238baed"): true, + common.HexToHash("0x5b46906f54509ae17757209c39223cdd667f0081420c7949b5d62c7f0ff1512e"): true, + common.HexToHash("0x0c40393fdcbb9afbdad4cc633608093e4c072c5531beb79c60a7a97f2b0e9987"): true, + common.HexToHash("0x5c11c96196bb12a26606b61c68cb5e6851dd5a65dfe635fa56412f07c58a2465"): true, + common.HexToHash("0xe298960d32d1f32f1d0b97411be8861cc50a2c3ccdc52b5a4ff1eaaa8ce98481"): true, + common.HexToHash("0x799b938dc5017c7519f09960de03605d3ad703cd3016acbf0ad4da44767fe16b"): true, + common.HexToHash("0xa4c5254d074f2bea83e7f8838c2d1086b1901b1ef3c5e098c501d374d93e6a80"): true, + common.HexToHash("0xdbf54c300b2b63f1fb84574f6b284df4e10ab0375e7290a206e81fdc57e5a2f8"): true, + common.HexToHash("0xec3af94389362f345325e4cf35d8fe14177c47ff99f62103cc3c1b1136891b9d"): true, + common.HexToHash("0x4e2f404664554b82e0f9ff71bc1dfb6da22f8a04d0680eeee18c4e25a9a6fa08"): true, + common.HexToHash("0x222e41a740fc401ea9e6e3741e694d82a9a09419a3a2bd8139eea3984b564123"): true, + common.HexToHash("0x768d52a7b36606af07ce06246c91063d09c2c0a7719c7c000bdb9abaa9883e5c"): true, + common.HexToHash("0x91d688522822d9d4817c3ed783e50e91e3e2d671d050fcaef432077a6db5db8c"): true, + common.HexToHash("0xac086dcebacfdc84f0d4fbcc20b3a341f6ec07061a62766381f479269a432d9f"): true, + common.HexToHash("0x7cad79ac86728b4d8a683d1703d8695598a80ef4b2a7f3b2832f7336b1037fbe"): true, + common.HexToHash("0x72fcbd896b05772dd4bdf56de84e7459c38f2141a2409e6195814323e87141b6"): true, + common.HexToHash("0x6488c942c043fb9e6fe4731f6e157582e2bbd19da1de8d7a8363db8a3802ad22"): true, + common.HexToHash("0xc4de4ea66225e4a78443cac21f6f8b4ed3bedb958cd3a1237ba940afa6d740fb"): true, + common.HexToHash("0x392f86074c21da509975bc09f900042431b323dd111b494ba2ea1ef73d753827"): true, + common.HexToHash("0x1f95b7313ec61af9142ec4798e9bd73b6135fb9d0a013574d5e126cfdb52241d"): true, + common.HexToHash("0x4645f93fd0da90b8e7c01145fe40e0cef749711388495dc6748e0a4f7709e45d"): true, + common.HexToHash("0xd83c1bd00019095cc553aa84b782645340c219412e06e7b5f769fa325950b5d5"): true, + common.HexToHash("0x08db6a1e451421d9b08e1e8ef5750327a30ff5ce583a404201f230232e13704c"): true, + common.HexToHash("0xc03570606acc857cca7a5cbf6746c538e0e11740b3dc9c82e47a3690db6856cd"): true, + common.HexToHash("0x0ea69988610d34d6a18e8fc1eb73d234247d77606cb89042a387c3923d5fd701"): true, + common.HexToHash("0xf54109270def4e22b9df5bf06a8da8c7fc2efc2faa409973a3d57d64204e7d20"): true, + common.HexToHash("0x8877930a5b174cab5257753c550b1e4854ce1ae2d593e1eacf0509ad2b6ae425"): true, + common.HexToHash("0xe381144cb3f60e49b64fa8f98564dcd0296fc445321ce747a7860ca655c82653"): true, + common.HexToHash("0x523327fd54b649976c3514f13ff0d141652a86aba4e37a4f08834aa9901b0b9d"): true, + common.HexToHash("0x9453f3b07d06b4708d6795a915f911a184fcad508c651c6ef786d44629748b37"): true, + common.HexToHash("0x99efaf839a2529de4da7ab3c8df4e8bc22c4bcfb169877d22068de6ef86b28e5"): true, + common.HexToHash("0x6af0d7bbc55e60835ffefac77eef5f0eddf1a942bc373ca1cecbd22cd2d276b4"): true, + common.HexToHash("0xa596e85fbdd4562af313fd4f4f15f3ee4af34f581f1a78e171818182dbe0dabe"): true, + common.HexToHash("0x893998e10bf40e6706e2a6b4aac595ce202bdde3092b547a928d2054eb58c56f"): true, + common.HexToHash("0x74177b3b261f230f5310a6dfb8cef2c1ab44308e6ab381f18b86850f48062115"): true, + common.HexToHash("0x5544c5c01a1c119f6d8dc449bad459af040ed2c11ae279b162e9b46df4140837"): true, + common.HexToHash("0x244524fdc2f12bf19e9554bb7682b61705b69bf08d294ab1a04389da1ef86933"): true, + common.HexToHash("0x4b9def16c06ba4c2e02f234c0fffeaf1289282b326c5a5fe86d75473cd45a9e9"): true, + common.HexToHash("0x6cb68da11c5178889b18f4c373812698698ee78154a27a09c2d33da24e6e1df5"): true, + common.HexToHash("0xdd166542c3b56449c4578d2cf85c9e04f91a935b3890edb50cf8141f66ed0c01"): true, + common.HexToHash("0x1d37217901e5745a0337293f42c43e6029d98752d01a946e8393d3cfb54cd9ec"): true, + common.HexToHash("0x7adc5f2b9e9952805d6246556c863765e865080f1fb48107e692bbb369305f93"): true, + common.HexToHash("0x170d595ceb3cc89f68bfcb4816230261f98b60a8f16cea8937a56e96b20a8ac1"): true, + common.HexToHash("0xff203e0ceb03bbd9b502f2c3a974bdca71a550e9ab9e65712c918d0c482e8d94"): true, + common.HexToHash("0xc09cde40ce196bdd861b42ecbc76ae85db41c6fd1ba3847f1829c9a98cffa29d"): true, + common.HexToHash("0xa1f4cf9a05bdd878c0d447cd36ce531bd6b423e94c85ed34aea3a9846f553e87"): true, + common.HexToHash("0x609a80215a39f2cdccbb53c44281f6e43b609c9ae99194ef47438e482cf81312"): true, + common.HexToHash("0x80126465f4a8c9885df9492549a10ba5e064d2b19f9555474b9b555a9722b128"): true, + common.HexToHash("0xdc996fa59b74b5ccf9164d94f851c2c5adf76a771923b3cabadcf9c706a6eec6"): true, + common.HexToHash("0xe8fb9615b9a16169db5d115235dfd9cad94b660e042949b9c60a920668243b74"): true, + common.HexToHash("0x61c93ec0e7deefbc60e6b48955e6887310503034f052643a7cc56240b5788c18"): true, + common.HexToHash("0x9f5307996929cc8e3e676a0c58e971771a5c9c2535ca6e002e5ea009544e5f51"): true, + common.HexToHash("0x7f3257c8343fb58bb3857284a25a264bdf30653d1c8003131bb4d04da7b12e00"): true, + common.HexToHash("0x9b1c52b82d94614bdadc06c3b0f3e779bd4f90d14a33d52b0cfef4e91226a8e9"): true, + common.HexToHash("0xf341f6ff192c99b2dc9cb015f6c83c1d82838831219a13936b71484f77ff45ff"): true, + common.HexToHash("0xfca7377979fb93b48ebc57e9c2d2d177b563fa51c44cc2ee307b2dc4618304ef"): true, + common.HexToHash("0x15711686f29e512fbe857bddf9cdcd1a200be5bd5ed07415be0e49ed589c28c1"): true, + common.HexToHash("0x3e53cb26d841f678aa4242d8d1aa5ffd63bd9be379a81059af9b13447bca3616"): true, + common.HexToHash("0xf0cca9363c1d5e5f11a40e8f627331db085eadfb1d5e3f360fdda04f7719bbcc"): true, + common.HexToHash("0x1a41bbd9c5b8bda907ce24aea530136111deaaf60966129f57d51a8c06b2d82c"): true, + common.HexToHash("0x61f8e0d0e55c6855c88f158f4f70e579d40be90742e8bf6665ad5e57e1ca7fa9"): true, + common.HexToHash("0x4b68894bf716e317379ed402df681b31b638a065ba4bc1f47ae1f0ef2fcc74d7"): true, + common.HexToHash("0x009968032fc0c152aece3c214a3652d5301366e376e5b33b64e3f737f5b2964c"): true, + common.HexToHash("0xf63e308da6f4afc3a22f48edfd5383f91e0cf81abed2d2776da1c46b08a2aa4a"): true, + common.HexToHash("0x803d2cc2a039ac2cd8e8defffc74dfb79f4777fef3c00886032ff6529bc41797"): true, + common.HexToHash("0x806eed59e3a213d653bccc793f19c561219dfc467eab597ea82a81e5ae833540"): true, + common.HexToHash("0xab5c9a72d778b855f66a0772d260ced2a651834a07ffd780309c2fd51afef79d"): true, + common.HexToHash("0x3fb9dc6c0f48b670c182e4b580bc7964939830ff828503905204e5ae832cca0d"): true, + common.HexToHash("0x035b63ddab0b046863949a0c8b11a371975218bf4fa6a4498f9f0986e898ca53"): true, + common.HexToHash("0x97763d6fe550a378f97898c446e5cbc4712d95cb6ce858a8419a51851340f5ff"): true, + common.HexToHash("0x99acc0407d11524636df976c23c2905a6f579b25e8dc0eb17eaa5bc363e6b523"): true, + common.HexToHash("0xe63b2fd8b355c35f16ccac14a52d5b18b8b6852801ee6e3b2050f918e4a75b45"): true, + common.HexToHash("0x8acbe4819ffa3933bd5ecb1c91e1042cf407d5f6d585a73f3e25da9cd7dc54bd"): true, + common.HexToHash("0x04cce7956f1a057583ecb6b11c88dcf03a8b0d535000a668a90962d8e0ec8d10"): true, + common.HexToHash("0x6553b131271ee80c3301d14a38f982b807ab5eb3f8918ff19c5e836d7fd33c4d"): true, + common.HexToHash("0x5b4940da2f174fa57ede7d7080125bac6ea00d6f1d96b4e45765e6d4c0f01b0b"): true, + common.HexToHash("0x12d108a0781530fb8d86c77e52e0316fbcaf03840e33e08c8c664bd5e96c5592"): true, + common.HexToHash("0x0905c4eb4b2582e2708e6156e0d6b4ae7d3f131e0fca409d29e47610400937be"): true, + common.HexToHash("0x154f6368a3d8aee09446be601cc666c04807b4ce3413018345e36d3fbcbf6e98"): true, + common.HexToHash("0xa74691b2675e0b2dec919bc6b6ff127255adc39ddc802a07e8aba781d930099f"): true, + common.HexToHash("0xf05ae914e802734311299e584f8ae3b7dd2116cd1d1b2e969ba9a03ccba220b4"): true, + common.HexToHash("0x7e88c1253d4a22d1574424c2caec302852e1b4b1bc5386b07ab23edacc27cc15"): true, + common.HexToHash("0xae67f0e20869f74285bd77ef56eb0f0a01e7f11abac0b31597e7f95341902a21"): true, + common.HexToHash("0x756f474238ad33fd95008d2a0d0b0da40e8a604bd3cdba52c5d1ac26a45bf6ac"): true, + common.HexToHash("0xd2c64fd034ef8dbc4794436cd4769208ce190fe63b60c885f25b45b3d87ac326"): true, + common.HexToHash("0x5693527aa98925ca4d75dc212a582c79aedcc847ddba3607ffdeb85f61bcf6fc"): true, + common.HexToHash("0x7ef3725e6a96d8c1499033b8a9a49f32bb133942c432ee5fa438b52c5f491b91"): true, + common.HexToHash("0xc28a5788cac1b94dafdc9460881ea73b9df0b8de3ddf0b60b7f330dcb5ac7612"): true, + common.HexToHash("0x6306399b9fa10923e2788aed42ced59298bc0bb6dc04a7406cbc96917519e689"): true, + common.HexToHash("0xb26a104665a10c3d7b81aa0012069c2b4b99f5b72ad9d1502ab72a8846a974aa"): true, + common.HexToHash("0x6cd73ce215d8e7887007e3cc0795ce3135f8abcbd4a5419f85c144953d1ef7a7"): true, + common.HexToHash("0xd39cb9bae0d7460ef86ba2d88bd650d91fabee13f4cd4ae79d6d9e6c00af513d"): true, + common.HexToHash("0xb624e5a289b62925f2dc733623ee8d02b44b15b439135a4699344f8c3a98b1c1"): true, + common.HexToHash("0xe12f214552ab434415678a794bd8dd5c28b4861f064a4e712b2037465ce9e845"): true, + common.HexToHash("0x33f41b53842d6065e08a78caefb0a60eea7e8dac97107422b11bc778f1f6b606"): true, + common.HexToHash("0xa4b74bb55bead760dc6eebf8ded5916aa4ac52199c3b59753f0e9aa8d9a2ecec"): true, + common.HexToHash("0xe529bda216bf52aeb3ad3473c310214b44fde42cd0e7bc1837c63b3e74cbbf02"): true, + common.HexToHash("0x28ff7cc19ecd3f925ff53dc6264944b8763198388cfa4ab0f34f3874524577a3"): true, + common.HexToHash("0xa87688762399870bc273ac2325b0fd65ca61a5ee0363eab24c64f93452ed75bf"): true, + common.HexToHash("0xa4c7c37dd97459eaa1a97dde5660e8a0649f82f48866ed5ec06341e4ec3021bb"): true, + common.HexToHash("0xaafdfe6cae8a0e21ac8895334a36327a3257d7616359f76cb92a705036456f6f"): true, + common.HexToHash("0xec32908cedb80b5815986a42b9c849ed136f8fd7da89409ba7428659e905b7cb"): true, + common.HexToHash("0x6d2d7d6967983799330c094bf0157c5f8f2098ceec312dde14a66bb23003e347"): true, + common.HexToHash("0xeb3b6877cc8a6466aa230dc05c820468c3fbc4b21ac69febeeaf1e654109ca37"): true, + common.HexToHash("0x9332d9ecc1861ba2ec36b6f28729260a2c5979a969c21e4067a6dd0376a416b1"): true, + common.HexToHash("0x038bc61d2bb3607f582ec827e28966727a13bd5d479c34cdcf0394fab3fbb038"): true, + common.HexToHash("0xc6c0b5702efd95949bea4c2ad328fba159f4e147e66fee3a9715dc808b1227db"): true, + common.HexToHash("0x8e4be683efd4bb386e069d2573bca3a70a451e768dd2ca398ff1495f0fa9cd1e"): true, + common.HexToHash("0x2bfd7b8032f940daa4e3154c9f8dc52c21fe06dbd4fe04cd0c00fb5faa00d44c"): true, + common.HexToHash("0x5a3360a2a1ac7a85558032585f7d4a914f46c30617a7dc0f5257e9c0d1e034a1"): true, + common.HexToHash("0x82affd0a09ce20078e5c56d3faae5f67e23351439c25cddcd6af6caf6f45dfdb"): true, + common.HexToHash("0x1e879e7438fce2e7fda120f05deb6abcfc38c8f70591b7f5282b3e3100a8f187"): true, + common.HexToHash("0x78105d1b7685e2475888cc256e3895ecf6ec8f29930a3d17376066495677eff8"): true, + common.HexToHash("0xcd6275b5a31520dd0fb36f215d0aa5e6c29256276500e3464634f69c600ba401"): true, + common.HexToHash("0x3b1c697b116da48f2f3e633a3f2a1779a55a1b468f8dff38f50f62b58a0871a7"): true, + common.HexToHash("0x8171a7982be0fe80d5c133e28f23e11ae5ee66a2bb34261b34670642f8920867"): true, + common.HexToHash("0x9cfeae741a80b83a058f679398660c43eb4134ccbfdd3fb42dd3fc5414faf51b"): true, + common.HexToHash("0xca3b60b2a771e7dd2dd345ffd91a1d69ede9c7eda214e057d04c64fc633544f5"): true, + common.HexToHash("0x29eacb03f471569328a5f4435f81a4c8fb08b1e28020dad6ec82367a2ce995d7"): true, + common.HexToHash("0x22f682992e9a59c689af2dfc69784ae972fb0f0b3eb5d3ee651889509433c68e"): true, + common.HexToHash("0x9ca33eb50f2fc6ef4182ce5fd179bc94c24e9cc02a24a7914635d7ecafbbb8af"): true, + common.HexToHash("0x3e7cdcf250c20a9c9fdcca2e9fc09829bd1bcc01054802042eeb200c31d43d5e"): true, + common.HexToHash("0xeed266d701db6a5c40aa6c2e993de8d5ab6aaf0ff028cded8117dca758b8ac27"): true, + common.HexToHash("0xcea855b1d37ed6b370b70426961f0516dadb63c01d7d1bf546b93765f30d7019"): true, + common.HexToHash("0x913a1c1b3d88d13b0dda377ec0c965f4c9adcc9476d38dec7bef476def74df2d"): true, + common.HexToHash("0xf6481924f53933f128e2d058f40a064cbc3d2f08b54fd9564b21e94132ea59ba"): true, + common.HexToHash("0xf1c10be67c165a47f89f19a25bd4bd64741b5887151c8bab332c930eec3f3478"): true, + common.HexToHash("0xd1cc831381d86c8acd6b510c70ac68d8fd9d082aad053f8c352f68a8a56e402e"): true, + common.HexToHash("0xe55ba7df258d2905b9517b0af46adce462819beb99edc8ff93398e7c1482b7a8"): true, + common.HexToHash("0x1e56e6a56b6b636f15cdd32eb41d97dfa43812f51d341c9eabdb67ab3bfb4e1d"): true, + common.HexToHash("0x7514db6a019a3b559ddcc34663f81b17886d016e76028c68e2c4952c277f2e7e"): true, + common.HexToHash("0xbc0e94093a65059486082672d0db6b00b2cc4b72f9a676ee42d7344524cd6786"): true, + common.HexToHash("0xdacccd98649ed5cec03709830802934222ad3136b4cee16e45a1e1e18596150c"): true, + common.HexToHash("0x4c61649c3c87ed1c6b82f8c6c1664a0cc820cce995d5ba5722621c9b80068806"): true, + common.HexToHash("0x912fce5633f694938985e601fac5a9d27a6749ee87b5e5d0b3618ffe2e1cdeb1"): true, + common.HexToHash("0x4da658a049ffcfbd427d828f5d4613fbf6dfa2eaae1bbacc4b8b03568f5d182c"): true, + common.HexToHash("0x32574a222410b42c4bb175726772203d716a6a2b7ea5d6c737a089688a3ae488"): true, + common.HexToHash("0x3f3ce176432401a7f5a679d4cb9379947e891827d35fc2e991136d3ffbce8b61"): true, + common.HexToHash("0x4120743bf3cc44c118b3af7b70f6f4b2562e9a61222dacb30abe04cd26476e78"): true, + common.HexToHash("0xdaf1a85e8add1637a2b656e33532eeac5a32376a050fd9f6e03ae9d8b21fdaab"): true, + common.HexToHash("0x0d164524c2a2166f4c4a96157e7550d6eb8f721d8ba48f35ea1328af211e85db"): true, + common.HexToHash("0xbc94744f6f38aaf6474c9817ca286db8faf82da2496aea5add812dc6907aa7c6"): true, + common.HexToHash("0xd26b7857623bba8d2d682b56b6740f4407276629a746f2f4577cc24f9e3367d8"): true, + common.HexToHash("0x259b1169e74797eb8dfb67df446075e8560404a3e2028e1b7e0866431b9a2217"): true, + common.HexToHash("0xae8cc4aafdfad7328b0d184f13d39ac61c179c3c9a6bcd1a056b4072b8327049"): true, + common.HexToHash("0x265b08d98d9a6c1d70c0bcf3d8a96924b2484ba309dff10276d48261acf654d2"): true, + common.HexToHash("0xe3e41948094dbd1e114355a3f12793b2ccb3dd50e250c4aa0f48f6de54cda22d"): true, + common.HexToHash("0x21a56df86a1d7a290584046948abe3547c33041e1911ef01fb16c50cf02cf507"): true, + common.HexToHash("0x82dcad6a8f6967376c5da96417b6b890eaab18b4dfa3a207803f0037e2b207e6"): true, + common.HexToHash("0x933407f590d968f14be33bae1c0baad7d6a038f567fff3e11b33ecc78e44dfa0"): true, + common.HexToHash("0xc220d49c7b6369ca1aafb4e463f483ebdb0e92440106a5d4d1240b56e4b15fd5"): true, + common.HexToHash("0x58eb4af1a521635eba8562b679d4aa5016a6c7cf425d2c1802530724347f2a6f"): true, + common.HexToHash("0x09d20b6a469182c808e76a10ce0ab0b143af3ecb2356612ca461466f988dc2b1"): true, + common.HexToHash("0xaba89e3fb9bfd143176e0b6b44b272070067b04779ee8407ec5c5145bb63c055"): true, + common.HexToHash("0x9b69399f37bcb0b45388fec74c7f3288f6e9e88bb55da13f9e876873d3e5ebbb"): true, + common.HexToHash("0xd50bc38c55ebeae94d02beff43ff0d5d499878c0f2fe25d4f27d50bebc715ddd"): true, + common.HexToHash("0x933a20689e1bab2b578d3292c6e483121657088c98ccec33649455d9540ae1fd"): true, + common.HexToHash("0x35ae988df0da5b5614a92bdfc8b18db3933a3d39857be04322f51cf5cba999c1"): true, + common.HexToHash("0xe3404f861ebcf43335ffb57fef1a8b1d19691f850ebdcd75aae26ef8e7192ed2"): true, + common.HexToHash("0x0dbd55192a971e611da5fd6ef6460944487761401bdd37d3340e14947477d385"): true, + common.HexToHash("0x641354d398c4709d5ec3f1ba503700cd31bd6f8f36ad41ac4770229073b8aa8e"): true, + common.HexToHash("0xc5b7dc0bc488ab7e5fd7963f5767a6e5857cf3960320e9f37126b3f6de2d444a"): true, + common.HexToHash("0xd6e8eb026eb85743eac886cf2963d6a006668cf9e7223a24c44631e0c9163c9b"): true, + common.HexToHash("0xa0e5910c42fa45b3cd9b7d985ce9db9befe87ed9fecf080edab6fe78f0c0defc"): true, + common.HexToHash("0x617afda45d31c2a59b3765cc4b2a580b965951aaa909eb4201a5aec35c5b2e61"): true, + common.HexToHash("0x19218b9cb9a4c32087d0d8f2e8ed6962e19369c271638107c136d1d3889b5c27"): true, + common.HexToHash("0x6a36850e60582d7eabc6c8eabdae0f4270d81e964e61dde40c0f029cc09a1d05"): true, + common.HexToHash("0xcd734e5d0bfff216a3772ccf42fc7a9fe3004c8c567235b67464deba4b28e74f"): true, + common.HexToHash("0x36f1214b705e9879929848da7ffe49e90959576aad6a0d354bcab96bc49f1077"): true, + common.HexToHash("0xc49ecc83a31e3c050f1a443f89a7f81ef4c9979b813604ee5f1306dd2b97f383"): true, + common.HexToHash("0xb921dfaac4cb35f065bd874e707104c80a7070113b4d6b22a7bfd0bf87edec9d"): true, + common.HexToHash("0x0713a6ec9bbc0268123d19ce1196ac669c819e17452503caa3b00b51b6fd116c"): true, + common.HexToHash("0xce37aa60579b4b790940f88dcf05d5eb58e4b84b956e6c5e176a3ca5a35fffe4"): true, + common.HexToHash("0x2dca233781324744deb7eea3099b2417d4c1330210af553867d7846e01a230c9"): true, + common.HexToHash("0x2ed0f0fe557e2b4445dc12ecccfb8c81acbb2b691cb767f51b056c42e6078537"): true, + common.HexToHash("0x658c9ff26e4179a57621fda683ceea033468fa1d4c8639c6511791688663240d"): true, + common.HexToHash("0x5305870febbc22974bccb2d754de393831ffce2e37ea209d1c2e90716a5a85ec"): true, + common.HexToHash("0x24cb6531a896c33ef58fc04ac53e4b192fb20b34e7837db01a7b0ea7c970321c"): true, + common.HexToHash("0x3b88fdfa1d0c7d41d150137f2cf2ad8161554f584a8cec2feaa282d79566f9d6"): true, + common.HexToHash("0xf0fab855b5904781d7382550bc9ad394d3c6dcb0be5070b7906d49a7a562a957"): true, + common.HexToHash("0x9d5a03fd19938ee20d523d7e7454a7d54224bcd682a3c3f64a8e60b88ea3bca6"): true, + common.HexToHash("0x59fcd72d40c208fc3e59e5b8722244f1936ff7523516fa918c537ec5d7dd79ac"): true, + common.HexToHash("0xd2b4bca689835dd8438b2fafac6db5a247511ea8b45cecf1bc83128798f1d0e5"): true, + common.HexToHash("0x134780860c9bc0696babdadad73b42997ef6e6d7e8ef61b9f71177474fc39c7c"): true, + common.HexToHash("0x82b11d0c545c2fbaa847ab7bbcd33d93439cfd055cad19c618337b42a7530fb2"): true, + common.HexToHash("0x1fa69b5cd0983806f684c75a30c0aaba132b583d969290074dcd49e9d05f8229"): true, + common.HexToHash("0xf0c81dedceef612808c0d41a9ad57c677090c7e3794d3e2c85cc1fd6e467e90a"): true, + common.HexToHash("0x9934c3602672ca262160dd2ae0e964df4a3e034a468a3a4001b7d02d20c3cfff"): true, + common.HexToHash("0xaafa97369c386d9e52a6a98e3669c5bbd2bd4c7db0e3297ddc967d657bd4b4ea"): true, + common.HexToHash("0xdb122fc58ddfc30dc04422d2ee7f8b041a628f5f4ef572e7518eb4951b8230a8"): true, + common.HexToHash("0x05c0438172ad17053810fdbf94bb20c247d0653a43f8c0127310eb8f35e1e720"): true, + common.HexToHash("0xec24265590d7a01fea6dd178b1ef06bd6065d2de38725dae98330f85572f8450"): true, + common.HexToHash("0xc72bf449ff3fedf9d54ee675a3d5736ce887463b43bcbbca5cad55fa33a7dd44"): true, + common.HexToHash("0x90eec7dbfee98a0130cea04baa9715d8ed722698a3a2b5f4e818713a42e39784"): true, + common.HexToHash("0x1cd88e053a08d10d81889da4a7d780d7d0a8baa1020852547e66ef45dae7f975"): true, + common.HexToHash("0x437745bf7258c9c2dbfd342b96756daaf36e795366ce283c912eb0b7850ef913"): true, + common.HexToHash("0xd3c4b832e06b864e9165a1ea995a64a14f56849edbcb156eeb9be92a574912d3"): true, + common.HexToHash("0x38f7ee1baaef3654f539bbaebbf447d913a87c26f7a211d92c315a9e6350f48e"): true, + common.HexToHash("0x5e025ad261ec5cbce8180e9651929918f800c5b37173972a2234c5dd227d22e1"): true, + common.HexToHash("0x2123ca872704278b4b08ead560876e294d82ee0332947f02ddfeb61f76f14dca"): true, + common.HexToHash("0x689675b2faee9ab4e116b1115f1f241adf21a05e13049dfaa6c5e066c8f36914"): true, + common.HexToHash("0xec409a8f2ed4c1c1779fdb434185b937b022e2c981c64f60b63cd41e4f9e7186"): true, + common.HexToHash("0x29db9b4f5ed2d467efbe6c244df44b6e9ab3a1e0d343f5a02c11253ac0ba2cde"): true, + common.HexToHash("0x2bcc3ecf798efdf86c9451adf16700807a9bb1066ffad77845e9e7623ae4f9ff"): true, + common.HexToHash("0x99d5a72229d5eeb3183f50685fdd438e855ce9b43d3abedd06efce85ee7332f2"): true, + common.HexToHash("0x275883cc76c6a875071bf603b128af454fa9b85ab461ae6168908268bb506c1e"): true, + common.HexToHash("0x8f83beac78647def8bc71c83daf201a800b24b0c0dc4c85c151d5fe1532982f1"): true, + common.HexToHash("0xca454cdb66dddf1a88f330716ead654aee0e423e7f467ff9975c5ceb81463605"): true, + common.HexToHash("0x1425a51e6c32f4ac04765998e737e441a2be260b1d208afa538c459e3229c708"): true, + common.HexToHash("0x953f74d53d928aca9ae24f4ef1aa537b87c22c94db3f62e40796c5d22c5243cf"): true, + common.HexToHash("0x1cbc8508fc076aad7743c811b5e04903389eda161da9e0a83940147dfd6a425d"): true, + common.HexToHash("0x16022191259999e56a25af78c2b51ebb7d5744c4333a6cb5187fedb16928fd04"): true, + common.HexToHash("0x7162d13c13c2fdbe2c4caeee80737a9a139139397e224278b8aa4af916faa214"): true, + common.HexToHash("0xd195d89e9ffa989e7b708cc386dff9d8d25b5173b281de6c7fd9dba93895c970"): true, + common.HexToHash("0xcd0e50f7bdccac1a7dba9a84b24932c6d3a1ce0015f9bd69f13bf769d69df627"): true, + common.HexToHash("0x8895a12c9b4c96199d1e13d6a486bb8e84b163afdb7cffb85112c70ed54784a0"): true, + common.HexToHash("0x371fedf903ede123bb9d7bf9c159c561cbf2db35f68c8fa1f98ebb311148ae8a"): true, + common.HexToHash("0x5a91f3c4aec03657e0866f1ada7fdfba1aba5cf0bfcaf52b49f3957f27a818c1"): true, + common.HexToHash("0xf437eef0c694e18bd07600d8f7fb65ff6a350d908644c2f084143356728846a8"): true, + common.HexToHash("0xb8e0bc736e907c06aef9c00253a32f4529049db581a9dafe0dde2821fbb51e45"): true, + common.HexToHash("0x8754f223eae202ac9816dbc24a9c77016e26623e5cdf101a5a8b8b6cc687976f"): true, + common.HexToHash("0x7478ef31e2ab2b94841aa432bd3043c3855ee667c06e7a30d62182a323539127"): true, + common.HexToHash("0x2c732e4bcef4283ac021b91f3d0726f5bbb472f189d09235b8cc7ef737c075c3"): true, + common.HexToHash("0xd70761cd55090b6fd8d80bfc0e9543f0f3ce21da4e91d91d75dbfae1ce77fb34"): true, + common.HexToHash("0xbcc27b0af0de9c58fdd238be64740c07622c167f4a1aadb6ebc8f7b25b04023d"): true, + common.HexToHash("0x8987b81c3b67397f903a14211ef2cc32f512fe43e9b2e5d3145e6008586b9759"): true, + common.HexToHash("0xe01e5b381e5b73e73a4aeffb56af2f6fddaad4855992e38c564976b44a97ed4d"): true, + common.HexToHash("0xcfb13c569db66ccfa7a7308b5e6f333d23f0313853e5200b997fa4222dd1f76c"): true, + common.HexToHash("0xacc1a20b1d26b2bd5de3dead295b1da5d6350523b7a73fef50a50d168734b2d5"): true, + common.HexToHash("0x8f8f40daa5564962059e3debeab61469f8d966bab49eba05174610f3f72e9b6c"): true, + common.HexToHash("0x785a6c77881ac804e9386fbff1c85ac081fae6b7324454c43160c051926d0d9c"): true, + common.HexToHash("0xdb7422b9b92ba0e39c0f09d6c154ae488597586f6f2c6bbd7b50144bc1359966"): true, + common.HexToHash("0xdbf65aa5106d6aebe81af57f47bf46f582c2421425cfc066103a20131005e18d"): true, + common.HexToHash("0x1c39522893670be78139bb1cca6f27a2eca25f8dcd187b437c7476e0cd8a39cb"): true, + common.HexToHash("0x84ce809baddde21b63f676e76a36b2f9fe9164c9f31cb25c7421ac6825462512"): true, + common.HexToHash("0xd172787c645d00d101bc5103f43ce327159ee744579acaeb816e9f26374cde7c"): true, + common.HexToHash("0x9ae190ba48e7dca56d04e4ca038150f92946834345312c45dbc174622ee8b1aa"): true, + common.HexToHash("0x5a3da3cb27b3709766e3201d0b5c1271a6c9ad9180ae56763e7912dd6814efcd"): true, + common.HexToHash("0x56bac7dcbb55c5e5ae8aa0df5966b1ed797019f33e7f95bcf0d087b658197ace"): true, + common.HexToHash("0xc8654fa1ba2728170afbc9d9b0d3a10114885b7a70e132fcdf76c207408de60f"): true, + common.HexToHash("0x735314b36d38674320c5e9eeac95211b142f4eb052f15de62489b16fd3f58b7b"): true, + common.HexToHash("0x606d05aa218a3a4eade06ecb3e2b23d6d0a35d51aa8781c9cdb09febbc8fa938"): true, + common.HexToHash("0xc31cb63218bf059cee47fac6f30ab6ed8a547d4c686f4297266da8972c2379e2"): true, + common.HexToHash("0x7d8cc03c0d9c65d179a80300cf8b7e9ff8b9dd2a1fc34137ee4353189de24372"): true, + common.HexToHash("0x8b84bdcf0e4956b2a458a31c3547a0b4b42f30077e1ce16f3b9b32fd5959bf52"): true, + common.HexToHash("0xdb22530ddd87fb453011dc1aad3e9a929fcce156d2d0be696e09b216a0cb58c8"): true, + common.HexToHash("0x0e128d97369b36d16058ee36f7a0a6045f8d4a05181098b777716c2731ba6edf"): true, + common.HexToHash("0xce465461721e91a263d250d0bbcdd57138b31866f6a00784bba93df8846ecdc0"): true, + common.HexToHash("0x5dead4612e24cb1d48e2787c92ea859e2948d40d185758d66ceb0f17a175f037"): true, + common.HexToHash("0x5d41bfc9aeb16a993d882142a1b4b0a9ce9090a9c843ded08c59df9ad88d5fd6"): true, + common.HexToHash("0x82449705a363a5d57f5c9ad36e31f4d8f7a0dc7a81e5bd911af375d7a4b5eefa"): true, + common.HexToHash("0x252bd9c01d3dad645a5533fb8f272a39d0bcc05b5255962924497ca0f0b038d2"): true, + common.HexToHash("0x91ed9b098f26ac74018e506dc722f6783cee62745c9a4d8bb810c68b7fff6f20"): true, + common.HexToHash("0x64b6290747858793fe6fdf52caf58a4535cdf885d340ab404efef4bb752e9c67"): true, + common.HexToHash("0x1cff9fdd15f99c1224d50633d1a7c6d5329803e19c05788de655b2ec9413289c"): true, + common.HexToHash("0x9e76f6562992812a301d4126860f04d2c7c8d0e3b1d4808880ceff00544072db"): true, + common.HexToHash("0x212c318716b45b2f4604b7646c5bc9078d6455d0f2df4a32ff4ba8b78a5bac4a"): true, + common.HexToHash("0x54ea6d99373c2b899dbc8a38fc09b3b90218ce056350000c4aa691254b5dc8f4"): true, + common.HexToHash("0xe6a89c4b67c147534ed6899645aed97e5d2dee1babdcb0af6a84391998314df4"): true, + common.HexToHash("0x9180c4be04d64740ccbd9b471446226c3ffa3ef6e7f35032af927e0579874c1e"): true, + common.HexToHash("0xf96e64c46ae849fb0a065399425073d8309d83b8a3a9626581ec1da647c03c12"): true, + common.HexToHash("0x3b21e334a93c707136b9957bedbc71191131b86cf516ee9e1944844d2370f0dc"): true, + common.HexToHash("0xfbe464df55b1304eb5e97fba463d85363c2b413544566cde7fded5a2b1f47ab7"): true, + common.HexToHash("0x9a4782c99eb1635e6286c757958e2bc2c8896dbbc8e637d8d46e9017a7e1f3d2"): true, + common.HexToHash("0x452b19abb1f3c004860637cd0706de5200decab97902893a7ea6043a02cac365"): true, + common.HexToHash("0x07bb85b6c830c4e8f8a1f0ffc5253a5e42e91e6ca2f1bbcf8ee61c1268eab72f"): true, + common.HexToHash("0xea4d6648ba45a1062862f4956a9c34f3bab5f4c09af701708e4afdc9de5dec38"): true, + common.HexToHash("0x2472e9a14a165a140df820e44ce4aa79d7de72b0a191646efce313569eb6e281"): true, + common.HexToHash("0xe8468330dcd661b24841869c072f01d4b82ea224fe6ce27e81a67b814b7212ab"): true, + common.HexToHash("0x89876ed74645ce5c762a64e8ca2ef77560f769f58d25decc968aabd58edbbdc0"): true, + common.HexToHash("0xec958a8e4fa973b2b3efb5187436538ad6becc14d6b472331a63e5524c29706a"): true, + common.HexToHash("0x572a2c37e74af273c161243383c4ef85179939b7e0d1afca4108826217611bf9"): true, + common.HexToHash("0xdd53491be2b5e120b26a2d63fa3487c5ab8f4057d547ca72f7e69fb59044ccb5"): true, + common.HexToHash("0xb7e2608746f213b84efd551844df81439dea385fa10174d9fe547d9414e7e206"): true, + common.HexToHash("0xab26fb81c6d11ca84aee9bb264df389a3e537f37ad427a06144288c82e6e1080"): true, + common.HexToHash("0x7e908af301e44d76383a2f6ec8ae77c3e7a18b1c6117391c3679624a516677d0"): true, + common.HexToHash("0x7cd6043eb8377ba76e5d1f0174d854d5a9d06361bc2fcee449d1f1acdf01b9a8"): true, + common.HexToHash("0x0c83b0d5b7b2f7ec95f11119bf9d54ce7a08cc7bed8e52e46549d639f01f5748"): true, + common.HexToHash("0x2cc024656802593ad7721ca4f381581906d358602a64ce7f1d0c42cec2aec873"): true, + common.HexToHash("0x3b2f43ba0afa9b961ce0fff21bd142d214f0d4f1bc24645ea18d2a4c57b7ac3c"): true, + common.HexToHash("0x06d05b674d02a9935240b2b15883be74a8f58453f0f363f50aaac478034114b0"): true, + common.HexToHash("0x76430b0e4dc5e57683556b1ad1af11a37d6307632359a4351993e9e4f75ca572"): true, + common.HexToHash("0x99468052aadb7e9d0a4105635dc86313ea9db412156ff9cf62057367da58b65c"): true, + common.HexToHash("0xfd1f5e076f7dff42458344ec17db1a2c2484bcff16e16d54f1ae3b43f449a4f6"): true, + common.HexToHash("0xd7a64577923d48dbeaa4011b425ca157cbd4fff6ae20fe91de9dea56245382c1"): true, + common.HexToHash("0x9f7dc94ec23e3655d0ac2a5915f7a0e9a071f1d3d65923bc938cd8cce055639b"): true, + common.HexToHash("0xf8e5c507c693c9c5eed719964f25cff818d30ecc51c0f6e46ab40226be402173"): true, + common.HexToHash("0x7334bce119448f20ab5b158f393f88759557bedf14f56f0e73381cdabe86ce00"): true, + common.HexToHash("0x10980dd50e11e2afc18d8a5d590216f696becfbabf35e2f4315463eadf5566cf"): true, + common.HexToHash("0x7f7814618d46968d598e44a1db07e1ba9afb6f60b78c1c5735338e1c1752064f"): true, + common.HexToHash("0x2405f0390e768b3baffeb305df4cc4b588245b2b30e02a39d122f8ae7054988d"): true, + common.HexToHash("0xa4385bb8cde172f588ff8707c1cfeeb6d09a824c1a6919fe1d6b41ee3edfc5bf"): true, + common.HexToHash("0xe4eda79abac61c9dc300bb37d5ed61d127dff02626bfdea5b96b42ed57adf0f3"): true, + common.HexToHash("0xccd2614f95a607e0fe2cd7ebd5ae0933559dac463d723f46f34635444d4e0c95"): true, + common.HexToHash("0x479eed95c89a80c914b02b65bb73926e1d501b5bed829559a2890fa2eae7f745"): true, + common.HexToHash("0x674729b10e97a371b3e2000a673405a063d49b3d3848de0b7c3622f0ae28d1e4"): true, + common.HexToHash("0x8ea0aa200da9e90adb96d904160ff9737d4d186593553a84a1013959a03c43c8"): true, + common.HexToHash("0x41b9289565070028a7ce3e118910160685a98a9f034c6e55122d9fe177a96c76"): true, + common.HexToHash("0xcb09cb2e60ec19dce2270d4a2a1df16323850e2813dad9da1d75d7f72d5a4dfd"): true, + common.HexToHash("0x3a5cb598b78aedb4268bc5c19e45733253d2166bd0f499e6ba7e4c973b1b90fd"): true, + common.HexToHash("0x55ee6e584326cac4f7749edaf2a76e6ce4d205aa6e048a7e6efc446a382f2396"): true, + common.HexToHash("0xdf76eff6323f1142a9a261e8bd35f2f357f67850363762ec69181398337eb2e2"): true, + common.HexToHash("0x27994c4c284fcaba892b49c31bc6540ff40dcd27b36431003c9f1d4fc1d3e22c"): true, + common.HexToHash("0xd0070300ace36dec7cff86d40eac5658c4c895d7ab3e8c03f3a54be4e5f635b2"): true, + common.HexToHash("0xf5684444fcd9c803cf0898a71cba740a1728f966fa561e913d6e7e6b32ebdbf9"): true, + common.HexToHash("0xf8879ef0d3c962054df4023c3155a89d46d448fdaafbac032c8d26cce7a15ff2"): true, + common.HexToHash("0xed319db44f23bb2d2b76b03127308f81b51cc0c2f4174e84edbddc8b3211df55"): true, + common.HexToHash("0x0e97223869be768e5568af002021b5ca6ec1507d48c28e17e9e6c84437432fe7"): true, + common.HexToHash("0xdec37ea426348704145a655a4edc713bee47e85d1ea4545d5e85b1983b7ca3b8"): true, + common.HexToHash("0xc61b41e5fb6e6bf2e6014fdea1ee6159b7e5aa5dad4b1d377975b536b34de9a0"): true, + common.HexToHash("0xa35a79da6a9376eb452dcccff91fabd4d833cc4a76d4f44e2b480dc3cb6fe299"): true, + common.HexToHash("0x7f91c8eb4bd99971825cf7862e0ba95b6e8989bf0dfd59c9c3bd08d97d5a3619"): true, + common.HexToHash("0x8da369c416decf5f85be8b50d157ba2ca77c8094921cab8629cac07f97e32e81"): true, + common.HexToHash("0x631c9df5da582062ef97cd800adfb4b359747579c8edff5894359bbd3c00dcf2"): true, + common.HexToHash("0x9571e49ba3306ef56ba7f9feac9c12c10add62e81356b7f6dd08fd8446b18e79"): true, + common.HexToHash("0xbdd12f3c636c981f9f547bbf5db1dc5686a9fef06bfe42986406fce758f89377"): true, + common.HexToHash("0x12782fe69787a906170f7923a8e3d7aaf8fe6f17290590eee00425528f5017ec"): true, + common.HexToHash("0xfd74c30e0a4f8f369dce6e2597f188fecf2cd6ac4087427ac0dcfb2fd3cf9707"): true, + common.HexToHash("0xecf0acebf4beafaa4b12901e739e81542a253b16b8baac9cda69c4de22009fa9"): true, + common.HexToHash("0x7f1699ace106cf3fcf2121628c1b0636846fd992c80b139438130a54312a577f"): true, + common.HexToHash("0xd944fd63365bd8be6e02b75c0602b10168d727374cd9655f0cc5726181f7bac5"): true, + common.HexToHash("0x813e427b94b28deaa6343d50a31182faad1649a1fb41e406daf23bc5e05cae2e"): true, + common.HexToHash("0xded93ba0cf958abd2305a9af9f24e21b3e665e562d604bfd7626fcfc068d8343"): true, + common.HexToHash("0x42e678754696cc92b4c966f981096cc3e6270ccf547a381433a684c5c8a8a70a"): true, + common.HexToHash("0x4fc1c3301e38f837f5a51150015b08c2318ab4778538d49474cffb4ab57b1142"): true, + common.HexToHash("0x37a733e3bd56bbd45fe6535c275499223d03b089294f0b7584bf6e0113aa7577"): true, + common.HexToHash("0xdd5a23b79d6ae71e2cf86a46e13afb5c4ef4d2e02f2fbf8325a95a43bd8ac957"): true, + common.HexToHash("0xf0f616697866a2d32a46eee44112ef74b5bd8bfc581588cb0e37aa4a6aa783d6"): true, + common.HexToHash("0xd040362426575a8580bf4205887a053c7b44865bc6cecdb8c7dbeefe8251cad1"): true, + common.HexToHash("0x8881b2cbcdf2c0a943476ed687afb8f0c37a00be2f78ca12dc55d5493ffbd354"): true, + common.HexToHash("0xc2ca96c7006f12fb09aeac35834f3290fce3c2eda8dcba5ccf20c9990a818e8d"): true, + common.HexToHash("0x3d60b1fd092f3d80f3d5295cc9b61d2a5e2a3d565a0d819f8d6222cae8c49981"): true, + common.HexToHash("0x1bf7147bdfc9aedf24237df0eee93d8bdacd1ea1304cac8c12e1f12a7d4a796e"): true, + common.HexToHash("0xd676861652f7551c5c97ec333109ea0cfc57498024ee4aa83dfe909801620607"): true, + common.HexToHash("0xfb708cf6304906cf2e8786b274d60687e1816c1425d66ac3e701201e21bc9927"): true, + common.HexToHash("0x2364e058cf069f55d99e4035cdc34065f4bcc5379b2bdda02caa322738b05873"): true, + common.HexToHash("0x3353e4581030f66d506477a988735854abca3badd49d4a363dc87b78362df0c0"): true, + common.HexToHash("0xbfe0bc2703e652d5ea857f6679c77572f09c9ef6a1c4caf4bf9e8e04d4738433"): true, + common.HexToHash("0xfac3ec3c9d0b399471b52c1dd4695d753201f5c1d8f00be55d00e2c16acb7940"): true, + common.HexToHash("0x49e9269da6ac7e3ba546c3e679cca77e5afa311751397dfc4e6d8b68ebce563c"): true, + common.HexToHash("0xf8e0178135d185e923d62bc619d83068ef160f1d18dce1dc48134045e2695353"): true, + common.HexToHash("0xf33b47ba85c60ce0a13cb3952192cfdcdcda4a4c8d11b74fc65b908efe9233f5"): true, + common.HexToHash("0x9fc6055c6cc0869dc64c56987b2d59eca10217c8b378fda4b55d6aa3619dcce2"): true, + common.HexToHash("0x60d84613bbdc484d0306326cbccd8492951b27fd5e761c4b29f76640fb730154"): true, + common.HexToHash("0xa5b04d6e1e7f7c37c75d4987c04602188d1c93b58e578fec366b102a6491aa12"): true, + common.HexToHash("0x7e9c965e830c615a21dd183cbafd555af842c97d10c5c75b2901aaaed2ea21a7"): true, + common.HexToHash("0x25a4a4dfac6326d93b63911c44a9b17dc5bd85dfa34e8af8a807733ae54e6765"): true, + common.HexToHash("0xe3a6b4bb70a7a6aed6260e46dee8ea557932ac55cd8fd13c2a27391176a7c50b"): true, + common.HexToHash("0x15b0688e079f7645d167b958da3c033c8b13b7a0609adbd6d368ed6545598168"): true, + common.HexToHash("0x50ea56acc5f84b9770dbda66a0d1e858ff7ba3cc0bb148f36c460afec97fc6c6"): true, + common.HexToHash("0xfb414c67e8f7872c08150653602fb54d39fb52a677040625a8cd941bf6da5135"): true, + common.HexToHash("0xb44b48d8e4d2c30abb39613039fe1eb706c46f746d01abdfbfe20b8c55ee5aef"): true, + common.HexToHash("0xd6b6b6a23e9b8dd83119d49a0e2553de82a63b292fa544360eea2310b8bf0c2a"): true, + common.HexToHash("0xc63aba8fe690c69bf2bb1590c003cb7d7c90507478a8a2c2d09663b6c6b15f4d"): true, + common.HexToHash("0xb7cd4ce2bd5e84db595c08930e40057eac03fa8efd82d75117b2b2c982cbe1f3"): true, + common.HexToHash("0xa855cea9791161af16f2c70ffc7751a12ddb87fad3355e5d9aeacbcbade31e30"): true, + common.HexToHash("0x714f9af8763b4ffe55de83615841630b35543d7c89aad46131fd503f877aa226"): true, + common.HexToHash("0x050cba9c161fa40c1bc24e81cbcd7f7e3a7274802aa7958ff8834180f2dbec5c"): true, + common.HexToHash("0x2cf0a91c3fbea37180c2a0d29c947b0a2aea86a60890b40ccb8b4f82ec317443"): true, + common.HexToHash("0x6f3662af04c5cdbbff62e71ec82a6ed174d3a7b84fb9d4ed76ee28456d0d3ef0"): true, + common.HexToHash("0xdd791284e88676a54a42488560c5de35cb1bfc7b83778d469df374a20113483b"): true, + common.HexToHash("0x6bf0d257f212b513e0a153ae5a8e2162522b616a7a82a934fc82ac37d14515d0"): true, + common.HexToHash("0xd36d21c4826f08dd0f9205e3c64f7088522e55a662f5a5cb19ed40d1043253d7"): true, + common.HexToHash("0x1c865bf0dcf426e7d4d44e9a77abae545e720d94b3aa498e2e0bab9ecce4617c"): true, + common.HexToHash("0xa7101550eeca33c17a9b692f3e20b9e0daf6ebfc9c7c545e3c746752be1f99b1"): true, + common.HexToHash("0x7c401687de64c560a60659c96955734b86697fb97e5be2557123cbb43b9344e7"): true, + common.HexToHash("0x0b44796bee891a66044eee8064e3e801129c039e8213e65276f4374ac81c3fc8"): true, + common.HexToHash("0x4560dc3bf6406a0e836477a81f94b5f59a4319619c6a28c018e8cd0827ccf4b6"): true, + common.HexToHash("0x9c9599a3170385ebf98d9bdc2329fc1b7cf8f794a14b1c2ff709d4fb1c0b09c9"): true, + common.HexToHash("0x561f8f9e331c3654e17907aa3b898cb2c626418b2c59c934c7164e5da5001ee1"): true, + common.HexToHash("0xfcb1bd83620a3a97c19ef126a2c5a28baa071b7f159f8e33a23b5f737726a082"): true, + common.HexToHash("0xdafee1b804b8a943ae014802d3cfda3b514119776024d3ad44ec169660679cc7"): true, + common.HexToHash("0x7f8e5a3db5e69e6d1966e24401ac56382427a4cadbcd6be4201db72971c59270"): true, + common.HexToHash("0xeddd5c36a328e487d49c1c87656155a35252e48e94da0f4a81d0e2f76a79fcd8"): true, + common.HexToHash("0xdd365ce6de86fdcf2f2d0c934ff806e4b6813c05d1317920b7c690ae4c2eb883"): true, + common.HexToHash("0x7014f0a7518dc9aaf1c5eb464401877e41d4095e87aed41561e20c3531b3fe70"): true, + common.HexToHash("0x251f5b3c5ba68f44064de88361c13c3eae8ba633604d6fc31245adaa856df8ce"): true, + common.HexToHash("0x21a18e94d402eadac39ed717f5cccfbe5df3a25324c4edd880917f8ca6c35fa8"): true, + common.HexToHash("0x1944953fa60bef7874e1a94414f6b6b39425f20df285f65b999bf1aab5ae3d23"): true, + common.HexToHash("0x551590420c6240f66458e502e49666bb63c40cf9127ce28662d730fd9d176447"): true, + common.HexToHash("0x0d5c64f2e0fd6216f54c5aa7282e0f08b2236977a4d06dbf8992848a815768ec"): true, + common.HexToHash("0xd569d9472a84eb39809c4daf9ca43cddfdc08077b8775ffc727dd110108c503b"): true, + common.HexToHash("0x228c93b2f1de9a45f109e323cdf2a5864d4967e21700fa02feb34c6a9b6adb96"): true, + common.HexToHash("0x1713e6ad0eb91b2ed8690e6784968f9e9938b5f80ca6ffd0225fb54c4c53a0e9"): true, + common.HexToHash("0xcf3881da579dfd0156484d6c11b72b2ecfe698601b1f1cdba37b442ca9e4010e"): true, + common.HexToHash("0x0a4a4ee81a26278a8b5d114766aba2ec8c9cd935a3b1d1665bfd6e8e187f9383"): true, + common.HexToHash("0x28a4611c78dcd0e0670b15a4ba7a2607addf06d69ee0baedb2b0362bf30af42d"): true, + common.HexToHash("0x1076eabf88204be8d6e751225326ce8cf3aa57fb3d73da3eb39e25f59891f90f"): true, + common.HexToHash("0x5d3ca4d17157e379f5893d0f81c99a9268cef833b911a9ed83dad80e74be2fff"): true, + common.HexToHash("0xda04af8433f21e728134277e43a1d915a2c002091396d4d802bf3b75c1f63ef0"): true, + common.HexToHash("0xb4ce451d3448c237f37ecf19c0e56a9cf9be65a5226022ea504aca38c7dc5c57"): true, + common.HexToHash("0xdf393aeb955872e8f7546a73e60a8a82aa1524ff0164cccf39c9c485550456e0"): true, + common.HexToHash("0xdbe8273bcc62a4f15a4ca2f606ad50b32f03318b892103b31bba18f227c91c97"): true, + common.HexToHash("0xde7c4500bddeddbd936dbce3cceb4ae425aa582c755af53c466438ce1873697d"): true, + common.HexToHash("0x2e7d43b3b0a6e0a07888614396f35d0a9749ab15649d282d87f78598eed9c70c"): true, + common.HexToHash("0x1a2fd7720e92678b63f92bb8ab400540f4dc85b127226868edf359c60f9cca4a"): true, + common.HexToHash("0xb653d83b6df8551efe41077d8092a8a3b7c6aa496a7026a27cd60c644fc54222"): true, + common.HexToHash("0x6f24ae55644d137cf757aa7c887e6f64237e8d9e9c32df35087d42b3d0d82ff6"): true, + common.HexToHash("0x364008b90dcd6d1ac3786a616e2bcff321c174d7a9a95c93d9b3e940dd2eeb16"): true, + common.HexToHash("0xcec9e2ecba446dd42d626495eabadbcbe2bb4fe611db0ade3f5bb677b951b3c4"): true, + common.HexToHash("0xfc665cd13dcffa213db168dd7fc60e5af057c9ed4b52440b091d547d7fc40031"): true, + common.HexToHash("0xd08852f2a8477b5ef7fa2d81badfd7df9661b53fe2fcf17db16d31e1b27cc587"): true, + common.HexToHash("0xa3390fbf7b2acb0af641c9809388a30b2bac5a04939b8876109418ed8c3562de"): true, + common.HexToHash("0xe40ec778c27f44802ab100cc1e17698f4dfe1cd421a7bd55dc691e5270193fb2"): true, + common.HexToHash("0x71f2a449254dd233db3242f093303e8e69e5322e1e4917e38a79cffc7259400b"): true, + common.HexToHash("0x1196acaf86d0e358899d842b524c9b5b50f9d4ddd3f8a3fc84c7442ea36f8134"): true, + common.HexToHash("0xf2111628c9307b33d1942a1360dac769091ad1ffc9ad9ffc1abcac3c369d4d41"): true, + common.HexToHash("0xfc486f163d375a8d3791424b41398f1a50a221fddad4711ad6278807ef728df6"): true, + common.HexToHash("0xfae525d74b79e0cf4e5dc539b338ce19d6608119f3691dc0bbeef23d90e2c2f5"): true, + common.HexToHash("0x0b52da5a1be4fc2b721e492e45052d7a5ef590225b8dbae57e1ecba6890a33dc"): true, + common.HexToHash("0x54ab76d182eb39b8a0020afba8c50e48f97b6a564875d608f1604a87e36cb29a"): true, + common.HexToHash("0xa8dd1e56e4c3d801ae06ecb1fa8b57a41c6cf6ff6406464bd2e3b89fd43e8e20"): true, + common.HexToHash("0x8ab6f73790d0434623e7a084edb566b04d3da2e0d669ef475ff4ad04ac9fae68"): true, + common.HexToHash("0xad67be369c2398c73e7a8be436e20d95076033d548e1c0b19a07695f60776d4f"): true, + common.HexToHash("0x1b0a0debfb24ad8687e461b79a47cb37cbf1ecc1748ec5d48957e847e73c142c"): true, + common.HexToHash("0xf34c9be605c4113794c863445ca44ec350c29b87d90c54b80af66a84d390d442"): true, + common.HexToHash("0xf27b961f3b3ca46a1f8ee6df28c09def8b95bc44a7e99bc5402d6b8123a791b4"): true, + common.HexToHash("0x441f53b38fd74060573540de5bb036d3041a843c75af3c6eb94522aadd92e177"): true, + common.HexToHash("0xdfa790b856e906c85c010ea52c98946feb199dd78b5459db733f766a59d66fa3"): true, + common.HexToHash("0x680d53c6e61e48f7224ac26ef220a25cc530ce03acd02f1aeee9c60c89a7eeb4"): true, + common.HexToHash("0xb4f458aab610ebcba07243a3f32303579e12b422ad53f2a7e30e02f28a3e7c3c"): true, + common.HexToHash("0xc4770dcf409ecfff2ad2e2f19cd5e44f71b479c161b732d0206b3a27fc555536"): true, + common.HexToHash("0x6ff8bfca9739d6e6226d71e2e7410d91f074331ae127fd7491467b03a9e40967"): true, + common.HexToHash("0xcaf812ea4aa963d02ef04159dd5953b44aa506637cfdfe4f18703028a862e037"): true, + common.HexToHash("0xedf8ca74dc4c2a6d68d918b5e78be0b2b01b407441207ea32a39bd4ab8aa9bb4"): true, + common.HexToHash("0x48f53329415c02a57c9a7299ba16864d028bc57890b22e3166404abb6dee36af"): true, + common.HexToHash("0xb2497f985370f44ea97e4e716d69d2fb16282ee38497b6874742c73eeaed91a6"): true, + common.HexToHash("0x4a932880f82112b0fc13d8b7961b3839a5037b9154635ec810d6eb8953498af2"): true, + common.HexToHash("0x1424db46bd2cd1b56c3f5a7d394ab9ed507b8237982ecf9cf2adc190a49032bf"): true, + common.HexToHash("0x6e0896c81548ed522908037e90a17d3292ebb2beedbe629a106d7b6c4b5b98e7"): true, + common.HexToHash("0xf772fc373708591d7a9f3387ae381b42dfbf319c436d98aea1273e693a17e3f5"): true, + common.HexToHash("0x6ba17eed249c7e90577b5648373c0ea455f43a674f7d3c861a30c503df1d8c2d"): true, + common.HexToHash("0x35e9a51e3d2c78884b214ad31f2cc32678a3c83ef5bd540e86d0c6618bb5b448"): true, + common.HexToHash("0x0b732bcf8279d14c12c98eb7e575222ca9310dbeca221016636b5255d2065096"): true, + common.HexToHash("0x79d6779edabcd21442e02110994a8f0e1cd0567e0d8b76f4614688c956acc3e2"): true, + common.HexToHash("0x7af48bfff7f18590c5806726fda8e9471929bd36ff39885e94250b888b1fcac0"): true, + common.HexToHash("0xe63518bc0417c7ad991c6748ee26fca0b0d854f3712779985b9f7fdd34a7c74c"): true, + common.HexToHash("0x9410e69c392decb526d8bdcbf9780a493621e107a058a384995285c2feceea9a"): true, + common.HexToHash("0x04e4dea03f3a9f7d04b606c5169968deef955c609176a7910a8ce4a6a9db60b7"): true, + common.HexToHash("0x0ab188651e3a97bc112f62d2f753a3fc9bdf5514376000882efc780f5a22b709"): true, + common.HexToHash("0xe263eddb6c5d33a7c3c1f227d03fdde6b24d66fc37b4db9221a07a2bc2c3670e"): true, + common.HexToHash("0x85348548cdcbf130479755658669f9624fa51098137b7764174cc8db9b531934"): true, + common.HexToHash("0x5521c4eaf1d234302e9005fc8143553a50b0fdc10e4c8362770fa666ab1fdf25"): true, + common.HexToHash("0x0b14a5035fed90e08312ac897dfd6ddaeaa5136cd55ef000c30fedd95d48f8f2"): true, + common.HexToHash("0x1ce2ecf9bebec8551e01c86dc8693f6fa8f1f9abceb4f6d4f711f955e09a4b27"): true, + common.HexToHash("0x5f139b30b33e4810ff43850c3b7d3102a32011d1b6f01dea6dce2063a869b3e0"): true, + common.HexToHash("0x995f489ee8a3407846ea43c6526e958e61431bbae818c4477530e61f2b2479dd"): true, + common.HexToHash("0x000bb252c64b0eb425282ae98869b2b7b16c5b3946af831ee4e59f0a2eb510f3"): true, + common.HexToHash("0xe2d1279ab58c140c0d8a9a255e60f5338940699a512a3bc43faf0a2fdfc328e7"): true, + common.HexToHash("0x6a28961c7ff8c30b8e936b26dfbf87c31a6701d95bd60162e068674f12be2d68"): true, + common.HexToHash("0x165a07af3e083c1c4eb664667420eba1eb854739e9fc04252123952bdee39d09"): true, + common.HexToHash("0x4169ba16a517de90940276ace656eb6d5139d11e09c0254c308a1c1c85de04fa"): true, + common.HexToHash("0x562f00dbe96e159a7596b395deb4aaf14128f8fba91322ead77271374b9602b2"): true, + common.HexToHash("0xabdbd293ffed707e552cf877b147d96f94a416811483cbff4e00adc0dbcb4fa3"): true, + common.HexToHash("0xe744e1eba80627ff3a74c95bed74bf9515d55eab2ba3de5e0d8d89c2b6ad2907"): true, + common.HexToHash("0x9ed315b6659a86f0954cd7a970bac1ec92129919744ef3b7584e673ed3cf8232"): true, + common.HexToHash("0xc0e696ccd02de24fc9ccf8ecee3e48ce16143c27d4d504bbcf0a6f53dd316551"): true, + common.HexToHash("0xada7b81b63c0ba6ff73b2ca37bdb9de723cb9633ad107deaf45f2a6d2ce9d8be"): true, + common.HexToHash("0xce3f2975fea79987ee951fad156628c4c6d7b20b2792f79dbfecd7959a8c6198"): true, + common.HexToHash("0x6eb5ec1a604b2b2faace03dd889b2b7cc6bc580611a1afb8b72a2cec4ab04751"): true, + common.HexToHash("0xd020212e5b2685af635e1bc827c0f9e45e7a900011b1d7f84dc2506baf11811f"): true, + common.HexToHash("0xe0686312b2efeed70f6d33facce4fb41c1240b75b1d983ca74d12e1fd072a870"): true, + common.HexToHash("0xe6c26e3827635233ff876e3fd777fa77aeb0895a3360f83d7ed2b51060bc7874"): true, + common.HexToHash("0xec6b95c6ca0b33e3376b334722bd4d8f7afa3899d01fd2821d9eee79557380d5"): true, + common.HexToHash("0x8be0b63e85a745c1cb341b1dd451d4e24bcfb68849d27d6a39d9a7feb7979523"): true, + common.HexToHash("0x06b73c05cab076fd2cacfff5cba726227abb5eb607a3235c27aabbcd9fa536a7"): true, + common.HexToHash("0x051c5e849c797a835fbe4c81e24367be116fd4c9e41a30e5883a429e965afea0"): true, + common.HexToHash("0xeb8d876797dead5f48afc4a897cc2a9dede5b859d26881d933edf08e89b552b8"): true, + common.HexToHash("0xbe50371ed809ad0156095619a1c03391cd19f804a36b27becd23ffdb1ffc1255"): true, + common.HexToHash("0x7ab9cfca237c6cf8d39294d96dc7d46edf8f5990a73dbb8ca3c6323fa3f9d5d1"): true, + common.HexToHash("0x4246e22a2d2062a92a48893e9532bb1eeed20c206b3fc15af16a3aa68dd9b447"): true, + common.HexToHash("0xbce43e3bcfe79082d9202f363a0cc35257dbfcae1ba0dd674263dcb9a70fdd40"): true, + common.HexToHash("0x5f8a10f62f96ad999f495d0f3a97346f7b5f6643531bbcf906acde8e045ae469"): true, + common.HexToHash("0xb79c7c8d09ddf5c438271e2e8dd44e21575ac3e59da55bb54c28ca595c2247a6"): true, + common.HexToHash("0x3c8ec95f4877ca7326863ca4f6102510838b1ca460de197f3c60d06ce5521698"): true, + common.HexToHash("0x35acb3b869ba7bfa2dcb3f3e94840f3062cb87f86b7e607dfb6e141162625d17"): true, + common.HexToHash("0xb8c02393785e6a60a1bdf170e66bab44d067a875c2273bb23425187afb0f62b8"): true, + common.HexToHash("0x08a85c3300bbf0c7a3d077946e8c1967190567a90e4eae57af594e638945c460"): true, + common.HexToHash("0x3fc80e38e40b952a4f0830a1eea25338919a007089bb89c129ae1074ef832b8b"): true, + common.HexToHash("0x895ddfb73aa9d567dfbbe22daae08e9ba9eaa3968370a901cea1bb5e4342e595"): true, + common.HexToHash("0x91257cf9932f7b9d653ec5ef03b7a61e1745b219cd647149f75aff7938364103"): true, + common.HexToHash("0xe07182cbe32779f1948557d827b58b38de5f35c1854cff066549287f4c11acb0"): true, + common.HexToHash("0x75f29c2429d89dce37be5e1b090557cbea25e8c6678a2701080a36adb41f1bd2"): true, + common.HexToHash("0x215989b4164155a08ebfb33bfe6d8646dc6886cea4aa8ee6c69ca8eeca5c58f7"): true, + common.HexToHash("0x5b43d3913395d8bec6558bdd90f1eb78b4ce7a1b4233c6f327589068312bba64"): true, + common.HexToHash("0x61a2c5faf0e3a88f02be44f2bc40b5f4d5fc522c754ce7619de041ba6095579e"): true, + common.HexToHash("0x07ed8f78c3df10d4f5f96c6c4e01e556355401ec0660b2c86a805e5ac453a25c"): true, + common.HexToHash("0x1d42ada0068e7d20cfabecdb3b2fa7da2ff0ae780f9c26899845022dc07ec728"): true, + common.HexToHash("0xc71d692560dcb16e652c2d949c6bce903b44490f815d5202d4192578c0a7518b"): true, + common.HexToHash("0xf1532a1944db7351c94b6d57d98e5d53ddc89c66e08a9370f1b16e90c147639b"): true, + common.HexToHash("0x14f5dd50aa30ebc6b453fc5a8d23090bd242b8a2f2a173758e4e0d1e0358bd1c"): true, + common.HexToHash("0xa40e4e9ffa1e1c0d51cc6a716654e6c18a1c606629d14bf2e254ed16f464e317"): true, + common.HexToHash("0x0a708cae0d19d8fae60e17f6757e9bb7900247f4824ec76ad096dc30d3360def"): true, + common.HexToHash("0xa6f0679b1c4b38f114ba55ac0a5ad0fb99db60a9effd4931b420f264ad20534e"): true, + common.HexToHash("0x3540449cb9bddab9f3e6b4d1d511f9c24ea952ed8ee6ab8450459d938fa50510"): true, + common.HexToHash("0x343418128e04b53be7bfb50614189310cb52d4b14d57720d99e1ea2148cfac6c"): true, + common.HexToHash("0x1991ec88a270b22a0f231eb2cf9a423a5a8f91cb0bfb909cfffe553dfc37254d"): true, + common.HexToHash("0xa032558872632aa884c6b9d1a0b5a3714190a969716b38ca8da2fdfdd66620d9"): true, + common.HexToHash("0x535f2eb56470c2553b7c2fd5fe996ef4c62d99b48706b55c8c60f22e9f6ba81c"): true, + common.HexToHash("0x4cf70b817d8f9784fa654aa4e8b9d6aff62c2d9a6ce2486b493669bda8563861"): true, + common.HexToHash("0x1d970925befe85d3625a35fd7ede2ad88123c0fecaff576cf9d6101355aaa299"): true, + common.HexToHash("0xea3ea3b23a8dc3bb6bb8837d2501858f2d4aa455b0a1b6835a28e646f0c7d272"): true, + common.HexToHash("0x0b4402f52eed0ee9f5a36839be0bccb9dc4c69a7338c8957ddcd4704bcfcc63a"): true, + common.HexToHash("0xa773492772ed2d76717e6d21e9cc91cdc966bc264f694adb0a678d67957f9d56"): true, + common.HexToHash("0x4d885b69a7e25a1817c6479a2fb4882d12ab9af0e3c0b610609aaafcab22c27d"): true, + common.HexToHash("0xcffc86905f42a08a13dacee8445b0e2fd01fdd1b9bc027e7275d8b675722fba8"): true, + common.HexToHash("0x2f6b5538eafb95b557ebd9c84ca5f83cba364aacc960525cc02052572cb51bc1"): true, + common.HexToHash("0x4049f0e9123e804601941f5042301a9c4e8307da8a2b08c8fd5e002fdea48937"): true, + common.HexToHash("0xe0c856771d01b38d590d445c3b6b900d87bdc6e1bc74a0c028fe53ccce0e70e4"): true, + common.HexToHash("0x61d3333fb30816d6d66bc7b7efc1bb46be6b192a6ceffa5555827f411a3a8be7"): true, + common.HexToHash("0x6b39d9b9488a6239bf5b521aba33eeff8eba00f505381659722ca1bf23314894"): true, + common.HexToHash("0x0f501a470a1f37a15ec4b39b2883aaa182e7dfa840c7505620a5326a82425b7c"): true, + common.HexToHash("0x033942433632ab1c7c5c3b03526fed4107743855bcfb6ee0a0f265ab6d5d94ce"): true, + common.HexToHash("0x26c2d33349bac1f2ee74505d5801bca997ef0e3f5e2093b33c7f226924dfa540"): true, + common.HexToHash("0x81c868a0270f702908a83d424322f905c5559501fb126572fb21d01051762371"): true, + common.HexToHash("0xf0a910ae2724f82d6850aee9057655d6bcb0efa7c2822467941172d8ddbeac68"): true, + common.HexToHash("0x6227ec2b4ee7f6582e2d8b5731cc47436b7faeefb424245b50f29114ba6a2893"): true, + common.HexToHash("0x84cfe05ef58f5ecc3665072ca077883e724661bf0c8c483719b31dee175e6c7d"): true, + common.HexToHash("0xf645d83262d7d5251bb4e5034759942de8769e0b09d28da22fd60b5da2097a06"): true, + common.HexToHash("0x32d6742ce648b38a0f901747ef84a3cffa5997164c4450368c51de47d6991f3a"): true, + common.HexToHash("0x891f1d9b3cfc7e20aba9c54a5e4bc102c6961b56b8b052ac52943c2c104ecadf"): true, + common.HexToHash("0xc64e20a7253cc737e11f5676c006e5d573e160e3e147db4ef7b8aaefb5c850db"): true, + common.HexToHash("0x21172019c46fb9c0d544223f67f2315feb9d2c248fc417eea8e74bf85609c2b1"): true, + common.HexToHash("0xc2797106883c488b4dcd5e7799a7498833cf6a09c4a836e3e40c63b80cb5d485"): true, + common.HexToHash("0x04acf79bd61e9b6e65931164a7c01d260603f5724a1b5a032e91878e22ed7ac3"): true, + common.HexToHash("0x35d27fe6d1e5b5c6a4020423872484fec30fec0e9362ceb507f6fc7c47a9f2ce"): true, + common.HexToHash("0x0eab957cb6bf2f07012984b4316754773e7dd87c8679f4d3f48a7d702d43f40b"): true, + common.HexToHash("0x96b7c64d03330e5bbec09384ecb8e8d6e7f14c9c6dc5d836e561c26b1526f08f"): true, + common.HexToHash("0x2a4a1d5ec7d0d38184747f857a3c7cf7defa9ee45b1546c19dd7e48432479c7a"): true, + common.HexToHash("0xf64f673dd68292975b66ab2d408f011dc2695f358d79a090dfe3f044170ecf07"): true, + common.HexToHash("0xd83525639a348b553bd80ee1c898d2f84c704700524c7f9a05ab9d9c3cb85d7a"): true, + common.HexToHash("0xdb716cac61247861d6c1583c01bba852d765598a6b176312544cfaf2d9739f0c"): true, + common.HexToHash("0x1561cf8e61d7538abe23f6462fe0a69435c749123a40d24c92ce60b877835009"): true, + common.HexToHash("0x4ada6426773f818304486e34a4bb6a1c8f65cdfd70277aa136c7188ea6442148"): true, + common.HexToHash("0xfaa74d8897c72fc6746dcf93e274eaa05b46039c84fa512c0bba15e1f410c77f"): true, + common.HexToHash("0xb0baf56dc4b3b92e69fb173c5329c0f337a5be1958cd22c69c07cd3b663a2efa"): true, + common.HexToHash("0x746644b505ba1372911c713f82bb2d8b3e71c28d1253ae6194b56b051d2389f8"): true, + common.HexToHash("0x3364bb420892cbcbebece0d04523f18fe1b7e83e3432529232bec1af64bc0df8"): true, + common.HexToHash("0x855868a75cf4961d6a2f4e0afaad7cd7b12c80bc2b6d26c5ad09b3bad13a80e8"): true, + common.HexToHash("0x1ccf8fcdfc4d91525b4160b5172c37c264e43d711f264685e27d6b589f2b96ba"): true, + common.HexToHash("0x0701654b82365f72301a88cc98104a58ed9d883c2c04a97dcfe6b0cab16e33be"): true, + common.HexToHash("0x80b8510916a78545e0f1b317d61fc6986e7dce3660eb0f9ebd9deb0628c07880"): true, + common.HexToHash("0x280f61907a8152a0f6a73143e1670fb4af0fbcbd6c3d8361bc95c15217a8ee69"): true, + common.HexToHash("0xc4ad0f271399a659e40edad4c81c4ed3e4a93011179348481451f1b1c7ffde8f"): true, + common.HexToHash("0xefce5bc16d08cb48bc56061b6495215d0871bf25579bccdce3ca4a1f2cffb33f"): true, + common.HexToHash("0xac207e4b285724dade94995a295dd0e1746dfde3551daefe75c449466ec7c1d6"): true, + common.HexToHash("0x522a8c1d9f67e8b28bdf7722f655b2fb1f1ae9e9975084c524d49be1a4501894"): true, + common.HexToHash("0x0555231939f8bf453415fb01d1c69f6193e9f6040166c4e10974694d732c979f"): true, + common.HexToHash("0x6e91078176f47046b726094067f3ab70a342079a02d84d67bb90ae285568403c"): true, + common.HexToHash("0x538181e3807f694ce92f1a98f70cf04846db16c705abc5336de01d878e803d51"): true, + common.HexToHash("0xbf8f7ecf25381d3654e915277c042d13dbe0e6e44a9004bee93e47a09094ccbc"): true, + common.HexToHash("0xe9c5d0ed04bc74b3b0c1e99b58dde881424dc37948e2dd42840265e5c78d49fd"): true, + common.HexToHash("0xaf70881d8b30462f5c428d2be6a63b98b2a21ce4cbfcdf87b9e8680cd31d8103"): true, + common.HexToHash("0x9a6fda0851da57bde01aa0a03dc849329a1c2f9e5c596f5795f00a3b54b5aa28"): true, + common.HexToHash("0x1d74f3c71c0001dbbee8d7bbc2019eec31b936c97383520066103720e6ce302a"): true, + common.HexToHash("0xc5138b41ae0f45855b0c236ccb8ba014ab7fb26f1f75d66d886a4f988c1c7fb4"): true, + common.HexToHash("0xaf297900a58f8e862cfb3109f4cc8d32cb775ff62ddfd7ad84964f3cd94cdb7c"): true, + common.HexToHash("0x1b2cf02c63eba801029b656f55f06e10f76a2c1ba6b60420582758f83b22357c"): true, + common.HexToHash("0x6ec37383c332276bf3dc52f7a963e48bd044aca3a49ae06b3e6c0493d3904154"): true, + common.HexToHash("0x4fa7fddcefc63e48388f6b5ecfb1b04b7b0760bf8381ab73e44fca9d9294e813"): true, + common.HexToHash("0x8c5eeb7bbfbc07614a8d0982b5eefd9a100735b1c9c7120e17583a2a0340f192"): true, + common.HexToHash("0xf0d4716f6458a6f7f481285d9850b20a70d1461ed413ee59fc65f6e58aa3b70b"): true, + common.HexToHash("0x544fd4a585fde110ce8171ba07ebfdb009d7c75d4578775ee343a29e260e0715"): true, + common.HexToHash("0x005c6d80930703c73ae5ba9b28a748ae6c7f795cf2a17c8031966481ad017b49"): true, + common.HexToHash("0x99f29f77c3a125b4f93f3ab4caa0fb40924ed06e73935b5dde6edc7eb1934f47"): true, + common.HexToHash("0x45929f133e8dc56c978f336691d2c36351b3d557f99a9a75e4487b165effc583"): true, + common.HexToHash("0x3367938263fdd904fe6de3eee12feefe36a568590330dffc5e940e14a84e4fba"): true, + common.HexToHash("0x3969e1ff21307c158b2b6193db47fa4501a7cb690459b77fdefbe246a80672c5"): true, + common.HexToHash("0x5f4835036ce12695f022d6406e90d6f3d7f53a7ca74dca41131296312835c597"): true, + common.HexToHash("0xb542a7bf8a6eaafedb775625b61f94a6514a16851d69fc5ba6da1d03c25f65d6"): true, + common.HexToHash("0x4be62c0ee40be10a9d84d4dc6ca94b405fcbfb34291663feb242944700c74ba7"): true, + common.HexToHash("0x8fbf522360e283379fc9c9b51c5bdcc0f33b8ae1fb1a74664b6831260fa03d9b"): true, + common.HexToHash("0x4be4fad44933f1175d018ce4a14a9f974b5748e3fc615e545d7517dcfd587b8c"): true, + common.HexToHash("0x3e0abefaf3116875136a650b6681084c4316885e6f4f77709155b4cf42714544"): true, + common.HexToHash("0xfc328853785f58b6149725527647179f148bbe4789226c33ce105deef17f4d59"): true, + common.HexToHash("0x8f879896b3ef71f19af9a69e84c81fffe6ff3c0ab7b04caa698df0e1f3c9695c"): true, + common.HexToHash("0xdd2509c19c350afa35e112829c1319ab08b18387fa9188c75b10bdb94023347c"): true, + common.HexToHash("0x4577ef160a8a504a66c6c05d45a7f47301e35a32e858ddab8e27e649db8b44b4"): true, + common.HexToHash("0xc7795ba60ad8c67ff8fbe08612e8b22db13fa10e531872d1b8bc0b566d119b04"): true, + common.HexToHash("0x9fe36608bf2a2d88665bd72c5948a3243f7ba8f488daa341717a320fafc664de"): true, + common.HexToHash("0xa691e15fd92b911993b9e1712e91d41b43e323f2ab3cc9a0d2776f60a9eaf75b"): true, + common.HexToHash("0x5bcc88d3d984416a589894b78be0b357b0e8d6aa2c4603b4adee09f6e1cf2886"): true, + common.HexToHash("0x9c2aa2a5bdc76be72136ad86019e688e23db6cc28fec83752a982a99cee02e64"): true, + common.HexToHash("0x5347e13b73fba8c1e1298ce60cb47c5b0de178a446cbc001a6ca47d073dd75a8"): true, + common.HexToHash("0xffd0e74260feb95f0e9cfe618a7b27b5087958ecc527c61635e72de19d51b197"): true, + common.HexToHash("0xc58d592b44b7d0bb3a777073a040573700814a8130ef0028cacebbb90338aaf0"): true, + common.HexToHash("0x532354b37e274bef7ca1b456d9866593a755d1afcc667c917d0509f1e71cb21b"): true, + common.HexToHash("0xd7606e6e6605d21c2e8a427c396a095673e0b5631745b72d6e0290a0ad4eaec1"): true, + common.HexToHash("0x00f0a8742fde7f04af91255440c34b259d54d4e81012bd880c1b8d777c5a7436"): true, + common.HexToHash("0x90a53cd75315d1a9aa409fba0d3b2228374655d2618f093dd16d0b259f00e56a"): true, + common.HexToHash("0xa9d1e7b0d6b46ccf57dfba12cc82fb5a87cda77f0a07e1210aaf42fa48a8312a"): true, + common.HexToHash("0xbf4ef280cc8b10326b57a91d362daf04e970ea21cd1c93850e661a969f71f66b"): true, + common.HexToHash("0xfac876a85a9d83ab77e4dc8364d9864c2f8283a90baf24af1ca485d41bffaebf"): true, + common.HexToHash("0xef2757f758a9545c9853e71f30ca15ac51e738a01507a1a43a03410e620f423d"): true, + common.HexToHash("0x8ab988c7da937142bbf31103692ee564c98b5f0cc4828213ac54b5d8ca10b062"): true, + common.HexToHash("0x9496ef5340340b1fcf7a192e8619d4eb119b5631f3d72eceae764fefc6535383"): true, + common.HexToHash("0x34e1ae3d7bb6defb29569af4c2a59cfd0a770fb21de814aedb0b0f4baaa3e929"): true, + common.HexToHash("0x2990a1ec314b9d79d5f339244747d57571c68e429407b940d664e35c9de850ff"): true, + common.HexToHash("0x2bbfabb2732d8fac7e1b4a69a8542a287159434a1d0f51417978db3af77af7b4"): true, + common.HexToHash("0x9ff7de488619a54ea30b510f2d5e77171d0d5d23a26a37690d05a064c6c072f6"): true, + common.HexToHash("0x57bd59ebeb32a9294b7124a8c8b89d225391925da6a0928b638a75cd508b007b"): true, + common.HexToHash("0xa05efc4c455254e0ed6a8e6e0ae57d67ddba8c5d5aa34bdcefb3cbc3ec770d27"): true, + common.HexToHash("0x97f1928d5330533f2024d65b2a482f0472199edf1cdb8b4aa2f401bbda6aa84e"): true, + common.HexToHash("0x58b19939c2a17ce8e62c6aceda03827156db94eae39ae321c2ee6a5de7896f8d"): true, + common.HexToHash("0xa0f7f3825d07922ad3a17eb9781dae84ace401d6f32d8976906ee6d7d33587d1"): true, + common.HexToHash("0x5ef4b2119e790e397bbcea4ef612c37e75178d5544441c1de98781bf08a44397"): true, + common.HexToHash("0xbe867cd167158c5ec3d2de17fea61ad62b53d4dfde77c2e820ff54342ced5252"): true, + common.HexToHash("0x1fef4cfacaefe4a5813473e2cf2786b76601833c0b44dc8bc729ab150e920ea8"): true, + common.HexToHash("0x8661490dee1fe3752c2725416ce1b6852a36fd5e4a75413042a4a8ed910aa9de"): true, + common.HexToHash("0x38679fe1d5fe8f881289035cc073da09e41bb370b0d1ee2a1515fce2a30bd76e"): true, + common.HexToHash("0x78dc8a72a0dc591813c4ca85d58e1b0e18b4b5eebb994eb29ab311e4f79f1cc9"): true, + common.HexToHash("0x83380958423c3075f95a0d81db0f727233059242fded6aec3772ef62d32fecdb"): true, + common.HexToHash("0x7d654e8978960ec3b08f70f0e837f1882f622d8a696adadf7e51e24fd2379d0a"): true, + common.HexToHash("0xb58caa16f8eeb4b822943268c4adff50e3fde1a609cc9cf473807ba3c36215ca"): true, + common.HexToHash("0xadfb90c3154dc7e7a5adc5d92220368c3724d0f310b98d7f3e7d16fcd9a3609c"): true, + common.HexToHash("0xb406e7e0d748499bec05e68c0b2b17cd421cafcbffe2d3609a9a1f2414a3f317"): true, + common.HexToHash("0x5a11c486cbd6176087a128b1dc1d0659ecae2915d2bb701a7b63d82739159386"): true, + common.HexToHash("0xfe4149e1aadfe6517d131bcc38ddc7ba459ae56e1d88e1beac6388594241fab6"): true, + common.HexToHash("0xa71759459621e870a6fcc2f96926987a03f1e07855d2afc72ab1f90737071ebc"): true, + common.HexToHash("0x110d6d78cbd0558909f43ff9753b4321e626e1620357dc998b818b11ba0dcff8"): true, + common.HexToHash("0x906a36f3dbb098acab9c550453a4f14be2407fda0a156dc6362282453d545b82"): true, + common.HexToHash("0x59a5896d5f0e4077288b8b11987f5b30fcae09004bf1afe35ed099064cfc9d81"): true, + common.HexToHash("0x5da4d5f8b2d6bccfc591c3bf1a7217c96efcfdd71958068ba134aa9cf5aa1fea"): true, + common.HexToHash("0x6ec29bc9a84f09a38fb055efd7b7ca151b57b2f470b3f7640b478d847164134f"): true, + common.HexToHash("0x98027c2f7fc3b4798ce76d9c886ab3078201d11038316ed1d14b4c07ecd84ed9"): true, + common.HexToHash("0xe253ae30bc264053ad5a32548e635c3f7137f65448ff16359972558455138b42"): true, + common.HexToHash("0x83febf7a4c153c4d694c8b88927c2b818d401ecd2a6c4dd77e9906186be3aa28"): true, + common.HexToHash("0xc64c2466186f1fbd5b798f3d099f9f5627eae2a226fd669d92577c850e70bda1"): true, + common.HexToHash("0x7bdc75e72fba6f5a2093d4fc99ca6d3854ec9a704fb28f372b5b628eec83f662"): true, + common.HexToHash("0x3cf78833cf3be59ae13ab49ffe0be4e8ff70c40675929f714350232c4c41d6f4"): true, + common.HexToHash("0x7978ebc8bb66123bfeca03ee3af0d680adea76a115ea425f38c8b05ee6fbfed8"): true, + common.HexToHash("0x54093864ed0caccf6bcb8be82943cff40b781593de4fad9df56f47747edb04f7"): true, + common.HexToHash("0xd8e0abedc64a47c62bc4c52e083ecba437a58e8084c25d78dd45feb23fb2315c"): true, + common.HexToHash("0x89a70078dbbc4ecc86b975e36c5ef6fec1c380958460746727da01422f880543"): true, + common.HexToHash("0xce2c295b95294b987736023ceb9db4d6b3b7207b998d614594a3b16e1aa183ba"): true, + common.HexToHash("0x8499c9a2412d596b19f0f53c7de8b704f3c2316ff22fabaab5ed0c42256a135d"): true, + common.HexToHash("0x0a980953fdffa98ae732ecb022af4767a5a8c54132e3557b7c784f871e186150"): true, + common.HexToHash("0x7397305ec93fe6608d9395d88f13a38045274ec848c432d7f07a5ac0388cc65f"): true, + common.HexToHash("0x46f498661dfaa36aaa941c82392c4fcbbf6787736dd27b9a281879a305640945"): true, + common.HexToHash("0x56c124892b368cff87d5c4028d356c79290f5ce10c819503ff9b89efc4ea836d"): true, + common.HexToHash("0x5c93cb6d937fcdd53a96f0e822f37cb2d20de70950f1d6ffcd7706ffd20c196a"): true, + common.HexToHash("0x6edc6b2054e0ab6fde60219b291cd725619edf9666a75af3511d17c8652ffe37"): true, + common.HexToHash("0xb2f09ee93fc820c1462c1d838c6ab9346e23ab6b6379e33128a851d605643a0a"): true, + common.HexToHash("0x03c016425401ca4c5dcf6687c397dc156a8e6e87ed2702c6c0624533ae173a96"): true, + common.HexToHash("0x6dc4e9cf4c4592eb9d9fe9a24c474777c41bf0bd21b057e052386453ad06f771"): true, + common.HexToHash("0x73560f7f15ea6c63f0b7afc2517b23cc0a49c56e9b836d46b44b6185bf9d76d3"): true, + common.HexToHash("0x80b9750a1c7898e1adb54c1355f956b8a5c2fc959ee69fd8a2b930b184089a15"): true, + common.HexToHash("0x1cdc2ed8823c26eebd4e8eb4fa973829ae4b1706c0cd97f725bfede476c4bad8"): true, + common.HexToHash("0x6cefaaca5c1a6659ddafe27201951e8214f33dba4e0ae1dfbf212b996547957f"): true, + common.HexToHash("0x6312d6baae979561ee948565203fa627c07599c6aa27f7793e7d9a889389d629"): true, + common.HexToHash("0x930e55156bac74415ae9327bb13718072690fb0780431bc2b8955d02ead58046"): true, + common.HexToHash("0x889b0f75587b32e9eb06df79da420592ccf32de8a53d44eeaf144b4dfec9cff4"): true, + common.HexToHash("0x56f94396d423a815abf7d93de6018103fb3969d2ba218326e105011fc83cf04e"): true, + common.HexToHash("0x589911b7d2a604c368aea7542a37d5cf6f071f505071c82da6ef734a2c549472"): true, + common.HexToHash("0x07ced94d914e73d85a921a87a0716cab2da23c40007f9471b1e9305c50a7fd31"): true, + common.HexToHash("0xa595bd73ea9a93b67d8cdbeb947858b38eea3f6a646febc1d6ff04b042997da6"): true, + common.HexToHash("0xb9ad10ac666dd5e7f3d37c0c607e1539ce4b839ac50683429aef08b95b2e35ff"): true, + common.HexToHash("0x0a6aa021b61cb7f670f746cc748cc9aa1cea4c25892ae2c003c05a7a7d4b1494"): true, + common.HexToHash("0x548c088d8e182335e0c510c7a9d4bd304a00baca5e333bbd35d2d449bd0e282a"): true, + common.HexToHash("0x0a9a9a1472c45adb38738d771a687cdfa8382d1d1ef6228ee5014bb8d333e058"): true, + common.HexToHash("0x733a3186e45e8c5d129a663597ceaf0b4c2e1497138a2dcaaf354abe0ea66a41"): true, + common.HexToHash("0x06850af8aca3b799e6cc0f883da99afb9302797ef69215811a25f909c5d52f17"): true, + common.HexToHash("0x0bc23271ff14358318a3b260b43544a396304f40ae7cc79f633e6585e2bb8c40"): true, + common.HexToHash("0x1b2820e60afe923c5f5e35b440948dd4c4bc306a1e20c7053498aeb7452d2ada"): true, + common.HexToHash("0x8dcb6a3c2c092e52664542f8f76c9dba28a91c864f07ca87ed2d39fd5818c66d"): true, + common.HexToHash("0xe2027ccf2e19521d7eb9ba95f1ba4371513980dda1259a4f91c8f72070db9169"): true, + common.HexToHash("0xbbea698bb4b1c18f92482b3ff7f17518b581ce4efe76e45a5ec294336268af5e"): true, + common.HexToHash("0x9c552df4aa00e6fd3c1a425bb29f7d9f7b08d02f391835f389343f999e4f0f4f"): true, + common.HexToHash("0x7e5628d1d90ab36ff98c7002fb093b182b6c93d52f7c1fcd3ad464a8ec0b4dbf"): true, + common.HexToHash("0x55d7ae7d1d9a693133b40eaf65288d183508709c20e9236af1a4f1ddd40546b9"): true, + common.HexToHash("0x12ac2564917ffce75f6b107656e7db01b58d00758868a4d3db5c6f14a2643850"): true, + common.HexToHash("0x4989bc849d3bd394a0d70d45f8b7268f06831970299d84fddeada651d626b25d"): true, + common.HexToHash("0x5c0d5835d7b803b21c11c1ae5f2a0d7cedfd42e4be38b15515924d24ab929e58"): true, + common.HexToHash("0x6eef29b16590450527e9b205c2b7b0ccb826d796d8a043b53a24cabce597fa30"): true, + common.HexToHash("0xba0f8e6c932edf7655f5880e0d10075675648d9c1758a9f096a41b06df0d812c"): true, + common.HexToHash("0xd54bcc1dd73a56e5cdfb295c6666a098c50d8d77619569bc8ac0ce83b1330025"): true, + common.HexToHash("0x46d68a4537e9d5689011a0c8c89abd823c48cb96b4afff95b6aa18fc83e985bc"): true, + common.HexToHash("0xd07fdf6e48ca60dd6dec8a76132b5e07be4be01b6e520cdaa90be554e03aecd9"): true, + common.HexToHash("0x0ca5665eb8537783b69fd545c01785c7e0f8381268cd68ca8953f6fe31e4fd0d"): true, + common.HexToHash("0x0f7b6dffae2fe74031a9b4130116f8aadf9a0660ca2bd8092068f706a8ffe64d"): true, + common.HexToHash("0xaa4370279428724b18d6bfec945742b5db3f2880f303f461c0c298beb58bc69a"): true, + common.HexToHash("0x4bc29ff88660d4ef453e6876fa4e32698112d76652186aec42336b03d9fe122c"): true, + common.HexToHash("0xd587ff893cfa938b7880e3042a122784b94e5c5ed7188afbabdc8a3823c3d66b"): true, + common.HexToHash("0x42e89b519bdee8e87f92c213d9eb2d3ea6cf8aec80ddacf8b7ddab0e0521d027"): true, + common.HexToHash("0xa2e5c3ccdeaf83d0c64655554353bb7b413b805733989cba9e62758fb58541d3"): true, + common.HexToHash("0xb8f3e7c7f84508b05160bd60c7128a219a81fb3b9e55d944bf565401ed720a20"): true, + common.HexToHash("0xf9e4122d153cebd613cb4d2aa868b0c3c4b64db4b30bfacf530838af98e96d62"): true, + common.HexToHash("0x8a3938f2da09da3f592f36ae815f2f15b6d6e55201e21817584619c452f920b7"): true, + common.HexToHash("0x38ce484c338e2af7d0e35e52618724b3e29cc25e48896fc59edc4f3a8a88ddb2"): true, + common.HexToHash("0xedb0dbe117dbb2b6257ad580b3c2ae145f4406dba2289f0491f71c6742d4add6"): true, + common.HexToHash("0xba9182700c2ffeda1f8b9bcaa1a0e8e2285c457950d980fe7a55b48596261db2"): true, + common.HexToHash("0xafad40ae55d4488cf04611db93bb131f13638aeaad58ea7f3a343b5572032082"): true, + common.HexToHash("0xb5ae2df4645fe2c7ddcddc8a87ceff8aa488baf32a51dace30dd02d2544a0795"): true, + common.HexToHash("0xade1265fa6facc582f0701b7c56a231aa414cf9fd215eeefc8a946e9c041bda5"): true, + common.HexToHash("0xc21a86eb151aa4a01423397c413f2929bd4998b6805e79e14f6623ff13c8e702"): true, + common.HexToHash("0xb61e59496d7cbadc7e29c735084c9634099dbef9006745af52aae863ba5afe24"): true, + common.HexToHash("0xcfdeea460cb19ac27118cc742f549134924a08fe72c06b17cde3c448d790a9b2"): true, + common.HexToHash("0x1a91411af1a30012f78b2e84b63cdff6046da917a4250dc602988b1f431e2c48"): true, + common.HexToHash("0x5a4896dbab4e71a8f785bbfdeb6a5acbf2560d9db373e74942377aa2397eccec"): true, + common.HexToHash("0xd4819d0bb567897e76bc0a30ef35ccedcd0a4a6ce622a43b92e5e67479e902a6"): true, + common.HexToHash("0x910a7f507760c614515c0c0df7c5954069c03ae921b374c0caedfd906df6d360"): true, + common.HexToHash("0x76943990f5279e92ba6aac772d684b1510100d3aa8e5dd1a3a598edc8af0b762"): true, + common.HexToHash("0x6da4c536e90f9bf2a1d8aa7585ef233ecf30fe675d04feac6d81fdd4eb4a35e4"): true, + common.HexToHash("0xc3d6c51a80e8f8769768e79aae80d3eba136bdb08834e6f8249a0129dff775d9"): true, + common.HexToHash("0x480d72464fdcc0b725bcec8e1c80766f43e648301918241fa095c2b46e730819"): true, + common.HexToHash("0x7f78081004afa151e4e5268ad70fc35b94e84af3744c2333be1455648ddb3a00"): true, + common.HexToHash("0x401aae70e70c561f89c6c2877fa86c733c80031a42ca8ac512b9c929330ef60e"): true, + common.HexToHash("0xbc2f8c0c2305e6ecd82655838d7d0dc120619febee09a552de9f6de549e9ca39"): true, + common.HexToHash("0xc3edfc2105624d46cfb5d8fea4e6d70d09477a11f8ca993e796a4cf9e220b1ce"): true, + common.HexToHash("0xc4517151627a75687cc06bb76e5c85b8f713671f6b30db44b1dd83393c10ec84"): true, + common.HexToHash("0x57bea4bb1c168002225e95b3c2399ebd3d66d29e36ff584de7578c6849ec76ec"): true, + common.HexToHash("0xaf034c3f432e4ba17bb1e57070fbe8c9788511b5e97b2c7d5637d6e3edbb75d6"): true, + common.HexToHash("0xd2f487c01579512fefc5d66fb98e49a4c09d2a41680536133865c9085a01144f"): true, + common.HexToHash("0x8353b016db9e34e0372d3b0cd34542a04c934a7f13ac398f935b9d19cfe49593"): true, + common.HexToHash("0x53fe6b3e69b4c97fa5841bc6e512a4ba4525b9b3df090ce12daf506c7ef63b26"): true, + common.HexToHash("0xddc074f901903ce5fb660c152df7872440f2f8f9ffb9f29ae7f1bdabb822a116"): true, + common.HexToHash("0x1debea07693b29b1fb231f4c9bc7032ed08011ca3e46da9657482c0c30ff8a71"): true, + common.HexToHash("0xf7f88f01d85911d75ed1521b00c219763e00714882eb105c924bd805eb3569e9"): true, + common.HexToHash("0x4cfdfbd2504c307704bc1222b7175e15539bffc3adc0627d483b8cbf21a28bfa"): true, + common.HexToHash("0x632bab8b24992f90001855efbd04dc66b02d069d2ff87f310d91a65fcb53e6b2"): true, + common.HexToHash("0x012c5eaff2de4842ca4cb455a6c157fb0f15aa07e42d2d3c66c496fb9be9dcc4"): true, + common.HexToHash("0x8a9e2bf9fa48450567875c21723b077bccc080f83d4d40eac93fc1558c5d0277"): true, + common.HexToHash("0xe8cc41dba8d2aad7d9aa4ca0f0e62ae182f533f0c76da56333490a4c0e98dccb"): true, + common.HexToHash("0x7ae4cfbd4d8b067880464adb6bf4a086bd6b290ef19e28c5781f9d314970f2b1"): true, + common.HexToHash("0x8e35fb4113a9cd468acb0fba2e70c58e82417bb2865e2e6a243fb75c36120729"): true, + common.HexToHash("0xe9314f1f95d4d163ace94078c48b9e1c231691212bdbc5376865d981252f663a"): true, + common.HexToHash("0x1295229c1b8008f4d12e928b283b8266238ef5742a99997d2a26cfed33677b2d"): true, + common.HexToHash("0x46e5f111eb336269a694cb2d1dbef2ff9778c768d4c3806ae99a5f556a01efac"): true, + common.HexToHash("0xa88d9a4fae60a53f8b2d04c301779a70b25aafedff877ff1eaade526102dd43c"): true, + common.HexToHash("0x3bbeab74cfd8ada953c96dc53552a131252e31585cb039310c73d01f39fc54a4"): true, + common.HexToHash("0x4ac98114882d2460cb1030a764c5d152379e8f647cf0cadb9f563e77c55a4d37"): true, + common.HexToHash("0xdc327d5d7e37896cf18230e0eadb4b5572e20b9a75ef3b33df7c25cb8a159c93"): true, + common.HexToHash("0xc5e961bb6ed4649270d9f2e0139651d0d836270738e89198f5281af631be11f0"): true, + common.HexToHash("0x5397c06ce0eabd78d25d36df1634799e9232f8891f0528894bf2dec537f81371"): true, + common.HexToHash("0x505ca78b79e189705faddda61372c535857a57c1f12625810d310b974a483ecc"): true, + common.HexToHash("0xd7babeb9a97f575194eec77d8316b68bd006ff1298ebc3df1535e1f5340281ba"): true, + common.HexToHash("0x3a80fe07d2f910be763fe80e58cd22121cba80f748cc4814ef486e9a2351c28b"): true, + common.HexToHash("0x2c7143c5a6dd987e4b7dab860471e29d595194467e0a7caa128bc301eae3f8b9"): true, + common.HexToHash("0x884010ff19a72bee2f3b3027bb883b721dbe71589f063080bf96457fc6ce815e"): true, + common.HexToHash("0xefdb0cab544662dc39e2c94c17c4f51ef994b83f33320d744b92cdc476c2af40"): true, + common.HexToHash("0xd64aa1e9640ce2fcfeaa22046ab2846eec6662a876514873a252cf41e1b7aa26"): true, + common.HexToHash("0x5840822700cea4925d568d7941b6549b91775c1fd586025e80f57ae8cf69d1e8"): true, + common.HexToHash("0xcd94a2fe5c5aff6f41cef8d256e47270bc1a1ebfd3439a2608bacb9289ab133b"): true, + common.HexToHash("0x261484d88761c43157696e3e9df12bec7035ecdf395243943f5e7ea94cc814b5"): true, + common.HexToHash("0x0f00b564942e85dcc0259a04a493329dcd175d1734e04d5bcc335eb4d7b19f76"): true, + common.HexToHash("0xde7d24de3b2adb41b5a0ab1771f26ab39639dec1ab5117e4102baa170da71ea0"): true, + common.HexToHash("0xcb50b76f5b4f5ad43c6938831f108f213ebb0f9b5a547515b119f5e17cb5dc99"): true, + common.HexToHash("0x703e431262594622cea535dd297d3c4e3afdab505c8f5f323aeb4572d7a4f308"): true, + common.HexToHash("0x98537265df01cfd92a89a4aa90751fbd2e6e66a43f79aed791c0817bce8061fb"): true, + common.HexToHash("0xa1e2e25c0afe1de3fce94e768e37a1a68285be08f6cdd9eda001ca60b418569a"): true, + common.HexToHash("0x2d98c93b7724db44cc4f32194872bf25179a2be1cbf4e2f29e132f5b9819a8d0"): true, + common.HexToHash("0x57b3fc591953300da6692f1c36d9424fc8f640308cd3f66a0b93abc4913cf1ca"): true, + common.HexToHash("0xb0454535afdd6ce15d085b553d0223a1e5b7eb927dd074dfd7a37df43558a814"): true, + common.HexToHash("0xe31b7478da298ce59f15e3e271f5056332ed3ef6f8595d2b30a1bdfabb784ab2"): true, + common.HexToHash("0xe72583cebdcf0e13830496c5523291784c185766137d47abc10747893cd98d3e"): true, + common.HexToHash("0xcda0e689e44fd18f16a98f3a572f9ef9ed11a0b20e231e68b5c31c9e07ae4b3c"): true, + common.HexToHash("0xe873185c7625df2082ab18bee344190fef96748b0b518a8a6319312daac7240d"): true, + common.HexToHash("0x1a842bc35cc6633894dfdce37fe9372c10a298d60b2a43828ce302673d404c27"): true, + common.HexToHash("0xe6b24c4ebb5592a7bc65f28b3bb05bb72114c44149716f07712ab504ea6a1a8e"): true, + common.HexToHash("0x10552218b64a437e9d725356dea28cc863cdf9443c7ab378f65e9ba521e492ec"): true, + common.HexToHash("0x15655c01d3f0d12b39ecdbc5ed0803eb4f145a4c3dd9e855f7c45bc1c546cd54"): true, + common.HexToHash("0x74fb887f08f3152ede7a28a06e496bd0a0fdcb7087a02c78a80a1112627e79ed"): true, + common.HexToHash("0x4e65402b7270bf30596f2b8c52a3bcc52c0f96268bb6e04f9c0fc9bc0a5bd302"): true, + common.HexToHash("0xfee44dd5c10d75f5bdf60f31742c5bb0aa8c095f5bdea6208c08871763bb705c"): true, + common.HexToHash("0xc4bf6b2ce66d5da5e619edc97aa90b8b71c6ca49808032cdb4b1ad8cfe203b05"): true, + common.HexToHash("0x9f60ba7881aaf4d28e414a7d30c6bb6c702bd161901902e4a53657c92bcdca6d"): true, + common.HexToHash("0x30cd3e7db050394689dd58c2842ae14b27daf15e68a54f84f9f97d1314a88d8f"): true, + common.HexToHash("0x13b94d4451ad9a76a4b9b0866bd4d88017891f99c746c802fc78c42bf57a6a2b"): true, + common.HexToHash("0x55b63b46fcaebd72fd0e3c4d37607183f15508f4213edd22d19a740131735c3e"): true, + common.HexToHash("0x36fb418cb467b364f705963373063770533b3928de4d05ac79969e58ed168458"): true, + common.HexToHash("0xb571ca9271ecd7f0db96c07b7a3c4ffde257338551baa9f375f5a54769470ac0"): true, + common.HexToHash("0x50d31f0551a517b3d20be208b661a70c9f182956c806657759d46c5c41134dc8"): true, + common.HexToHash("0x42fcea4cfb8c89e03e009e974c97587e0748f5b81377c3f0adf9b2047b27ef46"): true, + common.HexToHash("0xe0e63de5d4ad0c24159d5ff126b55a1287dc65b906db33af4dad5b5ec56c6692"): true, + common.HexToHash("0x2a23af1211fe2d366c446ab3e15e6ff864849905be32363589cf6263b128a2a1"): true, + common.HexToHash("0xd0fa0ba5f63c6147f17c5ca5118b21978ff6e7816de9d0631a0479ffc5135785"): true, + common.HexToHash("0x739279c35a763c15b65e48ec43a92e1e0e8a9fa665684023ab47ac56377cd980"): true, + common.HexToHash("0x66f7ca3d9f08c48c2707ebc688f90d39e72763882dcccd33719f76680c86fd48"): true, + common.HexToHash("0x9791c32332e18da3707950a79fe6dadb86a3ac0cb29dde2dd41b25212cdefac5"): true, + common.HexToHash("0x80c8077fe31cfb067e5897e2d3054cb51e495d8ea9d81890438a62db7d639258"): true, + common.HexToHash("0xc144caacce59496907a8829cbca89b949e27c44bae80405751a84ba162eb4271"): true, + common.HexToHash("0xadf48776fc21cabe15183b2d9d491dd67fddad9c5c2a33d5b9e6bc5e67abb9da"): true, + common.HexToHash("0xebcec098465d5e3e1ea1719c49c598b371ea7f7ef604a0bdb2d28008ecfb5a0c"): true, + common.HexToHash("0x8fa7994434ddc5e64b13ead39d8b13807d8b7224209e838e4b156e76fe8b38b7"): true, + common.HexToHash("0xb95b10221978ced25af2ac44ab81e3831eb7a3a9ad5bee9732fabd5080ffeeef"): true, + common.HexToHash("0x4c89b91f224a656f141e4106f6609a565c98a29d0daac275d543c312afbce198"): true, + common.HexToHash("0x2d17141734c4aeb910743d70522348517d2cf2c8aabd2e59c39843c503d6c2f3"): true, + common.HexToHash("0x39bbf97108d9b2d68388f8c844d7ecad60816aac85ca02b23958487aa025df02"): true, + common.HexToHash("0xc252a81c23f15df5734d494b35cc8614231a6e3acefd02be0c65a4159de551a2"): true, + common.HexToHash("0xfc556a04a85308199bd51dd83f0bba9bdc7e9634c72efb3bc77d613df405463a"): true, + common.HexToHash("0xdf78714ccd39c0dfd289c05af585ed25043e704d8eead939551df83dc964641b"): true, + common.HexToHash("0x3cdf691f80495562dee8d9b5cf13e1117b0013777cb722755364078077c4f249"): true, + common.HexToHash("0xf5d4889498470e685d06174e42711a2086467bab82ecd3f20ddf58c180c30496"): true, + common.HexToHash("0x356bc81164c2f3063640604ed2e4057820bccbd9d8e97eca73416404d7adc480"): true, + common.HexToHash("0xcfbe98637dc5a8e0f893fb01d9459fd42fc854b692cf10e56803780540753d0e"): true, + common.HexToHash("0x6ccda450d8d21ac18364966649b5fc7196a95bb4a6924dea6843a2b7e530cf23"): true, + common.HexToHash("0x54aacc363be26146b8ab5f8411e8dca7f77c921682bc256f5203f016d69b9389"): true, + common.HexToHash("0x7de39e52b599a0ff3bebc081af807f9f83b06d0e2f88c44afe6c08de3857418c"): true, + common.HexToHash("0x017c8f62e98e082cdeaadd96fda7431d7cf2c8b392e23276a4b412e9ceac456a"): true, + common.HexToHash("0x7c204b78c81936e2d2687ecc5d2c1da14f006c3caed80f8eec2a485c746f317c"): true, + common.HexToHash("0x12b42f0e99010e1f87e9e65f8809c77b0de17193aa11ef1d2850e51f1ef01aef"): true, + common.HexToHash("0x0b112122a84ae51b189dbe1c2cc75417db22dccfc2592a00cb68f0c7e11edb2a"): true, + common.HexToHash("0x410bb0c4c65f4a267b8313b0f2e4b83fbb68c098558c7edda1f8a1355ba9623c"): true, + common.HexToHash("0xd7dddaa497db616a1747caad15504b5c6000b8b4d03bb53304435563f0dc6b9d"): true, + common.HexToHash("0x2b9ec784f510d47fb3072823ee26359b2e79612160f97d62881d797228ba72cf"): true, + common.HexToHash("0x0142eae747721fe4e2f3a552d039e678f477fb0b23026a01c2e8cf1e0d177f81"): true, + common.HexToHash("0x3583177b88c0afe77219f8febe4a544a3a1ba0fc08ae9a15ae5140fc3b11faf5"): true, + common.HexToHash("0x54ac5d773b2dc19d7521657234f60f28747322c73a0f1f8bf73531d84e53b400"): true, + common.HexToHash("0xb45a9d2d418089b63b8db1bb05c7dcf786102fe7d6e0728501c94ff09351fbf0"): true, + common.HexToHash("0x703e1879b5d619ce3f8e8069bd2c2dd801cb7e621aab51b4a18ba8361e50f8d0"): true, + common.HexToHash("0xbbe57b25855dbc6c9f9f8fec018d4ead7b1134fb713eb29d642f72d8dd241a5f"): true, + common.HexToHash("0x202cd684eda5b274b8c10ed112bf7cad81cf457fae735f9490b077acd442ce6b"): true, + common.HexToHash("0x06e7e17467cb95fb6fc8652a12ad6e6bdafffb4432b087e2d20dd15fc9473ffd"): true, + common.HexToHash("0xe9effe93de0675d52d53bf559a9a443f015aa0a4e1ec5c793892af203bd829b8"): true, + common.HexToHash("0xafc7e072b4fcd7f3fdc1777b9ad5266e198cfafb82a2c4929b31698551c51d4d"): true, + common.HexToHash("0xf34fb184be0049afd1ed39725e069c89d47460c2895dc61990e0f173c99b1403"): true, + common.HexToHash("0xf39f7dcc790092fe20262381997be51d60831641cb30caac5e3809f85422c1ef"): true, + common.HexToHash("0xb31e8ac5dc0b1aba8dd110e80cfccf2712490baeb68bac49edc4f68af762e390"): true, + common.HexToHash("0xb9045b40df0979fe5b0a261f6cee637b6fb224d3ea2be15b36193eb82f3d3736"): true, + common.HexToHash("0x8f019885842acda7f89923be88a86791e920eb8fa71d865da928f3dafd6b2197"): true, + common.HexToHash("0xdeb2df415511a3cd6db5d3adf578d4adcbd6345c23768206cfdb286e4cc9137c"): true, + common.HexToHash("0xbaa51b85b2ad51d935d6e1ac4a82ac6cc4210f821d188e6d8cfdbafd2d28cb8f"): true, + common.HexToHash("0x7a1e60d6bb4fa0d34c8511d9efae1e57447ee8cb2ae288a3cb26405e8f955fc8"): true, + common.HexToHash("0x9d2047251e3c0f73d0719cfb34c57cea2fa75f957f181d530e6fd4c9223f022c"): true, + common.HexToHash("0xe552a4fbc701dc990addca81b7e232f329a700105ad9c8e27b591d98a697ab78"): true, + common.HexToHash("0xcad66848287076517c2138c1fe477022fb121248b12a11523f8c0ad812fb2ac7"): true, + common.HexToHash("0x88498d50ebf3a9ded99cf6db8d5f32f3dd7ffb9bca9bebab6cce95ff63ed7c0b"): true, + common.HexToHash("0x8770a040b6f3105ffcb4bf99ea6b9d207810447f3580a0a8d4bf2ec1316ae4bf"): true, + common.HexToHash("0x2911df05e30c2cee4a42e29841c65022f02631b88ac22b63539527d2d2d64829"): true, + common.HexToHash("0xccf9823db6e35a2d412b6495765d9c32af97748e5102f570031bb7981bef6115"): true, + common.HexToHash("0xf86524757de7fe576c1288f4525dcff381fe29b46c383050922adec66d2ac337"): true, + common.HexToHash("0x65fdbbf69167dd07074daed34898f4d3d1c79a59b075b2fff7ae1c54551e21af"): true, + common.HexToHash("0x77ebd1af0d8258842122225f13b0c222d8f47ada6e1e6cba0f92f8c15d0eb17b"): true, + common.HexToHash("0x0196b1cffddee536d8b91898e0788abf85800a860262fc154a4e4b2efb809dab"): true, + common.HexToHash("0x3cdb47e2462260fbd4f701e06d8b1f5b52b5f553424ad7047ba4357442190424"): true, + common.HexToHash("0x4ccd4a91559f8b0441210458a833e1bcb790e81afa0f153b2924a0b4b5a79d9a"): true, + common.HexToHash("0xfed452dc6c038ff4b1e633dbf994fa44fe16a6eb2eeaa2d0fe82fe5ff51e04a1"): true, + common.HexToHash("0xad34d33b61092f5f8239b942c1d4bd8e5a6d2e4fdf6f00e1540ac4185bc94315"): true, + common.HexToHash("0x62627124254ee2cca0fc073a6ce0de503cc293fcb5df841c0ef15f415ec9b7f6"): true, + common.HexToHash("0x128646617c50c883d0287de72cee06511a9a78f23c292112017c47b758743ca0"): true, + common.HexToHash("0xa31d5ab3f6251176b08d75daacd0dcd6b6aa1d7a311de5b744f4b1d0cda5531a"): true, + common.HexToHash("0x01be612969afcd9836eccb4c15e1c40b50d5d22c7d091281098abb84991d2f00"): true, + common.HexToHash("0xa54ee9054140ebcea0a8af4c88247b4b6cdecac5c4e1229b694c96530a5da52b"): true, + common.HexToHash("0xf9dab2c90fc97811e9939876bce66ac1b5fce467d1683c32f41e2ec79463ad3c"): true, + common.HexToHash("0x8c40cc9e2df037ab9bcac206c9b698bb8c5504307bba89ec2ff3c982d3aaf5d7"): true, + common.HexToHash("0xa42444bac7656a8efae6efdf9ff357adef021d79403a9b7324dd324771da24af"): true, + common.HexToHash("0x94e741c793df310086ffd92eaf319a4218b67e31f781eaccf28a025548b8ba02"): true, + common.HexToHash("0xf61f94dead97e1fca1bb5cdcb074571a08ab55557379334ea8726a4e77ed7c0a"): true, + common.HexToHash("0x510496ad2fd81e60bbcfc246f92c345d25a0b32e255d7b36424235ec5e9c4139"): true, + common.HexToHash("0x84e3b6161942edeb416fcb77a84b316b065ead44b891393e2c535f2e34df49be"): true, + common.HexToHash("0x781060b5c5bf56b3cbf06e19754c5997a497f5a41d599b4ff0ab75af3ff52de4"): true, + common.HexToHash("0x6a4023d31d2b7f3cb6ff34b906973a280a187e768977b951b4b327a7c07f60ef"): true, + common.HexToHash("0x4c0f1f8b1587109acce3833541321eadfc98524d91259ee2b60b20b0967cf3cd"): true, + common.HexToHash("0xfd884da8c5d83e263f0029d56b379f93a8f7c44bff094dab2dc14e7b2fa24c8b"): true, + common.HexToHash("0x1439583a1325e1dd4adadedc6b9f15dadb35b9d07d07d3752262193b8234b3be"): true, + common.HexToHash("0x976a8ac358fc0c4c780978c3197ecba24df22a1a75bf69b23e024fd29c6ceffd"): true, + common.HexToHash("0xd1c4f6e2a6fac598ce12a3889f02c3daae49a06cec9ae306ffe79d00b1e18913"): true, + common.HexToHash("0x04ac2b916b12ad1087b167079486945d94c0cf4610f1d179aa22649c83dc559a"): true, + common.HexToHash("0x89e2489c7537c9abab008c035fac5ccd5201dc879d902099f42866fd0986f947"): true, + common.HexToHash("0x54fe91fdd2dd27bb59a93da120e06f8e4af0b1350fda75aa4fd24acfa9a09654"): true, + common.HexToHash("0x5653f2d443f33e2c4147a62331d94a767f648dbbe299fbacad203fce53eaf35a"): true, + common.HexToHash("0x7cc36a32bf98602be3eecf53c5c7e2925672034467821f5deb62b28f7505db14"): true, + common.HexToHash("0x568135a1ab86d08402fe83924bb4ca3d57f53e4e18b9681ce1816e9d1774b328"): true, + common.HexToHash("0x7f2dffe4fec604da4b46650a43a24272ccc264a2daf996d5272f20594246575f"): true, + common.HexToHash("0x428c6a74d85ff518614c8ffcf2bac830c2c037bfe819b6330ee9c2f272960400"): true, + common.HexToHash("0x90937d4d91e5074d90b772d2ed0a7834f127f201151de29f56a9b34764732c10"): true, + common.HexToHash("0xe805fe4282156401bf743d5263ac0d2caab042b0f654f3c86592cf40648b828d"): true, + common.HexToHash("0xd952ff87fb48379b89f9c2946a39eadfa04b7a7d538be765b4d139e9a62c6d0f"): true, + common.HexToHash("0x2ff8d809b206bc6133bac6861eb32ec509c635a57161a6e44ebca92e41b8e105"): true, + common.HexToHash("0x3653056173e56d53aa3fb61228e1e701ef7fd77f640aeae08b6c27300301c7f1"): true, + common.HexToHash("0xeca0d0bcca1f775a3d70cbda66c4dd911206a5c4ab12b28098d9db2d654ea486"): true, + common.HexToHash("0xda963eeb1b5a269ca99ad751d71c03061391b33d5719e3d8dc73a3ab2bf8898c"): true, + common.HexToHash("0x49950861f1f184307fa19d2a0f5864da2792e33f2c15b3a3174f8107ca10d4f0"): true, + common.HexToHash("0xb9a4c65edb2525b637e3b3a26811db3870d1816bb8eafd9dc3afc58527ba2b07"): true, + common.HexToHash("0x75507fcefa8f22bc09752007527fc11ee014a9898f911ae7201131f09069b8d7"): true, + common.HexToHash("0xf7fa40f25996218dd7d1344d92856c155e57765d6c720d337a32ecab94b10fd4"): true, + common.HexToHash("0x940bc44828f60e84b28c0e2f85fa85a8c0081d5aae25e13eb2ada89eea829838"): true, + common.HexToHash("0xcaf17a7d9af6cf339097f7dc41d09d4c93ec8d22458aeb5c012ea512e1840f26"): true, + common.HexToHash("0x166dbf8e5711a0778b623240bc9cb2261fdd4e96adaf23b4c3ad262a0cca2cb5"): true, + common.HexToHash("0xcf270ebeb2cde2f52292f1c6c7bce9c34b0f2aa5b7776dc87bb022d125bded9e"): true, + common.HexToHash("0x18740041b7e42c030538d47a668481e7cd6739c11a451aba6684872a279fcb3c"): true, + common.HexToHash("0x044729b0255119af8c60ab269482061954de54ed2aaf008d5a4068849df8e0ce"): true, + common.HexToHash("0x00cd3b6d0ea37acc805987d56ba2a83827fe7f88ee03b07382045b45776c78b4"): true, + common.HexToHash("0xd31aaabdd4bfa01d982721e0d6efda0cd8c7ac6230bc79effbb07de1ec90ad00"): true, + common.HexToHash("0x73e40ed7a042bdc1914caaa5dcd6ba6e1863c02857b023a33a1b3c1d6692bf43"): true, + common.HexToHash("0xe827d5e720299335b97bccf41d5c77282bfa7ad864f5268c12ae742de9c0add6"): true, + common.HexToHash("0x669b4a2e8e60aa54255749494c1d9909223192ff2654f0a0bd4b6e665f587714"): true, + common.HexToHash("0xc4452fccfa970e6c92627eac1ee31b0442cd61bdf9a7b71e3ebe0826234b25d2"): true, + common.HexToHash("0xf63c63473fdcddf5868305dfe0cc091f880daeb99f4bf457f9766ca62fa9029f"): true, + common.HexToHash("0x99f062c575cbf90b891d8e06f24d59515c9fb3de6777f6dafe136016162fc68f"): true, + common.HexToHash("0x49b433a5ab2b8895053fb87714fb00758c9f9c713087347a30d02e6a7f602d93"): true, + common.HexToHash("0xe35f6da644982afde336224626011d711399b30c27973bc43151ec4f2647a884"): true, + common.HexToHash("0x2f20e78a8821d2132e9a28a7051fcb160dfd33193d8dd35a170871577f02a1c2"): true, + common.HexToHash("0xc2959bc997b594bc8622c37d359264676a022f3aed049580f262fb3f1635649e"): true, + common.HexToHash("0x304434a4165a47143dd1e12c8971409e101a1bc48d18af8ee916e2d9020c3ad6"): true, + common.HexToHash("0x5387535f9b0aa8722c1b63a9e911a29485a49bb995f70b4a0814ebef366a86d6"): true, + common.HexToHash("0xa0d738e4d394cf1bc3b9654fd2984f0547191070d2cd1ca3b841e875eb56bcff"): true, + common.HexToHash("0xc1118613fcc684513ceb0f8245255f8a71a439da2b2cbea1fc6b7367bbc693ca"): true, + common.HexToHash("0x2a6ebc47d02a72695866ea34ca3f741d596b324b4b2269fa435c6e3b79e11200"): true, + common.HexToHash("0x3042dc3332ef97493abe91305aab6127f7217f7eeb07e6bfed946f7da3cbffcf"): true, + common.HexToHash("0x4effd83c32880536bef1b7b6853bf8cdcc1124b43593932b85c9a123f545dd5b"): true, + common.HexToHash("0xd1fa49d5856c7472e6e740ef16f77385a4df293306edf3e80945be1bf609d5ee"): true, + common.HexToHash("0xbbd6a9a8b7a1cf9271b7612af6a739027a391d7e507696b4ea1d207f3f8ddfdd"): true, + common.HexToHash("0x17ca1970755411759faf051d3f4be3a5a51fdd6a4ff2d9a98a34d4dba3d2b79b"): true, + common.HexToHash("0x23978794b3204faa990fa93fea56e319f0ff9152c9236dfa5b6638022d7884a7"): true, + common.HexToHash("0x99364747d4ff2f9b6fce61998c1423676765c81b99e2a9d8fdd2246a444e5c65"): true, + common.HexToHash("0xfaa793f4b0c8c065e61d4cc19aaced9c6917cbd50bbbdb3d1cfeabed22c026c5"): true, + common.HexToHash("0x404b2d922d0006cbacfafa11aca5e0236f2d338a120028204ab7ad8ec0701b28"): true, + common.HexToHash("0xc96b2d3cd3294afa2eaaf3f82e372fd1b2a170cc8f04760e0ac3d57eff2ef462"): true, + common.HexToHash("0x662777969a1412b11a6400e930d28a0c01b87ef83e1b2c3b588f0b190bbee257"): true, + common.HexToHash("0x449fbd969188b332076b350a3d89e686b0cd3588b3a7e14ca9767275f5d76ede"): true, + common.HexToHash("0x73368bdf6149ed47512fd6acbfc6c4b0b9af32d3ac6ffbfbec45974a9adabf7b"): true, + common.HexToHash("0x0a71171448f8960702a768d5f95295ce7fc632eb169196345643c1eb5a787d47"): true, + common.HexToHash("0x4e64c6e3a52e1b57a325a14835ec534d0c1f29822740d30c335524a38c7fa982"): true, + common.HexToHash("0x67c96ef9d09c56c5ce7f1e6402952f81a87ba4546c0716da8e83108e5038f7ca"): true, + common.HexToHash("0x9f339abe564e034079b53d4cc2bfe5314ba5b7b809e15308fd7217eb987cfb8d"): true, + common.HexToHash("0xf1e33eecd402ecc68d30e0fb3b52a6bb5f3d7fee6f3f54d4b97fa2e16eb3c356"): true, + common.HexToHash("0x00c4105dffb47d04760a4332da77f72fbcbfb9587858aecbfdc147c83c59d94e"): true, + common.HexToHash("0x98731dc3c7dc06fb26c6d98b96b73001dc9607cbf86fa166b33e7221ed9276db"): true, + common.HexToHash("0xfa993b6615e5ef3f8b783d55a05efa1814e405d410956929a3f84b0f333b35e4"): true, + common.HexToHash("0xdbf2ab6e168d27ab8f3842ded623b638db754416e510d7cdcd6b66d216d9117c"): true, + common.HexToHash("0xac3bc087c0d17b4371bc094f24b6bda6334886c6b218b3d45982265aaf6193c5"): true, + common.HexToHash("0xeeeca9d15c62eab302bf2ffc814f8f27d22fd0221c43e5af3ee84eb5c3576dfd"): true, + common.HexToHash("0x61aa32ff47b0b5743f9545e723ee518a4c7426c06d4ead61f42f5d19398e3188"): true, + common.HexToHash("0x7ebeaead204b36989d8999d61c3fbcd723db0898c9a24694e28a9dfe1cbacb77"): true, + common.HexToHash("0x8c9ac0295aabf8301ed4c61333027814d5ff4e0d71b6174fcf7c7166d19c471e"): true, + common.HexToHash("0x9d4c4645d34cd65804066642f811251afec4f5fc333d3037d108fcbfa682537c"): true, + common.HexToHash("0x97f522537320441f593ad31580dac65b5e62b651f82ded694a94a4ad74ee59ba"): true, + common.HexToHash("0xc3e8675fa36cbf668f7ab326299aafe877458144e3b41e9a3f60b319c510d901"): true, + common.HexToHash("0xcab08b1ea5d8cbf103ebbb1208755dc6d96356e7a42ab2d3ffe19e4efd26455e"): true, + common.HexToHash("0xd14fdfc4c528820a47adafd902f51b46f94dfa8587d1cc5d1089b064f25ca852"): true, + common.HexToHash("0x5862b08ffd50d4156ffc852088a5d82bff61a4136e46f4504becd7141da9b940"): true, + common.HexToHash("0x6cec2859c09304d72fb2aecc578c05985203b83c2d05e544311b96cf5e769762"): true, + common.HexToHash("0x88425bf0b96399a8fc505ef6fe95406da215c822f180a363d4ee8c463caf5414"): true, + common.HexToHash("0x8b7b8834a2d1507d04fdf4f9d95a14a766f218b6a4fa7bdf6c0124163ccee22d"): true, + common.HexToHash("0x52950014ef4c0dd46c6927b743be029a02714bd3d3fa7062357a4e9024fefab2"): true, + common.HexToHash("0xf2408e658f4b9d397a1935cbdf380a2c2dfdf4971e243fd1de48530b9e005a1c"): true, + common.HexToHash("0x650506e32fd3d7ac1c7c7ffc1e331f69f570db12965e100536f713beafa5bd8e"): true, + common.HexToHash("0xb8caee470be5bb335ca80aae8aedc8a9d0232def68f205f111b5becb6276883c"): true, + common.HexToHash("0x32a8085c1376a56f2430e2fff3b6b4a92211ee29f70b3e5d76f9d9db17426872"): true, + common.HexToHash("0xdbdc1b2aac7191f4c47a8cef061210ceb23ad599451d6bfe4fcf5013171b138c"): true, + common.HexToHash("0xad10427bd27fb32026a638b715f0fb95b321c1594255ca9660c168813484d67a"): true, + common.HexToHash("0x2cb8cc387cf3fd10c87689f4a71fb5e15e3b9a8e6c210de8eb236fce51c1d5ae"): true, + common.HexToHash("0xd661d0f8b8535e449d5037b9869c25eac266815863373be4e970fd4f1fec17eb"): true, + common.HexToHash("0xc4591946db61050f61655d7ac87912e7369bcebdff28f857f72140a3a9c5a4f8"): true, + common.HexToHash("0x3968b69833adcab43e486824f709db93ecf01c9e561bf911afe867857b617975"): true, + common.HexToHash("0xa84f0ad10d0e8da91a3f9230114b60f643119bbdd99b5265c694839c9f7c64f5"): true, + common.HexToHash("0xd4738e3efc0592f87c855d2359158ae9366ff4afb8915e4c62f40a229e6a6a1f"): true, + common.HexToHash("0x26735e9897abeef6378a5e685ef4226fff58fe2bacdbbd5cddd99f19357c1f7c"): true, + common.HexToHash("0xa64291c62ded0ecd8c87fe0b831854dd9629442e89a93f1f13f42f6c8850daef"): true, + common.HexToHash("0x147c5e14fda41051a2c3114fe72789305c13631528a57524a61958a67482826b"): true, + common.HexToHash("0x63eeb4b690d928906ffa538adba5d10d09a0495a374654a9dbf30fb93e8481c0"): true, + common.HexToHash("0xe7c50a6454337a7cffd5ebbd2cc8f1d84c54855b292ccf9418316fd0e44d1e47"): true, + common.HexToHash("0xed9dcfe663f0a69128ba5572dc4a6dc72ae4f52cc2ec46be2be4951186941251"): true, + common.HexToHash("0xfc9f1414fc5c69ed421057dbf381dcda712f05aa48c65dce6d7042af73bdeef0"): true, + common.HexToHash("0x52c049c24ba5397b910ea0dd9e657bc1f4ba1e6a0d87881eb7dc55dc54cfed0c"): true, + common.HexToHash("0xce3c5690885972ceadc690495514c106d9c3d7bba8b6582b6b3e6660de8eccd6"): true, + common.HexToHash("0x58c065cd3e5f05da7e4fe3704b9d8a41a92aecdefce478334cb7f186e7be8988"): true, + common.HexToHash("0x695d794cb1d1aee553d92e0a0de011bf371a523d0270337d8d1e7dd2577178be"): true, + common.HexToHash("0xae8f03b380c666954358d5d1618089f97c4e96b934ea2af52cc06dcb835b030d"): true, + common.HexToHash("0xb4487cbe4ecdff79b15d80c8f5780460664ea7fa06e4178c47c7f15cfe7cd698"): true, + common.HexToHash("0xd5c2eb022ecc6b51740938001f3b1ca24aa3bda4c41e63e303b5150d9fcd675b"): true, + common.HexToHash("0x02a5128039eb2750327ddbe8e345c1b293ac92ba4190de22bdd7591a8dd42cec"): true, + common.HexToHash("0x911e2bb5709c60cab453004063154847ae02a293963b41e1195a1e558c1acdef"): true, + common.HexToHash("0x7bf1231180657d3a60c583aaa9d13c8989d5200ad425fb25b4b86ed417d4d280"): true, + common.HexToHash("0x637c2ec97a05dae3131b5b7a7400f30f00a01affd136178f28f8a3dd956270e4"): true, + common.HexToHash("0x0d373ddd1558ac3ffa07cd6d11001e425ea302c2e23c5dca3356852e11fca62b"): true, + common.HexToHash("0xb20ed36ca1d9293bbaafd961f286eb134c8a23c288ec1fccbc5ac83d32c9ac48"): true, + common.HexToHash("0x6463386b3ef6c1b65058b08217d01dea179d528023d93953535658582192701d"): true, + common.HexToHash("0x8c45a3ce5ad04b1f97302007983742777e9352d64281a4c1d2b6bcfa2fb8d032"): true, + common.HexToHash("0x880a5f73e8fa3ea1c74b59e502e0352f280020e66d599a3da674261fad031f9d"): true, + common.HexToHash("0x5014d5584e254b7a52cc12db022e12661fa1deb7e283b5d8d47490ee26e1eddf"): true, + common.HexToHash("0xc3503c153fc1875e94df0184b59799310a1d699cf304a838cbfae877b2000e21"): true, + common.HexToHash("0x604dfc1da930232f46d35c851d098272f8af75af69a9d9c0fb08d07b2fc41181"): true, + common.HexToHash("0x32ba8f3f27a8c6a051e20162a183bdd6a49c7f4a5f5cc98d4e40cd3e83652313"): true, + common.HexToHash("0x5cba7ed9bcd80a12016463e41e2504984b4fceee0c6fdf034902967dc4b46152"): true, + common.HexToHash("0x19a3a716e792d5e93f89c8d5212d13904c41cfd28feb534d5364141d76483412"): true, + common.HexToHash("0xb43d5d3067eb14632771f2ce9ba1ac03f37191599f7df0f28e24d5588dbc977c"): true, + common.HexToHash("0xeba7a0fb18f72da6503681f32e361b842249c002c437ae93c82e5672e4835503"): true, + common.HexToHash("0x259c2dcb221c6f21fa7b43c731ffe9a6e8e89cfd876076b5832ea0dba0e1e3f8"): true, + common.HexToHash("0x31e5b2b428e90efc1c29eab69825ff75a7556055f2c0346e0005313bd1627bf7"): true, + common.HexToHash("0xb06a15fee5387917c50cbfe22d6d267d82d3d6670ca72738a7e11c965098f831"): true, + common.HexToHash("0xeda3edeea780cb081eb2edad3c3219d3fc4d2aec03a7445d1e384b7b4f19224b"): true, + common.HexToHash("0xa0aa371e4cc71440cde096c79c94189e81d05d8fb1ab0244dafbcd8559273945"): true, + common.HexToHash("0x9cae880658b74882d8fa99f554fc8e8a177c5fa2c5280a3d2fa1c1bd26bff56f"): true, + common.HexToHash("0xd01a45a7603504e7bdf2e1729efc556a4b5a7d7d4bebbb683276b9e8ff0d9000"): true, + common.HexToHash("0x64faf9a8645213ce284aecd3b7fbbf433586b03e4f5856f885a9bfa8d0cf9773"): true, + common.HexToHash("0xc39d702f9ac0afe2ba461ffd6415c58caa7c2121658cd1d7a8fcd161dbe29d99"): true, + common.HexToHash("0x8fdea1d602cad6ca3c2fb76d8e398365ba4a1e680b53904951295bd20afe38a7"): true, + common.HexToHash("0x29265ad6b92d15b86eb28962a2d40225232abc474b252a8f2b39105e79683c03"): true, + common.HexToHash("0xc2c81d6649969601c12a44bddeaad78ef2961cb1283ec56a94bb06afdeef37da"): true, + common.HexToHash("0xc8cd0d9f8666e0d96bc4b3d2675d8d92749a6fb8050475d475c68ca1d822181d"): true, + common.HexToHash("0x3e2c03ff17dccca6ec606123cc4bc941fd559f121460f8eed81370e8fcafeba6"): true, + common.HexToHash("0xfb4796344ea013d2a279af72a6a5db255d10eca3221fb46ebe6bf7b453286b3f"): true, + common.HexToHash("0x32becc7e3b0d9b2a6ea374f72d7b60f8f85758d014ce5ff417e8b20880b9815d"): true, + common.HexToHash("0xc7eadd98b3bddbf680693449fbb1a139fb591bfb34b801aafd7ed479098ff1ea"): true, + common.HexToHash("0x82651d67960e6021c317256d52dccf96346ec244b8e45cfa5608c2448f71eaa5"): true, + common.HexToHash("0xa96abf37e28ddf5dfe3fea2c132b250bfa174534d61414c66e9ff106686f99fb"): true, + common.HexToHash("0x4285d3fff5b8f24c2b2bb157b964ac73fe149b20b61f86aea84a7fb9d49efd38"): true, + common.HexToHash("0x3d0c2a6ed92e6b877b110ae87383abd8c5b916447ac96457282bab20f7128852"): true, + common.HexToHash("0x5bfc7d057413a41b631d9cac5b807e8031ff94129f66294f08bc4119c60c40a4"): true, + common.HexToHash("0x90eef15a0cef33ea6caeb6fe567f3f6ea300f9cdd321925afce20a802b97f647"): true, + common.HexToHash("0x47ecc548cf215d81b732df4d3f0fd2c629019288c4dd9c5e24806c043c50d6f2"): true, + common.HexToHash("0x61db92e51fbc87f3570b6724c34f2f0535008dd413842a7f45d426ec6fa3ca77"): true, + common.HexToHash("0x4911800c4bf0deda0e368ff601cde187784127edbc18f8a5768e3e6e56468668"): true, + common.HexToHash("0xd8d3802d6f2ee12aad8c42230d946bfecbc889aec69abf1982010a2545b32f74"): true, + common.HexToHash("0x3ffb667e750010297a8903fa21deffad167eb9dc804a2c6c39ab0fe978170207"): true, + common.HexToHash("0xe0a3cfa15f53e3d922aef213c85a2a4f46cd6f900ab938bd1cab22d00caa3a6d"): true, + common.HexToHash("0x9b530317663f81332bc9841861a8e788afe9b31fd1d664332ebadbd0023139e3"): true, + common.HexToHash("0x601c84ad42763c87b0ddcbfdf8f1b3b46de36f715a18a5790a652a96a7839abd"): true, + common.HexToHash("0xd1ec1a9ed4961a5c8a1caf0950cab4804f569078e7b75fe52633d30e2819d94d"): true, + common.HexToHash("0xee8dab435cf64d8daada1d5284fc599556e6083d07719988bb69c6642991a803"): true, + common.HexToHash("0x39ec8ab0d1c01abf5641f85902107da16c982a84e132812891efe7335afe984e"): true, + common.HexToHash("0x292b857b6f49e1134c80777c996ce343d053377beafc61bfc99b74de66370977"): true, + common.HexToHash("0x9a0939d35c093b375ef54d9422cbd6ae609cbba9e7216cc635db38814dff0c30"): true, + common.HexToHash("0x3d885f559f085359703b8236d29b83ca199a072e240107affa52cfbbd137456c"): true, + common.HexToHash("0x6161dabf4b3b507455200fd6ef78efac50a167873c90564e097faa2aca87c260"): true, + common.HexToHash("0x5ce33ca45fca1a676b2076fce0cafcfd50a4c4854ae9e54c0ddef321d89f4441"): true, + common.HexToHash("0x99f88eaf1a16178f58b500607b583802120447fde09ce5cd2e944caa6cf511af"): true, + common.HexToHash("0xcd4faf2a3feb5e99b45bbb60e5fe6663ea005a525b0a4b2599e545d4b864291e"): true, + common.HexToHash("0x70763f797b482bf6744e5a3a3d72cdfdf7a2ca8823be0ade40f836c9c2dca012"): true, + common.HexToHash("0x8f5a6223696cfb48a375caabff0ffb4cd622eaae7ce9c62e43b074ec478b4239"): true, + common.HexToHash("0xa0ff94c71a1e5cd8411e6d0c460c99667ed84bff51f2d7f51677a2d6a661bae3"): true, + common.HexToHash("0x10d8b7263987d58f2d87faff1e0d84360abaccc3f12a715e5432cbd84970f35c"): true, + common.HexToHash("0x1eea797c779b7f5307ea7e1c32c64d8c2d1b807fa2ccbcd4be95aeb9daf1605f"): true, + common.HexToHash("0x4c967ef2c45d7c29a5183eb8467afce0af763b3291e987239be99d31f0cfaebd"): true, + common.HexToHash("0xc22cbf9257c6c4584c6fd546bbdfb7fd3d1819e17e65dafcdb3ddd118a14a322"): true, + common.HexToHash("0xd7154c4d5b587818e1c87e1fc850676b2b9c233deb70a6f59a845d94e7caf04e"): true, + common.HexToHash("0x0241ec8ea24dac82bfa64b85637fc812c127f035d61662a30f65ae10e85c6f58"): true, + common.HexToHash("0x81554c43d4ddc153965cb721a8a98fa77b45733b820bf6778abf6b599d36ee46"): true, + common.HexToHash("0x7f58436fd367db95900ebc0de62888cb99d8e43730cae25a191083d80c22a124"): true, + common.HexToHash("0x06b036b84ccefd78f540a803c18b6872e6cc2ad8e2ea17f67d0ad16529170da8"): true, + common.HexToHash("0x4541b9dbe97ded20ca5ad17dfe562681d327478488da6e841d7fa27ee5484510"): true, + common.HexToHash("0x58f7be37155d91eb95dabf4117cff1c4d53d4b1caaf0205dc0b270132c16b657"): true, + common.HexToHash("0xf1179927611535cab311b16feeed6ee294a82ead715ff1586e29538de708a28e"): true, + common.HexToHash("0xfb0e59bfa1bd05e08b2578c7f8eeab026151f00b891b710912bb85edc93318eb"): true, + common.HexToHash("0x48a9e0d0449626e8e0b9274f56cae12f42cf445c60978fa5f554865275d977e1"): true, + common.HexToHash("0xc1ff0ce10380bd12631abab9c25e91bbb0fad728a39384874077411d2260ca0d"): true, + common.HexToHash("0x6b2d4b5562323444e141b7bfc689a547587e0c708d58372ad81a0ccadf61adf4"): true, + common.HexToHash("0x7093ddd3ba4d39126d0ac845e1167314e1f6ec4b8fd973ca86698ce401fb529f"): true, + common.HexToHash("0x52662afceb2a8e39d4363421ba8d63671a9988da81bf2b0aa6ecc8e8f7d82e87"): true, + common.HexToHash("0xcf762678bdc947361d3f0d847149c0409b8d91136caf60eb6a15bab2a59c716a"): true, + common.HexToHash("0x11c0d39fb8222ff85c4f106f2f37c59d5b08c5bd88d6b6c1d0d44052d29b6b96"): true, + common.HexToHash("0x2d8058a084aadaa6027d12e260380769e89fdab8afa5e25ceaa79f73720e8f4b"): true, + common.HexToHash("0x0a87b4412df29c26e0f244b398f8831183753271b73a604e9d843a297f73d878"): true, + common.HexToHash("0x02bf8f387beb248054d3582ac7fc37cc23f5b2d340553d92405babb95b5bf55f"): true, + common.HexToHash("0x2a8b3a5066e1003737d4c59c832d7f6c0c424c1beed02be79c96b69c50dd9563"): true, + common.HexToHash("0x6d442b1f27ccce8cf069c3d68df22991d5b683eb75e430d7e73647079f66e204"): true, + common.HexToHash("0x8e837124c15ae846fd00a8e4242a60293b68f6da7f177a31f98dba8746c3a547"): true, + common.HexToHash("0xbfead2308ac1c3c994ab6dc20dc98ed084f775a34bc3da846c5afcab1c69ba75"): true, + common.HexToHash("0xcad83c26fe971b650208c4fe1af1776771583a878767dcfb58905a8bedbbc6f2"): true, + common.HexToHash("0x8aa564b5cdb5f132b11bac2a3132218e77bc916f335a8b2ef5f48dfe84c3af74"): true, + common.HexToHash("0x35f7dba6254373c48fe34aa43bcac1ab0bb55830b888e01f945cdd268d4af370"): true, + common.HexToHash("0x05d7f1054628541e18524d0fd17d3ee38a29bc9f9db6449532c82d1bc70829e2"): true, + common.HexToHash("0x27fb289bff8db89289bc1122b3fd0a841ed07f4133189cd18bf81a05a7a29b7b"): true, + common.HexToHash("0x1ff58d0bb407ddef7c2ca7d463e5bd208de2b84b7d28d780b846ffe865d42b1e"): true, + common.HexToHash("0xb38f5c904e90864fd06af7e0b7e8c2d54362ba4f445d1e125a9f7f14e27ec72f"): true, + common.HexToHash("0xead28d4f22b5c26793bc4c6dc3a98f3307fca4ddf9d8705e49b4cf1a816f468e"): true, + common.HexToHash("0xeb45d934d1c64b7af5afdad4d5823d7a2d3d41ef8f1a69357faeadaa3b26269d"): true, + common.HexToHash("0x56243e6e7358b3f13cdb43dbd39425ee3f2c454c77127ada67ff9047e379fa09"): true, + common.HexToHash("0x8f555638279bcf186e9944d4e44cfe642dcc3c69e3985398f2c9d5b9a12749ff"): true, + common.HexToHash("0xec609411d5ddaca195ce3d34c249c12490fc8f682c57290642b0cdaf4989dc31"): true, + common.HexToHash("0xaa0808d62714902c14042c9624cb058dd783edc2bf0b4fe64289cd9520da29ec"): true, + common.HexToHash("0x40c1ff02fc06e486d58ba8270c7ffaaaf7549a4201920327eb6f01c04f1d41c1"): true, + common.HexToHash("0x5db10e60445eb92ca767ff3b415b7f414ad2c95625c7ac64e6d79c7d38605658"): true, + common.HexToHash("0x857fadcc0244a6dea5e46dfc193d2877103b57f1d5569df9b9ee2421b9939d4a"): true, + common.HexToHash("0x383670f02056871943d5922149075156fd85cb262729dcc86e75ae359274a515"): true, + common.HexToHash("0x8518e7308ab04546282e55138ce54fe89592fe771cf572438a3582f70493549a"): true, + common.HexToHash("0x7e5c860a3df0fc8c5909a025fe2a2672c57e66cb046acf717d434f7f42a81ca9"): true, + common.HexToHash("0x991b22f53d8fc576dfb2e042658dd765ba282cd716b95af6717a210340561e17"): true, + common.HexToHash("0x5a799fa4f9aa9e8be5f0fd4b66f9fadd77f8548f4affaf1921091c75a414a238"): true, + common.HexToHash("0x26a5eebc5d98b250df4116c7239a204956b2df03f7a537806c3a2cdc56e86df2"): true, + common.HexToHash("0xb96c9d124c956de8e1ac2b70061332fb33da72eca0edc42a5f71625c3e0e527b"): true, + common.HexToHash("0x0a82040287124bef0c06019d483bc230f0a0b01dd24aa0539bfa3021e251e3dd"): true, + common.HexToHash("0x3b318fb40720df6fea874422c0e997d26acac0c03b57f800111d529dfb82c680"): true, + common.HexToHash("0xb3242441654493ee1b9e12e6db2f732f8821b2baeebb8686d4b63716b1d022de"): true, + common.HexToHash("0xaf32f3be52bb739b857fb5ff2153bbd7a486de92ed20a9457374b68aa574221d"): true, + common.HexToHash("0x475474fc9b23ed5a97e8fddfc99c48487efcc340f0810ab3201fbbdb7b15b528"): true, + common.HexToHash("0x26148a1b154132abae3db812f505e41a60fd46fc068750f756976e31d760a533"): true, + common.HexToHash("0x06bf41398e90ecc971f2bcb9bc41a3f8440195c1ee4afb91a0a16f0d5ac27ebf"): true, + common.HexToHash("0x03e1ba11bf3e8efef3830789a7ed9ff1ee2c58775bfbf116eb6b1dd55fdf3f05"): true, + common.HexToHash("0x7a245acd437c973290cbe4baffa3cc81dcc505d00f96240bae2b4ff8f0861c9e"): true, + common.HexToHash("0x7c432e075f28c4601ef0ede1e925886fe008063bdf23bcf2b9180eada225291b"): true, + common.HexToHash("0xb08d8bf252cd0164030326a0bd6b9775120e4dc9b340640e2ce2fd5b03815965"): true, + common.HexToHash("0x96166cb3c710c5e412b0fbea0496ee24549d770bce2f62d05bec03610d594363"): true, + common.HexToHash("0xe42da0b3d857797c161166b39ffb3cb88985ad48c9b6b01e0aca0510b396798a"): true, + common.HexToHash("0x1e44c5aa80db3a96789a5e3ff735d8c3e9371eadfb4175e15c98f55b3d2897ed"): true, + common.HexToHash("0xd275cdce43f9a88712ed38b1f7cd39f4e383a42b93b19ef7fd8309ffe5cc1230"): true, + common.HexToHash("0x4195b76dac98988ecee5b57dc3edcbe15759f567944b97b7b3c04d31f78f6618"): true, + common.HexToHash("0x14de970de4a7e25584917c2747bc9018bed9cb4f1c331c3bb8af3bb745739aa5"): true, + common.HexToHash("0x4a29304d36e266ff242c5185448eb8f2c7e46ebcae06ab4355168620440c0969"): true, + common.HexToHash("0x540d0bdcbee11756c4ddc9af87733516b6bcfa68aeaa2be3af1a7710e3db621a"): true, + common.HexToHash("0x318b434364f6c9915d1f23b271704adb61c86f55735ea3b9c09d6dd08d52ec13"): true, + common.HexToHash("0x857529a33b8bf1a2e5ec2a49425ac852403837c3a0a1cdca6b8c84768126f40b"): true, + common.HexToHash("0xba17c0fc6239717c68751e6888a55fd15788d4ebae4a854b8809a1cfcadd69b2"): true, + common.HexToHash("0x78e43225b4639e9540339ca90eac2a16807b2a0eecbd39a8847fb6e688ff4641"): true, + common.HexToHash("0x6a3fcf59aaf9c7e80167685790a1a7989a1a3ee8d99ac0c69d5af434619cb8c2"): true, + common.HexToHash("0xb47ffa8fca10c1d1b16fcdb96a2ffff5abc08f1e292e8cce9555b8ec2ecc3c8c"): true, + common.HexToHash("0x90703831d2cd100534266882fae8726923f4d60feaf16f7e9c835b8e7f699798"): true, + common.HexToHash("0x8275b7190d15c9c27dd7da8a0f07c4aa9c1028204a00750505586ab1556a4fd0"): true, + common.HexToHash("0xa4f8cf32b4c0b6528db55cf41dddbc6b129cb77cd357cd0e446fc98d5b22fcbb"): true, + common.HexToHash("0xbd3dd0ae7fee8984b70b543de9f76f79edc0e9faf3f0c8e88332ffe1a0e8df1c"): true, + common.HexToHash("0x508ade0e6adcde460b617e7ccb2415dedd34b98f9df07147fdceb59878a2635b"): true, + common.HexToHash("0x25cb35991f791f3189f5f1ae7ea77ce9bf92d7c69d141262ad049c4fd1916131"): true, + common.HexToHash("0x867e19627ff74610d98aa467956d562ca5c224ceea3d47c7a2b29906bbfc384f"): true, + common.HexToHash("0x0939fe1ae8cb16202fbf93153d560b6b32bafe7e7d7777287efdcc6bc7f1d67f"): true, + common.HexToHash("0x9369ef326a101de308986ed50867bc63f8b75c3fa6480ea5bce231d125418043"): true, + common.HexToHash("0x686a045208d3eb84cb7ca46a50dc4fed31e15b4d4ccf502fedb1a8be4f8c4634"): true, + common.HexToHash("0xa1826899dc5757648785da5df34fc9bff1b1390784f5d779988a0782fd494df5"): true, + common.HexToHash("0x8b4249df5619839361fe1891ad43c1f22148b4e0fcefdeefb6e5f89b13b8d8af"): true, + common.HexToHash("0x4bfa1c744a8f94085920bebc2feec2f7353bf0b5ef7d19ee72cf6284629165ec"): true, + common.HexToHash("0x344f5b77d76c9b45348006453f8acb23dc43d0771d4fb45bd198c35d4d6fce96"): true, + common.HexToHash("0x55989f581fc2944ae317d07c7945f83c1a0dde33e2d176145c54aa0cb3707ff1"): true, + common.HexToHash("0xe3002c0fe766465574e50dc6834e4d5c0eb3474e51cb7e7ab58946038ad44324"): true, + common.HexToHash("0x4a70f2a76d728f921ad33cb261f595d3006aa66c57eeca101676f51bf743767e"): true, + common.HexToHash("0x8b6730cbfe63d5e4a3de6a7c7b0b2705b9787c5c3b8d68bc7a98b92e486b4336"): true, + common.HexToHash("0x1014fb46ee9d9d33a369ec4238874fa2bf08f53c440647a2db8c17336cfa20a0"): true, + common.HexToHash("0x32fb06e23c360ebfce0d9faedcfcac10d3cfede97f64c9d5817dc54246ff7e68"): true, + common.HexToHash("0xa9f8612f4fdf09433fbe149d5afbea26285f819a131c67f3189d1b64103d7010"): true, + common.HexToHash("0xa637bc81fbcde2811f0e69fa1cefba207e42b388d8a7cd29f19744da17d36f75"): true, + common.HexToHash("0x50a86ba8c02bad00ed983650fa00b73d898d14faffbc00341051c792d4edcf73"): true, + common.HexToHash("0x133dbcdd1d4872c1f1604a8af757054110bcf589a1acc5376a37d54fa1338911"): true, + common.HexToHash("0x5b11427a76b8a2de0e8de83c81f267aca53b3e16d875c4ae0875559d906eb9b9"): true, + common.HexToHash("0xfc127a1044c4a6c169bb718586e91f9874d067727c38c6d3155a510c044af919"): true, + common.HexToHash("0x3485d17190166a38e777932bcfa30514aab05314eddcd05b32071a5260c4e7e7"): true, + common.HexToHash("0x3990e5087a9dc434d603f76fa8b4061e17da217892886afd55c94eef73b1b5f7"): true, + common.HexToHash("0xc5a1f298fec8cff41668127df38360cddb6c84acb4374fc9feb7ef085130b708"): true, + common.HexToHash("0x080012b9d2a620749fca3c4b3567c2373ba0f3c23113f85d36c968481ffce467"): true, + common.HexToHash("0x5d87434e05003d20d518b2f6815c018224595df1f6a60d2120a6cc524bfeca85"): true, + common.HexToHash("0x23702ec5f3c525143a5b81ab0509bf79e8a18a1d9f42a6fe17cc2b3fcaa38be8"): true, + common.HexToHash("0x6dbd40e57d3e4ecc77ac0f9323c703e3f5d083a59e8ddf83a66a0243dd369883"): true, + common.HexToHash("0xad0a6e7d61944d4ffb74455f1bd7a042c4ddf01ceba482563bbf9fb7240dcc99"): true, + common.HexToHash("0x157e97cd04ca19d1a1624bccc9c0cddda48c63ee61cc981f601617c81e3b660b"): true, + common.HexToHash("0x33d1acab51a3dddb4b704e9b24bc4d744327c0b12417e7d764649a7320c1e92f"): true, + common.HexToHash("0x4f8f768e3c8eb6ef7cdd4784b8ea6e2a54bba664316b34a829fca5afa5726ac0"): true, + common.HexToHash("0x803b0b60c68fb9eb003ddf6893f9d475b0480c542be3aa61040e4c50b4051212"): true, + common.HexToHash("0x7f21039846847bd8fb89d5655ed40c63f80854fbb7c64369974d00dfe2fdcbfa"): true, + common.HexToHash("0x8bd0f1dc12c67fb2b6144b392223da4b2290489d2f57b0c684af708093dfba81"): true, + common.HexToHash("0xf9ac3b69651a87311d19c5528f638c4fd9ab762b0428f64c1db3b214da1b2c62"): true, + common.HexToHash("0x383ebf351305f5603b227e03920bfb072c2685149dd927bc58768d8b39dfdea4"): true, + common.HexToHash("0x9cc380d997b9f990d4c7d4f8cd203cf77dbc3d3d480a42b7dbeedf0dc7fce97b"): true, + common.HexToHash("0x53989ae4f77be6d2c8c5881950b6e0357521b7e329f0a3562e88a1db480206ad"): true, + common.HexToHash("0xed9ff761f11a6321d97855f82748da10ceff9cff22068fe2ce5ee6897937e5f8"): true, + common.HexToHash("0xb0b413b93f8adf9fe2c7e5e8915f55f87b6bc6087c61107f2b8573eaaa12cd33"): true, + common.HexToHash("0xa86c8c9ac34bc9c819c7fd574128e1ca0c64fcb38b530161e77c7729177e94a7"): true, + common.HexToHash("0xa7d0c12ca96bb3050bcecb579814b01c1486bbdc282cd456da0303513fd0ff15"): true, + common.HexToHash("0xc41756b7b8f20b399e8cb711eb96d1f6511283a48e6bbfec09a64b08c894b2da"): true, + common.HexToHash("0x1283e846593931cd17ee60f6c16c7bf6bf64931a2dc3a865711f19c6f8a3c238"): true, + common.HexToHash("0x65f35a8f8cee28aa3d98828bf7f8e79fbe872335bc40bfd4ef54e7d1ab441d64"): true, + common.HexToHash("0x6fff5cb5fb81dd5e3494ee77f9206c6666d6542a0342c32cbb67a40907162569"): true, + common.HexToHash("0x95a4216b8112ef5fbc3d3bdb156f73b6507e7c865550d67c8e525e07695f0369"): true, + common.HexToHash("0x1b373e68e3abcedf35d131a49e52355a293f05d6f0723fbea8338a8a1ffa47e3"): true, + common.HexToHash("0x0f772a9abb09cada77cb41d1c30396aca7041b652b4280a87cdf8b7d4bd1065b"): true, + common.HexToHash("0xdc33bbd6136df8f6b89588159ee5f19a5b5f8498c3808ab767cfa0f3675767c7"): true, + common.HexToHash("0xae0f429679d9c981bf49b1b05177bbd08ae3c76f7f397abc949ee5a0b1acd665"): true, + common.HexToHash("0xc60edd06fc67d9218d43b97f0c9ab1f376a45b16d7387d937bbfbe5f4c7ddfac"): true, + common.HexToHash("0x978fe4b49b01ec86be752da869d6c7dff617409f3f330e23af2e77760005d81a"): true, + common.HexToHash("0x4d5ce7dbc1ff48906d07375f4ff08c32ebb9ce46784aff38a74d9d18d4903955"): true, + common.HexToHash("0xed1b6a5446c5f5933ca1a74a9e7c1265946c7e038836074ec877cf5e248a7f81"): true, + common.HexToHash("0xe5c995c5a6bd34c7e352e1684a447be97dc9a02b1cf05b2373ee1326a824486d"): true, + common.HexToHash("0xc2d3526953ca4ba8bfdaca5567aaffe82ad2a9a9a89c14dc8e5e62dec8b158b6"): true, + common.HexToHash("0x75d74f36db0eada34fe553043745bbe949baf2a6719b84190d9f1ff9c2788af7"): true, + common.HexToHash("0x3fdbaa4d9f096dd009137e224791f49525b52f4f0913ac5f184240b3d5ad7359"): true, + common.HexToHash("0xa1f397b51692f82f2e983b430c89bb0e19b9547b066132eb4dbd54dc3a4edb0b"): true, + common.HexToHash("0x422b8bc448d5abb4a91eef423a3a784ba5798f7a3f047ffb554b8bd7ddea6543"): true, + common.HexToHash("0x88423380af869d8937c7f074ec962866eddcf5c5fa410905a38630a172824a8f"): true, + common.HexToHash("0xf99e45cff3ac14cdf1c07ba485b842895ac69cae9e92d3b900bfba0e28ecd7cb"): true, + common.HexToHash("0xc3d6942582871583f9deeb106d7f33c5d11ca105143f67ef9a5bbafeed7573a3"): true, + common.HexToHash("0x1ea9ab3dfd35acada1340f532b1a14b0aad161e650a1c421379e9e7178b36208"): true, + common.HexToHash("0x486a82358ff15549c95571e2a1acd5bc3992c6be8bf3928c97e363d4148ec9e3"): true, + common.HexToHash("0x71a336bc6627fe7668a4b4df58019e816899751b578f19ef17cfd33b57143018"): true, + common.HexToHash("0xbb6f6b780c6f672d285001feacc53d7860bc3065c9d07b13088caafc9498b993"): true, + common.HexToHash("0x9eae3fbd9ff1c65d80896271e9f1a6f15449e25934171e7e04b48473ef35ab53"): true, + common.HexToHash("0x617d506b8e371bda582c14b9473709d1c61048521c779123f155e221dbb36d4e"): true, + common.HexToHash("0x7b1934f1eefc99b08ca0de98a31eb6fa0d759061969855b8593794c5106c4fd0"): true, + common.HexToHash("0x5b305748c028a1fdb33e92d35da68e70b1982f9b3658013e29e2b22c1bd5f6c9"): true, + common.HexToHash("0xe5962f468988ebeb62d2edeabc19e82dfa32010ef7226c1ca0e55f5b9e1aeb91"): true, + common.HexToHash("0xa3bc74bb0a8922551c1f05fae08b97882ec024c1d38c108d29b38678058f8506"): true, + common.HexToHash("0x6dd50e7a1486e6e03336350fa79dda92440f0a55275a340ae5d8bce632505206"): true, + common.HexToHash("0x526b8fd610133b1c2968d59c8103641b635cf03d31dbe41b51381432a12703e2"): true, + common.HexToHash("0xd769ed3fbeb167878f4921e4b3a36afd5e52b5a4897954d1ae18733950463d70"): true, + common.HexToHash("0xd60150eeaa53ba4c8413027dcd7a0be379020fbe5b191cb8fab2b0a8c1b98db6"): true, + common.HexToHash("0xcf50067c6d7ef237b95f200f7ec1d24c623ba90b93e86e7aa9b8d5726a80ba81"): true, + common.HexToHash("0x57d59a041ae76c7252f5e88456ffe68d3ecca1435c98d6222b0554adaa115fbe"): true, + common.HexToHash("0xdb11b34bc0cce98bedfec926b2a71ab24677eb885e1bb33cf030d8524727efa0"): true, + common.HexToHash("0x388476b62e02e1543327bd660ad2f6085796b46e158a7269694c44852037701c"): true, + common.HexToHash("0xd0de015c1175bb11166974a53f3de5e0cc63fc73485691f9e972cd4a0840a11e"): true, + common.HexToHash("0x64e40463454b63cbb9636100b0b2f36fdca42ea1621ffe0c89a818f92667dffb"): true, + common.HexToHash("0x76d9c285092a8440a6f29a9de7f58463a71f7d414e03858010657c6bd02f22c2"): true, + common.HexToHash("0xfef541c35a9daeff7fe910fcf5ca3f1de39d583380aeb4032b72d032b283fd91"): true, + common.HexToHash("0xc1567131bf5369a991acc112a7a608a506dce55081989877b32fe0b0770b62be"): true, + common.HexToHash("0xbc4343a911a8c28e9237471ff899924ea7c6d50d5df5d5fc97feb911ebb0e851"): true, + common.HexToHash("0x42f558727fd5d45c2c08d8d56fa8e0cc8aa965b310ab8040438b6fc5f985483d"): true, + common.HexToHash("0x5e59b96476f704c20a02fa1bcb71d8c5a9128c971e18cdcfe68359f1f8aacac1"): true, + common.HexToHash("0x1c6012da45fdf19c1a0365d24dcf0e14151f45dfb1b78356ade9cebc37f9017f"): true, + common.HexToHash("0x7a48784e332e0517b96241cbd6bf6a55711e6289b96371bc8e16d7624252d608"): true, + common.HexToHash("0x1785d74357552698f53d324856ea54e7bf0845e2fb1bae55b728bce7431e362c"): true, + common.HexToHash("0x3a572198120be8e09508a1265862e5426e4c16659fb56abfcbe5933855f189f1"): true, + common.HexToHash("0x54f5cda9c38e271abd3e83ddb78daa19a965ee560bd397a2720a302c1fd52d18"): true, + common.HexToHash("0xdbdb4b86cdaac7ddf74569c6c6fba86435eb61b432873f95448bf9c0f8f13bc5"): true, + common.HexToHash("0xe88fc014d0f6035b5549799e052e6a9b556d6a11668c977811d27d874d71d700"): true, + common.HexToHash("0xca319e0a25d9090533bc71f993748cd9e0503fa3c2680a68987147cffe37d0f5"): true, + common.HexToHash("0xf4cb4d83dd0fc71da7e00da1e1fda234c53c0c40bd44d228ee5164e6ba750895"): true, + common.HexToHash("0x5bb540a216f9fa04f2c96a1706d741ea0d23d12f316f230aded361a46443d2eb"): true, + common.HexToHash("0xf0d6e981dbf9bae5eec10e742dd8c52c60cccbffd61e7d71cdd89989a031f387"): true, + common.HexToHash("0xbe3b973249cd25987eedc3720d71744fcf2025b921215a72c3e4ac8f571640db"): true, + common.HexToHash("0x1ec8f29ad8b30120d8a40098f8ef0ccf12137b5c329ccf5b2eac4e3e9aa5a5d1"): true, + common.HexToHash("0xdced0f570e99fbe6699d14ab6ade5440f4b401b960181a970f39e2490e97b8fc"): true, + common.HexToHash("0xb475f6d34feabe3a6ebebf2a4dcdb835f636391baf053d70b084a8658139113d"): true, + common.HexToHash("0x207ca1b2c97631cac07d0d365534013ce34f3f1df4b4f7868e56410940872246"): true, + common.HexToHash("0x0e2605f21404a084f518914fbb10da58da0d2b026a0d4694cdbb9e90f2af0613"): true, + common.HexToHash("0xa22b959a24e2bf0f1c853e92ff6e3433d0faf7b909e81844ba3a6a3f97a20d3a"): true, + common.HexToHash("0x9b526c39ed9ef256e78e9484dd6f3b288b6944c6210862dd8121833887a0a551"): true, + common.HexToHash("0xab0333c08b000177f9d029bd637008bcfee281e56a07608bc3af78de60177ab2"): true, + common.HexToHash("0x10f2e8f1dbaf2c85debafe326b391c8e0b726e7fbc27cb3075deac8f5f3d0e09"): true, + common.HexToHash("0xbaa63927f3b87909f3135d3d2c6b6e406018dcf7bb77495a7441d5ff770a98b6"): true, + common.HexToHash("0x636817126754ee89d4a6c333139a6d10d79cfd3b8145931aa3f53e0ea42590a5"): true, + common.HexToHash("0x32a27323073b8e9ae80378551a79f0301be0c04ae4e85827adca2b73478bd5d8"): true, + common.HexToHash("0xbf55e807a83d6a9f34711d8983318cc8ac8ffd91507c14be364ccc02fad01f47"): true, + common.HexToHash("0x25fd4d654248a1a539ec0c6db82299e0cd235e55add8332573782f89bd0c0938"): true, + common.HexToHash("0xeb42961108201f7477e19dcea6bcbfe1ebed49035298272e9a6a2a7b2c69d25e"): true, + common.HexToHash("0x17c7ed7a327f8bf29f6c3949ac8883a9d07bfe6477d1c19f69c944f080856c97"): true, + common.HexToHash("0xb2bfc6eb084d8d2c716b538bb1d80c190577c73e73da7f03d79226fa01d26f16"): true, + common.HexToHash("0xa01ee7e12d9fcddfc486f5a04b7dbf39c06e0c13163e2bc923493f4f90982009"): true, + common.HexToHash("0x8921683b18eac51f8bb5278b847eb5005c02b3ae0000736c211f0402f841b05d"): true, + common.HexToHash("0xc38b345ce2c746e657fd6d4747651cc214d5d02c8a2cf836acbaf1b130c36a15"): true, + common.HexToHash("0x7cf294188d99f7781b49880bced5e48b27669b9c5e19cfface598414b2ab0951"): true, + common.HexToHash("0x754b1fce8cf2f382b37ff626f7aac376814fa23f13750084d84a0ec014113dd1"): true, + common.HexToHash("0x86318c6ab971136011301a53a2a5c96eba824608c5eb06f553f07fc9b9cb7c11"): true, + common.HexToHash("0x7b05badd8dfba4402d1eafd19ff5e26bdd33b74c174a1dbf0b4d453bc4d3be5f"): true, + common.HexToHash("0xbf1c002f86d8f59623c1f896c2f5f9ff7d32c3f852c841c3fa4ff7d63b07b7ca"): true, + common.HexToHash("0xf7d197dd99b16858d832ce7c56387be7efd0176fb067cd94636b78d96b4096c9"): true, + common.HexToHash("0xd06893bda1289e976e690797259902dce7c23952a099680500b0413025e36911"): true, + common.HexToHash("0xf066da998b3d70825fde3bb497a1415f20ce1cd78a725410d633fa142d68439d"): true, + common.HexToHash("0x2326a823ec3b307613a51ccf6702770b4fe6b00b0df0a394328805aa62c8c7b6"): true, + common.HexToHash("0x205fcaeeff4fa72809561c6413061c6dc5b4ef4e1a13e4742b75f37221477b76"): true, + common.HexToHash("0xc956ca7c00ba6020811e7a1f37469ae36e1a5366d6c8405f9bfec9b95ed6b8dc"): true, + common.HexToHash("0xb6c9871b30ecac9b0eb75ab1626bf166990a24066c39f4493694dd1b3bc51329"): true, + common.HexToHash("0x8139185b832e602689db92980d0ddf9e625a08cc232a76739f2a6b73bfd268bd"): true, + common.HexToHash("0x4e49ca4486276c1bc16f97cda5dd3b020bf3f3c2f9e6c1502f9511792f67e9ec"): true, + common.HexToHash("0x2396894dcd2bc2004c8e15d79e81fe70a6d6bf7e49110eab71b7a05bd5933621"): true, + common.HexToHash("0xd567181f6020123ba0adc0d4b184fe09b19efac94029cf44ba62628cd5867cc2"): true, + common.HexToHash("0x70c85ba7c05412c7f3652356aacee4da0e7d0952ee99843dca6ef3db7ad35fa2"): true, + common.HexToHash("0x7a590eff66e77e4deb4625286c18d8f3c2381da4ecee9d84d928c93c4454eb53"): true, + common.HexToHash("0xe72fa03338bf4227a58e6a461e3e70e21416faad032c277dd54a53c82d473508"): true, + common.HexToHash("0xf31e7df5021347532db9fec9829ce43d244c2127ef748de2834ac36fb6ef096f"): true, + common.HexToHash("0xc34ac0111cb88bec0ac878645cdbc650191e8deaae1ba1b2e1fb9137342e7b95"): true, + common.HexToHash("0xbdbf0cc9e1461d4638e6ed3b376ce900c0856aab3f5bf5734510c237ae8aed04"): true, + common.HexToHash("0x799863b50ae2c3f2145dc079317fc193b547b6f18a2b7a9a2c9de4955ec6a61e"): true, + common.HexToHash("0x02057f0fa5dc5bed1d8bf07edbf6bd8ea26ba57d1efcd1182a5e1826cec99e29"): true, + common.HexToHash("0x4b231534a48ba6a39ad9838b6779099db98dfec40ec266c20b9eaad97ebbcab7"): true, + common.HexToHash("0x767ae3f9a1a31718b6967fcd5fa3b4bbd94292ff53535719961347b37f0a372a"): true, + common.HexToHash("0x75fd053c54b00d03ccd0b2ad8624eb59d8088da0b3c91921f63e403834ab7575"): true, + common.HexToHash("0x619f0d2d5ec214b47f5fa4ed261bfb6dd00f7b003b08795b3280b9b329dfd939"): true, + common.HexToHash("0x5c8895a333107c63c674b1ec9f5af9fc4f0d012c1e510a0fd91a004f5e594b42"): true, + common.HexToHash("0x911af6d3493c46d3b4029ac5141bcae927927604653fa7ace2f7366c19d4e38f"): true, + common.HexToHash("0x8d8e6e0d64770611078b7f09f2f7957fec416da3992defff196ba88021a05bcd"): true, + common.HexToHash("0x7250651532e42ac0e49e761f4669342a3f63d31a52e7b55afead9385a09256f8"): true, + common.HexToHash("0xf2b5713243cd8fcfa71b14683a4f73e4a3fd3b21b4d7f7bad5da5373411b1140"): true, + common.HexToHash("0x01f055a206bc876ab1c4389f25cc5e6c3ed41307b1433ffa7784fdbd1c550b22"): true, + common.HexToHash("0x403b98a94989ea1f9e1f23e7537490d2f18db826bd420689727ec3f121265986"): true, + common.HexToHash("0x2e0700002301aa64667dd0296043253ab68ae83a4260487258cabb71400b21da"): true, + common.HexToHash("0x967414f7612415b80a5ab57d54daf738d5e97c70ccceb7fe8b4120130fb0a61d"): true, + common.HexToHash("0x4adca33d4f5f6525e91830b1ae38f5870c980e1e286e2899694eee0d0527804f"): true, + common.HexToHash("0x968b9df6791c4440a5cf5986849f2c5c479673ba9c1449e3a849a38ef23d7686"): true, + common.HexToHash("0xb1ccb09e13db0e1ba93706671c1c9a7eea5f05616009618873aa1b8ce21604c0"): true, + common.HexToHash("0x01130903f03eaa85e0778dc46a49be5d910ac4cf934e7acda5c19f52ea32df64"): true, + common.HexToHash("0x30739c0138dd1cf862c83c80127927cf4ef61a0eff58ce629126645c0738efb8"): true, + common.HexToHash("0x073b2078288b76fff861969f0e1d77ecd4f146dab5f30865220f313ef0a6871c"): true, + common.HexToHash("0xd6dc6dec1b0800bc919d715eb39bb2ed51afdd2d5ecb4db9d61482f0c855d330"): true, + common.HexToHash("0xe3bf451ff9aaf7121d782f458c6d7216c013dd0ad42347a75a3dc491bded9bcd"): true, + common.HexToHash("0xa656d80756cf073402b7fd31a80e5b056bca740e05931e4ec057310f53955e3f"): true, + common.HexToHash("0xfd7be745cf651e4f8ce0d3dc9b12f0f215a5a71ef489da36cd310f318c2aba63"): true, + common.HexToHash("0x175bed8657a8e97123ebfcccfb6f314f70d947fc9cc0c61622d9a3b8245f591f"): true, + common.HexToHash("0xec1c77a0d793b81c01e25ff7545fe63c751afd4d78e705d0f749913c188c1f8b"): true, + common.HexToHash("0xc4bd8927d6cd5529863215333af6a93388ac3e5c18b919a12b072c294e913b12"): true, + common.HexToHash("0xf98f89c85c4ab9acb513239e7feced1f9f7abc03f0ce072808b86a1c261e5695"): true, + common.HexToHash("0x8a01dba3512834b4678d67d30ed1f60bd345289f184b847cc4b9d4a9dbbd858b"): true, + common.HexToHash("0xe7bdef843136438bfc035644702873d073985c0e905237a44859372e70be6c96"): true, + common.HexToHash("0x60ab06a8b0162fd6deb0b70cd8915e77f7c1a5e09e2a443464b6d0c8e7cf119c"): true, + common.HexToHash("0xe436ae26f4f6c5feadf3a96d31948c799589705dcf6958a02ee82241fb11367f"): true, + common.HexToHash("0xcdd18b49d00fac017e80f9d78fc7259e71e47196c35e1e7b65051a7a65224496"): true, + common.HexToHash("0x462bc6f4922a586b4cd6097b89ea34ef48253564a8ca2eaede353304aaab04a6"): true, + common.HexToHash("0x21b2e145e575ae1e13ec02b2809324c2ee78df01cecb5109447be2649e6a23d3"): true, + common.HexToHash("0x489b8c96b8de0c53b07cacb77022481b0e66efaf17d3fe8b367f9798dbf4c978"): true, + common.HexToHash("0xe19f112c4c45f53870afe9b04f5931a9fd59873b02c1a6c12ead4ab8010390d5"): true, + common.HexToHash("0x020835716a220aee6987147373946b02592508732c28252d881039087af9c17c"): true, + common.HexToHash("0x133d6af3f1156819f0ba6eb84ee0ec3d0c6371e03708f8606ea7071c6993ca45"): true, + common.HexToHash("0xe3ea2c81052cf37d7be70c4c6f383433eee2a081ef4d4647dd8a2af189c0731f"): true, + common.HexToHash("0x434a26f103e1cd7e5e8b13316fb4e08508f8cb9f0d1df5e5b78408cbbe60a406"): true, + common.HexToHash("0x30928254951e10f2841e54dbe15132377596438228bbd519364e5cc0cbf487c1"): true, + common.HexToHash("0x2e80c0597d81a50f54201d6a0de7464d5ff16a63d1b548c296923ae2a883ccbf"): true, + common.HexToHash("0x468c69aac390c23e0d602cd8e700aeeeb9e8bc76767c6c576af4186f21bab53a"): true, + common.HexToHash("0xc340d25e3e88a00747f71c717aa217e40b5bd415f524c5aa477646996f338d8a"): true, + common.HexToHash("0x2bdada3c10dac704ef7686aba5de4c4fb7386541e102da7eee06a750c10dcf1e"): true, + common.HexToHash("0xf44d15e922bdf71648a7f9ecbee3ec027c74b20d046ced2d6675ee56ed027ad6"): true, + common.HexToHash("0x091fd7584d9c16c786dbf3fd29cdbbc1bc0cddf87864c66977685acaab6f3eb3"): true, + common.HexToHash("0x18f3f65527ed99164ec0b02f24603060d00690c0ecdf2219657402d62ad418ad"): true, + common.HexToHash("0x46423f3c1d63147d8b294fdf0f1a6ecba90d33d84979044581d92eab55be4196"): true, + common.HexToHash("0xa1fd93aafbdabe0f4024b126de0be684e14c4aa517cea40fa36f59b00d073ff8"): true, + common.HexToHash("0x8e5d5f2978787cc0cff7e6e0fb303613ef7398c660e1bba10fdf7bde7a8fb03f"): true, + common.HexToHash("0x193c7c4481a754f885b9772cde8a8d1a7b7ca5ba5656c563a54d4fc1e79686ed"): true, + common.HexToHash("0x5dd4f45acb203fe7faa0cb95c08d78ef9fd41bf4a7516aa98c54fa5459a9911b"): true, + common.HexToHash("0x5aed609db6913a1d92fedcc2216acb11c69ca14bc84437d801a3e6b2e21edca7"): true, + common.HexToHash("0xf058636cfae00be33ee37919b1c0f331ef31d18952adada1d50eda6d2302c2f0"): true, + common.HexToHash("0x16c1c074a1a1063e4fab24f2c4c643a95b1d950219cca9a7c831a9c060a973d6"): true, + common.HexToHash("0xd73754f0a0b243a046c4a0fa068693333e8dbea4f7569361cc54429d205adebe"): true, + common.HexToHash("0x78e5422eaaa27cd7723b8703efa89690b9122f021ae054a44c6d78a0431438a4"): true, + common.HexToHash("0x3976f37364124d985576aeda566ae3d1fe267ec7fa28fda17fdc45ef75164b5a"): true, + common.HexToHash("0x50b4e0de3648dccd31735d2ac7bbcbe0f8608bed6db60f54c7bb28a34a71f6f1"): true, + common.HexToHash("0x46bff5244d06d3bbcfda5f2f593672d1f4949eefd2c5d06ea2192ec31dbee738"): true, + common.HexToHash("0xa971a50c26f75eb8a3ef52f7d34438379b0118764dc4ff259c5da4d68a625f8f"): true, + common.HexToHash("0xb039ee1cc8e2504028cc417b40584a88d6f41ed3a0fa24b4553d95633a8cece5"): true, + common.HexToHash("0xda604ba77bdec92aba8bf5b5f75203e749a7e81c2af7f34a5ae8a90699f58e2d"): true, + common.HexToHash("0xff3753645b1b01395d32bb336b5ec56ff278e9a5dfb0eb99777508cb1384b3c2"): true, + common.HexToHash("0xd07d8d6e6294611ce40104107bdd1997337dfec7b78ee79bd45ece84f7bec8b1"): true, + common.HexToHash("0xddf380972a10ba74a7dac3f1e44656100a0bd0d8aad0e3bf25842008068e83c6"): true, + common.HexToHash("0xa5b5bffdf774de28bf64902aa204ca5e42cf669e5dc2426f0a90fdab8b8a0f87"): true, + common.HexToHash("0xa3a8cca2cabfc381a703ac63eb683f94aabf9bb0329da537766fee3907dfae63"): true, + common.HexToHash("0x876485e4229d6328b3f5cfb11f9750c48fcb661ded3d0189d6470f0aedf37ad7"): true, + common.HexToHash("0x55c1080e0665e52ef4919af2133d50b568e267b38f3df991be89c7db4aa0fdcf"): true, + common.HexToHash("0xa064efb032d9a30001f9cf1aa04863a537624b0b61b41d17c0cc270eda58eb8f"): true, + common.HexToHash("0x817d37fe9c5b05d5e645c4f5d42dbfa0606df310e3fc8d175707d4058f68938d"): true, + common.HexToHash("0x49c73c37ebbdb0b8046049faefbf55c88c469d6c7a840dd7ac898170eff19f27"): true, + common.HexToHash("0xfb2aee1cc6ab2932aabcdafe3f138192e20452b96df2cceee722fca1e1b26350"): true, + common.HexToHash("0x67041bd5603f301fa5e5f1cb0a173858ba1ab3ff302afecb9e4e59b95d465805"): true, + common.HexToHash("0x8eb7021a7e6461ceb86d68ca33f71044c1e981b3a3dcce4e825f09ed07e8ce4c"): true, + common.HexToHash("0x2e3e10bf4b501bbf7bff59136113c237e8222988ea5493394f3c4fe9929f12bc"): true, + common.HexToHash("0xed83669a3e9ab362ddb0f555c34345dd1ede01003a51b588b62547119ac00bc5"): true, + common.HexToHash("0x5fd806c26b94bc3fe4d2ac20dbaeebed9d64a1f6811973f35bb43812fd6a5903"): true, + common.HexToHash("0xfae81102f6da4cd87b48043a3ede9e2aded9d26c0fcd121d2f217472c11d25b9"): true, + common.HexToHash("0x162e2b3164c546356f5b7a004a59af57e69ccef3325c12e21ec6a124afa888ea"): true, + common.HexToHash("0x64eecbc5a8404a59468140f0315480ed5734f454f5b31d2a7bccb9a2ba461acd"): true, + common.HexToHash("0x1aae6a021f7c2f5a6b771c1f9f0f8d1eeb893490784ce0c19110d48208a18052"): true, + common.HexToHash("0xa6e47128c81946d1759651aceb2226954ec1f7961e20d73ae2d71aa54b96f44a"): true, + common.HexToHash("0x767e5a0fe4d6223d5eb70912474027228320bf022271f9dc5656b97c24daf558"): true, + common.HexToHash("0x8004b23033cddf7254e1fa9a8d153a2378e4d5b46bade9ab8795e8b84b804fef"): true, + common.HexToHash("0x37f3fec6083f6d3bfce2dc27c38df57386580552bb5e53f6ddd2dc115be56f48"): true, + common.HexToHash("0x0a658d63b39f0d12b86a7cf3faf211143eab8812bc9489431ef7f093904da0c7"): true, + common.HexToHash("0xa2bd889872426c3f3fe0c639dbf12354b46aecabbafc3cb39574da7b0c02f61b"): true, + common.HexToHash("0x5d3f4ddc66acb9d6bf428c967933de7e3daebb36059b45a1070ad87ade5f6731"): true, + common.HexToHash("0x176af05900fedfde1efda4cf9595ba8898cc2a0dc361a3a97d01256dc4e97a75"): true, + common.HexToHash("0xe824f2cfc208a19f875a59e14f335513e466649ef70318e83f0466b2d39541f5"): true, + common.HexToHash("0x577745c5b6f000f9abaa59f415bca3f27f01f99186e3316721319c5c8c7693fd"): true, + common.HexToHash("0x1774b72b524a45265c05e1f3c33fee692eabc2e6b3dc11049dbfc2eabd1ead3e"): true, + common.HexToHash("0x035bee9e3d323fb74503ec8b136e071dc06cd1cbb2e11513b195de629a3a882d"): true, + common.HexToHash("0x993a3a5a457bbe548e0b3bc33c0b492ca2f7dd354c3a6180fff8fd599b6aa3e9"): true, + common.HexToHash("0x87e5a0664a7d486b55af7776b6f4ff06d160101a0085b47055f5c80cd4f09980"): true, + common.HexToHash("0xb954e45071acb2a82fa11dd49c206d23d78dc035b2dc222a59d308e55a9da497"): true, + common.HexToHash("0x5a2c46b6ed1c2281b2f85d8915c1696045990008c5b6415107365958803a87ca"): true, + common.HexToHash("0xb2cc23ed6a8c911c0bb18648988fbe0e8fe1a38f48ff5a99579582b537e85b2e"): true, + common.HexToHash("0xe00caa3ed9d9b5e979a10b0cd6268dc7b1bc8c7c75a9a4abe614b1e6b704df39"): true, + common.HexToHash("0xfa5037bdfbd3de91c1dbd141b4a70a15b8927e11e73e10b42be8b1f1283ede27"): true, + common.HexToHash("0x086341677f8cdc5afe261243d6edf9368b1d8f48ded7fc19a84772ca30bc5e3f"): true, + common.HexToHash("0x98be7dcce811f89f6a26cac68eb522416b1f6e5c7358c3f625a02205f8d23d5a"): true, + common.HexToHash("0xbfd5ddd70c20580588df19c4dcca3ad26264d600c4be555b22463d8e89927477"): true, + common.HexToHash("0x7d5087f53b947efd5409f8c9acbf15625ebd027d363281ac8ffbab5e2259c81c"): true, + common.HexToHash("0x6ef189789a2049ae7a1972c3bdafc16c938a523d221c8c970d0ec7143ea4ce45"): true, + common.HexToHash("0xd48542a90399198e6295c7697672bbc535f763e718de6ce43ba940f61d2cae86"): true, + common.HexToHash("0xfdb7666e7d063587d035598a5fd86978bb1067751c956c402866901c5cee1333"): true, + common.HexToHash("0x0178a8241c0e2e9a99f2cfef0c57d332fbacbd7149ea6579ea4c1b883cacd403"): true, + common.HexToHash("0xc417325f5d7d675832eb9b52bbef995e3484434fefa738c6cddac0a9c75efc80"): true, + common.HexToHash("0x3663e1497179e035d3446a04c5f12ae321c0be9c4583cebc2f9b3d306495eb0e"): true, + common.HexToHash("0x43dd079e941f30dfef41adac5d0eabcbb40c1088c2cc74a7e6f18a22085775d5"): true, + common.HexToHash("0x79873d6bd1cd3f6062f414aa4e3dd0c6b76763f0736ee7f77f84a643ab399d25"): true, + common.HexToHash("0x24047ddcb6b885623d7ce92ffe93566101620086650bcbac4e025967ee1ea8f2"): true, + common.HexToHash("0x9129026100318fa78d1a03c5f2c2abe598e4baef3f4c6959124962914f263fd0"): true, + common.HexToHash("0x7e64e8e4c85c0fdc8f765b28ad527b4daeb23348e3a38c7669acf5871276e03b"): true, + common.HexToHash("0x11f71f6213ff1a51157441e9bf2d259df7ad7032850c890cb4503bd845889032"): true, + common.HexToHash("0x458316af381e4e3e76419ae6d1664138103de7c98c02b266345452c204d3e2b5"): true, + common.HexToHash("0xa4379521d31427a343706e76b6da4322852e3a208d6285931eb72ebb5e82e1d2"): true, + common.HexToHash("0x7975a997728ac0f1727852bf71f060b3f8f4113694c48bbbf4dbfd7b741a3a01"): true, + common.HexToHash("0x065c62f885bae226f7a01338c553b90f87244cc84447718e676cb65e6ba9d868"): true, + common.HexToHash("0xc0825c9b7f509e7888da866afe95cf79752fb05878ef5e5c9ca0f6c2790c4e7c"): true, + common.HexToHash("0x9d48f36534123022f9c04b6a793b400b11077b943f51651528f2381df7359ca0"): true, + common.HexToHash("0x4bf013e0d999a6635c1d1af9ed253c3b5e66205d59df275018a9052e35f559d8"): true, + common.HexToHash("0xa11c9fa2b45b3b794bdc523582cc36408e80a9e993dbf05a1b5383dfd54d0dd4"): true, + common.HexToHash("0x3f035f74bf11415438c3bfd8b8fb8b9341522e345d7d21f3c9ff0a87ad6ee63b"): true, + common.HexToHash("0x0663414d548a8df3985c456e865ed9a72c1c1e88c9e494416a4ef8aabfc71084"): true, + common.HexToHash("0x615be065ac9f566f7706ce7917b6bb8f7b103e0f008598ed4f2a0c15002c5357"): true, + common.HexToHash("0x5248b5cfdc186d742892385b0c65941822de6f8cbe546c41b9e981e5b83970f2"): true, + common.HexToHash("0x536a9ddf7fab760d4b3233ecf8adb729667196e5681d938c104e863abbcc7027"): true, + common.HexToHash("0x7bf4d980bcc988eab4bc6d201108cc9f21568f8308064e5bcb1a6cd9f289a1d0"): true, + common.HexToHash("0x7aa84dfcee70eb1caeec4782088dc672bf4dcc60383b0f799e05a28189621130"): true, + common.HexToHash("0x6ad5dee078f4796ac4bf90e100fcd964fe81059b1a6d7e326dab96604558e381"): true, + common.HexToHash("0xe00fbeeb765fe94af62e11c11a527210d180217624ebb50de7da75ac1873018d"): true, + common.HexToHash("0x039a00e2e5f16001ddfa283c14c263870431dadea8cccc8e0d31aa4593fe8f7e"): true, + common.HexToHash("0x569a838302a56ca194e55b6d60b349f4a932f7884c979dfdeefae86aac124721"): true, + common.HexToHash("0x65debd3124fed8b9f026a97ddbf89e4364f076cbfe3b3fd4ba1af7275a5f33fc"): true, + common.HexToHash("0x4d7fb691ec8dcf7e57ac8b759a6ff725526ea9ecefdd35841d7a972be637dbd4"): true, + common.HexToHash("0x5eedbee549781aa97447a52ac6143e69f5ae90047d8c801a0ecee8f95360856a"): true, + common.HexToHash("0x5a40bc47b0384762690c36b59a131a41f3a1cdbd1763462b6bb1c677689504aa"): true, + common.HexToHash("0x544ecd0fb4b05d39310c085f33e203c29f9daf34c719e60d6b2b79fbb6e79f7d"): true, + common.HexToHash("0x2cfa018170316b9221b352115452ea219fe34f209ed417012aca1525159015b3"): true, + common.HexToHash("0x386e7c8b8e6d493f7bd57cca5a80e6ff6f45f1c97144299ec29c8887715cd556"): true, + common.HexToHash("0x8379aeafa686cc29f0b47a52af1387b973334facc393689d84d630ad54edcc14"): true, + common.HexToHash("0x898bfd93e0ce54d237c0b0d20e162fabd95e6d42135b653fa2d9b4ee5b08b630"): true, + common.HexToHash("0x12d0ef99efa0c91ad63d4950c4830d380871f0a35b947dfd7ea47ea28b3ef305"): true, + common.HexToHash("0x80d2b717ebcb2dd0ea48466bfbf0bae447f12b854ffb142b37e7ee6541dbb988"): true, + common.HexToHash("0xa7fe01ca65d781f58b32384bb350a47e0a96f9f53d0012ccea13a5b420ef20b3"): true, + common.HexToHash("0x7463da264f777d02e6b99a39873fe235aa730eda14f65cac0345db3e412a910e"): true, + common.HexToHash("0xb70161efe0e7ae4c14a119a9b5180e6c43c001e9c80e8d6836dc44d5d899364d"): true, + common.HexToHash("0xfb0511c975e24c7ab982157fc9795ca69c738b0900c7350123c05c358fcf8102"): true, + common.HexToHash("0xdaaaa1dde4afcacbd234cf4db90425ec1473f505a5c8d229fb75eb1ac4769038"): true, + common.HexToHash("0xbaca0351de443b0c7d034ddecdbe245bf86d1dc1973cbab7d5146eaa4361e07d"): true, + common.HexToHash("0x177b6bd64419bf70a4c5bc4f553d27b203c50d2d47ddf9b4cd25f12f066e18e9"): true, + common.HexToHash("0xd0469479894677d8470f9fc404449118742d242d26004597609dddd8f3103a8b"): true, + common.HexToHash("0xf465b95a1298b1c6c1f1554b8abdca33af0ba688cb16c45cdce79aaef61d0f3f"): true, + common.HexToHash("0xbf5d01a4c955d74b0fcdf200510441d468afce4b63e61ee029e9a741c959c126"): true, + common.HexToHash("0x00d2e7705dbb5a833995ddd291428a01197569d7caabbee047f83ce0dfd2c2cc"): true, + common.HexToHash("0x007103241838eb0ba1d6a12f86e015ae3897f10ddc63493f701a9fa8b27c096f"): true, + common.HexToHash("0xb275908bdc5655c501b598573cde852aba0810cc19f9d81cca02f30a82eb9dfc"): true, + common.HexToHash("0xe54ec9641d3f9e24ca8f9d0341da504a28dd87c63e5cde38f80a96e1c76fce84"): true, + common.HexToHash("0x957b623f8675db99a56e6c9c812e1a78fc1ffc63c99c2c345effd8175ac8ee70"): true, + common.HexToHash("0xb3e2bc50d128f71e200f1f28df414ebc6a0857c5eb3b09d910ff2a07cff57b47"): true, + common.HexToHash("0x512250cde8e57acaf8ed1279e4dc8062ccb4ad426f4f8a7ebcf553cd98c082ea"): true, + common.HexToHash("0x0d5033d901caae32af386a07e8ed5f5e947f182329f9d4f668fa999e9bb3ff28"): true, + common.HexToHash("0x1b52b5eab7b8708e85f8a5200970b09a8faf54622d32aa424341895572815a51"): true, + common.HexToHash("0x270f1f560082ae1a7eb2cdadcb0765be268b7ccebdeefe80e65bf2b0233a0d63"): true, + common.HexToHash("0x26be10513dda84e4f97a9a1097fa5c739a527d6e822880310da48480b9a4b2d3"): true, + common.HexToHash("0xcc668d5a8fc7adaa99d60deee01c342d5130c709202c8a2e1df55a6fb3015c2e"): true, + common.HexToHash("0xb19ff73c8c4f2e6ab05dfcad0253c6a36b6a61533c013dfa5665d8ad00c6ce70"): true, + common.HexToHash("0x7189d3bb49ffb0cbdcd3c7d06c8d1b772e024b3a1ccdcfc5a3bb851c3155fbb5"): true, + common.HexToHash("0x908556120b21a878854e390b6495133c2f13b3de60896ca7d6a48dc9038f053b"): true, + common.HexToHash("0x85f67b270cb60cef812359e7280bbc5c41588d26bcdb70d1ab25da89bd454cb3"): true, + common.HexToHash("0x585a840e21cf894880debee8d35d274d325e123e2f9ee7036e111a0085bafca2"): true, + common.HexToHash("0x3d13fcee31bd266ca21a23366b0407cc59f0726790beafbea677f4398f3daf05"): true, + common.HexToHash("0xf4d27837fbec9b455a4ad4e9e5bb0a467b80c4eedee0483e10e001dc7c759e46"): true, + common.HexToHash("0xe2855192bd0656f92e5052b87960eebc0e5592437a2a80e837de1071873bc8dd"): true, + common.HexToHash("0x6c102e6d8a636267569fd4460bd9e7d106610b6de56b22a5c498564afe6b0514"): true, + common.HexToHash("0x3691ab0b9ff0412bd63d93229ff86f03cef9c7aca560d473d6899baa58be3d75"): true, + common.HexToHash("0x15d5e49abb53e07b4b040b9f4665908d32036fe8b2e19ebef9d768f5cbb14f54"): true, + common.HexToHash("0x95f2d896615504a27364bc026e2c0a59ae2081f389c651d35c9c61bf6d459170"): true, + common.HexToHash("0x4f42ad24e48c4e0d5a4ad2c25347530331114a253e342f938fb2c11ca3c242d9"): true, + common.HexToHash("0x37a11a800649fa61a751167c4f783019c46e388d99402e6c1626672b959771ce"): true, + common.HexToHash("0x8f5a704c7f0d5ec3d98e63c506ea6ce9375a48aac0493aeaeadec7a1c1fc2527"): true, + common.HexToHash("0x6b560a6cd6abdd9c46904d51aa82ddf58e3c39b55ac7da817220082ee3943488"): true, + common.HexToHash("0x69c4734878d416fa3d5b36570425ee05bdbab545fcfefcf164c0e5f74a146911"): true, + common.HexToHash("0xe43d384e0121645cfc8609cf31d9ce12dcb0647a33aa81c0c6f828a2dcab4317"): true, + common.HexToHash("0x0de7b76ec069d2e3285e734b5c9b9b3658ae00d131f1e6b069201ef073bfc101"): true, + common.HexToHash("0xccbf226248e733d258c1d9f9ce930365bee04feb60e71923595881fef0806c1f"): true, + common.HexToHash("0xa1333d67c8930cc2bd53663e865e74dcf913b6196e8df6d4415c1fe934cfb6b5"): true, + common.HexToHash("0x3e9938c49aa4dafb3d118e6e42c561b1d532640464136ee20da148c332e794d9"): true, + common.HexToHash("0xa6bc45161b69dbff9818d8297754071dcc60be19ba2b88de64a122956ea865cf"): true, + common.HexToHash("0x1cb117f8c91c92a53b46dad26250ffe23335fc02e2fbccba8f22e912d556030a"): true, + common.HexToHash("0xf170888fde9368adc39903eb25b61f912b3742dfcb5476d97d479901bcd1332b"): true, + common.HexToHash("0x18856cfbc7dfae939341c576d835aae66475a94e42134aeca37d4639216b8fb1"): true, + common.HexToHash("0xa03f3cdcc35ae06b58bdb48d7d4b67dd53770d4bb6f121a77a5bc381330813c0"): true, + common.HexToHash("0x8f37eef323ebfb7d655c29266ef8549a4872946b5cef97dec4366ac615bad71a"): true, + common.HexToHash("0x99cff7890cc9a0cef60b9c7d3fb4b4c1008a596b1b647dbf918c05dd6050ee13"): true, + common.HexToHash("0x93ce840b2c6e8ad34da7767dec8ea4b34842f682b4e6de79e250402ff8ee140e"): true, + common.HexToHash("0x78dcc206683dd14bcf83dfab96afe3815c03a8cc55534b74c0a5f9b7c8aa7523"): true, + common.HexToHash("0x45f5c5f5786807f806d6e5b80a3d7b7b23d0030025f829d1172ed8ee5be0de46"): true, + common.HexToHash("0xe571623cdc2fce74718f9badb5a80e86e21c26bbca4f659944589f4bf0ef1036"): true, + common.HexToHash("0xf8107903ff65d5cdc61e86aa700afa565c1cb8bf0b0f3d5800fbed4624223c81"): true, + common.HexToHash("0x37cab687b8e59c3e4917e526c49d1f07e79bfca00816718e3759074987825f6f"): true, + common.HexToHash("0x82a6be8ab16c411c43519d5ab1d657c976af0fc278d8a2f271247fb46b5807c6"): true, + common.HexToHash("0x1514acbf43b2bd3530b67984c1cbccc5944899c5c6e22be01dd7127e2c89b8aa"): true, + common.HexToHash("0xee7f416b5c4fae5fdb01cbfe34770bd4c6f1cf140d5566d3be993922fd27eb6c"): true, + common.HexToHash("0xcf8efcabdc5ef95f9bba28bdf20cfa1d4e72085256ffaa9e24330706299211ae"): true, + common.HexToHash("0x349a47ae2ef1cb356dbe73dff0895ceac9f1f4ec54c29c3424f4d7725ff5299a"): true, + common.HexToHash("0x2b119f52ed033290c995323ed76427c43c7dcddadf55e7f8772bb91c24ecb0f6"): true, + common.HexToHash("0x64a1eaa56099de17a99ef3b35f5971ed07a0363c669040d4f7515ccdc9137a10"): true, + common.HexToHash("0x45ca20b2e87f34b27e75011d3fe4ce8c10c419b08f7b8d4b0566fb68256a6e2a"): true, + common.HexToHash("0x4321c7a98fa3476221497445581f4c00491fe124d0fe416cf668f7c1d827a8f2"): true, + common.HexToHash("0x664b218ad6eb1c39bd5608bfd0a3a0a6adfde682adda21a18fe730ea89d35c07"): true, + common.HexToHash("0x65e229cab15f449e73df52e09fad5789499f97fffbb26583e9b0bb0d64166c8c"): true, + common.HexToHash("0xcc63d2429d7f7c1aeb703f82447f786c8d8f4f4636e749cb07e39fc53ff19743"): true, + common.HexToHash("0x1a0c098a792793baf8add45e4abb84f6284306f21fa38a8fc3e07ec73c1d7481"): true, + common.HexToHash("0x21778f6f8fb86e4a2720113f1da618a3174c397b8fec05f1f0c12dae6b14b81d"): true, + common.HexToHash("0x6a368d67eb95f457776b66e2018e29ebb99ca938b4a9db288fa9af02c9b610f6"): true, + common.HexToHash("0x98ee0cc7a19cf3e9f83ad4d595fc1279e79ad0a65e153f682e9360aaae663a51"): true, + common.HexToHash("0xa060a2c1d72598074a6afaaea37f8bbf096485f7d8da47cca1bffee8e75b0112"): true, + common.HexToHash("0xab9a1c6bc3223aec9defcfe9c23fc20d7a2a2be55944903b87ebb934ef524e66"): true, + common.HexToHash("0x4064d1943675b36cb40b6665a3895ff94e9b3c1afd7a2ece29a2ddd9cb3bb97e"): true, + common.HexToHash("0x7681fbe61f9e9c600ad92c128325fb925d0dcb815c2d5b188de1d83fb6539193"): true, + common.HexToHash("0x7c3f9a5e196bfa72edc154b817ded6822fa0b77e1aacfdece8c09ef2dbed9c9f"): true, + common.HexToHash("0x69eb811daf044ac2175d9b90d6ef2a5fc4f39d4396ab814fff450a3928ad336c"): true, + common.HexToHash("0x73cad4f945d9c4ff9a409e23ebfc6617b2697ecc5cafb0fe5451659a6fd7f1c2"): true, + common.HexToHash("0x7c365244ae8aa5f4e63a4cd7935e833b88de7c93336b296511c4e99cb9a0403b"): true, + common.HexToHash("0xca584a54d88900add7093edba8aa5ab9b4308e0f5d0c39e5c524912b500f73d8"): true, + common.HexToHash("0xd023908e904102c3de7e8614ef20f64d601b83b185f25da80ba0106d9904a42b"): true, + common.HexToHash("0xdc0243048b0e81d25d04d4b360f6350d7faff48563af8b2e7f051bdcda3ff0c2"): true, + common.HexToHash("0x106df18ccdcf8fcda56de6525ef2c3d0255eb55500079931cc9dfb270b002f95"): true, + common.HexToHash("0x3422fe1995c181a83847cd4ee35f433fbf714a245d6f78f8f6576a62011e6cdf"): true, + common.HexToHash("0xd4d9d810f31b58df3da2dd599d355a79fb1a2204ac218aab9ee4ae5ed5017bf6"): true, + common.HexToHash("0xb53355987e6b01651e656fcdfdf32aede6e7fb1245d243abe1430ea247115e2d"): true, + common.HexToHash("0xf785b637b32be35a279980b9ba569e87809746367759c63c69bcc900a64f1e85"): true, + common.HexToHash("0x5bd1bf44e93ee2051fe2e751c5cd165d1176584308f5906ca28c7cf010b8c05d"): true, + common.HexToHash("0x1a2ddcd8e732f46980ff1907ec637f393059d27b5ccddd6b0c07b8341e297c5e"): true, + common.HexToHash("0x180ca038df73360a8c0c92ee051d2e65e45957b59abdd0f31abf51ef94487dc6"): true, + common.HexToHash("0xb995596826a3ea61cdfeeb2d856f3834eabc1783afd7f1ae8081cf46916b1868"): true, + common.HexToHash("0xa7d927d8b68ccd30686be605fc310f42f5329ca2d2471f68ca86033eb8cbc0d7"): true, + common.HexToHash("0x75a16e06a9fa0e781011d295bab3c2055d1975141be323ddf7adeea0b051c1e6"): true, + common.HexToHash("0xa6e2c97aec738106f16a712f51078fd88f6705bfa1495e49b659fc6f88a74eef"): true, + common.HexToHash("0x3728dcb752bc9b12ef2d71141a5e71084c3d831499e5c2594b08f7b0d1b93053"): true, + common.HexToHash("0x2041408b3f98106f8261aad5b44a3eb874ab3885af732f5ec40a9cc51eb19161"): true, + common.HexToHash("0x396d9c55eae5686665c8f6291f62f37188187caaeed6b5f6882894af8f16822f"): true, + common.HexToHash("0xdfc663a2f1d605da8e592663fa71ed9e43b4a6bf823f6d2ae80473474533103d"): true, + common.HexToHash("0xccf5bec8212f9414488a8bad3a0600da21b47faf372ff7af6ba3dcdb399be84c"): true, + common.HexToHash("0x6316b28d7f586c05d517a6634d6df508d55ae44d2691a5dbeb7805e74548f4a8"): true, + common.HexToHash("0x65128f0981e030d35dcc998eacaa9e05b369074d953d5f30b3512c2f4ce74d3a"): true, + common.HexToHash("0x3d5618749a9cc28484ffd594000b583e74f6908caf8e0f6494880e34d9e19d07"): true, + common.HexToHash("0x20d30d8ea7558f5c890fb1ddc9522c066a474158f82d968e1449d779fb0e4dd1"): true, + common.HexToHash("0xbc301cd260bd468c6ca1498a682a9121357ece9cc353a6527af376774a7f33d6"): true, + common.HexToHash("0xc2fe8e1417882cd7b5935e1ee0c3c15192a0fcf4cfa9556a7734f4f2634821a7"): true, + common.HexToHash("0x6bca6f5f2acf5c00fde7ac7237d5a481e026eb94dd3b0d3e0c4ed808d55a0c6c"): true, + common.HexToHash("0xa7bc40082d98142626565dd077f2d63e6da5e9cf1dba0c66213b5dda87a7a28d"): true, + common.HexToHash("0x820745f2f93c8ea18b97ab0a1cf318de35f636672066b1644dc4a92fe4bf5d30"): true, + common.HexToHash("0xd96ea4e8eb988c7fcbc7b19aa889ebb83ce363b227fda6aa4ae934a038512a30"): true, + common.HexToHash("0x98670769c37b91d16815bc9f10ed73e167921ccd05180bc64955fa856c6f1578"): true, + common.HexToHash("0x9f261063ad865d2b23a31f9837ac8ae85122546638d13ed1e5ba4e820b5b9a8d"): true, + common.HexToHash("0x731b771e3fcbcdceea31ddbf5a993131ad8b5ea32496e8e5ae23570ee42f2917"): true, + common.HexToHash("0x4522d6e360d138bdc2bb2cdfa96977a16b2d893393c8b92bda8ea72b8d24d8a6"): true, + common.HexToHash("0xe0fad8903b534b88f3374de327d057340fe2eb0e3b7c63f77660e8f99f099357"): true, + common.HexToHash("0x5b4766c68dc94eec83e16a39c577bea364d6fe9ddb5baeecbbe6eb30f76ef697"): true, + common.HexToHash("0x5856c8936b016ff20b68ee37ca5ae29c282a73bb783c63c308847e4248291e54"): true, + common.HexToHash("0x63e64979d9bafde246701fc47d0ecb53288f6b80f1e8fd8036a3cbfd5cbaca1f"): true, + common.HexToHash("0x7c697ec896b960d0c54b2fbf8abad8fcaa94070e4b6898703622d3f7543b0bc7"): true, + common.HexToHash("0xca29b2fe1915e9826dde675fc87705133c3141f6b733fd78f93e7678f1d7326c"): true, + common.HexToHash("0xf1ef683ebdde47ed71af89f380447f66890551574a0177344c12b6b0b1998336"): true, + common.HexToHash("0x64df756d95da9281dd3fb28f015e5d1b09fee73d242872b7a0cb2b95c53e5e8d"): true, + common.HexToHash("0xf50537fac2d04baf21b794e530f73a9efc7babaa80af8e583177344427532a92"): true, + common.HexToHash("0xcbca2dcbbb0ce425a7130d25c830d72f8e21a0042a2828b2f4ec191dd8d97bac"): true, + common.HexToHash("0x39b86dae8045adf30168d21be8df3a9d4b2f6bafb9475a7c3451f511d501a63d"): true, + common.HexToHash("0x2d1ea45234e1e858cfafd6670f83da6649b868f9f9fc457c5ad9358324e79998"): true, + common.HexToHash("0xe1667067aed2cd18642037f77d9de506dc9bb5d0b446e5cf915aca77576c72a6"): true, + common.HexToHash("0xd4d7ad0f542de3bef080477385f0271e89b544b4ff9207c0a50bae4a9684f88b"): true, + common.HexToHash("0x70d7006340c6b61aed735dffb81d7ff68cfc4a6b926ceb6127c06a5faf14c9f5"): true, + common.HexToHash("0xa518bdeea9762d50b1bc6cc82b0ebbbcb2cf3480bac26348e153a6e5f904416e"): true, + common.HexToHash("0xc0145eeb581fc1f1369c33f9b9dde1c17209a4c7a0e10b4161d00e995ba4bd91"): true, + common.HexToHash("0x2c51bdb25d8f0ec3312df90d230c34749edf89c9f534acb6c7a0015edd0efc21"): true, + common.HexToHash("0x7264181e3787705f1614d1049849c00bbbac8582227d680b29d439e41b46abda"): true, + common.HexToHash("0x7108249b9143bb9509ee11c301f443af099ce98b243fcbf5dd6ee3880b0392c0"): true, + common.HexToHash("0x9f7de3757166a418f8e8929faa5919075f2d32432707c7681122427d627f1910"): true, + common.HexToHash("0xd8fb24a8a9b12bbfa8bf19149f50c3a304855fac4f3bfc3881617c58a8660f6e"): true, + common.HexToHash("0x625e55d69a846322720e7afcd37161af02156c89cba3b45ad6ea4f97bc391c19"): true, + common.HexToHash("0x7f3353cfe81e41de45fa452b35d9f0007d2dc1d3fe5516df5befb43c1d266bdd"): true, + common.HexToHash("0xfdbecbe1ac89c671ea671aff764320cdf068b669a15b5c0b954bc44ddc2e750b"): true, + common.HexToHash("0xa76c396a7478cda6475a55a2fc95deedb6e35046259724599bfae7c1febfc882"): true, + common.HexToHash("0x0a7eb1ba0b37ac8af144e91a48cc65a3b6c5a73b49bb3face9a9fde2bc890600"): true, + common.HexToHash("0x395d1e65a25211816cdd6b34e25d6ad8b15ee490462e3b55afd42f507b2eed16"): true, + common.HexToHash("0x72628e17a79ffdb169012332d5105def79406ddb9e0ee8e46617099498efe183"): true, + common.HexToHash("0x21ffd071b304756d2b367232a7c946cee246e0c2d432be061def6bc23138eb98"): true, + common.HexToHash("0xa7ac84fb9165e8a1a3b9f7f8b0725af1e1ddbb3faf614daaf1996135d3a8495c"): true, + common.HexToHash("0xce9e9ac98fb851ae582caf49e23752cf04bae77c96b47a5eb76db7cda23c81b8"): true, + common.HexToHash("0x8a2aa5d413b6915440f0654a7dcc14a5b433340d67ec2dce8fe41a510e34a6ca"): true, + common.HexToHash("0xd35eb9125b689737b769ee5b2d00e54bc1ded7385a563631a3e4f29f5162b362"): true, + common.HexToHash("0x259b58aafcbd179605fb12de63401e13eb5c8605b6cde66098f09871f337f223"): true, + common.HexToHash("0xf3e32f669c0e5114bb8c4f2235fe6ac7469702b44ccc7654d480c1aceb499421"): true, + common.HexToHash("0x380e3461bcc89d072ebe672e406d2acf937332482896b5fbd4ce12a803d1e1c4"): true, + common.HexToHash("0x40488588c148075b60d1628848bb03da96eeafdb2e156bc06a6caa7619905c83"): true, + common.HexToHash("0xf050e125a30f3c89e5563e522bd592bc97265105fead4617abefa232db576f8a"): true, + common.HexToHash("0xac126441ece73216e0a62a0c9457e524886eace7bfc26043ec3989ecee59435d"): true, + common.HexToHash("0x0088d819e27d6d77475a1f8744ea34b01605ee40df09ce1a81088e706ebbdbcb"): true, + common.HexToHash("0x2c1722521e2dbf8cd13d5efb1979efb87be0a8ecda59abef64dd27e5e3a281ed"): true, + common.HexToHash("0x724b4178945c48163b466de276bdf72871864fac10b85b20eca98001d9f308f0"): true, + common.HexToHash("0xd42ec32e0c9a45d0eb39ad44eafd9ec6f703d5ea3c3aafcc681aa8fc79c74f13"): true, + common.HexToHash("0x82c74d5b47b2c96263b9861539583f9f1073c86b97ac18da4745b3c90d588a27"): true, + common.HexToHash("0xf6b30e78506e7a7730968c2c845d0c72f188ba9b956ea5e9ad8875d0c6dbbdd5"): true, + common.HexToHash("0xddcdb24d23eb2e1f8624ad0c03c11c91b2a9f61d420b95375b3a85a6b046d414"): true, + common.HexToHash("0xc890e736eac516853d3a17bb153f5fce7df6405d8863ee7b8ea7809a20d422b3"): true, + common.HexToHash("0x65a61b4de9a3b755530c57028670fd9fb3aa4404215745add7080b13feafcc1a"): true, + common.HexToHash("0x86b4a3df89561f530f6db9f8f8b3e76476b4216981dde0906162418c0abc9008"): true, + common.HexToHash("0x131d8be33dee3dc8c9029b9025ca3235342d24542b4a3b9b0ccf0653cca8545d"): true, + common.HexToHash("0x76b00be6d8366e5f288ecef35872751f3aa59756aaabb6869bd223efd9b05897"): true, + common.HexToHash("0x247ff8b5a4adab7c7a9b728f0c15fcee5c2d3b722edcf46efc3c649c679c1e9f"): true, + common.HexToHash("0xfc6213395bab6afd2208a276daf633db0406616717cfd65c9ceae790c00b7f52"): true, + common.HexToHash("0x638c826ef6c19f4a66ee76e3da297459b6a0dfaceab64432d030c02c4fd806fc"): true, + common.HexToHash("0x33cd9affa1fc36ad69ad631a36b7c77bd2251367c04c4d24335bbbbd368ceea1"): true, + common.HexToHash("0xb0c80bbf48cc4242949beaf22b6d71200c9f7dede847f33e1deab8be700be412"): true, + common.HexToHash("0xa2476cc89ce036af0c24a2a847d1d3b203ec47b7d3fe9891f684d4dde1d227fa"): true, + common.HexToHash("0x872ada01d7fe0c183dcd4dadc35480e6bff6f3c3da072f41f95846bc852a4e9a"): true, + common.HexToHash("0x11fa257cc3d9cad312ec33efaf81e87b34d9e95c2197255284290c4a90e632cf"): true, + common.HexToHash("0xeceb21b9e0d8c9832afdb1fbda16f2d6e4c800aca354ece73ddb951715b42753"): true, + common.HexToHash("0x2ba9736b3433865bf056af1f5a93c069366cc0f68fbedd9fa5813acce1dddfb0"): true, + common.HexToHash("0x6aedc5d60eaa4d309d555a2d05293e8f3cb21ceadb9a1dbd98c20629e12369ed"): true, + common.HexToHash("0xb8558c822dc87091e046629ff3ac08438547ebbeb57c38df2cafc54cc9892aa2"): true, + common.HexToHash("0x95df447709b62f0d95e8816e8ae189234480608f43dd3e7f6de47994a9f8d92b"): true, + common.HexToHash("0xc3444a751f3df2c4542bb5b81031ceadf7ade1629839ef9d158942710a51670d"): true, + common.HexToHash("0x8f49ddebfb1b621d4ed8d00b9f3b4f859080e2b5e7c5e6ee5b1d9cb986a01215"): true, + common.HexToHash("0x27be7fe4dd018f12b247bd8c8074f84ebd7c1b0217e1fd63d76fc84b25ebe4a9"): true, + common.HexToHash("0x3e309cabaaa116c3dabadb5e0a866fc101fa471ccb0eba6cf6b32697a1d6a3dd"): true, + common.HexToHash("0x6ebfc26912ae1e19a8b0aa6fcf1e3324096a98bd1321ae52549d908f1d644e9d"): true, + common.HexToHash("0x81dd7a93f053c1a78fbbb8062370aa20c1ac9be319e4992c9a64809ee91cb68d"): true, + common.HexToHash("0xcd80e4dd4ae974ed3e0a010a53c62702d54613ea9493c22233682c8d2222e043"): true, + common.HexToHash("0x36dae9a361823e6a30723cc969fb216e8ae23d48326e2989b864acf2bc3e376f"): true, + common.HexToHash("0x1890dd7091534191ffc8a65fde62d820022041522aec35ec566f77ece2b4f2b1"): true, + common.HexToHash("0x352df026f1643784ff12be8782f47fe54a1512e234dff3e8eafcc70279aec521"): true, + common.HexToHash("0x376bbc5fffabf36ac71e31e309c265f77873a62d704d5ddfb1de1f872fc98aee"): true, + common.HexToHash("0xc30e0ba0b6f7542fbab44ca59bc6c59a8329a5c3a3091f0bda065e53abfbb2fc"): true, + common.HexToHash("0xb6cfd610a9e4fb5eed50c8af27d53d2ef4f7c266111c5d9e8dc96445235d4d3c"): true, + common.HexToHash("0x4df230e0df961ad9f910af982966bd1ce22bee8db3ba4b5b59a255411459903a"): true, + common.HexToHash("0xb588098105fb3c08982a9df100f8783b3f9c966c3258fc34346186ace6c76382"): true, + common.HexToHash("0x0321a10494b710264c36659ba20ccae33b789e2853ccbd9d702998fc07f415a2"): true, + common.HexToHash("0xddae4187523e11858e96afa94f57cc9d799dde3dc98a4d29a29b40bf813829f4"): true, + common.HexToHash("0x3b928f33f4ec64914a0293a38bca81db501d7aae2f7968f12e084bbbcf941c4d"): true, + common.HexToHash("0x9b05b29740cd8b5febc24f39b7863f33ae18a4bd3a494b41cefa9bef9fc47fb5"): true, + common.HexToHash("0x0bfa773920ae3d57d9a751c3700e185b936d5055c9ed55d1027261eb93656f51"): true, + common.HexToHash("0xcbe9a8e37915f94002db5e039ce3c9604bb9e087bf05d94e8299d8ec07647ba8"): true, + common.HexToHash("0xbfcc37bbf3102c316b5b2dbff5be4cc3856245560bf0f43ce31f9097e7eb58b8"): true, + common.HexToHash("0xbfc126a136eadfd49c0c09c2fd2905953826fdb23141e786feae1753ae0aa910"): true, + common.HexToHash("0x507ae13073e00f5a7ff6ec4663c1838b2c47f14a31f3654b6eaae86ddd474479"): true, + common.HexToHash("0x72415ccc3a1ee0850443b216e045bbaac56a4d6f12130e2f2d3559bbd4d1079f"): true, + common.HexToHash("0x6f28c86b6175343e6a12da1b250d14000ca619f151a5658895c3e6ce1de5aa00"): true, + common.HexToHash("0x465999e6d7a8e26c383fe62b490e583ea8d361f7761452024222cf9429c72239"): true, + common.HexToHash("0xd061f9f1a43fc24875452b8706d7df6acd2533dc43612bc3e0b1c9be79f44bbe"): true, + common.HexToHash("0xb08275cc47d313ee192d1dc00c2f3feb22a66b8fb7141b49d640bf4550387c4e"): true, + common.HexToHash("0x9d0a9099deb69a5f26a348a00081864a53c5616daffa378488e930fe225732d8"): true, + common.HexToHash("0x0b821beb96f2d499e3632a2d3a43152e615a2eb38eacd6fdfd5701c35c3fbd3e"): true, + common.HexToHash("0x7880a81a457a3c491d167677dbaa4465f318c8a1cafee6aa36522769e8f1ca25"): true, + common.HexToHash("0xd6b15289c04d7b6ae7b3a8276b0b304fb0c2e9324ee13c555710a723cef24b6e"): true, + common.HexToHash("0xb10e78fe74c946281c4929b50fa13fd26558a53d287c091b2878a35ea0d8d256"): true, + common.HexToHash("0xcf384edeca86769bbcd68152f47e6fcdde7a569030dc6812267434b6b99a716f"): true, + common.HexToHash("0x953d6701c8b282d21ac9c2a38be11933ca1f8edd83bb5e7438397229d83540d8"): true, + common.HexToHash("0x5bf900f6979f6b9bfa5277fba4892655755c5f5e44866f08000d97c7f310c8f9"): true, + common.HexToHash("0x93769944a9e30949e2250f9f54a4ba8fc53a177b77b93a4200f7788d3182f0dd"): true, + common.HexToHash("0x9d2789b9bbe7784040352343776a8d028ec350d45cd9da5a8b0aac93aecc5cf0"): true, + common.HexToHash("0x78f7d9a01736426414aab795cf14211c31b588de97dc2e502a67d853c4904d97"): true, + common.HexToHash("0x9c5f32a5993a61468989bb785d2897f142003aa3c959c4b6517433e0fc6a008a"): true, + common.HexToHash("0xba2ef60d2f94c8cd1302ede940040b9bef3e7af358f86490390d0fdda78ac92d"): true, + common.HexToHash("0x2c8cceadd2d748485adf0f6d9bead93829274cd8e26c6b4d1dc3b73edb9f7bc3"): true, + common.HexToHash("0xd65b2c66e53ad6830b7e883f1fc5476c3ebb2f7b976b0ab973a92b97f0de6217"): true, + common.HexToHash("0x09dc895ad6d4dbe5b2d4aaf8d0189cd86d18bc0129c6132a9a9d669ae69a38d9"): true, + common.HexToHash("0x3786696cf0ceec516f4d58dd6bebf90bdf0e19c82391b70a4b36b7428390ac7f"): true, + common.HexToHash("0x5f5ae41a6e6af60bd5fff45aa57b01fe5feb1ab29204e5c760740f3e1788c607"): true, + common.HexToHash("0xc5d96589ae7d8746020fd504db0bc8dc7df62594e42343d5daf77e3eaf68d3cd"): true, + common.HexToHash("0x5f2e7a602cddb30593dd3e447db70e5589212b6136c3b1cb99ebed8710923dbb"): true, + common.HexToHash("0x75b5fcaa2ee9c45748057963d9aac67a0b27c6c336aee4193b9175d006e491c3"): true, + common.HexToHash("0x46d5304f6cfbe60f184a4dc39ebfb01782fefa84f243480fc52107d88a2a04c3"): true, + common.HexToHash("0xc23dee2f413187e4fb5612064139a5ef4332c03a3303ce4e0596ed0334590bda"): true, + common.HexToHash("0x46bd228275015aa4bef7cf0ef902675a0607184819e18ac2403a243c1403a086"): true, + common.HexToHash("0x5f2db78a35b49cbe9b1bad23d3e47903a1aec48dd21fb2853d979023335735ae"): true, + common.HexToHash("0x90a8aed16cdf06598ee419f58601c2dc1bf3fdde0cb36108543c3222e34cd33c"): true, + common.HexToHash("0xc54498d2cd1e4a0044f8bb699f795e931e07b3ad1cde5b861634bf7e3c8df15a"): true, + common.HexToHash("0xd4e3dcf80c9955cca7bd426003dd974d38de1d19b5a981c997ed0877d415d05c"): true, + common.HexToHash("0xc617e2bd7e43d5c4b7c77b8e4f2274f99a3de6607ab9ad9446931d440dd2c485"): true, + common.HexToHash("0x9bcafc5fc99c180113683d6ad0ab361c6c748d21d29a712a8fb03150b9bb5d34"): true, + common.HexToHash("0xe225af597dcf790d364732679b69309e21f0828ba0f745a312b8fda2fc611610"): true, + common.HexToHash("0x3f6b64f71cf34fd32f5476fc1fad12ed9ee6568c268cd0c41211eacd6bf453b8"): true, + common.HexToHash("0xa26c35e4c0006fe9b65021b6b40bcb514f1f7cf4d5da5899f97a2fe9f336eba4"): true, + common.HexToHash("0xb699f2206cd7a872501053fde1a4ce67bd6fabd6ea610b2c66cf745882c5b687"): true, + common.HexToHash("0xa40743a37e6f6540525d663ee72f17b234391ce7149bef3ef4de5e1bdbf06006"): true, + common.HexToHash("0xc222e0e826e8b6606288a7caf13c2e4b87d6807baf443e3dcf6d5ef2aad468e5"): true, + common.HexToHash("0xe96e894a817a3c5287dfeaf886364d295c14f7ec948c08a701a46f319a01516a"): true, + common.HexToHash("0x753c3842c53abb4d109024e8c5438f6ca5f1d99a3c0c2f0fff0c5c3b15d7743d"): true, + common.HexToHash("0xf07ef4071f9c1a370c512d42157c54662a917eee0de702fdd21a39a64689bf68"): true, + common.HexToHash("0xba15b40def398d28c8756b489ed46f0ba521d0d5d78bffb7e575f8fc7ae0120c"): true, + common.HexToHash("0x76d6287b736ae155d1b87a59b94def820435014773eae526018aec9b95eeca2d"): true, + common.HexToHash("0x0e4dca7e666f31e45b37d8cd09af3bb9e197925cfe4049c794f129381def3490"): true, + common.HexToHash("0x5085a90f031cf3f37b553c8332192e018f1be5c1a9d7f82c803ff237aec49d30"): true, + common.HexToHash("0xe4edfb025a22a437ff8ad82cfa7d5256a0f4d8ecef37315fb08e7e0f7b48b392"): true, + common.HexToHash("0x6109bfbd4b9b23b91bebeec7a55568b288442ae4afe3b2a30b3d0e5941355b1c"): true, + common.HexToHash("0x734bc4a6d86234dddb7530f16f5a1aaaab46bb172b8ca045852f7b9974463568"): true, + common.HexToHash("0x307ba7b07ba145922195d4464e484248e09fd7243c9f673886b027c603ab598c"): true, + common.HexToHash("0x4fd23bd8b83ccd109703c719a05d41f53365ed4402115d7a25df9783cd68ffcc"): true, + common.HexToHash("0x5edc83438bed44670189e287e9cfd680508e33084437f14ee2ea56667fa68602"): true, + common.HexToHash("0x26ac5297c47b6279f7006e2cb7b5b4563ae26410b6a38cf0133c4c4e2141ec0d"): true, + common.HexToHash("0x2de4927fca57fffc648264809dafe8d9e1ced62a1d25c2012d0001650c9d14aa"): true, + common.HexToHash("0x62324b4aba471c3a1d821ac85fe844159c02a45dda983572928836d502ba4449"): true, + common.HexToHash("0x63acaff2c2fa47e59e6c614f6842028ae2657aafd484ec661fbe528df9f78971"): true, + common.HexToHash("0x78d797a86f0eeacd474ffda0039003088649e7cc60a54e12243dbbe59c52d942"): true, + common.HexToHash("0x75237feaf54cd961a85e33972e021e51e8919eb0d5742479757f02b2aef3772a"): true, + common.HexToHash("0xb09ce7c1e56365f22d6e65825c0b1a58ebba5db9a6d941a00e1e8dc9f4b41264"): true, + common.HexToHash("0x14f74f482a44dd2407f5500e84a69e75a786eab31a5bb3b769fe3189bfdc56cd"): true, + common.HexToHash("0x1d303fb95717d2a7a575222611f8aa5130d89759181f87c492dbaf4c43d9d521"): true, + common.HexToHash("0x0cd596d1e3a9d2f897a0cdab2f9e8743bbcbbf3493391d1d9bc01f05e89912cb"): true, + common.HexToHash("0x2f515189cb9b923a0d1c073a25a558ebdd4197f18c723e2fc1104a1ba425c71f"): true, + common.HexToHash("0x6ea75b779b9a82fe9d6747b602f5424c6a9c7a899294d762599229ebdb2a9675"): true, + common.HexToHash("0x8991f6ee826d6e1289794631ec8a8f07814828500263c916dc82e5178dc179ab"): true, + common.HexToHash("0x303a70d87846e955a954d19d0e4cd0daa860256a92ceb5bb8051d0594a14469d"): true, + common.HexToHash("0x8e182ce59c48521cdb39c1ede0d721d9a471edbe86c2a2962800ee6170322a61"): true, + common.HexToHash("0xd8afa8d4a53f46d7dcbe40d3f88c61e4ddc37793d7a23391f157d4b62fad453b"): true, + common.HexToHash("0xc3e115a5eb81d12067aa91d25ec6e1d29f801d49273c9bf97518d5b492a4b134"): true, + common.HexToHash("0xe7eaf296643c01a8be5761faa3e9fdc93cc0661ef1c960001a0b3ba893e6539d"): true, + common.HexToHash("0xf38b555f16c260e9656c3d165549b37040b9aef1db07312c67c4a9b81a88b15a"): true, + common.HexToHash("0x79d47715510cee9a6ef7b94ea3af2e5599e195f858945840093dd5df717ff71e"): true, + common.HexToHash("0xfb540f852f6e0bbd42ac39df2a4308de1c5267dfc9b0c1aab04cb09e5a023051"): true, + common.HexToHash("0xe63227aa8482fd5fe02282718581726b3bdfa6b453adce6c0ae39a2c7e141377"): true, + common.HexToHash("0x0ccc402b3c16d4b4be0ee9e4af78a5aa8410d1a0f97a5375699f73f930a6e41a"): true, + common.HexToHash("0xcfca4fdffbb027d99bdbdc6671bcf5694cc667d397a59d54d03736f0668eb252"): true, + common.HexToHash("0x389d2c786dbcd2c3f6d95e2715ac6f155828055935f2393c03208613e3f5f1e2"): true, + common.HexToHash("0xe64b763a5c0bc00949e6b6f898a466128b70208ca3a44c2d672ad23da8c1c7e1"): true, + common.HexToHash("0x544375af7018d3dc5db9046804a7cbabaf97212ab68ce1536dbae763e2d900f9"): true, + common.HexToHash("0xd3a8897b9b920141be0355f130c5df7fb52f34aaedc6ff5c6dce995a4d49d6c4"): true, + common.HexToHash("0xb5154d4cfb20183277d062be0c4cd34a1ac8096968aafb3e7f42a7e3c23a0dad"): true, + common.HexToHash("0x0ae5219a105e250c755b5dde6bffa28d18fc6ae01265224791b9b9e56a9383f0"): true, + common.HexToHash("0x5f33fa836cb29737c74effbcb706f18c1f87501222af852b9df23620994238b0"): true, + common.HexToHash("0xd885b792d274ce9f8fbc8af57735811403ff7fae79e2355063f57e60da023477"): true, + common.HexToHash("0xebd38ff03d3c81ea7a27f7b90c951f80ab359ce5ad36faaf0c3c76a750d242f4"): true, + common.HexToHash("0x09730d33fc9e024249344be642b3b1c3177b4266499dab0f9a2beb0344049a98"): true, + common.HexToHash("0xf2e7cb6e554b21e9197a591f0f8c7d2fc1fab1f30439d3f225cb43c9b6282aed"): true, + common.HexToHash("0x12bdd652dd001a2ff76ce15efe5f4415ec0a998e163b0e62c3b72729c8ed3ef1"): true, + common.HexToHash("0x21cd04f391d61dad2164dbd96d7e1b181dcc2fbe006f263b181c0156cc1ca8c2"): true, + common.HexToHash("0x3ba373bb3814da1c850eaccf0a09f9494374c3d84b7c3ad7fb33a162a8358b7b"): true, + common.HexToHash("0x5ead5569220facd3fd76803077c955516e8fec37c672e44cb587ca672d9f5cc8"): true, + common.HexToHash("0xb849ee70f1495f8f0658f39be3058b5218f24c5310410813fadb722a2d48b1d5"): true, + common.HexToHash("0xdbfc03b2b4f9d9d33773534c2362ea14f6a3c89910f06c3bf77284017b072c70"): true, + common.HexToHash("0xddc3cb335cea941697cb4e083e5aa809dd15ae073bad5a6ac6de3d0311b189b4"): true, + common.HexToHash("0xc28a9e1d1cde9f2772d27b354154cde16d5161762bea811714b012a68fd60618"): true, + common.HexToHash("0xc6671ddb3722076215a544f7be5eb83ba355966b9b6f45741555d0071dfffe43"): true, + common.HexToHash("0xe96d660add5a750fa9ac18bb27a7a00d95671e971e0faad4603c77d0686e1ce6"): true, + common.HexToHash("0x863309ef607e741c221997cf50c2aab3bba4092d5aedd8a63a7e8a653678c672"): true, + common.HexToHash("0xc24c04241dc6c69476a2ef77354c5bf148807001cae0b952a2c0753e90fcc099"): true, + common.HexToHash("0x2c54fdf6ec6f4d350807409554bba646b929ca5d625fbc32118c2e01df297638"): true, + common.HexToHash("0xb5fb1d02d6f26fe70e6d31955a4a50d26b470a7a8ca74bc52fff4161d3ef41b9"): true, + common.HexToHash("0xb4e5c4c5d021f7066e3d4227c456576e0cd94017d19c07eed699a118272030a9"): true, + common.HexToHash("0xaf269768a49e75770b6bddb51c3aa07a7a34aa6c0cbbaaf62047453f0879c68a"): true, + common.HexToHash("0x21561fa640890dbb6a7e70c46aec9c16bac738d4adac6bd99116298d5c666307"): true, + common.HexToHash("0xc7e486b4eac673d026753a0729123678db909ee67a76aa742522d96f72ce9377"): true, + common.HexToHash("0x779b3efa7cdf6720690726515a776c7780651808a4ae227aecd2d0fdf8f58fe6"): true, + common.HexToHash("0x8e1af8bc1438d23bfbaa2e552aaa3ec97051803d32a7593ca98e6945a5539bda"): true, + common.HexToHash("0xfb2d83d9c752c2de4e0c11c56d04802d79a4be58e97346332a53b8454663618e"): true, + common.HexToHash("0x33425a749fecd6709265c90f5ef6073767cabf316ef12f09981ff8ac3e0fef4c"): true, + common.HexToHash("0xae75dcbdd4f87499afa92069965be9d8699f699ce41784bff2f60773a91178ac"): true, + common.HexToHash("0x12eac9543d605bc1b6a917bef99cb6eb52c998a49399a5381e7f0c3dabd02909"): true, + common.HexToHash("0x794299a0768bf5b083758b9ea2e51755dca60854cd64e9aa30dcf85caf07ce90"): true, + common.HexToHash("0xb96df833218c1a98898c631b8f0349a8fb25f35c868d9781f648d3e7ae812ff5"): true, + common.HexToHash("0xb96718b4e0bc770cc2e4b63c5d27f7984d37f28965a35abcb68c3e14f55a0a70"): true, + common.HexToHash("0x11d9c74f8498ec4975a2553faec13b02594b99c1bef06914c3530428e7cb2af7"): true, + common.HexToHash("0xa5cb9e5a8ad18e94f19b61a29ed58040bdc7c5cecaae9c7bf2f6971d38f64afb"): true, + common.HexToHash("0x6918bf755770377156186d224add7b56b84253d4228d98be8e4793b79f1387cb"): true, + common.HexToHash("0x5ab42a71647862efb0ac3ebdf191fe16e563c23a316c1d2bd32b8beddfaf8904"): true, + common.HexToHash("0x613f01e7c9424fe1e01217e80bbe67fc0f5284049faa29e4b24797b1a5a58c50"): true, + common.HexToHash("0x71831b458b40c501581fb2f9565c89d64652ff80111fd27588b621ad454484a9"): true, + common.HexToHash("0x1f497726939f5e6485cd28719f820581b1b75b7016b3098b4b1e6627cd30a4a1"): true, + common.HexToHash("0x0d7c775164d284fb02a3e9314a9bbfc3c752bed348e37b386a74982096a7c4c0"): true, + common.HexToHash("0x266c0535c02422012f436f818baac6c3fcd1e7891df3bf2b58c37fa32bbdc94e"): true, + common.HexToHash("0xf2d3e140ead9c2140356fd604fc52da2bede85fbf39f93c4403307ff679ae70d"): true, + common.HexToHash("0xb37a8efcfddbc8afa0788bca7c4b1b2178fcd8645bc8527dd3cbf77e69c313f9"): true, + common.HexToHash("0xf4246f6e9688cbe1ded1f4fa184618b5eff09466c6e430f8d78b6e91f73493d3"): true, + common.HexToHash("0xdce83b65d6796454ea4f2f2b1fb7cf9b3a893b115b332607a7b476f193d3f5c7"): true, + common.HexToHash("0xe509e8ed3e6b3bda821f863b3a7d4c8088aa588abdd63b9bcc678ce57e6a50f7"): true, + common.HexToHash("0x417551cbefb7cbcfa3a93498986741ceea245d3b754174d368cf9d993fb6b4ca"): true, + common.HexToHash("0x2c6046f312a2380162ee15681e4c2a2a0857b3c5f1e27b0cee54a0acee605dad"): true, + common.HexToHash("0x938cf4f47bfded97bd5c531b04d69f3544dbdcacd0f0baa0f16be75a5e18a608"): true, + common.HexToHash("0x483957fb461e765b0fc0aeb6e0aa4ecf851a721575300230e6fabe5628ab0d93"): true, + common.HexToHash("0xb8c99d0d3dde85f1dbbcc498face81c1c8880bdd573301b74125e06ff11ca88f"): true, + common.HexToHash("0xe56e3a21bc3f01e6fec1c1aedc0f557e18035aa2c2a419d630ed2e52c192f0de"): true, + common.HexToHash("0xd087a80dd2ae0c57edc8998d0a8265dae14b1f3e0bf2ab3466dc46ceb5940d83"): true, + common.HexToHash("0xde0a69969328cfa54b98722cacc3482271078c2336e48551e34dd9c8c9f851a4"): true, + common.HexToHash("0xc48871c772c655d365f2f84fb74a9c20eade3840c9c37294f242def237521d35"): true, + common.HexToHash("0x0f5fd66aaf04b1287309ac81b7e3862c3b4e135a6e9f9915450c937c63bdfe15"): true, + common.HexToHash("0x65288e81e75d7fdff9b4ce79a6eb73f5e3158bab8ad9eae489538bceb140b4fa"): true, + common.HexToHash("0x8b1538c4b488e776c12af7236b61dc1a6e4d8146536320c4b1e3993aecc52350"): true, + common.HexToHash("0x91b973e913f4099448749be8008250b5aab8ed1f8a56c6faad8eb81522a88b72"): true, + common.HexToHash("0x7075c8587304ffe1d2896d635f1f608e7c8c16e77dba328c879adabaf8840fbf"): true, + common.HexToHash("0x70421de38ae597e83777e7a5ab5341d5981f40baab5de3d4bc3f24e5f62aa9f1"): true, + common.HexToHash("0x1058d31ab3b6d4d383407f33efbb33456ee516ef9708896070e5703711b793b4"): true, + common.HexToHash("0xf55888c3dba59fd63ba7ea0070b7a2f187281972f9e5188334d9fc4bcaf538ab"): true, + common.HexToHash("0xfdecbd8ec52bb60a71d56d0e6cc64d1aeaa8209ed67fcd138521a84179e08d6f"): true, + common.HexToHash("0xb69fa2211d4f7ec905a880bedb2b2d73920a235f9f248fa8c9ec739a128b2476"): true, + common.HexToHash("0xe15d1279956d3b1e8095125b9708ee000bf3dd520f2626b99db600a9c04c9c13"): true, + common.HexToHash("0x8037e431ff9da374658a6279a4e09bbc07bc20ecb5ae9861cb109f385c40d864"): true, + common.HexToHash("0x2bab03e2fb5aa9744f49948803eb6e3d74faf46cbb655eab82a6943636ddde22"): true, + common.HexToHash("0xe953825484aed0bf0e3e493d1e71ff70f3ee08e293fca6b6589c567d9fe7c6b6"): true, + common.HexToHash("0x294581934b60729c1150e27ada73c1096d97feae86236c8e3e1a0e1f75794d26"): true, + common.HexToHash("0xaf447283a38a929decdd1b9f18b6aff8151f5fd943398d45f3dd496902af56e0"): true, + common.HexToHash("0x55104fdc6e3303c8403b3fd2e3f5959323642a724c9a37e7205359ebe74d381b"): true, + common.HexToHash("0xa855ab73d57c7db817571c8d376d2c044cf4acb1de30df1c54db5e29ffc76e85"): true, + common.HexToHash("0x8774fe7d765a715cf9cae69868adc8bf8ce2a951a555af39a8b2272096507019"): true, + common.HexToHash("0x08ff5458045a3a78bfd4357f4922f8b3b1025b856d53de60ae931e43fab0f7a4"): true, + common.HexToHash("0xce76afa486d7e117dfb2b9dfe76081963b94027475ecce9d974283f4c12734d4"): true, + common.HexToHash("0xc97aeca590188f1f0fedf068e3316bb5ca09561a5c2bee0688056c094d8bfdfb"): true, + common.HexToHash("0x11e2a3c3fb17a0c620c5f7785ce465147061aaa3589c4a1d39b9781cea1217c2"): true, + common.HexToHash("0xce59c9cefcf16fd7f60e40179f5f4ef5f2ce9012ab3b7323525d42fc312c86a7"): true, + common.HexToHash("0xbf04b5fa559a5633be30bd702cb7220c99bdcf67c7112adb2582795e3645f2e6"): true, + common.HexToHash("0xc7ee849a24ed719abc9db698c9d9aa91eb7404032c8b11756cad67b26fd0a886"): true, + common.HexToHash("0xbe0571ace1ee23d679bf6f5d0740b60daac278d07caa22d21c992e368131f9b5"): true, + common.HexToHash("0xa0b555e534dfd6c874ddb7431b5886b64f5916bceebe9acab2fafd1ed7fc362d"): true, + common.HexToHash("0x2c82dd88342aa61416bd589a7422ca8457bb642a68f2eabb886db4030c92314d"): true, + common.HexToHash("0xba72cf3aff9940608c3a3ee2363b0756082128066806263f9acc6d13c83c6549"): true, + common.HexToHash("0xedb1ab7e97cd6510b9eee7339da503a01fe95da44fe4ed50cfe01d39b131e3d7"): true, + common.HexToHash("0xea512a6f9bdc588b0c6478f6f431dd5a47207b53736c24f23a9993177dd78d08"): true, + common.HexToHash("0x85f977a700dfeef5c38ecfc79881859ce466c596f868de28be96d083cc74f734"): true, + common.HexToHash("0x20a21b31435a4b80ed2ef3e921755f93f1f2754978c2436b68fa8314b8a17dc9"): true, + common.HexToHash("0xf245ea6fa2c7792c1491c5546cc9021a88ee9896d26a87d2acdbb19c64d52513"): true, + common.HexToHash("0x5827b7cd8e8fd99fb45814d7374dbaff2484a9427d931b17a5d24f0004d74d7d"): true, + common.HexToHash("0x579813d77ad4b123d7942306aa262016c7b040177be631d0a9ed00e140e40536"): true, + common.HexToHash("0xfe432dd8b5e91cc40d69684fdaa10f2cb77930de6602d4ff023c26c538888414"): true, + common.HexToHash("0xf4bca9703f09c6c7f3197106f6526f75d5051e281bc511a9b7039e0bad4fcdb0"): true, + common.HexToHash("0x618d873a93aa835b1cd7337e28b8f2df4b34c5b74228fbae9ab733ddcfe55557"): true, + common.HexToHash("0x86f5bdcdaf99fd82e265ba2e6354ad46a27d959c9273eef005bf76b5de0638e4"): true, + common.HexToHash("0x526bbcece49f10e52fb329d7150dd4827a33f04c90da92765fcdc11bc0375ba3"): true, + common.HexToHash("0x8b812b641b23f463e8144c0aa4bae25ed636292cb7ffeeaa7cb6d12edceaea2e"): true, + common.HexToHash("0x6937997631cf3c812ff38e40e6d9a5be8b99cd0e1efd690b5e2d38c7849b1928"): true, + common.HexToHash("0x228e9a8b2d4c827c78a7a82b3d440261d4953ecaf0f639e0c693f85a57b53fb4"): true, + common.HexToHash("0x2ac495ec5c698daf23b263bf2c8d7dc203d859b2d0dee76c02a2c34088b31be9"): true, + common.HexToHash("0x7be62196fcdb04e94735bed6e1fb9453f1e79dcfc9d5393db381af8ae817f318"): true, + common.HexToHash("0x33e83563685a7497923c2df92758c2c8a6cc6dfb69c3479048b4f03b09d56819"): true, + common.HexToHash("0x2148255deac06e28cab360c4db2beb9b3fd326d8167c44abf7d9e1deb49b34b9"): true, + common.HexToHash("0x1b2e09d778a4c2646816149cb523eae838b969f7ab5d53913fb05269e5a1d67f"): true, + common.HexToHash("0x2f45cd21a9e7bc96b98e7f53bff80ebec3bf80c53566b71a4eec499c6d9d70b6"): true, + common.HexToHash("0x613bbab3eda38be385b7665d2d029ea7b0ffab76e8ef44bf865c7aadbb011345"): true, + common.HexToHash("0x2b199353b6001201a2d207f498a11ec6212d746498d826abc7c8e0fc20448570"): true, + common.HexToHash("0xf958bdfea9f6aed03925acd791e298d563606069f0b5988f28a7525fb0d7a898"): true, + common.HexToHash("0x24999e9b3dc48555c09fe7ba42f4cc8291ec8e779a3a98213c13ff48d6aebee0"): true, + common.HexToHash("0xa42abe82ef313f6e6655f8f04a5a617417043db118a1b04b50fe77f3808ef193"): true, + common.HexToHash("0xa3081c5e08f8975179a72f81f7e8ad65cf79ee287fa7b30f8367b6b037c295cf"): true, + common.HexToHash("0xb3811e99bf5c3e54d80bd7323cb8b5cebc42188cd967ff9c51bfa2359dd7a0b9"): true, + common.HexToHash("0x56980a071d64f461c42dc95d20ac264d6a578355654a732dd5098fda0b2697ff"): true, + common.HexToHash("0x7ec7963c7a1b8b004d08f63671a6278872cd2a68efcf9fee79f3df5046e7fc31"): true, + common.HexToHash("0x16b390ad75ee25cd3ced13f6ef6de14cad999e4d13b29e3819afec29b0afce09"): true, + common.HexToHash("0xf9934e39687bc48c6048735bb9801fb185ea9e6480f3b1f2f7a15cb1293ff253"): true, + common.HexToHash("0x5ca0f8d47eea7fa7aad5b2b36ebf8b4d349c038d128b46c7f5194f1007db5c86"): true, + common.HexToHash("0xb7baaeaf9b0d23589e00d37792b87df9d1e22f5a5fc4da79ad556e76803466b9"): true, + common.HexToHash("0x69e78faa9acb0fef47a05423438f015ad8c306ac871ab040d78723bf219f0526"): true, + common.HexToHash("0xcbc66f752e08eb66cddab9301f6b34aa7281df3045960f44e8ccaf9e8373808f"): true, + common.HexToHash("0xb6812f8209ce8c25aa1edb0582aad3b84ecb88dade651a1bf0c3716810c0e9f8"): true, + common.HexToHash("0xc97d17afa0281e8eeec9a1307fecb245f2356f5d92e9b74daf67690fc73c32bb"): true, + common.HexToHash("0x2412cf18e2f426a4e7fa1a3a370f4b981870e90447296518fdcdee144862ead3"): true, + common.HexToHash("0x65b66e2db362b2607e9b79afd2b4b58ea18de91768226d8f9ef3fd3a8bcd437a"): true, + common.HexToHash("0xb411432b15ef5ade38eb9f5e49070c3f436e34265e8de159e2ad20cb198ad26a"): true, + common.HexToHash("0x8dfdb6e8f8411eca383b5575211c17e3fbefefed9ff83bc5f5b39cb540241938"): true, + common.HexToHash("0xaea98cbc67103f6aba019cab7c1e597cee4b581517f35da4b23c802cbe001a10"): true, + common.HexToHash("0x79f179964ad55b5efe1b98c0c0a97c05eb82b9cfef1d7ede7d08377ee8d4771b"): true, + common.HexToHash("0xc3261d67c7dc3ea621a2f1ed73011d1329818aa9eb99e962894e584421438516"): true, + common.HexToHash("0x2bad1aa7540abf9e5c81a0e3d2912272741e6f56002c01552a2f23905d9ec887"): true, + common.HexToHash("0x048951eadbc2b6c631ecd93fe82f6ef5bb4cf380731d2faa32dfbbc332ea7cd3"): true, + common.HexToHash("0xbbf7463696eec03d6bfda16cbadf7447c6a0d8e0310c0b50dd26491a990dc6a6"): true, + common.HexToHash("0x73518808e388dcb3a645b561e9d344a53d31d38838a141f359c24cbdca542e37"): true, + common.HexToHash("0x18b9ecc1616222f17d7fd1055998723aeb268fe06240029e8cc2a5de5d3811ee"): true, + common.HexToHash("0xfed4c3eb63ee6160514a5ea05131207bae677d7b287f401d9ac6e0ce78a85862"): true, + common.HexToHash("0x81c6313c7cd794210830533254314d19943623fbd5083cf51f1d35f49cc3e008"): true, + common.HexToHash("0x3408feafc49ac63fad0b217326f6ac81ab4bf08ef24c079acb909468b736417f"): true, + common.HexToHash("0x9a579b4ad69da19f98b9fee4517935b16e524ec3b1b7d06d962ce461da7e3139"): true, + common.HexToHash("0x35a5b097ddf76fa306d069ea79f6112f3d192e0ceb0eab13805f718a25d79407"): true, + common.HexToHash("0xe9e11175a31dd72ce31053d54b7c78957f44c25df6c9117d1311b402c2a5ad34"): true, + common.HexToHash("0x23fabb5e877ba2b211cffe378082b730fd21ee54d397f32716c2f8c3a54741df"): true, + common.HexToHash("0xa2502fc3620dbe7203d71e0b5ea6dd39342af61ac536811c011d8ad832cfd2df"): true, + common.HexToHash("0xaa8960c0e598b73f216daed750370f2e1760050207bd8d2f45197099e2195ff0"): true, + common.HexToHash("0x9f8a2f50b0fad0c5976e6f06d7ea6631db1c30ed9fa336e84cd20227225d955d"): true, + common.HexToHash("0x9654e7cbd7d12536618fe359b6602a011bde9d603cd3c5615874887ff60650c7"): true, + common.HexToHash("0x27cfa000610ae3a8ec1659d07add7aa041615569369b6a6b923c2741f3afc2b5"): true, + common.HexToHash("0xf57aa62d65dcdc1888806432a50f774e77f9cc53921e77d5056adee6919634b7"): true, + common.HexToHash("0xb67027bf962417ffd33ad04ca3da8188920d4fe6a8d57fe73de9df0ce3ebee5f"): true, + common.HexToHash("0x7191725256e826a07f5c3395cbb192adfcd0a799b5777582edd8c1eee83d904b"): true, + common.HexToHash("0xd7f6a47f397dfbe6f973e2056a2deba7004b6f54c4a7e6acf08c8b7d23d3fcb8"): true, + common.HexToHash("0xd2ce6c56757d79e84a0fd2d56deeb02567695aa54bfa316fccb4e50141124f10"): true, + common.HexToHash("0xa884f7228f65affe02abc0d38f99d00904bf84aea49459c3106741c54def27fd"): true, + common.HexToHash("0x7d66b8d7b945b9fcf2a3e77fedbfb6306001e1abebc608a95636e1e83b60ddba"): true, + common.HexToHash("0x21883c4a9f4398db4763c864d110b02d7e121977f60e628e9421eb9c43f673ec"): true, + common.HexToHash("0x82b618eb3770ccb8b6e5dad2b92262714b3c15b62d31041df2dffdf1246b613a"): true, + common.HexToHash("0x70354f3c8a7e87ae0a099e5a671f546b94fa26a7249f6ca92e1dc4a552cf8658"): true, + common.HexToHash("0x8c569df83f3f05cd0a5a89435c2fd0280b838002daa0a8f0a714d21bd41b406e"): true, + common.HexToHash("0x1fc7572b6bad2c63068e42a719f26e1a869efcf4e73d8bb91f1b30052d0e9314"): true, + common.HexToHash("0x5836e08b859468458086b5a9c0aa17798c90342b421afef1a012362168925a4e"): true, + common.HexToHash("0xe8265ac727741c83b5f4acf6fedb26e319e7a94a50bc05f2538b1ea45efb7411"): true, + common.HexToHash("0xfd50d18d526226991415cbd6d96548f0f649b720f9cd9abed73c5a05c12cda98"): true, + common.HexToHash("0xb140eb4953e3b4c64b72a9cf8e2b8e100b55d8aaf334823e15112d1653cc211a"): true, + common.HexToHash("0xf99ba1b22d2aa0e3c4ab362c4de4cc308cefba788bc70d9656347f4ba5bad128"): true, + common.HexToHash("0x2cea0e07a3ee12d914c92d1d744ada01bbd9952ce04914854152a244ae14c242"): true, + common.HexToHash("0xaa7d67c7df79387bbd2b9bf36ef25edbf6809782f46e9ad0e4157074edf39e1c"): true, + common.HexToHash("0x911346747c36bbb349a0aed841f08b2c3c353b0f3db4d11d7066a1792038e84d"): true, + common.HexToHash("0xe46771c2c164636a969518f766487846068db042d7d53d4db4c4496e89168ab4"): true, + common.HexToHash("0x935c15b0c60363a730eee098e3a22e49b77868ecdd1c8dd8ce565317005c8fa9"): true, + common.HexToHash("0x858ca920088516b9c8a5203c90bded1634511495df19c09672c2a33360d109a7"): true, + common.HexToHash("0xc913c4fa512b4fd18b4e5f79108e941114630dfcdfa33f93cb08fc0158f07e7f"): true, + common.HexToHash("0xe7111e3affe91b5ab50b87d72dfa83e79f5ef0a0db3d25c877e7cdc14fbf2da0"): true, + common.HexToHash("0x62933ac4554cb3f2e68b3d8aaf602fc1c750e02cbfc8b205c7e39e3d0a13b3a6"): true, + common.HexToHash("0x52a295cccfa665bfba52ee349fccd3cce59c4462cc1aa8ef5f11c4b7bdab2d72"): true, + common.HexToHash("0x2c08cb47e65704abb8b29ca108bfb169c7f84d8880b0f62c3a2a678bfb5ac7ed"): true, + common.HexToHash("0x6ae545c033a7901a7dad5acbd0c6481c6bb34bfed65dae83a8d698256edeb62f"): true, + common.HexToHash("0x29f16eb1d9d5ea2a2e70c1d0b18db593aa4e5260aa5a95144a97003e5e16f8f4"): true, + common.HexToHash("0x7a6ace53ce4e14331ebeeccbce15e4ec0331e19b62356e3d482a1c293981e05e"): true, + common.HexToHash("0xd381692b52cc75a236ae7d9f2e2154860ad7e7e70fff4c402a28644680befa22"): true, + common.HexToHash("0x8f7b1be9aa67d498e51f504dc9a430093ef8ec201900ba7ef3aefdf024bb6f24"): true, + common.HexToHash("0x35b9d3a1e14ac59ce9fd358d72b34da5dfefba9bc471a15ba25b1c2c895c8491"): true, + common.HexToHash("0xfef843e0edc410144d517c16c88424fbb4aa7c7ec7be666e93785b8fc76700eb"): true, + common.HexToHash("0x23034171e5ef4d0ad05c784ba34c252c5508e480223f1d019a1b6b5a3a2cabfd"): true, + common.HexToHash("0x36ae50563f7e7615366871c22ceee8d8c654376a977d9a723a3a7becf1a7f22e"): true, + common.HexToHash("0x336a2512fe72ad12de5bd65cab0903d4b4035e002f08abf45ae3a8100e6debbf"): true, + common.HexToHash("0x920bf4b44f90594a652a606fca87bea73dbd47bc5c0e48b05b26d68163495200"): true, + common.HexToHash("0x87cf346c5232a00f976138ed14f69a1a25580e7e5dbb8314648e27fcd6bbecfe"): true, + common.HexToHash("0x03bee1a2e1804d230bab03f07e2c2551cbdd878fafd215e54137cf28995ba303"): true, + common.HexToHash("0x17763143c7cff81d31eb77559b0db4aa72446afa012b8edd14fabee3339dd39e"): true, + common.HexToHash("0xc44a8d69f802e42d39601c4192c0ff2ebafbdc940f820623751df610cf1d0c72"): true, + common.HexToHash("0xa66413b978c5a115b07a54efc774e3f979e343d05d063011bbbf154b370033da"): true, + common.HexToHash("0xcc99cd522b9404167580ca33502b8a2a871a935f7e9cfc0dbfc449d8921a7935"): true, + common.HexToHash("0xd52d79fc590f0c1189ba7937ee63b217ef117b5e7d198a2ab0a5867606f10dad"): true, + common.HexToHash("0x8eb34be17e341aac6cb173d86aa9c0402082a97ae32787f7cf477e9e8631b328"): true, + common.HexToHash("0x446b6c58854f3fed9eb79369e749bd31631a4a0c863d75d62ea8b6fdd9d58da6"): true, + common.HexToHash("0x143fa17127e238f82e1f889aafecff8ea99317f4e89d05df3b5f82a399b24e60"): true, + common.HexToHash("0xc598274034da6198a51904c89ee5608f840dc33ec030fcdf43439346686ad0bb"): true, + common.HexToHash("0xd3d0c89a37bba08633cb26f447c4ca9b4787bb486c708af9af3b927a232b0d16"): true, + common.HexToHash("0x3ae950f02b9dced6e735153383f224d7d09d08f9137d110b766b44b899a290be"): true, + common.HexToHash("0x987bef480c56abeefd6f4b15b0d8fa0d255c6151aa3414b8f9e385f0bf400b26"): true, + common.HexToHash("0xb2b77f8c80dd47ba9a989a6b455a59812458e15fa10d1ed59748f8ed8acf5732"): true, + common.HexToHash("0xd1ec119463c1619ef855c046360e225e6a1f7d7ebb2ae30919d4ec471dd5b9a2"): true, + common.HexToHash("0x85ec43f70960ca169ee3b0946ac757d3059e99025907af58378d24521f655247"): true, + common.HexToHash("0x3faf4a8c6cf77b95f397907d6948d3e0efb41e76281620be1522739da04beae4"): true, + common.HexToHash("0xa6e0fadfc5e97a094aaeac6d3377220175ca092f8bcfa559315dd4a48eb1b8d2"): true, + common.HexToHash("0xb20fdb7f91333616063878908a8decadc188bc314489d15fca699b0386f7d69d"): true, + common.HexToHash("0xf6860b8a8cf05ef0c6a7a85b46120be1ad1cc0dba92778a3af3b184446eec827"): true, + common.HexToHash("0x045800d3ddb9a62dfc26842eab962dc3b3e91df088432608518bfda9557e9414"): true, + common.HexToHash("0x5a4017ec3f4cff3fa6cbf10a8d24152b941a855b96ba178d0e237dc90ca3ca81"): true, + common.HexToHash("0x77016e7b073ea74d066ad632876e43086ffe4e7485f99e8ad94b6688a631a83d"): true, + common.HexToHash("0xb8a8da358f521ea3ecdb1c4266cb180b4328582c68ccdae818520d91e73d609d"): true, + common.HexToHash("0xaf39760ba17a42694197a47b61a20833bcbaf95cd0fafe4e700599296599b2b6"): true, + common.HexToHash("0x458c20903fe33a92db2876e091021b226bb41aecfbb3db132d29cae28da293d3"): true, + common.HexToHash("0xc633038c2a22f521fc1caa91725270c8547c035a1d71c7237a8b9053a3b13075"): true, + common.HexToHash("0x3603969cc144ec192cba6a37299e76e2e62e2958b269ad612e425ad49df576f5"): true, + common.HexToHash("0xc93fc4d13ba41fa00f01c74581ae5d901949edb4f381e872d6258973408e7bab"): true, + common.HexToHash("0x925d0c607281d2e40c05492241388e1e808243e7849b53e9ab10256be6acdc19"): true, + common.HexToHash("0x752c7fd1f257e8df08ab96cd8a30b9ef9069582afb5db8536ab0c96ebbde1422"): true, + common.HexToHash("0x464fe95171434c7ad5e483f22f934117a1d1fe9a2c720aebf6ba0968c19e7490"): true, + common.HexToHash("0xdee860a922362f546f5fbeef45584349a1168242767fa198b24f370fae4cdd05"): true, + common.HexToHash("0xd8e28dca4315b50a499f8c0689aabffe49d86fb894da14d69bbf99943d7ca6f0"): true, + common.HexToHash("0x3fb648788b403edf2df0fbde93a142d522ecca05178399a1a5d175d69b7c3b01"): true, + common.HexToHash("0x3a15b6059cb833e1deda500ec69cdeecd218eb5d440265866758b39d69d8dfb3"): true, + common.HexToHash("0xf796c23b30745d960b69193b27028f04d5e60d2a1dc3672187f49270ca4fba55"): true, + common.HexToHash("0x5385fbe30703cdcea895a8b5a9676d6b5f54933d746dd9928f4399c488180914"): true, + common.HexToHash("0x87a10a1cb0c248fc4ade30b2b6a6c4c0cb533cc9638d5d43997224c48adee9a4"): true, + common.HexToHash("0xce83b02aba5fca96d0403a157dd2b48b43295e1bec0b5302c6c79f923fac43c8"): true, + common.HexToHash("0x7a207cf44540fb2de13c1c8469a65666deff1be9b9d991a68a5f4e34bed8ffa8"): true, + common.HexToHash("0x3a44f21533dfd4d61330abb7cea9ddc721a7eb781cf1fb6e6f0aa8444e6184c4"): true, + common.HexToHash("0x314fbc4afb13c898ff823de9e47968cb0312b5dfe39750d082911a4e7450a72a"): true, + common.HexToHash("0xd616cbeb7cf7fc39865ecd3af41d20d56ea21352b128797e4a05f064ce2d5c27"): true, + common.HexToHash("0xa1219709aa4e203f63d87954d6b150340228bde5e23d8072af4a909236e01bbf"): true, + common.HexToHash("0x3a5d8e308b89171cb58fc179dd981fa8961b9ff5fc0e3ef91a6b98f0263f6760"): true, + common.HexToHash("0xc36b29abcd83274d8a9f00d579156e96c7b7efe15231430ed86815eac00b1cae"): true, + common.HexToHash("0xd571f92d53083c8463d14cf6ae3467e7ffdb53d652570e48dc2808b4682cbcfe"): true, + common.HexToHash("0xa09bfed5b20ccde6de88a60b83fae67923ecf4149f0451ffb5b84ea74ed3695d"): true, + common.HexToHash("0x6c3e79d820f57d3bed96f2f547da00887533828db7ef400300cc57f9d7a7f072"): true, + common.HexToHash("0xf3d2701b1d7a28bb840072952c2fffb625b8c0fe225e9bf6995c44f2b0b253f7"): true, + common.HexToHash("0x600cb67560a922e3f83ba6060bc097a16194eb2f6696c1f7ba8ec6d729500d67"): true, + common.HexToHash("0xc1881e0188e9a093b2fe25638558dc43a3e997dfac7ea39993d10b755bac1c30"): true, + common.HexToHash("0x3c835c9403b9662c24d641feb0324c941422e4a20d645b9070e817ed1fcf9cf8"): true, + common.HexToHash("0xcc98278a3b686dea00bad677ae30be24979ae4616ea1bd3a22b30772d94b4122"): true, + common.HexToHash("0xca655ac16d45ea429eda731fa478d6466d104028dfe4d06c007525f59e526f9d"): true, + common.HexToHash("0x43c570745739cb1b457129c0596ed242460e80da3efac0c26ca14829af5f085f"): true, + common.HexToHash("0xcdda6000481559cb7bf55acfa8fa5889318cbec6cda8639a96ff9f21b1688976"): true, + common.HexToHash("0x321342d15a3231a67494471b6c2605ade5b91c0c9d8ac6a1263d854ea5498537"): true, + common.HexToHash("0xa287bc37051e75463af15d640bebd38234beafb8fc6fc37e4a66e2f4b9152aa8"): true, + common.HexToHash("0x821ef7183d650b3bede12830106250f4bab5043c58f0112a11032429678edee3"): true, + common.HexToHash("0x28904e951856f67d6921240781344af30946fdb15baf8da2baee1930eeb48fcf"): true, + common.HexToHash("0x8201f49444517d99baa2c9201f4f2ef6ba4c5aa0b5de38372c4667474ca27fc5"): true, + common.HexToHash("0xc6c979c1a6d83bae038d19a3a05201833ad1c5ec54d0b6708a32d6397319fcd2"): true, + common.HexToHash("0x1523b56c5353846b51a414725111f1b88c0b795dbfdb2e94b2d46ee0cb852a00"): true, + common.HexToHash("0x55a087f00ef9dd0312ab3ce416e63d777c2b88a9e43e74250b05c59448631f71"): true, + common.HexToHash("0x5000bb6f5e5af38ee85c1688d2ee060a17f3f28617c48dc2cde4378d42b59e1a"): true, + common.HexToHash("0x45be2702d70aa7239a61f0e47130fca87ba0bb5d4605165c38a6a51a6c7d21c4"): true, + common.HexToHash("0x7c6f03d67b241a1636bc66774ce34d01cde1395928236cc504592918c6b28ec9"): true, + common.HexToHash("0x1ed08ec31757f49169d5f64c6815d9f4f917293013a74f229c302c30d9121210"): true, + common.HexToHash("0x353dcb1e4ced4416b648f55012ac58684b20c9186f22afbf9adc18b027aaffb2"): true, + common.HexToHash("0x6ccbbca280719b04a8817dbb4820b1d7900b085e3cab802305c5f5da6afdda3e"): true, + common.HexToHash("0x45fba40d49656871065da7161c04595b2329db9a446bf3c1a90dcb6801f393be"): true, + common.HexToHash("0xe36c19d2f7fd76c5fce106569cd828405958abca75f54642c788b1e9726fecee"): true, + common.HexToHash("0x6c2c82c0223074e405bea53669c1e6000c590edb3af88ba22c9626f553c1cc05"): true, + common.HexToHash("0xc91911a3911e8ccc74781f14f01f4062e769c5c96587057d5d097110f4fc5a1a"): true, + common.HexToHash("0x35b0bfbc0b39fa00b653168f1b99a90dfc45df1bb370196b769496ee6fe18f87"): true, + common.HexToHash("0x83f000821962d5c263ded9b4bbd1c8649de364565ae9121c3888718b554dfefc"): true, + common.HexToHash("0x6027b94f77d0ec6ddf01a58982c106b7536eb5808646cbbcc8e4dd77677cd97b"): true, + common.HexToHash("0x851151d536115acea21d2f89dff04cc94a9ba4208d389d96679d2cd3fe78d631"): true, + common.HexToHash("0xcbef618a2b6ca76229f74352a9489a85518e8fb906d40f1e3daf086db9f00f94"): true, + common.HexToHash("0x35614b2f8d6e1aac7dcf2a85295b72dbb289d82ca87953c626d73401fda3b127"): true, + common.HexToHash("0xf75ab2a007a4021715dea90090f74935031975a8f9ea3b8fb36f3e51b976ffcf"): true, + common.HexToHash("0x398ae46ecdb42d4b2dcf26376d3497f373be702648aec949f6f3b92c1910d680"): true, + common.HexToHash("0x0a9be97d6a1a32b3e017687bab3964a7bcd515344e3aae4a6ddf6c2756afe169"): true, + common.HexToHash("0x39a0261089a8e0832b352a6b9272bf8d2ae1f32fdcef974e9134b82dc7d46687"): true, + common.HexToHash("0x1c535ae154669080b6d51e646acb23f823531319f6e51ffe0aa334046eed7b00"): true, + common.HexToHash("0xe85189227589b931b89fa7268ddfc1eb6f69332bafd75494e7a4217603786a0a"): true, + common.HexToHash("0x1979af58b0ce6b2516df5066667065d5b2bacc1bd18e17c48a817f519fd53164"): true, + common.HexToHash("0x76a680ed0a1ad6292a01b4a6a41a0d51b060769ae58e55af14a128765c32a141"): true, + common.HexToHash("0x8f18bf5c6af8be9953da0fea34d4bf684615108198466edd65afe8fd69601a8b"): true, + common.HexToHash("0x42fd7ec209b15d8f94ac877d4ef0301bef565cced8193e539b67f56e68eedfc4"): true, + common.HexToHash("0x4551581dfa38adf94e40df7aa02e5b97306dd52c75724ea9ec47a56d1bd3df3d"): true, + common.HexToHash("0x6b2536b5beb617b9e94dce681fe6b718af1a41a6d2cb84934437d300ac4990e4"): true, + common.HexToHash("0x57a6a3a14ee77bbce9074ddd937d701f3d55d9b01a469f9674d4804fb2000a3b"): true, + common.HexToHash("0xe1d8c22819beeeec93ac2b7d1d6fcf43a743590268bbf3fb4180d3ae70fa6495"): true, + common.HexToHash("0xa8fdb1f6ee027d3e97db1dfb08539d18a6ded652d6e3344e107ce21043744c7f"): true, + common.HexToHash("0x21c19bc2d94b5de798186b7550e33ddbe9404ca9e9905ea3b0002fe2d3e3afdb"): true, + common.HexToHash("0x748ed1834fc28196502e29293e7f99adbf6bbfba2426c5fed91d84cfcf42ce42"): true, + common.HexToHash("0xd237751b28fa90217addf54ccb1c896fa4d47f4d344b7ef7c5eae5c4f36c5c40"): true, + common.HexToHash("0xc829f67caa27f4892d0e1f80d65198f1b54c105fbfc04b8485850894e8cef400"): true, + common.HexToHash("0x683cbc84fb4f81deeb59e10c5d3b9d473b66423ca8f0b874a0ea74ac5faaaef0"): true, + common.HexToHash("0x25e722194f0bced3ec53a757d20d8cc1896991a26d0c7864bd313467dc3754a1"): true, + common.HexToHash("0x944654c991cb7d75d29b6e28ae4f90ecdeec660f8e33dced052fdea567d26ebd"): true, + common.HexToHash("0x52c4ab46c172f98f31ff1b31929f8a6ffd4d87c58b936d9f76984e8776e0c810"): true, + common.HexToHash("0x9ce5073401eeaa92174384c5288c1509b540409c27b26f07a4e6def8be5b7ab2"): true, + common.HexToHash("0xceea69e4aa47ef15cd005d8a44399f2a14a48a1c9a27bbafb27c1454978b7c6d"): true, + common.HexToHash("0x75975c9e5697b2a3011a1d004aabe8735a51bd368b9daeba080a3b743ca57d75"): true, + common.HexToHash("0x27ee9e4df2189915f32345d2e1ef180d82a149a3a0990aafc85c776fe0fcb64e"): true, + common.HexToHash("0xffe4fa932393b7044fc2ca875b5dbaee9bf902b86a32774b0031c17c8bc67ae9"): true, + common.HexToHash("0x23c6fb9822e70c73e3aa8e986263ffcef20a3abcbbb5d52173a7a37aae1d40b9"): true, + common.HexToHash("0xc8bf79941a4df25026b2606a3150c36200972f3e9d078dffaa698d690a6d94d4"): true, + common.HexToHash("0x2539db0eb01feca2737d5ea519f663b5600b95be50d2587bf503c2771af54c4f"): true, + common.HexToHash("0x42c6a18acfa538ab0a43823db2533fbf2e31c18e6d0027ba8467646a832516a1"): true, + common.HexToHash("0x461f46fa4294ed220c48abec60222fae4fadb4e0c285cb74808d5813906708bf"): true, + common.HexToHash("0xe8c81b72b9db6b1972bd482c223ffbce0fef009b8f1f716dfb5225a8f0fe09d8"): true, + common.HexToHash("0x65914f5a298dc668e9355974f9555c9b3f1b345889157b51dc8a515490eb07e5"): true, + common.HexToHash("0x378cad6abf2dcbe6ffe7a24b2434d05ce6dfdd68d8d60ed785d3431a005d5e16"): true, + common.HexToHash("0xbe12cc3af031bd3dc9a370b5ec756f56d8edb81d8d5233a334cd9cc88bce253a"): true, + common.HexToHash("0x6c905cedeaf9fc68ed3818f049318d0c6ae1daa2d26acf7937c6d03ba00048b4"): true, + common.HexToHash("0x93fb1889fe2db67f76af85185e4739f9e5845e32b2840ce3a439e0e1dd701a38"): true, + common.HexToHash("0xfba30daa4769086d2c0e92a2c34dabca2fc2551eeda8f32fa66497abd194a913"): true, + common.HexToHash("0xbb4cf22b89acb1c2968c9f1f88e11c078d1ffb178b2795caec0f50fc7f5424f0"): true, + common.HexToHash("0xf71650d9160af958a9f46e50148872fe5f6c88717276e5e8912f6ead5ffb71e3"): true, + common.HexToHash("0xeb12acc09750f6367366979efdae14d685774da5906bf56f23d99c053877c024"): true, + common.HexToHash("0x34d679cc3f5637708b451794c95adbb30e8da61a17c2a25f88829ac5e9530780"): true, + common.HexToHash("0x1222e96c850a2151c23d9c62046406556a2fb00f28893135a69dedd9fbf5217d"): true, + common.HexToHash("0x7f25e318fffba67b8f2ef7e79bd49bdab36b966b9478568e8e9bfdbb62cf22ec"): true, + common.HexToHash("0x5169393268a486e4827df583786321f2888276a0039a01d47bc1bb92735453cd"): true, + common.HexToHash("0x12606bb02012dc9138ae76067c019c2c11c029d02844a2dad2de3cd6cd813097"): true, + common.HexToHash("0xc3ce2436dff2f65a96e4eaa0eb5cffd45f1a4b6caf204176b3bc6a6635f67537"): true, + common.HexToHash("0xd46929e640a1794422b42008f89bbf3ca1c87d589c5a01f6e470119f1d25d3a3"): true, + common.HexToHash("0x4e48eba5597f00e30609727064b32018f14ba404e99cf8faa81613226be357f1"): true, + common.HexToHash("0x69945b1b8eea94fa08488018234409ae030ea0faf04205caa6dc3536b06e2de1"): true, + common.HexToHash("0xf6d5b02e0f3d86528d1f7dad59dbef0dc873d3b4db8fbb86da61b29fd22e947c"): true, + common.HexToHash("0x54c3fb99999ec649584546d065a4e7647521eaa05eba0279d607bbcd150c9e8c"): true, + common.HexToHash("0x0796d53379f8fbdf454af2ae698048163fec162d7e9e6e67934ad23bd8d7a92b"): true, + common.HexToHash("0x0ba627ee17e7b051772b8d1e7d8a2f3ce2309fb3c470accf416da4be5fd97959"): true, + common.HexToHash("0xf65dfc22c791f0ba3cd06f1814c2cfa6612dde169736cd6b166d729170d55814"): true, + common.HexToHash("0xda7975b67204ea511a594764eb23de53e3fd5ba82ebdafaf09b96d293d71ea42"): true, + common.HexToHash("0x376f47022769ed538322ced4fdaf215acd2905a46006f549985404f92800e305"): true, + common.HexToHash("0xae478e62bf63a165be3907694324717f372a61003be829ee0ba81d5be07f4ccf"): true, + common.HexToHash("0xf268d0172febca4aadbe533bc44d810e85068068edb7322afc7d56d5ae66f332"): true, + common.HexToHash("0x87b86840e04c9b147f943c67c034f34131294d982682defb5d9b0d2bd6dbb43e"): true, + common.HexToHash("0xed4ac62ee2d3347f839bec9c8f357bfa79d65f028a74888f4895a8cacbfd1300"): true, + common.HexToHash("0xcb7ed25a2d5553f4f9f96b7201dec739ea325618be1b1ff73cfb8b259301ffc5"): true, + common.HexToHash("0x018496c1115235a8a7f9f4ed4abe8322a550de8ffe872bbcaf3b0392d39b341e"): true, + common.HexToHash("0x67bbc04307a755f554726f785d634fa6f128d05d579a3c445005b585864ff11d"): true, + common.HexToHash("0x1a5bd38f81b44723f34198d3a111e6ca09bde2a51ab6facd6708d74e26086abe"): true, + common.HexToHash("0xec3e08fa24f8c3025376f54a12f219d8d8ad2c0c6a53137bfc6ebd560488a9cf"): true, + common.HexToHash("0xbd7edf30a3dcbb380a72c28ac5049fbe0df437cd12016524835d712369480847"): true, + common.HexToHash("0x53c820910ea2d043e9564a9e545e26cd02231b3a34dad7948fadbd6847c1c9f1"): true, + common.HexToHash("0x6bea1f4c0bf607af53b1cc25bcb9c590f52c7eadd44c49490ff8c53e75c28ed1"): true, + common.HexToHash("0x9af420c608fcb0688a97b9f20fd0776970f9eaab35965a2cbd695f994109550f"): true, + common.HexToHash("0xf0adf5c824579f1429f21276bdcdb1ee267a3c9d6ae43260c243f65634c0adaf"): true, + common.HexToHash("0xb0d55248e103c96fc55e9bb8a96843ae7f8fde7a7a955e5adccb39a35580dc6e"): true, + common.HexToHash("0xc17504d967f91e4a99e72bcb5c008a120a11c81aa56652624d2d137c395ef0e3"): true, + common.HexToHash("0xe038f855df4b54f3d27c51028c023a41719b37f1aeb11ffe2b0be508ab272abe"): true, + common.HexToHash("0x90edc372ae83ca28e7b1ef01b8d730c415a0829c5787881984cb35b3f0d7005d"): true, + common.HexToHash("0xf94ae2753032c2b2afb023c6472fc1f333ae87b1a5677e22812a69bfb0472b83"): true, + common.HexToHash("0x53f24971327c9e5618ee603b15140f1d9d4608db343cbd1072953fbdcbb91b65"): true, + common.HexToHash("0x7ea8d7be9b14473f46a6eeca4f30a3f7a3648306be625c57510d09704cfc518c"): true, + common.HexToHash("0x50334ae2eae53a6a7879c056e197a9b617eccbd4fc03bf6c6c306ef40241cbc9"): true, + common.HexToHash("0x1d7d1e0ec5c1d56f4be8be0298a4354b0eceaf79419bc2cfc60d72a49af52194"): true, + common.HexToHash("0x965cebe0fe75c5d4343465586c80b15d4c7558c3d3fcda09c4471318a4f8dba3"): true, + common.HexToHash("0x68e320a2ee406dd1c71f5371924681d2d99fc12717b3c70170e194eff789be0e"): true, + common.HexToHash("0x2777afe08732371a74d9144d3e7efdbc374f7a8202a6653ce6927e38a0e9b4f8"): true, + common.HexToHash("0x2e17ce45672ced98c931cd0ec6bda9cae3390d4e6ba804818e6338009b7b9f6b"): true, + common.HexToHash("0x7113ddb0a8dcfd0158c51ddd9228fa82ce40aed6190070a99f0de7a2a8c1fd81"): true, + common.HexToHash("0x30fa309985d9e5929f8a509c4a81ae7b213f0ae75bcb17b8933778d42d95e670"): true, + common.HexToHash("0x98996e962639ba7ffbc9a77c959c3ce00e824253326ce84ea6fc45cd7c1017db"): true, + common.HexToHash("0xd676b2a8db52ff40288909795fc0635a776ab0777a48f80b4f844adfc461277c"): true, + common.HexToHash("0x44f4abf2ca516308de59ec451cbe04c1ef34c1afb9f741265606d7f288e16256"): true, + common.HexToHash("0x0314901dd99e2dd061b97d607d04a13a9703166ed42fe26ad23523187b74fbca"): true, + common.HexToHash("0x12aab91ce257159b451a95c084690d978d2133c97ee3797626cb532cdb1f21e1"): true, + common.HexToHash("0xc6c9bd5fd157cca2c74a3265561e3d295856913634f0dfef87176ca3aab0c753"): true, + common.HexToHash("0x1b0a20f1e0a7c805268c56b24eda6745082a7950b987285632c8de491940b69e"): true, + common.HexToHash("0xadee7f580f476a4fcf1f04a1288975423ee126ced0ad62c5ab5efc16b0e900dc"): true, + common.HexToHash("0x4cc759eb635e61bf8f1c2d7712a10b124228ff18a7d4370a4b3aa797adb15513"): true, + common.HexToHash("0x2f51b8d730245d88a860dd286e9118b93edcaaa4b4be4373c66268d9a509469a"): true, + common.HexToHash("0x8aa9ea4229eaddc3ebec9ff302a400014cbfec4cfce036f7c3e03ac4767b9c65"): true, + common.HexToHash("0x32a1dede9b67ca23631e6816217167c456f5b8bff368fb7488a5ff0f5022e4a2"): true, + common.HexToHash("0x6259401204e3ea1144ef69a8a4271b588fc35af96a32b8d394927d36c663fb85"): true, + common.HexToHash("0x436bdefe76419da0a69b32ea9428bd103d3e10efdf6686b68e0d62009b81ccd2"): true, + common.HexToHash("0xd9557e339a4db8b86573434f0636758c4b7ea441d2bdba617d0be730555fd397"): true, + common.HexToHash("0x36e833d8374874325d1b28298bd0bceea6faaacac1ee28cedf345edaff84cd21"): true, + common.HexToHash("0x69072034d65e783232cd0ca2d629a386c0fd767e261212aa1369967c938585b4"): true, + common.HexToHash("0x01925a3667df38a604c77db5c9e0f601c2c0258370199a2adc13598721d5fdd5"): true, + common.HexToHash("0xc10a0db8dcf55fe1068fad5629587306900438af3828507192e749303c216938"): true, + common.HexToHash("0x29a6201751c28923acc8e0a68bf8027314c6c7b1f4a4c3ce24400e9afa5e55bf"): true, + common.HexToHash("0x877f74c45065e9aa6300d3ffa4cb1164b48857b329904e53463f4d6536b4e135"): true, + common.HexToHash("0x0d183e4a6a29d5067b1fc5e6a855c536f3ed52ad15f4362cf0b198a428b4cee5"): true, + common.HexToHash("0xb2e718ec2e32c75a0170c62d22fe6d6909409ac46a7d582779538d3bec5ceea6"): true, + common.HexToHash("0x3791259cb91415a505de9091a18d46530e44fabc205683a4d9272ac49ea904a1"): true, + common.HexToHash("0x895d71ac59d7cda1806a839193f38b4e4849b27978643e25ce879251d8790231"): true, + common.HexToHash("0xfec1dd9ffad7d1c97782996e46ab3d3ae589828257b252437b259450e25355db"): true, + common.HexToHash("0x5044a125bb365ae01714d5d735848dc292e958b080da30f947d00dae384e8ccb"): true, + common.HexToHash("0xc67faf391fda3c26b6474ea39141adde047376d564fb1402295b692f2fa7750b"): true, + common.HexToHash("0x2457ddbfe8cf62ba7826729bb9aad110191945de150bd6e9f6fbffb753cee986"): true, + common.HexToHash("0x837237b1e3e72f47b4f456dae63c069e57577a3a5ab65806409f7f0677f3bbdd"): true, + common.HexToHash("0x1315f83bbfc753b1165bc71defa28cefbcf750476d7c23b627a0193ce8651bc7"): true, + common.HexToHash("0xdbf2379a8524bf74834c858895feae3e2ec2acd0f971010d285e30365083eb9a"): true, + common.HexToHash("0xe15f266dfc14d34267c1773133262c9232695b64e8b0986c97dca2fb738762ef"): true, + common.HexToHash("0x153dedfc435ee846b84662cef98ebccb2e4a0721a4bc373b2cc953ec6b9c8d3c"): true, + common.HexToHash("0xd1b54f71d828300b3417db44e6d47661abc201636da0e537bc04e84236ebe65d"): true, + common.HexToHash("0xc7e291f3627da656b190cfd2c5a8d70146632d7e9100f87aaac804cc82b5df94"): true, + common.HexToHash("0x48070fc159f9885554229b8585951d7dc8f586bc3a6c3a24d43508310bc7f082"): true, + common.HexToHash("0x04cc3cb4763b223c0cb18dfd6316de61134f2654db83883dd9fb100dd140d3aa"): true, + common.HexToHash("0x8a3e841fb3d42b60aaa528f27143920389bdd3e52a010c4869dc13660cf89b02"): true, + common.HexToHash("0x6cf4be000c8b71bb66c923544a298ae9b698db4f1531781244447e77ebadec86"): true, + common.HexToHash("0xc11ff2f7dfe8f54f93a26e08f42c23f7ecc1471c8d2827cd3a3499dd4bf58fa3"): true, + common.HexToHash("0x6872e150412eb28600b15086d51659c21b230b4abbc61b7718eba6c2100dace0"): true, + common.HexToHash("0x15282b64b11c32233bebd1e290e9904b3eb376726b5350529620f4d88f26d4e9"): true, + common.HexToHash("0xf6bbf6518cbe88fdfb6bb0ed8ffa369f012cdd5abc3ee0ca2d68579c8a9520cf"): true, + common.HexToHash("0x74ff73dbe85da36f5836ab832e0697c6e8d5eda3074ee5da1e940d9e402c5288"): true, + common.HexToHash("0x81cde83485aa7f70832c063e13deddee13a8f7ecb622160a69efab69bb7317f1"): true, + common.HexToHash("0xdf4d515b622ff4a293cbd8f135ea522beb5a9d27767c8a038905ab5c4648d837"): true, + common.HexToHash("0x5b973dabc9ff65ef5315fabd783dbd38a9666af14c9e6301b85873f4bde2c02a"): true, + common.HexToHash("0x14a533c199dc356fc156fab532bc1fb972fdd9cb2d58b638aa8f1f9f9d4d8e3e"): true, + common.HexToHash("0x1082436f4e1741652d3d05729243a5b3d9f5d0eeaddd8006edbf1ed44826dbc2"): true, + common.HexToHash("0xa91df6ebb704ab8aa0040ef64cabcf47322e639f55cb32896bd86bf34a15bb30"): true, + common.HexToHash("0xc4aea7afa89ca5ef95c6bf57a139eb4ea370a77e56383036451a0e1b1646731b"): true, + common.HexToHash("0x4184f6d73444a828403510958b5dfeb0e8a72c5ed5994e38bad1bae9827fe5b6"): true, + common.HexToHash("0xd50d8b6edd6e0b7fd5fe89f40b5b77e55112dc8619cd82fc16ec53f36dfbc10a"): true, + common.HexToHash("0xa170cbcc54ef6195f41ce50c3de77517ce8bcbccf1e8b9a2a66118cecfacd26a"): true, + common.HexToHash("0x71f30e68469a80750051cefe5fcf31de830ad9e0c47a8707342ae11874253604"): true, + common.HexToHash("0xe5751e9e6a26f1c8473321825730803e7105819a64630fc89bb03d4af7e4e173"): true, + common.HexToHash("0x889d8db4d234531f54bd560921c72328a402c010408b8f033de413e0b619fe5a"): true, + common.HexToHash("0x5f4b4d17d680cbc8a793375b67ad7a21b0bf3a181a1337a7df41cfb1c697571d"): true, + common.HexToHash("0x9e01dac810bdfb9a6537206ce7718fec6b605df1c25f0b329a75d3ed532fd096"): true, + common.HexToHash("0x9ec0ab4eb8ee23ac047efffe22c8093f1bf44938f4c860609278aa55be3d91cc"): true, + common.HexToHash("0xbf3b054d6434dd4fe41d06b84cfd9e2542ba06ef61e8485e5a3cef9190136de3"): true, + common.HexToHash("0x13918300cb9dbfff15ce9776aee6046b07af3aceee621b26f92a6a7d595beadf"): true, + common.HexToHash("0x445535c7823a7736ad8bd56bd86df2bba342f74b16dc3936a28cc411243a2d4c"): true, + common.HexToHash("0x086cc9aceae87b465118f6af2130799027977b577ca46cade0a448a1e146b6c7"): true, + common.HexToHash("0x28609484aebfaf9250733ea4ce4873eaa7537600772addc753f7d9884dc0172a"): true, + common.HexToHash("0x0e56e1c0b8ac04366257686f4078f68e556d39d1f26f06747cde31e9faf066fd"): true, + common.HexToHash("0x06911c951fdeb5ff9c955cb74badc557020922e4b1dec0ecd27a1a91c0c03cf6"): true, + common.HexToHash("0x3f4761aa44e240e91bb4439575b458a4662336ae0e5c3610d1b163652dc62829"): true, + common.HexToHash("0x191bc75c34f57eb4549ba57dbaa044828a29c852cd6a876d6a3761fe161cd8d4"): true, + common.HexToHash("0xc22646184869ec7c512388b56ebd314d688bf5f5d62fd45a2320807444191c15"): true, + common.HexToHash("0x9310b653ab90e404ad4aef6f1a5a0711135a551cf49255868719377b347add1d"): true, + common.HexToHash("0x7a604e63b8b7df4876f46bd48539e17fdca5edc38b50a0af8094efe3fab2b982"): true, + common.HexToHash("0x56c9f618cd84746387acf0f87780702d0a35be25ac1a1405cc5e8eff912434a5"): true, + common.HexToHash("0x29fb5d5a4193097fddcb16b0ebe2dfcc16c654ccafcc194a06eef33a9d39613a"): true, + common.HexToHash("0xd488a9cedc46d787b28efc99163335507f0765decfeda3cbd6ce4dd8deee4162"): true, + common.HexToHash("0x4aebe555f6f610c4e465bc8e814a774d66e59b55d4df127eacf241c2ba0f4cf2"): true, + common.HexToHash("0x274e1dc84979d7a43a5903fa9db6f004d390bc587b2e861a43e4d487b904c4ae"): true, + common.HexToHash("0x0417959a73e9d102d4d1a80a0fec402713bd7ab803645923b3493757a6583ebc"): true, + common.HexToHash("0x2c7c1686dc260503faf110cc82b3756a3b49f3ba9a14a1bdef1b9784364353cf"): true, + common.HexToHash("0xd0d50f55b794afba859919f102ef28e2b05bb8cd9a6729647a918abd421abadb"): true, + common.HexToHash("0x91fdca58d5a9466029fe0f396e7711dc2c0b497d13b99e7eb7eb52ba51f278c0"): true, + common.HexToHash("0xbc0c0eac4d2917f02c3b1a48d9889796646a79d5a9febb433825e1549d60b993"): true, + common.HexToHash("0x2e5d5daa740b245ef51b997805dcf54285db8a9c5c947db5c231d8f81361e745"): true, + common.HexToHash("0xcc2f476181e1f66c81fc29057c74adc30b3f45b43a3a46efbf2057e092543322"): true, + common.HexToHash("0x9e1291b5045b08736e192ec449c971dbd2a164a748f0dfb1c6035bca7992afe3"): true, + common.HexToHash("0x114903f833232c363643f53d9852c879bf482a452229d41b5ff96b340fa25ee9"): true, + common.HexToHash("0x24265540ec4dfd78b0ff3a6c6453b31dc193efe790c075c71c39818dfc4d5ee2"): true, + common.HexToHash("0x76990a2a51e4cca8b177af313a4d8910f0a86c99127ed2fe90c927bae9402659"): true, + common.HexToHash("0x950f23032ca8a5f6a3e86e6f87c5c225e517f11aab6a5db856f7b933e119ea9d"): true, + common.HexToHash("0xa8ea8c132d519a98ab881df20bc3e72b47cfbe230f0f6d329f10e5bef8adeb91"): true, + common.HexToHash("0x1c56d4786df900855b08d14970a4f0bbf2ad16fcb00f18538cdd865ccc9fd096"): true, + common.HexToHash("0x83e8e55ec2f4caf201e8e2f1cc3faa98795568c9fe1c54024fdcbbfb10a9afbd"): true, + common.HexToHash("0xc6dd4738c99dbe8522d1284336f42147bdf70e4678bed6fefe0c6d02d62d856e"): true, + common.HexToHash("0xf285b51264dc4abc72cf119c239a937a7c033cb7b2d12adb9e943626f689d756"): true, + common.HexToHash("0xe9686966fee2e374870ad6d4f570d647da1308e56e23959c03bab73b6e8616a8"): true, + common.HexToHash("0x2a1e91bb0c127c1f3a5e12da4c2d71a30a252b373a5d596e6fbab6df5345990c"): true, + common.HexToHash("0x5bc2f707d98d5e94ef187d0fb9643806ec58a22d447db162b3a114b177dc8ceb"): true, + common.HexToHash("0x000a7e2eb1bcf30a112223a7ecb148c4603728c65de6ab0fbd39aa6f77a689bd"): true, + common.HexToHash("0x454f3ca147c7b404984a417ed2b74d0d64bcba48e3dd64e149a3eb149ee54b1f"): true, + common.HexToHash("0xcb35879b72a5901ae834e785cd1f5312f168f29a9b607056936f4c4c319395ce"): true, + common.HexToHash("0x91c946a8654551fda098cee82c316cac583d325cd7c5f6d6d4d0d4ca4df45a51"): true, + common.HexToHash("0x4c75f3529e9b8cd31f65b7e233c1755e71429bdb17dc01f4ae64978f51296496"): true, + common.HexToHash("0xc9aace4e902f288a890c57075946ff8a531e68b404b0114542dfe31398268452"): true, + common.HexToHash("0x98a98975dae653c959469170550249e4d85d23bcb92ea0554d278e54b328d800"): true, + common.HexToHash("0xe1dafb997121cfca17bba7a6d51d57bf3b55f1b3ce0c735714bea645c51a51b7"): true, + common.HexToHash("0x5601284d84d9249ee2bbbaf447185d31b7233fced2581e755e97a70e7222b959"): true, + common.HexToHash("0x500d618d56beea9782e8cfdb0e00704ee565cb4587c0b05d42e71660adaa7d6e"): true, + common.HexToHash("0x122d5777031a1306c2c7870fc1ddf6d1f4ec797c1d4ef1abbb809964b2b8c503"): true, + common.HexToHash("0x7666ae534faad39d61b5b1e0478da3a8859ee49d1ec161856a096ff51083abd7"): true, + common.HexToHash("0x6a50d6e4555de7537a8fd438b76eba7b994841d989609eee1810857b5a74634e"): true, + common.HexToHash("0x53b6c77397d3dac9d6bca3f5c45f3dc89a2d749021af0d83b88675e7c60b661d"): true, + common.HexToHash("0xabf112e6b450455150337c729a60838e65d473628caef5cc817a80ba29b09ccb"): true, + common.HexToHash("0x5756f1ec9761a86b39bfa0fdc429ae257e701fc6feced54d156ef549bbfc3b23"): true, + common.HexToHash("0x387d05694dcc915ec998aa4671b6201658d51520a11c2432b77a4706069d380d"): true, + common.HexToHash("0x78adc6c7877b253e917ca761a61c1dc87f8715343806a29d1ccbd5c851042cee"): true, + common.HexToHash("0x71989ce1bb1ee1534825a7753c372b016fca9194c542f8f32ed65bafca46510a"): true, + common.HexToHash("0xb07567ed9b03d3bdf61ea5a6b6dd000f87b8b952f85f0fbe19cb3914be04c7f5"): true, + common.HexToHash("0x7ec9b71912a064a0ccc4ecb158d8ee04c1eb905ec5a192f03fa2401dcd983eb3"): true, + common.HexToHash("0x68974403a77b78be9246526fbcec27c6577451cb2b22fbe5517924ebfd84e5d4"): true, + common.HexToHash("0xc8d0717d3131c2c72c3a2bc3665d6c026e9dbd43f7cfd9566571114da4a54d78"): true, + common.HexToHash("0xf89c70c980c5b2544718bd3d035b103489c654b879c098bb0bdf1283cd97f7ec"): true, + common.HexToHash("0x9c2ff3378e543ea2ef796ce81dfad563bcfd2e37c45aad6a38f0ee4696e04bfc"): true, + common.HexToHash("0x942ef0d9ca7dea0ea1cf14c4a8ddd627a90586fdd804e70e9085dcc356849384"): true, + common.HexToHash("0xcdbabfdea7b9458ab201085cd37f1f25d66e267dd7d9fadfd34ab3460d5a5205"): true, + common.HexToHash("0x2a50b2dfdcf8046a815cb16091722e0cf7d7c14e7786d5762ab8a63065e1f880"): true, + common.HexToHash("0x3a41c8554ab2a227134beecc420b164cd3e2170e3222e5e9b541c6a5832f1655"): true, + common.HexToHash("0x408b1971730dc55ae35990877aa12fa21ff59f89c29d266f94dea1a14d6a87f5"): true, + common.HexToHash("0x631914138438a866b8bca13d6cbd3ea2a5d9eb2abea540d73d5e92e78fa768d8"): true, + common.HexToHash("0xf334460a15a29ad604d654ac1b31649d46162be4f806be079393e8d730481f4c"): true, + common.HexToHash("0xf4b8c04cee2cc3a2e91b4c033e1269af64895ff282dc1303d4a1e0fd09cb24e7"): true, + common.HexToHash("0x2f028a53eb335d768af5c119d60a2bf6d39c200c8562ebe671ed3355adc746ac"): true, + common.HexToHash("0xdc1ae1002376ebd2807264c26b8e17f5c4afbd578ce990e67ce2ea465eae89a6"): true, + common.HexToHash("0xdf7f9d44be68622ebe4d65b3ce3ada01603e2c237b342c8893d5fb04dc490f8e"): true, + common.HexToHash("0x49e44b33eac39864b12b6b1fd8d3dd52dafa4a4fef2dd473cec112935d40166b"): true, + common.HexToHash("0x4ca75923f0bb772c5a30a6ba763767d4fb96e88daf3b19090f557df2ce275883"): true, + common.HexToHash("0x295d79106b9e3d92cde4f144680b5747171bfda78af5a65e41206b0468f30558"): true, + common.HexToHash("0x7fc3657976e866b6ba8508ad8faa3586ba3ad1dd1d5d06c15cbde7ec90442906"): true, + common.HexToHash("0xbf97e559c8766f8d9d38baa0de6af87594b0610313fea46373459aa664c41a1c"): true, + common.HexToHash("0x0dc4e25b29580c609f4dbe10869012be24a17d34e09b3a673e16f4df34bbd4ed"): true, + common.HexToHash("0x04859bb1ff836cce952de1d01a4d2363e3c6d0b3997a8dfe269fbf87a8cbf0ee"): true, + common.HexToHash("0x8694c1d2898e07e34c15c5ad6652866ae4ca4d88f4337bbbe855857502908009"): true, + common.HexToHash("0x4f09472a8c93d9de6d450df0fac45a68860c79bb76b91d56e94464f32df0b0a0"): true, + common.HexToHash("0x2caf3ff90dd89b5cf138d78f21b04f8f76b98cd10859c03c3bde11364ffb2882"): true, + common.HexToHash("0x2f24cc23ceb9bd22517bb02e761099c157c8f3b7a5f9a84d501a67e7f747a1da"): true, + common.HexToHash("0x710a78672353a69499709859a289e06b3a1be462e1155b8e7d0e75847d53db47"): true, + common.HexToHash("0xc7f572274c1798b0911f7927cb45c160e1b60ae9cd79fb3ab2646e1b6af23ef2"): true, + common.HexToHash("0xc60e7e0415d37e5a2dae135592f8efef9410a0cd674832dd4a4d31ab5ba1a0ac"): true, + common.HexToHash("0xbe42ff382a1e718ab350e96ac10588b347da0bff8d806a0c14b72a4fea497a36"): true, + common.HexToHash("0x6a13f42fd55bbb5f53d92c145d2a501cc8e2361ffabeabf68161ca4c4cb90f01"): true, + common.HexToHash("0x82dfa97685b5725003cbbf12a4f1f35503fd39460eab2ddcc2ef47868fbf0722"): true, + common.HexToHash("0x236e95fbb21f353e51d97438fb92d71067148595bfc56911a3784d22754fbd0f"): true, + common.HexToHash("0x9a7539b43d1dc2f86fb6917a915f29cd99589be406ceaed2e74be8a3780c13b6"): true, + common.HexToHash("0xaacad0380c878227b8466e2918440451f5b5aacf2fe77113493dc161faf276b2"): true, + common.HexToHash("0xb8fe5928ec9bfe507b74678bf9ccb31189095a527d09512dca1baa341eadec91"): true, + common.HexToHash("0xc47f539a2e3903d2ede6e060f926b9d3c881b0db753f8548e932963595c8ac28"): true, + common.HexToHash("0x44a29cc25194c30b94ca01e9fedbc6fe6cd96c56d9fe880c21ea59542fa72135"): true, + common.HexToHash("0xe5873bcdfebdd32544c46e753a6074df7c80822355d9e78aafee0b50c86e5f67"): true, + common.HexToHash("0x6125ce32efbe1222eb088a0594e2282e34a579c0aa8ec90d3da2e3e102d0565d"): true, + common.HexToHash("0xf73913b2102404613730971c9dbe94b13677e507d940d9ec3fc177bd4c4da27a"): true, + common.HexToHash("0x492e43da738dca5acdd32ae545ea10b72c523068d812cc7fdf99ed4e253be15e"): true, + common.HexToHash("0x517cfa00d20e7a21fb140adb36344110731fe20d6eed786b43df0926a3580062"): true, + common.HexToHash("0x2d0f1cfdcb0b516be618029f26be83db788b23dacdb6a2dcf7d862c64845116a"): true, + common.HexToHash("0x1ce8b77dc0b064c1b5a3c64a50f5067cf5cac6c6338b0ce81d13958bbe105907"): true, + common.HexToHash("0xb8fe0a90db1ad6cea9528dbfb7d52220c6207391f853a51e6c9826d8639e7987"): true, + common.HexToHash("0x33c34a1068c5d132e3e2c6767243b7cffaeabd256cfdccf86f8bfa03d280775f"): true, + common.HexToHash("0xca04ab416fb048eca1d019b3330d13faf363706cf7839d751dab0df91d09698b"): true, + common.HexToHash("0xaec9c3b6a72f600681e31559c9c825d3015893a920c216b5e834316f35e2ee98"): true, + common.HexToHash("0x582b3d0efea3544b77047f58d3f39c1d98848362b591a8c1b9ec7e70c6e117a6"): true, + common.HexToHash("0x1b2f4eb4b015af2ff17869c7cb4318ab1f5530e575c288e7ce46b16e984beeef"): true, + common.HexToHash("0xbf8c9485d18017960650809da0e1aeb1d0cbc16b6f9175b511fb588b2b062e38"): true, + common.HexToHash("0xce4115cbc712ceb7ded69dc89b4cebc229bac3e151b342f6a130467b7c167f1c"): true, + common.HexToHash("0xf0b2f7689d840e20b1f5f9102593f1dca44972ba77cabae6a74c2ddc455ad982"): true, + common.HexToHash("0xfca9b5d63bbe9d2a2c2ffed62afd56bff020263cadc946b7f577bcca4ed7d210"): true, + common.HexToHash("0x8b42539500207b1d5c5a68afa4df961a232280b81a386bc95ee824fe4fdfce71"): true, + common.HexToHash("0x0191cd056468a90e9b4d108e5108490ac260b3a3228c2721ad32d1200c2004cf"): true, + common.HexToHash("0x09aaf899f93a2df6e3c0c95d68d0206445718057a3ad35fb80cafc24a4f284ac"): true, + common.HexToHash("0x5c022679e284e5ad1fc856b9be52bab9990e7c26c7f33073824497fc3a3f845e"): true, + common.HexToHash("0x3c930265fd1dc92d2a3a207cddee529bfd560cf1187f747c452e3a9e33d41022"): true, + common.HexToHash("0x49831e7d90573379adcadf04b922daa677df4736ce0d53a313c8ed920470f619"): true, + common.HexToHash("0xe04840fe03030b79ea653447f76508cd33214f6afba9b3f9079c66e399acf7c4"): true, + common.HexToHash("0x537adf77905a762b14dd12dc264e0bc6ebdec615354d2611a9352071926bce00"): true, + common.HexToHash("0xd97da920a62c11a7ab1ed861d394e336507c94d48fa85ab45081af4dbac772b2"): true, + common.HexToHash("0xd7e5bac87f80b8e038123dfe9cb53f0473813e9c78c2194084f2f0fcc5e4a3d8"): true, + common.HexToHash("0x3cda1b5bf8dc9d2fac140486d0d57a1b031f7ea9f3096b64573cb89b2997977f"): true, + common.HexToHash("0x2c4d959ada0bdbc71c5c34db11f6247138ddd8ec4669188338f7b3919f1d95a8"): true, + common.HexToHash("0xeb424c1a0bf2f67a8b430b1758964bfb5f0eda73a03c3cfa05e4a1450f8a3839"): true, + common.HexToHash("0xf620beec1d4bc2c67f32676a4dc87144e59e424bb540457d7fb0a256aa2b06a2"): true, + common.HexToHash("0x7f019b5c465a9bca10b086972a4b2494dabd97c5c87b4acf52c2c21d6be87312"): true, + common.HexToHash("0x623ee9f2f444c9bd6e2492cc85187b4ba6aeef56d9b7e32d4945fac6a31a56c2"): true, + common.HexToHash("0xf9e8fa237518f0ff6ea66ea64bc3467c6822f20309e5efd9814ba209f8624d1b"): true, + common.HexToHash("0x80d1e9587768163a3ce90e6a1fce4c8fe67cdf2c12875734f31c28b6b0afa053"): true, + common.HexToHash("0x4eb244259648408cd7c3a85b425296e0401ea5bedc2d2e42593577e781e497a4"): true, + common.HexToHash("0x2577fd45d7982effd08a0f8f89c8e0e059650ee3c3c895d2f61d8be7fc1c121c"): true, + common.HexToHash("0x03c3ec1b249e16d921a99a032019a5acb13c82a7e5a675e3c573883f6f210867"): true, + common.HexToHash("0x6ac867bff5ae269465e7c0c7231e32c25301b178b2b92b5f2c946dd8e7378c3d"): true, + common.HexToHash("0x004bc3f219e62da1ef8bae0746e530aa31374ff131cdf053026a8dde56053b9c"): true, + common.HexToHash("0x9a3d2677d16ffbea382bf6a181d9f607a3a23424da4f39a089d89356b17cdd95"): true, + common.HexToHash("0x00624a6e95901def3278fcbbd3370e5e9d8fb2a4ea8c5f8c3ac795ee3ccee2f5"): true, + common.HexToHash("0x65c386f6dcf69fbd3ee7a95abf5b420a2f9d3f35fb78d24bc1a7e6a36bf92e30"): true, + common.HexToHash("0xf4850a15394dc1be40d869850931403057580fdeaf83ecd92bf01c1b510e73a6"): true, + common.HexToHash("0x3630ea17f8e892a2aa5d13e2961638eaefb8bad1782b16e5fda4aa0c79b8894a"): true, + common.HexToHash("0x2c7e59e1b20a622c8b481b88a8ecfbd9ded67d6c26f128ea087260065183d75c"): true, + common.HexToHash("0xdc0c0c6191f9a07625d788441e28f0ca0ac400ed92e816c1e1ed09cc7aee095b"): true, + common.HexToHash("0x1ebbaead84b4a5c147d8084d6ad8ae52fb4d2aa9c61cf7c3f6e2af4b6b028963"): true, + common.HexToHash("0x196738387fa8e92c33987a4a249c9a029e7697295f56b9a77da0e60595f476cb"): true, + common.HexToHash("0x486dab92ab08433602bd0ae9037d90b084dff768d953dc667818d9f16f2f4c08"): true, + common.HexToHash("0xb3efbbcdfb28f88a242931de34af12846c5494fc1772e943250375bb2dd699b5"): true, + common.HexToHash("0x5ee6d58da239991b184b61ef65daa9ca26e84d5a716bd60bd0bfd5c3c71d73dd"): true, + common.HexToHash("0x087de2b8a2fb08ade122942322487ca16dfcc620f2ffd4edfbd4798f261d941c"): true, + common.HexToHash("0x9abbd70da48188ef00c8846f3c4cf0d9ee638868c23a61fbf24f47f552ad45d9"): true, + common.HexToHash("0x4c2d9eb2c8c1db2f55dbf5e55d3f165f04448e548b83020cf4fd2689ab071fef"): true, + common.HexToHash("0x5c5c4749cce1654025d23abda8f21a8207455e456c734b211caf6294d289e88d"): true, + common.HexToHash("0x89d6a1803088f51edc3ef88d0712b0d766178c0c743a716865a5fef798fcfabc"): true, + common.HexToHash("0x4461ce18d461008cb7a0166f595529099c61e47add28d96282852dcf677b6e4d"): true, + common.HexToHash("0xe8f02c5535ead2c6cfa3130d0df7424d1c348c4f4d84ffa9b72e51d91c17f076"): true, + common.HexToHash("0xd196ff097ba7acef8276ed66d2f5fc1e04892edd1850a69a2700779e09a9625a"): true, + common.HexToHash("0x190b4c0b573587bd24a0bf5645284b0f797739b4c1ebf5d292e09eed07164d54"): true, + common.HexToHash("0x9074216fe2b7969b1bea9605136ab2bd0eeb7e8a1996af7813245b8a8b24317a"): true, + common.HexToHash("0x1fdcaa08ba2315c516d2ed2ed8e44612862b31f7ec5fbdf51c9e1f24873654a2"): true, + common.HexToHash("0xf7e39f05d5a2801fb8e7612f3042dde6e4223cc2f16a474b0bb3edb97facb5d2"): true, + common.HexToHash("0x39ce22498f3ebcb242b881b491e6834fa91b90b1a9ec266678386bdef8a2b22a"): true, + common.HexToHash("0xb297f291e11c6bc44209584e30de80140b5446efc9bfc88c2e7d78b0530b11eb"): true, + common.HexToHash("0x9ba1570940349ebabad3106d56ba84edd760588c507ebbf4d7c8fa17ba8e853f"): true, + common.HexToHash("0x60f9948b41f8fe6e942014209fb50ac85d73786d52e16761c20be9f730f04bcc"): true, + common.HexToHash("0x0535b1198131a17501710ba027e113bf106eb1f2036a48a5c551f1efdb9a9e97"): true, + common.HexToHash("0xe7f3826aadb8cf7ff7b9c26f2dcfc8eacd72f429c6b27c1bbeec2b007e2fd19f"): true, + common.HexToHash("0x1a40f2757a4d86450d9602c121baedc2ad5f77d91155e7bf8bc15fe1525d0a1b"): true, + common.HexToHash("0x5a12685bbed25aee317948a3f37b9e68e1a42aedfb1bf39bdbf1bbb81544a771"): true, + common.HexToHash("0xf98713b4a8e74858b28e9aaad48a423717a81be02884fc8bf8025e75d9803509"): true, + common.HexToHash("0x4536938604c1d864190b9d81b38b47c27f8672c6f8a4ef7307dbda762f37ba8f"): true, + common.HexToHash("0xc573bcaa21236fd094ee51846e5c088a59c7421f915ad7f3716690570dcf2065"): true, + common.HexToHash("0x46cec227197d92df065f291ffb9eadb05639902910128341ea0c1c5586b146a2"): true, + common.HexToHash("0x0605c9513c755394f4d0a4a6300a9df6628211fc5243284bd143a825712328da"): true, + common.HexToHash("0xb098d2c3ab9799c7688d457f62fede45b25b3a00981883ba0efca06b7d014dc2"): true, + common.HexToHash("0x3aaba64f3329bcf760bc9230c23c3f84b3da0d7bd2a85e84e1628fb425ef17c8"): true, + common.HexToHash("0xebdfbfe234bffb9a34a3e1623c8ffcde42793fdb5a009b47e80ba3e5d3efd6d3"): true, + common.HexToHash("0x0f51cf4e9d8125bc8e9d09d0d73c8a8f4fad540d86d387cec0a821539be876f2"): true, + common.HexToHash("0x6967df6a49fba32138744c7f4de3ff8141208ab6ab821c35f7d091f4898dcdaf"): true, + common.HexToHash("0x875a289706da4d647a60ef357e0e208a29b34b95ff12720dd5af22818d7560db"): true, + common.HexToHash("0x8f555392bfe149808234f60813e0c376817c6d96652a63431353557a66a25105"): true, + common.HexToHash("0xf09d6539f41015e5dab6aac4c3554364e014838132931869c97b0f31e2c44cca"): true, + common.HexToHash("0xc9df225d2c54e677e25d7d55c1cbbc72166c46e29fd96c44e63a6fb5f7a0e916"): true, + common.HexToHash("0x0083829b53470f4e3fb8d11f15c211f43637b81ef9cc13bbf8fdeedb1110a7e2"): true, + common.HexToHash("0x1639841e07b993ec284a4a2d866243512cc050e001f8f3765349b328df783fc1"): true, + common.HexToHash("0x584fd053c85f56837c893f080b07776f2e667d26c5e067af5d7404c8046adec6"): true, + common.HexToHash("0xbd618b836a45ae043dded69fccc0046aebbe64da9d7d574064317e978a989252"): true, + common.HexToHash("0x457497388a66322c6a06f255e7c2f86dcc3d4f80eec18dd1b5c95772b487374f"): true, + common.HexToHash("0x945c7b2a490d0ff7bcbc17977a9665a8ecf537a19099456c857757cc1f86fac2"): true, + common.HexToHash("0xe61077744555b2ee6e9e723a63a57e124881affc09ca23ba598033f42a697c80"): true, + common.HexToHash("0xc4512d93810c343d2ca68c739d94b259b5deb22be9d52edee01671ba9a68f9d0"): true, + common.HexToHash("0x00fdd302663d2556cfed7437f43b6fcb3cf850972e2e49c7fe3183fa4a5d4097"): true, + common.HexToHash("0xeda60fdf79d32e2ef1c1cb9feaf363a32e5242fa589d9e2a97935077536b213d"): true, + common.HexToHash("0x3b244509219cbe5eddafe8b5ef5b51530477010e0a5647c29ec02e0c91cbcf8b"): true, + common.HexToHash("0xbb14c4a3f46d2639f9240d496ba5941750fc5e6f3eb9295eda4d7b1a0c9f4437"): true, + common.HexToHash("0x028a5a074bf932bfef95890b37b440fdc10c14429930cc321b8408fcf665e5be"): true, + common.HexToHash("0xab079f060e7e08e34904b1218b4dbbb38045eba4688fe16a2e2cc17cb2292e6c"): true, + common.HexToHash("0xbba2d58b933215985fa34cc97ac2e60bb0a4d95429c664e728a2a65d3f6e68db"): true, + common.HexToHash("0x3cd96737675329994b381588eec6cf42d92d2b1d1a1d394f1bd6dc8138256ca4"): true, + common.HexToHash("0x4354e30096c938342a5c577de98c3dd2db86af60d5c314d7af9f331239ee96ff"): true, + common.HexToHash("0x9dff119192690c8578e35de233f566a1c3cd7b97272e8225e9f7b12d11a05cf3"): true, + common.HexToHash("0x3347f673ec1261a818213ab438bc0f53e64d74d8f33833e2e6c4b87f86657c26"): true, + common.HexToHash("0x1846514b2eac9a87e79163b107dc36cb69c4e8b8969d6f8c8ff5456893406b14"): true, + common.HexToHash("0x7d486caa096677934df109ec5b2874a127e6c55b5b2e56cfc4990487e45ca712"): true, + common.HexToHash("0xf523fd1974f7a02c3d775f9bcdeb4169416e63025337f8633c5aac448e7020f3"): true, + common.HexToHash("0x89053e940952b53451834fc15a2bd1c876ab536c01a0fd3f49408ee5dcd486ac"): true, + common.HexToHash("0xeadafba6d98d43fc77033d454e0c4e5f97d54780d6fa93592d0f51ee33224762"): true, + common.HexToHash("0x2ffe83fdf178bbf3dfdac99eca9b8b8f140ec8ffa04255a04df924dff723b820"): true, + common.HexToHash("0x25e110ded5dd9141559f893532670cb7c8ddca1c0880919adcceb45566fc5299"): true, + common.HexToHash("0x704ec94e0c94942a2826546fdc0d2e1c292ed3db272b2bde842003d87084db79"): true, + common.HexToHash("0x0505c452105b1b9fd6f1c95543a3e99332f36bc0f42a46b86e000aab42ada02d"): true, + common.HexToHash("0xe5fa19e36600d53e7d7e432a40a18fbcf841722aa5dc24beecfb1232b12785a2"): true, + common.HexToHash("0xdca6aa515d1a1ca869862b07db9361a38656ef4a01f58d076f4294cd1717ae54"): true, + common.HexToHash("0x5c09eb2436068d88bbc5242887e162ee666513a8af2075ba8dacbf9b4471b995"): true, + common.HexToHash("0xead0f614a00915c0948bc627d96b532e12a6a0a6adabf5cab5074e654b14d886"): true, + common.HexToHash("0x2a806eb47ebd6c99b95d2c56b8e77d8789979548c3b0bc95e6b623f28c9a669e"): true, + common.HexToHash("0x51635af9edf7feb9c1885ee5ff3d1219af1ceec438f4e23fa3b5a6f943c7a7b4"): true, + common.HexToHash("0x7dc744e3e11dcba3906471a8ba1fcc3947342b543d338143098fde500a0fdd01"): true, + common.HexToHash("0xda119a3d06feb50212898ea9791c68bd865b3a783c175456f1b5487257470882"): true, + common.HexToHash("0x8c146e3002f454ab8a10425d9a8fffdb4453cd21a940909cacc5ad75c72e007e"): true, + common.HexToHash("0x567886de7b1cf9d013669ae65ff5a9d67484fe44265a2292dcd83b851a237fc4"): true, + common.HexToHash("0xeebe3eac53fdd8fc9e588d89530ebb90514ee42d6059ed770494e67bc9f8226f"): true, + common.HexToHash("0x0e26c2d6a15b948cd6b5a258892570f68dcb546407cd82f0fd4c3ec6d79c190e"): true, + common.HexToHash("0x286f834fbe3edb6dd94ab2e3161df790a610ed765daa4286109c49f7efe72852"): true, + common.HexToHash("0x7613c909e676fc3ce99b18f98f214652a9c6191aa49d327be0eb8fc644026f6c"): true, + common.HexToHash("0x1ea7c2e1d4aace3432ac703e94ed47d04b6f97d44d6b0dbd91ce07726e7b276e"): true, + common.HexToHash("0x3b9cac2436b2d2b632b549b4e8dad8cc2e697d4c8da8e6bb91f3f3603a380d0c"): true, + common.HexToHash("0x9556d24cae361e90545d56039a510e31dd21e63ed3b000a82b6d9c7d11b9a643"): true, + common.HexToHash("0x6638c6a2f389e7a6cb608ff1a6ce8107222c5c7310c7537f2f46a5618ce6d47f"): true, + common.HexToHash("0x5ab2c72a3685b4811b581a064cc9f048fe8dc9bfee9655f988b1a56471632c3d"): true, + common.HexToHash("0x85b44bc494926ab08ed0a5615cc3c22ac726396e453bdeee8f86003fd35110e0"): true, + common.HexToHash("0x7f43c7a99f9ea7535ee6b33b923e7ec0f5a31bd899045820e5f2d06ddce2e022"): true, + common.HexToHash("0x61057ef078f703f852aec4e2f030bd856b45086594892c1c66430059cf675cb5"): true, + common.HexToHash("0xa5b43550f51246341afb329b6b828b2b719f7b9e4af11b6fa20fccc0b4b946a9"): true, + common.HexToHash("0x7797449e679fb435b46c73b6ba74cb12c06eeaf1be2fadb32cdc817261770d92"): true, + common.HexToHash("0x4465909c2c294ba3380bdfa1e997660585bce175b019dd0dc273a420af164006"): true, + common.HexToHash("0x1dc53f747c5425e01cfa3f6a201c1c2f1b9c3254cb559e690b0b2670ccbd1934"): true, + common.HexToHash("0xd4c5db77d6ac2e9baa322a5994e4d361c33cc7a7644b3c8c92196a4e8fb261e8"): true, + common.HexToHash("0xa8914dbf6a5ea3dc0ac0dd728f6e7ce06f7ba837f84ea7b10b2bfe9fb9fc6ba4"): true, + common.HexToHash("0x839b8d7e5aa0c7078dd4469b5e7d6f74ab4710017a0f2f287db87d7a1f7dea0f"): true, + common.HexToHash("0x1923879e9fccb2727d724d61f872ce7298b99e3dea0cd8d3552408abdf693520"): true, + common.HexToHash("0xae459932f37a0ed66023e50720eb3ff6022e29b5f14de50285604a2402d417c0"): true, + common.HexToHash("0x86b8244933ccde87ac7091c43e3af5f2f7db6a581e7fd87a84ad74430e7595c5"): true, + common.HexToHash("0x991bfe95b82e5af89c554c1974e034e965c48ea142039e337d147bbcbcebf7e2"): true, + common.HexToHash("0xb3a418d98e409af53b89a24b00260efa6e56900e37f3767760d37ec39597589f"): true, + common.HexToHash("0x7feadd7ec9f4df78627d5a0b085a1f6606e5a0fb0f504e87bb65a34eaf841226"): true, + common.HexToHash("0x8f37bf7728aef2408a8180a3d5bdd57c690df0db98df039b3225a894ea63efa1"): true, + common.HexToHash("0x39f0477116fd7f003c8c7818e9ec372f8908b7029233112cca5a21a340be56fd"): true, + common.HexToHash("0x42d170983509af58567afa3b0fe7ef7ae1162b911afa530ae130c0da3062b37f"): true, + common.HexToHash("0xbdd9d4f3f7ed8e354fd9f61c075eafecf08e1a345d069c9d735213aeda3a14f4"): true, + common.HexToHash("0x56a8653afb07f8fc9d112770d2a5faf51380d23a3be07a1ff253183480d39361"): true, + common.HexToHash("0x7a66c8cbe6433ec869a14f77773e2ae3068d4481d65b412e0bffd71fcbd25fd0"): true, + common.HexToHash("0x042d750f0cc7d51c40cd408e5107530af0aa0a3c270e46b12a235b8d72b7b249"): true, + common.HexToHash("0xb3cdee4736a10ab8fa938e3eab006e39b717b8e83020eabe0821867cf0893d7d"): true, + common.HexToHash("0xdc28df60c5fb4d75b04bd9c2d2e73967f25be88e771f80d3d6906f9ea8accd87"): true, + common.HexToHash("0x7ea064a75fddf3a07f973c46ffb74ef319d44736a9543f6419597df4b51fb097"): true, + common.HexToHash("0x935117a40aef6d8f6917c7611c8930da07e19998d6e9c357bdc3981fbf9b5bc8"): true, + common.HexToHash("0x74c8889c894f9ff382e977dd6b4044dd159af12ecc51c28b61aa0fbda2d62709"): true, + common.HexToHash("0xc6fe2e22aac8eebf6b7876d6acb07b2ffdc274000c05c9829fa4b2f8ad0d1451"): true, + common.HexToHash("0xe0a58b5e19fd0d2d7664b38d63f36f72bf9cd7a69ccbf776c91e1c6af847d101"): true, + common.HexToHash("0x7063fe302745018f4d028eeef5876dd956d0eaf1f1406b964b1a79f908c2b400"): true, + common.HexToHash("0xb405e70b1bf46a51e85f8407153e79ef47c269bf2e6e251b6ec5a32071f4f551"): true, + common.HexToHash("0xb54923a22ebccc0f9348e7dd23581f19bba6b4873f9f1a19e2174f14500e1efe"): true, + common.HexToHash("0xb52a083055aee0b7f453403629285589e7d226e8d0edbe14762505be376c2e64"): true, + common.HexToHash("0x40428a598667b036adbaf81e7066c182b1fa3792ee3943fc0401d0ca172c1663"): true, + common.HexToHash("0xd065f9a08c1899af3f4a29df1ffd0d2e8fbe1416fe9c9f4ce7df506c63aa7a5f"): true, + common.HexToHash("0xeef0d88f92c5105a7e5cf0de62ee095ae50ba73aef0530bb587f12ee66010778"): true, + common.HexToHash("0xb8fb49dd052ae920638425982813f1def34f7c53c9a0d43f1ecd10607dad62a5"): true, + common.HexToHash("0xeec3dcc3bb64c9ea982bb71bfb1c90cbaf5fbef602c0e99f4cf107401109f6c9"): true, + common.HexToHash("0x044f83ce132073cc9cbe4ce5a889441c38948a44e20fd818ce7492947ebfaf8c"): true, + common.HexToHash("0xff9c56cf9b9b6f332e627eae4f318a1e90c1533343725620c139e892a686e70a"): true, + common.HexToHash("0x6c4e26bd5c13206c2eadf93bef3e47a643ab93849ee7f356f1b5cfae624f3e49"): true, + common.HexToHash("0x272d55000f5f24fef890a421eb5f91862205e5f1b5bc289b22a7290aaf96458b"): true, + common.HexToHash("0x95da70df08067e382a9b85c8c65e4675ed2e8ccb26316ab6bf983a5d93c350d9"): true, + common.HexToHash("0xf80e56de1ebe75d3988937337bdfd0f6582d59d7c1ca00cb3b15ef8a187b1a31"): true, + common.HexToHash("0x9908652a5164daf377baee69d1301a2baf08cedabb4e058daa8397d30e021d76"): true, + common.HexToHash("0x6296361faa7a6c01226f3b2f172a3b3f0d7a3db84ebf8e5d9524cf8ede3652d8"): true, + common.HexToHash("0xc3d345d3f8e5e76f6507661c8130f5011e72f6d0739dbf6a83fa118d6d2c3b0b"): true, + common.HexToHash("0x52b0eda2b6598aa86085c3999c2facb6c8258c8f58476b0827e205d399fd5073"): true, + common.HexToHash("0x7049cfc167eaecf5cfecdbf9c2ed2a0daa6825a694a692c138819628e702c65a"): true, + common.HexToHash("0xab2ee5a4bc9ca1c4abe482035624a9f02158d7626ffbcf4bc1d35e745fb1d84f"): true, + common.HexToHash("0x73a3c59eba1841e087e1860080653ffa7cbc9e4b911a685851a2bbacd8e715a3"): true, + common.HexToHash("0x057bca477099015c26d464d87ee7f48d82b1414d726b7ce8a189fee5af870d20"): true, + common.HexToHash("0x914dad27714b594d564f72569efdfc30bc4e8982242f19f4d1c5011cfdebceef"): true, + common.HexToHash("0xc58cc229b7131d07fbc05c879bba8f19a57484b58be5a09aa7a18b61ff6dfccc"): true, + common.HexToHash("0x309116d2ed2f9eb441fdf32929f6f9030e106ec51d9f3c6807b42a47198a5e79"): true, + common.HexToHash("0x3a054c00c5a8012cd0d111d19a1c49cad8e9095c471c5617c8e30ed5bf28a6ee"): true, + common.HexToHash("0xee8d1fec2781e4950331b75418ce5cdfb054277a2d7e603c4062eee3966ffe62"): true, + common.HexToHash("0xf08a8b3e2f88436a43162561e5d5d9b9d702680380d196d4eb867816c2d60d97"): true, + common.HexToHash("0xabefdb29d256942b188b1eecbd5353f0e8e876ed7a9df26f41c027e376736875"): true, + common.HexToHash("0x6ccaa739ba870181b0a6438c9bb7c7ae4c336e48e4771765f46d5b31ce6340d2"): true, + common.HexToHash("0xede4133355bc6092726467e98db423874d8096b0636456f834ba835f0c031790"): true, + common.HexToHash("0x6ed42723d3366faa1e97a52ea8e40ce64bc94fe8a3bd6a0baf3244c90a929552"): true, + common.HexToHash("0x963187b29a4ba19613cb203287a065079afc03fd90f4fec71c9cd89159453e2d"): true, + common.HexToHash("0xef0053b4e594fbf81909cfacf582fd86f95a15a626663e75236130c09caa4c28"): true, + common.HexToHash("0x7f7c85a71113f9177c59bf8ac650232bed2a41dd0ef3990ab2fe03779c51338e"): true, + common.HexToHash("0xa018d1f408436b66fa8136263777523db276058b8736cbbaebdc8242f3111021"): true, + common.HexToHash("0x30dc0f1f172de1e81f6d333b43db506db9eaddbc4ca8453408fb77ed223a6678"): true, + common.HexToHash("0xc83adb406304d72d56d690e7e91c2cf4d959909e71c5b08652b901fe1acacb2a"): true, + common.HexToHash("0x85f9ebf0840f0689ae549a18c66fd041566419e78cf0ebbed3183f1e6a86de27"): true, + common.HexToHash("0xbb4ac8aec243801bc9fda76e32e4d09d2d93c719b3dc7b30060a26ba97b05d26"): true, + common.HexToHash("0xddff9ebbcb059b871f93eeb2bff28ce7bd5382cdfda3db7c6aefb6d2a5127fde"): true, + common.HexToHash("0xd22826c10d57ef84dbecb6898c4a94db6738348e9ac75d817de1bc1391499c83"): true, + common.HexToHash("0x29d3cf0354b1a0e6eb352523b0a1ce9a9e86e1e8cfba1b49f2c816c8c8b35a96"): true, + common.HexToHash("0x3ce80b5542e8370cd341957a1b73b7dc10b246922a59edeb99ba266d3da4b531"): true, + common.HexToHash("0x6360de86a1eb8e5e8d9edd1e6e69a4bdd067ae7c8eba426c24bf28242b459a75"): true, + common.HexToHash("0x2429abc6bdb4d39c015a0edde4666a2bb1d50fdcc761b843d9d6f89fbde7e97b"): true, + common.HexToHash("0xd425eb5d072eb71024ce2f890564fa09f1af2a6402dd09c05fb9e32023fb1d10"): true, + common.HexToHash("0x39607bc82d45d08505a5b12ad796f6b404ea4b169f21fd3c73a240a3f2cdcd0c"): true, + common.HexToHash("0xf6d020dde38e3c87166ba7f6eb05347f0c401a67c6bd6d4eadd4f4749e86b5a0"): true, + common.HexToHash("0x92f20e76fddfaeccfd21672b2f811f87a748f62bd5f3fde912ca939cd7f27adc"): true, + common.HexToHash("0x5b50e3fb7248f7975a77fa0f0b0cf62b89286053cd749dfda0b4d403dff31a82"): true, + common.HexToHash("0x221006b5bcd01e9eb79242fba179b006ab101f6494f164a0e3d48e39871c17c6"): true, + common.HexToHash("0xd2a76d3ff65894a44d87704c1f82735f3572223ab9341549837c33649a8d6d00"): true, + common.HexToHash("0x5376d56934db101b6f9df02d47ecac5098d84b4a25dac1ef03234b1c752bb82c"): true, + common.HexToHash("0xc14a9723b5f35088f0925820be59f7bf1ae8e393a0a6b8228ed14b0188f1afd1"): true, + common.HexToHash("0x6737139b6e882d14490ff4c81d08b1adafca0e3c6405d834db2c48c384a25391"): true, + common.HexToHash("0xb970867db13217450b6fa790c62c4f2259f61eb91ac74fcff2db97b4d875a679"): true, + common.HexToHash("0x814abae8149da6c1186661d0f061c94167a8ba3c390f5b67d8e2085181d6a7c7"): true, + common.HexToHash("0x7c6bf888146327edfd775ec578420cff9d57db07272590fd6267047da986b69a"): true, + common.HexToHash("0x3ca1cf6d5df1b60c07e78934044272055c11f3068ec2c157ef659d42de7f144b"): true, + common.HexToHash("0xaab8fda84c2e2fcd86fb3f7d5e7d8be9da0a5e6b5bd50eeadba3322bde0db052"): true, + common.HexToHash("0xacb326174b08f26956b8e4c8354fa96f70a80a00aa4439689c45703a8b560a68"): true, + common.HexToHash("0xdf7f87458a8686ed2a6634fca85eb43bbd18194b3edb64f9dfc5ee9015404169"): true, + common.HexToHash("0xe2327324dbcad26f611ec40d531d19251101baefbdbfc3e74d5d9c55855c93a9"): true, + common.HexToHash("0x81b31b61a3ae4323544241fdf98d8062f616e2ca72d6d5fd4b29d97765d144de"): true, + common.HexToHash("0xc5bd34c715067582e8d0c9794c37aa1e21403424ab795fb41d735a25ce1fc657"): true, + common.HexToHash("0x3207e1d7896b91dcc6e10b5afbb11134fc22ba49db627e1c72dae83201f30d10"): true, + common.HexToHash("0xc36e740a10bb5c373e544ebc91b0a7a258c846f858247d6d9551eb4613a0f341"): true, + common.HexToHash("0x923d819ebf615b9a870654c0aad7c44c46ec21806986751a9e62b490297b8138"): true, + common.HexToHash("0x048e942ca74e802e496a7e14550b0cbb2a6cdb64b9a9c30d7b02e31270569d00"): true, + common.HexToHash("0x0d71144bab1c0d36940cb31931b350aa39156994e78e505af07a7c8f59f3ec9b"): true, + common.HexToHash("0x5ccaca52749467bc70c743cf56f5b9b327fca7694d53f3141cb32f75ebbadbb2"): true, + common.HexToHash("0xee851881b496b05ffca87f07f5b0c8b90a4c33fc660ec04d3fc001626e9be2f8"): true, + common.HexToHash("0xcadcd0981ee9eb1598d0d37576ebb67985d4f5d25b8852db7751d3ed73687ab1"): true, + common.HexToHash("0x861f3557f6cbb2e48ee51c3cf8ecd16615185369eb2bbb313d52d1a6b52e804c"): true, + common.HexToHash("0xadfc16c8c7b4d76baa8f96498a0e7769a69565bbb596a173179230aee593c149"): true, + common.HexToHash("0x05cbef6f94db167530b672e2782e74d88e478847f4aa15958206a0a8ad82018f"): true, + common.HexToHash("0x7185c78332bc60faf3d861472011c948c81ff38e91ef3f541ec9bdae2ab914cc"): true, + common.HexToHash("0xcf5031bfe16e8e9dea2c0c9abd91459af981c2dd9a4290523e80ad0a1f7ea514"): true, + common.HexToHash("0xbf38eeac111658019938d99f8fef1590b022a46df3d6f1b86b2046452cc92829"): true, + common.HexToHash("0xdfffec2bdf3ad51a77535a7413e2107b9844741d5916181fbd3076a1f61f460b"): true, + common.HexToHash("0xd58aec8d07d5c1076936ce97aeb63417549f88584b73e9d16bad4cc9042c004e"): true, + common.HexToHash("0xa6c45f9ceef533411098a28fd2dfa5692d5349213913980287cbcf7e0bff2af1"): true, + common.HexToHash("0x94acd4d8a110f172a3af189f41f5112fff49a638c64f95708590493856f38075"): true, + common.HexToHash("0x0604d4872a2f1ef7d3bbf707cf6ccbb6490ff23aab5aa92741491d7268046265"): true, + common.HexToHash("0x6bdde4c713c5aeadf3ea4bd1337859b29d39061417bbf1ce4e25a59e32bff4aa"): true, + common.HexToHash("0x85a21052bcb9c90bdb181d5e39ee24a4e131dd3eeacef3a60efda28b4dc6e072"): true, + common.HexToHash("0xab9c63c2e88bab58ca1fb7c15f293574baec10a9ff937b1cb4bc2d25140714fc"): true, + common.HexToHash("0x8f035c2d14c172d0a341efabde0b2b36c1f079d933f664c2c4b69543c83bf37c"): true, + common.HexToHash("0x51be56ac61e044002a4340ccfc0036dbd3ba6bcba705070750e880f2710b787e"): true, + common.HexToHash("0xe20bf4ea15e50e5fbec6369484d5d253a9b882e461f639d8760d9158a7d8cb13"): true, + common.HexToHash("0xcdf2eba193d719893f6929cfcd3a8259f14fb3d7e38d9532b0246a4c5299c43a"): true, + common.HexToHash("0x748c0d68f8c81ea4261fe8717fdf30d51c6e54d73985132b4374c5ebba5c41c7"): true, + common.HexToHash("0x6d6f5206f7d8e3c29d4a6f43c9dc049f40bfd1d171abc1e6d8a3d6522b357f95"): true, + common.HexToHash("0xcecfa8fc1159f5d4e503f1c948cf32d6cd196561c9fb962273a05b331350e54c"): true, + common.HexToHash("0x009231bc52a49104005a9ff4da595f60c145eb6065f7c429e08f0e0ed2a94c31"): true, + common.HexToHash("0xada60bd4eb147bd54ef0a01eb6828cfdf9d26cf18ec12b516fd3988752eaf28b"): true, + common.HexToHash("0x5495db03e766f2671f78222687bcd4088597bac27b83f685aee00013ea5f06d8"): true, + common.HexToHash("0x73021a88c14ebcb4e94fac2c18a81a51c707ca85dbd9ba6e05c028e5e4cadf94"): true, + common.HexToHash("0x0abd5e1bd58f8706ecf41957821b596dfd13e5d6d8f25eb0b16a4e19e6e833c1"): true, + common.HexToHash("0x01ff9728c0b82b8f241e64f2654079fb50f021810b09647b4c94f3b5765c4de8"): true, + common.HexToHash("0xcd7bb90d0c4e24d76ab45cda061d18932e980956572e40b8fa8ccd5a36177022"): true, + common.HexToHash("0x20f99f403c9bcb3361ecfb0092d46fbf1b2f27189c662a52e73b8ad7affe6a8c"): true, + common.HexToHash("0x6ff45a70c27224598fb246a4d58951d2d837d12baea8583dda685d7e3927edd2"): true, + common.HexToHash("0xc429e6ed03ff6063aea94122b4867677ea8c2fa8ea6c1df73091b94ee90e49e4"): true, + common.HexToHash("0x4f831c5ba2e34f5097eeb8fafb5b470a125c64cae5d8f43c399a5b336a989b86"): true, + common.HexToHash("0x9c306c5d4adca08c84ab295956d613c2cd3fc2adb151897c64d6f5eaf64941ec"): true, + common.HexToHash("0x4cff9399f79d91e3f3e7672099d43fc37848dbd3f66403abfb2ece27e360c843"): true, + common.HexToHash("0x6b6e1150f6a75eb18c5e21a15c33614464b596cbdb061d9392f5db971dda4b03"): true, + common.HexToHash("0x278cf1103647011471906f7f40264c5d31000e42da510877c8d79bcee1dfd6d6"): true, + common.HexToHash("0xc250dd45366e30e73859ec5f720cffc3b7a54991e2d8124ae4f978b14f708143"): true, + common.HexToHash("0xa1d203f3e1157b7292ecf5b01b7350fbc550f11074c8a89b2e0ed749333e3dea"): true, + common.HexToHash("0xf392769b3fc1fea354ed10b35b6a764e834b4bc2bec782725e24039daa32dca2"): true, + common.HexToHash("0x36e8399787003e3301ecca2e0f46ea9869e06bf91ec8fd333074d16eadbc8435"): true, + common.HexToHash("0xd96039fd398f31f5d5617bf5ba28e036120a8efb114073a3f2bb9e323c9c3635"): true, + common.HexToHash("0x9adcd963b2b030e91177c7256b23ba2488f38aecb871005323388c4499600fca"): true, + common.HexToHash("0x18bcd20b10a9fa9f0dd590fe40f64c6ef354f3d045a8db733bc4132738563050"): true, + common.HexToHash("0x4c32b36a6d0dbf011c3eff9098e9222647aacc3b1015508de8989d66858907f5"): true, + common.HexToHash("0x06f7256e0fce940a4a060f22f7290df6395df2414d8ab072dfa5be9bdafcd122"): true, + common.HexToHash("0x9a152c8bdc7526e2f20f877a291bc3f2cb76e8c1d7cd476c365bdd635f980208"): true, + common.HexToHash("0x91d4a10eb24691ff3e6ce2bacd964baf2106cbe6c21a9336ee2ea3b377467f6a"): true, + common.HexToHash("0xab21c1cbc0dcf76b8b35573ca5432f2ce71bc62cfcc5c7279c46d7c50a240eb7"): true, + common.HexToHash("0xde812551c32d35f56f21369175d2f8f23fe2d5648fb64fb76b87c0156de96f0e"): true, + common.HexToHash("0x07b6e25c4d8e32c0d8d9ff2149ace8c2e00ff78017a113a12fb583de56665ca0"): true, + common.HexToHash("0x6a226b9cd43ad82b4586ebaac6e08b55077049a5ed81da0c4836a9d54cf124dd"): true, + common.HexToHash("0x38461785b930dfc128bb9d4a57ba4f376da68014fb6debec9f062245470fe99d"): true, + common.HexToHash("0x70fdd7f21eec520eb0d8ea34c168b5cf1d294e0d72ba3b8e596c617baa93f43c"): true, + common.HexToHash("0x6868c69206f36dc448f871ed663a2190ee0808c701a0d2408fac05fc28929fff"): true, + common.HexToHash("0x42b4dee2d8480e41a7b7971e929675a853b6485e76d38b7f82937495f769e949"): true, + common.HexToHash("0x348a07319773bb266cc875da1802aa12200ffa3ab78b37b25f8f14768e14cb78"): true, + common.HexToHash("0xaaf616b5b808a12a351d998c5e74264355dedc9ffdedc3e9729fa9e241356353"): true, + common.HexToHash("0xa547dd93f2895a17567b32cc01df21c00fc1f911f1aae523462d9ac5a1c562bd"): true, + common.HexToHash("0x41ba8d7d0cfe54f785d13e808140250057d6429250eb34bee4c0f77b5839944f"): true, + common.HexToHash("0x5a6f6c8424fa4fc3f329f9b6f0343a470acf51233bec8c2e79c1fef200f449b4"): true, + common.HexToHash("0x0517691c2c8796ce4c20e4ac50a4cfc4cce8f4a9ccb95f4a27740c24abb460e8"): true, + common.HexToHash("0x452f267df576c018923962ea85858cd3ab0f4e281c034f31ba6432ecde141de6"): true, + common.HexToHash("0x553e6c7f93b604013b9db825235af1af73e791ee60bf312093f8fa2959e1ef69"): true, + common.HexToHash("0x670754543af905583ccf1851aea6c25e1f0f2240dadbe6a97dfcaa432d3e946c"): true, + common.HexToHash("0x6f74f818bbc870cdfdf6f166fa4107ea456d3515c1f5c0cf214de4ab8d8b1906"): true, + common.HexToHash("0x27fc9f03ae370109226a4411e7f2336b26ccac6ea0dd867a6319232640b8c5b9"): true, + common.HexToHash("0x4e0cf7bb3564a0b1761948d9850284521cc7fad89c596e8e5e53168d0eca2214"): true, + common.HexToHash("0x001f75d2baae4c8a4f689e97e9e4d7a287c407424e147bdcf09edc0dd8b542cf"): true, + common.HexToHash("0x1ffabca521d99637141452b9bb1c90edf7d231af89bf0b4229e66a99b42ce832"): true, + common.HexToHash("0x568b548b9f44b4824f2717a9b17acdfc15fac3ad64529f8ff0c6dfc029400093"): true, + common.HexToHash("0x660cddcd8c7ce62c2a6d2a4e02bb570899fb54f2762ff0ac025b8cef7cd89c4d"): true, + common.HexToHash("0x2d2909ed7da8b76f360769dd9b88e78168d493e127e0a90704203481ade8c816"): true, + common.HexToHash("0x1322da3e1463f6e258c5f4c0285f2c587d5e428686349bd5243b77e468ea97fc"): true, + common.HexToHash("0x5e1ea63a4d3de6605de53172af0b5a82ce172a83f4d8357e06c1f22e8b9baaf0"): true, + common.HexToHash("0xd357dea2db3e60f57991161f165f8fa972cb6c7f98b53ea92bb778b1189ba75c"): true, + common.HexToHash("0x35cb8d64a35d770d52956720c728b239a69653baf8867a60eb4bfc7de9734b34"): true, + common.HexToHash("0x18c902aa05d29bb34939724253709817a5078e03689404a19ba7d33fc9934779"): true, + common.HexToHash("0x9283a69279863dcce9a391578640736820aee15efbfb8bfc8f09cb5a103f53f1"): true, + common.HexToHash("0x35e9413efa71916bfb8cd5ee67afb192d2c01e7e2152a04d4e7d1436cf9cb366"): true, + common.HexToHash("0xdd21fe9697331f388fe63a46e2fc76a22fb7dfc30a2bac7e9b838be655804a22"): true, + common.HexToHash("0x81268c9831630655e9bd718d0fa60ef8da9f605e2ed3b7aa1eb511dfe3acfd96"): true, + common.HexToHash("0x657a6feadbf46bc8d7d957e7744ef149f29690facf46e6e1f5be2a6c82e70b39"): true, + common.HexToHash("0x854b6e3dbc0caa8ef5b71ab45e410b735b292db7413fe6bbbf847d68cf93036c"): true, + common.HexToHash("0x2299a499bf9e83451c6b277adc135f93fbb634e97120f9e80c4ea9a0c192da02"): true, + common.HexToHash("0xf1e91ec20d7e1c026a6164329bbd243b760952d2066dc42f8123790c2435ad95"): true, + common.HexToHash("0x1749365486208bd527d3d3455bf539d067e674ca269c30ed14dd5ba89ce2937d"): true, + common.HexToHash("0xd4ce26e49a5d8da3e825161e2e4fa8599b6b4e142f3af3f720464f2188838d3d"): true, + common.HexToHash("0xd93dcac8388d3ecde809dec8984eaf547f631a573853f5b23ae13051ba4b59e5"): true, + common.HexToHash("0x580e764f19b1bbb656f7a21125e050cae4524118c2059fe7407d2357136d644f"): true, + common.HexToHash("0x662e9d3335da8fba22b1eddbf638ed1f9d02a7a71452668c83e6724990124676"): true, + common.HexToHash("0x55037dbde6b37c733fe3f00af0fcc8922417b09ecfeef2a536a409008c4081c6"): true, + common.HexToHash("0x1c8f46639f25aefdbd291b156c24a32f06ae21c5bdabd4159c6f5838b52534da"): true, + common.HexToHash("0x452a56397f7a9001be651ae731fd827977e1e61c49f04eec5b9eb84bc27118b9"): true, + common.HexToHash("0x18222640f4e0c943fbd3dee1a550b132280f9f05c3d8c58c067ea5df80ef9194"): true, + common.HexToHash("0xf290ad1c0ea3d1f0b0d2def1765f3ca0671b06bcfe12d82185514230507afed2"): true, + common.HexToHash("0xe008429dc32d7213fa5af8c18162d9fd060cc705d391da0c137c2d0d6b45481a"): true, + common.HexToHash("0x12938040e27acf40759b68a5292c5cf15251654132d3f41408381b6d2d5c25ba"): true, + common.HexToHash("0xd76131c02bd1bc5aa944e339bbe913131448ce0b5f19273d535405ac6dae8c99"): true, + common.HexToHash("0x781c31e262a99a55fb7970256347fd1f112a6c1dd0207f50b85973c83c469958"): true, + common.HexToHash("0x7e1a1c72470e17b953ebd03824b30d1701ffc384ce06bc7c8ef97840ba19d956"): true, + common.HexToHash("0x4896466c97e5ab1242d671dd3bfada9b4bde77a8a0502c81953ee66771c6efbd"): true, + common.HexToHash("0xc9d5ab1d200da542e57a8392c8accabd7c7ec902fc734ec314dab23f93aab30c"): true, + common.HexToHash("0x21ef1db10b1b4b4ceed10049347ef9b577d05944be58f489b90a313efc230d5b"): true, + common.HexToHash("0xb97ca415ee8d96e2e4ac17d3e73bce7cb04a7e9fa173f4718a78b5e01093846c"): true, + common.HexToHash("0x924bee3cff6d517fcc2c869c02f92e0a0544408d1dd5850fa271583f528ef37e"): true, + common.HexToHash("0xaf5d67064b6b81f970da45e9322f783472fb7b2d672492440c3692b4acfd80b1"): true, + common.HexToHash("0x9e647a0b9c0e59418eec9e5bdb0a0a9cfa567d5353fe00b2476c305dd4343209"): true, + common.HexToHash("0xa010df5328399664988c4cf5124b0202d893afce21808a7ee4e0734902cf9dcd"): true, + common.HexToHash("0x66a66ed6ca594b6dc8618080fd8fc90cefd0aa89f2f56a5a6078e9ad90a300fd"): true, + common.HexToHash("0xffdb97c92d3273c0fd0be23b9142b49ed830c5453935b230e736aaed973a2c0b"): true, + common.HexToHash("0xc8a95e9f34a3c5bc3cb47f3b3c5ce9d3591827024db28b0cdaff71fabc6706fa"): true, + common.HexToHash("0xffe61486462f1a84894eb55014debf71a965aa24303d45cbb0cd63136a54f384"): true, + common.HexToHash("0x68339d1244ba9fd79a351772d0a07587777f55286f21abe7b5ddbb7d5098301b"): true, + common.HexToHash("0xc74d7e1f14b1e238e533e8864c9e108aac1d44307ced953bd562a36dd7bbdc73"): true, + common.HexToHash("0x549a8d12ba4e7a7e782f1ac76684ba23c30cfb793cb2a90dbb2a38d9904bda92"): true, + common.HexToHash("0x22143d01e057f39e27725bd3c912866a8b462d7ecd806913660ea5e582a6083b"): true, + common.HexToHash("0xc28707a45f3fc6c322a2882b1870f01a6a07fce60ad257d8ab27f3d3056d0c70"): true, + common.HexToHash("0x6bc1b7f327f8909f14d777e2ea2f80fc10eaf4090684f478486e535105d39345"): true, + common.HexToHash("0xeb089d06e5710d39379bdd6bd11313df4d94342286d9243534dd22fcb12f21c9"): true, + common.HexToHash("0x02329f9443c033566882959cd1ff8f6ae82c0b6f6c5c3f72300989117726bd8b"): true, + common.HexToHash("0x8749e0a29793e36e41542716250c6553f31f2bd453f6aab8154a260e19c7a5f6"): true, + common.HexToHash("0xdecadc4427887206adc363657fe1022b0c59f7809271867f5d0a3afa6f754109"): true, + common.HexToHash("0xcbb7d1efff2400ab04e6f64954fd312a2f19df162b0d1a1decc2c9bc8966880e"): true, + common.HexToHash("0xb65f4a1b452ef31a1d610ff2cf5dda4d92f12237cdc195a092b4c14bbcc7a3ca"): true, + common.HexToHash("0x7a335dd6f37050df220287a9dc20cb47bc660b11a14e50dba22ca4e5a464c568"): true, + common.HexToHash("0xef938910f752fdf1883fd879adbe1050355d593fd2ef424efd9cc58c5b49ac89"): true, + common.HexToHash("0x8f7cd7c2405de596a967449f3cadfcf672f57d7f2b2e24e8537ab92000e75631"): true, + common.HexToHash("0x9bec4731dab1cb2b3571d959ed8fc07fa3fbd87ac111684b00878f1537b0ddad"): true, + common.HexToHash("0x730a2f6ef9b6b8a4f703c57a2c04069abc5875ef5a2a36262a7ffba5d70ce2cd"): true, + common.HexToHash("0xe0420afb6fd94b3a008c8561d2853d4b542a6ebfcbaadacf629655d6c7d93479"): true, + common.HexToHash("0x8f4a14bb0484b71e9ea16347d995aea337e865ed3d799224eefd20608ef62a4d"): true, + common.HexToHash("0xac30f0d156ff7eb6ff40a268d7799cc2490ea8003cc5590bf6e5dcc2ce5d0526"): true, + common.HexToHash("0xc9e639d695e60ea8e7365ae8b47062f358e2f3796a12410b7b7ab968e27a27d7"): true, + common.HexToHash("0x55f519f93539f4da2143683749954f853561036723efabc43bef33ee3c115083"): true, + common.HexToHash("0xb90fcb41bbbf2e814aea54052bc1e4aa7d918cf208287aac145b5821c1c59bad"): true, + common.HexToHash("0x48af4489c5b21103ac398036b1492d3fd36967a1958bcb1c658f9d2fc26f88e1"): true, + common.HexToHash("0x0e51093ba10a891a0e3f40dffabd001ba2afd8e15cea21598c667a7a1a84bab5"): true, + common.HexToHash("0x33ab14ee21728a7d4919ec924f086f84ca3e2eac0894e289990bdad0cb5a1d18"): true, + common.HexToHash("0x75a6ddc64eeacb083a8c894e4f28b9cc7a0eab6c215e603c61b70ae7497b07e6"): true, + common.HexToHash("0x853eda193f5d67541efbc436daf396b389d6cb466f9d449fcd39bdffd990008b"): true, + common.HexToHash("0xa42bc676731d7484948a82370f0e92c937949a0b7c5d1a68f3a76a415e539e85"): true, + common.HexToHash("0x8b088a1f3f61c3e878df877ed8691823bcc4d7a12fe6ca0ad3d499622ad0090b"): true, + common.HexToHash("0x944529e7669eec534a09b83e238ab7840ef9b8bd142c7274a66fa9fc0a19240f"): true, + common.HexToHash("0x66fe5a827f7b36673baa976ff490632c9cb84159684137cb8aa9b6d222ce97ab"): true, + common.HexToHash("0x1b4689f550a41415f2e69f105494b85e4a8283cebe2adc7f3267c833c0559481"): true, + common.HexToHash("0x90ab2a2f994a7039a97d970d15619e7a9a4d06fe2af36b31dd7d439b5b0cd225"): true, + common.HexToHash("0x691ab2507b0095a0457f69b37bd7108c96c7a6385cc666ac9f16d5c151904ed7"): true, + common.HexToHash("0x6f104772e9919080759a563416419af372f48a7d02d5aa1a3af47b989f5cd230"): true, + common.HexToHash("0x84c7d246a99cf1e380a27df6a1ddd6352e2177a1d55a3a260c962c6ec741363c"): true, + common.HexToHash("0xd3f8c22bfcec9e4aee84cdd4aa6155587e907413a0a314faa9950efcec2640eb"): true, + common.HexToHash("0xe4d61f5993f752c401d068413a5bbdadcb05035757b561cd2027a453b3f1d1db"): true, + common.HexToHash("0x325911b7dc2a995f9303c9e120d8b5452e656b802be452a4a1a35c44ea4dc05e"): true, + common.HexToHash("0x999da7eba9bc5f25293d29b070264bc680d6cbbd26202c08248a13a617914b82"): true, + common.HexToHash("0xc3361405881971cb25dafdc10582e659f184f2f5a0434dae3b92b950cb7bda08"): true, + common.HexToHash("0x6adcc81d8d0d55513a1b2b2bde5dc557f3a1b40782ec0228981bc9a2755550c2"): true, + common.HexToHash("0x1e8e1560f32199b4748eaf9ca5949014c1faf229b66f71b366eec0c3a7cbf6db"): true, + common.HexToHash("0xe558cd8bccf35a212d0c7d3a2f8a2e35bf6881488ba723f4da40bd87aba58924"): true, + common.HexToHash("0x5b1761fd464fa676799d3cfe9f2a204faa08f60a6bfef5b5df09897cd8b72c6b"): true, + common.HexToHash("0xcfb87b50a7730bab265880ec48af75dd77628c91f2b33ef30d2fbdccbba9ec70"): true, + common.HexToHash("0x005efedd50703ed3252b5b742896f20e27255d1b35cd60bc9c132dc36ad5a37d"): true, + common.HexToHash("0x4e8333b74ab9d0a1750918cb6f8c250482c6a8614afc4ee760b3cc72bd680f65"): true, + common.HexToHash("0x334a5572ce87263d45587b9367a8533b8a64eae8814b4566074dcfb237940dbe"): true, + common.HexToHash("0xf0345044aa81e4e1a23c7061a3b0baf690e16673fb1d0d123555f4309b4c506f"): true, + common.HexToHash("0xb2d58e67a871cc2fbf9cb81c55b3ae8a5854ecd86230ae219f0613bcc1954ddf"): true, + common.HexToHash("0xa850b275f9b1e94043cb3321f27afe26ae446c9df2db46ab37d2e5e594476453"): true, + common.HexToHash("0xe578b2d54eff0ea272b992b62d1b78236cfb52067d1859bf9641e9e4673db708"): true, + common.HexToHash("0xd63cee2eca6e0536b4d87ee0d32f0ee42920f31adde850e92b2dbe69760efc4c"): true, + common.HexToHash("0x0af8dd4bf4710b0970b883ffbc1aa9dca2e4f09b9ad827c6e5befb4434efd6d4"): true, + common.HexToHash("0xde986fed7238065ffbe04ab5737723b4ae67d1e050f82ffa4376894301e9f085"): true, + common.HexToHash("0x81ba884fff5db3e1e2c2547d0d489679a7afe24b5d5cc407f4b24e2f100753fe"): true, + common.HexToHash("0xd0c9786bb057afc057c42a63036c7a6425933df3f38b843a11709d9e37cb0a9a"): true, + common.HexToHash("0x0388fc130e843d1413750160933764855347e7712ecebad6b17b657624541950"): true, + common.HexToHash("0x6c6b83c73789ab071d2d4c35735568d1eec094ccf9c54d3455b40c4b3084f3bf"): true, + common.HexToHash("0x2606a1a80ca9a4876d13c8caad651f19730110d673865001f03f3e24274da738"): true, + common.HexToHash("0x687792d2cab7adf400fa2d6ebcef7de067931d52dae717aa2b0c01d1e89c50f1"): true, + common.HexToHash("0x75125d8835c08e41eec32e0b6420bcbd107ed9cd52eec4b302aef936843c82b2"): true, + common.HexToHash("0xfc93a4613fef894febf09a8f2b8262a659744e0df0a626c0a6bfb2e01bbe8e1e"): true, + common.HexToHash("0x8dbca4929a1625fe2161a9060a2d7e77f8991c86f50e39e77007b7009ff80fd2"): true, + common.HexToHash("0x3b24b80bb03776a138de2febf62e7f2dce723d4e3003997f7b245138e044076c"): true, + common.HexToHash("0xdca3a33a4517aa80eba5bf9c37f8ae7a478cb44a6df9bd2ef0ea70d7340e05aa"): true, + common.HexToHash("0x05140c5c7a5a048c549e2c03a43974fa508175190f70a40b34c5e318fcd50502"): true, + common.HexToHash("0x30828afaecee7cc0af583a0307f005c2eb6d27b1364c038880070e02e74b4d1a"): true, + common.HexToHash("0x3de1778f37679b42edb0e67ee65364d7fca9bdfa7b59a905b1eac66c03cdf851"): true, + common.HexToHash("0x7e63a75fc88c07e10fd2390168786d78709fb163d6bf8ece79be0b0be3b8e49d"): true, + common.HexToHash("0xb0621a14b69e8c9cbf55b1a65bd5fee653692a9d4df69a975aae1de77378b533"): true, + common.HexToHash("0xc68bd3981d4e43a2f7a83dd55ebb5a54595f3ca51899cab24a2097a7e5aeb0fa"): true, + common.HexToHash("0x92ebf9f8007b3df5374572ba49c7445f41f94bd14830f86886c7df1e34b6ddb6"): true, + common.HexToHash("0x544370a0934da5536bebdb5ac0ce89a688489777ad12e79514179a8c6f209e6b"): true, + common.HexToHash("0x2d615edbc619167cc87938069748f02f0174cbc0a9462812d25e9e1643316448"): true, + common.HexToHash("0xcb5e6c087ed4105cd77221e48e199307691bdb7aa51275bd3db7be8d120e4dc2"): true, + common.HexToHash("0x2f18f629f58bac44c2e3997dbddfd683295c3380b127e09a67a967b17ba0e445"): true, + common.HexToHash("0x1f940a37feba62cbd0fa2bfcc3f6b0426d274c069ae85d743bda955f0681f434"): true, + common.HexToHash("0x3103e73ac2bd65aa68795779602126b520e0d36df9c4748032dcc58330ec1b47"): true, + common.HexToHash("0xae16dc55f4c7d605bb2facdb16e9c2c80bec51f1513cf6bdc0234ac4cd972e88"): true, + common.HexToHash("0x1f4ccd1086641d3d0a40ee198717bfc12bf6322e323c2173ca7ec2c21e46dc06"): true, + common.HexToHash("0x2f623530fe41907305fb5738abd6f6d6462f2bc520fac169988266262a48ce9f"): true, + common.HexToHash("0xbe3c7a4227b390d8479d07716fc69f12f0f9ac40adc108f4ef6d715d5b71bb40"): true, + common.HexToHash("0xe91145baed4c108ebda0959263b994efd856e7b805fc981beb29bf828ec8b061"): true, + common.HexToHash("0x0f4bf07d35d887813352e32c29b8fd0f8a36947303f74a1291a688f24318e57c"): true, + common.HexToHash("0xebb3ac94f8c691f3bb6db49a0a7b38da2cbf16592aacfd6f4cabd5db20d7c7ca"): true, + common.HexToHash("0xcb7966cc4fbc768d88d51f411e0aba353773daebff5900e84773a04ebb204e34"): true, + common.HexToHash("0x1eb7f95c821072e6ba31cdfbbc7a2007902df87c809f3e169ae5bc7cf65d8407"): true, + common.HexToHash("0x09446d49fa203875c14e681d33bd9f39e020efcac054f1b980fcbe556f581f76"): true, + common.HexToHash("0x72795ee9577ed0875befde47ccba74e4dec4ae85ddd988c35402be675b42bc3f"): true, + common.HexToHash("0xb9dcbbbdf9c5ac58afe14cc7a71bb70afbf37a0b216a7e69c579b4b535b9a45c"): true, + common.HexToHash("0x38b947e883b2cc5139d1f9375ea8a065aca59ee086ba54fc2eca58c7c2538a82"): true, + common.HexToHash("0xac6bd289ba038a4165200fb498e8750e5b679e1be9464b475a1bd67e8b59924a"): true, + common.HexToHash("0xfeb54023f47074ff3803485226df87a5c0e50f3f2c0eb2817f68c3739401bdc2"): true, + common.HexToHash("0x37d7d4822388a0d69e509dd2276c51f2a0e26e5fd0a3d357597917e4e98d9f57"): true, + common.HexToHash("0x126abba68607aae9ad56a10eae9a107004266dcc5092acca193d8d5e3d97e4a9"): true, + common.HexToHash("0x80ddb3601f9a9f71673ca72119e216bde7324b0239aefeec3e84f9967e94453c"): true, + common.HexToHash("0xa01f543207b5e79ee5deb0628e26e545fabdbc7e83bc5f83d407bb3a9430cda7"): true, + common.HexToHash("0xc5078b0f4b40c4d2a74bd97aba25559c49456a653c99782dec8cccd38f9e635b"): true, + common.HexToHash("0xc7d1c668631bbddda8d64d4dd04068fe2bbcd99d9ac2ea94860bbd5dee21fa46"): true, + common.HexToHash("0x9e5e5e82c0b72816dbf2fb3da9921354a66a89cc272d20fb7729faacc337043c"): true, + common.HexToHash("0x6b9a2bc7b273e934e40fd85c0de41e0237e5ec9afda1caf91867b606cbde4615"): true, + common.HexToHash("0x109b2453018485e563f689fc6e68af55d27a5886b68b9deaf819339975547114"): true, + common.HexToHash("0x4d2bff29493c5074d0f5b3cf276525b9ea629647164a250afeb4fbe6b020a88d"): true, + common.HexToHash("0x114556a39b8a33df8c1bcd257b36bc9eed72d14d50d588586bdef16e8867780a"): true, + common.HexToHash("0xd62c1307e3856bdcd0c10db8f67b5b8352fa3931bdc95a7d7d400d2dc46d2d30"): true, + common.HexToHash("0x0119c7688fcc3a631bfe81932b4171e9e226cc611c85a012a8218aa569398704"): true, + common.HexToHash("0xc869495e92b9b3a4d5df8bf27730d0f6a03c677013d28e32467cb76a19e61577"): true, + common.HexToHash("0x997969b2c70143b2418757b86a6fcf002a83a52c4ab58c0758a4f1f5b6744d83"): true, + common.HexToHash("0x7fc58255a4d823d10c3097b970b001b455fa25e29ae47bd6df561b6d160f013b"): true, + common.HexToHash("0x9a1cc157f165f7a353afa95ab726a515004e26ef907d736d695838c0ef6669aa"): true, + common.HexToHash("0x6e27dc907a5e41fb6016267d59b6302885c7062bed5fd0e78d4c93afb99726b9"): true, + common.HexToHash("0xc0f001e83ba290ddd10f26402d4372d5ed6411a242f4cc6db45d3be2d44f0338"): true, + common.HexToHash("0x307ef23e56f3caf70399826722f99cc10c5cde411c4d068c6699bbfb4b022e7f"): true, + common.HexToHash("0x179fd1a7b71860d8b5c90b81641cd6554ded4ba8fe6bd2da3543cc78501266b6"): true, + common.HexToHash("0xa929e563ae689fe6cb44d1b8fcf4599fa02927f39789b3ede2ca0614005a684c"): true, + common.HexToHash("0x6e1bf20751923b45538e051406f4205a1e3d672ff89e500e6814a4c6ac9fd855"): true, + common.HexToHash("0x7f304ab18812aa98ed10a1c9255f7d699abd5cb9431f2cf860ec74e5b36b7718"): true, + common.HexToHash("0x005328f84870dc1ab7c0e59ca65248d5ed8cb0fc9b82711c5cc5a124543fbf59"): true, + common.HexToHash("0x1d8daad76af3ac1ca1300d1138e74661e0d3a8e7313632174e6362e377e2ffa7"): true, + common.HexToHash("0xf380e8259bd30d4dd4a6cb01c824b4b980d8d8d1f57304cb9843981570a316e9"): true, + common.HexToHash("0x22f6f8e1cfad60b13cf399ca29679a287ec240f9a710da4e124d3e42727c844e"): true, + common.HexToHash("0x1bbad858ebd511e74a30ca37707547d43f72fe987ff167f8004fbed2118a8a81"): true, + common.HexToHash("0x2e4e671ae15a11a33826107255431401f82b25e30152dd7abd2c30df8a01746a"): true, + common.HexToHash("0x07ddc1f6b581ed537b072d842dba1c0f0ab6c34e3cab32b596938856a540fa1b"): true, + common.HexToHash("0x3dbcdf16ad75aa7166227cb5bbafa68a1a8b657ad83c8f447a92d568aa873981"): true, + common.HexToHash("0x45f55bac1ea33c3dd287f69c1d7d25464891b593cbafd569544d293d93ff09ae"): true, + common.HexToHash("0xd5e33a7f615bde64e4bf23800149adf8cc3c08be50815c69df2d26f4b4ac7dd3"): true, + common.HexToHash("0x6db8b65bd0cd04a9bbcb09851d207bfb880cf447e3541ea2cb94f55bf550086f"): true, + common.HexToHash("0xb1e77ccf11840bb626cd5bba5bf3671da24c33ff304da3a7bfcaf247538df20e"): true, + common.HexToHash("0xc25fa2d07afe60fb2e6eadd9e6d473fd5a0b8790852e14c421cbf675aec35a93"): true, + common.HexToHash("0x3ba975c6ae44c0eca522cc79e20b38590bdca3c988a62ef0010d2090674f261d"): true, + common.HexToHash("0x99e0e0dee65835036ce7eede5f405e52fb220649f751883079dd78404c5256a1"): true, + common.HexToHash("0xc35b247352c7eaeaaee9148640ca7719baf735f427e690a92577d57eb5762811"): true, + common.HexToHash("0xf6151d9c0bbf57e519f8a9188b060d800d9f9454d8c9d170be125ba090c5876d"): true, + common.HexToHash("0xe250021dffa2991f7d86195fecb877da92d9f5ee9100a18baffa047f703ff6ad"): true, + common.HexToHash("0x203c77ae7b82e07c44e60335003ec4fcf7d972c514a85158dde0bd7d02882223"): true, + common.HexToHash("0x35f8477dc39b15359417f02e1076a924135fc41c64247b05d1cd8a2120a29012"): true, + common.HexToHash("0xc399e3c53408b1d079677b361b19c8b5426eda7b4a74aeeaafe40e580a1a6ea8"): true, + common.HexToHash("0x39c854c8a2e376c12e55ec1bd723a6429cabf5d61695d3b062253672e8326687"): true, + common.HexToHash("0xc2f0e2254e48154560342cdcd2a11ae487e4d5d565b27ddd55d164f381f92933"): true, + common.HexToHash("0xf0a20c0bb3da44c9fbb18f85730da0c31e7077c4ddc0d6e2a417d108d9ef228b"): true, + common.HexToHash("0x5ddde5b59fffc17b692f772d074c619b25a4455f6bee8fcafc2a4137493a8284"): true, + common.HexToHash("0xfa31f070ba5ee6e90c94f59fd2b53a7663e91b9c4d6cfdde8c52747a10229797"): true, + common.HexToHash("0x35826109e33193608ef9c0e94878e398202ce3d7e651269992f82ad8273fd77b"): true, + common.HexToHash("0xd340c04a53c88a59be1d90d4b1208c68d12ad84b99584905c8457fa694900c2c"): true, + common.HexToHash("0x3bb95f2f565caf364da81e5b78ccc96b5704a8e804523d348e42f1335647cec7"): true, + common.HexToHash("0xf767f15d66f683ad2c51305da77b0080f0bbaff9c4e3940c925261080df543ca"): true, + common.HexToHash("0x71ce829bc4adb8b94b06acdca9f760ee701bf17080df0f1e40fbcd6c34373c77"): true, + common.HexToHash("0x1d871205aedc16b3202d4d2378b45a069b28a861cb7b1fdeddcd0613646fedb1"): true, + common.HexToHash("0x2dfbee282487cf15ab60760c185cadc9a0ce0875b8c9563096b4eb34293e7d1a"): true, + common.HexToHash("0x16e0615ee92232f799aac90674bd8898f56420aea16b86f6c6796c5636a35bd2"): true, + common.HexToHash("0x76a2c250c253c6379c3d7db4bc8b4cf8116eab0823277cc6801445afbe311723"): true, + common.HexToHash("0xf01a3c2ce7158fa09eba86e60b4453d85402a6d95fad4fc72ed7c4e091d36bee"): true, + common.HexToHash("0x64fe5526bd473ae730d589cc39e303d9d33c96fa240844240205a09cf7ecd7e2"): true, + common.HexToHash("0x83e9cd8e83a7d9d598804c95bd0ff836224a48a972e42d8ba1e8dd9f8917d90c"): true, + common.HexToHash("0x57d30981668192e73aa4b0f1be18b8a93d31f5b10e4a9aefa2b74dbe4e03e826"): true, + common.HexToHash("0x77217b58d712492da1a4cb4ca805e6b7e8900f29953cd397585f18868b495cb9"): true, + common.HexToHash("0x4b3931dcf52b828e3a0e92f36e678b006a9ab74f5e970b1069866a688b45076b"): true, + common.HexToHash("0xee5783814443e5070ddd0fd3d2cd2b1e60a7e05ce764d8d199100d79fb6c669f"): true, + common.HexToHash("0x7f0aa6ecdd3ee4d42cc895cf25397c02fe9eeb28db62c5d52fe8328f874f2ed5"): true, + common.HexToHash("0x8eef149eddfe80d3f8a63ee5c2fcd33db9f45b10ad03e2daed7991e30f3a24aa"): true, + common.HexToHash("0xbd3d264fff52cc23be949e0118abbfb73ead81cb8c99b1b2dc1b92f551132984"): true, + common.HexToHash("0x52054ec0263e344a07c5c4ad4ffebcd1f76885792bee361012adcccc93e4c789"): true, + common.HexToHash("0x03d596fa7fefa826a1eb8924d425c37fd8393b54f35d91d3b9618d37be0ec3b6"): true, + common.HexToHash("0xfdbd705b99e86cdc6c5dd09ec3b1696e50ae329a3600b19668d7fc56e986dc6b"): true, + common.HexToHash("0xfe9c968f456a0d3089d8264abe46f5ea271cc2e9f964d52725fa809bf36a708f"): true, + common.HexToHash("0x69732af1e33cb737ad0c4dfb6f75aceca32199441c21c30641c39d6b29056cc6"): true, + common.HexToHash("0x6436082f5c2789facae67662ced451e51f4100eb7fe4e17165b3a15dffa4da0d"): true, + common.HexToHash("0x6397981a1bdf06d85a897bcd10fc463e4b9db2ce1d41dcdf8a8aadc11c937ad4"): true, + common.HexToHash("0x33962ce4a6d8617a9513bae389d4b9e38cf0f574105db5df6c507c341bf19858"): true, + common.HexToHash("0x6d1faffc720fee5a58a2baa7036368a034344f26ce27fe022c7a273592f99384"): true, + common.HexToHash("0x234db445382fc98fc99f6360ac642e5ab70787d1b0f44abeb92698ea8cf518dc"): true, + common.HexToHash("0x6b359d09cd92e01f7e158f46795594f4febda4509326c3dbd4a42010947a74b6"): true, + common.HexToHash("0x718148c6330d03adbbb9051b3b0e450ea2f76c56b0487be5a510598e2403234a"): true, + common.HexToHash("0xf2e6103fce0141269eeb71c1c77fc46253ea7f904818e0335afe6bf993f4a6fa"): true, + common.HexToHash("0xc3a02acef0d89e56eee4cb30846640c6b8b3f5f63ded43923bec056589c0fb63"): true, + common.HexToHash("0x6c42071bf4e0f827147a42fc76efb26b5ecc68920db13137cade5cfbc025c3eb"): true, + common.HexToHash("0x3910bd554ca0fd4966cc6e87dbbd0c27b1fc4243a2966ea4703b753bc1edc626"): true, + common.HexToHash("0x64a7e9b5848280318e30bbfcc35a93dc7c7d2b52307de6d162b2106b0b6823d6"): true, + common.HexToHash("0x012a20676dc98d29b0c77fb6b26b76b9249412611790d399ceb4ceb5d764b713"): true, + common.HexToHash("0x28b51433cec864ddd7a41e380205ba83e608451596cc1c9ed0c304fe1c491593"): true, + common.HexToHash("0xd49836d2f8a04e8ebe9a78ab4cdb460292cc71e0cbc93e26d8f107a865bd3202"): true, + common.HexToHash("0x2698839b17e503de50cd89617e48ae17223d7846ff37431e719787a5a56d9691"): true, + common.HexToHash("0x33b7bd22fd32d343a1a4c06dcf07d62139de6e4c16ceb597fc5140c24bc5d40b"): true, + common.HexToHash("0x73fff7db87ed5215af2efa4ab4e84cbcb1a3c44fdf78fd57d4fda20b81a3be46"): true, + common.HexToHash("0x6af873743fbe4cbea7ba7ac2c800e84aa1593ae574bba717245bcf8f3682eb33"): true, + common.HexToHash("0x32af5aa24a6be9770be78f7239e0f2197ecb7be3251eccae4d25d110d6f889f3"): true, + common.HexToHash("0xa7aa7003c3a8896aeee97cd93c24d6254c1344e377a71d822a2a7252df255d8f"): true, + common.HexToHash("0xfae9537ef56dbb4d38f997aaaf8bcb0741597496ea5d85ae58492b670936691f"): true, + common.HexToHash("0x2b1165a438623c9a25f129b6f8d978ff26729cc90223a19038c7f6746939202b"): true, + common.HexToHash("0xc641aa88a0fe8a2d36d29ce23fcd87bf5a0473c338f6d0f75b2646efb722727e"): true, + common.HexToHash("0x65729195e212730b8aa77ae92f588a746d9a1486798e04bf1ce7cca1147c3941"): true, + common.HexToHash("0xb9b669233fb2c8741f65e90fd50e313d214be4939f09dfef275c57228bcaab99"): true, + common.HexToHash("0xe8a2b3372452c58b5aeb7ce9cc5adaea97f5067cbe8d0406ce45b1384d0bb1cd"): true, + common.HexToHash("0xcdef088cb30908954d3c910a46fbc173d522efc4f0075518ce8c9b66265340f7"): true, + common.HexToHash("0xa33489e091cfe44b55af6a5d4f18996c664bdd4876a6464a699a560f8afb85ef"): true, + common.HexToHash("0x732d730e061931d8eb18f5158a28692b6d062a7cd59fc33ae00c639b6a7b6f48"): true, + common.HexToHash("0x99efdfc3d9c9f0773a15fe70a8ab52dca5981d82a393e411a29709d832be87b9"): true, + common.HexToHash("0x20450820c0ebff9edce7584a5bd38602ea41171ba7e5446d406fea0cae30d95e"): true, + common.HexToHash("0x02a1ab8efe76fbb67bc56610503c359be801062f87757934002e1e0a5a76fe08"): true, + common.HexToHash("0x565a385ced3c863b127ba4a5152acea4a37a1951cf0e99795addea7310920d32"): true, + common.HexToHash("0x578eada9dae6d74155ba865561772c888b3a207e39d126759886f2563591cc32"): true, + common.HexToHash("0x12cafeda0c138c491d4a120c3607cc52e5a74149faafeec384cdc1774aa9f4cc"): true, + common.HexToHash("0x5a4dfada60a0924278d436159ff70b20847c5fa9dc0c91c217c514e57e276323"): true, + common.HexToHash("0x021c2c990f21482ab4b313fcfa1b894905bc64ff3cf00a3daf928fde83877c0a"): true, + common.HexToHash("0x0318637ff57300c1f6bde2b719799f0071d40017c039be407e65366952b33344"): true, + common.HexToHash("0xf90c365ec8f843445065128e87d28994fbec47cc51311424bb3604991a2838b3"): true, + common.HexToHash("0x12e30bfc2457c43fdeaa91e0e7e39253c29aef04c1eecaa83091a38bb680931f"): true, + common.HexToHash("0x41e2fa3e49f174bff3c82a309130f365c23ff0f89a6f7ea4d42a4f7c5fcedf4c"): true, + common.HexToHash("0x7ed1b91fb0cc3b2f3b850e820d205d15e5a8205ddca8cde4e4f3a627032b3b7b"): true, + common.HexToHash("0x18d332be57ca270532976906a239d2dc2f8c4c0f01ed9de8df4ddee3a7ebf86d"): true, + common.HexToHash("0xaeb71cf69312a0f8aa1abda616b8c9824c2a1843cdde5ddaac1264a020ad128d"): true, + common.HexToHash("0xcf813fc30771c0849e8cec0c1197fd901e79becbcd85d7ccc2fdbcc3916f7070"): true, + common.HexToHash("0x664ef0a175e267f48a6e45311640f3227f38bb80c18da15778d993b975c3e40c"): true, + common.HexToHash("0xf3b9194c6ec8d666e20ebcc525355a9bdbb212dbc0fac7c3edc09d464a0eb3a7"): true, + common.HexToHash("0xcfdf32abc166ba0769eb4de84d76de79f537394e646fd480ce9c6209431bf3e3"): true, + common.HexToHash("0xed3f93b80c2bfbed36d8ba188299abbe19e1ca5cffd067f4c0d9ec6aaff1d470"): true, + common.HexToHash("0xff9e44bb49f94f87b46b12e048555ca4ef3e99b42ad2a873a1d0238cf2f28d5e"): true, + common.HexToHash("0x8e098b0c68302cda657ac0c54af0b827cc8ea74b942da18a4614b3d94284036a"): true, + common.HexToHash("0xafe83c3e423a4c33413a663c1c30949cd5d3dbd3d5b053e8b83a2457f08d9b6b"): true, + common.HexToHash("0xb7968dd0fd57cf3a444f7cb2ee5d8e3d2eb60ba6396ad342bbd126b7fb020305"): true, + common.HexToHash("0x3a8452993661adc45ca9b02be417d756b7c1ea12a29f2ce1c5be9789f94bf43f"): true, + common.HexToHash("0xa949d17fba5c36ddb724c8028afd19e488c69f1ebccab1f11b4a662dacd61dc0"): true, + common.HexToHash("0xbf8a9cca50acb2f7eb68fb0bcedf855438bed62a243f61cccdee5825eab8fdf6"): true, + common.HexToHash("0x1225d7132e48e7cb4b0b587956d446e9dea7c57c7cd14d506ed7bd30f4f0ddf3"): true, + common.HexToHash("0xf3e3e80f339d493962730fdec1f46e2b7f150c0a8eb88f0dd1ebc127c2cf538c"): true, + common.HexToHash("0x779410602c6c394802f6e65d3238c749d39aecdb0480cf34f8260b1a622c06e9"): true, + common.HexToHash("0x7687f18df2b4b669336d6bc09361b4b429f63bad1011d815cb3b4ceca493ba41"): true, + common.HexToHash("0x108531c31a6f1cd3ff4aa17c69f1096f3d81c3bc233bd5195c63c0f6d698c6ab"): true, + common.HexToHash("0xc7a97f5d66921c22c5fef7a5b8cf6c0117987ee34c39fc82cdfa043c0fac0495"): true, + common.HexToHash("0x9932cfb74e71ee161c5ebc9508945653445e8a35e9dab15f4e5e511249cd4ed2"): true, + common.HexToHash("0x243be295c6f70c37203bf7e9908565599798e873f6f80f6a9dedb59dade27b94"): true, + common.HexToHash("0x85218959b79b29f3ef21469690cdf365511899b0b07064563eb514c0af3e498a"): true, + common.HexToHash("0xed16d70708d3135438a964015087f1421d71ff5b5c6e261e71424896a8d20e65"): true, + common.HexToHash("0x1a92c3074b87df0e2c72e9aff300bbdc8a6bfed885805df028d08c27e2e93710"): true, + common.HexToHash("0xabdda767d77ec28d030def04912f0330b63bc6306f40207d63ef709d83d19346"): true, + common.HexToHash("0xa94f815665cc2648ac2f0562cb0c8597921f32b2b2adc0328e29e36703ee1d6e"): true, + common.HexToHash("0x227eec59b6923c335431ccbdb78ad1adc08062da32299947a400dc88cd22c923"): true, + common.HexToHash("0x48331a6bc8fe5a0fac1213f809e1e9c3b0ef909632dd8fabb74e35aa7f4b36ef"): true, + common.HexToHash("0x44b980f57960e7a014cd956482ddddac3e50cff3bb8a00cb0cea4996546b3a6a"): true, + common.HexToHash("0x5b515c41fc1d2d5015ed096fc62edc497126acc7e58da7e3611fb8ab4d9039bd"): true, + common.HexToHash("0xc2f3f9c53a7431656fd2fd6c428762566221fc31752e024939a5b1559bc20632"): true, + common.HexToHash("0x1d18b4951686540e5bed764aaf44e0066eb608bd8c9180cb181cb437abcc7002"): true, + common.HexToHash("0x97fb8d8df304cfb9e14183e0220f073236df3ca55e532e338acb237b5a73162e"): true, + common.HexToHash("0x0d06048e477e2d750fb0fd0077ce27d4191107c787ad08dd8607e854ca55c0d3"): true, + common.HexToHash("0x24d05f3e90a7b3ea33352033291834332bff42fda3134e294c15fefc226776b3"): true, + common.HexToHash("0x8949b7a232be1557726c28daa8275d95958f1cf68886d1e3ebd192d99f470f59"): true, + common.HexToHash("0x2bc8228bbb020657a991b6b7cb7546e93c164e711048dc7208d36721c512612f"): true, + common.HexToHash("0x6c13f500504cbd9466b4b7e75aa3c611c7ae1dc2718f1ab6be13c35ae10d854b"): true, + common.HexToHash("0xde40684ab2fc18727f7a749721bf4c83f494fe356fdbaf44d91639c83c000c6a"): true, + common.HexToHash("0x4d0e054bbd4fc4439395b8d79c2bf3dd499b39d99d9033a5bbee57daefb2e7fc"): true, + common.HexToHash("0xc7d11248851152bc83f1216a3393bab10996a123831ace5da482c880a63e64d9"): true, + common.HexToHash("0x1877b77a5073f1260efebc199c60210660350d05f6119067a1079fb49ba349f6"): true, + common.HexToHash("0x79caf0a9d7c3d10cc6d2f3736ef69d875ab6e8eca8a9223f136ff7078c9ea701"): true, + common.HexToHash("0xbc41518dbb90484a6595c9cb58d0c7b0dfa3d5b88bed52f5184b37f5c9c6f851"): true, + common.HexToHash("0x89eb33b2e667728015c698f54d8a107b2f720e10c7074e477e177dbc45ad1661"): true, + common.HexToHash("0xcb95725be3dae543e1bddc4029332714ca904656c8548b72d21b0eb950423b52"): true, + common.HexToHash("0x3ac374ea4379bc276324c98b6d0ee5aa064edcc30c5156a6a944a16ad9b4b1a0"): true, + common.HexToHash("0x0a404fc3c975e1241efdf23c81721364622496747331eae3eba6040e0cf98c9c"): true, + common.HexToHash("0xb2da7e7a7b17ddda1f98ece95da6a5c2208449fe547cb30edd82ffebcd5fc248"): true, + common.HexToHash("0x9426b4eb4631c6845107b7a4816f740d9a05c1501f463ba6baf264118cff03a0"): true, + common.HexToHash("0x3b3e23b8db6264ea8d752b6ebca90053b08f94c5d8e1b84627bdc1f4c170f374"): true, + common.HexToHash("0xcd4bafe6043837999c5708ccb88cb329f51d6eefe4516e8f39bb92bb1383850a"): true, + common.HexToHash("0x15c962cc73837566a1e411e6f42e4506956171e89d03cee17666bc7ceb8b9ec7"): true, + common.HexToHash("0xd4e4a0b0dc18873758e2fd758d8736d44834378f66b0257a38bc8fb9a7a0fad5"): true, + common.HexToHash("0xf5a7aba0c25064e030571b15ad9b782322f06cfd21cebcb9e5786dfdfa6618de"): true, + common.HexToHash("0xd66034fa5433acc4164139b4c4d4a1f2fe33ac9cb84d30465cb98f4ab7f803e2"): true, + common.HexToHash("0x18aba8ea883d1534ae69f2a46e45933d793fd84c6168ab7655fafa9dd9fbb117"): true, + common.HexToHash("0x619470ec53acd9d28950dddf7e2b6196a6fa4b8661eb31ffa16d49a9ef987f65"): true, + common.HexToHash("0x74cfa12ef674d147c975231099b32dd9074812e6ec9981ee010dccd618c54a36"): true, + common.HexToHash("0xf0ef4b83a23d987d22dd47ee9e24f9a22e92f19839da7fbf5c1b3059b318b20c"): true, + common.HexToHash("0x2c052919ddc23c5d1ea6a10ea122961f18e2bced05636c8e9eaf7ad07838949c"): true, + common.HexToHash("0xaff0894c1b2c675849d75ab682f4f03add5a4e4cc36a5fe5bb802faf29f275d1"): true, + common.HexToHash("0x911cde1fdf3ab2ddff7f49972bd2ffd6fd0b188469a4c6dcab6fe3f90f95046a"): true, + common.HexToHash("0x6cc3a29c96b59265a35d4909ef936bbf62cb227b6a537e33bb2fc236665738c3"): true, + common.HexToHash("0x614950f1b55df7dba5ab69bc6252e7ffdc7ca7dc66cabb5b3d8b75c1c42c212e"): true, + common.HexToHash("0xe983e2378e4af8e4af219e299d3b1e2f6f78b51e79cfba3b06f2ae3a27d1800c"): true, + common.HexToHash("0xed3ee18213773477f594770d6369a4124c675ddf7b1e1a1c3559b58420840ba4"): true, + common.HexToHash("0x0993c1852eec64b60ca2313216b35c739af793a40e767feb772f5924d0ca819f"): true, + common.HexToHash("0x1e55dee63fe4a6efe186eaf7e3f81e94eb0e396063265a9c4409fd92b39e0a3e"): true, + common.HexToHash("0x0920aa87afaac2566f3ab8d970b75e439780802450342329bc66e820b23e7bab"): true, + common.HexToHash("0xc4b5ccb985bca9c68eb1bc535c714286ae40b95c6ca0af06ca6b56fbbff74cef"): true, + common.HexToHash("0x7f25a79d2a871df49b1e7f1262e397cfd8292f9adb5639d218209c3e0c792510"): true, + common.HexToHash("0x6a5a7aee02a18a0763e4688838b41c118489aace4461909ef453e9dedb8bf6d1"): true, + common.HexToHash("0x666914bc4a74942cb3008db667cb5248cb3c0bea88f7196b8c0bbe928118ff18"): true, + common.HexToHash("0x9d3ae1dd4066357f0c66e8803a9bd88a2b40aff7c6268df8ea9717499a930d43"): true, + common.HexToHash("0x0d37db727e031fe15d0bd50b1a36e7708c5d07ca76c5747688c754022fed26a3"): true, + common.HexToHash("0x493af02747d08bb132b577612e86456dc8dac888998d59f6e1f1a9ed7ddaf507"): true, + common.HexToHash("0xbafb619733ce295f3debc6ceea9e0b7121307392e955b5423cbcf640f027bc14"): true, + common.HexToHash("0xdef8ed988db37fe1665f23c394abe53254611e91474d3f91279715eeafa6acbc"): true, + common.HexToHash("0xdd6fa1e4bf71d10286bda1306c7571ba918ef2c15c2d31f09cf6292cebbf6d46"): true, + common.HexToHash("0xb6d9e3a39b9a6dfeafcdc3ed374b1dfd640ee3f0aea7527801c971e560d32bd8"): true, + common.HexToHash("0x38bda22aa04392be9b1233e9372be3a2b4be4488cd18bb6f575943e30bb2bb0f"): true, + common.HexToHash("0xea0da17e89e808e1d0e0488f8971c1eb7f284fa2adf62902ea834fae7a5ef7de"): true, + common.HexToHash("0x4523fa34371511388fecf7c37ad96d19bc67e79728e99b4ad9f575699398844c"): true, + common.HexToHash("0xfc44947c422abb57811e9f1a385576fdc5ed891ebf65d3567d6f8440b3410abf"): true, + common.HexToHash("0xc2aa27ca77e17a82db65abbd3c30d1d641879841c8e92dcdef529dbef2073880"): true, + common.HexToHash("0xe68e14175a4c9a820ca76d0b3723ad796c4f39f2b985a19ba36167a11c41b4d7"): true, + common.HexToHash("0xaba4086963a5b0250a291cab2f0ad52ad346e691c9ec4107de4f88c62f7acebf"): true, + common.HexToHash("0xb90f36ac404625becfaa348cbc312b143aaeca4b8d2c073f9081f751a653e368"): true, + common.HexToHash("0xeca79a74c84f99bcf8345d11c50a333a5d306580f8e2d6ae6853a5a7df2c394d"): true, + common.HexToHash("0x45ecda6542124ffad68b393346871a6eafbb241d665ae69d539a37e4c92c654b"): true, + common.HexToHash("0x764c333e212c8d8e2984a3523355c11b6d0e0ad7d627e26dfafb6c76b9ab18d4"): true, + common.HexToHash("0x5d9e11e5fe4c3399145ef5defbf779ae749228568fc06a9ce187176b0870dd1c"): true, + common.HexToHash("0x60a6cbb18cf982a15ca8891e85391d26872288c752f9b32b5922f7c1b953c873"): true, + common.HexToHash("0xefc78199710b8ece59e59d5c9b494e6e460a7a30803a2c1d63b06783e75e64ba"): true, + common.HexToHash("0xc21479a6dedea4d09cf6f7324301cc7d7e1c586ab1a8a395a5da110155b28477"): true, + common.HexToHash("0x5eaa9969f29befef4872264d1e6e7270d0451f35078f15b7ff5e6de7427a1a66"): true, + common.HexToHash("0x57eeabc9ee0225b8691594e627545f1abebc9acef02fef7a56bcae7c44d8cc0a"): true, + common.HexToHash("0x14b50fb1b69a53754f529ac20daac3b360b9daec4ad36934327e4fd073919b02"): true, + common.HexToHash("0x9655c0462f2ce9c1949afcd6c65828e64dbcbe7396280771c5b3a2bdf76dc01d"): true, + common.HexToHash("0xe2da17665e5e7b4e4575e7201271d16b2010d6730b18ec4e8845a6cb74805c55"): true, + common.HexToHash("0x34fd7fed9991a55258b68d746014a98cca3b7f9e53dc8ee434776529d9235972"): true, + common.HexToHash("0xe84c18dbac22b2dc650a08f21a03cc05ee2cfc25996e208270840b65024c515e"): true, + common.HexToHash("0x78e68a0d1fa43b3c6a935270cbf526b4b9809acbf7ffd3e7f223832a3e715985"): true, + common.HexToHash("0xc9b94a44eed0da78a8a8d97f8fc53da9db6ddcbf6fc479f1631450ac961b7513"): true, + common.HexToHash("0x0afa536eea54a2772cdce9ac15746e1b34721ce63d084fcf79e88215dfc2ab7f"): true, + common.HexToHash("0x709297f84fd0451db48df9fc40653749c45bc2bb499eb983a875f2a17b9fce08"): true, + common.HexToHash("0x9f818991134709b75232b9b1cd583c7933f53a3626f53a8e1915ffa25bc0a25f"): true, + common.HexToHash("0x16586b1615e1f7fde6bba04f6c293eb17d59f23f49ab2419730b6d154728aafe"): true, + common.HexToHash("0xb1b75ca3a1bf2e5334690dca8d5eebecdc32c563e5d166bf02daee1ee0d6c4dd"): true, + common.HexToHash("0xf004c8b6518f488ec98bf28436854f6749376002368fc1e5763f7c088abd859f"): true, + common.HexToHash("0xe7861649d9b814d8a726fcde18ad7223947f02e3421ad73d082532486648ebe8"): true, + common.HexToHash("0x81241d726bc8c3b6dfc7b750e71699690bb3479eb3db1eb5806401bbd11df271"): true, + common.HexToHash("0x4b2b56b58067d1288f99aa2a0c688f2c7ae59bf5fd564badaa6dacc80441bd96"): true, + common.HexToHash("0xc2f54f3a3449011648a484cc218d738f623ff181ee2c15c48c39cc063830e293"): true, + common.HexToHash("0x47156e079bec23a76c712e87ae102bb127e6f4ef466e90f7e3d4b007c961696b"): true, + common.HexToHash("0xa5098e98d6fb703829cd516825cbfbea157578d2f41018a0100cd506a1770028"): true, + common.HexToHash("0xd54c9b30c766a3012bbf8b0fc9ad839a2a240470dee59485ea11fe27bb7a0e70"): true, + common.HexToHash("0xc1382b97374b39f3504797de3f54c79272da0a474d9f3d996505b04a1315145f"): true, + common.HexToHash("0x032503a962e9dea6190b2157f14c9d49482cdc94d5bdb5dde32bc2d5cebfe097"): true, + common.HexToHash("0x8eabec651677ca856aa5e320ecd3eaaf1691e58769656f343664e9336bb6eda1"): true, + common.HexToHash("0xe46f257fb378bf3c36afd656cca4a95e0237a6df0e5226d886617670fba2b372"): true, + common.HexToHash("0x59cd6277301b72f2b9b18056207c6b4d9d752228eb79b08d1856fcd36e22c45a"): true, + common.HexToHash("0x1ede0cfe342353f755b32112eddb17e72452d9f50702b09d5f88bbe754fa2ab0"): true, + common.HexToHash("0x18014fb548f53781015b20f5ee7eca62e6f25a9c735da729454aeea1f67a001b"): true, + common.HexToHash("0x1cfc4b514909a2ccbd4ab72ab3e0b8cea80ee5c5c019d447c65bb79568ca3f01"): true, + common.HexToHash("0x48a6d0f5c57c0ea067cd6896fa31638bfbfa25c2c47daeaab3cb821a6db32781"): true, + common.HexToHash("0x6213cefdf183a31736e80196fc6901d4474f451403f86e95d2a23c5f02e52a75"): true, + common.HexToHash("0x86e179587b1b486324f205b9f5af2cac70e6ce3cab20e08199ed77a045201323"): true, + common.HexToHash("0xcf2cba4343f36c0e1c78eb742bcdc6413f66143a311f0788b4e2c3d1e20f5532"): true, + common.HexToHash("0x372578485bbdd5b205ec44f56186b29f3dd40c8c80c8879ed36b5fd34d23a16f"): true, + common.HexToHash("0x0b7d882d82c14bed89142cb153d1b3892d2ac7c05a303c6dd3caef39a9bd53a9"): true, + common.HexToHash("0xbaebf559c6a8be210138f31fc592fe93d3931595979682f12666287244ee3cd7"): true, + common.HexToHash("0xebbab81c78201615e746f577efa08ecc4f52bc0f77a367cd522ed37867612a59"): true, + common.HexToHash("0x0fe3f47a3921bb4f39a95ef3ad15a5f61f50402fb26b6e6cb86e944eff2252b5"): true, + common.HexToHash("0xad935ab6ed92141256add48a73261f9a59267db8f7c6ecdf8a668575f0e7a5fa"): true, + common.HexToHash("0xb0cf173924caac78eacaab8cde4a39dd5dcdefbdd3ceb184f7c831b309337635"): true, + common.HexToHash("0x782cdbb06fb9db35cd09db20253a9e26f930ca8a311449b7f7fa6c7b83c2deb3"): true, + common.HexToHash("0x67540e630c0df14fec4f558d77a90f95155f46f8222fe9f6e6866ead75ec6d89"): true, + common.HexToHash("0xd59f8ba75bbca5fb351bb3f99ff1d7ad40432b8de544d0dc6464ef14b0bff9ec"): true, + common.HexToHash("0x59febde7eefcf06aa6d0d430bc4c803581f0422ef27220ef3be615bb04f7f1d3"): true, + common.HexToHash("0x90babf5ebf2724e49fa40d047d50b25a6c2803e266d71288bc69c4e9fa2992cb"): true, + common.HexToHash("0xbe0a69fa3246da420fa9c4bfd06af8832e69034879eae6fce516626899b1078a"): true, + common.HexToHash("0x36629f8455d93d54d0941d92c5d5023c4582dc32c110cf5d6cfe1744022897a6"): true, + common.HexToHash("0x79806f357ad3d825ff71ab9b4f66cc27b725d0c74aeb62e071faaa5564bd3f88"): true, + common.HexToHash("0x050d55e9a3cea124bc30fa816c285bf4baedec9c0dcea6aefcd8cb6489afea8a"): true, + common.HexToHash("0x66080f124ed80000357fdbfc58d1b470a914af15bd2b6a2b9dc8b2fafd7efaf5"): true, + common.HexToHash("0x645118c201cef30959537eed8918a4ee138ca640939f6545c8a77b76729665cc"): true, + common.HexToHash("0xbbb4ae746aeafa01901de4e19c7779471e655d68a4ca2d50cb95f7dec0a64277"): true, + common.HexToHash("0x5a9bf88cf30c0a694ccca0e5fef92793cdc10e82a2250fc2fdb3687c37c380b2"): true, + common.HexToHash("0x0175c205d8b4820da07a2c58186ac1479593ac8c76b56828e82cc66aeaeedf94"): true, + common.HexToHash("0x5fed84a9c1ff8c1647fa4e30e424422459bf80d088abefcf221db61dfcfc757c"): true, + common.HexToHash("0xd07da4e5c30581e5848f08be986fdbffb7cea1b23d9b94277f682223cc3e9dd5"): true, + common.HexToHash("0x056e61745c741c78093bd0096e121a6db7df65a7e2ecbc18f2550015d347f41a"): true, + common.HexToHash("0x5ad074ef3f03da48789c9d9cf89500e0ace9e74f3812be86598b8d9ac677104a"): true, + common.HexToHash("0xc296b6e4daa170747d4960f57120a90106625610e7cdfaa167ca7aa97996a1a6"): true, + common.HexToHash("0x807669c5f6cb90dc7a3e55c7e8e9e763cb29ba853f60119579018c417735073c"): true, + common.HexToHash("0x2f88da7c6250e0dfbb4ea59361a9d5d6c4728f3855d5b52477db82f96fe33823"): true, + common.HexToHash("0xb266a82d4d48276c344f713f20efe6f289ea06bea90db45ac1c676e461290a7d"): true, + common.HexToHash("0xcaa9bbb9aa4d68f6ac0bcbe84dd02017c21e790b194d5869f0484173b0a4956f"): true, + common.HexToHash("0xb52c1bba3e1f9b4b270d3f98d43ae5f0bb340f4cd4edf950426c13cdde5ae57a"): true, + common.HexToHash("0x1a2ef8d0c5f79fe07e2fb54ff6b005a92ff07c88cd5f65b4ea3b4b68b877e4ee"): true, + common.HexToHash("0xcfb97b067721b91b5bf6e8f95157ba1257da22c81bfc5c1ba0260dbdb1a11d41"): true, + common.HexToHash("0xb588eb437f51f684d91739d7861f01e71b24a58025b19567ea69654dab040c15"): true, + common.HexToHash("0xacff2f8c69a6c29a05cc522bc43884c99e35a88384913ed0c0497915dac715fb"): true, + common.HexToHash("0x3d1864984f50b91bc2b7c4e1855a7f51a598231b525a0c7551b3af57e2b4c288"): true, + common.HexToHash("0x585f4bf3503ef6c94f12552e8e4e443e3ed7f795e759687e3526693a56949879"): true, + common.HexToHash("0x8cb4e95aafa29e62b2fce0682125352709aaff4aac735ac8f2b22bf8ac2b80d6"): true, + common.HexToHash("0xeae8c46ce17450ed1253aa4ea33d36b95ece81f06d85e6e0919ea94a216ab524"): true, + common.HexToHash("0x7973132698c9ff25f2b7f54309dfe9451a0f59ffb6bf5c4481f017ac0629eca5"): true, + common.HexToHash("0xffd776d4ce1b830f0ed0b9e3add4b71aef2c08a86690fc760017d72b0f97a38c"): true, + common.HexToHash("0xc97c6beb84a6145ea34e52f370a750df29d55280949d4ddd620000aeffa75153"): true, + common.HexToHash("0x9b8e65b62358445cac203b866c528013194b2cadcc41e79f461df2e3557c669e"): true, + common.HexToHash("0x1e22e3d8a415ab0461981946e0b8bf7d69b4f7684091d3dd07cc5f837f191238"): true, + common.HexToHash("0x1adb914e555d90e3e7c70ca0a43b0f44ccda628f4bfd1e54a7e7db291048775f"): true, + common.HexToHash("0xc01d378cae8f92dae71cc80043e891562172465002177e3b13ca2d205206357f"): true, + common.HexToHash("0x4ec5c2cd300da62b9246cb4ab6747e799d0e8829e87a602244ca74f372116cd4"): true, + common.HexToHash("0x6bc7949c40e5ef1e9cc51e20f710e582e5174fb19a739c24602722a0a6c1396d"): true, + common.HexToHash("0x407c7c04756dea4190de855de5e14fc9dfe0c6de9643077202cb3771dee4dae2"): true, + common.HexToHash("0x9070bf57afd58027c91f5f02206440f7363594dc0d00082e0032ec416dfa210c"): true, + common.HexToHash("0x6c4bc4a6f6e291d6148eabf473d0dbb8435f64cd5b2739fde119072e49e7ba45"): true, + common.HexToHash("0x4ee5ec8fd25aa00bb11e1346c71986c8ee9b71cf0a46ba6266a4a93a2e767047"): true, + common.HexToHash("0x1b4023781d3e1f571b29ddb9bb84ba080ed17b5d921fce7fda066e78808305f5"): true, + common.HexToHash("0x7e64dfef3233adf95406468d48508bad1eefa2c85cf989f353c1c187b42ea19a"): true, + common.HexToHash("0x5bf830ea0d6f8af169db304a252db03ad6e573d922cc063d03d2a8a6b646ec04"): true, + common.HexToHash("0xb67bfea845392e0fc2b1e9cb908536edd007cf98f83ddb1f5b5e6b416ab7f6c4"): true, + common.HexToHash("0x1f0339b3a239c9d52cebb75785d57dabfc375138005e3fe339e968c6e16f5cf3"): true, + common.HexToHash("0xafd215ba4e33ce63130d429c9281885f81f2794cc6d8509cc3f9053db3ff9932"): true, + common.HexToHash("0xd901e6130bdb2991f6d5fb0a6bde0ca3aea40edf45b29979d81254594b694de4"): true, + common.HexToHash("0xf7f31f41f70119836347a226d3e3996463ca9f48379bb8456aca7013ff94987c"): true, + common.HexToHash("0x880f4743cb8ab4894f795ed6a796495bdd52ba21eab374c8728d10d598da359c"): true, + common.HexToHash("0xf3a926996547f278d5d86c414c00e0ed2d536f01c5f124eee5bc32e40831e124"): true, + common.HexToHash("0x3873c12aebf53284db4f70731cc9f7b7e852f793b27f3f7b301ffacc93364493"): true, + common.HexToHash("0x8cc48dd1480ba3a2380738064fef4490fead2c2fa50ef42d0cd5ed64cb7515ee"): true, + common.HexToHash("0xedf32bd84d00153b0c8073b6bebd25e08ca6b1d3b71fa7d03236261a81f32d58"): true, + common.HexToHash("0x3280671688e39363957ba70bfcd180047d2e48834275b22d72f9c661e3e90550"): true, + common.HexToHash("0xac6923b20ba37e5e99178654f2fadfe15d896a09fc028e0c500ea5b2561c4992"): true, + common.HexToHash("0xd6fcb37d33afe4a355672763b0fd0b45a94f805c94bcb3fb22ec8a38ef1c415b"): true, + common.HexToHash("0xc3aceb0f918725a5185ce17df75c9295bf4eef8b4d25d9d52d1806f87c9ce1de"): true, + common.HexToHash("0xadbca754d72535bf0b9c8874898136170e3a68fb3fc78286bac4124438f6ccb2"): true, + common.HexToHash("0x4aa35333503b8777bae7f93f3e28893a284f3c70e8d5a1fecb2e615db3b50ebe"): true, + common.HexToHash("0x6aa8f2e145ada0eed958ad2a2a13aff017d3374964385465f5052cbe4ba4887d"): true, + common.HexToHash("0xa0f69f7722d88cf8cd4e3b945b66e4ec7af292e2aa42f1a938250e17724a225f"): true, + common.HexToHash("0x5702553c7d31e3b4e3bf4640b22b51020eccc2602f852cfd77c3d51682fc3777"): true, + common.HexToHash("0x5ac146e0b238f948ddc24683646c3e33fe15f1686c257e5043133db46b304b92"): true, + common.HexToHash("0xe23dcff36e4cc8c7846273a8e6f168fee4d0a96cc0c9de42d1a389d402fdb1ec"): true, + common.HexToHash("0xd6e663ef35e0354a8d5a7e0fd58660accb42e2af8f34d3082871c0a017b0cffa"): true, + common.HexToHash("0x319a1b37c4726a2667dc39482b8121f1f54166bd9d38b825ebefeffffadcde6c"): true, + common.HexToHash("0xbe4fe6a861ccf46871cf9e67ca62f7b75a84710631504d8a3fd53af31774acba"): true, + common.HexToHash("0x4ce3136788c655f298be91459efa852e3af110f2f9c6624d354128c6ab42d440"): true, + common.HexToHash("0x6aca4e17ff711d4427e50fb6142a63d1a863cf7676ef2a5551aa7a2c85b63605"): true, + common.HexToHash("0x4d732fc63838cec2bb6bb4fc9dbfda11bca68d17cbb9ac7d3f90acecc4470b4b"): true, + common.HexToHash("0xd83c1744f50ee4c63f6065997703d92bf6e4552ecd862437ff8f843a8f593a83"): true, + common.HexToHash("0x0ecb31398518bba6e07011d1e814cd71f6fbd8dbeaf7b38955e5c861d987b226"): true, + common.HexToHash("0x2176110bc4667c8a132e4fb44732e3795fb89f3806f64eda6a2a593af95bf564"): true, + common.HexToHash("0x7070a7d1eda8f17b6cab865fec08af8a14167d17bc2497c0d12e4ac4350ddaf3"): true, + common.HexToHash("0x4faf4253645de9a199e42a8324e3159494f264b44f5f7583ea09a8ff4aa33599"): true, + common.HexToHash("0x5992404c91010a57c65553a6a58a83e1f966b5c73fa5900a004c3556b8b6911f"): true, + common.HexToHash("0xd7c3093cc406470a4c45e6c8161f2455b15a5f247e68b4c3add4f42b7ac4403e"): true, + common.HexToHash("0xfcc37cd7e6533aa8e62e6ca113a6a72d229708e18fab189f066396d5df1ffa2d"): true, + common.HexToHash("0x98d9192326d8dfb0b7f3ef0c13a603b1301c5d228220a7ee7ba4eceed68287b3"): true, + common.HexToHash("0x96a581090517d649d7598ae62b868c1e61d2a29e370f987214a77728d58ea739"): true, + common.HexToHash("0x066f04a9526d0a4af71b87dfa51d65959964ca44a40b051f0847ae88516a630e"): true, + common.HexToHash("0x4922144729ffe48657d2e716430ee41f6d3e8095705a60996c469007b560e0b3"): true, + common.HexToHash("0x7ebc7f2d018dbd0a1f4e32aaa7c8451cd82a7ef07ede3a2637bf37bfc6e0e244"): true, + common.HexToHash("0x434fe668c59804920e01e40445efbc60c200167da75c947b8042950eeda64422"): true, + common.HexToHash("0x41cd4dc0703e6e386f7cc378242aed44036a4d831ff960a8c47766ad92b289c5"): true, + common.HexToHash("0x174493871ffc28f361293ea83b372058e3938ce5250dee35ab9d852967e255b4"): true, + common.HexToHash("0x4bd68c57a79ef23562d8979c4467c525dcba3eaee1cd8044eb664027ba72f997"): true, + common.HexToHash("0xee8c84ad9fd34399c0850281ed50e6ad3fadeee69ff956e3cfc4d64287c35435"): true, + common.HexToHash("0x228aed0d85343d7347b9c34a14c6e77431a17404209b73a2473e1df86a8990a5"): true, + common.HexToHash("0x79cf509d7e31e920b70dbdd46734eb9a16b4be5aeabb186a00f3d0b1133d22fc"): true, + common.HexToHash("0xbed0993d51e70d54c286d361ba02e0f5c58eefed144aea783dc27c428fa74e2d"): true, + common.HexToHash("0x347165cbd39356a779522c79c961d90e1ba8edbaca050f5f8b22d7d2e35b9d0d"): true, + common.HexToHash("0xfac3ac33750b8dcb42a87a2af0de123a0101aec1aae57e333516328bc4083f98"): true, + common.HexToHash("0x88a0de0ba0cb38bf54368a92c0f46abd7140d43ef0c180a38fdcc5e59703f8f9"): true, + common.HexToHash("0x70616bf86559556e5041cba65b81e2b5f19b28a91da6883a8a1d21d3e91a4b80"): true, + common.HexToHash("0xc6d8bb9dbd3e808fd5755762d18dda11118b002d1357a0dec26e375202ca1841"): true, + common.HexToHash("0x05f74adbfd5fcf515b42e2d14481ad724fa28bd67621e2755ad33043cf4891e7"): true, + common.HexToHash("0x5dd5f86d143cdd6e6ddd63502abfa7c1348d255edcf47ff72b294075d2bd4ae2"): true, + common.HexToHash("0xdca9518a95fdb45d69fa3752b53a0945ec9cedb46eb332ca449cb3b264661d34"): true, + common.HexToHash("0x65c3ae0f0d60639b6810e5ea0612e2015e73e6d08318c29c8e02a6b2a43d5d2a"): true, + common.HexToHash("0xb1f603dec0393a64058dbe282b0489798f593a8c0f309050dc8589b085889849"): true, + common.HexToHash("0x01deb1e4b8c8440a17667006ed18e44475dba3c83c9a8a98a78a6d759196ebf0"): true, + common.HexToHash("0xe08870362cd8bbf28a2af534a43db186090b6eac86f77054f5c2cbb74aba3e46"): true, + common.HexToHash("0xc25f1bf94906e7ea95a5b807a928dc65608496d453eb738e6471422191557835"): true, + common.HexToHash("0x69dfa85c46f7e92f5427eb416229b8c36548d2e52753b03ed275593f654e561f"): true, + common.HexToHash("0x7119cffcedcc2b672938d7d7d57c06d582345edcd0877a1fafe46463a1323dd4"): true, + common.HexToHash("0x5748cdb427edef0d6babc87efb19585ec15e4af7f490195606af1b0182b7ae3e"): true, + common.HexToHash("0x31a9f47438649e3bbb5d6cd0183613032149b149c5e4e56c4c9785d04494e6a9"): true, + common.HexToHash("0xc982b849f39c7cc92560b74b099e4763bfb2493cf926bcecc6c50de641edb90e"): true, + common.HexToHash("0xb6cde7fc0f6ffce24c5548fbede40bcc15cbc9b7585fbedb17e3055aec9d7d7d"): true, + common.HexToHash("0x8c3d1bfb182d5e284e6699e87683cfa73b1b22a6f71fc53d9ea16b91e710e4de"): true, + common.HexToHash("0x6e836afaaa2305e41cb9ec638b625bf1786e1215d09f3bf89fffd2b0ff3a0645"): true, + common.HexToHash("0xef832f0a7ded94aa482e71a8337960db9d74f9448d2bfc6d088a6004fb01d925"): true, + common.HexToHash("0xc5ee55932b54cdc147f454e877188158d1e33cac113eac1c814d8d562b1186a5"): true, + common.HexToHash("0x9d51086543a5af15c32dcea52f10f26a11e1554db6985e04cc6ec751fae9c5bb"): true, + common.HexToHash("0xdeea30c19f1c77c66ebb9a9601057c349f218e50871d2d18afa4c307738eddcf"): true, + common.HexToHash("0x96fc8de45f17cc6d29848a4ed708f29d1f604adf3944865970f94c47d806d282"): true, + common.HexToHash("0x62f39c06d266e796586a4bfc76bdf5b7abe18f64012e9992684b86062ce46056"): true, + common.HexToHash("0x35d76024a98f54bf06cd3f21175c30bba0b6228a50a8345a087b92eea120d68d"): true, + common.HexToHash("0x181562a5d4bb8708cb52987b75a1e3d3d73d5dd1430e7af3e152c0fbeb1cfdeb"): true, + common.HexToHash("0xa0775b302819b9e001c3a7b7ffc2f1b5b42b31e86a1dfdc1d03cd267f7cfd5f5"): true, + common.HexToHash("0xf6ab35b07be91a61dbf56bcda1e01e3699d02259bae1b53b36cf5e44239211f8"): true, + common.HexToHash("0x935dd6286be18e46bd8b103ca9be0f533c8784d5824a554db6fc4a670268d310"): true, + common.HexToHash("0x52454be892bef545b1f80d5c34e06cfe9c6df7256ba41ad75b7beaccb72038d9"): true, + common.HexToHash("0xe6c327ed5d319064dad887747bc521f042b6aad6b126520dc2853036746f8580"): true, + common.HexToHash("0xa6e8570ddd779620a85822fc09a25a14e7b6151ad5fba4c7561493febcb449a8"): true, + common.HexToHash("0x701826a84a575687b8ea3c6f63e4af226e43ec3780c2d6320eb5bd70a9636809"): true, + common.HexToHash("0x04389f61da7d44280b5972b02985d3447cf1ad53978cd2b27446c1251df63890"): true, + common.HexToHash("0xf083c315a584e410a0aa9e0229e1e5d94b2481b155e5d68f1f0f4fdae41b11ea"): true, + common.HexToHash("0xb7e60fd9da5b3cab100031c6d82ea481a26d451d0a56279e2bb3020951733d1c"): true, + common.HexToHash("0x52ac1fcdc45ec40416309e463a5741ab3b4871e8339d3f7a024ddcafbe74a61e"): true, + common.HexToHash("0xc9d75e0fcf165be94cce98bc6da92c4840e5c9c90821fb749e9b80c3a92d5d63"): true, + common.HexToHash("0xa4b8829c455a1d46b94e2d0941b66fd59a4801622e46615212acc2e94e28c836"): true, + common.HexToHash("0xa865d425ab3346885c0418cb5d5d6f6621a36e997c204e2f78ed589faca08d73"): true, + common.HexToHash("0x0a738948f0d6610491762ac5a8b9c784707a1e6e3ead6e288e90f655ca51ea98"): true, + common.HexToHash("0x696fc0855dda5f6e30d77cc8b2d48c98858753d4d03383c76ff3336700b91132"): true, + common.HexToHash("0x2dcc3d3a49cd1db565ebce10d907141f3b5d400100598ea64436991198852a23"): true, + common.HexToHash("0x973066ae4e72ffd24afcd30c6703c0cc8f9f86cc8337668982432b60936c963d"): true, + common.HexToHash("0xfffd923399740411703071683dfdd9ffa13b22373671398bb0c08e96d0ee7a47"): true, + common.HexToHash("0xe008faf422486ae1b59f5dab261f20cb05e9c86fdc232647446d6239697533ae"): true, + common.HexToHash("0x37b0d0767c894f739a54fcf550d8fad7b98c6cdc365b0d3b364628ce9a0184da"): true, + common.HexToHash("0xd0e6d03804188ee1a8ba7bf895fd61f0d5ef2e17cdc64f2ecd16fa2a0e00b6c9"): true, + common.HexToHash("0xc45cf9c40e5130aab8294f8796edad868a4137246227dfc21dcaa5bc02c21ba2"): true, + common.HexToHash("0x6c8e9893474218aed23617b167f711f18006727bc6769aacbb727d28f6bfa135"): true, + common.HexToHash("0x6c826f858a42314e7d9fee4679a58a952d8e92ca3d5b57c2f4b1cc93616daa74"): true, + common.HexToHash("0x187d98cfddfd6c28575c68c1ffdd4f8f7f0ddd65c22d10145600fa6796896f11"): true, + common.HexToHash("0x54f8c72435e0dea6e0a553913ca40a1c0909621bf126e132355a78eca51402bc"): true, + common.HexToHash("0x18a5b0af4f18524c73485eca778a62291d80bacba0714efc5ba38f9eed3f0c70"): true, + common.HexToHash("0x2dd66e4126ea3d25941fbffe1d43d53d9fae0723928349c4c3e8208a3ae5a546"): true, + common.HexToHash("0x3395d73c03f9677ce1258484f515a3959b6c19885099a61a714ba25ed904ea5e"): true, + common.HexToHash("0x4bb187c2cc4352e80f38177d4b2693dce62a4cbd5fcbe314df58dafdc51884b1"): true, + common.HexToHash("0xc4a9408a2d6f696b99d11cd9cccf109f18d894456dc8b63515be56a722ec6c7f"): true, + common.HexToHash("0xf348b1cad639fab819196b6636984d9af2cc3fe5fc705e17ae4aa1a730820570"): true, + common.HexToHash("0x29a85fd9352fa6b342e2dbf6791ac2312d186ff3acd1707bbbaabe0a4b629bb4"): true, + common.HexToHash("0x466571258cce54acf87092dd1da1e0038f3d9c97ff72c4b079c8c783d4596c39"): true, + common.HexToHash("0x55febfb076e61653adff45b6a2cbc8492af26926e91709c6017772c59e41458a"): true, + common.HexToHash("0x712022c3f04dd61c8055d931e7100f1d92439af96707d7640304c1d8d424c5c5"): true, + common.HexToHash("0x86e2279632d26f44ae547278935afd7faba2f2b52891454e0d42483763197ab3"): true, + common.HexToHash("0x370ec4df8442c5d9985c9e424a56e8d5dbbc89cd06f6e8721cb88cba90bc878c"): true, + common.HexToHash("0x18f7a7e35b14e5cfc29a4ba1b3ed8d16367e23dfaedef93f62274bf9e6b0a724"): true, + common.HexToHash("0x0aaad8188cf03bcdce4f3eb9bd6ed21f4dd22c193e949244cdd3efa7e8cea5d7"): true, + common.HexToHash("0x5fddd391dd41409e86e7ab6cbdd909a93ae9e6c3a8726fd1bfb4634087b6aac5"): true, + common.HexToHash("0xd3b71840eb2dee83b32581c43a59196f21e5c02ad0ea17e61ae7a9ce932f3401"): true, + common.HexToHash("0xde68e7137d86ca27717791d71ec13a5c3ec1be39eb5f3e814f753e35854d61e0"): true, + common.HexToHash("0xcccb3c3c7227702aca6326013955ebf2a50ae9eef6b9f3db40418840de87364f"): true, + common.HexToHash("0x5c9c225b59f2a9a6d0404a073a27528b1d1d2d7fb0da2762cdd65aeb848205e9"): true, + common.HexToHash("0x31699dd37f278ed3437a11fcc829da5ca033ddd67f5c6a486ad9c4cbbb235c90"): true, + common.HexToHash("0xba93298007625f1ec55eccbbef6f859912c2d8c015856b9b6a967a88a12032c0"): true, + common.HexToHash("0x1a43b5d76384794a8782530cdade3aa9bb731addc2e838c4cd308910a2f783ee"): true, + common.HexToHash("0x85db8aab7ba342c712c404c9a3458fc9d453373261cd28a84e0bfb9d6f94643b"): true, + common.HexToHash("0xb6a747a677b75bb6bcec5be408896c27abadcf20f262727b53c54b5d797a42d8"): true, + common.HexToHash("0xdb8ad802802dec72240d95a65fb8c93a2b2f059af7757e2bf3cb8035afe5bf5a"): true, + common.HexToHash("0x6be8402452d56c9f832812ba2c196c1e9d9960f49250ed98221ee45723e6b3f6"): true, + common.HexToHash("0xb03495081976ca4556a7fa13b9beb6a691fbf4f91586225c4e5a3a73e855260d"): true, + common.HexToHash("0xad153acb0ae76a8b1d28fe3874e1cc4bb02e664d0cc4069cfe820e142030d7ed"): true, + common.HexToHash("0x3e8e4f30fc1368aa0eece4e86b1b987184d55375768143b1a9f82156dbbd4095"): true, + common.HexToHash("0x9f98795bd7f0247ed35f18dda0506fe9fa450858f706cb9d9d3233418ff63570"): true, + common.HexToHash("0x93c86cb599f5c5f132c5e252d7dea6f08a9ce4a99b75a962873782013a965d62"): true, + common.HexToHash("0x99db8d643ce02a4091dcaf6113e8c5e2c880a0ebb0fee61c3ea2ac80fbfe0b12"): true, + common.HexToHash("0x5b025f4624369c17632e024eddcd7dd8b024166673d21f3d874574d15aa72b21"): true, + common.HexToHash("0xa513b14174aa6f383abe06380f70c182be36a3e31d9d2d98261a5b7f7cba2fba"): true, + common.HexToHash("0x80a1a666436eb846538cc6fd3745f0ff9c16abccaf55d2faec613de871a333ca"): true, + common.HexToHash("0xa6f0c26933a7caef75fa21239ecd90be70fe87b4f8da235b87c409e66b662e27"): true, + common.HexToHash("0xceb86e1833503e9df8e8f4ceeaf679b3cd289d59e8fb60cdb70b3032a7b10acc"): true, + common.HexToHash("0x0aea0b7614ee3ff5f38258f2baf5f37c0a0c94e00f4837dd93d8444830a922cc"): true, + common.HexToHash("0xc7c3ca2da780a14a596a21d02ee9cb11e7071fb94fc6487009cae4b151035349"): true, + common.HexToHash("0xce84b9b598cbf0e2d6150c4c202e5ed45c5ee59560eba840de5bd0e0cfeeb80e"): true, + common.HexToHash("0x06ca08e690c6ea6bd25e9e830f8bc7fa539f292d746602365687249096f8e7ea"): true, + common.HexToHash("0x473ec878482ac3de685d9adfcc99d2b38252c93311a9c50fc73f0f7fdb71eba4"): true, + common.HexToHash("0xe90d68c171ed7c72b0aaa9750698d9441183e24e42d7f38cf44ff6c886644db0"): true, + common.HexToHash("0x0553040b6a66b48955c42f9dae7012b59cc0c632f4a0defe0ae3f4339989c3e3"): true, + common.HexToHash("0x179e5f0ea0fcc4846a1be2fa64dfe105ef12f91d4e047bc20f4de2491e802902"): true, + common.HexToHash("0xbbe7891d46972f4e17b86cf24ab112856ca34c5882edc61b4ba446fcbf8d4256"): true, + common.HexToHash("0xf91eae5a3568b1fa9c3db325a3bff5572e16c2a94143266c982367203530443d"): true, + common.HexToHash("0x8c15b4351e6717a437ae94d68b016cd5560060a82a5c5753111d0359f11e43dc"): true, + common.HexToHash("0x40ef850a27d16eb700e22b7218b55043c0f32114f66efe8b8e141b0831d38e96"): true, + common.HexToHash("0x6f88679cd91cc1bebd0281930725dcb54787d106cc193e38653a49dd0137e055"): true, + common.HexToHash("0xce366494f2fb4625b043cdc473d86cc62094e78e36ed41de9b197b9014326d45"): true, + common.HexToHash("0x81325040dc80b349543557ac9f3cce2234b58f50e7f62c5fae0c689d2cebe471"): true, + common.HexToHash("0xeb951f0c31c529f0ad5e4ae831af7534fc53fd7d71fb453b374fb1d695635a7a"): true, + common.HexToHash("0x63832143bb7795e29603bc93d76dfa2e488777ce68dbf7312e8ad776f7c08c93"): true, + common.HexToHash("0xf2f465179834b54b5b17550ff89e0f4253eea84538f22444bd63f94591cb8783"): true, + common.HexToHash("0x7e6eee161081d996d0b012f27770b247e432d62f307230392ceb61509cd3c730"): true, + common.HexToHash("0x25714e526156f0ca14a162bbadd93f28e2eb8bf5d0b8033d5555fe5bf234f930"): true, + common.HexToHash("0xa780fffcd439617aa5a8ad3b0da49e919a88434ab80a8133849b3e549cfef988"): true, + common.HexToHash("0xc17c4cf4844c337d0a3c0f50a049e4193cc1c592b09841d0fd7bb8286029b684"): true, + common.HexToHash("0x9bd7a97c61dc241c83559919e509a5a80882aa32a63e9b58ed4ab674288d05de"): true, + common.HexToHash("0x6936a5b2d52a4a1e2ccab0da8b52f2da788028702e648b70bf9e35ff0e5dc57b"): true, + common.HexToHash("0x817b60369d1bd8bb7fd29c1ef2de6a0865334eb0244d703841f66a88ff46503f"): true, + common.HexToHash("0x204fb7cc75e86ea55f095a6744a72a2bf531de1f0450da472cd0e0444c30fa14"): true, + common.HexToHash("0x9a70ba998be3c601dd3cfc9e57cbed12526d3cc015857e3c6242c31df904ca9b"): true, + common.HexToHash("0xd95a35edf970820f25a8568e591b7c4b588b3bb428858c621f56bfa77853e97d"): true, + common.HexToHash("0xf492d19eec561e1536db0a080e93366c63447eb7002ae0d69534e04c15634c57"): true, + common.HexToHash("0xdb844e4036537048255bb9bf12413981f6b568c6190b245b4172836efba6a3ec"): true, + common.HexToHash("0xf97ffc5d5de214dc25fcde7fe931f487246e72b5af12622da012b57dc7850bee"): true, + common.HexToHash("0xb7ad3f03e2c91bf6ad420c92aeb1e4485991021560d5e876a0ba24565935b43d"): true, + common.HexToHash("0xcbfa72e11d1377526db7d0b6dbb154ce7d163f5e4069da9bbcf03fe2022bb2a9"): true, + common.HexToHash("0x7f9f9db550513553ed372c5d2ccbd5dc09e72bb3519a7c1ac3667c5bde9edfb7"): true, + common.HexToHash("0x817d20fb94bce9fe77eea2ce7756de60f64d62f84191e7d347e93825b2418e60"): true, + common.HexToHash("0x8ed1abbbfb209330955998b2b4b7bfbba7bbe5a693beb9497d6ee1a662f4227a"): true, + common.HexToHash("0xca5c490cedb74806fa9dd7a8bee730a27e4b14d63c34806c3c3a4c85ea2b6bf7"): true, + common.HexToHash("0xfc13201d34858bea64008116119ebe4b98c7b7f0bb59252dceeee52739990b9e"): true, + common.HexToHash("0x17cdee24c81274ca9fe68c5b43a55d7969108aba7dc8dd51795d09df4485ae10"): true, + common.HexToHash("0x30808173209ca319485ef84216e1fb93fbe29a4d8effe353d5c273e2ec39b3ba"): true, + common.HexToHash("0x0ced1ef89c1e7e9b57c4d9554e16c5dd6e1942e572be02fff63da927540ae342"): true, + common.HexToHash("0xfa402d1f544876c15cf61e08fc76ea4b7514219f362a0552d0ec1975b916dfcf"): true, + common.HexToHash("0x242cd1b97eda5ca585457ff62d9dc133b20884fcce7f1ba944f186506205e595"): true, + common.HexToHash("0xc43d3b03eafacc7748cbc979f21b0f70a142d3119dad347f4f2b53679a2aa128"): true, + common.HexToHash("0x63a97f129993ec8f496bc5c48d898c2e4100f3d317ad2bb7817a28cbb255a8a9"): true, + common.HexToHash("0x2a49a175646d7ec7630a2c96305fc8f0874a5920f66e171a991e53a737593c79"): true, + common.HexToHash("0xad82e63c8dc7386d424a4d9b07ea8134e722ff38275ba8203a83093d3b95733d"): true, + common.HexToHash("0xc48efc7d7c12745da6dab0d1029626123de14b66a5e618bcfdfc3955d267f33b"): true, + common.HexToHash("0x938032fbbb2149cdd7d06ea2c897dc9831a43d7b4f77fb91aadf1f6dfd2d7827"): true, + common.HexToHash("0x3fdd0b463f38c316eef88586865d706ff8445a57245122767a15c7d981801232"): true, + common.HexToHash("0xc992b9f68e3b8d2d71302c5f01b821892d085edf91ce6016eedaf81521a71c52"): true, + common.HexToHash("0x5ffc492792784d16d1706951a3dd6d035993de0835dcee593ce8c3c6f8c1d768"): true, + common.HexToHash("0x796200c9d6b9b2ba1623bc9cd7a2041a793889d861289486b04e9b0daf574b23"): true, + common.HexToHash("0xa96d4c41ff71c85bd06a0edaa0e5a2e5e9fc2adee854b7ea38407be4cede444a"): true, + common.HexToHash("0x1ad7dc04111437f2cdae140f8b8b0a07f09b9f9cb02514f5f1c0168a306268e2"): true, + common.HexToHash("0xa5fa3e565dcfcdf0e1399798001e369f8425097fa88dd8259990fd310d74bba8"): true, + common.HexToHash("0x293f1d25e6a51a4cc2ff388bb609cb63d031f7bac1a2b269fcea73600e5b9b9a"): true, + common.HexToHash("0xe63cddbfae94c9a715095938b5ee290fc4d7dfd2cc3ae2cbb4165e2d017aa8ba"): true, + common.HexToHash("0x0f28285324448b62533a4ca23133b8f3337426e248fc40dd699e636ad8903ccf"): true, + common.HexToHash("0x3efd444431cd57c918fda0743beb7024fa72583ea23ceb843c959d1449c5b88a"): true, + common.HexToHash("0x4d0af07f9aae79a01816e1b2410c76918b82e947094e549b57014be5b18fe17b"): true, + common.HexToHash("0xbbe5d13d1c433cbb06d64559f71c5799989635168da55d2e42e53bad479a5cab"): true, + common.HexToHash("0xfaed507417b05173fc400c91b0ef4c860942c41be8c5f1449c4c802f1d7b849a"): true, + common.HexToHash("0x706400cfca1507e96797e25a514cb319c55f31482c19a437baede326b5d0b22e"): true, + common.HexToHash("0x424ec0992d2dda6e215e9564d9b0a40b643537e615d3833f15f7807fc637d127"): true, + common.HexToHash("0x49ee2231789037efed94dff9213d19e077c9def4c51e4fce4e0a7b1ef0194d51"): true, + common.HexToHash("0x98b5c8b25aac21ee6bbd4ade2ac393dd5b1178f74a89bdf51c1ffd9f2e6d579c"): true, + common.HexToHash("0x808dda52a9755fbdb12e4b97227300482c69eb506dbd5ccbfeb7e203f78965da"): true, + common.HexToHash("0x95922cbf09a5c121204aa34107735e8da7b2c62dfb58d21c29716708ab42c7ff"): true, + common.HexToHash("0x1808429b3458bf7ac2572ad3f8c45c003c5d13126f3c5e179efd37b02e3e324d"): true, + common.HexToHash("0x8391f5714db5a41b6e779e39ef79d28f956572120ee5f61ff5533c6ba0763db4"): true, + common.HexToHash("0xcc7de28f6251a4c7d24a58300cd11527cb4b77db5514671895434d1b9fb720eb"): true, + common.HexToHash("0x0197e1866c3e80f5eb6cbe5328f8451524f732793e3572742194355eaf3ae744"): true, + common.HexToHash("0x3a3b1c67c9820156e5e7728ce0aaffb8f3281e5201fac25c6828926ceaa27ea0"): true, + common.HexToHash("0xaa76414d7d42d2a63d8ed47c01e642e19fc2341cbb704098f0828403e6e94467"): true, + common.HexToHash("0x48dbec1814fd35a4911a446cce0f43ad6c3a96f26f26e75bb4cb8fe36a66eba0"): true, + common.HexToHash("0xdc464e1791d4c8a16d5775827555a5ca451b617ea91a2d1644475057d4dd574c"): true, + common.HexToHash("0xdf939a3b77f2347def8b5415f4f14204639f739e21aad24f8f7ebaecc0a84dbf"): true, + common.HexToHash("0x333f4c1ffce18ec4c6d06850f96304f59d27e06916b60babfd8bd88def041045"): true, + common.HexToHash("0xf3ea7b3f4ea48b2ad97b839b6eb23872b94a344140a3a277b2901c97820dd2ea"): true, + common.HexToHash("0xd5a6d0bf0cbe1844f19d95e622b1871cb5522087b4b07304fa9a4f1b965ee612"): true, + common.HexToHash("0xbcf84abb4c833f6685556aa81d5aaba48a443dacb469e1c968df15f2b651510f"): true, + common.HexToHash("0xa6d93dca1718e315edc4a13305a5ea828a7c9670dc12d424d7b549e60c910724"): true, + common.HexToHash("0xe8cc837580455d85444ab955f190f7523067a1823df15f3fd45f69f97880af3c"): true, + common.HexToHash("0x808f04f859305c735983fde702620bb7ebf7ca3d76446390ba9769a6b7273b13"): true, + common.HexToHash("0x840791c6365e0fb255147331291e3288f0c6b835c1a2644537397132d54909b3"): true, + common.HexToHash("0x44f9893ed97a2bac9249883577ad524a48007add65db9512f51474d55c4dcdd5"): true, + common.HexToHash("0x741e82bedee617e10749c01dd3581ed5f3163c6e75a9a5c31609a5799b7a15df"): true, + common.HexToHash("0xf44b3fe0001e687a067382826386c32843bf382ddc76fd32401d42798265072a"): true, + common.HexToHash("0x4994776da0ee55cb6ed68f0245595136d819528085173f9818b7a1d3e2279380"): true, + common.HexToHash("0x620da8073e31dcaef266107e8b6291e84a5417716ad8b697ab80a8e122376d98"): true, + common.HexToHash("0x8f82e3c17adafaf716fc46c056047c903002a83d00d02f6ab5c9adb36c9c6ddc"): true, + common.HexToHash("0x6492f26e10a340b33ae58a728a1812049ebf76ba9ee96d667986437be86de554"): true, + common.HexToHash("0x58d050ffb429340db6e1d73823c284f56519cb9766be5d4d158de886a506ed09"): true, + common.HexToHash("0xa9ff3613811cfcf8cb8825561dfbae050822f5a255b39ddccc426d773b6c5df7"): true, + common.HexToHash("0x784cc31812ac9bd95de9af0fc59611147cdec5d7fb5d88a46e20c73cb05adbe2"): true, + common.HexToHash("0x154ad13503315d50fefe95d4e37fdc8abb3a922f6f8b1d571a2aa8be594c8502"): true, + common.HexToHash("0x6cd8631c2b2b4474b8bca7200b5766a60d5c2be6fac1480988d62146c17e35c1"): true, + common.HexToHash("0xbe09026e810a07d4837b2eecdef575df02c685b2a7a15a18416c80cc7f5d77ce"): true, + common.HexToHash("0xe40e3562742fbb05e2a26ee50e02c15454d1f9ffb6f9af7e08b1bd1c6d3bcb3a"): true, + common.HexToHash("0xf3ed260a580b74e5e5ec5719d14edbf55325cbea0f35efdded72b78fbef20041"): true, + common.HexToHash("0xae14ae11f6d613aa0f898454401a989773db292413ec8de5ee2e49f3f22b6d4b"): true, + common.HexToHash("0x163ef18259651d9e61062f3ec12bb5515f09b25d00ab77114c850b46a15b7372"): true, + common.HexToHash("0x50aecb321d91e5c9f3ec5ca1a0a3ccf23423b38209d208504133005b6a165176"): true, + common.HexToHash("0x5e4f1b330a069e70cf61418a28d2efc069db11f4d0f3be396a9ecf2827855b70"): true, + common.HexToHash("0x1c039679828f193bb9a6f97bd35a8d4c3cf45a006c027edf01cb871bee252ece"): true, + common.HexToHash("0x31034e4713d516b98f5619e7de9f35b5d4e1e27a2e3284166cff10d2499fb811"): true, + common.HexToHash("0x417f4dd2cbaa962cc37a5479a34df6f6240fb22138154fba52555ba28b388e43"): true, + common.HexToHash("0x8aa1ecc821b58d94e6a99b7366092d6fa74f84e600dac68b9e7e591c809aa3d1"): true, + common.HexToHash("0x845cedd2806330b49da857033e2ad7de47058e0da8aebcfdf1578c74ad57f5a5"): true, + common.HexToHash("0x31c03fd7783333c79dfea353836ccc0154d09b81a5098764fa0547fd44060a64"): true, + common.HexToHash("0x20c028e67b2b87084750e9eea4263a682de232c85eca595e7f6238225fb1ff20"): true, + common.HexToHash("0xe7926b7b91cfd109bdbcf8b397363548b4ac044749bca738d69950a945a0bff4"): true, + common.HexToHash("0xf0897e234d74cedab03c8bef978b962462e995457e69a7d0d1746689723afcb2"): true, + common.HexToHash("0x874d82f47fb329e00eb4faed70f386f3ba8ddd037d0588c2476efa9faf2a2f76"): true, + common.HexToHash("0x676f7fe49ea1216ca771af159d7325f6c0545911909669c9d3857e4f7aef74f1"): true, + common.HexToHash("0x7b06e0a4bb84e6c09792eb5d0a35507d5ed3f059623a82fa164b8cc977b87b71"): true, + common.HexToHash("0x2dabf55ea833208b85ec48077ffcb4840797fbb00940fd16842a1f631abe6125"): true, + common.HexToHash("0x1f3cdc6878c9c5ff5ab6bbd552c03559cedd1fceaa59e192539abef996d70251"): true, + common.HexToHash("0x49e0818eb0ce0b05d4f7dfc6b78d584f1fc0be63ec350a3d807ed7972e9ac681"): true, + common.HexToHash("0x033126bdef31eac5c53d4826912659cfcabb165d66f675a6bfeb30989e68e19f"): true, + common.HexToHash("0x32719b9d294871585f3a06022c137060644f295918ff22670b0eb64b8818c150"): true, + common.HexToHash("0xcd411becc55f7b44fb3c671fdc1de1b50e75257ae202f267e125562836e7c07b"): true, + common.HexToHash("0x4520425ffdc06ffd236344fdf0f4910bc525d469318578dc43719bb674e321e2"): true, + common.HexToHash("0xc0d70a00a2034d4a1be7d99c3847616da252fcffbf1bf50e8d7127d3b7d37183"): true, + common.HexToHash("0xa761002daefb84a394df5f20b984b0427584e7c5663e0388d4e622545dc853c4"): true, + common.HexToHash("0x14ad61c8fde34f94c6d66334361edf07adc6bfef59b848966b4c63a1b1126659"): true, + common.HexToHash("0x91f02e5acd8768ddee6cf3d8e673de103cce8319c12549bd35f0936bfe24e286"): true, + common.HexToHash("0x8ff1a3bb0dda7bcc11cda5c2d171c70978d2052dc385532c7dffac05a1499991"): true, + common.HexToHash("0xb78fccd05bcc77ff582af360a32dc4ffbcf23bb1afd7f47e4afc2656d4a761d7"): true, + common.HexToHash("0x18f1ffc80b66f6b9ef04710c93718691053ccd355ca1f62ed039a43667d40302"): true, + common.HexToHash("0x14bac0223a199fe4f2f47937047b3117fb8963693c25572d94c617bb56d6e9b2"): true, + common.HexToHash("0x675f0e1e9a0405468e1c09d8485337dd619fbdf2fc86983e8cbc8fffc25678a4"): true, + common.HexToHash("0xd3bc486909abadf2f858812c19f48f01c1cd1f8168309b25773659d95d5e4810"): true, + common.HexToHash("0x7ec54dacface28f0c6082db44bcff76aade541a1b84f663720bb9349d67d8734"): true, + common.HexToHash("0xaabbef04d7b7bfbf813c55b8c8be4bea0ad5a53df67bba939a395d6b121f13e5"): true, + common.HexToHash("0xcc5b5fb39e3523ddd30e02d187b022352660000d6b0e9d3f6f539db870710fa6"): true, + common.HexToHash("0x500a04f856edfebfc4c8462633d31f1b3cd167ddb9a25f29254cb74f3fe35e83"): true, + common.HexToHash("0x02585c194b85d9e61d9f0ddba54c3c63825a8ab244f70dd709551a4c7d487c92"): true, + common.HexToHash("0xbd0cb598b63e07a3a8c51003de165eef2f962d53b43e4950bcdecbfbd1aeb144"): true, + common.HexToHash("0x54efd363d4f3513236a69ee518419ccadd730a6dd206ee97c784f0579139128d"): true, + common.HexToHash("0x38920726de40e794f092d331f32253867009227f4cdad66fc51fe921cbe6c18e"): true, + common.HexToHash("0xced0e2e1c8bbe6144ea63b55147a8d87814e2089edcb7dde77c05a9926bc7df6"): true, + common.HexToHash("0x29a4d4cd5d7458e06b8f8518c8d093c6fdf5487de347c8c5f14707e1f308e18b"): true, + common.HexToHash("0xf7df6393fffe00a4b15c65d35625323ea7ec9d3e93eda3aca3e11e98005d58da"): true, + common.HexToHash("0x14489eda4f319bf552589caf26bafea1445a8dc4a9401e6df7430a4cc08c05e4"): true, + common.HexToHash("0xf905e769fcdd6d48c9b7a84be0d40d7472cd7c9f4d13543d4110b703e53495b8"): true, + common.HexToHash("0x5dcd9e01b8b5d5432afc99957d3fb7ef8dc591f964ec85045df24351dca53a67"): true, + common.HexToHash("0xa899bad67726f4b0596f36755c50d2ddaad6ca80c530135e53558a02384212bf"): true, + common.HexToHash("0xf04ace508ed62a49e81300bdfcb4d9e75d4ac5adc736d864291ed9baefb9f2ce"): true, + common.HexToHash("0xcf06ad1d8b409ea92f4dcc3bf70f39b752775018b790473e9be086e42b43d9eb"): true, + common.HexToHash("0xac48c29b53866e764809716f58836d9e6cd2ad06f6473efb5850f583e6d3bf61"): true, + common.HexToHash("0xee0b769d61721a470a8c7eace0fb28f606c9429192640d9ca776895a0bb67b74"): true, + common.HexToHash("0x2b13a184bc30ec5a6751bf7162cbc00bce0cbc4f4a71d68dc40822b919af73fd"): true, + common.HexToHash("0xc2c4168242eb7fe0696eda5966acb8c8975679a8deefec927b2acdccf6b912ec"): true, + common.HexToHash("0x6dc2463edbf56200c17283eac1b5ee4bc2c634dc2698e00c855d8fe5f702d4e6"): true, + common.HexToHash("0x78b711b2241e23f0e170fa50c3743f04faa32333ceaa439f6767e3d50aae77a1"): true, + common.HexToHash("0x2f59c17687201abbe7a4f9015c2cc1c5d78ec96ac5524e801243346b395a2bc0"): true, + common.HexToHash("0x4c7db5229eff438e0ae2b72fe60942a7fdfa0c6ef8fc67b6562c90b486781aae"): true, + common.HexToHash("0x788d200ec8b6f89f4a24cf22a7b93c3cd8b52568c79aa6dae7993b0344e191dd"): true, + common.HexToHash("0x6864046345b7a9249938ff99e6cf758b06e7dcaf72e506223587abf9c136d27e"): true, + common.HexToHash("0xd6a98c1e9c559eb50e01f979b5bc69d31a56527f3ebae6f61f6b5d60f4e8b54b"): true, + common.HexToHash("0x048b3f792465024216d185ea408e2e743839132e45486837333d2d2a3eed2b5a"): true, + common.HexToHash("0x7d5867d01d655c5a9cdc4e2137a9a23c0f759786ad613e39f0c034a5ca3a8f37"): true, + common.HexToHash("0xb575314f3a46509486d1758e37852bca5a3fc5c3793b7db34928481ce51fa574"): true, + common.HexToHash("0xa2bef8c9091dd4d0940a6e6262db4860bde5014cb1087b1eb3992a092314ebfd"): true, + common.HexToHash("0x9be56611c6e58d68f957f124fcc232169448fe6f36aa65e66ed7414233802f72"): true, + common.HexToHash("0x65554dfbf801073eba3c450c8bc9a4c6ffcb13953876bac9428a970912f47767"): true, + common.HexToHash("0xb6521c2f63ae2b17753992a535328eed3c9de1b861595cbafee46d6b74fa2194"): true, + common.HexToHash("0x1d5b3fc7bf953260f5ebafee86c43083b68a0761941267cdad6a01acd2da7466"): true, + common.HexToHash("0xbcc371984bfd19781a42025c5a7689a3af7f210448ddf4e1f45cfd689d39139c"): true, + common.HexToHash("0xcabca6b8d2a63440e8411a28134c44bca755605890bdd12c26919f2fe0751a83"): true, + common.HexToHash("0xb1b10879fa868ee35104b2c3b5df360c38b201466680180420314ce5684473fa"): true, + common.HexToHash("0xb89f62cbfb050808c4f3df6aecd8bddfe16a1009a0a0bd0c1e52e85f0f393112"): true, + common.HexToHash("0x28efb5c98eeb0ba3e692218d5f87e8703daf459e7342d51a13a689c08aec68ef"): true, + common.HexToHash("0x927c987b5b715e3e703a4aecc436d011938359ba6d5be22348e120212923e3af"): true, + common.HexToHash("0xf8187edd4c0db6af79f00bb9ca34f78077c94234dd590fe2b13c44e1d0e76d5d"): true, + common.HexToHash("0xbb69909e3b6db1d1b2b90c3b320fb65cf435a020a6d488b6135714f37c33169d"): true, + common.HexToHash("0x13e2ac43f22da72cebc94f78223714308fce9b9ce6c4d42ee7cbedb1d1901c08"): true, + common.HexToHash("0xd9d438fc8721a77626ade7c0b28f4f9c8d4bcdc57a8cfc16225409c158a2ecd7"): true, + common.HexToHash("0xd5d1497485ea7d86c30f2a01b173c8a17acbd1b3f15318125b7e965af8ac0458"): true, + common.HexToHash("0x9d251ab462ea30705977fe8922ed6b03fd062c7a848241a22c3e4aebd6c8dd14"): true, + common.HexToHash("0x8fbdf2efa509177ebd876d4ff80d4d64c78c593812329717c1b10ee3b95280df"): true, + common.HexToHash("0x4d75f1af7b20db58afd9f4b2acd1329c54446e13c60260ba221e2666d341e148"): true, + common.HexToHash("0x9511ee65d4554abbf5b30319efc985d07e2dc057c2d30198b33089a8b7244790"): true, + common.HexToHash("0xe69a1a6d1e2c8c9c6d87df6159d599702298ccb27e6c22595a46bc02fe4a54bf"): true, + common.HexToHash("0x0315f611fe9691e11465724dc0b3df3dd726d4de576f667205a8de7287c6e453"): true, + common.HexToHash("0xc4a3478757a9d9f4d277f412851213cf58a41b55e45e1e94a0dad45bd372e032"): true, + common.HexToHash("0xf444bc7b8cd97c00ed301db35753efde426bd618de14be5b6cde4bdf43174ea1"): true, + common.HexToHash("0x7891004e673589de8eeeb6b4a3cd9f0960a5781b013a76a95db121dbda1c21a5"): true, + common.HexToHash("0x50d41a0cc65587c17b6c79b42ca41d11fa5302dc0a962c96e85538bcb1935e54"): true, + common.HexToHash("0xe4b7226a210298a6cbe5ae67f7e529d4a3cc2a0d6455d6c8e11e8f88b895061e"): true, + common.HexToHash("0x1ea1a4744bf73a15a2028f7b6a5edb8d5e7a1b6260b92e3ff233cfac2ecbb46a"): true, + common.HexToHash("0x45f4ab83e29986952eed0eca8f9cd0f83d75857ad26dbbdca3b4da26782fba93"): true, + common.HexToHash("0x11f4ed9a6d09dbfb65c12af9c44eea31289d8986ca194e4660770b6ba412e5ef"): true, + common.HexToHash("0xdd8267a2f88168030f0aaa913a1e0e0aadc1f690f2211a4051e18239dc92674a"): true, + common.HexToHash("0xe45894a244dab320965a20b562c1eb536712d8779e1496c1d42afbd4ca4f5bd3"): true, + common.HexToHash("0xde0eaaed1b6c5649a279d0ea257fc443f997042ad7497d929337e99468338459"): true, + common.HexToHash("0xaf589885426ea60cae8cdfbfb585d02c5275e0d52c0a6ba31d0febd65cac0a0a"): true, + common.HexToHash("0xfc02dbbcb446c5e7792e77c6d5e366d3fbc87305ef6c5cd6c090ab9e631fc0b8"): true, + common.HexToHash("0x56a51fc3aaa67cf3e0bab2d19d8da9f2a8f1699ace5f08592c6c7ccc6acc465b"): true, + common.HexToHash("0xd5cd9d7f7830cb09c1d5b07078828ac0a4379add727ce036b9d1310d1193bb8a"): true, + common.HexToHash("0xf8814b6924928a1d071d843128918344b94096f59f13cc6a5796ba0ea85ff591"): true, + common.HexToHash("0xee278d3fa7bd12a65ac1ad4910ac05a22b2408001bf9944318a4d834926c3400"): true, + common.HexToHash("0x7f7915d0bcd4fac0cadb4c07104e6d821af89715f2833f8ce45df0d08f235731"): true, + common.HexToHash("0x2dab014d4db0b3ea63cf7e54eaa329466a14211a4cd2c98b24a6a6b012665bbd"): true, + common.HexToHash("0x65c6339dcb6fa21a2e925ab6d28a41d2cf485e2125b9ea561032ca8d7b5cd65b"): true, + common.HexToHash("0x8d75bd530059d0fca87e1af0ea721ccccc0c4cf65741da2eaac99b574ccc3a80"): true, + common.HexToHash("0x3f4b468f910924d263d1ffd48bc873d57f169370838b4b84f0fb09fdf6a6ff3c"): true, + common.HexToHash("0x26b1ce1e9391ba78f6ccf2fd0d024b2625bdc90273b22def1ecd8d390a214bc2"): true, + common.HexToHash("0xaa5cef13d3e6b9e3fb98e949b19b0c8e8cb7689f52bf132f15137f8a5ba80e33"): true, + common.HexToHash("0x731990a97d19e816f386196b979a60105fef3f11a3e6787ed4285146598a6822"): true, + common.HexToHash("0x14f910db139f06d9a6557de80bb114fbc292345485168f2ce2d5edde3b0e438d"): true, + common.HexToHash("0x46ee5127c2cd219d388e4c9c35b9b8da4e748ae7185dfd9aeeaaa9c815f2bc77"): true, + common.HexToHash("0x99b3a531c090369bd038f218f30d00f9ba2eb4efe330b3836be2457163951955"): true, + common.HexToHash("0x8d93be9f4f52ab67f2e108f0bbf0a086e717525ce647d0a8a8299dd5ac55518a"): true, + common.HexToHash("0xb85d26f33cce59c6e8493482e128545451aff0e5b3d486f613290b14cf67a668"): true, + common.HexToHash("0x4aec8e76dabfe1cc67d7740eb227bee6ffece898fd3fc2b5aaddfcea8a6d00ea"): true, + common.HexToHash("0x0bd3074bfe69336d03beb9aecf639c28d37f2ac5a598ad460437e8e439d9de41"): true, + common.HexToHash("0xb09d928c13f38326d9a156bc0dec458c89aa9ae4bbb7adf10b5828ed8c6f5dac"): true, + common.HexToHash("0x927c3e6596239263bf6e22bbecd458b476321a6c9013047436c26507b9167d83"): true, + common.HexToHash("0x979c7c1da3d628d528567512ae7607bf3e7c5a29eafecb4461c073a12104312d"): true, + common.HexToHash("0xda522ebbde44b98e385a06146683550df92a7fc7c337b014dd6f2f46f1850efe"): true, + common.HexToHash("0xccf494c197da1d83c3ba350a4bdd0e296d83ebbcb5fc5ae25f0fed33c9c5805f"): true, + common.HexToHash("0x177746c7e815a1956b431b84a6b21cf6a6cd4b4140f6708a79fffab53b07425f"): true, + common.HexToHash("0x3a7482bf04e4e29efcfdb217c638ffa7dc604421677f7264c237941d5d73da51"): true, + common.HexToHash("0xdbae32943cc4f0c3c2df162301eb018d2af194a010eb10d5dfa6ef82ab4e4b82"): true, + common.HexToHash("0x270ec04254fd2f3a683ec67c2f81146b3e4c56ac70553c49edaff0ea81a66361"): true, + common.HexToHash("0xaf190cb37fa4fcde131010b2640f7f57bb98d714f6793130aba9d81761326408"): true, + common.HexToHash("0x116ad0a00f97848d81c722806aa40e5317d4f83db9dd7b70cb5a82577bb502f5"): true, + common.HexToHash("0xf340b4ed116497d3d9e168ea3cc16920f94f8a1d2a63695bc9f022c8bfe6b5b4"): true, + common.HexToHash("0x5e1b14ba95b5f8b6a86b4c4ed8f43585cba2db857719014995099558d5a09507"): true, + common.HexToHash("0xbf44922423457dee7e11cc7ced6a8f978b2d7ba72fd3b258818b2cb19225c8ea"): true, + common.HexToHash("0x9c2dbf905d7efb9b6702ca5ae6c73b1a4e1c83f32f4ef23d320354b06e03413c"): true, + common.HexToHash("0x1003b01e178de66878cca4ecde9fda70ac7f1c3b89022605bc2ccb216ce1f158"): true, + common.HexToHash("0x2ad2f616ab21b598a6682dd6ef112c7e36073450ac3cf196d3c4ff5ac61a9302"): true, + common.HexToHash("0x407bc05f1a9afb3e4246c249aa93f3a0ae996d571dead28e6531513e63b37345"): true, + common.HexToHash("0x1924ca79e0a82517596ce11974bf38b497adf811b1e139d77d25f8bd29877647"): true, + common.HexToHash("0x2f9e0e206bcb1d4db3cae0d74f5dc51163aba36a851dc4bbd5f90ac41550dcff"): true, + common.HexToHash("0x783f251374ea4af4e3495ebd1532ffafd2d82f4f0e371b030b235850ea5201f2"): true, + common.HexToHash("0x9f8e9b8f68c058cfa1edb5b3b36e37e6313ca801194b5be2b2efd2d0b5919330"): true, + common.HexToHash("0x0bad023395e60797334a1c7927687fa7b65f8a94fb013ef11133006174d9655e"): true, + common.HexToHash("0xf4369bbb6e72470cffe7d0e3a56d5999a104e70d0f9174e367b31c157ecbfc46"): true, + common.HexToHash("0x70f50ceea1ca909a740d4d018dff27564bb23700443a3597d5857865775fb9f5"): true, + common.HexToHash("0x2a11357ef2db9847a02d6cedf49bc69b39d5997a490c19b978b72a100d8862b8"): true, + common.HexToHash("0xd347a0e40f9e9db5da49d23883f4b152c5d1181e729173a77afce22469555129"): true, + common.HexToHash("0x309174e9e133a50a9451748d25de7694fae86160f3e297ea41eb640481ae9dcd"): true, + common.HexToHash("0x8e3eb3a16c78ce069001470227edc15258c4e88dce6b6bf10f0d76ecd8dc06b2"): true, + common.HexToHash("0x6a52c8e4bd012315361d35ef9e5048e5297f32c98207830b2d5734b3ac618a8f"): true, + common.HexToHash("0x04591074c0a1332348b705e3e2e888d8c8f05a197d334754b2048671ed05e811"): true, + common.HexToHash("0x107d2c3f49ec64aa1417b718c523ba2b7f26c0b50937c23db1cba1bcf5591b98"): true, + common.HexToHash("0xc79663a1fce1e22b590895ba3ad65fb285d88ab53456bb8b635b7795ad7efb2c"): true, + common.HexToHash("0xcd0d53fa43cb67cd7d7186ab6d1fd663d59ab9e76897946cef8f3fee47a3c605"): true, + common.HexToHash("0x0c3a4a89043a2c3d81b9f493fcf86f32a44891342f44b88436d935c882adf4f1"): true, + common.HexToHash("0x42657c16c0ec77b82d83fdbe5d552a023d0a65abcc32c9a4ec72c3cd9b183c71"): true, + common.HexToHash("0x9a444a2679fbfa6ad61676d24b5f842236d2110815c5b8b4669874860218998e"): true, + common.HexToHash("0x6510bc34ec5e85208050e0f7b0d39aa271ac8f083c71eb7225943fa3957dc8e5"): true, + common.HexToHash("0x885ccca67770c8b403c51827cccf3022c4dd2dc2af7889a4e2f5296184dbb414"): true, + common.HexToHash("0xd1233f32f1bcfc49e7f3e17e9c50e79fab9e52412e2fcd7b8f8756af96ca1bfa"): true, + common.HexToHash("0x65e05abc033cdc4de39d9cace0e5687338d543e38c3990277463652559121ba4"): true, + common.HexToHash("0x8ee69572e7eee823321862cef61d33b140730a39d09c25be102417232b9ff845"): true, + common.HexToHash("0x528911ba5bc0ad380ce80737c30d7417902d9618bb2fee9cecdc18e9b17e12ed"): true, + common.HexToHash("0x4043d678e0146ec7b7f072b69b1567512b0b01f9e06c4fac38a78545f55ac198"): true, + common.HexToHash("0x68f1decf8ddb996c619069d9cef3815963f3668705ef487eae1b5902d6f34b49"): true, + common.HexToHash("0xb2bcdfaeca1c41cc043e579b18eb1160deec1cc7bb02a1f239e0bedc5c6405e0"): true, + common.HexToHash("0x257b4dc98aaf0710a89b0d7466363eac820c85204325504ea47ef5d17b17fdd9"): true, + common.HexToHash("0xb363d6b71e903a65cfb03a1a68368333d4448326f5d585cd9b95d17ec21fb575"): true, + common.HexToHash("0x05615f0f4b250d6d870132f065b5eb920740536c0196ca553c54125c58e885ba"): true, + common.HexToHash("0xf2695ad75dbee2d772c536e3ccdc4e2e8991e5d51e10cade4e67f250b337c765"): true, + common.HexToHash("0x8af414f6b15c47f306b353d86dd7cb7f1d17e62bd3b9dc89033f9c7dcce302b8"): true, + common.HexToHash("0x86e89ede27e3fd127c5a7df42241673c822fdcf1e23c804ee92fdd33de8104a5"): true, + common.HexToHash("0x0c5948ab50ce32376d1b7deaf39c4630ecbf511856aa4aaca751309f486bf66f"): true, + common.HexToHash("0x6de6c3cee854cf085c1c898f425692c6da791bf67632f2a4792250b62337c597"): true, + common.HexToHash("0x39375a88ef48fa5b9c8cffa96f7ceb95c51857cbfbcf9930d3f9810c198e25ee"): true, + common.HexToHash("0xa53ba5a6329799c579f42db4e55f5e3fb45a2c7166114a25d06fa116a6c16f99"): true, + common.HexToHash("0xb0066663447fe2da3c7afa1e04420fcb74c1104c1b4052a5ba3771feb3c4b1df"): true, + common.HexToHash("0xd52c14acb9dac0c54df1105709ac278dec98908babd92e0f5097fc1f5ffec332"): true, + common.HexToHash("0x89845e3a835190e77eb58ee3254e890ecda5950721a4ab4ad1e143685ba477e0"): true, + common.HexToHash("0xe582cd3eb64eff5edd0efe276e0081fd7ba372c04a08f24cd814292be7576a88"): true, + common.HexToHash("0x8b14cd7eeec1594e4dfec06e2f18207e4c7cfeaf66e1c180d498b769accafe31"): true, + common.HexToHash("0xb1b2ed5b129f926930e27b35c1170be9077a010ceca827502d8619b79d038d23"): true, + common.HexToHash("0xaf68bacb8fc42e0e2f553d90d0ae60537d18069eced235393634d86fa0333e8c"): true, + common.HexToHash("0xae941845eb561d9605f16b6c7f49924dbbb10d8116fb721c7de475428b0c308e"): true, + common.HexToHash("0xf9d88a28770f0dd86cdd2145db9a4ddb5faddd3e63909dd518078b50cafe4e0c"): true, + common.HexToHash("0x70e50e85c834755dc79f86fc390e7e735bf02b95f4444f27b668a1f26f1c42a0"): true, + common.HexToHash("0xe91be3aec073b45335bf30411c6c5dac614c6502ba333b5f949249b4717f1290"): true, + common.HexToHash("0xf9e0e417e8da4f2f4cca27ca57f53d8045bac3f54f6a364930fe4d2e52108c95"): true, + common.HexToHash("0xd7429b24ec8a66e35f0e176216007a702689778f8d8957a77fbaaf7789c7efdd"): true, + common.HexToHash("0xa30608563ef071882b44578df6c718ae2a93961abef93bfb1ded44cf688df54a"): true, + common.HexToHash("0x95704ef8e11248b409b15cbfd040d98ff06c714a1e676763a703b65cd00442c2"): true, + common.HexToHash("0x1def542f025dbd0cef93efe77e9967af24eac884dce5be3fb9c617c270b31c04"): true, + common.HexToHash("0x830891a8ef7781eab69b7b1bcef96003fd99762c7f64711dbb7b659d9495c289"): true, + common.HexToHash("0x086484d75ff8c0857024df6c44ff7eb299b1960867e12cd86c53ae9795bb213b"): true, + common.HexToHash("0x3fa3fc5c7dcbcf86f01b1a3d79e6a6d6d205f42ebbf8c3cfde2fd73fdbc78ca8"): true, + common.HexToHash("0x2f2cc2c91d40f97c09a0ea29b077140fe9571ad57c54e3f830fec67f2f4d11ab"): true, + common.HexToHash("0x275108b7c082443826c0c43e73327505051ca052b8927b86323a1bebc67d5f0f"): true, + common.HexToHash("0xbf704530ecab8a64a55754ccb9d88e68cbc162039fa7dca3ff2000a60e679411"): true, + common.HexToHash("0x1c65076f4fb7006136272a213787a8c751085402098575ad35aa96a66bf0754e"): true, + common.HexToHash("0xfd1ac45f1485d5de08f833eae38ed2dbdc576d09f38093ca88da9335cc985ea1"): true, + common.HexToHash("0x9fbdd036abb6015d89efd1dd26c1ff6228d37ccaa08cc43d645b0016dd4b5d28"): true, + common.HexToHash("0x925997fbbee307c40037427e1b99d9ea5396c28e0c5913eca7cdb118bfbad4ed"): true, + common.HexToHash("0x422157b20e0e83f5a9cd7a1d3760ff3635a24c5b67e3251408ed0247929f6346"): true, + common.HexToHash("0xa8c0d272323eb91b66df7a282aa64175d829d9a21e5904067ac14b1a70438889"): true, + common.HexToHash("0x3f32d1049f12844e5573a761b6762c5bab99f15de73a9f3dc77080d1fb210263"): true, + common.HexToHash("0xd64677cc9ac92d66304ffbae16a38a917dbd5a6a49945898edd7b73c392a29ec"): true, + common.HexToHash("0x30a3a12272b1e0a710e7e07e2df4db5108d69b1fc1cb9c71ca0ad4ccc419f59a"): true, + common.HexToHash("0x7702d5204b0ea2ea0cbd5561121dad81644557a0b858fb609719e0deece2a64d"): true, + common.HexToHash("0x98b56e15c0755f796f9e4239b6992e2576ca84f18dfca0af6de958226d6b931b"): true, + common.HexToHash("0x0284ee83a0d54929369c4d394525ba605d481c2a53e7e474a09c593d30f77880"): true, + common.HexToHash("0xd79ad8e601664b1b3947d965c49f356262d1094c9d2ea419afbde56153f72144"): true, + common.HexToHash("0xf1408c25260803f56d1a87165e9674170878beb68d3223c49cc60814878c53f0"): true, + common.HexToHash("0xb757f74b165b9a310298396c0c3b8137a41c59d6db306109d0a8eb3ce5dde1c7"): true, + common.HexToHash("0x5ae0904a9b7ba3ecc50a7142dfdd511112bc09746a361a132258dd714c3b6df3"): true, + common.HexToHash("0x0a33aad288923ca2ea47c3873108989173427ac9424ed0bf0a3b8be7b847e862"): true, + common.HexToHash("0x7a40059d3179b0c6bd9f82e55c016243b0e16cd76d272e374c872f634f17ddf4"): true, + common.HexToHash("0x6e7084f8f50d96365f9a678cc5e022811bc8b92238deddf0fdaa855b04ce15a2"): true, + common.HexToHash("0x8cdc25ce8ad5839bc7289a5a967ff52d5055f8ee3403743583e28e24f87ce7fb"): true, + common.HexToHash("0xda657ab51f9287f817c21c843b60ed26ebeae2a94e848d1e582a51903aa8ed95"): true, + common.HexToHash("0x3bb07cd66579989e3a4cb692ca4d1f00c53b728ed35550f7dd587e159e32e696"): true, + common.HexToHash("0xa42017b6553119a60901c0b03425f0157d1e83715ccfe2d230db48bd838d8670"): true, + common.HexToHash("0xb037c934a79f96574d2e15d552154d3431b4838e99c670794b1e37d71f385736"): true, + common.HexToHash("0x93bed2778fc7885291dd52de659a5e8a0c9c6b8f6d0daac9f0baa71d91a86af5"): true, + common.HexToHash("0x4846daa95be2fb1025b382903afdf67bef9734b47b8f8d083eb4e2611a7452c4"): true, + common.HexToHash("0xa8f660857df07be9f346c9a69fe1d27268e79ce56847620ae3bd24198d7e8222"): true, + common.HexToHash("0x5a11d62ecc71e9cc764e75ef31415ba1cafb9c5ebfbb14a5bc5bc3c5f188b288"): true, + common.HexToHash("0xd931dd4af02b533b23f6e9f712241e61cc7eab964ce4954777be84c802b3724f"): true, + common.HexToHash("0x0242a79393941c69210df482da365eeabb8343bb53935d908371a0a6452d25ed"): true, + common.HexToHash("0xc77dfcd110b622a973ad0ad3954bdfab37371abc816addf434c83bac26032406"): true, + common.HexToHash("0x4287b46a99e3bec14684e18efefd45fbbd28bf3e90e715fe9d389f08e18e3c7e"): true, + common.HexToHash("0x5123edf8b7f76f60fb541c97d3de25373a9dcf0e8f64b1d949e20e1247e3b052"): true, + common.HexToHash("0xd221abd482f6c63dc2f90357c22da28767a204d6e5b814d39170d2fef5006ac1"): true, + common.HexToHash("0x952fbdbff52a265dc28c2b35e449d7a559c5969bee16c471090c9cc134e6dffd"): true, + common.HexToHash("0xcde27c09b22ea859a20baea41461746dd09c9150ec078a51827f17c64dc3edf8"): true, + common.HexToHash("0x2c34d63e3d498deed65e0a474abd2c73796ba0b0fb8b51b0b31bc633272dc756"): true, + common.HexToHash("0xff1dbb4ecf6d7dc9f049daa25f43abfb114e2998bae3f1a81f1108c0009791cf"): true, + common.HexToHash("0xfac3efd74ed3f250b1e546f274ac6a41dbb31ce9bf0a253ba752b7131f99e816"): true, + common.HexToHash("0x022983ed7350621a3009fb0cf531224e85dc581ffb02a778c61b951101cc3b56"): true, + common.HexToHash("0x1b5832d8da96176484e811c26a32ff910067deb9e9313cfd448f3330ca662350"): true, + common.HexToHash("0x8871a3161c56adda03e0be1a44f245f962628bdc7cdafa959e493b5ba1b8c3ab"): true, + common.HexToHash("0xa92c6e7b8f550d0d82f1c20434ae8e137aebe0360defb5602ff4d47ceba7d8b7"): true, + common.HexToHash("0x7b20b960eae02f707cfa32581880459381061af600aa6e38e6aa35fcdae6b068"): true, + common.HexToHash("0xc6b5c36d04089dd870aa73509fc6edbe0b4af72893d9d36cfb9f29bc5a34080a"): true, + common.HexToHash("0xea853b01d8bd9d63987291a68dec0627b9d164cd4446e5b1fba1394a816a323b"): true, + common.HexToHash("0x964f8d80f4d4090b702d55805e6a9b5bf036d5cf3deaa42b80f13ba6f9d7cf8f"): true, + common.HexToHash("0xa542282f391418155303e724b486257763f8843b44227a6129c858aa08f1bfe1"): true, + common.HexToHash("0x1ed9947501572bf45d38b1332124413116298f17b2ec360befb955b6daeba73c"): true, + common.HexToHash("0x30f6c14efa856cdba459b3f8252450b1cd5025b314800d75a629ac9d824b5c48"): true, + common.HexToHash("0xd2189037a8ab31b7e3106fd733d523f8fcbfc6246fae407ad65b22550b8f62a0"): true, + common.HexToHash("0x35c776c73a53c212b3a06325779d7fd77cf95e454d927bce9b2d004381fec858"): true, + common.HexToHash("0x4122cf010141fc35e7db3b4af46c1724903a8397fe3ea8811d5a88bbedb9072d"): true, + common.HexToHash("0x7c3f7c22bf9bfa250d456470278051c84c8a6a1996ec8ee7d7cb331596cdda53"): true, + common.HexToHash("0x3f1c62b30619535724567c74f4f83161676aedced76dbec566930abd4348573d"): true, + common.HexToHash("0x1e957251ec7e61407c0abeb5d7f290179640b0ee2bf9c69551a08be907715f66"): true, + common.HexToHash("0xd0df9d084bd019ab0a98f18b245a172c5b803e380b886f6ef821e15a1d4102fd"): true, + common.HexToHash("0xbd4238d256d1c3dc760e34a720a105330fad06b8c051a117ae7b16a0adac8c58"): true, + common.HexToHash("0x4530ecf03e101da3c2a536da20d18ee820f220ce5ed1c3eb54ac0257c4f098cd"): true, + common.HexToHash("0x96509c35ebd51ebb32a387ec04549f6297b6c1d15d40689c9d7c10d593418992"): true, + common.HexToHash("0x304246e20a33d32fa6ca68962e98d160196a7ec9419f6060ca34da9c9087da1b"): true, + common.HexToHash("0x1ec304aa2b98dccf46bb2624d8288499dd4284cc9c17513896ba33b60b8ca206"): true, + common.HexToHash("0x99e32e536089f9c5def5a22d8b0d0411417a277526929b8a363e2532988c146e"): true, + common.HexToHash("0x35ced9db086dd3a05c2747724abdaf3e70e9fd288a07042635cb2433432c93c7"): true, + common.HexToHash("0xad9b361053bccafb604820e9b1f2707c4c77dcb77071116456edcfff5efa10c2"): true, + common.HexToHash("0x694b60af4be575b7969b10eed523b954fb2fd49dc0581a5db74b1b428bf49a35"): true, + common.HexToHash("0x47b1432f11e155669265ecc9d2b16e1121604632f15d062e790e9141900eb926"): true, + common.HexToHash("0x6c6f1ef21e422427d737c261adbb162c4d4b3d1467c55302c2751a14e38f391d"): true, + common.HexToHash("0x8ceecb00bba12f4f4bb4e4913e069652c9dab4fa693e81f42ed921860500305c"): true, + common.HexToHash("0x63f0421f9a30a54ea223e7cacd60053e54479d1eac54767cc70cba8deee8c77b"): true, + common.HexToHash("0xd6998651602f21500e4000722245547f911e7b8167e572edf2fb2297de25bb2f"): true, + common.HexToHash("0x7a91de10d8dce24ba7439e88dfa4928af2a770800eee1d200b4a436d4c85edbe"): true, + common.HexToHash("0x8c154059cba0c5a2de12d32f868783e67d3cf0b794e95b8ad624a510b1222335"): true, + common.HexToHash("0x336d9f4f5b21c5ae02a978f3cf992b41450ce815255b984e80a868186529da02"): true, + common.HexToHash("0x9a037446fe9f3273284ac7eab9d2551db776d19d857941ebe2532659ddf019e6"): true, + common.HexToHash("0x4260151dcc9120b113d2e38f9b0b30804237c744920b6146ec9e06cd5d46fc4f"): true, + common.HexToHash("0x90d4538246dca53f1594e4b76a8a676a68f69b77c445723eb51b8aa98cc3ba10"): true, + common.HexToHash("0x412fa8362cc7c6e8ab33b66be8f891adf7469f6d71bee152257b5a0e348c101a"): true, + common.HexToHash("0x1275438572918f872d1fcf8dd0113bb0a8c6de46ddafe17cf096aaa8bc3f6477"): true, + common.HexToHash("0x5f3f07c7d1884409369e466568310eeef04bb8c4c10b1aaa4cedf7f4aa35a83c"): true, + common.HexToHash("0xbb261f66e6333d27b891a7683bf26befc625b2855032f19de3a2de761e0d9ba8"): true, + common.HexToHash("0x6bf377a5f31a54b1251190ae9a498b7e3e325b106d76c935a8aa026d8702aa77"): true, + common.HexToHash("0xc457d03349a94f93b6b0bcf24dd74d056904b19d53a209a4aaeaad5185b53c32"): true, + common.HexToHash("0xefb27539840775b41a011d892e358c9e84e42012965f27e3c8d1d5ee6982365d"): true, + common.HexToHash("0xccb4e3a2095294c0df0ceea3f3a9c7618952935b2003ce82f1997c4dcd15b0ea"): true, + common.HexToHash("0x01557b0ae2c37579068263a2cf2b70b15be3aa814c93308cb510743d903123e7"): true, + common.HexToHash("0x9627a8cc1fcbabcc746779a75cd8a09cee78353038f0ed890d4688505b2e239f"): true, + common.HexToHash("0xe3f861e11138cf92ebbd418b6731767c64e757d474f99233fd6e0c77125263d9"): true, + common.HexToHash("0xb3e7623a31cb7ee8e7847134e92e853d2ecf0673608fa62018464bfdb2d2df67"): true, + common.HexToHash("0x457dded3f3800240473873aa646e20903e6fc2ac8da74f18d426aea5ebc654d0"): true, + common.HexToHash("0x8e0e3b345576950449545ef345b661afe02d7f8066f4792368b826a5501de2ed"): true, + common.HexToHash("0xe848844eca7acf4922e01b3ab9313ce70befc753cb9439cb6d19009f350d7245"): true, + common.HexToHash("0x048b6fddc3b36bde07408c0804ea7e2592c58563b59b59a711dda51a462ceab7"): true, + common.HexToHash("0x21baafb7bc2a72bed1e982251f1a937f4f3ae1fdc2160f2571b4c8dda60280b8"): true, + common.HexToHash("0x00d39ae4403c002bef4e31841910ded360623d5b6f76ec838215e7095d3aa001"): true, + common.HexToHash("0x4a7602f51712057cec6f097f41b19add01b1e1350639d8f763d90b749006c63e"): true, + common.HexToHash("0x855f495f32e6d37346f767e1f8bbc4e9112fa3a508a9e31319eb91cac0cdb899"): true, + common.HexToHash("0xde5f661d9d73d7055e18b9f98026b341d3e412db6af0f425b118bea62e8a4a28"): true, + common.HexToHash("0x255a0f8f7bc707d3efbf9dc3e5e67105e24d7b5de6fb0711777e77afc8c6e13c"): true, + common.HexToHash("0x675aed220dd66b85411afe1c2af62c2f2057b73ddfa96209dafef0319734da0b"): true, + common.HexToHash("0x4cf707dd5f9c365718d1823cbc1a893343ff216748cbac25a2cce1d4e6fdc766"): true, + common.HexToHash("0x7104af8e9431a62f570af29c4c2f5c64a42379cad408b6fe06a065e48848fc90"): true, + common.HexToHash("0xd2b56bc453c3ef187b76dc12c30f06fb93188008faa755f8512d2c32fcd186b4"): true, + common.HexToHash("0x2f17f208ab3ad3e0d8d18287869f9f60140cca9751bdf06e5ab30662511bcf0b"): true, + common.HexToHash("0x32ccbe12883eba01cde8c371602a78e4dff7b33d4fb4b4299bbc2e0ee94a8414"): true, + common.HexToHash("0x350ebf7977a80b6ddbbff343818c8fd34a94651e5dcb367e4dcdecdf1ef7cc32"): true, + common.HexToHash("0xaa84faa88f103930f11ca9f257a60b4ea3eb6ee4f2bda76819fd838643910b0d"): true, + common.HexToHash("0xe8ac1469cc4d77dd1824a805b07c4d995ad29f03d9f1a74ff4a929d0193ffddf"): true, + common.HexToHash("0x12e0b76058b08ad20538c3ec1e97c4f1c5155241bef20e8cd8f34a5c40f038f9"): true, + common.HexToHash("0xea607eadb3d3b7f30e6fcb62b67d6a99f040c5b0f95310a57363b16daad62262"): true, + common.HexToHash("0xffac8d9d87159c62a8ef26640aef7b89afb2c9d2f110479f60fbf6e71e4d65df"): true, + common.HexToHash("0x050570d14354f56cf7bde0e449fce34311d3b093565ea48929e928678395bab9"): true, + common.HexToHash("0x5af8264eaa7a41de1d9d1df8d81b5d1c85f5ce7bc9b5429bb76efa3f73e8ee67"): true, + common.HexToHash("0x399f90f8027ce6dcb8da9f9726e2def702f95f062be9a6671024718029976444"): true, + common.HexToHash("0x2f756af78ac3997b2bec8a7d22bdb458e3af4a169ac88524b1eb050880e05b0e"): true, + common.HexToHash("0x222c3cc7cd49d2bded88ef53f9752d021f3766687d0b9869974a91339a1fdb23"): true, + common.HexToHash("0x6a035ac00eb0ecfa0e35b3ecb3348f6b5bdb624764ae037f4208c3b7c37187b3"): true, + common.HexToHash("0x177ab4f09e06727de2bf27d1943c7d031355324836b9344748c7d97160206f15"): true, + common.HexToHash("0x42c340d2accdb95dabe153917ccfd9294f2bb99ae2ed24c377780cca27d4822a"): true, + common.HexToHash("0x4d5baf352e5a9f35a92b295371754373073f2f8d2cfa6a10c842ee00e787c0f2"): true, + common.HexToHash("0x5881d4874144f1df0cccb35a4203e7ab19eeba98604706618efdd6aad073b201"): true, + common.HexToHash("0xcabe29abc1a7fcec68f4338aa71ee4d07c24ed12bcbff949ac25c75e2c3ea7c3"): true, + common.HexToHash("0x4dc09800bad13cbc115a264863aa8a72aaddbb89b366e05aa0800c63d946578d"): true, + common.HexToHash("0xbc1df678a9ad0255691249bc499ac01b628d1a39953ca109540f1d174e3ccdba"): true, + common.HexToHash("0xf870c9419833b1a2916e96baf79384eb29d0f82c09e3bd2e27aa96ce7b0da601"): true, + common.HexToHash("0x0ac088bd182132e2494ee65e3f5753bb4c57aec44ddcd89068178bc6d3ef4d00"): true, + common.HexToHash("0x6a0987cc63d26f3004116b52dbc264e84e0f58080f4ff560d963bfb78ad592cc"): true, + common.HexToHash("0x550d3ee274cf0fbffba1b8ae4abf9e164c63bba42ec74985d6f577b00a91daee"): true, + common.HexToHash("0xc33f99b63094dde8ad5d33659daf0cad122be69487e83bffcfe587445b1c9472"): true, + common.HexToHash("0x58be4c8f3c37341309f0d408178e45e64129896dceedfc2dc3fe34948c398f10"): true, + common.HexToHash("0x7a799f6e5318e38248df754c4cf362bec4a411c7113f3115daf4993a67c5edbd"): true, + common.HexToHash("0x79c287e4af23fed58c53aa8b2180758fa74837b66fc8a3c03e4bcd1ff135b529"): true, + common.HexToHash("0xba2a2d7095cd3d6e80f7cd33a7e38177fc9a3adff3b0c1c01f88f22746ef204b"): true, + common.HexToHash("0x8f08405cd120f56571d8ab0740de369fc566318f756cd5670c7a8396c6464db3"): true, + common.HexToHash("0x3c28f247109036eb3f9fcff2f8c9959cc0ed881bfe3554e57a2d0d987dc07800"): true, + common.HexToHash("0x1306cbf4423d6bdf89ed8a7817c03ffc6cf5e13919c5fbf803f288da3d3e7925"): true, + common.HexToHash("0x3a910c9ae2321a3a9103cac7d9d19e04d234d4e758bca3c0ef928f47e6d15896"): true, + common.HexToHash("0xc1426406007cfd281eb5eca1e4875d0c4e28255763ae4a35ac04dcc021ed65ed"): true, + common.HexToHash("0xea1f030435b5aa37e746b232c020e9f9a603557d3ebf95fe1c99515d8d308033"): true, + common.HexToHash("0x2a6a9a3381a09599c232ff969774cd2b9b39a050e42ed68c419dc70f5941fb04"): true, + common.HexToHash("0xd1834a0fe16a195946e834319f76d4382100149166f225252b491a892d0ff59d"): true, + common.HexToHash("0x1e3760632869669c408b39c89c549e3f9e63a24d750cf3e2fcc720a8d220c219"): true, + common.HexToHash("0x288eb45f334a360ada3811dd776e7a46dbaf545c93f52d35a4caec81fbb0eb0f"): true, + common.HexToHash("0xd40d05b714fd8f6e16cb27e18745d2acb26700f8d75c852d219b4b987af5f45c"): true, + common.HexToHash("0x5560aa37e4678123eecd56d1f2098835fb3891a2cd6aab2ffe881cbb316db59e"): true, + common.HexToHash("0xb548151d7303a4f8a66e45a5c6f5a6be8d273a9a8a10e85c29dd892bda17ef76"): true, + common.HexToHash("0x973e09929330386e0a1bf5eabe903bc3e2f165b538eb1d61196787902de98ca1"): true, + common.HexToHash("0x7881dff9ab062fb9341e94291c3f66c141d8404922d41ab5dfa606402115e384"): true, + common.HexToHash("0xb855a070ed273a8c44e7b0118892ed4e2f8dc9b020150f3fb331f779bec2e741"): true, + common.HexToHash("0xa16af3e2f0e77f869bac8f3e5eaa17686612e150495d1571220479a5ea32cde5"): true, + common.HexToHash("0xb019045e448d13754563c20a2105a41991b1bf4c6f8778825c24736f436a8ff0"): true, + common.HexToHash("0xeb37bffa9c54578fdcf70740b039249bab9813bb808f9b979f25106ef34d7043"): true, + common.HexToHash("0xe4643e118e59f67171e0b8689616043e670a9acbf4b3e3e93d757ada7a1383b9"): true, + common.HexToHash("0x0b6e6abbfc60e5eb9f734d5b0a4f914434913af09b650974f3ecd3ba406fdddd"): true, + common.HexToHash("0x1557a22ad02b642fc7e942c63ec60130010b85783e9c936d8861b1cd35ad9261"): true, + common.HexToHash("0xc7a2542a5efa06f7d5475f94c9a251876e5e65acb8f13854644e8f03266b6c62"): true, + common.HexToHash("0x1a6cd45d326992ab9147335a24b822d913aee7f458a1154cb16a1a480f986390"): true, + common.HexToHash("0x0892bcb51dbfdff1bcae2243753a16edb219314d426086fa22267e7d3bcecb39"): true, + common.HexToHash("0x9928ffbab398139fceba6b43b25cec86b07a025bb177a9d770e92a22a4530f8d"): true, + common.HexToHash("0xa1728737fed245d991369b1a3f28d8db841b5d6600bf9476e7a2c8d774ce73e6"): true, + common.HexToHash("0xf117c577155a57ee6a909180c6c44f63b80e80504b0b6999a10af928c360ce82"): true, + common.HexToHash("0x8ae61ab75341dbbd4c63357d83cdb83e67aed3d9c35dc48a684aafd645b7373a"): true, + common.HexToHash("0x1fbfc44c633181852af2bfeddd16a020a452ef64df478cd56f18a12b51c55f73"): true, + common.HexToHash("0x9c139d3a16622ba994abd5958c9b6ea9352e03b8c00a881c61e75eb9f6e29451"): true, + common.HexToHash("0xfd2d35b9796f49d5aa490ad5210aa7a2cccabeb6d9a96eab0c5cf72144201d59"): true, + common.HexToHash("0x4ebc7b7c598b6fd37dbd14a1da92bb8506c8d88a315293c46f72cd2023df91a7"): true, + common.HexToHash("0x34e028fd72d269ea29131c6cd8ce0ff6d0af2c98f4af5595f0c2cf3a38da4fab"): true, + common.HexToHash("0x0c3bd31dc3d81a51b095b0cf29ecd96cdf97bf454007ab6c2e8c5a2ac62fb6cf"): true, + common.HexToHash("0x4aecb34a4ba83d842300983ed5f27439c7f27c4d17b1be109a1c14726e66e4f9"): true, + common.HexToHash("0xad66401c77e543577682fb96f749b1fd8f474c629312c4ca086a50249a937bef"): true, + common.HexToHash("0x9d192f69197611fe7b56f0f87911e38b72aeacd6b9af07bd29b59e61b351fcc0"): true, + common.HexToHash("0xe8113b46a94599da40391ee85f37adaddf8c301dfab20d5df0101bda95ee0e9c"): true, + common.HexToHash("0x15edb2e9ec759c6325c1c38e9587938f2731d7b58b81e0740a95a566271323b8"): true, + common.HexToHash("0xdd93f1c24e3000d123a846f6657ddc21ffaf13630344deecb7668382bd268465"): true, + common.HexToHash("0xab2e5df3cd65249401bf4686c5c43f80a4fb381ac09b5b0be2664a00dd979ad9"): true, + common.HexToHash("0x8cce7656412df17b59e02d6caf3eafcd619cb593c9ed5a1c240af99ce37fa4ce"): true, + common.HexToHash("0xb98806fb7cd6e8a5adb3365029973f8462db9419d7d64ebfe1fc74485b236c19"): true, + common.HexToHash("0xed6e2b0795b909370688241905765bff748407485d885a3f43fe02a22143e63c"): true, + common.HexToHash("0xa365c24cbe62fada35f807513ff5ce9315e7587182fed82c7835544aea23ca14"): true, + common.HexToHash("0xfe4777c9d392f93f03e3eda3b297a478254fed7a88e25193ac05f0e16163b6cf"): true, + common.HexToHash("0x5e666339b2d5c5928438df8ad1f12d85e3cbe6dc5da4b9cd5d7de85aab8d5d88"): true, + common.HexToHash("0xb20d6a343c823603216ecb8df0033d6f42be6e055ae15d2abb315585ba4790fc"): true, + common.HexToHash("0x22d4a813714d193bcd6ece99e2f3d8b1f5db8fa3a54b52b7a463c050e622cac3"): true, + common.HexToHash("0xd5b9c652167c2349b10740d5ba9f7e5095a427630473af6f42e68128fa142034"): true, + common.HexToHash("0x1b8037fcea856cbed93b6916da35b3d3589f4e1792399e9fc40091295dae5073"): true, + common.HexToHash("0x9eaeaf2448789f254a1392145097553a6236b75989de5ddc6262cd50bb91f2c0"): true, + common.HexToHash("0x60bbdc07af2e5c5f51f55bfde0594ec55d5bef74282155524813e22ef519f002"): true, + common.HexToHash("0x3b9adad1fcf45dc71f9f357539796dfa8715459ad247c5feeb6559f1ef717095"): true, + common.HexToHash("0x976a8b2995c947041f6be7bb08e50f864340fada4be02eff701b6f2cbe0c8037"): true, + common.HexToHash("0xd1a40a047915bbcced79e3c3e7af7de78246cce369241f70a2f17d6dcfd99b0b"): true, + common.HexToHash("0x2078c29b1d8183cf3799136c23b997a0e44a9e09f1dc5051ac695426ec810d8a"): true, + common.HexToHash("0x8bd1c98df81a2af507a23ae073b0ec0fadce072e1951273051dd03afd872758e"): true, + common.HexToHash("0xe329020a18057a8cf68aa3a4a8f2533f2f4a7e2c4bd2400044b933cc60280dd5"): true, + common.HexToHash("0xaee8abdd8871c481edfe4b77f604c2157d9488f29b128d31b7807cb678b04303"): true, + common.HexToHash("0x7d1fa7c5fe5c90f0e85756cb4f61af198cebb597d87870d75de17b9e357709b7"): true, + common.HexToHash("0x88622c0428ad3d9efbe28df3d21f4eb5bb893b475a827e056b6735b9f3937c17"): true, + common.HexToHash("0x7d56620a1c743c146d385ae7ea29b6dabc7b42ece6502357a0f3701c0a37c068"): true, + common.HexToHash("0xa5586d169f1cae588ebab0b41d5a655ce3ab265aeb15f8726d97b42751a0506a"): true, + common.HexToHash("0x9ad02381381d886ee7e0ee4c6945e45365b04e59cb42c77f89875e1359d81e40"): true, + common.HexToHash("0x30468631f00f39e9363286c77d284197074f30e7ec7d3dedf5c6c750004ae8cd"): true, + common.HexToHash("0x63dd76525456ef4fd1a15cfd61f9a0f038aeff24765006a3be3c44775381afbf"): true, + common.HexToHash("0x99a0f2af744228016c531ef2ea36fd813ec07c57c512c08c59776bb8e9e07a81"): true, + common.HexToHash("0x494ada7d831331c71a7eefd59ae7cff9fa8e2487ad6d679cff231368339a3c55"): true, + common.HexToHash("0x19fdff97ca257471afcf1180ece7793dd053b6d11db50407edd8f2da6cac39e6"): true, + common.HexToHash("0x633023e7c17b4404bd0e8585f7a1ea899ab70eba8c0acd4ff32e30ebf7b8a115"): true, + common.HexToHash("0xc9e31484f1a1170df05eb2b71dcf110c46cdf2f91a104fc9021c5bf5d0e85dfd"): true, + common.HexToHash("0xe25dc38fa7a7a365a19db47bbf97ae7e71b91f58df397d09fa3a5a138381d91a"): true, + common.HexToHash("0x802605f4da19ee8dc2b812273b4f3b41ba3799c578527f89f8a314fbbc4ec724"): true, + common.HexToHash("0x2c60b16d4c036b7aee3d17d851493c1682569a99942aa8a252d48a4e3dab539a"): true, + common.HexToHash("0x914c7b180c996df3b7b96f495f5decc9bd2793ec492a385121a7dcbde7678ce2"): true, + common.HexToHash("0x8367a3b9243b75c4100cd7d66dc19014729a80a338429b97d4ad2efdf60f2e09"): true, + common.HexToHash("0x9b388e88deaed0b1b30c1c387b3861f95febd629193569516b56d9a40b0df6e9"): true, + common.HexToHash("0xc9f886e8ced76f7b3d89c676e346e7fd0cc6ddd2b66b74e0d0bdce47a175cc17"): true, + common.HexToHash("0x636cdb15139be6fabacb881c77a55c146d477d74971a97cbf9c88f7808969a18"): true, + common.HexToHash("0x323e1c538f1df202c2928f9e9279b7733e2b5e18ecd5c49d5aca53fb0241dbdd"): true, + common.HexToHash("0x67ea149edaed68d38176a496f84d8fcb014eaebaa2a9af300d3c02d74352ea20"): true, + common.HexToHash("0xd6bce857bb24d4efb51c2d78b7249a0dd5801d08db275a1a14ae44a76eaf0c37"): true, + common.HexToHash("0x72bb5a6693eba95a57fbec528cadfd5570d07772ee5c3abc3f5f9a21339722b9"): true, + common.HexToHash("0x6fbee03468f144e98ffd07d9af4eccfe517a16f07e384a54f0b5e8fe97c6c3d3"): true, + common.HexToHash("0x0cb66a89736996888280d5860b1f62fbc133b1cf7501e14675109e733111e2ca"): true, + common.HexToHash("0xd97025b4efe6e0607b038d7176e02929bff2db9e66bb58390e607911638c5a54"): true, + common.HexToHash("0x227fd9f5f2c814e033e7380205761d2470a384ca36faf4c4da8a11d75b22c070"): true, + common.HexToHash("0x8e017065ad8b4ae2a25a7a88943113aaea8b2dff9257f89c8ed2035ebb149858"): true, + common.HexToHash("0x8fb2770c9470a529a263cb1055dd174c208245976de48e0431a8748732239e2e"): true, + common.HexToHash("0x2cd3a002d1c33df5b6eb8833f6c2c294805b961f44aa6a9868e1300b9caef0ab"): true, + common.HexToHash("0xaf13fb49eeaa06a9154df6992ec7c0c7114838858801fe9f8b4edc1cf406e422"): true, + common.HexToHash("0xfdbf5c8f17a258d44cea13ad6cd4d9239057d7eda3af9b3d4e95fd22a7562aab"): true, + common.HexToHash("0xe0b6df5e22e6d263c64287ec5e4b64d3d61fae0c860800d0f72ce055d9773921"): true, + common.HexToHash("0x98dd8ce9df13dd763b493a748359cef821b6e50daded2181ba14abab998b80da"): true, + common.HexToHash("0x5ef79687d0565fd72f32a7bf0f311cfe026bf5a6ef0e3aad500c7e80f6da8b87"): true, + common.HexToHash("0x28ed9df1a4decdf0475fe2343a558d4e015f9c4efe9839c440fd03f6b9c7ee9b"): true, + common.HexToHash("0x019e43152b04ea999e0f85c7618d431cdf6cc9d1ecf8dc71c89c20fa3c78d3c9"): true, + common.HexToHash("0xbb66e2a2554188bdbed5ffe5fcff58e0678ff73164bd71e2f75ff865ff64262e"): true, + common.HexToHash("0x01d690583e3de2f59e1c75dc6136d3cbe7d6677b4d274ff31aa20f0fd6fa62b6"): true, + common.HexToHash("0xd76fcd1cf4fc95325eb1b6b86bd4f2c74ef2c2f384923b1ee2f1c507542e37b4"): true, + common.HexToHash("0x0b376c294c6992d104af00dd93309eca05e058c341197f7ff3c256e1923e59c4"): true, + common.HexToHash("0xe58e2cdd68e2881a23f1c84b19b300f61e38091dd99c034c9dd2d400526fc25a"): true, + common.HexToHash("0xe74c14994fa2581c9bbb17c586481e17690a4259fbb2425a7b8409ef717b369e"): true, + common.HexToHash("0x1f2b97b1f27e7e3aa809e86f996b6b6227da5bb50ceee0315e393eb913f6a9d9"): true, + common.HexToHash("0x09554dbc65d50a120d95384cd04665cf85ecf2909d7d4ce9abdb3dfea3d6409c"): true, + common.HexToHash("0x6e3f357ccb062373de43a266d0cddf290414ee7edaf90e6bfcc1613dcaf28272"): true, + common.HexToHash("0x845e11c597d474e8ed77e105bcc4c250662ac53adc47389cf8b5912d6e72e695"): true, + common.HexToHash("0x2898f62845aa2abe6af16df17e2e065d77f09b23854361b7628b9a2a02b67bdc"): true, + common.HexToHash("0x76d63eba9de8ef572a42849408168fe7dac41241503e511c5cbd258abf6343ed"): true, + common.HexToHash("0x18443599f26a066bed3f10d8b779385c2d38cb47e6071d578189f7bb41464cdb"): true, + common.HexToHash("0x19edefa786ed9f1bd4cb6c2c02dc3a23939bbe79c0d891bdd5249dae43626273"): true, + common.HexToHash("0xb1cc159bdab2e5df2d2e8e9851327cb4e134866de20ab6acdb5af9586996ea95"): true, + common.HexToHash("0xd9353122f91e8a85aae3d946316385bc2b352838e4ecfc1fc8ecdb4cbc7e06a2"): true, + common.HexToHash("0xa0de135251ff4de5d1feaf1bc88fde0d69dc992bfc5e926b4a3010ade3774add"): true, + common.HexToHash("0x535bb236a12768612403bb0ccc0f5633aba18ee00c698906e1480bf90b1c101c"): true, + common.HexToHash("0xbbb6a75f6d96e2155f6037b49441511b2e6cd2be905c297ac9694dc949ea56d5"): true, + common.HexToHash("0x06a75cb47c7de6a464424582e55163727a6985c5d7129170630e984362a096c7"): true, + common.HexToHash("0x5962dd40b1b038b208745dc9fc8d77859cb12b7249f5500c90bace2c81eeed18"): true, + common.HexToHash("0xd4b090bf741a3ddb8b9947b1297d33132498fac93431b25d0ae48b75fe47159b"): true, + common.HexToHash("0x29732e7b55aff9564a5e027da8ef64e4cbae975d6c74964416570a8bf03a2e69"): true, + common.HexToHash("0x6c1b67338f8a6c29629a3042b0292abb51ffa5f507484271ac8b9bc2b4973e1c"): true, + common.HexToHash("0xa46a5609faa9c857aefd1daad3efedd44dbe9a3d75abe3daaec286db1cd904f1"): true, + common.HexToHash("0xe18fd9f4a11afdddc4dd943d238e39c4a65e0981192be8e516d7770885038605"): true, + common.HexToHash("0xfe7417b36e55b6106944ab60e9cb2f6874854600f4a3f14de771ae499e33123f"): true, + common.HexToHash("0xcb9ddd1a47c778aec18a4e55cd6b2445c839eda3a65b9a7599ed692a891a10eb"): true, + common.HexToHash("0x1cc001e25622b992d5b44b872f8fe72d8040dd3db520909a2a52c9ed1a75f784"): true, + common.HexToHash("0x83d331ab3a3e59ade0ed07a99c6c38b0ef57aecb775097289c0e1ab1466c40dd"): true, + common.HexToHash("0x1288be02d3be0235b2e43135e5c572c8ed25c2188244851e994501274acc56ed"): true, + common.HexToHash("0x18a6141426bc89d482669fe6d8fcec1882a208ecb735ea0da221e7bfbfef7193"): true, + common.HexToHash("0x90c1306a4f31999bf63e031551ff5dca6a5de19301e1ced1ea828930e411b35c"): true, + common.HexToHash("0x2f9a53db7787372edd8625643ede618de71e9cb7ed2629339ebdd4f2d7f4e95d"): true, + common.HexToHash("0xe756dbb5e3c59762930013f46d57ded35e7ad85745ec11cb8f1e726789d471cc"): true, + common.HexToHash("0xd1f29676cbe907ebe1f4645a6d9cfa429465797b7a42f5eed393e5b2af3154ab"): true, + common.HexToHash("0xa75872271fb9018bfd4dd42a6caf682e5cb9777e62a244bef39f0665d5ab49f8"): true, + common.HexToHash("0x069c328a84cea9ccedea5893c782097c6dbab4ab24efd3951c2337ec6a12a3a5"): true, + common.HexToHash("0xfcc1c1c8f3b2ac8ce1608a3821e95e082279d176c48f436fb3a687ed250bd979"): true, + common.HexToHash("0x450d6dac79bf89cbd9ac2b18c18d1759409e19cd0a2b6d4a5cc6e7068b2a0a4f"): true, + common.HexToHash("0xa561493b737141e90a45c01b9d78256a5740e9f5d0645b615ab265af137e5dee"): true, + common.HexToHash("0x92663b79b6e533d755ea0d80c0c25e8c1af44be79f0e6ea3dd71ab6fa1c0cc15"): true, + common.HexToHash("0x30419c470f07cea782ef2a94c14e8dcf220d799c23d17c84bd001ad1c7bc36f7"): true, + common.HexToHash("0xdb41b50dc770097f3e7fd14a627477a4ecd31ea27298f2cd6a15ea5ce7299fa2"): true, + common.HexToHash("0x4fcf896baa2dd9f4ecf62e66e6552342cac354d6000581301b96e9d65986f90e"): true, + common.HexToHash("0xbe4695308b8859b14a55ec534f3e9f57cf998b37df8b66a5baebba4c396379a7"): true, + common.HexToHash("0x91c554b5460faddb1da01340142dea1ea777e180340d87c528a685a447ad2377"): true, + common.HexToHash("0xe133808315686de252cf3cbf1581a8f879d5061a4b6442d9162b3131f662f0e7"): true, + common.HexToHash("0x4c343fe1cf3f17d73bf80c52a20f71039dd9182a80c5acb148863a9d12965eff"): true, + common.HexToHash("0x79491621f33374e656220dda9fd18f02a5de1d160f65918e973e7f5cf9c09458"): true, + common.HexToHash("0xafa8a1401a7d49202101e51cafd0373b07522ca4f3ec4f4b56ced1f395bf7beb"): true, + common.HexToHash("0x27c764a0c8acf69c9ea8432821963f73a4c693fc4fcfb93b9699a5b227cc33dd"): true, + common.HexToHash("0xbbf59d28731f20e87b61608ad3b7198bc38fdfea2624afd411db1946aec5d4a6"): true, + common.HexToHash("0x608d2061e0938b06b57c1ff98dea0f00a581efded407aa715792795a49a438e5"): true, + common.HexToHash("0x60d8f3b8215c8948d84d3d38027aca506fa93ededa61b8683253b3bb8735e6e7"): true, + common.HexToHash("0x4696ce1663a72c75fd1bb7dfc4b0becd5fd847914d743e3669c4ab0b51835ff1"): true, + common.HexToHash("0x892e740076824515c87255319806f80887d0220109f52ae4741862dabe6cd0d8"): true, + common.HexToHash("0x136b9a5be2bcc12ddc0c8c8ddb7cec9374149d09b8a0d90078f572f8089bcddf"): true, + common.HexToHash("0xd7445b982559e92f9aef8b685d1c72eb1dd2a0cc292d68910a4807f9d518ff4e"): true, + common.HexToHash("0x7c8f0e685040671678018b5071b266852a320f2e6cab82cf7757cb1e1ec387ac"): true, + common.HexToHash("0x7f7a798a922dc9d066ac7082cb7d315aa9bda8b908684a1a0387c2368e7703d7"): true, + common.HexToHash("0x28be9908cc38e201b0006b69d0fc41bd0fdac3d7d0af943629bdbcb5e75d1a7d"): true, + common.HexToHash("0x9901697e7fdd24129a512d68bc5dd02e4e1dfe7607626ee2c3599bc89e3fdb85"): true, + common.HexToHash("0xc38327a68d06c66af2a67b45c73e410fc13c681fbdd3534f192c70c6560c6595"): true, + common.HexToHash("0xb2c3c05f96a03d29902da201c1f074184d1ae31b51963c4e38850a5ad9119f4b"): true, + common.HexToHash("0x597a2c19cff082aaa79f3e199afdcb25a0a879a86d43189f05f42fb1cd999992"): true, + common.HexToHash("0x0ffe5bcdd20730b448a546020870529b309cdda7cf7632fb421c9f21384ca471"): true, + common.HexToHash("0x290d8d9784f9c93200d72279e24b48eb6095167d25ce231bf7f457e21cd02724"): true, + common.HexToHash("0x6fce4223af87998a9144c3f7786c6b9172848af4295e81845676cb7f20446ee7"): true, + common.HexToHash("0xb334ad3c659cdd18d3bcf4cd9f800645b05e574f7bd3dea9efb18ed5526e8141"): true, + common.HexToHash("0x5bc33256358a447daa226c032077aa0b4c691f4a3c1b66cc0d5900406e79ad2e"): true, + common.HexToHash("0xe6256b9f6e06fd89057850a95804fafc407f8607d67f25be7062a3009091a335"): true, + common.HexToHash("0xf92950e5b00d6a9c9d73d6a86d62612a62a5a1c3575785eec960e3ad1f2db968"): true, + common.HexToHash("0x3bb168efcd48038f527009c027e6cdd451290c0a7fa3a6a3b1a8ebd4d3b97c4b"): true, + common.HexToHash("0xa57aa63522a26978552e654b2b75aad510d729ddf51145fd48d4556db3b7faf8"): true, + common.HexToHash("0xede38e42dd0305f0df1abede704d3c6b3c46de2924f94fd0f4b5da5b85331105"): true, + common.HexToHash("0x97fc883fd0bc519f11911e861c7789c30923cc703bb6f4e0d4faec71d58d3b65"): true, + common.HexToHash("0x93a45c51f19f3cebac8f2ed892602ffa80956ab932ca422d09a76f6f9f9e178e"): true, + common.HexToHash("0xda7f4fd106a848593f60c1fe4e149dee59c9f972071cead3773cfc338ae8155c"): true, + common.HexToHash("0x4d5d119aeef305221e2cfc5f8c27c787fcea4c9b4c17987cf258aabd03356adc"): true, + common.HexToHash("0x1e41bd12c4cf5b91fcb3ebbe9ab374c985ea9e7e8b022bcdf12614e7a0d619bd"): true, + common.HexToHash("0xaa5920dcc4ddce4fc4c2284d70352a42e707eda624cd83c61f2896e8c6ee73b1"): true, + common.HexToHash("0xf7b6386f31169fe846808732217f66077d8c497d333791bbb3a80c2a6ee0fcb5"): true, + common.HexToHash("0x02ca198de2843119a1832a7befd2109e94ff794bef94c5c2ec1841426e02e89f"): true, + common.HexToHash("0xa9d0ed56b49da83dbd3734f9fbd55666c46e2d1ab7478b4fa7fdc87370b3825d"): true, + common.HexToHash("0x768d69667fd4c683ff25b805aa6da22f9f1d3cbf52df15655d44eaa0ce04b7f8"): true, + common.HexToHash("0xcc7a6fe20739950f1efbd77295d08e0d009dc08503f498e44729c556d009ca66"): true, + common.HexToHash("0x06aef0a77ed72ec956546ae67741c21bed08fc78295bca1388a5b6f9eb6ec209"): true, + common.HexToHash("0x0526b56a9fd566a6a38aea4df8ab247e537e88675237ea5859c3f42d4f991122"): true, + common.HexToHash("0xfa316ca1cdcc82088f6d7d5a2532b8c12336a8d89373d34f95bacec4acf28597"): true, + common.HexToHash("0x6de109e61eeab09153a2c4792f4148790d18da0c74446f56d4719b224620b90b"): true, + common.HexToHash("0x71076413384858e4c25e8eaf79e68d5b9e4ed1ce8e3ff5f90e69ddb9425613ed"): true, + common.HexToHash("0x3762545899c470ada2668c9b159ee92a544955b0532f6c8f8e0b82844735e191"): true, + common.HexToHash("0x93f3dfdb12733bbb11ea5264aeeb2d4c8339a0d777eca217c260c97c8c601ce8"): true, + common.HexToHash("0x2a2f1766c0dcf976a1ba5c6d0f8b5bc2e56b1f65e4e9da621b3cc1d3adb12b3d"): true, + common.HexToHash("0x85fd5fcdcdcfd51f2801cf782809942d90a344bc801e378b3b37dd601f097c7b"): true, + common.HexToHash("0x23d0c4b3d9e581507c1cd5d34c7e51ab05b458f0a9fffffa31d57da0a3d305db"): true, + common.HexToHash("0xd5741ce19a99675d156d60ae914f64789fbe4694b39b67a3ffeadb3d34435a70"): true, + common.HexToHash("0x39e9096c984eaa91a2f592c238c9072f5d1907d970689b5ec3e2559b4f44728a"): true, + common.HexToHash("0x42fe934bed9217b21b99e9e251437fd5dcb7d6f76fa070edd6bd47f1d324d842"): true, + common.HexToHash("0xc8e05bc0553ebe45346ab8f3619284dc80cdc4814b655638ba53b6051f237439"): true, + common.HexToHash("0x8417e5aa5ff12f366e9397dadeb029c5df2da33eeb8e925143127396ca41cf6b"): true, + common.HexToHash("0xe3570cf54410e4a0f10efb07cbdc170c1ad3f72e861bdafae5041d9b06661df0"): true, + common.HexToHash("0xf6e3edd89abbce995fccdce4d985817bd4c11f3a1c3a978604339cde5219d29c"): true, + common.HexToHash("0x6ab664ed3be6ac229ddd5dd59ca9ffb530a6bc49e8f43d49bc1ad0521f6495e8"): true, + common.HexToHash("0x1ecf718533328db45123719dd29acfbcd38d91746f7fae2e5a50f5d073482653"): true, + common.HexToHash("0xe40cf2eaa819d618629e51e77c794e932e4f65403711ff65a00029f3801b5eb7"): true, + common.HexToHash("0x35e25cb589caeb18cb7f0bb706145d273672b8b2cb6776e265292ba1974310f9"): true, + common.HexToHash("0xeabd282284dba45c4765a6d80e5dcb81d05a8221b819f4561b6e86cd6d08a624"): true, + common.HexToHash("0xfb28619b924789550afac132c872934c47fbb5a65a038aaadc0e16fb9df9b94e"): true, + common.HexToHash("0xb682055f4040534137729631de137634fa33dafef8aed7fd3872f89ca9aa815c"): true, + common.HexToHash("0xaa7d944e9e4144cfe0cc9a8ecd25f12a38544ca80074e6bbacacb52a16440ae1"): true, + common.HexToHash("0x7495476f8e83ab3759ce2e644dfe87769de3ac147e340338053a10480c691131"): true, + common.HexToHash("0xa3bb4a3e08bd56030d3faf5aaf91fbcb0a01ad6ed8e22fb08ce901da444f1b1a"): true, + common.HexToHash("0xb11397b2983bbefb1aec59b21bf31d312d774c0739b727d45d72eff5789b8818"): true, + common.HexToHash("0x3147779a3a7af04f666281630f63506bf5120ca91bcdfae5dc1ff4eb43653ab7"): true, + common.HexToHash("0x2aeb3c39013b2e81a07414d06b7a99bf1d7430a5865f09ac7b7ee3a6692685f2"): true, + common.HexToHash("0x8e96fbfb8984f4e8099c88b1be9635625eb87f54d2bbea2649cd3f566988cbc3"): true, + common.HexToHash("0xc336634f8a7ce9049c27b2f96cc064202413dcb06d4602b444ea5ce41042b40d"): true, + common.HexToHash("0xdd2e54e00d1c1acb9e80040a050bb98e41a264343a8220565af80c273f038257"): true, + common.HexToHash("0xa30554611c9a285072f5dc83bcee47afd303538e26940d719cfcbad7962ec939"): true, + common.HexToHash("0x4c98464b498fa91b69e86d03a6f787d62e21e77a54be8a0ba06d1b30e92edaf0"): true, + common.HexToHash("0xf698e7de5c705aa9081259c0a46d269675344bd29385539bb77e7822207c184d"): true, + common.HexToHash("0x95e3c7d5b84b757cd6e591a0f2026a8d0365dcc3f9bbd0d0ba38c8f1bac833b4"): true, + common.HexToHash("0x9ea4f7590afa6c3fb239ff0346451a674c43428cf72826ec2b94c3e3419915c5"): true, + common.HexToHash("0xa71c6c5daf24bbfad5f772f39b601cca23ca8ae909df311457a1231256817193"): true, + common.HexToHash("0xbf5d8d5d09115b63760db24a7e201e93b94981a4ab9deba1018f27ca87819d4e"): true, + common.HexToHash("0x785be52c79100a918f881298adb335a02a2f494ad9e2dd0c28da2701a22bc058"): true, + common.HexToHash("0xaf8d5e5b8b16d790c79d1b1bc3e1b1934c3c38439f20a516846ad75946df6b20"): true, + common.HexToHash("0xccd2e83fdabba5f4812c68516ea1c767635d604102fe978b31241fd2f6123df8"): true, + common.HexToHash("0x61f7652b169402c8399b6ec62e54caef2dafe88427325d4d2f4a8bc1d4be50f6"): true, + common.HexToHash("0xba62d4ee4fd5e1ed0c630040db8f1a4979e98de156dbff49a1d9e9a285f37422"): true, + common.HexToHash("0xf9c36174b33856b1da2a50a43a2624c55672c999d78e8a00268bdcd34eacb9a7"): true, + common.HexToHash("0xd307cddafbbcfd8d140b95e1cdef0d4735609e723d1b8aa7cc792dfd77b01f55"): true, + common.HexToHash("0xa9238d1d12a0eb059445ecefe73d33b32b1b6749664c5bd748ac08fafbc3695f"): true, + common.HexToHash("0x850204c9336707fb6e21f7bbcdf1c76fdb8d88ca0a90243650707c81659dd889"): true, + common.HexToHash("0xbf6e2361afade5790528f74a22b2a61238b8b4efe44593877e785423d161be09"): true, + common.HexToHash("0x72f96c828db323e88651ff3d48ec30d3f88c0721555cf9c92a9ce0da364e2b31"): true, + common.HexToHash("0x39877e371be1adef25acebfc2155af9a8f41fa50bf0e468bb98068d7cc22d622"): true, + common.HexToHash("0x852dc0f5380f9b5ac012336a309ca8aedbd443f72e5716bfb75cf002dbd64b80"): true, + common.HexToHash("0xdd4bf50083d311bab8cd37aa1993fe546f2a5077349d3157b4f2e401bf55aec9"): true, + common.HexToHash("0x21b4edcb4ce3c144de5497c6325f72b5b3efc71ed131ed477d40f6ae7c91aa1e"): true, + common.HexToHash("0x412fc86f4d67567788c7fdc8a84f31f07854566a39e9df66a24d04047ccb08a3"): true, + common.HexToHash("0xcd37f3c1518caa7f23abd4a1ea2a2e9988471dc4183a62535c2596af7a5f562e"): true, + common.HexToHash("0x24ceea4254063c40281c876367e3d34233428b30a2414c39e89d018441b7e617"): true, + common.HexToHash("0x0a062af44e845d230def9c9ae8b3ca9568e99a34f52440b1a3433c92a1ba1ed6"): true, + common.HexToHash("0x4a5e9819bfa910e6ac79a76392f75fc49dd72f362c616a4fa430c78ad7dd2210"): true, + common.HexToHash("0x21159527533e7c9c530d529ba12b14ca685f8a91bdbff3ee24bb61adde0c7c9a"): true, + common.HexToHash("0x799b9f0dbf0d9aaa7b8a0f93ce3b4ff756fd4bd934171397685d0e8b16a5f1d5"): true, + common.HexToHash("0xdfdccb2c56cea754cd893388909258c517483480b71c23aaad3537f4664973eb"): true, + common.HexToHash("0x53e5f6dc2e5fd5a2b66d19a7f883ef2cea90c731a13ccafc10960dd7ff2e02ec"): true, + common.HexToHash("0x4ea607fbeaeb35a6a606b5b5ec55e84c7d1e7c43d7837e149596a9644db45f4d"): true, + common.HexToHash("0x0de4196aaad81aae400fbdf1005fc3173a65904890f9e31659e51b896f9c8581"): true, + common.HexToHash("0xe826ce0e37fb4aaa72adb54782cc22fde9af5ab757d5a5d6a73f6e40a3a3c8df"): true, + common.HexToHash("0x768d69b49110cd14c06912c2d4d2101d4278b3c901978631519f704810be40cd"): true, + common.HexToHash("0xb4f3613ce792473fab44ad51b6ce9768e6ec6f5ab6970d3a0695f8130a11b5f1"): true, + common.HexToHash("0xa9407aa0059957f0e6f4368c83bdb59522abfb3d54a8554b6d3266c728ccb8e7"): true, + common.HexToHash("0x7253c380282a01a3dbcd96076b82bd7a7716c7b62f1ed04caca2da316cf407b3"): true, + common.HexToHash("0x1c8fe520359f185ec3c96a533d8319abd1f17ea495725da87b27aa612a6c0d78"): true, + common.HexToHash("0x75de2f8ee3f79da53f3f548033f2110870ba543922997d3059b5a313a20b1a8c"): true, + common.HexToHash("0x5c0779ecd7b4eba7a4eb7778d7baea47348e691dec8ef812abc53585677fac64"): true, + common.HexToHash("0x33d1aca9fa9920d18bdbf4dcd46d87754828760ce02c2e551aa474ac6de8683d"): true, + common.HexToHash("0xe2d4c92dbe7399fddd9a38b040c72f654a3111757fb19a7e17c4e45678bd25fb"): true, + common.HexToHash("0xdcda175d430f409ed7a36afe36a301ce1c1dda92e90f17e012cda47741abb755"): true, + common.HexToHash("0xdddbfe4fcb9deb48cc6f6b3f708e09b5baf871427754b57894cdd3301ea3a526"): true, + common.HexToHash("0x142ab313f6769eacce2d8ab7818f7e7e515316dd9321da506377ba41d38687a8"): true, + common.HexToHash("0xd20d4d5def362883e8da90769ebed8c827d75e637e937f75eff3deb42fa31827"): true, + common.HexToHash("0x1db084c93818b3c3fa550ae35f7f3615a52a04cea1a0c5825150b889f3a65d59"): true, + common.HexToHash("0xef5022d37b3452b8dce1e3e47abd9917eb422d3fad9b86270bb9477460b88ff1"): true, + common.HexToHash("0xd65afdc0ef590a94d1484ac0526b2a9406bfa72a7a4b25207fd09efbbc072249"): true, + common.HexToHash("0x5b7950f5138dc09e4e684035ac61716d67475b9d0fbfe3c40e8d14f4675183c3"): true, + common.HexToHash("0xf4175059557e3ee97c9aebcde047b7d36f1cfa7629fc59694db54b98d76c635d"): true, + common.HexToHash("0x882711d3430b11dfeb4d3452d6c4298ac7a93105737ae16953714df3d2e76cf5"): true, + common.HexToHash("0x7767045c16eb4a8995ec494a7a2928133c73ef329dbcdda45fa4c6c639c03885"): true, + common.HexToHash("0x08d775f66d12345f90ea0a6f7747799c9beb3faf9ee376ccf59e6ebfc6dec7cf"): true, + common.HexToHash("0x52e2378cd772346b5b6c1a31ebaac17ebe36a4023ab31fb8f31b83a275f5460b"): true, + common.HexToHash("0xbbc4aa56f6838b865ffd813f450adfcc15626dfe4b7317be1b984db77ef9d806"): true, + common.HexToHash("0xb2f19755de4d2ba1d420d30475d683311a42ab0dcde94f111f33f3360075d13b"): true, + common.HexToHash("0x49a23477b597f6986934b1a08fc00e3702893220a2f6f4de136804f71f26356a"): true, + common.HexToHash("0xc7cdd6b59cde8472351ddb218688d2e49010e0a92a58943ff4eb5a976e159287"): true, + common.HexToHash("0x0088848af3c3d2ef987ac1c2bbea51479637290b592e48bc7b2957834f4b2f40"): true, + common.HexToHash("0xf0e5deb476b9ec5b7c5237fda7719fabf905716f85ddb2fdaf91ad2ded020b41"): true, + common.HexToHash("0xc1b0882ef612834fb240c9183bb6ec706fc12388126c50f73765501c7f223076"): true, + common.HexToHash("0x688d3073fe62fba51dae7706c9d100d2968f05a4f503f643f0b833905e683364"): true, + common.HexToHash("0x08345d0c4fae7b3f15509cf21bf30d8ab76051b4c843f5d7007b211929677aa1"): true, + common.HexToHash("0x0aac3e0e4261e3afa9b215337ba47e65f2f801a824027fbac0f5299ac4a21a1a"): true, + common.HexToHash("0xcf1ff92bace91a6171432263b432e2b69af9bea4fb8355c9612d52311cd3b86b"): true, + common.HexToHash("0xea9ec03b2f11ecef251c6ce5a6bb4e534cff436f466e0f29ea9cb410285b845b"): true, + common.HexToHash("0xad3290cf1485e511c7c6e39d9bdc5f52a6de01d3a5ebac3e159ab973778892c2"): true, + common.HexToHash("0x6aec64fd7bba4f4693ef572d960edce0adef0fb82b5949fdbb2ca5f9ffd372cd"): true, + common.HexToHash("0x1cd8fb4c0cf2fdf17efbdc515c3c3c138032908566eb892c8404a4a8f18b56c3"): true, + common.HexToHash("0x55bbf2c507f45883869c44591d1bff8053711d604700e7621d4c18989fd11a4e"): true, + common.HexToHash("0x4eba59d7079fa117e0ea9a9af5533680f05b0c90257a6c98ef83e18b730d49dd"): true, + common.HexToHash("0x5efbd5f39a26e7c8b6f3965b1865c72ec5fda918f9e2b8c2bf760d3dd3dd023d"): true, + common.HexToHash("0xff9e339aef06dde546aeb49f5adc335b677a6c860ebb492df853aa95aefcf70d"): true, + common.HexToHash("0xa33691dabcffc719794581aacb7897e3f5a4b034c60ac1a67870f5e144a1b482"): true, + common.HexToHash("0xa15f00d968ebf5aff6f054b55dcbe43f671002abef7734a7d57a1bb3ddae8ba8"): true, + common.HexToHash("0x8c2422c44a65e95196a0d28a2b4e057a53fc36d5ede9e1947821b4a92fa4a1e5"): true, + common.HexToHash("0x8c52a15bce2da506727267b759f5f8d6a3323ccbc7dfd37f05ed774595c84c9d"): true, + common.HexToHash("0xc5739c8943bba977e21fdbbfdee1012c682839d9fc05812916d4be9f098a0df8"): true, + common.HexToHash("0xf92531220c23ffaf1669bfcba6ff2899f928d9e2697c175b45b578dd91425da8"): true, + common.HexToHash("0xab8b0f44644ec1e2ffeb31c2cfd640db752fb5b6efe1c281e4a46458ecafc3c6"): true, + common.HexToHash("0xce69efd2a1db8295d387ea45979411ca2da3e4822c1df558e1d9410c045f884f"): true, + common.HexToHash("0x3d5f0a8e897e28e879056cc684935cb1dbb773460ddfe547b921d56fc7e503b8"): true, + common.HexToHash("0x95a21cee98240ac5139866a0a4e481069fc6555d914a4ca9d9eca7b43e5d81d1"): true, + common.HexToHash("0x6a25619a8b11b13367864ee0545f1d42439e4abbc80baa8dfe81276ca78490ab"): true, + common.HexToHash("0xedd42414d5da5ec4b2b40ba5b3d3b44af79de6414d2c64deb0d26d9f2b021d6e"): true, + common.HexToHash("0xff8733984166c70c8e6bc78b3e3eb52e6f484b359fd1dc884a80093ef900a59f"): true, + common.HexToHash("0xf3bd2b83a75319f74f25ddb111854877eec606199081ec17a28db541775353c8"): true, + common.HexToHash("0x81a17623f9b2ef39d1d8ed036d8ea65d71470870fc18d58500c8d627074af704"): true, + common.HexToHash("0x85f315254bdf973cbf827776549e6aef5e6a87dc1a911892a9ecb7c070ee40aa"): true, + common.HexToHash("0x4f8d1eb2dbf277f1a8c9b1fc780ab5d98e88b2b1b5ee3b5f68fdf25a2d3a8190"): true, + common.HexToHash("0x022dd0a37c497404f001011c7d734df189b3b684bbae3b902f168d9fd7915765"): true, + common.HexToHash("0x167494f9b5b44a0c48f47e75bdfec22f9e2fa20d9e3933bce994bdfa5f191275"): true, + common.HexToHash("0xdadda15192c3b63eacd5015349f18fdc003f3e9b5b6f51d721207f8c33806c10"): true, + common.HexToHash("0x36beeb5f737d60ea8b871e707294eabe263a40b56ff0cc657456e1e38784b438"): true, + common.HexToHash("0x1c72acc53d966826e174e653b604d5241d8f9cba525db3c3b5669e3cbb7310d9"): true, + common.HexToHash("0x5a57b4b51130cf28100643761a0227b9ea63272739d8994dcaf4c78ba35b0ac2"): true, + common.HexToHash("0xc7fce87242e5e0cfb305be8de1bc3a68d1c33ee677027c1c8189d0cebbc8e97d"): true, + common.HexToHash("0x4febea90cc856b391e7b4e98d5e9782ea8f016c4f5e539e70d0a0ecd4cb266a2"): true, + common.HexToHash("0xfd2ef33cf79070aec97e3fbfbca96fce5e3b1ad3f1d4fae9e01e80cbfeace01a"): true, + common.HexToHash("0x406a59f724b1a4a41a234b4ae142d21c574b9050f2818e23f0a0e215ad4d8925"): true, + common.HexToHash("0xe996cf028797c384a9aca6feda292e997e5bee4f6013a724e39fd11810ce36b2"): true, + common.HexToHash("0xa781b49d25066beb0bc308dba18237598db084ed4762cc0097c3c2d64e5e8bf6"): true, + common.HexToHash("0xf94580b105837393d4912c202eaf8caa9e9f7279251622ee594717c21c9671c6"): true, + common.HexToHash("0x701ce0bc44587307776434742601ffb395c5484c7725e443e0df02665b8da35c"): true, + common.HexToHash("0x55c6e2e7971d0ad9d5f37a644b182d0b624731f0ffde352201b523810b0afcc0"): true, + common.HexToHash("0xa1547b2dbcb81bec01677d7fa1ff23fb66b8d5c761eca58f0747b95960e18f55"): true, + common.HexToHash("0x80cb7a4f743ad9d79230fa324e771ff29a9a2b1b9eca1c93e1036e057350a1ce"): true, + common.HexToHash("0x9a3fad8920283d41fe52e640be1a844d0e2d2493a276a1bb5fb84f5f33c613a6"): true, + common.HexToHash("0x5578c3d64c1769e6593ee9d76a3564e6733be978489181d520ed99fc67ef3cdc"): true, + common.HexToHash("0xd37d88c9e60cac21ad66c31080b483d647bf0fb263dabff7854b04eec95f54a0"): true, + common.HexToHash("0x625bf2c4aa23c207024c9a2f8281067efbebe2c624925427760894ca9581b7b5"): true, + common.HexToHash("0xbc7f1bf592ebe13efc2f593fe7ac8eb35bc98478fede5e536bcb946411ac0d63"): true, + common.HexToHash("0xd8c48533574cd3e79bcc0995c553692e2451c8a218f60739cdce3f8304683a4c"): true, + common.HexToHash("0x9b8fb47bb991a55e703ec67235d01ceab86b66f0d83e4a7626d0c1c4712bb9cd"): true, + common.HexToHash("0x21efd596c7435b02fead509e79685fc1dfc71a60f2109d2ade694739061fe738"): true, + common.HexToHash("0x5486e39fb8499289bf5526f1a318adda7a845e51415c641c0edfef54d8b55639"): true, + common.HexToHash("0x15bbef131cfd4299d6e77d3cd4cbc180319ffed6b322166239c6285e742f681c"): true, + common.HexToHash("0x5d3c4c085dcde3e115ffb8118e13d4b3a9f88f1de57d210c390a2abef5a45f29"): true, + common.HexToHash("0x40480369ac928f5a8c3e7a95adcbd57e84c6d45fca865fa920ded463e41c6212"): true, + common.HexToHash("0x69593ce164b98c51c21ea2a22d9787be5596b6267c5dff31275ea246cfa0c17a"): true, + common.HexToHash("0x5beaa0f589cc4ef909cbbcbd657ff92ec30fa8f7693196850f9866fe55076c9a"): true, + common.HexToHash("0xc0596761765657f806def9fbea2533dbca9c75cdb0e7ae7cbf62ad232413fc8e"): true, + common.HexToHash("0x546b16609fdc70ac3948f8c40bc572026c1071a86549f54104436267cafa6c83"): true, + common.HexToHash("0xeb6acba573bb5199e60b79a313c7c54d6592da45e8414815da2483919d9841d0"): true, + common.HexToHash("0xde5ae06b60da5800a349f47e17a40ed73a662e6dc0375b0590a9b4f7d606c29e"): true, + common.HexToHash("0x56ce8f4a88cb455adb5ed661208b29a85e7284119046bed251de2f210531c104"): true, + common.HexToHash("0xc4b2dcd4f7b3fefe2573f337e3077590a1fa9b6de57c9df24cf25d2415e34d98"): true, + common.HexToHash("0x4e34495d7cbbcd166a4bda79f65a964ec5c1a6647af97f35df4265b13e43ef92"): true, + common.HexToHash("0x50430441db328e1c425c47c917249ca30cbe8de9ed0a4af3d4fd47165fed25c0"): true, + common.HexToHash("0x72271caa00440def6b84a76d006d663e299b98f763d7e04e6b59615a73c82a35"): true, + common.HexToHash("0x0eeb4e16a4893cf51786fbe8fe8075208ca0c2a91d42606241a5d5f1e2645fe3"): true, + common.HexToHash("0xacc25d09422c3d6d5659a756f1b9ae5a1897b5d928c5da53ec5575e67be813c1"): true, + common.HexToHash("0x0217175c27491589e19382723f7b0bfa4db5b662a673611b550ee071c0c3725c"): true, + common.HexToHash("0xf37209b4065e67651cc48f6d085999657b2264d001764c37b3650e4a6665c4b8"): true, + common.HexToHash("0x5fab478fe20f2cd28f958e6335c70d905d22dea462a04eeddb2eb28647f70e48"): true, + common.HexToHash("0xafb1a68843c5fd858967a3e7169a1472ebca9e8fd51d251b6ecb456203e1c0a6"): true, + common.HexToHash("0x9f46880a689de83d93b41dfb53ce235737124c17ba74beb6b6aeb5c4c8f45d56"): true, + common.HexToHash("0x19f1981c0b3ebd02f5c57b084846aa379c7965cc9e17726943d036c6c06d83f9"): true, + common.HexToHash("0xf178d6530e9a15083fc2c0fae62c483be6658b130f3928c6d35218389557b68e"): true, + common.HexToHash("0x55f9480083de41b31f48ff1ffc5f055b2eda214b509793eb0688f2491883517a"): true, + common.HexToHash("0x62830b4ef2f92d0ef14c464965e10dafd8999419ed1c3cf1bfa8f75bc08922a1"): true, + common.HexToHash("0x385a2f80940e68e0208a5deabce3152211e7bfbed3a6acbd3c5b037fca1b04bd"): true, + common.HexToHash("0xdb6d48f21d77e1a1c122b5dc45c1aaaa60020f4e8c0dfd90d69f126f85f4bec3"): true, + common.HexToHash("0x1c9c8d6b48cc7e10be82547101586625ba888f5e20c540ba67f59685c433a9ed"): true, + common.HexToHash("0x7c22e267267f70cb951a2b23b136a2dde0e3372e7f606dc363263734238a75d3"): true, + common.HexToHash("0x924753de21ef1f47e36fe85ac2aacdcf669b3381759d1579bd85ba71ced0f6a8"): true, + common.HexToHash("0x0fc8c9aeea8f05e5c5967903a0b045025838bea10aa2a69825af76ecda43568e"): true, + common.HexToHash("0x45e44ad69e067adcef6100ca8f4b2fc9bd65197360eb74dd4c276dd4036878f7"): true, + common.HexToHash("0x2f83a0a4d970bc4748669d3891f9913ba4b70c53466672cb4093a8013e40f998"): true, + common.HexToHash("0x613447bcf7f04cbad5596b48621dfd6d5d41f5c5b859b3e82403dce45b714368"): true, + common.HexToHash("0xf11d05b06b19faeec115b5fad430479dedd90eb4e43ebce7a5191aba4239973d"): true, + common.HexToHash("0x03776c305d01457a60ad30f967d20db247559f53b3ea84d2cd4228c66af413fc"): true, + common.HexToHash("0xbc7fc72eb894e7720d0ca4c1367f6fee9a581649960f8d0c5199928b5da4d48c"): true, + common.HexToHash("0xf289968de7cd33cccf5b3f8c9d0373ce5bebfa2c4766530b6d6bf9c0ef8ba73e"): true, + common.HexToHash("0x0c376c0b5d98bed7863f2e49a7919704a608d59d0d9afb9f8a67e8c79378d517"): true, + common.HexToHash("0xd2b332c38e52ab07f3444f55a265a6f13ed33fa5427446bf4ba93ceea26e5035"): true, + common.HexToHash("0x63329e2c5aa965a972001a0ace18f8ec10918690ef278adb36cbeb4675e2ebf0"): true, + common.HexToHash("0xa5e404035c508eb6f5439294f202ae17dc9023a52e7cc878b135ad8a4cf4b8b3"): true, + common.HexToHash("0x68f74003fafefdd07dcaf338d282ab4604b9be6a61cee548df575d14c3b43e2f"): true, + common.HexToHash("0x9e340e44c2980140d726da53f376a606ed8076cc77111e376587f802d3c7d644"): true, + common.HexToHash("0x07bc9e463bb5bf4943e5f53d0875a7c25308c89beb8faa35deb7b9cd04d7a964"): true, + common.HexToHash("0x8281e106f38d6835c12c6fb8ef472b2e54f2dcc3acb56cbabffd62b2ebf3c9b8"): true, + common.HexToHash("0x3dcbb836909f38fe0a1f4d7a3c9a3180fd40bce87629353c82ec1a96c2fc1544"): true, + common.HexToHash("0x6d34b078b645b61b527ce39d5cbd82912563788d7be108b3072b0f8f060fecaf"): true, + common.HexToHash("0x952074a4328948a18e8e3e33881d95d06f14fa77578ec853255cf8506ed8a709"): true, + common.HexToHash("0xa1d658a2b9f39c259a6dadf19c4d8f5c2510c6e2e8507b62a223c6e3af510348"): true, + common.HexToHash("0xf2fec98f1bf19fe654ffa8946d66eec381c819f270c98e77357dfa3b01a541d0"): true, + common.HexToHash("0x0dff56ac9d0ad17dbeb7a5c14de9cfceb246d1b7d050d33c4164d672fb67597d"): true, + common.HexToHash("0x11020773b77a1beb5cee39fa63df88ae6c30dcafb00a378d3b903876b9d53fd3"): true, + common.HexToHash("0xba02f2706c4f17b73b190c808aab857c8afad23d58f104cae9d6ab4777cd85d1"): true, + common.HexToHash("0xfc1f7c0d7771dbb944d676f8b36ffbe03448a83850a290c7483e1beeae4411c0"): true, + common.HexToHash("0x3944f6ee9291775b37c0b07be5b77a428c89f59db23d9d38b25cad63136f7874"): true, + common.HexToHash("0x2530c8d881b249fb051f6623d750524979d7a59f057a071fcad6a529f7cb0d47"): true, + common.HexToHash("0x2b57d98a8368ef6e154a219eb51deda37a9fced34859d9f81f2ce7fbc4d9fedd"): true, + common.HexToHash("0x039eab63557d7cc49e9e415eb4efc45a905243cf69e9782d5913c81ef48e2a28"): true, + common.HexToHash("0xef152ee6f987e36ab9578eb5e6fa6f79c7c6098d5ddf76e36af826aeff50edd6"): true, + common.HexToHash("0xcf1d5c68999350567c9f1f742c7f6b04776a414ccea14d70cfb8b09fa68e4e6c"): true, + common.HexToHash("0x1f21123fc4aef2a2cc7b1a7606d721076e065b9d4ebb13b92cfbdefa123b2414"): true, + common.HexToHash("0x3bb803fbee4763d3aa618b49e087dde49ab44e52aa0e6369a7feb9e730d5cfd6"): true, + common.HexToHash("0xea38440405f98b17d68d5ad00b2095df2733303dab24ee799c6997cc5ffc918e"): true, + common.HexToHash("0x27a75cabf6430ef067afb5124354b4913496d4335244608a9f63b4f52c2c95f5"): true, + common.HexToHash("0xd85355bbfe4ee36133f5c8d5f59c75f8b9a425f21b3d21dc7db3bfb3c4b5a38e"): true, + common.HexToHash("0x2c793a0e8c6fa00ff6bccb377d3434c483e0b86981615afde671b3d54433edbf"): true, + common.HexToHash("0x6fa70b26bc112610f431f02d9a445c37f6b80451a786ced31c4e2ba399fa2dd8"): true, + common.HexToHash("0x98354fd84d1b457c6190250c5d6d26d046185da9bf7f7664255ad56d97a19016"): true, + common.HexToHash("0xe1c037ab5c920bc226f86cefb44a4ebcbc222849bade966f291b0309e8faba0a"): true, + common.HexToHash("0xaeb710c6b5c1a5ab882f96def3aad42646bc96e0d07379ee1d2bea6ee06a7094"): true, + common.HexToHash("0x2fa40c933575f880ce854a5e04c8223717f52de9bc22e15ee4e0ff52b3cc28cd"): true, + common.HexToHash("0x63759037a9d70fc601548269d0cff4531024e8a95dbebb91f5aa002e2dd197f0"): true, + common.HexToHash("0xb1fc8a25e61b8cd1af09418d2285e50228993210a0a8610c04bf0d89cb018f33"): true, + common.HexToHash("0xce1c3ce658024a9b47e00a52c4293e2a838c3b685c5726daa567466a5165923a"): true, + common.HexToHash("0xfaf38081f10b896713c0ed2809f1a8f967431eb2744df2c743cf09f667a623b9"): true, + common.HexToHash("0xc49cc352d3720b9748a4d817b60f29b41de14ff5abbeb7f349474a81d0f6ad71"): true, + common.HexToHash("0x76edd86b9ec78c9f31b588def6a8709d76f99bf9ae45eebe4f3d7d39c73a58f1"): true, + common.HexToHash("0x56c7765498cfac12060665a348075c2d4e0577934be57ce60c4a74592378a710"): true, + common.HexToHash("0x044b78376809ece878b277e3a5405cc82f37e0e4e9ce773af3d48e2f61fd1256"): true, + common.HexToHash("0x9ff35921de87ea3fd25ff3c2bdae0c65b1d747ed71fca7f7f2a64c3eb95d0519"): true, + common.HexToHash("0x4f133c1ec46c34244f3cb6e1c6978a9029c2fe9075f2192fab0acd80132c7ac3"): true, + common.HexToHash("0xa881597bac3e534325ae862fe6d32131498e9abbfd53aa1de11e802ffc350337"): true, + common.HexToHash("0xe8705ab7f8b12350cd53c5587d327ad67b6b8cf3bf37455721278795cac3b7ec"): true, + common.HexToHash("0xa4c7a297a36b834665090c889762ac33b58c2c70667b4f0440d0401116e83f57"): true, + common.HexToHash("0x14f2a466a61aab8ee9c00f3158726a9b6f7676416a2b0bf6ed0eacbe450b566f"): true, + common.HexToHash("0x253ce3fb8c99a3ea770d5bc2d6498a3f90f6d3f78adef1a74d3da1b3f236571a"): true, + common.HexToHash("0xfad74857333b0a4c4e53bc4f3788fbace1b53232753e1b60ab3a2aad90388bb8"): true, + common.HexToHash("0x408da69028c741e695ba0328bc4ac338e531bd2ceab659f6fd39f914f41aed48"): true, + common.HexToHash("0xb8b593d38d2c8cbdc256facbf38ff842e7522c29121fffc9d0f2683e85f271fd"): true, + common.HexToHash("0xe101a8a6427e8930381ae5d5aad5d25c4210987175f49354cd95ff7fbc74c06d"): true, + common.HexToHash("0x4977aa1cdc2b946d3e2c20f33678b949218ec18287cd22ac23606deeec016e86"): true, + common.HexToHash("0x68043095c822560ebaba6b529f45c1614957a70b3eceb705a5f7759cedc8bd33"): true, + common.HexToHash("0xc9fbce31bb1c62f43b8f4210e12d16b351961ccb30c693dd7ef2bfd7eaf817b2"): true, + common.HexToHash("0x08337e8453b28ee696403d3674aa5d6a0e8949fc36a3ae382578e9ac70d21901"): true, + common.HexToHash("0xa399da95cb39c509f535465e863033f860332c77dd6f8c1933e5d4e355147f77"): true, + common.HexToHash("0x8f92758561b1e51ae430e82241cb143cf9c83cbca7d1ffb968dad544d9c51fb8"): true, + common.HexToHash("0x848ddd8df276aaf430b6b0e03f7d1bd0bdadd062d823889adf1c257afcb93eb3"): true, + common.HexToHash("0x709f8de205e120df97e755de68c4ca98fe09ca80c1ef8748f543460ecd4027d1"): true, + common.HexToHash("0x678e031586cb9442eff48a3d1cb53050e2956b7a4887f83f66357b8003bef653"): true, + common.HexToHash("0x6c68b37ab47c7fe2a4083bd08670a0413fafb35805814bb3294324848f4f3f0e"): true, + common.HexToHash("0x1ecc4a5d9f139646b0da7b8a3df477b787c69997442567871e2fdaecd1fb66ee"): true, + common.HexToHash("0x66816ae5fa5554e65e7380411c776011d6189e08f860ba51958ed04fa852f4c5"): true, + common.HexToHash("0x9bc5f215c2dc826c5f858224925ba2a84f224ea0fda249e8cb5bc9750e996e57"): true, + common.HexToHash("0x9b3e742d1aad7860dfce0b5c0cf499520452539e57e2a577f2503ad8f1f26063"): true, + common.HexToHash("0x02d3026bc2c5cd8bf3f30703ccc7bd64e3a43191a418e85e45ab8715bc200dd0"): true, + common.HexToHash("0x9170ee79b2a6f05a80e41f2978a262fe90e6b3b779608b1b8500a7834df940f6"): true, + common.HexToHash("0x883f5ca70537cc211803136f4488e984b8a4f6c1b19240a3d074292b92092733"): true, + common.HexToHash("0x6e94440300207e69ed823dd77cd63c9b076e22fb81ca2b7947f98ad55f2cf372"): true, + common.HexToHash("0xec549888c176234c577b3795d39f4c9c40ad819ba0a774d2a76b851df842fee4"): true, + common.HexToHash("0x1e8d70cb41bb8032e473556abf60bdb5705a10268faa239a01249cb774f304ea"): true, + common.HexToHash("0xb05a5b80b754802e381ee0b0476831b08dd8d0f10ea52045404e64e0d9ba9ab9"): true, + common.HexToHash("0x7875442a10d9e74060f4189d9f581a9157eb1140f061bd2c436f332ea78a501a"): true, + common.HexToHash("0x7b4afb4c1151fe72c15be62496ee4c6ec2ed41eff03796298669dccf534777d7"): true, + common.HexToHash("0xd11d4e55b0f0aa6e4e86f3db9a165e16bf54e552c412355615127434563ecdb6"): true, + common.HexToHash("0xa9519e68034d51346f84cb6e6a48839d864e34b35a31c2d83ae5334d41bc4365"): true, + common.HexToHash("0xd49d42c6872c721d717acfe772080cedf9b2a7bfda2175fdaa7a32dc1ca042e0"): true, + common.HexToHash("0x53bfabb8abbf6a9636b899c91ef5098c46c351651b6a03104d531ec83c291c5d"): true, + common.HexToHash("0x9600c2010d1a6d53d0f9e113d180f648259e2c0a4d843d3721ddc0ddebfbee00"): true, + common.HexToHash("0x9f88ccdb92dc7fd5c83c0cfdf958b36301b4ed824fce4a7d34fd51235d03a44d"): true, + common.HexToHash("0x1795b86d8d3aaf3c021e3aca79fe67a7742e70f8664e8f22a16196039a701180"): true, + common.HexToHash("0x46227ac9591203c2a26e697770c048cdb871d4957fea49e90b554f2263c051b0"): true, + common.HexToHash("0x69566095187998f41232f968acdb71993d2619fe5bfb0e447c79358e55fbb003"): true, + common.HexToHash("0x9e410e65689e88c74dda6a905ff1d80c1de75456e658c437f14c4ac39ddc387a"): true, + common.HexToHash("0xcd5ceda90e1931419f2a93817bba7cab80e610b297cc1f5af16e0ca28316b441"): true, + common.HexToHash("0x721e01afcc7516c729706634a3df34a49ac8e5b20077f9ae7ea229575774a4c5"): true, + common.HexToHash("0xed36f17e95133547d9aa1b4240fc6bf4735e021bebe42ab098894ccf1e20bd4c"): true, + common.HexToHash("0xe4ac212abe20b0325f18f9a5a078fe4a2b65c8ce9d8082ca25493b45b6ef947e"): true, + common.HexToHash("0x844b5241cbb1c569634de871f1af6cb43a56c5cb18f8ea406b931128624da69e"): true, + common.HexToHash("0x4d0682fe173a921968db87ed06a6f55121230672137600dd6b03be5c0b19ccf3"): true, + common.HexToHash("0x08abad329b65844923bf900c4dff7ab5f2325dc9ffe423c0ed136ad71a81c7fb"): true, + common.HexToHash("0x2a02af514097b384b5184160ccc1e602b4e179b5b89fb8daf746546ca8a6594f"): true, + common.HexToHash("0xb55627ccc0d01a21f56addc9ff440eb52d391560f608e19aca6b75e4fc7b2e44"): true, + common.HexToHash("0xe3f8dd14f9f6f5f39711abee4f3f8f70eba2fe28022b823ec1065c7c01cd3679"): true, + common.HexToHash("0xc12f19426a3473551e797e31b155268986c63dc47a66aa49405b7b80136c0a9f"): true, + common.HexToHash("0xb2568d585d26233e17a493e65ef098a6fac95eacb0648dbc2e43fbdde49a7e77"): true, + common.HexToHash("0xe1d1beade130c748750a244c4b227fd97720918afe6c389bfbe8f15767894d7a"): true, + common.HexToHash("0x99a1606232edf2d297dad9fb2e7b670a03ad28a8d3016eb2a8105441941ba575"): true, + common.HexToHash("0x814224bbbe5c701fe7cb0b6073b422fb57d66db0fd3f8908e1c49e4b6e564e89"): true, + common.HexToHash("0x2facbad55b007a216bc3190a627b1c3cf729d22a2f3e836055a59a4704448242"): true, + common.HexToHash("0x88595dfca685a5a328864b4b693d33a0ddd86bb57d8dca843d9748aea787d2da"): true, + common.HexToHash("0xf74c3a97828c381fa3f1cfac98f321476cde42c3f1c63231db7d67c177c466a5"): true, + common.HexToHash("0xd4118f9f4eb0f288c42db99b471a35d64f987d0a29a08f2b909732b84d1cc35e"): true, + common.HexToHash("0x9bd30e47b915ef80f01bd2b1fad595c5339c7d7b8ea0ebe1d6b0bc2678710fe8"): true, + common.HexToHash("0x861d856ad0a1ce01a19fc5d482b29990d86ef42042d799421b5540c6228c9339"): true, + common.HexToHash("0x0c0a74325567c5fefa049e93e9ebdbfd2b8e63169a9be55e9ee626bcc0e44a9a"): true, + common.HexToHash("0x5ece1054026654912f0deadd93f19b7bbf07c37dc0d5c2746ec0aad92a8bf3d6"): true, + common.HexToHash("0x92a062461008aca17cad0b3bfdeeb32c53dfa3ef914b4fe5f220142da12102ab"): true, + common.HexToHash("0x8f8e3b9c491612cc1d222055bf55778acc63d38193260e5d81e512c6998cf184"): true, + common.HexToHash("0x49265f491d6606c858108eb3911bdbfa2ff0c5a3b357ec98e876668f7e8652e8"): true, + common.HexToHash("0x1ba4076544da73b2c7e75416adf2f2c098a29a8df51a8c8cea7fd3195df4ee2d"): true, + common.HexToHash("0x55181b5848050e38e6615cab0e40afe9353447aceacc13466b8b77f22204d3e4"): true, + common.HexToHash("0xe1697cec4c1b86778de6f8572546a0fbb27da9eb7de58f1c480190b9636bef47"): true, + common.HexToHash("0x18c952f154662ed397e4ac66629d23c2e03409bfd7cb41f880d25107681f78f2"): true, + common.HexToHash("0x747c353f6da2c2b7880662791c89296ba93c8aa6b3289badccfd9e73478f481b"): true, + common.HexToHash("0x38b8e2c1f8b7af8c0588452a17787f93162edd58ca5a058650f53edf2c41684d"): true, + common.HexToHash("0xd3aae507847c720c1a90948f3f20dc4599af9e19f6b365c15e9e5f5a5328d917"): true, + common.HexToHash("0x70d99383fc6b8f317f28f0b8d5013bd8c37fc81a4cf9d2a1e8ebdbe40b8b55fb"): true, + common.HexToHash("0xaedec4441ad22602b802e619fe93e6bfa54a9147425b474396bc09d76c96d36c"): true, + common.HexToHash("0x6946093df94636a0dd0df1d7a25210e88d38a96cd266c63223c5903bded501d9"): true, + common.HexToHash("0x70d982fc9d5e28540f9fd455a3b40903a7594edb1a5963e19d8d1693c3f9418f"): true, + common.HexToHash("0xe802e1b8bd0d5715f810e83afc12dd418b41966a3df5dc6cb720f9f8beebc4dc"): true, + common.HexToHash("0x23f77b0d5c28c3f131118567bb4aa64c3769aa61f39e2f3b84acacda9e0c3348"): true, + common.HexToHash("0xa90f75c28a3fdb737168a1d13e08539ecf280f9fc793b82b133914ad335cb37b"): true, + common.HexToHash("0xfef2ea777ec11bebec7b72ccd14acea0521edac1360d718dad1e4f62104f895e"): true, + common.HexToHash("0x0c6f3f44b5ab00e23b5a29d150cd58a58523d25cd92aec036b04f631ad413076"): true, + common.HexToHash("0xd546dd27a09741d2c0f6ea85fb3a3c6397ad8ded8c497a3a9db37a3d6dbd9a7f"): true, + common.HexToHash("0xb7bfff183e7c9cf123e910e63ac4aac24cbbe18182b4dd78bb62845317600761"): true, + common.HexToHash("0x3c3e11139d8be72e31c028393cf48c8e5f1ada08dfd2d5bca093bcfcbb53fd18"): true, + common.HexToHash("0x8a2c2ace61635a74abeade80ca6ee69500b8c10077d10f99db3163f06bca69b5"): true, + common.HexToHash("0x9d924d88237e17915acc2fd9abf11d373b4d8a245e5dffa294f18d71a99e51cf"): true, + common.HexToHash("0x945b3d0b4a9f5bd3e053a0cbc4f344b0669860109c6c80a2045781f87ba82584"): true, + common.HexToHash("0xbd86643cbac68c2fbe5f1e34747b611d3b7bd84602ce6ae15e0483c5fb9d168a"): true, + common.HexToHash("0xec272e9112bda510bb6f7d769300e1346797ac6cf67eba5d1fd1e7483879b01b"): true, + common.HexToHash("0x039c221a3f552295192e225098e0a997c505cdb0078ce669523ff2e572e61ab5"): true, + common.HexToHash("0x9c1c4c80f4204fbe95bfbfc80b5e02cef6c08552d86bd67d624e29d5e46b60ec"): true, + common.HexToHash("0xfe30a89ea63b0a18a989dd0ff11b46ae202c9a1ea8eb9b7cb45b7496989658dc"): true, + common.HexToHash("0x8985d2680ae2234bf64accbd12260f11f6abc9047a720f8e5ccc251f730e9ab3"): true, + common.HexToHash("0xdc55013f668b09e833ef62f3439f961ac9680e87993766a2b43a42b176aa506f"): true, + common.HexToHash("0x01b1df4192e22870e93afd2aeb895afa65cf92b025a7d63c19c4e233a5c2296d"): true, + common.HexToHash("0xc332533219f6a6ca619c0ece640d46ff1b47cb96179bd1efb0ed6477efe03747"): true, + common.HexToHash("0xe3050885c9ab888cd24ac8acf47f99d79d9cecc5689f3771efc64fedd5e5f325"): true, + common.HexToHash("0x80aed73b3ba58c9dedd56730475c17b58bc2e1edebdbd2ab20c4cc5240def073"): true, + common.HexToHash("0xfbd9b8d3d9876de73a8f2de7f663debc237985264f863daed1d6211827beb134"): true, + common.HexToHash("0xad7aa9e2821623048d2a1fcc66d31d7fb6d956199b7e7c3ebf32299a8746528c"): true, + common.HexToHash("0x53e89c59d813c81da778c75a8b6079315e018640cde5aeaa5e5b1e4e7b63ae09"): true, + common.HexToHash("0x1437372d0f70f05f96aba349a7976ac2b840b3ee7511c2292aa8366e83f788aa"): true, + common.HexToHash("0x9fe8d8049fd0e874809a9c97b3b8a427470bec27825be9f23338a8bf6bf7034f"): true, + common.HexToHash("0x728a5a52b26aa4133728c190a51d926eac6d68e2a59de697b3f8f538d2cfbd9d"): true, + common.HexToHash("0x04028413d38a278b785f410cc4e4269351b44221399d3a0bbb76b9e643c556cc"): true, + common.HexToHash("0x4e657dc9d35750124cf71fb77d881fdc652fc5fbcc9cfebbaba942a1c73693a8"): true, + common.HexToHash("0xb23a72efb6cb15d3776020540393b9abaa2d077cfac4b1dffc63101eb816433c"): true, + common.HexToHash("0xee908f10bb33fe87bd5b594bee78bccd249ace73631921a13f2834cddccda3ed"): true, + common.HexToHash("0x9a4a3b03ab3ed0b547593b9e92db952e8f07b84837d5fd32a8d5f9a02283542c"): true, + common.HexToHash("0xad64a77ad1fad20b1e17aee964c92c02b76fe608cddb17580b04f114c9753cf1"): true, + common.HexToHash("0x620f951079ac5a845226c8000782e09687fcbf19699ae4e823631b54d222a9f2"): true, + common.HexToHash("0x495456796ce91b79c5e2e6e2c59ab241b8203e227b48b8412fb354a89049d892"): true, + common.HexToHash("0x4ad61ede7058bfe90f40ed8fee47aebbb1d9710b55318689622e7beba6f43c33"): true, + common.HexToHash("0x2d3a6c710e36302b6117c4b555182fd0391b3436ef863b89c0121c7f016f490c"): true, + common.HexToHash("0x10444df63586341e11d6e722e89b48e8c7afd83656a00876af25145736ffa906"): true, + common.HexToHash("0x512e8bf8d7e5688418481b64bad6ad692bfd5276456898b31195ec3918fc2cfd"): true, + common.HexToHash("0x5fa71ebe1751a0cc5fd1860a8b3d2a3598156f895d9f55cd8622614ee0fea16e"): true, + common.HexToHash("0x0f394ef0b9da09f37c265b8d9ade1858ee3cf662953964e9026c6cfc94af49e0"): true, + common.HexToHash("0x36c093adc463d9c8b7723c64ec10c98f4a5b6ba35aa611d42400b02009194e8f"): true, + common.HexToHash("0x1a31231d1902306b9b8bbace0918c17a62a6efb1f71fbdc3385ce46a878a7811"): true, + common.HexToHash("0x31c8b3303aa4b22bdf46b6d967b31dfd70f62b2199c12ef776ffffd84b7fe579"): true, + common.HexToHash("0x5ae463aa69131c33b5c9bb341a4614ae9a19bdfb7b76cc789d12556b84d91610"): true, + common.HexToHash("0x1dfb4c7f891289a257325fd24cb054b39a6ae60e39f10885c220e4ecc1339338"): true, + common.HexToHash("0xd57f0e0ae22ec818a8f0ae24caf742f3b710944185888b1894c63274091d09fa"): true, + common.HexToHash("0xd721293581784198b4a215467147636ba830b02317f9e72ee0cc251e6b2fc1a0"): true, + common.HexToHash("0x5223b24bc619edba25671f40e32b3c0ea1ab0643b949414941453ac9f8951b63"): true, + common.HexToHash("0xdf411c0bd970450fa3f67e598717699f057fed3b56a6cc168a2d026097dc9b14"): true, + common.HexToHash("0xb4969e8f80fc3a82d440444c09ea8bfbdd585ea8ee5aaa52b09fb274674fa0bb"): true, + common.HexToHash("0x97fd8ddae8a0652b86cfabe5b2bb9edda37235f03357ba8e09a20b0b28035a87"): true, + common.HexToHash("0x5c3fa6618bcb8ede27db6e1a26fd1f9faa93679a941169f0f21778c79ac2a3e4"): true, + common.HexToHash("0x336c4dd37118fe3cd90a7187efefdb90260355dffb8b5a22fed41fa39a94addf"): true, + common.HexToHash("0x2ee4ff53b9f0330f57470fe887d676d0c6f12e1b071a0e5e80e7f5cc79f4cc7e"): true, + common.HexToHash("0xa7adbf54b54b49338b11f52912ff15569963460d6b5c23635219bb9dc77c0964"): true, + common.HexToHash("0xfdfc81a133fc0a985f6b5e5e1c08c6d2719f337b7ae9849a183c5fec27e767f2"): true, + common.HexToHash("0x7ee2de87b80e60b26cfa8534ec59b868d81eb622e7132fd67af95a55c4d283f6"): true, + common.HexToHash("0xf728b6a4e69edd3c9fdcd41066dc49f44ba5e17c6a1488b33c4926c990ad7db9"): true, + common.HexToHash("0x2544ff908ebe85c5daef62b1a03436cc05b43db475b0db48839ccfb03fc829d0"): true, + common.HexToHash("0x9c9cce45c45293018735d7ecae30d800c522609b0eada12d2686bab9b311a3b3"): true, + common.HexToHash("0x79edb9ae4e19abdc67557bb9baa0ef5d036ec20a57d2ccaf54d6873d3baace87"): true, + common.HexToHash("0xc295615b39b3756d941ad1d24ecac2d24ce3235d350ad10ad1bb5bfb0c0a63b2"): true, + common.HexToHash("0x330169a56d79e7d4ac65da7a351baa0a3d0f7a935bb1d79fb6a4998d6526ebea"): true, + common.HexToHash("0x446b0ef22ec7902a0f9776c44846a9f0ab4e19db239da146ae817c70b47f80c7"): true, + common.HexToHash("0x7466da9bd56f68b86ec23fb3043146701884888c42d75365d8357fcfcace8b4b"): true, + common.HexToHash("0xf44bcee65473fae1f51fc08fd8ba67efde2aea7c19ef79fa7c0de916e581a084"): true, + common.HexToHash("0x30623ef33258726b4aae0fa1f9890f3e0c23309a0f7d2b3270548fee643b0844"): true, + common.HexToHash("0x13e26b3b3a0eca98eb75b3cd010f400bfb8105b3d4ed9236332e4c57642ff793"): true, + common.HexToHash("0x9e263628872415ff8e8834f13e5ce620140a8c3d1fcfcd80b60ea719e0b3b9cd"): true, + common.HexToHash("0x0ea4e0967efa1addba96d3cbc722fdf2175b78c39ffd7176e03f41427be18b5f"): true, + common.HexToHash("0xa4ad206df2b00d74bc9bf88c5726309e2e825807e8e89894eb9c54e232010c9b"): true, + common.HexToHash("0x858ae75a6ff48229c0ac257cc241bfaf091cee3e93192bfe6827b59a24a71524"): true, + common.HexToHash("0x87fb385b5eb67556ee7721f74f435e559d940fb9cf8558d57af0e1d43df96d39"): true, + common.HexToHash("0xee422ead09c48f48d3c673c90f0c1ac7b711056ff25447973b14372828a1f5fa"): true, + common.HexToHash("0x964d804e2c10f44734c5d6ba5fb39ae6f3e3ca90db3e8ac09feadd2ddaed61f7"): true, + common.HexToHash("0x65f90b4a963f6f41681917ad2bf8c67977053059bfb6d4dd3184129ab4b5acee"): true, + common.HexToHash("0x12574b72142da793f7cd5ab9c76f995393a097d9e940ae81a589f770702a9634"): true, + common.HexToHash("0x581182e4c2a929ba4c8ee16b2c05a3bc4e46c3568bef3ef6db937778769c4659"): true, + common.HexToHash("0x012bdb6f5056b286d49650e5f97428d632c498cdc511d0b8d465b41bac8b2f58"): true, + common.HexToHash("0x298c5f3d3a9766a4a56a905c04e808a92fd56baea3e996deaa89af64c1e5816c"): true, + common.HexToHash("0xbe419f0c73963e32da6da3b7e0e85458a0b30b18ea9ad6a07af6ac775ee5cb9d"): true, + common.HexToHash("0x878e6c015f30f4a764e60cf43b70d5edf3e01f1f0e30b5d6836d6389dd4e2f87"): true, + common.HexToHash("0xe07a3779aec268854e28b30864be293d4d5dc277366447b226be6d9ec7f74e90"): true, + common.HexToHash("0x8ff6a9c61ffc156f14fa386c545139ad185619e2f8667ad2e729d37d21ffc85e"): true, + common.HexToHash("0xc8282956ffd9761e4fef18ffc4a3dadda3de28d6b294d73cc3798fc7fabc5414"): true, + common.HexToHash("0xb4cb14c17045223b8fd24572a8f0ee247c77c5aade44f007d14fa2fd3186accc"): true, + common.HexToHash("0x18746f718add650eb742d8e5bceb2533ae259df641a92aed3e10a12c7f91533d"): true, + common.HexToHash("0xbb22183d68d88a1248f63cc7fe99dc894452a23f9539aa40b0a1a74259bf25e4"): true, + common.HexToHash("0xb547621f3713049e7583706afb8c11aab5df96254ca6daa6a583eeacb3159a0f"): true, + common.HexToHash("0xd394982f228c816b2a7b19d9c3137f92825cc5ef5f2876b920e47db5bb95ebdf"): true, + common.HexToHash("0x9711bdb16a0b7a63d27becad24d2e4828af9b22757ea706f025b1d15d8fcffc5"): true, + common.HexToHash("0xfccaaa3f9ae5f4f7fc3834733f37c8763ec877f62a1f912d357491c2aa9e5ae0"): true, + common.HexToHash("0xdca8f304df435d048bab0793e5ba494032286616541e00199fd226fa2b2ed9ab"): true, + common.HexToHash("0x8506414c55572e36bf3781e8aa00eaa496cbda73ea0f048324607a48fb96edb7"): true, + common.HexToHash("0xf4d78456136a7f309fba620a3775e70d6ee6aaf08ac30cd19b4d6c834616307c"): true, + common.HexToHash("0xe5687fdac128abbe8c8d8ae19477b63c49e577f29b79e3bcb077717d6415e3a6"): true, + common.HexToHash("0xe0931575b92f03673309d892bcfbf50050b613af30a38dc196b31c18d7646249"): true, + common.HexToHash("0xc8277445df6e7e6bbe0afc5de9acf49ebbaf80dc323d8445739fc08299de6734"): true, + common.HexToHash("0x500adabbc88107fed8738a8e4f68e20d548bd384680cc9b7d0b0d883b4ed9ba2"): true, + common.HexToHash("0x7d0561c3bbdd8620e13ca38eb02f07b1f8def4a61ca347a244b0c2c5c4fc6d0d"): true, + common.HexToHash("0x704e2856509e409020c307537cf78d6cc65e694832d1c8158c351a1920c4d992"): true, + common.HexToHash("0x65d8eed87e3bf09f4571e4c0d62212a338159545e577e1339f4c12db4b8b575d"): true, + common.HexToHash("0xa2ab9df936ce3e2f1dff638197581e18cf25174143ef5617ac83544eb4273cce"): true, + common.HexToHash("0x479565b62a4f3dd4a9dd607929f622552155f17202ddab17796f85808245778b"): true, + common.HexToHash("0xa0d912e3570d4e2b2bd5c77f6a7bae86a78731e405115daccc4fb499b75af564"): true, + common.HexToHash("0xb9805c71d747e3c86583fbee17d83273ef393d59fbe6045765f1cd77c25362ed"): true, + common.HexToHash("0x451010c0609204720f55a1aae54f230ac8a19edaf6866bb61ee2fdc3b5c09147"): true, + common.HexToHash("0x8864e29ca16151ebf37abf55b31fa45122963fa8fd0c56183f8f7667b2574f51"): true, + common.HexToHash("0xc860056f5044b04698998abd7eddf398df0ddcea361e6ce7e32f0e7d0afa142b"): true, + common.HexToHash("0xe0426a2e4f50ed36c7ae0bf9ab28d5fdf8dae5248c77bc09a332af1d99a81f0a"): true, + common.HexToHash("0x767d73190f0f4243f686752d457ff963f9fdbf562b6a61f60d7c5a16c1125f2e"): true, + common.HexToHash("0x67b448a29052a4383a5b1a7829e1f560519b6bfdcd367b60425a9c70106b9abd"): true, + common.HexToHash("0x6c38f3e0be46a350561b6647cf2ed607f152e2a133dab59c02460a76f66fc7c0"): true, + common.HexToHash("0x40ca985a64d56f66822ad9357d52e2cfc233d6a6447dea45367659c116054b6b"): true, + common.HexToHash("0xf85d3277b02bf9827e6616723814795998cff6cf4abf8bb8bf5fdc1cfbae1a1b"): true, + common.HexToHash("0x421ca394388af0875916f40fa938c2b0bc460d52a37282458cf232ed67d3ccc2"): true, + common.HexToHash("0xe0a5b7b5cc345cb34482b70d6651d640e03b3a3195cb8e38cd6bcfd0562832ef"): true, + common.HexToHash("0x462c3da39d67ef5154d7b2f81c77eeb9339e956804db6556c60b0e29f89b09d6"): true, + common.HexToHash("0x5d0d7a99d14a982d6194605ff83ea702fa3d8155ea507561d5bee3bdc69bdef2"): true, + common.HexToHash("0x52570a9db2393197f4e7496dbb514870c910e25a5125bdf8848fe6d62945c02d"): true, + common.HexToHash("0x32e7563675498e3039e1546c685c2e3df2c455383b1f4cdd4ada37cacf5ad6e3"): true, + common.HexToHash("0xc648d35706d2ab17ecd9a4da38540af0f57bcb12985569f25f93ff79ef0bb308"): true, + common.HexToHash("0x467d0f3b239a71095eac9301ef371ca0a7e7dd811c4e73b7f2f6aba66252489d"): true, + common.HexToHash("0x7e18d65e59ffb5b2774aa97739c182c554ad0d1dfc5ced7a9f816caf1358cb02"): true, + common.HexToHash("0x698ac219ea73ead1e1c702195a2b3041ad79cb7a7f05948362d8cc672b627eaf"): true, + common.HexToHash("0x931eb1749c302383de6acec2dd83642da74cf70aac0175b9aa6e00cf8d2aac10"): true, + common.HexToHash("0x015759962fc2857010a43f837ebe9bc9d305ba6786bf257d9c6ab3c535343202"): true, + common.HexToHash("0x7e9a72f76e05cbcdf7acccd46aaac49eee4b8cc6fe2be38ac54d1548e47a6573"): true, + common.HexToHash("0x5d7206b89593ae143ae61b0f23d21ab26e40356a0072d9f465795918b90a8290"): true, + common.HexToHash("0x539f8775626a860ac3be9f7b0be1a9e1ba070b4507b693324204d4cefe131574"): true, + common.HexToHash("0xd69829b73707d6ddcded1080d6c7a97b0ca5883e58bc68ee98a3ef5aa809637c"): true, + common.HexToHash("0xb25852e7dee9e4040600d21359930ce57f7094c0a8c18e92b9fabc7553585c7f"): true, + common.HexToHash("0x557cf17146abb40b50ff9721b7045cc22009cca580926fdbe7e9ada6d5292b1a"): true, + common.HexToHash("0xebc39a64a8354d6fe31c86828470f91442f93340163648ac19948079bc71dceb"): true, + common.HexToHash("0xb63d5e17316d8ff12f32a00896ba3bda23016c29f5128453eda564ad481070ba"): true, + common.HexToHash("0x084c2a941d8185679191413de10407690f3131de906c05cbe86fd2792b99eded"): true, + common.HexToHash("0x081f0d81c0941700aa408bf291700ddd8a925af0eab7ca01257364fa5955eb5b"): true, + common.HexToHash("0xa9bd82a9c8e6af68e03ae29d2c9f31de80ba5cab88c5edda5c9404e96443c9c2"): true, + common.HexToHash("0x59357c9a466cea8d8f07e90591a4dd2e7ee1cdd5e28c26544306e060a87faf1c"): true, + common.HexToHash("0x4bd47fa6b3708cea7aaea2848549a2aaaa38c0a37990979ab9cc843f2a87c2ff"): true, + common.HexToHash("0x0329f21972f27517d09e134aecd27393c8444df399e9cb0034d5f68ec39158ba"): true, + common.HexToHash("0xfdc230836e1bf5bdb5c89910cd43e8269a824bb1db7ff3dcb183a929a1172cda"): true, + common.HexToHash("0x11d38c2a6baa52f8b0f9cc3d13d0424dd6300e30985e738acb33cab4da8c0cdd"): true, + common.HexToHash("0x7bdf0e09d592d0934c5efdaaaecf21dd0cd36a7d1cb58c095403244143ae9aa6"): true, + common.HexToHash("0xfd253a70681b0aea9f76b83dd9c1850b925e0170dab1570c287d0e9b08ca8225"): true, + common.HexToHash("0x629a702c33da2b97275321cb6de58c991f8e3f3a947aa84230e4bf71f0f7385a"): true, + common.HexToHash("0x5fb06afef814af52abefff37e39958bca1e6df885d75b9d80cb32916b8ed7139"): true, + common.HexToHash("0xabbcbaee7fec5d556446ef73c1d0454d14316b461412c14fb96a9056179552a0"): true, + common.HexToHash("0xf8fb185714a190e5e064755a66f001830c6404f204f1df1e6ffad473c0c47f6c"): true, + common.HexToHash("0x28ce87d927a9472aa91100814e7da720a190b8fe605abb6d91f5cdaaf67a1550"): true, + common.HexToHash("0xf81be499651bbe97e7e2f9c0c3230d5f1eee8f2f05bb19f347b893db7aa77c13"): true, + common.HexToHash("0xb75b9bcc7cffae0a27360b56755c460d6f56fe04ccea96c2b23c8d525283dd84"): true, + common.HexToHash("0xd747f9f9d6903a3878e2d40674edf04352b6a45b922260880186d7992c552f5a"): true, + common.HexToHash("0x5e6366cdddacb7d1e2d4c90e63d636f02aaefd88dc626a7346a5460a4c9360f3"): true, + common.HexToHash("0x0f4b1d9ccc26c259bf7875593d4392102b4ce4fa63fc7fa8487a18c20b37ed73"): true, + common.HexToHash("0x41f879bd699d4bd43a02cba1550b896028711670376055a18b4b515b84076cdc"): true, + common.HexToHash("0x9be0a854a7363534aea6f7b5c21197d4f5f2ad051270e1fdd62e39d6139d359a"): true, + common.HexToHash("0x65bc03b26f6190d31eb32857ba2d26b1e761a89b9d44dc5fdef35da7a4cd42ee"): true, + common.HexToHash("0x99c04c4dc93ef2e51bb9512391868ba8f7b117bf09cef7ac6aef9e1b92da9178"): true, + common.HexToHash("0x4ff497afb8c9f20d502e3805bceeb091d5b88a8c7409b264691b897fe95b85f5"): true, + common.HexToHash("0xa71fdb27652fb71ed9b6f5a69ff3ae68a497c3cb21a80fc2a240a056f97bd49e"): true, + common.HexToHash("0xb9eb32d11526cfeafe53fd48d14baca00bcdceb774f9bc6534af34a0f4812cad"): true, + common.HexToHash("0x85e3e969f870420b7f253429b4ce551d16ffe59b03c719910082251b7c46be12"): true, + common.HexToHash("0xcfea0ff83a05fa2932d864b88c48cbd3b97f527932cc1a108258bcf487c76720"): true, + common.HexToHash("0xf6e78ec0a1a62c4746f1d20ea45b288b9c07ccde0ce58e5a0f156989d1fdc4ed"): true, + common.HexToHash("0x07c874ba7951aee815d0fb04354fdf4543736ba56b0807da9e8b1be7d684ff51"): true, + common.HexToHash("0x8895a416aae75ff8318ebeb75d8a5cfcad37b0c718078ec9e86114080364b207"): true, + common.HexToHash("0x447d725a3cb2e93ae12f1c9ec6098a4493e714c13302a7a5f3f577a7ff0d4990"): true, + common.HexToHash("0xbdfb709b64271dce662da0bc361791f388625e60d4967e292e4d28bb82e72e6d"): true, + common.HexToHash("0x01e274521973b033ae67693c9e03fcc028f5fee4491ff9d9ab448c7205e48fe4"): true, + common.HexToHash("0x603e8a3394a29df567fc749cf0c523cd0de9683bbcbefe580a15fd6e6263d86c"): true, + common.HexToHash("0xc057bcfe688d5dfc5e3d97b6ef6523d251e4bc68c82d75e33abe54c8caf47630"): true, + common.HexToHash("0x04c6d4a544bb404f364c247993280fb5712c50400409e2a85e903eb421778b70"): true, + common.HexToHash("0x10bd1e2bc71f900b9858f5c7b3645576463d671eacfac6d48968a040085f6a4a"): true, + common.HexToHash("0x20966b254b47fe4cbf577f5cad2036606ec7f6ed5cdff66bd859ca8e6a9ce0a8"): true, + common.HexToHash("0xc1533e1be01255d4a07547e25bd904d3a28596b077d5cdd52aa153581cf5515c"): true, + common.HexToHash("0xae2bce197c08d828d7c6c183f64be32dd9f3b406f93ab3b4d88aeb3037d979d4"): true, + common.HexToHash("0xba718cb1b25439a4469644bb6fee58c2721d3747f8fd766928e36d52ad829428"): true, + common.HexToHash("0x248fb97d37fb21f5f595ffc7ad19fab084c18f080ae5ddabdd231110bcdd1602"): true, + common.HexToHash("0x0e308c0d87e273949298c6bd775e5cf7ac7676205cedbff7f3f345d34f861dcf"): true, + common.HexToHash("0x069247cf0145b020cc738238b9857160aafa9fd8eaaa4c23e0db4dc939c9a6fd"): true, + common.HexToHash("0x365b9f6cb7584815c0b982f13622c4375a8b808f51de323d10fddf63fe7d24f1"): true, + common.HexToHash("0x91ae70713c7e64ec45a9e92ecf461f3dd378b9ee6ea9a1d4f1d0f516bc1b7f2c"): true, + common.HexToHash("0x3e513180109883f83f035540b9b77de67a19c09e7f6b75c572175c6e5695077b"): true, + common.HexToHash("0x598acb238ddc60fae578be94e40e2811fdf4df45304e32aee5d1cbdba964144c"): true, + common.HexToHash("0x0981dd6b23418edb4c9b531eeaf24137d2251212f55670753c60ea1426818969"): true, + common.HexToHash("0xdc5ff36ad662e778b4758e4f9c81dc8ceff68f11e44389a0ed8f9f9dfd4fdd1c"): true, + common.HexToHash("0xed720e25149ecf75c80c27a51a9fc5c28aa286c762b4271c35f10a59d1440ab1"): true, + common.HexToHash("0x2ff3abf5e1522ea32a041615232aaa6c32aca234afaf3c99324ed329384fa89c"): true, + common.HexToHash("0x608feee4187d3d188403e7c380d17e8c3622ed37bf8ec77e5f536d4c0e7bb649"): true, + common.HexToHash("0x1f11a41726d9ed0612fc3103b4f510a9d8ad3ad8b48e0d6e36731720d1958ca2"): true, + common.HexToHash("0xf022139743223f23f15bfedaa4532d441c905ec0eee06c1888f54e102c065422"): true, + common.HexToHash("0x3fc31af1b3882613ddb4c3cca7b00f2c1b934f76315b0b3f6c2e7e0e37029ff2"): true, + common.HexToHash("0xb746596360b0e3536c249aabc66d0ff9f7d1d23c7ff42dfadfcf9b491c9227a8"): true, + common.HexToHash("0xec6325a87aff068ad57d8a3d13f1b7af1eb2fec0d71e9e5501f4e47cf779bd39"): true, + common.HexToHash("0x1e1f66ec3b55b93ae9957c5889ff9d7006f9f22633f40c05d4b6da0b9c8cf6d3"): true, + common.HexToHash("0x2d27d6f07086b03cba93fd0a25353e36f5a5c65a2f91739415d8e44b1d15d7de"): true, + common.HexToHash("0x76e991bdf63f1d54c3dc2da60ad9e5042af88d4f94f2727868b046c26b4f2e5f"): true, + common.HexToHash("0x79f91cbca139d8e7e41d05202e34f0721f78d89e0b37581f2ae0ca9c4a6a7fca"): true, + common.HexToHash("0x4533dea0392022040daace542b8be22879a9701415a80c28d8baa307494ab239"): true, + common.HexToHash("0x925e6f6fb6fc2bada2b7638333fa6c067356f9e2436d1a026c3fd7000d60861a"): true, + common.HexToHash("0x27e5fe0ea1e05bd93a1bdf445ff341699bb1b468388585e6722c4327b22e9c0e"): true, + common.HexToHash("0xe07446818e5f193b564df2c3722e0c2484de25d2f365e0f1262e9dccfd34f73b"): true, + common.HexToHash("0xd1df2ad6c3c4fed7cf74bc974cd327cca6f12d26cfc2a2f5666c93c33c2dadbd"): true, + common.HexToHash("0xe7a599134dfa7e13fb720f0c45beeb78404dd1e491e14abb03b2c84d0b2f961a"): true, + common.HexToHash("0x08fc1b1d4b9823cb4cfd705ec770d3d5931de5c867dd3adfe0f409f732ae4d33"): true, + common.HexToHash("0xb7e6903437d0ccdd2b66d6d7c63f6f71d44d7f9aab00079c1ae6dc0d50e1d768"): true, + common.HexToHash("0x333ffa25239544cf212362e3d0bf5c3cf91be7aeef183961958306d341c9ba59"): true, + common.HexToHash("0x80659f03afe647402213815ef91ac69e03f30c1a84fdb366a11d821b51a984b6"): true, + common.HexToHash("0xe9f5755ae070c3d81d0b2f254e8985e3522cca573b992a6de75454b7d66afc98"): true, + common.HexToHash("0xeb079a12dab50368f52725df02e4cdef7754d57f46a59c0a3c1d2270b3c8991e"): true, + common.HexToHash("0x59402fa0bff338ca8b80e715696d82384da282b974609b815b5db27a29651986"): true, + common.HexToHash("0x27f39497af16865fbcee69f4ce178facc0b8ce8bb5033bcb2de786816807789b"): true, + common.HexToHash("0x15bed83553662fb45dd0a8c25a8e0f001450574a74e1f38a55eaaa85ec26a763"): true, + common.HexToHash("0xa8460a74a167c739b23c28f0475784dd5250d835a2e4f281627a0ce4cda2e242"): true, + common.HexToHash("0x7e0562b2401e94bf8cd7eb4c5159f84737002cf8db622bfe2853ef0aae22cb1f"): true, + common.HexToHash("0x4e017ddd34e9b78494932efdf08b890f746cf07c3883c7607fe69fc4aa633182"): true, + common.HexToHash("0x85b50d6258f54809b6427c35ebaf6fdd5023546c886e5f9bf5a6e7ae40fd4444"): true, + common.HexToHash("0x22660fc763650566ce872dd1c7f88ba575bce78f2192b3d6b1c4de3d438d38bc"): true, + common.HexToHash("0xf9822cce10466503d17466770250be7c9bd73522a878fe34a039ef865acbb53c"): true, + common.HexToHash("0xebc9fb62f89f8053aaa13665a39d8b68096a62c1293c3bdcff7ad6f6fd4f4beb"): true, + common.HexToHash("0x3bc25bb7d217059078914613160f620522b910d58cc6f61401ab21eef1fdb791"): true, + common.HexToHash("0xe724f60441d7d836d13a2c061a26bc0dbede12157ab9896bceadedc83809f5a7"): true, + common.HexToHash("0x014aaf1328d86a8c7119469bffc0efc71cb9d22c808bb0ad20cc02da7df36725"): true, + common.HexToHash("0xa5487716af7fbb10634fbf2fb65b375f67299ef089804c11f79e757f046f0c99"): true, + common.HexToHash("0x50f0a533fe935a8a2611907500fa412f39f1f4b2aba552acc25bab5f91b48969"): true, + common.HexToHash("0x25b66e78e0430c60c73d8ec7d8902eb4fbcb106d990e1183f1930c7516f38d86"): true, + common.HexToHash("0xf11009913f5d9320363f4dbb5b072327ffd656daab2d67ff8b42770b098b8dbf"): true, + common.HexToHash("0xcee86dff14f745baa1d7a714887ebedad3858ff652d495950612be504ed28590"): true, + common.HexToHash("0xa07d69903392964d6ad9f95456aa2798a1ae8206cb1232d2a1fc7c6f35692738"): true, + common.HexToHash("0xbed1478484d1e0d3e92bc0effa0c94b4a4ffca2cc0a63edac477ba63b0afc585"): true, + common.HexToHash("0x4d59828dc1b57f59b577a0c4cdf7c641b8ef1ad76d90b14fc140814123b3a58b"): true, + common.HexToHash("0x03c586f69e6c31e26a81e9d2a5a578b2138cd3deca20216e797d80cf0197029c"): true, + common.HexToHash("0xf1d2fa46202a592bab811ac851080c773283794e31ad488f9c0bd9c69a1af0b2"): true, + common.HexToHash("0xc874abccc945f0d1aa293fec33d5299a24b2dace5f158cf1b2a3a2edd4dc9b9a"): true, + common.HexToHash("0xfe47a8da89e85886d581169c1923448b2fdcb0db448fb430924a944648e753c1"): true, + common.HexToHash("0xe15b3636d35e08c68d4ea1607e6f23dd683e3bfac2a7aac7317c9737b00541ca"): true, + common.HexToHash("0xfa74f14d6b6498118bcb160740c16a22c51ac31efa00dd42576ea70d6ff2e52e"): true, + common.HexToHash("0x431e134119cd05fb2818168a21a44e4145228cbc72dee6301e1351eb00698b3b"): true, + common.HexToHash("0x83c43ed604f10dacbd9d27848136b4e9b371f4ebd156cb268fcc0a764b7f0b68"): true, + common.HexToHash("0xab3efc58042b11b3649011e51c3ce381ea4f283a32ee8c2b64925e0c892d184b"): true, + common.HexToHash("0x1f287956db57ed2b87f36bc35b37d4ff780eef821c8d40bbecdd5d844648843a"): true, + common.HexToHash("0x618e0de1fb0068da99a689c9d23d5898b2cb714b29b11908fb7db80f290a4f62"): true, + common.HexToHash("0x5bfaf8d3ffdde36ed6648e9598596edca8f9d5449400ea68786f07c454c72460"): true, + common.HexToHash("0xc42ed2a92f2ab1a68262e2c06f1223037a1ac0af242ec77a0459eca056b18ab2"): true, + common.HexToHash("0x47653c834dc5a932eb608d0780dd49007cd589668dc70b4c3f1f2ebdf0f0a464"): true, + common.HexToHash("0xd258378970a4a87ec19d492f8835be66e90ab168751e32fc3f13f8b6bd61165b"): true, + common.HexToHash("0x96b4ba9fe4a529542af5fab044aef504ffacc538444f97f43bbcc24167a1ddd9"): true, + common.HexToHash("0x1b84f58ffc8e43ab5ee382405b27697e985695d62fdce026b22445c88e36d8ca"): true, + common.HexToHash("0x6a0e812d82f3207e6932a8e65f6c2059e44c24421cd5f2fc518a2e428458d582"): true, + common.HexToHash("0xecb6174bcbefb25a7b6dc4575bffad362ab289fcefa4a05fe4a1d8e15c6281bc"): true, + common.HexToHash("0xdfc0884af131d1ee583c513a0dc26d2b72f2a5e3e0fc955dfdbd1b22c364fb66"): true, + common.HexToHash("0xd13535e40d801f789926ba2f27097feeb637939846d1b1aa67b349f2e7180b73"): true, + common.HexToHash("0x901eff599ac1680192438e5e73941078ecbe5560fe60dda22556719167dce0ad"): true, + common.HexToHash("0xbfc653f7670ad09310a34a9b9e4e4ac4e03d471042ea44174a49f96a538dafd1"): true, + common.HexToHash("0xd1da98503e402c4588596a02b6ef36fa9346cadfbee37280cd5f8a695f34d593"): true, + common.HexToHash("0x4b37539b8689249cb28f22795bd0687dce9fe85ec8d3d80617de2316fbe3fcc7"): true, + common.HexToHash("0x8a3da87b263cd0289d5db812b05b0fdb11b0c89f049df89c25c02abd0d971589"): true, + common.HexToHash("0x29c0d3610fc7acc6de56354a4e0d75bf8c7e4ab1e4ef08d21949470aa2e26d81"): true, + common.HexToHash("0xe870ba8e15418bac50eab15f9f30251927a017d0dc3980d769e97d20f0d802ac"): true, + common.HexToHash("0xf7e9f62ef921ae17ca550ea2805637fce2365ed8e6f6580bb9769dd7deb57d36"): true, + common.HexToHash("0x3543c77979cedc26a504b0dfe9cd5f72ca27f97be4c2ca8246bcd79cca71993f"): true, + common.HexToHash("0x5459a7153f4ca28d70547f181d87a70a97f72e468598e3bfb06db57c05392688"): true, + common.HexToHash("0x68a83e16083b034b44825b8b971a6f6ea9c47f3ef85500eb70d2043ba85181ad"): true, + common.HexToHash("0xf26e1262bf8f313a317d88bb1811fbda5a60fd892dc25916e355d20092248f50"): true, + common.HexToHash("0x5b817624ab3f2702fb5c0f604f11f9c42e0b96137e51afec57030d7726ea2b94"): true, + common.HexToHash("0x5d970a98fdd00a77019f044eba6f2f446fc31d124bc41d1083b28271d3e9be06"): true, + common.HexToHash("0x77bf9ae1a62ec7abe61c184c03b8803fa2a74362bba81d15e5839d984ebdb47f"): true, + common.HexToHash("0xa611640bbc70ea368c59df6adb71a7362bdfdcb76a935f9bd2fa921c43db1704"): true, + common.HexToHash("0x7db91eae5ca0ff705faa7fb766120cc9d3b935fb79b25876cb395125578878ae"): true, + common.HexToHash("0x6b9eeb00bf2a467951eb28d3bae0622b86eac97b2fc715fa1c9d2b7016cd6d0d"): true, + common.HexToHash("0x629d3e42e22fbb3eb21351cc8b9f8002da7d47da459d4902e0454f26f7a2c917"): true, + common.HexToHash("0xc7140a7face9a607264c0bd42b19eb10b6bc106d4d61578ad796e4b3f821c623"): true, + common.HexToHash("0x78321500d532b2aa0fa425a0f2ea7971d34bc556f2ed1691fba150eda606baae"): true, + common.HexToHash("0xae5956a3a0c070f568c6afcf047ef4a90cd922280cb60c1ca756b836ce0acf3d"): true, + common.HexToHash("0x80a9203be7bd7ba5eba2df8cd4dc30fe5e98e594e59225be4e23ce0631522d5f"): true, + common.HexToHash("0x2620db377ab3f507bbee25a913b9d1128db92ce75ec91c0ae5800545a9742bd2"): true, + common.HexToHash("0xae654b882e027db118af5d50f8abd917c12aeefe5a41e230b766a4785c452170"): true, + common.HexToHash("0x9e0d6a396a5dcc04afb5981d186d8a8938863678ae8978daddd521d351fef1f7"): true, + common.HexToHash("0xb144d21a766ef37b1b12acec7813255b17cc1c120438a205e51c3fff59d795fa"): true, + common.HexToHash("0xb38fc2cf102be3bc9ed6d89271a68b6790492fbff40d15213666fbdc51f26afb"): true, + common.HexToHash("0x110d4c47d6cc9013e0fbfb99265bcc444fd0fa6d6799680b093c5b8373afb2f1"): true, + common.HexToHash("0xd827b7f89455ea50915c8f71074cc45117e2c003c428f668178223e568d43195"): true, + common.HexToHash("0x6bc832d5e43cdea5cb3c41dd9485d119f29c2ae0cc871bc7399f8f9f3a512be9"): true, + common.HexToHash("0x9efd6981fc28fdd02104ed8ec7fbae6bbdbab3fd4140124117e3b3580555da21"): true, + common.HexToHash("0x67fb47fbcc10623705a7a0fcb7735276c232270f43cb1af142f75b2b0f63ff6d"): true, + common.HexToHash("0x306b7f21e0e971beeccf3a1ba2569eb5a495d9956677330a0c4921234fa1d6c1"): true, + common.HexToHash("0xb52e37dc4ca95be90d405b59395a78ea0c72b4cfd5e24ca6dfe90bdad7a0916d"): true, + common.HexToHash("0xdb2b48708ea218c4f469be2846b0e15bfda5f565c8d6dda13c8296daa9d5de2f"): true, + common.HexToHash("0x13b748313e1859d624a318ac9ce1fe999b43936e0097b3911315d5b6c1eb1a61"): true, + common.HexToHash("0x81614cdf300302d51eedf84c3a7475ef20a6d0ab5c8796c149cd98acff0b2edf"): true, + common.HexToHash("0x6186756aea973006bdd5793cb0154e1330d0550557d4a52cd9f590738b90719a"): true, + common.HexToHash("0x4f7326192aa666af2a83d8c9bd1187df65ff625515f3ee9946d023e4a4415601"): true, + common.HexToHash("0xecde14ed5967993e22b1b1907401d983a1bc95fc5873740c8d3838b6dcbf8914"): true, + common.HexToHash("0x5f7876bdbd7871ac21d668315d433784336686bc75e58d46b2cae0abc89466b8"): true, + common.HexToHash("0xd43df2fb91ae7927897079da9318a0dc4946ef4d0f9d92f49701e76451d8bb63"): true, + common.HexToHash("0xa7800a146242a3be9615a328aa63f5ed9b45c937a3b346f9b6d9d7b453efff09"): true, + common.HexToHash("0x9811d377087eb9cfebaebc3b05f1a0201c6d664ca2a716d5acf8b4135dd020dc"): true, + common.HexToHash("0x449aeb7a83b353d24fce840bfb4097bc4f89ae54bccacee41f26d734398e5ec3"): true, + common.HexToHash("0x9fc0f69f2f49b5cf5763cae8c7194aaa55dc14bb44359cb61006f925b67165cf"): true, + common.HexToHash("0xb2ccc3cd0cac0054eadcbac0a968ad238f0e47f4aad231c12d1347a786170e93"): true, + common.HexToHash("0xdb54a89c106022b8c43f58a037395ca8953fb4eaec8544d42096e0eb74b54875"): true, + common.HexToHash("0x10c3ab290bbe75c68a15f7181d7287700f8633b318442f00fed5659cb75d50a2"): true, + common.HexToHash("0x8bd4f4549a1f81caf22c60d52724a1bcdc9132297531c796680c40bd491cf20b"): true, + common.HexToHash("0xc9076d7fb1ad1104664f30bd8f8fd2d2a97b5b3a8934cbb36be385dbc3399a08"): true, + common.HexToHash("0xbe558f2e3de013e95b056b2f02a59ff194fef45c5cca40221b35bb0a74c74b5d"): true, + common.HexToHash("0xb3617a3260ec10058cc25b50f628ccabf95c2706c522e9249f6cc678c5c880cb"): true, + common.HexToHash("0xa6ff56e3fb8daecd7557a72821095151de621def135d8ca2aeb2a6e377b049e4"): true, + common.HexToHash("0x5c9a745569809c14e40118c80f36c6858431225d1f4250d6b1e500138b7d39b4"): true, + common.HexToHash("0x170cc057ae144698513f4940d92154416e551ad2b15bf301e76aee6c2bd88fb8"): true, + common.HexToHash("0x5fdfb3f90db2e212e81077b620b861d702891a9afbfb272f7ab425f6430afd24"): true, + common.HexToHash("0x89b41b19f37ac3923f93f434a30a9240bdbcbbc997edf49c214a25d5d1c7800f"): true, + common.HexToHash("0x1a53074eb5f0e2bac118b92c791d89b7dc649861deb9b033f717e52bb8936c87"): true, + common.HexToHash("0xd63ef31cd78eae104fa56c830157ea3c2408fa7357e96fcf764ecd5aa26c4dd0"): true, + common.HexToHash("0xf717d26b3a510f5de4258b3c95655adbe49cdf0219c1977a37b8bcaeb60b3672"): true, + common.HexToHash("0x1e478ca5c55c40a6caf75f5b062f14e1ca7cdfb6b6213aba764e84b431ba0028"): true, + common.HexToHash("0xb8facaef281f0ed2ff4c72cb2916d5c783fd694dc9689d132e76596b2129b7b1"): true, + common.HexToHash("0xccd00d403a562323e864b432ddef3545c9095c59a45ba62cac0bcfad4d0ec937"): true, + common.HexToHash("0x306dc65872e72bb8134419ef49bc9a0afda37a90adfc81d86b89cddd95af57bf"): true, + common.HexToHash("0xe08689e057f615b8fc8e74c94f8e1945f136a0bba2eb7e0c8e090eac05083d6b"): true, + common.HexToHash("0xef639001b1d34ab26600443c81c81eb7c394404cb40524e40488346746ffc854"): true, + common.HexToHash("0x842e86a6b516e9bc59a71a7512327c1139aabcab3f729db8bf7db3d8d1d41719"): true, + common.HexToHash("0x30202a04472ace4a37aa67118cf602d9907f3680d8f9ecd012566d3bf8052023"): true, + common.HexToHash("0x93e7608f0a71a3b09b30d5299103060db625ec824c1e0df6003148a4a42d3c5e"): true, + common.HexToHash("0x9a0da147dd9b48f7f59133e54fd42dde3d62f8c098a0938ce74a1eb65bf99ab6"): true, + common.HexToHash("0x3fffdb4d3faa289ccedad1a0037741107cf23cbccfc18cf9dc9fa27b265a6c4a"): true, + common.HexToHash("0x150ffeafd5dbc92c36098fca2259dae6751abcd7dd658fc1090a2d291568c818"): true, + common.HexToHash("0x92ac87084cbce9c20c1d09f929f5d71adcc53fe027ab0bdeb962a904d17a7074"): true, + common.HexToHash("0xe61339a8f06da279138607065d77031a11975b32688866726e9617e847421638"): true, + common.HexToHash("0x151f85464099f9d14f205554b61ef98090fd194e25272d47231c83d11df14a9d"): true, + common.HexToHash("0xc7de416e9d5b9f1c8e9cf22c5771653f9e18b281b1af71787ae9986a26f33540"): true, + common.HexToHash("0x2648da0bb76db713ad7086520b1eb61cbc9e79405c12b8819c04c51c3a796f6e"): true, + common.HexToHash("0xb6c8100ede0c4cbdcbe52ebfa312931c8da3c92e81e91bbe86f70c62edc84133"): true, + common.HexToHash("0x44b6272573515401d4f076b9524fedaa89835e518e7742492fca988112456745"): true, + common.HexToHash("0xf69a7983fe9915f4874566e313c454c61594882af7a9173ea78949bd24d72622"): true, + common.HexToHash("0xc4e6c74989cf430a0f4e076fa785b9ecbe833fbd4b422dfc838f86b759bf08d4"): true, + common.HexToHash("0x7077003691ef65d436f6feb3dd6c934890b3b1b73e16a6d4faadfe22ddb22820"): true, + common.HexToHash("0xc946ee015438b1895afa507fc50557f71d762cd6326d639fc08cf3fc53d46f47"): true, + common.HexToHash("0x9f66854d5a743b416ee4760d8301ee778702f983964c541a0a724cdfcd87732e"): true, + common.HexToHash("0xd3d3f00f5e1f7f961d47b20d5f068835f8da04be1cbac281a41b166247c10034"): true, + common.HexToHash("0xc65d6daeece779db49aa82c99ca6e60042b10c187a2ca1fb5fd194c7a5d29149"): true, + common.HexToHash("0xd91be64ac2eb69ba9e4c90658e02a200b4f03197a4e66436a3a3e08973f779b2"): true, + common.HexToHash("0x92bb0b370302aa25f886e99829e6fc33e5ede1b62b71a3ae41c341063adec83d"): true, + common.HexToHash("0x073bb8e6102048135e2754be927f2a8401e9f3ffbdec53aad9e3677c52e46cfc"): true, + common.HexToHash("0x5764e8883e9f52fc956cc54dc4146debbdf7d63099c53ca7d977a8bb5370ddd6"): true, + common.HexToHash("0xef2e939983f498047c97c8d0bff870903f7713004a8a6d6a40cd8ff50056feaf"): true, + common.HexToHash("0x58794efc861ec80afb294abb9193891be032d9b7496f22ea4c8b5b3e039ad599"): true, + common.HexToHash("0x0b3334da0ecdec3fd1a77e31ebe5bac21f3fbe21442f99de16f74ea3c7ba5cf7"): true, + common.HexToHash("0x3dd44a678d4e046c150a8a731ea0d304cd6684f7e8c4addc337811c3a0a8cfe8"): true, + common.HexToHash("0x03db02ec6fd4d484005230d68e30aea803aedb403c34e2470b4092bcea4e5313"): true, + common.HexToHash("0x4e578a12abe34e3e3661175c4e2e514109bfd8034ee86ace361b48257c41e5c3"): true, + common.HexToHash("0xf1ac04338c935de3355b24ff0b1dbf93e477e03faa7072d76318357c06f37941"): true, + common.HexToHash("0xe04a7e38206b2b6ff18dd06a42ba741e1e3634fa68db1becb9e48fcc6c9b9b33"): true, + common.HexToHash("0x6eb0c11629c5bcd158af318b5f35acd2eaca52b66dbbc99b138b86befa8c8c0c"): true, + common.HexToHash("0xe4f0fd808ea9139ed06bfcc24332c53e64a9425c16c8b73e5dc7b3a11fd12a65"): true, + common.HexToHash("0x1b48d3ce97a9d0b780d8d7a7648020906e7e10424f43a2072d83504bdb744b90"): true, + common.HexToHash("0x17fab8ef549e7b060bb504e00748a9ced28c22dea71ee0db67b6f304b0b2c689"): true, + common.HexToHash("0xf6bc04dc4dbf1440a6751e33cd52cdb1ca210991f731cabd826970ee48a264f8"): true, + common.HexToHash("0xb88e48627fc28c701fcfbee5f6fcda1ef89d9a80080d88a4d59959f18887a7c7"): true, + common.HexToHash("0x7b80e52b92508b5cf1d13a2637c0a5d982622183f985b2a8fdfa8e0f010a07b6"): true, + common.HexToHash("0x2969c9046da80af58cc8965a952dcf04ab5e4ddab997381215c9f7a9594fc047"): true, + common.HexToHash("0x2a056f66f98eef5884dc2a470764eed8d86d2b0582149b2eb2f1a6541d1e8780"): true, + common.HexToHash("0x1d272b62b65364c3a3fbad0ba49c1caec0f31fe1f3630d1b80193e6532ed5661"): true, + common.HexToHash("0x796c68c8aba3e78137917ac64438f0cc54fc3c0b89a3c81327857cb5a5f4c7ba"): true, + common.HexToHash("0xd6b23667a2856527edfe518f63a16cd8bd8709604f3ed0523dfed3853158c828"): true, + common.HexToHash("0xf17b49b984b537c109392d43ba7faef73baa6b0bcedf45c8d1795fa9d3fe07d5"): true, + common.HexToHash("0x39444ec8daf4af5b4c7f0b18c83396acff8fb8711cac1d49e5006c07de39fd51"): true, + common.HexToHash("0x02c65cc36f6e323baf4528b00448bec32956f8d9c3ce51465962067b81040d33"): true, + common.HexToHash("0x92951d1db7bcfee4668cc08a6ae61c9b516c1b8f782e547df6d61b04fc0c6d83"): true, + common.HexToHash("0x34e600b73b906bc8b6087394fe268e35633c0e08f3f095f399d06eeae84c28ec"): true, + common.HexToHash("0xd2beaa67e368e0f3f1727e664cf74274ef9fa30bedf2cc3c38f965628f632ef0"): true, + common.HexToHash("0x28a7d439c37a7873d7385536344fc8cd839f3f14dad59c1bf32a1387dd32e35b"): true, + common.HexToHash("0x957c9f8e0e6feb2cf6dbee17cc6b95cde167f721d057f74574c2522163c21fa7"): true, + common.HexToHash("0xca162174d03b35bb8898bea38fba99eaf63658cb92fa4c045ae78c8d2f7d33db"): true, + common.HexToHash("0x8a59d3c41c7a85aa8641e9e014989fbe240800269055ed096dfa1098bf7ac1f2"): true, + common.HexToHash("0x21d6b19c3bf77065197d609fdf34ae7800deeabc4293d69052f074ee9a8bd6a9"): true, + common.HexToHash("0x04548da69e70b60df023e0644f0ca13021718de14359e9a8d4ca451c6d39fd98"): true, + common.HexToHash("0x0878fa0c5f7823183bc0ea30baeab1a096291dde2820870cabbe6a1fef1e379c"): true, + common.HexToHash("0x0ca99e8645a6e51eaf9aab9ef2bb4291de94e66c15023d7ba039318b1e2213d9"): true, + common.HexToHash("0xa291efe01977313a4a70ce50cb831f5b57f370681dd575b15213d0e93fae9738"): true, + common.HexToHash("0x5c24694c35c553aea6f7d7ebe071c789f22f634058ba5ea3db205a0c0f1932bd"): true, + common.HexToHash("0x8683b2ac286e3e962b63864fc807cf2e6f8eb6c0ed5d7b97bf15cf5d70d2afae"): true, + common.HexToHash("0xf89b66d4c8410ec907c9f558e821333780747f7f03581329c6c5ee2214a42c03"): true, + common.HexToHash("0xd1bf38b63028544e2444b837936a61605ced02ac6f147cb265724aa8560bab19"): true, + common.HexToHash("0xe99ef416b3afc4093bbbc5d12f56cce2f7a2af823c17784a0e550520dff2e0c5"): true, + common.HexToHash("0xe703a92dd44f70140dbabb19e623f75ce62ccbb6ba0a7846d3d40046727b3c1e"): true, + common.HexToHash("0x44905f9f856212bf6dad4060a6d9d081ebdd4911c207a0cc74626ea66bdfe186"): true, + common.HexToHash("0x1a11213fffbcec1701f867f2ab52833628ba2601216e7bca755d4296e9b7ccec"): true, + common.HexToHash("0x4c6c1cb38559b82c4a898fd3524ae7baa53d0f5eb9fb5f59ea94f8fb044a886b"): true, + common.HexToHash("0xb1d209bb9b739a9748744c10f3532735365864c139d74cbf10ddcaee6c15b8fe"): true, + common.HexToHash("0x798e72a48653cb6907577bc9b812f8a88655fbb640106d7217e0372a22afa5a2"): true, + common.HexToHash("0xdc421fda5b73239b44d59091244e47876d448110e43bc152b53a80460e63861c"): true, + common.HexToHash("0x788e96a90fd0f3d2b83345903bf896b2fe4536516965da43a350254107189c30"): true, + common.HexToHash("0xff9193e448f8fc6ddd4029ce13d100237ea337d01a223beb2fabff65596ae83b"): true, + common.HexToHash("0x4cec7dcc6137fccd01fa5426e3ed14aa72b822ce6d9244b6226174d2c33b9810"): true, + common.HexToHash("0x54b9a2cd49e6adc6e6a93e7010d320778e5e5297b2f244054b45f326bb8bd780"): true, + common.HexToHash("0x085faaaf102818381b5bfe357d6e606326a112045fda627935df16dadaacdc6d"): true, + common.HexToHash("0x7431d9681e585733287bf0c1a86d75381a7112221fb37b365d46b6068619fbe2"): true, + common.HexToHash("0x22b186e450ec1b67b43d5a45b310327ce7cb24921617b36755426ffd26afc9a7"): true, + common.HexToHash("0xe50a18fbdcc7a143a8410162132b0a3ad9b5b9c2648e013c5f9f003f0b8e5023"): true, + common.HexToHash("0x436709e9a90f43ec0cff7e400177614b0eb59c52bcd9a2deb38e7bd958b0e0a6"): true, + common.HexToHash("0xdbfa65aaf9166af249adf7d6d55017483e24167f27cc2182006aff45f91701c3"): true, + common.HexToHash("0x0ca34c59ef2476943a37ec2d20df5bbafa7160787eef063462acfe4a04e513fb"): true, + common.HexToHash("0xe16f5ef6313b02e6fe25d9b3dbadc46470193442f2cf4e6a195ed6035d8b7623"): true, + common.HexToHash("0x5c96014758c3cda6a615ae8221cd83653f75695da22e0d2ed455b8f2e6eb9228"): true, + common.HexToHash("0xc45974d35421281b21cd36cbe1e451da7a5a224a05448c1c6dc28c84ab37e73b"): true, + common.HexToHash("0x2adc4390061c8dd4712d54d00923ba7ccad8b39fb384ade8847b732a4081357b"): true, + common.HexToHash("0xc3cbe095cdb43d46255920f68699080f5feb3fcdcb4d1311ea7c33439f713968"): true, + common.HexToHash("0x91d812199790398cd05c23d38bb7e2e766346e40f3ad159845c3b7591e3e2089"): true, + common.HexToHash("0xd1bc6d731966ee26d98482340fd0b2ea86e1b9816a2599c788e13fdf2d041b05"): true, + common.HexToHash("0x454dea0c7bad58d390b06583e5db000bc384ec7c27254c865375db4907d1aa47"): true, + common.HexToHash("0xe90065d0cfdb7901de728aa1bee51e7dd7ec69f8d06a1f5f1633b376b2c1cfdf"): true, + common.HexToHash("0xb176ea1c0b2d4c810686a82f30428730c4952350ed2f73bb7cb9c5aa61779f06"): true, + common.HexToHash("0x1db88b6e45f734955345c6a9cd8f19af27ec1ffd9ebeeadd18664ee429c0e56e"): true, + common.HexToHash("0xa15334234c741d908ea17e628a196acf06eb08a5491d81572c01fb8432e5c74c"): true, + common.HexToHash("0x6d781cc4eada367c089ebeed7a1b7a05d4684eb17c333724bfe63732cf02270e"): true, + common.HexToHash("0xba076f04a9f499d73abb3674d61b51261d541751c296269a2f25c7c7b3193f83"): true, + common.HexToHash("0x00a623160da81992cffca530defcb27887f78022aae9aca70552197c2698499b"): true, + common.HexToHash("0xc36d506cb3b8089506ae181f73b884ff3f65c0fdd53948f6bebd1f39ee10c476"): true, + common.HexToHash("0x98454db71ebc723d10cbfbe78d14edea5e797833e3c0613b6a8f02721cd519f0"): true, + common.HexToHash("0xe5dc1ff71c54630b680719e8b8b328049b8820bb99758e23a9a91b70ad27cb95"): true, + common.HexToHash("0xa8d0fe8bbbae33d830fec7ecbbb4841e36d4a2ce992549b58decc38f4f22abb3"): true, + common.HexToHash("0xb8a0d8275296cf8c3c79fd093d6bef813e6fa7ba6333308a2c19582ae9121f9b"): true, + common.HexToHash("0x0ccb478ad69766e54ed2c704b58dc7a204db269288ae8fabf21a3f65581375c4"): true, + common.HexToHash("0x3b9f54fbe660b232671fce7412b7cb89e6bedb50ec0c81c54338e43503c4c445"): true, + common.HexToHash("0x3a5d91cfaddc722e33a64cacb95d958b942aa88fb7c8ef4631c07c20efaf461a"): true, + common.HexToHash("0xfb31246c205ba747ca804992a9cab3587c2bb406ca34b3c0279f46f9a9487d4a"): true, + common.HexToHash("0x0c7cd1aab4bdc1e5bc770bbf3ac5208cc19e40bf83fa84d3b392baf06a7fd4a8"): true, + common.HexToHash("0x7e330ef9599521f0faa6d7363aea6515bebc25a473031d414ce4f17c4e1a4c53"): true, + common.HexToHash("0x2d719d50d914c379dcc1881897ea8097114cfb83588968307635b6234edb7b89"): true, + common.HexToHash("0x076ec78d03babac8270d1527f757ac7531504f726e435de48616598a38932473"): true, + common.HexToHash("0xf0bb8d4032102b02f79fcf90f0746093396d21584a38901f6ed3bf638f256fc0"): true, + common.HexToHash("0x967d8dbde99f15e1c34146688de3b982624d7a8729b3dd34c5e38bcf79cf94ce"): true, + common.HexToHash("0x96802bca9127c3a8385dc8925390933611cb541654e8a2234c0ac92a4c21cba6"): true, + common.HexToHash("0xc88e4078ef3833c13eef2703da3559182d4ae37496678b1dd4ad6f1d142ae900"): true, + common.HexToHash("0xbbc215bca5aaf024c6d103e34ad6046e0dcb95773fe3ccc95a030cc36615d997"): true, + common.HexToHash("0x095d7bd5caa38b56188c54ab33765e7240b974251610ccdefe583152a230652b"): true, + common.HexToHash("0x11e874a454e44beed3f9a8786658ec18358087a517978f4ef51879a0d413c5bd"): true, + common.HexToHash("0xd1c68d4e5728edaed9fac474b327f161685712c820132ce165fa5caea8682cd6"): true, + common.HexToHash("0xbd0bd7a2bfebece679b250e293ff7f4131b22c6385534ba1220dcb0f270369c8"): true, + common.HexToHash("0xabb88c573864c27e812859dd7b63bcfd5891d33a526f330fb60727bc744430e9"): true, + common.HexToHash("0xedc315d2461644de97188e9b9ecd56a7d20aa087faaf43322f02fb1059c7de64"): true, + common.HexToHash("0xf45c4c1b768fe1b85c926e255402dd3335a2c617e1bd8d86f138422826231715"): true, + common.HexToHash("0xd1a07b4be618951d139d1a0d96d6a44e1b51653470a5b6ed20a263af7632a31f"): true, + common.HexToHash("0xe682b93e5c4bb548fdcd0eddf9c06dab9a96f9f3db473b382f5448bd4fa3e775"): true, + common.HexToHash("0x0dfb1b2e157940ac241376877134762ab5eb686d9a1456ac8dee119be88530a1"): true, + common.HexToHash("0x0833a53974081905ee29e0f7095a14552f0092f9e054eaf5b06c7545d8894e28"): true, + common.HexToHash("0x43831a6537186c07cbd7ec47ed9b95d0207ad179fc7dcaf9997b952f8dd0fd8d"): true, + common.HexToHash("0x79b77e526136d46388a0d4b8cd91ee09d4ef4f0907c6ea9abdd7d5c5c46d3d74"): true, + common.HexToHash("0xd212801e265dc8e262fbd6aed30bcdb4b59a82fffc655e6243395419272df02f"): true, + common.HexToHash("0x25f95f03b420176e32699d6f6a7d872b3b8f470eaead9649e630fae173cb8a03"): true, + common.HexToHash("0x8cffded8bcca5cf9950f37049b5cb4b072be0cc25d7ad947f11fc38cbd014919"): true, + common.HexToHash("0x72ca87b0499fcb24b51052fc473c3c76521a0d3148c6f306000a6cf51758f6f2"): true, + common.HexToHash("0xc2434b698e1e4f5ac10dcded2a6834388aeb0eba13bb61ac2b19ce6c51e83a75"): true, + common.HexToHash("0xdc6bc29d28eb263d1fb156dcc2080a8462c53bf522a06aa8032e02458b45b118"): true, + common.HexToHash("0x62cc4324483a5434014649c4d1f4559231e0a718eca71e04ee0db9073d5ffa53"): true, + common.HexToHash("0xb10cc3bcbd5310442d58622c68c27845e1992df05538a612e11e07f73edc4c9b"): true, + common.HexToHash("0xd5fbbcf8c7c9d039bcdde194afe9d59caa4e7283d641f65e266c2432f7b5cdf7"): true, + common.HexToHash("0x47e9cb92bf636f53faa003a3cb0764f51600fd97d84119ceff608b6fac8aa5be"): true, + common.HexToHash("0xbf89c4871af333dc19aba880258c0a64786d41e0466c4aef31f92214760d3ee2"): true, + common.HexToHash("0x6e3a701632a58b04d21119f4be6d50d1548b903ef2d63f84efb66dcb8b140f4b"): true, + common.HexToHash("0x21fd0a8d2c5a2959840a9ae4b73158943fe30579d2e5ad3290b86b623a7ffff1"): true, + common.HexToHash("0xdc4dc26deddee03116dff2e9ef4fb07f6371a27df7163a731be75b91a4c84806"): true, + common.HexToHash("0x1c5aefa23d22aa128157f3fbbbe8b7b73c59dcd8636e5f7c2bfc59e02b357bf9"): true, + common.HexToHash("0xae68bfc66fbad1bbeaaf08f179ab889a95fdafc40a230fa5489fb9ef2ccd3cdb"): true, + common.HexToHash("0x25fa3bb603c792d3cc48ce2c70560d1e90e1a527253f170672140ae7909f358f"): true, + common.HexToHash("0xcb4f8d58ae74e684568cdddadfdccac68a854274210bc212349514755abefb74"): true, + common.HexToHash("0xa0695bf540872bb0c8c007ef5da7acd6032637964435005518565a0c9dd07bab"): true, + common.HexToHash("0xeb1f24c10d3d6cd324472c1e56b6b28bc17e781cd419a0f3162a6f84d4be77d3"): true, + common.HexToHash("0x060945291571bc074e6f4efc1b1fddd16e0d8d812fd3cded59bc91073f51a3f8"): true, + common.HexToHash("0x5ef4920e76e25a67784e9e2600164c5ff44edb91a0eacae13455c795b8f74d71"): true, + common.HexToHash("0x00122f6f5341104d896bd660aef65d6337b325483bd706c15e4207126cb82485"): true, + common.HexToHash("0x3915b3d8e790bd088d67125d4cb23024b806a7867b9f55b7ccaa67886cfd803b"): true, + common.HexToHash("0x73721e18fbab5860f00020c5f680663bbf9f778885e13c19acb21e5bd3952473"): true, + common.HexToHash("0x39558c83b3f5c66279d849836c666d5d089dd0b37100ca6aeef17f4d5542abe9"): true, + common.HexToHash("0x2af18ef6c44b158d14b560b63cc310da3a674289bd6debd05398d41644e6eb86"): true, + common.HexToHash("0xafd797a5b0e3a5b5608240a29506eb3ea6b3146441fc8539ac81c5b8753a3505"): true, + common.HexToHash("0xf65c44d2f6f09a5f5841be6b8e64dc6e1492224474868058031931929d41636d"): true, + common.HexToHash("0x70b5f8c4f101ee617beecd945911ac87379636a9b2427a2ac3723d67370297a9"): true, + common.HexToHash("0x200254a13c497ddb3b89e86ad4827711d8ccd7c71d548794aab927ae49197ab4"): true, + common.HexToHash("0xdfd39e681fc87d6458ff05336c4be5a0e10b90be9a971a2629b118fc20d5bacf"): true, + common.HexToHash("0xcc3c6441154c414ecbde42c252e4d9afc09a14b463640feb9adbd2bc6815f445"): true, + common.HexToHash("0x46b6f7451de09b82bf04a21c3f0996c4142612ae27817e44af775edd6a253f06"): true, + common.HexToHash("0x9a93641192e10971f8d3fabf3ac73e0d95630f92b84b1b31b7fc57585133d15c"): true, + common.HexToHash("0x33d411707316d2a619531b1e45ce63a337ed320c69d5807158066cd69ff9dc32"): true, + common.HexToHash("0xf65b22453e86b525d2612c61396690a65e43ee5dbd253307cb819c6f4fdb71ad"): true, + common.HexToHash("0x40119de6b12f8227ca26127859710370959812188f1207ea37faf42fa508cdd7"): true, + common.HexToHash("0xc0ed6353138adccf1b81cb81d43f4a0fb523d6b17a755f295b7837a6be479aaf"): true, + common.HexToHash("0x70e60ceb5e5825461e7eaa5440c35c78a9e53d8d4ad15fe0c2cd002577a7376e"): true, + common.HexToHash("0xe57677e83f725bab2f03410e6bc0583e0c0c7a4fae0d7b813e38d625f1f1e0be"): true, + common.HexToHash("0x3e4d7598f9f95df38747062b58bd4c81f9726d5c1294cfffcc684c51091b8e47"): true, + common.HexToHash("0xad9f8c3025cbb3399c359ce102b4607539932488369273a816c26fe68f9955ca"): true, + common.HexToHash("0x8e530cb1eedd7b88b74c649692e5c7a6fcd0e0ad378a3234b4552479f08ab7b0"): true, + common.HexToHash("0x30191b654f7f29389d913e212ff90da6d10a93ab4da105827c1fc868ff3f5f7a"): true, + common.HexToHash("0xd5b6c141477bd10999d9888c046f3ee9589bccb06e4411af794ea65a21685f58"): true, + common.HexToHash("0x393705edd64b2ccfa7b7f2265325a944a8030a25f7a6fa4418daf13a529862f3"): true, + common.HexToHash("0x093e7feb79b54f883ef4dc89d935c621dd2a79335492bf2bc48eb12addbd66e1"): true, + common.HexToHash("0x21fe15393dde06204d1c3f3f32073c8a6321237e9f9d8b80fc094bddd7a2f94b"): true, + common.HexToHash("0x9fd7f7c6518763722eef5e7dd0c0af51a3fbab9484a86a526f6345cfe75de3f6"): true, + common.HexToHash("0xd163cc145cfc4d38582b48a13951b67ff1a1b7752f4bd3a5bb21862ce5b10b7f"): true, + common.HexToHash("0xb95136ff709f07afb2b11bfb1ff1f427b82188970b94dad8d8f2dbcb3c8f3eb2"): true, + common.HexToHash("0xdb3ffdabeab40bc3c7b41669a834e0cb04ea0d052795d57a28628f5ead96cd24"): true, + common.HexToHash("0x4580f596ec525362103e1d62869740cf971dfcb38f0a3954d4aae87fc3a6d28e"): true, + common.HexToHash("0x1e4e0478e1faa2d28a98775eb8bd1b20a3d38fb19d3bf5519ed39ce6228ebb7c"): true, + common.HexToHash("0xa24336196467c0f45583b107f4a0fe7719d8b433d593fa428671bc2199318401"): true, + common.HexToHash("0xe713e8138728ed45de3cd54c0498067123ae48a84da7efe4001cd486f843e3d6"): true, + common.HexToHash("0xce6d8e487cafcc53e49bbf2f60e0c24c5ac2f408a9df17ddd08fb8483fecce55"): true, + common.HexToHash("0x6f2870851eeb6fff3ef486b803bec6241894ba594b22296655780f41dedd2a58"): true, + common.HexToHash("0x97a1f1030abec15b4761c7bd7db282426d7ca0d150558a16ee310f168d75c3fd"): true, + common.HexToHash("0x9fc8e65a769e94ae43d3aeb56775ce99a2923c8be273582c5429a26754e6825e"): true, + common.HexToHash("0xcb9f6b35dbc3be113c348842a9ecf4269a04b949a54a5db3512197ce7c831b1e"): true, + common.HexToHash("0x49393f4c29660e6a49093851c08fb1b6394279687108642b56a186feb5629360"): true, + common.HexToHash("0x14833f87df25c9c13c1e817dd4c895b3746518a0f4aba0e12b108c2990084591"): true, + common.HexToHash("0xbc7e93c4d4e988b7f88ace69046f9b0666009c40fc5fcfea023b25e0dd79daab"): true, + common.HexToHash("0x483f5e206ca3db0a5e7eb39ec03687c05c6ab4b18d2e8a5fe63c6c680903c824"): true, + common.HexToHash("0x04c18ac3f2594ebedbc8869b6e5c824555055f15685274921e364f73ed9c8b23"): true, + common.HexToHash("0xe3ec9ba7dddc48a992cd1736f3005ab407406dcb265bfcd72f1d5c6e5e4972b7"): true, + common.HexToHash("0xd8d9009becf45caad0ed5a790f8e04f6a0469f0323d703a3e3af342975d904b7"): true, + common.HexToHash("0x51ff3bc6c5d19ed3906d57a8f61f25b438fff10188f2212610b90e5cbb544f3e"): true, + common.HexToHash("0x1d8b84f9df785f912ec77430a89c998b570a7388450f3889afeb8d7760daa746"): true, + common.HexToHash("0x6bc7b1d740fb294f76aa31381462236736863d4dddfb96407f02aceb8b843b55"): true, + common.HexToHash("0xe01a4db92dff886c73aae6cca2334a7f9cc96ab26347733c358d5cd70ea3305d"): true, + common.HexToHash("0xb331bfb66be35da9f602a3dc89e9c81529f4b246173fc45bb86864b2ef7bc268"): true, + common.HexToHash("0x40cfeb1f30119fe93dfce03a4c0476745a54858c0f9a527a3baec8cd5cb27593"): true, + common.HexToHash("0xd81a740d65e36f2cc93f9e1afd9c7a6021cf99eb6fbf63305e7c62abcf75b768"): true, + common.HexToHash("0xb02dfbcaa95bd4b6957c6b9910e33b93a92c868d7318e113513fc29714c3c5ba"): true, + common.HexToHash("0x6c6a7add24b3d64f4f04b74ac23aebe618652ee8227110aad3aaa2bf5945588a"): true, + common.HexToHash("0xc1c2e8a0d7ed6b1eca3eda0a8d373aff825a5e1497e46f1cc750b1bee41a49b5"): true, + common.HexToHash("0x5b4a69369aeba7f36aa59bac6f03824f1c162184f8e94668314892592d861d0d"): true, + common.HexToHash("0x8c0b8b1b2d3444ef76a0a1d333148b2af7a42adec2b8a306b4be73efdc33d0ba"): true, + common.HexToHash("0x1fd5368890b9856a80a6e657aa4b09cbc58fe2a354d97dfb086fb5fb943765e7"): true, + common.HexToHash("0x8563e6afc8441ba7bdd1af0ad28318cba214612398de77d9e71afa6799fabe99"): true, + common.HexToHash("0x44f578e495905447ec97caf00f3d930eb85ea2336e29dda0d8a50b84bbcaf6e9"): true, + common.HexToHash("0x199684f636b961519d8397861553fdc9afc94495f932a84b6066006346b854f0"): true, + common.HexToHash("0x518b06991c42872d29c7e32732577ee868b041d4e1b0f5897781f95ef51c3662"): true, + common.HexToHash("0x62024a16ab85f5f34a6e2fc700175c29bd653983e466d2a4bdb59a22c4fc6d14"): true, + common.HexToHash("0xb1eb04bea9ed0a461572e129cf58affe3787109279053f2b996cfd4f3a8a3f1d"): true, + common.HexToHash("0xccbdb5949a8f007582cf1e90f5b6597215dc3180b13b7e9848c8bf7993c29a73"): true, + common.HexToHash("0x8c7c6e7732abc68763d4e6f8bc7c5643679f775e66d05b9b0174af2930dc9e30"): true, + common.HexToHash("0x6f58979ddcb923773314b9b00c90927e096901847e87c935a567ff7af205bb7f"): true, + common.HexToHash("0xa613192d74b5ef38cd9ab813ecdb1cbedd777d94caeb5c4400a7d3544db9ce60"): true, + common.HexToHash("0xd300c5d8d2c958f765ce622147ca1ad4382874606369687b34fed9f09a515511"): true, + common.HexToHash("0xce7dbdc9c33025112e733b710d10600090f9803bfd97f291bd77bec9754f399c"): true, + common.HexToHash("0xad1193fab31774fa55720edd6430cb16dd2c4daacdf3d32ff7e24edc86620217"): true, + common.HexToHash("0x5f5b702eb7e85ff2cfa1ca5e02c11b265870f666e7454d701b3b945e6d929830"): true, + common.HexToHash("0xf629e85d25ebb98b51a23b43c19d96c14953bc2454d8fdaceb25d3061a452080"): true, + common.HexToHash("0x2795447e4d3b085272ea6111075129ba3b87d45bb07620ffbdda22d46ffa6024"): true, + common.HexToHash("0x1b3bd186bebaa04fb9b0cc262697f8fd442f57f843b7af8390e3403ca10b9aa6"): true, + common.HexToHash("0x0006b9598bfa0c251323729ed2bbf61402441ab7762424a5f2be56d426ee613d"): true, + common.HexToHash("0x526e3f53bf140d56f38aad9c1187627525b470573a4535b7972ecc7487c7a60b"): true, + common.HexToHash("0xed58734462e45745bceb11c71ca1db8782f7cb8ce137a0a076e7a68bcf5f2c19"): true, + common.HexToHash("0x7f24dc67f5a9ab97d5758e54c98df1e62d6871ee72370755fd226314998c0f22"): true, + common.HexToHash("0xa7b23400be5de26ad8662ab50b6f51b77558d7c90e3fbbfaf94f611ac33a71dc"): true, + common.HexToHash("0x63e7323e2458c5058133502ea8a152272326f8aff0efcfa8316020147896c966"): true, + common.HexToHash("0x3eef9bae260c040574cf31c396130b22ae00582273daedd4c8989c0287d493ed"): true, + common.HexToHash("0x6b4d42dab550e28a4741260a39b6ae1e9f751d82d53f4ce4deba9ae2230a8bd1"): true, + common.HexToHash("0x71fa668821b2ac5f95181612620e71cb9f78b4402b24abbb1fe758e740fb6e5a"): true, + common.HexToHash("0x4af60a5d5e6f457c3cbbb4001c4f37fc91978e1f7c3f1a579740cb9f6d6f7f43"): true, + common.HexToHash("0x09dff8f373483c66564910dca210ae36e2ef04ff381a433a8dfd2e6655696626"): true, + common.HexToHash("0xc4f0f2cd977e3bfe441854e2c927f1db6d2b918bb3002e49d8e5908272da9a2f"): true, + common.HexToHash("0x011df9fd961f0aa8c81e840eb9f1c2b96bc3fb3fca93b31e4e13dd39f8ecc340"): true, + common.HexToHash("0xe01ab0e286f1afc5527b62e7e37b0f9fe88a6fbb16b5282e9424bbdc3373ece8"): true, + common.HexToHash("0xed6863e185b46f18793321718c0df2538110b8663bb39edb02d07daca61ee94d"): true, + common.HexToHash("0x2a076a1721d45c07f9487f6d59bf0dd2beff941673cefd9ecf1fd6a54e058751"): true, + common.HexToHash("0xafa443f37d3bc8624c60d241d5b447070ad3a161597a5cb6309c41408722b719"): true, + common.HexToHash("0xebc11e229be5734d0426ef487ff466a540af38ef077436f4149354d6068048ae"): true, + common.HexToHash("0xb19043b2fefe9d9a4d1cda83d3e3945a2dd57d2bc757a969acddb2449120755c"): true, + common.HexToHash("0x6fe910139fe9737ded2bed64a8d8ad1427e3a6d53351bd2c68ce40cc0110a531"): true, + common.HexToHash("0xf32d73a5a07f6c40373b3dd0fdf1d7625c514fe5f54f43f40970d6b71228d233"): true, + common.HexToHash("0x6a906dda6d1a2b59d89f128f200015bb2fa4ca9f49686bb98fb31f3ce21121f5"): true, + common.HexToHash("0xacb9e33e6dbf67848ac674125321552616c6b542b3d7d15b3f3f62aacd0c24de"): true, + common.HexToHash("0x25f17bd45d5ba1c6c36aec502590fe2dbdbf16325ab22581ed62c8f62a6d1ffd"): true, + common.HexToHash("0x1024ea7e77f59e6b0687ad8ac3fac3763a5e7c53df74dbe278b9f84f5c30fc03"): true, + common.HexToHash("0xaab29f86565bcb4a5d9f770990d05d26363af6fe3497cfe6fe426745dd34926d"): true, + common.HexToHash("0xefbe805a36e86e632321161e63f7150ac4e32b08a667ecda089579607f33b4fc"): true, + common.HexToHash("0x734a8edfe7470b4b62fcab3cc95496b0ce0d5c0d7565ece45a565a214681a052"): true, + common.HexToHash("0x4d05ac3560d01953a16d790f71d33091b55f0330f449a3e8f2dd00abbd6c441b"): true, + common.HexToHash("0x2c5f3206049500fae6f0022217255ee956051ad3cfe627cf4fae643278fb4306"): true, + common.HexToHash("0xcb638a4be5ecf4179aa1cc3544b65b7b93af684b825ec0099d86631790df1930"): true, + common.HexToHash("0xfac77d74419eaed639ab283f3e700c6392582c50d8c66a87632b5c4542f31eee"): true, + common.HexToHash("0xad7178bfe5d0020af9c5fa0d8cb714d53dde74c3fd60a69193b684940ddf25f0"): true, + common.HexToHash("0x0b3c93fbb4b81e749f057ae648734e38a779f5c576055960b5c9844b86ec60eb"): true, + common.HexToHash("0x63afcb1400561125bcd7fff3904c451b0c33f555a9fef47332768b1adb23ac0a"): true, + common.HexToHash("0x7322a70056904102cbaf83cc2094eb900de14ec2db0e9a3988c6b2e22f82cc78"): true, + common.HexToHash("0x7bd27a5debdea0a622a967cf5388a927ab6eac6258829d0469da8625a119aa97"): true, + common.HexToHash("0xf44bfe2d869f6f47cfc3369333688124787131cc7e7e8c8fde1ca784914583b8"): true, + common.HexToHash("0x680b0cfde5b67686507d4d6d4dc7a1a3bcafa5cbecc5ac8ee15d4ab14dc2b247"): true, + common.HexToHash("0x6caf37fddc5d7d7479bbb9d12762fa6b18d45aed3c0ba569778f4549c2165cdf"): true, + common.HexToHash("0x688155b8af79cd592a8fab9d8db79eea1b93c673920c3c6b31b6930b7dd63ce3"): true, + common.HexToHash("0x0212bec5087fb4ed5c861631eb528f5cd9f452bc9e14e946d8534a8d2e727cc6"): true, + common.HexToHash("0x4d3ef9bb6faee4b805434161419e7e410f5f1d0de10775093ebc681cb7085082"): true, + common.HexToHash("0xc3466a9c3e181c0e213ffd04fe8fb3a14615e4777890b9e38ebbc6a2bb16d4c2"): true, + common.HexToHash("0xa48f96d1c962e0f5edda672812293521bbcc0ffdb5d2d36dd351080ad616a9d6"): true, + common.HexToHash("0x96380782c0f47854d67fa10278d32c3c4d9f6855cadd7106553e60ba5b6ff6bb"): true, + common.HexToHash("0xf86cc099c4e7a1d61b36372eeb4ac04e74a80773ae15e55833716e27e35383fd"): true, + common.HexToHash("0xb4c4ae557ac06f42f7ce8ae1f7998bc3c7db4b08d1e7661b624a7e3b0fff0533"): true, + common.HexToHash("0x5dfb8b5dc466ffc8f0aaca74647c8166914a5459d872c3db6a80a77627820b2c"): true, + common.HexToHash("0xcc142c10670be24096b13a699de0d914e1a3c0c515ccc49f9f37816e455a4033"): true, + common.HexToHash("0x14cb9d3f699ad39a937f46a5c7b1fcbddb4e09fd1452e6701389fc3dd91f3828"): true, + common.HexToHash("0x5e664599d4f1859205c5cd7486e15455dfabf774445e2b47b87ea7f6fa38827f"): true, + common.HexToHash("0x5538fb4a4690b01064063f69b532b3a59913a891b5a6643ad373b7b8e34faca6"): true, + common.HexToHash("0x5d33427f81166cdebb8c2ed4bd4f934b05a069454167e0b5623c9676810dd2f9"): true, + common.HexToHash("0x1ca3ade542b05360ee6659a0992fc2903ac1ccdee28c8c262c636d1f81816787"): true, + common.HexToHash("0xd0fe1f276a23d8878b2bc2ab76235f53f7c2c1b1c0e2c0a09a756615b65074b1"): true, + common.HexToHash("0x24abea18b8b6ab32a3463772952c34f908d5289af54190084c415b58d74e1697"): true, + common.HexToHash("0x07e533c5cb847e3cea11f0a3b7a0da8431b4e2768d822cf2d4d6dee79e05f79d"): true, + common.HexToHash("0x6809e0fdc42c79c56939247a5b8b2905de28d33b7a99e83e177c9ee471b528f2"): true, + common.HexToHash("0x9dda1948fb6c210ad6d61b4e6bd79cd87592fb11d035ab55f144742cc15c6173"): true, + common.HexToHash("0x988192b6d9f43261a55bad1a1d49b419817fa08d757601a0c8e2d42995eddaf1"): true, + common.HexToHash("0x56968b20ed7711bff34222b755c8c125ade7c4f6437d01928a426e364e57cc8f"): true, + common.HexToHash("0xd0b4a2a51194a40dbe41c7aeeb730eb19bc4d0183862a8c2197a7f277bb4f69f"): true, + common.HexToHash("0x457701312e7c92143f4699f98641a3756dcb599415ddd14f2a86054be4865c11"): true, + common.HexToHash("0x2a1ff68720a6909f54f3457750777b2446cbd4bce7e1e8545e89a2e11296a90f"): true, + common.HexToHash("0x6eabde49032b9adf24b862c14076521618a4cc89a928d113bb910b88cf20a11d"): true, + common.HexToHash("0x2c0b8db406a504271097f26681a3930355104a071e4b603b59607242548811dc"): true, + common.HexToHash("0x52cf5b5cb0113d94ef47670a92fb079051dd573311bae7af7147d52bceb3b0c5"): true, + common.HexToHash("0x65cbef246124076951e64cc5e4052c65fc7c77576da3074e34ff0ebd7acb37b1"): true, + common.HexToHash("0xaf5f8b307fc7127cf0cbbcbff49b63ae59a324b58a89f67a910c75b2d3435ee8"): true, + common.HexToHash("0xd2a9dc42856a5672147626dd27dd19fcd8e0ba5fe72b564b8bbc5326d5fc2a2c"): true, + common.HexToHash("0x9460720efc37120c8de2ea80933d0fc71872a61861bd85bff050d586cf54a9ed"): true, + common.HexToHash("0xcfecc6b7b97f6b4bd460cdfccb59e4b7b6b58b193772dff9e85625554ab201be"): true, + common.HexToHash("0xad455ed8558af13f7a499648f01a387211429899eae15dd104a905145f9d1a1f"): true, + common.HexToHash("0x3535d6b32aef9169dbe51742b5d9017f47db85ae432f9e6e4e41f4517634d736"): true, + common.HexToHash("0x63a02025a6a6fcef72b66d3318ef2d7079a8b5635d5a2fe14dfe8b903cf65b5e"): true, + common.HexToHash("0x2fa3746c1147125b42e1a25a0496065eac097efc4bdb27edcbc3e1bccdac8462"): true, + common.HexToHash("0x7172400c519ac808cc689651d5b1fe77d30243987694fba9843ba08f85d6ad11"): true, + common.HexToHash("0xea64ff90d2b1e5dbb57787c6fab1c0b594e5e32ea27339da006585c75c2b4357"): true, + common.HexToHash("0xec723c77adc6ad8f13a77ee48646ac311550ded28b2c4ce6cba15b839d798ee6"): true, + common.HexToHash("0x4a71e7bdd45f6de7686f707f4e7e296e63c46e62cd660ee77c6684b69dbf803e"): true, + common.HexToHash("0x031c424bb1fabfeefd346d4968d340385fe91dff07dd77e595f5f762a195ab71"): true, + common.HexToHash("0x0977d11dc34626eaedd0424a0a0c186a04b3453e4bbc3e5aac81e9d3ea363d9c"): true, + common.HexToHash("0xa173b9e9bdd010d280da197f2aaa71604e8c9fe0ed02481f9c11b3cee6a22e9b"): true, + common.HexToHash("0x3b65a8df3d7f0ff287ebc531180975eea5cbc90b46229eb1e266d21fd207b27b"): true, + common.HexToHash("0x526e9fbd11ca1605d58164ecba1aff69b1419e6dc31297b12aaa00555c725772"): true, + common.HexToHash("0x4123eb9d0c826ac9e9d6de01a665be1f39d0885904d2554adf8cea8149394d42"): true, + common.HexToHash("0x02d4c7298afb1633cf3f30523374711385fc08541e9d1c7f6e8d049f25659d99"): true, + common.HexToHash("0xe9ea49ebc994be9ef11aad1d72e9899793818d963fdfc96363f9598db2a3a9e5"): true, + common.HexToHash("0xba8e276dede014519b6f4addcb0f9a6dcf5bfc8781ce59bd1b4c7facaab291e8"): true, + common.HexToHash("0xb50debf849b9932c304cecc0eed1d13dba6a55497ba5c7c81e1669d5995dc33b"): true, + common.HexToHash("0x52e7ec30ad36f9b59a1508eb38b1c5525b3ad1f93f9b1746b9b81354e9285a46"): true, + common.HexToHash("0x7c5aa1028fbf3dde52dea1b719777e6fff911fb65e1375e5dfbe2372b61297d9"): true, + common.HexToHash("0xa4e10c97e62419ae83d212cfd907261e077471835a305d5a026e2efd729197fb"): true, + common.HexToHash("0x77758e7f3587f884a988a9e845c224bd2b95f7f076e54c081505dc1874baf255"): true, + common.HexToHash("0x4d215bd36418dd5327789aa214f7accecd9b37f7f753c138649590e72fceb528"): true, + common.HexToHash("0x25ef61ccbf45f3e6da6d39518fc7a4869f688cafa37c310feab8a1babfd00a27"): true, + common.HexToHash("0x3919ccd0be7d68f05bcc48db6246d5acce85510e241554ed87ed046df93c55f7"): true, + common.HexToHash("0x337ab096bcd012cf5d8e0804e49c5a11cc0863a052ac341d7914c8f1821c4d31"): true, + common.HexToHash("0xc6c9e77fb4af50772a061f6095bcaf77ee9a362e35147e322b532b2d246c2a33"): true, + common.HexToHash("0xd1233a98aab494b019b703b4a040115784980999fa39d8663fa55673a5ab0f32"): true, + common.HexToHash("0xa6470da5da6f5e1bd43c778893e1d0844460766c93c0329a6baa24e736f62d24"): true, + common.HexToHash("0xbd7a7fa7876dff99b1fc8b0235201ca81f7b48ff7c0a85acd3dc8e54ebbc4f9d"): true, + common.HexToHash("0xf0654ff47a50f34d37d5c51c75dd217e2164b8ac403727692b65acf4b584688e"): true, + common.HexToHash("0xc57c33768d364696df06cc8d35913fac428c5c4ad44937fe210bb06f083e92ed"): true, + common.HexToHash("0x427e7593a7ec8b328fe5140ede3fcd8ff00219d2a26f93fc741674345b5043bd"): true, + common.HexToHash("0x06b9ba1ddf6b6170971b8d31da81831aecf3c9de4451c0d643096fb4a07d2c91"): true, + common.HexToHash("0x6280f6ad07ccb000464daa55acd02f77fbc53aa1e1600d816c15f9263b9689da"): true, + common.HexToHash("0x7c2f2bdd71ca78db0bd17d4629f05dc20ac6a40b42cda6e2d348b0310f61e3df"): true, + common.HexToHash("0x59ef1b508e71bcb5548c90d0c70492cc7504a919081141974f02a9177511dc23"): true, + common.HexToHash("0x97c1c20dc98241e7e191e556702ebc93e325348c58db3d96d28186697fe9de87"): true, + common.HexToHash("0x6906d2d29ceedabb60aaabd91579184935977cf0b8f88e71f99a15a98510a8b2"): true, + common.HexToHash("0x6a79132d69e4f0ade488db33007ef26031b8cb3c0570502b794d4617b0633ce8"): true, + common.HexToHash("0x12b19bb589153df21da0c9978e2ef03765ee22844a9cb7af32d9cb888df5c560"): true, + common.HexToHash("0x7386169cbb0b949e0d3eb1266f3b40ab418d6f6957ccd6f1ff5abcf4d1b13ec3"): true, + common.HexToHash("0x0f9fda80ff4519fd288d590351e3b9baf1f799ca48f3117751958853f42d0a0b"): true, + common.HexToHash("0x794661104bff9bad8961044db0d9b18da641c51851898ce53944213fb69df607"): true, + common.HexToHash("0x8067ee87fd0a26cb8db9c38a214022f9fe6c043a4308138e690886d3baad96d0"): true, + common.HexToHash("0x1d2e8f4e7f802403fb15f1431e168d5b64bd93e9597b8e3863e8c4f134e66c9f"): true, + common.HexToHash("0x05e3bcd5f5ea3212b112c5b10f873004268cc9ee2bab63c5b253d590782829c4"): true, + common.HexToHash("0x0344bb630d31bb89b57c90ee079f930333f63cc984f69e2f1136b39325ae54ea"): true, + common.HexToHash("0xc0bb2e89bf5c98b96129402ae06f9b529670c221d93264c57f3eec7571f17387"): true, + common.HexToHash("0x84b6a03fdb02b2064a1f611417575a19bfc656d826a41498d6cfce0ca47613d9"): true, + common.HexToHash("0x03d46f46b78d889e6d29b8ade4fa4d062af22d81d35010b653aa2e040625aa1b"): true, + common.HexToHash("0x0df7d75d00ac951d4e3da5de42934c8db39134bab4c692cde438a60b3d79164a"): true, + common.HexToHash("0x7a4552e0563749a380aebc32be369f1b15c0f0d9991c6e4eda21d941675d727c"): true, + common.HexToHash("0x799da67cf9dd599c500eb6c42cffa96046c9605663daf9060a92c4570ca009aa"): true, + common.HexToHash("0xa2095db62bd1fde792484c23f39e0d3b26b6a39b42eee1d7d40f2e33b2b28e61"): true, + common.HexToHash("0xd20c025e069faf0a1f2a3a4103e64dd2f5ae7d2734003482eb1aca9b6f6d9a59"): true, + common.HexToHash("0xc2261c3ae84e3e35b391fcb1c6d8ff6632e950c6b14e6f011e600b6b48050093"): true, + common.HexToHash("0x1c21bce5054a7b43b4183ff183053594dba48969306ef4956ed952de29758d99"): true, + common.HexToHash("0x1b647c2f40ea4656ba55f34b029ab805753dc874d953a1bd5aafb9fa1fd058f5"): true, + common.HexToHash("0xc7234ec4ec8eea000364e61c99492e33905bb4f3f71004347eb25196dc7d01ba"): true, + common.HexToHash("0xc487637bdf7a6dbc56ae9f8a4cc3fe90c3b32ad04f7a66454656d5e7c16812fa"): true, + common.HexToHash("0x70cf0c46fa305d67d0a1cfa3b69143b02f32e9124658555b4f741b1aaaf424e9"): true, + common.HexToHash("0xab7750051b107d3de6447fd92a213c30ff2f219a2412a46b54becd514d61a012"): true, + common.HexToHash("0x70c731c9ebe8f61d41836ba05c7c9bb98fe7092cdf5e79e455d5ed27f3d70b02"): true, + common.HexToHash("0x8808519f2d406bb5c80ff02786f37cecdbade514cd65b6f311f9e38b6799e555"): true, + common.HexToHash("0x5edf8170a87dc3c328fc8ee87c1a214748e2947d1d507197467bb4c6913577df"): true, + common.HexToHash("0x8a8700de460daa8e11429c520232e884bc1f662fbae23b9bd051e35682349b16"): true, + common.HexToHash("0x3ebc93e6bd77e92a2ac4240f9d0bae39538103661e1db0b6c2d69af543132820"): true, + common.HexToHash("0x33cedd76a375007ec49bc9ee2d63227f6375a5c13259b79206dc92b0565a8b49"): true, + common.HexToHash("0xbd76868e84f8ae1f6de005045d315247f8d99c523cdc6d8bfe8b74b6e090f3fe"): true, + common.HexToHash("0x4139a5575f02b4b998492b6fee50a9d5f8e7167d8656d524a403b8083d1a5766"): true, + common.HexToHash("0x4dd313fcd7b07fe0ae1b5b6ad3a2758f2aa8efeb580fcae1fe5ce325cf9abee7"): true, + common.HexToHash("0x8171e6197bb259f7c3fa812b5e3d85fd3bc9e1622d3bd634df8278cd93594be8"): true, + common.HexToHash("0xea72fc3b9179c80ac06b587f8a1f01a7692e66a05accc9df4d64c1dbcd921b09"): true, + common.HexToHash("0x4792a772c283d6d6212568ab72a05fc0e9bd362a3d3e83f536afc084d31759ae"): true, + common.HexToHash("0xce097d7774828ddce71811ced710817eecac0d110a4909691e179536f8344dfe"): true, + common.HexToHash("0x7503b9b08fb129038f331960fae03544ab83618a1fc6d8177b0e3867745d73d2"): true, + common.HexToHash("0xdc1cd465a3c64ef08f94bc0bda9b79f7c16370ecee7268210a09cf86bf50affa"): true, + common.HexToHash("0x4222ba54623302c11f3bcf1cc05295c2bc27920575078888eb70c73e741b48ac"): true, + common.HexToHash("0xd1f6d8a6a1b6501e6abccef945e2244bc8f63860ff55cbf61ef6188ea1057b4b"): true, + common.HexToHash("0x175330c05839e40eb2f4632c9a335164cb17d9ed7ab44048e671003e09446afc"): true, + common.HexToHash("0x10b60e7c7b4e5e82dec87168ed4b6546b168ea22aac8d7ce7c7f4dc65b7393b2"): true, + common.HexToHash("0x417aadf05e4d2dabdcc2a80fda119f864bfdb1a6d4facc8cd73b6246f0d380df"): true, + common.HexToHash("0x1462e7d51cd7403bceb0d9c8766699e01e528aa88b33045435f9a0f0e7f2c922"): true, + common.HexToHash("0x59665a7c0e82972dc195115f735dca7d5ddb4beceea857050fd8b0c909fad71f"): true, + common.HexToHash("0x53566815bd16a541946d04297d4c6e573dde3e4dd273eb1fe48825f1dbe5a3f0"): true, + common.HexToHash("0x444025b8a162ef3934e19587e8c9d707c8c4f2983714fbc12ba408f4459d14b7"): true, + common.HexToHash("0xdf963a6ccbb0be77f756c7b731fcd54568e5f77f297f9a17d8a0cacd60df922d"): true, + common.HexToHash("0x4453fdc82841cd9f8a287d98ab6d1a746eefae0ebb2fce04cbdda81effd55f68"): true, + common.HexToHash("0x106fb26e0a018d4522c565358ddc79395c82c4d65b50965283227782d2391c15"): true, + common.HexToHash("0x59564cf9eba5c4a667228008aecd00c2d55b7e3c12afdcc32313aa5c2ffd635a"): true, + common.HexToHash("0x6f7834e53aae2990682a68f8cf7b0b4d536c526ece376ad20e2433dd8e1c0b01"): true, + common.HexToHash("0x8f08750b26d51102c2857a150ff05bf419df59d7712b0ddfb56ba74fc8b23bb8"): true, + common.HexToHash("0x08e510cd464d354febcffacc3ab1c103962ec10104a6c4e802fb49b93eeeeb77"): true, + common.HexToHash("0x25921e4df9936259ca9064360821d6977f647e412b67c7a37910b6cde1690912"): true, + common.HexToHash("0x6debfef74adb54fa47dd5bfbba1b20af27fb85dc8803b0eb30d5aee0fe417805"): true, + common.HexToHash("0x6f81d789f5a9f462e0a84bf43b16063d0407df06a9ff624062ebe73cda59445b"): true, + common.HexToHash("0xcc0e2d2484b51f178cade23b8ce5d32085ff02fd6678c64cbdcc44a2f76a5442"): true, + common.HexToHash("0x173a3e32ca4a2b9c9c9950cb7f48040253a14c62711175d65191fca0c244590e"): true, + common.HexToHash("0x399581c245603ebdb262c0e5ae67114b6b0240d1f6511bc79975427b7745e3b4"): true, + common.HexToHash("0x4d77c52c1aabba8e57489c935f85ff771bc79c50daf1916d1c5348f4e89ed978"): true, + common.HexToHash("0xca82290bda03509b12a5a6a92ef28ad8c0d0219bb5c8db78834036c99143c7b8"): true, + common.HexToHash("0x222016b2ccba4838a43b348653c6d0f808003491b8644c99f0f5bd35b5e565df"): true, + common.HexToHash("0x86245c02a2415d337dbbb40dd77102bbe0f1d560c31a578aba54712a90e5dae5"): true, + common.HexToHash("0xee8424475b58f4688b8d761219683b69e3d0e06a2b13de529d135218cb97daea"): true, + common.HexToHash("0xb00b353c92c9e460b7b1163a6147b0cca9d8f42baf38952322d433e1e531a4d6"): true, + common.HexToHash("0xaa78e5d5aae244e826206bacb7cf2935d56d57684336f54069c2980e3e1c095a"): true, + common.HexToHash("0x69447c8291d61e0327f9765535d27d2eb43d33a538afca80490e7e3895261139"): true, + common.HexToHash("0x2534dbcc4ced9a9763145797eef60057c6e4ea196b99a3c652ccdf2d3c548512"): true, + common.HexToHash("0x9b67e206e2cc875e6a169e20e234cdbbd661412e7c4937defa64905343ef4ea4"): true, + common.HexToHash("0x931471d4f717e62a40e8552fe78552f4cb1414b1c615ec0bdbdb8d4292d864c2"): true, + common.HexToHash("0x2d728e0b09fa61a7553c5173aa3a6a1ecd05d02d57d188adfd160a8a48beb5d3"): true, + common.HexToHash("0x43acb3f0e487f24973c8d3edeec8b9aa3db8b42f07613c906dae3cb3e4fd73ce"): true, + common.HexToHash("0x7d3a7517f61af4249a2b2cbccaf5b55dad361a7065dbadafeb11e0a557211dd7"): true, + common.HexToHash("0xbf6a104d09fcb47a885c5f32a3dd9bb577d4d8a1fa4ee2d96048fd99f95cded9"): true, + common.HexToHash("0xddfdb49c09f7bd842d4dc35c94ba9d55a57f2cdce626ac51230894797bb59b53"): true, + common.HexToHash("0x4d3320b600b50132106c4a7ed988e1762f8f88dca4e5204f246ff775a14f18c1"): true, + common.HexToHash("0x92cbfa5c76666a3ff1eae937220c860abd062f0d498f1b56d0fa7cfb06ea452e"): true, + common.HexToHash("0x12e527a583c92131dc4e535e3675369abe90fe6a33011a022b0713bcbf55941f"): true, + common.HexToHash("0xd7e873500b68a20701d4dec17dd345b587331c31d85a0839518db65f3cfb540b"): true, + common.HexToHash("0x4bd6c34c5ca7c1a50012cbe999d6a05557da48020feebe49050c484750453c83"): true, + common.HexToHash("0x291ae91dc8ff77e857747905199672c60ea9785a67fc3ecc80d60996cf7302a2"): true, + common.HexToHash("0x32491885ffcc4a0a4416251dfbe56571844324b98bc4249280f50c0388721982"): true, + common.HexToHash("0x97a2f88940a0095fd902d17d6e2adc88193ad9333df7115a0926c7172d818e8c"): true, + common.HexToHash("0xb05957eafa3b426de80b9ea312b478209a7ab12f52a844c257b46442f9253c4a"): true, + common.HexToHash("0xd752f7d5acdee1ec56f17b95458e6459d4218c67a25807a7d62175a1c018f622"): true, + common.HexToHash("0x81ced39a1f6b0ae37d28dee7101bd94a0d9dcadbc7fb3fc3027d288769ed4806"): true, + common.HexToHash("0x944e59e19f7c39881e9a72c5ec97f4f352468f02ba6e08803a3870663eb6f551"): true, + common.HexToHash("0x3322819dac967947cf5f3e8cca02a5e065a15d74dddc13441b5875ee260f69ee"): true, + common.HexToHash("0x3a4e5dff0d5256287f1370123b29bb051729387d06d79383ad3adcb90497ce2e"): true, + common.HexToHash("0x83d18c06340b26843306f7c812894fa325a8e01fa4ba20404a789ac3399fc4c2"): true, + common.HexToHash("0xcd1740603cc47467c97b51afe10ba5b22c9aab9d5d68b287b19b7a560d6e4b5e"): true, + common.HexToHash("0x3ee6e39525c49775f02a3ddb1bddb2c3c6b742ccd17a8310305deb13b87b77b4"): true, + common.HexToHash("0x095ff47dcce55712b86318a059babd2a0c4d3d3ead07f485d9873673581d5ac3"): true, + common.HexToHash("0x75800090733521ae6dbfcae7ed2694eef59f3ef8c29a9f7fb2bc66730384a8f0"): true, + common.HexToHash("0x493fd2c3093494e195163ec6d7bea1bcaea8ddb4e934747d4ba6a629be658bd4"): true, + common.HexToHash("0xd8560d4dd08b17e65b8d5468394710172b758db3ee511fe99011bb03686eaa17"): true, + common.HexToHash("0xc2aea2451b6872f8948c8fa1250fb314e3e4d39abf0b52e50fc1c7faaae47065"): true, + common.HexToHash("0x4f01d5a0fb7d2651d82ad919e997c9340169db358043f4009b3a08047881e6ca"): true, + common.HexToHash("0x695985b49899132b2b4797615f02b80dcbbfd4533925ffe0d1f45de02cb1100a"): true, + common.HexToHash("0x51dd70b9d109a9bd5f3a8845d83b3b4e2a8236a4fb291dc072b098590962c02f"): true, + common.HexToHash("0x167b3e0ef2ec606db6a7f450399d75cfcb7a7866c3072e359a220c91f8437c9b"): true, + common.HexToHash("0x6b6736b2aecc22856ab8941df8207c116150e6694e346ce612b1c4981e893d87"): true, + common.HexToHash("0xd43cf99a8d62ed60f2c97def54ce76f39d34019a0349e65244f39e451209ada2"): true, + common.HexToHash("0x79942fd7a4627922ac02a9a86b9a236121a318389195db256efaae83f3a36a9a"): true, + common.HexToHash("0x008f5c32bbf1446bf991fdf1979043d753c8a24a6eb66c4549b0cc9557e90e17"): true, + common.HexToHash("0xe848a0a19f6c8013e4b55d733d46f282d471f759176b23a34431c579bd27dd46"): true, + common.HexToHash("0x3873d380c9e6f923cc1a48c916ead578b67af6897fa9e15be51274a58142b0b0"): true, + common.HexToHash("0xabdbd63f438d662a1e66135897ea4cd7030d3dfada97f269ce869f561dada395"): true, + common.HexToHash("0x0a3c005ff33a28d129fc30c4dec4540de2c75ab70d1c0abc3e6f84483d83271d"): true, + common.HexToHash("0xa68ed153ee773a457153a25d113614910135ba83db062ff5b6949f854e98e05f"): true, + common.HexToHash("0xf70c3ad7912e68ef0c3ab184ba0264ad2c886259c189cc9ca7af62d5100af99c"): true, + common.HexToHash("0xd8419188496388b62142a7c82564b99869933e021d8f299e726ca737650e26f7"): true, + common.HexToHash("0x95fb4455420320b3749900e82727cc92adf9b50583114ac2bec1673357473148"): true, + common.HexToHash("0x8e59f33f957fdfaeaf4e5a94cc50f8bdd1d6d52ee6ac72a882e49b95a9a01263"): true, + common.HexToHash("0x44af3ff5029bfa9e52b6002d1dd01ce6a3e81ca897973afeb1b5753f612f1b0b"): true, + common.HexToHash("0xfe691557d105e3445a46971f53c2b3577a440be92bf6c2bb4ab978e5ff1cf33e"): true, + common.HexToHash("0x1834dc1b4c2784e03ea392af4e299607afd8753a54816402ecd45701e173c83f"): true, + common.HexToHash("0x373c7ff83e30c9ca5d735198e84a2cf3afd74d784f17e24396993f7ca668c1be"): true, + common.HexToHash("0x5dd1c3a74e9902b2d951e045533fb472649851842bfbe49f4c10d32e831a77b9"): true, + common.HexToHash("0x85e521ebe708818eebdef5677b0ec78d3cac0c894d43f49cfd5ef97509b8d128"): true, + common.HexToHash("0x5db8faefacc7f1dc00736d4961712ae147cacab2ec64bbd659f6f18bb7787383"): true, + common.HexToHash("0x7ef9ed94cda9afee8c8a13aa7be6ce122fa40d93f5d65b53490d8e6d95f0bdb2"): true, + common.HexToHash("0xafb716b9cae46d88e2cadf298287fd33316366a55d41edddcdceb594ec492e0e"): true, + common.HexToHash("0xb21fd774bc941d95b47af2e6fdefea6d21486e4e1dae6845539ed9c46284c9c5"): true, + common.HexToHash("0x8c8aa612281263b3b6c7a1763939961d55120d6a8cbca7f8d0cfd7a0e046cfe9"): true, + common.HexToHash("0xd2169818b3ebb849da1af529667bbc5ed1627ba5fd0990e8ae2dd6f423578a38"): true, + common.HexToHash("0x95ce0bbfbe582565ef13ea0b9bf662ead4685df021cfa15104548abeb001d7bd"): true, + common.HexToHash("0x4dce0fc8ba19c6b407e34ae9d8830cf24be10ccfdac2c91224f2729a9a82987d"): true, + common.HexToHash("0xa703763d0f82a3b641f41d75f07305e15265589bf23649352ba7409cdec0042c"): true, + common.HexToHash("0x805c65653f2a1287e0135968d5ffe13b7b93942a2d8263e0a638e23c7d4a2ac2"): true, + common.HexToHash("0xd534cbc4ee1d59719d3b017088c95c2474ba80a8ecaf1f945ae3102940f1f74d"): true, + common.HexToHash("0xd9f1a6f8033e8b55aac55e79c1bd6c3e6bafb577eebd4fa529481182d56ab3f1"): true, + common.HexToHash("0xfee7ee4e9a6c0bd9c1fa341f5a53e0e75b7b29121c1fe5ebfe27a52bdcd2f6d2"): true, + common.HexToHash("0x8cf429cdfff40346519e6c716c4bf6419313dd581f712e41d7a707de1df72525"): true, + common.HexToHash("0x54f620f04bb98c0268b5bc4bfab90dc1b8bc06411a58ffbf5dd7fceb2355f7eb"): true, + common.HexToHash("0x9f95c9508653f9f51239b866f30fc7af9f61042353c4f0032f0cadeee522a62e"): true, + common.HexToHash("0xbe7cc8e252e9a60b44140c95526d7e4335f8df13236a6399e61366a0f264aa23"): true, + common.HexToHash("0xd98b5aac80c3fe352a59172ae152e3595934a50ef2e47c700f5a777fced07a8b"): true, + common.HexToHash("0x1a2803cbf4f9b8c773a572c12e36dc06250f19da07bd39288bc53893c7343a19"): true, + common.HexToHash("0xc38cb403ad5f564adba09633e773651703c2c3a9f677aa4aaaf2dd71cfe9394d"): true, + common.HexToHash("0x9f9ea07021dc29388b02a109085f33c38c6d6c7769f991f4747dd14081cdea1f"): true, + common.HexToHash("0xa60a748ff8d995d67152fb5c0c2be768beb8b94308aa718c3d6172720cae8952"): true, + common.HexToHash("0x4e9d7f3ded5fd053cae29a673c8f8f4c38b370ed10ffd6da5405fb7731f17cd5"): true, + common.HexToHash("0x127e696a9071937e675a29a04777d6a8aaab8d48ef59fe5e9aa94fd3a99dfe18"): true, + common.HexToHash("0xd9f3c72b5878ec0bfcfff14790349f00c4deb99924b6714f48d51115a7554499"): true, + common.HexToHash("0xed1207f40f127ca0c867ae2499c081201c3b0ffe13755687d18f572906a90df2"): true, + common.HexToHash("0x1b85d5cdf641252f2d66ed1181cdcf01b9c98713bb245ac0b722d4a7bfca8dcf"): true, + common.HexToHash("0xa3a728eb4e0f732c832f978beebe0b676a82c51c2d8896bd75e1a0b75c14db25"): true, + common.HexToHash("0x7c67db40bbc611a361f32f6b2d4d3f11881098003b3d815ef9766c2d3648c960"): true, + common.HexToHash("0x101423659a8b493f715a924bd6e502d7014bc4bc2e84f14f0ff62c9494f7d4ff"): true, + common.HexToHash("0x26e1e791abc618494ee094f91249afc4afcae83afa8e362e850ac06ac6b3516d"): true, + common.HexToHash("0x3df1814c6928721fb18d73cbc16b1864e0af90d109b1b3776550e83f72c54e89"): true, + common.HexToHash("0xe61eb1d25fc184081b9e05ecc23f94397d8254f1dbd6f4c893d6c5881f8bcb26"): true, + common.HexToHash("0xfc9e8268041fa3ef1e190bf2c5470bed88797d5d240e20a8103d9543ac78c05d"): true, + common.HexToHash("0x3ec7a63148bfcfdb8b54dde91cacfd1e0adacad108a059c82fa6924bf1486bea"): true, + common.HexToHash("0x931a885a3f6f9aeb759b7ddfca43f23c52b64ea1c6929d98e8af9c65f8c6f9c1"): true, + common.HexToHash("0xf431567bf3b0afedcde5c8fbc8369497209046cb572076a10cd2e5151c23d198"): true, + common.HexToHash("0xe96544618cc405d08c35994b735c616f438663e2430a898b925eb7a32ce260b1"): true, + common.HexToHash("0xd3fea1d9ad2a9283cc25a6c3b6c8a9ed4792b6db88ba12998bb7f42f326751fe"): true, + common.HexToHash("0xaf37f33cab79707c0cf55f68b51712c609e38c9baaf3e37c0c780b05f4dd9f61"): true, + common.HexToHash("0xa6983e6096457c6c30975b8267e7073fb8e28b7162cfa4f57b35647657c12594"): true, + common.HexToHash("0x108a88f18c6863f0992b6e2b39c7d0818056bb7597d0138cb8a47578feb505b2"): true, + common.HexToHash("0x6e1e2cb269372b6506c76cc932c8f83fea7a9c4d84823dceb8c56e38f18bd258"): true, + common.HexToHash("0x54521fc6e165e28e81cfd9f83c62b845354511675805dde659f0299028ca7eb4"): true, + common.HexToHash("0x295a9e624003ab1626fb4c4f6f756c6f27b7c5ee0ff1257f16ad1d50289fd97b"): true, + common.HexToHash("0x10259e5ca4286ba1ea59fc26ebe2118cbf80f4c3ae28024650298a0352488736"): true, + common.HexToHash("0xd01893b317ff6a591dbee156fa944d9137b607ef12023810fc2ac6373ddfb715"): true, + common.HexToHash("0x0bc9ee26b045cc2804d396839d3ab8821d58572c1b51c07f5cbda04f5b62a6a4"): true, + common.HexToHash("0x2a8af2421d347e9f61fee5cdf43fd039dd4464ff2e4ba03595ee4b92a55081f4"): true, + common.HexToHash("0x5b29f7e0124076623b9979718c9b912807115c1a9e23e06b8e1ce40da34e1ee2"): true, + common.HexToHash("0x16717abd9e21858e9220faa6f0d9e7ea5e71c5174bae2e7a2b738e55a2cc04c8"): true, + common.HexToHash("0x74c3f2b2bcc8b6f2fc0a7bb8d148544db585d3bb760d5a6d8d3abda6d019c421"): true, + common.HexToHash("0x748a8f094d848e23670287b33363e0663f5fe7f3be32821077292b965c46173a"): true, + common.HexToHash("0x6cb958d87211109655f606bc95b8cf6be143979cc6225c85a6d4572551007bd4"): true, + common.HexToHash("0xba21b1325c0528b9ae6ba274ba171202a157818e22e9ecdab2ad4169766b0349"): true, + common.HexToHash("0x22f384b57f6ead9371c66d6a8535fb3534ca1bdcefa841404dbc7279f5ea5af8"): true, + common.HexToHash("0x6ead917f378e2986f5055db0161cbbe4a61a8dff58e61256db097199dc8b9550"): true, + common.HexToHash("0x6093256ba19d3eb2cedb40040a19236efe47a400ef9de31e9fabbb7eb303e7cc"): true, + common.HexToHash("0x7ced5d2ceeadefba821d9a530a12776d7a90eb7ebf2116f404ef59b2102201e0"): true, + common.HexToHash("0x3ccc021ad8c7b88c734da31f0d7511784c5e73701aaa5573e69e0239be8c1d55"): true, + common.HexToHash("0x0426627792ccc9c925d1ce5f8b5712bf01e5614f193914fa4f5e12d330f58e54"): true, + common.HexToHash("0x765d7bbc4b5e10d42803a6047f660eb3f072e1be906ae46f5b9c26db4ed59aa6"): true, + common.HexToHash("0xa99203a7d1b6f6b55dedfe4eb4a73e7903597477359901795ecae04cdf40fbc2"): true, + common.HexToHash("0x6e8b484a9915f7b22f5698674d262089a479fc7a7b2d5b6128f55229331c2196"): true, + common.HexToHash("0x811764b49bfcb3060d16437215ec4b1415a91ffdf706f8ad83c414ce2c3a00b8"): true, + common.HexToHash("0xde3eb8482240dfb4633df56f15b2acbabf179e05d36d8dcc22693a84d6b5d00a"): true, + common.HexToHash("0x96dcf6a479f06194a06afb247ad493bf3c9d07a48145aa5e97d2d9d8a24b3954"): true, + common.HexToHash("0x23e468ceef78375b03d12d74f470e82254c06291f95b606e9a919aa504d97252"): true, + common.HexToHash("0x64120a05f20faee68840158b817fc2225fb2a437dd185569dd9844f48b0f312b"): true, + common.HexToHash("0x621afbc0442ca2a6d59d43d217a1aaf62336314455a9b2837135d63cbb43e883"): true, + common.HexToHash("0x89ddaa416d2469b344e2491c2eae68563b30337e3224e95ccfd3ade2065efeda"): true, + common.HexToHash("0xf39ae63be38e74a6d5873d181dfa452e0ce0ed758bfcb96898e8e53bba4a3c49"): true, + common.HexToHash("0x7aa904fc6ca5a46425fc413039fa52b739f7c6788dcb198620217d5d6949ace6"): true, + common.HexToHash("0xc01f15299871d58794ab18585a4b51482338be3468fd87bad02ceb72e00082fc"): true, + common.HexToHash("0x39b8138a5de70de640b840aa41c7bf850f9bf9bc39e5d76c8fbadfc1bd7edc99"): true, + common.HexToHash("0x1b45484fa668f7858bbf3e222982ab4f58c9c8ee54198d14b533d7272177047c"): true, + common.HexToHash("0x2430fff4c9bb262272bdf32fd7fb307cbf21f496861e017881ff9aac1310f09e"): true, + common.HexToHash("0x92eea9958fb099bda7f4fa3df9071e60cf52f79e143854134ae7c2f28662a339"): true, + common.HexToHash("0xfeb274b2dc0336a623b0fe51b7851c0cf08a57ef284093bcef0a9dbdb04d6d74"): true, + common.HexToHash("0xdaaac7a601f2556c56fb798aa4f7ddb3c37ddb6a5fbe797a69781091c2d4cbc7"): true, + common.HexToHash("0xf18e80389b883f564fef064c2a320f8fa1073adaa40c3604797bcc83dc6fe5a7"): true, + common.HexToHash("0x5fd5adad9448a9b91877c813b737815b7866133a9673a6e66cf31a61f095625f"): true, + common.HexToHash("0xe9c0508882ed7515d5cd1ca518290cd3ba1d254405c9b5378e24b1208fe0ae58"): true, + common.HexToHash("0x8901a36356c812114acbd476bcd80d7b22db11bd80f40f2ce35ea76178bbe418"): true, + common.HexToHash("0xac35453c171ffe92a61c94ade510360ba0cd6b2516ffa54cc26643d81dde19fc"): true, + common.HexToHash("0xd8e8c1ec07c5a029a46c3cb660a842748773f2c315c6bab63edbd50aafc3c7d1"): true, + common.HexToHash("0x56ed3bb534ecb0e17ccca740a98d91ee53ec3f6fd5ab8364d66052f1b4a3c10a"): true, + common.HexToHash("0x877ca58c200e5a61587135f020210c355531a56db9a344948fd27c312b7497bc"): true, + common.HexToHash("0x1618b497d53f56e56a01c58a3ac25313c5a7f654e7446dedd2dfdcd58cb24748"): true, + common.HexToHash("0x7fbb2af81df9e7311bf75bbee400c26c601f0d59a5241b65fcbcc6307db05834"): true, + common.HexToHash("0x285217e5b58d73ac003757293622a7a07380c0f1101ecdb9925633354c8da98f"): true, + common.HexToHash("0x8a63458e8d2510aa4e3445234c33f322190d9c1edf4f82047dc739e177798260"): true, + common.HexToHash("0x84416ab5eb3f88086ec6af9d786127c0053fe177a2a697732f5b3e6059a5c8c6"): true, + common.HexToHash("0xfd9fa3abdae7bcd4db35be08c6c0aff9128d47b199a8ed13c4fff147e3840e53"): true, + common.HexToHash("0xf97b2e85d8902179704f7e778fb30663916e2808b7f0e4634e4ce3d569e10c88"): true, + common.HexToHash("0x979da308c1ca4780008bc2af30ff48e2912085e6f8e8eb878cbb1721a3d95290"): true, + common.HexToHash("0xd30a7bc713072445a26114fa21a740b76fdecf11d8fa9c13b63badd099521844"): true, + common.HexToHash("0xc8e9e58370a6df128e9a631f1a9de337372cebc7a9597ee45a9d18523555e3df"): true, + common.HexToHash("0xaae0e97abaf5a8909603599e7e27601a55ae80f0a77e29bbd48b2fcb53943927"): true, + common.HexToHash("0x9b657eeb1bfe91aaf8abf55b5f9d919f07001f65da464d066e6747f957cc4f7e"): true, + common.HexToHash("0xcde6999f13db23dbb309b4b8f57ffe4cddbed382843a758bdd55181c988e586c"): true, + common.HexToHash("0x874a830dc43bed80fc4b63bb90fc3fc9aba99b5e5acc2121d73ed1549400e30e"): true, + common.HexToHash("0xacbcad122ffe9cf22ac7cd63792158719d8808317dd66b7d5dd57be3ddbd6954"): true, + common.HexToHash("0x18c2e4c62ca1740ae8d8a5c7416de0c9f9aee4236c272af8b66173aeff3de732"): true, + common.HexToHash("0xf319dc893ac5e5f75f3200a179dac66f8ab5470f60a39b25dfab56d24e11785d"): true, + common.HexToHash("0xf128e3ab4c7b0cbda9612eb5dc393bf484c7f69b1257aae1cca5e79418dbd103"): true, + common.HexToHash("0x7322338d370b5ec203ab7a594bb7eb644b35beeb07f2b315bba0daabefe4491a"): true, + common.HexToHash("0x31dc2d62c898dfd947f4f8e087189b7a1e1af2f101f5c4d8436278375c3ec22e"): true, + common.HexToHash("0x286d4917919d8c8b74dab8b93b40b582e67e49c37de16bceb17d2248ed80cf30"): true, + common.HexToHash("0x4382044db628a173d56fb582b5246ba197ae6b88f41def5ae343407dbac06df1"): true, + common.HexToHash("0xed91058a882d1f65cd5fb073e332a2a4fd96f64b874e1afe27903be1a828b195"): true, + common.HexToHash("0xe440ddb6122584048cec6650339cf57e0efffe39deb7f3f4eeb55e771a21be3b"): true, + common.HexToHash("0x9025b8140c5055ccb7d83fd6d38c58cc636257c5763b3d7f3941275ef9c5d4a6"): true, + common.HexToHash("0xa7a690deea9a8e234f7b5ab23d41362d4a4979da5fc635a95bc7ac3897fa1d15"): true, + common.HexToHash("0x2790b14b0c052767b68a5abb8df9811a5041415b6eecfb533e1cfa9569fd73ad"): true, + common.HexToHash("0x20b9650c9b3fb805e38f9c9e76fee1b6398f1d94f8b8b91d7f8928e1ed937142"): true, + common.HexToHash("0x5f5919c556b8a50fdb5bb577f190c91848826d78f2cdb265898e7f5a67fa33a1"): true, + common.HexToHash("0x23fccf7c455fa69c027637189343b2f24e7911ab8c7cb1e5eed59af8fb52e51e"): true, + common.HexToHash("0xd766df0c974db530df16cf375d08e93d4314bf72b20ba5fa97698e726ccc1450"): true, + common.HexToHash("0xd4d91340452e45f73ac7729733cbf0461bdd93851ca056ed6ca1e852e029a66f"): true, + common.HexToHash("0x1736b50958aa36410214302870d2e57888814aa1bcf50a691c2f566f96f7b1bc"): true, + common.HexToHash("0x4d555c1cf2c69882853ed94d213d0d5ea25ba65dd1278bb84d50374a94c34ec8"): true, + common.HexToHash("0xa9b8ee65c24a1aaa939356066a13446d9a1cd8d6b0a43e3891efa18d360ead81"): true, + common.HexToHash("0xb5a02acb4ae8e8df402d6fda7bb4d661ac0072d1c4d76e84bb21a01824b36d63"): true, + common.HexToHash("0x27387ff83328a37bcab0f7227c297aa56246061ff3eebd356894823c6e3a2f69"): true, + common.HexToHash("0x196c29ca53e78d1ea213885040e9acb5f0b7eff0bb6ebe58934c313ced548496"): true, + common.HexToHash("0x0873fc5b10acb469946007bdd5e36f45efc18bd00188c8cf803fff2c0fa24cd1"): true, + common.HexToHash("0x705a7f6898c6da47f2193f7af296625c1122b8271eafe8e64cedc626665e4227"): true, + common.HexToHash("0x2005d7a31293e9573d648a0f393280b1e26b27be4aa84573395ba030464791b7"): true, + common.HexToHash("0xd999d10596d8611a8cc0003ab511d688960d4766d40671e53b43a4e901beeca6"): true, + common.HexToHash("0x4c304c9f6a5cd8420590fd645d95f0967d88ef4d2ed82b63e2692c0127607bf4"): true, + common.HexToHash("0xcdee659d3f349847532d5f52c4b537d3c537b52b25cbed1e3a69ef60ce6d90e4"): true, + common.HexToHash("0x7681062cee1d5f13dc0b99ccfd2a5119adcc3e3874168d3a82d385b245ed3914"): true, + common.HexToHash("0x9f4d08d0fd7af634d1b5c589323a527a4b5eecf2a23433e45b1382b3fadb9a10"): true, + common.HexToHash("0xb2cad1af9beada006ed45adc31bd2ea092d04e56d7c25ea88ff0d5ab89316dc8"): true, + common.HexToHash("0x650419f0779141f6ea1b773d28dbfb19ba3ffa736ba2e7b1303dc9e25fc74c75"): true, + common.HexToHash("0xb574a4d466128ee62cf28ff1b5f7f8a145fa0ff1d08ca87eaadef231a24f6565"): true, + common.HexToHash("0x7a5dbe34a949c694e239674e6608570d23efa206fa45f8aba34cb84291b748c8"): true, + common.HexToHash("0x1a10da30f0b7098a8eb895630e07f797c104e363a373a9875b557bf2838740fa"): true, + common.HexToHash("0xe705c9833b00bb8f7ad98e9105aa86afb9f8ef7d93d970c9dfe8afb0c2a45a11"): true, + common.HexToHash("0x2724c994bd01090396716f8649f5d95c7f9b658749b96fb565bc0aba86245900"): true, + common.HexToHash("0x13ce9626298bb7d9314422ed9abeb57982d64ed852a455e7636e046905e362eb"): true, + common.HexToHash("0x10414976b576fc707ae03ed4fe553b3bb50caa7c56bb494245ce764faa9bacc6"): true, + common.HexToHash("0x9d41d97e99ef0ca97a1ec78087695c3b2ea0c53ee69ab625c71ab9c5fd22229f"): true, + common.HexToHash("0x0ec4e8570166bd4bfe64ab297b1eb7a682fd1c376334ea38da59b33e3eb5f17d"): true, + common.HexToHash("0x64e97d4b45d5d578062a38de86309256371639286c54266d972f851cf14264b2"): true, + common.HexToHash("0x0aae96090af64ada99ebad0fef347f610cfeb0b3f6fb76f3d7cf2e214ffda5b7"): true, + common.HexToHash("0xe0dc8c8750c164b6d5e842e588e61653ad2c1b1f98fb413fca0485a731084698"): true, + common.HexToHash("0xa36f8e8f830a3529eecff2bbda68e8165aa4c3e4de05b8e2347fa17c83e29b3c"): true, + common.HexToHash("0x40bd5d9d6c1f47a2ca5f1c864507a214d545b9ea9cfdbcfa3654a1248f309414"): true, + common.HexToHash("0xbd7aeef9a6b24e8f37d888a22c3402c628a8d3a7dd2906f0511f7a4d57d66f9e"): true, + common.HexToHash("0x6b5a57c0faa65802c22ce209e7f30fc00054a4d97b5c3dd2f5c5c4b6021601f6"): true, + common.HexToHash("0x586a4197792311a4532df4ebaaa4bb26a3c4c71f9159b970d99e89bf8c8db9d9"): true, + common.HexToHash("0x75aa6980476d95a6558f1431789adf897a41bbe7aee5fdac5496d1a9fdf67a53"): true, + common.HexToHash("0x494284034e01c7e5602b9be797c23f01cfb4f1f7ac24c720362d9fec850cc94b"): true, + common.HexToHash("0x4adc2857bb8b0d58d677d4c063ba21d99d2997ea4a8e36b4057fc35b9b5bac0f"): true, + common.HexToHash("0x596a8832b1296f0cc5f7d8bb81afeaea9063c6e7a9aa10cb56ec17e50ad92c19"): true, + common.HexToHash("0x531b8f9f47a3de75c4564f30a58124af3fae62a0c88dd2b44c15e008484670de"): true, + common.HexToHash("0x851295ec3117734c0b3bb216906ed418c49b062333f1e8660e0b27ac21179cb9"): true, + common.HexToHash("0x9e018b94569a9790f930d98b2fd4a3ae254147d355864a56095719ad68721756"): true, + common.HexToHash("0x29d716947503259154cde46dcf1c5702c77283ec7ce918426d66e75c2df59f91"): true, + common.HexToHash("0x1bb6233b9971b5855a6c33b2f27830245a189e24265637bd5d4214f2086b907a"): true, + common.HexToHash("0x7a70f443a467dc3c3d5a4b33c2ef1a12e6983ea7e87cf0fee9e4d4159ac95e29"): true, + common.HexToHash("0x9b19a112ff6144ae6d6048f4add177a0442edb8aee58067f7c3a1feada9ba681"): true, + common.HexToHash("0xe48ae24f38f95cf36f09dcf3c81a3a9c8caa65767d28828a1e4804242099abf0"): true, + common.HexToHash("0xe60fa89734bcab3e72cf2a2a5d00d20a5e4b44655b698aff3b60079ee7e86ae9"): true, + common.HexToHash("0x563b83e1ef215f552f04d8f263ac26a2edc9dcc337c9cbfb89e0320dc0ddbd4c"): true, + common.HexToHash("0x3007e78b29d9f5c0450c7b65827590089a13bd0549b48f4e21200a4f74519913"): true, + common.HexToHash("0xd6b7bd95527ef36ac6b13fb3bd7eff3dd205a0dcb87d03e6bc36c432aec28184"): true, + common.HexToHash("0x9423b5aacdf830f369535eaea7522feaaf7296340c050a253b612d05a3960523"): true, + common.HexToHash("0x54ab13ecd373fdfbbc734768862eefc392b5aaa18f4310b5f5605db1ad9853df"): true, + common.HexToHash("0x344ff3b2e8c4c4e37b2e82286b572aea8dcab198d98a0bf024a90ca5fcc15d64"): true, + common.HexToHash("0xb685bc6743bf552252acc0f65720027da10f03a04b6ad3053efb0c03c3dd30aa"): true, + common.HexToHash("0xb675ab49f756ba22dc9cc82db66028886d70bf405b6494e0cba42f6d92f80ec5"): true, + common.HexToHash("0xa8965876b21fcaf2365a1f7cd00c97442ccc2ad7bda950742a6b92cc43f923ae"): true, + common.HexToHash("0xb0c0c6494fb7e22abd69ad1cc20f4e71a8eeef6861a683a8a1733419be606637"): true, + common.HexToHash("0x6126dc3bbebb653d1c4af23d83d218e98c862d7309c62521febf3e77ad5442f2"): true, + common.HexToHash("0x3eebd1ce58de79ed71c3eda42734082acf50c19c283234b0277610e5f744cd33"): true, + common.HexToHash("0x441d9c6726104b965ffa87f61cf5a474e9d037082c117fbf19ca3b494a8eb571"): true, + common.HexToHash("0xbd8d30ca7456fcb09adebc47a931ba3b73c7de931bbc810e1e881d5ece561422"): true, + common.HexToHash("0x0ddc57989e4268ea15e5572d92f68ff10c0450bd54ea77e069ca6d31bd4b79ce"): true, + common.HexToHash("0x28540d34a72a8d901e2e531c845ade4f9030b088bfdc7bad07f41c6bfa56f982"): true, + common.HexToHash("0xa0047fada1933dcd382d0f2b1687b836aa80ec533f4e10f96a11a174b8882956"): true, + common.HexToHash("0xe60eabe81b61f860d97cfd536b8dbbc66aa98e7e5c4c04f47f84e14821ef3299"): true, + common.HexToHash("0x7d0a7f1079f6b2dfa5a9cc5a3345704d183a7b755ddb670bd1d5bd881c500d89"): true, + common.HexToHash("0x6a35903be36a1fa83ca588ba4a5e60abf85f7456ba9c940b648ebdbd33bfbe64"): true, + common.HexToHash("0x0d57f4c4b2869e162a80f21e8aa8c38d13b7f96eb1bdff599f7954e452ee71fe"): true, + common.HexToHash("0x009d56111d3a68e3a6be1023908fdee997da78214a603dbfd158286ca333a141"): true, + common.HexToHash("0xe8cfeea6641ffba377561c53b8e6ba80339e4bd116fc7a75caed8fb0029c7f5b"): true, + common.HexToHash("0x0956955929ed5b849fd33ed354d481cd1c9432bfe810434a0f8d38f673540818"): true, + common.HexToHash("0x8fd592e3a5ba7a63eccaf914e778018c4fbcfe8e51351ba2acdf179a5007ba47"): true, + common.HexToHash("0x664e053d92c5ee7d44f6a0e51d89b9a340d8775535f68fe6f5e59a9eedfc48a3"): true, + common.HexToHash("0xbf0a564171852ebf698f257de75c34b20f84ad624115b2b08002ac24846286f7"): true, + common.HexToHash("0xa8d6b02439eaf736b038b29074987ef3dc62e7145793cf0d231e0901064b63f7"): true, + common.HexToHash("0xab67f4b806d7cbdc44f41faa0df778316387e512dee13da60028b128afe59885"): true, + common.HexToHash("0x7aeeec4e2455651a08d575586517d83a0dd6e992ccdb59de6876e1d508308792"): true, + common.HexToHash("0x287d5bb67dc6efca02de427e27b6ac581833d4f77362fc6abaf11172a9d7332a"): true, + common.HexToHash("0x7953828d7d4acd7fe2eaf183172a1b8bc30cc57a1a8291e275a8a59729f5188f"): true, + common.HexToHash("0x08e75e4304524b7c4136830090bf804673d55c7374e23f0560aa7d9bb97b3666"): true, + common.HexToHash("0x18588a0197fc8b4fb4dc62d7e5e4066bfd6cfdf8e8fa6ed9af8902f071994b86"): true, + common.HexToHash("0xf0cdded7c91ad6480637a526076356387359d43527b1f7579df80e36b206e271"): true, + common.HexToHash("0x83b5af7f5acb2528039b23dd24526c941f4a09fdfcd4cdd82288d86527d13b87"): true, + common.HexToHash("0x3ad800fe651afc0b4b9c14ff6ab86845194d0e3555ec9c345117fb940dd595c8"): true, + common.HexToHash("0xad5af55efbe776cf5efd6150dbb517f3e50025e8ea0106642190e1157bc57d2f"): true, + common.HexToHash("0x2a1c093db878eda506115b2cdade17c9931962a39d936d22ee0d367ce8d2ecee"): true, + common.HexToHash("0x4b01187657df5f7b94e928036705123dd7d070b40002e8fe068960b6026f3089"): true, + common.HexToHash("0xbe25a0c2a9b7e8404d0d8b3a972b10fc6840213ac71cfb5a42d87d03cad42478"): true, + common.HexToHash("0x6cd3ad1105e9d1cd6daee2d577a5a8774bfdd24a64e82d8072b2e6348a3f3127"): true, + common.HexToHash("0x06f6a9c1c11a169dedbfc8691348ceb6cefde9bdc557e704da9348e0be80fc1f"): true, + common.HexToHash("0x9399e1e98b77638ef352683f930ddbbb019b10c6f0c49766e43a27ee21c84f0b"): true, + common.HexToHash("0x579fc71005ff8f98dec74042a3ffaa6a466e91bd342cbd036cf8a64532d7268d"): true, + common.HexToHash("0xb81d560ad7cc4ba649452022542ea6c5f8c34a11210ef1849a3c609e3550ec19"): true, + common.HexToHash("0x21e1f6ca5d83cc7be69dd1289e3c7f6da6abccd97db9eb721c0b15f63e3840d4"): true, + common.HexToHash("0xb59ff7df0b55ffc27225c8b48b47cf4ee015d32e1b181dbd915d9a7c9d9374e0"): true, + common.HexToHash("0x6860dae97db5fa6d17aa3948fdfdd0f86ea792fbd8ed95927bebd0893a6f37be"): true, + common.HexToHash("0x8bf6ebccbf128f7899591f1fa57228c5e19f6a0776badf9fb0ca2977335e4852"): true, + common.HexToHash("0x22ecb853b66375952e57967b8e3381fb50b7b63f7e3354c7fc12039c84d0c263"): true, + common.HexToHash("0x2de07d7efcab9b7858a1574d9a2776b29a023dcd85d12e362e4ba8ba7cd5efaf"): true, + common.HexToHash("0xecefe8aa54635fda4b939bd28c78378417d64f8f8ef35912aef40bdbcfa74480"): true, + common.HexToHash("0xe623b49453a79604d26dee786e3635a0885cf538c1ff89b61fdcfd04bbe7be0c"): true, + common.HexToHash("0xb32cfbbc344535d70186145c7d8ff0f7d4e8f8b0ea71d47235a13d6488742692"): true, + common.HexToHash("0xf06c61d8e0c8189fa912b7a6809e92b89a09fdf788f120855c6bb9fda11d1af0"): true, + common.HexToHash("0xb1c42eba4d1649efc9446fcc5fcc3639265e67097afd42c8713442a8c6591150"): true, + common.HexToHash("0xe3da81e55487bbe61e1e7065b8644d95e1c83ad9e8f15fe3fa8a02747f46136c"): true, + common.HexToHash("0xa3c4608b4453a7ad28437cc2afd6380267808922024f93865f89c994ad473290"): true, + common.HexToHash("0x5e91e2c31f36ef4cc8188262c438cc840a3d148e138580888e9ec0683b237134"): true, + common.HexToHash("0x5d62baf89b7f831e8da4b03ffd0d3d57d8efe8b74a437b380c4785f1251d88e2"): true, + common.HexToHash("0x427c794a201a0e303e930d5d85e791982aefb070d8d4a08d181bd99fd6a8cead"): true, + common.HexToHash("0xb68f83e4c87c622f8f62cff5c13d8ca25344c5ad64f3cad80287e06f2738f2cb"): true, + common.HexToHash("0x1f38bc8bb8a3552214420f1078078f5a03088b19a0ce65f356a61abf38d5bb96"): true, + common.HexToHash("0xe36120f6e8e228e79ef5d5e55d807260022fc0ed7e9f390060d5cb0d22bbc5cd"): true, + common.HexToHash("0xed79ad5636ed7769718086f76504644b44a6a51afd4d0e9cac09e6ea10046558"): true, + common.HexToHash("0xc78acb6a408b10c1de8ebf25f8cfa5440a364dbcdb263794543f69f464155070"): true, + common.HexToHash("0x49cd5ecb74eec4dfc2c202c8eb7e7336e98d95e39a148f4e860babb731ae087d"): true, + common.HexToHash("0xdcc06dbb484c70afa647fb212d6e483ebc8ffb6d268ad6210fd106df50fca248"): true, + common.HexToHash("0x83e8b851d6b6cd7ad32b26ac6398669a3e8d3b8e4454eb9dfc8843d2df94649c"): true, + common.HexToHash("0x025c3c5fd7fe3e5e95b7a4c0b595b402f168f14fd95a74a9948ec04f5bd83594"): true, + common.HexToHash("0x7457f833be5648138f90611c2b8ba72b36d0a8430c278a16dacc59ffebb16fbe"): true, + common.HexToHash("0x4e44b22a6a9598b2daee04780bdcdb89f92e073c97b479c1978537cf6e89c7c4"): true, + common.HexToHash("0x631e8e7c8fd40f22ae46c2ac459c292ffd3241ae7b54f4188a086427bca3cdb0"): true, + common.HexToHash("0x77985e946c9747f06aae402156499ad6328e202e279ca6ccec5110c2c106208d"): true, + common.HexToHash("0xe7078cd046553da43f395cf4479b26f759e0dcda1108f5a9e6d321eb1f9b8ee8"): true, + common.HexToHash("0x6ba88e951dcb8d941d6c6f4a6fe026249841413dcb147ec9aebd661bcac0bc91"): true, + common.HexToHash("0x06f66df9026423dc4823e6f34b586ef42837ad3f7b3cb3fec0a0717717840765"): true, + common.HexToHash("0x99e42cce01e0b0cfc6452c1a82d58e2f0ad56f677e0d964fd7ed2467f3e4c162"): true, + common.HexToHash("0xac0dba631716e9f2b3d623711ea99cfbc2535c006f5020ef4892f16d00ca0a0d"): true, + common.HexToHash("0xd3b426f0e88508e6e40ffb7bf1143546bec37e1b3f2d35e4ba923a25e43dc393"): true, + common.HexToHash("0x0e1fb03723850628e012a963fe1e46d984f0f814ff5eb53e5390cc89696fe742"): true, + common.HexToHash("0xa328a1a258944b46685bf8e4d1709bdd15b57628502530ecf635317f042b7a26"): true, + common.HexToHash("0x74fa128c7e28db13c9ad5e3c674e1c9d88e8d2a18c99ed12b1989eea79d3a499"): true, + common.HexToHash("0x2b7cc6511861aec00ceb75c5f565e795b0ebbccfe8c276494f35f3d4b19ee291"): true, + common.HexToHash("0xf77dde529f6d0ac7ceaeed3d585407808d0ad0e9bbf72bbf83bc62edc57716d5"): true, + common.HexToHash("0x922e9bbba10140708a3385c0f8280e96ecb274decef59a914ff7a1766eae6f39"): true, + common.HexToHash("0x12a1824350ba6407666b67b2dbb7151c1f27c02532049b7a3c80230b03bec523"): true, + common.HexToHash("0x0e5a35a7489dcf10bc366e4727d36f8496488bd352cb0987714f870bc66d34c3"): true, + common.HexToHash("0x965a0c8fec1371747a2e0e8303fcb55fb99217c406427b84b94b701e614a0624"): true, + common.HexToHash("0x69d77ec50804d19cc178e266297c14cbc108b0b81256bd4d4abf199d806823fa"): true, + common.HexToHash("0x3af5722ce30fb7eb0635a84fab7abf21c7af565eefdf0da4982f95ee34fe5abc"): true, + common.HexToHash("0xbf774819faf227ecc68edd4c5568bb47826d2bcb465924ade51b451405030dd3"): true, + common.HexToHash("0xc034025db9b7c6f6188432d5d63f9afa018c65eceac42ce1da5cc6a198f65d96"): true, + common.HexToHash("0x874bbfe6e3ca25a55c143b5db447285132164288978e32b71883e02e755c60da"): true, + common.HexToHash("0xf655d3ed87af5ad64abe5078bd85cee55df78b5244aaadeb2fff13116479f9a9"): true, + common.HexToHash("0x14e6b15f782c74f08bb3b3e00d6e295472ef3d4e38a8612439f8dfccd8a9ac07"): true, + common.HexToHash("0xe622606cf4138476848d9eca0fbf00ca6c930babacf4954a10d5b15da684ff16"): true, + common.HexToHash("0xc511c4424d70839d7ad6d4a0c50f26b8c207e1ac4a23ed519ac77facd6a5b401"): true, + common.HexToHash("0xd27bcb50128957e8145b79279433a7f76d8fc531ff8f0101c816261d7b215ec4"): true, + common.HexToHash("0x16d3e87decb322af21670a654b0700e94e15c39bd2e3b55c2b8163e074acc75e"): true, + common.HexToHash("0x2237931bed5572262bf6dbd027d2e84cd63d19610c941d8571be4c3b86d7744e"): true, + common.HexToHash("0x35ccabc3068d40676d7464c1938ee9f2f2c2183ebc76547139aa9c515fe5ac96"): true, + common.HexToHash("0xcc821708f9830d61a4d2baac94c4ed030ee95e52ccbc774805c0133dc3addcf8"): true, + common.HexToHash("0xaf65398db3c9737b76099d4ad2281b0a145af7c445bab0ac4fbdf9bdbb874f40"): true, + common.HexToHash("0x544ad9e5b7b1687944a01ea843dc9b90d6c79926f468e19478f6f2ef65096a7f"): true, + common.HexToHash("0x62e2ef9e281edf9412811968bc4d8171f1e47f7e62a221b395d63385cc0b1ab0"): true, + common.HexToHash("0x4f672fdd65d5d96c3bc9c7e21b9f30437fd8413c64fa9875d648a53a9ba36755"): true, + common.HexToHash("0x26340d81e838be0f417e774cbcd24ba3bcbc538015e2ed31fed87eb20ba8ae08"): true, + common.HexToHash("0x07f85ded7edef6529123ea2f22ab27e555f0b86aa11d0ef941963a1d8866b5aa"): true, + common.HexToHash("0x8c46bef9be18e4f86ead92623deaa4597c98c7680ee83aec3b1e6dd0a2c313ab"): true, + common.HexToHash("0x58ab8cdef113745ef721a9263352475a6b0e641b1daac814bcfea992bdce7351"): true, + common.HexToHash("0x40d7eb534f02d3b4d0084d8c6e409114a2043a584a376a502f2c6b46e03f6b0d"): true, + common.HexToHash("0x7e4980bbdf20d696311d5066e1592ffa065dbad113cf8f27d664b92a5e0bdd0f"): true, + common.HexToHash("0x3b79ab359ccd98ae8ed05d924e312a59f6d15bf0e0a2c8eac0cf67d0e4ba2403"): true, + common.HexToHash("0xbffc16ccd35ccc29370b6c3bf5caccf28767d45df16d8b5f65d14fad7919a2da"): true, + common.HexToHash("0x81b76831ffce400598185715a5d76a55201f57c4ae2d43c766bd20ae579cfd7e"): true, + common.HexToHash("0x4e80264221ae63ff349851dbf274375df49261d1272589f339ff353142400a47"): true, + common.HexToHash("0x2f6a42e35d67531713c6a2ce336c5670985020003747aa60a090c54db642b751"): true, + common.HexToHash("0x113d34f88edc795cbd3d99b096848154ba468a3a6d1dd730b897cd74205522c5"): true, + common.HexToHash("0x5097412e1764f9520148ea90ccab01967d14a64ea387a3b378e60a1d25f5f00e"): true, + common.HexToHash("0xa51f65f03fef7990ce2bf068ea5135ae0b3699a654d4bf0e05a0e55280454237"): true, + common.HexToHash("0xba3f8f15f17aa1ae0d293d217e82aabab63cef64aa135545a534dc969ee2c3bc"): true, + common.HexToHash("0xca9ce34ca50a4bb8263889f514c09e33eff046bcfd1fb261585892b861f6c2c4"): true, + common.HexToHash("0xd303f778b4ad5d4af75f4dd7e7100647ed43ad7e85934c8b8253a0f82ea0f51b"): true, + common.HexToHash("0x63bc4980be36326b0549fb26eacafeb0bca462a0843169cf78605e3cea94c7df"): true, + common.HexToHash("0xc1f8112975cbee9a8684c6d142f8da35e475d2a027b2c5a1864b3eda664f1be7"): true, + common.HexToHash("0xcd92a1d8505fc28de325a9128ac61941d67a744bfe23233e24b0a911f5f6a2ec"): true, + common.HexToHash("0xcf4a6128b2ff03c732e5cdb60b98c07de7b13581eb3de63ce8f60ab8dddad1f8"): true, + common.HexToHash("0xa17c7f14000864003939452420d90e3b3d4eb5e2a1819b7eb6e010776ee61a96"): true, + common.HexToHash("0x15792f0a7cf9dbf96b4dab362a8477693485cc6e866cbef76e08150978d01d2c"): true, + common.HexToHash("0xe5bd58e68b0edc19d924addb8d0c940816560eaa512a2b43a2df7fbf838cea66"): true, + common.HexToHash("0x3bd236c5ed092b18905420619d74564f91f6323aa7a343cfdd98ec476194038e"): true, + common.HexToHash("0x63dbe5394631bb54648e363dcefc542e945bd5e508778c30aa5f79cfa9498f5d"): true, + common.HexToHash("0x907ed45a93b4c50ba268cc8d19237b35caece7558b46831b0e85e901c92cecd0"): true, + common.HexToHash("0x4248314f8d58c3ea088ad6d5693a888a87637a66e43cd57eeb03ac4140182cf6"): true, + common.HexToHash("0xde19bed8f0bcfc40500dbc722cfb9dad231e5a7f80d1546534f452f1e9837541"): true, + common.HexToHash("0x8dd397c2a5b9ff45151438cdaca2d56418a9ebadd82f9e639fa6e48c6e104cee"): true, + common.HexToHash("0x7b5dda7dd375a1eb1618e828e199e2043ee80c7ca5a753f2ef092f03b755a5c1"): true, + common.HexToHash("0xcde8317794a16d5b4844c8c3c4383075f000f58cf328ef83c125d3336a450d69"): true, + common.HexToHash("0xd4fe0f28e50b2b4c5cdcfb84dc653edc9568408c37172614afd07619fe6deb4e"): true, + common.HexToHash("0x3a75890c9fe4da303a8defbfe541809ac86d2e79b35d6aec4e25d3359713b41c"): true, + common.HexToHash("0xdbc3e803be08a643e262acebbc9b24e6f9e566b4666cbd87b43c9cb6743488ef"): true, + common.HexToHash("0xe1f9ba117d1d843e0333e74210922d928ad0d4c89fb5ab83688b9acd5f51159e"): true, + common.HexToHash("0xeb975e544be097bb475b461587150fdaf99c2542b29b0bae01115541b13a2646"): true, + common.HexToHash("0x062066a2781566fb5c762ccf36f60e7c27fb4f39e5828783422b7dc92ec7e62c"): true, + common.HexToHash("0xaf6a2eec6bc3bf97cc08274ba4f30f6b4a014fe1ec073cda0e139cafd396b126"): true, + common.HexToHash("0xa23d8a94f394b1ce5f5ac6b136094d02def56086bd29ccf4951541e2642dd2e1"): true, + common.HexToHash("0xc721af984b77579516f1daef48957000cb90fff68b9cfb2ae45d4f674078ce97"): true, + common.HexToHash("0x5c6b5204d215d4f910a0b30b5d38c5a89b5f2a7b185ef4967a0cd21d14e4b11a"): true, + common.HexToHash("0xa32fafb1091b94bf4870fdbde762062cf55fbfc9ed449066548f8a2599f6e492"): true, + common.HexToHash("0x8870b7789afe95a771208da89a43d0d2566722fc6547b8aaa7ae8ef867994620"): true, + common.HexToHash("0x91b80a62c60944145fa233fa4612748a35ad3628a5d39746b51ae6ba507cb54a"): true, + common.HexToHash("0x30fa0b8e9c6c996942ec3f38c7f1c31e47240bb1f6fb83e80d8ddd49ecbc6ce9"): true, + common.HexToHash("0x1a349e8c1b06f5f48150da9e21de5a82cc60e7cb6a1737625ce2a7326813ca87"): true, + common.HexToHash("0x36099e4838c387be7a4bb53d47019b38eb5598638091b650cfb1e1d2e8d0ae63"): true, + common.HexToHash("0xa148f4cb0fad79b82651d7f56909d4c3625ee955a22ce3c2c3047c568b7bd678"): true, + common.HexToHash("0xfca063233059aae74d1f5d7970e588f2d56bd211fe21a4e3b6abe1f97819abcf"): true, + common.HexToHash("0x1081b2d7a76cf033129f50d45abc94d0f5bf235984ec9351f733f3424262892a"): true, + common.HexToHash("0x9f1b7ac30b4a4468c6c7a248d44f84cd64da012218d64d7e51c3c3b317893765"): true, + common.HexToHash("0xe1e086556c866f93e0b073c589a7b1d39e46c7c4d5163e5e39dbece5d868f4da"): true, + common.HexToHash("0x0e8c2222df3d60aa20140a6a04ea4111c408af994e2a6132de6f8f57f77e99f4"): true, + common.HexToHash("0x366fb4a6a02dd642a7f55900fd477e7a0c75818c5f599133d544abbd8bac301c"): true, + common.HexToHash("0x9fdf436aa283ff970cdf8ef1755acbda3cc5104700457b2a426d02dc44a76534"): true, + common.HexToHash("0xccd3d879e7767b2b5c35d134747beb0655f16e97e460e5c853838d70f1493f1b"): true, + common.HexToHash("0xd32dcabff30e9b847fe1503b491ef6997198233efc488e4889300c87c5e70e35"): true, + common.HexToHash("0x113f88fcd616ef04c6d442bf4cd8afe6c4aa48abcad963d8b8c8c64252343904"): true, + common.HexToHash("0x17c01617a5420d3924f9e3a336a643dc8ac274cd749e2301fe1ca204b80f2ab8"): true, + common.HexToHash("0xc99ffb737f74c1784f7f701ee4b289eeecf5b65a0742db4a9d969b181771e446"): true, + common.HexToHash("0x0336714632727f8bfe908b4095b8cd120b224efaa644712a4249baf1d384c97c"): true, + common.HexToHash("0x4d60a0fc28fbb3ebc77be56a338f7e205065a3aa46021e7a2c8e3086a8a550a9"): true, + common.HexToHash("0x808ca8473c2de785a207848ad747f4c03d750157a4a7755871903f7fbdd453fb"): true, + common.HexToHash("0x37cd9eb12fe1060520f270ff02231a017b2cd7fe81eec718c21ae08677c8906b"): true, + common.HexToHash("0x7fd872fec255d247137024ab026a2fd652611fc3677258fd7f292b6f228846db"): true, + common.HexToHash("0x7ee7a7b39aa50dc8e1fa5ad8e0a57c0a856e81fb86f11d621b1ec80ff9b6c954"): true, + common.HexToHash("0xef20403328518bfafa317398a0de02bb75b92a491afb44a1aaacf4617e4ac371"): true, + common.HexToHash("0x9d7d71b1c220beba23fd4db589aedea133fa3f2c363a90aeeae689a5150b9720"): true, + common.HexToHash("0x38e14ad2a755e8aebccec14dbfb53a9c79bd1c1aa42db1c08ac4670b558d993e"): true, + common.HexToHash("0x338a5bfb8d0ca33373ad90a13b081330c4b9fb5117c160bc14977dac612610ca"): true, + common.HexToHash("0x80468b46c0f2d3af4f416009f0413284f60a477a0a4889da72d599a1ab42c378"): true, + common.HexToHash("0x6779d1b99ebd3a5d1a7adce9fe1efc7424dfaabb5a0c9ce5f55c29c1cc0d1d91"): true, + common.HexToHash("0xa795e49408d01a6dc54a09e7607e3a4618a0a96a9692dd4cb47225ee9b98451b"): true, + common.HexToHash("0xdb2fbbf03d0d3c1d7072c86d80efa3ef75e0b29f540a08e3facf2027ef0aa6e5"): true, + common.HexToHash("0x20c615a565d47992e4b57d2ce379f5ff11bee7b0d92c4890d7bccfe35e4018e4"): true, + common.HexToHash("0xada4e01f6dc252205484bd1050f16ecef45c54d046185315df8b3af1b3bc953b"): true, + common.HexToHash("0x6cea27ebdd9fb82140cdca5cdb9f0c4da1cfe51452986a0334a940b19a773fa0"): true, + common.HexToHash("0xcd822075bd52fbf2de236db94b1ea06d31046119b4b74ce5e8f0444c4f586b0a"): true, + common.HexToHash("0xa23e34ef4cce0633ba890f2c5ebed609fbc6c029f88890869670528e79fd69a2"): true, + common.HexToHash("0x71b04ac8db2410c337c1f04b33f6dc55c0db3aa2600134a047ab8ab4c1da05a4"): true, + common.HexToHash("0x374f5447d76e2dd9ed4063d84da9aa5311dfd97fa3e970483f0b98f04ef1494d"): true, + common.HexToHash("0xbad260dd15f17afc29809891057601b375bba605cb2a115449101179f31df0a8"): true, + common.HexToHash("0x5245ca655de784893ed3974e53654a55834d2363393092ad57aee3412d787ab6"): true, + common.HexToHash("0x1de474944901fdd110931747e43f2c0d33967ea1f5cb7e4f53707db1cedf50a9"): true, + common.HexToHash("0x7c531563695c1dc7592310819def633ebfdd393429ba1aa3e27b91e519d27c42"): true, + common.HexToHash("0xeb0b14233661bbb3ae8d2c06b322b7635234f83d947cff486d3d298beca3e955"): true, + common.HexToHash("0x673aec2fa3ba29d46fba44386ff80dc292b8a561a6c5f10d61f82ebbf261a17f"): true, + common.HexToHash("0x8b4edeb853425a01e9228bdd78c7e558a5ab4594258cee3a8b39142071f1eeb5"): true, + common.HexToHash("0x2a35f254f32a44a563dd29910210466b2c76d458a713c0046dcec702b327b887"): true, + common.HexToHash("0x94fa61f2b03181234b01f2bc69ed1e07d5013f3dd2964c742329aac9b8060c59"): true, + common.HexToHash("0x3c579472fa31477c54a5904072fa44bc003f0c8cdb289805494b340bcbee3f29"): true, + common.HexToHash("0xd35c346beb155765f09e56cff919e57c574fe918307dd81903ee844cc6b6aa3f"): true, + common.HexToHash("0x9bfa128850d21fc162008c2c1df31e1900caf9017350e6acba973a76c2452a26"): true, + common.HexToHash("0xcef611fb31a52965f821cc7778781461016bf1c4602c18421f964bf65120f3fd"): true, + common.HexToHash("0x2b8ff5160a7758d76d1ea1bd2abc8399266820e61a843750e45dd54639b4736f"): true, + common.HexToHash("0x075978ba2a8f41709ac803d2715799550ed7340212afb480846d4d239610e895"): true, + common.HexToHash("0x989186eec6ce15454a4d38623edcecd90680b8ee55992cf3cd1e1ee92d404de5"): true, + common.HexToHash("0x01b7b93d279c2e90871717f604bce032ed6371f70a25319fa5597e8900a6a15a"): true, + common.HexToHash("0x6c59e2494644b39ff2977116349d8eeba672076b0de0315991d5bca27fb2f762"): true, + common.HexToHash("0xed43f213c46b825693733b36cc924cd9c21d048e26855a7114803ede3c8f7f11"): true, + common.HexToHash("0x568618ba480d37cf8cfcd6a0290a67cef4c6b4b1d605178de22fda36ce67406f"): true, + common.HexToHash("0x3c10918e160f95ac2ca442a3809dc2ed82f5205517db3a08240bc520932504cf"): true, + common.HexToHash("0xa83965251569b7d6083be5d20198f7ca8dbae857f277a774dc65d666fd5c66c1"): true, + common.HexToHash("0xd272e8d1ee400cf020dd8e5271c72ba10f0fa40d62687315df4114bfa7682d75"): true, + common.HexToHash("0xc36b2afe391f962a9d0b7085e7695480d95cf797f0cd441c1e39b5c508b88604"): true, + common.HexToHash("0xe7e1889f19c23bbe253b424a437004e8d7c4651100154fc8f3d50121dcd82ce0"): true, + common.HexToHash("0x8d982edb99dbe3605073e69a492941ff44fa5d3c763eba61c20817e6dce1072f"): true, + common.HexToHash("0xe2af84411c6bef607d2a60c49795f7ed1509bd96709b9fb208c52575702044fb"): true, + common.HexToHash("0x00e70a319ac973ffb443da94e9285f0d7d0fd970f383938c270fe0b97779bb75"): true, + common.HexToHash("0x138c0f228a1893a3a57faf5d9900b6b0a8d40d17e3598833b34502499fc8086d"): true, + common.HexToHash("0x90de5aa1e07b1cb238a381d82f4bdfd6f82d662177f63ae03177a017a217c12c"): true, + common.HexToHash("0x03092d446e1923b004855c529dbd64767f185733ecafdb814ff06d39fef7f3ea"): true, + common.HexToHash("0xb75407203ce65d19b5815e0fc0f1f003f6b1f09b1968a718d96b1945b8187f46"): true, + common.HexToHash("0x69c132c4c94c97ed0cef5b19403ca495315903cb61b529bd8309212634bb60f2"): true, + common.HexToHash("0xee3f598a88b4d1558c75998b9a235e06d0a9149a144d66c92bee3ddcecad6e37"): true, + common.HexToHash("0x98530ce36f269e0677b05bf1793eaf04d0a555cf639a325a8b946c387fcaf6aa"): true, + common.HexToHash("0xab9c179f66b42d3630a42b6526a34dfac03266d2f5962b2a4518a81ee7b6d5be"): true, + common.HexToHash("0x8f123395ed5a796052b05dfd5eb0758e9f62c2673bfedaf1de680bad06ad3f01"): true, + common.HexToHash("0x062c1173c09ee485e8449520ed87b68f13de35c4b1261f724b8eb754c6bad4fa"): true, + common.HexToHash("0x6882c8c7115e7db0dc89e6b725dc932f06660f4cd2480adc8c8e414ea135005e"): true, + common.HexToHash("0xd4180d2de0075cfe55a51e7cc7938b80eb469c4d897ebdee32e06b9a37f38213"): true, + common.HexToHash("0xdce79d0de94e50fd598f75a62e34c72c36b46ee2fc7d23fe2fc814f5537e4c61"): true, + common.HexToHash("0x90175bc8b40a7dfb62fd7ec84cdb899efce3c7df7ab68c5db1414b2a7e514272"): true, + common.HexToHash("0x88dc12ab489a070f0cd20bad5f627fc07e3e1096b32a287d5439ed4460f7d6ed"): true, + common.HexToHash("0x6af9d44bf5b84ac80b13fd54d4c2ecbbb31a900cac25696cb7c185cda5100b86"): true, + common.HexToHash("0xcb16c0b0f3b01a7f75e35a76ea6a981fe94d08f3ac4686ccbdc9de5916bfd085"): true, + common.HexToHash("0x08dff0deaa594dec518cfca8540d8000473429493c405aaaa790bc772f29fd43"): true, + common.HexToHash("0x106f949742d0f1b6bb7b8763853f2931f704cbae3df35faaba42c8ef4eb770a9"): true, + common.HexToHash("0x85e7d209d844158eb3464b177cd1a362f650165eaa6afb826d0467fbb436b7c1"): true, + common.HexToHash("0x99323177e778eb65f0620f6e62b9d560d6ccd7ebf6536baf03783f47c1fc063f"): true, + common.HexToHash("0x72c6648baf9ac7aa8f8d2523bd16f8dab2df5fd6080be9c91ba2f83ff1401959"): true, + common.HexToHash("0x923388232cf032ebf91cc9880a892164f2497c971a1448490c39dd686dc7faec"): true, + common.HexToHash("0xdfd7461ed9b0f88c496807b5ab9b01991426f5d76aefa0c3a055d59541b2afa1"): true, + common.HexToHash("0xc3e4562e0d423b93f24cc364ee00bcbc69e08e447a32da710d29958418817a34"): true, + common.HexToHash("0x375602010b61a449e9032e3768b35d45fb157399fed2d7b18115445bd553c9c1"): true, + common.HexToHash("0xb21696ef24a7fda4352a1c7a0e4d7990a1aac36d37486b1a9947f42ca056180a"): true, + common.HexToHash("0x98129d765bd335b640056884f35264578ce2c17389c8b5597ccd2a6ca33cb4bc"): true, + common.HexToHash("0x67b9cb1feb33319a08799b3e53d6a2a61548687bc310841763283046131b69d3"): true, + common.HexToHash("0x25352339598ac1a71ad7bda76267d508af9021d954add582320b69baace9fd38"): true, + common.HexToHash("0x57784f7d8dfac1330ab1875cbf33f9fe3a873088f18dfcda5168e7cd95d0509d"): true, + common.HexToHash("0xb8dc608b3736c0e7113ea472137bc866f5d29f773d04f0b14234b97ab4d5b046"): true, + common.HexToHash("0xb1dc75fb7c797b3a99b8cb1be61e4f5226dbe91172402868fe22017f1dac4011"): true, + common.HexToHash("0xc61e35eb8dae1e505c0a9d921445729a62c2ad748e3fd0a1cd437df06a1b9c33"): true, + common.HexToHash("0x2badb1cf58a6e65874de5a87aec0338255a806a3a31b665ef985fb5429f5b55d"): true, + common.HexToHash("0x8d2163197beff8e7b6169f625ebd28faa6dd7758ad90c1950fd1e942c68ebf36"): true, + common.HexToHash("0xc34e771a9482249afefdec3b8d45eaf15c3beb7803593be31bec7311ee0c7821"): true, + common.HexToHash("0xd0e35fe3caa16864ad7d77579278ad847783d4bffde39844ad2fa16535b71fbe"): true, + common.HexToHash("0x3f2202b5305f38d8d3b6acb4e95e2b1a70115299b1c569890630dd28a553d424"): true, + common.HexToHash("0x4f670cdef83c023a76600aa591b4c9ac8c830c4671a307670f20666df17243f6"): true, + common.HexToHash("0x989b42b4c4da98724a09c8189002f4628c7da49d3a485bebae0e100f5de46d66"): true, + common.HexToHash("0xd4e9bd0ad6b23b39797680fe0cd67357c409b7da29d799c211110c7a79a15909"): true, + common.HexToHash("0xa6a3ddcc10b09b09b789ad07125f9ec52272d9baa51535d41add241d08f78c8e"): true, + common.HexToHash("0xbf7db62ca729ac56bfbc931a1627b924b741dd91e583700a050346c4dd3048fe"): true, + common.HexToHash("0x4267a8c16956a61e368bdbf3cd5b624882227b537dd767a66501c733e5842c77"): true, + common.HexToHash("0x78e5469866e21c441349c2975be4b02650e8afa84439592367b4af0f11a7a1fa"): true, + common.HexToHash("0xcdadb528829ec1966ca9878932092cd267dc9c1f5285520758cfa4008b4d9608"): true, + common.HexToHash("0x459df1f31d6e2881e3221ca545533f022fbfbab31345e97f1e9ff0a09a299fc5"): true, + common.HexToHash("0xf5fbac5588507e8514fd6bc5cc4f8e6e95cac11779ebb35a2955e553e393e55f"): true, + common.HexToHash("0xbb257332389e9585d498feaa55dba222e8f97e9b6569708cc4487c25e29f6bcd"): true, + common.HexToHash("0xf75e0c1b6b535fdd903b4ee50220ad54ed090827ab3ec4476831ba3daa487dba"): true, + common.HexToHash("0xb95ec2452d8c4422f9486a6426e6580676bfc1d027d78fe6eed029ffcb5c26b3"): true, + common.HexToHash("0x6f3f1f80e982a2a229d2463b0d5ea5d3949874f1a9b2add6db6cb0116448da97"): true, + common.HexToHash("0x94678def27619c6ce4362558df6c9a41283db1361620135003476adf6c6fdd77"): true, + common.HexToHash("0x221ede47b76a059fcb6e288e7237940b423941b4e984b5cfd58c36e119f3bc4e"): true, + common.HexToHash("0xb63530b9605747d789cc81b8dd866d4cd23873e6b4694f4782c0e74301a83f71"): true, + common.HexToHash("0x1ba283130ee401226e8a2cdedf9f2a5552465a784c76bfc8faaf22856fe051f8"): true, + common.HexToHash("0xdbe9f030cf69715c7292e3fde99019c32ad9007f9638d56f87c545fb32864e74"): true, + common.HexToHash("0xbfb743040870f487ce68211cfca91f5c4c8ffd11d41d3827f5d00797bdf6e15c"): true, + common.HexToHash("0x0aabfce7a4b116da43e79b2bc4e683bce855f4030924a9aa3fb8d09bd53b3944"): true, + common.HexToHash("0x7bbb5eaeb623174b52204c386441ddc86ff87c622d8bb66190df8e791754ff36"): true, + common.HexToHash("0x7d7fcad66938329d961892351482bcba29202a49f75093c61b33b21262cffc86"): true, + common.HexToHash("0x85c0580fc585c02e7c4399801dabe1ee7d5a52d1e629cb4c0b2bbdecb3e50d5b"): true, + common.HexToHash("0xe610aa8d62fe0b116673dfc165e3f6f693b14126661e2b6315e5ff009c26fb92"): true, + common.HexToHash("0x5c35b3508cd1dc50ebcb213e0e259713d945358449200a227673600b18e919cf"): true, + common.HexToHash("0x1f6f2f632de416b346a2b3ec16f583f35ec67805a85b9f2f4db6f0d1a42b2995"): true, + common.HexToHash("0xa58503775de01626934b51eaf74765088a7884471a3a1aab93d26298efed6dcd"): true, + common.HexToHash("0xf877eabdf74c63f21d1f5b1f0dcc17ae2d8493b1ba996e7b3cbbdaac6f7ec65b"): true, + common.HexToHash("0xca169bf75843f4f482e5440cd0be2f6fcfff7be440f9f379d2aeac951edc4fd0"): true, + common.HexToHash("0x05d0f6902b307d8f0c79fbf98f4591685ba7939f32960cebaadfe8a2499a4581"): true, + common.HexToHash("0xf09fe18d5b5c9a9854e55d536c99eef55e93db9df180424c49fc50c7842c78a2"): true, + common.HexToHash("0x2a3c1f8f836cd3944654b20b2c30ca8934f3e0ff224f57200128660e03d8dfb0"): true, + common.HexToHash("0xeceeb78cbf777312e2f832b065602cd813ed984553271c87f6d8fc98bba23f8b"): true, + common.HexToHash("0x1ccb766b477729bf59235bf000a95aa8cc99fec6a53473dea8cfb0a717b31b7b"): true, + common.HexToHash("0xebed20880411ad070e920556a232fa374145e389aab3ac4cd768821e1611dd4a"): true, + common.HexToHash("0x868e5f76d7652319444531749f83db75c3afe6a525ccf854a110afbe9438208a"): true, + common.HexToHash("0x365f30d5cfeab548cf167fdc3c74f46f184c1697bdb6d41689a0a1c75a9d966d"): true, + common.HexToHash("0xbdaedf02decbeef77a9e9d81820bcf3d46c8add635002f752f668c0be45b03c8"): true, + common.HexToHash("0x27bd9f7e76717a5505c3f45befd3746d595fa20e0d797874497435fd2b41f2fb"): true, + common.HexToHash("0xdda07d673b5727e46affbf23e3bf7c4418c66c6d8a63e3e6cb0c30763c8bac5b"): true, + common.HexToHash("0x1ea4ed72896c75185aee0c767ef917233c6e297a60955abd7e1744e179b0486f"): true, + common.HexToHash("0x10c0c1f877514072092b5cb8f90770113e5b0e74750bfc79024a4ba244cd20da"): true, + common.HexToHash("0xed80cf2f24615042c295b05768f7e5f2532fb14be54dad0ea5ee0499bbfa798b"): true, + common.HexToHash("0x193f4cbba182055a262bdcfd607db1539ffdbbd69ed907e5db13a4f5883cfbcb"): true, + common.HexToHash("0xea9dc01f5d8e0fdba5344e85bdc9913b0099751b7ba2f3b8c9eaa25175345ccf"): true, + common.HexToHash("0x6a8db659921dad617066e67d668523e29e1a8308b65744e7ff70d4b7555adb6c"): true, + common.HexToHash("0xd0becc49b7cab73775996c328294e95024b9c587783b53fa42e91a5f6fd87984"): true, + common.HexToHash("0x9bf10206f289f02d81bd3fdc228e3548dedb0e656e45f32ff273b7dc5a5c6270"): true, + common.HexToHash("0xb6b5254dc96f610769b305f1a1ba8180c189d787ef0de2d90241c35904136858"): true, + common.HexToHash("0xc6a544f1bf1d81af35c3d4f3fefb7470984dcaef2e8c857257066b3cc6598b9b"): true, + common.HexToHash("0xfa86f71df3235724973fbc9129d415a83749d6b32f8721afc531407e1eea84fb"): true, + common.HexToHash("0xe98da4bf8c45672e1050733e5074ff0256cdfd5ae883af309ebbc221ac85eb96"): true, + common.HexToHash("0x4e8d1b4bcf3134ee7f088b51a679582da9e18afa4a6bc8c4d59a6a45709a2c6d"): true, + common.HexToHash("0xbc8c80d8a845a5a7c119783359737274989cfe1aab90c5dbd06de8cda50fe021"): true, + common.HexToHash("0x42174add1493577c1bedcea7b941129d45eac3d7bdda758ffcfea5db349c0e2e"): true, + common.HexToHash("0xf5de3650453f068ea57cafd4558866ee06ac5f7fbd19eff4aacff89782b17bd7"): true, + common.HexToHash("0xb5d7784e6749615d915cea8cbf370a5fef6648aa67af4381eddb65e42276675e"): true, + common.HexToHash("0x62750ee057dcfa440f1db7efe24ccf2b2072581a8bda9dec0eab9fc65486b1bc"): true, + common.HexToHash("0xe2ae590e6a18d63cd6e7cb265bcd66338881c1d7f8102a5467b352dbe09d8c48"): true, + common.HexToHash("0x4a54a905088d5260641937414195f5534fe5ba3ade2a272949521cf38b514b23"): true, + common.HexToHash("0x5e569053ebaae83a94d3ebb16b5167fc559ec1963cbb23ff446c72657cb3032a"): true, + common.HexToHash("0x9a1322c2b105d3843fbf287c02fb7dabb8f8975f058737f5a6edb7673eea5b6c"): true, + common.HexToHash("0xfc53d1c5ef66f938def4a97505177b4c8f0b4a1cbbdc39bc1d430420ec305707"): true, + common.HexToHash("0x891c103c399f3573054b84527c0917913b8562a00deeabde702b9f3f1359474e"): true, + common.HexToHash("0x83a4eb98d61a4937a60cf809b9471f83beacf20c7ea6b5a5e70dce4b28697bed"): true, + common.HexToHash("0xb0502dbe268f81c3bec066276b1a034cfc693a448ad172520f989b0d277e7d37"): true, + common.HexToHash("0x6f4363f81d18c3d4e5c75e3495a04ef318ee24edbf16d80597f79ea287082d06"): true, + common.HexToHash("0x43eed3370ff7358f43a5de0dc8e6060b97a514513978e2f4a82cee6a40283f78"): true, + common.HexToHash("0x21ed0cd2b0417942d1a7752c0e15e78da406f7956038105862d986d175f3f948"): true, + common.HexToHash("0x2a90b0029468dd978babc8eb27854903367af7a64dcef9a95bad49296a20040d"): true, + common.HexToHash("0x4faee88d9e37cdfba6f61e1f46b838519db2a13c2afd8653d5a98b6f43dd351b"): true, + common.HexToHash("0x8424c200b0fd25bc3b3406e764ce3cf0e298cc4f0e44fb949c1536a728991fb3"): true, + common.HexToHash("0x1a136c93bbba6da920d0590c5ae725fbbf298481eac647ebfd9a81edcab7d7a6"): true, + common.HexToHash("0xb4f2a23a3e0fea1b2a3f29f1328caaf4991c342f615e18800412f2b665659bde"): true, + common.HexToHash("0x30cdd7e73d3e6f145f4eada50fe05b41c0d9afb1da096b8d9f710d408a7929d6"): true, + common.HexToHash("0x9f4cb25aacdbedd3de2a236ccb05765d7ff99ba65338ac9017232783576a83a6"): true, + common.HexToHash("0x4ed004e342452bebe08d2c84406fa85402bfb9f4e98aa3f8c8f932ea74777708"): true, + common.HexToHash("0xe1e122c952e50478dc1dbd431801e7e2b2399bd6a2f8a4051b77cffe91960561"): true, + common.HexToHash("0x234b4c3fd67bf99dcea338f388386cedf8748759c19a7995c9942f6b70072514"): true, + common.HexToHash("0x504fd9f9ab0812930033a3294c07155b126d082e2ed23adcb2aee90cf3e6aeba"): true, + common.HexToHash("0xe4bf6bedf099ceee1f8197321a5358feffdc7a57c90d758cf57acb1e7774b53f"): true, + common.HexToHash("0x1d34e1b003e8795859829269abd4851e476662e89d1e100199c183cde7f6ad73"): true, + common.HexToHash("0x5cb63d1b9a23e7aaee181132827be7772f1f55512f9f01f51c515b517cca29ea"): true, + common.HexToHash("0x4704e71794d7b96c379f5b1de24643c4459bac0262b177c08afa1c9270dffe07"): true, + common.HexToHash("0x7cbbc01f0605380815eae5f57b27abbcfd8968bf666e9ca23bd0550db6905340"): true, + common.HexToHash("0x6d3bb91aa227cd2aba7987588443a182dcefc7eac643fa95f7f4ea0f6d2bac5b"): true, + common.HexToHash("0x20b5eb48125a45fe70f247294eec465a7d912f5c0d1e87a546bbe16236abca59"): true, + common.HexToHash("0xd275a784dd79dbf6dacf71a48f1ee1794d9f6d9abec9abc6744bef33fb74ce9f"): true, + common.HexToHash("0x6ec519dfa34a500badc54b86e2015d60e89f7df0533d1e53c191ac6853584661"): true, + common.HexToHash("0x2a162d28a6f8d3cee44bee6d900280b5d679f08c9bc342f2dc775eef2f7e1bae"): true, + common.HexToHash("0x587ae57f57c13578a478050fba77f45de0ce4551814f0eff9539aacaf7c96e29"): true, + common.HexToHash("0x9a285aab859364d7dd7d708c34259fce8e5ccf35081d891a33895d822b95e02c"): true, + common.HexToHash("0x3cf10d5eef6cf5bb649aa0385f033d2dd95061e826f328abf1992a36923413da"): true, + common.HexToHash("0x8c6e3a80c5039f5d92597fd180ed3735493fdbf3fddca94472c87133d91be60d"): true, + common.HexToHash("0x9ccc01363bdbaf1f7c5d5ac1e70927e83dfca7d2736ebd420a7a8309bf563ee6"): true, + common.HexToHash("0x97886879de60d208c3e6f7a7eeef44ee3710f1cfa453c92fa8487a7f7c0d5b95"): true, + common.HexToHash("0x51a846ee978b222662d7846026f9671433ac84a30e3ce8035e16e002c9429ebb"): true, + common.HexToHash("0x9aec9ba0e14775b3d569aeb5283fc38f6fb181e5f5eb1537333dd258b373b854"): true, + common.HexToHash("0x5ac4021b077fbcb7998fdd445e23d7d81e7693b328dad89ed050d166fa931f76"): true, + common.HexToHash("0xba14a7db6a0bcc9eb9a5a0c917a406110f16a0c8ddfbe2c3958f14d6d77f9edd"): true, + common.HexToHash("0xbf760305b523897733d0dd74cfaf785d54c43a1b4496b1ff76de60283c764c30"): true, + common.HexToHash("0x74b430af08e8ffe6bbf14080ce399c038b0ba6c2a5473597f6ebc5c545d68723"): true, + common.HexToHash("0x5f8f07b207996f8156e89b4f620d0faf42df909354a210d9b39f4eb4de970ff3"): true, + common.HexToHash("0x0c7aee9ee16e91a9c120d3492f7a2735de2c2d06c684a8a2b0f1d4415e48ed9d"): true, + common.HexToHash("0x8f944192b743dfdb1b0d40735ae0debf26fb05383558668bf3fad9a83fba52dd"): true, + common.HexToHash("0x95ae5e104de2c0e499c87ccd328fc441d4848e0cbb8729bf1a6eff2049aca968"): true, + common.HexToHash("0x0570950987d9ed8a8a8c092e72488774fd8e21fa2aa7a7912c4a39e825c73e8e"): true, + common.HexToHash("0x914cbd98f25f73f62e83bcdfe97fe4f22a024d49c00525a0662819c7a8f7a0b4"): true, + common.HexToHash("0x3050fa5b66fe18379e98b4f6a4d0c668b267e325ac7784125859140a8d1c73d8"): true, + common.HexToHash("0x8bf269edd06a13c03c25cdd16d02ea9b8494c38241b13e33e540ff6bbd96225d"): true, + common.HexToHash("0x8ceb85a3173bddb46b6807cc99a1c3ec9b9c0e08962b2be20aa5a04d53f703dc"): true, + common.HexToHash("0xde9305338feba8a8a041874d7422fe87677ce350e629351a5b37499cbcec5962"): true, + common.HexToHash("0x70f2a4dae864ffa7b8c5090b5c49f964e31e36a2900b89a982a484d42722c34a"): true, + common.HexToHash("0x81a4b3aaaf44879cf9e930db8e75c43be668051b6d66a0e684928941cfe88a26"): true, + common.HexToHash("0x73141835b94b2360edfa739a171f79e54fd6721b92d6d223194d8042a7457b09"): true, + common.HexToHash("0x5558148744956dd602a6eba1cc466eb759cfc6318e7503c4c64f1f62e8796889"): true, + common.HexToHash("0xaf9a3cf966393d6e91ec411ac6ca78b3335c6f6c505bcc5302d2688c93b8fd04"): true, + common.HexToHash("0x10dbac9c82e8b8ec5761c4c3569961bb351f8b8ab44425a251590323a8966269"): true, + common.HexToHash("0xd25d7400fee1570c0677ea329c582d02aa23eded1b1670804313a4dc252c7c60"): true, + common.HexToHash("0xb625d5a0b483d754370baa11a7f26b1a3c9bb319d52acfa7f13525bd30d1bb4f"): true, + common.HexToHash("0x7047c423e87bbd0ca3e13727e77e67e7a00605db00d8ffb10d113e78530733a1"): true, + common.HexToHash("0xdf93d82a9522d22d7815eac8d7696728c37ecf156db05595e36b62c5fa5679cb"): true, + common.HexToHash("0x7fbfc1bdaa3a1418c6ab41436fdae2cb905ac382de9fb83cd83e0f1584d51f37"): true, + common.HexToHash("0xeabbe8be7590f300174848ea66bd6918776536b6befdd83110010f394a62ce54"): true, + common.HexToHash("0x44bf29c4183057038d9513eaff51c6d533af3bb7239451cb0ec0be16c5b9de66"): true, + common.HexToHash("0xa2fedd66e398ad2238ef89b82e67a691de496592a86d4e9f7d35b9bf4c68ac4e"): true, + common.HexToHash("0xe197f4988d8953e3ea59be311f02f83d1eeb8a6d91c3eb59dc3aeeaf3a1f76ca"): true, + common.HexToHash("0xf134442431b38d2cd904804ed4ec8186488d775b47ebf28153ade23d8e96df06"): true, + common.HexToHash("0x8bf61b407e0ec573e3c2b0b321c40e10493b2a39333727edf7b7492942fcd104"): true, + common.HexToHash("0xc65c986a2397facd06e014cad2691c1e6c050f7645436b4cec180ccb932f8661"): true, + common.HexToHash("0x25cabe7254a7a23db244dbb31c053df88cf609379923bb9de23dbbd9337216e7"): true, + common.HexToHash("0x3ea42e5d8ebaaf9a315f36c691aae5a7b1d989d5b1e5155add3642aaf8e19859"): true, + common.HexToHash("0xc97090de6c788eaaf174ec9f54433e609090bfed030eb7da808e70a3afaf3e03"): true, + common.HexToHash("0x92334dd6aa4d5c409354391e3a5be5cb858ad10e02922733eb20f4bd19a46f12"): true, + common.HexToHash("0xda3b3fc1205eaa544bcd0df5d9b3cb48e92fc86b75b673b16ebf0afb1a508da0"): true, + common.HexToHash("0xde43adb13a337d7b12d15029594762b55bf9180f9c4d0573a352d9689f0e67a2"): true, + common.HexToHash("0x443f30616f0edfbc5d5192bc523a89ea81e10eff4ae00629a3c4b7489785aba0"): true, + common.HexToHash("0x23d61781abe9ff955fc7c8b353eb7688c84aea9cff0ed703ac2caea44995d488"): true, + common.HexToHash("0xa42611351c2126092bd68b45b6b8ea035df9842bba4d63caa9bab6a446248fad"): true, + common.HexToHash("0x38d2d095ce84fb83b30bfbb805a201f5073bccca9b195a8b16cb022f63db79a7"): true, + common.HexToHash("0xb011e5d3f7cd648a115d8eba61cf19bed48e0f1f2ed53f1221656e985009053f"): true, + common.HexToHash("0x3f991f335e92eec83124636ca0bcdf3ed34358a4a49dae3c31698b51c58fa11d"): true, + common.HexToHash("0x8ca74ab8cf2d7d0eac268bd6b9aca8ab5552caaefe7f981bd3427461f0d7aa97"): true, + common.HexToHash("0x72c7c382e1c02375f19ac80d20d46769edbf54a2230c64b8a822fdcae07fc745"): true, + common.HexToHash("0xc5e11e3a231b387402640bd8210108ed835f234bf72e2bd079efd45ae5762fcf"): true, + common.HexToHash("0x52854d212d8e7b1f948aa7082d38409519249a1cd389954bb9efc64f85402c14"): true, + common.HexToHash("0x5b9a0a76c77121fef2cd4ddca998da120951db30d4edb64d559556aaaecc978a"): true, + common.HexToHash("0x56b39810346606d59585ece5edfa5af64c51d689a1d665944d18eb8180582112"): true, + common.HexToHash("0x33fdd2476b5d79ab1e50bc184aec5e29cf55245161cf0c2d54be2b02381b85dd"): true, + common.HexToHash("0x1c7b6019dd4268cb2f6655a4c366f409e10726fc86d31a40aa08b5e6e5e63320"): true, + common.HexToHash("0x3013c3be640d9323728ac07224efe55b141d6eff7aa0676a0119047f498bfa8a"): true, + common.HexToHash("0x0fb40463164229148901d112cf31ef4f3d61284b7308740d0a8641e2aa3f4345"): true, + common.HexToHash("0x7dbe13662d807bc5fd10e0124521736a009d1089dbab3723b66da48eff02aa76"): true, + common.HexToHash("0x4be49eeeeef9013789762324741b35301815077f88eddcf4c032076b2ef6df4f"): true, + common.HexToHash("0xd9143b195f1c23f8a461818ac38c2b4c36c20f8d1efd5fc3b8d815a8e40338dd"): true, + common.HexToHash("0x62d3cd9648d6760320b411c0b2b61192c7c8b2c63386ee69b3f8347de4514caa"): true, + common.HexToHash("0x2c68ffe4c76e9d7aae9c31652224aefcbf387757319ccafaeb4a86123a527143"): true, + common.HexToHash("0xdd2706eb8bf54151b7fd51d823b0c4602c096506c9861e04e7f7d54f376d78a5"): true, + common.HexToHash("0x6e82cf13be3758d6b4283cbb5a2e8fdd306c5936982ed35520ada8704edab3a5"): true, + common.HexToHash("0x567e0ef200abdf9a9ca85ccf147621ead1acb320ed6fc32155f39b0f792e1c68"): true, + common.HexToHash("0x44de004819e3570418a335357352d7439c81563df22c4e3e3e47d2875fade931"): true, + common.HexToHash("0xc95850df938e21a7bf64e808d517fd6df3c908d77d36d14278d1208bcfdf1b10"): true, + common.HexToHash("0x959642f518dbdbc51ca2e3aaa7d56b055959289b9099e60f59922369447514b3"): true, + common.HexToHash("0x3b5d2ae8abcf4dc3a8123476746e154cf056a9720ee7a76582a5a3e9fc96d864"): true, + common.HexToHash("0x61d2310f7fb3d2a173ab15262e036c726db6cf9f08d271e54e75564836e1be74"): true, + common.HexToHash("0xf2af8573eb7000559395e5e2ee242233cfb5dd151a300aab848a76e1357c949f"): true, + common.HexToHash("0x8e5ab6706539a1387ed90c7c8dc8eb8d899945bec2e28a51c7ec2a2d5aee3f5f"): true, + common.HexToHash("0x9a5f23d522e28c630a56efba199f63c400d394fb7af4d2d55428c4bc8776fc8c"): true, + common.HexToHash("0x6fd73941d72819594b9787e58d59a2ddfb67bb31fddbb9c0af76f083fd3cb7b0"): true, + common.HexToHash("0xf236ccecdc5e401581ea1e6ad45e8e6a7adac59de0a9ad1e7085f7fe3d49ff5c"): true, + common.HexToHash("0xba59d55f5c290604fb847c2cd591cbdfa9e156faeffd53946143308a1c45d7b2"): true, + common.HexToHash("0x4bf1528c062e1a9e3311dd6f975606a2f55f8eb4b76d4d9b5de1145fb9e1fb58"): true, + common.HexToHash("0x57566a381ee8a3df4799980b4d8131371bcada38831dc116078d5cc59fbcc298"): true, + common.HexToHash("0x224e44bb2cc8a6889f3dfbc42eb71147521f9675502ef3a6883a5219b7a81457"): true, + common.HexToHash("0x620e24e173755d1c5e03e632af7c99faa75e18283336a03a92ed3ac89301b1be"): true, + common.HexToHash("0x039ef8f09eab3dcb8eea9604c629441e7c524f319e300956695ff92b37393df8"): true, + common.HexToHash("0x32dd7fdca1bf738ad16304ddb191365d2677b528a50890bf5d85c5d0312d7a4c"): true, + common.HexToHash("0xdc34f848eeb41149f522cdee91f63e4ca2fd300d9af1eec0cbd5f7d14d034f34"): true, + common.HexToHash("0xb54321023270ed309ff94812c5b4ca5ce10c0d77d58d1399ed22373a96644a0f"): true, + common.HexToHash("0x3334efccec1729964458aa1f275b46b6a95d683e180d31d8e4067174173c2efa"): true, + common.HexToHash("0xabe302cd86beb188071130242be7745a60d6ea1bc6cf031db8ba51d3da0945a0"): true, + common.HexToHash("0xefbaca27266dd829dee84b1ffb9925768907071f525ff445c07eb53a4c72ec7a"): true, + common.HexToHash("0x6f753ff134cb96a4f5758ca90476c240677139ca0c78d84bf19a2901137763ab"): true, + common.HexToHash("0xd0e1aed32ec8debb9219eb47c4972f44154ead12ab2fa7488873f8e4ef5b0cb6"): true, + common.HexToHash("0x111051da78d01a3906ac26b46736602faeba6ed2edf211316e2c85f9723cf07b"): true, + common.HexToHash("0xc749738d1e28007305e461770a159804fd931ab5da035942d0c18e5bd2466ec2"): true, + common.HexToHash("0xc3b8fb78c1d03ad21eab4f04b6be0f9a28e7771685dcdf41d6df0ee8d6c2a71f"): true, + common.HexToHash("0xa0e6339c8dee5bfd68be368fa2be06425bcd3a34f98d720044601711d208989e"): true, + common.HexToHash("0x60e3ee14237cc265e4354c5a6df42d6b8617d81560e502b5ed41898cfeeddf43"): true, + common.HexToHash("0xff9b554983085272cf71fce8fb58fb71eaa1856df704a4903911e11d3aca6ab7"): true, + common.HexToHash("0xfda5db544abceb602ba3e7e4e607cc9f95feb5d03f357adcfb59e4c208c64119"): true, + common.HexToHash("0x9d80aebdd0fd19d6c8292b8141f16c2714bd65aa16decb7acd1d87d530b341ae"): true, + common.HexToHash("0xfcbad15b52cd62007e702cf658f37d8375e6f4fdcfefd4c07fe3af5c617ad142"): true, + common.HexToHash("0xb9562b6a5e23c5ac147cbbf3fc623eeb863b780f4eace900a836871c3d8e5da7"): true, + common.HexToHash("0x80917f38c978c95f9b3b6b9029e86a9e788fc6615312969b7eb4bb0a7255b355"): true, + common.HexToHash("0x3d14606ac505b07534d9292e9239c3b3ddfe8f4236b95d8221a2c8ce7a483fe4"): true, + common.HexToHash("0x7e92b22f320edde005451e1ba8afb8fb34ad50487f6acd3eb851d11a8afaf811"): true, + common.HexToHash("0x187352e8d550c7a827155326923d3cfebc1085db704756415fa1a712cffc25eb"): true, + common.HexToHash("0xc9e553449cb9bea0fa62e3df9b68b37fb9e606ebe1e083e8afb3e0e2232d1b23"): true, + common.HexToHash("0x469ffc266ef6ef9ccaa971700a552abe0d82e6a2c12334da1bd6d932b8dea357"): true, + common.HexToHash("0x67ed0f4f5829b4a19fa7c3ff43eac5e2fc5bfc28306c3df852c2ef0cf47c3dcc"): true, + common.HexToHash("0x404efae210d0db82caeaeeffcaaa0a1572790045335acc944b07b6acf256b04f"): true, + common.HexToHash("0xb1a19665bc852a5b0f4b447e9dde0938b0358162b44a5362a49d80f4a57e82c2"): true, + common.HexToHash("0xd19a289c5a9375f7ade975ae4ae5f3c1dfe8d641f7750c180e4c83f388565297"): true, + common.HexToHash("0x96288e3fc3b649aa026d2dc1f8f16c9ac315123cb72b0f6244bb3291730db98f"): true, + common.HexToHash("0xa003f686bb37610443bb7d7c11bbc092e76b23b01c4d2f95b546d2a15d242db6"): true, + common.HexToHash("0x788518ac4c44902f88694526607aff4a35345d027f1bd11acbb90350b7b327b5"): true, + common.HexToHash("0xd80823e0c4a7708476611d9910abd1d8cc8e8282f4834affb05fc1ccb174cde1"): true, + common.HexToHash("0x4657eb7e113baf05f82dd80c0638f0ee3fe06ddc19971cc771ed5ea7dada4120"): true, + common.HexToHash("0x33692e574dcaea8f965d80e940a1373c8381249659981ee8420d6558e98523e5"): true, + common.HexToHash("0x884521c943b7c6c09fd5b32741dc6dc9ea09d377a0a8f3553569d75608aabd1a"): true, + common.HexToHash("0xfe277e5ce5a5559b4da872176a2cd16f960645bb01a224e2cd6defc66fa3a2bd"): true, + common.HexToHash("0xb7d306d209417b32cdc10a83bc7df980c2df2b2069e6688fce2c2f0ba26ab302"): true, + common.HexToHash("0xfd33e24397dc5b7b9b17df0e640ed79891f2206af777028c6c3b446834747f56"): true, + common.HexToHash("0x259b3a9626b7970f80354f9af71530a7bea946162d6b4a007d9c930016f5a030"): true, + common.HexToHash("0x6c8b4fc41c2c1c51d8f17fc366418cd1d802a9b8380a5f1dde8289bac177217e"): true, + common.HexToHash("0x2d6970dc6c95f4eb896a49cb9c51cb99d8bcc8c56823b49edf3d0ba22dc2951e"): true, + common.HexToHash("0x662f34508cb98a906176f99d5b055723f605599d66f64676f8c353cb76d13fca"): true, + common.HexToHash("0x9e73ed4625077150b03bf3aa56f4eef3afc6bd91224115c49767f31b4cd847a8"): true, + common.HexToHash("0x94ffbd207d325facb236f2228fed6842099cd50465f90b36dee641fd1338edfe"): true, + common.HexToHash("0xf7159c576a902462c6c473c7d90c6dfca25317fe50263f36c83590b2881d6613"): true, + common.HexToHash("0xc07f82b364d381b7e6617c71eddbf1d79a4a1c1637efd84ee793a2313db44277"): true, + common.HexToHash("0x932917fedf5995b9bc5744937ac5b2f78a1e8c18b23d8ac9e91a8d58939e3183"): true, + common.HexToHash("0x8501040ebb19829991bd1d4f48561e898f176b687e1abc5eaafac91359fb1b58"): true, + common.HexToHash("0x1cf9124208af5ac73d96305795b0033cf6ff3a7960a0228670842c6d77e2d86f"): true, + common.HexToHash("0xbcbbad0fc029299251c955808c174e403e7f2a3d01a93e2368c69b3ff38b9c64"): true, + common.HexToHash("0x9704a099832c26933cfcf7899663fdc4c08fec87446a5154a19838f57b0891cd"): true, + common.HexToHash("0x51a872560878d3dc999010b951863fff0bd1847705fade8145e4f6601981fd94"): true, + common.HexToHash("0xda12f7e1710e1c52e70ce8c4f2fe1c2a4bfba395cb907a7b5cbcfe3a9d485654"): true, + common.HexToHash("0x0d7860b357018697322b17c10d7a3ccd3fbb9357422706cd7bd1a917ead94ae0"): true, + common.HexToHash("0xf76763b7d250301cdffa3459e407098b57c20904213df96f59e38291231437d1"): true, + common.HexToHash("0x7f58393c6ee9cb9051c600289a81946e3d8674ba24612f583fde53ae33cb0f91"): true, + common.HexToHash("0x720494cac0754545e62a93d03be1a4aeb49e50e6f71ad4f329d452efe15563ed"): true, + common.HexToHash("0x52c51c70dd974ca6130ddf849b90507b826834598696f6691a65ef407e3b42e0"): true, + common.HexToHash("0xe71e3ed25abc1c8908a0d4dab877396c41f833a2f216fb9a2320eb7986bcb763"): true, + common.HexToHash("0xf42119ad092f05805ff955885d8918018c421d11ec17fc9c004edf9254eba6a1"): true, + common.HexToHash("0x49e2341ea0510a0101999725522202a784d2178cfc8fc41cce5a33641d8b3872"): true, + common.HexToHash("0xd183adb7218213d7dab5b59676ff28e899b621b1002a6a0cd0ab9907635c114f"): true, + common.HexToHash("0x67c08bf8fe8bb6121b361cba0690375913361bed6eff27e7f2680f7efb76ad87"): true, + common.HexToHash("0xbfd8af5a40251824b10e69955090bae54a547ff4808085f653ebc92d3d370366"): true, + common.HexToHash("0xc41c5d8627f1d449e9d4982c388d572666ac729862145721794b777365897f91"): true, + common.HexToHash("0x555a0f7065702ba8b34b7eac2b3a33e9a51565bd7d95da7be51e0a9a6a1577be"): true, + common.HexToHash("0x16c94f6cec128820a3f88db5fef68e74fa4d50bb2d67f23afbe9f8b9a2bb21e3"): true, + common.HexToHash("0x14eb62a5175f930ca5b9fb9b62d5dcb16475784453395a12c302a836e865a3e0"): true, + common.HexToHash("0x164943f5c33f991b84d94a7450943917143dd9b53c2ef624d02b13813ddd2a0a"): true, + common.HexToHash("0x83249539aad2c317cfc48b96d7c1159b2dd3b9cad75c25e6cc2e23adb8e3156d"): true, + common.HexToHash("0xf1f6d54e5a255da7bcf2f1f6f024838aaea89a8c6987d41d19ef33e80cf4357b"): true, + common.HexToHash("0x35335e7acd9af7290ec00d930cb3fe9a569a831d91ac471d1f6b5c8d88ee8406"): true, + common.HexToHash("0x5a0a22185d767950a881fe28e46ee414d0c8c482dbc459210a74af4b3037b5ee"): true, + common.HexToHash("0xa31000057ea9d1fa917312c2f68fb6803f662e93717ccac45c4442e3a87b3508"): true, + common.HexToHash("0xcd7958406501e488475728f6168da5d19c24378e7e5f65a0a59f1411a70b9fcd"): true, + common.HexToHash("0x9ddca6651ca94912c73b45de2cbc40ee5d1f3e2cece964eb4f26a8e39fc86b18"): true, + common.HexToHash("0x91309aaa6e7ec5692d4968686f15a3d286416cce2f444cbb8ef6c43556c7b7e3"): true, + common.HexToHash("0x2515f1b694184dbdea3ad14f10617cabb5345b4e48fc0c1ae9e5bf7a9fdaa519"): true, + common.HexToHash("0xbcb9000399c3250b88c7c2e50158274a85915b3f8adb4f98043a8083e22e4ec4"): true, + common.HexToHash("0xd7cae49867ea80f04687b6a38fe6f0698e65f24cc5307041769a1c678c2eb28d"): true, + common.HexToHash("0x106df31ae4e175bb41bf0615efbcde4cdffbca008c97c40378b1bd944e2c8e14"): true, + common.HexToHash("0xa995cc76bfa9d651b1c269de91cc98f51f6f3d48b49c94181c1f37f69b62ea11"): true, + common.HexToHash("0x4b5bdf24f1de69dfe1ab79dc78f7406ec19d79e94bdca0cabf7f2d2453034904"): true, + common.HexToHash("0x3f15c2fcaf2242a7dcb54a0cb4609afc6b1aa29db5512ae388c04ef342515786"): true, + common.HexToHash("0x09a7a0e00c1ee23529b0cb7739ae454426756e3151bc471d8179b8123eac52f6"): true, + common.HexToHash("0x321c04eb8aec5e3de6a0d1ccf41cb490badc21931d951c0366c0e11820eea81f"): true, + common.HexToHash("0xb34ced8d310e51f9601fdcdb98259777e9b340f817d6a3484069f83cc712f3a2"): true, + common.HexToHash("0xedddec1602b9ab7d15fde2329c6712a9fdc364211acb9b221d35955f34e805a7"): true, + common.HexToHash("0x7293b2c408f4cf089530d908ef3f0dd4ad590630e99502b5aab0e2abce72e3d3"): true, + common.HexToHash("0x83874636e82088616e39eb7164b2324dfc6a6e03b150221a57a65ca988440433"): true, + common.HexToHash("0x83100cfbbb828ae9cd7ee820e0b1be744524482de545f0d9e93c1f61a90153c7"): true, + common.HexToHash("0x88afa3b39afb7bb275deb4e860860feaf639e9498afb70632d5277c7da7782fb"): true, + common.HexToHash("0x37f5bb627216de64400b3c9a1a72c718da6bbe7b5da56b082ab7fc0139dc7635"): true, + common.HexToHash("0xec2fe14edbeab6a8f8ade1d2802d0997ea8b75756cbcab1cd2fce490f53b9378"): true, + common.HexToHash("0x9a6a4c664df08f141091a0bfbd75eb714147aec524fa57f5e604ee9ee205e1c0"): true, + common.HexToHash("0x9b84364ac92924740e4298d69e6c3f6d58a7de9c57eb7ba700da706cc0cde3dd"): true, + common.HexToHash("0xfbe0dee28712fb8fcc7f9d50d7436dfe0037ce953459e2ccafe83cf289e3e201"): true, + common.HexToHash("0xbe4cb7a0ccbf0b1fbfd566a512e1d70c702cb616a10cc65f5b383d9c3a800d55"): true, + common.HexToHash("0xce3bfe58b2fcb85fd150ebc36b0be81778a4f08b13014a650f43b165aa9a61f8"): true, + common.HexToHash("0xa832662ccd538a5eb00f45cef93d5d57d036b93822076ce91863ce357353a3a3"): true, + common.HexToHash("0x286a0db0f171c2187586435b1e07be6d34911078362d78a50a184abfd5b6b0a0"): true, + common.HexToHash("0x3cd5db0e2f7218832a1c8bac060e383d34314716fe6a681d0e7d6c74d583bdef"): true, + common.HexToHash("0xbc9b15652aa324cd45d6de4ee4304c3e2b14d5938b026891f070f18f98d7d298"): true, + common.HexToHash("0xb921a57c6635903a0c4281b0ffeba49ac5ecb85e3a7c6b4556ef4741081fd0d1"): true, + common.HexToHash("0x8a1cc500707d005d0454201db6f5194b2c458534946a5aff9f63f7e0edafe71f"): true, + common.HexToHash("0x80af323924f8c581aa92453bc5d83884d3147e685214f2cbb881102f627fa2c8"): true, + common.HexToHash("0xe3c8f702183bf419756135593390b0c2d4225787054b7d6862c390de69f6cfed"): true, + common.HexToHash("0xc11cef72ef2da5b1584f0d7f4ee093d42c7139684c88870ffff6dd6ac30bdcde"): true, + common.HexToHash("0x711e92e794466cbef275167b96f0e505458756485f1e53daba4fa7bf897019ac"): true, + common.HexToHash("0xee514070dc328eac7e5db3d73221ebde4f6924cf9ca89e8838cfe651c2bdd984"): true, + common.HexToHash("0x9b67a82aa6e4bcafc03ba4511898a652a0ee56101a7f300f639231d6f66550d1"): true, + common.HexToHash("0xdcfab19ae5b3243e5534b4195d0b83db01179f8b3521c37b0c91e9ffc09697eb"): true, + common.HexToHash("0x4c222752dec9638d57d6a44c9da0dfe9581783111d01a105d1ae09dfd1f3211e"): true, + common.HexToHash("0x2dafc9caaf5675352b117b344d972a37b4496d4b7d6cbdf247e04a83f6c803ec"): true, + common.HexToHash("0x89034847e4a8ca9160e8386abf5d1d0773be76527bb8cc057b5f7460df2c3dbe"): true, + common.HexToHash("0xb700a81c67e8e3b4ab0cb1d2b783b3008edc5a1cf0206b0b4ba5de5dca97eb32"): true, + common.HexToHash("0xa2ba96b88ec5d6d17d2bf0c4b12f5444ecb29ad43ad28e6417879a123f4e7bd4"): true, + common.HexToHash("0x1339593eb97d6d4724b25ae996131b4dcd8b8ec4111c277e3ffb06cad871aa73"): true, + common.HexToHash("0xa2f14dc72ddcea6099328f5c4f8c446509f6b5b6dc112edd4bef80955252a1ce"): true, + common.HexToHash("0x341eca98bef7b6488eaff86e610530e8270fa4e95b819d28686d0d5e4227da46"): true, + common.HexToHash("0x7034a0cce3599d88c507962bb11e6aa002f25c7b1c4ca1a0939d073ecc68ed90"): true, + common.HexToHash("0xda7c8270fb15be173819099f933156fef05d289d3a70103663071bb3ad6ff4fc"): true, + common.HexToHash("0x55c7d5ea33ef19ed0b2c8040cc57ecdde6670489d3d714c099744053278cbc67"): true, + common.HexToHash("0x6ddaa8dd46b588d49392c99f87bc8b94f4ad23121ae1fd3c3ad4c8873908e65a"): true, + common.HexToHash("0x20cc7790f3c6ade7f4ac7269cfa33cc379a6d334733f331d4d309234e8800356"): true, + common.HexToHash("0x8b014ab865bf62c95413647e723850c0973ed0e0f82d36475483a4b11aa2e5af"): true, + common.HexToHash("0xb1021832b9bb783dd857f04145a69988c98c091cdf1f68cf109c206371b74edd"): true, + common.HexToHash("0x791be6e51266acde14e912ec396537d8316b65ffd504b0bdd44f125d6d9db693"): true, + common.HexToHash("0xc116169fcab472bad3ba7259689677503208506343ec638f289c02bb5e905b41"): true, + common.HexToHash("0x43822e13f317623e35d534f12da8a954002a068a951d4bef5e9ad0dd0368c49e"): true, + common.HexToHash("0xe0bccdd9777781b07ada55216095fd60075d799612dedbba6ca0b222d7047b10"): true, + common.HexToHash("0x8bf3fb675998860126f4714dfcac337d138afd3d9ea64f8ae554d66a3bd4ba05"): true, + common.HexToHash("0xacb4e259206ce705da48258b2cb2f749dcf254bc2d103a9818af305526bc21a4"): true, + common.HexToHash("0x99adfcab66fc28787775e3a8b4947aa7e6b687ca328fb92c1705851a5eb51f22"): true, + common.HexToHash("0xf36b2bdc5badac1ee2705ef3d7ab779c0bc1eac77e0bb9bca61789cab5b07887"): true, + common.HexToHash("0xfc7cdaa59f77b0757aaf07f4fc13511255d9c432ec18a3461876da1ea462c49b"): true, + common.HexToHash("0x22405646094523b95f39172ff15acc00eb42bfab1fbeeb3f8a220503e461f25e"): true, + common.HexToHash("0xc513d1b3812633b36e0805de82d24d72dfe7072ec4784247433072030a94ce96"): true, + common.HexToHash("0xabb9cb5ccf0e8e8e686f98458ac7496394cb224365af6dafd94782f069a6686a"): true, + common.HexToHash("0x71b2aeb78eee0ec9ed2481295213a8e925b59a1dea64ed46616305c738e76f4e"): true, + common.HexToHash("0x2f7136e8b4f4eb693f99ab8656b2208891eb25fd16b7e67fe03b1cb9d1e012dc"): true, + common.HexToHash("0xa67606a294df641121c07513753e91c118653cb11bd1086f7d6e917e350c52f6"): true, + common.HexToHash("0x839c2dc31ea97422acaacd85ef5534da0a68f9715087c0484a8fb594ee54d33e"): true, + common.HexToHash("0xed2bc8e61bdab0fe68b23ab8ee39e8e5ed9a22a0b63b662a7fd1cb0f0110a514"): true, + common.HexToHash("0x3c25eceb25bcfc6f74f4e277459ab6f82572ddc162359c87df12b084864aa573"): true, + common.HexToHash("0x500396ef6ea9bff27588458fda9bd7751307c67194d803f78a8ae46b13703250"): true, + common.HexToHash("0xa10bce3a240c689e213bb72d84d70b885b089b71bf0160e727d982f55bbe037f"): true, + common.HexToHash("0x75c72adda82b9efe40ce307f9fe56a075b91a79eb269dc92d839e0fc32ef7f8f"): true, + common.HexToHash("0x671f20f80a9f680a2e33a6648c5c6e607d90e6b59548341fb8d11601b158928a"): true, + common.HexToHash("0x8dcbb11652a9ff3cd918876e500e438f7a415ce9b3e76f575378ef621e48920b"): true, + common.HexToHash("0x33350c9dee80576f1822b6f404637bafb5514fa41a0cb30e2f038cbd0253cdd5"): true, + common.HexToHash("0x65cee10584ff80c79c86938f91e5801b0273bf0f403e5160d9a7046f96fb6669"): true, + common.HexToHash("0xfc58a0e71716ef88b69fe9fc215518cf44dd325544fe8b78926f70290abf4d60"): true, + common.HexToHash("0x5fc99f5b33fea99185f4ee137cc9ab019aa90a33f9bae61c6c1b1bd694dcdea2"): true, + common.HexToHash("0x7388d2a182d061b8f75df700e3840c653f6930a506242b6f31d80d8a7366eca1"): true, + common.HexToHash("0x905a595ed6e3a921d8eef5468dc82469ca8731e63834615fe25718a62e51b6da"): true, + common.HexToHash("0x4b748ce099d23888fb1d2761ec1c69a5154e537cb62df7b297de674bc289be52"): true, + common.HexToHash("0xc0c12c86bfad27d386cbd6c69ef2364bad66e3fcc66c2e97e720f322eb6d42c4"): true, + common.HexToHash("0xd5fabb4965ab7e88a4f51f021fd9c94f766e9a92991d6788d9486623defa286e"): true, + common.HexToHash("0xaea0dcf4b115aedc767a2a1a01eaadbfa861a97b6f673351a07c51ee0cb0d9f4"): true, + common.HexToHash("0x2dc0dc5fd66341011038f9d050d0c7235dd92b2e8694745cb1d126fa403cc7dc"): true, + common.HexToHash("0x5bc85354025d0d7427c5912bec348053c774ab0dd6c0c995dcbc9f51455e9659"): true, + common.HexToHash("0x76e327ba09c42f3c5d6c0e2904eecbc06f651bbe6860fe3ca81226bdf41ec380"): true, + common.HexToHash("0xba9955178a576f4b19c4bda347c4be50eeb1128d211e20840b501652e1f235e6"): true, + common.HexToHash("0x0ab1f9425099cd4db700b400cf20979e8d8d0114e5d6162591e50a5029dc9330"): true, + common.HexToHash("0x8401da56ab5626f401e0be187e69ce3bfbe51b7bc7a5a97579d0dcb4a8a685dd"): true, + common.HexToHash("0xf23e63884e3f4e8877c56987dcd98e586bc02d5eafa61fe69db3c22b43b52715"): true, + common.HexToHash("0x98f3eeb99cfb6aad270720d7eb66f99804c8e672eeb587a971affb17d9bb5f58"): true, + common.HexToHash("0x452567dcb7fb29dfc5fdbaa13cd82a3ee31243faa8947a261176acbb7c51fe17"): true, + common.HexToHash("0x1a588d0284b7f08d4339b05dd75ec48547465d895aa609ded1078da979b2ccd8"): true, + common.HexToHash("0xfaa2e31efca2b6de8589da9fdce676d0438b4237bf28ca8e98c27ff37a3cdc00"): true, + common.HexToHash("0xe8d4b0a7b65b6f5665a2f9a6e4670b36abfa82def06b4b81107e346d0c86ebd2"): true, + common.HexToHash("0x138d7846f653bd5df6e13ad48ec543d7e18dc50b457b4f8259b71b8966375c41"): true, + common.HexToHash("0x5439a65a5c0083311934b60cfd2e3abb7f229e87a6b17a7b24a601545b421972"): true, + common.HexToHash("0x4da33a31e621995f9fd4e24abe1d4323f2902df9364800985f5832f2fd1f2630"): true, + common.HexToHash("0x0d0640a61264ca142a13723ba302075a62c1543ab5a76b21d1af3229098d9e33"): true, + common.HexToHash("0xf87831470044731e001adb4c7552050bd49ed44eecec7e782410d99ba2fb5152"): true, + common.HexToHash("0x7c0c3319c51999397b978f3c36d376060252e1562ae20cea7c4a7e2ab91e1b42"): true, + common.HexToHash("0x6df6f3edf3308ca558a4f09a184fc47eaff26bdd10de42de4e6e67877c0e7453"): true, + common.HexToHash("0xdfe58fd1ab8d02a76dd39dfeddb00b935c08137d2b70c160d1ad535c7a0d8897"): true, + common.HexToHash("0x90d5d6a446e17139ae64202ad4cda65f5ae4fc8a011c01342a5e7bdd37cf7ba2"): true, + common.HexToHash("0x49c247808605d2b1bc3ac77f6ef21c008e318d230da47565a20c324547f7312a"): true, + common.HexToHash("0x09e84a97322edcb893957dbd4e0dbd95108cd0c8cabf6cf29148fb7756d57a05"): true, + common.HexToHash("0xe2c10ed3c46b46e41ddae76169e4445dfaddd9f2f636103256c3d6647e040ece"): true, + common.HexToHash("0x96dfe19ce78290efb8425746ed67d7b3780c8e71a3251935932478c60214ed28"): true, + common.HexToHash("0xe6c82c374999215a8abf1f9daf67278c0b0cd4d3ffee2a99453ff4f638c26c82"): true, + common.HexToHash("0x276605e9cbb8ede894b016f678a47c2371fcb7b3b795042456f30ff19a71e84a"): true, + common.HexToHash("0xa053d73b1f47c0c89b85639ec96ee196131c404a38cd49cc4446026eea47b14b"): true, + common.HexToHash("0x4e4f83e99fbc2befb35f01b55b6d66ab0a5a0dbb8d528e3deeb9e9f19e68e6e5"): true, + common.HexToHash("0xd560e4283453290f44cc5172abc9e1f2aa9dfc23472531dc0374553148fec401"): true, + common.HexToHash("0xfc42aebdf0c74170416e095df9310f72b7a1d852fb5e8ee08aefd110b59de7ea"): true, + common.HexToHash("0xe5a604705853452a458e2d4b734ceb07913e36361c9efa60e16ad18e1d2dcda6"): true, + common.HexToHash("0xd51eaa775b34a7e4e2bc0afee1c0e6220faccc7d8b3e3acf530694f2fa4b862d"): true, + common.HexToHash("0xdf421805d03128eca627fe5d7f56648f14a944783c1af73f45cb775a7d27ba48"): true, + common.HexToHash("0xbc031efa05e33abc0d5b25c0ba867a00bf05346385418d764fdeb64322717e9d"): true, + common.HexToHash("0xa68e76612ec793923448374bcf8043c8d10b0dafa0738629a7906bd07ae32139"): true, + common.HexToHash("0x777c8453d3c59364fb78e57f4cfe9471a682d6089533d6104d44209f6f492002"): true, + common.HexToHash("0x8e12eb1c7d368078e03876ae76a52f6cf92bf3f6d58c174496c80d6939004567"): true, + common.HexToHash("0xc6f049ec455afa8c3ace23594885f6c0f4fdfba2db603ac01901978770768847"): true, + common.HexToHash("0x60b8d392b5800c7ef839141673383eb15e99b872c40d11efaca84240a25a0045"): true, + common.HexToHash("0x0a34196ff701a58467362fb3e462d89ee0e1a5805dd171b6b70dd7a3e08873e7"): true, + common.HexToHash("0x8d482f2b2d079e267ff0d102530d7a9cbd23763cfec5d31d4cbb5aab91face59"): true, + common.HexToHash("0x3ff17d6832a022f3dfd741fe03fb474911f0c33b6375979c3e05e03e769782e0"): true, + common.HexToHash("0x1af13e8f3bfaea8468c8e824e0cad14d72a7558583a766b0c055437fe7f6f858"): true, + common.HexToHash("0x17d5188dd7defcbcb1b187f84145b29a85b8b8f7253b3c8f6d102175497c9785"): true, + common.HexToHash("0x183e50a974f010394f020a49b90f94619bb3edd9e72b0b1d5d24015e1777471b"): true, + common.HexToHash("0xe782f7813fd956f5ced7fdb6174257e14c9a1d62d984afd7bb07c31166153a23"): true, + common.HexToHash("0x4a94db52dc7920fbce166b60f3377bc7842ecaac8aba5e72852ad4ba93b0ab95"): true, + common.HexToHash("0xc04fb55d2109640b4f4c8a45c9b9a651f6860129debf77d416c675f4b7f20080"): true, + common.HexToHash("0xa433807245543c9996d4490285ac91048dd0b0e7c10dcf1459212ca02b9cf209"): true, + common.HexToHash("0x511b23dbdd537f7d89cccc76d663f75ca44873fe4116ffc245f2e09ec0cd7dae"): true, + common.HexToHash("0x09fa20bfd1d637dfed699847fb491d07d31cd87550412ba17d2e24835eeb9ebe"): true, + common.HexToHash("0x2920993cdbd7d84ef7773ef526cc38bc4f083652c342c652b7832d4f35a411aa"): true, + common.HexToHash("0x03e4b30be2b722e818bc5291a1e53d84fe62e6d1b64429ed52ebd172b845a24c"): true, + common.HexToHash("0x6dcf1d1e075592a5f7870d26a576791b5330fba3f0b49c8d11f91b32770f64f8"): true, + common.HexToHash("0x0ea90f62dfbdbed0e7d639143eb0d1bd7cd2a25922a7717fa6f42e9f8d9c56f7"): true, + common.HexToHash("0x65e76a3376c77b2685c22fa9091f763480a7cd4d60a3438a9435c5a5a15d60e3"): true, + common.HexToHash("0x6f5c06acbcbeebf6f54dc24aafdea454fb0704eb2d3445ec4fb411fed5db6643"): true, + common.HexToHash("0x5a01a6d5537d8839f3dfba38fb75f540dba4a44d16c15bb06abab9b8cfa5bc5f"): true, + common.HexToHash("0xfe2c8415090b4e151ac5e261cefd8bc95f438b18a564bc33155216835ba1fac0"): true, + common.HexToHash("0xc583f10dfa99ddf80aea54105e021b581a6380dc0e28b2ec1dd3ca9232d5003a"): true, + common.HexToHash("0x212945ebde4b2d8e0875208ca943a84fc499381fa536aea565d7df192a437aca"): true, + common.HexToHash("0x51452407a098f216cc9b2cf49e8a87e9b1d11edac5c388a30d892679a5ba07aa"): true, + common.HexToHash("0xf2bd9e55ed8a35ba8391c571feaa70e6c195b5c27d373f7093f29719be31b1ee"): true, + common.HexToHash("0xabb162effd1ce63a814e62383112ab3b47feb9b124c117974cdc6472af2d4400"): true, + common.HexToHash("0x85de01b7ab44f54fe036ed22b9018762f06f1148028cbd91b6092e2950c9cef0"): true, + common.HexToHash("0xa46a8d1beefe543c4c9a11274f7ec099359eddb6ca32d553645c650581e1f51a"): true, + common.HexToHash("0xae3d2d0eea6fbb2fb6587f68e89252729db9b26eaa558abfa0343727f3460637"): true, + common.HexToHash("0x8ea4c34b3eec148438653be298321525619f2f1902b38c2b4e27cefdeb923510"): true, + common.HexToHash("0xa24d3e85f936e89e3065ed0ff938aa78acf66711046d0be28d2401ef52479ed6"): true, + common.HexToHash("0xd1a15f0a6a7ad7373104433db49157291d995005a54caee445af56ebaf67adfd"): true, + common.HexToHash("0x42144c05194f739423f93f559f83540c9013ba64d500a63edaaaa881a79f5073"): true, + common.HexToHash("0x67c6725c08ff647e24f4a9d09fa05ea5c88c17ccf9959160ed256383735b37e4"): true, + common.HexToHash("0x5fcf9c6c166c895b63f69e48a6883e554257b9ccd8e32284f28aaee344c58647"): true, + common.HexToHash("0xf8d7d550d2905cc942b1caa61e161cd99ae37c94857e2a1d29211f77792a11d2"): true, + common.HexToHash("0xea354f716d3fddd7fa014985b3366b91157e6e52950f913ff793476b75016d8b"): true, + common.HexToHash("0x0ebd94ab0327e2ff327ed87e9d624489da9c3d2dadd430429934dd4385caf0a1"): true, + common.HexToHash("0x65dd0579ae88a5fed5c8642898d8f86d99200d08b0aabb43b7c6d41d72cc5c67"): true, + common.HexToHash("0xfc59aeb215d49a7d7e157eadf00b470f4861e9e3936ae457645e27757fd145a4"): true, + common.HexToHash("0xcb19004ef8a72811b87530ecc354a58390bda2c1f3217d04c0478d76d2ea722a"): true, + common.HexToHash("0xd7f009a3060438d06620c13f5007a167c8020c113efcf59ef42dc511d3eb096c"): true, + common.HexToHash("0x3ed07f5d65c9fbf8ff2d142fafa3033bb26f65b6a2eceb9ac93d589ba46360d5"): true, + common.HexToHash("0x05cae351fe8038c7c76b8900c4ba24278c6fdf7654cf5871c53cf97707355f50"): true, + common.HexToHash("0x28ac8fbf41ffdf9504e384cf452d17bec3c62d7b4b21e0aa0cd175205ce155c2"): true, + common.HexToHash("0x3164ac0c70c0d7436e816cbe9aeb83456f1c17825479718a598fca3096df25e9"): true, + common.HexToHash("0x80ce5cc70b32d842f486d2c787f6cb9eecfe2c72f2e5297d0918050005c82e05"): true, + common.HexToHash("0xf1ffd5ba14a8e5deb2531872480855d5d4527a291503035e540ae18c3631f452"): true, + common.HexToHash("0xfd7de7be49a1f566a97ea0e033ff38a119228a4fcf061a6d37e91e794dfd57b0"): true, + common.HexToHash("0xf31a2a65c385dcb93b4d83fdad399372fdd2cff5352df97386cb91e41c98d352"): true, + common.HexToHash("0x4f7bdbe294d2a36f3c23bbf762f031ea65a999d30881dbb73e8b682b51c93a18"): true, + common.HexToHash("0x2d55895368cbd8c9c276e82c29aa50c85c002141cbd02bd879a2735a70213553"): true, + common.HexToHash("0x01493599bed67798ea27be5aa24f1116589361bf1a51bfa71f3f16a7191681d6"): true, + common.HexToHash("0x44ab0cf5c265c78d7f67a2d24a649e4a9a3a56793b328bd2b90bdd9e83596b9a"): true, + common.HexToHash("0x1742592c743c2fba6a7b1973e5c87d5c1dc1852dab89c72f18e1246673b62fd2"): true, + common.HexToHash("0x0e49ef939ccfc571c40d2c4f795997955053e63e4c11e44459e2aa23d810ec4e"): true, + common.HexToHash("0xf40c8ed8483030f77b72cf9592e792ba1f7db07e40f4da34fad7a51ec64c21a2"): true, + common.HexToHash("0xce5dead7ce1f123f866bb5cf040807ce3dc273a7eb0c0c71bbcb6ee0ee334348"): true, + common.HexToHash("0xd17740b7945eb70559226fd03db5c464b281f7772359b631cf0fa9f11b96e44f"): true, + common.HexToHash("0xcd35c93932ff0975fb129bb3d7832555afccb27d9f58576adb772c9e72a16dc0"): true, + common.HexToHash("0x6da9f21412aac27fb08e57089072471db3cb0324d2cdb6047a6c30388a5b6f3a"): true, + common.HexToHash("0xd4506c202bea6ff7694c40aa86f5a2c401ca2cafee554ec3cf9a0d906b65a71c"): true, + common.HexToHash("0xed61af2af94d11023d95c602cb90da63d256cf6f5c15bc06cd620e48fa80703f"): true, + common.HexToHash("0x1ba975c0d2c8abff2eb5cd80f36fa7c8db331c7dfe2a39e1023ff37b5dc8c6a4"): true, + common.HexToHash("0xe0eef72d1ef27cdc6671e126f24d3c26bfc5dfe50306f46cd3cc7fc9a2179169"): true, + common.HexToHash("0xb614b2848389c429a334a3a19e38c18b7d55fba24978d949c7fe8cfdf2e7d932"): true, + common.HexToHash("0x99e97d4abf299e7fd3ed470d8c66d61df134a8799a6a8cf422d47dc564e95c97"): true, + common.HexToHash("0x79cda9c803ca63d49040477da69ccc094c82c4a79ddc1dd66e45549ba007120b"): true, + common.HexToHash("0x51a877374c4ad5f1c92a9c437691439859d08e002970b3147dd875ac274f1048"): true, + common.HexToHash("0xdbcb96c4dd428f6ec5fa9d8af2095104f249b5d2f5378246701c9a0011b4a988"): true, + common.HexToHash("0xc8a705055a74a7c015d7ba31801ac5bca519481585b6215f143c000d7856af2f"): true, + common.HexToHash("0xb05bec2401b88ee8b7b0a100c5f256cb0d039d51633697374abf96f7ac76db30"): true, + common.HexToHash("0x570b93d2b665bbf02893c1b777ed73edcf76b436be0e387aa7ec9be1a431d83d"): true, + common.HexToHash("0x44cc01411cf825e3d26ddec50738120976c08247a2f46be384e8653707132b32"): true, + common.HexToHash("0xdeb1c36e832b2fa9a41b1434117e5f680e2efd9b99d24d8dd125804152ea844f"): true, + common.HexToHash("0x8fee033e24560cfe5aa492e5edfc3b7a7d2348ad92e3cda19f2ff9606625433d"): true, + common.HexToHash("0x895b5dcffdea36bde1f8e10da059e543579f21fd5f03cd5c75b63a38892db162"): true, + common.HexToHash("0x1c85e5b81d3459b21cace757fa0b1e5da125f2123e10951118fea00fe47be4a2"): true, + common.HexToHash("0xc3cb9529858ff8e6f8957e11389164a43ac3949f260c81633f0c81b103498cca"): true, + common.HexToHash("0x402663946ef87682c80895be6da64f4288524c696a52311f1893a19ed85a9a9d"): true, + common.HexToHash("0x917f00f262fbc480c1f097d812993194ff79cc63d55fc0c64476a9dccf13f5e5"): true, + common.HexToHash("0xc440e9fda75e9ea4985d9e72cb066469ce9ee706f561a32abc94e4b987a0dfa4"): true, + common.HexToHash("0x09d2ad70d894e3d6c364242900e901ff0d19d48bccda9983679fa9f8a9b3cea5"): true, + common.HexToHash("0x1ec6f3fb06f30117b2b714f8b9577dd369f20a5dcf17bd3ae73e59381b2b0fd9"): true, + common.HexToHash("0xa628eed1675345ce4ebbf4831cd8aefa03864fd4f3581590c68cfd1f0d62c83e"): true, + common.HexToHash("0x42d219f0f5882a6064d9d0d6d6db5e1ae5c9c38554b9cb061806386659daeb24"): true, + common.HexToHash("0xed9edfd2b2284d122f2dba2a5030795ddbbe3a424350fd3da89285372606bc7f"): true, + common.HexToHash("0xd1595cde50678679bc49d0ea3a43def6ea6465d3dfb57b30e431fd3faeac7de8"): true, + common.HexToHash("0xae7ce046d7c9402f42ed25d06e9df9958a015a6f5a0a614c11fdaf2dad390b57"): true, + common.HexToHash("0x09f251ff59a1650e2b59e3a6474c10371e0cc3bc32fefb6b9b24732c54b280ef"): true, + common.HexToHash("0x80b5d979ced91b103a3f87a6cd21550c413265803e4530932e51a3c3a67f50e1"): true, + common.HexToHash("0x83e3fba42de7e5e697ade59a35d0d55ff029eb4c71ad28b2a4f55030e34a421c"): true, + common.HexToHash("0x9b81c2c2602b926e5371042b6b7246f649c6ba66b85b90f1ac91443926433f6e"): true, + common.HexToHash("0x6e958d295346ceaf796ed08d25e5d86805ffab5183037f94faa806d413f1fb58"): true, + common.HexToHash("0x61bb5ddca8c9a692db81b26fb2e67263442cb1b7c2f90179a7f14f46f3d16dfe"): true, + common.HexToHash("0x071880af1e15df951c9d117140f60aa9f16651f7264cfaf6b0935ae7a7ea2199"): true, + common.HexToHash("0x637148d53722e4fb27160253b6365f910784c28cb523598ff0b5c2c9c5a4201f"): true, + common.HexToHash("0x42813ffb0b9bd9ad1deaddd774a8227c628f21a78259864fe37dea53fb8fcebb"): true, + common.HexToHash("0x34fa040647cc4f816b6a0d6b2d6ae49df915df2331fad4ae517cc4af31e9ab8a"): true, + common.HexToHash("0x88b65099aa6ca9d73cbdc73cdf4f851ad47f4ae6bcfb13811b35e1fa043012f3"): true, + common.HexToHash("0x04a69eb11566565601ae3a17eebcfd8d19970e593110bc48b2a421cd20b41c6b"): true, + common.HexToHash("0x29ff64901625e85eee8a827cb8ec31be89ab9c39e0bdcd14d24f09b5cf6fa1b1"): true, + common.HexToHash("0x01e6f0ed5b4aed11cfeb71b555f9ae3356766af1ffa170aaf4ba1c44eb154dbc"): true, + common.HexToHash("0x5413a37fe1a0a7dc488aaf517d0288c7e64fb79e660f3c4819ee42b6dc0942c0"): true, + common.HexToHash("0xac0dada257cab949b08bccb1bbde0e7cb1dae5989827c548b4e78bac44b8bac1"): true, + common.HexToHash("0x6ffb5cf321ca8383d72bc94e31190e15c2a7f7268019754c466cea0fb38c165d"): true, + common.HexToHash("0x6d31bf0bc368916a898d6080c51e00460647de9fdb3251dca03a68096f17d2cc"): true, + common.HexToHash("0x8ce56a53c10248687e26780c69f39447249327341071f7c2a31173d4cab9a527"): true, + common.HexToHash("0x165c53c50b38ec828bb6ff768eea943f7c277d1f9a4b7578ce99bd57a080f0f8"): true, + common.HexToHash("0x328ce7c90e1baa74821e6d03e44cd26e635e77d1601170f0b02a8690d29f13e3"): true, + common.HexToHash("0x18a4cd8723d430d3e105f61afe9ede60452cd10a38550516728e17f0a61bdecd"): true, + common.HexToHash("0x9431d50c1504cdc344a64b3903124ddeac1ae806f00784a70399b193f065f881"): true, + common.HexToHash("0xad94f0dc295ffd161d1c20aa8b883e7c2f753a366823f2676c3121b0ce9812ca"): true, + common.HexToHash("0x478b1c67d6cb7c2e9fb7c0386e9f704871d30384e3d0f15cbf0bedeebaa04ff2"): true, + common.HexToHash("0x6eaab60ab4970f3957e0e8fd7439eff77de007926c9930561e9a132783590f88"): true, + common.HexToHash("0x76ecda923163b338e8164f597d8e567c369f5901f17711a16f236932523f6b85"): true, + common.HexToHash("0xca81c6cbae5d5e569b9f86c6d9213feb02606a73af23db51494ea7a2752b6fb1"): true, + common.HexToHash("0x09be10d16c736723f8fb81a71a261d6940037e68ea66c0b094acf807e4d1842b"): true, + common.HexToHash("0x5c52e3aa3af17e1578571aa952b4904f0270de41f9e6066c9f81ea8deff1a8e7"): true, + common.HexToHash("0x9199354fa54e7bfd0051bb40bb8deddc7f62bd0707f33a74075a14af6563c276"): true, + common.HexToHash("0x026c45fe0f7a1160d699e9c78128e1b914623ef3263f58cc45c5420afcba53dc"): true, + common.HexToHash("0x03d958e285269020429f1c783bac7558adcb9f99a4b8de0ec40ca18bda410c7a"): true, + common.HexToHash("0xcc9f284d03523dd26ab799f50c4336c090e7bad30abf801914a7fdaf90c2acee"): true, + common.HexToHash("0xf4ef2544ec2baf824d17aeda5c4f7c7faba82f7a4c5d8187e6dd0cb9447b9969"): true, + common.HexToHash("0x39564dfd9e83ef9ad999ca08560fb4260c72ec3c0bcabdd2f7ba43f79a0c7d38"): true, + common.HexToHash("0x64cab010cb93353b70ae548aa85dc33f062ddc51c52b43a97d497f3fe3379ccd"): true, + common.HexToHash("0x7592d13b03fb2ff0f0953a97aa718844cfb226edab1c56191ce10e67a3b63e44"): true, + common.HexToHash("0xebfb913f929cc2375f34edfa7737eaafda03fd505ca5c3b1c2bd443600650904"): true, + common.HexToHash("0xcaf7567249c257bf7695e452ce57ffde981f1e6fa8838f8475b7f7628767e1f5"): true, + common.HexToHash("0x624318b94a10db23c9b71badf022c142614fd646a6383637f29cb731e170edf9"): true, + common.HexToHash("0x51ba020f17e75792ac12c560759987be6fd786a1df7fdc3830a56719ae9e4edf"): true, + common.HexToHash("0x694a4b3c151bd8c3bb99bf9f2444240b6f771459bfa3ab80b11461fa857ac685"): true, + common.HexToHash("0x722d36c99246bf503a97a57fafd799c5f826c8d8623ae1de3f6c9f3504a53d4e"): true, + common.HexToHash("0xd79cbb80ea776e1705f0fe30840daa6288ec91f28b711059983ce6399a2b46c5"): true, + common.HexToHash("0x7978bc1dfddd89183f8f5ec323e41e76f03afdb88ee61616093752c04caa2037"): true, + common.HexToHash("0xb67f8b033b3cdbb334c607812923dc8b2650ac8cf41ed8cfc4e157f4ae704494"): true, + common.HexToHash("0xcfa83ade5f13237de7cf2ae5a541b13854c93ac86e02d78ab292ff9a2e00c7d3"): true, + common.HexToHash("0xc22df45b666387f9a19a1a5ae4c6a00f25c09e4a1c730a210370146858ef2394"): true, + common.HexToHash("0x6be2664168f9f3c9a9a72d332dd10f175384300826d000e206d93978e34190bf"): true, + common.HexToHash("0xb087fc8989356254b717467e1335f07ca952a7ddb933ca20194c31f7cc7ba340"): true, + common.HexToHash("0xb31e868ded7658e34572c5ebf6749c78c39bfa8dc0df70f5fdbfd11a542f3040"): true, + common.HexToHash("0xeb0bbbf58ec184ad6d2e115f37b4ba6432744d32ad1c9e0d4a7fac2530dca6d4"): true, + common.HexToHash("0xd9c7850c674f4698a32c23d5d31efa7e84c7f5aff3f34d365590b344ea08084a"): true, + common.HexToHash("0xcfe1c130359ad83a93194f17b60e9778b3d867717239228cc5b3aeab680c99d6"): true, + common.HexToHash("0xad04e6187acedc6d9f896c5e9b1213eaf741efce305ab02d867d9b0ca31bdd44"): true, + common.HexToHash("0x6df227c7254e3bed1a814a958f50c20f14b008095fa2f72a3f0fbd53f2fc0363"): true, + common.HexToHash("0xe997e76cfc068a5bfddbc62952d33b0c75135e96ac9fce547b29c4c8bc73aff1"): true, + common.HexToHash("0x989ca363f8e69854c459562811cecf21afad350fb2a89aecc3281f545af127f3"): true, + common.HexToHash("0x0426e0c691d2502850410fff231d714d35831b53cef0d64c3f73a7fcbc722b65"): true, + common.HexToHash("0xb24a439698d44ab44b3749ce38df0d690f0ea8507d2104d32c40db99ff67f24e"): true, + common.HexToHash("0x27abd6e71a186f1b284b0751d67b4802d576e61ad0d20a85fc49f30eeba7652d"): true, + common.HexToHash("0x52a0b7ad9ba787b9e18c642f36b3d4594d858a3ceb3c86a465c9858a7618440f"): true, + common.HexToHash("0x7b6b79414078c35a4af9941516b691e712195d1783e4c3df2c6f8b47dc4cad2d"): true, + common.HexToHash("0x7212721123fc5b9557eb7f6cc7c920bfeceb80aef068d49ac558cc1d093a5fd1"): true, + common.HexToHash("0x65722ad0aa8eed03d848a30da86865a1cf69c748d9f2e7db715b4aac095d00b8"): true, + common.HexToHash("0xea266a572a059db96c5ef654783ad85d77d16300762c7f772556e6496877c2d9"): true, + common.HexToHash("0x883b19749e376960d12fbf57603092acb22b8f2248fdffd22ef8ac2b007a5245"): true, + common.HexToHash("0x85685481109cd03bfbf38d17485565ea6b05630b82fb8d686d5570b6d3663b4a"): true, + common.HexToHash("0xd9d355c884315b86946a0576239749c48a60097b956ff65b451fd54b5a68da9c"): true, + common.HexToHash("0x24299e57a359607fcb8674ae4f7f9d1469cbe9fc0f1e7b661a7214f6d0ba3a4a"): true, + common.HexToHash("0xe8de9ae390ac20a00aa87cbcbbb1a17f7d9a9121093772964e3e22e10793bd37"): true, + common.HexToHash("0xe24e4e86b633ce49cd7c7b490cd66f266022d4accfde77e366fa5db7cb4ac482"): true, + common.HexToHash("0x1240e8c091cff33f13c5c37812a73c59c7349974ccf8658035c389b180aba834"): true, + common.HexToHash("0x2579bf99d1d952f60e0b02bcaba6a06b10c1df5eccd331c0d53fddcf1cd3d5f2"): true, + common.HexToHash("0x6864398ac94558b129c0b302d39183c009e27c7d89cbaeb817e8db716861f2c8"): true, + common.HexToHash("0x48102dc3d83ff7c157693620f73517699af956d7d50c37a9c2d31125fb92d49b"): true, + common.HexToHash("0x3fb9e9ab7f6e50420109a69d6e6db724233564d9c6318fd1a8a4b0ed5e6cf36b"): true, + common.HexToHash("0x098b7ba1d530bd3440bde6ee2a137ceb86b349aaa44c18809b2f71e622372d5e"): true, + common.HexToHash("0xf5930c61c153a24d905c8a3b800463795fc8a93f57fc7ea95d1afb87f1a38d1d"): true, + common.HexToHash("0xfa53e2501eae245127ddae41c5408bc2260f3a4fedde082527012e60f41e7dc3"): true, + common.HexToHash("0xc0877120d0b7795fff6778daec4423574abf4fc55237423921be12c7383b53d0"): true, + common.HexToHash("0x0a846392a2c4b0051e51a32f653fcde6604da7a535332f43c15f8cd3a4f88962"): true, + common.HexToHash("0x22050eebb2c4084a75e651d0523880ecd56fd7d7b08ec94e4db9c7cc25eb22f1"): true, + common.HexToHash("0xb727b89eaf8073a9b48ca663138902a28d6b6d79307709a64d4c615d3fdc21b8"): true, + common.HexToHash("0xc7f3f2a81be146c8325fc4067c1fea0de704a58e2a946c314406b287d26737b5"): true, + common.HexToHash("0x4f8717d6c24e023ca6b8362d0a6177acb94d671fc541c0c632cd5d6f11e27f36"): true, + common.HexToHash("0x13fbef774dfdd0c1f9bdc0cc1e5e64c0ececb9c6c87658fa10e09a378ffa3c7e"): true, + common.HexToHash("0xb420b98f31b1e0aa0262165a6876144227fdbb608e0b3eb925afb14fac0197c7"): true, + common.HexToHash("0xfe0e5677f8ded28cbe19eb533b14d702db0bcd203025ce522b0b8aada524112b"): true, + common.HexToHash("0x4a70b9fb780af13692ca1c21fbca50f359aa0927ef0edc143d988bfca3e1891f"): true, + common.HexToHash("0x1a19de8c18b478d6fedef03ee55f67cbc20aff7abc7637989fda98101f00bb43"): true, + common.HexToHash("0x95e9a2cdd580930e303cb0ca3ca2861359f25b0424fcd7f9556aa1df977bfc0d"): true, + common.HexToHash("0xc38bc7794b56507d34756d95385a0eda72d679089c26d239b98dcae15b25d69b"): true, + common.HexToHash("0x43eabe03e1ddd0f5a42aeedbea6d003222fc9cfcca5ce4c7ec2c325e773a8d9c"): true, + common.HexToHash("0xb152acbfe6e6874448e4ce17944befa130c1999c5a6f99918c2da558453827c5"): true, + common.HexToHash("0x7eb183e47f617f5d8c356a8e1591733f6d2ae1e59a799beb6a1ec51a6ebccd8a"): true, + common.HexToHash("0xcad0d51414ba6ea5697e2330a98f5abb00e78151dbcba0b6d3f16bdd8bd209aa"): true, + common.HexToHash("0xab3f2d8fd920c158098174eb7955626f4b78f1260ed78de82139715d7b97ccc2"): true, + common.HexToHash("0x4a5266c2c776a58b8e02d59e1731d5e8f6c308f58f5fa25c4e2130a416443c3d"): true, + common.HexToHash("0xd47bcd3628175c3c55aeea6312c5c53ddaff083313249ada8dc27a91f9bbf5b0"): true, + common.HexToHash("0xaa4de85574a8122e2393de3becb0af4286f1d935066924248421ad8644733bfc"): true, + common.HexToHash("0x1a7bc1b07fd3a30f5112946f51a35524b5075f4b9b76ee316ffe5f792b8c89bc"): true, + common.HexToHash("0xc3cbe44c8ff0ae045024953d623c95d7c528dc4be4cb7db9fd83f727d05add5d"): true, + common.HexToHash("0x220af3a05900d4f6c61cc0b35496a5800d21977f3c5a3bfb475145e9ac12b00d"): true, + common.HexToHash("0x527f96dfcda17bcbc06b4199cff3d69792461ec1782a1af98fcfb2fbf2b15bae"): true, + common.HexToHash("0xfbb1ddf8f96c1ca51301c3bf5529faa7f0966acf88717b026c4e5b1720c58aad"): true, + common.HexToHash("0xf6dde4d259914c44f9e2effe153b67b9b59645cc12411e092a4cc40a550c6646"): true, + common.HexToHash("0x07445cfb7415ad177f0c736036521893102478ea4c3216f85d0fc4f75ecd11b3"): true, + common.HexToHash("0x2812d35332eeef6a164f432ff0bc039597aff676872f98ff7bdbf081addd4394"): true, + common.HexToHash("0x246b0504b560463a516f142b9e8b58d6766372c173168a55d10551f08a480531"): true, + common.HexToHash("0xa11a3ca01d1265d03a79f6765b3ecd977a41898767e996475d7a2e8c44828933"): true, + common.HexToHash("0x51dbec6c25bef037cfb6bd4fd837ce4f7fe137cf10b472a99ddbb0f56eebdcf7"): true, + common.HexToHash("0x24ca9b42cb154176a39b6f4402f3d4e7e4f7f0cdb4f9818f958ad683c6848541"): true, + common.HexToHash("0x471d59836f3835f71f92382b6c77da874467b134b4d8ec37afb41e3e14430684"): true, + common.HexToHash("0x5ea2335112d87f0bf73d998345027f020383a5647caa6690886129cc6b000be2"): true, + common.HexToHash("0x2e5557822a0f1cb6cb81ddfd0b3badfeeb1b89746a72df945a84c32b83caa463"): true, + common.HexToHash("0xe86c6db4727dcdae801205b75a82e59591a85ece6ddaedef31f3d13953d98ffa"): true, + common.HexToHash("0x1affd2a2de017d49f80cc94337c88dc63f69aec25232ffd5f3f8574285fa7364"): true, + common.HexToHash("0x2e7eaec9c50bf00f0d71a8221f4a7ad676b55a748e6c5ec059eefff0e4e8a1da"): true, + common.HexToHash("0xd884f208bc91a535e1878d7ba0937a2edbe69a7c7b0f6f2332aec443a942b157"): true, + common.HexToHash("0x9ff6470f64bfa107f08b5770d7772da486f6c09509c36989222c76a72d326996"): true, + common.HexToHash("0x44e39e48361ec58e277b45e99992e6fcfca84599617e62dec43110a6ca165d00"): true, + common.HexToHash("0x181e428ecac3f150b9bf40868e5628a5ffaa693a6e9a0a5ed947923c319bda3f"): true, + common.HexToHash("0x91eb10b4ab7ac09404c5fdad746d170d5d4325403bc05982b4b1934b9c17f2c4"): true, + common.HexToHash("0x761208912ffda5649efd4bf14afdd4f5bec83efbb54efc7e2d318f845b9c598f"): true, + common.HexToHash("0xdcd6857f8725c054cfdce166fa4030c943dfec89621b57ea95e25f4dd77844f3"): true, + common.HexToHash("0xf51edfea9276a1cb398e3bfa2e681b195f61f69594fd3cc361ce00fe514100de"): true, + common.HexToHash("0x0686573c3887087c7cb02e2113f6d9f3f10d9a2fc737dbd055f2a1b4d435b517"): true, + common.HexToHash("0xc8ab231b89f77cdc041cf276d1fc4df73777db10c540a8617556c60a54507268"): true, + common.HexToHash("0x18b155a2f25af9f00404927e04ef7b30f3d3b8c247ccb59d02a1108d751869bd"): true, + common.HexToHash("0xb040095c27641842acda67e6f93338bbfbdeafb3ead3b324f2964c057846b3ec"): true, + common.HexToHash("0x98ef10fcf45d09858329c5967e1648789df581e301b2a32cf2acaf8d8a49b630"): true, + common.HexToHash("0x088fbe98e436195ecfc030bdc3ada2422f27ea50e5f6fc2a7caae7f82438952e"): true, + common.HexToHash("0xa62c089fe081c67d322132059ca7aecb014449465357cf01d00d602643f5dcad"): true, + common.HexToHash("0x7dd7fde99b2eb25373b45d882c12dfa40249632530d608935e27ec4667142cb2"): true, + common.HexToHash("0xb0698a3414dec49a65e01ae1f7b71be46eac0eb0c342375e82f5396f1d1a3124"): true, + common.HexToHash("0xcbd5d911ae6606c57f7d104fff097460e4d173656c3ffd2d4ce3c5d153742215"): true, + common.HexToHash("0xf8634290272f78d253f706eaa311eaa6d11f32518d69be589f2f530d6a94f66a"): true, + common.HexToHash("0x4faecc2402b864f3366dad4bac14b46b75e3f42c7d83779f7f55195f67ffe57a"): true, + common.HexToHash("0xe74b0cf70356575c073be43fb0bac5a6c40700724e7411ce6abd3578fe7faeae"): true, + common.HexToHash("0x5dba605709150e0eb912e45e0bee61b83a04b6696d159f46ad2f66276d31c26c"): true, + common.HexToHash("0xe430ad1a5914efc902a20b95bb70a638143a4527c89fd26cf84bc23dd3149f37"): true, + common.HexToHash("0xc1bd5e101f0e20db681145d7698c73bc248c7cf36af4842da79d978d4b7fbeed"): true, + common.HexToHash("0xce56e03f39f31eeff36b8e71f44a7cbe4e2a076890bf61f19679172f878a0ae4"): true, + common.HexToHash("0xfa91be61fc980610f12007ae570f03c581057658ed04e9a4361299017a95bfff"): true, + common.HexToHash("0x3c63ea125192852c9c9d14d2ea576d9b552833490d7c5368641ff4d191375cc6"): true, + common.HexToHash("0x833cf8a41307be28997b8d669253e32af4714175ce0ff49089ea5e9120094470"): true, + common.HexToHash("0x9c1f9c08a6501281283606ef9e0b0987141e3edf30d387f3beff0c975693e4ad"): true, + common.HexToHash("0xe6dfd784a2e46ab83b312c884fb100fec3193409f63e1297cd050d186c0e154e"): true, + common.HexToHash("0xd1c83f0b72b6f9a280860aad4c61c2a91bed6a94bb7a43921d3e32d47c67f690"): true, + common.HexToHash("0xd52207b250298466a4ea936a28df340a579d859f541fee5121ec147e61ff7bc7"): true, + common.HexToHash("0x3bd9647ad0f14b438daa8e77ef9e172d383f38feaec61ffb24ca50ee6aaa8b03"): true, + common.HexToHash("0x35ea8c2a21cd9cbd5cdc8bf5a25278e6279b75e3e1863d0ebc33ed3b8a36b695"): true, + common.HexToHash("0x2e33df1fff58ad99151473a74d7f2d188acb3624e411d9f701e87519bac4de7d"): true, + common.HexToHash("0x359a05bbc3f50bc51a76519abdb4f68424f4e577670b9e43655f8b1533c468c6"): true, + common.HexToHash("0xcb398fd38a3813763a48ab6d4f3730137e6114a9fad6f2a44b2c9cda11657385"): true, + common.HexToHash("0x47c51b13ae740739b1916af5231b86961aaf284b1842a1c735798c450eedae54"): true, + common.HexToHash("0xecc0d7ebb306f3e54fc25351c64a8ec114dfeaf86ba85ccb890ce7b599c850a0"): true, + common.HexToHash("0xa8e27d5d417c2541af57442b65491678432e852a55c30c8ee1d92cf5b268aca1"): true, + common.HexToHash("0xcdb9e94332c20b6f1e9db91ed42d7f21cb2725588d51606759260f1bd89966f3"): true, + common.HexToHash("0x70b1e29288b0a3f3c2d0fe1d589814d1480ee29663a65f154ae68ea77826d7e6"): true, + common.HexToHash("0x3ec41e912bad0a9ff54b0909a3b833974c1574c073209e36f22d439d7a7c5653"): true, + common.HexToHash("0x42283e1ed2a9154b79430e7b89ee77697fc665e456f7fd6e1e85cab87777b94f"): true, + common.HexToHash("0xbfeeaa9ca1ccbb4331ff8675651b652faa50969f11ad0d153d9265bdae75f9bc"): true, + common.HexToHash("0xdd54f995126b12532d9f8d9d56f6e8761d6f4367b9bdc5816eff8aa88dd4f626"): true, + common.HexToHash("0x1856ed832a1f7f2cec808ecfb0e3bb18ba888625f378571ee6625ceb48f451c6"): true, + common.HexToHash("0xc2621bb6b1930e5f3d4cf36a88f6a22aad7bb193bda60f5642bf7186bc2a2da7"): true, + common.HexToHash("0x69c9eb44983e59e9f189907da4223e3f99afac47a6166bad492ced5ace61636e"): true, + common.HexToHash("0x615cffa18d521d8aed25ea994dd2b8ccb1a967dfceaf6b3741fa7aaf951b18c8"): true, + common.HexToHash("0x9bc9051360148286a8469c4121ff4b9c49d5092cba1fde56e88bafd21275114a"): true, + common.HexToHash("0x0d431bf3254e009974cc70bf62e30df5f3fdb99723ccd769b8c99e3bfba9932d"): true, + common.HexToHash("0xfe4bf8c2dba9cc1c9566133da03479e85bf4bcd28d5503cf2caf6ca0c23cc880"): true, + common.HexToHash("0xaba2728a901f26112d60981511d6d957f6ddc53844965cfa4df45dbf0b97eac7"): true, + common.HexToHash("0x09c38edd90923dbdc21eae7db1267f19b8f8e7a2c71059c4218a597493eca44e"): true, + common.HexToHash("0xd3bb90e4bf039519dc18a59cc5351b8cf76f250d017af0935aea204e38282f0f"): true, + common.HexToHash("0x88b702a005a0f388e3e9012e3d0d8496d9e3398f81a36ccc4c880ab3fdef86a4"): true, + common.HexToHash("0x08c41a4862e873b83b8252bca8e3e3027315873743dec6a9a0de68c39dad867c"): true, + common.HexToHash("0xdb2e310bfc3179df228f2df5e50d8744d0a8d6c93df4bdbbc4b6d4147b310e8e"): true, + common.HexToHash("0x1db00a1abea755d0ba483b27fc254b7886ff737d02047020e6a4edb5dcf59edd"): true, + common.HexToHash("0xba32e8716377451c711127c7d92ef8154399431e8eba19707415ca47da148a82"): true, + common.HexToHash("0xb5907ec5fba8222397ef80d174499303a2b55e4e43947d06b9ed1a6a1e0a7aa3"): true, + common.HexToHash("0x7d7a05bd482da8fa8dd0e6ef4704696153809257a76efb3ac6a54e36d77e5526"): true, + common.HexToHash("0x3c42612710e322cdf7b5ea7e5e3daf2d605128cfe30ed08833ccc594dde4c761"): true, + common.HexToHash("0xb69534aa36e118409f7920729b7b6ea52b276c48f1d09e01b4f079c56ddd5de7"): true, + common.HexToHash("0xc485e57b42aa0314d1053fc78cbf2faf5fe38d696d12582af4f21c355cb91597"): true, + common.HexToHash("0x8b2fe73a9e3e02bdfe257061106834c1d1522ba9b9e11071f415895b1b4dab67"): true, + common.HexToHash("0x2b2a815152d93fd408da7dad7b2cd480551483dda333c232c11c035909244c00"): true, + common.HexToHash("0xaf62bb6ae9425f39900f18c505b8b7a811ca20aff24ea3a3584fa89ca3917fcf"): true, + common.HexToHash("0x033ade0db0f7e3dc07bef496b3acc08630185c1e302c04a141e753ebfa27764e"): true, + common.HexToHash("0xa282672af291c84094223469aada0888ab8ea0023222472f2754eda7026401ad"): true, + common.HexToHash("0x817c23a40a0ee0141660bc6cf513e38576d9b7126ae7de2b5e8c2149d83846e8"): true, + common.HexToHash("0x733b4bfea2f8dc00984e1dd9519046fb6d2fa3879dfb17d8a7a412ea34b0bb40"): true, + common.HexToHash("0x2d2cf6c97836c46f41f4e7a44629c431e6b68a402d809c663d78ab3e8b76de9b"): true, + common.HexToHash("0xae02babfafceafc23f78ca7afd2fc2958adb0be474016290ef3b5b051647fbff"): true, + common.HexToHash("0x7683fe21c5354ffd6b7de4ed4ff802cb3920869e23657d7f9bff7473b930b460"): true, + common.HexToHash("0xd3f7d0e5349f9c54275a5440dbe29cc8473b6a838840b6338c16c4673e681b76"): true, + common.HexToHash("0x9a84ac34bf5b2447d2099c53d7c84b5fcd7f288863965bbb4a544c01ece1e1ab"): true, + common.HexToHash("0xdf2a4b32de374f561ab5286df8bc2492d42911175c5fb155b7c4c382d97845a7"): true, + common.HexToHash("0xd0d737e8b7b28162cfcce86c0058e3f8f0562f63260b0299a003424e32f25e98"): true, + common.HexToHash("0x19e2624bfe370fb8453f446e7c091ac1fd5b5526c8ceecf2cd9c79c076ae3315"): true, + common.HexToHash("0x2b6fcc1206129db2f582d1b90c0ca0128a952557cd1bdde8f6551f7d3d2330ac"): true, + common.HexToHash("0xa4ac6c9d0ddf3314a7c8a6062bd1c222a252fe8df8a17fe9938a0bdcaf6c523c"): true, + common.HexToHash("0x85ecbba7a79beac66b61d9bcab98b92b0260ad425c77af813e110b9ca1797a74"): true, + common.HexToHash("0x0b9ca26a08653b42bdb9a0a8ab99b100848b03acb046db40e19d7cf4c8a90133"): true, + common.HexToHash("0x24d326dc9f0c02c156d52da1ed4c7df7f10d8b3a07d288b43ff4268c3bc4f358"): true, + common.HexToHash("0xd5fcb1e7aad92477af1c924fb4bede0dc45e2d40db2c9867ed7168c0cc28c5cf"): true, + common.HexToHash("0x2361b3e4c792e85e2265c8465392de3ccd3e673fbde8699e3cc47bad90a14c39"): true, + common.HexToHash("0xa73877b599dacc8b9c1b1a9425044525b93b953c0b788c8e195b3fab788ab5a0"): true, + common.HexToHash("0x6afc9bf5e0a6c746f7ddda0e8e74330c08a6aff06c5d2fd97741ecd933225f26"): true, + common.HexToHash("0x47e628cfbafbbd53d6b1d7a5325ace4371045f0123fa381bfb48b7e616353618"): true, + common.HexToHash("0x5092cf5a493e4d98303e7ad4d6d0c91cae636926f4e5c9adcb6aa289ce19ad51"): true, + common.HexToHash("0x1a3826aaf4448e77c8b6556245c2ae3e209c6fc9e11c6e9c21e5e65d843ebe09"): true, + common.HexToHash("0xd42c619552c8da5afa2bb53b38302c22c4fe8969252145c838a2b7d735462da9"): true, + common.HexToHash("0x6eaf3d1cd31d186f25ada7e66f58735b96bdb50800483bfb23a954aa78a9c4a9"): true, + common.HexToHash("0x047cadc8dac5bed09c80667201c2382241aa6294dc281675a952c34320163f21"): true, + common.HexToHash("0x54e9264dd0a4a184bd5c4c2d9885ce9def87febbee5c6ae47335da6c98571e5f"): true, + common.HexToHash("0x6ba020d3899ca2028d737fa132421790203b2a3ca1378e9daf6d11fb49c8e900"): true, + common.HexToHash("0x427ccb60613f4b7e358089b16e56d21fbfbd711bff35521c7f4a18d33cc77e31"): true, + common.HexToHash("0x493301b352a8b32b67dd19f017fec0e6a243034f57803774a7f60a2a673d28dc"): true, + common.HexToHash("0xa78e96cb54abd34bf2187a45597fa857f40a025c99e58773f36a447235293a01"): true, + common.HexToHash("0xac8c356dbb2ac4e8d0ad99e6b7fee04ab0aa7f1db3c63d84804652f9d8d614c6"): true, + common.HexToHash("0xcc52b12fccfaafdb13b9944c9d644b91aa01dc003784987a82730e54f33d0cb6"): true, + common.HexToHash("0x20e3744cce20bce7eb8f7f731b4967ee4b44a97336d43b9e2227ce3014004e61"): true, + common.HexToHash("0x9aa7c6bf671abbd3024f78886f73d6cecfba4e91ddfbeb311e796ed5020ce5ac"): true, + common.HexToHash("0xa3d9d0106a646704d63168e913ac77ce8af7a290db7879997f03cc2b7a96867d"): true, + common.HexToHash("0xc65a750022be43fdf387b450cf7b36dbd3410028f063faa863a5bb81404834a1"): true, + common.HexToHash("0xd7b0dd31a1e48de9d5a47c229a8aaa467fd8001c9e3ffbfeb9d0e5711fd568b2"): true, + common.HexToHash("0x695df89ab9f27f53d778f88dc2166c1a948e7ab93c3c1bf510871e102b90c973"): true, + common.HexToHash("0xd9185fb278a181278b6e19c3ef9dad649f78cd3a36d1d404ff0de7e76cc4b40b"): true, + common.HexToHash("0xda551441cdf6f0e34b6e68732889e58d83bba7a3248bc36fe9fc2d7301510cb3"): true, + common.HexToHash("0xa7f8aeb866edc77dfbe727cb1dfab870e27907bb81efa970024c7127bd7d6a0c"): true, + common.HexToHash("0x3a1545d4fc744b909e2db1aac501efd5733a16d922d6757938748ec8a47d544d"): true, + common.HexToHash("0x0a85cce37de4ebc0b0e91989c311c7929d1e617a241395da231068045ae928d3"): true, + common.HexToHash("0x43f4d22a676b74d0c39882e7b6c8b7a4b34dedaf195be9752bc379629868929f"): true, + common.HexToHash("0xb8ddc7700a1997b8ca480633fd5063beacad5467c0753035e97904d3df61e068"): true, + common.HexToHash("0x7069b8dc328d9760bfe1ce6a7c16b8a8256be7dc81efb0a81f91035502d5ec38"): true, + common.HexToHash("0x03d17e528db3d32debb424cfaddd478873968d69cc1594f2a970aefd6274d472"): true, + common.HexToHash("0x9ad5a6a0f722fbf841164da2e46ec07d56eaaea251819fb789233c7098fe0445"): true, + common.HexToHash("0x211a6680c9ad1b20df75d9888fa7203831ff0674a3f1f25d81ce5c4ef003ea6b"): true, + common.HexToHash("0x0f1af5ab0e99be3637b9a8b23e653c888cd58ec0c921e9d6ca4db6c6c3d126ad"): true, + common.HexToHash("0x642f98be5e7ca2386e2635437ebf81b37a35a54af644eb374222c772a5658917"): true, + common.HexToHash("0x3eda6a4a43524494919cdb2ef7ea8954947c5b7d86924d1cbe015e9682f175e6"): true, + common.HexToHash("0x0248d42fa85b357d63ef847c61cb8d0b31618216d17b56e236234793de123ff4"): true, + common.HexToHash("0x326379b25c04674532f77ba91f59b42faf0112814bcdfbd8145c4c1046e08908"): true, + common.HexToHash("0x13be693491434b21b9df4fb58fdcc503c0e8067b0a1d448ad88d38876a9b1951"): true, + common.HexToHash("0x03f430b086740848c8123ae44ee3b4b5c734ce0791eeca43b69e24f703b10a81"): true, + common.HexToHash("0x2c54bd240bfa661a684d08a77d968ae53c917384bd8d86029cc871b6db757121"): true, + common.HexToHash("0x6914cf340c12ae743e15b8df9fd77c4681559e5c5b19e405608ad23fed113da7"): true, + common.HexToHash("0xb8f47bf4e0662b6f98d5faf5507e93e18c5d3566751c7d131ff7d59cb9cd63f7"): true, + common.HexToHash("0xfab1d73516c2b8831faab46e60005f0b41cccfcfad85b222fcd980a4965f13b0"): true, + common.HexToHash("0x8f2fbfaa02a4acf38c0dc7f3681d7fa3888bfc24ccf52bc1d838835269bc12a6"): true, + common.HexToHash("0xe404f1175b92f51237a2011b7661fa6c72120f4ef3ffd3fb399b14bed8fa5c79"): true, + common.HexToHash("0x4766be621fa730fa0518eddcd72a953d6f879d920af759847f6cc71045adf0d8"): true, + common.HexToHash("0xe47be20419fc0dd79556972eeff3588362bac2a9220d55cfc9f0575ac72987f6"): true, + common.HexToHash("0xbfb656e9865103738c4256150e4e4d62919921355a8f73b81aacfe0bf906cb47"): true, + common.HexToHash("0xb31052469abcce844dff4432dcdab30991ecac67474aabab52ed8cdd57481854"): true, + common.HexToHash("0xf8bb27dc1df4f524ddc5d209bc523398af6ff0517b8f5a746779eefb47dfabdd"): true, + common.HexToHash("0x76db08fef6072a01367df7ec9aa7775388b370e704b97b83c6a4881d15432a6c"): true, + common.HexToHash("0xd9de9164d86fcd28871a7fb78e85b2deb193af1cb1313b45988bfd6eee31fc6b"): true, + common.HexToHash("0xc47e55a178623a347c2545118b34449129768898989c3a58a4ff15286cf2bfa4"): true, + common.HexToHash("0xe681343145daca9e8359b18db9fa6f47bc78c78eac26ce6ebad9d3ad197b4615"): true, + common.HexToHash("0xf25b63c038f23ec1d748231cdd2b4be8f37b4a03c8e00eef3714bc795fe3a246"): true, + common.HexToHash("0xf5266ee7cac2a0f7714cd34a2dbae43ff4b62829959993b7c2ab97aad7ceec19"): true, + common.HexToHash("0xe0cebd56193fa9b7465a413f246953a9ec84cb75b4270357882c7c026dae2ceb"): true, + common.HexToHash("0xa4ff58e80b1e3e38b5c74597d650d90406ab24d5fb6504e7c5b7a4ce172fb9ca"): true, + common.HexToHash("0x07e70e6aacdf1591266f83a645bd3897b64997da2a75d518b37827d3aa7785a6"): true, + common.HexToHash("0x227cb2d99096301af905f3074ec308d39bb71f07edd5a4875d0c6ed178d26f79"): true, + common.HexToHash("0xa4194a5ad34e8d54350a14b4cacf5380be000140897f4981b9fa975efb4dc96c"): true, + common.HexToHash("0xf96aec960603731116bb02018a1679c2411571c171f367ffec28fcbb0d20f294"): true, + common.HexToHash("0xf250fd4d2887b25b2a7383b29c5f457e4d5f9cf3f06693db111aa2c38325a8fd"): true, + common.HexToHash("0x49047d501458da560a3efa8166dd29d18639c2ee03d7f218e7ff4d6dadf2ca13"): true, + common.HexToHash("0xcbf46f1dae6160e5ee0e7fa013b328dbbfdaaab102fc0fba61573855edade355"): true, + common.HexToHash("0xe555d5f8bd56106a32f428213f2439f2327eda0ee39f2bcf7d90a094fd9cdcaa"): true, + common.HexToHash("0x585a1bdfa84866e8004e8861e1127e7326ee195141bc406cdc690a77d5267080"): true, + common.HexToHash("0xcbc56bf0c5150231930aad486582feb499c49220d8669d3c32259cfb9226849b"): true, + common.HexToHash("0x5fc45fd72628b5c76a5f7449147d570d2e6ccdff801cc70ee54bca050587acf5"): true, + common.HexToHash("0xa7c0cb72fa86eb8daa533db2930c789e43b7933c3baa86020e77260c56ee3e63"): true, + common.HexToHash("0xae19c4d40d1a1d5e9f3f6bfa3f0a38c1bb42f577190ce811dcff843ffae9160c"): true, + common.HexToHash("0xe22399326bd95ef28d3693fa15eaafb2f082118c8fe7c2dfa788c86eb079a16c"): true, + common.HexToHash("0x8f16d6ae36d5cd720824ec90e06b98b6c2a0f460721f3b31e6a5e4596eb73b2c"): true, + common.HexToHash("0x1d8262dbe0acf3056a262c14e757d44d42c713456e8d2f3b0c5b79a8483d522f"): true, + common.HexToHash("0xae94c0239050ffdc02da3d3c303b8693e3fae988e7d6eaec0708963b0ed70a49"): true, + common.HexToHash("0x67704365fe0a34047d1dc33eeb4671d831da650f6183b4cd5eff5139aca20f55"): true, + common.HexToHash("0x65476688bd20a532ab70894920fa55892268b2d65b2cf8191d06643f878404c4"): true, + common.HexToHash("0x527b5006a86062cc67e3f6c9e4b39dd33f924b374098c24e9afe7f6cc5c44a2e"): true, + common.HexToHash("0x516dce66801d42baa3d463fd9eec1e32fb31148216b7827c4900c81e7753f06e"): true, + common.HexToHash("0x3e66a16cdadec53c6a0884a67d993a941d73c55a91b06615e0b0951646e02a62"): true, + common.HexToHash("0x80a7ef330219fe55c4e184f93034912b298e9bc1f93209015f8372bd0815dfb9"): true, + common.HexToHash("0xe250fe2a97c6fa693b1686118c8124aa321e5bc52312cd4fa24c8dd463dd7081"): true, + common.HexToHash("0x170a68fc1545d0ee8ff713167fcb6703949619f5f0f018e03e41ccf4bb1c36b3"): true, + common.HexToHash("0xcfd7ff18d00ab0f0dae434c70e5ec7f39fa8f32003627b1924f6034a21adb458"): true, + common.HexToHash("0x17907d507ba34793525cec8f80b7278d11618b014bb7951005349b2abbc8014e"): true, + common.HexToHash("0x83e6f439c752068697b4013ea1e74aaa5a9c0a42548bf7f2b11bc07b65815478"): true, + common.HexToHash("0x5d856cc73d2c8e66130e688fb0334b5bac232ba165986f1289880f595229c674"): true, + common.HexToHash("0xb7f8d163cb125d7ccecd7714be9faf6c09abd8ae2985c5bc53cbfc771e5440d0"): true, + common.HexToHash("0x23569b3349d622b8a913f0b8731edba0c2abc6665026c17e807a3c861b9ef983"): true, + common.HexToHash("0x2193d2d6ad463328bd3132e31f95f1d5c9418bd00e6e85c1372b56f0e3192a8a"): true, + common.HexToHash("0xbdcea5dc7f845be6876e8a75e303e86136acf7c039125d48f31d5dff2579367d"): true, + common.HexToHash("0xa7f2512d28898f265ccf129aa16acbf85af86457bfe272d208260e443b50e84a"): true, + common.HexToHash("0xcd40eb21b39a6847917bbf520b7f0c12d8b1dd15c29dd90adf32a3676e6f3a45"): true, + common.HexToHash("0x9b783d1c47565a71cdff3d76790b4591585ce90581bfdd532fb3016536a3beba"): true, + common.HexToHash("0xa8e907966fc908fe4a96ac252c472bbfbe0777275ad3b58a2230774b0d738a09"): true, + common.HexToHash("0x0504da16c3586ed37aa17aed8ec566b76d3b3a5e9423d765e1c1ea54c9318f67"): true, + common.HexToHash("0x1f2577c320a3c017f6b3dcab4f4c60e3c36a8fa99717ec0797cd3a39b206f5f4"): true, + common.HexToHash("0xb36371d53d9e64ee041a49f80c26d54671b9f8d49061ed1dd5aa7dc69d1f0986"): true, + common.HexToHash("0x871d1c1118fe1cd9b772a2c09d692ba79606ce40cedd19611c888fcd093da880"): true, + common.HexToHash("0xf58d492a4639eb79ab7d99d51976a9150ed59e7bdf597db7e070d11e52184ed1"): true, + common.HexToHash("0x52222146980e501bbcd02cd40d08af70973cedfdcfc12d407411277116c4fcc7"): true, + common.HexToHash("0x26bae03ba33b31ca39d23021ef7fa5cbb9a02e39e8bd8130ff147f368ea0016c"): true, + common.HexToHash("0xaa9c1dccdb4e0faebfe35b0c0f12274a0309d0d8bfa55e5a214afedf1259a59f"): true, + common.HexToHash("0xba29ac70482f32e4d8b228d7b88556424a19f64ec651ed67196880efb759fea2"): true, + common.HexToHash("0xfc0db100ed614ba903ddb745a274cfda1118dbf27b65ebc0e1891066030b2caf"): true, + common.HexToHash("0x1ecbc43eb07fd11c2e28e32e520852182eb1412675097a9a536ca32c967f135b"): true, + common.HexToHash("0x3cc64d93714357249cdc83d5f4d8d3747efc0fc1a4c8df62fe6078b3b67b3745"): true, + common.HexToHash("0x4b03f230a327c7cc2bf17e096b630eadaf06be28498f8d44e288e43eb3ad1781"): true, + common.HexToHash("0x032a0709d31d5767ef6aa9bb9eaab2313ef75e50ca299fc587464fbf49f21556"): true, + common.HexToHash("0x918d7a6cbc860adc11dded68bab435f3fabac6e3e2369e251b8f42f89086e04f"): true, + common.HexToHash("0xca9b06e61da4a30823d4d6ef9ec0c28329c5d4fe5d093a07729167945eb667ee"): true, + common.HexToHash("0x6021955f1300835454822aa603ed9f5346af4fd59e812c555c772f9ed4f98d89"): true, + common.HexToHash("0xabf13c511ad1b74b5d0f979f9fdc25fa300f93ee8904c166e327ec8271580a62"): true, + common.HexToHash("0xb66eb229183df9b7c73747f5e4f8408dd40fc4b8d4340f450c8d12e8e00ea96a"): true, + common.HexToHash("0xce312dcaecb83062b06fea4d022cc6050d992ff7c44296df36f6aa0e66d0f068"): true, + common.HexToHash("0x4b232971970d87549a26a98e417d62229f0ef1eda48c76d2db5e83e7e1c22e03"): true, + common.HexToHash("0x9e7a3e489989885b9d44987e57745a6ac940ea9af87aaef57cfe554fef035c59"): true, + common.HexToHash("0x70a91628bb64254fcd9f8c616be55ed54f33a42fc81439b4ebe88e647a4fa31b"): true, + common.HexToHash("0xb3b3997a697ca76612e5bc2c603d0b9f8ec48135856c31e7342d80073ef8dc89"): true, + common.HexToHash("0x9d16be18cf3ee549ee2218af536d964a60a6b595f1660f3c2d71d8486f7be85e"): true, + common.HexToHash("0xc40b92fd03aa4d2ad330332606e615b26618600762d544b49ae97d1d5933ed92"): true, + common.HexToHash("0x270ec91267cae02b75c1b738ceabcf4b6c7b53075872fe97665b1cb816f3b621"): true, + common.HexToHash("0x0d0ea3ece3ada99e9264e1aeb4f96c6843aabf3e190e3cc9485a4bc57b78a14b"): true, + common.HexToHash("0x7ab06a229f6dcb989643c507ccc787416ca1f88d5d6bf750551097f752c857b2"): true, + common.HexToHash("0x2553be735af16ba947d0ed837cb2d39e761011eea1426a2c17add209b84d5833"): true, + common.HexToHash("0x2da944254b4f3409bdfcec0696e814655c95ea84b90a2a6ef0d47e7365556816"): true, + common.HexToHash("0x320ac862829f418456769a5a68864b32ecfeff49dd12c05e7ba08f6a40444f58"): true, + common.HexToHash("0xd7af3a7b2e973834327eebc11cdfd8a091d2f513b9fccead64b8082ed897c7e1"): true, + common.HexToHash("0x52f8761a54b1f1b66fbed6b93e6d0df1d84611af41e092a1e74638f360da6730"): true, + common.HexToHash("0xd340cd653eb571b3364fb43ffa2cf32a9ca29f04e5c37bc21c2d4d66c9b7561d"): true, + common.HexToHash("0x54cea93f4a27ca23f255c8343269a7906bacfe534fd5c6f68990064b68ec084c"): true, + common.HexToHash("0x6e3a29011993451f7ddde854affde0e108d98e004c0de831b7c615ec1eabc4e7"): true, + common.HexToHash("0xb656c698b673e3090c6117c943fd3d39eee7f5003f9b3a68c53b673e1f98edc2"): true, + common.HexToHash("0xee490048e481fa6741b3c7b5fad48fa64ff3c1a7af251930244ae6b3ffa5d282"): true, + common.HexToHash("0x3027da6b1284b4ae5df0845ec1b0e9af7945341ca879ae7e04f4dd04f01fe65c"): true, + common.HexToHash("0xa1da8f46f58c66d1a7b164472b72e4a933c475741ac4651dad369518bcb52c97"): true, + common.HexToHash("0xbb760b39ecbb0ccc19164bcec5483da239b644215bcf0eace29fdb9893a0a204"): true, + common.HexToHash("0xea620cceac827e785cdb97b493ed974e235bbdbabc145482f9c00a72103c19e1"): true, + common.HexToHash("0x7d44791b5f573881a717dc6421bed9d7e4fdcce63a3a92d17a199160d50e6bd3"): true, + common.HexToHash("0xa44bb6c90cf744a950e5c8643ebb011d9e00a2be2f3bfd330199a6470eeafac5"): true, + common.HexToHash("0x6a2115f22ab21d200e98c89921ec532abcd829af20664de738c74971fa7bb1df"): true, + common.HexToHash("0xb0237875b31f26c2e0f772e3ea5adce3f4d6f643a1b13b14269f46837f94af46"): true, + common.HexToHash("0x68a75429873f782821ad2e007ceedf1a51fe0e7da9a99e0a4451cc29b720d756"): true, + common.HexToHash("0xc98d8cff57e5986dcbc6751bc27f3df33af8aa2fb93c48ef2e95ac5463bbbf4a"): true, + common.HexToHash("0x1c9f7260e0194399532ece830b5cc756005ab87b68dc94cfc68029c4c9a24461"): true, + common.HexToHash("0x0c63c75e201636f729598c43b81e02c0a131c9af48ee1306f10d582fb31dc913"): true, + common.HexToHash("0x07c3ac7a3e6e39d62e9e91a5868a4d6dc9a7d44702cba79cc9e1dfe1b99ef5a5"): true, + common.HexToHash("0x1f674dfcd526fe141bd16bbf446d55681330665747345f6abb509e51bcc88a9c"): true, + common.HexToHash("0xf06548adc1139e903421c7b85e2e4b74364683baffdf68414ac3ab8dfb04eaef"): true, + common.HexToHash("0x5b55b2b96f81477d2ecb178dbeba20cc7b898ba5ad94df9dae4b5124cb5fd2d4"): true, + common.HexToHash("0xcede8afe508525988e3b1fcb9347df0dd1a16bf2ff3295b53bef7f48e515ed93"): true, + common.HexToHash("0xc812f99647be7b11e18f249989667b4930814502ae7bf3548d6948616b23d67b"): true, + common.HexToHash("0x2d6e7ab7f1688292630d47ca5ac80b2be46d6790db0480f036b4855ce3b51b3d"): true, + common.HexToHash("0x44b4dd5838eb3e9d3ff7d3296be1d0f79464dea026a9a81b10ce5dd77988c624"): true, + common.HexToHash("0xec88e3528ae0a3fe2753d78c7cab4f0350ce42c353550bdbec5f3e16454598dd"): true, + common.HexToHash("0xeb986bd982c217be54a6f043a2581f3b7368348e19450ab0711e428f3b47be54"): true, + common.HexToHash("0x6a0a15d1f291f6e939eb54567c324fc2d79c5c820a3e684761bf1dd40f2c97d0"): true, + common.HexToHash("0xb028b01604f5df99a6fe66c0c9b023e8cda718c54475ba0db179d67b6df5be78"): true, + common.HexToHash("0x5311f67e507524de561f29952fdae7478ebf2af9ff79084aae1f7e51f77eba42"): true, + common.HexToHash("0xa0eb8390abfe2f074f1044585a4516c8536451dc08bf852651079aa2c1902524"): true, + common.HexToHash("0x5c2904c90259403ab27a05b5f2d722d91133959ae373e2de77fe4e688e88dcee"): true, + common.HexToHash("0xdf98a9dc3cf8a247806a66748533b55a844596da1c2adeae2c725a49d25e7d42"): true, + common.HexToHash("0x13d5529edf34133ad4799567a67deb71ffed3b1dff14a8c77e9ec7fe727de166"): true, + common.HexToHash("0x387dd69b3549d93b42058897101484c90ce7d7a3511baada86d032c8fa75d905"): true, + common.HexToHash("0xc53c4b364ad00e130313538b61075e355337466b6c1a7c713371add4e79ff76c"): true, + common.HexToHash("0x79a7d7127cd5eb426c6ab230618de3ac648591412680fd7e11052382c3632f34"): true, + common.HexToHash("0x565f323e0f7e2004b7f0d8e9c25b33623b007205d1354f7d746e107b76d9277f"): true, + common.HexToHash("0xddce93f59535544b51581db22bcaf22b274c009cb45e2b245a53822b4bb229e0"): true, + common.HexToHash("0xa601445a2321a8e1e54887bdd08cf0a0d648990225c36f1fdd9679fb84ebaf7b"): true, + common.HexToHash("0xac6d9b2548ec2971cb84c4ca7ede2978e7b33d77d999cddc90b8364399c4f766"): true, + common.HexToHash("0x8164670f5383dd651fc85106ffcdce1e6556bd04ce078f7e4667f7e9e8c6eff8"): true, + common.HexToHash("0xb1689853d15099c15521255c276259e299eb53e4254f5231837cb33b5b36ee5f"): true, + common.HexToHash("0x4f1e8ecd1b9d8a5ff23b00a1d7ef1b3a842c64101df0db0bec9b9547421ea370"): true, + common.HexToHash("0x9f3b4bc3c23bc07e16cca80a416c988615e21f4be1ee22052fc9e425db3d99c3"): true, + common.HexToHash("0x512a10c93c678be2bd2efeddb6d7b7dad24498489612b5dd5030d518cb843e5f"): true, + common.HexToHash("0x9304fafcb43c572005627a8f76a89fc28aaeb36768a8249641a722d9f3d61057"): true, + common.HexToHash("0xe669fd3cb5cdda1a7e9a4ff06372e302c4246f77a8a13cd456eaec026a36a360"): true, + common.HexToHash("0x73191da0ba0585ed58cbf77eb4c8d3c4be167642a1fc6497f6c47167b13cd600"): true, + common.HexToHash("0xa98e65d270acce38c6a61aeeeeb421927792dab87cc7c48336919665c6fe23fd"): true, + common.HexToHash("0x7e2a097a72e10dbf067c15369e599b5fc29dce88475b79304658c27026c0311e"): true, + common.HexToHash("0x0e7806d5a32ec8df4a36685f0a16d44adcd990eaf4c340e8c17f4dbfa0b327e7"): true, + common.HexToHash("0xf811cf94c64e6b1b9b3712488ffb6ed8aec53afee437d5bee2257a73e58957e2"): true, + common.HexToHash("0xbdcd5ae438d37895705c878265f42791e4c592c97cbacad3b4917d408ca4f4b5"): true, + common.HexToHash("0xd39e393f468aff64dbaf88960ce7ce19fe7788d2de24c86241744436a6638feb"): true, + common.HexToHash("0x678e2e9ea3ffc2a1a56e406dced3cfeee97bf260f610daff80f111959ff895ce"): true, + common.HexToHash("0x41f4afc92cd640b1e8e3df7ec53cb03de917a216314526ed989caea6e269c6a9"): true, + common.HexToHash("0xe44a2f86ee92e6249d6dd34be238692d80826d10b795a5fd1e11ac3c33598e18"): true, + common.HexToHash("0xb235f3c0ad4b1d477b43a4728472bc6d9bc1cca72aad3b0f8698256a56a6c463"): true, + common.HexToHash("0x015e61a3cc1f85566e9c038ddbdeb0aa3fc13b558436b80a48482bece3759128"): true, + common.HexToHash("0x0262085a6c16d412c4609b0a3e77d18ff709d961070831219dddf983a1c75b81"): true, + common.HexToHash("0x1b5e00cb094be562e493abf434a934330219f46cf6ec498728c581cf04dc7111"): true, + common.HexToHash("0xb0eb2ce6c2bed2067b1e7d621d9d07675cbe53e5a9b93ec6d3042e1f23447412"): true, + common.HexToHash("0x8a8c45dc9acea82f2834e5a11647bac52c841460a4f3c316c709d95c5bba5758"): true, + common.HexToHash("0xf438a9f9efff80528bada491ce6cfa1adb48bdc9b29c9fda96741c41593eee79"): true, + common.HexToHash("0xefe711f28bb1413925d6625fb1826507983e3b15437c22e6743ea2224653eaaf"): true, + common.HexToHash("0x05ce7602a9b29064779f37cd8ed70a25910a2b3475ccd00f1ccc8237e78e2808"): true, + common.HexToHash("0x20587520b27f3f2b4a3b95ff302d7ff97a9d84aaad3a475dbf0ec55a8698b1ad"): true, + common.HexToHash("0x5f77ddb672d58bd94db3954001fc77316c58665fe45151b044e43625be6ee656"): true, + common.HexToHash("0x51093802b659a2ca0d7ce100bfee7e95a610ee201ffd81b4122cf1d3e5772037"): true, + common.HexToHash("0x0d8f9e36cabac26a4853e54506c1a255676ccddcf29d8be9cab00f70c45a1516"): true, + common.HexToHash("0x7a2f4babe47e0cad2eab4b061b9e295e8a177a7987d527c0233a7f272f15f405"): true, + common.HexToHash("0x88d553623f58b9371e79b0e0aee845c229670e3b73d1e8984fae6a7b076ee64e"): true, + common.HexToHash("0x99317dbcfb57f5cc71b881ad0236f953ad8d003d1f1e4cbdc3ea41b707ff9bd8"): true, + common.HexToHash("0xd4444b07f3b3f0482e000cfb139b7e83178d84e0a32907c17d8ba7543ac780ab"): true, + common.HexToHash("0x21ec18f667ca5a1375e23499da9c6b2bda07134316762b765bc291122b8c0cfb"): true, + common.HexToHash("0xd31b45a1e1cf3571e2821b80e7fb913ce04c98051dd60c1a2c69bfbe0bb6ab90"): true, + common.HexToHash("0x35a124d0f522ac1b0564c5afe2138d4c9b5d4aed6f7209d56db8ae01b644cbff"): true, + common.HexToHash("0x35526bd44c1f6fff0ab7a6f8cb6f417c96e6da410d254b878865b92d1520dff8"): true, + common.HexToHash("0x4ddda98fa604769e5aa8f409de426b958881c8ccbf57e63b747dc0ba80697fec"): true, + common.HexToHash("0xfc982021499539c765a8bff688f3a6c24ce91fa24c033eeb8da52cd1369ebc20"): true, + common.HexToHash("0x09ef437aa9bf54cd9b74fa4779626a698696868656d8a920f5977280adf76f85"): true, + common.HexToHash("0x9f0b47d7840104f7f7cabaebb7e5fdd8edf696ef198083ea3bba34d25fcf4d51"): true, + common.HexToHash("0xe6806e36b9d81b4711c2b352dd71f4140c4df004044463e866cf9ba7fb051e2d"): true, + common.HexToHash("0x10f7118f2cb7c13afa9af2aa92c4ff9e876bd679e9f0559d628fa4ca22b3b8ab"): true, + common.HexToHash("0x5098422f3c870ee234be286f33d83b8cc1d791cff6db6d432f84af3d1b463088"): true, + common.HexToHash("0x99b9fc36a47c3a07a1fd5c211378f014be48b3bb53e2b4a50b5e51085b9dd8ae"): true, + common.HexToHash("0x3483f22e57682b9e077f04fe5317986afbf72c6ed12864bb7da3018e6d6632f8"): true, + common.HexToHash("0xa82d34795bc98ac911323e88e3dd2fe8ca206229aa689992f3f11379388c1cf3"): true, + common.HexToHash("0x870b54a21e270b2e3fe79360df0fbe21d456098c35adf11794ae4f5fea5953eb"): true, + common.HexToHash("0xe5b2f42fb70c2ffb4a4ecd4f51feaa5895001b92e580b0076b878f0d5c19c4e1"): true, + common.HexToHash("0x610d8975021149adbf5a46748303fe8a9ce08e17e607267a66798693fe08a85d"): true, + common.HexToHash("0x5f86fcd013d1630b27b31ecd8eb024946585fea8d8fa6710c8ec0c75014f6527"): true, + common.HexToHash("0x848b6f76053f90941b9d947313ea652497be2fabf4c93ec2b1d330d14b9daf4c"): true, + common.HexToHash("0x25a40e894140f49afc08d03c9676cfb54e5300671d19f538c8c3e62ac6d91c43"): true, + common.HexToHash("0x39198fb12e07bbaa2569d134beab8bac0d951cd8a3788acbd6bba21e08c7f3b1"): true, + common.HexToHash("0xb915b477b929059a331edbd5aec4a84df74c305e74ead400aac85fbaf34c84ce"): true, + common.HexToHash("0x4aae474dca928ae799442df48dc6c93e4457dd098fa02a8185c9c8bed3559ade"): true, + common.HexToHash("0xecda4ef5d1f12a0e31a7ab8d5bb319b0efecef3db16698672b9a6191311edfca"): true, + common.HexToHash("0x8ede416ba67a081bd7cc6240a7a8b6844f8b0a60e1c5ecad293e5988cc491b4b"): true, + common.HexToHash("0xbabeb5c2998effac23de5bfe89469a22e615bef3e0f3713794e20b98bb1e52b0"): true, + common.HexToHash("0x4149b26db2d1e2bef9014b3a34dfad707f8ab91e46da30a61095b6993b19cd9c"): true, + common.HexToHash("0xdacf1acaeb999326153f75adecd41fdead947d6696f4f9ab4d75bf119ed727b7"): true, + common.HexToHash("0xcc954e021677e8387e57454f833b58c70d76be583c2c99e8cddee9902e4d90ce"): true, + common.HexToHash("0x60c517141066a1653fddfb55b75245f3c10b185519edce6bd4fd88e1bfc62a17"): true, + common.HexToHash("0xfc19d15087a124ac1bfdb446ef46942840b7139ad3667e714d6967e162d379fc"): true, + common.HexToHash("0x0234589fb7aa22edf0578d5c01e3e8237b5a1dee9d55b6001a41280a68770de5"): true, + common.HexToHash("0x385909592a6f53a479f70e2160c89aaeff337558f7c77d24c95bd660c488bd14"): true, + common.HexToHash("0xf41644b522550e3566df8df668a15b0077744019bcb36a9b278157284fedd8d7"): true, + common.HexToHash("0x12e8b071f50adb52c5cb698d1f9f8e4dc79b9f0633554d46eeafc4caf69fcb38"): true, + common.HexToHash("0xd77c17e6e62eb6a86b24296f0bee507ffcdc53018cd13cf071e61908fc525daa"): true, + common.HexToHash("0x5788220d6110d83d4ab6d85c418b52fc288338155736a31aa7d5e7e0c3564e00"): true, + common.HexToHash("0x5130637aa64ffe49ec19efc5f0e8bdbaeec83d390f7cd4989300ae360a07fab6"): true, + common.HexToHash("0x060cd620e9058225d5cf81fe90bc1926972dde6aaecb31c95bf90b26dbb87e34"): true, + common.HexToHash("0xaf73d119ccc70b0c6203b39893df72d046f516f02e66d9159f616a2eee9d3e44"): true, + common.HexToHash("0xdf916906f393e95cdbe24a15ea694344940514adde5718764a3de13a5edf412b"): true, + common.HexToHash("0x65d00569ffdb6cd3f3f0e7740add66757515d3037f6aac6a5d9afcae76cd348b"): true, + common.HexToHash("0x34b47193cccbdae0372ee2fce70997d76b204506d53ec6a67d78935927c2fb59"): true, + common.HexToHash("0x98ae5632c7401212c5020b0b05ce83c61b03033425c3b759b43d36a958ed284f"): true, + common.HexToHash("0x108bace2b7b5efbdf89908e608681653e488fe3d31578640bfa460af6ae18e9c"): true, + common.HexToHash("0xd39039a57239ca606ed17e97529fb913ce3ae2adaead091e5440f90ff4ea1426"): true, + common.HexToHash("0xdaaf1874e1e138047760ce62f957c2c1e49eafcba45d509de6356c790177ed27"): true, + common.HexToHash("0x403fb0cdda7faa92ebc2a13b9e565d2650a179a21e6987a28353429393bc3f0c"): true, + common.HexToHash("0xc97125eac471a6377b2c03a82bd1b740b88019c254546a24c50fcdfcdf7c00e0"): true, + common.HexToHash("0xd3478e920c57ca3cf7b81023f9d23910088c25a53fead7eb6b083676b4bb468f"): true, + common.HexToHash("0xa79aee9d62ff4cbcdd7a4a9cd860f3f0ea5d957c8c7fdabd3cc822b38577ddb8"): true, + common.HexToHash("0x9f5cc7ec280cc96d46fe35fcfc345ba087cf2251866b5b00a2ca5456af29ef12"): true, + common.HexToHash("0x5e3535bea51973084eb43eeac3007fdb3224fb29a06520ccf6a37d3cabfc5dc9"): true, + common.HexToHash("0xd139023cbab698b29f453510e75f4d6d2cc58a9b0803697c7efd78666bcecbd8"): true, + common.HexToHash("0xc2283754e5a1e75e9afc2f8656aa731a5ad781d4a5b7ea00600b5b7175e8a8f8"): true, + common.HexToHash("0xbac258feea96d55e7a1bd48e020141e443aabe65de31f79276b9dac5b61814c0"): true, + common.HexToHash("0xcfd5fdf4324ad3feb36f9784b7489438898e28e6ed12a61976c5e8d89589797e"): true, + common.HexToHash("0x3a2c08a708fa410cfe84f0e0f0fbd06743cff9999ba5da537522a9e1cd14122a"): true, + common.HexToHash("0xb87c3c87742597202794025014200f5dd6e03a2f23caf435d6f2ee6b64df6c83"): true, + common.HexToHash("0x647682dc5c548411c5f394df4fa353064567129953b137ac2115126a1c29df9c"): true, + common.HexToHash("0x6a1fbf5a2a1c441d00f0ab1c2e3cae2cf611ea996215b49ad817dd60e4ad6c1f"): true, + common.HexToHash("0x9a6a8526b7a8c9bcdd2d2fccb678ca144daefac4f9208ff3bd18670e0518bdd5"): true, + common.HexToHash("0x9338c5bf96be42b163165132a41d13a11deced3e695e2aad89949ef3c264f1cf"): true, + common.HexToHash("0xd343b55f3e4df4e69e72019ab704cbed84d18faf3c335c992262634c990085be"): true, + common.HexToHash("0x1e373f22b539506e47ec345ede62ce7f5e2a555965f42a6b9fb0bffc064f0c5b"): true, + common.HexToHash("0x5da1b0ef017da1f06a6693e00aa85096010f74df85c01aebf31ee2d3d3d8018f"): true, + common.HexToHash("0x4a7d7bc98cd65bdc21ffdbeee5e1526bcc10d425da41ae174e1f795c148ea5b5"): true, + common.HexToHash("0x6b2fff7dc34f37c8f991653e981867ef31fc885a5aeaf31e5dc93b7a5969c1f3"): true, + common.HexToHash("0x35172c908646b16e9e7f065266a4b03b91a5043b3cdea3c0447c82b748106b2a"): true, + common.HexToHash("0x087eb07043f1dd67e16e57a76b769f5cb2f7160a271e1809bbf907499c7042bf"): true, + common.HexToHash("0xc5ff9f439336ad7b3ec477df8bf43cae81a2cc475dc62b30b00456a6bf433f61"): true, + common.HexToHash("0xc970c094bd7085a951c0ffdad58a42252b06eb22a43311be7909daa872b0d2f5"): true, + common.HexToHash("0x1e3e8d0fa2fecedc23eb96e3312dac42ef237f5a4fd397d44d76f9fda9a92049"): true, + common.HexToHash("0x6271ae7b81cda2a079886d77e76e48d1acb4fa0af770a081efc5b3ddef387556"): true, + common.HexToHash("0x387910b737b3984b8c81acac2dfe56a1274e4ccd45898ede5663944295231c9a"): true, + common.HexToHash("0x370c713dc8cb251021427e528fd2f68e51f3301fb02c59e0f1ba210fba5ae411"): true, + common.HexToHash("0xb5e3742594fe6e18ccfcaec45129f153216a3c011282e50273f8dc6cb6efe79d"): true, + common.HexToHash("0x2f79d1577db6d22b419ef302db36f40ed78e5657b50f3eb801827eadbc65c81f"): true, + common.HexToHash("0xa671375fb20f850125e452480440b58a7e10bd63a894c1bd528af0e91cffce6c"): true, + common.HexToHash("0x00c2d1b541645580b0b36c5e71003934ebe75f00a2ad3ed25b8411c92e77c2dd"): true, + common.HexToHash("0x68ce34ffa24210afb9692f5b656ad287177faf31411be2ed4e5f4335792c3334"): true, + common.HexToHash("0xe9f83631579850c8dbe9e80041a7c9b4e16de2a6c6046c24562c542d0cad5487"): true, + common.HexToHash("0x9a66ffc9be00ad76c30cf9f6b4b27b5a4d7c3e49bb1730b270e17491e337f4e8"): true, + common.HexToHash("0xda8cc5d4384829c3bf1c9ede255c3fd3356af7aab5ebf6cd8e6b1be7cd6450d3"): true, + common.HexToHash("0x1797edac4f2b4218fab4976040f83f69fd106a98434e19db0efc765f4f5312c6"): true, + common.HexToHash("0xa79cd1351dfcdbbabbb2b3aa78204b0acf993b7e077e1ed75123c98cb25881d9"): true, + common.HexToHash("0x30b13618a92e756093c2a8c0826046340e1d12c0b8865b398cd59edba502355f"): true, + common.HexToHash("0x7846f31f5d9a888583dd82c2e7fd784d1d7be57c7cfacfb3d7828f5f4a093b7a"): true, + common.HexToHash("0x79bc9f1b31b1dccc2b4a586969cd04c04f59808e3582f8c6b908fa4ffba8f090"): true, + common.HexToHash("0x6854ff8f20b3b7402bbd3178f2cf5320bc4f1c7f81d82c6aff5a0264fa91be5c"): true, + common.HexToHash("0x01661d9cff0b7e2175e5a3cc5f5ecfb4f621f846ed327260cca935dc42257068"): true, + common.HexToHash("0x79754942fd7ae619e70c83bab438276c145946bde1d552068e9ddd2f08ef9b9d"): true, + common.HexToHash("0x8023acdf497f81943d63778b786e14bd97afe3ae14f20c3ae1778f050235feb3"): true, + common.HexToHash("0xbb63f143c0747ba3f3a22c5198d77866829401e08856f7b65a8fa7b81bad8ba1"): true, + common.HexToHash("0xd3a2b8dc90b200c9b116f6caaf77d7275cd551e500346a16d422935deaab6aa3"): true, + common.HexToHash("0xee73b6e175e7a1a8462fad6230c4cad8063b577739ecfa12c514a0009e5f0519"): true, + common.HexToHash("0x5b77edac694cfc7225bef2c24727d44a0e801d9d196bcbc7633a2a8139c2e928"): true, + common.HexToHash("0x581837d7a13aec7f2f85ce77e550ac3cbc425735e831d7b9ef2bcb2f6b5571f3"): true, + common.HexToHash("0x0de62dcf166ba4f690b716396ea8e88c6a7c4b300efc944bf9a510eb2740eeae"): true, + common.HexToHash("0x845f5a0a593b23ce5dc97a17236c5d230d0d687fa039b7da997ded12086b3fa4"): true, + common.HexToHash("0xa5edd7c303d2e28e4746d4e0c67bcb1ab18e119b1b75d679fe908e4e341b6438"): true, + common.HexToHash("0xbb03a6246491750cdb844cc88121f9472c29aba6717fa4535851df4711b55b72"): true, + common.HexToHash("0xb51280fb3384ce404dcdf894da5b7d25c089895e6dbbd60ea268317ca3ea72fc"): true, + common.HexToHash("0x062e80dc34810548a0ecc6201a2da026248740100acb4d070af978549192edc5"): true, + common.HexToHash("0xf29dbc7fd08bef5c60c869c5cae2d4016021e1528d1ad1ed5851f6155c87d925"): true, + common.HexToHash("0x702d9f1b4caeb7070ecf3284cc14291acd972ef7717fc8d02dfeeb073bbd415a"): true, + common.HexToHash("0x3de11e5ad0857d134d53e23e90b1cf25fe999e11f95dcdcd86c3a309099aa270"): true, + common.HexToHash("0x12f03e74e2c64ad0018c64001911dae03f894de7d71da1c18a2c3935035597bd"): true, + common.HexToHash("0xdb10750e7d6b7361c7d223496df0278ed30d2a51ef9a84647c19f73dcbe77dfc"): true, + common.HexToHash("0x1502518dd184248e805f665b3a8418576f91e7e06da88b98e27165e2117a2917"): true, + common.HexToHash("0x1d50671d1c0218fdc0a5991df946fedfe285e0c89bf5a70aa2307077c3b0688e"): true, + common.HexToHash("0x687baecded2c6706f60cfa5e4e22ff53234fd3119f10383a42245bc0be2017cd"): true, + common.HexToHash("0x7f0092be06358a2331564b8a2759e38a6fba1f677b8de72243ab5fd846021c63"): true, + common.HexToHash("0x28795876258f6581f71fe212b833b680a770965db5a2a2aaa8f66446c642c828"): true, + common.HexToHash("0x54ebbf0e5ed689277b01bafb2b24c2b2ee5e70ab2f5198fd7603923f5d5888ab"): true, + common.HexToHash("0xbbb783b21700b48a082497329b0493ba8dcbe0b5f4bcb4ff6847a3ab098679d3"): true, + common.HexToHash("0x1d19b03636508ff3fbba1c277661607d874d75a1114cdb0427db80198f924d7e"): true, + common.HexToHash("0x89b080d9654076834f103e211e474986d645bf08c5c614d3c93cd73a15625460"): true, + common.HexToHash("0x9c977f8d0f2d2b5ade8c98b00b50f5d53d02f0a007e4d998d99abe204a8ef3f1"): true, + common.HexToHash("0x826fac1ccbaacf9ae423e1255b5b5bf5e20f37ccbd6bea3cb19da3d5345601e3"): true, + common.HexToHash("0x424028b9a8a25745013b3fbb1b3b5c72a49bb8aa6c2db44632e4a9d0de755bc9"): true, + common.HexToHash("0xae5618b0fdc63bc3e79cc8819e82d4d84bb62edaee8de3f5ce0e73be2bb079b0"): true, + common.HexToHash("0x73e9e6b76e9bcb1e2c25cb925a256c1525543814443e5584645fcd0b2fd5dc69"): true, + common.HexToHash("0x65cfa5845a8b76a8beb6a5868acba645111a450d9bfca1fb04fc8b89e6b74d24"): true, + common.HexToHash("0xe7149c0934d1fe64c50a977cbc4e116e6e05be820a1bdd4e2985df16e32bf333"): true, + common.HexToHash("0x57c999c02496531914b6417deb7139bf71efa044296abc2934caa87f4d7d0b0c"): true, + common.HexToHash("0x3a349f3026f8aea1ead8cefb9564b81a0ce12c8232299cc33f2d1ae292dce081"): true, + common.HexToHash("0x5afaf4048f58ed285bb793984e92987954f76c14a88f6e046a0ce98952c5f46b"): true, + common.HexToHash("0x93790c1c48dfd540b8393a9d36ac9f5474283bfea5171f2dd1dd5f9137b49524"): true, + common.HexToHash("0x15d39f1274846d450cbc83605c1f9f96ba2629d04a063e2f0ef5ae41ee665591"): true, + common.HexToHash("0xa7e3abdfa5853d81f4943f73e36b3798f32a2fc7f9d3cd507f4909d68036b59a"): true, + common.HexToHash("0xb9cbcbeca220aa04d115a80150e3c598949119a33434710a63e9a5c03dad3b4a"): true, + common.HexToHash("0xa4f6074724110f19e69b9a07c34432568ab420645c4c9e9f6526df083f0652b1"): true, + common.HexToHash("0x504561ebb22a8c171ef65827be51dbdae0f800165575f552b2c1f32b59e2f323"): true, + common.HexToHash("0x541c59dd8a16896a338677122646cf088e49d86143f55ebf358e6ae227fafb29"): true, + common.HexToHash("0x8b60400bdd673a66b352ecc3e4ebf1489000571fade40db50f32d146343297b0"): true, + common.HexToHash("0x2d331606d2823c35e689b6f74af4b2c1270eddf336787487054bf75317184d2c"): true, + common.HexToHash("0x2bb4bdc84a9f81799c33983451003afb5c33221dbad2605138fb3f8de270cb60"): true, + common.HexToHash("0x1200b33d1b7221c520771536d70f762692dc0316a17bdda15afe66ba6cc6e8a0"): true, + common.HexToHash("0xa01ae15affd3212e84002dda8f22e16bc6f03e11f40a780f4c2c0d118479a351"): true, + common.HexToHash("0xf7b4e26376a647b7703ca2d97cd04e4b3c8f7865ae4f17f3b5bd30ebaa96713a"): true, + common.HexToHash("0x82cf7b89909f9ad0008c99be1ae46663963905f9367edac4f15266ccc4f94977"): true, + common.HexToHash("0xe2d882cbb27d50792b02a139c064ffaaa1eec21ff24fc9cc6d020e015c3e5ca8"): true, + common.HexToHash("0x10a378591b8945998fb905db571831db5cf31dcbce948307481e08e5fcac17ea"): true, + common.HexToHash("0x2e6cd61838ccc112fd18b35f70c92236eb0012b586fbc493cb583944efac7495"): true, + common.HexToHash("0x15867a5ece065c62e195a9b766976384d1a2135c4cef3cef325567f9798e2a3c"): true, + common.HexToHash("0xc01208235c82b74b92ebbeabf1cea7b2306d0b7bb4c68df1ca0c9f42fb95f1a5"): true, + common.HexToHash("0x12747f481c0cf6762a6e906e91b71aa1727bc79bf26776422e95e1c9e7652d51"): true, + common.HexToHash("0x0d7570fd47ac53d21acbf663b3a6fa254807fba5e5e934d4d1d4cffa37154a74"): true, + common.HexToHash("0xd0192e54df3b9b8c8eefbd101b942beff1b15367353c2cbfc282569699d8c4bb"): true, + common.HexToHash("0x017b32c39fe3ead135641ba964bd53b08410616c13047ac404ac70217b5a366d"): true, + common.HexToHash("0x311b6091389e406ecdaa2059f45c1fbfcdb47ed826fe99b88eb4f78525d8968e"): true, + common.HexToHash("0x7cd1385b70b6dfa86dfb0b7340d74389ade7201fccf2c642c553166d3d2332f2"): true, + common.HexToHash("0x11e6b49fa9a293068e5eb9b676a1ca8bb742d23502c03d8900de960a28ea84c2"): true, + common.HexToHash("0xce5cee33d863594ee4e7b316cd3d259f51e68c1e29e3088d6a46e89e67b05587"): true, + common.HexToHash("0xc7c67e83f947c642ea9fac274c5c500e83f6b71dec2f1a9e853febc090819d19"): true, + common.HexToHash("0x12916fab25390e345a2fcd8b904d6c4a3ac53092b59b6a5cba89930c4c55c425"): true, + common.HexToHash("0xaa6debcf5e72665ac287aa061b7f9b1710e4c4d8b24d80789c172ef7e5af0c87"): true, + common.HexToHash("0xf1b3b648925beab4b6fdb63f8abe3f43005c95bd09c43d9fd12801eca7ac0292"): true, + common.HexToHash("0x08ff7ad57553cf6e299b796d496be6d51d4dcf2fc40bd61014cdd001ee558aa4"): true, + common.HexToHash("0x5cfdc9d98fc82c61403268a91688955d5e13239c4ca23463265b4b6dbbfca4bb"): true, + common.HexToHash("0x8c13012b1fae2ff950024b1bf707bc59b068846156cdbf0805813056b5f12dff"): true, + common.HexToHash("0xd19442f7752fa57e72c56f6b6b940ddfd2620d0ad45eed476eb9c2472e28808f"): true, + common.HexToHash("0x2f4bc0fa58f3a78eee8a88da21cb3dfc38202c5b9b98097206f875ca31756c40"): true, + common.HexToHash("0x7e44608f656ecff896f901eafb900bfd5f653ccb48244d6a8c40c86f709f5489"): true, + common.HexToHash("0xe36910835f9434f8ca7be9cf65289142380bfa888938d330df431890ca9e5f5b"): true, + common.HexToHash("0x909a5f2a9c015ea36d193339d89b9e621a7d70330d1cb40e4293649d5257bacd"): true, + common.HexToHash("0x26d664ef654281398f8551dd47217237312648b52a82037bcd2461b916ade997"): true, + common.HexToHash("0x911069e3098665879e2963c40836ebbe353d31065b9cc4331e83feaf4cc79dad"): true, + common.HexToHash("0xf5d088259c1619b719ee742c668055a2b29579cef73104390226c8e17ac9da35"): true, + common.HexToHash("0x5622518619c1df375127f511d70a96d7731baf1f1180c2728ab8883f2ee19f1f"): true, + common.HexToHash("0x0b83468252ce9a857fc5fef9f29c948aecafd85f2e5d763bec1bed4098c37e86"): true, + common.HexToHash("0xf6298b56e392582c5f8e1a16e684d6b0b7636d414ecb8b7cac3bc7b113dec058"): true, + common.HexToHash("0x60ee38b4024a787c8995aed21a29d730f95b9615ddeca7b176400182b6239269"): true, + common.HexToHash("0xced3ced3d2150c51477d5246812601390b002029180b6895892e9f0a76a4943a"): true, + common.HexToHash("0x2a0850a4a3d0edd01338798cd183e320f31e781bd64abb9725cc54311525b41d"): true, + common.HexToHash("0x78cfabc43a01b3128489367e5a3547092d191665cce34ae0c703ab4d7e83b912"): true, + common.HexToHash("0x2d0274bc0a397ecaf1b994efff429d864ac8c8c383f9b8340e751484f0ffd5a6"): true, + common.HexToHash("0x06599ca4ba42c83a86810a710cced2813427e0d84f779b71f5cea0c34a35ccde"): true, + common.HexToHash("0x61b6bbdc196f2625d959107ceca3d414a2f18f50750fd5b4e304325b5a6b13b0"): true, + common.HexToHash("0x0c3fe9c32505659ae9ddc658ef91027e454f8ea4dc74c15b30cc49de6e9ca909"): true, + common.HexToHash("0xdf2d9fb92d910597680947aafa4e4a1800852f570c0cf1dfbec6397556116160"): true, + common.HexToHash("0x30af6aac8c634e3f911951f1ae9628379968acd8775b3e49ecfefc33d3c04c58"): true, + common.HexToHash("0xfcfb9deabaf9cac005db35132735de4991608856372e302ae991c37a71f03ca1"): true, + common.HexToHash("0x21076ad4926f49a95e1cf2a5d1ee3a7c609003fb8525f997126a2f93b6d28a49"): true, + common.HexToHash("0xb98e2a6e97c26a7862e27eda367246ef8bee1ae42caa151b7ff8893690b68cb8"): true, + common.HexToHash("0x98ca46cba9616fc099477847817ba191514806e8110ed8a8b1e1fe2b3afa5d7e"): true, + common.HexToHash("0xfc1a2f4f3b401af817cf660c32fd0534e2707e14f050f58ae417104c7b620013"): true, + common.HexToHash("0x2d71a2e48acf8f28c576069c1009f68a8a27664dec4896d309d65587b293498c"): true, + common.HexToHash("0x7958d08cb29af4140160d339d063302a503155b67020ce3f347283525cb76ccf"): true, + common.HexToHash("0xaf9fd6aa18e47c9a719cdaa43825276712ce40cd3cc34085497cd0bcd47362a0"): true, + common.HexToHash("0xf95abdac52d1306ed43256aaca781eef6f4856c1b0635a168cf0f468a2d902fa"): true, + common.HexToHash("0xa4fe8fe7fcf1128d6b962179d043b84d678e1ebf324c02bebcd122f47d87e42a"): true, + common.HexToHash("0x80e1e8e165f9a45200563c9a9d1b727a266dca12a59dab0a511cfccc6bd6a86d"): true, + common.HexToHash("0x1e38476a67cf0d76fd2d63cc159ada1a6d63c45e7385e6a60da15d3115e5242f"): true, + common.HexToHash("0xde1203ba7d7d028836be56b2c3292417a0ddb99cc953dc1c6651f3831136a35b"): true, + common.HexToHash("0x4b4bde1e6829699bdbc2f9612c486247ec2b9c797235ffee64938a5b756baf1d"): true, + common.HexToHash("0xffe44e15ccb9bc37f697d17ba1dd88dc3821651b8e6caf528bc675ccc9f7c782"): true, + common.HexToHash("0x617929e002610ed20b043eb353f48f009784eddbcb924edb27df02c0e6ab6803"): true, + common.HexToHash("0xd626cb657039e849f083eb4a767bbfa11f5e6418f58fbead5845d9df0153bd88"): true, + common.HexToHash("0xde409266696e6c54c4c22c4e81bbe97a113c859855c4511a2bdf36142003e717"): true, + common.HexToHash("0x5bfab0bb5d473484e6b2f029fc929f8a930453fd11c4fb0a9eda76dd245817a1"): true, + common.HexToHash("0x81c80f9351f8a5597cc4dd90bfc79d6ff8501680d7d2f4e7c6d69010ca14255d"): true, + common.HexToHash("0x2131be5aa8bd9b05f67c570e01c8aadc857ee5ff36b0d23ac03ed75a0bd64537"): true, + common.HexToHash("0x6eaab3ace8556079d591e50c9abd4c95f520dd177d86bbc9eebee3473695fda0"): true, + common.HexToHash("0x305031ad001b7f383fee352c86b93a840a441b40a8ef9df54582705be7f8961c"): true, + common.HexToHash("0x1fbc593476878a5af057150147c8652901c4889b745ce46f608ab501b790073f"): true, + common.HexToHash("0xa2f5d1e230febaa37d4fcc8f17a0c1af95c002672ff93c4dbb645f04eadc8359"): true, + common.HexToHash("0x610d8f88a4992279b967d9543a8fec996b4ee42830ac0120c5ee35edb71f8aef"): true, + common.HexToHash("0x3f630b87bf0259f0ded37241723475a0fc722afc2a860ab52cfa5393ccaefba0"): true, + common.HexToHash("0x6ab3e0b85862aeab2c5238f41ec717ff639e900441fcd51a713e37924ec34fcb"): true, + common.HexToHash("0x5c809d859806fb7392e96c863d670180fd93b68b33db5c2fa4128705356aa1f5"): true, + common.HexToHash("0x1b6ae59b9487788b9385ed741aa17e32afda53a376254fb3030f0b5b403f9e36"): true, + common.HexToHash("0xecf9e8f1c383c114610686a7b971eca74d459fc310c6036dbf92ec194fae00d3"): true, + common.HexToHash("0x13cc36215aeedde62af0df94c744c33705eab000d940c447ff6db60dbe4c352f"): true, + common.HexToHash("0x2f288654f1f4747c0b26c5121d15ec2b9d7f8cffdc1b6fbe69f46033abfd1b4d"): true, + common.HexToHash("0xb2f2ef3a43f6353410600a8f77e0113cafe83f42a9d10a29ccdc665c2f17ac8b"): true, + common.HexToHash("0x3d05b08e5db4f3a25b7b106899d2ae095caf6520e634a932f3381092e064219e"): true, + common.HexToHash("0x0f1225b943348a76bdc29a88e5e1811227dc28005c67edf07c6f1838b6295161"): true, + common.HexToHash("0xc8dd80bd0313643ba55013f14100aded9b9d1778fda286dd3d4dd5bc82445fee"): true, + common.HexToHash("0x5b2cbc3bcd2016ec70672e971e8acbceeae2a42190f28f0bc7039e32e9a1ea34"): true, + common.HexToHash("0xf21e4d05bbe599f4a76c7f0148a47981307051b3070334a3a99b523f3a5368ed"): true, + common.HexToHash("0x815b1eb5c6b94a88a4c9144018bd476da19f5f6b60921c880faba8c520a78ac6"): true, + common.HexToHash("0x5d1fd58e3beabe22615f6d6fa0b1f3e9dba1bd44bcaaf2fedbfc2b6fbd89da60"): true, + common.HexToHash("0xd59e31f0707184af329ff057c65eaf2223454495bfc3f00c31653a1753abcd93"): true, + common.HexToHash("0x644b87d7a3ee8b5f4696d6d5a9861232eef6ef07504a7745199892df90a789d5"): true, + common.HexToHash("0x0123164ef51729af8afc7078fcd6786d23da11bd985a6311dffa922453f337cb"): true, + common.HexToHash("0x1edb8c3edc37b1839bd78a915a3c40d766e3d25a46aec49c01972596e66c4651"): true, + common.HexToHash("0xe751cd1b1f4fa676bbbbccd50f0742173ba124808574c4272ee35d751a2d2858"): true, + common.HexToHash("0x0135bf71b4058992e548cca4b3a4a121579271573eda52c789411ceb9a72c8b8"): true, + common.HexToHash("0xe126f71d5b4e5db1d7b31d1ed2707558bc86bdd1c4feb16bd04afd74b4f261e0"): true, + common.HexToHash("0x69314ae8ee1045d64b6168072550e6515053e55a8d4da1c3d9ad8c7ebd7f2470"): true, + common.HexToHash("0xf07e7b0c8eda59d27b2ea8353218e6027c351e16bcbf524fbcb1a10ba04d66d7"): true, + common.HexToHash("0x6084b75e38e36cb674aea245eb1df61281f748241b0dde3dd8118b557f583446"): true, + common.HexToHash("0x679d1ed615b06a31ed7fd87f016e42b51a057c2a40cd28c1df713688b05418a9"): true, + common.HexToHash("0xe067727b3928446e56492f74b3e11f82e0724500936036668947ad8032ae3609"): true, + common.HexToHash("0x8ec4e81ce98b875c622a39f2ec26e4c7b09f874799fe52cdaf32610e4171ea7e"): true, + common.HexToHash("0xd541d18f5079c5a798439eba658707f2701f03226bc2394b594c412ffacd6585"): true, + common.HexToHash("0xbfcb39608550ed1b35a36ecddd23d94e7dbcdc2a62e71387dca6fb1ab6aeb757"): true, + common.HexToHash("0x60f5806beb424075c745d67eda1627da2a121ff5d6ed5eceee7126b6847f17c7"): true, + common.HexToHash("0xda3d9a1a065c40c1ff17bfa4bde51a978a84fc54e1efa1e4165d4b40b5cea487"): true, + common.HexToHash("0x89eab70051953f0f6b98a3927c6af748ec257859876c328c4d7c4187dfcc4d7e"): true, + common.HexToHash("0x931f863d3f9b41e192687edba3901ee6bb5eee7d532d53981d9776a1351253b5"): true, + common.HexToHash("0xde218ddd32b95801cca9b1cea4a068a568c9a197b548e82a861600bf59ed80af"): true, + common.HexToHash("0xa1ce7e6881db1eb8330de3595484650a965e5087d15ce85d135813a184584714"): true, + common.HexToHash("0xfaf8242b0d424dad4efe49728a759bbc985d89fb51cde257609d74f548ad6c2e"): true, + common.HexToHash("0x226eeae142b332ad9772662e469b9a8569b3cebb56cd45edb996db56e6996e26"): true, + common.HexToHash("0x5f171c5d98dfba7bbd0dcf33b2bd5e5262879614ffb0653cdbd87fc789f4220f"): true, + common.HexToHash("0x7b1317bc827bb2327fc7a7d8113af9d7d83099d933c82cfe112b6e9bd8806be2"): true, + common.HexToHash("0x30836bf1d25539ed5610722e52101c3fbae3125de23733a387ff3854d572ec05"): true, + common.HexToHash("0x6955e49ead21f7c1e254b6a6164d0cd8486f5474d6140dac6beb7208f030d557"): true, + common.HexToHash("0x9cde067fc48f77157f43cd7adf0885a99f54286739e9e005b78e1655aa178a97"): true, + common.HexToHash("0xf8fd960002ae56754bb4bb1189bbf6dff9aebe9ca87c1cac5eecf07dabd57a23"): true, + common.HexToHash("0xde4c87089e58549456621b84c10e58324fe260e1ffdf6cbc0d47e4d0c8b96559"): true, + common.HexToHash("0x6e31a7db3528da27d5418d93f66c5da8ab0bd5817e9d3444311a87091784049e"): true, + common.HexToHash("0x7c5b6a46cdf23acce611d4619cfbea3c25ba3343caab156a9d84314409205a0a"): true, + common.HexToHash("0xa9924698c01122d5b66a679a445c7524af831b2246b3294048ae7d18d570e011"): true, + common.HexToHash("0xd7d062c34e0dcb93712d50ae5804c46bd759e0602727c4525c06325d0818db72"): true, + common.HexToHash("0x36656bb0f85b9a51b36339efdbd2d7874b4052441e8f13ef65fff8c98f95f323"): true, + common.HexToHash("0xc741c7f434053ca4a99c0b8d5285d34fb78d8ab42d3ea8dd07432b0a0a11bd43"): true, + common.HexToHash("0xe043b025efc9d4c6bf81cfc8da0487672bea494f404a63ee4d403c49974fca43"): true, + common.HexToHash("0x1345f69c226c3c0441579ffb0f32b2bb34cd86dbd74648d9d3a7c5a7651e678d"): true, + common.HexToHash("0x2ea51c2016d8f71956ebb3294d75c3534208648eeaa97a8944e10b3a340bef54"): true, + common.HexToHash("0x410f1441b895b142f7b89c9d367c131259aa733de19a2f3ca70699c2ae279581"): true, + common.HexToHash("0x0ad25a0e6a98cafb37ea5962c76264e12626af4658f800f268a9437f99cf3580"): true, + common.HexToHash("0x6e652e6ab4de147562675697153d26e5298f179459ec551b9385c4e705216267"): true, + common.HexToHash("0x90875bc109fc1cd904046e1f22c4502d27521a34f8f6405161e0067a4c31cabc"): true, + common.HexToHash("0x9d9f11766205680a6dc069ded6586bf9ba47eacf3f81206378c444da26d83121"): true, + common.HexToHash("0xa5b697a8015e901b13977d7be37f67a64a2deb88a0741197a29600ec44ee733a"): true, + common.HexToHash("0x7a4694c44a85b792ba989ccc61cbaeef1e3a49d00e65544f4b921011b509aea0"): true, + common.HexToHash("0x7bf2fff19cfcfa6f52ae8546b22f3221afd95efe20defe2d488dad085eb9488a"): true, + common.HexToHash("0xc37cc9d0982f9406483261e1b9a53b072f2f3d63ab91ffcafe956b4a2725768f"): true, + common.HexToHash("0x1bec53f7298bc272cb7d937f2c663221c44e424cd4bb5e12fb02785db31ed106"): true, + common.HexToHash("0x1c18727eae4c519b813b0ef9e1a4e45470c24abe931707ed162ea79eae658a49"): true, + common.HexToHash("0x1e5f68d3f80e7ef84ce647bd582e0d44378a832d168f8315c2268ff04fec81c7"): true, + common.HexToHash("0xce58afa19df98bfbd2531883cce8fbc64880fd50ac0057d91777cfd2a050a6de"): true, + common.HexToHash("0x959b6330355c8ad50c685b5eca727ac951b575ec745594ff3044ec934385783e"): true, + common.HexToHash("0xdc4b628e6c3cdeeebc136e069e6da6533e8c9b8db82d2a1b70fcad34a9cf0ad0"): true, + common.HexToHash("0x5209ce7ed07f9b032658d3385f3ce11590f1fe12b0eff8e7f58c10a1d6b1dbf9"): true, + common.HexToHash("0x190a38190243dd713cc00f4936772296657f18174174a66399e55231c726353b"): true, + common.HexToHash("0xaac7adfbd193e4e2043a0921d8f81b8ec0185755e9c29676c9395f8cc09656c2"): true, + common.HexToHash("0xe7b23ac268e0be11ac5296f71e018a5cbbf9eed907ee4ee3d9f5d5bbef09e056"): true, + common.HexToHash("0x51d2110a66c630b97d7b2345e81b504304938af0b44124e93cd4e4962c40e9a0"): true, + common.HexToHash("0x3b5da26902961a01c8989999256eddd0b7c275ff323b830de16114091d763e2d"): true, + common.HexToHash("0x349ac9ca17accc5132733e32e8c130ac4b09c3038540565ff2006bd6dfc17dc0"): true, + common.HexToHash("0xe5541796d20749f6f746408e8de91c68e770e4277beb0b2153b84eedc269c3b9"): true, + common.HexToHash("0xe4961105037ef886b15468c95726d3d09b0902976583dc2589918dcb6f31587f"): true, + common.HexToHash("0xbadf5b4e8b3e68c00f24749bbaf2ac57cea84c2ee00c5b8b7402900707ab6193"): true, + common.HexToHash("0x10b913a1366d3ffe29f3bc5e537da1f30dcf293cfbf68f942405cac3abb0577a"): true, + common.HexToHash("0x86b18373779b94e1c95d18e789a716eea6882e7e69e0a82975a0eea88bf68fd6"): true, + common.HexToHash("0x5465d04e76e1c7077a93f1978fdcffc6f41ecad26c151590166c60e94f05aba2"): true, + common.HexToHash("0x0af09fe9d5c6fd707c034a4aebd83168554381d20b23f5f82003c4f24552136b"): true, + common.HexToHash("0xe3db55a96a34f7a246ee4854e191172896a002112296558d859d1efe272f9ef6"): true, + common.HexToHash("0xd42720b8be6023a0248d0715db6b6dd36ecd1de61d09fec955e0eae65c42a617"): true, + common.HexToHash("0xba8b5d4b80df1e2268548e292921a344519a2bda0f1ff7e29cc616c58a89a1f9"): true, + common.HexToHash("0xe9fb10ece9933488c07077867dc8fce933991440ed5237ed4b60a3687ff9841d"): true, + common.HexToHash("0x378b90f402fd09cf8d8df4f2d951c4c6a5f872374af934d2803ce481f1bdd431"): true, + common.HexToHash("0x6ea211dbd57872dbced0fab5fc233e95c7302df00520bc5717fe981aa19bce25"): true, + common.HexToHash("0x20a59230339568a4e446ce91baef18893132d819f578d3ee93c5816f179fbe7b"): true, + common.HexToHash("0xf3d0223480f013347f1bca8c113455fd6afdbfdf8e4921fbda0b746f9996f66f"): true, + common.HexToHash("0xc3601489920b8294b084030aa43af6f06164341a5646695d696d0366c26a9424"): true, + common.HexToHash("0x270b33e0901807bc8584c7dc000605b3054aa7034d24d406e2327077f7ff3a83"): true, + common.HexToHash("0x9bacb6bf779bb852f88b4930f7047b83a73def47399a6b4e1039253a791f746c"): true, + common.HexToHash("0xb3eb82e80283a5150d355caada2950b232ef8f9e04231603d32ff69b71ee9098"): true, + common.HexToHash("0x8bf2b5c4e3a9b68d98f0b6e8b60eed53e0ae303b44d9be60e9817fd7f335e280"): true, + common.HexToHash("0xeca5bbfb03c4c16a2ec448198f7c233d87ada5e1dcc510cc5d197cc588f96301"): true, + common.HexToHash("0x98881578972295ce46161dadb256472c3b550dfe5c9e801d94943a4ad39e10b7"): true, + common.HexToHash("0x94fde01f4f61e2e6310428f25f6dbeaa0c8e4a0e4870df23dec12408847e60f6"): true, + common.HexToHash("0x569a9bf7a2dbd59b15974254052e104c79120ef7e964f853765c26c8a11e8a17"): true, + common.HexToHash("0x95384031160cc74842a6923e28e0589b792f56d3cfbe1608b2c53637c254e772"): true, + common.HexToHash("0x27b388ebd7fb919fe94113d90d4e63f2875aae67ba39c2ca65adbfac55f40cb9"): true, + common.HexToHash("0xcbc437db63acddd20f8fe79c942f4fece51cfa05a184d81fa6be4a463082c92a"): true, + common.HexToHash("0x9fd9d0f7593d132c6ed023ebe00f11e98036c8a0b5ec60c40defebef64d02b37"): true, + common.HexToHash("0xb9d5b4427829c81001d89f81e47ed9091b230a16fe5217c98b0d20c5ceffb24f"): true, + common.HexToHash("0xc23b7e3c8475f6448705ce3b27d63ed51392918aae0a2f12b48c843a933e6e0f"): true, + common.HexToHash("0x4e372d98a49ae5a95c92bab1b75bff1dd96c6ad6af6e9c4dc97f819a36ae1062"): true, + common.HexToHash("0xc3757a4b1b478168403db69d391c49809c8408cb6cc60e33687c856c6111f65c"): true, + common.HexToHash("0x755c9f4205f6119b5001d45140a90464f998d3efbde3882d951c2dbd0f5a781e"): true, + common.HexToHash("0x408dff60312f99e2e7dc89f667666ff94a4b73179a6f449b570911507530a4d9"): true, + common.HexToHash("0x5de2d73b3e5a6a5f057d7f6c27c3b62e2ad90082166f393378404ad7741ba13d"): true, + common.HexToHash("0x3a3443bafbc93f2f818ac54728229a6c9a8a3e5ba0a4617a97b194d673014299"): true, + common.HexToHash("0xd495618e7a89ef70984bb8f4e272cbc37ae49c8cfa9d5b9c9416c518272b9f59"): true, + common.HexToHash("0x4fe900f819d68b8f2471b2be7feb4f0c61af89dff59c078d0dde6a4f0cee4686"): true, + common.HexToHash("0xf276288e8846829975cfe5030ee7ff2020997021278527ec59475a0e55bf2aaf"): true, + common.HexToHash("0x5fa9137ddce705f8dd9de3e8857d30393f820e812cf4602c03315e6422514fdc"): true, + common.HexToHash("0x455389d683765ac6ba36834ed943c8b76691c18485ab27e75dc454846029fc55"): true, + common.HexToHash("0x7ab1d165cd77939cb0a69866f6482de47783a15a1e5c3ca2d95bbf85014b2d58"): true, + common.HexToHash("0xba0264668fd8800ee6796cd703a8480d91f03a3a3b8e6dfadc2454fee81cc82f"): true, + common.HexToHash("0xe959b48cce40022338bd5ddc1d7cda2fa616d346042f0819af1043ae2525882e"): true, + common.HexToHash("0x71fa4bd990581904844a539dba484d8db3ba7bf9e6db6d6f961960c66a72ef9f"): true, + common.HexToHash("0x54ce434380b684a34dfdc5e87e86d18adce6d95ea2b40795469e5be661a102c1"): true, + common.HexToHash("0xcea9f55f7d3582e17bf8e67954a714257db0282b4245b051a99ebbb2dd5f0fa3"): true, + common.HexToHash("0x69202baa30f63e29cfb80d37569d45d4848a041e58f3bae283f53a2a585568d1"): true, + common.HexToHash("0x11e5b6e5af57629926374ac8a6a9bf8aeb197367f14e17e1426becb3d1388278"): true, + common.HexToHash("0xd46d4b6d04fcf37008834c278a54c0569619089561eaf515891d4216740d1ae9"): true, + common.HexToHash("0x129889b60d3f4426fb51b504c6d7aab3600056fa72adc05e3b425a317e029db0"): true, + common.HexToHash("0x963c62ef60e593e2c1e24f622e38d2a568e70b7e2a24f8a01bfc801e1db806df"): true, + common.HexToHash("0x8a9c7219fb2170ed67b734fe7a975a0de5a80c08e745c5d75b98b0b80c7ab23b"): true, + common.HexToHash("0x7b9ac1d32d3c8b68ec8045b12d3186f803b910a611c0e696da0c1fd45075a5f3"): true, + common.HexToHash("0x4264919d38480979157d174e05b8642709611c702341349d5e34b9e13358c682"): true, + common.HexToHash("0x1bba0c52e55367cbe90f46dc9612fd26841965d2689c4eed31246dc433d6a5c7"): true, + common.HexToHash("0x0ab7e9fd786fe02ce082a208f3b397addf9c55c13094075291092b64a66daf82"): true, + common.HexToHash("0x160aaec2d2acf260b39fc042973275b406227fd7bfb9516f11a5c017011d70d8"): true, + common.HexToHash("0x08d1461e0fb1b4996fc0ea0390a5aaff3606780a222fbc56b82d07b55d842e79"): true, + common.HexToHash("0xcab042d23149bbe0fef497c6626d9ad4de61366aa294c75f7863b3b8d5f541bd"): true, + common.HexToHash("0x382db47dc3db8ea6a2f63b98df1f1e806ac627b3ad27774ec196b2496d30a8b3"): true, + common.HexToHash("0xe1d146a3012b4916875c8ddd92c573368cb631bc195ca1e505b44155f51e486a"): true, + common.HexToHash("0x12a60aa43eaf55f37cb6ab35ce79ccbf3c5298cfbed02f491ef547ebd6061536"): true, + common.HexToHash("0x588fb1584f259e22bace01a8cd9088665f5def5f5131766993d585fff2e2d8f8"): true, + common.HexToHash("0x62711722cd1c128301474d66ae84b0b213d095de02d4fff08858570b120e7f69"): true, + common.HexToHash("0x0352b07cfcf4dcf1f6d41a2a2903155f3d7806b8914ed6c866591216ab44c69c"): true, + common.HexToHash("0xfe4d54ab826c8ab2cbba0cd1e5342d4461ad159064278b91f672166789839bcd"): true, + common.HexToHash("0x9de1bd3bde1eb51a32b4b7303224f9284e5c5eff3dee00cc0e9bad585cae5c2c"): true, + common.HexToHash("0x779262e30423037d6a895acfd4623c65672e21c8dc3cb3239117623e7d72e85c"): true, + common.HexToHash("0xd2b0e126304d295484c0a206a0f02b5c2844d7ac760cd44a7ddfc9308069984e"): true, + common.HexToHash("0x05088af008186e466a2fa1fa11d705e3891c7ba7541be57ff1c198f3ee3c15f0"): true, + common.HexToHash("0xa7495bdb77a1c4ab6b020886d5fc50e76777a79057717511f85f44529f6859fb"): true, + common.HexToHash("0x1602d0ea7b7856a9c7aefe97ca24113655447a8d840b9789eda09e574e93dde0"): true, + common.HexToHash("0x64c9d4e8294b6d905cd3f828f679877b3545289dcadfed57bca4f7e3652df3eb"): true, + common.HexToHash("0xbfd953aca5930bfcd3e15fec1bc740e1cafa6579e7385a3844f9e460a9eadc50"): true, + common.HexToHash("0x836cbcbb93c8454614491018633f2cebfa4a8650e6db940865b17683cb7d1b1b"): true, + common.HexToHash("0x7a33cc67ad32b0026abb0735792ac2c7c1ef72c7ecf61d95b551222dbba58e1a"): true, + common.HexToHash("0x62ea18557b95ca75d7116e69ac33179a76384ab3738fe514913832df6b3dbbfa"): true, + common.HexToHash("0xa2bfd157d3709602b2205b8eb10be14db925a5b2162789fc9f6c0f21ae9cef8e"): true, + common.HexToHash("0x2cd39294a1b0221f0097d038d18d7a6ba4314599cba4134bb369fe62a552b944"): true, + common.HexToHash("0xcbccad833a691db627bbf8b26fa171d08335dbd2dd011ca53fbee19864c28512"): true, + common.HexToHash("0x5c1362646f681987f0ef3e540633663ceeb8d581dd0a9df89cddd17cd018d0aa"): true, + common.HexToHash("0x364d2d5a01933170b793aefde0d845efbdb72141987cb91aae3fdcbfecf722ef"): true, + common.HexToHash("0x0278cf54217de01e6ae8c6bb44706d62cd563e778c65dd4c10c1964dad6fa0d1"): true, + common.HexToHash("0xcc8012cc940ecee791ec76b755358c11e89b423c247fed6a27356c8401aacde6"): true, + common.HexToHash("0xad1a36fb6e3c2518b20fd377f10743a94d6506a366dd6a755206ef9cd6313422"): true, + common.HexToHash("0x35027ad60d9d405246cadb086d2247fbdad526c5a277a2db05da6c1036c64844"): true, + common.HexToHash("0x22d5b542167334a4b8a3096198861ebee80edf1e8de46d7b690fc59b73f0462a"): true, + common.HexToHash("0x0d108a5ec643ef954ef1dc09ed8b21061294f5192e952d487e3724ce5c87e74a"): true, + common.HexToHash("0x74c1fdc28941363e38d8edb7ac15edfe5cc667dde1692310b46954bec951dc10"): true, + common.HexToHash("0x46185995631732dd6cdddab4a0410e6724684568eed89a861d6afa3cb38252df"): true, + common.HexToHash("0xe9f6bde7411beb74e5034fd6ba9c6a6d1844307f324f1e7bfd3eb8be56ad23d9"): true, + common.HexToHash("0xe97e0b961099bb1cf7987aa4e707253753b02ebb006cf8d1963de19ce688c160"): true, + common.HexToHash("0xb5d7b6013db671ba5f044572b88e143fa0ad6ad7dfe3da1428713cd6503c7855"): true, + common.HexToHash("0x3ea031bc7caaebb05f4c0006c150344cd5887d6131e5acbbfbf740bb8b4d82ce"): true, + common.HexToHash("0xc78a5340d9ad8a83a753f2176f0b8c215f0468ef5632f11d7172128a5fec800a"): true, + common.HexToHash("0xf01cd6249fff3d4f2eb4d8e74530cfcc257a6983322f453dd74c16d85f9e8a91"): true, + common.HexToHash("0x6a1644b259a165d671ed0439dcad06d478896fba80fa3cffe30062fbb285ca45"): true, + common.HexToHash("0xbc82945316c41a062da8f21f39d6870dab7de980f93c1703e1994c05ed2fb763"): true, + common.HexToHash("0x328cf7372c0409f0446c3d94c70e25af9a7baaa6d796ba51c78607ebeb13c99d"): true, + common.HexToHash("0x4d7fdbb7f7783db03a122bc9f5ec2c532630420b33d426b08362c3715bd2f335"): true, + common.HexToHash("0x33433e6bfa84f11c471321a4da6b0bbff9475ad745473776711feed8b7d7ed8c"): true, + common.HexToHash("0x1ae626681c7327064e66fe23642c6e62acf4021e106fed6dc7a0b903cd022c10"): true, + common.HexToHash("0xda8c53d3c912a6a36d61ee0cda948c1dde55d5eddb92643c5481fd574e641cf9"): true, + common.HexToHash("0x6cfe48008f1e4cf298d94733e6e0c4386d4174f7b3d4f86f669b562c1be641e8"): true, + common.HexToHash("0x81e21754565cfa8bad43f37eb1f709b4da7ef8c36ac15ef09eeb650a46d826f3"): true, + common.HexToHash("0xa5f98c7b2f3843aa27d206b03869bfdc3cbceae25d60a917422544348d93be50"): true, + common.HexToHash("0xbc41de6c179d25e8a1eca4418e683cc73d003b612d089aac78c195ef38b618a1"): true, + common.HexToHash("0xb7d1c9ebafa4ab10e6faec0227fff1d74f846ae16cf85641ecb1197339ed506d"): true, + common.HexToHash("0x3f4e731de1d248c290281b26bbaf4cf9ba34112a5406ebbf7c97f21dccf35dc6"): true, + common.HexToHash("0x71e97fd2e71fef7956e509b2b9774d363464a5ec91622dcf6a0b5afb7f4b0496"): true, + common.HexToHash("0x54c126c248e23b8ddf7b7637024d7e41c4ae6a33c6149a0ed36f979730ea19ca"): true, + common.HexToHash("0x53c1186910cd5ee846d3f8fad74e6275b2dad2242287bef354b1e703e2abbf25"): true, + common.HexToHash("0x815ce4202e212440a5c78cf9db0c6733e366c289f5ad2ccecf86d44a86c9b0c8"): true, + common.HexToHash("0x75e63338557ab18b09816218c3d93d6a90bffc886936e824089e5c8863395410"): true, + common.HexToHash("0x3326e20750d8347d1e4b0876dc655817fd75e5df67045ff4010a763d56ecbef6"): true, + common.HexToHash("0xf653a96ebf7ef71ecfe512f0a59bcea1143a96c140cc93cfa1aaad82b3d6adcb"): true, + common.HexToHash("0xc1d24b02bf3bb5ed7c979e3c8b700b465b0e2f4ce68dd8103ba48db81d0ba744"): true, + common.HexToHash("0x3213cae1f90e2e901d9054da5192fba8052e444d86a60c31fab64ec8619b8c5c"): true, + common.HexToHash("0xafe006138aaf6484b8266be2d27e000f6614d03943ae8de263ee99363ffb1abe"): true, + common.HexToHash("0x2318e1e3ee335c707df7c1dcb9ee3c31f0b5c128c99a2055fd1cfb77bc63fa60"): true, + common.HexToHash("0x84ef61b9c2d6a951c8afb10755dade3b920ee2f17dba1adc83a1991ab0cb4a40"): true, + common.HexToHash("0x0e1d207577127ab13c089e26e31f79fa9b997e7e33413c05627564fa9e82f6e0"): true, + common.HexToHash("0x2feb68d3ba64929a067f9320e7543662aac2c915ec19dfa66d1b04cf0a27a6c4"): true, + common.HexToHash("0xab61317f53daf330756cb376ab8045d66fedabeea3583da2e5134a4e2e2c3eae"): true, + common.HexToHash("0x4dc12af8e286a73cd9fd4b1674118940ea992db7c1ba3011b9553940571940f7"): true, + common.HexToHash("0xed3909f1a1f78567a9f1f55d0d4db39bcf18940820ad2bf133bdbd2083b81a1d"): true, + common.HexToHash("0x5587385b63eb7ae2956fd8c4031bc1fc1e9e40f4d6affea631ce74e93c4e55a5"): true, + common.HexToHash("0x3be3a9fcfbe8b7da40a90f7ad0703c4aa0729cfd988a8ea786dcb83e3416385e"): true, + common.HexToHash("0x36eb132c8535b9546b9f956a47b40a8726c81c389464394622e9288acb88bbd2"): true, + common.HexToHash("0xe35516ae9520f20632bbfa6542c09b3c7bd26aaae3880ad9b55cfbc50da652c3"): true, + common.HexToHash("0x2e06082c40e9788980ff905241322a9b641e6d47bb231d8ee658afa2e04d905e"): true, + common.HexToHash("0x98a903a9f643875ae08aa5e8fd4bc3e11776d65a721b80af1638a5a1688e006a"): true, + common.HexToHash("0x3eadeef7bd2b75854fa907a7c2c7287fb62bd175ff63df4bd4c1d0126cacbbdd"): true, + common.HexToHash("0x4cd6ac7915132973a2234419f50d10f9fe970a79139f149f20ef2e302700561a"): true, + common.HexToHash("0x52d03fbe5b635e37b6d614bd18601966224d2d2b60dbcfa83700f195d215b1ed"): true, + common.HexToHash("0xb9ab7c35c8c12699077eca3a1e14f2588af34b8ca00306764b5063f5ea9b4863"): true, + common.HexToHash("0x7a6dd0661a2f423720b4ab58832386247427f278f1fef303e3f48af702140856"): true, + common.HexToHash("0x6db628ff22204bac4640cc17e3352856711521b30b1e0d2e078a05775680e98c"): true, + common.HexToHash("0x064ae254a253d04032fc6a548ec368a82020fbdd11b1cc96ea50cd0e9396d795"): true, + common.HexToHash("0x49015c4e61ca11136f587a82acabc297f4c14179dfa88b693a7e30242f80d155"): true, + common.HexToHash("0x486e4be8fc0f38bab98b9a77018fad4ed90a0aff92a99c6fa80c2f35e2449d11"): true, + common.HexToHash("0x64312e375c2a630d35f0f26100c411e667bc0f05083e7deb47bf29d4ce9a9fad"): true, + common.HexToHash("0x5348ad8bc5ba82351855974cff0d22afe25b2a0e8c0fc34b54d388c5cd84a71e"): true, + common.HexToHash("0xa069da0cee723b112f83c89523be942ff6fecaac89c054d0b416d5c98e6057c4"): true, + common.HexToHash("0x312b779f4872f0ac19c105130008a61cc29b66fc1b1a664d200d0ba5e2609afa"): true, + common.HexToHash("0x579ab93434b29518e55f41a5aabff9536be05628b9057b843c2ff95e3b17d759"): true, + common.HexToHash("0x21348fcd05e666d04ff962c68efbda0f13df0a9ef1737a917bd1d26130d2ab08"): true, + common.HexToHash("0x31e6e7fa0cbe4a12cb8741a273edea2d2b56660c103f47a8af229116c3f64823"): true, + common.HexToHash("0x18ef76aa1cfc538fa69c14569f9478c88d27ab232c44471c82edbcb95862e8ff"): true, + common.HexToHash("0xa50c945cf9c380ea8a3a12b6b8fc5706b8c5eab2f8580015e0e0ae179762f157"): true, + common.HexToHash("0xc6f0266fc89412f6eae2d7f5e9cc0564e4b1e02e23fd8cde68d9da0bd6295776"): true, + common.HexToHash("0xba516873d01a7a30e9b6e82b0de5f352648df225f413db875764d1487c0bd697"): true, + common.HexToHash("0xe2ba08036643c3b60a8ff7b19887af3e1abf7c3884a50f195f5a1bd189fe99ae"): true, + common.HexToHash("0x076736791b02df70b3d77ea11e466719e32501654a5982ce480c083c950e4873"): true, + common.HexToHash("0x8016e1a1aadac51b1babb8fbfb53ff73f6e75db9d017ce521629ad43881f542a"): true, + common.HexToHash("0x3cb777a151ed7f91baee954391bfeee48b410570b7a2f495157397015b77eddd"): true, + common.HexToHash("0x512a95def70da5144312d683d1e12e20a9c34098e9a4851a45cce5efd2d3f1b8"): true, + common.HexToHash("0xdd462107a25a2437ed25246fb271417e329b9a4009514c33512915931cabb3c4"): true, + common.HexToHash("0x05f35a02fa5a3d7ff25f39212ddeeee767bc09d111149c980869c0e7fbaf52a5"): true, + common.HexToHash("0x58ef7f92b7ab762830a1b90e1f4fce3b24d94a9f9162d789641f02635dbb14a8"): true, + common.HexToHash("0xf0c4945d842bc2c6bdfab8cbcd9d338faf2c8046a230c57e8a27df763ae81ef3"): true, + common.HexToHash("0x0afd33fe4f81e41efb5f4aa7860e90b381a272be652933715682dbf17f7c67f4"): true, + common.HexToHash("0x2c12e7f9e63fa634e062608048be01e44694cb118146f97f4d03e71a10b9ac34"): true, + common.HexToHash("0xb94417c6fcfb9df5e6640bd8e90a5433b86671829d0d4235a861c413125946f2"): true, + common.HexToHash("0x641b70176b7ea15f30459b9bb3e8e48c33a2bba478c0dc3232a538f84e30355f"): true, + common.HexToHash("0x98016653b95ccea286e5b4ec2d984487ca68e28697d166dd4b4da60d2208dac8"): true, + common.HexToHash("0x2016911c560b3a0d74a5675a5707b0af31c763c5eefcce6598a455db496bbb2f"): true, + common.HexToHash("0x73f65f21648c0aa53bf6214d7c0251eab1f50b495e476407b93b34edaa0b62fe"): true, + common.HexToHash("0xcbd697f389352f931307ef19077adc14f319b456e8fd20626c66ede338da0493"): true, + common.HexToHash("0xe82774292cbc49962faecd937950e84d8a38da39eecd080d0463b9386c794ec8"): true, + common.HexToHash("0x3b9a25f2b464b962dc1d1237102d51c71b9a5c3e941ec2a73c5d78321d69ff98"): true, + common.HexToHash("0xca8af4e704ffcf960a16f9a1e0f12cf1429a14d128c3cb2477d73a02c7e6c62c"): true, + common.HexToHash("0x51b6a910391c0a1982324c45205d5581cff69da29c5a53a6b4195462118daa15"): true, + common.HexToHash("0x1f4fdc5ca15434fa8fc90e663f473c23deb0861023b2565c1784835fce1cb3a8"): true, + common.HexToHash("0x28ae9795ac8f58eee2194628c1aa85bda5af073ea8f9674453d47bf27c721b04"): true, + common.HexToHash("0xa547d56f808829ea08ddd2551d24ee7f3d7e2d433e4bfd2448341c073d780039"): true, + common.HexToHash("0x30df0b99c7fb03ab7751c60b3327d1c41c0fb169d1c79e92a006a7e925839fd0"): true, + common.HexToHash("0xa474544c7ab52ab90b3840add10c74c9a8b42e8d66067c8e2bf3dc3325f5f9d3"): true, + common.HexToHash("0xca033307b518935673587c80485d10dc80fc515350ff97e71cf4f16ce507ad38"): true, + common.HexToHash("0x002698ce1da241705b8a32151a15d7ba23ff0c1df52c1d10630854783dd83e13"): true, + common.HexToHash("0x63850a38b2a0f0dc40be46a0494fa44c30652c52d4bb2cf1f0179c1e07dfe28e"): true, + common.HexToHash("0x785fe6a000180a799a6371be12fe419ca2d0680eb9f477bae133870378e4579a"): true, + common.HexToHash("0xbab0971e496543a6b7afa698b96600d0aec9c9cb6a3f6cde0c892d89440da91b"): true, + common.HexToHash("0x51c1e63baf80166175fd04bedc059393b95c6bc414888790a805a8977b88da97"): true, + common.HexToHash("0x2e67ed5bebba4e723f1d5589d559004d8fef023ace48820c691357e5d70322c4"): true, + common.HexToHash("0xa942bc892315c7ca941f3e24a30955901a80506aa964221000976ceaf555e33d"): true, + common.HexToHash("0x340f1bce99b585df86f5f96ac2cce0ceb59159fe4d57065d4e5ca5b9576d47f5"): true, + common.HexToHash("0xec8a68909854dae4e3c1b3ace70ff5ffdaa962e6a24e29f36968d0500b48c086"): true, + common.HexToHash("0x79174109747b1152b559123b1e6f7a7493e8dca36106058a241d021cab8ad93f"): true, + common.HexToHash("0x1e270fdb91bdf433213612159fd78c152b9b34991f83f384da9e53dd4e08c783"): true, + common.HexToHash("0x0af5899981ae5abfce65f2bfbfe1c4ee83bce17960c30e8b345a5d6baa843078"): true, + common.HexToHash("0x56649338c64761c4ef07f2849d1f266164d2d9f6219bbfed9fba9835c62b584a"): true, + common.HexToHash("0x8d5855b2f2308158f1e0bb6f4d07f23dc69df514f448f1ab34d9b180fcba33c7"): true, + common.HexToHash("0x4033f29068e62477a2aa5be5773b476f999f78a725fddffe3a623fe9faeec025"): true, + common.HexToHash("0xfe294ae34b4ba232149c6296287bc4f51764a7eb890e692ebfa5cffe0c9758ac"): true, + common.HexToHash("0xb55c32519f46c7ade998c9531a0568e19aa32e110f8f6f16be2fa2be2a628ea0"): true, + common.HexToHash("0x1a5ebfc746620a9430d4925723400e2fc4d47c431582dcc897d49552d4389cdd"): true, + common.HexToHash("0xa5fb2eb590729179858c56e28ff4828b0fb31f0561277dc645bd121e029227c3"): true, + common.HexToHash("0x7c31d6d1f34387fef9c7e84939c0d47f96be2e991b7526d3d795897ecee97303"): true, + common.HexToHash("0xa39c407312d25a4c2194fd32b3c89ddd0e51e4a658df8663d5a4c7969fb28c59"): true, + common.HexToHash("0xbd87acb207c0014192af40cd43ab91f7d2537f59d91a22382b15849d4ff65004"): true, + common.HexToHash("0x8a0fc43264a409b6865a9f308c78a943813e8b52462356f38ec057aa2309ca10"): true, + common.HexToHash("0xfe2bbdbb02e6d7d07c8740934442414cbcd3c0fbcab00222d88e8ba5ee0d7d79"): true, + common.HexToHash("0x1b0d61c889dec69916c8cb488fbca40289a9fadad89a0bb272e4ae483321dad7"): true, + common.HexToHash("0xf95e97b15976e40fe5fa0f6a035a804656e19fb9adb8e58cd809039cb37cf7e3"): true, + common.HexToHash("0xf1d9d86b996bfa9a837ec8c550f779db59218a952e2eec8d84e08e7fce5ddaf3"): true, + common.HexToHash("0x67673e1900c68ba2e5d4b86b4eec6d01eae619c91e79ac258259df71ec308399"): true, + common.HexToHash("0xc5ed94f5c28c35afb0d44c3f3a0e931a68fa782e3eab951d8d4b286b81040770"): true, + common.HexToHash("0x257e7bac09ef8a7698c1ecded2383db6b8ebdeb3526fc1977510db0cc79958c7"): true, + common.HexToHash("0x70cfb2c12476675b24ef206d9a32a3f9d5f97d3844d54120cfb823bcb6e7c74f"): true, + common.HexToHash("0xfd53f4396f0f1c8314471674bb2faaa5859b8bacffb65684d22f146c1ffe9363"): true, + common.HexToHash("0xf0d400a26d49ecdf08afba29b49509a390b86f9804f772816af8eccbbd19c991"): true, + common.HexToHash("0x964acdfd4e5f5e3129cc50ed462396cecb2431531fbe0a82a9302fac5948e1cc"): true, + common.HexToHash("0xa0f5a7b613429b5390b134f78774ca88dd3287247aef2f8dc3f3f0424806645a"): true, + common.HexToHash("0x2a7840b39929a79867582e0088f7d4dbce209c798eedeecb7e3ccd9d4a5f486e"): true, + common.HexToHash("0xb6ee61ca998ecb1e49400790589cbd4716dd822d9516b4f2383c2034a4e0cc38"): true, + common.HexToHash("0x9d77f114fb86b36f2de5707109ef67c0c996fde88c4f5473f629b8a0875d7ff7"): true, + common.HexToHash("0x4d632f77a5fae5dd8e0149dff8ec724d1592b099b75c530f42a5c6883d4556dd"): true, + common.HexToHash("0xadf64c70d651494d2776f9dfc354e0523218e73350c121e84057b2d3c33f2825"): true, + common.HexToHash("0x345dc8c17ade6210c082695170dfcb721e8ee675754fadc073814e7954cc62d0"): true, + common.HexToHash("0xb005a3f98034145f8f32fc21988be58ccb54825a03ac756c2fab03f106db863e"): true, + common.HexToHash("0x231d66c9c2cae49a101e4e81515cbb75b2285e6ca0059105648389d79557c56e"): true, + common.HexToHash("0x773e919d83e852e864699c912009e057479b200413a5b7aca0822164c075d1b3"): true, + common.HexToHash("0x7aa445f46cfc9ebe6f3753f22034b585b425eb38ec4adec69adff98410d6b9de"): true, + common.HexToHash("0xcf5b26b780a0041f865691da5b33d3bcd8761a9f7be7b497b6ed907ea5e84169"): true, + common.HexToHash("0x66f7de4b28bad2802652700d7657dfca962d9c3dcb3857349540f686e2f01b59"): true, + common.HexToHash("0x0c12d3a267e3c49feb3f395e18be11bf8bcda997b45e0d0e26522b40a2c61b2b"): true, + common.HexToHash("0x6112ef8c1ad1d8174a2f4e670711de5b7056673749a9f0eb11c627ffc45e2c8d"): true, + common.HexToHash("0x09cc9249fc907b7f3ee96550c6298e5280aaa09c72195c935a2a42fb025281b8"): true, + common.HexToHash("0x28cfd4b985514fdfb8e8ef6d9ed2740e60b818b49155d2b5c14c857434cbb438"): true, + common.HexToHash("0x5f8c6c1a67f48b843ca3ec78d4f68b29a26ef676d7ce6557547c57f02414601d"): true, + common.HexToHash("0x72c63367653d9d00fc3a3229f64b19afb025de0c1bf5ea2d3dab0d3cf7c2f426"): true, + common.HexToHash("0x4684e7d2c2943079953091031eb4c7921819fc5f9085d3473f4f858d93826fe8"): true, + common.HexToHash("0xae6dbf0f83d75e9abbcbfb132fc3230198f919be05250c13d8802865dfcca08c"): true, + common.HexToHash("0x609ebf00e5c90c3d7215ca5b8589437348c6be9a35bb1960ad337573e0d3d3cc"): true, + common.HexToHash("0xf93024ae0a42b3e292c388ac619e6afb264caae287149c7a6ed57b5ed2d3e96f"): true, + common.HexToHash("0x12d1c6e2d1e869379fc225eeadff7e6a5e5e26adac63369e38712273d9c40bfa"): true, + common.HexToHash("0xd6fdd5e1e952e3425b4b90b92db058b2eb16fb5ad586cc19cce8f7bb2589a171"): true, + common.HexToHash("0x28d401d7ee139a966f29cbc79001de11f33cef83bcac330d3d07614095dc832d"): true, + common.HexToHash("0x844e3f0646856c8f9a15186ffb12f9e99194ac36fa72fffbf63a9b92a835608b"): true, + common.HexToHash("0x699cff1474e80c5b6c93a4082d3ab886aed6c1cd5d0a537e83478a29e7a39326"): true, + common.HexToHash("0x4142cfc567d5059ce1352f2574fde47c73caa729d82fdd715a8e50887f042dbd"): true, + common.HexToHash("0xed25b65d21e8d3bda44c94bb42a24cd4fb5bbb1cdd6fca634dd83a4a78c2dacc"): true, + common.HexToHash("0xde66756fa74270860e2db45eeeee44b25ece07204a8a367371767961fd4ebd58"): true, + common.HexToHash("0x887d2aa34aee1c620c326729d86b36e57ffb120ce302fdd821134b386f081b7f"): true, + common.HexToHash("0x0e5d76cf88d12d62a35a5308a30593e7df68b8a163834bb4b5a38ab568292ae9"): true, + common.HexToHash("0xc325083927cd2058dd53c0929ba0ce0cfd66f2a30f87d2e776524d7c470bbcb8"): true, + common.HexToHash("0x55b94314a5aed593a0f11470871a2ce6610c1ffd8a33c4543ae80561e2a00a7a"): true, + common.HexToHash("0xb0ee0e7834762a0595a07d7258f2c001ef867a0d908920a3876df48a25fe3b4e"): true, + common.HexToHash("0xff480f8c4722db2e154ee0f366cf3341b3c1faf60235245cae2a02307a2023a7"): true, + common.HexToHash("0x44d9d7b5a70d74bc3e49c0e9771e8d3b809507b2ecd9b23253ea287b58ca7eda"): true, + common.HexToHash("0xe9125896969396b124b8d7531cda42f7f8dc2439ceb3f317b78b1290ef38c2ba"): true, + common.HexToHash("0x4904616ec8dcfc2456ca4f5516cb1d0d7ed19a82e76bcd6d2883d302e542835e"): true, + common.HexToHash("0x873422bd785e56500af20027b95e5821aafaed8efa1016464ab086a13ce54422"): true, + common.HexToHash("0xda0f5e913e8d56599b958f1833e573193222308212ac96f4e3531a353567d1ba"): true, + common.HexToHash("0x039eb704999935c5720c01578cfd07fec91cbf9b9d18aea8fc64e0e1b977724e"): true, + common.HexToHash("0x0611b617c74eafd96760a9e72601e3acf22f30fc239786226dcad0cb1da85af2"): true, + common.HexToHash("0x4f7052d2320603d9e761f65ad31fa0d3f88bf57e1d18a5a8c732e66849ae6238"): true, + common.HexToHash("0x1e25b9686df142f724b7d2adcd9aa1f01d42ddbebe231df0989abed1a1fd6f65"): true, + common.HexToHash("0x3f299deefed3972fd862c8eb57ec3fdf308fba9d210b9dcf3611c2709ac2194f"): true, + common.HexToHash("0xd350aaf328e3e243ec7623af9bdfb4235c0c7c7d7dad2fed31293f99e7d8093f"): true, + common.HexToHash("0xc677954dd47b4470b5d74d8765272a8bc8fdee7a6c3fe28bb6b946c063d7a376"): true, + common.HexToHash("0x70288b40d0d8c81ead1f239aaba0395fbb967a14225440f747b536250f87c100"): true, + common.HexToHash("0xfa0ab4fdb55f751d83218f9d41059fb30fd972b81a7cc0b376567581718f0cc8"): true, + common.HexToHash("0xa801d1d7a4e1f4c5f107c9734579fc494eedc661340bc2577b6bc0ca79e8db4d"): true, + common.HexToHash("0x20303986ae8b02c1258dc5599ab2962d774741d4dc5fb49536b43d8ce7c68d33"): true, + common.HexToHash("0xc152181c053b23092bf2a5e313a040d0e24d0026f21d20694b4eb1193323c210"): true, + common.HexToHash("0x0217bc80d9e942f469d3b83e8fedbaeeaafb1a91b160be14b1c2adc3353198da"): true, + common.HexToHash("0x3725796fdd6b10898ecd5237f170491bfb063aeab310056ae953897e7b355a4e"): true, + common.HexToHash("0xabdfcd21b23f6457a6f0da0f992223bacb19fc605d0a7e4cca4c61a1a1d75ef5"): true, + common.HexToHash("0x414aabd9a203355d2f1b2d693d56a59b40119f9214d32fba746f297bd280cb4b"): true, + common.HexToHash("0x8416dd62f7def884812f737967b76251282af4df638294fca14334292b0b3820"): true, + common.HexToHash("0x743bd0166766b276489300b8cdc635d7595e213e42df4117b6650b444c276524"): true, + common.HexToHash("0x656fa2686ce0de2525d2a9996d7467f78e3f0051947cbb27e10b1b968a748ced"): true, + common.HexToHash("0x39c3a88a51306e9f2e6ebb7c2978f06d55a4d73743f48144b7851c7bd534c9b0"): true, + common.HexToHash("0xa7eb3db7c3a2f9fbacf544226c3511f9af3baa2b6c4d77276b12e873e86a0e56"): true, + common.HexToHash("0x9c279e17954b00780a8a3722a748b37066b3e50b3616dacc557e85c99d45e670"): true, + common.HexToHash("0x9226acc6017575d61413a5b16326e5e801d7672ddee7b90bb8b9ff3af8b63471"): true, + common.HexToHash("0xfdd53c94463091b78d385684f5e4f41b2a5a5fe47df33d20df601e0ff12aed48"): true, + common.HexToHash("0xb09b9a2dd007cd568e78f23812ca36b68c552054491b875445b6e0d812952434"): true, + common.HexToHash("0x4f8f4a49967ddd846cec6468b871d98f3c6ae6a42f9a21d115a2f130756fca71"): true, + common.HexToHash("0x11495d91185a600b0964e0e8657d9b0da0519f63f7fe6928579ed64dbab02411"): true, + common.HexToHash("0xf57e632dd306c7ffa7a6c01900122d4153e48e5a2f66bf5f1aae21a4ab49e74b"): true, + common.HexToHash("0xc57a23daf7a31009899c00924af7723abd5e5ec505a483c2e899b1b4e1370e49"): true, + common.HexToHash("0xf9b147c13e85e10b31efe7ad403af4c2d7bda452fcd768ba313a6565bdcb0564"): true, + common.HexToHash("0x290e9420c7df5b58c88584e20bd92f6db7236e5d41fe25bae0e690984288b2b3"): true, + common.HexToHash("0x60aae339abb0eae92504970dcc2308bb3e3756e4608e6ec386624e0e9e1707e8"): true, + common.HexToHash("0x2a09868bfbd6e991ba4c41b9f9d62e87439d826692207601ed75e1c8b28a81f4"): true, + common.HexToHash("0x732e254eb3fb5aa295a6037527e386dd0f8e3565d00324833a78dd2d325f70e0"): true, + common.HexToHash("0xb9962f14ecb898f9eb512cb80381dad06cd9765e18b0afd9b1bf6518bb626282"): true, + common.HexToHash("0x635c45eca2fdbf89fed4e1a88466af5b534e104e10aeea3139213bbbaaa39e82"): true, + common.HexToHash("0x8c081d752df7b6801d51a6db981aef312df0e18e8c95024306ef0e775a24c592"): true, + common.HexToHash("0x648e36d7b83ea535ba036549ad224662df9a1a57f0abaa6c1ccf9c4f41fe35fb"): true, + common.HexToHash("0xd8f77d4b9de339a24749f6d31ae5ea449c4c52d45e00251f2394f1424f416b5e"): true, + common.HexToHash("0x8815bec4f9e6d7d703a948ea1b0c9a10ed0d83b6df234eb9ff6f177ace815f39"): true, + common.HexToHash("0xd23f3735e538c6cd80930f74c6cd9d4c77c479d67cd099d8a043c4cb9b964ddf"): true, + common.HexToHash("0xb4df1c973c1d227e35cd0ce625aed1ef349727c47738e432087ff106a6ebb34b"): true, + common.HexToHash("0x608241a344fd5d9198053929f6dc3b0d53d674c19bbfbb656c75e62c44bae814"): true, + common.HexToHash("0xfb4729569055ea64160bdc8cb33d01805734b97505b7c74ec99af7dfa05edb3a"): true, + common.HexToHash("0xee68ee9a57b9d90a706011b85821c666171cc31b87a497ba30b933f45b357324"): true, + common.HexToHash("0x61ea86c6bc4f20e27a6679956768f4f2ee0c7c62772dff4fce442c4b849102f2"): true, + common.HexToHash("0x0f07ef7f7ae2bd04328366d05986c82f3cf91dd19f6d2ed812c94ccb38b35e96"): true, + common.HexToHash("0x5405915ffe0630eefcd88914b095f95073d07fe687e7cc700a8381415b550924"): true, + common.HexToHash("0x613d9a89e66c87e7eca88ad3152ed58038c3d81345bb7a3309189c63dee8012d"): true, + common.HexToHash("0x99c5305cdc46fa74c57f244f9fc035a43a880cc5ca1c987b037f70923d8f5f81"): true, + common.HexToHash("0xdd33d6172041d2ab567872103b090ac46982e306302f96f7aab2c727dcac80f9"): true, + common.HexToHash("0x0823f0474aa02e9f3921659cedc14ee3f6b78f35938a00b10f63eb61f87a6380"): true, + common.HexToHash("0x3da48ff1a431b471bf8751b3e40116e80cbcb730ef7e86d7756d7990fcfa661a"): true, + common.HexToHash("0xe1da71eef4a1c010116e3f36d5e58a1c44c08db321880bd558793bba67dd7ea0"): true, + common.HexToHash("0x01e4d648af6774536779839839d95828a75da3835351b2929000bfbcf6546267"): true, + common.HexToHash("0xa9f5a76329fb993cd098d3d3d31b73fc26ff13ca92540abcbf04fe0d1188dc8f"): true, + common.HexToHash("0x303530c0b26a64895ee37e989f425eb3f27d464e0fa64de0e1612b4939c8f7f4"): true, + common.HexToHash("0xfeaf901740b91fedfa2843e1d8a6d3111247ad3225e7b0b695c8acc40a967aa5"): true, + common.HexToHash("0x5987d3e2a8ceeddd3b9aca7dac9fba3b56591204fb5d4b0b16dc205a3d5f2ee8"): true, + common.HexToHash("0x9b820e9435abd45b4221f04a0a51d2402c3f361c6a1dfa54e9af27c8bec82b2f"): true, + common.HexToHash("0x24a89f9e9eb0524f33be5e65d1b201348231f9b1ec12d90416dad2d5c65805d8"): true, + common.HexToHash("0xe69122559fd9543f38f4a4b725d694e18cab08e48f0be227404030278d2f3f61"): true, + common.HexToHash("0xc3782fe15e109da03d12c55d19ea1076be53182d082620ff8d5d5ff76da0f807"): true, + common.HexToHash("0xf6988dc3c4f779cd492f50dbcd26e2e9042cc48b4821d80bc1a0bd1937223fe3"): true, + common.HexToHash("0xa68e94691fe01dc927c405b87a9167d80817127a654c24dddceaa9e7d8020afb"): true, + common.HexToHash("0xd82a22d729d58f1aed5951c2b7f4fbf46d6c35f72c7459e5574593af95a44bc4"): true, + common.HexToHash("0xb2e0e36413087c8f8d3a8c8ac9f39787d8f94102c2516093dd6c02e46c844706"): true, + common.HexToHash("0xad34804af9038ad2b9b4707bea7418b3b8973bcf83d5cfdd749e91c32103c8a0"): true, + common.HexToHash("0x0b37209cdbe20f2f60ffbece1c1e2bb194553faf1b0ec9b46aa558c617d4f0cd"): true, + common.HexToHash("0xd07987dc39615734a9687d8dbb33186641edfbdd8e158a1ba5430c01c362c448"): true, + common.HexToHash("0xecbee6959b14d0c7746ec71243c01e774573ffe362ee6cbb03dd71252d5cb67d"): true, + common.HexToHash("0x48f6b6cb2f492d38fe82989f23c4d86d2a5fee415a6d1321cc64e29db5481d6c"): true, + common.HexToHash("0x2c63cebb56b2b8dd0f60a3462a1c479ae2c420252e95ee0b3371b383abc51c65"): true, + common.HexToHash("0x248b000a9329af44de8563d96895edd012800d76121c769aac500d09ea65d385"): true, + common.HexToHash("0x1d75c9d1774305d62f8f51e65c06547623a7c2afdfcfab5cabe032186dfba75a"): true, + common.HexToHash("0x361c0866dff92a705cbdec7c1babeae586470662f82b3ad0bdb666f8986fc408"): true, + common.HexToHash("0xa12ee8d9baa8985ee7c69fcbcb1e942dbea7b7ad1e2c0f2a5dc0846021ee1b1b"): true, + common.HexToHash("0x6b340ae790fbdcd4d9df9f0be27f20c560145b54bf305f702f92822e50e1ad1f"): true, + common.HexToHash("0xc48e8598b958bd485a5efc8a19be23f3006d912cc11b882c65e5d61d8023438f"): true, + common.HexToHash("0x5f0cc81d95cccae6b690188c1b58f583fa6754bba0cf93d9452c0b4e3b997c31"): true, + common.HexToHash("0x4650000304429b031a2c56debd844f20fb9b393749eeaa3c5cda1c277b3b66ef"): true, + common.HexToHash("0xf4f91947ce3b4c683681d80e9eef4a25bbbeb22050b3562da2a9c39436c4228d"): true, + common.HexToHash("0x036d4995cd62007ec69a8a22aa4849a504241951c24a0d5fef8c848ef1fbaf15"): true, + common.HexToHash("0x0e225cef3316c8bdde687997cf7f02ed41b35dc105f82e917b8d1a08186352ad"): true, + common.HexToHash("0xbdb623d24d4298b20d3078d1801642a6c47ba3d014904e2daa306f9dc15ceac5"): true, + common.HexToHash("0xd132ac96c452cb462bd28074825b488c7d52410d4f9c1bbb512e22b06a56b8ef"): true, + common.HexToHash("0x30770a68ece8d64f0ed94dcfe6097d3187dfb1459d1f99d0fa915c5c0d774fc9"): true, + common.HexToHash("0x043d6a2c88a366acc849fc05e5629fc257371fc5578aac3c810a90ff117bfc54"): true, + common.HexToHash("0x87b9f7a447ad9b1a772f0d48404bbe0b4aa751de50d157833132db528c42ca40"): true, + common.HexToHash("0x312a6b487c2288f1ef954c11e6d5ae7a3ce0086c96b6d1e1904ce2e630f371b4"): true, + common.HexToHash("0xa3c948b8b929e0b7c73df42aa5b6e6e1a31e2095115e1d66ff8b9dc4a567fb23"): true, + common.HexToHash("0xab0c5fa9ef7a455f4db07af92584d67abda785e9e41b95a7b77f151fd264ce58"): true, + common.HexToHash("0xe03229a89c7d75844c31ba18f3f2183da728a26744f959f742025ea557bba9c5"): true, + common.HexToHash("0x82f5a847ed268c51ae6890e185cde448772a4a371c5b96fee05a23e134fcf445"): true, + common.HexToHash("0x47d5f7a04e7d18e24ff60755c9f84e534d2753f6f7f7d31bea6e9d6e9d9807a7"): true, + common.HexToHash("0xc89ddaabf2b8eafc75355963615540aafb05e532438e27b9f7e46817c1dd60b9"): true, + common.HexToHash("0xb24e73394f8e5ded6132c421bf02e147666ccbe490a1b064fe0370a7c855259f"): true, + common.HexToHash("0x72e573f06ee53d1656b769bb84186d7c3732543f1df21392b23f0aec236f23d8"): true, + common.HexToHash("0xb488f5d874d5db96cfdb830153146a19e00164545a5a151b5b22f0fa6c2fa764"): true, + common.HexToHash("0xf62679cf3226ce71e9e47efe720c455004978fcc3d8185437c292c66c9f605c7"): true, + common.HexToHash("0xc1489f804a0da8ca7ee7da2ed94cc5524755b09ef1d5c01055adf7d8e70e11a7"): true, + common.HexToHash("0x41a00c5b859dffc16d63f5ce474ec7d88689bc3c615b1d8c826829e65122d2d1"): true, + common.HexToHash("0x498d238f1e09a6f7c8aff1ed2987f99ed0272e0ad8cb4117caaa98af1d3bb943"): true, + common.HexToHash("0xf12da2b7a0201106b2ef7af5b9cc4601711640ef8fb3ddfd793e874f4fa7193a"): true, + common.HexToHash("0xc18d99d0140b0c64415af780397e7c5ca3d72337ceccfe27623bba3e4760a7f6"): true, + common.HexToHash("0xebe3ac2276d8cb04f54b4802611a395b0246fa972fd556aeb88f5665d9f02ea0"): true, + common.HexToHash("0xb45253aa48237d7d436bf123a9953b196b2a97dc6489d4592fbeba7552881c62"): true, + common.HexToHash("0x3ff7e504053d0b817023664ad84737ac5cc201f3b9c82592f518d9d59f6d1c78"): true, + common.HexToHash("0x834ee42f208ea8657bc0369c088c3af32ad11b655c09be12d9978f74004c6d15"): true, + common.HexToHash("0x831c203027a19edf673c42046d8120806f08b136303337e4a189bd0de2e57c17"): true, + common.HexToHash("0x0d866c341056617482675085e12266156b212f70af9420a1f77c163e51b92742"): true, + common.HexToHash("0xc17892b38e4691d44028a47fa9c139a6cac73ac4287cdfad206384af647d809f"): true, + common.HexToHash("0x8cd3cab7bd6d6697bb8654f988fe480fdc86b7c4177c3e7ce3477183e9ee1296"): true, + common.HexToHash("0xaca57133f25d666a11974d1396feae3e87b69f9c407c6c51bcc707c0a4dd8da0"): true, + common.HexToHash("0xdc55dffaff55651f40371d35acef612c4d73309044ed4243a50ba4a0bbb34eae"): true, + common.HexToHash("0xeb090111bc96ca89a485219b9c19252e5b70c24814dd104974c3234f52200f67"): true, + common.HexToHash("0x6c90ada60e305e43e6e5b3fb74fac321a5eb777034c99e30856efd94d979187e"): true, + common.HexToHash("0x3f79f7a8f9e2362550b26fc14fe3a6867809f76c65390a20bd5af68ccd8c03a3"): true, + common.HexToHash("0x9108782f3de8dd09f961cc61546092778a4ea5346d93cf610ff493279b393fe3"): true, + common.HexToHash("0xa05feb348d658af7c26ea24e7bee0fbf84a4c03424c3737182cc2f301ed7006a"): true, + common.HexToHash("0x8bc823c5f9cf9d0a47546c67a20ed94ee746c788b84337a63f98ca1647d299f8"): true, + common.HexToHash("0x6bb8889158f67f92fb8bba33de7ed9eb190348bcc0072e6e8ece14db8f9788f7"): true, + common.HexToHash("0xca19d4f78bf7d199de4173dec82a32e6aec0ac01720378ab04e5e501317a7cb8"): true, + common.HexToHash("0x00873d0d9a6aef5750a5d7427f911e600d54e7fe1ff60ec2af1c0a1ca79fac53"): true, + common.HexToHash("0x9f06cc4ead09869f00aac6e2dc1af53eeb9773c14ced2072e66b2c813b928e1e"): true, + common.HexToHash("0x2a350b43ceee7f046659fc8d7d4fc724726e4a4bfb7fe4445b47113e887dca95"): true, + common.HexToHash("0xf05cbb8c96c12470542a34e6d19d58ca5c7de7c001016ff6e299fdac3819a865"): true, + common.HexToHash("0xc36ffc39e4e280389f219211ceae8f17d00edc782f7078968d52ffe9a46c09ec"): true, + common.HexToHash("0xdfa1a959a688d2d207cada47b571a6d391678f07775ed96e8fdbc59cbae647a4"): true, + common.HexToHash("0x32e330fcbe601e2d0572c6ed502271b837e9e0daf9989d22e3e617da1b4a00d1"): true, + common.HexToHash("0xf66d9c4ff47cb85dc99febbf93f1e8ce34c9c8d097ad9d15175ca9b16444f9ea"): true, + common.HexToHash("0x7d7ea3f1cdb5add6224eec1486d0d95a0c78e02542e7a12c9404da8a2733ceed"): true, + common.HexToHash("0x219808602b84e5626b3c633c9aedfde52a9e2f9608e41a7093f468db8ba47578"): true, + common.HexToHash("0x1467fa9027f6643d60f24fb6446efa6a59782c49998580dee5422b64b14194c8"): true, + common.HexToHash("0x88376e890733504a269a4a7c7872811ebad3f7586db98254a9ba128049ab89d6"): true, + common.HexToHash("0x21495e0741dcf4c5a59f8027c121cd347ced13988fa2d5baf053e4081cc7bb62"): true, + common.HexToHash("0x6032782d97ae588165a7653fcd5a46bdf436d92f90ec6231e20651f3d0e84c1e"): true, + common.HexToHash("0x82629e0055e03e1b62c9a4cd9e8e9b7247bde661a2e03575ca856a36079f9e9c"): true, + common.HexToHash("0x8c4f90215106e97d48090bb4864f5bd084a3e05a90834c92d4a2a7cbf37611a6"): true, + common.HexToHash("0x0f44370832a0f5d4c52c05dbcd427a81703b6582cee822c256c746cf0386e3ce"): true, + common.HexToHash("0xef0619dd61d69ee49ac5eef98f367378b256a78340fa6d679389688430e2b230"): true, + common.HexToHash("0xd9e7c581b0fd708a51cdfe9375bfc9a566dcfdfbba65585e353d050fdd1f77b2"): true, + common.HexToHash("0x22a9bc9d1e73506d756a3e1306ed51e0009d2cbf8c0a19f5ebdbc16216548f10"): true, + common.HexToHash("0x69eb9a80b7bd62da0a70b1f9a58c286ef9534f0f215e9781184701805c53ace1"): true, + common.HexToHash("0x96edad056b26f06737a4e22b2921bf8fd65d8bb2ab9c0c98a6d4f8f731d00ecc"): true, + common.HexToHash("0x49f7b8b506373de81a9a99333180204bbc58665a7dc1f13cfff3c17bebc7ca2c"): true, + common.HexToHash("0x2c20d1e5e5e836478774b4b7f4a30d285a97c21aac0ca70d4b6c908a03fbcb06"): true, + common.HexToHash("0xd7eda3c4237efa830f1d69d6fb84ae7a38592cb2d7653e82b1e2d29f06a821c2"): true, + common.HexToHash("0x20416d3dccd725e42018974674e23d420cbb23a54a174a590f8c2668d2e52e67"): true, + common.HexToHash("0x2ad0879206b0bde1ce2eaf8dc7b146a302484e9c566bb524210dad5a3f06f1aa"): true, + common.HexToHash("0x80d19bcd1b8c70aed40916f4f27f0017b8c60987f71401bc69fe9fc6da2c6812"): true, + common.HexToHash("0x9eb9a3919cbb7ab03de5c4e7771e1fae4b5d5307fa89498a4706a24108422687"): true, + common.HexToHash("0xaa62b5a385e24b4341bfb2ffccd4fd300147610c0ead0fa8e9c6cc1c61bede1f"): true, + common.HexToHash("0xba34d380bbd7f688d4f0c13b6f3cb16be1ec9e6b3b9f4f853487715e78369694"): true, + common.HexToHash("0x1548346ca1475eea1be210946a7ab70b29c3ed67bd93b39823d0087f389d9967"): true, + common.HexToHash("0xf39f6d8551e53504ef56e273a15633e08510f51ac73231fa29b101c5b7b8a26a"): true, + common.HexToHash("0x6bab8ffc1ae1f340726e0dea950ad40593deda31988b7c1f6a9b5c34f2999cf1"): true, + common.HexToHash("0x31c24184bf2a79be4985587db3394c379be37fd5040070730ae4178b5f6fc7b5"): true, + common.HexToHash("0x98425d2c19e85fb96ea3c6fa8eb88acc5a87595f7b6d209851995ff320ae923a"): true, + common.HexToHash("0x96b4b5236680f12f927710146595b9799615b1786d27e53d6df2b6dfeac2ba38"): true, + common.HexToHash("0xbfecfe0a7b7870299806c9aea7f638816fec766397a047cc08eef2206c40dbb7"): true, + common.HexToHash("0xf36e329132c3d24802a6635fa77e0efe9b70269c196ac88fb336ea255079b9df"): true, + common.HexToHash("0x6d640cb11e6e5e1d07c13ad4c5a49f23bf1935911d1a7909b6086324860ecb13"): true, + common.HexToHash("0x21446d98a9de73fc6c1dc525e9a2e584f527c9e6dd83ec5a9a0b6f6586446c33"): true, + common.HexToHash("0xe59cb637415618fc3c5a65dc0ded4dfc6a5447772818014eb560e2236e03d2c6"): true, + common.HexToHash("0xf104b56e4d6be07948c684f9fe2ab01c103a46f5903af7132cd9ede58b2ba6f0"): true, + common.HexToHash("0x69416a6eeb5e8006fcf747fffa18483a32404521826b3ca2991714b40df5e7b5"): true, + common.HexToHash("0x123cce5c152bfaafdde852d0b49b451df19ddd3201bd92fa5f806bfdf424bf65"): true, + common.HexToHash("0x78eefb4b5f2e33e173342cc450ba27fa3a0b0fd8e19c2326712ea235aaac8e5a"): true, + common.HexToHash("0x0c459100118f87f80ce34bdab8ec58a9815bed37c14d5f073d9f12265dada249"): true, + common.HexToHash("0xaa3ca5ae3b00b14b4b14a6d35200a532cb3c036b6d3a405ea822a3ee9dee1ddd"): true, + common.HexToHash("0xfac95cdf471d590c995d71f2fe431a6c55eb2afb14515f5e9108ae18d900cac0"): true, + common.HexToHash("0x72bc01b2a6682f9ccd5c87f4b0bfb7c1cae0ace1dbda315ea69272c75991ff9f"): true, + common.HexToHash("0x09e28e5506e373879400ccc81d3834ef84e7ec9e6df9575676b42d0061ade919"): true, + common.HexToHash("0x280edf28a7dca28ea98eeb361308568d1df67816c72ae9ac8c3811a3f77218ef"): true, + common.HexToHash("0x103a81c490c15dc6d4b946279683a42f14675e71bf188f9e69c6e828146c319c"): true, + common.HexToHash("0xe055c1a84d6a7e62a34d84853b962b18269fc6e7a2f10dea8182f9598adab63a"): true, + common.HexToHash("0xc7d51af2a8ed99843c94f12679608c2ef86118901f4c1355fd1b8b66e28609cb"): true, + common.HexToHash("0xceec554607bd4b9e3701b590b7d9db6f5441d3c65e76bfd3352d4d5965300544"): true, + common.HexToHash("0xc27b87b2261f3b6d1580ef43723702c50dab7fe856444d4f913f077bcf6fa50b"): true, + common.HexToHash("0xf3c592e1d97ef8f78a7efbf619f39e1d21a20b6e326abbbd5ec85ae5798711d4"): true, + common.HexToHash("0x2446fdd4357a5f1165977c2a5ea5d9849b0446598e78114846d70645a5c78975"): true, + common.HexToHash("0xb2866d51ab30dfb998dbd3a7055a6527fdbac9a147fb17fcf7e6d9bbc3be0168"): true, + common.HexToHash("0x4c7ee274bbefa644eba60710c1eb4168543cda75b3e8605883e7d3acce045291"): true, + common.HexToHash("0x1475f231e0e93f8cbfd87a69497677af26d5123315a447d0106020abbb4b0dd6"): true, + common.HexToHash("0x5c0ea43b64415169c5cea328c92e3c24824d16154a5c0ef9c276e375cfebebf6"): true, + common.HexToHash("0xc0bd5f6752084a3a86510542864b7cf7c0101c1d2cb11193246aca81e4e47302"): true, + common.HexToHash("0xbf9f56871a55fab83dc769403bd9b5e5e059b7d7f83718992953dbfcee570603"): true, + common.HexToHash("0x5c7a62f8a515eaa55c39053c19ec426155f51c1a5e4c2d2795df0d9cc9722e3e"): true, + common.HexToHash("0x63ae9b657a49ba4ee382f0ff477e030c19247d79949028e5858f4f2c2794df58"): true, + common.HexToHash("0xbcd520449d04e99c296f4cde04470127436f22f46574087aba463872b4bbf4d9"): true, + common.HexToHash("0x5f687c7f3f46ebb7dbb4d8c61605be0fe1d40651aa5e696b05f45ad8075d066f"): true, + common.HexToHash("0x9d9d544cd37890e5971e5f29c1d630059166125b70fd04059e6b6ac99d4685a7"): true, + common.HexToHash("0x542836bd3c0791e93db8f268e6f72d2e56a7d5c2fe05f1fa0bcfad1bf4ffc6d6"): true, + common.HexToHash("0x41dc115eac25fc12591c927cb045b70df4025a288ebf0df3cb99427226c0a12d"): true, + common.HexToHash("0xf36b1ff9e641c1473cac4c56340161a3d7915bd251f05365c0540d714eee9d28"): true, + common.HexToHash("0x73c314e38937c4a5682c3c95ceab04c0260909bd7d64788885a9afffa52444b5"): true, + common.HexToHash("0x6c02480a8ff00eb8336cf7c1bc0262a5970ae472b370638ca15e514627a8bec8"): true, + common.HexToHash("0x4291d1cfbdc4d3361385f4d80ee177b0b11864bc734a2feee0ea3fbd24eb10cb"): true, + common.HexToHash("0xac145f0a4a4303906fdf639344d7807e0e086d6e5f9d78ca032217bb0e2d6b3d"): true, + common.HexToHash("0x351fdff29db94f8895cb08068da49b07280ac69a76e12b05d81b7663c3493652"): true, + common.HexToHash("0x2c26050bb2541af454637281d460b8a5be214e654a7595e569160d489606913e"): true, + common.HexToHash("0x62361e0594ad9e13eb357edb612fba811c26d470c5c4a3d9138b82274778a13f"): true, + common.HexToHash("0x21e6fbe2c7d18d0aa0d2a44eacf973d739226b885d7cb2eb3bf563078112754f"): true, + common.HexToHash("0x4ef27efa794965d5de2881c484b6fe0380d897f8cd3520ad0ee40454d4e8f3ab"): true, + common.HexToHash("0x429aaaf65c24539804a1ae95389d227dbbdffc95630a9f2eb6a478eb2e0e549b"): true, + common.HexToHash("0x883ec7e325c172f59435175cb4e692a1d3f76b570629bc1ab25d0de3e4547a75"): true, + common.HexToHash("0x477c209e37894e8e826094cca3e4020e37f1a9cb096b65ac8608cae6a20477cc"): true, + common.HexToHash("0x4cbe2f6a25d5985cdf5f008e58d0ec7eceaab05c0b2ea946e9d3e256d7ecec2d"): true, + common.HexToHash("0xd484e09b531d9cdb32e9271e8cc35c0ee5a2574baa11572ab66413f17e160d9a"): true, + common.HexToHash("0xb7ee3325f71919b5efe23178c92b9059d854831ad8fa1dfe59d4300f06c0b03c"): true, + common.HexToHash("0x5af96a0c41ad8ab613695081f60aae53a3bba7e305bda61b18281c9ecff42f98"): true, + common.HexToHash("0xbca423ba99bfd20eb8b97c4b1e47c1fb94933abcd6941cc2cf8d1fa8aae72d09"): true, + common.HexToHash("0x3b4eb09bd03204c15b138127f97156d1f9af5eccca842a745256aeb6f5f52cac"): true, + common.HexToHash("0x97ae7aae824d15b60992bda9bb7e4594493d6d725fbfbc715590be0684223b8b"): true, + common.HexToHash("0x3c903ea0d270ad5214df3d6d585f215c78b4e658b38751e5009008e1d60069c0"): true, + common.HexToHash("0x3fec95d4117d87efbe1ae9f2acd833809d74d09b7fbd31b090981832a3279c70"): true, + common.HexToHash("0xd21c5915230e9c7878822fb5a3ce0d70a971b4f91b76ccc7b24572e72a378d2a"): true, + common.HexToHash("0xb52f6211f06c696c35265b134aa7aae63377eb6d93310e5d025db69386cea8d7"): true, + common.HexToHash("0x3df0d331133938da7798af0c63101d4d65dc4de3499b8467254ba1cc8dc8c2f9"): true, + common.HexToHash("0xce6aec090dff6527efcad5fb422aa7445c35e92729dc63b706ecd0ba48e7c929"): true, + common.HexToHash("0x5a473880cff2ff8ee112992b462df2f3e202ee0808d6ca13732f990dfc40554c"): true, + common.HexToHash("0x15f14ec4fe404648b0d311c393505789a3710137ae3fb960dd96824c2bc14646"): true, + common.HexToHash("0xc9be2a77b0f1368242ab9908fa5cf22fab90c40745b2b083aa898b582b2c3ba0"): true, + common.HexToHash("0xa0131858b591c2aaaef4124b3341969db247a31f8c8fc5e54cdda83a12cb0a3f"): true, + common.HexToHash("0x0ba4d4d0ec54c14d692bd4c9ef6731d8d2f6b19b11c8867cfc1dc6f78d958217"): true, + common.HexToHash("0xffe690130ad9aa479f8f916e94bf03865901c14c6408393a741e458c946681f6"): true, + common.HexToHash("0x13309d1d5207ea191a5e3eace881644c30772d1f79e5e267abc115b488edc9d3"): true, + common.HexToHash("0x33804b0ab86e35d010bb60b66ac3f5b0cc8600251cbcffed64b0ece57c004519"): true, + common.HexToHash("0x7a903fe9888269044418192e98aaeca885118a890ea6d7e593022adccda4ee7e"): true, + common.HexToHash("0x11790409e85fbec2ef8e8f46de769e6721c1710dcebf2f8cf2e0422422f86e80"): true, + common.HexToHash("0x0e88ab3ee483aac088436a55611faae66170f50b18829b9e5a099995fade1d6b"): true, + common.HexToHash("0x241d5c7720ea2c2fa3663041ed929a72f4ae41d271de627036f31df8c517ea58"): true, + common.HexToHash("0xd097724448ffea21204afd9ffdf46056fb755061202c13ecac7683412dc18236"): true, + common.HexToHash("0x05574b166511c549d3677b4196b6f4fd8478f3705848813d8768fe283ae235f4"): true, + common.HexToHash("0x2bb56957e535068727971384688002891951ab827eba817debe32b1c705aea1f"): true, + common.HexToHash("0x09cb0ce0eef208f4c244b6add256c49d038d4ae647f4461860644ac70aff46be"): true, + common.HexToHash("0x6d737e35559cd46e36ca35a6e1d78e0d411a9bb75bd15419e99971d1e9f421f9"): true, + common.HexToHash("0x4b694dbdad45655708c7d61e9d5c18d2827434257d6e90ce52120d5139bf23e6"): true, + common.HexToHash("0x836542b88d1eee95b6f402b5d2eaae55be5d5b2e636f1641eea5371c2d40d245"): true, + common.HexToHash("0x7a82580c935bbf698ae6e078dd350dd6aea0e33552f8fe10f89e32c2ae73b258"): true, + common.HexToHash("0xb317b50232aa014caa0d910015837b7b809411fc2c7df2e6409c4d7726cd8123"): true, + common.HexToHash("0xa5a2aec3205aec03dd43a24adecd620a1d530a965aff612682932d2c3ee52d1d"): true, + common.HexToHash("0x7974cb480b6a1cddafd4bf6ca71abbd1ba3b72c277fcad0a3cb69e52c475c34b"): true, + common.HexToHash("0x963acda76ac17c25494aa32a6f226ad0f7ebdce18bad0c118f89b8237110c085"): true, + common.HexToHash("0xeb3ca8f26e022905044e238b19bd8631c825f0cd6c9e7f78c13ead0d889ca93f"): true, + common.HexToHash("0x112b1cba4ac0f2652db16e22518294fb00c7a8442549140a924829027439ca03"): true, + common.HexToHash("0x4e9598e54fefa2ff4006c956fecfb237f4fc8498d3f201f29d9c996503e1b690"): true, + common.HexToHash("0x78e36cf0ce4af8b2d3d11d01abe36788c0adb24ac26c375bca282e45d5b88ef7"): true, + common.HexToHash("0x7776845cb822640ccd1e97bafdd7175407b7cc6b6ea81bd022be6ded0dc6e715"): true, + common.HexToHash("0x70f1c8fe6e3fec95b9a36f6cae34c86e068ad45063aadc5c2bce52b2e3f8f2c1"): true, + common.HexToHash("0x3de8a46c5f3747de92ce05c5bbfdbdcedc8e57af864665708b2b966ba71efb79"): true, + common.HexToHash("0x4b07bf7726e86b7fc2233c4fb744ce0fe82e6e153accdf49a570d43574290dff"): true, + common.HexToHash("0x2282a4ec0040f4e2e4732afdd0862bc6d02fbdf65ff92038e5d459122a36ff76"): true, + common.HexToHash("0x07555018531da894617b8b942f282d04530f2f0622cfedf831fcb8ea2950612c"): true, + common.HexToHash("0x4e4b98d5be6fc65fc9ae4986a9e86bc21db05041a5b6df6e133327cb9685d2cb"): true, + common.HexToHash("0x3d17d835ffaf50b3e55e091735180ec48033c5b90b5c61f5b8d6eb897d6a7351"): true, + common.HexToHash("0xe09478df2a3bf49d69f5fe04ae9d5ddc9bf24373fc3adda96d269e5c26842bcb"): true, + common.HexToHash("0x35e8a716280e03b83126b1527c5b2bcdac72e84e914a2911073975fa2b3199c7"): true, + common.HexToHash("0x3fd24aa35bffa38f0ee6f030b660ba64ec85ebf0ba4ee99a7864b79c761096bb"): true, + common.HexToHash("0x32fd6e68cf91b89b6c58a1b3ec21259e1f0559c552d70236aa3f9b2c0d422092"): true, + common.HexToHash("0xa00de8b00a582f1037c453ebe85278139a54e74f030a4a840dd2715af7a2f903"): true, + common.HexToHash("0x495e978a0ffa7660684d7047ae164354ea54bae97f502f1bc306dd5c4fc7ee0a"): true, + common.HexToHash("0x2ace053148aba036c2f7da15248b760ee16c8b4f2ef1f34b45ec36d56fba8549"): true, + common.HexToHash("0xd0a445cc9e95efe83574f62b6db78166f1e9f4d876188ec59114995bf0b136af"): true, + common.HexToHash("0x275a4bb1a5e59c0993e998d38e95d8bbe253de81b9202f6a9a59f7d775930acd"): true, + common.HexToHash("0x57802fbc1804ea6618b2e355ae3e2aafe9d3871a762afd741cb18561a4521d77"): true, + common.HexToHash("0xab16c364a4fe4d61501d1a40266ba2875fc51bbcac827e25524dcd75ecfe525a"): true, + common.HexToHash("0xadffcf18c978e1abe65f7c7e3c5b9f6645bbd5c505dc674afb342d9fa563ec5b"): true, + common.HexToHash("0x30ee5df34615cebd862af8e4ca3d1e0feae338a131af839b72a119515e4b925d"): true, + common.HexToHash("0xcf61c93bd81121a9204507df11b180c70ff65e49f437b0bc1f5fb910f026609c"): true, + common.HexToHash("0xd4b47211921b02692e081ee9fc1a87bbc6482c6ae49a2b03e58bf39f21b5b2fd"): true, + common.HexToHash("0xc58b5208577870c56026a36d57d12e804d42197b9b3cf54f855c2798bd80af0a"): true, + common.HexToHash("0x82fbe8fc949d582d3ae2b19e3d8ec9cca9c84483b7203445eee531674af7fd3f"): true, + common.HexToHash("0xe4322f12206df42b847042ec57eef3a3c6d8b49b66e679fc49b9bafbd7c48f84"): true, + common.HexToHash("0xdb078721c45027345991f19400819df143c09fbfad54cefdf2dfb34cfa604f51"): true, + common.HexToHash("0xd0799340f5987f6850ac48fea9fc225c60c39b0d2e58c6c9c79447d1e38a9882"): true, + common.HexToHash("0x0ee025e772cb24b97a03dbb9f6c7e23a86529bd4b0b192944705e605c36dfb52"): true, + common.HexToHash("0x9d700e904ff584b82755c7acbb055ff71ad4434f9b680dcad8688d038dff9697"): true, + common.HexToHash("0xe12ec5c34cf26482e520efebfb719c75121436f23d5e35edbff26ed5d29ace54"): true, + common.HexToHash("0x239d3db68a72a5227fc5522b7f0c9ff61c0f70339942dd5f7e58f88cc98a857f"): true, + common.HexToHash("0x8b64b95b5033d22e746ed8eabb41d80f1031ba1529a07ac3fb6e80c6ad948b4f"): true, + common.HexToHash("0x73c09ac4bb2e83b94ad09cbdc7418de3679c73b97cccb9a0eef702c6dce79b95"): true, + common.HexToHash("0x809097039a175d96f990c2a016ece8b9f46069d5d1bb404119af985f921c2e80"): true, + common.HexToHash("0x75be507a4637437631cee85eaafbfd054cc07497d0e2e0b196daccbfc868fdd6"): true, + common.HexToHash("0x1fbd6f83ef51425739e26550d5ffee5c57a0a5caa3cdcb596dc09b69b4cf7749"): true, + common.HexToHash("0x10753d32e6fea36d2ec7a96db3a8f69b13cb178f6c4416b5f11976f1f740af15"): true, + common.HexToHash("0x7624920a711800e2161fc7249a98aa32de667856ea9f403696a5ced3628c177d"): true, + common.HexToHash("0x1fdd12d173e887d032fefddf732f2b4db10a2cc49b24973fd382bda4f2cddfbe"): true, + common.HexToHash("0xa9d13a1803e736980d0c87f0840b530143befa0f68c2db3e543dee6f9c2ea35f"): true, + common.HexToHash("0x38597d532f483494ba23dee981e29a6eb4f97bb45385a2893e835bb2a77991e0"): true, + common.HexToHash("0xc6f62e3e725938f7d7bc52ba67f6b704a0903684df6dfe3dc3ba3ca416133890"): true, + common.HexToHash("0x8676d58d1eca216243d8224015bb1269a2f4c88657d2f0851de7bca887b0fd75"): true, + common.HexToHash("0x212a068846160aadd254c02bf21760ce10198cb434032c7abc5df253d687cf53"): true, + common.HexToHash("0x2d295806a22161e86de0a2987e33fc32f1476460ccb5248b0a13e250ed5d772b"): true, + common.HexToHash("0xaf8d9ecd3f157e64a50095cece9fc3541e35936cd9b4813c5abbc684d2cbb050"): true, + common.HexToHash("0x18f9ef66e5f8f17f0509e314d68474a48d36810e923c78769799e2df123e1712"): true, + common.HexToHash("0xc37255da7edc4f41d051ea20a2038b8f69cc76c38fc17d6d2f3841bf736ab86a"): true, + common.HexToHash("0x7bd6fb9af24b2a4741054627e588eab08e84bc2c70b22c0f077f89979849ad49"): true, + common.HexToHash("0x22bb6afa4da620a73c9dc86d49d198ff7ceb3b765a3ff1f8cdbafdb9d215caee"): true, + common.HexToHash("0x1e1fcfaad94859f2a5c5d83837e86e9c91de30252aaf95a6241b7e39c00a5c46"): true, + common.HexToHash("0xa46ae845e281d11195f60ac4071d6ebfbc03a45ad1a03a1952e35ddb36bcee28"): true, + common.HexToHash("0xf51458b147754d2a2b649f070e89616993b09121c155e3164881ec50f0b0b412"): true, + common.HexToHash("0xb9a512e3849683d4cd49730e1cb528f8ae845f9968d7fad574f06aa4fe3cca3e"): true, + common.HexToHash("0x21d6b4cb20696758f5f58b5fe018cc37f7748a593aa0a757b93b97237f70d780"): true, + common.HexToHash("0x312b25d12300deeb06c4ab54ef2da5aa30e53d0510bb6abd25eaa3c78bdca771"): true, + common.HexToHash("0x85446d248909b85211714e3c4547ccb80fa18e46dca2d46303ca87b26ef93d51"): true, + common.HexToHash("0xf8df96c57c6b659e86628b49c8d7e180788e804845f6f86c1ab9fab50b4a3be0"): true, + common.HexToHash("0x3ddfd8779bf4c61306e8f550c522d74fa5a67e13de2845aae942c2a67c28a132"): true, + common.HexToHash("0x48071e37c0ca1916e6533a3be461590a5542808dd7fbc4936ef4792decdeb58a"): true, + common.HexToHash("0x85cff247a48d5a78c261f62526cccc093e198314036d0d8840d7d02cbb9b2484"): true, + common.HexToHash("0x640e2a93170d08544e9b2e6e3157ee7f28c34ffa40526fdfb81e6ba29b4d0614"): true, + common.HexToHash("0x71a12f7cfb67177e9d2bc8d8f88f0412151e0bd20dbafa2bfacde72ca17304c2"): true, + common.HexToHash("0x173a44a72e3ccd40063a433b42f871c7d15dfe063641898916371307f9fbc18e"): true, + common.HexToHash("0x9b57d88a5800a8eb4dd26c535273a067a3a6c664f6bb4106a1f55cad89bfded4"): true, + common.HexToHash("0x0ba10a4bfcbaaad3c1533bc0836cdd139fa29888ef6b3461e4f5304b283a2f85"): true, + common.HexToHash("0x712d9b2a1354dd4fd0093ea12110166dd3a66c2150d3ddc1d00c4d07323f61b6"): true, + common.HexToHash("0xc694d59ef6f421bfe12aa9af2c0b2bbc5429eecc842bced5a2833c542e262a17"): true, + common.HexToHash("0xa68b0e764a44c6297cda0992489da69d1de46acd9f6c5972916a886c1df96fcf"): true, + common.HexToHash("0xc78de3329a170387d2efa2cf51728523ef09ddae1066908c606da355ebc134c5"): true, + common.HexToHash("0x3c7ab9f2d70e30a0870366024d09679060542f0f4d985eab417313bcd4c7dc86"): true, + common.HexToHash("0x260899df4e4cadf2d7cd41cf39eaafe88d1ee5f7df1e1e98ab24afb43edae8d4"): true, + common.HexToHash("0x0d3bc2bef2b8d69bd8b117375c0411c5d770e469d45b81642bdfba3144fa612e"): true, + common.HexToHash("0xd525fcdec2edc7162c839ce7b73a0c19fb5647d4337739e6cd8b48b8c2094007"): true, + common.HexToHash("0xcd6fdc9246465bed35a071a9834465f13dd5673bbd842d4f358313b53c1076f2"): true, + common.HexToHash("0x740161ad0a19088ec847bdbff4b0420b9db95285ca1a2b3e416d768ea8301a9d"): true, + common.HexToHash("0x3ea42258aaba72ce186bdcc5a0aaf27c6c6a6eaffffc8dda605b90150acf87db"): true, + common.HexToHash("0x8978e04d898bfa2b8b9c29fbdca635f1a2b2a91cc15a0d8bbd477375683f52ec"): true, + common.HexToHash("0xfe00267333e3eb375dcf1c1a6a964d844735a8610b4b0bf966313523b9951c1d"): true, + common.HexToHash("0xe3e764d3c4b9d32136e6562df5632601d64bda7111a2bcdab246cb1d15d2ed8b"): true, + common.HexToHash("0xe8eafd8859f2e8bb42d952dddec0828ce1e89e9c6748064f3f2f2a9afc3fcc5e"): true, + common.HexToHash("0xb1f235e62c1a26412a483ced72e87d77dce330ac471837db1195b1e50861ddf0"): true, + common.HexToHash("0x851d749c759b1f9c0845cd8998f9b4ab4cdcca9d507026c0366107d2e4d7cd9a"): true, + common.HexToHash("0x8c07cf9f3e42850f3792c7d023caf5194bab4ab1c2183b76be0f2636d2e63026"): true, + common.HexToHash("0xcb3f8826ee1a847eae24bb5e67115e41e169a00d7aa40b5f63d2a2b72d754e8e"): true, + common.HexToHash("0xeb0d0d7b3246199b5c89203118d249e098a5614d5937b5fe95744b993bfe2105"): true, + common.HexToHash("0x3435b3fb3ba6f16832d7098be3c8ff1759a122f6799dbb5e999963323e51cfad"): true, + common.HexToHash("0x35cb61bb9bb490a50650b92c78101f16d8623a0f1eecef86e4bedf292c75caa5"): true, + common.HexToHash("0x5ffdba2c8e19fadc7a37e58b31e86fe49e107d1f6f10e0d2c19d91caab696ffe"): true, + common.HexToHash("0x5acaac7738e9cc2382dcd81cc932b92d7eef9a09b39d1126129aeee69a6d59d9"): true, + common.HexToHash("0x8377d3b49f4a7a4e7c8187feb2512acadae5d289a09690a89c986206b0763777"): true, + common.HexToHash("0x7192a1d3e518e94ffd44569e3714ac7bcc506c49cfb2f3eef9734f39037e7842"): true, + common.HexToHash("0x125ffd89a1b42673e8be04edd4770930ff3857ba2a849817f70efc93c81079b0"): true, + common.HexToHash("0x12c8564fda631843492284a5d5eb2320cecd32340e0ea1ce8e34ab7d8370afc0"): true, + common.HexToHash("0x6fd2bb39e5d69a2e2a09b04e9fcfcfee4d5cd94d662299bca6710ad2d028558f"): true, + common.HexToHash("0x2f3cb6975707f206e94129451b0ff136dbd6db7bb959bfcd4d6bfc3da1582399"): true, + common.HexToHash("0x712f6d6b88fd353ae4da4c5fd7c960de3b231699cc5e8ae7577d1b688a8edca3"): true, + common.HexToHash("0xd4f33c26eb94c4bb9e661e5e6b385e565880487adbd1eabd45699ae8a392b30b"): true, + common.HexToHash("0xafb1f3df43776253d427699bd08cefe2eb097cb6825c5a0cc8fce79df44278c6"): true, + common.HexToHash("0x484f849ab582f477e45a088477cb150a5183b803307933c903c00b85da92b3bb"): true, + common.HexToHash("0x9501c2c0fc764d30faed6dbf79a4c8bb3eaa15c357893f0f02103c26736384c0"): true, + common.HexToHash("0xf2f8613e3d2eef51a56542c96b88abcd7bb43fa9220216938ac1c36c6af61aa9"): true, + common.HexToHash("0x908ed43e4660de2f0e8a13ec52fe248b969a74fb6074ec45e5397b73bbc730ce"): true, + common.HexToHash("0x5b2a68a23f68ecb8125d06e6e196b736baa96e8341b4ca80c304506c79bf9045"): true, + common.HexToHash("0x49a171350a209b3116573ba17cc1905b63b345ad3d48d1c5c2897017ba7909f3"): true, + common.HexToHash("0x7b433847166348e5f8487293c29007c784f762f7db3c75d5a99a2d7fd8ef6948"): true, + common.HexToHash("0xca8dbf0b3d7182fe57b06c318bb06d6bf4c1e281a319fc8581edeee849c955c7"): true, + common.HexToHash("0xed476b90dd6c6b383aeec7bb943a079bbad76d344ced6311346ce2b5409acbd0"): true, + common.HexToHash("0x02c1b5b68f0561d3c4c01dd6abb313d3ee02366263b71805c2a031344720b380"): true, + common.HexToHash("0xaccd41c6f7f2a6cd6da129eef9b0cffc299fe6f6c7913d2ac96ac63e8ef256ea"): true, + common.HexToHash("0xae06aff4ec67d4a60a115172c4002c46bb1b4c956cbefd865678f9d5b651f4d5"): true, + common.HexToHash("0xd17426b6dc51893c80b3a59d2f2b0f0a0de41ea64b8dee49284de286d1c38296"): true, + common.HexToHash("0x8d2d83b23ce7ef31e8a179e0b85bd8c49602d21e335f4dbcca1548f524340a44"): true, + common.HexToHash("0xb1a83e62d03013f910ea48456e4b9e438adade5aa90f2d29b1d821f8be5ea216"): true, + common.HexToHash("0xe8f7868e896a5407c56b0c6ff31eaf93a9bed8d9baaddb1ca9a2882296909495"): true, + common.HexToHash("0xc4d11175b232c3928f7e538272ae05e1aacc41ef358fe06bdbddbae73623f428"): true, + common.HexToHash("0xe872cdd8f04997ae04c6b86cc1a67b992219cb00be37811539fd43b38618a7e2"): true, + common.HexToHash("0xb4671882cd261ae1b83a8185a3869d8014792506f16edc0200679a555c416094"): true, + common.HexToHash("0x965855fcc98de8fa8b59fa5913f5a3d17f1f491d3a1bdd1efe075ef09293d57e"): true, + common.HexToHash("0xa687a571b90d7aa1f3903b9a6675462d148ee55b599612a865fed8292bc8e62a"): true, + common.HexToHash("0x611bd04c7dffd28900f3b797a86e1592c0c6659dd2bd3a79d9ac47917807ce65"): true, + common.HexToHash("0x89c782e05447b540bf5d2ee38c66bb35a7afa6d8aa1493bf83e4df3253ab286d"): true, + common.HexToHash("0x7dc1c0e874dc3a14870e52362d7ef60a0f43cf87aac225f6c99a8b4390be65ae"): true, + common.HexToHash("0x3be0867a9d49d0062ba090c6c0dc4a45b2662fe9e8c47815f93e2deb730a521c"): true, + common.HexToHash("0xa2196cf95a31554f551dc39370b948adb6fcc07d4fe521d996196278ccdb919c"): true, + common.HexToHash("0xe943d42dc6f1ebca9bd718b3964c0bdffd1e12137be82e06d7e516e8282fe3e8"): true, + common.HexToHash("0x5c6347d2057871e8f2d1bae8f17c2f8b01b3c86ccc963cc33500ed87f07511f4"): true, + common.HexToHash("0x23215b8a7c288baa538255203ac06f164c348bf8bb062fc64b04f9de754bf6d2"): true, + common.HexToHash("0xd76670c76ed36dbb4153ec1c18d3c3f9d5f0108a914f66a96e1d9ab8683b3089"): true, + common.HexToHash("0x4d5900f3cde4d2cfec373be18838c7482c589e5af9557a468448813658f7af51"): true, + common.HexToHash("0x77617efa708361f9b3e01152226489bff21c11e44208f8ce6d911ed2b40c90ba"): true, + common.HexToHash("0x53803e1b395683cf92c7c41362a587e7a3eab2f8ce5ef430e4257599a034a13a"): true, + common.HexToHash("0xf14cd0e0a1a6989c9c9e7757c108c1f3af8d2e4aa46a3a2f8ea5b80956dd10f1"): true, + common.HexToHash("0x4d52952a6e74eb1f168ec568dfbfea0b089c7113f790e1fd03032a8ea56d56de"): true, + common.HexToHash("0x43024d72f5244b1f24b7dc05f6fdcd1e541fa19a548f30e225e6f4f4307e0386"): true, + common.HexToHash("0xf5b7f8e13ffd26b97edafb90d293f1802f6a269695c7879898c83070d3de8769"): true, + common.HexToHash("0x26869bd6fe870a2c457f94214c149fdf65529984f7ddbda59aca49151e8d6c6d"): true, + common.HexToHash("0xa2dfd64e23f0ec042f9bf5c9a61ec2ec4dbd6ca2e4e73b4cf6c324cf36cb2971"): true, + common.HexToHash("0xde9bc4471d9233d7f467029d3df145a7d351d151285bbda27dc6bf9c09c9cba1"): true, + common.HexToHash("0x300f2607b9275c2fd3b399b5114f1adf3d8b76fd85001de9b9cd9ccf87fcec59"): true, + common.HexToHash("0x51f3d27ecfccb28bd83bafd07f1248aa1fb3f22c2974279dae5088d95f4d302a"): true, + common.HexToHash("0x0144254b94f19b19bc9d33644a71ff33726602bd30485aebfeb6a506f27ee976"): true, + common.HexToHash("0xdbb4f29519513f38b8d81ecf663510d7fc9011e70fdb865c19657d286420785a"): true, + common.HexToHash("0xef506b34519f2e89dcf3d9d685f912c342f04baa2c17cae9816b14915c8a625d"): true, + common.HexToHash("0x7bfd877f680b8034e1ba9ed80fef819769d13b0c5c2059ee614f0681cbf639c3"): true, + common.HexToHash("0xc092b753b3ebfa32486265841c85c79bb4ed74965e5fc5bc31d1164d8e80b5d4"): true, + common.HexToHash("0x2986398d6d291ff85d66ce03345ebaa91472c003b2b18ea431746a297644b7c6"): true, + common.HexToHash("0xb006e27bf722a2cdbd5d90ca9996929dc2545a45f926788191a2052aabe91652"): true, + common.HexToHash("0xdcb4d626559312eaff0c652e523156149271a4f407ca44dda335f77091bd3552"): true, + common.HexToHash("0x4fb91f39c1f273ff5ddde828787564ab36c153a9917947e567565dd17e2339d4"): true, + common.HexToHash("0xb399f616686e35ce02919dae5420acd8351f699c0d261689e0847105b5483b54"): true, + common.HexToHash("0xe7e7e6ea4762a8782fa8b938499d55117dc58302826d33a3245cb8ab982b1957"): true, + common.HexToHash("0x18b55093e9c84a869620b5eb414f3196bdc9213eb98759ba1c60ede39be319e5"): true, + common.HexToHash("0x8e937a8316d47af79e6a2908e86014282cd95014f1abb9e644c4afcfd28c0644"): true, + common.HexToHash("0x8da16d67d31b2850a636b70f4db6ba93044fd98f4164bcef4952e8d28014787f"): true, + common.HexToHash("0x2a0a107e01d6cbf717197013573a284ad5ff94b4ccccb3d5255ab749402a90ea"): true, + common.HexToHash("0x44030cc0e1952db1ab94c78ceb6ada0186de861807c22045635fcf0d0c5d0edf"): true, + common.HexToHash("0x0b9ea3661f008369e1afad4ebcf3824f6ea0bf8ac8a771f163f915d312afabc2"): true, + common.HexToHash("0x3e1f697e34f00d306449f2206b6f7e364e76761f1683110dec1ae517e619dd95"): true, + common.HexToHash("0xcfb6a3a98e373a2d1d1f038252961119fc900397523a8b1442158c77777328db"): true, + common.HexToHash("0xc0198ec0ce92d7d9342f301a524ab98ba73e9fe0f462c9315223804af6ca6642"): true, + common.HexToHash("0xa252b712cce9bde2cf998c3d6f805ce1c392f448b2e04b9ba05ae0c73210c821"): true, + common.HexToHash("0x52d1ff62e42d8f13d239ce9362459e2afd2d068e52d7ecae41682845e5b34fc7"): true, + common.HexToHash("0x377352dbdb60aff526b2a6915e99add57e80b40b55e8343eefafe56d58b5ebba"): true, + common.HexToHash("0x5418a3eecce75c88031b30fcc2f798bbe8c46cee55903e46ae3dabf6c38666ad"): true, + common.HexToHash("0x8f3576eb423b6be4eb2d014d0e06db71982f6a4cdee60598d33b962f26dcd3cc"): true, + common.HexToHash("0x67f558710720266948125dc6551d0996d05ac3cfc23fc4ae993f5cded9826d00"): true, + common.HexToHash("0xbf3cd7f67ed9ee58a81ad49c3d5ab4c5d1b4a6efe439f16cad7fe0310942fad5"): true, + common.HexToHash("0xfbd18e659efac229cdc79962b10a6ba1937fb4f58d3811b4c4dba043073cd268"): true, + common.HexToHash("0x8ac48336f20bfc2df916c417caadd975bb45c8929f76a17dafeacefa2ecea95d"): true, + common.HexToHash("0xe068a5c3228dedd61af7c24c3acf336f078162e5b86f8fa1f6fdf9a769e2121c"): true, + common.HexToHash("0xfa93939ccd4a7c206e4069f64ab5986a0d3089d12063c9aef47583010f9a862e"): true, + common.HexToHash("0x64b188a0084e143d65554a62f551b5b615f87ce4f4bcfef4dbce62abaef441b4"): true, + common.HexToHash("0xbb334d4ec6d5ab18ae62ec1c64c8836282e8c7102546a37d3307b9373e5a5347"): true, + common.HexToHash("0xee8d206387f8b243da53963b469fc761bfa45372c8faf5e57420b44da4924d66"): true, + common.HexToHash("0xe4103fb8cddb7d86e8ab987996648f5cd486142455971dc4f292c2eb929427c4"): true, + common.HexToHash("0x18ba7179750b8a11d88d23309fa052ec3485c7445914f95f056d6667e8db3664"): true, + common.HexToHash("0xc965fc943f2def44d0e946491ac6661d2a274f0b2f7cc023e40e42a3e6a9bdf5"): true, + common.HexToHash("0xf6d55d653ceb41ba4c16010d47cee49a2a8ed34051c4f8dc265153e784bcb550"): true, + common.HexToHash("0x922bd057b9cfd0d493102304c6e107acc58f3b1f1f75c6ab5477d4f12a081486"): true, + common.HexToHash("0xeab35800c0b7e5b50765dc185096502ec69d8ad4e204017f5c73307a493b10c3"): true, + common.HexToHash("0xfbbca375d45aeb0c06ff9f45c9e83e2ba661ed398041f037cbfc1c7acddcf009"): true, + common.HexToHash("0x7fc626db76f2190c85d506c711ae4b7a07e2ab7926dd1cb8432c5a4886d6eee8"): true, + common.HexToHash("0x1a09d36f32e44cc5b5bb50fd7d0747f5bef012ac3dfa8e7539caaa9d47cd61f2"): true, + common.HexToHash("0xae97b99d689282deaa4e80dd16002c7f40b463521813625a6d93705d1699365f"): true, + common.HexToHash("0xc40b4edb71399dcb7eebed2035e69d60f9ba369150d1db243bf431837254e231"): true, + common.HexToHash("0xd473f277aa9bde66dc7edf788a2e7b8a0404fe0b085493de42e903cf6b8521e1"): true, + common.HexToHash("0x1ac98f13fb0fd1e59241698d64d611ec965ce02d1ac754ed9f73c2c2ec911db7"): true, + common.HexToHash("0xddf0fc792f173262c67be0e28bd5c95c3626828f52f56fdd3c8efcc5c289e993"): true, + common.HexToHash("0x13de01ff6aa03c889d4afe1cd215bf79dd2d8e122976ddfcab547c95b82e08df"): true, + common.HexToHash("0xe1ef8252b2a45bee21adf13a808c0614849d43a1313fda6e6350db14491e38f5"): true, + common.HexToHash("0x292875c3424cda66eb8727378fcb0f78f6816193d04d621fd8c7966b5bbf5256"): true, + common.HexToHash("0x3bdf8377c6e03a77252a9d31d9a8932acf41ac79cd17e88feaecdd17159af349"): true, + common.HexToHash("0x2fef475f077ba0401d638617da64fc6f0c2f8cda25a1cb43199236c49cbaecb3"): true, + common.HexToHash("0xcc6383f05305ddb59b469bbb94bf9de9c67ab9c8679375a8eb6f77c7ee22e815"): true, + common.HexToHash("0xe027b24784584454a652e1656df6fabda2f921d408d69ada7dd19dfd0b388f94"): true, + common.HexToHash("0x172d140946108dd78b67cf1e3b57c3c2e718764242acc93a1d3127748e968e30"): true, + common.HexToHash("0x286b4795daeef797aab6dcf972b7c7b293912c95d594842eaf7caa63fbd10ad5"): true, + common.HexToHash("0x13cfc2f6b0e37e7ce9e706fc1a818f4bb2f41309bdfefa6879854d6e1b436538"): true, + common.HexToHash("0xcdcc696ccfeb86e07dd0274c4e35d021b6d38b497db7554269d89fbf9ccaf4e1"): true, + common.HexToHash("0x126d97bf742933ab17d72a1fd56cdcc5b82e509ee3edbee219af399c743b00c0"): true, + common.HexToHash("0x1029967463514986023eeb214f6b6ddfbceaa0ea34af2d74d4831f51c131c9fc"): true, + common.HexToHash("0x7e67dd87f4576580eac6662d7788b03484b8767518c02066cad4cce8e4cb6efb"): true, + common.HexToHash("0xe17530f25d34095881e24298257542d3cc19174bfcfd461b35555d6fadb854cc"): true, + common.HexToHash("0x034627ea13d5ae6f854ec3e195dcad7936c374a9e8488168ce85cf726638fece"): true, + common.HexToHash("0xdc72db86d5d0bdb79bbf74bd1b79df06ba95b8cfe27e3d68cf9383edd56ce0e8"): true, + common.HexToHash("0xd7576c0b236a48f13aa29b46ec64867b865203315483659b2fd9f60f82c77813"): true, + common.HexToHash("0xbb2b5db37a162d2115351bbee7f443b6e3ace397a6cf90fb195fe5b6444bf732"): true, + common.HexToHash("0xc8405bdb6296520d15ebde9c4444a0bdb04b6ff32ec3b6bccd03ef2ab950b480"): true, + common.HexToHash("0x2108e106044088a7722c16817df6e18c1ed63ae3fe05b96fe4f33f1641e05693"): true, + common.HexToHash("0xd9a53a3811ccdf4b37203a81d536e232a6bf3bf1ce708f6c4e5f044d1dee87a5"): true, + common.HexToHash("0xba09b32bcc0022a3fcca8cbae8f7124c4df8d2ace3ecb14cc043b8712ce82aed"): true, + common.HexToHash("0xf601f7915bd392b072f8eb503b23e67c91073c263db8ee84ce82e35727950a8b"): true, + common.HexToHash("0x80c6dc6f89f5ddb749c18b7733e36917f2eddc607e7ef53ea6607a691dd52e19"): true, + common.HexToHash("0x122bbfa355176fd4eb90dcf4b9beacc6e0fccb7a3df3780a5c8f4bff8aa87c0a"): true, + common.HexToHash("0x2c33803551863b7f4378af3c3802808f764adc2d8b4139a3052514be5b27a4a6"): true, + common.HexToHash("0x9f92130dec85455041c4a39265c41983bb457c60671218696f4179ff70058756"): true, + common.HexToHash("0xe6a08499bd5b7cd5558ee1e5f73842d012dd8d73fe9c17510a8861a9fd6437a1"): true, + common.HexToHash("0x6ecb138e574fbd04b743971b7bb768d2b6c7adf9e6c8ad043a30d9bb0e942313"): true, + common.HexToHash("0x3bd0613cdad486df4ebfcb67bda3669f09bd402e6596713cb6205bafd27854ab"): true, + common.HexToHash("0xa74f9f23b1233603c40d0890152b746755fbd445412cfe193463b9993b4dcef8"): true, + common.HexToHash("0x872088698fd4fe39ec037ef862ba757f63235f514cb337031a8bb10703e10c51"): true, + common.HexToHash("0xd7518e0356b994fc3d804f882bffc37822c334f4cc38e2c1af0a099239b5aab5"): true, + common.HexToHash("0x7bbb049d439292d6317243bcf5f1ecd09e05c2abaa2ef412447c75162179065f"): true, + common.HexToHash("0x8c977dbf7fa9d248fe4881ab3dff88c0d4f0e64798d29634b469b4e08e088418"): true, + common.HexToHash("0x30eb12504e2003580f02a2d81901b7ac09bfc04fae6783d0a287458a9766057d"): true, + common.HexToHash("0x3828668735f5718ae7939714e5c45bf2ad03709195c9b01dbdf37d4ea3332330"): true, + common.HexToHash("0x934cfd04adb3b38725e4f5863a691bc303221cf0ce1f59c2d812195e2b4819e2"): true, + common.HexToHash("0x299d7ed7180c1c4863b4f61bd6b193f36962d8bf36d1282f041c5082682eaec9"): true, + common.HexToHash("0x533856f95964fc04b7b15b204ac724dd53ad5156ba60a09a0a7bfe5f7f4ad835"): true, + common.HexToHash("0x75570ff0c0ecb3549dc135de76cfa56a26ace0a553e5dd2197fd95b4dfd04331"): true, + common.HexToHash("0xc2f135ecb591a3df13edb9da5cff1389dea6b745c14382b2329ef8a78aaaf7bf"): true, + common.HexToHash("0x33344544306285b5b03848fd6e27107ce833b830b4401f8db555501bf6ef50f6"): true, + common.HexToHash("0x7ab4a4ff0bf3d90d9b75c3e5406e2332f333b17e62538423540a7dda4e8774cd"): true, + common.HexToHash("0x028f3fa87b486f1fb8d7c743a03ef43f5677a24f4e0dd4ab42e0db5ad505456f"): true, + common.HexToHash("0xef9c472be09077cc1553c1be23470d41ebd88e3b94c570e9c4904a73f3fa06d9"): true, + common.HexToHash("0xdbca07f400ffcf041cf0047dfd055ed38d138943de27f611e09cea5c6d096f4c"): true, + common.HexToHash("0x6a1c60d47a421da92d3f50e122a30d0bbf8541413ef0588d9588bd6c05c22c7d"): true, + common.HexToHash("0x3e169d472d466b68a66cbef70c9389b40866cea4c25b6e69d111ac4bff537d0e"): true, + common.HexToHash("0x2dd876d480e16dc76d473f768e45fad7b1a1584c08259818478cae07ebe01609"): true, + common.HexToHash("0xe36eec0530636793354dfdbd55799d266e9e3c7f8bbe6c0649e03295a6e64fa6"): true, + common.HexToHash("0xc44101233db98528830387bdf15d064002f58f9cf2fc984c69ac73fda3bdfa2f"): true, + common.HexToHash("0x1c8bc39be8945f363dfdbcf70cd8479d2dccd08ade0bed32d6a6638cd92b4d3d"): true, + common.HexToHash("0xeb6a1e12149e1b5b822bcec703f475fc0e19d0bbcafbd8699e17486f502ef24f"): true, + common.HexToHash("0x22ab3048dbdbdd3f5278bc6c511639dd010ebb07ace60d60c146d6044e639397"): true, + common.HexToHash("0xbda73ba256d8c66e2223a9995c99610e1098096ece94d8698cfa2dfca6bed491"): true, + common.HexToHash("0xa125d12a349847587c9b6381afc5fa970a227006795f77ee0153722221e804d0"): true, + common.HexToHash("0xa330056d9c88e5f19206d90cc8fa403074cd02dd8cac4f62bb306a45fb359b7c"): true, + common.HexToHash("0x38bbe56dd27bca5e5aaf3a38911fdb958f21a72a2644bb817ac54c2897595af1"): true, + common.HexToHash("0x52cd1512023dcbdf14ef56ce0f1189bfdae29eb411fcf2b8d191e5d8b8116da3"): true, + common.HexToHash("0xd28a7456c6515e5da434c8e85ca39b85b27dc2179a6d542f8ed830b06dda61fc"): true, + common.HexToHash("0x8e784b6287f75ff2484580c9c568ddf7d12d76d6965002c5fb1db525ba753589"): true, + common.HexToHash("0xeb257b4344c9a3d607179cd5618447e50010c54a056cc4c9ea6e81459359c36d"): true, + common.HexToHash("0x1020925e95425583552e59b3390623b50985d3fd6676c96d3b9d0c7f1015d27d"): true, + common.HexToHash("0xf2cfbd83718664ce0ccf189aced3a64013a466ccd4fca175d323f840b1733d4b"): true, + common.HexToHash("0xfd048e5652487adf2d971ef17d44e292434ef94fc4a8df43db96b78a7205f18e"): true, + common.HexToHash("0x02cad3b63e2e3097c42a6798d9332c92ed0e2f03a7498d5dd9bf75e81bee5b46"): true, + common.HexToHash("0xf6558ec6b46e92acbfd39f580be16308da17206c432ea8933e06ded86f5a06f7"): true, + common.HexToHash("0x1cae70048830d0895b81fb726a51e2cb26f4bb8cffc010d3e2907a76e1d74939"): true, + common.HexToHash("0xb875a6e243c602525ee49c862d73316a848b3e0c266eb230aae6a556798195f8"): true, + common.HexToHash("0x9e439e3ba9318ddd62db03d9fbbde756268b778c87177fbb623e14649783b83b"): true, + common.HexToHash("0x5781098699097e74535ee14610c6f4f09922a064611fddea8cb43a2da0deab93"): true, + common.HexToHash("0x5d5bbf7440624a9c74975f28d070eba759848e7d2533c5440f656695fa368348"): true, + common.HexToHash("0x40b978e03bb23cd0e79a228d39947b6a623cbdf09308bd30affdf7c4194b43d3"): true, + common.HexToHash("0xad60688428c596396b05d31ffbc449cf1be49efd31384805b0c6cb5d8fa1e233"): true, + common.HexToHash("0x786cff6f605070e6e54757cef896c27d94e71244d7319c642f9f7dd131eebc47"): true, + common.HexToHash("0x0053f85df9d53cfc5f0a59f8763090349c54b420a808ef4b57d034747d355b21"): true, + common.HexToHash("0x768c72ad2bf55337728cdfc49c8b7a352862b62dc7de2f9dc98ee9654e4492da"): true, + common.HexToHash("0xdbc28cb6502902f37f3796dbad16b10fdefd567d9a4fcf8d17e6c3052acf38ea"): true, + common.HexToHash("0x28c6a944507221aac1dd1e87c125ac3e89e16278b3a9aef94d79aa4a6c2f88f7"): true, + common.HexToHash("0xf35c76b816f67c058f2132c9ac11b07ba82e70a24e287b399cd3c498f95c32d3"): true, + common.HexToHash("0x829c1b5f7b180e11dd0848d75be7adc83cd44452a9237f880733f395d71ef73a"): true, + common.HexToHash("0xd44d785251d9e05500ec9d46cae810b39a8e0c012c2fdc64afb8839f5ef07b59"): true, + common.HexToHash("0xbbda71eb244805658e101411838c3bf16f4783c3f2008928628f9ef7963a1926"): true, + common.HexToHash("0x3128b851dd5506472e273cf1d201e2e1d28b0948e7ede841d05d1b1201b9bb5f"): true, + common.HexToHash("0xf3eced4675fbf517493ce52588a8aef4692cafec957659f60fbe8642ab7a052d"): true, + common.HexToHash("0xd92c8075de456c11793a6e1cf51a3288cfe705dd73e0a1dc20994aa506f87a22"): true, + common.HexToHash("0xf940fdaae983fc57c8337415efcf0b77b91e21798e1e6d30344f9af3bb2f6ef3"): true, + common.HexToHash("0x160106afbb5adc6d29dc3017a2f1942aa3c02859b61b1f72a0c63725f3dab05f"): true, + common.HexToHash("0xe784e1a63212a3e8c7e0aab6e5baafe68dd11d0eeb62dbfd1f9e28d5509acbe3"): true, + common.HexToHash("0x7710d361d215a064c94ef59c4c89ebbcf9af087bc714c373436cf38bbdcc03f4"): true, + common.HexToHash("0xd0b23067ad9d8555594988125842187392db5ee8c60776e8ff8a47aeed2aa679"): true, + common.HexToHash("0x8b0c9310d8887916d42d55de23152fadf050fba9ebe963a70d001dbfe6ecda31"): true, + common.HexToHash("0x07f747786c025a76eca5efb9144b5b33de5ee2c0fdeecf957bc6fdabbc02fea1"): true, + common.HexToHash("0x5b55a434eaf1124cbd2fae23e713c15b6c8d44f28ab17ae1e1537677d764246a"): true, + common.HexToHash("0x6558e5ff27309d7e8327ef75af8bac426615f81d69b10f83b72c292b1c4541ec"): true, + common.HexToHash("0x49601d7b36efaa3e7e3e93985b3ce5781491d6b605432ee1acd5aa6a25452c39"): true, + common.HexToHash("0xcfc123cc708dca853258b0c10f61ca40e739a284eb5932cd142b2d60e117dcd7"): true, + common.HexToHash("0xf8fdb7c1c6f461fa7b3a6e7a15a61fc0489b678a81f418b311b9c22ef9e65f71"): true, + common.HexToHash("0x17a9ca8e2d333fae0b8318aa93dcf159a9d358d6987044f7aa757e2a0b742613"): true, + common.HexToHash("0x4fc68cdd3a3d8b1d616d2f2869a7337650e53a45da8042a715a8c77d792879f0"): true, + common.HexToHash("0xf61b096ac1b0a0a43270cf98fce8282a5fc2de10dad34d5830af11b10d93430e"): true, + common.HexToHash("0x684b713fa7b6bfc7ed4522d70ddd0d038c0cbf5aec9a7bc8d4747769c63b941e"): true, + common.HexToHash("0x6e4ffecafbf425c652c87702440428d9f1d00104174e2adf27f7209fe03868a5"): true, + common.HexToHash("0xe53ebc3129fb009222a4062cf21c6cb4c1768036ce303fdb005b4b073fd8b866"): true, + common.HexToHash("0xdffc0d9db0ba205d43a998ed687e7454d710690b7df52c8fa10c0b891e4e631c"): true, + common.HexToHash("0x82aef69cb8e404afb0a8b85b51ec96c470bdd4668bc544b76b47bf69a1df2441"): true, + common.HexToHash("0x714a474edffa752cca4eb26b64e1d210361b1ff33999bc92459e70928055cb35"): true, + common.HexToHash("0xe080883addb541adb50f80466b32ce5034769396ae8e137758e971c9074db53a"): true, + common.HexToHash("0xb012da67c8c0e30cb8172ce7b0846beebe75b4b4671f8cd770387e5059e60d95"): true, + common.HexToHash("0x2215943a94dce03639e9cfa345dfeb80258b95628a9a2d6c805605746fb21284"): true, + common.HexToHash("0x4706bbd33bfedcfcee8770615977c7043a607f1a6708b4b34d7241356a50fa97"): true, + common.HexToHash("0x849b32eae449645aecb62cd61d69e3945fdfd3d73ab813e257ab9bba36853c04"): true, + common.HexToHash("0xef1afedfa9f2af2a2fd88ff439daa2e8bcf3d3b36de01b1919454020b096307c"): true, + common.HexToHash("0x6a6465190e8ff72ccdb8fc46d1dfbcb0acf94ebc4b5db9da832994a68b9a95e9"): true, + common.HexToHash("0x590de006c27a8560705bc196b615a4231a6078e1c254ac48e82c52fa36154f72"): true, + common.HexToHash("0xb755833102c106de904d9a681b92f3b4fe6f834aae1d565ee2c5de3dbfc445d5"): true, + common.HexToHash("0xc54cf57d6578e931e62c2b41db9a0cb065b538e116b74d9b424ffc9f662c9c01"): true, + common.HexToHash("0xd10ed1c47a66bef5da52f5a137375e3d2c235805cacbdf12bb8ba6278b671404"): true, + common.HexToHash("0xd491040b2e68e8da81e2e4b815235f8bbe77e1473a15804a84ecb513add326ef"): true, + common.HexToHash("0x16693db7e63d2f40eee743099937cbb6c612d832912c19ac35e1d50039bd4ffd"): true, + common.HexToHash("0xc907ae4f292ffd98e5cdfd4f503a1e703e4ba3c39dda40f2b6b518513f35da3d"): true, + common.HexToHash("0x9b453b78f017d61c55aa80e51a2d56dde5b17cdaedbaa79b526f85c9db4b4350"): true, + common.HexToHash("0x8c746235edf3c67652353f1e9f4380cfad548f03ce9e796a28c32afcf227edd5"): true, + common.HexToHash("0xf9aee42b836c609d28c724e42931d28e09c24b6054e39195eac705f9377a241a"): true, + common.HexToHash("0xe679d281b912024e4b69320ded67ff69e234850206215518159aed13ef1aafd7"): true, + common.HexToHash("0x876f5fdfca06bc7d7e9471b07b035ce6556c13e5077d4366e1b704fa9366341e"): true, + common.HexToHash("0xac463a714c493b195112722b24673836fe6e99dc0dfc063e0cbb9bf7fedd56b9"): true, + common.HexToHash("0x0ea138137865dc1e45845df9cbe9e634d080fa4640d183113b43f204db4d1f37"): true, + common.HexToHash("0x3bb1ace19790e53f8dc754534684af25b1afd54faa4b0329f5b9d42743b7a6aa"): true, + common.HexToHash("0x327673f2dc0c4765bb3ea2e24aa455ac45e46fa42e32acdc0c0cd1db548201e0"): true, + common.HexToHash("0x97a49c4802fbfdaf128708722169130562a9e4cabc158b9610e6d33ee94e83c4"): true, + common.HexToHash("0x64af0b81703691b0dc27047ebc961f351c258d5f544e7f0f807338d7e1649cc0"): true, + common.HexToHash("0xbb9bdc331513867d5a17634f0a2e51891d7498063b185bf4c0cad91caf2234e7"): true, + common.HexToHash("0xe48d836b3b0bfaa5063bfca2566ad02f9e5e38468e5de5ca30e8f411026b2898"): true, + common.HexToHash("0xe9108eac88bab79bc299cd6bfabef3d0a0d378c0d2f7a147d85a9a7c1671b125"): true, + common.HexToHash("0xf0b5fea55d74a76c0984df6f630d68490f3372688b5334233419e21277612719"): true, + common.HexToHash("0x6076abf602ed6dfa4c89c5e0f98c20cc8ce1a027cf7bc1227ae764e7eb49d75d"): true, + common.HexToHash("0xf5a17efcbb01a5557cb1131d6453498c696b70f2ba46f12ac30017b50cc9529d"): true, + common.HexToHash("0xdf22d04931d259fee6d762485a81ae4713aba3c574f374b9604d9129a7a73e70"): true, + common.HexToHash("0x61631d946892e3ff9a1103be0effd72904c276b232d800cea1aab11c20fe3691"): true, + common.HexToHash("0xf8a5cff64e5dfaa0b66511e70e4050e00e47b7dcef217b0a6909ea571a6b7bf4"): true, + common.HexToHash("0x7a6f45ef12343e4d160bb0d9112b712daac4de1b25b85be2d2bdbf918690da32"): true, + common.HexToHash("0x920eee1990ea228fd94a9cc88c994856132565c66e8c1503a9ee987e5bf12473"): true, + common.HexToHash("0xb86049f4513552bae2433173421b519f512b89fbfd2f24fe9de8832dcca7a939"): true, + common.HexToHash("0xcd9c5d307dc50dfaaaa8a2780fb56df567331d80e4209d63129302efcdce3250"): true, + common.HexToHash("0xde2ab1d3c3864e8acbee59fa07e5df029459b596c06c5ab734707e019d805993"): true, + common.HexToHash("0xe1fc308af2387d7014adb55759ba9ce5b3c4fc2682bb80f3fd4182d00df05ac0"): true, + common.HexToHash("0xa6d8b553b8d431510f3a9d3a6198d25fb7b8747792d51b96dbea248c731a8292"): true, + common.HexToHash("0x83fae404ee81342b380d5da9289fa256fb4897e0b3aa235e87771802c1d88f44"): true, + common.HexToHash("0x9cbba5ac1278c71fe6174be71da455922366b575128ffb562629e3fc7a4e370b"): true, + common.HexToHash("0x225fecd126fd60ce1c83f573849775666378bd6903398d0ab300e2f02d05a436"): true, + common.HexToHash("0x926fe12200e0d7dca0685f6e91e8cbfb24b58226de613d1fc79e73def52effe3"): true, + common.HexToHash("0x37f0ca9c84aff3225ff66c703e669b4ab4038c88d3d15682966a091957fc366d"): true, + common.HexToHash("0xc14d0804e17a45f42e55c786a19d0c07fb84b1735c907c239104ce8ae712905e"): true, + common.HexToHash("0x3d9c09533ea7de9517b98fc7345564b29954f0c35a783489005fbe5274cfb4bc"): true, + common.HexToHash("0x095e26ebea83462c6e673d3d0a9fdf4341d57c1631d34df781d2753b84b1911d"): true, + common.HexToHash("0x8fe3d0f57b3ae2780a9f14000ee4d922997c01b8596456b409e2fbae00a872a4"): true, + common.HexToHash("0x02ce0b6662a04e9d28dea84ab18b5326cd84f5a22ca9f34eb90fb493e9458ada"): true, + common.HexToHash("0x55e2b7dd5d135c3383bac1f5c399cc48f5dcced87193bb0f0d24326936debd66"): true, + common.HexToHash("0x21852e918fd9881ff0fd3a5c09b3ae1aa08de7d9ade9a8939d6024e91b97f780"): true, + common.HexToHash("0x33035b2238d9077caa219959d0ce122218197dd07c54c6fc90490f3bb6143828"): true, + common.HexToHash("0x85b36905c3b2bdf18d52ce67d75a6468f027f569302c1f12b62bc92384a58ece"): true, + common.HexToHash("0x0f6a61c9532730ed044ec33600650c5f7545605e52ecaa029f66d1bd168ca44e"): true, + common.HexToHash("0x5348397cd816d8e5a8a521937c0f567a19c4547662e3bf6b378e534dd5323ad1"): true, + common.HexToHash("0x0ba479d7d95d99dd27d9717a83587f6e4c24e827d591c8e1de431d2d3e07d02e"): true, + common.HexToHash("0x54de461ebabe6716784e00a263bc9a6faadbc4946a11b8e5862eba2c478302c0"): true, + common.HexToHash("0x5c73b0d81e0f274ac60f8a2a8bcecdfdbf14b5f1acfd5d73782913014c4e2053"): true, + common.HexToHash("0x220ee38a62f4bf280ceef30fcacf302126e4f29e65af3ee292b528bce5a74e98"): true, + common.HexToHash("0x4da8c39c6dd820e9228b161a7813cb6c0e89feffe8b8905044a48e6df213d420"): true, + common.HexToHash("0x7104a2dcc3400686bd8d3d452802f3c351fe355d045f9cd7ec159c74ef490852"): true, + common.HexToHash("0x8404ace5da8e9be0dae99b509161ca7fcaae7ca18a544ed8015612023e6d8ef3"): true, + common.HexToHash("0x413b8863964ecbc13639fa25c5122baa792a03b52315d0203035d2a3c4c4cb86"): true, + common.HexToHash("0xb098af50e64c550b6273bcfd2adccc76e892772134ace327ab373c98be5de40b"): true, + common.HexToHash("0xcfe3a5c0bca721aa32085adf2184cab18188237a5762d0ba49dbd7ca8d969d15"): true, + common.HexToHash("0x061ed458d96cbcbc12c4644a2cc9b979889047f5ca28709dde14f977e6dea4f2"): true, + common.HexToHash("0xfa3a441d56892b3c69523f4372628e4ea0849a4971914df1911c0544ba9f423f"): true, + common.HexToHash("0xc015dbd9de24cac3e8aca963f6ce5b7640427a56d23fbd582e6e8c86e0bc11ca"): true, + common.HexToHash("0x89d6e9cff8783f4ead8d6c1a5c76833f36d416cf032fe788c544a36c8c4543e8"): true, + common.HexToHash("0x69c14976090d04ca8bb0dfe605ebd29c4f67a28025eba00a319e530a9d9ec971"): true, + common.HexToHash("0x706505c8ae4597970b601a539fb622021a29fb01ce5aaae32b57da8f1b00e1b8"): true, + common.HexToHash("0x6624209c20837d3149d923a9b93b391e762ffee0dbc15d08b9fac8be4c1ce38a"): true, + common.HexToHash("0x968859397b819cd637da66fc1e9324d0e3beefcda367b2301dd6e1c2177e6c82"): true, + common.HexToHash("0x5b9498d685c4ef372db140ba2a72d6c8a87fce6c3cd427608a5d29d20960e90c"): true, + common.HexToHash("0x3865cb74df32f04b47c45460b3152053e9e3956b51a5df4ea1eccd1e7d17cf79"): true, + common.HexToHash("0x55f3ae17c91f0977e5f8246451d5ff31e5e7f9670244837b46e1c5ad68033ab1"): true, + common.HexToHash("0x19d3f1bc6517d0c6de6a218eaad17f079c6faa72c0736640bdb82755ded10446"): true, + common.HexToHash("0xbbb641c0485853ac1832e0a282ed6dddb798deac1325a484ea303f7cc3e0ae88"): true, + common.HexToHash("0x81dd85157c40bf77692b4706b940f23113790c52d5d55f373593335eb736c578"): true, + common.HexToHash("0x36aa99f22feb3f12c7ce0b50cc3cb2acc8659314eee0615e946cffc7e308cbec"): true, + common.HexToHash("0xfb756941d04adad1b03f4bd476b505257add2ef112dfaaada4b1718e171f392c"): true, + common.HexToHash("0x85fa6135f41e8180a536afb6157990c9415144780a071b60465713bcf350daeb"): true, + common.HexToHash("0xf38ab1c0feb7cd807322b2a56381eae526cb2452d492c8bd49ae1163b928a74f"): true, + common.HexToHash("0x50a3b8ffac5fb5227c517b0f2225c5020c0df8cd8bcb8b5434d68ead72d69bf9"): true, + common.HexToHash("0x0c493f7e29280101396fb5cfdaea5e75407ca0b81078287c13b7ab8f2fb1a512"): true, + common.HexToHash("0xff1656d0d758dc28c2bfe46e42b56f4cf03684900cf1bebc0cc3fa2e2b881d91"): true, + common.HexToHash("0xdd41bc92628b673e47c402811083d5dd286dd7751d870713d5f271b235aa67c0"): true, + common.HexToHash("0x8751e9ea611d0cac2cf0a67c1bc282cd0174493cc72aae1ff7935a7b8d23752a"): true, + common.HexToHash("0x36dee5147615f66b77a5c62066abe8139ad1fe87348a3dc8ce75523db2bef3e6"): true, + common.HexToHash("0x11b8486fd4d31e7662a93acd997f3426bfe240b44ca6f0cf043df18a076ef5e7"): true, + common.HexToHash("0x00bc82aa74fe201a94219766a863e9604c86067e450c93a831f5ced73ff6fbe8"): true, + common.HexToHash("0x973e3618a2db3579ae56662708bed4b03bbdddd9ccd8cb8ca985dc11628ff36c"): true, + common.HexToHash("0xece004df3c1cc89258b909415cf9fea96a29605960a89e4d1f68e376519b81e2"): true, + common.HexToHash("0xc48249770a7b833fa4c6819604bafac5edf6d5aa59ce58524514efe8971d8b5b"): true, + common.HexToHash("0xa4080fc79ac8bfcf24bf21a540bec97d119a4a9f42c1054af95ff5cd20f3fbed"): true, + common.HexToHash("0x3a21d2a077107f470ac0d4010edc7c2614dc944839301e5b7b7b752b024db139"): true, + common.HexToHash("0x76012afbabc681c37075f606397f08796db005414e984b5c9f39cf2de7b81186"): true, + common.HexToHash("0xac525927f3bd6b25cef92636e84681adc67f7bf5fa0d309c446dbe9c47964ee9"): true, + common.HexToHash("0x2b8b27efa56750039adc723d9487f1d467b08860b3774fcbd0e7be53fe7a901e"): true, + common.HexToHash("0xc656f18e6aa177839dd8a9fe76059198ee0723fbbbb8239382f6c0693e620ba6"): true, + common.HexToHash("0x484e95537f0b84a4ab9ebf93c3f03aa4425ba5542b83cfb8687d3dc375d2fbc8"): true, + common.HexToHash("0x583e6ae584d90af03815ce362c7c93339eb525ac2e9764541f45a0b80bc5cf30"): true, + common.HexToHash("0xea8830ad0665518bab243cd0c17b5a0311fdd3a31113812b5abf9bca2394c104"): true, + common.HexToHash("0x62aecc5b34331f817c59715cf41d88e9d4f17c41757da2c53262448bc50c57e6"): true, + common.HexToHash("0xdf9bbf6f7cdb85f6b95f17da43830074036cddbb6402c69752193dd8ca3e7eb2"): true, + common.HexToHash("0x5f62c81093e0be62bfc7ed30accac2f16379d5db978f67346735aa7e1446d256"): true, + common.HexToHash("0xe1226f32016b0be70aa338622680bb7e2357938999cb4fffe8a57e0fa3e87fd8"): true, + common.HexToHash("0xb38970494ae07e577601229adc3520d7dea2a050094607e2932d2b7bb005e119"): true, + common.HexToHash("0x5254c48e10d99bf188340d126abd14899e2a90c96dd803faf0b529d92f47cd66"): true, + common.HexToHash("0x861c7f12a4ad39353e8ee086fb58a70544f4da286adaa8285b42a3f392a7ba28"): true, + common.HexToHash("0x03fa226ef65ef2e3604959cf3e2dc035b26e1e9cfd0a31053ca2601b03f7dbe5"): true, + common.HexToHash("0xbf767e90c46809a02c00db0e5b09d8712a194ce1f78c80a86822666d8f18a99f"): true, + common.HexToHash("0x0400daa2ff8820f2191bdc5de00a34248815e1375d4367934d7ec33fe5f2e53d"): true, + common.HexToHash("0x1effa7c0ccef56f2aef3d0feb1f5e61dc66b548e65c3fc4b20ea77bba7385d48"): true, + common.HexToHash("0x9b6af0ea3cc176ec02dd01a61286f6f31e5186708b63a4c42b02ea9117f007c4"): true, + common.HexToHash("0xe56e69f270920e6cc4bc93d5f00762b64c0ec3e172c5b1485df48426cf5f7ca6"): true, + common.HexToHash("0xa22d0bd506a530a624134b472473ed9f56e0616fc9949d6feb202fd92e487480"): true, + common.HexToHash("0xf351524815093c3fad60862e0f0678428a1d0c76c812e142959ed7466b555659"): true, + common.HexToHash("0x45573f5ce1156dd59a732af37d27635488d659092ba749a5bc5b84540d1ad5c6"): true, + common.HexToHash("0xc73d59e3848c6678c4b46ba172cfd8b2354be2e2829815c979712c5bcf9a2aeb"): true, + common.HexToHash("0xad7fbc483f0540a25d2fff1d064dbc9c62056c4c4d5853a26243376a747c8ff2"): true, + common.HexToHash("0x61c64343e89c0a3e50fd6391295bca7792116d1070dbadbbd93b093ea9f4a00d"): true, + common.HexToHash("0xb03d00b19439850ab8c547d0b550a5a1723d2bddd34d6315d5d0f14123e52888"): true, + common.HexToHash("0x42ef0e41aa24ed58ce276f4070a5802ce0a405f326c9969d5c066a3258341b7d"): true, + common.HexToHash("0x81d18facd34a9b6b05fee4ee69fa4f377618ab44c5fa84d09cb607dce7bf65e3"): true, + common.HexToHash("0xcee8618e6ecb9e39e189379f3bf6f1835121e65534b863c7cf4d2391c8e770ed"): true, + common.HexToHash("0x4f21f04f19db0f90deb537533a0c12b1e47cc928d23e5ecfe801847d1fbb15dd"): true, + common.HexToHash("0xb43fffaa6837faa5dfc87488c49a592345d520ae420575653e39fea740d15f15"): true, + common.HexToHash("0x2e74486b43248b673a0c87eb443c475759be8b70327b41e83a121c722d25d995"): true, + common.HexToHash("0x579c3672396600c5a3a2dc0878d3d6b0587dcfd8abcdc2f7bdf9ff9ba887e545"): true, + common.HexToHash("0xc23fbc331122a09e89ffa7e0a0461a91ad5edd6223fcfdba3fd24e624688a28d"): true, + common.HexToHash("0x28637d527629b0f9a9dd3fab962a9fd2d347e2687579004153512742e47c19dd"): true, + common.HexToHash("0xd456a8e3546c5d1ff2cd715aaacc44c74eaf740ee5086bbce74194ec92fd52fd"): true, + common.HexToHash("0x34b84ab8b4ff32a78807e0e6a9c77f092b25c801aa8eed3798c38e5fc6db66ff"): true, + common.HexToHash("0x84c867f6ea8f138fb0d7e3025a375a397f446b0fb3b91754cbe4ff311d0564bb"): true, + common.HexToHash("0x33f8323ba69a4eca9d6dde083486fdd37cf19180fbda0bee843c54c903510c9b"): true, + common.HexToHash("0x6d59ce565d40fbd7dbd8db3a4332f9bbb266f370b89d6d0b749bb2d47222fc4f"): true, + common.HexToHash("0x44e4ee931a96270d522dd2da09e93ef92132efc65e52ce4883c23c0a1e339c4e"): true, + common.HexToHash("0x64a75c636d624e9e56f15beb7a50ab55648d0f0a3258c1c34bdd4226ef168292"): true, + common.HexToHash("0x8a2d7c3468c8b8363eb4aca764e12ecdb0e8f84bed5ba5ad3d242b929f7caa9b"): true, + common.HexToHash("0xaf17eb247fe260a2aa3a03a9d99167f7ecfecd6a4be73cc0708a7b32e3e31024"): true, + common.HexToHash("0x5e3ed931e77f735d2491ec26ea1053e9c0e0d07dcba5507174da927155ff8af5"): true, + common.HexToHash("0xd482587cd677552b00bd7a366ff427cd82455eae431521ec646e070d4f40b9ae"): true, + common.HexToHash("0xb98d6ab37028d126d28b1db37b6efbc85480d4e2ce932802867a981c0dfab9fc"): true, + common.HexToHash("0x52f327e4cc48f67df38777820a71ee0bfd1d9dc208b15a86b3f83cfafa750eed"): true, + common.HexToHash("0x2fd9c3eb7c7f661c4b2c606d3bf19c521355512a9fd0196d466f19b72bd97731"): true, + common.HexToHash("0x6f0cc5fc0ce7b519f30770f26e2ddc74c22a06fe7b47e6ebe6bd991cde25096d"): true, + common.HexToHash("0x91f8f3c39ecdd2e5382d0d3248b91b42919a0e81a9e75aaeb5c68a42417fbe0d"): true, + common.HexToHash("0x5435bba9d1d359d1a0d9564c8b7b06582f16f5b0c0e0b5fe2d1be7b43a1180bb"): true, + common.HexToHash("0xa94658325f1e107fb9c743b159ff14542cb39582a8ac0eff0d5f2dde5e607cee"): true, + common.HexToHash("0xfabd51475efdaaaae5b49ee0fe0c16e20a8795d456206b270e0dd2fed4a33023"): true, + common.HexToHash("0xb11d4f73812f6439cdaf0945f979b04fce6969225e299e98aba63fbfe03f0f5c"): true, + common.HexToHash("0x99e3937e65d6ad5e24020fbee502629c44c3e71b8f29736495426d6fdbf22bbe"): true, + common.HexToHash("0x7cab00e0417b2d1d96512f9aec0fb3ec7babf6e0d7354213d8e9be582d7f1358"): true, + common.HexToHash("0x29e60e6239f4b39d0b6dfd386309582c4faa5b48bf2aa240954938fea1409c4b"): true, + common.HexToHash("0x58fb695c3ae06fdf161290b447b7724b754c0fca1258673086279327a8675f67"): true, + common.HexToHash("0x91bbccb7a8337ed6c0c27515b8e4c38318d25b3e2bef55afebbd37fe50c0e45b"): true, + common.HexToHash("0x4c347788306f85cff4c6d6530c9c632e1047a967c1855fe0d0812b4978ab9f96"): true, + common.HexToHash("0x5f785193fe03e9b6b8ffd470335ea6854a2c1325a517a52ce57bbdc3490a0ed1"): true, + common.HexToHash("0x3387ba8e98d2c28752f439f1d90b71b2302e268b9964982704b2a7826d74981d"): true, + common.HexToHash("0x253d4815b58943cd438553f708829a49b454decc787b73590a634a1aff2b4950"): true, + common.HexToHash("0x3c3d05cf119c4252f280e57815de2f649113927416cee0a350a91e33c92bb577"): true, + common.HexToHash("0x7969b36cfc185ef305206dee7f450a50220d9f5b3194f4ea493b9b266848664c"): true, + common.HexToHash("0xdeffa2d21ff96477ccc0f3957227730f86df81f9fa838023151bab40d040faab"): true, + common.HexToHash("0x997918520dfbf126e69cfffd26b89c84217c607f393392d258c014060c52f46a"): true, + common.HexToHash("0x3f54c687eb9517d4e7e831de2aa9d8d6b808b7b64f69498eb5205da717645452"): true, + common.HexToHash("0x5db55793e7a5fd334fc364b3aadf4aff28520e03aa41c1f84c498a2a4ba19390"): true, + common.HexToHash("0xfb2f455a73b5a65aa8bce881730dd79e43e9ac95cfc586a58a2dfa33f1bbce0c"): true, + common.HexToHash("0xec364991112d47227e2a1d47bbc4d3ac36ee397517e6e7e7ab4b289636047283"): true, + common.HexToHash("0x06aad3ddd9b93e456f7b066522580aed44f22d351d415c08a0514631ad34ef74"): true, + common.HexToHash("0x37b4b33060b1dbf703defc079ca1fc22795f9c865019be0a40b3e978409d0902"): true, + common.HexToHash("0x718db9b97a30c5cda22fe4a2767808a373a861f748c0bae93b18da45112f5e8e"): true, + common.HexToHash("0x8626f838bbb31932106b801972a4b71f14487f9b28cf653e16f1e66fe2464051"): true, + common.HexToHash("0x2114a824278b545fc703797b4cada217427082e34e10c21b551803aa17288306"): true, + common.HexToHash("0xb885205ab9176081272dc57fb25ad132f1c39c3c67fe34572ba38f24a4eed077"): true, + common.HexToHash("0xfc05937a2d2f137ac8323a7a85c3f8f176e1543d49b96c5d2d0917a784ecb084"): true, + common.HexToHash("0x7117cd4e2fd3eb954cc037dc7b49605dfcf16f4dbba483d76b854964eab16d94"): true, + common.HexToHash("0x472e30274f2964943ea4eaf82d0ac59c8c0abff31de7c171a74d6f1bdeaef79a"): true, + common.HexToHash("0xdc5c7067c5ab194a4d64d9acae190f22701f6582787bb7c39158b53815711828"): true, + common.HexToHash("0x641eef73c279d23e5946c30e62b2531c1fa9f2dcd06397f4d2e5e4b24cfb59ef"): true, + common.HexToHash("0x6e7f7f290201bdb2de052e51462b462e88eab95ce5b155b5a4958d1bf4837bab"): true, + common.HexToHash("0x0d8bf04eec2ef95a65d5e06b653571d1ee6e1875fc1a1e02d98560e4ec576363"): true, + common.HexToHash("0x56ba02c77504b7b5fc68b089b0fb0140b67c452679b7ab45b1860dc84b44ec99"): true, + common.HexToHash("0x4fdd33252d847c5bd98824c49d47d31cf756d3c9df3b55b28a20c335a624e63b"): true, + common.HexToHash("0x85ee0d444573259a4973f434fb8ef446f3508e8e1e207581b3c044d563ad97f2"): true, + common.HexToHash("0x3dd7224900ec1c83ebf6926e7690a50cabf1472fd5a722ddfba6a47b4a5b386d"): true, + common.HexToHash("0x3f339bf5b30e78166bdd67280d474d5fe44f85f63d4efdbbaae02d53e914f6aa"): true, + common.HexToHash("0xb10160890f18052535e74b2e4733aba35cbdb3119c7053c0307dc70175bb2ef0"): true, + common.HexToHash("0xa3802117bccbd0b2077d65d1d500063fe8a28303da05ee93da996e36cc762b0b"): true, + common.HexToHash("0xcf2592e21627f1625409e23fcbb9697411e4f5f7696b8982e18d4baec09cbc74"): true, + common.HexToHash("0x996ff04213e96f65173c918cd463c5e405503e15482f79519ee0ee31cf40f53b"): true, + common.HexToHash("0x78df2a781181cdf77d68fea9b3788b0202bfe8fa066c7fe5c5a714d5444708dc"): true, + common.HexToHash("0x5b393f00f94476bda4e261c4b984ffb8fa04df99c70c8c75f39391f40c01ffc9"): true, + common.HexToHash("0x484278c6b020cacf8dfdec4796b5cfbfe41a20e8a5c9493c77f6c20b4ebe891d"): true, + common.HexToHash("0xd700bc7a549467ccb38bf7254fff688dd30a30f693b1ab1e2b772d858efc9da7"): true, + common.HexToHash("0x75936fb8224977d399ab7e99e589cc42c518e599428371be1b264cb5d3de11ad"): true, + common.HexToHash("0xcb6e0955e92b730fa21dc75281cf4a400c97508da7af08b491705d8747195e83"): true, + common.HexToHash("0xd54cb1b5cc52bfbce92c03cc7c5c2c53055808898c2f48ab2dbd3100def32883"): true, + common.HexToHash("0x31dfa72356f53ea7cbc8df1bd122e1dfdc8e091bd0ad101841af7623bb7541af"): true, + common.HexToHash("0xdddffb1758c88709f564bcc7c0d95ffe5b0a646e2beca6b6fd6f33887113cb8b"): true, + common.HexToHash("0xecaf3a9a4c2a0c19a6b2fcb8c339168c64959c8c60fb9160b0c9c90da6e7a54f"): true, + common.HexToHash("0x85f4044b5ba4ef8326e7be2ad559b91f5490f05855265954fbf28cc1403200e1"): true, + common.HexToHash("0x812fdadd7df1817477b886c355efa7080e5071aec943e1d0c2f96380d61a9514"): true, + common.HexToHash("0x583de89859e177bba09bf6549ff1894ee6e0d883134fee4da02d33247c10799b"): true, + common.HexToHash("0x2d7e377e5ad05a39046d2cdef3e639eb9b3f03cc9f2614e5dfcf0a79614f37a4"): true, + common.HexToHash("0x7c8935cea73fb305bd94d333e725dd6b7448ffb214b8a10982ca0049f2f3692c"): true, + common.HexToHash("0x4ef4699068755efb6e89d66e5f0db3370c22dacb505612d46e6e89e5a7711f6b"): true, + common.HexToHash("0x4d46ef23760ed76e195a25882a17369432a013b058bb8186585ad2c5cbcf0158"): true, + common.HexToHash("0xa13c895cb1cfca9df4a95532e9bbb305b47e938b43a8a17f474c7334071958c0"): true, + common.HexToHash("0x387988ae7206523689c2698bd071bbbb1dc2ac36e13c63543767e10f647a0524"): true, + common.HexToHash("0xa0f9abc9f5d8f44d0a75ece4e191e9cd931667adbb1b4fd4a47670b31c3ea186"): true, + common.HexToHash("0x798726c2e362dbc44f5b0a00322f87832b4a071a3607de6405c184036affbb8f"): true, + common.HexToHash("0xaeca6d5eec11e616a952b6bf18807d5109950488dfe9d1f8b1a81935d1a830ef"): true, + common.HexToHash("0x9b800a770a1eae5d3d729152555ad135eb621fc65c8a87568d848e0eba315d4c"): true, + common.HexToHash("0xd849901cac304a55cdadbd318f21a4e2789a54da7e18ffd495f74b1bb8f1cedd"): true, + common.HexToHash("0xbc759f89ca9a4e1058f608aa3a280011539feb438e371152b3887264a42f72a7"): true, + common.HexToHash("0x8c687a5b9de903d8b8daa4790c3baa431d92a3a832b7786c191d9a839a24d1a1"): true, + common.HexToHash("0x8d6d58666f5b303c10b8a8db30b192340d27025d90018aec9a8eae675a0ca47d"): true, + common.HexToHash("0xe302470d4045256489d498fa9e46247d52bcfee6823d99ad8dbd7b0b697fd334"): true, + common.HexToHash("0xf2c4b9c6f42e21aaeb88172904d0bc99329bc1487bb3ba1e99578bd101e6ac5f"): true, + common.HexToHash("0x7e58b8a09d3c799e54ba9d5cfc9cbc3bb05b40c6f843d5d0c41fd49ffee0305e"): true, + common.HexToHash("0x855f38969eddc363d6bc5df543df7c2935640bb9204ef70004e06f8975c768bd"): true, + common.HexToHash("0xb0d30a2db77c1c7220f094f80e7a81b1e706c4de58a7d08464c0ad106c3729a9"): true, + common.HexToHash("0x9c20e24e07b4b36aaf1045e6f714908be686beac93410c4536d16d64ee5c8f39"): true, + common.HexToHash("0xe1bfb7a902ab990c612f5ca8a1ed679361193627620ca5a47f701c0763a32963"): true, + common.HexToHash("0xfad6da7c94a27c3121e16baf26b031aa4b826648c014ab8b0fd573f6163d258b"): true, + common.HexToHash("0xda48ca192faca0a2beaea14d389fdbbfd555f02d4fd7156284212ad578e723c8"): true, + common.HexToHash("0xb25667393cc7e32b42f6d79fa0d8ebf0ba75a5d34911cc75f3af7ba34079ed08"): true, + common.HexToHash("0x875b3fe393a16b642b5d81e664f7402cd46a1faf0ab22330d18dc244ee6751b3"): true, + common.HexToHash("0xa526c94cbcf4617e3e0ed678aa98342763ec63b69e6ad83eef2ef43137a4e6da"): true, + common.HexToHash("0x52d2b3ea1411623c16aa4fc082b4c61aecbd918d49a08f71abdfa1f20bb58251"): true, + common.HexToHash("0x265ce7118a2b27d96f5121ab12ace2cba3e71d050e244a339ea90c323e2ff23c"): true, + common.HexToHash("0xc5b98117ac5eee875263913409e74f3cb69b13aa1313c3e0bb425edfd7cc5401"): true, + common.HexToHash("0x04bd5d1c033a1f8b0bbcd0f226154de16cead3ba1c66eba13f78314fc8537e20"): true, + common.HexToHash("0x3c5b8b440e24a10daf09c706458d1be8dca7d519388630b54529c27264f092be"): true, + common.HexToHash("0x9a5565c3b19d398fe3ad1f6b9b394a5bfa8e0fb85678812debf9b5b2353f2bde"): true, + common.HexToHash("0x359c018d9f3ed1e7b539cdea48a278fcc5b3a45d5b8f747f992fae13f5e7a0c8"): true, + common.HexToHash("0xde136f4b9b87588ec07f779e6ca1f0ef6f2ac9e6c1951cc9e1529ff8bc7707b7"): true, + common.HexToHash("0xadd6b33daa2acffb92656a680733f9c17111afcaf3dee596f9a554a2dabc087c"): true, + common.HexToHash("0xb2b2b929deb837286328113f74e6402d122b634a4c6ec4cb266d62b8011c6f4c"): true, + common.HexToHash("0x932b555fc6a125318b5706706cf3d14a29996ed7e67dd1fa52d64a5de3d3098a"): true, + common.HexToHash("0x4314c1c32d1ff52faeb4a95ab1366e710212197a69ee1a22606fd51cea040b0e"): true, + common.HexToHash("0x12c21adedce209c13b5a5bc3075ed774bfba341538dee2d6b045b0db11d9d3c6"): true, + common.HexToHash("0x2efab1e44c0fb64db029376f6252c3a9bb11e2bfa9c7c534767f3ad740b69bc4"): true, + common.HexToHash("0x137ca702d10effd8ffbaa43f864b5c27eeb362a88b3a77333c323db8e04eb74b"): true, + common.HexToHash("0xaae6604d43405d7663cd182540e35a925308195dbf480408169a954bcde91d72"): true, + common.HexToHash("0xc2d9dbf1f52a8da25357bed8ba89a95832916b8187fea3c8d5241d632226f9b6"): true, + common.HexToHash("0x418af742372d2916d447b6e3433281e269700a6bc6a4a1448ffa1e61e51c45d3"): true, + common.HexToHash("0x9ac66ab8f6b1fea74710a992101423bc84ef3e5d18fdd661a5cec57a131803de"): true, + common.HexToHash("0xb442db66977d3b0564174a54d893d406f90da0bfa283c64d970fb7df0731ed76"): true, + common.HexToHash("0x53b9155b32968438062ed4e40f22c06d33067f8b8a3516f811de2b9a6ac12616"): true, + common.HexToHash("0x67d85994762b712b2d06543ab7531ea39c47f318245eb297e85f5c11420c0a58"): true, + common.HexToHash("0xb0e83651e11cd13ea4df8a77aa795eb05027ce3a31448f3b685b9ae617273d47"): true, + common.HexToHash("0xf699d0b72db0f5a522b0408fa5f9dcedea62b7630d911bc31530219f37f71e4b"): true, + common.HexToHash("0x4e62e2ee3324d45cedba71fb576d51b9b82068dc1a8da2c53ef0250b5715430b"): true, + common.HexToHash("0xf787ba279d80be3756985ade19d7d4c748ab1ecba80ba5ecd6edf4ca27a03cf8"): true, + common.HexToHash("0x86b1ac482630c0ca4ed57976159de4cbec85933e707815c242af3efa122e13dc"): true, + common.HexToHash("0x780366002ec83c29c64841c753986ef67cd234e8359ad1c5113dd82aaa517aa7"): true, + common.HexToHash("0x550ea23779ae60a19f390548b67ba126b882402ea88835b53140af4c29d502b0"): true, + common.HexToHash("0x3dce8491854a074d2715f7f8faba6f5e39d3af6ba273e4bd2d049280bb0056fe"): true, + common.HexToHash("0x6558445725bd0ce92ae73a1069f836a65170291e66cdb14167bfef67fab5a167"): true, + common.HexToHash("0xf17ee2106f527eae01d3588498837f6b1ee8a65bfa267fec157efc52c4ad9e7b"): true, + common.HexToHash("0x0e08cabc9c61ff8f3be128f306c08c68b13fe72e47dd19d8063709dbff663e82"): true, + common.HexToHash("0x8154e996474e93910f09f0a0aa59ec5ef08c5eb7befab447d07d5ce8b54ccc92"): true, + common.HexToHash("0x01bdcdf5d5e087e9143b1d6b3729b81017ccb84a52e1011a6dcfc592bf72fa15"): true, + common.HexToHash("0x17d2a04b2da79177883527dd25c4a4d701af8320dd9cf54597a268e5048bdd3c"): true, + common.HexToHash("0x805888adb44790a8dcdcdd89b054269285def112e60cc9037b4684c6b3a00c47"): true, + common.HexToHash("0x4371a4b1300d7c68b5085239e9451bd10cc5500bd7aaeb94a007ca5c4952bcc7"): true, + common.HexToHash("0x92fa1211e003a7e7ad98408c49f1348ab6e12d308665ee3b28d2494d21ab584d"): true, + common.HexToHash("0xaf9b41e92fd5ba32f5d6031a080379cfc35e5f016ed98015e211efb1984c3058"): true, + common.HexToHash("0xbcccb632f392adae43095e30ed2c17fd99ccb53198c122e9471029f35f305f9d"): true, + common.HexToHash("0xd27822f4c866ac5b3bba2d30d1cf73149d9de4922670f4417cc46a2a02c08c6e"): true, + common.HexToHash("0xabb0ba038b57cb91411bc40cd9e1498b4bd6f36bcfe94fa35d6d52b63a561317"): true, + common.HexToHash("0xb80070505574b0b77d87332a0a8ab3c637928493023a2ad3b4b1c39d4d04e599"): true, + common.HexToHash("0x7a804a45f83cbd4a0093695b58083669aab2bee150d3b1c664609f989175cfe7"): true, + common.HexToHash("0xe15346e6fa2c1d40aaec0ed758f5b12313e707c59158fd96fd282d87aaff5b1a"): true, + common.HexToHash("0x8c49f52e99ac9d8a7f0a349a5acec4ccfdb7b88f3ab794d9f535b4364d912220"): true, + common.HexToHash("0x993c1030e5be7de5d22162e587700c61cd29b2dd75116347f422a4d99a41b091"): true, + common.HexToHash("0xcb08804badbd8df592d3e40031da4078ba667ca912d4e1c92c4c8a6682e32385"): true, + common.HexToHash("0xec424301fbc70eb10a49f3b618a988f73f3a9999da008ff03fb769e4ccc749a4"): true, + common.HexToHash("0x1312a431afbaabb8bd7fc5fbb8bef90646291e5c5788fe3ebe79ca4fcfd25dc7"): true, + common.HexToHash("0xf43f9d53d6c5de209fe08af62ebdc64e8c0700e9c8859710a66ec6b741b1df4f"): true, + common.HexToHash("0xc2c2f2a40e53c6ec53a0892b10d4ed48d2650cf6f998aa4305369e8ba7a1a2b6"): true, + common.HexToHash("0x4628e2f32050240ef86fae0093f09bd83dc112e947229efa159fc0be23c5f06a"): true, + common.HexToHash("0x225e3d44e6ea78d600c36261fa1ec2ab845d4a221783172a5f6f7531af2fb501"): true, + common.HexToHash("0x981a1cd7bf86c72dd4f0dec044e242104711faeae41c182be70ae9d9e27ef865"): true, + common.HexToHash("0x75ca5b37a1a1016bc73915fbe04675aa777a8b1a477190d0764822cb168bd622"): true, + common.HexToHash("0x3d602766875c0f000f951003f7a6d4884bd87056741aeb1b0b68d7cc217012d0"): true, + common.HexToHash("0x609e1b9d9a7b7ef8cf0e6c760e423d1eb48591591b1c72e8c7e1664e325b1927"): true, + common.HexToHash("0xe0b76e56630c5863ca66c11f910627a8779ff89294396645f95c0eecaaba79d0"): true, + common.HexToHash("0x3b077cd652dd887638e9b8ad1c9466a1f99fde63b88f986297b16ee235633665"): true, + common.HexToHash("0x788e87e56e7453b5709ad885f4eaa50578f3c5efb14ca2d26e090919a4007cb2"): true, + common.HexToHash("0xb73f0d7a23ba1ef137913a72d097c6d0f9801660fa41595b718bb2ebb46010d0"): true, + common.HexToHash("0x7133463cd3f384a8238413361ca66e4c2bc8bea43cdf55462a41240497f0b4ba"): true, + common.HexToHash("0x33703c48c3fe565b759914c408dba695219827c37367c9cec456280240bceb68"): true, + common.HexToHash("0x8f644440bb09bfb0c922c8088463cb3cc2bf2c2386336e440e91a10b22a3bf96"): true, + common.HexToHash("0xa711b4b800d2b602abbae53e3c546f3abbf8b643b9c925ee49a55781e9c6665a"): true, + common.HexToHash("0xde12f552fa393a4808929c238f8343b03bbbbc170df9fe65898b55a71cf40542"): true, + common.HexToHash("0xcc997b0f5d7d80c8fdd66d061b56640b43d8837380b69e3a9c7984993c96aaea"): true, + common.HexToHash("0x5dc997d0767d26710489c5b0b9fe7ba89277fa80a5159dd304d0cbd22da23534"): true, + common.HexToHash("0xa9b110368a6052c04b8b429eb2583ffd4f1225db02268bd721a988a771cbf828"): true, + common.HexToHash("0x9400f0960b7dbbc0ef0cc2a9db4e8b1f2344d38b116ded1d59da11021d365cf5"): true, + common.HexToHash("0x1de212913d6a04a07264575ec4a549064b4655048dcc128da74e5f3a2831ed87"): true, + common.HexToHash("0xfd2eedc401efaa73614b8ef7919dcbaa9c5c5528cf865f00216bd551c7c37399"): true, + common.HexToHash("0xa7d47effb340f88da8e4aad8d3fdbaaa94395fbf2924a948627af790d44ca68b"): true, + common.HexToHash("0xaf9fa8870bbdd1d7256895c77fa48b7cc0cda9f9acce2bd8c885feabc26d845d"): true, + common.HexToHash("0xafb790ce67678de09e862a397c44968462ec71eaecdaa60507b85b72a8185366"): true, + common.HexToHash("0xde810c0ae8640a33662a61a065dfc5d09324ac303e82188f18f832af409bb1a0"): true, + common.HexToHash("0x6cac32d5bd46bea1947da0e083b34df2e399dc8020570fd753562b93973c4f53"): true, + common.HexToHash("0x336fd29101a80b0ab1c1acaec7915280f2077a6d01f5ee733047cc26378f1d9e"): true, + common.HexToHash("0xa2a957586e17c4270359d052016eaaa16cb502d5b8be5313ba3e9897406a9fff"): true, + common.HexToHash("0x50ef3c613040e75c8308ee71babcfb3357a701a33c7fc12e69077fd0988769d6"): true, + common.HexToHash("0xd827fd0964908d9f22b502a25f56c72e232cc1afa4dc24ef8763cc0e743d9a16"): true, + common.HexToHash("0xe95f2cc79f03165faa4f689e5fac8a90a1529646459d4df0f4876b40c8621240"): true, + common.HexToHash("0xb16f500a65cfc1f59f58028319ed7b8c3cb6111cf7637e4429bdbcc9b2e470fd"): true, + common.HexToHash("0x0d4fc1bfa7ee5ddb45337a947f3a2300a96e4e2cbfe6f6f7dec1eadce929c1da"): true, + common.HexToHash("0xa27e2b1d2a88f5b7354a1b8ff1a55a7099449a3b97cd3c955f5bd640feb2b9c7"): true, + common.HexToHash("0xb008cd27b4c447318084a658cd7e08ba60d2388d8c3c36f2d1f3f36a9fde5621"): true, + common.HexToHash("0xaa10e17298d63ba4d35b3c6a9e3fed7c1a71b5e30049cc640b78d756144da1bf"): true, + common.HexToHash("0x93b1d2967ce69d8bdcd038df2a5837b3fe3e198a3f2e8d0138f3cd425c135ee1"): true, + common.HexToHash("0xc40ff663f9814581a4dc6fa87ced19f649db3eb9920669964814422c8d955ea7"): true, + common.HexToHash("0x88c993532b8ed99b462d1d8d89717ed0b7f8836d0e9f7615c3ec2f88644b336a"): true, + common.HexToHash("0x17207e874c61c4708fdbdc6063aca3d6e68534dfdf6ca0265c41cd2e1d21ad6a"): true, + common.HexToHash("0x51273de9b8f190452010e71003348241a9d136defe8db4b082a7af5f281b9f64"): true, + common.HexToHash("0x39a3279819ecf6b0baa858bca82379dfa8c797321f6bb2fc026291fd18de3acb"): true, + common.HexToHash("0x564cd54e54a5ea8c9bc63024f1da2f60bc4c5603ed9da6d69251c1b358f5a7e2"): true, + common.HexToHash("0xa64e4870c539859674b5e628ce31edc0c9f28d250eb0eba5b5dc8c1587bd292d"): true, + common.HexToHash("0x7a6e8c5f34cd54745dd759910a590808604f410cd5f07b209a22abd0c6850a6e"): true, + common.HexToHash("0x494e45de5f2fd519813aa76f690e234e1eab27e4657278930af8ba2f37761679"): true, + common.HexToHash("0xa508292da14311d1756be7d27fda6f880edca40f30baa805ec1599711baab9a0"): true, + common.HexToHash("0x8a2eeb423480120d7fd36e7963f7cc2a2d1da1b5262c1227c776cc47c318b553"): true, + common.HexToHash("0x35950f2f6f9c5320f46bbc428b85a2c12b0712038ebdfc7318acd6dead4b7dae"): true, + common.HexToHash("0xb574272734a269c39cfbcecd293fbbb80a33e1974230204333c351c34728c6cc"): true, + common.HexToHash("0xf5dd250306bd9b47cb513a15187e5dd21760fe35b46b041e6427e14f83b81719"): true, + common.HexToHash("0x67d33d1e992a35d0f536d74070b26cfeb0b633a38e86c42bb2b16aaf27023754"): true, + common.HexToHash("0x89d4761e918d71df80105d364e1e8ee48729dd863a5851175be8f0de2bb7b8a0"): true, + common.HexToHash("0x956028f3b193952421b0fb32a1e0b1658a0080b990ab6856668d3b4978c83dbc"): true, + common.HexToHash("0x1fe6b1958915082849ae1363045c7c6806ccda2ab7dd8861a1ea4e9f89a48cbe"): true, + common.HexToHash("0x3df71b7de73a11ba9437173fe67e2625039a77be86f2d4d880f9ec3055b9313a"): true, + common.HexToHash("0xdbceb909fa21bc802a7870e0b1ece3c67ab7bae4ba760f4d6438531f6b51aea5"): true, + common.HexToHash("0xc43568e5ba1b12d33fdedc133894e8fbb655d215866d821fd0825e9a3cfb18a1"): true, + common.HexToHash("0x9f522e4f1d80506f549e9a9510f986a18621d7df7ce35fad5da9b7652630fd6b"): true, + common.HexToHash("0x90d9ca7916e0a96ca59afd31f5abf79802daa943bb5836cb64b16fafc001c946"): true, + common.HexToHash("0xac54a1e6ea578f673594d589c3772fe2e787314aa2a38dafc95bc9ac722aded3"): true, + common.HexToHash("0x730f60f864eb5fc7d95224a42b6043a8f3aad83d8afe28260e4be85cd0f9697a"): true, + common.HexToHash("0xf73ca6122b49fe52c64e8477648874fcf9ad209da95d6e8d02cafe1e832ff6c5"): true, + common.HexToHash("0xb940f9b7c62de81195f82fe6de8bd4c8a3f5a5ec3c482a26f00d4f3a27727656"): true, + common.HexToHash("0x4bed1fb76b369da8ba9c8fd0cee800b456f6663f08f2c6d458332a2ee9888da7"): true, + common.HexToHash("0xa52fa7413f3ca1aa7212032d8b9cb84ae2543e8a17c11899ae5c4c709cf4c570"): true, + common.HexToHash("0xc8ec096615fd073e9bdd0a57899e30daa2e8b3f99e0c23626da3cdb21788eeba"): true, + common.HexToHash("0xc278c39a2ab6b9d76627dcffa46c7b46b26eebded322c0f119de0e959de21156"): true, + common.HexToHash("0xcecd205167a6805925b2f5fad84d282a8ad981162d0fb8e21621b1f9ccf3dbd9"): true, + common.HexToHash("0x176aa6799a6640b3e9280570342fb5263019e8b5f88386e1051630dfaedfeb4f"): true, + common.HexToHash("0x3ab844cb0d91ba427c758576140a858ab921325bdb81144f40692fb0f92254f3"): true, + common.HexToHash("0x9af57d120b37df882a1208570d0dfcdb8d3b60056492251fad3dfbe94674c747"): true, + common.HexToHash("0x4fb7490fd36af7baf0a9250257ebe18a5702e7fff2f1c3bd6d6b2e54e381cafc"): true, + common.HexToHash("0x3c91b7dfcd085795ebe6fcd9ecce7e0ff2ae30a765cea58add21d6e350bdd9ec"): true, + common.HexToHash("0x6eab8f2803966b795636e76ec9a624201e96ca95b51a601dfd574e75e984de89"): true, + common.HexToHash("0x3b2b420978ed8134aac1baabd6c0122efaa87c33dc504e7ceba5c5d252c238ba"): true, + common.HexToHash("0xef66a97c0a640a2a75af35ba5797d5cc313f8b6f0b4d029fe41ec215c3b02bad"): true, + common.HexToHash("0xdfe318a3cc94737eeb60f1f5cda3bc7d69552f255d7570cb6fedd5643bf1b390"): true, + common.HexToHash("0x8cb2faa3071068c280b7e14371fdd733843d6067270424e031d187bb5e380c6b"): true, + common.HexToHash("0x74ea7082e28b195b0ee3f7b7fc2ee07b77accd179df3300245ab4d89aa953f71"): true, + common.HexToHash("0x34e8f3deff0bc344a9491b45856f2a0bdabadc9ea53c3ee2115691c12419ba5c"): true, + common.HexToHash("0xf7a4bdec0186a7564fa95b9d934bbee542b7f993cfef8d690dc05566ea078b28"): true, + common.HexToHash("0x69b8b04a7523926b4e31532f68f1c738e4133577a80d48e4bd1f05ea810ec07e"): true, + common.HexToHash("0x996335c76551274ed7335b428642e596a0c1a59a9ee189035d2f7d5664456e8a"): true, + common.HexToHash("0x729cde297672d3fc4145bef05c8c7707ca322e98d5158e87f4240af1dc815493"): true, + common.HexToHash("0xbde41f6ab11a9fd10ca0a87ba494a203675899c178f679b575a42dbf1ec726cd"): true, + common.HexToHash("0x9e6ae8cdd1628efc7b17ead5cd4901d54ffc946d651da6cbee84eaa6a872c08a"): true, + common.HexToHash("0xb868b54ed8d38840c49eee055d3659f7ce534108883b903255a49c3834738150"): true, + common.HexToHash("0xa1ce05cd3dbe972c321e3a1de1533b75134ecd40ffd69201320fbf31c2712c94"): true, + common.HexToHash("0xc35b2a206cf5d13c85fb1ea35e0627543981a89a6aa432b0043fe25ca9d566b0"): true, + common.HexToHash("0x9950664a7d8d2e4b5d772722e1337ea9758cac77fed61cfc37bea54deb79cb89"): true, + common.HexToHash("0xe98b23684a2947393c5b4f0e47cabe4ec764e31ee5d6bbee2130cae1105e68bd"): true, + common.HexToHash("0xee4e673b99c705127ac712d6cc6a24017b6c57b4ce5ffdb52044dd5e476ce808"): true, + common.HexToHash("0x3d4deb69769b0550120e3663c9a6dbbdccc4b0ba4b6c73f1dc4ba2768a44ceed"): true, + common.HexToHash("0x6f8f3157368b6b301632cde269e8d426659385b0385d2c028316d7da87380f64"): true, + common.HexToHash("0x0ed37d143edfdfaec8b926bb3451147268ad9179ce9fb069b9118ed4afd79c2a"): true, + common.HexToHash("0x37e8340d3d080143836fb81339bb62deea555a60236bfaefc3a2a0911b861ebc"): true, + common.HexToHash("0xee45ffdabe94f547ab6d28b0817d66e494e5b79942286896cc71881bc19f8db4"): true, + common.HexToHash("0x3355d8c3116a27c645670c449ec515243adb0356cf39571bb6d6512d02fe0623"): true, + common.HexToHash("0x03aad1d07e6b84c9efe856d213d4ef5c66a6a0e085bb8df749ca7f12b6a0c3c1"): true, + common.HexToHash("0x044c6de1fc909016a3384cce8e29dcbdcb70a92bab6cf32d63b025e91e84ec81"): true, + common.HexToHash("0x313dd2d843fffafcf3eaea2b321f1b6e0c00805217fc58309fca05a8dd65f87d"): true, + common.HexToHash("0x22158c9d5b390ce262edb16badf2fc552c088c16b2b43e06e6a38c33c9a9b01b"): true, + common.HexToHash("0x8dabb31b4239a83cb2579da7c9fe3aa1c2574afd97e66c90660218c31a7d4dd4"): true, + common.HexToHash("0x480846cf6c2c467efd23c1409f952eff4c9d3f44e8530a9075209c62b430843c"): true, + common.HexToHash("0xd83874ca0a80ad522d04e45344ac949d2b4371a9baa917300f33f8984c805382"): true, + common.HexToHash("0x2a8af6a267bbf17532d43ee313724f152bded55b2a1b01999029669e12cc3960"): true, + common.HexToHash("0x6e6f5c9782296a7e2fde6c16dd882bd882793ece18d73e5deb52f48969ab781d"): true, + common.HexToHash("0xf683be203b495d689ea69b36185ff1f6aed870d346afdb3ae302ca398843b622"): true, + common.HexToHash("0xccdd36a21a55d71117f88e47850e56d127ef869835530d783883af97c9401979"): true, + common.HexToHash("0x741889aeab54579b3abd4ebaee049615580e31871f21fdc30c6af8c5e3974e61"): true, + common.HexToHash("0xd04cfc8ae4cd3ef1ba0d00ad7f38706114ba6bae79ba379977ee286d785bf818"): true, + common.HexToHash("0x7470804ce546c4a8ad6f3be00b5532b6107fd53bf0e90d0d5a70fc1e3454e454"): true, + common.HexToHash("0xc420cb614c3f8238fab279ddf86e825a1f876ac014d5309b531a839ba700fa0a"): true, + common.HexToHash("0xc874f0025deae829b2007637f1c7911da30261e7342a518a3fc2a706e5ed0893"): true, + common.HexToHash("0x2a536b42a9f981eb1b162cbf64586a23947ff4daacb5f3d8da63637f3d7d1be1"): true, + common.HexToHash("0xc596ae561dce986cbeb936df984bcfbffc504872165bb23d444f615490123768"): true, + common.HexToHash("0x22b6dfc71a6f269cac754cbc492159ff1cab6f716bfc4d97abe89b9d5433439a"): true, + common.HexToHash("0xa36517f20b74f531bba0f96ab5373dbf4bd67cfd9156b13d0f8b2d102b3610c8"): true, + common.HexToHash("0x0a090c6c88bc524ad3bb6f85fb42bcb1754811a623a900ff07eed35a987af239"): true, + common.HexToHash("0xdb1af1d9ef01faf66ec3fa1d402253221648106580bb1ab2ef507639054b3a19"): true, + common.HexToHash("0x383b4cb963e94cb0c869f0f30f905370941b502e6fc30858f56129a2bde9c1fb"): true, + common.HexToHash("0x1b35e898cf794dbdab5e73f2e3c2649e462bf6abf6be3dc4dcf9aba5591d52b4"): true, + common.HexToHash("0x2168343fde5a543af36835d52308b915ddc37663531b94f772060f3725a66253"): true, + common.HexToHash("0xe99bec7b6bc61d89d127aea75360f6384b312969c3f979aee3bafb0e3978f638"): true, + common.HexToHash("0x9a2107328ec5538261f81d869a4f50258d314bcef153b13adb101dc5e68351ba"): true, + common.HexToHash("0xff195b75524cbe2ad24ea8b107cddfb3ec6d179447ff4e87c9d0149ccb509c7e"): true, + common.HexToHash("0x0cb9d74d57793b242f0ae8fafdd354f8ce0f4681da3eacb486a5b4f0101b71d9"): true, + common.HexToHash("0x8883469aef1f21e4477a439c12cb6ef720f678653bb2abb3f8a352dfea799e6f"): true, + common.HexToHash("0xa767988cd7206b8c9f04fc17cc3339df4081d21ee527308c4025140b18219c5b"): true, + common.HexToHash("0x528f9dcf838aac71e8801327486ba65e0e9aa361030a232961fe19e382f32ad6"): true, + common.HexToHash("0x1baff0272a4bbcfbf2440335a3584ac7d0f6c702cca0aa79c2fba27f366847c4"): true, + common.HexToHash("0x783c78761856f99e38344c04525972d41d29df86a4e27f777141e807ac8682eb"): true, + common.HexToHash("0x16d53d7e9abcb7f3d07af3ef6ccbfbe27beae5a467a1113d7115275dc2c46f03"): true, + common.HexToHash("0x60ebbf9097951e6f50468ee55083342896521a7d6f69866cade961352fa3fa37"): true, + common.HexToHash("0xa2c6aaacb1ff32005d56a9f9fb58bbc0ea829303abfc13393cf5e0007b675550"): true, + common.HexToHash("0x430350f3d6334c6a662abfba8f6aa211fbc15ee0d7ab7e15c2b7fa6e1dd6863f"): true, + common.HexToHash("0xf49d9e2b4231ef0362cc8586a54bae12144ce04e17ff3dac356fe416da6da38a"): true, + common.HexToHash("0x230c7179abf0634d17ae8cb88ff2b12700c405a0a8ffdd321c5a7eda6470592d"): true, + common.HexToHash("0x059b6bb1787067b17a6da143adc5772d838bcaf4c6511235ea991fcbdecd108a"): true, + common.HexToHash("0xbbbe40eb05f8ca1f2aa470ec4fbed3345c724a26188c50bc380fffef94539f1f"): true, + common.HexToHash("0xfd3e9522e21972584a8d1955f482ab812321e2185c774053ec94ed9f49e2d6d9"): true, + common.HexToHash("0xa8a19a48e3f78e512411d3fb3ae09ddaaa9fe62c5cff6a42370d39acda82f232"): true, + common.HexToHash("0xb12ff480def6d0cdecf81ef32b5c72fb5940f6d81fcd456426fdada147760c4b"): true, + common.HexToHash("0x02628e88c7604c5ca9dd56410459bdce55849fbb6205b7c0ac6f0d639ae1d8dc"): true, + common.HexToHash("0xb7ce36d8ea324cc7e476493e88a76ae1d871b3036b5d2d33267c93b8ea0358ab"): true, + common.HexToHash("0x9136053f3a85acb9f80354c4e1416c53aa781d97e6d7e3ef8d0f629c26c8c939"): true, + common.HexToHash("0x2950188390257fd5f117a1b6e60190f1a780d2c230371c94221b9a774226249c"): true, + common.HexToHash("0xf042589b7be7bcdf12c0b3b56170a4d9052890c8ffb6dcd88fe7e2eb9dfd3aaf"): true, + common.HexToHash("0xdf87f43f1252f8698d3f5b4816a03047c933c417d6ce5c0bff4f1a3e6a724301"): true, + common.HexToHash("0xc5450968e55ddefb450e19a14529a7849f5ad66cde61ab4c036e7e0f60efd854"): true, + common.HexToHash("0xf4d0ea7a96dc36e143fbb9f82d0af09a3879d46197e93fd354ddfa37738560bd"): true, + common.HexToHash("0xa1fcd7e3fb77aceb5c24d0d1fd2deb5d12df24350ea2c416112aa1c5e4c1ed41"): true, + common.HexToHash("0x9eb97c0658f41280e7d778d1324c7c4738af51e4d5d57210ac921ee3e583fd49"): true, + common.HexToHash("0xefe59eaecb0e7f5e494ec881b80c3ed55543c09e9b24ad69ad46e38c68c70396"): true, + common.HexToHash("0x78d61a668a154158a5516efa0b76e6aa3b92dbd3f61864bc8c63c15d0e8b7e7f"): true, + common.HexToHash("0x3b636be19bad075a294f8de8ab5cfbaa7a492473452eaf5daafbabec4970533f"): true, + common.HexToHash("0x4b8625fcb932bb68b16ae7c99db9ccc3371de240b9b8ce6b9d4dbc2e263f6b7b"): true, + common.HexToHash("0xb0b8cc7a28eb47ad1c290ac580ab0093f65acf68d4e501c8d8a6627488edb443"): true, + common.HexToHash("0xe663ea80db358141472af5f5ff9e88272c6151258c21b57d5475e4dc80b34208"): true, + common.HexToHash("0x63fb0699915e55e5dc503f5e06394caf35cf00f6135b1fd6fa48673aba3a8e00"): true, + common.HexToHash("0x78356f6b164c24821cfb69ff3e39ae419acc4145e14d632e5d2dcac7bd5dbbda"): true, + common.HexToHash("0xd2aab4e6cedcaf53fb38fcc75532bbf2410a42344b61a6439e39a99165653d6d"): true, + common.HexToHash("0x01cbb6ce92e395eaae4ad7335ec5c79d650b9689d5cbb2f1f0bf9c6f0badf280"): true, + common.HexToHash("0xe840be30b82dc140db09315fca9fde352b4b857d5052c45321d70c81e7c62430"): true, + common.HexToHash("0xfc0dd4be2c21b2fe60cd1ccbcf902307b822a8706de0487c2be39a460c5315bc"): true, + common.HexToHash("0x3808e6b4955c72b0a990e1a12e80e145febf7cb3237116d848abf41590bb47dc"): true, + common.HexToHash("0x1ec54fe898d9c9e9ea0bdce980749e8173b5cde067e91ca1e19724be9d724f2d"): true, + common.HexToHash("0x14519611a01a828fae649422c0cd45251416e6ec60544005bc4f936706f78b02"): true, + common.HexToHash("0x521ffceba3e9da2ddf2bd88cfee827ce326ca636722e023f9158387980a25c45"): true, + common.HexToHash("0xf9a424cb058b08ac1103fb9784831e61526d238c420b1966d96889c40ebf97dc"): true, + common.HexToHash("0xfcdc21e663dd3e271aa0e513b7c9805ad3739192ecf767eeedb74a381a7d718a"): true, + common.HexToHash("0xce5a45e3106c3a994ea0ae270c322cd75ebcd6d63a494c285491f64f53437798"): true, + common.HexToHash("0xe393b8a0ac6154c5bec6da9faa2edd98cf1864c18be75bb50f490f0945ee3d6a"): true, + common.HexToHash("0x6607a64596183ec9f9774aee089ebe7a87959346e8bd9c2ffd3277ddd81b2606"): true, + common.HexToHash("0xb852732751e03d69175ed7bcfcf97ed0d4d47113b6d8c3f7623474c41db8f5a0"): true, + common.HexToHash("0x8dfb8d4c0a15160d1081babaa33ce384b23c48e00c7e7e97a8651cb091d848e7"): true, + common.HexToHash("0x56dbc59cf8de56a9aa404f3ae85683b369ee4340690e26ae36774db136e5e74e"): true, + common.HexToHash("0xda02a8ecb200f126f08d2d67945c2a8ba02e9d1c6271147b2e9b093ac968630f"): true, + common.HexToHash("0x27e30603da3064202d618f5f2af5fa76a61ef3a80c39a922338f8ec40fb101bc"): true, + common.HexToHash("0xfaba0b5295fda5e2badfc68ed08751d40b225d6abd5e0e5b7dd4c07dc7a7569c"): true, + common.HexToHash("0xda4504302a3663662899b5c5a48821e4455da250f068cd8d02f12a82c4e098c2"): true, + common.HexToHash("0xd721b0bfa7768b58601292463a2345a1ed945880f4e0bfa388fe1c6ddcb6e429"): true, + common.HexToHash("0x048b8698ebc1c20bb424150aa62ad9a380dc58b828b512c49976297aadf9954a"): true, + common.HexToHash("0xe91533cfb01f1a0bb1303c25b91d4ffc17ef740f105000f1c9215a72afd56f5a"): true, + common.HexToHash("0x6bf0b0085ecb5266dbe36cef98e5526160b15f77c3c8c17e15906359ad53e7e0"): true, + common.HexToHash("0x51beb5eb624da75176c41f71fa6e46b0bd1c2b9bf68da822fadecb033ff2942c"): true, + common.HexToHash("0xe2a91e378c9445da68ccfae49b39ac956bd598daa5fc47d20e41fe55cba1edfc"): true, + common.HexToHash("0x4f05baa15846dc545a1e4a9414044f9505062ede35f62486a073c26ad8b17f0f"): true, + common.HexToHash("0xde0bfb83654f7c37ff1513f4619572d00c611a76b35c9a21e2d04373360bca6b"): true, + common.HexToHash("0xc09b3427ce3604768de6928b87e5520d91bd8f3fb8268d1c31ec212133716d52"): true, + common.HexToHash("0x2384a51f0c9716bd091c4713582621eb3f70df2577f1ee6eb2033027c31affb9"): true, + common.HexToHash("0x18ed7298ac14bc880bfab216b545179cb5d3cb20393df0e6f1fcef544a34e682"): true, + common.HexToHash("0xe0c5c369cf74914904962e22b6297919e54c52ce4b3ca337829174d6ccfec932"): true, + common.HexToHash("0x061bab760924d0ca83725acf9d08314e36f16a17f22c440431b62dfce931e0c8"): true, + common.HexToHash("0x80fe6c3d5fb3d8d01fb1127e07505701b8f3ffe6cf205acead2076e618f3d165"): true, + common.HexToHash("0xe9bce6c6109e3af1118ab032c60a22c29ce6a735d1aca71daa9de441b77ece65"): true, + common.HexToHash("0x63b451fd73fd25c4f77ecd8625f493b4651369aca0961c025c146204bf6fc2f6"): true, + common.HexToHash("0x3d773d71d1a0a948c81edfb4b3841cf760924ce2d3d98fe117a1487b13bac596"): true, + common.HexToHash("0x44f9a19bd0ddec1efaf63b4e671155d20b0846c11f7eaf9ecff7914e05528a74"): true, + common.HexToHash("0x4e3409ee9e3f168c65a85d89fd5d5054eca1f8b8bff051abd5b3013f91f68007"): true, + common.HexToHash("0x589bfca8f9ba7ec05a1d109da040a916a3e361d4389f385b9c5f949fdfab9f1e"): true, + common.HexToHash("0x809a983d4e5bc61dacfe32253a4b4d54626b3f3243120fa0a39f69428c33cb3a"): true, + common.HexToHash("0x67d1564122c0dd095dc9c2c47c64f3022d88e18e7eb1b1dee780e62625aadf81"): true, + common.HexToHash("0x994426b95056d94c172d771b3122873fbeefeda1e6e17051794aa82516e80068"): true, + common.HexToHash("0xd13cb78badef94f60a28bb7b868bf4872ee981a5683909c5e0d30b11dc621337"): true, + common.HexToHash("0x6ae227985c6cfa09d8a271cd416af964983f858cbb87a0a3740fabfd36b82b3b"): true, + common.HexToHash("0xf7bbe671afbd378e3e89e0f0e9c637c9080b6154ee9138b8e2b021d4eb1ebbc6"): true, + common.HexToHash("0xe9b36e669d8e7dec88f3badd86e7bb445316f0c58d3246ac3bfaa1e257d218dc"): true, + common.HexToHash("0xfa98f745d067827cc3364955d7ecdad8380f732a1a9e5a54af174afde1d805c3"): true, + common.HexToHash("0xf9fed6412bd435842bb1dfb0e759d7d62c3fdc43205c4c82f1747f6395035952"): true, + common.HexToHash("0x77099b626ac15d8f9f31a25d59fcd62b8bcff742af37110b385b872d456b9a19"): true, + common.HexToHash("0x3825756f2f2bff0c304bd826556889dc5755e81d348ef530840e2dcb2a0fdf9f"): true, + common.HexToHash("0xad49a2bda1989129a92761df302f0544724bd12d04a599519a8d1c903725c837"): true, + common.HexToHash("0xbe22105c225dd1bbc3d6abd721ffb4796c610a3b9a1ef23da534af688949ec56"): true, + common.HexToHash("0xdbfa6953c6cff0f3b7962af6d192716a159664b27fcc176cfd26ed327a76b3b2"): true, + common.HexToHash("0x83013046d2a40f087b65a6d158e845175b27c6093a9ecb1835db4f248a54bd45"): true, + common.HexToHash("0x2edb51f53e8da5ee89c48e6f20cc81d5462ec50cc3ac4cc262812ae530b663e3"): true, + common.HexToHash("0x736e02aea8fdf736a9c5aadfa6628cfe812b632b2e149f0f591e3c935725e514"): true, + common.HexToHash("0xd6fab21b56eec4fe09550990193b021048c14ea67880493048d040baa9a39391"): true, + common.HexToHash("0x7d9cc6959d99741c7b89d30b5893521de619910c707117f91f78c17069ec2072"): true, + common.HexToHash("0x8ae2e235d869b09a3be3ad17ba07dc08bcc1ca6fed881721eade400fc37deabd"): true, + common.HexToHash("0xe3b3936a3b1758befc72b62c973db346ebda27c4f5a7b5b47b6022433bac733b"): true, + common.HexToHash("0x8c3bdeff8dffddb31f6f8a38d181d0b2eba229193b6c2e47c240025b413f5a59"): true, + common.HexToHash("0xf090a410188eb29a0d10cf2449ff137a4aaa53f4eaf20bff96f2d87ee703a16f"): true, + common.HexToHash("0x1e7a967bdca12e15cb5c28cb994ad0a7c05a4d354e00d85bed169218f0b2251f"): true, + common.HexToHash("0xefd41ce1fe5cfd2a5bcc2f4616460a6baf92577b72307791bebdd71f63f21fd2"): true, + common.HexToHash("0xb21792b03fce3e2c39dd9b4acd545836e96897d8132eb5881f724538c779ed07"): true, + common.HexToHash("0xd27b5d491d0a8aa7b1955b8e534b8582906a89892be1ba1c1198fea4139d7540"): true, + common.HexToHash("0x3088604fdc5cfde5edc9b70e951f5be68d0a8dc7c7c9077852314ea1dd178bec"): true, + common.HexToHash("0xc7fac985dfd1854d1696f6bfb22892bdb8d093ee0d67b1a7d56497daa27a44c9"): true, + common.HexToHash("0x387d7d5343079b4bb9bc344e26f72fd812a6b18ead7636c1080e0db262fe66ab"): true, + common.HexToHash("0x6e17c91acbb756db47dae903c47f85b0a32efd72548b76cc4787befb187487fc"): true, + common.HexToHash("0x83543ad4f57c7f07b3cff32257c4b50bc74800e4a27c99a795866f466335f2b6"): true, + common.HexToHash("0x1c71f4637780e2bb471c7a0ec8fca834a2d8ebe537cb0123fb31d6b021eff6f6"): true, + common.HexToHash("0x0e6c5767b73272ccc6ea4b59faebbc6941000962494ccd956481bb87f6a7116d"): true, + common.HexToHash("0xf7631f0da3b7ce6deb899a686ff2d2caa580be3b4f718908ab8f67df99f8f06f"): true, + common.HexToHash("0xaec89191f357e97e6f6a7745a2f6d63401a49823390cb533942456458e7c65be"): true, + common.HexToHash("0x38b497fee3ddf4cebb0c83549381d4c0c0c16d2dd16b5339b1581523c6914e2f"): true, + common.HexToHash("0x894947463203a2d86a76af8752042c183dfa30659488e6d788b7a1e8fcbfd3ba"): true, + common.HexToHash("0xfd736c8edf95eb39bf8df96f9981bd03c12742559b51fb18221ef925616f7479"): true, + common.HexToHash("0x627a93f1a31ed45fe87a614665eeeff695a47c9a70663423bc803488598d19c5"): true, + common.HexToHash("0x38ff6f53462dbf70ef3256d5eee70c855bcc0f1deb36500519af0f3c9776eaf2"): true, + common.HexToHash("0xc71a9fef662200602e5b91977b023900e83b2ce6ce49b11b361d8302fbc9b37b"): true, + common.HexToHash("0x334874ed7fc5a8a01e21332fe44d03126c8871f3ae7e2098f5453f50b8fb4677"): true, + common.HexToHash("0x4956c642f68e8127fd6eaa27a173dd24d357f7a288d192af99cd139a51292798"): true, + common.HexToHash("0x02f6029c2c75f3c8fd5593d18968232b798ba73d2575f0403eaeee1bbf0eba9f"): true, + common.HexToHash("0x9cb2bdd61ea2c7440bdbaceb94d2999d642b444ae09a6cf94b9ce6df28e18e97"): true, + common.HexToHash("0xedb5540557fdc3a21d7e92cdba1cbb09d12c913ed724ef2aad0239fd2c111bdf"): true, + common.HexToHash("0xd0e855c20abc3a9a4235585467b700019ca1437921181b9baf7b519d3d7c2987"): true, + common.HexToHash("0x36e3c71b92237850d7199905f4b1e1cc6bed6c863a2ba59ecc921c321c396643"): true, + common.HexToHash("0xc5a6c33c357b742ac979ea0fbf8729318c1a1a20ae201494672147080d477e5b"): true, + common.HexToHash("0x2c460870b9df431f654d0f87589ec85622529bf2228584d05f7c732bf8656d3f"): true, + common.HexToHash("0xe586e9487444af3a2cbff84e81f5f41fa901e57aff507ad41d2cbffb2ef37e95"): true, + common.HexToHash("0x36155aa4108132b88700b68535cb7accf23a40c9cc90fe2a3858baf4debe5edf"): true, + common.HexToHash("0xa6494896b8a17acf3febe215b1e5e10a30e92521f15ed7a5062b30405ebfb2e3"): true, + common.HexToHash("0x28bcba7ecb5152d488bbcf8d88537c6bd99f069a7aba07353d58db0890f9fe09"): true, + common.HexToHash("0x43ad1f0cb448d43a23de8563d0be42737a1fb214ab154db22965135a012020a1"): true, + common.HexToHash("0xfa5654a55bc5283378a89d9b2a9efeb09bff0b1680ebebcaaa04cea5a1d8b088"): true, + common.HexToHash("0x59e19c2f078285cd76795e14d6c02bdc0c165ddc6ecbb41f7b33d723dcc3157d"): true, + common.HexToHash("0x74dba729015383c19b180abfabd803d19a9bdd70b4de1101db499d91a36cf5bf"): true, + common.HexToHash("0x873d585c6d59e90f32265d6529cc9210016421390e28d2789cd2584405514dc5"): true, + common.HexToHash("0x48acaaa7efc1608da7f64dcfc133621d2c7aa7980ca325925f7be28ab017f57c"): true, + common.HexToHash("0x019aa3ecf0e97f05af753236cd122fe617b82ad735a9f0089fd5668aa581fe8b"): true, + common.HexToHash("0x92cd9da09a2d17ebfbd15f01308500b3d2cce236e52f900a5b6da61ed2536432"): true, + common.HexToHash("0xe8a5f27894dec7122e89c188cb7e949df45a6586775ed2545607584f9fe54e4f"): true, + common.HexToHash("0xce406a1426740d7369d71a0737d79e4a8b1be64252f02b216893a56a65af14ed"): true, + common.HexToHash("0x4bc45eb8dc1e6b4773e2c5ee2e66dedaa1c518e264bd080721f6024a4a7f1b94"): true, + common.HexToHash("0xc8339587170bc2ac8fc2441104f402e3a46f7001340d3922fe34904b6afe0eaf"): true, + common.HexToHash("0x08ab0cb154c1c526d587be76861bb2b6a17cac60a98de37b7ce820c2f84ea999"): true, + common.HexToHash("0xf085f7a9d72f6eca9f43465c529a1ea33791dae0eebc1f847f825c1b629caf18"): true, + common.HexToHash("0x1ec63ba4329e38b099f01e131265c8b4aed42f7a040f5f0889296c2b3a4e1d85"): true, + common.HexToHash("0xdc4a4c03fbbab7fc58ecee9c6e26173e11f65d7ff86ec353b1436bba69e4a971"): true, + common.HexToHash("0xaa2059ad99f570dec13ac837926276af2af496664b8075df02298403f0192b93"): true, + common.HexToHash("0x136dc3054634cc86e676b73b9ee75e1beec07760529dafd705a11754683b3480"): true, + common.HexToHash("0x01c6a635fbd6e78590e1cfff62aa148d7a2d05029ac0b4f00ad42abae9cc92a7"): true, + common.HexToHash("0x0eae0228aea706ee9141209e7948c288ef60e1ae4f940c624db4975e66290430"): true, + common.HexToHash("0x742abdc14bed51eb1cb35523844e33c7c42535fe7809b5bd7525f98c57ad1dfe"): true, + common.HexToHash("0x09d48813616375f0686e6900db85096dcef0d3fa1474286e476893649636c60c"): true, + common.HexToHash("0x6b33536a8c057b6db6f2b5f3aa70fa9d2e7b3347214218625d15f73b1b60b4b2"): true, + common.HexToHash("0xd349761e3af2cd65dd63d6d647e13a7634d7838112dede33cf72b01b0cb4bc25"): true, + common.HexToHash("0x698201f1cbf8011fad01b76eca69154daf1c2d1608056ff9c553be2a3820d7fa"): true, + common.HexToHash("0x65323e1931e37d44c9037b989d8adceb3711a43561e644729b2e996d41caea0a"): true, + common.HexToHash("0x496139c641a85cf8fd3e39a8cdc5388826c300152a349e8648143d8a3cb4917d"): true, + common.HexToHash("0x65920bd9e064d1198d38fd49a30f0e9ce2b9791ba81ce1246f955ac113086d85"): true, + common.HexToHash("0x3cc53e85daf7b71f3a2baef37fe718e3a951b30c7d5e8a3317d674a678b469e5"): true, + common.HexToHash("0xb0552349a090f79549ef0a0afd36f9ace116d59b7504d2f77e10fd671f1a7ea3"): true, + common.HexToHash("0x0c355cf6db9d8c10d93c0eac99b923d51f81a442e7e004176091d5e5dfd4a5c6"): true, + common.HexToHash("0x4523f8d92d1d4a2b82e6fa57484dfce6af2713cabd8da8942d059e4dad46952f"): true, + common.HexToHash("0x8ab5deed52549529ec94f54b141023009b320ee844a28673fe6efc48afcc18bb"): true, + common.HexToHash("0x5a0a0709f62dc5a02670cf29d9fa074ed9f58f291d17992b2c5618b031608ec8"): true, + common.HexToHash("0xc595543ca31b414f1b5acd65d62bfd105d22e99f503a3d1581358c78a57595ca"): true, + common.HexToHash("0xcee7524f41c7ca607c3519b17c740266af72dc10f50b3cd1335ec7d56560d80e"): true, + common.HexToHash("0x977f31f7ddbe60e3b288df08eb88da957713aac5438cffa53628b9136733e413"): true, + common.HexToHash("0xa376f3426147778a5446c7d52d9159724a0bacbb40e97483fb2d1cb52b56daf9"): true, + common.HexToHash("0xf04dc93275d14f2312de75cdc1bb38676a6a334a4c2c59700934e85d9d9b6ae8"): true, + common.HexToHash("0xc67394782cfaee0057fbfc38df1c712ed7b4b1218d292e5fdd973a57c6c5a705"): true, + common.HexToHash("0xaa1ee71c2cba59396dbb1386f839e92befdbf2863c800b5bd5fa9d50dfe8ffcd"): true, + common.HexToHash("0x091ebfe924ee81644dac8ef9220b5b0ede5bc43d0692f7d1057c6d54793b1bf4"): true, + common.HexToHash("0x2824305cf20f85f3c5e10f0ec3ba19ad0f288e7cbbb3d44228b89b1145f3341f"): true, + common.HexToHash("0x9618735742b9d1aebf452afcadf35d058b0bb4e116609a0b1f50d124bd898749"): true, + common.HexToHash("0x9708c30a1eb52a97593aa1d9159c5c5e01a70b394782a0a1c39512543cb7e1aa"): true, + common.HexToHash("0x3ad1a7fcc307300c99016682b36468694dd6a8ad9b63f379479da50dce062c1e"): true, + common.HexToHash("0x4d6b2e7ac60d5d990a0fa12f104779e821a1b1b453604899adaed9763c4992d8"): true, + common.HexToHash("0x7cae338278eb6c54042ed118036d017a0f55a68c3df60a0efa0be73b0cc7010f"): true, + common.HexToHash("0xc93f0227d6281c5b2dcb87ae9f947be0c20468be0d991d56726f43fdf5fa8a43"): true, + common.HexToHash("0xc9ae46e1fb92310ea39dde38a9b455cbd2b7e9c0f6703d9b8ea0464bcfb5c955"): true, + common.HexToHash("0x05af18ec2907ba818bd5713f4f8582f6c7edd61fd425ea46fa9c202453c1844f"): true, + common.HexToHash("0xfee56e358adbf912c8404caada6121aef23527a3a85a0e3ef5104e855ea999de"): true, + common.HexToHash("0xe1c8e5a247d014f2121ed32235c50c43a9d01afd4df45dad7d478afbd03f68a5"): true, + common.HexToHash("0x2b7b96d91a4510cbbb0004236c4c06a061b6fa9779ecc2acb4dee46bc9cf37aa"): true, + common.HexToHash("0xd9d7a55783fc4cf005b173df706178a6d79e9221c0883d92747548c38d8ac0e8"): true, + common.HexToHash("0x3a3da492e4d42c234a5e436345e94ae7d1196ca739f620c0db38f2167862be75"): true, + common.HexToHash("0x03fa8fbd22c0194f8ed480f2da5034a996e2c7c7068391e264acf2581e44e4a0"): true, + common.HexToHash("0x5db1b9bb57f72c63f1c1f3477ac2601f697e1d5a54addcd2e3d6715e1d75b17d"): true, + common.HexToHash("0x73326bc3884c843009911f7a1af794ef703d756afd53393dca9237270482ce73"): true, + common.HexToHash("0x67c3252ae6baad76a47f472ddeb304a0c5ee63dd2f430df15a26f436589bb0ce"): true, + common.HexToHash("0xb6811fe6fb8c94b5c0107b1d1b2d6c4f6fa15869e596e0b3590987c8b5ae582f"): true, + common.HexToHash("0x005869f2e1f233f5056d384a347a62e7a891da478e6a6b5ce76a096dec6b5604"): true, + common.HexToHash("0x79c165a512cc9d57b4f9c83b0f1de8ba239f2c34521f6688ff936d8fd3dd0fa1"): true, + common.HexToHash("0xc7690e0953187ed8c2935667e8310bc9f0884ceae97891a4dfe1e51c085fcfbd"): true, + common.HexToHash("0xb31f211c265de235569aa8a9309f0d533be88d4c42a49db231374c5adb36445d"): true, + common.HexToHash("0xaeb756d6920342fab0417ab2864b99dce49c9510971e7ae74fb849dfd21ca55b"): true, + common.HexToHash("0x16fbda0365a0d3e9271d87587a5e7210a92cc461539c10107c19c1f60a31e033"): true, + common.HexToHash("0x294bd77e45dd16b2f8b7fcf864198b6c82f0a009773d19d441ee9d9e842632b9"): true, + common.HexToHash("0xb782f94c0ef21a7f73d28c23822a6dc79cc9ec8f476a2c900def1e0e2b09bf40"): true, + common.HexToHash("0xd4e017be8f5bdb2229f3557200408ca4fb335e564d40c576ba75b4141d83bdbb"): true, + common.HexToHash("0x2952b8d6a8dd517b7986549a5b430209b31904113a03c6a75acc6ba4f3cfcd9d"): true, + common.HexToHash("0xd7c5755974811ef92dba4e8d144e5599a623092e8ed97fbc1d135f12d9d6e6da"): true, + common.HexToHash("0x2f124157e6e7268889b6f8c196da169bc47760157abacf46012d1f0a75c9a98f"): true, + common.HexToHash("0xf5cdf09300f42d1f637c90d739064a3fb5c8e18602859a4052a8a02463fbd1e5"): true, + common.HexToHash("0x567b9e6b3e39f5b7642903c20cb1505d1607af0f61a4759ad7374d7259cdf0b9"): true, + common.HexToHash("0x314eab38dccca3e557650f572f3bd25af505f8d4dda893e1415b7219e846b545"): true, + common.HexToHash("0x8b65d38a950d2adf50bd3337daa1fd8edb16e4114b4863b9be871ea358dfeb61"): true, + common.HexToHash("0xd90bd581182afae822464444073be54e3fcf61d43060ad73c6ab353617a658c2"): true, + common.HexToHash("0x78f759914bed8b1a9c8c0a0500249bcd477dbc9dd8f29934ec69552707ae3f13"): true, + common.HexToHash("0x41ff211444c7495a58b2dcfb3f9e68a6df22d3f85985f064da173b115952417b"): true, + common.HexToHash("0xe23122bc9a41a12fed594592095b74a3740c906f9367647c809b557fe53670e4"): true, + common.HexToHash("0x19c5789adc50ed84198e672818545aa0503e07405fdebc078d158cc1d731c779"): true, + common.HexToHash("0xd4ce299240a10f48fe7a18f9a01054126b7c7981aa98c2c4d87f9e63dae7c39c"): true, + common.HexToHash("0xbc23937033b757749b560e051d557f14e8fd64fea2450c9bd3de8ad41dcf9a85"): true, + common.HexToHash("0x39443776d098c0208223ac8fc1f201cb3fb4896fb7883425c4d4f9b3712117ae"): true, + common.HexToHash("0xccecc310d4032d5a13cfcb303ca2f2ee0fc5643866378474e90f8b255d3d00eb"): true, + common.HexToHash("0x0bb1a88a3a68cc74ed0ec166f46978d72827efb979ab8f550f612e2347b38873"): true, + common.HexToHash("0x42ccd0c30a9444f61960b2c08c25e4ef465eb7218ad3c126fee3bcccbae7c56a"): true, + common.HexToHash("0x9c19964638f6620115592a4096c8e529a408d270832d61f63bd2e6194daab3e2"): true, + common.HexToHash("0x7554c0a1d736456c04a28b58d23668e646df51b84623f97ffc9aa049ac2348c2"): true, + common.HexToHash("0xe8447d6c9059070e57b802f1130f01d70a32856b94ecbc0c2e5f321a7ef43fd0"): true, + common.HexToHash("0xb41ab35e334699060b28927cc30ad96a269d4abbd37357d71ef38f2cc2c083bd"): true, + common.HexToHash("0x82fa6b41bfa1e1dd750c62e7dc27050ab136dc95c04cf955edac4e9265983efe"): true, + common.HexToHash("0x264f9aa4af110535ebfef3296fbe55c05e2f7f9054f67381fccec403d3711b60"): true, + common.HexToHash("0xd2e71f3fe9d65eaf0d69a47e7f0a69ab4c37ab1a779218b14f2bcb8dc739b0de"): true, + common.HexToHash("0xe1340d5ed14d73dbe8aa51b4978135db504e687d213892979ef2487f4ffbc3d7"): true, + common.HexToHash("0x8eb7d93f26f7db6e95bf8e1b95777fc0827a22ddc40ece1a1dfa157ebe4f3e13"): true, + common.HexToHash("0xf1da1df66f482e73a9eccfbdc642335e0e58562e9cadb3dbb70b200ba0f53846"): true, + common.HexToHash("0x48c8d6b9d8c396490aa521b78cd60f75c500383b99d961233195af8ad37b4f8a"): true, + common.HexToHash("0x7859c2be5bfb19956ff2921951d55e3ee936cc5755c36396c20f06f98175a2ac"): true, + common.HexToHash("0xe7e5cbbfda5b3499c9305b2dace7af425c43ab329b7cb9a9bdfbd56a58054a04"): true, + common.HexToHash("0x1a7ce3153d5ff9ec531bb997a2d54e533ccfc0c993c7edc073f4915bb9323bea"): true, + common.HexToHash("0x5b6f65814e1d95ab376079c1fe8c32a3d8b48c48b058a18c3940e1ad628470eb"): true, + common.HexToHash("0x02a899a48be368a3bd3f8a04c30d9299a41fa6049aa11271ac5a59fe7b1c81f7"): true, + common.HexToHash("0xdab6c4cf091f7c5cea9a455d5645aae4195ef305999cb66941a8feea5b0310fb"): true, + common.HexToHash("0x69ab785eb2873212fe5fb96188ec7ff253d32aad71169b804cb2aef3da11a106"): true, + common.HexToHash("0x8397aa3aad14bf3f0547885055ca0cb059cfa8e431df877b859d4b64e215330d"): true, + common.HexToHash("0x9824689037757b7cf75f8db7bff272614e6dc95f8f15b38577215f0330b29b39"): true, + common.HexToHash("0x4dbd3a162f470350d67b48fbc9e6d221c4f545f8646855fdc2803526de508e6a"): true, + common.HexToHash("0xdb9aa15f0417ab28ce3019b8ea5f7c1f634fa773681880d6a38d811fd084dfd0"): true, + common.HexToHash("0x8d48e1a0686762e462f9024f96f3870de1ec7ea8708d94b31985586f2d265d54"): true, + common.HexToHash("0x51e17068f8544aca4a75013efb1e5516456078632f55cbb627e600e2212e68e4"): true, + common.HexToHash("0x480a70732b479cb0775308e0d649ae5b3595c8beff091c763d5f8cc9cb8d5e87"): true, + common.HexToHash("0xd69bf654ad86cdfa9a4daa04999aace3adb4a24362fa7c9a60e1b274ffd0715f"): true, + common.HexToHash("0xbbfa2547c009c0c2eb348ac05ed629ad77a685ef0d947f63b71994e2a1e18a2b"): true, + common.HexToHash("0x622fac41fd2c53e4080da2e66ab4b5a53b44e98a6c1fd4c482ecc95b00b9bf25"): true, + common.HexToHash("0x59932e96964b00f15f625b4060b31fd0e4c0f35fa05bd25e0cf94f83645bb59d"): true, + common.HexToHash("0x76dc3d977d2dd666768a42016128c186310704cbe44956f29f7ea60e227c2599"): true, + common.HexToHash("0x22d69361fc32c55f78094ac9f50cf030452e0f99e090175ef853a67914a3a2c7"): true, + common.HexToHash("0x55b3c0f244d040757a84dfd05b09f22fef5706db19a7473afbd83a7c672ddb9f"): true, + common.HexToHash("0xc5dd69b41d74a463288244559451d457f877f5fac84d7d257122bc2f27baa2bb"): true, + common.HexToHash("0xa9cf1b47fd07604b96555b5f9c650720ebad7fe731d69935988647f763f4e18f"): true, + common.HexToHash("0x35d2d4cd072fbd7b296a8979d75997613aeee8cfe5d6edd23ce10b45f1aae456"): true, + common.HexToHash("0x5a12e35b501b99bcf3ad40831f252a86786e8e12b1843abce6f98ce5b316fc3e"): true, + common.HexToHash("0xc5e162851fef6ddd549240269f7fa46d1e4cbfbf92ca84f6b84db9943f4d4637"): true, + common.HexToHash("0x5fe4cacf83434f06b3154f64df1fc6c0d8ccd3cf6cfea908790c13cfde34be27"): true, + common.HexToHash("0xb6701e49c3e1a660568f0301b60fc483a149bbfb6442d3336dbb38bcedb569ec"): true, + common.HexToHash("0x2651bee6ef46e05c33e4bb77eb25516acd9cecc378f25c7b2505edaf60f2fba3"): true, + common.HexToHash("0xfad635eb6f20d15f169c342589b9efe3149f0a57894c7b0e33884829d5a16a7c"): true, + common.HexToHash("0x7ebd76550e6dee08475c43fefae2aae5338b155798094d749ee114fb77743187"): true, + common.HexToHash("0x16fe71842883ab23e82d82dca856b7c84cc546573c966ad02f331826ae44e739"): true, + common.HexToHash("0x51969776ff798c451ac7089c8ea4c147493685474f6568a5596ead2bccf81164"): true, + common.HexToHash("0x6fc2f9ac4c5dbabfe9fd3fe699d12611766509a44bdbbdc13524a1bd513393b0"): true, + common.HexToHash("0xc83fa314e6a5e819205a1dbf472f56ee103964bb12bee006310bb04a4f85eaa8"): true, + common.HexToHash("0xed40c486d509fee468515791753cad2b174fa75bc67bddca1999a92e9c0d89bc"): true, + common.HexToHash("0x2f51795b22f8a3eaf6f155b9c60ecdf506175a909f2cdc3ab8be8971fc307e99"): true, + common.HexToHash("0x2d0beca36f9310fdede63c5ce6888f14e0f1dc7d9eb11db08b7874f34607ca77"): true, + common.HexToHash("0x426a146fcc7a161db36d8fd201f38d0f861a07a57c2e78df8d0b39275f391c46"): true, + common.HexToHash("0x0cf1fb3c3b5f5c7e564c3f95129b6c7980f76cf5dbc5e196132bf3af10dd672c"): true, + common.HexToHash("0xb430c0604c1dcd2fff0af138871198bc4861e239a713844e63512c330a3a2e0c"): true, + common.HexToHash("0x429b561b5d836430c62e947066197f1cda0d0cb9f0e95f5f66d10123ba8215e3"): true, + common.HexToHash("0x67133e95576438d35641a83c1a7bc96de895b53d7296f69e8bd16e52e2c0def4"): true, + common.HexToHash("0x0f8de33b58f5dc0a957dcbbb0a82feefba8e829b4424827dd5c0cca8917a36cc"): true, + common.HexToHash("0x7eba291173839457d1ec2754f5e3b142e79986ff029056309de5f581bc7c91b4"): true, + common.HexToHash("0xaf909bfce37de71892d1b4c006f575866fb600be6c739d7a7800370723d12fa1"): true, + common.HexToHash("0xe1d8476f9ec08a1e608e942aba38a31e51d30163718b1978bbef128c295d4ccc"): true, + common.HexToHash("0x33510d65d02f46c46febebf44f80f4bbef2cc37495345fbfa4444c6f6dd842f7"): true, + common.HexToHash("0x69e55223ef2ceb84eccf2986c73501916dff89394bb9ec15e29871e138973f9d"): true, + common.HexToHash("0x3e90549882b14a081202f872bfff4330f74b6bcf4aaf1a6ed6853352046e3b00"): true, + common.HexToHash("0xa494b301e1c76c44f9eac061e86329281d3d210e73567d926c5ed8696e2419f1"): true, + common.HexToHash("0x41cd4c010195d51e73e1735a42a38984db87ef14ab544a9de502685d41fdc9a1"): true, + common.HexToHash("0x26eb0b575456ece88ddc05d4f0d76173f9da813dcb8dcb823a4b510ba7778f87"): true, + common.HexToHash("0xc9f548078635447864802b450cfb9047349987e8b1353e51f3fcaf186ba28b1d"): true, + common.HexToHash("0x4c5176956a7c243d7ca82873efa00bd51124801044e0db86f9dea2ce448bd0ad"): true, + common.HexToHash("0x60980ec2e41456d6fa5c4a19aac8ee0d551e56b444f65c3bde7888f71bcb1fb8"): true, + common.HexToHash("0x587f4cfb3b663a02c295a487171dc1dbd73f8c30cad0c17a4c240671240496ad"): true, + common.HexToHash("0x325ec645aea44975c20a4f72d9836950c94bbd1d28ac70970fca157ae18ca30b"): true, + common.HexToHash("0x48151219d12178defdce47a10d472592c583f7e1b964b40f02d175a1cd4e3686"): true, + common.HexToHash("0x6535a981de74f4ef4f2401db1c9c8470e5c40297229aed4574ad632a64c45344"): true, + common.HexToHash("0x084a9f1010c6f25c3846249fb28f698695fbb12bdf8ac9503af3a9028073d923"): true, + common.HexToHash("0xa2205e64d0f5924a7f9fbfd5f957118eb98e131e3ca9a8439a4fc089a3d5605f"): true, + common.HexToHash("0xcd3a2a545738c0034ef89f055bb6b6acfeee3341f8fbc5fabed0941793b84628"): true, + common.HexToHash("0xe5ad85c4b6d938771fe14be447b214247fb7bf147be5f026f3e37f5b7df8d03c"): true, + common.HexToHash("0xa1736446e7911bae396519523e8747bfb80acf93ee8a3ca4662655a0273b310f"): true, + common.HexToHash("0x097f8889430dd46c829f8a15f04fdaec04e5581ff90b8999263f3dcb63a6955e"): true, + common.HexToHash("0xe7ca5888cd1dc842966f9a3c6a2d54d13fd264ff0a57bd9ad409b5feac928f27"): true, + common.HexToHash("0x1c2f5cc537e0bc11c3121b390b8efaee14ca02c37331dc8999eb4fa47e986b66"): true, + common.HexToHash("0x890baba0c18763fcf77220a410aa793a6ae2c93e8200bec3c657d0ed93fbb18d"): true, + common.HexToHash("0x9ff5717ac1989690dde13218225f198816cf60114e0485ad9ca1e81644b716ff"): true, + common.HexToHash("0x7699251026a09b5f2b21aae48a075a349991c9fc86464d31bd909c98f165b8f2"): true, + common.HexToHash("0xd3e5de0b59b6d6ba63aa6fd90547cd9c06abeab622f3735bd6168f8edf7cdeb8"): true, + common.HexToHash("0x478b996bc3d88aa0ac868a5d72f6a4a0b0ecd6e1c6cf241b91590dac28048622"): true, + common.HexToHash("0xc4ba9fb2bbe714126e104ccf9a9bf386fdbe383b26db1d898a73c14134f90631"): true, + common.HexToHash("0x5394242b38c05556233c1361523777f87c67c62b8f78246d3dd6c45bde646eed"): true, + common.HexToHash("0x320abd92245d255c48a6e1887624a6ffb1fb019d2358905c45fb0436366c10af"): true, + common.HexToHash("0x2122bbd188e5bbf2e11c5b1f53e478ea026aa006fb903c9d9a671c704180b617"): true, + common.HexToHash("0xa753a19b7f895e3ded34820437244716bdeafe4c399099f82e2645a1cd0012b9"): true, + common.HexToHash("0xed02ecfc681d3e2623cda190cb4a5a0dc125e99e59e6d32198435d13019ddeb6"): true, + common.HexToHash("0xb9b005fcf4dba3d183b8ffcd0e296a0341d07fdef8f93fe0166eed9d9e4cdb86"): true, + common.HexToHash("0xefc7aa37ca049f97e91f93fda30461509dc85ac4b63cf08971b7ba71468b657d"): true, + common.HexToHash("0x3f317e330afdc67b7952734326cbc765d0bb486c79f6750eba642abbf1591825"): true, + common.HexToHash("0x41e03a42bafd0a975eda6e24c741d19d6e22200ea4aa25bb3ca17602daaecc40"): true, + common.HexToHash("0x7e60d5b2657b3ccf2adbe5841e984f1896408cbc0b2ee683ca5902a4ca020212"): true, + common.HexToHash("0xe86ab648e4be6128163f121890dd2987cd0f92d9745e0ee346bb42880f9b97c5"): true, + common.HexToHash("0x45ff59ac3c435a87e971f72b6bf223befb1c150848420453fd2f85cd5a6c120f"): true, + common.HexToHash("0xab1a773cfae1f0c1d40969beae6ec57506501519cd97e74c1b28de31ed453bda"): true, + common.HexToHash("0x451b8a5f0e769b8623062c9eebe698541e2ce3b5900d371996bb11c6c888c617"): true, + common.HexToHash("0x8136740b3ab4f8a7e0e6a5e3b4fabd5209dc20eaa373d942830dee891c426017"): true, + common.HexToHash("0x28eb6c004aab4e0be0bc477efe61ed728d44bb5e23edb0cb69d0155d5454396a"): true, + common.HexToHash("0x3647416ab5c88b79ca639496dd6329f978cfb0be1d5b05660054cf78a16c354e"): true, + common.HexToHash("0x2dea54ea45ef4a2e47295625e35b2972dda607c61c51d40929ca85748c663820"): true, + common.HexToHash("0xda9326456945b50aa0e8ac595d2c1f152d9da4cec89e200a0a3207290d10e1d4"): true, + common.HexToHash("0x1b035630e57fbc4a05a23171d54747c00f04a2fe65ca2fea782eeaf28a3f6672"): true, + common.HexToHash("0x64a4fcb5c591002cb113bad8afa123b1e99d46bd7b72163e1e561440e57f3180"): true, + common.HexToHash("0x1df4d1d28c90e2d646560dfff0f2586bed1c65eb94e980c9ce14368173a12feb"): true, + common.HexToHash("0xb48e43f4e8f3d563db2fccfe4f9208a617b1af5ab976ee63ad4d15304d0f2cd6"): true, + common.HexToHash("0x9c42a4ac83c85f7fc6a5924aeaea36009d6345ce3221025d0d00bcd688290cf3"): true, + common.HexToHash("0x39818fb0abea48eab917d024b9db7fa5d2c01d7008a7aed515c950366ec6672a"): true, + common.HexToHash("0xf5d40f8ddac4054c5e605f5f9f4aac024787022800f478258f282685c762eb5f"): true, + common.HexToHash("0x1592bcf2a4a2af6c065c4dc25b1bc24ce093fcc62720f28210ccf2a009f35ae2"): true, + common.HexToHash("0xb8e62dd5247ecc5f3936553d4e72963de2409feca94e2fe8910949d265e27d08"): true, + common.HexToHash("0xea4873f7633f4abe2b2c40127c351868c5f3427b304617ccee956da9c1d87a08"): true, + common.HexToHash("0x4001e6158a72928b0306b4c0d044cd6e665cfb62a4376609bf4f1ca5fd4cab84"): true, + common.HexToHash("0xa147e892221cbc159d1a351989770b9a500add802905962220b7e6dbc4171f4a"): true, + common.HexToHash("0xb1a7e5787dd2749f8699d1a20bf1a7a629e9cc56b4a1c5aa53a515246df38c14"): true, + common.HexToHash("0x61e7d347e00d98e6d6148393833497f1b776a36ce0ac89a97e5349aa39c1ff39"): true, + common.HexToHash("0x8428e53b05ccf22e79455f290fea44ef282d7c19f9f8dd969bc39e1ca9bc4d67"): true, + common.HexToHash("0x8a7940fbd9a696cbed9233a4f0e683865d2ef948e7f5d399fabfbb61a5f8eb22"): true, + common.HexToHash("0x70eaa5027c0d97045722ba76b9faf3147e8a84d120e005d0173ec6f0d6db0fcf"): true, + common.HexToHash("0x80a17293ae97a46c72a9e9b38ce3d5fc471cb5e55d4ab8facfbaaca5dad8856c"): true, + common.HexToHash("0x5021bd6eebd046c9990d008d42af82f72811294d5e081701e17c00f948317b48"): true, + common.HexToHash("0x639c7884661a6f40026e524d2f80740ec45d157e9a90410b293194d41731ce4b"): true, + common.HexToHash("0x2345d4ec9f3f562beb154035d5dade40f5c96a7c4376128cfc7705116fe01efb"): true, + common.HexToHash("0xc00d499a78279479a19f447ac3f331d5f838193f8d311d470c3fb1571df34105"): true, + common.HexToHash("0xc3920ef98d68c2826943a04da13a780e9d2be2dbc31cb3bd44db3fd3de0bc055"): true, + common.HexToHash("0xc07203be6e5305ba4f10af8bdf93ec03b883100c095dd49bc9e0d9b467977996"): true, + common.HexToHash("0xfb87372c460b7ea139bb697cf8a04d2aa892b8e815199e8aae53277c5960a1d0"): true, + common.HexToHash("0x14d158ac1fbf92b2a0db1a531beefb8b2395cc614f9fc53aa942bdc0b1873022"): true, + common.HexToHash("0xc7fa3bdbf85e5b80b2d5a594b6371b7f4bd6eff5486ce7ed8d4492734adda37f"): true, + common.HexToHash("0x7fde76c1552f117f714e2052cdadb819a0ba90e5c05d0bee47e2cae6186b1c7d"): true, + common.HexToHash("0x4640c560956c483853b4b2500d58513a36c26061f227a690e283a89681b42c57"): true, + common.HexToHash("0xbef9167f85463641f67ecf39120e45705b2e3df9164a15cfa33e08f6bda75f3b"): true, + common.HexToHash("0x398d4a283546b0468db663345cbb87540816d316a93ae7d701a0322a7783e2ff"): true, + common.HexToHash("0x5c863bf9c17d45c2b71e0b009e620808868fe2b2bfbb58ea8cc2dd4d1a80d940"): true, + common.HexToHash("0x1286758346c50277368065b1a4b8be62ec9d542384703b63e29943afef9f8165"): true, + common.HexToHash("0x215ac97d2243a980862e1b7bf9232203fa23b8078971a72794e593965d1f6ac7"): true, + common.HexToHash("0x1156c2ea52f456e126964d7974a8749657c6573a55284b2d8764582f2f5a5756"): true, + common.HexToHash("0xc02b0576e251e254134bc247cf5f065102dcee9864579dd83039d4c42d937e00"): true, + common.HexToHash("0x57787068a7ded5454b4a8fda9c37a77bf5a30937e7284d6b5b8dfaaec957eb1c"): true, + common.HexToHash("0xa0ac653d8b7b4a8c0c7bac5afa9d563961fac3dab2f899ec27c76adc325ab956"): true, + common.HexToHash("0xff40b1c2c58d2eb9f62f92728c0ad843656a7bbec9ab418cb9e68b639ffc78a4"): true, + common.HexToHash("0x8d56937e96d39b825876f70d6b74c9bbf53503ab4bef4d5898e05b6c6cf093c2"): true, + common.HexToHash("0x1a01e2fe12be68a15695ab0b3704cabfe88b1d48471cc68d0149e387bbd913ab"): true, + common.HexToHash("0xd592f67b5d3128d39b7b4fdc27b700c62d8d80f19709c1277c371308da59c4a8"): true, + common.HexToHash("0x3973abc43b177031d860ea27e3717d0120261a5aa8ceb7896f027704864781f3"): true, + common.HexToHash("0x729f3abc1eadbca979b44e276c70006248256d623daeb08254ecfb5e9b8b7294"): true, + common.HexToHash("0xaeccc5120a3ffd326b1366853c8f28f619c8d928b5e19ea44e27f412814c61f7"): true, + common.HexToHash("0xf7cbdf93723a9c4539790a65df641af0242d46e1e1f9ea5c80ffb673902f6ff3"): true, + common.HexToHash("0x8de876f26b4645ca6c782813ceb7b594b95baa8c856b61a1628610e90c106617"): true, + common.HexToHash("0xd864a82e52431066d1ce21931a6628d2060d40abad14077f6ab01a50beb61895"): true, + common.HexToHash("0x718d3f9fb54acdc006fae5ea37ed4917f389e1ab8c0e96621995a3d1d72b802c"): true, + common.HexToHash("0xc3a211b1c396c13ad0c5418df64a4755385f77d30e805062fe747e79b93f20cb"): true, + common.HexToHash("0xfef93fec936ad8d0c38cf49370a9e73add6c1c308bd6c10f3b1389d389ec274b"): true, + common.HexToHash("0xb6f466e1212f7abb95aba852f12c1133c2dc8a22d2008fea3d4d51f7253578c3"): true, + common.HexToHash("0x550009c94f70498549551554bc3dd522f707447d3c59dcd102e666de961d63f3"): true, + common.HexToHash("0xefa94ce544b44a0d594f01743a260f9e39686a2757d90d8b222cde512aa42038"): true, + common.HexToHash("0x998b1f850ffbd71989ccf6e67e1ba78388b4b4bf852cee8b8a8ccff6fb9ddaed"): true, + common.HexToHash("0x68e9d70c276e0c1b1838fa324f8376845d57073e080b0e49e549c18d2322abda"): true, + common.HexToHash("0x07082abd1fd686025087c8747698582c5c09794e23dbdd24e786866a7a00d5cc"): true, + common.HexToHash("0xefee4b8ce0ff24e79de268d6d4e2ca60bfc340ae4e3fbd63069bd0a08cad273b"): true, + common.HexToHash("0xce41a56c9943958fe4b0f118f3f510f592c6c7e4a9378dafb13019644fc1723b"): true, + common.HexToHash("0xd3835d8e384b0857046bcc464ffe77c1311ae08d5d4920fa82d324034e8fe5e9"): true, + common.HexToHash("0xe840817be0e558fffc28dbe7ccbd617afb170916c9371947a4ce1078b23656e0"): true, + common.HexToHash("0x202f2854f915410abd97b3819cd2574f885505f5871374eac284ad30faf778de"): true, + common.HexToHash("0x480b045b3e52e16fc15123644479f498cb320fcbb17e30ced0d8248bbf2db332"): true, + common.HexToHash("0xc7c0d4864bb2549646eee0bbf6effc3ed18c9e2b651dfc93fcd3ddbfa2f00a72"): true, + common.HexToHash("0x0164c2231312a024a5fa31c53198d6a4268f7fad64bb2d4b940da2d09cf99f3b"): true, + common.HexToHash("0x6ffd881bfea0151ce51360a707efdff12443638cc72735df90cbb73983943b4f"): true, + common.HexToHash("0xf5d4af92db25dd6f6ba06e8e9ae82ad048be6ac945dac4a9fb6a154c27516f0f"): true, + common.HexToHash("0x9741eaff16e1580e303fe0d58dbd99aa3673750277fb10989e37cbf96b83f13c"): true, + common.HexToHash("0xfe9541774260ba07621f09a0cb9cdf5cf0c736b5dc6eafccc704a2ff30e0af22"): true, + common.HexToHash("0x4e7282b1f7bd9347c6392d9f9500d2e35474d6ea6aaf34618179d3f261a297be"): true, + common.HexToHash("0x238c997d511c275567949889cffece4467b2f74c61728da55b84b8b2efa6554b"): true, + common.HexToHash("0xfb22ca0069fac62548734de3e196e7094b8118feffeb86276ed4736e6ef24f2a"): true, + common.HexToHash("0x4f5f6314c73d562e355cc86572d47ff7c7484476afb08732da9060f808372e4c"): true, + common.HexToHash("0x2716b0ef1518c18c197fe35f5b2933760b0731b71295f369fa09e95d5cfdf127"): true, + common.HexToHash("0x853beac1c1272e0e53ffca57a9cba7ee96a3afaceb171f05aa054faba1acf623"): true, + common.HexToHash("0xd5c71158c0ead7f7b95ed4b4f799a76ef4782cc734856f6fbc20f0602792da16"): true, + common.HexToHash("0xe387f3a98299c968f00c9f88cc5841bfb4c9dfc59efb2f6874164de28536b52f"): true, + common.HexToHash("0x1444c88e8c9f67ee0690d0f94d75304546b594070915655e43e1c91dbbccb741"): true, + common.HexToHash("0x216f731920a77db10c10ac35891a2199abee3b1a663b33c1ffff8419315811fc"): true, + common.HexToHash("0x4f2ca5af4a683ed489ddef5a7f34a35a07dec32e33bf6287abf1f3b01ca91893"): true, + common.HexToHash("0x7f9def093b064b46d2633518a1b10bfb6da72d487637130d9edd9b1a8e56b501"): true, + common.HexToHash("0x8f122ffe8727300074f6299eebdd3fcccdadafbf872e9265768b85911e39e66c"): true, + common.HexToHash("0xac0878717f9e9b3863c5c6072020fbe5ac4589afd5aa8df919dd4a463bb35ba7"): true, + common.HexToHash("0x8c2cbedede5cd93497ebfae436ace89cf47050a993fb27d44bc21dcc9c1564a5"): true, + common.HexToHash("0x391ea233ac77085d53d167b8712a8e9f8c18069a9e7082380a159f0ab841d40e"): true, + common.HexToHash("0xe15ea3c5c0931f8e8bb01aafd2d0f29886f6dc284c2662e21be485a6340b7ff9"): true, + common.HexToHash("0x0d27662706aacc31dbb6900678aa17ecf6f2847abc9005578197a73c51d464ec"): true, + common.HexToHash("0x673c0b3eb95deb3eecefff01b03fba918f304d28a1c8cca7b819ebd842e349e2"): true, + common.HexToHash("0xe614534807d74523d09673ffb6a6635ee5f2120e1a34ca084afcd34cf6446d69"): true, + common.HexToHash("0x1a764fa85a7f416f922fd9990b12dce15f8ddc3704d2ab24b0820badd0519cf1"): true, + common.HexToHash("0x1f6d4a03cdad8d80b1d24d9391da1ac12065cb06c24a052a461094f44ec0b8c7"): true, + common.HexToHash("0xec078aad71726e4dff97bb8f57b23887c56b1f6bbffae2a86d21f4497d166b8b"): true, + common.HexToHash("0x1d6c6deaf847277a67adc2a984b3631be113816dce1e3a20a9c8320564850abc"): true, + common.HexToHash("0x4d75bb07397415d19084334c7a8ad7ee6490c524d57932f553f88366fdecab10"): true, + common.HexToHash("0x64a4a7abd0f9db032104ca8a6f87cc63b24fbb3a94ec5379f5e6a375afb5a495"): true, + common.HexToHash("0x2f8f241bbb7df8ab07e0d937f7ac7e4d04ce010bbe08fa8c72474352a36db3b4"): true, + common.HexToHash("0x07ddbf7bbc813fb3f4f8bd3feb0d7640c8e13fc722552e6678a411015771d063"): true, + common.HexToHash("0xbbd3daeeb96255f4a3aedee8a6f5ba6d30853ff5552b0ac2c9577701849aec99"): true, + common.HexToHash("0xd9bc25309a8828f320b86b0d24367fb1c6b35c2ea533c9823e0f858e3abeba63"): true, + common.HexToHash("0x9cb832ae83afa58e4681e394075b0af34bb063b9c5417bf1ae5359257a026db5"): true, + common.HexToHash("0x61ef71f8dc7fcfea38ec61ddd4b8ac492d42f3bec1859d3287a5f9fd6dabd6fb"): true, + common.HexToHash("0xa23a3360bb65c3e6a153d35678afe2b20f551bc1d7a763ef27082c434682670d"): true, + common.HexToHash("0x672fb77da0fd076668da708b22e6e1c7ab750bc47e3df78d5ad143d0576f21fe"): true, + common.HexToHash("0x439ba36a0c6ec1a1d3f0ceb42212ace719b28015f66a467989c1e7bc2dc8aa48"): true, + common.HexToHash("0x627bcc833c84abcc1e29db3098f3e6dbbcc83727003c10748318765b25143105"): true, + common.HexToHash("0x8dcb3abae76856463d978d0e074af61e970cceef744600a705c6cfcbc97e5851"): true, + common.HexToHash("0x6aa9622936ef1a32bdfe49db894eaa922ccfb44fe0755a0293b178a7bedeb3d1"): true, + common.HexToHash("0x7698e1e3a6321dafe0d67acba305661ab3728ba913f61d11cfa0e64cafa4f30f"): true, + common.HexToHash("0x21a4f12485321acb7ba29221f1df1b58fd1c4b348e4a61d03c4832389f8c687a"): true, + common.HexToHash("0x7c1f51e700fdbb9feb611b29d1bb01988d7cf9d860f93e97e89ed4bea50fc389"): true, + common.HexToHash("0x527efb77deb59ed7a90f82604553efb8a2c38ddcf2f594c0f0c5242e63a52711"): true, + common.HexToHash("0x93e020f5c458758acb846aedb2cc0db39a197ceb8cdd8fdb8806f6aaf1b639f5"): true, + common.HexToHash("0xb48712a81d27d1c012df34a422017ad33a9bb0badc3983c8be3b7eeb875ac3d9"): true, + common.HexToHash("0x06dd66e64b1262d474472b7b2b25e4b7ec87713922643146e5086c043fe0e52c"): true, + common.HexToHash("0xa6f407249bb67ca5743b3b75412c6c47729d6677020b22a2330a1f38ad7da1cb"): true, + common.HexToHash("0x358f37fe82c2ccb8aefacdd26d1b63309bf755986825bad91afd796ea06a8199"): true, + common.HexToHash("0x6ceebad9474cc61b82d72e2a77e0d489b6503cf43ca6ef91649069eb28010ebc"): true, + common.HexToHash("0x550d54e1e918219013adc28c4db84748e8d265a9f5c3b9e60c8c6f8961dcc298"): true, + common.HexToHash("0x7a862b6b42136b3137a2ecc5a69ba4d86395a42337c364412ae26f247db176b4"): true, + common.HexToHash("0xe4001d7ee2b117e3b29d3bfdb9e8d609afd62e5c442780af0a2c3ab87bd09e9d"): true, + common.HexToHash("0x496e367ecfce310d6b0501bc1e7b23bca99fedacdf664e0e4a7e8deff0e04431"): true, + common.HexToHash("0xbdda87c37ad880f9015cc107bab66dbbfb435a74f719c729e5275dbb189d76bf"): true, + common.HexToHash("0x241701f0b6b80a5e2f65b62a49f97cbd8dd552eec037ab1b52adf134eb7269a3"): true, + common.HexToHash("0xe565a5784bd5da650b01320d9687e834ea542e024f23b1d8084d3f735c421601"): true, + common.HexToHash("0x441e0062edac01e48e85d09bd7c99288900cacd3276d3968f261aec886ebc895"): true, + common.HexToHash("0x22099fab06a49138621fe0747084d628e84d2331070a1e1fa5b7eee0cd8a5ff2"): true, + common.HexToHash("0x03c2f6fdb72b89aa4db14bf8f8a46ff2a122966c51cbc17339a573de3ed4deeb"): true, + common.HexToHash("0x4fb5b54dc2952513b7f75016fe4cdb9b265bf97952727ed6e52e5d9619557370"): true, + common.HexToHash("0xad20071855d758e9b766f0fa27ffd5d430b71d4dd32bf30a6212995a2916af1d"): true, + common.HexToHash("0x36a70f8d618c729dcf855352fdb3b9981fe7863d91fbef1973c4243f965b57d6"): true, + common.HexToHash("0xb102af2a6af90e82100b773b5962f84c9188088b9d5fa7e98c50e6560cc147a1"): true, + common.HexToHash("0xfffa7a8a33f2852d77b5101a8fbb15350fcbdb84fa06a790e64a576f917d8729"): true, + common.HexToHash("0xc656d11e3273921dd348e3bc418a076c7f25cd656bd435aef9a463e53c78ce6c"): true, + common.HexToHash("0x052d34fb0e64a4de6975f2de61689be332b33db00e8060d0599e0ae9a57f1d52"): true, + common.HexToHash("0x7bc954b7f437a21d9a34ee07fab41ebd60bbcae44752c561f5e05a9b7164ba52"): true, + common.HexToHash("0xd0a39d5325a74bc144500f8001806b68993350355e4484ca1bba89c227bbbb92"): true, + common.HexToHash("0xb7c171cc07f12d6a2f451254fed35fd1805844f874553e0fc559ead3092bcd5a"): true, + common.HexToHash("0x37ac91e8c48403d6128a931679058a9201e70f6ca17f776abdf2dafd9643356f"): true, + common.HexToHash("0x218a1d1c5100e8f1fd4ebfb45b6aa2ada98cb676a420862e1dbbcc3916bdd680"): true, + common.HexToHash("0xad46a4f9ce6b07ec83a73f3680faa9cb9250fe2dfc3bbbb6017ece56fc4b05e0"): true, + common.HexToHash("0x843e64bbd6d209fa0e308bcb6269dc7c0e3c20bb09839510666bdc222352be33"): true, + common.HexToHash("0xed0756841aef3850853a9d86a504191f9c3cda3f0dfbe5b6f2a5fe325806a41b"): true, + common.HexToHash("0x89f2d89a0fa68263b47506ac7c8b51267b1ccbccd12cc318abeeaba8bd40a7b9"): true, + common.HexToHash("0x5123ff2d7adbaa1518974a7bcb9099841bfb402552503534f2f7f7bf6a968ff3"): true, + common.HexToHash("0xfaa05533b48595c8360ae944826106fe0aa414903a9f18637b153aeda1b2381f"): true, + common.HexToHash("0x5007ba4af329a8161629443a110274a177a9653d676eb4dc501f2cfba36bec17"): true, + common.HexToHash("0xf120cce07b80b4e562dc4e8869338f73a95e6c31775f4a79e3086781456a1e12"): true, + common.HexToHash("0x1109b93a201caab4724a21c9010b082d04f032f7a37f5d560704f4911e32c047"): true, + common.HexToHash("0x41432dc3ef33c78bcfa05bdfdc12f05c131d25ac8210ac1d21454d77f6ca3e27"): true, + common.HexToHash("0xbcab2cdf507117e29dae0500c6d97b567661cccd3b1e968c48fb962d6b212072"): true, + common.HexToHash("0x75cf65a43082c31155cb203d8b78fef9f397cc601e3ce9c715668a0f7a634528"): true, + common.HexToHash("0xf4abb48b68a6f974693b419ecc436a41c6596625493ecbb2520d98f63053e5a4"): true, + common.HexToHash("0xafbb23448be00eadd409e867161174db81dee4c30e6faf40ace26ee3b046538b"): true, + common.HexToHash("0xdabd2b967703987955685adf893f98b3da5f116bf58b524f86d2af2740f040dc"): true, + common.HexToHash("0x98a629405cf85acfafe9f167ac36419fd32f292a8e24864ec118933f4090695f"): true, + common.HexToHash("0xb9fd486bbc709826b5c1383d3aa5fdab278be6262f4fd4fc7ade5c1fa5144d63"): true, + common.HexToHash("0x65a8ab383a2482c0fd958b13e7a3587c1a07c911a723834ce5d044240059e3d0"): true, + common.HexToHash("0xe2fc06044a31d13e1dc72dfd10eed8e020daa66b495bf87a68c377e5d8975ca8"): true, + common.HexToHash("0x0a1346c2cacfc677a1de3dc173284e200b40541c244f8c7c6beafc7c24603034"): true, + common.HexToHash("0x872cc193296e226a9d63a0463dcd720914d7f5b654a8cab414b1102084cac5c4"): true, + common.HexToHash("0xcd3725dc892c1aa01cb9dd9ffec6f810895b23b0f1df360d747b81de0362cc0b"): true, + common.HexToHash("0x87cdbb89691d2093fdc784aa83b816bf70365e8066b03cecefc8c7f3b5568c0e"): true, + common.HexToHash("0x6ae4406f6a57579991def8b42fbba09942d9607df7e4629dff4b68f684d76774"): true, + common.HexToHash("0x964e821d967afe29b7fcceebb76fa0f89a08f29af170ddf73e0019f9b239f89f"): true, + common.HexToHash("0x080f32f7fbe030f8d1416fc06a78387e8a64d6e1b80577a622837c65cd62b167"): true, + common.HexToHash("0x7969abb0d2e685c45a182c6729dfee26a3dedd9af283a863cfc5303e0a3602f2"): true, + common.HexToHash("0x7ae50fe40e932a8833c262b1d8aca8e9384da3d33dd46e74abd1abf196d31d2a"): true, + common.HexToHash("0x2d91cb42864234fe27f7a3633ca7c2863c4b6769a9a19a466b564e96b17fda3a"): true, + common.HexToHash("0x6697dff7fbdf96816c2b251ed1bccdb4b95606efbef94a7d5ef7fb941a7b518f"): true, + common.HexToHash("0x32a72916b6cbadfe33df977130f5e51c72892d1dced2c2da54b274387eb02dc9"): true, + common.HexToHash("0x7bf9d7269e0ee1c041b8d358b40188e504310c0217d5d6b372dbf8532a136ae9"): true, + common.HexToHash("0x635e1ece7e47c2c418604ece16b44ea7e78eb3382aa4c73046d8b69807a5b925"): true, + common.HexToHash("0x3f5c7787dc6144c4276a2d1eadf0ad96aa8cd626596563a7d27ba98f0b39ca68"): true, + common.HexToHash("0x1c417da95174e3acd0ffaef95a22d7f330818a2e509c51d5f3b309b05e579944"): true, + common.HexToHash("0x2fce8d265d0682920b892373ba06667eaafbcdd300908c284e9f68b3758a3765"): true, + common.HexToHash("0xaa824bd89057494ddb011a0a86ce7c13d4eb693206b4057b8a219d41d4cca7ed"): true, + common.HexToHash("0x92208cb90f141c63cc586a72b4ae24e32471737fba2d6d7711c8facff592c44a"): true, + common.HexToHash("0x80049859c831539ca8d367463cd078374da666fe25555aacc35e8f524d770994"): true, + common.HexToHash("0x187185a70c2094a13e3a23b1c3fd9fca76785859a8e409faa3b6924994945c80"): true, + common.HexToHash("0x9b32ab2b6c27ca4250daf53a7a610d947c5a88034942168b7581cbf403820f02"): true, + common.HexToHash("0x0ac291a24477a8e665c8eab4aafd6c26fdd51fce06911511a41bbeee28d6f96d"): true, + common.HexToHash("0x4ad503cadd170be00884c0e0e435e4e52983095231714334a7d7d63ba47fc96a"): true, + common.HexToHash("0xabc7b65a6af1f5d7422ceaa635c6a0d98c0251edc9f65b0a9796005d4beb9f27"): true, + common.HexToHash("0xfb278f6844ef89d99968bb3fa9cd6a31b8d445f56b235aeea476e7fb6b741085"): true, + common.HexToHash("0x65a490df79d6f04ed3d1b9aba6fda35950927a1420c84182a9333a65df8303ba"): true, + common.HexToHash("0xb776942b9bbef3afe2044efc9a9ac01c82cd190f8c0fa3f2527011bd18847d22"): true, + common.HexToHash("0x44208cb9b62ac71c7275cb24150be1389d4acaf94d96bc8c401a0d4e611065b1"): true, + common.HexToHash("0xad94cec8c7098d5c571ef5acd813ef2dae0340218daf76416db6fd46a5cf9c73"): true, + common.HexToHash("0x6fa95229d61139d06c9fd8bde2e051fdb3d9ff4e214f13e00e1283cb802ce1fb"): true, + common.HexToHash("0xfb012d9b0f89fcaac5be1b8041fbabbd50917dff8f1dd0de5ec6e5c155ac33ea"): true, + common.HexToHash("0xe77aec41041672f9a4eaf05b02106df2be5b5565371ad84ac6380e4946ef5832"): true, + common.HexToHash("0x0a85b23c5fc790672667206752ed3372913f3f049315db81e0e77e0a5364881e"): true, + common.HexToHash("0x0778f8b967016dde46030836fbb3c96ab4321cf3447278bff55981ff8ecc4f50"): true, + common.HexToHash("0xbaba7480574764d1b3c344e12999d3071ba96b483c3d0011f5bcd168c2c43468"): true, + common.HexToHash("0x47034cf0c5dc2e6043d518fdaddb715d04f5da4c2320314ef2d31d3ad1024aa5"): true, + common.HexToHash("0x7c2d49a63e606ad32cf711f484e97f28424f3f687390d762387030da48b46f82"): true, + common.HexToHash("0x67a613bb50f485cef1930dca3f59f3e51b367290ebe0700a30d80367a2bcc1da"): true, + common.HexToHash("0x338714105f45c06abdcfaa5815e2fbb03b28c3040d411edb278959698503db19"): true, + common.HexToHash("0xd577c7d8ae69805495c132132b1f7d71e69be7cbfe978dc0ce793de30622a5fe"): true, + common.HexToHash("0xee4e2f2e332feba6fd2be00b27ab52a16f442de3f28c50cb5d9f5fa9182cef7b"): true, + common.HexToHash("0xc4b836efb903a20fa320bc7dd9a74b40631686717b28c1cde9148d31c2c6966a"): true, + common.HexToHash("0x57720494fd0188157f3ac8efdb9cd3fa3065a2f1668f4388a422704a3e1d210b"): true, + common.HexToHash("0xd165e6703af6ae172671209f602acf58545d150e3931da8f4b6829e377d6fc38"): true, + common.HexToHash("0x68f74acd1e90bee096cd064881dfaa52fb3d6c45b6752b15e21484ea4f7ba188"): true, + common.HexToHash("0x40e32032cc7f358509d52c90c3fba1da73623b822f6adb98bbf38cc143ba6e61"): true, + common.HexToHash("0x12ee728c3db1748ffb18396802f8995c997d30cb20c3d27924ae07ed24018be8"): true, + common.HexToHash("0x01852fcb5c2ef1ca1862710c3c508a27a8c2dc05cc02f6d0c4c3ce9139cc73d8"): true, + common.HexToHash("0x2138ca970b9d6478e064f8cbd7adaae31487a806b011c244b4cc2f1c5a9a2546"): true, + common.HexToHash("0xeaee525ee63b33bd50441526bfc3f65c1132ac434b3571e3684e6f97430b7803"): true, + common.HexToHash("0xbef6c14af3b741f4fbf325a7c927fafb6065d687a9a0ece19c90956038db848b"): true, + common.HexToHash("0x621cfade0ec6051af144918e1c18208670b721de1126ce8626f5913ccd54e637"): true, + common.HexToHash("0x776bdd6d8a03eb52f082f2cca127fab37b7a1d985a61283d5299584cebbba9af"): true, + common.HexToHash("0x2ea0ec2782a3eb4000af0cc6c59e64ae7ebbfae0cfc1444db571016b91afcfd0"): true, + common.HexToHash("0x13d3ebb1acbd8bb966f8580acde8654d1213c9dfd498168f3618d85675a65c7e"): true, + common.HexToHash("0xd2dd0e182b793a5826484ed787df73c3d427749721e4163525c8370adf32aa21"): true, + common.HexToHash("0x111eaa23ede75a632f659e825cde91bee4a1d7263b44e53ec1c73a5de52902a1"): true, + common.HexToHash("0x4db800a4a42f745df1f82ecb68b26f264af77f7813ce7158d24efd88abf5d53b"): true, + common.HexToHash("0xeb5ca553b5d6296154e1b3207399ef774a51835f5fd1ca94a7328eeb2144a5aa"): true, + common.HexToHash("0x935868e214a10759587fb140a8bd4e68f73a7028a55ee1fbc90a3240b57a6597"): true, + common.HexToHash("0x6db7ad19abbc84c5583127f99757eeb2f1ccfb7311cde29d1383f872635f6689"): true, + common.HexToHash("0x2aa7befec3525a138fc19ad5a2769d318c794b7e5d30ebaba87bc9725d237ff1"): true, + common.HexToHash("0x9dca456add3092da4a33d9150236ef3c98638c90fcdbb268408decd2ba3f9e2a"): true, + common.HexToHash("0xb5ae6f21c6b06e0bb46db6b024d63431beda204758fda10ef0ba044edff34b72"): true, + common.HexToHash("0xda39c5933da8243d6033ffa37b9f421a759c0bf3e5c5af02ba99d53ce6b7779c"): true, + common.HexToHash("0x73c4ae88b4b754499afa94e79b433ce4d3d9bc746febd90350554484c9c9959b"): true, + common.HexToHash("0xb9bf6f61eb87170efcd2c7a6903cb36b233b6ec9f49b9ed8fc33afe2244d5e50"): true, + common.HexToHash("0x3d361a22efb83629c17e5039cb61bf95248e8b6f23ff3edcc5cb418780fc2390"): true, + common.HexToHash("0x1ef5db2d815bedd6993e37f64e5d4430c7ccbf5f69b3b35c35646ca6b177a257"): true, + common.HexToHash("0xa8320858275e0ff2f77494b5f64b6ff2c8e767815534b96f7cbf148f43efc5ce"): true, + common.HexToHash("0x2a6c707500f2e922106853710e3e63755b75bddcf7328aeba6118d1fd6dd72f0"): true, + common.HexToHash("0xc2e19b3c585619a74116c8600addc1c38e65770a64c8c16b8b83f19545964fda"): true, + common.HexToHash("0xc61b97cf1b2faef84bd8e033abe03ee28d4c9a022db20f9ad91b0c344efc9673"): true, + common.HexToHash("0x2aa83ca94b1a2aa75d01be528eebd6fc5c651c99c2ac4ebfab7a840319e29dd3"): true, + common.HexToHash("0x38e4cb6e5d3b9543529756a7692805e4bbca407d29412d122b8b5d1176cef14e"): true, + common.HexToHash("0x375a6796700b3350d2eb25047a57c9b404fd33fbb7c2868d2bfcebae2783d8ad"): true, + common.HexToHash("0x65a6adae51fbb0f09d83273f48cb3a078fa666bfa348304f448139273b3c27b6"): true, + common.HexToHash("0x3319974dc0bc4ae39dc7bd212c610ee188ef73d25cc56d78423a7f3a31881538"): true, + common.HexToHash("0x1d0eb00e0bb95e101a137c85c6674119a6eecae0396309a841c6b6e149c95011"): true, + common.HexToHash("0x5dea1e052b448597d393cf81f0736fe6fa7f05ea296c1c7690f0c552e2c8a1fc"): true, + common.HexToHash("0xccc20eb1107cfcdba0434813a06d9b36caa42df885718fdb901040b9c9458bf0"): true, + common.HexToHash("0x39339174027dcce2e1c4dca60ed3ac69710716923130749dd45f5c2ded85c3c3"): true, + common.HexToHash("0x2fc7d5b254f1ca15d8bb9e8a77f56191621a7b12235e7f50ec08a802d0278ae4"): true, + common.HexToHash("0x33af0d05823ebb0065d4bfeb155c9fe2591d82fefd7c566289db63b0ddf94ef1"): true, + common.HexToHash("0xde4e31b04914b5852c1d015a33c6ac81c0d79ad97f058e9854b8c9657830c143"): true, + common.HexToHash("0x92519a655b4b8a93d91ede1b592c06cd033454018f1df4c954423acdb0afe758"): true, + common.HexToHash("0x263b822ecaafabe71a780f15ed38e23f62cb97b700b41f0f2d0c0d8bc2668d77"): true, + common.HexToHash("0x4def05da417295df7e8d792d4864bd1cd63dfdccfb3f3a2c23b25291b7248542"): true, + common.HexToHash("0x3fe01c1fa8545c1577a6da7eb8fe60f5a8877caf5701317852e34cfc8ea8514f"): true, + common.HexToHash("0x05c4b7a1bcd804f5ff103aee90bafc61bd66435d2764d50d93b2cd84637407f8"): true, + common.HexToHash("0x52582b8e5e2cd3b22ad7c59c1e40e6da5b1ef284a722f81eeea6ba123b75fc94"): true, + common.HexToHash("0x908186e1d9b4ac9a1c4eeccb43e59d7c49b0f18a290e08284dc663b20b4bd00f"): true, + common.HexToHash("0x36f55f73bb6581e129b1c30f8980d0e9eebf33f570bb03918d8ddca125a9ef9d"): true, + common.HexToHash("0x6b82a524b04d7c0976536cd6a70fd195e72a28ef9d5bcc3ded305714f828255c"): true, + common.HexToHash("0x5da6f21acb855f7498fca77ed948574aa07f7c29234971606efefaaea41ffd36"): true, + common.HexToHash("0x2f46e85a1c13bf6faf470cdab29353f5589b4de3e212cf551c4ececfc2b6019d"): true, + common.HexToHash("0xc065696f94bfb502ae12346cc51acb1c1d2761034a5ec507772270d5d6d0d754"): true, + common.HexToHash("0x71b02011090fd02f15a88fdf4bba0a5316218f3d1785a4eb39269ca46598500c"): true, + common.HexToHash("0x683cc80151407eb815730116076c22a735cb5498c578ecd029391512f8afde8f"): true, + common.HexToHash("0xcdbf1bc7ccdce30e028ddfe6b792692431c0efc9bcaa48fe208bc01452c75ded"): true, + common.HexToHash("0x2161a2fda3c176ff5a670a362c0d8f53c689ed0f79e22ba4b3456575dc9c12e8"): true, + common.HexToHash("0x379ef8846cb03d224f074f3791e1da7dffb04df6b7856db979a6147a33815993"): true, + common.HexToHash("0xcb299bd55304af3ec14fb4b5c9c012823393766db4435fc1788765798fe4db91"): true, + common.HexToHash("0x519868f47aa99dd7c054521330e9476bbf39fa0c5f431e75815aebb7f722dc19"): true, + common.HexToHash("0xf906366dc4d92d2651db3e3a243d3d377dd2c0b180551644af2eaf44bec4d4b9"): true, + common.HexToHash("0x0d32c4b438224e50a6baa1bd78631a52168354966aba0c8d03ec682edb2b7b92"): true, + common.HexToHash("0xeff64cd55a8c72a69850fe915cc9715ad1e9047fce72ae2b40e4e6d27bfd6fb7"): true, + common.HexToHash("0x4fd84ac9681ae5582a2868420be968da36214350e91ed49b778b90412fbf0f15"): true, + common.HexToHash("0x6b6fdd41b6d1bdd0ce748a3603ea23f5a100357a6a4e7a3254db84793052bc1e"): true, + common.HexToHash("0x76594ba712a4de2c2aa110aadc5db5bbfeac2b9e77d66e7e7d80a94070d5b484"): true, + common.HexToHash("0x920e48e4bcc0c5aa5025809fd24fe99544d70d00f499c0f0d577e517cf60e919"): true, + common.HexToHash("0xaf7327ee08f551e56724f0013a5408c1a3a212be2bf1308ce11a5d8dd2d5dfbf"): true, + common.HexToHash("0x324e6909f1e59e5c84b987841e3254f5eafac50ddfec58dc6ae62f09890af974"): true, + common.HexToHash("0x94ef3424f97d7e7a72dda9aca8c3bbb4080e4937e971145325ce29b98cf41ae3"): true, + common.HexToHash("0xf97c70fec3f992b27112ce2ad5e40805cc8dd11c86d2d620c3f92f819918e9d1"): true, + common.HexToHash("0x73010a65be4e723276d652a6ec453f20ab7d2593193a10a255901fde00c3ccf1"): true, + common.HexToHash("0x132876c968259dcc36f7f70998bef3215c1badb6cd1cbe129bb96340929a30f5"): true, + common.HexToHash("0xa63b7fd0cbb87c1eb1716fc50d2e82256940b52ac8245db76cdf264aaba3adff"): true, + common.HexToHash("0x8db8f37585ac19718603e6a1c3076d7f902ece0bfecd57dfde17ebac46c5c08f"): true, + common.HexToHash("0xace176047826d43a0710960755b60dc465848004c950b34346b26a259421a04a"): true, + common.HexToHash("0x4af21138e1f44a89e624dffd8f32cf001317ef297bc3cefca63c998bd30c319c"): true, + common.HexToHash("0xe7cc773c1f2102bfb12d716cd834e2ac6a57daa418ed970b8e50475e2d09ca77"): true, + common.HexToHash("0x20a3cc9423ac468bee18723b0a45c6bf303573723da65d00f5340840bff620a1"): true, + common.HexToHash("0x6660954b7329dac9a49eb92f99f96a5a9087bf6b167f23b5677373b648eed4f5"): true, + common.HexToHash("0x04d796d4d27555b752a1ea381c9f7fb43bfc31b9e679f8cabfef34a2b1e83cb1"): true, + common.HexToHash("0xfdd26065efc5839bac7450c3c48f596206eb82a565cd7da9e9b037d263b2b3c9"): true, + common.HexToHash("0x329a50d9e709b020f6f9ae1621534e048bab50198be4cd954a0a914a04ba7776"): true, + common.HexToHash("0x9540ea7bae114e554641f035d3d2c2ee54757d284191b2a2007c9f5b3ca8b59d"): true, + common.HexToHash("0x6579bd8f0ad39273dd12f62fb6659790f805f920f7713f091739066313d53218"): true, + common.HexToHash("0x1f0572ce90f6b231e132b39d933bc5e680e898956fde0d9e7d14b0d58aff4f6a"): true, + common.HexToHash("0x90afc7be38e46f3f474bfcaf24eb17f5796f6db04c6256e74dd872f10549eeba"): true, + common.HexToHash("0xdda82a3dd81dcc89878c87c14f4fdc6d898f66e135dcf20417db584cd0e55fb3"): true, + common.HexToHash("0x9bdbb329615a2b58624bacae75f749bf7893412b4939d5319e7591402fc6732a"): true, + common.HexToHash("0x4bd3b4c2b323d783927712d9ceccb547f942278877caa6d812f989e70393db5f"): true, + common.HexToHash("0x41476508e488f18d2a6d3d79e582d6122be9d3ecc0e10e64249f4d384f558f19"): true, + common.HexToHash("0x0819d8be3305bfeb07adeb6871a10afd1b9779c965f4b9cccd98527f04047b0e"): true, + common.HexToHash("0x378a36b8220067d8e63b7c3dcdb19d13d8075f75f0df096a6d6d292db45bc465"): true, + common.HexToHash("0xc007268ea20758d8000a0e8b6a38be244335768dcfef1a51c2bb65cbf5744fd1"): true, + common.HexToHash("0xf897056feaff27f7ce5329954d2e7c7b5e088d9ac9d07f84f85de67ed49b911c"): true, + common.HexToHash("0x8a79b48c45dbfbb7c75b151a1779c4f5d794f0d8c0e1402f167efeb8d3e09dbb"): true, + common.HexToHash("0xdf139305edca840d4ecb8665ad8d24d8ed9b5d4aa67d1b4292fd444bcde2c1d9"): true, + common.HexToHash("0x5c494ad150f21387522ab3880476304c8b812800113515dc05c7bc43e1a11588"): true, + common.HexToHash("0xd270f52626ebe648b713d24252ef896fb6db7a8e32e068a8393556b9dec96a63"): true, + common.HexToHash("0x0a80955559db7ea006eecbc1ec39d1ca04111aeed4542e1e5fa522ce215b5658"): true, + common.HexToHash("0x7c1ba3743811cf39e3cac961d4811f020cab2aa07abb81de7a783ee693cc8491"): true, + common.HexToHash("0xe9c71cbb4398bbe6cf9e5b6bf245391c9ae65a4d25a23b7119212e5dd105fa86"): true, + common.HexToHash("0xc67e88a4a0273032e55f771aa0248d93c6aedda5c8def19a2b9c5cab6286985c"): true, + common.HexToHash("0x99021a841e43bd599e87c089cf851bc295823a8772dd7f1e18558c0ce4b6908f"): true, + common.HexToHash("0x04e8fe6a14792d756b8ae98cb23a458171c55fc28b3d02e7f7dd14dbe467b672"): true, + common.HexToHash("0x02e687972e19ac17120806b5feb2be8e6b8a5e626c65ae6a902efd09123cf7d6"): true, + common.HexToHash("0x2d84e956eee66f5fcff860784233e9780a1a30b600c49130a29539cd3cb1bb4f"): true, + common.HexToHash("0x9ecbb0cc5e4e51b8374397d7e3d294956fc23913e02ce21f0c002806df90e283"): true, + common.HexToHash("0xfa1519a44d341db8144b8e9c583b716c094e88a0cc6cf2ec13af2624a5572f68"): true, + common.HexToHash("0x0709de6541474ec7db7c16beccf0eb92692777551dc54f83a6db7292d29546f2"): true, + common.HexToHash("0x8f48009730988649fb94e911a52ed28b37162231e51800cf450b6e45c415a453"): true, + common.HexToHash("0xa475fa1b2301d3197e2da0b6c4a81a6b230bb4e92b2be5e5873a785be09fe87f"): true, + common.HexToHash("0xaf9250d6e2025051aadb4c510b2cde7e2955bd4330f16bfcec8326d174efd023"): true, + common.HexToHash("0xd5c4e2fa7bf356f2ca2b73b712876274d4593dbf47bd96cd3f7ecdc6f91a3ac4"): true, + common.HexToHash("0x18437cd35835103739374625cfd99708d309c27b4904caf81868354bbf3082e1"): true, + common.HexToHash("0x44f7d61b1d14c9d4d467ffb6c6d72951f8fa930d8fd0051d1acef46827ae428c"): true, + common.HexToHash("0xaf88ac115e2465dcd317bd4e7e509c149d2dae8c86af4915d6bf2cd99fbe18b6"): true, + common.HexToHash("0xaa0149c513fcc624a29c945a71bbe8ae3490ff22b9aa3f0b27e281f70aaa71c4"): true, + common.HexToHash("0x70bb736ffd200bde946596f973fc833abc61cd306d66130785fb3951bfc11183"): true, + common.HexToHash("0x0f50bc870aa4d15893dcd125d9e4e89d5b5a8dbe7bb59ae18eb6eba264ee7035"): true, + common.HexToHash("0x714eba00868dbbcbc78d1a96968b167fecfe32b1e3924aa66c83d3a44e318a60"): true, + common.HexToHash("0x0ec019e31c02c02174f43c7053036cea48aa89d59c2c1dbe47afb0c3deb421b5"): true, + common.HexToHash("0x8fa03767c27d3bddb71eb6cc3bdbd256554dc03f304c49cdd6427b3d7812a0f1"): true, + common.HexToHash("0x7f904a09ab23e33facf8f3f9aa1dcfaed65611cec480b15545854b6fb18d3702"): true, + common.HexToHash("0x0e96bbdc348d2c75e5248d97869f3a2eb44ab4f56096c935e3dc0746dcb13e70"): true, + common.HexToHash("0x1b0e95b92dd39529ad18c0291c1d9be01d5e50a407b8a18ac20ad51acfa387dc"): true, + common.HexToHash("0xa2a114be1b1f19252292d4a7650e31a3bf8e24be55989920c2ca221979d2b9fc"): true, + common.HexToHash("0x8f49ce7f567022a43d967681680aa7dbbafb0abbcdf69e112cede4f410e6d2c2"): true, + common.HexToHash("0xb42c559a5d79d2374fad671384c7fb5ed199b0fdff558e14452557accac82c1c"): true, + common.HexToHash("0x4e0597c25a4cccc60c5a95d87e62b88c55ddc234cadf809a04f56456754c4c9b"): true, + common.HexToHash("0xf455c71926a3be85785243c2e095381dcf4b5435dd60737b2bfd39725d3ddc66"): true, + common.HexToHash("0xc1087267dfad1097624c905b655e24bcb1dd1d5b673629655725f6caccd4a9d9"): true, + common.HexToHash("0x5d88d4cb02913d8ecf17a64689bf2bd97fd68b8f23a584fa9454fd1a2fd50f53"): true, + common.HexToHash("0x141d03aef998d9ab58ad25b6d5efa0e8571acf072eb61684cce755c7d0b153a2"): true, + common.HexToHash("0x2dc94b86dbe0e528f299fe352ef72d154b2c6b0be08276c27bc590ed6347e438"): true, + common.HexToHash("0x152104d93b457021d914b269daab2f7b6e6ad57509ad3de2365c006bca323428"): true, + common.HexToHash("0xb2170f35864653a894a086b2695fcec4915065422dc651d5e9025cbd9002fef6"): true, + common.HexToHash("0xfe17a92ddbf8eccb10b4320d07f294b4d102545f6e8122f1ca69c136b2ff572d"): true, + common.HexToHash("0x9c22053e87afbe1c686371e16226ee989b20bfa40edf87e0bc302e25c653e2cd"): true, + common.HexToHash("0x2dabf625db9184b5443ddb3afa8360b588f70489d6d3ecb605bffdf9ba7587b0"): true, + common.HexToHash("0xa7dba7c9866fbd0f8ccdc2ac0e4ae64a05fc9ef9ba68be592934573629c6b94c"): true, + common.HexToHash("0x4be51d69813b2f10a754927c43980745324b85455422b37ed20adc7e6d589873"): true, + common.HexToHash("0xa38f3ad40c9091c13aa39a0f5d17838950346d6db7b3739167aeb97b5b21f787"): true, + common.HexToHash("0x4a7a81eb58918b51b1ee751eac855fb6592061e74f5c5e8bb80d0a28ad08bbf1"): true, + common.HexToHash("0xbf18c671c3017fe2564b40cf9aacc8fb1f9a3b577b6bb29e7cbfe28caa50363d"): true, + common.HexToHash("0x8c0b3b6e9f4e6b7560757c6221e40fc08fd5df6319bd23f38035fee0b57a2bcb"): true, + common.HexToHash("0x1941ef6e0184f399febe5f5c27f96b7b44b949e15a944434c56966e86cae6997"): true, + common.HexToHash("0xbcac44d1767e8378f0c7dce850520a9e8b9e7b1c4c42b12d5431f841e8d3707f"): true, + common.HexToHash("0x6f56441d16799792d08f774e8f13e225c98c008a0fa6b6f1a601dd0e3d12ab11"): true, + common.HexToHash("0xd7f8e9f49675642e8265b45fdf12b18f473fa8cb2613088723b7b0342c9ad6de"): true, + common.HexToHash("0x6c78d0c61b7c5595594bd95264114b6d75931668459fbfdbfaa2bee36951cd69"): true, + common.HexToHash("0xf72a1ef487217354ce3ed6763d47a70db1ccf39606ddbaea84b94723dd68937d"): true, + common.HexToHash("0x2f9d31affa2b62c4e145aa7914f120e7a730b4f7226d048f364751dff794a1ca"): true, + common.HexToHash("0xf63be13b50eb711bcea5356e78e0658472c1e0ba4bc1070dbbbb4ec39f42d8e3"): true, + common.HexToHash("0xd0252dc75cc0f87e7bb8ef4a792f80c7fdfffcd356e9bd00a5ecf6c7d89f3f4b"): true, + common.HexToHash("0x767f5276b3e65a742c26b2db14d8daf34b50ef5f73b8f3b22702b787573fea94"): true, + common.HexToHash("0x8fed9a4e8c4f511794fad61c0d4d6bd192e1e1236aad2f9a9f5ad5612f053339"): true, + common.HexToHash("0xf496e1d9a75a73ed59c992cc7fb02a7391552dfb37328976b3b65404a57b1f0e"): true, + common.HexToHash("0xc9d4a422e5615219de9625f6c93bb02d761311d3f6b902bbfbc50d4fe9008d95"): true, + common.HexToHash("0x95f0637fbfd1ebc33358803b7ceb31dbfae79e9fb42f7b79126e535a99ad0864"): true, + common.HexToHash("0x0ca41561b475fe1489ef5bf4f4c1ce41f83fcb846ae89ed091abca444efbdd3c"): true, + common.HexToHash("0xa8a175486f5473cdf71b3062cdf2392c8056346ac108d8ddf17cccfadce90171"): true, + common.HexToHash("0xbf4d15bd2be946337580081046294f2ec0d5b7f7742ae110b48560772932007e"): true, + common.HexToHash("0x7ae7dc3146e3e5ac5b738c2cc23a0fcdb272857ec98990138f631d429bd1c10d"): true, + common.HexToHash("0xa37071c292580a29b841673e5c7ae17d70325f46e189123575d7d61ed46f1530"): true, + common.HexToHash("0xb66f2700ec1a633b63b1e73916b7a9d636737958dadbe05cac8ee6b534f1c2f7"): true, + common.HexToHash("0xf645964ef20d3ef805cbebecc5ba93a783f68c27bbde2e67e4da4357e452a0d4"): true, + common.HexToHash("0x2237bd81f9e417ee2acbcc511fa8c7bafeb796f8678287cf6433517782722f56"): true, + common.HexToHash("0xb6aeacaf6ce291dd2236b57110e61eddaf917bfba17fadd0b6f042b110592a9e"): true, + common.HexToHash("0xc8a2fe36186333753b09e9d673bc95ece9da81cf3877c4063967388d1626a537"): true, + common.HexToHash("0x236c2233f20d3e3b329ee048e077c94aa935bcacbd70f66182e3aad782c6f3dc"): true, + common.HexToHash("0xf21d46f2bbba64ea47dbea8fa145098360e0982013522c5ded753a412dd340bc"): true, + common.HexToHash("0x76ea80caa75f500ffd48e07925f470f62610d7d48e138736c12a3e430471a5b6"): true, + common.HexToHash("0x99260222f48cb3bd556d5d46fae19e486be1cc371eb2c909e63e931311d3567a"): true, + common.HexToHash("0x73b6f18fcc4bfe6930965396035a8201bc9c350b0f9fd5e13b016823c21e2f63"): true, + common.HexToHash("0x0720f1b621bd0af931169b9fe6b816e7d1f92b3d9ff72fc66251d163ec7acaa5"): true, + common.HexToHash("0x0a0239449da56134e61f578fa0e75f017ffee3802780915d9d8b0a146fbe3aed"): true, + common.HexToHash("0xb18ebbfc0cb685744c96934ee013880126b4123a591ff17b51f25b16cc731ec2"): true, + common.HexToHash("0x69cb1f04cf70b8168b81ea35617bb52f960eb9cffee8616cf5c87a46b83f05fe"): true, + common.HexToHash("0xab1cae5752ebbcd1ccd9d50bbfe573ad2d4cee2f5677f72a3a6c26e411bdab29"): true, + common.HexToHash("0xc98101b31bb6318efb5e259eecd9efb5d46a65b64ed8ad02684b46a5d169fe14"): true, + common.HexToHash("0xfe45e582ebf56fc0fb9a30b866f7821f6dc2c0f3809610424919ed477469dce5"): true, + common.HexToHash("0x850fb4fcb1c4eb1751bf8bae419732c8c7ac4272718c094af181a7b748419401"): true, + common.HexToHash("0x72b46a829e420d358faeef57f73e4986aa36e244bf33e1a766392ec838786392"): true, + common.HexToHash("0xb8408e13e11f4a4c02fc9fbfde65123cc19149e29b70713968ab6ce116cba653"): true, + common.HexToHash("0x4c2d7b44e997732c71296b87125044eae2bad3cd09f0ef7e8bb9eef87f779637"): true, + common.HexToHash("0x1ace21d7a3f7b3060261ed75f7d234d3fd66171411b6fecb05d6f4373857adce"): true, + common.HexToHash("0x9457e350ffd0ac8ea148089b37c9586ccd63284897795bbfc10efc381e416371"): true, + common.HexToHash("0x367fea4c7067e37dea3c5d27406872dd17e4e63040b12ef24ea1e9af866c17da"): true, + common.HexToHash("0xc6539dff3fa8e2fab045b538a9ca5b6b0cb1023ca58c7218a8852cc20ee67c46"): true, + common.HexToHash("0xbbab7d38146306af1e1b1f7a8e6c9368e75f9133a6ac7b88d02a296f90cd865e"): true, + common.HexToHash("0x54fe9336e2ba28b482aa3b78d2a9deedac82f1b25e4af5f5a8b769dc13693aba"): true, + common.HexToHash("0xd0d1777885ee8b011c7c942353efc5cf7bc02e0a42f63c4257e0e8fac63396b5"): true, + common.HexToHash("0x77fcb73a880654dd68b91af8b24dff9e7c28be7a19e7ff82de34f6de2f2a93b5"): true, + common.HexToHash("0xbe6a4feece860acd4bab390d2accb58fec2c03b37a798220017182e81a903f67"): true, + common.HexToHash("0xb5118e79d4775200c60de48978f20266f97fdcbb33c3234d08458d2e2e724813"): true, + common.HexToHash("0xab575b85d3f0716b3fde4e4277ff5244ae245dfd07e05622735e7486a5c61e61"): true, + common.HexToHash("0x0d531f7ed4af9c55edf38af1e7429514a45b5f16e8235829bce2ea65131673b9"): true, + common.HexToHash("0x6e76f60befb34caeabd5566751e93e46874d3694f9bc33b4df815b889c0297c2"): true, + common.HexToHash("0xffdda7dbd2f5807112f8b3988c0b00c747050d31660920886f39bae1ea5677ba"): true, + common.HexToHash("0x113b641a382cf80ca9b3dc2b072a8056d376b46d833589925531fd4e9f100b25"): true, + common.HexToHash("0x2ac59016a2937b12a8547f9ff0c02fc4a0d8f205dbb708ccb0f8e5d4745b7c34"): true, + common.HexToHash("0x19828b0320cc981ecdec521b0c7c72e6730046aaa6226e0e83128d3c51f1881f"): true, + common.HexToHash("0x8e6afeb54901d4349724a43eef7f2f20ea785ecd1b44d125a5ec14936ca276e1"): true, + common.HexToHash("0xe5d8a43a4e62c17d1571028813f301e093e79c857bce0fadb0ab52997bd1af60"): true, + common.HexToHash("0x798751d90ff2b90c29ce30757ffcb6ff11fe3acef5bb580cf71750edc90be2ff"): true, + common.HexToHash("0x33bf9bca4c6dcff9b17e35f9c8222870cb8e9da1219d2df8363ff7ef258c6b93"): true, + common.HexToHash("0x55a7c1c776cd43cd7e0a87a63ad575bc357323686b334a3852ca4a2761b36665"): true, + common.HexToHash("0x0acf57138ce7c71d026d6e476cdccb230060f846be59c2ee323ff076582d2a3d"): true, + common.HexToHash("0x0c8d1f7da83ca5bc0abe1199fadab638008301debe142a27d14cdc1f54d2a3e2"): true, + common.HexToHash("0xffd209bd5681e7e74b99e47b73953b19154db764714bfa4df9590e8875e07175"): true, + common.HexToHash("0x21c70f56a2bea486b26d8565285e8b8a6e85d2a16cb5a0e57c95dfaee048e5b3"): true, + common.HexToHash("0xade1bb9ffa5d52d1e12d9ddf003235e8983809639d2462dc373c0d920efe634b"): true, + common.HexToHash("0x7da2f3e0697b60d693366f882806d32ec35af84f8c2c8bc89ece7774557202df"): true, + common.HexToHash("0xa5650fb960e886879216da22eb9ea63177aa43aa4d20e198ca472da8f5e4a32e"): true, + common.HexToHash("0x7e6f46506189270c2530347adfe2456491cb07cb07bc4ac511f5c545ad6724fa"): true, + common.HexToHash("0x05eaebf5429604bf2f0b92a0d7d0636a8173611988ef75129d6de22ce583a8ad"): true, + common.HexToHash("0x18403c144f4380bb832711050d53bb9d0b43b830946bf2cf074174ea122c1fd6"): true, + common.HexToHash("0x6f762831d67932f41005194bfff0b49ffa4839f27d9e55d2f68a6bebb4148be1"): true, + common.HexToHash("0x24fa2624b6a73fbbd3269f609084e11f02a9a0565ea1cfc955dd08bbf4e93e8f"): true, + common.HexToHash("0xfacb2c4eaca0e6b6bdf46bc2fb5a30941b24261539f6d1aaad6af48e7e32eb99"): true, + common.HexToHash("0x3e80095383eab9070b2da41bc76958c859cf886ca2cef3b69b38634ef60e643c"): true, + common.HexToHash("0x477967803c32f9d8810416166a0d0c70ac96f29baf249538c833d1e15530ae34"): true, + common.HexToHash("0x0927b06be7294189397752bfdd19d7fdca7d9fc50bae4a7dc4acf0aa0d7230f2"): true, + common.HexToHash("0xa0dd365ef949e23081af76677063b44fe10525e5212c7bbe7e263f3b7603a615"): true, + common.HexToHash("0xa8c5693a8d9c5c32d9fd133ee29fd9436cc21febce8f7883d3f5a403cdf5a521"): true, + common.HexToHash("0xed20dc09ee1b78f068d2fb2fd007a42886dec930677ec4bd31bc02e827cab788"): true, + common.HexToHash("0x45eee8aa5889c70fc20621b016d4ea186cd59c3b683a6a47cf5de4f455436cea"): true, + common.HexToHash("0x92c379415f9d010ba059b36ac210ead9dc42f3dda5f890bcfbc4e3714f93af3e"): true, + common.HexToHash("0xa3e2ce9ac33f84cc78c640ce960bb62b7fe1b885013d0ae634c8012842ce7423"): true, + common.HexToHash("0x35d8be25d67b833356e6db1c3e33487129e10a12635db5bf13373c875e4cd9b3"): true, + common.HexToHash("0x19b10401c0e9dbf8ad02031358150815f02be90f3083c67b604d9df9aca03085"): true, + common.HexToHash("0x88cbcabd5b65606416e048856b8d7feb997bb93f525e474d3cceeb300d74c303"): true, + common.HexToHash("0x7d866fbf1ac745d16bd8431993d2c8bbcd32fd7bf3a01459f621fd2d49470cc9"): true, + common.HexToHash("0xb2ab4152f2bb2d4dc7af2fc11b89583b2c5667030e576b6497a2320ec035e5ea"): true, + common.HexToHash("0xb5d8a759c194eade592e518191a65272de336c84f7828815b2009f430aa0d83c"): true, + common.HexToHash("0x5bf47b95ceb2890240f5e9727f220fffdca54bd3c74a70309d08e30840fc8294"): true, + common.HexToHash("0x2cc20eeeeb24da41fb117a737c9f9e0d9de5c31174d92ceb7bd5edc3f42929c9"): true, + common.HexToHash("0x18e1d36315a8c6eb112fffe382dbc80c8cafb6a89151bfec0b3b917ca5c9946a"): true, + common.HexToHash("0x3aa2ff15a88fcb3dac4533be81cf47c72c92848333af211906afe50abeb460f6"): true, + common.HexToHash("0x7c5e81c71b1c246f8965450aa566ae08871e8c2c01d2eee3ed5dd41ee5e8a212"): true, + common.HexToHash("0xa5ad4b5b823393d95b2912834ad1a0a9d0cf1ba6df916fe86a749f6140e7546c"): true, + common.HexToHash("0x350e68fdbe02ff6673db3b27fb7463031de915dd4456f7e0539bde3a0afa1057"): true, + common.HexToHash("0x5b059f7a093d7e9d09e98919313c0cf006e7ed6322d7f9a4aed53825ade18351"): true, + common.HexToHash("0xb89ce69a3565a7437ea9d6f2ece9abbfaf5dae45a6c131190d82925c6ccdadb4"): true, + common.HexToHash("0x03537fdb3a1f18dfa1296378ea0971a223cfd3a0fdba7c2521d9f6ef8d9e3e34"): true, + common.HexToHash("0xd2c6aa5333ea92b90bfdfb861fa9cfe7aa5bb6e332394a018cad4117f4aff8c0"): true, + common.HexToHash("0x883c926c333ba672a5abe2da472dcd07ee8e020a309028381d5788439f106852"): true, + common.HexToHash("0x2579d36234e157edeb3a942eb34439875b300bbc926d5ec8e6daeca9a9ee1fed"): true, + common.HexToHash("0x68d43eae0b1d199ad4ea7b15441e0d3cad35e486783929c087f4fa7ba2d8981c"): true, + common.HexToHash("0x59726a2de2a2fca17762035a9c9d24676632d491789daffd54c60362f658a5e7"): true, + common.HexToHash("0x744b586ad046af154e03b5cae4d987b291b57e19f73fcfa64f68e5481439047c"): true, + common.HexToHash("0x37170b687acfd1c4ee47bf7bd2643a21ae115adf464b153b379f01b9bc4b7209"): true, + common.HexToHash("0xf4fb8482b1327786894464857010110b3443f531c92f91060ca0094b7dc14295"): true, + common.HexToHash("0x3e5aa87cbf3b4f6e52a235435ab02c9f7899854da1a5fbbd7c221241dee004c0"): true, + common.HexToHash("0x61146c1ffcf32786ddfbc9575db6724978775d572ac664a789ebbeaaed6ae07e"): true, + common.HexToHash("0x2d82a5e6fc9e6592db788b8edaa8fab90cbda6bc0e0194144c4ace0ab6b6a77c"): true, + common.HexToHash("0x6b76b008c36a54d4ed1b739289d22650b3857899aef883eb65126a4d4caa201e"): true, + common.HexToHash("0xbcef001ec8894855d90c6d22d22aea1c97cb491d4dedabdb8448242d53b26185"): true, + common.HexToHash("0xa3dbcdb22bf72a038dd3998ade312aa6a8a7d541e37bc5b1f4c484afcb3aea2a"): true, + common.HexToHash("0x1e24d23fa9fec24e99d193f528a42d7e666fd6254ba72f663b1bf60ed4990c8f"): true, + common.HexToHash("0xd050817e5ad5b99126c3b84762143e5169c93cb56b744d372ba4f464c532673f"): true, + common.HexToHash("0xa989f5f2bdb3d4d492910586fb9c8c754934d4dc5074c6d84466ee51cb5b9cde"): true, + common.HexToHash("0x82a36b9f388405119c1bc8fb6d014599dcc833ce1d37892399a98ac0d70fb783"): true, + common.HexToHash("0x67b8413e376298ff3ab5defd8eaaec3b66d78b5b41022ff2748516bf97b7c70d"): true, + common.HexToHash("0xa634c929b55bd9b7d726d25c31c824d75abb183359e456665b9ba0ab50edb725"): true, + common.HexToHash("0x3253da4e2ac5a133c7834439b20702f44ad2b58de9e39fb50275a5a5a007296e"): true, + common.HexToHash("0x73f3d07a57dc2e3baf13bfa7c4b5b1dc6dfbb0d79ff5d13ac797482a2bd65b0e"): true, + common.HexToHash("0x8e3780116d48096466891db19b5a24973de96a723d5754b095df049bcdf562a1"): true, + common.HexToHash("0x3f2ccfe2ccd8989c241620e4bed556e8b6dff0ebe312f4d25311aae3e0e61ea0"): true, + common.HexToHash("0x713af0f6b9922898656ecbf49daf5f79d72a6bb5e3b078eeaff4ce54cb8fd81f"): true, + common.HexToHash("0x46dedcb7ec4def9956487a2d7cf8bd30b74cdabf585b00e6efc37c38e84b5154"): true, + common.HexToHash("0xf68ccd0cc1bf07a545d0200c77fcb06b504cffa187bb5c375b535c8f8c9305e9"): true, + common.HexToHash("0x639535f1a7d80bb0003748589e71c0c050702526cdbf243a6432c6a6ad734aea"): true, + common.HexToHash("0x7fedad28ef88756f9c80e5aea990c430e6a4c614b24ae125ff253eac1577147f"): true, + common.HexToHash("0xfac2a4b7001bb409c664e3e4e4f89f248831525ad16c5b6369eb860885635ed8"): true, + common.HexToHash("0xc3d8a64a1eb3e10c21525a7990e464fb76d94dd76c052daa0207c566f5e4d6ca"): true, + common.HexToHash("0x16e5d2287e000e04f0c95829a0ceae4d368e65c4d17dc07b409eb61273fd5af9"): true, + common.HexToHash("0xa8fb1e0f911e8db0748b1ae7d1d31d59033f310972f8b1201bdff8a22830c960"): true, + common.HexToHash("0x5dab9dceeba3c2f5952c50cb9ecaae771fbdb0e6fc5a5ecf70cc82a4c8725e5a"): true, + common.HexToHash("0x3910f2d251028604054b11859f3592f29b66f88a301d31654c53eaa66fa37723"): true, + common.HexToHash("0x9fa0f1f2e6932d52451b3acbd1e057786c3bf9550b5e6cf37f556a8f79eb4474"): true, + common.HexToHash("0x148af6c278250b7c97deeaa1289fb191eb29de28ee42051f9c969f7342e8ed56"): true, + common.HexToHash("0xdb3a596e80218e6d142b52cdf61851e43899fbe89117f2414056da3568a0ea5f"): true, + common.HexToHash("0x244a347bda56bd37fe5b8933730e0ee84ff15446d79a0b793410749628c457d3"): true, + common.HexToHash("0xaea404f865288054dddddcbbbb31fd9090a601b116e0ac120ab4c892fb47b65e"): true, + common.HexToHash("0x78bf89ee09ad288c8ec2e87d1bebe5ce9b58eb5af4d58c1a856ce43f97fcba25"): true, + common.HexToHash("0x3572859acce625f32d70d77bb17535fd972eb30394eadb19806f02998baf141e"): true, + common.HexToHash("0x64a1a22bf403286db4b39644247061b7f5c6781e5c8816d803cac6081b55e446"): true, + common.HexToHash("0xd9b6ce7d25426f881cf1cbb1514a2ebd8119dd78ddb0191154d5abd76cdbac15"): true, + common.HexToHash("0xffcc72ae29d918b6c9f1e58fc46330d34d45cfedbe44f86852939cb3304115c8"): true, + common.HexToHash("0xb9f1cd17e97472d860ccec788d277601b941a9485722a8fa3aac64a0da99b3c2"): true, + common.HexToHash("0xd86f39ccb91129489184c847a46e762920d686a8e9ba9ef42a74c386de5c28bb"): true, + common.HexToHash("0x0bc931fc592408190e47c2c2fed8331cef1499b1a81a292b970711928f2b9d4b"): true, + common.HexToHash("0x0bd27ec62641913813a6b650fdfbafaa2d8f2fc6d2059cbfcf5868eafc0eb997"): true, + common.HexToHash("0x8c81af7da6a9a68fd6d34e9f88fdb523134af357d683815bf0c576176b6f5cf0"): true, + common.HexToHash("0x179a4181fa1871a7e211cd94b4f754d577ad53aa0b15ee822cc5e0532f243fdf"): true, + common.HexToHash("0x6da114df55e8a7a95830aa39a4b28da2dacedc1020aaf23d846032dd83f84f50"): true, + common.HexToHash("0x1d1ef79cd1901d56838161136df871c5c96b2a9841683da30b7f37b2331e6a15"): true, + common.HexToHash("0xeaf11a62980effe9b1622168870b005a52695ddfd0c6d52d0ad7cde2158be9b3"): true, + common.HexToHash("0x80bbb4db938a157ec217a9eadf384671eaca03fcd57e62871b9af213afd9f059"): true, + common.HexToHash("0x590e02b4e4c6f8e1338733b36837a80e33144ade856e8b27d4cd4616b5fcbf49"): true, + common.HexToHash("0x9415e7b9cf88d8bb72f8608fae85f3021d595dcb36acc4881d1941baf6ea2e3d"): true, + common.HexToHash("0xb44d176b038f9059da5b4a62ed328365fa5b98cc687cbc28f2a5e9737368f4ef"): true, + common.HexToHash("0xb5c1608cecf71433cb507f0e7d66ae582d3f8056a820764ab764ad5fd3e1fda2"): true, + common.HexToHash("0xa9e97299b7698f3ae23458ca69a5ff267c57f5628f495513066138b6c8306293"): true, + common.HexToHash("0xd70daf2f5162b4880da9b2be3827c56a372ad4d258bc5060444acbeb31c2b878"): true, + common.HexToHash("0x7f86869a6e581aaa8332249b962c260a0f29bb172dd99cf64ed0c3b641f82e43"): true, + common.HexToHash("0xfae47919914e93aa3e3b8e7fd36daf145e3a41ea7b76dec1c61a1b5f41afd809"): true, + common.HexToHash("0xd7ca1770071adbd2acbc02a2290732f2b024ac80cc01583475583746f71974f4"): true, + common.HexToHash("0x32e2c95c405acb39554da71c254a44c373e5d1018acc21ef0bf1eeff3906d814"): true, + common.HexToHash("0x7716be1a7bd4863d93eadd513e40f9dcd40352d9734d0b5d66a5c588e8997e77"): true, + common.HexToHash("0x34bc2ea7095b4b8d5d7cbb81eaac04e21bffd0af7ddf52327894254f53ab342e"): true, + common.HexToHash("0xa43d1d21ef4b48de0ca5924d8d7bd0811bd4bac6861976c9429e478d24c21a3a"): true, + common.HexToHash("0x780ab503c57887c5558c5083911379013a8407e7818617ca2e87177a21c8a689"): true, + common.HexToHash("0x3f6970d898c5761786e1b708367c0f3fa2a64c3eaf234ceb29d18252ffdeb378"): true, + common.HexToHash("0xd7f98a68d4d7d2bb32d546cd0a11001db2b6f341f92f72ca34a98fab7ddfbc13"): true, + common.HexToHash("0xc36cf2765c80cecdd1010b849a8f94e2f8c23335a43cd9a3a11f62369171421f"): true, + common.HexToHash("0x904830500f9c9ff58f57873346e210be4049af508fa539b3476835c8cc0dd879"): true, + common.HexToHash("0xeafcaae7452a683274851a5aca546c0421b3911d0648f0b67b027d22c2dc2fc0"): true, + common.HexToHash("0x7d874487fc41abb071233f3851e87fc5530153a49bad6b9c3d84bbdcab710f72"): true, + common.HexToHash("0xcaa4ea936ae48fcab50e6ffda0e8702db8de92ac57ac6391bde4a96ac4b117f5"): true, + common.HexToHash("0xc36c5e73eaafc50c5fc43a0bb32e95b938fa287e7d43e741ef5e88e79dfc78b3"): true, + common.HexToHash("0x74370c278f002286fd4541460074a858be253c852424904b99f30f1c0742aa9a"): true, + common.HexToHash("0x73db54b08251674638447d6d145674bf6e39b892151380f6a176320eaa1ef655"): true, + common.HexToHash("0xee6ec48b7b7808dba0fcbc791289eca0a84382c6e5ae35353f8b2bc2b7d0f428"): true, + common.HexToHash("0x5bfb047788e6961119207ea10473640322f28c88dc16f9b2f9c2a2483cf60f3f"): true, + common.HexToHash("0xe286941284748b10ad4f3f51c3b0cb869b4b7be51bd87ca9d64dff56063827ba"): true, + common.HexToHash("0x5567745614cb17cc97e688d8f0b15c1936931b7c9c1937f1011ba8bb4e61d830"): true, + common.HexToHash("0x87ba74bdf5dd6ae6d45d1d6ae4aa31af364e98a1059b0e75cca441402bb4efa0"): true, + common.HexToHash("0xf9dc6df532fa6bb7790a794590e1d40f566e254f0219464e4a730b48009195e0"): true, + common.HexToHash("0x8159dab08d71d8b479a4cbdd4c2c6b369df9a131e5c74b9c14c2adcec2744c39"): true, + common.HexToHash("0xd12edb645fa6aa71902fbc415fa2db39f1602735a7bc425d8548212128793bba"): true, + common.HexToHash("0xe5203ed06219bcb934751ae0a9e4744a914b04248c460853f6b99b16142a9720"): true, + common.HexToHash("0x4c34932ead183717ee227516f256b40bd73ecad4819c60406805d0420377f0f0"): true, + common.HexToHash("0xb282b3217dce3723d6a982f8ded91e59ca335fc27610523390afb345d11baaf1"): true, + common.HexToHash("0x67b6db72f7ca9d7695af6e4aceaad3f693505e5702f6e1b42a9f8065868bc6f4"): true, + common.HexToHash("0x71aab0060f3ae3c8439de215641af042760a6d624c6502b033f2d59c6281a736"): true, + common.HexToHash("0x3e95c467e590cdfafc7a5adbbd1487004b0dc18260387f2f5af15c1e011ad668"): true, + common.HexToHash("0x753fc926864f08226f028c08c8dc748e0340431e64745328a7c1e06e65eafdb9"): true, + common.HexToHash("0x2d49d765c829f249c6b629dbf54ca1d54376144bd4c488b1edd30ca84200c368"): true, + common.HexToHash("0x530712c7e6a9f970fa0d83c3b22ad6628aa109f4928f5460870a9f9aaff01dc3"): true, + common.HexToHash("0xa8c4d71003d470b9536f17c11e8336554e7a8706adc6d8681370bfdf36fff70c"): true, + common.HexToHash("0x4a2e9e00fc6bfc6fed3da6410d0856998d57d10261cee22cd4427ff91dc29eb8"): true, + common.HexToHash("0xabec3bb820126376b052aee6f343063a4293c53abcbc232586fd2bb1417b3b28"): true, + common.HexToHash("0xba818d15e0843d0a74f3297a396338c86b8c12c9e087107cc686c3b5a4f8840e"): true, + common.HexToHash("0x272559357d7cd41256f125dd4aa728ecd28772783946b31d2b2224101ed999e2"): true, + common.HexToHash("0xa1bcb8240496986ed64f22d7590c67e95be7a63c27acc51ab89684f7b5e0713f"): true, + common.HexToHash("0x423872f6692c6405821ea768503e0b6923231e4b9ef6699451334a4e3e4d0d07"): true, + common.HexToHash("0x2e8b8d10d77b44430f574d139858ada53290a07bc6a6f5d9508bc7a652ce515d"): true, + common.HexToHash("0x9c593aa7430e8ac3b44e8e68a90a8a6df48b5b30427f97f54ec1d563f0209564"): true, + common.HexToHash("0x6efb3bfecfd8d61f402f59f796bc85ad18c9147c08e4b059975e63614656838f"): true, + common.HexToHash("0x4dd40515bcf97067419544de7c2a51b3d5448edc0cf33c9ef9e16edd8ad81c40"): true, + common.HexToHash("0x127881f7194a24df7cd33729dcd11947e16564b3cb43826e0cbcccb6edc64797"): true, + common.HexToHash("0x9fcbd5808133ec75924608286a25102769b4ae8a6b10612ad129508ad816a412"): true, + common.HexToHash("0x837782653e7f39e0562326df35b4a8bd27bbc2484d2280e2a150f694fa4cecae"): true, + common.HexToHash("0x4a4aae2db561b4469ac9bd09d1ef6faff0850928b007119ad9dedc61c6f96da5"): true, + common.HexToHash("0xd98b7842c6c80cf02a7bec2f236a33647cd3d3f741b38479955f6a474286c570"): true, + common.HexToHash("0x52a3ec60b44fdce888d98190521a7be54d2687452c55e34ed4a3853f241a18db"): true, + common.HexToHash("0xb38737b99a6a62b78737b99077f7bd97f4398133f8fc1a45c1eb7a3b6bf41870"): true, + common.HexToHash("0x9e5840113b4e33f2344c316317c7ce5074edb2f32de3f210f9292db3d08878c3"): true, + common.HexToHash("0x9bef2e9a474fc1c9bf4ccbd404086fa45297e79565f8c8489abc2f83aec8f919"): true, + common.HexToHash("0x8591daff901a9af8c159cb7ac2cd09d510acaadd862ba736a55c2975eb7f311a"): true, + common.HexToHash("0x7bd9d9cae7e4a8898a91cd529f363ef747b94971e4c2aff877be519f8da060d5"): true, + common.HexToHash("0xdef544ef68a49bfbb7028b21bf08236e17da6ec0aea77a1b0c41128e8b199548"): true, + common.HexToHash("0x5e8045220c20d39ad642f1808efa9278d9ba97a10b08b494ffb09091bce51f4a"): true, + common.HexToHash("0x772aa4690924530d44f79e338126f05a76366fc47b804d82f1f534755fae5797"): true, + common.HexToHash("0xd0adb4f7165515e1e9df62ca36f9f214b3822eec5f703d25f8c4058b1f35b2ea"): true, + common.HexToHash("0x990748ad0f88c0866da150b4575777ac213e0d2f4345729adb0febd095f51a84"): true, + common.HexToHash("0xb6c38371b38c930c04e02a97c77d6013db12843e9c4c2b88465c49079f77d3df"): true, + common.HexToHash("0x5f9e9afa92c4c1d42c6dab7538d77254049138a9c765a28fe8d1fba724101dea"): true, + common.HexToHash("0xdbc3e3724d496986eec72f360caa8c3ae83279117d8efd049712d613e5724a92"): true, + common.HexToHash("0xbb381f4c47a3326a013fc4a757c6e8fecf9adbcf38a221ca1ee562526a41b024"): true, + common.HexToHash("0xf6078258d7485fee6db07eb2f5d20d5157c02bc8dddba69f1ec8c661ad9bd66f"): true, + common.HexToHash("0x98e9bb0dad1bdb04128f0265b410d71b58f16404017d5502ea4f412bc65db81a"): true, + common.HexToHash("0x1108bf5b6a4b339d16d3b252b087929fef0087ea915183a1db476fb4607d1c02"): true, + common.HexToHash("0x3ed0352e4bedf7f836188bcd2abcae561961d607a220f9d07cc57bbf6960e188"): true, + common.HexToHash("0xcb62f7a81c38ba42387ce7e6c1a56b6a0072d0697df3c065cf87e1dba4ed6c33"): true, + common.HexToHash("0x093b18b83fea7cbc5569e42836a51237bc8ed6e0da3f9435562945d5a49ff110"): true, + common.HexToHash("0x2be347241106f1754bb7af1b18799ca74b884d9b6c42e5135b55585f98a380da"): true, + common.HexToHash("0x194eb7f98f040092a1b8b68864a41aa2439d224d087fc5128275279b3f336665"): true, + common.HexToHash("0xf6714d74ccc43f265477cb0fadbc73b9ce51d9f8323270a819e1687da4c55f99"): true, + common.HexToHash("0x004f5e3dff0d0e2645d3b2e81eec5b50e8560475959d7b993147f36a25ef0f95"): true, + common.HexToHash("0xca076462162e9cb8c016c1258e26438827fb7ede2e6c9dec56f989dc01a783f7"): true, + common.HexToHash("0x28a02799c47aab7c109cd50321a6d3617058bbbe536311f99c21c11fff2970c7"): true, + common.HexToHash("0x1388edfc94fb2d11302b5fc31ab83f5d796778133968cc6a2950928a252085a3"): true, + common.HexToHash("0x581ad570b8d0f5f1345705437ef680a18091e6771cc42c294d6c171ca7fefdb7"): true, + common.HexToHash("0x00be6b0c4155e469655492d01672ffec714f00f395888cc69d53a13940fb91b3"): true, + common.HexToHash("0x5516f998321e79877864ab7f317fe1270c5fcb5099d3fe2cf3c825fcfabb24de"): true, + common.HexToHash("0xb61bb321f0ef4a564fe75e80385e8e830059a754aab3f395cf5bfb8dd5b4b9db"): true, + common.HexToHash("0xbcc7e468a0600dff7afb549cfc9d9202eca8815980fbd428328c91590c1fd356"): true, + common.HexToHash("0x05f5049d9ea71535626b77067fbd6568629745f1ced245ac8d409de5babe5513"): true, + common.HexToHash("0xe78a7364011ca1f388c8eca7ba8c6e5fad08ce9149185cfd8111c152fa934d1d"): true, + common.HexToHash("0xcb75e880f94dce56ea1ea2f6f741a29203895743743036f5da6e44d2b02654c2"): true, + common.HexToHash("0x1bab795349231658eef76bc654ca2aa73a517abd08ada0942f837594e69e3014"): true, + common.HexToHash("0x4264e2a70f1c37c5c26f346b92bf4d1aa5ece8578211fda4b549569a17fbad12"): true, + common.HexToHash("0x833f8e8f29567f0dc34bc925cbe1fd7eac10fa77a1c5413cbf42b63c6790bc8c"): true, + common.HexToHash("0x28f3b4abb6439c1b97c09905f6909b32a2ba79a6857581d3906d303a747619e1"): true, + common.HexToHash("0x2f6a4453760f871f3cff672f6da04163a2e9a4d7580cbcb494479a21fdd3dd43"): true, + common.HexToHash("0xeb177c04987744013ca52be2a2cbf24376724d4efb4039ea96edaf6e2bbd8978"): true, + common.HexToHash("0x992864aa379aaed1ef33fc87871488f0b183621aaf8f28198c295358f3394d34"): true, + common.HexToHash("0x9a31cdb824fced6aa40f699fcd1e3c856d11b525e211f98de90fbb4eca0faa88"): true, + common.HexToHash("0x146213a9606972deadea418103725bb0b14079ce0f1adcdec3aa413e531e1749"): true, + common.HexToHash("0xbaedcd710b2a468bdae1eee1e4775fbd2b3badae318e416c7716a4f2f90eb001"): true, + common.HexToHash("0xb57491da3d4e81282adb0112fc83cb307a59a712153053ab2a1e697189ba4734"): true, + common.HexToHash("0xb483cca2377e9d193bb8da09ffe1be4e36241caa1008489bc37ed41ce2557dae"): true, + common.HexToHash("0xd7f9a02a26d2ab4c936ed6f14ba6abd71e47255627bcf942db57672958928966"): true, + common.HexToHash("0xc9f3d8eb3e4c339e40c53d30a902a50a733353488d13ab606be6cdf6c772527b"): true, + common.HexToHash("0xf85ace1f4bb51e6dcbb6285d46f29970ea618fc550acaeea744b962b37f966de"): true, + common.HexToHash("0xd6193dc625a14956ebc8e996c570e6e2e01d5a5792e50b6b466569c76b021c21"): true, + common.HexToHash("0x35a877141fe3cd092db4c72955863442b7c9e61839a995020fb194c901f545a0"): true, + common.HexToHash("0x2e829757dd1034090c0d71d0367baa6b097e0ecd23c53a61f049d84641bd7be6"): true, + common.HexToHash("0xde63a480c9d5fc1c6e2adf3a8a685acd8cd57c2710cb2576839510454a9851e8"): true, + common.HexToHash("0x327fd05aa511196181b8f2743dd6d3a22e409c043a7d8977737ece5087152ebf"): true, + common.HexToHash("0x3082a3f45e20753d8d1148376797bfd9732828d3f0b740fce3c7a2666dad4eca"): true, + common.HexToHash("0x69854dfd05d67e9c80e9b3e49e721360b7befe462dc40825355a0d9cc99e9d32"): true, + common.HexToHash("0xd3cfb856d3c835a8fac53cb3cad4fe200440890a7a2f687b6d6d4b666046db76"): true, + common.HexToHash("0xd4bb8d25891454f2dbe492198fa6549239809b8b5a3137a9ef637bfda3f5efef"): true, + common.HexToHash("0x476054604ca96a843fa91314df7b1856f723e84c9498189aaede56a4d2c7f5d4"): true, + common.HexToHash("0xcc7591cb9cd6269bd83e550351295e4d7e3066c8f5a33258ab8dae00d7ddfec4"): true, + common.HexToHash("0x2e14b6d8ee42ee54f4d373c11a68e66dbece9d9dfc6633753a4a5056f35b5952"): true, + common.HexToHash("0x7f5a26afdf79b7ddb4c5e4a356effe071d739b84379a81e672baf8a78673fb72"): true, + common.HexToHash("0x89c416e52ee67dc53b45f4a7f1fc03cc976cc257328ac7c048884ef2ca6c99e6"): true, + common.HexToHash("0xf1f695d201a7496563427767b27c9f3bbf4f8291b01c297903acb37f84be7bc9"): true, + common.HexToHash("0x20a60d18085b78f2163a2b7d4d08d5410573c2ebc01b30f8bf029d985812f6f4"): true, + common.HexToHash("0x9c35e2ffc563222ecfe27935d6c7c4c325cbde95bebbab8d18fdf135fbfb46b4"): true, + common.HexToHash("0xb0b2bf26e60a213f0a378182596e36f3041fb42c1ee3d7fe7468b5250b76ba34"): true, + common.HexToHash("0x0d024f20d75b7c81af62434680a45ade1a01719eb862260d6e791bc3a1b8b762"): true, + common.HexToHash("0xa374559df771d978845969d85f02180afe3b80812c589b6a6dc580e6baab81f4"): true, + common.HexToHash("0x7a4a5a93f63a821e8aa3cf2d0b22f9b02f2e195aac6b6b08a29ccb8116c874f3"): true, + common.HexToHash("0x7300ebd92b171660aaf00edde9cb1afdb39767d662642d1391f156eb5bbe7ff9"): true, + common.HexToHash("0xfd19dda835ad91cd03e065e93257fcebbf9b122c5bf7e9820228d4d1e5544cc2"): true, + common.HexToHash("0xed0c2a4969dfd20ce9199648a3e77ef573e889038710bf00e75bc9c68bf476f0"): true, + common.HexToHash("0x9b10cc81aff67cbf57bf5c307007fbdc6bfd915bc120e4c594e42a63db6afa6d"): true, + common.HexToHash("0x1a1b2c49cd6536577a6cc02d15cd385645dcbc643ac5a300a8981e6471457fdb"): true, + common.HexToHash("0x6e1938701494545f10f674a095d577768144e13a81b32753a74abc8f46be4ec6"): true, + common.HexToHash("0x78bfd2df5503ebd52f84f4886e5373fe8a7c6b1f46a0f4381bfba24c6efe3899"): true, + common.HexToHash("0x882214d78a59d043ea3ab71abcdb262f3a7d762e38fbeba6669ea4fbbebe5a10"): true, + common.HexToHash("0x93df4ba5f5d570897a5a433dda2da358d0ccb79fa15ee41a45b99612d829633f"): true, + common.HexToHash("0x2a640b8c9390b0c5f4c6cb4196ad209ef2c63a46c52315b1e2d4953d59198d65"): true, + common.HexToHash("0xc59eae025a9eeca2f9f2b87cec8b41720e6eb47e0cef6e52c56212baefc36618"): true, + common.HexToHash("0x5f154a20951e1ef895d1cc486002318075d72d1fb9f7f1607cfeb242091d31db"): true, + common.HexToHash("0x3e5a23e2eb389964528c2293bbf08a685c2e9f26e1611e187d2a52d002a04762"): true, + common.HexToHash("0x2e8db1c353571d8c11a05ff9e7f7a24d48893db4ff299ea3602998ab97893f83"): true, + common.HexToHash("0xb4a32c0eb55c502f3c637e1e6cdc0e3b094173ffa40faca697b5b66515e68f0b"): true, + common.HexToHash("0xe8fd82bd5d6a886476a38507c13fd162eba008fe2d3873a81b949302bf3e308b"): true, + common.HexToHash("0x269ec6624facff0a4a547aaaf0b49037ae1f2bf311fae4ef787a36e9a13af86f"): true, + common.HexToHash("0x1048b184ed8969a506e9fdecbb4fdfafaedb44b0429a9dcbec9d991b82927056"): true, + common.HexToHash("0xc9e3b6614f421a1b37c626257830aebbbb9cd0c7618dc156308d1ca1efa7973b"): true, + common.HexToHash("0xea9cc67a110e5c1a6244fcb8e4ba63178d0a3cc5687dca01ed2675178751f94b"): true, + common.HexToHash("0xdff8fbe6f5d625dabe5b4fffd6a145e4b3ae5763d3a0be0a1eedc9c20fe6fb11"): true, + common.HexToHash("0x26fd8461dec36e624a375174d872916f2b9b23d1f23866007a1e1c3f943d28ff"): true, + common.HexToHash("0xab1fc2ac93d6df48899054bd7d8da313feea30d91aef542509d0dfa45c22ceb0"): true, + common.HexToHash("0xafe98ade27da80cecff46e5b641deee1779901ef0178541f235d9c577d98d255"): true, + common.HexToHash("0x0d00bf257e05d604491c4773e1e725b866b48e62f24bb4cb4be799dc962fdd49"): true, + common.HexToHash("0x37671711cdb9accc144bd742e5558a4e9fc5dc2baae6b15a560c0cbbe4130393"): true, + common.HexToHash("0xa67a3accf2c5b54b88a1d07c75c5b4c2eea1b0f52acdda3d97d9bae26f865582"): true, + common.HexToHash("0x8c5cb67d3782197e42329772e8990545fdcb58bfd488f454ac254e90ba30c50a"): true, + common.HexToHash("0xb36ed550e87e15d1aa8bb59439be6d635fc9d779e2ced7d73da79177842707d4"): true, + common.HexToHash("0xeb1752d9422fc15496ee6d92caec3065ead3f381e6296c0fbc55fd52ac93bf1e"): true, + common.HexToHash("0x87f8b2c0ae039e2eafe10c04aab0ebec34263fdb73052cfa282396b93153ae14"): true, + common.HexToHash("0x489c379bd5d0044a76efb7691713e66476b82c1c55de968aeeb49d0eb8854f38"): true, + common.HexToHash("0x4bed8f739faa4a4c507bfce715b6137e4554428660da48ab527fbab3996cc149"): true, + common.HexToHash("0xfaf7976507ae217b6ec164acab20170d29a8dce7d2121173765f50553b01a218"): true, + common.HexToHash("0xdc076528dd1db684c4e20558870543bab10ea3c4a9847df0403e060dee98f676"): true, + common.HexToHash("0xc098c41ca5cce94687ab8f89059b49e7df564737b753e033d120817955ec7b06"): true, + common.HexToHash("0xf1013ce99cbb1c7e96a410ebf4e54ccadc6a44efd36d3de10f3444f135ae8c74"): true, + common.HexToHash("0x9dec4be2bc7d18d6126cba51a6bc37a0fb6f2ae7aff93367665f49672097c55b"): true, + common.HexToHash("0x9884d4030dbc8f58d18da8267dec0cf11d10f415134b144e845245f8132f52d5"): true, + common.HexToHash("0xbb6ea9b7b426c372215a425e8f1ca1c1550c3c94367e77354daaffa06b8878fd"): true, + common.HexToHash("0x0c2819752c4f4107aea2ebe6b6daf90d222a19d6f94166ce08c1559f599f706b"): true, + common.HexToHash("0xbca81d7e2ca19c797e21c74ec019e8ce355f8403e81ca19c6a3479658aaa307e"): true, + common.HexToHash("0x542ee52fd50a62ddf1106cf210a7b6655292b9acdc0edafdf06d89803de2b6f0"): true, + common.HexToHash("0x1d048a0bf1e66e06f161baa7701e31d5db89312496793511f57ef9bfd4b1c6a3"): true, + common.HexToHash("0xfc7c666be19e0aa9ac5f8ad05a5d90e0b3231c62b9e6009fa757576d0781892c"): true, + common.HexToHash("0xb500bdd7466cd1d9ecc8be61e7a5b75daff16b450954171f98aaeda88e1eb871"): true, + common.HexToHash("0x98569b231a5a1e2dd7ca4d6fb65d8042c8d920bb93425caa6e8116c660de6dab"): true, + common.HexToHash("0x97e2de25c05b8b1dbebc5fe4c75c1e339d9ad7b80ff4761a826a22a3bb8365ac"): true, + common.HexToHash("0xf5fec74ac5774079edc42d88b6c9136d928f026226e07ec753d63cd12541197b"): true, + common.HexToHash("0xbbf14fcc917afc815811d50b79ba70867ca2e5a3dbf8bffb4c5a6b3ced2646fd"): true, + common.HexToHash("0xc77526b370fd0a30f532e4b092151cd5e1f50d4d97ff79249569e2b4106aa52a"): true, + common.HexToHash("0x9f431d2e2d3f82e02106768cb7045a4f4fdf098ea166ff9773377e3c438bb88f"): true, + common.HexToHash("0xa407af5e865619b5a59a52c123c8850945b8eb4b8da1585e903fe68f65933f93"): true, + common.HexToHash("0x9f25b2ab3fad6bb8a68ed301d00a133c90e258d53492569329ac8c114f4b9ba5"): true, + common.HexToHash("0x69ab098f5c69137a07b4f51c1d2dfe07c3f1d782c925f3593dcf83b02bc25d87"): true, + common.HexToHash("0xca71c1c1865d462b24bc0bddf8ac551de6144314f17f20329c1e436e916a52ae"): true, + common.HexToHash("0xba476c04d6abc10bffd972f436bbaa7299bd6012360973c6dc9a060f7bd56c6b"): true, + common.HexToHash("0x812a6c8641bf19de37ac53af81fe6fb0090825e934a8f27fc5cc9f230a2345ed"): true, + common.HexToHash("0xf3ab0c97f17dbccdb4ca26e839f31af727a8a927b1f098f233d863046e05116a"): true, + common.HexToHash("0x02fa7597cf47bd72c48888ed779111a0e4848bc175c066d23384e63c5e96676f"): true, + common.HexToHash("0xd1c2f6648d43b440449fb97847d1d4e13074ff24832a020cf1ccb99c7ffa49a2"): true, + common.HexToHash("0xf1979cc7d417ba22a587f5f02c18b802c0b6073e72f8e031d66a27be53094b15"): true, + common.HexToHash("0x1aa3bb430e28b9a08389660af677561dc26f94e70260a219c894ed22caec9758"): true, + common.HexToHash("0x7fc8db186fa13a7d058d3b6b7e3eaa27e0b9da978f08a883bc5ec3105f12dc08"): true, + common.HexToHash("0xc2c3b5f87f62398d5d68afa44ee44f283bbd5df7cc0c03b75129ee513c7dc3e5"): true, + common.HexToHash("0x2de0f6be6a697686f17c676bbcb688f40def9aa59fa3f0964f3f0a5ff67d231e"): true, + common.HexToHash("0x16fa491040de78d3d18ff1f409d9c6a4dcabd879739679b4688e4f92aa73e431"): true, + common.HexToHash("0xe8d5a0eaa2fb83caae8bfe95a06b8cd93b94dc15ad1fba8a7eeecf13e27e501a"): true, + common.HexToHash("0x898fbe9ddca24da6847fa2874cef5dd6e146b29f71b95328d77272e30c259a06"): true, + common.HexToHash("0x2ae3737123bb91b6ef3d9586b2acf67edf4fe9fdc49ff6d5594eaea3212310b1"): true, + common.HexToHash("0xebd90b1246b2993c5384ccaaeb2bd2db4cc77b53deb3e09d15660b7026b29be3"): true, + common.HexToHash("0xa6ba70fb38ca155802e31feaece03ad18d1c0cf0713564290fc1a5cf3eedfaf6"): true, + common.HexToHash("0x74b4404e5bebe97ac23723b62095ffaff1743bdb6436ca3676bd8d4546a5f2af"): true, + common.HexToHash("0x79a1aa1e24216330efe88dc7421cc85f8a14c5857354c6d6a9abf68cf193c2c7"): true, + common.HexToHash("0x78f98b44004b42dc96e071570bb507d47b3ce7bbd6c4a60bc3add1f6f5243594"): true, + common.HexToHash("0x6272dcf1af876b11633ea569b84f171c5b32bf779aa6641855ad796598d463f6"): true, + common.HexToHash("0x96adeedea8102b959e2332284c6599291b876b9a261a8ec7d6aaa83a1b7d5da9"): true, + common.HexToHash("0x8bdee0abc563d3e049e335301c7d96017e53ec3ad70d6616c5900fb1bc7f0b5b"): true, + common.HexToHash("0x201a2773599a3803cf8441165bee8ed1ce134eba54ebe4818c45b3e7adaa4adc"): true, + common.HexToHash("0xfd2c3b2770b085ca1fca61378d7a970aa25d4868515e32b2335977bfa893b641"): true, + common.HexToHash("0xba932e37d51da0bf4856e2564f06519307a9b2b0eabf43631ceb4ef6c8dbb791"): true, + common.HexToHash("0xce43fd475064dd5f057f423ebf271f420e7904ee01c57672cac0924ff8f550ee"): true, + common.HexToHash("0x27854e00cded18f9cbd435ca985ef5a66d2e817348d034c915bc7db160a53134"): true, + common.HexToHash("0xfc4d9fe5f866055926155a636dd6dc593e4518fd169af659deb889c70f1b2548"): true, + common.HexToHash("0xa0209d36eb3bcbd3bd49ab45d8e947b90ff667e2409376a4350265144662f770"): true, + common.HexToHash("0x3ad5a0e15214585bd6313b35f9881960d554c68ed2a9a12578a23113a85f293d"): true, + common.HexToHash("0xa3288961e6a73143043961d19d4bcbd8f53e95ba55bd0f6e9c56dacb1c3d3d24"): true, + common.HexToHash("0x8ddb81df78f3c5b66a5a485f813d5aeaa17de78308663504a491e6da707b6fc4"): true, + common.HexToHash("0xa050bffb91333830241383431a900633fa3185daebc5efd4ecc22d7b611debd9"): true, + common.HexToHash("0xc87e677e4a418c0729dcff249eacc3a0181df2db16753d76e54050c93cc502bc"): true, + common.HexToHash("0xc4ffa7a69cee3e6fd280404fe22f87375301042085c5f43ba466da41a7f05b3f"): true, + common.HexToHash("0x0aa2477f0c6842d1c6b6cd22c5746ce5dc2000dd374d912be03ed8e5d1b9b71a"): true, + common.HexToHash("0x8b650053d269e9d5fbe1fc195dde1e8adf5ba19bce82ad83ea9cde0bd29dc62f"): true, + common.HexToHash("0x80726b95ac7825549f2292dfd40bb01b13ba7e3014a307a13a4ff38a4ce0c6b0"): true, + common.HexToHash("0xc02155aaa71d5b863e3b77e47191308719698b785a7707c1273da01d29a37bdf"): true, + common.HexToHash("0xccf048c8ef030a995ccb3ee13158bdd21c75f73a60f90b26d5ca62b8a6e6c1b6"): true, + common.HexToHash("0xd5b7be24d0c6d418ae1d69b1a7162dad1658dad336b9163f829d75d1a26c6a62"): true, + common.HexToHash("0x40b0efe86092feefc837c094898cf7eb2a48358a2be2596ac1c200492907a2ff"): true, + common.HexToHash("0x6fa6fdf28a99e02b864f65712c342090323ec37f97eb3a8a20ff4ae54423fe01"): true, + common.HexToHash("0xe6a8ffbab5f92a449e015dd6a04bf1742ba7baee4f39dff20b928e87846e8fee"): true, + common.HexToHash("0x1b75b46cbae4465dadb9f61fe9a770a8086f7b64363d171c46acd1263997d8af"): true, + common.HexToHash("0x1a9c72efafa1a46e665c0f0bcb5c7cc41f573c170ae53a39ac8f481845a3138f"): true, + common.HexToHash("0x8ce68a559f8f8a2f8a941a3c34d556315624fd8e5633ccdf4b1fa16af7cabb20"): true, + common.HexToHash("0x777eadfc2ea41a965c258e252fa6e21a3d456c085c3ffb74418e77580ca5a5e8"): true, + common.HexToHash("0xc12cfd65fc82420fc6327130ea63bc357e9cb6893d03febbfb239b5a363518ae"): true, + common.HexToHash("0x0d80ee9063bb32c8bda85470511c818b3d80c1503a6182048b5d1047c88e743b"): true, + common.HexToHash("0xcae26d31da685b862b0eb510251317d1452239039a3595420cc0e97f0489ffc0"): true, + common.HexToHash("0x3f447751b9e35174f016612762832fdad6931c16f19f0b3903fdc8f7d9e4b608"): true, + common.HexToHash("0x73de5c470d90c2284fdd3f1007c9f1f348dd68fd25835b3cec97bf2c6d7d0602"): true, + common.HexToHash("0x08065aec5004bca006c7ba3077dddfb8aa6dff1a212f3f76b56ddf11ca47d4b8"): true, + common.HexToHash("0x51e5bade17986e6a5af43a3569cda039206bd539524132ceacff9c7365c029e2"): true, + common.HexToHash("0xc42ec1d0b959066a8af0ab09261521d521ee56220c13725062c87275222108f6"): true, + common.HexToHash("0x8a716271fe07f29aa131dd4a6d2ac626c2f23908be35a4ae9eff598653d18588"): true, + common.HexToHash("0xd091e770f2ddb4efc005d4f4290a161d3276ec2ca1e064802ed4273bf9c9b594"): true, + common.HexToHash("0xeaa239ce2db213735564adceb2e05c2eb60de2d09db2334add11c79fcb5ccb79"): true, + common.HexToHash("0x0bf142d521b9c359073a838deed0cf80c8ccafcf1f9888eb2dd127806da62e9c"): true, + common.HexToHash("0x9fa2ca7a5aaabcb394f233faf854e685265fe5a1bb33e8f28510712ece414217"): true, + common.HexToHash("0x56e9b732839c6f21ea937193ee07e5c90238385638be1d099142a4be67524f68"): true, + common.HexToHash("0x828f434e6f6dc95ba21f7a0edf68cae63c2140f4b135215c44e26178aa07f3a2"): true, + common.HexToHash("0xee9dc07b2dd9b41f77b7e0dfd0fb6d54c263955d91a4cd1c3da435855f363942"): true, + common.HexToHash("0xe7369febd26140ea769f9988fea198dd9273e8b81e6319ce2d7eb6f3e62d74cc"): true, + common.HexToHash("0x8eafd59da7be61fec24b59082c5092bb28a9b1471a8445f1eef7d1ad3d3deaad"): true, + common.HexToHash("0x900a06415ededbb1a2a30f5677d24418982d59f12238ea07b3855b9207a70fb2"): true, + common.HexToHash("0x5f9020fe8daaba8712ac02019cf51184bd27eacb523477433cc414be56f00ee0"): true, + common.HexToHash("0x315c20f9da6e10168449da5ecb8689b56da5bc12e98fd1a3e9ced5b4026fb638"): true, + common.HexToHash("0x99a0767fa26ead5e6cfd8fa95673cb728b6d74412e082513d5beeeaceb9f6ab0"): true, + common.HexToHash("0x1432ed21e246dcabf21be129b8c58b949a5826815e3c4e5539e034ddef54fc78"): true, + common.HexToHash("0x74a8849d26e60bd7de479eac66250e58654b18ed6e2a0770faa5c4dbe13cc549"): true, + common.HexToHash("0x2f436a3359fa5b2d7c2c77fbe45005d6f2e77bf8c7de3f3e0997d9335dd9e8b1"): true, + common.HexToHash("0x48a0bd62e92178d958b1f59ea7cf50c9556f794ce5fdd763d0bd7434ebefa078"): true, + common.HexToHash("0x142e58f091f2333110d634427ee399455bbb7473225e275f4d7ba8ecb0b4a4e3"): true, + common.HexToHash("0x601c688e86f1e3d6a8558b93142ba84a944e2a068ccce2f223a8854713b4e55b"): true, + common.HexToHash("0xe26b28080313d140226e278499b1b2eae7044021c680ff4c24a3d70c1ccc791b"): true, + common.HexToHash("0xe527f79257434017ba99688fbbfecacaf971e603eb0954abcdd3e7a3de4999be"): true, + common.HexToHash("0xacb979a3514afa662dfd9a4d585c1cf35c4d57d5b7c2c49d9fe812423ef901ee"): true, + common.HexToHash("0x18e58c653eaa5ac90c78a8ff7df2126e18bd009eb37fa750a0dd3a0eea3b43f6"): true, + common.HexToHash("0xc9d2979b7b632599387e7a0d2c6f8961a2f541838e30370fde7c3b32f8b8d39b"): true, + common.HexToHash("0x8361de1ebcbde486daf94c98f081efa8b0f71a224867dca7866aabe0766f866c"): true, + common.HexToHash("0x7ea41d2bd279f92838b2042e837b65be6fb797009c1c61e99eb9158856bb3edc"): true, + common.HexToHash("0xed937d4fc3cdad0ba5cde27ed71bd0f8c43e250d04d083c6d2f9baa5eca9ee71"): true, + common.HexToHash("0x55326ab5e6879668d3edddfaa77ca8d72f389bcbb5288123a65de95cca663ec3"): true, + common.HexToHash("0x931b72352ea41d5416afb4e5e2ea837ded8827eaa66c97379f9dc61767ffda7c"): true, + common.HexToHash("0xa8f823114883d156eaba37a134f5889f19030646bdf147ddb3636f5809974ccd"): true, + common.HexToHash("0xb83b5b7b23258e80c57eb6f6b239777bef63575e4fa154097887bf85c0674ea3"): true, + common.HexToHash("0xeb488a9daed3220ce6765fedffd1ee06a75d28e5f132801987c212ce5e7ed99f"): true, + common.HexToHash("0x4e1f38b029da9dbc08f18ada82e31dafc6b7020d30f9980833460f4fd4bf1f34"): true, + common.HexToHash("0x2b7ef70ee13cc8fe0eca4ab31a92025f29a418a6087d61bc1fd8374209ec69c2"): true, + common.HexToHash("0x047ef5d698108ae4e76cda43770a432f43af5f767c6a117f4be0a85e28e55353"): true, + common.HexToHash("0x575ab16d567924c3e726d907ac551503c418eca327609e399bee62f2f9edff1b"): true, + common.HexToHash("0xb26d5f3ce414af18e672b816bd8f42833b39290b1e90d4f342254e0b3bfcc525"): true, + common.HexToHash("0xca2109ff2cc4279fc4d271732d3f974a33069be213672a54802fb9fd93ab61e5"): true, + common.HexToHash("0x330fcba5c97aa63bbed3a8745891e301c7cd682f1ab339fe01660f1c3c4b3184"): true, + common.HexToHash("0x90af1209910dc3e2bf6df357b9b175dae02cf43c7e3251a5e094872c777f9266"): true, + common.HexToHash("0x311ed791ce7ea14bb93d7b0d54dddf00c8072ceb9bda1ccb905789c959e7e15c"): true, + common.HexToHash("0x7224ad442bcacb3813650fb505a1540d2209888d2e28dba1b0b7530dd866ebff"): true, + common.HexToHash("0xc112a8b2c0c87c0f0c8b21fbaf7bbcce4206bae805cf7f71ca6a3a35b5f746d4"): true, + common.HexToHash("0xa04bb7536768e1d7f11cb3e4ada47d5cf4ff72c1a3984e011c30d5dface230b3"): true, + common.HexToHash("0x7adaed7eccd4432dc89fb8b7d02a447a1a4c7e1d628309bdd4a4187a291b9cc0"): true, + common.HexToHash("0xb9db60a119e00eaf5f2f67665c1688bf0dd41d81da31477353780714b3660343"): true, + common.HexToHash("0x72ba0a6e7eff1b6683ef3b981587c9b061f3a3ce8c8d687b4dc8e70819f0e82b"): true, + common.HexToHash("0x7ef90df27fa50ac666ab2fb2c2a12a1e7094e484570ce4c6d175d3d465a34d53"): true, + common.HexToHash("0x1d8803abebb0e75c597d4bd40a3158f62bf953814cc87bfacb070cc5760b5650"): true, + common.HexToHash("0x80c5aa3322db9df3b3344efb6fbec4d3099749f2eee46295237d7e5af9ab507a"): true, + common.HexToHash("0x686df01e5c0e6046e7fa99086f169405597c1a93784866f2b68cb95aeef8806f"): true, + common.HexToHash("0xa68996bac63609020e754e5777a426b5a108d1b9769c53a0fd98a049a65e79f5"): true, + common.HexToHash("0x58ba618a2239e4bdf9cf9f2f5845584088a97bbe6d8d8d7de944d1a11a2ff7f2"): true, + common.HexToHash("0x6b671ea3016802e4682eafee55925806adbe8dd09159d64dbc7a2ae1c6f53d22"): true, + common.HexToHash("0x83ef3186493d503d64cbc3337c8e5c65e1be914225f923e5bbcfa7d84f8c91d7"): true, + common.HexToHash("0xe2fdb6fe42765a5c5d3a3d8d323a8beb29744b278815658f4dcabd90cc91b477"): true, + common.HexToHash("0x026291eb74331bca3a3319f82dd7d9fe7855795ffe270e6e079f492a94af5b42"): true, + common.HexToHash("0xee7d0822e0f172d8dc72317200897aa23b684e0cdbdec3ccfbe73ddc2cbdcaf7"): true, + common.HexToHash("0x10322207e6688f4258b0a525c806efde4cca09fec45d90330f863fe60c4a165a"): true, + common.HexToHash("0x8a1422a1cf5f89bb9468a4cd96753ec0b301d7ba45e8b6efd6264a6aa3d325ef"): true, + common.HexToHash("0x47265fd3fe5a5172eaf2c1116bef11a7cc820903a04a02ef95b3ec1bc16887a3"): true, + common.HexToHash("0xf652f1d6b11be26ac6c0880797e486ead38b165d45bc983f3117c5c497c19b53"): true, + common.HexToHash("0x23ff460ad23481e7af446675137e07fc09d2351d8656a050ebfe5c92224b06f6"): true, + common.HexToHash("0x9738bd8b332285f620df78a6c45ea97fc356989f3e2fa703fa1159930ee96aba"): true, + common.HexToHash("0x9e2c9552d360e1f93644baafe169294d2b5a110919f3ccaa882606e59465a0e8"): true, + common.HexToHash("0x8c99a05b1848a90a6d51d0225a14621ced15608b6ebbe27c040e2857f53c737c"): true, + common.HexToHash("0xe03db51969fbfb027c08ee1062de523f89292c63b4329b686f64f965be75c1c8"): true, + common.HexToHash("0x0a2ee9af6a3d7a3aa44ed855f1edda7420cb748f9b011eb3b024e70c7fa763de"): true, + common.HexToHash("0xf19984c6c97d4432564f6df94acd7c700ab847670f137da043446f3092b9545e"): true, + common.HexToHash("0x2a08af795e37f243ca12cbde6e2237e16b554871404248bec6ab3be36798a3cb"): true, + common.HexToHash("0x0b6817b9e907502f31f4d61ce5afbe947a6afa7ff30b86604938233747247ab9"): true, + common.HexToHash("0x24f36315011f6dab87fa725896778b499941aa5508df470d0843d65a96f02644"): true, + common.HexToHash("0x55fa79958e72eb8142b693cef90cd2a05050ad7f0b83869758b4e1534352f2eb"): true, + common.HexToHash("0x4e41131551e173b4e74941c72949006b9aaab22abb5b7330338f9ce759b01cde"): true, + common.HexToHash("0x69185bae98bb8a24246269b6c9b2de69a59c966ff7934cfea3e13cf83504d58d"): true, + common.HexToHash("0x8a9943f10f017e94cf23451c3aa8b004aa369016c0a3af06f7baf99b1a45eb8b"): true, + common.HexToHash("0xcafdba764e2a4f4273f8b544d662ced1706de28d3c2c960f1af4f0f01be4ed94"): true, + common.HexToHash("0x8ad7f28495ebbd04b986c23d10936ee85730bcd03b7f99c60ad9c3d3de3a5cbe"): true, + common.HexToHash("0xe20de2918e584326721752e08af25472d4c8ca4f7a0a3e3fbfbc1282274f6ca0"): true, + common.HexToHash("0x1a19434cf9753f751e2d4f1bf8fb264b963209dad4abf87e3dd113353bbc2dd8"): true, + common.HexToHash("0xfd116fffbc0a146320e85df433679c4b45cb09401669cfa74a2515c8215471ce"): true, + common.HexToHash("0x4b7f7def1b51ab35cbaf63e92b48de043670eae7308d4f5372f6608809f55e9f"): true, + common.HexToHash("0x4151f721678652537ff1375c7b0b1ec7a5076cffee0d95c02d1fef2062cb5dab"): true, + common.HexToHash("0x63a9f1030eac9b0565ea77125f99adf7e5c4521057673b3463cd13fe27cfd5ab"): true, + common.HexToHash("0xd07836f7fe824b76dadbaedbc4f782e4170c62f784c457db759ef368785291c3"): true, + common.HexToHash("0x30030ba1f059554ff1073fc7f534d1d6522e936143db059fcf270cd7976cb5d0"): true, + common.HexToHash("0x53b21798011f4092b57f3f19824bdcf309b3438caee55191c8e4a9b58f4e5445"): true, + common.HexToHash("0x6b3e78e4c57f7e5a01ecf7be9fac30de35290328d205708168c3adb3c945384b"): true, + common.HexToHash("0x8e1660ab17d771c5b2d5c630f3a661c955f56c447edfd61345a663a8fe42f53a"): true, + common.HexToHash("0x4aadc9b2c599b8ef3c699c14e6537e244195b3269dd0b21eb8c9b6053421deb8"): true, + common.HexToHash("0x74fca5068a88f9ebdff4d02f0dac34adc4d0882b50c6feea791a658df9fcf8c2"): true, + common.HexToHash("0xed36029edacdb4ecd3528bd3081910e23954601fb9404ca5b4af27aedf9b7f3d"): true, + common.HexToHash("0x58a5baae0ab358c19b8e38ba4d6265d9ecb54d872488d59ba923015c470c58b0"): true, + common.HexToHash("0x70c41d863a7bd0aed0c67a45bf7ca17f7a26602b306d6aa01209361c5987d068"): true, + common.HexToHash("0xc04b065f06a3673074a45c60e14e84dbd11d9333e3adc5cd311c42c4b010b156"): true, + common.HexToHash("0x6fb74dcc736a981e4d1d034382a92b2181b376d4d806422dddb78337a5d022aa"): true, + common.HexToHash("0xa930a7c2bf5791edd38abaabcb59ff6e763d59939b7057ee954b631b53f6f7fa"): true, + common.HexToHash("0xd575b906f3c6274d389f1b1e17fb6619a49baca40ca4b89add4a9f2932281cdf"): true, + common.HexToHash("0x4f3d5886362effe8929ab18bdb53c2a8e507fb45dcbc122667c80e1a65b487f1"): true, + common.HexToHash("0x67b7e1d8407fd9e6ebd9a1001320bc68b6bf1f68ffa91c0180ab1427ec8d47d3"): true, + common.HexToHash("0x0bc04ae6646ddc1a9c876263e1f1d598e54b0f145b9fe8fcaae6c75a5edf675d"): true, + common.HexToHash("0xf2bd1caff5ebb69bdf64050ced3ff8e1912cebf98cb2df721e83a386efd8eb3b"): true, + common.HexToHash("0xbc894d51ad3559090ab9fda56ce1e38e536ebc894d0bf5afc57fe47fb7ba72d6"): true, + common.HexToHash("0xce2063fba02937870a98726b4ac416954ab03992842434292fdbc29efb428f12"): true, + common.HexToHash("0xf20961c5509166a8476697d9e28f38b828d79782f3dbd974d6185b46e5690796"): true, + common.HexToHash("0xf70a3c801f960dcc33ea98171fa0b8cff68b6c6ca39851296b3e0dd3d4db90a3"): true, + common.HexToHash("0x10714ce2dcf5ac1b70d549b2d42c3076b36e4a098db50b64e5947ceda41aa027"): true, + common.HexToHash("0x25c666a1e7f965c17c4a13f0ed660deb761626fe74c5c8cadb36cb8222bed434"): true, + common.HexToHash("0xfa42754f0eba34dfb5f05c36d6382937a1d7d5acafaa72ad471691843b6904f7"): true, + common.HexToHash("0x5df35c39b3afd4deb200afe07634c8c1b180e4651a0d8b01420c505e19912677"): true, + common.HexToHash("0x07558df14b5de3dc224be1340781fe04238eea48909efc8cb9ebbf42e97107c2"): true, + common.HexToHash("0xe52006517ecf8038da44e23ee41a27babb5ce9d2ed1e2d302bfa65eeb52bc287"): true, + common.HexToHash("0xb952b6cb4acf5597f201121604fd9919cbf22fb329aa239eb3c97eacfe4cbe10"): true, + common.HexToHash("0xcedee877927849c0de6427ecb18d5adf87d10bb616a749905a72a84d6cec4bdf"): true, + common.HexToHash("0x4a39a3bbb6ccd9295ad26053afc9bac883ccf780505fdee5d49d1419454244dd"): true, + common.HexToHash("0xf86fd11bbf968f5e9178f85e0c65ad7e62a13cceda17934dcaaad7aa7c931326"): true, + common.HexToHash("0x7d22ce3c5a0828e38fd8ad3f7c76e5f497f1efd8d12b4276589a851bcabc9138"): true, + common.HexToHash("0xcc00d63e2576b28648fed93f52adbbf6168f0caecb83cf5b0f87b0c8c0a2169b"): true, + common.HexToHash("0x313a1f28ee2cd550f732ac1c0e5137e3c31b37c0015128e3c184637fdf054e45"): true, + common.HexToHash("0x8d9c534a790341d13a07c81bd5ddbcce2b02f86b024ac6f78a77bdbb6be7ddf9"): true, + common.HexToHash("0x0b027a3e179ed2cd4ac36b089bf42c49d69141bac07ad21114521f76af2f8b80"): true, + common.HexToHash("0x3be0e15e5a4c46438f88b04cf25e5631e2cc2a7ff0d9d0438b1843a245189bab"): true, + common.HexToHash("0xb69867ae90be205a445f59ad7211e61c70d7836b807a6961898611b9391aa1e7"): true, + common.HexToHash("0x10deae902babfd3f800ca4cc5e6576683736f755464cae9d0f753e00365e13d4"): true, + common.HexToHash("0xf421e0b6c8f5c2ec08075a8fc67558af8d8d0a05517c57da8365aad8a7b0e69f"): true, + common.HexToHash("0x4004bff3c5ef93edcb3e6823fc5a02608f67df903574c17d7c0be0ede853bb66"): true, + common.HexToHash("0xcdc12c2de51c9b8d451c19dcaa41f0438fae6badb199e7495b23c983a83c68a3"): true, + common.HexToHash("0x4d69d838eedfd0df842bd2fd097aeb0e52b5d666f23cebdf7bc224f109a0787c"): true, + common.HexToHash("0x12077ba64fddaccd91fd2af9320f31953702717fc6a35e5c0dc5cd5c2037ea42"): true, + common.HexToHash("0x5705946a64f6bec6f465f5e6e51590fd87fe38fa6fcedb37cab7b1825d97c71e"): true, + common.HexToHash("0x75c71d58e065772bbbd71377d5060e15c026468e95968c33ce261e8913686e8e"): true, + common.HexToHash("0x5e797fc26e505ce8b973e29ef4dba9b8540606b3550ed61dc02354348406ce57"): true, + common.HexToHash("0x8bc45b443d17859aee43c20c432cc8afb60c34bae15529e7596da4f410adb81d"): true, + common.HexToHash("0x55220b204012a19722ae7e795b2b723c0a57d8189c76a4d0f75f37ad1b5f8c55"): true, + common.HexToHash("0xfc53c82ed604abe7a5a47dd4c1d0c99259c77039960122756d6f4d7ce576aaf0"): true, + common.HexToHash("0x74a08d15ae277b6567bf184bed953983948548e12f0ab220017371cef5a0f1bd"): true, + common.HexToHash("0x78f46f2ef9cac5dac4af3be8b434a2923b99d1e232a7ab0a4f7da743fbecc3da"): true, + common.HexToHash("0xcb6613a7ae6451955f561405033e533466b98e1a1d0af4e4bedff8635021543a"): true, + common.HexToHash("0xe46ceba4c0c587960946d77b3c8f6ec24d800ccd313d1efbab501916be9ead48"): true, + common.HexToHash("0x337bf1b85567b507635bff0af35c53ce50b155e94079977ccd0dade292a429a2"): true, + common.HexToHash("0x29302faaac0942fb9b003938d0d75f3c80872eb017226ddc4e23cf22caab582e"): true, + common.HexToHash("0x9db5b856feda13810db241325aaa956bffa560a2678c62ce67c41f70fdd77cd7"): true, + common.HexToHash("0xf7ffcc08aa1f97892f3c2c130453845103e8cc9c61dcd9d9d96e91000886f677"): true, + common.HexToHash("0x53c4e8f89c53ba7e5c2a01dee3770638cf5988603851c4d247c05162d9ad1cba"): true, + common.HexToHash("0x78ac0d8ca3154fec48172feb62fba268db8e0f6fc2049db7c03a106c1d1b6a81"): true, + common.HexToHash("0x5e9240af2d103ae5b1d8469582f65c758ef5f5808a9b43a7bb0ccee8c074eebd"): true, + common.HexToHash("0xa8c6aad48a9a85ad0f8ac21f945ab848dd26bd623ec750f5a611a18c9235da00"): true, + common.HexToHash("0x02f33212cff551d83d891c0d82294c3f95c0baed4d8bde73a0a2ec995c150207"): true, + common.HexToHash("0x794c0c63f77e34428323406e9f5a61efb39fc14eba8d1b11b6ce8f6e66a9410a"): true, + common.HexToHash("0x9d37b92d449471b6dc684c6cd04e9f95bd44c6a8fd1996b33af5133eaac4c771"): true, + common.HexToHash("0xbda8a8a523356d9c991f0093875ad30590279df395343c1df6bcbd9e3e9e1f8a"): true, + common.HexToHash("0xb16f3434b0fff89bd3fe1c26d16d22240946de50ca8126c95c293e97066b7f7d"): true, + common.HexToHash("0x8a45d2a8ccc71893ddb2e63b0614819ab13f9c604dff997f8bc47fd3b5622712"): true, + common.HexToHash("0xaf8d9fad0ba9d4180d87ddfffbcaceba289ff9bd99eb7cde91a51bc7a351984a"): true, + common.HexToHash("0xdfe12ceb012865f0147e91f2727d5488d9629a7e7f5e0db31d7e57e2713f1a33"): true, + common.HexToHash("0x52ccb3d86884700b308ae9170c47f7e85207f9ce6ce605fd659c1c3d285dd0d7"): true, + common.HexToHash("0xc7d04bfd53056da3b366127819c21ccd48bd47ddf76eff005436ab53c0f29be3"): true, + common.HexToHash("0x665235eaf4ccaf2acb34960cf262c8ca04d22ebce8716a16a6c472c182e522e7"): true, + common.HexToHash("0xb4a504432261ef1111aa2667e56746a6212d9ebb03c0116f176bf55acb4af571"): true, + common.HexToHash("0x2424a942129d9924e9f51d88de56c0e2302ed2c0c1ea9a780eb89320a9229e35"): true, + common.HexToHash("0xcfaad8ea264499ffde50fc1eb4ae4d0923b9844ed2346dab5f0af8c7e7fa8cf6"): true, + common.HexToHash("0x767cb57c039615e820b6326c784243111492ec7e629ea176b7824997f08d7f34"): true, + common.HexToHash("0x1d0b1fb491b88e0f656cc0e23c3201ed46f80fbe093d9b3b75430c5af85a7063"): true, + common.HexToHash("0x62c845bdc8817127190a48ee90d370d1d489267648a34b703f689b4b92b165f6"): true, + common.HexToHash("0x2dccac61d07046ad4b817d343a8f0541eb458d41f05f641a4e5f308ce5e6bd43"): true, + common.HexToHash("0x18d9390f31e4937525e0f14bc92f260217ba26e728518fdc8c8dc499f42eedc8"): true, + common.HexToHash("0x6135e79f067ce8bcfb0dad68958a57106bbd5b9291455c0ebcc94d5cbb4919a5"): true, + common.HexToHash("0xfb7e67df61d4256e2ec26e4b8617b6c2b3db5a58a143fc23e282033d5ba99ef1"): true, + common.HexToHash("0xce8be5e626001a6c441481612536e4befd7ac0f01fd69cdbdf56645856f3a817"): true, + common.HexToHash("0x5dc634df18490b843f8f16343bce99578c608dcc34592ac49bfc7ff3ac9ee09c"): true, + common.HexToHash("0x7a67f0a279dc9176de1f288501f216f7e79ce40d8f58020aa44c93b896703c2d"): true, + common.HexToHash("0x02ff221b7566778f3fb24d6950937470075d1699d82b101f610fbf3994e5de38"): true, + common.HexToHash("0x18145dbb25a3491d29938f6a5ab07e0111f2cb2d2927b20d8f4939466aabafa7"): true, + common.HexToHash("0xd35aee46b8f3682e99c2c150fd113988faf3688c82944cd8e1283731820a59d3"): true, + common.HexToHash("0xd2ed13ea3bb5fb9865bc9dee643eeeb382ea93663c0bf18cebebe73c68489020"): true, + common.HexToHash("0xbcaeb4d813c8f9cef2aa4f9d30d1ac570c03800d2f6a0fc78fdea9814dca76e3"): true, + common.HexToHash("0x1ad5e426ae51416faf3d41a54ebdc570d00e8c67c5f140b76233ee944557e2c3"): true, + common.HexToHash("0xde4072e31492e7e629054632a3e0f1a7392f6c907180dcbd56980f725687633e"): true, + common.HexToHash("0x4ab465ff8163f1573daaec5b2b2dfbf7200cdb21f71de33e824b717c6ee5b1a0"): true, + common.HexToHash("0x152fa8890ef118aabc410678232f18bbd46521b302d07e357025f1ee401fc46d"): true, + common.HexToHash("0x737e951c6d812681d80088ca249eb1bfcdbed7a51da8a966ebe277d27a6bf48d"): true, + common.HexToHash("0xd2cfe05d0f69ba59c31c23502527bfb237ee0ad4c65113150f7b07fa0214a673"): true, + common.HexToHash("0x95d8a901b26618ece3ae8193c5b760d1641c3bd85866d9a280561c94c69e95c0"): true, + common.HexToHash("0x831c7233c7d094cb88d70eadb0c7246b5c09ece3209edde28d725fa17ff408d0"): true, + common.HexToHash("0x3731f8ee5f3828f598536c4ef024922ab2eb1578d4bedd02e09482a47d402f8d"): true, + common.HexToHash("0xf9855d24a74932b78a9addc5dc5fa873ec296b19888c00dfc73b761e27ce8fc5"): true, + common.HexToHash("0xc26f8f340e77723b28e412105a247de52fae615cde10d216802f08f86299e04a"): true, + common.HexToHash("0x1abfabb20928cb784057b51e2e8a1468100265e9d85896b6f52d5ccc29d286c3"): true, + common.HexToHash("0x7277855aea36d88da5c335b68e9ee188ea75c47c2e9cff979baa2e6c65c24f58"): true, + common.HexToHash("0x5a610e1141ddb184e23f0c536ae403082c71081dc5afd88ce43f6d85202dea26"): true, + common.HexToHash("0x8034b5f7888fcb0e05342a6e044e334fa372eee70349c9dd06b561b5553b8586"): true, + common.HexToHash("0x7f33091b5b23a9a98619e2d33ba75332aa81a832a8f15cd751198e5fca64d62f"): true, + common.HexToHash("0x651a006742f6fad0c1cd82a13bb7879c42c163879b149f62a7ce594ca5030131"): true, + common.HexToHash("0x48cd60c91cbb30f8cc6d2e7dc5431cce4e0738bd4b14b1aa959d508994a09ad2"): true, + common.HexToHash("0x3dccf3b08f8387a53a59e7d0ed3b0c926a4ecb01a2b93c8dd18f971ea5f011ee"): true, + common.HexToHash("0x70d3ad94a09fb82397686f53d24853b9a3b0e9eda0ec774143cc2a2a616ccbff"): true, + common.HexToHash("0xd74121a07e746cafaf12b3576e700198c3e1781d941fb998364ae6ea551c6614"): true, + common.HexToHash("0x2b4bce80c80119637491d8971101b7cfee45ebe54eb8f280c8bae5bbadd4969d"): true, + common.HexToHash("0x67337446ebcc8e966e34c4c290bf5cb670259dcd49b1cc64c13b35765b4d7427"): true, + common.HexToHash("0x71b6d8ea89b2a02fbb41de0441e3d483c2384f7351968a25d76097e85dcd94ad"): true, + common.HexToHash("0xa836bcd0e4aa5630a3ec72d5e62c23c2fcb89f88fb52db386ac2b2f803a2135e"): true, + common.HexToHash("0x624abc5f417ed0581f374634039be58fcf5f03ffa305465d17620e90740e6ce9"): true, + common.HexToHash("0xa6f5039d0873cfced1a48b2b0447620ece196ad77e7ed7d8c0ea1990b71a13b9"): true, + common.HexToHash("0xe5576a4461753e2b69a7b26bdb07932c81d7728cc65705fa88ae296513933bd1"): true, + common.HexToHash("0x9c15dde0a63cf157233605c8928796515b5135095b4c2e721439c007a3c88849"): true, + common.HexToHash("0x8bd6cb25f9fbb89086f90a93608287ba0d0980aa1765f94e1ed92e7d7e8a7d46"): true, + common.HexToHash("0x5f84ebd1094c00a6781c54e0241cd1e737a12797eeb01824669af6726929782d"): true, + common.HexToHash("0xa76cccd9a6d93104a6373f4e5f3766905015756b8deb6ce8e64593c8baac09f0"): true, + common.HexToHash("0xb49bf2d635e84ff70ce798cf5f28af0b154e5946c4a0eec06a43c95e873b1635"): true, + common.HexToHash("0xb91e3551fa4c85a2bcbfe4dea33a654fee2cd34ba7bdd3e9c37d59e7dc461ea4"): true, + common.HexToHash("0x8d51dbc6b79c7a0a90b339a6d07ec9d7768688a4c5eab20b292e22d78f1e6f85"): true, + common.HexToHash("0x3e4780548393ca3df0be28d5910910756651776d23befe0ebba8a617337040bb"): true, + common.HexToHash("0xe5cf5dbd7a9006f6e4c85f3f2930e3de4d293914ed19786211da1b0402f4d177"): true, + common.HexToHash("0x318606d2d42c9691cad1d614d26dae101b5f9d4c3f3de0daae476fe62aad68b6"): true, + common.HexToHash("0x6f40075e1ac836303634dc8253121059a3e589c76f27cae441eba41c5c329120"): true, + common.HexToHash("0xb710566f0331abf4a087429b73cb325bd2603c00ea6da340e60cd2256797aa95"): true, + common.HexToHash("0x68f21838901ff46f91694e19bbef6d2d505ea1ab45777724acc129971c85efc5"): true, + common.HexToHash("0x264bc83af80cb5978d35486f5ada091b0f7c4d5328f4e33abacecf003a523c37"): true, + common.HexToHash("0x604f409ddeb3eaddaa1ae3faa73767ca0d58036a44f7fbb32a7ea37051ab52d3"): true, + common.HexToHash("0x6d6dd182d6ee36a0d2893c52628a923f8150b9115673fb226716c5bf69543ade"): true, + common.HexToHash("0xf671ec485fa978106bc33f8317f7cf25d5478c414aab53f13555609ddd83208b"): true, + common.HexToHash("0xffee52f411fe928fae73ae305bbc98c2444d16df7b841cf61be1af491226cfea"): true, + common.HexToHash("0xcdb00a09fdc2512a9784d9d52a1a377ac9e762ca5f7dacff370dcdca5c2cb406"): true, + common.HexToHash("0xc7e48ca9538b6daecd0cdd99d314a795d47413d7fe412cdf46df54378b9d21d0"): true, + common.HexToHash("0x4266a117a46cd44e3a2b9c8987413513158e1852213c461b5af094781225f9b1"): true, + common.HexToHash("0x4e458895e1a7de4711f2b59530696e159d8864ea105ec31139d9bcbcf80957f0"): true, + common.HexToHash("0xb98b462a3dfe8ecd75db4e816cd45cdec75eb8e4ebb9b0f7c65932e881ca56ab"): true, + common.HexToHash("0x238aeaea45b2e978d9f8fb7ec376ce255885f321ccd163c9ab68af9eef92f948"): true, + common.HexToHash("0xe0bcb3accd99ca4037c2e3abd8b54c9decb6d943310588fb5441e2fef16c3171"): true, + common.HexToHash("0x19388e17a1998ad82aca922bf492c1e1eb8fa5f9220b2519f53e09fc917e528d"): true, + common.HexToHash("0x39d2f34b1b8540f4308a93edf8d093167cc344330850acc13e3a6a58c7ada80f"): true, + common.HexToHash("0x4408b83090b29b64af8e1dc6384d8962e481a7d7f63192a31ca08604b480036a"): true, + common.HexToHash("0x6d886ecb6ee7eb370511d55777c30bbef653ba8c65d903c2b7037f854788abcf"): true, + common.HexToHash("0x5f0a92f882c8b31f41066a817040ec7e10e5f37521f0af1b62ce733ff55f657c"): true, + common.HexToHash("0xbf894bdc9075b89a5820207f5fde893936a956612f7bdca1a909899a5bcc4f26"): true, + common.HexToHash("0xccc42ac2ceae9771bbacabaa246fa528f69fb5ac285b96beed2a0902c7b1a490"): true, + common.HexToHash("0x4ff66b7f1bb67f9fe79b9baa0ed0065fb26939d5ace9a6c2cc39db25168b879e"): true, + common.HexToHash("0xf12c7bfcc23c7ade920922165eb243655b41e7b301edb3ddb8df7ba0ce03b6ab"): true, + common.HexToHash("0xe5332fda30389c1c6dc1fa9549b44800fb260954c22cb2fa5fe0cadb47b86682"): true, + common.HexToHash("0xaaa4abfd1366aad128e82eeb3913b4f3755095168c6f1c28f5c8650c1c0a74b6"): true, + common.HexToHash("0x5ec146c10d7245b0ca3a4c222c0cd3028a1651f240e7fd7bb6339c624c1e3558"): true, + common.HexToHash("0x1eccc1eb34d5099abd8099f6294173d8cd294817117c2753645afc195f11f517"): true, + common.HexToHash("0x9c9216d4f532209b02dd2780e8c415bcd5f542e27a3844f799e441f9cf31f821"): true, + common.HexToHash("0xaa7d9a445397c1020fcfef7e39fe2e754ecd2b1740be00124641a4dd1f90d843"): true, + common.HexToHash("0xb411dc11d466256144588833d125dbd4150d39a5f237a7473aadb4574b3d1e82"): true, + common.HexToHash("0x72433a53e6d0f9227dbc4a27361b5fedb2985257bf3a9c1bb499d31ff4927535"): true, + common.HexToHash("0x4ad848a31413405fe187cbeefd4fd350030a12973fecb01b8606bec95bbd707b"): true, + common.HexToHash("0xa67656e79cffb6ac1461dc6ebc54bf8cb0d3ce3dbd7848fb0f8268a688ee4c87"): true, + common.HexToHash("0x21446d624a891953d32fe0b8ee800d9b50efa4dfc1e6821762f032ef68d77eaa"): true, + common.HexToHash("0xda2fe59b584852f0cb2ffc36065e7f3554f1f0116fd14be4fa4ea95912663fe2"): true, + common.HexToHash("0x9856346aa90a4a06b29167ad821e7eb289e2e0b6de6c301b7992e65eedf152e0"): true, + common.HexToHash("0xc6cb2003600bdc43703abe34357cb91501152907abba21f79f9b53b3ac3a0af6"): true, + common.HexToHash("0xa585c877802efba10b717631795fa506b49ed552597a37386e08087146120f58"): true, + common.HexToHash("0x6675b88381d3959ec4ef693fde196ad5e507a77de5eca4c5fedb5b1067799b05"): true, + common.HexToHash("0x9f92f1cd1a83b8f2c87d0d339292365e3fc92b05e70b3d4578a83b5d634feb27"): true, + common.HexToHash("0x8d57f6eb62e2eeabcf38a72e2d39db4952134760c8d0189628b382c3758bed35"): true, + common.HexToHash("0xee1041d2e72ffe8df085e7477c64ceeda6ccfa645b226e9be7eca69972fab3d5"): true, + common.HexToHash("0x57ff0f6a74ceb5e5fab59fe7b5df263fbe2ac5d55e3992752308a491195d0b92"): true, + common.HexToHash("0x3d5ec468102927b37a1bc9824ca8353bab20f44374de6e3c6ad2a235818060d0"): true, + common.HexToHash("0x0583526e3207227a76aeed52f70f43b9bcfbc54b47384dc9daf646f5cb4de1c1"): true, + common.HexToHash("0x503fc82bc2024e617870985e9e6baeb9e7bf93fa7da15e9fba465994be092b3a"): true, + common.HexToHash("0x7f028632a0feb6a115f991f081d0663a72ccbbf95c48315f804188f26225c333"): true, + common.HexToHash("0xaaeb3e515dd0267a3184169210aa18626c23e31c6038537e46f45596c0f067d6"): true, + common.HexToHash("0x0924cf1dc0fcbc56bf290abf4e9187a744948f9dbe98ae2ee031683c91d59af2"): true, + common.HexToHash("0x443626418963b18c013c4d1964a6ef964040af647b1d71cba478d204f2bbcbff"): true, + common.HexToHash("0xd1b749e492eca49e10b0c0f0d61a2eec0a89fdbffe122007c6dd919fb427a65b"): true, + common.HexToHash("0x80f3b46b233670625549922a00a2cd3d1e5ce08298cdf81e79375360533991fc"): true, + common.HexToHash("0x7d85d78f7cbdbd86a8b4fca04c54c7a7fc60350e2a6d363ffaa44819ae4f7f14"): true, + common.HexToHash("0x64a813ee188c39a0a8cfbf6ae02db17c3304a5d6802cdfd74980f0a8a0b11679"): true, + common.HexToHash("0x80fe3c9474415b3c694c50e02d73829f9f6970ebdcff75e6c6b2207e15a897fb"): true, + common.HexToHash("0x41c02eb238a75843975b6cd4f4b389f80cdef77b43e3f86d314e0d07d4a96b3e"): true, + common.HexToHash("0x6c62abb07a3905d17866caf6cdb9e04ab53a5358e1e310d2cf10004c1f2a1770"): true, + common.HexToHash("0x724e5b0f28119bac269012aaccf6ef7a965877b1ab15a09a159ef9275179fe07"): true, + common.HexToHash("0x7944a6b382665f5aa5bda187c6b1d137220af05239dae7c6f89be3b59b72a712"): true, + common.HexToHash("0x8fa19fe3404d30e631d00f305afe38ad6d9c2b8106d8a2ad2ee2d53af153d4b2"): true, + common.HexToHash("0x38f892312ff7b8fb38ef9481f405b468a86125316cb005f21a2b6c1ed4b2cf45"): true, + common.HexToHash("0x4aa360527fdeb920d15ee37365e3c92332eec06a70d92ae060b6092c5d859bd8"): true, + common.HexToHash("0x60de79b01dfc2bc1c8e67e5240b01db13352d4318217c03951fe182650c94b4b"): true, + common.HexToHash("0xd39d868e5133a3971c803cd8d87362f2bbd49075f844d97082e874f804e373a1"): true, + common.HexToHash("0xb5091172417bfc15b878ac9a40bae281603a109a9f907638ee3b256044bf9c9e"): true, + common.HexToHash("0xc47b4e8f13c3810b844196983be3869189bfeb300636cbb8d6ab931ced0f6d1c"): true, + common.HexToHash("0xc7c6591f8caf8cf5e695bb40b042dc498bc1b391410730614eecd01976b5591a"): true, + common.HexToHash("0x9fe917898fa3ee56ff5e8a54bb0e0c175462c9af3858f497c77eb677751a049d"): true, + common.HexToHash("0xe82f06e6470c2ed139d4ebf2b15d6b8a07510e71550533ddfe1861620620bd37"): true, + common.HexToHash("0xe33a07c87418c5e39a56d5a1b1e2be71265fad308b8d600c8570b9fe5990ffa6"): true, + common.HexToHash("0xaf4bfde3a6bbc8052363ea7944e2655047d7f562898028de81cdee5000d94120"): true, + common.HexToHash("0xcbbc609af5a26f75a2cbb4fa330d91e31484bfa00d8e72c05bec24c4346df19e"): true, + common.HexToHash("0x0af3232485be4f654e02e6f86c13c20c4255f400b3b671f4618d541963d57b8b"): true, + common.HexToHash("0xdffee8e2325f6043ba34f9f633547a5f3f5068acfb4232240f8bfe8ff01306e9"): true, + common.HexToHash("0xd9b48107c455a4f5221c10c075df4b0192fbf9543393266a443b361aa84e2c17"): true, + common.HexToHash("0xf34cede5899fc570c29d38c10a4e6d4dabf208f805d3f1fa1a9fc1a7ce968f25"): true, + common.HexToHash("0x1fafef2819035f2b65ff99700b6c427692364b1bbd8acf3aa5c2ba0dc0fd08bb"): true, + common.HexToHash("0x8a63772f7b9abdb49b504b9898bc56177ad3a67628716f9a1a47ab4a63ecffb7"): true, + common.HexToHash("0x29f47baa451c6a79a9e00cad613de36886398fbbd4dfe548d90476f2df9b11b4"): true, + common.HexToHash("0x0d34ba009ef811c8df320e7e46a48940f84e59c4748ef6b634c5c5e205016ae8"): true, + common.HexToHash("0x5d0054fae7f48b77b2cb5ec5318b06f9a1368b1d113826d15ccc334123c6e956"): true, + common.HexToHash("0xebb2f3f527b84054fd9811e8ceb2c3fca0abe8bb722e678997aca30d77415f8a"): true, + common.HexToHash("0x3fb130e05f825357961d3f670019d8b161c914a164dfc5057edb709099d0137a"): true, + common.HexToHash("0x33716060a655c6ce19647a6218961eb8e0577e70e0484e877417836ea224d932"): true, + common.HexToHash("0xea8f64092e2854495239bc84cead1a811fbc5907d1a06363fd2e0e5ba80cc791"): true, + common.HexToHash("0xede5aa40c02a3c385d2d013714ff0790f7dfbd1361fc65710ecd2ecdc4ce95ee"): true, + common.HexToHash("0x5b8fd05a28d0304583f28d34693ab5254445f9f2ff90512aab7351b28070d7fe"): true, + common.HexToHash("0x56636b0fee3594ad4cfe31a2a86f84618b98f60a33c08da36e36de172ce2517d"): true, + common.HexToHash("0x99ed28ead02b11087f5df8ff89ee17e88e152172fee1400d692b845db93334be"): true, + common.HexToHash("0x2bf4ff3f0866677390d3c288ced2a701c864ffb9e96ec136ea32dac42fb95f95"): true, + common.HexToHash("0x9f34a7669bc48cba0eaf057f56aa0a3b6e93909eef57cfe4f66546d8d461b427"): true, + common.HexToHash("0x5510cfec8dd2d51bf27f8c8d1b7e68af56e18783715310ec5b297bbb674d1860"): true, + common.HexToHash("0x4738fd72bbb0f5496d95e5abdebb775463f832c2eede29e61f99ab4a987248ff"): true, + common.HexToHash("0xa1896b18267798037c29332389345583d876266fdfa74ab7a803c2a7d442f03c"): true, + common.HexToHash("0x605ddc19b3ce7be5bbaeebee98409e913a197b803ea8185755122025156d9d77"): true, + common.HexToHash("0xf1376e7988c88c8fae5ef2a6ef3b2801169af671c4cd8132a58c955aefb17177"): true, + common.HexToHash("0x77197ec7550a84a016f75156920ee0d74c772e7c89db81a071e9a396b2af73f2"): true, + common.HexToHash("0xb80d3a547a15350380d8561b61adff6ade7da36da7d56ce947531180c8cbd5aa"): true, + common.HexToHash("0x52a70bca4688bbc3d04e2f930bfc50ed8fbbc8f404844eef6b31b96b40374b05"): true, + common.HexToHash("0xfa1ee4def89f184353f044c03ee422fa2102150babd0ea7083b9baccfbe48509"): true, + common.HexToHash("0xc899cc9f0355b665d9234cea902c9e7257e548d24084fc5b1b7c14216e129b85"): true, + common.HexToHash("0x4314af325b4bc11baaadc94277999a1a372b572ccee30db8bb0adabd7a7140dd"): true, + common.HexToHash("0x7e4d56c1576c919281b768e3ca1bfb85b676443b2026c333c723e4bf8b702ff8"): true, + common.HexToHash("0xe2303b90dea65ccc1a9fe8da18e326fa71ccb377812a88eeb52032b8781f9138"): true, + common.HexToHash("0x18f57dcae844b5cb2741c88eb0b663a7796475a3a69c04a50ed32a4e81e9a149"): true, + common.HexToHash("0x5834eeeebe537d599ffb3d36810254332d00e5bd7bd3847ac5e88be739ed380f"): true, + common.HexToHash("0x917a5046effe5d62e94256ea10913cfb85e72b2af92193999ae84b9e94d610f7"): true, + common.HexToHash("0x57ae6ff53bc4b3e5d9e56e5b0ecf488a6b109c19755b7780078921286ad90434"): true, + common.HexToHash("0x66d155f16ad5b8b0e29e2c6a6c820382a41335df9e6a21b02c50ee5a841a0fff"): true, + common.HexToHash("0x2c36e16e4acbd26a9a75c397e606a18dfd44a8ae3de5b5844e24224bca9e3bf5"): true, + common.HexToHash("0x9d43895ac5e603186a886da7f5302ec71106e13362adf634673b2191925d8118"): true, + common.HexToHash("0xd5bdd7771d3b021f428ecca8f75a81504fb2523b89621a2f5f573e590e790996"): true, + common.HexToHash("0xf3c16b8f0b4be3156769943c92a156d8d60f07b68ce25ad6a30b33e7d3de76e9"): true, + common.HexToHash("0xd410e2cf7272aad93eba35781797a7cb4b26b5a1cca35ace865e2ec3238f2ecc"): true, + common.HexToHash("0x27c41ff582fa40319a89511beb5f30ca7d22f41b0d33321be58a2b8072437eb9"): true, + common.HexToHash("0x54ef09f9919932d9edae268fb558ad8d732e116e2ce16408c5cdaf206b84da1a"): true, + common.HexToHash("0x6187aa01ea087da574dbd823f5ddb55b9cf81f1f08057e801ed96192d125690f"): true, + common.HexToHash("0xd4328251c5ee28ed4bfc8680d9d2efe716a9a415108b8af343a4fb58dff88605"): true, + common.HexToHash("0x6a0b079de1e6164dd071d63b69e14431278173c58412358f81435011dcf9937d"): true, + common.HexToHash("0xd62b2753f4ff54d33d6f02c2cb853132994ddfd2944b845598ff9ad035eef2f2"): true, + common.HexToHash("0xb06cf999c6d861a205ed88a1c0ae76f2d81f7584fe5416e91af67186774e2590"): true, + common.HexToHash("0x552316ae8a4372574045c1a8a2edb51b2d3ff8f6cc07151627505bcaf9f1c06d"): true, + common.HexToHash("0xa9cfe5313bc4f618395e483a51ab36256277dc67fa9ce4246cdc6c8fbd89fed0"): true, + common.HexToHash("0x7a2fa87947512ee78dd99d4bf4fbe8c7e4ea135c0b950d6d0d0bff27e70f7bfe"): true, + common.HexToHash("0x39de5e5ba315f3786fe13e1ebddb4a068b9d06953b039f674e4fb02ea3b99311"): true, + common.HexToHash("0xd1663701b0148978890e787533240f69ccc31738947ea2f3c5e9270aa1ab17c4"): true, + common.HexToHash("0x718aedbc1bd16f90bd2019483fffe3027ff4df90cdd59eb691e70cfd54266f6d"): true, + common.HexToHash("0xd93cbb04ebd5752641a36dbe18b8705947a56ec765e01c47f0d872cb7daf4abb"): true, + common.HexToHash("0xcee320903216fa89618047e9cd2af9653f62c261f3bfdd837d70e80496df8d17"): true, + common.HexToHash("0x7d1affe74a8dca38ab56c433e165af9c5c75e4be90f5425eb18dc25c7e1da074"): true, + common.HexToHash("0x5bf9d5b53f31682e927f9b2193daec44e09506b867a7c815bd06283a8db0a584"): true, + common.HexToHash("0xfdf4b6c184b26cc910db96fc95760a7eb39a0d141a64ce9ed99f5aafcf4e01f6"): true, + common.HexToHash("0xad091e9928c493e6bb92753889b50a003787e81266d93376b20ef5dae94e5a51"): true, + common.HexToHash("0xb9ab3712efd0e5c767a1289650d5c7bfa8b9f91ce589d4f9b19fc3ad2db4f285"): true, + common.HexToHash("0x67b2f235af22d5be0bafc0f74779547cd0b4c5208ef09e40805ada4914ce9d3f"): true, + common.HexToHash("0xe9bd070e555193d3e033e0e5800cb5ee7c8b8cd8fda033760f54a63c1eb9d614"): true, + common.HexToHash("0x45b42b5fda64da7fdf5c9901312481baec2f3fd1e0a183c72e7615d31cde7ddd"): true, + common.HexToHash("0x54297d1ec78c5235967057f10bb5325499f95f7eefefdac9244076c62a58c3b1"): true, + common.HexToHash("0x5d525c4b30df13e22190b78c6aabe8409f8dc11f990f57cf06f4b8248e1ef324"): true, + common.HexToHash("0x7bd5bbea138853f7ab136b977d74db83985af085852fac1da7e7874af35ba65e"): true, + common.HexToHash("0x3155109b6ad841e75ce5399bc603fac7507ab18a693f3a9c616f6e17b5017ed7"): true, + common.HexToHash("0xaa9d9e114bf4063c15954b01dfc1a889dbc8e8159d9ef0a3651660bddad0446c"): true, + common.HexToHash("0x9f9dfd479983345a85a43acd680efdbec969067c1e6885851608d467a2d98fe1"): true, + common.HexToHash("0x304a356ae99121a9540babc9707c62b4c41f2f581a5e372ca04a374987c1566c"): true, + common.HexToHash("0xad1222c85393d0a32efcc152fe1e2df707b9b28289fc4af889a5e905c0863ca1"): true, + common.HexToHash("0x3752f3fc92b7d717c99869198e6a04bfb4a603b09426b6cdcf56d35981ec794f"): true, + common.HexToHash("0xc29624aa720f53e2834c316c2453ada58e8099f4cea46ad555a08b9088cd309b"): true, + common.HexToHash("0xd0993399d602aabb6e5ad3175e829ae99067aef9f125c8fb5b6060d01f4dcf6d"): true, + common.HexToHash("0x980640461434ef986262b59609edac0ded911dba84e27c2ef7e2d3eab72ae58f"): true, + common.HexToHash("0x7ed3ea59226f9e0fa647a72d03906269b4adf6473f3128490c05b4b32dc787cc"): true, + common.HexToHash("0x0b1f47516e5a8b6d19755d8166c607bbbc13e6465f1da8d118b6a26663bc5c3b"): true, + common.HexToHash("0x1d2d3831390f449ecac4415f433bd784c32a6421f76236896b5791683d163552"): true, + common.HexToHash("0xf5142d5cc6b171e24d85746fe40ed1c982e3e1dc6b8d4a5290a02ceebf9c71b9"): true, + common.HexToHash("0x9866e7f58aea3841719d2f96cb4118d2efa078fd84f709009ed579c33c89c82a"): true, + common.HexToHash("0x4192de0810d0cdeca111ec20dddf72fe693e7779e9909ca44470043fac11f2df"): true, + common.HexToHash("0xfeca51ea53cd94bd7d5b535290d7b712707e0e1fddcf790840586bfe1fe22c0e"): true, + common.HexToHash("0x0bc2c5704d60c8c0f2232e4b97c6a0a92528d9b16484c74aad4db9559052d7b9"): true, + common.HexToHash("0x4d453b0fb2ac05829616d16d154745dc46e619509ad8a89e54fff2c2d06c443d"): true, + common.HexToHash("0x624894b3ede185b16645f147a10238c74b192ffd89cb5c90f6433ed268ff1df7"): true, + common.HexToHash("0x84c7e5b7eb80edb9cf35923971277cf5c53a984d383845292a38bc704251916e"): true, + common.HexToHash("0x7ff681ba115e39f18c6200f5770b389a8a4a22f45d81a51acbaa36aa4010be8b"): true, + common.HexToHash("0xe3b5656d8643f42edfca8a86d4a0724c0473ecce1132e811ae3740320a5d87f4"): true, + common.HexToHash("0xcf9a6e62301deff138455b3b21f468024363384a7b9d747a8b51f634cf78bd80"): true, + common.HexToHash("0x486744320db74b4c17b5163ac2b3dceb20ff320932fc7e197335c640605d2e1d"): true, + common.HexToHash("0x60bd77c934d9885fb53b7e6b2fe166a654c8d4331e3aff8d84ee306c6599971a"): true, + common.HexToHash("0x512cace2a3e5c326e543606c5c39eef9bba17c6c1c812e29a808c117d27e8743"): true, + common.HexToHash("0xb046612a0048ee5602a0a9d73b091061142b9433fe98f4f95e4abdfbaf3585b2"): true, + common.HexToHash("0x3f33d0a01d14b9f5ef58cce6449f9ef011f19836ce055f84ad84103aafe02211"): true, + common.HexToHash("0x6abe8b77b0cbe0bbbeaee7bca24979adc702ff81e350fd745608e129dae4043a"): true, + common.HexToHash("0xacdba686bf9aa57d466d785552921e1a425e7877b1a33009ee851c01e66cea49"): true, + common.HexToHash("0xac2459ccb3156d56d24790358c8bb995427a8d2d768d65dca94a1e283c905f62"): true, + common.HexToHash("0x4fbb34164b7d330b345a9ee65e80860188e80d7dd41a998ca835dd6853eec733"): true, + common.HexToHash("0x05c550bdeb532c6aff332a1a455aa03fbc0d7666139a8d12feb5eaaec2cb4380"): true, + common.HexToHash("0xa484505835ee9b234f2b9a18bb28beaf4b2b5c2bd618149acf8cb810f86f61bc"): true, + common.HexToHash("0xfad6eae71404839ec86ccf3cc8d2f67e1ab3549aff5222355d3b8978240b5289"): true, + common.HexToHash("0x434813f871ba32cdfb9b2cc242e3c3c9e7383ad27bbab261dc4ade1f8ab0417b"): true, + common.HexToHash("0xe73a8e83b4ad5d77e35145dc67d71f0426f2cb844ed851163adfbc1d7214638e"): true, + common.HexToHash("0x66b44dc872b92daeb7c56336c868a501232b4bbd3ede237605cbbc0addd7dd01"): true, + common.HexToHash("0x4c7be533d3cf79a4e0ab4f6941a94dac5b2b18cd5c62f342ddf5341736f3a4ae"): true, + common.HexToHash("0xd721b8afdb1b4644c0d21ff2ab1a9c95d849d34ef6d695147f4d77a4ab4e3b26"): true, + common.HexToHash("0x10779e99cf64d6f5834d6b7be01479f2085b7ec1aba583295ccf03882b1a4b9b"): true, + common.HexToHash("0x4b23e5b16d2e4e9237d9b20f231d5a6d7c2c1c3c25f420575056d7e9239542cd"): true, + common.HexToHash("0x64b4fb5ca16096cf2c472cd3501e211bf78f24a5bbdfb0a63484161bb7904523"): true, + common.HexToHash("0xb2c62a6ceeff1483fb9b53aae2e0a4181753390187d13d901d87b82c8189ace7"): true, + common.HexToHash("0x72c36d2cf9cfeb4291272be4d827b982b4c22d6bce87e623c60d0d2fa8912f78"): true, + common.HexToHash("0xdf4f6177eb117407751efd5e39cd47101e1a7a3298b1f3e62c586e0332f6bb14"): true, + common.HexToHash("0x091083c84b1047b550b5d626eef78360067354a44c9c1f17ab3da32d4a0ab675"): true, + common.HexToHash("0x2f2624ff1a3df966b58933585be4a23e634d8787432fa6507dbe31055a59e088"): true, + common.HexToHash("0xc7c2c477223b2fe9dceb421874e7fe21b5dac7d8f160040002bcd362f1a3c56e"): true, + common.HexToHash("0x43db96cd1f16d7eb4969153b2ab77f6adf294e2b25d37d6083f49c39597fd997"): true, + common.HexToHash("0x3cfeff570bd97c42e2b3957d33e5fd86f3f73154572b33c67291d863ddf861bd"): true, + common.HexToHash("0x3157970fbd37968c8cd5efb415e7bda9a24f872412ae5313af9894d8f0c53eaf"): true, + common.HexToHash("0x2e2668c22277a70dd9523342e9ee04019b04a3d3a68167b843856c01914c8301"): true, + common.HexToHash("0xa1f71bf222062dd08500761277a94a68870987fd6f5f63c0c05999024260839e"): true, + common.HexToHash("0x180b40bc702633cd72fe347e199e9a3be7874999d7b01c83bfbcec786bdd6796"): true, + common.HexToHash("0x85bd8abdaaf501880d432d43f44ad63784503439575c20db28f1e59dc4dc5225"): true, + common.HexToHash("0xf633cc2e962562b547f9803ec4fb70b9f71d2e1750f9bfe093b4408acce7bbf8"): true, + common.HexToHash("0xf0eb1d0fab2987951f695085f1add99b3195d0ca3e0ed9b60ffbaca04dc7b518"): true, + common.HexToHash("0x859b060e103c7b13befe7ae18d47a874bb091d54d24961fffdd5896020d317eb"): true, + common.HexToHash("0x02fd36f32483b2219fddf3d23c9755b50effa968cb43a0b6d9ef00daaa14510b"): true, + common.HexToHash("0x6e9b6c4ae7844869c1cc7b1ebe7aa7cc27633054ee007e7e5bcbb1786a04ff69"): true, + common.HexToHash("0x2bff36dd7f64aa5af4a03a68ca2e85bedd5d2d00ef131dda94d13b1db4723c9b"): true, + common.HexToHash("0xdaafc62841134d6b40e9c64ce7bf64bf98e3fda994407ca33a04d6c6ee0c5103"): true, + common.HexToHash("0x18996e055aac3438d477b83f9c1d3a1e8d807e75b022a2955877aa89935f826e"): true, + common.HexToHash("0xba8df1fb8a4e7402251aa4232209c905ae76ae70e3593a6a1bc211495b53b267"): true, + common.HexToHash("0xaeefc2634406cfef34189907c5b05583522082dd1f693df240545a15f76a99b2"): true, + common.HexToHash("0x5da4daf74c0db5f8a550e55bf301890e72ba09b027f6c6f691f7a987f894405d"): true, + common.HexToHash("0x9402d3915e204596b62820e0e40d738a703d1c13dda9bb8ae016218aba462abd"): true, + common.HexToHash("0x5fcaca79be2fa7ac6572b6ed62e8579ce533799edcbf1c2956e77c0e81ed9151"): true, + common.HexToHash("0xfedc90f490c0a9122e0ad71b756c3fb14ab2f086603013272ebaba3ba256eea9"): true, + common.HexToHash("0x1ffae809539978877aa20ff5da9fd6269444e57026b151d8d069360d971a8df2"): true, + common.HexToHash("0x6eea2d50f4ebcfb2d9710b87a5876a29f0de17dc88d028e010221cf7e00e81eb"): true, + common.HexToHash("0xf8bfca9e8084c8f0629bdc3b5b5f2553a7f1e6f70c7a3c24c9a4a04117e78bc3"): true, + common.HexToHash("0x9bed94bd79a7488aecfb1fda41067b07859d8c09b8cb767adbdac5b00804161f"): true, + common.HexToHash("0x65f2b5f8af9082c9fb27d80f219be35ca990df354a756379f976bf91f2251883"): true, + common.HexToHash("0xcfeab12d7a8e472250e219637011459b99f4062ba4f6ee6ecd3a2a46d99ead9f"): true, + common.HexToHash("0x5bafaeed11b6feb6ab1b805091b59331ac54df08e1c7c7c2431b34ea8668e3e6"): true, + common.HexToHash("0x79b181167c4e0280eacd9adbdf957845097e6cb01c598905ba37dca3ec16ac66"): true, + common.HexToHash("0xd5b9c767834214a68376b260d825624a3c4ba917ebe28bcf1b06c525471a65cb"): true, + common.HexToHash("0xc1f9b00cf17f96f3d06fcb2f62675bd9b2303bbbbf208b7d74176681cf8d4777"): true, + common.HexToHash("0x09a31e73689c9339855ffe22542ea4a417288fb276130b4de99eb833528540af"): true, + common.HexToHash("0x8e946ac3e56e99759ee4357f06c9070b5fd742551d85041b7c6320ee9f82fc93"): true, + common.HexToHash("0x20af83bb67730f90355ec2b13536cf05eaf9e3da14a2096e56096f38f90c3f15"): true, + common.HexToHash("0x5598dc7312dcf943776625047bff1f7f287fcb8ba78de41343b9a1aa1748010e"): true, + common.HexToHash("0xcfa58d74b8f0de548d01ba5cea44af0e02b68579b0d2bf146aa3883ca2d5707b"): true, + common.HexToHash("0x3dd0efbf33321d079d6c5eb5f4a0892d0e3acf1a5a858e149eeb6fc809477d3e"): true, + common.HexToHash("0x1ae3ba422e13be8ce2dfbdc427b7f9565c8cf0c64318a51a7711838a8b04b9e7"): true, + common.HexToHash("0xc5228e0b9e49eeeb3fc923a563103339de9527e7547e203517668ea64db198a7"): true, + common.HexToHash("0x67ce79d626f1925fd196db430525d0ba0c2e41837cde00b175f4d1cb90c3c84c"): true, + common.HexToHash("0xc384cc216342b9fb529efbed00bc9a5fd0fb3f2eb7f396b3e90cfda151103860"): true, + common.HexToHash("0xdf341a135466eac1326d5596f9c6aa6e066a908258a4ec94918a73e84f155f0d"): true, + common.HexToHash("0x2d4ecce29c53b761352c332e582eb3683175d49ee95c2f1ddc64f6b8af8927cc"): true, + common.HexToHash("0xcc5381a0447254ca4d6042b6c85917300202409ccae83e6357b942cce1b0c240"): true, + common.HexToHash("0xca6393519a7ded861467ecfc467764a453ef7d26bcb08ae168fd21f7322226b6"): true, + common.HexToHash("0xf6a8221ccae907afb1567cad14acad68604af0e742497c3667a1864c1ae38c49"): true, + common.HexToHash("0x839127e9bb0d4bf6f29a90d1bbed8159647f8f943eb5c6ee2503dc5d6067af10"): true, + common.HexToHash("0x6bfb641277f5d218abfb55a5a1eba517be3069f1be545f6bc6832af8916a0f49"): true, + common.HexToHash("0x3967f9c16ef06e02e4496e95169a396463c68ce5985695f1523289ac635d450c"): true, + common.HexToHash("0x3e63bfebff8be233e2352ac5a784bae34c9c481038b8607c1b2cf7db47fc77e7"): true, + common.HexToHash("0xc945ce775895fa3de520d11b64ce63956e76a02326cf1b06421d742c51a91c35"): true, + common.HexToHash("0x35fa312e8ee4b87f51a71c2cbf23fde64e48a078795fac3a410c4c777c2324c1"): true, + common.HexToHash("0xc2011db5db6eecdf5b9e25ecdde215939024cff0cc325516e9231454548edd11"): true, + common.HexToHash("0xbf350f2aa20fe179e3aff0e4ce7f7e971817d7578efc3b78706019aea370fd7b"): true, + common.HexToHash("0x54b466c8abf10d8166e2a5392b0f25f082d65c51d8e4a9d26f26a83ce4ade1b6"): true, + common.HexToHash("0x7891cd6b12117e7a1aecccbbdf6723462e8064b25355d6ccb945684ed6d4b424"): true, + common.HexToHash("0x2f8c2305fd8ebf1e59dc328ef50163b554a3b58c08aea3437d88003f9b2e77a7"): true, + common.HexToHash("0xf617dd94df9a49cc6eb438f5fb5019244c92721d9769b017d3535bca5b0ae69a"): true, + common.HexToHash("0x8a8311025c3ff614fc7439d9d1cf705029db2ccb89f780d2c2ff0eac62617820"): true, + common.HexToHash("0xbd7db4429d0d3da187d72dc2e20c694b4da5d5e068204cd33cd62e5128dc3341"): true, + common.HexToHash("0xe3be2584ba9a1f19cc03d9447a848f4e767b6cbd17d5702a71ccf9223eb9d2b7"): true, + common.HexToHash("0xcea45d58d3b7ec48f55b1e557be12ab55979dd1963927b5062634602a8fe60bd"): true, + common.HexToHash("0x281c17c00aff9d53e19a74e7c4656a522af337e09ae4eae7b8799e8770728026"): true, + common.HexToHash("0xecd679d95f9e3c25e42ab1d1c3c52ecf2c5af1b8f745da67e0ca17d25460b0e8"): true, + common.HexToHash("0x1fec4948023fa9b5bbc6906b9d9e7b0609c520276af80d7b150c15563860f935"): true, + common.HexToHash("0xffcb2405d1e53131c36d5c0fe19e983862f28181604688ce6049d1f95b7ac0de"): true, + common.HexToHash("0x807756d59481ccc5933ddd1f6dbdbc453e02e796f53e8f98219f74b39f9a6d8a"): true, + common.HexToHash("0xebcd9acee77a1938d94b520fd5fbd14286f0c24e4b6e39c4c7ff3254201f128d"): true, + common.HexToHash("0x4b65a07cb34534a1cf3d42876b7e3fec0857c2db6c394cc8d9edb8a56f5c603b"): true, + common.HexToHash("0xd5d218821f840e7c482edb833ddfe83d91ea98ddf85870cadafaaba5cc265e70"): true, + common.HexToHash("0xd10041cb4db026a7dd62abc407cf38ae4d626de0d2bd1aea009aaf62d61874fa"): true, + common.HexToHash("0x98c13e2b19a57948ff28601e02eb0c86d2a2717719a55aef23f688bf57f65eef"): true, + common.HexToHash("0x77bcb91bb115172de82286b40f9d8b653bf4499a754af12c260557d156d2846c"): true, + common.HexToHash("0x993abd321fab7b5806621b800a61eb09a64c8371446a54bb336d2214aab564e6"): true, + common.HexToHash("0xea8d8c1a7e90f15d845b57e0875d95e5a56bb3fa919b813f5dcd53ee18a5dfb0"): true, + common.HexToHash("0x97a76bb7de8d018dc97f51b04de375368fba59c6a481c0ecff36c34c3c69755c"): true, + common.HexToHash("0xde6ba823df53acd77cafab7b8bcb192f57bfb1b7a0e0ac0885ed7dd06408eba1"): true, + common.HexToHash("0x4d8eb77a10603a6a1092f222e53192d3ea04bfcf6b2535252ee9d025eda6e035"): true, + common.HexToHash("0x974dab0aca5b511cd879220f864f5d00e206b19cc31517353376d74588dc6584"): true, + common.HexToHash("0xbd996c7f4e81dd6c7e40a3b2f77e18c9d81da59cf9c051b12455467d5a4daba1"): true, + common.HexToHash("0xf3165b999b2a1583267784d514523019d225ad589686e6b277aaa550f1fdca57"): true, + common.HexToHash("0xe0e6c1e2f65dfbdafba21257b33ba1cdbdc5e73ef604a26b7670814ab27f79a1"): true, + common.HexToHash("0x7fb1a5ee9c8e803446ab30f7f15085afe49e0ed5b24368b0663c4ca722c7a56f"): true, + common.HexToHash("0x9519657d4bd8c6d20fcb5044d253e8199b78fd984fe817207acb71c898131447"): true, + common.HexToHash("0x5f6d8d20803104321f8dc27836e11c1b5e968acd1a68a20d5b5f689a4d620e31"): true, + common.HexToHash("0x67ea4e3578a302dcd02f36fde192c57bc4d61de453e739242d58adeccd0001f9"): true, + common.HexToHash("0x7b7ef12edb54edc40875263728248b4b642da6afcc5e01636c26fc124e234578"): true, + common.HexToHash("0x3187b8a4e6d288e5ca512fa9c3fddfa80091c8008c36e24ce825ac0df856b001"): true, + common.HexToHash("0x69255c34cf9effc9db84fc8b4a774c1fce9e46a4320125f3028e6f4b0243eca8"): true, + common.HexToHash("0x60fcbbaaa0823b4c658e2dafcac20c0ef21d21072269fa406b8c20fcc1819bd7"): true, + common.HexToHash("0x560ab268ff09cdf42ebf05862f2100675d11791b793d17ab4dc128cd2091a746"): true, + common.HexToHash("0x91212b534fde3f21d8dd45db995424eb6cd8ae0652c46da063ceef016c673a23"): true, + common.HexToHash("0xa2975d0cca0146ce79165fbf8537728b8766d92c83acad5a54c1158b0ceaf85c"): true, + common.HexToHash("0xbc8e444ee8df63f2ce650ce2873d390a48365e1d50d89a795a1f923716c1b56a"): true, + common.HexToHash("0xa4f802e99df917e41bad00c83ee5dbaa861ff950a70fb7608051be1b0944ae59"): true, + common.HexToHash("0x34154fc87b6d28b3d2690ca88001f7438b6885e97239cd9b8128b6be154d830c"): true, + common.HexToHash("0x2a0c86c34374f211ab3973584227984719f0b87f77a8afa31fdcf3c467acacfa"): true, + common.HexToHash("0xfb992b5803e8dc1f2dbfb8c604e2ba7cb2b1488c8d7ccf6f4805e308d5350f3a"): true, + common.HexToHash("0x1a2514fd01e697c12f129cfb2bc2a81780a3e2a08aade45ebcc390e79995abf5"): true, + common.HexToHash("0x1419fdafb1ee3ea6cc608bb6faebd789dae0cf77d01cab7eb13471bc8797a022"): true, + common.HexToHash("0xda7c8fc5586c657a200c9cf7d3d58a66e0a2f85fe7e35f4fa79e0c76c30bc0b0"): true, + common.HexToHash("0xf09b480278faeba7bede5bcdb54c8aedd1035a7505e3c32f19890c482f5f0c7c"): true, + common.HexToHash("0x11057f1141f797ba816b4a256b13c60f2d2a446ab197b0e41df6976c9779befe"): true, + common.HexToHash("0x047e7dd4d9aedd436ebfd33b1481273d982dcbc0214e9524e52b3455ab1dad77"): true, +} + +/* Sample Go script used to parse through the list of OVM1 withdrawals to generate and +dump the hashes that need to get skipped as L1 finalization events are processed. + - Dune Query used to generate CSV: https://dune.com/queries/3231132/5404047 + +func GenerateOVM1Hashes() error { + file, err := os.Open("OVM1Withdrawals.csv") + if err != nil { + return err + } + + r := csv.NewReader(file) + records, err := r.ReadAll() + if err != nil { + return err + } + fmt.Printf("First Nonce: %s, Last Nonce: %s", records[1][0], records[len(records)-1][0]) + + withdrawals, messages := "", "" + for _, record := range records[1:] { + nonce, ok := new(big.Int).SetString(record[0], 10) + if !ok { + return fmt.Errorf("bad nonce: %s", record[0]) + } + + target := common.HexToAddress(record[1]) + sender := common.HexToAddress(record[2]) + data := common.FromHex(record[3]) + + legacyWithdrawal := crossdomain.NewLegacyWithdrawal(predeploys.L2CrossDomainMessengerAddr, target, sender, data, nonce) + + relayMsgVersion := record[6] + switch relayMsgVersion { + case "0": + messageHash, err := crossdomain.HashCrossDomainMessageV0(target, sender, data, nonce) + if err != nil { + return err + } + + messages = fmt.Sprintf("%s\ncommon.HexToHash(\"%s\"): true,", messages, messageHash) + case "1": + l1CdmAddr := config.Presets[10].ChainConfig.L1Contracts.L1CrossDomainMessengerProxy + value, err := legacyWithdrawal.Value() + if err != nil { + return err + } + + migratedWithdrawal, err := crossdomain.MigrateWithdrawal(legacyWithdrawal, &l1CdmAddr, big.NewInt(int64(10))) + if err != nil { + return err + } + + withdrawalHash, err := migratedWithdrawal.Hash() + if err != nil { + return err + } + + messageHash, err := crossdomain.HashCrossDomainMessageV1(nonce, sender, target, value, new(big.Int), data) + if err != nil { + return err + } + + withdrawals = fmt.Sprintf("%s\ncommon.HexToHash(\"%s\"): true,", withdrawals, withdrawalHash) + messages = fmt.Sprintf("%s\ncommon.HexToHash(\"%s\"): true,", messages, messageHash) + } + } + + withdrawalsFile, err := os.Create("skipped_withdrawal_hashes.txt") + if err != nil { + return err + } + + messagesFile, err := os.Create("skipped_message_hashes.txt") + if err != nil { + return err + } + + withdrawalsFile.WriteString(withdrawals) + messagesFile.WriteString(messages) + return nil +} + +*/ diff --git a/indexer/processors/contracts/cross_domain_messenger.go b/indexer/processors/contracts/cross_domain_messenger.go index b74e2fc24185..52cf944d33a1 100644 --- a/indexer/processors/contracts/cross_domain_messenger.go +++ b/indexer/processors/contracts/cross_domain_messenger.go @@ -4,43 +4,18 @@ import ( "fmt" "math/big" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum-optimism/optimism/indexer/bigint" "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/op-bindings/bindings" -) - -var ( - // Standard ABI types copied from golang ABI tests - uint256Type, _ = abi.NewType("uint256", "", nil) - bytesType, _ = abi.NewType("bytes", "", nil) - addressType, _ = abi.NewType("address", "", nil) - - CrossDomainMessengerLegacyRelayMessageEncoding = abi.NewMethod( - "relayMessage", - "relayMessage", - abi.Function, - "external", // mutability - false, // isConst - true, // payable - abi.Arguments{ // inputs - {Name: "target", Type: addressType}, - {Name: "sender", Type: addressType}, - {Name: "data", Type: bytesType}, - {Name: "nonce", Type: uint256Type}, - // The actual transaction on the legacy L1CrossDomainMessenger has a trailing - // proof argument but is ignored for the `XDomainCallData` encoding - }, - abi.Arguments{}, // outputs - ) + "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" ) type CrossDomainMessengerSentMessageEvent struct { - Event *database.ContractEvent - MessageCalldata []byte - BridgeMessage database.BridgeMessage + Event *database.ContractEvent + BridgeMessage database.BridgeMessage + Version uint16 } type CrossDomainMessengerRelayedMessageEvent struct { @@ -85,32 +60,47 @@ func CrossDomainMessengerSentMessageEvents(chainSelector string, contractAddress return nil, err } - version, _ := DecodeVersionedNonce(sentMessage.MessageNonce) + _, versionBig := crossdomain.DecodeVersionedNonce(sentMessage.MessageNonce) + version := uint16(versionBig.Uint64()) if i < numVersionZeroMessages && version != 0 { - return nil, fmt.Errorf("expected version zero nonce. nonce %d tx_hash %s", sentMessage.MessageNonce, sentMessage.Raw.TxHash) + return nil, fmt.Errorf("expected version zero nonce: nonce %d, tx_hash %s", sentMessage.MessageNonce, sentMessage.Raw.TxHash) } - // In version zero, to value is bridged through the cross domain messenger. - value := big.NewInt(0) - if version > 0 { + value := bigint.Zero + var messageHash common.Hash + switch version { + case 0: + messageHash, err = crossdomain.HashCrossDomainMessageV0(sentMessage.Target, sentMessage.Sender, sentMessage.Message, sentMessage.MessageNonce) + if err != nil { + return nil, err + } + + case 1: sentMessageExtension := bindings.CrossDomainMessengerSentMessageExtension1{Raw: *sentMessageExtensionEvents[i].RLPLog} err = UnpackLog(&sentMessageExtension, sentMessageExtensionEvents[i].RLPLog, sentMessageExtensionEventAbi.Name, crossDomainMessengerAbi) if err != nil { return nil, err } + value = sentMessageExtension.Value - } + messageHash, err = crossdomain.HashCrossDomainMessageV1(sentMessage.MessageNonce, sentMessage.Sender, sentMessage.Target, value, sentMessage.GasLimit, sentMessage.Message) + if err != nil { + return nil, err + } - messageCalldata, err := CrossDomainMessageCalldata(crossDomainMessengerAbi, &sentMessage, value) - if err != nil { - return nil, err + default: + // NOTE: We explicitly fail here since the presence of a new version means finalization + // logic needs to be updated to ensure L1 finalization can run from genesis and handle + // the changing version formats. Any unrelayed OVM1 messages that have been hardcoded with + // the v1 hash format also need to be updated. This failure is a serving indicator + return nil, fmt.Errorf("expected cross domain version 0 or version 1: %d", version) } crossDomainSentMessages[i] = CrossDomainMessengerSentMessageEvent{ - Event: &sentMessageEvents[i], - MessageCalldata: messageCalldata, + Event: &sentMessageEvents[i], + Version: version, BridgeMessage: database.BridgeMessage{ - MessageHash: crypto.Keccak256Hash(messageCalldata), + MessageHash: messageHash, Nonce: sentMessage.MessageNonce, SentMessageEventGUID: sentMessageEvents[i].GUID, GasLimit: sentMessage.GasLimit, @@ -157,26 +147,3 @@ func CrossDomainMessengerRelayedMessageEvents(chainSelector string, contractAddr return crossDomainRelayedMessages, nil } - -// Replica of `Encoding.sol#encodeCrossDomainMessage` solidity implementation -func CrossDomainMessageCalldata(abi *abi.ABI, sentMsg *bindings.CrossDomainMessengerSentMessage, value *big.Int) ([]byte, error) { - version, _ := DecodeVersionedNonce(sentMsg.MessageNonce) - switch version { - case 0: - // Legacy Message - inputBytes, err := CrossDomainMessengerLegacyRelayMessageEncoding.Inputs.Pack(sentMsg.Target, sentMsg.Sender, sentMsg.Message, sentMsg.MessageNonce) - if err != nil { - return nil, err - } - return append(CrossDomainMessengerLegacyRelayMessageEncoding.ID, inputBytes...), nil - case 1: - // Current Message - msgBytes, err := abi.Pack("relayMessage", sentMsg.MessageNonce, sentMsg.Sender, sentMsg.Target, value, sentMsg.GasLimit, sentMsg.Message) - if err != nil { - return nil, err - } - return msgBytes, nil - } - - return nil, fmt.Errorf("unsupported cross domain messenger version: %d", version) -} diff --git a/indexer/processors/contracts/legacy_ctc.go b/indexer/processors/contracts/legacy_ctc.go index b34c35ef84e3..da237f6ae2e9 100644 --- a/indexer/processors/contracts/legacy_ctc.go +++ b/indexer/processors/contracts/legacy_ctc.go @@ -39,7 +39,7 @@ func LegacyCTCDepositEvents(contractAddress common.Address, db *database.DB, fro return nil, err } - // Enqueued Deposits do not carry a `msg.value` amount. ETH is only minted on L2 via the L1StandardBrige + // Enqueued Deposits do not carry a `msg.value` amount. ETH is only minted on L2 via the L1StandardBridge ctcTxDeposits[i] = LegacyCTCDepositEvent{ Event: &events[i].ContractEvent, GasLimit: txEnqueued.GasLimit, diff --git a/indexer/processors/contracts/optimism_portal.go b/indexer/processors/contracts/optimism_portal.go index ea56714c4b09..141001bdc004 100644 --- a/indexer/processors/contracts/optimism_portal.go +++ b/indexer/processors/contracts/optimism_portal.go @@ -30,12 +30,6 @@ type OptimismPortalWithdrawalFinalizedEvent struct { Event *database.ContractEvent } -type OptimismPortalProvenWithdrawal struct { - OutputRoot [32]byte - Timestamp *big.Int - L2OutputIndex *big.Int -} - func OptimismPortalTransactionDepositEvents(contractAddress common.Address, db *database.DB, fromHeight, toHeight *big.Int) ([]OptimismPortalTransactionDepositEvent, error) { optimismPortalAbi, err := bindings.OptimismPortalMetaData.GetAbi() if err != nil { diff --git a/indexer/processors/contracts/utils.go b/indexer/processors/contracts/utils.go index d95d18517e84..1c249d4b9765 100644 --- a/indexer/processors/contracts/utils.go +++ b/indexer/processors/contracts/utils.go @@ -1,33 +1,13 @@ package contracts import ( - "encoding/binary" "errors" "fmt" - "math/big" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/core/types" ) -// DecodeVersionNonce is an re-implementation of Encoding.sol#decodeVersionedNonce. -// If the nonce is greater than 32 bytes (solidity uint256), bytes [32:] are ignored -func DecodeVersionedNonce(nonce *big.Int) (uint16, *big.Int) { - nonceBytes := nonce.Bytes() - nonceByteLen := len(nonceBytes) - if nonceByteLen < 30 { - // version is 0x0000 - return 0, nonce - } else if nonceByteLen == 31 { - // version is 0x00[01..ff] - return uint16(nonceBytes[0]), new(big.Int).SetBytes(nonceBytes[1:]) - } else { - // fully specified - version := binary.BigEndian.Uint16(nonceBytes[:2]) - return version, new(big.Int).SetBytes(nonceBytes[2:]) - } -} - func UnpackLog(out interface{}, log *types.Log, name string, contractAbi *abi.ABI) error { eventAbi, ok := contractAbi.Events[name] if !ok { diff --git a/indexer/ui/Dockerfile b/indexer/ui/Dockerfile deleted file mode 100644 index 5907e33b43de..000000000000 --- a/indexer/ui/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM node:18.16.0-bullseye-slim - -WORKDIR /app - -RUN echo {} > package.json && \ - npm install prisma - -COPY indexer/ui/prisma.sh prisma.sh -COPY indexer/ui/schema.prisma schema.prisma - -RUN npx prisma generate --schema schema.prisma - -CMD ["npx", "prisma", "studio", "--port", "5555", "--hostname", "0.0.0.0", "--schema", "schema.prisma" ] diff --git a/indexer/ui/README.md b/indexer/ui/README.md deleted file mode 100644 index 61f8c743ce03..000000000000 --- a/indexer/ui/README.md +++ /dev/null @@ -1,39 +0,0 @@ -## @eth-optimism/indexer-ui - -A simple UI for exploring the indexer DB using [Prisma studio](https://www.prisma.io) - -## Usage - -Included in the docker-compose file as `ui` service - -```bash -docker compose up -``` - -Prisma can be viewed at [localhost:5555](http://localhost:5555) - -## Update the schema - -The [prisma schema](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference) is what allows prisma to work. It is automatically generated from the db schema. - -To update the schema to the latest db schema start the database and run [./ui/prisma.sh](./prisma.sh). Optionally pass in a DATABASE_URL if not the default - -```bash -DATABASE_URL=postgresql://db_username:db_password@postgres:5432/db_name -``` - -## Other functionality - -We mostly just use prisma as a UI. But brisma provides much other functionality that can be useful including. - -- Ability to change the [db schema](https://www.prisma.io/docs/reference/api-reference/command-reference#db-push) direction from modifying the [schema.prisma](./schema.prisma) in place. This can be a fast way to [start prototyping](https://www.prisma.io/docs/guides/migrate/prototyping-schema-db-push) -- Ability to [seed the database](https://www.prisma.io/docs/guides/migrate/seed-database) -- Ability to write quick scripts with [prisma client](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference) - -## Running prisma studio outside of docker - -Prisma can also be run with [npx](https://docs.npmjs.com/cli/v8/commands/npx) - -```bash -npx prisma studio --schema indexer/ui/schema.prisma -``` diff --git a/indexer/ui/prisma.sh b/indexer/ui/prisma.sh deleted file mode 100755 index b2e1eb1f8e46..000000000000 --- a/indexer/ui/prisma.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash - -# This script updates the prisma schema -# -SCRIPT_DIR=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) - -DATABASE_URL=${DATABASE_URL:-postgresql://db_username:db_password@localhost:5434/db_name} -PRISMA_FILE="$SCRIPT_DIR/schema.prisma" -TEMP_FILE="$SCRIPT_DIR/temp-schema.prisma" - -function update_prisma() { - echo "Updating Prisma Schema..." - npx prisma db pull --url $DATABASE_URL --schema $PRISMA_FILE - echo "Update completed." -} - -function check_prisma() { - echo "Checking Prisma Schema..." - cp $PRISMA_FILE $TEMP_FILE - npx prisma db pull --url $DATABASE_URL --schema $TEMP_FILE - diff $PRISMA_FILE $TEMP_FILE > /dev/null - if [ $? -eq 0 ]; then - echo "Prisma Schema is up-to-date." - rm $TEMP_FILE - else - echo "Prisma Schema is not up-to-date." - rm $TEMP_FILE - return 1 - fi -} - -if [ "$1" == "--check" ]; then - check_prisma -else - update_prisma -fi diff --git a/indexer/ui/schema.prisma b/indexer/ui/schema.prisma deleted file mode 100644 index e3ba4a3c91f4..000000000000 --- a/indexer/ui/schema.prisma +++ /dev/null @@ -1,205 +0,0 @@ -generator client { - provider = "prisma-client-js" -} - -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -} - -model l1_bridged_tokens { - address String @id @db.VarChar - bridge_address String @db.VarChar - name String @db.VarChar - symbol String @db.VarChar - decimals Int - l2_bridged_tokens l2_bridged_tokens[] -} - -model l2_bridged_tokens { - address String @id @db.VarChar - bridge_address String @db.VarChar - l1_token_address String? @db.VarChar - name String @db.VarChar - symbol String @db.VarChar - decimals Int - l1_bridged_tokens l1_bridged_tokens? @relation(fields: [l1_token_address], references: [address], onDelete: Cascade, onUpdate: NoAction) -} - -/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info. -model l1_block_headers { - hash String @id @db.VarChar - parent_hash String @unique @db.VarChar - number Decimal @unique @db.Decimal - timestamp Int @unique - rlp_bytes String @db.VarChar - l1_contract_events l1_contract_events[] -} - -/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info. -model l1_bridge_deposits { - transaction_source_hash String @id @db.VarChar - cross_domain_message_hash String @unique @db.VarChar - from_address String @db.VarChar - to_address String @db.VarChar - local_token_address String @db.VarChar - remote_token_address String @db.VarChar - amount Decimal @db.Decimal - data String @db.VarChar - timestamp Int - l1_bridge_messages l1_bridge_messages @relation(fields: [cross_domain_message_hash], references: [message_hash], onDelete: Cascade, onUpdate: NoAction) - l1_transaction_deposits l1_transaction_deposits @relation(fields: [transaction_source_hash], references: [source_hash], onDelete: Cascade, onUpdate: NoAction) -} - -/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info. -model l1_bridge_messages { - message_hash String @id @db.VarChar - nonce Decimal @unique @db.Decimal - transaction_source_hash String @unique @db.VarChar - sent_message_event_guid String @unique @db.VarChar - relayed_message_event_guid String? @unique @db.VarChar - from_address String @db.VarChar - to_address String @db.VarChar - amount Decimal @db.Decimal - gas_limit Decimal @db.Decimal - data String @db.VarChar - timestamp Int - l1_bridge_deposits l1_bridge_deposits? - l2_contract_events l2_contract_events? @relation(fields: [relayed_message_event_guid], references: [guid], onDelete: Cascade, onUpdate: NoAction) - l1_contract_events l1_contract_events @relation(fields: [sent_message_event_guid], references: [guid], onDelete: Cascade, onUpdate: NoAction) - l1_transaction_deposits l1_transaction_deposits @relation(fields: [transaction_source_hash], references: [source_hash], onDelete: Cascade, onUpdate: NoAction) -} - -/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info. -model l1_contract_events { - guid String @id @db.VarChar - block_hash String @db.VarChar - contract_address String @db.VarChar - transaction_hash String @db.VarChar - log_index Int - event_signature String @db.VarChar - timestamp Int - rlp_bytes String @db.VarChar - l1_bridge_messages l1_bridge_messages? - l1_block_headers l1_block_headers @relation(fields: [block_hash], references: [hash], onDelete: Cascade, onUpdate: NoAction) - l1_transaction_deposits l1_transaction_deposits? - l2_bridge_messages l2_bridge_messages? - l2_transaction_withdrawals_l2_transaction_withdrawals_finalized_l1_event_guidTol1_contract_events l2_transaction_withdrawals? @relation("l2_transaction_withdrawals_finalized_l1_event_guidTol1_contract_events") - l2_transaction_withdrawals_l2_transaction_withdrawals_proven_l1_event_guidTol1_contract_events l2_transaction_withdrawals? @relation("l2_transaction_withdrawals_proven_l1_event_guidTol1_contract_events") - legacy_state_batches legacy_state_batches? - output_proposals output_proposals? -} - -/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info. -model l1_transaction_deposits { - source_hash String @id @db.VarChar - l2_transaction_hash String @unique @db.VarChar - initiated_l1_event_guid String @unique @db.VarChar - from_address String @db.VarChar - to_address String @db.VarChar - amount Decimal @db.Decimal - gas_limit Decimal @db.Decimal - data String @db.VarChar - timestamp Int - l1_bridge_deposits l1_bridge_deposits? - l1_bridge_messages l1_bridge_messages? - l1_contract_events l1_contract_events @relation(fields: [initiated_l1_event_guid], references: [guid], onDelete: Cascade, onUpdate: NoAction) -} - -/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info. -model l2_block_headers { - hash String @id @db.VarChar - parent_hash String @unique @db.VarChar - number Decimal @unique @db.Decimal - timestamp Int - rlp_bytes String @db.VarChar - l2_contract_events l2_contract_events[] -} - -/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info. -model l2_bridge_messages { - message_hash String @id @db.VarChar - nonce Decimal @unique @db.Decimal - transaction_withdrawal_hash String @unique @db.VarChar - sent_message_event_guid String @unique @db.VarChar - relayed_message_event_guid String? @unique @db.VarChar - from_address String @db.VarChar - to_address String @db.VarChar - amount Decimal @db.Decimal - gas_limit Decimal @db.Decimal - data String @db.VarChar - timestamp Int - l1_contract_events l1_contract_events? @relation(fields: [relayed_message_event_guid], references: [guid], onDelete: Cascade, onUpdate: NoAction) - l2_contract_events l2_contract_events @relation(fields: [sent_message_event_guid], references: [guid], onDelete: Cascade, onUpdate: NoAction) - l2_transaction_withdrawals l2_transaction_withdrawals @relation(fields: [transaction_withdrawal_hash], references: [withdrawal_hash], onDelete: Cascade, onUpdate: NoAction) - l2_bridge_withdrawals l2_bridge_withdrawals? -} - -/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info. -model l2_bridge_withdrawals { - transaction_withdrawal_hash String @id @db.VarChar - cross_domain_message_hash String @unique @db.VarChar - from_address String @db.VarChar - to_address String @db.VarChar - local_token_address String @db.VarChar - remote_token_address String @db.VarChar - amount Decimal @db.Decimal - data String @db.VarChar - timestamp Int - l2_bridge_messages l2_bridge_messages @relation(fields: [cross_domain_message_hash], references: [message_hash], onDelete: Cascade, onUpdate: NoAction) - l2_transaction_withdrawals l2_transaction_withdrawals @relation(fields: [transaction_withdrawal_hash], references: [withdrawal_hash], onDelete: Cascade, onUpdate: NoAction) -} - -/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info. -model l2_contract_events { - guid String @id @db.VarChar - block_hash String @db.VarChar - contract_address String @db.VarChar - transaction_hash String @db.VarChar - log_index Int - event_signature String @db.VarChar - timestamp Int - rlp_bytes String @db.VarChar - l1_bridge_messages l1_bridge_messages? - l2_bridge_messages l2_bridge_messages? - l2_block_headers l2_block_headers @relation(fields: [block_hash], references: [hash], onDelete: Cascade, onUpdate: NoAction) - l2_transaction_withdrawals l2_transaction_withdrawals? -} - -/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info. -model l2_transaction_withdrawals { - withdrawal_hash String @id @db.VarChar - nonce Decimal @unique @db.Decimal - initiated_l2_event_guid String @unique @db.VarChar - proven_l1_event_guid String? @unique @db.VarChar - finalized_l1_event_guid String? @unique @db.VarChar - succeeded Boolean? - from_address String @db.VarChar - to_address String @db.VarChar - amount Decimal @db.Decimal - gas_limit Decimal @db.Decimal - data String @db.VarChar - timestamp Int - l2_bridge_messages l2_bridge_messages? - l2_bridge_withdrawals l2_bridge_withdrawals? - l1_contract_events_l2_transaction_withdrawals_finalized_l1_event_guidTol1_contract_events l1_contract_events? @relation("l2_transaction_withdrawals_finalized_l1_event_guidTol1_contract_events", fields: [finalized_l1_event_guid], references: [guid], onDelete: Cascade, onUpdate: NoAction) - l2_contract_events l2_contract_events @relation(fields: [initiated_l2_event_guid], references: [guid], onDelete: Cascade, onUpdate: NoAction) - l1_contract_events_l2_transaction_withdrawals_proven_l1_event_guidTol1_contract_events l1_contract_events? @relation("l2_transaction_withdrawals_proven_l1_event_guidTol1_contract_events", fields: [proven_l1_event_guid], references: [guid], onDelete: Cascade, onUpdate: NoAction) -} - -model legacy_state_batches { - index Int @id - root String @unique @db.VarChar - size Int - prev_total Int - state_batch_appended_guid String @unique @db.VarChar - l1_contract_events l1_contract_events @relation(fields: [state_batch_appended_guid], references: [guid], onDelete: Cascade, onUpdate: NoAction) -} - -model output_proposals { - output_root String @id @db.VarChar - l2_output_index Decimal @unique @db.Decimal - l2_block_number Decimal @unique @db.Decimal - output_proposed_guid String @unique @db.VarChar - l1_contract_events l1_contract_events @relation(fields: [output_proposed_guid], references: [guid], onDelete: Cascade, onUpdate: NoAction) -} diff --git a/nx.json b/nx.json index b817383c10b8..9ad91cf1a539 100644 --- a/nx.json +++ b/nx.json @@ -1,5 +1,7 @@ { + "$schema": "./node_modules/nx/schemas/nx-schema.json", "defaultBase": "develop", + "neverConnectToCloud": true, "affected": { "defaultBase": "develop" }, @@ -51,7 +53,7 @@ }, "targetDefaults": { "lint": { - "inputs": ["{workspaceRoot}/.markdownlint.json", "default"] + "inputs": ["default"] }, "test": { "inputs": ["default", "testing", "^production"], @@ -79,6 +81,5 @@ "dependsOn": ["^build", "build:contracts"], "outputs": ["{projectRoot}/dist"] } - }, - "$schema": "./node_modules/nx/schemas/nx-schema.json" + } } diff --git a/op-batcher/Dockerfile b/op-batcher/Dockerfile index 99dda06aba4d..a1d08badfc71 100644 --- a/op-batcher/Dockerfile +++ b/op-batcher/Dockerfile @@ -11,6 +11,7 @@ COPY ./op-bindings /app/op-bindings COPY ./op-node /app/op-node COPY ./op-service /app/op-service COPY ./op-aws-sdk /app/op-aws-sdk +COPY ./op-plasma /app/op-plasma COPY ./go.mod /app/go.mod COPY ./go.sum /app/go.sum diff --git a/op-batcher/batcher/batch_submitter.go b/op-batcher/batcher/batch_submitter.go index a3257075d5b3..77ac57065a11 100644 --- a/op-batcher/batcher/batch_submitter.go +++ b/op-batcher/batcher/batch_submitter.go @@ -29,7 +29,7 @@ func Main(version string) cliapp.LifecycleAction { } l := oplog.NewLogger(oplog.AppOut(cliCtx), cfg.LogConfig) - oplog.SetGlobalLogHandler(l.GetHandler()) + oplog.SetGlobalLogHandler(l.Handler()) opservice.ValidateEnvVars(flags.EnvVarPrefix, flags.Flags, l) l.Info("Initializing Batch Submitter") diff --git a/op-batcher/batcher/channel.go b/op-batcher/batcher/channel.go index 1d1eb2d5f568..0aaa194a73c4 100644 --- a/op-batcher/batcher/channel.go +++ b/op-batcher/batcher/channel.go @@ -12,7 +12,7 @@ import ( "github.com/ethereum/go-ethereum/log" ) -// channel is a lightweight wrapper around a channelBuilder which keeps track of pending +// channel is a lightweight wrapper around a ChannelBuilder which keeps track of pending // and confirmed transactions for a single channel. type channel struct { log log.Logger @@ -20,37 +20,45 @@ type channel struct { cfg ChannelConfig // pending channel builder - channelBuilder *channelBuilder - // Set of unconfirmed txID -> frame data. For tx resubmission - pendingTransactions map[txID]txData + channelBuilder *ChannelBuilder + // Set of unconfirmed txID -> tx data. For tx resubmission + pendingTransactions map[string]txData // Set of confirmed txID -> inclusion block. For determining if the channel is timed out - confirmedTransactions map[txID]eth.BlockID + confirmedTransactions map[string]eth.BlockID + + // True if confirmed TX list is updated. Set to false after updated min/max inclusion blocks. + confirmedTxUpdated bool + // Inclusion block number of first confirmed TX + minInclusionBlock uint64 + // Inclusion block number of last confirmed TX + maxInclusionBlock uint64 } -func newChannel(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, rcfg *rollup.Config) (*channel, error) { - cb, err := newChannelBuilder(cfg, rcfg) +func newChannel(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, rollupCfg *rollup.Config, latestL1OriginBlockNum uint64) (*channel, error) { + cb, err := NewChannelBuilder(cfg, *rollupCfg, latestL1OriginBlockNum) if err != nil { return nil, fmt.Errorf("creating new channel: %w", err) } + return &channel{ log: log, metr: metr, cfg: cfg, channelBuilder: cb, - pendingTransactions: make(map[txID]txData), - confirmedTransactions: make(map[txID]eth.BlockID), + pendingTransactions: make(map[string]txData), + confirmedTransactions: make(map[string]eth.BlockID), }, nil } // TxFailed records a transaction as failed. It will attempt to resubmit the data // in the failed transaction. -func (s *channel) TxFailed(id txID) { +func (s *channel) TxFailed(id string) { if data, ok := s.pendingTransactions[id]; ok { s.log.Trace("marked transaction as failed", "id", id) // Note: when the batcher is changed to send multiple frames per tx, // this needs to be changed to iterate over all frames of the tx data // and re-queue them. - s.channelBuilder.PushFrame(data.Frame()) + s.channelBuilder.PushFrames(data.Frames()...) delete(s.pendingTransactions, id) } else { s.log.Warn("unknown transaction marked as failed", "id", id) @@ -63,7 +71,7 @@ func (s *channel) TxFailed(id txID) { // a channel have been marked as confirmed on L1 the channel may be invalid & need to be // resubmitted. // This function may reset the pending channel if the pending channel has timed out. -func (s *channel) TxConfirmed(id txID, inclusionBlock eth.BlockID) (bool, []*types.Block) { +func (s *channel) TxConfirmed(id string, inclusionBlock eth.BlockID) (bool, []*types.Block) { s.metr.RecordBatchTxSubmitted() s.log.Debug("marked transaction as confirmed", "id", id, "block", inclusionBlock) if _, ok := s.pendingTransactions[id]; !ok { @@ -74,31 +82,35 @@ func (s *channel) TxConfirmed(id txID, inclusionBlock eth.BlockID) (bool, []*typ } delete(s.pendingTransactions, id) s.confirmedTransactions[id] = inclusionBlock + s.confirmedTxUpdated = true s.channelBuilder.FramePublished(inclusionBlock.Number) // If this channel timed out, put the pending blocks back into the local saved blocks // and then reset this state so it can try to build a new channel. if s.isTimedOut() { s.metr.RecordChannelTimedOut(s.ID()) - s.log.Warn("Channel timed out", "id", s.ID()) + s.log.Warn("Channel timed out", "id", s.ID(), "min_inclusion_block", s.minInclusionBlock, "max_inclusion_block", s.maxInclusionBlock) return true, s.channelBuilder.Blocks() } // If we are done with this channel, record that. if s.isFullySubmitted() { s.metr.RecordChannelFullySubmitted(s.ID()) - s.log.Info("Channel is fully submitted", "id", s.ID()) + s.log.Info("Channel is fully submitted", "id", s.ID(), "min_inclusion_block", s.minInclusionBlock, "max_inclusion_block", s.maxInclusionBlock) return true, nil } return false, nil } -// pendingChannelIsTimedOut returns true if submitted channel has timed out. -// A channel has timed out if the difference in L1 Inclusion blocks between -// the first & last included block is greater than or equal to the channel timeout. -func (s *channel) isTimedOut() bool { - if len(s.confirmedTransactions) == 0 { - return false +// Timeout returns the channel timeout L1 block number. If there is no timeout set, it returns 0. +func (s *channel) Timeout() uint64 { + return s.channelBuilder.Timeout() +} + +// updateInclusionBlocks finds the first & last confirmed tx and saves its inclusion numbers +func (s *channel) updateInclusionBlocks() { + if len(s.confirmedTransactions) == 0 || !s.confirmedTxUpdated { + return } // If there are confirmed transactions, find the first + last confirmed block numbers min := uint64(math.MaxUint64) @@ -111,11 +123,24 @@ func (s *channel) isTimedOut() bool { max = inclusionBlock.Number } } - return max-min >= s.cfg.ChannelTimeout + s.minInclusionBlock = min + s.maxInclusionBlock = max + s.confirmedTxUpdated = false +} + +// pendingChannelIsTimedOut returns true if submitted channel has timed out. +// A channel has timed out if the difference in L1 Inclusion blocks between +// the first & last included block is greater than or equal to the channel timeout. +func (s *channel) isTimedOut() bool { + // Update min/max inclusion blocks for timeout check + s.updateInclusionBlocks() + return s.maxInclusionBlock-s.minInclusionBlock >= s.cfg.ChannelTimeout } // pendingChannelIsFullySubmitted returns true if the channel has been fully submitted. func (s *channel) isFullySubmitted() bool { + // Update min/max inclusion blocks for timeout check + s.updateInclusionBlocks() return s.IsFull() && len(s.pendingTransactions)+s.PendingFrames() == 0 } @@ -127,20 +152,33 @@ func (s *channel) ID() derive.ChannelID { return s.channelBuilder.ID() } +// NextTxData returns the next tx data packet. +// If cfg.MultiFrameTxs is false, it returns txData with a single frame. +// If cfg.MultiFrameTxs is true, it will read frames from its channel builder +// until it either doesn't have more frames or the target number of frames is reached. +// +// NextTxData should only be called after HasTxData returned true. func (s *channel) NextTxData() txData { - frame := s.channelBuilder.NextFrame() - - txdata := txData{frame} - id := txdata.ID() + nf := s.cfg.MaxFramesPerTx() + txdata := txData{frames: make([]frameData, 0, nf)} + for i := 0; i < nf && s.channelBuilder.HasFrame(); i++ { + frame := s.channelBuilder.NextFrame() + txdata.frames = append(txdata.frames, frame) + } - s.log.Trace("returning next tx data", "id", id) + id := txdata.ID().String() + s.log.Debug("returning next tx data", "id", id, "num_frames", len(txdata.frames)) s.pendingTransactions[id] = txdata return txdata } -func (s *channel) HasFrame() bool { - return s.channelBuilder.HasFrame() +func (s *channel) HasTxData() bool { + if s.IsFull() || !s.cfg.MultiFrameTxs { + return s.channelBuilder.HasFrame() + } + // collect enough frames if channel is not full yet + return s.channelBuilder.PendingFrames() >= int(s.cfg.MaxFramesPerTx()) } func (s *channel) IsFull() bool { @@ -151,11 +189,11 @@ func (s *channel) FullErr() error { return s.channelBuilder.FullErr() } -func (s *channel) RegisterL1Block(l1BlockNum uint64) { - s.channelBuilder.RegisterL1Block(l1BlockNum) +func (s *channel) CheckTimeout(l1BlockNum uint64) { + s.channelBuilder.CheckTimeout(l1BlockNum) } -func (s *channel) AddBlock(block *types.Block) (derive.L1BlockInfo, error) { +func (s *channel) AddBlock(block *types.Block) (*derive.L1BlockInfo, error) { return s.channelBuilder.AddBlock(block) } @@ -183,6 +221,11 @@ func (s *channel) OutputFrames() error { return s.channelBuilder.OutputFrames() } +// LatestL1Origin returns the latest L1 block origin from all the L2 blocks that have been added to the channel +func (c *channel) LatestL1Origin() eth.BlockID { + return c.channelBuilder.LatestL1Origin() +} + func (s *channel) Close() { s.channelBuilder.Close() } diff --git a/op-batcher/batcher/channel_builder.go b/op-batcher/batcher/channel_builder.go index e336c90ad3d5..b55071f46908 100644 --- a/op-batcher/batcher/channel_builder.go +++ b/op-batcher/batcher/channel_builder.go @@ -7,9 +7,9 @@ import ( "io" "math" - "github.com/ethereum-optimism/optimism/op-batcher/compressor" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/core/types" ) @@ -34,66 +34,6 @@ func (e *ChannelFullError) Unwrap() error { return e.Err } -type ChannelConfig struct { - // Number of epochs (L1 blocks) per sequencing window, including the epoch - // L1 origin block itself - SeqWindowSize uint64 - // The maximum number of L1 blocks that the inclusion transactions of a - // channel's frames can span. - ChannelTimeout uint64 - - // Builder Config - - // MaxChannelDuration is the maximum duration (in #L1-blocks) to keep the - // channel open. This allows control over how long a channel is kept open - // during times of low transaction volume. - // - // If 0, duration checks are disabled. - MaxChannelDuration uint64 - // The batcher tx submission safety margin (in #L1-blocks) to subtract from - // a channel's timeout and sequencing window, to guarantee safe inclusion of - // a channel on L1. - SubSafetyMargin uint64 - // The maximum byte-size a frame can have. - MaxFrameSize uint64 - - // CompressorConfig contains the configuration for creating new compressors. - CompressorConfig compressor.Config - - // BatchType indicates whether the channel uses SingularBatch or SpanBatch. - BatchType uint -} - -// Check validates the [ChannelConfig] parameters. -func (cc *ChannelConfig) Check() error { - // The [ChannelTimeout] must be larger than the [SubSafetyMargin]. - // Otherwise, new blocks would always be considered timed out. - if cc.ChannelTimeout < cc.SubSafetyMargin { - return ErrInvalidChannelTimeout - } - - // If the [MaxFrameSize] is set to 0, the channel builder - // will infinitely loop when trying to create frames in the - // [channelBuilder.OutputFrames] function. - if cc.MaxFrameSize == 0 { - return errors.New("max frame size cannot be zero") - } - - // If the [MaxFrameSize] is less than [FrameV0OverHeadSize], the channel - // out will underflow the maxSize variable in the [derive.ChannelOut]. - // Since it is of type uint64, it will wrap around to a very large - // number, making the frame size extremely large. - if cc.MaxFrameSize < derive.FrameV0OverHeadSize { - return fmt.Errorf("max frame size %d is less than the minimum 23", cc.MaxFrameSize) - } - - if cc.BatchType > derive.SpanBatchType { - return fmt.Errorf("unrecognized batch type: %d", cc.BatchType) - } - - return nil -} - type frameID struct { chID derive.ChannelID frameNumber uint16 @@ -104,10 +44,11 @@ type frameData struct { id frameID } -// channelBuilder uses a ChannelOut to create a channel with output frame +// ChannelBuilder uses a ChannelOut to create a channel with output frame // size approximation. -type channelBuilder struct { - cfg ChannelConfig +type ChannelBuilder struct { + cfg ChannelConfig + rollupCfg rollup.Config // L1 block number timeout of combined // - channel duration timeout, @@ -125,6 +66,8 @@ type channelBuilder struct { co derive.ChannelOut // list of blocks in the channel. Saved in case the channel must be rebuilt blocks []*types.Block + // latestL1Origin is the latest L1 origin of all the L2 blocks that have been added to the channel + latestL1Origin eth.BlockID // frames data queue, to be send as txs frames []frameData // total frames counter @@ -135,59 +78,59 @@ type channelBuilder struct { // newChannelBuilder creates a new channel builder or returns an error if the // channel out could not be created. -func newChannelBuilder(cfg ChannelConfig, rcfg *rollup.Config) (*channelBuilder, error) { +func NewChannelBuilder(cfg ChannelConfig, rollupCfg rollup.Config, latestL1OriginBlockNum uint64) (*ChannelBuilder, error) { c, err := cfg.CompressorConfig.NewCompressor() if err != nil { return nil, err } var spanBatchBuilder *derive.SpanBatchBuilder if cfg.BatchType == derive.SpanBatchType { - spanBatchBuilder = derive.NewSpanBatchBuilder(rcfg.Genesis.L2Time, rcfg.L2ChainID) + spanBatchBuilder = derive.NewSpanBatchBuilder(rollupCfg.Genesis.L2Time, rollupCfg.L2ChainID) } co, err := derive.NewChannelOut(cfg.BatchType, c, spanBatchBuilder) if err != nil { return nil, err } - return &channelBuilder{ - cfg: cfg, - co: co, - }, nil + cb := &ChannelBuilder{ + cfg: cfg, + rollupCfg: rollupCfg, + co: co, + } + + cb.updateDurationTimeout(latestL1OriginBlockNum) + + return cb, nil } -func (c *channelBuilder) ID() derive.ChannelID { +func (c *ChannelBuilder) ID() derive.ChannelID { return c.co.ID() } // InputBytes returns the total amount of input bytes added to the channel. -func (c *channelBuilder) InputBytes() int { +func (c *ChannelBuilder) InputBytes() int { return c.co.InputBytes() } // ReadyBytes returns the amount of bytes ready in the compression pipeline to // output into a frame. -func (c *channelBuilder) ReadyBytes() int { +func (c *ChannelBuilder) ReadyBytes() int { return c.co.ReadyBytes() } -func (c *channelBuilder) OutputBytes() int { +func (c *ChannelBuilder) OutputBytes() int { return c.outputBytes } // Blocks returns a backup list of all blocks that were added to the channel. It // can be used in case the channel needs to be rebuilt. -func (c *channelBuilder) Blocks() []*types.Block { +func (c *ChannelBuilder) Blocks() []*types.Block { return c.blocks } -// Reset resets the internal state of the channel builder so that it can be -// reused. Note that a new channel id is also generated by Reset. -func (c *channelBuilder) Reset() error { - c.blocks = c.blocks[:0] - c.frames = c.frames[:0] - c.timeout = 0 - c.fullErr = nil - return c.co.Reset() +// LatestL1Origin returns the latest L1 block origin from all the L2 blocks that have been added to the channel +func (c *ChannelBuilder) LatestL1Origin() eth.BlockID { + return c.latestL1Origin } // AddBlock adds a block to the channel compression pipeline. IsFull should be @@ -201,12 +144,12 @@ func (c *channelBuilder) Reset() error { // first transaction for subsequent use by the caller. // // Call OutputFrames() afterwards to create frames. -func (c *channelBuilder) AddBlock(block *types.Block) (derive.L1BlockInfo, error) { +func (c *ChannelBuilder) AddBlock(block *types.Block) (*derive.L1BlockInfo, error) { if c.IsFull() { - return derive.L1BlockInfo{}, c.FullErr() + return nil, c.FullErr() } - batch, l1info, err := derive.BlockToSingularBatch(block) + batch, l1info, err := derive.BlockToSingularBatch(&c.rollupCfg, block) if err != nil { return l1info, fmt.Errorf("converting block to batch: %w", err) } @@ -217,9 +160,17 @@ func (c *channelBuilder) AddBlock(block *types.Block) (derive.L1BlockInfo, error } else if err != nil { return l1info, fmt.Errorf("adding block to channel out: %w", err) } + c.blocks = append(c.blocks, block) c.updateSwTimeout(batch) + if l1info.Number > c.latestL1Origin.Number { + c.latestL1Origin = eth.BlockID{ + Hash: l1info.BlockHash, + Number: l1info.Number, + } + } + if err = c.co.FullErr(); err != nil { c.setFullErr(err) // Adding this block still worked, so don't return error, just mark as full @@ -230,19 +181,15 @@ func (c *channelBuilder) AddBlock(block *types.Block) (derive.L1BlockInfo, error // Timeout management -// RegisterL1Block should be called whenever a new L1-block is seen. -// -// It ensures proper tracking of all possible timeouts (max channel duration, -// close to consensus channel timeout, close to end of sequencing window). -func (c *channelBuilder) RegisterL1Block(l1BlockNum uint64) { - c.updateDurationTimeout(l1BlockNum) - c.checkTimeout(l1BlockNum) +// Timeout returns the block number of the channel timeout. If no timeout is set it returns 0 +func (c *ChannelBuilder) Timeout() uint64 { + return c.timeout } // FramePublished should be called whenever a frame of this channel got // published with the L1-block number of the block that the frame got included // in. -func (c *channelBuilder) FramePublished(l1BlockNum uint64) { +func (c *ChannelBuilder) FramePublished(l1BlockNum uint64) { timeout := l1BlockNum + c.cfg.ChannelTimeout - c.cfg.SubSafetyMargin c.updateTimeout(timeout, ErrChannelTimeoutClose) } @@ -252,7 +199,7 @@ func (c *channelBuilder) FramePublished(l1BlockNum uint64) { // forward if the derived timeout is earlier than the currently set timeout. // // It does nothing if the max channel duration is set to 0. -func (c *channelBuilder) updateDurationTimeout(l1BlockNum uint64) { +func (c *ChannelBuilder) updateDurationTimeout(l1BlockNum uint64) { if c.cfg.MaxChannelDuration == 0 { return } @@ -264,7 +211,7 @@ func (c *channelBuilder) updateDurationTimeout(l1BlockNum uint64) { // derived from the batch's origin L1 block. The timeout is only moved forward // if the derived sequencer window timeout is earlier than the currently set // timeout. -func (c *channelBuilder) updateSwTimeout(batch *derive.SingularBatch) { +func (c *ChannelBuilder) updateSwTimeout(batch *derive.SingularBatch) { timeout := uint64(batch.EpochNum) + c.cfg.SeqWindowSize - c.cfg.SubSafetyMargin c.updateTimeout(timeout, ErrSeqWindowClose) } @@ -274,30 +221,30 @@ func (c *channelBuilder) updateSwTimeout(batch *derive.SingularBatch) { // // If the timeout is updated, the provided reason will be set as the channel // full error reason in case the timeout is hit in the future. -func (c *channelBuilder) updateTimeout(timeoutBlockNum uint64, reason error) { +func (c *ChannelBuilder) updateTimeout(timeoutBlockNum uint64, reason error) { if c.timeout == 0 || c.timeout > timeoutBlockNum { c.timeout = timeoutBlockNum c.timeoutReason = reason } } -// checkTimeout checks if the channel is timed out at the given block number and +// CheckTimeout checks if the channel is timed out at the given block number and // in this case marks the channel as full, if it wasn't full already. -func (c *channelBuilder) checkTimeout(blockNum uint64) { - if !c.IsFull() && c.TimedOut(blockNum) { +func (c *ChannelBuilder) CheckTimeout(l1BlockNum uint64) { + if !c.IsFull() && c.TimedOut(l1BlockNum) { c.setFullErr(c.timeoutReason) } } // TimedOut returns whether the passed block number is after the timeout block // number. If no block timeout is set yet, it returns false. -func (c *channelBuilder) TimedOut(blockNum uint64) bool { +func (c *ChannelBuilder) TimedOut(blockNum uint64) bool { return c.timeout != 0 && blockNum >= c.timeout } // IsFull returns whether the channel is full. // FullErr returns the reason for the channel being full. -func (c *channelBuilder) IsFull() bool { +func (c *ChannelBuilder) IsFull() bool { return c.fullErr != nil } @@ -315,11 +262,11 @@ func (c *channelBuilder) IsFull() bool { // - ErrChannelTimeoutClose if the consensus channel timeout got too close, // - ErrSeqWindowClose if the end of the sequencer window got too close, // - ErrTerminated if the channel was explicitly terminated. -func (c *channelBuilder) FullErr() error { +func (c *ChannelBuilder) FullErr() error { return c.fullErr } -func (c *channelBuilder) setFullErr(err error) { +func (c *ChannelBuilder) setFullErr(err error) { c.fullErr = &ChannelFullError{Err: err} } @@ -331,9 +278,13 @@ func (c *channelBuilder) setFullErr(err error) { // pull readily available frames from the compression output. // If it is full, the channel is closed and all remaining // frames will be created, possibly with a small leftover frame. -func (c *channelBuilder) OutputFrames() error { +func (c *ChannelBuilder) OutputFrames() error { if c.IsFull() { - return c.closeAndOutputAllFrames() + err := c.closeAndOutputAllFrames() + if err != nil { + return fmt.Errorf("error while closing full channel (full reason: %w): %w", c.FullErr(), err) + } + return nil } return c.outputReadyFrames() } @@ -343,10 +294,10 @@ func (c *channelBuilder) OutputFrames() error { // // This is part of an optimization to already generate frames and send them off // as txs while still collecting blocks in the channel builder. -func (c *channelBuilder) outputReadyFrames() error { - // TODO: Decide whether we want to fill frames to max size and use target - // only for estimation, or use target size. - for c.co.ReadyBytes() >= int(c.cfg.MaxFrameSize) { +func (c *ChannelBuilder) outputReadyFrames() error { + // When creating a frame from the ready compression data, the frame overhead + // will be added to the total output size, so we can add it in the condition. + for c.co.ReadyBytes()+derive.FrameV0OverHeadSize >= int(c.cfg.MaxFrameSize) { if err := c.outputFrame(); err == io.EOF { return nil } else if err != nil { @@ -356,7 +307,7 @@ func (c *channelBuilder) outputReadyFrames() error { return nil } -func (c *channelBuilder) closeAndOutputAllFrames() error { +func (c *ChannelBuilder) closeAndOutputAllFrames() error { if err := c.co.Close(); err != nil { return fmt.Errorf("closing channel out: %w", err) } @@ -373,7 +324,7 @@ func (c *channelBuilder) closeAndOutputAllFrames() error { // outputFrame creates one new frame and adds it to the frames queue. // Note that compressed output data must be available on the underlying // ChannelOut, or an empty frame will be produced. -func (c *channelBuilder) outputFrame() error { +func (c *ChannelBuilder) outputFrame() error { var buf bytes.Buffer fn, err := c.co.OutputFrame(&buf, c.cfg.MaxFrameSize) if err != io.EOF && err != nil { @@ -403,7 +354,7 @@ func (c *channelBuilder) outputFrame() error { // Close immediately marks the channel as full with an ErrTerminated // if the channel is not already full. -func (c *channelBuilder) Close() { +func (c *ChannelBuilder) Close() { if !c.IsFull() { c.setFullErr(ErrTerminated) } @@ -411,7 +362,7 @@ func (c *channelBuilder) Close() { // TotalFrames returns the total number of frames that were created in this channel so far. // It does not decrease when the frames queue is being emptied. -func (c *channelBuilder) TotalFrames() int { +func (c *ChannelBuilder) TotalFrames() int { return c.numFrames } @@ -420,20 +371,20 @@ func (c *channelBuilder) TotalFrames() int { // // Call OutputFrames before to create new frames from the channel out // compression pipeline. -func (c *channelBuilder) HasFrame() bool { +func (c *ChannelBuilder) HasFrame() bool { return len(c.frames) > 0 } // PendingFrames returns the number of pending frames in the frames queue. // It is larger zero iff HasFrames() returns true. -func (c *channelBuilder) PendingFrames() int { +func (c *ChannelBuilder) PendingFrames() int { return len(c.frames) } // NextFrame returns the next available frame. // HasFrame must be called prior to check if there's a next frame available. // Panics if called when there's no next frame. -func (c *channelBuilder) NextFrame() frameData { +func (c *ChannelBuilder) NextFrame() frameData { if len(c.frames) == 0 { panic("no next frame") } @@ -443,11 +394,13 @@ func (c *channelBuilder) NextFrame() frameData { return f } -// PushFrame adds the frame back to the internal frames queue. Panics if not of +// PushFrames adds the frames back to the internal frames queue. Panics if not of // the same channel. -func (c *channelBuilder) PushFrame(frame frameData) { - if frame.id.chID != c.ID() { - panic("wrong channel") +func (c *ChannelBuilder) PushFrames(frames ...frameData) { + for _, f := range frames { + if f.id.chID != c.ID() { + panic("wrong channel") + } + c.frames = append(c.frames, f) } - c.frames = append(c.frames, frame) } diff --git a/op-batcher/batcher/channel_builder_test.go b/op-batcher/batcher/channel_builder_test.go index 5ee5c5367134..4c428ee31f9e 100644 --- a/op-batcher/batcher/channel_builder_test.go +++ b/op-batcher/batcher/channel_builder_test.go @@ -3,13 +3,11 @@ package batcher import ( "bytes" "errors" - "fmt" "math" "math/big" "math/rand" "testing" - "github.com/ethereum-optimism/optimism/op-batcher/compressor" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" dtest "github.com/ethereum-optimism/optimism/op-node/rollup/derive/test" @@ -21,103 +19,16 @@ import ( "github.com/stretchr/testify/require" ) -var defaultTestChannelConfig = ChannelConfig{ - SeqWindowSize: 15, - ChannelTimeout: 40, - MaxChannelDuration: 1, - SubSafetyMargin: 4, - MaxFrameSize: 120000, - CompressorConfig: compressor.Config{ - TargetFrameSize: 100000, - TargetNumFrames: 1, - ApproxComprRatio: 0.4, - }, - BatchType: derive.SingularBatchType, -} +const latestL1BlockOrigin = 10 var defaultTestRollupConfig = rollup.Config{ Genesis: rollup.Genesis{L2: eth.BlockID{Number: 0}}, L2ChainID: big.NewInt(1234), } -// TestChannelConfig_Check tests the [ChannelConfig] [Check] function. -func TestChannelConfig_Check(t *testing.T) { - type test struct { - input ChannelConfig - assertion func(error) - } - - // Construct test cases that test the boundary conditions - zeroChannelConfig := defaultTestChannelConfig - zeroChannelConfig.MaxFrameSize = 0 - timeoutChannelConfig := defaultTestChannelConfig - timeoutChannelConfig.ChannelTimeout = 0 - timeoutChannelConfig.SubSafetyMargin = 1 - tests := []test{ - { - input: defaultTestChannelConfig, - assertion: func(output error) { - require.NoError(t, output) - }, - }, - { - input: timeoutChannelConfig, - assertion: func(output error) { - require.ErrorIs(t, output, ErrInvalidChannelTimeout) - }, - }, - { - input: zeroChannelConfig, - assertion: func(output error) { - require.EqualError(t, output, "max frame size cannot be zero") - }, - }, - } - for i := 1; i < derive.FrameV0OverHeadSize; i++ { - smallChannelConfig := defaultTestChannelConfig - smallChannelConfig.MaxFrameSize = uint64(i) - expectedErr := fmt.Sprintf("max frame size %d is less than the minimum 23", i) - tests = append(tests, test{ - input: smallChannelConfig, - assertion: func(output error) { - require.EqualError(t, output, expectedErr) - }, - }) - } - - // Run the table tests - for _, test := range tests { - test.assertion(test.input.Check()) - } -} - -// FuzzChannelConfig_CheckTimeout tests the [ChannelConfig] [Check] function -// with fuzzing to make sure that a [ErrInvalidChannelTimeout] is thrown when -// the [ChannelTimeout] is less than the [SubSafetyMargin]. -func FuzzChannelConfig_CheckTimeout(f *testing.F) { - for i := range [10]int{} { - f.Add(uint64(i+1), uint64(i)) - } - f.Fuzz(func(t *testing.T, channelTimeout uint64, subSafetyMargin uint64) { - // We only test where [ChannelTimeout] is less than the [SubSafetyMargin] - // So we cannot have [ChannelTimeout] be [math.MaxUint64] - if channelTimeout == math.MaxUint64 { - channelTimeout = math.MaxUint64 - 1 - } - if subSafetyMargin <= channelTimeout { - subSafetyMargin = channelTimeout + 1 - } - - channelConfig := defaultTestChannelConfig - channelConfig.ChannelTimeout = channelTimeout - channelConfig.SubSafetyMargin = subSafetyMargin - require.ErrorIs(t, channelConfig.Check(), ErrInvalidChannelTimeout) - }) -} - // addMiniBlock adds a minimal valid L2 block to the channel builder using the -// channelBuilder.AddBlock method. -func addMiniBlock(cb *channelBuilder) error { +// ChannelBuilder.AddBlock method. +func addMiniBlock(cb *ChannelBuilder) error { a := newMiniL2Block(0) _, err := cb.AddBlock(a) return err @@ -139,12 +50,19 @@ func newMiniL2Block(numTx int) *types.Block { // // If numTx > 0, that many empty DynamicFeeTxs will be added to the txs. func newMiniL2BlockWithNumberParent(numTx int, number *big.Int, parent common.Hash) *types.Block { + return newMiniL2BlockWithNumberParentAndL1Information(numTx, number, parent, 100, 0) +} + +// newMiniL2BlockWithNumberParentAndL1Information returns a minimal L2 block with a minimal valid L1InfoDeposit +// It allows you to specify the l1 block number and the block time in addition to the parameters exposed in newMiniL2Block. +func newMiniL2BlockWithNumberParentAndL1Information(numTx int, l2Number *big.Int, parent common.Hash, l1Number int64, blockTime uint64) *types.Block { l1Block := types.NewBlock(&types.Header{ BaseFee: big.NewInt(10), Difficulty: common.Big0, - Number: big.NewInt(100), + Number: big.NewInt(l1Number), + Time: blockTime, }, nil, nil, nil, trie.NewStackTrie(nil)) - l1InfoTx, err := derive.L1InfoDeposit(0, eth.BlockToInfo(l1Block), eth.SystemConfig{}, false) + l1InfoTx, err := derive.L1InfoDeposit(&defaultTestRollupConfig, eth.SystemConfig{}, 0, eth.BlockToInfo(l1Block), blockTime) if err != nil { panic(err) } @@ -156,14 +74,14 @@ func newMiniL2BlockWithNumberParent(numTx int, number *big.Int, parent common.Ha } return types.NewBlock(&types.Header{ - Number: number, + Number: l2Number, ParentHash: parent, }, txs, nil, nil, trie.NewStackTrie(nil)) } // addTooManyBlocks adds blocks to the channel until it hits an error, // which is presumably ErrTooManyRLPBytes. -func addTooManyBlocks(cb *channelBuilder) error { +func addTooManyBlocks(cb *ChannelBuilder) error { rng := rand.New(rand.NewSource(1234)) for i := 0; i < 10_000; i++ { block := dtest.RandomL2BlockWithChainId(rng, 1000, defaultTestRollupConfig.L2ChainID) @@ -183,9 +101,9 @@ func FuzzDurationTimeoutZeroMaxChannelDuration(f *testing.F) { f.Add(uint64(i)) } f.Fuzz(func(t *testing.T, l1BlockNum uint64) { - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() channelConfig.MaxChannelDuration = 0 - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) cb.timeout = 0 cb.updateDurationTimeout(l1BlockNum) @@ -206,15 +124,15 @@ func FuzzChannelBuilder_DurationZero(f *testing.F) { } // Create the channel builder - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() channelConfig.MaxChannelDuration = maxChannelDuration - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) // Whenever the timeout is set to 0, the channel builder should have a duration timeout cb.timeout = 0 cb.updateDurationTimeout(l1BlockNum) - cb.checkTimeout(l1BlockNum + maxChannelDuration) + cb.CheckTimeout(l1BlockNum + maxChannelDuration) require.ErrorIs(t, cb.FullErr(), ErrMaxDurationReached) }) } @@ -233,9 +151,9 @@ func FuzzDurationTimeoutMaxChannelDuration(f *testing.F) { } // Create the channel builder - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() channelConfig.MaxChannelDuration = maxChannelDuration - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) // Whenever the timeout is greater than the l1BlockNum, @@ -248,7 +166,7 @@ func FuzzDurationTimeoutMaxChannelDuration(f *testing.F) { // That is, where the channel builder has a value set for the timeout // with no timeoutReason. This subsequently causes a panic when // a nil timeoutReason is used as an error (eg when calling FullErr). - cb.checkTimeout(l1BlockNum + maxChannelDuration) + cb.CheckTimeout(l1BlockNum + maxChannelDuration) require.ErrorIs(t, cb.FullErr(), ErrMaxDurationReached) } else { require.NoError(t, cb.FullErr()) @@ -266,10 +184,10 @@ func FuzzChannelCloseTimeout(f *testing.F) { } f.Fuzz(func(t *testing.T, l1BlockNum uint64, channelTimeout uint64, subSafetyMargin uint64, timeout uint64) { // Create the channel builder - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() channelConfig.ChannelTimeout = channelTimeout channelConfig.SubSafetyMargin = subSafetyMargin - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) // Check the timeout @@ -277,7 +195,7 @@ func FuzzChannelCloseTimeout(f *testing.F) { cb.FramePublished(l1BlockNum) calculatedTimeout := l1BlockNum + channelTimeout - subSafetyMargin if timeout > calculatedTimeout && calculatedTimeout != 0 { - cb.checkTimeout(calculatedTimeout) + cb.CheckTimeout(calculatedTimeout) require.ErrorIs(t, cb.FullErr(), ErrChannelTimeoutClose) } else { require.NoError(t, cb.FullErr()) @@ -294,17 +212,17 @@ func FuzzChannelZeroCloseTimeout(f *testing.F) { } f.Fuzz(func(t *testing.T, l1BlockNum uint64, channelTimeout uint64, subSafetyMargin uint64) { // Create the channel builder - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() channelConfig.ChannelTimeout = channelTimeout channelConfig.SubSafetyMargin = subSafetyMargin - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) // Check the timeout cb.timeout = 0 cb.FramePublished(l1BlockNum) calculatedTimeout := l1BlockNum + channelTimeout - subSafetyMargin - cb.checkTimeout(calculatedTimeout) + cb.CheckTimeout(calculatedTimeout) if cb.timeout != 0 { require.ErrorIs(t, cb.FullErr(), ErrChannelTimeoutClose) } @@ -321,10 +239,10 @@ func FuzzSeqWindowClose(f *testing.F) { } f.Fuzz(func(t *testing.T, epochNum uint64, seqWindowSize uint64, subSafetyMargin uint64, timeout uint64) { // Create the channel builder - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() channelConfig.SeqWindowSize = seqWindowSize channelConfig.SubSafetyMargin = subSafetyMargin - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) // Check the timeout @@ -332,7 +250,7 @@ func FuzzSeqWindowClose(f *testing.F) { cb.updateSwTimeout(&derive.SingularBatch{EpochNum: rollup.Epoch(epochNum)}) calculatedTimeout := epochNum + seqWindowSize - subSafetyMargin if timeout > calculatedTimeout && calculatedTimeout != 0 { - cb.checkTimeout(calculatedTimeout) + cb.CheckTimeout(calculatedTimeout) require.ErrorIs(t, cb.FullErr(), ErrSeqWindowClose) } else { require.NoError(t, cb.FullErr()) @@ -349,17 +267,17 @@ func FuzzSeqWindowZeroTimeoutClose(f *testing.F) { } f.Fuzz(func(t *testing.T, epochNum uint64, seqWindowSize uint64, subSafetyMargin uint64) { // Create the channel builder - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() channelConfig.SeqWindowSize = seqWindowSize channelConfig.SubSafetyMargin = subSafetyMargin - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) // Check the timeout cb.timeout = 0 cb.updateSwTimeout(&derive.SingularBatch{EpochNum: rollup.Epoch(epochNum)}) calculatedTimeout := epochNum + seqWindowSize - subSafetyMargin - cb.checkTimeout(calculatedTimeout) + cb.CheckTimeout(calculatedTimeout) if cb.timeout != 0 { require.ErrorIs(t, cb.FullErr(), ErrSeqWindowClose, "Sequence window close should be reached") } @@ -374,7 +292,6 @@ func TestChannelBuilderBatchType(t *testing.T) { {"ChannelBuilder_MaxRLPBytesPerChannel", ChannelBuilder_MaxRLPBytesPerChannel}, {"ChannelBuilder_OutputFramesMaxFrameIndex", ChannelBuilder_OutputFramesMaxFrameIndex}, {"ChannelBuilder_AddBlock", ChannelBuilder_AddBlock}, - {"ChannelBuilder_Reset", ChannelBuilder_Reset}, {"ChannelBuilder_PendingFrames_TotalFrames", ChannelBuilder_PendingFrames_TotalFrames}, {"ChannelBuilder_InputBytes", ChannelBuilder_InputBytes}, {"ChannelBuilder_OutputBytes", ChannelBuilder_OutputBytes}, @@ -396,13 +313,13 @@ func TestChannelBuilderBatchType(t *testing.T) { // TestChannelBuilder_NextFrame tests calling NextFrame on a ChannelBuilder with only one frame func TestChannelBuilder_NextFrame(t *testing.T) { - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() // Create a new channel builder - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) - // Mock the internals of `channelBuilder.outputFrame` + // Mock the internals of `ChannelBuilder.outputFrame` // to construct a single frame co := cb.co var buf bytes.Buffer @@ -410,7 +327,7 @@ func TestChannelBuilder_NextFrame(t *testing.T) { require.NoError(t, err) // Push one frame into to the channel builder - expectedTx := txID{chID: co.ID(), frameNumber: fn} + expectedTx := txID{frameID{chID: co.ID(), frameNumber: fn}} expectedBytes := buf.Bytes() frameData := frameData{ id: frameID{ @@ -419,14 +336,14 @@ func TestChannelBuilder_NextFrame(t *testing.T) { }, data: expectedBytes, } - cb.PushFrame(frameData) + cb.PushFrames(frameData) // There should only be 1 frame in the channel builder require.Equal(t, 1, cb.PendingFrames()) // We should be able to increment to the next frame constructedFrame := cb.NextFrame() - require.Equal(t, expectedTx, constructedFrame.id) + require.Equal(t, expectedTx[0], constructedFrame.id) require.Equal(t, expectedBytes, constructedFrame.data) require.Equal(t, 0, cb.PendingFrames()) @@ -436,13 +353,13 @@ func TestChannelBuilder_NextFrame(t *testing.T) { // TestChannelBuilder_OutputWrongFramePanic tests that a panic is thrown when a frame is pushed with an invalid frame id func TestChannelBuilder_OutputWrongFramePanic(t *testing.T) { - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() // Construct a channel builder - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) - // Mock the internals of `channelBuilder.outputFrame` + // Mock the internals of `ChannelBuilder.outputFrame` // to construct a single frame c, err := channelConfig.CompressorConfig.NewCompressor() require.NoError(t, err) @@ -462,17 +379,19 @@ func TestChannelBuilder_OutputWrongFramePanic(t *testing.T) { }, data: buf.Bytes(), } - cb.PushFrame(frame) + cb.PushFrames(frame) }) } -// TestChannelBuilder_OutputFramesWorks tests the [ChannelBuilder] OutputFrames is successful. -func TestChannelBuilder_OutputFramesWorks(t *testing.T) { - channelConfig := defaultTestChannelConfig - channelConfig.MaxFrameSize = 24 +// TestChannelBuilder_OutputFrames tests [ChannelBuilder.OutputFrames] for singular batches. +func TestChannelBuilder_OutputFrames(t *testing.T) { + channelConfig := defaultTestChannelConfig() + channelConfig.MaxFrameSize = derive.FrameV0OverHeadSize + 1 + channelConfig.TargetNumFrames = 1000 + channelConfig.InitNoneCompressor() // Construct the channel builder - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) require.False(t, cb.IsFull()) require.Equal(t, 0, cb.PendingFrames()) @@ -486,11 +405,9 @@ func TestChannelBuilder_OutputFramesWorks(t *testing.T) { // Let's add a block require.NoError(t, addMiniBlock(cb)) - require.NoError(t, cb.co.Flush()) // Check how many ready bytes - // There should be more than the max frame size ready - require.Greater(t, uint64(cb.co.ReadyBytes()), channelConfig.MaxFrameSize) + require.Greater(t, uint64(cb.co.ReadyBytes()+derive.FrameV0OverHeadSize), channelConfig.MaxFrameSize) require.Equal(t, 0, cb.PendingFrames()) // The channel should not be full @@ -507,15 +424,15 @@ func TestChannelBuilder_OutputFramesWorks(t *testing.T) { } } -// TestChannelBuilder_OutputFramesWorks tests the [ChannelBuilder] OutputFrames is successful. -func TestChannelBuilder_OutputFramesWorks_SpanBatch(t *testing.T) { - channelConfig := defaultTestChannelConfig - channelConfig.MaxFrameSize = 24 - channelConfig.CompressorConfig.TargetFrameSize = 50 +func TestChannelBuilder_OutputFrames_SpanBatch(t *testing.T) { + channelConfig := defaultTestChannelConfig() + channelConfig.MaxFrameSize = 20 + derive.FrameV0OverHeadSize + channelConfig.TargetNumFrames = 5 channelConfig.BatchType = derive.SpanBatchType + channelConfig.InitRatioCompressor(1) // Construct the channel builder - cb, err := newChannelBuilder(channelConfig, &defaultTestRollupConfig) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) require.False(t, cb.IsFull()) require.Equal(t, 0, cb.PendingFrames()) @@ -542,14 +459,15 @@ func TestChannelBuilder_OutputFramesWorks_SpanBatch(t *testing.T) { require.True(t, cb.IsFull()) // Check how many ready bytes - // There should be more than the max frame size ready - require.Greater(t, uint64(cb.co.ReadyBytes()), channelConfig.MaxFrameSize) + require.GreaterOrEqual(t, + cb.co.ReadyBytes()+derive.FrameV0OverHeadSize, + int(channelConfig.MaxFrameSize)) require.Equal(t, 0, cb.PendingFrames()) // We should be able to output the frames require.NoError(t, cb.OutputFrames()) - // There should be many frames in the channel builder now + // There should be several frames in the channel builder now require.Greater(t, cb.PendingFrames(), 1) for i := 0; i < cb.numFrames-1; i++ { require.Len(t, cb.frames[i].data, int(channelConfig.MaxFrameSize)) @@ -557,18 +475,17 @@ func TestChannelBuilder_OutputFramesWorks_SpanBatch(t *testing.T) { require.LessOrEqual(t, len(cb.frames[len(cb.frames)-1].data), int(channelConfig.MaxFrameSize)) } -// ChannelBuilder_MaxRLPBytesPerChannel tests the [channelBuilder.OutputFrames] +// ChannelBuilder_MaxRLPBytesPerChannel tests the [ChannelBuilder.OutputFrames] // function errors when the max RLP bytes per channel is reached. func ChannelBuilder_MaxRLPBytesPerChannel(t *testing.T, batchType uint) { t.Parallel() - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() channelConfig.MaxFrameSize = derive.MaxRLPBytesPerChannel * 2 - channelConfig.CompressorConfig.TargetFrameSize = derive.MaxRLPBytesPerChannel * 2 - channelConfig.CompressorConfig.ApproxComprRatio = 1 + channelConfig.InitNoneCompressor() channelConfig.BatchType = batchType // Construct the channel builder - cb, err := newChannelBuilder(channelConfig, &defaultTestRollupConfig) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) // Add a block that overflows the [ChannelOut] @@ -579,24 +496,23 @@ func ChannelBuilder_MaxRLPBytesPerChannel(t *testing.T, batchType uint) { // ChannelBuilder_OutputFramesMaxFrameIndex tests the [ChannelBuilder.OutputFrames] // function errors when the max frame index is reached. func ChannelBuilder_OutputFramesMaxFrameIndex(t *testing.T, batchType uint) { - channelConfig := defaultTestChannelConfig - channelConfig.MaxFrameSize = 24 - channelConfig.CompressorConfig.TargetNumFrames = 6000 - channelConfig.CompressorConfig.TargetFrameSize = 24 - channelConfig.CompressorConfig.ApproxComprRatio = 1 + channelConfig := defaultTestChannelConfig() + channelConfig.MaxFrameSize = derive.FrameV0OverHeadSize + 1 + channelConfig.TargetNumFrames = math.MaxUint16 + 1 + channelConfig.InitRatioCompressor(.1) channelConfig.BatchType = batchType rng := rand.New(rand.NewSource(123)) // Continuously add blocks until the max frame index is reached - // This should cause the [channelBuilder.OutputFrames] function + // This should cause the [ChannelBuilder.OutputFrames] function // to error - cb, err := newChannelBuilder(channelConfig, &defaultTestRollupConfig) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) require.False(t, cb.IsFull()) require.Equal(t, 0, cb.PendingFrames()) for { - a := dtest.RandomL2BlockWithChainId(rng, 1, defaultTestRollupConfig.L2ChainID) + a := dtest.RandomL2BlockWithChainId(rng, 1000, defaultTestRollupConfig.L2ChainID) _, err = cb.AddBlock(a) if cb.IsFull() { fullErr := cb.FullErr() @@ -610,21 +526,55 @@ func ChannelBuilder_OutputFramesMaxFrameIndex(t *testing.T, batchType uint) { require.ErrorIs(t, cb.FullErr(), ErrMaxFrameIndex) } -// ChannelBuilder_AddBlock tests the AddBlock function +// TestChannelBuilder_FullShadowCompressor is a regression test testing that +// the shadow compressor is correctly marked as full if adding another block +// would produce a leftover frame. +// +// This test fails in multiple places if the subtraction of +// [derive.FrameV0OverHeadSize] in [MaxDataSize] is omitted, which has been the +// case before it got fixed it #9887. +func TestChannelBuilder_FullShadowCompressor(t *testing.T) { + require := require.New(t) + cfg := ChannelConfig{ + MaxFrameSize: 752, + TargetNumFrames: 1, + BatchType: derive.SpanBatchType, + } + cfg.InitShadowCompressor() + + cb, err := NewChannelBuilder(cfg, defaultTestRollupConfig, latestL1BlockOrigin) + require.NoError(err) + + rng := rand.New(rand.NewSource(420)) + a := dtest.RandomL2BlockWithChainId(rng, 1, defaultTestRollupConfig.L2ChainID) + _, err = cb.AddBlock(a) + require.NoError(err) + _, err = cb.AddBlock(a) + require.ErrorIs(err, derive.CompressorFullErr) + // without fix, adding the second block would succeed and then adding a + // third block would fail with full error and the compressor would be full. + + require.NoError(cb.OutputFrames()) + + require.True(cb.HasFrame()) + f := cb.NextFrame() + require.Less(len(f.data), int(cfg.MaxFrameSize)) // would fail without fix, full frame + + require.False(cb.HasFrame(), "no leftover frame expected") // would fail without fix +} + func ChannelBuilder_AddBlock(t *testing.T, batchType uint) { - channelConfig := defaultTestChannelConfig + channelConfig := defaultTestChannelConfig() channelConfig.BatchType = batchType // Lower the max frame size so that we can batch - channelConfig.MaxFrameSize = 20 - + channelConfig.MaxFrameSize = 20 + derive.FrameV0OverHeadSize + channelConfig.TargetNumFrames = 2 // Configure the Input Threshold params so we observe a full channel - channelConfig.CompressorConfig.TargetFrameSize = 20 - channelConfig.CompressorConfig.TargetNumFrames = 2 - channelConfig.CompressorConfig.ApproxComprRatio = 1 + channelConfig.InitRatioCompressor(1) // Construct the channel builder - cb, err := newChannelBuilder(channelConfig, &defaultTestRollupConfig) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) // Add a nonsense block to the channel builder @@ -646,90 +596,44 @@ func ChannelBuilder_AddBlock(t *testing.T, batchType uint) { require.ErrorIs(t, addMiniBlock(cb), derive.CompressorFullErr) } -// ChannelBuilder_Reset tests the [Reset] function -func ChannelBuilder_Reset(t *testing.T, batchType uint) { - channelConfig := defaultTestChannelConfig - channelConfig.BatchType = batchType - - // Lower the max frame size so that we can batch - channelConfig.MaxFrameSize = 24 - channelConfig.CompressorConfig.TargetNumFrames = 1 - channelConfig.CompressorConfig.TargetFrameSize = 24 - channelConfig.CompressorConfig.ApproxComprRatio = 1 - - cb, err := newChannelBuilder(channelConfig, &defaultTestRollupConfig) - require.NoError(t, err) - - // Add a nonsense block to the channel builder - require.NoError(t, addMiniBlock(cb)) - require.NoError(t, cb.co.Flush()) - - // Check the fields reset in the Reset function - require.Equal(t, 1, len(cb.blocks)) - require.Equal(t, 0, len(cb.frames)) - // Timeout should be updated in the AddBlock internal call to `updateSwTimeout` - timeout := uint64(100) + cb.cfg.SeqWindowSize - cb.cfg.SubSafetyMargin - require.Equal(t, timeout, cb.timeout) - require.Error(t, cb.fullErr) - - // Output frames so we can set the channel builder frames - require.NoError(t, cb.OutputFrames()) - - // Check the fields reset in the Reset function - require.Equal(t, 1, len(cb.blocks)) - require.Equal(t, timeout, cb.timeout) - require.Error(t, cb.fullErr) - require.Greater(t, len(cb.frames), 1) - - // Reset the channel builder - require.NoError(t, cb.Reset()) - - // Check the fields reset in the Reset function - require.Equal(t, 0, len(cb.blocks)) - require.Equal(t, 0, len(cb.frames)) - require.Equal(t, uint64(0), cb.timeout) - require.NoError(t, cb.fullErr) - require.Equal(t, 0, cb.co.InputBytes()) - require.Equal(t, 0, cb.co.ReadyBytes()) -} - -// TestBuilderRegisterL1Block tests the RegisterL1Block function -func TestBuilderRegisterL1Block(t *testing.T) { - channelConfig := defaultTestChannelConfig +func TestChannelBuilder_CheckTimeout(t *testing.T) { + channelConfig := defaultTestChannelConfig() // Construct the channel builder - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) - // Assert params modified in RegisterL1Block + // Assert timeout is setup correctly require.Equal(t, uint64(1), channelConfig.MaxChannelDuration) - require.Equal(t, uint64(0), cb.timeout) + require.Equal(t, latestL1BlockOrigin+channelConfig.MaxChannelDuration, cb.timeout) - // Register a new L1 block - cb.RegisterL1Block(uint64(100)) + // Check an L1 block which is after the timeout + blockNum := uint64(100) + cb.CheckTimeout(blockNum) + require.Greater(t, blockNum, cb.timeout) - // Assert params modified in RegisterL1Block + // Assert params not modified in CheckTimeout require.Equal(t, uint64(1), channelConfig.MaxChannelDuration) - require.Equal(t, uint64(101), cb.timeout) + require.Equal(t, latestL1BlockOrigin+channelConfig.MaxChannelDuration, cb.timeout) + require.ErrorIs(t, cb.FullErr(), ErrMaxDurationReached) } -// TestBuilderRegisterL1BlockZeroMaxChannelDuration tests the RegisterL1Block function -func TestBuilderRegisterL1BlockZeroMaxChannelDuration(t *testing.T) { - channelConfig := defaultTestChannelConfig +func TestChannelBuilder_CheckTimeoutZeroMaxChannelDuration(t *testing.T) { + channelConfig := defaultTestChannelConfig() // Set the max channel duration to 0 channelConfig.MaxChannelDuration = 0 // Construct the channel builder - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(channelConfig, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) - // Assert params modified in RegisterL1Block + // Without a max channel duration, timeout should not be set require.Equal(t, uint64(0), channelConfig.MaxChannelDuration) require.Equal(t, uint64(0), cb.timeout) - // Register a new L1 block - cb.RegisterL1Block(uint64(100)) + // Check a new L1 block which should not update the timeout + cb.CheckTimeout(uint64(100)) // Since the max channel duration is set to 0, // the L1 block register should not update the timeout @@ -737,38 +641,61 @@ func TestBuilderRegisterL1BlockZeroMaxChannelDuration(t *testing.T) { require.Equal(t, uint64(0), cb.timeout) } -// TestFramePublished tests the FramePublished function -func TestFramePublished(t *testing.T) { - channelConfig := defaultTestChannelConfig +func TestChannelBuilder_FramePublished(t *testing.T) { + cfg := defaultTestChannelConfig() + cfg.MaxChannelDuration = 10_000 + cfg.ChannelTimeout = 1000 + cfg.SubSafetyMargin = 100 // Construct the channel builder - cb, err := newChannelBuilder(channelConfig, nil) + cb, err := NewChannelBuilder(cfg, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(t, err) + require.Equal(t, latestL1BlockOrigin+cfg.MaxChannelDuration, cb.timeout) - // Let's say the block number is fed in as 100 - // and the channel timeout is 1000 - l1BlockNum := uint64(100) - cb.cfg.ChannelTimeout = uint64(1000) - cb.cfg.SubSafetyMargin = 100 + priorTimeout := cb.timeout // Then the frame published will update the timeout + l1BlockNum := uint64(100) + require.Less(t, l1BlockNum, cb.timeout) cb.FramePublished(l1BlockNum) - // Now the timeout will be 1000 + // Now the timeout will be 1000, blockNum + channelTimeout - subSafetyMargin require.Equal(t, uint64(1000), cb.timeout) + require.Less(t, cb.timeout, priorTimeout) +} + +func TestChannelBuilder_LatestL1Origin(t *testing.T) { + cb, err := NewChannelBuilder(defaultTestChannelConfig(), defaultTestRollupConfig, latestL1BlockOrigin) + require.NoError(t, err) + require.Equal(t, eth.BlockID{}, cb.LatestL1Origin()) + + _, err = cb.AddBlock(newMiniL2BlockWithNumberParentAndL1Information(0, big.NewInt(1), common.Hash{}, 1, 100)) + require.NoError(t, err) + require.Equal(t, uint64(1), cb.LatestL1Origin().Number) + + _, err = cb.AddBlock(newMiniL2BlockWithNumberParentAndL1Information(0, big.NewInt(2), common.Hash{}, 1, 100)) + require.NoError(t, err) + require.Equal(t, uint64(1), cb.LatestL1Origin().Number) + + _, err = cb.AddBlock(newMiniL2BlockWithNumberParentAndL1Information(0, big.NewInt(3), common.Hash{}, 2, 110)) + require.NoError(t, err) + require.Equal(t, uint64(2), cb.LatestL1Origin().Number) + + _, err = cb.AddBlock(newMiniL2BlockWithNumberParentAndL1Information(0, big.NewInt(3), common.Hash{}, 1, 110)) + require.NoError(t, err) + require.Equal(t, uint64(2), cb.LatestL1Origin().Number) } func ChannelBuilder_PendingFrames_TotalFrames(t *testing.T, batchType uint) { const tnf = 9 rng := rand.New(rand.NewSource(94572314)) require := require.New(t) - cfg := defaultTestChannelConfig - cfg.CompressorConfig.TargetFrameSize = 1000 + cfg := defaultTestChannelConfig() cfg.MaxFrameSize = 1000 - cfg.CompressorConfig.TargetNumFrames = tnf - cfg.CompressorConfig.Kind = "shadow" + cfg.TargetNumFrames = tnf cfg.BatchType = batchType - cb, err := newChannelBuilder(cfg, &defaultTestRollupConfig) + cfg.InitShadowCompressor() + cb, err := NewChannelBuilder(cfg, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(err) // initial builder should be empty @@ -805,14 +732,14 @@ func ChannelBuilder_PendingFrames_TotalFrames(t *testing.T, batchType uint) { func ChannelBuilder_InputBytes(t *testing.T, batchType uint) { require := require.New(t) rng := rand.New(rand.NewSource(4982432)) - cfg := defaultTestChannelConfig + cfg := defaultTestChannelConfig() cfg.BatchType = batchType var spanBatchBuilder *derive.SpanBatchBuilder if batchType == derive.SpanBatchType { chainId := big.NewInt(1234) spanBatchBuilder = derive.NewSpanBatchBuilder(uint64(0), chainId) } - cb, err := newChannelBuilder(cfg, &defaultTestRollupConfig) + cb, err := NewChannelBuilder(cfg, defaultTestRollupConfig, latestL1BlockOrigin) require.NoError(err) require.Zero(cb.InputBytes()) @@ -823,7 +750,7 @@ func ChannelBuilder_InputBytes(t *testing.T, batchType uint) { if batchType == derive.SingularBatchType { l += blockBatchRlpSize(t, block) } else { - singularBatch, l1Info, err := derive.BlockToSingularBatch(block) + singularBatch, l1Info, err := derive.BlockToSingularBatch(&defaultTestRollupConfig, block) require.NoError(err) spanBatchBuilder.AppendSingularBatch(singularBatch, l1Info.SequenceNumber) rawSpanBatch, err := spanBatchBuilder.GetRawSpanBatch() @@ -842,14 +769,13 @@ func ChannelBuilder_InputBytes(t *testing.T, batchType uint) { func ChannelBuilder_OutputBytes(t *testing.T, batchType uint) { require := require.New(t) rng := rand.New(rand.NewSource(9860372)) - cfg := defaultTestChannelConfig - cfg.CompressorConfig.TargetFrameSize = 1000 + cfg := defaultTestChannelConfig() cfg.MaxFrameSize = 1000 - cfg.CompressorConfig.TargetNumFrames = 16 - cfg.CompressorConfig.ApproxComprRatio = 1.0 + cfg.TargetNumFrames = 16 cfg.BatchType = batchType - cb, err := newChannelBuilder(cfg, &defaultTestRollupConfig) - require.NoError(err, "newChannelBuilder") + cfg.InitRatioCompressor(1.0) + cb, err := NewChannelBuilder(cfg, defaultTestRollupConfig, latestL1BlockOrigin) + require.NoError(err, "NewChannelBuilder") require.Zero(cb.OutputBytes()) @@ -877,7 +803,7 @@ func ChannelBuilder_OutputBytes(t *testing.T, batchType uint) { func blockBatchRlpSize(t *testing.T, b *types.Block) int { t.Helper() - singularBatch, _, err := derive.BlockToSingularBatch(b) + singularBatch, _, err := derive.BlockToSingularBatch(&defaultTestRollupConfig, b) batch := derive.NewBatchData(singularBatch) require.NoError(t, err) var buf bytes.Buffer diff --git a/op-batcher/batcher/channel_config.go b/op-batcher/batcher/channel_config.go new file mode 100644 index 000000000000..c6a0eec4c04c --- /dev/null +++ b/op-batcher/batcher/channel_config.go @@ -0,0 +1,119 @@ +package batcher + +import ( + "fmt" + + "github.com/ethereum-optimism/optimism/op-batcher/compressor" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" +) + +type ChannelConfig struct { + // Number of epochs (L1 blocks) per sequencing window, including the epoch + // L1 origin block itself + SeqWindowSize uint64 + // The maximum number of L1 blocks that the inclusion transactions of a + // channel's frames can span. + ChannelTimeout uint64 + + // Builder Config + + // MaxChannelDuration is the maximum duration (in #L1-blocks) to keep the + // channel open. This allows control over how long a channel is kept open + // during times of low transaction volume. + // + // If 0, duration checks are disabled. + MaxChannelDuration uint64 + // The batcher tx submission safety margin (in #L1-blocks) to subtract from + // a channel's timeout and sequencing window, to guarantee safe inclusion of + // a channel on L1. + SubSafetyMargin uint64 + // The maximum byte-size a frame can have. + MaxFrameSize uint64 + + // Target number of frames to create per channel. + // For blob transactions, this controls the number of blobs to target adding + // to each blob tx. + TargetNumFrames int + + // CompressorConfig contains the configuration for creating new compressors. + // It should not be set directly, but via the Init*Compressor methods after + // creating the ChannelConfig to guarantee a consistent configuration. + CompressorConfig compressor.Config + + // BatchType indicates whether the channel uses SingularBatch or SpanBatch. + BatchType uint + + // Whether to put all frames of a channel inside a single tx. + // Should only be used for blob transactions. + MultiFrameTxs bool +} + +// InitCompressorConfig (re)initializes the channel configuration's compressor +// configuration using the given values. The TargetOutputSize will be set to a +// value consistent with cc.TargetNumFrames and cc.MaxFrameSize. +// comprKind can be the empty string, in which case the default compressor will +// be used. +func (cc *ChannelConfig) InitCompressorConfig(approxComprRatio float64, comprKind string) { + cc.CompressorConfig = compressor.Config{ + // Compressor output size needs to account for frame encoding overhead + TargetOutputSize: MaxDataSize(cc.TargetNumFrames, cc.MaxFrameSize), + ApproxComprRatio: approxComprRatio, + Kind: comprKind, + } +} + +func (cc *ChannelConfig) InitRatioCompressor(approxComprRatio float64) { + cc.InitCompressorConfig(approxComprRatio, compressor.RatioKind) +} + +func (cc *ChannelConfig) InitShadowCompressor() { + cc.InitCompressorConfig(0, compressor.ShadowKind) +} + +func (cc *ChannelConfig) InitNoneCompressor() { + cc.InitCompressorConfig(0, compressor.NoneKind) +} + +func (cc *ChannelConfig) MaxFramesPerTx() int { + if !cc.MultiFrameTxs { + return 1 + } + return cc.TargetNumFrames +} + +// Check validates the [ChannelConfig] parameters. +func (cc *ChannelConfig) Check() error { + // The [ChannelTimeout] must be larger than the [SubSafetyMargin]. + // Otherwise, new blocks would always be considered timed out. + if cc.ChannelTimeout < cc.SubSafetyMargin { + return ErrInvalidChannelTimeout + } + + // The max frame size must at least be able to accommodate the constant + // frame overhead. + if cc.MaxFrameSize < derive.FrameV0OverHeadSize { + return fmt.Errorf("max frame size %d is less than the minimum %d", + cc.MaxFrameSize, derive.FrameV0OverHeadSize) + } + + if cc.BatchType > derive.SpanBatchType { + return fmt.Errorf("unrecognized batch type: %d", cc.BatchType) + } + + if nf := cc.TargetNumFrames; nf < 1 { + return fmt.Errorf("invalid number of frames %d", nf) + } + + return nil +} + +// MaxDataSize returns the maximum byte size of output data that can be packed +// into a channel with numFrames frames and frames of max size maxFrameSize. +// It accounts for the constant frame overhead. It panics if the maxFrameSize +// is smaller than [derive.FrameV0OverHeadSize]. +func MaxDataSize(numFrames int, maxFrameSize uint64) uint64 { + if maxFrameSize < derive.FrameV0OverHeadSize { + panic("max frame size smaller than frame overhead") + } + return uint64(numFrames) * (maxFrameSize - derive.FrameV0OverHeadSize) +} diff --git a/op-batcher/batcher/channel_config_test.go b/op-batcher/batcher/channel_config_test.go new file mode 100644 index 000000000000..a89d780ab558 --- /dev/null +++ b/op-batcher/batcher/channel_config_test.go @@ -0,0 +1,96 @@ +package batcher + +import ( + "fmt" + "math" + "testing" + + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + + "github.com/stretchr/testify/require" +) + +func defaultTestChannelConfig() ChannelConfig { + c := ChannelConfig{ + SeqWindowSize: 15, + ChannelTimeout: 40, + MaxChannelDuration: 1, + SubSafetyMargin: 4, + MaxFrameSize: 120_000, + TargetNumFrames: 1, + BatchType: derive.SingularBatchType, + } + c.InitRatioCompressor(0.4) + return c +} + +func TestChannelConfig_Check(t *testing.T) { + type test struct { + input func() ChannelConfig + assertion func(error) + } + + tests := []test{ + { + input: defaultTestChannelConfig, + assertion: func(output error) { + require.NoError(t, output) + }, + }, + { + input: func() ChannelConfig { + cfg := defaultTestChannelConfig() + cfg.ChannelTimeout = 0 + cfg.SubSafetyMargin = 1 + return cfg + }, + assertion: func(output error) { + require.ErrorIs(t, output, ErrInvalidChannelTimeout) + }, + }, + } + for i := 0; i < derive.FrameV0OverHeadSize; i++ { + expectedErr := fmt.Sprintf("max frame size %d is less than the minimum 23", i) + i := i // need to udpate Go version... + tests = append(tests, test{ + input: func() ChannelConfig { + cfg := defaultTestChannelConfig() + cfg.MaxFrameSize = uint64(i) + return cfg + }, + assertion: func(output error) { + require.EqualError(t, output, expectedErr) + }, + }) + } + + // Run the table tests + for _, test := range tests { + cfg := test.input() + test.assertion(cfg.Check()) + } +} + +// FuzzChannelConfig_CheckTimeout tests the [ChannelConfig.Check] function +// with fuzzing to make sure that a [ErrInvalidChannelTimeout] is thrown when +// the ChannelTimeout is less than the SubSafetyMargin. +func FuzzChannelConfig_CheckTimeout(f *testing.F) { + for i := range [10]int{} { + f.Add(uint64(i+1), uint64(i)) + } + f.Fuzz(func(t *testing.T, channelTimeout uint64, subSafetyMargin uint64) { + // We only test where [ChannelTimeout] is less than the [SubSafetyMargin] + // So we cannot have [ChannelTimeout] be [math.MaxUint64] + if channelTimeout == math.MaxUint64 { + channelTimeout = math.MaxUint64 - 1 + } + if subSafetyMargin <= channelTimeout { + subSafetyMargin = channelTimeout + 1 + } + + channelConfig := defaultTestChannelConfig() + channelConfig.ChannelTimeout = channelTimeout + channelConfig.SubSafetyMargin = subSafetyMargin + require.ErrorIs(t, channelConfig.Check(), ErrInvalidChannelTimeout) + }) +} diff --git a/op-batcher/batcher/channel_manager.go b/op-batcher/batcher/channel_manager.go index 8100a3a2826e..491837182acb 100644 --- a/op-batcher/batcher/channel_manager.go +++ b/op-batcher/batcher/channel_manager.go @@ -25,14 +25,16 @@ var ErrReorg = errors.New("block does not extend existing chain") // channel. // Public functions on channelManager are safe for concurrent access. type channelManager struct { - mu sync.Mutex - log log.Logger - metr metrics.Metricer - cfg ChannelConfig - rcfg *rollup.Config + mu sync.Mutex + log log.Logger + metr metrics.Metricer + cfg ChannelConfig + rollupCfg *rollup.Config // All blocks since the last request for new tx data. blocks []*types.Block + // The latest L1 block from all the L2 blocks in the most recently closed channel + l1OriginLastClosedChannel eth.BlockID // last block hash - for reorg detection tip common.Hash @@ -41,41 +43,43 @@ type channelManager struct { // channels to read frame data from, for writing batches onchain channelQueue []*channel // used to lookup channels by tx ID upon tx success / failure - txChannels map[txID]*channel + txChannels map[string]*channel // if set to true, prevents production of any new channel frames closed bool } -func NewChannelManager(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, rcfg *rollup.Config) *channelManager { +func NewChannelManager(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, rollupCfg *rollup.Config) *channelManager { return &channelManager{ log: log, metr: metr, cfg: cfg, - rcfg: rcfg, - txChannels: make(map[txID]*channel), + rollupCfg: rollupCfg, + txChannels: make(map[string]*channel), } } // Clear clears the entire state of the channel manager. // It is intended to be used before launching op-batcher and after an L2 reorg. -func (s *channelManager) Clear() { +func (s *channelManager) Clear(l1OriginLastClosedChannel eth.BlockID) { s.mu.Lock() defer s.mu.Unlock() s.log.Trace("clearing channel manager state") s.blocks = s.blocks[:0] + s.l1OriginLastClosedChannel = l1OriginLastClosedChannel s.tip = common.Hash{} s.closed = false s.currentChannel = nil s.channelQueue = nil - s.txChannels = make(map[txID]*channel) + s.txChannels = make(map[string]*channel) } // TxFailed records a transaction as failed. It will attempt to resubmit the data // in the failed transaction. -func (s *channelManager) TxFailed(id txID) { +func (s *channelManager) TxFailed(_id txID) { s.mu.Lock() defer s.mu.Unlock() + id := _id.String() if channel, ok := s.txChannels[id]; ok { delete(s.txChannels, id) channel.TxFailed(id) @@ -92,9 +96,10 @@ func (s *channelManager) TxFailed(id txID) { // a channel have been marked as confirmed on L1 the channel may be invalid & need to be // resubmitted. // This function may reset the pending channel if the pending channel has timed out. -func (s *channelManager) TxConfirmed(id txID, inclusionBlock eth.BlockID) { +func (s *channelManager) TxConfirmed(_id txID, inclusionBlock eth.BlockID) { s.mu.Lock() defer s.mu.Unlock() + id := _id.String() if channel, ok := s.txChannels[id]; ok { delete(s.txChannels, id) done, blocks := channel.TxConfirmed(id, inclusionBlock) @@ -130,40 +135,40 @@ func (s *channelManager) removePendingChannel(channel *channel) { // nextTxData pops off s.datas & handles updating the internal state func (s *channelManager) nextTxData(channel *channel) (txData, error) { - if channel == nil || !channel.HasFrame() { + if channel == nil || !channel.HasTxData() { s.log.Trace("no next tx data") return txData{}, io.EOF // TODO: not enough data error instead } tx := channel.NextTxData() - s.txChannels[tx.ID()] = channel + s.txChannels[tx.ID().String()] = channel return tx, nil } // TxData returns the next tx data that should be submitted to L1. // -// It currently only uses one frame per transaction. If the pending channel is +// If the pending channel is // full, it only returns the remaining frames of this channel until it got -// successfully fully sent to L1. It returns io.EOF if there's no pending frame. +// successfully fully sent to L1. It returns io.EOF if there's no pending tx data. func (s *channelManager) TxData(l1Head eth.BlockID) (txData, error) { s.mu.Lock() defer s.mu.Unlock() - var firstWithFrame *channel + var firstWithTxData *channel for _, ch := range s.channelQueue { - if ch.HasFrame() { - firstWithFrame = ch + if ch.HasTxData() { + firstWithTxData = ch break } } - dataPending := firstWithFrame != nil && firstWithFrame.HasFrame() - s.log.Debug("Requested tx data", "l1Head", l1Head, "data_pending", dataPending, "blocks_pending", len(s.blocks)) + dataPending := firstWithTxData != nil && firstWithTxData.HasTxData() + s.log.Debug("Requested tx data", "l1Head", l1Head, "txdata_pending", dataPending, "blocks_pending", len(s.blocks)) - // Short circuit if there is a pending frame or the channel manager is closed. + // Short circuit if there is pending tx data or the channel manager is closed. if dataPending || s.closed { - return s.nextTxData(firstWithFrame) + return s.nextTxData(firstWithTxData) } - // No pending frame, so we have to add new blocks to the channel + // No pending tx data, so we have to add new blocks to the channel // If we have no saved blocks, we will not be able to create valid frames if len(s.blocks) == 0 { @@ -198,16 +203,23 @@ func (s *channelManager) ensureChannelWithSpace(l1Head eth.BlockID) error { return nil } - pc, err := newChannel(s.log, s.metr, s.cfg, s.rcfg) + pc, err := newChannel(s.log, s.metr, s.cfg, s.rollupCfg, s.l1OriginLastClosedChannel.Number) + if err != nil { return fmt.Errorf("creating new channel: %w", err) } + s.currentChannel = pc s.channelQueue = append(s.channelQueue, pc) + s.log.Info("Created channel", "id", pc.ID(), "l1Head", l1Head, - "blocks_pending", len(s.blocks)) + "l1OriginLastClosedChannel", s.l1OriginLastClosedChannel, + "blocks_pending", len(s.blocks), + "batch_type", s.cfg.BatchType, + "max_frame_size", s.cfg.MaxFrameSize, + ) s.metr.RecordChannelOpened(pc.ID(), len(s.blocks)) return nil @@ -215,7 +227,7 @@ func (s *channelManager) ensureChannelWithSpace(l1Head eth.BlockID) error { // registerL1Block registers the given block at the pending channel. func (s *channelManager) registerL1Block(l1Head eth.BlockID) { - s.currentChannel.RegisterL1Block(l1Head.Number) + s.currentChannel.CheckTimeout(l1Head.Number) s.log.Debug("new L1-block registered at channel builder", "l1Head", l1Head, "channel_full", s.currentChannel.IsFull(), @@ -239,7 +251,7 @@ func (s *channelManager) processBlocks() error { } else if err != nil { return fmt.Errorf("adding block[%d] to channel builder: %w", i, err) } - s.log.Debug("Added block to channel", "channel", s.currentChannel.ID(), "block", block) + s.log.Debug("Added block to channel", "id", s.currentChannel.ID(), "block", eth.ToBlockID(block)) blocksAdded += 1 latestL2ref = l2BlockRefFromBlockAndL1Info(block, l1info) @@ -281,6 +293,11 @@ func (s *channelManager) outputFrames() error { return nil } + lastClosedL1Origin := s.currentChannel.LatestL1Origin() + if lastClosedL1Origin.Number > s.l1OriginLastClosedChannel.Number { + s.l1OriginLastClosedChannel = lastClosedL1Origin + } + inBytes, outBytes := s.currentChannel.InputBytes(), s.currentChannel.OutputBytes() s.metr.RecordChannelClosed( s.currentChannel.ID(), @@ -295,14 +312,17 @@ func (s *channelManager) outputFrames() error { if inBytes > 0 { comprRatio = float64(outBytes) / float64(inBytes) } + s.log.Info("Channel closed", "id", s.currentChannel.ID(), "blocks_pending", len(s.blocks), "num_frames", s.currentChannel.TotalFrames(), "input_bytes", inBytes, "output_bytes", outBytes, + "l1_origin", lastClosedL1Origin, "full_reason", s.currentChannel.FullErr(), "compr_ratio", comprRatio, + "latest_l1_origin", s.l1OriginLastClosedChannel, ) return nil } @@ -324,7 +344,7 @@ func (s *channelManager) AddL2Block(block *types.Block) error { return nil } -func l2BlockRefFromBlockAndL1Info(block *types.Block, l1info derive.L1BlockInfo) eth.L2BlockRef { +func l2BlockRefFromBlockAndL1Info(block *types.Block, l1info *derive.L1BlockInfo) eth.L2BlockRef { return eth.L2BlockRef{ Hash: block.Hash(), Number: block.NumberU64(), @@ -335,9 +355,15 @@ func l2BlockRefFromBlockAndL1Info(block *types.Block, l1info derive.L1BlockInfo) } } -// Close closes the current pending channel, if one exists, outputs any remaining frames, -// and prevents the creation of any new channels. -// Any outputted frames still need to be published. +var ErrPendingAfterClose = errors.New("pending channels remain after closing channel-manager") + +// Close clears any pending channels that are not in-flight already, to leave a clean derivation state. +// Close then marks the remaining current open channel, if any, as "full" so it can be submitted as well. +// Close does NOT immediately output frames for the current remaining channel: +// as this might error, due to limitations on a single channel. +// Instead, this is part of the pending-channel submission work: after closing, +// the caller SHOULD drain pending channels by generating TxData repeatedly until there is none left (io.EOF). +// A ErrPendingAfterClose error will be returned if there are any remaining pending channels to submit. func (s *channelManager) Close() error { s.mu.Lock() defer s.mu.Unlock() @@ -346,19 +372,39 @@ func (s *channelManager) Close() error { } s.closed = true + s.log.Info("Channel manager is closing") // Any pending state can be proactively cleared if there are no submitted transactions for _, ch := range s.channelQueue { if ch.NoneSubmitted() { + s.log.Info("Channel has no past or pending submission - dropping", "id", ch.ID()) s.removePendingChannel(ch) + } else { + s.log.Info("Channel is in-flight and will need to be submitted after close", "id", ch.ID(), "confirmed", len(ch.confirmedTransactions), "pending", len(ch.pendingTransactions)) } } + s.log.Info("Reviewed all pending channels on close", "remaining", len(s.channelQueue)) if s.currentChannel == nil { return nil } - s.currentChannel.Close() + // If the channel is already full, we don't need to close it or output frames. + // This would already have happened in TxData. + if !s.currentChannel.IsFull() { + // Force-close the remaining open channel early (if not already closed): + // it will be marked as "full" due to service termination. + s.currentChannel.Close() - return s.outputFrames() + // Final outputFrames call in case there was unflushed data in the compressor. + if err := s.outputFrames(); err != nil { + return fmt.Errorf("outputting frames during close: %w", err) + } + } + + if s.currentChannel.HasTxData() { + // Make it clear to the caller that there is remaining pending work. + return ErrPendingAfterClose + } + return nil } diff --git a/op-batcher/batcher/channel_manager_test.go b/op-batcher/batcher/channel_manager_test.go index 852961c75b9a..e029e69e658c 100644 --- a/op-batcher/batcher/channel_manager_test.go +++ b/op-batcher/batcher/channel_manager_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - "github.com/ethereum-optimism/optimism/op-batcher/compressor" "github.com/ethereum-optimism/optimism/op-batcher/metrics" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" @@ -20,6 +19,16 @@ import ( "github.com/stretchr/testify/require" ) +func channelManagerTestConfig(maxFrameSize uint64, batchType uint) ChannelConfig { + cfg := ChannelConfig{ + MaxFrameSize: maxFrameSize, + TargetNumFrames: 1, + BatchType: batchType, + } + cfg.InitRatioCompressor(1) + return cfg +} + func TestChannelManagerBatchType(t *testing.T) { tests := []struct { name string @@ -52,9 +61,9 @@ func TestChannelManagerBatchType(t *testing.T) { // ChannelManagerReturnsErrReorg ensures that the channel manager // detects a reorg when it has cached L1 blocks. func ChannelManagerReturnsErrReorg(t *testing.T, batchType uint) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{BatchType: batchType}, &rollup.Config{}) - m.Clear() + m.Clear(eth.BlockID{}) a := types.NewBlock(&types.Header{ Number: big.NewInt(0), @@ -83,20 +92,11 @@ func ChannelManagerReturnsErrReorg(t *testing.T, batchType uint) { // ChannelManagerReturnsErrReorgWhenDrained ensures that the channel manager // detects a reorg even if it does not have any blocks inside it. func ChannelManagerReturnsErrReorgWhenDrained(t *testing.T, batchType uint) { - log := testlog.Logger(t, log.LvlCrit) - m := NewChannelManager(log, metrics.NoopMetrics, - ChannelConfig{ - MaxFrameSize: 120_000, - CompressorConfig: compressor.Config{ - TargetFrameSize: 1, - TargetNumFrames: 1, - ApproxComprRatio: 1.0, - }, - BatchType: batchType, - }, - &rollup.Config{}, - ) - m.Clear() + log := testlog.Logger(t, log.LevelCrit) + cfg := channelManagerTestConfig(120_000, batchType) + cfg.CompressorConfig.TargetOutputSize = 1 // full on first block + m := NewChannelManager(log, metrics.NoopMetrics, cfg, &rollup.Config{}) + m.Clear(eth.BlockID{}) a := newMiniL2Block(0) x := newMiniL2BlockWithNumberParent(0, big.NewInt(1), common.Hash{0xff}) @@ -116,34 +116,25 @@ func ChannelManager_Clear(t *testing.T, batchType uint) { require := require.New(t) // Create a channel manager - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) rng := rand.New(rand.NewSource(time.Now().UnixNano())) - m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{ - // Need to set the channel timeout here so we don't clear pending - // channels on confirmation. This would result in [TxConfirmed] - // clearing confirmed transactions, and reseting the pendingChannels map - ChannelTimeout: 10, - // Have to set the max frame size here otherwise the channel builder would not - // be able to output any frames - MaxFrameSize: 24, - CompressorConfig: compressor.Config{ - TargetFrameSize: 24, - TargetNumFrames: 1, - ApproxComprRatio: 1.0, - }, - BatchType: batchType, - }, - &defaultTestRollupConfig, - ) + cfg := channelManagerTestConfig(derive.FrameV0OverHeadSize+1, batchType) + // Need to set the channel timeout here so we don't clear pending + // channels on confirmation. This would result in [TxConfirmed] + // clearing confirmed transactions, and resetting the pendingChannels map + cfg.ChannelTimeout = 10 + cfg.InitRatioCompressor(1) + m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) // Channel Manager state should be empty by default require.Empty(m.blocks) + require.Equal(eth.BlockID{}, m.l1OriginLastClosedChannel) require.Equal(common.Hash{}, m.tip) require.Nil(m.currentChannel) require.Empty(m.channelQueue) require.Empty(m.txChannels) // Set the last block - m.Clear() + m.Clear(eth.BlockID{}) // Add a block to the channel manager a := derivetest.RandomL2BlockWithChainId(rng, 4, defaultTestRollupConfig.L2ChainID) @@ -165,9 +156,10 @@ func ChannelManager_Clear(t *testing.T, batchType uint) { // the list require.NoError(m.processBlocks()) require.NoError(m.currentChannel.channelBuilder.co.Flush()) - require.NoError(m.currentChannel.OutputFrames()) + require.NoError(m.outputFrames()) _, err := m.nextTxData(m.currentChannel) require.NoError(err) + require.NotNil(m.l1OriginLastClosedChannel) require.Len(m.blocks, 0) require.Equal(newL1Tip, m.tip) require.Len(m.currentChannel.pendingTransactions, 1) @@ -182,11 +174,15 @@ func ChannelManager_Clear(t *testing.T, batchType uint) { require.Len(m.blocks, 1) require.Equal(b.Hash(), m.tip) + safeL1Origin := eth.BlockID{ + Number: 123, + } // Clear the channel manager - m.Clear() + m.Clear(safeL1Origin) // Check that the entire channel manager state cleared require.Empty(m.blocks) + require.Equal(uint64(123), m.l1OriginLastClosedChannel.Number) require.Equal(common.Hash{}, m.tip) require.Nil(m.currentChannel) require.Empty(m.channelQueue) @@ -196,20 +192,11 @@ func ChannelManager_Clear(t *testing.T, batchType uint) { func ChannelManager_TxResend(t *testing.T, batchType uint) { require := require.New(t) rng := rand.New(rand.NewSource(time.Now().UnixNano())) - log := testlog.Logger(t, log.LvlError) - m := NewChannelManager(log, metrics.NoopMetrics, - ChannelConfig{ - MaxFrameSize: 120_000, - CompressorConfig: compressor.Config{ - TargetFrameSize: 1, - TargetNumFrames: 1, - ApproxComprRatio: 1.0, - }, - BatchType: batchType, - }, - &defaultTestRollupConfig, - ) - m.Clear() + log := testlog.Logger(t, log.LevelError) + cfg := channelManagerTestConfig(120_000, batchType) + cfg.CompressorConfig.TargetOutputSize = 1 // full on first block + m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m.Clear(eth.BlockID{}) a := derivetest.RandomL2BlockWithChainId(rng, 4, defaultTestRollupConfig.L2ChainID) @@ -217,7 +204,7 @@ func ChannelManager_TxResend(t *testing.T, batchType uint) { txdata0, err := m.TxData(eth.BlockID{}) require.NoError(err) - txdata0bytes := txdata0.Bytes() + txdata0bytes := txdata0.CallData() data0 := make([]byte, len(txdata0bytes)) // make sure we have a clone for later comparison copy(data0, txdata0bytes) @@ -232,7 +219,7 @@ func ChannelManager_TxResend(t *testing.T, batchType uint) { txdata1, err := m.TxData(eth.BlockID{}) require.NoError(err) - data1 := txdata1.Bytes() + data1 := txdata1.CallData() require.Equal(data1, data0) fs, err := derive.ParseFrames(data1) require.NoError(err) @@ -244,24 +231,16 @@ func ChannelManager_TxResend(t *testing.T, batchType uint) { func ChannelManagerCloseBeforeFirstUse(t *testing.T, batchType uint) { require := require.New(t) rng := rand.New(rand.NewSource(time.Now().UnixNano())) - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) m := NewChannelManager(log, metrics.NoopMetrics, - ChannelConfig{ - MaxFrameSize: 100, - ChannelTimeout: 1000, - CompressorConfig: compressor.Config{ - TargetFrameSize: 0, - ApproxComprRatio: 1.0, - }, - BatchType: batchType, - }, + channelManagerTestConfig(10000, batchType), &defaultTestRollupConfig, ) - m.Clear() + m.Clear(eth.BlockID{}) a := derivetest.RandomL2BlockWithChainId(rng, 4, defaultTestRollupConfig.L2ChainID) - m.Close() + require.NoError(m.Close(), "Expected to close channel manager gracefully") err := m.AddL2Block(a) require.NoError(err, "Failed to add L2 block") @@ -275,21 +254,12 @@ func ChannelManagerCloseBeforeFirstUse(t *testing.T, batchType uint) { // channel frames. func ChannelManagerCloseNoPendingChannel(t *testing.T, batchType uint) { require := require.New(t) - log := testlog.Logger(t, log.LvlCrit) - m := NewChannelManager(log, metrics.NoopMetrics, - ChannelConfig{ - MaxFrameSize: 100, - ChannelTimeout: 1000, - CompressorConfig: compressor.Config{ - TargetFrameSize: 1, - TargetNumFrames: 1, - ApproxComprRatio: 1.0, - }, - BatchType: batchType, - }, - &defaultTestRollupConfig, - ) - m.Clear() + log := testlog.Logger(t, log.LevelCrit) + cfg := channelManagerTestConfig(10000, batchType) + cfg.CompressorConfig.TargetOutputSize = 1 // full on first block + cfg.ChannelTimeout = 1000 + m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m.Clear(eth.BlockID{}) a := newMiniL2Block(0) b := newMiniL2BlockWithNumberParent(0, big.NewInt(1), a.Hash()) @@ -304,7 +274,7 @@ func ChannelManagerCloseNoPendingChannel(t *testing.T, batchType uint) { _, err = m.TxData(eth.BlockID{}) require.ErrorIs(err, io.EOF, "Expected channel manager to EOF") - m.Close() + require.NoError(m.Close(), "Expected to close channel manager gracefully") err = m.AddL2Block(b) require.NoError(err, "Failed to add L2 block") @@ -321,50 +291,98 @@ func ChannelManagerClosePendingChannel(t *testing.T, batchType uint) { // The number of batch txs depends on compression of the random data, hence the static test RNG seed. // Example of different RNG seed that creates less than 2 frames: 1698700588902821588 rng := rand.New(rand.NewSource(123)) - log := testlog.Logger(t, log.LvlCrit) - m := NewChannelManager(log, metrics.NoopMetrics, - ChannelConfig{ - MaxFrameSize: 10000, - ChannelTimeout: 1000, - CompressorConfig: compressor.Config{ - TargetNumFrames: 1, - TargetFrameSize: 10000, - ApproxComprRatio: 1.0, - }, - BatchType: batchType, - }, - &defaultTestRollupConfig, - ) - m.Clear() + log := testlog.Logger(t, log.LevelError) + cfg := channelManagerTestConfig(10_000, batchType) + cfg.ChannelTimeout = 1000 + m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m.Clear(eth.BlockID{}) numTx := 20 // Adjust number of txs to make 2 frames a := derivetest.RandomL2BlockWithChainId(rng, numTx, defaultTestRollupConfig.L2ChainID) - b := derivetest.RandomL2BlockWithChainId(rng, 10, defaultTestRollupConfig.L2ChainID) - bHeader := b.Header() - bHeader.Number = new(big.Int).Add(a.Number(), big.NewInt(1)) - bHeader.ParentHash = a.Hash() - b = b.WithSeal(bHeader) err := m.AddL2Block(a) require.NoError(err, "Failed to add L2 block") txdata, err := m.TxData(eth.BlockID{}) require.NoError(err, "Expected channel manager to produce valid tx data") + log.Info("generated first tx data", "len", txdata.Len()) m.TxConfirmed(txdata.ID(), eth.BlockID{}) - m.Close() + require.ErrorIs(m.Close(), ErrPendingAfterClose, "Expected channel manager to error on close because of pending tx data") txdata, err = m.TxData(eth.BlockID{}) require.NoError(err, "Expected channel manager to produce tx data from remaining L2 block data") + log.Info("generated more tx data", "len", txdata.Len()) m.TxConfirmed(txdata.ID(), eth.BlockID{}) _, err = m.TxData(eth.BlockID{}) require.ErrorIs(err, io.EOF, "Expected channel manager to have no more tx data") - err = m.AddL2Block(b) - require.NoError(err, "Failed to add L2 block") + _, err = m.TxData(eth.BlockID{}) + require.ErrorIs(err, io.EOF, "Expected closed channel manager to produce no more tx data") +} + +// ChannelManager_Close_PartiallyPendingChannel ensures that the channel manager +// can gracefully close with a pending channel, where a block is still waiting +// inside the compressor to be flushed. +// +// This test runs only for singular batches on purpose. +// The SpanChannelOut writes full span batches to the compressor for +// every new block that's added, so NonCompressor cannot be used to +// set up a scenario where data is only partially flushed. +// Couldn't get the test to work even with modifying NonCompressor +// to flush half-way through writing to the compressor... +func TestChannelManager_Close_PartiallyPendingChannel(t *testing.T) { + require := require.New(t) + // The number of batch txs depends on compression of the random data, hence the static test RNG seed. + // Example of different RNG seed that creates less than 2 frames: 1698700588902821588 + rng := rand.New(rand.NewSource(123)) + log := testlog.Logger(t, log.LevelError) + cfg := ChannelConfig{ + MaxFrameSize: 2200, + ChannelTimeout: 1000, + TargetNumFrames: 100, + } + cfg.InitNoneCompressor() + m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m.Clear(eth.BlockID{}) + + numTx := 3 // Adjust number of txs to make 2 frames + a := derivetest.RandomL2BlockWithChainId(rng, numTx, defaultTestRollupConfig.L2ChainID) + b := derivetest.RandomL2BlockWithChainId(rng, numTx, defaultTestRollupConfig.L2ChainID) + bHeader := b.Header() + bHeader.Number = new(big.Int).Add(a.Number(), big.NewInt(1)) + bHeader.ParentHash = a.Hash() + b = b.WithSeal(bHeader) + + require.NoError(m.AddL2Block(a), "adding 1st L2 block") + require.NoError(m.AddL2Block(b), "adding 2nd L2 block") + + // Inside TxData, the two blocks queued above are written to the compressor. + // The NonCompressor will flush the first, but not the second block, when + // adding the second block, setting up the test with a partially flushed + // compressor. + txdata, err := m.TxData(eth.BlockID{}) + require.NoError(err, "Expected channel manager to produce valid tx data") + log.Info("generated first tx data", "len", txdata.Len()) + + m.TxConfirmed(txdata.ID(), eth.BlockID{}) + + // ensure no new ready data before closing + _, err = m.TxData(eth.BlockID{}) + require.ErrorIs(err, io.EOF, "Expected unclosed channel manager to only return a single frame") + + require.ErrorIs(m.Close(), ErrPendingAfterClose, "Expected channel manager to error on close because of pending tx data") + require.NotNil(m.currentChannel) + require.ErrorIs(m.currentChannel.FullErr(), ErrTerminated, "Expected current channel to be terminated by Close") + + txdata, err = m.TxData(eth.BlockID{}) + require.NoError(err, "Expected channel manager to produce tx data from remaining L2 block data") + log.Info("generated more tx data", "len", txdata.Len()) + + m.TxConfirmed(txdata.ID(), eth.BlockID{}) _, err = m.TxData(eth.BlockID{}) require.ErrorIs(err, io.EOF, "Expected closed channel manager to produce no more tx data") @@ -375,41 +393,93 @@ func ChannelManagerClosePendingChannel(t *testing.T, batchType uint) { // have successfully landed on chain. func ChannelManagerCloseAllTxsFailed(t *testing.T, batchType uint) { require := require.New(t) - rng := rand.New(rand.NewSource(time.Now().UnixNano())) - log := testlog.Logger(t, log.LvlCrit) - m := NewChannelManager(log, metrics.NoopMetrics, - ChannelConfig{ - MaxFrameSize: 1000, - ChannelTimeout: 1000, - CompressorConfig: compressor.Config{ - TargetNumFrames: 100, - TargetFrameSize: 1000, - ApproxComprRatio: 1.0, - }, - BatchType: batchType, - }, &defaultTestRollupConfig, - ) - m.Clear() + rng := rand.New(rand.NewSource(1357)) + log := testlog.Logger(t, log.LevelCrit) + cfg := channelManagerTestConfig(100, batchType) + cfg.TargetNumFrames = 1000 + cfg.InitNoneCompressor() + m := NewChannelManager(log, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + m.Clear(eth.BlockID{}) - a := derivetest.RandomL2BlockWithChainId(rng, 50000, defaultTestRollupConfig.L2ChainID) + a := derivetest.RandomL2BlockWithChainId(rng, 1000, defaultTestRollupConfig.L2ChainID) err := m.AddL2Block(a) require.NoError(err, "Failed to add L2 block") - txdata, err := m.TxData(eth.BlockID{}) - require.NoError(err, "Expected channel manager to produce valid tx data") + drainTxData := func() (txdatas []txData) { + for { + txdata, err := m.TxData(eth.BlockID{}) + if err == io.EOF { + return + } + require.NoError(err, "Expected channel manager to produce valid tx data") + txdatas = append(txdatas, txdata) + } + } - m.TxFailed(txdata.ID()) + txdatas := drainTxData() + require.NotEmpty(txdatas) + + for _, txdata := range txdatas { + m.TxFailed(txdata.ID()) + } // Show that this data will continue to be emitted as long as the transaction // fails and the channel manager is not closed - txdata, err = m.TxData(eth.BlockID{}) - require.NoError(err, "Expected channel manager to re-attempt the failed transaction") + txdatas1 := drainTxData() + require.NotEmpty(txdatas) + require.ElementsMatch(txdatas, txdatas1, "expected same txdatas on re-attempt") - m.TxFailed(txdata.ID()) + for _, txdata := range txdatas1 { + m.TxFailed(txdata.ID()) + } - m.Close() + require.NoError(m.Close(), "Expected to close channel manager gracefully") _, err = m.TxData(eth.BlockID{}) require.ErrorIs(err, io.EOF, "Expected closed channel manager to produce no more tx data") } + +func TestChannelManager_ChannelCreation(t *testing.T) { + l := testlog.Logger(t, log.LevelCrit) + const maxChannelDuration = 15 + cfg := channelManagerTestConfig(1000, derive.SpanBatchType) + cfg.MaxChannelDuration = maxChannelDuration + cfg.InitNoneCompressor() + + for _, tt := range []struct { + name string + safeL1Block eth.BlockID + expectedChannelTimeout uint64 + }{ + { + name: "UseSafeHeadWhenNoLastL1Block", + safeL1Block: eth.BlockID{ + Number: uint64(123), + }, + // Safe head + maxChannelDuration + expectedChannelTimeout: 123 + maxChannelDuration, + }, + { + name: "NoLastL1BlockNoSafeL1Block", + safeL1Block: eth.BlockID{ + Number: 0, + }, + // No timeout + expectedChannelTimeout: 0 + maxChannelDuration, + }, + } { + test := tt + t.Run(test.name, func(t *testing.T) { + m := NewChannelManager(l, metrics.NoopMetrics, cfg, &defaultTestRollupConfig) + + m.l1OriginLastClosedChannel = test.safeL1Block + require.Nil(t, m.currentChannel) + + require.NoError(t, m.ensureChannelWithSpace(eth.BlockID{})) + + require.NotNil(t, m.currentChannel) + require.Equal(t, test.expectedChannelTimeout, m.currentChannel.Timeout()) + }) + } +} diff --git a/op-batcher/batcher/channel_test.go b/op-batcher/batcher/channel_test.go index 138416069767..71903eb370ca 100644 --- a/op-batcher/batcher/channel_test.go +++ b/op-batcher/batcher/channel_test.go @@ -14,15 +14,23 @@ import ( "github.com/stretchr/testify/require" ) +func singleFrameTxID(cid derive.ChannelID, fn uint16) txID { + return txID{frameID{chID: cid, frameNumber: fn}} +} + +func zeroFrameTxID(fn uint16) txID { + return txID{frameID{frameNumber: fn}} +} + // TestChannelTimeout tests that the channel manager // correctly identifies when a pending channel is timed out. func TestChannelTimeout(t *testing.T) { // Create a new channel manager with a ChannelTimeout - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{ ChannelTimeout: 100, }, &rollup.Config{}) - m.Clear() + m.Clear(eth.BlockID{}) // Pending channel is nil so is cannot be timed out require.Nil(t, m.currentChannel) @@ -39,8 +47,9 @@ func TestChannelTimeout(t *testing.T) { // Manually set a confirmed transactions // To avoid other methods clearing state - channel.confirmedTransactions[frameID{frameNumber: 0}] = eth.BlockID{Number: 0} - channel.confirmedTransactions[frameID{frameNumber: 1}] = eth.BlockID{Number: 99} + channel.confirmedTransactions[zeroFrameTxID(0).String()] = eth.BlockID{Number: 0} + channel.confirmedTransactions[zeroFrameTxID(1).String()] = eth.BlockID{Number: 99} + channel.confirmedTxUpdated = true // Since the ChannelTimeout is 100, the // pending channel should not be timed out @@ -49,22 +58,21 @@ func TestChannelTimeout(t *testing.T) { // Add a confirmed transaction with a higher number // than the ChannelTimeout - channel.confirmedTransactions[frameID{ - frameNumber: 2, - }] = eth.BlockID{ + channel.confirmedTransactions[zeroFrameTxID(2).String()] = eth.BlockID{ Number: 101, } + channel.confirmedTxUpdated = true // Now the pending channel should be timed out timeout = channel.isTimedOut() require.True(t, timeout) } -// TestChannelNextTxData checks the nextTxData function. -func TestChannelNextTxData(t *testing.T) { - log := testlog.Logger(t, log.LvlCrit) +// TestChannelManager_NextTxData tests the nextTxData function. +func TestChannelManager_NextTxData(t *testing.T) { + log := testlog.Logger(t, log.LevelCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{}, &rollup.Config{}) - m.Clear() + m.Clear(eth.BlockID{}) // Nil pending channel should return EOF returnedTxData, err := m.nextTxData(nil) @@ -90,30 +98,112 @@ func TestChannelNextTxData(t *testing.T) { frameNumber: uint16(0), }, } - channel.channelBuilder.PushFrame(frame) + channel.channelBuilder.PushFrames(frame) require.Equal(t, 1, channel.PendingFrames()) // Now the nextTxData function should return the frame returnedTxData, err = m.nextTxData(channel) - expectedTxData := txData{frame} - expectedChannelID := expectedTxData.ID() + expectedTxData := singleFrameTxData(frame) + expectedChannelID := expectedTxData.ID().String() require.NoError(t, err) require.Equal(t, expectedTxData, returnedTxData) require.Equal(t, 0, channel.PendingFrames()) require.Equal(t, expectedTxData, channel.pendingTransactions[expectedChannelID]) } +func TestChannel_NextTxData_singleFrameTx(t *testing.T) { + require := require.New(t) + const n = 6 + lgr := testlog.Logger(t, log.LevelWarn) + ch, err := newChannel(lgr, metrics.NoopMetrics, ChannelConfig{ + MultiFrameTxs: false, + TargetNumFrames: n, + }, &rollup.Config{}, latestL1BlockOrigin) + require.NoError(err) + chID := ch.ID() + + mockframes := makeMockFrameDatas(chID, n+1) + // put multiple frames into channel, but less than target + ch.channelBuilder.PushFrames(mockframes[:n-1]...) + + requireTxData := func(i int) { + require.True(ch.HasTxData(), "expected tx data %d", i) + txdata := ch.NextTxData() + require.Len(txdata.frames, 1) + frame := txdata.frames[0] + require.Len(frame.data, 1) + require.EqualValues(i, frame.data[0]) + require.Equal(frameID{chID: chID, frameNumber: uint16(i)}, frame.id) + } + + for i := 0; i < n-1; i++ { + requireTxData(i) + } + require.False(ch.HasTxData()) + + // put in last two + ch.channelBuilder.PushFrames(mockframes[n-1 : n+1]...) + for i := n - 1; i < n+1; i++ { + requireTxData(i) + } + require.False(ch.HasTxData()) +} + +func TestChannel_NextTxData_multiFrameTx(t *testing.T) { + require := require.New(t) + const n = 6 + lgr := testlog.Logger(t, log.LevelWarn) + ch, err := newChannel(lgr, metrics.NoopMetrics, ChannelConfig{ + MultiFrameTxs: true, + TargetNumFrames: n, + }, &rollup.Config{}, latestL1BlockOrigin) + require.NoError(err) + chID := ch.ID() + + mockframes := makeMockFrameDatas(chID, n+1) + // put multiple frames into channel, but less than target + ch.channelBuilder.PushFrames(mockframes[:n-1]...) + require.False(ch.HasTxData()) + + // put in last two + ch.channelBuilder.PushFrames(mockframes[n-1 : n+1]...) + require.True(ch.HasTxData()) + txdata := ch.NextTxData() + require.Len(txdata.frames, n) + for i := 0; i < n; i++ { + frame := txdata.frames[i] + require.Len(frame.data, 1) + require.EqualValues(i, frame.data[0]) + require.Equal(frameID{chID: chID, frameNumber: uint16(i)}, frame.id) + } + require.False(ch.HasTxData(), "no tx data expected with single pending frame") +} + +func makeMockFrameDatas(id derive.ChannelID, n int) []frameData { + fds := make([]frameData, 0, n) + for i := 0; i < n; i++ { + fds = append(fds, frameData{ + data: []byte{byte(i)}, + id: frameID{ + chID: id, + frameNumber: uint16(i), + }, + }) + } + return fds +} + // TestChannelTxConfirmed checks the [ChannelManager.TxConfirmed] function. func TestChannelTxConfirmed(t *testing.T) { // Create a channel manager - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{ // Need to set the channel timeout here so we don't clear pending // channels on confirmation. This would result in [TxConfirmed] - // clearing confirmed transactions, and reseting the pendingChannels map + // clearing confirmed transactions, and resetting the pendingChannels map ChannelTimeout: 10, }, &rollup.Config{}) - m.Clear() + m.Clear(eth.BlockID{}) // Let's add a valid pending transaction to the channel manager // So we can demonstrate that TxConfirmed's correctness @@ -126,15 +216,15 @@ func TestChannelTxConfirmed(t *testing.T) { frameNumber: uint16(0), }, } - m.currentChannel.channelBuilder.PushFrame(frame) + m.currentChannel.channelBuilder.PushFrames(frame) require.Equal(t, 1, m.currentChannel.PendingFrames()) returnedTxData, err := m.nextTxData(m.currentChannel) - expectedTxData := txData{frame} + expectedTxData := singleFrameTxData(frame) expectedChannelID := expectedTxData.ID() require.NoError(t, err) require.Equal(t, expectedTxData, returnedTxData) require.Equal(t, 0, m.currentChannel.PendingFrames()) - require.Equal(t, expectedTxData, m.currentChannel.pendingTransactions[expectedChannelID]) + require.Equal(t, expectedTxData, m.currentChannel.pendingTransactions[expectedChannelID.String()]) require.Len(t, m.currentChannel.pendingTransactions, 1) // An unknown pending transaction should not be marked as confirmed @@ -142,7 +232,7 @@ func TestChannelTxConfirmed(t *testing.T) { actualChannelID := m.currentChannel.ID() unknownChannelID := derive.ChannelID([derive.ChannelIDLength]byte{0x69}) require.NotEqual(t, actualChannelID, unknownChannelID) - unknownTxID := frameID{chID: unknownChannelID, frameNumber: 0} + unknownTxID := singleFrameTxID(unknownChannelID, 0) blockID := eth.BlockID{Number: 0, Hash: common.Hash{0x69}} m.TxConfirmed(unknownTxID, blockID) require.Empty(t, m.currentChannel.confirmedTransactions) @@ -154,15 +244,15 @@ func TestChannelTxConfirmed(t *testing.T) { m.TxConfirmed(expectedChannelID, blockID) require.Empty(t, m.currentChannel.pendingTransactions) require.Len(t, m.currentChannel.confirmedTransactions, 1) - require.Equal(t, blockID, m.currentChannel.confirmedTransactions[expectedChannelID]) + require.Equal(t, blockID, m.currentChannel.confirmedTransactions[expectedChannelID.String()]) } // TestChannelTxFailed checks the [ChannelManager.TxFailed] function. func TestChannelTxFailed(t *testing.T) { // Create a channel manager - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{}, &rollup.Config{}) - m.Clear() + m.Clear(eth.BlockID{}) // Let's add a valid pending transaction to the channel // manager so we can demonstrate correctness @@ -175,22 +265,22 @@ func TestChannelTxFailed(t *testing.T) { frameNumber: uint16(0), }, } - m.currentChannel.channelBuilder.PushFrame(frame) + m.currentChannel.channelBuilder.PushFrames(frame) require.Equal(t, 1, m.currentChannel.PendingFrames()) returnedTxData, err := m.nextTxData(m.currentChannel) - expectedTxData := txData{frame} + expectedTxData := singleFrameTxData(frame) expectedChannelID := expectedTxData.ID() require.NoError(t, err) require.Equal(t, expectedTxData, returnedTxData) require.Equal(t, 0, m.currentChannel.PendingFrames()) - require.Equal(t, expectedTxData, m.currentChannel.pendingTransactions[expectedChannelID]) + require.Equal(t, expectedTxData, m.currentChannel.pendingTransactions[expectedChannelID.String()]) require.Len(t, m.currentChannel.pendingTransactions, 1) // Trying to mark an unknown pending transaction as failed // shouldn't modify state - m.TxFailed(frameID{}) + m.TxFailed(zeroFrameTxID(0)) require.Equal(t, 0, m.currentChannel.PendingFrames()) - require.Equal(t, expectedTxData, m.currentChannel.pendingTransactions[expectedChannelID]) + require.Equal(t, expectedTxData, m.currentChannel.pendingTransactions[expectedChannelID.String()]) // Now we still have a pending transaction // Let's mark it as failed diff --git a/op-batcher/batcher/config.go b/op-batcher/batcher/config.go index d4f34461f02d..7450e83fb55f 100644 --- a/op-batcher/batcher/config.go +++ b/op-batcher/batcher/config.go @@ -1,15 +1,19 @@ package batcher import ( + "errors" + "fmt" + "strings" "time" "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/op-batcher/compressor" "github.com/ethereum-optimism/optimism/op-batcher/flags" + plasma "github.com/ethereum-optimism/optimism/op-plasma" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) @@ -18,10 +22,10 @@ type CLIConfig struct { // L1EthRpc is the HTTP provider URL for L1. L1EthRpc string - // L2EthRpc is the HTTP provider URL for the L2 execution engine. + // L2EthRpc is the HTTP provider URL for the L2 execution engine. A comma-separated list enables the active L2 provider. Such a list needs to match the number of RollupRpcs provided. L2EthRpc string - // RollupRpc is the HTTP provider URL for the L2 rollup node. + // RollupRpc is the HTTP provider URL for the L2 rollup node. A comma-separated list enables the active L2 provider. Such a list needs to match the number of L2EthRpcs provided. RollupRpc string // MaxChannelDuration is the maximum duration (in #L1-blocks) to keep a @@ -48,23 +52,78 @@ type CLIConfig struct { MaxPendingTransactions uint64 // MaxL1TxSize is the maximum size of a batch tx submitted to L1. + // If using blobs, this setting is ignored and the max blob size is used. MaxL1TxSize uint64 + // The target number of frames to create per channel. Controls number of blobs + // per blob tx, if using Blob DA. + TargetNumFrames int + + // ApproxComprRatio to assume (only [compressor.RatioCompressor]). + // Should be slightly smaller than average from experiments to avoid the + // chances of creating a small additional leftover frame. + ApproxComprRatio float64 + + // Type of compressor to use. Must be one of [compressor.KindKeys]. + Compressor string + Stopped bool BatchType uint - TxMgrConfig txmgr.CLIConfig - LogConfig oplog.CLIConfig - MetricsConfig opmetrics.CLIConfig - PprofConfig oppprof.CLIConfig - CompressorConfig compressor.CLIConfig - RPC oprpc.CLIConfig + // DataAvailabilityType is one of the values defined in op-batcher/flags/types.go and dictates + // the data availability type to use for posting batches, e.g. blobs vs calldata. + DataAvailabilityType flags.DataAvailabilityType + + // TestUseMaxTxSizeForBlobs allows to set the blob size with MaxL1TxSize. + // Should only be used for testing purposes. + TestUseMaxTxSizeForBlobs bool + + // ActiveSequencerCheckDuration is the duration between checks to determine the active sequencer endpoint. + ActiveSequencerCheckDuration time.Duration + + TxMgrConfig txmgr.CLIConfig + LogConfig oplog.CLIConfig + MetricsConfig opmetrics.CLIConfig + PprofConfig oppprof.CLIConfig + RPC oprpc.CLIConfig + PlasmaDA plasma.CLIConfig } func (c *CLIConfig) Check() error { - // TODO(7512): check the sanity of flags loaded directly https://github.com/ethereum-optimism/optimism/issues/7512 - + if c.L1EthRpc == "" { + return errors.New("empty L1 RPC URL") + } + if c.L2EthRpc == "" { + return errors.New("empty L2 RPC URL") + } + if c.RollupRpc == "" { + return errors.New("empty rollup RPC URL") + } + if strings.Count(c.RollupRpc, ",") != strings.Count(c.L2EthRpc, ",") { + return errors.New("number of rollup and eth URLs must match") + } + if c.PollInterval == 0 { + return errors.New("must set PollInterval") + } + if c.MaxL1TxSize <= 1 { + return errors.New("MaxL1TxSize must be greater than 1") + } + if c.TargetNumFrames < 1 { + return errors.New("TargetNumFrames must be at least 1") + } + if c.Compressor == compressor.RatioKind && (c.ApproxComprRatio <= 0 || c.ApproxComprRatio > 1) { + return fmt.Errorf("invalid ApproxComprRatio %v for ratio compressor", c.ApproxComprRatio) + } + if c.BatchType > 1 { + return fmt.Errorf("unknown batch type: %v", c.BatchType) + } + if c.DataAvailabilityType == flags.BlobsType && c.TargetNumFrames > 6 { + return errors.New("too many frames for blob transactions, max 6") + } + if !flags.ValidDataAvailabilityType(c.DataAvailabilityType) { + return fmt.Errorf("unknown data availability type: %q", c.DataAvailabilityType) + } if err := c.MetricsConfig.Check(); err != nil { return err } @@ -91,16 +150,21 @@ func NewConfig(ctx *cli.Context) *CLIConfig { PollInterval: ctx.Duration(flags.PollIntervalFlag.Name), /* Optional Flags */ - MaxPendingTransactions: ctx.Uint64(flags.MaxPendingTransactionsFlag.Name), - MaxChannelDuration: ctx.Uint64(flags.MaxChannelDurationFlag.Name), - MaxL1TxSize: ctx.Uint64(flags.MaxL1TxSizeBytesFlag.Name), - Stopped: ctx.Bool(flags.StoppedFlag.Name), - BatchType: ctx.Uint(flags.BatchTypeFlag.Name), - TxMgrConfig: txmgr.ReadCLIConfig(ctx), - LogConfig: oplog.ReadCLIConfig(ctx), - MetricsConfig: opmetrics.ReadCLIConfig(ctx), - PprofConfig: oppprof.ReadCLIConfig(ctx), - CompressorConfig: compressor.ReadCLIConfig(ctx), - RPC: oprpc.ReadCLIConfig(ctx), + MaxPendingTransactions: ctx.Uint64(flags.MaxPendingTransactionsFlag.Name), + MaxChannelDuration: ctx.Uint64(flags.MaxChannelDurationFlag.Name), + MaxL1TxSize: ctx.Uint64(flags.MaxL1TxSizeBytesFlag.Name), + TargetNumFrames: ctx.Int(flags.TargetNumFramesFlag.Name), + ApproxComprRatio: ctx.Float64(flags.ApproxComprRatioFlag.Name), + Compressor: ctx.String(flags.CompressorFlag.Name), + Stopped: ctx.Bool(flags.StoppedFlag.Name), + BatchType: ctx.Uint(flags.BatchTypeFlag.Name), + DataAvailabilityType: flags.DataAvailabilityType(ctx.String(flags.DataAvailabilityTypeFlag.Name)), + ActiveSequencerCheckDuration: ctx.Duration(flags.ActiveSequencerCheckDurationFlag.Name), + TxMgrConfig: txmgr.ReadCLIConfig(ctx), + LogConfig: oplog.ReadCLIConfig(ctx), + MetricsConfig: opmetrics.ReadCLIConfig(ctx), + PprofConfig: oppprof.ReadCLIConfig(ctx), + RPC: oprpc.ReadCLIConfig(ctx), + PlasmaDA: plasma.ReadCLIConfig(ctx), } } diff --git a/op-batcher/batcher/config_test.go b/op-batcher/batcher/config_test.go new file mode 100644 index 000000000000..18a6227e0011 --- /dev/null +++ b/op-batcher/batcher/config_test.go @@ -0,0 +1,124 @@ +package batcher_test + +import ( + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-batcher/batcher" + "github.com/ethereum-optimism/optimism/op-batcher/compressor" + "github.com/ethereum-optimism/optimism/op-batcher/flags" + "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/oppprof" + "github.com/ethereum-optimism/optimism/op-service/rpc" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/stretchr/testify/require" +) + +func validBatcherConfig() batcher.CLIConfig { + return batcher.CLIConfig{ + L1EthRpc: "fake", + L2EthRpc: "fake", + RollupRpc: "fake", + MaxChannelDuration: 0, + SubSafetyMargin: 0, + PollInterval: time.Second, + MaxPendingTransactions: 0, + MaxL1TxSize: 10, + TargetNumFrames: 1, + Compressor: "shadow", + Stopped: false, + BatchType: 0, + DataAvailabilityType: flags.CalldataType, + TxMgrConfig: txmgr.NewCLIConfig("fake", txmgr.DefaultBatcherFlagValues), + LogConfig: log.DefaultCLIConfig(), + MetricsConfig: metrics.DefaultCLIConfig(), + PprofConfig: oppprof.DefaultCLIConfig(), + // The compressor config is not checked in config.Check() + RPC: rpc.DefaultCLIConfig(), + } +} + +func TestValidBatcherConfig(t *testing.T) { + cfg := validBatcherConfig() + require.NoError(t, cfg.Check(), "valid config should pass the check function") +} + +func TestBatcherConfig(t *testing.T) { + tests := []struct { + name string + override func(*batcher.CLIConfig) + errString string + }{ + { + name: "empty L1", + override: func(c *batcher.CLIConfig) { c.L1EthRpc = "" }, + errString: "empty L1 RPC URL", + }, + { + name: "empty L2", + override: func(c *batcher.CLIConfig) { c.L2EthRpc = "" }, + errString: "empty L2 RPC URL", + }, + { + name: "empty rollup", + override: func(c *batcher.CLIConfig) { c.RollupRpc = "" }, + errString: "empty rollup RPC URL", + }, + { + name: "empty poll interval", + override: func(c *batcher.CLIConfig) { c.PollInterval = 0 }, + errString: "must set PollInterval", + }, + { + name: "max L1 tx size too small", + override: func(c *batcher.CLIConfig) { c.MaxL1TxSize = 0 }, + errString: "MaxL1TxSize must be greater than 1", + }, + { + name: "invalid batch type close", + override: func(c *batcher.CLIConfig) { c.BatchType = 2 }, + errString: "unknown batch type: 2", + }, + { + name: "invalid batch type far", + override: func(c *batcher.CLIConfig) { c.BatchType = 100 }, + errString: "unknown batch type: 100", + }, + { + name: "invalid batch submission policy", + override: func(c *batcher.CLIConfig) { c.DataAvailabilityType = "foo" }, + errString: "unknown data availability type: \"foo\"", + }, + { + name: "zero TargetNumFrames", + override: func(c *batcher.CLIConfig) { c.TargetNumFrames = 0 }, + errString: "TargetNumFrames must be at least 1", + }, + { + name: "larger 6 TargetNumFrames for blobs", + override: func(c *batcher.CLIConfig) { + c.TargetNumFrames = 7 + c.DataAvailabilityType = flags.BlobsType + }, + errString: "too many frames for blob transactions, max 6", + }, + { + name: "invalid compr ratio for ratio compressor", + override: func(c *batcher.CLIConfig) { + c.ApproxComprRatio = 4.2 + c.Compressor = compressor.RatioKind + }, + errString: "invalid ApproxComprRatio 4.2 for ratio compressor", + }, + } + + for _, test := range tests { + tc := test + t.Run(tc.name, func(t *testing.T) { + cfg := validBatcherConfig() + tc.override(&cfg) + require.ErrorContains(t, cfg.Check(), tc.errString) + }) + } +} diff --git a/op-batcher/batcher/driver.go b/op-batcher/batcher/driver.go index 54633060dac4..50bc25142e22 100644 --- a/op-batcher/batcher/driver.go +++ b/op-batcher/batcher/driver.go @@ -10,15 +10,16 @@ import ( "sync" "time" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum-optimism/optimism/op-batcher/metrics" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + plasma "github.com/ethereum-optimism/optimism/op-plasma" + "github.com/ethereum-optimism/optimism/op-service/dial" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" ) var ErrBatcherNotRunning = errors.New("batcher is not running") @@ -37,15 +38,15 @@ type RollupClient interface { // DriverSetup is the collection of input/output interfaces and configuration that the driver operates on. type DriverSetup struct { - Log log.Logger - Metr metrics.Metricer - RollupCfg *rollup.Config - Cfg BatcherConfig - Txmgr txmgr.TxManager - L1Client L1Client - L2Client L2Client - RollupClient RollupClient - Channel ChannelConfig + Log log.Logger + Metr metrics.Metricer + RollupConfig *rollup.Config + Config BatcherConfig + Txmgr txmgr.TxManager + L1Client L1Client + EndpointProvider dial.L2EndpointProvider + ChannelConfig ChannelConfig + PlasmaDA *plasma.DAClient } // BatchSubmitter encapsulates a service responsible for submitting L2 tx @@ -74,7 +75,7 @@ type BatchSubmitter struct { func NewBatchSubmitter(setup DriverSetup) *BatchSubmitter { return &BatchSubmitter{ DriverSetup: setup, - state: NewChannelManager(setup.Log, setup.Metr, setup.Channel, setup.RollupCfg), + state: NewChannelManager(setup.Log, setup.Metr, setup.ChannelConfig, setup.RollupConfig), } } @@ -91,7 +92,7 @@ func (l *BatchSubmitter) StartBatchSubmitting() error { l.shutdownCtx, l.cancelShutdownCtx = context.WithCancel(context.Background()) l.killCtx, l.cancelKillCtx = context.WithCancel(context.Background()) - l.state.Clear() + l.clearState(l.shutdownCtx) l.lastStoredBlock = eth.BlockID{} l.wg.Add(1) @@ -171,7 +172,7 @@ func (l *BatchSubmitter) loadBlocksIntoState(ctx context.Context) error { latestBlock = block } - l2ref, err := derive.L2BlockToBlockRef(latestBlock, &l.RollupCfg.Genesis) + l2ref, err := derive.L2BlockToBlockRef(l.RollupConfig, latestBlock) if err != nil { l.Log.Warn("Invalid L2 block loaded into state", "err", err) return err @@ -183,9 +184,13 @@ func (l *BatchSubmitter) loadBlocksIntoState(ctx context.Context) error { // loadBlockIntoState fetches & stores a single block into `state`. It returns the block it loaded. func (l *BatchSubmitter) loadBlockIntoState(ctx context.Context, blockNumber uint64) (*types.Block, error) { - ctx, cancel := context.WithTimeout(ctx, l.Cfg.NetworkTimeout) + ctx, cancel := context.WithTimeout(ctx, l.Config.NetworkTimeout) defer cancel() - block, err := l.L2Client.BlockByNumber(ctx, new(big.Int).SetUint64(blockNumber)) + l2Client, err := l.EndpointProvider.EthClient(ctx) + if err != nil { + return nil, fmt.Errorf("getting L2 client: %w", err) + } + block, err := l2Client.BlockByNumber(ctx, new(big.Int).SetUint64(blockNumber)) if err != nil { return nil, fmt.Errorf("getting L2 block: %w", err) } @@ -201,9 +206,13 @@ func (l *BatchSubmitter) loadBlockIntoState(ctx context.Context, blockNumber uin // calculateL2BlockRangeToStore determines the range (start,end] that should be loaded into the local state. // It also takes care of initializing some local state (i.e. will modify l.lastStoredBlock in certain conditions) func (l *BatchSubmitter) calculateL2BlockRangeToStore(ctx context.Context) (eth.BlockID, eth.BlockID, error) { - ctx, cancel := context.WithTimeout(ctx, l.Cfg.NetworkTimeout) + ctx, cancel := context.WithTimeout(ctx, l.Config.NetworkTimeout) defer cancel() - syncStatus, err := l.RollupClient.SyncStatus(ctx) + rollupClient, err := l.EndpointProvider.RollupClient(ctx) + if err != nil { + return eth.BlockID{}, eth.BlockID{}, fmt.Errorf("getting rollup client: %w", err) + } + syncStatus, err := rollupClient.SyncStatus(ctx) // Ensure that we have the sync status if err != nil { return eth.BlockID{}, eth.BlockID{}, fmt.Errorf("failed to get sync status: %w", err) @@ -244,84 +253,148 @@ func (l *BatchSubmitter) calculateL2BlockRangeToStore(ctx context.Context) (eth. func (l *BatchSubmitter) loop() { defer l.wg.Done() - ticker := time.NewTicker(l.Cfg.PollInterval) - defer ticker.Stop() + receiptsCh := make(chan txmgr.TxReceipt[txID]) + queue := txmgr.NewQueue[txID](l.killCtx, l.Txmgr, l.Config.MaxPendingTransactions) + + // start the receipt/result processing loop + receiptLoopDone := make(chan struct{}) + defer close(receiptLoopDone) // shut down receipt loop + go func() { + for { + select { + case r := <-receiptsCh: + l.Log.Info("handling receipt", "id", r.ID) + l.handleReceipt(r) + case <-receiptLoopDone: + l.Log.Info("receipt processing loop done") + return + } + } + }() - receiptsCh := make(chan txmgr.TxReceipt[txData]) - queue := txmgr.NewQueue[txData](l.killCtx, l.Txmgr, l.Cfg.MaxPendingTransactions) + ticker := time.NewTicker(l.Config.PollInterval) + defer ticker.Stop() + publishAndWait := func() { + l.publishStateToL1(queue, receiptsCh) + if !l.Txmgr.IsClosed() { + queue.Wait() + } else { + l.Log.Info("Txmgr is closed, remaining channel data won't be sent") + } + } for { select { case <-ticker.C: if err := l.loadBlocksIntoState(l.shutdownCtx); errors.Is(err, ErrReorg) { err := l.state.Close() if err != nil { - l.Log.Error("error closing the channel manager to handle a L2 reorg", "err", err) + if errors.Is(err, ErrPendingAfterClose) { + l.Log.Warn("Closed channel manager to handle L2 reorg with pending channel(s) remaining - submitting") + } else { + l.Log.Error("Error closing the channel manager to handle a L2 reorg", "err", err) + } } - l.publishStateToL1(queue, receiptsCh, true) - l.state.Clear() + // on reorg we want to publish all pending state then wait until each result clears before resetting + // the state. + publishAndWait() + l.clearState(l.shutdownCtx) continue } - l.publishStateToL1(queue, receiptsCh, false) - case r := <-receiptsCh: - l.handleReceipt(r) + l.publishStateToL1(queue, receiptsCh) case <-l.shutdownCtx.Done(): + if l.Txmgr.IsClosed() { + l.Log.Info("Txmgr is closed, remaining channel data won't be sent") + return + } + // This removes any never-submitted pending channels, so these do not have to be drained with transactions. + // Any remaining unfinished channel is terminated, so its data gets submitted. err := l.state.Close() if err != nil { - l.Log.Error("error closing the channel manager", "err", err) + if errors.Is(err, ErrPendingAfterClose) { + l.Log.Warn("Closed channel manager on shutdown with pending channel(s) remaining - submitting") + } else { + l.Log.Error("Error closing the channel manager on shutdown", "err", err) + } } - l.publishStateToL1(queue, receiptsCh, true) + publishAndWait() + l.Log.Info("Finished publishing all remaining channel data") return } } } -// publishStateToL1 loops through the block data loaded into `state` and -// submits the associated data to the L1 in the form of channel frames. -func (l *BatchSubmitter) publishStateToL1(queue *txmgr.Queue[txData], receiptsCh chan txmgr.TxReceipt[txData], drain bool) { - txDone := make(chan struct{}) - // send/wait and receipt reading must be on a separate goroutines to avoid deadlocks - go func() { - defer func() { - if drain { - // if draining, we wait for all transactions to complete - queue.Wait() - } - close(txDone) - }() - for { - err := l.publishTxToL1(l.killCtx, queue, receiptsCh) - if err != nil { - if drain && err != io.EOF { - l.Log.Error("error sending tx while draining state", "err", err) - } - return +// publishStateToL1 queues up all pending TxData to be published to the L1, returning when there is +// no more data to queue for publishing or if there was an error queing the data. +func (l *BatchSubmitter) publishStateToL1(queue *txmgr.Queue[txID], receiptsCh chan txmgr.TxReceipt[txID]) { + for { + // if the txmgr is closed, we stop the transaction sending + if l.Txmgr.IsClosed() { + l.Log.Info("Txmgr is closed, aborting state publishing") + return + } + err := l.publishTxToL1(l.killCtx, queue, receiptsCh) + if err != nil { + if err != io.EOF { + l.Log.Error("error publishing tx to l1", "err", err) } + return } - }() + } +} + +// clearState clears the state of the channel manager +func (l *BatchSubmitter) clearState(ctx context.Context) { + l.Log.Info("Clearing state") + defer l.Log.Info("State cleared") + + clearStateWithL1Origin := func() bool { + l1SafeOrigin, err := l.safeL1Origin(ctx) + if err != nil { + l.Log.Warn("Failed to query L1 safe origin, will retry", "err", err) + return false + } else { + l.Log.Info("Clearing state with safe L1 origin", "origin", l1SafeOrigin) + l.state.Clear(l1SafeOrigin) + return true + } + } + + // Attempt to set the L1 safe origin and clear the state, if fetching fails -- fall through to an infinite retry + if clearStateWithL1Origin() { + return + } + + tick := time.NewTicker(5 * time.Second) + defer tick.Stop() for { select { - case r := <-receiptsCh: - l.handleReceipt(r) - case <-txDone: + case <-tick.C: + if clearStateWithL1Origin() { + return + } + case <-ctx.Done(): + l.Log.Warn("Clearing state cancelled") + l.state.Clear(eth.BlockID{}) return } } } // publishTxToL1 submits a single state tx to the L1 -func (l *BatchSubmitter) publishTxToL1(ctx context.Context, queue *txmgr.Queue[txData], receiptsCh chan txmgr.TxReceipt[txData]) error { +func (l *BatchSubmitter) publishTxToL1(ctx context.Context, queue *txmgr.Queue[txID], receiptsCh chan txmgr.TxReceipt[txID]) error { // send all available transactions l1tip, err := l.l1Tip(ctx) if err != nil { - l.Log.Error("Failed to query L1 tip", "error", err) + l.Log.Error("Failed to query L1 tip", "err", err) return err } l.recordL1Tip(l1tip) // Collect next transaction data txdata, err := l.state.TxData(l1tip.ID()) + if err == io.EOF { l.Log.Trace("no transaction data available") return err @@ -330,38 +403,114 @@ func (l *BatchSubmitter) publishTxToL1(ctx context.Context, queue *txmgr.Queue[t return err } - l.sendTransaction(txdata, queue, receiptsCh) + if err = l.sendTransaction(ctx, txdata, queue, receiptsCh); err != nil { + return fmt.Errorf("BatchSubmitter.sendTransaction failed: %w", err) + } return nil } -// sendTransaction creates & submits a transaction to the batch inbox address with the given `data`. -// It currently uses the underlying `txmgr` to handle transaction sending & price management. -// This is a blocking method. It should not be called concurrently. -func (l *BatchSubmitter) sendTransaction(txdata txData, queue *txmgr.Queue[txData], receiptsCh chan txmgr.TxReceipt[txData]) { +func (l *BatchSubmitter) safeL1Origin(ctx context.Context) (eth.BlockID, error) { + ctx, cancel := context.WithTimeout(ctx, l.Config.NetworkTimeout) + defer cancel() + + c, err := l.EndpointProvider.RollupClient(ctx) + if err != nil { + log.Error("Failed to get rollup client", "err", err) + return eth.BlockID{}, fmt.Errorf("safe l1 origin: error getting rollup client: %w", err) + } + + status, err := c.SyncStatus(ctx) + if err != nil { + log.Error("Failed to get sync status", "err", err) + return eth.BlockID{}, fmt.Errorf("safe l1 origin: error getting sync status: %w", err) + } + + // If the safe L2 block origin is 0, we are at the genesis block and should use the L1 origin from the rollup config. + if status.SafeL2.L1Origin.Number == 0 { + return l.RollupConfig.Genesis.L1, nil + } + + return status.SafeL2.L1Origin, nil +} + +// sendTransaction creates & queues for sending a transaction to the batch inbox address with the given `txData`. +// The method will block if the queue's MaxPendingTransactions is exceeded. +func (l *BatchSubmitter) sendTransaction(ctx context.Context, txdata txData, queue *txmgr.Queue[txID], receiptsCh chan txmgr.TxReceipt[txID]) error { + var err error // Do the gas estimation offline. A value of 0 will cause the [txmgr] to estimate the gas limit. - data := txdata.Bytes() - intrinsicGas, err := core.IntrinsicGas(data, nil, false, true, true, false) + + var candidate *txmgr.TxCandidate + if l.Config.UseBlobs { + if candidate, err = l.blobTxCandidate(txdata); err != nil { + // We could potentially fall through and try a calldata tx instead, but this would + // likely result in the chain spending more in gas fees than it is tuned for, so best + // to just fail. We do not expect this error to trigger unless there is a serious bug + // or configuration issue. + return fmt.Errorf("could not create blob tx candidate: %w", err) + } + } else { + // sanity check + if nf := len(txdata.frames); nf != 1 { + l.Log.Crit("unexpected number of frames in calldata tx", "num_frames", nf) + } + data := txdata.CallData() + // if plasma DA is enabled we post the txdata to the DA Provider and replace it with the commitment. + if l.Config.UsePlasma { + comm, err := l.PlasmaDA.SetInput(ctx, data) + if err != nil { + l.Log.Error("Failed to post input to Plasma DA", "error", err) + // requeue frame if we fail to post to the DA Provider so it can be retried + l.recordFailedTx(txdata.ID(), err) + return nil + } + // signal plasma commitment tx with TxDataVersion1 + data = comm.TxData() + } + candidate = l.calldataTxCandidate(data) + } + + intrinsicGas, err := core.IntrinsicGas(candidate.TxData, nil, false, true, true, false) if err != nil { - l.Log.Error("Failed to calculate intrinsic gas", "error", err) - return + // we log instead of return an error here because txmgr can do its own gas estimation + l.Log.Error("Failed to calculate intrinsic gas", "err", err) + } else { + candidate.GasLimit = intrinsicGas + } + + queue.Send(txdata.ID(), *candidate, receiptsCh) + return nil +} + +func (l *BatchSubmitter) blobTxCandidate(data txData) (*txmgr.TxCandidate, error) { + blobs, err := data.Blobs() + if err != nil { + return nil, fmt.Errorf("generating blobs for tx data: %w", err) } + size := data.Len() + lastSize := len(data.frames[len(data.frames)-1].data) + l.Log.Info("building Blob transaction candidate", + "size", size, "last_size", lastSize, "num_blobs", len(blobs)) + l.Metr.RecordBlobUsedBytes(lastSize) + return &txmgr.TxCandidate{ + To: &l.RollupConfig.BatchInboxAddress, + Blobs: blobs, + }, nil +} - candidate := txmgr.TxCandidate{ - To: &l.RollupCfg.BatchInboxAddress, - TxData: data, - GasLimit: intrinsicGas, +func (l *BatchSubmitter) calldataTxCandidate(data []byte) *txmgr.TxCandidate { + l.Log.Info("building Calldata transaction candidate", "size", len(data)) + return &txmgr.TxCandidate{ + To: &l.RollupConfig.BatchInboxAddress, + TxData: data, } - queue.Send(txdata, candidate, receiptsCh) } -func (l *BatchSubmitter) handleReceipt(r txmgr.TxReceipt[txData]) { +func (l *BatchSubmitter) handleReceipt(r txmgr.TxReceipt[txID]) { // Record TX Status if r.Err != nil { - l.Log.Warn("unable to publish tx", "err", r.Err, "data_size", r.ID.Len()) - l.recordFailedTx(r.ID.ID(), r.Err) + l.recordFailedTx(r.ID, r.Err) } else { - l.Log.Info("tx successfully published", "tx_hash", r.Receipt.TxHash, "data_size", r.ID.Len()) - l.recordConfirmedTx(r.ID.ID(), r.Receipt) + l.recordConfirmedTx(r.ID, r.Receipt) } } @@ -374,20 +523,20 @@ func (l *BatchSubmitter) recordL1Tip(l1tip eth.L1BlockRef) { } func (l *BatchSubmitter) recordFailedTx(id txID, err error) { - l.Log.Warn("Failed to send transaction", "err", err) + l.Log.Warn("Transaction failed to send", logFields(id, err)...) l.state.TxFailed(id) } func (l *BatchSubmitter) recordConfirmedTx(id txID, receipt *types.Receipt) { - l.Log.Info("Transaction confirmed", "tx_hash", receipt.TxHash, "status", receipt.Status, "block_hash", receipt.BlockHash, "block_number", receipt.BlockNumber) - l1block := eth.BlockID{Number: receipt.BlockNumber.Uint64(), Hash: receipt.BlockHash} + l.Log.Info("Transaction confirmed", logFields(id, receipt)...) + l1block := eth.ReceiptBlockID(receipt) l.state.TxConfirmed(id, l1block) } // l1Tip gets the current L1 tip as a L1BlockRef. The passed context is assumed // to be a lifetime context, so it is internally wrapped with a network timeout. func (l *BatchSubmitter) l1Tip(ctx context.Context) (eth.L1BlockRef, error) { - tctx, cancel := context.WithTimeout(ctx, l.Cfg.NetworkTimeout) + tctx, cancel := context.WithTimeout(ctx, l.Config.NetworkTimeout) defer cancel() head, err := l.L1Client.HeaderByNumber(tctx, nil) if err != nil { @@ -395,3 +544,19 @@ func (l *BatchSubmitter) l1Tip(ctx context.Context) (eth.L1BlockRef, error) { } return eth.InfoToL1BlockRef(eth.HeaderBlockInfo(head)), nil } + +func logFields(xs ...any) (fs []any) { + for _, x := range xs { + switch v := x.(type) { + case txID: + fs = append(fs, "tx_id", v.String()) + case *types.Receipt: + fs = append(fs, "tx", v.TxHash, "block", eth.ReceiptBlockID(v)) + case error: + fs = append(fs, "err", v) + default: + fs = append(fs, "ERROR", fmt.Sprintf("logFields: unknown type: %T", x)) + } + } + return fs +} diff --git a/op-batcher/batcher/driver_test.go b/op-batcher/batcher/driver_test.go new file mode 100644 index 000000000000..df72fa28d49a --- /dev/null +++ b/op-batcher/batcher/driver_test.go @@ -0,0 +1,119 @@ +package batcher + +import ( + "context" + "errors" + "testing" + + "github.com/ethereum-optimism/optimism/op-batcher/metrics" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +type mockL2EndpointProvider struct { + ethClient *testutils.MockL2Client + ethClientErr error + rollupClient *testutils.MockRollupClient + rollupClientErr error +} + +func newEndpointProvider() *mockL2EndpointProvider { + return &mockL2EndpointProvider{ + ethClient: new(testutils.MockL2Client), + rollupClient: new(testutils.MockRollupClient), + } +} + +func (p *mockL2EndpointProvider) EthClient(context.Context) (dial.EthClientInterface, error) { + return p.ethClient, p.ethClientErr +} + +func (p *mockL2EndpointProvider) RollupClient(context.Context) (dial.RollupClientInterface, error) { + return p.rollupClient, p.rollupClientErr +} + +func (p *mockL2EndpointProvider) Close() {} + +const genesisL1Origin = uint64(123) + +func setup(t *testing.T) (*BatchSubmitter, *mockL2EndpointProvider) { + ep := newEndpointProvider() + + cfg := defaultTestRollupConfig + cfg.Genesis.L1.Number = genesisL1Origin + + return NewBatchSubmitter(DriverSetup{ + Log: testlog.Logger(t, log.LevelDebug), + Metr: metrics.NoopMetrics, + RollupConfig: &cfg, + EndpointProvider: ep, + }), ep +} + +func TestBatchSubmitter_SafeL1Origin(t *testing.T) { + bs, ep := setup(t) + + tests := []struct { + name string + currentSafeOrigin uint64 + failsToFetchSyncStatus bool + expectResult uint64 + expectErr bool + }{ + { + name: "ExistingSafeL1Origin", + currentSafeOrigin: 999, + expectResult: 999, + }, + { + name: "NoExistingSafeL1OriginUsesGenesis", + currentSafeOrigin: 0, + expectResult: genesisL1Origin, + }, + { + name: "ErrorFetchingSyncStatus", + failsToFetchSyncStatus: true, + expectErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.failsToFetchSyncStatus { + ep.rollupClient.ExpectSyncStatus(ð.SyncStatus{}, errors.New("failed to fetch sync status")) + + } else { + ep.rollupClient.ExpectSyncStatus(ð.SyncStatus{ + SafeL2: eth.L2BlockRef{ + L1Origin: eth.BlockID{ + Number: tt.currentSafeOrigin, + }, + }, + }, nil) + } + + id, err := bs.safeL1Origin(context.Background()) + + if tt.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.expectResult, id.Number) + } + }) + } + +} + +func TestBatchSubmitter_SafeL1Origin_FailsToResolveRollupClient(t *testing.T) { + bs, ep := setup(t) + + ep.rollupClientErr = errors.New("failed to resolve rollup client") + + _, err := bs.safeL1Origin(context.Background()) + require.Error(t, err) +} diff --git a/op-batcher/batcher/service.go b/op-batcher/batcher/service.go index 1b6e849bb5f3..9da6f969d50f 100644 --- a/op-batcher/batcher/service.go +++ b/op-batcher/batcher/service.go @@ -5,32 +5,43 @@ import ( "errors" "fmt" "io" - "net" _ "net/http/pprof" - "strconv" + "strings" "sync/atomic" "time" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-batcher/flags" "github.com/ethereum-optimism/optimism/op-batcher/metrics" "github.com/ethereum-optimism/optimism/op-batcher/rpc" + "github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-node/rollup" + plasma "github.com/ethereum-optimism/optimism/op-plasma" "github.com/ethereum-optimism/optimism/op-service/cliapp" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/httputil" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" - "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) +var ErrAlreadyStopped = errors.New("already stopped") + type BatcherConfig struct { NetworkTimeout time.Duration PollInterval time.Duration MaxPendingTransactions uint64 + + // UseBlobs is true if the batcher should use blobs instead of calldata for posting blobs + UseBlobs bool + + // UsePlasma is true if the rollup config has a DA challenge address so the batcher + // will post inputs to the Plasma DA server and post commitments to blobs or calldata. + UsePlasma bool } // BatcherService represents a full batch-submitter instance and its resources, @@ -39,28 +50,28 @@ type BatcherService struct { Log log.Logger Metrics metrics.Metricer L1Client client.Client - L2Client client.Client - RollupNode *sources.RollupClient - TxManager txmgr.TxManager + + EndpointProvider dial.L2EndpointProvider + TxManager txmgr.TxManager + PlasmaDA *plasma.DAClient BatcherConfig RollupConfig *rollup.Config // Channel builder parameters - Channel ChannelConfig + ChannelConfig ChannelConfig driver *BatchSubmitter Version string - pprofSrv *httputil.HTTPServer - metricsSrv *httputil.HTTPServer - rpcServer *oprpc.Server + pprofService *oppprof.Service + metricsSrv *httputil.HTTPServer + rpcServer *oprpc.Server balanceMetricer io.Closer - - stopped atomic.Bool + stopped atomic.Bool NotSubmittingOnStart bool } @@ -86,11 +97,10 @@ func (bs *BatcherService) initFromCLIConfig(ctx context.Context, version string, bs.PollInterval = cfg.PollInterval bs.MaxPendingTransactions = cfg.MaxPendingTransactions bs.NetworkTimeout = cfg.TxMgrConfig.NetworkTimeout - if err := bs.initRPCClients(ctx, cfg); err != nil { return err } - if err := bs.initRollupCfg(ctx); err != nil { + if err := bs.initRollupConfig(ctx); err != nil { return fmt.Errorf("failed to load rollup config: %w", err) } if err := bs.initChannelConfig(cfg); err != nil { @@ -104,7 +114,11 @@ func (bs *BatcherService) initFromCLIConfig(ctx context.Context, version string, return fmt.Errorf("failed to start metrics server: %w", err) } if err := bs.initPProf(cfg); err != nil { - return fmt.Errorf("failed to start pprof server: %w", err) + return fmt.Errorf("failed to init profiling: %w", err) + } + // init before driver + if err := bs.initPlasmaDA(cfg); err != nil { + return fmt.Errorf("failed to init plasma DA: %w", err) } bs.initDriver() if err := bs.initRPCServer(cfg); err != nil { @@ -123,17 +137,19 @@ func (bs *BatcherService) initRPCClients(ctx context.Context, cfg *CLIConfig) er } bs.L1Client = client.NewInstrumentedClient(l1Client, bs.Metrics) - l2Client, err := dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, bs.Log, cfg.L2EthRpc) - if err != nil { - return fmt.Errorf("failed to dial L2 engine RPC: %w", err) + var endpointProvider dial.L2EndpointProvider + if strings.Contains(cfg.RollupRpc, ",") && strings.Contains(cfg.L2EthRpc, ",") { + rollupUrls := strings.Split(cfg.RollupRpc, ",") + ethUrls := strings.Split(cfg.L2EthRpc, ",") + endpointProvider, err = dial.NewActiveL2EndpointProvider(ctx, ethUrls, rollupUrls, cfg.ActiveSequencerCheckDuration, dial.DefaultDialTimeout, bs.Log) + } else { + endpointProvider, err = dial.NewStaticL2EndpointProvider(ctx, bs.Log, cfg.L2EthRpc, cfg.RollupRpc, bs.Metrics) } - bs.L2Client = client.NewInstrumentedClient(l2Client, bs.Metrics) - - rollupClient, err := dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, bs.Log, cfg.RollupRpc) if err != nil { - return fmt.Errorf("failed to dial L2 rollup-client RPC: %w", err) + return fmt.Errorf("failed to build L2 endpoint provider: %w", err) } - bs.RollupNode = rollupClient + bs.EndpointProvider = endpointProvider + return nil } @@ -153,31 +169,75 @@ func (bs *BatcherService) initBalanceMonitor(cfg *CLIConfig) { } } -func (bs *BatcherService) initRollupCfg(ctx context.Context) error { - rollupCfg, err := bs.RollupNode.RollupConfig(ctx) +func (bs *BatcherService) initRollupConfig(ctx context.Context) error { + rollupNode, err := bs.EndpointProvider.RollupClient(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve rollup client: %w", err) + } + rollupConfig, err := rollupNode.RollupConfig(ctx) if err != nil { return fmt.Errorf("failed to retrieve rollup config: %w", err) } - bs.RollupConfig = rollupCfg + bs.RollupConfig = rollupConfig if err := bs.RollupConfig.Check(); err != nil { return fmt.Errorf("invalid rollup config: %w", err) } + bs.RollupConfig.LogDescription(bs.Log, chaincfg.L2ChainIDToNetworkDisplayName) return nil } func (bs *BatcherService) initChannelConfig(cfg *CLIConfig) error { - bs.Channel = ChannelConfig{ + cc := ChannelConfig{ SeqWindowSize: bs.RollupConfig.SeqWindowSize, ChannelTimeout: bs.RollupConfig.ChannelTimeout, MaxChannelDuration: cfg.MaxChannelDuration, + MaxFrameSize: cfg.MaxL1TxSize - 1, // account for version byte prefix; reset for blobs + TargetNumFrames: cfg.TargetNumFrames, SubSafetyMargin: cfg.SubSafetyMargin, - MaxFrameSize: cfg.MaxL1TxSize - 1, // subtract 1 byte for version - CompressorConfig: cfg.CompressorConfig.Config(), BatchType: cfg.BatchType, } - if err := bs.Channel.Check(); err != nil { + + switch cfg.DataAvailabilityType { + case flags.BlobsType: + if !cfg.TestUseMaxTxSizeForBlobs { + // account for version byte prefix + cc.MaxFrameSize = eth.MaxBlobDataSize - 1 + } + cc.MultiFrameTxs = true + bs.UseBlobs = true + case flags.CalldataType: + bs.UseBlobs = false + default: + return fmt.Errorf("unknown data availability type: %v", cfg.DataAvailabilityType) + } + + if bs.UsePlasma && cc.MaxFrameSize > plasma.MaxInputSize { + return fmt.Errorf("max frame size %d exceeds plasma max input size %d", cc.MaxFrameSize, plasma.MaxInputSize) + } + + cc.InitCompressorConfig(cfg.ApproxComprRatio, cfg.Compressor) + + if bs.UseBlobs && !bs.RollupConfig.IsEcotone(uint64(time.Now().Unix())) { + bs.Log.Error("Cannot use Blob data before Ecotone!") // log only, the batcher may not be actively running. + } + if !bs.UseBlobs && bs.RollupConfig.IsEcotone(uint64(time.Now().Unix())) { + bs.Log.Warn("Ecotone upgrade is active, but batcher is not configured to use Blobs!") + } + + if err := cc.Check(); err != nil { return fmt.Errorf("invalid channel configuration: %w", err) } + bs.Log.Info("Initialized channel-config", + "use_blobs", bs.UseBlobs, + "use_plasma", bs.UsePlasma, + "max_frame_size", cc.MaxFrameSize, + "target_num_frames", cc.TargetNumFrames, + "compressor", cc.CompressorConfig.Kind, + "max_channel_duration", cc.MaxChannelDuration, + "channel_timeout", cc.ChannelTimeout, + "batch_type", cc.BatchType, + "sub_safety_margin", cc.SubSafetyMargin) + bs.ChannelConfig = cc return nil } @@ -191,16 +251,19 @@ func (bs *BatcherService) initTxManager(cfg *CLIConfig) error { } func (bs *BatcherService) initPProf(cfg *CLIConfig) error { - if !cfg.PprofConfig.Enabled { - return nil - } - log.Debug("starting pprof server", "addr", net.JoinHostPort(cfg.PprofConfig.ListenAddr, strconv.Itoa(cfg.PprofConfig.ListenPort))) - srv, err := oppprof.StartServer(cfg.PprofConfig.ListenAddr, cfg.PprofConfig.ListenPort) - if err != nil { - return err + bs.pprofService = oppprof.New( + cfg.PprofConfig.ListenEnabled, + cfg.PprofConfig.ListenAddr, + cfg.PprofConfig.ListenPort, + cfg.PprofConfig.ProfileType, + cfg.PprofConfig.ProfileDir, + cfg.PprofConfig.ProfileFilename, + ) + + if err := bs.pprofService.Start(); err != nil { + return fmt.Errorf("failed to start pprof service: %w", err) } - bs.pprofSrv = srv - log.Info("started pprof server", "addr", srv.Addr()) + return nil } @@ -225,15 +288,15 @@ func (bs *BatcherService) initMetricsServer(cfg *CLIConfig) error { func (bs *BatcherService) initDriver() { bs.driver = NewBatchSubmitter(DriverSetup{ - Log: bs.Log, - Metr: bs.Metrics, - RollupCfg: bs.RollupConfig, - Cfg: bs.BatcherConfig, - Txmgr: bs.TxManager, - L1Client: bs.L1Client, - L2Client: bs.L2Client, - RollupClient: bs.RollupNode, - Channel: bs.Channel, + Log: bs.Log, + Metr: bs.Metrics, + RollupConfig: bs.RollupConfig, + Config: bs.BatcherConfig, + Txmgr: bs.TxManager, + L1Client: bs.L1Client, + EndpointProvider: bs.EndpointProvider, + ChannelConfig: bs.ChannelConfig, + PlasmaDA: bs.PlasmaDA, }) } @@ -257,6 +320,16 @@ func (bs *BatcherService) initRPCServer(cfg *CLIConfig) error { return nil } +func (bs *BatcherService) initPlasmaDA(cfg *CLIConfig) error { + config := cfg.PlasmaDA + if err := config.Check(); err != nil { + return err + } + bs.PlasmaDA = config.NewDAClient() + bs.UsePlasma = config.Enabled + return nil +} + // Start runs once upon start of the batcher lifecycle, // and starts batch-submission work if the batcher is configured to start submit data on startup. func (bs *BatcherService) Start(_ context.Context) error { @@ -285,13 +358,21 @@ func (bs *BatcherService) Kill() error { // If the provided ctx is cancelled, the stopping is forced, i.e. the batching work is killed non-gracefully. func (bs *BatcherService) Stop(ctx context.Context) error { if bs.stopped.Load() { - return errors.New("already stopped") + return ErrAlreadyStopped } bs.Log.Info("Stopping batcher") + // close the TxManager first, so that new work is denied, in-flight work is cancelled as early as possible + // (transactions which are expected to be confirmed are still waited for) + if bs.TxManager != nil { + bs.TxManager.Close() + } + var result error - if err := bs.driver.StopBatchSubmittingIfRunning(ctx); err != nil { - result = errors.Join(result, fmt.Errorf("failed to stop batch submitting: %w", err)) + if bs.driver != nil { + if err := bs.driver.StopBatchSubmittingIfRunning(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to stop batch submitting: %w", err)) + } } if bs.rpcServer != nil { @@ -300,8 +381,8 @@ func (bs *BatcherService) Stop(ctx context.Context) error { result = errors.Join(result, fmt.Errorf("failed to stop RPC server: %w", err)) } } - if bs.pprofSrv != nil { - if err := bs.pprofSrv.Stop(ctx); err != nil { + if bs.pprofService != nil { + if err := bs.pprofService.Stop(ctx); err != nil { result = errors.Join(result, fmt.Errorf("failed to stop PProf server: %w", err)) } } @@ -310,6 +391,7 @@ func (bs *BatcherService) Stop(ctx context.Context) error { result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err)) } } + if bs.metricsSrv != nil { if err := bs.metricsSrv.Stop(ctx); err != nil { result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err)) @@ -319,16 +401,13 @@ func (bs *BatcherService) Stop(ctx context.Context) error { if bs.L1Client != nil { bs.L1Client.Close() } - if bs.L2Client != nil { - bs.L2Client.Close() - } - if bs.RollupNode != nil { - bs.RollupNode.Close() + if bs.EndpointProvider != nil { + bs.EndpointProvider.Close() } if result == nil { bs.stopped.Store(true) - bs.driver.Log.Info("Batch Submitter stopped") + bs.Log.Info("Batch Submitter stopped") } return result } diff --git a/op-batcher/batcher/tx_data.go b/op-batcher/batcher/tx_data.go index d32d44be2c53..73e1adbbe179 100644 --- a/op-batcher/batcher/tx_data.go +++ b/op-batcher/batcher/tx_data.go @@ -2,8 +2,10 @@ package batcher import ( "fmt" + "strings" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/eth" ) // txData represents the data for a single transaction. @@ -12,47 +14,89 @@ import ( // might change in the future to allow for multiple frames from possibly // different channels. type txData struct { - frame frameData + frames []frameData } -// ID returns the id for this transaction data. It can be used as a map key. +func singleFrameTxData(frame frameData) txData { + return txData{frames: []frameData{frame}} +} + +// ID returns the id for this transaction data. Its String() can be used as a map key. func (td *txData) ID() txID { - return td.frame.id + id := make(txID, 0, len(td.frames)) + for _, f := range td.frames { + id = append(id, f.id) + } + return id +} + +// CallData returns the transaction data as calldata. +// It's a version byte (0) followed by the concatenated frames for this transaction. +func (td *txData) CallData() []byte { + data := make([]byte, 1, 1+td.Len()) + data[0] = derive.DerivationVersion0 + for _, f := range td.frames { + data = append(data, f.data...) + } + return data } -// Bytes returns the transaction data. It's a version byte (0) followed by the -// concatenated frames for this transaction. -func (td *txData) Bytes() []byte { - return append([]byte{derive.DerivationVersion0}, td.frame.data...) +func (td *txData) Blobs() ([]*eth.Blob, error) { + blobs := make([]*eth.Blob, 0, len(td.frames)) + for _, f := range td.frames { + var blob eth.Blob + if err := blob.FromData(append([]byte{derive.DerivationVersion0}, f.data...)); err != nil { + return nil, err + } + blobs = append(blobs, &blob) + } + return blobs, nil } -func (td *txData) Len() int { - return 1 + len(td.frame.data) +// Len returns the sum of all the sizes of data in all frames. +// Len only counts the data itself and doesn't account for the version byte(s). +func (td *txData) Len() (l int) { + for _, f := range td.frames { + l += len(f.data) + } + return l } // Frame returns the single frame of this tx data. -// -// Note: when the batcher is changed to possibly send multiple frames per tx, -// this should be changed to a func Frames() []frameData. -func (td *txData) Frame() frameData { - return td.frame +func (td *txData) Frames() []frameData { + return td.frames } // txID is an opaque identifier for a transaction. -// It's internal fields should not be inspected after creation & are subject to change. -// This ID must be trivially comparable & work as a map key. -// -// Note: transactions currently only hold a single frame, so it can be -// identified by the frame. This needs to be changed once the batcher is changed -// to send multiple frames per tx. -type txID = frameID +// Its internal fields should not be inspected after creation & are subject to change. +// Its String() can be used for comparisons and works as a map key. +type txID []frameID func (id txID) String() string { - return fmt.Sprintf("%s:%d", id.chID.String(), id.frameNumber) + return id.string(func(id derive.ChannelID) string { return id.String() }) } // TerminalString implements log.TerminalStringer, formatting a string for console // output during logging. func (id txID) TerminalString() string { - return fmt.Sprintf("%s:%d", id.chID.TerminalString(), id.frameNumber) + return id.string(func(id derive.ChannelID) string { return id.TerminalString() }) +} + +func (id txID) string(chIDStringer func(id derive.ChannelID) string) string { + var ( + sb strings.Builder + curChID derive.ChannelID + ) + for _, f := range id { + if f.chID == curChID { + sb.WriteString(fmt.Sprintf("+%d", f.frameNumber)) + } else { + if curChID != (derive.ChannelID{}) { + sb.WriteString("|") + } + curChID = f.chID + sb.WriteString(fmt.Sprintf("%s:%d", chIDStringer(f.chID), f.frameNumber)) + } + } + return sb.String() } diff --git a/op-batcher/batcher/tx_data_test.go b/op-batcher/batcher/tx_data_test.go new file mode 100644 index 000000000000..317aafc375f6 --- /dev/null +++ b/op-batcher/batcher/tx_data_test.go @@ -0,0 +1,60 @@ +package batcher + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestTxID_String(t *testing.T) { + for _, test := range []struct { + desc string + id txID + expStr string + }{ + { + desc: "empty", + id: []frameID{}, + expStr: "", + }, + { + desc: "nil", + id: nil, + expStr: "", + }, + { + desc: "single", + id: []frameID{{ + chID: [16]byte{0: 0xca, 15: 0xaf}, + frameNumber: 42, + }}, + expStr: "ca0000000000000000000000000000af:42", + }, + { + desc: "multi", + id: []frameID{ + { + chID: [16]byte{0: 0xca, 15: 0xaf}, + frameNumber: 42, + }, + { + chID: [16]byte{0: 0xca, 15: 0xaf}, + frameNumber: 33, + }, + { + chID: [16]byte{0: 0xbe, 15: 0xef}, + frameNumber: 0, + }, + { + chID: [16]byte{0: 0xbe, 15: 0xef}, + frameNumber: 128, + }, + }, + expStr: "ca0000000000000000000000000000af:42+33|be0000000000000000000000000000ef:0+128", + }, + } { + t.Run(test.desc, func(t *testing.T) { + require.Equal(t, test.expStr, test.id.String()) + }) + } +} diff --git a/op-batcher/cmd/main.go b/op-batcher/cmd/main.go index cc64b6eeb459..91e032ff36b4 100644 --- a/op-batcher/cmd/main.go +++ b/op-batcher/cmd/main.go @@ -1,17 +1,19 @@ package main import ( + "context" "os" - opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/op-batcher/batcher" "github.com/ethereum-optimism/optimism/op-batcher/flags" "github.com/ethereum-optimism/optimism/op-batcher/metrics" + opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/metrics/doc" + "github.com/ethereum-optimism/optimism/op-service/opio" "github.com/ethereum/go-ethereum/log" ) @@ -38,7 +40,8 @@ func main() { }, } - err := app.Run(os.Args) + ctx := opio.WithInterruptBlocker(context.Background()) + err := app.RunContext(ctx, os.Args) if err != nil { log.Crit("Application failed", "message", err) } diff --git a/op-batcher/compressor/cli.go b/op-batcher/compressor/cli.go deleted file mode 100644 index 5da3cd164310..000000000000 --- a/op-batcher/compressor/cli.go +++ /dev/null @@ -1,78 +0,0 @@ -package compressor - -import ( - "strings" - - opservice "github.com/ethereum-optimism/optimism/op-service" - "github.com/urfave/cli/v2" -) - -const ( - TargetL1TxSizeBytesFlagName = "target-l1-tx-size-bytes" - TargetNumFramesFlagName = "target-num-frames" - ApproxComprRatioFlagName = "approx-compr-ratio" - KindFlagName = "compressor" -) - -func CLIFlags(envPrefix string) []cli.Flag { - return []cli.Flag{ - &cli.Uint64Flag{ - Name: TargetL1TxSizeBytesFlagName, - Usage: "The target size of a batch tx submitted to L1.", - Value: 100_000, - EnvVars: opservice.PrefixEnvVar(envPrefix, "TARGET_L1_TX_SIZE_BYTES"), - }, - &cli.IntFlag{ - Name: TargetNumFramesFlagName, - Usage: "The target number of frames to create per channel", - Value: 1, - EnvVars: opservice.PrefixEnvVar(envPrefix, "TARGET_NUM_FRAMES"), - }, - &cli.Float64Flag{ - Name: ApproxComprRatioFlagName, - Usage: "The approximate compression ratio (<= 1.0)", - Value: 0.4, - EnvVars: opservice.PrefixEnvVar(envPrefix, "APPROX_COMPR_RATIO"), - }, - &cli.StringFlag{ - Name: KindFlagName, - Usage: "The type of compressor. Valid options: " + strings.Join(KindKeys, ", "), - EnvVars: opservice.PrefixEnvVar(envPrefix, "COMPRESSOR"), - Value: RatioKind, - }, - } -} - -type CLIConfig struct { - // TargetL1TxSizeBytes to target when creating channel frames. Note that if the - // realized compression ratio is worse than the approximate, more frames may - // actually be created. This also depends on how close the target is to the - // max frame size. - TargetL1TxSizeBytes uint64 - // TargetNumFrames to create in this channel. If the realized compression ratio - // is worse than approxComprRatio, additional leftover frame(s) might get created. - TargetNumFrames int - // ApproxComprRatio to assume. Should be slightly smaller than average from - // experiments to avoid the chances of creating a small additional leftover frame. - ApproxComprRatio float64 - // Type of compressor to use. Must be one of KindKeys. - Kind string -} - -func (c *CLIConfig) Config() Config { - return Config{ - TargetFrameSize: c.TargetL1TxSizeBytes - 1, // subtract 1 byte for version - TargetNumFrames: c.TargetNumFrames, - ApproxComprRatio: c.ApproxComprRatio, - Kind: c.Kind, - } -} - -func ReadCLIConfig(ctx *cli.Context) CLIConfig { - return CLIConfig{ - Kind: ctx.String(KindFlagName), - TargetL1TxSizeBytes: ctx.Uint64(TargetL1TxSizeBytesFlagName), - TargetNumFrames: ctx.Int(TargetNumFramesFlagName), - ApproxComprRatio: ctx.Float64(ApproxComprRatioFlagName), - } -} diff --git a/op-batcher/compressor/compressors.go b/op-batcher/compressor/compressors.go index 2b873460ca8c..1a6d64da13e6 100644 --- a/op-batcher/compressor/compressors.go +++ b/op-batcher/compressor/compressors.go @@ -6,12 +6,20 @@ import ( type FactoryFunc func(Config) (derive.Compressor, error) -const RatioKind = "ratio" -const ShadowKind = "shadow" +const ( + RatioKind = "ratio" + ShadowKind = "shadow" + NoneKind = "none" + + // CloseOverheadZlib is the number of final bytes a [zlib.Writer] call writes + // to the output buffer. + CloseOverheadZlib = 9 +) var Kinds = map[string]FactoryFunc{ RatioKind: NewRatioCompressor, ShadowKind: NewShadowCompressor, + NoneKind: NewNonCompressor, } var KindKeys []string diff --git a/op-batcher/compressor/compressors_test.go b/op-batcher/compressor/compressors_test.go new file mode 100644 index 000000000000..ed6d852d0411 --- /dev/null +++ b/op-batcher/compressor/compressors_test.go @@ -0,0 +1,25 @@ +package compressor + +import ( + "bytes" + "compress/zlib" + "io" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCloseOverheadZlib(t *testing.T) { + var buf bytes.Buffer + z := zlib.NewWriter(&buf) + rng := rand.New(rand.NewSource(420)) + _, err := io.CopyN(z, rng, 0xff) + require.NoError(t, err) + + require.NoError(t, z.Flush()) + fsize := buf.Len() + require.NoError(t, z.Close()) + csize := buf.Len() + require.Equal(t, CloseOverheadZlib, csize-fsize) +} diff --git a/op-batcher/compressor/config.go b/op-batcher/compressor/config.go index 1ab42347d007..8befc43812ae 100644 --- a/op-batcher/compressor/config.go +++ b/op-batcher/compressor/config.go @@ -5,16 +5,13 @@ import ( ) type Config struct { - // TargetFrameSize to target when creating channel frames. Note that if the - // realized compression ratio is worse than the approximate, more frames may - // actually be created. This also depends on how close the target is to the - // max frame size. - TargetFrameSize uint64 - // TargetNumFrames to create in this channel. If the realized compression ratio - // is worse than approxComprRatio, additional leftover frame(s) might get created. - TargetNumFrames int - // ApproxComprRatio to assume. Should be slightly smaller than average from - // experiments to avoid the chances of creating a small additional leftover frame. + // TargetOutputSize is the target size that the compressed data should reach. + // The shadow compressor guarantees that the compressed data stays below + // this bound. The ratio compressor might go over. + TargetOutputSize uint64 + // ApproxComprRatio to assume (only ratio compressor). Should be slightly smaller + // than average from experiments to avoid the chances of creating a small + // additional leftover frame. ApproxComprRatio float64 // Kind of compressor to use. Must be one of KindKeys. If unset, NewCompressor // will default to RatioKind. diff --git a/op-batcher/compressor/non_compressor.go b/op-batcher/compressor/non_compressor.go new file mode 100644 index 000000000000..ee9d4d618cab --- /dev/null +++ b/op-batcher/compressor/non_compressor.go @@ -0,0 +1,77 @@ +package compressor + +import ( + "bytes" + "compress/zlib" + + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" +) + +type NonCompressor struct { + config Config + + buf bytes.Buffer + compress *zlib.Writer + + fullErr error +} + +// NewNonCompressor creates a new derive.Compressor implementation that doesn't +// compress by using zlib.NoCompression. +// It flushes to the underlying buffer any data from a prior write call. +// This is very unoptimal behavior and should only be used in tests. +// The NonCompressor can be used in tests to create a partially flushed channel. +// If the output buffer size after a write exceeds TargetFrameSize*TargetNumFrames, +// the compressor is marked as full, but the write succeeds. +func NewNonCompressor(config Config) (derive.Compressor, error) { + c := &NonCompressor{ + config: config, + } + + var err error + c.compress, err = zlib.NewWriterLevel(&c.buf, zlib.NoCompression) + if err != nil { + return nil, err + } + return c, nil +} + +func (t *NonCompressor) Write(p []byte) (int, error) { + if err := t.compress.Flush(); err != nil { + return 0, err + } + n, err := t.compress.Write(p) + if err != nil { + return 0, err + } + if uint64(t.buf.Len()) > t.config.TargetOutputSize { + t.fullErr = derive.CompressorFullErr + } + return n, nil +} + +func (t *NonCompressor) Close() error { + return t.compress.Close() +} + +func (t *NonCompressor) Read(p []byte) (int, error) { + return t.buf.Read(p) +} + +func (t *NonCompressor) Reset() { + t.buf.Reset() + t.compress.Reset(&t.buf) + t.fullErr = nil +} + +func (t *NonCompressor) Len() int { + return t.buf.Len() +} + +func (t *NonCompressor) Flush() error { + return t.compress.Flush() +} + +func (t *NonCompressor) FullErr() error { + return t.fullErr +} diff --git a/op-batcher/compressor/non_compressor_test.go b/op-batcher/compressor/non_compressor_test.go new file mode 100644 index 000000000000..972582469a99 --- /dev/null +++ b/op-batcher/compressor/non_compressor_test.go @@ -0,0 +1,38 @@ +package compressor + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNonCompressor(t *testing.T) { + require := require.New(t) + c, err := NewNonCompressor(Config{ + TargetOutputSize: 100000, + }) + require.NoError(err) + + const dlen = 100 + data := make([]byte, dlen) + rng := rand.New(rand.NewSource(42)) + rng.Read(data) + + n, err := c.Write(data) + require.NoError(err) + require.Equal(n, dlen) + l0 := c.Len() + require.Less(l0, dlen) + require.Equal(7, l0) + c.Flush() + l1 := c.Len() + require.Greater(l1, l0) + require.Greater(l1, dlen) + + n, err = c.Write(data) + require.NoError(err) + require.Equal(n, dlen) + l2 := c.Len() + require.Equal(l1+5, l2) +} diff --git a/op-batcher/compressor/ratio_compressor.go b/op-batcher/compressor/ratio_compressor.go index 6e726ae8a53e..5c4de94edf55 100644 --- a/op-batcher/compressor/ratio_compressor.go +++ b/op-batcher/compressor/ratio_compressor.go @@ -74,7 +74,7 @@ func (t *RatioCompressor) FullErr() error { // InputThreshold calculates the input data threshold in bytes from the given // parameters. func (t *RatioCompressor) InputThreshold() uint64 { - return uint64(float64(t.config.TargetNumFrames) * float64(t.config.TargetFrameSize) / t.config.ApproxComprRatio) + return uint64(float64(t.config.TargetOutputSize) / t.config.ApproxComprRatio) } // inputTargetReached says whether the target amount of input data has been diff --git a/op-batcher/compressor/ratio_compressor_test.go b/op-batcher/compressor/ratio_compressor_test.go index c380c4041f8d..27e377a234d6 100644 --- a/op-batcher/compressor/ratio_compressor_test.go +++ b/op-batcher/compressor/ratio_compressor_test.go @@ -1,6 +1,7 @@ package compressor_test import ( + "fmt" "math" "testing" @@ -8,107 +9,46 @@ import ( "github.com/stretchr/testify/require" ) -// TestInputThreshold tests the [ChannelConfig.InputThreshold] -// function using a table-driven testing approach. -func TestInputThreshold(t *testing.T) { - type testInput struct { - TargetFrameSize uint64 - TargetNumFrames int - ApproxComprRatio float64 - } - type test struct { - input testInput - assertion func(uint64) - } - - // Construct test cases that test the boundary conditions - tests := []test{ - { - input: testInput{ - TargetFrameSize: 1, - TargetNumFrames: 1, - ApproxComprRatio: 0.4, - }, - assertion: func(output uint64) { - require.Equal(t, uint64(2), output) - }, - }, +func TestChannelConfig_InputThreshold(t *testing.T) { + tests := []struct { + targetOutputSize uint64 + approxComprRatio float64 + expInputThreshold uint64 + assertion func(uint64) // optional, for more complex assertion + }{ { - input: testInput{ - TargetFrameSize: 1, - TargetNumFrames: 100000, - ApproxComprRatio: 0.4, - }, - assertion: func(output uint64) { - require.Equal(t, uint64(250_000), output) - }, - }, - { - input: testInput{ - TargetFrameSize: 1, - TargetNumFrames: 1, - ApproxComprRatio: 1, - }, - assertion: func(output uint64) { - require.Equal(t, uint64(1), output) - }, + targetOutputSize: 1, + approxComprRatio: 0.4, + expInputThreshold: 2, }, { - input: testInput{ - TargetFrameSize: 1, - TargetNumFrames: 1, - ApproxComprRatio: 2, - }, - assertion: func(output uint64) { - require.Equal(t, uint64(0), output) - }, + targetOutputSize: 1, + approxComprRatio: 1, + expInputThreshold: 1, }, { - input: testInput{ - TargetFrameSize: 100000, - TargetNumFrames: 1, - ApproxComprRatio: 0.4, - }, - assertion: func(output uint64) { - require.Equal(t, uint64(250_000), output) - }, + targetOutputSize: 100_000, + approxComprRatio: 0.4, + expInputThreshold: 250_000, }, { - input: testInput{ - TargetFrameSize: 1, - TargetNumFrames: 100000, - ApproxComprRatio: 0.4, - }, - assertion: func(output uint64) { - require.Equal(t, uint64(250_000), output) - }, + targetOutputSize: 1, + approxComprRatio: 0.4, + expInputThreshold: 2, }, { - input: testInput{ - TargetFrameSize: 100000, - TargetNumFrames: 100000, - ApproxComprRatio: 0.4, - }, - assertion: func(output uint64) { - require.Equal(t, uint64(25_000_000_000), output) - }, + targetOutputSize: 100_000, + approxComprRatio: 0.4, + expInputThreshold: 250_000, }, { - input: testInput{ - TargetFrameSize: 1, - TargetNumFrames: 1, - ApproxComprRatio: 0.000001, - }, - assertion: func(output uint64) { - require.Equal(t, uint64(1_000_000), output) - }, + targetOutputSize: 1, + approxComprRatio: 0.000001, + expInputThreshold: 1_000_000, }, { - input: testInput{ - TargetFrameSize: 0, - TargetNumFrames: 0, - ApproxComprRatio: 0, - }, + targetOutputSize: 0, + approxComprRatio: 0, assertion: func(output uint64) { // Need to allow for NaN depending on the machine architecture require.True(t, output == uint64(0) || output == uint64(math.NaN())) @@ -117,14 +57,19 @@ func TestInputThreshold(t *testing.T) { } // Validate each test case - for _, tt := range tests { - comp, err := compressor.NewRatioCompressor(compressor.Config{ - TargetFrameSize: tt.input.TargetFrameSize, - TargetNumFrames: tt.input.TargetNumFrames, - ApproxComprRatio: tt.input.ApproxComprRatio, + for i, tt := range tests { + t.Run(fmt.Sprintf("test-%d", i), func(t *testing.T) { + comp, err := compressor.NewRatioCompressor(compressor.Config{ + TargetOutputSize: tt.targetOutputSize, + ApproxComprRatio: tt.approxComprRatio, + }) + require.NoError(t, err) + got := comp.(*compressor.RatioCompressor).InputThreshold() + if tt.assertion != nil { + tt.assertion(got) + } else { + require.Equal(t, tt.expInputThreshold, got) + } }) - require.NoError(t, err) - got := comp.(*compressor.RatioCompressor).InputThreshold() - tt.assertion(got) } } diff --git a/op-batcher/compressor/shadow_compressor.go b/op-batcher/compressor/shadow_compressor.go index 567928e79533..9fadb914de25 100644 --- a/op-batcher/compressor/shadow_compressor.go +++ b/op-batcher/compressor/shadow_compressor.go @@ -7,6 +7,17 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup/derive" ) +const ( + // safeCompressionOverhead is the largest potential blow-up in bytes we expect to see when + // compressing arbitrary (e.g. random) data. Here we account for a 2 byte header, 4 byte + // digest, 5 byte EOF indicator, and then 5 byte flate block header for each 16k of potential + // data. Assuming frames are max 128k size (the current max blob size) this is 2+4+5+(5*8) = 51 + // bytes. If we start using larger frames (e.g. should max blob size increase) a larger blowup + // might be possible, but it would be highly unlikely, and the system still works if our + // estimate is wrong -- we just end up writing one more tx for the overflow. + safeCompressionOverhead = 51 +) + type ShadowCompressor struct { config Config @@ -17,6 +28,8 @@ type ShadowCompressor struct { shadowCompress *zlib.Writer fullErr error + + bound uint64 // best known upperbound on the size of the compressed output } // NewShadowCompressor creates a new derive.Compressor implementation that contains two @@ -41,26 +54,37 @@ func NewShadowCompressor(config Config) (derive.Compressor, error) { return nil, err } + c.bound = safeCompressionOverhead return c, nil } func (t *ShadowCompressor) Write(p []byte) (int, error) { - _, err := t.shadowCompress.Write(p) - if err != nil { - return 0, err + if t.fullErr != nil { + return 0, t.fullErr } - err = t.shadowCompress.Flush() + _, err := t.shadowCompress.Write(p) if err != nil { return 0, err } - if uint64(t.shadowBuf.Len()) > t.config.TargetFrameSize*uint64(t.config.TargetNumFrames) { - t.fullErr = derive.CompressorFullErr - if t.Len() > 0 { - // only return an error if we've already written data to this compressor before - // (otherwise individual blocks over the target would never be written) - return 0, t.fullErr + newBound := t.bound + uint64(len(p)) + if newBound > t.config.TargetOutputSize { + // Do not flush the buffer unless there's some chance we will be over the size limit. + // This reduces CPU but more importantly it makes the shadow compression ratio more + // closely reflect the ultimate compression ratio. + if err = t.shadowCompress.Flush(); err != nil { + return 0, err + } + newBound = uint64(t.shadowBuf.Len()) + CloseOverheadZlib + if newBound > t.config.TargetOutputSize { + t.fullErr = derive.CompressorFullErr + if t.Len() > 0 { + // only return an error if we've already written data to this compressor before + // (otherwise single blocks over the target would never be written) + return 0, t.fullErr + } } } + t.bound = newBound return t.compress.Write(p) } @@ -78,6 +102,7 @@ func (t *ShadowCompressor) Reset() { t.shadowBuf.Reset() t.shadowCompress.Reset(&t.shadowBuf) t.fullErr = nil + t.bound = safeCompressionOverhead } func (t *ShadowCompressor) Len() int { diff --git a/op-batcher/compressor/shadow_compressor_test.go b/op-batcher/compressor/shadow_compressor_test.go index e756522caa0c..eb0efea0f13c 100644 --- a/op-batcher/compressor/shadow_compressor_test.go +++ b/op-batcher/compressor/shadow_compressor_test.go @@ -1,62 +1,59 @@ -package compressor_test +package compressor import ( "bytes" "compress/zlib" - "crypto/rand" "io" + "math/rand" "testing" - "github.com/ethereum-optimism/optimism/op-batcher/compressor" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/stretchr/testify/require" ) -func randomBytes(t *testing.T, length int) []byte { +var r = rand.New(rand.NewSource(99)) + +func randomBytes(length int) []byte { b := make([]byte, length) - _, err := rand.Read(b) - require.NoError(t, err) + _, err := r.Read(b) + // Rand.Read always returns nil error + if err != nil { + panic(err) + } return b } func TestShadowCompressor(t *testing.T) { - type test struct { - name string - targetFrameSize uint64 - targetNumFrames int - data [][]byte - errs []error - fullErr error - } - - tests := []test{{ - name: "no data", - targetFrameSize: 1, - targetNumFrames: 1, - data: [][]byte{}, - errs: []error{}, - fullErr: nil, + tests := []struct { + name string + targetOutputSize uint64 + data [][]byte + errs []error + fullErr error + }{{ + name: "no data", + targetOutputSize: 1 + derive.FrameV0OverHeadSize, + data: [][]byte{}, + errs: []error{}, + fullErr: nil, }, { - name: "large first block", - targetFrameSize: 1, - targetNumFrames: 1, - data: [][]byte{bytes.Repeat([]byte{0}, 1024)}, - errs: []error{nil}, - fullErr: derive.CompressorFullErr, + name: "large first block", + targetOutputSize: 1 + derive.FrameV0OverHeadSize, + data: [][]byte{bytes.Repeat([]byte{0}, 1024)}, + errs: []error{nil}, + fullErr: derive.CompressorFullErr, }, { - name: "large second block", - targetFrameSize: 1, - targetNumFrames: 1, - data: [][]byte{bytes.Repeat([]byte{0}, 512), bytes.Repeat([]byte{0}, 1024)}, - errs: []error{nil, derive.CompressorFullErr}, - fullErr: derive.CompressorFullErr, + name: "large second block", + targetOutputSize: 1 + derive.FrameV0OverHeadSize, + data: [][]byte{bytes.Repeat([]byte{0}, 512), bytes.Repeat([]byte{0}, 1024)}, + errs: []error{nil, derive.CompressorFullErr}, + fullErr: derive.CompressorFullErr, }, { - name: "random data", - targetFrameSize: 1200, - targetNumFrames: 1, - data: [][]byte{randomBytes(t, 512), randomBytes(t, 512), randomBytes(t, 512)}, - errs: []error{nil, nil, derive.CompressorFullErr}, - fullErr: derive.CompressorFullErr, + name: "random data", + targetOutputSize: 1 << 17, + data: [][]byte{randomBytes((1 << 17) - 1000), randomBytes(512), randomBytes(512)}, + errs: []error{nil, nil, derive.CompressorFullErr}, + fullErr: derive.CompressorFullErr, }} for _, test := range tests { test := test @@ -64,9 +61,8 @@ func TestShadowCompressor(t *testing.T) { t.Parallel() require.Equal(t, len(test.errs), len(test.data), "invalid test case: len(data) != len(errs)") - sc, err := compressor.NewShadowCompressor(compressor.Config{ - TargetFrameSize: test.targetFrameSize, - TargetNumFrames: test.targetNumFrames, + sc, err := NewShadowCompressor(Config{ + TargetOutputSize: test.targetOutputSize, }) require.NoError(t, err) @@ -88,6 +84,7 @@ func TestShadowCompressor(t *testing.T) { err = sc.Close() require.NoError(t, err) + require.LessOrEqual(t, uint64(sc.Len()), sc.(*ShadowCompressor).bound) buf, err := io.ReadAll(sc) require.NoError(t, err) @@ -110,3 +107,27 @@ func TestShadowCompressor(t *testing.T) { }) } } + +// TestBoundInaccruateForLargeRandomData documents where our bounding heuristic starts to fail +// (writing at least 128k of random data) +func TestBoundInaccurateForLargeRandomData(t *testing.T) { + const sizeLimit = 1 << 17 + + sc, err := NewShadowCompressor(Config{ + TargetOutputSize: sizeLimit + 100, + }) + require.NoError(t, err) + + _, err = sc.Write(randomBytes(sizeLimit + 1)) + require.NoError(t, err) + err = sc.Close() + require.NoError(t, err) + require.Greater(t, uint64(sc.Len()), sc.(*ShadowCompressor).bound) + + sc.Reset() + _, err = sc.Write(randomBytes(sizeLimit)) + require.NoError(t, err) + err = sc.Close() + require.NoError(t, err) + require.LessOrEqual(t, uint64(sc.Len()), sc.(*ShadowCompressor).bound) +} diff --git a/op-batcher/flags/flags.go b/op-batcher/flags/flags.go index 7370c4b0c2b6..46b00f99c653 100644 --- a/op-batcher/flags/flags.go +++ b/op-batcher/flags/flags.go @@ -2,15 +2,19 @@ package flags import ( "fmt" + "strings" "time" "github.com/urfave/cli/v2" + "golang.org/x/exp/slices" "github.com/ethereum-optimism/optimism/op-batcher/compressor" + plasma "github.com/ethereum-optimism/optimism/op-plasma" opservice "github.com/ethereum-optimism/optimism/op-service" + openum "github.com/ethereum-optimism/optimism/op-service/enum" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) @@ -30,12 +34,12 @@ var ( } L2EthRpcFlag = &cli.StringFlag{ Name: "l2-eth-rpc", - Usage: "HTTP provider URL for L2 execution engine", + Usage: "HTTP provider URL for L2 execution engine. A comma-separated list enables the active L2 endpoint provider. Such a list needs to match the number of rollup-rpcs provided.", EnvVars: prefixEnvVars("L2_ETH_RPC"), } RollupRpcFlag = &cli.StringFlag{ Name: "rollup-rpc", - Usage: "HTTP provider URL for Rollup node", + Usage: "HTTP provider URL for Rollup node. A comma-separated list enables the active L2 endpoint provider. Such a list needs to match the number of l2-eth-rpcs provided.", EnvVars: prefixEnvVars("ROLLUP_RPC"), } // Optional flags @@ -67,20 +71,61 @@ var ( } MaxL1TxSizeBytesFlag = &cli.Uint64Flag{ Name: "max-l1-tx-size-bytes", - Usage: "The maximum size of a batch tx submitted to L1.", - Value: 120_000, + Usage: "The maximum size of a batch tx submitted to L1. Ignored for blobs, where max blob size will be used.", + Value: 120_000, // will be overwritten to max for blob da-type EnvVars: prefixEnvVars("MAX_L1_TX_SIZE_BYTES"), } + TargetNumFramesFlag = &cli.IntFlag{ + Name: "target-num-frames", + Usage: "The target number of frames to create per channel. Controls number of blobs per blob tx, if using Blob DA.", + Value: 1, + EnvVars: prefixEnvVars("TARGET_NUM_FRAMES"), + } + ApproxComprRatioFlag = &cli.Float64Flag{ + Name: "approx-compr-ratio", + Usage: "The approximate compression ratio (<= 1.0). Only relevant for ratio compressor.", + Value: 0.6, + EnvVars: prefixEnvVars("APPROX_COMPR_RATIO"), + } + CompressorFlag = &cli.StringFlag{ + Name: "compressor", + Usage: "The type of compressor. Valid options: " + strings.Join(compressor.KindKeys, ", "), + EnvVars: prefixEnvVars("COMPRESSOR"), + Value: compressor.ShadowKind, + Action: func(_ *cli.Context, s string) error { + if !slices.Contains(compressor.KindKeys, s) { + return fmt.Errorf("unsupported compressor: %s", s) + } + return nil + }, + } StoppedFlag = &cli.BoolFlag{ Name: "stopped", Usage: "Initialize the batcher in a stopped state. The batcher can be started using the admin_startBatcher RPC", EnvVars: prefixEnvVars("STOPPED"), } BatchTypeFlag = &cli.UintFlag{ - Name: "batch-type", - Usage: "The batch type. 0 for SingularBatch and 1 for SpanBatch.", - Value: 0, - EnvVars: prefixEnvVars("BATCH_TYPE"), + Name: "batch-type", + Usage: "The batch type. 0 for SingularBatch and 1 for SpanBatch.", + Value: 0, + EnvVars: prefixEnvVars("BATCH_TYPE"), + DefaultText: "singular", + } + DataAvailabilityTypeFlag = &cli.GenericFlag{ + Name: "data-availability-type", + Usage: "The data availability type to use for submitting batches to the L1. Valid options: " + + openum.EnumString(DataAvailabilityTypes), + Value: func() *DataAvailabilityType { + out := CalldataType + return &out + }(), + EnvVars: prefixEnvVars("DATA_AVAILABILITY_TYPE"), + } + ActiveSequencerCheckDurationFlag = &cli.DurationFlag{ + Name: "active-sequencer-check-duration", + Usage: "The duration between checks to determine the active sequencer endpoint. ", + Value: 2 * time.Minute, + EnvVars: prefixEnvVars("ACTIVE_SEQUENCER_CHECK_DURATION"), } // Legacy Flags SequencerHDPathFlag = txmgr.SequencerHDPathFlag @@ -98,9 +143,14 @@ var optionalFlags = []cli.Flag{ MaxPendingTransactionsFlag, MaxChannelDurationFlag, MaxL1TxSizeBytesFlag, + TargetNumFramesFlag, + ApproxComprRatioFlag, + CompressorFlag, StoppedFlag, SequencerHDPathFlag, BatchTypeFlag, + DataAvailabilityTypeFlag, + ActiveSequencerCheckDurationFlag, } func init() { @@ -109,7 +159,7 @@ func init() { optionalFlags = append(optionalFlags, opmetrics.CLIFlags(EnvVarPrefix)...) optionalFlags = append(optionalFlags, oppprof.CLIFlags(EnvVarPrefix)...) optionalFlags = append(optionalFlags, txmgr.CLIFlags(EnvVarPrefix)...) - optionalFlags = append(optionalFlags, compressor.CLIFlags(EnvVarPrefix)...) + optionalFlags = append(optionalFlags, plasma.CLIFlags(EnvVarPrefix, "")...) Flags = append(requiredFlags, optionalFlags...) } diff --git a/op-batcher/flags/flags_test.go b/op-batcher/flags/flags_test.go new file mode 100644 index 000000000000..af303724e25d --- /dev/null +++ b/op-batcher/flags/flags_test.go @@ -0,0 +1,100 @@ +package flags + +import ( + "slices" + "strings" + "testing" + + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + + "github.com/stretchr/testify/require" + "github.com/urfave/cli/v2" +) + +// TestOptionalFlagsDontSetRequired asserts that all flags deemed optional set +// the Required field to false. +func TestOptionalFlagsDontSetRequired(t *testing.T) { + for _, flag := range optionalFlags { + reqFlag, ok := flag.(cli.RequiredFlag) + require.True(t, ok) + require.False(t, reqFlag.IsRequired()) + } +} + +// TestUniqueFlags asserts that all flag names are unique, to avoid accidental conflicts between the many flags. +func TestUniqueFlags(t *testing.T) { + seenCLI := make(map[string]struct{}) + for _, flag := range Flags { + for _, name := range flag.Names() { + if _, ok := seenCLI[name]; ok { + t.Errorf("duplicate flag %s", name) + continue + } + seenCLI[name] = struct{}{} + } + } +} + +// TestBetaFlags test that all flags starting with "beta." have "BETA_" in the env var, and vice versa. +func TestBetaFlags(t *testing.T) { + for _, flag := range Flags { + envFlag, ok := flag.(interface { + GetEnvVars() []string + }) + if !ok || len(envFlag.GetEnvVars()) == 0 { // skip flags without env-var support + continue + } + name := flag.Names()[0] + envName := envFlag.GetEnvVars()[0] + if strings.HasPrefix(name, "beta.") { + require.Contains(t, envName, "BETA_", "%q flag must contain BETA in env var to match \"beta.\" flag name", name) + } + if strings.Contains(envName, "BETA_") { + require.True(t, strings.HasPrefix(name, "beta."), "%q flag must start with \"beta.\" in flag name to match \"BETA_\" env var", name) + } + } +} + +func TestHasEnvVar(t *testing.T) { + for _, flag := range Flags { + flag := flag + flagName := flag.Names()[0] + + t.Run(flagName, func(t *testing.T) { + envFlagGetter, ok := flag.(interface { + GetEnvVars() []string + }) + envFlags := envFlagGetter.GetEnvVars() + require.True(t, ok, "must be able to cast the flag to an EnvVar interface") + require.Equal(t, 1, len(envFlags), "flags should have exactly one env var") + }) + } +} + +func TestEnvVarFormat(t *testing.T) { + for _, flag := range Flags { + flag := flag + flagName := flag.Names()[0] + + skippedFlags := []string{ + txmgr.FeeLimitMultiplierFlagName, + txmgr.TxSendTimeoutFlagName, + txmgr.TxNotInMempoolTimeoutFlagName, + } + + t.Run(flagName, func(t *testing.T) { + if slices.Contains(skippedFlags, flagName) { + t.Skipf("Skipping flag %v which is known to not have a standard flag name <-> env var conversion", flagName) + } + envFlagGetter, ok := flag.(interface { + GetEnvVars() []string + }) + envFlags := envFlagGetter.GetEnvVars() + require.True(t, ok, "must be able to cast the flag to an EnvVar interface") + require.Equal(t, 1, len(envFlags), "flags should have exactly one env var") + expectedEnvVar := opservice.FlagNameToEnvVarName(flagName, "OP_BATCHER") + require.Equal(t, expectedEnvVar, envFlags[0]) + }) + } +} diff --git a/op-batcher/flags/types.go b/op-batcher/flags/types.go new file mode 100644 index 000000000000..0db97cdad219 --- /dev/null +++ b/op-batcher/flags/types.go @@ -0,0 +1,42 @@ +package flags + +import "fmt" + +type DataAvailabilityType string + +const ( + // data availability types + CalldataType DataAvailabilityType = "calldata" + BlobsType DataAvailabilityType = "blobs" +) + +var DataAvailabilityTypes = []DataAvailabilityType{ + CalldataType, + BlobsType, +} + +func (kind DataAvailabilityType) String() string { + return string(kind) +} + +func (kind *DataAvailabilityType) Set(value string) error { + if !ValidDataAvailabilityType(DataAvailabilityType(value)) { + return fmt.Errorf("unknown data-availability type: %q", value) + } + *kind = DataAvailabilityType(value) + return nil +} + +func (kind *DataAvailabilityType) Clone() any { + cpy := *kind + return &cpy +} + +func ValidDataAvailabilityType(value DataAvailabilityType) bool { + for _, k := range DataAvailabilityTypes { + if k == value { + return true + } + } + return false +} diff --git a/op-batcher/metrics/metrics.go b/op-batcher/metrics/metrics.go index 60ec194f745d..e1ae77ad854a 100644 --- a/op-batcher/metrics/metrics.go +++ b/op-batcher/metrics/metrics.go @@ -5,14 +5,15 @@ import ( "github.com/prometheus/client_golang/prometheus" - "github.com/ethereum-optimism/optimism/op-node/rollup/derive" - "github.com/ethereum-optimism/optimism/op-service/eth" - opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/eth" + opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" ) const Namespace = "op_batcher" @@ -44,6 +45,8 @@ type Metricer interface { RecordBatchTxSuccess() RecordBatchTxFailed() + RecordBlobUsedBytes(num int) + Document() []opmetrics.DocumentedMetric } @@ -58,7 +61,7 @@ type Metrics struct { info prometheus.GaugeVec up prometheus.Gauge - // label by openend, closed, fully_submitted, timed_out + // label by opened, closed, fully_submitted, timed_out channelEvs opmetrics.EventVec pendingBlocksCount prometheus.GaugeVec @@ -76,6 +79,8 @@ type Metrics struct { channelOutputBytesTotal prometheus.Counter batcherTxEvs opmetrics.EventVec + + blobUsedBytes prometheus.Histogram } var _ Metricer = (*Metrics)(nil) @@ -177,6 +182,12 @@ func NewMetrics(procName string) *Metrics { Name: "output_bytes_total", Help: "Total number of compressed output bytes from a channel.", }), + blobUsedBytes: factory.NewHistogram(prometheus.HistogramOpts{ + Namespace: ns, + Name: "blob_used_bytes", + Help: "Blob size in bytes being submitted.", + Buckets: prometheus.LinearBuckets(0.0, eth.MaxBlobDataSize/13, 13), + }), batcherTxEvs: opmetrics.NewEventVec(factory, ns, "", "batcher_tx", "BatcherTx", []string{"stage"}), } @@ -300,6 +311,10 @@ func (m *Metrics) RecordBatchTxFailed() { m.batcherTxEvs.Record(TxStageFailed) } +func (m *Metrics) RecordBlobUsedBytes(num int) { + m.blobUsedBytes.Observe(float64(num)) +} + // estimateBatchSize estimates the size of the batch func estimateBatchSize(block *types.Block) uint64 { size := uint64(70) // estimated overhead of batch metadata diff --git a/op-batcher/metrics/noop.go b/op-batcher/metrics/noop.go index bcaa9a362dc4..328cee9c797c 100644 --- a/op-batcher/metrics/noop.go +++ b/op-batcher/metrics/noop.go @@ -41,6 +41,7 @@ func (*noopMetrics) RecordChannelTimedOut(derive.ChannelID) {} func (*noopMetrics) RecordBatchTxSubmitted() {} func (*noopMetrics) RecordBatchTxSuccess() {} func (*noopMetrics) RecordBatchTxFailed() {} +func (*noopMetrics) RecordBlobUsedBytes(int) {} func (*noopMetrics) StartBalanceMetrics(log.Logger, ethereum.ChainStateReader, common.Address) io.Closer { return nil } diff --git a/op-bindings-e2e/Makefile b/op-bindings-e2e/Makefile new file mode 100644 index 000000000000..d04035b19735 --- /dev/null +++ b/op-bindings-e2e/Makefile @@ -0,0 +1,2 @@ +test-bindgen-e2e: + go test ./... -count=1 \ No newline at end of file diff --git a/op-bindings-e2e/fixtures_bytecode_test.go b/op-bindings-e2e/fixtures_bytecode_test.go new file mode 100644 index 000000000000..7360dda6b020 --- /dev/null +++ b/op-bindings-e2e/fixtures_bytecode_test.go @@ -0,0 +1,20 @@ +package bindgen + +const Safe_v130InitBytecode = "0x0000000000000000000000000000000000000000000000000000000000000000608060405234801561001057600080fd5b5060016004819055506159ae80620000296000396000f3fe6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506127d7565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b81019080803590602001909291908035906020019092919050505061280d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b8101908080359060200190929190505050612894565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128ac565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612c3e565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d78565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506132b5565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506132da565b005b348015610d3457600080fd5b50610d3d613369565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613512565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613518565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061353a565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff1690602001909291905050506136f8565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613820565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613a12565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613bb1565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bde565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f6f565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ff3565b005b34801561148957600080fd5b50611492614665565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061466f565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614817565b005b3480156116a457600080fd5b506116ad614878565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506148f6565b005b34801561174a57600080fd5b50611753614d29565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612c3e565b5b5050565b611bd2604182614e0590919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614e3f565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614e0590919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614e6e90919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614e6e90919063ffffffff16565b614e6e90919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156126bc5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b61272e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61273b858585855a614e8d565b9050801561278b573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a26127cf565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b600060606127e7868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561282b57600080fd5b506040519080825280601f01601f19166020018201604052801561285e5781602001600182028036833780820191505090505b50905060005b8381101561288957808501548060208302602085010152508080600101915050612864565b508091505092915050565b60076020528060005260406000206000915090505481565b6128b4614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561291e5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612a91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612c46614d62565b600354811115612cbe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612d35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000806000612d928e8e8e8e8e8e8e8e8e8e60055461466f565b905060056000815480929190600101919050555080805190602001209150612dbb8282866132da565b506000612dc6614ed9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612fac578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612e6957fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015612f3b578082015181840152602081019050612f20565b50505050905090810190601f168015612f685780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015612f9357600080fd5b505af1158015612fa7573d6000803e3d6000fd5b505050505b6101f4612fd36109c48b01603f60408d0281612fc457fe5b04614f0a90919063ffffffff16565b015a1015613049576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506130b28f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d146130a7578e6130ad565b6109c45a035b614e8d565b93506130c75a82614f2490919063ffffffff16565b905083806130d6575060008a14155b806130e2575060008814155b613154576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008089111561316e5761316b828b8b8b8b614f44565b90505b84156131b8577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a16131f8565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146132a4578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561328b57600080fd5b505af115801561329f573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111613357576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61336384848484611bbe565b50505050565b6060600060035467ffffffffffffffff8111801561338657600080fd5b506040519080825280602002602001820160405280156133b55781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613509578083838151811061346057fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061341f565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6135858a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508961514a565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146135c3576135c28461564a565b5b6136118787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615679565b600082111561362b5761362982600060018685614f44565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061374f878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a614e8d565b61375857600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156137e55780820151818401526020810190506137ca565b50505050905090810190601f1680156138125780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561383b57600080fd5b5060405190808252806020026020018201604052801561386a5781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561393d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561394857508482105b15613a03578084838151811061395a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506138d3565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613b14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613bc68c8c8c8c8c8c8c8c8c8c8c61466f565b8051906020012090509b9a5050505050505050505050565b613be6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c505750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613cc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613dc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f77614d62565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613ffb614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156140655750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561409d57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61410f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614210576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561427a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6142ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561470057fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b61478c614878565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61481f614d62565b6148288161564a565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6148a66125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b6148fe614d62565b806001600354031015614979576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156149e35750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614b55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614d2457614d2381612c3e565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614e03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614e185760009050614e39565b6000828402905082848281614e2957fe5b0414614e3457600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614e8357600080fd5b8091505092915050565b6000600180811115614e9b57fe5b836001811115614ea757fe5b1415614ec0576000808551602087018986f49050614ed0565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015614f1a5781614f1c565b825b905092915050565b600082821115614f3357600080fd5b600082840390508091505092915050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614614f815782614f83565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561509b57614fed3a8610614fca573a614fcc565b855b614fdf888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615096576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615140565b6150c0856150b2888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91506150cd8482846158b4565b61513f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600454146151c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615239576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156152b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156155b65760008482815181106152d057fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153445750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561537c57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156153b457508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b615426576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506152b9565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461577b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146158b05761583d8260008360015a614e8d565b6158af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d6000811461595b5760208114615963576000935061596e565b81935061596e565b600051158215171593505b505050939250505056fea26469706673582212203874bcf92e1722cc7bfa0cef1a0985cf0dc3485ba0663db3747ccdf1605df53464736f6c63430007060033" +const Safe_v130InitBytecodeNoSalt = "608060405234801561001057600080fd5b5060016004819055506159ae80620000296000396000f3fe6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506127d7565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b81019080803590602001909291908035906020019092919050505061280d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b8101908080359060200190929190505050612894565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128ac565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612c3e565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d78565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506132b5565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506132da565b005b348015610d3457600080fd5b50610d3d613369565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613512565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613518565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061353a565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff1690602001909291905050506136f8565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613820565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613a12565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613bb1565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bde565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f6f565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ff3565b005b34801561148957600080fd5b50611492614665565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061466f565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614817565b005b3480156116a457600080fd5b506116ad614878565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506148f6565b005b34801561174a57600080fd5b50611753614d29565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612c3e565b5b5050565b611bd2604182614e0590919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614e3f565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614e0590919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614e6e90919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614e6e90919063ffffffff16565b614e6e90919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156126bc5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b61272e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61273b858585855a614e8d565b9050801561278b573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a26127cf565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b600060606127e7868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561282b57600080fd5b506040519080825280601f01601f19166020018201604052801561285e5781602001600182028036833780820191505090505b50905060005b8381101561288957808501548060208302602085010152508080600101915050612864565b508091505092915050565b60076020528060005260406000206000915090505481565b6128b4614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561291e5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612a91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612c46614d62565b600354811115612cbe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612d35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000806000612d928e8e8e8e8e8e8e8e8e8e60055461466f565b905060056000815480929190600101919050555080805190602001209150612dbb8282866132da565b506000612dc6614ed9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612fac578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612e6957fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015612f3b578082015181840152602081019050612f20565b50505050905090810190601f168015612f685780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015612f9357600080fd5b505af1158015612fa7573d6000803e3d6000fd5b505050505b6101f4612fd36109c48b01603f60408d0281612fc457fe5b04614f0a90919063ffffffff16565b015a1015613049576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506130b28f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d146130a7578e6130ad565b6109c45a035b614e8d565b93506130c75a82614f2490919063ffffffff16565b905083806130d6575060008a14155b806130e2575060008814155b613154576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008089111561316e5761316b828b8b8b8b614f44565b90505b84156131b8577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a16131f8565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146132a4578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561328b57600080fd5b505af115801561329f573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111613357576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61336384848484611bbe565b50505050565b6060600060035467ffffffffffffffff8111801561338657600080fd5b506040519080825280602002602001820160405280156133b55781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613509578083838151811061346057fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061341f565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6135858a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508961514a565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146135c3576135c28461564a565b5b6136118787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615679565b600082111561362b5761362982600060018685614f44565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061374f878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a614e8d565b61375857600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156137e55780820151818401526020810190506137ca565b50505050905090810190601f1680156138125780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561383b57600080fd5b5060405190808252806020026020018201604052801561386a5781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561393d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561394857508482105b15613a03578084838151811061395a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506138d3565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613b14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613bc68c8c8c8c8c8c8c8c8c8c8c61466f565b8051906020012090509b9a5050505050505050505050565b613be6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c505750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613cc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613dc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f77614d62565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613ffb614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156140655750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561409d57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61410f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614210576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561427a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6142ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561470057fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b61478c614878565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61481f614d62565b6148288161564a565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6148a66125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b6148fe614d62565b806001600354031015614979576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156149e35750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614b55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614d2457614d2381612c3e565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614e03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614e185760009050614e39565b6000828402905082848281614e2957fe5b0414614e3457600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614e8357600080fd5b8091505092915050565b6000600180811115614e9b57fe5b836001811115614ea757fe5b1415614ec0576000808551602087018986f49050614ed0565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015614f1a5781614f1c565b825b905092915050565b600082821115614f3357600080fd5b600082840390508091505092915050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614614f815782614f83565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561509b57614fed3a8610614fca573a614fcc565b855b614fdf888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615096576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615140565b6150c0856150b2888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91506150cd8482846158b4565b61513f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600454146151c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615239576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156152b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156155b65760008482815181106152d057fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153445750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561537c57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156153b457508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b615426576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506152b9565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461577b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146158b05761583d8260008360015a614e8d565b6158af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d6000811461595b5760208114615963576000935061596e565b81935061596e565b600051158215171593505b505050939250505056fea26469706673582212203874bcf92e1722cc7bfa0cef1a0985cf0dc3485ba0663db3747ccdf1605df53464736f6c63430007060033" +const Safe_v130DeployedBytecode = "0x6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506127d7565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b81019080803590602001909291908035906020019092919050505061280d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b8101908080359060200190929190505050612894565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128ac565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612c3e565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d78565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506132b5565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506132da565b005b348015610d3457600080fd5b50610d3d613369565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613512565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613518565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061353a565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff1690602001909291905050506136f8565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613820565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613a12565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613bb1565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bde565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f6f565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ff3565b005b34801561148957600080fd5b50611492614665565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061466f565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614817565b005b3480156116a457600080fd5b506116ad614878565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506148f6565b005b34801561174a57600080fd5b50611753614d29565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612c3e565b5b5050565b611bd2604182614e0590919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614e3f565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614e0590919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614e6e90919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614e6e90919063ffffffff16565b614e6e90919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156126bc5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b61272e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61273b858585855a614e8d565b9050801561278b573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a26127cf565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b600060606127e7868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561282b57600080fd5b506040519080825280601f01601f19166020018201604052801561285e5781602001600182028036833780820191505090505b50905060005b8381101561288957808501548060208302602085010152508080600101915050612864565b508091505092915050565b60076020528060005260406000206000915090505481565b6128b4614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561291e5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612a91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612c46614d62565b600354811115612cbe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612d35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000806000612d928e8e8e8e8e8e8e8e8e8e60055461466f565b905060056000815480929190600101919050555080805190602001209150612dbb8282866132da565b506000612dc6614ed9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612fac578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612e6957fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015612f3b578082015181840152602081019050612f20565b50505050905090810190601f168015612f685780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015612f9357600080fd5b505af1158015612fa7573d6000803e3d6000fd5b505050505b6101f4612fd36109c48b01603f60408d0281612fc457fe5b04614f0a90919063ffffffff16565b015a1015613049576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506130b28f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d146130a7578e6130ad565b6109c45a035b614e8d565b93506130c75a82614f2490919063ffffffff16565b905083806130d6575060008a14155b806130e2575060008814155b613154576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008089111561316e5761316b828b8b8b8b614f44565b90505b84156131b8577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a16131f8565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146132a4578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561328b57600080fd5b505af115801561329f573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111613357576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61336384848484611bbe565b50505050565b6060600060035467ffffffffffffffff8111801561338657600080fd5b506040519080825280602002602001820160405280156133b55781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613509578083838151811061346057fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061341f565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6135858a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508961514a565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146135c3576135c28461564a565b5b6136118787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615679565b600082111561362b5761362982600060018685614f44565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061374f878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a614e8d565b61375857600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156137e55780820151818401526020810190506137ca565b50505050905090810190601f1680156138125780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561383b57600080fd5b5060405190808252806020026020018201604052801561386a5781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561393d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561394857508482105b15613a03578084838151811061395a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506138d3565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613b14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613bc68c8c8c8c8c8c8c8c8c8c8c61466f565b8051906020012090509b9a5050505050505050505050565b613be6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c505750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613cc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613dc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f77614d62565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613ffb614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156140655750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561409d57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61410f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614210576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561427a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6142ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561470057fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b61478c614878565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61481f614d62565b6148288161564a565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6148a66125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b6148fe614d62565b806001600354031015614979576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156149e35750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614b55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614d2457614d2381612c3e565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614e03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614e185760009050614e39565b6000828402905082848281614e2957fe5b0414614e3457600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614e8357600080fd5b8091505092915050565b6000600180811115614e9b57fe5b836001811115614ea757fe5b1415614ec0576000808551602087018986f49050614ed0565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015614f1a5781614f1c565b825b905092915050565b600082821115614f3357600080fd5b600082840390508091505092915050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614614f815782614f83565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561509b57614fed3a8610614fca573a614fcc565b855b614fdf888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615096576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615140565b6150c0856150b2888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91506150cd8482846158b4565b61513f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600454146151c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615239576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156152b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156155b65760008482815181106152d057fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153445750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561537c57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156153b457508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b615426576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506152b9565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461577b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146158b05761583d8260008360015a614e8d565b6158af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d6000811461595b5760208114615963576000935061596e565b81935061596e565b600051158215171593505b505050939250505056fea26469706673582212203874bcf92e1722cc7bfa0cef1a0985cf0dc3485ba0663db3747ccdf1605df53464736f6c63430007060033" + +const Permit2InitBytecode = "0x0000000000000000000000000000000000000000d3af2663da51c1021500000060c0346100bb574660a052602081017f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a60408301524660608301523060808301526080825260a082019180831060018060401b038411176100a557826040525190206080526123c090816100c1823960805181611b47015260a05181611b210152f35b634e487b7160e01b600052604160045260246000fd5b600080fdfe6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000003611b69577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a" +const Permit2InitBytecodeNoSalt = "60c0346100bb574660a052602081017f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a60408301524660608301523060808301526080825260a082019180831060018060401b038411176100a557826040525190206080526123c090816100c1823960805181611b47015260a05181611b210152f35b634e487b7160e01b600052604160045260246000fd5b600080fdfe6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000003611b69577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a" +const Permit2Abi = "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"name\":\"AllowanceExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExcessiveInvalidation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxAmount\",\"type\":\"uint256\"}],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidContractSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"signatureDeadline\",\"type\":\"uint256\"}],\"name\":\"SignatureExpired\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"Lockdown\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"newNonce\",\"type\":\"uint48\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"oldNonce\",\"type\":\"uint48\"}],\"name\":\"NonceInvalidation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"nonce\",\"type\":\"uint48\"}],\"name\":\"Permit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"word\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"mask\",\"type\":\"uint256\"}],\"name\":\"UnorderedNonceInvalidation\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"nonce\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint48\",\"name\":\"newNonce\",\"type\":\"uint48\"}],\"name\":\"invalidateNonces\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wordPos\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mask\",\"type\":\"uint256\"}],\"name\":\"invalidateUnorderedNonces\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"internalType\":\"struct IAllowanceTransfer.TokenSpenderPair[]\",\"name\":\"approvals\",\"type\":\"tuple[]\"}],\"name\":\"lockdown\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"nonceBitmap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"nonce\",\"type\":\"uint48\"}],\"internalType\":\"struct IAllowanceTransfer.PermitDetails[]\",\"name\":\"details\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"sigDeadline\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowanceTransfer.PermitBatch\",\"name\":\"permitBatch\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"nonce\",\"type\":\"uint48\"}],\"internalType\":\"struct IAllowanceTransfer.PermitDetails\",\"name\":\"details\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"sigDeadline\",\"type\":\"uint256\"}],\"internalType\":\"struct IAllowanceTransfer.PermitSingle\",\"name\":\"permitSingle\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.TokenPermissions\",\"name\":\"permitted\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.PermitTransferFrom\",\"name\":\"permit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestedAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.SignatureTransferDetails\",\"name\":\"transferDetails\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permitTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.TokenPermissions[]\",\"name\":\"permitted\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.PermitBatchTransferFrom\",\"name\":\"permit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestedAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.SignatureTransferDetails[]\",\"name\":\"transferDetails\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permitTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.TokenPermissions\",\"name\":\"permitted\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.PermitTransferFrom\",\"name\":\"permit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestedAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.SignatureTransferDetails\",\"name\":\"transferDetails\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"witness\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"witnessTypeString\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permitWitnessTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.TokenPermissions[]\",\"name\":\"permitted\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.PermitBatchTransferFrom\",\"name\":\"permit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestedAmount\",\"type\":\"uint256\"}],\"internalType\":\"struct ISignatureTransfer.SignatureTransferDetails[]\",\"name\":\"transferDetails\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"witness\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"witnessTypeString\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permitWitnessTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"struct IAllowanceTransfer.AllowanceTransferDetails[]\",\"name\":\"transferDetails\",\"type\":\"tuple[]\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" +const Permit2DeployedBytecode = "0x6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000103611b69577f866a5aba21966af95d6c7ab78eb2b2fc913915c28be3b9aa07cc04ff903e3f2890565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a" + +const MultiCall3Abi = "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"returnData\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call3[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call3Value[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3Value\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"blockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBasefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"basefee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockCoinbase\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockDifficulty\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"difficulty\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gaslimit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getEthBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryAggregate\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryBlockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]" +const MultiCall3DeployedBytecode = "0x6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033" +const MultiCall3InitBytecode = "0x608060405234801561001057600080fd5b50610ee0806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033" + +const SafeSingletonFactoryDeployedBytecode = "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" +const SafeSingletonFactoryInitBytecode = "0x604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" + +const Create2DeployerInitBytecode = "0x608060405234801561001057600080fd5b50610630806100206000396000f3fe6080604052600436106100435760003560e01c8063076c37b21461004f578063481286e61461007157806356299481146100ba57806366cfa057146100da57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a366004610327565b6100fa565b005b34801561007d57600080fd5b5061009161008c366004610327565b61014a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100c657600080fd5b506100916100d5366004610349565b61015d565b3480156100e657600080fd5b5061006f6100f53660046103ca565b610172565b61014582826040518060200161010f9061031a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052610183565b505050565b600061015683836102e7565b9392505050565b600061016a8484846102f0565b949350505050565b61017d838383610183565b50505050565b6000834710156101f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b815160000361025f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f60448201526064016101eb565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610156576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f790000000000000060448201526064016101eb565b60006101568383305b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b61014e806104ad83390190565b6000806040838503121561033a57600080fd5b50508035926020909101359150565b60008060006060848603121561035e57600080fd5b8335925060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156103df57600080fd5b8335925060208401359150604084013567ffffffffffffffff8082111561040557600080fd5b818601915086601f83011261041957600080fd5b81358181111561042b5761042b61039b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156104715761047161039b565b8160405282815289602084870101111561048a57600080fd5b826020860160208301376000602084830101528095505050505050925092509256fe608060405234801561001057600080fd5b5061012e806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063249cb3fa14602d575b600080fd5b603c603836600460b1565b604e565b60405190815260200160405180910390f35b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16608857600060aa565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b45b9392505050565b6000806040838503121560c357600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811460ed57600080fd5b80915050925092905056fea26469706673582212205ffd4e6cede7d06a5daf93d48d0541fc68189eeb16608c1999a82063b666eb1164736f6c63430008130033a2646970667358221220fdc4a0fe96e3b21c108ca155438d37c9143fb01278a3c1d274948bad89c564ba64736f6c63430008130033" +const Create2DeployerDeployedBytecode = "0x6080604052600436106100435760003560e01c8063076c37b21461004f578063481286e61461007157806356299481146100ba57806366cfa057146100da57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a366004610327565b6100fa565b005b34801561007d57600080fd5b5061009161008c366004610327565b61014a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100c657600080fd5b506100916100d5366004610349565b61015d565b3480156100e657600080fd5b5061006f6100f53660046103ca565b610172565b61014582826040518060200161010f9061031a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052610183565b505050565b600061015683836102e7565b9392505050565b600061016a8484846102f0565b949350505050565b61017d838383610183565b50505050565b6000834710156101f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b815160000361025f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f60448201526064016101eb565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610156576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f790000000000000060448201526064016101eb565b60006101568383305b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b61014e806104ad83390190565b6000806040838503121561033a57600080fd5b50508035926020909101359150565b60008060006060848603121561035e57600080fd5b8335925060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156103df57600080fd5b8335925060208401359150604084013567ffffffffffffffff8082111561040557600080fd5b818601915086601f83011261041957600080fd5b81358181111561042b5761042b61039b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156104715761047161039b565b8160405282815289602084870101111561048a57600080fd5b826020860160208301376000602084830101528095505050505050925092509256fe608060405234801561001057600080fd5b5061012e806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063249cb3fa14602d575b600080fd5b603c603836600460b1565b604e565b60405190815260200160405180910390f35b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16608857600060aa565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b45b9392505050565b6000806040838503121560c357600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811460ed57600080fd5b80915050925092905056fea26469706673582212205ffd4e6cede7d06a5daf93d48d0541fc68189eeb16608c1999a82063b666eb1164736f6c63430008130033a2646970667358221220fdc4a0fe96e3b21c108ca155438d37c9143fb01278a3c1d274948bad89c564ba64736f6c63430008130033" diff --git a/op-bindings-e2e/fixtures_test.go b/op-bindings-e2e/fixtures_test.go new file mode 100644 index 000000000000..f4e7cc30cf5e --- /dev/null +++ b/op-bindings-e2e/fixtures_test.go @@ -0,0 +1,541 @@ +package bindgen + +import ( + "github.com/ethereum-optimism/optimism/op-bindings/bindgen" + "github.com/ethereum-optimism/optimism/op-bindings/etherscan" + "github.com/ethereum/go-ethereum/common" +) + +var fetchContractDataTests = []struct { + name string + contractVerified bool + chain string + deploymentAddress string + expectedContractData bindgen.ContractData +}{ + { + "MultiCall3 on ETH", + true, + "eth", + "0xcA11bde05977b3631167028862bE2a173976CA11", + bindgen.ContractData{ + Abi: MultiCall3Abi, + DeployedBin: MultiCall3DeployedBytecode, + DeploymentTx: etherscan.Transaction{ + Input: MultiCall3InitBytecode, + Hash: "0x00d9fcb7848f6f6b0aae4fb709c133d69262b902156c85a473ef23faa60760bd", + To: "", + }, + }, + }, + { + "MultiCall3 on OP", + true, + "op", + "0xcA11bde05977b3631167028862bE2a173976CA11", + bindgen.ContractData{ + Abi: MultiCall3Abi, + DeployedBin: MultiCall3DeployedBytecode, + DeploymentTx: etherscan.Transaction{ + Input: MultiCall3InitBytecode, + Hash: "0xb62f9191a2cf399c0d2afd33f5b8baf7c6b52af6dd2386e44121b1bab91b80e5", + To: "", + }, + }, + }, + { + "SafeSingletonFactory on ETH", + false, + "eth", + "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7", + bindgen.ContractData{ + Abi: "", + DeployedBin: SafeSingletonFactoryDeployedBytecode, + DeploymentTx: etherscan.Transaction{ + Input: SafeSingletonFactoryInitBytecode, + Hash: "0x69c275b5304db980105b7a6d731f9e1157a3fe29e7ff6ff95235297df53e9928", + To: "", + }, + }, + }, + { + "Permit2 on ETH", + true, + "eth", + "0x000000000022D473030F116dDEE9F6B43aC78BA3", + bindgen.ContractData{ + Abi: Permit2Abi, + DeployedBin: Permit2DeployedBytecode, + DeploymentTx: etherscan.Transaction{ + Input: Permit2InitBytecode, + Hash: "0xf2f1fe96c16ee674bb7fcee166be52465a418927d124f5f1d231b36eae65d377", + To: "0x4e59b44847b379578588920ca78fbf26c0b4956c", + }, + }, + }, +} + +// Not currently being tested due to complexity of test setup: +// - FetchDeploymentTxHash failure +// Not being tested because the contract would need to have deployed bytecode to +// pass FetchDeployedBytecode, which means Etherscan should have indexed the deployment tx +// - FetchDeploymentTx failure +// Not being tested for the same reason and there would be no way to pass FetchDeploymentTxHash, +// but not be able to retrieve tx details +var fetchContractDataTestsFailures = []struct { + name string + contractVerified bool + chain string + deploymentAddress string + expectedError string +}{ + { + "MultiCall3 on Foo", + true, + "foo", + "0xcA11bde05977b3631167028862bE2a173976CA11", + "unknown chain, unable to retrieve a contract data client for chain: foo", + }, + { + // This test case is covering fetching an ABI for a non-verified contract that's we're saying is verified + "SafeSingletonFactory on ETH", + true, + "eth", + "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7", + "error fetching ABI: operation failed permanently after 3 attempts: there was an issue with the Etherscan request", + }, + { + // This test case is covering fetching the deployed bytecode for a non-existent contract + "Nonexistent on ETH", + false, + "eth", + "0x914d7Fec6aaC8cd542e72Bca78B30650d455555", + "error fetching deployed bytecode: API response result is not expected bytecode string", + }, +} + +var compareInitBytecodeWithOpTests = []struct { + name string + contractMetadataEth bindgen.RemoteContractMetadata + initCodeShouldMatch bool +}{ + { + name: "Safe_v130 Init Bytecode Should Match", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552"), + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: Safe_v130InitBytecodeNoSalt, + DeployedBin: "", + }, + initCodeShouldMatch: true, + }, + { + name: "Safe_v130 Compare Init Bytecode Only On OP", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: Safe_v130InitBytecodeNoSalt, + DeployedBin: "", + }, + initCodeShouldMatch: true, + }, + { + name: "Create2Deployer's Init Bytecode Should Not Match", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Create2Deployer", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2"), + Eth: common.HexToAddress("0xF49600926c7109BD66Ab97a2c036bf696e58Dbc2"), + }, + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: Create2DeployerInitBytecode, + DeployedBin: Create2DeployerDeployedBytecode, + }, + initCodeShouldMatch: false, + }, +} + +var compareInitBytecodeWithOpTestsFailures = []struct { + name string + contractMetadataEth bindgen.RemoteContractMetadata + initCodeShouldMatch bool + expectedError string +}{ + { + name: "Safe_v130 Mismatch Init Bytecode", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552"), + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: Permit2InitBytecodeNoSalt, + DeployedBin: "", + }, + initCodeShouldMatch: true, + expectedError: "expected initialization bytecode to match on Ethereum and Optimism, but it doesn't.", + }, + { + name: "Safe_v130 No Deployment on Optimism", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: Safe_v130InitBytecode, + DeployedBin: Safe_v130DeployedBytecode, + }, + initCodeShouldMatch: true, + expectedError: "no deployment address on Optimism provided for Safe_v130", + }, + { + name: "MultiCall3 Expected Init Code Not to Match, but it Does", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "MultiCall3", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0xcA11bde05977b3631167028862bE2a173976CA11"), + Eth: common.HexToAddress("0xcA11bde05977b3631167028862bE2a173976CA11"), + }, + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: MultiCall3InitBytecode, + DeployedBin: MultiCall3DeployedBytecode, + }, + initCodeShouldMatch: false, + expectedError: "expected initialization bytecode on Ethereum to not match on Optimism, but it did.", + }, + { + name: "Safe_v130 No Init Bytecode Provided", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552"), + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: "", + DeployedBin: Safe_v130DeployedBytecode, + }, + initCodeShouldMatch: false, + expectedError: "no initialization bytecode provided for ETH deployment for comparison", + }, +} + +var compareDeployedBytecodeWithOpTests = []struct { + name string + contractMetadataEth bindgen.RemoteContractMetadata + deployedCodeShouldMatch bool +}{ + { + name: "Safe_v130 Deployed Bytecode Should Match", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552"), + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: "", + DeployedBin: Safe_v130DeployedBytecode, + }, + deployedCodeShouldMatch: true, + }, + { + name: "Safe_v130 Compare Deployed Bytecode Only On OP", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: Safe_v130InitBytecodeNoSalt, + DeployedBin: Safe_v130DeployedBytecode, + }, + deployedCodeShouldMatch: true, + }, + { + name: "Permit2's Deployed Bytecode Should Not Match", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Permit2", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0x000000000022D473030F116dDEE9F6B43aC78BA3"), + Eth: common.HexToAddress("0x000000000022D473030F116dDEE9F6B43aC78BA3"), + }, + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: Permit2InitBytecode, + DeployedBin: Permit2DeployedBytecode, + }, + deployedCodeShouldMatch: false, + }, +} + +var compareDeployedBytecodeWithOpTestsFailures = []struct { + name string + contractMetadataEth bindgen.RemoteContractMetadata + deployedCodeShouldMatch bool + expectedError string +}{ + { + name: "Safe_v130 Mismatch Deplolyed Bytecode", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552"), + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: "", + DeployedBin: Permit2DeployedBytecode, + }, + deployedCodeShouldMatch: true, + expectedError: "expected deployed bytecode to match on Ethereum and Optimism, but it doesn't.", + }, + { + name: "Safe_v130 No Deployment on Optimism", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: "", + DeployedBin: Permit2DeployedBytecode, + }, + deployedCodeShouldMatch: true, + expectedError: "no deployment address on Optimism provided for Safe_v130", + }, + { + name: "Safe_v130 Expected Deployed Code Not to Match, but it Does", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552"), + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: Safe_v130InitBytecode, + DeployedBin: Safe_v130DeployedBytecode, + }, + deployedCodeShouldMatch: false, + expectedError: "expected deployed bytecode on Ethereum to not match on Optimism, but it does.", + }, + { + name: "Safe_v130 No Deployed Bytecode Provided", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552"), + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: Safe_v130InitBytecode, + DeployedBin: "", + }, + deployedCodeShouldMatch: false, + expectedError: "no deployed bytecode provided for ETH deployment for comparison", + }, +} + +var compareDeployedBytecodeWithRpcTests = []struct { + name string + contractMetadataEth bindgen.RemoteContractMetadata + chain string +}{ + { + name: "Safe_v130 Compare Against ETH", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.Address{}, + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: "", + DeployedBin: Safe_v130DeployedBytecode, + }, + chain: "eth", + }, + { + name: "Safe_v130 Compare Against OP", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.HexToAddress("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552"), + Eth: common.Address{}, + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: "", + DeployedBin: Safe_v130DeployedBytecode, + }, + chain: "op", + }, +} + +var compareDeployedBytecodeWithRpcTestsFailures = []struct { + name string + contractMetadataEth bindgen.RemoteContractMetadata + chain string + expectedError string +}{ + { + name: "Safe_v130 Compare Against foo", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.Address{}, + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: "", + DeployedBin: "", + }, + chain: "foo", + expectedError: "unknown chain: foo, unable to retrieve a RPC client", + }, + { + name: "Safe_v130 Bytecode Mismatch", + contractMetadataEth: bindgen.RemoteContractMetadata{ + RemoteContract: bindgen.RemoteContract{ + Name: "Safe_v130", + Verified: true, + Deployments: bindgen.Deployments{ + Op: common.Address{}, + Eth: common.HexToAddress("0x69f4D1788e39c87893C980c06EdF4b7f686e2938"), + }, + DeploymentSalt: "0000000000000000000000000000000000000000000000000000000000000000", + Deployer: common.Address{}, + ABI: "", + InitBytecode: "", + }, + Package: "bindings", + InitBin: "", + DeployedBin: Permit2DeployedBytecode, + }, + chain: "eth", + expectedError: "Safe_v130 deployment bytecode from RPC doesn't match bytecode from Etherscan.", + }, +} diff --git a/op-bindings-e2e/remote_handlers_test.go b/op-bindings-e2e/remote_handlers_test.go new file mode 100644 index 000000000000..b476b9381696 --- /dev/null +++ b/op-bindings-e2e/remote_handlers_test.go @@ -0,0 +1,177 @@ +package bindgen + +import ( + "fmt" + "os" + "reflect" + "strings" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindgen" + "github.com/ethereum-optimism/optimism/op-bindings/etherscan" + "github.com/ethereum/go-ethereum/ethclient" +) + +var generator bindgen.BindGenGeneratorRemote = bindgen.BindGenGeneratorRemote{} + +func configureGenerator(t *testing.T) error { + generator.ContractDataClients.Eth = etherscan.NewEthereumClient(os.Getenv("ETHERSCAN_APIKEY_ETH")) + generator.ContractDataClients.Op = etherscan.NewOptimismClient(os.Getenv("ETHERSCAN_APIKEY_OP")) + + var err error + if generator.RpcClients.Eth, err = ethclient.Dial(os.Getenv("RPC_URL_ETH")); err != nil { + return fmt.Errorf("error initializing Ethereum client: %w", err) + } + if generator.RpcClients.Op, err = ethclient.Dial(os.Getenv("RPC_URL_OP")); err != nil { + return fmt.Errorf("error initializing Optimism client: %w", err) + } + + return nil +} + +func TestFetchContractData(t *testing.T) { + if err := configureGenerator(t); err != nil { + t.Error(err) + } + + for _, tt := range fetchContractDataTests { + t.Run(tt.name, func(t *testing.T) { + contractData, err := generator.FetchContractData(tt.contractVerified, tt.chain, tt.deploymentAddress) + if err != nil { + t.Error(err) + } + if !reflect.DeepEqual(contractData, tt.expectedContractData) { + t.Errorf("Retrieved contract data doesn't match expected. Expected: %s Retrieved: %s", tt.expectedContractData, contractData) + } + }) + } +} + +func TestFetchContractDataFailures(t *testing.T) { + if err := configureGenerator(t); err != nil { + t.Error(err) + } + + for _, tt := range fetchContractDataTestsFailures { + t.Run(tt.name, func(t *testing.T) { + _, err := generator.FetchContractData(tt.contractVerified, tt.chain, tt.deploymentAddress) + if err == nil { + t.Errorf("Expected error: %s but didn't receive it", tt.expectedError) + return + } + + if !strings.Contains(err.Error(), tt.expectedError) { + t.Errorf("Expected error: %s Received: %s", tt.expectedError, err) + return + } + }) + } +} + +func TestCompareInitBytecodeWithOp(t *testing.T) { + if err := configureGenerator(t); err != nil { + t.Error(err) + } + + for _, tt := range compareInitBytecodeWithOpTests { + t.Run(tt.name, func(t *testing.T) { + err := generator.CompareInitBytecodeWithOp(&tt.contractMetadataEth, tt.initCodeShouldMatch) + if err != nil { + t.Error(err) + } + }) + } +} + +func TestCompareInitBytecodeWithOpFailures(t *testing.T) { + if err := configureGenerator(t); err != nil { + t.Error(err) + } + + for _, tt := range compareInitBytecodeWithOpTestsFailures { + t.Run(tt.name, func(t *testing.T) { + err := generator.CompareInitBytecodeWithOp(&tt.contractMetadataEth, tt.initCodeShouldMatch) + if err == nil { + t.Errorf("Expected error: %s but didn't receive it", tt.expectedError) + return + } + + if !strings.Contains(err.Error(), tt.expectedError) { + t.Errorf("Expected error: %s Received: %s", tt.expectedError, err) + return + } + }) + } +} + +func TestCompareDeployedBytecodeWithOp(t *testing.T) { + if err := configureGenerator(t); err != nil { + t.Error(err) + } + + for _, tt := range compareDeployedBytecodeWithOpTests { + t.Run(tt.name, func(t *testing.T) { + err := generator.CompareDeployedBytecodeWithOp(&tt.contractMetadataEth, tt.deployedCodeShouldMatch) + if err != nil { + t.Error(err) + } + }) + } +} + +func TestCompareDeployedBytecodeWithOpFailures(t *testing.T) { + if err := configureGenerator(t); err != nil { + t.Error(err) + } + + for _, tt := range compareDeployedBytecodeWithOpTestsFailures { + t.Run(tt.name, func(t *testing.T) { + err := generator.CompareDeployedBytecodeWithOp(&tt.contractMetadataEth, tt.deployedCodeShouldMatch) + if err == nil { + t.Errorf("Expected error: %s but didn't receive it", tt.expectedError) + return + } + + if !strings.Contains(err.Error(), tt.expectedError) { + t.Errorf("Expected error: %s Received: %s", tt.expectedError, err) + return + } + }) + } +} + +func TestCompareDeployedBytecodeWithRpc(t *testing.T) { + if err := configureGenerator(t); err != nil { + t.Error(err) + } + + for _, tt := range compareDeployedBytecodeWithRpcTests { + t.Run(tt.name, func(t *testing.T) { + err := generator.CompareDeployedBytecodeWithRpc(&tt.contractMetadataEth, tt.chain) + if err != nil { + t.Error(err) + } + }) + } +} + +func TestCompareDeployedBytecodeWithRpcFailures(t *testing.T) { + if err := configureGenerator(t); err != nil { + t.Error(err) + } + + for _, tt := range compareDeployedBytecodeWithRpcTestsFailures { + t.Run(tt.name, func(t *testing.T) { + err := generator.CompareDeployedBytecodeWithRpc(&tt.contractMetadataEth, tt.chain) + if err == nil { + t.Errorf("Expected error: %s but didn't receive it", tt.expectedError) + return + } + + if !strings.Contains(err.Error(), tt.expectedError) { + t.Errorf("Expected error: %s Received: %s", tt.expectedError, err) + return + } + }) + } +} diff --git a/op-bindings/Makefile b/op-bindings/Makefile index 1a5b8360bfe1..7066489f6a20 100644 --- a/op-bindings/Makefile +++ b/op-bindings/Makefile @@ -1,8 +1,16 @@ SHELL := /usr/bin/env bash pkg := bindings +pkg-preview := bindingspreview monorepo-base := $(shell dirname $(realpath .)) contracts-dir := $(monorepo-base)/packages/contracts-bedrock +contracts-list := ./artifacts.json +contracts-list-preview := ./artifacts-preview.json +log-level := info +ETHERSCAN_APIKEY_ETH ?= +ETHERSCAN_APIKEY_OP ?= +RPC_URL_ETH ?= +RPC_URL_OP ?= all: version mkdir bindings @@ -15,16 +23,62 @@ compile: forge clean && \ pnpm build -bindings: compile bindings-build +bindings: bindgen-local bindgen-preview -bindings-build: - go run ./gen/main.go \ - -forge-artifacts $(contracts-dir)/forge-artifacts \ - -out ./bindings \ - -contracts ./artifacts.json \ - -source-maps MIPS,PreimageOracle \ - -package $(pkg) \ - -monorepo-base $(monorepo-base) +bindings-build: bindgen-generate-local bindgen-generate-preview + +bindgen: compile bindgen-generate-all + +bindgen-generate-all: + go run ./cmd/ \ + generate \ + --metadata-out ./$(pkg) \ + --bindings-package $(pkg) \ + --contracts-list $(contracts-list) \ + --log.level $(log-level) \ + all \ + --forge-artifacts $(contracts-dir)/forge-artifacts \ + --etherscan.apikey.eth $(ETHERSCAN_APIKEY_ETH) \ + --etherscan.apikey.op $(ETHERSCAN_APIKEY_OP) \ + --rpc.url.eth $(RPC_URL_ETH) \ + --rpc.url.op $(RPC_URL_OP) + +bindgen-local: compile bindgen-generate-local + +bindgen-generate-local: + go run ./cmd/ \ + generate \ + --metadata-out ./$(pkg) \ + --bindings-package $(pkg) \ + --contracts-list $(contracts-list) \ + --log.level $(log-level) \ + local \ + --forge-artifacts $(contracts-dir)/forge-artifacts + +bindgen-preview: compile bindgen-generate-preview + +bindgen-generate-preview: + go run ./cmd \ + generate \ + --metadata-out ./$(pkg-preview) \ + --bindings-package $(pkg-preview) \ + --contracts-list $(contracts-list-preview) \ + --log.level $(log-level) \ + local \ + --forge-artifacts $(contracts-dir)/forge-artifacts + +bindgen-remote: + go run ./cmd/ \ + generate \ + --metadata-out ./$(pkg) \ + --bindings-package $(pkg) \ + --contracts-list $(contracts-list) \ + --log.level $(log-level) \ + remote \ + --etherscan.apikey.eth $(ETHERSCAN_APIKEY_ETH) \ + --etherscan.apikey.op $(ETHERSCAN_APIKEY_OP) \ + --rpc.url.eth $(RPC_URL_ETH) \ + --rpc.url.op $(RPC_URL_OP) mkdir: mkdir -p $(pkg) diff --git a/op-bindings/artifacts-preview.json b/op-bindings/artifacts-preview.json new file mode 100644 index 000000000000..9d1630f96d2f --- /dev/null +++ b/op-bindings/artifacts-preview.json @@ -0,0 +1,6 @@ +{ + "local": [ + "OptimismPortal2" + ], + "remote": [] +} diff --git a/op-bindings/artifacts.json b/op-bindings/artifacts.json index 61b0a1dc97f8..ec22fbc34b75 100644 --- a/op-bindings/artifacts.json +++ b/op-bindings/artifacts.json @@ -1,45 +1,148 @@ -[ - "SystemConfig", - "L1CrossDomainMessenger", - "L1StandardBridge", - "OptimismPortal", - "L2OutputOracle", - "AddressManager", - "L1Block", - "L2ToL1MessagePasser", - "GasPriceOracle", - "L2CrossDomainMessenger", - "L2StandardBridge", - "L2ERC721Bridge", - "L1ERC721Bridge", - "OptimismMintableERC721Factory", - "SequencerFeeVault", - "BaseFeeVault", - "L1FeeVault", - "OptimismMintableERC20Factory", - "OptimismMintableERC20", - "LegacyERC20ETH", - "Proxy", - "ProxyAdmin", - "LegacyMessagePasser", - "ERC20", - "WETH9", - "DeployerWhitelist", - "L1BlockNumber", - "DisputeGameFactory", - "FaultDisputeGame", - "AlphabetVM", - "StandardBridge", - "CrossDomainMessenger", - "MIPS", - "PreimageOracle", - "BlockOracle", - "EAS", - "SchemaRegistry", - "ProtocolVersions", - "Safe", - "SafeProxyFactory", - "DelayedVetoable", - "ISemver", - "StorageSetter" -] +{ + "local": [ + "SystemConfig", + "L1CrossDomainMessenger", + "L1StandardBridge", + "OptimismPortal", + "L2OutputOracle", + "AddressManager", + "L1Block", + "L2ToL1MessagePasser", + "GasPriceOracle", + "L2CrossDomainMessenger", + "L2StandardBridge", + "L2ERC721Bridge", + "L1ERC721Bridge", + "OptimismMintableERC721Factory", + "SequencerFeeVault", + "BaseFeeVault", + "L1FeeVault", + "OptimismMintableERC20Factory", + "OptimismMintableERC20", + "Proxy", + "ProxyAdmin", + "LegacyMessagePasser", + "ERC20", + "WETH9", + "DeployerWhitelist", + "L1BlockNumber", + "DelayedWETH", + "DisputeGameFactory", + "FaultDisputeGame", + "AlphabetVM", + "StandardBridge", + "CrossDomainMessenger", + "MIPS", + "PreimageOracle", + "EAS", + "SchemaRegistry", + "ProtocolVersions", + "Safe", + "SafeProxyFactory", + "DelayedVetoable", + "ISemver", + "StorageSetter", + "SuperchainConfig", + "DataAvailabilityChallenge" + ], + "remote": [ + { + "name": "MultiCall3", + "verified": true, + "deployments": { + "eth": "0xcA11bde05977b3631167028862bE2a173976CA11", + "op": "0xcA11bde05977b3631167028862bE2a173976CA11" + } + }, + { + "name": "Create2Deployer", + "verified": true, + "deployments": { + "eth": "0xF49600926c7109BD66Ab97a2c036bf696e58Dbc2", + "op": "0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2" + } + }, + { + "name": "Safe_v130", + "verified": true, + "deployments": { + "eth": "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552", + "op": "0x69f4D1788e39c87893C980c06EdF4b7f686e2938" + }, + "deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "name": "SafeL2_v130", + "verified": true, + "deployments": { + "eth": "0x3E5c63644E683549055b9Be8653de26E0B4CD36E", + "op": "0xfb1bffC9d739B8D520DaF37dF666da4C687191EA" + }, + "deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "name": "MultiSendCallOnly_v130", + "verified": true, + "deployments": { + "eth": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D", + "op": "0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B" + }, + "deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "name": "SafeSingletonFactory", + "verified": false, + "deployments": { + "eth": "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7", + "op": "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7" + }, + "abi": "[{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\",\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"creationCode\",\"type\":\"bytes\"}]}]" + }, + { + "name": "DeterministicDeploymentProxy", + "verified": false, + "deployments": { + "eth": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "op": "0x4e59b44847b379578588920cA78FbF26c0B4956C" + }, + "abi": "[{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\",\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"creationCode\",\"type\":\"bytes\"}]}]" + }, + { + "name": "MultiSend_v130", + "verified": true, + "deployments": { + "op": "0x998739BFdAAdde7C933B942a68053933098f9EDa" + }, + "deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "name": "Permit2", + "verified": true, + "deployments": { + "eth": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "op": "0x000000000022D473030F116dDEE9F6B43aC78BA3" + }, + "deploymentSalt": "0000000000000000000000000000000000000000d3af2663da51c10215000000", + "deployer": "0x4e59b44847b379578588920cA78FbF26c0B4956C" + }, + { + "name": "SenderCreator", + "verified": false, + "deployments": { + "eth": "0x7fc98430eaedbb6070b35b39d798725049088348", + "op": "0x7fc98430eaedbb6070b35b39d798725049088348" + }, + "initBytecode": "0x6080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033", + "abi": "[{\"inputs\": [{\"internalType\": \"bytes\",\"name\": \"initCode\",\"type\": \"bytes\"}],\"name\": \"createSender\",\"outputs\": [{\"internalType\": \"address\",\"name\": \"sender\",\"type\": \"address\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"}]" + }, + { + "name": "EntryPoint", + "verified": true, + "deployments": { + "eth": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "op": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" + }, + "deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000" + } + ] +} diff --git a/op-bindings/ast/canonicalize.go b/op-bindings/ast/canonicalize.go index f0b69ae578e0..eae1a431b428 100644 --- a/op-bindings/ast/canonicalize.go +++ b/op-bindings/ast/canonicalize.go @@ -63,7 +63,7 @@ func CanonicalizeASTIDs(in *solc.StorageLayout, monorepoBase string) *solc.Stora continue } - // The storage types include the size when its a fixed size. + // The storage types include the size when it's a fixed size. // This is subject to breaking in the future if a type with // an ast id is added in a fixed storage type. We don't want // to skip a type with `_storage` in it if it has a subtype diff --git a/op-bindings/ast/canonicalize_test.go b/op-bindings/ast/canonicalize_test.go index 438653e4bde7..1e992584effc 100644 --- a/op-bindings/ast/canonicalize_test.go +++ b/op-bindings/ast/canonicalize_test.go @@ -10,11 +10,6 @@ import ( "github.com/stretchr/testify/require" ) -type astIDTest struct { - In *solc.StorageLayout `json:"in"` - Out *solc.StorageLayout `json:"out"` -} - func TestCanonicalize(t *testing.T) { tests := []struct { name string @@ -42,7 +37,10 @@ func TestCanonicalize(t *testing.T) { f, err := os.Open(path.Join("testdata", tt.filename)) require.NoError(t, err) dec := json.NewDecoder(f) - var testData astIDTest + var testData struct { + In *solc.StorageLayout `json:"in"` + Out *solc.StorageLayout `json:"out"` + } require.NoError(t, dec.Decode(&testData)) require.NoError(t, f.Close()) diff --git a/op-bindings/bindgen/README.md b/op-bindings/bindgen/README.md new file mode 100644 index 000000000000..914c54df94c2 --- /dev/null +++ b/op-bindings/bindgen/README.md @@ -0,0 +1,338 @@ +![BindGen Header Image](./bindgen_header.png) + +A CLI for generating Go bindings from Forge artifacts and API clients such as Etherscan's + +- [Dependencies](#dependencies) +- [Running BindGen](#running-bindgen) + - [Using the Makefile Commands](#using-the-makefile-commands) + - [`bindgen`](#bindgen) + - [Required ENVs](#required-envs) + - [`bindgen-local`](#bindgen-local) + - [`bindgen-remote`](#bindgen-remote) + - [Required ENVs](#required-envs-1) + - [Using the CLI Directly](#using-the-cli-directly) + - [CLI Flags](#cli-flags) + - [Global Flags](#global-flags) + - [Local Flags](#local-flags) + - [Remote Flags](#remote-flags) +- [Using BindGen to Add New Preinstalls to L2 Genesis](#using-bindgen-to-add-new-preinstalls-to-l2-genesis) + - [Anatomy of `artifacts.json`](#anatomy-of-artifactsjson) + - [`"local"` Contracts](#local-contracts) + - [`"remote"` Contracts](#remote-contracts) + - [Adding A New `"remote"` Contract](#adding-a-new-remote-contract) + - [Contracts that Don't Make Good Preinstalls](#contracts-that-dont-make-good-preinstalls) + - [Adding the Contract to L2 Genesis](#adding-the-contract-to-l2-genesis) + +# Dependencies + +- [Go](https://go.dev/dl/) +- [Foundry](https://getfoundry.sh/) +- [pnpm](https://pnpm.io/installation) + +If you're running the CLI inside the Optimism monorepo, please make sure you've executed `pnpm i` and `pnpm build` to install and setup all of the monorepo's dependencies. + +# Running BindGen + +BindGen can be run in one of two ways: + +1. Using the provided [Makefile](../Makefile) which defaults some of the required flags +2. Executing the CLI directly with `go run`, or building a Go binary and executing it + +Before executing BindGen, please review the [artifacts.json](../artifacts.json) file which specifies what contracts BindGen should generate Go bindings and metadata files for. More information on how to configure `artifacts.json` can be found [here](#anatomy-of-artifactsjson). + +## Using the Makefile Commands + +### `bindgen` + +```bash +ETHERSCAN_APIKEY_ETH=your_api_key \ +ETHERSCAN_APIKEY_OP=your_api_key \ +RPC_URL_ETH=your_rpc_url \ +RPC_URL_OP=your_rpc_url \ +make bindgen +``` + +This command will run `forge clean` to remove any existing Forge artifacts found in the [contracts-bedrock](../../packages/contracts-bedrock/) directory, re-build the Forge artifacts, then will use BindGen to generate Go bindings and metadata files for the contracts specified in [artifacts.json](../artifacts.json). + +#### Required ENVs + +- `ETHERSCAN_APIKEY_ETH` An Etherscan API key for querying Ethereum Mainnet. + + - [Here's a guide](https://docs.etherscan.io/getting-started/viewing-api-usage-statistics) on how to obtain a key. + +- `ETHERSCAN_APIKEY_OP` An Etherscan API key for querying Optimism Mainnet. + + - You can follow the above guide to obtain a key, but make sure you're on the [Optimistic Etherscan](https://optimistic.etherscan.io/) + +- `RPC_URL_ETH` This is any HTTP URL that can be used to query an Ethereum Mainnet RPC node. + + - Expected to use API key authentication. + +- `RPC_URL_OP` This is any HTTP URL that can be used to query an Optimism Mainnet RPC node. + + - Expected to use API key authentication. + +### `bindgen-local` + +```bash +make bindgen-local +``` + +This command will run `forge clean` to remove any existing Forge artifacts found in the [contracts-bedrock](../../packages/contracts-bedrock/) directory, re-build the Forge artifacts, then will use BindGen to generate Go bindings and metadata files for the `"local"` contracts specified in [artifacts.json](../artifacts.json). + +### `bindgen-remote` + +```bash +ETHERSCAN_APIKEY_ETH=your_api_key \ +ETHERSCAN_APIKEY_OP=your_api_key \ +RPC_URL_ETH=your_rpc_url \ +RPC_URL_OP=your_rpc_url \ +make bindgen-remote +``` + +This command will use BindGen to generate Go bindings and metadata files for the `"remote"` contracts specified in [artifacts.json](../artifacts.json). + +#### Required ENVs + +- `ETHERSCAN_APIKEY_ETH` An Etherscan API key for querying Ethereum Mainnet. + + - [Here's a guide](https://docs.etherscan.io/getting-started/viewing-api-usage-statistics) on how to obtain a key. + +- `ETHERSCAN_APIKEY_OP` An Etherscan API key for querying Optimism Mainnet. + + - You can follow the above guide to obtain a key, but make sure you're on the [Optimistic Etherscan](https://optimistic.etherscan.io/) + +- `RPC_URL_ETH` This is any HTTP URL that can be used to query an Ethereum Mainnet RPC node. + + - Expected to use API key authentication. + +- `RPC_URL_OP` This is any HTTP URL that can be used to query an Optimism Mainnet RPC node. + + - Expected to use API key authentication. + +## Using the CLI Directly + +Currently the CLI only has one command, `generate`, which expects one of the following sub-commands: + +Command | Description | Flags | Usage +-------- | -------------------------------------------------------------------------- | ----------------------------- | ------------------------------------------------------------------ +`all` | Generates bindings for both local and remotely sourced contracts. | [Global Flags](#global-flags) | `bindgen generate [global-flags] all [local-flags] [remote-flags]` +`local` | Generates bindings for contracts with locally available Forge artifacts. | [Local Flags](#local-flags) | `bindgen generate [global-flags] local [local-flags]` +`remote` | Generates bindings for contracts whose metadata is sourced from Etherscan. | [Remote Flags](#remote-flags) | `bindgen generate [global-flags] remote [remote-flags]` + +The following displays how the CLI can be invoked from the monorepo root: + +```bash +go run ./op-bindings/cmd/ +``` + +## CLI Flags + +### Global Flags + +These flags are used by all CLI commands + +Flag | Type | Description | Required +------------------ | ------ | ------------------------------------------------------------------------------ | -------- +`metadata-out` | String | Output directory for Go bindings contract metadata files | Yes +`bindings-package` | String | Go package name used for generated Go bindings | Yes +`contracts-list` | String | Path to the list of `local` and/or `remote` contracts | Yes +`log.level` | String | Log level (`none`, `debug`, `info`, `warn`, `error`, `crit`) (Default: `info`) | No + +## Local Flags + +These flags are used with `all` and `local` commands + +Flag | Type | Description | Required +------------------ | ------ | ------------------------------------------------------------- | -------- +`source-maps-list` | String | Comma-separated list of contracts to generate source-maps for | No +`forge-artifacts` | String | Path to the directory with compiled Forge artifacts | Yes + +## Remote Flags + +These flags are used with `all` and `remote` commands + +Flag | Type | Description | Required +---------------------- | ------ | --------------------------------------------------------------------------- | -------- +`etherscan.apikey.eth` | String | An Etherscan API key for querying Ethereum Mainnet | Yes +`etherscan.apikey.op` | String | An Etherscan API key for querying Optimism Mainnet | Yes +`rpc.url.eth` | String | This is any HTTP URL that can be used to query an Ethereum Mainnet RPC node | Yes +`rpc.url.op` | String | This is any HTTP URL that can be used to query an Optimism Mainnet RPC node | Yes + +# Using BindGen to Add New Preinstalls to L2 Genesis + +**Note** While we encourage hacking on the OP stack, we are not actively looking to integrate more contracts to the official OP stack genesis. + +BindGen uses the provided `contracts-list` to generate Go bindings and metadata files which are used when building the L2 genesis. The first step in adding a new preinstall to L2 genesis is adding the contract to your `contracts-list` (by default this list is [artifacts.json](../artifacts.json)). + +## Anatomy of `artifacts.json` + +Below is a condensed version of the default [artifacts.json](../artifacts.json) file for reference: + +```json +{ + "local": [ + "SystemConfig", + "L1CrossDomainMessenger", + + ... + + "StorageSetter", + "SuperchainConfig" + ], + "remote": [ + { + "name": "MultiCall3", + "verified": true, + "deployments": { + "eth": "0xcA11bde05977b3631167028862bE2a173976CA11", + "op": "0xcA11bde05977b3631167028862bE2a173976CA11" + } + }, + + ... + + { + "name": "EntryPoint", + "verified": true, + "deployments": { + "eth": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "op": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" + }, + "deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000" + } + ] +} +``` + +### `"local"` Contracts + +The first property of this JSON object, `"local"`, specifies the name of the contracts that have locally available Forge artifacts which BindGen will use to generate Go bindings and metadata files. This property specifies an array of strings where each string corresponds to the name of the contract which is used in the name of its corresponding Forge artifact. + +For example, the first contract listed in the default contract list is `SystemConfig`. After running `pnpm build` in the [contract-bedrock](../../packages/contracts-bedrock/), you'll have a [forge-artifacts](../../packages/contracts-bedrock/forge-artifacts/) directory where you can find [SystemConfig.sol](../../packages/contracts-bedrock/forge-artifacts/SystemConfig.sol/). Inside is the Forge artifacts BindGen will use to generate the Go bindings and metadata file. + +In some cases, such as `Safe`, there will exist multiple versioned Forge artifacts (e.g. [contracts-bedrock/forge-artifacts/Safe.sol/](../../packages/contracts-bedrock/forge-artifacts/Safe.sol/) contains `Safe.0.8.15.json` and `Safe.0.8.19.json`). In this case BindGen will default to using the lesser version (`Safe.0.8.19.json` in this case), and when running BindGen you will see a warning logged to the console to notify you: + +```bash +... +WARN [12-22|13:39:19.217] Multiple versions of forge artifacts exist, using lesser version contract=Safe +... +INFO [12-22|13:39:20.253] Generating bindings and metadata for local contract contract=Safe +``` + +### `"remote"` Contracts + +The second property specifies a list of `RemoteContract` objects which contain metadata used to fetch the needed contract info to generate Go bindings from Etherscan; these contracts do **not** have locally available Forge artifacts. + +There are a couple different variations of the `RemoteContract` object, but the following is the Go struct for reference: + +```go +type Deployments struct { + Eth common.Address `json:"eth"` + Op common.Address `json:"op"` +} + +type RemoteContract struct { + Name string `json:"name"` + Verified bool `json:"verified"` + Deployments Deployments `json:"deployments"` + DeploymentSalt string `json:"deploymentSalt"` + Deployer common.Address `json:"deployer"` + ABI string `json:"abi"` + InitBytecode string `json:"initBytecode"` +} +``` + +Name | Description +---------------------- | ----------- +`name` | The name of the remote contract that will be used for the Go bindings and metadata files +`verified` | Denotes whether the contract is verified on Etherscan +`deployments` | An object that maps a network and the address the contract is deployed to on that network +`deployments.eth` | The address the contract is deployed to on Ethereum Mainnet +`deployments.op` | The address the contract is deployed to on Optimism Mainnet +`deploymentSalt` | If the contract was deployed using CREATE2 or a CREATE2 proxy deployer, here is where you specify the salt that was used for creation +`deployer` | The address used to deploy the contract, used to mimic CREATE2 deployments +`abi` | The ABI of the contract, required if the contract is **not** verified on Etherscan +`initBytecode` | The initialization bytecode for the contract, required if the contract is a part of the initialization of another contract (i.e. the `input` data of the deployment transaction contains initialization bytecode other than what belongs to the specific contract you're adding) + +### Adding A New `"remote"` Contract + +After adding a `RemoteContract` object to your `contracts-list`, you will need to add the `name` of your contract to the `switch` statement found in the `processContracts` function in [generator_remote.go](./generator_remote.go): + +```go +... + +switch contract.Name { + case "MultiCall3", "Safe_v130", "SafeL2_v130", "MultiSendCallOnly_v130", + "EntryPoint", "SafeSingletonFactory", "DeterministicDeploymentProxy": + err = generator.standardHandler(&contractMetadata) + case "Create2Deployer": + err = generator.create2DeployerHandler(&contractMetadata) + case "MultiSend_v130": + err = generator.multiSendHandler(&contractMetadata) + case "SenderCreator": + // The SenderCreator contract is deployed by EntryPoint, so the transaction data + // from the deployment transaction is for the entire EntryPoint deployment. + // So, we're manually providing the initialization bytecode + contractMetadata.InitBin = contract.InitBytecode + err = generator.senderCreatorHandler(&contractMetadata) + case "Permit2": + // Permit2 has an immutable Solidity variable that resolves to block.chainid, + // so we can't use the deployed bytecode, and instead must generate it + // at some later point not handled by BindGen. + // DeployerAddress is intended to be used to help deploy Permit2 at it's deterministic address + // to a chain set with the required id to be able to obtain a diff minimized deployed bytecode + contractMetadata.Deployer = contract.Deployer + err = generator.permit2Handler(&contractMetadata) + default: + err = fmt.Errorf("unknown contract: %s, don't know how to handle it", contract.Name) + } + +... +``` + +If your contract is verified on Etherscan, doesn't contain any Solidity `immutable`s, and doesn't require any special handling, then you most likely can add your contract's `name` to the first switch case. Then will use the `standardHandler` which: + +1. Fetches the required contract metadata from Etherscan (i.e. initialization and deployed bytecode, ABI, deployment transaction hash, etc.) +2. Compares the retrieved deployed bytecode from Etherscan against the response of `eth_codeAt` from an RPC node for each network specified in `RemoteContract.deployments` (this is a sanity check to verify Etherscan is returning correct data) +3. If applicable, removes the provided `RemoteContract.deploymentSalt` from the initialization bytecode +4. Compares the initialization bytecode retrieved from Etherscan on Ethereum Mainnet against the bytecode retrieved from Etherscan on Optimism Mainnet + - This is an important sanity check! If the initialization bytecode from Ethereum differs from Optimism, then there's a big chance the deployment from Ethereum may not behave as expected if preinstalled to an OP stack L2 +5. Compares the deployment bytecode retrieved from Etherscan on Ethereum Mainnet against the bytecode retrieved from Etherscan on Optimism Mainnet + - This has the same concern as differing initialization bytecode +6. Lastly, the Go bindings are generated and the metadata file is written to the path provided as `metadata-out` CLI flag + +All other default `"remote"` contract have some variation of the above execution flow depending on the nuances of each contract. For example: + +- `Create2Deployer`'s initialization and deployed bytecode is expected to differ from its Optimism Mainnet deployment +- `MultiSend_v130` has an `immutable` Solidity variable the resolves to `address(this)`, so we can't use the deployment bytecode from Ethereum Mainnet, we must get its deployment bytecode from Optimism Mainnet +- `SenderCreator` is deployed by `EntryPoint`, so its initialization bytecode is provided in [artifacts.json](../artifacts.json) and not being fetched from Etherscan like other contracts + +#### Contracts that Don't Make Good Preinstalls + +Not every contract can be added as a preinstall, and some contracts have nuances that make them potentially dangerous or troublesome to preinstall. Below are some examples of contracts that wouldn't make good preinstalls. This is not a comprehensive list, so make sure to use judgment for each contract added as a preinstall. + +- Contracts that haven't been audited or stood the test of time + - Once a contract is preinstalled and a network is started, if a vulnerability is discovered for the contract and there is no way to easily disable the contract, the only options to "disable" the vulnerable contract are to either (A) remove it from the L2 genesis and restart the L2 network, (B) Hardfork the network to remove/replace the preinstall, or (C) Warn users not to use the vulnerable preinstall +- Related to above, contracts that may become deprecated/unsupported relatively soon + - As mentioned above, you're limited to options A, B, or C +- Upgradeable Contracts + - While it's certainly feasible to preinstall an upgradeable contract, great care should be taken to minimize security risks to users if the contract is upgraded to a malicious or buggy implementation. Understanding who has the ability to upgrade the contract is key to avoiding this. Additionally, users might be expecting a preinstall to do something and may be caught off guard if the implementation was upgraded without their knowledge +- Contracts with Privileged Roles and Configuration Parameters + - Similar to the upgradeable contracts, simply having an owner or other privileged role with the ability to make configuration changes can present a security risk and result in unexpected different behaviors across chains. +- Contracts that have dependencies + - Dependencies has many definitions, for example: + - Being reliant on specific Oracle contracts that may not be available on your L2 + - Specific contract state that's set on L1 but won't be on L2 + - Relying on specific values of block and transaction properties (e.g. `block.chainid`, `block.timestamp`, `block.number`, etc.) + - Contract libraries that may not be deployed on L2 + +### Adding the Contract to L2 Genesis + +Once you've configured the `contracts-list` to include the contracts you'd like to add as preinstalls, the next step is utilizing the BindGen outputs to configure the L2 genesis. + +1. First we must update the [addresses.go](../predeploys/addresses.go) file to include the address we're preinstalling our contracts to +1. Update the `switch` case found in [layer_two.go](../../op-chain-ops/genesis/layer_two.go) to include the `name` of your contracts +1. Update [immutables.go](../../op-chain-ops/immutables/immutables.go) to include your added contracts +1. Update [Predeploys.sol](../../packages/contracts-bedrock/src/libraries/Predeploys.sol) to include your added contracts at their expected addresses +1. Update [Predeploys.t.sol](../../packages/contracts-bedrock/test/Predeploys.t.sol) to include the `name` of your contracts to avoid being tested for `Predeploys.PROXY_ADMIN` diff --git a/op-bindings/bindgen/bindgen_header.png b/op-bindings/bindgen/bindgen_header.png new file mode 100644 index 000000000000..b8df6378ee73 Binary files /dev/null and b/op-bindings/bindgen/bindgen_header.png differ diff --git a/op-bindings/bindgen/fixtures_bytecode_test.go b/op-bindings/bindgen/fixtures_bytecode_test.go new file mode 100644 index 000000000000..c91f7ac76740 --- /dev/null +++ b/op-bindings/bindgen/fixtures_bytecode_test.go @@ -0,0 +1,10 @@ +package bindgen + +const Safe_v130InitBytecode = "0x0000000000000000000000000000000000000000000000000000000000000000608060405234801561001057600080fd5b5060016004819055506159ae80620000296000396000f3fe6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506127d7565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b81019080803590602001909291908035906020019092919050505061280d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b8101908080359060200190929190505050612894565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128ac565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612c3e565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d78565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506132b5565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506132da565b005b348015610d3457600080fd5b50610d3d613369565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613512565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613518565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061353a565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff1690602001909291905050506136f8565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613820565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613a12565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613bb1565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bde565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f6f565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ff3565b005b34801561148957600080fd5b50611492614665565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061466f565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614817565b005b3480156116a457600080fd5b506116ad614878565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506148f6565b005b34801561174a57600080fd5b50611753614d29565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612c3e565b5b5050565b611bd2604182614e0590919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614e3f565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614e0590919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614e6e90919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614e6e90919063ffffffff16565b614e6e90919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156126bc5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b61272e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61273b858585855a614e8d565b9050801561278b573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a26127cf565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b600060606127e7868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561282b57600080fd5b506040519080825280601f01601f19166020018201604052801561285e5781602001600182028036833780820191505090505b50905060005b8381101561288957808501548060208302602085010152508080600101915050612864565b508091505092915050565b60076020528060005260406000206000915090505481565b6128b4614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561291e5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612a91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612c46614d62565b600354811115612cbe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612d35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000806000612d928e8e8e8e8e8e8e8e8e8e60055461466f565b905060056000815480929190600101919050555080805190602001209150612dbb8282866132da565b506000612dc6614ed9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612fac578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612e6957fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015612f3b578082015181840152602081019050612f20565b50505050905090810190601f168015612f685780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015612f9357600080fd5b505af1158015612fa7573d6000803e3d6000fd5b505050505b6101f4612fd36109c48b01603f60408d0281612fc457fe5b04614f0a90919063ffffffff16565b015a1015613049576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506130b28f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d146130a7578e6130ad565b6109c45a035b614e8d565b93506130c75a82614f2490919063ffffffff16565b905083806130d6575060008a14155b806130e2575060008814155b613154576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008089111561316e5761316b828b8b8b8b614f44565b90505b84156131b8577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a16131f8565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146132a4578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561328b57600080fd5b505af115801561329f573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111613357576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61336384848484611bbe565b50505050565b6060600060035467ffffffffffffffff8111801561338657600080fd5b506040519080825280602002602001820160405280156133b55781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613509578083838151811061346057fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061341f565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6135858a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508961514a565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146135c3576135c28461564a565b5b6136118787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615679565b600082111561362b5761362982600060018685614f44565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061374f878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a614e8d565b61375857600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156137e55780820151818401526020810190506137ca565b50505050905090810190601f1680156138125780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561383b57600080fd5b5060405190808252806020026020018201604052801561386a5781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561393d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561394857508482105b15613a03578084838151811061395a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506138d3565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613b14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613bc68c8c8c8c8c8c8c8c8c8c8c61466f565b8051906020012090509b9a5050505050505050505050565b613be6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c505750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613cc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613dc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f77614d62565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613ffb614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156140655750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561409d57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61410f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614210576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561427a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6142ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561470057fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b61478c614878565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61481f614d62565b6148288161564a565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6148a66125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b6148fe614d62565b806001600354031015614979576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156149e35750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614b55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614d2457614d2381612c3e565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614e03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614e185760009050614e39565b6000828402905082848281614e2957fe5b0414614e3457600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614e8357600080fd5b8091505092915050565b6000600180811115614e9b57fe5b836001811115614ea757fe5b1415614ec0576000808551602087018986f49050614ed0565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015614f1a5781614f1c565b825b905092915050565b600082821115614f3357600080fd5b600082840390508091505092915050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614614f815782614f83565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561509b57614fed3a8610614fca573a614fcc565b855b614fdf888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615096576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615140565b6150c0856150b2888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91506150cd8482846158b4565b61513f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600454146151c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615239576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156152b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156155b65760008482815181106152d057fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153445750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561537c57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156153b457508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b615426576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506152b9565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461577b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146158b05761583d8260008360015a614e8d565b6158af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d6000811461595b5760208114615963576000935061596e565b81935061596e565b600051158215171593505b505050939250505056fea26469706673582212203874bcf92e1722cc7bfa0cef1a0985cf0dc3485ba0663db3747ccdf1605df53464736f6c63430007060033" +const Safe_v130InitBytecodeNoSalt = "608060405234801561001057600080fd5b5060016004819055506159ae80620000296000396000f3fe6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506127d7565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b81019080803590602001909291908035906020019092919050505061280d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b8101908080359060200190929190505050612894565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128ac565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612c3e565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d78565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506132b5565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506132da565b005b348015610d3457600080fd5b50610d3d613369565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613512565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613518565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061353a565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff1690602001909291905050506136f8565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613820565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613a12565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613bb1565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bde565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f6f565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ff3565b005b34801561148957600080fd5b50611492614665565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061466f565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614817565b005b3480156116a457600080fd5b506116ad614878565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506148f6565b005b34801561174a57600080fd5b50611753614d29565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612c3e565b5b5050565b611bd2604182614e0590919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614e3f565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614e0590919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614e6e90919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614e6e90919063ffffffff16565b614e6e90919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156126bc5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b61272e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61273b858585855a614e8d565b9050801561278b573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a26127cf565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b600060606127e7868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561282b57600080fd5b506040519080825280601f01601f19166020018201604052801561285e5781602001600182028036833780820191505090505b50905060005b8381101561288957808501548060208302602085010152508080600101915050612864565b508091505092915050565b60076020528060005260406000206000915090505481565b6128b4614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561291e5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612a91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612c46614d62565b600354811115612cbe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612d35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000806000612d928e8e8e8e8e8e8e8e8e8e60055461466f565b905060056000815480929190600101919050555080805190602001209150612dbb8282866132da565b506000612dc6614ed9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612fac578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612e6957fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015612f3b578082015181840152602081019050612f20565b50505050905090810190601f168015612f685780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015612f9357600080fd5b505af1158015612fa7573d6000803e3d6000fd5b505050505b6101f4612fd36109c48b01603f60408d0281612fc457fe5b04614f0a90919063ffffffff16565b015a1015613049576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506130b28f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d146130a7578e6130ad565b6109c45a035b614e8d565b93506130c75a82614f2490919063ffffffff16565b905083806130d6575060008a14155b806130e2575060008814155b613154576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008089111561316e5761316b828b8b8b8b614f44565b90505b84156131b8577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a16131f8565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146132a4578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561328b57600080fd5b505af115801561329f573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111613357576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61336384848484611bbe565b50505050565b6060600060035467ffffffffffffffff8111801561338657600080fd5b506040519080825280602002602001820160405280156133b55781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613509578083838151811061346057fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061341f565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6135858a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508961514a565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146135c3576135c28461564a565b5b6136118787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615679565b600082111561362b5761362982600060018685614f44565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061374f878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a614e8d565b61375857600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156137e55780820151818401526020810190506137ca565b50505050905090810190601f1680156138125780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561383b57600080fd5b5060405190808252806020026020018201604052801561386a5781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561393d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561394857508482105b15613a03578084838151811061395a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506138d3565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613b14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613bc68c8c8c8c8c8c8c8c8c8c8c61466f565b8051906020012090509b9a5050505050505050505050565b613be6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c505750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613cc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613dc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f77614d62565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613ffb614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156140655750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561409d57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61410f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614210576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561427a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6142ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561470057fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b61478c614878565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61481f614d62565b6148288161564a565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6148a66125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b6148fe614d62565b806001600354031015614979576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156149e35750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614b55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614d2457614d2381612c3e565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614e03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614e185760009050614e39565b6000828402905082848281614e2957fe5b0414614e3457600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614e8357600080fd5b8091505092915050565b6000600180811115614e9b57fe5b836001811115614ea757fe5b1415614ec0576000808551602087018986f49050614ed0565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015614f1a5781614f1c565b825b905092915050565b600082821115614f3357600080fd5b600082840390508091505092915050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614614f815782614f83565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561509b57614fed3a8610614fca573a614fcc565b855b614fdf888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615096576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615140565b6150c0856150b2888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91506150cd8482846158b4565b61513f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600454146151c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615239576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156152b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156155b65760008482815181106152d057fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153445750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561537c57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156153b457508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b615426576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506152b9565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461577b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146158b05761583d8260008360015a614e8d565b6158af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d6000811461595b5760208114615963576000935061596e565b81935061596e565b600051158215171593505b505050939250505056fea26469706673582212203874bcf92e1722cc7bfa0cef1a0985cf0dc3485ba0663db3747ccdf1605df53464736f6c63430007060033" + +const Permit2InitBytecode = "0x0000000000000000000000000000000000000000d3af2663da51c1021500000060c0346100bb574660a052602081017f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a60408301524660608301523060808301526080825260a082019180831060018060401b038411176100a557826040525190206080526123c090816100c1823960805181611b47015260a05181611b210152f35b634e487b7160e01b600052604160045260246000fd5b600080fdfe6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000003611b69577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a" +const Permit2InitBytecodeNoSalt = "60c0346100bb574660a052602081017f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a60408301524660608301523060808301526080825260a082019180831060018060401b038411176100a557826040525190206080526123c090816100c1823960805181611b47015260a05181611b210152f35b634e487b7160e01b600052604160045260246000fd5b600080fdfe6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000003611b69577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a" + +const EntryPointInitBytecode = "0x000000000000000000000000000000000000000000000000000000000000000060a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033" +const EntryPointInitBytecodeNoSalt = "60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033" diff --git a/op-bindings/bindgen/fixtures_test.go b/op-bindings/bindgen/fixtures_test.go new file mode 100644 index 000000000000..8234dd3f1dda --- /dev/null +++ b/op-bindings/bindgen/fixtures_test.go @@ -0,0 +1,50 @@ +package bindgen + +// The Init bytecode used for these tests can either be sourced +// on-chain using the deployment tx of these contracts, or can be +// found in the bindings output from BindGen (../bindings/) +var removeDeploymentSaltTests = []struct { + name string + deploymentData string + deploymentSalt string + expected string +}{ + { + "Case #1", + Safe_v130InitBytecode, + "0000000000000000000000000000000000000000000000000000000000000000", + Safe_v130InitBytecodeNoSalt, + }, + { + "Case #2", + Permit2InitBytecode, + "0000000000000000000000000000000000000000d3af2663da51c10215000000", + Permit2InitBytecodeNoSalt, + }, + { + "Case #3", + EntryPointInitBytecode, + "0000000000000000000000000000000000000000000000000000000000000000", + EntryPointInitBytecodeNoSalt, + }, +} + +var removeDeploymentSaltTestsFailures = []struct { + name string + deploymentData string + deploymentSalt string + expectedError string +}{ + { + "Failure Case #1 Invalid Regex", + "0x1234abc", + "[invalid-regex", + "failed to compile regular expression: error parsing regexp: missing closing ]: `[invalid-regex)`", + }, + { + "Failure Case #2 Salt Not Found", + "0x1234abc", + "4567", + "expected salt: 4567 to be at the beginning of the contract initialization code: 0x1234abc, but it wasn't", + }, +} diff --git a/op-bindings/bindgen/generator_local.go b/op-bindings/bindgen/generator_local.go new file mode 100644 index 000000000000..26f69822e26e --- /dev/null +++ b/op-bindings/bindgen/generator_local.go @@ -0,0 +1,253 @@ +package bindgen + +import ( + "encoding/json" + "errors" + "fmt" + "os" + "path" + "path/filepath" + "regexp" + "strings" + "text/template" + + "github.com/ethereum-optimism/optimism/op-bindings/ast" + "github.com/ethereum-optimism/optimism/op-bindings/foundry" +) + +type BindGenGeneratorLocal struct { + BindGenGeneratorBase + SourceMapsList string + ForgeArtifactsPath string +} + +type localContractMetadata struct { + Name string + StorageLayout string + DeployedBin string + Package string + DeployedSourceMap string + HasImmutableReferences bool +} + +func (generator *BindGenGeneratorLocal) GenerateBindings() error { + contracts, err := readContractList(generator.Logger, generator.ContractsListPath) + if err != nil { + return fmt.Errorf("error reading contract list %s: %w", generator.ContractsListPath, err) + } + if len(contracts.Local) == 0 { + return fmt.Errorf("no contracts parsed from given contract list: %s", generator.ContractsListPath) + } + + return generator.processContracts(contracts.Local) +} + +func (generator *BindGenGeneratorLocal) processContracts(contracts []string) error { + tempArtifactsDir, err := mkTempArtifactsDir(generator.Logger) + if err != nil { + return err + } + defer func() { + err := os.RemoveAll(tempArtifactsDir) + if err != nil { + generator.Logger.Error("Error removing temporary artifact directory", "path", tempArtifactsDir, "err", err.Error()) + } else { + generator.Logger.Debug("Successfully removed temporary artifact directory") + } + }() + + sourceMapsList := strings.Split(generator.SourceMapsList, ",") + sourceMapsSet := make(map[string]struct{}) + for _, k := range sourceMapsList { + sourceMapsSet[k] = struct{}{} + } + + contractArtifactPaths, err := generator.getContractArtifactPaths() + if err != nil { + return err + } + + contractMetadataFileTemplate := template.Must(template.New("localContractMetadata").Parse(localContractMetadataTemplate)) + + for _, contractName := range contracts { + generator.Logger.Info("Generating bindings and metadata for local contract", "contract", contractName) + + forgeArtifact, err := generator.readForgeArtifact(contractName, contractArtifactPaths) + if err != nil { + return err + } + + abiFilePath, bytecodeFilePath, err := writeContractArtifacts(generator.Logger, tempArtifactsDir, contractName, forgeArtifact.Abi, []byte(forgeArtifact.Bytecode.Object.String())) + if err != nil { + return err + } + + err = genContractBindings(generator.Logger, generator.MonorepoBasePath, abiFilePath, bytecodeFilePath, generator.BindingsPackageName, contractName) + if err != nil { + return err + } + + deployedSourceMap, canonicalStorageStr, err := generator.canonicalizeStorageLayout(forgeArtifact, sourceMapsSet, contractName) + if err != nil { + return err + } + + re := regexp.MustCompile(`\s+`) + immutableRefs, err := json.Marshal(re.ReplaceAllString(string(forgeArtifact.DeployedBytecode.ImmutableReferences), "")) + if err != nil { + return fmt.Errorf("error marshaling immutable references: %w", err) + } + + hasImmutables := string(immutableRefs) != `""` + + contractMetaData := localContractMetadata{ + Name: contractName, + StorageLayout: canonicalStorageStr, + DeployedBin: forgeArtifact.DeployedBytecode.Object.String(), + Package: generator.BindingsPackageName, + DeployedSourceMap: deployedSourceMap, + HasImmutableReferences: hasImmutables, + } + + if err := generator.writeContractMetadata(contractMetaData, contractName, contractMetadataFileTemplate); err != nil { + return err + } + } + + return nil +} + +func (generator *BindGenGeneratorLocal) getContractArtifactPaths() (map[string]string, error) { + // If some contracts have the same name then the path to their + // artifact depends on their full import path. Scan over all artifacts + // and hold a mapping from the contract name to the contract path. + // Walk walks the directory deterministically, so the earliest instance + // of the contract with the same name will be used + artifactPaths := make(map[string]string) + if err := filepath.Walk(generator.ForgeArtifactsPath, + func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if strings.HasSuffix(path, ".json") { + base := filepath.Base(path) + name := strings.TrimSuffix(base, ".json") + + // remove the compiler version from the name + re := regexp.MustCompile(`\.\d+\.\d+\.\d+`) + sanitized := re.ReplaceAllString(name, "") + _, ok := artifactPaths[sanitized] + if !ok { + artifactPaths[sanitized] = path + } else { + generator.Logger.Warn("Multiple versions of forge artifacts exist, using lesser version", "contract", sanitized) + } + } + return nil + }); err != nil { + return artifactPaths, err + } + + return artifactPaths, nil +} + +func (generator *BindGenGeneratorLocal) readForgeArtifact(contractName string, contractArtifactPaths map[string]string) (foundry.Artifact, error) { + var forgeArtifact foundry.Artifact + + contractArtifactPath := path.Join(generator.ForgeArtifactsPath, contractName+".sol", contractName+".json") + forgeArtifactRaw, err := os.ReadFile(contractArtifactPath) + if errors.Is(err, os.ErrNotExist) { + generator.Logger.Debug("Cannot find forge-artifact at standard path, trying provided path", "contract", contractName, "standardPath", contractArtifactPath, "providedPath", contractArtifactPaths[contractName]) + contractArtifactPath = contractArtifactPaths[contractName] + forgeArtifactRaw, err = os.ReadFile(contractArtifactPath) + if errors.Is(err, os.ErrNotExist) { + return forgeArtifact, fmt.Errorf("cannot find forge-artifact of %q", contractName) + } + } + + generator.Logger.Debug("Using forge-artifact", "path", contractArtifactPath) + if err := json.Unmarshal(forgeArtifactRaw, &forgeArtifact); err != nil { + return forgeArtifact, fmt.Errorf("failed to parse forge artifact of %q: %w", contractName, err) + } + + return forgeArtifact, nil +} + +func (generator *BindGenGeneratorLocal) canonicalizeStorageLayout(forgeArtifact foundry.Artifact, sourceMapsSet map[string]struct{}, contractName string) (string, string, error) { + artifactStorageStruct := forgeArtifact.StorageLayout + canonicalStorageStruct := ast.CanonicalizeASTIDs(&artifactStorageStruct, generator.MonorepoBasePath) + canonicalStorageJson, err := json.Marshal(canonicalStorageStruct) + if err != nil { + return "", "", fmt.Errorf("error marshaling canonical storage: %w", err) + } + canonicalStorageStr := strings.Replace(string(canonicalStorageJson), "\"", "\\\"", -1) + + deployedSourceMap := "" + if _, ok := sourceMapsSet[contractName]; ok { + deployedSourceMap = forgeArtifact.DeployedBytecode.SourceMap + } + + return deployedSourceMap, canonicalStorageStr, nil +} + +func (generator *BindGenGeneratorLocal) writeContractMetadata(contractMetaData localContractMetadata, contractName string, fileTemplate *template.Template) error { + metadataFilePath := filepath.Join(generator.MetadataOut, strings.ToLower(contractName)+"_more.go") + metadataFile, err := os.OpenFile( + metadataFilePath, + os.O_RDWR|os.O_CREATE|os.O_TRUNC, + 0o600, + ) + if err != nil { + return fmt.Errorf("error opening %s's metadata file at %s: %w", contractName, metadataFilePath, err) + } + defer metadataFile.Close() + + if err := fileTemplate.Execute(metadataFile, contractMetaData); err != nil { + return fmt.Errorf("error writing %s's contract metadata at %s: %w", contractName, metadataFilePath, err) + } + + generator.Logger.Debug("Successfully wrote contract metadata", "contract", contractName, "path", metadataFilePath) + return nil +} + +// associated with a local Ethereum contract. This template is used to produce +// Go code containing necessary constants and initialization logic for the contract's +// storage layout, deployed bytecode, and optionally its deployed source map. +// +// The template expects the following fields to be provided: +// - Package: The name of the Go package for the generated bindings. +// - Name: The name of the contract. +// - StorageLayout: Canonicalized storage layout of the contract as a JSON string. +// - DeployedBin: The deployed bytecode of the contract. +// - DeployedSourceMap (optional): The source map of the deployed contract. +var localContractMetadataTemplate = `// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package {{.Package}} + +import ( + "encoding/json" + + "github.com/ethereum-optimism/optimism/op-bindings/solc" +) + +const {{.Name}}StorageLayoutJSON = "{{.StorageLayout}}" + +var {{.Name}}StorageLayout = new(solc.StorageLayout) + +var {{.Name}}DeployedBin = "{{.DeployedBin}}" +{{if .DeployedSourceMap}} +var {{.Name}}DeployedSourceMap = "{{.DeployedSourceMap}}" +{{end}} + +func init() { + if err := json.Unmarshal([]byte({{.Name}}StorageLayoutJSON), {{.Name}}StorageLayout); err != nil { + panic(err) + } + + layouts["{{.Name}}"] = {{.Name}}StorageLayout + deployedBytecodes["{{.Name}}"] = {{.Name}}DeployedBin + immutableReferences["{{.Name}}"] = {{.HasImmutableReferences}} +} +` diff --git a/op-bindings/bindgen/generator_remote.go b/op-bindings/bindgen/generator_remote.go new file mode 100644 index 000000000000..43c073d19b38 --- /dev/null +++ b/op-bindings/bindgen/generator_remote.go @@ -0,0 +1,129 @@ +package bindgen + +import ( + "context" + "fmt" + "os" + + "github.com/ethereum-optimism/optimism/op-bindings/etherscan" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" +) + +type BindGenGeneratorRemote struct { + BindGenGeneratorBase + ContractDataClients struct { + Eth contractDataClient + Op contractDataClient + } + RpcClients struct { + Eth *ethclient.Client + Op *ethclient.Client + } + tempArtifactsDir string +} + +type contractDataClient interface { + FetchAbi(ctx context.Context, address string) (string, error) + FetchDeployedBytecode(ctx context.Context, address string) (string, error) + FetchDeploymentTxHash(ctx context.Context, address string) (string, error) + FetchDeploymentTx(ctx context.Context, txHash string) (etherscan.Transaction, error) +} + +type Deployments struct { + Eth common.Address `json:"eth"` + Op common.Address `json:"op"` +} + +type RemoteContract struct { + Name string `json:"name"` + Verified bool `json:"verified"` + Deployments Deployments `json:"deployments"` + DeploymentSalt string `json:"deploymentSalt"` + Deployer common.Address `json:"deployer"` + ABI string `json:"abi"` + InitBytecode string `json:"initBytecode"` +} + +type RemoteContractMetadata struct { + RemoteContract + Package string + InitBin string + DeployedBin string +} + +func (generator *BindGenGeneratorRemote) GenerateBindings() error { + contracts, err := readContractList(generator.Logger, generator.ContractsListPath) + if err != nil { + return fmt.Errorf("error reading contract list %s: %w", generator.ContractsListPath, err) + } + if len(contracts.Remote) == 0 { + return fmt.Errorf("no contracts parsed from given contract list: %s", generator.ContractsListPath) + } + + return generator.processContracts(contracts.Remote) +} + +func (generator *BindGenGeneratorRemote) processContracts(contracts []RemoteContract) error { + var err error + generator.tempArtifactsDir, err = mkTempArtifactsDir(generator.Logger) + if err != nil { + return err + } + defer func() { + err := os.RemoveAll(generator.tempArtifactsDir) + if err != nil { + generator.Logger.Error("Error removing temporary artifact directory", "path", generator.tempArtifactsDir, "err", err.Error()) + } else { + generator.Logger.Debug("Successfully removed temporary artifact directory") + } + }() + + for _, contract := range contracts { + generator.Logger.Info("Generating bindings and metadata for remote contract", "contract", contract.Name) + + contractMetadata := RemoteContractMetadata{ + RemoteContract: RemoteContract{ + Name: contract.Name, + Deployments: contract.Deployments, + DeploymentSalt: contract.DeploymentSalt, + ABI: contract.ABI, + Verified: contract.Verified, + }, + Package: generator.BindingsPackageName, + } + + var err error + switch contract.Name { + case "MultiCall3", "Safe_v130", "SafeL2_v130", "MultiSendCallOnly_v130", + "EntryPoint", "SafeSingletonFactory", "DeterministicDeploymentProxy": + err = generator.standardHandler(&contractMetadata) + case "Create2Deployer": + err = generator.create2DeployerHandler(&contractMetadata) + case "MultiSend_v130": + err = generator.multiSendHandler(&contractMetadata) + case "SenderCreator": + // The SenderCreator contract is deployed by EntryPoint, so the transaction data + // from the deployment transaction is for the entire EntryPoint deployment. + // So, we're manually providing the initialization bytecode + contractMetadata.InitBin = contract.InitBytecode + err = generator.senderCreatorHandler(&contractMetadata) + case "Permit2": + // Permit2 has an immutable Solidity variable that resolves to block.chainid, + // so we can't use the deployed bytecode, and instead must generate it + // at some later point not handled by BindGen. + // DeployerAddress is intended to be used to help deploy Permit2 at it's deterministic address + // to a chain set with the required id to be able to obtain a diff minimized deployed bytecode + contractMetadata.Deployer = contract.Deployer + err = generator.permit2Handler(&contractMetadata) + default: + err = fmt.Errorf("unknown contract: %s, don't know how to handle it", contract.Name) + } + + if err != nil { + return err + } + } + + return nil +} diff --git a/op-bindings/bindgen/remote_handlers.go b/op-bindings/bindgen/remote_handlers.go new file mode 100644 index 000000000000..380f0d5e21b7 --- /dev/null +++ b/op-bindings/bindgen/remote_handlers.go @@ -0,0 +1,444 @@ +package bindgen + +import ( + "bytes" + "context" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + "text/template" + + "github.com/ethereum-optimism/optimism/op-bindings/etherscan" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" +) + +type ContractData struct { + Abi string + DeployedBin string + DeploymentTx etherscan.Transaction +} + +func (generator *BindGenGeneratorRemote) standardHandler(contractMetadata *RemoteContractMetadata) error { + fetchedData, err := generator.FetchContractData(contractMetadata.Verified, "eth", contractMetadata.Deployments.Eth.Hex()) + if err != nil { + return err + } + + contractMetadata.DeployedBin = fetchedData.DeployedBin + if err = generator.CompareDeployedBytecodeWithRpc(contractMetadata, "eth"); err != nil { + return err + } + if err = generator.CompareDeployedBytecodeWithRpc(contractMetadata, "op"); err != nil { + return err + } + + // If ABI was explicitly provided by config, don't overwrite + if contractMetadata.ABI == "" { + contractMetadata.ABI = fetchedData.Abi + } else if fetchedData.Abi != "" && contractMetadata.ABI != fetchedData.Abi { + generator.Logger.Debug("ABIs", "given", contractMetadata.ABI, "fetched", fetchedData.Abi) + return fmt.Errorf("the given ABI for %s differs from what was fetched from Etherscan", contractMetadata.Name) + } + + if contractMetadata.InitBin, err = generator.removeDeploymentSalt(fetchedData.DeploymentTx.Input, contractMetadata.DeploymentSalt); err != nil { + return err + } + + if err := generator.CompareInitBytecodeWithOp(contractMetadata, true); err != nil { + return fmt.Errorf("%s: %w", contractMetadata.Name, err) + } + if err := generator.CompareDeployedBytecodeWithOp(contractMetadata, true); err != nil { + return fmt.Errorf("%s: %w", contractMetadata.Name, err) + } + + return generator.writeAllOutputs(contractMetadata, remoteContractMetadataTemplate) +} + +func (generator *BindGenGeneratorRemote) create2DeployerHandler(contractMetadata *RemoteContractMetadata) error { + fetchedData, err := generator.FetchContractData(contractMetadata.Verified, "eth", contractMetadata.Deployments.Eth.Hex()) + if err != nil { + return err + } + + contractMetadata.ABI = fetchedData.Abi + contractMetadata.DeployedBin = fetchedData.DeployedBin + if contractMetadata.InitBin, err = generator.removeDeploymentSalt(fetchedData.DeploymentTx.Input, contractMetadata.DeploymentSalt); err != nil { + return err + } + + // We're expecting the initialization bytecode for Create2Deployer to not match the init code on OP, + // because the deployment on OP has been overwritten by the Canyon hardfork, and the init code + // Etherscan returns for the OP deployment is from the initial outdated deployment. + // For context: https://github.com/ethereum-optimism/op-geth/pull/126 + if err := generator.CompareInitBytecodeWithOp(contractMetadata, false); err != nil { + return fmt.Errorf("%s: %w", contractMetadata.Name, err) + } + if err := generator.CompareDeployedBytecodeWithOp(contractMetadata, true); err != nil { + return fmt.Errorf("%s: %w", contractMetadata.Name, err) + } + + return generator.writeAllOutputs(contractMetadata, remoteContractMetadataTemplate) +} + +func (generator *BindGenGeneratorRemote) multiSendHandler(contractMetadata *RemoteContractMetadata) error { + // MultiSend has an immutable that resolves to this(address). + // Because we're predeploying MultiSend to the same address as on OP, + // we can use the deployed bytecode directly for the predeploy + fetchedData, err := generator.FetchContractData(contractMetadata.Verified, "op", contractMetadata.Deployments.Op.Hex()) + if err != nil { + return err + } + + contractMetadata.ABI = fetchedData.Abi + contractMetadata.DeployedBin = fetchedData.DeployedBin + if err = generator.CompareDeployedBytecodeWithRpc(contractMetadata, "op"); err != nil { + return err + } + if contractMetadata.InitBin, err = generator.removeDeploymentSalt(fetchedData.DeploymentTx.Input, contractMetadata.DeploymentSalt); err != nil { + return err + } + + return generator.writeAllOutputs(contractMetadata, remoteContractMetadataTemplate) +} + +func (generator *BindGenGeneratorRemote) senderCreatorHandler(contractMetadata *RemoteContractMetadata) error { + var err error + contractMetadata.DeployedBin, err = generator.ContractDataClients.Eth.FetchDeployedBytecode(context.Background(), contractMetadata.Deployments.Eth.Hex()) + if err != nil { + return fmt.Errorf("error fetching deployed bytecode: %w", err) + } + if err = generator.CompareDeployedBytecodeWithRpc(contractMetadata, "eth"); err != nil { + return err + } + if err = generator.CompareDeployedBytecodeWithRpc(contractMetadata, "op"); err != nil { + return err + } + + // The SenderCreator contract is deployed by EntryPoint, so the transaction data + // from the deployment transaction is for the entire EntryPoint deployment. + // So, we're manually providing the initialization bytecode and therefore it isn't being compared here + if err := generator.CompareInitBytecodeWithOp(contractMetadata, false); err != nil { + return fmt.Errorf("%s: %w", contractMetadata.Name, err) + } + if err := generator.CompareDeployedBytecodeWithOp(contractMetadata, true); err != nil { + return fmt.Errorf("%s: %w", contractMetadata.Name, err) + } + + return generator.writeAllOutputs(contractMetadata, remoteContractMetadataTemplate) +} + +func (generator *BindGenGeneratorRemote) permit2Handler(contractMetadata *RemoteContractMetadata) error { + fetchedData, err := generator.FetchContractData(contractMetadata.Verified, "eth", contractMetadata.Deployments.Eth.Hex()) + if err != nil { + return err + } + + contractMetadata.ABI = fetchedData.Abi + contractMetadata.DeployedBin = fetchedData.DeployedBin + if contractMetadata.InitBin, err = generator.removeDeploymentSalt(fetchedData.DeploymentTx.Input, contractMetadata.DeploymentSalt); err != nil { + return err + } + + if !strings.EqualFold(contractMetadata.Deployer.Hex(), fetchedData.DeploymentTx.To) { + return fmt.Errorf( + "expected deployer address: %s doesn't match the to address: %s for Permit2's proxy deployment transaction", + contractMetadata.Deployer.Hex(), + fetchedData.DeploymentTx.To, + ) + } + + if err := generator.CompareInitBytecodeWithOp(contractMetadata, true); err != nil { + return fmt.Errorf("%s: %w", contractMetadata.Name, err) + } + // We're asserting the deployed bytecode doesn't match, because Permit2 has immutable Solidity variables that + // are dependent on block.chainid + if err := generator.CompareDeployedBytecodeWithOp(contractMetadata, false); err != nil { + return fmt.Errorf("%s: %w", contractMetadata.Name, err) + } + + return generator.writeAllOutputs(contractMetadata, permit2MetadataTemplate) +} + +func (generator *BindGenGeneratorRemote) FetchContractData(contractVerified bool, chain, deploymentAddress string) (ContractData, error) { + var data ContractData + var err error + + var client contractDataClient + switch chain { + case "eth": + client = generator.ContractDataClients.Eth + case "op": + client = generator.ContractDataClients.Op + default: + return data, fmt.Errorf("unknown chain, unable to retrieve a contract data client for chain: %s", chain) + } + + if contractVerified { + data.Abi, err = client.FetchAbi(context.Background(), deploymentAddress) + if err != nil { + return ContractData{}, fmt.Errorf("error fetching ABI: %w", err) + } + } + + data.DeployedBin, err = client.FetchDeployedBytecode(context.Background(), deploymentAddress) + if err != nil { + return ContractData{}, fmt.Errorf("error fetching deployed bytecode: %w", err) + } + + deploymentTxHash, err := client.FetchDeploymentTxHash(context.Background(), deploymentAddress) + if err != nil { + return ContractData{}, fmt.Errorf("error fetching deployment transaction hash: %w", err) + } + + data.DeploymentTx, err = client.FetchDeploymentTx(context.Background(), deploymentTxHash) + if err != nil { + return ContractData{}, fmt.Errorf("error fetching deployment transaction data: %w", err) + } + + return data, nil +} + +func (generator *BindGenGeneratorRemote) removeDeploymentSalt(deploymentData, deploymentSalt string) (string, error) { + if deploymentSalt == "" { + return deploymentData, nil + } + + re, err := regexp.Compile(fmt.Sprintf("^0x(%s)", deploymentSalt)) + if err != nil { + return "", fmt.Errorf("failed to compile regular expression: %w", err) + } + if !re.MatchString(deploymentData) { + return "", fmt.Errorf( + "expected salt: %s to be at the beginning of the contract initialization code: %s, but it wasn't", + deploymentSalt, deploymentData, + ) + } + return re.ReplaceAllString(deploymentData, ""), nil +} + +func (generator *BindGenGeneratorRemote) CompareInitBytecodeWithOp(contractMetadataEth *RemoteContractMetadata, initCodeShouldMatch bool) error { + if contractMetadataEth.InitBin == "" { + return fmt.Errorf("no initialization bytecode provided for ETH deployment for comparison") + } + + var zeroAddress common.Address + if contractMetadataEth.Deployments.Op == zeroAddress { + return fmt.Errorf("no deployment address on Optimism provided for %s", contractMetadataEth.Name) + } + + // Passing false here, because true will retrieve contract's ABI, but we don't need it for bytecode comparison + opContractData, err := generator.FetchContractData(false, "op", contractMetadataEth.Deployments.Op.Hex()) + if err != nil { + return err + } + + if opContractData.DeploymentTx.Input, err = generator.removeDeploymentSalt(opContractData.DeploymentTx.Input, contractMetadataEth.DeploymentSalt); err != nil { + return err + } + + initCodeComparison := strings.EqualFold(contractMetadataEth.InitBin, opContractData.DeploymentTx.Input) + if initCodeShouldMatch && !initCodeComparison { + return fmt.Errorf( + "expected initialization bytecode to match on Ethereum and Optimism, but it doesn't. contract=%s bytecodeEth=%s bytecodeOp=%s", + contractMetadataEth.Name, + contractMetadataEth.InitBin, + opContractData.DeploymentTx.Input, + ) + } else if !initCodeShouldMatch && initCodeComparison { + return fmt.Errorf( + "expected initialization bytecode on Ethereum to not match on Optimism, but it did. contract=%s bytecodeEth=%s bytecodeOp=%s", + contractMetadataEth.Name, + contractMetadataEth.InitBin, + opContractData.DeploymentTx.Input, + ) + } + + return nil +} + +func (generator *BindGenGeneratorRemote) CompareDeployedBytecodeWithOp(contractMetadataEth *RemoteContractMetadata, deployedCodeShouldMatch bool) error { + if contractMetadataEth.DeployedBin == "" { + return fmt.Errorf("no deployed bytecode provided for ETH deployment for comparison") + } + + var zeroAddress common.Address + if contractMetadataEth.Deployments.Op == zeroAddress { + return fmt.Errorf("no deployment address on Optimism provided for %s", contractMetadataEth.Name) + } + + // Passing false here, because true will retrieve contract's ABI, but we don't need it for bytecode comparison + opContractData, err := generator.FetchContractData(false, "op", contractMetadataEth.Deployments.Op.Hex()) + if err != nil { + return err + } + + deployedCodeComparison := strings.EqualFold(contractMetadataEth.DeployedBin, opContractData.DeployedBin) + if deployedCodeShouldMatch && !deployedCodeComparison { + return fmt.Errorf( + "expected deployed bytecode to match on Ethereum and Optimism, but it doesn't. contract=%s bytecodeEth=%s bytecodeOp=%s", + contractMetadataEth.Name, + contractMetadataEth.DeployedBin, + opContractData.DeployedBin, + ) + } else if !deployedCodeShouldMatch && deployedCodeComparison { + return fmt.Errorf( + "expected deployed bytecode on Ethereum to not match on Optimism, but it does. contract=%s bytecodeEth=%s bytecodeOp=%s", + contractMetadataEth.Name, + contractMetadataEth.DeployedBin, + opContractData.DeployedBin, + ) + } + + return nil +} + +func (generator *BindGenGeneratorRemote) CompareDeployedBytecodeWithRpc(contractMetadata *RemoteContractMetadata, chain string) error { + var client *ethclient.Client + switch chain { + case "eth": + client = generator.RpcClients.Eth + case "op": + client = generator.RpcClients.Op + default: + return fmt.Errorf("unknown chain: %s, unable to retrieve a RPC client", chain) + } + + var deployment common.Address + switch chain { + case "eth": + deployment = contractMetadata.Deployments.Eth + case "op": + deployment = contractMetadata.Deployments.Op + default: + generator.Logger.Warn("Unable to compare bytecode from Etherscan against RPC client, no deployment address provided for chain", "chain", chain) + } + + if deployment != (common.Address{}) { + bytecode, err := client.CodeAt(context.Background(), common.HexToAddress(deployment.Hex()), nil) + if err != nil { + return fmt.Errorf("error getting deployed bytecode from RPC on chain: %s err: %w", chain, err) + } + bytecodeHex := common.Bytes2Hex(bytecode) + if !strings.EqualFold(strings.TrimPrefix(contractMetadata.DeployedBin, "0x"), bytecodeHex) { + return fmt.Errorf("%s deployment bytecode from RPC doesn't match bytecode from Etherscan. rpcBytecode: %s etherscanBytecode: %s", contractMetadata.Name, bytecodeHex, contractMetadata.DeployedBin) + } + } + + return nil +} + +func (generator *BindGenGeneratorRemote) writeAllOutputs(contractMetadata *RemoteContractMetadata, fileTemplate string) error { + abiFilePath, bytecodeFilePath, err := writeContractArtifacts( + generator.Logger, generator.tempArtifactsDir, contractMetadata.Name, + []byte(contractMetadata.ABI), []byte(contractMetadata.InitBin), + ) + if err != nil { + return err + } + + err = genContractBindings(generator.Logger, generator.MonorepoBasePath, abiFilePath, bytecodeFilePath, generator.BindingsPackageName, contractMetadata.Name) + if err != nil { + return err + } + + return generator.writeContractMetadata( + contractMetadata, + template.Must(template.New("RemoteContractMetadata").Parse(fileTemplate)), + ) +} + +func (generator *BindGenGeneratorRemote) writeContractMetadata(contractMetadata *RemoteContractMetadata, fileTemplate *template.Template) error { + metadataFilePath := filepath.Join(generator.MetadataOut, strings.ToLower(contractMetadata.Name)+"_more.go") + + var existingOutput []byte + if _, err := os.Stat(metadataFilePath); err == nil { + existingOutput, err = os.ReadFile(metadataFilePath) + if err != nil { + return fmt.Errorf("error reading existing metadata output file, metadataFilePath: %s err: %w", metadataFilePath, err) + } + } + + metadataFile, err := os.OpenFile( + metadataFilePath, + os.O_RDWR|os.O_CREATE|os.O_TRUNC, + 0o600, + ) + if err != nil { + return fmt.Errorf("error opening %s's metadata file at %s: %w", contractMetadata.Name, metadataFilePath, err) + } + defer metadataFile.Close() + + if err := fileTemplate.Execute(metadataFile, contractMetadata); err != nil { + return fmt.Errorf("error writing %s's contract metadata at %s: %w", contractMetadata.Name, metadataFilePath, err) + } + + if len(existingOutput) != 0 { + var newOutput []byte + newOutput, err = os.ReadFile(metadataFilePath) + if err != nil { + return fmt.Errorf("error reading new file: %w", err) + } + + if bytes.Equal(existingOutput, newOutput) { + generator.Logger.Debug("No changes detected in the contract metadata", "contract", contractMetadata.Name) + } else { + generator.Logger.Warn("Changes detected in the contract metadata, old metadata has been overwritten", "contract", contractMetadata.Name) + } + } else { + generator.Logger.Debug("No existing contract metadata found, skipping comparison", "contract", contractMetadata.Name) + } + + generator.Logger.Debug("Successfully wrote contract metadata", "contract", contractMetadata.Name, "path", metadataFilePath) + return nil +} + +// remoteContractMetadataTemplate is a Go text template for generating the metadata +// associated with a remotely sourced contracts. +// +// The template expects the following data to be provided: +// - .Package: the name of the Go package. +// - .Name: the name of the contract. +// - .DeployedBin: the binary (hex-encoded) of the deployed contract. +var remoteContractMetadataTemplate = `// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package {{.Package}} + +var {{.Name}}DeployedBin = "{{.DeployedBin}}" +func init() { + deployedBytecodes["{{.Name}}"] = {{.Name}}DeployedBin +} +` + +// permit2MetadataTemplate is a Go text template used to generate metadata +// for remotely sourced Permit2 contract. Because Permit2 has an immutable +// Solidity variables that depends on block.chainid, we can't use the deployed +// bytecode, but instead need to generate it specifically for each chain. +// To help with this, the metadata contains the initialization bytecode, the +// deployer address, and the CREATE2 salt, so that deployment can be +// replicated as closely as possible. +// +// The template expects the following data to be provided: +// - .Package: the name of the Go package. +// - .Name: the name of the contract. +// - .InitBin: the binary (hex-encoded) of the contract's initialization code. +// - .DeploymentSalt: the salt used during the contract's deployment. +// - .Deployer: the Ethereum address of the contract's deployer. +var permit2MetadataTemplate = `// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package {{.Package}} + +var {{.Name}}InitBin = "{{.InitBin}}" +var {{.Name}}DeploymentSalt = "{{.DeploymentSalt}}" +var {{.Name}}Deployer = "{{.Deployer}}" + +func init() { + initBytecodes["{{.Name}}"] = {{.Name}}InitBin + deploymentSalts["{{.Name}}"] = {{.Name}}DeploymentSalt + deployers["{{.Name}}"] = {{.Name}}Deployer +} +` diff --git a/op-bindings/bindgen/remote_handlers_test.go b/op-bindings/bindgen/remote_handlers_test.go new file mode 100644 index 000000000000..43248db20b57 --- /dev/null +++ b/op-bindings/bindgen/remote_handlers_test.go @@ -0,0 +1,27 @@ +package bindgen + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +var generator BindGenGeneratorRemote = BindGenGeneratorRemote{} + +func TestRemoveDeploymentSalt(t *testing.T) { + for _, tt := range removeDeploymentSaltTests { + t.Run(tt.name, func(t *testing.T) { + got, _ := generator.removeDeploymentSalt(tt.deploymentData, tt.deploymentSalt) + require.Equal(t, tt.expected, got) + }) + } +} + +func TestRemoveDeploymentSaltFailures(t *testing.T) { + for _, tt := range removeDeploymentSaltTestsFailures { + t.Run(tt.name, func(t *testing.T) { + _, err := generator.removeDeploymentSalt(tt.deploymentData, tt.deploymentSalt) + require.Equal(t, err.Error(), tt.expectedError) + }) + } +} diff --git a/op-bindings/bindgen/utils.go b/op-bindings/bindgen/utils.go new file mode 100644 index 000000000000..8ea2f99dc01f --- /dev/null +++ b/op-bindings/bindgen/utils.go @@ -0,0 +1,229 @@ +package bindgen + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "io" + "os" + "os/exec" + "path" + "strings" + + "github.com/ethereum/go-ethereum/log" +) + +type BindGenGeneratorBase struct { + MetadataOut string + BindingsPackageName string + MonorepoBasePath string + ContractsListPath string + Logger log.Logger +} + +type contractsList struct { + Local []string `json:"local"` + Remote []RemoteContract `json:"remote"` +} + +// readContractList reads a JSON file from the given `filePath` and unmarshals +// its content into the provided result interface. It logs the path of the file +// being read. +// +// Parameters: +// - logger: An instance of go-ethereum/log +// - filePath: The path to the JSON file to be read. +// - result: A pointer to the structure where the JSON data will be unmarshaled. +// +// Returns: +// - An error if reading the file or unmarshaling fails, nil otherwise. +func readContractList(logger log.Logger, filePath string) (contractsList, error) { + logger.Debug("Reading contract list", "filePath", filePath) + + var contracts contractsList + contractData, err := os.ReadFile(filePath) + if err != nil { + return contracts, err + } + + return contracts, json.Unmarshal(contractData, &contracts) +} + +// mkTempArtifactsDir creates a temporary directory with a "op-bindings" prefix +// for holding contract artifacts. The path to the created directory is logged. +// +// Parameters: +// - logger: An instance of go-ethereum/log +// +// Returns: +// - The path to the created temporary directory. +// - An error if the directory creation fails, nil otherwise. +func mkTempArtifactsDir(logger log.Logger) (string, error) { + dir, err := os.MkdirTemp("", "op-bindings") + if err != nil { + return "", err + } + + logger.Debug("Created temporary artifacts directory", "dir", dir) + return dir, nil +} + +// writeContractArtifacts writes the provided ABI and bytecode data to respective +// files in the specified temporary directory. The naming convention for these +// files is based on the provided contract name. The ABI data is written to a file +// with a ".abi" extension, and the bytecode data is written to a file with a ".bin" +// extension. +// +// Parameters: +// - logger: An instance of go-ethereum/log +// - tempDirPath: The directory path where the ABI and bytecode files will be written. +// - contractName: The name of the contract, used to create the filenames. +// - abi: The ABI data of the contract. +// - bytecode: The bytecode of the contract. +// +// Returns: +// - The full path to the written ABI file. +// - The full path to the written bytecode file. +// - An error if writing either file fails, nil otherwise. +func writeContractArtifacts(logger log.Logger, tempDirPath, contractName string, abi, bytecode []byte) (string, string, error) { + logger.Debug("Writing ABI and bytecode to temporary artifacts directory", "contractName", contractName, "tempDirPath", tempDirPath) + + abiFilePath := path.Join(tempDirPath, contractName+".abi") + if err := os.WriteFile(abiFilePath, abi, 0o600); err != nil { + return "", "", fmt.Errorf("error writing %s's ABI file: %w", contractName, err) + } + + bytecodeFilePath := path.Join(tempDirPath, contractName+".bin") + if err := os.WriteFile(bytecodeFilePath, bytecode, 0o600); err != nil { + return "", "", fmt.Errorf("error writing %s's bytecode file: %w", contractName, err) + } + + return abiFilePath, bytecodeFilePath, nil +} + +// genContractBindings generates Go bindings for an Ethereum contract using +// the provided ABI and bytecode files. The bindings are generated using the +// `abigen` tool and are written to the specified Go package directory. The +// generated file's name is based on the provided contract name and will have +// a ".go" extension. The generated bindings will be part of the provided Go +// package. +// +// Parameters: +// - logger: An instance of go-ethereum/log +// - abiFilePath: The path to the ABI file for the contract. +// - bytecodeFilePath: The path to the bytecode file for the contract. +// - goPackageName: The name of the Go package where the bindings will be written. +// - contractName: The name of the contract, used for naming the output file and +// defining the type in the generated bindings. +// +// Returns: +// - An error if there's an issue during any step of the binding generation process, +// nil otherwise. +// +// Note: This function relies on the external `abigen` tool, which should be +// installed and available in the system's PATH. +func genContractBindings(logger log.Logger, monorepoRootPath, abiFilePath, bytecodeFilePath, goPackageName, contractName string) error { + cwd, err := os.Getwd() + if err != nil { + return fmt.Errorf("error getting cwd: %w", err) + } + + outFilePath := path.Join(cwd, goPackageName, strings.ToLower(contractName)+".go") + + var existingOutput []byte + if _, err := os.Stat(outFilePath); err == nil { + existingOutput, err = os.ReadFile(outFilePath) + if err != nil { + return fmt.Errorf("error reading existing bindings output file, outFilePath: %s err: %w", outFilePath, err) + } + } + + if monorepoRootPath != "" { + logger.Debug("Checking abigen version") + + // Fetch installed abigen version (format: abigen version X.Y.Z--) + cmd := exec.Command("abigen", "--version") + var versionBuf bytes.Buffer + cmd.Stdout = bufio.NewWriter(&versionBuf) + if err := cmd.Run(); err != nil { + return fmt.Errorf("error fetching abigen version: %w", err) + } + abigenVersion := bytes.Trim(versionBuf.Bytes(), "\n") + + // Fetch expected abigen version (format: vX.Y.Z) + expectedAbigenVersion, err := readExpectedAbigenVersion(monorepoRootPath) + if err != nil { + return fmt.Errorf("error fetching the expected abigen version: %w", err) + } + + if !bytes.Contains(abigenVersion, []byte(expectedAbigenVersion)) { + return fmt.Errorf("abigen version mismatch, expected %s, got %s. Please run `pnpm install:abigen` in the monorepo root", expectedAbigenVersion, abigenVersion) + } + } else { + logger.Debug("No monorepo root path provided, skipping abigen version check") + } + + logger.Debug("Generating contract bindings", "contractName", contractName, "outFilePath", outFilePath) + cmd := exec.Command("abigen", "--abi", abiFilePath, "--bin", bytecodeFilePath, "--pkg", goPackageName, "--type", contractName, "--out", outFilePath) + cmd.Stdout = os.Stdout + if err := cmd.Run(); err != nil { + return fmt.Errorf("error running abigen for %s: %w", contractName, err) + } + + if len(existingOutput) != 0 { + newOutput, err := os.ReadFile(outFilePath) + if err != nil { + return fmt.Errorf("error reading new file: %w", err) + } + + if bytes.Equal(existingOutput, newOutput) { + logger.Debug("No changes detected in the contract bindings", "contractName", contractName) + } else { + logger.Warn("Changes detected in the contract bindings, old bindings have been overwritten", "contractName", contractName) + } + } else { + logger.Debug("No existing contract bindings found, skipping comparison", "contractName", contractName) + } + + return nil +} + +// Versions is a struct for holding the versions of the tools used in the monorepo +type Versions struct { + Abigen string `json:"abigen"` + Foundry string `json:"foundry"` + Geth string `json:"geth"` + Nvm string `json:"nvm"` + Slither string `json:"slither"` + Kontrol string `json:"kontrol"` +} + +// readExpectedAbigenVersion reads the expected abigen version from the monorepo's +// versions.json file. This function will remove the 'v' prefix from the version +// string. +// +// Parameters: +// - monorepoRootPath: The path to the monorepo's root directory. +// +// Returns: +// - The expected abigen version. +// - An error if the versions.json file cannot be read or parsed, nil otherwise. +func readExpectedAbigenVersion(monorepoRootPath string) (string, error) { + // Open the version control file + jsonFile, err := os.Open(path.Join(monorepoRootPath, "versions.json")) + if err != nil { + return "", fmt.Errorf("error reading versions.json file: %w", err) + } + defer jsonFile.Close() + + // Parse the version control file + byteValue, _ := io.ReadAll(jsonFile) + var versions Versions + if err := json.Unmarshal(byteValue, &versions); err != nil { + return "", fmt.Errorf("error parsing versions.json file: %w", err) + } + + // Trim the 'v' prefix from the version string + return strings.Trim(versions.Abigen, "v"), nil +} diff --git a/op-bindings/bindgen/utils_test.go b/op-bindings/bindgen/utils_test.go new file mode 100644 index 000000000000..33d511b76f23 --- /dev/null +++ b/op-bindings/bindgen/utils_test.go @@ -0,0 +1,34 @@ +package bindgen + +import ( + "encoding/json" + "os" + "path" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestReadExpectedAbigenVersion(t *testing.T) { + // Create a temporary directory for the version control file. + tmpDir := path.Join(os.TempDir(), "version-tests") + defer os.RemoveAll(tmpDir) + require.NoError(t, os.MkdirAll(tmpDir, 0755)) + + // Create a temporary version control file. + versionFile := path.Join(tmpDir, "versions.json") + versions := Versions{Abigen: "v1.2.3"} + + // Marshal the versions to JSON. + versionsJSON, err := json.Marshal(versions) + require.NoError(t, err) + + // Write the JSON to the version control file. + require.NoError(t, os.WriteFile(versionFile, versionsJSON, 0644)) + + // Read the expected version from the version control file. + // The read version should not have a "v" prefix. + expectedVersion, err := readExpectedAbigenVersion(tmpDir) + require.NoError(t, err) + require.Equal(t, expectedVersion, "1.2.3") +} diff --git a/op-bindings/bindings/addressmanager.go b/op-bindings/bindings/addressmanager.go index c812c9c2c31d..dd650e998d6c 100644 --- a/op-bindings/bindings/addressmanager.go +++ b/op-bindings/bindings/addressmanager.go @@ -30,7 +30,7 @@ var ( // AddressManagerMetaData contains all meta data concerning the AddressManager contract. var AddressManagerMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAddress\",\"type\":\"address\"}],\"name\":\"AddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"type\":\"function\",\"name\":\"getAddress\",\"inputs\":[{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setAddress\",\"inputs\":[{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_address\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"AddressSet\",\"inputs\":[{\"name\":\"name\",\"type\":\"string\",\"indexed\":true,\"internalType\":\"string\"},{\"name\":\"newAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"oldAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", Bin: "0x608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6105ef8061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046104fa565b610106565b6100906100da366004610548565b6101d9565b6100746100ed366004610585565b610215565b6100fa6102d1565b6101046000610352565b565b61010e6102d1565b6000610119836103c7565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff00000000000000000000000000000000000000008316179092559151929350169061017c9085906105a7565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006101e8846103c7565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b61021d6102d1565b73ffffffffffffffffffffffffffffffffffffffff81166102c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ce81610352565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bc565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016103da91906105a7565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261043757600080fd5b813567ffffffffffffffff80821115610452576104526103f7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610498576104986103f7565b816040528381528660208588010111156104b157600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b919050565b6000806040838503121561050d57600080fd5b823567ffffffffffffffff81111561052457600080fd5b61053085828601610426565b92505061053f602084016104d1565b90509250929050565b60006020828403121561055a57600080fd5b813567ffffffffffffffff81111561057157600080fd5b61057d84828501610426565b949350505050565b60006020828403121561059757600080fd5b6105a0826104d1565b9392505050565b6000825160005b818110156105c857602081860181015185830152016105ae565b818111156105d7576000828501525b50919091019291505056fea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/addressmanager_more.go b/op-bindings/bindings/addressmanager_more.go index 40bd6be3956e..0bb85c7d9c85 100644 --- a/op-bindings/bindings/addressmanager_more.go +++ b/op-bindings/bindings/addressmanager_more.go @@ -15,6 +15,7 @@ var AddressManagerStorageLayout = new(solc.StorageLayout) var AddressManagerDeployedBin = "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046104fa565b610106565b6100906100da366004610548565b6101d9565b6100746100ed366004610585565b610215565b6100fa6102d1565b6101046000610352565b565b61010e6102d1565b6000610119836103c7565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff00000000000000000000000000000000000000008316179092559151929350169061017c9085906105a7565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006101e8846103c7565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b61021d6102d1565b73ffffffffffffffffffffffffffffffffffffffff81166102c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ce81610352565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bc565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016103da91906105a7565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261043757600080fd5b813567ffffffffffffffff80821115610452576104526103f7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610498576104986103f7565b816040528381528660208588010111156104b157600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b919050565b6000806040838503121561050d57600080fd5b823567ffffffffffffffff81111561052457600080fd5b61053085828601610426565b92505061053f602084016104d1565b90509250929050565b60006020828403121561055a57600080fd5b813567ffffffffffffffff81111561057157600080fd5b61057d84828501610426565b949350505050565b60006020828403121561059757600080fd5b6105a0826104d1565b9392505050565b6000825160005b818110156105c857602081860181015185830152016105ae565b818111156105d7576000828501525b50919091019291505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(AddressManagerStorageLayoutJSON), AddressManagerStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["AddressManager"] = AddressManagerStorageLayout deployedBytecodes["AddressManager"] = AddressManagerDeployedBin + immutableReferences["AddressManager"] = false } diff --git a/op-bindings/bindings/alphabetvm.go b/op-bindings/bindings/alphabetvm.go index 67c960d91624..7f0607b6cee1 100644 --- a/op-bindings/bindings/alphabetvm.go +++ b/op-bindings/bindings/alphabetvm.go @@ -30,8 +30,8 @@ var ( // AlphabetVMMetaData contains all meta data concerning the AlphabetVM contract. var AlphabetVMMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"Claim\",\"name\":\"_absolutePrestate\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contractIPreimageOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_stateData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"step\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"postState_\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a060405234801561001057600080fd5b50604051610a7d380380610a7d83398101604081905261002f91610090565b608081905260405161004090610083565b604051809103906000f08015801561005c573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b0392909216919091179055506100a9565b61065c8061042183390190565b6000602082840312156100a257600080fd5b5051919050565b60805161035e6100c3600039600060af015261035e6000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063836e7b3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610098610093366004610213565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610287565b6040518091039020901b03610108576000915061010187890189610297565b9050610127565b610114878901896102b0565b90925090508161012381610301565b9250505b81610133826001610339565b604080516020810193909352820152606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b60008083601f8401126101dc57600080fd5b50813567ffffffffffffffff8111156101f457600080fd5b60208301915083602082850101111561020c57600080fd5b9250929050565b60008060008060006060868803121561022b57600080fd5b853567ffffffffffffffff8082111561024357600080fd5b61024f89838a016101ca565b9097509550602088013591508082111561026857600080fd5b50610275888289016101ca565b96999598509660400135949350505050565b8183823760009101908152919050565b6000602082840312156102a957600080fd5b5035919050565b600080604083850312156102c357600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610332576103326102d2565b5060010190565b6000821982111561034c5761034c6102d2565b50019056fea164736f6c634300080f000a608060405234801561001057600080fd5b5061063c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_oracle\",\"type\":\"address\",\"internalType\":\"contractPreimageOracle\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"oracle\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPreimageOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_localContext\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"postState_\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"}]", + Bin: "0x60a060405234801561001057600080fd5b506040516105d23803806105d283398101604081905261002f91610059565b608091909152600080546001600160a01b0319166001600160a01b03909216919091179055610096565b6000806040838503121561006c57600080fd5b825160208401519092506001600160a01b038116811461008b57600080fd5b809150509250929050565b6080516105226100b0600039600060af01526105226000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063e14ced3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61009861009336600461039c565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610410565b6040518091039020901b036101e0576000805473ffffffffffffffffffffffffffffffffffffffff1663e03110e161011b6004886102a6565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152600060248201526044016040805180830381865afa158015610175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101999190610420565b50905060006101b3600163ffffffff608085901c16610473565b600481901b9450905060006101ca8a8c018c61048a565b90506101d685826104a3565b935050505061020d565b6101ec878901896104bb565b9092509050816101fb816104dd565b9250508080610209906104dd565b9150505b6040805160208101849052908101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83161761034c818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b60008083601f84011261036557600080fd5b50813567ffffffffffffffff81111561037d57600080fd5b60208301915083602082850101111561039557600080fd5b9250929050565b6000806000806000606086880312156103b457600080fd5b853567ffffffffffffffff808211156103cc57600080fd5b6103d889838a01610353565b909750955060208801359150808211156103f157600080fd5b506103fe88828901610353565b96999598509660400135949350505050565b8183823760009101908152919050565b6000806040838503121561043357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561048557610485610444565b500390565b60006020828403121561049c57600080fd5b5035919050565b600082198211156104b6576104b6610444565b500190565b600080604083850312156104ce57600080fd5b50508035926020909101359150565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361050e5761050e610444565b506001019056fea164736f6c634300080f000a", } // AlphabetVMABI is the input ABI used to generate the binding from. @@ -43,7 +43,7 @@ var AlphabetVMABI = AlphabetVMMetaData.ABI var AlphabetVMBin = AlphabetVMMetaData.Bin // DeployAlphabetVM deploys a new Ethereum contract, binding an instance of AlphabetVM to it. -func DeployAlphabetVM(auth *bind.TransactOpts, backend bind.ContractBackend, _absolutePrestate [32]byte) (common.Address, *types.Transaction, *AlphabetVM, error) { +func DeployAlphabetVM(auth *bind.TransactOpts, backend bind.ContractBackend, _absolutePrestate [32]byte, _oracle common.Address) (common.Address, *types.Transaction, *AlphabetVM, error) { parsed, err := AlphabetVMMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -52,7 +52,7 @@ func DeployAlphabetVM(auth *bind.TransactOpts, backend bind.ContractBackend, _ab return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(AlphabetVMBin), backend, _absolutePrestate) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(AlphabetVMBin), backend, _absolutePrestate, _oracle) if err != nil { return common.Address{}, nil, nil, err } @@ -232,12 +232,12 @@ func (_AlphabetVM *AlphabetVMCallerSession) Oracle() (common.Address, error) { return _AlphabetVM.Contract.Oracle(&_AlphabetVM.CallOpts) } -// Step is a free data retrieval call binding the contract method 0x836e7b32. +// Step is a free data retrieval call binding the contract method 0xe14ced32. // -// Solidity: function step(bytes _stateData, bytes , uint256 ) view returns(bytes32 postState_) -func (_AlphabetVM *AlphabetVMCaller) Step(opts *bind.CallOpts, _stateData []byte, arg1 []byte, arg2 *big.Int) ([32]byte, error) { +// Solidity: function step(bytes _stateData, bytes , bytes32 _localContext) view returns(bytes32 postState_) +func (_AlphabetVM *AlphabetVMCaller) Step(opts *bind.CallOpts, _stateData []byte, arg1 []byte, _localContext [32]byte) ([32]byte, error) { var out []interface{} - err := _AlphabetVM.contract.Call(opts, &out, "step", _stateData, arg1, arg2) + err := _AlphabetVM.contract.Call(opts, &out, "step", _stateData, arg1, _localContext) if err != nil { return *new([32]byte), err @@ -249,16 +249,16 @@ func (_AlphabetVM *AlphabetVMCaller) Step(opts *bind.CallOpts, _stateData []byte } -// Step is a free data retrieval call binding the contract method 0x836e7b32. +// Step is a free data retrieval call binding the contract method 0xe14ced32. // -// Solidity: function step(bytes _stateData, bytes , uint256 ) view returns(bytes32 postState_) -func (_AlphabetVM *AlphabetVMSession) Step(_stateData []byte, arg1 []byte, arg2 *big.Int) ([32]byte, error) { - return _AlphabetVM.Contract.Step(&_AlphabetVM.CallOpts, _stateData, arg1, arg2) +// Solidity: function step(bytes _stateData, bytes , bytes32 _localContext) view returns(bytes32 postState_) +func (_AlphabetVM *AlphabetVMSession) Step(_stateData []byte, arg1 []byte, _localContext [32]byte) ([32]byte, error) { + return _AlphabetVM.Contract.Step(&_AlphabetVM.CallOpts, _stateData, arg1, _localContext) } -// Step is a free data retrieval call binding the contract method 0x836e7b32. +// Step is a free data retrieval call binding the contract method 0xe14ced32. // -// Solidity: function step(bytes _stateData, bytes , uint256 ) view returns(bytes32 postState_) -func (_AlphabetVM *AlphabetVMCallerSession) Step(_stateData []byte, arg1 []byte, arg2 *big.Int) ([32]byte, error) { - return _AlphabetVM.Contract.Step(&_AlphabetVM.CallOpts, _stateData, arg1, arg2) +// Solidity: function step(bytes _stateData, bytes , bytes32 _localContext) view returns(bytes32 postState_) +func (_AlphabetVM *AlphabetVMCallerSession) Step(_stateData []byte, arg1 []byte, _localContext [32]byte) ([32]byte, error) { + return _AlphabetVM.Contract.Step(&_AlphabetVM.CallOpts, _stateData, arg1, _localContext) } diff --git a/op-bindings/bindings/alphabetvm2.go b/op-bindings/bindings/alphabetvm2.go new file mode 100644 index 000000000000..5ec135eed596 --- /dev/null +++ b/op-bindings/bindings/alphabetvm2.go @@ -0,0 +1,264 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// AlphabetVM2MetaData contains all meta data concerning the AlphabetVM2 contract. +var AlphabetVM2MetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"oracle\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPreimageOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_localContext\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"postState_\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"}]", + Bin: "0x60a060405234801561001057600080fd5b50604051610c23380380610c2383398101604081905261002f91610090565b608081905260405161004090610083565b604051809103906000f08015801561005c573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b0392909216919091179055506100a9565b61065c806105c783390190565b6000602082840312156100a257600080fd5b5051919050565b6080516105046100c3600039600060af01526105046000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063e14ced3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610098610093366004610395565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610409565b6040518091039020901b036101d9576000805473ffffffffffffffffffffffffffffffffffffffff1663e03110e161011b60048861029f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152600060248201526044016040805180830381865afa158015610175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101999190610419565b50640ffffffff0607c82901c169350905063ffffffff608082901c1660006101c38a8c018c61043d565b90506101cf8582610485565b9350505050610206565b6101e58789018961049d565b9092509050816101f4816104bf565b9250508080610202906104bf565b9150505b6040805160208101849052908101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617610345818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b60008083601f84011261035e57600080fd5b50813567ffffffffffffffff81111561037657600080fd5b60208301915083602082850101111561038e57600080fd5b9250929050565b6000806000806000606086880312156103ad57600080fd5b853567ffffffffffffffff808211156103c557600080fd5b6103d189838a0161034c565b909750955060208801359150808211156103ea57600080fd5b506103f78882890161034c565b96999598509660400135949350505050565b8183823760009101908152919050565b6000806040838503121561042c57600080fd5b505080516020909101519092909150565b60006020828403121561044f57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561049857610498610456565b500190565b600080604083850312156104b057600080fd5b50508035926020909101359150565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036104f0576104f0610456565b506001019056fea164736f6c634300080f000a608060405234801561001057600080fd5b5061063c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806352f0f3ad1461007757806361238bde1461009d5780638542cf50146100c8575b600080fd5b61008a6100853660046104df565b610163565b6040519081526020015b60405180910390f35b61008a6100ab36600461051a565b600160209081526000928352604080842090915290825290205481565b6100f66100d636600461051a565b600260209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610094565b61011961011436600461051a565b610238565b60408051928352602083019190915201610094565b61014161013c36600461053c565b610329565b005b61008a6101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080600080600060a086880312156104f757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806040838503121561052d57600080fd5b50508035926020909101359150565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a", +} + +// AlphabetVM2ABI is the input ABI used to generate the binding from. +// Deprecated: Use AlphabetVM2MetaData.ABI instead. +var AlphabetVM2ABI = AlphabetVM2MetaData.ABI + +// AlphabetVM2Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use AlphabetVM2MetaData.Bin instead. +var AlphabetVM2Bin = AlphabetVM2MetaData.Bin + +// DeployAlphabetVM2 deploys a new Ethereum contract, binding an instance of AlphabetVM2 to it. +func DeployAlphabetVM2(auth *bind.TransactOpts, backend bind.ContractBackend, _absolutePrestate [32]byte) (common.Address, *types.Transaction, *AlphabetVM2, error) { + parsed, err := AlphabetVM2MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(AlphabetVM2Bin), backend, _absolutePrestate) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &AlphabetVM2{AlphabetVM2Caller: AlphabetVM2Caller{contract: contract}, AlphabetVM2Transactor: AlphabetVM2Transactor{contract: contract}, AlphabetVM2Filterer: AlphabetVM2Filterer{contract: contract}}, nil +} + +// AlphabetVM2 is an auto generated Go binding around an Ethereum contract. +type AlphabetVM2 struct { + AlphabetVM2Caller // Read-only binding to the contract + AlphabetVM2Transactor // Write-only binding to the contract + AlphabetVM2Filterer // Log filterer for contract events +} + +// AlphabetVM2Caller is an auto generated read-only Go binding around an Ethereum contract. +type AlphabetVM2Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AlphabetVM2Transactor is an auto generated write-only Go binding around an Ethereum contract. +type AlphabetVM2Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AlphabetVM2Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AlphabetVM2Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AlphabetVM2Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AlphabetVM2Session struct { + Contract *AlphabetVM2 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AlphabetVM2CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AlphabetVM2CallerSession struct { + Contract *AlphabetVM2Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AlphabetVM2TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AlphabetVM2TransactorSession struct { + Contract *AlphabetVM2Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AlphabetVM2Raw is an auto generated low-level Go binding around an Ethereum contract. +type AlphabetVM2Raw struct { + Contract *AlphabetVM2 // Generic contract binding to access the raw methods on +} + +// AlphabetVM2CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AlphabetVM2CallerRaw struct { + Contract *AlphabetVM2Caller // Generic read-only contract binding to access the raw methods on +} + +// AlphabetVM2TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AlphabetVM2TransactorRaw struct { + Contract *AlphabetVM2Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewAlphabetVM2 creates a new instance of AlphabetVM2, bound to a specific deployed contract. +func NewAlphabetVM2(address common.Address, backend bind.ContractBackend) (*AlphabetVM2, error) { + contract, err := bindAlphabetVM2(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AlphabetVM2{AlphabetVM2Caller: AlphabetVM2Caller{contract: contract}, AlphabetVM2Transactor: AlphabetVM2Transactor{contract: contract}, AlphabetVM2Filterer: AlphabetVM2Filterer{contract: contract}}, nil +} + +// NewAlphabetVM2Caller creates a new read-only instance of AlphabetVM2, bound to a specific deployed contract. +func NewAlphabetVM2Caller(address common.Address, caller bind.ContractCaller) (*AlphabetVM2Caller, error) { + contract, err := bindAlphabetVM2(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AlphabetVM2Caller{contract: contract}, nil +} + +// NewAlphabetVM2Transactor creates a new write-only instance of AlphabetVM2, bound to a specific deployed contract. +func NewAlphabetVM2Transactor(address common.Address, transactor bind.ContractTransactor) (*AlphabetVM2Transactor, error) { + contract, err := bindAlphabetVM2(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AlphabetVM2Transactor{contract: contract}, nil +} + +// NewAlphabetVM2Filterer creates a new log filterer instance of AlphabetVM2, bound to a specific deployed contract. +func NewAlphabetVM2Filterer(address common.Address, filterer bind.ContractFilterer) (*AlphabetVM2Filterer, error) { + contract, err := bindAlphabetVM2(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AlphabetVM2Filterer{contract: contract}, nil +} + +// bindAlphabetVM2 binds a generic wrapper to an already deployed contract. +func bindAlphabetVM2(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AlphabetVM2ABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AlphabetVM2 *AlphabetVM2Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AlphabetVM2.Contract.AlphabetVM2Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AlphabetVM2 *AlphabetVM2Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AlphabetVM2.Contract.AlphabetVM2Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AlphabetVM2 *AlphabetVM2Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AlphabetVM2.Contract.AlphabetVM2Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AlphabetVM2 *AlphabetVM2CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AlphabetVM2.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AlphabetVM2 *AlphabetVM2TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AlphabetVM2.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AlphabetVM2 *AlphabetVM2TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AlphabetVM2.Contract.contract.Transact(opts, method, params...) +} + +// Oracle is a free data retrieval call binding the contract method 0x7dc0d1d0. +// +// Solidity: function oracle() view returns(address) +func (_AlphabetVM2 *AlphabetVM2Caller) Oracle(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AlphabetVM2.contract.Call(opts, &out, "oracle") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Oracle is a free data retrieval call binding the contract method 0x7dc0d1d0. +// +// Solidity: function oracle() view returns(address) +func (_AlphabetVM2 *AlphabetVM2Session) Oracle() (common.Address, error) { + return _AlphabetVM2.Contract.Oracle(&_AlphabetVM2.CallOpts) +} + +// Oracle is a free data retrieval call binding the contract method 0x7dc0d1d0. +// +// Solidity: function oracle() view returns(address) +func (_AlphabetVM2 *AlphabetVM2CallerSession) Oracle() (common.Address, error) { + return _AlphabetVM2.Contract.Oracle(&_AlphabetVM2.CallOpts) +} + +// Step is a free data retrieval call binding the contract method 0xe14ced32. +// +// Solidity: function step(bytes _stateData, bytes , bytes32 _localContext) view returns(bytes32 postState_) +func (_AlphabetVM2 *AlphabetVM2Caller) Step(opts *bind.CallOpts, _stateData []byte, arg1 []byte, _localContext [32]byte) ([32]byte, error) { + var out []interface{} + err := _AlphabetVM2.contract.Call(opts, &out, "step", _stateData, arg1, _localContext) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// Step is a free data retrieval call binding the contract method 0xe14ced32. +// +// Solidity: function step(bytes _stateData, bytes , bytes32 _localContext) view returns(bytes32 postState_) +func (_AlphabetVM2 *AlphabetVM2Session) Step(_stateData []byte, arg1 []byte, _localContext [32]byte) ([32]byte, error) { + return _AlphabetVM2.Contract.Step(&_AlphabetVM2.CallOpts, _stateData, arg1, _localContext) +} + +// Step is a free data retrieval call binding the contract method 0xe14ced32. +// +// Solidity: function step(bytes _stateData, bytes , bytes32 _localContext) view returns(bytes32 postState_) +func (_AlphabetVM2 *AlphabetVM2CallerSession) Step(_stateData []byte, arg1 []byte, _localContext [32]byte) ([32]byte, error) { + return _AlphabetVM2.Contract.Step(&_AlphabetVM2.CallOpts, _stateData, arg1, _localContext) +} diff --git a/op-bindings/bindings/alphabetvm2_more.go b/op-bindings/bindings/alphabetvm2_more.go new file mode 100644 index 000000000000..50882f9f8655 --- /dev/null +++ b/op-bindings/bindings/alphabetvm2_more.go @@ -0,0 +1,27 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "encoding/json" + + "github.com/ethereum-optimism/optimism/op-bindings/solc" +) + +const AlphabetVM2StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"test/mocks/AlphabetVM2.sol:AlphabetVM2\",\"label\":\"oracle\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_contract(IPreimageOracle)1001\"}],\"types\":{\"t_contract(IPreimageOracle)1001\":{\"encoding\":\"inplace\",\"label\":\"contract IPreimageOracle\",\"numberOfBytes\":\"20\"}}}" + +var AlphabetVM2StorageLayout = new(solc.StorageLayout) + +var AlphabetVM2DeployedBin = "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063e14ced3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610098610093366004610395565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610409565b6040518091039020901b036101d9576000805473ffffffffffffffffffffffffffffffffffffffff1663e03110e161011b60048861029f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152600060248201526044016040805180830381865afa158015610175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101999190610419565b50640ffffffff0607c82901c169350905063ffffffff608082901c1660006101c38a8c018c61043d565b90506101cf8582610485565b9350505050610206565b6101e58789018961049d565b9092509050816101f4816104bf565b9250508080610202906104bf565b9150505b6040805160208101849052908101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831617610345818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b60008083601f84011261035e57600080fd5b50813567ffffffffffffffff81111561037657600080fd5b60208301915083602082850101111561038e57600080fd5b9250929050565b6000806000806000606086880312156103ad57600080fd5b853567ffffffffffffffff808211156103c557600080fd5b6103d189838a0161034c565b909750955060208801359150808211156103ea57600080fd5b506103f78882890161034c565b96999598509660400135949350505050565b8183823760009101908152919050565b6000806040838503121561042c57600080fd5b505080516020909101519092909150565b60006020828403121561044f57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561049857610498610456565b500190565b600080604083850312156104b057600080fd5b50508035926020909101359150565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036104f0576104f0610456565b506001019056fea164736f6c634300080f000a" + + +func init() { + if err := json.Unmarshal([]byte(AlphabetVM2StorageLayoutJSON), AlphabetVM2StorageLayout); err != nil { + panic(err) + } + + layouts["AlphabetVM2"] = AlphabetVM2StorageLayout + deployedBytecodes["AlphabetVM2"] = AlphabetVM2DeployedBin + immutableReferences["AlphabetVM2"] = true +} diff --git a/op-bindings/bindings/alphabetvm_more.go b/op-bindings/bindings/alphabetvm_more.go index 1236b475958b..7f4302fbc669 100644 --- a/op-bindings/bindings/alphabetvm_more.go +++ b/op-bindings/bindings/alphabetvm_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const AlphabetVMStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"test/FaultDisputeGame.t.sol:AlphabetVM\",\"label\":\"oracle\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_contract(IPreimageOracle)1001\"}],\"types\":{\"t_contract(IPreimageOracle)1001\":{\"encoding\":\"inplace\",\"label\":\"contract IPreimageOracle\",\"numberOfBytes\":\"20\"}}}" +const AlphabetVMStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"test/mocks/AlphabetVM.sol:AlphabetVM\",\"label\":\"oracle\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_contract(IPreimageOracle)1001\"}],\"types\":{\"t_contract(IPreimageOracle)1001\":{\"encoding\":\"inplace\",\"label\":\"contract IPreimageOracle\",\"numberOfBytes\":\"20\"}}}" var AlphabetVMStorageLayout = new(solc.StorageLayout) -var AlphabetVMDeployedBin = "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063836e7b3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610098610093366004610213565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610287565b6040518091039020901b03610108576000915061010187890189610297565b9050610127565b610114878901896102b0565b90925090508161012381610301565b9250505b81610133826001610339565b604080516020810193909352820152606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b60008083601f8401126101dc57600080fd5b50813567ffffffffffffffff8111156101f457600080fd5b60208301915083602082850101111561020c57600080fd5b9250929050565b60008060008060006060868803121561022b57600080fd5b853567ffffffffffffffff8082111561024357600080fd5b61024f89838a016101ca565b9097509550602088013591508082111561026857600080fd5b50610275888289016101ca565b96999598509660400135949350505050565b8183823760009101908152919050565b6000602082840312156102a957600080fd5b5035919050565b600080604083850312156102c357600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610332576103326102d2565b5060010190565b6000821982111561034c5761034c6102d2565b50019056fea164736f6c634300080f000a" +var AlphabetVMDeployedBin = "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063e14ced3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61009861009336600461039c565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610410565b6040518091039020901b036101e0576000805473ffffffffffffffffffffffffffffffffffffffff1663e03110e161011b6004886102a6565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526004810191909152600060248201526044016040805180830381865afa158015610175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101999190610420565b50905060006101b3600163ffffffff608085901c16610473565b600481901b9450905060006101ca8a8c018c61048a565b90506101d685826104a3565b935050505061020d565b6101ec878901896104bb565b9092509050816101fb816104dd565b9250508080610209906104dd565b9150505b6040805160208101849052908101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83161761034c818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b60008083601f84011261036557600080fd5b50813567ffffffffffffffff81111561037d57600080fd5b60208301915083602082850101111561039557600080fd5b9250929050565b6000806000806000606086880312156103b457600080fd5b853567ffffffffffffffff808211156103cc57600080fd5b6103d889838a01610353565b909750955060208801359150808211156103f157600080fd5b506103fe88828901610353565b96999598509660400135949350505050565b8183823760009101908152919050565b6000806040838503121561043357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561048557610485610444565b500390565b60006020828403121561049c57600080fd5b5035919050565b600082198211156104b6576104b6610444565b500190565b600080604083850312156104ce57600080fd5b50508035926020909101359150565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361050e5761050e610444565b506001019056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(AlphabetVMStorageLayoutJSON), AlphabetVMStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["AlphabetVM"] = AlphabetVMStorageLayout deployedBytecodes["AlphabetVM"] = AlphabetVMDeployedBin + immutableReferences["AlphabetVM"] = true } diff --git a/op-bindings/bindings/basefeevault.go b/op-bindings/bindings/basefeevault.go index 7fcfefc400ad..c81c322485c5 100644 --- a/op-bindings/bindings/basefeevault.go +++ b/op-bindings/bindings/basefeevault.go @@ -30,7 +30,7 @@ var ( // BaseFeeVaultMetaData contains all meta data concerning the BaseFeeVault contract. var BaseFeeVaultMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minWithdrawalAmount\",\"type\":\"uint256\"},{\"internalType\":\"enumFeeVault.WithdrawalNetwork\",\"name\":\"_withdrawalNetwork\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFeeVault.WithdrawalNetwork\",\"name\":\"withdrawalNetwork\",\"type\":\"uint8\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_WITHDRAWAL_AMOUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RECIPIENT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WITHDRAWAL_NETWORK\",\"outputs\":[{\"internalType\":\"enumFeeVault.WithdrawalNetwork\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalProcessed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_minWithdrawalAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_withdrawalNetwork\",\"type\":\"uint8\",\"internalType\":\"enumFeeVault.WithdrawalNetwork\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"MIN_WITHDRAWAL_AMOUNT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RECIPIENT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"WITHDRAWAL_NETWORK\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumFeeVault.WithdrawalNetwork\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalProcessed\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Withdrawal\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdrawal\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalNetwork\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"enumFeeVault.WithdrawalNetwork\"}],\"anonymous\":false}]", Bin: "0x60e060405234801561001057600080fd5b506040516108d13803806108d183398101604081905261002f91610079565b6001600160a01b03831660a0526080829052828282806001811115610056576100566100cc565b60c081600181111561006a5761006a6100cc565b815250505050505050506100e2565b60008060006060848603121561008e57600080fd5b83516001600160a01b03811681146100a557600080fd5b602085015160408601519194509250600281106100c157600080fd5b809150509250925092565b634e487b7160e01b600052602160045260246000fd5b60805160a05160c051610790610141600039600081816101760152818161038901526103c40152600081816087015281816102d801528181610367015281816103fd01526105640152600081816101b701526101db01526107906000f3fe6080604052600436106100695760003560e01c806384411d651161004357806384411d6514610140578063d0e12f9014610164578063d3e5792b146101a557600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e86101d9565b005b3480156100f657600080fd5b506101336040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b6040516100ca9190610630565b34801561014c57600080fd5b5061015660005481565b6040519081526020016100ca565b34801561017057600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516100ca91906106b4565b3480156101b157600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000004710156102b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546102ca91906106c8565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f0000000000000000000000000000000000000000000000000000000000000000337f00000000000000000000000000000000000000000000000000000000000000006040516103b89493929190610707565b60405180910390a160017f000000000000000000000000000000000000000000000000000000000000000060018111156103f4576103f461064a565b0361050d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610473576040519150601f19603f3d011682016040523d82523d6000602084013e610478565b606091505b5050905080610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e740000000000000000000000000000000060648201526084016102ab565b5050565b604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610590917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610748565b6000604051808303818588803b1580156105a957600080fd5b505af11580156105bd573d6000803e3d6000fd5b505050505050565b6000815180845260005b818110156105eb576020818501810151868301820152016105cf565b818111156105fd576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061064360208301846105c5565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106106b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016106c28284610679565b92915050565b60008219821115610702577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff8481166020830152831660408201526080810161073f6060830184610679565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061073f60608301846105c556fea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/basefeevault_more.go b/op-bindings/bindings/basefeevault_more.go index e62ffc0e217a..39bcd68c22c2 100644 --- a/op-bindings/bindings/basefeevault_more.go +++ b/op-bindings/bindings/basefeevault_more.go @@ -15,6 +15,7 @@ var BaseFeeVaultStorageLayout = new(solc.StorageLayout) var BaseFeeVaultDeployedBin = "0x6080604052600436106100695760003560e01c806384411d651161004357806384411d6514610140578063d0e12f9014610164578063d3e5792b146101a557600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e86101d9565b005b3480156100f657600080fd5b506101336040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b6040516100ca9190610630565b34801561014c57600080fd5b5061015660005481565b6040519081526020016100ca565b34801561017057600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516100ca91906106b4565b3480156101b157600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000004710156102b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546102ca91906106c8565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f0000000000000000000000000000000000000000000000000000000000000000337f00000000000000000000000000000000000000000000000000000000000000006040516103b89493929190610707565b60405180910390a160017f000000000000000000000000000000000000000000000000000000000000000060018111156103f4576103f461064a565b0361050d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610473576040519150601f19603f3d011682016040523d82523d6000602084013e610478565b606091505b5050905080610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e740000000000000000000000000000000060648201526084016102ab565b5050565b604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610590917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610748565b6000604051808303818588803b1580156105a957600080fd5b505af11580156105bd573d6000803e3d6000fd5b505050505050565b6000815180845260005b818110156105eb576020818501810151868301820152016105cf565b818111156105fd576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061064360208301846105c5565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106106b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016106c28284610679565b92915050565b60008219821115610702577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff8481166020830152831660408201526080810161073f6060830184610679565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061073f60608301846105c556fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(BaseFeeVaultStorageLayoutJSON), BaseFeeVaultStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["BaseFeeVault"] = BaseFeeVaultStorageLayout deployedBytecodes["BaseFeeVault"] = BaseFeeVaultDeployedBin + immutableReferences["BaseFeeVault"] = true } diff --git a/op-bindings/bindings/blockoracle.go b/op-bindings/bindings/blockoracle.go deleted file mode 100644 index 686061c1aa12..000000000000 --- a/op-bindings/bindings/blockoracle.go +++ /dev/null @@ -1,453 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package bindings - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// BlockOracleBlockInfo is an auto generated low-level Go binding around an user-defined struct. -type BlockOracleBlockInfo struct { - Hash [32]byte - ChildTimestamp uint64 -} - -// BlockOracleMetaData contains all meta data concerning the BlockOracle contract. -var BlockOracleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"BlockHashNotPresent\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"Hash\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"Timestamp\",\"name\":\"childTimestamp\",\"type\":\"uint64\"}],\"name\":\"Checkpoint\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"checkpoint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_blockNumber\",\"type\":\"uint256\"}],\"name\":\"load\",\"outputs\":[{\"components\":[{\"internalType\":\"Hash\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"Timestamp\",\"name\":\"childTimestamp\",\"type\":\"uint64\"}],\"internalType\":\"structBlockOracle.BlockInfo\",\"name\":\"blockInfo_\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b506102e7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806399d548aa14610098578063c2c4c5c1146100d0575b600080fd5b6100826040518060400160405280600581526020017f302e302e3100000000000000000000000000000000000000000000000000000081525081565b60405161008f9190610210565b60405180910390f35b6100ab6100a6366004610283565b6100e6565b604080518251815260209283015167ffffffffffffffff16928101929092520161008f565b6100d8610165565b60405190815260200161008f565b604080518082018252600080825260209182018190528381528082528281208351808501909452805480855260019091015467ffffffffffffffff169284019290925203610160576040517f37cf270500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600061017260014361029c565b60408051808201825282408082524267ffffffffffffffff81811660208086018281526000898152918290528782209651875551600190960180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016969093169590951790915593519495509093909291849186917fb67ff58b33060fd371a35ae2d9f1c3cdaec9b8197969f6efe2594a1ff4ba68c691a4505090565b600060208083528351808285015260005b8181101561023d57858101830151858201604001528201610221565b8181111561024f576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561029557600080fd5b5035919050565b6000828210156102d5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", -} - -// BlockOracleABI is the input ABI used to generate the binding from. -// Deprecated: Use BlockOracleMetaData.ABI instead. -var BlockOracleABI = BlockOracleMetaData.ABI - -// BlockOracleBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use BlockOracleMetaData.Bin instead. -var BlockOracleBin = BlockOracleMetaData.Bin - -// DeployBlockOracle deploys a new Ethereum contract, binding an instance of BlockOracle to it. -func DeployBlockOracle(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *BlockOracle, error) { - parsed, err := BlockOracleMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BlockOracleBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &BlockOracle{BlockOracleCaller: BlockOracleCaller{contract: contract}, BlockOracleTransactor: BlockOracleTransactor{contract: contract}, BlockOracleFilterer: BlockOracleFilterer{contract: contract}}, nil -} - -// BlockOracle is an auto generated Go binding around an Ethereum contract. -type BlockOracle struct { - BlockOracleCaller // Read-only binding to the contract - BlockOracleTransactor // Write-only binding to the contract - BlockOracleFilterer // Log filterer for contract events -} - -// BlockOracleCaller is an auto generated read-only Go binding around an Ethereum contract. -type BlockOracleCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// BlockOracleTransactor is an auto generated write-only Go binding around an Ethereum contract. -type BlockOracleTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// BlockOracleFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type BlockOracleFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// BlockOracleSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type BlockOracleSession struct { - Contract *BlockOracle // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// BlockOracleCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type BlockOracleCallerSession struct { - Contract *BlockOracleCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// BlockOracleTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type BlockOracleTransactorSession struct { - Contract *BlockOracleTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// BlockOracleRaw is an auto generated low-level Go binding around an Ethereum contract. -type BlockOracleRaw struct { - Contract *BlockOracle // Generic contract binding to access the raw methods on -} - -// BlockOracleCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type BlockOracleCallerRaw struct { - Contract *BlockOracleCaller // Generic read-only contract binding to access the raw methods on -} - -// BlockOracleTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type BlockOracleTransactorRaw struct { - Contract *BlockOracleTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewBlockOracle creates a new instance of BlockOracle, bound to a specific deployed contract. -func NewBlockOracle(address common.Address, backend bind.ContractBackend) (*BlockOracle, error) { - contract, err := bindBlockOracle(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &BlockOracle{BlockOracleCaller: BlockOracleCaller{contract: contract}, BlockOracleTransactor: BlockOracleTransactor{contract: contract}, BlockOracleFilterer: BlockOracleFilterer{contract: contract}}, nil -} - -// NewBlockOracleCaller creates a new read-only instance of BlockOracle, bound to a specific deployed contract. -func NewBlockOracleCaller(address common.Address, caller bind.ContractCaller) (*BlockOracleCaller, error) { - contract, err := bindBlockOracle(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &BlockOracleCaller{contract: contract}, nil -} - -// NewBlockOracleTransactor creates a new write-only instance of BlockOracle, bound to a specific deployed contract. -func NewBlockOracleTransactor(address common.Address, transactor bind.ContractTransactor) (*BlockOracleTransactor, error) { - contract, err := bindBlockOracle(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &BlockOracleTransactor{contract: contract}, nil -} - -// NewBlockOracleFilterer creates a new log filterer instance of BlockOracle, bound to a specific deployed contract. -func NewBlockOracleFilterer(address common.Address, filterer bind.ContractFilterer) (*BlockOracleFilterer, error) { - contract, err := bindBlockOracle(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &BlockOracleFilterer{contract: contract}, nil -} - -// bindBlockOracle binds a generic wrapper to an already deployed contract. -func bindBlockOracle(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(BlockOracleABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_BlockOracle *BlockOracleRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _BlockOracle.Contract.BlockOracleCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_BlockOracle *BlockOracleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _BlockOracle.Contract.BlockOracleTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_BlockOracle *BlockOracleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _BlockOracle.Contract.BlockOracleTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_BlockOracle *BlockOracleCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _BlockOracle.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_BlockOracle *BlockOracleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _BlockOracle.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_BlockOracle *BlockOracleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _BlockOracle.Contract.contract.Transact(opts, method, params...) -} - -// Load is a free data retrieval call binding the contract method 0x99d548aa. -// -// Solidity: function load(uint256 _blockNumber) view returns((bytes32,uint64) blockInfo_) -func (_BlockOracle *BlockOracleCaller) Load(opts *bind.CallOpts, _blockNumber *big.Int) (BlockOracleBlockInfo, error) { - var out []interface{} - err := _BlockOracle.contract.Call(opts, &out, "load", _blockNumber) - - if err != nil { - return *new(BlockOracleBlockInfo), err - } - - out0 := *abi.ConvertType(out[0], new(BlockOracleBlockInfo)).(*BlockOracleBlockInfo) - - return out0, err - -} - -// Load is a free data retrieval call binding the contract method 0x99d548aa. -// -// Solidity: function load(uint256 _blockNumber) view returns((bytes32,uint64) blockInfo_) -func (_BlockOracle *BlockOracleSession) Load(_blockNumber *big.Int) (BlockOracleBlockInfo, error) { - return _BlockOracle.Contract.Load(&_BlockOracle.CallOpts, _blockNumber) -} - -// Load is a free data retrieval call binding the contract method 0x99d548aa. -// -// Solidity: function load(uint256 _blockNumber) view returns((bytes32,uint64) blockInfo_) -func (_BlockOracle *BlockOracleCallerSession) Load(_blockNumber *big.Int) (BlockOracleBlockInfo, error) { - return _BlockOracle.Contract.Load(&_BlockOracle.CallOpts, _blockNumber) -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() view returns(string) -func (_BlockOracle *BlockOracleCaller) Version(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _BlockOracle.contract.Call(opts, &out, "version") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() view returns(string) -func (_BlockOracle *BlockOracleSession) Version() (string, error) { - return _BlockOracle.Contract.Version(&_BlockOracle.CallOpts) -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() view returns(string) -func (_BlockOracle *BlockOracleCallerSession) Version() (string, error) { - return _BlockOracle.Contract.Version(&_BlockOracle.CallOpts) -} - -// Checkpoint is a paid mutator transaction binding the contract method 0xc2c4c5c1. -// -// Solidity: function checkpoint() returns(uint256 blockNumber_) -func (_BlockOracle *BlockOracleTransactor) Checkpoint(opts *bind.TransactOpts) (*types.Transaction, error) { - return _BlockOracle.contract.Transact(opts, "checkpoint") -} - -// Checkpoint is a paid mutator transaction binding the contract method 0xc2c4c5c1. -// -// Solidity: function checkpoint() returns(uint256 blockNumber_) -func (_BlockOracle *BlockOracleSession) Checkpoint() (*types.Transaction, error) { - return _BlockOracle.Contract.Checkpoint(&_BlockOracle.TransactOpts) -} - -// Checkpoint is a paid mutator transaction binding the contract method 0xc2c4c5c1. -// -// Solidity: function checkpoint() returns(uint256 blockNumber_) -func (_BlockOracle *BlockOracleTransactorSession) Checkpoint() (*types.Transaction, error) { - return _BlockOracle.Contract.Checkpoint(&_BlockOracle.TransactOpts) -} - -// BlockOracleCheckpointIterator is returned from FilterCheckpoint and is used to iterate over the raw logs and unpacked data for Checkpoint events raised by the BlockOracle contract. -type BlockOracleCheckpointIterator struct { - Event *BlockOracleCheckpoint // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *BlockOracleCheckpointIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(BlockOracleCheckpoint) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(BlockOracleCheckpoint) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *BlockOracleCheckpointIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *BlockOracleCheckpointIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// BlockOracleCheckpoint represents a Checkpoint event raised by the BlockOracle contract. -type BlockOracleCheckpoint struct { - BlockNumber *big.Int - BlockHash [32]byte - ChildTimestamp uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterCheckpoint is a free log retrieval operation binding the contract event 0xb67ff58b33060fd371a35ae2d9f1c3cdaec9b8197969f6efe2594a1ff4ba68c6. -// -// Solidity: event Checkpoint(uint256 indexed blockNumber, bytes32 indexed blockHash, uint64 indexed childTimestamp) -func (_BlockOracle *BlockOracleFilterer) FilterCheckpoint(opts *bind.FilterOpts, blockNumber []*big.Int, blockHash [][32]byte, childTimestamp []uint64) (*BlockOracleCheckpointIterator, error) { - - var blockNumberRule []interface{} - for _, blockNumberItem := range blockNumber { - blockNumberRule = append(blockNumberRule, blockNumberItem) - } - var blockHashRule []interface{} - for _, blockHashItem := range blockHash { - blockHashRule = append(blockHashRule, blockHashItem) - } - var childTimestampRule []interface{} - for _, childTimestampItem := range childTimestamp { - childTimestampRule = append(childTimestampRule, childTimestampItem) - } - - logs, sub, err := _BlockOracle.contract.FilterLogs(opts, "Checkpoint", blockNumberRule, blockHashRule, childTimestampRule) - if err != nil { - return nil, err - } - return &BlockOracleCheckpointIterator{contract: _BlockOracle.contract, event: "Checkpoint", logs: logs, sub: sub}, nil -} - -// WatchCheckpoint is a free log subscription operation binding the contract event 0xb67ff58b33060fd371a35ae2d9f1c3cdaec9b8197969f6efe2594a1ff4ba68c6. -// -// Solidity: event Checkpoint(uint256 indexed blockNumber, bytes32 indexed blockHash, uint64 indexed childTimestamp) -func (_BlockOracle *BlockOracleFilterer) WatchCheckpoint(opts *bind.WatchOpts, sink chan<- *BlockOracleCheckpoint, blockNumber []*big.Int, blockHash [][32]byte, childTimestamp []uint64) (event.Subscription, error) { - - var blockNumberRule []interface{} - for _, blockNumberItem := range blockNumber { - blockNumberRule = append(blockNumberRule, blockNumberItem) - } - var blockHashRule []interface{} - for _, blockHashItem := range blockHash { - blockHashRule = append(blockHashRule, blockHashItem) - } - var childTimestampRule []interface{} - for _, childTimestampItem := range childTimestamp { - childTimestampRule = append(childTimestampRule, childTimestampItem) - } - - logs, sub, err := _BlockOracle.contract.WatchLogs(opts, "Checkpoint", blockNumberRule, blockHashRule, childTimestampRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(BlockOracleCheckpoint) - if err := _BlockOracle.contract.UnpackLog(event, "Checkpoint", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseCheckpoint is a log parse operation binding the contract event 0xb67ff58b33060fd371a35ae2d9f1c3cdaec9b8197969f6efe2594a1ff4ba68c6. -// -// Solidity: event Checkpoint(uint256 indexed blockNumber, bytes32 indexed blockHash, uint64 indexed childTimestamp) -func (_BlockOracle *BlockOracleFilterer) ParseCheckpoint(log types.Log) (*BlockOracleCheckpoint, error) { - event := new(BlockOracleCheckpoint) - if err := _BlockOracle.contract.UnpackLog(event, "Checkpoint", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/op-bindings/bindings/blockoracle_more.go b/op-bindings/bindings/blockoracle_more.go deleted file mode 100644 index e50c0c007a6d..000000000000 --- a/op-bindings/bindings/blockoracle_more.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package bindings - -import ( - "encoding/json" - - "github.com/ethereum-optimism/optimism/op-bindings/solc" -) - -const BlockOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/dispute/BlockOracle.sol:BlockOracle\",\"label\":\"blocks\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_uint256,t_struct(BlockInfo)1001_storage)\"}],\"types\":{\"t_mapping(t_uint256,t_struct(BlockInfo)1001_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e struct BlockOracle.BlockInfo)\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_struct(BlockInfo)1001_storage\"},\"t_struct(BlockInfo)1001_storage\":{\"encoding\":\"inplace\",\"label\":\"struct BlockOracle.BlockInfo\",\"numberOfBytes\":\"64\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Hash)1002\":{\"encoding\":\"inplace\",\"label\":\"Hash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Timestamp)1003\":{\"encoding\":\"inplace\",\"label\":\"Timestamp\",\"numberOfBytes\":\"8\"}}}" - -var BlockOracleStorageLayout = new(solc.StorageLayout) - -var BlockOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806399d548aa14610098578063c2c4c5c1146100d0575b600080fd5b6100826040518060400160405280600581526020017f302e302e3100000000000000000000000000000000000000000000000000000081525081565b60405161008f9190610210565b60405180910390f35b6100ab6100a6366004610283565b6100e6565b604080518251815260209283015167ffffffffffffffff16928101929092520161008f565b6100d8610165565b60405190815260200161008f565b604080518082018252600080825260209182018190528381528082528281208351808501909452805480855260019091015467ffffffffffffffff169284019290925203610160576040517f37cf270500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600061017260014361029c565b60408051808201825282408082524267ffffffffffffffff81811660208086018281526000898152918290528782209651875551600190960180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016969093169590951790915593519495509093909291849186917fb67ff58b33060fd371a35ae2d9f1c3cdaec9b8197969f6efe2594a1ff4ba68c691a4505090565b600060208083528351808285015260005b8181101561023d57858101830151858201604001528201610221565b8181111561024f576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561029557600080fd5b5035919050565b6000828210156102d5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a" - -func init() { - if err := json.Unmarshal([]byte(BlockOracleStorageLayoutJSON), BlockOracleStorageLayout); err != nil { - panic(err) - } - - layouts["BlockOracle"] = BlockOracleStorageLayout - deployedBytecodes["BlockOracle"] = BlockOracleDeployedBin -} diff --git a/op-bindings/bindings/create2deployer.go b/op-bindings/bindings/create2deployer.go new file mode 100644 index 000000000000..5e2141ea7a4b --- /dev/null +++ b/op-bindings/bindings/create2deployer.go @@ -0,0 +1,327 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// Create2DeployerMetaData contains all meta data concerning the Create2Deployer contract. +var Create2DeployerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"codeHash\",\"type\":\"bytes32\"}],\"name\":\"computeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"codeHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"}],\"name\":\"computeAddressWithDeployer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"code\",\"type\":\"bytes\"}],\"name\":\"deploy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"deployERC1820Implementer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561001057600080fd5b50610630806100206000396000f3fe6080604052600436106100435760003560e01c8063076c37b21461004f578063481286e61461007157806356299481146100ba57806366cfa057146100da57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a366004610327565b6100fa565b005b34801561007d57600080fd5b5061009161008c366004610327565b61014a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100c657600080fd5b506100916100d5366004610349565b61015d565b3480156100e657600080fd5b5061006f6100f53660046103ca565b610172565b61014582826040518060200161010f9061031a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052610183565b505050565b600061015683836102e7565b9392505050565b600061016a8484846102f0565b949350505050565b61017d838383610183565b50505050565b6000834710156101f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b815160000361025f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f60448201526064016101eb565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610156576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f790000000000000060448201526064016101eb565b60006101568383305b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b61014e806104ad83390190565b6000806040838503121561033a57600080fd5b50508035926020909101359150565b60008060006060848603121561035e57600080fd5b8335925060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156103df57600080fd5b8335925060208401359150604084013567ffffffffffffffff8082111561040557600080fd5b818601915086601f83011261041957600080fd5b81358181111561042b5761042b61039b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156104715761047161039b565b8160405282815289602084870101111561048a57600080fd5b826020860160208301376000602084830101528095505050505050925092509256fe608060405234801561001057600080fd5b5061012e806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063249cb3fa14602d575b600080fd5b603c603836600460b1565b604e565b60405190815260200160405180910390f35b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16608857600060aa565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b45b9392505050565b6000806040838503121560c357600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811460ed57600080fd5b80915050925092905056fea26469706673582212205ffd4e6cede7d06a5daf93d48d0541fc68189eeb16608c1999a82063b666eb1164736f6c63430008130033a2646970667358221220fdc4a0fe96e3b21c108ca155438d37c9143fb01278a3c1d274948bad89c564ba64736f6c63430008130033", +} + +// Create2DeployerABI is the input ABI used to generate the binding from. +// Deprecated: Use Create2DeployerMetaData.ABI instead. +var Create2DeployerABI = Create2DeployerMetaData.ABI + +// Create2DeployerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use Create2DeployerMetaData.Bin instead. +var Create2DeployerBin = Create2DeployerMetaData.Bin + +// DeployCreate2Deployer deploys a new Ethereum contract, binding an instance of Create2Deployer to it. +func DeployCreate2Deployer(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Create2Deployer, error) { + parsed, err := Create2DeployerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(Create2DeployerBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Create2Deployer{Create2DeployerCaller: Create2DeployerCaller{contract: contract}, Create2DeployerTransactor: Create2DeployerTransactor{contract: contract}, Create2DeployerFilterer: Create2DeployerFilterer{contract: contract}}, nil +} + +// Create2Deployer is an auto generated Go binding around an Ethereum contract. +type Create2Deployer struct { + Create2DeployerCaller // Read-only binding to the contract + Create2DeployerTransactor // Write-only binding to the contract + Create2DeployerFilterer // Log filterer for contract events +} + +// Create2DeployerCaller is an auto generated read-only Go binding around an Ethereum contract. +type Create2DeployerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Create2DeployerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type Create2DeployerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Create2DeployerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type Create2DeployerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Create2DeployerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type Create2DeployerSession struct { + Contract *Create2Deployer // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// Create2DeployerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type Create2DeployerCallerSession struct { + Contract *Create2DeployerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// Create2DeployerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type Create2DeployerTransactorSession struct { + Contract *Create2DeployerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// Create2DeployerRaw is an auto generated low-level Go binding around an Ethereum contract. +type Create2DeployerRaw struct { + Contract *Create2Deployer // Generic contract binding to access the raw methods on +} + +// Create2DeployerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type Create2DeployerCallerRaw struct { + Contract *Create2DeployerCaller // Generic read-only contract binding to access the raw methods on +} + +// Create2DeployerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type Create2DeployerTransactorRaw struct { + Contract *Create2DeployerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewCreate2Deployer creates a new instance of Create2Deployer, bound to a specific deployed contract. +func NewCreate2Deployer(address common.Address, backend bind.ContractBackend) (*Create2Deployer, error) { + contract, err := bindCreate2Deployer(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Create2Deployer{Create2DeployerCaller: Create2DeployerCaller{contract: contract}, Create2DeployerTransactor: Create2DeployerTransactor{contract: contract}, Create2DeployerFilterer: Create2DeployerFilterer{contract: contract}}, nil +} + +// NewCreate2DeployerCaller creates a new read-only instance of Create2Deployer, bound to a specific deployed contract. +func NewCreate2DeployerCaller(address common.Address, caller bind.ContractCaller) (*Create2DeployerCaller, error) { + contract, err := bindCreate2Deployer(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &Create2DeployerCaller{contract: contract}, nil +} + +// NewCreate2DeployerTransactor creates a new write-only instance of Create2Deployer, bound to a specific deployed contract. +func NewCreate2DeployerTransactor(address common.Address, transactor bind.ContractTransactor) (*Create2DeployerTransactor, error) { + contract, err := bindCreate2Deployer(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &Create2DeployerTransactor{contract: contract}, nil +} + +// NewCreate2DeployerFilterer creates a new log filterer instance of Create2Deployer, bound to a specific deployed contract. +func NewCreate2DeployerFilterer(address common.Address, filterer bind.ContractFilterer) (*Create2DeployerFilterer, error) { + contract, err := bindCreate2Deployer(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &Create2DeployerFilterer{contract: contract}, nil +} + +// bindCreate2Deployer binds a generic wrapper to an already deployed contract. +func bindCreate2Deployer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(Create2DeployerABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Create2Deployer *Create2DeployerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Create2Deployer.Contract.Create2DeployerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Create2Deployer *Create2DeployerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Create2Deployer.Contract.Create2DeployerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Create2Deployer *Create2DeployerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Create2Deployer.Contract.Create2DeployerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Create2Deployer *Create2DeployerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Create2Deployer.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Create2Deployer *Create2DeployerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Create2Deployer.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Create2Deployer *Create2DeployerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Create2Deployer.Contract.contract.Transact(opts, method, params...) +} + +// ComputeAddress is a free data retrieval call binding the contract method 0x481286e6. +// +// Solidity: function computeAddress(bytes32 salt, bytes32 codeHash) view returns(address) +func (_Create2Deployer *Create2DeployerCaller) ComputeAddress(opts *bind.CallOpts, salt [32]byte, codeHash [32]byte) (common.Address, error) { + var out []interface{} + err := _Create2Deployer.contract.Call(opts, &out, "computeAddress", salt, codeHash) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// ComputeAddress is a free data retrieval call binding the contract method 0x481286e6. +// +// Solidity: function computeAddress(bytes32 salt, bytes32 codeHash) view returns(address) +func (_Create2Deployer *Create2DeployerSession) ComputeAddress(salt [32]byte, codeHash [32]byte) (common.Address, error) { + return _Create2Deployer.Contract.ComputeAddress(&_Create2Deployer.CallOpts, salt, codeHash) +} + +// ComputeAddress is a free data retrieval call binding the contract method 0x481286e6. +// +// Solidity: function computeAddress(bytes32 salt, bytes32 codeHash) view returns(address) +func (_Create2Deployer *Create2DeployerCallerSession) ComputeAddress(salt [32]byte, codeHash [32]byte) (common.Address, error) { + return _Create2Deployer.Contract.ComputeAddress(&_Create2Deployer.CallOpts, salt, codeHash) +} + +// ComputeAddressWithDeployer is a free data retrieval call binding the contract method 0x56299481. +// +// Solidity: function computeAddressWithDeployer(bytes32 salt, bytes32 codeHash, address deployer) pure returns(address) +func (_Create2Deployer *Create2DeployerCaller) ComputeAddressWithDeployer(opts *bind.CallOpts, salt [32]byte, codeHash [32]byte, deployer common.Address) (common.Address, error) { + var out []interface{} + err := _Create2Deployer.contract.Call(opts, &out, "computeAddressWithDeployer", salt, codeHash, deployer) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// ComputeAddressWithDeployer is a free data retrieval call binding the contract method 0x56299481. +// +// Solidity: function computeAddressWithDeployer(bytes32 salt, bytes32 codeHash, address deployer) pure returns(address) +func (_Create2Deployer *Create2DeployerSession) ComputeAddressWithDeployer(salt [32]byte, codeHash [32]byte, deployer common.Address) (common.Address, error) { + return _Create2Deployer.Contract.ComputeAddressWithDeployer(&_Create2Deployer.CallOpts, salt, codeHash, deployer) +} + +// ComputeAddressWithDeployer is a free data retrieval call binding the contract method 0x56299481. +// +// Solidity: function computeAddressWithDeployer(bytes32 salt, bytes32 codeHash, address deployer) pure returns(address) +func (_Create2Deployer *Create2DeployerCallerSession) ComputeAddressWithDeployer(salt [32]byte, codeHash [32]byte, deployer common.Address) (common.Address, error) { + return _Create2Deployer.Contract.ComputeAddressWithDeployer(&_Create2Deployer.CallOpts, salt, codeHash, deployer) +} + +// Deploy is a paid mutator transaction binding the contract method 0x66cfa057. +// +// Solidity: function deploy(uint256 value, bytes32 salt, bytes code) returns() +func (_Create2Deployer *Create2DeployerTransactor) Deploy(opts *bind.TransactOpts, value *big.Int, salt [32]byte, code []byte) (*types.Transaction, error) { + return _Create2Deployer.contract.Transact(opts, "deploy", value, salt, code) +} + +// Deploy is a paid mutator transaction binding the contract method 0x66cfa057. +// +// Solidity: function deploy(uint256 value, bytes32 salt, bytes code) returns() +func (_Create2Deployer *Create2DeployerSession) Deploy(value *big.Int, salt [32]byte, code []byte) (*types.Transaction, error) { + return _Create2Deployer.Contract.Deploy(&_Create2Deployer.TransactOpts, value, salt, code) +} + +// Deploy is a paid mutator transaction binding the contract method 0x66cfa057. +// +// Solidity: function deploy(uint256 value, bytes32 salt, bytes code) returns() +func (_Create2Deployer *Create2DeployerTransactorSession) Deploy(value *big.Int, salt [32]byte, code []byte) (*types.Transaction, error) { + return _Create2Deployer.Contract.Deploy(&_Create2Deployer.TransactOpts, value, salt, code) +} + +// DeployERC1820Implementer is a paid mutator transaction binding the contract method 0x076c37b2. +// +// Solidity: function deployERC1820Implementer(uint256 value, bytes32 salt) returns() +func (_Create2Deployer *Create2DeployerTransactor) DeployERC1820Implementer(opts *bind.TransactOpts, value *big.Int, salt [32]byte) (*types.Transaction, error) { + return _Create2Deployer.contract.Transact(opts, "deployERC1820Implementer", value, salt) +} + +// DeployERC1820Implementer is a paid mutator transaction binding the contract method 0x076c37b2. +// +// Solidity: function deployERC1820Implementer(uint256 value, bytes32 salt) returns() +func (_Create2Deployer *Create2DeployerSession) DeployERC1820Implementer(value *big.Int, salt [32]byte) (*types.Transaction, error) { + return _Create2Deployer.Contract.DeployERC1820Implementer(&_Create2Deployer.TransactOpts, value, salt) +} + +// DeployERC1820Implementer is a paid mutator transaction binding the contract method 0x076c37b2. +// +// Solidity: function deployERC1820Implementer(uint256 value, bytes32 salt) returns() +func (_Create2Deployer *Create2DeployerTransactorSession) DeployERC1820Implementer(value *big.Int, salt [32]byte) (*types.Transaction, error) { + return _Create2Deployer.Contract.DeployERC1820Implementer(&_Create2Deployer.TransactOpts, value, salt) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Create2Deployer *Create2DeployerTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Create2Deployer.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Create2Deployer *Create2DeployerSession) Receive() (*types.Transaction, error) { + return _Create2Deployer.Contract.Receive(&_Create2Deployer.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_Create2Deployer *Create2DeployerTransactorSession) Receive() (*types.Transaction, error) { + return _Create2Deployer.Contract.Receive(&_Create2Deployer.TransactOpts) +} diff --git a/op-bindings/bindings/create2deployer_more.go b/op-bindings/bindings/create2deployer_more.go new file mode 100644 index 000000000000..396d0fe6ed29 --- /dev/null +++ b/op-bindings/bindings/create2deployer_more.go @@ -0,0 +1,9 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var Create2DeployerDeployedBin = "0x6080604052600436106100435760003560e01c8063076c37b21461004f578063481286e61461007157806356299481146100ba57806366cfa057146100da57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a366004610327565b6100fa565b005b34801561007d57600080fd5b5061009161008c366004610327565b61014a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100c657600080fd5b506100916100d5366004610349565b61015d565b3480156100e657600080fd5b5061006f6100f53660046103ca565b610172565b61014582826040518060200161010f9061031a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052610183565b505050565b600061015683836102e7565b9392505050565b600061016a8484846102f0565b949350505050565b61017d838383610183565b50505050565b6000834710156101f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b815160000361025f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f60448201526064016101eb565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610156576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f790000000000000060448201526064016101eb565b60006101568383305b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b61014e806104ad83390190565b6000806040838503121561033a57600080fd5b50508035926020909101359150565b60008060006060848603121561035e57600080fd5b8335925060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156103df57600080fd5b8335925060208401359150604084013567ffffffffffffffff8082111561040557600080fd5b818601915086601f83011261041957600080fd5b81358181111561042b5761042b61039b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156104715761047161039b565b8160405282815289602084870101111561048a57600080fd5b826020860160208301376000602084830101528095505050505050925092509256fe608060405234801561001057600080fd5b5061012e806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063249cb3fa14602d575b600080fd5b603c603836600460b1565b604e565b60405190815260200160405180910390f35b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16608857600060aa565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b45b9392505050565b6000806040838503121560c357600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811460ed57600080fd5b80915050925092905056fea26469706673582212205ffd4e6cede7d06a5daf93d48d0541fc68189eeb16608c1999a82063b666eb1164736f6c63430008130033a2646970667358221220fdc4a0fe96e3b21c108ca155438d37c9143fb01278a3c1d274948bad89c564ba64736f6c63430008130033" +func init() { + deployedBytecodes["Create2Deployer"] = Create2DeployerDeployedBin +} diff --git a/op-bindings/bindings/crossdomainmessenger.go b/op-bindings/bindings/crossdomainmessenger.go index b70c4232a075..516b49cbffab 100644 --- a/op-bindings/bindings/crossdomainmessenger.go +++ b/op-bindings/bindings/crossdomainmessenger.go @@ -30,7 +30,7 @@ var ( // CrossDomainMessengerMetaData contains all meta data concerning the CrossDomainMessenger contract. var CrossDomainMessengerMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"FailedRelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"RelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"SentMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SentMessageExtension1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CALL_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_RESERVED_GAS\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"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\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"relayMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"sendMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"type\":\"function\",\"name\":\"MESSAGE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OTHER_MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_CALL_OVERHEAD\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_RESERVED_GAS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"baseGas\",\"inputs\":[{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"failedMessages\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"messageNonce\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"otherMessenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"relayMessage\",\"inputs\":[{\"name\":\"_nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"sendMessage\",\"inputs\":[{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"successfulMessages\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"xDomainMessageSender\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"FailedRelayedMessage\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RelayedMessage\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SentMessage\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"message\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"messageNonce\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"gasLimit\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SentMessageExtension1\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", } // CrossDomainMessengerABI is the input ABI used to generate the binding from. @@ -551,6 +551,68 @@ func (_CrossDomainMessenger *CrossDomainMessengerCallerSession) MessageNonce() ( return _CrossDomainMessenger.Contract.MessageNonce(&_CrossDomainMessenger.CallOpts) } +// OtherMessenger is a free data retrieval call binding the contract method 0xdb505d80. +// +// Solidity: function otherMessenger() view returns(address) +func (_CrossDomainMessenger *CrossDomainMessengerCaller) OtherMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CrossDomainMessenger.contract.Call(opts, &out, "otherMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// OtherMessenger is a free data retrieval call binding the contract method 0xdb505d80. +// +// Solidity: function otherMessenger() view returns(address) +func (_CrossDomainMessenger *CrossDomainMessengerSession) OtherMessenger() (common.Address, error) { + return _CrossDomainMessenger.Contract.OtherMessenger(&_CrossDomainMessenger.CallOpts) +} + +// OtherMessenger is a free data retrieval call binding the contract method 0xdb505d80. +// +// Solidity: function otherMessenger() view returns(address) +func (_CrossDomainMessenger *CrossDomainMessengerCallerSession) OtherMessenger() (common.Address, error) { + return _CrossDomainMessenger.Contract.OtherMessenger(&_CrossDomainMessenger.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_CrossDomainMessenger *CrossDomainMessengerCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CrossDomainMessenger.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_CrossDomainMessenger *CrossDomainMessengerSession) Paused() (bool, error) { + return _CrossDomainMessenger.Contract.Paused(&_CrossDomainMessenger.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_CrossDomainMessenger *CrossDomainMessengerCallerSession) Paused() (bool, error) { + return _CrossDomainMessenger.Contract.Paused(&_CrossDomainMessenger.CallOpts) +} + // SuccessfulMessages is a free data retrieval call binding the contract method 0xb1b1b209. // // Solidity: function successfulMessages(bytes32 ) view returns(bool) diff --git a/op-bindings/bindings/crossdomainmessenger_more.go b/op-bindings/bindings/crossdomainmessenger_more.go index a0134cebf4df..6e603a1fb9e5 100644 --- a/op-bindings/bindings/crossdomainmessenger_more.go +++ b/op-bindings/bindings/crossdomainmessenger_more.go @@ -9,12 +9,13 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1001,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1002,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1003,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_1_0_1600\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1004,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_51_0_20\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1005,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_52_0_1568\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1006,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_101_0_1\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":1007,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_102_0_1568\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1008,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_151_0_32\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":1009,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_152_0_1568\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1010,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1011,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1012,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1013,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":1014,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":1015,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"failedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1016,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\",\"base\":\"t_uint256\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1001,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1002,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1003,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_1_0_1600\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1004,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_51_0_20\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1005,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_52_0_1568\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1006,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_101_0_1\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":1007,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_102_0_1568\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1008,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_151_0_32\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":1009,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_152_0_1568\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1010,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1011,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1012,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1013,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":1014,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":1015,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"failedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1016,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"otherMessenger\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_contract(CrossDomainMessenger)1018\"},{\"astId\":1017,\"contract\":\"src/universal/CrossDomainMessenger.sol:CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"208\",\"type\":\"t_array(t_uint256)43_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)43_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[43]\",\"numberOfBytes\":\"1376\",\"base\":\"t_uint256\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_contract(CrossDomainMessenger)1018\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var CrossDomainMessengerStorageLayout = new(solc.StorageLayout) var CrossDomainMessengerDeployedBin = "0x" + func init() { if err := json.Unmarshal([]byte(CrossDomainMessengerStorageLayoutJSON), CrossDomainMessengerStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["CrossDomainMessenger"] = CrossDomainMessengerStorageLayout deployedBytecodes["CrossDomainMessenger"] = CrossDomainMessengerDeployedBin + immutableReferences["CrossDomainMessenger"] = false } diff --git a/op-bindings/bindings/dataavailabilitychallenge.go b/op-bindings/bindings/dataavailabilitychallenge.go new file mode 100644 index 000000000000..cbd8dd6edcec --- /dev/null +++ b/op-bindings/bindings/dataavailabilitychallenge.go @@ -0,0 +1,1678 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// Challenge is an auto generated low-level Go binding around an user-defined struct. +type Challenge struct { + Challenger common.Address + LockedBond *big.Int + StartBlock *big.Int + ResolvedBlock *big.Int +} + +// DataAvailabilityChallengeMetaData contains all meta data concerning the DataAvailabilityChallenge contract. +var DataAvailabilityChallengeMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"balances\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"bondSize\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"challenge\",\"inputs\":[{\"name\":\"challengedBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"challengedCommitment\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"challengeWindow\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deposit\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"fixedResolutionCost\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getChallenge\",\"inputs\":[{\"name\":\"challengedBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"challengedCommitment\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structChallenge\",\"components\":[{\"name\":\"challenger\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"lockedBond\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startBlock\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"resolvedBlock\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getChallengeStatus\",\"inputs\":[{\"name\":\"challengedBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"challengedCommitment\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumChallengeStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_challengeWindow\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_resolveWindow\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_bondSize\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_resolverRefundPercentage\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[{\"name\":\"challengedBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"challengedCommitment\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"resolveData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolveWindow\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resolverRefundPercentage\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setBondSize\",\"inputs\":[{\"name\":\"_bondSize\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setResolverRefundPercentage\",\"inputs\":[{\"name\":\"_resolverRefundPercentage\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unlockBond\",\"inputs\":[{\"name\":\"challengedBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"challengedCommitment\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"validateCommitment\",\"inputs\":[{\"name\":\"commitment\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"variableResolutionCost\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"variableResolutionCostPrecision\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"BalanceChanged\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"balance\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ChallengeStatusChanged\",\"inputs\":[{\"name\":\"challengedBlockNumber\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"challengedCommitment\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"enumChallengeStatus\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RequiredBondSizeChanged\",\"inputs\":[{\"name\":\"challengeWindow\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ResolverRefundPercentageChanged\",\"inputs\":[{\"name\":\"resolverRefundPercentage\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"BondTooLow\",\"inputs\":[{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"required\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ChallengeExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChallengeNotActive\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChallengeNotExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ChallengeWindowNotOpen\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidCommitmentLength\",\"inputs\":[{\"name\":\"commitmentType\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"expectedLength\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"actualLength\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"InvalidInputData\",\"inputs\":[{\"name\":\"providedDataCommitment\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"expectedCommitment\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"type\":\"error\",\"name\":\"InvalidResolverRefundPercentage\",\"inputs\":[{\"name\":\"invalidResolverRefundPercentage\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"UnknownCommitmentType\",\"inputs\":[{\"name\":\"commitmentType\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"type\":\"error\",\"name\":\"WithdrawalFailed\",\"inputs\":[]}]", + Bin: "0x60806040523480156200001157600080fd5b506200002461dead60008080806200002a565b62000392565b600054610100900460ff16158080156200004b5750600054600160ff909116105b806200007b575062000068306200018c60201b6200100e1760201c565b1580156200007b575060005460ff166001145b620000e45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000108576000805461ff0019166101001790555b620001126200019b565b60658590556066849055620001278362000203565b620001328262000248565b6200013d866200027d565b801562000184576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6001600160a01b03163b151590565b600054610100900460ff16620001f75760405162461bcd60e51b815260206004820152602b602482015260008051602062001d7783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000db565b62000201620002cf565b565b6200020d62000336565b60678190556040518181527f4468d695a0389e5f9e8ef0c9aee6d84e74cc0d0e0a28c8413badb54697d1bbae9060200160405180910390a150565b6200025262000336565b60648111156200027857604051622d549d60e71b815260048101829052602401620000db565b606855565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166200032b5760405162461bcd60e51b815260206004820152602b602482015260008051602062001d7783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000db565b62000201336200027d565b6033546001600160a01b03163314620002015760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000db565b6119d580620003a26000396000f3fe6080604052600436106101845760003560e01c8063848afb3d116100d6578063956118521161007f578063d7d04e5411610059578063d7d04e5414610459578063f2fde38b14610479578063f92ad2191461049957600080fd5b80639561185214610427578063a03aafbf1461043e578063d0e30db01461045157600080fd5b80638ecb85e1116100b05780638ecb85e1146103d157806393988233146103e757806393fb19441461040757600080fd5b8063848afb3d1461031d578063861a1412146103865780638da5cb5b1461039c57600080fd5b80634ebaf3ce11610138578063715018a611610112578063715018a6146102bb57806379e8a8b3146102d05780637ae929d9146102fd57600080fd5b80634ebaf3ce1461023957806354fd4d501461024f5780637099c581146102a557600080fd5b806327e235e31161016957806327e235e3146101d7578063336409fd146102045780633ccfd60b1461022457600080fd5b806321cf39ee1461019857806323c30f59146101c157600080fd5b36610193576101916104b9565b005b600080fd5b3480156101a457600080fd5b506101ae60665481565b6040519081526020015b60405180910390f35b3480156101cd57600080fd5b506101ae61410081565b3480156101e357600080fd5b506101ae6101f2366004611539565b60696020526000908152604090205481565b34801561021057600080fd5b5061019161021f366004611554565b610527565b34801561023057600080fd5b50610191610577565b34801561024557600080fd5b506101ae6103e881565b34801561025b57600080fd5b506102986040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101b891906115d8565b3480156102b157600080fd5b506101ae60675481565b3480156102c757600080fd5b50610191610611565b3480156102dc57600080fd5b506102f06102eb366004611634565b610625565b6040516101b891906116ea565b34801561030957600080fd5b506101916103183660046116f8565b6106e8565b34801561032957600080fd5b5061033d610338366004611634565b610884565b6040516101b89190815173ffffffffffffffffffffffffffffffffffffffff16815260208083015190820152604080830151908201526060918201519181019190915260800190565b34801561039257600080fd5b506101ae60655481565b3480156103a857600080fd5b5060335460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b8565b3480156103dd57600080fd5b506101ae60685481565b3480156103f357600080fd5b50610191610402366004611634565b610940565b34801561041357600080fd5b50610191610422366004611772565b610a72565b34801561043357600080fd5b506101ae62011cdd81565b61019161044c366004611634565b610b0f565b6101916104b9565b34801561046557600080fd5b50610191610474366004611554565b610d58565b34801561048557600080fd5b50610191610494366004611539565b610d9b565b3480156104a557600080fd5b506101916104b43660046117b4565b610e52565b33600090815260696020526040812080543492906104d8908490611825565b909155505033600081815260696020908152604091829020548251938452908301527fa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05910160405180910390a1565b61052f61102a565b6064811115610572576040517f16aa4e80000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b606855565b336000818152606960209081526040808320805490849055815194855291840192909252917fa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05910160405180910390a160006105d4335a846110ab565b90508061060d576040517f27fcd9d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b61061961102a565b61062360006110c1565b565b6000838152606a60205260408082209051829190610646908690869061183d565b9081526040805160209281900383018120608082018352805473ffffffffffffffffffffffffffffffffffffffff16808352600182015494830194909452600281015492820192909252600390910154606082015291506106ab5760009150506106e1565b6060810151156106bf5760029150506106e1565b6106cc8160400151611138565b156106db5760019150506106e1565b60039150505b9392505050565b6106f28484610a72565b60016106ff868686610625565b600381111561071057610710611680565b14610747576040517fbeb11d3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107538585611151565b9050606060ff82166107a15761079e84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061116992505050565b90505b85856040516107b192919061183d565b60405180910390208180519060200120146107fe578086866040517f1a0bbf9f00000000000000000000000000000000000000000000000000000000815260040161056993929190611896565b6000878152606a6020526040808220905161081c908990899061183d565b908152604051908190036020018120436003820155915088907fc5d8c630ba2fdacb1db24c4599df78c7fb8cf97b5aecde34939597f6697bb1ad90610867908a908a906002906118c6565b60405180910390a261087a81853361119c565b5050505050505050565b6108c56040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081525090565b6000848152606a60205260409081902090516108e4908590859061183d565b908152604080519182900360209081018320608084018352805473ffffffffffffffffffffffffffffffffffffffff16845260018101549184019190915260028101549183019190915260030154606082015290509392505050565b600361094d848484610625565b600381111561095e5761095e611680565b14610995576040517f151f07fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152606a602052604080822090516109b3908590859061183d565b90815260408051602092819003830190206001810154815473ffffffffffffffffffffffffffffffffffffffff16600090815260699094529183208054919450919290610a01908490611825565b9091555050600060018201819055815473ffffffffffffffffffffffffffffffffffffffff1680825260696020908152604092839020548351928352908201527fa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05910160405180910390a150505050565b6000610a7e8383611151565b905060ff8116610ad85760218214610ad3576040517ffd9a7e5b000000000000000000000000000000000000000000000000000000008152600060048201526021602482015260448101839052606401610569565b505050565b6040517f81ff071300000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610569565b610b198282610a72565b610b216104b9565b606754336000908152606960205260409020541015610b895733600090815260696020526040908190205460675491517e0155b50000000000000000000000000000000000000000000000000000000081526105699290600401918252602082015260400190565b6000610b96848484610625565b6003811115610ba757610ba7611680565b14610bde576040517f9bb6c64e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610be7836113bc565b610c1d576040517ff9e0d1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6067543360009081526069602052604081208054909190610c3f9084906118f1565b9250508190555060405180608001604052803373ffffffffffffffffffffffffffffffffffffffff16815260200160675481526020014381526020016000815250606a60008581526020019081526020016000208383604051610ca392919061183d565b9081526040805160209281900383018120845181547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781559284015160018085019190915591840151600284015560609093015160039092019190915584917fc5d8c630ba2fdacb1db24c4599df78c7fb8cf97b5aecde34939597f6697bb1ad91610d4b91869186916118c6565b60405180910390a2505050565b610d6061102a565b60678190556040518181527f4468d695a0389e5f9e8ef0c9aee6d84e74cc0d0e0a28c8413badb54697d1bbae9060200160405180910390a150565b610da361102a565b73ffffffffffffffffffffffffffffffffffffffff8116610e46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610569565b610e4f816110c1565b50565b600054610100900460ff1615808015610e725750600054600160ff909116105b80610e8c5750303b158015610e8c575060005460ff166001145b610f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610569565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610f7657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610f7e6113d6565b60658590556066849055610f9183610d58565b610f9a82610527565b610fa3866110c1565b801561100657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610623576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610569565b600080600080600080868989f195945050505050565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000606654826111489190611825565b43111592915050565b600061115d8284611908565b60f81c90505b92915050565b80516020918201206040805160009381019390935260218084019290925280518084039092018252604190920190915290565b6001830154835473ffffffffffffffffffffffffffffffffffffffff166000486103e86111cb61410088611950565b6111d5919061198d565b6111e29062011cdd611825565b6111ec9190611950565b90508083111561129e5761120081846118f1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526069602052604081208054909190611235908490611825565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152606960209081526040918290205482519384529083015291935083917fa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05910160405180910390a15b60006064606854836112b09190611950565b6112ba919061198d565b9050838111156112c75750825b80156113745773ffffffffffffffffffffffffffffffffffffffff851660009081526069602052604081208054839290611302908490611825565b90915550611312905081856118f1565b73ffffffffffffffffffffffffffffffffffffffff8616600081815260696020908152604091829020548251938452908301529195507fa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05910160405180910390a15b83156113a95760405160009085156108fc0290869083818181858288f193505050501580156113a7573d6000803e3d6000fd5b505b6000876001018190555050505050505050565b600081431015801561116357506065546111489083611825565b600054610100900460ff1661146d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610569565b610623600054610100900460ff16611507576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610569565b610623336110c1565b803573ffffffffffffffffffffffffffffffffffffffff8116811461153457600080fd5b919050565b60006020828403121561154b57600080fd5b6106e182611510565b60006020828403121561156657600080fd5b5035919050565b6000815180845260005b8181101561159357602081850181015186830182015201611577565b818111156115a5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106e1602083018461156d565b60008083601f8401126115fd57600080fd5b50813567ffffffffffffffff81111561161557600080fd5b60208301915083602082850101111561162d57600080fd5b9250929050565b60008060006040848603121561164957600080fd5b83359250602084013567ffffffffffffffff81111561166757600080fd5b611673868287016115eb565b9497909650939450505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600481106116e6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6020810161116382846116af565b60008060008060006060868803121561171057600080fd5b85359450602086013567ffffffffffffffff8082111561172f57600080fd5b61173b89838a016115eb565b9096509450604088013591508082111561175457600080fd5b50611761888289016115eb565b969995985093965092949392505050565b6000806020838503121561178557600080fd5b823567ffffffffffffffff81111561179c57600080fd5b6117a8858286016115eb565b90969095509350505050565b600080600080600060a086880312156117cc57600080fd5b6117d586611510565b97602087013597506040870135966060810135965060800135945092505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115611838576118386117f6565b500190565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6040815260006118a9604083018661156d565b82810360208401526118bc81858761184d565b9695505050505050565b6040815260006118da60408301858761184d565b90506118e960208301846116af565b949350505050565b600082821015611903576119036117f6565b500390565b7fff0000000000000000000000000000000000000000000000000000000000000081358181169160018510156119485780818660010360031b1b83161692505b505092915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611988576119886117f6565b500290565b6000826119c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", +} + +// DataAvailabilityChallengeABI is the input ABI used to generate the binding from. +// Deprecated: Use DataAvailabilityChallengeMetaData.ABI instead. +var DataAvailabilityChallengeABI = DataAvailabilityChallengeMetaData.ABI + +// DataAvailabilityChallengeBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use DataAvailabilityChallengeMetaData.Bin instead. +var DataAvailabilityChallengeBin = DataAvailabilityChallengeMetaData.Bin + +// DeployDataAvailabilityChallenge deploys a new Ethereum contract, binding an instance of DataAvailabilityChallenge to it. +func DeployDataAvailabilityChallenge(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *DataAvailabilityChallenge, error) { + parsed, err := DataAvailabilityChallengeMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DataAvailabilityChallengeBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &DataAvailabilityChallenge{DataAvailabilityChallengeCaller: DataAvailabilityChallengeCaller{contract: contract}, DataAvailabilityChallengeTransactor: DataAvailabilityChallengeTransactor{contract: contract}, DataAvailabilityChallengeFilterer: DataAvailabilityChallengeFilterer{contract: contract}}, nil +} + +// DataAvailabilityChallenge is an auto generated Go binding around an Ethereum contract. +type DataAvailabilityChallenge struct { + DataAvailabilityChallengeCaller // Read-only binding to the contract + DataAvailabilityChallengeTransactor // Write-only binding to the contract + DataAvailabilityChallengeFilterer // Log filterer for contract events +} + +// DataAvailabilityChallengeCaller is an auto generated read-only Go binding around an Ethereum contract. +type DataAvailabilityChallengeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DataAvailabilityChallengeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type DataAvailabilityChallengeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DataAvailabilityChallengeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type DataAvailabilityChallengeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DataAvailabilityChallengeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type DataAvailabilityChallengeSession struct { + Contract *DataAvailabilityChallenge // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// DataAvailabilityChallengeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type DataAvailabilityChallengeCallerSession struct { + Contract *DataAvailabilityChallengeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// DataAvailabilityChallengeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type DataAvailabilityChallengeTransactorSession struct { + Contract *DataAvailabilityChallengeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// DataAvailabilityChallengeRaw is an auto generated low-level Go binding around an Ethereum contract. +type DataAvailabilityChallengeRaw struct { + Contract *DataAvailabilityChallenge // Generic contract binding to access the raw methods on +} + +// DataAvailabilityChallengeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type DataAvailabilityChallengeCallerRaw struct { + Contract *DataAvailabilityChallengeCaller // Generic read-only contract binding to access the raw methods on +} + +// DataAvailabilityChallengeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type DataAvailabilityChallengeTransactorRaw struct { + Contract *DataAvailabilityChallengeTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewDataAvailabilityChallenge creates a new instance of DataAvailabilityChallenge, bound to a specific deployed contract. +func NewDataAvailabilityChallenge(address common.Address, backend bind.ContractBackend) (*DataAvailabilityChallenge, error) { + contract, err := bindDataAvailabilityChallenge(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &DataAvailabilityChallenge{DataAvailabilityChallengeCaller: DataAvailabilityChallengeCaller{contract: contract}, DataAvailabilityChallengeTransactor: DataAvailabilityChallengeTransactor{contract: contract}, DataAvailabilityChallengeFilterer: DataAvailabilityChallengeFilterer{contract: contract}}, nil +} + +// NewDataAvailabilityChallengeCaller creates a new read-only instance of DataAvailabilityChallenge, bound to a specific deployed contract. +func NewDataAvailabilityChallengeCaller(address common.Address, caller bind.ContractCaller) (*DataAvailabilityChallengeCaller, error) { + contract, err := bindDataAvailabilityChallenge(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &DataAvailabilityChallengeCaller{contract: contract}, nil +} + +// NewDataAvailabilityChallengeTransactor creates a new write-only instance of DataAvailabilityChallenge, bound to a specific deployed contract. +func NewDataAvailabilityChallengeTransactor(address common.Address, transactor bind.ContractTransactor) (*DataAvailabilityChallengeTransactor, error) { + contract, err := bindDataAvailabilityChallenge(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &DataAvailabilityChallengeTransactor{contract: contract}, nil +} + +// NewDataAvailabilityChallengeFilterer creates a new log filterer instance of DataAvailabilityChallenge, bound to a specific deployed contract. +func NewDataAvailabilityChallengeFilterer(address common.Address, filterer bind.ContractFilterer) (*DataAvailabilityChallengeFilterer, error) { + contract, err := bindDataAvailabilityChallenge(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &DataAvailabilityChallengeFilterer{contract: contract}, nil +} + +// bindDataAvailabilityChallenge binds a generic wrapper to an already deployed contract. +func bindDataAvailabilityChallenge(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(DataAvailabilityChallengeABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_DataAvailabilityChallenge *DataAvailabilityChallengeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DataAvailabilityChallenge.Contract.DataAvailabilityChallengeCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_DataAvailabilityChallenge *DataAvailabilityChallengeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.DataAvailabilityChallengeTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_DataAvailabilityChallenge *DataAvailabilityChallengeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.DataAvailabilityChallengeTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DataAvailabilityChallenge.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.contract.Transact(opts, method, params...) +} + +// Balances is a free data retrieval call binding the contract method 0x27e235e3. +// +// Solidity: function balances(address ) view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) Balances(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "balances", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Balances is a free data retrieval call binding the contract method 0x27e235e3. +// +// Solidity: function balances(address ) view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) Balances(arg0 common.Address) (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.Balances(&_DataAvailabilityChallenge.CallOpts, arg0) +} + +// Balances is a free data retrieval call binding the contract method 0x27e235e3. +// +// Solidity: function balances(address ) view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) Balances(arg0 common.Address) (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.Balances(&_DataAvailabilityChallenge.CallOpts, arg0) +} + +// BondSize is a free data retrieval call binding the contract method 0x7099c581. +// +// Solidity: function bondSize() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) BondSize(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "bondSize") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BondSize is a free data retrieval call binding the contract method 0x7099c581. +// +// Solidity: function bondSize() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) BondSize() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.BondSize(&_DataAvailabilityChallenge.CallOpts) +} + +// BondSize is a free data retrieval call binding the contract method 0x7099c581. +// +// Solidity: function bondSize() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) BondSize() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.BondSize(&_DataAvailabilityChallenge.CallOpts) +} + +// ChallengeWindow is a free data retrieval call binding the contract method 0x861a1412. +// +// Solidity: function challengeWindow() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) ChallengeWindow(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "challengeWindow") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ChallengeWindow is a free data retrieval call binding the contract method 0x861a1412. +// +// Solidity: function challengeWindow() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) ChallengeWindow() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.ChallengeWindow(&_DataAvailabilityChallenge.CallOpts) +} + +// ChallengeWindow is a free data retrieval call binding the contract method 0x861a1412. +// +// Solidity: function challengeWindow() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) ChallengeWindow() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.ChallengeWindow(&_DataAvailabilityChallenge.CallOpts) +} + +// FixedResolutionCost is a free data retrieval call binding the contract method 0x95611852. +// +// Solidity: function fixedResolutionCost() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) FixedResolutionCost(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "fixedResolutionCost") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// FixedResolutionCost is a free data retrieval call binding the contract method 0x95611852. +// +// Solidity: function fixedResolutionCost() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) FixedResolutionCost() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.FixedResolutionCost(&_DataAvailabilityChallenge.CallOpts) +} + +// FixedResolutionCost is a free data retrieval call binding the contract method 0x95611852. +// +// Solidity: function fixedResolutionCost() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) FixedResolutionCost() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.FixedResolutionCost(&_DataAvailabilityChallenge.CallOpts) +} + +// GetChallenge is a free data retrieval call binding the contract method 0x848afb3d. +// +// Solidity: function getChallenge(uint256 challengedBlockNumber, bytes challengedCommitment) view returns((address,uint256,uint256,uint256)) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) GetChallenge(opts *bind.CallOpts, challengedBlockNumber *big.Int, challengedCommitment []byte) (Challenge, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "getChallenge", challengedBlockNumber, challengedCommitment) + + if err != nil { + return *new(Challenge), err + } + + out0 := *abi.ConvertType(out[0], new(Challenge)).(*Challenge) + + return out0, err + +} + +// GetChallenge is a free data retrieval call binding the contract method 0x848afb3d. +// +// Solidity: function getChallenge(uint256 challengedBlockNumber, bytes challengedCommitment) view returns((address,uint256,uint256,uint256)) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) GetChallenge(challengedBlockNumber *big.Int, challengedCommitment []byte) (Challenge, error) { + return _DataAvailabilityChallenge.Contract.GetChallenge(&_DataAvailabilityChallenge.CallOpts, challengedBlockNumber, challengedCommitment) +} + +// GetChallenge is a free data retrieval call binding the contract method 0x848afb3d. +// +// Solidity: function getChallenge(uint256 challengedBlockNumber, bytes challengedCommitment) view returns((address,uint256,uint256,uint256)) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) GetChallenge(challengedBlockNumber *big.Int, challengedCommitment []byte) (Challenge, error) { + return _DataAvailabilityChallenge.Contract.GetChallenge(&_DataAvailabilityChallenge.CallOpts, challengedBlockNumber, challengedCommitment) +} + +// GetChallengeStatus is a free data retrieval call binding the contract method 0x79e8a8b3. +// +// Solidity: function getChallengeStatus(uint256 challengedBlockNumber, bytes challengedCommitment) view returns(uint8) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) GetChallengeStatus(opts *bind.CallOpts, challengedBlockNumber *big.Int, challengedCommitment []byte) (uint8, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "getChallengeStatus", challengedBlockNumber, challengedCommitment) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// GetChallengeStatus is a free data retrieval call binding the contract method 0x79e8a8b3. +// +// Solidity: function getChallengeStatus(uint256 challengedBlockNumber, bytes challengedCommitment) view returns(uint8) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) GetChallengeStatus(challengedBlockNumber *big.Int, challengedCommitment []byte) (uint8, error) { + return _DataAvailabilityChallenge.Contract.GetChallengeStatus(&_DataAvailabilityChallenge.CallOpts, challengedBlockNumber, challengedCommitment) +} + +// GetChallengeStatus is a free data retrieval call binding the contract method 0x79e8a8b3. +// +// Solidity: function getChallengeStatus(uint256 challengedBlockNumber, bytes challengedCommitment) view returns(uint8) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) GetChallengeStatus(challengedBlockNumber *big.Int, challengedCommitment []byte) (uint8, error) { + return _DataAvailabilityChallenge.Contract.GetChallengeStatus(&_DataAvailabilityChallenge.CallOpts, challengedBlockNumber, challengedCommitment) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) Owner() (common.Address, error) { + return _DataAvailabilityChallenge.Contract.Owner(&_DataAvailabilityChallenge.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) Owner() (common.Address, error) { + return _DataAvailabilityChallenge.Contract.Owner(&_DataAvailabilityChallenge.CallOpts) +} + +// ResolveWindow is a free data retrieval call binding the contract method 0x21cf39ee. +// +// Solidity: function resolveWindow() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) ResolveWindow(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "resolveWindow") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ResolveWindow is a free data retrieval call binding the contract method 0x21cf39ee. +// +// Solidity: function resolveWindow() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) ResolveWindow() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.ResolveWindow(&_DataAvailabilityChallenge.CallOpts) +} + +// ResolveWindow is a free data retrieval call binding the contract method 0x21cf39ee. +// +// Solidity: function resolveWindow() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) ResolveWindow() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.ResolveWindow(&_DataAvailabilityChallenge.CallOpts) +} + +// ResolverRefundPercentage is a free data retrieval call binding the contract method 0x8ecb85e1. +// +// Solidity: function resolverRefundPercentage() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) ResolverRefundPercentage(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "resolverRefundPercentage") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ResolverRefundPercentage is a free data retrieval call binding the contract method 0x8ecb85e1. +// +// Solidity: function resolverRefundPercentage() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) ResolverRefundPercentage() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.ResolverRefundPercentage(&_DataAvailabilityChallenge.CallOpts) +} + +// ResolverRefundPercentage is a free data retrieval call binding the contract method 0x8ecb85e1. +// +// Solidity: function resolverRefundPercentage() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) ResolverRefundPercentage() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.ResolverRefundPercentage(&_DataAvailabilityChallenge.CallOpts) +} + +// ValidateCommitment is a free data retrieval call binding the contract method 0x93fb1944. +// +// Solidity: function validateCommitment(bytes commitment) pure returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) ValidateCommitment(opts *bind.CallOpts, commitment []byte) error { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "validateCommitment", commitment) + + if err != nil { + return err + } + + return err + +} + +// ValidateCommitment is a free data retrieval call binding the contract method 0x93fb1944. +// +// Solidity: function validateCommitment(bytes commitment) pure returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) ValidateCommitment(commitment []byte) error { + return _DataAvailabilityChallenge.Contract.ValidateCommitment(&_DataAvailabilityChallenge.CallOpts, commitment) +} + +// ValidateCommitment is a free data retrieval call binding the contract method 0x93fb1944. +// +// Solidity: function validateCommitment(bytes commitment) pure returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) ValidateCommitment(commitment []byte) error { + return _DataAvailabilityChallenge.Contract.ValidateCommitment(&_DataAvailabilityChallenge.CallOpts, commitment) +} + +// VariableResolutionCost is a free data retrieval call binding the contract method 0x23c30f59. +// +// Solidity: function variableResolutionCost() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) VariableResolutionCost(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "variableResolutionCost") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// VariableResolutionCost is a free data retrieval call binding the contract method 0x23c30f59. +// +// Solidity: function variableResolutionCost() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) VariableResolutionCost() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.VariableResolutionCost(&_DataAvailabilityChallenge.CallOpts) +} + +// VariableResolutionCost is a free data retrieval call binding the contract method 0x23c30f59. +// +// Solidity: function variableResolutionCost() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) VariableResolutionCost() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.VariableResolutionCost(&_DataAvailabilityChallenge.CallOpts) +} + +// VariableResolutionCostPrecision is a free data retrieval call binding the contract method 0x4ebaf3ce. +// +// Solidity: function variableResolutionCostPrecision() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) VariableResolutionCostPrecision(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "variableResolutionCostPrecision") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// VariableResolutionCostPrecision is a free data retrieval call binding the contract method 0x4ebaf3ce. +// +// Solidity: function variableResolutionCostPrecision() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) VariableResolutionCostPrecision() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.VariableResolutionCostPrecision(&_DataAvailabilityChallenge.CallOpts) +} + +// VariableResolutionCostPrecision is a free data retrieval call binding the contract method 0x4ebaf3ce. +// +// Solidity: function variableResolutionCostPrecision() view returns(uint256) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) VariableResolutionCostPrecision() (*big.Int, error) { + return _DataAvailabilityChallenge.Contract.VariableResolutionCostPrecision(&_DataAvailabilityChallenge.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCaller) Version(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _DataAvailabilityChallenge.contract.Call(opts, &out, "version") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) Version() (string, error) { + return _DataAvailabilityChallenge.Contract.Version(&_DataAvailabilityChallenge.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeCallerSession) Version() (string, error) { + return _DataAvailabilityChallenge.Contract.Version(&_DataAvailabilityChallenge.CallOpts) +} + +// Challenge is a paid mutator transaction binding the contract method 0xa03aafbf. +// +// Solidity: function challenge(uint256 challengedBlockNumber, bytes challengedCommitment) payable returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) Challenge(opts *bind.TransactOpts, challengedBlockNumber *big.Int, challengedCommitment []byte) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.Transact(opts, "challenge", challengedBlockNumber, challengedCommitment) +} + +// Challenge is a paid mutator transaction binding the contract method 0xa03aafbf. +// +// Solidity: function challenge(uint256 challengedBlockNumber, bytes challengedCommitment) payable returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) Challenge(challengedBlockNumber *big.Int, challengedCommitment []byte) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Challenge(&_DataAvailabilityChallenge.TransactOpts, challengedBlockNumber, challengedCommitment) +} + +// Challenge is a paid mutator transaction binding the contract method 0xa03aafbf. +// +// Solidity: function challenge(uint256 challengedBlockNumber, bytes challengedCommitment) payable returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) Challenge(challengedBlockNumber *big.Int, challengedCommitment []byte) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Challenge(&_DataAvailabilityChallenge.TransactOpts, challengedBlockNumber, challengedCommitment) +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) Deposit(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.Transact(opts, "deposit") +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) Deposit() (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Deposit(&_DataAvailabilityChallenge.TransactOpts) +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) Deposit() (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Deposit(&_DataAvailabilityChallenge.TransactOpts) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf92ad219. +// +// Solidity: function initialize(address _owner, uint256 _challengeWindow, uint256 _resolveWindow, uint256 _bondSize, uint256 _resolverRefundPercentage) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) Initialize(opts *bind.TransactOpts, _owner common.Address, _challengeWindow *big.Int, _resolveWindow *big.Int, _bondSize *big.Int, _resolverRefundPercentage *big.Int) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.Transact(opts, "initialize", _owner, _challengeWindow, _resolveWindow, _bondSize, _resolverRefundPercentage) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf92ad219. +// +// Solidity: function initialize(address _owner, uint256 _challengeWindow, uint256 _resolveWindow, uint256 _bondSize, uint256 _resolverRefundPercentage) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) Initialize(_owner common.Address, _challengeWindow *big.Int, _resolveWindow *big.Int, _bondSize *big.Int, _resolverRefundPercentage *big.Int) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Initialize(&_DataAvailabilityChallenge.TransactOpts, _owner, _challengeWindow, _resolveWindow, _bondSize, _resolverRefundPercentage) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf92ad219. +// +// Solidity: function initialize(address _owner, uint256 _challengeWindow, uint256 _resolveWindow, uint256 _bondSize, uint256 _resolverRefundPercentage) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) Initialize(_owner common.Address, _challengeWindow *big.Int, _resolveWindow *big.Int, _bondSize *big.Int, _resolverRefundPercentage *big.Int) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Initialize(&_DataAvailabilityChallenge.TransactOpts, _owner, _challengeWindow, _resolveWindow, _bondSize, _resolverRefundPercentage) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) RenounceOwnership() (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.RenounceOwnership(&_DataAvailabilityChallenge.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.RenounceOwnership(&_DataAvailabilityChallenge.TransactOpts) +} + +// Resolve is a paid mutator transaction binding the contract method 0x7ae929d9. +// +// Solidity: function resolve(uint256 challengedBlockNumber, bytes challengedCommitment, bytes resolveData) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) Resolve(opts *bind.TransactOpts, challengedBlockNumber *big.Int, challengedCommitment []byte, resolveData []byte) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.Transact(opts, "resolve", challengedBlockNumber, challengedCommitment, resolveData) +} + +// Resolve is a paid mutator transaction binding the contract method 0x7ae929d9. +// +// Solidity: function resolve(uint256 challengedBlockNumber, bytes challengedCommitment, bytes resolveData) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) Resolve(challengedBlockNumber *big.Int, challengedCommitment []byte, resolveData []byte) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Resolve(&_DataAvailabilityChallenge.TransactOpts, challengedBlockNumber, challengedCommitment, resolveData) +} + +// Resolve is a paid mutator transaction binding the contract method 0x7ae929d9. +// +// Solidity: function resolve(uint256 challengedBlockNumber, bytes challengedCommitment, bytes resolveData) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) Resolve(challengedBlockNumber *big.Int, challengedCommitment []byte, resolveData []byte) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Resolve(&_DataAvailabilityChallenge.TransactOpts, challengedBlockNumber, challengedCommitment, resolveData) +} + +// SetBondSize is a paid mutator transaction binding the contract method 0xd7d04e54. +// +// Solidity: function setBondSize(uint256 _bondSize) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) SetBondSize(opts *bind.TransactOpts, _bondSize *big.Int) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.Transact(opts, "setBondSize", _bondSize) +} + +// SetBondSize is a paid mutator transaction binding the contract method 0xd7d04e54. +// +// Solidity: function setBondSize(uint256 _bondSize) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) SetBondSize(_bondSize *big.Int) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.SetBondSize(&_DataAvailabilityChallenge.TransactOpts, _bondSize) +} + +// SetBondSize is a paid mutator transaction binding the contract method 0xd7d04e54. +// +// Solidity: function setBondSize(uint256 _bondSize) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) SetBondSize(_bondSize *big.Int) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.SetBondSize(&_DataAvailabilityChallenge.TransactOpts, _bondSize) +} + +// SetResolverRefundPercentage is a paid mutator transaction binding the contract method 0x336409fd. +// +// Solidity: function setResolverRefundPercentage(uint256 _resolverRefundPercentage) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) SetResolverRefundPercentage(opts *bind.TransactOpts, _resolverRefundPercentage *big.Int) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.Transact(opts, "setResolverRefundPercentage", _resolverRefundPercentage) +} + +// SetResolverRefundPercentage is a paid mutator transaction binding the contract method 0x336409fd. +// +// Solidity: function setResolverRefundPercentage(uint256 _resolverRefundPercentage) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) SetResolverRefundPercentage(_resolverRefundPercentage *big.Int) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.SetResolverRefundPercentage(&_DataAvailabilityChallenge.TransactOpts, _resolverRefundPercentage) +} + +// SetResolverRefundPercentage is a paid mutator transaction binding the contract method 0x336409fd. +// +// Solidity: function setResolverRefundPercentage(uint256 _resolverRefundPercentage) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) SetResolverRefundPercentage(_resolverRefundPercentage *big.Int) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.SetResolverRefundPercentage(&_DataAvailabilityChallenge.TransactOpts, _resolverRefundPercentage) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.TransferOwnership(&_DataAvailabilityChallenge.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.TransferOwnership(&_DataAvailabilityChallenge.TransactOpts, newOwner) +} + +// UnlockBond is a paid mutator transaction binding the contract method 0x93988233. +// +// Solidity: function unlockBond(uint256 challengedBlockNumber, bytes challengedCommitment) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) UnlockBond(opts *bind.TransactOpts, challengedBlockNumber *big.Int, challengedCommitment []byte) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.Transact(opts, "unlockBond", challengedBlockNumber, challengedCommitment) +} + +// UnlockBond is a paid mutator transaction binding the contract method 0x93988233. +// +// Solidity: function unlockBond(uint256 challengedBlockNumber, bytes challengedCommitment) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) UnlockBond(challengedBlockNumber *big.Int, challengedCommitment []byte) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.UnlockBond(&_DataAvailabilityChallenge.TransactOpts, challengedBlockNumber, challengedCommitment) +} + +// UnlockBond is a paid mutator transaction binding the contract method 0x93988233. +// +// Solidity: function unlockBond(uint256 challengedBlockNumber, bytes challengedCommitment) returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) UnlockBond(challengedBlockNumber *big.Int, challengedCommitment []byte) (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.UnlockBond(&_DataAvailabilityChallenge.TransactOpts, challengedBlockNumber, challengedCommitment) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x3ccfd60b. +// +// Solidity: function withdraw() returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) Withdraw(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.Transact(opts, "withdraw") +} + +// Withdraw is a paid mutator transaction binding the contract method 0x3ccfd60b. +// +// Solidity: function withdraw() returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) Withdraw() (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Withdraw(&_DataAvailabilityChallenge.TransactOpts) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x3ccfd60b. +// +// Solidity: function withdraw() returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) Withdraw() (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Withdraw(&_DataAvailabilityChallenge.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DataAvailabilityChallenge.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeSession) Receive() (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Receive(&_DataAvailabilityChallenge.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_DataAvailabilityChallenge *DataAvailabilityChallengeTransactorSession) Receive() (*types.Transaction, error) { + return _DataAvailabilityChallenge.Contract.Receive(&_DataAvailabilityChallenge.TransactOpts) +} + +// DataAvailabilityChallengeBalanceChangedIterator is returned from FilterBalanceChanged and is used to iterate over the raw logs and unpacked data for BalanceChanged events raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeBalanceChangedIterator struct { + Event *DataAvailabilityChallengeBalanceChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DataAvailabilityChallengeBalanceChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeBalanceChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeBalanceChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DataAvailabilityChallengeBalanceChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DataAvailabilityChallengeBalanceChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DataAvailabilityChallengeBalanceChanged represents a BalanceChanged event raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeBalanceChanged struct { + Account common.Address + Balance *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBalanceChanged is a free log retrieval operation binding the contract event 0xa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05. +// +// Solidity: event BalanceChanged(address account, uint256 balance) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) FilterBalanceChanged(opts *bind.FilterOpts) (*DataAvailabilityChallengeBalanceChangedIterator, error) { + + logs, sub, err := _DataAvailabilityChallenge.contract.FilterLogs(opts, "BalanceChanged") + if err != nil { + return nil, err + } + return &DataAvailabilityChallengeBalanceChangedIterator{contract: _DataAvailabilityChallenge.contract, event: "BalanceChanged", logs: logs, sub: sub}, nil +} + +// WatchBalanceChanged is a free log subscription operation binding the contract event 0xa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05. +// +// Solidity: event BalanceChanged(address account, uint256 balance) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) WatchBalanceChanged(opts *bind.WatchOpts, sink chan<- *DataAvailabilityChallengeBalanceChanged) (event.Subscription, error) { + + logs, sub, err := _DataAvailabilityChallenge.contract.WatchLogs(opts, "BalanceChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DataAvailabilityChallengeBalanceChanged) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "BalanceChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseBalanceChanged is a log parse operation binding the contract event 0xa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05. +// +// Solidity: event BalanceChanged(address account, uint256 balance) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) ParseBalanceChanged(log types.Log) (*DataAvailabilityChallengeBalanceChanged, error) { + event := new(DataAvailabilityChallengeBalanceChanged) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "BalanceChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DataAvailabilityChallengeChallengeStatusChangedIterator is returned from FilterChallengeStatusChanged and is used to iterate over the raw logs and unpacked data for ChallengeStatusChanged events raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeChallengeStatusChangedIterator struct { + Event *DataAvailabilityChallengeChallengeStatusChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DataAvailabilityChallengeChallengeStatusChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeChallengeStatusChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeChallengeStatusChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DataAvailabilityChallengeChallengeStatusChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DataAvailabilityChallengeChallengeStatusChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DataAvailabilityChallengeChallengeStatusChanged represents a ChallengeStatusChanged event raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeChallengeStatusChanged struct { + ChallengedBlockNumber *big.Int + ChallengedCommitment []byte + Status uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChallengeStatusChanged is a free log retrieval operation binding the contract event 0xc5d8c630ba2fdacb1db24c4599df78c7fb8cf97b5aecde34939597f6697bb1ad. +// +// Solidity: event ChallengeStatusChanged(uint256 indexed challengedBlockNumber, bytes challengedCommitment, uint8 status) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) FilterChallengeStatusChanged(opts *bind.FilterOpts, challengedBlockNumber []*big.Int) (*DataAvailabilityChallengeChallengeStatusChangedIterator, error) { + + var challengedBlockNumberRule []interface{} + for _, challengedBlockNumberItem := range challengedBlockNumber { + challengedBlockNumberRule = append(challengedBlockNumberRule, challengedBlockNumberItem) + } + + logs, sub, err := _DataAvailabilityChallenge.contract.FilterLogs(opts, "ChallengeStatusChanged", challengedBlockNumberRule) + if err != nil { + return nil, err + } + return &DataAvailabilityChallengeChallengeStatusChangedIterator{contract: _DataAvailabilityChallenge.contract, event: "ChallengeStatusChanged", logs: logs, sub: sub}, nil +} + +// WatchChallengeStatusChanged is a free log subscription operation binding the contract event 0xc5d8c630ba2fdacb1db24c4599df78c7fb8cf97b5aecde34939597f6697bb1ad. +// +// Solidity: event ChallengeStatusChanged(uint256 indexed challengedBlockNumber, bytes challengedCommitment, uint8 status) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) WatchChallengeStatusChanged(opts *bind.WatchOpts, sink chan<- *DataAvailabilityChallengeChallengeStatusChanged, challengedBlockNumber []*big.Int) (event.Subscription, error) { + + var challengedBlockNumberRule []interface{} + for _, challengedBlockNumberItem := range challengedBlockNumber { + challengedBlockNumberRule = append(challengedBlockNumberRule, challengedBlockNumberItem) + } + + logs, sub, err := _DataAvailabilityChallenge.contract.WatchLogs(opts, "ChallengeStatusChanged", challengedBlockNumberRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DataAvailabilityChallengeChallengeStatusChanged) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "ChallengeStatusChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChallengeStatusChanged is a log parse operation binding the contract event 0xc5d8c630ba2fdacb1db24c4599df78c7fb8cf97b5aecde34939597f6697bb1ad. +// +// Solidity: event ChallengeStatusChanged(uint256 indexed challengedBlockNumber, bytes challengedCommitment, uint8 status) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) ParseChallengeStatusChanged(log types.Log) (*DataAvailabilityChallengeChallengeStatusChanged, error) { + event := new(DataAvailabilityChallengeChallengeStatusChanged) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "ChallengeStatusChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DataAvailabilityChallengeInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeInitializedIterator struct { + Event *DataAvailabilityChallengeInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DataAvailabilityChallengeInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DataAvailabilityChallengeInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DataAvailabilityChallengeInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DataAvailabilityChallengeInitialized represents a Initialized event raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) FilterInitialized(opts *bind.FilterOpts) (*DataAvailabilityChallengeInitializedIterator, error) { + + logs, sub, err := _DataAvailabilityChallenge.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &DataAvailabilityChallengeInitializedIterator{contract: _DataAvailabilityChallenge.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *DataAvailabilityChallengeInitialized) (event.Subscription, error) { + + logs, sub, err := _DataAvailabilityChallenge.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DataAvailabilityChallengeInitialized) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) ParseInitialized(log types.Log) (*DataAvailabilityChallengeInitialized, error) { + event := new(DataAvailabilityChallengeInitialized) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DataAvailabilityChallengeOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeOwnershipTransferredIterator struct { + Event *DataAvailabilityChallengeOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DataAvailabilityChallengeOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DataAvailabilityChallengeOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DataAvailabilityChallengeOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DataAvailabilityChallengeOwnershipTransferred represents a OwnershipTransferred event raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*DataAvailabilityChallengeOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _DataAvailabilityChallenge.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &DataAvailabilityChallengeOwnershipTransferredIterator{contract: _DataAvailabilityChallenge.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DataAvailabilityChallengeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _DataAvailabilityChallenge.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DataAvailabilityChallengeOwnershipTransferred) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) ParseOwnershipTransferred(log types.Log) (*DataAvailabilityChallengeOwnershipTransferred, error) { + event := new(DataAvailabilityChallengeOwnershipTransferred) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DataAvailabilityChallengeRequiredBondSizeChangedIterator is returned from FilterRequiredBondSizeChanged and is used to iterate over the raw logs and unpacked data for RequiredBondSizeChanged events raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeRequiredBondSizeChangedIterator struct { + Event *DataAvailabilityChallengeRequiredBondSizeChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DataAvailabilityChallengeRequiredBondSizeChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeRequiredBondSizeChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeRequiredBondSizeChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DataAvailabilityChallengeRequiredBondSizeChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DataAvailabilityChallengeRequiredBondSizeChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DataAvailabilityChallengeRequiredBondSizeChanged represents a RequiredBondSizeChanged event raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeRequiredBondSizeChanged struct { + ChallengeWindow *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRequiredBondSizeChanged is a free log retrieval operation binding the contract event 0x4468d695a0389e5f9e8ef0c9aee6d84e74cc0d0e0a28c8413badb54697d1bbae. +// +// Solidity: event RequiredBondSizeChanged(uint256 challengeWindow) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) FilterRequiredBondSizeChanged(opts *bind.FilterOpts) (*DataAvailabilityChallengeRequiredBondSizeChangedIterator, error) { + + logs, sub, err := _DataAvailabilityChallenge.contract.FilterLogs(opts, "RequiredBondSizeChanged") + if err != nil { + return nil, err + } + return &DataAvailabilityChallengeRequiredBondSizeChangedIterator{contract: _DataAvailabilityChallenge.contract, event: "RequiredBondSizeChanged", logs: logs, sub: sub}, nil +} + +// WatchRequiredBondSizeChanged is a free log subscription operation binding the contract event 0x4468d695a0389e5f9e8ef0c9aee6d84e74cc0d0e0a28c8413badb54697d1bbae. +// +// Solidity: event RequiredBondSizeChanged(uint256 challengeWindow) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) WatchRequiredBondSizeChanged(opts *bind.WatchOpts, sink chan<- *DataAvailabilityChallengeRequiredBondSizeChanged) (event.Subscription, error) { + + logs, sub, err := _DataAvailabilityChallenge.contract.WatchLogs(opts, "RequiredBondSizeChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DataAvailabilityChallengeRequiredBondSizeChanged) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "RequiredBondSizeChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRequiredBondSizeChanged is a log parse operation binding the contract event 0x4468d695a0389e5f9e8ef0c9aee6d84e74cc0d0e0a28c8413badb54697d1bbae. +// +// Solidity: event RequiredBondSizeChanged(uint256 challengeWindow) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) ParseRequiredBondSizeChanged(log types.Log) (*DataAvailabilityChallengeRequiredBondSizeChanged, error) { + event := new(DataAvailabilityChallengeRequiredBondSizeChanged) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "RequiredBondSizeChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DataAvailabilityChallengeResolverRefundPercentageChangedIterator is returned from FilterResolverRefundPercentageChanged and is used to iterate over the raw logs and unpacked data for ResolverRefundPercentageChanged events raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeResolverRefundPercentageChangedIterator struct { + Event *DataAvailabilityChallengeResolverRefundPercentageChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DataAvailabilityChallengeResolverRefundPercentageChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeResolverRefundPercentageChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DataAvailabilityChallengeResolverRefundPercentageChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DataAvailabilityChallengeResolverRefundPercentageChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DataAvailabilityChallengeResolverRefundPercentageChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DataAvailabilityChallengeResolverRefundPercentageChanged represents a ResolverRefundPercentageChanged event raised by the DataAvailabilityChallenge contract. +type DataAvailabilityChallengeResolverRefundPercentageChanged struct { + ResolverRefundPercentage *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterResolverRefundPercentageChanged is a free log retrieval operation binding the contract event 0xbbd8605de8f773fedb355c2fecd4b6b2e16a10a44e6676a63b375ac8f693758d. +// +// Solidity: event ResolverRefundPercentageChanged(uint256 resolverRefundPercentage) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) FilterResolverRefundPercentageChanged(opts *bind.FilterOpts) (*DataAvailabilityChallengeResolverRefundPercentageChangedIterator, error) { + + logs, sub, err := _DataAvailabilityChallenge.contract.FilterLogs(opts, "ResolverRefundPercentageChanged") + if err != nil { + return nil, err + } + return &DataAvailabilityChallengeResolverRefundPercentageChangedIterator{contract: _DataAvailabilityChallenge.contract, event: "ResolverRefundPercentageChanged", logs: logs, sub: sub}, nil +} + +// WatchResolverRefundPercentageChanged is a free log subscription operation binding the contract event 0xbbd8605de8f773fedb355c2fecd4b6b2e16a10a44e6676a63b375ac8f693758d. +// +// Solidity: event ResolverRefundPercentageChanged(uint256 resolverRefundPercentage) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) WatchResolverRefundPercentageChanged(opts *bind.WatchOpts, sink chan<- *DataAvailabilityChallengeResolverRefundPercentageChanged) (event.Subscription, error) { + + logs, sub, err := _DataAvailabilityChallenge.contract.WatchLogs(opts, "ResolverRefundPercentageChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DataAvailabilityChallengeResolverRefundPercentageChanged) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "ResolverRefundPercentageChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseResolverRefundPercentageChanged is a log parse operation binding the contract event 0xbbd8605de8f773fedb355c2fecd4b6b2e16a10a44e6676a63b375ac8f693758d. +// +// Solidity: event ResolverRefundPercentageChanged(uint256 resolverRefundPercentage) +func (_DataAvailabilityChallenge *DataAvailabilityChallengeFilterer) ParseResolverRefundPercentageChanged(log types.Log) (*DataAvailabilityChallengeResolverRefundPercentageChanged, error) { + event := new(DataAvailabilityChallengeResolverRefundPercentageChanged) + if err := _DataAvailabilityChallenge.contract.UnpackLog(event, "ResolverRefundPercentageChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-bindings/bindings/dataavailabilitychallenge_more.go b/op-bindings/bindings/dataavailabilitychallenge_more.go new file mode 100644 index 000000000000..01d69710123b --- /dev/null +++ b/op-bindings/bindings/dataavailabilitychallenge_more.go @@ -0,0 +1,27 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "encoding/json" + + "github.com/ethereum-optimism/optimism/op-bindings/solc" +) + +const DataAvailabilityChallengeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1003,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1005,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"challengeWindow\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_uint256\"},{\"astId\":1006,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"resolveWindow\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_uint256\"},{\"astId\":1007,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"bondSize\",\"offset\":0,\"slot\":\"103\",\"type\":\"t_uint256\"},{\"astId\":1008,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"resolverRefundPercentage\",\"offset\":0,\"slot\":\"104\",\"type\":\"t_uint256\"},{\"astId\":1009,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"balances\",\"offset\":0,\"slot\":\"105\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":1010,\"contract\":\"src/L1/DataAvailabilityChallenge.sol:DataAvailabilityChallenge\",\"label\":\"challenges\",\"offset\":0,\"slot\":\"106\",\"type\":\"t_mapping(t_uint256,t_mapping(t_bytes_memory_ptr,t_struct(Challenge)1011_storage))\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes_memory_ptr\":{\"encoding\":\"bytes\",\"label\":\"bytes\",\"numberOfBytes\":\"32\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_mapping(t_bytes_memory_ptr,t_struct(Challenge)1011_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes =\u003e struct Challenge)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes_memory_ptr\",\"value\":\"t_struct(Challenge)1011_storage\"},\"t_mapping(t_uint256,t_mapping(t_bytes_memory_ptr,t_struct(Challenge)1011_storage))\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e mapping(bytes =\u003e struct Challenge))\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_mapping(t_bytes_memory_ptr,t_struct(Challenge)1011_storage)\"},\"t_struct(Challenge)1011_storage\":{\"encoding\":\"inplace\",\"label\":\"struct Challenge\",\"numberOfBytes\":\"128\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" + +var DataAvailabilityChallengeStorageLayout = new(solc.StorageLayout) + +var DataAvailabilityChallengeDeployedBin = "0x6080604052600436106101845760003560e01c8063848afb3d116100d6578063956118521161007f578063d7d04e5411610059578063d7d04e5414610459578063f2fde38b14610479578063f92ad2191461049957600080fd5b80639561185214610427578063a03aafbf1461043e578063d0e30db01461045157600080fd5b80638ecb85e1116100b05780638ecb85e1146103d157806393988233146103e757806393fb19441461040757600080fd5b8063848afb3d1461031d578063861a1412146103865780638da5cb5b1461039c57600080fd5b80634ebaf3ce11610138578063715018a611610112578063715018a6146102bb57806379e8a8b3146102d05780637ae929d9146102fd57600080fd5b80634ebaf3ce1461023957806354fd4d501461024f5780637099c581146102a557600080fd5b806327e235e31161016957806327e235e3146101d7578063336409fd146102045780633ccfd60b1461022457600080fd5b806321cf39ee1461019857806323c30f59146101c157600080fd5b36610193576101916104b9565b005b600080fd5b3480156101a457600080fd5b506101ae60665481565b6040519081526020015b60405180910390f35b3480156101cd57600080fd5b506101ae61410081565b3480156101e357600080fd5b506101ae6101f2366004611539565b60696020526000908152604090205481565b34801561021057600080fd5b5061019161021f366004611554565b610527565b34801561023057600080fd5b50610191610577565b34801561024557600080fd5b506101ae6103e881565b34801561025b57600080fd5b506102986040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101b891906115d8565b3480156102b157600080fd5b506101ae60675481565b3480156102c757600080fd5b50610191610611565b3480156102dc57600080fd5b506102f06102eb366004611634565b610625565b6040516101b891906116ea565b34801561030957600080fd5b506101916103183660046116f8565b6106e8565b34801561032957600080fd5b5061033d610338366004611634565b610884565b6040516101b89190815173ffffffffffffffffffffffffffffffffffffffff16815260208083015190820152604080830151908201526060918201519181019190915260800190565b34801561039257600080fd5b506101ae60655481565b3480156103a857600080fd5b5060335460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b8565b3480156103dd57600080fd5b506101ae60685481565b3480156103f357600080fd5b50610191610402366004611634565b610940565b34801561041357600080fd5b50610191610422366004611772565b610a72565b34801561043357600080fd5b506101ae62011cdd81565b61019161044c366004611634565b610b0f565b6101916104b9565b34801561046557600080fd5b50610191610474366004611554565b610d58565b34801561048557600080fd5b50610191610494366004611539565b610d9b565b3480156104a557600080fd5b506101916104b43660046117b4565b610e52565b33600090815260696020526040812080543492906104d8908490611825565b909155505033600081815260696020908152604091829020548251938452908301527fa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05910160405180910390a1565b61052f61102a565b6064811115610572576040517f16aa4e80000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b606855565b336000818152606960209081526040808320805490849055815194855291840192909252917fa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05910160405180910390a160006105d4335a846110ab565b90508061060d576040517f27fcd9d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b61061961102a565b61062360006110c1565b565b6000838152606a60205260408082209051829190610646908690869061183d565b9081526040805160209281900383018120608082018352805473ffffffffffffffffffffffffffffffffffffffff16808352600182015494830194909452600281015492820192909252600390910154606082015291506106ab5760009150506106e1565b6060810151156106bf5760029150506106e1565b6106cc8160400151611138565b156106db5760019150506106e1565b60039150505b9392505050565b6106f28484610a72565b60016106ff868686610625565b600381111561071057610710611680565b14610747576040517fbeb11d3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107538585611151565b9050606060ff82166107a15761079e84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061116992505050565b90505b85856040516107b192919061183d565b60405180910390208180519060200120146107fe578086866040517f1a0bbf9f00000000000000000000000000000000000000000000000000000000815260040161056993929190611896565b6000878152606a6020526040808220905161081c908990899061183d565b908152604051908190036020018120436003820155915088907fc5d8c630ba2fdacb1db24c4599df78c7fb8cf97b5aecde34939597f6697bb1ad90610867908a908a906002906118c6565b60405180910390a261087a81853361119c565b5050505050505050565b6108c56040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081525090565b6000848152606a60205260409081902090516108e4908590859061183d565b908152604080519182900360209081018320608084018352805473ffffffffffffffffffffffffffffffffffffffff16845260018101549184019190915260028101549183019190915260030154606082015290509392505050565b600361094d848484610625565b600381111561095e5761095e611680565b14610995576040517f151f07fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152606a602052604080822090516109b3908590859061183d565b90815260408051602092819003830190206001810154815473ffffffffffffffffffffffffffffffffffffffff16600090815260699094529183208054919450919290610a01908490611825565b9091555050600060018201819055815473ffffffffffffffffffffffffffffffffffffffff1680825260696020908152604092839020548351928352908201527fa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05910160405180910390a150505050565b6000610a7e8383611151565b905060ff8116610ad85760218214610ad3576040517ffd9a7e5b000000000000000000000000000000000000000000000000000000008152600060048201526021602482015260448101839052606401610569565b505050565b6040517f81ff071300000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610569565b610b198282610a72565b610b216104b9565b606754336000908152606960205260409020541015610b895733600090815260696020526040908190205460675491517e0155b50000000000000000000000000000000000000000000000000000000081526105699290600401918252602082015260400190565b6000610b96848484610625565b6003811115610ba757610ba7611680565b14610bde576040517f9bb6c64e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610be7836113bc565b610c1d576040517ff9e0d1f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6067543360009081526069602052604081208054909190610c3f9084906118f1565b9250508190555060405180608001604052803373ffffffffffffffffffffffffffffffffffffffff16815260200160675481526020014381526020016000815250606a60008581526020019081526020016000208383604051610ca392919061183d565b9081526040805160209281900383018120845181547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161781559284015160018085019190915591840151600284015560609093015160039092019190915584917fc5d8c630ba2fdacb1db24c4599df78c7fb8cf97b5aecde34939597f6697bb1ad91610d4b91869186916118c6565b60405180910390a2505050565b610d6061102a565b60678190556040518181527f4468d695a0389e5f9e8ef0c9aee6d84e74cc0d0e0a28c8413badb54697d1bbae9060200160405180910390a150565b610da361102a565b73ffffffffffffffffffffffffffffffffffffffff8116610e46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610569565b610e4f816110c1565b50565b600054610100900460ff1615808015610e725750600054600160ff909116105b80610e8c5750303b158015610e8c575060005460ff166001145b610f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610569565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610f7657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610f7e6113d6565b60658590556066849055610f9183610d58565b610f9a82610527565b610fa3866110c1565b801561100657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610623576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610569565b600080600080600080868989f195945050505050565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000606654826111489190611825565b43111592915050565b600061115d8284611908565b60f81c90505b92915050565b80516020918201206040805160009381019390935260218084019290925280518084039092018252604190920190915290565b6001830154835473ffffffffffffffffffffffffffffffffffffffff166000486103e86111cb61410088611950565b6111d5919061198d565b6111e29062011cdd611825565b6111ec9190611950565b90508083111561129e5761120081846118f1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526069602052604081208054909190611235908490611825565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152606960209081526040918290205482519384529083015291935083917fa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05910160405180910390a15b60006064606854836112b09190611950565b6112ba919061198d565b9050838111156112c75750825b80156113745773ffffffffffffffffffffffffffffffffffffffff851660009081526069602052604081208054839290611302908490611825565b90915550611312905081856118f1565b73ffffffffffffffffffffffffffffffffffffffff8616600081815260696020908152604091829020548251938452908301529195507fa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05910160405180910390a15b83156113a95760405160009085156108fc0290869083818181858288f193505050501580156113a7573d6000803e3d6000fd5b505b6000876001018190555050505050505050565b600081431015801561116357506065546111489083611825565b600054610100900460ff1661146d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610569565b610623600054610100900460ff16611507576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610569565b610623336110c1565b803573ffffffffffffffffffffffffffffffffffffffff8116811461153457600080fd5b919050565b60006020828403121561154b57600080fd5b6106e182611510565b60006020828403121561156657600080fd5b5035919050565b6000815180845260005b8181101561159357602081850181015186830182015201611577565b818111156115a5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106e1602083018461156d565b60008083601f8401126115fd57600080fd5b50813567ffffffffffffffff81111561161557600080fd5b60208301915083602082850101111561162d57600080fd5b9250929050565b60008060006040848603121561164957600080fd5b83359250602084013567ffffffffffffffff81111561166757600080fd5b611673868287016115eb565b9497909650939450505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600481106116e6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6020810161116382846116af565b60008060008060006060868803121561171057600080fd5b85359450602086013567ffffffffffffffff8082111561172f57600080fd5b61173b89838a016115eb565b9096509450604088013591508082111561175457600080fd5b50611761888289016115eb565b969995985093965092949392505050565b6000806020838503121561178557600080fd5b823567ffffffffffffffff81111561179c57600080fd5b6117a8858286016115eb565b90969095509350505050565b600080600080600060a086880312156117cc57600080fd5b6117d586611510565b97602087013597506040870135966060810135965060800135945092505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115611838576118386117f6565b500190565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6040815260006118a9604083018661156d565b82810360208401526118bc81858761184d565b9695505050505050565b6040815260006118da60408301858761184d565b90506118e960208301846116af565b949350505050565b600082821015611903576119036117f6565b500390565b7fff0000000000000000000000000000000000000000000000000000000000000081358181169160018510156119485780818660010360031b1b83161692505b505092915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611988576119886117f6565b500290565b6000826119c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c634300080f000a" + + +func init() { + if err := json.Unmarshal([]byte(DataAvailabilityChallengeStorageLayoutJSON), DataAvailabilityChallengeStorageLayout); err != nil { + panic(err) + } + + layouts["DataAvailabilityChallenge"] = DataAvailabilityChallengeStorageLayout + deployedBytecodes["DataAvailabilityChallenge"] = DataAvailabilityChallengeDeployedBin + immutableReferences["DataAvailabilityChallenge"] = false +} diff --git a/op-bindings/bindings/delayedvetoable.go b/op-bindings/bindings/delayedvetoable.go index 0166fdc68f78..989bb0278d20 100644 --- a/op-bindings/bindings/delayedvetoable.go +++ b/op-bindings/bindings/delayedvetoable.go @@ -30,8 +30,8 @@ var ( // DelayedVetoableMetaData contains all meta data concerning the DelayedVetoable contract. var DelayedVetoableMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vetoer_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"initiator_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"operatingDelay_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyDelayed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForwardingEarly\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TargetUnitialized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"expected\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"actual\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"delay\",\"type\":\"uint256\"}],\"name\":\"DelayActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"callHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Forwarded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"callHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Initiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"callHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"Vetoed\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"delay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"delay_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initiator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"initiator_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"callHash\",\"type\":\"bytes32\"}],\"name\":\"queuedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"queuedAt_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"target\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"target_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"vetoer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"vetoer_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x61010060405234801561001157600080fd5b506040516108ff3803806108ff8339810160408190526100309161006e565b6001600160a01b0393841660a05291831660c05290911660805260e0526100b9565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b6060959095015193969295505050565b60805160a05160c05160e0516107dc610123600039600061023f01526000818161015f01528181610205015281816102cd0152818161045801526105050152600081816101a001528181610384015261059d01526000818161057101526105ff01526107dc6000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b912de5d11610050578063b912de5d14610111578063d4b8399214610124578063d8bff4401461012c57610072565b806354fd4d501461007c5780635c39fcc1146100ce5780636a42b8f8146100fb575b61007a610134565b005b6100b86040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100c591906106a7565b60405180910390f35b6100d66104fb565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b610103610532565b6040519081526020016100c5565b61010361011f36600461071a565b610540565b6100d6610567565b6100d6610593565b361580156101425750600054155b15610298573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015906101c357503373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614155b1561023d576040517f295a81c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000060008190556040519081527febf28bfb587e28dfffd9173cf71c32ba5d3f0544a0117b5539c9b274a5bba2a89060200160405180910390a1565b600080366040516102aa929190610733565b60405190819003902090503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156103065750600081815260016020526040902054155b1561036c5760005460000361031e5761031e816105bf565b6000818152600160205260408082204290555182917f87a332a414acbc7da074543639ce7ae02ff1ea72e88379da9f261b080beb5a139161036191903690610743565b60405180910390a250565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156103be575060008181526001602052604090205415155b15610406576000818152600160205260408082208290555182917fbede6852c1d97d93ff557f676de76670cd0dec861e7fe8beb13aa0ba2b0ab0409161036191903690610743565b600081815260016020526040812054900361048b576040517f295a81c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610234565b60008054828252600160205260409091205442916104a891610790565b10156104e0576040517f43dc986d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600160205260408120556104f8816105bf565b50565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b61052f610134565b90565b600033610527575060005490565b60003361055a575060009081526001602052604090205490565b610562610134565b919050565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b807f4c109d85bcd0bb5c735b4be850953d652afe4cd9aa2e0b1426a65a4dcb2e12296000366040516105f2929190610743565b60405180910390a26000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600036604051610645929190610733565b6000604051808303816000865af19150503d8060008114610682576040519150601f19603f3d011682016040523d82523d6000602084013e610687565b606091505b50909250905081151560010361069f57805160208201f35b805160208201fd5b600060208083528351808285015260005b818110156106d4578581018301518582016040015282016106b8565b818111156106e6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561072c57600080fd5b5035919050565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b600082198211156107ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"vetoer_\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"initiator_\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"target_\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatingDelay_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delay\",\"inputs\":[],\"outputs\":[{\"name\":\"delay_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initiator\",\"inputs\":[],\"outputs\":[{\"name\":\"initiator_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"queuedAt\",\"inputs\":[{\"name\":\"callHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"queuedAt_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"target\",\"inputs\":[],\"outputs\":[{\"name\":\"target_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"vetoer\",\"inputs\":[],\"outputs\":[{\"name\":\"vetoer_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"DelayActivated\",\"inputs\":[{\"name\":\"delay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Forwarded\",\"inputs\":[{\"name\":\"callHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initiated\",\"inputs\":[{\"name\":\"callHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Vetoed\",\"inputs\":[{\"name\":\"callHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"ForwardingEarly\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"Unauthorized\",\"inputs\":[{\"name\":\"expected\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"actual\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + Bin: "0x61010060405234801561001157600080fd5b506040516108ff3803806108ff8339810160408190526100309161006e565b6001600160a01b0393841660a05291831660c05290911660805260e0526100b9565b80516001600160a01b038116811461006957600080fd5b919050565b6000806000806080858703121561008457600080fd5b61008d85610052565b935061009b60208601610052565b92506100a960408601610052565b6060959095015193969295505050565b60805160a05160c05160e0516107dc610123600039600061023f01526000818161015f01528181610205015281816102cd0152818161045801526105050152600081816101a001528181610384015261059d01526000818161057101526105ff01526107dc6000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063b912de5d11610050578063b912de5d14610111578063d4b8399214610124578063d8bff4401461012c57610072565b806354fd4d501461007c5780635c39fcc1146100ce5780636a42b8f8146100fb575b61007a610134565b005b6100b86040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100c591906106a7565b60405180910390f35b6100d66104fb565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b610103610532565b6040519081526020016100c5565b61010361011f36600461071a565b610540565b6100d6610567565b6100d6610593565b361580156101425750600054155b15610298573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015906101c357503373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614155b1561023d576040517f295a81c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000060008190556040519081527febf28bfb587e28dfffd9173cf71c32ba5d3f0544a0117b5539c9b274a5bba2a89060200160405180910390a1565b600080366040516102aa929190610733565b60405190819003902090503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156103065750600081815260016020526040902054155b1561036c5760005460000361031e5761031e816105bf565b6000818152600160205260408082204290555182917f87a332a414acbc7da074543639ce7ae02ff1ea72e88379da9f261b080beb5a139161036191903690610743565b60405180910390a250565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156103be575060008181526001602052604090205415155b15610406576000818152600160205260408082208290555182917fbede6852c1d97d93ff557f676de76670cd0dec861e7fe8beb13aa0ba2b0ab0409161036191903690610743565b600081815260016020526040812054900361048b576040517f295a81c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610234565b60008054828252600160205260409091205442916104a891610790565b11156104e0576040517f43dc986d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600160205260408120556104f8816105bf565b50565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b61052f610134565b90565b600033610527575060005490565b60003361055a575060009081526001602052604090205490565b610562610134565b919050565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b807f4c109d85bcd0bb5c735b4be850953d652afe4cd9aa2e0b1426a65a4dcb2e12296000366040516105f2929190610743565b60405180910390a26000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600036604051610645929190610733565b6000604051808303816000865af19150503d8060008114610682576040519150601f19603f3d011682016040523d82523d6000602084013e610687565b606091505b50909250905081151560010361069f57805160208201f35b805160208201fd5b600060208083528351808285015260005b818110156106d4578581018301518582016040015282016106b8565b818111156106e6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561072c57600080fd5b5035919050565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b600082198211156107ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fea164736f6c634300080f000a", } // DelayedVetoableABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/delayedvetoable_more.go b/op-bindings/bindings/delayedvetoable_more.go index 3ad43c89e384..447987519301 100644 --- a/op-bindings/bindings/delayedvetoable_more.go +++ b/op-bindings/bindings/delayedvetoable_more.go @@ -13,7 +13,8 @@ const DelayedVetoableStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contra var DelayedVetoableStorageLayout = new(solc.StorageLayout) -var DelayedVetoableDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b912de5d11610050578063b912de5d14610111578063d4b8399214610124578063d8bff4401461012c57610072565b806354fd4d501461007c5780635c39fcc1146100ce5780636a42b8f8146100fb575b61007a610134565b005b6100b86040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100c591906106a7565b60405180910390f35b6100d66104fb565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b610103610532565b6040519081526020016100c5565b61010361011f36600461071a565b610540565b6100d6610567565b6100d6610593565b361580156101425750600054155b15610298573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015906101c357503373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614155b1561023d576040517f295a81c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000060008190556040519081527febf28bfb587e28dfffd9173cf71c32ba5d3f0544a0117b5539c9b274a5bba2a89060200160405180910390a1565b600080366040516102aa929190610733565b60405190819003902090503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156103065750600081815260016020526040902054155b1561036c5760005460000361031e5761031e816105bf565b6000818152600160205260408082204290555182917f87a332a414acbc7da074543639ce7ae02ff1ea72e88379da9f261b080beb5a139161036191903690610743565b60405180910390a250565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156103be575060008181526001602052604090205415155b15610406576000818152600160205260408082208290555182917fbede6852c1d97d93ff557f676de76670cd0dec861e7fe8beb13aa0ba2b0ab0409161036191903690610743565b600081815260016020526040812054900361048b576040517f295a81c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610234565b60008054828252600160205260409091205442916104a891610790565b10156104e0576040517f43dc986d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600160205260408120556104f8816105bf565b50565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b61052f610134565b90565b600033610527575060005490565b60003361055a575060009081526001602052604090205490565b610562610134565b919050565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b807f4c109d85bcd0bb5c735b4be850953d652afe4cd9aa2e0b1426a65a4dcb2e12296000366040516105f2929190610743565b60405180910390a26000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600036604051610645929190610733565b6000604051808303816000865af19150503d8060008114610682576040519150601f19603f3d011682016040523d82523d6000602084013e610687565b606091505b50909250905081151560010361069f57805160208201f35b805160208201fd5b600060208083528351808285015260005b818110156106d4578581018301518582016040015282016106b8565b818111156106e6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561072c57600080fd5b5035919050565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b600082198211156107ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fea164736f6c634300080f000a" +var DelayedVetoableDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063b912de5d11610050578063b912de5d14610111578063d4b8399214610124578063d8bff4401461012c57610072565b806354fd4d501461007c5780635c39fcc1146100ce5780636a42b8f8146100fb575b61007a610134565b005b6100b86040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100c591906106a7565b60405180910390f35b6100d66104fb565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c5565b610103610532565b6040519081526020016100c5565b61010361011f36600461071a565b610540565b6100d6610567565b6100d6610593565b361580156101425750600054155b15610298573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015906101c357503373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614155b1561023d576040517f295a81c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000060008190556040519081527febf28bfb587e28dfffd9173cf71c32ba5d3f0544a0117b5539c9b274a5bba2a89060200160405180910390a1565b600080366040516102aa929190610733565b60405190819003902090503373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156103065750600081815260016020526040902054155b1561036c5760005460000361031e5761031e816105bf565b6000818152600160205260408082204290555182917f87a332a414acbc7da074543639ce7ae02ff1ea72e88379da9f261b080beb5a139161036191903690610743565b60405180910390a250565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156103be575060008181526001602052604090205415155b15610406576000818152600160205260408082208290555182917fbede6852c1d97d93ff557f676de76670cd0dec861e7fe8beb13aa0ba2b0ab0409161036191903690610743565b600081815260016020526040812054900361048b576040517f295a81c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610234565b60008054828252600160205260409091205442916104a891610790565b11156104e0576040517f43dc986d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600160205260408120556104f8816105bf565b50565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b61052f610134565b90565b600033610527575060005490565b60003361055a575060009081526001602052604090205490565b610562610134565b919050565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b60003361052757507f000000000000000000000000000000000000000000000000000000000000000090565b807f4c109d85bcd0bb5c735b4be850953d652afe4cd9aa2e0b1426a65a4dcb2e12296000366040516105f2929190610743565b60405180910390a26000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600036604051610645929190610733565b6000604051808303816000865af19150503d8060008114610682576040519150601f19603f3d011682016040523d82523d6000602084013e610687565b606091505b50909250905081151560010361069f57805160208201f35b805160208201fd5b600060208083528351808285015260005b818110156106d4578581018301518582016040015282016106b8565b818111156106e6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561072c57600080fd5b5035919050565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b600082198211156107ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(DelayedVetoableStorageLayoutJSON), DelayedVetoableStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["DelayedVetoable"] = DelayedVetoableStorageLayout deployedBytecodes["DelayedVetoable"] = DelayedVetoableDeployedBin + immutableReferences["DelayedVetoable"] = true } diff --git a/op-bindings/bindings/delayedweth.go b/op-bindings/bindings/delayedweth.go new file mode 100644 index 000000000000..d4dc77699835 --- /dev/null +++ b/op-bindings/bindings/delayedweth.go @@ -0,0 +1,1860 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// DelayedWETHMetaData contains all meta data concerning the DelayedWETH contract. +var DelayedWETHMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_delay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"allowance\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"guy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"config\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"decimals\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"delay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deposit\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"hold\",\"inputs\":[{\"name\":\"_guy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_config\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recover\",\"inputs\":[{\"name\":\"_wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalSupply\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transfer\",\"inputs\":[{\"name\":\"dst\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"src\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"dst\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unlock\",\"inputs\":[{\"name\":\"_guy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"_wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"_guy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawals\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"src\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"guy\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Deposit\",\"inputs\":[{\"name\":\"dst\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"src\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"dst\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unwrap\",\"inputs\":[{\"name\":\"src\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdrawal\",\"inputs\":[{\"name\":\"src\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620018b9380380620018b98339810160408190526200003491620002d7565b6080819052620000466000806200004d565b50620002f1565b600054610100900460ff16158080156200006e5750600054600160ff909116105b806200009e57506200008b30620001a760201b6200108e1760201c565b1580156200009e575060005460ff166001145b620001075760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156200012b576000805461ff0019166101001790555b62000135620001b6565b62000140836200021e565b606880546001600160a01b0319166001600160a01b0384161790558015620001a2576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002125760405162461bcd60e51b815260206004820152602b60248201526000805160206200189983398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fe565b6200021c62000270565b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16620002cc5760405162461bcd60e51b815260206004820152602b60248201526000805160206200189983398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fe565b6200021c336200021e565b600060208284031215620002ea57600080fd5b5051919050565b60805161158562000314600039600081816103430152610faf01526115856000f3fe6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461052b578063f2fde38b14610563578063f3fef3a31461058357600080fd5b8063a9059cbb146104af578063cd47bde1146104cf578063d0e30db01461052357600080fd5b80638da5cb5b116100b05780638da5cb5b1461041b57806395d89b4114610446578063977a5ec51461048f57600080fd5b8063715018a61461039457806379502c55146103a95780637eee288d146103fb57600080fd5b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102eb5780636a42b8f81461033457806370a082311461036757600080fd5b80632e1a7d4d14610284578063313ce567146102a4578063485cc955146102cb57600080fd5b80630ca35682116101695780630ca356821461022757806318160ddd1461024757806323b872dd1461026457600080fd5b806306fdde0314610198578063095ea7b3146101f757600080fd5b36610193576101916105a3565b005b600080fd5b3480156101a457600080fd5b506101e16040518060400160405280600d81526020017f577261707065642045746865720000000000000000000000000000000000000081525081565b6040516101ee9190611387565b60405180910390f35b34801561020357600080fd5b5061021761021236600461141c565b6105fe565b60405190151581526020016101ee565b34801561023357600080fd5b50610191610242366004611448565b610677565b34801561025357600080fd5b50475b6040519081526020016101ee565b34801561027057600080fd5b5061021761027f366004611461565b610743565b34801561029057600080fd5b5061019161029f366004611448565b61095a565b3480156102b057600080fd5b506102b9601281565b60405160ff90911681526020016101ee565b3480156102d757600080fd5b506101916102e63660046114a2565b610967565b3480156102f757600080fd5b506101e16040518060400160405280600581526020017f302e322e3000000000000000000000000000000000000000000000000000000081525081565b34801561034057600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610256565b34801561037357600080fd5b506102566103823660046114db565b60656020526000908152604090205481565b3480156103a057600080fd5b50610191610b43565b3480156103b557600080fd5b506068546103d69073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ee565b34801561040757600080fd5b5061019161041636600461141c565b610b57565b34801561042757600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d6565b34801561045257600080fd5b506101e16040518060400160405280600481526020017f574554480000000000000000000000000000000000000000000000000000000081525081565b34801561049b57600080fd5b506101916104aa36600461141c565b610bab565b3480156104bb57600080fd5b506102176104ca36600461141c565b610c98565b3480156104db57600080fd5b5061050e6104ea3660046114a2565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ee565b6101916105a3565b34801561053757600080fd5b506102566105463660046114a2565b606660209081526000928352604080842090915290825290205481565b34801561056f57600080fd5b5061019161057e3660046114db565b610cac565b34801561058f57600080fd5b5061019161059e36600461141c565b610d60565b33600090815260656020526040812080543492906105c2908490611527565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106669086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b600047821061070c574761070e565b815b604051909150339082156108fc029083906000818181858888f1935050505015801561073e573d6000803e3d6000fd5b505050565b73ffffffffffffffffffffffffffffffffffffffff831660009081526065602052604081205482111561077557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841633148015906107eb575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108735773ffffffffffffffffffffffffffffffffffffffff8416600090815260666020908152604080832033845290915290205482111561082d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091528120805484929061086d90849061153f565b90915550505b73ffffffffffffffffffffffffffffffffffffffff8416600090815260656020526040812080548492906108a890849061153f565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600090815260656020526040812080548492906108e2908490611527565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161094891815260200190565b60405180910390a35060019392505050565b6109643382610d60565b50565b600054610100900460ff16158080156109875750600054600160ff909116105b806109a15750303b1580156109a1575060005460ff166001145b610a2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106f4565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610a8b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a936110aa565b610a9c83611149565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561073e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610b4b6111c0565b610b556000611149565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610ba1908490611527565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106f4565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610ca5338484610743565b9392505050565b610cb46111c0565b73ffffffffffffffffffffffffffffffffffffffff8116610d57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106f4565b61096481611149565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df19190611556565b15610e58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106f4565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106f4565b6000816001015411610fac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106f4565b427f00000000000000000000000000000000000000000000000000000000000000008260010154610fdd9190611527565b111561106b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106f4565b8181600001600082825461107f919061153f565b9091555061073e905082611241565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16611141576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106f4565b610b556112e7565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610b55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f4565b3360009081526065602052604090205481111561125d57600080fd5b336000908152606560205260408120805483929061127c90849061153f565b9091555050604051339082156108fc029083906000818181858888f193505050501580156112ae573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff1661137e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106f4565b610b5533611149565b600060208083528351808285015260005b818110156113b457858101830151858201604001528201611398565b818111156113c6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461096457600080fd5b6000806040838503121561142f57600080fd5b823561143a816113fa565b946020939093013593505050565b60006020828403121561145a57600080fd5b5035919050565b60008060006060848603121561147657600080fd5b8335611481816113fa565b92506020840135611491816113fa565b929592945050506040919091013590565b600080604083850312156114b557600080fd5b82356114c0816113fa565b915060208301356114d0816113fa565b809150509250929050565b6000602082840312156114ed57600080fd5b8135610ca5816113fa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561153a5761153a6114f8565b500190565b600082821015611551576115516114f8565b500390565b60006020828403121561156857600080fd5b81518015158114610ca557600080fdfea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", +} + +// DelayedWETHABI is the input ABI used to generate the binding from. +// Deprecated: Use DelayedWETHMetaData.ABI instead. +var DelayedWETHABI = DelayedWETHMetaData.ABI + +// DelayedWETHBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use DelayedWETHMetaData.Bin instead. +var DelayedWETHBin = DelayedWETHMetaData.Bin + +// DeployDelayedWETH deploys a new Ethereum contract, binding an instance of DelayedWETH to it. +func DeployDelayedWETH(auth *bind.TransactOpts, backend bind.ContractBackend, _delay *big.Int) (common.Address, *types.Transaction, *DelayedWETH, error) { + parsed, err := DelayedWETHMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DelayedWETHBin), backend, _delay) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &DelayedWETH{DelayedWETHCaller: DelayedWETHCaller{contract: contract}, DelayedWETHTransactor: DelayedWETHTransactor{contract: contract}, DelayedWETHFilterer: DelayedWETHFilterer{contract: contract}}, nil +} + +// DelayedWETH is an auto generated Go binding around an Ethereum contract. +type DelayedWETH struct { + DelayedWETHCaller // Read-only binding to the contract + DelayedWETHTransactor // Write-only binding to the contract + DelayedWETHFilterer // Log filterer for contract events +} + +// DelayedWETHCaller is an auto generated read-only Go binding around an Ethereum contract. +type DelayedWETHCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DelayedWETHTransactor is an auto generated write-only Go binding around an Ethereum contract. +type DelayedWETHTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DelayedWETHFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type DelayedWETHFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DelayedWETHSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type DelayedWETHSession struct { + Contract *DelayedWETH // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// DelayedWETHCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type DelayedWETHCallerSession struct { + Contract *DelayedWETHCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// DelayedWETHTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type DelayedWETHTransactorSession struct { + Contract *DelayedWETHTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// DelayedWETHRaw is an auto generated low-level Go binding around an Ethereum contract. +type DelayedWETHRaw struct { + Contract *DelayedWETH // Generic contract binding to access the raw methods on +} + +// DelayedWETHCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type DelayedWETHCallerRaw struct { + Contract *DelayedWETHCaller // Generic read-only contract binding to access the raw methods on +} + +// DelayedWETHTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type DelayedWETHTransactorRaw struct { + Contract *DelayedWETHTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewDelayedWETH creates a new instance of DelayedWETH, bound to a specific deployed contract. +func NewDelayedWETH(address common.Address, backend bind.ContractBackend) (*DelayedWETH, error) { + contract, err := bindDelayedWETH(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &DelayedWETH{DelayedWETHCaller: DelayedWETHCaller{contract: contract}, DelayedWETHTransactor: DelayedWETHTransactor{contract: contract}, DelayedWETHFilterer: DelayedWETHFilterer{contract: contract}}, nil +} + +// NewDelayedWETHCaller creates a new read-only instance of DelayedWETH, bound to a specific deployed contract. +func NewDelayedWETHCaller(address common.Address, caller bind.ContractCaller) (*DelayedWETHCaller, error) { + contract, err := bindDelayedWETH(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &DelayedWETHCaller{contract: contract}, nil +} + +// NewDelayedWETHTransactor creates a new write-only instance of DelayedWETH, bound to a specific deployed contract. +func NewDelayedWETHTransactor(address common.Address, transactor bind.ContractTransactor) (*DelayedWETHTransactor, error) { + contract, err := bindDelayedWETH(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &DelayedWETHTransactor{contract: contract}, nil +} + +// NewDelayedWETHFilterer creates a new log filterer instance of DelayedWETH, bound to a specific deployed contract. +func NewDelayedWETHFilterer(address common.Address, filterer bind.ContractFilterer) (*DelayedWETHFilterer, error) { + contract, err := bindDelayedWETH(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &DelayedWETHFilterer{contract: contract}, nil +} + +// bindDelayedWETH binds a generic wrapper to an already deployed contract. +func bindDelayedWETH(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(DelayedWETHABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_DelayedWETH *DelayedWETHRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DelayedWETH.Contract.DelayedWETHCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_DelayedWETH *DelayedWETHRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DelayedWETH.Contract.DelayedWETHTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_DelayedWETH *DelayedWETHRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DelayedWETH.Contract.DelayedWETHTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_DelayedWETH *DelayedWETHCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DelayedWETH.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_DelayedWETH *DelayedWETHTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DelayedWETH.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_DelayedWETH *DelayedWETHTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DelayedWETH.Contract.contract.Transact(opts, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address , address ) view returns(uint256) +func (_DelayedWETH *DelayedWETHCaller) Allowance(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "allowance", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address , address ) view returns(uint256) +func (_DelayedWETH *DelayedWETHSession) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _DelayedWETH.Contract.Allowance(&_DelayedWETH.CallOpts, arg0, arg1) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address , address ) view returns(uint256) +func (_DelayedWETH *DelayedWETHCallerSession) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _DelayedWETH.Contract.Allowance(&_DelayedWETH.CallOpts, arg0, arg1) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address ) view returns(uint256) +func (_DelayedWETH *DelayedWETHCaller) BalanceOf(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "balanceOf", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address ) view returns(uint256) +func (_DelayedWETH *DelayedWETHSession) BalanceOf(arg0 common.Address) (*big.Int, error) { + return _DelayedWETH.Contract.BalanceOf(&_DelayedWETH.CallOpts, arg0) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address ) view returns(uint256) +func (_DelayedWETH *DelayedWETHCallerSession) BalanceOf(arg0 common.Address) (*big.Int, error) { + return _DelayedWETH.Contract.BalanceOf(&_DelayedWETH.CallOpts, arg0) +} + +// Config is a free data retrieval call binding the contract method 0x79502c55. +// +// Solidity: function config() view returns(address) +func (_DelayedWETH *DelayedWETHCaller) Config(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "config") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Config is a free data retrieval call binding the contract method 0x79502c55. +// +// Solidity: function config() view returns(address) +func (_DelayedWETH *DelayedWETHSession) Config() (common.Address, error) { + return _DelayedWETH.Contract.Config(&_DelayedWETH.CallOpts) +} + +// Config is a free data retrieval call binding the contract method 0x79502c55. +// +// Solidity: function config() view returns(address) +func (_DelayedWETH *DelayedWETHCallerSession) Config() (common.Address, error) { + return _DelayedWETH.Contract.Config(&_DelayedWETH.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_DelayedWETH *DelayedWETHCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_DelayedWETH *DelayedWETHSession) Decimals() (uint8, error) { + return _DelayedWETH.Contract.Decimals(&_DelayedWETH.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_DelayedWETH *DelayedWETHCallerSession) Decimals() (uint8, error) { + return _DelayedWETH.Contract.Decimals(&_DelayedWETH.CallOpts) +} + +// Delay is a free data retrieval call binding the contract method 0x6a42b8f8. +// +// Solidity: function delay() view returns(uint256) +func (_DelayedWETH *DelayedWETHCaller) Delay(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "delay") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Delay is a free data retrieval call binding the contract method 0x6a42b8f8. +// +// Solidity: function delay() view returns(uint256) +func (_DelayedWETH *DelayedWETHSession) Delay() (*big.Int, error) { + return _DelayedWETH.Contract.Delay(&_DelayedWETH.CallOpts) +} + +// Delay is a free data retrieval call binding the contract method 0x6a42b8f8. +// +// Solidity: function delay() view returns(uint256) +func (_DelayedWETH *DelayedWETHCallerSession) Delay() (*big.Int, error) { + return _DelayedWETH.Contract.Delay(&_DelayedWETH.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_DelayedWETH *DelayedWETHCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_DelayedWETH *DelayedWETHSession) Name() (string, error) { + return _DelayedWETH.Contract.Name(&_DelayedWETH.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_DelayedWETH *DelayedWETHCallerSession) Name() (string, error) { + return _DelayedWETH.Contract.Name(&_DelayedWETH.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_DelayedWETH *DelayedWETHCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_DelayedWETH *DelayedWETHSession) Owner() (common.Address, error) { + return _DelayedWETH.Contract.Owner(&_DelayedWETH.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_DelayedWETH *DelayedWETHCallerSession) Owner() (common.Address, error) { + return _DelayedWETH.Contract.Owner(&_DelayedWETH.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_DelayedWETH *DelayedWETHCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_DelayedWETH *DelayedWETHSession) Symbol() (string, error) { + return _DelayedWETH.Contract.Symbol(&_DelayedWETH.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_DelayedWETH *DelayedWETHCallerSession) Symbol() (string, error) { + return _DelayedWETH.Contract.Symbol(&_DelayedWETH.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_DelayedWETH *DelayedWETHCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_DelayedWETH *DelayedWETHSession) TotalSupply() (*big.Int, error) { + return _DelayedWETH.Contract.TotalSupply(&_DelayedWETH.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_DelayedWETH *DelayedWETHCallerSession) TotalSupply() (*big.Int, error) { + return _DelayedWETH.Contract.TotalSupply(&_DelayedWETH.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_DelayedWETH *DelayedWETHCaller) Version(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "version") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_DelayedWETH *DelayedWETHSession) Version() (string, error) { + return _DelayedWETH.Contract.Version(&_DelayedWETH.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_DelayedWETH *DelayedWETHCallerSession) Version() (string, error) { + return _DelayedWETH.Contract.Version(&_DelayedWETH.CallOpts) +} + +// Withdrawals is a free data retrieval call binding the contract method 0xcd47bde1. +// +// Solidity: function withdrawals(address , address ) view returns(uint256 amount, uint256 timestamp) +func (_DelayedWETH *DelayedWETHCaller) Withdrawals(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (struct { + Amount *big.Int + Timestamp *big.Int +}, error) { + var out []interface{} + err := _DelayedWETH.contract.Call(opts, &out, "withdrawals", arg0, arg1) + + outstruct := new(struct { + Amount *big.Int + Timestamp *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Amount = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Timestamp = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// Withdrawals is a free data retrieval call binding the contract method 0xcd47bde1. +// +// Solidity: function withdrawals(address , address ) view returns(uint256 amount, uint256 timestamp) +func (_DelayedWETH *DelayedWETHSession) Withdrawals(arg0 common.Address, arg1 common.Address) (struct { + Amount *big.Int + Timestamp *big.Int +}, error) { + return _DelayedWETH.Contract.Withdrawals(&_DelayedWETH.CallOpts, arg0, arg1) +} + +// Withdrawals is a free data retrieval call binding the contract method 0xcd47bde1. +// +// Solidity: function withdrawals(address , address ) view returns(uint256 amount, uint256 timestamp) +func (_DelayedWETH *DelayedWETHCallerSession) Withdrawals(arg0 common.Address, arg1 common.Address) (struct { + Amount *big.Int + Timestamp *big.Int +}, error) { + return _DelayedWETH.Contract.Withdrawals(&_DelayedWETH.CallOpts, arg0, arg1) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address guy, uint256 wad) returns(bool) +func (_DelayedWETH *DelayedWETHTransactor) Approve(opts *bind.TransactOpts, guy common.Address, wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "approve", guy, wad) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address guy, uint256 wad) returns(bool) +func (_DelayedWETH *DelayedWETHSession) Approve(guy common.Address, wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Approve(&_DelayedWETH.TransactOpts, guy, wad) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address guy, uint256 wad) returns(bool) +func (_DelayedWETH *DelayedWETHTransactorSession) Approve(guy common.Address, wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Approve(&_DelayedWETH.TransactOpts, guy, wad) +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_DelayedWETH *DelayedWETHTransactor) Deposit(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "deposit") +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_DelayedWETH *DelayedWETHSession) Deposit() (*types.Transaction, error) { + return _DelayedWETH.Contract.Deposit(&_DelayedWETH.TransactOpts) +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_DelayedWETH *DelayedWETHTransactorSession) Deposit() (*types.Transaction, error) { + return _DelayedWETH.Contract.Deposit(&_DelayedWETH.TransactOpts) +} + +// Hold is a paid mutator transaction binding the contract method 0x977a5ec5. +// +// Solidity: function hold(address _guy, uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHTransactor) Hold(opts *bind.TransactOpts, _guy common.Address, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "hold", _guy, _wad) +} + +// Hold is a paid mutator transaction binding the contract method 0x977a5ec5. +// +// Solidity: function hold(address _guy, uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHSession) Hold(_guy common.Address, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Hold(&_DelayedWETH.TransactOpts, _guy, _wad) +} + +// Hold is a paid mutator transaction binding the contract method 0x977a5ec5. +// +// Solidity: function hold(address _guy, uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHTransactorSession) Hold(_guy common.Address, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Hold(&_DelayedWETH.TransactOpts, _guy, _wad) +} + +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. +// +// Solidity: function initialize(address _owner, address _config) returns() +func (_DelayedWETH *DelayedWETHTransactor) Initialize(opts *bind.TransactOpts, _owner common.Address, _config common.Address) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "initialize", _owner, _config) +} + +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. +// +// Solidity: function initialize(address _owner, address _config) returns() +func (_DelayedWETH *DelayedWETHSession) Initialize(_owner common.Address, _config common.Address) (*types.Transaction, error) { + return _DelayedWETH.Contract.Initialize(&_DelayedWETH.TransactOpts, _owner, _config) +} + +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. +// +// Solidity: function initialize(address _owner, address _config) returns() +func (_DelayedWETH *DelayedWETHTransactorSession) Initialize(_owner common.Address, _config common.Address) (*types.Transaction, error) { + return _DelayedWETH.Contract.Initialize(&_DelayedWETH.TransactOpts, _owner, _config) +} + +// Recover is a paid mutator transaction binding the contract method 0x0ca35682. +// +// Solidity: function recover(uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHTransactor) Recover(opts *bind.TransactOpts, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "recover", _wad) +} + +// Recover is a paid mutator transaction binding the contract method 0x0ca35682. +// +// Solidity: function recover(uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHSession) Recover(_wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Recover(&_DelayedWETH.TransactOpts, _wad) +} + +// Recover is a paid mutator transaction binding the contract method 0x0ca35682. +// +// Solidity: function recover(uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHTransactorSession) Recover(_wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Recover(&_DelayedWETH.TransactOpts, _wad) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_DelayedWETH *DelayedWETHTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_DelayedWETH *DelayedWETHSession) RenounceOwnership() (*types.Transaction, error) { + return _DelayedWETH.Contract.RenounceOwnership(&_DelayedWETH.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_DelayedWETH *DelayedWETHTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _DelayedWETH.Contract.RenounceOwnership(&_DelayedWETH.TransactOpts) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address dst, uint256 wad) returns(bool) +func (_DelayedWETH *DelayedWETHTransactor) Transfer(opts *bind.TransactOpts, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "transfer", dst, wad) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address dst, uint256 wad) returns(bool) +func (_DelayedWETH *DelayedWETHSession) Transfer(dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Transfer(&_DelayedWETH.TransactOpts, dst, wad) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address dst, uint256 wad) returns(bool) +func (_DelayedWETH *DelayedWETHTransactorSession) Transfer(dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Transfer(&_DelayedWETH.TransactOpts, dst, wad) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address src, address dst, uint256 wad) returns(bool) +func (_DelayedWETH *DelayedWETHTransactor) TransferFrom(opts *bind.TransactOpts, src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "transferFrom", src, dst, wad) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address src, address dst, uint256 wad) returns(bool) +func (_DelayedWETH *DelayedWETHSession) TransferFrom(src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.TransferFrom(&_DelayedWETH.TransactOpts, src, dst, wad) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address src, address dst, uint256 wad) returns(bool) +func (_DelayedWETH *DelayedWETHTransactorSession) TransferFrom(src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.TransferFrom(&_DelayedWETH.TransactOpts, src, dst, wad) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_DelayedWETH *DelayedWETHTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_DelayedWETH *DelayedWETHSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _DelayedWETH.Contract.TransferOwnership(&_DelayedWETH.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_DelayedWETH *DelayedWETHTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _DelayedWETH.Contract.TransferOwnership(&_DelayedWETH.TransactOpts, newOwner) +} + +// Unlock is a paid mutator transaction binding the contract method 0x7eee288d. +// +// Solidity: function unlock(address _guy, uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHTransactor) Unlock(opts *bind.TransactOpts, _guy common.Address, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "unlock", _guy, _wad) +} + +// Unlock is a paid mutator transaction binding the contract method 0x7eee288d. +// +// Solidity: function unlock(address _guy, uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHSession) Unlock(_guy common.Address, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Unlock(&_DelayedWETH.TransactOpts, _guy, _wad) +} + +// Unlock is a paid mutator transaction binding the contract method 0x7eee288d. +// +// Solidity: function unlock(address _guy, uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHTransactorSession) Unlock(_guy common.Address, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Unlock(&_DelayedWETH.TransactOpts, _guy, _wad) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHTransactor) Withdraw(opts *bind.TransactOpts, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "withdraw", _wad) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHSession) Withdraw(_wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Withdraw(&_DelayedWETH.TransactOpts, _wad) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHTransactorSession) Withdraw(_wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Withdraw(&_DelayedWETH.TransactOpts, _wad) +} + +// Withdraw0 is a paid mutator transaction binding the contract method 0xf3fef3a3. +// +// Solidity: function withdraw(address _guy, uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHTransactor) Withdraw0(opts *bind.TransactOpts, _guy common.Address, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.contract.Transact(opts, "withdraw0", _guy, _wad) +} + +// Withdraw0 is a paid mutator transaction binding the contract method 0xf3fef3a3. +// +// Solidity: function withdraw(address _guy, uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHSession) Withdraw0(_guy common.Address, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Withdraw0(&_DelayedWETH.TransactOpts, _guy, _wad) +} + +// Withdraw0 is a paid mutator transaction binding the contract method 0xf3fef3a3. +// +// Solidity: function withdraw(address _guy, uint256 _wad) returns() +func (_DelayedWETH *DelayedWETHTransactorSession) Withdraw0(_guy common.Address, _wad *big.Int) (*types.Transaction, error) { + return _DelayedWETH.Contract.Withdraw0(&_DelayedWETH.TransactOpts, _guy, _wad) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_DelayedWETH *DelayedWETHTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DelayedWETH.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_DelayedWETH *DelayedWETHSession) Receive() (*types.Transaction, error) { + return _DelayedWETH.Contract.Receive(&_DelayedWETH.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_DelayedWETH *DelayedWETHTransactorSession) Receive() (*types.Transaction, error) { + return _DelayedWETH.Contract.Receive(&_DelayedWETH.TransactOpts) +} + +// DelayedWETHApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the DelayedWETH contract. +type DelayedWETHApprovalIterator struct { + Event *DelayedWETHApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DelayedWETHApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DelayedWETHApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DelayedWETHApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DelayedWETHApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DelayedWETHApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DelayedWETHApproval represents a Approval event raised by the DelayedWETH contract. +type DelayedWETHApproval struct { + Src common.Address + Guy common.Address + Wad *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed src, address indexed guy, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) FilterApproval(opts *bind.FilterOpts, src []common.Address, guy []common.Address) (*DelayedWETHApprovalIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var guyRule []interface{} + for _, guyItem := range guy { + guyRule = append(guyRule, guyItem) + } + + logs, sub, err := _DelayedWETH.contract.FilterLogs(opts, "Approval", srcRule, guyRule) + if err != nil { + return nil, err + } + return &DelayedWETHApprovalIterator{contract: _DelayedWETH.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed src, address indexed guy, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *DelayedWETHApproval, src []common.Address, guy []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var guyRule []interface{} + for _, guyItem := range guy { + guyRule = append(guyRule, guyItem) + } + + logs, sub, err := _DelayedWETH.contract.WatchLogs(opts, "Approval", srcRule, guyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DelayedWETHApproval) + if err := _DelayedWETH.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed src, address indexed guy, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) ParseApproval(log types.Log) (*DelayedWETHApproval, error) { + event := new(DelayedWETHApproval) + if err := _DelayedWETH.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DelayedWETHDepositIterator is returned from FilterDeposit and is used to iterate over the raw logs and unpacked data for Deposit events raised by the DelayedWETH contract. +type DelayedWETHDepositIterator struct { + Event *DelayedWETHDeposit // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DelayedWETHDepositIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DelayedWETHDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DelayedWETHDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DelayedWETHDepositIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DelayedWETHDepositIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DelayedWETHDeposit represents a Deposit event raised by the DelayedWETH contract. +type DelayedWETHDeposit struct { + Dst common.Address + Wad *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDeposit is a free log retrieval operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed dst, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) FilterDeposit(opts *bind.FilterOpts, dst []common.Address) (*DelayedWETHDepositIterator, error) { + + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _DelayedWETH.contract.FilterLogs(opts, "Deposit", dstRule) + if err != nil { + return nil, err + } + return &DelayedWETHDepositIterator{contract: _DelayedWETH.contract, event: "Deposit", logs: logs, sub: sub}, nil +} + +// WatchDeposit is a free log subscription operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed dst, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *DelayedWETHDeposit, dst []common.Address) (event.Subscription, error) { + + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _DelayedWETH.contract.WatchLogs(opts, "Deposit", dstRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DelayedWETHDeposit) + if err := _DelayedWETH.contract.UnpackLog(event, "Deposit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDeposit is a log parse operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed dst, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) ParseDeposit(log types.Log) (*DelayedWETHDeposit, error) { + event := new(DelayedWETHDeposit) + if err := _DelayedWETH.contract.UnpackLog(event, "Deposit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DelayedWETHInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the DelayedWETH contract. +type DelayedWETHInitializedIterator struct { + Event *DelayedWETHInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DelayedWETHInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DelayedWETHInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DelayedWETHInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DelayedWETHInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DelayedWETHInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DelayedWETHInitialized represents a Initialized event raised by the DelayedWETH contract. +type DelayedWETHInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_DelayedWETH *DelayedWETHFilterer) FilterInitialized(opts *bind.FilterOpts) (*DelayedWETHInitializedIterator, error) { + + logs, sub, err := _DelayedWETH.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &DelayedWETHInitializedIterator{contract: _DelayedWETH.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_DelayedWETH *DelayedWETHFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *DelayedWETHInitialized) (event.Subscription, error) { + + logs, sub, err := _DelayedWETH.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DelayedWETHInitialized) + if err := _DelayedWETH.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_DelayedWETH *DelayedWETHFilterer) ParseInitialized(log types.Log) (*DelayedWETHInitialized, error) { + event := new(DelayedWETHInitialized) + if err := _DelayedWETH.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DelayedWETHOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the DelayedWETH contract. +type DelayedWETHOwnershipTransferredIterator struct { + Event *DelayedWETHOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DelayedWETHOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DelayedWETHOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DelayedWETHOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DelayedWETHOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DelayedWETHOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DelayedWETHOwnershipTransferred represents a OwnershipTransferred event raised by the DelayedWETH contract. +type DelayedWETHOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_DelayedWETH *DelayedWETHFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*DelayedWETHOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _DelayedWETH.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &DelayedWETHOwnershipTransferredIterator{contract: _DelayedWETH.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_DelayedWETH *DelayedWETHFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DelayedWETHOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _DelayedWETH.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DelayedWETHOwnershipTransferred) + if err := _DelayedWETH.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_DelayedWETH *DelayedWETHFilterer) ParseOwnershipTransferred(log types.Log) (*DelayedWETHOwnershipTransferred, error) { + event := new(DelayedWETHOwnershipTransferred) + if err := _DelayedWETH.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DelayedWETHTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the DelayedWETH contract. +type DelayedWETHTransferIterator struct { + Event *DelayedWETHTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DelayedWETHTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DelayedWETHTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DelayedWETHTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DelayedWETHTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DelayedWETHTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DelayedWETHTransfer represents a Transfer event raised by the DelayedWETH contract. +type DelayedWETHTransfer struct { + Src common.Address + Dst common.Address + Wad *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed src, address indexed dst, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) FilterTransfer(opts *bind.FilterOpts, src []common.Address, dst []common.Address) (*DelayedWETHTransferIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _DelayedWETH.contract.FilterLogs(opts, "Transfer", srcRule, dstRule) + if err != nil { + return nil, err + } + return &DelayedWETHTransferIterator{contract: _DelayedWETH.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed src, address indexed dst, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *DelayedWETHTransfer, src []common.Address, dst []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _DelayedWETH.contract.WatchLogs(opts, "Transfer", srcRule, dstRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DelayedWETHTransfer) + if err := _DelayedWETH.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed src, address indexed dst, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) ParseTransfer(log types.Log) (*DelayedWETHTransfer, error) { + event := new(DelayedWETHTransfer) + if err := _DelayedWETH.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DelayedWETHUnwrapIterator is returned from FilterUnwrap and is used to iterate over the raw logs and unpacked data for Unwrap events raised by the DelayedWETH contract. +type DelayedWETHUnwrapIterator struct { + Event *DelayedWETHUnwrap // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DelayedWETHUnwrapIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DelayedWETHUnwrap) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DelayedWETHUnwrap) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DelayedWETHUnwrapIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DelayedWETHUnwrapIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DelayedWETHUnwrap represents a Unwrap event raised by the DelayedWETH contract. +type DelayedWETHUnwrap struct { + Src common.Address + Wad *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnwrap is a free log retrieval operation binding the contract event 0x5dd085b6070b4cae004f84daafd199fd55b0bdfa11c3a802baffe89c2419d8c2. +// +// Solidity: event Unwrap(address indexed src, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) FilterUnwrap(opts *bind.FilterOpts, src []common.Address) (*DelayedWETHUnwrapIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + + logs, sub, err := _DelayedWETH.contract.FilterLogs(opts, "Unwrap", srcRule) + if err != nil { + return nil, err + } + return &DelayedWETHUnwrapIterator{contract: _DelayedWETH.contract, event: "Unwrap", logs: logs, sub: sub}, nil +} + +// WatchUnwrap is a free log subscription operation binding the contract event 0x5dd085b6070b4cae004f84daafd199fd55b0bdfa11c3a802baffe89c2419d8c2. +// +// Solidity: event Unwrap(address indexed src, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) WatchUnwrap(opts *bind.WatchOpts, sink chan<- *DelayedWETHUnwrap, src []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + + logs, sub, err := _DelayedWETH.contract.WatchLogs(opts, "Unwrap", srcRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DelayedWETHUnwrap) + if err := _DelayedWETH.contract.UnpackLog(event, "Unwrap", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUnwrap is a log parse operation binding the contract event 0x5dd085b6070b4cae004f84daafd199fd55b0bdfa11c3a802baffe89c2419d8c2. +// +// Solidity: event Unwrap(address indexed src, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) ParseUnwrap(log types.Log) (*DelayedWETHUnwrap, error) { + event := new(DelayedWETHUnwrap) + if err := _DelayedWETH.contract.UnpackLog(event, "Unwrap", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// DelayedWETHWithdrawalIterator is returned from FilterWithdrawal and is used to iterate over the raw logs and unpacked data for Withdrawal events raised by the DelayedWETH contract. +type DelayedWETHWithdrawalIterator struct { + Event *DelayedWETHWithdrawal // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DelayedWETHWithdrawalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DelayedWETHWithdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DelayedWETHWithdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DelayedWETHWithdrawalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DelayedWETHWithdrawalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DelayedWETHWithdrawal represents a Withdrawal event raised by the DelayedWETH contract. +type DelayedWETHWithdrawal struct { + Src common.Address + Wad *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdrawal is a free log retrieval operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed src, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) FilterWithdrawal(opts *bind.FilterOpts, src []common.Address) (*DelayedWETHWithdrawalIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + + logs, sub, err := _DelayedWETH.contract.FilterLogs(opts, "Withdrawal", srcRule) + if err != nil { + return nil, err + } + return &DelayedWETHWithdrawalIterator{contract: _DelayedWETH.contract, event: "Withdrawal", logs: logs, sub: sub}, nil +} + +// WatchWithdrawal is a free log subscription operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed src, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *DelayedWETHWithdrawal, src []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + + logs, sub, err := _DelayedWETH.contract.WatchLogs(opts, "Withdrawal", srcRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DelayedWETHWithdrawal) + if err := _DelayedWETH.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseWithdrawal is a log parse operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed src, uint256 wad) +func (_DelayedWETH *DelayedWETHFilterer) ParseWithdrawal(log types.Log) (*DelayedWETHWithdrawal, error) { + event := new(DelayedWETHWithdrawal) + if err := _DelayedWETH.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-bindings/bindings/delayedweth_more.go b/op-bindings/bindings/delayedweth_more.go new file mode 100644 index 000000000000..6cf91b0ae447 --- /dev/null +++ b/op-bindings/bindings/delayedweth_more.go @@ -0,0 +1,27 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "encoding/json" + + "github.com/ethereum-optimism/optimism/op-bindings/solc" +) + +const DelayedWETHStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/dispute/weth/DelayedWETH.sol:DelayedWETH\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/dispute/weth/DelayedWETH.sol:DelayedWETH\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/dispute/weth/DelayedWETH.sol:DelayedWETH\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1003,\"contract\":\"src/dispute/weth/DelayedWETH.sol:DelayedWETH\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/dispute/weth/DelayedWETH.sol:DelayedWETH\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1005,\"contract\":\"src/dispute/weth/DelayedWETH.sol:DelayedWETH\",\"label\":\"balanceOf\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":1006,\"contract\":\"src/dispute/weth/DelayedWETH.sol:DelayedWETH\",\"label\":\"allowance\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1007,\"contract\":\"src/dispute/weth/DelayedWETH.sol:DelayedWETH\",\"label\":\"withdrawals\",\"offset\":0,\"slot\":\"103\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_struct(WithdrawalRequest)1010_storage))\"},{\"astId\":1008,\"contract\":\"src/dispute/weth/DelayedWETH.sol:DelayedWETH\",\"label\":\"config\",\"offset\":0,\"slot\":\"104\",\"type\":\"t_contract(SuperchainConfig)1009\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(SuperchainConfig)1009\":{\"encoding\":\"inplace\",\"label\":\"contract SuperchainConfig\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_struct(WithdrawalRequest)1010_storage))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e struct IDelayedWETH.WithdrawalRequest))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_struct(WithdrawalRequest)1010_storage)\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_struct(WithdrawalRequest)1010_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e struct IDelayedWETH.WithdrawalRequest)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_struct(WithdrawalRequest)1010_storage\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_struct(WithdrawalRequest)1010_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IDelayedWETH.WithdrawalRequest\",\"numberOfBytes\":\"64\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" + +var DelayedWETHStorageLayout = new(solc.StorageLayout) + +var DelayedWETHDeployedBin = "0x6080604052600436106101845760003560e01c8063715018a6116100d6578063a9059cbb1161007f578063dd62ed3e11610059578063dd62ed3e1461052b578063f2fde38b14610563578063f3fef3a31461058357600080fd5b8063a9059cbb146104af578063cd47bde1146104cf578063d0e30db01461052357600080fd5b80638da5cb5b116100b05780638da5cb5b1461041b57806395d89b4114610446578063977a5ec51461048f57600080fd5b8063715018a61461039457806379502c55146103a95780637eee288d146103fb57600080fd5b80632e1a7d4d1161013857806354fd4d501161011257806354fd4d50146102eb5780636a42b8f81461033457806370a082311461036757600080fd5b80632e1a7d4d14610284578063313ce567146102a4578063485cc955146102cb57600080fd5b80630ca35682116101695780630ca356821461022757806318160ddd1461024757806323b872dd1461026457600080fd5b806306fdde0314610198578063095ea7b3146101f757600080fd5b36610193576101916105a3565b005b600080fd5b3480156101a457600080fd5b506101e16040518060400160405280600d81526020017f577261707065642045746865720000000000000000000000000000000000000081525081565b6040516101ee9190611387565b60405180910390f35b34801561020357600080fd5b5061021761021236600461141c565b6105fe565b60405190151581526020016101ee565b34801561023357600080fd5b50610191610242366004611448565b610677565b34801561025357600080fd5b50475b6040519081526020016101ee565b34801561027057600080fd5b5061021761027f366004611461565b610743565b34801561029057600080fd5b5061019161029f366004611448565b61095a565b3480156102b057600080fd5b506102b9601281565b60405160ff90911681526020016101ee565b3480156102d757600080fd5b506101916102e63660046114a2565b610967565b3480156102f757600080fd5b506101e16040518060400160405280600581526020017f302e322e3000000000000000000000000000000000000000000000000000000081525081565b34801561034057600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610256565b34801561037357600080fd5b506102566103823660046114db565b60656020526000908152604090205481565b3480156103a057600080fd5b50610191610b43565b3480156103b557600080fd5b506068546103d69073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ee565b34801561040757600080fd5b5061019161041636600461141c565b610b57565b34801561042757600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166103d6565b34801561045257600080fd5b506101e16040518060400160405280600481526020017f574554480000000000000000000000000000000000000000000000000000000081525081565b34801561049b57600080fd5b506101916104aa36600461141c565b610bab565b3480156104bb57600080fd5b506102176104ca36600461141c565b610c98565b3480156104db57600080fd5b5061050e6104ea3660046114a2565b60676020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101ee565b6101916105a3565b34801561053757600080fd5b506102566105463660046114a2565b606660209081526000928352604080842090915290825290205481565b34801561056f57600080fd5b5061019161057e3660046114db565b610cac565b34801561058f57600080fd5b5061019161059e36600461141c565b610d60565b33600090815260656020526040812080543492906105c2908490611527565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b33600081815260666020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106669086815260200190565b60405180910390a350600192915050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064015b60405180910390fd5b600047821061070c574761070e565b815b604051909150339082156108fc029083906000818181858888f1935050505015801561073e573d6000803e3d6000fd5b505050565b73ffffffffffffffffffffffffffffffffffffffff831660009081526065602052604081205482111561077557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841633148015906107eb575073ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156108735773ffffffffffffffffffffffffffffffffffffffff8416600090815260666020908152604080832033845290915290205482111561082d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526066602090815260408083203384529091528120805484929061086d90849061153f565b90915550505b73ffffffffffffffffffffffffffffffffffffffff8416600090815260656020526040812080548492906108a890849061153f565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600090815260656020526040812080548492906108e2908490611527565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161094891815260200190565b60405180910390a35060019392505050565b6109643382610d60565b50565b600054610100900460ff16158080156109875750600054600160ff909116105b806109a15750303b1580156109a1575060005460ff166001145b610a2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106f4565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610a8b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a936110aa565b610a9c83611149565b606880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561073e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b610b4b6111c0565b610b556000611149565b565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120426001820155805490918391839190610ba1908490611527565b9091555050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f44656c61796564574554483a206e6f74206f776e65720000000000000000000060448201526064016106f4565b73ffffffffffffffffffffffffffffffffffffffff821660008181526066602090815260408083203380855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050565b6000610ca5338484610743565b9392505050565b610cb46111c0565b73ffffffffffffffffffffffffffffffffffffffff8116610d57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106f4565b61096481611149565b606860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df19190611556565b15610e58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f44656c61796564574554483a20636f6e7472616374206973207061757365640060448201526064016106f4565b33600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290208054821115610f19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f44656c61796564574554483a20696e73756666696369656e7420756e6c6f636b60448201527f6564207769746864726177616c0000000000000000000000000000000000000060648201526084016106f4565b6000816001015411610fac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f44656c61796564574554483a207769746864726177616c206e6f7420756e6c6f60448201527f636b65640000000000000000000000000000000000000000000000000000000060648201526084016106f4565b427f00000000000000000000000000000000000000000000000000000000000000008260010154610fdd9190611527565b111561106b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f44656c61796564574554483a207769746864726177616c2064656c6179206e6f60448201527f74206d657400000000000000000000000000000000000000000000000000000060648201526084016106f4565b8181600001600082825461107f919061153f565b9091555061073e905082611241565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16611141576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106f4565b610b556112e7565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610b55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f4565b3360009081526065602052604090205481111561125d57600080fd5b336000908152606560205260408120805483929061127c90849061153f565b9091555050604051339082156108fc029083906000818181858888f193505050501580156112ae573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b600054610100900460ff1661137e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106f4565b610b5533611149565b600060208083528351808285015260005b818110156113b457858101830151858201604001528201611398565b818111156113c6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461096457600080fd5b6000806040838503121561142f57600080fd5b823561143a816113fa565b946020939093013593505050565b60006020828403121561145a57600080fd5b5035919050565b60008060006060848603121561147657600080fd5b8335611481816113fa565b92506020840135611491816113fa565b929592945050506040919091013590565b600080604083850312156114b557600080fd5b82356114c0816113fa565b915060208301356114d0816113fa565b809150509250929050565b6000602082840312156114ed57600080fd5b8135610ca5816113fa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561153a5761153a6114f8565b500190565b600082821015611551576115516114f8565b500390565b60006020828403121561156857600080fd5b81518015158114610ca557600080fdfea164736f6c634300080f000a" + + +func init() { + if err := json.Unmarshal([]byte(DelayedWETHStorageLayoutJSON), DelayedWETHStorageLayout); err != nil { + panic(err) + } + + layouts["DelayedWETH"] = DelayedWETHStorageLayout + deployedBytecodes["DelayedWETH"] = DelayedWETHDeployedBin + immutableReferences["DelayedWETH"] = true +} diff --git a/op-bindings/bindings/deployerwhitelist.go b/op-bindings/bindings/deployerwhitelist.go index 4e66b0af4265..f70892a12f7a 100644 --- a/op-bindings/bindings/deployerwhitelist.go +++ b/op-bindings/bindings/deployerwhitelist.go @@ -30,7 +30,7 @@ var ( // DeployerWhitelistMetaData contains all meta data concerning the DeployerWhitelist contract. var DeployerWhitelistMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"}],\"name\":\"WhitelistDisabled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"whitelisted\",\"type\":\"bool\"}],\"name\":\"WhitelistStatusChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"enableArbitraryContractDeployment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_deployer\",\"type\":\"address\"}],\"name\":\"isDeployerAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_deployer\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_isWhitelisted\",\"type\":\"bool\"}],\"name\":\"setWhitelistedDeployer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"whitelist\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"type\":\"function\",\"name\":\"enableArbitraryContractDeployment\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isDeployerAllowed\",\"inputs\":[{\"name\":\"_deployer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setOwner\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setWhitelistedDeployer\",\"inputs\":[{\"name\":\"_deployer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_isWhitelisted\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"whitelist\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"OwnerChanged\",\"inputs\":[{\"name\":\"oldOwner\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WhitelistDisabled\",\"inputs\":[{\"name\":\"oldOwner\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WhitelistStatusChanged\",\"inputs\":[{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"whitelisted\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false}]", Bin: "0x608060405234801561001057600080fd5b506107bc806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100fc5780639b19251a14610141578063b1540a0114610174578063bdc7b54f1461018757600080fd5b806308fd63221461008257806313af40351461009757806354fd4d50146100aa575b600080fd5b6100956100903660046106de565b61018f565b005b6100956100a536600461071a565b6102ef565b6100e66040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100f3919061073c565b60405180910390f35b60005461011c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f3565b61016461014f36600461071a565b60016020526000908152604090205460ff1681565b60405190151581526020016100f3565b61016461018236600461071a565b610520565b610095610571565b60005473ffffffffffffffffffffffffffffffffffffffff163314610261576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4465706c6f79657257686974656c6973743a2066756e6374696f6e2063616e2060448201527f6f6e6c792062652063616c6c656420627920746865206f776e6572206f66207460648201527f68697320636f6e74726163740000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526001602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558251938452908301527f8daaf060c3306c38e068a75c054bf96ecd85a3db1252712c4d93632744c42e0d910160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4465706c6f79657257686974656c6973743a2066756e6374696f6e2063616e2060448201527f6f6e6c792062652063616c6c656420627920746865206f776e6572206f66207460648201527f68697320636f6e74726163740000000000000000000000000000000000000000608482015260a401610258565b73ffffffffffffffffffffffffffffffffffffffff8116610485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f4465706c6f79657257686974656c6973743a2063616e206f6e6c79206265206460448201527f697361626c65642076696120656e61626c65417262697472617279436f6e747260648201527f6163744465706c6f796d656e7400000000000000000000000000000000000000608482015260a401610258565b6000546040805173ffffffffffffffffffffffffffffffffffffffff928316815291831660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000805473ffffffffffffffffffffffffffffffffffffffff16158061056b575073ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090205460ff165b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461063e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4465706c6f79657257686974656c6973743a2066756e6374696f6e2063616e2060448201527f6f6e6c792062652063616c6c656420627920746865206f776e6572206f66207460648201527f68697320636f6e74726163740000000000000000000000000000000000000000608482015260a401610258565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681527fc0e106cf568e50698fdbde1eff56f5a5c966cc7958e37e276918e9e4ccdf8cd49060200160405180910390a1600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d957600080fd5b919050565b600080604083850312156106f157600080fd5b6106fa836106b5565b91506020830135801515811461070f57600080fd5b809150509250929050565b60006020828403121561072c57600080fd5b610735826106b5565b9392505050565b600060208083528351808285015260005b818110156107695785810183015185820160400152820161074d565b8181111561077b576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/deployerwhitelist_more.go b/op-bindings/bindings/deployerwhitelist_more.go index b19acbdd0dca..f324998285dd 100644 --- a/op-bindings/bindings/deployerwhitelist_more.go +++ b/op-bindings/bindings/deployerwhitelist_more.go @@ -15,6 +15,7 @@ var DeployerWhitelistStorageLayout = new(solc.StorageLayout) var DeployerWhitelistDeployedBin = "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100fc5780639b19251a14610141578063b1540a0114610174578063bdc7b54f1461018757600080fd5b806308fd63221461008257806313af40351461009757806354fd4d50146100aa575b600080fd5b6100956100903660046106de565b61018f565b005b6100956100a536600461071a565b6102ef565b6100e66040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100f3919061073c565b60405180910390f35b60005461011c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f3565b61016461014f36600461071a565b60016020526000908152604090205460ff1681565b60405190151581526020016100f3565b61016461018236600461071a565b610520565b610095610571565b60005473ffffffffffffffffffffffffffffffffffffffff163314610261576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4465706c6f79657257686974656c6973743a2066756e6374696f6e2063616e2060448201527f6f6e6c792062652063616c6c656420627920746865206f776e6572206f66207460648201527f68697320636f6e74726163740000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526001602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558251938452908301527f8daaf060c3306c38e068a75c054bf96ecd85a3db1252712c4d93632744c42e0d910160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4465706c6f79657257686974656c6973743a2066756e6374696f6e2063616e2060448201527f6f6e6c792062652063616c6c656420627920746865206f776e6572206f66207460648201527f68697320636f6e74726163740000000000000000000000000000000000000000608482015260a401610258565b73ffffffffffffffffffffffffffffffffffffffff8116610485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f4465706c6f79657257686974656c6973743a2063616e206f6e6c79206265206460448201527f697361626c65642076696120656e61626c65417262697472617279436f6e747260648201527f6163744465706c6f796d656e7400000000000000000000000000000000000000608482015260a401610258565b6000546040805173ffffffffffffffffffffffffffffffffffffffff928316815291831660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000805473ffffffffffffffffffffffffffffffffffffffff16158061056b575073ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090205460ff165b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461063e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4465706c6f79657257686974656c6973743a2066756e6374696f6e2063616e2060448201527f6f6e6c792062652063616c6c656420627920746865206f776e6572206f66207460648201527f68697320636f6e74726163740000000000000000000000000000000000000000608482015260a401610258565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681527fc0e106cf568e50698fdbde1eff56f5a5c966cc7958e37e276918e9e4ccdf8cd49060200160405180910390a1600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d957600080fd5b919050565b600080604083850312156106f157600080fd5b6106fa836106b5565b91506020830135801515811461070f57600080fd5b809150509250929050565b60006020828403121561072c57600080fd5b610735826106b5565b9392505050565b600060208083528351808285015260005b818110156107695785810183015185820160400152820161074d565b8181111561077b576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(DeployerWhitelistStorageLayoutJSON), DeployerWhitelistStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["DeployerWhitelist"] = DeployerWhitelistStorageLayout deployedBytecodes["DeployerWhitelist"] = DeployerWhitelistDeployedBin + immutableReferences["DeployerWhitelist"] = false } diff --git a/op-bindings/bindings/deterministicdeploymentproxy.go b/op-bindings/bindings/deterministicdeploymentproxy.go new file mode 100644 index 000000000000..329d5f8366f9 --- /dev/null +++ b/op-bindings/bindings/deterministicdeploymentproxy.go @@ -0,0 +1,223 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// DeterministicDeploymentProxyMetaData contains all meta data concerning the DeterministicDeploymentProxy contract. +var DeterministicDeploymentProxyMetaData = &bind.MetaData{ + ABI: "[{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\",\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"creationCode\",\"type\":\"bytes\"}]}]", + Bin: "0x604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3", +} + +// DeterministicDeploymentProxyABI is the input ABI used to generate the binding from. +// Deprecated: Use DeterministicDeploymentProxyMetaData.ABI instead. +var DeterministicDeploymentProxyABI = DeterministicDeploymentProxyMetaData.ABI + +// DeterministicDeploymentProxyBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use DeterministicDeploymentProxyMetaData.Bin instead. +var DeterministicDeploymentProxyBin = DeterministicDeploymentProxyMetaData.Bin + +// DeployDeterministicDeploymentProxy deploys a new Ethereum contract, binding an instance of DeterministicDeploymentProxy to it. +func DeployDeterministicDeploymentProxy(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *DeterministicDeploymentProxy, error) { + parsed, err := DeterministicDeploymentProxyMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DeterministicDeploymentProxyBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &DeterministicDeploymentProxy{DeterministicDeploymentProxyCaller: DeterministicDeploymentProxyCaller{contract: contract}, DeterministicDeploymentProxyTransactor: DeterministicDeploymentProxyTransactor{contract: contract}, DeterministicDeploymentProxyFilterer: DeterministicDeploymentProxyFilterer{contract: contract}}, nil +} + +// DeterministicDeploymentProxy is an auto generated Go binding around an Ethereum contract. +type DeterministicDeploymentProxy struct { + DeterministicDeploymentProxyCaller // Read-only binding to the contract + DeterministicDeploymentProxyTransactor // Write-only binding to the contract + DeterministicDeploymentProxyFilterer // Log filterer for contract events +} + +// DeterministicDeploymentProxyCaller is an auto generated read-only Go binding around an Ethereum contract. +type DeterministicDeploymentProxyCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DeterministicDeploymentProxyTransactor is an auto generated write-only Go binding around an Ethereum contract. +type DeterministicDeploymentProxyTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DeterministicDeploymentProxyFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type DeterministicDeploymentProxyFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DeterministicDeploymentProxySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type DeterministicDeploymentProxySession struct { + Contract *DeterministicDeploymentProxy // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// DeterministicDeploymentProxyCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type DeterministicDeploymentProxyCallerSession struct { + Contract *DeterministicDeploymentProxyCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// DeterministicDeploymentProxyTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type DeterministicDeploymentProxyTransactorSession struct { + Contract *DeterministicDeploymentProxyTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// DeterministicDeploymentProxyRaw is an auto generated low-level Go binding around an Ethereum contract. +type DeterministicDeploymentProxyRaw struct { + Contract *DeterministicDeploymentProxy // Generic contract binding to access the raw methods on +} + +// DeterministicDeploymentProxyCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type DeterministicDeploymentProxyCallerRaw struct { + Contract *DeterministicDeploymentProxyCaller // Generic read-only contract binding to access the raw methods on +} + +// DeterministicDeploymentProxyTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type DeterministicDeploymentProxyTransactorRaw struct { + Contract *DeterministicDeploymentProxyTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewDeterministicDeploymentProxy creates a new instance of DeterministicDeploymentProxy, bound to a specific deployed contract. +func NewDeterministicDeploymentProxy(address common.Address, backend bind.ContractBackend) (*DeterministicDeploymentProxy, error) { + contract, err := bindDeterministicDeploymentProxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &DeterministicDeploymentProxy{DeterministicDeploymentProxyCaller: DeterministicDeploymentProxyCaller{contract: contract}, DeterministicDeploymentProxyTransactor: DeterministicDeploymentProxyTransactor{contract: contract}, DeterministicDeploymentProxyFilterer: DeterministicDeploymentProxyFilterer{contract: contract}}, nil +} + +// NewDeterministicDeploymentProxyCaller creates a new read-only instance of DeterministicDeploymentProxy, bound to a specific deployed contract. +func NewDeterministicDeploymentProxyCaller(address common.Address, caller bind.ContractCaller) (*DeterministicDeploymentProxyCaller, error) { + contract, err := bindDeterministicDeploymentProxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &DeterministicDeploymentProxyCaller{contract: contract}, nil +} + +// NewDeterministicDeploymentProxyTransactor creates a new write-only instance of DeterministicDeploymentProxy, bound to a specific deployed contract. +func NewDeterministicDeploymentProxyTransactor(address common.Address, transactor bind.ContractTransactor) (*DeterministicDeploymentProxyTransactor, error) { + contract, err := bindDeterministicDeploymentProxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &DeterministicDeploymentProxyTransactor{contract: contract}, nil +} + +// NewDeterministicDeploymentProxyFilterer creates a new log filterer instance of DeterministicDeploymentProxy, bound to a specific deployed contract. +func NewDeterministicDeploymentProxyFilterer(address common.Address, filterer bind.ContractFilterer) (*DeterministicDeploymentProxyFilterer, error) { + contract, err := bindDeterministicDeploymentProxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &DeterministicDeploymentProxyFilterer{contract: contract}, nil +} + +// bindDeterministicDeploymentProxy binds a generic wrapper to an already deployed contract. +func bindDeterministicDeploymentProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(DeterministicDeploymentProxyABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_DeterministicDeploymentProxy *DeterministicDeploymentProxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DeterministicDeploymentProxy.Contract.DeterministicDeploymentProxyCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_DeterministicDeploymentProxy *DeterministicDeploymentProxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DeterministicDeploymentProxy.Contract.DeterministicDeploymentProxyTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_DeterministicDeploymentProxy *DeterministicDeploymentProxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DeterministicDeploymentProxy.Contract.DeterministicDeploymentProxyTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_DeterministicDeploymentProxy *DeterministicDeploymentProxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DeterministicDeploymentProxy.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_DeterministicDeploymentProxy *DeterministicDeploymentProxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DeterministicDeploymentProxy.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_DeterministicDeploymentProxy *DeterministicDeploymentProxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DeterministicDeploymentProxy.Contract.contract.Transact(opts, method, params...) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_DeterministicDeploymentProxy *DeterministicDeploymentProxyTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _DeterministicDeploymentProxy.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_DeterministicDeploymentProxy *DeterministicDeploymentProxySession) Fallback(calldata []byte) (*types.Transaction, error) { + return _DeterministicDeploymentProxy.Contract.Fallback(&_DeterministicDeploymentProxy.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_DeterministicDeploymentProxy *DeterministicDeploymentProxyTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _DeterministicDeploymentProxy.Contract.Fallback(&_DeterministicDeploymentProxy.TransactOpts, calldata) +} diff --git a/op-bindings/bindings/deterministicdeploymentproxy_more.go b/op-bindings/bindings/deterministicdeploymentproxy_more.go new file mode 100644 index 000000000000..86774b7df91e --- /dev/null +++ b/op-bindings/bindings/deterministicdeploymentproxy_more.go @@ -0,0 +1,9 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var DeterministicDeploymentProxyDeployedBin = "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" +func init() { + deployedBytecodes["DeterministicDeploymentProxy"] = DeterministicDeploymentProxyDeployedBin +} diff --git a/op-bindings/bindings/disputegamefactory.go b/op-bindings/bindings/disputegamefactory.go index ab4bab88050a..acf988458001 100644 --- a/op-bindings/bindings/disputegamefactory.go +++ b/op-bindings/bindings/disputegamefactory.go @@ -28,10 +28,19 @@ var ( _ = event.NewSubscription ) +// IDisputeGameFactoryGameSearchResult is an auto generated low-level Go binding around an user-defined struct. +type IDisputeGameFactoryGameSearchResult struct { + Index *big.Int + Metadata [32]byte + Timestamp uint64 + RootClaim [32]byte + ExtraData []byte +} + // DisputeGameFactoryMetaData contains all meta data concerning the DisputeGameFactory contract. var DisputeGameFactoryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"Hash\",\"name\":\"uuid\",\"type\":\"bytes32\"}],\"name\":\"GameAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"GameType\",\"name\":\"gameType\",\"type\":\"uint8\"}],\"name\":\"NoImplementation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"disputeProxy\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"GameType\",\"name\":\"gameType\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"}],\"name\":\"DisputeGameCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"impl\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"GameType\",\"name\":\"gameType\",\"type\":\"uint8\"}],\"name\":\"ImplementationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"GameType\",\"name\":\"_gameType\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"_rootClaim\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"create\",\"outputs\":[{\"internalType\":\"contractIDisputeGame\",\"name\":\"proxy_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"gameAtIndex\",\"outputs\":[{\"internalType\":\"GameType\",\"name\":\"gameType_\",\"type\":\"uint8\"},{\"internalType\":\"Timestamp\",\"name\":\"timestamp_\",\"type\":\"uint64\"},{\"internalType\":\"contractIDisputeGame\",\"name\":\"proxy_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gameCount_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"GameType\",\"name\":\"\",\"type\":\"uint8\"}],\"name\":\"gameImpls\",\"outputs\":[{\"internalType\":\"contractIDisputeGame\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"GameType\",\"name\":\"_gameType\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"_rootClaim\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"games\",\"outputs\":[{\"internalType\":\"contractIDisputeGame\",\"name\":\"proxy_\",\"type\":\"address\"},{\"internalType\":\"Timestamp\",\"name\":\"timestamp_\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"GameType\",\"name\":\"_gameType\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"_rootClaim\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"getGameUUID\",\"outputs\":[{\"internalType\":\"Hash\",\"name\":\"uuid_\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"GameType\",\"name\":\"_gameType\",\"type\":\"uint8\"},{\"internalType\":\"contractIDisputeGame\",\"name\":\"_impl\",\"type\":\"address\"}],\"name\":\"setImplementation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b506200001e600062000024565b62000292565b600054610100900460ff1615808015620000455750600054600160ff909116105b8062000075575062000062306200016260201b6200097e1760201c565b15801562000075575060005460ff166001145b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000102576000805461ff0019166101001790555b6200010c62000171565b6200011782620001d9565b80156200015e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff16620001cd5760405162461bcd60e51b815260206004820152602b6024820152600080516020620012d183398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b620001d76200022b565b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16620002875760405162461bcd60e51b815260206004820152602b6024820152600080516020620012d183398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b620001d733620001d9565b61102f80620002a26000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063c4d66de81161005b578063c4d66de8146102e8578063dfa162d3146102fb578063f2fde38b1461033157600080fd5b80638da5cb5b14610231578063bb8aa1fc1461024f578063c49d5271146102a057600080fd5b80634d1975b4116100b25780634d1975b4146101d857806354fd4d50146101e0578063715018a61461022957600080fd5b806326daafbe146100d95780633142e55e1461018b57806345583b7a146101c3575b600080fd5b6101786100e7366004610d45565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0810180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0830180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086018051988652968352606087529451609f0190941683209190925291905291905290565b6040519081526020015b60405180910390f35b61019e610199366004610e2e565b610344565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610182565b6101d66101d1366004610ed7565b6105a6565b005b606754610178565b61021c6040518060400160405280600581526020017f302e302e3600000000000000000000000000000000000000000000000000000081525081565b6040516101829190610f0e565b6101d661062d565b60335473ffffffffffffffffffffffffffffffffffffffff1661019e565b61026261025d366004610f81565b610641565b6040805160ff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610182565b6102b36102ae366004610e2e565b6106a3565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610182565b6101d66102f6366004610f9a565b61072b565b61019e610309366004610fbe565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6101d661033f366004610f9a565b6108c7565b60ff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806103ae576040517f44265d6f00000000000000000000000000000000000000000000000000000000815260ff871660048201526024015b60405180910390fd5b6104118585856040516020016103c693929190610fd9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff83169061099a565b91508173ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561045b57600080fd5b505af115801561046f573d6000803e3d6000fd5b5050505060006104b6878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506100e792505050565b60008181526066602052604090205490915015610502576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016103a5565b60004260b81b60f889901b178417600083815260666020526040808220839055606780546001810182559083527f9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae0183905551919250889160ff8b169173ffffffffffffffffffffffffffffffffffffffff8816917ffad0599ff449d8d9685eadecca8cb9e00924c5fd8367c1c09469824939e1ffec9190a4505050949350505050565b6105ae610ace565b60ff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917f623713f72f6e427a8044bb8b3bd6834357cf285decbaa21bcc73c1d0632c4d8491a35050565b610635610ace565b61063f6000610b4f565b565b60008060006106966067858154811061065c5761065c610ff3565b906000526020600020015460f881901c9167ffffffffffffffff60b883901c169173ffffffffffffffffffffffffffffffffffffffff1690565b9196909550909350915050565b60008060006106e9878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506100e792505050565b60009081526066602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860b89190911c67ffffffffffffffff16975095505050505050565b600054610100900460ff161580801561074b5750600054600160ff909116105b806107655750303b158015610765575060005460ff166001145b6107f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016103a5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561084f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610857610bc6565b61086082610b4f565b80156108c357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6108cf610ace565b73ffffffffffffffffffffffffffffffffffffffff8116610972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a5565b61097b81610b4f565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60006002825101603f8101600a81036040518360581b8260e81b177f6100003d81600a3d39f3363d3d373d3d3d3d610000806035363936013d7300001781528660601b601e8201527f5af43d3d93803e603357fd5bf300000000000000000000000000000000000000603282015285519150603f8101602087015b60208410610a5257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09093019260209182019101610a15565b517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602085900360031b1b16815260f085901b9083015282816000f0945084610abf577febfef1880000000000000000000000000000000000000000000000000000000060005260206000fd5b90910160405250909392505050565b60335473ffffffffffffffffffffffffffffffffffffffff16331461063f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a5565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610c5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016103a5565b61063f600054610100900460ff16610cf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016103a5565b61063f33610b4f565b803560ff81168114610d1157600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080600060608486031215610d5a57600080fd5b610d6384610d00565b925060208401359150604084013567ffffffffffffffff80821115610d8757600080fd5b818601915086601f830112610d9b57600080fd5b813581811115610dad57610dad610d16565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610df357610df3610d16565b81604052828152896020848701011115610e0c57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60008060008060608587031215610e4457600080fd5b610e4d85610d00565b935060208501359250604085013567ffffffffffffffff80821115610e7157600080fd5b818701915087601f830112610e8557600080fd5b813581811115610e9457600080fd5b886020828501011115610ea657600080fd5b95989497505060200194505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461097b57600080fd5b60008060408385031215610eea57600080fd5b610ef383610d00565b91506020830135610f0381610eb5565b809150509250929050565b600060208083528351808285015260005b81811015610f3b57858101830151858201604001528201610f1f565b81811115610f4d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600060208284031215610f9357600080fd5b5035919050565b600060208284031215610fac57600080fd5b8135610fb781610eb5565b9392505050565b600060208284031215610fd057600080fd5b610fb782610d00565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"create\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"_rootClaim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"proxy_\",\"type\":\"address\",\"internalType\":\"contractIDisputeGame\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"findLatestGames\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"_start\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_n\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"games_\",\"type\":\"tuple[]\",\"internalType\":\"structIDisputeGameFactory.GameSearchResult[]\",\"components\":[{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"metadata\",\"type\":\"bytes32\",\"internalType\":\"GameId\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"},{\"name\":\"rootClaim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameAtIndex\",\"inputs\":[{\"name\":\"_index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"timestamp_\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"},{\"name\":\"proxy_\",\"type\":\"address\",\"internalType\":\"contractIDisputeGame\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameCount\",\"inputs\":[],\"outputs\":[{\"name\":\"gameCount_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameImpls\",\"inputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"GameType\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIDisputeGame\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"games\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"_rootClaim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"proxy_\",\"type\":\"address\",\"internalType\":\"contractIDisputeGame\"},{\"name\":\"timestamp_\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getGameUUID\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"_rootClaim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"uuid_\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"initBonds\",\"inputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"GameType\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setImplementation\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"_impl\",\"type\":\"address\",\"internalType\":\"contractIDisputeGame\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setInitBond\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"_initBond\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"DisputeGameCreated\",\"inputs\":[{\"name\":\"disputeProxy\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"gameType\",\"type\":\"uint32\",\"indexed\":true,\"internalType\":\"GameType\"},{\"name\":\"rootClaim\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"Claim\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ImplementationSet\",\"inputs\":[{\"name\":\"impl\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"gameType\",\"type\":\"uint32\",\"indexed\":true,\"internalType\":\"GameType\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"InitBondUpdated\",\"inputs\":[{\"name\":\"gameType\",\"type\":\"uint32\",\"indexed\":true,\"internalType\":\"GameType\"},{\"name\":\"newBond\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"GameAlreadyExists\",\"inputs\":[{\"name\":\"uuid\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}]},{\"type\":\"error\",\"name\":\"InsufficientBond\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoImplementation\",\"inputs\":[{\"name\":\"gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"}]}]", + Bin: "0x60806040523480156200001157600080fd5b506200001e600062000024565b62000292565b600054610100900460ff1615808015620000455750600054600160ff909116105b8062000075575062000062306200016260201b62000cdc1760201c565b15801562000075575060005460ff166001145b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000102576000805461ff0019166101001790555b6200010c62000171565b6200011782620001d9565b80156200015e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff16620001cd5760405162461bcd60e51b815260206004820152602b60248201526000805160206200180083398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b620001d76200022b565b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16620002875760405162461bcd60e51b815260206004820152602b60248201526000805160206200180083398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b620001d733620001d9565b61155e80620002a26000396000f3fe6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d610108366004611099565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110d0565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d6101973660046110eb565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611115565b6104aa565b60405161017391906111c2565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600581526020017f302e322e3000000000000000000000000000000000000000000000000000000081525081565b604051610173919061127f565b34801561024a57600080fd5b5061025e610259366004611292565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110d0565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e3366004611292565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e366004611292565b6109ee565b34801561033f57600080fd5b5061035361034e366004611319565b610a27565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af366004611332565b610a89565b3480156103c057600080fd5b5061010d6103cf366004611332565b610c25565b6103dc610cf8565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610cf8565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061134f565b600091825260209091200154905060e081901c67ffffffffffffffff60a083901c1673ffffffffffffffffffffffffffffffffffffffff831660ff808a16908416036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113ad565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106439190611478565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a516106859190611491565b815181106106955761069561134f565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ee565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610cf8565b6107536000610d79565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff8616600090815260666020526040902054341015610814576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610821600143611491565b4090506108898682878760405160200161083e94939291906114cf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df0565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d357600080fd5b505af11580156108e7573d6000803e3d6000fd5b505050505060006108fa888888886109ee565b60008181526067602052604090205490915015610946576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a0794939291906114f0565b604051602081830303815290604052805190602001209050949350505050565b6000806000610a7c60688581548110610a4257610a4261134f565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9196909550909350915050565b600054610100900460ff1615808015610aa95750600054600160ff909116105b80610ac35750303b158015610ac3575060005460ff166001145b610b4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bad57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bb5610f24565b610bbe82610d79565b8015610c2157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c2d610cf8565b73ffffffffffffffffffffffffffffffffffffffff8116610cd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610cd981610d79565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006002825101603f8101600a81036040518360581b8260e81b177f6100003d81600a3d39f3363d3d373d3d3d3d610000806035363936013d7300001781528660601b601e8201527f5af43d3d93803e603357fd5bf300000000000000000000000000000000000000603282015285519150603f8101602087015b60208410610ea857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09093019260209182019101610e6b565b517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602085900360031b1b16815260f085901b9083015282816000f0945084610f15577febfef1880000000000000000000000000000000000000000000000000000000060005260206000fd5b90910160405250909392505050565b600054610100900460ff16610fbb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753600054610100900460ff16611055576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d79565b803563ffffffff8116811461107257600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610cd957600080fd5b600080604083850312156110ac57600080fd5b6110b58361105e565b915060208301356110c581611077565b809150509250929050565b6000602082840312156110e257600080fd5b6106e78261105e565b600080604083850312156110fe57600080fd5b6111078361105e565b946020939093013593505050565b60008060006060848603121561112a57600080fd5b6111338461105e565b95602085013595506040909401359392505050565b60005b8381101561116357818101518382015260200161114b565b83811115611172576000848401525b50505050565b60008151808452611190816020860160208601611148565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611271578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061125d81860183611178565b9689019694505050908601906001016111e9565b509098975050505050505050565b6020815260006106e76020830184611178565b600080600080606085870312156112a857600080fd5b6112b18561105e565b935060208501359250604085013567ffffffffffffffff808211156112d557600080fd5b818701915087601f8301126112e957600080fd5b8135818111156112f857600080fd5b88602082850101111561130a57600080fd5b95989497505060200194505050565b60006020828403121561132b57600080fd5b5035919050565b60006020828403121561134457600080fd5b81356106e781611077565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113bf57600080fd5b815167ffffffffffffffff808211156113d757600080fd5b818401915084601f8301126113eb57600080fd5b8151818111156113fd576113fd61137e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156114435761144361137e565b8160405282815287602084870101111561145c57600080fd5b61146d836020830160208801611148565b979650505050505050565b60006020828403121561148a57600080fd5b5051919050565b6000828210156114ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b84815283602082015281836040830137600091016040019081529392505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", } // DisputeGameFactoryABI is the input ABI used to generate the binding from. @@ -201,11 +210,42 @@ func (_DisputeGameFactory *DisputeGameFactoryTransactorRaw) Transact(opts *bind. return _DisputeGameFactory.Contract.contract.Transact(opts, method, params...) } +// FindLatestGames is a free data retrieval call binding the contract method 0x254bd683. +// +// Solidity: function findLatestGames(uint32 _gameType, uint256 _start, uint256 _n) view returns((uint256,bytes32,uint64,bytes32,bytes)[] games_) +func (_DisputeGameFactory *DisputeGameFactoryCaller) FindLatestGames(opts *bind.CallOpts, _gameType uint32, _start *big.Int, _n *big.Int) ([]IDisputeGameFactoryGameSearchResult, error) { + var out []interface{} + err := _DisputeGameFactory.contract.Call(opts, &out, "findLatestGames", _gameType, _start, _n) + + if err != nil { + return *new([]IDisputeGameFactoryGameSearchResult), err + } + + out0 := *abi.ConvertType(out[0], new([]IDisputeGameFactoryGameSearchResult)).(*[]IDisputeGameFactoryGameSearchResult) + + return out0, err + +} + +// FindLatestGames is a free data retrieval call binding the contract method 0x254bd683. +// +// Solidity: function findLatestGames(uint32 _gameType, uint256 _start, uint256 _n) view returns((uint256,bytes32,uint64,bytes32,bytes)[] games_) +func (_DisputeGameFactory *DisputeGameFactorySession) FindLatestGames(_gameType uint32, _start *big.Int, _n *big.Int) ([]IDisputeGameFactoryGameSearchResult, error) { + return _DisputeGameFactory.Contract.FindLatestGames(&_DisputeGameFactory.CallOpts, _gameType, _start, _n) +} + +// FindLatestGames is a free data retrieval call binding the contract method 0x254bd683. +// +// Solidity: function findLatestGames(uint32 _gameType, uint256 _start, uint256 _n) view returns((uint256,bytes32,uint64,bytes32,bytes)[] games_) +func (_DisputeGameFactory *DisputeGameFactoryCallerSession) FindLatestGames(_gameType uint32, _start *big.Int, _n *big.Int) ([]IDisputeGameFactoryGameSearchResult, error) { + return _DisputeGameFactory.Contract.FindLatestGames(&_DisputeGameFactory.CallOpts, _gameType, _start, _n) +} + // GameAtIndex is a free data retrieval call binding the contract method 0xbb8aa1fc. // -// Solidity: function gameAtIndex(uint256 _index) view returns(uint8 gameType_, uint64 timestamp_, address proxy_) +// Solidity: function gameAtIndex(uint256 _index) view returns(uint32 gameType_, uint64 timestamp_, address proxy_) func (_DisputeGameFactory *DisputeGameFactoryCaller) GameAtIndex(opts *bind.CallOpts, _index *big.Int) (struct { - GameType uint8 + GameType uint32 Timestamp uint64 Proxy common.Address }, error) { @@ -213,7 +253,7 @@ func (_DisputeGameFactory *DisputeGameFactoryCaller) GameAtIndex(opts *bind.Call err := _DisputeGameFactory.contract.Call(opts, &out, "gameAtIndex", _index) outstruct := new(struct { - GameType uint8 + GameType uint32 Timestamp uint64 Proxy common.Address }) @@ -221,7 +261,7 @@ func (_DisputeGameFactory *DisputeGameFactoryCaller) GameAtIndex(opts *bind.Call return *outstruct, err } - outstruct.GameType = *abi.ConvertType(out[0], new(uint8)).(*uint8) + outstruct.GameType = *abi.ConvertType(out[0], new(uint32)).(*uint32) outstruct.Timestamp = *abi.ConvertType(out[1], new(uint64)).(*uint64) outstruct.Proxy = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) @@ -231,9 +271,9 @@ func (_DisputeGameFactory *DisputeGameFactoryCaller) GameAtIndex(opts *bind.Call // GameAtIndex is a free data retrieval call binding the contract method 0xbb8aa1fc. // -// Solidity: function gameAtIndex(uint256 _index) view returns(uint8 gameType_, uint64 timestamp_, address proxy_) +// Solidity: function gameAtIndex(uint256 _index) view returns(uint32 gameType_, uint64 timestamp_, address proxy_) func (_DisputeGameFactory *DisputeGameFactorySession) GameAtIndex(_index *big.Int) (struct { - GameType uint8 + GameType uint32 Timestamp uint64 Proxy common.Address }, error) { @@ -242,9 +282,9 @@ func (_DisputeGameFactory *DisputeGameFactorySession) GameAtIndex(_index *big.In // GameAtIndex is a free data retrieval call binding the contract method 0xbb8aa1fc. // -// Solidity: function gameAtIndex(uint256 _index) view returns(uint8 gameType_, uint64 timestamp_, address proxy_) +// Solidity: function gameAtIndex(uint256 _index) view returns(uint32 gameType_, uint64 timestamp_, address proxy_) func (_DisputeGameFactory *DisputeGameFactoryCallerSession) GameAtIndex(_index *big.Int) (struct { - GameType uint8 + GameType uint32 Timestamp uint64 Proxy common.Address }, error) { @@ -282,10 +322,10 @@ func (_DisputeGameFactory *DisputeGameFactoryCallerSession) GameCount() (*big.In return _DisputeGameFactory.Contract.GameCount(&_DisputeGameFactory.CallOpts) } -// GameImpls is a free data retrieval call binding the contract method 0xdfa162d3. +// GameImpls is a free data retrieval call binding the contract method 0x1b685b9e. // -// Solidity: function gameImpls(uint8 ) view returns(address) -func (_DisputeGameFactory *DisputeGameFactoryCaller) GameImpls(opts *bind.CallOpts, arg0 uint8) (common.Address, error) { +// Solidity: function gameImpls(uint32 ) view returns(address) +func (_DisputeGameFactory *DisputeGameFactoryCaller) GameImpls(opts *bind.CallOpts, arg0 uint32) (common.Address, error) { var out []interface{} err := _DisputeGameFactory.contract.Call(opts, &out, "gameImpls", arg0) @@ -299,24 +339,24 @@ func (_DisputeGameFactory *DisputeGameFactoryCaller) GameImpls(opts *bind.CallOp } -// GameImpls is a free data retrieval call binding the contract method 0xdfa162d3. +// GameImpls is a free data retrieval call binding the contract method 0x1b685b9e. // -// Solidity: function gameImpls(uint8 ) view returns(address) -func (_DisputeGameFactory *DisputeGameFactorySession) GameImpls(arg0 uint8) (common.Address, error) { +// Solidity: function gameImpls(uint32 ) view returns(address) +func (_DisputeGameFactory *DisputeGameFactorySession) GameImpls(arg0 uint32) (common.Address, error) { return _DisputeGameFactory.Contract.GameImpls(&_DisputeGameFactory.CallOpts, arg0) } -// GameImpls is a free data retrieval call binding the contract method 0xdfa162d3. +// GameImpls is a free data retrieval call binding the contract method 0x1b685b9e. // -// Solidity: function gameImpls(uint8 ) view returns(address) -func (_DisputeGameFactory *DisputeGameFactoryCallerSession) GameImpls(arg0 uint8) (common.Address, error) { +// Solidity: function gameImpls(uint32 ) view returns(address) +func (_DisputeGameFactory *DisputeGameFactoryCallerSession) GameImpls(arg0 uint32) (common.Address, error) { return _DisputeGameFactory.Contract.GameImpls(&_DisputeGameFactory.CallOpts, arg0) } -// Games is a free data retrieval call binding the contract method 0xc49d5271. +// Games is a free data retrieval call binding the contract method 0x5f0150cb. // -// Solidity: function games(uint8 _gameType, bytes32 _rootClaim, bytes _extraData) view returns(address proxy_, uint64 timestamp_) -func (_DisputeGameFactory *DisputeGameFactoryCaller) Games(opts *bind.CallOpts, _gameType uint8, _rootClaim [32]byte, _extraData []byte) (struct { +// Solidity: function games(uint32 _gameType, bytes32 _rootClaim, bytes _extraData) view returns(address proxy_, uint64 timestamp_) +func (_DisputeGameFactory *DisputeGameFactoryCaller) Games(opts *bind.CallOpts, _gameType uint32, _rootClaim [32]byte, _extraData []byte) (struct { Proxy common.Address Timestamp uint64 }, error) { @@ -338,30 +378,30 @@ func (_DisputeGameFactory *DisputeGameFactoryCaller) Games(opts *bind.CallOpts, } -// Games is a free data retrieval call binding the contract method 0xc49d5271. +// Games is a free data retrieval call binding the contract method 0x5f0150cb. // -// Solidity: function games(uint8 _gameType, bytes32 _rootClaim, bytes _extraData) view returns(address proxy_, uint64 timestamp_) -func (_DisputeGameFactory *DisputeGameFactorySession) Games(_gameType uint8, _rootClaim [32]byte, _extraData []byte) (struct { +// Solidity: function games(uint32 _gameType, bytes32 _rootClaim, bytes _extraData) view returns(address proxy_, uint64 timestamp_) +func (_DisputeGameFactory *DisputeGameFactorySession) Games(_gameType uint32, _rootClaim [32]byte, _extraData []byte) (struct { Proxy common.Address Timestamp uint64 }, error) { return _DisputeGameFactory.Contract.Games(&_DisputeGameFactory.CallOpts, _gameType, _rootClaim, _extraData) } -// Games is a free data retrieval call binding the contract method 0xc49d5271. +// Games is a free data retrieval call binding the contract method 0x5f0150cb. // -// Solidity: function games(uint8 _gameType, bytes32 _rootClaim, bytes _extraData) view returns(address proxy_, uint64 timestamp_) -func (_DisputeGameFactory *DisputeGameFactoryCallerSession) Games(_gameType uint8, _rootClaim [32]byte, _extraData []byte) (struct { +// Solidity: function games(uint32 _gameType, bytes32 _rootClaim, bytes _extraData) view returns(address proxy_, uint64 timestamp_) +func (_DisputeGameFactory *DisputeGameFactoryCallerSession) Games(_gameType uint32, _rootClaim [32]byte, _extraData []byte) (struct { Proxy common.Address Timestamp uint64 }, error) { return _DisputeGameFactory.Contract.Games(&_DisputeGameFactory.CallOpts, _gameType, _rootClaim, _extraData) } -// GetGameUUID is a free data retrieval call binding the contract method 0x26daafbe. +// GetGameUUID is a free data retrieval call binding the contract method 0x96cd9720. // -// Solidity: function getGameUUID(uint8 _gameType, bytes32 _rootClaim, bytes _extraData) pure returns(bytes32 uuid_) -func (_DisputeGameFactory *DisputeGameFactoryCaller) GetGameUUID(opts *bind.CallOpts, _gameType uint8, _rootClaim [32]byte, _extraData []byte) ([32]byte, error) { +// Solidity: function getGameUUID(uint32 _gameType, bytes32 _rootClaim, bytes _extraData) pure returns(bytes32 uuid_) +func (_DisputeGameFactory *DisputeGameFactoryCaller) GetGameUUID(opts *bind.CallOpts, _gameType uint32, _rootClaim [32]byte, _extraData []byte) ([32]byte, error) { var out []interface{} err := _DisputeGameFactory.contract.Call(opts, &out, "getGameUUID", _gameType, _rootClaim, _extraData) @@ -375,20 +415,51 @@ func (_DisputeGameFactory *DisputeGameFactoryCaller) GetGameUUID(opts *bind.Call } -// GetGameUUID is a free data retrieval call binding the contract method 0x26daafbe. +// GetGameUUID is a free data retrieval call binding the contract method 0x96cd9720. // -// Solidity: function getGameUUID(uint8 _gameType, bytes32 _rootClaim, bytes _extraData) pure returns(bytes32 uuid_) -func (_DisputeGameFactory *DisputeGameFactorySession) GetGameUUID(_gameType uint8, _rootClaim [32]byte, _extraData []byte) ([32]byte, error) { +// Solidity: function getGameUUID(uint32 _gameType, bytes32 _rootClaim, bytes _extraData) pure returns(bytes32 uuid_) +func (_DisputeGameFactory *DisputeGameFactorySession) GetGameUUID(_gameType uint32, _rootClaim [32]byte, _extraData []byte) ([32]byte, error) { return _DisputeGameFactory.Contract.GetGameUUID(&_DisputeGameFactory.CallOpts, _gameType, _rootClaim, _extraData) } -// GetGameUUID is a free data retrieval call binding the contract method 0x26daafbe. +// GetGameUUID is a free data retrieval call binding the contract method 0x96cd9720. // -// Solidity: function getGameUUID(uint8 _gameType, bytes32 _rootClaim, bytes _extraData) pure returns(bytes32 uuid_) -func (_DisputeGameFactory *DisputeGameFactoryCallerSession) GetGameUUID(_gameType uint8, _rootClaim [32]byte, _extraData []byte) ([32]byte, error) { +// Solidity: function getGameUUID(uint32 _gameType, bytes32 _rootClaim, bytes _extraData) pure returns(bytes32 uuid_) +func (_DisputeGameFactory *DisputeGameFactoryCallerSession) GetGameUUID(_gameType uint32, _rootClaim [32]byte, _extraData []byte) ([32]byte, error) { return _DisputeGameFactory.Contract.GetGameUUID(&_DisputeGameFactory.CallOpts, _gameType, _rootClaim, _extraData) } +// InitBonds is a free data retrieval call binding the contract method 0x6593dc6e. +// +// Solidity: function initBonds(uint32 ) view returns(uint256) +func (_DisputeGameFactory *DisputeGameFactoryCaller) InitBonds(opts *bind.CallOpts, arg0 uint32) (*big.Int, error) { + var out []interface{} + err := _DisputeGameFactory.contract.Call(opts, &out, "initBonds", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// InitBonds is a free data retrieval call binding the contract method 0x6593dc6e. +// +// Solidity: function initBonds(uint32 ) view returns(uint256) +func (_DisputeGameFactory *DisputeGameFactorySession) InitBonds(arg0 uint32) (*big.Int, error) { + return _DisputeGameFactory.Contract.InitBonds(&_DisputeGameFactory.CallOpts, arg0) +} + +// InitBonds is a free data retrieval call binding the contract method 0x6593dc6e. +// +// Solidity: function initBonds(uint32 ) view returns(uint256) +func (_DisputeGameFactory *DisputeGameFactoryCallerSession) InitBonds(arg0 uint32) (*big.Int, error) { + return _DisputeGameFactory.Contract.InitBonds(&_DisputeGameFactory.CallOpts, arg0) +} + // Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // // Solidity: function owner() view returns(address) @@ -451,24 +522,24 @@ func (_DisputeGameFactory *DisputeGameFactoryCallerSession) Version() (string, e return _DisputeGameFactory.Contract.Version(&_DisputeGameFactory.CallOpts) } -// Create is a paid mutator transaction binding the contract method 0x3142e55e. +// Create is a paid mutator transaction binding the contract method 0x82ecf2f6. // -// Solidity: function create(uint8 _gameType, bytes32 _rootClaim, bytes _extraData) returns(address proxy_) -func (_DisputeGameFactory *DisputeGameFactoryTransactor) Create(opts *bind.TransactOpts, _gameType uint8, _rootClaim [32]byte, _extraData []byte) (*types.Transaction, error) { +// Solidity: function create(uint32 _gameType, bytes32 _rootClaim, bytes _extraData) payable returns(address proxy_) +func (_DisputeGameFactory *DisputeGameFactoryTransactor) Create(opts *bind.TransactOpts, _gameType uint32, _rootClaim [32]byte, _extraData []byte) (*types.Transaction, error) { return _DisputeGameFactory.contract.Transact(opts, "create", _gameType, _rootClaim, _extraData) } -// Create is a paid mutator transaction binding the contract method 0x3142e55e. +// Create is a paid mutator transaction binding the contract method 0x82ecf2f6. // -// Solidity: function create(uint8 _gameType, bytes32 _rootClaim, bytes _extraData) returns(address proxy_) -func (_DisputeGameFactory *DisputeGameFactorySession) Create(_gameType uint8, _rootClaim [32]byte, _extraData []byte) (*types.Transaction, error) { +// Solidity: function create(uint32 _gameType, bytes32 _rootClaim, bytes _extraData) payable returns(address proxy_) +func (_DisputeGameFactory *DisputeGameFactorySession) Create(_gameType uint32, _rootClaim [32]byte, _extraData []byte) (*types.Transaction, error) { return _DisputeGameFactory.Contract.Create(&_DisputeGameFactory.TransactOpts, _gameType, _rootClaim, _extraData) } -// Create is a paid mutator transaction binding the contract method 0x3142e55e. +// Create is a paid mutator transaction binding the contract method 0x82ecf2f6. // -// Solidity: function create(uint8 _gameType, bytes32 _rootClaim, bytes _extraData) returns(address proxy_) -func (_DisputeGameFactory *DisputeGameFactoryTransactorSession) Create(_gameType uint8, _rootClaim [32]byte, _extraData []byte) (*types.Transaction, error) { +// Solidity: function create(uint32 _gameType, bytes32 _rootClaim, bytes _extraData) payable returns(address proxy_) +func (_DisputeGameFactory *DisputeGameFactoryTransactorSession) Create(_gameType uint32, _rootClaim [32]byte, _extraData []byte) (*types.Transaction, error) { return _DisputeGameFactory.Contract.Create(&_DisputeGameFactory.TransactOpts, _gameType, _rootClaim, _extraData) } @@ -514,27 +585,48 @@ func (_DisputeGameFactory *DisputeGameFactoryTransactorSession) RenounceOwnershi return _DisputeGameFactory.Contract.RenounceOwnership(&_DisputeGameFactory.TransactOpts) } -// SetImplementation is a paid mutator transaction binding the contract method 0x45583b7a. +// SetImplementation is a paid mutator transaction binding the contract method 0x14f6b1a3. // -// Solidity: function setImplementation(uint8 _gameType, address _impl) returns() -func (_DisputeGameFactory *DisputeGameFactoryTransactor) SetImplementation(opts *bind.TransactOpts, _gameType uint8, _impl common.Address) (*types.Transaction, error) { +// Solidity: function setImplementation(uint32 _gameType, address _impl) returns() +func (_DisputeGameFactory *DisputeGameFactoryTransactor) SetImplementation(opts *bind.TransactOpts, _gameType uint32, _impl common.Address) (*types.Transaction, error) { return _DisputeGameFactory.contract.Transact(opts, "setImplementation", _gameType, _impl) } -// SetImplementation is a paid mutator transaction binding the contract method 0x45583b7a. +// SetImplementation is a paid mutator transaction binding the contract method 0x14f6b1a3. // -// Solidity: function setImplementation(uint8 _gameType, address _impl) returns() -func (_DisputeGameFactory *DisputeGameFactorySession) SetImplementation(_gameType uint8, _impl common.Address) (*types.Transaction, error) { +// Solidity: function setImplementation(uint32 _gameType, address _impl) returns() +func (_DisputeGameFactory *DisputeGameFactorySession) SetImplementation(_gameType uint32, _impl common.Address) (*types.Transaction, error) { return _DisputeGameFactory.Contract.SetImplementation(&_DisputeGameFactory.TransactOpts, _gameType, _impl) } -// SetImplementation is a paid mutator transaction binding the contract method 0x45583b7a. +// SetImplementation is a paid mutator transaction binding the contract method 0x14f6b1a3. // -// Solidity: function setImplementation(uint8 _gameType, address _impl) returns() -func (_DisputeGameFactory *DisputeGameFactoryTransactorSession) SetImplementation(_gameType uint8, _impl common.Address) (*types.Transaction, error) { +// Solidity: function setImplementation(uint32 _gameType, address _impl) returns() +func (_DisputeGameFactory *DisputeGameFactoryTransactorSession) SetImplementation(_gameType uint32, _impl common.Address) (*types.Transaction, error) { return _DisputeGameFactory.Contract.SetImplementation(&_DisputeGameFactory.TransactOpts, _gameType, _impl) } +// SetInitBond is a paid mutator transaction binding the contract method 0x1e334240. +// +// Solidity: function setInitBond(uint32 _gameType, uint256 _initBond) returns() +func (_DisputeGameFactory *DisputeGameFactoryTransactor) SetInitBond(opts *bind.TransactOpts, _gameType uint32, _initBond *big.Int) (*types.Transaction, error) { + return _DisputeGameFactory.contract.Transact(opts, "setInitBond", _gameType, _initBond) +} + +// SetInitBond is a paid mutator transaction binding the contract method 0x1e334240. +// +// Solidity: function setInitBond(uint32 _gameType, uint256 _initBond) returns() +func (_DisputeGameFactory *DisputeGameFactorySession) SetInitBond(_gameType uint32, _initBond *big.Int) (*types.Transaction, error) { + return _DisputeGameFactory.Contract.SetInitBond(&_DisputeGameFactory.TransactOpts, _gameType, _initBond) +} + +// SetInitBond is a paid mutator transaction binding the contract method 0x1e334240. +// +// Solidity: function setInitBond(uint32 _gameType, uint256 _initBond) returns() +func (_DisputeGameFactory *DisputeGameFactoryTransactorSession) SetInitBond(_gameType uint32, _initBond *big.Int) (*types.Transaction, error) { + return _DisputeGameFactory.Contract.SetInitBond(&_DisputeGameFactory.TransactOpts, _gameType, _initBond) +} + // TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // // Solidity: function transferOwnership(address newOwner) returns() @@ -626,15 +718,15 @@ func (it *DisputeGameFactoryDisputeGameCreatedIterator) Close() error { // DisputeGameFactoryDisputeGameCreated represents a DisputeGameCreated event raised by the DisputeGameFactory contract. type DisputeGameFactoryDisputeGameCreated struct { DisputeProxy common.Address - GameType uint8 + GameType uint32 RootClaim [32]byte Raw types.Log // Blockchain specific contextual infos } -// FilterDisputeGameCreated is a free log retrieval operation binding the contract event 0xfad0599ff449d8d9685eadecca8cb9e00924c5fd8367c1c09469824939e1ffec. +// FilterDisputeGameCreated is a free log retrieval operation binding the contract event 0x5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e35. // -// Solidity: event DisputeGameCreated(address indexed disputeProxy, uint8 indexed gameType, bytes32 indexed rootClaim) -func (_DisputeGameFactory *DisputeGameFactoryFilterer) FilterDisputeGameCreated(opts *bind.FilterOpts, disputeProxy []common.Address, gameType []uint8, rootClaim [][32]byte) (*DisputeGameFactoryDisputeGameCreatedIterator, error) { +// Solidity: event DisputeGameCreated(address indexed disputeProxy, uint32 indexed gameType, bytes32 indexed rootClaim) +func (_DisputeGameFactory *DisputeGameFactoryFilterer) FilterDisputeGameCreated(opts *bind.FilterOpts, disputeProxy []common.Address, gameType []uint32, rootClaim [][32]byte) (*DisputeGameFactoryDisputeGameCreatedIterator, error) { var disputeProxyRule []interface{} for _, disputeProxyItem := range disputeProxy { @@ -656,10 +748,10 @@ func (_DisputeGameFactory *DisputeGameFactoryFilterer) FilterDisputeGameCreated( return &DisputeGameFactoryDisputeGameCreatedIterator{contract: _DisputeGameFactory.contract, event: "DisputeGameCreated", logs: logs, sub: sub}, nil } -// WatchDisputeGameCreated is a free log subscription operation binding the contract event 0xfad0599ff449d8d9685eadecca8cb9e00924c5fd8367c1c09469824939e1ffec. +// WatchDisputeGameCreated is a free log subscription operation binding the contract event 0x5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e35. // -// Solidity: event DisputeGameCreated(address indexed disputeProxy, uint8 indexed gameType, bytes32 indexed rootClaim) -func (_DisputeGameFactory *DisputeGameFactoryFilterer) WatchDisputeGameCreated(opts *bind.WatchOpts, sink chan<- *DisputeGameFactoryDisputeGameCreated, disputeProxy []common.Address, gameType []uint8, rootClaim [][32]byte) (event.Subscription, error) { +// Solidity: event DisputeGameCreated(address indexed disputeProxy, uint32 indexed gameType, bytes32 indexed rootClaim) +func (_DisputeGameFactory *DisputeGameFactoryFilterer) WatchDisputeGameCreated(opts *bind.WatchOpts, sink chan<- *DisputeGameFactoryDisputeGameCreated, disputeProxy []common.Address, gameType []uint32, rootClaim [][32]byte) (event.Subscription, error) { var disputeProxyRule []interface{} for _, disputeProxyItem := range disputeProxy { @@ -706,9 +798,9 @@ func (_DisputeGameFactory *DisputeGameFactoryFilterer) WatchDisputeGameCreated(o }), nil } -// ParseDisputeGameCreated is a log parse operation binding the contract event 0xfad0599ff449d8d9685eadecca8cb9e00924c5fd8367c1c09469824939e1ffec. +// ParseDisputeGameCreated is a log parse operation binding the contract event 0x5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e35. // -// Solidity: event DisputeGameCreated(address indexed disputeProxy, uint8 indexed gameType, bytes32 indexed rootClaim) +// Solidity: event DisputeGameCreated(address indexed disputeProxy, uint32 indexed gameType, bytes32 indexed rootClaim) func (_DisputeGameFactory *DisputeGameFactoryFilterer) ParseDisputeGameCreated(log types.Log) (*DisputeGameFactoryDisputeGameCreated, error) { event := new(DisputeGameFactoryDisputeGameCreated) if err := _DisputeGameFactory.contract.UnpackLog(event, "DisputeGameCreated", log); err != nil { @@ -788,14 +880,14 @@ func (it *DisputeGameFactoryImplementationSetIterator) Close() error { // DisputeGameFactoryImplementationSet represents a ImplementationSet event raised by the DisputeGameFactory contract. type DisputeGameFactoryImplementationSet struct { Impl common.Address - GameType uint8 + GameType uint32 Raw types.Log // Blockchain specific contextual infos } -// FilterImplementationSet is a free log retrieval operation binding the contract event 0x623713f72f6e427a8044bb8b3bd6834357cf285decbaa21bcc73c1d0632c4d84. +// FilterImplementationSet is a free log retrieval operation binding the contract event 0xff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de. // -// Solidity: event ImplementationSet(address indexed impl, uint8 indexed gameType) -func (_DisputeGameFactory *DisputeGameFactoryFilterer) FilterImplementationSet(opts *bind.FilterOpts, impl []common.Address, gameType []uint8) (*DisputeGameFactoryImplementationSetIterator, error) { +// Solidity: event ImplementationSet(address indexed impl, uint32 indexed gameType) +func (_DisputeGameFactory *DisputeGameFactoryFilterer) FilterImplementationSet(opts *bind.FilterOpts, impl []common.Address, gameType []uint32) (*DisputeGameFactoryImplementationSetIterator, error) { var implRule []interface{} for _, implItem := range impl { @@ -813,10 +905,10 @@ func (_DisputeGameFactory *DisputeGameFactoryFilterer) FilterImplementationSet(o return &DisputeGameFactoryImplementationSetIterator{contract: _DisputeGameFactory.contract, event: "ImplementationSet", logs: logs, sub: sub}, nil } -// WatchImplementationSet is a free log subscription operation binding the contract event 0x623713f72f6e427a8044bb8b3bd6834357cf285decbaa21bcc73c1d0632c4d84. +// WatchImplementationSet is a free log subscription operation binding the contract event 0xff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de. // -// Solidity: event ImplementationSet(address indexed impl, uint8 indexed gameType) -func (_DisputeGameFactory *DisputeGameFactoryFilterer) WatchImplementationSet(opts *bind.WatchOpts, sink chan<- *DisputeGameFactoryImplementationSet, impl []common.Address, gameType []uint8) (event.Subscription, error) { +// Solidity: event ImplementationSet(address indexed impl, uint32 indexed gameType) +func (_DisputeGameFactory *DisputeGameFactoryFilterer) WatchImplementationSet(opts *bind.WatchOpts, sink chan<- *DisputeGameFactoryImplementationSet, impl []common.Address, gameType []uint32) (event.Subscription, error) { var implRule []interface{} for _, implItem := range impl { @@ -859,9 +951,9 @@ func (_DisputeGameFactory *DisputeGameFactoryFilterer) WatchImplementationSet(op }), nil } -// ParseImplementationSet is a log parse operation binding the contract event 0x623713f72f6e427a8044bb8b3bd6834357cf285decbaa21bcc73c1d0632c4d84. +// ParseImplementationSet is a log parse operation binding the contract event 0xff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de. // -// Solidity: event ImplementationSet(address indexed impl, uint8 indexed gameType) +// Solidity: event ImplementationSet(address indexed impl, uint32 indexed gameType) func (_DisputeGameFactory *DisputeGameFactoryFilterer) ParseImplementationSet(log types.Log) (*DisputeGameFactoryImplementationSet, error) { event := new(DisputeGameFactoryImplementationSet) if err := _DisputeGameFactory.contract.UnpackLog(event, "ImplementationSet", log); err != nil { @@ -871,6 +963,159 @@ func (_DisputeGameFactory *DisputeGameFactoryFilterer) ParseImplementationSet(lo return event, nil } +// DisputeGameFactoryInitBondUpdatedIterator is returned from FilterInitBondUpdated and is used to iterate over the raw logs and unpacked data for InitBondUpdated events raised by the DisputeGameFactory contract. +type DisputeGameFactoryInitBondUpdatedIterator struct { + Event *DisputeGameFactoryInitBondUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DisputeGameFactoryInitBondUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DisputeGameFactoryInitBondUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DisputeGameFactoryInitBondUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DisputeGameFactoryInitBondUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DisputeGameFactoryInitBondUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// DisputeGameFactoryInitBondUpdated represents a InitBondUpdated event raised by the DisputeGameFactory contract. +type DisputeGameFactoryInitBondUpdated struct { + GameType uint32 + NewBond *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitBondUpdated is a free log retrieval operation binding the contract event 0x74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca. +// +// Solidity: event InitBondUpdated(uint32 indexed gameType, uint256 indexed newBond) +func (_DisputeGameFactory *DisputeGameFactoryFilterer) FilterInitBondUpdated(opts *bind.FilterOpts, gameType []uint32, newBond []*big.Int) (*DisputeGameFactoryInitBondUpdatedIterator, error) { + + var gameTypeRule []interface{} + for _, gameTypeItem := range gameType { + gameTypeRule = append(gameTypeRule, gameTypeItem) + } + var newBondRule []interface{} + for _, newBondItem := range newBond { + newBondRule = append(newBondRule, newBondItem) + } + + logs, sub, err := _DisputeGameFactory.contract.FilterLogs(opts, "InitBondUpdated", gameTypeRule, newBondRule) + if err != nil { + return nil, err + } + return &DisputeGameFactoryInitBondUpdatedIterator{contract: _DisputeGameFactory.contract, event: "InitBondUpdated", logs: logs, sub: sub}, nil +} + +// WatchInitBondUpdated is a free log subscription operation binding the contract event 0x74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca. +// +// Solidity: event InitBondUpdated(uint32 indexed gameType, uint256 indexed newBond) +func (_DisputeGameFactory *DisputeGameFactoryFilterer) WatchInitBondUpdated(opts *bind.WatchOpts, sink chan<- *DisputeGameFactoryInitBondUpdated, gameType []uint32, newBond []*big.Int) (event.Subscription, error) { + + var gameTypeRule []interface{} + for _, gameTypeItem := range gameType { + gameTypeRule = append(gameTypeRule, gameTypeItem) + } + var newBondRule []interface{} + for _, newBondItem := range newBond { + newBondRule = append(newBondRule, newBondItem) + } + + logs, sub, err := _DisputeGameFactory.contract.WatchLogs(opts, "InitBondUpdated", gameTypeRule, newBondRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DisputeGameFactoryInitBondUpdated) + if err := _DisputeGameFactory.contract.UnpackLog(event, "InitBondUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitBondUpdated is a log parse operation binding the contract event 0x74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca. +// +// Solidity: event InitBondUpdated(uint32 indexed gameType, uint256 indexed newBond) +func (_DisputeGameFactory *DisputeGameFactoryFilterer) ParseInitBondUpdated(log types.Log) (*DisputeGameFactoryInitBondUpdated, error) { + event := new(DisputeGameFactoryInitBondUpdated) + if err := _DisputeGameFactory.contract.UnpackLog(event, "InitBondUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + // DisputeGameFactoryInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the DisputeGameFactory contract. type DisputeGameFactoryInitializedIterator struct { Event *DisputeGameFactoryInitialized // Event containing the contract specifics and raw log diff --git a/op-bindings/bindings/disputegamefactory_more.go b/op-bindings/bindings/disputegamefactory_more.go index 6869e051ef16..2b84757b3efd 100644 --- a/op-bindings/bindings/disputegamefactory_more.go +++ b/op-bindings/bindings/disputegamefactory_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const DisputeGameFactoryStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1003,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1005,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"gameImpls\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_mapping(t_userDefinedValueType(GameType)1010,t_contract(IDisputeGame)1008)\"},{\"astId\":1006,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"_disputeGames\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_mapping(t_userDefinedValueType(Hash)1011,t_userDefinedValueType(GameId)1009)\"},{\"astId\":1007,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"_disputeGameList\",\"offset\":0,\"slot\":\"103\",\"type\":\"t_array(t_userDefinedValueType(GameId)1009)dyn_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_array(t_userDefinedValueType(GameId)1009)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"GameId[]\",\"numberOfBytes\":\"32\",\"base\":\"t_userDefinedValueType(GameId)1009\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(IDisputeGame)1008\":{\"encoding\":\"inplace\",\"label\":\"contract IDisputeGame\",\"numberOfBytes\":\"20\"},\"t_mapping(t_userDefinedValueType(GameType)1010,t_contract(IDisputeGame)1008)\":{\"encoding\":\"mapping\",\"label\":\"mapping(GameType =\u003e contract IDisputeGame)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(GameType)1010\",\"value\":\"t_contract(IDisputeGame)1008\"},\"t_mapping(t_userDefinedValueType(Hash)1011,t_userDefinedValueType(GameId)1009)\":{\"encoding\":\"mapping\",\"label\":\"mapping(Hash =\u003e GameId)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(Hash)1011\",\"value\":\"t_userDefinedValueType(GameId)1009\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"},\"t_userDefinedValueType(GameId)1009\":{\"encoding\":\"inplace\",\"label\":\"GameId\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(GameType)1010\":{\"encoding\":\"inplace\",\"label\":\"GameType\",\"numberOfBytes\":\"1\"},\"t_userDefinedValueType(Hash)1011\":{\"encoding\":\"inplace\",\"label\":\"Hash\",\"numberOfBytes\":\"32\"}}}" +const DisputeGameFactoryStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1003,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1005,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"gameImpls\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_mapping(t_userDefinedValueType(GameType)1011,t_contract(IDisputeGame)1009)\"},{\"astId\":1006,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"initBonds\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_mapping(t_userDefinedValueType(GameType)1011,t_uint256)\"},{\"astId\":1007,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"_disputeGames\",\"offset\":0,\"slot\":\"103\",\"type\":\"t_mapping(t_userDefinedValueType(Hash)1012,t_userDefinedValueType(GameId)1010)\"},{\"astId\":1008,\"contract\":\"src/dispute/DisputeGameFactory.sol:DisputeGameFactory\",\"label\":\"_disputeGameList\",\"offset\":0,\"slot\":\"104\",\"type\":\"t_array(t_userDefinedValueType(GameId)1010)dyn_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_array(t_userDefinedValueType(GameId)1010)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"GameId[]\",\"numberOfBytes\":\"32\",\"base\":\"t_userDefinedValueType(GameId)1010\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(IDisputeGame)1009\":{\"encoding\":\"inplace\",\"label\":\"contract IDisputeGame\",\"numberOfBytes\":\"20\"},\"t_mapping(t_userDefinedValueType(GameType)1011,t_contract(IDisputeGame)1009)\":{\"encoding\":\"mapping\",\"label\":\"mapping(GameType =\u003e contract IDisputeGame)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(GameType)1011\",\"value\":\"t_contract(IDisputeGame)1009\"},\"t_mapping(t_userDefinedValueType(GameType)1011,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(GameType =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(GameType)1011\",\"value\":\"t_uint256\"},\"t_mapping(t_userDefinedValueType(Hash)1012,t_userDefinedValueType(GameId)1010)\":{\"encoding\":\"mapping\",\"label\":\"mapping(Hash =\u003e GameId)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(Hash)1012\",\"value\":\"t_userDefinedValueType(GameId)1010\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"},\"t_userDefinedValueType(GameId)1010\":{\"encoding\":\"inplace\",\"label\":\"GameId\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(GameType)1011\":{\"encoding\":\"inplace\",\"label\":\"GameType\",\"numberOfBytes\":\"4\"},\"t_userDefinedValueType(Hash)1012\":{\"encoding\":\"inplace\",\"label\":\"Hash\",\"numberOfBytes\":\"32\"}}}" var DisputeGameFactoryStorageLayout = new(solc.StorageLayout) -var DisputeGameFactoryDeployedBin = "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063c4d66de81161005b578063c4d66de8146102e8578063dfa162d3146102fb578063f2fde38b1461033157600080fd5b80638da5cb5b14610231578063bb8aa1fc1461024f578063c49d5271146102a057600080fd5b80634d1975b4116100b25780634d1975b4146101d857806354fd4d50146101e0578063715018a61461022957600080fd5b806326daafbe146100d95780633142e55e1461018b57806345583b7a146101c3575b600080fd5b6101786100e7366004610d45565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0810180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0830180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086018051988652968352606087529451609f0190941683209190925291905291905290565b6040519081526020015b60405180910390f35b61019e610199366004610e2e565b610344565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610182565b6101d66101d1366004610ed7565b6105a6565b005b606754610178565b61021c6040518060400160405280600581526020017f302e302e3600000000000000000000000000000000000000000000000000000081525081565b6040516101829190610f0e565b6101d661062d565b60335473ffffffffffffffffffffffffffffffffffffffff1661019e565b61026261025d366004610f81565b610641565b6040805160ff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610182565b6102b36102ae366004610e2e565b6106a3565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610182565b6101d66102f6366004610f9a565b61072b565b61019e610309366004610fbe565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6101d661033f366004610f9a565b6108c7565b60ff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806103ae576040517f44265d6f00000000000000000000000000000000000000000000000000000000815260ff871660048201526024015b60405180910390fd5b6104118585856040516020016103c693929190610fd9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff83169061099a565b91508173ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561045b57600080fd5b505af115801561046f573d6000803e3d6000fd5b5050505060006104b6878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506100e792505050565b60008181526066602052604090205490915015610502576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016103a5565b60004260b81b60f889901b178417600083815260666020526040808220839055606780546001810182559083527f9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae0183905551919250889160ff8b169173ffffffffffffffffffffffffffffffffffffffff8816917ffad0599ff449d8d9685eadecca8cb9e00924c5fd8367c1c09469824939e1ffec9190a4505050949350505050565b6105ae610ace565b60ff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917f623713f72f6e427a8044bb8b3bd6834357cf285decbaa21bcc73c1d0632c4d8491a35050565b610635610ace565b61063f6000610b4f565b565b60008060006106966067858154811061065c5761065c610ff3565b906000526020600020015460f881901c9167ffffffffffffffff60b883901c169173ffffffffffffffffffffffffffffffffffffffff1690565b9196909550909350915050565b60008060006106e9878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506100e792505050565b60009081526066602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860b89190911c67ffffffffffffffff16975095505050505050565b600054610100900460ff161580801561074b5750600054600160ff909116105b806107655750303b158015610765575060005460ff166001145b6107f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016103a5565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561084f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610857610bc6565b61086082610b4f565b80156108c357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6108cf610ace565b73ffffffffffffffffffffffffffffffffffffffff8116610972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a5565b61097b81610b4f565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60006002825101603f8101600a81036040518360581b8260e81b177f6100003d81600a3d39f3363d3d373d3d3d3d610000806035363936013d7300001781528660601b601e8201527f5af43d3d93803e603357fd5bf300000000000000000000000000000000000000603282015285519150603f8101602087015b60208410610a5257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09093019260209182019101610a15565b517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602085900360031b1b16815260f085901b9083015282816000f0945084610abf577febfef1880000000000000000000000000000000000000000000000000000000060005260206000fd5b90910160405250909392505050565b60335473ffffffffffffffffffffffffffffffffffffffff16331461063f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a5565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610c5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016103a5565b61063f600054610100900460ff16610cf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016103a5565b61063f33610b4f565b803560ff81168114610d1157600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080600060608486031215610d5a57600080fd5b610d6384610d00565b925060208401359150604084013567ffffffffffffffff80821115610d8757600080fd5b818601915086601f830112610d9b57600080fd5b813581811115610dad57610dad610d16565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610df357610df3610d16565b81604052828152896020848701011115610e0c57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60008060008060608587031215610e4457600080fd5b610e4d85610d00565b935060208501359250604085013567ffffffffffffffff80821115610e7157600080fd5b818701915087601f830112610e8557600080fd5b813581811115610e9457600080fd5b886020828501011115610ea657600080fd5b95989497505060200194505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461097b57600080fd5b60008060408385031215610eea57600080fd5b610ef383610d00565b91506020830135610f0381610eb5565b809150509250929050565b600060208083528351808285015260005b81811015610f3b57858101830151858201604001528201610f1f565b81811115610f4d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600060208284031215610f9357600080fd5b5035919050565b600060208284031215610fac57600080fd5b8135610fb781610eb5565b9392505050565b600060208284031215610fd057600080fd5b610fb782610d00565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a" +var DisputeGameFactoryDeployedBin = "0x6080604052600436106100e85760003560e01c80636593dc6e1161008a57806396cd97201161005957806396cd972014610313578063bb8aa1fc14610333578063c4d66de814610394578063f2fde38b146103b457600080fd5b80636593dc6e14610293578063715018a6146102c057806382ecf2f6146102d55780638da5cb5b146102e857600080fd5b8063254bd683116100c6578063254bd6831461019c5780634d1975b4146101c957806354fd4d50146101e85780635f0150cb1461023e57600080fd5b806314f6b1a3146100ed5780631b685b9e1461010f5780631e3342401461017c575b600080fd5b3480156100f957600080fd5b5061010d610108366004611099565b6103d4565b005b34801561011b57600080fd5b5061015261012a3660046110d0565b60656020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061010d6101973660046110eb565b61045e565b3480156101a857600080fd5b506101bc6101b7366004611115565b6104aa565b60405161017391906111c2565b3480156101d557600080fd5b506068545b604051908152602001610173565b3480156101f457600080fd5b506102316040518060400160405280600581526020017f302e322e3000000000000000000000000000000000000000000000000000000081525081565b604051610173919061127f565b34801561024a57600080fd5b5061025e610259366004611292565b6106ee565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff909116602083015201610173565b34801561029f57600080fd5b506101da6102ae3660046110d0565b60666020526000908152604090205481565b3480156102cc57600080fd5b5061010d610741565b6101526102e3366004611292565b610755565b3480156102f457600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610152565b34801561031f57600080fd5b506101da61032e366004611292565b6109ee565b34801561033f57600080fd5b5061035361034e366004611319565b610a27565b6040805163ffffffff909416845267ffffffffffffffff909216602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610173565b3480156103a057600080fd5b5061010d6103af366004611332565b610a89565b3480156103c057600080fd5b5061010d6103cf366004611332565b610c25565b6103dc610cf8565b63ffffffff821660008181526065602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155905190917fff513d80e2c7fa487608f70a618dfbc0cf415699dc69588c747e8c71566c88de91a35050565b610466610cf8565b63ffffffff8216600081815260666020526040808220849055518392917f74d6665c4b26d5596a5aa13d3014e0c06af4d322075a797f87b03cd4c5bc91ca91a35050565b606854606090831015806104bc575081155b6106e7575060408051600583901b8101602001909152825b8381116106e5576000606882815481106104f0576104f061134f565b600091825260209091200154905060e081901c67ffffffffffffffff60a083901c1673ffffffffffffffffffffffffffffffffffffffff831660ff808a16908416036106b6576001865101865260008173ffffffffffffffffffffffffffffffffffffffff1663609d33346040518163ffffffff1660e01b8152600401600060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d091908101906113ad565b905060008273ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106439190611478565b90506040518060a001604052808881526020018781526020018567ffffffffffffffff168152602001828152602001838152508860018a516106859190611491565b815181106106955761069561134f565b6020026020010181905250888851106106b3575050505050506106e5565b50505b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191506104d49050565b505b9392505050565b60008060006106ff878787876109ee565b60009081526067602052604090205473ffffffffffffffffffffffffffffffffffffffff81169860a09190911c67ffffffffffffffff16975095505050505050565b610749610cf8565b6107536000610d79565b565b63ffffffff841660009081526065602052604081205473ffffffffffffffffffffffffffffffffffffffff16806107c5576040517f031c6de400000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526024015b60405180910390fd5b63ffffffff8616600090815260666020526040902054341015610814576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610821600143611491565b4090506108898682878760405160200161083e94939291906114cf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905273ffffffffffffffffffffffffffffffffffffffff841690610df0565b92508273ffffffffffffffffffffffffffffffffffffffff16638129fc1c346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156108d357600080fd5b505af11580156108e7573d6000803e3d6000fd5b505050505060006108fa888888886109ee565b60008181526067602052604090205490915015610946576040517f014f6fe5000000000000000000000000000000000000000000000000000000008152600481018290526024016107bc565b60004260a01b60e08a901b178517600083815260676020526040808220839055606880546001810182559083527fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530183905551919250899163ffffffff8c169173ffffffffffffffffffffffffffffffffffffffff8916917f5b565efe82411da98814f356d0e7bcb8f0219b8d970307c5afb4a6903a8b2e359190a450505050949350505050565b600084848484604051602001610a0794939291906114f0565b604051602081830303815290604052805190602001209050949350505050565b6000806000610a7c60688581548110610a4257610a4261134f565b906000526020600020015460e081901c9160a082901c67ffffffffffffffff169173ffffffffffffffffffffffffffffffffffffffff1690565b9196909550909350915050565b600054610100900460ff1615808015610aa95750600054600160ff909116105b80610ac35750303b158015610ac3575060005460ff166001145b610b4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107bc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bad57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610bb5610f24565b610bbe82610d79565b8015610c2157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610c2d610cf8565b73ffffffffffffffffffffffffffffffffffffffff8116610cd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107bc565b610cd981610d79565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff163314610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bc565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006002825101603f8101600a81036040518360581b8260e81b177f6100003d81600a3d39f3363d3d373d3d3d3d610000806035363936013d7300001781528660601b601e8201527f5af43d3d93803e603357fd5bf300000000000000000000000000000000000000603282015285519150603f8101602087015b60208410610ea857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09093019260209182019101610e6b565b517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602085900360031b1b16815260f085901b9083015282816000f0945084610f15577febfef1880000000000000000000000000000000000000000000000000000000060005260206000fd5b90910160405250909392505050565b600054610100900460ff16610fbb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b610753600054610100900460ff16611055576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107bc565b61075333610d79565b803563ffffffff8116811461107257600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610cd957600080fd5b600080604083850312156110ac57600080fd5b6110b58361105e565b915060208301356110c581611077565b809150509250929050565b6000602082840312156110e257600080fd5b6106e78261105e565b600080604083850312156110fe57600080fd5b6111078361105e565b946020939093013593505050565b60008060006060848603121561112a57600080fd5b6111338461105e565b95602085013595506040909401359392505050565b60005b8381101561116357818101518382015260200161114b565b83811115611172576000848401525b50505050565b60008151808452611190816020860160208601611148565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611271578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001855281518051845287810151888501528681015167ffffffffffffffff16878501526060808201519085015260809081015160a09185018290529061125d81860183611178565b9689019694505050908601906001016111e9565b509098975050505050505050565b6020815260006106e76020830184611178565b600080600080606085870312156112a857600080fd5b6112b18561105e565b935060208501359250604085013567ffffffffffffffff808211156112d557600080fd5b818701915087601f8301126112e957600080fd5b8135818111156112f857600080fd5b88602082850101111561130a57600080fd5b95989497505060200194505050565b60006020828403121561132b57600080fd5b5035919050565b60006020828403121561134457600080fd5b81356106e781611077565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156113bf57600080fd5b815167ffffffffffffffff808211156113d757600080fd5b818401915084601f8301126113eb57600080fd5b8151818111156113fd576113fd61137e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156114435761144361137e565b8160405282815287602084870101111561145c57600080fd5b61146d836020830160208801611148565b979650505050505050565b60006020828403121561148a57600080fd5b5051919050565b6000828210156114ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500390565b84815283602082015281836040830137600091016040019081529392505050565b63ffffffff8516815283602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101939250505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(DisputeGameFactoryStorageLayoutJSON), DisputeGameFactoryStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["DisputeGameFactory"] = DisputeGameFactoryStorageLayout deployedBytecodes["DisputeGameFactory"] = DisputeGameFactoryDeployedBin + immutableReferences["DisputeGameFactory"] = false } diff --git a/op-bindings/bindings/eas.go b/op-bindings/bindings/eas.go index 623166d4ec63..ff8141960bce 100644 --- a/op-bindings/bindings/eas.go +++ b/op-bindings/bindings/eas.go @@ -127,8 +127,8 @@ type Signature struct { // EASMetaData contains all meta data concerning the EAS contract. var EASMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessDenied\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyRevoked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyRevokedOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyTimestamped\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExpirationTime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidOffset\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRevocation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRevocations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSchema\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidVerifier\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Irrevocable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotPayable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongSchema\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"schemaUID\",\"type\":\"bytes32\"}],\"name\":\"Attested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNonce\",\"type\":\"uint256\"}],\"name\":\"NonceIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"schemaUID\",\"type\":\"bytes32\"}],\"name\":\"Revoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"}],\"name\":\"RevokedOffchain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"}],\"name\":\"Timestamped\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structAttestationRequestData\",\"name\":\"data\",\"type\":\"tuple\"}],\"internalType\":\"structAttestationRequest\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"attest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structAttestationRequestData\",\"name\":\"data\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature\",\"name\":\"signature\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"deadline\",\"type\":\"uint64\"}],\"internalType\":\"structDelegatedAttestationRequest\",\"name\":\"delegatedRequest\",\"type\":\"tuple\"}],\"name\":\"attestByDelegation\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAttestTypeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"name\":\"getAttestation\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"time\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"revocationTime\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structAttestation\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDomainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"name\":\"getRevokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRevokeTypeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSchemaRegistry\",\"outputs\":[{\"internalType\":\"contractISchemaRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"name\":\"getTimestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newNonce\",\"type\":\"uint256\"}],\"name\":\"increaseNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"name\":\"isAttestationValid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structAttestationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\"}],\"internalType\":\"structMultiAttestationRequest[]\",\"name\":\"multiRequests\",\"type\":\"tuple[]\"}],\"name\":\"multiAttest\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structAttestationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"deadline\",\"type\":\"uint64\"}],\"internalType\":\"structMultiDelegatedAttestationRequest[]\",\"name\":\"multiDelegatedRequests\",\"type\":\"tuple[]\"}],\"name\":\"multiAttestByDelegation\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structRevocationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\"}],\"internalType\":\"structMultiRevocationRequest[]\",\"name\":\"multiRequests\",\"type\":\"tuple[]\"}],\"name\":\"multiRevoke\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structRevocationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"deadline\",\"type\":\"uint64\"}],\"internalType\":\"structMultiDelegatedRevocationRequest[]\",\"name\":\"multiDelegatedRequests\",\"type\":\"tuple[]\"}],\"name\":\"multiRevokeByDelegation\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"data\",\"type\":\"bytes32[]\"}],\"name\":\"multiRevokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"data\",\"type\":\"bytes32[]\"}],\"name\":\"multiTimestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structRevocationRequestData\",\"name\":\"data\",\"type\":\"tuple\"}],\"internalType\":\"structRevocationRequest\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"revoke\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structRevocationRequestData\",\"name\":\"data\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature\",\"name\":\"signature\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"deadline\",\"type\":\"uint64\"}],\"internalType\":\"structDelegatedRevocationRequest\",\"name\":\"delegatedRequest\",\"type\":\"tuple\"}],\"name\":\"revokeByDelegation\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"name\":\"revokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"name\":\"timestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x61016060405234801561001157600080fd5b50604080518082018252600381526245415360e81b60208083019182528351808501855260058152640312e322e360dc1b908201529151812060e08190527fe374587661e69268352d25204d81b23ce801573f4b09f3545e69536dc085a37a6101008190524660a081815286517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818801819052818901959095526060810193909352608080840192909252308382018190528751808503909201825260c093840190975280519501949094209093529290915261012091909152516101405260805160a05160c05160e05161010051610120516101405161454d61014b600039600061073701526000612753015260006127a20152600061277d015260006126d6015260006127000152600061272a015261454d6000f3fe60806040526004361061018b5760003560e01c806395411525116100d6578063d45c44351161007f578063ed24911d11610059578063ed24911d146104fd578063f10b5cc814610512578063f17325e71461054157600080fd5b8063d45c443514610467578063e30bb5631461049e578063e71ff365146104dd57600080fd5b8063b469318d116100b0578063b469318d146103ba578063b83010d314610414578063cf190f341461044757600080fd5b80639541152514610367578063a3112a641461037a578063a6d4dbc7146103a757600080fd5b806344adc90e116101385780634d003070116101125780634d003070146102de57806354fd4d50146102fe57806379f7573a1461034757600080fd5b806344adc90e1461029857806346926267146102b85780634cb7e9e5146102cb57600080fd5b806317d7de7c1161016957806317d7de7c146102205780632d0335ab146102425780633c0427151461028557600080fd5b80630eabf6601461019057806312b11a17146101a557806313893f61146101e7575b600080fd5b6101a361019e366004613497565b610554565b005b3480156101b157600080fd5b507ff83bb2b0ede93a840239f7e701a54d9bc35f03701f51ae153d601c6947ff3d3f5b6040519081526020015b60405180910390f35b3480156101f357600080fd5b50610207610202366004613497565b6106eb565b60405167ffffffffffffffff90911681526020016101de565b34801561022c57600080fd5b50610235610730565b6040516101de9190613547565b34801561024e57600080fd5b506101d461025d36600461358c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101d46102933660046135a9565b610760565b6102ab6102a6366004613497565b610863565b6040516101de91906135e4565b6101a36102c6366004613628565b6109e4565b6101a36102d9366004613497565b610a68565b3480156102ea57600080fd5b506102076102f9366004613640565b610b4b565b34801561030a57600080fd5b506102356040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b34801561035357600080fd5b506101a3610362366004613640565b610b58565b6102ab610375366004613497565b610bef565b34801561038657600080fd5b5061039a610395366004613640565b610e62565b6040516101de9190613740565b6101a36103b5366004613753565b611025565b3480156103c657600080fd5b506102076103d5366004613766565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561042057600080fd5b507f2d4116d8c9824e4c316453e5c2843a1885580374159ce8768603c49085ef424c6101d4565b34801561045357600080fd5b50610207610462366004613640565b6110ca565b34801561047357600080fd5b50610207610482366004613640565b60009081526033602052604090205467ffffffffffffffff1690565b3480156104aa57600080fd5b506104cd6104b9366004613640565b600090815260326020526040902054151590565b60405190151581526020016101de565b3480156104e957600080fd5b506102076104f8366004613497565b6110d8565b34801561050957600080fd5b506101d4611110565b34801561051e57600080fd5b5060405173420000000000000000000000000000000000002081526020016101de565b6101d461054f366004613792565b61111a565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82018114600086868481811061059a5761059a6137cd565b90506020028101906105ac91906137fc565b6105b590613a92565b60208101518051919250908015806105d257508260400151518114155b15610609576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156106ad576106a56040518060a001604052808660000151815260200185848151811061063e5761063e6137cd565b6020026020010151815260200186604001518481518110610661576106616137cd565b60200260200101518152602001866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866080015167ffffffffffffffff168152506111d8565b60010161060c565b506106c383600001518385606001518a886113c5565b6106cd9088613bbc565b9650505050506106dd8160010190565b9050610559565b5050505050565b60004282825b818110156107245761071c3387878481811061070f5761070f6137cd565b90506020020135856119f4565b6001016106f1565b50909150505b92915050565b606061075b7f0000000000000000000000000000000000000000000000000000000000000000611af3565b905090565b600061077361076e83613cf1565b611c81565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161078a5790505090506107f86020840184613d6c565b61080190613da0565b81600081518110610814576108146137cd565b602090810291909101015261083d83358261083560c0870160a0880161358c565b346001611dfe565b60200151600081518110610853576108536137cd565b6020026020010151915050919050565b60608160008167ffffffffffffffff8111156108815761088161383a565b6040519080825280602002602001820160405280156108b457816020015b606081526020019060019003908161089f5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85018114368989848181106108fc576108fc6137cd565b905060200281019061090e9190613dac565b905061091d6020820182613de0565b9050600003610958576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061097d823561096c6020850185613de0565b61097591613e48565b338887611dfe565b805190915061098c9086613bbc565b945080602001518785815181106109a5576109a56137cd565b6020026020010181905250806020015151860195505050506109c78160010190565b90506108bc565b506109d98383612510565b979650505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816109fb579050509050610a3636839003830160208401613ebc565b81600081518110610a4957610a496137cd565b6020908102919091010152610a63823582333460016113c5565b505050565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201811436868684818110610aad57610aad6137cd565b9050602002810190610abf9190613dac565b9050610b2c8135610ad36020840184613ed8565b808060200260200160405190810160405280939291908181526020016000905b82821015610b1f57610b1060408302860136819003810190613ebc565b81526020019060010190610af3565b50505050503388866113c5565b610b369086613bbc565b94505050610b448160010190565b9050610a6d565b60004261072a83826125fa565b33600090815260208190526040902054808211610ba1576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152602081815260409182902084905581518381529081018490527f57b09af877df9068fd60a69d7b21f5576b8b38955812d6ae4ac52942f1e38fb7910160405180910390a15050565b60608160008167ffffffffffffffff811115610c0d57610c0d61383a565b604051908082528060200260200182016040528015610c4057816020015b6060815260200190600190039081610c2b5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501811436898984818110610c8857610c886137cd565b9050602002810190610c9a91906137fc565b9050366000610cac6020840184613de0565b909250905080801580610ccd5750610cc76040850185613f40565b90508114155b15610d04576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610de557610ddd6040518060a0016040528087600001358152602001868685818110610d3957610d396137cd565b9050602002810190610d4b9190613d6c565b610d5490613da0565b8152602001610d666040890189613f40565b85818110610d7657610d766137cd565b905060600201803603810190610d8c9190613fa7565b8152602001610da16080890160608a0161358c565b73ffffffffffffffffffffffffffffffffffffffff168152602001610dcc60a0890160808a01613fc3565b67ffffffffffffffff169052611c81565b600101610d07565b506000610e0e8535610df78587613e48565b610e076080890160608a0161358c565b8b8a611dfe565b8051909150610e1d9089613bbc565b975080602001518a8881518110610e3657610e366137cd565b602002602001018190525080602001515189019850505050505050610e5b8160010190565b9050610c48565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610f9c90613fde565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc890613fde565b80156110155780601f10610fea57610100808354040283529160200191611015565b820191906000526020600020905b815481529060010190602001808311610ff857829003601f168201915b5050505050815250509050919050565b61103c6110373683900383018361402b565b6111d8565b604080516001808252818301909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161105357905050905061108e36839003830160208401613ebc565b816000815181106110a1576110a16137cd565b6020908102919091010152610a638235826110c260e0860160c0870161358c565b3460016113c5565b60004261072a3384836119f4565b60004282825b81811015610724576111088686838181106110fb576110fb6137cd565b90506020020135846125fa565b6001016110de565b600061075b6126bc565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816111345790505090506111a26020840184613d6c565b6111ab90613da0565b816000815181106111be576111be6137cd565b602090810291909101015261083d83358233346001611dfe565b608081015167ffffffffffffffff161580159061120c57504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611243576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401518451835184860151606088015173ffffffffffffffffffffffffffffffffffffffff166000908152968790529386208054959693959394611313947f2d4116d8c9824e4c316453e5c2843a1885580374159ce8768603c49085ef424c949392876112b883614099565b909155506080808b015160408051602081019890985287019590955260608601939093529184015260a083015267ffffffffffffffff1660c082015260e0015b604051602081830303815290604052805190602001206127f0565b905061138984606001518284602001518560400151866000015160405160200161137593929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612803565b6113bf576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611433573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261147991908101906140d1565b80519091506114b4576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff8111156114d1576114d161383a565b60405190808252806020026020018201604052801561157057816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816114ef5790505b50905060008267ffffffffffffffff81111561158e5761158e61383a565b6040519080825280602002602001820160405280156115b7578160200160208202803683370190505b50905060005b838110156119d65760008a82815181106115d9576115d96137cd565b6020908102919091018101518051600090815260329092526040909120805491925090611632576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c81600101541461166f576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c81169116146116c5576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff1661171b576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611775576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff161515610100820152600682018054839161012084019161188190613fde565b80601f01602080910402602001604051908101604052809291908181526020018280546118ad90613fde565b80156118fa5780601f106118cf576101008083540402835291602001916118fa565b820191906000526020600020905b8154815290600101906020018083116118dd57829003601f168201915b505050505081525050858481518110611915576119156137cd565b60200260200101819052508160200151848481518110611937576119376137cd565b6020026020010181815250508c8b73ffffffffffffffffffffffffffffffffffffffff1686858151811061196d5761196d6137cd565b602002602001015160c0015173ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f61585600001516040516119c491815260200190565b60405180910390a450506001016115bd565b506119e684838360018b8b6129d2565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611a68576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b6020811015611bbe576000858260208110611b3957611b396137cd565b1a60f81b90507fff000000000000000000000000000000000000000000000000000000000000008116600003611b6f5750611bbe565b80848481518110611b8257611b826137cd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505060019182019101611b1c565b5060008167ffffffffffffffff811115611bda57611bda61383a565b6040519080825280601f01601f191660200182016040528015611c04576020820181803683370190505b50905060005b82811015611c7857838181518110611c2457611c246137cd565b602001015160f81c60f81b828281518110611c4157611c416137cd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611c0a565b50949350505050565b608081015167ffffffffffffffff1615801590611cb557504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611cec576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015160408084015184518351848601518486015160608088015160808901518051908b012060a08a0151928c015173ffffffffffffffffffffffffffffffffffffffff1660009081529a8b9052978a208054999a97999798611313987ff83bb2b0ede93a840239f7e701a54d9bc35f03701f51ae153d601c6947ff3d3f989796959491928b611d7e83614099565b909155506080808f015160408051602081019c909c528b019990995273ffffffffffffffffffffffffffffffffffffffff90971660608a015267ffffffffffffffff9586169689019690965292151560a088015260c087019190915260e086015261010085015261012084019190915216610140820152610160016112f8565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff811115611e4357611e4361383a565b604051908082528060200260200182016040528015611e6c578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611ede573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f2491908101906140d1565b8051909150611f5f576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff811115611f7a57611f7a61383a565b60405190808252806020026020018201604052801561201957816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611f985790505b50905060008467ffffffffffffffff8111156120375761203761383a565b604051908082528060200260200182016040528015612060578160200160208202803683370190505b50905060005b858110156124ef5760008b8281518110612082576120826137cd565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff16141580156120cd57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15612104576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151158015612117575080604001515b1561214e576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016121724290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6122148382612dc3565b600081815260326020526040902054909250156122335760010161220a565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906123b390826141f7565b50505060608401511561240a57606084015160009081526032602052604090205461240a576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8287868151811061241d5761241d6137cd565b60200260200101819052508360a0015186868151811061243f5761243f6137cd565b6020026020010181815250508189602001518681518110612462576124626137cd565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b35856040516124d291815260200190565b60405180910390a4505050506124e88160010190565b9050612066565b506124ff83838360008c8c6129d2565b845250919998505050505050505050565b606060008267ffffffffffffffff81111561252d5761252d61383a565b604051908082528060200260200182016040528015612556578160200160208202803683370190505b508451909150600090815b818110156125ef57600087828151811061257d5761257d6137cd565b6020026020010151905060008151905060005b818110156125db578281815181106125aa576125aa6137cd565b60200260200101518787815181106125c4576125c46137cd565b602090810291909101015260019586019501612590565b5050506125e88160010190565b9050612561565b509195945050505050565b60008281526033602052604090205467ffffffffffffffff161561264a576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561272257507f000000000000000000000000000000000000000000000000000000000000000046145b1561274c57507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b600061072a6127fd6126bc565b83612e22565b60008060006128128585612e64565b9092509050600081600481111561282b5761282b614311565b14801561286357508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15612873576001925050506129cb565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016128a8929190614340565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516129319190614361565b600060405180830381855afa9150503d806000811461296c576040519150601f19603f3d011682016040523d82523d6000602084013e612971565b606091505b5091509150818015612984575080516020145b80156129c4575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906129c29083016020908101908401614373565b145b9450505050505b9392505050565b84516000906001819003612a2a57612a2288886000815181106129f7576129f76137cd565b602002602001015188600081518110612a1257612a126137cd565b6020026020010151888888612ea9565b915050612db9565b602088015173ffffffffffffffffffffffffffffffffffffffff8116612acb5760005b82811015612ab057878181518110612a6757612a676137cd565b6020026020010151600014612aa8576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101612a4d565b508315612ac057612ac0856131c8565b600092505050612db9565b6000808273ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b3d919061438c565b905060005b84811015612bfa5760008a8281518110612b5e57612b5e6137cd565b6020026020010151905080600003612b765750612bf2565b82612bad576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88811115612be7576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b978890039792909201915b600101612b42565b508715612cd5576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906388e5b2d9908490612c57908e908e906004016143a9565b60206040518083038185885af1158015612c75573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612c9a919061438c565b612cd0576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612da4565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906391db0b7e908490612d2b908e908e906004016143a9565b60206040518083038185885af1158015612d49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d6e919061438c565b612da4576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8515612db357612db3876131c8565b50925050505b9695505050505050565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b01519451600099612e0499989796918c9101614462565b60405160208183030381529060405280519060200120905092915050565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612e04565b6000808251604103612e9a5760208301516040840151606085015160001a612e8e878285856131db565b94509450505050612ea2565b506000905060025b9250929050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612f1d578515612f04576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612f1357612f13846131c8565b6000915050612db9565b8515613008578073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f92919061438c565b612fc8576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115613002576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393505b84156130e0576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890613062908b90600401613740565b60206040518083038185885af1158015613080573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906130a5919061438c565b6130db576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131ad565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890613134908b90600401613740565b60206040518083038185885af1158015613152573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613177919061438c565b6131ad576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156131bc576131bc846131c8565b50939695505050505050565b80156131d8576131d833826132f3565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561321257506000905060036132ea565b8460ff16601b1415801561322a57508460ff16601c14155b1561323b57506000905060046132ea565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561328f573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166132e3576000600192509250506132ea565b9150600090505b94509492505050565b80471015613362576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146133bc576040519150601f19603f3d011682016040523d82523d6000602084013e6133c1565b606091505b5050905080610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401613359565b60008083601f84011261346457600080fd5b50813567ffffffffffffffff81111561347c57600080fd5b6020830191508360208260051b8501011115612ea257600080fd5b600080602083850312156134aa57600080fd5b823567ffffffffffffffff8111156134c157600080fd5b6134cd85828601613452565b90969095509350505050565b60005b838110156134f45781810151838201526020016134dc565b50506000910152565b600081518084526135158160208601602086016134d9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129cb60208301846134fd565b73ffffffffffffffffffffffffffffffffffffffff811681146131d857600080fd5b80356135878161355a565b919050565b60006020828403121561359e57600080fd5b81356129cb8161355a565b6000602082840312156135bb57600080fd5b813567ffffffffffffffff8111156135d257600080fd5b820160e081850312156129cb57600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561361c57835183529284019291840191600101613600565b50909695505050505050565b60006060828403121561363a57600080fd5b50919050565b60006020828403121561365257600080fd5b5035919050565b600061014082518452602083015160208501526040830151613687604086018267ffffffffffffffff169052565b5060608301516136a3606086018267ffffffffffffffff169052565b5060808301516136bf608086018267ffffffffffffffff169052565b5060a083015160a085015260c08301516136f160c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161371960e086018273ffffffffffffffffffffffffffffffffffffffff169052565b506101008381015115159085015261012080840151818601839052612db9838701826134fd565b6020815260006129cb6020830184613659565b6000610100828403121561363a57600080fd5b6000806040838503121561377957600080fd5b82356137848161355a565b946020939093013593505050565b6000602082840312156137a457600080fd5b813567ffffffffffffffff8111156137bb57600080fd5b8201604081850312156129cb57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261383057600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561388c5761388c61383a565b60405290565b60405160c0810167ffffffffffffffff8111828210171561388c5761388c61383a565b6040516080810167ffffffffffffffff8111828210171561388c5761388c61383a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561391f5761391f61383a565b604052919050565b600067ffffffffffffffff8211156139415761394161383a565b5060051b60200190565b60006040828403121561395d57600080fd5b6040516040810181811067ffffffffffffffff821117156139805761398061383a565b604052823581526020928301359281019290925250919050565b6000606082840312156139ac57600080fd5b6040516060810181811067ffffffffffffffff821117156139cf576139cf61383a565b604052905080823560ff811681146139e657600080fd5b8082525060208301356020820152604083013560408201525092915050565b600082601f830112613a1657600080fd5b81356020613a2b613a2683613927565b6138d8565b82815260609283028501820192828201919087851115613a4a57600080fd5b8387015b85811015613a6d57613a60898261399a565b8452928401928101613a4e565b5090979650505050505050565b803567ffffffffffffffff8116811461358757600080fd5b600060a08236031215613aa457600080fd5b613aac613869565b8235815260208084013567ffffffffffffffff80821115613acc57600080fd5b9085019036601f830112613adf57600080fd5b8135613aed613a2682613927565b81815260069190911b83018401908481019036831115613b0c57600080fd5b938501935b82851015613b3557613b23368661394b565b82528582019150604085019450613b11565b80868801525050506040860135925080831115613b5157600080fd5b5050613b5f36828601613a05565b604083015250613b716060840161357c565b6060820152613b8260808401613a7a565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561072a5761072a613b8d565b80151581146131d857600080fd5b600067ffffffffffffffff821115613bf757613bf761383a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060c08284031215613c3557600080fd5b613c3d613892565b90508135613c4a8161355a565b81526020613c59838201613a7a565b818301526040830135613c6b81613bcf565b604083015260608381013590830152608083013567ffffffffffffffff811115613c9457600080fd5b8301601f81018513613ca557600080fd5b8035613cb3613a2682613bdd565b8181528684838501011115613cc757600080fd5b818484018583013760008483830101528060808601525050505060a082013560a082015292915050565b600060e08236031215613d0357600080fd5b613d0b613869565b82358152602083013567ffffffffffffffff811115613d2957600080fd5b613d3536828601613c23565b602083015250613d48366040850161399a565b604082015260a0830135613d5b8161355a565b6060820152613b8260c08401613a7a565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261383057600080fd5b600061072a3683613c23565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261383057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e1557600080fd5b83018035915067ffffffffffffffff821115613e3057600080fd5b6020019150600581901b3603821315612ea257600080fd5b6000613e56613a2684613927565b80848252602080830192508560051b850136811115613e7457600080fd5b855b81811015613eb057803567ffffffffffffffff811115613e965760008081fd5b613ea236828a01613c23565b865250938201938201613e76565b50919695505050505050565b600060408284031215613ece57600080fd5b6129cb838361394b565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f0d57600080fd5b83018035915067ffffffffffffffff821115613f2857600080fd5b6020019150600681901b3603821315612ea257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f7557600080fd5b83018035915067ffffffffffffffff821115613f9057600080fd5b6020019150606081023603821315612ea257600080fd5b600060608284031215613fb957600080fd5b6129cb838361399a565b600060208284031215613fd557600080fd5b6129cb82613a7a565b600181811c90821680613ff257607f821691505b60208210810361363a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000610100828403121561403e57600080fd5b614046613869565b82358152614057846020850161394b565b6020820152614069846060850161399a565b604082015260c083013561407c8161355a565b606082015261408d60e08401613a7a565b60808201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140ca576140ca613b8d565b5060010190565b600060208083850312156140e457600080fd5b825167ffffffffffffffff808211156140fc57600080fd5b908401906080828703121561411057600080fd5b6141186138b5565b82518152838301516141298161355a565b81850152604083015161413b81613bcf565b604082015260608301518281111561415257600080fd5b80840193505086601f84011261416757600080fd5b82519150614177613a2683613bdd565b828152878584860101111561418b57600080fd5b61419a838683018787016134d9565b60608201529695505050505050565b601f821115610a6357600081815260208120601f850160051c810160208610156141d05750805b601f850160051c820191505b818110156141ef578281556001016141dc565b505050505050565b815167ffffffffffffffff8111156142115761421161383a565b6142258161421f8454613fde565b846141a9565b602080601f83116001811461427857600084156142425750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556141ef565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142c5578886015182559484019460019091019084016142a6565b508582101561430157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061435960408301846134fd565b949350505050565b600082516138308184602087016134d9565b60006020828403121561438557600080fd5b5051919050565b60006020828403121561439e57600080fd5b81516129cb81613bcf565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561441e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261440c868351613659565b955093820193908201906001016143d2565b50508584038187015286518085528782019482019350915060005b8281101561445557845184529381019392810192600101614439565b5091979650505050505050565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b605883015284605983015283516144fb8160798501602088016134d9565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a995050505050505050505056fea164736f6c6343000813000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"attest\",\"inputs\":[{\"name\":\"request\",\"type\":\"tuple\",\"internalType\":\"structAttestationRequest\",\"components\":[{\"name\":\"schema\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"tuple\",\"internalType\":\"structAttestationRequestData\",\"components\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"expirationTime\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"revocable\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"refUID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"attestByDelegation\",\"inputs\":[{\"name\":\"delegatedRequest\",\"type\":\"tuple\",\"internalType\":\"structDelegatedAttestationRequest\",\"components\":[{\"name\":\"schema\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"tuple\",\"internalType\":\"structAttestationRequestData\",\"components\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"expirationTime\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"revocable\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"refUID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"signature\",\"type\":\"tuple\",\"internalType\":\"structSignature\",\"components\":[{\"name\":\"v\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"r\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"s\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"attester\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"deadline\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"getAttestTypeHash\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getAttestation\",\"inputs\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structAttestation\",\"components\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"schema\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"time\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"expirationTime\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"revocationTime\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"refUID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"attester\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"revocable\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getDomainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getName\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getNonce\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRevokeOffchain\",\"inputs\":[{\"name\":\"revoker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRevokeTypeHash\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getSchemaRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISchemaRegistry\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getTimestamp\",\"inputs\":[{\"name\":\"data\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"increaseNonce\",\"inputs\":[{\"name\":\"newNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isAttestationValid\",\"inputs\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"multiAttest\",\"inputs\":[{\"name\":\"multiRequests\",\"type\":\"tuple[]\",\"internalType\":\"structMultiAttestationRequest[]\",\"components\":[{\"name\":\"schema\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"tuple[]\",\"internalType\":\"structAttestationRequestData[]\",\"components\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"expirationTime\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"revocable\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"refUID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"multiAttestByDelegation\",\"inputs\":[{\"name\":\"multiDelegatedRequests\",\"type\":\"tuple[]\",\"internalType\":\"structMultiDelegatedAttestationRequest[]\",\"components\":[{\"name\":\"schema\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"tuple[]\",\"internalType\":\"structAttestationRequestData[]\",\"components\":[{\"name\":\"recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"expirationTime\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"revocable\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"refUID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"signatures\",\"type\":\"tuple[]\",\"internalType\":\"structSignature[]\",\"components\":[{\"name\":\"v\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"r\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"s\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"attester\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"deadline\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"multiRevoke\",\"inputs\":[{\"name\":\"multiRequests\",\"type\":\"tuple[]\",\"internalType\":\"structMultiRevocationRequest[]\",\"components\":[{\"name\":\"schema\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"tuple[]\",\"internalType\":\"structRevocationRequestData[]\",\"components\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}]}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"multiRevokeByDelegation\",\"inputs\":[{\"name\":\"multiDelegatedRequests\",\"type\":\"tuple[]\",\"internalType\":\"structMultiDelegatedRevocationRequest[]\",\"components\":[{\"name\":\"schema\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"tuple[]\",\"internalType\":\"structRevocationRequestData[]\",\"components\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"signatures\",\"type\":\"tuple[]\",\"internalType\":\"structSignature[]\",\"components\":[{\"name\":\"v\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"r\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"s\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"revoker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"deadline\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"multiRevokeOffchain\",\"inputs\":[{\"name\":\"data\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"multiTimestamp\",\"inputs\":[{\"name\":\"data\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"revoke\",\"inputs\":[{\"name\":\"request\",\"type\":\"tuple\",\"internalType\":\"structRevocationRequest\",\"components\":[{\"name\":\"schema\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"tuple\",\"internalType\":\"structRevocationRequestData\",\"components\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}]}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"revokeByDelegation\",\"inputs\":[{\"name\":\"delegatedRequest\",\"type\":\"tuple\",\"internalType\":\"structDelegatedRevocationRequest\",\"components\":[{\"name\":\"schema\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"tuple\",\"internalType\":\"structRevocationRequestData\",\"components\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"signature\",\"type\":\"tuple\",\"internalType\":\"structSignature\",\"components\":[{\"name\":\"v\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"r\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"s\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"revoker\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"deadline\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"revokeOffchain\",\"inputs\":[{\"name\":\"data\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"timestamp\",\"inputs\":[{\"name\":\"data\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Attested\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"attester\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"uid\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"schemaUID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NonceIncreased\",\"inputs\":[{\"name\":\"oldNonce\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newNonce\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Revoked\",\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"attester\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"uid\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"schemaUID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RevokedOffchain\",\"inputs\":[{\"name\":\"revoker\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Timestamped\",\"inputs\":[{\"name\":\"data\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AccessDenied\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AlreadyRevoked\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AlreadyRevokedOffchain\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AlreadyTimestamped\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"DeadlineExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientValue\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAttestation\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAttestations\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidExpirationTime\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidLength\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidNonce\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidOffset\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidRegistry\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidRevocation\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidRevocations\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSchema\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidVerifier\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"Irrevocable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotFound\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"WrongSchema\",\"inputs\":[]}]", + Bin: "0x61016060405234801561001157600080fd5b50604080518082018252600381526245415360e81b60208083019182528351808501855260058152640312e332e360dc1b908201529151812060e08190527f6a08c3e203132c561752255a4d52ffae85bb9c5d33cb3291520dea1b843563896101008190524660a081815286517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818801819052818901959095526060810193909352608080840192909252308382018190528751808503909201825260c093840190975280519501949094209093529290915261012091909152516101405260805160a05160c05160e05161010051610120516101405161457e61014b600039600061073701526000612784015260006127d3015260006127ae01526000612707015260006127310152600061275b015261457e6000f3fe60806040526004361061018b5760003560e01c806395411525116100d6578063d45c44351161007f578063ed24911d11610059578063ed24911d146104fd578063f10b5cc814610512578063f17325e71461054157600080fd5b8063d45c443514610467578063e30bb5631461049e578063e71ff365146104dd57600080fd5b8063b469318d116100b0578063b469318d146103ba578063b83010d314610414578063cf190f341461044757600080fd5b80639541152514610367578063a3112a641461037a578063a6d4dbc7146103a757600080fd5b806344adc90e116101385780634d003070116101125780634d003070146102de57806354fd4d50146102fe57806379f7573a1461034757600080fd5b806344adc90e1461029857806346926267146102b85780634cb7e9e5146102cb57600080fd5b806317d7de7c1161016957806317d7de7c146102205780632d0335ab146102425780633c0427151461028557600080fd5b80630eabf6601461019057806312b11a17146101a557806313893f61146101e7575b600080fd5b6101a361019e3660046134c8565b610554565b005b3480156101b157600080fd5b507ffeb2925a02bae3dae48d424a0437a2b6ac939aa9230ddc55a1a76f065d9880765b6040519081526020015b60405180910390f35b3480156101f357600080fd5b506102076102023660046134c8565b6106eb565b60405167ffffffffffffffff90911681526020016101de565b34801561022c57600080fd5b50610235610730565b6040516101de9190613578565b34801561024e57600080fd5b506101d461025d3660046135bd565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101d46102933660046135da565b610760565b6102ab6102a63660046134c8565b610863565b6040516101de9190613615565b6101a36102c6366004613659565b6109e4565b6101a36102d93660046134c8565b610a68565b3480156102ea57600080fd5b506102076102f9366004613671565b610b4b565b34801561030a57600080fd5b506102356040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b34801561035357600080fd5b506101a3610362366004613671565b610b58565b6102ab6103753660046134c8565b610bef565b34801561038657600080fd5b5061039a610395366004613671565b610e62565b6040516101de9190613771565b6101a36103b5366004613784565b611025565b3480156103c657600080fd5b506102076103d5366004613797565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561042057600080fd5b507fb5d556f07587ec0f08cf386545cc4362c702a001650c2058002615ee5c9d1e756101d4565b34801561045357600080fd5b50610207610462366004613671565b6110ca565b34801561047357600080fd5b50610207610482366004613671565b60009081526033602052604090205467ffffffffffffffff1690565b3480156104aa57600080fd5b506104cd6104b9366004613671565b600090815260326020526040902054151590565b60405190151581526020016101de565b3480156104e957600080fd5b506102076104f83660046134c8565b6110d8565b34801561050957600080fd5b506101d4611110565b34801561051e57600080fd5b5060405173420000000000000000000000000000000000002081526020016101de565b6101d461054f3660046137c3565b61111a565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82018114600086868481811061059a5761059a6137fe565b90506020028101906105ac919061382d565b6105b590613ac3565b60208101518051919250908015806105d257508260400151518114155b15610609576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156106ad576106a56040518060a001604052808660000151815260200185848151811061063e5761063e6137fe565b6020026020010151815260200186604001518481518110610661576106616137fe565b60200260200101518152602001866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866080015167ffffffffffffffff168152506111d8565b60010161060c565b506106c383600001518385606001518a886113e9565b6106cd9088613bed565b9650505050506106dd8160010190565b9050610559565b5050505050565b60004282825b818110156107245761071c3387878481811061070f5761070f6137fe565b9050602002013585611a18565b6001016106f1565b50909150505b92915050565b606061075b7f0000000000000000000000000000000000000000000000000000000000000000611b17565b905090565b600061077361076e83613d22565b611ca5565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161078a5790505090506107f86020840184613d9d565b61080190613dd1565b81600081518110610814576108146137fe565b602090810291909101015261083d83358261083560c0870160a088016135bd565b346001611e2f565b60200151600081518110610853576108536137fe565b6020026020010151915050919050565b60608160008167ffffffffffffffff8111156108815761088161386b565b6040519080825280602002602001820160405280156108b457816020015b606081526020019060019003908161089f5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85018114368989848181106108fc576108fc6137fe565b905060200281019061090e9190613ddd565b905061091d6020820182613e11565b9050600003610958576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061097d823561096c6020850185613e11565b61097591613e79565b338887611e2f565b805190915061098c9086613bed565b945080602001518785815181106109a5576109a56137fe565b6020026020010181905250806020015151860195505050506109c78160010190565b90506108bc565b506109d98383612541565b979650505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816109fb579050509050610a3636839003830160208401613eed565b81600081518110610a4957610a496137fe565b6020908102919091010152610a63823582333460016113e9565b505050565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201811436868684818110610aad57610aad6137fe565b9050602002810190610abf9190613ddd565b9050610b2c8135610ad36020840184613f09565b808060200260200160405190810160405280939291908181526020016000905b82821015610b1f57610b1060408302860136819003810190613eed565b81526020019060010190610af3565b50505050503388866113e9565b610b369086613bed565b94505050610b448160010190565b9050610a6d565b60004261072a838261262b565b33600090815260208190526040902054808211610ba1576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152602081815260409182902084905581518381529081018490527f57b09af877df9068fd60a69d7b21f5576b8b38955812d6ae4ac52942f1e38fb7910160405180910390a15050565b60608160008167ffffffffffffffff811115610c0d57610c0d61386b565b604051908082528060200260200182016040528015610c4057816020015b6060815260200190600190039081610c2b5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501811436898984818110610c8857610c886137fe565b9050602002810190610c9a919061382d565b9050366000610cac6020840184613e11565b909250905080801580610ccd5750610cc76040850185613f71565b90508114155b15610d04576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610de557610ddd6040518060a0016040528087600001358152602001868685818110610d3957610d396137fe565b9050602002810190610d4b9190613d9d565b610d5490613dd1565b8152602001610d666040890189613f71565b85818110610d7657610d766137fe565b905060600201803603810190610d8c9190613fd8565b8152602001610da16080890160608a016135bd565b73ffffffffffffffffffffffffffffffffffffffff168152602001610dcc60a0890160808a01613ff4565b67ffffffffffffffff169052611ca5565b600101610d07565b506000610e0e8535610df78587613e79565b610e076080890160608a016135bd565b8b8a611e2f565b8051909150610e1d9089613bed565b975080602001518a8881518110610e3657610e366137fe565b602002602001018190525080602001515189019850505050505050610e5b8160010190565b9050610c48565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610f9c9061400f565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc89061400f565b80156110155780601f10610fea57610100808354040283529160200191611015565b820191906000526020600020905b815481529060010190602001808311610ff857829003601f168201915b5050505050815250509050919050565b61103c6110373683900383018361405c565b6111d8565b604080516001808252818301909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161105357905050905061108e36839003830160208401613eed565b816000815181106110a1576110a16137fe565b6020908102919091010152610a638235826110c260e0860160c087016135bd565b3460016113e9565b60004261072a338483611a18565b60004282825b81811015610724576111088686838181106110fb576110fb6137fe565b905060200201358461262b565b6001016110de565b600061075b6126ed565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816111345790505090506111a26020840184613d9d565b6111ab90613dd1565b816000815181106111be576111be6137fe565b602090810291909101015261083d83358233346001611e2f565b608081015167ffffffffffffffff161580159061120c57504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611243576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401516060850151855184518587015173ffffffffffffffffffffffffffffffffffffffff84166000908152978890529487208054969794969495611337957fb5d556f07587ec0f08cf386545cc4362c702a001650c2058002615ee5c9d1e7595949392886112ba836140ca565b909155506080808c015160408051602081019990995273ffffffffffffffffffffffffffffffffffffffff9097169688019690965260608701949094529285019190915260a084015260c083015267ffffffffffffffff1660e0820152610100015b60405160208183030381529060405280519060200120612821565b90506113ad84606001518284602001518560400151866000015160405160200161139993929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612834565b6113e3576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261149d9190810190614102565b80519091506114d8576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff8111156114f5576114f561386b565b60405190808252806020026020018201604052801561159457816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816115135790505b50905060008267ffffffffffffffff8111156115b2576115b261386b565b6040519080825280602002602001820160405280156115db578160200160208202803683370190505b50905060005b838110156119fa5760008a82815181106115fd576115fd6137fe565b6020908102919091018101518051600090815260329092526040909120805491925090611656576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c816001015414611693576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c81169116146116e9576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff1661173f576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611799576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805483916101208401916118a59061400f565b80601f01602080910402602001604051908101604052809291908181526020018280546118d19061400f565b801561191e5780601f106118f35761010080835404028352916020019161191e565b820191906000526020600020905b81548152906001019060200180831161190157829003601f168201915b505050505081525050858481518110611939576119396137fe565b6020026020010181905250816020015184848151811061195b5761195b6137fe565b6020026020010181815250508c8b73ffffffffffffffffffffffffffffffffffffffff16868581518110611991576119916137fe565b602002602001015160c0015173ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f61585600001516040516119e891815260200190565b60405180910390a450506001016115e1565b50611a0a84838360018b8b612a03565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611a8c576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b6020811015611be2576000858260208110611b5d57611b5d6137fe565b1a60f81b90507fff000000000000000000000000000000000000000000000000000000000000008116600003611b935750611be2565b80848481518110611ba657611ba66137fe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505060019182019101611b40565b5060008167ffffffffffffffff811115611bfe57611bfe61386b565b6040519080825280601f01601f191660200182016040528015611c28576020820181803683370190505b50905060005b82811015611c9c57838181518110611c4857611c486137fe565b602001015160f81c60f81b828281518110611c6557611c656137fe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611c2e565b50949350505050565b608081015167ffffffffffffffff1615801590611cd957504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611d10576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401516060808601518651855186880151868801519488015160808901518051908b012060a08a015173ffffffffffffffffffffffffffffffffffffffff871660009081529b8c9052988b2080549a9b989a9899611337997ffeb2925a02bae3dae48d424a0437a2b6ac939aa9230ddc55a1a76f065d988076999493928c611da0836140ca565b919050558e6080015160405160200161131c9b9a999897969594939291909a8b5273ffffffffffffffffffffffffffffffffffffffff998a1660208c015260408b019890985295909716606089015267ffffffffffffffff938416608089015291151560a088015260c087015260e0860152610100850193909352610120840152166101408201526101600190565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff811115611e7457611e7461386b565b604051908082528060200260200182016040528015611e9d578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611f0f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f559190810190614102565b8051909150611f90576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff811115611fab57611fab61386b565b60405190808252806020026020018201604052801561204a57816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611fc95790505b50905060008467ffffffffffffffff8111156120685761206861386b565b604051908082528060200260200182016040528015612091578160200160208202803683370190505b50905060005b858110156125205760008b82815181106120b3576120b36137fe565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff16141580156120fe57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15612135576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151158015612148575080604001515b1561217f576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016121a34290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6122458382612df4565b600081815260326020526040902054909250156122645760010161223b565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906123e49082614228565b50505060608401511561243b57606084015160009081526032602052604090205461243b576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8287868151811061244e5761244e6137fe565b60200260200101819052508360a00151868681518110612470576124706137fe565b6020026020010181815250508189602001518681518110612493576124936137fe565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b358560405161250391815260200190565b60405180910390a4505050506125198160010190565b9050612097565b5061253083838360008c8c612a03565b845250919998505050505050505050565b606060008267ffffffffffffffff81111561255e5761255e61386b565b604051908082528060200260200182016040528015612587578160200160208202803683370190505b508451909150600090815b818110156126205760008782815181106125ae576125ae6137fe565b6020026020010151905060008151905060005b8181101561260c578281815181106125db576125db6137fe565b60200260200101518787815181106125f5576125f56137fe565b6020908102919091010152600195860195016125c1565b5050506126198160010190565b9050612592565b509195945050505050565b60008281526033602052604090205467ffffffffffffffff161561267b576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561275357507f000000000000000000000000000000000000000000000000000000000000000046145b1561277d57507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b600061072a61282e6126ed565b83612e53565b60008060006128438585612e95565b9092509050600081600481111561285c5761285c614342565b14801561289457508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b156128a4576001925050506129fc565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016128d9929190614371565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516129629190614392565b600060405180830381855afa9150503d806000811461299d576040519150601f19603f3d011682016040523d82523d6000602084013e6129a2565b606091505b50915091508180156129b5575080516020145b80156129f5575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906129f390830160209081019084016143a4565b145b9450505050505b9392505050565b84516000906001819003612a5b57612a538888600081518110612a2857612a286137fe565b602002602001015188600081518110612a4357612a436137fe565b6020026020010151888888612eda565b915050612dea565b602088015173ffffffffffffffffffffffffffffffffffffffff8116612afc5760005b82811015612ae157878181518110612a9857612a986137fe565b6020026020010151600014612ad9576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101612a7e565b508315612af157612af1856131f9565b600092505050612dea565b6000808273ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6e91906143bd565b905060005b84811015612c2b5760008a8281518110612b8f57612b8f6137fe565b6020026020010151905080600003612ba75750612c23565b82612bde576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88811115612c18576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b978890039792909201915b600101612b73565b508715612d06576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906388e5b2d9908490612c88908e908e906004016143da565b60206040518083038185885af1158015612ca6573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612ccb91906143bd565b612d01576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612dd5565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906391db0b7e908490612d5c908e908e906004016143da565b60206040518083038185885af1158015612d7a573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d9f91906143bd565b612dd5576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8515612de457612de4876131f9565b50925050505b9695505050505050565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b01519451600099612e3599989796918c9101614493565b60405160208183030381529060405280519060200120905092915050565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612e35565b6000808251604103612ecb5760208301516040840151606085015160001a612ebf8782858561320c565b94509450505050612ed3565b506000905060025b9250929050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612f4e578515612f35576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612f4457612f44846131f9565b6000915050612dea565b8515613039578073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc391906143bd565b612ff9576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115613033576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393505b8415613111576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890613093908b90600401613771565b60206040518083038185885af11580156130b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906130d691906143bd565b61310c576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131de565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890613165908b90600401613771565b60206040518083038185885af1158015613183573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906131a891906143bd565b6131de576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156131ed576131ed846131f9565b50939695505050505050565b8015613209576132093382613324565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613243575060009050600361331b565b8460ff16601b1415801561325b57508460ff16601c14155b1561326c575060009050600461331b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156132c0573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166133145760006001925092505061331b565b9150600090505b94509492505050565b80471015613393576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146133ed576040519150601f19603f3d011682016040523d82523d6000602084013e6133f2565b606091505b5050905080610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161338a565b60008083601f84011261349557600080fd5b50813567ffffffffffffffff8111156134ad57600080fd5b6020830191508360208260051b8501011115612ed357600080fd5b600080602083850312156134db57600080fd5b823567ffffffffffffffff8111156134f257600080fd5b6134fe85828601613483565b90969095509350505050565b60005b8381101561352557818101518382015260200161350d565b50506000910152565b6000815180845261354681602086016020860161350a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129fc602083018461352e565b73ffffffffffffffffffffffffffffffffffffffff8116811461320957600080fd5b80356135b88161358b565b919050565b6000602082840312156135cf57600080fd5b81356129fc8161358b565b6000602082840312156135ec57600080fd5b813567ffffffffffffffff81111561360357600080fd5b820160e081850312156129fc57600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561364d57835183529284019291840191600101613631565b50909695505050505050565b60006060828403121561366b57600080fd5b50919050565b60006020828403121561368357600080fd5b5035919050565b6000610140825184526020830151602085015260408301516136b8604086018267ffffffffffffffff169052565b5060608301516136d4606086018267ffffffffffffffff169052565b5060808301516136f0608086018267ffffffffffffffff169052565b5060a083015160a085015260c083015161372260c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161374a60e086018273ffffffffffffffffffffffffffffffffffffffff169052565b506101008381015115159085015261012080840151818601839052612dea8387018261352e565b6020815260006129fc602083018461368a565b6000610100828403121561366b57600080fd5b600080604083850312156137aa57600080fd5b82356137b58161358b565b946020939093013593505050565b6000602082840312156137d557600080fd5b813567ffffffffffffffff8111156137ec57600080fd5b8201604081850312156129fc57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261386157600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156138bd576138bd61386b565b60405290565b60405160c0810167ffffffffffffffff811182821017156138bd576138bd61386b565b6040516080810167ffffffffffffffff811182821017156138bd576138bd61386b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156139505761395061386b565b604052919050565b600067ffffffffffffffff8211156139725761397261386b565b5060051b60200190565b60006040828403121561398e57600080fd5b6040516040810181811067ffffffffffffffff821117156139b1576139b161386b565b604052823581526020928301359281019290925250919050565b6000606082840312156139dd57600080fd5b6040516060810181811067ffffffffffffffff82111715613a0057613a0061386b565b604052905080823560ff81168114613a1757600080fd5b8082525060208301356020820152604083013560408201525092915050565b600082601f830112613a4757600080fd5b81356020613a5c613a5783613958565b613909565b82815260609283028501820192828201919087851115613a7b57600080fd5b8387015b85811015613a9e57613a9189826139cb565b8452928401928101613a7f565b5090979650505050505050565b803567ffffffffffffffff811681146135b857600080fd5b600060a08236031215613ad557600080fd5b613add61389a565b8235815260208084013567ffffffffffffffff80821115613afd57600080fd5b9085019036601f830112613b1057600080fd5b8135613b1e613a5782613958565b81815260069190911b83018401908481019036831115613b3d57600080fd5b938501935b82851015613b6657613b54368661397c565b82528582019150604085019450613b42565b80868801525050506040860135925080831115613b8257600080fd5b5050613b9036828601613a36565b604083015250613ba2606084016135ad565b6060820152613bb360808401613aab565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561072a5761072a613bbe565b801515811461320957600080fd5b600067ffffffffffffffff821115613c2857613c2861386b565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060c08284031215613c6657600080fd5b613c6e6138c3565b90508135613c7b8161358b565b81526020613c8a838201613aab565b818301526040830135613c9c81613c00565b604083015260608381013590830152608083013567ffffffffffffffff811115613cc557600080fd5b8301601f81018513613cd657600080fd5b8035613ce4613a5782613c0e565b8181528684838501011115613cf857600080fd5b818484018583013760008483830101528060808601525050505060a082013560a082015292915050565b600060e08236031215613d3457600080fd5b613d3c61389a565b82358152602083013567ffffffffffffffff811115613d5a57600080fd5b613d6636828601613c54565b602083015250613d7936604085016139cb565b604082015260a0830135613d8c8161358b565b6060820152613bb360c08401613aab565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261386157600080fd5b600061072a3683613c54565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261386157600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e4657600080fd5b83018035915067ffffffffffffffff821115613e6157600080fd5b6020019150600581901b3603821315612ed357600080fd5b6000613e87613a5784613958565b80848252602080830192508560051b850136811115613ea557600080fd5b855b81811015613ee157803567ffffffffffffffff811115613ec75760008081fd5b613ed336828a01613c54565b865250938201938201613ea7565b50919695505050505050565b600060408284031215613eff57600080fd5b6129fc838361397c565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f3e57600080fd5b83018035915067ffffffffffffffff821115613f5957600080fd5b6020019150600681901b3603821315612ed357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613fa657600080fd5b83018035915067ffffffffffffffff821115613fc157600080fd5b6020019150606081023603821315612ed357600080fd5b600060608284031215613fea57600080fd5b6129fc83836139cb565b60006020828403121561400657600080fd5b6129fc82613aab565b600181811c9082168061402357607f821691505b60208210810361366b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000610100828403121561406f57600080fd5b61407761389a565b82358152614088846020850161397c565b602082015261409a84606085016139cb565b604082015260c08301356140ad8161358b565b60608201526140be60e08401613aab565b60808201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140fb576140fb613bbe565b5060010190565b6000602080838503121561411557600080fd5b825167ffffffffffffffff8082111561412d57600080fd5b908401906080828703121561414157600080fd5b6141496138e6565b825181528383015161415a8161358b565b81850152604083015161416c81613c00565b604082015260608301518281111561418357600080fd5b80840193505086601f84011261419857600080fd5b825191506141a8613a5783613c0e565b82815287858486010111156141bc57600080fd5b6141cb8386830187870161350a565b60608201529695505050505050565b601f821115610a6357600081815260208120601f850160051c810160208610156142015750805b601f850160051c820191505b818110156142205782815560010161420d565b505050505050565b815167ffffffffffffffff8111156142425761424261386b565b61425681614250845461400f565b846141da565b602080601f8311600181146142a957600084156142735750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614220565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142f6578886015182559484019460019091019084016142d7565b508582101561433257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061438a604083018461352e565b949350505050565b6000825161386181846020870161350a565b6000602082840312156143b657600080fd5b5051919050565b6000602082840312156143cf57600080fd5b81516129fc81613c00565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561444f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261443d86835161368a565b95509382019390820190600101614403565b50508584038187015286518085528782019482019350915060005b828110156144865784518452938101939281019260010161446a565b5091979650505050505050565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b6058830152846059830152835161452c81607985016020880161350a565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a995050505050505050505056fea164736f6c6343000813000a", } // EASABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/eas_more.go b/op-bindings/bindings/eas_more.go index 56cb953e5b84..1ce9443c7cb4 100644 --- a/op-bindings/bindings/eas_more.go +++ b/op-bindings/bindings/eas_more.go @@ -13,7 +13,8 @@ const EASStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/E var EASStorageLayout = new(solc.StorageLayout) -var EASDeployedBin = "0x60806040526004361061018b5760003560e01c806395411525116100d6578063d45c44351161007f578063ed24911d11610059578063ed24911d146104fd578063f10b5cc814610512578063f17325e71461054157600080fd5b8063d45c443514610467578063e30bb5631461049e578063e71ff365146104dd57600080fd5b8063b469318d116100b0578063b469318d146103ba578063b83010d314610414578063cf190f341461044757600080fd5b80639541152514610367578063a3112a641461037a578063a6d4dbc7146103a757600080fd5b806344adc90e116101385780634d003070116101125780634d003070146102de57806354fd4d50146102fe57806379f7573a1461034757600080fd5b806344adc90e1461029857806346926267146102b85780634cb7e9e5146102cb57600080fd5b806317d7de7c1161016957806317d7de7c146102205780632d0335ab146102425780633c0427151461028557600080fd5b80630eabf6601461019057806312b11a17146101a557806313893f61146101e7575b600080fd5b6101a361019e366004613497565b610554565b005b3480156101b157600080fd5b507ff83bb2b0ede93a840239f7e701a54d9bc35f03701f51ae153d601c6947ff3d3f5b6040519081526020015b60405180910390f35b3480156101f357600080fd5b50610207610202366004613497565b6106eb565b60405167ffffffffffffffff90911681526020016101de565b34801561022c57600080fd5b50610235610730565b6040516101de9190613547565b34801561024e57600080fd5b506101d461025d36600461358c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101d46102933660046135a9565b610760565b6102ab6102a6366004613497565b610863565b6040516101de91906135e4565b6101a36102c6366004613628565b6109e4565b6101a36102d9366004613497565b610a68565b3480156102ea57600080fd5b506102076102f9366004613640565b610b4b565b34801561030a57600080fd5b506102356040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b34801561035357600080fd5b506101a3610362366004613640565b610b58565b6102ab610375366004613497565b610bef565b34801561038657600080fd5b5061039a610395366004613640565b610e62565b6040516101de9190613740565b6101a36103b5366004613753565b611025565b3480156103c657600080fd5b506102076103d5366004613766565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561042057600080fd5b507f2d4116d8c9824e4c316453e5c2843a1885580374159ce8768603c49085ef424c6101d4565b34801561045357600080fd5b50610207610462366004613640565b6110ca565b34801561047357600080fd5b50610207610482366004613640565b60009081526033602052604090205467ffffffffffffffff1690565b3480156104aa57600080fd5b506104cd6104b9366004613640565b600090815260326020526040902054151590565b60405190151581526020016101de565b3480156104e957600080fd5b506102076104f8366004613497565b6110d8565b34801561050957600080fd5b506101d4611110565b34801561051e57600080fd5b5060405173420000000000000000000000000000000000002081526020016101de565b6101d461054f366004613792565b61111a565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82018114600086868481811061059a5761059a6137cd565b90506020028101906105ac91906137fc565b6105b590613a92565b60208101518051919250908015806105d257508260400151518114155b15610609576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156106ad576106a56040518060a001604052808660000151815260200185848151811061063e5761063e6137cd565b6020026020010151815260200186604001518481518110610661576106616137cd565b60200260200101518152602001866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866080015167ffffffffffffffff168152506111d8565b60010161060c565b506106c383600001518385606001518a886113c5565b6106cd9088613bbc565b9650505050506106dd8160010190565b9050610559565b5050505050565b60004282825b818110156107245761071c3387878481811061070f5761070f6137cd565b90506020020135856119f4565b6001016106f1565b50909150505b92915050565b606061075b7f0000000000000000000000000000000000000000000000000000000000000000611af3565b905090565b600061077361076e83613cf1565b611c81565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161078a5790505090506107f86020840184613d6c565b61080190613da0565b81600081518110610814576108146137cd565b602090810291909101015261083d83358261083560c0870160a0880161358c565b346001611dfe565b60200151600081518110610853576108536137cd565b6020026020010151915050919050565b60608160008167ffffffffffffffff8111156108815761088161383a565b6040519080825280602002602001820160405280156108b457816020015b606081526020019060019003908161089f5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85018114368989848181106108fc576108fc6137cd565b905060200281019061090e9190613dac565b905061091d6020820182613de0565b9050600003610958576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061097d823561096c6020850185613de0565b61097591613e48565b338887611dfe565b805190915061098c9086613bbc565b945080602001518785815181106109a5576109a56137cd565b6020026020010181905250806020015151860195505050506109c78160010190565b90506108bc565b506109d98383612510565b979650505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816109fb579050509050610a3636839003830160208401613ebc565b81600081518110610a4957610a496137cd565b6020908102919091010152610a63823582333460016113c5565b505050565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201811436868684818110610aad57610aad6137cd565b9050602002810190610abf9190613dac565b9050610b2c8135610ad36020840184613ed8565b808060200260200160405190810160405280939291908181526020016000905b82821015610b1f57610b1060408302860136819003810190613ebc565b81526020019060010190610af3565b50505050503388866113c5565b610b369086613bbc565b94505050610b448160010190565b9050610a6d565b60004261072a83826125fa565b33600090815260208190526040902054808211610ba1576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152602081815260409182902084905581518381529081018490527f57b09af877df9068fd60a69d7b21f5576b8b38955812d6ae4ac52942f1e38fb7910160405180910390a15050565b60608160008167ffffffffffffffff811115610c0d57610c0d61383a565b604051908082528060200260200182016040528015610c4057816020015b6060815260200190600190039081610c2b5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501811436898984818110610c8857610c886137cd565b9050602002810190610c9a91906137fc565b9050366000610cac6020840184613de0565b909250905080801580610ccd5750610cc76040850185613f40565b90508114155b15610d04576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610de557610ddd6040518060a0016040528087600001358152602001868685818110610d3957610d396137cd565b9050602002810190610d4b9190613d6c565b610d5490613da0565b8152602001610d666040890189613f40565b85818110610d7657610d766137cd565b905060600201803603810190610d8c9190613fa7565b8152602001610da16080890160608a0161358c565b73ffffffffffffffffffffffffffffffffffffffff168152602001610dcc60a0890160808a01613fc3565b67ffffffffffffffff169052611c81565b600101610d07565b506000610e0e8535610df78587613e48565b610e076080890160608a0161358c565b8b8a611dfe565b8051909150610e1d9089613bbc565b975080602001518a8881518110610e3657610e366137cd565b602002602001018190525080602001515189019850505050505050610e5b8160010190565b9050610c48565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610f9c90613fde565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc890613fde565b80156110155780601f10610fea57610100808354040283529160200191611015565b820191906000526020600020905b815481529060010190602001808311610ff857829003601f168201915b5050505050815250509050919050565b61103c6110373683900383018361402b565b6111d8565b604080516001808252818301909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161105357905050905061108e36839003830160208401613ebc565b816000815181106110a1576110a16137cd565b6020908102919091010152610a638235826110c260e0860160c0870161358c565b3460016113c5565b60004261072a3384836119f4565b60004282825b81811015610724576111088686838181106110fb576110fb6137cd565b90506020020135846125fa565b6001016110de565b600061075b6126bc565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816111345790505090506111a26020840184613d6c565b6111ab90613da0565b816000815181106111be576111be6137cd565b602090810291909101015261083d83358233346001611dfe565b608081015167ffffffffffffffff161580159061120c57504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611243576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401518451835184860151606088015173ffffffffffffffffffffffffffffffffffffffff166000908152968790529386208054959693959394611313947f2d4116d8c9824e4c316453e5c2843a1885580374159ce8768603c49085ef424c949392876112b883614099565b909155506080808b015160408051602081019890985287019590955260608601939093529184015260a083015267ffffffffffffffff1660c082015260e0015b604051602081830303815290604052805190602001206127f0565b905061138984606001518284602001518560400151866000015160405160200161137593929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612803565b6113bf576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611433573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261147991908101906140d1565b80519091506114b4576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff8111156114d1576114d161383a565b60405190808252806020026020018201604052801561157057816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816114ef5790505b50905060008267ffffffffffffffff81111561158e5761158e61383a565b6040519080825280602002602001820160405280156115b7578160200160208202803683370190505b50905060005b838110156119d65760008a82815181106115d9576115d96137cd565b6020908102919091018101518051600090815260329092526040909120805491925090611632576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c81600101541461166f576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c81169116146116c5576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff1661171b576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611775576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff161515610100820152600682018054839161012084019161188190613fde565b80601f01602080910402602001604051908101604052809291908181526020018280546118ad90613fde565b80156118fa5780601f106118cf576101008083540402835291602001916118fa565b820191906000526020600020905b8154815290600101906020018083116118dd57829003601f168201915b505050505081525050858481518110611915576119156137cd565b60200260200101819052508160200151848481518110611937576119376137cd565b6020026020010181815250508c8b73ffffffffffffffffffffffffffffffffffffffff1686858151811061196d5761196d6137cd565b602002602001015160c0015173ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f61585600001516040516119c491815260200190565b60405180910390a450506001016115bd565b506119e684838360018b8b6129d2565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611a68576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b6020811015611bbe576000858260208110611b3957611b396137cd565b1a60f81b90507fff000000000000000000000000000000000000000000000000000000000000008116600003611b6f5750611bbe565b80848481518110611b8257611b826137cd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505060019182019101611b1c565b5060008167ffffffffffffffff811115611bda57611bda61383a565b6040519080825280601f01601f191660200182016040528015611c04576020820181803683370190505b50905060005b82811015611c7857838181518110611c2457611c246137cd565b602001015160f81c60f81b828281518110611c4157611c416137cd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611c0a565b50949350505050565b608081015167ffffffffffffffff1615801590611cb557504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611cec576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015160408084015184518351848601518486015160608088015160808901518051908b012060a08a0151928c015173ffffffffffffffffffffffffffffffffffffffff1660009081529a8b9052978a208054999a97999798611313987ff83bb2b0ede93a840239f7e701a54d9bc35f03701f51ae153d601c6947ff3d3f989796959491928b611d7e83614099565b909155506080808f015160408051602081019c909c528b019990995273ffffffffffffffffffffffffffffffffffffffff90971660608a015267ffffffffffffffff9586169689019690965292151560a088015260c087019190915260e086015261010085015261012084019190915216610140820152610160016112f8565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff811115611e4357611e4361383a565b604051908082528060200260200182016040528015611e6c578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611ede573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f2491908101906140d1565b8051909150611f5f576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff811115611f7a57611f7a61383a565b60405190808252806020026020018201604052801561201957816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611f985790505b50905060008467ffffffffffffffff8111156120375761203761383a565b604051908082528060200260200182016040528015612060578160200160208202803683370190505b50905060005b858110156124ef5760008b8281518110612082576120826137cd565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff16141580156120cd57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15612104576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151158015612117575080604001515b1561214e576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016121724290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6122148382612dc3565b600081815260326020526040902054909250156122335760010161220a565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906123b390826141f7565b50505060608401511561240a57606084015160009081526032602052604090205461240a576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8287868151811061241d5761241d6137cd565b60200260200101819052508360a0015186868151811061243f5761243f6137cd565b6020026020010181815250508189602001518681518110612462576124626137cd565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b35856040516124d291815260200190565b60405180910390a4505050506124e88160010190565b9050612066565b506124ff83838360008c8c6129d2565b845250919998505050505050505050565b606060008267ffffffffffffffff81111561252d5761252d61383a565b604051908082528060200260200182016040528015612556578160200160208202803683370190505b508451909150600090815b818110156125ef57600087828151811061257d5761257d6137cd565b6020026020010151905060008151905060005b818110156125db578281815181106125aa576125aa6137cd565b60200260200101518787815181106125c4576125c46137cd565b602090810291909101015260019586019501612590565b5050506125e88160010190565b9050612561565b509195945050505050565b60008281526033602052604090205467ffffffffffffffff161561264a576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561272257507f000000000000000000000000000000000000000000000000000000000000000046145b1561274c57507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b600061072a6127fd6126bc565b83612e22565b60008060006128128585612e64565b9092509050600081600481111561282b5761282b614311565b14801561286357508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15612873576001925050506129cb565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016128a8929190614340565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516129319190614361565b600060405180830381855afa9150503d806000811461296c576040519150601f19603f3d011682016040523d82523d6000602084013e612971565b606091505b5091509150818015612984575080516020145b80156129c4575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906129c29083016020908101908401614373565b145b9450505050505b9392505050565b84516000906001819003612a2a57612a2288886000815181106129f7576129f76137cd565b602002602001015188600081518110612a1257612a126137cd565b6020026020010151888888612ea9565b915050612db9565b602088015173ffffffffffffffffffffffffffffffffffffffff8116612acb5760005b82811015612ab057878181518110612a6757612a676137cd565b6020026020010151600014612aa8576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101612a4d565b508315612ac057612ac0856131c8565b600092505050612db9565b6000808273ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b3d919061438c565b905060005b84811015612bfa5760008a8281518110612b5e57612b5e6137cd565b6020026020010151905080600003612b765750612bf2565b82612bad576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88811115612be7576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b978890039792909201915b600101612b42565b508715612cd5576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906388e5b2d9908490612c57908e908e906004016143a9565b60206040518083038185885af1158015612c75573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612c9a919061438c565b612cd0576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612da4565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906391db0b7e908490612d2b908e908e906004016143a9565b60206040518083038185885af1158015612d49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d6e919061438c565b612da4576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8515612db357612db3876131c8565b50925050505b9695505050505050565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b01519451600099612e0499989796918c9101614462565b60405160208183030381529060405280519060200120905092915050565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612e04565b6000808251604103612e9a5760208301516040840151606085015160001a612e8e878285856131db565b94509450505050612ea2565b506000905060025b9250929050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612f1d578515612f04576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612f1357612f13846131c8565b6000915050612db9565b8515613008578073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f92919061438c565b612fc8576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115613002576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393505b84156130e0576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890613062908b90600401613740565b60206040518083038185885af1158015613080573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906130a5919061438c565b6130db576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131ad565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890613134908b90600401613740565b60206040518083038185885af1158015613152573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613177919061438c565b6131ad576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156131bc576131bc846131c8565b50939695505050505050565b80156131d8576131d833826132f3565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561321257506000905060036132ea565b8460ff16601b1415801561322a57508460ff16601c14155b1561323b57506000905060046132ea565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561328f573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166132e3576000600192509250506132ea565b9150600090505b94509492505050565b80471015613362576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146133bc576040519150601f19603f3d011682016040523d82523d6000602084013e6133c1565b606091505b5050905080610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401613359565b60008083601f84011261346457600080fd5b50813567ffffffffffffffff81111561347c57600080fd5b6020830191508360208260051b8501011115612ea257600080fd5b600080602083850312156134aa57600080fd5b823567ffffffffffffffff8111156134c157600080fd5b6134cd85828601613452565b90969095509350505050565b60005b838110156134f45781810151838201526020016134dc565b50506000910152565b600081518084526135158160208601602086016134d9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129cb60208301846134fd565b73ffffffffffffffffffffffffffffffffffffffff811681146131d857600080fd5b80356135878161355a565b919050565b60006020828403121561359e57600080fd5b81356129cb8161355a565b6000602082840312156135bb57600080fd5b813567ffffffffffffffff8111156135d257600080fd5b820160e081850312156129cb57600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561361c57835183529284019291840191600101613600565b50909695505050505050565b60006060828403121561363a57600080fd5b50919050565b60006020828403121561365257600080fd5b5035919050565b600061014082518452602083015160208501526040830151613687604086018267ffffffffffffffff169052565b5060608301516136a3606086018267ffffffffffffffff169052565b5060808301516136bf608086018267ffffffffffffffff169052565b5060a083015160a085015260c08301516136f160c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161371960e086018273ffffffffffffffffffffffffffffffffffffffff169052565b506101008381015115159085015261012080840151818601839052612db9838701826134fd565b6020815260006129cb6020830184613659565b6000610100828403121561363a57600080fd5b6000806040838503121561377957600080fd5b82356137848161355a565b946020939093013593505050565b6000602082840312156137a457600080fd5b813567ffffffffffffffff8111156137bb57600080fd5b8201604081850312156129cb57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261383057600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561388c5761388c61383a565b60405290565b60405160c0810167ffffffffffffffff8111828210171561388c5761388c61383a565b6040516080810167ffffffffffffffff8111828210171561388c5761388c61383a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561391f5761391f61383a565b604052919050565b600067ffffffffffffffff8211156139415761394161383a565b5060051b60200190565b60006040828403121561395d57600080fd5b6040516040810181811067ffffffffffffffff821117156139805761398061383a565b604052823581526020928301359281019290925250919050565b6000606082840312156139ac57600080fd5b6040516060810181811067ffffffffffffffff821117156139cf576139cf61383a565b604052905080823560ff811681146139e657600080fd5b8082525060208301356020820152604083013560408201525092915050565b600082601f830112613a1657600080fd5b81356020613a2b613a2683613927565b6138d8565b82815260609283028501820192828201919087851115613a4a57600080fd5b8387015b85811015613a6d57613a60898261399a565b8452928401928101613a4e565b5090979650505050505050565b803567ffffffffffffffff8116811461358757600080fd5b600060a08236031215613aa457600080fd5b613aac613869565b8235815260208084013567ffffffffffffffff80821115613acc57600080fd5b9085019036601f830112613adf57600080fd5b8135613aed613a2682613927565b81815260069190911b83018401908481019036831115613b0c57600080fd5b938501935b82851015613b3557613b23368661394b565b82528582019150604085019450613b11565b80868801525050506040860135925080831115613b5157600080fd5b5050613b5f36828601613a05565b604083015250613b716060840161357c565b6060820152613b8260808401613a7a565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561072a5761072a613b8d565b80151581146131d857600080fd5b600067ffffffffffffffff821115613bf757613bf761383a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060c08284031215613c3557600080fd5b613c3d613892565b90508135613c4a8161355a565b81526020613c59838201613a7a565b818301526040830135613c6b81613bcf565b604083015260608381013590830152608083013567ffffffffffffffff811115613c9457600080fd5b8301601f81018513613ca557600080fd5b8035613cb3613a2682613bdd565b8181528684838501011115613cc757600080fd5b818484018583013760008483830101528060808601525050505060a082013560a082015292915050565b600060e08236031215613d0357600080fd5b613d0b613869565b82358152602083013567ffffffffffffffff811115613d2957600080fd5b613d3536828601613c23565b602083015250613d48366040850161399a565b604082015260a0830135613d5b8161355a565b6060820152613b8260c08401613a7a565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261383057600080fd5b600061072a3683613c23565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261383057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e1557600080fd5b83018035915067ffffffffffffffff821115613e3057600080fd5b6020019150600581901b3603821315612ea257600080fd5b6000613e56613a2684613927565b80848252602080830192508560051b850136811115613e7457600080fd5b855b81811015613eb057803567ffffffffffffffff811115613e965760008081fd5b613ea236828a01613c23565b865250938201938201613e76565b50919695505050505050565b600060408284031215613ece57600080fd5b6129cb838361394b565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f0d57600080fd5b83018035915067ffffffffffffffff821115613f2857600080fd5b6020019150600681901b3603821315612ea257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f7557600080fd5b83018035915067ffffffffffffffff821115613f9057600080fd5b6020019150606081023603821315612ea257600080fd5b600060608284031215613fb957600080fd5b6129cb838361399a565b600060208284031215613fd557600080fd5b6129cb82613a7a565b600181811c90821680613ff257607f821691505b60208210810361363a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000610100828403121561403e57600080fd5b614046613869565b82358152614057846020850161394b565b6020820152614069846060850161399a565b604082015260c083013561407c8161355a565b606082015261408d60e08401613a7a565b60808201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140ca576140ca613b8d565b5060010190565b600060208083850312156140e457600080fd5b825167ffffffffffffffff808211156140fc57600080fd5b908401906080828703121561411057600080fd5b6141186138b5565b82518152838301516141298161355a565b81850152604083015161413b81613bcf565b604082015260608301518281111561415257600080fd5b80840193505086601f84011261416757600080fd5b82519150614177613a2683613bdd565b828152878584860101111561418b57600080fd5b61419a838683018787016134d9565b60608201529695505050505050565b601f821115610a6357600081815260208120601f850160051c810160208610156141d05750805b601f850160051c820191505b818110156141ef578281556001016141dc565b505050505050565b815167ffffffffffffffff8111156142115761421161383a565b6142258161421f8454613fde565b846141a9565b602080601f83116001811461427857600084156142425750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556141ef565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142c5578886015182559484019460019091019084016142a6565b508582101561430157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061435960408301846134fd565b949350505050565b600082516138308184602087016134d9565b60006020828403121561438557600080fd5b5051919050565b60006020828403121561439e57600080fd5b81516129cb81613bcf565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561441e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261440c868351613659565b955093820193908201906001016143d2565b50508584038187015286518085528782019482019350915060005b8281101561445557845184529381019392810192600101614439565b5091979650505050505050565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b605883015284605983015283516144fb8160798501602088016134d9565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a995050505050505050505056fea164736f6c6343000813000a" +var EASDeployedBin = "0x60806040526004361061018b5760003560e01c806395411525116100d6578063d45c44351161007f578063ed24911d11610059578063ed24911d146104fd578063f10b5cc814610512578063f17325e71461054157600080fd5b8063d45c443514610467578063e30bb5631461049e578063e71ff365146104dd57600080fd5b8063b469318d116100b0578063b469318d146103ba578063b83010d314610414578063cf190f341461044757600080fd5b80639541152514610367578063a3112a641461037a578063a6d4dbc7146103a757600080fd5b806344adc90e116101385780634d003070116101125780634d003070146102de57806354fd4d50146102fe57806379f7573a1461034757600080fd5b806344adc90e1461029857806346926267146102b85780634cb7e9e5146102cb57600080fd5b806317d7de7c1161016957806317d7de7c146102205780632d0335ab146102425780633c0427151461028557600080fd5b80630eabf6601461019057806312b11a17146101a557806313893f61146101e7575b600080fd5b6101a361019e3660046134c8565b610554565b005b3480156101b157600080fd5b507ffeb2925a02bae3dae48d424a0437a2b6ac939aa9230ddc55a1a76f065d9880765b6040519081526020015b60405180910390f35b3480156101f357600080fd5b506102076102023660046134c8565b6106eb565b60405167ffffffffffffffff90911681526020016101de565b34801561022c57600080fd5b50610235610730565b6040516101de9190613578565b34801561024e57600080fd5b506101d461025d3660046135bd565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101d46102933660046135da565b610760565b6102ab6102a63660046134c8565b610863565b6040516101de9190613615565b6101a36102c6366004613659565b6109e4565b6101a36102d93660046134c8565b610a68565b3480156102ea57600080fd5b506102076102f9366004613671565b610b4b565b34801561030a57600080fd5b506102356040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b34801561035357600080fd5b506101a3610362366004613671565b610b58565b6102ab6103753660046134c8565b610bef565b34801561038657600080fd5b5061039a610395366004613671565b610e62565b6040516101de9190613771565b6101a36103b5366004613784565b611025565b3480156103c657600080fd5b506102076103d5366004613797565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561042057600080fd5b507fb5d556f07587ec0f08cf386545cc4362c702a001650c2058002615ee5c9d1e756101d4565b34801561045357600080fd5b50610207610462366004613671565b6110ca565b34801561047357600080fd5b50610207610482366004613671565b60009081526033602052604090205467ffffffffffffffff1690565b3480156104aa57600080fd5b506104cd6104b9366004613671565b600090815260326020526040902054151590565b60405190151581526020016101de565b3480156104e957600080fd5b506102076104f83660046134c8565b6110d8565b34801561050957600080fd5b506101d4611110565b34801561051e57600080fd5b5060405173420000000000000000000000000000000000002081526020016101de565b6101d461054f3660046137c3565b61111a565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82018114600086868481811061059a5761059a6137fe565b90506020028101906105ac919061382d565b6105b590613ac3565b60208101518051919250908015806105d257508260400151518114155b15610609576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156106ad576106a56040518060a001604052808660000151815260200185848151811061063e5761063e6137fe565b6020026020010151815260200186604001518481518110610661576106616137fe565b60200260200101518152602001866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866080015167ffffffffffffffff168152506111d8565b60010161060c565b506106c383600001518385606001518a886113e9565b6106cd9088613bed565b9650505050506106dd8160010190565b9050610559565b5050505050565b60004282825b818110156107245761071c3387878481811061070f5761070f6137fe565b9050602002013585611a18565b6001016106f1565b50909150505b92915050565b606061075b7f0000000000000000000000000000000000000000000000000000000000000000611b17565b905090565b600061077361076e83613d22565b611ca5565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161078a5790505090506107f86020840184613d9d565b61080190613dd1565b81600081518110610814576108146137fe565b602090810291909101015261083d83358261083560c0870160a088016135bd565b346001611e2f565b60200151600081518110610853576108536137fe565b6020026020010151915050919050565b60608160008167ffffffffffffffff8111156108815761088161386b565b6040519080825280602002602001820160405280156108b457816020015b606081526020019060019003908161089f5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85018114368989848181106108fc576108fc6137fe565b905060200281019061090e9190613ddd565b905061091d6020820182613e11565b9050600003610958576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061097d823561096c6020850185613e11565b61097591613e79565b338887611e2f565b805190915061098c9086613bed565b945080602001518785815181106109a5576109a56137fe565b6020026020010181905250806020015151860195505050506109c78160010190565b90506108bc565b506109d98383612541565b979650505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816109fb579050509050610a3636839003830160208401613eed565b81600081518110610a4957610a496137fe565b6020908102919091010152610a63823582333460016113e9565b505050565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201811436868684818110610aad57610aad6137fe565b9050602002810190610abf9190613ddd565b9050610b2c8135610ad36020840184613f09565b808060200260200160405190810160405280939291908181526020016000905b82821015610b1f57610b1060408302860136819003810190613eed565b81526020019060010190610af3565b50505050503388866113e9565b610b369086613bed565b94505050610b448160010190565b9050610a6d565b60004261072a838261262b565b33600090815260208190526040902054808211610ba1576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152602081815260409182902084905581518381529081018490527f57b09af877df9068fd60a69d7b21f5576b8b38955812d6ae4ac52942f1e38fb7910160405180910390a15050565b60608160008167ffffffffffffffff811115610c0d57610c0d61386b565b604051908082528060200260200182016040528015610c4057816020015b6060815260200190600190039081610c2b5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501811436898984818110610c8857610c886137fe565b9050602002810190610c9a919061382d565b9050366000610cac6020840184613e11565b909250905080801580610ccd5750610cc76040850185613f71565b90508114155b15610d04576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610de557610ddd6040518060a0016040528087600001358152602001868685818110610d3957610d396137fe565b9050602002810190610d4b9190613d9d565b610d5490613dd1565b8152602001610d666040890189613f71565b85818110610d7657610d766137fe565b905060600201803603810190610d8c9190613fd8565b8152602001610da16080890160608a016135bd565b73ffffffffffffffffffffffffffffffffffffffff168152602001610dcc60a0890160808a01613ff4565b67ffffffffffffffff169052611ca5565b600101610d07565b506000610e0e8535610df78587613e79565b610e076080890160608a016135bd565b8b8a611e2f565b8051909150610e1d9089613bed565b975080602001518a8881518110610e3657610e366137fe565b602002602001018190525080602001515189019850505050505050610e5b8160010190565b9050610c48565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610f9c9061400f565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc89061400f565b80156110155780601f10610fea57610100808354040283529160200191611015565b820191906000526020600020905b815481529060010190602001808311610ff857829003601f168201915b5050505050815250509050919050565b61103c6110373683900383018361405c565b6111d8565b604080516001808252818301909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161105357905050905061108e36839003830160208401613eed565b816000815181106110a1576110a16137fe565b6020908102919091010152610a638235826110c260e0860160c087016135bd565b3460016113e9565b60004261072a338483611a18565b60004282825b81811015610724576111088686838181106110fb576110fb6137fe565b905060200201358461262b565b6001016110de565b600061075b6126ed565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816111345790505090506111a26020840184613d9d565b6111ab90613dd1565b816000815181106111be576111be6137fe565b602090810291909101015261083d83358233346001611e2f565b608081015167ffffffffffffffff161580159061120c57504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611243576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401516060850151855184518587015173ffffffffffffffffffffffffffffffffffffffff84166000908152978890529487208054969794969495611337957fb5d556f07587ec0f08cf386545cc4362c702a001650c2058002615ee5c9d1e7595949392886112ba836140ca565b909155506080808c015160408051602081019990995273ffffffffffffffffffffffffffffffffffffffff9097169688019690965260608701949094529285019190915260a084015260c083015267ffffffffffffffff1660e0820152610100015b60405160208183030381529060405280519060200120612821565b90506113ad84606001518284602001518560400151866000015160405160200161139993929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612834565b6113e3576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261149d9190810190614102565b80519091506114d8576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff8111156114f5576114f561386b565b60405190808252806020026020018201604052801561159457816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816115135790505b50905060008267ffffffffffffffff8111156115b2576115b261386b565b6040519080825280602002602001820160405280156115db578160200160208202803683370190505b50905060005b838110156119fa5760008a82815181106115fd576115fd6137fe565b6020908102919091018101518051600090815260329092526040909120805491925090611656576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c816001015414611693576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c81169116146116e9576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff1661173f576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611799576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805483916101208401916118a59061400f565b80601f01602080910402602001604051908101604052809291908181526020018280546118d19061400f565b801561191e5780601f106118f35761010080835404028352916020019161191e565b820191906000526020600020905b81548152906001019060200180831161190157829003601f168201915b505050505081525050858481518110611939576119396137fe565b6020026020010181905250816020015184848151811061195b5761195b6137fe565b6020026020010181815250508c8b73ffffffffffffffffffffffffffffffffffffffff16868581518110611991576119916137fe565b602002602001015160c0015173ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f61585600001516040516119e891815260200190565b60405180910390a450506001016115e1565b50611a0a84838360018b8b612a03565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611a8c576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b6020811015611be2576000858260208110611b5d57611b5d6137fe565b1a60f81b90507fff000000000000000000000000000000000000000000000000000000000000008116600003611b935750611be2565b80848481518110611ba657611ba66137fe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505060019182019101611b40565b5060008167ffffffffffffffff811115611bfe57611bfe61386b565b6040519080825280601f01601f191660200182016040528015611c28576020820181803683370190505b50905060005b82811015611c9c57838181518110611c4857611c486137fe565b602001015160f81c60f81b828281518110611c6557611c656137fe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611c2e565b50949350505050565b608081015167ffffffffffffffff1615801590611cd957504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611d10576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401516060808601518651855186880151868801519488015160808901518051908b012060a08a015173ffffffffffffffffffffffffffffffffffffffff871660009081529b8c9052988b2080549a9b989a9899611337997ffeb2925a02bae3dae48d424a0437a2b6ac939aa9230ddc55a1a76f065d988076999493928c611da0836140ca565b919050558e6080015160405160200161131c9b9a999897969594939291909a8b5273ffffffffffffffffffffffffffffffffffffffff998a1660208c015260408b019890985295909716606089015267ffffffffffffffff938416608089015291151560a088015260c087015260e0860152610100850193909352610120840152166101408201526101600190565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff811115611e7457611e7461386b565b604051908082528060200260200182016040528015611e9d578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611f0f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f559190810190614102565b8051909150611f90576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff811115611fab57611fab61386b565b60405190808252806020026020018201604052801561204a57816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611fc95790505b50905060008467ffffffffffffffff8111156120685761206861386b565b604051908082528060200260200182016040528015612091578160200160208202803683370190505b50905060005b858110156125205760008b82815181106120b3576120b36137fe565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff16141580156120fe57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15612135576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151158015612148575080604001515b1561217f576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016121a34290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6122458382612df4565b600081815260326020526040902054909250156122645760010161223b565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906123e49082614228565b50505060608401511561243b57606084015160009081526032602052604090205461243b576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8287868151811061244e5761244e6137fe565b60200260200101819052508360a00151868681518110612470576124706137fe565b6020026020010181815250508189602001518681518110612493576124936137fe565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b358560405161250391815260200190565b60405180910390a4505050506125198160010190565b9050612097565b5061253083838360008c8c612a03565b845250919998505050505050505050565b606060008267ffffffffffffffff81111561255e5761255e61386b565b604051908082528060200260200182016040528015612587578160200160208202803683370190505b508451909150600090815b818110156126205760008782815181106125ae576125ae6137fe565b6020026020010151905060008151905060005b8181101561260c578281815181106125db576125db6137fe565b60200260200101518787815181106125f5576125f56137fe565b6020908102919091010152600195860195016125c1565b5050506126198160010190565b9050612592565b509195945050505050565b60008281526033602052604090205467ffffffffffffffff161561267b576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561275357507f000000000000000000000000000000000000000000000000000000000000000046145b1561277d57507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b600061072a61282e6126ed565b83612e53565b60008060006128438585612e95565b9092509050600081600481111561285c5761285c614342565b14801561289457508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b156128a4576001925050506129fc565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016128d9929190614371565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516129629190614392565b600060405180830381855afa9150503d806000811461299d576040519150601f19603f3d011682016040523d82523d6000602084013e6129a2565b606091505b50915091508180156129b5575080516020145b80156129f5575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906129f390830160209081019084016143a4565b145b9450505050505b9392505050565b84516000906001819003612a5b57612a538888600081518110612a2857612a286137fe565b602002602001015188600081518110612a4357612a436137fe565b6020026020010151888888612eda565b915050612dea565b602088015173ffffffffffffffffffffffffffffffffffffffff8116612afc5760005b82811015612ae157878181518110612a9857612a986137fe565b6020026020010151600014612ad9576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101612a7e565b508315612af157612af1856131f9565b600092505050612dea565b6000808273ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6e91906143bd565b905060005b84811015612c2b5760008a8281518110612b8f57612b8f6137fe565b6020026020010151905080600003612ba75750612c23565b82612bde576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88811115612c18576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b978890039792909201915b600101612b73565b508715612d06576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906388e5b2d9908490612c88908e908e906004016143da565b60206040518083038185885af1158015612ca6573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612ccb91906143bd565b612d01576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612dd5565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906391db0b7e908490612d5c908e908e906004016143da565b60206040518083038185885af1158015612d7a573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d9f91906143bd565b612dd5576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8515612de457612de4876131f9565b50925050505b9695505050505050565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b01519451600099612e3599989796918c9101614493565b60405160208183030381529060405280519060200120905092915050565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612e35565b6000808251604103612ecb5760208301516040840151606085015160001a612ebf8782858561320c565b94509450505050612ed3565b506000905060025b9250929050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612f4e578515612f35576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612f4457612f44846131f9565b6000915050612dea565b8515613039578073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc391906143bd565b612ff9576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115613033576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393505b8415613111576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890613093908b90600401613771565b60206040518083038185885af11580156130b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906130d691906143bd565b61310c576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131de565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890613165908b90600401613771565b60206040518083038185885af1158015613183573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906131a891906143bd565b6131de576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156131ed576131ed846131f9565b50939695505050505050565b8015613209576132093382613324565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613243575060009050600361331b565b8460ff16601b1415801561325b57508460ff16601c14155b1561326c575060009050600461331b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156132c0573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166133145760006001925092505061331b565b9150600090505b94509492505050565b80471015613393576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146133ed576040519150601f19603f3d011682016040523d82523d6000602084013e6133f2565b606091505b5050905080610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161338a565b60008083601f84011261349557600080fd5b50813567ffffffffffffffff8111156134ad57600080fd5b6020830191508360208260051b8501011115612ed357600080fd5b600080602083850312156134db57600080fd5b823567ffffffffffffffff8111156134f257600080fd5b6134fe85828601613483565b90969095509350505050565b60005b8381101561352557818101518382015260200161350d565b50506000910152565b6000815180845261354681602086016020860161350a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129fc602083018461352e565b73ffffffffffffffffffffffffffffffffffffffff8116811461320957600080fd5b80356135b88161358b565b919050565b6000602082840312156135cf57600080fd5b81356129fc8161358b565b6000602082840312156135ec57600080fd5b813567ffffffffffffffff81111561360357600080fd5b820160e081850312156129fc57600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561364d57835183529284019291840191600101613631565b50909695505050505050565b60006060828403121561366b57600080fd5b50919050565b60006020828403121561368357600080fd5b5035919050565b6000610140825184526020830151602085015260408301516136b8604086018267ffffffffffffffff169052565b5060608301516136d4606086018267ffffffffffffffff169052565b5060808301516136f0608086018267ffffffffffffffff169052565b5060a083015160a085015260c083015161372260c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161374a60e086018273ffffffffffffffffffffffffffffffffffffffff169052565b506101008381015115159085015261012080840151818601839052612dea8387018261352e565b6020815260006129fc602083018461368a565b6000610100828403121561366b57600080fd5b600080604083850312156137aa57600080fd5b82356137b58161358b565b946020939093013593505050565b6000602082840312156137d557600080fd5b813567ffffffffffffffff8111156137ec57600080fd5b8201604081850312156129fc57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261386157600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156138bd576138bd61386b565b60405290565b60405160c0810167ffffffffffffffff811182821017156138bd576138bd61386b565b6040516080810167ffffffffffffffff811182821017156138bd576138bd61386b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156139505761395061386b565b604052919050565b600067ffffffffffffffff8211156139725761397261386b565b5060051b60200190565b60006040828403121561398e57600080fd5b6040516040810181811067ffffffffffffffff821117156139b1576139b161386b565b604052823581526020928301359281019290925250919050565b6000606082840312156139dd57600080fd5b6040516060810181811067ffffffffffffffff82111715613a0057613a0061386b565b604052905080823560ff81168114613a1757600080fd5b8082525060208301356020820152604083013560408201525092915050565b600082601f830112613a4757600080fd5b81356020613a5c613a5783613958565b613909565b82815260609283028501820192828201919087851115613a7b57600080fd5b8387015b85811015613a9e57613a9189826139cb565b8452928401928101613a7f565b5090979650505050505050565b803567ffffffffffffffff811681146135b857600080fd5b600060a08236031215613ad557600080fd5b613add61389a565b8235815260208084013567ffffffffffffffff80821115613afd57600080fd5b9085019036601f830112613b1057600080fd5b8135613b1e613a5782613958565b81815260069190911b83018401908481019036831115613b3d57600080fd5b938501935b82851015613b6657613b54368661397c565b82528582019150604085019450613b42565b80868801525050506040860135925080831115613b8257600080fd5b5050613b9036828601613a36565b604083015250613ba2606084016135ad565b6060820152613bb360808401613aab565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561072a5761072a613bbe565b801515811461320957600080fd5b600067ffffffffffffffff821115613c2857613c2861386b565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060c08284031215613c6657600080fd5b613c6e6138c3565b90508135613c7b8161358b565b81526020613c8a838201613aab565b818301526040830135613c9c81613c00565b604083015260608381013590830152608083013567ffffffffffffffff811115613cc557600080fd5b8301601f81018513613cd657600080fd5b8035613ce4613a5782613c0e565b8181528684838501011115613cf857600080fd5b818484018583013760008483830101528060808601525050505060a082013560a082015292915050565b600060e08236031215613d3457600080fd5b613d3c61389a565b82358152602083013567ffffffffffffffff811115613d5a57600080fd5b613d6636828601613c54565b602083015250613d7936604085016139cb565b604082015260a0830135613d8c8161358b565b6060820152613bb360c08401613aab565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261386157600080fd5b600061072a3683613c54565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261386157600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e4657600080fd5b83018035915067ffffffffffffffff821115613e6157600080fd5b6020019150600581901b3603821315612ed357600080fd5b6000613e87613a5784613958565b80848252602080830192508560051b850136811115613ea557600080fd5b855b81811015613ee157803567ffffffffffffffff811115613ec75760008081fd5b613ed336828a01613c54565b865250938201938201613ea7565b50919695505050505050565b600060408284031215613eff57600080fd5b6129fc838361397c565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f3e57600080fd5b83018035915067ffffffffffffffff821115613f5957600080fd5b6020019150600681901b3603821315612ed357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613fa657600080fd5b83018035915067ffffffffffffffff821115613fc157600080fd5b6020019150606081023603821315612ed357600080fd5b600060608284031215613fea57600080fd5b6129fc83836139cb565b60006020828403121561400657600080fd5b6129fc82613aab565b600181811c9082168061402357607f821691505b60208210810361366b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000610100828403121561406f57600080fd5b61407761389a565b82358152614088846020850161397c565b602082015261409a84606085016139cb565b604082015260c08301356140ad8161358b565b60608201526140be60e08401613aab565b60808201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140fb576140fb613bbe565b5060010190565b6000602080838503121561411557600080fd5b825167ffffffffffffffff8082111561412d57600080fd5b908401906080828703121561414157600080fd5b6141496138e6565b825181528383015161415a8161358b565b81850152604083015161416c81613c00565b604082015260608301518281111561418357600080fd5b80840193505086601f84011261419857600080fd5b825191506141a8613a5783613c0e565b82815287858486010111156141bc57600080fd5b6141cb8386830187870161350a565b60608201529695505050505050565b601f821115610a6357600081815260208120601f850160051c810160208610156142015750805b601f850160051c820191505b818110156142205782815560010161420d565b505050505050565b815167ffffffffffffffff8111156142425761424261386b565b61425681614250845461400f565b846141da565b602080601f8311600181146142a957600084156142735750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614220565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142f6578886015182559484019460019091019084016142d7565b508582101561433257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061438a604083018461352e565b949350505050565b6000825161386181846020870161350a565b6000602082840312156143b657600080fd5b5051919050565b6000602082840312156143cf57600080fd5b81516129fc81613c00565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561444f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261443d86835161368a565b95509382019390820190600101614403565b50508584038187015286518085528782019482019350915060005b828110156144865784518452938101939281019260010161446a565b5091979650505050505050565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b6058830152846059830152835161452c81607985016020880161350a565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a995050505050505050505056fea164736f6c6343000813000a" + func init() { if err := json.Unmarshal([]byte(EASStorageLayoutJSON), EASStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["EAS"] = EASStorageLayout deployedBytecodes["EAS"] = EASDeployedBin + immutableReferences["EAS"] = true } diff --git a/op-bindings/bindings/entrypoint.go b/op-bindings/bindings/entrypoint.go new file mode 100644 index 000000000000..e26ceb245460 --- /dev/null +++ b/op-bindings/bindings/entrypoint.go @@ -0,0 +1,2283 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// EntryPointMemoryUserOp is an auto generated low-level Go binding around an user-defined struct. +type EntryPointMemoryUserOp struct { + Sender common.Address + Nonce *big.Int + CallGasLimit *big.Int + VerificationGasLimit *big.Int + PreVerificationGas *big.Int + Paymaster common.Address + MaxFeePerGas *big.Int + MaxPriorityFeePerGas *big.Int +} + +// EntryPointUserOpInfo is an auto generated low-level Go binding around an user-defined struct. +type EntryPointUserOpInfo struct { + MUserOp EntryPointMemoryUserOp + UserOpHash [32]byte + Prefund *big.Int + ContextOffset *big.Int + PreOpGas *big.Int +} + +// IEntryPointUserOpsPerAggregator is an auto generated low-level Go binding around an user-defined struct. +type IEntryPointUserOpsPerAggregator struct { + UserOps []UserOperation + Aggregator common.Address + Signature []byte +} + +// IStakeManagerDepositInfo is an auto generated low-level Go binding around an user-defined struct. +type IStakeManagerDepositInfo struct { + Deposit *big.Int + Staked bool + Stake *big.Int + UnstakeDelaySec uint32 + WithdrawTime *big.Int +} + +// UserOperation is an auto generated low-level Go binding around an user-defined struct. +type UserOperation struct { + Sender common.Address + Nonce *big.Int + InitCode []byte + CallData []byte + CallGasLimit *big.Int + VerificationGasLimit *big.Int + PreVerificationGas *big.Int + MaxFeePerGas *big.Int + MaxPriorityFeePerGas *big.Int + PaymasterAndData []byte + Signature []byte +} + +// EntryPointMetaData contains all meta data concerning the EntryPoint contract. +var EntryPointMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"targetSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"targetResult\",\"type\":\"bytes\"}],\"name\":\"ExecutionResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"opIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"FailedOp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderAddressResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureValidationFailed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"structIEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"structIStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"structIStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"structIStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResult\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"structIEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"structIStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"structIStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"structIStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"structIStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"}],\"internalType\":\"structIEntryPoint.AggregatorStakeInfo\",\"name\":\"aggregatorInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResultWithAggregation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BeforeExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalDeposit\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureAggregatorChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStaked\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"name\":\"StakeLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasUsed\",\"type\":\"uint256\"}],\"name\":\"UserOperationEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"revertReason\",\"type\":\"bytes\"}],\"name\":\"UserOperationRevertReason\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SIG_VALIDATION_FAILED\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"}],\"name\":\"_validateSenderAndPaymaster\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getDepositInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"internalType\":\"structIStakeManager.DepositInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"getSenderAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"structUserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"structUserOperation[]\",\"name\":\"userOps\",\"type\":\"tuple[]\"},{\"internalType\":\"contractIAggregator\",\"name\":\"aggregator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"structIEntryPoint.UserOpsPerAggregator[]\",\"name\":\"opsPerAggregator\",\"type\":\"tuple[]\"},{\"internalType\":\"addresspayable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleAggregatedOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"structUserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"addresspayable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"incrementNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"structEntryPoint.MemoryUserOp\",\"name\":\"mUserOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contextOffset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"}],\"internalType\":\"structEntryPoint.UserOpInfo\",\"name\":\"opInfo\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"name\":\"innerHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"name\":\"nonceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"structUserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCallData\",\"type\":\"bytes\"}],\"name\":\"simulateHandleOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"structUserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateValidation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"withdrawAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033", +} + +// EntryPointABI is the input ABI used to generate the binding from. +// Deprecated: Use EntryPointMetaData.ABI instead. +var EntryPointABI = EntryPointMetaData.ABI + +// EntryPointBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use EntryPointMetaData.Bin instead. +var EntryPointBin = EntryPointMetaData.Bin + +// DeployEntryPoint deploys a new Ethereum contract, binding an instance of EntryPoint to it. +func DeployEntryPoint(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *EntryPoint, error) { + parsed, err := EntryPointMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EntryPointBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EntryPoint{EntryPointCaller: EntryPointCaller{contract: contract}, EntryPointTransactor: EntryPointTransactor{contract: contract}, EntryPointFilterer: EntryPointFilterer{contract: contract}}, nil +} + +// EntryPoint is an auto generated Go binding around an Ethereum contract. +type EntryPoint struct { + EntryPointCaller // Read-only binding to the contract + EntryPointTransactor // Write-only binding to the contract + EntryPointFilterer // Log filterer for contract events +} + +// EntryPointCaller is an auto generated read-only Go binding around an Ethereum contract. +type EntryPointCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EntryPointTransactor is an auto generated write-only Go binding around an Ethereum contract. +type EntryPointTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EntryPointFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type EntryPointFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EntryPointSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type EntryPointSession struct { + Contract *EntryPoint // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// EntryPointCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type EntryPointCallerSession struct { + Contract *EntryPointCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// EntryPointTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type EntryPointTransactorSession struct { + Contract *EntryPointTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// EntryPointRaw is an auto generated low-level Go binding around an Ethereum contract. +type EntryPointRaw struct { + Contract *EntryPoint // Generic contract binding to access the raw methods on +} + +// EntryPointCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type EntryPointCallerRaw struct { + Contract *EntryPointCaller // Generic read-only contract binding to access the raw methods on +} + +// EntryPointTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type EntryPointTransactorRaw struct { + Contract *EntryPointTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewEntryPoint creates a new instance of EntryPoint, bound to a specific deployed contract. +func NewEntryPoint(address common.Address, backend bind.ContractBackend) (*EntryPoint, error) { + contract, err := bindEntryPoint(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &EntryPoint{EntryPointCaller: EntryPointCaller{contract: contract}, EntryPointTransactor: EntryPointTransactor{contract: contract}, EntryPointFilterer: EntryPointFilterer{contract: contract}}, nil +} + +// NewEntryPointCaller creates a new read-only instance of EntryPoint, bound to a specific deployed contract. +func NewEntryPointCaller(address common.Address, caller bind.ContractCaller) (*EntryPointCaller, error) { + contract, err := bindEntryPoint(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EntryPointCaller{contract: contract}, nil +} + +// NewEntryPointTransactor creates a new write-only instance of EntryPoint, bound to a specific deployed contract. +func NewEntryPointTransactor(address common.Address, transactor bind.ContractTransactor) (*EntryPointTransactor, error) { + contract, err := bindEntryPoint(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EntryPointTransactor{contract: contract}, nil +} + +// NewEntryPointFilterer creates a new log filterer instance of EntryPoint, bound to a specific deployed contract. +func NewEntryPointFilterer(address common.Address, filterer bind.ContractFilterer) (*EntryPointFilterer, error) { + contract, err := bindEntryPoint(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EntryPointFilterer{contract: contract}, nil +} + +// bindEntryPoint binds a generic wrapper to an already deployed contract. +func bindEntryPoint(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(EntryPointABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_EntryPoint *EntryPointRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EntryPoint.Contract.EntryPointCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_EntryPoint *EntryPointRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EntryPoint.Contract.EntryPointTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_EntryPoint *EntryPointRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EntryPoint.Contract.EntryPointTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_EntryPoint *EntryPointCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EntryPoint.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_EntryPoint *EntryPointTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EntryPoint.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_EntryPoint *EntryPointTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EntryPoint.Contract.contract.Transact(opts, method, params...) +} + +// SIGVALIDATIONFAILED is a free data retrieval call binding the contract method 0x8f41ec5a. +// +// Solidity: function SIG_VALIDATION_FAILED() view returns(uint256) +func (_EntryPoint *EntryPointCaller) SIGVALIDATIONFAILED(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _EntryPoint.contract.Call(opts, &out, "SIG_VALIDATION_FAILED") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SIGVALIDATIONFAILED is a free data retrieval call binding the contract method 0x8f41ec5a. +// +// Solidity: function SIG_VALIDATION_FAILED() view returns(uint256) +func (_EntryPoint *EntryPointSession) SIGVALIDATIONFAILED() (*big.Int, error) { + return _EntryPoint.Contract.SIGVALIDATIONFAILED(&_EntryPoint.CallOpts) +} + +// SIGVALIDATIONFAILED is a free data retrieval call binding the contract method 0x8f41ec5a. +// +// Solidity: function SIG_VALIDATION_FAILED() view returns(uint256) +func (_EntryPoint *EntryPointCallerSession) SIGVALIDATIONFAILED() (*big.Int, error) { + return _EntryPoint.Contract.SIGVALIDATIONFAILED(&_EntryPoint.CallOpts) +} + +// ValidateSenderAndPaymaster is a free data retrieval call binding the contract method 0x957122ab. +// +// Solidity: function _validateSenderAndPaymaster(bytes initCode, address sender, bytes paymasterAndData) view returns() +func (_EntryPoint *EntryPointCaller) ValidateSenderAndPaymaster(opts *bind.CallOpts, initCode []byte, sender common.Address, paymasterAndData []byte) error { + var out []interface{} + err := _EntryPoint.contract.Call(opts, &out, "_validateSenderAndPaymaster", initCode, sender, paymasterAndData) + + if err != nil { + return err + } + + return err + +} + +// ValidateSenderAndPaymaster is a free data retrieval call binding the contract method 0x957122ab. +// +// Solidity: function _validateSenderAndPaymaster(bytes initCode, address sender, bytes paymasterAndData) view returns() +func (_EntryPoint *EntryPointSession) ValidateSenderAndPaymaster(initCode []byte, sender common.Address, paymasterAndData []byte) error { + return _EntryPoint.Contract.ValidateSenderAndPaymaster(&_EntryPoint.CallOpts, initCode, sender, paymasterAndData) +} + +// ValidateSenderAndPaymaster is a free data retrieval call binding the contract method 0x957122ab. +// +// Solidity: function _validateSenderAndPaymaster(bytes initCode, address sender, bytes paymasterAndData) view returns() +func (_EntryPoint *EntryPointCallerSession) ValidateSenderAndPaymaster(initCode []byte, sender common.Address, paymasterAndData []byte) error { + return _EntryPoint.Contract.ValidateSenderAndPaymaster(&_EntryPoint.CallOpts, initCode, sender, paymasterAndData) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_EntryPoint *EntryPointCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _EntryPoint.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_EntryPoint *EntryPointSession) BalanceOf(account common.Address) (*big.Int, error) { + return _EntryPoint.Contract.BalanceOf(&_EntryPoint.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_EntryPoint *EntryPointCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _EntryPoint.Contract.BalanceOf(&_EntryPoint.CallOpts, account) +} + +// Deposits is a free data retrieval call binding the contract method 0xfc7e286d. +// +// Solidity: function deposits(address ) view returns(uint112 deposit, bool staked, uint112 stake, uint32 unstakeDelaySec, uint48 withdrawTime) +func (_EntryPoint *EntryPointCaller) Deposits(opts *bind.CallOpts, arg0 common.Address) (struct { + Deposit *big.Int + Staked bool + Stake *big.Int + UnstakeDelaySec uint32 + WithdrawTime *big.Int +}, error) { + var out []interface{} + err := _EntryPoint.contract.Call(opts, &out, "deposits", arg0) + + outstruct := new(struct { + Deposit *big.Int + Staked bool + Stake *big.Int + UnstakeDelaySec uint32 + WithdrawTime *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Deposit = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Staked = *abi.ConvertType(out[1], new(bool)).(*bool) + outstruct.Stake = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.UnstakeDelaySec = *abi.ConvertType(out[3], new(uint32)).(*uint32) + outstruct.WithdrawTime = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// Deposits is a free data retrieval call binding the contract method 0xfc7e286d. +// +// Solidity: function deposits(address ) view returns(uint112 deposit, bool staked, uint112 stake, uint32 unstakeDelaySec, uint48 withdrawTime) +func (_EntryPoint *EntryPointSession) Deposits(arg0 common.Address) (struct { + Deposit *big.Int + Staked bool + Stake *big.Int + UnstakeDelaySec uint32 + WithdrawTime *big.Int +}, error) { + return _EntryPoint.Contract.Deposits(&_EntryPoint.CallOpts, arg0) +} + +// Deposits is a free data retrieval call binding the contract method 0xfc7e286d. +// +// Solidity: function deposits(address ) view returns(uint112 deposit, bool staked, uint112 stake, uint32 unstakeDelaySec, uint48 withdrawTime) +func (_EntryPoint *EntryPointCallerSession) Deposits(arg0 common.Address) (struct { + Deposit *big.Int + Staked bool + Stake *big.Int + UnstakeDelaySec uint32 + WithdrawTime *big.Int +}, error) { + return _EntryPoint.Contract.Deposits(&_EntryPoint.CallOpts, arg0) +} + +// GetDepositInfo is a free data retrieval call binding the contract method 0x5287ce12. +// +// Solidity: function getDepositInfo(address account) view returns((uint112,bool,uint112,uint32,uint48) info) +func (_EntryPoint *EntryPointCaller) GetDepositInfo(opts *bind.CallOpts, account common.Address) (IStakeManagerDepositInfo, error) { + var out []interface{} + err := _EntryPoint.contract.Call(opts, &out, "getDepositInfo", account) + + if err != nil { + return *new(IStakeManagerDepositInfo), err + } + + out0 := *abi.ConvertType(out[0], new(IStakeManagerDepositInfo)).(*IStakeManagerDepositInfo) + + return out0, err + +} + +// GetDepositInfo is a free data retrieval call binding the contract method 0x5287ce12. +// +// Solidity: function getDepositInfo(address account) view returns((uint112,bool,uint112,uint32,uint48) info) +func (_EntryPoint *EntryPointSession) GetDepositInfo(account common.Address) (IStakeManagerDepositInfo, error) { + return _EntryPoint.Contract.GetDepositInfo(&_EntryPoint.CallOpts, account) +} + +// GetDepositInfo is a free data retrieval call binding the contract method 0x5287ce12. +// +// Solidity: function getDepositInfo(address account) view returns((uint112,bool,uint112,uint32,uint48) info) +func (_EntryPoint *EntryPointCallerSession) GetDepositInfo(account common.Address) (IStakeManagerDepositInfo, error) { + return _EntryPoint.Contract.GetDepositInfo(&_EntryPoint.CallOpts, account) +} + +// GetNonce is a free data retrieval call binding the contract method 0x35567e1a. +// +// Solidity: function getNonce(address sender, uint192 key) view returns(uint256 nonce) +func (_EntryPoint *EntryPointCaller) GetNonce(opts *bind.CallOpts, sender common.Address, key *big.Int) (*big.Int, error) { + var out []interface{} + err := _EntryPoint.contract.Call(opts, &out, "getNonce", sender, key) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetNonce is a free data retrieval call binding the contract method 0x35567e1a. +// +// Solidity: function getNonce(address sender, uint192 key) view returns(uint256 nonce) +func (_EntryPoint *EntryPointSession) GetNonce(sender common.Address, key *big.Int) (*big.Int, error) { + return _EntryPoint.Contract.GetNonce(&_EntryPoint.CallOpts, sender, key) +} + +// GetNonce is a free data retrieval call binding the contract method 0x35567e1a. +// +// Solidity: function getNonce(address sender, uint192 key) view returns(uint256 nonce) +func (_EntryPoint *EntryPointCallerSession) GetNonce(sender common.Address, key *big.Int) (*big.Int, error) { + return _EntryPoint.Contract.GetNonce(&_EntryPoint.CallOpts, sender, key) +} + +// GetUserOpHash is a free data retrieval call binding the contract method 0xa6193531. +// +// Solidity: function getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes) userOp) view returns(bytes32) +func (_EntryPoint *EntryPointCaller) GetUserOpHash(opts *bind.CallOpts, userOp UserOperation) ([32]byte, error) { + var out []interface{} + err := _EntryPoint.contract.Call(opts, &out, "getUserOpHash", userOp) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetUserOpHash is a free data retrieval call binding the contract method 0xa6193531. +// +// Solidity: function getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes) userOp) view returns(bytes32) +func (_EntryPoint *EntryPointSession) GetUserOpHash(userOp UserOperation) ([32]byte, error) { + return _EntryPoint.Contract.GetUserOpHash(&_EntryPoint.CallOpts, userOp) +} + +// GetUserOpHash is a free data retrieval call binding the contract method 0xa6193531. +// +// Solidity: function getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes) userOp) view returns(bytes32) +func (_EntryPoint *EntryPointCallerSession) GetUserOpHash(userOp UserOperation) ([32]byte, error) { + return _EntryPoint.Contract.GetUserOpHash(&_EntryPoint.CallOpts, userOp) +} + +// NonceSequenceNumber is a free data retrieval call binding the contract method 0x1b2e01b8. +// +// Solidity: function nonceSequenceNumber(address , uint192 ) view returns(uint256) +func (_EntryPoint *EntryPointCaller) NonceSequenceNumber(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _EntryPoint.contract.Call(opts, &out, "nonceSequenceNumber", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NonceSequenceNumber is a free data retrieval call binding the contract method 0x1b2e01b8. +// +// Solidity: function nonceSequenceNumber(address , uint192 ) view returns(uint256) +func (_EntryPoint *EntryPointSession) NonceSequenceNumber(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { + return _EntryPoint.Contract.NonceSequenceNumber(&_EntryPoint.CallOpts, arg0, arg1) +} + +// NonceSequenceNumber is a free data retrieval call binding the contract method 0x1b2e01b8. +// +// Solidity: function nonceSequenceNumber(address , uint192 ) view returns(uint256) +func (_EntryPoint *EntryPointCallerSession) NonceSequenceNumber(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { + return _EntryPoint.Contract.NonceSequenceNumber(&_EntryPoint.CallOpts, arg0, arg1) +} + +// AddStake is a paid mutator transaction binding the contract method 0x0396cb60. +// +// Solidity: function addStake(uint32 unstakeDelaySec) payable returns() +func (_EntryPoint *EntryPointTransactor) AddStake(opts *bind.TransactOpts, unstakeDelaySec uint32) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "addStake", unstakeDelaySec) +} + +// AddStake is a paid mutator transaction binding the contract method 0x0396cb60. +// +// Solidity: function addStake(uint32 unstakeDelaySec) payable returns() +func (_EntryPoint *EntryPointSession) AddStake(unstakeDelaySec uint32) (*types.Transaction, error) { + return _EntryPoint.Contract.AddStake(&_EntryPoint.TransactOpts, unstakeDelaySec) +} + +// AddStake is a paid mutator transaction binding the contract method 0x0396cb60. +// +// Solidity: function addStake(uint32 unstakeDelaySec) payable returns() +func (_EntryPoint *EntryPointTransactorSession) AddStake(unstakeDelaySec uint32) (*types.Transaction, error) { + return _EntryPoint.Contract.AddStake(&_EntryPoint.TransactOpts, unstakeDelaySec) +} + +// DepositTo is a paid mutator transaction binding the contract method 0xb760faf9. +// +// Solidity: function depositTo(address account) payable returns() +func (_EntryPoint *EntryPointTransactor) DepositTo(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "depositTo", account) +} + +// DepositTo is a paid mutator transaction binding the contract method 0xb760faf9. +// +// Solidity: function depositTo(address account) payable returns() +func (_EntryPoint *EntryPointSession) DepositTo(account common.Address) (*types.Transaction, error) { + return _EntryPoint.Contract.DepositTo(&_EntryPoint.TransactOpts, account) +} + +// DepositTo is a paid mutator transaction binding the contract method 0xb760faf9. +// +// Solidity: function depositTo(address account) payable returns() +func (_EntryPoint *EntryPointTransactorSession) DepositTo(account common.Address) (*types.Transaction, error) { + return _EntryPoint.Contract.DepositTo(&_EntryPoint.TransactOpts, account) +} + +// GetSenderAddress is a paid mutator transaction binding the contract method 0x9b249f69. +// +// Solidity: function getSenderAddress(bytes initCode) returns() +func (_EntryPoint *EntryPointTransactor) GetSenderAddress(opts *bind.TransactOpts, initCode []byte) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "getSenderAddress", initCode) +} + +// GetSenderAddress is a paid mutator transaction binding the contract method 0x9b249f69. +// +// Solidity: function getSenderAddress(bytes initCode) returns() +func (_EntryPoint *EntryPointSession) GetSenderAddress(initCode []byte) (*types.Transaction, error) { + return _EntryPoint.Contract.GetSenderAddress(&_EntryPoint.TransactOpts, initCode) +} + +// GetSenderAddress is a paid mutator transaction binding the contract method 0x9b249f69. +// +// Solidity: function getSenderAddress(bytes initCode) returns() +func (_EntryPoint *EntryPointTransactorSession) GetSenderAddress(initCode []byte) (*types.Transaction, error) { + return _EntryPoint.Contract.GetSenderAddress(&_EntryPoint.TransactOpts, initCode) +} + +// HandleAggregatedOps is a paid mutator transaction binding the contract method 0x4b1d7cf5. +// +// Solidity: function handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[] opsPerAggregator, address beneficiary) returns() +func (_EntryPoint *EntryPointTransactor) HandleAggregatedOps(opts *bind.TransactOpts, opsPerAggregator []IEntryPointUserOpsPerAggregator, beneficiary common.Address) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "handleAggregatedOps", opsPerAggregator, beneficiary) +} + +// HandleAggregatedOps is a paid mutator transaction binding the contract method 0x4b1d7cf5. +// +// Solidity: function handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[] opsPerAggregator, address beneficiary) returns() +func (_EntryPoint *EntryPointSession) HandleAggregatedOps(opsPerAggregator []IEntryPointUserOpsPerAggregator, beneficiary common.Address) (*types.Transaction, error) { + return _EntryPoint.Contract.HandleAggregatedOps(&_EntryPoint.TransactOpts, opsPerAggregator, beneficiary) +} + +// HandleAggregatedOps is a paid mutator transaction binding the contract method 0x4b1d7cf5. +// +// Solidity: function handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[] opsPerAggregator, address beneficiary) returns() +func (_EntryPoint *EntryPointTransactorSession) HandleAggregatedOps(opsPerAggregator []IEntryPointUserOpsPerAggregator, beneficiary common.Address) (*types.Transaction, error) { + return _EntryPoint.Contract.HandleAggregatedOps(&_EntryPoint.TransactOpts, opsPerAggregator, beneficiary) +} + +// HandleOps is a paid mutator transaction binding the contract method 0x1fad948c. +// +// Solidity: function handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[] ops, address beneficiary) returns() +func (_EntryPoint *EntryPointTransactor) HandleOps(opts *bind.TransactOpts, ops []UserOperation, beneficiary common.Address) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "handleOps", ops, beneficiary) +} + +// HandleOps is a paid mutator transaction binding the contract method 0x1fad948c. +// +// Solidity: function handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[] ops, address beneficiary) returns() +func (_EntryPoint *EntryPointSession) HandleOps(ops []UserOperation, beneficiary common.Address) (*types.Transaction, error) { + return _EntryPoint.Contract.HandleOps(&_EntryPoint.TransactOpts, ops, beneficiary) +} + +// HandleOps is a paid mutator transaction binding the contract method 0x1fad948c. +// +// Solidity: function handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[] ops, address beneficiary) returns() +func (_EntryPoint *EntryPointTransactorSession) HandleOps(ops []UserOperation, beneficiary common.Address) (*types.Transaction, error) { + return _EntryPoint.Contract.HandleOps(&_EntryPoint.TransactOpts, ops, beneficiary) +} + +// IncrementNonce is a paid mutator transaction binding the contract method 0x0bd28e3b. +// +// Solidity: function incrementNonce(uint192 key) returns() +func (_EntryPoint *EntryPointTransactor) IncrementNonce(opts *bind.TransactOpts, key *big.Int) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "incrementNonce", key) +} + +// IncrementNonce is a paid mutator transaction binding the contract method 0x0bd28e3b. +// +// Solidity: function incrementNonce(uint192 key) returns() +func (_EntryPoint *EntryPointSession) IncrementNonce(key *big.Int) (*types.Transaction, error) { + return _EntryPoint.Contract.IncrementNonce(&_EntryPoint.TransactOpts, key) +} + +// IncrementNonce is a paid mutator transaction binding the contract method 0x0bd28e3b. +// +// Solidity: function incrementNonce(uint192 key) returns() +func (_EntryPoint *EntryPointTransactorSession) IncrementNonce(key *big.Int) (*types.Transaction, error) { + return _EntryPoint.Contract.IncrementNonce(&_EntryPoint.TransactOpts, key) +} + +// InnerHandleOp is a paid mutator transaction binding the contract method 0x1d732756. +// +// Solidity: function innerHandleOp(bytes callData, ((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256) opInfo, bytes context) returns(uint256 actualGasCost) +func (_EntryPoint *EntryPointTransactor) InnerHandleOp(opts *bind.TransactOpts, callData []byte, opInfo EntryPointUserOpInfo, context []byte) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "innerHandleOp", callData, opInfo, context) +} + +// InnerHandleOp is a paid mutator transaction binding the contract method 0x1d732756. +// +// Solidity: function innerHandleOp(bytes callData, ((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256) opInfo, bytes context) returns(uint256 actualGasCost) +func (_EntryPoint *EntryPointSession) InnerHandleOp(callData []byte, opInfo EntryPointUserOpInfo, context []byte) (*types.Transaction, error) { + return _EntryPoint.Contract.InnerHandleOp(&_EntryPoint.TransactOpts, callData, opInfo, context) +} + +// InnerHandleOp is a paid mutator transaction binding the contract method 0x1d732756. +// +// Solidity: function innerHandleOp(bytes callData, ((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256) opInfo, bytes context) returns(uint256 actualGasCost) +func (_EntryPoint *EntryPointTransactorSession) InnerHandleOp(callData []byte, opInfo EntryPointUserOpInfo, context []byte) (*types.Transaction, error) { + return _EntryPoint.Contract.InnerHandleOp(&_EntryPoint.TransactOpts, callData, opInfo, context) +} + +// SimulateHandleOp is a paid mutator transaction binding the contract method 0xd6383f94. +// +// Solidity: function simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes) op, address target, bytes targetCallData) returns() +func (_EntryPoint *EntryPointTransactor) SimulateHandleOp(opts *bind.TransactOpts, op UserOperation, target common.Address, targetCallData []byte) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "simulateHandleOp", op, target, targetCallData) +} + +// SimulateHandleOp is a paid mutator transaction binding the contract method 0xd6383f94. +// +// Solidity: function simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes) op, address target, bytes targetCallData) returns() +func (_EntryPoint *EntryPointSession) SimulateHandleOp(op UserOperation, target common.Address, targetCallData []byte) (*types.Transaction, error) { + return _EntryPoint.Contract.SimulateHandleOp(&_EntryPoint.TransactOpts, op, target, targetCallData) +} + +// SimulateHandleOp is a paid mutator transaction binding the contract method 0xd6383f94. +// +// Solidity: function simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes) op, address target, bytes targetCallData) returns() +func (_EntryPoint *EntryPointTransactorSession) SimulateHandleOp(op UserOperation, target common.Address, targetCallData []byte) (*types.Transaction, error) { + return _EntryPoint.Contract.SimulateHandleOp(&_EntryPoint.TransactOpts, op, target, targetCallData) +} + +// SimulateValidation is a paid mutator transaction binding the contract method 0xee219423. +// +// Solidity: function simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes) userOp) returns() +func (_EntryPoint *EntryPointTransactor) SimulateValidation(opts *bind.TransactOpts, userOp UserOperation) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "simulateValidation", userOp) +} + +// SimulateValidation is a paid mutator transaction binding the contract method 0xee219423. +// +// Solidity: function simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes) userOp) returns() +func (_EntryPoint *EntryPointSession) SimulateValidation(userOp UserOperation) (*types.Transaction, error) { + return _EntryPoint.Contract.SimulateValidation(&_EntryPoint.TransactOpts, userOp) +} + +// SimulateValidation is a paid mutator transaction binding the contract method 0xee219423. +// +// Solidity: function simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes) userOp) returns() +func (_EntryPoint *EntryPointTransactorSession) SimulateValidation(userOp UserOperation) (*types.Transaction, error) { + return _EntryPoint.Contract.SimulateValidation(&_EntryPoint.TransactOpts, userOp) +} + +// UnlockStake is a paid mutator transaction binding the contract method 0xbb9fe6bf. +// +// Solidity: function unlockStake() returns() +func (_EntryPoint *EntryPointTransactor) UnlockStake(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "unlockStake") +} + +// UnlockStake is a paid mutator transaction binding the contract method 0xbb9fe6bf. +// +// Solidity: function unlockStake() returns() +func (_EntryPoint *EntryPointSession) UnlockStake() (*types.Transaction, error) { + return _EntryPoint.Contract.UnlockStake(&_EntryPoint.TransactOpts) +} + +// UnlockStake is a paid mutator transaction binding the contract method 0xbb9fe6bf. +// +// Solidity: function unlockStake() returns() +func (_EntryPoint *EntryPointTransactorSession) UnlockStake() (*types.Transaction, error) { + return _EntryPoint.Contract.UnlockStake(&_EntryPoint.TransactOpts) +} + +// WithdrawStake is a paid mutator transaction binding the contract method 0xc23a5cea. +// +// Solidity: function withdrawStake(address withdrawAddress) returns() +func (_EntryPoint *EntryPointTransactor) WithdrawStake(opts *bind.TransactOpts, withdrawAddress common.Address) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "withdrawStake", withdrawAddress) +} + +// WithdrawStake is a paid mutator transaction binding the contract method 0xc23a5cea. +// +// Solidity: function withdrawStake(address withdrawAddress) returns() +func (_EntryPoint *EntryPointSession) WithdrawStake(withdrawAddress common.Address) (*types.Transaction, error) { + return _EntryPoint.Contract.WithdrawStake(&_EntryPoint.TransactOpts, withdrawAddress) +} + +// WithdrawStake is a paid mutator transaction binding the contract method 0xc23a5cea. +// +// Solidity: function withdrawStake(address withdrawAddress) returns() +func (_EntryPoint *EntryPointTransactorSession) WithdrawStake(withdrawAddress common.Address) (*types.Transaction, error) { + return _EntryPoint.Contract.WithdrawStake(&_EntryPoint.TransactOpts, withdrawAddress) +} + +// WithdrawTo is a paid mutator transaction binding the contract method 0x205c2878. +// +// Solidity: function withdrawTo(address withdrawAddress, uint256 withdrawAmount) returns() +func (_EntryPoint *EntryPointTransactor) WithdrawTo(opts *bind.TransactOpts, withdrawAddress common.Address, withdrawAmount *big.Int) (*types.Transaction, error) { + return _EntryPoint.contract.Transact(opts, "withdrawTo", withdrawAddress, withdrawAmount) +} + +// WithdrawTo is a paid mutator transaction binding the contract method 0x205c2878. +// +// Solidity: function withdrawTo(address withdrawAddress, uint256 withdrawAmount) returns() +func (_EntryPoint *EntryPointSession) WithdrawTo(withdrawAddress common.Address, withdrawAmount *big.Int) (*types.Transaction, error) { + return _EntryPoint.Contract.WithdrawTo(&_EntryPoint.TransactOpts, withdrawAddress, withdrawAmount) +} + +// WithdrawTo is a paid mutator transaction binding the contract method 0x205c2878. +// +// Solidity: function withdrawTo(address withdrawAddress, uint256 withdrawAmount) returns() +func (_EntryPoint *EntryPointTransactorSession) WithdrawTo(withdrawAddress common.Address, withdrawAmount *big.Int) (*types.Transaction, error) { + return _EntryPoint.Contract.WithdrawTo(&_EntryPoint.TransactOpts, withdrawAddress, withdrawAmount) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_EntryPoint *EntryPointTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EntryPoint.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_EntryPoint *EntryPointSession) Receive() (*types.Transaction, error) { + return _EntryPoint.Contract.Receive(&_EntryPoint.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_EntryPoint *EntryPointTransactorSession) Receive() (*types.Transaction, error) { + return _EntryPoint.Contract.Receive(&_EntryPoint.TransactOpts) +} + +// EntryPointAccountDeployedIterator is returned from FilterAccountDeployed and is used to iterate over the raw logs and unpacked data for AccountDeployed events raised by the EntryPoint contract. +type EntryPointAccountDeployedIterator struct { + Event *EntryPointAccountDeployed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EntryPointAccountDeployedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EntryPointAccountDeployed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EntryPointAccountDeployed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EntryPointAccountDeployedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EntryPointAccountDeployedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EntryPointAccountDeployed represents a AccountDeployed event raised by the EntryPoint contract. +type EntryPointAccountDeployed struct { + UserOpHash [32]byte + Sender common.Address + Factory common.Address + Paymaster common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAccountDeployed is a free log retrieval operation binding the contract event 0xd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d. +// +// Solidity: event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster) +func (_EntryPoint *EntryPointFilterer) FilterAccountDeployed(opts *bind.FilterOpts, userOpHash [][32]byte, sender []common.Address) (*EntryPointAccountDeployedIterator, error) { + + var userOpHashRule []interface{} + for _, userOpHashItem := range userOpHash { + userOpHashRule = append(userOpHashRule, userOpHashItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EntryPoint.contract.FilterLogs(opts, "AccountDeployed", userOpHashRule, senderRule) + if err != nil { + return nil, err + } + return &EntryPointAccountDeployedIterator{contract: _EntryPoint.contract, event: "AccountDeployed", logs: logs, sub: sub}, nil +} + +// WatchAccountDeployed is a free log subscription operation binding the contract event 0xd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d. +// +// Solidity: event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster) +func (_EntryPoint *EntryPointFilterer) WatchAccountDeployed(opts *bind.WatchOpts, sink chan<- *EntryPointAccountDeployed, userOpHash [][32]byte, sender []common.Address) (event.Subscription, error) { + + var userOpHashRule []interface{} + for _, userOpHashItem := range userOpHash { + userOpHashRule = append(userOpHashRule, userOpHashItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EntryPoint.contract.WatchLogs(opts, "AccountDeployed", userOpHashRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EntryPointAccountDeployed) + if err := _EntryPoint.contract.UnpackLog(event, "AccountDeployed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAccountDeployed is a log parse operation binding the contract event 0xd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d. +// +// Solidity: event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster) +func (_EntryPoint *EntryPointFilterer) ParseAccountDeployed(log types.Log) (*EntryPointAccountDeployed, error) { + event := new(EntryPointAccountDeployed) + if err := _EntryPoint.contract.UnpackLog(event, "AccountDeployed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EntryPointBeforeExecutionIterator is returned from FilterBeforeExecution and is used to iterate over the raw logs and unpacked data for BeforeExecution events raised by the EntryPoint contract. +type EntryPointBeforeExecutionIterator struct { + Event *EntryPointBeforeExecution // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EntryPointBeforeExecutionIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EntryPointBeforeExecution) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EntryPointBeforeExecution) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EntryPointBeforeExecutionIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EntryPointBeforeExecutionIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EntryPointBeforeExecution represents a BeforeExecution event raised by the EntryPoint contract. +type EntryPointBeforeExecution struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBeforeExecution is a free log retrieval operation binding the contract event 0xbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972. +// +// Solidity: event BeforeExecution() +func (_EntryPoint *EntryPointFilterer) FilterBeforeExecution(opts *bind.FilterOpts) (*EntryPointBeforeExecutionIterator, error) { + + logs, sub, err := _EntryPoint.contract.FilterLogs(opts, "BeforeExecution") + if err != nil { + return nil, err + } + return &EntryPointBeforeExecutionIterator{contract: _EntryPoint.contract, event: "BeforeExecution", logs: logs, sub: sub}, nil +} + +// WatchBeforeExecution is a free log subscription operation binding the contract event 0xbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972. +// +// Solidity: event BeforeExecution() +func (_EntryPoint *EntryPointFilterer) WatchBeforeExecution(opts *bind.WatchOpts, sink chan<- *EntryPointBeforeExecution) (event.Subscription, error) { + + logs, sub, err := _EntryPoint.contract.WatchLogs(opts, "BeforeExecution") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EntryPointBeforeExecution) + if err := _EntryPoint.contract.UnpackLog(event, "BeforeExecution", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseBeforeExecution is a log parse operation binding the contract event 0xbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972. +// +// Solidity: event BeforeExecution() +func (_EntryPoint *EntryPointFilterer) ParseBeforeExecution(log types.Log) (*EntryPointBeforeExecution, error) { + event := new(EntryPointBeforeExecution) + if err := _EntryPoint.contract.UnpackLog(event, "BeforeExecution", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EntryPointDepositedIterator is returned from FilterDeposited and is used to iterate over the raw logs and unpacked data for Deposited events raised by the EntryPoint contract. +type EntryPointDepositedIterator struct { + Event *EntryPointDeposited // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EntryPointDepositedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EntryPointDeposited) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EntryPointDeposited) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EntryPointDepositedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EntryPointDepositedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EntryPointDeposited represents a Deposited event raised by the EntryPoint contract. +type EntryPointDeposited struct { + Account common.Address + TotalDeposit *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDeposited is a free log retrieval operation binding the contract event 0x2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4. +// +// Solidity: event Deposited(address indexed account, uint256 totalDeposit) +func (_EntryPoint *EntryPointFilterer) FilterDeposited(opts *bind.FilterOpts, account []common.Address) (*EntryPointDepositedIterator, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _EntryPoint.contract.FilterLogs(opts, "Deposited", accountRule) + if err != nil { + return nil, err + } + return &EntryPointDepositedIterator{contract: _EntryPoint.contract, event: "Deposited", logs: logs, sub: sub}, nil +} + +// WatchDeposited is a free log subscription operation binding the contract event 0x2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4. +// +// Solidity: event Deposited(address indexed account, uint256 totalDeposit) +func (_EntryPoint *EntryPointFilterer) WatchDeposited(opts *bind.WatchOpts, sink chan<- *EntryPointDeposited, account []common.Address) (event.Subscription, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _EntryPoint.contract.WatchLogs(opts, "Deposited", accountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EntryPointDeposited) + if err := _EntryPoint.contract.UnpackLog(event, "Deposited", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDeposited is a log parse operation binding the contract event 0x2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4. +// +// Solidity: event Deposited(address indexed account, uint256 totalDeposit) +func (_EntryPoint *EntryPointFilterer) ParseDeposited(log types.Log) (*EntryPointDeposited, error) { + event := new(EntryPointDeposited) + if err := _EntryPoint.contract.UnpackLog(event, "Deposited", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EntryPointSignatureAggregatorChangedIterator is returned from FilterSignatureAggregatorChanged and is used to iterate over the raw logs and unpacked data for SignatureAggregatorChanged events raised by the EntryPoint contract. +type EntryPointSignatureAggregatorChangedIterator struct { + Event *EntryPointSignatureAggregatorChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EntryPointSignatureAggregatorChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EntryPointSignatureAggregatorChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EntryPointSignatureAggregatorChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EntryPointSignatureAggregatorChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EntryPointSignatureAggregatorChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EntryPointSignatureAggregatorChanged represents a SignatureAggregatorChanged event raised by the EntryPoint contract. +type EntryPointSignatureAggregatorChanged struct { + Aggregator common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSignatureAggregatorChanged is a free log retrieval operation binding the contract event 0x575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d. +// +// Solidity: event SignatureAggregatorChanged(address indexed aggregator) +func (_EntryPoint *EntryPointFilterer) FilterSignatureAggregatorChanged(opts *bind.FilterOpts, aggregator []common.Address) (*EntryPointSignatureAggregatorChangedIterator, error) { + + var aggregatorRule []interface{} + for _, aggregatorItem := range aggregator { + aggregatorRule = append(aggregatorRule, aggregatorItem) + } + + logs, sub, err := _EntryPoint.contract.FilterLogs(opts, "SignatureAggregatorChanged", aggregatorRule) + if err != nil { + return nil, err + } + return &EntryPointSignatureAggregatorChangedIterator{contract: _EntryPoint.contract, event: "SignatureAggregatorChanged", logs: logs, sub: sub}, nil +} + +// WatchSignatureAggregatorChanged is a free log subscription operation binding the contract event 0x575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d. +// +// Solidity: event SignatureAggregatorChanged(address indexed aggregator) +func (_EntryPoint *EntryPointFilterer) WatchSignatureAggregatorChanged(opts *bind.WatchOpts, sink chan<- *EntryPointSignatureAggregatorChanged, aggregator []common.Address) (event.Subscription, error) { + + var aggregatorRule []interface{} + for _, aggregatorItem := range aggregator { + aggregatorRule = append(aggregatorRule, aggregatorItem) + } + + logs, sub, err := _EntryPoint.contract.WatchLogs(opts, "SignatureAggregatorChanged", aggregatorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EntryPointSignatureAggregatorChanged) + if err := _EntryPoint.contract.UnpackLog(event, "SignatureAggregatorChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSignatureAggregatorChanged is a log parse operation binding the contract event 0x575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d. +// +// Solidity: event SignatureAggregatorChanged(address indexed aggregator) +func (_EntryPoint *EntryPointFilterer) ParseSignatureAggregatorChanged(log types.Log) (*EntryPointSignatureAggregatorChanged, error) { + event := new(EntryPointSignatureAggregatorChanged) + if err := _EntryPoint.contract.UnpackLog(event, "SignatureAggregatorChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EntryPointStakeLockedIterator is returned from FilterStakeLocked and is used to iterate over the raw logs and unpacked data for StakeLocked events raised by the EntryPoint contract. +type EntryPointStakeLockedIterator struct { + Event *EntryPointStakeLocked // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EntryPointStakeLockedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EntryPointStakeLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EntryPointStakeLocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EntryPointStakeLockedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EntryPointStakeLockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EntryPointStakeLocked represents a StakeLocked event raised by the EntryPoint contract. +type EntryPointStakeLocked struct { + Account common.Address + TotalStaked *big.Int + UnstakeDelaySec *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStakeLocked is a free log retrieval operation binding the contract event 0xa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01. +// +// Solidity: event StakeLocked(address indexed account, uint256 totalStaked, uint256 unstakeDelaySec) +func (_EntryPoint *EntryPointFilterer) FilterStakeLocked(opts *bind.FilterOpts, account []common.Address) (*EntryPointStakeLockedIterator, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _EntryPoint.contract.FilterLogs(opts, "StakeLocked", accountRule) + if err != nil { + return nil, err + } + return &EntryPointStakeLockedIterator{contract: _EntryPoint.contract, event: "StakeLocked", logs: logs, sub: sub}, nil +} + +// WatchStakeLocked is a free log subscription operation binding the contract event 0xa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01. +// +// Solidity: event StakeLocked(address indexed account, uint256 totalStaked, uint256 unstakeDelaySec) +func (_EntryPoint *EntryPointFilterer) WatchStakeLocked(opts *bind.WatchOpts, sink chan<- *EntryPointStakeLocked, account []common.Address) (event.Subscription, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _EntryPoint.contract.WatchLogs(opts, "StakeLocked", accountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EntryPointStakeLocked) + if err := _EntryPoint.contract.UnpackLog(event, "StakeLocked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseStakeLocked is a log parse operation binding the contract event 0xa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01. +// +// Solidity: event StakeLocked(address indexed account, uint256 totalStaked, uint256 unstakeDelaySec) +func (_EntryPoint *EntryPointFilterer) ParseStakeLocked(log types.Log) (*EntryPointStakeLocked, error) { + event := new(EntryPointStakeLocked) + if err := _EntryPoint.contract.UnpackLog(event, "StakeLocked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EntryPointStakeUnlockedIterator is returned from FilterStakeUnlocked and is used to iterate over the raw logs and unpacked data for StakeUnlocked events raised by the EntryPoint contract. +type EntryPointStakeUnlockedIterator struct { + Event *EntryPointStakeUnlocked // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EntryPointStakeUnlockedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EntryPointStakeUnlocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EntryPointStakeUnlocked) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EntryPointStakeUnlockedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EntryPointStakeUnlockedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EntryPointStakeUnlocked represents a StakeUnlocked event raised by the EntryPoint contract. +type EntryPointStakeUnlocked struct { + Account common.Address + WithdrawTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStakeUnlocked is a free log retrieval operation binding the contract event 0xfa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a. +// +// Solidity: event StakeUnlocked(address indexed account, uint256 withdrawTime) +func (_EntryPoint *EntryPointFilterer) FilterStakeUnlocked(opts *bind.FilterOpts, account []common.Address) (*EntryPointStakeUnlockedIterator, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _EntryPoint.contract.FilterLogs(opts, "StakeUnlocked", accountRule) + if err != nil { + return nil, err + } + return &EntryPointStakeUnlockedIterator{contract: _EntryPoint.contract, event: "StakeUnlocked", logs: logs, sub: sub}, nil +} + +// WatchStakeUnlocked is a free log subscription operation binding the contract event 0xfa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a. +// +// Solidity: event StakeUnlocked(address indexed account, uint256 withdrawTime) +func (_EntryPoint *EntryPointFilterer) WatchStakeUnlocked(opts *bind.WatchOpts, sink chan<- *EntryPointStakeUnlocked, account []common.Address) (event.Subscription, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _EntryPoint.contract.WatchLogs(opts, "StakeUnlocked", accountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EntryPointStakeUnlocked) + if err := _EntryPoint.contract.UnpackLog(event, "StakeUnlocked", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseStakeUnlocked is a log parse operation binding the contract event 0xfa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a. +// +// Solidity: event StakeUnlocked(address indexed account, uint256 withdrawTime) +func (_EntryPoint *EntryPointFilterer) ParseStakeUnlocked(log types.Log) (*EntryPointStakeUnlocked, error) { + event := new(EntryPointStakeUnlocked) + if err := _EntryPoint.contract.UnpackLog(event, "StakeUnlocked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EntryPointStakeWithdrawnIterator is returned from FilterStakeWithdrawn and is used to iterate over the raw logs and unpacked data for StakeWithdrawn events raised by the EntryPoint contract. +type EntryPointStakeWithdrawnIterator struct { + Event *EntryPointStakeWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EntryPointStakeWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EntryPointStakeWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EntryPointStakeWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EntryPointStakeWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EntryPointStakeWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EntryPointStakeWithdrawn represents a StakeWithdrawn event raised by the EntryPoint contract. +type EntryPointStakeWithdrawn struct { + Account common.Address + WithdrawAddress common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStakeWithdrawn is a free log retrieval operation binding the contract event 0xb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda3. +// +// Solidity: event StakeWithdrawn(address indexed account, address withdrawAddress, uint256 amount) +func (_EntryPoint *EntryPointFilterer) FilterStakeWithdrawn(opts *bind.FilterOpts, account []common.Address) (*EntryPointStakeWithdrawnIterator, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _EntryPoint.contract.FilterLogs(opts, "StakeWithdrawn", accountRule) + if err != nil { + return nil, err + } + return &EntryPointStakeWithdrawnIterator{contract: _EntryPoint.contract, event: "StakeWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchStakeWithdrawn is a free log subscription operation binding the contract event 0xb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda3. +// +// Solidity: event StakeWithdrawn(address indexed account, address withdrawAddress, uint256 amount) +func (_EntryPoint *EntryPointFilterer) WatchStakeWithdrawn(opts *bind.WatchOpts, sink chan<- *EntryPointStakeWithdrawn, account []common.Address) (event.Subscription, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _EntryPoint.contract.WatchLogs(opts, "StakeWithdrawn", accountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EntryPointStakeWithdrawn) + if err := _EntryPoint.contract.UnpackLog(event, "StakeWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseStakeWithdrawn is a log parse operation binding the contract event 0xb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda3. +// +// Solidity: event StakeWithdrawn(address indexed account, address withdrawAddress, uint256 amount) +func (_EntryPoint *EntryPointFilterer) ParseStakeWithdrawn(log types.Log) (*EntryPointStakeWithdrawn, error) { + event := new(EntryPointStakeWithdrawn) + if err := _EntryPoint.contract.UnpackLog(event, "StakeWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EntryPointUserOperationEventIterator is returned from FilterUserOperationEvent and is used to iterate over the raw logs and unpacked data for UserOperationEvent events raised by the EntryPoint contract. +type EntryPointUserOperationEventIterator struct { + Event *EntryPointUserOperationEvent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EntryPointUserOperationEventIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EntryPointUserOperationEvent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EntryPointUserOperationEvent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EntryPointUserOperationEventIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EntryPointUserOperationEventIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EntryPointUserOperationEvent represents a UserOperationEvent event raised by the EntryPoint contract. +type EntryPointUserOperationEvent struct { + UserOpHash [32]byte + Sender common.Address + Paymaster common.Address + Nonce *big.Int + Success bool + ActualGasCost *big.Int + ActualGasUsed *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUserOperationEvent is a free log retrieval operation binding the contract event 0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f. +// +// Solidity: event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed) +func (_EntryPoint *EntryPointFilterer) FilterUserOperationEvent(opts *bind.FilterOpts, userOpHash [][32]byte, sender []common.Address, paymaster []common.Address) (*EntryPointUserOperationEventIterator, error) { + + var userOpHashRule []interface{} + for _, userOpHashItem := range userOpHash { + userOpHashRule = append(userOpHashRule, userOpHashItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var paymasterRule []interface{} + for _, paymasterItem := range paymaster { + paymasterRule = append(paymasterRule, paymasterItem) + } + + logs, sub, err := _EntryPoint.contract.FilterLogs(opts, "UserOperationEvent", userOpHashRule, senderRule, paymasterRule) + if err != nil { + return nil, err + } + return &EntryPointUserOperationEventIterator{contract: _EntryPoint.contract, event: "UserOperationEvent", logs: logs, sub: sub}, nil +} + +// WatchUserOperationEvent is a free log subscription operation binding the contract event 0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f. +// +// Solidity: event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed) +func (_EntryPoint *EntryPointFilterer) WatchUserOperationEvent(opts *bind.WatchOpts, sink chan<- *EntryPointUserOperationEvent, userOpHash [][32]byte, sender []common.Address, paymaster []common.Address) (event.Subscription, error) { + + var userOpHashRule []interface{} + for _, userOpHashItem := range userOpHash { + userOpHashRule = append(userOpHashRule, userOpHashItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var paymasterRule []interface{} + for _, paymasterItem := range paymaster { + paymasterRule = append(paymasterRule, paymasterItem) + } + + logs, sub, err := _EntryPoint.contract.WatchLogs(opts, "UserOperationEvent", userOpHashRule, senderRule, paymasterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EntryPointUserOperationEvent) + if err := _EntryPoint.contract.UnpackLog(event, "UserOperationEvent", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUserOperationEvent is a log parse operation binding the contract event 0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f. +// +// Solidity: event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed) +func (_EntryPoint *EntryPointFilterer) ParseUserOperationEvent(log types.Log) (*EntryPointUserOperationEvent, error) { + event := new(EntryPointUserOperationEvent) + if err := _EntryPoint.contract.UnpackLog(event, "UserOperationEvent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EntryPointUserOperationRevertReasonIterator is returned from FilterUserOperationRevertReason and is used to iterate over the raw logs and unpacked data for UserOperationRevertReason events raised by the EntryPoint contract. +type EntryPointUserOperationRevertReasonIterator struct { + Event *EntryPointUserOperationRevertReason // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EntryPointUserOperationRevertReasonIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EntryPointUserOperationRevertReason) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EntryPointUserOperationRevertReason) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EntryPointUserOperationRevertReasonIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EntryPointUserOperationRevertReasonIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EntryPointUserOperationRevertReason represents a UserOperationRevertReason event raised by the EntryPoint contract. +type EntryPointUserOperationRevertReason struct { + UserOpHash [32]byte + Sender common.Address + Nonce *big.Int + RevertReason []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUserOperationRevertReason is a free log retrieval operation binding the contract event 0x1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a201. +// +// Solidity: event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason) +func (_EntryPoint *EntryPointFilterer) FilterUserOperationRevertReason(opts *bind.FilterOpts, userOpHash [][32]byte, sender []common.Address) (*EntryPointUserOperationRevertReasonIterator, error) { + + var userOpHashRule []interface{} + for _, userOpHashItem := range userOpHash { + userOpHashRule = append(userOpHashRule, userOpHashItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EntryPoint.contract.FilterLogs(opts, "UserOperationRevertReason", userOpHashRule, senderRule) + if err != nil { + return nil, err + } + return &EntryPointUserOperationRevertReasonIterator{contract: _EntryPoint.contract, event: "UserOperationRevertReason", logs: logs, sub: sub}, nil +} + +// WatchUserOperationRevertReason is a free log subscription operation binding the contract event 0x1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a201. +// +// Solidity: event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason) +func (_EntryPoint *EntryPointFilterer) WatchUserOperationRevertReason(opts *bind.WatchOpts, sink chan<- *EntryPointUserOperationRevertReason, userOpHash [][32]byte, sender []common.Address) (event.Subscription, error) { + + var userOpHashRule []interface{} + for _, userOpHashItem := range userOpHash { + userOpHashRule = append(userOpHashRule, userOpHashItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _EntryPoint.contract.WatchLogs(opts, "UserOperationRevertReason", userOpHashRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EntryPointUserOperationRevertReason) + if err := _EntryPoint.contract.UnpackLog(event, "UserOperationRevertReason", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUserOperationRevertReason is a log parse operation binding the contract event 0x1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a201. +// +// Solidity: event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason) +func (_EntryPoint *EntryPointFilterer) ParseUserOperationRevertReason(log types.Log) (*EntryPointUserOperationRevertReason, error) { + event := new(EntryPointUserOperationRevertReason) + if err := _EntryPoint.contract.UnpackLog(event, "UserOperationRevertReason", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EntryPointWithdrawnIterator is returned from FilterWithdrawn and is used to iterate over the raw logs and unpacked data for Withdrawn events raised by the EntryPoint contract. +type EntryPointWithdrawnIterator struct { + Event *EntryPointWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EntryPointWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EntryPointWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EntryPointWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EntryPointWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EntryPointWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EntryPointWithdrawn represents a Withdrawn event raised by the EntryPoint contract. +type EntryPointWithdrawn struct { + Account common.Address + WithdrawAddress common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdrawn is a free log retrieval operation binding the contract event 0xd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb. +// +// Solidity: event Withdrawn(address indexed account, address withdrawAddress, uint256 amount) +func (_EntryPoint *EntryPointFilterer) FilterWithdrawn(opts *bind.FilterOpts, account []common.Address) (*EntryPointWithdrawnIterator, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _EntryPoint.contract.FilterLogs(opts, "Withdrawn", accountRule) + if err != nil { + return nil, err + } + return &EntryPointWithdrawnIterator{contract: _EntryPoint.contract, event: "Withdrawn", logs: logs, sub: sub}, nil +} + +// WatchWithdrawn is a free log subscription operation binding the contract event 0xd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb. +// +// Solidity: event Withdrawn(address indexed account, address withdrawAddress, uint256 amount) +func (_EntryPoint *EntryPointFilterer) WatchWithdrawn(opts *bind.WatchOpts, sink chan<- *EntryPointWithdrawn, account []common.Address) (event.Subscription, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _EntryPoint.contract.WatchLogs(opts, "Withdrawn", accountRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EntryPointWithdrawn) + if err := _EntryPoint.contract.UnpackLog(event, "Withdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseWithdrawn is a log parse operation binding the contract event 0xd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb. +// +// Solidity: event Withdrawn(address indexed account, address withdrawAddress, uint256 amount) +func (_EntryPoint *EntryPointFilterer) ParseWithdrawn(log types.Log) (*EntryPointWithdrawn, error) { + event := new(EntryPointWithdrawn) + if err := _EntryPoint.contract.UnpackLog(event, "Withdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-bindings/bindings/entrypoint_more.go b/op-bindings/bindings/entrypoint_more.go new file mode 100644 index 000000000000..847b0d7d9d01 --- /dev/null +++ b/op-bindings/bindings/entrypoint_more.go @@ -0,0 +1,9 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var EntryPointDeployedBin = "0x60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000007fc98430eaedbb6070b35b39d798725049088348165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f0000000000000000000000007fc98430eaedbb6070b35b39d7987250490883481690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f0000000000000000000000007fc98430eaedbb6070b35b39d7987250490883481690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033" +func init() { + deployedBytecodes["EntryPoint"] = EntryPointDeployedBin +} diff --git a/op-bindings/bindings/erc20.go b/op-bindings/bindings/erc20.go index 766f6eb69b11..e2ca076125b7 100644 --- a/op-bindings/bindings/erc20.go +++ b/op-bindings/bindings/erc20.go @@ -30,7 +30,7 @@ var ( // ERC20MetaData contains all meta data concerning the ERC20 contract. var ERC20MetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"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\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"name_\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"symbol_\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"allowance\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"decimals\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"decreaseAllowance\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"subtractedValue\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"increaseAllowance\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"addedValue\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalSupply\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transfer\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", Bin: "0x60806040523480156200001157600080fd5b5060405162000e3c38038062000e3c833981016040819052620000349162000127565b600362000042838262000220565b50600462000051828262000220565b505050620002ec565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008257600080fd5b81516001600160401b03808211156200009f576200009f6200005a565b604051601f8301601f19908116603f01168101908282118183101715620000ca57620000ca6200005a565b81604052838152602092508683858801011115620000e757600080fd5b600091505b838210156200010b5785820183015181830184015290820190620000ec565b838211156200011d5760008385830101525b9695505050505050565b600080604083850312156200013b57600080fd5b82516001600160401b03808211156200015357600080fd5b620001618683870162000070565b935060208501519150808211156200017857600080fd5b50620001878582860162000070565b9150509250929050565b600181811c90821680620001a657607f821691505b602082108103620001c757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021b57600081815260208120601f850160051c81016020861015620001f65750805b601f850160051c820191505b81811015620002175782815560010162000202565b5050505b505050565b81516001600160401b038111156200023c576200023c6200005a565b62000254816200024d845462000191565b84620001cd565b602080601f8311600181146200028c5760008415620002735750858301515b600019600386901b1c1916600185901b17855562000217565b600085815260208120601f198616915b82811015620002bd578886015182559484019460019091019084016200029c565b5085821015620002dc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610b4080620002fc6000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80633950935111610081578063a457c2d71161005b578063a457c2d714610194578063a9059cbb146101a7578063dd62ed3e146101ba57600080fd5b8063395093511461014357806370a082311461015657806395d89b411461018c57600080fd5b806318160ddd116100b257806318160ddd1461010f57806323b872dd14610121578063313ce5671461013457600080fd5b806306fdde03146100ce578063095ea7b3146100ec575b600080fd5b6100d6610200565b6040516100e3919061094a565b60405180910390f35b6100ff6100fa3660046109e6565b610292565b60405190151581526020016100e3565b6002545b6040519081526020016100e3565b6100ff61012f366004610a10565b6102aa565b604051601281526020016100e3565b6100ff6101513660046109e6565b6102ce565b610113610164366004610a4c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6100d661031a565b6100ff6101a23660046109e6565b610329565b6100ff6101b53660046109e6565b6103ff565b6101136101c8366004610a6e565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60606003805461020f90610aa1565b80601f016020809104026020016040519081016040528092919081815260200182805461023b90610aa1565b80156102885780601f1061025d57610100808354040283529160200191610288565b820191906000526020600020905b81548152906001019060200180831161026b57829003601f168201915b5050505050905090565b6000336102a081858561040d565b5060019392505050565b6000336102b88582856105c0565b6102c3858585610697565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906102a09082908690610315908790610af4565b61040d565b60606004805461020f90610aa1565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156103f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102c3828686840361040d565b6000336102a0818585610697565b73ffffffffffffffffffffffffffffffffffffffff83166104af576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff8216610552576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146106915781811015610684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103e9565b610691848484840361040d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff831661073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff82166107dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610893576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152602081905260408082208585039055918516815290812080548492906108d7908490610af4565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161093d91815260200190565b60405180910390a3610691565b600060208083528351808285015260005b818110156109775785810183015185820160400152820161095b565b81811115610989576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146109e157600080fd5b919050565b600080604083850312156109f957600080fd5b610a02836109bd565b946020939093013593505050565b600080600060608486031215610a2557600080fd5b610a2e846109bd565b9250610a3c602085016109bd565b9150604084013590509250925092565b600060208284031215610a5e57600080fd5b610a67826109bd565b9392505050565b60008060408385031215610a8157600080fd5b610a8a836109bd565b9150610a98602084016109bd565b90509250929050565b600181811c90821680610ab557607f821691505b602082108103610aee577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008219821115610b2e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/erc20_more.go b/op-bindings/bindings/erc20_more.go index 11a76077e57a..fa16335c9f64 100644 --- a/op-bindings/bindings/erc20_more.go +++ b/op-bindings/bindings/erc20_more.go @@ -15,6 +15,7 @@ var ERC20StorageLayout = new(solc.StorageLayout) var ERC20DeployedBin = "0x608060405234801561001057600080fd5b50600436106100c95760003560e01c80633950935111610081578063a457c2d71161005b578063a457c2d714610194578063a9059cbb146101a7578063dd62ed3e146101ba57600080fd5b8063395093511461014357806370a082311461015657806395d89b411461018c57600080fd5b806318160ddd116100b257806318160ddd1461010f57806323b872dd14610121578063313ce5671461013457600080fd5b806306fdde03146100ce578063095ea7b3146100ec575b600080fd5b6100d6610200565b6040516100e3919061094a565b60405180910390f35b6100ff6100fa3660046109e6565b610292565b60405190151581526020016100e3565b6002545b6040519081526020016100e3565b6100ff61012f366004610a10565b6102aa565b604051601281526020016100e3565b6100ff6101513660046109e6565b6102ce565b610113610164366004610a4c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6100d661031a565b6100ff6101a23660046109e6565b610329565b6100ff6101b53660046109e6565b6103ff565b6101136101c8366004610a6e565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60606003805461020f90610aa1565b80601f016020809104026020016040519081016040528092919081815260200182805461023b90610aa1565b80156102885780601f1061025d57610100808354040283529160200191610288565b820191906000526020600020905b81548152906001019060200180831161026b57829003601f168201915b5050505050905090565b6000336102a081858561040d565b5060019392505050565b6000336102b88582856105c0565b6102c3858585610697565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906102a09082908690610315908790610af4565b61040d565b60606004805461020f90610aa1565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156103f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102c3828686840361040d565b6000336102a0818585610697565b73ffffffffffffffffffffffffffffffffffffffff83166104af576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff8216610552576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146106915781811015610684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103e9565b610691848484840361040d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff831661073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff82166107dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610893576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152602081905260408082208585039055918516815290812080548492906108d7908490610af4565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161093d91815260200190565b60405180910390a3610691565b600060208083528351808285015260005b818110156109775785810183015185820160400152820161095b565b81811115610989576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146109e157600080fd5b919050565b600080604083850312156109f957600080fd5b610a02836109bd565b946020939093013593505050565b600080600060608486031215610a2557600080fd5b610a2e846109bd565b9250610a3c602085016109bd565b9150604084013590509250925092565b600060208284031215610a5e57600080fd5b610a67826109bd565b9392505050565b60008060408385031215610a8157600080fd5b610a8a836109bd565b9150610a98602084016109bd565b90509250929050565b600181811c90821680610ab557607f821691505b602082108103610aee577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008219821115610b2e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(ERC20StorageLayoutJSON), ERC20StorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["ERC20"] = ERC20StorageLayout deployedBytecodes["ERC20"] = ERC20DeployedBin + immutableReferences["ERC20"] = false } diff --git a/op-bindings/bindings/faultdisputegame.go b/op-bindings/bindings/faultdisputegame.go index 9790cadb0d55..48bfae7bf838 100644 --- a/op-bindings/bindings/faultdisputegame.go +++ b/op-bindings/bindings/faultdisputegame.go @@ -28,17 +28,10 @@ var ( _ = event.NewSubscription ) -// IFaultDisputeGameOutputProposal is an auto generated low-level Go binding around an user-defined struct. -type IFaultDisputeGameOutputProposal struct { - Index *big.Int - L2BlockNumber *big.Int - OutputRoot [32]byte -} - // FaultDisputeGameMetaData contains all meta data concerning the FaultDisputeGame contract. var FaultDisputeGameMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"GameType\",\"name\":\"_gameType\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"_absolutePrestate\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_maxGameDepth\",\"type\":\"uint256\"},{\"internalType\":\"Duration\",\"name\":\"_gameDuration\",\"type\":\"uint64\"},{\"internalType\":\"contractIBigStepper\",\"name\":\"_vm\",\"type\":\"address\"},{\"internalType\":\"contractL2OutputOracle\",\"name\":\"_l2oo\",\"type\":\"address\"},{\"internalType\":\"contractBlockOracle\",\"name\":\"_blockOracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotDefendRootClaim\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClaimAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClaimAlreadyResolved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClockNotExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClockTimeExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GameDepthExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GameNotInProgress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidParent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPrestate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1HeadTooOld\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OutOfOrderResolution\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"Claim\",\"name\":\"rootClaim\",\"type\":\"bytes32\"}],\"name\":\"UnexpectedRootClaim\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValidStep\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"parentIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"Claim\",\"name\":\"claim\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"claimant\",\"type\":\"address\"}],\"name\":\"Move\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"enumGameStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"Resolved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ABSOLUTE_PRESTATE\",\"outputs\":[{\"internalType\":\"Claim\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BLOCK_ORACLE\",\"outputs\":[{\"internalType\":\"contractBlockOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GAME_DURATION\",\"outputs\":[{\"internalType\":\"Duration\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_OUTPUT_ORACLE\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_GAME_DEPTH\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VM\",\"outputs\":[{\"internalType\":\"contractIBigStepper\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_ident\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_partOffset\",\"type\":\"uint256\"}],\"name\":\"addLocalData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_parentIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_claim\",\"type\":\"bytes32\"}],\"name\":\"attack\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondManager\",\"outputs\":[{\"internalType\":\"contractIBondManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"claimData\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"parentIndex\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"countered\",\"type\":\"bool\"},{\"internalType\":\"Claim\",\"name\":\"claim\",\"type\":\"bytes32\"},{\"internalType\":\"Position\",\"name\":\"position\",\"type\":\"uint128\"},{\"internalType\":\"Clock\",\"name\":\"clock\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimDataLen\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"len_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createdAt\",\"outputs\":[{\"internalType\":\"Timestamp\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_parentIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_claim\",\"type\":\"bytes32\"}],\"name\":\"defend\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"extraData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"extraData_\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameData\",\"outputs\":[{\"internalType\":\"GameType\",\"name\":\"gameType_\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim_\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData_\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameType\",\"outputs\":[{\"internalType\":\"GameType\",\"name\":\"gameType_\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1BlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"l1BlockNumber_\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1Head\",\"outputs\":[{\"internalType\":\"Hash\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2BlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"l2BlockNumber_\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_challengeIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_claim\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"_isAttack\",\"type\":\"bool\"}],\"name\":\"move\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposals\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"index\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"},{\"internalType\":\"Hash\",\"name\":\"outputRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structIFaultDisputeGame.OutputProposal\",\"name\":\"starting\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint128\",\"name\":\"index\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"},{\"internalType\":\"Hash\",\"name\":\"outputRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structIFaultDisputeGame.OutputProposal\",\"name\":\"disputed\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"enumGameStatus\",\"name\":\"status_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_claimIndex\",\"type\":\"uint256\"}],\"name\":\"resolveClaim\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rootClaim\",\"outputs\":[{\"internalType\":\"Claim\",\"name\":\"rootClaim_\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"status\",\"outputs\":[{\"internalType\":\"enumGameStatus\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_claimIndex\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_isAttack\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_stateData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_proof\",\"type\":\"bytes\"}],\"name\":\"step\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101606040523480156200001257600080fd5b5060405162002b5d38038062002b5d83398101604081905262000035916200008f565b60ff9096166101405260809490945260a0929092526001600160401b031660c0526001600160a01b0390811660e05290811661010052166101205262000133565b6001600160a01b03811681146200008c57600080fd5b50565b600080600080600080600060e0888a031215620000ab57600080fd5b875160ff81168114620000bd57600080fd5b602089015160408a015160608b015192995090975095506001600160401b0381168114620000ea57600080fd5b6080890151909450620000fd8162000076565b60a0890151909350620001108162000076565b60c0890151909250620001238162000076565b8091505092959891949750929550565b60805160a05160c05160e05161010051610120516101405161297b620001e2600039600081816105410152611c4401526000818161034901526112fd0152600081816105ba015281816110ca0152818161119e015261127701526000818161050b015281816117fb0152611adc0152600081816105ee01528181610bc60152611d3301526000818161031501528181610a0501526115fa01526000818161020a0152611756015261297b6000f3fe6080604052600436106101b75760003560e01c80638980e0cc116100ec578063c55cd0c71161008a578063d8cc1a3c11610064578063d8cc1a3c146106c1578063f8f43ff6146106e1578063fa24f74314610701578063fdffbb281461072557600080fd5b8063c55cd0c714610629578063c6f0308c1461063c578063cf09e0d0146106a057600080fd5b8063bbdc02db116100c6578063bbdc02db1461052d578063bcef3b551461056b578063c0c3a092146105a8578063c31b29ce146105dc57600080fd5b80638980e0cc146104a45780638b85902b146104b957806392931298146104f957600080fd5b8063529184c911610159578063609d333411610133578063609d333414610451578063632247ea146104665780636361506d146104795780638129fc1c1461048f57600080fd5b8063529184c91461033757806354fd4d501461036b57806355ef20e6146103c157600080fd5b8063298c900511610195578063298c90051461024f57806335fef5671461028f578063363cc427146102a45780634778efe81461030357600080fd5b8063200d2ed2146101bc578063266198f9146101f85780632810e1d61461023a575b600080fd5b3480156101c857600080fd5b506000546101e29068010000000000000000900460ff1681565b6040516101ef91906122c8565b60405180910390f35b34801561020457600080fd5b5061022c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101ef565b34801561024657600080fd5b506101e2610738565b34801561025b57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561022c565b6102a261029d366004612309565b61089c565b005b3480156102b057600080fd5b506000546102de906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ef565b34801561030f57600080fd5b5061022c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561034357600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b34801561037757600080fd5b506103b46040518060400160405280600681526020017f302e302e3131000000000000000000000000000000000000000000000000000081525081565b6040516101ef9190612396565b3480156103cd57600080fd5b5060408051606080820183526003546fffffffffffffffffffffffffffffffff808216845270010000000000000000000000000000000091829004811660208086019190915260045485870152855193840186526005548083168552929092041690820152600654928101929092526104439182565b6040516101ef9291906123b0565b34801561045d57600080fd5b506103b46108ac565b6102a2610474366004612419565b6108ba565b34801561048557600080fd5b5061022c60015481565b34801561049b57600080fd5b506102a2610ed0565b3480156104b057600080fd5b5060025461022c565b3480156104c557600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561022c565b34801561050557600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b34801561053957600080fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101ef565b34801561057757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561022c565b3480156105b457600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105e857600080fd5b506106107f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff90911681526020016101ef565b6102a2610637366004612309565b6114d4565b34801561064857600080fd5b5061065c61065736600461244e565b6114e0565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101ef565b3480156106ac57600080fd5b506000546106109067ffffffffffffffff1681565b3480156106cd57600080fd5b506102a26106dc3660046124b0565b611551565b3480156106ed57600080fd5b506102a26106fc36600461253a565b611a7d565b34801561070d57600080fd5b50610716611c42565b6040516101ef93929190612566565b6102a261073336600461244e565b611c9f565b60008060005468010000000000000000900460ff16600281111561075e5761075e612299565b14610795576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460ff166107d1576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000815481106107e5576107e5612591565b6000918252602090912060039091020154640100000000900460ff1661080c57600261080f565b60015b6000805491925082917fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff166801000000000000000083600281111561085657610856612299565b02179055600281111561086b5761086b612299565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b905090565b6108a8828260006108ba565b5050565b606061089760206040611fd1565b6000805468010000000000000000900460ff1660028111156108de576108de612299565b14610915576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610921575080155b15610958576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002848154811061096d5761096d612591565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff80821660608501819052700100000000000000000000000000000000909204166080840152919350610a019190859061206816565b90507f0000000000000000000000000000000000000000000000000000000000000000610ac0826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610b02576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610b62576002836000015163ffffffff1681548110610b3157610b31612591565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610b9b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610baf91906125ef565b610bb99190612607565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff82161115610c2c576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b42176000888152608086901b6fffffffffffffffffffffffffffffffff8b1617602052604081209192509060008181526007602052604090205490915060ff1615610caa576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260076020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581529281018d81526fffffffffffffffffffffffffffffffff808c16606084019081528982166080850190815260028054808801825599819052945160039099027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101805498511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009099169a909916999099179690961790965590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8701559351925184167001000000000000000000000000000000000292909316919091177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad09093019290925580548b908110610e2257610e22612591565b6000918252602080832060039092029091018054931515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909416939093179092558a8152600890915260409020600254610e8690600190612607565b8154600181018355600092835260208320015560405133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560001a6001811480610f10575060ff81166002145b610f76576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335600482015260240160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff81526020810192909252600291908101610ffb7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff9081169091528254600181810185556000948552602080862085516003909402018054918601511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090921663ffffffff909416939093171782556040840151908201556060830151608090930151821670010000000000000000000000000000000002929091169190911760029091015573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016637f00642061112460207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c9003013590565b6040518263ffffffff1660e01b815260040161114291815260200190565b602060405180830381865afa15801561115f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611183919061261e565b9050600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae5576111ce600185612607565b6040518263ffffffff1660e01b81526004016111ec91815260200190565b606060405180830381865afa158015611209573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122d9190612686565b6040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810184905290915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa1580156112be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e29190612686565b9050600073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166399d548aa367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003604001356040518263ffffffff1660e01b815260040161136e91815260200190565b6040805180830381865afa15801561138a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ae9190612712565b905081602001516fffffffffffffffffffffffffffffffff16816020015167ffffffffffffffff161161140d576040517f13809ba500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a081018252908190810180611428600189612607565b6fffffffffffffffffffffffffffffffff908116825260408881015182166020808501919091529851928101929092529183528051606081018252978216885285810151821688880152945187860152908501959095528051805181860151908716700100000000000000000000000000000000918816820217600355908401516004559084015180519481015194861694909516029290921760055591909101516006555160015550565b6108a8828260016108ba565b600281815481106114f057600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff16600281111561157557611575612299565b146115ac576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600287815481106115c1576115c1612591565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506116207f000000000000000000000000000000000000000000000000000000000000000060016125ef565b6116bc826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16146116fd576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561178057611721836fffffffffffffffffffffffffffffffff16612070565b67ffffffffffffffff16156117545761174b61173e600186612799565b865463ffffffff16612116565b60010154611776565b7f00000000000000000000000000000000000000000000000000000000000000005b915084905061179a565b8460010154915061179784600161173e91906127ca565b90505b600882901b60088a8a6040516117b19291906127fe565b6040518091039020901b146117f2576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663836e7b328c8c8c8c60006040518663ffffffff1660e01b815260040161185b959493929190612857565b6020604051808303816000875af115801561187a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189e919061261e565b600284810154929091149250600091611949906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6119e5886fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6119ef9190612891565b6119f991906128b2565b67ffffffffffffffff161590508115158103611a41576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505084547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790945550505050505050505050565b6000805468010000000000000000900460ff166002811115611aa157611aa1612299565b14611ad8576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b699190612900565b7fc0c220c900000000000000000000000000000000000000000000000000000000601c8190526020869052604085905290915060008560018114611bd55760028114611bdf5760038114611be95760048114611bf35760058114611c035763ff137e656000526004601cfd5b6001549150611c0a565b6004549150611c0a565b6006549150611c0a565b60035460801c60c01b9150611c0a565b4660c01b91505b50606052600160038611811b6005031b60805260a083905260008060a4601c82865af1611c3b573d6000803e3d6000fd5b5050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611c986108ac565b9050909192565b6000805468010000000000000000900460ff166002811115611cc357611cc3612299565b14611cfa576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611d0f57611d0f612591565b60009182526020909120600260039092020190810154909150677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1690611d7f90700100000000000000000000000000000000900467ffffffffffffffff1642612607565b6002830154611daf9190700100000000000000000000000000000000900460401c67ffffffffffffffff166125ef565b11611de6576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260086020526040902082158015611e04575060095460ff165b15611e3b576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054158015611e4957508215155b15611e80576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8254811015611f4e576000838281548110611ea157611ea1612591565b6000918252602080832090910154808352600890915260409091205490915015611ef7576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611f0c57611f0c612591565b600091825260209091206003909102018054909150640100000000900460ff16611f3b57600193505050611f4e565b505080611f4790612936565b9050611e84565b5082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000821515021783556000848152600860205260408120611f979161225f565b83600003611fcb57600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b50505050565b6060600061200884367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036125ef565b90508267ffffffffffffffff1667ffffffffffffffff81111561202d5761202d612637565b6040519080825280601f01601f191660200182016040528015612057576020820181803683370190505b509150828160208401375092915050565b151760011b90565b6000806120fd837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b600080612134846fffffffffffffffffffffffffffffffff166121b3565b90506002838154811061214957612149612591565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff8281169116146121ac57815460028054909163ffffffff1690811061219757612197612591565b9060005260206000209060030201915061215a565b5092915050565b60008119600183011681612247827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b508054600082559060005260206000209081019061227d9190612280565b50565b5b808211156122955760008155600101612281565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612303577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561231c57600080fd5b50508035926020909101359150565b6000815180845260005b8181101561235157602081850181015186830182015201612335565b81811115612363576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006123a9602083018461232b565b9392505050565b82516fffffffffffffffffffffffffffffffff90811682526020808501518216818401526040808601518185015284518316606085015290840151909116608083015282015160a082015260c081016123a9565b8035801515811461241457600080fd5b919050565b60008060006060848603121561242e57600080fd5b833592506020840135915061244560408501612404565b90509250925092565b60006020828403121561246057600080fd5b5035919050565b60008083601f84011261247957600080fd5b50813567ffffffffffffffff81111561249157600080fd5b6020830191508360208285010111156124a957600080fd5b9250929050565b600080600080600080608087890312156124c957600080fd5b863595506124d960208801612404565b9450604087013567ffffffffffffffff808211156124f657600080fd5b6125028a838b01612467565b9096509450606089013591508082111561251b57600080fd5b5061252889828a01612467565b979a9699509497509295939492505050565b60008060006060848603121561254f57600080fd5b505081359360208301359350604090920135919050565b60ff84168152826020820152606060408201526000612588606083018461232b565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612602576126026125c0565b500190565b600082821015612619576126196125c0565b500390565b60006020828403121561263057600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80516fffffffffffffffffffffffffffffffff8116811461241457600080fd5b60006060828403121561269857600080fd5b6040516060810181811067ffffffffffffffff821117156126e2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052825181526126f560208401612666565b602082015261270660408401612666565b60408201529392505050565b60006040828403121561272457600080fd5b6040516040810167ffffffffffffffff828210818311171561276f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b816040528451835260208501519150808216821461278c57600080fd5b5060208201529392505050565b60006fffffffffffffffffffffffffffffffff838116908316818110156127c2576127c26125c0565b039392505050565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156127f5576127f56125c0565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60608152600061286b60608301878961280e565b828103602084015261287e81868861280e565b9150508260408301529695505050505050565b600067ffffffffffffffff838116908316818110156127c2576127c26125c0565b600067ffffffffffffffff808416806128f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910692915050565b60006020828403121561291257600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146123a957600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612967576129676125c0565b506001019056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"_absolutePrestate\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_maxGameDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_splitDepth\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_gameDuration\",\"type\":\"uint64\",\"internalType\":\"Duration\"},{\"name\":\"_vm\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"},{\"name\":\"_weth\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"},{\"name\":\"_anchorStateRegistry\",\"type\":\"address\",\"internalType\":\"contractIAnchorStateRegistry\"},{\"name\":\"_l2ChainId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"absolutePrestate\",\"inputs\":[],\"outputs\":[{\"name\":\"absolutePrestate_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addLocalData\",\"inputs\":[{\"name\":\"_ident\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_execLeafIdx\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"attack\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"claimCredit\",\"inputs\":[{\"name\":\"_recipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"claimData\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"parentIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"counteredBy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"claimant\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"bond\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"position\",\"type\":\"uint128\",\"internalType\":\"Position\"},{\"name\":\"clock\",\"type\":\"uint128\",\"internalType\":\"Clock\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimDataLen\",\"inputs\":[],\"outputs\":[{\"name\":\"len_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimedBondFlag\",\"inputs\":[],\"outputs\":[{\"name\":\"claimedBondFlag_\",\"type\":\"uint128\",\"internalType\":\"uint128\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"createdAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"credit\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"defend\",\"inputs\":[{\"name\":\"_parentIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"extraData\",\"inputs\":[],\"outputs\":[{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"gameData\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint32\",\"internalType\":\"GameType\"},{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"extraData_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameDuration\",\"inputs\":[],\"outputs\":[{\"name\":\"gameDuration_\",\"type\":\"uint64\",\"internalType\":\"Duration\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gameType\",\"inputs\":[],\"outputs\":[{\"name\":\"gameType_\",\"type\":\"uint32\",\"internalType\":\"GameType\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRequiredBond\",\"inputs\":[{\"name\":\"_position\",\"type\":\"uint128\",\"internalType\":\"Position\"}],\"outputs\":[{\"name\":\"requiredBond_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"l1Head\",\"inputs\":[],\"outputs\":[{\"name\":\"l1Head_\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"l2BlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"l2BlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"l2ChainId\",\"inputs\":[],\"outputs\":[{\"name\":\"l2ChainId_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"maxGameDepth\",\"inputs\":[],\"outputs\":[{\"name\":\"maxGameDepth_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"move\",\"inputs\":[{\"name\":\"_challengeIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_claim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resolve\",\"inputs\":[],\"outputs\":[{\"name\":\"status_\",\"type\":\"uint8\",\"internalType\":\"enumGameStatus\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resolveClaim\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resolvedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"Timestamp\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"rootClaim\",\"inputs\":[],\"outputs\":[{\"name\":\"rootClaim_\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"splitDepth\",\"inputs\":[],\"outputs\":[{\"name\":\"splitDepth_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"startingBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"startingBlockNumber_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"startingOutputRoot\",\"inputs\":[],\"outputs\":[{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"Hash\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"startingRootHash\",\"inputs\":[],\"outputs\":[{\"name\":\"startingRootHash_\",\"type\":\"bytes32\",\"internalType\":\"Hash\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"status\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumGameStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_claimIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_isAttack\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"vm\",\"inputs\":[],\"outputs\":[{\"name\":\"vm_\",\"type\":\"address\",\"internalType\":\"contractIBigStepper\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"weth\",\"inputs\":[],\"outputs\":[{\"name\":\"weth_\",\"type\":\"address\",\"internalType\":\"contractIDelayedWETH\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Move\",\"inputs\":[{\"name\":\"parentIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"claim\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"Claim\"},{\"name\":\"claimant\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Resolved\",\"inputs\":[{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumGameStatus\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AlreadyInitialized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AnchorRootNotFound\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"BondTransferFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"CannotDefendRootClaim\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAboveSplit\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyExists\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClaimAlreadyResolved\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockNotExpired\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ClockTimeExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"DuplicateStep\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameDepthExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GameNotInProgress\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientBond\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidLocalIdent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidParent\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPrestate\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSplitDepth\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoCreditToClaim\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OutOfOrderResolution\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UnexpectedRootClaim\",\"inputs\":[{\"name\":\"rootClaim\",\"type\":\"bytes32\",\"internalType\":\"Claim\"}]},{\"type\":\"error\",\"name\":\"ValidStep\",\"inputs\":[]}]", + Bin: "0x6101a06040523480156200001257600080fd5b5060405162004988380380620049888339810160408190526200003591620000d0565b868610620000565760405163e62ccf3960e01b815260040160405180910390fd5b63ffffffff9098166101205260809690965260a09490945260c0929092526001600160401b031660e0526001600160a01b03908116610100529081166101405216610160526101805262000183565b6001600160a01b0381168114620000bb57600080fd5b50565b8051620000cb81620000a5565b919050565b60008060008060008060008060006101208a8c031215620000f057600080fd5b895163ffffffff811681146200010557600080fd5b60208b015160408c015160608d015160808e0151939c50919a50985096506001600160401b03811681146200013957600080fd5b60a08b01519095506200014c81620000a5565b93506200015c60c08b01620000be565b92506200016c60e08b01620000be565b91506101008a015190509295985092959850929598565b60805160a05160c05160e05161010051610120516101405161016051610180516146d7620002b1600039600081816106a7015261267d015260008181610a02015261157a01526000818161033801528181610b5701528181611430015281816119310152613b9d0152600081816105260152818161153901526127170152600081816102e401528181611fea01526123460152600081816106fa0152818161105b015261287501526000818161072d01528181610e4801528181610f1101528181611e450152818161254501528181612cb6015281816133f3015281816135210152818161362901526137050152600081816107cf01528181610eb401528181611aa301528181611b2901528181611d340152611e660152600081816104eb0152611efc01526146d76000f3fe6080604052600436106101ff5760003560e01c80638d450a951161010e578063d6ae3cd5116100a7578063f3f7214e11610079578063fa24f74311610061578063fa24f7431461079c578063fa315aa9146107c0578063fdffbb28146107f357005b8063f3f7214e14610751578063f8f43ff61461077c57005b8063d6ae3cd514610698578063d8cc1a3c146106cb578063e1f0c376146106eb578063ec5e63081461071e57005b8063c55cd0c7116100e0578063c55cd0c7146105ad578063c6f0308c146105c0578063cf09e0d01461064a578063d5d44d801461066b57005b80638d450a95146104dc578063bbdc02db1461050f578063bcef3b5514610550578063c395e1ca1461058d57005b806357da950e116101985780636361506d1161016a5780638129fc1c116101525780638129fc1c1461047f5780638980e0cc146104875780638b85902b1461049c57005b80636361506d1461042a57806370872aa51461046a57005b806357da950e146103b2578063609d3334146103e257806360e27464146103f7578063632247ea1461041757005b806335fef567116101d157806335fef567146102c25780633a768463146102d55780633fc8cef31461032957806354fd4d501461035c57005b806319effeb414610208578063200d2ed21461025357806325fc2ace1461028e5780632810e1d6146102ad57005b3661020657005b005b34801561021457600080fd5b506000546102359068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561025f57600080fd5b5060005461028190700100000000000000000000000000000000900460ff1681565b60405161024a9190613f78565b34801561029a57600080fd5b506006545b60405190815260200161024a565b3480156102b957600080fd5b50610281610806565b6102066102d0366004613fb9565b610a83565b3480156102e157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161024a565b34801561033557600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610304565b34801561036857600080fd5b506103a56040518060400160405280600581526020017f302e382e3100000000000000000000000000000000000000000000000000000081525081565b60405161024a9190614046565b3480156103be57600080fd5b506006546007546103cd919082565b6040805192835260208301919091520161024a565b3480156103ee57600080fd5b506103a5610a93565b34801561040357600080fd5b5061020661041236600461407b565b610aa6565b6102066104253660046140b4565b610c52565b34801561043657600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561029f565b34801561047657600080fd5b5060075461029f565b6102066114ca565b34801561049357600080fd5b5060015461029f565b3480156104a857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561029f565b3480156104e857600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b34801561051b57600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161024a565b34801561055c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561029f565b34801561059957600080fd5b5061029f6105a83660046140e9565b6119f6565b6102066105bb366004613fb9565b611be0565b3480156105cc57600080fd5b506105e06105db36600461411b565b611bec565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161024a565b34801561065657600080fd5b506000546102359067ffffffffffffffff1681565b34801561067757600080fd5b5061029f61068636600461407b565b60026020526000908152604090205481565b3480156106a457600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b3480156106d757600080fd5b506102066106e636600461417d565b611c83565b3480156106f757600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610235565b34801561072a57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b34801561075d57600080fd5b506040516fffffffffffffffffffffffffffffffff815260200161024a565b34801561078857600080fd5b50610206610797366004614207565b6122b8565b3480156107a857600080fd5b506107b1612715565b60405161024a93929190614233565b3480156107cc57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b61020661080136600461411b565b612772565b600080600054700100000000000000000000000000000000900460ff16600281111561083457610834613f49565b1461086b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055460ff166108a7576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660016000815481106108d3576108d3614261565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff161461090e576001610911565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156109c2576109c2613f49565b0217905560028111156109d7576109d7613f49565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a6857600080fd5b505af1158015610a7c573d6000803e3d6000fd5b5050505090565b610a8f82826000610c52565b5050565b6060610aa160406020612bd3565b905090565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040812080549082905590819003610b0b576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f3fef3a390604401600060405180830381600087803b158015610b9b57600080fd5b505af1158015610baf573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610c0d576040519150601f19603f3d011682016040523d82523d6000602084013e610c12565b606091505b5050905080610c4d576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60008054700100000000000000000000000000000000900460ff166002811115610c7e57610c7e613f49565b14610cb5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018481548110610cca57610cca614261565b600091825260208083206040805160e0810182526005909402909101805463ffffffff808216865273ffffffffffffffffffffffffffffffffffffffff6401000000009092048216948601949094526001820154169184019190915260028101546fffffffffffffffffffffffffffffffff90811660608501526003820154608085015260049091015480821660a0850181905270010000000000000000000000000000000090910490911660c0840152919350909190610d8f9083908690612c6a16565b90506000610e2f826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610e715750610e6e7f000000000000000000000000000000000000000000000000000000000000000060026142bf565b81145b8015610e7b575084155b15610eb2576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610f0c576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f377f000000000000000000000000000000000000000000000000000000000000000060016142bf565b8103610f4957610f4986888588612c72565b34610f53836119f6565b1115610f8b576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835160009063ffffffff90811614610feb576001856000015163ffffffff1681548110610fba57610fba614261565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b60c085015160009061100f9067ffffffffffffffff165b67ffffffffffffffff1690565b67ffffffffffffffff1642611039611002856fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff1661104d91906142bf565b61105791906142d7565b90507f000000000000000000000000000000000000000000000000000000000000000060011c677fffffffffffffff1667ffffffffffffffff821611156110ca576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526003602052604090205490915060ff1615611148576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016003600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060016040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600460008c8152602001908152602001600020600180805490506113dd91906142d7565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263d0e30db09234926004808301939282900301818588803b15801561147557600080fd5b505af1158015611489573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a45050505050505050505050565b600554610100900460ff161561150c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690637258a807906024016040805180830381865afa1580156115c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e491906142ee565b909250905081611620576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082018252838152602001829052600683905560078290558190367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90030135116116d2576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b60663611156116e95763c407e0256000526004601cfd5b6040805160e08101825263ffffffff808252600060208301818152328486019081526fffffffffffffffffffffffffffffffff34818116606088019081527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033560808901908152600160a08a0181815242861660c08c0190815282548084018455928a529a5160059092027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf681018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915594517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf787018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905590517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8860180549185167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909216919091179055517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9850155915195518116700100000000000000000000000000000000029516949094177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa9091015583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f00000000000000000000000000000000000000000000000000000000000000009092169363d0e30db093926004828101939282900301818588803b15801561197757600080fd5b505af115801561198b573d6000803e3d6000fd5b50506000805467ffffffffffffffff42167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009091161790555050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055505050565b600080611a95836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690507f0000000000000000000000000000000000000000000000000000000000000000811115611afb576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a80630bebc2006000611b168383614341565b9050670de0b6b3a76400006000611b4d827f0000000000000000000000000000000000000000000000000000000000000000614355565b90506000611b6b611b66670de0b6b3a764000086614355565b612e33565b90506000611b79848461308e565b90506000611b8783836130dd565b90506000611b948261310b565b90506000611bb382611bae670de0b6b3a76400008f614355565b6132f3565b90506000611bc18b836130dd565b9050611bcd818d614355565b9f9e505050505050505050505050505050565b610a8f82826001610c52565b60018181548110611bfc57600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115611caf57611caf613f49565b14611ce6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018781548110611cfb57611cfb614261565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050611d5a7f000000000000000000000000000000000000000000000000000000000000000060016142bf565b611df6826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1614611e37576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808915611f2657611e8a7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006142d7565b6001901b611ea9846fffffffffffffffffffffffffffffffff1661332d565b67ffffffffffffffff16611ebd9190614392565b15611efa57611ef1611ee260016fffffffffffffffffffffffffffffffff87166143a6565b865463ffffffff1660006133d3565b60030154611f1c565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611f50565b60038501549150611f4d611ee26fffffffffffffffffffffffffffffffff861660016143d7565b90505b600882901b60088a8a604051611f6792919061440b565b6040518091039020901b14611fa8576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611fb38c6134b7565b90506000611fc2836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e14ced329061203c908f908f908f908f908a90600401614464565b6020604051808303816000875af115801561205b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207f919061449e565b60048501549114915060009060029061212a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6121c6896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6121d091906144b7565b6121da91906144d8565b67ffffffffffffffff161590508115158103612222576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff1615612279576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156122e4576122e4613f49565b1461231b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061232a866134e6565b93509350935093506000612340858585856138f5565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d391906144ff565b9050600189036124cb5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461242f367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156124a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c5919061449e565b5061270a565b600289036124f75773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961242f565b600389036125235773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761242f565b6004890361263f5760006125696fffffffffffffffffffffffffffffffff85167f00000000000000000000000000000000000000000000000000000000000000006139b4565b60075461257691906142bf565b6125819060016142bf565b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af1158015612614573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612638919061449e565b505061270a565b600589036126d8576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000000060c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a401612482565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335606061276b610a93565b9050909192565b60008054700100000000000000000000000000000000900460ff16600281111561279e5761279e613f49565b146127d5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600182815481106127ea576127ea614261565b60009182526020822060059190910201600481015490925061282c90700100000000000000000000000000000000900460401c67ffffffffffffffff16611002565b600483015490915060009061285e90700100000000000000000000000000000000900467ffffffffffffffff16611002565b61286890426144b7565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c166128a2828461451c565b67ffffffffffffffff16116128e3576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600460205260409020805485158015612903575060055460ff165b1561293a576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015801561294757508515155b156129ac578454640100000000900473ffffffffffffffffffffffffffffffffffffffff166000811561297a5781612996565b600187015473ffffffffffffffffffffffffffffffffffffffff165b90506129a28188613a69565b5050505050505050565b60006fffffffffffffffffffffffffffffffff815b83811015612af25760008582815481106129dd576129dd614261565b6000918252602080832090910154808352600490915260409091205490915015612a33576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018281548110612a4857612a48614261565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff16158015612aa1575060048101546fffffffffffffffffffffffffffffffff908116908516115b15612adf576001810154600482015473ffffffffffffffffffffffffffffffffffffffff90911695506fffffffffffffffffffffffffffffffff1693505b505080612aeb9061453f565b90506129c1565b50612b3a73ffffffffffffffffffffffffffffffffffffffff831615612b185782612b34565b600188015473ffffffffffffffffffffffffffffffffffffffff165b88613a69565b86547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416021787556000888152600460205260408120612b9691613f0f565b876000036129a257600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555050505050505050565b60606000612c0a84367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036142bf565b90508267ffffffffffffffff1667ffffffffffffffff811115612c2f57612c2f614577565b6040519080825280601f01601f191660200182016040528015612c59576020820181803683370190505b509150828160208401375092915050565b151760011b90565b6000612c916fffffffffffffffffffffffffffffffff841660016143d7565b90506000612ca1828660016133d3565b9050600086901a8380612d945750612cda60027f0000000000000000000000000000000000000000000000000000000000000000614392565b6004830154600290612d7e906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b612d8891906144d8565b67ffffffffffffffff16145b15612dec5760ff811660011480612dae575060ff81166002145b612de7576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016116c9565b612e2a565b60ff811615612e2a576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016116c9565b50505050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213612e9257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a7640000021582026130cb57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156130fb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361313957919050565b680755bf798b4a1bf1e582126131575763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613324670de0b6b3a76400008361330b86612e33565b61331591906145a6565b61331f9190614662565b61310b565b90505b92915050565b6000806133ba837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000808261341c576134176fffffffffffffffffffffffffffffffff86167f0000000000000000000000000000000000000000000000000000000000000000613bf5565b613437565b613437856fffffffffffffffffffffffffffffffff16613db3565b90506001848154811061344c5761344c614261565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146134af57815460018054909163ffffffff1690811061349a5761349a614261565b9060005260206000209060050201915061345d565b509392505050565b60008060008060006134c8866134e6565b93509350935093506134dc848484846138f5565b9695505050505050565b600080600080600085905060006001828154811061350657613506614261565b600091825260209091206004600590920201908101549091507f0000000000000000000000000000000000000000000000000000000000000000906135dd906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161361e576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f0000000000000000000000000000000000000000000000000000000000000000906136e5906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16925082111561376157825463ffffffff1661372b7f000000000000000000000000000000000000000000000000000000000000000060016142bf565b8303613735578391505b6001818154811061374857613748614261565b9060005260206000209060050201935080945050613622565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166137ca6137b5856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015613891576000613802836fffffffffffffffffffffffffffffffff1661332d565b67ffffffffffffffff16111561386557600061383c61383460016fffffffffffffffffffffffffffffffff86166143a6565b8960016133d3565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a5061386b9050565b6006549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff1697506138e7565b60006138b36138346fffffffffffffffffffffffffffffffff851660016143d7565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff8416810361395b57828260405160200161393e9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012090506139ac565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b600080613a41847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60028101546fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000018101613ad9576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280830180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff17905573ffffffffffffffffffffffffffffffffffffffff84166000908152602091909152604081208054839290613b4c9084906142bf565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f00000000000000000000000000000000000000000000000000000000000000001690637eee288d90604401600060405180830381600087803b158015613be157600080fd5b505af1158015612e2a573d6000803e3d6000fd5b600081613c94846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611613cd5576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613cde83613db3565b905081613d7d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161332757613324613d9a8360016142bf565b6fffffffffffffffffffffffffffffffff831690613e5f565b60008119600183011681613e47827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080613eec847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b5080546000825590600052602060002090810190613f2d9190613f30565b50565b5b80821115613f455760008155600101613f31565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310613fb3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215613fcc57600080fd5b50508035926020909101359150565b6000815180845260005b8181101561400157602081850181015186830182015201613fe5565b81811115614013576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006133246020830184613fdb565b73ffffffffffffffffffffffffffffffffffffffff81168114613f2d57600080fd5b60006020828403121561408d57600080fd5b813561409881614059565b9392505050565b803580151581146140af57600080fd5b919050565b6000806000606084860312156140c957600080fd5b83359250602084013591506140e06040850161409f565b90509250925092565b6000602082840312156140fb57600080fd5b81356fffffffffffffffffffffffffffffffff8116811461409857600080fd5b60006020828403121561412d57600080fd5b5035919050565b60008083601f84011261414657600080fd5b50813567ffffffffffffffff81111561415e57600080fd5b60208301915083602082850101111561417657600080fd5b9250929050565b6000806000806000806080878903121561419657600080fd5b863595506141a66020880161409f565b9450604087013567ffffffffffffffff808211156141c357600080fd5b6141cf8a838b01614134565b909650945060608901359150808211156141e857600080fd5b506141f589828a01614134565b979a9699509497509295939492505050565b60008060006060848603121561421c57600080fd5b505081359360208301359350604090920135919050565b63ffffffff841681528260208201526060604082015260006142586060830184613fdb565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156142d2576142d2614290565b500190565b6000828210156142e9576142e9614290565b500390565b6000806040838503121561430157600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261435057614350614312565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561438d5761438d614290565b500290565b6000826143a1576143a1614312565b500690565b60006fffffffffffffffffffffffffffffffff838116908316818110156143cf576143cf614290565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561440257614402614290565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60608152600061447860608301878961441b565b828103602084015261448b81868861441b565b9150508260408301529695505050505050565b6000602082840312156144b057600080fd5b5051919050565b600067ffffffffffffffff838116908316818110156143cf576143cf614290565b600067ffffffffffffffff808416806144f3576144f3614312565b92169190910692915050565b60006020828403121561451157600080fd5b815161409881614059565b600067ffffffffffffffff80831681851680830382111561440257614402614290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361457057614570614290565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156145e7576145e7614290565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561462257614622614290565b6000871292508782058712848416161561463e5761463e614290565b8785058712818416161561465457614654614290565b505050929093029392505050565b60008261467157614671614312565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156146c5576146c5614290565b50059056fea164736f6c634300080f000a", } // FaultDisputeGameABI is the input ABI used to generate the binding from. @@ -50,7 +43,7 @@ var FaultDisputeGameABI = FaultDisputeGameMetaData.ABI var FaultDisputeGameBin = FaultDisputeGameMetaData.Bin // DeployFaultDisputeGame deploys a new Ethereum contract, binding an instance of FaultDisputeGame to it. -func DeployFaultDisputeGame(auth *bind.TransactOpts, backend bind.ContractBackend, _gameType uint8, _absolutePrestate [32]byte, _maxGameDepth *big.Int, _gameDuration uint64, _vm common.Address, _l2oo common.Address, _blockOracle common.Address) (common.Address, *types.Transaction, *FaultDisputeGame, error) { +func DeployFaultDisputeGame(auth *bind.TransactOpts, backend bind.ContractBackend, _gameType uint32, _absolutePrestate [32]byte, _maxGameDepth *big.Int, _splitDepth *big.Int, _gameDuration uint64, _vm common.Address, _weth common.Address, _anchorStateRegistry common.Address, _l2ChainId *big.Int) (common.Address, *types.Transaction, *FaultDisputeGame, error) { parsed, err := FaultDisputeGameMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -59,7 +52,7 @@ func DeployFaultDisputeGame(auth *bind.TransactOpts, backend bind.ContractBacken return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FaultDisputeGameBin), backend, _gameType, _absolutePrestate, _maxGameDepth, _gameDuration, _vm, _l2oo, _blockOracle) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FaultDisputeGameBin), backend, _gameType, _absolutePrestate, _maxGameDepth, _splitDepth, _gameDuration, _vm, _weth, _anchorStateRegistry, _l2ChainId) if err != nil { return common.Address{}, nil, nil, err } @@ -208,12 +201,12 @@ func (_FaultDisputeGame *FaultDisputeGameTransactorRaw) Transact(opts *bind.Tran return _FaultDisputeGame.Contract.contract.Transact(opts, method, params...) } -// ABSOLUTEPRESTATE is a free data retrieval call binding the contract method 0x266198f9. +// AbsolutePrestate is a free data retrieval call binding the contract method 0x8d450a95. // -// Solidity: function ABSOLUTE_PRESTATE() view returns(bytes32) -func (_FaultDisputeGame *FaultDisputeGameCaller) ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) { +// Solidity: function absolutePrestate() view returns(bytes32 absolutePrestate_) +func (_FaultDisputeGame *FaultDisputeGameCaller) AbsolutePrestate(opts *bind.CallOpts) ([32]byte, error) { var out []interface{} - err := _FaultDisputeGame.contract.Call(opts, &out, "ABSOLUTE_PRESTATE") + err := _FaultDisputeGame.contract.Call(opts, &out, "absolutePrestate") if err != nil { return *new([32]byte), err @@ -225,212 +218,28 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) ABSOLUTEPRESTATE(opts *bind.Cal } -// ABSOLUTEPRESTATE is a free data retrieval call binding the contract method 0x266198f9. -// -// Solidity: function ABSOLUTE_PRESTATE() view returns(bytes32) -func (_FaultDisputeGame *FaultDisputeGameSession) ABSOLUTEPRESTATE() ([32]byte, error) { - return _FaultDisputeGame.Contract.ABSOLUTEPRESTATE(&_FaultDisputeGame.CallOpts) -} - -// ABSOLUTEPRESTATE is a free data retrieval call binding the contract method 0x266198f9. -// -// Solidity: function ABSOLUTE_PRESTATE() view returns(bytes32) -func (_FaultDisputeGame *FaultDisputeGameCallerSession) ABSOLUTEPRESTATE() ([32]byte, error) { - return _FaultDisputeGame.Contract.ABSOLUTEPRESTATE(&_FaultDisputeGame.CallOpts) -} - -// BLOCKORACLE is a free data retrieval call binding the contract method 0x529184c9. -// -// Solidity: function BLOCK_ORACLE() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameCaller) BLOCKORACLE(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _FaultDisputeGame.contract.Call(opts, &out, "BLOCK_ORACLE") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// BLOCKORACLE is a free data retrieval call binding the contract method 0x529184c9. -// -// Solidity: function BLOCK_ORACLE() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameSession) BLOCKORACLE() (common.Address, error) { - return _FaultDisputeGame.Contract.BLOCKORACLE(&_FaultDisputeGame.CallOpts) -} - -// BLOCKORACLE is a free data retrieval call binding the contract method 0x529184c9. -// -// Solidity: function BLOCK_ORACLE() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameCallerSession) BLOCKORACLE() (common.Address, error) { - return _FaultDisputeGame.Contract.BLOCKORACLE(&_FaultDisputeGame.CallOpts) -} - -// GAMEDURATION is a free data retrieval call binding the contract method 0xc31b29ce. -// -// Solidity: function GAME_DURATION() view returns(uint64) -func (_FaultDisputeGame *FaultDisputeGameCaller) GAMEDURATION(opts *bind.CallOpts) (uint64, error) { - var out []interface{} - err := _FaultDisputeGame.contract.Call(opts, &out, "GAME_DURATION") - - if err != nil { - return *new(uint64), err - } - - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) - - return out0, err - -} - -// GAMEDURATION is a free data retrieval call binding the contract method 0xc31b29ce. -// -// Solidity: function GAME_DURATION() view returns(uint64) -func (_FaultDisputeGame *FaultDisputeGameSession) GAMEDURATION() (uint64, error) { - return _FaultDisputeGame.Contract.GAMEDURATION(&_FaultDisputeGame.CallOpts) -} - -// GAMEDURATION is a free data retrieval call binding the contract method 0xc31b29ce. -// -// Solidity: function GAME_DURATION() view returns(uint64) -func (_FaultDisputeGame *FaultDisputeGameCallerSession) GAMEDURATION() (uint64, error) { - return _FaultDisputeGame.Contract.GAMEDURATION(&_FaultDisputeGame.CallOpts) -} - -// L2OUTPUTORACLE is a free data retrieval call binding the contract method 0xc0c3a092. -// -// Solidity: function L2_OUTPUT_ORACLE() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameCaller) L2OUTPUTORACLE(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _FaultDisputeGame.contract.Call(opts, &out, "L2_OUTPUT_ORACLE") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// L2OUTPUTORACLE is a free data retrieval call binding the contract method 0xc0c3a092. -// -// Solidity: function L2_OUTPUT_ORACLE() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameSession) L2OUTPUTORACLE() (common.Address, error) { - return _FaultDisputeGame.Contract.L2OUTPUTORACLE(&_FaultDisputeGame.CallOpts) -} - -// L2OUTPUTORACLE is a free data retrieval call binding the contract method 0xc0c3a092. -// -// Solidity: function L2_OUTPUT_ORACLE() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameCallerSession) L2OUTPUTORACLE() (common.Address, error) { - return _FaultDisputeGame.Contract.L2OUTPUTORACLE(&_FaultDisputeGame.CallOpts) -} - -// MAXGAMEDEPTH is a free data retrieval call binding the contract method 0x4778efe8. -// -// Solidity: function MAX_GAME_DEPTH() view returns(uint256) -func (_FaultDisputeGame *FaultDisputeGameCaller) MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _FaultDisputeGame.contract.Call(opts, &out, "MAX_GAME_DEPTH") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// MAXGAMEDEPTH is a free data retrieval call binding the contract method 0x4778efe8. -// -// Solidity: function MAX_GAME_DEPTH() view returns(uint256) -func (_FaultDisputeGame *FaultDisputeGameSession) MAXGAMEDEPTH() (*big.Int, error) { - return _FaultDisputeGame.Contract.MAXGAMEDEPTH(&_FaultDisputeGame.CallOpts) -} - -// MAXGAMEDEPTH is a free data retrieval call binding the contract method 0x4778efe8. -// -// Solidity: function MAX_GAME_DEPTH() view returns(uint256) -func (_FaultDisputeGame *FaultDisputeGameCallerSession) MAXGAMEDEPTH() (*big.Int, error) { - return _FaultDisputeGame.Contract.MAXGAMEDEPTH(&_FaultDisputeGame.CallOpts) -} - -// VM is a free data retrieval call binding the contract method 0x92931298. -// -// Solidity: function VM() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameCaller) VM(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _FaultDisputeGame.contract.Call(opts, &out, "VM") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// VM is a free data retrieval call binding the contract method 0x92931298. -// -// Solidity: function VM() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameSession) VM() (common.Address, error) { - return _FaultDisputeGame.Contract.VM(&_FaultDisputeGame.CallOpts) -} - -// VM is a free data retrieval call binding the contract method 0x92931298. -// -// Solidity: function VM() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameCallerSession) VM() (common.Address, error) { - return _FaultDisputeGame.Contract.VM(&_FaultDisputeGame.CallOpts) -} - -// BondManager is a free data retrieval call binding the contract method 0x363cc427. -// -// Solidity: function bondManager() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameCaller) BondManager(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _FaultDisputeGame.contract.Call(opts, &out, "bondManager") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// BondManager is a free data retrieval call binding the contract method 0x363cc427. +// AbsolutePrestate is a free data retrieval call binding the contract method 0x8d450a95. // -// Solidity: function bondManager() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameSession) BondManager() (common.Address, error) { - return _FaultDisputeGame.Contract.BondManager(&_FaultDisputeGame.CallOpts) +// Solidity: function absolutePrestate() view returns(bytes32 absolutePrestate_) +func (_FaultDisputeGame *FaultDisputeGameSession) AbsolutePrestate() ([32]byte, error) { + return _FaultDisputeGame.Contract.AbsolutePrestate(&_FaultDisputeGame.CallOpts) } -// BondManager is a free data retrieval call binding the contract method 0x363cc427. +// AbsolutePrestate is a free data retrieval call binding the contract method 0x8d450a95. // -// Solidity: function bondManager() view returns(address) -func (_FaultDisputeGame *FaultDisputeGameCallerSession) BondManager() (common.Address, error) { - return _FaultDisputeGame.Contract.BondManager(&_FaultDisputeGame.CallOpts) +// Solidity: function absolutePrestate() view returns(bytes32 absolutePrestate_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) AbsolutePrestate() ([32]byte, error) { + return _FaultDisputeGame.Contract.AbsolutePrestate(&_FaultDisputeGame.CallOpts) } // ClaimData is a free data retrieval call binding the contract method 0xc6f0308c. // -// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, bool countered, bytes32 claim, uint128 position, uint128 clock) +// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, address counteredBy, address claimant, uint128 bond, bytes32 claim, uint128 position, uint128 clock) func (_FaultDisputeGame *FaultDisputeGameCaller) ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct { ParentIndex uint32 - Countered bool + CounteredBy common.Address + Claimant common.Address + Bond *big.Int Claim [32]byte Position *big.Int Clock *big.Int @@ -440,7 +249,9 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) ClaimData(opts *bind.CallOpts, outstruct := new(struct { ParentIndex uint32 - Countered bool + CounteredBy common.Address + Claimant common.Address + Bond *big.Int Claim [32]byte Position *big.Int Clock *big.Int @@ -450,10 +261,12 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) ClaimData(opts *bind.CallOpts, } outstruct.ParentIndex = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.Countered = *abi.ConvertType(out[1], new(bool)).(*bool) - outstruct.Claim = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) - outstruct.Position = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) - outstruct.Clock = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + outstruct.CounteredBy = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + outstruct.Claimant = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) + outstruct.Bond = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.Claim = *abi.ConvertType(out[4], new([32]byte)).(*[32]byte) + outstruct.Position = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) + outstruct.Clock = *abi.ConvertType(out[6], new(*big.Int)).(**big.Int) return *outstruct, err @@ -461,10 +274,12 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) ClaimData(opts *bind.CallOpts, // ClaimData is a free data retrieval call binding the contract method 0xc6f0308c. // -// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, bool countered, bytes32 claim, uint128 position, uint128 clock) +// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, address counteredBy, address claimant, uint128 bond, bytes32 claim, uint128 position, uint128 clock) func (_FaultDisputeGame *FaultDisputeGameSession) ClaimData(arg0 *big.Int) (struct { ParentIndex uint32 - Countered bool + CounteredBy common.Address + Claimant common.Address + Bond *big.Int Claim [32]byte Position *big.Int Clock *big.Int @@ -474,10 +289,12 @@ func (_FaultDisputeGame *FaultDisputeGameSession) ClaimData(arg0 *big.Int) (stru // ClaimData is a free data retrieval call binding the contract method 0xc6f0308c. // -// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, bool countered, bytes32 claim, uint128 position, uint128 clock) +// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, address counteredBy, address claimant, uint128 bond, bytes32 claim, uint128 position, uint128 clock) func (_FaultDisputeGame *FaultDisputeGameCallerSession) ClaimData(arg0 *big.Int) (struct { ParentIndex uint32 - Countered bool + CounteredBy common.Address + Claimant common.Address + Bond *big.Int Claim [32]byte Position *big.Int Clock *big.Int @@ -516,6 +333,37 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) ClaimDataLen() (*big.Int return _FaultDisputeGame.Contract.ClaimDataLen(&_FaultDisputeGame.CallOpts) } +// ClaimedBondFlag is a free data retrieval call binding the contract method 0xf3f7214e. +// +// Solidity: function claimedBondFlag() pure returns(uint128 claimedBondFlag_) +func (_FaultDisputeGame *FaultDisputeGameCaller) ClaimedBondFlag(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "claimedBondFlag") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ClaimedBondFlag is a free data retrieval call binding the contract method 0xf3f7214e. +// +// Solidity: function claimedBondFlag() pure returns(uint128 claimedBondFlag_) +func (_FaultDisputeGame *FaultDisputeGameSession) ClaimedBondFlag() (*big.Int, error) { + return _FaultDisputeGame.Contract.ClaimedBondFlag(&_FaultDisputeGame.CallOpts) +} + +// ClaimedBondFlag is a free data retrieval call binding the contract method 0xf3f7214e. +// +// Solidity: function claimedBondFlag() pure returns(uint128 claimedBondFlag_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) ClaimedBondFlag() (*big.Int, error) { + return _FaultDisputeGame.Contract.ClaimedBondFlag(&_FaultDisputeGame.CallOpts) +} + // CreatedAt is a free data retrieval call binding the contract method 0xcf09e0d0. // // Solidity: function createdAt() view returns(uint64) @@ -547,6 +395,37 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) CreatedAt() (uint64, err return _FaultDisputeGame.Contract.CreatedAt(&_FaultDisputeGame.CallOpts) } +// Credit is a free data retrieval call binding the contract method 0xd5d44d80. +// +// Solidity: function credit(address ) view returns(uint256) +func (_FaultDisputeGame *FaultDisputeGameCaller) Credit(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "credit", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Credit is a free data retrieval call binding the contract method 0xd5d44d80. +// +// Solidity: function credit(address ) view returns(uint256) +func (_FaultDisputeGame *FaultDisputeGameSession) Credit(arg0 common.Address) (*big.Int, error) { + return _FaultDisputeGame.Contract.Credit(&_FaultDisputeGame.CallOpts, arg0) +} + +// Credit is a free data retrieval call binding the contract method 0xd5d44d80. +// +// Solidity: function credit(address ) view returns(uint256) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) Credit(arg0 common.Address) (*big.Int, error) { + return _FaultDisputeGame.Contract.Credit(&_FaultDisputeGame.CallOpts, arg0) +} + // ExtraData is a free data retrieval call binding the contract method 0x609d3334. // // Solidity: function extraData() pure returns(bytes extraData_) @@ -580,9 +459,9 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) ExtraData() ([]byte, err // GameData is a free data retrieval call binding the contract method 0xfa24f743. // -// Solidity: function gameData() view returns(uint8 gameType_, bytes32 rootClaim_, bytes extraData_) +// Solidity: function gameData() view returns(uint32 gameType_, bytes32 rootClaim_, bytes extraData_) func (_FaultDisputeGame *FaultDisputeGameCaller) GameData(opts *bind.CallOpts) (struct { - GameType uint8 + GameType uint32 RootClaim [32]byte ExtraData []byte }, error) { @@ -590,7 +469,7 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) GameData(opts *bind.CallOpts) ( err := _FaultDisputeGame.contract.Call(opts, &out, "gameData") outstruct := new(struct { - GameType uint8 + GameType uint32 RootClaim [32]byte ExtraData []byte }) @@ -598,7 +477,7 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) GameData(opts *bind.CallOpts) ( return *outstruct, err } - outstruct.GameType = *abi.ConvertType(out[0], new(uint8)).(*uint8) + outstruct.GameType = *abi.ConvertType(out[0], new(uint32)).(*uint32) outstruct.RootClaim = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) outstruct.ExtraData = *abi.ConvertType(out[2], new([]byte)).(*[]byte) @@ -608,9 +487,9 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) GameData(opts *bind.CallOpts) ( // GameData is a free data retrieval call binding the contract method 0xfa24f743. // -// Solidity: function gameData() view returns(uint8 gameType_, bytes32 rootClaim_, bytes extraData_) +// Solidity: function gameData() view returns(uint32 gameType_, bytes32 rootClaim_, bytes extraData_) func (_FaultDisputeGame *FaultDisputeGameSession) GameData() (struct { - GameType uint8 + GameType uint32 RootClaim [32]byte ExtraData []byte }, error) { @@ -619,27 +498,58 @@ func (_FaultDisputeGame *FaultDisputeGameSession) GameData() (struct { // GameData is a free data retrieval call binding the contract method 0xfa24f743. // -// Solidity: function gameData() view returns(uint8 gameType_, bytes32 rootClaim_, bytes extraData_) +// Solidity: function gameData() view returns(uint32 gameType_, bytes32 rootClaim_, bytes extraData_) func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameData() (struct { - GameType uint8 + GameType uint32 RootClaim [32]byte ExtraData []byte }, error) { return _FaultDisputeGame.Contract.GameData(&_FaultDisputeGame.CallOpts) } +// GameDuration is a free data retrieval call binding the contract method 0xe1f0c376. +// +// Solidity: function gameDuration() view returns(uint64 gameDuration_) +func (_FaultDisputeGame *FaultDisputeGameCaller) GameDuration(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "gameDuration") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// GameDuration is a free data retrieval call binding the contract method 0xe1f0c376. +// +// Solidity: function gameDuration() view returns(uint64 gameDuration_) +func (_FaultDisputeGame *FaultDisputeGameSession) GameDuration() (uint64, error) { + return _FaultDisputeGame.Contract.GameDuration(&_FaultDisputeGame.CallOpts) +} + +// GameDuration is a free data retrieval call binding the contract method 0xe1f0c376. +// +// Solidity: function gameDuration() view returns(uint64 gameDuration_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameDuration() (uint64, error) { + return _FaultDisputeGame.Contract.GameDuration(&_FaultDisputeGame.CallOpts) +} + // GameType is a free data retrieval call binding the contract method 0xbbdc02db. // -// Solidity: function gameType() view returns(uint8 gameType_) -func (_FaultDisputeGame *FaultDisputeGameCaller) GameType(opts *bind.CallOpts) (uint8, error) { +// Solidity: function gameType() view returns(uint32 gameType_) +func (_FaultDisputeGame *FaultDisputeGameCaller) GameType(opts *bind.CallOpts) (uint32, error) { var out []interface{} err := _FaultDisputeGame.contract.Call(opts, &out, "gameType") if err != nil { - return *new(uint8), err + return *new(uint32), err } - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) return out0, err @@ -647,24 +557,24 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) GameType(opts *bind.CallOpts) ( // GameType is a free data retrieval call binding the contract method 0xbbdc02db. // -// Solidity: function gameType() view returns(uint8 gameType_) -func (_FaultDisputeGame *FaultDisputeGameSession) GameType() (uint8, error) { +// Solidity: function gameType() view returns(uint32 gameType_) +func (_FaultDisputeGame *FaultDisputeGameSession) GameType() (uint32, error) { return _FaultDisputeGame.Contract.GameType(&_FaultDisputeGame.CallOpts) } // GameType is a free data retrieval call binding the contract method 0xbbdc02db. // -// Solidity: function gameType() view returns(uint8 gameType_) -func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameType() (uint8, error) { +// Solidity: function gameType() view returns(uint32 gameType_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameType() (uint32, error) { return _FaultDisputeGame.Contract.GameType(&_FaultDisputeGame.CallOpts) } -// L1BlockNumber is a free data retrieval call binding the contract method 0x298c9005. +// GetRequiredBond is a free data retrieval call binding the contract method 0xc395e1ca. // -// Solidity: function l1BlockNumber() pure returns(uint256 l1BlockNumber_) -func (_FaultDisputeGame *FaultDisputeGameCaller) L1BlockNumber(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function getRequiredBond(uint128 _position) view returns(uint256 requiredBond_) +func (_FaultDisputeGame *FaultDisputeGameCaller) GetRequiredBond(opts *bind.CallOpts, _position *big.Int) (*big.Int, error) { var out []interface{} - err := _FaultDisputeGame.contract.Call(opts, &out, "l1BlockNumber") + err := _FaultDisputeGame.contract.Call(opts, &out, "getRequiredBond", _position) if err != nil { return *new(*big.Int), err @@ -676,23 +586,23 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) L1BlockNumber(opts *bind.CallOp } -// L1BlockNumber is a free data retrieval call binding the contract method 0x298c9005. +// GetRequiredBond is a free data retrieval call binding the contract method 0xc395e1ca. // -// Solidity: function l1BlockNumber() pure returns(uint256 l1BlockNumber_) -func (_FaultDisputeGame *FaultDisputeGameSession) L1BlockNumber() (*big.Int, error) { - return _FaultDisputeGame.Contract.L1BlockNumber(&_FaultDisputeGame.CallOpts) +// Solidity: function getRequiredBond(uint128 _position) view returns(uint256 requiredBond_) +func (_FaultDisputeGame *FaultDisputeGameSession) GetRequiredBond(_position *big.Int) (*big.Int, error) { + return _FaultDisputeGame.Contract.GetRequiredBond(&_FaultDisputeGame.CallOpts, _position) } -// L1BlockNumber is a free data retrieval call binding the contract method 0x298c9005. +// GetRequiredBond is a free data retrieval call binding the contract method 0xc395e1ca. // -// Solidity: function l1BlockNumber() pure returns(uint256 l1BlockNumber_) -func (_FaultDisputeGame *FaultDisputeGameCallerSession) L1BlockNumber() (*big.Int, error) { - return _FaultDisputeGame.Contract.L1BlockNumber(&_FaultDisputeGame.CallOpts) +// Solidity: function getRequiredBond(uint128 _position) view returns(uint256 requiredBond_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) GetRequiredBond(_position *big.Int) (*big.Int, error) { + return _FaultDisputeGame.Contract.GetRequiredBond(&_FaultDisputeGame.CallOpts, _position) } // L1Head is a free data retrieval call binding the contract method 0x6361506d. // -// Solidity: function l1Head() view returns(bytes32) +// Solidity: function l1Head() pure returns(bytes32 l1Head_) func (_FaultDisputeGame *FaultDisputeGameCaller) L1Head(opts *bind.CallOpts) ([32]byte, error) { var out []interface{} err := _FaultDisputeGame.contract.Call(opts, &out, "l1Head") @@ -709,14 +619,14 @@ func (_FaultDisputeGame *FaultDisputeGameCaller) L1Head(opts *bind.CallOpts) ([3 // L1Head is a free data retrieval call binding the contract method 0x6361506d. // -// Solidity: function l1Head() view returns(bytes32) +// Solidity: function l1Head() pure returns(bytes32 l1Head_) func (_FaultDisputeGame *FaultDisputeGameSession) L1Head() ([32]byte, error) { return _FaultDisputeGame.Contract.L1Head(&_FaultDisputeGame.CallOpts) } // L1Head is a free data retrieval call binding the contract method 0x6361506d. // -// Solidity: function l1Head() view returns(bytes32) +// Solidity: function l1Head() pure returns(bytes32 l1Head_) func (_FaultDisputeGame *FaultDisputeGameCallerSession) L1Head() ([32]byte, error) { return _FaultDisputeGame.Contract.L1Head(&_FaultDisputeGame.CallOpts) } @@ -752,49 +662,97 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) L2BlockNumber() (*big.In return _FaultDisputeGame.Contract.L2BlockNumber(&_FaultDisputeGame.CallOpts) } -// Proposals is a free data retrieval call binding the contract method 0x55ef20e6. +// L2ChainId is a free data retrieval call binding the contract method 0xd6ae3cd5. // -// Solidity: function proposals() view returns((uint128,uint128,bytes32) starting, (uint128,uint128,bytes32) disputed) -func (_FaultDisputeGame *FaultDisputeGameCaller) Proposals(opts *bind.CallOpts) (struct { - Starting IFaultDisputeGameOutputProposal - Disputed IFaultDisputeGameOutputProposal -}, error) { +// Solidity: function l2ChainId() view returns(uint256 l2ChainId_) +func (_FaultDisputeGame *FaultDisputeGameCaller) L2ChainId(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _FaultDisputeGame.contract.Call(opts, &out, "proposals") + err := _FaultDisputeGame.contract.Call(opts, &out, "l2ChainId") - outstruct := new(struct { - Starting IFaultDisputeGameOutputProposal - Disputed IFaultDisputeGameOutputProposal - }) if err != nil { - return *outstruct, err + return *new(*big.Int), err } - outstruct.Starting = *abi.ConvertType(out[0], new(IFaultDisputeGameOutputProposal)).(*IFaultDisputeGameOutputProposal) - outstruct.Disputed = *abi.ConvertType(out[1], new(IFaultDisputeGameOutputProposal)).(*IFaultDisputeGameOutputProposal) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - return *outstruct, err + return out0, err } -// Proposals is a free data retrieval call binding the contract method 0x55ef20e6. +// L2ChainId is a free data retrieval call binding the contract method 0xd6ae3cd5. // -// Solidity: function proposals() view returns((uint128,uint128,bytes32) starting, (uint128,uint128,bytes32) disputed) -func (_FaultDisputeGame *FaultDisputeGameSession) Proposals() (struct { - Starting IFaultDisputeGameOutputProposal - Disputed IFaultDisputeGameOutputProposal -}, error) { - return _FaultDisputeGame.Contract.Proposals(&_FaultDisputeGame.CallOpts) +// Solidity: function l2ChainId() view returns(uint256 l2ChainId_) +func (_FaultDisputeGame *FaultDisputeGameSession) L2ChainId() (*big.Int, error) { + return _FaultDisputeGame.Contract.L2ChainId(&_FaultDisputeGame.CallOpts) } -// Proposals is a free data retrieval call binding the contract method 0x55ef20e6. +// L2ChainId is a free data retrieval call binding the contract method 0xd6ae3cd5. // -// Solidity: function proposals() view returns((uint128,uint128,bytes32) starting, (uint128,uint128,bytes32) disputed) -func (_FaultDisputeGame *FaultDisputeGameCallerSession) Proposals() (struct { - Starting IFaultDisputeGameOutputProposal - Disputed IFaultDisputeGameOutputProposal -}, error) { - return _FaultDisputeGame.Contract.Proposals(&_FaultDisputeGame.CallOpts) +// Solidity: function l2ChainId() view returns(uint256 l2ChainId_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) L2ChainId() (*big.Int, error) { + return _FaultDisputeGame.Contract.L2ChainId(&_FaultDisputeGame.CallOpts) +} + +// MaxGameDepth is a free data retrieval call binding the contract method 0xfa315aa9. +// +// Solidity: function maxGameDepth() view returns(uint256 maxGameDepth_) +func (_FaultDisputeGame *FaultDisputeGameCaller) MaxGameDepth(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "maxGameDepth") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MaxGameDepth is a free data retrieval call binding the contract method 0xfa315aa9. +// +// Solidity: function maxGameDepth() view returns(uint256 maxGameDepth_) +func (_FaultDisputeGame *FaultDisputeGameSession) MaxGameDepth() (*big.Int, error) { + return _FaultDisputeGame.Contract.MaxGameDepth(&_FaultDisputeGame.CallOpts) +} + +// MaxGameDepth is a free data retrieval call binding the contract method 0xfa315aa9. +// +// Solidity: function maxGameDepth() view returns(uint256 maxGameDepth_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) MaxGameDepth() (*big.Int, error) { + return _FaultDisputeGame.Contract.MaxGameDepth(&_FaultDisputeGame.CallOpts) +} + +// ResolvedAt is a free data retrieval call binding the contract method 0x19effeb4. +// +// Solidity: function resolvedAt() view returns(uint64) +func (_FaultDisputeGame *FaultDisputeGameCaller) ResolvedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "resolvedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// ResolvedAt is a free data retrieval call binding the contract method 0x19effeb4. +// +// Solidity: function resolvedAt() view returns(uint64) +func (_FaultDisputeGame *FaultDisputeGameSession) ResolvedAt() (uint64, error) { + return _FaultDisputeGame.Contract.ResolvedAt(&_FaultDisputeGame.CallOpts) +} + +// ResolvedAt is a free data retrieval call binding the contract method 0x19effeb4. +// +// Solidity: function resolvedAt() view returns(uint64) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) ResolvedAt() (uint64, error) { + return _FaultDisputeGame.Contract.ResolvedAt(&_FaultDisputeGame.CallOpts) } // RootClaim is a free data retrieval call binding the contract method 0xbcef3b55. @@ -828,6 +786,144 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) RootClaim() ([32]byte, e return _FaultDisputeGame.Contract.RootClaim(&_FaultDisputeGame.CallOpts) } +// SplitDepth is a free data retrieval call binding the contract method 0xec5e6308. +// +// Solidity: function splitDepth() view returns(uint256 splitDepth_) +func (_FaultDisputeGame *FaultDisputeGameCaller) SplitDepth(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "splitDepth") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SplitDepth is a free data retrieval call binding the contract method 0xec5e6308. +// +// Solidity: function splitDepth() view returns(uint256 splitDepth_) +func (_FaultDisputeGame *FaultDisputeGameSession) SplitDepth() (*big.Int, error) { + return _FaultDisputeGame.Contract.SplitDepth(&_FaultDisputeGame.CallOpts) +} + +// SplitDepth is a free data retrieval call binding the contract method 0xec5e6308. +// +// Solidity: function splitDepth() view returns(uint256 splitDepth_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) SplitDepth() (*big.Int, error) { + return _FaultDisputeGame.Contract.SplitDepth(&_FaultDisputeGame.CallOpts) +} + +// StartingBlockNumber is a free data retrieval call binding the contract method 0x70872aa5. +// +// Solidity: function startingBlockNumber() view returns(uint256 startingBlockNumber_) +func (_FaultDisputeGame *FaultDisputeGameCaller) StartingBlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "startingBlockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// StartingBlockNumber is a free data retrieval call binding the contract method 0x70872aa5. +// +// Solidity: function startingBlockNumber() view returns(uint256 startingBlockNumber_) +func (_FaultDisputeGame *FaultDisputeGameSession) StartingBlockNumber() (*big.Int, error) { + return _FaultDisputeGame.Contract.StartingBlockNumber(&_FaultDisputeGame.CallOpts) +} + +// StartingBlockNumber is a free data retrieval call binding the contract method 0x70872aa5. +// +// Solidity: function startingBlockNumber() view returns(uint256 startingBlockNumber_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) StartingBlockNumber() (*big.Int, error) { + return _FaultDisputeGame.Contract.StartingBlockNumber(&_FaultDisputeGame.CallOpts) +} + +// StartingOutputRoot is a free data retrieval call binding the contract method 0x57da950e. +// +// Solidity: function startingOutputRoot() view returns(bytes32 root, uint256 l2BlockNumber) +func (_FaultDisputeGame *FaultDisputeGameCaller) StartingOutputRoot(opts *bind.CallOpts) (struct { + Root [32]byte + L2BlockNumber *big.Int +}, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "startingOutputRoot") + + outstruct := new(struct { + Root [32]byte + L2BlockNumber *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Root = *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + outstruct.L2BlockNumber = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// StartingOutputRoot is a free data retrieval call binding the contract method 0x57da950e. +// +// Solidity: function startingOutputRoot() view returns(bytes32 root, uint256 l2BlockNumber) +func (_FaultDisputeGame *FaultDisputeGameSession) StartingOutputRoot() (struct { + Root [32]byte + L2BlockNumber *big.Int +}, error) { + return _FaultDisputeGame.Contract.StartingOutputRoot(&_FaultDisputeGame.CallOpts) +} + +// StartingOutputRoot is a free data retrieval call binding the contract method 0x57da950e. +// +// Solidity: function startingOutputRoot() view returns(bytes32 root, uint256 l2BlockNumber) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) StartingOutputRoot() (struct { + Root [32]byte + L2BlockNumber *big.Int +}, error) { + return _FaultDisputeGame.Contract.StartingOutputRoot(&_FaultDisputeGame.CallOpts) +} + +// StartingRootHash is a free data retrieval call binding the contract method 0x25fc2ace. +// +// Solidity: function startingRootHash() view returns(bytes32 startingRootHash_) +func (_FaultDisputeGame *FaultDisputeGameCaller) StartingRootHash(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "startingRootHash") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// StartingRootHash is a free data retrieval call binding the contract method 0x25fc2ace. +// +// Solidity: function startingRootHash() view returns(bytes32 startingRootHash_) +func (_FaultDisputeGame *FaultDisputeGameSession) StartingRootHash() ([32]byte, error) { + return _FaultDisputeGame.Contract.StartingRootHash(&_FaultDisputeGame.CallOpts) +} + +// StartingRootHash is a free data retrieval call binding the contract method 0x25fc2ace. +// +// Solidity: function startingRootHash() view returns(bytes32 startingRootHash_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) StartingRootHash() ([32]byte, error) { + return _FaultDisputeGame.Contract.StartingRootHash(&_FaultDisputeGame.CallOpts) +} + // Status is a free data retrieval call binding the contract method 0x200d2ed2. // // Solidity: function status() view returns(uint8) @@ -890,25 +986,87 @@ func (_FaultDisputeGame *FaultDisputeGameCallerSession) Version() (string, error return _FaultDisputeGame.Contract.Version(&_FaultDisputeGame.CallOpts) } +// Vm is a free data retrieval call binding the contract method 0x3a768463. +// +// Solidity: function vm() view returns(address vm_) +func (_FaultDisputeGame *FaultDisputeGameCaller) Vm(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "vm") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Vm is a free data retrieval call binding the contract method 0x3a768463. +// +// Solidity: function vm() view returns(address vm_) +func (_FaultDisputeGame *FaultDisputeGameSession) Vm() (common.Address, error) { + return _FaultDisputeGame.Contract.Vm(&_FaultDisputeGame.CallOpts) +} + +// Vm is a free data retrieval call binding the contract method 0x3a768463. +// +// Solidity: function vm() view returns(address vm_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) Vm() (common.Address, error) { + return _FaultDisputeGame.Contract.Vm(&_FaultDisputeGame.CallOpts) +} + +// Weth is a free data retrieval call binding the contract method 0x3fc8cef3. +// +// Solidity: function weth() view returns(address weth_) +func (_FaultDisputeGame *FaultDisputeGameCaller) Weth(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _FaultDisputeGame.contract.Call(opts, &out, "weth") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Weth is a free data retrieval call binding the contract method 0x3fc8cef3. +// +// Solidity: function weth() view returns(address weth_) +func (_FaultDisputeGame *FaultDisputeGameSession) Weth() (common.Address, error) { + return _FaultDisputeGame.Contract.Weth(&_FaultDisputeGame.CallOpts) +} + +// Weth is a free data retrieval call binding the contract method 0x3fc8cef3. +// +// Solidity: function weth() view returns(address weth_) +func (_FaultDisputeGame *FaultDisputeGameCallerSession) Weth() (common.Address, error) { + return _FaultDisputeGame.Contract.Weth(&_FaultDisputeGame.CallOpts) +} + // AddLocalData is a paid mutator transaction binding the contract method 0xf8f43ff6. // -// Solidity: function addLocalData(uint256 _ident, uint256 _l2BlockNumber, uint256 _partOffset) returns() -func (_FaultDisputeGame *FaultDisputeGameTransactor) AddLocalData(opts *bind.TransactOpts, _ident *big.Int, _l2BlockNumber *big.Int, _partOffset *big.Int) (*types.Transaction, error) { - return _FaultDisputeGame.contract.Transact(opts, "addLocalData", _ident, _l2BlockNumber, _partOffset) +// Solidity: function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) returns() +func (_FaultDisputeGame *FaultDisputeGameTransactor) AddLocalData(opts *bind.TransactOpts, _ident *big.Int, _execLeafIdx *big.Int, _partOffset *big.Int) (*types.Transaction, error) { + return _FaultDisputeGame.contract.Transact(opts, "addLocalData", _ident, _execLeafIdx, _partOffset) } // AddLocalData is a paid mutator transaction binding the contract method 0xf8f43ff6. // -// Solidity: function addLocalData(uint256 _ident, uint256 _l2BlockNumber, uint256 _partOffset) returns() -func (_FaultDisputeGame *FaultDisputeGameSession) AddLocalData(_ident *big.Int, _l2BlockNumber *big.Int, _partOffset *big.Int) (*types.Transaction, error) { - return _FaultDisputeGame.Contract.AddLocalData(&_FaultDisputeGame.TransactOpts, _ident, _l2BlockNumber, _partOffset) +// Solidity: function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) returns() +func (_FaultDisputeGame *FaultDisputeGameSession) AddLocalData(_ident *big.Int, _execLeafIdx *big.Int, _partOffset *big.Int) (*types.Transaction, error) { + return _FaultDisputeGame.Contract.AddLocalData(&_FaultDisputeGame.TransactOpts, _ident, _execLeafIdx, _partOffset) } // AddLocalData is a paid mutator transaction binding the contract method 0xf8f43ff6. // -// Solidity: function addLocalData(uint256 _ident, uint256 _l2BlockNumber, uint256 _partOffset) returns() -func (_FaultDisputeGame *FaultDisputeGameTransactorSession) AddLocalData(_ident *big.Int, _l2BlockNumber *big.Int, _partOffset *big.Int) (*types.Transaction, error) { - return _FaultDisputeGame.Contract.AddLocalData(&_FaultDisputeGame.TransactOpts, _ident, _l2BlockNumber, _partOffset) +// Solidity: function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) returns() +func (_FaultDisputeGame *FaultDisputeGameTransactorSession) AddLocalData(_ident *big.Int, _execLeafIdx *big.Int, _partOffset *big.Int) (*types.Transaction, error) { + return _FaultDisputeGame.Contract.AddLocalData(&_FaultDisputeGame.TransactOpts, _ident, _execLeafIdx, _partOffset) } // Attack is a paid mutator transaction binding the contract method 0xc55cd0c7. @@ -932,6 +1090,27 @@ func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Attack(_parentIndex return _FaultDisputeGame.Contract.Attack(&_FaultDisputeGame.TransactOpts, _parentIndex, _claim) } +// ClaimCredit is a paid mutator transaction binding the contract method 0x60e27464. +// +// Solidity: function claimCredit(address _recipient) returns() +func (_FaultDisputeGame *FaultDisputeGameTransactor) ClaimCredit(opts *bind.TransactOpts, _recipient common.Address) (*types.Transaction, error) { + return _FaultDisputeGame.contract.Transact(opts, "claimCredit", _recipient) +} + +// ClaimCredit is a paid mutator transaction binding the contract method 0x60e27464. +// +// Solidity: function claimCredit(address _recipient) returns() +func (_FaultDisputeGame *FaultDisputeGameSession) ClaimCredit(_recipient common.Address) (*types.Transaction, error) { + return _FaultDisputeGame.Contract.ClaimCredit(&_FaultDisputeGame.TransactOpts, _recipient) +} + +// ClaimCredit is a paid mutator transaction binding the contract method 0x60e27464. +// +// Solidity: function claimCredit(address _recipient) returns() +func (_FaultDisputeGame *FaultDisputeGameTransactorSession) ClaimCredit(_recipient common.Address) (*types.Transaction, error) { + return _FaultDisputeGame.Contract.ClaimCredit(&_FaultDisputeGame.TransactOpts, _recipient) +} + // Defend is a paid mutator transaction binding the contract method 0x35fef567. // // Solidity: function defend(uint256 _parentIndex, bytes32 _claim) payable returns() @@ -955,21 +1134,21 @@ func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Defend(_parentIndex // Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. // -// Solidity: function initialize() returns() +// Solidity: function initialize() payable returns() func (_FaultDisputeGame *FaultDisputeGameTransactor) Initialize(opts *bind.TransactOpts) (*types.Transaction, error) { return _FaultDisputeGame.contract.Transact(opts, "initialize") } // Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. // -// Solidity: function initialize() returns() +// Solidity: function initialize() payable returns() func (_FaultDisputeGame *FaultDisputeGameSession) Initialize() (*types.Transaction, error) { return _FaultDisputeGame.Contract.Initialize(&_FaultDisputeGame.TransactOpts) } // Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. // -// Solidity: function initialize() returns() +// Solidity: function initialize() payable returns() func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Initialize() (*types.Transaction, error) { return _FaultDisputeGame.Contract.Initialize(&_FaultDisputeGame.TransactOpts) } @@ -1058,6 +1237,48 @@ func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Step(_claimIndex *bi return _FaultDisputeGame.Contract.Step(&_FaultDisputeGame.TransactOpts, _claimIndex, _isAttack, _stateData, _proof) } +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_FaultDisputeGame *FaultDisputeGameTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _FaultDisputeGame.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_FaultDisputeGame *FaultDisputeGameSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _FaultDisputeGame.Contract.Fallback(&_FaultDisputeGame.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _FaultDisputeGame.Contract.Fallback(&_FaultDisputeGame.TransactOpts, calldata) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_FaultDisputeGame *FaultDisputeGameTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FaultDisputeGame.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_FaultDisputeGame *FaultDisputeGameSession) Receive() (*types.Transaction, error) { + return _FaultDisputeGame.Contract.Receive(&_FaultDisputeGame.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Receive() (*types.Transaction, error) { + return _FaultDisputeGame.Contract.Receive(&_FaultDisputeGame.TransactOpts) +} + // FaultDisputeGameMoveIterator is returned from FilterMove and is used to iterate over the raw logs and unpacked data for Move events raised by the FaultDisputeGame contract. type FaultDisputeGameMoveIterator struct { Event *FaultDisputeGameMove // Event containing the contract specifics and raw log diff --git a/op-bindings/bindings/faultdisputegame_more.go b/op-bindings/bindings/faultdisputegame_more.go index 896757e12c84..f2a2d88a23a6 100644 --- a/op-bindings/bindings/faultdisputegame_more.go +++ b/op-bindings/bindings/faultdisputegame_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const FaultDisputeGameStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"createdAt\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_userDefinedValueType(Timestamp)1019\"},{\"astId\":1001,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"status\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_enum(GameStatus)1010\"},{\"astId\":1002,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"bondManager\",\"offset\":9,\"slot\":\"0\",\"type\":\"t_contract(IBondManager)1009\"},{\"astId\":1003,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"l1Head\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_userDefinedValueType(Hash)1017\"},{\"astId\":1004,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claimData\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\"},{\"astId\":1005,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"proposals\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_struct(OutputProposals)1013_storage\"},{\"astId\":1006,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claims\",\"offset\":0,\"slot\":\"7\",\"type\":\"t_mapping(t_userDefinedValueType(ClaimHash)1015,t_bool)\"},{\"astId\":1007,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgames\",\"offset\":0,\"slot\":\"8\",\"type\":\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\"},{\"astId\":1008,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgameAtRootResolved\",\"offset\":0,\"slot\":\"9\",\"type\":\"t_bool\"}],\"types\":{\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct IFaultDisputeGame.ClaimData[]\",\"numberOfBytes\":\"32\",\"base\":\"t_struct(ClaimData)1011_storage\"},\"t_array(t_uint256)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"uint256[]\",\"numberOfBytes\":\"32\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(IBondManager)1009\":{\"encoding\":\"inplace\",\"label\":\"contract IBondManager\",\"numberOfBytes\":\"20\"},\"t_enum(GameStatus)1010\":{\"encoding\":\"inplace\",\"label\":\"enum GameStatus\",\"numberOfBytes\":\"1\"},\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e uint256[])\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_array(t_uint256)dyn_storage\"},\"t_mapping(t_userDefinedValueType(ClaimHash)1015,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(ClaimHash =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(ClaimHash)1015\",\"value\":\"t_bool\"},\"t_struct(ClaimData)1011_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IFaultDisputeGame.ClaimData\",\"numberOfBytes\":\"96\"},\"t_struct(OutputProposal)1012_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IFaultDisputeGame.OutputProposal\",\"numberOfBytes\":\"64\"},\"t_struct(OutputProposals)1013_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IFaultDisputeGame.OutputProposals\",\"numberOfBytes\":\"128\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"},\"t_userDefinedValueType(Claim)1014\":{\"encoding\":\"inplace\",\"label\":\"Claim\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(ClaimHash)1015\":{\"encoding\":\"inplace\",\"label\":\"ClaimHash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Clock)1016\":{\"encoding\":\"inplace\",\"label\":\"Clock\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Hash)1017\":{\"encoding\":\"inplace\",\"label\":\"Hash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Position)1018\":{\"encoding\":\"inplace\",\"label\":\"Position\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Timestamp)1019\":{\"encoding\":\"inplace\",\"label\":\"Timestamp\",\"numberOfBytes\":\"8\"}}}" +const FaultDisputeGameStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"createdAt\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_userDefinedValueType(Timestamp)1018\"},{\"astId\":1001,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"resolvedAt\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_userDefinedValueType(Timestamp)1018\"},{\"astId\":1002,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"status\",\"offset\":16,\"slot\":\"0\",\"type\":\"t_enum(GameStatus)1010\"},{\"astId\":1003,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claimData\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\"},{\"astId\":1004,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"credit\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":1005,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"claims\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_mapping(t_userDefinedValueType(ClaimHash)1014,t_bool)\"},{\"astId\":1006,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgames\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\"},{\"astId\":1007,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"subgameAtRootResolved\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_bool\"},{\"astId\":1008,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"initialized\",\"offset\":1,\"slot\":\"5\",\"type\":\"t_bool\"},{\"astId\":1009,\"contract\":\"src/dispute/FaultDisputeGame.sol:FaultDisputeGame\",\"label\":\"startingOutputRoot\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_struct(OutputRoot)1012_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_struct(ClaimData)1011_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct IFaultDisputeGame.ClaimData[]\",\"numberOfBytes\":\"32\",\"base\":\"t_struct(ClaimData)1011_storage\"},\"t_array(t_uint256)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"uint256[]\",\"numberOfBytes\":\"32\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_enum(GameStatus)1010\":{\"encoding\":\"inplace\",\"label\":\"enum GameStatus\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_mapping(t_uint256,t_array(t_uint256)dyn_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e uint256[])\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_array(t_uint256)dyn_storage\"},\"t_mapping(t_userDefinedValueType(ClaimHash)1014,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(ClaimHash =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_userDefinedValueType(ClaimHash)1014\",\"value\":\"t_bool\"},\"t_struct(ClaimData)1011_storage\":{\"encoding\":\"inplace\",\"label\":\"struct IFaultDisputeGame.ClaimData\",\"numberOfBytes\":\"160\"},\"t_struct(OutputRoot)1012_storage\":{\"encoding\":\"inplace\",\"label\":\"struct OutputRoot\",\"numberOfBytes\":\"64\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"},\"t_userDefinedValueType(Claim)1013\":{\"encoding\":\"inplace\",\"label\":\"Claim\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(ClaimHash)1014\":{\"encoding\":\"inplace\",\"label\":\"ClaimHash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Clock)1015\":{\"encoding\":\"inplace\",\"label\":\"Clock\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Hash)1016\":{\"encoding\":\"inplace\",\"label\":\"Hash\",\"numberOfBytes\":\"32\"},\"t_userDefinedValueType(Position)1017\":{\"encoding\":\"inplace\",\"label\":\"Position\",\"numberOfBytes\":\"16\"},\"t_userDefinedValueType(Timestamp)1018\":{\"encoding\":\"inplace\",\"label\":\"Timestamp\",\"numberOfBytes\":\"8\"}}}" var FaultDisputeGameStorageLayout = new(solc.StorageLayout) -var FaultDisputeGameDeployedBin = "0x6080604052600436106101b75760003560e01c80638980e0cc116100ec578063c55cd0c71161008a578063d8cc1a3c11610064578063d8cc1a3c146106c1578063f8f43ff6146106e1578063fa24f74314610701578063fdffbb281461072557600080fd5b8063c55cd0c714610629578063c6f0308c1461063c578063cf09e0d0146106a057600080fd5b8063bbdc02db116100c6578063bbdc02db1461052d578063bcef3b551461056b578063c0c3a092146105a8578063c31b29ce146105dc57600080fd5b80638980e0cc146104a45780638b85902b146104b957806392931298146104f957600080fd5b8063529184c911610159578063609d333411610133578063609d333414610451578063632247ea146104665780636361506d146104795780638129fc1c1461048f57600080fd5b8063529184c91461033757806354fd4d501461036b57806355ef20e6146103c157600080fd5b8063298c900511610195578063298c90051461024f57806335fef5671461028f578063363cc427146102a45780634778efe81461030357600080fd5b8063200d2ed2146101bc578063266198f9146101f85780632810e1d61461023a575b600080fd5b3480156101c857600080fd5b506000546101e29068010000000000000000900460ff1681565b6040516101ef91906122c8565b60405180910390f35b34801561020457600080fd5b5061022c7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101ef565b34801561024657600080fd5b506101e2610738565b34801561025b57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561022c565b6102a261029d366004612309565b61089c565b005b3480156102b057600080fd5b506000546102de906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ef565b34801561030f57600080fd5b5061022c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561034357600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b34801561037757600080fd5b506103b46040518060400160405280600681526020017f302e302e3131000000000000000000000000000000000000000000000000000081525081565b6040516101ef9190612396565b3480156103cd57600080fd5b5060408051606080820183526003546fffffffffffffffffffffffffffffffff808216845270010000000000000000000000000000000091829004811660208086019190915260045485870152855193840186526005548083168552929092041690820152600654928101929092526104439182565b6040516101ef9291906123b0565b34801561045d57600080fd5b506103b46108ac565b6102a2610474366004612419565b6108ba565b34801561048557600080fd5b5061022c60015481565b34801561049b57600080fd5b506102a2610ed0565b3480156104b057600080fd5b5060025461022c565b3480156104c557600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561022c565b34801561050557600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b34801561053957600080fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101ef565b34801561057757600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561022c565b3480156105b457600080fd5b506102de7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105e857600080fd5b506106107f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff90911681526020016101ef565b6102a2610637366004612309565b6114d4565b34801561064857600080fd5b5061065c61065736600461244e565b6114e0565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101ef565b3480156106ac57600080fd5b506000546106109067ffffffffffffffff1681565b3480156106cd57600080fd5b506102a26106dc3660046124b0565b611551565b3480156106ed57600080fd5b506102a26106fc36600461253a565b611a7d565b34801561070d57600080fd5b50610716611c42565b6040516101ef93929190612566565b6102a261073336600461244e565b611c9f565b60008060005468010000000000000000900460ff16600281111561075e5761075e612299565b14610795576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460ff166107d1576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000815481106107e5576107e5612591565b6000918252602090912060039091020154640100000000900460ff1661080c57600261080f565b60015b6000805491925082917fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff166801000000000000000083600281111561085657610856612299565b02179055600281111561086b5761086b612299565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b905090565b6108a8828260006108ba565b5050565b606061089760206040611fd1565b6000805468010000000000000000900460ff1660028111156108de576108de612299565b14610915576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610921575080155b15610958576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002848154811061096d5761096d612591565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff80821660608501819052700100000000000000000000000000000000909204166080840152919350610a019190859061206816565b90507f0000000000000000000000000000000000000000000000000000000000000000610ac0826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610b02576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610b62576002836000015163ffffffff1681548110610b3157610b31612591565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610b9b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610baf91906125ef565b610bb99190612607565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff82161115610c2c576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b42176000888152608086901b6fffffffffffffffffffffffffffffffff8b1617602052604081209192509060008181526007602052604090205490915060ff1615610caa576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260076020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581529281018d81526fffffffffffffffffffffffffffffffff808c16606084019081528982166080850190815260028054808801825599819052945160039099027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101805498511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009099169a909916999099179690961790965590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8701559351925184167001000000000000000000000000000000000292909316919091177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad09093019290925580548b908110610e2257610e22612591565b6000918252602080832060039092029091018054931515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909416939093179092558a8152600890915260409020600254610e8690600190612607565b8154600181018355600092835260208320015560405133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560001a6001811480610f10575060ff81166002145b610f76576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335600482015260240160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff81526020810192909252600291908101610ffb7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff9081169091528254600181810185556000948552602080862085516003909402018054918601511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090921663ffffffff909416939093171782556040840151908201556060830151608090930151821670010000000000000000000000000000000002929091169190911760029091015573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016637f00642061112460207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c9003013590565b6040518263ffffffff1660e01b815260040161114291815260200190565b602060405180830381865afa15801561115f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611183919061261e565b9050600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae5576111ce600185612607565b6040518263ffffffff1660e01b81526004016111ec91815260200190565b606060405180830381865afa158015611209573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122d9190612686565b6040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810184905290915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa1580156112be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e29190612686565b9050600073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166399d548aa367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003604001356040518263ffffffff1660e01b815260040161136e91815260200190565b6040805180830381865afa15801561138a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ae9190612712565b905081602001516fffffffffffffffffffffffffffffffff16816020015167ffffffffffffffff161161140d576040517f13809ba500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a081018252908190810180611428600189612607565b6fffffffffffffffffffffffffffffffff908116825260408881015182166020808501919091529851928101929092529183528051606081018252978216885285810151821688880152945187860152908501959095528051805181860151908716700100000000000000000000000000000000918816820217600355908401516004559084015180519481015194861694909516029290921760055591909101516006555160015550565b6108a8828260016108ba565b600281815481106114f057600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff16600281111561157557611575612299565b146115ac576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600287815481106115c1576115c1612591565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506116207f000000000000000000000000000000000000000000000000000000000000000060016125ef565b6116bc826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16146116fd576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561178057611721836fffffffffffffffffffffffffffffffff16612070565b67ffffffffffffffff16156117545761174b61173e600186612799565b865463ffffffff16612116565b60010154611776565b7f00000000000000000000000000000000000000000000000000000000000000005b915084905061179a565b8460010154915061179784600161173e91906127ca565b90505b600882901b60088a8a6040516117b19291906127fe565b6040518091039020901b146117f2576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663836e7b328c8c8c8c60006040518663ffffffff1660e01b815260040161185b959493929190612857565b6020604051808303816000875af115801561187a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189e919061261e565b600284810154929091149250600091611949906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6119e5886fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6119ef9190612891565b6119f991906128b2565b67ffffffffffffffff161590508115158103611a41576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505084547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790945550505050505050505050565b6000805468010000000000000000900460ff166002811115611aa157611aa1612299565b14611ad8576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b699190612900565b7fc0c220c900000000000000000000000000000000000000000000000000000000601c8190526020869052604085905290915060008560018114611bd55760028114611bdf5760038114611be95760048114611bf35760058114611c035763ff137e656000526004601cfd5b6001549150611c0a565b6004549150611c0a565b6006549150611c0a565b60035460801c60c01b9150611c0a565b4660c01b91505b50606052600160038611811b6005031b60805260a083905260008060a4601c82865af1611c3b573d6000803e3d6000fd5b5050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611c986108ac565b9050909192565b6000805468010000000000000000900460ff166002811115611cc357611cc3612299565b14611cfa576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611d0f57611d0f612591565b60009182526020909120600260039092020190810154909150677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1690611d7f90700100000000000000000000000000000000900467ffffffffffffffff1642612607565b6002830154611daf9190700100000000000000000000000000000000900460401c67ffffffffffffffff166125ef565b11611de6576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260086020526040902082158015611e04575060095460ff165b15611e3b576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054158015611e4957508215155b15611e80576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8254811015611f4e576000838281548110611ea157611ea1612591565b6000918252602080832090910154808352600890915260409091205490915015611ef7576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611f0c57611f0c612591565b600091825260209091206003909102018054909150640100000000900460ff16611f3b57600193505050611f4e565b505080611f4790612936565b9050611e84565b5082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000821515021783556000848152600860205260408120611f979161225f565b83600003611fcb57600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b50505050565b6060600061200884367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036125ef565b90508267ffffffffffffffff1667ffffffffffffffff81111561202d5761202d612637565b6040519080825280601f01601f191660200182016040528015612057576020820181803683370190505b509150828160208401375092915050565b151760011b90565b6000806120fd837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b600080612134846fffffffffffffffffffffffffffffffff166121b3565b90506002838154811061214957612149612591565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff8281169116146121ac57815460028054909163ffffffff1690811061219757612197612591565b9060005260206000209060030201915061215a565b5092915050565b60008119600183011681612247827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b508054600082559060005260206000209081019061227d9190612280565b50565b5b808211156122955760008155600101612281565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612303577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561231c57600080fd5b50508035926020909101359150565b6000815180845260005b8181101561235157602081850181015186830182015201612335565b81811115612363576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006123a9602083018461232b565b9392505050565b82516fffffffffffffffffffffffffffffffff90811682526020808501518216818401526040808601518185015284518316606085015290840151909116608083015282015160a082015260c081016123a9565b8035801515811461241457600080fd5b919050565b60008060006060848603121561242e57600080fd5b833592506020840135915061244560408501612404565b90509250925092565b60006020828403121561246057600080fd5b5035919050565b60008083601f84011261247957600080fd5b50813567ffffffffffffffff81111561249157600080fd5b6020830191508360208285010111156124a957600080fd5b9250929050565b600080600080600080608087890312156124c957600080fd5b863595506124d960208801612404565b9450604087013567ffffffffffffffff808211156124f657600080fd5b6125028a838b01612467565b9096509450606089013591508082111561251b57600080fd5b5061252889828a01612467565b979a9699509497509295939492505050565b60008060006060848603121561254f57600080fd5b505081359360208301359350604090920135919050565b60ff84168152826020820152606060408201526000612588606083018461232b565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612602576126026125c0565b500190565b600082821015612619576126196125c0565b500390565b60006020828403121561263057600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80516fffffffffffffffffffffffffffffffff8116811461241457600080fd5b60006060828403121561269857600080fd5b6040516060810181811067ffffffffffffffff821117156126e2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052825181526126f560208401612666565b602082015261270660408401612666565b60408201529392505050565b60006040828403121561272457600080fd5b6040516040810167ffffffffffffffff828210818311171561276f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b816040528451835260208501519150808216821461278c57600080fd5b5060208201529392505050565b60006fffffffffffffffffffffffffffffffff838116908316818110156127c2576127c26125c0565b039392505050565b60006fffffffffffffffffffffffffffffffff8083168185168083038211156127f5576127f56125c0565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60608152600061286b60608301878961280e565b828103602084015261287e81868861280e565b9150508260408301529695505050505050565b600067ffffffffffffffff838116908316818110156127c2576127c26125c0565b600067ffffffffffffffff808416806128f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910692915050565b60006020828403121561291257600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146123a957600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612967576129676125c0565b506001019056fea164736f6c634300080f000a" +var FaultDisputeGameDeployedBin = "0x6080604052600436106101ff5760003560e01c80638d450a951161010e578063d6ae3cd5116100a7578063f3f7214e11610079578063fa24f74311610061578063fa24f7431461079c578063fa315aa9146107c0578063fdffbb28146107f357005b8063f3f7214e14610751578063f8f43ff61461077c57005b8063d6ae3cd514610698578063d8cc1a3c146106cb578063e1f0c376146106eb578063ec5e63081461071e57005b8063c55cd0c7116100e0578063c55cd0c7146105ad578063c6f0308c146105c0578063cf09e0d01461064a578063d5d44d801461066b57005b80638d450a95146104dc578063bbdc02db1461050f578063bcef3b5514610550578063c395e1ca1461058d57005b806357da950e116101985780636361506d1161016a5780638129fc1c116101525780638129fc1c1461047f5780638980e0cc146104875780638b85902b1461049c57005b80636361506d1461042a57806370872aa51461046a57005b806357da950e146103b2578063609d3334146103e257806360e27464146103f7578063632247ea1461041757005b806335fef567116101d157806335fef567146102c25780633a768463146102d55780633fc8cef31461032957806354fd4d501461035c57005b806319effeb414610208578063200d2ed21461025357806325fc2ace1461028e5780632810e1d6146102ad57005b3661020657005b005b34801561021457600080fd5b506000546102359068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561025f57600080fd5b5060005461028190700100000000000000000000000000000000900460ff1681565b60405161024a9190613f78565b34801561029a57600080fd5b506006545b60405190815260200161024a565b3480156102b957600080fd5b50610281610806565b6102066102d0366004613fb9565b610a83565b3480156102e157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161024a565b34801561033557600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610304565b34801561036857600080fd5b506103a56040518060400160405280600581526020017f302e382e3100000000000000000000000000000000000000000000000000000081525081565b60405161024a9190614046565b3480156103be57600080fd5b506006546007546103cd919082565b6040805192835260208301919091520161024a565b3480156103ee57600080fd5b506103a5610a93565b34801561040357600080fd5b5061020661041236600461407b565b610aa6565b6102066104253660046140b4565b610c52565b34801561043657600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561029f565b34801561047657600080fd5b5060075461029f565b6102066114ca565b34801561049357600080fd5b5060015461029f565b3480156104a857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561029f565b3480156104e857600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b34801561051b57600080fd5b5060405163ffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161024a565b34801561055c57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561029f565b34801561059957600080fd5b5061029f6105a83660046140e9565b6119f6565b6102066105bb366004613fb9565b611be0565b3480156105cc57600080fd5b506105e06105db36600461411b565b611bec565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161024a565b34801561065657600080fd5b506000546102359067ffffffffffffffff1681565b34801561067757600080fd5b5061029f61068636600461407b565b60026020526000908152604090205481565b3480156106a457600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b3480156106d757600080fd5b506102066106e636600461417d565b611c83565b3480156106f757600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610235565b34801561072a57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b34801561075d57600080fd5b506040516fffffffffffffffffffffffffffffffff815260200161024a565b34801561078857600080fd5b50610206610797366004614207565b6122b8565b3480156107a857600080fd5b506107b1612715565b60405161024a93929190614233565b3480156107cc57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061029f565b61020661080136600461411b565b612772565b600080600054700100000000000000000000000000000000900460ff16600281111561083457610834613f49565b1461086b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055460ff166108a7576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660016000815481106108d3576108d3614261565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff161461090e576001610911565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156109c2576109c2613f49565b0217905560028111156109d7576109d7613f49565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a27f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663838c2d1e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a6857600080fd5b505af1158015610a7c573d6000803e3d6000fd5b5050505090565b610a8f82826000610c52565b5050565b6060610aa160406020612bd3565b905090565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040812080549082905590819003610b0b576040517f17bfe5f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f3fef3a390604401600060405180830381600087803b158015610b9b57600080fd5b505af1158015610baf573d6000803e3d6000fd5b5050505060008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610c0d576040519150601f19603f3d011682016040523d82523d6000602084013e610c12565b606091505b5050905080610c4d576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60008054700100000000000000000000000000000000900460ff166002811115610c7e57610c7e613f49565b14610cb5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018481548110610cca57610cca614261565b600091825260208083206040805160e0810182526005909402909101805463ffffffff808216865273ffffffffffffffffffffffffffffffffffffffff6401000000009092048216948601949094526001820154169184019190915260028101546fffffffffffffffffffffffffffffffff90811660608501526003820154608085015260049091015480821660a0850181905270010000000000000000000000000000000090910490911660c0840152919350909190610d8f9083908690612c6a16565b90506000610e2f826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610e715750610e6e7f000000000000000000000000000000000000000000000000000000000000000060026142bf565b81145b8015610e7b575084155b15610eb2576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610f0c576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f377f000000000000000000000000000000000000000000000000000000000000000060016142bf565b8103610f4957610f4986888588612c72565b34610f53836119f6565b1115610f8b576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835160009063ffffffff90811614610feb576001856000015163ffffffff1681548110610fba57610fba614261565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b60c085015160009061100f9067ffffffffffffffff165b67ffffffffffffffff1690565b67ffffffffffffffff1642611039611002856fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff1661104d91906142bf565b61105791906142d7565b90507f000000000000000000000000000000000000000000000000000000000000000060011c677fffffffffffffff1667ffffffffffffffff821611156110ca576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526003602052604090205490915060ff1615611148576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016003600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060016040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505050600460008c8152602001908152602001600020600180805490506113dd91906142d7565b81546001810183556000928352602083200155604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263d0e30db09234926004808301939282900301818588803b15801561147557600080fd5b505af1158015611489573d6000803e3d6000fd5b50506040513393508d92508e91507f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be90600090a45050505050505050505050565b600554610100900460ff161561150c576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7258a80700000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690637258a807906024016040805180830381865afa1580156115c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e491906142ee565b909250905081611620576040517f6a6bc3b200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082018252838152602001829052600683905560078290558190367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90030135116116d2576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b60663611156116e95763c407e0256000526004601cfd5b6040805160e08101825263ffffffff808252600060208301818152328486019081526fffffffffffffffffffffffffffffffff34818116606088019081527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033560808901908152600160a08a0181815242861660c08c0190815282548084018455928a529a5160059092027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf681018054995173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff000000000000000000000000000000000000000000000000909b1694909c16939093179890981790915594517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf787018054918a167fffffffffffffffffffffffff000000000000000000000000000000000000000090921691909117905590517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8860180549185167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909216919091179055517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9850155915195518116700100000000000000000000000000000000029516949094177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa9091015583517fd0e30db000000000000000000000000000000000000000000000000000000000815293517f00000000000000000000000000000000000000000000000000000000000000009092169363d0e30db093926004828101939282900301818588803b15801561197757600080fd5b505af115801561198b573d6000803e3d6000fd5b50506000805467ffffffffffffffff42167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009091161790555050600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055505050565b600080611a95836fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690507f0000000000000000000000000000000000000000000000000000000000000000811115611afb576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b642e90edd00062061a80630bebc2006000611b168383614341565b9050670de0b6b3a76400006000611b4d827f0000000000000000000000000000000000000000000000000000000000000000614355565b90506000611b6b611b66670de0b6b3a764000086614355565b612e33565b90506000611b79848461308e565b90506000611b8783836130dd565b90506000611b948261310b565b90506000611bb382611bae670de0b6b3a76400008f614355565b6132f3565b90506000611bc18b836130dd565b9050611bcd818d614355565b9f9e505050505050505050505050505050565b610a8f82826001610c52565b60018181548110611bfc57600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff166002811115611caf57611caf613f49565b14611ce6576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018781548110611cfb57611cfb614261565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050611d5a7f000000000000000000000000000000000000000000000000000000000000000060016142bf565b611df6826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1614611e37576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808915611f2657611e8a7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006142d7565b6001901b611ea9846fffffffffffffffffffffffffffffffff1661332d565b67ffffffffffffffff16611ebd9190614392565b15611efa57611ef1611ee260016fffffffffffffffffffffffffffffffff87166143a6565b865463ffffffff1660006133d3565b60030154611f1c565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611f50565b60038501549150611f4d611ee26fffffffffffffffffffffffffffffffff861660016143d7565b90505b600882901b60088a8a604051611f6792919061440b565b6040518091039020901b14611fa8576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611fb38c6134b7565b90506000611fc2836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e14ced329061203c908f908f908f908f908a90600401614464565b6020604051808303816000875af115801561205b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207f919061449e565b60048501549114915060009060029061212a906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6121c6896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6121d091906144b7565b6121da91906144d8565b67ffffffffffffffff161590508115158103612222576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8754640100000000900473ffffffffffffffffffffffffffffffffffffffff1615612279576040517f9071e6af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff1660028111156122e4576122e4613f49565b1461231b576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008061232a866134e6565b93509350935093506000612340858585856138f5565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d391906144ff565b9050600189036124cb5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8461242f367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013590565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af11580156124a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c5919061449e565b5061270a565b600289036124f75773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848961242f565b600389036125235773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a848761242f565b6004890361263f5760006125696fffffffffffffffffffffffffffffffff85167f00000000000000000000000000000000000000000000000000000000000000006139b4565b60075461257691906142bf565b6125819060016142bf565b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af1158015612614573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612638919061449e565b505061270a565b600589036126d8576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390527f000000000000000000000000000000000000000000000000000000000000000060c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a401612482565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335606061276b610a93565b9050909192565b60008054700100000000000000000000000000000000900460ff16600281111561279e5761279e613f49565b146127d5576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600182815481106127ea576127ea614261565b60009182526020822060059190910201600481015490925061282c90700100000000000000000000000000000000900460401c67ffffffffffffffff16611002565b600483015490915060009061285e90700100000000000000000000000000000000900467ffffffffffffffff16611002565b61286890426144b7565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c166128a2828461451c565b67ffffffffffffffff16116128e3576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600460205260409020805485158015612903575060055460ff165b1561293a576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015801561294757508515155b156129ac578454640100000000900473ffffffffffffffffffffffffffffffffffffffff166000811561297a5781612996565b600187015473ffffffffffffffffffffffffffffffffffffffff165b90506129a28188613a69565b5050505050505050565b60006fffffffffffffffffffffffffffffffff815b83811015612af25760008582815481106129dd576129dd614261565b6000918252602080832090910154808352600490915260409091205490915015612a33576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018281548110612a4857612a48614261565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff16158015612aa1575060048101546fffffffffffffffffffffffffffffffff908116908516115b15612adf576001810154600482015473ffffffffffffffffffffffffffffffffffffffff90911695506fffffffffffffffffffffffffffffffff1693505b505080612aeb9061453f565b90506129c1565b50612b3a73ffffffffffffffffffffffffffffffffffffffff831615612b185782612b34565b600188015473ffffffffffffffffffffffffffffffffffffffff165b88613a69565b86547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416021787556000888152600460205260408120612b9691613f0f565b876000036129a257600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555050505050505050565b60606000612c0a84367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036142bf565b90508267ffffffffffffffff1667ffffffffffffffff811115612c2f57612c2f614577565b6040519080825280601f01601f191660200182016040528015612c59576020820181803683370190505b509150828160208401375092915050565b151760011b90565b6000612c916fffffffffffffffffffffffffffffffff841660016143d7565b90506000612ca1828660016133d3565b9050600086901a8380612d945750612cda60027f0000000000000000000000000000000000000000000000000000000000000000614392565b6004830154600290612d7e906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b612d8891906144d8565b67ffffffffffffffff16145b15612dec5760ff811660011480612dae575060ff81166002145b612de7576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016116c9565b612e2a565b60ff811615612e2a576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016116c9565b50505050505050565b6fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff1060061b1781811c63ffffffff1060051b1781811c61ffff1060041b1781811c60ff1060031b1760008213612e9257631615e6386000526004601cfd5b7ff8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff6f8421084210842108cc6318c6db6d54be83831c1c601f161a1890811b609f90811c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506029190037d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a7640000021582026130cb57637c5f487d6000526004601cfd5b50670de0b6b3a7640000919091020490565b6000816000190483118202156130fb5763bac65e5b6000526004601cfd5b50670de0b6b3a764000091020490565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d7821361313957919050565b680755bf798b4a1bf1e582126131575763a37bfec96000526004601cfd5b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b6000613324670de0b6b3a76400008361330b86612e33565b61331591906145a6565b61331f9190614662565b61310b565b90505b92915050565b6000806133ba837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000808261341c576134176fffffffffffffffffffffffffffffffff86167f0000000000000000000000000000000000000000000000000000000000000000613bf5565b613437565b613437856fffffffffffffffffffffffffffffffff16613db3565b90506001848154811061344c5761344c614261565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146134af57815460018054909163ffffffff1690811061349a5761349a614261565b9060005260206000209060050201915061345d565b509392505050565b60008060008060006134c8866134e6565b93509350935093506134dc848484846138f5565b9695505050505050565b600080600080600085905060006001828154811061350657613506614261565b600091825260209091206004600590920201908101549091507f0000000000000000000000000000000000000000000000000000000000000000906135dd906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161361e576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f0000000000000000000000000000000000000000000000000000000000000000906136e5906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16925082111561376157825463ffffffff1661372b7f000000000000000000000000000000000000000000000000000000000000000060016142bf565b8303613735578391505b6001818154811061374857613748614261565b9060005260206000209060050201935080945050613622565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff166137ca6137b5856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015613891576000613802836fffffffffffffffffffffffffffffffff1661332d565b67ffffffffffffffff16111561386557600061383c61383460016fffffffffffffffffffffffffffffffff86166143a6565b8960016133d3565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a5061386b9050565b6006549a505b600386015460048701549099506fffffffffffffffffffffffffffffffff1697506138e7565b60006138b36138346fffffffffffffffffffffffffffffffff851660016143d7565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff8416810361395b57828260405160200161393e9291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b6040516020818303038152906040528051906020012090506139ac565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b600080613a41847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60028101546fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000018101613ad9576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280830180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff17905573ffffffffffffffffffffffffffffffffffffffff84166000908152602091909152604081208054839290613b4c9084906142bf565b90915550506040517f7eee288d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390527f00000000000000000000000000000000000000000000000000000000000000001690637eee288d90604401600060405180830381600087803b158015613be157600080fd5b505af1158015612e2a573d6000803e3d6000fd5b600081613c94846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611613cd5576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613cde83613db3565b905081613d7d826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161161332757613324613d9a8360016142bf565b6fffffffffffffffffffffffffffffffff831690613e5f565b60008119600183011681613e47827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080613eec847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b5080546000825590600052602060002090810190613f2d9190613f30565b50565b5b80821115613f455760008155600101613f31565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310613fb3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215613fcc57600080fd5b50508035926020909101359150565b6000815180845260005b8181101561400157602081850181015186830182015201613fe5565b81811115614013576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006133246020830184613fdb565b73ffffffffffffffffffffffffffffffffffffffff81168114613f2d57600080fd5b60006020828403121561408d57600080fd5b813561409881614059565b9392505050565b803580151581146140af57600080fd5b919050565b6000806000606084860312156140c957600080fd5b83359250602084013591506140e06040850161409f565b90509250925092565b6000602082840312156140fb57600080fd5b81356fffffffffffffffffffffffffffffffff8116811461409857600080fd5b60006020828403121561412d57600080fd5b5035919050565b60008083601f84011261414657600080fd5b50813567ffffffffffffffff81111561415e57600080fd5b60208301915083602082850101111561417657600080fd5b9250929050565b6000806000806000806080878903121561419657600080fd5b863595506141a66020880161409f565b9450604087013567ffffffffffffffff808211156141c357600080fd5b6141cf8a838b01614134565b909650945060608901359150808211156141e857600080fd5b506141f589828a01614134565b979a9699509497509295939492505050565b60008060006060848603121561421c57600080fd5b505081359360208301359350604090920135919050565b63ffffffff841681528260208201526060604082015260006142586060830184613fdb565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156142d2576142d2614290565b500190565b6000828210156142e9576142e9614290565b500390565b6000806040838503121561430157600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261435057614350614312565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561438d5761438d614290565b500290565b6000826143a1576143a1614312565b500690565b60006fffffffffffffffffffffffffffffffff838116908316818110156143cf576143cf614290565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561440257614402614290565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60608152600061447860608301878961441b565b828103602084015261448b81868861441b565b9150508260408301529695505050505050565b6000602082840312156144b057600080fd5b5051919050565b600067ffffffffffffffff838116908316818110156143cf576143cf614290565b600067ffffffffffffffff808416806144f3576144f3614312565b92169190910692915050565b60006020828403121561451157600080fd5b815161409881614059565b600067ffffffffffffffff80831681851680830382111561440257614402614290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361457057614570614290565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156145e7576145e7614290565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561462257614622614290565b6000871292508782058712848416161561463e5761463e614290565b8785058712818416161561465457614654614290565b505050929093029392505050565b60008261467157614671614312565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156146c5576146c5614290565b50059056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(FaultDisputeGameStorageLayoutJSON), FaultDisputeGameStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["FaultDisputeGame"] = FaultDisputeGameStorageLayout deployedBytecodes["FaultDisputeGame"] = FaultDisputeGameDeployedBin + immutableReferences["FaultDisputeGame"] = true } diff --git a/op-bindings/bindings/gaspriceoracle.go b/op-bindings/bindings/gaspriceoracle.go index 547218a6cb8e..7636a7c2f105 100644 --- a/op-bindings/bindings/gaspriceoracle.go +++ b/op-bindings/bindings/gaspriceoracle.go @@ -30,8 +30,8 @@ var ( // GasPriceOracleMetaData contains all meta data concerning the GasPriceOracle contract. var GasPriceOracleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"DECIMALS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"baseFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gasPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"getL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"getL1GasUsed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1BaseFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"overhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"scalar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b506107c0806100206000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c806354fd4d5011610076578063de26c4a11161005b578063de26c4a114610157578063f45e65d81461016a578063fe173b971461015157600080fd5b806354fd4d50146101085780636ef25c3a1461015157600080fd5b8063313ce567116100a7578063313ce567146100e657806349948e0e146100ed578063519b4bd31461010057600080fd5b80630c18c162146100c35780632e0f2625146100de575b600080fd5b6100cb610172565b6040519081526020015b60405180910390f35b6100cb600681565b60066100cb565b6100cb6100fb3660046103fd565b6101fc565b6100cb61025d565b6101446040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d591906104cc565b486100cb565b6100cb6101653660046103fd565b6102be565b6100cb61036d565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101f7919061053f565b905090565b600080610208836102be565b9050600061021461025d565b61021e9083610587565b9050600061022e6006600a6106e6565b9050600061023a61036d565b6102449084610587565b9050600061025283836106f9565b979650505050505050565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101d3573d6000803e3d6000fd5b80516000908190815b81811015610341578481815181106102e1576102e1610734565b01602001517fff00000000000000000000000000000000000000000000000000000000000000166000036103215761031a600484610763565b925061032f565b61032c601084610763565b92505b806103398161077b565b9150506102c7565b50600061034c610172565b6103569084610763565b905061036481610440610763565b95945050505050565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101d3573d6000803e3d6000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561040f57600080fd5b813567ffffffffffffffff8082111561042757600080fd5b818401915084601f83011261043b57600080fd5b81358181111561044d5761044d6103ce565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610493576104936103ce565b816040528281528760208487010111156104ac57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156104f9578581018301518582016040015282016104dd565b8181111561050b576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561055157600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156105bf576105bf610558565b500290565b600181815b8085111561061d57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561060357610603610558565b8085161561061057918102915b93841c93908002906105c9565b509250929050565b600082610634575060016106e0565b81610641575060006106e0565b816001811461065757600281146106615761067d565b60019150506106e0565b60ff84111561067257610672610558565b50506001821b6106e0565b5060208310610133831016604e8410600b84101617156106a0575081810a6106e0565b6106aa83836105c4565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156106dc576106dc610558565b0290505b92915050565b60006106f28383610625565b9392505050565b60008261072f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561077657610776610558565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036107ac576107ac610558565b506001019056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"function\",\"name\":\"DECIMALS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"baseFee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"baseFeeScalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blobBaseFee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blobBaseFeeScalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"decimals\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"gasPrice\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL1Fee\",\"inputs\":[{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL1GasUsed\",\"inputs\":[{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isEcotone\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1BaseFee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"overhead\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"scalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setEcotone\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"}]", + Bin: "0x608060405234801561001057600080fd5b50610fb5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806354fd4d5011610097578063de26c4a111610066578063de26c4a1146101da578063f45e65d8146101ed578063f8206140146101f5578063fe173b97146101cc57600080fd5b806354fd4d501461016657806368d5dca6146101af5780636ef25c3a146101cc578063c5985918146101d257600080fd5b8063313ce567116100d3578063313ce5671461012757806349948e0e1461012e5780634ef6e22414610141578063519b4bd31461015e57600080fd5b80630c18c162146100fa57806322b90ab3146101155780632e0f26251461011f575b600080fd5b6101026101fd565b6040519081526020015b60405180910390f35b61011d61031e565b005b610102600681565b6006610102565b61010261013c366004610b73565b610541565b60005461014e9060ff1681565b604051901515815260200161010c565b610102610565565b6101a26040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161010c9190610c42565b6101b76105c6565b60405163ffffffff909116815260200161010c565b48610102565b6101b761064b565b6101026101e8366004610b73565b6106ac565b610102610760565b610102610853565b6000805460ff1615610296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f47617350726963654f7261636c653a206f76657268656164282920697320646560448201527f707265636174656400000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610cb5565b905090565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663e591b2826040518163ffffffff1660e01b8152600401602060405180830381865afa15801561037d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a19190610cce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610481576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f47617350726963654f7261636c653a206f6e6c7920746865206465706f73697460448201527f6f72206163636f756e742063616e2073657420697345636f746f6e6520666c6160648201527f6700000000000000000000000000000000000000000000000000000000000000608482015260a40161028d565b60005460ff1615610514576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a2045636f746f6e6520616c72656164792060448201527f6163746976650000000000000000000000000000000000000000000000000000606482015260840161028d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000805460ff161561055c57610556826108b4565b92915050565b61055682610958565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff166368d5dca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610d04565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663c59859186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b6000806106b883610ab4565b60005490915060ff16156106cc5792915050565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074f9190610cb5565b6107599082610d59565b9392505050565b6000805460ff16156107f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a207363616c61722829206973206465707260448201527f6563617465640000000000000000000000000000000000000000000000000000606482015260840161028d565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663f82061406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b6000806108c083610ab4565b905060006108cc610565565b6108d461064b565b6108df906010610d71565b63ffffffff166108ef9190610d9d565b905060006108fb610853565b6109036105c6565b63ffffffff166109139190610d9d565b905060006109218284610d59565b61092b9085610d9d565b90506109396006600a610efa565b610944906010610d9d565b61094e9082610f06565b9695505050505050565b60008061096483610ab4565b9050600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109eb9190610cb5565b6109f3610565565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a769190610cb5565b610a809085610d59565b610a8a9190610d9d565b610a949190610d9d565b9050610aa26006600a610efa565b610aac9082610f06565b949350505050565b80516000908190815b81811015610b3757848181518110610ad757610ad7610f41565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016600003610b1757610b10600484610d59565b9250610b25565b610b22601084610d59565b92505b80610b2f81610f70565b915050610abd565b50610aac82610440610d59565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610b8557600080fd5b813567ffffffffffffffff80821115610b9d57600080fd5b818401915084601f830112610bb157600080fd5b813581811115610bc357610bc3610b44565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610c0957610c09610b44565b81604052828152876020848701011115610c2257600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b81811115610c81576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600060208284031215610cc757600080fd5b5051919050565b600060208284031215610ce057600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461075957600080fd5b600060208284031215610d1657600080fd5b815163ffffffff8116811461075957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610d6c57610d6c610d2a565b500190565b600063ffffffff80831681851681830481118215151615610d9457610d94610d2a565b02949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610dd557610dd5610d2a565b500290565b600181815b80851115610e3357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610e1957610e19610d2a565b80851615610e2657918102915b93841c9390800290610ddf565b509250929050565b600082610e4a57506001610556565b81610e5757506000610556565b8160018114610e6d5760028114610e7757610e93565b6001915050610556565b60ff841115610e8857610e88610d2a565b50506001821b610556565b5060208310610133831016604e8410600b8410161715610eb6575081810a610556565b610ec08383610dda565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610ef257610ef2610d2a565b029392505050565b60006107598383610e3b565b600082610f3c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610fa157610fa1610d2a565b506001019056fea164736f6c634300080f000a", } // GasPriceOracleABI is the input ABI used to generate the binding from. @@ -263,6 +263,99 @@ func (_GasPriceOracle *GasPriceOracleCallerSession) BaseFee() (*big.Int, error) return _GasPriceOracle.Contract.BaseFee(&_GasPriceOracle.CallOpts) } +// BaseFeeScalar is a free data retrieval call binding the contract method 0xc5985918. +// +// Solidity: function baseFeeScalar() view returns(uint32) +func (_GasPriceOracle *GasPriceOracleCaller) BaseFeeScalar(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _GasPriceOracle.contract.Call(opts, &out, "baseFeeScalar") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// BaseFeeScalar is a free data retrieval call binding the contract method 0xc5985918. +// +// Solidity: function baseFeeScalar() view returns(uint32) +func (_GasPriceOracle *GasPriceOracleSession) BaseFeeScalar() (uint32, error) { + return _GasPriceOracle.Contract.BaseFeeScalar(&_GasPriceOracle.CallOpts) +} + +// BaseFeeScalar is a free data retrieval call binding the contract method 0xc5985918. +// +// Solidity: function baseFeeScalar() view returns(uint32) +func (_GasPriceOracle *GasPriceOracleCallerSession) BaseFeeScalar() (uint32, error) { + return _GasPriceOracle.Contract.BaseFeeScalar(&_GasPriceOracle.CallOpts) +} + +// BlobBaseFee is a free data retrieval call binding the contract method 0xf8206140. +// +// Solidity: function blobBaseFee() view returns(uint256) +func (_GasPriceOracle *GasPriceOracleCaller) BlobBaseFee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _GasPriceOracle.contract.Call(opts, &out, "blobBaseFee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BlobBaseFee is a free data retrieval call binding the contract method 0xf8206140. +// +// Solidity: function blobBaseFee() view returns(uint256) +func (_GasPriceOracle *GasPriceOracleSession) BlobBaseFee() (*big.Int, error) { + return _GasPriceOracle.Contract.BlobBaseFee(&_GasPriceOracle.CallOpts) +} + +// BlobBaseFee is a free data retrieval call binding the contract method 0xf8206140. +// +// Solidity: function blobBaseFee() view returns(uint256) +func (_GasPriceOracle *GasPriceOracleCallerSession) BlobBaseFee() (*big.Int, error) { + return _GasPriceOracle.Contract.BlobBaseFee(&_GasPriceOracle.CallOpts) +} + +// BlobBaseFeeScalar is a free data retrieval call binding the contract method 0x68d5dca6. +// +// Solidity: function blobBaseFeeScalar() view returns(uint32) +func (_GasPriceOracle *GasPriceOracleCaller) BlobBaseFeeScalar(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _GasPriceOracle.contract.Call(opts, &out, "blobBaseFeeScalar") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// BlobBaseFeeScalar is a free data retrieval call binding the contract method 0x68d5dca6. +// +// Solidity: function blobBaseFeeScalar() view returns(uint32) +func (_GasPriceOracle *GasPriceOracleSession) BlobBaseFeeScalar() (uint32, error) { + return _GasPriceOracle.Contract.BlobBaseFeeScalar(&_GasPriceOracle.CallOpts) +} + +// BlobBaseFeeScalar is a free data retrieval call binding the contract method 0x68d5dca6. +// +// Solidity: function blobBaseFeeScalar() view returns(uint32) +func (_GasPriceOracle *GasPriceOracleCallerSession) BlobBaseFeeScalar() (uint32, error) { + return _GasPriceOracle.Contract.BlobBaseFeeScalar(&_GasPriceOracle.CallOpts) +} + // Decimals is a free data retrieval call binding the contract method 0x313ce567. // // Solidity: function decimals() pure returns(uint256) @@ -387,6 +480,37 @@ func (_GasPriceOracle *GasPriceOracleCallerSession) GetL1GasUsed(_data []byte) ( return _GasPriceOracle.Contract.GetL1GasUsed(&_GasPriceOracle.CallOpts, _data) } +// IsEcotone is a free data retrieval call binding the contract method 0x4ef6e224. +// +// Solidity: function isEcotone() view returns(bool) +func (_GasPriceOracle *GasPriceOracleCaller) IsEcotone(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _GasPriceOracle.contract.Call(opts, &out, "isEcotone") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsEcotone is a free data retrieval call binding the contract method 0x4ef6e224. +// +// Solidity: function isEcotone() view returns(bool) +func (_GasPriceOracle *GasPriceOracleSession) IsEcotone() (bool, error) { + return _GasPriceOracle.Contract.IsEcotone(&_GasPriceOracle.CallOpts) +} + +// IsEcotone is a free data retrieval call binding the contract method 0x4ef6e224. +// +// Solidity: function isEcotone() view returns(bool) +func (_GasPriceOracle *GasPriceOracleCallerSession) IsEcotone() (bool, error) { + return _GasPriceOracle.Contract.IsEcotone(&_GasPriceOracle.CallOpts) +} + // L1BaseFee is a free data retrieval call binding the contract method 0x519b4bd3. // // Solidity: function l1BaseFee() view returns(uint256) @@ -510,3 +634,24 @@ func (_GasPriceOracle *GasPriceOracleSession) Version() (string, error) { func (_GasPriceOracle *GasPriceOracleCallerSession) Version() (string, error) { return _GasPriceOracle.Contract.Version(&_GasPriceOracle.CallOpts) } + +// SetEcotone is a paid mutator transaction binding the contract method 0x22b90ab3. +// +// Solidity: function setEcotone() returns() +func (_GasPriceOracle *GasPriceOracleTransactor) SetEcotone(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GasPriceOracle.contract.Transact(opts, "setEcotone") +} + +// SetEcotone is a paid mutator transaction binding the contract method 0x22b90ab3. +// +// Solidity: function setEcotone() returns() +func (_GasPriceOracle *GasPriceOracleSession) SetEcotone() (*types.Transaction, error) { + return _GasPriceOracle.Contract.SetEcotone(&_GasPriceOracle.TransactOpts) +} + +// SetEcotone is a paid mutator transaction binding the contract method 0x22b90ab3. +// +// Solidity: function setEcotone() returns() +func (_GasPriceOracle *GasPriceOracleTransactorSession) SetEcotone() (*types.Transaction, error) { + return _GasPriceOracle.Contract.SetEcotone(&_GasPriceOracle.TransactOpts) +} diff --git a/op-bindings/bindings/gaspriceoracle_more.go b/op-bindings/bindings/gaspriceoracle_more.go index c0ca8d8858dd..dce3d218d930 100644 --- a/op-bindings/bindings/gaspriceoracle_more.go +++ b/op-bindings/bindings/gaspriceoracle_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const GasPriceOracleStorageLayoutJSON = "{\"storage\":null,\"types\":{}}" +const GasPriceOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"isEcotone\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_bool\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"}}}" var GasPriceOracleStorageLayout = new(solc.StorageLayout) -var GasPriceOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c806354fd4d5011610076578063de26c4a11161005b578063de26c4a114610157578063f45e65d81461016a578063fe173b971461015157600080fd5b806354fd4d50146101085780636ef25c3a1461015157600080fd5b8063313ce567116100a7578063313ce567146100e657806349948e0e146100ed578063519b4bd31461010057600080fd5b80630c18c162146100c35780632e0f2625146100de575b600080fd5b6100cb610172565b6040519081526020015b60405180910390f35b6100cb600681565b60066100cb565b6100cb6100fb3660046103fd565b6101fc565b6100cb61025d565b6101446040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d591906104cc565b486100cb565b6100cb6101653660046103fd565b6102be565b6100cb61036d565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101f7919061053f565b905090565b600080610208836102be565b9050600061021461025d565b61021e9083610587565b9050600061022e6006600a6106e6565b9050600061023a61036d565b6102449084610587565b9050600061025283836106f9565b979650505050505050565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101d3573d6000803e3d6000fd5b80516000908190815b81811015610341578481815181106102e1576102e1610734565b01602001517fff00000000000000000000000000000000000000000000000000000000000000166000036103215761031a600484610763565b925061032f565b61032c601084610763565b92505b806103398161077b565b9150506102c7565b50600061034c610172565b6103569084610763565b905061036481610440610763565b95945050505050565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101d3573d6000803e3d6000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561040f57600080fd5b813567ffffffffffffffff8082111561042757600080fd5b818401915084601f83011261043b57600080fd5b81358181111561044d5761044d6103ce565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610493576104936103ce565b816040528281528760208487010111156104ac57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156104f9578581018301518582016040015282016104dd565b8181111561050b576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561055157600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156105bf576105bf610558565b500290565b600181815b8085111561061d57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561060357610603610558565b8085161561061057918102915b93841c93908002906105c9565b509250929050565b600082610634575060016106e0565b81610641575060006106e0565b816001811461065757600281146106615761067d565b60019150506106e0565b60ff84111561067257610672610558565b50506001821b6106e0565b5060208310610133831016604e8410600b84101617156106a0575081810a6106e0565b6106aa83836105c4565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156106dc576106dc610558565b0290505b92915050565b60006106f28383610625565b9392505050565b60008261072f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561077657610776610558565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036107ac576107ac610558565b506001019056fea164736f6c634300080f000a" +var GasPriceOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c806354fd4d5011610097578063de26c4a111610066578063de26c4a1146101da578063f45e65d8146101ed578063f8206140146101f5578063fe173b97146101cc57600080fd5b806354fd4d501461016657806368d5dca6146101af5780636ef25c3a146101cc578063c5985918146101d257600080fd5b8063313ce567116100d3578063313ce5671461012757806349948e0e1461012e5780634ef6e22414610141578063519b4bd31461015e57600080fd5b80630c18c162146100fa57806322b90ab3146101155780632e0f26251461011f575b600080fd5b6101026101fd565b6040519081526020015b60405180910390f35b61011d61031e565b005b610102600681565b6006610102565b61010261013c366004610b73565b610541565b60005461014e9060ff1681565b604051901515815260200161010c565b610102610565565b6101a26040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161010c9190610c42565b6101b76105c6565b60405163ffffffff909116815260200161010c565b48610102565b6101b761064b565b6101026101e8366004610b73565b6106ac565b610102610760565b610102610853565b6000805460ff1615610296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f47617350726963654f7261636c653a206f76657268656164282920697320646560448201527f707265636174656400000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610cb5565b905090565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663e591b2826040518163ffffffff1660e01b8152600401602060405180830381865afa15801561037d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a19190610cce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610481576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f47617350726963654f7261636c653a206f6e6c7920746865206465706f73697460448201527f6f72206163636f756e742063616e2073657420697345636f746f6e6520666c6160648201527f6700000000000000000000000000000000000000000000000000000000000000608482015260a40161028d565b60005460ff1615610514576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a2045636f746f6e6520616c72656164792060448201527f6163746976650000000000000000000000000000000000000000000000000000606482015260840161028d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000805460ff161561055c57610556826108b4565b92915050565b61055682610958565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff166368d5dca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610d04565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663c59859186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b6000806106b883610ab4565b60005490915060ff16156106cc5792915050565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074f9190610cb5565b6107599082610d59565b9392505050565b6000805460ff16156107f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a207363616c61722829206973206465707260448201527f6563617465640000000000000000000000000000000000000000000000000000606482015260840161028d565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663f82061406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b6000806108c083610ab4565b905060006108cc610565565b6108d461064b565b6108df906010610d71565b63ffffffff166108ef9190610d9d565b905060006108fb610853565b6109036105c6565b63ffffffff166109139190610d9d565b905060006109218284610d59565b61092b9085610d9d565b90506109396006600a610efa565b610944906010610d9d565b61094e9082610f06565b9695505050505050565b60008061096483610ab4565b9050600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109eb9190610cb5565b6109f3610565565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a769190610cb5565b610a809085610d59565b610a8a9190610d9d565b610a949190610d9d565b9050610aa26006600a610efa565b610aac9082610f06565b949350505050565b80516000908190815b81811015610b3757848181518110610ad757610ad7610f41565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016600003610b1757610b10600484610d59565b9250610b25565b610b22601084610d59565b92505b80610b2f81610f70565b915050610abd565b50610aac82610440610d59565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610b8557600080fd5b813567ffffffffffffffff80821115610b9d57600080fd5b818401915084601f830112610bb157600080fd5b813581811115610bc357610bc3610b44565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610c0957610c09610b44565b81604052828152876020848701011115610c2257600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b81811115610c81576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600060208284031215610cc757600080fd5b5051919050565b600060208284031215610ce057600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461075957600080fd5b600060208284031215610d1657600080fd5b815163ffffffff8116811461075957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610d6c57610d6c610d2a565b500190565b600063ffffffff80831681851681830481118215151615610d9457610d94610d2a565b02949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610dd557610dd5610d2a565b500290565b600181815b80851115610e3357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610e1957610e19610d2a565b80851615610e2657918102915b93841c9390800290610ddf565b509250929050565b600082610e4a57506001610556565b81610e5757506000610556565b8160018114610e6d5760028114610e7757610e93565b6001915050610556565b60ff841115610e8857610e88610d2a565b50506001821b610556565b5060208310610133831016604e8410600b8410161715610eb6575081810a610556565b610ec08383610dda565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610ef257610ef2610d2a565b029392505050565b60006107598383610e3b565b600082610f3c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610fa157610fa1610d2a565b506001019056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(GasPriceOracleStorageLayoutJSON), GasPriceOracleStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["GasPriceOracle"] = GasPriceOracleStorageLayout deployedBytecodes["GasPriceOracle"] = GasPriceOracleDeployedBin + immutableReferences["GasPriceOracle"] = false } diff --git a/op-bindings/bindings/isemver.go b/op-bindings/bindings/isemver.go index 91eebe5d9d17..66a940654d05 100644 --- a/op-bindings/bindings/isemver.go +++ b/op-bindings/bindings/isemver.go @@ -30,7 +30,7 @@ var ( // ISemverMetaData contains all meta data concerning the ISemver contract. var ISemverMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"}]", } // ISemverABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/isemver_more.go b/op-bindings/bindings/isemver_more.go index 473560e61efc..6951b15c91a1 100644 --- a/op-bindings/bindings/isemver_more.go +++ b/op-bindings/bindings/isemver_more.go @@ -15,6 +15,7 @@ var ISemverStorageLayout = new(solc.StorageLayout) var ISemverDeployedBin = "0x" + func init() { if err := json.Unmarshal([]byte(ISemverStorageLayoutJSON), ISemverStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["ISemver"] = ISemverStorageLayout deployedBytecodes["ISemver"] = ISemverDeployedBin + immutableReferences["ISemver"] = false } diff --git a/op-bindings/bindings/l1block.go b/op-bindings/bindings/l1block.go index 4d9cc4c468dd..41a24ec38878 100644 --- a/op-bindings/bindings/l1block.go +++ b/op-bindings/bindings/l1block.go @@ -30,8 +30,8 @@ var ( // L1BlockMetaData contains all meta data concerning the L1Block contract. var L1BlockMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"DEPOSITOR_ACCOUNT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"basefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batcherHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1FeeOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1FeeScalar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"number\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_number\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"_timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"_basefee\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"_batcherHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1FeeOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l1FeeScalar\",\"type\":\"uint256\"}],\"name\":\"setL1BlockValues\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061045b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638381f58a11610081578063b80777ea1161005b578063b80777ea146101a4578063e591b282146101c4578063e81b2c6d1461020457600080fd5b80638381f58a1461017e5780638b239f73146101925780639e8c49661461019b57600080fd5b806354fd4d50116100b257806354fd4d50146100ff5780635cf249691461014857806364ca23ef1461015157600080fd5b8063015d8eb9146100ce57806309bd5a60146100e3575b600080fd5b6100e16100dc366004610369565b61020d565b005b6100ec60025481565b6040519081526020015b60405180910390f35b61013b6040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100f691906103db565b6100ec60015481565b6003546101659067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100f6565b6000546101659067ffffffffffffffff1681565b6100ec60055481565b6100ec60065481565b6000546101659068010000000000000000900467ffffffffffffffff1681565b6101df73deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60045481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead0001146102b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b803567ffffffffffffffff8116811461036457600080fd5b919050565b600080600080600080600080610100898b03121561038657600080fd5b61038f8961034c565b975061039d60208a0161034c565b965060408901359550606089013594506103b960808a0161034c565b979a969950949793969560a0850135955060c08501359460e001359350915050565b600060208083528351808285015260005b81811015610408578581018301518582016040015282016103ec565b8181111561041a576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"function\",\"name\":\"DEPOSITOR_ACCOUNT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"baseFeeScalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"basefee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"batcherHash\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blobBaseFee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blobBaseFeeScalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hash\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1FeeOverhead\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1FeeScalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"number\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"sequenceNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setL1BlockValues\",\"inputs\":[{\"name\":\"_number\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_basefee\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_sequenceNumber\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_batcherHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_l1FeeOverhead\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_l1FeeScalar\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setL1BlockValuesEcotone\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"timestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"}]", + Bin: "0x608060405234801561001057600080fd5b5061053e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638381f58a11610097578063c598591811610066578063c598591814610229578063e591b28214610249578063e81b2c6d14610289578063f82061401461029257600080fd5b80638381f58a146101e35780638b239f73146101f75780639e8c496614610200578063b80777ea1461020957600080fd5b806354fd4d50116100d357806354fd4d50146101335780635cf249691461017c57806364ca23ef1461018557806368d5dca6146101b257600080fd5b8063015d8eb9146100fa57806309bd5a601461010f578063440a5e201461012b575b600080fd5b61010d61010836600461044c565b61029b565b005b61011860025481565b6040519081526020015b60405180910390f35b61010d6103da565b61016f6040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161012291906104be565b61011860015481565b6003546101999067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610122565b6003546101ce9068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610122565b6000546101999067ffffffffffffffff1681565b61011860055481565b61011860065481565b6000546101999068010000000000000000900467ffffffffffffffff1681565b6003546101ce906c01000000000000000000000000900463ffffffff1681565b61026473deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b61011860045481565b61011860075481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b3373deaddeaddeaddeaddeaddeaddeaddeaddead00011461040357633cc50b456000526004601cfd5b60043560801c60035560143560801c600055602435600155604435600755606435600255608435600455565b803567ffffffffffffffff8116811461044757600080fd5b919050565b600080600080600080600080610100898b03121561046957600080fd5b6104728961042f565b975061048060208a0161042f565b9650604089013595506060890135945061049c60808a0161042f565b979a969950949793969560a0850135955060c08501359460e001359350915050565b600060208083528351808285015260005b818110156104eb578581018301518582016040015282016104cf565b818111156104fd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a", } // L1BlockABI is the input ABI used to generate the binding from. @@ -232,6 +232,37 @@ func (_L1Block *L1BlockCallerSession) DEPOSITORACCOUNT() (common.Address, error) return _L1Block.Contract.DEPOSITORACCOUNT(&_L1Block.CallOpts) } +// BaseFeeScalar is a free data retrieval call binding the contract method 0xc5985918. +// +// Solidity: function baseFeeScalar() view returns(uint32) +func (_L1Block *L1BlockCaller) BaseFeeScalar(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _L1Block.contract.Call(opts, &out, "baseFeeScalar") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// BaseFeeScalar is a free data retrieval call binding the contract method 0xc5985918. +// +// Solidity: function baseFeeScalar() view returns(uint32) +func (_L1Block *L1BlockSession) BaseFeeScalar() (uint32, error) { + return _L1Block.Contract.BaseFeeScalar(&_L1Block.CallOpts) +} + +// BaseFeeScalar is a free data retrieval call binding the contract method 0xc5985918. +// +// Solidity: function baseFeeScalar() view returns(uint32) +func (_L1Block *L1BlockCallerSession) BaseFeeScalar() (uint32, error) { + return _L1Block.Contract.BaseFeeScalar(&_L1Block.CallOpts) +} + // Basefee is a free data retrieval call binding the contract method 0x5cf24969. // // Solidity: function basefee() view returns(uint256) @@ -294,6 +325,68 @@ func (_L1Block *L1BlockCallerSession) BatcherHash() ([32]byte, error) { return _L1Block.Contract.BatcherHash(&_L1Block.CallOpts) } +// BlobBaseFee is a free data retrieval call binding the contract method 0xf8206140. +// +// Solidity: function blobBaseFee() view returns(uint256) +func (_L1Block *L1BlockCaller) BlobBaseFee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _L1Block.contract.Call(opts, &out, "blobBaseFee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BlobBaseFee is a free data retrieval call binding the contract method 0xf8206140. +// +// Solidity: function blobBaseFee() view returns(uint256) +func (_L1Block *L1BlockSession) BlobBaseFee() (*big.Int, error) { + return _L1Block.Contract.BlobBaseFee(&_L1Block.CallOpts) +} + +// BlobBaseFee is a free data retrieval call binding the contract method 0xf8206140. +// +// Solidity: function blobBaseFee() view returns(uint256) +func (_L1Block *L1BlockCallerSession) BlobBaseFee() (*big.Int, error) { + return _L1Block.Contract.BlobBaseFee(&_L1Block.CallOpts) +} + +// BlobBaseFeeScalar is a free data retrieval call binding the contract method 0x68d5dca6. +// +// Solidity: function blobBaseFeeScalar() view returns(uint32) +func (_L1Block *L1BlockCaller) BlobBaseFeeScalar(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _L1Block.contract.Call(opts, &out, "blobBaseFeeScalar") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// BlobBaseFeeScalar is a free data retrieval call binding the contract method 0x68d5dca6. +// +// Solidity: function blobBaseFeeScalar() view returns(uint32) +func (_L1Block *L1BlockSession) BlobBaseFeeScalar() (uint32, error) { + return _L1Block.Contract.BlobBaseFeeScalar(&_L1Block.CallOpts) +} + +// BlobBaseFeeScalar is a free data retrieval call binding the contract method 0x68d5dca6. +// +// Solidity: function blobBaseFeeScalar() view returns(uint32) +func (_L1Block *L1BlockCallerSession) BlobBaseFeeScalar() (uint32, error) { + return _L1Block.Contract.BlobBaseFeeScalar(&_L1Block.CallOpts) +} + // Hash is a free data retrieval call binding the contract method 0x09bd5a60. // // Solidity: function hash() view returns(bytes32) @@ -531,3 +624,24 @@ func (_L1Block *L1BlockSession) SetL1BlockValues(_number uint64, _timestamp uint func (_L1Block *L1BlockTransactorSession) SetL1BlockValues(_number uint64, _timestamp uint64, _basefee *big.Int, _hash [32]byte, _sequenceNumber uint64, _batcherHash [32]byte, _l1FeeOverhead *big.Int, _l1FeeScalar *big.Int) (*types.Transaction, error) { return _L1Block.Contract.SetL1BlockValues(&_L1Block.TransactOpts, _number, _timestamp, _basefee, _hash, _sequenceNumber, _batcherHash, _l1FeeOverhead, _l1FeeScalar) } + +// SetL1BlockValuesEcotone is a paid mutator transaction binding the contract method 0x440a5e20. +// +// Solidity: function setL1BlockValuesEcotone() returns() +func (_L1Block *L1BlockTransactor) SetL1BlockValuesEcotone(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L1Block.contract.Transact(opts, "setL1BlockValuesEcotone") +} + +// SetL1BlockValuesEcotone is a paid mutator transaction binding the contract method 0x440a5e20. +// +// Solidity: function setL1BlockValuesEcotone() returns() +func (_L1Block *L1BlockSession) SetL1BlockValuesEcotone() (*types.Transaction, error) { + return _L1Block.Contract.SetL1BlockValuesEcotone(&_L1Block.TransactOpts) +} + +// SetL1BlockValuesEcotone is a paid mutator transaction binding the contract method 0x440a5e20. +// +// Solidity: function setL1BlockValuesEcotone() returns() +func (_L1Block *L1BlockTransactorSession) SetL1BlockValuesEcotone() (*types.Transaction, error) { + return _L1Block.Contract.SetL1BlockValuesEcotone(&_L1Block.TransactOpts) +} diff --git a/op-bindings/bindings/l1block_more.go b/op-bindings/bindings/l1block_more.go index be401e12bf4e..3908246395d5 100644 --- a/op-bindings/bindings/l1block_more.go +++ b/op-bindings/bindings/l1block_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const L1BlockStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"number\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint64\"},{\"astId\":1001,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"timestamp\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_uint64\"},{\"astId\":1002,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"basefee\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1003,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"hash\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_bytes32\"},{\"astId\":1004,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"sequenceNumber\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_uint64\"},{\"astId\":1005,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"batcherHash\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_bytes32\"},{\"astId\":1006,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"l1FeeOverhead\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_uint256\"},{\"astId\":1007,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"l1FeeScalar\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_uint256\"}],\"types\":{\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"}}}" +const L1BlockStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"number\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint64\"},{\"astId\":1001,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"timestamp\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_uint64\"},{\"astId\":1002,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"basefee\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1003,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"hash\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_bytes32\"},{\"astId\":1004,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"sequenceNumber\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_uint64\"},{\"astId\":1005,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"blobBaseFeeScalar\",\"offset\":8,\"slot\":\"3\",\"type\":\"t_uint32\"},{\"astId\":1006,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"baseFeeScalar\",\"offset\":12,\"slot\":\"3\",\"type\":\"t_uint32\"},{\"astId\":1007,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"batcherHash\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_bytes32\"},{\"astId\":1008,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"l1FeeOverhead\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_uint256\"},{\"astId\":1009,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"l1FeeScalar\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_uint256\"},{\"astId\":1010,\"contract\":\"src/L2/L1Block.sol:L1Block\",\"label\":\"blobBaseFee\",\"offset\":0,\"slot\":\"7\",\"type\":\"t_uint256\"}],\"types\":{\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"}}}" var L1BlockStorageLayout = new(solc.StorageLayout) -var L1BlockDeployedBin = "0x608060405234801561001057600080fd5b50600436106100c95760003560e01c80638381f58a11610081578063b80777ea1161005b578063b80777ea146101a4578063e591b282146101c4578063e81b2c6d1461020457600080fd5b80638381f58a1461017e5780638b239f73146101925780639e8c49661461019b57600080fd5b806354fd4d50116100b257806354fd4d50146100ff5780635cf249691461014857806364ca23ef1461015157600080fd5b8063015d8eb9146100ce57806309bd5a60146100e3575b600080fd5b6100e16100dc366004610369565b61020d565b005b6100ec60025481565b6040519081526020015b60405180910390f35b61013b6040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100f691906103db565b6100ec60015481565b6003546101659067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100f6565b6000546101659067ffffffffffffffff1681565b6100ec60055481565b6100ec60065481565b6000546101659068010000000000000000900467ffffffffffffffff1681565b6101df73deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60045481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead0001146102b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b803567ffffffffffffffff8116811461036457600080fd5b919050565b600080600080600080600080610100898b03121561038657600080fd5b61038f8961034c565b975061039d60208a0161034c565b965060408901359550606089013594506103b960808a0161034c565b979a969950949793969560a0850135955060c08501359460e001359350915050565b600060208083528351808285015260005b81811015610408578581018301518582016040015282016103ec565b8181111561041a576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a" +var L1BlockDeployedBin = "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80638381f58a11610097578063c598591811610066578063c598591814610229578063e591b28214610249578063e81b2c6d14610289578063f82061401461029257600080fd5b80638381f58a146101e35780638b239f73146101f75780639e8c496614610200578063b80777ea1461020957600080fd5b806354fd4d50116100d357806354fd4d50146101335780635cf249691461017c57806364ca23ef1461018557806368d5dca6146101b257600080fd5b8063015d8eb9146100fa57806309bd5a601461010f578063440a5e201461012b575b600080fd5b61010d61010836600461044c565b61029b565b005b61011860025481565b6040519081526020015b60405180910390f35b61010d6103da565b61016f6040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161012291906104be565b61011860015481565b6003546101999067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610122565b6003546101ce9068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610122565b6000546101999067ffffffffffffffff1681565b61011860055481565b61011860065481565b6000546101999068010000000000000000900467ffffffffffffffff1681565b6003546101ce906c01000000000000000000000000900463ffffffff1681565b61026473deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b61011860045481565b61011860075481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b3373deaddeaddeaddeaddeaddeaddeaddeaddead00011461040357633cc50b456000526004601cfd5b60043560801c60035560143560801c600055602435600155604435600755606435600255608435600455565b803567ffffffffffffffff8116811461044757600080fd5b919050565b600080600080600080600080610100898b03121561046957600080fd5b6104728961042f565b975061048060208a0161042f565b9650604089013595506060890135945061049c60808a0161042f565b979a969950949793969560a0850135955060c08501359460e001359350915050565b600060208083528351808285015260005b818110156104eb578581018301518582016040015282016104cf565b818111156104fd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L1BlockStorageLayoutJSON), L1BlockStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["L1Block"] = L1BlockStorageLayout deployedBytecodes["L1Block"] = L1BlockDeployedBin + immutableReferences["L1Block"] = false } diff --git a/op-bindings/bindings/l1blocknumber.go b/op-bindings/bindings/l1blocknumber.go index e1ca1486e395..f7a5628f89a7 100644 --- a/op-bindings/bindings/l1blocknumber.go +++ b/op-bindings/bindings/l1blocknumber.go @@ -30,7 +30,7 @@ var ( // L1BlockNumberMetaData contains all meta data concerning the L1BlockNumber contract. var L1BlockNumberMetaData = &bind.MetaData{ - ABI: "[{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"getL1BlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ABI: "[{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"getL1BlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"}]", Bin: "0x608060405234801561001057600080fd5b50610219806100206000396000f3fe60806040526004361061002d5760003560e01c806354fd4d5014610052578063b9b3efe9146100b157610048565b3661004857600061003c6100d4565b90508060005260206000f35b600061003c6100d4565b34801561005e57600080fd5b5061009b6040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100a89190610168565b60405180910390f35b3480156100bd57600080fd5b506100c66100d4565b6040519081526020016100a8565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638381f58a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610135573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015991906101db565b67ffffffffffffffff16905090565b600060208083528351808285015260005b8181101561019557858101830151858201604001528201610179565b818111156101a7576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156101ed57600080fd5b815167ffffffffffffffff8116811461020557600080fd5b939250505056fea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/l1blocknumber_more.go b/op-bindings/bindings/l1blocknumber_more.go index 475fcb7fcf39..ec5798b244d3 100644 --- a/op-bindings/bindings/l1blocknumber_more.go +++ b/op-bindings/bindings/l1blocknumber_more.go @@ -15,6 +15,7 @@ var L1BlockNumberStorageLayout = new(solc.StorageLayout) var L1BlockNumberDeployedBin = "0x60806040526004361061002d5760003560e01c806354fd4d5014610052578063b9b3efe9146100b157610048565b3661004857600061003c6100d4565b90508060005260206000f35b600061003c6100d4565b34801561005e57600080fd5b5061009b6040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100a89190610168565b60405180910390f35b3480156100bd57600080fd5b506100c66100d4565b6040519081526020016100a8565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638381f58a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610135573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015991906101db565b67ffffffffffffffff16905090565b600060208083528351808285015260005b8181101561019557858101830151858201604001528201610179565b818111156101a7576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156101ed57600080fd5b815167ffffffffffffffff8116811461020557600080fd5b939250505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L1BlockNumberStorageLayoutJSON), L1BlockNumberStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["L1BlockNumber"] = L1BlockNumberStorageLayout deployedBytecodes["L1BlockNumber"] = L1BlockNumberDeployedBin + immutableReferences["L1BlockNumber"] = false } diff --git a/op-bindings/bindings/l1crossdomainmessenger.go b/op-bindings/bindings/l1crossdomainmessenger.go index 9ad96309297e..0aa353e32aff 100644 --- a/op-bindings/bindings/l1crossdomainmessenger.go +++ b/op-bindings/bindings/l1crossdomainmessenger.go @@ -30,8 +30,8 @@ var ( // L1CrossDomainMessengerMetaData contains all meta data concerning the L1CrossDomainMessenger contract. var L1CrossDomainMessengerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"FailedRelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"RelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"SentMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SentMessageExtension1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PORTAL\",\"outputs\":[{\"internalType\":\"contractOptimismPortal\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CALL_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_RESERVED_GAS\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractOptimismPortal\",\"name\":\"_portal\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"portal\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"relayMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"sendMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b507342000000000000000000000000000000000000076080526200003660006200003c565b620001ea565b600054600390600160a81b900460ff1615801562000068575060005460ff808316600160a01b90920416105b620000d15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b60008054600160a81b61ffff60a01b19909116600160a01b60ff85160260ff60a81b19161717905560f980546001600160a01b0319166001600160a01b0384161790556200011e62000165565b6000805460ff60a81b1916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054600160a81b900460ff16620001d45760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000c8565b60cc80546001600160a01b03191661dead179055565b608051611cee620002146000396000818161033b0152818161048a01526114ef0152611cee6000f3fe60806040526004361061015f5760003560e01c80636e296e45116100c0578063b1b1b20911610074578063c4d66de811610059578063c4d66de8146103ed578063d764ad0b1461040d578063ecc704281461042057600080fd5b8063b1b1b2091461039d578063b28ade25146103cd57600080fd5b80638cbeeef2116100a55780638cbeeef2146102505780639fce812c14610329578063a4e7f8bd1461035d57600080fd5b80636e296e45146102fd57806383a740741461031257600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146102665780635644cfdf146102bc5780636425666b146102d257600080fd5b80633f827a5a146102285780634c1d6a691461025057600080fd5b80630ff754ea116101485780630ff754ea146101ac5780632828d7e8146101fe5780633dbb202b1461021357600080fd5b8063028f85f7146101645780630c56849814610197575b600080fd5b34801561017057600080fd5b50610179601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101a357600080fd5b50610179603f81565b3480156101b857600080fd5b5060f9546101d99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018e565b34801561020a57600080fd5b50610179604081565b6102266102213660046117ba565b610485565b005b34801561023457600080fd5b5061023d600181565b60405161ffff909116815260200161018e565b34801561025c57600080fd5b50610179619c4081565b34801561027257600080fd5b506102af6040518060400160405280600581526020017f312e372e3100000000000000000000000000000000000000000000000000000081525081565b60405161018e919061188c565b3480156102c857600080fd5b5061017961138881565b3480156102de57600080fd5b5060f95473ffffffffffffffffffffffffffffffffffffffff166101d9565b34801561030957600080fd5b506101d96106e9565b34801561031e57600080fd5b5061017962030d4081565b34801561033557600080fd5b506101d97f000000000000000000000000000000000000000000000000000000000000000081565b34801561036957600080fd5b5061038d6103783660046118a6565b60ce6020526000908152604090205460ff1681565b604051901515815260200161018e565b3480156103a957600080fd5b5061038d6103b83660046118a6565b60cb6020526000908152604090205460ff1681565b3480156103d957600080fd5b506101796103e83660046118bf565b6107d5565b3480156103f957600080fd5b50610226610408366004611913565b610843565b61022661041b366004611930565b610a47565b34801561042c57600080fd5b5061047760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b60405190815260200161018e565b6105be7f00000000000000000000000000000000000000000000000000000000000000006104b48585856107d5565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061052060cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c60405160240161053c97969594939291906119ff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526112d3565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561064360cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b86604051610655959493929190611a5e565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6107f1604063ffffffff8816611adb565b6107fb9190611b0b565b610806601088611adb565b6108139062030d40611b59565b61081d9190611b59565b6108279190611b59565b6108319190611b59565b61083b9190611b59565b949350505050565b6000546003907501000000000000000000000000000000000000000000900460ff16158015610891575060005460ff8083167401000000000000000000000000000000000000000090920416105b61091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107af565b6000805475010000000000000000000000000000000000000000007fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000060ff8516027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff161717905560f980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556109e561136c565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60f087901c60028110610b02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107af565b8061ffff16600003610bf7576000610b53878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250611445915050565b600081815260cb602052604090205490915060ff1615610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107af565b505b6000610c3d898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146492505050565b9050610c47611487565b15610c7f57853414610c5b57610c5b611b85565b600081815260ce602052604090205460ff1615610c7a57610c7a611b85565b610dd1565b3415610d33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107af565b600081815260ce602052604090205460ff16610dd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107af565b610dda8761157d565b15610e8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107af565b600081815260cb602052604090205460ff1615610f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107af565b610f4d85610f3e611388619c40611b59565b67ffffffffffffffff166115c3565b1580610f73575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561108c57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b50506112c5565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061111d88619c405a6110e09190611bb4565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115e192505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111b457600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112c1565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b5050505b50505050505050565b905090565b60f9546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611334908890839089906000908990600401611bcb565b6000604051808303818588803b15801561134d57600080fd5b505af1158015611361573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107af565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611453858585856115fb565b805190602001209050949350505050565b6000611474878787878787611694565b8051906020012090509695505050505050565b60f95460009073ffffffffffffffffffffffffffffffffffffffff16331480156112ce575060f954604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691639bf62d829160048083019260209291908290030181865afa15801561153d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115619190611c23565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff82163014806115bd575060f95473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116149493929190611c40565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60608686868686866040516024016116b196959493929190611c8a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461175557600080fd5b50565b60008083601f84011261176a57600080fd5b50813567ffffffffffffffff81111561178257600080fd5b60208301915083602082850101111561179a57600080fd5b9250929050565b803563ffffffff811681146117b557600080fd5b919050565b600080600080606085870312156117d057600080fd5b84356117db81611733565b9350602085013567ffffffffffffffff8111156117f757600080fd5b61180387828801611758565b90945092506118169050604086016117a1565b905092959194509250565b6000815180845260005b818110156118475760208185018101518683018201520161182b565b81811115611859576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061189f6020830184611821565b9392505050565b6000602082840312156118b857600080fd5b5035919050565b6000806000604084860312156118d457600080fd5b833567ffffffffffffffff8111156118eb57600080fd5b6118f786828701611758565b909450925061190a9050602085016117a1565b90509250925092565b60006020828403121561192557600080fd5b813561189f81611733565b600080600080600080600060c0888a03121561194b57600080fd5b87359650602088013561195d81611733565b9550604088013561196d81611733565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561199757600080fd5b6119a38a828b01611758565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611a5160c0830184866119b6565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611a8e6080830186886119b6565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611b0257611b02611aac565b02949350505050565b600067ffffffffffffffff80841680611b4d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b7c57611b7c611aac565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611bc657611bc6611aac565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611c1860a0830184611821565b979650505050505050565b600060208284031215611c3557600080fd5b815161189f81611733565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611c796080830185611821565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611cd560c0830184611821565b9897505050505050505056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"MESSAGE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OTHER_MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PORTAL\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOptimismPortal\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_CALL_OVERHEAD\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_RESERVED_GAS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"baseGas\",\"inputs\":[{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"failedMessages\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_superchainConfig\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"},{\"name\":\"_portal\",\"type\":\"address\",\"internalType\":\"contractOptimismPortal\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"messageNonce\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"otherMessenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"portal\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractOptimismPortal\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"relayMessage\",\"inputs\":[{\"name\":\"_nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"sendMessage\",\"inputs\":[{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"successfulMessages\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"superchainConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"xDomainMessageSender\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"FailedRelayedMessage\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RelayedMessage\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SentMessage\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"message\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"messageNonce\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"gasLimit\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SentMessageExtension1\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b506200001f60008062000025565b6200027f565b600054600160a81b900460ff16158080156200004e57506000546001600160a01b90910460ff16105b806200008557506200006b30620001b960201b620014d61760201c565b158015620000855750600054600160a01b900460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a01b1916600160a01b17905580156200011c576000805460ff60a81b1916600160a81b1790555b60fb80546001600160a01b038086166001600160a01b03199283161790925560fc8054928516929091169190911790556200016b734200000000000000000000000000000000000007620001c8565b8015620001b4576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054600160a81b900460ff16620002375760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60cc546001600160a01b03166200025d5760cc80546001600160a01b03191661dead1790555b60cf80546001600160a01b0319166001600160a01b0392909216919091179055565b611f94806200028f6000396000f3fe6080604052600436106101805760003560e01c80635c975abb116100d6578063a4e7f8bd1161007f578063d764ad0b11610059578063d764ad0b14610463578063db505d8014610476578063ecc70428146104a357600080fd5b8063a4e7f8bd146103e3578063b1b1b20914610413578063b28ade251461044357600080fd5b806383a74074116100b057806383a74074146103a15780638cbeeef2146102b85780639fce812c146103b857600080fd5b80635c975abb1461033a5780636425666b1461035f5780636e296e451461038c57600080fd5b80633dbb202b116101385780634c1d6a69116101125780634c1d6a69146102b857806354fd4d50146102ce5780635644cfdf1461032457600080fd5b80633dbb202b1461025b5780633f827a5a14610270578063485cc9551461029857600080fd5b80630ff754ea116101695780630ff754ea146101cd5780632828d7e81461021957806335e80ab31461022e57600080fd5b8063028f85f7146101855780630c568498146101b8575b600080fd5b34801561019157600080fd5b5061019a601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101c457600080fd5b5061019a603f81565b3480156101d957600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101af565b34801561022557600080fd5b5061019a604081565b34801561023a57600080fd5b5060fb546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b61026e610269366004611a22565b610508565b005b34801561027c57600080fd5b50610285600181565b60405161ffff90911681526020016101af565b3480156102a457600080fd5b5061026e6102b3366004611a89565b610765565b3480156102c457600080fd5b5061019a619c4081565b3480156102da57600080fd5b506103176040518060400160405280600581526020017f322e332e3000000000000000000000000000000000000000000000000000000081525081565b6040516101af9190611b2d565b34801561033057600080fd5b5061019a61138881565b34801561034657600080fd5b5061034f6109d3565b60405190151581526020016101af565b34801561036b57600080fd5b5060fc546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b34801561039857600080fd5b506101f4610a6c565b3480156103ad57600080fd5b5061019a62030d4081565b3480156103c457600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101f4565b3480156103ef57600080fd5b5061034f6103fe366004611b47565b60ce6020526000908152604090205460ff1681565b34801561041f57600080fd5b5061034f61042e366004611b47565b60cb6020526000908152604090205460ff1681565b34801561044f57600080fd5b5061019a61045e366004611b60565b610b53565b61026e610471366004611bb4565b610bc1565b34801561048257600080fd5b5060cf546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104af57600080fd5b506104fa60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101af565b60cf5461063a9073ffffffffffffffffffffffffffffffffffffffff16610530858585610b53565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061059c60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016105b89796959493929190611c83565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526114f2565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856106bf60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516106d1959493929190611ce2565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b6000547501000000000000000000000000000000000000000000900460ff16158080156107b0575060005460017401000000000000000000000000000000000000000090910460ff16105b806107e25750303b1580156107e2575060005474010000000000000000000000000000000000000000900460ff166001145b610873576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905580156108f957600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc80549285169290911691909117905561096b73420000000000000000000000000000000000000761158b565b80156109ce57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a679190611d30565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff215301610b36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f74207365740000000000000000000000606482015260840161086a565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f610b6f604063ffffffff8816611d81565b610b799190611db1565b610b84601088611d81565b610b919062030d40611dff565b610b9b9190611dff565b610ba59190611dff565b610baf9190611dff565b610bb99190611dff565b949350505050565b610bc96109d3565b15610c30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a2070617573656400000000604482015260640161086a565b60f087901c60028110610ceb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a40161086a565b8061ffff16600003610de0576000610d3c878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506116c7915050565b600081815260cb602052604090205490915060ff1615610dde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c61796564000000000000000000606482015260840161086a565b505b6000610e26898989898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116e692505050565b9050610e30611709565b15610e6857853414610e4457610e44611e2b565b600081815260ce602052604090205460ff1615610e6357610e63611e2b565b610fba565b3415610f1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a40161086a565b600081815260ce602052604090205460ff16610fba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c6179656400000000000000000000000000000000606482015260840161086a565b610fc3876117e5565b15611076576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a40161086a565b600081815260cb602052604090205460ff1615611115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c6179656400000000000000000000606482015260840161086a565b61113685611127611388619c40611dff565b67ffffffffffffffff1661182b565b158061115c575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561127557600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161126e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161086a565b50506114cd565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061130688619c405a6112c99190611e5a565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061184992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156113bc57600082815260cb602052604090205460ff161561135957611359611e2b565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26114c9565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016114c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161086a565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611553908890839089906000908990600401611e71565b6000604051808303818588803b15801561156c57600080fd5b505af1158015611580573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611636576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161086a565b60cc5473ffffffffffffffffffffffffffffffffffffffff166116805760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006116d585858585611863565b805190602001209050949350505050565b60006116f68787878787876118fc565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff1633148015610a67575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156117a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c99190611ec9565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611825575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b60608484848460405160240161187c9493929190611ee6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161191996959493929190611f30565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146119bd57600080fd5b50565b60008083601f8401126119d257600080fd5b50813567ffffffffffffffff8111156119ea57600080fd5b602083019150836020828501011115611a0257600080fd5b9250929050565b803563ffffffff81168114611a1d57600080fd5b919050565b60008060008060608587031215611a3857600080fd5b8435611a438161199b565b9350602085013567ffffffffffffffff811115611a5f57600080fd5b611a6b878288016119c0565b9094509250611a7e905060408601611a09565b905092959194509250565b60008060408385031215611a9c57600080fd5b8235611aa78161199b565b91506020830135611ab78161199b565b809150509250929050565b6000815180845260005b81811015611ae857602081850181015186830182015201611acc565b81811115611afa576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611b406020830184611ac2565b9392505050565b600060208284031215611b5957600080fd5b5035919050565b600080600060408486031215611b7557600080fd5b833567ffffffffffffffff811115611b8c57600080fd5b611b98868287016119c0565b9094509250611bab905060208501611a09565b90509250925092565b600080600080600080600060c0888a031215611bcf57600080fd5b873596506020880135611be18161199b565b95506040880135611bf18161199b565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611c1b57600080fd5b611c278a828b016119c0565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611cd560c083018486611c3a565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611d12608083018688611c3a565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611d4257600080fd5b81518015158114611b4057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611da857611da8611d52565b02949350505050565b600067ffffffffffffffff80841680611df3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611e2257611e22611d52565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611e6c57611e6c611d52565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611ebe60a0830184611ac2565b979650505050505050565b600060208284031215611edb57600080fd5b8151611b408161199b565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611f1f6080830185611ac2565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611f7b60c0830184611ac2565b9897505050505050505056fea164736f6c634300080f000a", } // L1CrossDomainMessengerABI is the input ABI used to generate the binding from. @@ -604,6 +604,68 @@ func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) MessageNonce return _L1CrossDomainMessenger.Contract.MessageNonce(&_L1CrossDomainMessenger.CallOpts) } +// OtherMessenger is a free data retrieval call binding the contract method 0xdb505d80. +// +// Solidity: function otherMessenger() view returns(address) +func (_L1CrossDomainMessenger *L1CrossDomainMessengerCaller) OtherMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L1CrossDomainMessenger.contract.Call(opts, &out, "otherMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// OtherMessenger is a free data retrieval call binding the contract method 0xdb505d80. +// +// Solidity: function otherMessenger() view returns(address) +func (_L1CrossDomainMessenger *L1CrossDomainMessengerSession) OtherMessenger() (common.Address, error) { + return _L1CrossDomainMessenger.Contract.OtherMessenger(&_L1CrossDomainMessenger.CallOpts) +} + +// OtherMessenger is a free data retrieval call binding the contract method 0xdb505d80. +// +// Solidity: function otherMessenger() view returns(address) +func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) OtherMessenger() (common.Address, error) { + return _L1CrossDomainMessenger.Contract.OtherMessenger(&_L1CrossDomainMessenger.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1CrossDomainMessenger *L1CrossDomainMessengerCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _L1CrossDomainMessenger.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1CrossDomainMessenger *L1CrossDomainMessengerSession) Paused() (bool, error) { + return _L1CrossDomainMessenger.Contract.Paused(&_L1CrossDomainMessenger.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) Paused() (bool, error) { + return _L1CrossDomainMessenger.Contract.Paused(&_L1CrossDomainMessenger.CallOpts) +} + // Portal is a free data retrieval call binding the contract method 0x6425666b. // // Solidity: function portal() view returns(address) @@ -666,6 +728,37 @@ func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) SuccessfulMe return _L1CrossDomainMessenger.Contract.SuccessfulMessages(&_L1CrossDomainMessenger.CallOpts, arg0) } +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_L1CrossDomainMessenger *L1CrossDomainMessengerCaller) SuperchainConfig(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L1CrossDomainMessenger.contract.Call(opts, &out, "superchainConfig") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_L1CrossDomainMessenger *L1CrossDomainMessengerSession) SuperchainConfig() (common.Address, error) { + return _L1CrossDomainMessenger.Contract.SuperchainConfig(&_L1CrossDomainMessenger.CallOpts) +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) SuperchainConfig() (common.Address, error) { + return _L1CrossDomainMessenger.Contract.SuperchainConfig(&_L1CrossDomainMessenger.CallOpts) +} + // Version is a free data retrieval call binding the contract method 0x54fd4d50. // // Solidity: function version() view returns(string) @@ -728,25 +821,25 @@ func (_L1CrossDomainMessenger *L1CrossDomainMessengerCallerSession) XDomainMessa return _L1CrossDomainMessenger.Contract.XDomainMessageSender(&_L1CrossDomainMessenger.CallOpts) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. // -// Solidity: function initialize(address _portal) returns() -func (_L1CrossDomainMessenger *L1CrossDomainMessengerTransactor) Initialize(opts *bind.TransactOpts, _portal common.Address) (*types.Transaction, error) { - return _L1CrossDomainMessenger.contract.Transact(opts, "initialize", _portal) +// Solidity: function initialize(address _superchainConfig, address _portal) returns() +func (_L1CrossDomainMessenger *L1CrossDomainMessengerTransactor) Initialize(opts *bind.TransactOpts, _superchainConfig common.Address, _portal common.Address) (*types.Transaction, error) { + return _L1CrossDomainMessenger.contract.Transact(opts, "initialize", _superchainConfig, _portal) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. // -// Solidity: function initialize(address _portal) returns() -func (_L1CrossDomainMessenger *L1CrossDomainMessengerSession) Initialize(_portal common.Address) (*types.Transaction, error) { - return _L1CrossDomainMessenger.Contract.Initialize(&_L1CrossDomainMessenger.TransactOpts, _portal) +// Solidity: function initialize(address _superchainConfig, address _portal) returns() +func (_L1CrossDomainMessenger *L1CrossDomainMessengerSession) Initialize(_superchainConfig common.Address, _portal common.Address) (*types.Transaction, error) { + return _L1CrossDomainMessenger.Contract.Initialize(&_L1CrossDomainMessenger.TransactOpts, _superchainConfig, _portal) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. // -// Solidity: function initialize(address _portal) returns() -func (_L1CrossDomainMessenger *L1CrossDomainMessengerTransactorSession) Initialize(_portal common.Address) (*types.Transaction, error) { - return _L1CrossDomainMessenger.Contract.Initialize(&_L1CrossDomainMessenger.TransactOpts, _portal) +// Solidity: function initialize(address _superchainConfig, address _portal) returns() +func (_L1CrossDomainMessenger *L1CrossDomainMessengerTransactorSession) Initialize(_superchainConfig common.Address, _portal common.Address) (*types.Transaction, error) { + return _L1CrossDomainMessenger.Contract.Initialize(&_L1CrossDomainMessenger.TransactOpts, _superchainConfig, _portal) } // RelayMessage is a paid mutator transaction binding the contract method 0xd764ad0b. diff --git a/op-bindings/bindings/l1crossdomainmessenger_more.go b/op-bindings/bindings/l1crossdomainmessenger_more.go index 66a1c93bbe6f..29bf2328d28d 100644 --- a/op-bindings/bindings/l1crossdomainmessenger_more.go +++ b/op-bindings/bindings/l1crossdomainmessenger_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const L1CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1001,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1002,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1003,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_1_0_1600\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1004,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_51_0_20\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1005,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_52_0_1568\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1006,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_101_0_1\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":1007,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_102_0_1568\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1008,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_151_0_32\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":1009,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_152_0_1568\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1010,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1011,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1012,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1013,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":1014,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":1015,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"failedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1016,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"},{\"astId\":1017,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"PORTAL\",\"offset\":0,\"slot\":\"249\",\"type\":\"t_contract(OptimismPortal)1018\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\",\"base\":\"t_uint256\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_contract(OptimismPortal)1018\":{\"encoding\":\"inplace\",\"label\":\"contract OptimismPortal\",\"numberOfBytes\":\"20\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const L1CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1001,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1002,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1003,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_1_0_1600\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1004,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_51_0_20\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1005,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_52_0_1568\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1006,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_101_0_1\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":1007,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_102_0_1568\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1008,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_151_0_32\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":1009,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_152_0_1568\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1010,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1011,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1012,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1013,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":1014,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":1015,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"failedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1016,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"otherMessenger\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_contract(CrossDomainMessenger)1020\"},{\"astId\":1017,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"208\",\"type\":\"t_array(t_uint256)43_storage\"},{\"astId\":1018,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"superchainConfig\",\"offset\":0,\"slot\":\"251\",\"type\":\"t_contract(SuperchainConfig)1022\"},{\"astId\":1019,\"contract\":\"src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"portal\",\"offset\":0,\"slot\":\"252\",\"type\":\"t_contract(OptimismPortal)1021\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)43_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[43]\",\"numberOfBytes\":\"1376\",\"base\":\"t_uint256\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_contract(CrossDomainMessenger)1020\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_contract(OptimismPortal)1021\":{\"encoding\":\"inplace\",\"label\":\"contract OptimismPortal\",\"numberOfBytes\":\"20\"},\"t_contract(SuperchainConfig)1022\":{\"encoding\":\"inplace\",\"label\":\"contract SuperchainConfig\",\"numberOfBytes\":\"20\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var L1CrossDomainMessengerStorageLayout = new(solc.StorageLayout) -var L1CrossDomainMessengerDeployedBin = "0x60806040526004361061015f5760003560e01c80636e296e45116100c0578063b1b1b20911610074578063c4d66de811610059578063c4d66de8146103ed578063d764ad0b1461040d578063ecc704281461042057600080fd5b8063b1b1b2091461039d578063b28ade25146103cd57600080fd5b80638cbeeef2116100a55780638cbeeef2146102505780639fce812c14610329578063a4e7f8bd1461035d57600080fd5b80636e296e45146102fd57806383a740741461031257600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146102665780635644cfdf146102bc5780636425666b146102d257600080fd5b80633f827a5a146102285780634c1d6a691461025057600080fd5b80630ff754ea116101485780630ff754ea146101ac5780632828d7e8146101fe5780633dbb202b1461021357600080fd5b8063028f85f7146101645780630c56849814610197575b600080fd5b34801561017057600080fd5b50610179601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101a357600080fd5b50610179603f81565b3480156101b857600080fd5b5060f9546101d99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018e565b34801561020a57600080fd5b50610179604081565b6102266102213660046117ba565b610485565b005b34801561023457600080fd5b5061023d600181565b60405161ffff909116815260200161018e565b34801561025c57600080fd5b50610179619c4081565b34801561027257600080fd5b506102af6040518060400160405280600581526020017f312e372e3100000000000000000000000000000000000000000000000000000081525081565b60405161018e919061188c565b3480156102c857600080fd5b5061017961138881565b3480156102de57600080fd5b5060f95473ffffffffffffffffffffffffffffffffffffffff166101d9565b34801561030957600080fd5b506101d96106e9565b34801561031e57600080fd5b5061017962030d4081565b34801561033557600080fd5b506101d97f000000000000000000000000000000000000000000000000000000000000000081565b34801561036957600080fd5b5061038d6103783660046118a6565b60ce6020526000908152604090205460ff1681565b604051901515815260200161018e565b3480156103a957600080fd5b5061038d6103b83660046118a6565b60cb6020526000908152604090205460ff1681565b3480156103d957600080fd5b506101796103e83660046118bf565b6107d5565b3480156103f957600080fd5b50610226610408366004611913565b610843565b61022661041b366004611930565b610a47565b34801561042c57600080fd5b5061047760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b60405190815260200161018e565b6105be7f00000000000000000000000000000000000000000000000000000000000000006104b48585856107d5565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061052060cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c60405160240161053c97969594939291906119ff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526112d3565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561064360cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b86604051610655959493929190611a5e565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6107f1604063ffffffff8816611adb565b6107fb9190611b0b565b610806601088611adb565b6108139062030d40611b59565b61081d9190611b59565b6108279190611b59565b6108319190611b59565b61083b9190611b59565b949350505050565b6000546003907501000000000000000000000000000000000000000000900460ff16158015610891575060005460ff8083167401000000000000000000000000000000000000000090920416105b61091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107af565b6000805475010000000000000000000000000000000000000000007fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000060ff8516027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff161717905560f980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556109e561136c565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60f087901c60028110610b02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107af565b8061ffff16600003610bf7576000610b53878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250611445915050565b600081815260cb602052604090205490915060ff1615610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107af565b505b6000610c3d898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146492505050565b9050610c47611487565b15610c7f57853414610c5b57610c5b611b85565b600081815260ce602052604090205460ff1615610c7a57610c7a611b85565b610dd1565b3415610d33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107af565b600081815260ce602052604090205460ff16610dd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107af565b610dda8761157d565b15610e8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107af565b600081815260cb602052604090205460ff1615610f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107af565b610f4d85610f3e611388619c40611b59565b67ffffffffffffffff166115c3565b1580610f73575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561108c57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b50506112c5565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061111d88619c405a6110e09190611bb4565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115e192505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111b457600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112c1565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b5050505b50505050505050565b905090565b60f9546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611334908890839089906000908990600401611bcb565b6000604051808303818588803b15801561134d57600080fd5b505af1158015611361573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107af565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611453858585856115fb565b805190602001209050949350505050565b6000611474878787878787611694565b8051906020012090509695505050505050565b60f95460009073ffffffffffffffffffffffffffffffffffffffff16331480156112ce575060f954604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691639bf62d829160048083019260209291908290030181865afa15801561153d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115619190611c23565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff82163014806115bd575060f95473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116149493929190611c40565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60608686868686866040516024016116b196959493929190611c8a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461175557600080fd5b50565b60008083601f84011261176a57600080fd5b50813567ffffffffffffffff81111561178257600080fd5b60208301915083602082850101111561179a57600080fd5b9250929050565b803563ffffffff811681146117b557600080fd5b919050565b600080600080606085870312156117d057600080fd5b84356117db81611733565b9350602085013567ffffffffffffffff8111156117f757600080fd5b61180387828801611758565b90945092506118169050604086016117a1565b905092959194509250565b6000815180845260005b818110156118475760208185018101518683018201520161182b565b81811115611859576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061189f6020830184611821565b9392505050565b6000602082840312156118b857600080fd5b5035919050565b6000806000604084860312156118d457600080fd5b833567ffffffffffffffff8111156118eb57600080fd5b6118f786828701611758565b909450925061190a9050602085016117a1565b90509250925092565b60006020828403121561192557600080fd5b813561189f81611733565b600080600080600080600060c0888a03121561194b57600080fd5b87359650602088013561195d81611733565b9550604088013561196d81611733565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561199757600080fd5b6119a38a828b01611758565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611a5160c0830184866119b6565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611a8e6080830186886119b6565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611b0257611b02611aac565b02949350505050565b600067ffffffffffffffff80841680611b4d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b7c57611b7c611aac565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611bc657611bc6611aac565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611c1860a0830184611821565b979650505050505050565b600060208284031215611c3557600080fd5b815161189f81611733565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611c796080830185611821565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611cd560c0830184611821565b9897505050505050505056fea164736f6c634300080f000a" +var L1CrossDomainMessengerDeployedBin = "0x6080604052600436106101805760003560e01c80635c975abb116100d6578063a4e7f8bd1161007f578063d764ad0b11610059578063d764ad0b14610463578063db505d8014610476578063ecc70428146104a357600080fd5b8063a4e7f8bd146103e3578063b1b1b20914610413578063b28ade251461044357600080fd5b806383a74074116100b057806383a74074146103a15780638cbeeef2146102b85780639fce812c146103b857600080fd5b80635c975abb1461033a5780636425666b1461035f5780636e296e451461038c57600080fd5b80633dbb202b116101385780634c1d6a69116101125780634c1d6a69146102b857806354fd4d50146102ce5780635644cfdf1461032457600080fd5b80633dbb202b1461025b5780633f827a5a14610270578063485cc9551461029857600080fd5b80630ff754ea116101695780630ff754ea146101cd5780632828d7e81461021957806335e80ab31461022e57600080fd5b8063028f85f7146101855780630c568498146101b8575b600080fd5b34801561019157600080fd5b5061019a601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101c457600080fd5b5061019a603f81565b3480156101d957600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101af565b34801561022557600080fd5b5061019a604081565b34801561023a57600080fd5b5060fb546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b61026e610269366004611a22565b610508565b005b34801561027c57600080fd5b50610285600181565b60405161ffff90911681526020016101af565b3480156102a457600080fd5b5061026e6102b3366004611a89565b610765565b3480156102c457600080fd5b5061019a619c4081565b3480156102da57600080fd5b506103176040518060400160405280600581526020017f322e332e3000000000000000000000000000000000000000000000000000000081525081565b6040516101af9190611b2d565b34801561033057600080fd5b5061019a61138881565b34801561034657600080fd5b5061034f6109d3565b60405190151581526020016101af565b34801561036b57600080fd5b5060fc546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b34801561039857600080fd5b506101f4610a6c565b3480156103ad57600080fd5b5061019a62030d4081565b3480156103c457600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101f4565b3480156103ef57600080fd5b5061034f6103fe366004611b47565b60ce6020526000908152604090205460ff1681565b34801561041f57600080fd5b5061034f61042e366004611b47565b60cb6020526000908152604090205460ff1681565b34801561044f57600080fd5b5061019a61045e366004611b60565b610b53565b61026e610471366004611bb4565b610bc1565b34801561048257600080fd5b5060cf546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104af57600080fd5b506104fa60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101af565b60cf5461063a9073ffffffffffffffffffffffffffffffffffffffff16610530858585610b53565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061059c60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016105b89796959493929190611c83565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526114f2565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856106bf60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516106d1959493929190611ce2565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b6000547501000000000000000000000000000000000000000000900460ff16158080156107b0575060005460017401000000000000000000000000000000000000000090910460ff16105b806107e25750303b1580156107e2575060005474010000000000000000000000000000000000000000900460ff166001145b610873576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905580156108f957600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc80549285169290911691909117905561096b73420000000000000000000000000000000000000761158b565b80156109ce57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a679190611d30565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff215301610b36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f74207365740000000000000000000000606482015260840161086a565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f610b6f604063ffffffff8816611d81565b610b799190611db1565b610b84601088611d81565b610b919062030d40611dff565b610b9b9190611dff565b610ba59190611dff565b610baf9190611dff565b610bb99190611dff565b949350505050565b610bc96109d3565b15610c30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a2070617573656400000000604482015260640161086a565b60f087901c60028110610ceb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a40161086a565b8061ffff16600003610de0576000610d3c878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506116c7915050565b600081815260cb602052604090205490915060ff1615610dde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c61796564000000000000000000606482015260840161086a565b505b6000610e26898989898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116e692505050565b9050610e30611709565b15610e6857853414610e4457610e44611e2b565b600081815260ce602052604090205460ff1615610e6357610e63611e2b565b610fba565b3415610f1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a40161086a565b600081815260ce602052604090205460ff16610fba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c6179656400000000000000000000000000000000606482015260840161086a565b610fc3876117e5565b15611076576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a40161086a565b600081815260cb602052604090205460ff1615611115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c6179656400000000000000000000606482015260840161086a565b61113685611127611388619c40611dff565b67ffffffffffffffff1661182b565b158061115c575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561127557600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161126e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161086a565b50506114cd565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061130688619c405a6112c99190611e5a565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061184992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156113bc57600082815260cb602052604090205460ff161561135957611359611e2b565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26114c9565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016114c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161086a565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611553908890839089906000908990600401611e71565b6000604051808303818588803b15801561156c57600080fd5b505af1158015611580573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611636576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161086a565b60cc5473ffffffffffffffffffffffffffffffffffffffff166116805760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006116d585858585611863565b805190602001209050949350505050565b60006116f68787878787876118fc565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff1633148015610a67575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156117a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c99190611ec9565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611825575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b60608484848460405160240161187c9493929190611ee6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161191996959493929190611f30565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146119bd57600080fd5b50565b60008083601f8401126119d257600080fd5b50813567ffffffffffffffff8111156119ea57600080fd5b602083019150836020828501011115611a0257600080fd5b9250929050565b803563ffffffff81168114611a1d57600080fd5b919050565b60008060008060608587031215611a3857600080fd5b8435611a438161199b565b9350602085013567ffffffffffffffff811115611a5f57600080fd5b611a6b878288016119c0565b9094509250611a7e905060408601611a09565b905092959194509250565b60008060408385031215611a9c57600080fd5b8235611aa78161199b565b91506020830135611ab78161199b565b809150509250929050565b6000815180845260005b81811015611ae857602081850181015186830182015201611acc565b81811115611afa576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611b406020830184611ac2565b9392505050565b600060208284031215611b5957600080fd5b5035919050565b600080600060408486031215611b7557600080fd5b833567ffffffffffffffff811115611b8c57600080fd5b611b98868287016119c0565b9094509250611bab905060208501611a09565b90509250925092565b600080600080600080600060c0888a031215611bcf57600080fd5b873596506020880135611be18161199b565b95506040880135611bf18161199b565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611c1b57600080fd5b611c278a828b016119c0565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611cd560c083018486611c3a565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611d12608083018688611c3a565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611d4257600080fd5b81518015158114611b4057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611da857611da8611d52565b02949350505050565b600067ffffffffffffffff80841680611df3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611e2257611e22611d52565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611e6c57611e6c611d52565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611ebe60a0830184611ac2565b979650505050505050565b600060208284031215611edb57600080fd5b8151611b408161199b565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611f1f6080830185611ac2565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611f7b60c0830184611ac2565b9897505050505050505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L1CrossDomainMessengerStorageLayoutJSON), L1CrossDomainMessengerStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["L1CrossDomainMessenger"] = L1CrossDomainMessengerStorageLayout deployedBytecodes["L1CrossDomainMessenger"] = L1CrossDomainMessengerDeployedBin + immutableReferences["L1CrossDomainMessenger"] = false } diff --git a/op-bindings/bindings/l1erc721bridge.go b/op-bindings/bindings/l1erc721bridge.go index ad0349dbd1d5..c80d2bb3b95a 100644 --- a/op-bindings/bindings/l1erc721bridge.go +++ b/op-bindings/bindings/l1erc721bridge.go @@ -30,8 +30,8 @@ var ( // L1ERC721BridgeMetaData contains all meta data concerning the L1ERC721Bridge contract. var L1ERC721BridgeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC721BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC721BridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC721To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"_messenger\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a060405234801561001057600080fd5b50734200000000000000000000000000000000000014610034565b60405180910390fd5b6001600160a01b031660805261004a600061004f565b6101cb565b600054600390610100900460ff16158015610071575060005460ff8083169116105b6100d45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161002b565b6000805461ffff191660ff8316176101001790556100f182610136565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054610100900460ff166101a15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161002b565b600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6080516112116101fb600039600081816101cd0152818161023b015281816103350152610bf101526112116000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80637f46ddb211610076578063aa5574521161005b578063aa55745214610213578063c4d66de814610226578063c89701a21461023957600080fd5b80637f46ddb2146101c8578063927ede2d146101ef57600080fd5b806354fd4d50116100a757806354fd4d50146101285780635d93a3fc14610171578063761f4493146101b557600080fd5b80633687011a146100c35780633cb747bf146100d8575b600080fd5b6100d66100d1366004610e47565b61025f565b005b6000546100fe9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101646040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b60405161011f9190610f35565b6101a561017f366004610f4f565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b604051901515815260200161011f565b6100d66101c3366004610f90565b61030b565b6100fe7f000000000000000000000000000000000000000000000000000000000000000081565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166100fe565b6100d6610221366004611028565b610776565b6100d661023436600461109f565b610832565b7f00000000000000000000000000000000000000000000000000000000000000006100fe565b333b156102f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b610303868633338888888861097c565b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314801561041357507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fb91906110bc565b73ffffffffffffffffffffffffffffffffffffffff16145b61049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f74686572206272696467650060648201526084016102ea565b3073ffffffffffffffffffffffffffffffffffffffff881603610544576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff161515600114610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c31204272696467650000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156106d357600080fd5b505af11580156106e7573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107659493929190611122565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f7420626520616464726573732830290000000000000000000000000000000060648201526084016102ea565b610829878733888888888861097c565b50505050505050565b600054600390610100900460ff16158015610854575060005460ff8083169116105b6108e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016102ea565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561091a82610cdc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b73ffffffffffffffffffffffffffffffffffffffff8716610a1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f74206265206164647265737328302900000000000000000000000000000060648201526084016102ea565b600063761f449360e01b888a8989898888604051602401610a469796959493929190611162565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610b8657600080fd5b505af1158015610b9a573d6000803e3d6000fd5b50506000546040517f3dbb202b0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169250633dbb202b9150610c1d907f000000000000000000000000000000000000000000000000000000000000000090859089906004016111bf565b600060405180830381600087803b158015610c3757600080fd5b505af1158015610c4b573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610cc99493929190611122565b60405180910390a4505050505050505050565b600054610100900460ff16610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ea565b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610de257600080fd5b50565b803563ffffffff81168114610df957600080fd5b919050565b60008083601f840112610e1057600080fd5b50813567ffffffffffffffff811115610e2857600080fd5b602083019150836020828501011115610e4057600080fd5b9250929050565b60008060008060008060a08789031215610e6057600080fd5b8635610e6b81610dc0565b95506020870135610e7b81610dc0565b945060408701359350610e9060608801610de5565b9250608087013567ffffffffffffffff811115610eac57600080fd5b610eb889828a01610dfe565b979a9699509497509295939492505050565b6000815180845260005b81811015610ef057602081850181015186830182015201610ed4565b81811115610f02576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f486020830184610eca565b9392505050565b600080600060608486031215610f6457600080fd5b8335610f6f81610dc0565b92506020840135610f7f81610dc0565b929592945050506040919091013590565b600080600080600080600060c0888a031215610fab57600080fd5b8735610fb681610dc0565b96506020880135610fc681610dc0565b95506040880135610fd681610dc0565b94506060880135610fe681610dc0565b93506080880135925060a088013567ffffffffffffffff81111561100957600080fd5b6110158a828b01610dfe565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561104357600080fd5b873561104e81610dc0565b9650602088013561105e81610dc0565b9550604088013561106e81610dc0565b94506060880135935061108360808901610de5565b925060a088013567ffffffffffffffff81111561100957600080fd5b6000602082840312156110b157600080fd5b8135610f4881610dc0565b6000602082840312156110ce57600080fd5b8151610f4881610dc0565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006111586060830184866110d9565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a08301526111b260c0830184866110d9565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006111ee6060830185610eca565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"bridgeERC721\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bridgeERC721To\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"deposits\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"finalizeBridgeERC721\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_messenger\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"},{\"name\":\"_superchainConfig\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"messenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"otherBridge\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"superchainConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ERC721BridgeFinalized\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ERC721BridgeInitiated\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b506200001f60008062000025565b62000234565b600054610100900460ff1615808015620000465750600054600160ff909116105b8062000076575062000063306200018a60201b62000b141760201c565b15801562000076575060005460ff166001145b620000df5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000103576000805461ff0019166101001790555b603280546001600160a01b0319166001600160a01b0384161790556200013e8373420000000000000000000000000000000000001462000199565b801562000185576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002065760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d6565b600180546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b6113e980620002446000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600581526020017f322e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", } // L1ERC721BridgeABI is the input ABI used to generate the binding from. @@ -356,6 +356,68 @@ func (_L1ERC721Bridge *L1ERC721BridgeCallerSession) OtherBridge() (common.Addres return _L1ERC721Bridge.Contract.OtherBridge(&_L1ERC721Bridge.CallOpts) } +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1ERC721Bridge *L1ERC721BridgeCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _L1ERC721Bridge.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1ERC721Bridge *L1ERC721BridgeSession) Paused() (bool, error) { + return _L1ERC721Bridge.Contract.Paused(&_L1ERC721Bridge.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1ERC721Bridge *L1ERC721BridgeCallerSession) Paused() (bool, error) { + return _L1ERC721Bridge.Contract.Paused(&_L1ERC721Bridge.CallOpts) +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_L1ERC721Bridge *L1ERC721BridgeCaller) SuperchainConfig(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L1ERC721Bridge.contract.Call(opts, &out, "superchainConfig") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_L1ERC721Bridge *L1ERC721BridgeSession) SuperchainConfig() (common.Address, error) { + return _L1ERC721Bridge.Contract.SuperchainConfig(&_L1ERC721Bridge.CallOpts) +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_L1ERC721Bridge *L1ERC721BridgeCallerSession) SuperchainConfig() (common.Address, error) { + return _L1ERC721Bridge.Contract.SuperchainConfig(&_L1ERC721Bridge.CallOpts) +} + // Version is a free data retrieval call binding the contract method 0x54fd4d50. // // Solidity: function version() view returns(string) @@ -450,25 +512,25 @@ func (_L1ERC721Bridge *L1ERC721BridgeTransactorSession) FinalizeBridgeERC721(_lo return _L1ERC721Bridge.Contract.FinalizeBridgeERC721(&_L1ERC721Bridge.TransactOpts, _localToken, _remoteToken, _from, _to, _tokenId, _extraData) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. // -// Solidity: function initialize(address _messenger) returns() -func (_L1ERC721Bridge *L1ERC721BridgeTransactor) Initialize(opts *bind.TransactOpts, _messenger common.Address) (*types.Transaction, error) { - return _L1ERC721Bridge.contract.Transact(opts, "initialize", _messenger) +// Solidity: function initialize(address _messenger, address _superchainConfig) returns() +func (_L1ERC721Bridge *L1ERC721BridgeTransactor) Initialize(opts *bind.TransactOpts, _messenger common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _L1ERC721Bridge.contract.Transact(opts, "initialize", _messenger, _superchainConfig) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. // -// Solidity: function initialize(address _messenger) returns() -func (_L1ERC721Bridge *L1ERC721BridgeSession) Initialize(_messenger common.Address) (*types.Transaction, error) { - return _L1ERC721Bridge.Contract.Initialize(&_L1ERC721Bridge.TransactOpts, _messenger) +// Solidity: function initialize(address _messenger, address _superchainConfig) returns() +func (_L1ERC721Bridge *L1ERC721BridgeSession) Initialize(_messenger common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _L1ERC721Bridge.Contract.Initialize(&_L1ERC721Bridge.TransactOpts, _messenger, _superchainConfig) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. // -// Solidity: function initialize(address _messenger) returns() -func (_L1ERC721Bridge *L1ERC721BridgeTransactorSession) Initialize(_messenger common.Address) (*types.Transaction, error) { - return _L1ERC721Bridge.Contract.Initialize(&_L1ERC721Bridge.TransactOpts, _messenger) +// Solidity: function initialize(address _messenger, address _superchainConfig) returns() +func (_L1ERC721Bridge *L1ERC721BridgeTransactorSession) Initialize(_messenger common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _L1ERC721Bridge.Contract.Initialize(&_L1ERC721Bridge.TransactOpts, _messenger, _superchainConfig) } // L1ERC721BridgeERC721BridgeFinalizedIterator is returned from FilterERC721BridgeFinalized and is used to iterate over the raw logs and unpacked data for ERC721BridgeFinalized events raised by the L1ERC721Bridge contract. diff --git a/op-bindings/bindings/l1erc721bridge_more.go b/op-bindings/bindings/l1erc721bridge_more.go index eac99b59ec12..522375412c14 100644 --- a/op-bindings/bindings/l1erc721bridge_more.go +++ b/op-bindings/bindings/l1erc721bridge_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const L1ERC721BridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"messenger\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_contract(CrossDomainMessenger)1005\"},{\"astId\":1003,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)48_storage\"},{\"astId\":1004,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"49\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint256,t_bool)))\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)48_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[48]\",\"numberOfBytes\":\"1536\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(CrossDomainMessenger)1005\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint256,t_bool)))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e mapping(uint256 =\u003e bool)))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_mapping(t_uint256,t_bool))\"},\"t_mapping(t_address,t_mapping(t_uint256,t_bool))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(uint256 =\u003e bool))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_uint256,t_bool)\"},\"t_mapping(t_uint256,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_bool\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const L1ERC721BridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"spacer_0_2_30\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_bytes30\"},{\"astId\":1003,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"messenger\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_contract(CrossDomainMessenger)1008\"},{\"astId\":1004,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"otherBridge\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_contract(StandardBridge)1009\"},{\"astId\":1005,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_uint256)46_storage\"},{\"astId\":1006,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"49\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint256,t_bool)))\"},{\"astId\":1007,\"contract\":\"src/L1/L1ERC721Bridge.sol:L1ERC721Bridge\",\"label\":\"superchainConfig\",\"offset\":0,\"slot\":\"50\",\"type\":\"t_contract(SuperchainConfig)1010\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)46_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[46]\",\"numberOfBytes\":\"1472\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes30\":{\"encoding\":\"inplace\",\"label\":\"bytes30\",\"numberOfBytes\":\"30\"},\"t_contract(CrossDomainMessenger)1008\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_contract(StandardBridge)1009\":{\"encoding\":\"inplace\",\"label\":\"contract StandardBridge\",\"numberOfBytes\":\"20\"},\"t_contract(SuperchainConfig)1010\":{\"encoding\":\"inplace\",\"label\":\"contract SuperchainConfig\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint256,t_bool)))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e mapping(uint256 =\u003e bool)))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_mapping(t_uint256,t_bool))\"},\"t_mapping(t_address,t_mapping(t_uint256,t_bool))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(uint256 =\u003e bool))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_uint256,t_bool)\"},\"t_mapping(t_uint256,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_bool\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var L1ERC721BridgeStorageLayout = new(solc.StorageLayout) -var L1ERC721BridgeDeployedBin = "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c80637f46ddb211610076578063aa5574521161005b578063aa55745214610213578063c4d66de814610226578063c89701a21461023957600080fd5b80637f46ddb2146101c8578063927ede2d146101ef57600080fd5b806354fd4d50116100a757806354fd4d50146101285780635d93a3fc14610171578063761f4493146101b557600080fd5b80633687011a146100c35780633cb747bf146100d8575b600080fd5b6100d66100d1366004610e47565b61025f565b005b6000546100fe9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101646040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b60405161011f9190610f35565b6101a561017f366004610f4f565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b604051901515815260200161011f565b6100d66101c3366004610f90565b61030b565b6100fe7f000000000000000000000000000000000000000000000000000000000000000081565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166100fe565b6100d6610221366004611028565b610776565b6100d661023436600461109f565b610832565b7f00000000000000000000000000000000000000000000000000000000000000006100fe565b333b156102f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b610303868633338888888861097c565b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314801561041357507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fb91906110bc565b73ffffffffffffffffffffffffffffffffffffffff16145b61049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f74686572206272696467650060648201526084016102ea565b3073ffffffffffffffffffffffffffffffffffffffff881603610544576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff161515600114610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c31204272696467650000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156106d357600080fd5b505af11580156106e7573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107659493929190611122565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f7420626520616464726573732830290000000000000000000000000000000060648201526084016102ea565b610829878733888888888861097c565b50505050505050565b600054600390610100900460ff16158015610854575060005460ff8083169116105b6108e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016102ea565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561091a82610cdc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b73ffffffffffffffffffffffffffffffffffffffff8716610a1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f74206265206164647265737328302900000000000000000000000000000060648201526084016102ea565b600063761f449360e01b888a8989898888604051602401610a469796959493929190611162565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610b8657600080fd5b505af1158015610b9a573d6000803e3d6000fd5b50506000546040517f3dbb202b0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169250633dbb202b9150610c1d907f000000000000000000000000000000000000000000000000000000000000000090859089906004016111bf565b600060405180830381600087803b158015610c3757600080fd5b505af1158015610c4b573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610cc99493929190611122565b60405180910390a4505050505050505050565b600054610100900460ff16610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ea565b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610de257600080fd5b50565b803563ffffffff81168114610df957600080fd5b919050565b60008083601f840112610e1057600080fd5b50813567ffffffffffffffff811115610e2857600080fd5b602083019150836020828501011115610e4057600080fd5b9250929050565b60008060008060008060a08789031215610e6057600080fd5b8635610e6b81610dc0565b95506020870135610e7b81610dc0565b945060408701359350610e9060608801610de5565b9250608087013567ffffffffffffffff811115610eac57600080fd5b610eb889828a01610dfe565b979a9699509497509295939492505050565b6000815180845260005b81811015610ef057602081850181015186830182015201610ed4565b81811115610f02576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f486020830184610eca565b9392505050565b600080600060608486031215610f6457600080fd5b8335610f6f81610dc0565b92506020840135610f7f81610dc0565b929592945050506040919091013590565b600080600080600080600060c0888a031215610fab57600080fd5b8735610fb681610dc0565b96506020880135610fc681610dc0565b95506040880135610fd681610dc0565b94506060880135610fe681610dc0565b93506080880135925060a088013567ffffffffffffffff81111561100957600080fd5b6110158a828b01610dfe565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561104357600080fd5b873561104e81610dc0565b9650602088013561105e81610dc0565b9550604088013561106e81610dc0565b94506060880135935061108360808901610de5565b925060a088013567ffffffffffffffff81111561100957600080fd5b6000602082840312156110b157600080fd5b8135610f4881610dc0565b6000602082840312156110ce57600080fd5b8151610f4881610dc0565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006111586060830184866110d9565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a08301526111b260c0830184866110d9565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006111ee6060830185610eca565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a" +var L1ERC721BridgeDeployedBin = "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600581526020017f322e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L1ERC721BridgeStorageLayoutJSON), L1ERC721BridgeStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["L1ERC721Bridge"] = L1ERC721BridgeStorageLayout deployedBytecodes["L1ERC721Bridge"] = L1ERC721BridgeDeployedBin + immutableReferences["L1ERC721Bridge"] = false } diff --git a/op-bindings/bindings/l1feevault.go b/op-bindings/bindings/l1feevault.go index f23769918312..a2d470a1dd44 100644 --- a/op-bindings/bindings/l1feevault.go +++ b/op-bindings/bindings/l1feevault.go @@ -30,7 +30,7 @@ var ( // L1FeeVaultMetaData contains all meta data concerning the L1FeeVault contract. var L1FeeVaultMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minWithdrawalAmount\",\"type\":\"uint256\"},{\"internalType\":\"enumFeeVault.WithdrawalNetwork\",\"name\":\"_withdrawalNetwork\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFeeVault.WithdrawalNetwork\",\"name\":\"withdrawalNetwork\",\"type\":\"uint8\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_WITHDRAWAL_AMOUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RECIPIENT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WITHDRAWAL_NETWORK\",\"outputs\":[{\"internalType\":\"enumFeeVault.WithdrawalNetwork\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalProcessed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_minWithdrawalAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_withdrawalNetwork\",\"type\":\"uint8\",\"internalType\":\"enumFeeVault.WithdrawalNetwork\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"MIN_WITHDRAWAL_AMOUNT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RECIPIENT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"WITHDRAWAL_NETWORK\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumFeeVault.WithdrawalNetwork\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalProcessed\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Withdrawal\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdrawal\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalNetwork\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"enumFeeVault.WithdrawalNetwork\"}],\"anonymous\":false}]", Bin: "0x60e060405234801561001057600080fd5b506040516108d13803806108d183398101604081905261002f91610079565b6001600160a01b03831660a0526080829052828282806001811115610056576100566100cc565b60c081600181111561006a5761006a6100cc565b815250505050505050506100e2565b60008060006060848603121561008e57600080fd5b83516001600160a01b03811681146100a557600080fd5b602085015160408601519194509250600281106100c157600080fd5b809150509250925092565b634e487b7160e01b600052602160045260246000fd5b60805160a05160c051610790610141600039600081816101760152818161038901526103c40152600081816087015281816102d801528181610367015281816103fd01526105640152600081816101b701526101db01526107906000f3fe6080604052600436106100695760003560e01c806384411d651161004357806384411d6514610140578063d0e12f9014610164578063d3e5792b146101a557600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e86101d9565b005b3480156100f657600080fd5b506101336040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b6040516100ca9190610630565b34801561014c57600080fd5b5061015660005481565b6040519081526020016100ca565b34801561017057600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516100ca91906106b4565b3480156101b157600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000004710156102b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546102ca91906106c8565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f0000000000000000000000000000000000000000000000000000000000000000337f00000000000000000000000000000000000000000000000000000000000000006040516103b89493929190610707565b60405180910390a160017f000000000000000000000000000000000000000000000000000000000000000060018111156103f4576103f461064a565b0361050d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610473576040519150601f19603f3d011682016040523d82523d6000602084013e610478565b606091505b5050905080610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e740000000000000000000000000000000060648201526084016102ab565b5050565b604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610590917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610748565b6000604051808303818588803b1580156105a957600080fd5b505af11580156105bd573d6000803e3d6000fd5b505050505050565b6000815180845260005b818110156105eb576020818501810151868301820152016105cf565b818111156105fd576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061064360208301846105c5565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106106b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016106c28284610679565b92915050565b60008219821115610702577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff8481166020830152831660408201526080810161073f6060830184610679565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061073f60608301846105c556fea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/l1feevault_more.go b/op-bindings/bindings/l1feevault_more.go index 8f6fe05076ab..c3b8cb5126fd 100644 --- a/op-bindings/bindings/l1feevault_more.go +++ b/op-bindings/bindings/l1feevault_more.go @@ -15,6 +15,7 @@ var L1FeeVaultStorageLayout = new(solc.StorageLayout) var L1FeeVaultDeployedBin = "0x6080604052600436106100695760003560e01c806384411d651161004357806384411d6514610140578063d0e12f9014610164578063d3e5792b146101a557600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e86101d9565b005b3480156100f657600080fd5b506101336040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b6040516100ca9190610630565b34801561014c57600080fd5b5061015660005481565b6040519081526020016100ca565b34801561017057600080fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516100ca91906106b4565b3480156101b157600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000004710156102b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546102ca91906106c8565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f0000000000000000000000000000000000000000000000000000000000000000337f00000000000000000000000000000000000000000000000000000000000000006040516103b89493929190610707565b60405180910390a160017f000000000000000000000000000000000000000000000000000000000000000060018111156103f4576103f461064a565b0361050d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610473576040519150601f19603f3d011682016040523d82523d6000602084013e610478565b606091505b5050905080610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e740000000000000000000000000000000060648201526084016102ab565b5050565b604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610590917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610748565b6000604051808303818588803b1580156105a957600080fd5b505af11580156105bd573d6000803e3d6000fd5b505050505050565b6000815180845260005b818110156105eb576020818501810151868301820152016105cf565b818111156105fd576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061064360208301846105c5565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106106b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016106c28284610679565b92915050565b60008219821115610702577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff8481166020830152831660408201526080810161073f6060830184610679565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061073f60608301846105c556fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L1FeeVaultStorageLayoutJSON), L1FeeVaultStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["L1FeeVault"] = L1FeeVaultStorageLayout deployedBytecodes["L1FeeVault"] = L1FeeVaultDeployedBin + immutableReferences["L1FeeVault"] = true } diff --git a/op-bindings/bindings/l1standardbridge.go b/op-bindings/bindings/l1standardbridge.go index 203102557485..619df3f3bcb2 100644 --- a/op-bindings/bindings/l1standardbridge.go +++ b/op-bindings/bindings/l1standardbridge.go @@ -30,8 +30,8 @@ var ( // L1StandardBridgeMetaData contains all meta data concerning the L1StandardBridge contract. var L1StandardBridgeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20DepositInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHDepositInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHWithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeERC20Withdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeETHWithdrawal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"_messenger\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2TokenBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x60a06040523480156200001157600080fd5b507342000000000000000000000000000000000000106080526200003660006200003c565b620001bb565b600054600390610100900460ff161580156200005f575060005460ff8083169116105b620000c85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620000e7826200012c565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054610100900460ff16620001995760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000bf565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b608051612a44620001fa60003960008181610379015281816104300152818161057001528181610a22015281816113d80152611a8b0152612a446000f3fe6080604052600436106101635760003560e01c806387087623116100c0578063a9f9e67511610074578063c4d66de811610059578063c4d66de8146104c5578063c89701a214610421578063e11013dd146104e557600080fd5b8063a9f9e67514610492578063b1a1a882146104b257600080fd5b806391c49bf8116100a557806391c49bf814610421578063927ede2d146104545780639a2ac6d51461047f57600080fd5b806387087623146103bb5780638f601f66146103db57600080fd5b8063540abf731161011757806358a997f6116100fc57806358a997f6146103475780637f46ddb214610367578063838b25201461039b57600080fd5b8063540abf73146102d157806354fd4d50146102f157600080fd5b80631532ec34116101485780631532ec34146102545780631635f5fd146102675780633cb747bf1461027a57600080fd5b80630166a07a1461022157806309fc88431461024157600080fd5b3661021c57333b156101fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61021a333362030d40604051806020016040528060008152506104f8565b005b600080fd5b34801561022d57600080fd5b5061021a61023c36600461248b565b61050b565b61021a61024f36600461253c565b6108d2565b61021a61026236600461258f565b6109a9565b61021a61027536600461258f565b6109bd565b34801561028657600080fd5b506003546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102dd57600080fd5b5061021a6102ec366004612602565b610e33565b3480156102fd57600080fd5b5061033a6040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b6040516102c891906126ef565b34801561035357600080fd5b5061021a610362366004612702565b610e78565b34801561037357600080fd5b506102a77f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a757600080fd5b5061021a6103b6366004612602565b610f4c565b3480156103c757600080fd5b5061021a6103d6366004612702565b610f91565b3480156103e757600080fd5b506104136103f6366004612785565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102c8565b34801561042d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102a7565b34801561046057600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102a7565b61021a61048d3660046127be565b611065565b34801561049e57600080fd5b5061021a6104ad36600461248b565b6110a7565b61021a6104c036600461253c565b6110b6565b3480156104d157600080fd5b5061021a6104e0366004612821565b611187565b61021a6104f33660046127be565b6112d1565b6105058484348585611314565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff16331480156105fa5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e2919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b6106ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b6106b5876114fa565b15610803576106c4878761155c565b610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107e657600080fd5b505af11580156107fa573d6000803e3d6000fd5b50505050610885565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461084190849061288a565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561088590858561167c565b6108c9878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175092505050565b50505050505050565b333b15610961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b505050565b6109b685858585856109bd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610aac5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b823414610bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101f3565b3073ffffffffffffffffffffffffffffffffffffffff851603610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101f3565b610d7f85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117de92505050565b6000610d9c855a8660405180602001604052806000815250611851565b905080610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b505050505050565b6108c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b333b15610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b6108c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b333b15611020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b61050533858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b6108c98787878787878761050b565b333b15611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b600054600390610100900460ff161580156111a9575060005460ff8083169116105b611235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101f3565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561126f82611bc2565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6105053385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b8234146113a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101f3565b6113af85858584611ca0565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b9085907f0000000000000000000000000000000000000000000000000000000000000000907f1635f5fd000000000000000000000000000000000000000000000000000000009061142e908b908b9086908a906024016128a1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526114c1929188906004016128ea565b6000604051808303818588803b1580156114da57600080fd5b505af11580156114ee573d6000803e3d6000fd5b50505050505050505050565b6000611526827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b806115565750611556827fec4fc8e300000000000000000000000000000000000000000000000000000000611d13565b92915050565b6000611588837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b15611631578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fc919061283e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611556565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109a49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611d36565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516117c89392919061292f565b60405180910390a4610e2b868686868686611e42565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631848460405161183d92919061296d565b60405180910390a361050584848484611eca565b600080600080845160208601878a8af19695505050505050565b611874876114fa565b156119c257611883878761155c565b611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b50505050611a56565b6119e473ffffffffffffffffffffffffffffffffffffffff8816863086611f37565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611a22908490612986565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611a64878787878786611f95565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b907f0000000000000000000000000000000000000000000000000000000000000000907f0166a07a0000000000000000000000000000000000000000000000000000000090611ae5908b908d908c908c908c908b9060240161299e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611b78929187906004016128ea565b600060405180830381600087803b158015611b9257600080fd5b505af1158015611ba6573d6000803e3d6000fd5b5050505050505050505050565b6108c98787878787878761186b565b600054610100900460ff16611c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101f3565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611cff92919061296d565b60405180910390a361050584848484612023565b6000611d1e83612082565b8015611d2f5750611d2f83836120e6565b9392505050565b6000611d98826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b59092919063ffffffff16565b8051909150156109a45780806020019051810190611db691906129f9565b6109a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101f3565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611eba9392919061292f565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f2992919061296d565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105059085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116ce565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161200d9392919061292f565b60405180910390a4610e2b8686868686866121cc565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f2992919061296d565b60006120ae827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e6565b801561155657506120df827fffffffff000000000000000000000000000000000000000000000000000000006120e6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219e575060208210155b80156121aa5750600081115b979650505050505050565b60606121c48484600085612244565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611eba9392919061292f565b6060824710156122d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101f3565b73ffffffffffffffffffffffffffffffffffffffff85163b612354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161237d9190612a1b565b60006040518083038185875af1925050503d80600081146123ba576040519150601f19603f3d011682016040523d82523d6000602084013e6123bf565b606091505b50915091506121aa828286606083156123d9575081611d2f565b8251156123e95782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f391906126ef565b73ffffffffffffffffffffffffffffffffffffffff8116811461243f57600080fd5b50565b60008083601f84011261245457600080fd5b50813567ffffffffffffffff81111561246c57600080fd5b60208301915083602082850101111561248457600080fd5b9250929050565b600080600080600080600060c0888a0312156124a657600080fd5b87356124b18161241d565b965060208801356124c18161241d565b955060408801356124d18161241d565b945060608801356124e18161241d565b93506080880135925060a088013567ffffffffffffffff81111561250457600080fd5b6125108a828b01612442565b989b979a50959850939692959293505050565b803563ffffffff8116811461253757600080fd5b919050565b60008060006040848603121561255157600080fd5b61255a84612523565b9250602084013567ffffffffffffffff81111561257657600080fd5b61258286828701612442565b9497909650939450505050565b6000806000806000608086880312156125a757600080fd5b85356125b28161241d565b945060208601356125c28161241d565b935060408601359250606086013567ffffffffffffffff8111156125e557600080fd5b6125f188828901612442565b969995985093965092949392505050565b600080600080600080600060c0888a03121561261d57600080fd5b87356126288161241d565b965060208801356126388161241d565b955060408801356126488161241d565b94506060880135935061265d60808901612523565b925060a088013567ffffffffffffffff81111561250457600080fd5b60005b8381101561269457818101518382015260200161267c565b838111156105055750506000910152565b600081518084526126bd816020860160208601612679565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d2f60208301846126a5565b60008060008060008060a0878903121561271b57600080fd5b86356127268161241d565b955060208701356127368161241d565b94506040870135935061274b60608801612523565b9250608087013567ffffffffffffffff81111561276757600080fd5b61277389828a01612442565b979a9699509497509295939492505050565b6000806040838503121561279857600080fd5b82356127a38161241d565b915060208301356127b38161241d565b809150509250929050565b600080600080606085870312156127d457600080fd5b84356127df8161241d565b93506127ed60208601612523565b9250604085013567ffffffffffffffff81111561280957600080fd5b61281587828801612442565b95989497509550505050565b60006020828403121561283357600080fd5b8135611d2f8161241d565b60006020828403121561285057600080fd5b8151611d2f8161241d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561289c5761289c61285b565b500390565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128e060808301846126a5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061291960608301856126a5565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296460608301846126a5565b95945050505050565b8281526040602082015260006121c460408301846126a5565b600082198211156129995761299961285b565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526129ed60c08301846126a5565b98975050505050505050565b600060208284031215612a0b57600080fd5b81518015158114611d2f57600080fd5b60008251612a2d818460208701612679565b919091019291505056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"bridgeERC20\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bridgeERC20To\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bridgeETH\",\"inputs\":[{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"bridgeETHTo\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"depositERC20\",\"inputs\":[{\"name\":\"_l1Token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_l2Token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"depositERC20To\",\"inputs\":[{\"name\":\"_l1Token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_l2Token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"depositETH\",\"inputs\":[{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"depositETHTo\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"deposits\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"finalizeBridgeERC20\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"finalizeBridgeETH\",\"inputs\":[{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"finalizeERC20Withdrawal\",\"inputs\":[{\"name\":\"_l1Token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_l2Token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"finalizeETHWithdrawal\",\"inputs\":[{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_messenger\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"},{\"name\":\"_superchainConfig\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l2TokenBridge\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"messenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"otherBridge\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"superchainConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ERC20BridgeFinalized\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ERC20BridgeInitiated\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ERC20DepositInitiated\",\"inputs\":[{\"name\":\"l1Token\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"l2Token\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ERC20WithdrawalFinalized\",\"inputs\":[{\"name\":\"l1Token\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"l2Token\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ETHBridgeFinalized\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ETHBridgeInitiated\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ETHDepositInitiated\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ETHWithdrawalFinalized\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b506200001f60008062000025565b62000234565b600054610100900460ff1615808015620000465750600054600160ff909116105b8062000076575062000063306200018a60201b620005511760201c565b15801562000076575060005460ff166001145b620000df5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000103576000805461ff0019166101001790555b603280546001600160a01b0319166001600160a01b0384161790556200013e8373420000000000000000000000000000000000001062000199565b801562000185576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002065760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d6565b600380546001600160a01b039384166001600160a01b03199182161790915560048054929093169116179055565b612c4d80620002446000396000f3fe6080604052600436106101795760003560e01c80637f46ddb2116100cb578063927ede2d1161007f578063b1a1a88211610059578063b1a1a882146104fe578063c89701a214610511578063e11013dd1461053e57600080fd5b8063927ede2d146104a05780639a2ac6d5146104cb578063a9f9e675146104de57600080fd5b806387087623116100b0578063870876231461043a5780638f601f661461045a57806391c49bf8146103ef57600080fd5b80637f46ddb2146103ef578063838b25201461041a57600080fd5b80633cb747bf1161012d57806354fd4d501161010757806354fd4d501461035457806358a997f6146103aa5780635c975abb146103ca57600080fd5b80633cb747bf146102e7578063485cc95514610314578063540abf731461033457600080fd5b80631532ec341161015e5780631532ec341461026a5780631635f5fd1461027d57806335e80ab31461029057600080fd5b80630166a07a1461023757806309fc88431461025757600080fd5b3661023257333b15610212576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b610230333362030d406040518060200160405280600081525061056d565b005b600080fd5b34801561024357600080fd5b506102306102523660046126b1565b610580565b610230610265366004612762565b61099a565b6102306102783660046127b5565b610a71565b61023061028b3660046127b5565b610a85565b34801561029c57600080fd5b506032546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102f357600080fd5b506003546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032057600080fd5b5061023061032f366004612828565b610f4e565b34801561034057600080fd5b5061023061034f366004612861565b611137565b34801561036057600080fd5b5061039d6040518060400160405280600581526020017f322e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516102de919061294e565b3480156103b657600080fd5b506102306103c5366004612961565b61117c565b3480156103d657600080fd5b506103df611250565b60405190151581526020016102de565b3480156103fb57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102bd565b34801561042657600080fd5b50610230610435366004612861565b6112e9565b34801561044657600080fd5b50610230610455366004612961565b61132e565b34801561046657600080fd5b50610492610475366004612828565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102de565b3480156104ac57600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102bd565b6102306104d93660046129e4565b611402565b3480156104ea57600080fd5b506102306104f93660046126b1565b611444565b61023061050c366004612762565b611453565b34801561051d57600080fd5b506004546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b61023061054c3660046129e4565b611524565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61057a8484348585611567565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610653575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610617573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063b9190612a47565b73ffffffffffffffffffffffffffffffffffffffff16145b610705576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610209565b61070d611250565b15610774576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610209565b61077d87611731565b156108cb5761078c8787611793565b61083e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610209565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108ae57600080fd5b505af11580156108c2573d6000803e3d6000fd5b5050505061094d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610909908490612a93565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561094d9085856118b3565b610991878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061198792505050565b50505050505050565b333b15610a29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610a6c3333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061156792505050565b505050565b610a7e8585858585610a85565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b58575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b409190612a47565b73ffffffffffffffffffffffffffffffffffffffff16145b610c0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610209565b610c12611250565b15610c79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610209565b823414610d08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610209565b3073ffffffffffffffffffffffffffffffffffffffff851603610dad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610209565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610e58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610209565b610e9a85858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a1592505050565b6000610eb7855a8660405180602001604052806000815250611a88565b905080610f46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610209565b505050505050565b600054610100900460ff1615808015610f6e5750600054600160ff909116105b80610f885750303b158015610f88575060005460ff166001145b611014576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610209565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561107257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556110d083734200000000000000000000000000000000000010611aa2565b8015610a6c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b61099187873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b8c92505050565b333b1561120b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610f4686863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611eb792505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e49190612aaa565b905090565b61099187873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611eb792505050565b333b156113bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610f4686863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b8c92505050565b61057a33858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061056d92505050565b61099187878787878787610580565b333b156114e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610a6c33338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061056d92505050565b61057a3385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061156792505050565b8234146115f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610209565b61160285858584611ec6565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd0000000000000000000000000000000000000000000000000000000090611665908b908b9086908a90602401612acc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526116f892918890600401612b15565b6000604051808303818588803b15801561171157600080fd5b505af1158015611725573d6000803e3d6000fd5b50505050505050505050565b600061175d827f1d1d8b6300000000000000000000000000000000000000000000000000000000611f39565b8061178d575061178d827fec4fc8e300000000000000000000000000000000000000000000000000000000611f39565b92915050565b60006117bf837f1d1d8b6300000000000000000000000000000000000000000000000000000000611f39565b15611868578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561180f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118339190612a47565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905061178d565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561180f573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a6c9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611f5c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516119ff93929190612b5a565b60405180910390a4610f46868686868686612068565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611a74929190612b98565b60405180910390a361057a848484846120f0565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16611b39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610209565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b611b9587611731565b15611ce357611ba48787611793565b611c56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610209565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611cc657600080fd5b505af1158015611cda573d6000803e3d6000fd5b50505050611d77565b611d0573ffffffffffffffffffffffffffffffffffffffff881686308661215d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611d43908490612bb1565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611d858787878787866121bb565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611de9908b908d908c908c908c908b90602401612bc9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611e7c92918790600401612b15565b600060405180830381600087803b158015611e9657600080fd5b505af1158015611eaa573d6000803e3d6000fd5b5050505050505050505050565b61099187878787878787611b8c565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611f25929190612b98565b60405180910390a361057a84848484612249565b6000611f44836122a8565b8015611f555750611f55838361230c565b9392505050565b6000611fbe826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123db9092919063ffffffff16565b805190915015610a6c5780806020019051810190611fdc9190612aaa565b610a6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610209565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd8686866040516120e093929190612b5a565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161214f929190612b98565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261057a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611905565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161223393929190612b5a565b60405180910390a4610f468686868686866123f2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161214f929190612b98565b60006122d4827f01ffc9a70000000000000000000000000000000000000000000000000000000061230c565b801561178d5750612305827fffffffff0000000000000000000000000000000000000000000000000000000061230c565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156123c4575060208210155b80156123d05750600081115b979650505050505050565b60606123ea848460008561246a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf8686866040516120e093929190612b5a565b6060824710156124fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610209565b73ffffffffffffffffffffffffffffffffffffffff85163b61257a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610209565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125a39190612c24565b60006040518083038185875af1925050503d80600081146125e0576040519150601f19603f3d011682016040523d82523d6000602084013e6125e5565b606091505b50915091506123d0828286606083156125ff575081611f55565b82511561260f5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610209919061294e565b73ffffffffffffffffffffffffffffffffffffffff8116811461266557600080fd5b50565b60008083601f84011261267a57600080fd5b50813567ffffffffffffffff81111561269257600080fd5b6020830191508360208285010111156126aa57600080fd5b9250929050565b600080600080600080600060c0888a0312156126cc57600080fd5b87356126d781612643565b965060208801356126e781612643565b955060408801356126f781612643565b9450606088013561270781612643565b93506080880135925060a088013567ffffffffffffffff81111561272a57600080fd5b6127368a828b01612668565b989b979a50959850939692959293505050565b803563ffffffff8116811461275d57600080fd5b919050565b60008060006040848603121561277757600080fd5b61278084612749565b9250602084013567ffffffffffffffff81111561279c57600080fd5b6127a886828701612668565b9497909650939450505050565b6000806000806000608086880312156127cd57600080fd5b85356127d881612643565b945060208601356127e881612643565b935060408601359250606086013567ffffffffffffffff81111561280b57600080fd5b61281788828901612668565b969995985093965092949392505050565b6000806040838503121561283b57600080fd5b823561284681612643565b9150602083013561285681612643565b809150509250929050565b600080600080600080600060c0888a03121561287c57600080fd5b873561288781612643565b9650602088013561289781612643565b955060408801356128a781612643565b9450606088013593506128bc60808901612749565b925060a088013567ffffffffffffffff81111561272a57600080fd5b60005b838110156128f35781810151838201526020016128db565b8381111561057a5750506000910152565b6000815180845261291c8160208601602086016128d8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f556020830184612904565b60008060008060008060a0878903121561297a57600080fd5b863561298581612643565b9550602087013561299581612643565b9450604087013593506129aa60608801612749565b9250608087013567ffffffffffffffff8111156129c657600080fd5b6129d289828a01612668565b979a9699509497509295939492505050565b600080600080606085870312156129fa57600080fd5b8435612a0581612643565b9350612a1360208601612749565b9250604085013567ffffffffffffffff811115612a2f57600080fd5b612a3b87828801612668565b95989497509550505050565b600060208284031215612a5957600080fd5b8151611f5581612643565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612aa557612aa5612a64565b500390565b600060208284031215612abc57600080fd5b81518015158114611f5557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612b0b6080830184612904565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612b446060830185612904565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612b8f6060830184612904565b95945050505050565b8281526040602082015260006123ea6040830184612904565b60008219821115612bc457612bc4612a64565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612c1860c0830184612904565b98975050505050505050565b60008251612c368184602087016128d8565b919091019291505056fea164736f6c634300080f000a", } // L1StandardBridgeABI is the input ABI used to generate the binding from. @@ -387,6 +387,68 @@ func (_L1StandardBridge *L1StandardBridgeCallerSession) OtherBridge() (common.Ad return _L1StandardBridge.Contract.OtherBridge(&_L1StandardBridge.CallOpts) } +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1StandardBridge *L1StandardBridgeCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _L1StandardBridge.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1StandardBridge *L1StandardBridgeSession) Paused() (bool, error) { + return _L1StandardBridge.Contract.Paused(&_L1StandardBridge.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1StandardBridge *L1StandardBridgeCallerSession) Paused() (bool, error) { + return _L1StandardBridge.Contract.Paused(&_L1StandardBridge.CallOpts) +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_L1StandardBridge *L1StandardBridgeCaller) SuperchainConfig(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L1StandardBridge.contract.Call(opts, &out, "superchainConfig") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_L1StandardBridge *L1StandardBridgeSession) SuperchainConfig() (common.Address, error) { + return _L1StandardBridge.Contract.SuperchainConfig(&_L1StandardBridge.CallOpts) +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_L1StandardBridge *L1StandardBridgeCallerSession) SuperchainConfig() (common.Address, error) { + return _L1StandardBridge.Contract.SuperchainConfig(&_L1StandardBridge.CallOpts) +} + // Version is a free data retrieval call binding the contract method 0x54fd4d50. // // Solidity: function version() view returns(string) @@ -670,25 +732,25 @@ func (_L1StandardBridge *L1StandardBridgeTransactorSession) FinalizeETHWithdrawa return _L1StandardBridge.Contract.FinalizeETHWithdrawal(&_L1StandardBridge.TransactOpts, _from, _to, _amount, _extraData) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. // -// Solidity: function initialize(address _messenger) returns() -func (_L1StandardBridge *L1StandardBridgeTransactor) Initialize(opts *bind.TransactOpts, _messenger common.Address) (*types.Transaction, error) { - return _L1StandardBridge.contract.Transact(opts, "initialize", _messenger) +// Solidity: function initialize(address _messenger, address _superchainConfig) returns() +func (_L1StandardBridge *L1StandardBridgeTransactor) Initialize(opts *bind.TransactOpts, _messenger common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _L1StandardBridge.contract.Transact(opts, "initialize", _messenger, _superchainConfig) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. // -// Solidity: function initialize(address _messenger) returns() -func (_L1StandardBridge *L1StandardBridgeSession) Initialize(_messenger common.Address) (*types.Transaction, error) { - return _L1StandardBridge.Contract.Initialize(&_L1StandardBridge.TransactOpts, _messenger) +// Solidity: function initialize(address _messenger, address _superchainConfig) returns() +func (_L1StandardBridge *L1StandardBridgeSession) Initialize(_messenger common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _L1StandardBridge.Contract.Initialize(&_L1StandardBridge.TransactOpts, _messenger, _superchainConfig) } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// Initialize is a paid mutator transaction binding the contract method 0x485cc955. // -// Solidity: function initialize(address _messenger) returns() -func (_L1StandardBridge *L1StandardBridgeTransactorSession) Initialize(_messenger common.Address) (*types.Transaction, error) { - return _L1StandardBridge.Contract.Initialize(&_L1StandardBridge.TransactOpts, _messenger) +// Solidity: function initialize(address _messenger, address _superchainConfig) returns() +func (_L1StandardBridge *L1StandardBridgeTransactorSession) Initialize(_messenger common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _L1StandardBridge.Contract.Initialize(&_L1StandardBridge.TransactOpts, _messenger, _superchainConfig) } // Receive is a paid mutator transaction binding the contract receive function. diff --git a/op-bindings/bindings/l1standardbridge_more.go b/op-bindings/bindings/l1standardbridge_more.go index 8d2d77be4957..53217f6bf028 100644 --- a/op-bindings/bindings/l1standardbridge_more.go +++ b/op-bindings/bindings/l1standardbridge_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const L1StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"spacer_0_2_20\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1003,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1005,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"messenger\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_contract(CrossDomainMessenger)1007\"},{\"astId\":1006,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_array(t_uint256)46_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)46_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[46]\",\"numberOfBytes\":\"1472\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(CrossDomainMessenger)1007\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const L1StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"spacer_0_2_30\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_bytes30\"},{\"astId\":1003,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1005,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"messenger\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_contract(CrossDomainMessenger)1009\"},{\"astId\":1006,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"otherBridge\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_contract(StandardBridge)1010\"},{\"astId\":1007,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_array(t_uint256)45_storage\"},{\"astId\":1008,\"contract\":\"src/L1/L1StandardBridge.sol:L1StandardBridge\",\"label\":\"superchainConfig\",\"offset\":0,\"slot\":\"50\",\"type\":\"t_contract(SuperchainConfig)1011\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)45_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[45]\",\"numberOfBytes\":\"1440\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes30\":{\"encoding\":\"inplace\",\"label\":\"bytes30\",\"numberOfBytes\":\"30\"},\"t_contract(CrossDomainMessenger)1009\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_contract(StandardBridge)1010\":{\"encoding\":\"inplace\",\"label\":\"contract StandardBridge\",\"numberOfBytes\":\"20\"},\"t_contract(SuperchainConfig)1011\":{\"encoding\":\"inplace\",\"label\":\"contract SuperchainConfig\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var L1StandardBridgeStorageLayout = new(solc.StorageLayout) -var L1StandardBridgeDeployedBin = "0x6080604052600436106101635760003560e01c806387087623116100c0578063a9f9e67511610074578063c4d66de811610059578063c4d66de8146104c5578063c89701a214610421578063e11013dd146104e557600080fd5b8063a9f9e67514610492578063b1a1a882146104b257600080fd5b806391c49bf8116100a557806391c49bf814610421578063927ede2d146104545780639a2ac6d51461047f57600080fd5b806387087623146103bb5780638f601f66146103db57600080fd5b8063540abf731161011757806358a997f6116100fc57806358a997f6146103475780637f46ddb214610367578063838b25201461039b57600080fd5b8063540abf73146102d157806354fd4d50146102f157600080fd5b80631532ec34116101485780631532ec34146102545780631635f5fd146102675780633cb747bf1461027a57600080fd5b80630166a07a1461022157806309fc88431461024157600080fd5b3661021c57333b156101fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61021a333362030d40604051806020016040528060008152506104f8565b005b600080fd5b34801561022d57600080fd5b5061021a61023c36600461248b565b61050b565b61021a61024f36600461253c565b6108d2565b61021a61026236600461258f565b6109a9565b61021a61027536600461258f565b6109bd565b34801561028657600080fd5b506003546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102dd57600080fd5b5061021a6102ec366004612602565b610e33565b3480156102fd57600080fd5b5061033a6040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b6040516102c891906126ef565b34801561035357600080fd5b5061021a610362366004612702565b610e78565b34801561037357600080fd5b506102a77f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a757600080fd5b5061021a6103b6366004612602565b610f4c565b3480156103c757600080fd5b5061021a6103d6366004612702565b610f91565b3480156103e757600080fd5b506104136103f6366004612785565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102c8565b34801561042d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102a7565b34801561046057600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102a7565b61021a61048d3660046127be565b611065565b34801561049e57600080fd5b5061021a6104ad36600461248b565b6110a7565b61021a6104c036600461253c565b6110b6565b3480156104d157600080fd5b5061021a6104e0366004612821565b611187565b61021a6104f33660046127be565b6112d1565b6105058484348585611314565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff16331480156105fa5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e2919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b6106ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b6106b5876114fa565b15610803576106c4878761155c565b610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107e657600080fd5b505af11580156107fa573d6000803e3d6000fd5b50505050610885565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461084190849061288a565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561088590858561167c565b6108c9878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175092505050565b50505050505050565b333b15610961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b505050565b6109b685858585856109bd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610aac5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b823414610bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101f3565b3073ffffffffffffffffffffffffffffffffffffffff851603610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101f3565b610d7f85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117de92505050565b6000610d9c855a8660405180602001604052806000815250611851565b905080610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b505050505050565b6108c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b333b15610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b6108c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b333b15611020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b61050533858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b6108c98787878787878761050b565b333b15611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b600054600390610100900460ff161580156111a9575060005460ff8083169116105b611235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101f3565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561126f82611bc2565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6105053385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b8234146113a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101f3565b6113af85858584611ca0565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b9085907f0000000000000000000000000000000000000000000000000000000000000000907f1635f5fd000000000000000000000000000000000000000000000000000000009061142e908b908b9086908a906024016128a1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526114c1929188906004016128ea565b6000604051808303818588803b1580156114da57600080fd5b505af11580156114ee573d6000803e3d6000fd5b50505050505050505050565b6000611526827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b806115565750611556827fec4fc8e300000000000000000000000000000000000000000000000000000000611d13565b92915050565b6000611588837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b15611631578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fc919061283e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611556565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109a49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611d36565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516117c89392919061292f565b60405180910390a4610e2b868686868686611e42565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631848460405161183d92919061296d565b60405180910390a361050584848484611eca565b600080600080845160208601878a8af19695505050505050565b611874876114fa565b156119c257611883878761155c565b611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b50505050611a56565b6119e473ffffffffffffffffffffffffffffffffffffffff8816863086611f37565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611a22908490612986565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611a64878787878786611f95565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b907f0000000000000000000000000000000000000000000000000000000000000000907f0166a07a0000000000000000000000000000000000000000000000000000000090611ae5908b908d908c908c908c908b9060240161299e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611b78929187906004016128ea565b600060405180830381600087803b158015611b9257600080fd5b505af1158015611ba6573d6000803e3d6000fd5b5050505050505050505050565b6108c98787878787878761186b565b600054610100900460ff16611c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101f3565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611cff92919061296d565b60405180910390a361050584848484612023565b6000611d1e83612082565b8015611d2f5750611d2f83836120e6565b9392505050565b6000611d98826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b59092919063ffffffff16565b8051909150156109a45780806020019051810190611db691906129f9565b6109a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101f3565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611eba9392919061292f565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f2992919061296d565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105059085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116ce565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161200d9392919061292f565b60405180910390a4610e2b8686868686866121cc565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f2992919061296d565b60006120ae827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e6565b801561155657506120df827fffffffff000000000000000000000000000000000000000000000000000000006120e6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219e575060208210155b80156121aa5750600081115b979650505050505050565b60606121c48484600085612244565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611eba9392919061292f565b6060824710156122d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101f3565b73ffffffffffffffffffffffffffffffffffffffff85163b612354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161237d9190612a1b565b60006040518083038185875af1925050503d80600081146123ba576040519150601f19603f3d011682016040523d82523d6000602084013e6123bf565b606091505b50915091506121aa828286606083156123d9575081611d2f565b8251156123e95782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f391906126ef565b73ffffffffffffffffffffffffffffffffffffffff8116811461243f57600080fd5b50565b60008083601f84011261245457600080fd5b50813567ffffffffffffffff81111561246c57600080fd5b60208301915083602082850101111561248457600080fd5b9250929050565b600080600080600080600060c0888a0312156124a657600080fd5b87356124b18161241d565b965060208801356124c18161241d565b955060408801356124d18161241d565b945060608801356124e18161241d565b93506080880135925060a088013567ffffffffffffffff81111561250457600080fd5b6125108a828b01612442565b989b979a50959850939692959293505050565b803563ffffffff8116811461253757600080fd5b919050565b60008060006040848603121561255157600080fd5b61255a84612523565b9250602084013567ffffffffffffffff81111561257657600080fd5b61258286828701612442565b9497909650939450505050565b6000806000806000608086880312156125a757600080fd5b85356125b28161241d565b945060208601356125c28161241d565b935060408601359250606086013567ffffffffffffffff8111156125e557600080fd5b6125f188828901612442565b969995985093965092949392505050565b600080600080600080600060c0888a03121561261d57600080fd5b87356126288161241d565b965060208801356126388161241d565b955060408801356126488161241d565b94506060880135935061265d60808901612523565b925060a088013567ffffffffffffffff81111561250457600080fd5b60005b8381101561269457818101518382015260200161267c565b838111156105055750506000910152565b600081518084526126bd816020860160208601612679565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d2f60208301846126a5565b60008060008060008060a0878903121561271b57600080fd5b86356127268161241d565b955060208701356127368161241d565b94506040870135935061274b60608801612523565b9250608087013567ffffffffffffffff81111561276757600080fd5b61277389828a01612442565b979a9699509497509295939492505050565b6000806040838503121561279857600080fd5b82356127a38161241d565b915060208301356127b38161241d565b809150509250929050565b600080600080606085870312156127d457600080fd5b84356127df8161241d565b93506127ed60208601612523565b9250604085013567ffffffffffffffff81111561280957600080fd5b61281587828801612442565b95989497509550505050565b60006020828403121561283357600080fd5b8135611d2f8161241d565b60006020828403121561285057600080fd5b8151611d2f8161241d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561289c5761289c61285b565b500390565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128e060808301846126a5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061291960608301856126a5565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296460608301846126a5565b95945050505050565b8281526040602082015260006121c460408301846126a5565b600082198211156129995761299961285b565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526129ed60c08301846126a5565b98975050505050505050565b600060208284031215612a0b57600080fd5b81518015158114611d2f57600080fd5b60008251612a2d818460208701612679565b919091019291505056fea164736f6c634300080f000a" +var L1StandardBridgeDeployedBin = "0x6080604052600436106101795760003560e01c80637f46ddb2116100cb578063927ede2d1161007f578063b1a1a88211610059578063b1a1a882146104fe578063c89701a214610511578063e11013dd1461053e57600080fd5b8063927ede2d146104a05780639a2ac6d5146104cb578063a9f9e675146104de57600080fd5b806387087623116100b0578063870876231461043a5780638f601f661461045a57806391c49bf8146103ef57600080fd5b80637f46ddb2146103ef578063838b25201461041a57600080fd5b80633cb747bf1161012d57806354fd4d501161010757806354fd4d501461035457806358a997f6146103aa5780635c975abb146103ca57600080fd5b80633cb747bf146102e7578063485cc95514610314578063540abf731461033457600080fd5b80631532ec341161015e5780631532ec341461026a5780631635f5fd1461027d57806335e80ab31461029057600080fd5b80630166a07a1461023757806309fc88431461025757600080fd5b3661023257333b15610212576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b610230333362030d406040518060200160405280600081525061056d565b005b600080fd5b34801561024357600080fd5b506102306102523660046126b1565b610580565b610230610265366004612762565b61099a565b6102306102783660046127b5565b610a71565b61023061028b3660046127b5565b610a85565b34801561029c57600080fd5b506032546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102f357600080fd5b506003546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032057600080fd5b5061023061032f366004612828565b610f4e565b34801561034057600080fd5b5061023061034f366004612861565b611137565b34801561036057600080fd5b5061039d6040518060400160405280600581526020017f322e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516102de919061294e565b3480156103b657600080fd5b506102306103c5366004612961565b61117c565b3480156103d657600080fd5b506103df611250565b60405190151581526020016102de565b3480156103fb57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102bd565b34801561042657600080fd5b50610230610435366004612861565b6112e9565b34801561044657600080fd5b50610230610455366004612961565b61132e565b34801561046657600080fd5b50610492610475366004612828565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102de565b3480156104ac57600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102bd565b6102306104d93660046129e4565b611402565b3480156104ea57600080fd5b506102306104f93660046126b1565b611444565b61023061050c366004612762565b611453565b34801561051d57600080fd5b506004546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b61023061054c3660046129e4565b611524565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61057a8484348585611567565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610653575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610617573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063b9190612a47565b73ffffffffffffffffffffffffffffffffffffffff16145b610705576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610209565b61070d611250565b15610774576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610209565b61077d87611731565b156108cb5761078c8787611793565b61083e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610209565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108ae57600080fd5b505af11580156108c2573d6000803e3d6000fd5b5050505061094d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610909908490612a93565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561094d9085856118b3565b610991878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061198792505050565b50505050505050565b333b15610a29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610a6c3333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061156792505050565b505050565b610a7e8585858585610a85565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b58575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b409190612a47565b73ffffffffffffffffffffffffffffffffffffffff16145b610c0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610209565b610c12611250565b15610c79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610209565b823414610d08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610209565b3073ffffffffffffffffffffffffffffffffffffffff851603610dad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610209565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610e58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610209565b610e9a85858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a1592505050565b6000610eb7855a8660405180602001604052806000815250611a88565b905080610f46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610209565b505050505050565b600054610100900460ff1615808015610f6e5750600054600160ff909116105b80610f885750303b158015610f88575060005460ff166001145b611014576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610209565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561107257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556110d083734200000000000000000000000000000000000010611aa2565b8015610a6c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b61099187873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b8c92505050565b333b1561120b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610f4686863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611eb792505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e49190612aaa565b905090565b61099187873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611eb792505050565b333b156113bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610f4686863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b8c92505050565b61057a33858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061056d92505050565b61099187878787878787610580565b333b156114e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610a6c33338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061056d92505050565b61057a3385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061156792505050565b8234146115f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610209565b61160285858584611ec6565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd0000000000000000000000000000000000000000000000000000000090611665908b908b9086908a90602401612acc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526116f892918890600401612b15565b6000604051808303818588803b15801561171157600080fd5b505af1158015611725573d6000803e3d6000fd5b50505050505050505050565b600061175d827f1d1d8b6300000000000000000000000000000000000000000000000000000000611f39565b8061178d575061178d827fec4fc8e300000000000000000000000000000000000000000000000000000000611f39565b92915050565b60006117bf837f1d1d8b6300000000000000000000000000000000000000000000000000000000611f39565b15611868578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561180f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118339190612a47565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905061178d565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561180f573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a6c9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611f5c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516119ff93929190612b5a565b60405180910390a4610f46868686868686612068565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611a74929190612b98565b60405180910390a361057a848484846120f0565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16611b39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610209565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b611b9587611731565b15611ce357611ba48787611793565b611c56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610209565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611cc657600080fd5b505af1158015611cda573d6000803e3d6000fd5b50505050611d77565b611d0573ffffffffffffffffffffffffffffffffffffffff881686308661215d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611d43908490612bb1565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611d858787878787866121bb565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611de9908b908d908c908c908c908b90602401612bc9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611e7c92918790600401612b15565b600060405180830381600087803b158015611e9657600080fd5b505af1158015611eaa573d6000803e3d6000fd5b5050505050505050505050565b61099187878787878787611b8c565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611f25929190612b98565b60405180910390a361057a84848484612249565b6000611f44836122a8565b8015611f555750611f55838361230c565b9392505050565b6000611fbe826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123db9092919063ffffffff16565b805190915015610a6c5780806020019051810190611fdc9190612aaa565b610a6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610209565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd8686866040516120e093929190612b5a565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161214f929190612b98565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261057a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611905565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161223393929190612b5a565b60405180910390a4610f468686868686866123f2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161214f929190612b98565b60006122d4827f01ffc9a70000000000000000000000000000000000000000000000000000000061230c565b801561178d5750612305827fffffffff0000000000000000000000000000000000000000000000000000000061230c565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156123c4575060208210155b80156123d05750600081115b979650505050505050565b60606123ea848460008561246a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf8686866040516120e093929190612b5a565b6060824710156124fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610209565b73ffffffffffffffffffffffffffffffffffffffff85163b61257a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610209565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125a39190612c24565b60006040518083038185875af1925050503d80600081146125e0576040519150601f19603f3d011682016040523d82523d6000602084013e6125e5565b606091505b50915091506123d0828286606083156125ff575081611f55565b82511561260f5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610209919061294e565b73ffffffffffffffffffffffffffffffffffffffff8116811461266557600080fd5b50565b60008083601f84011261267a57600080fd5b50813567ffffffffffffffff81111561269257600080fd5b6020830191508360208285010111156126aa57600080fd5b9250929050565b600080600080600080600060c0888a0312156126cc57600080fd5b87356126d781612643565b965060208801356126e781612643565b955060408801356126f781612643565b9450606088013561270781612643565b93506080880135925060a088013567ffffffffffffffff81111561272a57600080fd5b6127368a828b01612668565b989b979a50959850939692959293505050565b803563ffffffff8116811461275d57600080fd5b919050565b60008060006040848603121561277757600080fd5b61278084612749565b9250602084013567ffffffffffffffff81111561279c57600080fd5b6127a886828701612668565b9497909650939450505050565b6000806000806000608086880312156127cd57600080fd5b85356127d881612643565b945060208601356127e881612643565b935060408601359250606086013567ffffffffffffffff81111561280b57600080fd5b61281788828901612668565b969995985093965092949392505050565b6000806040838503121561283b57600080fd5b823561284681612643565b9150602083013561285681612643565b809150509250929050565b600080600080600080600060c0888a03121561287c57600080fd5b873561288781612643565b9650602088013561289781612643565b955060408801356128a781612643565b9450606088013593506128bc60808901612749565b925060a088013567ffffffffffffffff81111561272a57600080fd5b60005b838110156128f35781810151838201526020016128db565b8381111561057a5750506000910152565b6000815180845261291c8160208601602086016128d8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f556020830184612904565b60008060008060008060a0878903121561297a57600080fd5b863561298581612643565b9550602087013561299581612643565b9450604087013593506129aa60608801612749565b9250608087013567ffffffffffffffff8111156129c657600080fd5b6129d289828a01612668565b979a9699509497509295939492505050565b600080600080606085870312156129fa57600080fd5b8435612a0581612643565b9350612a1360208601612749565b9250604085013567ffffffffffffffff811115612a2f57600080fd5b612a3b87828801612668565b95989497509550505050565b600060208284031215612a5957600080fd5b8151611f5581612643565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612aa557612aa5612a64565b500390565b600060208284031215612abc57600080fd5b81518015158114611f5557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612b0b6080830184612904565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612b446060830185612904565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612b8f6060830184612904565b95945050505050565b8281526040602082015260006123ea6040830184612904565b60008219821115612bc457612bc4612a64565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612c1860c0830184612904565b98975050505050505050565b60008251612c368184602087016128d8565b919091019291505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L1StandardBridgeStorageLayoutJSON), L1StandardBridgeStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["L1StandardBridge"] = L1StandardBridgeStorageLayout deployedBytecodes["L1StandardBridge"] = L1StandardBridgeDeployedBin + immutableReferences["L1StandardBridge"] = false } diff --git a/op-bindings/bindings/l2crossdomainmessenger.go b/op-bindings/bindings/l2crossdomainmessenger.go index 8c7a5d6236e1..ff7241f5e272 100644 --- a/op-bindings/bindings/l2crossdomainmessenger.go +++ b/op-bindings/bindings/l2crossdomainmessenger.go @@ -30,8 +30,8 @@ var ( // L2CrossDomainMessengerMetaData contains all meta data concerning the L2CrossDomainMessenger contract. var L2CrossDomainMessengerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1CrossDomainMessenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"FailedRelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"RelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"SentMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SentMessageExtension1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CALL_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_RESERVED_GAS\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1CrossDomainMessenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"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\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"relayMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"sendMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001db738038062001db78339810160408190526200003491620001e4565b6001600160a01b0381166080526200004b62000052565b5062000216565b600054600390600160a81b900460ff161580156200007e575060005460ff808316600160a01b90920416105b620000e75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a81b1960ff8416600160a01b021661ffff60a01b1990911617600160a81b179055620001196200015f565b6000805460ff60a81b1916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b600054600160a81b900460ff16620001ce5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000de565b60cc80546001600160a01b03191661dead179055565b600060208284031215620001f757600080fd5b81516001600160a01b03811681146200020f57600080fd5b9392505050565b608051611b7062000247600039600081816102dd0152818161034e0152818161043f0152610bef0152611b706000f3fe6080604052600436106101445760003560e01c80638129fc1c116100c0578063a711986911610074578063b28ade2511610059578063b28ade25146103a2578063d764ad0b146103c2578063ecc70428146103d557600080fd5b8063a71198691461033f578063b1b1b2091461037257600080fd5b80638cbeeef2116100a55780638cbeeef2146101e35780639fce812c146102cb578063a4e7f8bd146102ff57600080fd5b80638129fc1c1461029f57806383a74074146102b457600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146101f95780635644cfdf1461024f5780636e296e451461026557600080fd5b80633f827a5a146101bb5780634c1d6a69146101e357600080fd5b8063028f85f7146101495780630c5684981461017c5780632828d7e8146101915780633dbb202b146101a6575b600080fd5b34801561015557600080fd5b5061015e601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061015e603f81565b34801561019d57600080fd5b5061015e604081565b6101b96101b436600461168c565b61043a565b005b3480156101c757600080fd5b506101d0600181565b60405161ffff9091168152602001610173565b3480156101ef57600080fd5b5061015e619c4081565b34801561020557600080fd5b506102426040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b604051610173919061175c565b34801561025b57600080fd5b5061015e61138881565b34801561027157600080fd5b5061027a61069e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b3480156102ab57600080fd5b506101b961078a565b3480156102c057600080fd5b5061015e62030d4081565b3480156102d757600080fd5b5061027a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561030b57600080fd5b5061032f61031a366004611776565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610173565b34801561034b57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061027a565b34801561037e57600080fd5b5061032f61038d366004611776565b60cb6020526000908152604090205460ff1681565b3480156103ae57600080fd5b5061015e6103bd36600461178f565b61094d565b6101b96103d03660046117e3565b6109bb565b3480156103e157600080fd5b5061042c60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610173565b6105737f000000000000000000000000000000000000000000000000000000000000000061046985858561094d565b347fd764ad0b000000000000000000000000000000000000000000000000000000006104d560cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104f197969594939291906118ae565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611298565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856105f860cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b8660405161060a95949392919061190d565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff21530161076d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000546003907501000000000000000000000000000000000000000000900460ff161580156107d8575060005460ff8083167401000000000000000000000000000000000000000090920416105b610864576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610764565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff60ff84167401000000000000000000000000000000000000000002167fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff9091161775010000000000000000000000000000000000000000001790556108ec611326565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b6000611388619c4080603f610969604063ffffffff881661198a565b61097391906119ba565b61097e60108861198a565b61098b9062030d40611a08565b6109959190611a08565b61099f9190611a08565b6109a99190611a08565b6109b39190611a08565b949350505050565b60f087901c60028110610a76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a401610764565b8061ffff16600003610b6b576000610ac7878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506113ff915050565b600081815260cb602052604090205490915060ff1615610b69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c617965640000000000000000006064820152608401610764565b505b6000610bb1898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141e92505050565b905073ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330181167f000000000000000000000000000000000000000000000000000000000000000090911603610c4957853414610c2557610c25611a34565b600081815260ce602052604090205460ff1615610c4457610c44611a34565b610d9b565b3415610cfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a401610764565b600081815260ce602052604090205460ff16610d9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c61796564000000000000000000000000000000006064820152608401610764565b610da487611441565b15610e57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a401610764565b600081815260cb602052604090205460ff1615610ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c61796564000000000000000000006064820152608401610764565b610f1785610f08611388619c40611a08565b67ffffffffffffffff16611496565b1580610f3d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561105657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d657373616765000000000000000000000000000000000000006064820152608401610764565b505061128f565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006110e788619c405a6110aa9190611a63565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506114b492505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561117e57600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a261128b565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161128b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d657373616765000000000000000000000000000000000000006064820152608401610764565b5050505b50505050505050565b6040517fc2b3e5ac0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000169063c2b3e5ac9084906112ee90889088908790600401611a7a565b6000604051808303818588803b15801561130757600080fd5b505af115801561131b573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff166113d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610764565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b600061140d858585856114ce565b805190602001209050949350505050565b600061142e878787878787611567565b8051906020012090509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611490575073ffffffffffffffffffffffffffffffffffffffff8216734200000000000000000000000000000000000016145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016114e79493929190611ac2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161158496959493929190611b0c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461162a57600080fd5b919050565b60008083601f84011261164157600080fd5b50813567ffffffffffffffff81111561165957600080fd5b60208301915083602082850101111561167157600080fd5b9250929050565b803563ffffffff8116811461162a57600080fd5b600080600080606085870312156116a257600080fd5b6116ab85611606565b9350602085013567ffffffffffffffff8111156116c757600080fd5b6116d38782880161162f565b90945092506116e6905060408601611678565b905092959194509250565b6000815180845260005b81811015611717576020818501810151868301820152016116fb565b81811115611729576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061176f60208301846116f1565b9392505050565b60006020828403121561178857600080fd5b5035919050565b6000806000604084860312156117a457600080fd5b833567ffffffffffffffff8111156117bb57600080fd5b6117c78682870161162f565b90945092506117da905060208501611678565b90509250925092565b600080600080600080600060c0888a0312156117fe57600080fd5b8735965061180e60208901611606565b955061181c60408901611606565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561184657600080fd5b6118528a828b0161162f565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a083015261190060c083018486611865565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8616815260806020820152600061193d608083018688611865565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff808316818516818304811182151516156119b1576119b161195b565b02949350505050565b600067ffffffffffffffff808416806119fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611a2b57611a2b61195b565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611a7557611a7561195b565b500390565b73ffffffffffffffffffffffffffffffffffffffff8416815267ffffffffffffffff83166020820152606060408201526000611ab960608301846116f1565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611afb60808301856116f1565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611b5760c08301846116f1565b9897505050505050505056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"MESSAGE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OTHER_MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_CALL_OVERHEAD\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RELAY_RESERVED_GAS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"baseGas\",\"inputs\":[{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"failedMessages\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_l1CrossDomainMessenger\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l1CrossDomainMessenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"messageNonce\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"otherMessenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"relayMessage\",\"inputs\":[{\"name\":\"_nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"sendMessage\",\"inputs\":[{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"successfulMessages\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"xDomainMessageSender\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"FailedRelayedMessage\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RelayedMessage\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SentMessage\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"message\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"messageNonce\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"gasLimit\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SentMessageExtension1\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b506200001e600062000024565b62000239565b600054600160a81b900460ff16158080156200004d57506000546001600160a01b90910460ff16105b806200008457506200006a306200017360201b620013071760201c565b158015620000845750600054600160a01b900460ff166001145b620000ed5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a01b1916600160a01b17905580156200011b576000805460ff60a81b1916600160a81b1790555b620001268262000182565b80156200016f576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054600160a81b900460ff16620001f15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000e4565b60cc546001600160a01b0316620002175760cc80546001600160a01b03191661dead1790555b60cf80546001600160a01b0319166001600160a01b0392909216919091179055565b611c8280620002496000396000f3fe60806040526004361061016a5760003560e01c806383a74074116100cb578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b146103c7578063db505d80146103da578063ecc704281461040757600080fd5b8063b1b1b20914610357578063b28ade2514610387578063c4d66de8146103a757600080fd5b80639fce812c116100b05780639fce812c146102fc578063a4e7f8bd14610327578063a7119869146102fc57600080fd5b806383a74074146102e55780638cbeeef21461020957600080fd5b80634c1d6a69116101225780635644cfdf116101075780635644cfdf146102755780635c975abb1461028b5780636e296e45146102ab57600080fd5b80634c1d6a691461020957806354fd4d501461021f57600080fd5b80632828d7e8116101535780632828d7e8146101b75780633dbb202b146101cc5780633f827a5a146101e157600080fd5b8063028f85f71461016f5780630c568498146101a2575b600080fd5b34801561017b57600080fd5b50610184601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101ae57600080fd5b50610184603f81565b3480156101c357600080fd5b50610184604081565b6101df6101da36600461177b565b61046c565b005b3480156101ed57600080fd5b506101f6600181565b60405161ffff9091168152602001610199565b34801561021557600080fd5b50610184619c4081565b34801561022b57600080fd5b506102686040518060400160405280600581526020017f322e302e3000000000000000000000000000000000000000000000000000000081525081565b604051610199919061184d565b34801561028157600080fd5b5061018461138881565b34801561029757600080fd5b5060005b6040519015158152602001610199565b3480156102b757600080fd5b506102c06106c9565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610199565b3480156102f157600080fd5b5061018462030d4081565b34801561030857600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166102c0565b34801561033357600080fd5b5061029b610342366004611867565b60ce6020526000908152604090205460ff1681565b34801561036357600080fd5b5061029b610372366004611867565b60cb6020526000908152604090205460ff1681565b34801561039357600080fd5b506101846103a2366004611880565b6107b5565b3480156103b357600080fd5b506101df6103c23660046118d4565b610823565b6101df6103d53660046118f1565b610a22565b3480156103e657600080fd5b5060cf546102c09073ffffffffffffffffffffffffffffffffffffffff1681565b34801561041357600080fd5b5061045e60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610199565b60cf5461059e9073ffffffffffffffffffffffffffffffffffffffff166104948585856107b5565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061050060cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c60405160240161051c97969594939291906119c0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611323565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561062360cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b86604051610635959493929190611a1f565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff215301610798576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6107d1604063ffffffff8816611a9c565b6107db9190611acc565b6107e6601088611a9c565b6107f39062030d40611b1a565b6107fd9190611b1a565b6108079190611b1a565b6108119190611b1a565b61081b9190611b1a565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff161580801561086e575060005460017401000000000000000000000000000000000000000090910460ff16105b806108a05750303b1580156108a0575060005474010000000000000000000000000000000000000000900460ff166001145b61092c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161078f565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905580156109b257600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b6109bb826113b1565b8015610a1e57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60f087901c60028110610add576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a40161078f565b8061ffff16600003610bd2576000610b2e878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506114ed915050565b600081815260cb602052604090205490915060ff1615610bd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c61796564000000000000000000606482015260840161078f565b505b6000610c18898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061150c92505050565b9050610c6160cf54337fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef0173ffffffffffffffffffffffffffffffffffffffff90811691161490565b15610c9957853414610c7557610c75611b46565b600081815260ce602052604090205460ff1615610c9457610c94611b46565b610deb565b3415610d4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a40161078f565b600081815260ce602052604090205460ff16610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c6179656400000000000000000000000000000000606482015260840161078f565b610df48761152f565b15610ea7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a40161078f565b600081815260cb602052604090205460ff1615610f46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c6179656400000000000000000000606482015260840161078f565b610f6785610f58611388619c40611b1a565b67ffffffffffffffff16611584565b1580610f8d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b156110a657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161109f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161078f565b50506112fe565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061113788619c405a6110fa9190611b75565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115a292505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111ed57600082815260cb602052604090205460ff161561118a5761118a611b46565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112fa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161078f565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fc2b3e5ac0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000169063c2b3e5ac90849061137990889088908790600401611b8c565b6000604051808303818588803b15801561139257600080fd5b505af11580156113a6573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff1661145c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078f565b60cc5473ffffffffffffffffffffffffffffffffffffffff166114a65760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006114fb858585856115bc565b805190602001209050949350505050565b600061151c878787878787611655565b8051906020012090509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff821630148061157e575073ffffffffffffffffffffffffffffffffffffffff8216734200000000000000000000000000000000000016145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016115d59493929190611bd4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161167296959493929190611c1e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461171657600080fd5b50565b60008083601f84011261172b57600080fd5b50813567ffffffffffffffff81111561174357600080fd5b60208301915083602082850101111561175b57600080fd5b9250929050565b803563ffffffff8116811461177657600080fd5b919050565b6000806000806060858703121561179157600080fd5b843561179c816116f4565b9350602085013567ffffffffffffffff8111156117b857600080fd5b6117c487828801611719565b90945092506117d7905060408601611762565b905092959194509250565b6000815180845260005b81811015611808576020818501810151868301820152016117ec565b8181111561181a576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061186060208301846117e2565b9392505050565b60006020828403121561187957600080fd5b5035919050565b60008060006040848603121561189557600080fd5b833567ffffffffffffffff8111156118ac57600080fd5b6118b886828701611719565b90945092506118cb905060208501611762565b90509250925092565b6000602082840312156118e657600080fd5b8135611860816116f4565b600080600080600080600060c0888a03121561190c57600080fd5b87359650602088013561191e816116f4565b9550604088013561192e816116f4565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561195857600080fd5b6119648a828b01611719565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611a1260c083018486611977565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611a4f608083018688611977565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611ac357611ac3611a6d565b02949350505050565b600067ffffffffffffffff80841680611b0e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b3d57611b3d611a6d565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611b8757611b87611a6d565b500390565b73ffffffffffffffffffffffffffffffffffffffff8416815267ffffffffffffffff83166020820152606060408201526000611bcb60608301846117e2565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611c0d60808301856117e2565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611c6960c08301846117e2565b9897505050505050505056fea164736f6c634300080f000a", } // L2CrossDomainMessengerABI is the input ABI used to generate the binding from. @@ -43,7 +43,7 @@ var L2CrossDomainMessengerABI = L2CrossDomainMessengerMetaData.ABI var L2CrossDomainMessengerBin = L2CrossDomainMessengerMetaData.Bin // DeployL2CrossDomainMessenger deploys a new Ethereum contract, binding an instance of L2CrossDomainMessenger to it. -func DeployL2CrossDomainMessenger(auth *bind.TransactOpts, backend bind.ContractBackend, _l1CrossDomainMessenger common.Address) (common.Address, *types.Transaction, *L2CrossDomainMessenger, error) { +func DeployL2CrossDomainMessenger(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *L2CrossDomainMessenger, error) { parsed, err := L2CrossDomainMessengerMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -52,7 +52,7 @@ func DeployL2CrossDomainMessenger(auth *bind.TransactOpts, backend bind.Contract return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2CrossDomainMessengerBin), backend, _l1CrossDomainMessenger) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2CrossDomainMessengerBin), backend) if err != nil { return common.Address{}, nil, nil, err } @@ -604,6 +604,68 @@ func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) MessageNonce return _L2CrossDomainMessenger.Contract.MessageNonce(&_L2CrossDomainMessenger.CallOpts) } +// OtherMessenger is a free data retrieval call binding the contract method 0xdb505d80. +// +// Solidity: function otherMessenger() view returns(address) +func (_L2CrossDomainMessenger *L2CrossDomainMessengerCaller) OtherMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L2CrossDomainMessenger.contract.Call(opts, &out, "otherMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// OtherMessenger is a free data retrieval call binding the contract method 0xdb505d80. +// +// Solidity: function otherMessenger() view returns(address) +func (_L2CrossDomainMessenger *L2CrossDomainMessengerSession) OtherMessenger() (common.Address, error) { + return _L2CrossDomainMessenger.Contract.OtherMessenger(&_L2CrossDomainMessenger.CallOpts) +} + +// OtherMessenger is a free data retrieval call binding the contract method 0xdb505d80. +// +// Solidity: function otherMessenger() view returns(address) +func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) OtherMessenger() (common.Address, error) { + return _L2CrossDomainMessenger.Contract.OtherMessenger(&_L2CrossDomainMessenger.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L2CrossDomainMessenger *L2CrossDomainMessengerCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _L2CrossDomainMessenger.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L2CrossDomainMessenger *L2CrossDomainMessengerSession) Paused() (bool, error) { + return _L2CrossDomainMessenger.Contract.Paused(&_L2CrossDomainMessenger.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) Paused() (bool, error) { + return _L2CrossDomainMessenger.Contract.Paused(&_L2CrossDomainMessenger.CallOpts) +} + // SuccessfulMessages is a free data retrieval call binding the contract method 0xb1b1b209. // // Solidity: function successfulMessages(bytes32 ) view returns(bool) @@ -697,25 +759,25 @@ func (_L2CrossDomainMessenger *L2CrossDomainMessengerCallerSession) XDomainMessa return _L2CrossDomainMessenger.Contract.XDomainMessageSender(&_L2CrossDomainMessenger.CallOpts) } -// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function initialize() returns() -func (_L2CrossDomainMessenger *L2CrossDomainMessengerTransactor) Initialize(opts *bind.TransactOpts) (*types.Transaction, error) { - return _L2CrossDomainMessenger.contract.Transact(opts, "initialize") +// Solidity: function initialize(address _l1CrossDomainMessenger) returns() +func (_L2CrossDomainMessenger *L2CrossDomainMessengerTransactor) Initialize(opts *bind.TransactOpts, _l1CrossDomainMessenger common.Address) (*types.Transaction, error) { + return _L2CrossDomainMessenger.contract.Transact(opts, "initialize", _l1CrossDomainMessenger) } -// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function initialize() returns() -func (_L2CrossDomainMessenger *L2CrossDomainMessengerSession) Initialize() (*types.Transaction, error) { - return _L2CrossDomainMessenger.Contract.Initialize(&_L2CrossDomainMessenger.TransactOpts) +// Solidity: function initialize(address _l1CrossDomainMessenger) returns() +func (_L2CrossDomainMessenger *L2CrossDomainMessengerSession) Initialize(_l1CrossDomainMessenger common.Address) (*types.Transaction, error) { + return _L2CrossDomainMessenger.Contract.Initialize(&_L2CrossDomainMessenger.TransactOpts, _l1CrossDomainMessenger) } -// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function initialize() returns() -func (_L2CrossDomainMessenger *L2CrossDomainMessengerTransactorSession) Initialize() (*types.Transaction, error) { - return _L2CrossDomainMessenger.Contract.Initialize(&_L2CrossDomainMessenger.TransactOpts) +// Solidity: function initialize(address _l1CrossDomainMessenger) returns() +func (_L2CrossDomainMessenger *L2CrossDomainMessengerTransactorSession) Initialize(_l1CrossDomainMessenger common.Address) (*types.Transaction, error) { + return _L2CrossDomainMessenger.Contract.Initialize(&_L2CrossDomainMessenger.TransactOpts, _l1CrossDomainMessenger) } // RelayMessage is a paid mutator transaction binding the contract method 0xd764ad0b. diff --git a/op-bindings/bindings/l2crossdomainmessenger_more.go b/op-bindings/bindings/l2crossdomainmessenger_more.go index 8f2263d3f3d3..743b69412ffd 100644 --- a/op-bindings/bindings/l2crossdomainmessenger_more.go +++ b/op-bindings/bindings/l2crossdomainmessenger_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const L2CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1001,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1002,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1003,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_1_0_1600\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1004,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_51_0_20\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1005,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_52_0_1568\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1006,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_101_0_1\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":1007,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_102_0_1568\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1008,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_151_0_32\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":1009,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_152_0_1568\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1010,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1011,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1012,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1013,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":1014,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":1015,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"failedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1016,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\",\"base\":\"t_uint256\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const L2CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1001,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1002,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1003,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_1_0_1600\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1004,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_51_0_20\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1005,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_52_0_1568\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1006,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_101_0_1\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":1007,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_102_0_1568\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1008,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_151_0_32\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":1009,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_152_0_1568\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1010,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1011,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1012,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1013,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":1014,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":1015,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"failedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1016,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"otherMessenger\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_contract(CrossDomainMessenger)1018\"},{\"astId\":1017,\"contract\":\"src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"208\",\"type\":\"t_array(t_uint256)43_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)43_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[43]\",\"numberOfBytes\":\"1376\",\"base\":\"t_uint256\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_contract(CrossDomainMessenger)1018\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var L2CrossDomainMessengerStorageLayout = new(solc.StorageLayout) -var L2CrossDomainMessengerDeployedBin = "0x6080604052600436106101445760003560e01c80638129fc1c116100c0578063a711986911610074578063b28ade2511610059578063b28ade25146103a2578063d764ad0b146103c2578063ecc70428146103d557600080fd5b8063a71198691461033f578063b1b1b2091461037257600080fd5b80638cbeeef2116100a55780638cbeeef2146101e35780639fce812c146102cb578063a4e7f8bd146102ff57600080fd5b80638129fc1c1461029f57806383a74074146102b457600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146101f95780635644cfdf1461024f5780636e296e451461026557600080fd5b80633f827a5a146101bb5780634c1d6a69146101e357600080fd5b8063028f85f7146101495780630c5684981461017c5780632828d7e8146101915780633dbb202b146101a6575b600080fd5b34801561015557600080fd5b5061015e601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061015e603f81565b34801561019d57600080fd5b5061015e604081565b6101b96101b436600461168c565b61043a565b005b3480156101c757600080fd5b506101d0600181565b60405161ffff9091168152602001610173565b3480156101ef57600080fd5b5061015e619c4081565b34801561020557600080fd5b506102426040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b604051610173919061175c565b34801561025b57600080fd5b5061015e61138881565b34801561027157600080fd5b5061027a61069e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b3480156102ab57600080fd5b506101b961078a565b3480156102c057600080fd5b5061015e62030d4081565b3480156102d757600080fd5b5061027a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561030b57600080fd5b5061032f61031a366004611776565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610173565b34801561034b57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061027a565b34801561037e57600080fd5b5061032f61038d366004611776565b60cb6020526000908152604090205460ff1681565b3480156103ae57600080fd5b5061015e6103bd36600461178f565b61094d565b6101b96103d03660046117e3565b6109bb565b3480156103e157600080fd5b5061042c60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610173565b6105737f000000000000000000000000000000000000000000000000000000000000000061046985858561094d565b347fd764ad0b000000000000000000000000000000000000000000000000000000006104d560cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104f197969594939291906118ae565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611298565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856105f860cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b8660405161060a95949392919061190d565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff21530161076d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000546003907501000000000000000000000000000000000000000000900460ff161580156107d8575060005460ff8083167401000000000000000000000000000000000000000090920416105b610864576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610764565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff60ff84167401000000000000000000000000000000000000000002167fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff9091161775010000000000000000000000000000000000000000001790556108ec611326565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b6000611388619c4080603f610969604063ffffffff881661198a565b61097391906119ba565b61097e60108861198a565b61098b9062030d40611a08565b6109959190611a08565b61099f9190611a08565b6109a99190611a08565b6109b39190611a08565b949350505050565b60f087901c60028110610a76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a401610764565b8061ffff16600003610b6b576000610ac7878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506113ff915050565b600081815260cb602052604090205490915060ff1615610b69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c617965640000000000000000006064820152608401610764565b505b6000610bb1898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061141e92505050565b905073ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330181167f000000000000000000000000000000000000000000000000000000000000000090911603610c4957853414610c2557610c25611a34565b600081815260ce602052604090205460ff1615610c4457610c44611a34565b610d9b565b3415610cfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a401610764565b600081815260ce602052604090205460ff16610d9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c61796564000000000000000000000000000000006064820152608401610764565b610da487611441565b15610e57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a401610764565b600081815260cb602052604090205460ff1615610ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c61796564000000000000000000006064820152608401610764565b610f1785610f08611388619c40611a08565b67ffffffffffffffff16611496565b1580610f3d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561105657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d657373616765000000000000000000000000000000000000006064820152608401610764565b505061128f565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a1617905560006110e788619c405a6110aa9190611a63565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506114b492505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561117e57600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a261128b565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161128b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d657373616765000000000000000000000000000000000000006064820152608401610764565b5050505b50505050505050565b6040517fc2b3e5ac0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000169063c2b3e5ac9084906112ee90889088908790600401611a7a565b6000604051808303818588803b15801561130757600080fd5b505af115801561131b573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff166113d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610764565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b600061140d858585856114ce565b805190602001209050949350505050565b600061142e878787878787611567565b8051906020012090509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611490575073ffffffffffffffffffffffffffffffffffffffff8216734200000000000000000000000000000000000016145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016114e79493929190611ac2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161158496959493929190611b0c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461162a57600080fd5b919050565b60008083601f84011261164157600080fd5b50813567ffffffffffffffff81111561165957600080fd5b60208301915083602082850101111561167157600080fd5b9250929050565b803563ffffffff8116811461162a57600080fd5b600080600080606085870312156116a257600080fd5b6116ab85611606565b9350602085013567ffffffffffffffff8111156116c757600080fd5b6116d38782880161162f565b90945092506116e6905060408601611678565b905092959194509250565b6000815180845260005b81811015611717576020818501810151868301820152016116fb565b81811115611729576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061176f60208301846116f1565b9392505050565b60006020828403121561178857600080fd5b5035919050565b6000806000604084860312156117a457600080fd5b833567ffffffffffffffff8111156117bb57600080fd5b6117c78682870161162f565b90945092506117da905060208501611678565b90509250925092565b600080600080600080600060c0888a0312156117fe57600080fd5b8735965061180e60208901611606565b955061181c60408901611606565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561184657600080fd5b6118528a828b0161162f565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a083015261190060c083018486611865565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8616815260806020820152600061193d608083018688611865565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff808316818516818304811182151516156119b1576119b161195b565b02949350505050565b600067ffffffffffffffff808416806119fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611a2b57611a2b61195b565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611a7557611a7561195b565b500390565b73ffffffffffffffffffffffffffffffffffffffff8416815267ffffffffffffffff83166020820152606060408201526000611ab960608301846116f1565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611afb60808301856116f1565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611b5760c08301846116f1565b9897505050505050505056fea164736f6c634300080f000a" +var L2CrossDomainMessengerDeployedBin = "0x60806040526004361061016a5760003560e01c806383a74074116100cb578063b1b1b2091161007f578063d764ad0b11610059578063d764ad0b146103c7578063db505d80146103da578063ecc704281461040757600080fd5b8063b1b1b20914610357578063b28ade2514610387578063c4d66de8146103a757600080fd5b80639fce812c116100b05780639fce812c146102fc578063a4e7f8bd14610327578063a7119869146102fc57600080fd5b806383a74074146102e55780638cbeeef21461020957600080fd5b80634c1d6a69116101225780635644cfdf116101075780635644cfdf146102755780635c975abb1461028b5780636e296e45146102ab57600080fd5b80634c1d6a691461020957806354fd4d501461021f57600080fd5b80632828d7e8116101535780632828d7e8146101b75780633dbb202b146101cc5780633f827a5a146101e157600080fd5b8063028f85f71461016f5780630c568498146101a2575b600080fd5b34801561017b57600080fd5b50610184601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101ae57600080fd5b50610184603f81565b3480156101c357600080fd5b50610184604081565b6101df6101da36600461177b565b61046c565b005b3480156101ed57600080fd5b506101f6600181565b60405161ffff9091168152602001610199565b34801561021557600080fd5b50610184619c4081565b34801561022b57600080fd5b506102686040518060400160405280600581526020017f322e302e3000000000000000000000000000000000000000000000000000000081525081565b604051610199919061184d565b34801561028157600080fd5b5061018461138881565b34801561029757600080fd5b5060005b6040519015158152602001610199565b3480156102b757600080fd5b506102c06106c9565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610199565b3480156102f157600080fd5b5061018462030d4081565b34801561030857600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166102c0565b34801561033357600080fd5b5061029b610342366004611867565b60ce6020526000908152604090205460ff1681565b34801561036357600080fd5b5061029b610372366004611867565b60cb6020526000908152604090205460ff1681565b34801561039357600080fd5b506101846103a2366004611880565b6107b5565b3480156103b357600080fd5b506101df6103c23660046118d4565b610823565b6101df6103d53660046118f1565b610a22565b3480156103e657600080fd5b5060cf546102c09073ffffffffffffffffffffffffffffffffffffffff1681565b34801561041357600080fd5b5061045e60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610199565b60cf5461059e9073ffffffffffffffffffffffffffffffffffffffff166104948585856107b5565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061050060cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c60405160240161051c97969594939291906119c0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611323565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561062360cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b86604051610635959493929190611a1f565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff215301610798576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6107d1604063ffffffff8816611a9c565b6107db9190611acc565b6107e6601088611a9c565b6107f39062030d40611b1a565b6107fd9190611b1a565b6108079190611b1a565b6108119190611b1a565b61081b9190611b1a565b949350505050565b6000547501000000000000000000000000000000000000000000900460ff161580801561086e575060005460017401000000000000000000000000000000000000000090910460ff16105b806108a05750303b1580156108a0575060005474010000000000000000000000000000000000000000900460ff166001145b61092c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161078f565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905580156109b257600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b6109bb826113b1565b8015610a1e57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60f087901c60028110610add576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a40161078f565b8061ffff16600003610bd2576000610b2e878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506114ed915050565b600081815260cb602052604090205490915060ff1615610bd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c61796564000000000000000000606482015260840161078f565b505b6000610c18898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061150c92505050565b9050610c6160cf54337fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef0173ffffffffffffffffffffffffffffffffffffffff90811691161490565b15610c9957853414610c7557610c75611b46565b600081815260ce602052604090205460ff1615610c9457610c94611b46565b610deb565b3415610d4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a40161078f565b600081815260ce602052604090205460ff16610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c6179656400000000000000000000000000000000606482015260840161078f565b610df48761152f565b15610ea7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a40161078f565b600081815260cb602052604090205460ff1615610f46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c6179656400000000000000000000606482015260840161078f565b610f6785610f58611388619c40611b1a565b67ffffffffffffffff16611584565b1580610f8d575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b156110a657600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161109f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161078f565b50506112fe565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061113788619c405a6110fa9190611b75565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115a292505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111ed57600082815260cb602052604090205460ff161561118a5761118a611b46565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112fa565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161078f565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fc2b3e5ac0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000169063c2b3e5ac90849061137990889088908790600401611b8c565b6000604051808303818588803b15801561139257600080fd5b505af11580156113a6573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff1661145c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078f565b60cc5473ffffffffffffffffffffffffffffffffffffffff166114a65760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006114fb858585856115bc565b805190602001209050949350505050565b600061151c878787878787611655565b8051906020012090509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff821630148061157e575073ffffffffffffffffffffffffffffffffffffffff8216734200000000000000000000000000000000000016145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016115d59493929190611bd4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161167296959493929190611c1e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461171657600080fd5b50565b60008083601f84011261172b57600080fd5b50813567ffffffffffffffff81111561174357600080fd5b60208301915083602082850101111561175b57600080fd5b9250929050565b803563ffffffff8116811461177657600080fd5b919050565b6000806000806060858703121561179157600080fd5b843561179c816116f4565b9350602085013567ffffffffffffffff8111156117b857600080fd5b6117c487828801611719565b90945092506117d7905060408601611762565b905092959194509250565b6000815180845260005b81811015611808576020818501810151868301820152016117ec565b8181111561181a576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061186060208301846117e2565b9392505050565b60006020828403121561187957600080fd5b5035919050565b60008060006040848603121561189557600080fd5b833567ffffffffffffffff8111156118ac57600080fd5b6118b886828701611719565b90945092506118cb905060208501611762565b90509250925092565b6000602082840312156118e657600080fd5b8135611860816116f4565b600080600080600080600060c0888a03121561190c57600080fd5b87359650602088013561191e816116f4565b9550604088013561192e816116f4565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561195857600080fd5b6119648a828b01611719565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611a1260c083018486611977565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611a4f608083018688611977565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611ac357611ac3611a6d565b02949350505050565b600067ffffffffffffffff80841680611b0e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b3d57611b3d611a6d565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611b8757611b87611a6d565b500390565b73ffffffffffffffffffffffffffffffffffffffff8416815267ffffffffffffffff83166020820152606060408201526000611bcb60608301846117e2565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611c0d60808301856117e2565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611c6960c08301846117e2565b9897505050505050505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L2CrossDomainMessengerStorageLayoutJSON), L2CrossDomainMessengerStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["L2CrossDomainMessenger"] = L2CrossDomainMessengerStorageLayout deployedBytecodes["L2CrossDomainMessenger"] = L2CrossDomainMessengerDeployedBin + immutableReferences["L2CrossDomainMessenger"] = false } diff --git a/op-bindings/bindings/l2erc721bridge.go b/op-bindings/bindings/l2erc721bridge.go index edb9c6030f5a..cd4ba2f7fab4 100644 --- a/op-bindings/bindings/l2erc721bridge.go +++ b/op-bindings/bindings/l2erc721bridge.go @@ -30,8 +30,8 @@ var ( // L2ERC721BridgeMetaData contains all meta data concerning the L2ERC721Bridge contract. var L2ERC721BridgeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_otherBridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC721BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC721BridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC721To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b506040516200187b3803806200187b83398101604081905262000034916200025c565b806001600160a01b038116620000a95760405162461bcd60e51b815260206004820152602f60248201527f4552433732314272696467653a206f74686572206272696467652063616e6e6f60448201526e74206265206164647265737328302960881b60648201526084015b60405180910390fd5b6001600160a01b0316608052620000bf620000c6565b506200028e565b600054600390610100900460ff16158015620000e9575060005460ff8083169116105b6200014e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000a0565b6000805461ffff191660ff83161761010017905562000181734200000000000000000000000000000000000007620001c5565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b600054610100900460ff16620002325760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000a0565b600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6000602082840312156200026f57600080fd5b81516001600160a01b03811681146200028757600080fd5b9392505050565b6080516115bc620002bf6000396000818161016e015281816101d1015281816102cb0152610ea901526115bc6000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80637f46ddb211610076578063927ede2d1161005b578063927ede2d14610198578063aa557452146101bc578063c89701a2146101cf57600080fd5b80637f46ddb2146101695780638129fc1c1461019057600080fd5b80633687011a146100a85780633cb747bf146100bd57806354fd4d501461010d578063761f449314610156575b600080fd5b6100bb6100b6366004611257565b6101f5565b005b6000546100e39062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101496040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516101049190611345565b6100bb610164366004611358565b6102a1565b6100e37f000000000000000000000000000000000000000000000000000000000000000081565b6100bb6107f2565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166100e3565b6100bb6101ca3660046113f0565b61094f565b7f00000000000000000000000000000000000000000000000000000000000000006100e3565b333b15610289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102998686333388888888610a0b565b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16331480156103a957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa15801561036d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103919190611467565b73ffffffffffffffffffffffffffffffffffffffff16145b610435576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f7468657220627269646765006064820152608401610280565b3073ffffffffffffffffffffffffffffffffffffffff8816036104da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c66000000000000000000000000000000000000000000006064820152608401610280565b610504877f74259ebf00000000000000000000000000000000000000000000000000000000610f95565b610590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e20696e746560448201527f7266616365206973206e6f7420636f6d706c69616e74000000000000000000006064820152608401610280565b8673ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ff9190611467565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146106df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324552433732314272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433732312060648201527f6c6f63616c20746f6b656e000000000000000000000000000000000000000000608482015260a401610280565b6040517fa144819400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301526024820185905288169063a144819490604401600060405180830381600087803b15801561074f57600080fd5b505af1158015610763573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107e194939291906114cd565b60405180910390a450505050505050565b600054600390610100900460ff16158015610814575060005460ff8083169116105b6108a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610280565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556108ee734200000000000000000000000000000000000007610fb8565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff85166109f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f742062652061646472657373283029000000000000000000000000000000006064820152608401610280565b610a028787338888888888610a0b565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff8716610aae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f7420626520616464726573732830290000000000000000000000000000006064820152608401610280565b6040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff891690636352211e90602401602060405180830381865afa158015610b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d9190611467565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610bf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324552433732314272696467653a205769746864726177616c206973206e6f60448201527f74206265696e6720696e69746961746564206279204e4654206f776e657200006064820152608401610280565b60008873ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c689190611467565b90508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e20646f6560448201527f73206e6f74206d6174636820676976656e2076616c75650000000000000000006064820152608401610280565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018790528a1690639dc29fac90604401600060405180830381600087803b158015610d9557600080fd5b505af1158015610da9573d6000803e3d6000fd5b50505050600063761f449360e01b828b8a8a8a8989604051602401610dd4979695949392919061150d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260005491517f3dbb202b00000000000000000000000000000000000000000000000000000000815290925073ffffffffffffffffffffffffffffffffffffffff620100009092049190911690633dbb202b90610ed5907f00000000000000000000000000000000000000000000000000000000000000009085908a9060040161156a565b600060405180830381600087803b158015610eef57600080fd5b505af1158015610f03573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a58a8a8989604051610f8194939291906114cd565b60405180910390a450505050505050505050565b6000610fa08361109c565b8015610fb15750610fb18383611101565b9392505050565b600054610100900460ff1661104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610280565b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b60006110c8827f01ffc9a700000000000000000000000000000000000000000000000000000000611101565b80156110fb57506110f9827fffffffff00000000000000000000000000000000000000000000000000000000611101565b155b92915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156111b9575060208210155b80156111c55750600081115b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146111f257600080fd5b50565b803563ffffffff8116811461120957600080fd5b919050565b60008083601f84011261122057600080fd5b50813567ffffffffffffffff81111561123857600080fd5b60208301915083602082850101111561125057600080fd5b9250929050565b60008060008060008060a0878903121561127057600080fd5b863561127b816111d0565b9550602087013561128b816111d0565b9450604087013593506112a0606088016111f5565b9250608087013567ffffffffffffffff8111156112bc57600080fd5b6112c889828a0161120e565b979a9699509497509295939492505050565b6000815180845260005b81811015611300576020818501810151868301820152016112e4565b81811115611312576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610fb160208301846112da565b600080600080600080600060c0888a03121561137357600080fd5b873561137e816111d0565b9650602088013561138e816111d0565b9550604088013561139e816111d0565b945060608801356113ae816111d0565b93506080880135925060a088013567ffffffffffffffff8111156113d157600080fd5b6113dd8a828b0161120e565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561140b57600080fd5b8735611416816111d0565b96506020880135611426816111d0565b95506040880135611436816111d0565b94506060880135935061144b608089016111f5565b925060a088013567ffffffffffffffff8111156113d157600080fd5b60006020828403121561147957600080fd5b8151610fb1816111d0565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000611503606083018486611484565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261155d60c083018486611484565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061159960608301856112da565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"bridgeERC721\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bridgeERC721To\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"finalizeBridgeERC721\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_l1ERC721Bridge\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"messenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"otherBridge\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ERC721BridgeFinalized\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ERC721BridgeInitiated\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b506200001e600062000024565b62000217565b600054610100900460ff1615808015620000455750600054600160ff909116105b8062000075575062000062306200016d60201b62000a3e1760201c565b15801562000075575060005460ff166001145b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000102576000805461ff0019166101001790555b62000122734200000000000000000000000000000000000007836200017c565b801562000169576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff16620001e95760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b600180546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b61160c80620002276000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80637f46ddb211610076578063aa5574521161005b578063aa557452146101c9578063c4d66de8146101dc578063c89701a2146101ef57600080fd5b80637f46ddb21461018d578063927ede2d146101ab57600080fd5b806354fd4d50116100a757806354fd4d50146101225780635c975abb1461016b578063761f44931461017a57600080fd5b80633687011a146100c35780633cb747bf146100d8575b600080fd5b6100d66100d136600461128a565b61020f565b005b6001546100f89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61015e6040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b6040516101199190611378565b60405160008152602001610119565b6100d661018836600461138b565b6102bb565b60025473ffffffffffffffffffffffffffffffffffffffff166100f8565b60015473ffffffffffffffffffffffffffffffffffffffff166100f8565b6100d66101d7366004611423565b6107d9565b6100d66101ea36600461149a565b610895565b6002546100f89073ffffffffffffffffffffffffffffffffffffffff1681565b333b156102a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102b38686333388888888610a5a565b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156103905750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa158015610354573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037891906114b7565b73ffffffffffffffffffffffffffffffffffffffff16145b61041c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161029a565b3073ffffffffffffffffffffffffffffffffffffffff8816036104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161029a565b6104eb877f74259ebf00000000000000000000000000000000000000000000000000000000610fc2565b610577576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e20696e746560448201527f7266616365206973206e6f7420636f6d706c69616e7400000000000000000000606482015260840161029a565b8673ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e691906114b7565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146106c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324552433732314272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433732312060648201527f6c6f63616c20746f6b656e000000000000000000000000000000000000000000608482015260a40161029a565b6040517fa144819400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301526024820185905288169063a144819490604401600060405180830381600087803b15801561073657600080fd5b505af115801561074a573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107c8949392919061151d565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff851661087c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161029a565b61088c8787338888888888610a5a565b50505050505050565b600054610100900460ff16158080156108b55750600054600160ff909116105b806108cf5750303b1580156108cf575060005460ff166001145b61095b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161029a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156109b957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6109d773420000000000000000000000000000000000000783610fe5565b8015610a3a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610afd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161029a565b6040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff891690636352211e90602401602060405180830381865afa158015610b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8c91906114b7565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610c46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324552433732314272696467653a205769746864726177616c206973206e6f60448201527f74206265696e6720696e69746961746564206279204e4654206f776e65720000606482015260840161029a565b60008873ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb791906114b7565b90508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e20646f6560448201527f73206e6f74206d6174636820676976656e2076616c7565000000000000000000606482015260840161029a565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018790528a1690639dc29fac90604401600060405180830381600087803b158015610de457600080fd5b505af1158015610df8573d6000803e3d6000fd5b50505050600063761f449360e01b828b8a8a8a8989604051602401610e23979695949392919061155d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260015460025492517f3dbb202b00000000000000000000000000000000000000000000000000000000815291935073ffffffffffffffffffffffffffffffffffffffff90811692633dbb202b92610f0292919091169085908a906004016115ba565b600060405180830381600087803b158015610f1c57600080fd5b505af1158015610f30573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a58a8a8989604051610fae949392919061151d565b60405180910390a450505050505050505050565b6000610fcd836110cf565b8015610fde5750610fde8383611134565b9392505050565b600054610100900460ff1661107c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161029a565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b60006110fb827f01ffc9a700000000000000000000000000000000000000000000000000000000611134565b801561112e575061112c827fffffffff00000000000000000000000000000000000000000000000000000000611134565b155b92915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156111ec575060208210155b80156111f85750600081115b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461122557600080fd5b50565b803563ffffffff8116811461123c57600080fd5b919050565b60008083601f84011261125357600080fd5b50813567ffffffffffffffff81111561126b57600080fd5b60208301915083602082850101111561128357600080fd5b9250929050565b60008060008060008060a087890312156112a357600080fd5b86356112ae81611203565b955060208701356112be81611203565b9450604087013593506112d360608801611228565b9250608087013567ffffffffffffffff8111156112ef57600080fd5b6112fb89828a01611241565b979a9699509497509295939492505050565b6000815180845260005b8181101561133357602081850181015186830182015201611317565b81811115611345576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610fde602083018461130d565b600080600080600080600060c0888a0312156113a657600080fd5b87356113b181611203565b965060208801356113c181611203565b955060408801356113d181611203565b945060608801356113e181611203565b93506080880135925060a088013567ffffffffffffffff81111561140457600080fd5b6114108a828b01611241565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561143e57600080fd5b873561144981611203565b9650602088013561145981611203565b9550604088013561146981611203565b94506060880135935061147e60808901611228565b925060a088013567ffffffffffffffff81111561140457600080fd5b6000602082840312156114ac57600080fd5b8135610fde81611203565b6000602082840312156114c957600080fd5b8151610fde81611203565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006115536060830184866114d4565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a08301526115ad60c0830184866114d4565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006115e9606083018561130d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", } // L2ERC721BridgeABI is the input ABI used to generate the binding from. @@ -43,7 +43,7 @@ var L2ERC721BridgeABI = L2ERC721BridgeMetaData.ABI var L2ERC721BridgeBin = L2ERC721BridgeMetaData.Bin // DeployL2ERC721Bridge deploys a new Ethereum contract, binding an instance of L2ERC721Bridge to it. -func DeployL2ERC721Bridge(auth *bind.TransactOpts, backend bind.ContractBackend, _otherBridge common.Address) (common.Address, *types.Transaction, *L2ERC721Bridge, error) { +func DeployL2ERC721Bridge(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *L2ERC721Bridge, error) { parsed, err := L2ERC721BridgeMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -52,7 +52,7 @@ func DeployL2ERC721Bridge(auth *bind.TransactOpts, backend bind.ContractBackend, return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2ERC721BridgeBin), backend, _otherBridge) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2ERC721BridgeBin), backend) if err != nil { return common.Address{}, nil, nil, err } @@ -325,6 +325,37 @@ func (_L2ERC721Bridge *L2ERC721BridgeCallerSession) OtherBridge() (common.Addres return _L2ERC721Bridge.Contract.OtherBridge(&_L2ERC721Bridge.CallOpts) } +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L2ERC721Bridge *L2ERC721BridgeCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _L2ERC721Bridge.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L2ERC721Bridge *L2ERC721BridgeSession) Paused() (bool, error) { + return _L2ERC721Bridge.Contract.Paused(&_L2ERC721Bridge.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L2ERC721Bridge *L2ERC721BridgeCallerSession) Paused() (bool, error) { + return _L2ERC721Bridge.Contract.Paused(&_L2ERC721Bridge.CallOpts) +} + // Version is a free data retrieval call binding the contract method 0x54fd4d50. // // Solidity: function version() view returns(string) @@ -419,25 +450,25 @@ func (_L2ERC721Bridge *L2ERC721BridgeTransactorSession) FinalizeBridgeERC721(_lo return _L2ERC721Bridge.Contract.FinalizeBridgeERC721(&_L2ERC721Bridge.TransactOpts, _localToken, _remoteToken, _from, _to, _tokenId, _extraData) } -// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function initialize() returns() -func (_L2ERC721Bridge *L2ERC721BridgeTransactor) Initialize(opts *bind.TransactOpts) (*types.Transaction, error) { - return _L2ERC721Bridge.contract.Transact(opts, "initialize") +// Solidity: function initialize(address _l1ERC721Bridge) returns() +func (_L2ERC721Bridge *L2ERC721BridgeTransactor) Initialize(opts *bind.TransactOpts, _l1ERC721Bridge common.Address) (*types.Transaction, error) { + return _L2ERC721Bridge.contract.Transact(opts, "initialize", _l1ERC721Bridge) } -// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function initialize() returns() -func (_L2ERC721Bridge *L2ERC721BridgeSession) Initialize() (*types.Transaction, error) { - return _L2ERC721Bridge.Contract.Initialize(&_L2ERC721Bridge.TransactOpts) +// Solidity: function initialize(address _l1ERC721Bridge) returns() +func (_L2ERC721Bridge *L2ERC721BridgeSession) Initialize(_l1ERC721Bridge common.Address) (*types.Transaction, error) { + return _L2ERC721Bridge.Contract.Initialize(&_L2ERC721Bridge.TransactOpts, _l1ERC721Bridge) } -// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function initialize() returns() -func (_L2ERC721Bridge *L2ERC721BridgeTransactorSession) Initialize() (*types.Transaction, error) { - return _L2ERC721Bridge.Contract.Initialize(&_L2ERC721Bridge.TransactOpts) +// Solidity: function initialize(address _l1ERC721Bridge) returns() +func (_L2ERC721Bridge *L2ERC721BridgeTransactorSession) Initialize(_l1ERC721Bridge common.Address) (*types.Transaction, error) { + return _L2ERC721Bridge.Contract.Initialize(&_L2ERC721Bridge.TransactOpts, _l1ERC721Bridge) } // L2ERC721BridgeERC721BridgeFinalizedIterator is returned from FilterERC721BridgeFinalized and is used to iterate over the raw logs and unpacked data for ERC721BridgeFinalized events raised by the L2ERC721Bridge contract. diff --git a/op-bindings/bindings/l2erc721bridge_more.go b/op-bindings/bindings/l2erc721bridge_more.go index 2f568f57cdfc..6c05fd789837 100644 --- a/op-bindings/bindings/l2erc721bridge_more.go +++ b/op-bindings/bindings/l2erc721bridge_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const L2ERC721BridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"messenger\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_contract(CrossDomainMessenger)1004\"},{\"astId\":1003,\"contract\":\"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)48_storage\"}],\"types\":{\"t_array(t_uint256)48_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[48]\",\"numberOfBytes\":\"1536\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(CrossDomainMessenger)1004\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const L2ERC721BridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"spacer_0_2_30\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_bytes30\"},{\"astId\":1003,\"contract\":\"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"messenger\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_contract(CrossDomainMessenger)1006\"},{\"astId\":1004,\"contract\":\"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"otherBridge\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_contract(StandardBridge)1007\"},{\"astId\":1005,\"contract\":\"src/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_uint256)46_storage\"}],\"types\":{\"t_array(t_uint256)46_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[46]\",\"numberOfBytes\":\"1472\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes30\":{\"encoding\":\"inplace\",\"label\":\"bytes30\",\"numberOfBytes\":\"30\"},\"t_contract(CrossDomainMessenger)1006\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_contract(StandardBridge)1007\":{\"encoding\":\"inplace\",\"label\":\"contract StandardBridge\",\"numberOfBytes\":\"20\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var L2ERC721BridgeStorageLayout = new(solc.StorageLayout) -var L2ERC721BridgeDeployedBin = "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80637f46ddb211610076578063927ede2d1161005b578063927ede2d14610198578063aa557452146101bc578063c89701a2146101cf57600080fd5b80637f46ddb2146101695780638129fc1c1461019057600080fd5b80633687011a146100a85780633cb747bf146100bd57806354fd4d501461010d578063761f449314610156575b600080fd5b6100bb6100b6366004611257565b6101f5565b005b6000546100e39062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101496040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516101049190611345565b6100bb610164366004611358565b6102a1565b6100e37f000000000000000000000000000000000000000000000000000000000000000081565b6100bb6107f2565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166100e3565b6100bb6101ca3660046113f0565b61094f565b7f00000000000000000000000000000000000000000000000000000000000000006100e3565b333b15610289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102998686333388888888610a0b565b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16331480156103a957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa15801561036d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103919190611467565b73ffffffffffffffffffffffffffffffffffffffff16145b610435576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f7468657220627269646765006064820152608401610280565b3073ffffffffffffffffffffffffffffffffffffffff8816036104da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c66000000000000000000000000000000000000000000006064820152608401610280565b610504877f74259ebf00000000000000000000000000000000000000000000000000000000610f95565b610590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e20696e746560448201527f7266616365206973206e6f7420636f6d706c69616e74000000000000000000006064820152608401610280565b8673ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ff9190611467565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146106df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324552433732314272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433732312060648201527f6c6f63616c20746f6b656e000000000000000000000000000000000000000000608482015260a401610280565b6040517fa144819400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301526024820185905288169063a144819490604401600060405180830381600087803b15801561074f57600080fd5b505af1158015610763573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107e194939291906114cd565b60405180910390a450505050505050565b600054600390610100900460ff16158015610814575060005460ff8083169116105b6108a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610280565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556108ee734200000000000000000000000000000000000007610fb8565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff85166109f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f742062652061646472657373283029000000000000000000000000000000006064820152608401610280565b610a028787338888888888610a0b565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff8716610aae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f7420626520616464726573732830290000000000000000000000000000006064820152608401610280565b6040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff891690636352211e90602401602060405180830381865afa158015610b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d9190611467565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610bf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324552433732314272696467653a205769746864726177616c206973206e6f60448201527f74206265696e6720696e69746961746564206279204e4654206f776e657200006064820152608401610280565b60008873ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c689190611467565b90508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e20646f6560448201527f73206e6f74206d6174636820676976656e2076616c75650000000000000000006064820152608401610280565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018790528a1690639dc29fac90604401600060405180830381600087803b158015610d9557600080fd5b505af1158015610da9573d6000803e3d6000fd5b50505050600063761f449360e01b828b8a8a8a8989604051602401610dd4979695949392919061150d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260005491517f3dbb202b00000000000000000000000000000000000000000000000000000000815290925073ffffffffffffffffffffffffffffffffffffffff620100009092049190911690633dbb202b90610ed5907f00000000000000000000000000000000000000000000000000000000000000009085908a9060040161156a565b600060405180830381600087803b158015610eef57600080fd5b505af1158015610f03573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a58a8a8989604051610f8194939291906114cd565b60405180910390a450505050505050505050565b6000610fa08361109c565b8015610fb15750610fb18383611101565b9392505050565b600054610100900460ff1661104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610280565b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b60006110c8827f01ffc9a700000000000000000000000000000000000000000000000000000000611101565b80156110fb57506110f9827fffffffff00000000000000000000000000000000000000000000000000000000611101565b155b92915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156111b9575060208210155b80156111c55750600081115b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146111f257600080fd5b50565b803563ffffffff8116811461120957600080fd5b919050565b60008083601f84011261122057600080fd5b50813567ffffffffffffffff81111561123857600080fd5b60208301915083602082850101111561125057600080fd5b9250929050565b60008060008060008060a0878903121561127057600080fd5b863561127b816111d0565b9550602087013561128b816111d0565b9450604087013593506112a0606088016111f5565b9250608087013567ffffffffffffffff8111156112bc57600080fd5b6112c889828a0161120e565b979a9699509497509295939492505050565b6000815180845260005b81811015611300576020818501810151868301820152016112e4565b81811115611312576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610fb160208301846112da565b600080600080600080600060c0888a03121561137357600080fd5b873561137e816111d0565b9650602088013561138e816111d0565b9550604088013561139e816111d0565b945060608801356113ae816111d0565b93506080880135925060a088013567ffffffffffffffff8111156113d157600080fd5b6113dd8a828b0161120e565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561140b57600080fd5b8735611416816111d0565b96506020880135611426816111d0565b95506040880135611436816111d0565b94506060880135935061144b608089016111f5565b925060a088013567ffffffffffffffff8111156113d157600080fd5b60006020828403121561147957600080fd5b8151610fb1816111d0565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000611503606083018486611484565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261155d60c083018486611484565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061159960608301856112da565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a" +var L2ERC721BridgeDeployedBin = "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c80637f46ddb211610076578063aa5574521161005b578063aa557452146101c9578063c4d66de8146101dc578063c89701a2146101ef57600080fd5b80637f46ddb21461018d578063927ede2d146101ab57600080fd5b806354fd4d50116100a757806354fd4d50146101225780635c975abb1461016b578063761f44931461017a57600080fd5b80633687011a146100c35780633cb747bf146100d8575b600080fd5b6100d66100d136600461128a565b61020f565b005b6001546100f89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61015e6040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b6040516101199190611378565b60405160008152602001610119565b6100d661018836600461138b565b6102bb565b60025473ffffffffffffffffffffffffffffffffffffffff166100f8565b60015473ffffffffffffffffffffffffffffffffffffffff166100f8565b6100d66101d7366004611423565b6107d9565b6100d66101ea36600461149a565b610895565b6002546100f89073ffffffffffffffffffffffffffffffffffffffff1681565b333b156102a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102b38686333388888888610a5a565b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156103905750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa158015610354573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037891906114b7565b73ffffffffffffffffffffffffffffffffffffffff16145b61041c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161029a565b3073ffffffffffffffffffffffffffffffffffffffff8816036104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161029a565b6104eb877f74259ebf00000000000000000000000000000000000000000000000000000000610fc2565b610577576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e20696e746560448201527f7266616365206973206e6f7420636f6d706c69616e7400000000000000000000606482015260840161029a565b8673ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e691906114b7565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146106c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324552433732314272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433732312060648201527f6c6f63616c20746f6b656e000000000000000000000000000000000000000000608482015260a40161029a565b6040517fa144819400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301526024820185905288169063a144819490604401600060405180830381600087803b15801561073657600080fd5b505af115801561074a573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107c8949392919061151d565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff851661087c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161029a565b61088c8787338888888888610a5a565b50505050505050565b600054610100900460ff16158080156108b55750600054600160ff909116105b806108cf5750303b1580156108cf575060005460ff166001145b61095b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161029a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156109b957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6109d773420000000000000000000000000000000000000783610fe5565b8015610a3a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610afd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161029a565b6040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff891690636352211e90602401602060405180830381865afa158015610b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8c91906114b7565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610c46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324552433732314272696467653a205769746864726177616c206973206e6f60448201527f74206265696e6720696e69746961746564206279204e4654206f776e65720000606482015260840161029a565b60008873ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb791906114b7565b90508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e20646f6560448201527f73206e6f74206d6174636820676976656e2076616c7565000000000000000000606482015260840161029a565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018790528a1690639dc29fac90604401600060405180830381600087803b158015610de457600080fd5b505af1158015610df8573d6000803e3d6000fd5b50505050600063761f449360e01b828b8a8a8a8989604051602401610e23979695949392919061155d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260015460025492517f3dbb202b00000000000000000000000000000000000000000000000000000000815291935073ffffffffffffffffffffffffffffffffffffffff90811692633dbb202b92610f0292919091169085908a906004016115ba565b600060405180830381600087803b158015610f1c57600080fd5b505af1158015610f30573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a58a8a8989604051610fae949392919061151d565b60405180910390a450505050505050505050565b6000610fcd836110cf565b8015610fde5750610fde8383611134565b9392505050565b600054610100900460ff1661107c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161029a565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b60006110fb827f01ffc9a700000000000000000000000000000000000000000000000000000000611134565b801561112e575061112c827fffffffff00000000000000000000000000000000000000000000000000000000611134565b155b92915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156111ec575060208210155b80156111f85750600081115b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461122557600080fd5b50565b803563ffffffff8116811461123c57600080fd5b919050565b60008083601f84011261125357600080fd5b50813567ffffffffffffffff81111561126b57600080fd5b60208301915083602082850101111561128357600080fd5b9250929050565b60008060008060008060a087890312156112a357600080fd5b86356112ae81611203565b955060208701356112be81611203565b9450604087013593506112d360608801611228565b9250608087013567ffffffffffffffff8111156112ef57600080fd5b6112fb89828a01611241565b979a9699509497509295939492505050565b6000815180845260005b8181101561133357602081850181015186830182015201611317565b81811115611345576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610fde602083018461130d565b600080600080600080600060c0888a0312156113a657600080fd5b87356113b181611203565b965060208801356113c181611203565b955060408801356113d181611203565b945060608801356113e181611203565b93506080880135925060a088013567ffffffffffffffff81111561140457600080fd5b6114108a828b01611241565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561143e57600080fd5b873561144981611203565b9650602088013561145981611203565b9550604088013561146981611203565b94506060880135935061147e60808901611228565b925060a088013567ffffffffffffffff81111561140457600080fd5b6000602082840312156114ac57600080fd5b8135610fde81611203565b6000602082840312156114c957600080fd5b8151610fde81611203565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006115536060830184866114d4565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a08301526115ad60c0830184866114d4565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006115e9606083018561130d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L2ERC721BridgeStorageLayoutJSON), L2ERC721BridgeStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["L2ERC721Bridge"] = L2ERC721BridgeStorageLayout deployedBytecodes["L2ERC721Bridge"] = L2ERC721BridgeDeployedBin + immutableReferences["L2ERC721Bridge"] = false } diff --git a/op-bindings/bindings/l2outputoracle.go b/op-bindings/bindings/l2outputoracle.go index c0b3974157af..1d8934c7c838 100644 --- a/op-bindings/bindings/l2outputoracle.go +++ b/op-bindings/bindings/l2outputoracle.go @@ -37,8 +37,8 @@ type TypesOutputProposal struct { // L2OutputOracleMetaData contains all meta data concerning the L2OutputOracle contract. var L2OutputOracleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_submissionInterval\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockTime\",\"type\":\"uint256\"},{\"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\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"l2OutputIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"l2BlockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"l1Timestamp\",\"type\":\"uint256\"}],\"name\":\"OutputProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"prevNextOutputIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newNextOutputIndex\",\"type\":\"uint256\"}],\"name\":\"OutputsDeleted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CHALLENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_BLOCK_TIME\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PROPOSER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"challenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"computeL2Timestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"deleteL2Outputs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"finalizationPeriodSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"getL2Output\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}],\"internalType\":\"structTypes.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2OutputAfter\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}],\"internalType\":\"structTypes.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2OutputIndexAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_proposer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_challenger\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2BlockTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestOutputIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextOutputIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1BlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1BlockNumber\",\"type\":\"uint256\"}],\"name\":\"proposeL2Output\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startingBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startingTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"submissionInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620018ae380380620018ae8339810160408190526200003491620002f3565b60008211620000b05760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e203000000000000000000000000060648201526084015b60405180910390fd5b60008311620001285760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e20300000000000006064820152608401620000a7565b608083905260a082905260c08190526200014660008080806200014f565b50505062000322565b600054600390610100900460ff1615801562000172575060005460ff8083169116105b620001d75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000a7565b6000805461ffff191660ff83161761010017905542841115620002715760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401620000a7565b60028490556001859055600580546001600160a01b038581166001600160a01b03199283161790925560048054928516929091169190911790556000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6000806000606084860312156200030957600080fd5b8351925060208401519150604084015190509250925092565b60805160a05160c0516115326200037c600039600081816104b3015281816105710152610beb0152600081816101a1015281816103b9015261127401526000818161021f0152818161053b01526112c201526115326000f3fe60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec334814610517578063e1a41bcf1461052c578063f4daa2911461055f57600080fd5b8063ce5db8d6146104a4578063cf8e5cf0146104d7578063d1de856c146104f757600080fd5b8063a25ae557116100b0578063a25ae557146103f0578063a8e4fb901461044c578063bffa7f0f1461047957600080fd5b806389c44cbb1461038a57806393991af3146103aa5780639aaab648146103dd57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa51461033e5780637f00642014610354578063887862721461037457600080fd5b806369f16eec146102e95780636abcf563146102fe5780636b4d98dd1461031357600080fd5b8063529933df11610169578063529933df1461020d578063534db0e21461024157806354fd4d501461029357600080fd5b80622134cc1461018f578063019e2729146101d65780634599c788146101f8575b600080fd5b34801561019b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101e257600080fd5b506101f66101f136600461131c565b610593565b005b34801561020457600080fd5b506101c36107f2565b34801561021957600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561024d57600080fd5b5060045461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cd565b34801561029f57600080fd5b506102dc6040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101cd9190611362565b3480156102f557600080fd5b506101c3610865565b34801561030a57600080fd5b506003546101c3565b34801561031f57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1661026e565b34801561034a57600080fd5b506101c360015481565b34801561036057600080fd5b506101c361036f3660046113d5565b610877565b34801561038057600080fd5b506101c360025481565b34801561039657600080fd5b506101f66103a53660046113d5565b610a8b565b3480156103b657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b6101f66103eb3660046113ee565b610d43565b3480156103fc57600080fd5b5061041061040b3660046113d5565b6111a4565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101cd565b34801561045857600080fd5b5060055461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561048557600080fd5b5060055473ffffffffffffffffffffffffffffffffffffffff1661026e565b3480156104b057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b3480156104e357600080fd5b506104106104f23660046113d5565b611238565b34801561050357600080fd5b506101c36105123660046113d5565b611270565b34801561052357600080fd5b506101c36112be565b34801561053857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b34801561056b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b600054600390610100900460ff161580156105b5575060005460ff8083169116105b610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790554284111561072e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161063d565b600284905560018590556005805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556004805492851692909116919091179055600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6003546000901561085c576003805461080d9060019061144f565b8154811061081d5761081d611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b6003546000906108609060019061144f565b60006108816107f2565b821115610936576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546109eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546000905b80821015610a845760006002610a088385611495565b610a1291906114ad565b90508460038281548110610a2857610a28611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610a7a57610a73816001611495565b9250610a7e565b8091505b506109f2565b5092915050565b60045473ffffffffffffffffffffffffffffffffffffffff163314610b32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161063d565b6003548110610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b7f000000000000000000000000000000000000000000000000000000000000000060038281548110610c1d57610c1d611466565b6000918252602090912060016002909202010154610c4d906fffffffffffffffffffffffffffffffff164261144f565b10610d00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161063d565b6000610d0b60035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60055473ffffffffffffffffffffffffffffffffffffffff163314610e10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b610e186112be565b8314610ecc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161063d565b42610ed684611270565b10610f63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161063d565b83610ff0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161063d565b81156110ac57818140146110ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161063d565b826110b660035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2426040516110e891815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b6040805160608101825260008082526020820181905291810191909152600382815481106111d4576111d4611466565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b6040805160608101825260008082526020820181905291810191909152600361126083610877565b815481106111d4576111d4611466565b60007f0000000000000000000000000000000000000000000000000000000000000000600154836112a1919061144f565b6112ab91906114e8565b6002546112b89190611495565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006112e96107f2565b6108609190611495565b803573ffffffffffffffffffffffffffffffffffffffff8116811461131757600080fd5b919050565b6000806000806080858703121561133257600080fd5b8435935060208501359250611349604086016112f3565b9150611357606086016112f3565b905092959194509250565b600060208083528351808285015260005b8181101561138f57858101830151858201604001528201611373565b818111156113a1576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156113e757600080fd5b5035919050565b6000806000806080858703121561140457600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561146157611461611420565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082198211156114a8576114a8611420565b500190565b6000826114e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561152057611520611420565b50029056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"CHALLENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L2_BLOCK_TIME\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PROPOSER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"SUBMISSION_INTERVAL\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"challenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"computeL2Timestamp\",\"inputs\":[{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deleteL2Outputs\",\"inputs\":[{\"name\":\"_l2OutputIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"finalizationPeriodSeconds\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL2Output\",\"inputs\":[{\"name\":\"_l2OutputIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTypes.OutputProposal\",\"components\":[{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"timestamp\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL2OutputAfter\",\"inputs\":[{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTypes.OutputProposal\",\"components\":[{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"timestamp\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL2OutputIndexAfter\",\"inputs\":[{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_submissionInterval\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_l2BlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_startingBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_startingTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_proposer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_challenger\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_finalizationPeriodSeconds\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l2BlockTime\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"latestBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"latestOutputIndex\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nextBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nextOutputIndex\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposeL2Output\",\"inputs\":[{\"name\":\"_outputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_l1BlockHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_l1BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"proposer\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"startingBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"startingTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"submissionInterval\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OutputProposed\",\"inputs\":[{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"l2OutputIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"l1Timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OutputsDeleted\",\"inputs\":[{\"name\":\"prevNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"newNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b50620000256001806000808080806200002b565b62000328565b600054610100900460ff16158080156200004c5750600054600160ff909116105b806200007c575062000069306200031960201b6200135d1760201c565b1580156200007c575060005460ff166001145b620000e55760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000109576000805461ff0019166101001790555b60008811620001815760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e20300000000000006064820152608401620000dc565b60008711620001f95760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e20300000000000000000000000006064820152608401620000dc565b428511156200027f5760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401620000dc565b6004889055600587905560018690556002859055600780546001600160a01b038087166001600160a01b0319928316179092556006805492861692909116919091179055600882905580156200030f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6001600160a01b03163b151590565b6115d580620003386000396000f3fe60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a", } // L2OutputOracleABI is the input ABI used to generate the binding from. @@ -50,7 +50,7 @@ var L2OutputOracleABI = L2OutputOracleMetaData.ABI var L2OutputOracleBin = L2OutputOracleMetaData.Bin // DeployL2OutputOracle deploys a new Ethereum contract, binding an instance of L2OutputOracle to it. -func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend, _submissionInterval *big.Int, _l2BlockTime *big.Int, _finalizationPeriodSeconds *big.Int) (common.Address, *types.Transaction, *L2OutputOracle, error) { +func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *L2OutputOracle, error) { parsed, err := L2OutputOracleMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -59,7 +59,7 @@ func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend, return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2OutputOracleBin), backend, _submissionInterval, _l2BlockTime, _finalizationPeriodSeconds) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2OutputOracleBin), backend) if err != nil { return common.Address{}, nil, nil, err } @@ -880,25 +880,25 @@ func (_L2OutputOracle *L2OutputOracleTransactorSession) DeleteL2Outputs(_l2Outpu return _L2OutputOracle.Contract.DeleteL2Outputs(&_L2OutputOracle.TransactOpts, _l2OutputIndex) } -// Initialize is a paid mutator transaction binding the contract method 0x019e2729. +// Initialize is a paid mutator transaction binding the contract method 0x1c89c97d. // -// Solidity: function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp, address _proposer, address _challenger) returns() -func (_L2OutputOracle *L2OutputOracleTransactor) Initialize(opts *bind.TransactOpts, _startingBlockNumber *big.Int, _startingTimestamp *big.Int, _proposer common.Address, _challenger common.Address) (*types.Transaction, error) { - return _L2OutputOracle.contract.Transact(opts, "initialize", _startingBlockNumber, _startingTimestamp, _proposer, _challenger) +// Solidity: function initialize(uint256 _submissionInterval, uint256 _l2BlockTime, uint256 _startingBlockNumber, uint256 _startingTimestamp, address _proposer, address _challenger, uint256 _finalizationPeriodSeconds) returns() +func (_L2OutputOracle *L2OutputOracleTransactor) Initialize(opts *bind.TransactOpts, _submissionInterval *big.Int, _l2BlockTime *big.Int, _startingBlockNumber *big.Int, _startingTimestamp *big.Int, _proposer common.Address, _challenger common.Address, _finalizationPeriodSeconds *big.Int) (*types.Transaction, error) { + return _L2OutputOracle.contract.Transact(opts, "initialize", _submissionInterval, _l2BlockTime, _startingBlockNumber, _startingTimestamp, _proposer, _challenger, _finalizationPeriodSeconds) } -// Initialize is a paid mutator transaction binding the contract method 0x019e2729. +// Initialize is a paid mutator transaction binding the contract method 0x1c89c97d. // -// Solidity: function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp, address _proposer, address _challenger) returns() -func (_L2OutputOracle *L2OutputOracleSession) Initialize(_startingBlockNumber *big.Int, _startingTimestamp *big.Int, _proposer common.Address, _challenger common.Address) (*types.Transaction, error) { - return _L2OutputOracle.Contract.Initialize(&_L2OutputOracle.TransactOpts, _startingBlockNumber, _startingTimestamp, _proposer, _challenger) +// Solidity: function initialize(uint256 _submissionInterval, uint256 _l2BlockTime, uint256 _startingBlockNumber, uint256 _startingTimestamp, address _proposer, address _challenger, uint256 _finalizationPeriodSeconds) returns() +func (_L2OutputOracle *L2OutputOracleSession) Initialize(_submissionInterval *big.Int, _l2BlockTime *big.Int, _startingBlockNumber *big.Int, _startingTimestamp *big.Int, _proposer common.Address, _challenger common.Address, _finalizationPeriodSeconds *big.Int) (*types.Transaction, error) { + return _L2OutputOracle.Contract.Initialize(&_L2OutputOracle.TransactOpts, _submissionInterval, _l2BlockTime, _startingBlockNumber, _startingTimestamp, _proposer, _challenger, _finalizationPeriodSeconds) } -// Initialize is a paid mutator transaction binding the contract method 0x019e2729. +// Initialize is a paid mutator transaction binding the contract method 0x1c89c97d. // -// Solidity: function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp, address _proposer, address _challenger) returns() -func (_L2OutputOracle *L2OutputOracleTransactorSession) Initialize(_startingBlockNumber *big.Int, _startingTimestamp *big.Int, _proposer common.Address, _challenger common.Address) (*types.Transaction, error) { - return _L2OutputOracle.Contract.Initialize(&_L2OutputOracle.TransactOpts, _startingBlockNumber, _startingTimestamp, _proposer, _challenger) +// Solidity: function initialize(uint256 _submissionInterval, uint256 _l2BlockTime, uint256 _startingBlockNumber, uint256 _startingTimestamp, address _proposer, address _challenger, uint256 _finalizationPeriodSeconds) returns() +func (_L2OutputOracle *L2OutputOracleTransactorSession) Initialize(_submissionInterval *big.Int, _l2BlockTime *big.Int, _startingBlockNumber *big.Int, _startingTimestamp *big.Int, _proposer common.Address, _challenger common.Address, _finalizationPeriodSeconds *big.Int) (*types.Transaction, error) { + return _L2OutputOracle.Contract.Initialize(&_L2OutputOracle.TransactOpts, _submissionInterval, _l2BlockTime, _startingBlockNumber, _startingTimestamp, _proposer, _challenger, _finalizationPeriodSeconds) } // ProposeL2Output is a paid mutator transaction binding the contract method 0x9aaab648. diff --git a/op-bindings/bindings/l2outputoracle_more.go b/op-bindings/bindings/l2outputoracle_more.go index ef124a186670..361430a161e7 100644 --- a/op-bindings/bindings/l2outputoracle_more.go +++ b/op-bindings/bindings/l2outputoracle_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const L2OutputOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"startingBlockNumber\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1003,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"startingTimestamp\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":1004,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"l2Outputs\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_struct(OutputProposal)1007_storage)dyn_storage\"},{\"astId\":1005,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"challenger\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_address\"},{\"astId\":1006,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"proposer\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_struct(OutputProposal)1007_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct Types.OutputProposal[]\",\"numberOfBytes\":\"32\",\"base\":\"t_struct(OutputProposal)1007_storage\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_struct(OutputProposal)1007_storage\":{\"encoding\":\"inplace\",\"label\":\"struct Types.OutputProposal\",\"numberOfBytes\":\"64\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const L2OutputOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"startingBlockNumber\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1003,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"startingTimestamp\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":1004,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"l2Outputs\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_struct(OutputProposal)1010_storage)dyn_storage\"},{\"astId\":1005,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"submissionInterval\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_uint256\"},{\"astId\":1006,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"l2BlockTime\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_uint256\"},{\"astId\":1007,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"challenger\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_address\"},{\"astId\":1008,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"proposer\",\"offset\":0,\"slot\":\"7\",\"type\":\"t_address\"},{\"astId\":1009,\"contract\":\"src/L1/L2OutputOracle.sol:L2OutputOracle\",\"label\":\"finalizationPeriodSeconds\",\"offset\":0,\"slot\":\"8\",\"type\":\"t_uint256\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_struct(OutputProposal)1010_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct Types.OutputProposal[]\",\"numberOfBytes\":\"32\",\"base\":\"t_struct(OutputProposal)1010_storage\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_struct(OutputProposal)1010_storage\":{\"encoding\":\"inplace\",\"label\":\"struct Types.OutputProposal\",\"numberOfBytes\":\"64\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var L2OutputOracleStorageLayout = new(solc.StorageLayout) -var L2OutputOracleDeployedBin = "0x60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec334814610517578063e1a41bcf1461052c578063f4daa2911461055f57600080fd5b8063ce5db8d6146104a4578063cf8e5cf0146104d7578063d1de856c146104f757600080fd5b8063a25ae557116100b0578063a25ae557146103f0578063a8e4fb901461044c578063bffa7f0f1461047957600080fd5b806389c44cbb1461038a57806393991af3146103aa5780639aaab648146103dd57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa51461033e5780637f00642014610354578063887862721461037457600080fd5b806369f16eec146102e95780636abcf563146102fe5780636b4d98dd1461031357600080fd5b8063529933df11610169578063529933df1461020d578063534db0e21461024157806354fd4d501461029357600080fd5b80622134cc1461018f578063019e2729146101d65780634599c788146101f8575b600080fd5b34801561019b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101e257600080fd5b506101f66101f136600461131c565b610593565b005b34801561020457600080fd5b506101c36107f2565b34801561021957600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561024d57600080fd5b5060045461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cd565b34801561029f57600080fd5b506102dc6040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101cd9190611362565b3480156102f557600080fd5b506101c3610865565b34801561030a57600080fd5b506003546101c3565b34801561031f57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1661026e565b34801561034a57600080fd5b506101c360015481565b34801561036057600080fd5b506101c361036f3660046113d5565b610877565b34801561038057600080fd5b506101c360025481565b34801561039657600080fd5b506101f66103a53660046113d5565b610a8b565b3480156103b657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b6101f66103eb3660046113ee565b610d43565b3480156103fc57600080fd5b5061041061040b3660046113d5565b6111a4565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101cd565b34801561045857600080fd5b5060055461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561048557600080fd5b5060055473ffffffffffffffffffffffffffffffffffffffff1661026e565b3480156104b057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b3480156104e357600080fd5b506104106104f23660046113d5565b611238565b34801561050357600080fd5b506101c36105123660046113d5565b611270565b34801561052357600080fd5b506101c36112be565b34801561053857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b34801561056b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b600054600390610100900460ff161580156105b5575060005460ff8083169116105b610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790554284111561072e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161063d565b600284905560018590556005805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556004805492851692909116919091179055600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6003546000901561085c576003805461080d9060019061144f565b8154811061081d5761081d611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b6003546000906108609060019061144f565b60006108816107f2565b821115610936576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546109eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546000905b80821015610a845760006002610a088385611495565b610a1291906114ad565b90508460038281548110610a2857610a28611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610a7a57610a73816001611495565b9250610a7e565b8091505b506109f2565b5092915050565b60045473ffffffffffffffffffffffffffffffffffffffff163314610b32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161063d565b6003548110610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b7f000000000000000000000000000000000000000000000000000000000000000060038281548110610c1d57610c1d611466565b6000918252602090912060016002909202010154610c4d906fffffffffffffffffffffffffffffffff164261144f565b10610d00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161063d565b6000610d0b60035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60055473ffffffffffffffffffffffffffffffffffffffff163314610e10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b610e186112be565b8314610ecc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161063d565b42610ed684611270565b10610f63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161063d565b83610ff0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161063d565b81156110ac57818140146110ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161063d565b826110b660035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2426040516110e891815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b6040805160608101825260008082526020820181905291810191909152600382815481106111d4576111d4611466565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b6040805160608101825260008082526020820181905291810191909152600361126083610877565b815481106111d4576111d4611466565b60007f0000000000000000000000000000000000000000000000000000000000000000600154836112a1919061144f565b6112ab91906114e8565b6002546112b89190611495565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006112e96107f2565b6108609190611495565b803573ffffffffffffffffffffffffffffffffffffffff8116811461131757600080fd5b919050565b6000806000806080858703121561133257600080fd5b8435935060208501359250611349604086016112f3565b9150611357606086016112f3565b905092959194509250565b600060208083528351808285015260005b8181101561138f57858101830151858201604001528201611373565b818111156113a1576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156113e757600080fd5b5035919050565b6000806000806080858703121561140457600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561146157611461611420565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082198211156114a8576114a8611420565b500190565b6000826114e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561152057611520611420565b50029056fea164736f6c634300080f000a" +var L2OutputOracleDeployedBin = "0x60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L2OutputOracleStorageLayoutJSON), L2OutputOracleStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["L2OutputOracle"] = L2OutputOracleStorageLayout deployedBytecodes["L2OutputOracle"] = L2OutputOracleDeployedBin + immutableReferences["L2OutputOracle"] = false } diff --git a/op-bindings/bindings/l2standardbridge.go b/op-bindings/bindings/l2standardbridge.go index 4e12122873ee..8a935e961a7f 100644 --- a/op-bindings/bindings/l2standardbridge.go +++ b/op-bindings/bindings/l2standardbridge.go @@ -30,8 +30,8 @@ var ( // L2StandardBridgeMetaData contains all meta data concerning the L2StandardBridge contract. var L2StandardBridgeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"_otherBridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"DepositFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"WithdrawalInitiated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeDeposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1TokenBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162002c8538038062002c858339810160408190526200003491620001e4565b6001600160a01b0381166080526200004b62000052565b5062000216565b600054600390610100900460ff1615801562000075575060005460ff8083169116105b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff8316176101001790556200011173420000000000000000000000000000000000000762000155565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b600054610100900460ff16620001c25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600060208284031215620001f757600080fd5b81516001600160a01b03811681146200020f57600080fd5b9392505050565b608051612a30620002556000396000818161024e015281816103600152818161058e01528181610a230152818161134001526116820152612a306000f3fe6080604052600436106101125760003560e01c8063662a633a116100a55780638f601f6611610074578063a3a7954811610059578063a3a7954814610428578063c89701a21461023f578063e11013dd1461043b57600080fd5b80638f601f66146103b7578063927ede2d146103fd57600080fd5b8063662a633a1461033b5780637f46ddb21461034e5780638129fc1c14610382578063870876231461039757600080fd5b806336c717c1116100e157806336c717c11461023f5780633cb747bf14610298578063540abf73146102c557806354fd4d50146102e557600080fd5b80630166a07a146101e657806309fc8843146102065780631635f5fd1461021957806332b7006d1461022c57600080fd5b366101e157333b156101ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101df73deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d406040518060200160405280600081525061044e565b005b600080fd5b3480156101f257600080fd5b506101df610201366004612440565b610529565b6101df6102143660046124f1565b6108e7565b6101df610227366004612544565b6109be565b6101df61023a3660046125b7565b610e2c565b34801561024b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102a457600080fd5b5060035461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102d157600080fd5b506101df6102e036600461260b565b610f06565b3480156102f157600080fd5b5061032e6040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b60405161028f91906126f8565b6101df610349366004612440565b610f4b565b34801561035a57600080fd5b5061026e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561038e57600080fd5b506101df610fbe565b3480156103a357600080fd5b506101df6103b236600461270b565b61111b565b3480156103c357600080fd5b506103ef6103d236600461278e565b600260209081526000928352604080842090915290825290205481565b60405190815260200161028f565b34801561040957600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff1661026e565b6101df61043636600461270b565b6111ef565b6101df6104493660046127c7565b611233565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff87160161049d57610498858585858561127c565b610521565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050e919061282a565b905061051f87828888888888611462565b505b505050505050565b60035473ffffffffffffffffffffffffffffffffffffffff16331480156106185750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa1580156105dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610600919061282a565b73ffffffffffffffffffffffffffffffffffffffff16145b6106ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101a2565b6106d3876117aa565b15610821576106e2878761180c565b610794576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101a2565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b15801561080457600080fd5b505af1158015610818573d6000803e3d6000fd5b505050506108a3565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461085f908490612876565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c16835293905291909120919091556108a390858561192c565b61051f878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a0092505050565b333b15610976576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101a2565b6109b93333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061127c92505050565b505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610aad5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa158015610a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a95919061282a565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101a2565b823414610bee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101a2565b3073ffffffffffffffffffffffffffffffffffffffff851603610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101a2565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101a2565b610d8085858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a8e92505050565b6000610d9d855a8660405180602001604052806000815250611b2f565b905080610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101a2565b333b15610ebb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101a2565b610eff853333878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061044e92505050565b5050505050565b61051f87873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146292505050565b73ffffffffffffffffffffffffffffffffffffffff8716158015610f98575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b15610faf57610faa85858585856109be565b61051f565b61051f86888787878787610529565b600054600390610100900460ff16158015610fe0575060005460ff8083169116105b61106c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101a2565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556110ba734200000000000000000000000000000000000007611b49565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b333b156111aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101a2565b61052186863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146292505050565b610521863387878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061044e92505050565b6112763385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061127c92505050565b50505050565b82341461130b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101a2565b61131785858584611c27565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b9085907f0000000000000000000000000000000000000000000000000000000000000000907f1635f5fd0000000000000000000000000000000000000000000000000000000090611396908b908b9086908a9060240161288d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b9092168252611429929188906004016128d6565b6000604051808303818588803b15801561144257600080fd5b505af1158015611456573d6000803e3d6000fd5b50505050505050505050565b61146b876117aa565b156115b95761147a878761180c565b61152c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101a2565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561159c57600080fd5b505af11580156115b0573d6000803e3d6000fd5b5050505061164d565b6115db73ffffffffffffffffffffffffffffffffffffffff8816863086611cc8565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461161990849061291b565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b61165b878787878786611d26565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b907f0000000000000000000000000000000000000000000000000000000000000000907f0166a07a00000000000000000000000000000000000000000000000000000000906116dc908b908d908c908c908c908b90602401612933565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b909216825261176f929187906004016128d6565b600060405180830381600087803b15801561178957600080fd5b505af115801561179d573d6000803e3d6000fd5b5050505050505050505050565b60006117d6827f1d1d8b6300000000000000000000000000000000000000000000000000000000611db4565b806118065750611806827fec4fc8e300000000000000000000000000000000000000000000000000000000611db4565b92915050565b6000611838837f1d1d8b6300000000000000000000000000000000000000000000000000000000611db4565b156118e1578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611888573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ac919061282a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611806565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611888573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109b99084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611dd7565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611a789392919061298e565b60405180910390a4610521868686868686611ee3565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611b1b9392919061298e565b60405180910390a461127684848484611f6b565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16611be0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101a2565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611cb49392919061298e565b60405180910390a461127684848484611fd8565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112769085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161197e565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611d9e9392919061298e565b60405180910390a4610521868686868686612037565b6000611dbf836120af565b8015611dd05750611dd08383612113565b9392505050565b6000611e39826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121e29092919063ffffffff16565b8051909150156109b95780806020019051810190611e5791906129cc565b6109b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101a2565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611f5b9392919061298e565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611fca9291906129ee565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611fca9291906129ee565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611f5b9392919061298e565b60006120db827f01ffc9a700000000000000000000000000000000000000000000000000000000612113565b8015611806575061210c827fffffffff00000000000000000000000000000000000000000000000000000000612113565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156121cb575060208210155b80156121d75750600081115b979650505050505050565b60606121f184846000856121f9565b949350505050565b60608247101561228b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101a2565b73ffffffffffffffffffffffffffffffffffffffff85163b612309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101a2565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516123329190612a07565b60006040518083038185875af1925050503d806000811461236f576040519150601f19603f3d011682016040523d82523d6000602084013e612374565b606091505b50915091506121d78282866060831561238e575081611dd0565b82511561239e5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a291906126f8565b73ffffffffffffffffffffffffffffffffffffffff811681146123f457600080fd5b50565b60008083601f84011261240957600080fd5b50813567ffffffffffffffff81111561242157600080fd5b60208301915083602082850101111561243957600080fd5b9250929050565b600080600080600080600060c0888a03121561245b57600080fd5b8735612466816123d2565b96506020880135612476816123d2565b95506040880135612486816123d2565b94506060880135612496816123d2565b93506080880135925060a088013567ffffffffffffffff8111156124b957600080fd5b6124c58a828b016123f7565b989b979a50959850939692959293505050565b803563ffffffff811681146124ec57600080fd5b919050565b60008060006040848603121561250657600080fd5b61250f846124d8565b9250602084013567ffffffffffffffff81111561252b57600080fd5b612537868287016123f7565b9497909650939450505050565b60008060008060006080868803121561255c57600080fd5b8535612567816123d2565b94506020860135612577816123d2565b935060408601359250606086013567ffffffffffffffff81111561259a57600080fd5b6125a6888289016123f7565b969995985093965092949392505050565b6000806000806000608086880312156125cf57600080fd5b85356125da816123d2565b9450602086013593506125ef604087016124d8565b9250606086013567ffffffffffffffff81111561259a57600080fd5b600080600080600080600060c0888a03121561262657600080fd5b8735612631816123d2565b96506020880135612641816123d2565b95506040880135612651816123d2565b945060608801359350612666608089016124d8565b925060a088013567ffffffffffffffff8111156124b957600080fd5b60005b8381101561269d578181015183820152602001612685565b838111156112765750506000910152565b600081518084526126c6816020860160208601612682565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611dd060208301846126ae565b60008060008060008060a0878903121561272457600080fd5b863561272f816123d2565b9550602087013561273f816123d2565b945060408701359350612754606088016124d8565b9250608087013567ffffffffffffffff81111561277057600080fd5b61277c89828a016123f7565b979a9699509497509295939492505050565b600080604083850312156127a157600080fd5b82356127ac816123d2565b915060208301356127bc816123d2565b809150509250929050565b600080600080606085870312156127dd57600080fd5b84356127e8816123d2565b93506127f6602086016124d8565b9250604085013567ffffffffffffffff81111561281257600080fd5b61281e878288016123f7565b95989497509550505050565b60006020828403121561283c57600080fd5b8151611dd0816123d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561288857612888612847565b500390565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128cc60808301846126ae565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061290560608301856126ae565b905063ffffffff83166040830152949350505050565b6000821982111561292e5761292e612847565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261298260c08301846126ae565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006129c360608301846126ae565b95945050505050565b6000602082840312156129de57600080fd5b81518015158114611dd057600080fd5b8281526040602082015260006121f160408301846126ae565b60008251612a19818460208701612682565b919091019291505056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"bridgeERC20\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bridgeERC20To\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bridgeETH\",\"inputs\":[{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"bridgeETHTo\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"deposits\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"finalizeBridgeERC20\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"finalizeBridgeETH\",\"inputs\":[{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"finalizeDeposit\",\"inputs\":[{\"name\":\"_l1Token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_l2Token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_otherBridge\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l1TokenBridge\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"messenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"otherBridge\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"_l2Token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"withdrawTo\",\"inputs\":[{\"name\":\"_l2Token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"DepositFinalized\",\"inputs\":[{\"name\":\"l1Token\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"l2Token\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ERC20BridgeFinalized\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ERC20BridgeInitiated\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ETHBridgeFinalized\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ETHBridgeInitiated\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalInitiated\",\"inputs\":[{\"name\":\"l1Token\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"l2Token\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b506200001e600062000024565b62000217565b600054610100900460ff1615808015620000455750600054600160ff909116105b8062000075575062000062306200016d60201b620004811760201c565b15801562000075575060005460ff166001145b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000102576000805461ff0019166101001790555b62000122734200000000000000000000000000000000000007836200017c565b801562000169576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff16620001e95760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d5565b600380546001600160a01b039384166001600160a01b03199182161790915560048054929093169116179055565b612a8380620002276000396000f3fe60806040526004361061012d5760003560e01c8063662a633a116100a5578063927ede2d11610074578063c4d66de811610059578063c4d66de814610421578063c89701a214610441578063e11013dd1461046e57600080fd5b8063927ede2d146103e3578063a3a795481461040e57600080fd5b8063662a633a1461036a5780637f46ddb21461025a578063870876231461037d5780638f601f661461039d57600080fd5b806336c717c1116100fc578063540abf73116100e1578063540abf73146102d857806354fd4d50146102f85780635c975abb1461034e57600080fd5b806336c717c11461025a5780633cb747bf146102ab57600080fd5b80630166a07a1461020157806309fc8843146102215780631635f5fd1461023457806332b7006d1461024757600080fd5b366101fc57333b156101c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101fa73deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d406040518060200160405280600081525061049d565b005b600080fd5b34801561020d57600080fd5b506101fa61021c366004612476565b610578565b6101fa61022f366004612527565b61091a565b6101fa61024236600461257a565b6109f1565b6101fa6102553660046125ed565b610e43565b34801561026657600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102b757600080fd5b506003546102819073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102e457600080fd5b506101fa6102f3366004612641565b610f1d565b34801561030457600080fd5b506103416040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516102a2919061272e565b34801561035a57600080fd5b50604051600081526020016102a2565b6101fa610378366004612476565b610f62565b34801561038957600080fd5b506101fa610398366004612741565b610fd5565b3480156103a957600080fd5b506103d56103b83660046127c4565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102a2565b3480156103ef57600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff16610281565b6101fa61041c366004612741565b6110a9565b34801561042d57600080fd5b506101fa61043c3660046127fd565b6110ed565b34801561044d57600080fd5b506004546102819073ffffffffffffffffffffffffffffffffffffffff1681565b6101fa61047c36600461281a565b611296565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff8716016104ec576104e785858585856112df565b610570565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610539573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055d919061287d565b905061056e878288888888886114a9565b505b505050505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314801561064b575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa15801561060f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610633919061287d565b73ffffffffffffffffffffffffffffffffffffffff16145b6106fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b610706876117d4565b15610854576107158787611836565b6107c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101bd565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b505050506108d6565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a16835292905220546108929084906128c9565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c16835293905291909120919091556108d6908585611956565b61056e878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a2a92505050565b333b156109a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b6109ec3333348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112df92505050565b505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610ac4575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aac919061287d565b73ffffffffffffffffffffffffffffffffffffffff16145b610b76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b823414610c05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101bd565b3073ffffffffffffffffffffffffffffffffffffffff851603610caa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101bd565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101bd565b610d9785858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ab892505050565b6000610db4855a8660405180602001604052806000815250611b59565b905080610570576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101bd565b333b15610ed2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b610f16853333878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061049d92505050565b5050505050565b61056e87873388888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506114a992505050565b73ffffffffffffffffffffffffffffffffffffffff8716158015610faf575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b15610fc657610fc185858585856109f1565b61056e565b61056e86888787878787610578565b333b15611064576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b61057086863333888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506114a992505050565b610570863387878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061049d92505050565b600054610100900460ff161580801561110d5750600054600160ff909116105b806111275750303b158015611127575060005460ff166001145b6111b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101bd565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561121157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61122f73420000000000000000000000000000000000000783611b73565b801561129257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6112d93385348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112df92505050565b50505050565b82341461136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101bd565b61137a85858584611c5d565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd00000000000000000000000000000000000000000000000000000000906113dd908b908b9086908a906024016128e0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261147092918890600401612929565b6000604051808303818588803b15801561148957600080fd5b505af115801561149d573d6000803e3d6000fd5b50505050505050505050565b6114b2876117d4565b15611600576114c18787611836565b611573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101bd565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b1580156115e357600080fd5b505af11580156115f7573d6000803e3d6000fd5b50505050611694565b61162273ffffffffffffffffffffffffffffffffffffffff8816863086611cfe565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461166090849061296e565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b6116a2878787878786611d5c565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611706908b908d908c908c908c908b90602401612986565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b909216825261179992918790600401612929565b600060405180830381600087803b1580156117b357600080fd5b505af11580156117c7573d6000803e3d6000fd5b5050505050505050505050565b6000611800827f1d1d8b6300000000000000000000000000000000000000000000000000000000611dea565b806118305750611830827fec4fc8e300000000000000000000000000000000000000000000000000000000611dea565b92915050565b6000611862837f1d1d8b6300000000000000000000000000000000000000000000000000000000611dea565b1561190b578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d6919061287d565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611830565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118b2573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109ec9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611e0d565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611aa2939291906129e1565b60405180910390a4610570868686868686611f19565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611b45939291906129e1565b60405180910390a46112d984848484611fa1565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16611c0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101bd565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611cea939291906129e1565b60405180910390a46112d98484848461200e565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112d99085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016119a8565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611dd4939291906129e1565b60405180910390a461057086868686868661206d565b6000611df5836120e5565b8015611e065750611e068383612149565b9392505050565b6000611e6f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122189092919063ffffffff16565b8051909150156109ec5780806020019051810190611e8d9190612a1f565b6109ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101bd565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611f91939291906129e1565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051612000929190612a41565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051612000929190612a41565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611f91939291906129e1565b6000612111827f01ffc9a700000000000000000000000000000000000000000000000000000000612149565b80156118305750612142827fffffffff00000000000000000000000000000000000000000000000000000000612149565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015612201575060208210155b801561220d5750600081115b979650505050505050565b6060612227848460008561222f565b949350505050565b6060824710156122c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101bd565b73ffffffffffffffffffffffffffffffffffffffff85163b61233f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101bd565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516123689190612a5a565b60006040518083038185875af1925050503d80600081146123a5576040519150601f19603f3d011682016040523d82523d6000602084013e6123aa565b606091505b509150915061220d828286606083156123c4575081611e06565b8251156123d45782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101bd919061272e565b73ffffffffffffffffffffffffffffffffffffffff8116811461242a57600080fd5b50565b60008083601f84011261243f57600080fd5b50813567ffffffffffffffff81111561245757600080fd5b60208301915083602082850101111561246f57600080fd5b9250929050565b600080600080600080600060c0888a03121561249157600080fd5b873561249c81612408565b965060208801356124ac81612408565b955060408801356124bc81612408565b945060608801356124cc81612408565b93506080880135925060a088013567ffffffffffffffff8111156124ef57600080fd5b6124fb8a828b0161242d565b989b979a50959850939692959293505050565b803563ffffffff8116811461252257600080fd5b919050565b60008060006040848603121561253c57600080fd5b6125458461250e565b9250602084013567ffffffffffffffff81111561256157600080fd5b61256d8682870161242d565b9497909650939450505050565b60008060008060006080868803121561259257600080fd5b853561259d81612408565b945060208601356125ad81612408565b935060408601359250606086013567ffffffffffffffff8111156125d057600080fd5b6125dc8882890161242d565b969995985093965092949392505050565b60008060008060006080868803121561260557600080fd5b853561261081612408565b9450602086013593506126256040870161250e565b9250606086013567ffffffffffffffff8111156125d057600080fd5b600080600080600080600060c0888a03121561265c57600080fd5b873561266781612408565b9650602088013561267781612408565b9550604088013561268781612408565b94506060880135935061269c6080890161250e565b925060a088013567ffffffffffffffff8111156124ef57600080fd5b60005b838110156126d35781810151838201526020016126bb565b838111156112d95750506000910152565b600081518084526126fc8160208601602086016126b8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611e0660208301846126e4565b60008060008060008060a0878903121561275a57600080fd5b863561276581612408565b9550602087013561277581612408565b94506040870135935061278a6060880161250e565b9250608087013567ffffffffffffffff8111156127a657600080fd5b6127b289828a0161242d565b979a9699509497509295939492505050565b600080604083850312156127d757600080fd5b82356127e281612408565b915060208301356127f281612408565b809150509250929050565b60006020828403121561280f57600080fd5b8135611e0681612408565b6000806000806060858703121561283057600080fd5b843561283b81612408565b93506128496020860161250e565b9250604085013567ffffffffffffffff81111561286557600080fd5b6128718782880161242d565b95989497509550505050565b60006020828403121561288f57600080fd5b8151611e0681612408565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156128db576128db61289a565b500390565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261291f60808301846126e4565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061295860608301856126e4565b905063ffffffff83166040830152949350505050565b600082198211156129815761298161289a565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526129d560c08301846126e4565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612a1660608301846126e4565b95945050505050565b600060208284031215612a3157600080fd5b81518015158114611e0657600080fd5b82815260406020820152600061222760408301846126e4565b60008251612a6c8184602087016126b8565b919091019291505056fea164736f6c634300080f000a", } // L2StandardBridgeABI is the input ABI used to generate the binding from. @@ -43,7 +43,7 @@ var L2StandardBridgeABI = L2StandardBridgeMetaData.ABI var L2StandardBridgeBin = L2StandardBridgeMetaData.Bin // DeployL2StandardBridge deploys a new Ethereum contract, binding an instance of L2StandardBridge to it. -func DeployL2StandardBridge(auth *bind.TransactOpts, backend bind.ContractBackend, _otherBridge common.Address) (common.Address, *types.Transaction, *L2StandardBridge, error) { +func DeployL2StandardBridge(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *L2StandardBridge, error) { parsed, err := L2StandardBridgeMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -52,7 +52,7 @@ func DeployL2StandardBridge(auth *bind.TransactOpts, backend bind.ContractBacken return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2StandardBridgeBin), backend, _otherBridge) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2StandardBridgeBin), backend) if err != nil { return common.Address{}, nil, nil, err } @@ -387,6 +387,37 @@ func (_L2StandardBridge *L2StandardBridgeCallerSession) OtherBridge() (common.Ad return _L2StandardBridge.Contract.OtherBridge(&_L2StandardBridge.CallOpts) } +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L2StandardBridge *L2StandardBridgeCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _L2StandardBridge.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L2StandardBridge *L2StandardBridgeSession) Paused() (bool, error) { + return _L2StandardBridge.Contract.Paused(&_L2StandardBridge.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L2StandardBridge *L2StandardBridgeCallerSession) Paused() (bool, error) { + return _L2StandardBridge.Contract.Paused(&_L2StandardBridge.CallOpts) +} + // Version is a free data retrieval call binding the contract method 0x54fd4d50. // // Solidity: function version() view returns(string) @@ -565,25 +596,25 @@ func (_L2StandardBridge *L2StandardBridgeTransactorSession) FinalizeDeposit(_l1T return _L2StandardBridge.Contract.FinalizeDeposit(&_L2StandardBridge.TransactOpts, _l1Token, _l2Token, _from, _to, _amount, _extraData) } -// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function initialize() returns() -func (_L2StandardBridge *L2StandardBridgeTransactor) Initialize(opts *bind.TransactOpts) (*types.Transaction, error) { - return _L2StandardBridge.contract.Transact(opts, "initialize") +// Solidity: function initialize(address _otherBridge) returns() +func (_L2StandardBridge *L2StandardBridgeTransactor) Initialize(opts *bind.TransactOpts, _otherBridge common.Address) (*types.Transaction, error) { + return _L2StandardBridge.contract.Transact(opts, "initialize", _otherBridge) } -// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function initialize() returns() -func (_L2StandardBridge *L2StandardBridgeSession) Initialize() (*types.Transaction, error) { - return _L2StandardBridge.Contract.Initialize(&_L2StandardBridge.TransactOpts) +// Solidity: function initialize(address _otherBridge) returns() +func (_L2StandardBridge *L2StandardBridgeSession) Initialize(_otherBridge common.Address) (*types.Transaction, error) { + return _L2StandardBridge.Contract.Initialize(&_L2StandardBridge.TransactOpts, _otherBridge) } -// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function initialize() returns() -func (_L2StandardBridge *L2StandardBridgeTransactorSession) Initialize() (*types.Transaction, error) { - return _L2StandardBridge.Contract.Initialize(&_L2StandardBridge.TransactOpts) +// Solidity: function initialize(address _otherBridge) returns() +func (_L2StandardBridge *L2StandardBridgeTransactorSession) Initialize(_otherBridge common.Address) (*types.Transaction, error) { + return _L2StandardBridge.Contract.Initialize(&_L2StandardBridge.TransactOpts, _otherBridge) } // Withdraw is a paid mutator transaction binding the contract method 0x32b7006d. diff --git a/op-bindings/bindings/l2standardbridge_more.go b/op-bindings/bindings/l2standardbridge_more.go index 7ef9a32d886b..dc0a5f0be8ae 100644 --- a/op-bindings/bindings/l2standardbridge_more.go +++ b/op-bindings/bindings/l2standardbridge_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const L2StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_0_2_20\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1003,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1005,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"messenger\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_contract(CrossDomainMessenger)1007\"},{\"astId\":1006,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_array(t_uint256)46_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)46_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[46]\",\"numberOfBytes\":\"1472\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(CrossDomainMessenger)1007\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const L2StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_0_2_30\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_bytes30\"},{\"astId\":1003,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1005,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"messenger\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_contract(CrossDomainMessenger)1008\"},{\"astId\":1006,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"otherBridge\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_contract(StandardBridge)1009\"},{\"astId\":1007,\"contract\":\"src/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_array(t_uint256)45_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)45_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[45]\",\"numberOfBytes\":\"1440\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes30\":{\"encoding\":\"inplace\",\"label\":\"bytes30\",\"numberOfBytes\":\"30\"},\"t_contract(CrossDomainMessenger)1008\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_contract(StandardBridge)1009\":{\"encoding\":\"inplace\",\"label\":\"contract StandardBridge\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var L2StandardBridgeStorageLayout = new(solc.StorageLayout) -var L2StandardBridgeDeployedBin = "0x6080604052600436106101125760003560e01c8063662a633a116100a55780638f601f6611610074578063a3a7954811610059578063a3a7954814610428578063c89701a21461023f578063e11013dd1461043b57600080fd5b80638f601f66146103b7578063927ede2d146103fd57600080fd5b8063662a633a1461033b5780637f46ddb21461034e5780638129fc1c14610382578063870876231461039757600080fd5b806336c717c1116100e157806336c717c11461023f5780633cb747bf14610298578063540abf73146102c557806354fd4d50146102e557600080fd5b80630166a07a146101e657806309fc8843146102065780631635f5fd1461021957806332b7006d1461022c57600080fd5b366101e157333b156101ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101df73deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d406040518060200160405280600081525061044e565b005b600080fd5b3480156101f257600080fd5b506101df610201366004612440565b610529565b6101df6102143660046124f1565b6108e7565b6101df610227366004612544565b6109be565b6101df61023a3660046125b7565b610e2c565b34801561024b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102a457600080fd5b5060035461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102d157600080fd5b506101df6102e036600461260b565b610f06565b3480156102f157600080fd5b5061032e6040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b60405161028f91906126f8565b6101df610349366004612440565b610f4b565b34801561035a57600080fd5b5061026e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561038e57600080fd5b506101df610fbe565b3480156103a357600080fd5b506101df6103b236600461270b565b61111b565b3480156103c357600080fd5b506103ef6103d236600461278e565b600260209081526000928352604080842090915290825290205481565b60405190815260200161028f565b34801561040957600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff1661026e565b6101df61043636600461270b565b6111ef565b6101df6104493660046127c7565b611233565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff87160161049d57610498858585858561127c565b610521565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050e919061282a565b905061051f87828888888888611462565b505b505050505050565b60035473ffffffffffffffffffffffffffffffffffffffff16331480156106185750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa1580156105dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610600919061282a565b73ffffffffffffffffffffffffffffffffffffffff16145b6106ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101a2565b6106d3876117aa565b15610821576106e2878761180c565b610794576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101a2565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b15801561080457600080fd5b505af1158015610818573d6000803e3d6000fd5b505050506108a3565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461085f908490612876565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c16835293905291909120919091556108a390858561192c565b61051f878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a0092505050565b333b15610976576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101a2565b6109b93333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061127c92505050565b505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610aad5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa158015610a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a95919061282a565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101a2565b823414610bee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101a2565b3073ffffffffffffffffffffffffffffffffffffffff851603610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101a2565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101a2565b610d8085858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a8e92505050565b6000610d9d855a8660405180602001604052806000815250611b2f565b905080610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101a2565b333b15610ebb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101a2565b610eff853333878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061044e92505050565b5050505050565b61051f87873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146292505050565b73ffffffffffffffffffffffffffffffffffffffff8716158015610f98575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b15610faf57610faa85858585856109be565b61051f565b61051f86888787878787610529565b600054600390610100900460ff16158015610fe0575060005460ff8083169116105b61106c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101a2565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556110ba734200000000000000000000000000000000000007611b49565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b333b156111aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101a2565b61052186863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146292505050565b610521863387878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061044e92505050565b6112763385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061127c92505050565b50505050565b82341461130b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101a2565b61131785858584611c27565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b9085907f0000000000000000000000000000000000000000000000000000000000000000907f1635f5fd0000000000000000000000000000000000000000000000000000000090611396908b908b9086908a9060240161288d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b9092168252611429929188906004016128d6565b6000604051808303818588803b15801561144257600080fd5b505af1158015611456573d6000803e3d6000fd5b50505050505050505050565b61146b876117aa565b156115b95761147a878761180c565b61152c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101a2565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561159c57600080fd5b505af11580156115b0573d6000803e3d6000fd5b5050505061164d565b6115db73ffffffffffffffffffffffffffffffffffffffff8816863086611cc8565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461161990849061291b565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b61165b878787878786611d26565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b907f0000000000000000000000000000000000000000000000000000000000000000907f0166a07a00000000000000000000000000000000000000000000000000000000906116dc908b908d908c908c908c908b90602401612933565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b909216825261176f929187906004016128d6565b600060405180830381600087803b15801561178957600080fd5b505af115801561179d573d6000803e3d6000fd5b5050505050505050505050565b60006117d6827f1d1d8b6300000000000000000000000000000000000000000000000000000000611db4565b806118065750611806827fec4fc8e300000000000000000000000000000000000000000000000000000000611db4565b92915050565b6000611838837f1d1d8b6300000000000000000000000000000000000000000000000000000000611db4565b156118e1578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611888573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ac919061282a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611806565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611888573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109b99084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611dd7565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611a789392919061298e565b60405180910390a4610521868686868686611ee3565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611b1b9392919061298e565b60405180910390a461127684848484611f6b565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16611be0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101a2565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611cb49392919061298e565b60405180910390a461127684848484611fd8565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112769085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161197e565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611d9e9392919061298e565b60405180910390a4610521868686868686612037565b6000611dbf836120af565b8015611dd05750611dd08383612113565b9392505050565b6000611e39826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121e29092919063ffffffff16565b8051909150156109b95780806020019051810190611e5791906129cc565b6109b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101a2565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611f5b9392919061298e565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611fca9291906129ee565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611fca9291906129ee565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611f5b9392919061298e565b60006120db827f01ffc9a700000000000000000000000000000000000000000000000000000000612113565b8015611806575061210c827fffffffff00000000000000000000000000000000000000000000000000000000612113565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156121cb575060208210155b80156121d75750600081115b979650505050505050565b60606121f184846000856121f9565b949350505050565b60608247101561228b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101a2565b73ffffffffffffffffffffffffffffffffffffffff85163b612309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101a2565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516123329190612a07565b60006040518083038185875af1925050503d806000811461236f576040519150601f19603f3d011682016040523d82523d6000602084013e612374565b606091505b50915091506121d78282866060831561238e575081611dd0565b82511561239e5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a291906126f8565b73ffffffffffffffffffffffffffffffffffffffff811681146123f457600080fd5b50565b60008083601f84011261240957600080fd5b50813567ffffffffffffffff81111561242157600080fd5b60208301915083602082850101111561243957600080fd5b9250929050565b600080600080600080600060c0888a03121561245b57600080fd5b8735612466816123d2565b96506020880135612476816123d2565b95506040880135612486816123d2565b94506060880135612496816123d2565b93506080880135925060a088013567ffffffffffffffff8111156124b957600080fd5b6124c58a828b016123f7565b989b979a50959850939692959293505050565b803563ffffffff811681146124ec57600080fd5b919050565b60008060006040848603121561250657600080fd5b61250f846124d8565b9250602084013567ffffffffffffffff81111561252b57600080fd5b612537868287016123f7565b9497909650939450505050565b60008060008060006080868803121561255c57600080fd5b8535612567816123d2565b94506020860135612577816123d2565b935060408601359250606086013567ffffffffffffffff81111561259a57600080fd5b6125a6888289016123f7565b969995985093965092949392505050565b6000806000806000608086880312156125cf57600080fd5b85356125da816123d2565b9450602086013593506125ef604087016124d8565b9250606086013567ffffffffffffffff81111561259a57600080fd5b600080600080600080600060c0888a03121561262657600080fd5b8735612631816123d2565b96506020880135612641816123d2565b95506040880135612651816123d2565b945060608801359350612666608089016124d8565b925060a088013567ffffffffffffffff8111156124b957600080fd5b60005b8381101561269d578181015183820152602001612685565b838111156112765750506000910152565b600081518084526126c6816020860160208601612682565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611dd060208301846126ae565b60008060008060008060a0878903121561272457600080fd5b863561272f816123d2565b9550602087013561273f816123d2565b945060408701359350612754606088016124d8565b9250608087013567ffffffffffffffff81111561277057600080fd5b61277c89828a016123f7565b979a9699509497509295939492505050565b600080604083850312156127a157600080fd5b82356127ac816123d2565b915060208301356127bc816123d2565b809150509250929050565b600080600080606085870312156127dd57600080fd5b84356127e8816123d2565b93506127f6602086016124d8565b9250604085013567ffffffffffffffff81111561281257600080fd5b61281e878288016123f7565b95989497509550505050565b60006020828403121561283c57600080fd5b8151611dd0816123d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561288857612888612847565b500390565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128cc60808301846126ae565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061290560608301856126ae565b905063ffffffff83166040830152949350505050565b6000821982111561292e5761292e612847565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261298260c08301846126ae565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006129c360608301846126ae565b95945050505050565b6000602082840312156129de57600080fd5b81518015158114611dd057600080fd5b8281526040602082015260006121f160408301846126ae565b60008251612a19818460208701612682565b919091019291505056fea164736f6c634300080f000a" +var L2StandardBridgeDeployedBin = "0x60806040526004361061012d5760003560e01c8063662a633a116100a5578063927ede2d11610074578063c4d66de811610059578063c4d66de814610421578063c89701a214610441578063e11013dd1461046e57600080fd5b8063927ede2d146103e3578063a3a795481461040e57600080fd5b8063662a633a1461036a5780637f46ddb21461025a578063870876231461037d5780638f601f661461039d57600080fd5b806336c717c1116100fc578063540abf73116100e1578063540abf73146102d857806354fd4d50146102f85780635c975abb1461034e57600080fd5b806336c717c11461025a5780633cb747bf146102ab57600080fd5b80630166a07a1461020157806309fc8843146102215780631635f5fd1461023457806332b7006d1461024757600080fd5b366101fc57333b156101c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101fa73deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d406040518060200160405280600081525061049d565b005b600080fd5b34801561020d57600080fd5b506101fa61021c366004612476565b610578565b6101fa61022f366004612527565b61091a565b6101fa61024236600461257a565b6109f1565b6101fa6102553660046125ed565b610e43565b34801561026657600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102b757600080fd5b506003546102819073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102e457600080fd5b506101fa6102f3366004612641565b610f1d565b34801561030457600080fd5b506103416040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516102a2919061272e565b34801561035a57600080fd5b50604051600081526020016102a2565b6101fa610378366004612476565b610f62565b34801561038957600080fd5b506101fa610398366004612741565b610fd5565b3480156103a957600080fd5b506103d56103b83660046127c4565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102a2565b3480156103ef57600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff16610281565b6101fa61041c366004612741565b6110a9565b34801561042d57600080fd5b506101fa61043c3660046127fd565b6110ed565b34801561044d57600080fd5b506004546102819073ffffffffffffffffffffffffffffffffffffffff1681565b6101fa61047c36600461281a565b611296565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff8716016104ec576104e785858585856112df565b610570565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610539573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055d919061287d565b905061056e878288888888886114a9565b505b505050505050565b60035473ffffffffffffffffffffffffffffffffffffffff163314801561064b575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa15801561060f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610633919061287d565b73ffffffffffffffffffffffffffffffffffffffff16145b6106fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b610706876117d4565b15610854576107158787611836565b6107c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101bd565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b505050506108d6565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a16835292905220546108929084906128c9565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c16835293905291909120919091556108d6908585611956565b61056e878787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a2a92505050565b333b156109a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b6109ec3333348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112df92505050565b505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610ac4575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aac919061287d565b73ffffffffffffffffffffffffffffffffffffffff16145b610b76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b823414610c05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101bd565b3073ffffffffffffffffffffffffffffffffffffffff851603610caa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101bd565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101bd565b610d9785858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ab892505050565b6000610db4855a8660405180602001604052806000815250611b59565b905080610570576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101bd565b333b15610ed2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b610f16853333878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061049d92505050565b5050505050565b61056e87873388888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506114a992505050565b73ffffffffffffffffffffffffffffffffffffffff8716158015610faf575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b15610fc657610fc185858585856109f1565b61056e565b61056e86888787878787610578565b333b15611064576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b61057086863333888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506114a992505050565b610570863387878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061049d92505050565b600054610100900460ff161580801561110d5750600054600160ff909116105b806111275750303b158015611127575060005460ff166001145b6111b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101bd565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561121157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61122f73420000000000000000000000000000000000000783611b73565b801561129257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6112d93385348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112df92505050565b50505050565b82341461136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101bd565b61137a85858584611c5d565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd00000000000000000000000000000000000000000000000000000000906113dd908b908b9086908a906024016128e0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261147092918890600401612929565b6000604051808303818588803b15801561148957600080fd5b505af115801561149d573d6000803e3d6000fd5b50505050505050505050565b6114b2876117d4565b15611600576114c18787611836565b611573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101bd565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b1580156115e357600080fd5b505af11580156115f7573d6000803e3d6000fd5b50505050611694565b61162273ffffffffffffffffffffffffffffffffffffffff8816863086611cfe565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461166090849061296e565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b6116a2878787878786611d5c565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611706908b908d908c908c908c908b90602401612986565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b909216825261179992918790600401612929565b600060405180830381600087803b1580156117b357600080fd5b505af11580156117c7573d6000803e3d6000fd5b5050505050505050505050565b6000611800827f1d1d8b6300000000000000000000000000000000000000000000000000000000611dea565b806118305750611830827fec4fc8e300000000000000000000000000000000000000000000000000000000611dea565b92915050565b6000611862837f1d1d8b6300000000000000000000000000000000000000000000000000000000611dea565b1561190b578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d6919061287d565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611830565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118b2573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109ec9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611e0d565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611aa2939291906129e1565b60405180910390a4610570868686868686611f19565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611b45939291906129e1565b60405180910390a46112d984848484611fa1565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16611c0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101bd565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611cea939291906129e1565b60405180910390a46112d98484848461200e565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112d99085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016119a8565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611dd4939291906129e1565b60405180910390a461057086868686868661206d565b6000611df5836120e5565b8015611e065750611e068383612149565b9392505050565b6000611e6f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122189092919063ffffffff16565b8051909150156109ec5780806020019051810190611e8d9190612a1f565b6109ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101bd565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611f91939291906129e1565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051612000929190612a41565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051612000929190612a41565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611f91939291906129e1565b6000612111827f01ffc9a700000000000000000000000000000000000000000000000000000000612149565b80156118305750612142827fffffffff00000000000000000000000000000000000000000000000000000000612149565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015612201575060208210155b801561220d5750600081115b979650505050505050565b6060612227848460008561222f565b949350505050565b6060824710156122c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101bd565b73ffffffffffffffffffffffffffffffffffffffff85163b61233f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101bd565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516123689190612a5a565b60006040518083038185875af1925050503d80600081146123a5576040519150601f19603f3d011682016040523d82523d6000602084013e6123aa565b606091505b509150915061220d828286606083156123c4575081611e06565b8251156123d45782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101bd919061272e565b73ffffffffffffffffffffffffffffffffffffffff8116811461242a57600080fd5b50565b60008083601f84011261243f57600080fd5b50813567ffffffffffffffff81111561245757600080fd5b60208301915083602082850101111561246f57600080fd5b9250929050565b600080600080600080600060c0888a03121561249157600080fd5b873561249c81612408565b965060208801356124ac81612408565b955060408801356124bc81612408565b945060608801356124cc81612408565b93506080880135925060a088013567ffffffffffffffff8111156124ef57600080fd5b6124fb8a828b0161242d565b989b979a50959850939692959293505050565b803563ffffffff8116811461252257600080fd5b919050565b60008060006040848603121561253c57600080fd5b6125458461250e565b9250602084013567ffffffffffffffff81111561256157600080fd5b61256d8682870161242d565b9497909650939450505050565b60008060008060006080868803121561259257600080fd5b853561259d81612408565b945060208601356125ad81612408565b935060408601359250606086013567ffffffffffffffff8111156125d057600080fd5b6125dc8882890161242d565b969995985093965092949392505050565b60008060008060006080868803121561260557600080fd5b853561261081612408565b9450602086013593506126256040870161250e565b9250606086013567ffffffffffffffff8111156125d057600080fd5b600080600080600080600060c0888a03121561265c57600080fd5b873561266781612408565b9650602088013561267781612408565b9550604088013561268781612408565b94506060880135935061269c6080890161250e565b925060a088013567ffffffffffffffff8111156124ef57600080fd5b60005b838110156126d35781810151838201526020016126bb565b838111156112d95750506000910152565b600081518084526126fc8160208601602086016126b8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611e0660208301846126e4565b60008060008060008060a0878903121561275a57600080fd5b863561276581612408565b9550602087013561277581612408565b94506040870135935061278a6060880161250e565b9250608087013567ffffffffffffffff8111156127a657600080fd5b6127b289828a0161242d565b979a9699509497509295939492505050565b600080604083850312156127d757600080fd5b82356127e281612408565b915060208301356127f281612408565b809150509250929050565b60006020828403121561280f57600080fd5b8135611e0681612408565b6000806000806060858703121561283057600080fd5b843561283b81612408565b93506128496020860161250e565b9250604085013567ffffffffffffffff81111561286557600080fd5b6128718782880161242d565b95989497509550505050565b60006020828403121561288f57600080fd5b8151611e0681612408565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156128db576128db61289a565b500390565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261291f60808301846126e4565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061295860608301856126e4565b905063ffffffff83166040830152949350505050565b600082198211156129815761298161289a565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526129d560c08301846126e4565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612a1660608301846126e4565b95945050505050565b600060208284031215612a3157600080fd5b81518015158114611e0657600080fd5b82815260406020820152600061222760408301846126e4565b60008251612a6c8184602087016126b8565b919091019291505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L2StandardBridgeStorageLayoutJSON), L2StandardBridgeStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["L2StandardBridge"] = L2StandardBridgeStorageLayout deployedBytecodes["L2StandardBridge"] = L2StandardBridgeDeployedBin + immutableReferences["L2StandardBridge"] = false } diff --git a/op-bindings/bindings/l2tol1messagepasser.go b/op-bindings/bindings/l2tol1messagepasser.go index ce4a37ae4aa2..cc419d057adf 100644 --- a/op-bindings/bindings/l2tol1messagepasser.go +++ b/op-bindings/bindings/l2tol1messagepasser.go @@ -30,7 +30,7 @@ var ( // L2ToL1MessagePasserMetaData contains all meta data concerning the L2ToL1MessagePasser contract. var L2ToL1MessagePasserMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"}],\"name\":\"MessagePassed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawerBalanceBurnt\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"initiateWithdrawal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"sentMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ABI: "[{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"MESSAGE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"burn\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initiateWithdrawal\",\"inputs\":[{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_gasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"messageNonce\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"sentMessages\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"MessagePassed\",\"inputs\":[{\"name\":\"nonce\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"target\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"gasLimit\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawerBalanceBurnt\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false}]", Bin: "0x608060405234801561001057600080fd5b506106d3806100206000396000f3fe6080604052600436106100695760003560e01c806382e3702d1161004357806382e3702d1461012a578063c2b3e5ac1461016a578063ecc704281461017d57600080fd5b80633f827a5a1461009257806344df8e70146100bf57806354fd4d50146100d457600080fd5b3661008d5761008b33620186a0604051806020016040528060008152506101e2565b005b600080fd5b34801561009e57600080fd5b506100a7600181565b60405161ffff90911681526020015b60405180910390f35b3480156100cb57600080fd5b5061008b6103a6565b3480156100e057600080fd5b5061011d6040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100b691906104d1565b34801561013657600080fd5b5061015a6101453660046104eb565b60006020819052908152604090205460ff1681565b60405190151581526020016100b6565b61008b610178366004610533565b6101e2565b34801561018957600080fd5b506101d46001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016100b6565b60006102786040518060c0016040528061023c6001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b815233602082015273ffffffffffffffffffffffffffffffffffffffff871660408201523460608201526080810186905260a0018490526103de565b600081815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055905073ffffffffffffffffffffffffffffffffffffffff8416336103136001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b7f02a52367d10742d8032712c1bb8e0144ff1ec5ffda1ed7d70bb05a2744955054348787876040516103489493929190610637565b60405180910390a45050600180547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082168301167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b476103b08161042b565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b80516020808301516040808501516060860151608087015160a0880151935160009761040e979096959101610667565b604051602081830303815290604052805190602001209050919050565b806040516104389061045a565b6040518091039082f0905080158015610455573d6000803e3d6000fd5b505050565b6008806106bf83390190565b6000815180845260005b8181101561048c57602081850181015186830182015201610470565b8181111561049e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104e46020830184610466565b9392505050565b6000602082840312156104fd57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561054857600080fd5b833573ffffffffffffffffffffffffffffffffffffffff8116811461056c57600080fd5b925060208401359150604084013567ffffffffffffffff8082111561059057600080fd5b818601915086601f8301126105a457600080fd5b8135818111156105b6576105b6610504565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156105fc576105fc610504565b8160405282815289602084870101111561061557600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b8481528360208201526080604082015260006106566080830185610466565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526106b260c0830184610466565b9897505050505050505056fe608060405230fffea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/l2tol1messagepasser_more.go b/op-bindings/bindings/l2tol1messagepasser_more.go index 25fea0ccd990..1af5727ff4d7 100644 --- a/op-bindings/bindings/l2tol1messagepasser_more.go +++ b/op-bindings/bindings/l2tol1messagepasser_more.go @@ -15,6 +15,7 @@ var L2ToL1MessagePasserStorageLayout = new(solc.StorageLayout) var L2ToL1MessagePasserDeployedBin = "0x6080604052600436106100695760003560e01c806382e3702d1161004357806382e3702d1461012a578063c2b3e5ac1461016a578063ecc704281461017d57600080fd5b80633f827a5a1461009257806344df8e70146100bf57806354fd4d50146100d457600080fd5b3661008d5761008b33620186a0604051806020016040528060008152506101e2565b005b600080fd5b34801561009e57600080fd5b506100a7600181565b60405161ffff90911681526020015b60405180910390f35b3480156100cb57600080fd5b5061008b6103a6565b3480156100e057600080fd5b5061011d6040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100b691906104d1565b34801561013657600080fd5b5061015a6101453660046104eb565b60006020819052908152604090205460ff1681565b60405190151581526020016100b6565b61008b610178366004610533565b6101e2565b34801561018957600080fd5b506101d46001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016100b6565b60006102786040518060c0016040528061023c6001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b815233602082015273ffffffffffffffffffffffffffffffffffffffff871660408201523460608201526080810186905260a0018490526103de565b600081815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055905073ffffffffffffffffffffffffffffffffffffffff8416336103136001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b7f02a52367d10742d8032712c1bb8e0144ff1ec5ffda1ed7d70bb05a2744955054348787876040516103489493929190610637565b60405180910390a45050600180547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082168301167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b476103b08161042b565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b80516020808301516040808501516060860151608087015160a0880151935160009761040e979096959101610667565b604051602081830303815290604052805190602001209050919050565b806040516104389061045a565b6040518091039082f0905080158015610455573d6000803e3d6000fd5b505050565b6008806106bf83390190565b6000815180845260005b8181101561048c57602081850181015186830182015201610470565b8181111561049e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104e46020830184610466565b9392505050565b6000602082840312156104fd57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561054857600080fd5b833573ffffffffffffffffffffffffffffffffffffffff8116811461056c57600080fd5b925060208401359150604084013567ffffffffffffffff8082111561059057600080fd5b818601915086601f8301126105a457600080fd5b8135818111156105b6576105b6610504565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156105fc576105fc610504565b8160405282815289602084870101111561061557600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b8481528360208201526080604082015260006106566080830185610466565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526106b260c0830184610466565b9897505050505050505056fe608060405230fffea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(L2ToL1MessagePasserStorageLayoutJSON), L2ToL1MessagePasserStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["L2ToL1MessagePasser"] = L2ToL1MessagePasserStorageLayout deployedBytecodes["L2ToL1MessagePasser"] = L2ToL1MessagePasserDeployedBin + immutableReferences["L2ToL1MessagePasser"] = false } diff --git a/op-bindings/bindings/legacyerc20eth.go b/op-bindings/bindings/legacyerc20eth.go deleted file mode 100644 index 46f88532deaf..000000000000 --- a/op-bindings/bindings/legacyerc20eth.go +++ /dev/null @@ -1,1381 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package bindings - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// LegacyERC20ETHMetaData contains all meta data concerning the LegacyERC20ETH contract. -var LegacyERC20ETHMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"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\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REMOTE_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_who\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"remoteToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b5073420000000000000000000000000000000000001060006040518060400160405280600581526020016422ba3432b960d91b8152506040518060400160405280600381526020016208aa8960eb1b8152506012600160026001858581600390816200007f919062000167565b5060046200008e828262000167565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff166101205262000233565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000ed57607f821691505b6020821081036200010e57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200016257600081815260208120601f850160051c810160208610156200013d5750805b601f850160051c820191505b818110156200015e5782815560010162000149565b5050505b505050565b81516001600160401b03811115620001835762000183620000c2565b6200019b81620001948454620000d8565b8462000114565b602080601f831160018114620001d35760008415620001ba5750858301515b600019600386901b1c1916600185901b1785556200015e565b600085815260208120601f198616915b828110156200020457888601518255948401946001909101908401620001e3565b5085821015620002235787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516101005161012051610e79620002916000396000610244015260008181610309015261039e0152600081816101a9015261032f015260006107a40152600061077b015260006107520152610e796000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610353578063e78cea9214610307578063ee9a31a21461039957600080fd5b8063ae1f6aaf14610307578063c01e1bd61461032d578063d6c0b2c41461032d57600080fd5b80639dc29fac116100bd5780639dc29fac146102ce578063a457c2d7146102e1578063a9059cbb146102f457600080fd5b806370a082311461029e57806395d89b41146102c657600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004610ab1565b6103c0565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104b1565b60405161019b9190610b2a565b61018f610213366004610ba4565b610543565b6002545b60405190815260200161019b565b61018f610238366004610bce565b6105d3565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004610ba4565b61065e565b61029461028f366004610ba4565b6106e9565b005b6101f861074b565b61021c6102ac366004610c0a565b73ffffffffffffffffffffffffffffffffffffffff163190565b6101f86107ee565b6102946102dc366004610ba4565b6107fd565b61018f6102ef366004610ba4565b61085f565b61018f610302366004610ba4565b6108ea565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c610361366004610c25565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061047957507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104a857507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104c090610c58565b80601f01602080910402602001604051908101604052809291908181526020018280546104ec90610c58565b80156105395780601f1061050e57610100808354040283529160200191610539565b820191906000526020600020905b81548152906001019060200180831161051c57829003601f168201915b5050505050905090565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4c656761637945524332304554483a20617070726f766520697320646973616260448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526000906084015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4c656761637945524332304554483a207472616e7366657246726f6d2069732060448201527f64697361626c656400000000000000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a20696e637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206d696e742069732064697361626c656460448201526064016105ca565b60606107767f0000000000000000000000000000000000000000000000000000000000000000610974565b61079f7f0000000000000000000000000000000000000000000000000000000000000000610974565b6107c87f0000000000000000000000000000000000000000000000000000000000000000610974565b6040516020016107da93929190610cab565b604051602081830303815290604052905090565b6060600480546104c090610c58565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206275726e2069732064697361626c656460448201526064016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a206465637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4c656761637945524332304554483a207472616e73666572206973206469736160448201527f626c65640000000000000000000000000000000000000000000000000000000060648201526000906084016105ca565b6060816000036109b757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156109e157806109cb81610d50565b91506109da9050600a83610db7565b91506109bb565b60008167ffffffffffffffff8111156109fc576109fc610dcb565b6040519080825280601f01601f191660200182016040528015610a26576020820181803683370190505b5090505b8415610aa957610a3b600183610dfa565b9150610a48600a86610e11565b610a53906030610e25565b60f81b818381518110610a6857610a68610e3d565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610aa2600a86610db7565b9450610a2a565b949350505050565b600060208284031215610ac357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610af357600080fd5b9392505050565b60005b83811015610b15578181015183820152602001610afd565b83811115610b24576000848401525b50505050565b6020815260008251806020840152610b49816040850160208701610afa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b9f57600080fd5b919050565b60008060408385031215610bb757600080fd5b610bc083610b7b565b946020939093013593505050565b600080600060608486031215610be357600080fd5b610bec84610b7b565b9250610bfa60208501610b7b565b9150604084013590509250925092565b600060208284031215610c1c57600080fd5b610af382610b7b565b60008060408385031215610c3857600080fd5b610c4183610b7b565b9150610c4f60208401610b7b565b90509250929050565b600181811c90821680610c6c57607f821691505b602082108103610ca5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008451610cbd818460208901610afa565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610cf9816001850160208a01610afa565b60019201918201528351610d14816002840160208801610afa565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8157610d81610d21565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610dc657610dc6610d88565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015610e0c57610e0c610d21565b500390565b600082610e2057610e20610d88565b500690565b60008219821115610e3857610e38610d21565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", -} - -// LegacyERC20ETHABI is the input ABI used to generate the binding from. -// Deprecated: Use LegacyERC20ETHMetaData.ABI instead. -var LegacyERC20ETHABI = LegacyERC20ETHMetaData.ABI - -// LegacyERC20ETHBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use LegacyERC20ETHMetaData.Bin instead. -var LegacyERC20ETHBin = LegacyERC20ETHMetaData.Bin - -// DeployLegacyERC20ETH deploys a new Ethereum contract, binding an instance of LegacyERC20ETH to it. -func DeployLegacyERC20ETH(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *LegacyERC20ETH, error) { - parsed, err := LegacyERC20ETHMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LegacyERC20ETHBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &LegacyERC20ETH{LegacyERC20ETHCaller: LegacyERC20ETHCaller{contract: contract}, LegacyERC20ETHTransactor: LegacyERC20ETHTransactor{contract: contract}, LegacyERC20ETHFilterer: LegacyERC20ETHFilterer{contract: contract}}, nil -} - -// LegacyERC20ETH is an auto generated Go binding around an Ethereum contract. -type LegacyERC20ETH struct { - LegacyERC20ETHCaller // Read-only binding to the contract - LegacyERC20ETHTransactor // Write-only binding to the contract - LegacyERC20ETHFilterer // Log filterer for contract events -} - -// LegacyERC20ETHCaller is an auto generated read-only Go binding around an Ethereum contract. -type LegacyERC20ETHCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// LegacyERC20ETHTransactor is an auto generated write-only Go binding around an Ethereum contract. -type LegacyERC20ETHTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// LegacyERC20ETHFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type LegacyERC20ETHFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// LegacyERC20ETHSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type LegacyERC20ETHSession struct { - Contract *LegacyERC20ETH // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// LegacyERC20ETHCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type LegacyERC20ETHCallerSession struct { - Contract *LegacyERC20ETHCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// LegacyERC20ETHTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type LegacyERC20ETHTransactorSession struct { - Contract *LegacyERC20ETHTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// LegacyERC20ETHRaw is an auto generated low-level Go binding around an Ethereum contract. -type LegacyERC20ETHRaw struct { - Contract *LegacyERC20ETH // Generic contract binding to access the raw methods on -} - -// LegacyERC20ETHCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type LegacyERC20ETHCallerRaw struct { - Contract *LegacyERC20ETHCaller // Generic read-only contract binding to access the raw methods on -} - -// LegacyERC20ETHTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type LegacyERC20ETHTransactorRaw struct { - Contract *LegacyERC20ETHTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewLegacyERC20ETH creates a new instance of LegacyERC20ETH, bound to a specific deployed contract. -func NewLegacyERC20ETH(address common.Address, backend bind.ContractBackend) (*LegacyERC20ETH, error) { - contract, err := bindLegacyERC20ETH(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &LegacyERC20ETH{LegacyERC20ETHCaller: LegacyERC20ETHCaller{contract: contract}, LegacyERC20ETHTransactor: LegacyERC20ETHTransactor{contract: contract}, LegacyERC20ETHFilterer: LegacyERC20ETHFilterer{contract: contract}}, nil -} - -// NewLegacyERC20ETHCaller creates a new read-only instance of LegacyERC20ETH, bound to a specific deployed contract. -func NewLegacyERC20ETHCaller(address common.Address, caller bind.ContractCaller) (*LegacyERC20ETHCaller, error) { - contract, err := bindLegacyERC20ETH(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &LegacyERC20ETHCaller{contract: contract}, nil -} - -// NewLegacyERC20ETHTransactor creates a new write-only instance of LegacyERC20ETH, bound to a specific deployed contract. -func NewLegacyERC20ETHTransactor(address common.Address, transactor bind.ContractTransactor) (*LegacyERC20ETHTransactor, error) { - contract, err := bindLegacyERC20ETH(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &LegacyERC20ETHTransactor{contract: contract}, nil -} - -// NewLegacyERC20ETHFilterer creates a new log filterer instance of LegacyERC20ETH, bound to a specific deployed contract. -func NewLegacyERC20ETHFilterer(address common.Address, filterer bind.ContractFilterer) (*LegacyERC20ETHFilterer, error) { - contract, err := bindLegacyERC20ETH(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &LegacyERC20ETHFilterer{contract: contract}, nil -} - -// bindLegacyERC20ETH binds a generic wrapper to an already deployed contract. -func bindLegacyERC20ETH(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(LegacyERC20ETHABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_LegacyERC20ETH *LegacyERC20ETHRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _LegacyERC20ETH.Contract.LegacyERC20ETHCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_LegacyERC20ETH *LegacyERC20ETHRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.LegacyERC20ETHTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_LegacyERC20ETH *LegacyERC20ETHRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.LegacyERC20ETHTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_LegacyERC20ETH *LegacyERC20ETHCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _LegacyERC20ETH.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_LegacyERC20ETH *LegacyERC20ETHTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_LegacyERC20ETH *LegacyERC20ETHTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.contract.Transact(opts, method, params...) -} - -// BRIDGE is a free data retrieval call binding the contract method 0xee9a31a2. -// -// Solidity: function BRIDGE() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) BRIDGE(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "BRIDGE") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// BRIDGE is a free data retrieval call binding the contract method 0xee9a31a2. -// -// Solidity: function BRIDGE() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHSession) BRIDGE() (common.Address, error) { - return _LegacyERC20ETH.Contract.BRIDGE(&_LegacyERC20ETH.CallOpts) -} - -// BRIDGE is a free data retrieval call binding the contract method 0xee9a31a2. -// -// Solidity: function BRIDGE() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) BRIDGE() (common.Address, error) { - return _LegacyERC20ETH.Contract.BRIDGE(&_LegacyERC20ETH.CallOpts) -} - -// REMOTETOKEN is a free data retrieval call binding the contract method 0x033964be. -// -// Solidity: function REMOTE_TOKEN() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) REMOTETOKEN(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "REMOTE_TOKEN") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// REMOTETOKEN is a free data retrieval call binding the contract method 0x033964be. -// -// Solidity: function REMOTE_TOKEN() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHSession) REMOTETOKEN() (common.Address, error) { - return _LegacyERC20ETH.Contract.REMOTETOKEN(&_LegacyERC20ETH.CallOpts) -} - -// REMOTETOKEN is a free data retrieval call binding the contract method 0x033964be. -// -// Solidity: function REMOTE_TOKEN() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) REMOTETOKEN() (common.Address, error) { - return _LegacyERC20ETH.Contract.REMOTETOKEN(&_LegacyERC20ETH.CallOpts) -} - -// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. -// -// Solidity: function allowance(address owner, address spender) view returns(uint256) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "allowance", owner, spender) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. -// -// Solidity: function allowance(address owner, address spender) view returns(uint256) -func (_LegacyERC20ETH *LegacyERC20ETHSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { - return _LegacyERC20ETH.Contract.Allowance(&_LegacyERC20ETH.CallOpts, owner, spender) -} - -// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. -// -// Solidity: function allowance(address owner, address spender) view returns(uint256) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { - return _LegacyERC20ETH.Contract.Allowance(&_LegacyERC20ETH.CallOpts, owner, spender) -} - -// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. -// -// Solidity: function balanceOf(address _who) view returns(uint256) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) BalanceOf(opts *bind.CallOpts, _who common.Address) (*big.Int, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "balanceOf", _who) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. -// -// Solidity: function balanceOf(address _who) view returns(uint256) -func (_LegacyERC20ETH *LegacyERC20ETHSession) BalanceOf(_who common.Address) (*big.Int, error) { - return _LegacyERC20ETH.Contract.BalanceOf(&_LegacyERC20ETH.CallOpts, _who) -} - -// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. -// -// Solidity: function balanceOf(address _who) view returns(uint256) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) BalanceOf(_who common.Address) (*big.Int, error) { - return _LegacyERC20ETH.Contract.BalanceOf(&_LegacyERC20ETH.CallOpts, _who) -} - -// Bridge is a free data retrieval call binding the contract method 0xe78cea92. -// -// Solidity: function bridge() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) Bridge(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "bridge") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Bridge is a free data retrieval call binding the contract method 0xe78cea92. -// -// Solidity: function bridge() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHSession) Bridge() (common.Address, error) { - return _LegacyERC20ETH.Contract.Bridge(&_LegacyERC20ETH.CallOpts) -} - -// Bridge is a free data retrieval call binding the contract method 0xe78cea92. -// -// Solidity: function bridge() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) Bridge() (common.Address, error) { - return _LegacyERC20ETH.Contract.Bridge(&_LegacyERC20ETH.CallOpts) -} - -// Decimals is a free data retrieval call binding the contract method 0x313ce567. -// -// Solidity: function decimals() view returns(uint8) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) Decimals(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "decimals") - - if err != nil { - return *new(uint8), err - } - - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) - - return out0, err - -} - -// Decimals is a free data retrieval call binding the contract method 0x313ce567. -// -// Solidity: function decimals() view returns(uint8) -func (_LegacyERC20ETH *LegacyERC20ETHSession) Decimals() (uint8, error) { - return _LegacyERC20ETH.Contract.Decimals(&_LegacyERC20ETH.CallOpts) -} - -// Decimals is a free data retrieval call binding the contract method 0x313ce567. -// -// Solidity: function decimals() view returns(uint8) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) Decimals() (uint8, error) { - return _LegacyERC20ETH.Contract.Decimals(&_LegacyERC20ETH.CallOpts) -} - -// L1Token is a free data retrieval call binding the contract method 0xc01e1bd6. -// -// Solidity: function l1Token() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) L1Token(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "l1Token") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// L1Token is a free data retrieval call binding the contract method 0xc01e1bd6. -// -// Solidity: function l1Token() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHSession) L1Token() (common.Address, error) { - return _LegacyERC20ETH.Contract.L1Token(&_LegacyERC20ETH.CallOpts) -} - -// L1Token is a free data retrieval call binding the contract method 0xc01e1bd6. -// -// Solidity: function l1Token() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) L1Token() (common.Address, error) { - return _LegacyERC20ETH.Contract.L1Token(&_LegacyERC20ETH.CallOpts) -} - -// L2Bridge is a free data retrieval call binding the contract method 0xae1f6aaf. -// -// Solidity: function l2Bridge() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) L2Bridge(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "l2Bridge") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// L2Bridge is a free data retrieval call binding the contract method 0xae1f6aaf. -// -// Solidity: function l2Bridge() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHSession) L2Bridge() (common.Address, error) { - return _LegacyERC20ETH.Contract.L2Bridge(&_LegacyERC20ETH.CallOpts) -} - -// L2Bridge is a free data retrieval call binding the contract method 0xae1f6aaf. -// -// Solidity: function l2Bridge() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) L2Bridge() (common.Address, error) { - return _LegacyERC20ETH.Contract.L2Bridge(&_LegacyERC20ETH.CallOpts) -} - -// Name is a free data retrieval call binding the contract method 0x06fdde03. -// -// Solidity: function name() view returns(string) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) Name(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "name") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// Name is a free data retrieval call binding the contract method 0x06fdde03. -// -// Solidity: function name() view returns(string) -func (_LegacyERC20ETH *LegacyERC20ETHSession) Name() (string, error) { - return _LegacyERC20ETH.Contract.Name(&_LegacyERC20ETH.CallOpts) -} - -// Name is a free data retrieval call binding the contract method 0x06fdde03. -// -// Solidity: function name() view returns(string) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) Name() (string, error) { - return _LegacyERC20ETH.Contract.Name(&_LegacyERC20ETH.CallOpts) -} - -// RemoteToken is a free data retrieval call binding the contract method 0xd6c0b2c4. -// -// Solidity: function remoteToken() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) RemoteToken(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "remoteToken") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// RemoteToken is a free data retrieval call binding the contract method 0xd6c0b2c4. -// -// Solidity: function remoteToken() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHSession) RemoteToken() (common.Address, error) { - return _LegacyERC20ETH.Contract.RemoteToken(&_LegacyERC20ETH.CallOpts) -} - -// RemoteToken is a free data retrieval call binding the contract method 0xd6c0b2c4. -// -// Solidity: function remoteToken() view returns(address) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) RemoteToken() (common.Address, error) { - return _LegacyERC20ETH.Contract.RemoteToken(&_LegacyERC20ETH.CallOpts) -} - -// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. -// -// Solidity: function supportsInterface(bytes4 _interfaceId) pure returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) SupportsInterface(opts *bind.CallOpts, _interfaceId [4]byte) (bool, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "supportsInterface", _interfaceId) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. -// -// Solidity: function supportsInterface(bytes4 _interfaceId) pure returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHSession) SupportsInterface(_interfaceId [4]byte) (bool, error) { - return _LegacyERC20ETH.Contract.SupportsInterface(&_LegacyERC20ETH.CallOpts, _interfaceId) -} - -// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. -// -// Solidity: function supportsInterface(bytes4 _interfaceId) pure returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) SupportsInterface(_interfaceId [4]byte) (bool, error) { - return _LegacyERC20ETH.Contract.SupportsInterface(&_LegacyERC20ETH.CallOpts, _interfaceId) -} - -// Symbol is a free data retrieval call binding the contract method 0x95d89b41. -// -// Solidity: function symbol() view returns(string) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) Symbol(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "symbol") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// Symbol is a free data retrieval call binding the contract method 0x95d89b41. -// -// Solidity: function symbol() view returns(string) -func (_LegacyERC20ETH *LegacyERC20ETHSession) Symbol() (string, error) { - return _LegacyERC20ETH.Contract.Symbol(&_LegacyERC20ETH.CallOpts) -} - -// Symbol is a free data retrieval call binding the contract method 0x95d89b41. -// -// Solidity: function symbol() view returns(string) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) Symbol() (string, error) { - return _LegacyERC20ETH.Contract.Symbol(&_LegacyERC20ETH.CallOpts) -} - -// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. -// -// Solidity: function totalSupply() view returns(uint256) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "totalSupply") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. -// -// Solidity: function totalSupply() view returns(uint256) -func (_LegacyERC20ETH *LegacyERC20ETHSession) TotalSupply() (*big.Int, error) { - return _LegacyERC20ETH.Contract.TotalSupply(&_LegacyERC20ETH.CallOpts) -} - -// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. -// -// Solidity: function totalSupply() view returns(uint256) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) TotalSupply() (*big.Int, error) { - return _LegacyERC20ETH.Contract.TotalSupply(&_LegacyERC20ETH.CallOpts) -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() view returns(string) -func (_LegacyERC20ETH *LegacyERC20ETHCaller) Version(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _LegacyERC20ETH.contract.Call(opts, &out, "version") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() view returns(string) -func (_LegacyERC20ETH *LegacyERC20ETHSession) Version() (string, error) { - return _LegacyERC20ETH.Contract.Version(&_LegacyERC20ETH.CallOpts) -} - -// Version is a free data retrieval call binding the contract method 0x54fd4d50. -// -// Solidity: function version() view returns(string) -func (_LegacyERC20ETH *LegacyERC20ETHCallerSession) Version() (string, error) { - return _LegacyERC20ETH.Contract.Version(&_LegacyERC20ETH.CallOpts) -} - -// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. -// -// Solidity: function approve(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHTransactor) Approve(opts *bind.TransactOpts, arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.contract.Transact(opts, "approve", arg0, arg1) -} - -// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. -// -// Solidity: function approve(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHSession) Approve(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.Approve(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. -// -// Solidity: function approve(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHTransactorSession) Approve(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.Approve(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// Burn is a paid mutator transaction binding the contract method 0x9dc29fac. -// -// Solidity: function burn(address , uint256 ) returns() -func (_LegacyERC20ETH *LegacyERC20ETHTransactor) Burn(opts *bind.TransactOpts, arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.contract.Transact(opts, "burn", arg0, arg1) -} - -// Burn is a paid mutator transaction binding the contract method 0x9dc29fac. -// -// Solidity: function burn(address , uint256 ) returns() -func (_LegacyERC20ETH *LegacyERC20ETHSession) Burn(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.Burn(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// Burn is a paid mutator transaction binding the contract method 0x9dc29fac. -// -// Solidity: function burn(address , uint256 ) returns() -func (_LegacyERC20ETH *LegacyERC20ETHTransactorSession) Burn(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.Burn(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. -// -// Solidity: function decreaseAllowance(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHTransactor) DecreaseAllowance(opts *bind.TransactOpts, arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.contract.Transact(opts, "decreaseAllowance", arg0, arg1) -} - -// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. -// -// Solidity: function decreaseAllowance(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHSession) DecreaseAllowance(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.DecreaseAllowance(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// DecreaseAllowance is a paid mutator transaction binding the contract method 0xa457c2d7. -// -// Solidity: function decreaseAllowance(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHTransactorSession) DecreaseAllowance(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.DecreaseAllowance(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. -// -// Solidity: function increaseAllowance(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHTransactor) IncreaseAllowance(opts *bind.TransactOpts, arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.contract.Transact(opts, "increaseAllowance", arg0, arg1) -} - -// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. -// -// Solidity: function increaseAllowance(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHSession) IncreaseAllowance(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.IncreaseAllowance(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// IncreaseAllowance is a paid mutator transaction binding the contract method 0x39509351. -// -// Solidity: function increaseAllowance(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHTransactorSession) IncreaseAllowance(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.IncreaseAllowance(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// Mint is a paid mutator transaction binding the contract method 0x40c10f19. -// -// Solidity: function mint(address , uint256 ) returns() -func (_LegacyERC20ETH *LegacyERC20ETHTransactor) Mint(opts *bind.TransactOpts, arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.contract.Transact(opts, "mint", arg0, arg1) -} - -// Mint is a paid mutator transaction binding the contract method 0x40c10f19. -// -// Solidity: function mint(address , uint256 ) returns() -func (_LegacyERC20ETH *LegacyERC20ETHSession) Mint(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.Mint(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// Mint is a paid mutator transaction binding the contract method 0x40c10f19. -// -// Solidity: function mint(address , uint256 ) returns() -func (_LegacyERC20ETH *LegacyERC20ETHTransactorSession) Mint(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.Mint(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. -// -// Solidity: function transfer(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHTransactor) Transfer(opts *bind.TransactOpts, arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.contract.Transact(opts, "transfer", arg0, arg1) -} - -// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. -// -// Solidity: function transfer(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHSession) Transfer(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.Transfer(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. -// -// Solidity: function transfer(address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHTransactorSession) Transfer(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.Transfer(&_LegacyERC20ETH.TransactOpts, arg0, arg1) -} - -// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. -// -// Solidity: function transferFrom(address , address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHTransactor) TransferFrom(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, arg2 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.contract.Transact(opts, "transferFrom", arg0, arg1, arg2) -} - -// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. -// -// Solidity: function transferFrom(address , address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHSession) TransferFrom(arg0 common.Address, arg1 common.Address, arg2 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.TransferFrom(&_LegacyERC20ETH.TransactOpts, arg0, arg1, arg2) -} - -// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. -// -// Solidity: function transferFrom(address , address , uint256 ) returns(bool) -func (_LegacyERC20ETH *LegacyERC20ETHTransactorSession) TransferFrom(arg0 common.Address, arg1 common.Address, arg2 *big.Int) (*types.Transaction, error) { - return _LegacyERC20ETH.Contract.TransferFrom(&_LegacyERC20ETH.TransactOpts, arg0, arg1, arg2) -} - -// LegacyERC20ETHApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the LegacyERC20ETH contract. -type LegacyERC20ETHApprovalIterator struct { - Event *LegacyERC20ETHApproval // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *LegacyERC20ETHApprovalIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(LegacyERC20ETHApproval) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(LegacyERC20ETHApproval) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *LegacyERC20ETHApprovalIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *LegacyERC20ETHApprovalIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// LegacyERC20ETHApproval represents a Approval event raised by the LegacyERC20ETH contract. -type LegacyERC20ETHApproval struct { - Owner common.Address - Spender common.Address - Value *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. -// -// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*LegacyERC20ETHApprovalIterator, error) { - - var ownerRule []interface{} - for _, ownerItem := range owner { - ownerRule = append(ownerRule, ownerItem) - } - var spenderRule []interface{} - for _, spenderItem := range spender { - spenderRule = append(spenderRule, spenderItem) - } - - logs, sub, err := _LegacyERC20ETH.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) - if err != nil { - return nil, err - } - return &LegacyERC20ETHApprovalIterator{contract: _LegacyERC20ETH.contract, event: "Approval", logs: logs, sub: sub}, nil -} - -// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. -// -// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *LegacyERC20ETHApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { - - var ownerRule []interface{} - for _, ownerItem := range owner { - ownerRule = append(ownerRule, ownerItem) - } - var spenderRule []interface{} - for _, spenderItem := range spender { - spenderRule = append(spenderRule, spenderItem) - } - - logs, sub, err := _LegacyERC20ETH.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(LegacyERC20ETHApproval) - if err := _LegacyERC20ETH.contract.UnpackLog(event, "Approval", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. -// -// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) ParseApproval(log types.Log) (*LegacyERC20ETHApproval, error) { - event := new(LegacyERC20ETHApproval) - if err := _LegacyERC20ETH.contract.UnpackLog(event, "Approval", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// LegacyERC20ETHBurnIterator is returned from FilterBurn and is used to iterate over the raw logs and unpacked data for Burn events raised by the LegacyERC20ETH contract. -type LegacyERC20ETHBurnIterator struct { - Event *LegacyERC20ETHBurn // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *LegacyERC20ETHBurnIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(LegacyERC20ETHBurn) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(LegacyERC20ETHBurn) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *LegacyERC20ETHBurnIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *LegacyERC20ETHBurnIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// LegacyERC20ETHBurn represents a Burn event raised by the LegacyERC20ETH contract. -type LegacyERC20ETHBurn struct { - Account common.Address - Amount *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterBurn is a free log retrieval operation binding the contract event 0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5. -// -// Solidity: event Burn(address indexed account, uint256 amount) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) FilterBurn(opts *bind.FilterOpts, account []common.Address) (*LegacyERC20ETHBurnIterator, error) { - - var accountRule []interface{} - for _, accountItem := range account { - accountRule = append(accountRule, accountItem) - } - - logs, sub, err := _LegacyERC20ETH.contract.FilterLogs(opts, "Burn", accountRule) - if err != nil { - return nil, err - } - return &LegacyERC20ETHBurnIterator{contract: _LegacyERC20ETH.contract, event: "Burn", logs: logs, sub: sub}, nil -} - -// WatchBurn is a free log subscription operation binding the contract event 0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5. -// -// Solidity: event Burn(address indexed account, uint256 amount) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) WatchBurn(opts *bind.WatchOpts, sink chan<- *LegacyERC20ETHBurn, account []common.Address) (event.Subscription, error) { - - var accountRule []interface{} - for _, accountItem := range account { - accountRule = append(accountRule, accountItem) - } - - logs, sub, err := _LegacyERC20ETH.contract.WatchLogs(opts, "Burn", accountRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(LegacyERC20ETHBurn) - if err := _LegacyERC20ETH.contract.UnpackLog(event, "Burn", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseBurn is a log parse operation binding the contract event 0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5. -// -// Solidity: event Burn(address indexed account, uint256 amount) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) ParseBurn(log types.Log) (*LegacyERC20ETHBurn, error) { - event := new(LegacyERC20ETHBurn) - if err := _LegacyERC20ETH.contract.UnpackLog(event, "Burn", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// LegacyERC20ETHMintIterator is returned from FilterMint and is used to iterate over the raw logs and unpacked data for Mint events raised by the LegacyERC20ETH contract. -type LegacyERC20ETHMintIterator struct { - Event *LegacyERC20ETHMint // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *LegacyERC20ETHMintIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(LegacyERC20ETHMint) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(LegacyERC20ETHMint) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *LegacyERC20ETHMintIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *LegacyERC20ETHMintIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// LegacyERC20ETHMint represents a Mint event raised by the LegacyERC20ETH contract. -type LegacyERC20ETHMint struct { - Account common.Address - Amount *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterMint is a free log retrieval operation binding the contract event 0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885. -// -// Solidity: event Mint(address indexed account, uint256 amount) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) FilterMint(opts *bind.FilterOpts, account []common.Address) (*LegacyERC20ETHMintIterator, error) { - - var accountRule []interface{} - for _, accountItem := range account { - accountRule = append(accountRule, accountItem) - } - - logs, sub, err := _LegacyERC20ETH.contract.FilterLogs(opts, "Mint", accountRule) - if err != nil { - return nil, err - } - return &LegacyERC20ETHMintIterator{contract: _LegacyERC20ETH.contract, event: "Mint", logs: logs, sub: sub}, nil -} - -// WatchMint is a free log subscription operation binding the contract event 0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885. -// -// Solidity: event Mint(address indexed account, uint256 amount) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) WatchMint(opts *bind.WatchOpts, sink chan<- *LegacyERC20ETHMint, account []common.Address) (event.Subscription, error) { - - var accountRule []interface{} - for _, accountItem := range account { - accountRule = append(accountRule, accountItem) - } - - logs, sub, err := _LegacyERC20ETH.contract.WatchLogs(opts, "Mint", accountRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(LegacyERC20ETHMint) - if err := _LegacyERC20ETH.contract.UnpackLog(event, "Mint", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseMint is a log parse operation binding the contract event 0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885. -// -// Solidity: event Mint(address indexed account, uint256 amount) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) ParseMint(log types.Log) (*LegacyERC20ETHMint, error) { - event := new(LegacyERC20ETHMint) - if err := _LegacyERC20ETH.contract.UnpackLog(event, "Mint", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// LegacyERC20ETHTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the LegacyERC20ETH contract. -type LegacyERC20ETHTransferIterator struct { - Event *LegacyERC20ETHTransfer // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *LegacyERC20ETHTransferIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(LegacyERC20ETHTransfer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(LegacyERC20ETHTransfer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *LegacyERC20ETHTransferIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *LegacyERC20ETHTransferIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// LegacyERC20ETHTransfer represents a Transfer event raised by the LegacyERC20ETH contract. -type LegacyERC20ETHTransfer struct { - From common.Address - To common.Address - Value *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. -// -// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LegacyERC20ETHTransferIterator, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _LegacyERC20ETH.contract.FilterLogs(opts, "Transfer", fromRule, toRule) - if err != nil { - return nil, err - } - return &LegacyERC20ETHTransferIterator{contract: _LegacyERC20ETH.contract, event: "Transfer", logs: logs, sub: sub}, nil -} - -// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. -// -// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *LegacyERC20ETHTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { - - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _LegacyERC20ETH.contract.WatchLogs(opts, "Transfer", fromRule, toRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(LegacyERC20ETHTransfer) - if err := _LegacyERC20ETH.contract.UnpackLog(event, "Transfer", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. -// -// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) -func (_LegacyERC20ETH *LegacyERC20ETHFilterer) ParseTransfer(log types.Log) (*LegacyERC20ETHTransfer, error) { - event := new(LegacyERC20ETHTransfer) - if err := _LegacyERC20ETH.contract.UnpackLog(event, "Transfer", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/op-bindings/bindings/legacyerc20eth_more.go b/op-bindings/bindings/legacyerc20eth_more.go deleted file mode 100644 index cb79ddddc2c8..000000000000 --- a/op-bindings/bindings/legacyerc20eth_more.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package bindings - -import ( - "encoding/json" - - "github.com/ethereum-optimism/optimism/op-bindings/solc" -) - -const LegacyERC20ETHStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":1001,\"contract\":\"src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1002,\"contract\":\"src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":1003,\"contract\":\"src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":1004,\"contract\":\"src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}" - -var LegacyERC20ETHStorageLayout = new(solc.StorageLayout) - -var LegacyERC20ETHDeployedBin = "0x608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610353578063e78cea9214610307578063ee9a31a21461039957600080fd5b8063ae1f6aaf14610307578063c01e1bd61461032d578063d6c0b2c41461032d57600080fd5b80639dc29fac116100bd5780639dc29fac146102ce578063a457c2d7146102e1578063a9059cbb146102f457600080fd5b806370a082311461029e57806395d89b41146102c657600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004610ab1565b6103c0565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104b1565b60405161019b9190610b2a565b61018f610213366004610ba4565b610543565b6002545b60405190815260200161019b565b61018f610238366004610bce565b6105d3565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004610ba4565b61065e565b61029461028f366004610ba4565b6106e9565b005b6101f861074b565b61021c6102ac366004610c0a565b73ffffffffffffffffffffffffffffffffffffffff163190565b6101f86107ee565b6102946102dc366004610ba4565b6107fd565b61018f6102ef366004610ba4565b61085f565b61018f610302366004610ba4565b6108ea565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c610361366004610c25565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061047957507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104a857507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104c090610c58565b80601f01602080910402602001604051908101604052809291908181526020018280546104ec90610c58565b80156105395780601f1061050e57610100808354040283529160200191610539565b820191906000526020600020905b81548152906001019060200180831161051c57829003601f168201915b5050505050905090565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4c656761637945524332304554483a20617070726f766520697320646973616260448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526000906084015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4c656761637945524332304554483a207472616e7366657246726f6d2069732060448201527f64697361626c656400000000000000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a20696e637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206d696e742069732064697361626c656460448201526064016105ca565b60606107767f0000000000000000000000000000000000000000000000000000000000000000610974565b61079f7f0000000000000000000000000000000000000000000000000000000000000000610974565b6107c87f0000000000000000000000000000000000000000000000000000000000000000610974565b6040516020016107da93929190610cab565b604051602081830303815290604052905090565b6060600480546104c090610c58565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206275726e2069732064697361626c656460448201526064016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a206465637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4c656761637945524332304554483a207472616e73666572206973206469736160448201527f626c65640000000000000000000000000000000000000000000000000000000060648201526000906084016105ca565b6060816000036109b757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156109e157806109cb81610d50565b91506109da9050600a83610db7565b91506109bb565b60008167ffffffffffffffff8111156109fc576109fc610dcb565b6040519080825280601f01601f191660200182016040528015610a26576020820181803683370190505b5090505b8415610aa957610a3b600183610dfa565b9150610a48600a86610e11565b610a53906030610e25565b60f81b818381518110610a6857610a68610e3d565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610aa2600a86610db7565b9450610a2a565b949350505050565b600060208284031215610ac357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610af357600080fd5b9392505050565b60005b83811015610b15578181015183820152602001610afd565b83811115610b24576000848401525b50505050565b6020815260008251806020840152610b49816040850160208701610afa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b9f57600080fd5b919050565b60008060408385031215610bb757600080fd5b610bc083610b7b565b946020939093013593505050565b600080600060608486031215610be357600080fd5b610bec84610b7b565b9250610bfa60208501610b7b565b9150604084013590509250925092565b600060208284031215610c1c57600080fd5b610af382610b7b565b60008060408385031215610c3857600080fd5b610c4183610b7b565b9150610c4f60208401610b7b565b90509250929050565b600181811c90821680610c6c57607f821691505b602082108103610ca5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008451610cbd818460208901610afa565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610cf9816001850160208a01610afa565b60019201918201528351610d14816002840160208801610afa565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8157610d81610d21565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610dc657610dc6610d88565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015610e0c57610e0c610d21565b500390565b600082610e2057610e20610d88565b500690565b60008219821115610e3857610e38610d21565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a" - -func init() { - if err := json.Unmarshal([]byte(LegacyERC20ETHStorageLayoutJSON), LegacyERC20ETHStorageLayout); err != nil { - panic(err) - } - - layouts["LegacyERC20ETH"] = LegacyERC20ETHStorageLayout - deployedBytecodes["LegacyERC20ETH"] = LegacyERC20ETHDeployedBin -} diff --git a/op-bindings/bindings/legacymessagepasser.go b/op-bindings/bindings/legacymessagepasser.go index 2fd2c82c7995..2c9c072716b3 100644 --- a/op-bindings/bindings/legacymessagepasser.go +++ b/op-bindings/bindings/legacymessagepasser.go @@ -30,7 +30,7 @@ var ( // LegacyMessagePasserMetaData contains all meta data concerning the LegacyMessagePasser contract. var LegacyMessagePasserMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"passMessageToL1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"sentMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"type\":\"function\",\"name\":\"passMessageToL1\",\"inputs\":[{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"sentMessages\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"}]", Bin: "0x608060405234801561001057600080fd5b5061035a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806382e3702d14610098578063cafa81dc146100cb575b600080fd5b6100826040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161008f919061019b565b60405180910390f35b6100bb6100a63660046101ec565b60006020819052908152604090205460ff1681565b604051901515815260200161008f565b6100de6100d9366004610234565b6100e0565b005b600160008083336040516020016100f8929190610303565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905550565b60005b8381101561018657818101518382015260200161016e565b83811115610195576000848401525b50505050565b60208152600082518060208401526101ba81604085016020870161016b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156101fe57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561024657600080fd5b813567ffffffffffffffff8082111561025e57600080fd5b818401915084601f83011261027257600080fd5b81358181111561028457610284610205565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156102ca576102ca610205565b816040528281528760208487010111156102e357600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000835161031581846020880161016b565b60609390931b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016919092019081526014019291505056fea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/legacymessagepasser_more.go b/op-bindings/bindings/legacymessagepasser_more.go index eea91eb9ea1f..4f512661a4fb 100644 --- a/op-bindings/bindings/legacymessagepasser_more.go +++ b/op-bindings/bindings/legacymessagepasser_more.go @@ -15,6 +15,7 @@ var LegacyMessagePasserStorageLayout = new(solc.StorageLayout) var LegacyMessagePasserDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806382e3702d14610098578063cafa81dc146100cb575b600080fd5b6100826040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161008f919061019b565b60405180910390f35b6100bb6100a63660046101ec565b60006020819052908152604090205460ff1681565b604051901515815260200161008f565b6100de6100d9366004610234565b6100e0565b005b600160008083336040516020016100f8929190610303565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905550565b60005b8381101561018657818101518382015260200161016e565b83811115610195576000848401525b50505050565b60208152600082518060208401526101ba81604085016020870161016b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156101fe57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561024657600080fd5b813567ffffffffffffffff8082111561025e57600080fd5b818401915084601f83011261027257600080fd5b81358181111561028457610284610205565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156102ca576102ca610205565b816040528281528760208487010111156102e357600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000835161031581846020880161016b565b60609390931b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016919092019081526014019291505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(LegacyMessagePasserStorageLayoutJSON), LegacyMessagePasserStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["LegacyMessagePasser"] = LegacyMessagePasserStorageLayout deployedBytecodes["LegacyMessagePasser"] = LegacyMessagePasserDeployedBin + immutableReferences["LegacyMessagePasser"] = false } diff --git a/op-bindings/bindings/mips.go b/op-bindings/bindings/mips.go index 29f26ac73887..46eaa3505da1 100644 --- a/op-bindings/bindings/mips.go +++ b/op-bindings/bindings/mips.go @@ -30,8 +30,8 @@ var ( // MIPSMetaData contains all meta data concerning the MIPS contract. var MIPSMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIPreimageOracle\",\"name\":\"_oracle\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BRK_START\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contractIPreimageOracle\",\"name\":\"oracle_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_stateData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_proof\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_localContext\",\"type\":\"uint256\"}],\"name\":\"step\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a060405234801561001057600080fd5b50604051611ec2380380611ec283398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b608051611e3161009160003960008181608501526115ef0152611e316000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_oracle\",\"type\":\"address\",\"internalType\":\"contractIPreimageOracle\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"BRK_START\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"oracle\",\"inputs\":[],\"outputs\":[{\"name\":\"oracle_\",\"type\":\"address\",\"internalType\":\"contractIPreimageOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"step\",\"inputs\":[{\"name\":\"_stateData\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_localContext\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"}]", + Bin: "0x60a060405234801561001057600080fd5b50604051611f89380380611f8983398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b608051611ef86100916000396000818160d901526116430152611ef86000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063155633fe1461005157806354fd4d50146100765780637dc0d1d0146100bf578063e14ced3214610103575b600080fd5b61005c634000000081565b60405163ffffffff90911681526020015b60405180910390f35b6100b26040518060400160405280600581526020017f302e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161006d9190611d39565b60405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161006d565b610116610111366004611df5565b610124565b60405190815260200161006d565b600061012e611caf565b6080811461013b57600080fd5b6040516106001461014b57600080fd5b6084871461015857600080fd5b6101a4851461016657600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b602081101561021157823560e01c82526004909201916020909101906001016101ed565b5050508061012001511561022f5761022761066f565b915050610666565b6101408101805160010167ffffffffffffffff1690526060810151600090610257908261078b565b9050603f601a82901c16600281148061027657508063ffffffff166003145b156102cb5760006002836303ffffff1663ffffffff16901b846080015163f0000000161790506102c08263ffffffff166002146102b457601f6102b7565b60005b60ff1682610847565b945050505050610666565b6101608301516000908190601f601086901c81169190601587901c16602081106102f7576102f7611e69565b602002015192508063ffffffff8516158061031857508463ffffffff16601c145b1561034f578661016001518263ffffffff166020811061033a5761033a611e69565b6020020151925050601f600b86901c1661040b565b60208563ffffffff1610156103b1578463ffffffff16600c148061037957508463ffffffff16600d145b8061038a57508463ffffffff16600e145b1561039b578561ffff16925061040b565b6103aa8661ffff166010610938565b925061040b565b60288563ffffffff161015806103cd57508463ffffffff166022145b806103de57508463ffffffff166026145b1561040b578661016001518263ffffffff166020811061040057610400611e69565b602002015192508190505b60048563ffffffff1610158015610428575060088563ffffffff16105b8061043957508463ffffffff166001145b156104585761044a858784876109ab565b975050505050505050610666565b63ffffffff60006020878316106104bd576104788861ffff166010610938565b9095019463fffffffc861661048e81600161078b565b915060288863ffffffff16101580156104ae57508763ffffffff16603014155b156104bb57809250600093505b505b60006104cb89888885610bbb565b63ffffffff9081169150603f8a169089161580156104f0575060088163ffffffff1610155b80156105025750601c8163ffffffff16105b156105df578063ffffffff166008148061052257508063ffffffff166009145b15610559576105478163ffffffff1660081461053e5785610541565b60005b89610847565b9b505050505050505050505050610666565b8063ffffffff16600a0361057957610547858963ffffffff8a161561134b565b8063ffffffff16600b0361059a57610547858963ffffffff8a16151561134b565b8063ffffffff16600c036105b1576105478d611431565b60108163ffffffff16101580156105ce5750601c8163ffffffff16105b156105df5761054781898988611968565b8863ffffffff1660381480156105fa575063ffffffff861615155b1561062f5760018b61016001518763ffffffff166020811061061e5761061e611e69565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff1461064c5761064c84600184611b62565b6106588583600161134b565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b602081101561070e57601c86015184526020909501946004909301926001016106ea565b506000835283830384a060009450806001811461072e5760039550610756565b828015610746576001811461074f5760029650610754565b60009650610754565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061079783611c06565b905060038416156107a757600080fd5b6020810190358460051c8160005b601b81101561080d5760208501943583821c60011680156107dd57600181146107f257610803565b60008481526020839052604090209350610803565b600082815260208590526040902093505b50506001016107b5565b50608051915081811461082857630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b6000610851611caf565b60809050806060015160040163ffffffff16816080015163ffffffff16146108da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff90811690935285831690529085161561093057806008018261016001518663ffffffff166020811061091f5761091f611e69565b63ffffffff90921660209290920201525b61066661066f565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610995576000610997565b815b90861663ffffffff16179250505092915050565b60006109b5611caf565b608090506000816060015160040163ffffffff16826080015163ffffffff1614610a3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016108d1565b8663ffffffff1660041480610a5657508663ffffffff166005145b15610ad25760008261016001518663ffffffff1660208110610a7a57610a7a611e69565b602002015190508063ffffffff168563ffffffff16148015610aa257508763ffffffff166004145b80610aca57508063ffffffff168563ffffffff1614158015610aca57508763ffffffff166005145b915050610b4f565b8663ffffffff16600603610aef5760008460030b13159050610b4f565b8663ffffffff16600703610b0b5760008460030b139050610b4f565b8663ffffffff16600103610b4f57601f601087901c166000819003610b345760008560030b1291505b8063ffffffff16600103610b4d5760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b95576002610b7a8861ffff166010610938565b63ffffffff90811690911b8201600401166080840152610ba7565b60808301805160040163ffffffff1690525b610baf61066f565b98975050505050505050565b6000603f601a86901c16801580610bea575060088163ffffffff1610158015610bea5750600f8163ffffffff16105b1561104057603f86168160088114610c315760098114610c3a57600a8114610c4357600b8114610c4c57600c8114610c5557600d8114610c5e57600e8114610c6757610c6c565b60209150610c6c565b60219150610c6c565b602a9150610c6c565b602b9150610c6c565b60249150610c6c565b60259150610c6c565b602691505b508063ffffffff16600003610c935750505063ffffffff8216601f600686901c161b611343565b8063ffffffff16600203610cb95750505063ffffffff8216601f600686901c161c611343565b8063ffffffff16600303610cef57601f600688901c16610ce563ffffffff8716821c6020839003610938565b9350505050611343565b8063ffffffff16600403610d115750505063ffffffff8216601f84161b611343565b8063ffffffff16600603610d335750505063ffffffff8216601f84161c611343565b8063ffffffff16600703610d6657610d5d8663ffffffff168663ffffffff16901c87602003610938565b92505050611343565b8063ffffffff16600803610d7e578592505050611343565b8063ffffffff16600903610d96578592505050611343565b8063ffffffff16600a03610dae578592505050611343565b8063ffffffff16600b03610dc6578592505050611343565b8063ffffffff16600c03610dde578592505050611343565b8063ffffffff16600f03610df6578592505050611343565b8063ffffffff16601003610e0e578592505050611343565b8063ffffffff16601103610e26578592505050611343565b8063ffffffff16601203610e3e578592505050611343565b8063ffffffff16601303610e56578592505050611343565b8063ffffffff16601803610e6e578592505050611343565b8063ffffffff16601903610e86578592505050611343565b8063ffffffff16601a03610e9e578592505050611343565b8063ffffffff16601b03610eb6578592505050611343565b8063ffffffff16602003610ecf57505050828201611343565b8063ffffffff16602103610ee857505050828201611343565b8063ffffffff16602203610f0157505050818303611343565b8063ffffffff16602303610f1a57505050818303611343565b8063ffffffff16602403610f3357505050828216611343565b8063ffffffff16602503610f4c57505050828217611343565b8063ffffffff16602603610f6557505050828218611343565b8063ffffffff16602703610f7f5750505082821719611343565b8063ffffffff16602a03610fb0578460030b8660030b12610fa1576000610fa4565b60015b60ff1692505050611343565b8063ffffffff16602b03610fd8578463ffffffff168663ffffffff1610610fa1576000610fa4565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016108d1565b50610fd8565b8063ffffffff16601c036110c457603f8616600281900361106657505050828202611343565b8063ffffffff166020148061108157508063ffffffff166021145b1561103a578063ffffffff16602003611098579419945b60005b63800000008716156110ba576401fffffffe600197881b16960161109b565b9250611343915050565b8063ffffffff16600f036110e657505065ffffffff0000601083901b16611343565b8063ffffffff166020036111225761111a8560031660080260180363ffffffff168463ffffffff16901c60ff166008610938565b915050611343565b8063ffffffff166021036111575761111a8560021660080260100363ffffffff168463ffffffff16901c61ffff166010610938565b8063ffffffff1660220361118657505063ffffffff60086003851602811681811b198416918316901b17611343565b8063ffffffff1660230361119d5782915050611343565b8063ffffffff166024036111cf578460031660080260180363ffffffff168363ffffffff16901c60ff16915050611343565b8063ffffffff16602503611202578460021660080260100363ffffffff168363ffffffff16901c61ffff16915050611343565b8063ffffffff1660260361123457505063ffffffff60086003851602601803811681811c198416918316901c17611343565b8063ffffffff1660280361126a57505060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611343565b8063ffffffff166029036112a157505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611343565b8063ffffffff16602a036112d057505063ffffffff60086003851602811681811c198316918416901c17611343565b8063ffffffff16602b036112e75783915050611343565b8063ffffffff16602e0361131957505063ffffffff60086003851602601803811681811b198316918416901b17611343565b8063ffffffff166030036113305782915050611343565b8063ffffffff16603803610fd857839150505b949350505050565b6000611355611caf565b506080602063ffffffff8616106113c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016108d1565b63ffffffff8516158015906113da5750825b1561140e57838161016001518663ffffffff16602081106113fd576113fd611e69565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261066661066f565b600061143b611caf565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114b55781610fff81161561148457610fff811661100003015b8363ffffffff166000036114ab5760e08801805163ffffffff8382011690915295506114af565b8395505b50611927565b8563ffffffff16610fcd036114d05763400000009450611927565b8563ffffffff16611018036114e85760019450611927565b8563ffffffff166110960361151e57600161012088015260ff831661010088015261151161066f565b9998505050505050505050565b8563ffffffff16610fa30361178a5763ffffffff831615611927577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016117445760006115798363fffffffc16600161078b565b60208901519091508060001a6001036115e857604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ad9190611e98565b915091506003861680600403828110156116c5578092505b50818610156116d2578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506117298663fffffffc16600186611b62565b60408b018051820163ffffffff169052975061178592505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff84160161177957809450611927565b63ffffffff9450600993505b611927565b8563ffffffff16610fa40361187b5763ffffffff8316600114806117b4575063ffffffff83166002145b806117c5575063ffffffff83166004145b156117d257809450611927565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117795760006118128363fffffffc16600161078b565b6020890151909150600384166004038381101561182d578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b17602088015260006040880152935083611927565b8563ffffffff16610fd703611927578163ffffffff1660030361191b5763ffffffff831615806118b1575063ffffffff83166005145b806118c2575063ffffffff83166003145b156118d05760009450611927565b63ffffffff8316600114806118eb575063ffffffff83166002145b806118fc575063ffffffff83166006145b8061190d575063ffffffff83166004145b156117795760019450611927565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b0152600401909116905261151161066f565b6000611972611caf565b506080600063ffffffff8716601003611990575060c0810151611af9565b8663ffffffff166011036119af5763ffffffff861660c0830152611af9565b8663ffffffff166012036119c8575060a0810151611af9565b8663ffffffff166013036119e75763ffffffff861660a0830152611af9565b8663ffffffff16601803611a1b5763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611af9565b8663ffffffff16601903611a4c5763ffffffff86811681871602602081901c821660c08501521660a0830152611af9565b8663ffffffff16601a03611aa2578460030b8660030b81611a6f57611a6f611ebc565b0763ffffffff1660c0830152600385810b9087900b81611a9157611a91611ebc565b0563ffffffff1660a0830152611af9565b8663ffffffff16601b03611af9578463ffffffff168663ffffffff1681611acb57611acb611ebc565b0663ffffffff90811660c084015285811690871681611aec57611aec611ebc565b0463ffffffff1660a08301525b63ffffffff841615611b3457808261016001518563ffffffff1660208110611b2357611b23611e69565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b5761066f565b979650505050505050565b6000611b6d83611c06565b90506003841615611b7d57600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611bfb5760208401933582821c6001168015611bcb5760018114611be057611bf1565b60008581526020839052604090209450611bf1565b600082815260208690526040902094505b5050600101611ba3565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611ca9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016108d1565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611d15611d1a565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b81811015611d6657858101830151858201604001528201611d4a565b81811115611d78576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f840112611dbe57600080fd5b50813567ffffffffffffffff811115611dd657600080fd5b602083019150836020828501011115611dee57600080fd5b9250929050565b600080600080600060608688031215611e0d57600080fd5b853567ffffffffffffffff80821115611e2557600080fd5b611e3189838a01611dac565b90975095506020880135915080821115611e4a57600080fd5b50611e5788828901611dac565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611eab57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a", } // MIPSABI is the input ABI used to generate the binding from. @@ -263,23 +263,54 @@ func (_MIPS *MIPSCallerSession) Oracle() (common.Address, error) { return _MIPS.Contract.Oracle(&_MIPS.CallOpts) } -// Step is a paid mutator transaction binding the contract method 0x836e7b32. +// Version is a free data retrieval call binding the contract method 0x54fd4d50. // -// Solidity: function step(bytes _stateData, bytes _proof, uint256 _localContext) returns(bytes32) -func (_MIPS *MIPSTransactor) Step(opts *bind.TransactOpts, _stateData []byte, _proof []byte, _localContext *big.Int) (*types.Transaction, error) { +// Solidity: function version() view returns(string) +func (_MIPS *MIPSCaller) Version(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _MIPS.contract.Call(opts, &out, "version") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_MIPS *MIPSSession) Version() (string, error) { + return _MIPS.Contract.Version(&_MIPS.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_MIPS *MIPSCallerSession) Version() (string, error) { + return _MIPS.Contract.Version(&_MIPS.CallOpts) +} + +// Step is a paid mutator transaction binding the contract method 0xe14ced32. +// +// Solidity: function step(bytes _stateData, bytes _proof, bytes32 _localContext) returns(bytes32) +func (_MIPS *MIPSTransactor) Step(opts *bind.TransactOpts, _stateData []byte, _proof []byte, _localContext [32]byte) (*types.Transaction, error) { return _MIPS.contract.Transact(opts, "step", _stateData, _proof, _localContext) } -// Step is a paid mutator transaction binding the contract method 0x836e7b32. +// Step is a paid mutator transaction binding the contract method 0xe14ced32. // -// Solidity: function step(bytes _stateData, bytes _proof, uint256 _localContext) returns(bytes32) -func (_MIPS *MIPSSession) Step(_stateData []byte, _proof []byte, _localContext *big.Int) (*types.Transaction, error) { +// Solidity: function step(bytes _stateData, bytes _proof, bytes32 _localContext) returns(bytes32) +func (_MIPS *MIPSSession) Step(_stateData []byte, _proof []byte, _localContext [32]byte) (*types.Transaction, error) { return _MIPS.Contract.Step(&_MIPS.TransactOpts, _stateData, _proof, _localContext) } -// Step is a paid mutator transaction binding the contract method 0x836e7b32. +// Step is a paid mutator transaction binding the contract method 0xe14ced32. // -// Solidity: function step(bytes _stateData, bytes _proof, uint256 _localContext) returns(bytes32) -func (_MIPS *MIPSTransactorSession) Step(_stateData []byte, _proof []byte, _localContext *big.Int) (*types.Transaction, error) { +// Solidity: function step(bytes _stateData, bytes _proof, bytes32 _localContext) returns(bytes32) +func (_MIPS *MIPSTransactorSession) Step(_stateData []byte, _proof []byte, _localContext [32]byte) (*types.Transaction, error) { return _MIPS.Contract.Step(&_MIPS.TransactOpts, _stateData, _proof, _localContext) } diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index 33a4d555c8e5..3413ca05d789 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -13,9 +13,8 @@ const MIPSStorageLayoutJSON = "{\"storage\":null,\"types\":{}}" var MIPSStorageLayout = new(solc.StorageLayout) -var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" +var MIPSDeployedBin = "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063155633fe1461005157806354fd4d50146100765780637dc0d1d0146100bf578063e14ced3214610103575b600080fd5b61005c634000000081565b60405163ffffffff90911681526020015b60405180910390f35b6100b26040518060400160405280600581526020017f302e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161006d9190611d39565b60405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161006d565b610116610111366004611df5565b610124565b60405190815260200161006d565b600061012e611caf565b6080811461013b57600080fd5b6040516106001461014b57600080fd5b6084871461015857600080fd5b6101a4851461016657600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b602081101561021157823560e01c82526004909201916020909101906001016101ed565b5050508061012001511561022f5761022761066f565b915050610666565b6101408101805160010167ffffffffffffffff1690526060810151600090610257908261078b565b9050603f601a82901c16600281148061027657508063ffffffff166003145b156102cb5760006002836303ffffff1663ffffffff16901b846080015163f0000000161790506102c08263ffffffff166002146102b457601f6102b7565b60005b60ff1682610847565b945050505050610666565b6101608301516000908190601f601086901c81169190601587901c16602081106102f7576102f7611e69565b602002015192508063ffffffff8516158061031857508463ffffffff16601c145b1561034f578661016001518263ffffffff166020811061033a5761033a611e69565b6020020151925050601f600b86901c1661040b565b60208563ffffffff1610156103b1578463ffffffff16600c148061037957508463ffffffff16600d145b8061038a57508463ffffffff16600e145b1561039b578561ffff16925061040b565b6103aa8661ffff166010610938565b925061040b565b60288563ffffffff161015806103cd57508463ffffffff166022145b806103de57508463ffffffff166026145b1561040b578661016001518263ffffffff166020811061040057610400611e69565b602002015192508190505b60048563ffffffff1610158015610428575060088563ffffffff16105b8061043957508463ffffffff166001145b156104585761044a858784876109ab565b975050505050505050610666565b63ffffffff60006020878316106104bd576104788861ffff166010610938565b9095019463fffffffc861661048e81600161078b565b915060288863ffffffff16101580156104ae57508763ffffffff16603014155b156104bb57809250600093505b505b60006104cb89888885610bbb565b63ffffffff9081169150603f8a169089161580156104f0575060088163ffffffff1610155b80156105025750601c8163ffffffff16105b156105df578063ffffffff166008148061052257508063ffffffff166009145b15610559576105478163ffffffff1660081461053e5785610541565b60005b89610847565b9b505050505050505050505050610666565b8063ffffffff16600a0361057957610547858963ffffffff8a161561134b565b8063ffffffff16600b0361059a57610547858963ffffffff8a16151561134b565b8063ffffffff16600c036105b1576105478d611431565b60108163ffffffff16101580156105ce5750601c8163ffffffff16105b156105df5761054781898988611968565b8863ffffffff1660381480156105fa575063ffffffff861615155b1561062f5760018b61016001518763ffffffff166020811061061e5761061e611e69565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff1461064c5761064c84600184611b62565b6106588583600161134b565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b602081101561070e57601c86015184526020909501946004909301926001016106ea565b506000835283830384a060009450806001811461072e5760039550610756565b828015610746576001811461074f5760029650610754565b60009650610754565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061079783611c06565b905060038416156107a757600080fd5b6020810190358460051c8160005b601b81101561080d5760208501943583821c60011680156107dd57600181146107f257610803565b60008481526020839052604090209350610803565b600082815260208590526040902093505b50506001016107b5565b50608051915081811461082857630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b6000610851611caf565b60809050806060015160040163ffffffff16816080015163ffffffff16146108da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff90811690935285831690529085161561093057806008018261016001518663ffffffff166020811061091f5761091f611e69565b63ffffffff90921660209290920201525b61066661066f565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610995576000610997565b815b90861663ffffffff16179250505092915050565b60006109b5611caf565b608090506000816060015160040163ffffffff16826080015163ffffffff1614610a3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f7400000000000000000000000060448201526064016108d1565b8663ffffffff1660041480610a5657508663ffffffff166005145b15610ad25760008261016001518663ffffffff1660208110610a7a57610a7a611e69565b602002015190508063ffffffff168563ffffffff16148015610aa257508763ffffffff166004145b80610aca57508063ffffffff168563ffffffff1614158015610aca57508763ffffffff166005145b915050610b4f565b8663ffffffff16600603610aef5760008460030b13159050610b4f565b8663ffffffff16600703610b0b5760008460030b139050610b4f565b8663ffffffff16600103610b4f57601f601087901c166000819003610b345760008560030b1291505b8063ffffffff16600103610b4d5760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b95576002610b7a8861ffff166010610938565b63ffffffff90811690911b8201600401166080840152610ba7565b60808301805160040163ffffffff1690525b610baf61066f565b98975050505050505050565b6000603f601a86901c16801580610bea575060088163ffffffff1610158015610bea5750600f8163ffffffff16105b1561104057603f86168160088114610c315760098114610c3a57600a8114610c4357600b8114610c4c57600c8114610c5557600d8114610c5e57600e8114610c6757610c6c565b60209150610c6c565b60219150610c6c565b602a9150610c6c565b602b9150610c6c565b60249150610c6c565b60259150610c6c565b602691505b508063ffffffff16600003610c935750505063ffffffff8216601f600686901c161b611343565b8063ffffffff16600203610cb95750505063ffffffff8216601f600686901c161c611343565b8063ffffffff16600303610cef57601f600688901c16610ce563ffffffff8716821c6020839003610938565b9350505050611343565b8063ffffffff16600403610d115750505063ffffffff8216601f84161b611343565b8063ffffffff16600603610d335750505063ffffffff8216601f84161c611343565b8063ffffffff16600703610d6657610d5d8663ffffffff168663ffffffff16901c87602003610938565b92505050611343565b8063ffffffff16600803610d7e578592505050611343565b8063ffffffff16600903610d96578592505050611343565b8063ffffffff16600a03610dae578592505050611343565b8063ffffffff16600b03610dc6578592505050611343565b8063ffffffff16600c03610dde578592505050611343565b8063ffffffff16600f03610df6578592505050611343565b8063ffffffff16601003610e0e578592505050611343565b8063ffffffff16601103610e26578592505050611343565b8063ffffffff16601203610e3e578592505050611343565b8063ffffffff16601303610e56578592505050611343565b8063ffffffff16601803610e6e578592505050611343565b8063ffffffff16601903610e86578592505050611343565b8063ffffffff16601a03610e9e578592505050611343565b8063ffffffff16601b03610eb6578592505050611343565b8063ffffffff16602003610ecf57505050828201611343565b8063ffffffff16602103610ee857505050828201611343565b8063ffffffff16602203610f0157505050818303611343565b8063ffffffff16602303610f1a57505050818303611343565b8063ffffffff16602403610f3357505050828216611343565b8063ffffffff16602503610f4c57505050828217611343565b8063ffffffff16602603610f6557505050828218611343565b8063ffffffff16602703610f7f5750505082821719611343565b8063ffffffff16602a03610fb0578460030b8660030b12610fa1576000610fa4565b60015b60ff1692505050611343565b8063ffffffff16602b03610fd8578463ffffffff168663ffffffff1610610fa1576000610fa4565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e0000000000000000000000000060448201526064016108d1565b50610fd8565b8063ffffffff16601c036110c457603f8616600281900361106657505050828202611343565b8063ffffffff166020148061108157508063ffffffff166021145b1561103a578063ffffffff16602003611098579419945b60005b63800000008716156110ba576401fffffffe600197881b16960161109b565b9250611343915050565b8063ffffffff16600f036110e657505065ffffffff0000601083901b16611343565b8063ffffffff166020036111225761111a8560031660080260180363ffffffff168463ffffffff16901c60ff166008610938565b915050611343565b8063ffffffff166021036111575761111a8560021660080260100363ffffffff168463ffffffff16901c61ffff166010610938565b8063ffffffff1660220361118657505063ffffffff60086003851602811681811b198416918316901b17611343565b8063ffffffff1660230361119d5782915050611343565b8063ffffffff166024036111cf578460031660080260180363ffffffff168363ffffffff16901c60ff16915050611343565b8063ffffffff16602503611202578460021660080260100363ffffffff168363ffffffff16901c61ffff16915050611343565b8063ffffffff1660260361123457505063ffffffff60086003851602601803811681811c198416918316901c17611343565b8063ffffffff1660280361126a57505060ff63ffffffff60086003861602601803811682811b9091188316918416901b17611343565b8063ffffffff166029036112a157505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b17611343565b8063ffffffff16602a036112d057505063ffffffff60086003851602811681811c198316918416901c17611343565b8063ffffffff16602b036112e75783915050611343565b8063ffffffff16602e0361131957505063ffffffff60086003851602601803811681811b198316918416901b17611343565b8063ffffffff166030036113305782915050611343565b8063ffffffff16603803610fd857839150505b949350505050565b6000611355611caf565b506080602063ffffffff8616106113c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c696420726567697374657200000000000000000000000000000000000060448201526064016108d1565b63ffffffff8516158015906113da5750825b1561140e57838161016001518663ffffffff16602081106113fd576113fd611e69565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261066661066f565b600061143b611caf565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114b55781610fff81161561148457610fff811661100003015b8363ffffffff166000036114ab5760e08801805163ffffffff8382011690915295506114af565b8395505b50611927565b8563ffffffff16610fcd036114d05763400000009450611927565b8563ffffffff16611018036114e85760019450611927565b8563ffffffff166110960361151e57600161012088015260ff831661010088015261151161066f565b9998505050505050505050565b8563ffffffff16610fa30361178a5763ffffffff831615611927577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016117445760006115798363fffffffc16600161078b565b60208901519091508060001a6001036115e857604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ad9190611e98565b915091506003861680600403828110156116c5578092505b50818610156116d2578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506117298663fffffffc16600186611b62565b60408b018051820163ffffffff169052975061178592505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff84160161177957809450611927565b63ffffffff9450600993505b611927565b8563ffffffff16610fa40361187b5763ffffffff8316600114806117b4575063ffffffff83166002145b806117c5575063ffffffff83166004145b156117d257809450611927565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117795760006118128363fffffffc16600161078b565b6020890151909150600384166004038381101561182d578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b17602088015260006040880152935083611927565b8563ffffffff16610fd703611927578163ffffffff1660030361191b5763ffffffff831615806118b1575063ffffffff83166005145b806118c2575063ffffffff83166003145b156118d05760009450611927565b63ffffffff8316600114806118eb575063ffffffff83166002145b806118fc575063ffffffff83166006145b8061190d575063ffffffff83166004145b156117795760019450611927565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b0152600401909116905261151161066f565b6000611972611caf565b506080600063ffffffff8716601003611990575060c0810151611af9565b8663ffffffff166011036119af5763ffffffff861660c0830152611af9565b8663ffffffff166012036119c8575060a0810151611af9565b8663ffffffff166013036119e75763ffffffff861660a0830152611af9565b8663ffffffff16601803611a1b5763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611af9565b8663ffffffff16601903611a4c5763ffffffff86811681871602602081901c821660c08501521660a0830152611af9565b8663ffffffff16601a03611aa2578460030b8660030b81611a6f57611a6f611ebc565b0763ffffffff1660c0830152600385810b9087900b81611a9157611a91611ebc565b0563ffffffff1660a0830152611af9565b8663ffffffff16601b03611af9578463ffffffff168663ffffffff1681611acb57611acb611ebc565b0663ffffffff90811660c084015285811690871681611aec57611aec611ebc565b0463ffffffff1660a08301525b63ffffffff841615611b3457808261016001518563ffffffff1660208110611b2357611b23611e69565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b5761066f565b979650505050505050565b6000611b6d83611c06565b90506003841615611b7d57600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611bfb5760208401933582821c6001168015611bcb5760018114611be057611bf1565b60008581526020839052604090209450611bf1565b600082815260208690526040902094505b5050600101611ba3565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611ca9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f617461000000000000000000000000000000000000000000000000000000000060648201526084016108d1565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611d15611d1a565b905290565b6040518061040001604052806020906020820280368337509192915050565b600060208083528351808285015260005b81811015611d6657858101830151858201604001528201611d4a565b81811115611d78576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60008083601f840112611dbe57600080fd5b50813567ffffffffffffffff811115611dd657600080fd5b602083019150836020828501011115611dee57600080fd5b9250929050565b600080600080600060608688031215611e0d57600080fd5b853567ffffffffffffffff80821115611e2557600080fd5b611e3189838a01611dac565b90975095506020880135915080821115611e4a57600080fd5b50611e5788828901611dac565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611eab57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:187:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:351;176:23;;;158:42;;146:2;131:18;1710:45:187;;;;;;;;2448:99;;;412:42:351;2534:6:187;400:55:351;382:74;;370:2;355:18;2448:99:187;211:251:351;26025:6379:187;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:351;;;1743:2;1728:18;26025:6379:187;1609:177:351;26025:6379:187;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:187;;-1:-1:-1;28593:7:187;:20::i;:::-;28579:34;-1:-1:-1;28643:10:187;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:187;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:187;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:187;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:187;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:187;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:187:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:187;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:187;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:187:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:351;19164:28:187;;;2164:21:351;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:187;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:187;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:351;14107:30:187;;;2511:21:351;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:187;2327:344:351;14055:97:187;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:187:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:187;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:187;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:187;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:187;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:187;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:187;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:187;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:187;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:187;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:187;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:187;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:187;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:351;37406:29:187;;;2860:21:351;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:187;2676:343:351;37297:157:187;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:187;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:187;;-1:-1:-1;;38164:8:187;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:187;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:187;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:187;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:187;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:187;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:187;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:187;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:187;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:351;20288:41:187;;;3208:21:351;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:187;3024:338:351;20288:41:187;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:187;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:187;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:187:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:187;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:188;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:187;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:351;;;8234:54:187;3601:23:351;;;3581:18;;;3574:51;8203:11:187;;;;8234:19;:6;:19;;;;3513:18:351;;8234:54:187;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:187;;-1:-1:-1;;;7642:2553:187;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:187;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:187;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:187;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:187;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:187;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:187;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:187;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:187;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:187;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:187;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:187;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:187;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:187;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:187:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:187;25120:9;25084:343;;;-1:-1:-1;;25526:4:187;25519:18;-1:-1:-1;;;;23913:1654:187:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:351;21415:72:187;;;4259:21:351;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:187;4075:399:351;21415:72:187;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:351:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:351;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:351;-1:-1:-1;1349:2:351;1334:18;;1321:32;;-1:-1:-1;1365:16:351;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:351;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:351:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:351;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:351:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { @@ -24,4 +23,5 @@ func init() { layouts["MIPS"] = MIPSStorageLayout deployedBytecodes["MIPS"] = MIPSDeployedBin + immutableReferences["MIPS"] = true } diff --git a/op-bindings/bindings/multicall3.go b/op-bindings/bindings/multicall3.go new file mode 100644 index 000000000000..68cf9c8507b7 --- /dev/null +++ b/op-bindings/bindings/multicall3.go @@ -0,0 +1,665 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// Multicall3Call is an auto generated low-level Go binding around an user-defined struct. +type Multicall3Call struct { + Target common.Address + CallData []byte +} + +// Multicall3Call3 is an auto generated low-level Go binding around an user-defined struct. +type Multicall3Call3 struct { + Target common.Address + AllowFailure bool + CallData []byte +} + +// Multicall3Call3Value is an auto generated low-level Go binding around an user-defined struct. +type Multicall3Call3Value struct { + Target common.Address + AllowFailure bool + Value *big.Int + CallData []byte +} + +// Multicall3Result is an auto generated low-level Go binding around an user-defined struct. +type Multicall3Result struct { + Success bool + ReturnData []byte +} + +// MultiCall3MetaData contains all meta data concerning the MultiCall3 contract. +var MultiCall3MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"returnData\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call3[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call3Value[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3Value\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"blockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBasefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"basefee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockCoinbase\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockDifficulty\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"difficulty\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gaslimit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getEthBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryAggregate\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryBlockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50610ee0806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033", +} + +// MultiCall3ABI is the input ABI used to generate the binding from. +// Deprecated: Use MultiCall3MetaData.ABI instead. +var MultiCall3ABI = MultiCall3MetaData.ABI + +// MultiCall3Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MultiCall3MetaData.Bin instead. +var MultiCall3Bin = MultiCall3MetaData.Bin + +// DeployMultiCall3 deploys a new Ethereum contract, binding an instance of MultiCall3 to it. +func DeployMultiCall3(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MultiCall3, error) { + parsed, err := MultiCall3MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MultiCall3Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MultiCall3{MultiCall3Caller: MultiCall3Caller{contract: contract}, MultiCall3Transactor: MultiCall3Transactor{contract: contract}, MultiCall3Filterer: MultiCall3Filterer{contract: contract}}, nil +} + +// MultiCall3 is an auto generated Go binding around an Ethereum contract. +type MultiCall3 struct { + MultiCall3Caller // Read-only binding to the contract + MultiCall3Transactor // Write-only binding to the contract + MultiCall3Filterer // Log filterer for contract events +} + +// MultiCall3Caller is an auto generated read-only Go binding around an Ethereum contract. +type MultiCall3Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MultiCall3Transactor is an auto generated write-only Go binding around an Ethereum contract. +type MultiCall3Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MultiCall3Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MultiCall3Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MultiCall3Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type MultiCall3Session struct { + Contract *MultiCall3 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MultiCall3CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type MultiCall3CallerSession struct { + Contract *MultiCall3Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// MultiCall3TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type MultiCall3TransactorSession struct { + Contract *MultiCall3Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MultiCall3Raw is an auto generated low-level Go binding around an Ethereum contract. +type MultiCall3Raw struct { + Contract *MultiCall3 // Generic contract binding to access the raw methods on +} + +// MultiCall3CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MultiCall3CallerRaw struct { + Contract *MultiCall3Caller // Generic read-only contract binding to access the raw methods on +} + +// MultiCall3TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MultiCall3TransactorRaw struct { + Contract *MultiCall3Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewMultiCall3 creates a new instance of MultiCall3, bound to a specific deployed contract. +func NewMultiCall3(address common.Address, backend bind.ContractBackend) (*MultiCall3, error) { + contract, err := bindMultiCall3(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MultiCall3{MultiCall3Caller: MultiCall3Caller{contract: contract}, MultiCall3Transactor: MultiCall3Transactor{contract: contract}, MultiCall3Filterer: MultiCall3Filterer{contract: contract}}, nil +} + +// NewMultiCall3Caller creates a new read-only instance of MultiCall3, bound to a specific deployed contract. +func NewMultiCall3Caller(address common.Address, caller bind.ContractCaller) (*MultiCall3Caller, error) { + contract, err := bindMultiCall3(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MultiCall3Caller{contract: contract}, nil +} + +// NewMultiCall3Transactor creates a new write-only instance of MultiCall3, bound to a specific deployed contract. +func NewMultiCall3Transactor(address common.Address, transactor bind.ContractTransactor) (*MultiCall3Transactor, error) { + contract, err := bindMultiCall3(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MultiCall3Transactor{contract: contract}, nil +} + +// NewMultiCall3Filterer creates a new log filterer instance of MultiCall3, bound to a specific deployed contract. +func NewMultiCall3Filterer(address common.Address, filterer bind.ContractFilterer) (*MultiCall3Filterer, error) { + contract, err := bindMultiCall3(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MultiCall3Filterer{contract: contract}, nil +} + +// bindMultiCall3 binds a generic wrapper to an already deployed contract. +func bindMultiCall3(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MultiCall3ABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MultiCall3 *MultiCall3Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MultiCall3.Contract.MultiCall3Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MultiCall3 *MultiCall3Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiCall3.Contract.MultiCall3Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MultiCall3 *MultiCall3Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MultiCall3.Contract.MultiCall3Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MultiCall3 *MultiCall3CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MultiCall3.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MultiCall3 *MultiCall3TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiCall3.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MultiCall3 *MultiCall3TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MultiCall3.Contract.contract.Transact(opts, method, params...) +} + +// GetBasefee is a free data retrieval call binding the contract method 0x3e64a696. +// +// Solidity: function getBasefee() view returns(uint256 basefee) +func (_MultiCall3 *MultiCall3Caller) GetBasefee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MultiCall3.contract.Call(opts, &out, "getBasefee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetBasefee is a free data retrieval call binding the contract method 0x3e64a696. +// +// Solidity: function getBasefee() view returns(uint256 basefee) +func (_MultiCall3 *MultiCall3Session) GetBasefee() (*big.Int, error) { + return _MultiCall3.Contract.GetBasefee(&_MultiCall3.CallOpts) +} + +// GetBasefee is a free data retrieval call binding the contract method 0x3e64a696. +// +// Solidity: function getBasefee() view returns(uint256 basefee) +func (_MultiCall3 *MultiCall3CallerSession) GetBasefee() (*big.Int, error) { + return _MultiCall3.Contract.GetBasefee(&_MultiCall3.CallOpts) +} + +// GetBlockHash is a free data retrieval call binding the contract method 0xee82ac5e. +// +// Solidity: function getBlockHash(uint256 blockNumber) view returns(bytes32 blockHash) +func (_MultiCall3 *MultiCall3Caller) GetBlockHash(opts *bind.CallOpts, blockNumber *big.Int) ([32]byte, error) { + var out []interface{} + err := _MultiCall3.contract.Call(opts, &out, "getBlockHash", blockNumber) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockHash is a free data retrieval call binding the contract method 0xee82ac5e. +// +// Solidity: function getBlockHash(uint256 blockNumber) view returns(bytes32 blockHash) +func (_MultiCall3 *MultiCall3Session) GetBlockHash(blockNumber *big.Int) ([32]byte, error) { + return _MultiCall3.Contract.GetBlockHash(&_MultiCall3.CallOpts, blockNumber) +} + +// GetBlockHash is a free data retrieval call binding the contract method 0xee82ac5e. +// +// Solidity: function getBlockHash(uint256 blockNumber) view returns(bytes32 blockHash) +func (_MultiCall3 *MultiCall3CallerSession) GetBlockHash(blockNumber *big.Int) ([32]byte, error) { + return _MultiCall3.Contract.GetBlockHash(&_MultiCall3.CallOpts, blockNumber) +} + +// GetBlockNumber is a free data retrieval call binding the contract method 0x42cbb15c. +// +// Solidity: function getBlockNumber() view returns(uint256 blockNumber) +func (_MultiCall3 *MultiCall3Caller) GetBlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MultiCall3.contract.Call(opts, &out, "getBlockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetBlockNumber is a free data retrieval call binding the contract method 0x42cbb15c. +// +// Solidity: function getBlockNumber() view returns(uint256 blockNumber) +func (_MultiCall3 *MultiCall3Session) GetBlockNumber() (*big.Int, error) { + return _MultiCall3.Contract.GetBlockNumber(&_MultiCall3.CallOpts) +} + +// GetBlockNumber is a free data retrieval call binding the contract method 0x42cbb15c. +// +// Solidity: function getBlockNumber() view returns(uint256 blockNumber) +func (_MultiCall3 *MultiCall3CallerSession) GetBlockNumber() (*big.Int, error) { + return _MultiCall3.Contract.GetBlockNumber(&_MultiCall3.CallOpts) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256 chainid) +func (_MultiCall3 *MultiCall3Caller) GetChainId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MultiCall3.contract.Call(opts, &out, "getChainId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256 chainid) +func (_MultiCall3 *MultiCall3Session) GetChainId() (*big.Int, error) { + return _MultiCall3.Contract.GetChainId(&_MultiCall3.CallOpts) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256 chainid) +func (_MultiCall3 *MultiCall3CallerSession) GetChainId() (*big.Int, error) { + return _MultiCall3.Contract.GetChainId(&_MultiCall3.CallOpts) +} + +// GetCurrentBlockCoinbase is a free data retrieval call binding the contract method 0xa8b0574e. +// +// Solidity: function getCurrentBlockCoinbase() view returns(address coinbase) +func (_MultiCall3 *MultiCall3Caller) GetCurrentBlockCoinbase(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _MultiCall3.contract.Call(opts, &out, "getCurrentBlockCoinbase") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetCurrentBlockCoinbase is a free data retrieval call binding the contract method 0xa8b0574e. +// +// Solidity: function getCurrentBlockCoinbase() view returns(address coinbase) +func (_MultiCall3 *MultiCall3Session) GetCurrentBlockCoinbase() (common.Address, error) { + return _MultiCall3.Contract.GetCurrentBlockCoinbase(&_MultiCall3.CallOpts) +} + +// GetCurrentBlockCoinbase is a free data retrieval call binding the contract method 0xa8b0574e. +// +// Solidity: function getCurrentBlockCoinbase() view returns(address coinbase) +func (_MultiCall3 *MultiCall3CallerSession) GetCurrentBlockCoinbase() (common.Address, error) { + return _MultiCall3.Contract.GetCurrentBlockCoinbase(&_MultiCall3.CallOpts) +} + +// GetCurrentBlockDifficulty is a free data retrieval call binding the contract method 0x72425d9d. +// +// Solidity: function getCurrentBlockDifficulty() view returns(uint256 difficulty) +func (_MultiCall3 *MultiCall3Caller) GetCurrentBlockDifficulty(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MultiCall3.contract.Call(opts, &out, "getCurrentBlockDifficulty") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetCurrentBlockDifficulty is a free data retrieval call binding the contract method 0x72425d9d. +// +// Solidity: function getCurrentBlockDifficulty() view returns(uint256 difficulty) +func (_MultiCall3 *MultiCall3Session) GetCurrentBlockDifficulty() (*big.Int, error) { + return _MultiCall3.Contract.GetCurrentBlockDifficulty(&_MultiCall3.CallOpts) +} + +// GetCurrentBlockDifficulty is a free data retrieval call binding the contract method 0x72425d9d. +// +// Solidity: function getCurrentBlockDifficulty() view returns(uint256 difficulty) +func (_MultiCall3 *MultiCall3CallerSession) GetCurrentBlockDifficulty() (*big.Int, error) { + return _MultiCall3.Contract.GetCurrentBlockDifficulty(&_MultiCall3.CallOpts) +} + +// GetCurrentBlockGasLimit is a free data retrieval call binding the contract method 0x86d516e8. +// +// Solidity: function getCurrentBlockGasLimit() view returns(uint256 gaslimit) +func (_MultiCall3 *MultiCall3Caller) GetCurrentBlockGasLimit(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MultiCall3.contract.Call(opts, &out, "getCurrentBlockGasLimit") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetCurrentBlockGasLimit is a free data retrieval call binding the contract method 0x86d516e8. +// +// Solidity: function getCurrentBlockGasLimit() view returns(uint256 gaslimit) +func (_MultiCall3 *MultiCall3Session) GetCurrentBlockGasLimit() (*big.Int, error) { + return _MultiCall3.Contract.GetCurrentBlockGasLimit(&_MultiCall3.CallOpts) +} + +// GetCurrentBlockGasLimit is a free data retrieval call binding the contract method 0x86d516e8. +// +// Solidity: function getCurrentBlockGasLimit() view returns(uint256 gaslimit) +func (_MultiCall3 *MultiCall3CallerSession) GetCurrentBlockGasLimit() (*big.Int, error) { + return _MultiCall3.Contract.GetCurrentBlockGasLimit(&_MultiCall3.CallOpts) +} + +// GetCurrentBlockTimestamp is a free data retrieval call binding the contract method 0x0f28c97d. +// +// Solidity: function getCurrentBlockTimestamp() view returns(uint256 timestamp) +func (_MultiCall3 *MultiCall3Caller) GetCurrentBlockTimestamp(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MultiCall3.contract.Call(opts, &out, "getCurrentBlockTimestamp") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetCurrentBlockTimestamp is a free data retrieval call binding the contract method 0x0f28c97d. +// +// Solidity: function getCurrentBlockTimestamp() view returns(uint256 timestamp) +func (_MultiCall3 *MultiCall3Session) GetCurrentBlockTimestamp() (*big.Int, error) { + return _MultiCall3.Contract.GetCurrentBlockTimestamp(&_MultiCall3.CallOpts) +} + +// GetCurrentBlockTimestamp is a free data retrieval call binding the contract method 0x0f28c97d. +// +// Solidity: function getCurrentBlockTimestamp() view returns(uint256 timestamp) +func (_MultiCall3 *MultiCall3CallerSession) GetCurrentBlockTimestamp() (*big.Int, error) { + return _MultiCall3.Contract.GetCurrentBlockTimestamp(&_MultiCall3.CallOpts) +} + +// GetEthBalance is a free data retrieval call binding the contract method 0x4d2301cc. +// +// Solidity: function getEthBalance(address addr) view returns(uint256 balance) +func (_MultiCall3 *MultiCall3Caller) GetEthBalance(opts *bind.CallOpts, addr common.Address) (*big.Int, error) { + var out []interface{} + err := _MultiCall3.contract.Call(opts, &out, "getEthBalance", addr) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetEthBalance is a free data retrieval call binding the contract method 0x4d2301cc. +// +// Solidity: function getEthBalance(address addr) view returns(uint256 balance) +func (_MultiCall3 *MultiCall3Session) GetEthBalance(addr common.Address) (*big.Int, error) { + return _MultiCall3.Contract.GetEthBalance(&_MultiCall3.CallOpts, addr) +} + +// GetEthBalance is a free data retrieval call binding the contract method 0x4d2301cc. +// +// Solidity: function getEthBalance(address addr) view returns(uint256 balance) +func (_MultiCall3 *MultiCall3CallerSession) GetEthBalance(addr common.Address) (*big.Int, error) { + return _MultiCall3.Contract.GetEthBalance(&_MultiCall3.CallOpts, addr) +} + +// GetLastBlockHash is a free data retrieval call binding the contract method 0x27e86d6e. +// +// Solidity: function getLastBlockHash() view returns(bytes32 blockHash) +func (_MultiCall3 *MultiCall3Caller) GetLastBlockHash(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _MultiCall3.contract.Call(opts, &out, "getLastBlockHash") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetLastBlockHash is a free data retrieval call binding the contract method 0x27e86d6e. +// +// Solidity: function getLastBlockHash() view returns(bytes32 blockHash) +func (_MultiCall3 *MultiCall3Session) GetLastBlockHash() ([32]byte, error) { + return _MultiCall3.Contract.GetLastBlockHash(&_MultiCall3.CallOpts) +} + +// GetLastBlockHash is a free data retrieval call binding the contract method 0x27e86d6e. +// +// Solidity: function getLastBlockHash() view returns(bytes32 blockHash) +func (_MultiCall3 *MultiCall3CallerSession) GetLastBlockHash() ([32]byte, error) { + return _MultiCall3.Contract.GetLastBlockHash(&_MultiCall3.CallOpts) +} + +// Aggregate is a paid mutator transaction binding the contract method 0x252dba42. +// +// Solidity: function aggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes[] returnData) +func (_MultiCall3 *MultiCall3Transactor) Aggregate(opts *bind.TransactOpts, calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.contract.Transact(opts, "aggregate", calls) +} + +// Aggregate is a paid mutator transaction binding the contract method 0x252dba42. +// +// Solidity: function aggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes[] returnData) +func (_MultiCall3 *MultiCall3Session) Aggregate(calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.Contract.Aggregate(&_MultiCall3.TransactOpts, calls) +} + +// Aggregate is a paid mutator transaction binding the contract method 0x252dba42. +// +// Solidity: function aggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes[] returnData) +func (_MultiCall3 *MultiCall3TransactorSession) Aggregate(calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.Contract.Aggregate(&_MultiCall3.TransactOpts, calls) +} + +// Aggregate3 is a paid mutator transaction binding the contract method 0x82ad56cb. +// +// Solidity: function aggregate3((address,bool,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3Transactor) Aggregate3(opts *bind.TransactOpts, calls []Multicall3Call3) (*types.Transaction, error) { + return _MultiCall3.contract.Transact(opts, "aggregate3", calls) +} + +// Aggregate3 is a paid mutator transaction binding the contract method 0x82ad56cb. +// +// Solidity: function aggregate3((address,bool,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3Session) Aggregate3(calls []Multicall3Call3) (*types.Transaction, error) { + return _MultiCall3.Contract.Aggregate3(&_MultiCall3.TransactOpts, calls) +} + +// Aggregate3 is a paid mutator transaction binding the contract method 0x82ad56cb. +// +// Solidity: function aggregate3((address,bool,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3TransactorSession) Aggregate3(calls []Multicall3Call3) (*types.Transaction, error) { + return _MultiCall3.Contract.Aggregate3(&_MultiCall3.TransactOpts, calls) +} + +// Aggregate3Value is a paid mutator transaction binding the contract method 0x174dea71. +// +// Solidity: function aggregate3Value((address,bool,uint256,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3Transactor) Aggregate3Value(opts *bind.TransactOpts, calls []Multicall3Call3Value) (*types.Transaction, error) { + return _MultiCall3.contract.Transact(opts, "aggregate3Value", calls) +} + +// Aggregate3Value is a paid mutator transaction binding the contract method 0x174dea71. +// +// Solidity: function aggregate3Value((address,bool,uint256,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3Session) Aggregate3Value(calls []Multicall3Call3Value) (*types.Transaction, error) { + return _MultiCall3.Contract.Aggregate3Value(&_MultiCall3.TransactOpts, calls) +} + +// Aggregate3Value is a paid mutator transaction binding the contract method 0x174dea71. +// +// Solidity: function aggregate3Value((address,bool,uint256,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3TransactorSession) Aggregate3Value(calls []Multicall3Call3Value) (*types.Transaction, error) { + return _MultiCall3.Contract.Aggregate3Value(&_MultiCall3.TransactOpts, calls) +} + +// BlockAndAggregate is a paid mutator transaction binding the contract method 0xc3077fa9. +// +// Solidity: function blockAndAggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3Transactor) BlockAndAggregate(opts *bind.TransactOpts, calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.contract.Transact(opts, "blockAndAggregate", calls) +} + +// BlockAndAggregate is a paid mutator transaction binding the contract method 0xc3077fa9. +// +// Solidity: function blockAndAggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3Session) BlockAndAggregate(calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.Contract.BlockAndAggregate(&_MultiCall3.TransactOpts, calls) +} + +// BlockAndAggregate is a paid mutator transaction binding the contract method 0xc3077fa9. +// +// Solidity: function blockAndAggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3TransactorSession) BlockAndAggregate(calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.Contract.BlockAndAggregate(&_MultiCall3.TransactOpts, calls) +} + +// TryAggregate is a paid mutator transaction binding the contract method 0xbce38bd7. +// +// Solidity: function tryAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3Transactor) TryAggregate(opts *bind.TransactOpts, requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.contract.Transact(opts, "tryAggregate", requireSuccess, calls) +} + +// TryAggregate is a paid mutator transaction binding the contract method 0xbce38bd7. +// +// Solidity: function tryAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3Session) TryAggregate(requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.Contract.TryAggregate(&_MultiCall3.TransactOpts, requireSuccess, calls) +} + +// TryAggregate is a paid mutator transaction binding the contract method 0xbce38bd7. +// +// Solidity: function tryAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3TransactorSession) TryAggregate(requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.Contract.TryAggregate(&_MultiCall3.TransactOpts, requireSuccess, calls) +} + +// TryBlockAndAggregate is a paid mutator transaction binding the contract method 0x399542e9. +// +// Solidity: function tryBlockAndAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3Transactor) TryBlockAndAggregate(opts *bind.TransactOpts, requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.contract.Transact(opts, "tryBlockAndAggregate", requireSuccess, calls) +} + +// TryBlockAndAggregate is a paid mutator transaction binding the contract method 0x399542e9. +// +// Solidity: function tryBlockAndAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3Session) TryBlockAndAggregate(requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.Contract.TryBlockAndAggregate(&_MultiCall3.TransactOpts, requireSuccess, calls) +} + +// TryBlockAndAggregate is a paid mutator transaction binding the contract method 0x399542e9. +// +// Solidity: function tryBlockAndAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_MultiCall3 *MultiCall3TransactorSession) TryBlockAndAggregate(requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _MultiCall3.Contract.TryBlockAndAggregate(&_MultiCall3.TransactOpts, requireSuccess, calls) +} diff --git a/op-bindings/bindings/multicall3_more.go b/op-bindings/bindings/multicall3_more.go new file mode 100644 index 000000000000..aff7e0660fa5 --- /dev/null +++ b/op-bindings/bindings/multicall3_more.go @@ -0,0 +1,9 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var MultiCall3DeployedBin = "0x6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033" +func init() { + deployedBytecodes["MultiCall3"] = MultiCall3DeployedBin +} diff --git a/op-bindings/bindings/multisend_v130.go b/op-bindings/bindings/multisend_v130.go new file mode 100644 index 000000000000..94d019113d66 --- /dev/null +++ b/op-bindings/bindings/multisend_v130.go @@ -0,0 +1,223 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// MultiSendV130MetaData contains all meta data concerning the MultiSendV130 contract. +var MultiSendV130MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"}],\"name\":\"multiSend\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561001057600080fd5b503073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b8152505060805160601c6102756100646000398060e052506102756000f3fe60806040526004361061001e5760003560e01c80638d80ff0a14610023575b600080fd5b6100dc6004803603602081101561003957600080fd5b810190808035906020019064010000000081111561005657600080fd5b82018360208201111561006857600080fd5b8035906020019184600183028401116401000000008311171561008a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100de565b005b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161415610183576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806102106030913960400191505060405180910390fd5b805160205b8181101561020a578083015160f81c6001820184015160601c6015830185015160358401860151605585018701600085600081146101cd57600181146101dd576101e8565b6000808585888a5af191506101e8565b6000808585895af491505b5060008114156101f757600080fd5b8260550187019650505050505050610188565b50505056fe4d756c746953656e642073686f756c64206f6e6c792062652063616c6c6564207669612064656c656761746563616c6ca26469706673582212205c784303626eec02b71940b551976170b500a8a36cc5adcbeb2c19751a76d05464736f6c63430007060033", +} + +// MultiSendV130ABI is the input ABI used to generate the binding from. +// Deprecated: Use MultiSendV130MetaData.ABI instead. +var MultiSendV130ABI = MultiSendV130MetaData.ABI + +// MultiSendV130Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MultiSendV130MetaData.Bin instead. +var MultiSendV130Bin = MultiSendV130MetaData.Bin + +// DeployMultiSendV130 deploys a new Ethereum contract, binding an instance of MultiSendV130 to it. +func DeployMultiSendV130(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MultiSendV130, error) { + parsed, err := MultiSendV130MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MultiSendV130Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MultiSendV130{MultiSendV130Caller: MultiSendV130Caller{contract: contract}, MultiSendV130Transactor: MultiSendV130Transactor{contract: contract}, MultiSendV130Filterer: MultiSendV130Filterer{contract: contract}}, nil +} + +// MultiSendV130 is an auto generated Go binding around an Ethereum contract. +type MultiSendV130 struct { + MultiSendV130Caller // Read-only binding to the contract + MultiSendV130Transactor // Write-only binding to the contract + MultiSendV130Filterer // Log filterer for contract events +} + +// MultiSendV130Caller is an auto generated read-only Go binding around an Ethereum contract. +type MultiSendV130Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MultiSendV130Transactor is an auto generated write-only Go binding around an Ethereum contract. +type MultiSendV130Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MultiSendV130Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MultiSendV130Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MultiSendV130Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type MultiSendV130Session struct { + Contract *MultiSendV130 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MultiSendV130CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type MultiSendV130CallerSession struct { + Contract *MultiSendV130Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// MultiSendV130TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type MultiSendV130TransactorSession struct { + Contract *MultiSendV130Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MultiSendV130Raw is an auto generated low-level Go binding around an Ethereum contract. +type MultiSendV130Raw struct { + Contract *MultiSendV130 // Generic contract binding to access the raw methods on +} + +// MultiSendV130CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MultiSendV130CallerRaw struct { + Contract *MultiSendV130Caller // Generic read-only contract binding to access the raw methods on +} + +// MultiSendV130TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MultiSendV130TransactorRaw struct { + Contract *MultiSendV130Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewMultiSendV130 creates a new instance of MultiSendV130, bound to a specific deployed contract. +func NewMultiSendV130(address common.Address, backend bind.ContractBackend) (*MultiSendV130, error) { + contract, err := bindMultiSendV130(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MultiSendV130{MultiSendV130Caller: MultiSendV130Caller{contract: contract}, MultiSendV130Transactor: MultiSendV130Transactor{contract: contract}, MultiSendV130Filterer: MultiSendV130Filterer{contract: contract}}, nil +} + +// NewMultiSendV130Caller creates a new read-only instance of MultiSendV130, bound to a specific deployed contract. +func NewMultiSendV130Caller(address common.Address, caller bind.ContractCaller) (*MultiSendV130Caller, error) { + contract, err := bindMultiSendV130(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MultiSendV130Caller{contract: contract}, nil +} + +// NewMultiSendV130Transactor creates a new write-only instance of MultiSendV130, bound to a specific deployed contract. +func NewMultiSendV130Transactor(address common.Address, transactor bind.ContractTransactor) (*MultiSendV130Transactor, error) { + contract, err := bindMultiSendV130(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MultiSendV130Transactor{contract: contract}, nil +} + +// NewMultiSendV130Filterer creates a new log filterer instance of MultiSendV130, bound to a specific deployed contract. +func NewMultiSendV130Filterer(address common.Address, filterer bind.ContractFilterer) (*MultiSendV130Filterer, error) { + contract, err := bindMultiSendV130(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MultiSendV130Filterer{contract: contract}, nil +} + +// bindMultiSendV130 binds a generic wrapper to an already deployed contract. +func bindMultiSendV130(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MultiSendV130ABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MultiSendV130 *MultiSendV130Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MultiSendV130.Contract.MultiSendV130Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MultiSendV130 *MultiSendV130Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiSendV130.Contract.MultiSendV130Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MultiSendV130 *MultiSendV130Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MultiSendV130.Contract.MultiSendV130Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MultiSendV130 *MultiSendV130CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MultiSendV130.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MultiSendV130 *MultiSendV130TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiSendV130.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MultiSendV130 *MultiSendV130TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MultiSendV130.Contract.contract.Transact(opts, method, params...) +} + +// MultiSend is a paid mutator transaction binding the contract method 0x8d80ff0a. +// +// Solidity: function multiSend(bytes transactions) payable returns() +func (_MultiSendV130 *MultiSendV130Transactor) MultiSend(opts *bind.TransactOpts, transactions []byte) (*types.Transaction, error) { + return _MultiSendV130.contract.Transact(opts, "multiSend", transactions) +} + +// MultiSend is a paid mutator transaction binding the contract method 0x8d80ff0a. +// +// Solidity: function multiSend(bytes transactions) payable returns() +func (_MultiSendV130 *MultiSendV130Session) MultiSend(transactions []byte) (*types.Transaction, error) { + return _MultiSendV130.Contract.MultiSend(&_MultiSendV130.TransactOpts, transactions) +} + +// MultiSend is a paid mutator transaction binding the contract method 0x8d80ff0a. +// +// Solidity: function multiSend(bytes transactions) payable returns() +func (_MultiSendV130 *MultiSendV130TransactorSession) MultiSend(transactions []byte) (*types.Transaction, error) { + return _MultiSendV130.Contract.MultiSend(&_MultiSendV130.TransactOpts, transactions) +} diff --git a/op-bindings/bindings/multisend_v130_more.go b/op-bindings/bindings/multisend_v130_more.go new file mode 100644 index 000000000000..9e2c7fe41236 --- /dev/null +++ b/op-bindings/bindings/multisend_v130_more.go @@ -0,0 +1,9 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var MultiSend_v130DeployedBin = "0x60806040526004361061001e5760003560e01c80638d80ff0a14610023575b600080fd5b6100dc6004803603602081101561003957600080fd5b810190808035906020019064010000000081111561005657600080fd5b82018360208201111561006857600080fd5b8035906020019184600183028401116401000000008311171561008a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100de565b005b7f000000000000000000000000998739bfdaadde7c933b942a68053933098f9eda73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161415610183576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806102106030913960400191505060405180910390fd5b805160205b8181101561020a578083015160f81c6001820184015160601c6015830185015160358401860151605585018701600085600081146101cd57600181146101dd576101e8565b6000808585888a5af191506101e8565b6000808585895af491505b5060008114156101f757600080fd5b8260550187019650505050505050610188565b50505056fe4d756c746953656e642073686f756c64206f6e6c792062652063616c6c6564207669612064656c656761746563616c6ca26469706673582212205c784303626eec02b71940b551976170b500a8a36cc5adcbeb2c19751a76d05464736f6c63430007060033" +func init() { + deployedBytecodes["MultiSend_v130"] = MultiSend_v130DeployedBin +} diff --git a/op-bindings/bindings/multisendcallonly_v130.go b/op-bindings/bindings/multisendcallonly_v130.go new file mode 100644 index 000000000000..22c4bb17c37b --- /dev/null +++ b/op-bindings/bindings/multisendcallonly_v130.go @@ -0,0 +1,223 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// MultiSendCallOnlyV130MetaData contains all meta data concerning the MultiSendCallOnlyV130 contract. +var MultiSendCallOnlyV130MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"}],\"name\":\"multiSend\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061019a806100206000396000f3fe60806040526004361061001e5760003560e01c80638d80ff0a14610023575b600080fd5b6100dc6004803603602081101561003957600080fd5b810190808035906020019064010000000081111561005657600080fd5b82018360208201111561006857600080fd5b8035906020019184600183028401116401000000008311171561008a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100de565b005b805160205b8181101561015f578083015160f81c6001820184015160601c60158301850151603584018601516055850187016000856000811461012857600181146101385761013d565b6000808585888a5af1915061013d565b600080fd5b50600081141561014c57600080fd5b82605501870196505050505050506100e3565b50505056fea264697066735822122035246402746c96964495cae5b36461fd44dfb89f8e6cf6f6b8d60c0aa89f414864736f6c63430007060033", +} + +// MultiSendCallOnlyV130ABI is the input ABI used to generate the binding from. +// Deprecated: Use MultiSendCallOnlyV130MetaData.ABI instead. +var MultiSendCallOnlyV130ABI = MultiSendCallOnlyV130MetaData.ABI + +// MultiSendCallOnlyV130Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MultiSendCallOnlyV130MetaData.Bin instead. +var MultiSendCallOnlyV130Bin = MultiSendCallOnlyV130MetaData.Bin + +// DeployMultiSendCallOnlyV130 deploys a new Ethereum contract, binding an instance of MultiSendCallOnlyV130 to it. +func DeployMultiSendCallOnlyV130(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MultiSendCallOnlyV130, error) { + parsed, err := MultiSendCallOnlyV130MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MultiSendCallOnlyV130Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MultiSendCallOnlyV130{MultiSendCallOnlyV130Caller: MultiSendCallOnlyV130Caller{contract: contract}, MultiSendCallOnlyV130Transactor: MultiSendCallOnlyV130Transactor{contract: contract}, MultiSendCallOnlyV130Filterer: MultiSendCallOnlyV130Filterer{contract: contract}}, nil +} + +// MultiSendCallOnlyV130 is an auto generated Go binding around an Ethereum contract. +type MultiSendCallOnlyV130 struct { + MultiSendCallOnlyV130Caller // Read-only binding to the contract + MultiSendCallOnlyV130Transactor // Write-only binding to the contract + MultiSendCallOnlyV130Filterer // Log filterer for contract events +} + +// MultiSendCallOnlyV130Caller is an auto generated read-only Go binding around an Ethereum contract. +type MultiSendCallOnlyV130Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MultiSendCallOnlyV130Transactor is an auto generated write-only Go binding around an Ethereum contract. +type MultiSendCallOnlyV130Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MultiSendCallOnlyV130Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MultiSendCallOnlyV130Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MultiSendCallOnlyV130Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type MultiSendCallOnlyV130Session struct { + Contract *MultiSendCallOnlyV130 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MultiSendCallOnlyV130CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type MultiSendCallOnlyV130CallerSession struct { + Contract *MultiSendCallOnlyV130Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// MultiSendCallOnlyV130TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type MultiSendCallOnlyV130TransactorSession struct { + Contract *MultiSendCallOnlyV130Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MultiSendCallOnlyV130Raw is an auto generated low-level Go binding around an Ethereum contract. +type MultiSendCallOnlyV130Raw struct { + Contract *MultiSendCallOnlyV130 // Generic contract binding to access the raw methods on +} + +// MultiSendCallOnlyV130CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MultiSendCallOnlyV130CallerRaw struct { + Contract *MultiSendCallOnlyV130Caller // Generic read-only contract binding to access the raw methods on +} + +// MultiSendCallOnlyV130TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MultiSendCallOnlyV130TransactorRaw struct { + Contract *MultiSendCallOnlyV130Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewMultiSendCallOnlyV130 creates a new instance of MultiSendCallOnlyV130, bound to a specific deployed contract. +func NewMultiSendCallOnlyV130(address common.Address, backend bind.ContractBackend) (*MultiSendCallOnlyV130, error) { + contract, err := bindMultiSendCallOnlyV130(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MultiSendCallOnlyV130{MultiSendCallOnlyV130Caller: MultiSendCallOnlyV130Caller{contract: contract}, MultiSendCallOnlyV130Transactor: MultiSendCallOnlyV130Transactor{contract: contract}, MultiSendCallOnlyV130Filterer: MultiSendCallOnlyV130Filterer{contract: contract}}, nil +} + +// NewMultiSendCallOnlyV130Caller creates a new read-only instance of MultiSendCallOnlyV130, bound to a specific deployed contract. +func NewMultiSendCallOnlyV130Caller(address common.Address, caller bind.ContractCaller) (*MultiSendCallOnlyV130Caller, error) { + contract, err := bindMultiSendCallOnlyV130(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MultiSendCallOnlyV130Caller{contract: contract}, nil +} + +// NewMultiSendCallOnlyV130Transactor creates a new write-only instance of MultiSendCallOnlyV130, bound to a specific deployed contract. +func NewMultiSendCallOnlyV130Transactor(address common.Address, transactor bind.ContractTransactor) (*MultiSendCallOnlyV130Transactor, error) { + contract, err := bindMultiSendCallOnlyV130(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MultiSendCallOnlyV130Transactor{contract: contract}, nil +} + +// NewMultiSendCallOnlyV130Filterer creates a new log filterer instance of MultiSendCallOnlyV130, bound to a specific deployed contract. +func NewMultiSendCallOnlyV130Filterer(address common.Address, filterer bind.ContractFilterer) (*MultiSendCallOnlyV130Filterer, error) { + contract, err := bindMultiSendCallOnlyV130(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MultiSendCallOnlyV130Filterer{contract: contract}, nil +} + +// bindMultiSendCallOnlyV130 binds a generic wrapper to an already deployed contract. +func bindMultiSendCallOnlyV130(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MultiSendCallOnlyV130ABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MultiSendCallOnlyV130 *MultiSendCallOnlyV130Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MultiSendCallOnlyV130.Contract.MultiSendCallOnlyV130Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MultiSendCallOnlyV130 *MultiSendCallOnlyV130Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiSendCallOnlyV130.Contract.MultiSendCallOnlyV130Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MultiSendCallOnlyV130 *MultiSendCallOnlyV130Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MultiSendCallOnlyV130.Contract.MultiSendCallOnlyV130Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MultiSendCallOnlyV130 *MultiSendCallOnlyV130CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MultiSendCallOnlyV130.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MultiSendCallOnlyV130 *MultiSendCallOnlyV130TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MultiSendCallOnlyV130.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MultiSendCallOnlyV130 *MultiSendCallOnlyV130TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MultiSendCallOnlyV130.Contract.contract.Transact(opts, method, params...) +} + +// MultiSend is a paid mutator transaction binding the contract method 0x8d80ff0a. +// +// Solidity: function multiSend(bytes transactions) payable returns() +func (_MultiSendCallOnlyV130 *MultiSendCallOnlyV130Transactor) MultiSend(opts *bind.TransactOpts, transactions []byte) (*types.Transaction, error) { + return _MultiSendCallOnlyV130.contract.Transact(opts, "multiSend", transactions) +} + +// MultiSend is a paid mutator transaction binding the contract method 0x8d80ff0a. +// +// Solidity: function multiSend(bytes transactions) payable returns() +func (_MultiSendCallOnlyV130 *MultiSendCallOnlyV130Session) MultiSend(transactions []byte) (*types.Transaction, error) { + return _MultiSendCallOnlyV130.Contract.MultiSend(&_MultiSendCallOnlyV130.TransactOpts, transactions) +} + +// MultiSend is a paid mutator transaction binding the contract method 0x8d80ff0a. +// +// Solidity: function multiSend(bytes transactions) payable returns() +func (_MultiSendCallOnlyV130 *MultiSendCallOnlyV130TransactorSession) MultiSend(transactions []byte) (*types.Transaction, error) { + return _MultiSendCallOnlyV130.Contract.MultiSend(&_MultiSendCallOnlyV130.TransactOpts, transactions) +} diff --git a/op-bindings/bindings/multisendcallonly_v130_more.go b/op-bindings/bindings/multisendcallonly_v130_more.go new file mode 100644 index 000000000000..c4c91d9704f0 --- /dev/null +++ b/op-bindings/bindings/multisendcallonly_v130_more.go @@ -0,0 +1,9 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var MultiSendCallOnly_v130DeployedBin = "0x60806040526004361061001e5760003560e01c80638d80ff0a14610023575b600080fd5b6100dc6004803603602081101561003957600080fd5b810190808035906020019064010000000081111561005657600080fd5b82018360208201111561006857600080fd5b8035906020019184600183028401116401000000008311171561008a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100de565b005b805160205b8181101561015f578083015160f81c6001820184015160601c60158301850151603584018601516055850187016000856000811461012857600181146101385761013d565b6000808585888a5af1915061013d565b600080fd5b50600081141561014c57600080fd5b82605501870196505050505050506100e3565b50505056fea264697066735822122035246402746c96964495cae5b36461fd44dfb89f8e6cf6f6b8d60c0aa89f414864736f6c63430007060033" +func init() { + deployedBytecodes["MultiSendCallOnly_v130"] = MultiSendCallOnly_v130DeployedBin +} diff --git a/op-bindings/bindings/optimismmintableerc20.go b/op-bindings/bindings/optimismmintableerc20.go index 0450ec37f705..62c4827f1be1 100644 --- a/op-bindings/bindings/optimismmintableerc20.go +++ b/op-bindings/bindings/optimismmintableerc20.go @@ -30,8 +30,8 @@ var ( // OptimismMintableERC20MetaData contains all meta data concerning the OptimismMintableERC20 contract. var OptimismMintableERC20MetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"_decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"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\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REMOTE_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"remoteToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b5060405162001ad738038062001ad7833981016040819052620000359162000177565b6001600281858560036200004a8382620002b2565b506004620000598282620002b2565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037e565b80516001600160a01b0381168114620000a557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d257600080fd5b81516001600160401b0380821115620000ef57620000ef620000aa565b604051601f8301601f19908116603f011681019082821181831017156200011a576200011a620000aa565b816040528381526020925086838588010111156200013757600080fd5b600091505b838210156200015b57858201830151818301840152908201906200013c565b838211156200016d5760008385830101525b9695505050505050565b600080600080600060a086880312156200019057600080fd5b6200019b866200008d565b9450620001ab602087016200008d565b60408701519094506001600160401b0380821115620001c957600080fd5b620001d789838a01620000c0565b94506060880151915080821115620001ee57600080fd5b50620001fd88828901620000c0565b925050608086015160ff811681146200021557600080fd5b809150509295509295909350565b600181811c908216806200023857607f821691505b6020821081036200025957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ad57600081815260208120601f850160051c81016020861015620002885750805b601f850160051c820191505b81811015620002a95782815560010162000294565b5050505b505050565b81516001600160401b03811115620002ce57620002ce620000aa565b620002e681620002df845462000223565b846200025f565b602080601f8311600181146200031e5760008415620003055750858301515b600019600386901b1c1916600185901b178555620002a9565b600085815260208120601f198616915b828110156200034f578886015182559484019460019091019084016200032e565b50858210156200036e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003ea6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_bridge\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_symbol\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_decimals\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"BRIDGE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"REMOTE_TOKEN\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"allowance\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"bridge\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"burn\",\"inputs\":[{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"decimals\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"decreaseAllowance\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"subtractedValue\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"increaseAllowance\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"addedValue\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l1Token\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l2Bridge\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"mint\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"remoteToken\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"_interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalSupply\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transfer\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Burn\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Mint\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", + Bin: "0x60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000a", } // OptimismMintableERC20ABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/optimismmintableerc20_more.go b/op-bindings/bindings/optimismmintableerc20_more.go index 9370be0182c4..2a2d844f6112 100644 --- a/op-bindings/bindings/optimismmintableerc20_more.go +++ b/op-bindings/bindings/optimismmintableerc20_more.go @@ -13,7 +13,8 @@ const OptimismMintableERC20StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\" var OptimismMintableERC20StorageLayout = new(solc.StorageLayout) -var OptimismMintableERC20DeployedBin = "0x608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a" +var OptimismMintableERC20DeployedBin = "0x608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(OptimismMintableERC20StorageLayoutJSON), OptimismMintableERC20StorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["OptimismMintableERC20"] = OptimismMintableERC20StorageLayout deployedBytecodes["OptimismMintableERC20"] = OptimismMintableERC20DeployedBin + immutableReferences["OptimismMintableERC20"] = true } diff --git a/op-bindings/bindings/optimismmintableerc20factory.go b/op-bindings/bindings/optimismmintableerc20factory.go index 59ea87305e34..b97fe223cd87 100644 --- a/op-bindings/bindings/optimismmintableerc20factory.go +++ b/op-bindings/bindings/optimismmintableerc20factory.go @@ -30,8 +30,8 @@ var ( // OptimismMintableERC20FactoryMetaData contains all meta data concerning the OptimismMintableERC20Factory contract. var OptimismMintableERC20FactoryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"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\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"}],\"name\":\"OptimismMintableERC20Created\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"StandardL2TokenCreated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createOptimismMintableERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"_decimals\",\"type\":\"uint8\"}],\"name\":\"createOptimismMintableERC20WithDecimals\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createStandardL2Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061001b6000610020565b610118565b600054600390610100900460ff16158015610042575060005460ff8083169116105b6100a95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805461010060ff841661ffff19909216821717610100600160b01b03191661ff0019620100006001600160a01b0387160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6123ce806101276000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e362e3100000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b611ad780620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe6101406040523480156200001257600080fd5b5060405162001ad738038062001ad7833981016040819052620000359162000177565b6001600281858560036200004a8382620002b2565b506004620000598282620002b2565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037e565b80516001600160a01b0381168114620000a557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d257600080fd5b81516001600160401b0380821115620000ef57620000ef620000aa565b604051601f8301601f19908116603f011681019082821181831017156200011a576200011a620000aa565b816040528381526020925086838588010111156200013757600080fd5b600091505b838210156200015b57858201830151818301840152908201906200013c565b838211156200016d5760008385830101525b9695505050505050565b600080600080600060a086880312156200019057600080fd5b6200019b866200008d565b9450620001ab602087016200008d565b60408701519094506001600160401b0380821115620001c957600080fd5b620001d789838a01620000c0565b94506060880151915080821115620001ee57600080fd5b50620001fd88828901620000c0565b925050608086015160ff811681146200021557600080fd5b809150509295509295909350565b600181811c908216806200023857607f821691505b6020821081036200025957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ad57600081815260208120601f850160051c81016020861015620002885750805b601f850160051c820191505b81811015620002a95782815560010162000294565b5050505b505050565b81516001600160401b03811115620002ce57620002ce620000aa565b620002e681620002df845462000223565b846200025f565b602080601f8311600181146200031e5760008415620003055750858301515b600019600386901b1c1916600185901b178555620002a9565b600085815260208120601f198616915b828110156200034f578886015182559484019460019091019084016200032e565b50858210156200036e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003ea6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"BRIDGE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"bridge\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createOptimismMintableERC20\",\"inputs\":[{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_symbol\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createOptimismMintableERC20WithDecimals\",\"inputs\":[{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_symbol\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_decimals\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createStandardL2Token\",\"inputs\":[{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_symbol\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_bridge\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OptimismMintableERC20Created\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StandardL2TokenCreated\",\"inputs\":[{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", + Bin: "0x608060405234801561001057600080fd5b5061001b6000610020565b610169565b600054610100900460ff16158080156100405750600054600160ff909116105b8061006b57506100593061015a60201b61059d1760201c565b15801561006b575060005460ff166001145b6100d25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff1916600117905580156100f5576000805461ff0019166101001790555b600180546001600160a01b0319166001600160a01b0384161790558015610156576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b6120e5806101786000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018657600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e392e3000000000000000000000000000000000000000000000000000000081525081565b604051620000d8919062000635565b60405180910390f35b620000f8620000f23660046200075d565b620001a5565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f366004620007da565b620001bc565b6200014c6200014636600462000871565b620003ba565b005b620000f86200015f3660046200075d565b6200058c565b600154620000f89073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001b48484846200058c565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028294939291906200088f565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002d290620005b9565b620002e2959493929190620008e9565b8190604051809103906000f590508015801562000303573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff1615808015620003db5750600054600160ff909116105b80620003f75750303b158015620003f7575060005460ff166001145b62000485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200025e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015620004e457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156200058857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001b48484846012620001bc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a806200094f83390190565b6000815180845260005b81811015620005ef57602081850181015186830182015201620005d1565b8181111562000602576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006200064a6020830184620005c7565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200067657600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112620006bc57600080fd5b813567ffffffffffffffff80821115620006da57620006da6200067b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156200072357620007236200067b565b816040528381528660208588010111156200073d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200077357600080fd5b6200077e8462000651565b9250602084013567ffffffffffffffff808211156200079c57600080fd5b620007aa87838801620006aa565b93506040860135915080821115620007c157600080fd5b50620007d086828701620006aa565b9150509250925092565b60008060008060808587031215620007f157600080fd5b620007fc8562000651565b9350602085013567ffffffffffffffff808211156200081a57600080fd5b6200082888838901620006aa565b945060408701359150808211156200083f57600080fd5b506200084e87828801620006aa565b925050606085013560ff811681146200086657600080fd5b939692955090935050565b6000602082840312156200088457600080fd5b6200064a8262000651565b73ffffffffffffffffffffffffffffffffffffffff85168152608060208201526000620008c06080830186620005c7565b8281036040840152620008d48186620005c7565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200092460a0830186620005c7565b8281036060840152620009388186620005c7565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a", } // OptimismMintableERC20FactoryABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/optimismmintableerc20factory_more.go b/op-bindings/bindings/optimismmintableerc20factory_more.go index 1542700419d7..f7b09838fc41 100644 --- a/op-bindings/bindings/optimismmintableerc20factory_more.go +++ b/op-bindings/bindings/optimismmintableerc20factory_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const OptimismMintableERC20FactoryStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory\",\"label\":\"bridge\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const OptimismMintableERC20FactoryStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory\",\"label\":\"spacer_0_2_30\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_bytes30\"},{\"astId\":1003,\"contract\":\"src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory\",\"label\":\"bridge\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_array(t_uint256)49_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes30\":{\"encoding\":\"inplace\",\"label\":\"bytes30\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var OptimismMintableERC20FactoryStorageLayout = new(solc.StorageLayout) -var OptimismMintableERC20FactoryDeployedBin = "0x60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e362e3100000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b611ad780620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe6101406040523480156200001257600080fd5b5060405162001ad738038062001ad7833981016040819052620000359162000177565b6001600281858560036200004a8382620002b2565b506004620000598282620002b2565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037e565b80516001600160a01b0381168114620000a557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d257600080fd5b81516001600160401b0380821115620000ef57620000ef620000aa565b604051601f8301601f19908116603f011681019082821181831017156200011a576200011a620000aa565b816040528381526020925086838588010111156200013757600080fd5b600091505b838210156200015b57858201830151818301840152908201906200013c565b838211156200016d5760008385830101525b9695505050505050565b600080600080600060a086880312156200019057600080fd5b6200019b866200008d565b9450620001ab602087016200008d565b60408701519094506001600160401b0380821115620001c957600080fd5b620001d789838a01620000c0565b94506060880151915080821115620001ee57600080fd5b50620001fd88828901620000c0565b925050608086015160ff811681146200021557600080fd5b809150509295509295909350565b600181811c908216806200023857607f821691505b6020821081036200025957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ad57600081815260208120601f850160051c81016020861015620002885750805b601f850160051c820191505b81811015620002a95782815560010162000294565b5050505b505050565b81516001600160401b03811115620002ce57620002ce620000aa565b620002e681620002df845462000223565b846200025f565b602080601f8311600181146200031e5760008415620003055750858301515b600019600386901b1c1916600185901b178555620002a9565b600085815260208120601f198616915b828110156200034f578886015182559484019460019091019084016200032e565b50858210156200036e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003ea6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a" +var OptimismMintableERC20FactoryDeployedBin = "0x60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018657600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e392e3000000000000000000000000000000000000000000000000000000081525081565b604051620000d8919062000635565b60405180910390f35b620000f8620000f23660046200075d565b620001a5565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f366004620007da565b620001bc565b6200014c6200014636600462000871565b620003ba565b005b620000f86200015f3660046200075d565b6200058c565b600154620000f89073ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001b48484846200058c565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028294939291906200088f565b604051602081830303815290604052805190602001209050600081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002d290620005b9565b620002e2959493929190620008e9565b8190604051809103906000f590508015801562000303573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054610100900460ff1615808015620003db5750600054600160ff909116105b80620003f75750303b158015620003f7575060005460ff166001145b62000485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200025e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015620004e457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905580156200058857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6000620001b48484846012620001bc565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61178a806200094f83390190565b6000815180845260005b81811015620005ef57602081850181015186830182015201620005d1565b8181111562000602576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006200064a6020830184620005c7565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200067657600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112620006bc57600080fd5b813567ffffffffffffffff80821115620006da57620006da6200067b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156200072357620007236200067b565b816040528381528660208588010111156200073d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200077357600080fd5b6200077e8462000651565b9250602084013567ffffffffffffffff808211156200079c57600080fd5b620007aa87838801620006aa565b93506040860135915080821115620007c157600080fd5b50620007d086828701620006aa565b9150509250925092565b60008060008060808587031215620007f157600080fd5b620007fc8562000651565b9350602085013567ffffffffffffffff808211156200081a57600080fd5b6200082888838901620006aa565b945060408701359150808211156200083f57600080fd5b506200084e87828801620006aa565b925050606085013560ff811681146200086657600080fd5b939692955090935050565b6000602082840312156200088457600080fd5b6200064a8262000651565b73ffffffffffffffffffffffffffffffffffffffff85168152608060208201526000620008c06080830186620005c7565b8281036040840152620008d48186620005c7565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526200092460a0830186620005c7565b8281036060840152620009388186620005c7565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(OptimismMintableERC20FactoryStorageLayoutJSON), OptimismMintableERC20FactoryStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["OptimismMintableERC20Factory"] = OptimismMintableERC20FactoryStorageLayout deployedBytecodes["OptimismMintableERC20Factory"] = OptimismMintableERC20FactoryDeployedBin + immutableReferences["OptimismMintableERC20Factory"] = false } diff --git a/op-bindings/bindings/optimismmintableerc721factory.go b/op-bindings/bindings/optimismmintableerc721factory.go index f31cd8e958a3..3870b184f6f1 100644 --- a/op-bindings/bindings/optimismmintableerc721factory.go +++ b/op-bindings/bindings/optimismmintableerc721factory.go @@ -30,7 +30,7 @@ var ( // OptimismMintableERC721FactoryMetaData contains all meta data concerning the OptimismMintableERC721Factory contract. var OptimismMintableERC721FactoryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_remoteChainId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"}],\"name\":\"OptimismMintableERC721Created\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REMOTE_CHAIN_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createOptimismMintableERC721\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOptimismMintableERC721\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_bridge\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteChainId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"BRIDGE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"REMOTE_CHAIN_ID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createOptimismMintableERC721\",\"inputs\":[{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_symbol\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isOptimismMintableERC721\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"OptimismMintableERC721Created\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"deployer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false}]", Bin: "0x60c060405234801561001057600080fd5b5060405161392638038061392683398101604081905261002f91610045565b6001600160a01b0390911660805260a05261007f565b6000806040838503121561005857600080fd5b82516001600160a01b038116811461006f57600080fd5b6020939093015192949293505050565b60805160a0516138746100b26000396000818161010601526102c401526000818161017a01526102a301526138746000f3fe60806040523480156200001157600080fd5b50600436106200006f5760003560e01c80637d1d0c5b11620000565780637d1d0c5b1462000100578063d97df6521462000137578063ee9a31a2146200017457600080fd5b806354fd4d5014620000745780635572acae14620000c9575b600080fd5b620000b16040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b604051620000c0919062000435565b60405180910390f35b620000ef620000da3660046200047b565b60006020819052908152604090205460ff1681565b6040519015158152602001620000c0565b620001287f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001620000c0565b6200014e620001483660046200057b565b6200019c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000c0565b6200014e7f000000000000000000000000000000000000000000000000000000000000000081565b600073ffffffffffffffffffffffffffffffffffffffff84166200026d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4f7074696d69736d4d696e7461626c65455243373231466163746f72793a204c908201527f3120746f6b656e20616464726573732063616e6e6f742062652061646472657360648201527f7328302900000000000000000000000000000000000000000000000000000000608482015260a40160405180910390fd5b60008484846040516020016200028693929190620005f8565b6040516020818303038152906040528051906020012090506000817f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000888888604051620002f490620003b9565b6200030495949392919062000647565b8190604051809103906000f590508015801562000325573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff8181166000818152602081815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590513381529394509189169290917fe72783bb8e0ca31286b85278da59684dd814df9762a52f0837f89edd1483b299910160405180910390a395945050505050565b6131bf80620006a983390190565b6000815180845260005b81811015620003ef57602081850181015186830182015201620003d1565b8181111562000402576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006200044a6020830184620003c7565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200047657600080fd5b919050565b6000602082840312156200048e57600080fd5b6200044a8262000451565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112620004da57600080fd5b813567ffffffffffffffff80821115620004f857620004f862000499565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171562000541576200054162000499565b816040528381528660208588010111156200055b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200059157600080fd5b6200059c8462000451565b9250602084013567ffffffffffffffff80821115620005ba57600080fd5b620005c887838801620004c8565b93506040860135915080821115620005df57600080fd5b50620005ee86828701620004c8565b9150509250925092565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000620006296060830185620003c7565b82810360408401526200063d8185620003c7565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835286602084015280861660408401525060a060608301526200068860a0830185620003c7565b82810360808401526200069c8185620003c7565b9897505050505050505056fe60e06040523480156200001157600080fd5b50604051620031bf380380620031bf83398101604081905262000034916200062d565b8181600062000044838262000756565b50600162000053828262000756565b5050506001600160a01b038516620000d85760405162461bcd60e51b815260206004820152603360248201527f4f7074696d69736d4d696e7461626c654552433732313a20627269646765206360448201527f616e6e6f7420626520616464726573732830290000000000000000000000000060648201526084015b60405180910390fd5b83600003620001505760405162461bcd60e51b815260206004820152603660248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465206360448201527f6861696e2069642063616e6e6f74206265207a65726f000000000000000000006064820152608401620000cf565b6001600160a01b038316620001ce5760405162461bcd60e51b815260206004820152603960248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465207460448201527f6f6b656e2063616e6e6f742062652061646472657373283029000000000000006064820152608401620000cf565b60808490526001600160a01b0383811660a081905290861660c0526200020290601462000256602090811b62000eed17901c565b62000218856200041660201b620011301760201c565b6040516020016200022b92919062000822565b604051602081830303815290604052600a90816200024a919062000756565b50505050505062000993565b6060600062000267836002620008ac565b62000274906002620008ce565b6001600160401b038111156200028e576200028e62000553565b6040519080825280601f01601f191660200182016040528015620002b9576020820181803683370190505b509050600360fc1b81600081518110620002d757620002d7620008e9565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110620003095762000309620008e9565b60200101906001600160f81b031916908160001a90535060006200032f846002620008ac565b6200033c906001620008ce565b90505b6001811115620003be576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110620003745762000374620008e9565b1a60f81b8282815181106200038d576200038d620008e9565b60200101906001600160f81b031916908160001a90535060049490941c93620003b681620008ff565b90506200033f565b5083156200040f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620000cf565b9392505050565b6060816000036200043e5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156200046e5780620004558162000919565b9150620004669050600a836200094b565b915062000442565b6000816001600160401b038111156200048b576200048b62000553565b6040519080825280601f01601f191660200182016040528015620004b6576020820181803683370190505b5090505b84156200052e57620004ce60018362000962565b9150620004dd600a866200097c565b620004ea906030620008ce565b60f81b818381518110620005025762000502620008e9565b60200101906001600160f81b031916908160001a90535062000526600a866200094b565b9450620004ba565b949350505050565b80516001600160a01b03811681146200054e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620005865781810151838201526020016200056c565b8381111562000596576000848401525b50505050565b600082601f830112620005ae57600080fd5b81516001600160401b0380821115620005cb57620005cb62000553565b604051601f8301601f19908116603f01168101908282118183101715620005f657620005f662000553565b816040528381528660208588010111156200061057600080fd5b6200062384602083016020890162000569565b9695505050505050565b600080600080600060a086880312156200064657600080fd5b620006518662000536565b945060208601519350620006686040870162000536565b60608701519093506001600160401b03808211156200068657600080fd5b6200069489838a016200059c565b93506080880151915080821115620006ab57600080fd5b50620006ba888289016200059c565b9150509295509295909350565b600181811c90821680620006dc57607f821691505b602082108103620006fd57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200075157600081815260208120601f850160051c810160208610156200072c5750805b601f850160051c820191505b818110156200074d5782815560010162000738565b5050505b505050565b81516001600160401b0381111562000772576200077262000553565b6200078a81620007838454620006c7565b8462000703565b602080601f831160018114620007c25760008415620007a95750858301515b600019600386901b1c1916600185901b1785556200074d565b600085815260208120601f198616915b82811015620007f357888601518255948401946001909101908401620007d2565b5085821015620008125787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6832ba3432b932bab69d60b91b8152600083516200084881600985016020880162000569565b600160fe1b60099184019182015283516200086b81600a84016020880162000569565b712f746f6b656e5552493f75696e743235363d60701b600a9290910191820152601c01949350505050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620008c957620008c962000896565b500290565b60008219821115620008e457620008e462000896565b500190565b634e487b7160e01b600052603260045260246000fd5b60008162000911576200091162000896565b506000190190565b6000600182016200092e576200092e62000896565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826200095d576200095d62000935565b500490565b60008282101562000977576200097762000896565b500390565b6000826200098e576200098e62000935565b500690565b60805160a05160c0516127d9620009e6600039600081816103e20152818161047a01528181610b210152610c430152600081816101e001526103bc015260008181610329015261040801526127d96000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80637d1d0c5b116100ee578063c87b56dd11610097578063e78cea9211610071578063e78cea92146103e0578063e951819614610406578063e985e9c51461042c578063ee9a31a21461047557600080fd5b8063c87b56dd1461039f578063d547cfb7146103b2578063d6c0b2c4146103ba57600080fd5b8063a1448194116100c8578063a144819414610366578063a22cb46514610379578063b88d4fde1461038c57600080fd5b80637d1d0c5b1461032457806395d89b411461034b5780639dc29fac1461035357600080fd5b806323b872dd1161015b5780634f6ccce7116101355780634f6ccce7146102af57806354fd4d50146102c25780636352211e146102fe57806370a082311461031157600080fd5b806323b872dd146102765780632f745c591461028957806342842e0e1461029c57600080fd5b8063081812fc1161018c578063081812fc1461023c578063095ea7b31461024f57806318160ddd1461026457600080fd5b806301ffc9a7146101b3578063033964be146101db57806306fdde0314610227575b600080fd5b6101c66101c1366004612226565b61049c565b60405190151581526020015b60405180910390f35b6102027f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b61022f6104fa565b6040516101d291906122b9565b61020261024a3660046122cc565b61058c565b61026261025d36600461230e565b6105c0565b005b6008545b6040519081526020016101d2565b610262610284366004612338565b610751565b61026861029736600461230e565b6107f2565b6102626102aa366004612338565b6108c1565b6102686102bd3660046122cc565b6108dc565b61022f6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61020261030c3660046122cc565b61099a565b61026861031f366004612374565b610a2c565b6102687f000000000000000000000000000000000000000000000000000000000000000081565b61022f610afa565b61026261036136600461230e565b610b09565b61026261037436600461230e565b610c2b565b61026261038736600461238f565b610d42565b61026261039a3660046123fa565b610d51565b61022f6103ad3660046122cc565b610df9565b61022f610e5f565b7f0000000000000000000000000000000000000000000000000000000000000000610202565b7f0000000000000000000000000000000000000000000000000000000000000000610202565b7f0000000000000000000000000000000000000000000000000000000000000000610268565b6101c661043a3660046124f4565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b6102027f000000000000000000000000000000000000000000000000000000000000000081565b60007f74259ebf000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083168114806104f357506104f38361126d565b9392505050565b60606000805461050990612527565b80601f016020809104026020016040519081016040528092919081815260200182805461053590612527565b80156105825780601f1061055757610100808354040283529160200191610582565b820191906000526020600020905b81548152906001019060200180831161056557829003601f168201915b5050505050905090565b6000610597826112c3565b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60006105cb8261099a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361068d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614806106b657506106b6813361043a565b610742576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610684565b61074c8383611351565b505050565b61075b33826113f1565b6107e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610684565b61074c8383836114b0565b60006107fd83610a2c565b821061088b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610684565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b61074c83838360405180602001604052806000815250610d51565b60006108e760085490565b8210610975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610684565b600882815481106109885761098861257a565b90600052602060002001549050919050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610a26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610684565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff8216610ad1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152608401610684565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60606001805461050990612527565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610bce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e0000000000006064820152608401610684565b610bd781611722565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca582604051610c1f91815260200190565b60405180910390a25050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610cf0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e0000000000006064820152608401610684565b610cfa82826117fb565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610c1f91815260200190565b610d4d338383611815565b5050565b610d5b33836113f1565b610de7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610684565b610df384848484611942565b50505050565b6060610e04826112c3565b6000610e0e6119e5565b90506000815111610e2e57604051806020016040528060008152506104f3565b80610e3884611130565b604051602001610e499291906125a9565b6040516020818303038152906040529392505050565b600a8054610e6c90612527565b80601f0160208091040260200160405190810160405280929190818152602001828054610e9890612527565b8015610ee55780601f10610eba57610100808354040283529160200191610ee5565b820191906000526020600020905b815481529060010190602001808311610ec857829003601f168201915b505050505081565b60606000610efc836002612607565b610f07906002612644565b67ffffffffffffffff811115610f1f57610f1f6123cb565b6040519080825280601f01601f191660200182016040528015610f49576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110610f8057610f8061257a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110610fe357610fe361257a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061101f846002612607565b61102a906001612644565b90505b60018111156110c7577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061106b5761106b61257a565b1a60f81b8282815181106110815761108161257a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936110c08161265c565b905061102d565b5083156104f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610684565b60608160000361117357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561119d578061118781612691565b91506111969050600a836126f8565b9150611177565b60008167ffffffffffffffff8111156111b8576111b86123cb565b6040519080825280601f01601f1916602001820160405280156111e2576020820181803683370190505b5090505b8415611265576111f760018361270c565b9150611204600a86612723565b61120f906030612644565b60f81b8183815181106112245761122461257a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061125e600a866126f8565b94506111e6565b949350505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610a265750610a26826119f4565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1661134e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610684565b50565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841690811790915581906113ab8261099a565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806113fd8361099a565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061146b575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b8061126557508373ffffffffffffffffffffffffffffffffffffffff166114918461058c565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b8273ffffffffffffffffffffffffffffffffffffffff166114d08261099a565b73ffffffffffffffffffffffffffffffffffffffff1614611573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610684565b73ffffffffffffffffffffffffffffffffffffffff8216611615576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610684565b611620838383611ad7565b61162b600082611351565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546001929061166190849061270c565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040812080546001929061169c908490612644565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061172d8261099a565b905061173b81600084611ad7565b611746600083611351565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080546001929061177c90849061270c565b909155505060008281526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b610d4d828260405180602001604052806000815250611bdd565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610684565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61194d8484846114b0565b61195984848484611c80565b610df3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610684565b6060600a805461050990612527565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480611a8757507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610a2657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610a26565b73ffffffffffffffffffffffffffffffffffffffff8316611b3f57611b3a81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611b7c565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611b7c57611b7c8382611e73565b73ffffffffffffffffffffffffffffffffffffffff8216611ba05761074c81611f2a565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461074c5761074c8282611fd9565b611be7838361202a565b611bf46000848484611c80565b61074c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610684565b600073ffffffffffffffffffffffffffffffffffffffff84163b15611e68576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290611cf7903390899088908890600401612737565b6020604051808303816000875af1925050508015611d50575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611d4d91810190612780565b60015b611e1d573d808015611d7e576040519150601f19603f3d011682016040523d82523d6000602084013e611d83565b606091505b508051600003611e15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610684565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050611265565b506001949350505050565b60006001611e8084610a2c565b611e8a919061270c565b600083815260076020526040902054909150808214611eea5773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b600854600090611f3c9060019061270c565b60008381526009602052604081205460088054939450909284908110611f6457611f6461257a565b906000526020600020015490508060088381548110611f8557611f8561257a565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480611fbd57611fbd61279d565b6001900381819060005260206000200160009055905550505050565b6000611fe483610a2c565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b73ffffffffffffffffffffffffffffffffffffffff82166120a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610684565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615612133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610684565b61213f60008383611ad7565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290612175908490612644565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461134e57600080fd5b60006020828403121561223857600080fd5b81356104f3816121f8565b60005b8381101561225e578181015183820152602001612246565b83811115610df35750506000910152565b60008151808452612287816020860160208601612243565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f3602083018461226f565b6000602082840312156122de57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461230957600080fd5b919050565b6000806040838503121561232157600080fd5b61232a836122e5565b946020939093013593505050565b60008060006060848603121561234d57600080fd5b612356846122e5565b9250612364602085016122e5565b9150604084013590509250925092565b60006020828403121561238657600080fd5b6104f3826122e5565b600080604083850312156123a257600080fd5b6123ab836122e5565b9150602083013580151581146123c057600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561241057600080fd5b612419856122e5565b9350612427602086016122e5565b925060408501359150606085013567ffffffffffffffff8082111561244b57600080fd5b818701915087601f83011261245f57600080fd5b813581811115612471576124716123cb565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156124b7576124b76123cb565b816040528281528a60208487010111156124d057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561250757600080fd5b612510836122e5565b915061251e602084016122e5565b90509250929050565b600181811c9082168061253b57607f821691505b602082108103612574577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600083516125bb818460208801612243565b8351908301906125cf818360208801612243565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561263f5761263f6125d8565b500290565b60008219821115612657576126576125d8565b500190565b60008161266b5761266b6125d8565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036126c2576126c26125d8565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612707576127076126c9565b500490565b60008282101561271e5761271e6125d8565b500390565b600082612732576127326126c9565b500690565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612776608083018461226f565b9695505050505050565b60006020828403121561279257600080fd5b81516104f3816121f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", } diff --git a/op-bindings/bindings/optimismmintableerc721factory_more.go b/op-bindings/bindings/optimismmintableerc721factory_more.go index 86cd6eb8648c..92db3f22ab30 100644 --- a/op-bindings/bindings/optimismmintableerc721factory_more.go +++ b/op-bindings/bindings/optimismmintableerc721factory_more.go @@ -15,6 +15,7 @@ var OptimismMintableERC721FactoryStorageLayout = new(solc.StorageLayout) var OptimismMintableERC721FactoryDeployedBin = "0x60806040523480156200001157600080fd5b50600436106200006f5760003560e01c80637d1d0c5b11620000565780637d1d0c5b1462000100578063d97df6521462000137578063ee9a31a2146200017457600080fd5b806354fd4d5014620000745780635572acae14620000c9575b600080fd5b620000b16040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b604051620000c0919062000435565b60405180910390f35b620000ef620000da3660046200047b565b60006020819052908152604090205460ff1681565b6040519015158152602001620000c0565b620001287f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001620000c0565b6200014e620001483660046200057b565b6200019c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000c0565b6200014e7f000000000000000000000000000000000000000000000000000000000000000081565b600073ffffffffffffffffffffffffffffffffffffffff84166200026d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4f7074696d69736d4d696e7461626c65455243373231466163746f72793a204c908201527f3120746f6b656e20616464726573732063616e6e6f742062652061646472657360648201527f7328302900000000000000000000000000000000000000000000000000000000608482015260a40160405180910390fd5b60008484846040516020016200028693929190620005f8565b6040516020818303038152906040528051906020012090506000817f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000888888604051620002f490620003b9565b6200030495949392919062000647565b8190604051809103906000f590508015801562000325573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff8181166000818152602081815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590513381529394509189169290917fe72783bb8e0ca31286b85278da59684dd814df9762a52f0837f89edd1483b299910160405180910390a395945050505050565b6131bf80620006a983390190565b6000815180845260005b81811015620003ef57602081850181015186830182015201620003d1565b8181111562000402576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006200044a6020830184620003c7565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200047657600080fd5b919050565b6000602082840312156200048e57600080fd5b6200044a8262000451565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112620004da57600080fd5b813567ffffffffffffffff80821115620004f857620004f862000499565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171562000541576200054162000499565b816040528381528660208588010111156200055b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200059157600080fd5b6200059c8462000451565b9250602084013567ffffffffffffffff80821115620005ba57600080fd5b620005c887838801620004c8565b93506040860135915080821115620005df57600080fd5b50620005ee86828701620004c8565b9150509250925092565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000620006296060830185620003c7565b82810360408401526200063d8185620003c7565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835286602084015280861660408401525060a060608301526200068860a0830185620003c7565b82810360808401526200069c8185620003c7565b9897505050505050505056fe60e06040523480156200001157600080fd5b50604051620031bf380380620031bf83398101604081905262000034916200062d565b8181600062000044838262000756565b50600162000053828262000756565b5050506001600160a01b038516620000d85760405162461bcd60e51b815260206004820152603360248201527f4f7074696d69736d4d696e7461626c654552433732313a20627269646765206360448201527f616e6e6f7420626520616464726573732830290000000000000000000000000060648201526084015b60405180910390fd5b83600003620001505760405162461bcd60e51b815260206004820152603660248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465206360448201527f6861696e2069642063616e6e6f74206265207a65726f000000000000000000006064820152608401620000cf565b6001600160a01b038316620001ce5760405162461bcd60e51b815260206004820152603960248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465207460448201527f6f6b656e2063616e6e6f742062652061646472657373283029000000000000006064820152608401620000cf565b60808490526001600160a01b0383811660a081905290861660c0526200020290601462000256602090811b62000eed17901c565b62000218856200041660201b620011301760201c565b6040516020016200022b92919062000822565b604051602081830303815290604052600a90816200024a919062000756565b50505050505062000993565b6060600062000267836002620008ac565b62000274906002620008ce565b6001600160401b038111156200028e576200028e62000553565b6040519080825280601f01601f191660200182016040528015620002b9576020820181803683370190505b509050600360fc1b81600081518110620002d757620002d7620008e9565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110620003095762000309620008e9565b60200101906001600160f81b031916908160001a90535060006200032f846002620008ac565b6200033c906001620008ce565b90505b6001811115620003be576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110620003745762000374620008e9565b1a60f81b8282815181106200038d576200038d620008e9565b60200101906001600160f81b031916908160001a90535060049490941c93620003b681620008ff565b90506200033f565b5083156200040f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620000cf565b9392505050565b6060816000036200043e5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156200046e5780620004558162000919565b9150620004669050600a836200094b565b915062000442565b6000816001600160401b038111156200048b576200048b62000553565b6040519080825280601f01601f191660200182016040528015620004b6576020820181803683370190505b5090505b84156200052e57620004ce60018362000962565b9150620004dd600a866200097c565b620004ea906030620008ce565b60f81b818381518110620005025762000502620008e9565b60200101906001600160f81b031916908160001a90535062000526600a866200094b565b9450620004ba565b949350505050565b80516001600160a01b03811681146200054e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620005865781810151838201526020016200056c565b8381111562000596576000848401525b50505050565b600082601f830112620005ae57600080fd5b81516001600160401b0380821115620005cb57620005cb62000553565b604051601f8301601f19908116603f01168101908282118183101715620005f657620005f662000553565b816040528381528660208588010111156200061057600080fd5b6200062384602083016020890162000569565b9695505050505050565b600080600080600060a086880312156200064657600080fd5b620006518662000536565b945060208601519350620006686040870162000536565b60608701519093506001600160401b03808211156200068657600080fd5b6200069489838a016200059c565b93506080880151915080821115620006ab57600080fd5b50620006ba888289016200059c565b9150509295509295909350565b600181811c90821680620006dc57607f821691505b602082108103620006fd57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200075157600081815260208120601f850160051c810160208610156200072c5750805b601f850160051c820191505b818110156200074d5782815560010162000738565b5050505b505050565b81516001600160401b0381111562000772576200077262000553565b6200078a81620007838454620006c7565b8462000703565b602080601f831160018114620007c25760008415620007a95750858301515b600019600386901b1c1916600185901b1785556200074d565b600085815260208120601f198616915b82811015620007f357888601518255948401946001909101908401620007d2565b5085821015620008125787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6832ba3432b932bab69d60b91b8152600083516200084881600985016020880162000569565b600160fe1b60099184019182015283516200086b81600a84016020880162000569565b712f746f6b656e5552493f75696e743235363d60701b600a9290910191820152601c01949350505050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620008c957620008c962000896565b500290565b60008219821115620008e457620008e462000896565b500190565b634e487b7160e01b600052603260045260246000fd5b60008162000911576200091162000896565b506000190190565b6000600182016200092e576200092e62000896565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826200095d576200095d62000935565b500490565b60008282101562000977576200097762000896565b500390565b6000826200098e576200098e62000935565b500690565b60805160a05160c0516127d9620009e6600039600081816103e20152818161047a01528181610b210152610c430152600081816101e001526103bc015260008181610329015261040801526127d96000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80637d1d0c5b116100ee578063c87b56dd11610097578063e78cea9211610071578063e78cea92146103e0578063e951819614610406578063e985e9c51461042c578063ee9a31a21461047557600080fd5b8063c87b56dd1461039f578063d547cfb7146103b2578063d6c0b2c4146103ba57600080fd5b8063a1448194116100c8578063a144819414610366578063a22cb46514610379578063b88d4fde1461038c57600080fd5b80637d1d0c5b1461032457806395d89b411461034b5780639dc29fac1461035357600080fd5b806323b872dd1161015b5780634f6ccce7116101355780634f6ccce7146102af57806354fd4d50146102c25780636352211e146102fe57806370a082311461031157600080fd5b806323b872dd146102765780632f745c591461028957806342842e0e1461029c57600080fd5b8063081812fc1161018c578063081812fc1461023c578063095ea7b31461024f57806318160ddd1461026457600080fd5b806301ffc9a7146101b3578063033964be146101db57806306fdde0314610227575b600080fd5b6101c66101c1366004612226565b61049c565b60405190151581526020015b60405180910390f35b6102027f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b61022f6104fa565b6040516101d291906122b9565b61020261024a3660046122cc565b61058c565b61026261025d36600461230e565b6105c0565b005b6008545b6040519081526020016101d2565b610262610284366004612338565b610751565b61026861029736600461230e565b6107f2565b6102626102aa366004612338565b6108c1565b6102686102bd3660046122cc565b6108dc565b61022f6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61020261030c3660046122cc565b61099a565b61026861031f366004612374565b610a2c565b6102687f000000000000000000000000000000000000000000000000000000000000000081565b61022f610afa565b61026261036136600461230e565b610b09565b61026261037436600461230e565b610c2b565b61026261038736600461238f565b610d42565b61026261039a3660046123fa565b610d51565b61022f6103ad3660046122cc565b610df9565b61022f610e5f565b7f0000000000000000000000000000000000000000000000000000000000000000610202565b7f0000000000000000000000000000000000000000000000000000000000000000610202565b7f0000000000000000000000000000000000000000000000000000000000000000610268565b6101c661043a3660046124f4565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b6102027f000000000000000000000000000000000000000000000000000000000000000081565b60007f74259ebf000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083168114806104f357506104f38361126d565b9392505050565b60606000805461050990612527565b80601f016020809104026020016040519081016040528092919081815260200182805461053590612527565b80156105825780601f1061055757610100808354040283529160200191610582565b820191906000526020600020905b81548152906001019060200180831161056557829003601f168201915b5050505050905090565b6000610597826112c3565b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60006105cb8261099a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361068d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614806106b657506106b6813361043a565b610742576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610684565b61074c8383611351565b505050565b61075b33826113f1565b6107e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610684565b61074c8383836114b0565b60006107fd83610a2c565b821061088b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610684565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b61074c83838360405180602001604052806000815250610d51565b60006108e760085490565b8210610975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610684565b600882815481106109885761098861257a565b90600052602060002001549050919050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610a26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610684565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff8216610ad1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152608401610684565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60606001805461050990612527565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610bce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e0000000000006064820152608401610684565b610bd781611722565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca582604051610c1f91815260200190565b60405180910390a25050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610cf0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e0000000000006064820152608401610684565b610cfa82826117fb565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610c1f91815260200190565b610d4d338383611815565b5050565b610d5b33836113f1565b610de7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610684565b610df384848484611942565b50505050565b6060610e04826112c3565b6000610e0e6119e5565b90506000815111610e2e57604051806020016040528060008152506104f3565b80610e3884611130565b604051602001610e499291906125a9565b6040516020818303038152906040529392505050565b600a8054610e6c90612527565b80601f0160208091040260200160405190810160405280929190818152602001828054610e9890612527565b8015610ee55780601f10610eba57610100808354040283529160200191610ee5565b820191906000526020600020905b815481529060010190602001808311610ec857829003601f168201915b505050505081565b60606000610efc836002612607565b610f07906002612644565b67ffffffffffffffff811115610f1f57610f1f6123cb565b6040519080825280601f01601f191660200182016040528015610f49576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110610f8057610f8061257a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110610fe357610fe361257a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061101f846002612607565b61102a906001612644565b90505b60018111156110c7577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061106b5761106b61257a565b1a60f81b8282815181106110815761108161257a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936110c08161265c565b905061102d565b5083156104f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610684565b60608160000361117357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561119d578061118781612691565b91506111969050600a836126f8565b9150611177565b60008167ffffffffffffffff8111156111b8576111b86123cb565b6040519080825280601f01601f1916602001820160405280156111e2576020820181803683370190505b5090505b8415611265576111f760018361270c565b9150611204600a86612723565b61120f906030612644565b60f81b8183815181106112245761122461257a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061125e600a866126f8565b94506111e6565b949350505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610a265750610a26826119f4565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1661134e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610684565b50565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841690811790915581906113ab8261099a565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806113fd8361099a565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061146b575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b8061126557508373ffffffffffffffffffffffffffffffffffffffff166114918461058c565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b8273ffffffffffffffffffffffffffffffffffffffff166114d08261099a565b73ffffffffffffffffffffffffffffffffffffffff1614611573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610684565b73ffffffffffffffffffffffffffffffffffffffff8216611615576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610684565b611620838383611ad7565b61162b600082611351565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080546001929061166190849061270c565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040812080546001929061169c908490612644565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061172d8261099a565b905061173b81600084611ad7565b611746600083611351565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080546001929061177c90849061270c565b909155505060008281526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b610d4d828260405180602001604052806000815250611bdd565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610684565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61194d8484846114b0565b61195984848484611c80565b610df3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610684565b6060600a805461050990612527565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480611a8757507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610a2657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610a26565b73ffffffffffffffffffffffffffffffffffffffff8316611b3f57611b3a81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611b7c565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611b7c57611b7c8382611e73565b73ffffffffffffffffffffffffffffffffffffffff8216611ba05761074c81611f2a565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461074c5761074c8282611fd9565b611be7838361202a565b611bf46000848484611c80565b61074c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610684565b600073ffffffffffffffffffffffffffffffffffffffff84163b15611e68576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290611cf7903390899088908890600401612737565b6020604051808303816000875af1925050508015611d50575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611d4d91810190612780565b60015b611e1d573d808015611d7e576040519150601f19603f3d011682016040523d82523d6000602084013e611d83565b606091505b508051600003611e15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610684565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050611265565b506001949350505050565b60006001611e8084610a2c565b611e8a919061270c565b600083815260076020526040902054909150808214611eea5773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b600854600090611f3c9060019061270c565b60008381526009602052604081205460088054939450909284908110611f6457611f6461257a565b906000526020600020015490508060088381548110611f8557611f8561257a565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480611fbd57611fbd61279d565b6001900381819060005260206000200160009055905550505050565b6000611fe483610a2c565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b73ffffffffffffffffffffffffffffffffffffffff82166120a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610684565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615612133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610684565b61213f60008383611ad7565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290612175908490612644565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461134e57600080fd5b60006020828403121561223857600080fd5b81356104f3816121f8565b60005b8381101561225e578181015183820152602001612246565b83811115610df35750506000910152565b60008151808452612287816020860160208601612243565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f3602083018461226f565b6000602082840312156122de57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461230957600080fd5b919050565b6000806040838503121561232157600080fd5b61232a836122e5565b946020939093013593505050565b60008060006060848603121561234d57600080fd5b612356846122e5565b9250612364602085016122e5565b9150604084013590509250925092565b60006020828403121561238657600080fd5b6104f3826122e5565b600080604083850312156123a257600080fd5b6123ab836122e5565b9150602083013580151581146123c057600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561241057600080fd5b612419856122e5565b9350612427602086016122e5565b925060408501359150606085013567ffffffffffffffff8082111561244b57600080fd5b818701915087601f83011261245f57600080fd5b813581811115612471576124716123cb565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156124b7576124b76123cb565b816040528281528a60208487010111156124d057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561250757600080fd5b612510836122e5565b915061251e602084016122e5565b90509250929050565b600181811c9082168061253b57607f821691505b602082108103612574577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600083516125bb818460208801612243565b8351908301906125cf818360208801612243565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561263f5761263f6125d8565b500290565b60008219821115612657576126576125d8565b500190565b60008161266b5761266b6125d8565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036126c2576126c26125d8565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612707576127076126c9565b500490565b60008282101561271e5761271e6125d8565b500390565b600082612732576127326126c9565b500690565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612776608083018461226f565b9695505050505050565b60006020828403121561279257600080fd5b81516104f3816121f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(OptimismMintableERC721FactoryStorageLayoutJSON), OptimismMintableERC721FactoryStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["OptimismMintableERC721Factory"] = OptimismMintableERC721FactoryStorageLayout deployedBytecodes["OptimismMintableERC721Factory"] = OptimismMintableERC721FactoryDeployedBin + immutableReferences["OptimismMintableERC721Factory"] = true } diff --git a/op-bindings/bindings/optimismportal.go b/op-bindings/bindings/optimismportal.go index 969336118897..2bf20f0e408c 100644 --- a/op-bindings/bindings/optimismportal.go +++ b/op-bindings/bindings/optimismportal.go @@ -48,8 +48,8 @@ type TypesWithdrawalTransaction struct { // OptimismPortalMetaData contains all meta data concerning the OptimismPortal contract. var OptimismPortalMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"opaqueData\",\"type\":\"bytes\"}],\"name\":\"TransactionDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"WithdrawalProven\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GUARDIAN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SYSTEM_CONFIG\",\"outputs\":[{\"internalType\":\"contractSystemConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"_isCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"donateETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_guardian\",\"type\":\"address\"},{\"internalType\":\"contractSystemConfig\",\"name\":\"_systemConfig\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"isOutputFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Oracle\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_byteCount\",\"type\":\"uint64\"}],\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structTypes.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\"}],\"name\":\"proveWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"provenWithdrawals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2OutputIndex\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemConfig\",\"outputs\":[{\"internalType\":\"contractSystemConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x60806040523480156200001157600080fd5b506200002260008080600162000028565b62000224565b600054600390610100900460ff161580156200004b575060005460ff8083169116105b620000b45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100908117909155603280546001600160a01b031990811661dead1790915560358054603680546001600160a01b0389811691861691909117909155603780548a831695169490941790935585151592891690930260ff19166001600160a81b0319909316929092171790556200013962000181565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600054610100900460ff16620001ee5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b61544280620002346000396000f3fe60806040526004361061016d5760003560e01c80638b4c40b0116100cb578063a35d99df1161007f578063e9e05c4211610059578063e9e05c4214610573578063f049875014610586578063fecf9734146105b157600080fd5b8063a35d99df1461040d578063cff0ab9614610446578063e965084c146104e757600080fd5b80639b5f694a116100b05780639b5f694a1461037e5780639bf62d82146103b0578063a14238e7146103dd57600080fd5b80638b4c40b0146101925780638c3152e91461035e57600080fd5b806354fd4d50116101225780636dbffb78116101075780636dbffb78146102fe578063724c184c1461031e5780638456cb591461034957600080fd5b806354fd4d501461027e5780635c975abb146102d457600080fd5b80633f4ba83a116101535780633f4ba83a1461021c578063452a9320146102315780634870496f1461025e57600080fd5b80621c2ff61461019957806333d7e2bd146101ef57600080fd5b36610194576101923334620186a06000604051806020016040528060008152506105d1565b005b600080fd5b3480156101a557600080fd5b50603554610100900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101fb57600080fd5b506036546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022857600080fd5b5061019261086c565b34801561023d57600080fd5b506037546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026a57600080fd5b50610192610279366004614a30565b610971565b34801561028a57600080fd5b506102c76040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b6040516101e69190614b86565b3480156102e057600080fd5b506035546102ee9060ff1681565b60405190151581526020016101e6565b34801561030a57600080fd5b506102ee610319366004614b99565b610fa6565b34801561032a57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101c5565b34801561035557600080fd5b50610192611065565b34801561036a57600080fd5b50610192610379366004614bb2565b611167565b34801561038a57600080fd5b506035546101c590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103bc57600080fd5b506032546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e957600080fd5b506102ee6103f8366004614b99565b60336020526000908152604090205460ff1681565b34801561041957600080fd5b5061042d610428366004614c0c565b611a2b565b60405167ffffffffffffffff90911681526020016101e6565b34801561045257600080fd5b506001546104ae906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101e6565b3480156104f357600080fd5b50610545610502366004614b99565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101e6565b610192610581366004614c37565b6105d1565b34801561059257600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff166101c5565b3480156105bd57600080fd5b506101926105cc366004614cb2565b611a44565b8260005a905083156106885773ffffffffffffffffffffffffffffffffffffffff87161561068857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6106928351611a2b565b67ffffffffffffffff168567ffffffffffffffff161015610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161067f565b6201d4c0835111156107a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161067f565b333281146107c4575033731111000000000000000000000000000000001111015b600034888888886040516020016107df959493929190614d0c565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161084f9190614b86565b60405180910390a450506108638282611c52565b50505050505050565b60375473ffffffffffffffffffffffffffffffffffffffff163314610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e70617573650000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff16156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161067f565b6035546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101869052600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190614d91565b519050610b50610b4b36869003860186614df6565b611f75565b8114610bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161067f565b6000610be987611fd1565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d035750805160355460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190614d91565b5114155b610d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161067f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610e589101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610e4e888a614e5c565b8a60400135612001565b610ee4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161067f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6035546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161105f9161010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190614d91565b602001516fffffffffffffffffffffffffffffffff16612025565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff16331461110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20706175736500000000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610967565b60355460ff16156111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161067f565b600061128882611fd1565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161067f565b603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190614ee0565b81602001516fffffffffffffffffffffffffffffffff1610156114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161067f565b6114ee81602001516fffffffffffffffffffffffffffffffff16612025565b6115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60355460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff9091166004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561162c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116509190614d91565b825181519192501461170a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161067f565b61172981602001516fffffffffffffffffffffffffffffffff16612025565b6117db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60008381526033602052604090205460ff161561187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161067f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161191c939291906120ca565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061198190841515815260200190565b60405180910390a2801580156119975750326001145b15611a24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161067f565b5050505050565b6000611a38826010614f28565b61105f90615208614f58565b600054600390610100900460ff16158015611a66575060005460ff8083169116105b611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100908117909155603280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811661dead17909155603580546036805473ffffffffffffffffffffffffffffffffffffffff89811691861691909117909155603780548a83169516949094179093558515159289169093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fffffffffffffffffffffff00000000000000000000000000000000000000000090931692909217179055611bed612128565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600154600090611c88907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f84565b90506000611c9461220b565b90506000816020015160ff16826000015163ffffffff16611cb59190614fca565b90508215611dec57600154600090611cec908390700100000000000000000000000000000000900467ffffffffffffffff16615032565b90506000836040015160ff1683611d0391906150a6565b600154611d239084906fffffffffffffffffffffffffffffffff166150a6565b611d2d9190614fca565b600154909150600090611d7e90611d579084906fffffffffffffffffffffffffffffffff16615162565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166122d1565b90506001861115611dad57611daa611d5782876040015160ff1660018a611da59190614f84565b6122f0565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e1f908490700100000000000000000000000000000000900467ffffffffffffffff16614f58565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161067f565b600154600090611f2e906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166151d6565b90506000611f4063b2d05e0083615213565b905060005a611f4f9088614f84565b905080821115611f6b57611f6b611f668284614f84565b612345565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611fb4949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611fb4979096959101615227565b60008061200d86612373565b905061201b818686866123a5565b9695505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa158015612094573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b89190614ee0565b6120c2908361527e565b421192915050565b60008060006120da8660006123d5565b905080612110576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166121bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067f565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260365483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156122a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122cc91906152bb565b905090565b60006122e66122e085856123f3565b8361240a565b90505b9392505050565b6000670de0b6b3a76400006123316123088583614fca565b61231a90670de0b6b3a7640000615032565b61232c85670de0b6b3a76400006150a6565b612419565b61233b90866150a6565b6122e69190614fca565b6000805a90505b825a6123589083614f84565b101561236e576123678261535a565b915061234c565b505050565b6060818051906020012060405160200161238f91815260200190565b6040516020818303038152906040529050919050565b60006123cc846123b687868661244a565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561240357816122e9565b5090919050565b600081831261240357816122e9565b60006122e9670de0b6b3a76400008361243186612ec8565b61243b91906150a6565b6124459190614fca565b61310c565b606060008451116124b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161067f565b60006124c28461334b565b905060006124cf86613437565b90506000846040516020016124e691815260200190565b60405160208183030381529060405290506000805b8451811015612e3f57600085828151811061251857612518615392565b6020026020010151905084518311156125b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161067f565b8260000361266c5780518051602091820120604051612601926125db92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612667576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067f565b6127c3565b8051516020116127225780518051602091820120604051612696926125db92910190815260200190565b612667576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161067f565b8051845160208087019190912082519190920120146127c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161067f565b6127cf6010600161527e565b816020015151036129ab57845183036129435761280981602001516010815181106127fc576127fc615392565b602002602001015161349a565b9650600087511161289c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067f565b600186516128aa9190614f84565b8214612938576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067f565b5050505050506122e9565b600085848151811061295757612957615392565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061298257612982615392565b60200260200101519050612995816135fa565b95506129a260018661527e565b94505050612e2c565b600281602001515103612da45760006129c38261361f565b90506000816000815181106129da576129da615392565b016020015160f81c905060006129f16002836153c1565b6129fc9060026153e3565b90506000612a0d848360ff16613643565b90506000612a1b8a89613643565b90506000612a298383613679565b905080835114612abb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067f565b60ff851660021480612ad0575060ff85166003145b15612cbf5780825114612b65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067f565b612b7f87602001516001815181106127fc576127fc615392565b9c5060008d5111612c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067f565b60018c51612c209190614f84565b8814612cae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067f565b5050505050505050505050506122e9565b60ff85161580612cd2575060ff85166001145b15612d1157612cfe8760200151600181518110612cf157612cf1615392565b60200260200101516135fa565b9950612d0a818a61527e565b9850612d99565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161067f565b505050505050612e2c565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161067f565b5080612e378161535a565b9150506124fb565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161067f565b6000808213612f33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b60006060612f408461372d565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361313d57506000919050565b680755bf798b4a1bf1e582126131af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161067f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff81111561336957613369614850565b6040519080825280602002602001820160405280156133ae57816020015b60408051808201909152606080825260208201528152602001906001900390816133875790505b50915060005b818110156134305760405180604001604052808583815181106133d9576133d9615392565b602002602001015181526020016134088684815181106133fb576133fb615392565b6020026020010151613803565b81525083828151811061341d5761341d615392565b60209081029190910101526001016133b4565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b8381101561348f578060011b82018184015160001a8060041c8253600f811660018301535050600101613461565b509295945050505050565b606060008060006134aa85613816565b9194509250905060008160018111156134c5576134c5615406565b14613552576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067f565b61355c828461527e565b8551146135eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161067f565b6123cc85602001518484614283565b60606020826000015110613616576136118261349a565b61105f565b61105f82614317565b606061105f61363e83602001516000815181106127fc576127fc615392565b613437565b606082518210613662575060408051602081019091526000815261105f565b6122e983838486516136749190614f84565b61432d565b600080825184511061368c57825161368f565b83515b90505b808210801561371657508282815181106136ae576136ae615392565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106136ed576136ed615392565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b1561372657816001019150613692565b5092915050565b6000808211613798576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061105f61381183614505565b6145ee565b6000806000808460000151116138d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b6020840151805160001a607f81116138f957600060016000945094509450505061427c565b60b78111613b0757600061390e608083614f84565b9050808760000151116139c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161067f565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613a4257507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613af4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161067f565b506001955093506000925061427c915050565b60bf8111613e55576000613b1c60b783614f84565b905080876000015111613bd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161067f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c60378111613d79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161067f565b613d83818461527e565b895111613e38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161067f565b613e4383600161527e565b975095506000945061427c9350505050565b60f78111613f36576000613e6a60c083614f84565b905080876000015111613f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b60019550935084925061427c915050565b6000613f4360f783614f84565b905080876000015111613ffe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161067f565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036140dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c603781116141a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161067f565b6141aa818461527e565b89511161425f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b61426a83600161527e565b975095506001945061427c9350505050565b9193909250565b60608167ffffffffffffffff81111561429e5761429e614850565b6040519080825280601f01601f1916602001820160405280156142c8576020820181803683370190505b50905081156122e95760006142dd848661527e565b90506020820160005b848110156142fe5782810151828201526020016142e6565b8481111561430d576000858301525b5050509392505050565b606061105f826020015160008460000151614283565b60608182601f01101561439c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b828284011015614408576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b81830184511015614475576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161067f565b60608215801561449457604051915060008252602082016040526144fc565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156144cd5780518352602092830192016144b5565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116145d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b50604080518082019091528151815260209182019181019190915290565b606060008060006145fe85613816565b91945092509050600181600181111561461957614619615406565b146146a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067f565b84516146b2838561527e565b1461473f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161067f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816147565790505093506000835b8651811015614844576000806147c96040518060400160405280858c600001516147ad9190614f84565b8152602001858c602001516147c2919061527e565b9052613816565b5091509150604051806040016040528083836147e5919061527e565b8152602001848b602001516147fa919061527e565b81525088858151811061480f5761480f615392565b602090810291909101015261482560018561527e565b9350614831818361527e565b61483b908461527e565b92505050614783565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156148c6576148c6614850565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff811681146148f057600080fd5b50565b600082601f83011261490457600080fd5b813567ffffffffffffffff81111561491e5761491e614850565b61494f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161487f565b81815284602083860101111561496457600080fd5b816020850160208301376000918101602001919091529392505050565b600060c0828403121561499357600080fd5b60405160c0810167ffffffffffffffff82821081831117156149b7576149b7614850565b8160405282935084358352602085013591506149d2826148ce565b816020840152604085013591506149e8826148ce565b816040840152606085013560608401526080850135608084015260a0850135915080821115614a1657600080fd5b50614a23858286016148f3565b60a0830152505092915050565b600080600080600085870360e0811215614a4957600080fd5b863567ffffffffffffffff80821115614a6157600080fd5b614a6d8a838b01614981565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614aa657600080fd5b60408901955060c0890135925080831115614ac057600080fd5b828901925089601f840112614ad457600080fd5b8235915080821115614ae557600080fd5b508860208260051b8401011115614afb57600080fd5b959894975092955050506020019190565b60005b83811015614b27578181015183820152602001614b0f565b83811115614b36576000848401525b50505050565b60008151808452614b54816020860160208601614b0c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122e96020830184614b3c565b600060208284031215614bab57600080fd5b5035919050565b600060208284031215614bc457600080fd5b813567ffffffffffffffff811115614bdb57600080fd5b614be784828501614981565b949350505050565b803567ffffffffffffffff81168114614c0757600080fd5b919050565b600060208284031215614c1e57600080fd5b6122e982614bef565b80358015158114614c0757600080fd5b600080600080600060a08688031215614c4f57600080fd5b8535614c5a816148ce565b945060208601359350614c6f60408701614bef565b9250614c7d60608701614c27565b9150608086013567ffffffffffffffff811115614c9957600080fd5b614ca5888289016148f3565b9150509295509295909350565b60008060008060808587031215614cc857600080fd5b8435614cd3816148ce565b93506020850135614ce3816148ce565b92506040850135614cf3816148ce565b9150614d0160608601614c27565b905092959194509250565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614d60816049850160208701614b0c565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614c0757600080fd5b600060608284031215614da357600080fd5b6040516060810181811067ffffffffffffffff82111715614dc657614dc6614850565b60405282518152614dd960208401614d71565b6020820152614dea60408401614d71565b60408201529392505050565b600060808284031215614e0857600080fd5b6040516080810181811067ffffffffffffffff82111715614e2b57614e2b614850565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e7757614e77614850565b8360051b6020614e8881830161487f565b868152918501918181019036841115614ea057600080fd5b865b84811015614ed457803586811115614eba5760008081fd5b614ec636828b016148f3565b845250918301918301614ea2565b50979650505050505050565b600060208284031215614ef257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614f4f57614f4f614ef9565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f7b57614f7b614ef9565b01949350505050565b600082821015614f9657614f96614ef9565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614fd957614fd9614f9b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561502d5761502d614ef9565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561506c5761506c614ef9565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150a0576150a0614ef9565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156150e7576150e7614ef9565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561512257615122614ef9565b6000871292508782058712848416161561513e5761513e614ef9565b8785058712818416161561515457615154614ef9565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561519c5761519c614ef9565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151d0576151d0614ef9565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561520e5761520e614ef9565b500290565b60008261522257615222614f9b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261527260c0830184614b3c565b98975050505050505050565b6000821982111561529157615291614ef9565b500190565b805163ffffffff81168114614c0757600080fd5b805160ff81168114614c0757600080fd5b600060c082840312156152cd57600080fd5b60405160c0810181811067ffffffffffffffff821117156152f0576152f0614850565b6040526152fc83615296565b815261530a602084016152aa565b602082015261531b604084016152aa565b604082015261532c60608401615296565b606082015261533d60808401615296565b608082015261534e60a08401614d71565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361538b5761538b614ef9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806153d4576153d4614f9b565b8060ff84160691505092915050565b600060ff821660ff8416808210156153fd576153fd614ef9565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"GUARDIAN\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L2_ORACLE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractL2OutputOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"SYSTEM_CONFIG\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractSystemConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"depositTransaction\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_gasLimit\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_isCreation\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"donateETH\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"finalizeWithdrawalTransaction\",\"inputs\":[{\"name\":\"_tx\",\"type\":\"tuple\",\"internalType\":\"structTypes.WithdrawalTransaction\",\"components\":[{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"finalizedWithdrawals\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"guardian\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_l2Oracle\",\"type\":\"address\",\"internalType\":\"contractL2OutputOracle\"},{\"name\":\"_systemConfig\",\"type\":\"address\",\"internalType\":\"contractSystemConfig\"},{\"name\":\"_superchainConfig\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isOutputFinalized\",\"inputs\":[{\"name\":\"_l2OutputIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l2Oracle\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractL2OutputOracle\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l2Sender\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"minimumGasLimit\",\"inputs\":[{\"name\":\"_byteCount\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"params\",\"inputs\":[],\"outputs\":[{\"name\":\"prevBaseFee\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"prevBoughtGas\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"prevBlockNum\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"paused_\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proveWithdrawalTransaction\",\"inputs\":[{\"name\":\"_tx\",\"type\":\"tuple\",\"internalType\":\"structTypes.WithdrawalTransaction\",\"components\":[{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"_l2OutputIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_outputRootProof\",\"type\":\"tuple\",\"internalType\":\"structTypes.OutputRootProof\",\"components\":[{\"name\":\"version\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"latestBlockhash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"provenWithdrawals\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"timestamp\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"l2OutputIndex\",\"type\":\"uint128\",\"internalType\":\"uint128\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"superchainConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"systemConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractSystemConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransactionDeposited\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"opaqueData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalFinalized\",\"inputs\":[{\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"success\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalProven\",\"inputs\":[{\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b50620000206000808062000026565b6200028f565b600054610100900460ff1615808015620000475750600054600160ff909116105b806200007757506200006430620001c160201b62001b741760201c565b15801562000077575060005460ff166001145b620000e05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000104576000805461ff0019166101001790555b603680546001600160a01b03199081166001600160a01b03878116919091179092556037805490911685831617905560358054610100600160a81b03191661010085841602179055603254166200016a57603280546001600160a01b03191661dead1790555b62000174620001d0565b8015620001bb576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff166200023d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d7565b600154600160c01b90046001600160401b03166000036200028d5760408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b02176001555b565b6153ed806200029f6000396000f3fe6080604052600436106101625760003560e01c80638c3152e9116100c0578063c0c53b8b11610074578063e965084c11610059578063e965084c146104c7578063e9e05c4214610553578063f04987501461056657600080fd5b8063c0c53b8b14610406578063cff0ab961461042657600080fd5b80639bf62d82116100a55780639bf62d8214610370578063a14238e71461039d578063a35d99df146103cd57600080fd5b80638c3152e9146103235780639b5f694a1461034357600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102ee578063724c184c1461030e5780638b4c40b01461018757600080fd5b806354fd4d50146102735780635c975abb146102c957600080fd5b806335e80ab31161014857806335e80ab31461020c578063452a93201461023e5780634870496f1461025357600080fd5b80621c2ff61461018e57806333d7e2bd146101df57600080fd5b36610189576101873334620186a0600060405180602001604052806000815250610591565b005b600080fd5b34801561019a57600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101eb57600080fd5b506037546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021857600080fd5b506035546101b590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024a57600080fd5b506101b561082c565b34801561025f57600080fd5b5061018761026e3660046149b4565b6108c4565b34801561027f57600080fd5b506102bc6040518060400160405280600581526020017f322e352e3000000000000000000000000000000000000000000000000000000081525081565b6040516101d69190614b06565b3480156102d557600080fd5b506102de610ef2565b60405190151581526020016101d6565b3480156102fa57600080fd5b506102de610309366004614b19565b610f85565b34801561031a57600080fd5b506101b5611040565b34801561032f57600080fd5b5061018761033e366004614b32565b61104c565b34801561034f57600080fd5b506036546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037c57600080fd5b506032546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a957600080fd5b506102de6103b8366004614b19565b60336020526000908152604090205460ff1681565b3480156103d957600080fd5b506103ed6103e8366004614b8c565b61190d565b60405167ffffffffffffffff90911681526020016101d6565b34801561041257600080fd5b50610187610421366004614ba7565b611926565b34801561043257600080fd5b5060015461048e906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101d6565b3480156104d357600080fd5b506105256104e2366004614b19565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101d6565b610187610561366004614c00565b610591565b34801561057257600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101b5565b8260005a905083156106485773ffffffffffffffffffffffffffffffffffffffff87161561064857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b610652835161190d565b67ffffffffffffffff168567ffffffffffffffff1610156106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161063f565b6201d4c083511115610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161063f565b33328114610784575033731111000000000000000000000000000000001111015b6000348888888860405160200161079f959493929190614c7d565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161080f9190614b06565b60405180910390a450506108238282611b90565b50505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561089b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190614ce2565b905090565b6108cc610ef2565b15610933576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161063f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161063f565b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a869190614d1f565b519050610aa0610a9b36869003860186614d84565b611ebd565b8114610b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161063f565b6000610b3987611f19565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c4f5750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4b9190614d1f565b5114155b610cdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161063f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610da49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d9a888a614dea565b8a60400135611f49565b610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161063f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f61573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190614e6e565b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161103a9173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610ffb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101f9190614d1f565b602001516fffffffffffffffffffffffffffffffff16611f6d565b92915050565b60006108bf61082c565b565b611054610ef2565b156110bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161063f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14611164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161063f565b600061116f82611f19565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff8082169483018590527001000000000000000000000000000000009091041691810191909152929350900361125a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161063f565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112eb9190614e8b565b81602001516fffffffffffffffffffffffffffffffff1610156113b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161063f565b6113d581602001516fffffffffffffffffffffffffffffffff16611f6d565b611487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161063f565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561150e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115329190614d1f565b82518151919250146115ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161063f565b61160b81602001516fffffffffffffffffffffffffffffffff16611f6d565b6116bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161063f565b60008381526033602052604090205460ff161561175c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161063f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a08801516117fe93929190612013565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061186390841515815260200190565b60405180910390a2801580156118795750326001145b15611906576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161063f565b5050505050565b600061191a826010614ed3565b61103a90615208614f03565b600054610100900460ff16158080156119465750600054600160ff909116105b806119605750303b158015611960575060005460ff166001145b6119ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161063f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611a4a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611b0357603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611b0b612071565b8015611b6e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090611bc6907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f2f565b90506000611bd2612184565b90506000816020015160ff16826000015163ffffffff16611bf39190614f75565b90508215611d2a57600154600090611c2a908390700100000000000000000000000000000000900467ffffffffffffffff16614fdd565b90506000836040015160ff1683611c419190615051565b600154611c619084906fffffffffffffffffffffffffffffffff16615051565b611c6b9190614f75565b600154909150600090611cbc90611c959084906fffffffffffffffffffffffffffffffff1661510d565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612245565b90506001861115611ceb57611ce8611c9582876040015160ff1660018a611ce39190614f2f565b612264565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611d5d908490700100000000000000000000000000000000900467ffffffffffffffff16614f03565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611e40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161063f565b600154600090611e6c906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615181565b90506000611e7e48633b9aca006122b9565b611e8890836151be565b905060005a611e979088614f2f565b905080821115611eb357611eb3611eae8284614f2f565b6122d0565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611efc949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611efc9790969591016151d2565b600080611f55866122fe565b9050611f6381868686612330565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa158015611fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120019190614e8b565b61200b9083615229565b421192915050565b6000806000612023866000612360565b905080612059576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff16612108576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161063f565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361104a5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612221573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190615266565b600061225a612254858561237e565b8361238e565b90505b9392505050565b6000670de0b6b3a76400006122a561227c8583614f75565b61228e90670de0b6b3a7640000614fdd565b6122a085670de0b6b3a7640000615051565b61239d565b6122af9086615051565b61225a9190614f75565b6000818310156122c9578161225d565b5090919050565b6000805a90505b825a6122e39083614f2f565b10156122f9576122f282615305565b91506122d7565b505050565b6060818051906020012060405160200161231a91815260200190565b6040516020818303038152906040529050919050565b6000612357846123418786866123ce565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156122c9578161225d565b60008183126122c9578161225d565b600061225d670de0b6b3a7640000836123b586612e4c565b6123bf9190615051565b6123c99190614f75565b613090565b6060600084511161243b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161063f565b6000612446846132cf565b90506000612453866133bb565b905060008460405160200161246a91815260200190565b60405160208183030381529060405290506000805b8451811015612dc357600085828151811061249c5761249c61533d565b602002602001015190508451831115612537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161063f565b826000036125f057805180516020918201206040516125859261255f92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6125eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161063f565b612747565b8051516020116126a6578051805160209182012060405161261a9261255f92910190815260200190565b6125eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161063f565b805184516020808701919091208251919092012014612747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161063f565b61275360106001615229565b8160200151510361292f57845183036128c75761278d81602001516010815181106127805761278061533d565b602002602001015161341e565b96506000875111612820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161063f565b6001865161282e9190614f2f565b82146128bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161063f565b50505050505061225d565b60008584815181106128db576128db61533d565b602001015160f81c60f81b60f81c9050600082602001518260ff16815181106129065761290661533d565b602002602001015190506129198161357e565b9550612926600186615229565b94505050612db0565b600281602001515103612d28576000612947826135a3565b905060008160008151811061295e5761295e61533d565b016020015160f81c9050600061297560028361536c565b61298090600261538e565b90506000612991848360ff166135c7565b9050600061299f8a896135c7565b905060006129ad83836135fd565b905080835114612a3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161063f565b60ff851660021480612a54575060ff85166003145b15612c435780825114612ae9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161063f565b612b0387602001516001815181106127805761278061533d565b9c5060008d5111612b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161063f565b60018c51612ba49190614f2f565b8814612c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161063f565b50505050505050505050505061225d565b60ff85161580612c56575060ff85166001145b15612c9557612c828760200151600181518110612c7557612c7561533d565b602002602001015161357e565b9950612c8e818a615229565b9850612d1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161063f565b505050505050612db0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161063f565b5080612dbb81615305565b91505061247f565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161063f565b6000808213612eb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161063f565b60006060612ec4846136b1565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136130c157506000919050565b680755bf798b4a1bf1e58212613133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161063f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156132ed576132ed6147d4565b60405190808252806020026020018201604052801561333257816020015b604080518082019091526060808252602082015281526020019060019003908161330b5790505b50915060005b818110156133b457604051806040016040528085838151811061335d5761335d61533d565b6020026020010151815260200161338c86848151811061337f5761337f61533d565b6020026020010151613787565b8152508382815181106133a1576133a161533d565b6020908102919091010152600101613338565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613413578060011b82018184015160001a8060041c8253600f8116600183015350506001016133e5565b509295945050505050565b6060600080600061342e8561379a565b919450925090506000816001811115613449576134496153b1565b146134d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161063f565b6134e08284615229565b85511461356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161063f565b61235785602001518484614207565b6060602082600001511061359a576135958261341e565b61103a565b61103a8261429b565b606061103a6135c283602001516000815181106127805761278061533d565b6133bb565b6060825182106135e6575060408051602081019091526000815261103a565b61225d83838486516135f89190614f2f565b6142b1565b6000808251845110613610578251613613565b83515b90505b808210801561369a57508282815181106136325761363261533d565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106136715761367161533d565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156136aa57816001019150613616565b5092915050565b600080821161371c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161063f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061103a61379583614489565b614572565b600080600080846000015111613858576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161063f565b6020840151805160001a607f811161387d576000600160009450945094505050614200565b60b78111613a8b576000613892608083614f2f565b90508087600001511161394d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161063f565b6001838101517fff000000000000000000000000000000000000000000000000000000000000001690821415806139c657507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613a78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161063f565b5060019550935060009250614200915050565b60bf8111613dd9576000613aa060b783614f2f565b905080876000015111613b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161063f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613c39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161063f565b600184015160088302610100031c60378111613cfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161063f565b613d078184615229565b895111613dbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161063f565b613dc7836001615229565b97509550600094506142009350505050565b60f78111613eba576000613dee60c083614f2f565b905080876000015111613ea9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161063f565b600195509350849250614200915050565b6000613ec760f783614f2f565b905080876000015111613f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161063f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161063f565b600184015160088302610100031c60378111614124576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161063f565b61412e8184615229565b8951116141e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161063f565b6141ee836001615229565b97509550600194506142009350505050565b9193909250565b60608167ffffffffffffffff811115614222576142226147d4565b6040519080825280601f01601f19166020018201604052801561424c576020820181803683370190505b509050811561225d5760006142618486615229565b90506020820160005b8481101561428257828101518282015260200161426a565b84811115614291576000858301525b5050509392505050565b606061103a826020015160008460000151614207565b60608182601f011015614320576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161063f565b82828401101561438c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161063f565b818301845110156143f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161063f565b6060821580156144185760405191506000825260208201604052614480565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614451578051835260209283019201614439565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201526000825111614554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161063f565b50604080518082019091528151815260209182019181019190915290565b606060008060006145828561379a565b91945092509050600181600181111561459d5761459d6153b1565b1461462a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161063f565b84516146368385615229565b146146c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161063f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816146da5790505093506000835b86518110156147c85760008061474d6040518060400160405280858c600001516147319190614f2f565b8152602001858c602001516147469190615229565b905261379a565b5091509150604051806040016040528083836147699190615229565b8152602001848b6020015161477e9190615229565b8152508885815181106147935761479361533d565b60209081029190910101526147a9600185615229565b93506147b58183615229565b6147bf9084615229565b92505050614707565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561484a5761484a6147d4565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461487457600080fd5b50565b600082601f83011261488857600080fd5b813567ffffffffffffffff8111156148a2576148a26147d4565b6148d360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614803565b8181528460208386010111156148e857600080fd5b816020850160208301376000918101602001919091529392505050565b600060c0828403121561491757600080fd5b60405160c0810167ffffffffffffffff828210818311171561493b5761493b6147d4565b81604052829350843583526020850135915061495682614852565b8160208401526040850135915061496c82614852565b816040840152606085013560608401526080850135608084015260a085013591508082111561499a57600080fd5b506149a785828601614877565b60a0830152505092915050565b600080600080600085870360e08112156149cd57600080fd5b863567ffffffffffffffff808211156149e557600080fd5b6149f18a838b01614905565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614a2a57600080fd5b60408901955060c0890135925080831115614a4457600080fd5b828901925089601f840112614a5857600080fd5b8235915080821115614a6957600080fd5b508860208260051b8401011115614a7f57600080fd5b959894975092955050506020019190565b60005b83811015614aab578181015183820152602001614a93565b83811115611b6e5750506000910152565b60008151808452614ad4816020860160208601614a90565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225d6020830184614abc565b600060208284031215614b2b57600080fd5b5035919050565b600060208284031215614b4457600080fd5b813567ffffffffffffffff811115614b5b57600080fd5b614b6784828501614905565b949350505050565b803567ffffffffffffffff81168114614b8757600080fd5b919050565b600060208284031215614b9e57600080fd5b61225d82614b6f565b600080600060608486031215614bbc57600080fd5b8335614bc781614852565b92506020840135614bd781614852565b91506040840135614be781614852565b809150509250925092565b801515811461487457600080fd5b600080600080600060a08688031215614c1857600080fd5b8535614c2381614852565b945060208601359350614c3860408701614b6f565b92506060860135614c4881614bf2565b9150608086013567ffffffffffffffff811115614c6457600080fd5b614c7088828901614877565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614cd1816049850160208701614a90565b919091016049019695505050505050565b600060208284031215614cf457600080fd5b815161225d81614852565b80516fffffffffffffffffffffffffffffffff81168114614b8757600080fd5b600060608284031215614d3157600080fd5b6040516060810181811067ffffffffffffffff82111715614d5457614d546147d4565b60405282518152614d6760208401614cff565b6020820152614d7860408401614cff565b60408201529392505050565b600060808284031215614d9657600080fd5b6040516080810181811067ffffffffffffffff82111715614db957614db96147d4565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e0557614e056147d4565b8360051b6020614e16818301614803565b868152918501918181019036841115614e2e57600080fd5b865b84811015614e6257803586811115614e485760008081fd5b614e5436828b01614877565b845250918301918301614e30565b50979650505050505050565b600060208284031215614e8057600080fd5b815161225d81614bf2565b600060208284031215614e9d57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614efa57614efa614ea4565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f2657614f26614ea4565b01949350505050565b600082821015614f4157614f41614ea4565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614f8457614f84614f46565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615614fd857614fd8614ea4565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561501757615017614ea4565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561504b5761504b614ea4565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561509257615092614ea4565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156150cd576150cd614ea4565b600087129250878205871284841616156150e9576150e9614ea4565b878505871281841616156150ff576150ff614ea4565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561514757615147614ea4565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561517b5761517b614ea4565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156151b9576151b9614ea4565b500290565b6000826151cd576151cd614f46565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261521d60c0830184614abc565b98975050505050505050565b6000821982111561523c5761523c614ea4565b500190565b805163ffffffff81168114614b8757600080fd5b805160ff81168114614b8757600080fd5b600060c0828403121561527857600080fd5b60405160c0810181811067ffffffffffffffff8211171561529b5761529b6147d4565b6040526152a783615241565b81526152b560208401615255565b60208201526152c660408401615255565b60408201526152d760608401615241565b60608201526152e860808401615241565b60808201526152f960a08401614cff565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361533657615336614ea4565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061537f5761537f614f46565b8060ff84160691505092915050565b600060ff821660ff8416808210156153a8576153a8614ea4565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", } // OptimismPortalABI is the input ABI used to generate the binding from. @@ -550,7 +550,7 @@ func (_OptimismPortal *OptimismPortalCallerSession) Params() (struct { // Paused is a free data retrieval call binding the contract method 0x5c975abb. // -// Solidity: function paused() view returns(bool) +// Solidity: function paused() view returns(bool paused_) func (_OptimismPortal *OptimismPortalCaller) Paused(opts *bind.CallOpts) (bool, error) { var out []interface{} err := _OptimismPortal.contract.Call(opts, &out, "paused") @@ -567,14 +567,14 @@ func (_OptimismPortal *OptimismPortalCaller) Paused(opts *bind.CallOpts) (bool, // Paused is a free data retrieval call binding the contract method 0x5c975abb. // -// Solidity: function paused() view returns(bool) +// Solidity: function paused() view returns(bool paused_) func (_OptimismPortal *OptimismPortalSession) Paused() (bool, error) { return _OptimismPortal.Contract.Paused(&_OptimismPortal.CallOpts) } // Paused is a free data retrieval call binding the contract method 0x5c975abb. // -// Solidity: function paused() view returns(bool) +// Solidity: function paused() view returns(bool paused_) func (_OptimismPortal *OptimismPortalCallerSession) Paused() (bool, error) { return _OptimismPortal.Contract.Paused(&_OptimismPortal.CallOpts) } @@ -629,6 +629,37 @@ func (_OptimismPortal *OptimismPortalCallerSession) ProvenWithdrawals(arg0 [32]b return _OptimismPortal.Contract.ProvenWithdrawals(&_OptimismPortal.CallOpts, arg0) } +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_OptimismPortal *OptimismPortalCaller) SuperchainConfig(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismPortal.contract.Call(opts, &out, "superchainConfig") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_OptimismPortal *OptimismPortalSession) SuperchainConfig() (common.Address, error) { + return _OptimismPortal.Contract.SuperchainConfig(&_OptimismPortal.CallOpts) +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_OptimismPortal *OptimismPortalCallerSession) SuperchainConfig() (common.Address, error) { + return _OptimismPortal.Contract.SuperchainConfig(&_OptimismPortal.CallOpts) +} + // SystemConfig is a free data retrieval call binding the contract method 0x33d7e2bd. // // Solidity: function systemConfig() view returns(address) @@ -754,46 +785,25 @@ func (_OptimismPortal *OptimismPortalTransactorSession) FinalizeWithdrawalTransa return _OptimismPortal.Contract.FinalizeWithdrawalTransaction(&_OptimismPortal.TransactOpts, _tx) } -// Initialize is a paid mutator transaction binding the contract method 0xfecf9734. -// -// Solidity: function initialize(address _l2Oracle, address _guardian, address _systemConfig, bool _paused) returns() -func (_OptimismPortal *OptimismPortalTransactor) Initialize(opts *bind.TransactOpts, _l2Oracle common.Address, _guardian common.Address, _systemConfig common.Address, _paused bool) (*types.Transaction, error) { - return _OptimismPortal.contract.Transact(opts, "initialize", _l2Oracle, _guardian, _systemConfig, _paused) -} - -// Initialize is a paid mutator transaction binding the contract method 0xfecf9734. -// -// Solidity: function initialize(address _l2Oracle, address _guardian, address _systemConfig, bool _paused) returns() -func (_OptimismPortal *OptimismPortalSession) Initialize(_l2Oracle common.Address, _guardian common.Address, _systemConfig common.Address, _paused bool) (*types.Transaction, error) { - return _OptimismPortal.Contract.Initialize(&_OptimismPortal.TransactOpts, _l2Oracle, _guardian, _systemConfig, _paused) -} - -// Initialize is a paid mutator transaction binding the contract method 0xfecf9734. -// -// Solidity: function initialize(address _l2Oracle, address _guardian, address _systemConfig, bool _paused) returns() -func (_OptimismPortal *OptimismPortalTransactorSession) Initialize(_l2Oracle common.Address, _guardian common.Address, _systemConfig common.Address, _paused bool) (*types.Transaction, error) { - return _OptimismPortal.Contract.Initialize(&_OptimismPortal.TransactOpts, _l2Oracle, _guardian, _systemConfig, _paused) -} - -// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// Initialize is a paid mutator transaction binding the contract method 0xc0c53b8b. // -// Solidity: function pause() returns() -func (_OptimismPortal *OptimismPortalTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OptimismPortal.contract.Transact(opts, "pause") +// Solidity: function initialize(address _l2Oracle, address _systemConfig, address _superchainConfig) returns() +func (_OptimismPortal *OptimismPortalTransactor) Initialize(opts *bind.TransactOpts, _l2Oracle common.Address, _systemConfig common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _OptimismPortal.contract.Transact(opts, "initialize", _l2Oracle, _systemConfig, _superchainConfig) } -// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// Initialize is a paid mutator transaction binding the contract method 0xc0c53b8b. // -// Solidity: function pause() returns() -func (_OptimismPortal *OptimismPortalSession) Pause() (*types.Transaction, error) { - return _OptimismPortal.Contract.Pause(&_OptimismPortal.TransactOpts) +// Solidity: function initialize(address _l2Oracle, address _systemConfig, address _superchainConfig) returns() +func (_OptimismPortal *OptimismPortalSession) Initialize(_l2Oracle common.Address, _systemConfig common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _OptimismPortal.Contract.Initialize(&_OptimismPortal.TransactOpts, _l2Oracle, _systemConfig, _superchainConfig) } -// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// Initialize is a paid mutator transaction binding the contract method 0xc0c53b8b. // -// Solidity: function pause() returns() -func (_OptimismPortal *OptimismPortalTransactorSession) Pause() (*types.Transaction, error) { - return _OptimismPortal.Contract.Pause(&_OptimismPortal.TransactOpts) +// Solidity: function initialize(address _l2Oracle, address _systemConfig, address _superchainConfig) returns() +func (_OptimismPortal *OptimismPortalTransactorSession) Initialize(_l2Oracle common.Address, _systemConfig common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _OptimismPortal.Contract.Initialize(&_OptimismPortal.TransactOpts, _l2Oracle, _systemConfig, _superchainConfig) } // ProveWithdrawalTransaction is a paid mutator transaction binding the contract method 0x4870496f. @@ -817,27 +827,6 @@ func (_OptimismPortal *OptimismPortalTransactorSession) ProveWithdrawalTransacti return _OptimismPortal.Contract.ProveWithdrawalTransaction(&_OptimismPortal.TransactOpts, _tx, _l2OutputIndex, _outputRootProof, _withdrawalProof) } -// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. -// -// Solidity: function unpause() returns() -func (_OptimismPortal *OptimismPortalTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OptimismPortal.contract.Transact(opts, "unpause") -} - -// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. -// -// Solidity: function unpause() returns() -func (_OptimismPortal *OptimismPortalSession) Unpause() (*types.Transaction, error) { - return _OptimismPortal.Contract.Unpause(&_OptimismPortal.TransactOpts) -} - -// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. -// -// Solidity: function unpause() returns() -func (_OptimismPortal *OptimismPortalTransactorSession) Unpause() (*types.Transaction, error) { - return _OptimismPortal.Contract.Unpause(&_OptimismPortal.TransactOpts) -} - // Receive is a paid mutator transaction binding the contract receive function. // // Solidity: receive() payable returns() @@ -993,140 +982,6 @@ func (_OptimismPortal *OptimismPortalFilterer) ParseInitialized(log types.Log) ( return event, nil } -// OptimismPortalPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the OptimismPortal contract. -type OptimismPortalPausedIterator struct { - Event *OptimismPortalPaused // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *OptimismPortalPausedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(OptimismPortalPaused) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(OptimismPortalPaused) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *OptimismPortalPausedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *OptimismPortalPausedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// OptimismPortalPaused represents a Paused event raised by the OptimismPortal contract. -type OptimismPortalPaused struct { - Account common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. -// -// Solidity: event Paused(address account) -func (_OptimismPortal *OptimismPortalFilterer) FilterPaused(opts *bind.FilterOpts) (*OptimismPortalPausedIterator, error) { - - logs, sub, err := _OptimismPortal.contract.FilterLogs(opts, "Paused") - if err != nil { - return nil, err - } - return &OptimismPortalPausedIterator{contract: _OptimismPortal.contract, event: "Paused", logs: logs, sub: sub}, nil -} - -// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. -// -// Solidity: event Paused(address account) -func (_OptimismPortal *OptimismPortalFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *OptimismPortalPaused) (event.Subscription, error) { - - logs, sub, err := _OptimismPortal.contract.WatchLogs(opts, "Paused") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(OptimismPortalPaused) - if err := _OptimismPortal.contract.UnpackLog(event, "Paused", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. -// -// Solidity: event Paused(address account) -func (_OptimismPortal *OptimismPortalFilterer) ParsePaused(log types.Log) (*OptimismPortalPaused, error) { - event := new(OptimismPortalPaused) - if err := _OptimismPortal.contract.UnpackLog(event, "Paused", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - // OptimismPortalTransactionDepositedIterator is returned from FilterTransactionDeposited and is used to iterate over the raw logs and unpacked data for TransactionDeposited events raised by the OptimismPortal contract. type OptimismPortalTransactionDepositedIterator struct { Event *OptimismPortalTransactionDeposited // Event containing the contract specifics and raw log @@ -1290,140 +1145,6 @@ func (_OptimismPortal *OptimismPortalFilterer) ParseTransactionDeposited(log typ return event, nil } -// OptimismPortalUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the OptimismPortal contract. -type OptimismPortalUnpausedIterator struct { - Event *OptimismPortalUnpaused // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *OptimismPortalUnpausedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(OptimismPortalUnpaused) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(OptimismPortalUnpaused) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *OptimismPortalUnpausedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *OptimismPortalUnpausedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// OptimismPortalUnpaused represents a Unpaused event raised by the OptimismPortal contract. -type OptimismPortalUnpaused struct { - Account common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. -// -// Solidity: event Unpaused(address account) -func (_OptimismPortal *OptimismPortalFilterer) FilterUnpaused(opts *bind.FilterOpts) (*OptimismPortalUnpausedIterator, error) { - - logs, sub, err := _OptimismPortal.contract.FilterLogs(opts, "Unpaused") - if err != nil { - return nil, err - } - return &OptimismPortalUnpausedIterator{contract: _OptimismPortal.contract, event: "Unpaused", logs: logs, sub: sub}, nil -} - -// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. -// -// Solidity: event Unpaused(address account) -func (_OptimismPortal *OptimismPortalFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *OptimismPortalUnpaused) (event.Subscription, error) { - - logs, sub, err := _OptimismPortal.contract.WatchLogs(opts, "Unpaused") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(OptimismPortalUnpaused) - if err := _OptimismPortal.contract.UnpackLog(event, "Unpaused", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. -// -// Solidity: event Unpaused(address account) -func (_OptimismPortal *OptimismPortalFilterer) ParseUnpaused(log types.Log) (*OptimismPortalUnpaused, error) { - event := new(OptimismPortalUnpaused) - if err := _OptimismPortal.contract.UnpackLog(event, "Unpaused", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - // OptimismPortalWithdrawalFinalizedIterator is returned from FilterWithdrawalFinalized and is used to iterate over the raw logs and unpacked data for WithdrawalFinalized events raised by the OptimismPortal contract. type OptimismPortalWithdrawalFinalizedIterator struct { Event *OptimismPortalWithdrawalFinalized // Event containing the contract specifics and raw log diff --git a/op-bindings/bindings/optimismportal_more.go b/op-bindings/bindings/optimismportal_more.go index ccad47b3f316..7610e608c68a 100644 --- a/op-bindings/bindings/optimismportal_more.go +++ b/op-bindings/bindings/optimismportal_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const OptimismPortalStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"params\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_struct(ResourceParams)1014_storage\"},{\"astId\":1003,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_array(t_uint256)48_storage\"},{\"astId\":1004,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"l2Sender\",\"offset\":0,\"slot\":\"50\",\"type\":\"t_address\"},{\"astId\":1005,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"finalizedWithdrawals\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1006,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"provenWithdrawals\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_mapping(t_bytes32,t_struct(ProvenWithdrawal)1013_storage)\"},{\"astId\":1007,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"paused\",\"offset\":0,\"slot\":\"53\",\"type\":\"t_bool\"},{\"astId\":1008,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"l2Oracle\",\"offset\":1,\"slot\":\"53\",\"type\":\"t_contract(L2OutputOracle)1011\"},{\"astId\":1009,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"systemConfig\",\"offset\":0,\"slot\":\"54\",\"type\":\"t_contract(SystemConfig)1012\"},{\"astId\":1010,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"guardian\",\"offset\":0,\"slot\":\"55\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)48_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[48]\",\"numberOfBytes\":\"1536\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_contract(L2OutputOracle)1011\":{\"encoding\":\"inplace\",\"label\":\"contract L2OutputOracle\",\"numberOfBytes\":\"20\"},\"t_contract(SystemConfig)1012\":{\"encoding\":\"inplace\",\"label\":\"contract SystemConfig\",\"numberOfBytes\":\"20\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_mapping(t_bytes32,t_struct(ProvenWithdrawal)1013_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e struct OptimismPortal.ProvenWithdrawal)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_struct(ProvenWithdrawal)1013_storage\"},\"t_struct(ProvenWithdrawal)1013_storage\":{\"encoding\":\"inplace\",\"label\":\"struct OptimismPortal.ProvenWithdrawal\",\"numberOfBytes\":\"64\"},\"t_struct(ResourceParams)1014_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ResourceMetering.ResourceParams\",\"numberOfBytes\":\"32\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const OptimismPortalStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"params\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_struct(ResourceParams)1015_storage\"},{\"astId\":1003,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_array(t_uint256)48_storage\"},{\"astId\":1004,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"l2Sender\",\"offset\":0,\"slot\":\"50\",\"type\":\"t_address\"},{\"astId\":1005,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"finalizedWithdrawals\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1006,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"provenWithdrawals\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_mapping(t_bytes32,t_struct(ProvenWithdrawal)1014_storage)\"},{\"astId\":1007,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"spacer_53_0_1\",\"offset\":0,\"slot\":\"53\",\"type\":\"t_bool\"},{\"astId\":1008,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"superchainConfig\",\"offset\":1,\"slot\":\"53\",\"type\":\"t_contract(SuperchainConfig)1012\"},{\"astId\":1009,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"l2Oracle\",\"offset\":0,\"slot\":\"54\",\"type\":\"t_contract(L2OutputOracle)1011\"},{\"astId\":1010,\"contract\":\"src/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"systemConfig\",\"offset\":0,\"slot\":\"55\",\"type\":\"t_contract(SystemConfig)1013\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)48_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[48]\",\"numberOfBytes\":\"1536\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_contract(L2OutputOracle)1011\":{\"encoding\":\"inplace\",\"label\":\"contract L2OutputOracle\",\"numberOfBytes\":\"20\"},\"t_contract(SuperchainConfig)1012\":{\"encoding\":\"inplace\",\"label\":\"contract SuperchainConfig\",\"numberOfBytes\":\"20\"},\"t_contract(SystemConfig)1013\":{\"encoding\":\"inplace\",\"label\":\"contract SystemConfig\",\"numberOfBytes\":\"20\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_mapping(t_bytes32,t_struct(ProvenWithdrawal)1014_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e struct OptimismPortal.ProvenWithdrawal)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_struct(ProvenWithdrawal)1014_storage\"},\"t_struct(ProvenWithdrawal)1014_storage\":{\"encoding\":\"inplace\",\"label\":\"struct OptimismPortal.ProvenWithdrawal\",\"numberOfBytes\":\"64\"},\"t_struct(ResourceParams)1015_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ResourceMetering.ResourceParams\",\"numberOfBytes\":\"32\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var OptimismPortalStorageLayout = new(solc.StorageLayout) -var OptimismPortalDeployedBin = "0x60806040526004361061016d5760003560e01c80638b4c40b0116100cb578063a35d99df1161007f578063e9e05c4211610059578063e9e05c4214610573578063f049875014610586578063fecf9734146105b157600080fd5b8063a35d99df1461040d578063cff0ab9614610446578063e965084c146104e757600080fd5b80639b5f694a116100b05780639b5f694a1461037e5780639bf62d82146103b0578063a14238e7146103dd57600080fd5b80638b4c40b0146101925780638c3152e91461035e57600080fd5b806354fd4d50116101225780636dbffb78116101075780636dbffb78146102fe578063724c184c1461031e5780638456cb591461034957600080fd5b806354fd4d501461027e5780635c975abb146102d457600080fd5b80633f4ba83a116101535780633f4ba83a1461021c578063452a9320146102315780634870496f1461025e57600080fd5b80621c2ff61461019957806333d7e2bd146101ef57600080fd5b36610194576101923334620186a06000604051806020016040528060008152506105d1565b005b600080fd5b3480156101a557600080fd5b50603554610100900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101fb57600080fd5b506036546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022857600080fd5b5061019261086c565b34801561023d57600080fd5b506037546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026a57600080fd5b50610192610279366004614a30565b610971565b34801561028a57600080fd5b506102c76040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b6040516101e69190614b86565b3480156102e057600080fd5b506035546102ee9060ff1681565b60405190151581526020016101e6565b34801561030a57600080fd5b506102ee610319366004614b99565b610fa6565b34801561032a57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101c5565b34801561035557600080fd5b50610192611065565b34801561036a57600080fd5b50610192610379366004614bb2565b611167565b34801561038a57600080fd5b506035546101c590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103bc57600080fd5b506032546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e957600080fd5b506102ee6103f8366004614b99565b60336020526000908152604090205460ff1681565b34801561041957600080fd5b5061042d610428366004614c0c565b611a2b565b60405167ffffffffffffffff90911681526020016101e6565b34801561045257600080fd5b506001546104ae906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101e6565b3480156104f357600080fd5b50610545610502366004614b99565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101e6565b610192610581366004614c37565b6105d1565b34801561059257600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff166101c5565b3480156105bd57600080fd5b506101926105cc366004614cb2565b611a44565b8260005a905083156106885773ffffffffffffffffffffffffffffffffffffffff87161561068857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6106928351611a2b565b67ffffffffffffffff168567ffffffffffffffff161015610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161067f565b6201d4c0835111156107a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161067f565b333281146107c4575033731111000000000000000000000000000000001111015b600034888888886040516020016107df959493929190614d0c565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161084f9190614b86565b60405180910390a450506108638282611c52565b50505050505050565b60375473ffffffffffffffffffffffffffffffffffffffff163314610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e70617573650000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff16156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161067f565b6035546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101869052600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190614d91565b519050610b50610b4b36869003860186614df6565b611f75565b8114610bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161067f565b6000610be987611fd1565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d035750805160355460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190614d91565b5114155b610d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161067f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610e589101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610e4e888a614e5c565b8a60400135612001565b610ee4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161067f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6035546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161105f9161010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190614d91565b602001516fffffffffffffffffffffffffffffffff16612025565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff16331461110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20706175736500000000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610967565b60355460ff16156111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161067f565b600061128882611fd1565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161067f565b603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190614ee0565b81602001516fffffffffffffffffffffffffffffffff1610156114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161067f565b6114ee81602001516fffffffffffffffffffffffffffffffff16612025565b6115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60355460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff9091166004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561162c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116509190614d91565b825181519192501461170a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161067f565b61172981602001516fffffffffffffffffffffffffffffffff16612025565b6117db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60008381526033602052604090205460ff161561187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161067f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161191c939291906120ca565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061198190841515815260200190565b60405180910390a2801580156119975750326001145b15611a24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161067f565b5050505050565b6000611a38826010614f28565b61105f90615208614f58565b600054600390610100900460ff16158015611a66575060005460ff8083169116105b611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100908117909155603280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811661dead17909155603580546036805473ffffffffffffffffffffffffffffffffffffffff89811691861691909117909155603780548a83169516949094179093558515159289169093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fffffffffffffffffffffff00000000000000000000000000000000000000000090931692909217179055611bed612128565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600154600090611c88907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f84565b90506000611c9461220b565b90506000816020015160ff16826000015163ffffffff16611cb59190614fca565b90508215611dec57600154600090611cec908390700100000000000000000000000000000000900467ffffffffffffffff16615032565b90506000836040015160ff1683611d0391906150a6565b600154611d239084906fffffffffffffffffffffffffffffffff166150a6565b611d2d9190614fca565b600154909150600090611d7e90611d579084906fffffffffffffffffffffffffffffffff16615162565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166122d1565b90506001861115611dad57611daa611d5782876040015160ff1660018a611da59190614f84565b6122f0565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e1f908490700100000000000000000000000000000000900467ffffffffffffffff16614f58565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161067f565b600154600090611f2e906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166151d6565b90506000611f4063b2d05e0083615213565b905060005a611f4f9088614f84565b905080821115611f6b57611f6b611f668284614f84565b612345565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611fb4949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611fb4979096959101615227565b60008061200d86612373565b905061201b818686866123a5565b9695505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa158015612094573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b89190614ee0565b6120c2908361527e565b421192915050565b60008060006120da8660006123d5565b905080612110576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166121bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067f565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260365483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156122a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122cc91906152bb565b905090565b60006122e66122e085856123f3565b8361240a565b90505b9392505050565b6000670de0b6b3a76400006123316123088583614fca565b61231a90670de0b6b3a7640000615032565b61232c85670de0b6b3a76400006150a6565b612419565b61233b90866150a6565b6122e69190614fca565b6000805a90505b825a6123589083614f84565b101561236e576123678261535a565b915061234c565b505050565b6060818051906020012060405160200161238f91815260200190565b6040516020818303038152906040529050919050565b60006123cc846123b687868661244a565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561240357816122e9565b5090919050565b600081831261240357816122e9565b60006122e9670de0b6b3a76400008361243186612ec8565b61243b91906150a6565b6124459190614fca565b61310c565b606060008451116124b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161067f565b60006124c28461334b565b905060006124cf86613437565b90506000846040516020016124e691815260200190565b60405160208183030381529060405290506000805b8451811015612e3f57600085828151811061251857612518615392565b6020026020010151905084518311156125b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161067f565b8260000361266c5780518051602091820120604051612601926125db92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612667576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067f565b6127c3565b8051516020116127225780518051602091820120604051612696926125db92910190815260200190565b612667576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161067f565b8051845160208087019190912082519190920120146127c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161067f565b6127cf6010600161527e565b816020015151036129ab57845183036129435761280981602001516010815181106127fc576127fc615392565b602002602001015161349a565b9650600087511161289c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067f565b600186516128aa9190614f84565b8214612938576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067f565b5050505050506122e9565b600085848151811061295757612957615392565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061298257612982615392565b60200260200101519050612995816135fa565b95506129a260018661527e565b94505050612e2c565b600281602001515103612da45760006129c38261361f565b90506000816000815181106129da576129da615392565b016020015160f81c905060006129f16002836153c1565b6129fc9060026153e3565b90506000612a0d848360ff16613643565b90506000612a1b8a89613643565b90506000612a298383613679565b905080835114612abb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067f565b60ff851660021480612ad0575060ff85166003145b15612cbf5780825114612b65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067f565b612b7f87602001516001815181106127fc576127fc615392565b9c5060008d5111612c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067f565b60018c51612c209190614f84565b8814612cae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067f565b5050505050505050505050506122e9565b60ff85161580612cd2575060ff85166001145b15612d1157612cfe8760200151600181518110612cf157612cf1615392565b60200260200101516135fa565b9950612d0a818a61527e565b9850612d99565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161067f565b505050505050612e2c565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161067f565b5080612e378161535a565b9150506124fb565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161067f565b6000808213612f33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b60006060612f408461372d565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361313d57506000919050565b680755bf798b4a1bf1e582126131af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161067f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff81111561336957613369614850565b6040519080825280602002602001820160405280156133ae57816020015b60408051808201909152606080825260208201528152602001906001900390816133875790505b50915060005b818110156134305760405180604001604052808583815181106133d9576133d9615392565b602002602001015181526020016134088684815181106133fb576133fb615392565b6020026020010151613803565b81525083828151811061341d5761341d615392565b60209081029190910101526001016133b4565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b8381101561348f578060011b82018184015160001a8060041c8253600f811660018301535050600101613461565b509295945050505050565b606060008060006134aa85613816565b9194509250905060008160018111156134c5576134c5615406565b14613552576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067f565b61355c828461527e565b8551146135eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161067f565b6123cc85602001518484614283565b60606020826000015110613616576136118261349a565b61105f565b61105f82614317565b606061105f61363e83602001516000815181106127fc576127fc615392565b613437565b606082518210613662575060408051602081019091526000815261105f565b6122e983838486516136749190614f84565b61432d565b600080825184511061368c57825161368f565b83515b90505b808210801561371657508282815181106136ae576136ae615392565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106136ed576136ed615392565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b1561372657816001019150613692565b5092915050565b6000808211613798576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061105f61381183614505565b6145ee565b6000806000808460000151116138d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b6020840151805160001a607f81116138f957600060016000945094509450505061427c565b60b78111613b0757600061390e608083614f84565b9050808760000151116139c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161067f565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613a4257507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613af4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161067f565b506001955093506000925061427c915050565b60bf8111613e55576000613b1c60b783614f84565b905080876000015111613bd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161067f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c60378111613d79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161067f565b613d83818461527e565b895111613e38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161067f565b613e4383600161527e565b975095506000945061427c9350505050565b60f78111613f36576000613e6a60c083614f84565b905080876000015111613f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b60019550935084925061427c915050565b6000613f4360f783614f84565b905080876000015111613ffe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161067f565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036140dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c603781116141a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161067f565b6141aa818461527e565b89511161425f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b61426a83600161527e565b975095506001945061427c9350505050565b9193909250565b60608167ffffffffffffffff81111561429e5761429e614850565b6040519080825280601f01601f1916602001820160405280156142c8576020820181803683370190505b50905081156122e95760006142dd848661527e565b90506020820160005b848110156142fe5782810151828201526020016142e6565b8481111561430d576000858301525b5050509392505050565b606061105f826020015160008460000151614283565b60608182601f01101561439c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b828284011015614408576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b81830184511015614475576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161067f565b60608215801561449457604051915060008252602082016040526144fc565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156144cd5780518352602092830192016144b5565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116145d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b50604080518082019091528151815260209182019181019190915290565b606060008060006145fe85613816565b91945092509050600181600181111561461957614619615406565b146146a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067f565b84516146b2838561527e565b1461473f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161067f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816147565790505093506000835b8651811015614844576000806147c96040518060400160405280858c600001516147ad9190614f84565b8152602001858c602001516147c2919061527e565b9052613816565b5091509150604051806040016040528083836147e5919061527e565b8152602001848b602001516147fa919061527e565b81525088858151811061480f5761480f615392565b602090810291909101015261482560018561527e565b9350614831818361527e565b61483b908461527e565b92505050614783565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156148c6576148c6614850565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff811681146148f057600080fd5b50565b600082601f83011261490457600080fd5b813567ffffffffffffffff81111561491e5761491e614850565b61494f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161487f565b81815284602083860101111561496457600080fd5b816020850160208301376000918101602001919091529392505050565b600060c0828403121561499357600080fd5b60405160c0810167ffffffffffffffff82821081831117156149b7576149b7614850565b8160405282935084358352602085013591506149d2826148ce565b816020840152604085013591506149e8826148ce565b816040840152606085013560608401526080850135608084015260a0850135915080821115614a1657600080fd5b50614a23858286016148f3565b60a0830152505092915050565b600080600080600085870360e0811215614a4957600080fd5b863567ffffffffffffffff80821115614a6157600080fd5b614a6d8a838b01614981565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614aa657600080fd5b60408901955060c0890135925080831115614ac057600080fd5b828901925089601f840112614ad457600080fd5b8235915080821115614ae557600080fd5b508860208260051b8401011115614afb57600080fd5b959894975092955050506020019190565b60005b83811015614b27578181015183820152602001614b0f565b83811115614b36576000848401525b50505050565b60008151808452614b54816020860160208601614b0c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122e96020830184614b3c565b600060208284031215614bab57600080fd5b5035919050565b600060208284031215614bc457600080fd5b813567ffffffffffffffff811115614bdb57600080fd5b614be784828501614981565b949350505050565b803567ffffffffffffffff81168114614c0757600080fd5b919050565b600060208284031215614c1e57600080fd5b6122e982614bef565b80358015158114614c0757600080fd5b600080600080600060a08688031215614c4f57600080fd5b8535614c5a816148ce565b945060208601359350614c6f60408701614bef565b9250614c7d60608701614c27565b9150608086013567ffffffffffffffff811115614c9957600080fd5b614ca5888289016148f3565b9150509295509295909350565b60008060008060808587031215614cc857600080fd5b8435614cd3816148ce565b93506020850135614ce3816148ce565b92506040850135614cf3816148ce565b9150614d0160608601614c27565b905092959194509250565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614d60816049850160208701614b0c565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614c0757600080fd5b600060608284031215614da357600080fd5b6040516060810181811067ffffffffffffffff82111715614dc657614dc6614850565b60405282518152614dd960208401614d71565b6020820152614dea60408401614d71565b60408201529392505050565b600060808284031215614e0857600080fd5b6040516080810181811067ffffffffffffffff82111715614e2b57614e2b614850565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e7757614e77614850565b8360051b6020614e8881830161487f565b868152918501918181019036841115614ea057600080fd5b865b84811015614ed457803586811115614eba5760008081fd5b614ec636828b016148f3565b845250918301918301614ea2565b50979650505050505050565b600060208284031215614ef257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614f4f57614f4f614ef9565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f7b57614f7b614ef9565b01949350505050565b600082821015614f9657614f96614ef9565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614fd957614fd9614f9b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561502d5761502d614ef9565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561506c5761506c614ef9565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150a0576150a0614ef9565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156150e7576150e7614ef9565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561512257615122614ef9565b6000871292508782058712848416161561513e5761513e614ef9565b8785058712818416161561515457615154614ef9565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561519c5761519c614ef9565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151d0576151d0614ef9565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561520e5761520e614ef9565b500290565b60008261522257615222614f9b565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261527260c0830184614b3c565b98975050505050505050565b6000821982111561529157615291614ef9565b500190565b805163ffffffff81168114614c0757600080fd5b805160ff81168114614c0757600080fd5b600060c082840312156152cd57600080fd5b60405160c0810181811067ffffffffffffffff821117156152f0576152f0614850565b6040526152fc83615296565b815261530a602084016152aa565b602082015261531b604084016152aa565b604082015261532c60608401615296565b606082015261533d60808401615296565b608082015261534e60a08401614d71565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361538b5761538b614ef9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806153d4576153d4614f9b565b8060ff84160691505092915050565b600060ff821660ff8416808210156153fd576153fd614ef9565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a" +var OptimismPortalDeployedBin = "0x6080604052600436106101625760003560e01c80638c3152e9116100c0578063c0c53b8b11610074578063e965084c11610059578063e965084c146104c7578063e9e05c4214610553578063f04987501461056657600080fd5b8063c0c53b8b14610406578063cff0ab961461042657600080fd5b80639bf62d82116100a55780639bf62d8214610370578063a14238e71461039d578063a35d99df146103cd57600080fd5b80638c3152e9146103235780639b5f694a1461034357600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102ee578063724c184c1461030e5780638b4c40b01461018757600080fd5b806354fd4d50146102735780635c975abb146102c957600080fd5b806335e80ab31161014857806335e80ab31461020c578063452a93201461023e5780634870496f1461025357600080fd5b80621c2ff61461018e57806333d7e2bd146101df57600080fd5b36610189576101873334620186a0600060405180602001604052806000815250610591565b005b600080fd5b34801561019a57600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101eb57600080fd5b506037546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021857600080fd5b506035546101b590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024a57600080fd5b506101b561082c565b34801561025f57600080fd5b5061018761026e3660046149b4565b6108c4565b34801561027f57600080fd5b506102bc6040518060400160405280600581526020017f322e352e3000000000000000000000000000000000000000000000000000000081525081565b6040516101d69190614b06565b3480156102d557600080fd5b506102de610ef2565b60405190151581526020016101d6565b3480156102fa57600080fd5b506102de610309366004614b19565b610f85565b34801561031a57600080fd5b506101b5611040565b34801561032f57600080fd5b5061018761033e366004614b32565b61104c565b34801561034f57600080fd5b506036546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037c57600080fd5b506032546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a957600080fd5b506102de6103b8366004614b19565b60336020526000908152604090205460ff1681565b3480156103d957600080fd5b506103ed6103e8366004614b8c565b61190d565b60405167ffffffffffffffff90911681526020016101d6565b34801561041257600080fd5b50610187610421366004614ba7565b611926565b34801561043257600080fd5b5060015461048e906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101d6565b3480156104d357600080fd5b506105256104e2366004614b19565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101d6565b610187610561366004614c00565b610591565b34801561057257600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101b5565b8260005a905083156106485773ffffffffffffffffffffffffffffffffffffffff87161561064857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b610652835161190d565b67ffffffffffffffff168567ffffffffffffffff1610156106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161063f565b6201d4c083511115610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161063f565b33328114610784575033731111000000000000000000000000000000001111015b6000348888888860405160200161079f959493929190614c7d565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161080f9190614b06565b60405180910390a450506108238282611b90565b50505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561089b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190614ce2565b905090565b6108cc610ef2565b15610933576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161063f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161063f565b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a869190614d1f565b519050610aa0610a9b36869003860186614d84565b611ebd565b8114610b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161063f565b6000610b3987611f19565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c4f5750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4b9190614d1f565b5114155b610cdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161063f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610da49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d9a888a614dea565b8a60400135611f49565b610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161063f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f61573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190614e6e565b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161103a9173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610ffb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101f9190614d1f565b602001516fffffffffffffffffffffffffffffffff16611f6d565b92915050565b60006108bf61082c565b565b611054610ef2565b156110bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161063f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14611164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161063f565b600061116f82611f19565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff8082169483018590527001000000000000000000000000000000009091041691810191909152929350900361125a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161063f565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112eb9190614e8b565b81602001516fffffffffffffffffffffffffffffffff1610156113b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161063f565b6113d581602001516fffffffffffffffffffffffffffffffff16611f6d565b611487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161063f565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561150e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115329190614d1f565b82518151919250146115ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161063f565b61160b81602001516fffffffffffffffffffffffffffffffff16611f6d565b6116bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161063f565b60008381526033602052604090205460ff161561175c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161063f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a08801516117fe93929190612013565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061186390841515815260200190565b60405180910390a2801580156118795750326001145b15611906576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161063f565b5050505050565b600061191a826010614ed3565b61103a90615208614f03565b600054610100900460ff16158080156119465750600054600160ff909116105b806119605750303b158015611960575060005460ff166001145b6119ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161063f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611a4a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611b0357603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611b0b612071565b8015611b6e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090611bc6907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f2f565b90506000611bd2612184565b90506000816020015160ff16826000015163ffffffff16611bf39190614f75565b90508215611d2a57600154600090611c2a908390700100000000000000000000000000000000900467ffffffffffffffff16614fdd565b90506000836040015160ff1683611c419190615051565b600154611c619084906fffffffffffffffffffffffffffffffff16615051565b611c6b9190614f75565b600154909150600090611cbc90611c959084906fffffffffffffffffffffffffffffffff1661510d565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612245565b90506001861115611ceb57611ce8611c9582876040015160ff1660018a611ce39190614f2f565b612264565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611d5d908490700100000000000000000000000000000000900467ffffffffffffffff16614f03565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611e40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161063f565b600154600090611e6c906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615181565b90506000611e7e48633b9aca006122b9565b611e8890836151be565b905060005a611e979088614f2f565b905080821115611eb357611eb3611eae8284614f2f565b6122d0565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611efc949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611efc9790969591016151d2565b600080611f55866122fe565b9050611f6381868686612330565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa158015611fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120019190614e8b565b61200b9083615229565b421192915050565b6000806000612023866000612360565b905080612059576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff16612108576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161063f565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361104a5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612221573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190615266565b600061225a612254858561237e565b8361238e565b90505b9392505050565b6000670de0b6b3a76400006122a561227c8583614f75565b61228e90670de0b6b3a7640000614fdd565b6122a085670de0b6b3a7640000615051565b61239d565b6122af9086615051565b61225a9190614f75565b6000818310156122c9578161225d565b5090919050565b6000805a90505b825a6122e39083614f2f565b10156122f9576122f282615305565b91506122d7565b505050565b6060818051906020012060405160200161231a91815260200190565b6040516020818303038152906040529050919050565b6000612357846123418786866123ce565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156122c9578161225d565b60008183126122c9578161225d565b600061225d670de0b6b3a7640000836123b586612e4c565b6123bf9190615051565b6123c99190614f75565b613090565b6060600084511161243b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161063f565b6000612446846132cf565b90506000612453866133bb565b905060008460405160200161246a91815260200190565b60405160208183030381529060405290506000805b8451811015612dc357600085828151811061249c5761249c61533d565b602002602001015190508451831115612537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161063f565b826000036125f057805180516020918201206040516125859261255f92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6125eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161063f565b612747565b8051516020116126a6578051805160209182012060405161261a9261255f92910190815260200190565b6125eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161063f565b805184516020808701919091208251919092012014612747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161063f565b61275360106001615229565b8160200151510361292f57845183036128c75761278d81602001516010815181106127805761278061533d565b602002602001015161341e565b96506000875111612820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161063f565b6001865161282e9190614f2f565b82146128bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161063f565b50505050505061225d565b60008584815181106128db576128db61533d565b602001015160f81c60f81b60f81c9050600082602001518260ff16815181106129065761290661533d565b602002602001015190506129198161357e565b9550612926600186615229565b94505050612db0565b600281602001515103612d28576000612947826135a3565b905060008160008151811061295e5761295e61533d565b016020015160f81c9050600061297560028361536c565b61298090600261538e565b90506000612991848360ff166135c7565b9050600061299f8a896135c7565b905060006129ad83836135fd565b905080835114612a3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161063f565b60ff851660021480612a54575060ff85166003145b15612c435780825114612ae9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161063f565b612b0387602001516001815181106127805761278061533d565b9c5060008d5111612b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161063f565b60018c51612ba49190614f2f565b8814612c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161063f565b50505050505050505050505061225d565b60ff85161580612c56575060ff85166001145b15612c9557612c828760200151600181518110612c7557612c7561533d565b602002602001015161357e565b9950612c8e818a615229565b9850612d1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161063f565b505050505050612db0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161063f565b5080612dbb81615305565b91505061247f565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161063f565b6000808213612eb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161063f565b60006060612ec4846136b1565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136130c157506000919050565b680755bf798b4a1bf1e58212613133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161063f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156132ed576132ed6147d4565b60405190808252806020026020018201604052801561333257816020015b604080518082019091526060808252602082015281526020019060019003908161330b5790505b50915060005b818110156133b457604051806040016040528085838151811061335d5761335d61533d565b6020026020010151815260200161338c86848151811061337f5761337f61533d565b6020026020010151613787565b8152508382815181106133a1576133a161533d565b6020908102919091010152600101613338565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613413578060011b82018184015160001a8060041c8253600f8116600183015350506001016133e5565b509295945050505050565b6060600080600061342e8561379a565b919450925090506000816001811115613449576134496153b1565b146134d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161063f565b6134e08284615229565b85511461356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161063f565b61235785602001518484614207565b6060602082600001511061359a576135958261341e565b61103a565b61103a8261429b565b606061103a6135c283602001516000815181106127805761278061533d565b6133bb565b6060825182106135e6575060408051602081019091526000815261103a565b61225d83838486516135f89190614f2f565b6142b1565b6000808251845110613610578251613613565b83515b90505b808210801561369a57508282815181106136325761363261533d565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106136715761367161533d565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156136aa57816001019150613616565b5092915050565b600080821161371c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161063f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061103a61379583614489565b614572565b600080600080846000015111613858576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161063f565b6020840151805160001a607f811161387d576000600160009450945094505050614200565b60b78111613a8b576000613892608083614f2f565b90508087600001511161394d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161063f565b6001838101517fff000000000000000000000000000000000000000000000000000000000000001690821415806139c657507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613a78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161063f565b5060019550935060009250614200915050565b60bf8111613dd9576000613aa060b783614f2f565b905080876000015111613b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161063f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613c39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161063f565b600184015160088302610100031c60378111613cfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161063f565b613d078184615229565b895111613dbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161063f565b613dc7836001615229565b97509550600094506142009350505050565b60f78111613eba576000613dee60c083614f2f565b905080876000015111613ea9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161063f565b600195509350849250614200915050565b6000613ec760f783614f2f565b905080876000015111613f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161063f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161063f565b600184015160088302610100031c60378111614124576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161063f565b61412e8184615229565b8951116141e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161063f565b6141ee836001615229565b97509550600194506142009350505050565b9193909250565b60608167ffffffffffffffff811115614222576142226147d4565b6040519080825280601f01601f19166020018201604052801561424c576020820181803683370190505b509050811561225d5760006142618486615229565b90506020820160005b8481101561428257828101518282015260200161426a565b84811115614291576000858301525b5050509392505050565b606061103a826020015160008460000151614207565b60608182601f011015614320576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161063f565b82828401101561438c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161063f565b818301845110156143f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161063f565b6060821580156144185760405191506000825260208201604052614480565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614451578051835260209283019201614439565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201526000825111614554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161063f565b50604080518082019091528151815260209182019181019190915290565b606060008060006145828561379a565b91945092509050600181600181111561459d5761459d6153b1565b1461462a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161063f565b84516146368385615229565b146146c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161063f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816146da5790505093506000835b86518110156147c85760008061474d6040518060400160405280858c600001516147319190614f2f565b8152602001858c602001516147469190615229565b905261379a565b5091509150604051806040016040528083836147699190615229565b8152602001848b6020015161477e9190615229565b8152508885815181106147935761479361533d565b60209081029190910101526147a9600185615229565b93506147b58183615229565b6147bf9084615229565b92505050614707565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561484a5761484a6147d4565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461487457600080fd5b50565b600082601f83011261488857600080fd5b813567ffffffffffffffff8111156148a2576148a26147d4565b6148d360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614803565b8181528460208386010111156148e857600080fd5b816020850160208301376000918101602001919091529392505050565b600060c0828403121561491757600080fd5b60405160c0810167ffffffffffffffff828210818311171561493b5761493b6147d4565b81604052829350843583526020850135915061495682614852565b8160208401526040850135915061496c82614852565b816040840152606085013560608401526080850135608084015260a085013591508082111561499a57600080fd5b506149a785828601614877565b60a0830152505092915050565b600080600080600085870360e08112156149cd57600080fd5b863567ffffffffffffffff808211156149e557600080fd5b6149f18a838b01614905565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614a2a57600080fd5b60408901955060c0890135925080831115614a4457600080fd5b828901925089601f840112614a5857600080fd5b8235915080821115614a6957600080fd5b508860208260051b8401011115614a7f57600080fd5b959894975092955050506020019190565b60005b83811015614aab578181015183820152602001614a93565b83811115611b6e5750506000910152565b60008151808452614ad4816020860160208601614a90565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225d6020830184614abc565b600060208284031215614b2b57600080fd5b5035919050565b600060208284031215614b4457600080fd5b813567ffffffffffffffff811115614b5b57600080fd5b614b6784828501614905565b949350505050565b803567ffffffffffffffff81168114614b8757600080fd5b919050565b600060208284031215614b9e57600080fd5b61225d82614b6f565b600080600060608486031215614bbc57600080fd5b8335614bc781614852565b92506020840135614bd781614852565b91506040840135614be781614852565b809150509250925092565b801515811461487457600080fd5b600080600080600060a08688031215614c1857600080fd5b8535614c2381614852565b945060208601359350614c3860408701614b6f565b92506060860135614c4881614bf2565b9150608086013567ffffffffffffffff811115614c6457600080fd5b614c7088828901614877565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614cd1816049850160208701614a90565b919091016049019695505050505050565b600060208284031215614cf457600080fd5b815161225d81614852565b80516fffffffffffffffffffffffffffffffff81168114614b8757600080fd5b600060608284031215614d3157600080fd5b6040516060810181811067ffffffffffffffff82111715614d5457614d546147d4565b60405282518152614d6760208401614cff565b6020820152614d7860408401614cff565b60408201529392505050565b600060808284031215614d9657600080fd5b6040516080810181811067ffffffffffffffff82111715614db957614db96147d4565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e0557614e056147d4565b8360051b6020614e16818301614803565b868152918501918181019036841115614e2e57600080fd5b865b84811015614e6257803586811115614e485760008081fd5b614e5436828b01614877565b845250918301918301614e30565b50979650505050505050565b600060208284031215614e8057600080fd5b815161225d81614bf2565b600060208284031215614e9d57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614efa57614efa614ea4565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f2657614f26614ea4565b01949350505050565b600082821015614f4157614f41614ea4565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614f8457614f84614f46565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615614fd857614fd8614ea4565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561501757615017614ea4565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561504b5761504b614ea4565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561509257615092614ea4565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156150cd576150cd614ea4565b600087129250878205871284841616156150e9576150e9614ea4565b878505871281841616156150ff576150ff614ea4565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561514757615147614ea4565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561517b5761517b614ea4565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156151b9576151b9614ea4565b500290565b6000826151cd576151cd614f46565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261521d60c0830184614abc565b98975050505050505050565b6000821982111561523c5761523c614ea4565b500190565b805163ffffffff81168114614b8757600080fd5b805160ff81168114614b8757600080fd5b600060c0828403121561527857600080fd5b60405160c0810181811067ffffffffffffffff8211171561529b5761529b6147d4565b6040526152a783615241565b81526152b560208401615255565b60208201526152c660408401615255565b60408201526152d760608401615241565b60608201526152e860808401615241565b60808201526152f960a08401614cff565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361533657615336614ea4565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061537f5761537f614f46565b8060ff84160691505092915050565b600060ff821660ff8416808210156153a8576153a8614ea4565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(OptimismPortalStorageLayoutJSON), OptimismPortalStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["OptimismPortal"] = OptimismPortalStorageLayout deployedBytecodes["OptimismPortal"] = OptimismPortalDeployedBin + immutableReferences["OptimismPortal"] = false } diff --git a/op-bindings/bindings/permit2.go b/op-bindings/bindings/permit2.go new file mode 100644 index 000000000000..9a380f0cee8a --- /dev/null +++ b/op-bindings/bindings/permit2.go @@ -0,0 +1,1413 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// IAllowanceTransferAllowanceTransferDetails is an auto generated low-level Go binding around an user-defined struct. +type IAllowanceTransferAllowanceTransferDetails struct { + From common.Address + To common.Address + Amount *big.Int + Token common.Address +} + +// IAllowanceTransferPermitBatch is an auto generated low-level Go binding around an user-defined struct. +type IAllowanceTransferPermitBatch struct { + Details []IAllowanceTransferPermitDetails + Spender common.Address + SigDeadline *big.Int +} + +// IAllowanceTransferPermitDetails is an auto generated low-level Go binding around an user-defined struct. +type IAllowanceTransferPermitDetails struct { + Token common.Address + Amount *big.Int + Expiration *big.Int + Nonce *big.Int +} + +// IAllowanceTransferPermitSingle is an auto generated low-level Go binding around an user-defined struct. +type IAllowanceTransferPermitSingle struct { + Details IAllowanceTransferPermitDetails + Spender common.Address + SigDeadline *big.Int +} + +// IAllowanceTransferTokenSpenderPair is an auto generated low-level Go binding around an user-defined struct. +type IAllowanceTransferTokenSpenderPair struct { + Token common.Address + Spender common.Address +} + +// ISignatureTransferPermitBatchTransferFrom is an auto generated low-level Go binding around an user-defined struct. +type ISignatureTransferPermitBatchTransferFrom struct { + Permitted []ISignatureTransferTokenPermissions + Nonce *big.Int + Deadline *big.Int +} + +// ISignatureTransferPermitTransferFrom is an auto generated low-level Go binding around an user-defined struct. +type ISignatureTransferPermitTransferFrom struct { + Permitted ISignatureTransferTokenPermissions + Nonce *big.Int + Deadline *big.Int +} + +// ISignatureTransferSignatureTransferDetails is an auto generated low-level Go binding around an user-defined struct. +type ISignatureTransferSignatureTransferDetails struct { + To common.Address + RequestedAmount *big.Int +} + +// ISignatureTransferTokenPermissions is an auto generated low-level Go binding around an user-defined struct. +type ISignatureTransferTokenPermissions struct { + Token common.Address + Amount *big.Int +} + +// Permit2MetaData contains all meta data concerning the Permit2 contract. +var Permit2MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"name\":\"AllowanceExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExcessiveInvalidation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxAmount\",\"type\":\"uint256\"}],\"name\":\"InvalidAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidContractSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"signatureDeadline\",\"type\":\"uint256\"}],\"name\":\"SignatureExpired\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"Lockdown\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"newNonce\",\"type\":\"uint48\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"oldNonce\",\"type\":\"uint48\"}],\"name\":\"NonceInvalidation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"},{\"indexed\":false,\"internalType\":\"uint48\",\"name\":\"nonce\",\"type\":\"uint48\"}],\"name\":\"Permit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"word\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"mask\",\"type\":\"uint256\"}],\"name\":\"UnorderedNonceInvalidation\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"nonce\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint48\",\"name\":\"newNonce\",\"type\":\"uint48\"}],\"name\":\"invalidateNonces\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wordPos\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mask\",\"type\":\"uint256\"}],\"name\":\"invalidateUnorderedNonces\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"internalType\":\"structIAllowanceTransfer.TokenSpenderPair[]\",\"name\":\"approvals\",\"type\":\"tuple[]\"}],\"name\":\"lockdown\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"nonceBitmap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"nonce\",\"type\":\"uint48\"}],\"internalType\":\"structIAllowanceTransfer.PermitDetails[]\",\"name\":\"details\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"sigDeadline\",\"type\":\"uint256\"}],\"internalType\":\"structIAllowanceTransfer.PermitBatch\",\"name\":\"permitBatch\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"uint48\",\"name\":\"expiration\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"nonce\",\"type\":\"uint48\"}],\"internalType\":\"structIAllowanceTransfer.PermitDetails\",\"name\":\"details\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"sigDeadline\",\"type\":\"uint256\"}],\"internalType\":\"structIAllowanceTransfer.PermitSingle\",\"name\":\"permitSingle\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.TokenPermissions\",\"name\":\"permitted\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.PermitTransferFrom\",\"name\":\"permit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestedAmount\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.SignatureTransferDetails\",\"name\":\"transferDetails\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permitTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.TokenPermissions[]\",\"name\":\"permitted\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.PermitBatchTransferFrom\",\"name\":\"permit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestedAmount\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.SignatureTransferDetails[]\",\"name\":\"transferDetails\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permitTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.TokenPermissions\",\"name\":\"permitted\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.PermitTransferFrom\",\"name\":\"permit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestedAmount\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.SignatureTransferDetails\",\"name\":\"transferDetails\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"witness\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"witnessTypeString\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permitWitnessTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.TokenPermissions[]\",\"name\":\"permitted\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.PermitBatchTransferFrom\",\"name\":\"permit\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestedAmount\",\"type\":\"uint256\"}],\"internalType\":\"structISignatureTransfer.SignatureTransferDetails[]\",\"name\":\"transferDetails\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"witness\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"witnessTypeString\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"permitWitnessTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structIAllowanceTransfer.AllowanceTransferDetails[]\",\"name\":\"transferDetails\",\"type\":\"tuple[]\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amount\",\"type\":\"uint160\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c0346100bb574660a052602081017f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a60408301524660608301523060808301526080825260a082019180831060018060401b038411176100a557826040525190206080526123c090816100c1823960805181611b47015260a05181611b210152f35b634e487b7160e01b600052604160045260246000fd5b600080fdfe6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000003611b69577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a", +} + +// Permit2ABI is the input ABI used to generate the binding from. +// Deprecated: Use Permit2MetaData.ABI instead. +var Permit2ABI = Permit2MetaData.ABI + +// Permit2Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use Permit2MetaData.Bin instead. +var Permit2Bin = Permit2MetaData.Bin + +// DeployPermit2 deploys a new Ethereum contract, binding an instance of Permit2 to it. +func DeployPermit2(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Permit2, error) { + parsed, err := Permit2MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(Permit2Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Permit2{Permit2Caller: Permit2Caller{contract: contract}, Permit2Transactor: Permit2Transactor{contract: contract}, Permit2Filterer: Permit2Filterer{contract: contract}}, nil +} + +// Permit2 is an auto generated Go binding around an Ethereum contract. +type Permit2 struct { + Permit2Caller // Read-only binding to the contract + Permit2Transactor // Write-only binding to the contract + Permit2Filterer // Log filterer for contract events +} + +// Permit2Caller is an auto generated read-only Go binding around an Ethereum contract. +type Permit2Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Permit2Transactor is an auto generated write-only Go binding around an Ethereum contract. +type Permit2Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Permit2Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type Permit2Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Permit2Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type Permit2Session struct { + Contract *Permit2 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// Permit2CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type Permit2CallerSession struct { + Contract *Permit2Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// Permit2TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type Permit2TransactorSession struct { + Contract *Permit2Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// Permit2Raw is an auto generated low-level Go binding around an Ethereum contract. +type Permit2Raw struct { + Contract *Permit2 // Generic contract binding to access the raw methods on +} + +// Permit2CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type Permit2CallerRaw struct { + Contract *Permit2Caller // Generic read-only contract binding to access the raw methods on +} + +// Permit2TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type Permit2TransactorRaw struct { + Contract *Permit2Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewPermit2 creates a new instance of Permit2, bound to a specific deployed contract. +func NewPermit2(address common.Address, backend bind.ContractBackend) (*Permit2, error) { + contract, err := bindPermit2(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Permit2{Permit2Caller: Permit2Caller{contract: contract}, Permit2Transactor: Permit2Transactor{contract: contract}, Permit2Filterer: Permit2Filterer{contract: contract}}, nil +} + +// NewPermit2Caller creates a new read-only instance of Permit2, bound to a specific deployed contract. +func NewPermit2Caller(address common.Address, caller bind.ContractCaller) (*Permit2Caller, error) { + contract, err := bindPermit2(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &Permit2Caller{contract: contract}, nil +} + +// NewPermit2Transactor creates a new write-only instance of Permit2, bound to a specific deployed contract. +func NewPermit2Transactor(address common.Address, transactor bind.ContractTransactor) (*Permit2Transactor, error) { + contract, err := bindPermit2(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &Permit2Transactor{contract: contract}, nil +} + +// NewPermit2Filterer creates a new log filterer instance of Permit2, bound to a specific deployed contract. +func NewPermit2Filterer(address common.Address, filterer bind.ContractFilterer) (*Permit2Filterer, error) { + contract, err := bindPermit2(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &Permit2Filterer{contract: contract}, nil +} + +// bindPermit2 binds a generic wrapper to an already deployed contract. +func bindPermit2(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(Permit2ABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Permit2 *Permit2Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Permit2.Contract.Permit2Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Permit2 *Permit2Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Permit2.Contract.Permit2Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Permit2 *Permit2Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Permit2.Contract.Permit2Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Permit2 *Permit2CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Permit2.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Permit2 *Permit2TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Permit2.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Permit2 *Permit2TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Permit2.Contract.contract.Transact(opts, method, params...) +} + +// DOMAINSEPARATOR is a free data retrieval call binding the contract method 0x3644e515. +// +// Solidity: function DOMAIN_SEPARATOR() view returns(bytes32) +func (_Permit2 *Permit2Caller) DOMAINSEPARATOR(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Permit2.contract.Call(opts, &out, "DOMAIN_SEPARATOR") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DOMAINSEPARATOR is a free data retrieval call binding the contract method 0x3644e515. +// +// Solidity: function DOMAIN_SEPARATOR() view returns(bytes32) +func (_Permit2 *Permit2Session) DOMAINSEPARATOR() ([32]byte, error) { + return _Permit2.Contract.DOMAINSEPARATOR(&_Permit2.CallOpts) +} + +// DOMAINSEPARATOR is a free data retrieval call binding the contract method 0x3644e515. +// +// Solidity: function DOMAIN_SEPARATOR() view returns(bytes32) +func (_Permit2 *Permit2CallerSession) DOMAINSEPARATOR() ([32]byte, error) { + return _Permit2.Contract.DOMAINSEPARATOR(&_Permit2.CallOpts) +} + +// Allowance is a free data retrieval call binding the contract method 0x927da105. +// +// Solidity: function allowance(address , address , address ) view returns(uint160 amount, uint48 expiration, uint48 nonce) +func (_Permit2 *Permit2Caller) Allowance(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 common.Address) (struct { + Amount *big.Int + Expiration *big.Int + Nonce *big.Int +}, error) { + var out []interface{} + err := _Permit2.contract.Call(opts, &out, "allowance", arg0, arg1, arg2) + + outstruct := new(struct { + Amount *big.Int + Expiration *big.Int + Nonce *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Amount = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Expiration = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.Nonce = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// Allowance is a free data retrieval call binding the contract method 0x927da105. +// +// Solidity: function allowance(address , address , address ) view returns(uint160 amount, uint48 expiration, uint48 nonce) +func (_Permit2 *Permit2Session) Allowance(arg0 common.Address, arg1 common.Address, arg2 common.Address) (struct { + Amount *big.Int + Expiration *big.Int + Nonce *big.Int +}, error) { + return _Permit2.Contract.Allowance(&_Permit2.CallOpts, arg0, arg1, arg2) +} + +// Allowance is a free data retrieval call binding the contract method 0x927da105. +// +// Solidity: function allowance(address , address , address ) view returns(uint160 amount, uint48 expiration, uint48 nonce) +func (_Permit2 *Permit2CallerSession) Allowance(arg0 common.Address, arg1 common.Address, arg2 common.Address) (struct { + Amount *big.Int + Expiration *big.Int + Nonce *big.Int +}, error) { + return _Permit2.Contract.Allowance(&_Permit2.CallOpts, arg0, arg1, arg2) +} + +// NonceBitmap is a free data retrieval call binding the contract method 0x4fe02b44. +// +// Solidity: function nonceBitmap(address , uint256 ) view returns(uint256) +func (_Permit2 *Permit2Caller) NonceBitmap(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _Permit2.contract.Call(opts, &out, "nonceBitmap", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NonceBitmap is a free data retrieval call binding the contract method 0x4fe02b44. +// +// Solidity: function nonceBitmap(address , uint256 ) view returns(uint256) +func (_Permit2 *Permit2Session) NonceBitmap(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { + return _Permit2.Contract.NonceBitmap(&_Permit2.CallOpts, arg0, arg1) +} + +// NonceBitmap is a free data retrieval call binding the contract method 0x4fe02b44. +// +// Solidity: function nonceBitmap(address , uint256 ) view returns(uint256) +func (_Permit2 *Permit2CallerSession) NonceBitmap(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { + return _Permit2.Contract.NonceBitmap(&_Permit2.CallOpts, arg0, arg1) +} + +// Approve is a paid mutator transaction binding the contract method 0x87517c45. +// +// Solidity: function approve(address token, address spender, uint160 amount, uint48 expiration) returns() +func (_Permit2 *Permit2Transactor) Approve(opts *bind.TransactOpts, token common.Address, spender common.Address, amount *big.Int, expiration *big.Int) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "approve", token, spender, amount, expiration) +} + +// Approve is a paid mutator transaction binding the contract method 0x87517c45. +// +// Solidity: function approve(address token, address spender, uint160 amount, uint48 expiration) returns() +func (_Permit2 *Permit2Session) Approve(token common.Address, spender common.Address, amount *big.Int, expiration *big.Int) (*types.Transaction, error) { + return _Permit2.Contract.Approve(&_Permit2.TransactOpts, token, spender, amount, expiration) +} + +// Approve is a paid mutator transaction binding the contract method 0x87517c45. +// +// Solidity: function approve(address token, address spender, uint160 amount, uint48 expiration) returns() +func (_Permit2 *Permit2TransactorSession) Approve(token common.Address, spender common.Address, amount *big.Int, expiration *big.Int) (*types.Transaction, error) { + return _Permit2.Contract.Approve(&_Permit2.TransactOpts, token, spender, amount, expiration) +} + +// InvalidateNonces is a paid mutator transaction binding the contract method 0x65d9723c. +// +// Solidity: function invalidateNonces(address token, address spender, uint48 newNonce) returns() +func (_Permit2 *Permit2Transactor) InvalidateNonces(opts *bind.TransactOpts, token common.Address, spender common.Address, newNonce *big.Int) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "invalidateNonces", token, spender, newNonce) +} + +// InvalidateNonces is a paid mutator transaction binding the contract method 0x65d9723c. +// +// Solidity: function invalidateNonces(address token, address spender, uint48 newNonce) returns() +func (_Permit2 *Permit2Session) InvalidateNonces(token common.Address, spender common.Address, newNonce *big.Int) (*types.Transaction, error) { + return _Permit2.Contract.InvalidateNonces(&_Permit2.TransactOpts, token, spender, newNonce) +} + +// InvalidateNonces is a paid mutator transaction binding the contract method 0x65d9723c. +// +// Solidity: function invalidateNonces(address token, address spender, uint48 newNonce) returns() +func (_Permit2 *Permit2TransactorSession) InvalidateNonces(token common.Address, spender common.Address, newNonce *big.Int) (*types.Transaction, error) { + return _Permit2.Contract.InvalidateNonces(&_Permit2.TransactOpts, token, spender, newNonce) +} + +// InvalidateUnorderedNonces is a paid mutator transaction binding the contract method 0x3ff9dcb1. +// +// Solidity: function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) returns() +func (_Permit2 *Permit2Transactor) InvalidateUnorderedNonces(opts *bind.TransactOpts, wordPos *big.Int, mask *big.Int) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "invalidateUnorderedNonces", wordPos, mask) +} + +// InvalidateUnorderedNonces is a paid mutator transaction binding the contract method 0x3ff9dcb1. +// +// Solidity: function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) returns() +func (_Permit2 *Permit2Session) InvalidateUnorderedNonces(wordPos *big.Int, mask *big.Int) (*types.Transaction, error) { + return _Permit2.Contract.InvalidateUnorderedNonces(&_Permit2.TransactOpts, wordPos, mask) +} + +// InvalidateUnorderedNonces is a paid mutator transaction binding the contract method 0x3ff9dcb1. +// +// Solidity: function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) returns() +func (_Permit2 *Permit2TransactorSession) InvalidateUnorderedNonces(wordPos *big.Int, mask *big.Int) (*types.Transaction, error) { + return _Permit2.Contract.InvalidateUnorderedNonces(&_Permit2.TransactOpts, wordPos, mask) +} + +// Lockdown is a paid mutator transaction binding the contract method 0xcc53287f. +// +// Solidity: function lockdown((address,address)[] approvals) returns() +func (_Permit2 *Permit2Transactor) Lockdown(opts *bind.TransactOpts, approvals []IAllowanceTransferTokenSpenderPair) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "lockdown", approvals) +} + +// Lockdown is a paid mutator transaction binding the contract method 0xcc53287f. +// +// Solidity: function lockdown((address,address)[] approvals) returns() +func (_Permit2 *Permit2Session) Lockdown(approvals []IAllowanceTransferTokenSpenderPair) (*types.Transaction, error) { + return _Permit2.Contract.Lockdown(&_Permit2.TransactOpts, approvals) +} + +// Lockdown is a paid mutator transaction binding the contract method 0xcc53287f. +// +// Solidity: function lockdown((address,address)[] approvals) returns() +func (_Permit2 *Permit2TransactorSession) Lockdown(approvals []IAllowanceTransferTokenSpenderPair) (*types.Transaction, error) { + return _Permit2.Contract.Lockdown(&_Permit2.TransactOpts, approvals) +} + +// Permit is a paid mutator transaction binding the contract method 0x2a2d80d1. +// +// Solidity: function permit(address owner, ((address,uint160,uint48,uint48)[],address,uint256) permitBatch, bytes signature) returns() +func (_Permit2 *Permit2Transactor) Permit(opts *bind.TransactOpts, owner common.Address, permitBatch IAllowanceTransferPermitBatch, signature []byte) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "permit", owner, permitBatch, signature) +} + +// Permit is a paid mutator transaction binding the contract method 0x2a2d80d1. +// +// Solidity: function permit(address owner, ((address,uint160,uint48,uint48)[],address,uint256) permitBatch, bytes signature) returns() +func (_Permit2 *Permit2Session) Permit(owner common.Address, permitBatch IAllowanceTransferPermitBatch, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.Permit(&_Permit2.TransactOpts, owner, permitBatch, signature) +} + +// Permit is a paid mutator transaction binding the contract method 0x2a2d80d1. +// +// Solidity: function permit(address owner, ((address,uint160,uint48,uint48)[],address,uint256) permitBatch, bytes signature) returns() +func (_Permit2 *Permit2TransactorSession) Permit(owner common.Address, permitBatch IAllowanceTransferPermitBatch, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.Permit(&_Permit2.TransactOpts, owner, permitBatch, signature) +} + +// Permit0 is a paid mutator transaction binding the contract method 0x2b67b570. +// +// Solidity: function permit(address owner, ((address,uint160,uint48,uint48),address,uint256) permitSingle, bytes signature) returns() +func (_Permit2 *Permit2Transactor) Permit0(opts *bind.TransactOpts, owner common.Address, permitSingle IAllowanceTransferPermitSingle, signature []byte) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "permit0", owner, permitSingle, signature) +} + +// Permit0 is a paid mutator transaction binding the contract method 0x2b67b570. +// +// Solidity: function permit(address owner, ((address,uint160,uint48,uint48),address,uint256) permitSingle, bytes signature) returns() +func (_Permit2 *Permit2Session) Permit0(owner common.Address, permitSingle IAllowanceTransferPermitSingle, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.Permit0(&_Permit2.TransactOpts, owner, permitSingle, signature) +} + +// Permit0 is a paid mutator transaction binding the contract method 0x2b67b570. +// +// Solidity: function permit(address owner, ((address,uint160,uint48,uint48),address,uint256) permitSingle, bytes signature) returns() +func (_Permit2 *Permit2TransactorSession) Permit0(owner common.Address, permitSingle IAllowanceTransferPermitSingle, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.Permit0(&_Permit2.TransactOpts, owner, permitSingle, signature) +} + +// PermitTransferFrom is a paid mutator transaction binding the contract method 0x30f28b7a. +// +// Solidity: function permitTransferFrom(((address,uint256),uint256,uint256) permit, (address,uint256) transferDetails, address owner, bytes signature) returns() +func (_Permit2 *Permit2Transactor) PermitTransferFrom(opts *bind.TransactOpts, permit ISignatureTransferPermitTransferFrom, transferDetails ISignatureTransferSignatureTransferDetails, owner common.Address, signature []byte) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "permitTransferFrom", permit, transferDetails, owner, signature) +} + +// PermitTransferFrom is a paid mutator transaction binding the contract method 0x30f28b7a. +// +// Solidity: function permitTransferFrom(((address,uint256),uint256,uint256) permit, (address,uint256) transferDetails, address owner, bytes signature) returns() +func (_Permit2 *Permit2Session) PermitTransferFrom(permit ISignatureTransferPermitTransferFrom, transferDetails ISignatureTransferSignatureTransferDetails, owner common.Address, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.PermitTransferFrom(&_Permit2.TransactOpts, permit, transferDetails, owner, signature) +} + +// PermitTransferFrom is a paid mutator transaction binding the contract method 0x30f28b7a. +// +// Solidity: function permitTransferFrom(((address,uint256),uint256,uint256) permit, (address,uint256) transferDetails, address owner, bytes signature) returns() +func (_Permit2 *Permit2TransactorSession) PermitTransferFrom(permit ISignatureTransferPermitTransferFrom, transferDetails ISignatureTransferSignatureTransferDetails, owner common.Address, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.PermitTransferFrom(&_Permit2.TransactOpts, permit, transferDetails, owner, signature) +} + +// PermitTransferFrom0 is a paid mutator transaction binding the contract method 0xedd9444b. +// +// Solidity: function permitTransferFrom(((address,uint256)[],uint256,uint256) permit, (address,uint256)[] transferDetails, address owner, bytes signature) returns() +func (_Permit2 *Permit2Transactor) PermitTransferFrom0(opts *bind.TransactOpts, permit ISignatureTransferPermitBatchTransferFrom, transferDetails []ISignatureTransferSignatureTransferDetails, owner common.Address, signature []byte) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "permitTransferFrom0", permit, transferDetails, owner, signature) +} + +// PermitTransferFrom0 is a paid mutator transaction binding the contract method 0xedd9444b. +// +// Solidity: function permitTransferFrom(((address,uint256)[],uint256,uint256) permit, (address,uint256)[] transferDetails, address owner, bytes signature) returns() +func (_Permit2 *Permit2Session) PermitTransferFrom0(permit ISignatureTransferPermitBatchTransferFrom, transferDetails []ISignatureTransferSignatureTransferDetails, owner common.Address, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.PermitTransferFrom0(&_Permit2.TransactOpts, permit, transferDetails, owner, signature) +} + +// PermitTransferFrom0 is a paid mutator transaction binding the contract method 0xedd9444b. +// +// Solidity: function permitTransferFrom(((address,uint256)[],uint256,uint256) permit, (address,uint256)[] transferDetails, address owner, bytes signature) returns() +func (_Permit2 *Permit2TransactorSession) PermitTransferFrom0(permit ISignatureTransferPermitBatchTransferFrom, transferDetails []ISignatureTransferSignatureTransferDetails, owner common.Address, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.PermitTransferFrom0(&_Permit2.TransactOpts, permit, transferDetails, owner, signature) +} + +// PermitWitnessTransferFrom is a paid mutator transaction binding the contract method 0x137c29fe. +// +// Solidity: function permitWitnessTransferFrom(((address,uint256),uint256,uint256) permit, (address,uint256) transferDetails, address owner, bytes32 witness, string witnessTypeString, bytes signature) returns() +func (_Permit2 *Permit2Transactor) PermitWitnessTransferFrom(opts *bind.TransactOpts, permit ISignatureTransferPermitTransferFrom, transferDetails ISignatureTransferSignatureTransferDetails, owner common.Address, witness [32]byte, witnessTypeString string, signature []byte) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "permitWitnessTransferFrom", permit, transferDetails, owner, witness, witnessTypeString, signature) +} + +// PermitWitnessTransferFrom is a paid mutator transaction binding the contract method 0x137c29fe. +// +// Solidity: function permitWitnessTransferFrom(((address,uint256),uint256,uint256) permit, (address,uint256) transferDetails, address owner, bytes32 witness, string witnessTypeString, bytes signature) returns() +func (_Permit2 *Permit2Session) PermitWitnessTransferFrom(permit ISignatureTransferPermitTransferFrom, transferDetails ISignatureTransferSignatureTransferDetails, owner common.Address, witness [32]byte, witnessTypeString string, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.PermitWitnessTransferFrom(&_Permit2.TransactOpts, permit, transferDetails, owner, witness, witnessTypeString, signature) +} + +// PermitWitnessTransferFrom is a paid mutator transaction binding the contract method 0x137c29fe. +// +// Solidity: function permitWitnessTransferFrom(((address,uint256),uint256,uint256) permit, (address,uint256) transferDetails, address owner, bytes32 witness, string witnessTypeString, bytes signature) returns() +func (_Permit2 *Permit2TransactorSession) PermitWitnessTransferFrom(permit ISignatureTransferPermitTransferFrom, transferDetails ISignatureTransferSignatureTransferDetails, owner common.Address, witness [32]byte, witnessTypeString string, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.PermitWitnessTransferFrom(&_Permit2.TransactOpts, permit, transferDetails, owner, witness, witnessTypeString, signature) +} + +// PermitWitnessTransferFrom0 is a paid mutator transaction binding the contract method 0xfe8ec1a7. +// +// Solidity: function permitWitnessTransferFrom(((address,uint256)[],uint256,uint256) permit, (address,uint256)[] transferDetails, address owner, bytes32 witness, string witnessTypeString, bytes signature) returns() +func (_Permit2 *Permit2Transactor) PermitWitnessTransferFrom0(opts *bind.TransactOpts, permit ISignatureTransferPermitBatchTransferFrom, transferDetails []ISignatureTransferSignatureTransferDetails, owner common.Address, witness [32]byte, witnessTypeString string, signature []byte) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "permitWitnessTransferFrom0", permit, transferDetails, owner, witness, witnessTypeString, signature) +} + +// PermitWitnessTransferFrom0 is a paid mutator transaction binding the contract method 0xfe8ec1a7. +// +// Solidity: function permitWitnessTransferFrom(((address,uint256)[],uint256,uint256) permit, (address,uint256)[] transferDetails, address owner, bytes32 witness, string witnessTypeString, bytes signature) returns() +func (_Permit2 *Permit2Session) PermitWitnessTransferFrom0(permit ISignatureTransferPermitBatchTransferFrom, transferDetails []ISignatureTransferSignatureTransferDetails, owner common.Address, witness [32]byte, witnessTypeString string, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.PermitWitnessTransferFrom0(&_Permit2.TransactOpts, permit, transferDetails, owner, witness, witnessTypeString, signature) +} + +// PermitWitnessTransferFrom0 is a paid mutator transaction binding the contract method 0xfe8ec1a7. +// +// Solidity: function permitWitnessTransferFrom(((address,uint256)[],uint256,uint256) permit, (address,uint256)[] transferDetails, address owner, bytes32 witness, string witnessTypeString, bytes signature) returns() +func (_Permit2 *Permit2TransactorSession) PermitWitnessTransferFrom0(permit ISignatureTransferPermitBatchTransferFrom, transferDetails []ISignatureTransferSignatureTransferDetails, owner common.Address, witness [32]byte, witnessTypeString string, signature []byte) (*types.Transaction, error) { + return _Permit2.Contract.PermitWitnessTransferFrom0(&_Permit2.TransactOpts, permit, transferDetails, owner, witness, witnessTypeString, signature) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x0d58b1db. +// +// Solidity: function transferFrom((address,address,uint160,address)[] transferDetails) returns() +func (_Permit2 *Permit2Transactor) TransferFrom(opts *bind.TransactOpts, transferDetails []IAllowanceTransferAllowanceTransferDetails) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "transferFrom", transferDetails) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x0d58b1db. +// +// Solidity: function transferFrom((address,address,uint160,address)[] transferDetails) returns() +func (_Permit2 *Permit2Session) TransferFrom(transferDetails []IAllowanceTransferAllowanceTransferDetails) (*types.Transaction, error) { + return _Permit2.Contract.TransferFrom(&_Permit2.TransactOpts, transferDetails) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x0d58b1db. +// +// Solidity: function transferFrom((address,address,uint160,address)[] transferDetails) returns() +func (_Permit2 *Permit2TransactorSession) TransferFrom(transferDetails []IAllowanceTransferAllowanceTransferDetails) (*types.Transaction, error) { + return _Permit2.Contract.TransferFrom(&_Permit2.TransactOpts, transferDetails) +} + +// TransferFrom0 is a paid mutator transaction binding the contract method 0x36c78516. +// +// Solidity: function transferFrom(address from, address to, uint160 amount, address token) returns() +func (_Permit2 *Permit2Transactor) TransferFrom0(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int, token common.Address) (*types.Transaction, error) { + return _Permit2.contract.Transact(opts, "transferFrom0", from, to, amount, token) +} + +// TransferFrom0 is a paid mutator transaction binding the contract method 0x36c78516. +// +// Solidity: function transferFrom(address from, address to, uint160 amount, address token) returns() +func (_Permit2 *Permit2Session) TransferFrom0(from common.Address, to common.Address, amount *big.Int, token common.Address) (*types.Transaction, error) { + return _Permit2.Contract.TransferFrom0(&_Permit2.TransactOpts, from, to, amount, token) +} + +// TransferFrom0 is a paid mutator transaction binding the contract method 0x36c78516. +// +// Solidity: function transferFrom(address from, address to, uint160 amount, address token) returns() +func (_Permit2 *Permit2TransactorSession) TransferFrom0(from common.Address, to common.Address, amount *big.Int, token common.Address) (*types.Transaction, error) { + return _Permit2.Contract.TransferFrom0(&_Permit2.TransactOpts, from, to, amount, token) +} + +// Permit2ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the Permit2 contract. +type Permit2ApprovalIterator struct { + Event *Permit2Approval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *Permit2ApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(Permit2Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(Permit2Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *Permit2ApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *Permit2ApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// Permit2Approval represents a Approval event raised by the Permit2 contract. +type Permit2Approval struct { + Owner common.Address + Token common.Address + Spender common.Address + Amount *big.Int + Expiration *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0xda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b. +// +// Solidity: event Approval(address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration) +func (_Permit2 *Permit2Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, token []common.Address, spender []common.Address) (*Permit2ApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _Permit2.contract.FilterLogs(opts, "Approval", ownerRule, tokenRule, spenderRule) + if err != nil { + return nil, err + } + return &Permit2ApprovalIterator{contract: _Permit2.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0xda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b. +// +// Solidity: event Approval(address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration) +func (_Permit2 *Permit2Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *Permit2Approval, owner []common.Address, token []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _Permit2.contract.WatchLogs(opts, "Approval", ownerRule, tokenRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(Permit2Approval) + if err := _Permit2.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0xda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b. +// +// Solidity: event Approval(address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration) +func (_Permit2 *Permit2Filterer) ParseApproval(log types.Log) (*Permit2Approval, error) { + event := new(Permit2Approval) + if err := _Permit2.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// Permit2LockdownIterator is returned from FilterLockdown and is used to iterate over the raw logs and unpacked data for Lockdown events raised by the Permit2 contract. +type Permit2LockdownIterator struct { + Event *Permit2Lockdown // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *Permit2LockdownIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(Permit2Lockdown) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(Permit2Lockdown) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *Permit2LockdownIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *Permit2LockdownIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// Permit2Lockdown represents a Lockdown event raised by the Permit2 contract. +type Permit2Lockdown struct { + Owner common.Address + Token common.Address + Spender common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterLockdown is a free log retrieval operation binding the contract event 0x89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4. +// +// Solidity: event Lockdown(address indexed owner, address token, address spender) +func (_Permit2 *Permit2Filterer) FilterLockdown(opts *bind.FilterOpts, owner []common.Address) (*Permit2LockdownIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _Permit2.contract.FilterLogs(opts, "Lockdown", ownerRule) + if err != nil { + return nil, err + } + return &Permit2LockdownIterator{contract: _Permit2.contract, event: "Lockdown", logs: logs, sub: sub}, nil +} + +// WatchLockdown is a free log subscription operation binding the contract event 0x89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4. +// +// Solidity: event Lockdown(address indexed owner, address token, address spender) +func (_Permit2 *Permit2Filterer) WatchLockdown(opts *bind.WatchOpts, sink chan<- *Permit2Lockdown, owner []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _Permit2.contract.WatchLogs(opts, "Lockdown", ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(Permit2Lockdown) + if err := _Permit2.contract.UnpackLog(event, "Lockdown", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseLockdown is a log parse operation binding the contract event 0x89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4. +// +// Solidity: event Lockdown(address indexed owner, address token, address spender) +func (_Permit2 *Permit2Filterer) ParseLockdown(log types.Log) (*Permit2Lockdown, error) { + event := new(Permit2Lockdown) + if err := _Permit2.contract.UnpackLog(event, "Lockdown", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// Permit2NonceInvalidationIterator is returned from FilterNonceInvalidation and is used to iterate over the raw logs and unpacked data for NonceInvalidation events raised by the Permit2 contract. +type Permit2NonceInvalidationIterator struct { + Event *Permit2NonceInvalidation // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *Permit2NonceInvalidationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(Permit2NonceInvalidation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(Permit2NonceInvalidation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *Permit2NonceInvalidationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *Permit2NonceInvalidationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// Permit2NonceInvalidation represents a NonceInvalidation event raised by the Permit2 contract. +type Permit2NonceInvalidation struct { + Owner common.Address + Token common.Address + Spender common.Address + NewNonce *big.Int + OldNonce *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNonceInvalidation is a free log retrieval operation binding the contract event 0x55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f3. +// +// Solidity: event NonceInvalidation(address indexed owner, address indexed token, address indexed spender, uint48 newNonce, uint48 oldNonce) +func (_Permit2 *Permit2Filterer) FilterNonceInvalidation(opts *bind.FilterOpts, owner []common.Address, token []common.Address, spender []common.Address) (*Permit2NonceInvalidationIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _Permit2.contract.FilterLogs(opts, "NonceInvalidation", ownerRule, tokenRule, spenderRule) + if err != nil { + return nil, err + } + return &Permit2NonceInvalidationIterator{contract: _Permit2.contract, event: "NonceInvalidation", logs: logs, sub: sub}, nil +} + +// WatchNonceInvalidation is a free log subscription operation binding the contract event 0x55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f3. +// +// Solidity: event NonceInvalidation(address indexed owner, address indexed token, address indexed spender, uint48 newNonce, uint48 oldNonce) +func (_Permit2 *Permit2Filterer) WatchNonceInvalidation(opts *bind.WatchOpts, sink chan<- *Permit2NonceInvalidation, owner []common.Address, token []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _Permit2.contract.WatchLogs(opts, "NonceInvalidation", ownerRule, tokenRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(Permit2NonceInvalidation) + if err := _Permit2.contract.UnpackLog(event, "NonceInvalidation", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNonceInvalidation is a log parse operation binding the contract event 0x55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f3. +// +// Solidity: event NonceInvalidation(address indexed owner, address indexed token, address indexed spender, uint48 newNonce, uint48 oldNonce) +func (_Permit2 *Permit2Filterer) ParseNonceInvalidation(log types.Log) (*Permit2NonceInvalidation, error) { + event := new(Permit2NonceInvalidation) + if err := _Permit2.contract.UnpackLog(event, "NonceInvalidation", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// Permit2PermitIterator is returned from FilterPermit and is used to iterate over the raw logs and unpacked data for Permit events raised by the Permit2 contract. +type Permit2PermitIterator struct { + Event *Permit2Permit // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *Permit2PermitIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(Permit2Permit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(Permit2Permit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *Permit2PermitIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *Permit2PermitIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// Permit2Permit represents a Permit event raised by the Permit2 contract. +type Permit2Permit struct { + Owner common.Address + Token common.Address + Spender common.Address + Amount *big.Int + Expiration *big.Int + Nonce *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPermit is a free log retrieval operation binding the contract event 0xc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec. +// +// Solidity: event Permit(address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration, uint48 nonce) +func (_Permit2 *Permit2Filterer) FilterPermit(opts *bind.FilterOpts, owner []common.Address, token []common.Address, spender []common.Address) (*Permit2PermitIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _Permit2.contract.FilterLogs(opts, "Permit", ownerRule, tokenRule, spenderRule) + if err != nil { + return nil, err + } + return &Permit2PermitIterator{contract: _Permit2.contract, event: "Permit", logs: logs, sub: sub}, nil +} + +// WatchPermit is a free log subscription operation binding the contract event 0xc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec. +// +// Solidity: event Permit(address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration, uint48 nonce) +func (_Permit2 *Permit2Filterer) WatchPermit(opts *bind.WatchOpts, sink chan<- *Permit2Permit, owner []common.Address, token []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _Permit2.contract.WatchLogs(opts, "Permit", ownerRule, tokenRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(Permit2Permit) + if err := _Permit2.contract.UnpackLog(event, "Permit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParsePermit is a log parse operation binding the contract event 0xc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec. +// +// Solidity: event Permit(address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration, uint48 nonce) +func (_Permit2 *Permit2Filterer) ParsePermit(log types.Log) (*Permit2Permit, error) { + event := new(Permit2Permit) + if err := _Permit2.contract.UnpackLog(event, "Permit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// Permit2UnorderedNonceInvalidationIterator is returned from FilterUnorderedNonceInvalidation and is used to iterate over the raw logs and unpacked data for UnorderedNonceInvalidation events raised by the Permit2 contract. +type Permit2UnorderedNonceInvalidationIterator struct { + Event *Permit2UnorderedNonceInvalidation // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *Permit2UnorderedNonceInvalidationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(Permit2UnorderedNonceInvalidation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(Permit2UnorderedNonceInvalidation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *Permit2UnorderedNonceInvalidationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *Permit2UnorderedNonceInvalidationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// Permit2UnorderedNonceInvalidation represents a UnorderedNonceInvalidation event raised by the Permit2 contract. +type Permit2UnorderedNonceInvalidation struct { + Owner common.Address + Word *big.Int + Mask *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnorderedNonceInvalidation is a free log retrieval operation binding the contract event 0x3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d. +// +// Solidity: event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask) +func (_Permit2 *Permit2Filterer) FilterUnorderedNonceInvalidation(opts *bind.FilterOpts, owner []common.Address) (*Permit2UnorderedNonceInvalidationIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _Permit2.contract.FilterLogs(opts, "UnorderedNonceInvalidation", ownerRule) + if err != nil { + return nil, err + } + return &Permit2UnorderedNonceInvalidationIterator{contract: _Permit2.contract, event: "UnorderedNonceInvalidation", logs: logs, sub: sub}, nil +} + +// WatchUnorderedNonceInvalidation is a free log subscription operation binding the contract event 0x3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d. +// +// Solidity: event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask) +func (_Permit2 *Permit2Filterer) WatchUnorderedNonceInvalidation(opts *bind.WatchOpts, sink chan<- *Permit2UnorderedNonceInvalidation, owner []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _Permit2.contract.WatchLogs(opts, "UnorderedNonceInvalidation", ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(Permit2UnorderedNonceInvalidation) + if err := _Permit2.contract.UnpackLog(event, "UnorderedNonceInvalidation", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUnorderedNonceInvalidation is a log parse operation binding the contract event 0x3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d. +// +// Solidity: event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask) +func (_Permit2 *Permit2Filterer) ParseUnorderedNonceInvalidation(log types.Log) (*Permit2UnorderedNonceInvalidation, error) { + event := new(Permit2UnorderedNonceInvalidation) + if err := _Permit2.contract.UnpackLog(event, "UnorderedNonceInvalidation", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-bindings/bindings/permit2_more.go b/op-bindings/bindings/permit2_more.go new file mode 100644 index 000000000000..844bac8f9fae --- /dev/null +++ b/op-bindings/bindings/permit2_more.go @@ -0,0 +1,14 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var Permit2InitBin = "60c0346100bb574660a052602081017f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a60408301524660608301523060808301526080825260a082019180831060018060401b038411176100a557826040525190206080526123c090816100c1823960805181611b47015260a05181611b210152f35b634e487b7160e01b600052604160045260246000fd5b600080fdfe6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000003611b69577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a" +var Permit2DeploymentSalt = "0000000000000000000000000000000000000000d3af2663da51c10215000000" +var Permit2Deployer = "0x4e59b44847b379578588920cA78FbF26c0B4956C" + +func init() { + initBytecodes["Permit2"] = Permit2InitBin + deploymentSalts["Permit2"] = Permit2DeploymentSalt + deployers["Permit2"] = Permit2Deployer +} diff --git a/op-bindings/bindings/preimageoracle.go b/op-bindings/bindings/preimageoracle.go index 1a2e196af20d..32744870529f 100644 --- a/op-bindings/bindings/preimageoracle.go +++ b/op-bindings/bindings/preimageoracle.go @@ -28,10 +28,22 @@ var ( _ = event.NewSubscription ) +// LibKeccakStateMatrix is an auto generated low-level Go binding around an user-defined struct. +type LibKeccakStateMatrix struct { + State [25]uint64 +} + +// PreimageOracleLeaf is an auto generated low-level Go binding around an user-defined struct. +type PreimageOracleLeaf struct { + Input []byte + Index *big.Int + StateCommitment [32]byte +} + // PreimageOracleMetaData contains all meta data concerning the PreimageOracle contract. var PreimageOracleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"PartOffsetOOB\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_partOffset\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_preimage\",\"type\":\"bytes\"}],\"name\":\"loadKeccak256PreimagePart\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_ident\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_localContext\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_word\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_size\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_partOffset\",\"type\":\"uint256\"}],\"name\":\"loadLocalData\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"key_\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"preimageLengths\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"preimagePartOk\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"preimageParts\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"}],\"name\":\"readPreimage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"dat_\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"datLen_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061063c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_minProposalSize\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_challengePeriod\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"KECCAK_TREE_DEPTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAX_LEAF_COUNT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MIN_BOND_SIZE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addLeavesLPP\",\"inputs\":[{\"name\":\"_uuid\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_inputStartBlock\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_input\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_stateCommitments\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"},{\"name\":\"_finalize\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"challengeFirstLPP\",\"inputs\":[{\"name\":\"_claimant\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_uuid\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_postState\",\"type\":\"tuple\",\"internalType\":\"structPreimageOracle.Leaf\",\"components\":[{\"name\":\"input\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"stateCommitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_postStateProof\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"challengeLPP\",\"inputs\":[{\"name\":\"_claimant\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_uuid\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_stateMatrix\",\"type\":\"tuple\",\"internalType\":\"structLibKeccak.StateMatrix\",\"components\":[{\"name\":\"state\",\"type\":\"uint64[25]\",\"internalType\":\"uint64[25]\"}]},{\"name\":\"_preState\",\"type\":\"tuple\",\"internalType\":\"structPreimageOracle.Leaf\",\"components\":[{\"name\":\"input\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"stateCommitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_preStateProof\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"},{\"name\":\"_postState\",\"type\":\"tuple\",\"internalType\":\"structPreimageOracle.Leaf\",\"components\":[{\"name\":\"input\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"stateCommitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_postStateProof\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"challengePeriod\",\"inputs\":[],\"outputs\":[{\"name\":\"challengePeriod_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTreeRootLPP\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_uuid\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"treeRoot_\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initLPP\",\"inputs\":[{\"name\":\"_uuid\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_partOffset\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_claimedSize\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"loadBlobPreimagePart\",\"inputs\":[{\"name\":\"_z\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_y\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_commitment\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"loadKeccak256PreimagePart\",\"inputs\":[{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_preimage\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"loadLocalData\",\"inputs\":[{\"name\":\"_ident\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_localContext\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_word\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_size\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"key_\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"loadPrecompilePreimagePart\",\"inputs\":[{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_precompile\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_input\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"loadSha256PreimagePart\",\"inputs\":[{\"name\":\"_partOffset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_preimage\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"minProposalSize\",\"inputs\":[],\"outputs\":[{\"name\":\"minProposalSize_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preimageLengths\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preimagePartOk\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preimageParts\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposalBlocks\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposalBlocksLen\",\"inputs\":[{\"name\":\"_claimant\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_uuid\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"len_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposalBonds\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposalBranches\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposalCount\",\"inputs\":[],\"outputs\":[{\"name\":\"count_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposalMetadata\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"LPPMetaData\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposalParts\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposals\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"claimant\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"uuid\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"readPreimage\",\"inputs\":[{\"name\":\"_key\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"dat_\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"datLen_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"squeezeLPP\",\"inputs\":[{\"name\":\"_claimant\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_uuid\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_stateMatrix\",\"type\":\"tuple\",\"internalType\":\"structLibKeccak.StateMatrix\",\"components\":[{\"name\":\"state\",\"type\":\"uint64[25]\",\"internalType\":\"uint64[25]\"}]},{\"name\":\"_preState\",\"type\":\"tuple\",\"internalType\":\"structPreimageOracle.Leaf\",\"components\":[{\"name\":\"input\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"stateCommitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_preStateProof\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"},{\"name\":\"_postState\",\"type\":\"tuple\",\"internalType\":\"structPreimageOracle.Leaf\",\"components\":[{\"name\":\"input\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"stateCommitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_postStateProof\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"zeroHashes\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"error\",\"name\":\"ActiveProposal\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AlreadyFinalized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"BadProposal\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"BondTransferFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InsufficientBond\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInputSize\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidPreimage\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidProof\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotEOA\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitialized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"PartOffsetOOB\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"PostStateMatches\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"StatesNotContiguous\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"TreeSizeOverflow\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"WrongStartingBlock\",\"inputs\":[]}]", + Bin: "0x60c06040523480156200001157600080fd5b50604051620039e6380380620039e68339810160408190526200003491620000f3565b60a0829052608081905260005b6200004f600160106200012e565b811015620000ea57600381601081106200006d576200006d62000148565b01546003826010811062000085576200008562000148565b0154604080516020810193909352820152606001604051602081830303815290604052805190602001206003826001620000c091906200015e565b60108110620000d357620000d362000148565b015580620000e18162000179565b91505062000041565b50505062000195565b600080604083850312156200010757600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b60008282101562000143576200014362000118565b500390565b634e487b7160e01b600052603260045260246000fd5b6000821982111562000174576200017462000118565b500190565b6000600182016200018e576200018e62000118565b5060010190565b60805160a05161381d620001c9600039600081816105ae0152611d3e01526000818161068e01526115a6015261381d6000f3fe6080604052600436106101cd5760003560e01c80638dc4be11116100f7578063dd24f9bf11610095578063ec5efcbc11610064578063ec5efcbc1461065f578063f3f480d91461067f578063faf37bc7146106b2578063fef2b4ed146106c557600080fd5b8063dd24f9bf1461059f578063ddcd58de146105d2578063e03110e11461060a578063e15926111461063f57600080fd5b8063b2e67ba8116100d1578063b2e67ba814610512578063b4801e611461054a578063d18534b51461056a578063da35c6641461058a57600080fd5b80638dc4be11146104835780639d53a648146104a35780639d7e8769146104f257600080fd5b806354fd4d501161016f5780637917de1d1161013e5780637917de1d146103bf5780637ac54767146103df5780638542cf50146103ff578063882856ef1461044a57600080fd5b806354fd4d50146102dd57806361238bde146103335780636551927b1461036b5780637051472e146103a357600080fd5b80632055b36b116101ab5780632055b36b146102735780633909af5c146102885780634d52b4c9146102a857806352f0f3ad146102bd57600080fd5b8063013cf08b146101d25780630359a5631461022357806304697c7814610251575b600080fd5b3480156101de57600080fd5b506101f26101ed366004612d1c565b6106f2565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561022f57600080fd5b5061024361023e366004612d5e565b610737565b60405190815260200161021a565b34801561025d57600080fd5b5061027161026c366004612dd1565b61086f565b005b34801561027f57600080fd5b50610243601081565b34801561029457600080fd5b506102716102a3366004612ff5565b6109a5565b3480156102b457600080fd5b50610243610bfc565b3480156102c957600080fd5b506102436102d83660046130e1565b610c17565b3480156102e957600080fd5b506103266040518060400160405280600581526020017f302e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161021a9190613148565b34801561033f57600080fd5b5061024361034e366004613199565b600160209081526000928352604080842090915290825290205481565b34801561037757600080fd5b50610243610386366004612d5e565b601560209081526000928352604080842090915290825290205481565b3480156103af57600080fd5b506102436703782dace9d9000081565b3480156103cb57600080fd5b506102716103da3660046131bb565b610cec565b3480156103eb57600080fd5b506102436103fa366004612d1c565b6111dc565b34801561040b57600080fd5b5061043a61041a366004613199565b600260209081526000928352604080842090915290825290205460ff1681565b604051901515815260200161021a565b34801561045657600080fd5b5061046a610465366004613257565b6111f3565b60405167ffffffffffffffff909116815260200161021a565b34801561048f57600080fd5b5061027161049e36600461328a565b61124d565b3480156104af57600080fd5b506102436104be366004612d5e565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104fe57600080fd5b5061027161050d3660046132d6565b611348565b34801561051e57600080fd5b5061024361052d366004612d5e565b601760209081526000928352604080842090915290825290205481565b34801561055657600080fd5b50610243610565366004613257565b6114ff565b34801561057657600080fd5b50610271610585366004612ff5565b611531565b34801561059657600080fd5b50601354610243565b3480156105ab57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610243565b3480156105de57600080fd5b506102436105ed366004612d5e565b601660209081526000928352604080842090915290825290205481565b34801561061657600080fd5b5061062a610625366004613199565b6118f3565b6040805192835260208301919091520161021a565b34801561064b57600080fd5b5061027161065a36600461328a565b6119e4565b34801561066b57600080fd5b5061027161067a366004613362565b611aec565b34801561068b57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610243565b6102716106c03660046133fb565b611c72565b3480156106d157600080fd5b506102436106e0366004612d1c565b60006020819052908152604090205481565b6013818154811061070257600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061077a9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610867578160011660010361080d5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107da576107da613437565b0154604080516020810192909252810184905260600160405160208183030381529060405280519060200120925061084e565b826003826010811061082157610821613437565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c908061085f81613495565b915050610785565b505092915050565b600080600080608060146030823785878260140137601480870182207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06000000000000000000000000000000000000000000000000000000000000001794506000908190889084018b5afa94503d60010191506008820189106108fc5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e88017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208c8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209b83529a81528a82209290925593845283905296909120959095555050505050565b60006109b18a8a610737565b90506109d486868360208b01356109cf6109ca8d6134cd565b611edd565b611f1d565b80156109f257506109f283838360208801356109cf6109ca8a6134cd565b610a28576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b866040013588604051602001610a3e919061359c565b6040516020818303038152906040528051906020012014610a8b576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836020013587602001356001610aa191906135da565b14610ad8576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b2088610ae686806135f2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f7e92505050565b610b29886120d9565b836040013588604051602001610b3f919061359c565b6040516020818303038152906040528051906020012003610b8c576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610bf08a8a33612881565b50505050505050505050565b6001610c0a60106002613779565b610c149190613785565b81565b6000610c23868661293a565b9050610c308360086135da565b821180610c3d5750602083115b15610c74576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610d0557610cfe86866129e7565b9050610d3f565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610d6c57505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610ded8260601c63ffffffff1690565b63ffffffff169050333214610e2e576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3e8260801c63ffffffff1690565b63ffffffff16600003610e7d576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e878260c01c90565b67ffffffffffffffff1615610ec8576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610f01576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f0e89898d8886612a60565b83516020850160888204881415608883061715610f33576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610fe3578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610fd8576001821615610fb85782818b0152610fd8565b8981015160009081526020938452604090209260019290921c9101610f9b565b505050608801610f40565b50505050600160106002610ff79190613779565b6110019190613785565b81111561103a576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110af61104d8360401c63ffffffff1690565b61105d9063ffffffff168a6135da565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b9150841561113c5777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b1791506110e98260801c63ffffffff1690565b63ffffffff166110ff8360401c63ffffffff1690565b63ffffffff161461113c576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061116290846010612c92565b50503360008181526018602090815260408083208e8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055928252601581528282209c82529b909b52909920989098555050505050505050565b600381601081106111ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061121b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061126b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061129857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806113705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826113f2576309bde3396000526004601cfd5b602886106114085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061152757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156115a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006115cf8260c01c90565b6115e39067ffffffffffffffff1642613785565b1161161a576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006116268b8b610737565b905061163f87878360208c01356109cf6109ca8e6134cd565b801561165d575061165d84848360208901356109cf6109ca8b6134cd565b611693576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016116a9919061359c565b60405160208183030381529060405280519060200120146116f6576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161170c91906135da565b14158061173e575060016117268360601c63ffffffff1690565b611730919061379c565b63ffffffff16856020013514155b15611775576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61178389610ae687806135f2565b61178c896120d9565b60006117978a612bb3565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f020000000000000000000000000000000000000000000000000000000000000017905060006117ee8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d815260200190815260200160002054600160008481526020019081526020016000206000838152602001908152602001600020819055506118c08460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118e48d8d81612881565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff1661197c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546119988160086135da565b6119a38560206135da565b106119c157836119b48260086135da565b6119be9190613785565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018610611a025763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b6000611af88686610737565b9050611b1183838360208801356109cf6109ca8a6134cd565b611b47576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611b83576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b8b612cd0565b611b9981610ae687806135f2565b611ba2816120d9565b846040013581604051602001611bb8919061359c565b6040516020818303038152906040528051906020012003611c05576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611c69878733612881565b50505050505050565b6703782dace9d90000341015611cb4576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611ced576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cf88160086137c1565b63ffffffff168263ffffffff1610611d3c576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008163ffffffff161015611d9c576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000818152601560209081526040808320878452825280832080547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1660a09790971b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff169690961760809590951b949094179094558251808401845282815280850186815260138054600181018255908452915160029092027f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0908101805473ffffffffffffffffffffffffffffffffffffffff9094167fffffffffffffffffffffffff000000000000000000000000000000000000000090941693909317909255517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015590815260168352818120938152929091529020349055565b6000816000015182602001518360400151604051602001611f00939291906137e9565b604051602081830303815290604052805190602001209050919050565b60008160005b6010811015611f71578060051b880135600186831c1660018114611f565760008481526020839052604090209350611f67565b600082815260208590526040902093505b5050600101611f23565b5090931495945050505050565b6088815114611f8c57600080fd5b602081016020830161200d565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b171717905061200781611ff2868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b61201960008383611f99565b61202560018383611f99565b61203160028383611f99565b61203d60038383611f99565b61204960048383611f99565b61205560058383611f99565b61206160068383611f99565b61206d60078383611f99565b61207960088383611f99565b61208560098383611f99565b612091600a8383611f99565b61209d600b8383611f99565b6120a9600c8383611f99565b6120b5600d8383611f99565b6120c1600e8383611f99565b6120cd600f8383611f99565b61200760108383611f99565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e00160405160208183030381529060405290506020820160208201612761565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c61228c8660011b67ffffffffffffffff1690565b18188584603f1c6122a78660011b67ffffffffffffffff1690565b18188584603f1c6122c28660011b67ffffffffffffffff1690565b181895508483603f1c6122df8560011b67ffffffffffffffff1690565b181894508387603f1c6122fc8960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611c69565b6126fb600082612674565b612706600582612674565b612711600a82612674565b61271c600f82612674565b612727601482612674565b50565b612733816121cf565b61273c816126f0565b600383901b820151815160c09190911c9061200790821867ffffffffffffffff168352565b61276d6000828461272a565b6127796001828461272a565b6127856002828461272a565b6127916003828461272a565b61279d6004828461272a565b6127a96005828461272a565b6127b56006828461272a565b6127c16007828461272a565b6127cd6008828461272a565b6127d96009828461272a565b6127e5600a828461272a565b6127f1600b828461272a565b6127fd600c828461272a565b612809600d828461272a565b612815600e828461272a565b612821600f828461272a565b61282d6010828461272a565b6128396011828461272a565b6128456012828461272a565b6128516013828461272a565b61285d6014828461272a565b6128696015828461272a565b6128756016828461272a565b6120076017828461272a565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d80600081146128fa576040519150601f19603f3d011682016040523d82523d6000602084013e6128ff565b606091505b505090508061266d576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176129e0818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612a305760888290038501848101848103803687375060806001820353506001845160001a1784538652612a47565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612a728260a01c63ffffffff1690565b67ffffffffffffffff1690506000612a908360801c63ffffffff1690565b63ffffffff1690506000612aaa8460401c63ffffffff1690565b63ffffffff169050600883108015612ac0575080155b15612af45760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612ba9565b60088310158015612b12575080612b0c600885613785565b93508310155b8015612b265750612b2387826135da565b83105b15612ba9576000612b378285613785565b905087612b458260206135da565b10158015612b51575085155b15612b88576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612c36565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612be48360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612c118360101b67ffffffffffffffff1690565b1617905060008160201c612c2f8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612c4e90612bba565b612bba565b6040820151612c5c90612bba565b60401b17612c74612c4960018460059190911b015190565b825160809190911b90612c8690612bba565b60c01b17179392505050565b8260108101928215612cc0579160200282015b82811115612cc0578251825591602001919060010190612ca5565b50612ccc929150612ce8565b5090565b6040518060200160405280612ce3612cfd565b905290565b5b80821115612ccc5760008155600101612ce9565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612d2e57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612d5957600080fd5b919050565b60008060408385031215612d7157600080fd5b612d7a83612d35565b946020939093013593505050565b60008083601f840112612d9a57600080fd5b50813567ffffffffffffffff811115612db257600080fd5b602083019150836020828501011115612dca57600080fd5b9250929050565b60008060008060608587031215612de757600080fd5b84359350612df760208601612d35565b9250604085013567ffffffffffffffff811115612e1357600080fd5b612e1f87828801612d88565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612e7e57612e7e612e2b565b60405290565b6040516060810167ffffffffffffffff81118282101715612e7e57612e7e612e2b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612eee57612eee612e2b565b604052919050565b6000610320808385031215612f0a57600080fd5b604051602080820167ffffffffffffffff8382108183111715612f2f57612f2f612e2b565b8160405283955087601f880112612f4557600080fd5b612f4d612e5a565b9487019491508188861115612f6157600080fd5b875b86811015612f895780358381168114612f7c5760008081fd5b8452928401928401612f63565b50909352509295945050505050565b600060608284031215612faa57600080fd5b50919050565b60008083601f840112612fc257600080fd5b50813567ffffffffffffffff811115612fda57600080fd5b6020830191508360208260051b8501011115612dca57600080fd5b60008060008060008060008060006103e08a8c03121561301457600080fd5b61301d8a612d35565b985060208a013597506130338b60408c01612ef6565b96506103608a013567ffffffffffffffff8082111561305157600080fd5b61305d8d838e01612f98565b97506103808c013591508082111561307457600080fd5b6130808d838e01612fb0565b90975095506103a08c013591508082111561309a57600080fd5b6130a68d838e01612f98565b94506103c08c01359150808211156130bd57600080fd5b506130ca8c828d01612fb0565b915080935050809150509295985092959850929598565b600080600080600060a086880312156130f957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b8381101561313757818101518382015260200161311f565b838111156120075750506000910152565b602081526000825180602084015261316781604085016020870161311c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600080604083850312156131ac57600080fd5b50508035926020909101359150565b600080600080600080600060a0888a0312156131d657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156131fc57600080fd5b6132088b838c01612d88565b909750955060608a013591508082111561322157600080fd5b5061322e8a828b01612fb0565b9094509250506080880135801515811461324757600080fd5b8091505092959891949750929550565b60008060006060848603121561326c57600080fd5b61327584612d35565b95602085013595506040909401359392505050565b60008060006040848603121561329f57600080fd5b83359250602084013567ffffffffffffffff8111156132bd57600080fd5b6132c986828701612d88565b9497909650939450505050565b600080600080600080600060a0888a0312156132f157600080fd5b8735965060208801359550604088013567ffffffffffffffff8082111561331757600080fd5b6133238b838c01612d88565b909750955060608a013591508082111561333c57600080fd5b506133498a828b01612d88565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561337a57600080fd5b61338386612d35565b945060208601359350604086013567ffffffffffffffff808211156133a757600080fd5b6133b389838a01612f98565b945060608801359150808211156133c957600080fd5b506133d688828901612fb0565b969995985093965092949392505050565b803563ffffffff81168114612d5957600080fd5b60008060006060848603121561341057600080fd5b83359250613420602085016133e7565b915061342e604085016133e7565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036134c6576134c6613466565b5060010190565b6000606082360312156134df57600080fd5b6134e7612e84565b823567ffffffffffffffff808211156134ff57600080fd5b9084019036601f83011261351257600080fd5b813560208282111561352657613526612e2b565b613556817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612ea7565b9250818352368183860101111561356c57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156135d157825167ffffffffffffffff168252602092830192909101906001016135a8565b50505092915050565b600082198211156135ed576135ed613466565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261362757600080fd5b83018035915067ffffffffffffffff82111561364257600080fd5b602001915036819003821315612dca57600080fd5b600181815b808511156136b057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561369657613696613466565b808516156136a357918102915b93841c939080029061365c565b509250929050565b6000826136c757506001613773565b816136d457506000613773565b81600181146136ea57600281146136f457613710565b6001915050613773565b60ff84111561370557613705613466565b50506001821b613773565b5060208310610133831016604e8410600b8410161715613733575081810a613773565b61373d8383613657565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561376f5761376f613466565b0290505b92915050565b60006129e083836136b8565b60008282101561379757613797613466565b500390565b600063ffffffff838116908316818110156137b9576137b9613466565b039392505050565b600063ffffffff8083168185168083038211156137e0576137e0613466565b01949350505050565b600084516137fb81846020890161311c565b9190910192835250602082015260400191905056fea164736f6c634300080f000a", } // PreimageOracleABI is the input ABI used to generate the binding from. @@ -43,7 +55,7 @@ var PreimageOracleABI = PreimageOracleMetaData.ABI var PreimageOracleBin = PreimageOracleMetaData.Bin // DeployPreimageOracle deploys a new Ethereum contract, binding an instance of PreimageOracle to it. -func DeployPreimageOracle(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *PreimageOracle, error) { +func DeployPreimageOracle(auth *bind.TransactOpts, backend bind.ContractBackend, _minProposalSize *big.Int, _challengePeriod *big.Int) (common.Address, *types.Transaction, *PreimageOracle, error) { parsed, err := PreimageOracleMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -52,7 +64,7 @@ func DeployPreimageOracle(auth *bind.TransactOpts, backend bind.ContractBackend) return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PreimageOracleBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PreimageOracleBin), backend, _minProposalSize, _challengePeriod) if err != nil { return common.Address{}, nil, nil, err } @@ -201,6 +213,192 @@ func (_PreimageOracle *PreimageOracleTransactorRaw) Transact(opts *bind.Transact return _PreimageOracle.Contract.contract.Transact(opts, method, params...) } +// KECCAKTREEDEPTH is a free data retrieval call binding the contract method 0x2055b36b. +// +// Solidity: function KECCAK_TREE_DEPTH() view returns(uint256) +func (_PreimageOracle *PreimageOracleCaller) KECCAKTREEDEPTH(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "KECCAK_TREE_DEPTH") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// KECCAKTREEDEPTH is a free data retrieval call binding the contract method 0x2055b36b. +// +// Solidity: function KECCAK_TREE_DEPTH() view returns(uint256) +func (_PreimageOracle *PreimageOracleSession) KECCAKTREEDEPTH() (*big.Int, error) { + return _PreimageOracle.Contract.KECCAKTREEDEPTH(&_PreimageOracle.CallOpts) +} + +// KECCAKTREEDEPTH is a free data retrieval call binding the contract method 0x2055b36b. +// +// Solidity: function KECCAK_TREE_DEPTH() view returns(uint256) +func (_PreimageOracle *PreimageOracleCallerSession) KECCAKTREEDEPTH() (*big.Int, error) { + return _PreimageOracle.Contract.KECCAKTREEDEPTH(&_PreimageOracle.CallOpts) +} + +// MAXLEAFCOUNT is a free data retrieval call binding the contract method 0x4d52b4c9. +// +// Solidity: function MAX_LEAF_COUNT() view returns(uint256) +func (_PreimageOracle *PreimageOracleCaller) MAXLEAFCOUNT(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "MAX_LEAF_COUNT") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MAXLEAFCOUNT is a free data retrieval call binding the contract method 0x4d52b4c9. +// +// Solidity: function MAX_LEAF_COUNT() view returns(uint256) +func (_PreimageOracle *PreimageOracleSession) MAXLEAFCOUNT() (*big.Int, error) { + return _PreimageOracle.Contract.MAXLEAFCOUNT(&_PreimageOracle.CallOpts) +} + +// MAXLEAFCOUNT is a free data retrieval call binding the contract method 0x4d52b4c9. +// +// Solidity: function MAX_LEAF_COUNT() view returns(uint256) +func (_PreimageOracle *PreimageOracleCallerSession) MAXLEAFCOUNT() (*big.Int, error) { + return _PreimageOracle.Contract.MAXLEAFCOUNT(&_PreimageOracle.CallOpts) +} + +// MINBONDSIZE is a free data retrieval call binding the contract method 0x7051472e. +// +// Solidity: function MIN_BOND_SIZE() view returns(uint256) +func (_PreimageOracle *PreimageOracleCaller) MINBONDSIZE(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "MIN_BOND_SIZE") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MINBONDSIZE is a free data retrieval call binding the contract method 0x7051472e. +// +// Solidity: function MIN_BOND_SIZE() view returns(uint256) +func (_PreimageOracle *PreimageOracleSession) MINBONDSIZE() (*big.Int, error) { + return _PreimageOracle.Contract.MINBONDSIZE(&_PreimageOracle.CallOpts) +} + +// MINBONDSIZE is a free data retrieval call binding the contract method 0x7051472e. +// +// Solidity: function MIN_BOND_SIZE() view returns(uint256) +func (_PreimageOracle *PreimageOracleCallerSession) MINBONDSIZE() (*big.Int, error) { + return _PreimageOracle.Contract.MINBONDSIZE(&_PreimageOracle.CallOpts) +} + +// ChallengePeriod is a free data retrieval call binding the contract method 0xf3f480d9. +// +// Solidity: function challengePeriod() view returns(uint256 challengePeriod_) +func (_PreimageOracle *PreimageOracleCaller) ChallengePeriod(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "challengePeriod") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ChallengePeriod is a free data retrieval call binding the contract method 0xf3f480d9. +// +// Solidity: function challengePeriod() view returns(uint256 challengePeriod_) +func (_PreimageOracle *PreimageOracleSession) ChallengePeriod() (*big.Int, error) { + return _PreimageOracle.Contract.ChallengePeriod(&_PreimageOracle.CallOpts) +} + +// ChallengePeriod is a free data retrieval call binding the contract method 0xf3f480d9. +// +// Solidity: function challengePeriod() view returns(uint256 challengePeriod_) +func (_PreimageOracle *PreimageOracleCallerSession) ChallengePeriod() (*big.Int, error) { + return _PreimageOracle.Contract.ChallengePeriod(&_PreimageOracle.CallOpts) +} + +// GetTreeRootLPP is a free data retrieval call binding the contract method 0x0359a563. +// +// Solidity: function getTreeRootLPP(address _owner, uint256 _uuid) view returns(bytes32 treeRoot_) +func (_PreimageOracle *PreimageOracleCaller) GetTreeRootLPP(opts *bind.CallOpts, _owner common.Address, _uuid *big.Int) ([32]byte, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "getTreeRootLPP", _owner, _uuid) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetTreeRootLPP is a free data retrieval call binding the contract method 0x0359a563. +// +// Solidity: function getTreeRootLPP(address _owner, uint256 _uuid) view returns(bytes32 treeRoot_) +func (_PreimageOracle *PreimageOracleSession) GetTreeRootLPP(_owner common.Address, _uuid *big.Int) ([32]byte, error) { + return _PreimageOracle.Contract.GetTreeRootLPP(&_PreimageOracle.CallOpts, _owner, _uuid) +} + +// GetTreeRootLPP is a free data retrieval call binding the contract method 0x0359a563. +// +// Solidity: function getTreeRootLPP(address _owner, uint256 _uuid) view returns(bytes32 treeRoot_) +func (_PreimageOracle *PreimageOracleCallerSession) GetTreeRootLPP(_owner common.Address, _uuid *big.Int) ([32]byte, error) { + return _PreimageOracle.Contract.GetTreeRootLPP(&_PreimageOracle.CallOpts, _owner, _uuid) +} + +// MinProposalSize is a free data retrieval call binding the contract method 0xdd24f9bf. +// +// Solidity: function minProposalSize() view returns(uint256 minProposalSize_) +func (_PreimageOracle *PreimageOracleCaller) MinProposalSize(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "minProposalSize") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MinProposalSize is a free data retrieval call binding the contract method 0xdd24f9bf. +// +// Solidity: function minProposalSize() view returns(uint256 minProposalSize_) +func (_PreimageOracle *PreimageOracleSession) MinProposalSize() (*big.Int, error) { + return _PreimageOracle.Contract.MinProposalSize(&_PreimageOracle.CallOpts) +} + +// MinProposalSize is a free data retrieval call binding the contract method 0xdd24f9bf. +// +// Solidity: function minProposalSize() view returns(uint256 minProposalSize_) +func (_PreimageOracle *PreimageOracleCallerSession) MinProposalSize() (*big.Int, error) { + return _PreimageOracle.Contract.MinProposalSize(&_PreimageOracle.CallOpts) +} + // PreimageLengths is a free data retrieval call binding the contract method 0xfef2b4ed. // // Solidity: function preimageLengths(bytes32 ) view returns(uint256) @@ -294,6 +492,268 @@ func (_PreimageOracle *PreimageOracleCallerSession) PreimageParts(arg0 [32]byte, return _PreimageOracle.Contract.PreimageParts(&_PreimageOracle.CallOpts, arg0, arg1) } +// ProposalBlocks is a free data retrieval call binding the contract method 0x882856ef. +// +// Solidity: function proposalBlocks(address , uint256 , uint256 ) view returns(uint64) +func (_PreimageOracle *PreimageOracleCaller) ProposalBlocks(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int, arg2 *big.Int) (uint64, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "proposalBlocks", arg0, arg1, arg2) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// ProposalBlocks is a free data retrieval call binding the contract method 0x882856ef. +// +// Solidity: function proposalBlocks(address , uint256 , uint256 ) view returns(uint64) +func (_PreimageOracle *PreimageOracleSession) ProposalBlocks(arg0 common.Address, arg1 *big.Int, arg2 *big.Int) (uint64, error) { + return _PreimageOracle.Contract.ProposalBlocks(&_PreimageOracle.CallOpts, arg0, arg1, arg2) +} + +// ProposalBlocks is a free data retrieval call binding the contract method 0x882856ef. +// +// Solidity: function proposalBlocks(address , uint256 , uint256 ) view returns(uint64) +func (_PreimageOracle *PreimageOracleCallerSession) ProposalBlocks(arg0 common.Address, arg1 *big.Int, arg2 *big.Int) (uint64, error) { + return _PreimageOracle.Contract.ProposalBlocks(&_PreimageOracle.CallOpts, arg0, arg1, arg2) +} + +// ProposalBlocksLen is a free data retrieval call binding the contract method 0x9d53a648. +// +// Solidity: function proposalBlocksLen(address _claimant, uint256 _uuid) view returns(uint256 len_) +func (_PreimageOracle *PreimageOracleCaller) ProposalBlocksLen(opts *bind.CallOpts, _claimant common.Address, _uuid *big.Int) (*big.Int, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "proposalBlocksLen", _claimant, _uuid) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ProposalBlocksLen is a free data retrieval call binding the contract method 0x9d53a648. +// +// Solidity: function proposalBlocksLen(address _claimant, uint256 _uuid) view returns(uint256 len_) +func (_PreimageOracle *PreimageOracleSession) ProposalBlocksLen(_claimant common.Address, _uuid *big.Int) (*big.Int, error) { + return _PreimageOracle.Contract.ProposalBlocksLen(&_PreimageOracle.CallOpts, _claimant, _uuid) +} + +// ProposalBlocksLen is a free data retrieval call binding the contract method 0x9d53a648. +// +// Solidity: function proposalBlocksLen(address _claimant, uint256 _uuid) view returns(uint256 len_) +func (_PreimageOracle *PreimageOracleCallerSession) ProposalBlocksLen(_claimant common.Address, _uuid *big.Int) (*big.Int, error) { + return _PreimageOracle.Contract.ProposalBlocksLen(&_PreimageOracle.CallOpts, _claimant, _uuid) +} + +// ProposalBonds is a free data retrieval call binding the contract method 0xddcd58de. +// +// Solidity: function proposalBonds(address , uint256 ) view returns(uint256) +func (_PreimageOracle *PreimageOracleCaller) ProposalBonds(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "proposalBonds", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ProposalBonds is a free data retrieval call binding the contract method 0xddcd58de. +// +// Solidity: function proposalBonds(address , uint256 ) view returns(uint256) +func (_PreimageOracle *PreimageOracleSession) ProposalBonds(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { + return _PreimageOracle.Contract.ProposalBonds(&_PreimageOracle.CallOpts, arg0, arg1) +} + +// ProposalBonds is a free data retrieval call binding the contract method 0xddcd58de. +// +// Solidity: function proposalBonds(address , uint256 ) view returns(uint256) +func (_PreimageOracle *PreimageOracleCallerSession) ProposalBonds(arg0 common.Address, arg1 *big.Int) (*big.Int, error) { + return _PreimageOracle.Contract.ProposalBonds(&_PreimageOracle.CallOpts, arg0, arg1) +} + +// ProposalBranches is a free data retrieval call binding the contract method 0xb4801e61. +// +// Solidity: function proposalBranches(address , uint256 , uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleCaller) ProposalBranches(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int, arg2 *big.Int) ([32]byte, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "proposalBranches", arg0, arg1, arg2) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProposalBranches is a free data retrieval call binding the contract method 0xb4801e61. +// +// Solidity: function proposalBranches(address , uint256 , uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleSession) ProposalBranches(arg0 common.Address, arg1 *big.Int, arg2 *big.Int) ([32]byte, error) { + return _PreimageOracle.Contract.ProposalBranches(&_PreimageOracle.CallOpts, arg0, arg1, arg2) +} + +// ProposalBranches is a free data retrieval call binding the contract method 0xb4801e61. +// +// Solidity: function proposalBranches(address , uint256 , uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleCallerSession) ProposalBranches(arg0 common.Address, arg1 *big.Int, arg2 *big.Int) ([32]byte, error) { + return _PreimageOracle.Contract.ProposalBranches(&_PreimageOracle.CallOpts, arg0, arg1, arg2) +} + +// ProposalCount is a free data retrieval call binding the contract method 0xda35c664. +// +// Solidity: function proposalCount() view returns(uint256 count_) +func (_PreimageOracle *PreimageOracleCaller) ProposalCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "proposalCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ProposalCount is a free data retrieval call binding the contract method 0xda35c664. +// +// Solidity: function proposalCount() view returns(uint256 count_) +func (_PreimageOracle *PreimageOracleSession) ProposalCount() (*big.Int, error) { + return _PreimageOracle.Contract.ProposalCount(&_PreimageOracle.CallOpts) +} + +// ProposalCount is a free data retrieval call binding the contract method 0xda35c664. +// +// Solidity: function proposalCount() view returns(uint256 count_) +func (_PreimageOracle *PreimageOracleCallerSession) ProposalCount() (*big.Int, error) { + return _PreimageOracle.Contract.ProposalCount(&_PreimageOracle.CallOpts) +} + +// ProposalMetadata is a free data retrieval call binding the contract method 0x6551927b. +// +// Solidity: function proposalMetadata(address , uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleCaller) ProposalMetadata(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) ([32]byte, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "proposalMetadata", arg0, arg1) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProposalMetadata is a free data retrieval call binding the contract method 0x6551927b. +// +// Solidity: function proposalMetadata(address , uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleSession) ProposalMetadata(arg0 common.Address, arg1 *big.Int) ([32]byte, error) { + return _PreimageOracle.Contract.ProposalMetadata(&_PreimageOracle.CallOpts, arg0, arg1) +} + +// ProposalMetadata is a free data retrieval call binding the contract method 0x6551927b. +// +// Solidity: function proposalMetadata(address , uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleCallerSession) ProposalMetadata(arg0 common.Address, arg1 *big.Int) ([32]byte, error) { + return _PreimageOracle.Contract.ProposalMetadata(&_PreimageOracle.CallOpts, arg0, arg1) +} + +// ProposalParts is a free data retrieval call binding the contract method 0xb2e67ba8. +// +// Solidity: function proposalParts(address , uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleCaller) ProposalParts(opts *bind.CallOpts, arg0 common.Address, arg1 *big.Int) ([32]byte, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "proposalParts", arg0, arg1) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ProposalParts is a free data retrieval call binding the contract method 0xb2e67ba8. +// +// Solidity: function proposalParts(address , uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleSession) ProposalParts(arg0 common.Address, arg1 *big.Int) ([32]byte, error) { + return _PreimageOracle.Contract.ProposalParts(&_PreimageOracle.CallOpts, arg0, arg1) +} + +// ProposalParts is a free data retrieval call binding the contract method 0xb2e67ba8. +// +// Solidity: function proposalParts(address , uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleCallerSession) ProposalParts(arg0 common.Address, arg1 *big.Int) ([32]byte, error) { + return _PreimageOracle.Contract.ProposalParts(&_PreimageOracle.CallOpts, arg0, arg1) +} + +// Proposals is a free data retrieval call binding the contract method 0x013cf08b. +// +// Solidity: function proposals(uint256 ) view returns(address claimant, uint256 uuid) +func (_PreimageOracle *PreimageOracleCaller) Proposals(opts *bind.CallOpts, arg0 *big.Int) (struct { + Claimant common.Address + Uuid *big.Int +}, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "proposals", arg0) + + outstruct := new(struct { + Claimant common.Address + Uuid *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Claimant = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.Uuid = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// Proposals is a free data retrieval call binding the contract method 0x013cf08b. +// +// Solidity: function proposals(uint256 ) view returns(address claimant, uint256 uuid) +func (_PreimageOracle *PreimageOracleSession) Proposals(arg0 *big.Int) (struct { + Claimant common.Address + Uuid *big.Int +}, error) { + return _PreimageOracle.Contract.Proposals(&_PreimageOracle.CallOpts, arg0) +} + +// Proposals is a free data retrieval call binding the contract method 0x013cf08b. +// +// Solidity: function proposals(uint256 ) view returns(address claimant, uint256 uuid) +func (_PreimageOracle *PreimageOracleCallerSession) Proposals(arg0 *big.Int) (struct { + Claimant common.Address + Uuid *big.Int +}, error) { + return _PreimageOracle.Contract.Proposals(&_PreimageOracle.CallOpts, arg0) +} + // ReadPreimage is a free data retrieval call binding the contract method 0xe03110e1. // // Solidity: function readPreimage(bytes32 _key, uint256 _offset) view returns(bytes32 dat_, uint256 datLen_) @@ -339,6 +799,173 @@ func (_PreimageOracle *PreimageOracleCallerSession) ReadPreimage(_key [32]byte, return _PreimageOracle.Contract.ReadPreimage(&_PreimageOracle.CallOpts, _key, _offset) } +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_PreimageOracle *PreimageOracleCaller) Version(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "version") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_PreimageOracle *PreimageOracleSession) Version() (string, error) { + return _PreimageOracle.Contract.Version(&_PreimageOracle.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_PreimageOracle *PreimageOracleCallerSession) Version() (string, error) { + return _PreimageOracle.Contract.Version(&_PreimageOracle.CallOpts) +} + +// ZeroHashes is a free data retrieval call binding the contract method 0x7ac54767. +// +// Solidity: function zeroHashes(uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleCaller) ZeroHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _PreimageOracle.contract.Call(opts, &out, "zeroHashes", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ZeroHashes is a free data retrieval call binding the contract method 0x7ac54767. +// +// Solidity: function zeroHashes(uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleSession) ZeroHashes(arg0 *big.Int) ([32]byte, error) { + return _PreimageOracle.Contract.ZeroHashes(&_PreimageOracle.CallOpts, arg0) +} + +// ZeroHashes is a free data retrieval call binding the contract method 0x7ac54767. +// +// Solidity: function zeroHashes(uint256 ) view returns(bytes32) +func (_PreimageOracle *PreimageOracleCallerSession) ZeroHashes(arg0 *big.Int) ([32]byte, error) { + return _PreimageOracle.Contract.ZeroHashes(&_PreimageOracle.CallOpts, arg0) +} + +// AddLeavesLPP is a paid mutator transaction binding the contract method 0x7917de1d. +// +// Solidity: function addLeavesLPP(uint256 _uuid, uint256 _inputStartBlock, bytes _input, bytes32[] _stateCommitments, bool _finalize) returns() +func (_PreimageOracle *PreimageOracleTransactor) AddLeavesLPP(opts *bind.TransactOpts, _uuid *big.Int, _inputStartBlock *big.Int, _input []byte, _stateCommitments [][32]byte, _finalize bool) (*types.Transaction, error) { + return _PreimageOracle.contract.Transact(opts, "addLeavesLPP", _uuid, _inputStartBlock, _input, _stateCommitments, _finalize) +} + +// AddLeavesLPP is a paid mutator transaction binding the contract method 0x7917de1d. +// +// Solidity: function addLeavesLPP(uint256 _uuid, uint256 _inputStartBlock, bytes _input, bytes32[] _stateCommitments, bool _finalize) returns() +func (_PreimageOracle *PreimageOracleSession) AddLeavesLPP(_uuid *big.Int, _inputStartBlock *big.Int, _input []byte, _stateCommitments [][32]byte, _finalize bool) (*types.Transaction, error) { + return _PreimageOracle.Contract.AddLeavesLPP(&_PreimageOracle.TransactOpts, _uuid, _inputStartBlock, _input, _stateCommitments, _finalize) +} + +// AddLeavesLPP is a paid mutator transaction binding the contract method 0x7917de1d. +// +// Solidity: function addLeavesLPP(uint256 _uuid, uint256 _inputStartBlock, bytes _input, bytes32[] _stateCommitments, bool _finalize) returns() +func (_PreimageOracle *PreimageOracleTransactorSession) AddLeavesLPP(_uuid *big.Int, _inputStartBlock *big.Int, _input []byte, _stateCommitments [][32]byte, _finalize bool) (*types.Transaction, error) { + return _PreimageOracle.Contract.AddLeavesLPP(&_PreimageOracle.TransactOpts, _uuid, _inputStartBlock, _input, _stateCommitments, _finalize) +} + +// ChallengeFirstLPP is a paid mutator transaction binding the contract method 0xec5efcbc. +// +// Solidity: function challengeFirstLPP(address _claimant, uint256 _uuid, (bytes,uint256,bytes32) _postState, bytes32[] _postStateProof) returns() +func (_PreimageOracle *PreimageOracleTransactor) ChallengeFirstLPP(opts *bind.TransactOpts, _claimant common.Address, _uuid *big.Int, _postState PreimageOracleLeaf, _postStateProof [][32]byte) (*types.Transaction, error) { + return _PreimageOracle.contract.Transact(opts, "challengeFirstLPP", _claimant, _uuid, _postState, _postStateProof) +} + +// ChallengeFirstLPP is a paid mutator transaction binding the contract method 0xec5efcbc. +// +// Solidity: function challengeFirstLPP(address _claimant, uint256 _uuid, (bytes,uint256,bytes32) _postState, bytes32[] _postStateProof) returns() +func (_PreimageOracle *PreimageOracleSession) ChallengeFirstLPP(_claimant common.Address, _uuid *big.Int, _postState PreimageOracleLeaf, _postStateProof [][32]byte) (*types.Transaction, error) { + return _PreimageOracle.Contract.ChallengeFirstLPP(&_PreimageOracle.TransactOpts, _claimant, _uuid, _postState, _postStateProof) +} + +// ChallengeFirstLPP is a paid mutator transaction binding the contract method 0xec5efcbc. +// +// Solidity: function challengeFirstLPP(address _claimant, uint256 _uuid, (bytes,uint256,bytes32) _postState, bytes32[] _postStateProof) returns() +func (_PreimageOracle *PreimageOracleTransactorSession) ChallengeFirstLPP(_claimant common.Address, _uuid *big.Int, _postState PreimageOracleLeaf, _postStateProof [][32]byte) (*types.Transaction, error) { + return _PreimageOracle.Contract.ChallengeFirstLPP(&_PreimageOracle.TransactOpts, _claimant, _uuid, _postState, _postStateProof) +} + +// ChallengeLPP is a paid mutator transaction binding the contract method 0x3909af5c. +// +// Solidity: function challengeLPP(address _claimant, uint256 _uuid, (uint64[25]) _stateMatrix, (bytes,uint256,bytes32) _preState, bytes32[] _preStateProof, (bytes,uint256,bytes32) _postState, bytes32[] _postStateProof) returns() +func (_PreimageOracle *PreimageOracleTransactor) ChallengeLPP(opts *bind.TransactOpts, _claimant common.Address, _uuid *big.Int, _stateMatrix LibKeccakStateMatrix, _preState PreimageOracleLeaf, _preStateProof [][32]byte, _postState PreimageOracleLeaf, _postStateProof [][32]byte) (*types.Transaction, error) { + return _PreimageOracle.contract.Transact(opts, "challengeLPP", _claimant, _uuid, _stateMatrix, _preState, _preStateProof, _postState, _postStateProof) +} + +// ChallengeLPP is a paid mutator transaction binding the contract method 0x3909af5c. +// +// Solidity: function challengeLPP(address _claimant, uint256 _uuid, (uint64[25]) _stateMatrix, (bytes,uint256,bytes32) _preState, bytes32[] _preStateProof, (bytes,uint256,bytes32) _postState, bytes32[] _postStateProof) returns() +func (_PreimageOracle *PreimageOracleSession) ChallengeLPP(_claimant common.Address, _uuid *big.Int, _stateMatrix LibKeccakStateMatrix, _preState PreimageOracleLeaf, _preStateProof [][32]byte, _postState PreimageOracleLeaf, _postStateProof [][32]byte) (*types.Transaction, error) { + return _PreimageOracle.Contract.ChallengeLPP(&_PreimageOracle.TransactOpts, _claimant, _uuid, _stateMatrix, _preState, _preStateProof, _postState, _postStateProof) +} + +// ChallengeLPP is a paid mutator transaction binding the contract method 0x3909af5c. +// +// Solidity: function challengeLPP(address _claimant, uint256 _uuid, (uint64[25]) _stateMatrix, (bytes,uint256,bytes32) _preState, bytes32[] _preStateProof, (bytes,uint256,bytes32) _postState, bytes32[] _postStateProof) returns() +func (_PreimageOracle *PreimageOracleTransactorSession) ChallengeLPP(_claimant common.Address, _uuid *big.Int, _stateMatrix LibKeccakStateMatrix, _preState PreimageOracleLeaf, _preStateProof [][32]byte, _postState PreimageOracleLeaf, _postStateProof [][32]byte) (*types.Transaction, error) { + return _PreimageOracle.Contract.ChallengeLPP(&_PreimageOracle.TransactOpts, _claimant, _uuid, _stateMatrix, _preState, _preStateProof, _postState, _postStateProof) +} + +// InitLPP is a paid mutator transaction binding the contract method 0xfaf37bc7. +// +// Solidity: function initLPP(uint256 _uuid, uint32 _partOffset, uint32 _claimedSize) payable returns() +func (_PreimageOracle *PreimageOracleTransactor) InitLPP(opts *bind.TransactOpts, _uuid *big.Int, _partOffset uint32, _claimedSize uint32) (*types.Transaction, error) { + return _PreimageOracle.contract.Transact(opts, "initLPP", _uuid, _partOffset, _claimedSize) +} + +// InitLPP is a paid mutator transaction binding the contract method 0xfaf37bc7. +// +// Solidity: function initLPP(uint256 _uuid, uint32 _partOffset, uint32 _claimedSize) payable returns() +func (_PreimageOracle *PreimageOracleSession) InitLPP(_uuid *big.Int, _partOffset uint32, _claimedSize uint32) (*types.Transaction, error) { + return _PreimageOracle.Contract.InitLPP(&_PreimageOracle.TransactOpts, _uuid, _partOffset, _claimedSize) +} + +// InitLPP is a paid mutator transaction binding the contract method 0xfaf37bc7. +// +// Solidity: function initLPP(uint256 _uuid, uint32 _partOffset, uint32 _claimedSize) payable returns() +func (_PreimageOracle *PreimageOracleTransactorSession) InitLPP(_uuid *big.Int, _partOffset uint32, _claimedSize uint32) (*types.Transaction, error) { + return _PreimageOracle.Contract.InitLPP(&_PreimageOracle.TransactOpts, _uuid, _partOffset, _claimedSize) +} + +// LoadBlobPreimagePart is a paid mutator transaction binding the contract method 0x9d7e8769. +// +// Solidity: function loadBlobPreimagePart(uint256 _z, uint256 _y, bytes _commitment, bytes _proof, uint256 _partOffset) returns() +func (_PreimageOracle *PreimageOracleTransactor) LoadBlobPreimagePart(opts *bind.TransactOpts, _z *big.Int, _y *big.Int, _commitment []byte, _proof []byte, _partOffset *big.Int) (*types.Transaction, error) { + return _PreimageOracle.contract.Transact(opts, "loadBlobPreimagePart", _z, _y, _commitment, _proof, _partOffset) +} + +// LoadBlobPreimagePart is a paid mutator transaction binding the contract method 0x9d7e8769. +// +// Solidity: function loadBlobPreimagePart(uint256 _z, uint256 _y, bytes _commitment, bytes _proof, uint256 _partOffset) returns() +func (_PreimageOracle *PreimageOracleSession) LoadBlobPreimagePart(_z *big.Int, _y *big.Int, _commitment []byte, _proof []byte, _partOffset *big.Int) (*types.Transaction, error) { + return _PreimageOracle.Contract.LoadBlobPreimagePart(&_PreimageOracle.TransactOpts, _z, _y, _commitment, _proof, _partOffset) +} + +// LoadBlobPreimagePart is a paid mutator transaction binding the contract method 0x9d7e8769. +// +// Solidity: function loadBlobPreimagePart(uint256 _z, uint256 _y, bytes _commitment, bytes _proof, uint256 _partOffset) returns() +func (_PreimageOracle *PreimageOracleTransactorSession) LoadBlobPreimagePart(_z *big.Int, _y *big.Int, _commitment []byte, _proof []byte, _partOffset *big.Int) (*types.Transaction, error) { + return _PreimageOracle.Contract.LoadBlobPreimagePart(&_PreimageOracle.TransactOpts, _z, _y, _commitment, _proof, _partOffset) +} + // LoadKeccak256PreimagePart is a paid mutator transaction binding the contract method 0xe1592611. // // Solidity: function loadKeccak256PreimagePart(uint256 _partOffset, bytes _preimage) returns() @@ -360,23 +987,86 @@ func (_PreimageOracle *PreimageOracleTransactorSession) LoadKeccak256PreimagePar return _PreimageOracle.Contract.LoadKeccak256PreimagePart(&_PreimageOracle.TransactOpts, _partOffset, _preimage) } -// LoadLocalData is a paid mutator transaction binding the contract method 0xc0c220c9. +// LoadLocalData is a paid mutator transaction binding the contract method 0x52f0f3ad. // -// Solidity: function loadLocalData(uint256 _ident, uint256 _localContext, bytes32 _word, uint256 _size, uint256 _partOffset) returns(bytes32 key_) -func (_PreimageOracle *PreimageOracleTransactor) LoadLocalData(opts *bind.TransactOpts, _ident *big.Int, _localContext *big.Int, _word [32]byte, _size *big.Int, _partOffset *big.Int) (*types.Transaction, error) { +// Solidity: function loadLocalData(uint256 _ident, bytes32 _localContext, bytes32 _word, uint256 _size, uint256 _partOffset) returns(bytes32 key_) +func (_PreimageOracle *PreimageOracleTransactor) LoadLocalData(opts *bind.TransactOpts, _ident *big.Int, _localContext [32]byte, _word [32]byte, _size *big.Int, _partOffset *big.Int) (*types.Transaction, error) { return _PreimageOracle.contract.Transact(opts, "loadLocalData", _ident, _localContext, _word, _size, _partOffset) } -// LoadLocalData is a paid mutator transaction binding the contract method 0xc0c220c9. +// LoadLocalData is a paid mutator transaction binding the contract method 0x52f0f3ad. // -// Solidity: function loadLocalData(uint256 _ident, uint256 _localContext, bytes32 _word, uint256 _size, uint256 _partOffset) returns(bytes32 key_) -func (_PreimageOracle *PreimageOracleSession) LoadLocalData(_ident *big.Int, _localContext *big.Int, _word [32]byte, _size *big.Int, _partOffset *big.Int) (*types.Transaction, error) { +// Solidity: function loadLocalData(uint256 _ident, bytes32 _localContext, bytes32 _word, uint256 _size, uint256 _partOffset) returns(bytes32 key_) +func (_PreimageOracle *PreimageOracleSession) LoadLocalData(_ident *big.Int, _localContext [32]byte, _word [32]byte, _size *big.Int, _partOffset *big.Int) (*types.Transaction, error) { return _PreimageOracle.Contract.LoadLocalData(&_PreimageOracle.TransactOpts, _ident, _localContext, _word, _size, _partOffset) } -// LoadLocalData is a paid mutator transaction binding the contract method 0xc0c220c9. +// LoadLocalData is a paid mutator transaction binding the contract method 0x52f0f3ad. // -// Solidity: function loadLocalData(uint256 _ident, uint256 _localContext, bytes32 _word, uint256 _size, uint256 _partOffset) returns(bytes32 key_) -func (_PreimageOracle *PreimageOracleTransactorSession) LoadLocalData(_ident *big.Int, _localContext *big.Int, _word [32]byte, _size *big.Int, _partOffset *big.Int) (*types.Transaction, error) { +// Solidity: function loadLocalData(uint256 _ident, bytes32 _localContext, bytes32 _word, uint256 _size, uint256 _partOffset) returns(bytes32 key_) +func (_PreimageOracle *PreimageOracleTransactorSession) LoadLocalData(_ident *big.Int, _localContext [32]byte, _word [32]byte, _size *big.Int, _partOffset *big.Int) (*types.Transaction, error) { return _PreimageOracle.Contract.LoadLocalData(&_PreimageOracle.TransactOpts, _ident, _localContext, _word, _size, _partOffset) } + +// LoadPrecompilePreimagePart is a paid mutator transaction binding the contract method 0x04697c78. +// +// Solidity: function loadPrecompilePreimagePart(uint256 _partOffset, address _precompile, bytes _input) returns() +func (_PreimageOracle *PreimageOracleTransactor) LoadPrecompilePreimagePart(opts *bind.TransactOpts, _partOffset *big.Int, _precompile common.Address, _input []byte) (*types.Transaction, error) { + return _PreimageOracle.contract.Transact(opts, "loadPrecompilePreimagePart", _partOffset, _precompile, _input) +} + +// LoadPrecompilePreimagePart is a paid mutator transaction binding the contract method 0x04697c78. +// +// Solidity: function loadPrecompilePreimagePart(uint256 _partOffset, address _precompile, bytes _input) returns() +func (_PreimageOracle *PreimageOracleSession) LoadPrecompilePreimagePart(_partOffset *big.Int, _precompile common.Address, _input []byte) (*types.Transaction, error) { + return _PreimageOracle.Contract.LoadPrecompilePreimagePart(&_PreimageOracle.TransactOpts, _partOffset, _precompile, _input) +} + +// LoadPrecompilePreimagePart is a paid mutator transaction binding the contract method 0x04697c78. +// +// Solidity: function loadPrecompilePreimagePart(uint256 _partOffset, address _precompile, bytes _input) returns() +func (_PreimageOracle *PreimageOracleTransactorSession) LoadPrecompilePreimagePart(_partOffset *big.Int, _precompile common.Address, _input []byte) (*types.Transaction, error) { + return _PreimageOracle.Contract.LoadPrecompilePreimagePart(&_PreimageOracle.TransactOpts, _partOffset, _precompile, _input) +} + +// LoadSha256PreimagePart is a paid mutator transaction binding the contract method 0x8dc4be11. +// +// Solidity: function loadSha256PreimagePart(uint256 _partOffset, bytes _preimage) returns() +func (_PreimageOracle *PreimageOracleTransactor) LoadSha256PreimagePart(opts *bind.TransactOpts, _partOffset *big.Int, _preimage []byte) (*types.Transaction, error) { + return _PreimageOracle.contract.Transact(opts, "loadSha256PreimagePart", _partOffset, _preimage) +} + +// LoadSha256PreimagePart is a paid mutator transaction binding the contract method 0x8dc4be11. +// +// Solidity: function loadSha256PreimagePart(uint256 _partOffset, bytes _preimage) returns() +func (_PreimageOracle *PreimageOracleSession) LoadSha256PreimagePart(_partOffset *big.Int, _preimage []byte) (*types.Transaction, error) { + return _PreimageOracle.Contract.LoadSha256PreimagePart(&_PreimageOracle.TransactOpts, _partOffset, _preimage) +} + +// LoadSha256PreimagePart is a paid mutator transaction binding the contract method 0x8dc4be11. +// +// Solidity: function loadSha256PreimagePart(uint256 _partOffset, bytes _preimage) returns() +func (_PreimageOracle *PreimageOracleTransactorSession) LoadSha256PreimagePart(_partOffset *big.Int, _preimage []byte) (*types.Transaction, error) { + return _PreimageOracle.Contract.LoadSha256PreimagePart(&_PreimageOracle.TransactOpts, _partOffset, _preimage) +} + +// SqueezeLPP is a paid mutator transaction binding the contract method 0xd18534b5. +// +// Solidity: function squeezeLPP(address _claimant, uint256 _uuid, (uint64[25]) _stateMatrix, (bytes,uint256,bytes32) _preState, bytes32[] _preStateProof, (bytes,uint256,bytes32) _postState, bytes32[] _postStateProof) returns() +func (_PreimageOracle *PreimageOracleTransactor) SqueezeLPP(opts *bind.TransactOpts, _claimant common.Address, _uuid *big.Int, _stateMatrix LibKeccakStateMatrix, _preState PreimageOracleLeaf, _preStateProof [][32]byte, _postState PreimageOracleLeaf, _postStateProof [][32]byte) (*types.Transaction, error) { + return _PreimageOracle.contract.Transact(opts, "squeezeLPP", _claimant, _uuid, _stateMatrix, _preState, _preStateProof, _postState, _postStateProof) +} + +// SqueezeLPP is a paid mutator transaction binding the contract method 0xd18534b5. +// +// Solidity: function squeezeLPP(address _claimant, uint256 _uuid, (uint64[25]) _stateMatrix, (bytes,uint256,bytes32) _preState, bytes32[] _preStateProof, (bytes,uint256,bytes32) _postState, bytes32[] _postStateProof) returns() +func (_PreimageOracle *PreimageOracleSession) SqueezeLPP(_claimant common.Address, _uuid *big.Int, _stateMatrix LibKeccakStateMatrix, _preState PreimageOracleLeaf, _preStateProof [][32]byte, _postState PreimageOracleLeaf, _postStateProof [][32]byte) (*types.Transaction, error) { + return _PreimageOracle.Contract.SqueezeLPP(&_PreimageOracle.TransactOpts, _claimant, _uuid, _stateMatrix, _preState, _preStateProof, _postState, _postStateProof) +} + +// SqueezeLPP is a paid mutator transaction binding the contract method 0xd18534b5. +// +// Solidity: function squeezeLPP(address _claimant, uint256 _uuid, (uint64[25]) _stateMatrix, (bytes,uint256,bytes32) _preState, bytes32[] _preStateProof, (bytes,uint256,bytes32) _postState, bytes32[] _postStateProof) returns() +func (_PreimageOracle *PreimageOracleTransactorSession) SqueezeLPP(_claimant common.Address, _uuid *big.Int, _stateMatrix LibKeccakStateMatrix, _preState PreimageOracleLeaf, _preStateProof [][32]byte, _postState PreimageOracleLeaf, _postStateProof [][32]byte) (*types.Transaction, error) { + return _PreimageOracle.Contract.SqueezeLPP(&_PreimageOracle.TransactOpts, _claimant, _uuid, _stateMatrix, _preState, _preStateProof, _postState, _postStateProof) +} diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 8599e2f8762a..8a68057bd712 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -9,13 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const PreimageOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"preimageLengths\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_uint256)\"},{\"astId\":1001,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"preimageParts\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_bytes32,t_mapping(t_uint256,t_bytes32))\"},{\"astId\":1002,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"preimagePartOk\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_bytes32,t_mapping(t_uint256,t_bool))\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_mapping(t_uint256,t_bool))\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e mapping(uint256 =\u003e bool))\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_mapping(t_uint256,t_bool)\"},\"t_mapping(t_bytes32,t_mapping(t_uint256,t_bytes32))\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e mapping(uint256 =\u003e bytes32))\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_mapping(t_uint256,t_bytes32)\"},\"t_mapping(t_bytes32,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_uint256\"},\"t_mapping(t_uint256,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_bool\"},\"t_mapping(t_uint256,t_bytes32)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e bytes32)\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_bytes32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}" +const PreimageOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"preimageLengths\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_uint256)\"},{\"astId\":1001,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"preimageParts\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_bytes32,t_mapping(t_uint256,t_bytes32))\"},{\"astId\":1002,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"preimagePartOk\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_bytes32,t_mapping(t_uint256,t_bool))\"},{\"astId\":1003,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"zeroHashes\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_bytes32)16_storage\"},{\"astId\":1004,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"proposals\",\"offset\":0,\"slot\":\"19\",\"type\":\"t_array(t_struct(LargePreimageProposalKeys)1010_storage)dyn_storage\"},{\"astId\":1005,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"proposalBranches\",\"offset\":0,\"slot\":\"20\",\"type\":\"t_mapping(t_address,t_mapping(t_uint256,t_array(t_bytes32)16_storage))\"},{\"astId\":1006,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"proposalMetadata\",\"offset\":0,\"slot\":\"21\",\"type\":\"t_mapping(t_address,t_mapping(t_uint256,t_userDefinedValueType(LPPMetaData)1011))\"},{\"astId\":1007,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"proposalBonds\",\"offset\":0,\"slot\":\"22\",\"type\":\"t_mapping(t_address,t_mapping(t_uint256,t_uint256))\"},{\"astId\":1008,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"proposalParts\",\"offset\":0,\"slot\":\"23\",\"type\":\"t_mapping(t_address,t_mapping(t_uint256,t_bytes32))\"},{\"astId\":1009,\"contract\":\"src/cannon/PreimageOracle.sol:PreimageOracle\",\"label\":\"proposalBlocks\",\"offset\":0,\"slot\":\"24\",\"type\":\"t_mapping(t_address,t_mapping(t_uint256,t_array(t_uint64)dyn_storage))\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_bytes32)16_storage\":{\"encoding\":\"inplace\",\"label\":\"bytes32[16]\",\"numberOfBytes\":\"512\",\"base\":\"t_bytes32\"},\"t_array(t_struct(LargePreimageProposalKeys)1010_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct PreimageOracle.LargePreimageProposalKeys[]\",\"numberOfBytes\":\"32\",\"base\":\"t_struct(LargePreimageProposalKeys)1010_storage\"},\"t_array(t_uint64)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"uint64[]\",\"numberOfBytes\":\"32\",\"base\":\"t_uint64\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_address,t_mapping(t_uint256,t_array(t_bytes32)16_storage))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(uint256 =\u003e bytes32[16]))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_uint256,t_array(t_bytes32)16_storage)\"},\"t_mapping(t_address,t_mapping(t_uint256,t_array(t_uint64)dyn_storage))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(uint256 =\u003e uint64[]))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_uint256,t_array(t_uint64)dyn_storage)\"},\"t_mapping(t_address,t_mapping(t_uint256,t_bytes32))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(uint256 =\u003e bytes32))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_uint256,t_bytes32)\"},\"t_mapping(t_address,t_mapping(t_uint256,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(uint256 =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_uint256,t_uint256)\"},\"t_mapping(t_address,t_mapping(t_uint256,t_userDefinedValueType(LPPMetaData)1011))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(uint256 =\u003e LPPMetaData))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_uint256,t_userDefinedValueType(LPPMetaData)1011)\"},\"t_mapping(t_bytes32,t_mapping(t_uint256,t_bool))\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e mapping(uint256 =\u003e bool))\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_mapping(t_uint256,t_bool)\"},\"t_mapping(t_bytes32,t_mapping(t_uint256,t_bytes32))\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e mapping(uint256 =\u003e bytes32))\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_mapping(t_uint256,t_bytes32)\"},\"t_mapping(t_bytes32,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_uint256\"},\"t_mapping(t_uint256,t_array(t_bytes32)16_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e bytes32[16])\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_array(t_bytes32)16_storage\"},\"t_mapping(t_uint256,t_array(t_uint64)dyn_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e uint64[])\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_array(t_uint64)dyn_storage\"},\"t_mapping(t_uint256,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_bool\"},\"t_mapping(t_uint256,t_bytes32)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e bytes32)\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_bytes32\"},\"t_mapping(t_uint256,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_uint256\"},\"t_mapping(t_uint256,t_userDefinedValueType(LPPMetaData)1011)\":{\"encoding\":\"mapping\",\"label\":\"mapping(uint256 =\u003e LPPMetaData)\",\"numberOfBytes\":\"32\",\"key\":\"t_uint256\",\"value\":\"t_userDefinedValueType(LPPMetaData)1011\"},\"t_struct(LargePreimageProposalKeys)1010_storage\":{\"encoding\":\"inplace\",\"label\":\"struct PreimageOracle.LargePreimageProposalKeys\",\"numberOfBytes\":\"64\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"},\"t_userDefinedValueType(LPPMetaData)1011\":{\"encoding\":\"inplace\",\"label\":\"LPPMetaData\",\"numberOfBytes\":\"32\"}}}" var PreimageOracleStorageLayout = new(solc.StorageLayout) -var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" +var PreimageOracleDeployedBin = "0x6080604052600436106101cd5760003560e01c80638dc4be11116100f7578063dd24f9bf11610095578063ec5efcbc11610064578063ec5efcbc1461065f578063f3f480d91461067f578063faf37bc7146106b2578063fef2b4ed146106c557600080fd5b8063dd24f9bf1461059f578063ddcd58de146105d2578063e03110e11461060a578063e15926111461063f57600080fd5b8063b2e67ba8116100d1578063b2e67ba814610512578063b4801e611461054a578063d18534b51461056a578063da35c6641461058a57600080fd5b80638dc4be11146104835780639d53a648146104a35780639d7e8769146104f257600080fd5b806354fd4d501161016f5780637917de1d1161013e5780637917de1d146103bf5780637ac54767146103df5780638542cf50146103ff578063882856ef1461044a57600080fd5b806354fd4d50146102dd57806361238bde146103335780636551927b1461036b5780637051472e146103a357600080fd5b80632055b36b116101ab5780632055b36b146102735780633909af5c146102885780634d52b4c9146102a857806352f0f3ad146102bd57600080fd5b8063013cf08b146101d25780630359a5631461022357806304697c7814610251575b600080fd5b3480156101de57600080fd5b506101f26101ed366004612d1c565b6106f2565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152015b60405180910390f35b34801561022f57600080fd5b5061024361023e366004612d5e565b610737565b60405190815260200161021a565b34801561025d57600080fd5b5061027161026c366004612dd1565b61086f565b005b34801561027f57600080fd5b50610243601081565b34801561029457600080fd5b506102716102a3366004612ff5565b6109a5565b3480156102b457600080fd5b50610243610bfc565b3480156102c957600080fd5b506102436102d83660046130e1565b610c17565b3480156102e957600080fd5b506103266040518060400160405280600581526020017f302e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161021a9190613148565b34801561033f57600080fd5b5061024361034e366004613199565b600160209081526000928352604080842090915290825290205481565b34801561037757600080fd5b50610243610386366004612d5e565b601560209081526000928352604080842090915290825290205481565b3480156103af57600080fd5b506102436703782dace9d9000081565b3480156103cb57600080fd5b506102716103da3660046131bb565b610cec565b3480156103eb57600080fd5b506102436103fa366004612d1c565b6111dc565b34801561040b57600080fd5b5061043a61041a366004613199565b600260209081526000928352604080842090915290825290205460ff1681565b604051901515815260200161021a565b34801561045657600080fd5b5061046a610465366004613257565b6111f3565b60405167ffffffffffffffff909116815260200161021a565b34801561048f57600080fd5b5061027161049e36600461328a565b61124d565b3480156104af57600080fd5b506102436104be366004612d5e565b73ffffffffffffffffffffffffffffffffffffffff9091166000908152601860209081526040808320938352929052205490565b3480156104fe57600080fd5b5061027161050d3660046132d6565b611348565b34801561051e57600080fd5b5061024361052d366004612d5e565b601760209081526000928352604080842090915290825290205481565b34801561055657600080fd5b50610243610565366004613257565b6114ff565b34801561057657600080fd5b50610271610585366004612ff5565b611531565b34801561059657600080fd5b50601354610243565b3480156105ab57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610243565b3480156105de57600080fd5b506102436105ed366004612d5e565b601660209081526000928352604080842090915290825290205481565b34801561061657600080fd5b5061062a610625366004613199565b6118f3565b6040805192835260208301919091520161021a565b34801561064b57600080fd5b5061027161065a36600461328a565b6119e4565b34801561066b57600080fd5b5061027161067a366004613362565b611aec565b34801561068b57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610243565b6102716106c03660046133fb565b611c72565b3480156106d157600080fd5b506102436106e0366004612d1c565b60006020819052908152604090205481565b6013818154811061070257600080fd5b60009182526020909120600290910201805460019091015473ffffffffffffffffffffffffffffffffffffffff909116915082565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601560209081526040808320848452909152812054819061077a9060601c63ffffffff1690565b63ffffffff16905060005b6010811015610867578160011660010361080d5773ffffffffffffffffffffffffffffffffffffffff85166000908152601460209081526040808320878452909152902081601081106107da576107da613437565b0154604080516020810192909252810184905260600160405160208183030381529060405280519060200120925061084e565b826003826010811061082157610821613437565b01546040805160208101939093528201526060016040516020818303038152906040528051906020012092505b60019190911c908061085f81613495565b915050610785565b505092915050565b600080600080608060146030823785878260140137601480870182207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06000000000000000000000000000000000000000000000000000000000000001794506000908190889084018b5afa94503d60010191506008820189106108fc5763fe2549876000526004601cfd5b60c082901b81526008018481533d6000600183013e88017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8015160008481526002602090815260408083208c8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915587845282528083209b83529a81528a82209290925593845283905296909120959095555050505050565b60006109b18a8a610737565b90506109d486868360208b01356109cf6109ca8d6134cd565b611edd565b611f1d565b80156109f257506109f283838360208801356109cf6109ca8a6134cd565b610a28576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b866040013588604051602001610a3e919061359c565b6040516020818303038152906040528051906020012014610a8b576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836020013587602001356001610aa191906135da565b14610ad8576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b2088610ae686806135f2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f7e92505050565b610b29886120d9565b836040013588604051602001610b3f919061359c565b6040516020818303038152906040528051906020012003610b8c576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526015602090815260408083208c8452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055610bf08a8a33612881565b50505050505050505050565b6001610c0a60106002613779565b610c149190613785565b81565b6000610c23868661293a565b9050610c308360086135da565b821180610c3d5750602083115b15610c74576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b60608115610d0557610cfe86866129e7565b9050610d3f565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b3360009081526014602090815260408083208b845290915280822081516102008101928390529160109082845b815481526020019060010190808311610d6c57505050505090506000601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b81526020019081526020016000205490506000610ded8260601c63ffffffff1690565b63ffffffff169050333214610e2e576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3e8260801c63ffffffff1690565b63ffffffff16600003610e7d576040517f87138d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e878260c01c90565b67ffffffffffffffff1615610ec8576040517f475a253500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b898114610f01576040517f60f95d5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f0e89898d8886612a60565b83516020850160888204881415608883061715610f33576307b1daf16000526004601cfd5b60405160c8810160405260005b83811015610fe3578083018051835260208101516020840152604081015160408401526060810151606084015260808101516080840152508460888301526088810460051b8b013560a883015260c882206001860195508560005b610200811015610fd8576001821615610fb85782818b0152610fd8565b8981015160009081526020938452604090209260019290921c9101610f9b565b505050608801610f40565b50505050600160106002610ff79190613779565b6110019190613785565b81111561103a576040517f6229572300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110af61104d8360401c63ffffffff1690565b61105d9063ffffffff168a6135da565b60401b7fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff606084901b167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516171790565b9150841561113c5777ffffffffffffffffffffffffffffffffffffffffffffffff82164260c01b1791506110e98260801c63ffffffff1690565b63ffffffff166110ff8360401c63ffffffff1690565b63ffffffff161461113c576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526014602090815260408083208e8452909152902061116290846010612c92565b50503360008181526018602090815260408083208e8452825280832080546001810182559084528284206004820401805460039092166008026101000a67ffffffffffffffff818102199093164390931602919091179055928252601581528282209c82529b909b52909920989098555050505050505050565b600381601081106111ec57600080fd5b0154905081565b6018602052826000526040600020602052816000526040600020818154811061121b57600080fd5b906000526020600020906004918282040191900660080292509250509054906101000a900467ffffffffffffffff1681565b60443560008060088301861061126b5763fe2549876000526004601cfd5b60c083901b60805260888386823786600882030151915060206000858360025afa90508061129857600080fd5b50600080517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0400000000000000000000000000000000000000000000000000000000000000178082526002602090815260408084208a8552825280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558385528252808420998452988152888320939093558152908190529490942055505050565b600080603087600037602060006030600060025afa806113705763f91129696000526004601cfd5b6000517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017608081815260a08c905260c08b905260308a60e037603088609083013760008060c083600a5afa9250826113f2576309bde3396000526004601cfd5b602886106114085763fe2549876000526004601cfd5b6000602882015278200000000000000000000000000000000000000000000000008152600881018b905285810151935060308a8237603081019b909b52505060509098207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0500000000000000000000000000000000000000000000000000000000000000176000818152600260209081526040808320868452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209583529481528482209a909a559081528089529190912096909655505050505050565b6014602052826000526040600020602052816000526040600020816010811061152757600080fd5b0154925083915050565b73ffffffffffffffffffffffffffffffffffffffff891660009081526015602090815260408083208b845290915290205467ffffffffffffffff8116156115a4576040517fc334f06900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006115cf8260c01c90565b6115e39067ffffffffffffffff1642613785565b1161161a576040517f55d4cbf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006116268b8b610737565b905061163f87878360208c01356109cf6109ca8e6134cd565b801561165d575061165d84848360208901356109cf6109ca8b6134cd565b611693576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760400135896040516020016116a9919061359c565b60405160208183030381529060405280519060200120146116f6576040517f1968a90200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84602001358860200135600161170c91906135da565b14158061173e575060016117268360601c63ffffffff1690565b611730919061379c565b63ffffffff16856020013514155b15611775576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61178389610ae687806135f2565b61178c896120d9565b60006117978a612bb3565b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f020000000000000000000000000000000000000000000000000000000000000017905060006117ee8460a01c63ffffffff1690565b67ffffffffffffffff169050600160026000848152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff021916908315150217905550601760008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d815260200190815260200160002054600160008481526020019081526020016000206000838152602001908152602001600020819055506118c08460801c63ffffffff1690565b600083815260208190526040902063ffffffff9190911690556118e48d8d81612881565b50505050505050505050505050565b6000828152600260209081526040808320848452909152812054819060ff1661197c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546119988160086135da565b6119a38560206135da565b106119c157836119b48260086135da565b6119be9190613785565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018610611a025763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b6000611af88686610737565b9050611b1183838360208801356109cf6109ca8a6134cd565b611b47576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084013515611b83576040517f9a3b119900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b8b612cd0565b611b9981610ae687806135f2565b611ba2816120d9565b846040013581604051602001611bb8919061359c565b6040516020818303038152906040528051906020012003611c05576040517f9843145b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152601560209081526040808320898452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001179055611c69878733612881565b50505050505050565b6703782dace9d90000341015611cb4576040517fe92c469f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b333214611ced576040517fba092d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cf88160086137c1565b63ffffffff168263ffffffff1610611d3c576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008163ffffffff161015611d9c576040517f7b1dafd100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000818152601560209081526040808320878452825280832080547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1660a09790971b7fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff169690961760809590951b949094179094558251808401845282815280850186815260138054600181018255908452915160029092027f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0908101805473ffffffffffffffffffffffffffffffffffffffff9094167fffffffffffffffffffffffff000000000000000000000000000000000000000090941693909317909255517f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0919091015590815260168352818120938152929091529020349055565b6000816000015182602001518360400151604051602001611f00939291906137e9565b604051602081830303815290604052805190602001209050919050565b60008160005b6010811015611f71578060051b880135600186831c1660018114611f565760008481526020839052604090209350611f67565b600082815260208590526040902093505b5050600101611f23565b5090931495945050505050565b6088815114611f8c57600080fd5b602081016020830161200d565b8260031b8201518060001a8160011a60081b178160021a60101b8260031a60181b17178160041a60201b8260051a60281b178260061a60301b8360071a60381b171717905061200781611ff2868560059190911b015190565b1867ffffffffffffffff16600586901b840152565b50505050565b61201960008383611f99565b61202560018383611f99565b61203160028383611f99565b61203d60038383611f99565b61204960048383611f99565b61205560058383611f99565b61206160068383611f99565b61206d60078383611f99565b61207960088383611f99565b61208560098383611f99565b612091600a8383611f99565b61209d600b8383611f99565b6120a9600c8383611f99565b6120b5600d8383611f99565b6120c1600e8383611f99565b6120cd600f8383611f99565b61200760108383611f99565b6040805178010000000000008082800000000000808a8000000080008000602082015279808b00000000800000018000000080008081800000000000800991810191909152788a00000000000000880000000080008009000000008000000a60608201527b8000808b800000000000008b8000000000008089800000000000800360808201527f80000000000080028000000000000080000000000000800a800000008000000a60a08201527f800000008000808180000000000080800000000080000001800000008000800860c082015260009060e00160405160208183030381529060405290506020820160208201612761565b6102808101516101e082015161014083015160a0840151845118189118186102a082015161020083015161016084015160c0850151602086015118189118186102c083015161022084015161018085015160e0860151604087015118189118186102e08401516102408501516101a0860151610100870151606088015118189118186103008501516102608601516101c0870151610120880151608089015118189118188084603f1c61228c8660011b67ffffffffffffffff1690565b18188584603f1c6122a78660011b67ffffffffffffffff1690565b18188584603f1c6122c28660011b67ffffffffffffffff1690565b181895508483603f1c6122df8560011b67ffffffffffffffff1690565b181894508387603f1c6122fc8960011b67ffffffffffffffff1690565b60208b01518b51861867ffffffffffffffff168c5291189190911897508118600181901b603f9190911c18935060c08801518118601481901c602c9190911b1867ffffffffffffffff1660208901526101208801518718602c81901c60149190911b1867ffffffffffffffff1660c08901526102c08801518618600381901c603d9190911b1867ffffffffffffffff166101208901526101c08801518718601981901c60279190911b1867ffffffffffffffff166102c08901526102808801518218602e81901c60129190911b1867ffffffffffffffff166101c089015260408801518618600281901c603e9190911b1867ffffffffffffffff166102808901526101808801518618601581901c602b9190911b1867ffffffffffffffff1660408901526101a08801518518602781901c60199190911b1867ffffffffffffffff166101808901526102608801518718603881901c60089190911b1867ffffffffffffffff166101a08901526102e08801518518600881901c60389190911b1867ffffffffffffffff166102608901526101e08801518218601781901c60299190911b1867ffffffffffffffff166102e089015260808801518718602581901c601b9190911b1867ffffffffffffffff166101e08901526103008801518718603281901c600e9190911b1867ffffffffffffffff1660808901526102a08801518118603e81901c60029190911b1867ffffffffffffffff166103008901526101008801518518600981901c60379190911b1867ffffffffffffffff166102a08901526102008801518118601381901c602d9190911b1867ffffffffffffffff1661010089015260a08801518218601c81901c60249190911b1867ffffffffffffffff1661020089015260608801518518602481901c601c9190911b1867ffffffffffffffff1660a08901526102408801518518602b81901c60159190911b1867ffffffffffffffff1660608901526102208801518618603181901c600f9190911b1867ffffffffffffffff166102408901526101608801518118603681901c600a9190911b1867ffffffffffffffff166102208901525060e08701518518603a81901c60069190911b1867ffffffffffffffff166101608801526101408701518118603d81901c60039190911b1867ffffffffffffffff1660e0880152505067ffffffffffffffff81166101408601525b5050505050565b600582811b8201805160018501831b8401805160028701851b8601805160038901871b8801805160048b0190981b8901805167ffffffffffffffff861985168918811690995283198a16861889169096528819861683188816909352841986168818871690528419831684189095169052919391929190611c69565b6126fb600082612674565b612706600582612674565b612711600a82612674565b61271c600f82612674565b612727601482612674565b50565b612733816121cf565b61273c816126f0565b600383901b820151815160c09190911c9061200790821867ffffffffffffffff168352565b61276d6000828461272a565b6127796001828461272a565b6127856002828461272a565b6127916003828461272a565b61279d6004828461272a565b6127a96005828461272a565b6127b56006828461272a565b6127c16007828461272a565b6127cd6008828461272a565b6127d96009828461272a565b6127e5600a828461272a565b6127f1600b828461272a565b6127fd600c828461272a565b612809600d828461272a565b612815600e828461272a565b612821600f828461272a565b61282d6010828461272a565b6128396011828461272a565b6128456012828461272a565b6128516013828461272a565b61285d6014828461272a565b6128696015828461272a565b6128756016828461272a565b6120076017828461272a565b73ffffffffffffffffffffffffffffffffffffffff83811660009081526016602090815260408083208684529091528082208054908390559051909284169083908381818185875af1925050503d80600081146128fa576040519150601f19603f3d011682016040523d82523d6000602084013e6128ff565b606091505b505090508061266d576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176129e0818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b6060604051905081602082018181018286833760888306808015612a305760888290038501848101848103803687375060806001820353506001845160001a1784538652612a47565b608836843760018353608060878401536088850186525b5050505050601f19603f82510116810160405292915050565b6000612a728260a01c63ffffffff1690565b67ffffffffffffffff1690506000612a908360801c63ffffffff1690565b63ffffffff1690506000612aaa8460401c63ffffffff1690565b63ffffffff169050600883108015612ac0575080155b15612af45760c082901b6000908152883560085283513382526017602090815260408084208a855290915290912055612ba9565b60088310158015612b12575080612b0c600885613785565b93508310155b8015612b265750612b2387826135da565b83105b15612ba9576000612b378285613785565b905087612b458260206135da565b10158015612b51575085155b15612b88576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526017602090815260408083208a845290915290209089013590555b5050505050505050565b6000612c36565b66ff00ff00ff00ff8160081c1667ff00ff00ff00ff00612be48360081b67ffffffffffffffff1690565b1617905065ffff0000ffff8160101c1667ffff0000ffff0000612c118360101b67ffffffffffffffff1690565b1617905060008160201c612c2f8360201b67ffffffffffffffff1690565b1792915050565b60808201516020830190612c4e90612bba565b612bba565b6040820151612c5c90612bba565b60401b17612c74612c4960018460059190911b015190565b825160809190911b90612c8690612bba565b60c01b17179392505050565b8260108101928215612cc0579160200282015b82811115612cc0578251825591602001919060010190612ca5565b50612ccc929150612ce8565b5090565b6040518060200160405280612ce3612cfd565b905290565b5b80821115612ccc5760008155600101612ce9565b6040518061032001604052806019906020820280368337509192915050565b600060208284031215612d2e57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612d5957600080fd5b919050565b60008060408385031215612d7157600080fd5b612d7a83612d35565b946020939093013593505050565b60008083601f840112612d9a57600080fd5b50813567ffffffffffffffff811115612db257600080fd5b602083019150836020828501011115612dca57600080fd5b9250929050565b60008060008060608587031215612de757600080fd5b84359350612df760208601612d35565b9250604085013567ffffffffffffffff811115612e1357600080fd5b612e1f87828801612d88565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610320810167ffffffffffffffff81118282101715612e7e57612e7e612e2b565b60405290565b6040516060810167ffffffffffffffff81118282101715612e7e57612e7e612e2b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612eee57612eee612e2b565b604052919050565b6000610320808385031215612f0a57600080fd5b604051602080820167ffffffffffffffff8382108183111715612f2f57612f2f612e2b565b8160405283955087601f880112612f4557600080fd5b612f4d612e5a565b9487019491508188861115612f6157600080fd5b875b86811015612f895780358381168114612f7c5760008081fd5b8452928401928401612f63565b50909352509295945050505050565b600060608284031215612faa57600080fd5b50919050565b60008083601f840112612fc257600080fd5b50813567ffffffffffffffff811115612fda57600080fd5b6020830191508360208260051b8501011115612dca57600080fd5b60008060008060008060008060006103e08a8c03121561301457600080fd5b61301d8a612d35565b985060208a013597506130338b60408c01612ef6565b96506103608a013567ffffffffffffffff8082111561305157600080fd5b61305d8d838e01612f98565b97506103808c013591508082111561307457600080fd5b6130808d838e01612fb0565b90975095506103a08c013591508082111561309a57600080fd5b6130a68d838e01612f98565b94506103c08c01359150808211156130bd57600080fd5b506130ca8c828d01612fb0565b915080935050809150509295985092959850929598565b600080600080600060a086880312156130f957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b8381101561313757818101518382015260200161311f565b838111156120075750506000910152565b602081526000825180602084015261316781604085016020870161311c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600080604083850312156131ac57600080fd5b50508035926020909101359150565b600080600080600080600060a0888a0312156131d657600080fd5b8735965060208801359550604088013567ffffffffffffffff808211156131fc57600080fd5b6132088b838c01612d88565b909750955060608a013591508082111561322157600080fd5b5061322e8a828b01612fb0565b9094509250506080880135801515811461324757600080fd5b8091505092959891949750929550565b60008060006060848603121561326c57600080fd5b61327584612d35565b95602085013595506040909401359392505050565b60008060006040848603121561329f57600080fd5b83359250602084013567ffffffffffffffff8111156132bd57600080fd5b6132c986828701612d88565b9497909650939450505050565b600080600080600080600060a0888a0312156132f157600080fd5b8735965060208801359550604088013567ffffffffffffffff8082111561331757600080fd5b6133238b838c01612d88565b909750955060608a013591508082111561333c57600080fd5b506133498a828b01612d88565b989b979a50959894979596608090950135949350505050565b60008060008060006080868803121561337a57600080fd5b61338386612d35565b945060208601359350604086013567ffffffffffffffff808211156133a757600080fd5b6133b389838a01612f98565b945060608801359150808211156133c957600080fd5b506133d688828901612fb0565b969995985093965092949392505050565b803563ffffffff81168114612d5957600080fd5b60008060006060848603121561341057600080fd5b83359250613420602085016133e7565b915061342e604085016133e7565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036134c6576134c6613466565b5060010190565b6000606082360312156134df57600080fd5b6134e7612e84565b823567ffffffffffffffff808211156134ff57600080fd5b9084019036601f83011261351257600080fd5b813560208282111561352657613526612e2b565b613556817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601612ea7565b9250818352368183860101111561356c57600080fd5b81818501828501376000918301810191909152908352848101359083015250604092830135928101929092525090565b81516103208201908260005b60198110156135d157825167ffffffffffffffff168252602092830192909101906001016135a8565b50505092915050565b600082198211156135ed576135ed613466565b500190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261362757600080fd5b83018035915067ffffffffffffffff82111561364257600080fd5b602001915036819003821315612dca57600080fd5b600181815b808511156136b057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561369657613696613466565b808516156136a357918102915b93841c939080029061365c565b509250929050565b6000826136c757506001613773565b816136d457506000613773565b81600181146136ea57600281146136f457613710565b6001915050613773565b60ff84111561370557613705613466565b50506001821b613773565b5060208310610133831016604e8410600b8410161715613733575081810a613773565b61373d8383613657565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561376f5761376f613466565b0290505b92915050565b60006129e083836136b8565b60008282101561379757613797613466565b500390565b600063ffffffff838116908316818110156137b9576137b9613466565b039392505050565b600063ffffffff8083168185168083038211156137e0576137e0613466565b01949350505050565b600084516137fb81846020890161311c565b9190910192835250602082015260400191905056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:189:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:351;;;401:2;386:18;537:68:189;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:351;;607:22;589:41;;577:2;562:18;680:66:189;449:187:351;1367:1211:189;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:351;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:189;1100:248:351;2620:1595:189;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:189;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:189:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:351;906:62:189;;;2890:21:351;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:189;;;;;;;;-1:-1:-1;1099:14:189;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:189;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:189:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:189:o;552:449:188:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:188:o;14:248:351:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:351;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:351:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:351;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:351;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:351;1069:19;1056:33;;-1:-1:-1;641:454:351;-1:-1:-1;641:454:351:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:351;;2017:180;-1:-1:-1;2017:180:351:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:351;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:351;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { @@ -24,4 +23,5 @@ func init() { layouts["PreimageOracle"] = PreimageOracleStorageLayout deployedBytecodes["PreimageOracle"] = PreimageOracleDeployedBin + immutableReferences["PreimageOracle"] = true } diff --git a/op-bindings/bindings/protocolversions.go b/op-bindings/bindings/protocolversions.go index 9535ea8cb52c..c63e46f16cbb 100644 --- a/op-bindings/bindings/protocolversions.go +++ b/op-bindings/bindings/protocolversions.go @@ -30,8 +30,8 @@ var ( // ProtocolVersionsMetaData contains all meta data concerning the ProtocolVersions contract. var ProtocolVersionsMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"enumProtocolVersions.UpdateType\",\"name\":\"updateType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"ConfigUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"RECOMMENDED_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REQUIRED_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"ProtocolVersion\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"ProtocolVersion\",\"name\":\"_recommended\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recommended\",\"outputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"out_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"required\",\"outputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"out_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"_recommended\",\"type\":\"uint256\"}],\"name\":\"setRecommended\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"_required\",\"type\":\"uint256\"}],\"name\":\"setRequired\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b506200002261dead60008062000028565b620004c9565b600054600390610100900460ff161580156200004b575060005460ff8083169116105b620000b45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620000d26200013a565b620000dd84620001a2565b620000e88362000221565b620000f382620002d1565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b600054610100900460ff16620001965760405162461bcd60e51b815260206004820152602b602482015260008051602062000e9683398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b620001a062000332565b565b620001ac62000399565b6001600160a01b038116620002135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620000ab565b6200021e81620003f5565b50565b620002676200025260017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16200044b565b60001b826200044760201b620004f51760201c565b6000816040516020016200027d91815260200190565b60408051601f19818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051620002c5919062000471565b60405180910390a35050565b620003026200025260017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6200044b565b6000816040516020016200031891815260200190565b60408051601f198184030181529190529050600162000292565b600054610100900460ff166200038e5760405162461bcd60e51b815260206004820152602b602482015260008051602062000e9683398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b620001a033620003f5565b6033546001600160a01b03163314620001a05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000ab565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b9055565b6000828210156200046c57634e487b7160e01b600052601160045260246000fd5b500390565b600060208083528351808285015260005b81811015620004a05785810183015185820160400152820162000482565b81811115620004b3576000604083870101525b50601f01601f1916929092016040019392505050565b6109bd80620004d96000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e736600461085d565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161010091906108e1565b6100ec61016036600461085d565b61021d565b6100ec61022e565b6100ec61017b366004610924565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103ad565b6100f66103e6565b6100ec6101c6366004610957565b610416565b6100f66104ca565b6100f6600081565b6101e36104f9565b6101ec8161057a565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b81565b6102256104f9565b6101ec81610632565b6102366104f9565b61024060006106ac565b565b600054600390610100900460ff16158015610264575060005460ff8083169116105b6102f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561032e610723565b61033784610416565b6103408361057a565b61034982610632565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b60006103e16103dd60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b5490565b905090565b60006103e16103dd60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b61041e6104f9565b73ffffffffffffffffffffffffffffffffffffffff81166104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102ec565b6101ec816106ac565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102ec565b6105ad6105a860017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b829055565b6000816040516020016105c291815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161062691906108e1565b60405180910390a35050565b6106606105a860017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b60008160405160200161067591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060016105f5565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240600054610100900460ff16610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240336106ac565b60006020828403121561086f57600080fd5b5035919050565b6000815180845260005b8181101561089c57602081850181015186830182015201610880565b818111156108ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006108f46020830184610876565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091f57600080fd5b919050565b60008060006060848603121561093957600080fd5b610942846108fb565b95602085013595506040909401359392505050565b60006020828403121561096957600080fd5b6108f4826108fb565b6000828210156109ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"RECOMMENDED_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"REQUIRED_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_required\",\"type\":\"uint256\",\"internalType\":\"ProtocolVersion\"},{\"name\":\"_recommended\",\"type\":\"uint256\",\"internalType\":\"ProtocolVersion\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"recommended\",\"inputs\":[],\"outputs\":[{\"name\":\"out_\",\"type\":\"uint256\",\"internalType\":\"ProtocolVersion\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"required\",\"inputs\":[],\"outputs\":[{\"name\":\"out_\",\"type\":\"uint256\",\"internalType\":\"ProtocolVersion\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setRecommended\",\"inputs\":[{\"name\":\"_recommended\",\"type\":\"uint256\",\"internalType\":\"ProtocolVersion\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setRequired\",\"inputs\":[{\"name\":\"_required\",\"type\":\"uint256\",\"internalType\":\"ProtocolVersion\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ConfigUpdate\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumProtocolVersions.UpdateType\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b506200002261dead60008062000028565b6200051c565b600054610100900460ff1615808015620000495750600054600160ff909116105b8062000079575062000066306200017e60201b6200053f1760201c565b15801562000079575060005460ff166001145b620000e25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000106576000805461ff0019166101001790555b620001106200018d565b6200011b84620001f5565b620001268362000274565b620001318262000324565b801562000178576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff16620001e95760405162461bcd60e51b815260206004820152602b602482015260008051602062000f4f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d9565b620001f362000385565b565b620001ff620003ec565b6001600160a01b038116620002665760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620000d9565b620002718162000448565b50565b620002ba620002a560017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16200049e565b60001b826200049a60201b6200055b1760201c565b600081604051602001620002d091815260200190565b60408051601f19818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051620003189190620004c4565b60405180910390a35050565b62000355620002a560017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6200049e565b6000816040516020016200036b91815260200190565b60408051601f1981840301815291905290506001620002e5565b600054610100900460ff16620003e15760405162461bcd60e51b815260206004820152602b602482015260008051602062000f4f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d9565b620001f33362000448565b6033546001600160a01b03163314620001f35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000d9565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b9055565b600082821015620004bf57634e487b7160e01b600052601160045260246000fd5b500390565b600060208083528351808285015260005b81811015620004f357858101830151858201604001528201620004d5565b8181111562000506576000604083870101525b50601f01601f1916929092016040019392505050565b610a23806200052c6000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", } // ProtocolVersionsABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/protocolversions_more.go b/op-bindings/bindings/protocolversions_more.go index d1e40edc5932..7e262a683869 100644 --- a/op-bindings/bindings/protocolversions_more.go +++ b/op-bindings/bindings/protocolversions_more.go @@ -13,7 +13,8 @@ const ProtocolVersionsStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contr var ProtocolVersionsStorageLayout = new(solc.StorageLayout) -var ProtocolVersionsDeployedBin = "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e736600461085d565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161010091906108e1565b6100ec61016036600461085d565b61021d565b6100ec61022e565b6100ec61017b366004610924565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103ad565b6100f66103e6565b6100ec6101c6366004610957565b610416565b6100f66104ca565b6100f6600081565b6101e36104f9565b6101ec8161057a565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b81565b6102256104f9565b6101ec81610632565b6102366104f9565b61024060006106ac565b565b600054600390610100900460ff16158015610264575060005460ff8083169116105b6102f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561032e610723565b61033784610416565b6103408361057a565b61034982610632565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b60006103e16103dd60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b5490565b905090565b60006103e16103dd60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b61041e6104f9565b73ffffffffffffffffffffffffffffffffffffffff81166104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102ec565b6101ec816106ac565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102ec565b6105ad6105a860017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b829055565b6000816040516020016105c291815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161062691906108e1565b60405180910390a35050565b6106606105a860017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b60008160405160200161067591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060016105f5565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240600054610100900460ff16610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240336106ac565b60006020828403121561086f57600080fd5b5035919050565b6000815180845260005b8181101561089c57602081850181015186830182015201610880565b818111156108ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006108f46020830184610876565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091f57600080fd5b919050565b60008060006060848603121561093957600080fd5b610942846108fb565b95602085013595506040909401359392505050565b60006020828403121561096957600080fd5b6108f4826108fb565b6000828210156109ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a" +var ProtocolVersionsDeployedBin = "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(ProtocolVersionsStorageLayoutJSON), ProtocolVersionsStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["ProtocolVersions"] = ProtocolVersionsStorageLayout deployedBytecodes["ProtocolVersions"] = ProtocolVersionsDeployedBin + immutableReferences["ProtocolVersions"] = false } diff --git a/op-bindings/bindings/proxy.go b/op-bindings/bindings/proxy.go index 346a4a33c0ef..a484a8144db3 100644 --- a/op-bindings/bindings/proxy.go +++ b/op-bindings/bindings/proxy.go @@ -30,7 +30,7 @@ var ( // ProxyMetaData contains all meta data concerning the Proxy contract. var ProxyMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"admin\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"changeAdmin\",\"inputs\":[{\"name\":\"_admin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"implementation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeTo\",\"inputs\":[{\"name\":\"_implementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"_implementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", Bin: "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", } diff --git a/op-bindings/bindings/proxy_more.go b/op-bindings/bindings/proxy_more.go index 914f84348cb7..1ed30a48bd53 100644 --- a/op-bindings/bindings/proxy_more.go +++ b/op-bindings/bindings/proxy_more.go @@ -15,6 +15,7 @@ var ProxyStorageLayout = new(solc.StorageLayout) var ProxyDeployedBin = "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(ProxyStorageLayoutJSON), ProxyStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["Proxy"] = ProxyStorageLayout deployedBytecodes["Proxy"] = ProxyDeployedBin + immutableReferences["Proxy"] = false } diff --git a/op-bindings/bindings/proxyadmin.go b/op-bindings/bindings/proxyadmin.go index 100a6490bd75..405a2b91d051 100644 --- a/op-bindings/bindings/proxyadmin.go +++ b/op-bindings/bindings/proxyadmin.go @@ -30,7 +30,7 @@ var ( // ProxyAdminMetaData contains all meta data concerning the ProxyAdmin contract. var ProxyAdminMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"contractAddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"implementationName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"proxyType\",\"outputs\":[{\"internalType\":\"enumProxyAdmin.ProxyType\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAddressManager\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddressManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"setImplementationName\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"enumProxyAdmin.ProxyType\",\"name\":\"_type\",\"type\":\"uint8\"}],\"name\":\"setProxyType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_upgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addressManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractAddressManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"changeProxyAdmin\",\"inputs\":[{\"name\":\"_proxy\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"_newAdmin\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getProxyAdmin\",\"inputs\":[{\"name\":\"_proxy\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getProxyImplementation\",\"inputs\":[{\"name\":\"_proxy\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"implementationName\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isUpgrading\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxyType\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumProxyAdmin.ProxyType\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setAddress\",\"inputs\":[{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_address\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setAddressManager\",\"inputs\":[{\"name\":\"_address\",\"type\":\"address\",\"internalType\":\"contractAddressManager\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setImplementationName\",\"inputs\":[{\"name\":\"_address\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setProxyType\",\"inputs\":[{\"name\":\"_address\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_type\",\"type\":\"uint8\",\"internalType\":\"enumProxyAdmin.ProxyType\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setUpgrading\",\"inputs\":[{\"name\":\"_upgrading\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgrade\",\"inputs\":[{\"name\":\"_proxy\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"_implementation\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeAndCall\",\"inputs\":[{\"name\":\"_proxy\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"_implementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", Bin: "0x60806040523480156200001157600080fd5b5060405162001a5f38038062001a5f8339810160408190526200003491620000a1565b6200003f3362000051565b6200004a8162000051565b50620000d3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208284031215620000b457600080fd5b81516001600160a01b0381168114620000cc57600080fd5b9392505050565b61197c80620000e36000396000f3fe60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/proxyadmin_more.go b/op-bindings/bindings/proxyadmin_more.go index 198b4c15928c..cbd348f21934 100644 --- a/op-bindings/bindings/proxyadmin_more.go +++ b/op-bindings/bindings/proxyadmin_more.go @@ -15,6 +15,7 @@ var ProxyAdminStorageLayout = new(solc.StorageLayout) var ProxyAdminDeployedBin = "0x60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(ProxyAdminStorageLayoutJSON), ProxyAdminStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["ProxyAdmin"] = ProxyAdminStorageLayout deployedBytecodes["ProxyAdmin"] = ProxyAdminDeployedBin + immutableReferences["ProxyAdmin"] = false } diff --git a/op-bindings/bindings/registry.go b/op-bindings/bindings/registry.go index 56977ce52800..32e31e0a3f78 100644 --- a/op-bindings/bindings/registry.go +++ b/op-bindings/bindings/registry.go @@ -4,17 +4,38 @@ import ( "fmt" "strings" + "github.com/ethereum-optimism/superchain-registry/superchain" + "github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum/go-ethereum/common" ) -// layouts respresents the set of storage layouts. It is populated in an init function. +// layouts represents the set of storage layouts. It is populated in an init function. var layouts = make(map[string]*solc.StorageLayout) // deployedBytecodes represents the set of deployed bytecodes. It is populated // in an init function. var deployedBytecodes = make(map[string]string) +var initBytecodes = make(map[string]string) +var deploymentSalts = make(map[string]string) +var deployers = make(map[string]string) + +// immutableReferences represents the set of immutable references. It is populated +// in an init function. +var immutableReferences = make(map[string]bool) + +// Create2DeployerCodeHash represents the codehash of the Create2Deployer contract. +var Create2DeployerCodeHash = common.HexToHash("0xb0550b5b431e30d38000efb7107aaa0ade03d48a7198a140edda9d27134468b2") + +func init() { + code, err := superchain.LoadContractBytecode(superchain.Hash(Create2DeployerCodeHash)) + if err != nil { + panic(err) + } + deployedBytecodes["Create2Deployer"] = common.Bytes2Hex(code) +} + // GetStorageLayout returns the storage layout of a contract by name. func GetStorageLayout(name string) (*solc.StorageLayout, error) { layout := layouts[name] @@ -38,6 +59,54 @@ func GetDeployedBytecode(name string) ([]byte, error) { return common.FromHex(bc), nil } +// HasImmutableReferences returns the immutable references of a contract by name. +func HasImmutableReferences(name string) (bool, error) { + has, ok := immutableReferences[name] + if !ok { + return false, fmt.Errorf("%s: immutable reference not found", name) + } + return has, nil +} + +func GetInitBytecode(name string) ([]byte, error) { + bc := initBytecodes[name] + if bc == "" { + return nil, fmt.Errorf("%s: init bytecode not found", name) + } + + if !isHex(bc) { + return nil, fmt.Errorf("%s: invalid init bytecode", name) + } + + return common.FromHex(bc), nil +} + +func GetDeployerAddress(name string) ([]byte, error) { + addr := deployers[name] + if addr == "" { + return nil, fmt.Errorf("%s: deployer address not found", name) + } + + if !common.IsHexAddress(addr) { + return nil, fmt.Errorf("%s: invalid deployer address", name) + } + + return common.FromHex(addr), nil +} + +func GetDeploymentSalt(name string) ([]byte, error) { + salt := deploymentSalts[name] + if salt == "" { + return nil, fmt.Errorf("%s: deployment salt not found", name) + } + + if !isHex(salt) { + return nil, fmt.Errorf("%s: invalid deployment salt", name) + } + + return common.FromHex(salt), nil +} + // isHexCharacter returns bool of c being a valid hexadecimal. func isHexCharacter(c byte) bool { return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') diff --git a/op-bindings/bindings/safe.go b/op-bindings/bindings/safe.go index 725223954c6f..571d7db4c84f 100644 --- a/op-bindings/bindings/safe.go +++ b/op-bindings/bindings/safe.go @@ -30,7 +30,7 @@ var ( // SafeMetaData contains all meta data concerning the Safe contract. var SafeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"AddedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"approvedHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ApproveHash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"handler\",\"type\":\"address\"}],\"name\":\"ChangedFallbackHandler\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"ChangedGuard\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"name\":\"ChangedThreshold\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"DisabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"EnabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"RemovedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SafeReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"owners\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fallbackHandler\",\"type\":\"address\"}],\"name\":\"SafeSetup\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"SignMsg\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"addOwnerWithThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashToApprove\",\"type\":\"bytes32\"}],\"name\":\"approveHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"approvedHashes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"changeThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredSignatures\",\"type\":\"uint256\"}],\"name\":\"checkNSignatures\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"}],\"name\":\"checkSignatures\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevModule\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"disableModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"enableModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"encodeTransactionData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"}],\"name\":\"execTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModule\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModuleReturnData\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"start\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getModulesPaginated\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"array\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"next\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"getStorageAt\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"getTransactionHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"isModuleEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"removeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"handler\",\"type\":\"address\"}],\"name\":\"setFallbackHandler\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"setGuard\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"fallbackHandler\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"paymentToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"},{\"internalType\":\"addresspayable\",\"name\":\"paymentReceiver\",\"type\":\"address\"}],\"name\":\"setup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"signedMessages\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"calldataPayload\",\"type\":\"bytes\"}],\"name\":\"simulateAndRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"swapOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addOwnerWithThreshold\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"approveHash\",\"inputs\":[{\"name\":\"hashToApprove\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"approvedHashes\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"changeThreshold\",\"inputs\":[{\"name\":\"_threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"checkNSignatures\",\"inputs\":[{\"name\":\"dataHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signatures\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"requiredSignatures\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkSignatures\",\"inputs\":[{\"name\":\"dataHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signatures\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"disableModule\",\"inputs\":[{\"name\":\"prevModule\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"module\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"domainSeparator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"enableModule\",\"inputs\":[{\"name\":\"module\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"encodeTransactionData\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"operation\",\"type\":\"uint8\",\"internalType\":\"enumEnum.Operation\"},{\"name\":\"safeTxGas\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"baseGas\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasPrice\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"refundReceiver\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"execTransaction\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"operation\",\"type\":\"uint8\",\"internalType\":\"enumEnum.Operation\"},{\"name\":\"safeTxGas\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"baseGas\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasPrice\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"refundReceiver\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"signatures\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"success\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"execTransactionFromModule\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"operation\",\"type\":\"uint8\",\"internalType\":\"enumEnum.Operation\"}],\"outputs\":[{\"name\":\"success\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"execTransactionFromModuleReturnData\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"operation\",\"type\":\"uint8\",\"internalType\":\"enumEnum.Operation\"}],\"outputs\":[{\"name\":\"success\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"returnData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getChainId\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getModulesPaginated\",\"inputs\":[{\"name\":\"start\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"pageSize\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"array\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"next\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getOwners\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getStorageAt\",\"inputs\":[{\"name\":\"offset\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"length\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getThreshold\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTransactionHash\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"operation\",\"type\":\"uint8\",\"internalType\":\"enumEnum.Operation\"},{\"name\":\"safeTxGas\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"baseGas\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasPrice\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"refundReceiver\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isModuleEnabled\",\"inputs\":[{\"name\":\"module\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nonce\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"removeOwner\",\"inputs\":[{\"name\":\"prevOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setFallbackHandler\",\"inputs\":[{\"name\":\"handler\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setGuard\",\"inputs\":[{\"name\":\"guard\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setup\",\"inputs\":[{\"name\":\"_owners\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"_threshold\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"fallbackHandler\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"paymentToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"payment\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"paymentReceiver\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"signedMessages\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"simulateAndRevert\",\"inputs\":[{\"name\":\"targetContract\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"calldataPayload\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"swapOwner\",\"inputs\":[{\"name\":\"prevOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"oldOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"AddedOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ApproveHash\",\"inputs\":[{\"name\":\"approvedHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ChangedFallbackHandler\",\"inputs\":[{\"name\":\"handler\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ChangedGuard\",\"inputs\":[{\"name\":\"guard\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ChangedThreshold\",\"inputs\":[{\"name\":\"threshold\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DisabledModule\",\"inputs\":[{\"name\":\"module\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EnabledModule\",\"inputs\":[{\"name\":\"module\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ExecutionFailure\",\"inputs\":[{\"name\":\"txHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"payment\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ExecutionFromModuleFailure\",\"inputs\":[{\"name\":\"module\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ExecutionFromModuleSuccess\",\"inputs\":[{\"name\":\"module\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ExecutionSuccess\",\"inputs\":[{\"name\":\"txHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"payment\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RemovedOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SafeReceived\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SafeSetup\",\"inputs\":[{\"name\":\"initiator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"owners\",\"type\":\"address[]\",\"indexed\":false,\"internalType\":\"address[]\"},{\"name\":\"threshold\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"initializer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"fallbackHandler\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SignMsg\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false}]", Bin: "0x608060405234801561001057600080fd5b506001600455614201806100256000396000f3fe6080604052600436106101d15760003560e01c8063affed0e0116100f7578063e19a9dd911610095578063f08a032311610064578063f08a0323146105f5578063f698da2514610615578063f8dc5dd91461067c578063ffa1ad741461069c5761020d565b8063e19a9dd914610580578063e318b52b146105a0578063e75235b8146105c0578063e86637db146105d55761020d565b8063cc2f8452116100d1578063cc2f8452146104f2578063d4d9bdcd14610520578063d8d11f7814610540578063e009cfde146105605761020d565b8063affed0e01461049c578063b4faba09146104b2578063b63e800d146104d25761020d565b80635624b25b1161016f5780636a7612021161013e5780636a7612021461040f5780637d83297414610422578063934f3a111461045a578063a0e67e2b1461047a5761020d565b80635624b25b146103755780635ae6bd37146103a2578063610b5925146103cf578063694e80c3146103ef5761020d565b80632f54bf6e116101ab5780632f54bf6e146102ea5780633408e4701461030a578063468721a7146103275780635229073f146103475761020d565b80630d582f131461027357806312fb68e0146102955780632d9ad53d146102b55761020d565b3661020d5760405134815233907f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d9060200160405180910390a2005b34801561021957600080fd5b507f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d580548061024457005b36600080373360601b365260008060143601600080855af190503d6000803e8061026d573d6000fd5b503d6000f35b34801561027f57600080fd5b5061029361028e366004613568565b6106e5565b005b3480156102a157600080fd5b506102936102b036600461366e565b610933565b3480156102c157600080fd5b506102d56102d03660046136e3565b610ff7565b60405190151581526020015b60405180910390f35b3480156102f657600080fd5b506102d56103053660046136e3565b61104c565b34801561031657600080fd5b50465b6040519081526020016102e1565b34801561033357600080fd5b506102d561034236600461370f565b61109e565b34801561035357600080fd5b5061036761036236600461370f565b6111d4565b6040516102e19291906137e4565b34801561038157600080fd5b506103956103903660046137ff565b61120a565b6040516102e19190613821565b3480156103ae57600080fd5b506103196103bd366004613834565b60076020526000908152604090205481565b3480156103db57600080fd5b506102936103ea3660046136e3565b611290565b3480156103fb57600080fd5b5061029361040a366004613834565b611479565b6102d561041d366004613896565b611593565b34801561042e57600080fd5b5061031961043d366004613568565b600860209081526000928352604080842090915290825290205481565b34801561046657600080fd5b5061029361047536600461396f565b61198f565b34801561048657600080fd5b5061048f611a0b565b6040516102e19190613a2d565b3480156104a857600080fd5b5061031960055481565b3480156104be57600080fd5b506102936104cd366004613a40565b611b23565b3480156104de57600080fd5b506102936104ed366004613a90565b611b46565b3480156104fe57600080fd5b5061051261050d366004613568565b611c62565b6040516102e1929190613b85565b34801561052c57600080fd5b5061029361053b366004613834565b611ed0565b34801561054c57600080fd5b5061031961055b366004613bbd565b611fa4565b34801561056c57600080fd5b5061029361057b366004613c7e565b611fd1565b34801561058c57600080fd5b5061029361059b3660046136e3565b6121a3565b3480156105ac57600080fd5b506102936105bb366004613cb7565b612344565b3480156105cc57600080fd5b50600454610319565b3480156105e157600080fd5b506103956105f0366004613bbd565b6126bc565b34801561060157600080fd5b506102936106103660046136e3565b612855565b34801561062157600080fd5b5061031960007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b34801561068857600080fd5b50610293610697366004613d02565b6128aa565b3480156106a857600080fd5b506103956040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6106ed612b34565b73ffffffffffffffffffffffffffffffffffffffff821615801590610729575073ffffffffffffffffffffffffffffffffffffffff8216600114155b801561074b575073ffffffffffffffffffffffffffffffffffffffff82163014155b6107b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600260205260409020541615610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b60026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0805473ffffffffffffffffffffffffffffffffffffffff8481166000818152604081208054939094167fffffffffffffffffffffffff0000000000000000000000000000000000000000938416179093556001835283549091161790915560038054916108d783613d72565b909155505060405173ffffffffffffffffffffffffffffffffffffffff8316907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2690600090a2806004541461092f5761092f81611479565b5050565b61093e816041612b9f565b825110156109a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6000808060008060005b86811015610feb576041818102890160208101516040820151919092015160ff16955090935091506000849003610cf857885160208a01208a14610a52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323700000000000000000000000000000000000000000000000000000060448201526064016107ad565b9193508391610a62876041612b9f565b821015610acb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323100000000000000000000000000000000000000000000000000000060448201526064016107ad565b8751610ad8836020612bdb565b1115610b40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323200000000000000000000000000000000000000000000000000000060448201526064016107ad565b602082890181015189519091610b63908390610b5d908790612bdb565b90612bdb565b1115610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323300000000000000000000000000000000000000000000000000000060448201526064016107ad565b6040517f20c13b0b000000000000000000000000000000000000000000000000000000008082528a85016020019173ffffffffffffffffffffffffffffffffffffffff8916906320c13b0b90610c27908f908690600401613daa565b602060405180830381865afa158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c689190613dcf565b7fffffffff000000000000000000000000000000000000000000000000000000001614610cf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323400000000000000000000000000000000000000000000000000000060448201526064016107ad565b5050610eeb565b8360ff16600103610dc65791935083913373ffffffffffffffffffffffffffffffffffffffff84161480610d5b575073ffffffffffffffffffffffffffffffffffffffff851660009081526008602090815260408083208d845290915290205415155b610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323500000000000000000000000000000000000000000000000000000060448201526064016107ad565b610eeb565b601e8460ff161115610e8b576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018b9052600190605c0160405160208183030381529060405280519060200120600486610e2b9190613e11565b6040805160008152602081018083529390935260ff90911690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610e7a573d6000803e3d6000fd5b505050602060405103519450610eeb565b6040805160008152602081018083528c905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610ede573d6000803e3d6000fd5b5050506020604051035194505b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16118015610f4c575073ffffffffffffffffffffffffffffffffffffffff8581166000908152600260205260409020541615155b8015610f6f575073ffffffffffffffffffffffffffffffffffffffff8516600114155b610fd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323600000000000000000000000000000000000000000000000000000060448201526064016107ad565b8495508080610fe390613d72565b9150506109b2565b50505050505050505050565b6000600173ffffffffffffffffffffffffffffffffffffffff831614801590611046575073ffffffffffffffffffffffffffffffffffffffff8281166000908152600160205260409020541615155b92915050565b600073ffffffffffffffffffffffffffffffffffffffff821660011480159061104657505073ffffffffffffffffffffffffffffffffffffffff90811660009081526002602052604090205416151590565b6000336001148015906110d557503360009081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1615155b61113b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b611168858585857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612bf7565b905080156111a05760405133907f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb890600090a26111cc565b60405133907facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37590600090a25b949350505050565b600060606111e48686868661109e565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b60606000611219836020613e34565b67ffffffffffffffff81111561123157611231613594565b6040519080825280601f01601f19166020018201604052801561125b576020820181803683370190505b50905060005b8381101561128857848101546020808302840101528061128081613d72565b915050611261565b509392505050565b611298612b34565b73ffffffffffffffffffffffffffffffffffffffff8116158015906112d4575073ffffffffffffffffffffffffffffffffffffffff8116600114155b61133a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526001602052604090205416156113c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b600160208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f805473ffffffffffffffffffffffffffffffffffffffff848116600081815260408082208054949095167fffffffffffffffffffffffff000000000000000000000000000000000000000094851617909455948552835490911681179092555190917fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844091a250565b611481612b34565b6003548111156114ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001811015611558576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b60048190556040518181527f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c939060200160405180910390a150565b60008060006115ad8e8e8e8e8e8e8e8e8e8e6005546126bc565b6005805491925060006115bf83613d72565b90915550508051602082012091506115d882828661198f565b5060006116037f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c85490565b905073ffffffffffffffffffffffffffffffffffffffff8116156116a3578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b81526004016116709c9b9a99989796959493929190613edb565b600060405180830381600087803b15801561168a57600080fd5b505af115801561169e573d6000803e3d6000fd5b505050505b6116cf6116b28a6109c4613ff1565b603f6116bf8c6040613e34565b6116c99190614009565b90612c3e565b6116db906101f4613ff1565b5a1015611744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313000000000000000000000000000000000000000000000000000000060448201526064016107ad565b60005a90506117b58f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8c6000146117a2578e612bf7565b6109c45a6117b09190614044565b612bf7565b93506117c25a8290612c55565b905083806117cf57508915155b806117d957508715155b61183f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313300000000000000000000000000000000000000000000000000000060448201526064016107ad565b6000881561185757611854828b8b8b8b612c70565b90505b841561189c57837f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8260405161188f91815260200190565b60405180910390a26118d7565b837f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23826040516118ce91815260200190565b60405180910390a25b505073ffffffffffffffffffffffffffffffffffffffff81161561197e576040517f9327136800000000000000000000000000000000000000000000000000000000815260048101839052831515602482015273ffffffffffffffffffffffffffffffffffffffff821690639327136890604401600060405180830381600087803b15801561196557600080fd5b505af1158015611979573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b600454806119f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b611a0584848484610933565b50505050565b6060600060035467ffffffffffffffff811115611a2a57611a2a613594565b604051908082528060200260200182016040528015611a53578160200160208202803683370190505b506001600090815260026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0549192509073ffffffffffffffffffffffffffffffffffffffff165b73ffffffffffffffffffffffffffffffffffffffff8116600114611b1b5780838381518110611ace57611ace61405b565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152918116600090815260029092526040909120541681611b1381613d72565b925050611a9d565b509092915050565b600080825160208401855af480600052503d6020523d600060403e60403d016000fd5b611b848a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508c9250612e01915050565b73ffffffffffffffffffffffffffffffffffffffff841615611ba957611ba9846131ce565b611be98787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061327192505050565b8115611c0057611bfe82600060018685612c70565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b89604051611c4e95949392919061408a565b60405180910390a250505050505050505050565b6060600073ffffffffffffffffffffffffffffffffffffffff841660011480611c8f5750611c8f84610ff7565b611cf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b60008311611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303600000000000000000000000000000000000000000000000000000060448201526064016107ad565b8267ffffffffffffffff811115611d7857611d78613594565b604051908082528060200260200182016040528015611da1578160200160208202803683370190505b5073ffffffffffffffffffffffffffffffffffffffff808616600090815260016020526040812054929450911691505b73ffffffffffffffffffffffffffffffffffffffff821615801590611e0d575073ffffffffffffffffffffffffffffffffffffffff8216600114155b8015611e1857508381105b15611e805781838281518110611e3057611e3061405b565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152928116600090815260019093526040909220549091169080611e7881613d72565b915050611dd1565b73ffffffffffffffffffffffffffffffffffffffff8216600114611ec55782611eaa600183614044565b81518110611eba57611eba61405b565b602002602001015191505b808352509250929050565b3360009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16611f5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333000000000000000000000000000000000000000000000000000000060448201526064016107ad565b336000818152600860209081526040808320858452909152808220600190555183917ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c91a350565b6000611fb98c8c8c8c8c8c8c8c8c8c8c6126bc565b8051906020012090509b9a5050505050505050505050565b611fd9612b34565b73ffffffffffffffffffffffffffffffffffffffff811615801590612015575073ffffffffffffffffffffffffffffffffffffffff8116600114155b61207b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526001602052604090205481169082161461210e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff818116600081815260016020526040808220805487861684528284208054919096167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179095558383528054909416909355915190917faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427691a25050565b6121ab612b34565b73ffffffffffffffffffffffffffffffffffffffff8116156122db576040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fe6d7a83a00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015612251573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122759190614110565b6122db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475333303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b7f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c881815560405173ffffffffffffffffffffffffffffffffffffffff8316907f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa290600090a25050565b61234c612b34565b73ffffffffffffffffffffffffffffffffffffffff811615801590612388575073ffffffffffffffffffffffffffffffffffffffff8116600114155b80156123aa575073ffffffffffffffffffffffffffffffffffffffff81163014155b612410576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260026020526040902054161561249f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8216158015906124db575073ffffffffffffffffffffffffffffffffffffffff8216600114155b612541576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600260205260409020548116908316146125d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260026020526040808220805486861680855283852080549288167fffffffffffffffffffffffff00000000000000000000000000000000000000009384161790559589168452828420805482169096179095558383528054909416909355915190917ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf91a260405173ffffffffffffffffffffffffffffffffffffffff8216907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2690600090a2505050565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d6040516126f6929190614132565b60405190819003812061271c949392918e908e908e908e908e908e908e90602001614142565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012090507f19000000000000000000000000000000000000000000000000000000000000007f01000000000000000000000000000000000000000000000000000000000000006127f060007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b6040517fff0000000000000000000000000000000000000000000000000000000000000093841660208201529290911660218301526022820152604281018290526062016040516020818303038152906040529150509b9a5050505050505050505050565b61285d612b34565b612866816131ce565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b090600090a250565b6128b2612b34565b8060016003546128c29190614044565b101561292a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff821615801590612966575073ffffffffffffffffffffffffffffffffffffffff8216600114155b6129cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260026020526040902054811690831614612a5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260026020526040808220805488861684529183208054929095167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790945591815282549091169091556003805491612ad7836141bf565b909155505060405173ffffffffffffffffffffffffffffffffffffffff8316907ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf90600090a28060045414612b2f57612b2f81611479565b505050565b333014612b9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333100000000000000000000000000000000000000000000000000000060448201526064016107ad565b565b600082600003612bb157506000611046565b6000612bbd8385613e34565b905082612bca8583614009565b14612bd457600080fd5b9392505050565b600080612be88385613ff1565b905083811015612bd457600080fd5b60006001836001811115612c0d57612c0d613e71565b03612c25576000808551602087018986f49050612c35565b600080855160208701888a87f190505b95945050505050565b600081831015612c4e5781612bd4565b5090919050565b600082821115612c6457600080fd5b60006111cc8385614044565b60008073ffffffffffffffffffffffffffffffffffffffff831615612c955782612c97565b325b905073ffffffffffffffffffffffffffffffffffffffff8416612d7657612cd63a8610612cc4573a612cc6565b855b612cd08989612bdb565b90612b9f565b60405190925073ffffffffffffffffffffffffffffffffffffffff82169083156108fc029084906000818181858888f19350505050612d71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313100000000000000000000000000000000000000000000000000000060448201526064016107ad565b612df7565b612d8485612cd08989612bdb565b9150612d91848284613469565b612df7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313200000000000000000000000000000000000000000000000000000060448201526064016107ad565b5095945050505050565b60045415612e6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b8151811115612ed6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001811015612f41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b600160005b8351811015613176576000848281518110612f6357612f6361405b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612fc1575073ffffffffffffffffffffffffffffffffffffffff8116600114155b8015612fe3575073ffffffffffffffffffffffffffffffffffffffff81163014155b801561301b57508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b613081576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600260205260409020541615613110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff928316600090815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016938216939093179092558061316e81613d72565b915050612f46565b5073ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011790559051600355600455565b3073ffffffffffffffffffffffffffffffffffffffff82160361324d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475334303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b7f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d555565b600160008190526020527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5473ffffffffffffffffffffffffffffffffffffffff161561331a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001600081905260208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80547fffffffffffffffffffffffff000000000000000000000000000000000000000016909117905573ffffffffffffffffffffffffffffffffffffffff82161561092f57813b6133f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b6134038260008360015a612bf7565b61092f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6040805173ffffffffffffffffffffffffffffffffffffffff841660248201526044808201849052825180830390910181526064909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781528251600093929184919082896127105a03f13d8015613516576020811461351e5760009350613529565b819350613529565b600051158215171593505b5050509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461355557600080fd5b50565b803561356381613533565b919050565b6000806040838503121561357b57600080fd5b823561358681613533565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126135d457600080fd5b813567ffffffffffffffff808211156135ef576135ef613594565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561363557613635613594565b8160405283815286602085880101111561364e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561368457600080fd5b84359350602085013567ffffffffffffffff808211156136a357600080fd5b6136af888389016135c3565b945060408701359150808211156136c557600080fd5b506136d2878288016135c3565b949793965093946060013593505050565b6000602082840312156136f557600080fd5b8135612bd481613533565b80356002811061356357600080fd5b6000806000806080858703121561372557600080fd5b843561373081613533565b935060208501359250604085013567ffffffffffffffff81111561375357600080fd5b61375f878288016135c3565b92505061376e60608601613700565b905092959194509250565b6000815180845260005b8181101561379f57602081850181015186830182015201613783565b818111156137b1576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b82151581526040602082015260006111cc6040830184613779565b6000806040838503121561381257600080fd5b50508035926020909101359150565b602081526000612bd46020830184613779565b60006020828403121561384657600080fd5b5035919050565b60008083601f84011261385f57600080fd5b50813567ffffffffffffffff81111561387757600080fd5b60208301915083602082850101111561388f57600080fd5b9250929050565b60008060008060008060008060008060006101408c8e0312156138b857600080fd5b6138c18c613558565b9a5060208c0135995067ffffffffffffffff8060408e013511156138e457600080fd5b6138f48e60408f01358f0161384d565b909a50985061390560608e01613700565b975060808d0135965060a08d0135955060c08d0135945061392860e08e01613558565b93506139376101008e01613558565b9250806101208e0135111561394b57600080fd5b5061395d8d6101208e01358e016135c3565b90509295989b509295989b9093969950565b60008060006060848603121561398457600080fd5b83359250602084013567ffffffffffffffff808211156139a357600080fd5b6139af878388016135c3565b935060408601359150808211156139c557600080fd5b506139d2868287016135c3565b9150509250925092565b600081518084526020808501945080840160005b83811015613a2257815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016139f0565b509495945050505050565b602081526000612bd460208301846139dc565b60008060408385031215613a5357600080fd5b8235613a5e81613533565b9150602083013567ffffffffffffffff811115613a7a57600080fd5b613a86858286016135c3565b9150509250929050565b6000806000806000806000806000806101008b8d031215613ab057600080fd5b8a3567ffffffffffffffff80821115613ac857600080fd5b818d0191508d601f830112613adc57600080fd5b813581811115613aeb57600080fd5b8e60208260051b8501011115613b0057600080fd5b60208381019d50909b508d01359950613b1b60408e01613558565b985060608d0135915080821115613b3157600080fd5b50613b3e8d828e0161384d565b9097509550613b51905060808c01613558565b9350613b5f60a08c01613558565b925060c08b01359150613b7460e08c01613558565b90509295989b9194979a5092959850565b604081526000613b9860408301856139dc565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b60008060008060008060008060008060006101408c8e031215613bdf57600080fd5b8b35613bea81613533565b9a5060208c0135995060408c013567ffffffffffffffff811115613c0d57600080fd5b613c198e828f0161384d565b909a509850613c2c905060608d01613700565b965060808c0135955060a08c0135945060c08c0135935060e08c0135613c5181613533565b92506101008c0135613c6281613533565b809250506101208c013590509295989b509295989b9093969950565b60008060408385031215613c9157600080fd5b8235613c9c81613533565b91506020830135613cac81613533565b809150509250929050565b600080600060608486031215613ccc57600080fd5b8335613cd781613533565b92506020840135613ce781613533565b91506040840135613cf781613533565b809150509250925092565b600080600060608486031215613d1757600080fd5b8335613d2281613533565b92506020840135613d3281613533565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613da357613da3613d43565b5060010190565b604081526000613dbd6040830185613779565b8281036020840152612c358185613779565b600060208284031215613de157600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114612bd457600080fd5b600060ff821660ff841680821015613e2b57613e2b613d43565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613e6c57613e6c613d43565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613ed7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b600061016073ffffffffffffffffffffffffffffffffffffffff8f1683528d60208401528060408401528b81840152506101808b8d828501376000818d850101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8d01168301613f51606085018d613ea0565b8a60808501528960a08501528860c0850152613f8560e085018973ffffffffffffffffffffffffffffffffffffffff169052565b73ffffffffffffffffffffffffffffffffffffffff87166101008501528184820301610120850152613fb982820187613779565b92505050613fe061014083018473ffffffffffffffffffffffffffffffffffffffff169052565b9d9c50505050505050505050505050565b6000821982111561400457614004613d43565b500190565b60008261403f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008282101561405657614056613d43565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6080808252810185905260008660a08301825b888110156140da5782356140b081613533565b73ffffffffffffffffffffffffffffffffffffffff1682526020928301929091019060010161409d565b506020840196909652505073ffffffffffffffffffffffffffffffffffffffff9283166040820152911660609091015292915050565b60006020828403121561412257600080fd5b81518015158114612bd457600080fd5b8183823760009101908152919050565b6000610160820190508c825273ffffffffffffffffffffffffffffffffffffffff808d1660208401528b60408401528a6060840152614184608084018b613ea0565b60a083019890985260c082019690965260e0810194909452918516610100840152909316610120820152610140019190915295945050505050565b6000816141ce576141ce613d43565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/safe_more.go b/op-bindings/bindings/safe_more.go index bbdbc7b93fb2..b67a15791450 100644 --- a/op-bindings/bindings/safe_more.go +++ b/op-bindings/bindings/safe_more.go @@ -15,6 +15,7 @@ var SafeStorageLayout = new(solc.StorageLayout) var SafeDeployedBin = "0x6080604052600436106101d15760003560e01c8063affed0e0116100f7578063e19a9dd911610095578063f08a032311610064578063f08a0323146105f5578063f698da2514610615578063f8dc5dd91461067c578063ffa1ad741461069c5761020d565b8063e19a9dd914610580578063e318b52b146105a0578063e75235b8146105c0578063e86637db146105d55761020d565b8063cc2f8452116100d1578063cc2f8452146104f2578063d4d9bdcd14610520578063d8d11f7814610540578063e009cfde146105605761020d565b8063affed0e01461049c578063b4faba09146104b2578063b63e800d146104d25761020d565b80635624b25b1161016f5780636a7612021161013e5780636a7612021461040f5780637d83297414610422578063934f3a111461045a578063a0e67e2b1461047a5761020d565b80635624b25b146103755780635ae6bd37146103a2578063610b5925146103cf578063694e80c3146103ef5761020d565b80632f54bf6e116101ab5780632f54bf6e146102ea5780633408e4701461030a578063468721a7146103275780635229073f146103475761020d565b80630d582f131461027357806312fb68e0146102955780632d9ad53d146102b55761020d565b3661020d5760405134815233907f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d9060200160405180910390a2005b34801561021957600080fd5b507f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d580548061024457005b36600080373360601b365260008060143601600080855af190503d6000803e8061026d573d6000fd5b503d6000f35b34801561027f57600080fd5b5061029361028e366004613568565b6106e5565b005b3480156102a157600080fd5b506102936102b036600461366e565b610933565b3480156102c157600080fd5b506102d56102d03660046136e3565b610ff7565b60405190151581526020015b60405180910390f35b3480156102f657600080fd5b506102d56103053660046136e3565b61104c565b34801561031657600080fd5b50465b6040519081526020016102e1565b34801561033357600080fd5b506102d561034236600461370f565b61109e565b34801561035357600080fd5b5061036761036236600461370f565b6111d4565b6040516102e19291906137e4565b34801561038157600080fd5b506103956103903660046137ff565b61120a565b6040516102e19190613821565b3480156103ae57600080fd5b506103196103bd366004613834565b60076020526000908152604090205481565b3480156103db57600080fd5b506102936103ea3660046136e3565b611290565b3480156103fb57600080fd5b5061029361040a366004613834565b611479565b6102d561041d366004613896565b611593565b34801561042e57600080fd5b5061031961043d366004613568565b600860209081526000928352604080842090915290825290205481565b34801561046657600080fd5b5061029361047536600461396f565b61198f565b34801561048657600080fd5b5061048f611a0b565b6040516102e19190613a2d565b3480156104a857600080fd5b5061031960055481565b3480156104be57600080fd5b506102936104cd366004613a40565b611b23565b3480156104de57600080fd5b506102936104ed366004613a90565b611b46565b3480156104fe57600080fd5b5061051261050d366004613568565b611c62565b6040516102e1929190613b85565b34801561052c57600080fd5b5061029361053b366004613834565b611ed0565b34801561054c57600080fd5b5061031961055b366004613bbd565b611fa4565b34801561056c57600080fd5b5061029361057b366004613c7e565b611fd1565b34801561058c57600080fd5b5061029361059b3660046136e3565b6121a3565b3480156105ac57600080fd5b506102936105bb366004613cb7565b612344565b3480156105cc57600080fd5b50600454610319565b3480156105e157600080fd5b506103956105f0366004613bbd565b6126bc565b34801561060157600080fd5b506102936106103660046136e3565b612855565b34801561062157600080fd5b5061031960007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b34801561068857600080fd5b50610293610697366004613d02565b6128aa565b3480156106a857600080fd5b506103956040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6106ed612b34565b73ffffffffffffffffffffffffffffffffffffffff821615801590610729575073ffffffffffffffffffffffffffffffffffffffff8216600114155b801561074b575073ffffffffffffffffffffffffffffffffffffffff82163014155b6107b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600260205260409020541615610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b60026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0805473ffffffffffffffffffffffffffffffffffffffff8481166000818152604081208054939094167fffffffffffffffffffffffff0000000000000000000000000000000000000000938416179093556001835283549091161790915560038054916108d783613d72565b909155505060405173ffffffffffffffffffffffffffffffffffffffff8316907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2690600090a2806004541461092f5761092f81611479565b5050565b61093e816041612b9f565b825110156109a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6000808060008060005b86811015610feb576041818102890160208101516040820151919092015160ff16955090935091506000849003610cf857885160208a01208a14610a52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323700000000000000000000000000000000000000000000000000000060448201526064016107ad565b9193508391610a62876041612b9f565b821015610acb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323100000000000000000000000000000000000000000000000000000060448201526064016107ad565b8751610ad8836020612bdb565b1115610b40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323200000000000000000000000000000000000000000000000000000060448201526064016107ad565b602082890181015189519091610b63908390610b5d908790612bdb565b90612bdb565b1115610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323300000000000000000000000000000000000000000000000000000060448201526064016107ad565b6040517f20c13b0b000000000000000000000000000000000000000000000000000000008082528a85016020019173ffffffffffffffffffffffffffffffffffffffff8916906320c13b0b90610c27908f908690600401613daa565b602060405180830381865afa158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c689190613dcf565b7fffffffff000000000000000000000000000000000000000000000000000000001614610cf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323400000000000000000000000000000000000000000000000000000060448201526064016107ad565b5050610eeb565b8360ff16600103610dc65791935083913373ffffffffffffffffffffffffffffffffffffffff84161480610d5b575073ffffffffffffffffffffffffffffffffffffffff851660009081526008602090815260408083208d845290915290205415155b610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323500000000000000000000000000000000000000000000000000000060448201526064016107ad565b610eeb565b601e8460ff161115610e8b576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018b9052600190605c0160405160208183030381529060405280519060200120600486610e2b9190613e11565b6040805160008152602081018083529390935260ff90911690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610e7a573d6000803e3d6000fd5b505050602060405103519450610eeb565b6040805160008152602081018083528c905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610ede573d6000803e3d6000fd5b5050506020604051035194505b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16118015610f4c575073ffffffffffffffffffffffffffffffffffffffff8581166000908152600260205260409020541615155b8015610f6f575073ffffffffffffffffffffffffffffffffffffffff8516600114155b610fd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323600000000000000000000000000000000000000000000000000000060448201526064016107ad565b8495508080610fe390613d72565b9150506109b2565b50505050505050505050565b6000600173ffffffffffffffffffffffffffffffffffffffff831614801590611046575073ffffffffffffffffffffffffffffffffffffffff8281166000908152600160205260409020541615155b92915050565b600073ffffffffffffffffffffffffffffffffffffffff821660011480159061104657505073ffffffffffffffffffffffffffffffffffffffff90811660009081526002602052604090205416151590565b6000336001148015906110d557503360009081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1615155b61113b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b611168858585857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612bf7565b905080156111a05760405133907f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb890600090a26111cc565b60405133907facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37590600090a25b949350505050565b600060606111e48686868661109e565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b60606000611219836020613e34565b67ffffffffffffffff81111561123157611231613594565b6040519080825280601f01601f19166020018201604052801561125b576020820181803683370190505b50905060005b8381101561128857848101546020808302840101528061128081613d72565b915050611261565b509392505050565b611298612b34565b73ffffffffffffffffffffffffffffffffffffffff8116158015906112d4575073ffffffffffffffffffffffffffffffffffffffff8116600114155b61133a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526001602052604090205416156113c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b600160208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f805473ffffffffffffffffffffffffffffffffffffffff848116600081815260408082208054949095167fffffffffffffffffffffffff000000000000000000000000000000000000000094851617909455948552835490911681179092555190917fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844091a250565b611481612b34565b6003548111156114ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001811015611558576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b60048190556040518181527f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c939060200160405180910390a150565b60008060006115ad8e8e8e8e8e8e8e8e8e8e6005546126bc565b6005805491925060006115bf83613d72565b90915550508051602082012091506115d882828661198f565b5060006116037f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c85490565b905073ffffffffffffffffffffffffffffffffffffffff8116156116a3578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b81526004016116709c9b9a99989796959493929190613edb565b600060405180830381600087803b15801561168a57600080fd5b505af115801561169e573d6000803e3d6000fd5b505050505b6116cf6116b28a6109c4613ff1565b603f6116bf8c6040613e34565b6116c99190614009565b90612c3e565b6116db906101f4613ff1565b5a1015611744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313000000000000000000000000000000000000000000000000000000060448201526064016107ad565b60005a90506117b58f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8c6000146117a2578e612bf7565b6109c45a6117b09190614044565b612bf7565b93506117c25a8290612c55565b905083806117cf57508915155b806117d957508715155b61183f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313300000000000000000000000000000000000000000000000000000060448201526064016107ad565b6000881561185757611854828b8b8b8b612c70565b90505b841561189c57837f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8260405161188f91815260200190565b60405180910390a26118d7565b837f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23826040516118ce91815260200190565b60405180910390a25b505073ffffffffffffffffffffffffffffffffffffffff81161561197e576040517f9327136800000000000000000000000000000000000000000000000000000000815260048101839052831515602482015273ffffffffffffffffffffffffffffffffffffffff821690639327136890604401600060405180830381600087803b15801561196557600080fd5b505af1158015611979573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b600454806119f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b611a0584848484610933565b50505050565b6060600060035467ffffffffffffffff811115611a2a57611a2a613594565b604051908082528060200260200182016040528015611a53578160200160208202803683370190505b506001600090815260026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0549192509073ffffffffffffffffffffffffffffffffffffffff165b73ffffffffffffffffffffffffffffffffffffffff8116600114611b1b5780838381518110611ace57611ace61405b565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152918116600090815260029092526040909120541681611b1381613d72565b925050611a9d565b509092915050565b600080825160208401855af480600052503d6020523d600060403e60403d016000fd5b611b848a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508c9250612e01915050565b73ffffffffffffffffffffffffffffffffffffffff841615611ba957611ba9846131ce565b611be98787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061327192505050565b8115611c0057611bfe82600060018685612c70565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b89604051611c4e95949392919061408a565b60405180910390a250505050505050505050565b6060600073ffffffffffffffffffffffffffffffffffffffff841660011480611c8f5750611c8f84610ff7565b611cf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b60008311611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303600000000000000000000000000000000000000000000000000000060448201526064016107ad565b8267ffffffffffffffff811115611d7857611d78613594565b604051908082528060200260200182016040528015611da1578160200160208202803683370190505b5073ffffffffffffffffffffffffffffffffffffffff808616600090815260016020526040812054929450911691505b73ffffffffffffffffffffffffffffffffffffffff821615801590611e0d575073ffffffffffffffffffffffffffffffffffffffff8216600114155b8015611e1857508381105b15611e805781838281518110611e3057611e3061405b565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152928116600090815260019093526040909220549091169080611e7881613d72565b915050611dd1565b73ffffffffffffffffffffffffffffffffffffffff8216600114611ec55782611eaa600183614044565b81518110611eba57611eba61405b565b602002602001015191505b808352509250929050565b3360009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16611f5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333000000000000000000000000000000000000000000000000000000060448201526064016107ad565b336000818152600860209081526040808320858452909152808220600190555183917ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c91a350565b6000611fb98c8c8c8c8c8c8c8c8c8c8c6126bc565b8051906020012090509b9a5050505050505050505050565b611fd9612b34565b73ffffffffffffffffffffffffffffffffffffffff811615801590612015575073ffffffffffffffffffffffffffffffffffffffff8116600114155b61207b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526001602052604090205481169082161461210e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff818116600081815260016020526040808220805487861684528284208054919096167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179095558383528054909416909355915190917faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427691a25050565b6121ab612b34565b73ffffffffffffffffffffffffffffffffffffffff8116156122db576040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fe6d7a83a00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015612251573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122759190614110565b6122db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475333303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b7f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c881815560405173ffffffffffffffffffffffffffffffffffffffff8316907f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa290600090a25050565b61234c612b34565b73ffffffffffffffffffffffffffffffffffffffff811615801590612388575073ffffffffffffffffffffffffffffffffffffffff8116600114155b80156123aa575073ffffffffffffffffffffffffffffffffffffffff81163014155b612410576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260026020526040902054161561249f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8216158015906124db575073ffffffffffffffffffffffffffffffffffffffff8216600114155b612541576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600260205260409020548116908316146125d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260026020526040808220805486861680855283852080549288167fffffffffffffffffffffffff00000000000000000000000000000000000000009384161790559589168452828420805482169096179095558383528054909416909355915190917ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf91a260405173ffffffffffffffffffffffffffffffffffffffff8216907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2690600090a2505050565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d6040516126f6929190614132565b60405190819003812061271c949392918e908e908e908e908e908e908e90602001614142565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012090507f19000000000000000000000000000000000000000000000000000000000000007f01000000000000000000000000000000000000000000000000000000000000006127f060007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b6040517fff0000000000000000000000000000000000000000000000000000000000000093841660208201529290911660218301526022820152604281018290526062016040516020818303038152906040529150509b9a5050505050505050505050565b61285d612b34565b612866816131ce565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b090600090a250565b6128b2612b34565b8060016003546128c29190614044565b101561292a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff821615801590612966575073ffffffffffffffffffffffffffffffffffffffff8216600114155b6129cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260026020526040902054811690831614612a5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260026020526040808220805488861684529183208054929095167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790945591815282549091169091556003805491612ad7836141bf565b909155505060405173ffffffffffffffffffffffffffffffffffffffff8316907ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf90600090a28060045414612b2f57612b2f81611479565b505050565b333014612b9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333100000000000000000000000000000000000000000000000000000060448201526064016107ad565b565b600082600003612bb157506000611046565b6000612bbd8385613e34565b905082612bca8583614009565b14612bd457600080fd5b9392505050565b600080612be88385613ff1565b905083811015612bd457600080fd5b60006001836001811115612c0d57612c0d613e71565b03612c25576000808551602087018986f49050612c35565b600080855160208701888a87f190505b95945050505050565b600081831015612c4e5781612bd4565b5090919050565b600082821115612c6457600080fd5b60006111cc8385614044565b60008073ffffffffffffffffffffffffffffffffffffffff831615612c955782612c97565b325b905073ffffffffffffffffffffffffffffffffffffffff8416612d7657612cd63a8610612cc4573a612cc6565b855b612cd08989612bdb565b90612b9f565b60405190925073ffffffffffffffffffffffffffffffffffffffff82169083156108fc029084906000818181858888f19350505050612d71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313100000000000000000000000000000000000000000000000000000060448201526064016107ad565b612df7565b612d8485612cd08989612bdb565b9150612d91848284613469565b612df7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313200000000000000000000000000000000000000000000000000000060448201526064016107ad565b5095945050505050565b60045415612e6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b8151811115612ed6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001811015612f41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b600160005b8351811015613176576000848281518110612f6357612f6361405b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612fc1575073ffffffffffffffffffffffffffffffffffffffff8116600114155b8015612fe3575073ffffffffffffffffffffffffffffffffffffffff81163014155b801561301b57508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b613081576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600260205260409020541615613110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff928316600090815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016938216939093179092558061316e81613d72565b915050612f46565b5073ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011790559051600355600455565b3073ffffffffffffffffffffffffffffffffffffffff82160361324d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475334303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b7f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d555565b600160008190526020527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5473ffffffffffffffffffffffffffffffffffffffff161561331a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001600081905260208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80547fffffffffffffffffffffffff000000000000000000000000000000000000000016909117905573ffffffffffffffffffffffffffffffffffffffff82161561092f57813b6133f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b6134038260008360015a612bf7565b61092f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6040805173ffffffffffffffffffffffffffffffffffffffff841660248201526044808201849052825180830390910181526064909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781528251600093929184919082896127105a03f13d8015613516576020811461351e5760009350613529565b819350613529565b600051158215171593505b5050509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461355557600080fd5b50565b803561356381613533565b919050565b6000806040838503121561357b57600080fd5b823561358681613533565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126135d457600080fd5b813567ffffffffffffffff808211156135ef576135ef613594565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561363557613635613594565b8160405283815286602085880101111561364e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561368457600080fd5b84359350602085013567ffffffffffffffff808211156136a357600080fd5b6136af888389016135c3565b945060408701359150808211156136c557600080fd5b506136d2878288016135c3565b949793965093946060013593505050565b6000602082840312156136f557600080fd5b8135612bd481613533565b80356002811061356357600080fd5b6000806000806080858703121561372557600080fd5b843561373081613533565b935060208501359250604085013567ffffffffffffffff81111561375357600080fd5b61375f878288016135c3565b92505061376e60608601613700565b905092959194509250565b6000815180845260005b8181101561379f57602081850181015186830182015201613783565b818111156137b1576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b82151581526040602082015260006111cc6040830184613779565b6000806040838503121561381257600080fd5b50508035926020909101359150565b602081526000612bd46020830184613779565b60006020828403121561384657600080fd5b5035919050565b60008083601f84011261385f57600080fd5b50813567ffffffffffffffff81111561387757600080fd5b60208301915083602082850101111561388f57600080fd5b9250929050565b60008060008060008060008060008060006101408c8e0312156138b857600080fd5b6138c18c613558565b9a5060208c0135995067ffffffffffffffff8060408e013511156138e457600080fd5b6138f48e60408f01358f0161384d565b909a50985061390560608e01613700565b975060808d0135965060a08d0135955060c08d0135945061392860e08e01613558565b93506139376101008e01613558565b9250806101208e0135111561394b57600080fd5b5061395d8d6101208e01358e016135c3565b90509295989b509295989b9093969950565b60008060006060848603121561398457600080fd5b83359250602084013567ffffffffffffffff808211156139a357600080fd5b6139af878388016135c3565b935060408601359150808211156139c557600080fd5b506139d2868287016135c3565b9150509250925092565b600081518084526020808501945080840160005b83811015613a2257815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016139f0565b509495945050505050565b602081526000612bd460208301846139dc565b60008060408385031215613a5357600080fd5b8235613a5e81613533565b9150602083013567ffffffffffffffff811115613a7a57600080fd5b613a86858286016135c3565b9150509250929050565b6000806000806000806000806000806101008b8d031215613ab057600080fd5b8a3567ffffffffffffffff80821115613ac857600080fd5b818d0191508d601f830112613adc57600080fd5b813581811115613aeb57600080fd5b8e60208260051b8501011115613b0057600080fd5b60208381019d50909b508d01359950613b1b60408e01613558565b985060608d0135915080821115613b3157600080fd5b50613b3e8d828e0161384d565b9097509550613b51905060808c01613558565b9350613b5f60a08c01613558565b925060c08b01359150613b7460e08c01613558565b90509295989b9194979a5092959850565b604081526000613b9860408301856139dc565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b60008060008060008060008060008060006101408c8e031215613bdf57600080fd5b8b35613bea81613533565b9a5060208c0135995060408c013567ffffffffffffffff811115613c0d57600080fd5b613c198e828f0161384d565b909a509850613c2c905060608d01613700565b965060808c0135955060a08c0135945060c08c0135935060e08c0135613c5181613533565b92506101008c0135613c6281613533565b809250506101208c013590509295989b509295989b9093969950565b60008060408385031215613c9157600080fd5b8235613c9c81613533565b91506020830135613cac81613533565b809150509250929050565b600080600060608486031215613ccc57600080fd5b8335613cd781613533565b92506020840135613ce781613533565b91506040840135613cf781613533565b809150509250925092565b600080600060608486031215613d1757600080fd5b8335613d2281613533565b92506020840135613d3281613533565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613da357613da3613d43565b5060010190565b604081526000613dbd6040830185613779565b8281036020840152612c358185613779565b600060208284031215613de157600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114612bd457600080fd5b600060ff821660ff841680821015613e2b57613e2b613d43565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613e6c57613e6c613d43565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613ed7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b600061016073ffffffffffffffffffffffffffffffffffffffff8f1683528d60208401528060408401528b81840152506101808b8d828501376000818d850101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8d01168301613f51606085018d613ea0565b8a60808501528960a08501528860c0850152613f8560e085018973ffffffffffffffffffffffffffffffffffffffff169052565b73ffffffffffffffffffffffffffffffffffffffff87166101008501528184820301610120850152613fb982820187613779565b92505050613fe061014083018473ffffffffffffffffffffffffffffffffffffffff169052565b9d9c50505050505050505050505050565b6000821982111561400457614004613d43565b500190565b60008261403f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008282101561405657614056613d43565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6080808252810185905260008660a08301825b888110156140da5782356140b081613533565b73ffffffffffffffffffffffffffffffffffffffff1682526020928301929091019060010161409d565b506020840196909652505073ffffffffffffffffffffffffffffffffffffffff9283166040820152911660609091015292915050565b60006020828403121561412257600080fd5b81518015158114612bd457600080fd5b8183823760009101908152919050565b6000610160820190508c825273ffffffffffffffffffffffffffffffffffffffff808d1660208401528b60408401528a6060840152614184608084018b613ea0565b60a083019890985260c082019690965260e0810194909452918516610100840152909316610120820152610140019190915295945050505050565b6000816141ce576141ce613d43565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(SafeStorageLayoutJSON), SafeStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["Safe"] = SafeStorageLayout deployedBytecodes["Safe"] = SafeDeployedBin + immutableReferences["Safe"] = false } diff --git a/op-bindings/bindings/safe_v130.go b/op-bindings/bindings/safe_v130.go new file mode 100644 index 000000000000..29a162a41235 --- /dev/null +++ b/op-bindings/bindings/safe_v130.go @@ -0,0 +1,3151 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// SafeV130MetaData contains all meta data concerning the SafeV130 contract. +var SafeV130MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"AddedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"approvedHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ApproveHash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"handler\",\"type\":\"address\"}],\"name\":\"ChangedFallbackHandler\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"ChangedGuard\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"name\":\"ChangedThreshold\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"DisabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"EnabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"RemovedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SafeReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"owners\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fallbackHandler\",\"type\":\"address\"}],\"name\":\"SafeSetup\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"SignMsg\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"addOwnerWithThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashToApprove\",\"type\":\"bytes32\"}],\"name\":\"approveHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"approvedHashes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"changeThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredSignatures\",\"type\":\"uint256\"}],\"name\":\"checkNSignatures\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"}],\"name\":\"checkSignatures\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevModule\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"disableModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"enableModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"encodeTransactionData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"}],\"name\":\"execTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModule\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModuleReturnData\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"start\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getModulesPaginated\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"array\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"next\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"getStorageAt\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"getTransactionHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"isModuleEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"removeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"requiredTxGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"handler\",\"type\":\"address\"}],\"name\":\"setFallbackHandler\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"setGuard\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"fallbackHandler\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"paymentToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"},{\"internalType\":\"addresspayable\",\"name\":\"paymentReceiver\",\"type\":\"address\"}],\"name\":\"setup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"signedMessages\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"calldataPayload\",\"type\":\"bytes\"}],\"name\":\"simulateAndRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"swapOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561001057600080fd5b5060016004819055506159ae80620000296000396000f3fe6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506127d7565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b81019080803590602001909291908035906020019092919050505061280d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b8101908080359060200190929190505050612894565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128ac565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612c3e565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d78565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506132b5565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506132da565b005b348015610d3457600080fd5b50610d3d613369565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613512565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613518565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061353a565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff1690602001909291905050506136f8565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613820565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613a12565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613bb1565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bde565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f6f565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ff3565b005b34801561148957600080fd5b50611492614665565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061466f565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614817565b005b3480156116a457600080fd5b506116ad614878565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506148f6565b005b34801561174a57600080fd5b50611753614d29565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612c3e565b5b5050565b611bd2604182614e0590919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614e3f565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614e0590919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614e6e90919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614e6e90919063ffffffff16565b614e6e90919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156126bc5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b61272e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61273b858585855a614e8d565b9050801561278b573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a26127cf565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b600060606127e7868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561282b57600080fd5b506040519080825280601f01601f19166020018201604052801561285e5781602001600182028036833780820191505090505b50905060005b8381101561288957808501548060208302602085010152508080600101915050612864565b508091505092915050565b60076020528060005260406000206000915090505481565b6128b4614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561291e5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612a91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612c46614d62565b600354811115612cbe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612d35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000806000612d928e8e8e8e8e8e8e8e8e8e60055461466f565b905060056000815480929190600101919050555080805190602001209150612dbb8282866132da565b506000612dc6614ed9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612fac578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612e6957fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015612f3b578082015181840152602081019050612f20565b50505050905090810190601f168015612f685780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015612f9357600080fd5b505af1158015612fa7573d6000803e3d6000fd5b505050505b6101f4612fd36109c48b01603f60408d0281612fc457fe5b04614f0a90919063ffffffff16565b015a1015613049576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506130b28f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d146130a7578e6130ad565b6109c45a035b614e8d565b93506130c75a82614f2490919063ffffffff16565b905083806130d6575060008a14155b806130e2575060008814155b613154576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008089111561316e5761316b828b8b8b8b614f44565b90505b84156131b8577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a16131f8565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146132a4578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561328b57600080fd5b505af115801561329f573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111613357576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61336384848484611bbe565b50505050565b6060600060035467ffffffffffffffff8111801561338657600080fd5b506040519080825280602002602001820160405280156133b55781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613509578083838151811061346057fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061341f565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6135858a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508961514a565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146135c3576135c28461564a565b5b6136118787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615679565b600082111561362b5761362982600060018685614f44565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061374f878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a614e8d565b61375857600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156137e55780820151818401526020810190506137ca565b50505050905090810190601f1680156138125780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561383b57600080fd5b5060405190808252806020026020018201604052801561386a5781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561393d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561394857508482105b15613a03578084838151811061395a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506138d3565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613b14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613bc68c8c8c8c8c8c8c8c8c8c8c61466f565b8051906020012090509b9a5050505050505050505050565b613be6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c505750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613cc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613dc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f77614d62565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613ffb614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156140655750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561409d57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61410f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614210576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561427a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6142ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561470057fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b61478c614878565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61481f614d62565b6148288161564a565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6148a66125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b6148fe614d62565b806001600354031015614979576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156149e35750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614b55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614d2457614d2381612c3e565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614e03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614e185760009050614e39565b6000828402905082848281614e2957fe5b0414614e3457600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614e8357600080fd5b8091505092915050565b6000600180811115614e9b57fe5b836001811115614ea757fe5b1415614ec0576000808551602087018986f49050614ed0565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015614f1a5781614f1c565b825b905092915050565b600082821115614f3357600080fd5b600082840390508091505092915050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614614f815782614f83565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561509b57614fed3a8610614fca573a614fcc565b855b614fdf888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615096576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615140565b6150c0856150b2888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91506150cd8482846158b4565b61513f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600454146151c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615239576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156152b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156155b65760008482815181106152d057fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153445750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561537c57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156153b457508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b615426576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506152b9565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461577b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146158b05761583d8260008360015a614e8d565b6158af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d6000811461595b5760208114615963576000935061596e565b81935061596e565b600051158215171593505b505050939250505056fea26469706673582212203874bcf92e1722cc7bfa0cef1a0985cf0dc3485ba0663db3747ccdf1605df53464736f6c63430007060033", +} + +// SafeV130ABI is the input ABI used to generate the binding from. +// Deprecated: Use SafeV130MetaData.ABI instead. +var SafeV130ABI = SafeV130MetaData.ABI + +// SafeV130Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SafeV130MetaData.Bin instead. +var SafeV130Bin = SafeV130MetaData.Bin + +// DeploySafeV130 deploys a new Ethereum contract, binding an instance of SafeV130 to it. +func DeploySafeV130(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SafeV130, error) { + parsed, err := SafeV130MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SafeV130Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &SafeV130{SafeV130Caller: SafeV130Caller{contract: contract}, SafeV130Transactor: SafeV130Transactor{contract: contract}, SafeV130Filterer: SafeV130Filterer{contract: contract}}, nil +} + +// SafeV130 is an auto generated Go binding around an Ethereum contract. +type SafeV130 struct { + SafeV130Caller // Read-only binding to the contract + SafeV130Transactor // Write-only binding to the contract + SafeV130Filterer // Log filterer for contract events +} + +// SafeV130Caller is an auto generated read-only Go binding around an Ethereum contract. +type SafeV130Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeV130Transactor is an auto generated write-only Go binding around an Ethereum contract. +type SafeV130Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeV130Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SafeV130Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeV130Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type SafeV130Session struct { + Contract *SafeV130 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SafeV130CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type SafeV130CallerSession struct { + Contract *SafeV130Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// SafeV130TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type SafeV130TransactorSession struct { + Contract *SafeV130Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SafeV130Raw is an auto generated low-level Go binding around an Ethereum contract. +type SafeV130Raw struct { + Contract *SafeV130 // Generic contract binding to access the raw methods on +} + +// SafeV130CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SafeV130CallerRaw struct { + Contract *SafeV130Caller // Generic read-only contract binding to access the raw methods on +} + +// SafeV130TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SafeV130TransactorRaw struct { + Contract *SafeV130Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewSafeV130 creates a new instance of SafeV130, bound to a specific deployed contract. +func NewSafeV130(address common.Address, backend bind.ContractBackend) (*SafeV130, error) { + contract, err := bindSafeV130(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &SafeV130{SafeV130Caller: SafeV130Caller{contract: contract}, SafeV130Transactor: SafeV130Transactor{contract: contract}, SafeV130Filterer: SafeV130Filterer{contract: contract}}, nil +} + +// NewSafeV130Caller creates a new read-only instance of SafeV130, bound to a specific deployed contract. +func NewSafeV130Caller(address common.Address, caller bind.ContractCaller) (*SafeV130Caller, error) { + contract, err := bindSafeV130(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &SafeV130Caller{contract: contract}, nil +} + +// NewSafeV130Transactor creates a new write-only instance of SafeV130, bound to a specific deployed contract. +func NewSafeV130Transactor(address common.Address, transactor bind.ContractTransactor) (*SafeV130Transactor, error) { + contract, err := bindSafeV130(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &SafeV130Transactor{contract: contract}, nil +} + +// NewSafeV130Filterer creates a new log filterer instance of SafeV130, bound to a specific deployed contract. +func NewSafeV130Filterer(address common.Address, filterer bind.ContractFilterer) (*SafeV130Filterer, error) { + contract, err := bindSafeV130(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &SafeV130Filterer{contract: contract}, nil +} + +// bindSafeV130 binds a generic wrapper to an already deployed contract. +func bindSafeV130(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SafeV130ABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SafeV130 *SafeV130Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SafeV130.Contract.SafeV130Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SafeV130 *SafeV130Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeV130.Contract.SafeV130Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SafeV130 *SafeV130Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SafeV130.Contract.SafeV130Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SafeV130 *SafeV130CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SafeV130.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SafeV130 *SafeV130TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeV130.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SafeV130 *SafeV130TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SafeV130.Contract.contract.Transact(opts, method, params...) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_SafeV130 *SafeV130Caller) VERSION(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "VERSION") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_SafeV130 *SafeV130Session) VERSION() (string, error) { + return _SafeV130.Contract.VERSION(&_SafeV130.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_SafeV130 *SafeV130CallerSession) VERSION() (string, error) { + return _SafeV130.Contract.VERSION(&_SafeV130.CallOpts) +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_SafeV130 *SafeV130Caller) ApprovedHashes(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "approvedHashes", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_SafeV130 *SafeV130Session) ApprovedHashes(arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + return _SafeV130.Contract.ApprovedHashes(&_SafeV130.CallOpts, arg0, arg1) +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_SafeV130 *SafeV130CallerSession) ApprovedHashes(arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + return _SafeV130.Contract.ApprovedHashes(&_SafeV130.CallOpts, arg0, arg1) +} + +// CheckNSignatures is a free data retrieval call binding the contract method 0x12fb68e0. +// +// Solidity: function checkNSignatures(bytes32 dataHash, bytes data, bytes signatures, uint256 requiredSignatures) view returns() +func (_SafeV130 *SafeV130Caller) CheckNSignatures(opts *bind.CallOpts, dataHash [32]byte, data []byte, signatures []byte, requiredSignatures *big.Int) error { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "checkNSignatures", dataHash, data, signatures, requiredSignatures) + + if err != nil { + return err + } + + return err + +} + +// CheckNSignatures is a free data retrieval call binding the contract method 0x12fb68e0. +// +// Solidity: function checkNSignatures(bytes32 dataHash, bytes data, bytes signatures, uint256 requiredSignatures) view returns() +func (_SafeV130 *SafeV130Session) CheckNSignatures(dataHash [32]byte, data []byte, signatures []byte, requiredSignatures *big.Int) error { + return _SafeV130.Contract.CheckNSignatures(&_SafeV130.CallOpts, dataHash, data, signatures, requiredSignatures) +} + +// CheckNSignatures is a free data retrieval call binding the contract method 0x12fb68e0. +// +// Solidity: function checkNSignatures(bytes32 dataHash, bytes data, bytes signatures, uint256 requiredSignatures) view returns() +func (_SafeV130 *SafeV130CallerSession) CheckNSignatures(dataHash [32]byte, data []byte, signatures []byte, requiredSignatures *big.Int) error { + return _SafeV130.Contract.CheckNSignatures(&_SafeV130.CallOpts, dataHash, data, signatures, requiredSignatures) +} + +// CheckSignatures is a free data retrieval call binding the contract method 0x934f3a11. +// +// Solidity: function checkSignatures(bytes32 dataHash, bytes data, bytes signatures) view returns() +func (_SafeV130 *SafeV130Caller) CheckSignatures(opts *bind.CallOpts, dataHash [32]byte, data []byte, signatures []byte) error { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "checkSignatures", dataHash, data, signatures) + + if err != nil { + return err + } + + return err + +} + +// CheckSignatures is a free data retrieval call binding the contract method 0x934f3a11. +// +// Solidity: function checkSignatures(bytes32 dataHash, bytes data, bytes signatures) view returns() +func (_SafeV130 *SafeV130Session) CheckSignatures(dataHash [32]byte, data []byte, signatures []byte) error { + return _SafeV130.Contract.CheckSignatures(&_SafeV130.CallOpts, dataHash, data, signatures) +} + +// CheckSignatures is a free data retrieval call binding the contract method 0x934f3a11. +// +// Solidity: function checkSignatures(bytes32 dataHash, bytes data, bytes signatures) view returns() +func (_SafeV130 *SafeV130CallerSession) CheckSignatures(dataHash [32]byte, data []byte, signatures []byte) error { + return _SafeV130.Contract.CheckSignatures(&_SafeV130.CallOpts, dataHash, data, signatures) +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_SafeV130 *SafeV130Caller) DomainSeparator(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "domainSeparator") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_SafeV130 *SafeV130Session) DomainSeparator() ([32]byte, error) { + return _SafeV130.Contract.DomainSeparator(&_SafeV130.CallOpts) +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_SafeV130 *SafeV130CallerSession) DomainSeparator() ([32]byte, error) { + return _SafeV130.Contract.DomainSeparator(&_SafeV130.CallOpts) +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_SafeV130 *SafeV130Caller) EncodeTransactionData(opts *bind.CallOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "encodeTransactionData", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_SafeV130 *SafeV130Session) EncodeTransactionData(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + return _SafeV130.Contract.EncodeTransactionData(&_SafeV130.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_SafeV130 *SafeV130CallerSession) EncodeTransactionData(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + return _SafeV130.Contract.EncodeTransactionData(&_SafeV130.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_SafeV130 *SafeV130Caller) GetChainId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "getChainId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_SafeV130 *SafeV130Session) GetChainId() (*big.Int, error) { + return _SafeV130.Contract.GetChainId(&_SafeV130.CallOpts) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_SafeV130 *SafeV130CallerSession) GetChainId() (*big.Int, error) { + return _SafeV130.Contract.GetChainId(&_SafeV130.CallOpts) +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_SafeV130 *SafeV130Caller) GetModulesPaginated(opts *bind.CallOpts, start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "getModulesPaginated", start, pageSize) + + outstruct := new(struct { + Array []common.Address + Next common.Address + }) + if err != nil { + return *outstruct, err + } + + outstruct.Array = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + outstruct.Next = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_SafeV130 *SafeV130Session) GetModulesPaginated(start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + return _SafeV130.Contract.GetModulesPaginated(&_SafeV130.CallOpts, start, pageSize) +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_SafeV130 *SafeV130CallerSession) GetModulesPaginated(start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + return _SafeV130.Contract.GetModulesPaginated(&_SafeV130.CallOpts, start, pageSize) +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_SafeV130 *SafeV130Caller) GetOwners(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "getOwners") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_SafeV130 *SafeV130Session) GetOwners() ([]common.Address, error) { + return _SafeV130.Contract.GetOwners(&_SafeV130.CallOpts) +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_SafeV130 *SafeV130CallerSession) GetOwners() ([]common.Address, error) { + return _SafeV130.Contract.GetOwners(&_SafeV130.CallOpts) +} + +// GetStorageAt is a free data retrieval call binding the contract method 0x5624b25b. +// +// Solidity: function getStorageAt(uint256 offset, uint256 length) view returns(bytes) +func (_SafeV130 *SafeV130Caller) GetStorageAt(opts *bind.CallOpts, offset *big.Int, length *big.Int) ([]byte, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "getStorageAt", offset, length) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// GetStorageAt is a free data retrieval call binding the contract method 0x5624b25b. +// +// Solidity: function getStorageAt(uint256 offset, uint256 length) view returns(bytes) +func (_SafeV130 *SafeV130Session) GetStorageAt(offset *big.Int, length *big.Int) ([]byte, error) { + return _SafeV130.Contract.GetStorageAt(&_SafeV130.CallOpts, offset, length) +} + +// GetStorageAt is a free data retrieval call binding the contract method 0x5624b25b. +// +// Solidity: function getStorageAt(uint256 offset, uint256 length) view returns(bytes) +func (_SafeV130 *SafeV130CallerSession) GetStorageAt(offset *big.Int, length *big.Int) ([]byte, error) { + return _SafeV130.Contract.GetStorageAt(&_SafeV130.CallOpts, offset, length) +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_SafeV130 *SafeV130Caller) GetThreshold(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "getThreshold") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_SafeV130 *SafeV130Session) GetThreshold() (*big.Int, error) { + return _SafeV130.Contract.GetThreshold(&_SafeV130.CallOpts) +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_SafeV130 *SafeV130CallerSession) GetThreshold() (*big.Int, error) { + return _SafeV130.Contract.GetThreshold(&_SafeV130.CallOpts) +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_SafeV130 *SafeV130Caller) GetTransactionHash(opts *bind.CallOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "getTransactionHash", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_SafeV130 *SafeV130Session) GetTransactionHash(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + return _SafeV130.Contract.GetTransactionHash(&_SafeV130.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_SafeV130 *SafeV130CallerSession) GetTransactionHash(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + return _SafeV130.Contract.GetTransactionHash(&_SafeV130.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_SafeV130 *SafeV130Caller) IsModuleEnabled(opts *bind.CallOpts, module common.Address) (bool, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "isModuleEnabled", module) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_SafeV130 *SafeV130Session) IsModuleEnabled(module common.Address) (bool, error) { + return _SafeV130.Contract.IsModuleEnabled(&_SafeV130.CallOpts, module) +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_SafeV130 *SafeV130CallerSession) IsModuleEnabled(module common.Address) (bool, error) { + return _SafeV130.Contract.IsModuleEnabled(&_SafeV130.CallOpts, module) +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_SafeV130 *SafeV130Caller) IsOwner(opts *bind.CallOpts, owner common.Address) (bool, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "isOwner", owner) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_SafeV130 *SafeV130Session) IsOwner(owner common.Address) (bool, error) { + return _SafeV130.Contract.IsOwner(&_SafeV130.CallOpts, owner) +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_SafeV130 *SafeV130CallerSession) IsOwner(owner common.Address) (bool, error) { + return _SafeV130.Contract.IsOwner(&_SafeV130.CallOpts, owner) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_SafeV130 *SafeV130Caller) Nonce(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "nonce") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_SafeV130 *SafeV130Session) Nonce() (*big.Int, error) { + return _SafeV130.Contract.Nonce(&_SafeV130.CallOpts) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_SafeV130 *SafeV130CallerSession) Nonce() (*big.Int, error) { + return _SafeV130.Contract.Nonce(&_SafeV130.CallOpts) +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_SafeV130 *SafeV130Caller) SignedMessages(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { + var out []interface{} + err := _SafeV130.contract.Call(opts, &out, "signedMessages", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_SafeV130 *SafeV130Session) SignedMessages(arg0 [32]byte) (*big.Int, error) { + return _SafeV130.Contract.SignedMessages(&_SafeV130.CallOpts, arg0) +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_SafeV130 *SafeV130CallerSession) SignedMessages(arg0 [32]byte) (*big.Int, error) { + return _SafeV130.Contract.SignedMessages(&_SafeV130.CallOpts, arg0) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_SafeV130 *SafeV130Transactor) AddOwnerWithThreshold(opts *bind.TransactOpts, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "addOwnerWithThreshold", owner, _threshold) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_SafeV130 *SafeV130Session) AddOwnerWithThreshold(owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeV130.Contract.AddOwnerWithThreshold(&_SafeV130.TransactOpts, owner, _threshold) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_SafeV130 *SafeV130TransactorSession) AddOwnerWithThreshold(owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeV130.Contract.AddOwnerWithThreshold(&_SafeV130.TransactOpts, owner, _threshold) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_SafeV130 *SafeV130Transactor) ApproveHash(opts *bind.TransactOpts, hashToApprove [32]byte) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "approveHash", hashToApprove) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_SafeV130 *SafeV130Session) ApproveHash(hashToApprove [32]byte) (*types.Transaction, error) { + return _SafeV130.Contract.ApproveHash(&_SafeV130.TransactOpts, hashToApprove) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_SafeV130 *SafeV130TransactorSession) ApproveHash(hashToApprove [32]byte) (*types.Transaction, error) { + return _SafeV130.Contract.ApproveHash(&_SafeV130.TransactOpts, hashToApprove) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_SafeV130 *SafeV130Transactor) ChangeThreshold(opts *bind.TransactOpts, _threshold *big.Int) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "changeThreshold", _threshold) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_SafeV130 *SafeV130Session) ChangeThreshold(_threshold *big.Int) (*types.Transaction, error) { + return _SafeV130.Contract.ChangeThreshold(&_SafeV130.TransactOpts, _threshold) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_SafeV130 *SafeV130TransactorSession) ChangeThreshold(_threshold *big.Int) (*types.Transaction, error) { + return _SafeV130.Contract.ChangeThreshold(&_SafeV130.TransactOpts, _threshold) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_SafeV130 *SafeV130Transactor) DisableModule(opts *bind.TransactOpts, prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "disableModule", prevModule, module) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_SafeV130 *SafeV130Session) DisableModule(prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.DisableModule(&_SafeV130.TransactOpts, prevModule, module) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_SafeV130 *SafeV130TransactorSession) DisableModule(prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.DisableModule(&_SafeV130.TransactOpts, prevModule, module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_SafeV130 *SafeV130Transactor) EnableModule(opts *bind.TransactOpts, module common.Address) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "enableModule", module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_SafeV130 *SafeV130Session) EnableModule(module common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.EnableModule(&_SafeV130.TransactOpts, module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_SafeV130 *SafeV130TransactorSession) EnableModule(module common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.EnableModule(&_SafeV130.TransactOpts, module) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool success) +func (_SafeV130 *SafeV130Transactor) ExecTransaction(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "execTransaction", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool success) +func (_SafeV130 *SafeV130Session) ExecTransaction(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _SafeV130.Contract.ExecTransaction(&_SafeV130.TransactOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool success) +func (_SafeV130 *SafeV130TransactorSession) ExecTransaction(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _SafeV130.Contract.ExecTransaction(&_SafeV130.TransactOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_SafeV130 *SafeV130Transactor) ExecTransactionFromModule(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "execTransactionFromModule", to, value, data, operation) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_SafeV130 *SafeV130Session) ExecTransactionFromModule(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeV130.Contract.ExecTransactionFromModule(&_SafeV130.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_SafeV130 *SafeV130TransactorSession) ExecTransactionFromModule(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeV130.Contract.ExecTransactionFromModule(&_SafeV130.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_SafeV130 *SafeV130Transactor) ExecTransactionFromModuleReturnData(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "execTransactionFromModuleReturnData", to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_SafeV130 *SafeV130Session) ExecTransactionFromModuleReturnData(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeV130.Contract.ExecTransactionFromModuleReturnData(&_SafeV130.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_SafeV130 *SafeV130TransactorSession) ExecTransactionFromModuleReturnData(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeV130.Contract.ExecTransactionFromModuleReturnData(&_SafeV130.TransactOpts, to, value, data, operation) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_SafeV130 *SafeV130Transactor) RemoveOwner(opts *bind.TransactOpts, prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "removeOwner", prevOwner, owner, _threshold) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_SafeV130 *SafeV130Session) RemoveOwner(prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeV130.Contract.RemoveOwner(&_SafeV130.TransactOpts, prevOwner, owner, _threshold) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_SafeV130 *SafeV130TransactorSession) RemoveOwner(prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeV130.Contract.RemoveOwner(&_SafeV130.TransactOpts, prevOwner, owner, _threshold) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_SafeV130 *SafeV130Transactor) RequiredTxGas(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "requiredTxGas", to, value, data, operation) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_SafeV130 *SafeV130Session) RequiredTxGas(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeV130.Contract.RequiredTxGas(&_SafeV130.TransactOpts, to, value, data, operation) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_SafeV130 *SafeV130TransactorSession) RequiredTxGas(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeV130.Contract.RequiredTxGas(&_SafeV130.TransactOpts, to, value, data, operation) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_SafeV130 *SafeV130Transactor) SetFallbackHandler(opts *bind.TransactOpts, handler common.Address) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "setFallbackHandler", handler) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_SafeV130 *SafeV130Session) SetFallbackHandler(handler common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.SetFallbackHandler(&_SafeV130.TransactOpts, handler) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_SafeV130 *SafeV130TransactorSession) SetFallbackHandler(handler common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.SetFallbackHandler(&_SafeV130.TransactOpts, handler) +} + +// SetGuard is a paid mutator transaction binding the contract method 0xe19a9dd9. +// +// Solidity: function setGuard(address guard) returns() +func (_SafeV130 *SafeV130Transactor) SetGuard(opts *bind.TransactOpts, guard common.Address) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "setGuard", guard) +} + +// SetGuard is a paid mutator transaction binding the contract method 0xe19a9dd9. +// +// Solidity: function setGuard(address guard) returns() +func (_SafeV130 *SafeV130Session) SetGuard(guard common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.SetGuard(&_SafeV130.TransactOpts, guard) +} + +// SetGuard is a paid mutator transaction binding the contract method 0xe19a9dd9. +// +// Solidity: function setGuard(address guard) returns() +func (_SafeV130 *SafeV130TransactorSession) SetGuard(guard common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.SetGuard(&_SafeV130.TransactOpts, guard) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_SafeV130 *SafeV130Transactor) Setup(opts *bind.TransactOpts, _owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "setup", _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_SafeV130 *SafeV130Session) Setup(_owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.Setup(&_SafeV130.TransactOpts, _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_SafeV130 *SafeV130TransactorSession) Setup(_owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.Setup(&_SafeV130.TransactOpts, _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// SimulateAndRevert is a paid mutator transaction binding the contract method 0xb4faba09. +// +// Solidity: function simulateAndRevert(address targetContract, bytes calldataPayload) returns() +func (_SafeV130 *SafeV130Transactor) SimulateAndRevert(opts *bind.TransactOpts, targetContract common.Address, calldataPayload []byte) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "simulateAndRevert", targetContract, calldataPayload) +} + +// SimulateAndRevert is a paid mutator transaction binding the contract method 0xb4faba09. +// +// Solidity: function simulateAndRevert(address targetContract, bytes calldataPayload) returns() +func (_SafeV130 *SafeV130Session) SimulateAndRevert(targetContract common.Address, calldataPayload []byte) (*types.Transaction, error) { + return _SafeV130.Contract.SimulateAndRevert(&_SafeV130.TransactOpts, targetContract, calldataPayload) +} + +// SimulateAndRevert is a paid mutator transaction binding the contract method 0xb4faba09. +// +// Solidity: function simulateAndRevert(address targetContract, bytes calldataPayload) returns() +func (_SafeV130 *SafeV130TransactorSession) SimulateAndRevert(targetContract common.Address, calldataPayload []byte) (*types.Transaction, error) { + return _SafeV130.Contract.SimulateAndRevert(&_SafeV130.TransactOpts, targetContract, calldataPayload) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_SafeV130 *SafeV130Transactor) SwapOwner(opts *bind.TransactOpts, prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _SafeV130.contract.Transact(opts, "swapOwner", prevOwner, oldOwner, newOwner) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_SafeV130 *SafeV130Session) SwapOwner(prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.SwapOwner(&_SafeV130.TransactOpts, prevOwner, oldOwner, newOwner) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_SafeV130 *SafeV130TransactorSession) SwapOwner(prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _SafeV130.Contract.SwapOwner(&_SafeV130.TransactOpts, prevOwner, oldOwner, newOwner) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() returns() +func (_SafeV130 *SafeV130Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _SafeV130.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() returns() +func (_SafeV130 *SafeV130Session) Fallback(calldata []byte) (*types.Transaction, error) { + return _SafeV130.Contract.Fallback(&_SafeV130.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() returns() +func (_SafeV130 *SafeV130TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _SafeV130.Contract.Fallback(&_SafeV130.TransactOpts, calldata) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_SafeV130 *SafeV130Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeV130.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_SafeV130 *SafeV130Session) Receive() (*types.Transaction, error) { + return _SafeV130.Contract.Receive(&_SafeV130.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_SafeV130 *SafeV130TransactorSession) Receive() (*types.Transaction, error) { + return _SafeV130.Contract.Receive(&_SafeV130.TransactOpts) +} + +// SafeV130AddedOwnerIterator is returned from FilterAddedOwner and is used to iterate over the raw logs and unpacked data for AddedOwner events raised by the SafeV130 contract. +type SafeV130AddedOwnerIterator struct { + Event *SafeV130AddedOwner // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130AddedOwnerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130AddedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130AddedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130AddedOwnerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130AddedOwnerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130AddedOwner represents a AddedOwner event raised by the SafeV130 contract. +type SafeV130AddedOwner struct { + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAddedOwner is a free log retrieval operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_SafeV130 *SafeV130Filterer) FilterAddedOwner(opts *bind.FilterOpts) (*SafeV130AddedOwnerIterator, error) { + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "AddedOwner") + if err != nil { + return nil, err + } + return &SafeV130AddedOwnerIterator{contract: _SafeV130.contract, event: "AddedOwner", logs: logs, sub: sub}, nil +} + +// WatchAddedOwner is a free log subscription operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_SafeV130 *SafeV130Filterer) WatchAddedOwner(opts *bind.WatchOpts, sink chan<- *SafeV130AddedOwner) (event.Subscription, error) { + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "AddedOwner") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130AddedOwner) + if err := _SafeV130.contract.UnpackLog(event, "AddedOwner", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAddedOwner is a log parse operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_SafeV130 *SafeV130Filterer) ParseAddedOwner(log types.Log) (*SafeV130AddedOwner, error) { + event := new(SafeV130AddedOwner) + if err := _SafeV130.contract.UnpackLog(event, "AddedOwner", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130ApproveHashIterator is returned from FilterApproveHash and is used to iterate over the raw logs and unpacked data for ApproveHash events raised by the SafeV130 contract. +type SafeV130ApproveHashIterator struct { + Event *SafeV130ApproveHash // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130ApproveHashIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130ApproveHash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130ApproveHash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130ApproveHashIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130ApproveHashIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130ApproveHash represents a ApproveHash event raised by the SafeV130 contract. +type SafeV130ApproveHash struct { + ApprovedHash [32]byte + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproveHash is a free log retrieval operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_SafeV130 *SafeV130Filterer) FilterApproveHash(opts *bind.FilterOpts, approvedHash [][32]byte, owner []common.Address) (*SafeV130ApproveHashIterator, error) { + + var approvedHashRule []interface{} + for _, approvedHashItem := range approvedHash { + approvedHashRule = append(approvedHashRule, approvedHashItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "ApproveHash", approvedHashRule, ownerRule) + if err != nil { + return nil, err + } + return &SafeV130ApproveHashIterator{contract: _SafeV130.contract, event: "ApproveHash", logs: logs, sub: sub}, nil +} + +// WatchApproveHash is a free log subscription operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_SafeV130 *SafeV130Filterer) WatchApproveHash(opts *bind.WatchOpts, sink chan<- *SafeV130ApproveHash, approvedHash [][32]byte, owner []common.Address) (event.Subscription, error) { + + var approvedHashRule []interface{} + for _, approvedHashItem := range approvedHash { + approvedHashRule = append(approvedHashRule, approvedHashItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "ApproveHash", approvedHashRule, ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130ApproveHash) + if err := _SafeV130.contract.UnpackLog(event, "ApproveHash", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproveHash is a log parse operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_SafeV130 *SafeV130Filterer) ParseApproveHash(log types.Log) (*SafeV130ApproveHash, error) { + event := new(SafeV130ApproveHash) + if err := _SafeV130.contract.UnpackLog(event, "ApproveHash", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130ChangedFallbackHandlerIterator is returned from FilterChangedFallbackHandler and is used to iterate over the raw logs and unpacked data for ChangedFallbackHandler events raised by the SafeV130 contract. +type SafeV130ChangedFallbackHandlerIterator struct { + Event *SafeV130ChangedFallbackHandler // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130ChangedFallbackHandlerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130ChangedFallbackHandler) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130ChangedFallbackHandler) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130ChangedFallbackHandlerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130ChangedFallbackHandlerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130ChangedFallbackHandler represents a ChangedFallbackHandler event raised by the SafeV130 contract. +type SafeV130ChangedFallbackHandler struct { + Handler common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangedFallbackHandler is a free log retrieval operation binding the contract event 0x5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b0. +// +// Solidity: event ChangedFallbackHandler(address handler) +func (_SafeV130 *SafeV130Filterer) FilterChangedFallbackHandler(opts *bind.FilterOpts) (*SafeV130ChangedFallbackHandlerIterator, error) { + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "ChangedFallbackHandler") + if err != nil { + return nil, err + } + return &SafeV130ChangedFallbackHandlerIterator{contract: _SafeV130.contract, event: "ChangedFallbackHandler", logs: logs, sub: sub}, nil +} + +// WatchChangedFallbackHandler is a free log subscription operation binding the contract event 0x5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b0. +// +// Solidity: event ChangedFallbackHandler(address handler) +func (_SafeV130 *SafeV130Filterer) WatchChangedFallbackHandler(opts *bind.WatchOpts, sink chan<- *SafeV130ChangedFallbackHandler) (event.Subscription, error) { + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "ChangedFallbackHandler") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130ChangedFallbackHandler) + if err := _SafeV130.contract.UnpackLog(event, "ChangedFallbackHandler", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangedFallbackHandler is a log parse operation binding the contract event 0x5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b0. +// +// Solidity: event ChangedFallbackHandler(address handler) +func (_SafeV130 *SafeV130Filterer) ParseChangedFallbackHandler(log types.Log) (*SafeV130ChangedFallbackHandler, error) { + event := new(SafeV130ChangedFallbackHandler) + if err := _SafeV130.contract.UnpackLog(event, "ChangedFallbackHandler", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130ChangedGuardIterator is returned from FilterChangedGuard and is used to iterate over the raw logs and unpacked data for ChangedGuard events raised by the SafeV130 contract. +type SafeV130ChangedGuardIterator struct { + Event *SafeV130ChangedGuard // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130ChangedGuardIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130ChangedGuard) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130ChangedGuard) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130ChangedGuardIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130ChangedGuardIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130ChangedGuard represents a ChangedGuard event raised by the SafeV130 contract. +type SafeV130ChangedGuard struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangedGuard is a free log retrieval operation binding the contract event 0x1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2. +// +// Solidity: event ChangedGuard(address guard) +func (_SafeV130 *SafeV130Filterer) FilterChangedGuard(opts *bind.FilterOpts) (*SafeV130ChangedGuardIterator, error) { + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "ChangedGuard") + if err != nil { + return nil, err + } + return &SafeV130ChangedGuardIterator{contract: _SafeV130.contract, event: "ChangedGuard", logs: logs, sub: sub}, nil +} + +// WatchChangedGuard is a free log subscription operation binding the contract event 0x1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2. +// +// Solidity: event ChangedGuard(address guard) +func (_SafeV130 *SafeV130Filterer) WatchChangedGuard(opts *bind.WatchOpts, sink chan<- *SafeV130ChangedGuard) (event.Subscription, error) { + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "ChangedGuard") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130ChangedGuard) + if err := _SafeV130.contract.UnpackLog(event, "ChangedGuard", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangedGuard is a log parse operation binding the contract event 0x1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2. +// +// Solidity: event ChangedGuard(address guard) +func (_SafeV130 *SafeV130Filterer) ParseChangedGuard(log types.Log) (*SafeV130ChangedGuard, error) { + event := new(SafeV130ChangedGuard) + if err := _SafeV130.contract.UnpackLog(event, "ChangedGuard", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130ChangedThresholdIterator is returned from FilterChangedThreshold and is used to iterate over the raw logs and unpacked data for ChangedThreshold events raised by the SafeV130 contract. +type SafeV130ChangedThresholdIterator struct { + Event *SafeV130ChangedThreshold // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130ChangedThresholdIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130ChangedThreshold) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130ChangedThreshold) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130ChangedThresholdIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130ChangedThresholdIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130ChangedThreshold represents a ChangedThreshold event raised by the SafeV130 contract. +type SafeV130ChangedThreshold struct { + Threshold *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangedThreshold is a free log retrieval operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_SafeV130 *SafeV130Filterer) FilterChangedThreshold(opts *bind.FilterOpts) (*SafeV130ChangedThresholdIterator, error) { + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "ChangedThreshold") + if err != nil { + return nil, err + } + return &SafeV130ChangedThresholdIterator{contract: _SafeV130.contract, event: "ChangedThreshold", logs: logs, sub: sub}, nil +} + +// WatchChangedThreshold is a free log subscription operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_SafeV130 *SafeV130Filterer) WatchChangedThreshold(opts *bind.WatchOpts, sink chan<- *SafeV130ChangedThreshold) (event.Subscription, error) { + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "ChangedThreshold") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130ChangedThreshold) + if err := _SafeV130.contract.UnpackLog(event, "ChangedThreshold", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangedThreshold is a log parse operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_SafeV130 *SafeV130Filterer) ParseChangedThreshold(log types.Log) (*SafeV130ChangedThreshold, error) { + event := new(SafeV130ChangedThreshold) + if err := _SafeV130.contract.UnpackLog(event, "ChangedThreshold", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130DisabledModuleIterator is returned from FilterDisabledModule and is used to iterate over the raw logs and unpacked data for DisabledModule events raised by the SafeV130 contract. +type SafeV130DisabledModuleIterator struct { + Event *SafeV130DisabledModule // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130DisabledModuleIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130DisabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130DisabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130DisabledModuleIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130DisabledModuleIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130DisabledModule represents a DisabledModule event raised by the SafeV130 contract. +type SafeV130DisabledModule struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDisabledModule is a free log retrieval operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_SafeV130 *SafeV130Filterer) FilterDisabledModule(opts *bind.FilterOpts) (*SafeV130DisabledModuleIterator, error) { + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "DisabledModule") + if err != nil { + return nil, err + } + return &SafeV130DisabledModuleIterator{contract: _SafeV130.contract, event: "DisabledModule", logs: logs, sub: sub}, nil +} + +// WatchDisabledModule is a free log subscription operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_SafeV130 *SafeV130Filterer) WatchDisabledModule(opts *bind.WatchOpts, sink chan<- *SafeV130DisabledModule) (event.Subscription, error) { + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "DisabledModule") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130DisabledModule) + if err := _SafeV130.contract.UnpackLog(event, "DisabledModule", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDisabledModule is a log parse operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_SafeV130 *SafeV130Filterer) ParseDisabledModule(log types.Log) (*SafeV130DisabledModule, error) { + event := new(SafeV130DisabledModule) + if err := _SafeV130.contract.UnpackLog(event, "DisabledModule", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130EnabledModuleIterator is returned from FilterEnabledModule and is used to iterate over the raw logs and unpacked data for EnabledModule events raised by the SafeV130 contract. +type SafeV130EnabledModuleIterator struct { + Event *SafeV130EnabledModule // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130EnabledModuleIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130EnabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130EnabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130EnabledModuleIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130EnabledModuleIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130EnabledModule represents a EnabledModule event raised by the SafeV130 contract. +type SafeV130EnabledModule struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEnabledModule is a free log retrieval operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_SafeV130 *SafeV130Filterer) FilterEnabledModule(opts *bind.FilterOpts) (*SafeV130EnabledModuleIterator, error) { + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "EnabledModule") + if err != nil { + return nil, err + } + return &SafeV130EnabledModuleIterator{contract: _SafeV130.contract, event: "EnabledModule", logs: logs, sub: sub}, nil +} + +// WatchEnabledModule is a free log subscription operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_SafeV130 *SafeV130Filterer) WatchEnabledModule(opts *bind.WatchOpts, sink chan<- *SafeV130EnabledModule) (event.Subscription, error) { + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "EnabledModule") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130EnabledModule) + if err := _SafeV130.contract.UnpackLog(event, "EnabledModule", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseEnabledModule is a log parse operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_SafeV130 *SafeV130Filterer) ParseEnabledModule(log types.Log) (*SafeV130EnabledModule, error) { + event := new(SafeV130EnabledModule) + if err := _SafeV130.contract.UnpackLog(event, "EnabledModule", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130ExecutionFailureIterator is returned from FilterExecutionFailure and is used to iterate over the raw logs and unpacked data for ExecutionFailure events raised by the SafeV130 contract. +type SafeV130ExecutionFailureIterator struct { + Event *SafeV130ExecutionFailure // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130ExecutionFailureIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130ExecutionFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130ExecutionFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130ExecutionFailureIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130ExecutionFailureIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130ExecutionFailure represents a ExecutionFailure event raised by the SafeV130 contract. +type SafeV130ExecutionFailure struct { + TxHash [32]byte + Payment *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFailure is a free log retrieval operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_SafeV130 *SafeV130Filterer) FilterExecutionFailure(opts *bind.FilterOpts) (*SafeV130ExecutionFailureIterator, error) { + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "ExecutionFailure") + if err != nil { + return nil, err + } + return &SafeV130ExecutionFailureIterator{contract: _SafeV130.contract, event: "ExecutionFailure", logs: logs, sub: sub}, nil +} + +// WatchExecutionFailure is a free log subscription operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_SafeV130 *SafeV130Filterer) WatchExecutionFailure(opts *bind.WatchOpts, sink chan<- *SafeV130ExecutionFailure) (event.Subscription, error) { + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "ExecutionFailure") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130ExecutionFailure) + if err := _SafeV130.contract.UnpackLog(event, "ExecutionFailure", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFailure is a log parse operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_SafeV130 *SafeV130Filterer) ParseExecutionFailure(log types.Log) (*SafeV130ExecutionFailure, error) { + event := new(SafeV130ExecutionFailure) + if err := _SafeV130.contract.UnpackLog(event, "ExecutionFailure", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130ExecutionFromModuleFailureIterator is returned from FilterExecutionFromModuleFailure and is used to iterate over the raw logs and unpacked data for ExecutionFromModuleFailure events raised by the SafeV130 contract. +type SafeV130ExecutionFromModuleFailureIterator struct { + Event *SafeV130ExecutionFromModuleFailure // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130ExecutionFromModuleFailureIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130ExecutionFromModuleFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130ExecutionFromModuleFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130ExecutionFromModuleFailureIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130ExecutionFromModuleFailureIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130ExecutionFromModuleFailure represents a ExecutionFromModuleFailure event raised by the SafeV130 contract. +type SafeV130ExecutionFromModuleFailure struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFromModuleFailure is a free log retrieval operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_SafeV130 *SafeV130Filterer) FilterExecutionFromModuleFailure(opts *bind.FilterOpts, module []common.Address) (*SafeV130ExecutionFromModuleFailureIterator, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "ExecutionFromModuleFailure", moduleRule) + if err != nil { + return nil, err + } + return &SafeV130ExecutionFromModuleFailureIterator{contract: _SafeV130.contract, event: "ExecutionFromModuleFailure", logs: logs, sub: sub}, nil +} + +// WatchExecutionFromModuleFailure is a free log subscription operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_SafeV130 *SafeV130Filterer) WatchExecutionFromModuleFailure(opts *bind.WatchOpts, sink chan<- *SafeV130ExecutionFromModuleFailure, module []common.Address) (event.Subscription, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "ExecutionFromModuleFailure", moduleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130ExecutionFromModuleFailure) + if err := _SafeV130.contract.UnpackLog(event, "ExecutionFromModuleFailure", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFromModuleFailure is a log parse operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_SafeV130 *SafeV130Filterer) ParseExecutionFromModuleFailure(log types.Log) (*SafeV130ExecutionFromModuleFailure, error) { + event := new(SafeV130ExecutionFromModuleFailure) + if err := _SafeV130.contract.UnpackLog(event, "ExecutionFromModuleFailure", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130ExecutionFromModuleSuccessIterator is returned from FilterExecutionFromModuleSuccess and is used to iterate over the raw logs and unpacked data for ExecutionFromModuleSuccess events raised by the SafeV130 contract. +type SafeV130ExecutionFromModuleSuccessIterator struct { + Event *SafeV130ExecutionFromModuleSuccess // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130ExecutionFromModuleSuccessIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130ExecutionFromModuleSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130ExecutionFromModuleSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130ExecutionFromModuleSuccessIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130ExecutionFromModuleSuccessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130ExecutionFromModuleSuccess represents a ExecutionFromModuleSuccess event raised by the SafeV130 contract. +type SafeV130ExecutionFromModuleSuccess struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFromModuleSuccess is a free log retrieval operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_SafeV130 *SafeV130Filterer) FilterExecutionFromModuleSuccess(opts *bind.FilterOpts, module []common.Address) (*SafeV130ExecutionFromModuleSuccessIterator, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "ExecutionFromModuleSuccess", moduleRule) + if err != nil { + return nil, err + } + return &SafeV130ExecutionFromModuleSuccessIterator{contract: _SafeV130.contract, event: "ExecutionFromModuleSuccess", logs: logs, sub: sub}, nil +} + +// WatchExecutionFromModuleSuccess is a free log subscription operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_SafeV130 *SafeV130Filterer) WatchExecutionFromModuleSuccess(opts *bind.WatchOpts, sink chan<- *SafeV130ExecutionFromModuleSuccess, module []common.Address) (event.Subscription, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "ExecutionFromModuleSuccess", moduleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130ExecutionFromModuleSuccess) + if err := _SafeV130.contract.UnpackLog(event, "ExecutionFromModuleSuccess", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFromModuleSuccess is a log parse operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_SafeV130 *SafeV130Filterer) ParseExecutionFromModuleSuccess(log types.Log) (*SafeV130ExecutionFromModuleSuccess, error) { + event := new(SafeV130ExecutionFromModuleSuccess) + if err := _SafeV130.contract.UnpackLog(event, "ExecutionFromModuleSuccess", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130ExecutionSuccessIterator is returned from FilterExecutionSuccess and is used to iterate over the raw logs and unpacked data for ExecutionSuccess events raised by the SafeV130 contract. +type SafeV130ExecutionSuccessIterator struct { + Event *SafeV130ExecutionSuccess // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130ExecutionSuccessIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130ExecutionSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130ExecutionSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130ExecutionSuccessIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130ExecutionSuccessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130ExecutionSuccess represents a ExecutionSuccess event raised by the SafeV130 contract. +type SafeV130ExecutionSuccess struct { + TxHash [32]byte + Payment *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionSuccess is a free log retrieval operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_SafeV130 *SafeV130Filterer) FilterExecutionSuccess(opts *bind.FilterOpts) (*SafeV130ExecutionSuccessIterator, error) { + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "ExecutionSuccess") + if err != nil { + return nil, err + } + return &SafeV130ExecutionSuccessIterator{contract: _SafeV130.contract, event: "ExecutionSuccess", logs: logs, sub: sub}, nil +} + +// WatchExecutionSuccess is a free log subscription operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_SafeV130 *SafeV130Filterer) WatchExecutionSuccess(opts *bind.WatchOpts, sink chan<- *SafeV130ExecutionSuccess) (event.Subscription, error) { + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "ExecutionSuccess") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130ExecutionSuccess) + if err := _SafeV130.contract.UnpackLog(event, "ExecutionSuccess", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionSuccess is a log parse operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_SafeV130 *SafeV130Filterer) ParseExecutionSuccess(log types.Log) (*SafeV130ExecutionSuccess, error) { + event := new(SafeV130ExecutionSuccess) + if err := _SafeV130.contract.UnpackLog(event, "ExecutionSuccess", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130RemovedOwnerIterator is returned from FilterRemovedOwner and is used to iterate over the raw logs and unpacked data for RemovedOwner events raised by the SafeV130 contract. +type SafeV130RemovedOwnerIterator struct { + Event *SafeV130RemovedOwner // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130RemovedOwnerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130RemovedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130RemovedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130RemovedOwnerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130RemovedOwnerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130RemovedOwner represents a RemovedOwner event raised by the SafeV130 contract. +type SafeV130RemovedOwner struct { + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemovedOwner is a free log retrieval operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_SafeV130 *SafeV130Filterer) FilterRemovedOwner(opts *bind.FilterOpts) (*SafeV130RemovedOwnerIterator, error) { + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "RemovedOwner") + if err != nil { + return nil, err + } + return &SafeV130RemovedOwnerIterator{contract: _SafeV130.contract, event: "RemovedOwner", logs: logs, sub: sub}, nil +} + +// WatchRemovedOwner is a free log subscription operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_SafeV130 *SafeV130Filterer) WatchRemovedOwner(opts *bind.WatchOpts, sink chan<- *SafeV130RemovedOwner) (event.Subscription, error) { + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "RemovedOwner") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130RemovedOwner) + if err := _SafeV130.contract.UnpackLog(event, "RemovedOwner", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRemovedOwner is a log parse operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_SafeV130 *SafeV130Filterer) ParseRemovedOwner(log types.Log) (*SafeV130RemovedOwner, error) { + event := new(SafeV130RemovedOwner) + if err := _SafeV130.contract.UnpackLog(event, "RemovedOwner", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130SafeReceivedIterator is returned from FilterSafeReceived and is used to iterate over the raw logs and unpacked data for SafeReceived events raised by the SafeV130 contract. +type SafeV130SafeReceivedIterator struct { + Event *SafeV130SafeReceived // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130SafeReceivedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130SafeReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130SafeReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130SafeReceivedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130SafeReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130SafeReceived represents a SafeReceived event raised by the SafeV130 contract. +type SafeV130SafeReceived struct { + Sender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSafeReceived is a free log retrieval operation binding the contract event 0x3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d. +// +// Solidity: event SafeReceived(address indexed sender, uint256 value) +func (_SafeV130 *SafeV130Filterer) FilterSafeReceived(opts *bind.FilterOpts, sender []common.Address) (*SafeV130SafeReceivedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "SafeReceived", senderRule) + if err != nil { + return nil, err + } + return &SafeV130SafeReceivedIterator{contract: _SafeV130.contract, event: "SafeReceived", logs: logs, sub: sub}, nil +} + +// WatchSafeReceived is a free log subscription operation binding the contract event 0x3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d. +// +// Solidity: event SafeReceived(address indexed sender, uint256 value) +func (_SafeV130 *SafeV130Filterer) WatchSafeReceived(opts *bind.WatchOpts, sink chan<- *SafeV130SafeReceived, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "SafeReceived", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130SafeReceived) + if err := _SafeV130.contract.UnpackLog(event, "SafeReceived", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSafeReceived is a log parse operation binding the contract event 0x3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d. +// +// Solidity: event SafeReceived(address indexed sender, uint256 value) +func (_SafeV130 *SafeV130Filterer) ParseSafeReceived(log types.Log) (*SafeV130SafeReceived, error) { + event := new(SafeV130SafeReceived) + if err := _SafeV130.contract.UnpackLog(event, "SafeReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130SafeSetupIterator is returned from FilterSafeSetup and is used to iterate over the raw logs and unpacked data for SafeSetup events raised by the SafeV130 contract. +type SafeV130SafeSetupIterator struct { + Event *SafeV130SafeSetup // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130SafeSetupIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130SafeSetup) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130SafeSetup) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130SafeSetupIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130SafeSetupIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130SafeSetup represents a SafeSetup event raised by the SafeV130 contract. +type SafeV130SafeSetup struct { + Initiator common.Address + Owners []common.Address + Threshold *big.Int + Initializer common.Address + FallbackHandler common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSafeSetup is a free log retrieval operation binding the contract event 0x141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a8. +// +// Solidity: event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler) +func (_SafeV130 *SafeV130Filterer) FilterSafeSetup(opts *bind.FilterOpts, initiator []common.Address) (*SafeV130SafeSetupIterator, error) { + + var initiatorRule []interface{} + for _, initiatorItem := range initiator { + initiatorRule = append(initiatorRule, initiatorItem) + } + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "SafeSetup", initiatorRule) + if err != nil { + return nil, err + } + return &SafeV130SafeSetupIterator{contract: _SafeV130.contract, event: "SafeSetup", logs: logs, sub: sub}, nil +} + +// WatchSafeSetup is a free log subscription operation binding the contract event 0x141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a8. +// +// Solidity: event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler) +func (_SafeV130 *SafeV130Filterer) WatchSafeSetup(opts *bind.WatchOpts, sink chan<- *SafeV130SafeSetup, initiator []common.Address) (event.Subscription, error) { + + var initiatorRule []interface{} + for _, initiatorItem := range initiator { + initiatorRule = append(initiatorRule, initiatorItem) + } + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "SafeSetup", initiatorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130SafeSetup) + if err := _SafeV130.contract.UnpackLog(event, "SafeSetup", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSafeSetup is a log parse operation binding the contract event 0x141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a8. +// +// Solidity: event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler) +func (_SafeV130 *SafeV130Filterer) ParseSafeSetup(log types.Log) (*SafeV130SafeSetup, error) { + event := new(SafeV130SafeSetup) + if err := _SafeV130.contract.UnpackLog(event, "SafeSetup", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeV130SignMsgIterator is returned from FilterSignMsg and is used to iterate over the raw logs and unpacked data for SignMsg events raised by the SafeV130 contract. +type SafeV130SignMsgIterator struct { + Event *SafeV130SignMsg // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeV130SignMsgIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeV130SignMsg) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeV130SignMsg) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeV130SignMsgIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeV130SignMsgIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeV130SignMsg represents a SignMsg event raised by the SafeV130 contract. +type SafeV130SignMsg struct { + MsgHash [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSignMsg is a free log retrieval operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_SafeV130 *SafeV130Filterer) FilterSignMsg(opts *bind.FilterOpts, msgHash [][32]byte) (*SafeV130SignMsgIterator, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _SafeV130.contract.FilterLogs(opts, "SignMsg", msgHashRule) + if err != nil { + return nil, err + } + return &SafeV130SignMsgIterator{contract: _SafeV130.contract, event: "SignMsg", logs: logs, sub: sub}, nil +} + +// WatchSignMsg is a free log subscription operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_SafeV130 *SafeV130Filterer) WatchSignMsg(opts *bind.WatchOpts, sink chan<- *SafeV130SignMsg, msgHash [][32]byte) (event.Subscription, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _SafeV130.contract.WatchLogs(opts, "SignMsg", msgHashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeV130SignMsg) + if err := _SafeV130.contract.UnpackLog(event, "SignMsg", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSignMsg is a log parse operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_SafeV130 *SafeV130Filterer) ParseSignMsg(log types.Log) (*SafeV130SignMsg, error) { + event := new(SafeV130SignMsg) + if err := _SafeV130.contract.UnpackLog(event, "SignMsg", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-bindings/bindings/safe_v130_more.go b/op-bindings/bindings/safe_v130_more.go new file mode 100644 index 000000000000..22fcb12de9a4 --- /dev/null +++ b/op-bindings/bindings/safe_v130_more.go @@ -0,0 +1,9 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var Safe_v130DeployedBin = "0x6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506127d7565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b81019080803590602001909291908035906020019092919050505061280d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b8101908080359060200190929190505050612894565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128ac565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612c3e565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d78565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506132b5565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506132da565b005b348015610d3457600080fd5b50610d3d613369565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613512565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613518565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061353a565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff1690602001909291905050506136f8565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613820565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613a12565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613bb1565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bde565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f6f565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ff3565b005b34801561148957600080fd5b50611492614665565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061466f565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614817565b005b3480156116a457600080fd5b506116ad614878565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506148f6565b005b34801561174a57600080fd5b50611753614d29565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612c3e565b5b5050565b611bd2604182614e0590919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614e3f565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614e0590919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614e6e90919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614e6e90919063ffffffff16565b614e6e90919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156126bc5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b61272e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61273b858585855a614e8d565b9050801561278b573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a26127cf565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b600060606127e7868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561282b57600080fd5b506040519080825280601f01601f19166020018201604052801561285e5781602001600182028036833780820191505090505b50905060005b8381101561288957808501548060208302602085010152508080600101915050612864565b508091505092915050565b60076020528060005260406000206000915090505481565b6128b4614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561291e5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612a91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612c46614d62565b600354811115612cbe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612d35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000806000612d928e8e8e8e8e8e8e8e8e8e60055461466f565b905060056000815480929190600101919050555080805190602001209150612dbb8282866132da565b506000612dc6614ed9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612fac578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612e6957fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015612f3b578082015181840152602081019050612f20565b50505050905090810190601f168015612f685780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015612f9357600080fd5b505af1158015612fa7573d6000803e3d6000fd5b505050505b6101f4612fd36109c48b01603f60408d0281612fc457fe5b04614f0a90919063ffffffff16565b015a1015613049576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506130b28f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d146130a7578e6130ad565b6109c45a035b614e8d565b93506130c75a82614f2490919063ffffffff16565b905083806130d6575060008a14155b806130e2575060008814155b613154576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008089111561316e5761316b828b8b8b8b614f44565b90505b84156131b8577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a16131f8565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146132a4578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561328b57600080fd5b505af115801561329f573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111613357576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61336384848484611bbe565b50505050565b6060600060035467ffffffffffffffff8111801561338657600080fd5b506040519080825280602002602001820160405280156133b55781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613509578083838151811061346057fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061341f565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6135858a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508961514a565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146135c3576135c28461564a565b5b6136118787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615679565b600082111561362b5761362982600060018685614f44565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061374f878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a614e8d565b61375857600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156137e55780820151818401526020810190506137ca565b50505050905090810190601f1680156138125780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561383b57600080fd5b5060405190808252806020026020018201604052801561386a5781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561393d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561394857508482105b15613a03578084838151811061395a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506138d3565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613b14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613bc68c8c8c8c8c8c8c8c8c8c8c61466f565b8051906020012090509b9a5050505050505050505050565b613be6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c505750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613cc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613dc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f77614d62565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613ffb614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156140655750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561409d57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61410f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614210576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561427a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6142ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561470057fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b61478c614878565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61481f614d62565b6148288161564a565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6148a66125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b6148fe614d62565b806001600354031015614979576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156149e35750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614b55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614d2457614d2381612c3e565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614e03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614e185760009050614e39565b6000828402905082848281614e2957fe5b0414614e3457600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614e8357600080fd5b8091505092915050565b6000600180811115614e9b57fe5b836001811115614ea757fe5b1415614ec0576000808551602087018986f49050614ed0565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015614f1a5781614f1c565b825b905092915050565b600082821115614f3357600080fd5b600082840390508091505092915050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614614f815782614f83565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561509b57614fed3a8610614fca573a614fcc565b855b614fdf888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615096576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615140565b6150c0856150b2888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91506150cd8482846158b4565b61513f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600454146151c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615239576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156152b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156155b65760008482815181106152d057fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153445750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561537c57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156153b457508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b615426576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506152b9565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461577b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146158b05761583d8260008360015a614e8d565b6158af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d6000811461595b5760208114615963576000935061596e565b81935061596e565b600051158215171593505b505050939250505056fea26469706673582212203874bcf92e1722cc7bfa0cef1a0985cf0dc3485ba0663db3747ccdf1605df53464736f6c63430007060033" +func init() { + deployedBytecodes["Safe_v130"] = Safe_v130DeployedBin +} diff --git a/op-bindings/bindings/safel2_v130.go b/op-bindings/bindings/safel2_v130.go new file mode 100644 index 000000000000..c56dd37fa775 --- /dev/null +++ b/op-bindings/bindings/safel2_v130.go @@ -0,0 +1,3433 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// SafeL2V130MetaData contains all meta data concerning the SafeL2V130 contract. +var SafeL2V130MetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"AddedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"approvedHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ApproveHash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"handler\",\"type\":\"address\"}],\"name\":\"ChangedFallbackHandler\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"ChangedGuard\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"name\":\"ChangedThreshold\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"DisabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"EnabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"RemovedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"SafeModuleTransaction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"addresspayable\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"additionalInfo\",\"type\":\"bytes\"}],\"name\":\"SafeMultiSigTransaction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SafeReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"owners\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fallbackHandler\",\"type\":\"address\"}],\"name\":\"SafeSetup\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"SignMsg\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"addOwnerWithThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashToApprove\",\"type\":\"bytes32\"}],\"name\":\"approveHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"approvedHashes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"changeThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredSignatures\",\"type\":\"uint256\"}],\"name\":\"checkNSignatures\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"}],\"name\":\"checkSignatures\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevModule\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"disableModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"enableModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"encodeTransactionData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"addresspayable\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"}],\"name\":\"execTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModule\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModuleReturnData\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"start\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getModulesPaginated\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"array\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"next\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"getStorageAt\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"getTransactionHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"isModuleEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"removeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enumEnum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"requiredTxGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"handler\",\"type\":\"address\"}],\"name\":\"setFallbackHandler\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"setGuard\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"fallbackHandler\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"paymentToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"},{\"internalType\":\"addresspayable\",\"name\":\"paymentReceiver\",\"type\":\"address\"}],\"name\":\"setup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"signedMessages\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"calldataPayload\",\"type\":\"bytes\"}],\"name\":\"simulateAndRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"swapOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561001057600080fd5b506001600481905550615cf880620000296000396000f3fe6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506126fc565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b810190808035906020019092919080359060200190929190505050612732565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b81019080803590602001909291905050506127b9565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506127d1565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612b63565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612c9d565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612edc565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612f01565b005b348015610d3457600080fd5b50610d3d612f90565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613139565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061313f565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613161565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff16906020019092919050505061331f565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613447565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613639565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506137d8565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613805565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b96565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613c1a565b005b34801561148957600080fd5b5061149261428c565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614296565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061443e565b005b3480156116a457600080fd5b506116ad61449f565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061451d565b005b34801561174a57600080fd5b50611753614950565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614989565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612b63565b5b5050565b611bd2604182614a2c90919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614a66565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614a2c90919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614a9590919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614a9590919063ffffffff16565b614a9590919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b60007fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183600181111561266b57fe5b8152602001828103825284818151815260200191508051906020019080838360005b838110156126a857808201518184015260208101905061268d565b50505050905090810190601f1680156126d55780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a16126f285858585614ab4565b9050949350505050565b6000606061270c868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561275057600080fd5b506040519080825280601f01601f1916602001820160405280156127835781602001600182028036833780820191505090505b50905060005b838110156127ae57808501548060208302602085010152508080600101915050612789565b508091505092915050565b60076020528060005260406000206000915090505481565b6127d9614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156128435750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b6128b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146129b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612b6b614989565b600354811115612be3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612c5a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000606060055433600454604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612d5057fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184810384528e8e82818152602001925080828437600081840152601f19601f820116905080830192505050848103835286818151815260200191508051906020019080838360005b83811015612e0a578082015181840152602081019050612def565b50505050905090810190601f168015612e375780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b83811015612e70578082015181840152602081019050612e55565b50505050905090810190601f168015612e9d5780820380516001836020036101000a031916815260200191505b509f5050505050505050505050505050505060405180910390a1612eca8d8d8d8d8d8d8d8d8d8d8d614c9a565b9150509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111612f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612f8a84848484611bbe565b50505050565b6060600060035467ffffffffffffffff81118015612fad57600080fd5b50604051908082528060200260200182016040528015612fdc5781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613130578083838151811061308757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050613046565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6131ac8a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050896151d7565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146131ea576131e9846156d7565b5b6132388787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615706565b60008211156132525761325082600060018685615941565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a9050613376878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615b47565b61337f57600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561340c5780820151818401526020810190506133f1565b50505050905090810190601f1680156134395780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561346257600080fd5b506040519080825280602002602001820160405280156134915781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156135645750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561356f57508482105b1561362a578084838151811061358157fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506134fa565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561373b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b60006137ed8c8c8c8c8c8c8c8c8c8c8c614296565b8051906020012090509b9a5050505050505050505050565b61380d614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156138775750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b6138e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146139e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613b9e614989565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613c22614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c8c5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613cc457503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613d36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613e37576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613ea15750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b613f13576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614013576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561432757fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6143b361449f565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b614446614989565b61444f816156d7565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6144cd6125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b614525614989565b8060016003540310156145a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561460a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b61467c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461477c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1806004541461494b5761494a81612b63565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614a2a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614a3f5760009050614a60565b6000828402905082848281614a5057fe5b0414614a5b57600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614aaa57600080fd5b8091505092915050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015614b7f5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b614bf1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b614bfe858585855a615b47565b90508015614c4e573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a2614c92565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000806000614cb48e8e8e8e8e8e8e8e8e8e600554614296565b905060056000815480929190600101919050555080805190602001209150614cdd828286612f01565b506000614ce8615b93565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614614ece578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115614d8b57fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015614e5d578082015181840152602081019050614e42565b50505050905090810190601f168015614e8a5780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015614eb557600080fd5b505af1158015614ec9573d6000803e3d6000fd5b505050505b6101f4614ef56109c48b01603f60408d0281614ee657fe5b04615bc490919063ffffffff16565b015a1015614f6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a9050614fd48f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d14614fc9578e614fcf565b6109c45a035b615b47565b9350614fe95a82615bde90919063ffffffff16565b90508380614ff8575060008a14155b80615004575060008814155b615076576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808911156150905761508d828b8b8b8b615941565b90505b84156150da577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a161511a565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146151c6578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b1580156151ad57600080fd5b505af11580156151c1573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b60006004541461524f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b81518111156152c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600181101561533d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b835181101561564357600084828151811061535d57fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153d15750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561540957503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561544157508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b6154b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146155b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550809250508080600101915050615346565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615808576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461593d576158ca8260008360015a615b47565b61593c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461597e5782615980565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615a98576159ea3a86106159c7573a6159c9565b855b6159dc888a614a9590919063ffffffff16565b614a2c90919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615a93576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615b3d565b615abd85615aaf888a614a9590919063ffffffff16565b614a2c90919063ffffffff16565b9150615aca848284615bfe565b615b3c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600180811115615b5557fe5b836001811115615b6157fe5b1415615b7a576000808551602087018986f49050615b8a565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015615bd45781615bd6565b825b905092915050565b600082821115615bed57600080fd5b600082840390508091505092915050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d60008114615ca55760208114615cad5760009350615cb8565b819350615cb8565b600051158215171593505b505050939250505056fea2646970667358221220047fac33099ca576d1c4f1ac6a8abdb0396e42ad6a397d2cb2f4dc1624cc0c5b64736f6c63430007060033", +} + +// SafeL2V130ABI is the input ABI used to generate the binding from. +// Deprecated: Use SafeL2V130MetaData.ABI instead. +var SafeL2V130ABI = SafeL2V130MetaData.ABI + +// SafeL2V130Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SafeL2V130MetaData.Bin instead. +var SafeL2V130Bin = SafeL2V130MetaData.Bin + +// DeploySafeL2V130 deploys a new Ethereum contract, binding an instance of SafeL2V130 to it. +func DeploySafeL2V130(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SafeL2V130, error) { + parsed, err := SafeL2V130MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SafeL2V130Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &SafeL2V130{SafeL2V130Caller: SafeL2V130Caller{contract: contract}, SafeL2V130Transactor: SafeL2V130Transactor{contract: contract}, SafeL2V130Filterer: SafeL2V130Filterer{contract: contract}}, nil +} + +// SafeL2V130 is an auto generated Go binding around an Ethereum contract. +type SafeL2V130 struct { + SafeL2V130Caller // Read-only binding to the contract + SafeL2V130Transactor // Write-only binding to the contract + SafeL2V130Filterer // Log filterer for contract events +} + +// SafeL2V130Caller is an auto generated read-only Go binding around an Ethereum contract. +type SafeL2V130Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeL2V130Transactor is an auto generated write-only Go binding around an Ethereum contract. +type SafeL2V130Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeL2V130Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SafeL2V130Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeL2V130Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type SafeL2V130Session struct { + Contract *SafeL2V130 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SafeL2V130CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type SafeL2V130CallerSession struct { + Contract *SafeL2V130Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// SafeL2V130TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type SafeL2V130TransactorSession struct { + Contract *SafeL2V130Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SafeL2V130Raw is an auto generated low-level Go binding around an Ethereum contract. +type SafeL2V130Raw struct { + Contract *SafeL2V130 // Generic contract binding to access the raw methods on +} + +// SafeL2V130CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SafeL2V130CallerRaw struct { + Contract *SafeL2V130Caller // Generic read-only contract binding to access the raw methods on +} + +// SafeL2V130TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SafeL2V130TransactorRaw struct { + Contract *SafeL2V130Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewSafeL2V130 creates a new instance of SafeL2V130, bound to a specific deployed contract. +func NewSafeL2V130(address common.Address, backend bind.ContractBackend) (*SafeL2V130, error) { + contract, err := bindSafeL2V130(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &SafeL2V130{SafeL2V130Caller: SafeL2V130Caller{contract: contract}, SafeL2V130Transactor: SafeL2V130Transactor{contract: contract}, SafeL2V130Filterer: SafeL2V130Filterer{contract: contract}}, nil +} + +// NewSafeL2V130Caller creates a new read-only instance of SafeL2V130, bound to a specific deployed contract. +func NewSafeL2V130Caller(address common.Address, caller bind.ContractCaller) (*SafeL2V130Caller, error) { + contract, err := bindSafeL2V130(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &SafeL2V130Caller{contract: contract}, nil +} + +// NewSafeL2V130Transactor creates a new write-only instance of SafeL2V130, bound to a specific deployed contract. +func NewSafeL2V130Transactor(address common.Address, transactor bind.ContractTransactor) (*SafeL2V130Transactor, error) { + contract, err := bindSafeL2V130(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &SafeL2V130Transactor{contract: contract}, nil +} + +// NewSafeL2V130Filterer creates a new log filterer instance of SafeL2V130, bound to a specific deployed contract. +func NewSafeL2V130Filterer(address common.Address, filterer bind.ContractFilterer) (*SafeL2V130Filterer, error) { + contract, err := bindSafeL2V130(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &SafeL2V130Filterer{contract: contract}, nil +} + +// bindSafeL2V130 binds a generic wrapper to an already deployed contract. +func bindSafeL2V130(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SafeL2V130ABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SafeL2V130 *SafeL2V130Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SafeL2V130.Contract.SafeL2V130Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SafeL2V130 *SafeL2V130Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeL2V130.Contract.SafeL2V130Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SafeL2V130 *SafeL2V130Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SafeL2V130.Contract.SafeL2V130Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SafeL2V130 *SafeL2V130CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SafeL2V130.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SafeL2V130 *SafeL2V130TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeL2V130.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SafeL2V130 *SafeL2V130TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SafeL2V130.Contract.contract.Transact(opts, method, params...) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_SafeL2V130 *SafeL2V130Caller) VERSION(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "VERSION") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_SafeL2V130 *SafeL2V130Session) VERSION() (string, error) { + return _SafeL2V130.Contract.VERSION(&_SafeL2V130.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(string) +func (_SafeL2V130 *SafeL2V130CallerSession) VERSION() (string, error) { + return _SafeL2V130.Contract.VERSION(&_SafeL2V130.CallOpts) +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_SafeL2V130 *SafeL2V130Caller) ApprovedHashes(opts *bind.CallOpts, arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "approvedHashes", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_SafeL2V130 *SafeL2V130Session) ApprovedHashes(arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + return _SafeL2V130.Contract.ApprovedHashes(&_SafeL2V130.CallOpts, arg0, arg1) +} + +// ApprovedHashes is a free data retrieval call binding the contract method 0x7d832974. +// +// Solidity: function approvedHashes(address , bytes32 ) view returns(uint256) +func (_SafeL2V130 *SafeL2V130CallerSession) ApprovedHashes(arg0 common.Address, arg1 [32]byte) (*big.Int, error) { + return _SafeL2V130.Contract.ApprovedHashes(&_SafeL2V130.CallOpts, arg0, arg1) +} + +// CheckNSignatures is a free data retrieval call binding the contract method 0x12fb68e0. +// +// Solidity: function checkNSignatures(bytes32 dataHash, bytes data, bytes signatures, uint256 requiredSignatures) view returns() +func (_SafeL2V130 *SafeL2V130Caller) CheckNSignatures(opts *bind.CallOpts, dataHash [32]byte, data []byte, signatures []byte, requiredSignatures *big.Int) error { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "checkNSignatures", dataHash, data, signatures, requiredSignatures) + + if err != nil { + return err + } + + return err + +} + +// CheckNSignatures is a free data retrieval call binding the contract method 0x12fb68e0. +// +// Solidity: function checkNSignatures(bytes32 dataHash, bytes data, bytes signatures, uint256 requiredSignatures) view returns() +func (_SafeL2V130 *SafeL2V130Session) CheckNSignatures(dataHash [32]byte, data []byte, signatures []byte, requiredSignatures *big.Int) error { + return _SafeL2V130.Contract.CheckNSignatures(&_SafeL2V130.CallOpts, dataHash, data, signatures, requiredSignatures) +} + +// CheckNSignatures is a free data retrieval call binding the contract method 0x12fb68e0. +// +// Solidity: function checkNSignatures(bytes32 dataHash, bytes data, bytes signatures, uint256 requiredSignatures) view returns() +func (_SafeL2V130 *SafeL2V130CallerSession) CheckNSignatures(dataHash [32]byte, data []byte, signatures []byte, requiredSignatures *big.Int) error { + return _SafeL2V130.Contract.CheckNSignatures(&_SafeL2V130.CallOpts, dataHash, data, signatures, requiredSignatures) +} + +// CheckSignatures is a free data retrieval call binding the contract method 0x934f3a11. +// +// Solidity: function checkSignatures(bytes32 dataHash, bytes data, bytes signatures) view returns() +func (_SafeL2V130 *SafeL2V130Caller) CheckSignatures(opts *bind.CallOpts, dataHash [32]byte, data []byte, signatures []byte) error { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "checkSignatures", dataHash, data, signatures) + + if err != nil { + return err + } + + return err + +} + +// CheckSignatures is a free data retrieval call binding the contract method 0x934f3a11. +// +// Solidity: function checkSignatures(bytes32 dataHash, bytes data, bytes signatures) view returns() +func (_SafeL2V130 *SafeL2V130Session) CheckSignatures(dataHash [32]byte, data []byte, signatures []byte) error { + return _SafeL2V130.Contract.CheckSignatures(&_SafeL2V130.CallOpts, dataHash, data, signatures) +} + +// CheckSignatures is a free data retrieval call binding the contract method 0x934f3a11. +// +// Solidity: function checkSignatures(bytes32 dataHash, bytes data, bytes signatures) view returns() +func (_SafeL2V130 *SafeL2V130CallerSession) CheckSignatures(dataHash [32]byte, data []byte, signatures []byte) error { + return _SafeL2V130.Contract.CheckSignatures(&_SafeL2V130.CallOpts, dataHash, data, signatures) +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_SafeL2V130 *SafeL2V130Caller) DomainSeparator(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "domainSeparator") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_SafeL2V130 *SafeL2V130Session) DomainSeparator() ([32]byte, error) { + return _SafeL2V130.Contract.DomainSeparator(&_SafeL2V130.CallOpts) +} + +// DomainSeparator is a free data retrieval call binding the contract method 0xf698da25. +// +// Solidity: function domainSeparator() view returns(bytes32) +func (_SafeL2V130 *SafeL2V130CallerSession) DomainSeparator() ([32]byte, error) { + return _SafeL2V130.Contract.DomainSeparator(&_SafeL2V130.CallOpts) +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_SafeL2V130 *SafeL2V130Caller) EncodeTransactionData(opts *bind.CallOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "encodeTransactionData", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_SafeL2V130 *SafeL2V130Session) EncodeTransactionData(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + return _SafeL2V130.Contract.EncodeTransactionData(&_SafeL2V130.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// EncodeTransactionData is a free data retrieval call binding the contract method 0xe86637db. +// +// Solidity: function encodeTransactionData(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes) +func (_SafeL2V130 *SafeL2V130CallerSession) EncodeTransactionData(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([]byte, error) { + return _SafeL2V130.Contract.EncodeTransactionData(&_SafeL2V130.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_SafeL2V130 *SafeL2V130Caller) GetChainId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "getChainId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_SafeL2V130 *SafeL2V130Session) GetChainId() (*big.Int, error) { + return _SafeL2V130.Contract.GetChainId(&_SafeL2V130.CallOpts) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_SafeL2V130 *SafeL2V130CallerSession) GetChainId() (*big.Int, error) { + return _SafeL2V130.Contract.GetChainId(&_SafeL2V130.CallOpts) +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_SafeL2V130 *SafeL2V130Caller) GetModulesPaginated(opts *bind.CallOpts, start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "getModulesPaginated", start, pageSize) + + outstruct := new(struct { + Array []common.Address + Next common.Address + }) + if err != nil { + return *outstruct, err + } + + outstruct.Array = *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + outstruct.Next = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_SafeL2V130 *SafeL2V130Session) GetModulesPaginated(start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + return _SafeL2V130.Contract.GetModulesPaginated(&_SafeL2V130.CallOpts, start, pageSize) +} + +// GetModulesPaginated is a free data retrieval call binding the contract method 0xcc2f8452. +// +// Solidity: function getModulesPaginated(address start, uint256 pageSize) view returns(address[] array, address next) +func (_SafeL2V130 *SafeL2V130CallerSession) GetModulesPaginated(start common.Address, pageSize *big.Int) (struct { + Array []common.Address + Next common.Address +}, error) { + return _SafeL2V130.Contract.GetModulesPaginated(&_SafeL2V130.CallOpts, start, pageSize) +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_SafeL2V130 *SafeL2V130Caller) GetOwners(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "getOwners") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_SafeL2V130 *SafeL2V130Session) GetOwners() ([]common.Address, error) { + return _SafeL2V130.Contract.GetOwners(&_SafeL2V130.CallOpts) +} + +// GetOwners is a free data retrieval call binding the contract method 0xa0e67e2b. +// +// Solidity: function getOwners() view returns(address[]) +func (_SafeL2V130 *SafeL2V130CallerSession) GetOwners() ([]common.Address, error) { + return _SafeL2V130.Contract.GetOwners(&_SafeL2V130.CallOpts) +} + +// GetStorageAt is a free data retrieval call binding the contract method 0x5624b25b. +// +// Solidity: function getStorageAt(uint256 offset, uint256 length) view returns(bytes) +func (_SafeL2V130 *SafeL2V130Caller) GetStorageAt(opts *bind.CallOpts, offset *big.Int, length *big.Int) ([]byte, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "getStorageAt", offset, length) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// GetStorageAt is a free data retrieval call binding the contract method 0x5624b25b. +// +// Solidity: function getStorageAt(uint256 offset, uint256 length) view returns(bytes) +func (_SafeL2V130 *SafeL2V130Session) GetStorageAt(offset *big.Int, length *big.Int) ([]byte, error) { + return _SafeL2V130.Contract.GetStorageAt(&_SafeL2V130.CallOpts, offset, length) +} + +// GetStorageAt is a free data retrieval call binding the contract method 0x5624b25b. +// +// Solidity: function getStorageAt(uint256 offset, uint256 length) view returns(bytes) +func (_SafeL2V130 *SafeL2V130CallerSession) GetStorageAt(offset *big.Int, length *big.Int) ([]byte, error) { + return _SafeL2V130.Contract.GetStorageAt(&_SafeL2V130.CallOpts, offset, length) +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_SafeL2V130 *SafeL2V130Caller) GetThreshold(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "getThreshold") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_SafeL2V130 *SafeL2V130Session) GetThreshold() (*big.Int, error) { + return _SafeL2V130.Contract.GetThreshold(&_SafeL2V130.CallOpts) +} + +// GetThreshold is a free data retrieval call binding the contract method 0xe75235b8. +// +// Solidity: function getThreshold() view returns(uint256) +func (_SafeL2V130 *SafeL2V130CallerSession) GetThreshold() (*big.Int, error) { + return _SafeL2V130.Contract.GetThreshold(&_SafeL2V130.CallOpts) +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_SafeL2V130 *SafeL2V130Caller) GetTransactionHash(opts *bind.CallOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "getTransactionHash", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_SafeL2V130 *SafeL2V130Session) GetTransactionHash(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + return _SafeL2V130.Contract.GetTransactionHash(&_SafeL2V130.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// GetTransactionHash is a free data retrieval call binding the contract method 0xd8d11f78. +// +// Solidity: function getTransactionHash(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce) view returns(bytes32) +func (_SafeL2V130 *SafeL2V130CallerSession) GetTransactionHash(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, _nonce *big.Int) ([32]byte, error) { + return _SafeL2V130.Contract.GetTransactionHash(&_SafeL2V130.CallOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_SafeL2V130 *SafeL2V130Caller) IsModuleEnabled(opts *bind.CallOpts, module common.Address) (bool, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "isModuleEnabled", module) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_SafeL2V130 *SafeL2V130Session) IsModuleEnabled(module common.Address) (bool, error) { + return _SafeL2V130.Contract.IsModuleEnabled(&_SafeL2V130.CallOpts, module) +} + +// IsModuleEnabled is a free data retrieval call binding the contract method 0x2d9ad53d. +// +// Solidity: function isModuleEnabled(address module) view returns(bool) +func (_SafeL2V130 *SafeL2V130CallerSession) IsModuleEnabled(module common.Address) (bool, error) { + return _SafeL2V130.Contract.IsModuleEnabled(&_SafeL2V130.CallOpts, module) +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_SafeL2V130 *SafeL2V130Caller) IsOwner(opts *bind.CallOpts, owner common.Address) (bool, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "isOwner", owner) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_SafeL2V130 *SafeL2V130Session) IsOwner(owner common.Address) (bool, error) { + return _SafeL2V130.Contract.IsOwner(&_SafeL2V130.CallOpts, owner) +} + +// IsOwner is a free data retrieval call binding the contract method 0x2f54bf6e. +// +// Solidity: function isOwner(address owner) view returns(bool) +func (_SafeL2V130 *SafeL2V130CallerSession) IsOwner(owner common.Address) (bool, error) { + return _SafeL2V130.Contract.IsOwner(&_SafeL2V130.CallOpts, owner) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_SafeL2V130 *SafeL2V130Caller) Nonce(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "nonce") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_SafeL2V130 *SafeL2V130Session) Nonce() (*big.Int, error) { + return _SafeL2V130.Contract.Nonce(&_SafeL2V130.CallOpts) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint256) +func (_SafeL2V130 *SafeL2V130CallerSession) Nonce() (*big.Int, error) { + return _SafeL2V130.Contract.Nonce(&_SafeL2V130.CallOpts) +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_SafeL2V130 *SafeL2V130Caller) SignedMessages(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) { + var out []interface{} + err := _SafeL2V130.contract.Call(opts, &out, "signedMessages", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_SafeL2V130 *SafeL2V130Session) SignedMessages(arg0 [32]byte) (*big.Int, error) { + return _SafeL2V130.Contract.SignedMessages(&_SafeL2V130.CallOpts, arg0) +} + +// SignedMessages is a free data retrieval call binding the contract method 0x5ae6bd37. +// +// Solidity: function signedMessages(bytes32 ) view returns(uint256) +func (_SafeL2V130 *SafeL2V130CallerSession) SignedMessages(arg0 [32]byte) (*big.Int, error) { + return _SafeL2V130.Contract.SignedMessages(&_SafeL2V130.CallOpts, arg0) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_SafeL2V130 *SafeL2V130Transactor) AddOwnerWithThreshold(opts *bind.TransactOpts, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "addOwnerWithThreshold", owner, _threshold) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_SafeL2V130 *SafeL2V130Session) AddOwnerWithThreshold(owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeL2V130.Contract.AddOwnerWithThreshold(&_SafeL2V130.TransactOpts, owner, _threshold) +} + +// AddOwnerWithThreshold is a paid mutator transaction binding the contract method 0x0d582f13. +// +// Solidity: function addOwnerWithThreshold(address owner, uint256 _threshold) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) AddOwnerWithThreshold(owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeL2V130.Contract.AddOwnerWithThreshold(&_SafeL2V130.TransactOpts, owner, _threshold) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_SafeL2V130 *SafeL2V130Transactor) ApproveHash(opts *bind.TransactOpts, hashToApprove [32]byte) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "approveHash", hashToApprove) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_SafeL2V130 *SafeL2V130Session) ApproveHash(hashToApprove [32]byte) (*types.Transaction, error) { + return _SafeL2V130.Contract.ApproveHash(&_SafeL2V130.TransactOpts, hashToApprove) +} + +// ApproveHash is a paid mutator transaction binding the contract method 0xd4d9bdcd. +// +// Solidity: function approveHash(bytes32 hashToApprove) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) ApproveHash(hashToApprove [32]byte) (*types.Transaction, error) { + return _SafeL2V130.Contract.ApproveHash(&_SafeL2V130.TransactOpts, hashToApprove) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_SafeL2V130 *SafeL2V130Transactor) ChangeThreshold(opts *bind.TransactOpts, _threshold *big.Int) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "changeThreshold", _threshold) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_SafeL2V130 *SafeL2V130Session) ChangeThreshold(_threshold *big.Int) (*types.Transaction, error) { + return _SafeL2V130.Contract.ChangeThreshold(&_SafeL2V130.TransactOpts, _threshold) +} + +// ChangeThreshold is a paid mutator transaction binding the contract method 0x694e80c3. +// +// Solidity: function changeThreshold(uint256 _threshold) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) ChangeThreshold(_threshold *big.Int) (*types.Transaction, error) { + return _SafeL2V130.Contract.ChangeThreshold(&_SafeL2V130.TransactOpts, _threshold) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_SafeL2V130 *SafeL2V130Transactor) DisableModule(opts *bind.TransactOpts, prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "disableModule", prevModule, module) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_SafeL2V130 *SafeL2V130Session) DisableModule(prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.DisableModule(&_SafeL2V130.TransactOpts, prevModule, module) +} + +// DisableModule is a paid mutator transaction binding the contract method 0xe009cfde. +// +// Solidity: function disableModule(address prevModule, address module) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) DisableModule(prevModule common.Address, module common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.DisableModule(&_SafeL2V130.TransactOpts, prevModule, module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_SafeL2V130 *SafeL2V130Transactor) EnableModule(opts *bind.TransactOpts, module common.Address) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "enableModule", module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_SafeL2V130 *SafeL2V130Session) EnableModule(module common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.EnableModule(&_SafeL2V130.TransactOpts, module) +} + +// EnableModule is a paid mutator transaction binding the contract method 0x610b5925. +// +// Solidity: function enableModule(address module) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) EnableModule(module common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.EnableModule(&_SafeL2V130.TransactOpts, module) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool) +func (_SafeL2V130 *SafeL2V130Transactor) ExecTransaction(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "execTransaction", to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool) +func (_SafeL2V130 *SafeL2V130Session) ExecTransaction(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _SafeL2V130.Contract.ExecTransaction(&_SafeL2V130.TransactOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransaction is a paid mutator transaction binding the contract method 0x6a761202. +// +// Solidity: function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures) payable returns(bool) +func (_SafeL2V130 *SafeL2V130TransactorSession) ExecTransaction(to common.Address, value *big.Int, data []byte, operation uint8, safeTxGas *big.Int, baseGas *big.Int, gasPrice *big.Int, gasToken common.Address, refundReceiver common.Address, signatures []byte) (*types.Transaction, error) { + return _SafeL2V130.Contract.ExecTransaction(&_SafeL2V130.TransactOpts, to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_SafeL2V130 *SafeL2V130Transactor) ExecTransactionFromModule(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "execTransactionFromModule", to, value, data, operation) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_SafeL2V130 *SafeL2V130Session) ExecTransactionFromModule(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeL2V130.Contract.ExecTransactionFromModule(&_SafeL2V130.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModule is a paid mutator transaction binding the contract method 0x468721a7. +// +// Solidity: function execTransactionFromModule(address to, uint256 value, bytes data, uint8 operation) returns(bool success) +func (_SafeL2V130 *SafeL2V130TransactorSession) ExecTransactionFromModule(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeL2V130.Contract.ExecTransactionFromModule(&_SafeL2V130.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_SafeL2V130 *SafeL2V130Transactor) ExecTransactionFromModuleReturnData(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "execTransactionFromModuleReturnData", to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_SafeL2V130 *SafeL2V130Session) ExecTransactionFromModuleReturnData(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeL2V130.Contract.ExecTransactionFromModuleReturnData(&_SafeL2V130.TransactOpts, to, value, data, operation) +} + +// ExecTransactionFromModuleReturnData is a paid mutator transaction binding the contract method 0x5229073f. +// +// Solidity: function execTransactionFromModuleReturnData(address to, uint256 value, bytes data, uint8 operation) returns(bool success, bytes returnData) +func (_SafeL2V130 *SafeL2V130TransactorSession) ExecTransactionFromModuleReturnData(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeL2V130.Contract.ExecTransactionFromModuleReturnData(&_SafeL2V130.TransactOpts, to, value, data, operation) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_SafeL2V130 *SafeL2V130Transactor) RemoveOwner(opts *bind.TransactOpts, prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "removeOwner", prevOwner, owner, _threshold) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_SafeL2V130 *SafeL2V130Session) RemoveOwner(prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeL2V130.Contract.RemoveOwner(&_SafeL2V130.TransactOpts, prevOwner, owner, _threshold) +} + +// RemoveOwner is a paid mutator transaction binding the contract method 0xf8dc5dd9. +// +// Solidity: function removeOwner(address prevOwner, address owner, uint256 _threshold) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) RemoveOwner(prevOwner common.Address, owner common.Address, _threshold *big.Int) (*types.Transaction, error) { + return _SafeL2V130.Contract.RemoveOwner(&_SafeL2V130.TransactOpts, prevOwner, owner, _threshold) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_SafeL2V130 *SafeL2V130Transactor) RequiredTxGas(opts *bind.TransactOpts, to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "requiredTxGas", to, value, data, operation) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_SafeL2V130 *SafeL2V130Session) RequiredTxGas(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeL2V130.Contract.RequiredTxGas(&_SafeL2V130.TransactOpts, to, value, data, operation) +} + +// RequiredTxGas is a paid mutator transaction binding the contract method 0xc4ca3a9c. +// +// Solidity: function requiredTxGas(address to, uint256 value, bytes data, uint8 operation) returns(uint256) +func (_SafeL2V130 *SafeL2V130TransactorSession) RequiredTxGas(to common.Address, value *big.Int, data []byte, operation uint8) (*types.Transaction, error) { + return _SafeL2V130.Contract.RequiredTxGas(&_SafeL2V130.TransactOpts, to, value, data, operation) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_SafeL2V130 *SafeL2V130Transactor) SetFallbackHandler(opts *bind.TransactOpts, handler common.Address) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "setFallbackHandler", handler) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_SafeL2V130 *SafeL2V130Session) SetFallbackHandler(handler common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.SetFallbackHandler(&_SafeL2V130.TransactOpts, handler) +} + +// SetFallbackHandler is a paid mutator transaction binding the contract method 0xf08a0323. +// +// Solidity: function setFallbackHandler(address handler) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) SetFallbackHandler(handler common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.SetFallbackHandler(&_SafeL2V130.TransactOpts, handler) +} + +// SetGuard is a paid mutator transaction binding the contract method 0xe19a9dd9. +// +// Solidity: function setGuard(address guard) returns() +func (_SafeL2V130 *SafeL2V130Transactor) SetGuard(opts *bind.TransactOpts, guard common.Address) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "setGuard", guard) +} + +// SetGuard is a paid mutator transaction binding the contract method 0xe19a9dd9. +// +// Solidity: function setGuard(address guard) returns() +func (_SafeL2V130 *SafeL2V130Session) SetGuard(guard common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.SetGuard(&_SafeL2V130.TransactOpts, guard) +} + +// SetGuard is a paid mutator transaction binding the contract method 0xe19a9dd9. +// +// Solidity: function setGuard(address guard) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) SetGuard(guard common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.SetGuard(&_SafeL2V130.TransactOpts, guard) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_SafeL2V130 *SafeL2V130Transactor) Setup(opts *bind.TransactOpts, _owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "setup", _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_SafeL2V130 *SafeL2V130Session) Setup(_owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.Setup(&_SafeL2V130.TransactOpts, _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// Setup is a paid mutator transaction binding the contract method 0xb63e800d. +// +// Solidity: function setup(address[] _owners, uint256 _threshold, address to, bytes data, address fallbackHandler, address paymentToken, uint256 payment, address paymentReceiver) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) Setup(_owners []common.Address, _threshold *big.Int, to common.Address, data []byte, fallbackHandler common.Address, paymentToken common.Address, payment *big.Int, paymentReceiver common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.Setup(&_SafeL2V130.TransactOpts, _owners, _threshold, to, data, fallbackHandler, paymentToken, payment, paymentReceiver) +} + +// SimulateAndRevert is a paid mutator transaction binding the contract method 0xb4faba09. +// +// Solidity: function simulateAndRevert(address targetContract, bytes calldataPayload) returns() +func (_SafeL2V130 *SafeL2V130Transactor) SimulateAndRevert(opts *bind.TransactOpts, targetContract common.Address, calldataPayload []byte) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "simulateAndRevert", targetContract, calldataPayload) +} + +// SimulateAndRevert is a paid mutator transaction binding the contract method 0xb4faba09. +// +// Solidity: function simulateAndRevert(address targetContract, bytes calldataPayload) returns() +func (_SafeL2V130 *SafeL2V130Session) SimulateAndRevert(targetContract common.Address, calldataPayload []byte) (*types.Transaction, error) { + return _SafeL2V130.Contract.SimulateAndRevert(&_SafeL2V130.TransactOpts, targetContract, calldataPayload) +} + +// SimulateAndRevert is a paid mutator transaction binding the contract method 0xb4faba09. +// +// Solidity: function simulateAndRevert(address targetContract, bytes calldataPayload) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) SimulateAndRevert(targetContract common.Address, calldataPayload []byte) (*types.Transaction, error) { + return _SafeL2V130.Contract.SimulateAndRevert(&_SafeL2V130.TransactOpts, targetContract, calldataPayload) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_SafeL2V130 *SafeL2V130Transactor) SwapOwner(opts *bind.TransactOpts, prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _SafeL2V130.contract.Transact(opts, "swapOwner", prevOwner, oldOwner, newOwner) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_SafeL2V130 *SafeL2V130Session) SwapOwner(prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.SwapOwner(&_SafeL2V130.TransactOpts, prevOwner, oldOwner, newOwner) +} + +// SwapOwner is a paid mutator transaction binding the contract method 0xe318b52b. +// +// Solidity: function swapOwner(address prevOwner, address oldOwner, address newOwner) returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) SwapOwner(prevOwner common.Address, oldOwner common.Address, newOwner common.Address) (*types.Transaction, error) { + return _SafeL2V130.Contract.SwapOwner(&_SafeL2V130.TransactOpts, prevOwner, oldOwner, newOwner) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() returns() +func (_SafeL2V130 *SafeL2V130Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _SafeL2V130.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() returns() +func (_SafeL2V130 *SafeL2V130Session) Fallback(calldata []byte) (*types.Transaction, error) { + return _SafeL2V130.Contract.Fallback(&_SafeL2V130.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _SafeL2V130.Contract.Fallback(&_SafeL2V130.TransactOpts, calldata) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_SafeL2V130 *SafeL2V130Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeL2V130.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_SafeL2V130 *SafeL2V130Session) Receive() (*types.Transaction, error) { + return _SafeL2V130.Contract.Receive(&_SafeL2V130.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_SafeL2V130 *SafeL2V130TransactorSession) Receive() (*types.Transaction, error) { + return _SafeL2V130.Contract.Receive(&_SafeL2V130.TransactOpts) +} + +// SafeL2V130AddedOwnerIterator is returned from FilterAddedOwner and is used to iterate over the raw logs and unpacked data for AddedOwner events raised by the SafeL2V130 contract. +type SafeL2V130AddedOwnerIterator struct { + Event *SafeL2V130AddedOwner // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130AddedOwnerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130AddedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130AddedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130AddedOwnerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130AddedOwnerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130AddedOwner represents a AddedOwner event raised by the SafeL2V130 contract. +type SafeL2V130AddedOwner struct { + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAddedOwner is a free log retrieval operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_SafeL2V130 *SafeL2V130Filterer) FilterAddedOwner(opts *bind.FilterOpts) (*SafeL2V130AddedOwnerIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "AddedOwner") + if err != nil { + return nil, err + } + return &SafeL2V130AddedOwnerIterator{contract: _SafeL2V130.contract, event: "AddedOwner", logs: logs, sub: sub}, nil +} + +// WatchAddedOwner is a free log subscription operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_SafeL2V130 *SafeL2V130Filterer) WatchAddedOwner(opts *bind.WatchOpts, sink chan<- *SafeL2V130AddedOwner) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "AddedOwner") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130AddedOwner) + if err := _SafeL2V130.contract.UnpackLog(event, "AddedOwner", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAddedOwner is a log parse operation binding the contract event 0x9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26. +// +// Solidity: event AddedOwner(address owner) +func (_SafeL2V130 *SafeL2V130Filterer) ParseAddedOwner(log types.Log) (*SafeL2V130AddedOwner, error) { + event := new(SafeL2V130AddedOwner) + if err := _SafeL2V130.contract.UnpackLog(event, "AddedOwner", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130ApproveHashIterator is returned from FilterApproveHash and is used to iterate over the raw logs and unpacked data for ApproveHash events raised by the SafeL2V130 contract. +type SafeL2V130ApproveHashIterator struct { + Event *SafeL2V130ApproveHash // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130ApproveHashIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ApproveHash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ApproveHash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130ApproveHashIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130ApproveHashIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130ApproveHash represents a ApproveHash event raised by the SafeL2V130 contract. +type SafeL2V130ApproveHash struct { + ApprovedHash [32]byte + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproveHash is a free log retrieval operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_SafeL2V130 *SafeL2V130Filterer) FilterApproveHash(opts *bind.FilterOpts, approvedHash [][32]byte, owner []common.Address) (*SafeL2V130ApproveHashIterator, error) { + + var approvedHashRule []interface{} + for _, approvedHashItem := range approvedHash { + approvedHashRule = append(approvedHashRule, approvedHashItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "ApproveHash", approvedHashRule, ownerRule) + if err != nil { + return nil, err + } + return &SafeL2V130ApproveHashIterator{contract: _SafeL2V130.contract, event: "ApproveHash", logs: logs, sub: sub}, nil +} + +// WatchApproveHash is a free log subscription operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_SafeL2V130 *SafeL2V130Filterer) WatchApproveHash(opts *bind.WatchOpts, sink chan<- *SafeL2V130ApproveHash, approvedHash [][32]byte, owner []common.Address) (event.Subscription, error) { + + var approvedHashRule []interface{} + for _, approvedHashItem := range approvedHash { + approvedHashRule = append(approvedHashRule, approvedHashItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "ApproveHash", approvedHashRule, ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130ApproveHash) + if err := _SafeL2V130.contract.UnpackLog(event, "ApproveHash", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproveHash is a log parse operation binding the contract event 0xf2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c. +// +// Solidity: event ApproveHash(bytes32 indexed approvedHash, address indexed owner) +func (_SafeL2V130 *SafeL2V130Filterer) ParseApproveHash(log types.Log) (*SafeL2V130ApproveHash, error) { + event := new(SafeL2V130ApproveHash) + if err := _SafeL2V130.contract.UnpackLog(event, "ApproveHash", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130ChangedFallbackHandlerIterator is returned from FilterChangedFallbackHandler and is used to iterate over the raw logs and unpacked data for ChangedFallbackHandler events raised by the SafeL2V130 contract. +type SafeL2V130ChangedFallbackHandlerIterator struct { + Event *SafeL2V130ChangedFallbackHandler // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130ChangedFallbackHandlerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ChangedFallbackHandler) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ChangedFallbackHandler) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130ChangedFallbackHandlerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130ChangedFallbackHandlerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130ChangedFallbackHandler represents a ChangedFallbackHandler event raised by the SafeL2V130 contract. +type SafeL2V130ChangedFallbackHandler struct { + Handler common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangedFallbackHandler is a free log retrieval operation binding the contract event 0x5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b0. +// +// Solidity: event ChangedFallbackHandler(address handler) +func (_SafeL2V130 *SafeL2V130Filterer) FilterChangedFallbackHandler(opts *bind.FilterOpts) (*SafeL2V130ChangedFallbackHandlerIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "ChangedFallbackHandler") + if err != nil { + return nil, err + } + return &SafeL2V130ChangedFallbackHandlerIterator{contract: _SafeL2V130.contract, event: "ChangedFallbackHandler", logs: logs, sub: sub}, nil +} + +// WatchChangedFallbackHandler is a free log subscription operation binding the contract event 0x5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b0. +// +// Solidity: event ChangedFallbackHandler(address handler) +func (_SafeL2V130 *SafeL2V130Filterer) WatchChangedFallbackHandler(opts *bind.WatchOpts, sink chan<- *SafeL2V130ChangedFallbackHandler) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "ChangedFallbackHandler") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130ChangedFallbackHandler) + if err := _SafeL2V130.contract.UnpackLog(event, "ChangedFallbackHandler", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangedFallbackHandler is a log parse operation binding the contract event 0x5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b0. +// +// Solidity: event ChangedFallbackHandler(address handler) +func (_SafeL2V130 *SafeL2V130Filterer) ParseChangedFallbackHandler(log types.Log) (*SafeL2V130ChangedFallbackHandler, error) { + event := new(SafeL2V130ChangedFallbackHandler) + if err := _SafeL2V130.contract.UnpackLog(event, "ChangedFallbackHandler", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130ChangedGuardIterator is returned from FilterChangedGuard and is used to iterate over the raw logs and unpacked data for ChangedGuard events raised by the SafeL2V130 contract. +type SafeL2V130ChangedGuardIterator struct { + Event *SafeL2V130ChangedGuard // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130ChangedGuardIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ChangedGuard) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ChangedGuard) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130ChangedGuardIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130ChangedGuardIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130ChangedGuard represents a ChangedGuard event raised by the SafeL2V130 contract. +type SafeL2V130ChangedGuard struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangedGuard is a free log retrieval operation binding the contract event 0x1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2. +// +// Solidity: event ChangedGuard(address guard) +func (_SafeL2V130 *SafeL2V130Filterer) FilterChangedGuard(opts *bind.FilterOpts) (*SafeL2V130ChangedGuardIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "ChangedGuard") + if err != nil { + return nil, err + } + return &SafeL2V130ChangedGuardIterator{contract: _SafeL2V130.contract, event: "ChangedGuard", logs: logs, sub: sub}, nil +} + +// WatchChangedGuard is a free log subscription operation binding the contract event 0x1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2. +// +// Solidity: event ChangedGuard(address guard) +func (_SafeL2V130 *SafeL2V130Filterer) WatchChangedGuard(opts *bind.WatchOpts, sink chan<- *SafeL2V130ChangedGuard) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "ChangedGuard") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130ChangedGuard) + if err := _SafeL2V130.contract.UnpackLog(event, "ChangedGuard", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangedGuard is a log parse operation binding the contract event 0x1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2. +// +// Solidity: event ChangedGuard(address guard) +func (_SafeL2V130 *SafeL2V130Filterer) ParseChangedGuard(log types.Log) (*SafeL2V130ChangedGuard, error) { + event := new(SafeL2V130ChangedGuard) + if err := _SafeL2V130.contract.UnpackLog(event, "ChangedGuard", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130ChangedThresholdIterator is returned from FilterChangedThreshold and is used to iterate over the raw logs and unpacked data for ChangedThreshold events raised by the SafeL2V130 contract. +type SafeL2V130ChangedThresholdIterator struct { + Event *SafeL2V130ChangedThreshold // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130ChangedThresholdIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ChangedThreshold) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ChangedThreshold) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130ChangedThresholdIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130ChangedThresholdIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130ChangedThreshold represents a ChangedThreshold event raised by the SafeL2V130 contract. +type SafeL2V130ChangedThreshold struct { + Threshold *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangedThreshold is a free log retrieval operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_SafeL2V130 *SafeL2V130Filterer) FilterChangedThreshold(opts *bind.FilterOpts) (*SafeL2V130ChangedThresholdIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "ChangedThreshold") + if err != nil { + return nil, err + } + return &SafeL2V130ChangedThresholdIterator{contract: _SafeL2V130.contract, event: "ChangedThreshold", logs: logs, sub: sub}, nil +} + +// WatchChangedThreshold is a free log subscription operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_SafeL2V130 *SafeL2V130Filterer) WatchChangedThreshold(opts *bind.WatchOpts, sink chan<- *SafeL2V130ChangedThreshold) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "ChangedThreshold") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130ChangedThreshold) + if err := _SafeL2V130.contract.UnpackLog(event, "ChangedThreshold", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangedThreshold is a log parse operation binding the contract event 0x610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93. +// +// Solidity: event ChangedThreshold(uint256 threshold) +func (_SafeL2V130 *SafeL2V130Filterer) ParseChangedThreshold(log types.Log) (*SafeL2V130ChangedThreshold, error) { + event := new(SafeL2V130ChangedThreshold) + if err := _SafeL2V130.contract.UnpackLog(event, "ChangedThreshold", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130DisabledModuleIterator is returned from FilterDisabledModule and is used to iterate over the raw logs and unpacked data for DisabledModule events raised by the SafeL2V130 contract. +type SafeL2V130DisabledModuleIterator struct { + Event *SafeL2V130DisabledModule // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130DisabledModuleIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130DisabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130DisabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130DisabledModuleIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130DisabledModuleIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130DisabledModule represents a DisabledModule event raised by the SafeL2V130 contract. +type SafeL2V130DisabledModule struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDisabledModule is a free log retrieval operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_SafeL2V130 *SafeL2V130Filterer) FilterDisabledModule(opts *bind.FilterOpts) (*SafeL2V130DisabledModuleIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "DisabledModule") + if err != nil { + return nil, err + } + return &SafeL2V130DisabledModuleIterator{contract: _SafeL2V130.contract, event: "DisabledModule", logs: logs, sub: sub}, nil +} + +// WatchDisabledModule is a free log subscription operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_SafeL2V130 *SafeL2V130Filterer) WatchDisabledModule(opts *bind.WatchOpts, sink chan<- *SafeL2V130DisabledModule) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "DisabledModule") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130DisabledModule) + if err := _SafeL2V130.contract.UnpackLog(event, "DisabledModule", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDisabledModule is a log parse operation binding the contract event 0xaab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276. +// +// Solidity: event DisabledModule(address module) +func (_SafeL2V130 *SafeL2V130Filterer) ParseDisabledModule(log types.Log) (*SafeL2V130DisabledModule, error) { + event := new(SafeL2V130DisabledModule) + if err := _SafeL2V130.contract.UnpackLog(event, "DisabledModule", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130EnabledModuleIterator is returned from FilterEnabledModule and is used to iterate over the raw logs and unpacked data for EnabledModule events raised by the SafeL2V130 contract. +type SafeL2V130EnabledModuleIterator struct { + Event *SafeL2V130EnabledModule // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130EnabledModuleIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130EnabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130EnabledModule) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130EnabledModuleIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130EnabledModuleIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130EnabledModule represents a EnabledModule event raised by the SafeL2V130 contract. +type SafeL2V130EnabledModule struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEnabledModule is a free log retrieval operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_SafeL2V130 *SafeL2V130Filterer) FilterEnabledModule(opts *bind.FilterOpts) (*SafeL2V130EnabledModuleIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "EnabledModule") + if err != nil { + return nil, err + } + return &SafeL2V130EnabledModuleIterator{contract: _SafeL2V130.contract, event: "EnabledModule", logs: logs, sub: sub}, nil +} + +// WatchEnabledModule is a free log subscription operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_SafeL2V130 *SafeL2V130Filterer) WatchEnabledModule(opts *bind.WatchOpts, sink chan<- *SafeL2V130EnabledModule) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "EnabledModule") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130EnabledModule) + if err := _SafeL2V130.contract.UnpackLog(event, "EnabledModule", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseEnabledModule is a log parse operation binding the contract event 0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440. +// +// Solidity: event EnabledModule(address module) +func (_SafeL2V130 *SafeL2V130Filterer) ParseEnabledModule(log types.Log) (*SafeL2V130EnabledModule, error) { + event := new(SafeL2V130EnabledModule) + if err := _SafeL2V130.contract.UnpackLog(event, "EnabledModule", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130ExecutionFailureIterator is returned from FilterExecutionFailure and is used to iterate over the raw logs and unpacked data for ExecutionFailure events raised by the SafeL2V130 contract. +type SafeL2V130ExecutionFailureIterator struct { + Event *SafeL2V130ExecutionFailure // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130ExecutionFailureIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ExecutionFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ExecutionFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130ExecutionFailureIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130ExecutionFailureIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130ExecutionFailure represents a ExecutionFailure event raised by the SafeL2V130 contract. +type SafeL2V130ExecutionFailure struct { + TxHash [32]byte + Payment *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFailure is a free log retrieval operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_SafeL2V130 *SafeL2V130Filterer) FilterExecutionFailure(opts *bind.FilterOpts) (*SafeL2V130ExecutionFailureIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "ExecutionFailure") + if err != nil { + return nil, err + } + return &SafeL2V130ExecutionFailureIterator{contract: _SafeL2V130.contract, event: "ExecutionFailure", logs: logs, sub: sub}, nil +} + +// WatchExecutionFailure is a free log subscription operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_SafeL2V130 *SafeL2V130Filterer) WatchExecutionFailure(opts *bind.WatchOpts, sink chan<- *SafeL2V130ExecutionFailure) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "ExecutionFailure") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130ExecutionFailure) + if err := _SafeL2V130.contract.UnpackLog(event, "ExecutionFailure", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFailure is a log parse operation binding the contract event 0x23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23. +// +// Solidity: event ExecutionFailure(bytes32 txHash, uint256 payment) +func (_SafeL2V130 *SafeL2V130Filterer) ParseExecutionFailure(log types.Log) (*SafeL2V130ExecutionFailure, error) { + event := new(SafeL2V130ExecutionFailure) + if err := _SafeL2V130.contract.UnpackLog(event, "ExecutionFailure", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130ExecutionFromModuleFailureIterator is returned from FilterExecutionFromModuleFailure and is used to iterate over the raw logs and unpacked data for ExecutionFromModuleFailure events raised by the SafeL2V130 contract. +type SafeL2V130ExecutionFromModuleFailureIterator struct { + Event *SafeL2V130ExecutionFromModuleFailure // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130ExecutionFromModuleFailureIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ExecutionFromModuleFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ExecutionFromModuleFailure) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130ExecutionFromModuleFailureIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130ExecutionFromModuleFailureIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130ExecutionFromModuleFailure represents a ExecutionFromModuleFailure event raised by the SafeL2V130 contract. +type SafeL2V130ExecutionFromModuleFailure struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFromModuleFailure is a free log retrieval operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_SafeL2V130 *SafeL2V130Filterer) FilterExecutionFromModuleFailure(opts *bind.FilterOpts, module []common.Address) (*SafeL2V130ExecutionFromModuleFailureIterator, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "ExecutionFromModuleFailure", moduleRule) + if err != nil { + return nil, err + } + return &SafeL2V130ExecutionFromModuleFailureIterator{contract: _SafeL2V130.contract, event: "ExecutionFromModuleFailure", logs: logs, sub: sub}, nil +} + +// WatchExecutionFromModuleFailure is a free log subscription operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_SafeL2V130 *SafeL2V130Filterer) WatchExecutionFromModuleFailure(opts *bind.WatchOpts, sink chan<- *SafeL2V130ExecutionFromModuleFailure, module []common.Address) (event.Subscription, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "ExecutionFromModuleFailure", moduleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130ExecutionFromModuleFailure) + if err := _SafeL2V130.contract.UnpackLog(event, "ExecutionFromModuleFailure", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFromModuleFailure is a log parse operation binding the contract event 0xacd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375. +// +// Solidity: event ExecutionFromModuleFailure(address indexed module) +func (_SafeL2V130 *SafeL2V130Filterer) ParseExecutionFromModuleFailure(log types.Log) (*SafeL2V130ExecutionFromModuleFailure, error) { + event := new(SafeL2V130ExecutionFromModuleFailure) + if err := _SafeL2V130.contract.UnpackLog(event, "ExecutionFromModuleFailure", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130ExecutionFromModuleSuccessIterator is returned from FilterExecutionFromModuleSuccess and is used to iterate over the raw logs and unpacked data for ExecutionFromModuleSuccess events raised by the SafeL2V130 contract. +type SafeL2V130ExecutionFromModuleSuccessIterator struct { + Event *SafeL2V130ExecutionFromModuleSuccess // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130ExecutionFromModuleSuccessIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ExecutionFromModuleSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ExecutionFromModuleSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130ExecutionFromModuleSuccessIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130ExecutionFromModuleSuccessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130ExecutionFromModuleSuccess represents a ExecutionFromModuleSuccess event raised by the SafeL2V130 contract. +type SafeL2V130ExecutionFromModuleSuccess struct { + Module common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionFromModuleSuccess is a free log retrieval operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_SafeL2V130 *SafeL2V130Filterer) FilterExecutionFromModuleSuccess(opts *bind.FilterOpts, module []common.Address) (*SafeL2V130ExecutionFromModuleSuccessIterator, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "ExecutionFromModuleSuccess", moduleRule) + if err != nil { + return nil, err + } + return &SafeL2V130ExecutionFromModuleSuccessIterator{contract: _SafeL2V130.contract, event: "ExecutionFromModuleSuccess", logs: logs, sub: sub}, nil +} + +// WatchExecutionFromModuleSuccess is a free log subscription operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_SafeL2V130 *SafeL2V130Filterer) WatchExecutionFromModuleSuccess(opts *bind.WatchOpts, sink chan<- *SafeL2V130ExecutionFromModuleSuccess, module []common.Address) (event.Subscription, error) { + + var moduleRule []interface{} + for _, moduleItem := range module { + moduleRule = append(moduleRule, moduleItem) + } + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "ExecutionFromModuleSuccess", moduleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130ExecutionFromModuleSuccess) + if err := _SafeL2V130.contract.UnpackLog(event, "ExecutionFromModuleSuccess", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionFromModuleSuccess is a log parse operation binding the contract event 0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8. +// +// Solidity: event ExecutionFromModuleSuccess(address indexed module) +func (_SafeL2V130 *SafeL2V130Filterer) ParseExecutionFromModuleSuccess(log types.Log) (*SafeL2V130ExecutionFromModuleSuccess, error) { + event := new(SafeL2V130ExecutionFromModuleSuccess) + if err := _SafeL2V130.contract.UnpackLog(event, "ExecutionFromModuleSuccess", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130ExecutionSuccessIterator is returned from FilterExecutionSuccess and is used to iterate over the raw logs and unpacked data for ExecutionSuccess events raised by the SafeL2V130 contract. +type SafeL2V130ExecutionSuccessIterator struct { + Event *SafeL2V130ExecutionSuccess // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130ExecutionSuccessIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ExecutionSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130ExecutionSuccess) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130ExecutionSuccessIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130ExecutionSuccessIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130ExecutionSuccess represents a ExecutionSuccess event raised by the SafeL2V130 contract. +type SafeL2V130ExecutionSuccess struct { + TxHash [32]byte + Payment *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExecutionSuccess is a free log retrieval operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_SafeL2V130 *SafeL2V130Filterer) FilterExecutionSuccess(opts *bind.FilterOpts) (*SafeL2V130ExecutionSuccessIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "ExecutionSuccess") + if err != nil { + return nil, err + } + return &SafeL2V130ExecutionSuccessIterator{contract: _SafeL2V130.contract, event: "ExecutionSuccess", logs: logs, sub: sub}, nil +} + +// WatchExecutionSuccess is a free log subscription operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_SafeL2V130 *SafeL2V130Filterer) WatchExecutionSuccess(opts *bind.WatchOpts, sink chan<- *SafeL2V130ExecutionSuccess) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "ExecutionSuccess") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130ExecutionSuccess) + if err := _SafeL2V130.contract.UnpackLog(event, "ExecutionSuccess", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExecutionSuccess is a log parse operation binding the contract event 0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e. +// +// Solidity: event ExecutionSuccess(bytes32 txHash, uint256 payment) +func (_SafeL2V130 *SafeL2V130Filterer) ParseExecutionSuccess(log types.Log) (*SafeL2V130ExecutionSuccess, error) { + event := new(SafeL2V130ExecutionSuccess) + if err := _SafeL2V130.contract.UnpackLog(event, "ExecutionSuccess", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130RemovedOwnerIterator is returned from FilterRemovedOwner and is used to iterate over the raw logs and unpacked data for RemovedOwner events raised by the SafeL2V130 contract. +type SafeL2V130RemovedOwnerIterator struct { + Event *SafeL2V130RemovedOwner // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130RemovedOwnerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130RemovedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130RemovedOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130RemovedOwnerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130RemovedOwnerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130RemovedOwner represents a RemovedOwner event raised by the SafeL2V130 contract. +type SafeL2V130RemovedOwner struct { + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemovedOwner is a free log retrieval operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_SafeL2V130 *SafeL2V130Filterer) FilterRemovedOwner(opts *bind.FilterOpts) (*SafeL2V130RemovedOwnerIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "RemovedOwner") + if err != nil { + return nil, err + } + return &SafeL2V130RemovedOwnerIterator{contract: _SafeL2V130.contract, event: "RemovedOwner", logs: logs, sub: sub}, nil +} + +// WatchRemovedOwner is a free log subscription operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_SafeL2V130 *SafeL2V130Filterer) WatchRemovedOwner(opts *bind.WatchOpts, sink chan<- *SafeL2V130RemovedOwner) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "RemovedOwner") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130RemovedOwner) + if err := _SafeL2V130.contract.UnpackLog(event, "RemovedOwner", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRemovedOwner is a log parse operation binding the contract event 0xf8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf. +// +// Solidity: event RemovedOwner(address owner) +func (_SafeL2V130 *SafeL2V130Filterer) ParseRemovedOwner(log types.Log) (*SafeL2V130RemovedOwner, error) { + event := new(SafeL2V130RemovedOwner) + if err := _SafeL2V130.contract.UnpackLog(event, "RemovedOwner", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130SafeModuleTransactionIterator is returned from FilterSafeModuleTransaction and is used to iterate over the raw logs and unpacked data for SafeModuleTransaction events raised by the SafeL2V130 contract. +type SafeL2V130SafeModuleTransactionIterator struct { + Event *SafeL2V130SafeModuleTransaction // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130SafeModuleTransactionIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130SafeModuleTransaction) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130SafeModuleTransaction) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130SafeModuleTransactionIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130SafeModuleTransactionIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130SafeModuleTransaction represents a SafeModuleTransaction event raised by the SafeL2V130 contract. +type SafeL2V130SafeModuleTransaction struct { + Module common.Address + To common.Address + Value *big.Int + Data []byte + Operation uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSafeModuleTransaction is a free log retrieval operation binding the contract event 0xb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e. +// +// Solidity: event SafeModuleTransaction(address module, address to, uint256 value, bytes data, uint8 operation) +func (_SafeL2V130 *SafeL2V130Filterer) FilterSafeModuleTransaction(opts *bind.FilterOpts) (*SafeL2V130SafeModuleTransactionIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "SafeModuleTransaction") + if err != nil { + return nil, err + } + return &SafeL2V130SafeModuleTransactionIterator{contract: _SafeL2V130.contract, event: "SafeModuleTransaction", logs: logs, sub: sub}, nil +} + +// WatchSafeModuleTransaction is a free log subscription operation binding the contract event 0xb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e. +// +// Solidity: event SafeModuleTransaction(address module, address to, uint256 value, bytes data, uint8 operation) +func (_SafeL2V130 *SafeL2V130Filterer) WatchSafeModuleTransaction(opts *bind.WatchOpts, sink chan<- *SafeL2V130SafeModuleTransaction) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "SafeModuleTransaction") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130SafeModuleTransaction) + if err := _SafeL2V130.contract.UnpackLog(event, "SafeModuleTransaction", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSafeModuleTransaction is a log parse operation binding the contract event 0xb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e. +// +// Solidity: event SafeModuleTransaction(address module, address to, uint256 value, bytes data, uint8 operation) +func (_SafeL2V130 *SafeL2V130Filterer) ParseSafeModuleTransaction(log types.Log) (*SafeL2V130SafeModuleTransaction, error) { + event := new(SafeL2V130SafeModuleTransaction) + if err := _SafeL2V130.contract.UnpackLog(event, "SafeModuleTransaction", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130SafeMultiSigTransactionIterator is returned from FilterSafeMultiSigTransaction and is used to iterate over the raw logs and unpacked data for SafeMultiSigTransaction events raised by the SafeL2V130 contract. +type SafeL2V130SafeMultiSigTransactionIterator struct { + Event *SafeL2V130SafeMultiSigTransaction // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130SafeMultiSigTransactionIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130SafeMultiSigTransaction) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130SafeMultiSigTransaction) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130SafeMultiSigTransactionIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130SafeMultiSigTransactionIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130SafeMultiSigTransaction represents a SafeMultiSigTransaction event raised by the SafeL2V130 contract. +type SafeL2V130SafeMultiSigTransaction struct { + To common.Address + Value *big.Int + Data []byte + Operation uint8 + SafeTxGas *big.Int + BaseGas *big.Int + GasPrice *big.Int + GasToken common.Address + RefundReceiver common.Address + Signatures []byte + AdditionalInfo []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSafeMultiSigTransaction is a free log retrieval operation binding the contract event 0x66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed. +// +// Solidity: event SafeMultiSigTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures, bytes additionalInfo) +func (_SafeL2V130 *SafeL2V130Filterer) FilterSafeMultiSigTransaction(opts *bind.FilterOpts) (*SafeL2V130SafeMultiSigTransactionIterator, error) { + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "SafeMultiSigTransaction") + if err != nil { + return nil, err + } + return &SafeL2V130SafeMultiSigTransactionIterator{contract: _SafeL2V130.contract, event: "SafeMultiSigTransaction", logs: logs, sub: sub}, nil +} + +// WatchSafeMultiSigTransaction is a free log subscription operation binding the contract event 0x66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed. +// +// Solidity: event SafeMultiSigTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures, bytes additionalInfo) +func (_SafeL2V130 *SafeL2V130Filterer) WatchSafeMultiSigTransaction(opts *bind.WatchOpts, sink chan<- *SafeL2V130SafeMultiSigTransaction) (event.Subscription, error) { + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "SafeMultiSigTransaction") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130SafeMultiSigTransaction) + if err := _SafeL2V130.contract.UnpackLog(event, "SafeMultiSigTransaction", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSafeMultiSigTransaction is a log parse operation binding the contract event 0x66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed. +// +// Solidity: event SafeMultiSigTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures, bytes additionalInfo) +func (_SafeL2V130 *SafeL2V130Filterer) ParseSafeMultiSigTransaction(log types.Log) (*SafeL2V130SafeMultiSigTransaction, error) { + event := new(SafeL2V130SafeMultiSigTransaction) + if err := _SafeL2V130.contract.UnpackLog(event, "SafeMultiSigTransaction", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130SafeReceivedIterator is returned from FilterSafeReceived and is used to iterate over the raw logs and unpacked data for SafeReceived events raised by the SafeL2V130 contract. +type SafeL2V130SafeReceivedIterator struct { + Event *SafeL2V130SafeReceived // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130SafeReceivedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130SafeReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130SafeReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130SafeReceivedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130SafeReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130SafeReceived represents a SafeReceived event raised by the SafeL2V130 contract. +type SafeL2V130SafeReceived struct { + Sender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSafeReceived is a free log retrieval operation binding the contract event 0x3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d. +// +// Solidity: event SafeReceived(address indexed sender, uint256 value) +func (_SafeL2V130 *SafeL2V130Filterer) FilterSafeReceived(opts *bind.FilterOpts, sender []common.Address) (*SafeL2V130SafeReceivedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "SafeReceived", senderRule) + if err != nil { + return nil, err + } + return &SafeL2V130SafeReceivedIterator{contract: _SafeL2V130.contract, event: "SafeReceived", logs: logs, sub: sub}, nil +} + +// WatchSafeReceived is a free log subscription operation binding the contract event 0x3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d. +// +// Solidity: event SafeReceived(address indexed sender, uint256 value) +func (_SafeL2V130 *SafeL2V130Filterer) WatchSafeReceived(opts *bind.WatchOpts, sink chan<- *SafeL2V130SafeReceived, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "SafeReceived", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130SafeReceived) + if err := _SafeL2V130.contract.UnpackLog(event, "SafeReceived", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSafeReceived is a log parse operation binding the contract event 0x3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d. +// +// Solidity: event SafeReceived(address indexed sender, uint256 value) +func (_SafeL2V130 *SafeL2V130Filterer) ParseSafeReceived(log types.Log) (*SafeL2V130SafeReceived, error) { + event := new(SafeL2V130SafeReceived) + if err := _SafeL2V130.contract.UnpackLog(event, "SafeReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130SafeSetupIterator is returned from FilterSafeSetup and is used to iterate over the raw logs and unpacked data for SafeSetup events raised by the SafeL2V130 contract. +type SafeL2V130SafeSetupIterator struct { + Event *SafeL2V130SafeSetup // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130SafeSetupIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130SafeSetup) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130SafeSetup) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130SafeSetupIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130SafeSetupIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130SafeSetup represents a SafeSetup event raised by the SafeL2V130 contract. +type SafeL2V130SafeSetup struct { + Initiator common.Address + Owners []common.Address + Threshold *big.Int + Initializer common.Address + FallbackHandler common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSafeSetup is a free log retrieval operation binding the contract event 0x141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a8. +// +// Solidity: event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler) +func (_SafeL2V130 *SafeL2V130Filterer) FilterSafeSetup(opts *bind.FilterOpts, initiator []common.Address) (*SafeL2V130SafeSetupIterator, error) { + + var initiatorRule []interface{} + for _, initiatorItem := range initiator { + initiatorRule = append(initiatorRule, initiatorItem) + } + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "SafeSetup", initiatorRule) + if err != nil { + return nil, err + } + return &SafeL2V130SafeSetupIterator{contract: _SafeL2V130.contract, event: "SafeSetup", logs: logs, sub: sub}, nil +} + +// WatchSafeSetup is a free log subscription operation binding the contract event 0x141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a8. +// +// Solidity: event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler) +func (_SafeL2V130 *SafeL2V130Filterer) WatchSafeSetup(opts *bind.WatchOpts, sink chan<- *SafeL2V130SafeSetup, initiator []common.Address) (event.Subscription, error) { + + var initiatorRule []interface{} + for _, initiatorItem := range initiator { + initiatorRule = append(initiatorRule, initiatorItem) + } + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "SafeSetup", initiatorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130SafeSetup) + if err := _SafeL2V130.contract.UnpackLog(event, "SafeSetup", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSafeSetup is a log parse operation binding the contract event 0x141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a8. +// +// Solidity: event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler) +func (_SafeL2V130 *SafeL2V130Filterer) ParseSafeSetup(log types.Log) (*SafeL2V130SafeSetup, error) { + event := new(SafeL2V130SafeSetup) + if err := _SafeL2V130.contract.UnpackLog(event, "SafeSetup", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SafeL2V130SignMsgIterator is returned from FilterSignMsg and is used to iterate over the raw logs and unpacked data for SignMsg events raised by the SafeL2V130 contract. +type SafeL2V130SignMsgIterator struct { + Event *SafeL2V130SignMsg // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SafeL2V130SignMsgIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SafeL2V130SignMsg) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SafeL2V130SignMsg) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SafeL2V130SignMsgIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SafeL2V130SignMsgIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SafeL2V130SignMsg represents a SignMsg event raised by the SafeL2V130 contract. +type SafeL2V130SignMsg struct { + MsgHash [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSignMsg is a free log retrieval operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_SafeL2V130 *SafeL2V130Filterer) FilterSignMsg(opts *bind.FilterOpts, msgHash [][32]byte) (*SafeL2V130SignMsgIterator, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _SafeL2V130.contract.FilterLogs(opts, "SignMsg", msgHashRule) + if err != nil { + return nil, err + } + return &SafeL2V130SignMsgIterator{contract: _SafeL2V130.contract, event: "SignMsg", logs: logs, sub: sub}, nil +} + +// WatchSignMsg is a free log subscription operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_SafeL2V130 *SafeL2V130Filterer) WatchSignMsg(opts *bind.WatchOpts, sink chan<- *SafeL2V130SignMsg, msgHash [][32]byte) (event.Subscription, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _SafeL2V130.contract.WatchLogs(opts, "SignMsg", msgHashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SafeL2V130SignMsg) + if err := _SafeL2V130.contract.UnpackLog(event, "SignMsg", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSignMsg is a log parse operation binding the contract event 0xe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4. +// +// Solidity: event SignMsg(bytes32 indexed msgHash) +func (_SafeL2V130 *SafeL2V130Filterer) ParseSignMsg(log types.Log) (*SafeL2V130SignMsg, error) { + event := new(SafeL2V130SignMsg) + if err := _SafeL2V130.contract.UnpackLog(event, "SignMsg", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-bindings/bindings/safel2_v130_more.go b/op-bindings/bindings/safel2_v130_more.go new file mode 100644 index 000000000000..06887e0a8306 --- /dev/null +++ b/op-bindings/bindings/safel2_v130_more.go @@ -0,0 +1,9 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var SafeL2_v130DeployedBin = "0x6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506126fc565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b810190808035906020019092919080359060200190929190505050612732565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b81019080803590602001909291905050506127b9565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506127d1565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612b63565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612c9d565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612edc565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612f01565b005b348015610d3457600080fd5b50610d3d612f90565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613139565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061313f565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613161565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff16906020019092919050505061331f565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613447565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613639565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506137d8565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613805565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b96565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613c1a565b005b34801561148957600080fd5b5061149261428c565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614296565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061443e565b005b3480156116a457600080fd5b506116ad61449f565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061451d565b005b34801561174a57600080fd5b50611753614950565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614989565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612b63565b5b5050565b611bd2604182614a2c90919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614a66565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614a2c90919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614a9590919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614a9590919063ffffffff16565b614a9590919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b60007fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183600181111561266b57fe5b8152602001828103825284818151815260200191508051906020019080838360005b838110156126a857808201518184015260208101905061268d565b50505050905090810190601f1680156126d55780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a16126f285858585614ab4565b9050949350505050565b6000606061270c868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561275057600080fd5b506040519080825280601f01601f1916602001820160405280156127835781602001600182028036833780820191505090505b50905060005b838110156127ae57808501548060208302602085010152508080600101915050612789565b508091505092915050565b60076020528060005260406000206000915090505481565b6127d9614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156128435750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b6128b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146129b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612b6b614989565b600354811115612be3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612c5a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000606060055433600454604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612d5057fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184810384528e8e82818152602001925080828437600081840152601f19601f820116905080830192505050848103835286818151815260200191508051906020019080838360005b83811015612e0a578082015181840152602081019050612def565b50505050905090810190601f168015612e375780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b83811015612e70578082015181840152602081019050612e55565b50505050905090810190601f168015612e9d5780820380516001836020036101000a031916815260200191505b509f5050505050505050505050505050505060405180910390a1612eca8d8d8d8d8d8d8d8d8d8d8d614c9a565b9150509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111612f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612f8a84848484611bbe565b50505050565b6060600060035467ffffffffffffffff81118015612fad57600080fd5b50604051908082528060200260200182016040528015612fdc5781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613130578083838151811061308757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050613046565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6131ac8a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050896151d7565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146131ea576131e9846156d7565b5b6132388787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615706565b60008211156132525761325082600060018685615941565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a9050613376878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615b47565b61337f57600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561340c5780820151818401526020810190506133f1565b50505050905090810190601f1680156134395780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561346257600080fd5b506040519080825280602002602001820160405280156134915781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156135645750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561356f57508482105b1561362a578084838151811061358157fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506134fa565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561373b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b60006137ed8c8c8c8c8c8c8c8c8c8c8c614296565b8051906020012090509b9a5050505050505050505050565b61380d614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156138775750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b6138e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146139e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613b9e614989565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613c22614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c8c5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613cc457503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613d36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613e37576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613ea15750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b613f13576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614013576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561432757fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6143b361449f565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b614446614989565b61444f816156d7565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6144cd6125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b614525614989565b8060016003540310156145a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561460a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b61467c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461477c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1806004541461494b5761494a81612b63565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614a2a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614a3f5760009050614a60565b6000828402905082848281614a5057fe5b0414614a5b57600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614aaa57600080fd5b8091505092915050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015614b7f5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b614bf1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b614bfe858585855a615b47565b90508015614c4e573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a2614c92565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000806000614cb48e8e8e8e8e8e8e8e8e8e600554614296565b905060056000815480929190600101919050555080805190602001209150614cdd828286612f01565b506000614ce8615b93565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614614ece578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115614d8b57fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015614e5d578082015181840152602081019050614e42565b50505050905090810190601f168015614e8a5780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015614eb557600080fd5b505af1158015614ec9573d6000803e3d6000fd5b505050505b6101f4614ef56109c48b01603f60408d0281614ee657fe5b04615bc490919063ffffffff16565b015a1015614f6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a9050614fd48f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d14614fc9578e614fcf565b6109c45a035b615b47565b9350614fe95a82615bde90919063ffffffff16565b90508380614ff8575060008a14155b80615004575060008814155b615076576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808911156150905761508d828b8b8b8b615941565b90505b84156150da577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a161511a565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146151c6578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b1580156151ad57600080fd5b505af11580156151c1573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b60006004541461524f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b81518111156152c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600181101561533d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b835181101561564357600084828151811061535d57fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153d15750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561540957503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561544157508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b6154b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146155b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550809250508080600101915050615346565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615808576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461593d576158ca8260008360015a615b47565b61593c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461597e5782615980565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615a98576159ea3a86106159c7573a6159c9565b855b6159dc888a614a9590919063ffffffff16565b614a2c90919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615a93576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615b3d565b615abd85615aaf888a614a9590919063ffffffff16565b614a2c90919063ffffffff16565b9150615aca848284615bfe565b615b3c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600180811115615b5557fe5b836001811115615b6157fe5b1415615b7a576000808551602087018986f49050615b8a565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015615bd45781615bd6565b825b905092915050565b600082821115615bed57600080fd5b600082840390508091505092915050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d60008114615ca55760208114615cad5760009350615cb8565b819350615cb8565b600051158215171593505b505050939250505056fea2646970667358221220047fac33099ca576d1c4f1ac6a8abdb0396e42ad6a397d2cb2f4dc1624cc0c5b64736f6c63430007060033" +func init() { + deployedBytecodes["SafeL2_v130"] = SafeL2_v130DeployedBin +} diff --git a/op-bindings/bindings/safeproxyfactory.go b/op-bindings/bindings/safeproxyfactory.go index 98f132db27a2..e9ce776ade14 100644 --- a/op-bindings/bindings/safeproxyfactory.go +++ b/op-bindings/bindings/safeproxyfactory.go @@ -30,7 +30,7 @@ var ( // SafeProxyFactoryMetaData contains all meta data concerning the SafeProxyFactory contract. var SafeProxyFactoryMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractSafeProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"singleton\",\"type\":\"address\"}],\"name\":\"ProxyCreation\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_singleton\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"initializer\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"saltNonce\",\"type\":\"uint256\"}],\"name\":\"createChainSpecificProxyWithNonce\",\"outputs\":[{\"internalType\":\"contractSafeProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_singleton\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"initializer\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"saltNonce\",\"type\":\"uint256\"},{\"internalType\":\"contractIProxyCreationCallback\",\"name\":\"callback\",\"type\":\"address\"}],\"name\":\"createProxyWithCallback\",\"outputs\":[{\"internalType\":\"contractSafeProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_singleton\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"initializer\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"saltNonce\",\"type\":\"uint256\"}],\"name\":\"createProxyWithNonce\",\"outputs\":[{\"internalType\":\"contractSafeProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxyCreationCode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + ABI: "[{\"type\":\"function\",\"name\":\"createChainSpecificProxyWithNonce\",\"inputs\":[{\"name\":\"_singleton\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"initializer\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"saltNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"proxy\",\"type\":\"address\",\"internalType\":\"contractSafeProxy\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createProxyWithCallback\",\"inputs\":[{\"name\":\"_singleton\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"initializer\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"saltNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"callback\",\"type\":\"address\",\"internalType\":\"contractIProxyCreationCallback\"}],\"outputs\":[{\"name\":\"proxy\",\"type\":\"address\",\"internalType\":\"contractSafeProxy\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"createProxyWithNonce\",\"inputs\":[{\"name\":\"_singleton\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"initializer\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"saltNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"proxy\",\"type\":\"address\",\"internalType\":\"contractSafeProxy\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getChainId\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxyCreationCode\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"pure\"},{\"type\":\"event\",\"name\":\"ProxyCreation\",\"inputs\":[{\"name\":\"proxy\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"contractSafeProxy\"},{\"name\":\"singleton\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false}]", Bin: "0x608060405234801561001057600080fd5b50610913806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806353e5d9351161005057806353e5d935146100b7578063d18af54d146100cc578063ec9e80bb146100df57600080fd5b80631688f0b91461006c5780633408e470146100a9575b600080fd5b61007f61007a3660046105d2565b6100f2565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6040514681526020016100a0565b6100bf610194565b6040516100a091906106a5565b61007f6100da3660046106bf565b6101dc565b61007f6100ed3660046105d2565b6102f8565b600080838051906020012083604051602001610118929190918252602082015260400190565b60405160208183030381529060405280519060200120905061013b85858361032a565b60405173ffffffffffffffffffffffffffffffffffffffff8781168252919350908316907f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2359060200160405180910390a2509392505050565b6060604051806020016101a6906104c6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b600080838360405160200161022092919091825260601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602082015260340190565b6040516020818303038152906040528051906020012060001c90506102468686836100f2565b915073ffffffffffffffffffffffffffffffffffffffff8316156102ef576040517f1e52b51800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690631e52b518906102bc9085908a908a908a9060040161072b565b600060405180830381600087803b1580156102d657600080fd5b505af11580156102ea573d6000803e3d6000fd5b505050505b50949350505050565b60008083805190602001208361030b4690565b6040805160208101949094528301919091526060820152608001610118565b6000833b610399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53696e676c65746f6e20636f6e7472616374206e6f74206465706c6f7965640060448201526064015b60405180910390fd5b6000604051806020016103ab906104c6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052610403919073ffffffffffffffffffffffffffffffffffffffff881690602001610775565b6040516020818303038152906040529050828151826020016000f5915073ffffffffffffffffffffffffffffffffffffffff821661049d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f437265617465322063616c6c206661696c6564000000000000000000000000006044820152606401610390565b8351156104be5760008060008651602088016000875af1036104be57600080fd5b509392505050565b61016f8061079883390190565b73ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261053857600080fd5b813567ffffffffffffffff80821115610553576105536104f8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610599576105996104f8565b816040528381528660208588010111156105b257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156105e757600080fd5b83356105f2816104d3565b9250602084013567ffffffffffffffff81111561060e57600080fd5b61061a86828701610527565b925050604084013590509250925092565b60005b8381101561064657818101518382015260200161062e565b83811115610655576000848401525b50505050565b6000815180845261067381602086016020860161062b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106b8602083018461065b565b9392505050565b600080600080608085870312156106d557600080fd5b84356106e0816104d3565b9350602085013567ffffffffffffffff8111156106fc57600080fd5b61070887828801610527565b935050604085013591506060850135610720816104d3565b939692955090935050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152610764608083018561065b565b905082606083015295945050505050565b6000835161078781846020880161062b565b919091019182525060200191905056fe608060405234801561001057600080fd5b5060405161016f38038061016f83398101604081905261002f916100b9565b6001600160a01b0381166100945760405162461bcd60e51b815260206004820152602260248201527f496e76616c69642073696e676c65746f6e20616464726573732070726f766964604482015261195960f21b606482015260840160405180910390fd5b600080546001600160a01b0319166001600160a01b03929092169190911790556100e9565b6000602082840312156100cb57600080fd5b81516001600160a01b03811681146100e257600080fd5b9392505050565b6078806100f76000396000f3fe6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000aa164736f6c634300080f000a", } diff --git a/op-bindings/bindings/safeproxyfactory_more.go b/op-bindings/bindings/safeproxyfactory_more.go index dbc455aa9f72..1c70e0b1d81f 100644 --- a/op-bindings/bindings/safeproxyfactory_more.go +++ b/op-bindings/bindings/safeproxyfactory_more.go @@ -15,6 +15,7 @@ var SafeProxyFactoryStorageLayout = new(solc.StorageLayout) var SafeProxyFactoryDeployedBin = "0x608060405234801561001057600080fd5b50600436106100675760003560e01c806353e5d9351161005057806353e5d935146100b7578063d18af54d146100cc578063ec9e80bb146100df57600080fd5b80631688f0b91461006c5780633408e470146100a9575b600080fd5b61007f61007a3660046105d2565b6100f2565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6040514681526020016100a0565b6100bf610194565b6040516100a091906106a5565b61007f6100da3660046106bf565b6101dc565b61007f6100ed3660046105d2565b6102f8565b600080838051906020012083604051602001610118929190918252602082015260400190565b60405160208183030381529060405280519060200120905061013b85858361032a565b60405173ffffffffffffffffffffffffffffffffffffffff8781168252919350908316907f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2359060200160405180910390a2509392505050565b6060604051806020016101a6906104c6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b600080838360405160200161022092919091825260601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602082015260340190565b6040516020818303038152906040528051906020012060001c90506102468686836100f2565b915073ffffffffffffffffffffffffffffffffffffffff8316156102ef576040517f1e52b51800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690631e52b518906102bc9085908a908a908a9060040161072b565b600060405180830381600087803b1580156102d657600080fd5b505af11580156102ea573d6000803e3d6000fd5b505050505b50949350505050565b60008083805190602001208361030b4690565b6040805160208101949094528301919091526060820152608001610118565b6000833b610399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53696e676c65746f6e20636f6e7472616374206e6f74206465706c6f7965640060448201526064015b60405180910390fd5b6000604051806020016103ab906104c6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052610403919073ffffffffffffffffffffffffffffffffffffffff881690602001610775565b6040516020818303038152906040529050828151826020016000f5915073ffffffffffffffffffffffffffffffffffffffff821661049d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f437265617465322063616c6c206661696c6564000000000000000000000000006044820152606401610390565b8351156104be5760008060008651602088016000875af1036104be57600080fd5b509392505050565b61016f8061079883390190565b73ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261053857600080fd5b813567ffffffffffffffff80821115610553576105536104f8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610599576105996104f8565b816040528381528660208588010111156105b257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156105e757600080fd5b83356105f2816104d3565b9250602084013567ffffffffffffffff81111561060e57600080fd5b61061a86828701610527565b925050604084013590509250925092565b60005b8381101561064657818101518382015260200161062e565b83811115610655576000848401525b50505050565b6000815180845261067381602086016020860161062b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106b8602083018461065b565b9392505050565b600080600080608085870312156106d557600080fd5b84356106e0816104d3565b9350602085013567ffffffffffffffff8111156106fc57600080fd5b61070887828801610527565b935050604085013591506060850135610720816104d3565b939692955090935050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152610764608083018561065b565b905082606083015295945050505050565b6000835161078781846020880161062b565b919091019182525060200191905056fe608060405234801561001057600080fd5b5060405161016f38038061016f83398101604081905261002f916100b9565b6001600160a01b0381166100945760405162461bcd60e51b815260206004820152602260248201527f496e76616c69642073696e676c65746f6e20616464726573732070726f766964604482015261195960f21b606482015260840160405180910390fd5b600080546001600160a01b0319166001600160a01b03929092169190911790556100e9565b6000602082840312156100cb57600080fd5b81516001600160a01b03811681146100e257600080fd5b9392505050565b6078806100f76000396000f3fe6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000aa164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(SafeProxyFactoryStorageLayoutJSON), SafeProxyFactoryStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["SafeProxyFactory"] = SafeProxyFactoryStorageLayout deployedBytecodes["SafeProxyFactory"] = SafeProxyFactoryDeployedBin + immutableReferences["SafeProxyFactory"] = false } diff --git a/op-bindings/bindings/safesingletonfactory.go b/op-bindings/bindings/safesingletonfactory.go new file mode 100644 index 000000000000..d0f16ee4ab06 --- /dev/null +++ b/op-bindings/bindings/safesingletonfactory.go @@ -0,0 +1,223 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// SafeSingletonFactoryMetaData contains all meta data concerning the SafeSingletonFactory contract. +var SafeSingletonFactoryMetaData = &bind.MetaData{ + ABI: "[{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\",\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"creationCode\",\"type\":\"bytes\"}]}]", + Bin: "0x604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3", +} + +// SafeSingletonFactoryABI is the input ABI used to generate the binding from. +// Deprecated: Use SafeSingletonFactoryMetaData.ABI instead. +var SafeSingletonFactoryABI = SafeSingletonFactoryMetaData.ABI + +// SafeSingletonFactoryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SafeSingletonFactoryMetaData.Bin instead. +var SafeSingletonFactoryBin = SafeSingletonFactoryMetaData.Bin + +// DeploySafeSingletonFactory deploys a new Ethereum contract, binding an instance of SafeSingletonFactory to it. +func DeploySafeSingletonFactory(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SafeSingletonFactory, error) { + parsed, err := SafeSingletonFactoryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SafeSingletonFactoryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &SafeSingletonFactory{SafeSingletonFactoryCaller: SafeSingletonFactoryCaller{contract: contract}, SafeSingletonFactoryTransactor: SafeSingletonFactoryTransactor{contract: contract}, SafeSingletonFactoryFilterer: SafeSingletonFactoryFilterer{contract: contract}}, nil +} + +// SafeSingletonFactory is an auto generated Go binding around an Ethereum contract. +type SafeSingletonFactory struct { + SafeSingletonFactoryCaller // Read-only binding to the contract + SafeSingletonFactoryTransactor // Write-only binding to the contract + SafeSingletonFactoryFilterer // Log filterer for contract events +} + +// SafeSingletonFactoryCaller is an auto generated read-only Go binding around an Ethereum contract. +type SafeSingletonFactoryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeSingletonFactoryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SafeSingletonFactoryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeSingletonFactoryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SafeSingletonFactoryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SafeSingletonFactorySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type SafeSingletonFactorySession struct { + Contract *SafeSingletonFactory // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SafeSingletonFactoryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type SafeSingletonFactoryCallerSession struct { + Contract *SafeSingletonFactoryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// SafeSingletonFactoryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type SafeSingletonFactoryTransactorSession struct { + Contract *SafeSingletonFactoryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SafeSingletonFactoryRaw is an auto generated low-level Go binding around an Ethereum contract. +type SafeSingletonFactoryRaw struct { + Contract *SafeSingletonFactory // Generic contract binding to access the raw methods on +} + +// SafeSingletonFactoryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SafeSingletonFactoryCallerRaw struct { + Contract *SafeSingletonFactoryCaller // Generic read-only contract binding to access the raw methods on +} + +// SafeSingletonFactoryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SafeSingletonFactoryTransactorRaw struct { + Contract *SafeSingletonFactoryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewSafeSingletonFactory creates a new instance of SafeSingletonFactory, bound to a specific deployed contract. +func NewSafeSingletonFactory(address common.Address, backend bind.ContractBackend) (*SafeSingletonFactory, error) { + contract, err := bindSafeSingletonFactory(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &SafeSingletonFactory{SafeSingletonFactoryCaller: SafeSingletonFactoryCaller{contract: contract}, SafeSingletonFactoryTransactor: SafeSingletonFactoryTransactor{contract: contract}, SafeSingletonFactoryFilterer: SafeSingletonFactoryFilterer{contract: contract}}, nil +} + +// NewSafeSingletonFactoryCaller creates a new read-only instance of SafeSingletonFactory, bound to a specific deployed contract. +func NewSafeSingletonFactoryCaller(address common.Address, caller bind.ContractCaller) (*SafeSingletonFactoryCaller, error) { + contract, err := bindSafeSingletonFactory(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &SafeSingletonFactoryCaller{contract: contract}, nil +} + +// NewSafeSingletonFactoryTransactor creates a new write-only instance of SafeSingletonFactory, bound to a specific deployed contract. +func NewSafeSingletonFactoryTransactor(address common.Address, transactor bind.ContractTransactor) (*SafeSingletonFactoryTransactor, error) { + contract, err := bindSafeSingletonFactory(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &SafeSingletonFactoryTransactor{contract: contract}, nil +} + +// NewSafeSingletonFactoryFilterer creates a new log filterer instance of SafeSingletonFactory, bound to a specific deployed contract. +func NewSafeSingletonFactoryFilterer(address common.Address, filterer bind.ContractFilterer) (*SafeSingletonFactoryFilterer, error) { + contract, err := bindSafeSingletonFactory(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &SafeSingletonFactoryFilterer{contract: contract}, nil +} + +// bindSafeSingletonFactory binds a generic wrapper to an already deployed contract. +func bindSafeSingletonFactory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SafeSingletonFactoryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SafeSingletonFactory *SafeSingletonFactoryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SafeSingletonFactory.Contract.SafeSingletonFactoryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SafeSingletonFactory *SafeSingletonFactoryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeSingletonFactory.Contract.SafeSingletonFactoryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SafeSingletonFactory *SafeSingletonFactoryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SafeSingletonFactory.Contract.SafeSingletonFactoryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SafeSingletonFactory *SafeSingletonFactoryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SafeSingletonFactory.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SafeSingletonFactory *SafeSingletonFactoryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SafeSingletonFactory.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SafeSingletonFactory *SafeSingletonFactoryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SafeSingletonFactory.Contract.contract.Transact(opts, method, params...) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_SafeSingletonFactory *SafeSingletonFactoryTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _SafeSingletonFactory.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_SafeSingletonFactory *SafeSingletonFactorySession) Fallback(calldata []byte) (*types.Transaction, error) { + return _SafeSingletonFactory.Contract.Fallback(&_SafeSingletonFactory.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_SafeSingletonFactory *SafeSingletonFactoryTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _SafeSingletonFactory.Contract.Fallback(&_SafeSingletonFactory.TransactOpts, calldata) +} diff --git a/op-bindings/bindings/safesingletonfactory_more.go b/op-bindings/bindings/safesingletonfactory_more.go new file mode 100644 index 000000000000..d71e463ec436 --- /dev/null +++ b/op-bindings/bindings/safesingletonfactory_more.go @@ -0,0 +1,9 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var SafeSingletonFactoryDeployedBin = "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" +func init() { + deployedBytecodes["SafeSingletonFactory"] = SafeSingletonFactoryDeployedBin +} diff --git a/op-bindings/bindings/schemaregistry.go b/op-bindings/bindings/schemaregistry.go index 984bcf2c5688..6fe4407948e2 100644 --- a/op-bindings/bindings/schemaregistry.go +++ b/op-bindings/bindings/schemaregistry.go @@ -38,7 +38,7 @@ type SchemaRecord struct { // SchemaRegistryMetaData contains all meta data concerning the SchemaRegistry contract. var SchemaRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"AlreadyExists\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"registerer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"contractISchemaResolver\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"schema\",\"type\":\"string\"}],\"indexed\":false,\"internalType\":\"structSchemaRecord\",\"name\":\"schema\",\"type\":\"tuple\"}],\"name\":\"Registered\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"name\":\"getSchema\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"contractISchemaResolver\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"schema\",\"type\":\"string\"}],\"internalType\":\"structSchemaRecord\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"schema\",\"type\":\"string\"},{\"internalType\":\"contractISchemaResolver\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"}],\"name\":\"register\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"type\":\"function\",\"name\":\"getSchema\",\"inputs\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structSchemaRecord\",\"components\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"resolver\",\"type\":\"address\",\"internalType\":\"contractISchemaResolver\"},{\"name\":\"revocable\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"schema\",\"type\":\"string\",\"internalType\":\"string\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"register\",\"inputs\":[{\"name\":\"schema\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"resolver\",\"type\":\"address\",\"internalType\":\"contractISchemaResolver\"},{\"name\":\"revocable\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Registered\",\"inputs\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"registerer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"schema\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structSchemaRecord\",\"components\":[{\"name\":\"uid\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"resolver\",\"type\":\"address\",\"internalType\":\"contractISchemaResolver\"},{\"name\":\"revocable\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"schema\",\"type\":\"string\",\"internalType\":\"string\"}]}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AlreadyExists\",\"inputs\":[]}]", Bin: "0x608060405234801561001057600080fd5b506107fe806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806360d7a27814610098578063a2ea7c6e146100b9575b600080fd5b6100826040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b60405161008f9190610473565b60405180910390f35b6100ab6100a636600461048d565b6100d9565b60405190815260200161008f565b6100cc6100c736600461053f565b61029d565b60405161008f9190610558565b60008060405180608001604052806000801b81526020018573ffffffffffffffffffffffffffffffffffffffff168152602001841515815260200187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250929350915061015b9050826103c5565b600081815260208190526040902054909150156101a4576040517f23369fa600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80825260008181526020818152604091829020845181559084015160018201805493860151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00000000000000000000000000000000000000000090941673ffffffffffffffffffffffffffffffffffffffff9092169190911792909217909155606083015183919060028201906102409082610682565b509050503373ffffffffffffffffffffffffffffffffffffffff16817fd0b86852e21f9e5fa4bc3b0cff9757ffe243d50c4b43968a42202153d651ea5e8460405161028b9190610558565b60405180910390a39695505050505050565b604080516080810182526000808252602082018190529181019190915260608082015260008281526020818152604091829020825160808101845281548152600182015473ffffffffffffffffffffffffffffffffffffffff8116938201939093527401000000000000000000000000000000000000000090920460ff1615159282019290925260028201805491929160608401919061033c906105e0565b80601f0160208091040260200160405190810160405280929190818152602001828054610368906105e0565b80156103b55780601f1061038a576101008083540402835291602001916103b5565b820191906000526020600020905b81548152906001019060200180831161039857829003601f168201915b5050505050815250509050919050565b60008160600151826020015183604001516040516020016103e89392919061079c565b604051602081830303815290604052805190602001209050919050565b60005b83811015610420578181015183820152602001610408565b50506000910152565b60008151808452610441816020860160208601610405565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104866020830184610429565b9392505050565b600080600080606085870312156104a357600080fd5b843567ffffffffffffffff808211156104bb57600080fd5b818701915087601f8301126104cf57600080fd5b8135818111156104de57600080fd5b8860208285010111156104f057600080fd5b6020928301965094505085013573ffffffffffffffffffffffffffffffffffffffff8116811461051f57600080fd5b91506040850135801515811461053457600080fd5b939692955090935050565b60006020828403121561055157600080fd5b5035919050565b602081528151602082015273ffffffffffffffffffffffffffffffffffffffff6020830151166040820152604082015115156060820152600060608301516080808401526105a960a0840182610429565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600181811c908216806105f457607f821691505b60208210810361062d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561067d57600081815260208120601f850160051c8101602086101561065a5750805b601f850160051c820191505b8181101561067957828155600101610666565b5050505b505050565b815167ffffffffffffffff81111561069c5761069c6105b1565b6106b0816106aa84546105e0565b84610633565b602080601f83116001811461070357600084156106cd5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610679565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561075057888601518255948401946001909101908401610731565b508582101561078c57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600084516107ae818460208901610405565b60609490941b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190930190815290151560f81b60148201526015019291505056fea164736f6c6343000813000a", } diff --git a/op-bindings/bindings/schemaregistry_more.go b/op-bindings/bindings/schemaregistry_more.go index f0347979543b..78e4bc9e50f6 100644 --- a/op-bindings/bindings/schemaregistry_more.go +++ b/op-bindings/bindings/schemaregistry_more.go @@ -15,6 +15,7 @@ var SchemaRegistryStorageLayout = new(solc.StorageLayout) var SchemaRegistryDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806360d7a27814610098578063a2ea7c6e146100b9575b600080fd5b6100826040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b60405161008f9190610473565b60405180910390f35b6100ab6100a636600461048d565b6100d9565b60405190815260200161008f565b6100cc6100c736600461053f565b61029d565b60405161008f9190610558565b60008060405180608001604052806000801b81526020018573ffffffffffffffffffffffffffffffffffffffff168152602001841515815260200187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250929350915061015b9050826103c5565b600081815260208190526040902054909150156101a4576040517f23369fa600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80825260008181526020818152604091829020845181559084015160018201805493860151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00000000000000000000000000000000000000000090941673ffffffffffffffffffffffffffffffffffffffff9092169190911792909217909155606083015183919060028201906102409082610682565b509050503373ffffffffffffffffffffffffffffffffffffffff16817fd0b86852e21f9e5fa4bc3b0cff9757ffe243d50c4b43968a42202153d651ea5e8460405161028b9190610558565b60405180910390a39695505050505050565b604080516080810182526000808252602082018190529181019190915260608082015260008281526020818152604091829020825160808101845281548152600182015473ffffffffffffffffffffffffffffffffffffffff8116938201939093527401000000000000000000000000000000000000000090920460ff1615159282019290925260028201805491929160608401919061033c906105e0565b80601f0160208091040260200160405190810160405280929190818152602001828054610368906105e0565b80156103b55780601f1061038a576101008083540402835291602001916103b5565b820191906000526020600020905b81548152906001019060200180831161039857829003601f168201915b5050505050815250509050919050565b60008160600151826020015183604001516040516020016103e89392919061079c565b604051602081830303815290604052805190602001209050919050565b60005b83811015610420578181015183820152602001610408565b50506000910152565b60008151808452610441816020860160208601610405565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104866020830184610429565b9392505050565b600080600080606085870312156104a357600080fd5b843567ffffffffffffffff808211156104bb57600080fd5b818701915087601f8301126104cf57600080fd5b8135818111156104de57600080fd5b8860208285010111156104f057600080fd5b6020928301965094505085013573ffffffffffffffffffffffffffffffffffffffff8116811461051f57600080fd5b91506040850135801515811461053457600080fd5b939692955090935050565b60006020828403121561055157600080fd5b5035919050565b602081528151602082015273ffffffffffffffffffffffffffffffffffffffff6020830151166040820152604082015115156060820152600060608301516080808401526105a960a0840182610429565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600181811c908216806105f457607f821691505b60208210810361062d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561067d57600081815260208120601f850160051c8101602086101561065a5750805b601f850160051c820191505b8181101561067957828155600101610666565b5050505b505050565b815167ffffffffffffffff81111561069c5761069c6105b1565b6106b0816106aa84546105e0565b84610633565b602080601f83116001811461070357600084156106cd5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610679565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561075057888601518255948401946001909101908401610731565b508582101561078c57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600084516107ae818460208901610405565b60609490941b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190930190815290151560f81b60148201526015019291505056fea164736f6c6343000813000a" + func init() { if err := json.Unmarshal([]byte(SchemaRegistryStorageLayoutJSON), SchemaRegistryStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["SchemaRegistry"] = SchemaRegistryStorageLayout deployedBytecodes["SchemaRegistry"] = SchemaRegistryDeployedBin + immutableReferences["SchemaRegistry"] = false } diff --git a/op-bindings/bindings/sendercreator.go b/op-bindings/bindings/sendercreator.go new file mode 100644 index 000000000000..2d2c332856ed --- /dev/null +++ b/op-bindings/bindings/sendercreator.go @@ -0,0 +1,223 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// SenderCreatorMetaData contains all meta data concerning the SenderCreator contract. +var SenderCreatorMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"createSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033", +} + +// SenderCreatorABI is the input ABI used to generate the binding from. +// Deprecated: Use SenderCreatorMetaData.ABI instead. +var SenderCreatorABI = SenderCreatorMetaData.ABI + +// SenderCreatorBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SenderCreatorMetaData.Bin instead. +var SenderCreatorBin = SenderCreatorMetaData.Bin + +// DeploySenderCreator deploys a new Ethereum contract, binding an instance of SenderCreator to it. +func DeploySenderCreator(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SenderCreator, error) { + parsed, err := SenderCreatorMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SenderCreatorBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &SenderCreator{SenderCreatorCaller: SenderCreatorCaller{contract: contract}, SenderCreatorTransactor: SenderCreatorTransactor{contract: contract}, SenderCreatorFilterer: SenderCreatorFilterer{contract: contract}}, nil +} + +// SenderCreator is an auto generated Go binding around an Ethereum contract. +type SenderCreator struct { + SenderCreatorCaller // Read-only binding to the contract + SenderCreatorTransactor // Write-only binding to the contract + SenderCreatorFilterer // Log filterer for contract events +} + +// SenderCreatorCaller is an auto generated read-only Go binding around an Ethereum contract. +type SenderCreatorCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SenderCreatorTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SenderCreatorTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SenderCreatorFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SenderCreatorFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SenderCreatorSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type SenderCreatorSession struct { + Contract *SenderCreator // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SenderCreatorCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type SenderCreatorCallerSession struct { + Contract *SenderCreatorCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// SenderCreatorTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type SenderCreatorTransactorSession struct { + Contract *SenderCreatorTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SenderCreatorRaw is an auto generated low-level Go binding around an Ethereum contract. +type SenderCreatorRaw struct { + Contract *SenderCreator // Generic contract binding to access the raw methods on +} + +// SenderCreatorCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SenderCreatorCallerRaw struct { + Contract *SenderCreatorCaller // Generic read-only contract binding to access the raw methods on +} + +// SenderCreatorTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SenderCreatorTransactorRaw struct { + Contract *SenderCreatorTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewSenderCreator creates a new instance of SenderCreator, bound to a specific deployed contract. +func NewSenderCreator(address common.Address, backend bind.ContractBackend) (*SenderCreator, error) { + contract, err := bindSenderCreator(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &SenderCreator{SenderCreatorCaller: SenderCreatorCaller{contract: contract}, SenderCreatorTransactor: SenderCreatorTransactor{contract: contract}, SenderCreatorFilterer: SenderCreatorFilterer{contract: contract}}, nil +} + +// NewSenderCreatorCaller creates a new read-only instance of SenderCreator, bound to a specific deployed contract. +func NewSenderCreatorCaller(address common.Address, caller bind.ContractCaller) (*SenderCreatorCaller, error) { + contract, err := bindSenderCreator(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &SenderCreatorCaller{contract: contract}, nil +} + +// NewSenderCreatorTransactor creates a new write-only instance of SenderCreator, bound to a specific deployed contract. +func NewSenderCreatorTransactor(address common.Address, transactor bind.ContractTransactor) (*SenderCreatorTransactor, error) { + contract, err := bindSenderCreator(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &SenderCreatorTransactor{contract: contract}, nil +} + +// NewSenderCreatorFilterer creates a new log filterer instance of SenderCreator, bound to a specific deployed contract. +func NewSenderCreatorFilterer(address common.Address, filterer bind.ContractFilterer) (*SenderCreatorFilterer, error) { + contract, err := bindSenderCreator(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &SenderCreatorFilterer{contract: contract}, nil +} + +// bindSenderCreator binds a generic wrapper to an already deployed contract. +func bindSenderCreator(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SenderCreatorABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SenderCreator *SenderCreatorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SenderCreator.Contract.SenderCreatorCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SenderCreator *SenderCreatorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SenderCreator.Contract.SenderCreatorTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SenderCreator *SenderCreatorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SenderCreator.Contract.SenderCreatorTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SenderCreator *SenderCreatorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SenderCreator.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SenderCreator *SenderCreatorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SenderCreator.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SenderCreator *SenderCreatorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SenderCreator.Contract.contract.Transact(opts, method, params...) +} + +// CreateSender is a paid mutator transaction binding the contract method 0x570e1a36. +// +// Solidity: function createSender(bytes initCode) returns(address sender) +func (_SenderCreator *SenderCreatorTransactor) CreateSender(opts *bind.TransactOpts, initCode []byte) (*types.Transaction, error) { + return _SenderCreator.contract.Transact(opts, "createSender", initCode) +} + +// CreateSender is a paid mutator transaction binding the contract method 0x570e1a36. +// +// Solidity: function createSender(bytes initCode) returns(address sender) +func (_SenderCreator *SenderCreatorSession) CreateSender(initCode []byte) (*types.Transaction, error) { + return _SenderCreator.Contract.CreateSender(&_SenderCreator.TransactOpts, initCode) +} + +// CreateSender is a paid mutator transaction binding the contract method 0x570e1a36. +// +// Solidity: function createSender(bytes initCode) returns(address sender) +func (_SenderCreator *SenderCreatorTransactorSession) CreateSender(initCode []byte) (*types.Transaction, error) { + return _SenderCreator.Contract.CreateSender(&_SenderCreator.TransactOpts, initCode) +} diff --git a/op-bindings/bindings/sendercreator_more.go b/op-bindings/bindings/sendercreator_more.go new file mode 100644 index 000000000000..73717610145e --- /dev/null +++ b/op-bindings/bindings/sendercreator_more.go @@ -0,0 +1,9 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +var SenderCreatorDeployedBin = "0x6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033" +func init() { + deployedBytecodes["SenderCreator"] = SenderCreatorDeployedBin +} diff --git a/op-bindings/bindings/sequencerfeevault.go b/op-bindings/bindings/sequencerfeevault.go index 10c70e4e1aa8..443fa3af97a7 100644 --- a/op-bindings/bindings/sequencerfeevault.go +++ b/op-bindings/bindings/sequencerfeevault.go @@ -30,7 +30,7 @@ var ( // SequencerFeeVaultMetaData contains all meta data concerning the SequencerFeeVault contract. var SequencerFeeVaultMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minWithdrawalAmount\",\"type\":\"uint256\"},{\"internalType\":\"enumFeeVault.WithdrawalNetwork\",\"name\":\"_withdrawalNetwork\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFeeVault.WithdrawalNetwork\",\"name\":\"withdrawalNetwork\",\"type\":\"uint8\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_WITHDRAWAL_AMOUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RECIPIENT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WITHDRAWAL_NETWORK\",\"outputs\":[{\"internalType\":\"enumFeeVault.WithdrawalNetwork\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1FeeWallet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalProcessed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_minWithdrawalAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_withdrawalNetwork\",\"type\":\"uint8\",\"internalType\":\"enumFeeVault.WithdrawalNetwork\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"MIN_WITHDRAWAL_AMOUNT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"RECIPIENT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"WITHDRAWAL_NETWORK\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumFeeVault.WithdrawalNetwork\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1FeeWallet\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalProcessed\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Withdrawal\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdrawal\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"withdrawalNetwork\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"enumFeeVault.WithdrawalNetwork\"}],\"anonymous\":false}]", Bin: "0x60e060405234801561001057600080fd5b5060405161091638038061091683398101604081905261002f91610079565b6001600160a01b03831660a0526080829052828282806001811115610056576100566100cc565b60c081600181111561006a5761006a6100cc565b815250505050505050506100e2565b60008060006060848603121561008e57600080fd5b83516001600160a01b03811681146100a557600080fd5b602085015160408601519194509250600281106100c157600080fd5b809150509250925092565b634e487b7160e01b600052602160045260246000fd5b60805160a05160c0516107ce61014860003960008181610181015281816103c701526104020152600081816092015281816101f301528181610316015281816103a50152818161043b01526105a20152600081816101c2015261021901526107ce6000f3fe6080604052600436106100745760003560e01c806384411d651161004e57806384411d651461014b578063d0e12f901461016f578063d3e5792b146101b0578063d4ff9218146101e457600080fd5b80630d9019e1146100805780633ccfd60b146100de57806354fd4d50146100f557600080fd5b3661007b57005b600080fd5b34801561008c57600080fd5b506100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100ea57600080fd5b506100f3610217565b005b34801561010157600080fd5b5061013e6040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b6040516100d5919061066e565b34801561015757600080fd5b5061016160005481565b6040519081526020016100d5565b34801561017b57600080fd5b506101a37f000000000000000000000000000000000000000000000000000000000000000081565b6040516100d591906106f2565b3480156101bc57600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b3480156101f057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006100b4565b7f00000000000000000000000000000000000000000000000000000000000000004710156102f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546103089190610706565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f0000000000000000000000000000000000000000000000000000000000000000337f00000000000000000000000000000000000000000000000000000000000000006040516103f69493929190610745565b60405180910390a160017f0000000000000000000000000000000000000000000000000000000000000000600181111561043257610432610688565b0361054b5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146104b1576040519150601f19603f3d011682016040523d82523d6000602084013e6104b6565b606091505b5050905080610547576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e740000000000000000000000000000000060648201526084016102e9565b5050565b604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd9184916105ce917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610786565b6000604051808303818588803b1580156105e757600080fd5b505af11580156105fb573d6000803e3d6000fd5b505050505050565b6000815180845260005b818110156106295760208185018101518683018201520161060d565b8181111561063b576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106816020830184610603565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106106ee577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6020810161070082846106b7565b92915050565b60008219821115610740577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff8481166020830152831660408201526080810161077d60608301846106b7565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061077d606083018461060356fea164736f6c634300080f000a", } diff --git a/op-bindings/bindings/sequencerfeevault_more.go b/op-bindings/bindings/sequencerfeevault_more.go index 0b1afa812db2..25d61dac2187 100644 --- a/op-bindings/bindings/sequencerfeevault_more.go +++ b/op-bindings/bindings/sequencerfeevault_more.go @@ -15,6 +15,7 @@ var SequencerFeeVaultStorageLayout = new(solc.StorageLayout) var SequencerFeeVaultDeployedBin = "0x6080604052600436106100745760003560e01c806384411d651161004e57806384411d651461014b578063d0e12f901461016f578063d3e5792b146101b0578063d4ff9218146101e457600080fd5b80630d9019e1146100805780633ccfd60b146100de57806354fd4d50146100f557600080fd5b3661007b57005b600080fd5b34801561008c57600080fd5b506100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100ea57600080fd5b506100f3610217565b005b34801561010157600080fd5b5061013e6040518060400160405280600581526020017f312e342e3100000000000000000000000000000000000000000000000000000081525081565b6040516100d5919061066e565b34801561015757600080fd5b5061016160005481565b6040519081526020016100d5565b34801561017b57600080fd5b506101a37f000000000000000000000000000000000000000000000000000000000000000081565b6040516100d591906106f2565b3480156101bc57600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b3480156101f057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006100b4565b7f00000000000000000000000000000000000000000000000000000000000000004710156102f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000479050806000808282546103089190610706565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a17f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee817f0000000000000000000000000000000000000000000000000000000000000000337f00000000000000000000000000000000000000000000000000000000000000006040516103f69493929190610745565b60405180910390a160017f0000000000000000000000000000000000000000000000000000000000000000600181111561043257610432610688565b0361054b5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146104b1576040519150601f19603f3d011682016040523d82523d6000602084013e6104b6565b606091505b5050905080610547576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e740000000000000000000000000000000060648201526084016102e9565b5050565b604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd9184916105ce917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610786565b6000604051808303818588803b1580156105e757600080fd5b505af11580156105fb573d6000803e3d6000fd5b505050505050565b6000815180845260005b818110156106295760208185018101518683018201520161060d565b8181111561063b576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106816020830184610603565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106106ee577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6020810161070082846106b7565b92915050565b60008219821115610740577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b84815273ffffffffffffffffffffffffffffffffffffffff8481166020830152831660408201526080810161077d60608301846106b7565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff8316602082015260606040820152600061077d606083018461060356fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(SequencerFeeVaultStorageLayoutJSON), SequencerFeeVaultStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["SequencerFeeVault"] = SequencerFeeVaultStorageLayout deployedBytecodes["SequencerFeeVault"] = SequencerFeeVaultDeployedBin + immutableReferences["SequencerFeeVault"] = true } diff --git a/op-bindings/bindings/standardbridge.go b/op-bindings/bindings/standardbridge.go index 1faadc60fec7..eb5866bb7254 100644 --- a/op-bindings/bindings/standardbridge.go +++ b/op-bindings/bindings/standardbridge.go @@ -30,7 +30,7 @@ var ( // StandardBridgeMetaData contains all meta data concerning the StandardBridge contract. var StandardBridgeMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ABI: "[{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"bridgeERC20\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bridgeERC20To\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bridgeETH\",\"inputs\":[{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"bridgeETHTo\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_minGasLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"deposits\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"finalizeBridgeERC20\",\"inputs\":[{\"name\":\"_localToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_remoteToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"finalizeBridgeETH\",\"inputs\":[{\"name\":\"_from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"messenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractCrossDomainMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"otherBridge\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractStandardBridge\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ERC20BridgeFinalized\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ERC20BridgeInitiated\",\"inputs\":[{\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ETHBridgeFinalized\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ETHBridgeInitiated\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false}]", } // StandardBridgeABI is the input ABI used to generate the binding from. @@ -334,6 +334,37 @@ func (_StandardBridge *StandardBridgeCallerSession) OtherBridge() (common.Addres return _StandardBridge.Contract.OtherBridge(&_StandardBridge.CallOpts) } +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_StandardBridge *StandardBridgeCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _StandardBridge.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_StandardBridge *StandardBridgeSession) Paused() (bool, error) { + return _StandardBridge.Contract.Paused(&_StandardBridge.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_StandardBridge *StandardBridgeCallerSession) Paused() (bool, error) { + return _StandardBridge.Contract.Paused(&_StandardBridge.CallOpts) +} + // BridgeERC20 is a paid mutator transaction binding the contract method 0x87087623. // // Solidity: function bridgeERC20(address _localToken, address _remoteToken, uint256 _amount, uint32 _minGasLimit, bytes _extraData) returns() diff --git a/op-bindings/bindings/standardbridge_more.go b/op-bindings/bindings/standardbridge_more.go index cd12378397df..e7915d5190f6 100644 --- a/op-bindings/bindings/standardbridge_more.go +++ b/op-bindings/bindings/standardbridge_more.go @@ -9,12 +9,13 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"spacer_0_2_20\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1003,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1005,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"messenger\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_contract(CrossDomainMessenger)1007\"},{\"astId\":1006,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_array(t_uint256)46_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)46_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[46]\",\"numberOfBytes\":\"1472\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(CrossDomainMessenger)1007\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"spacer_0_2_30\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_bytes30\"},{\"astId\":1003,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1005,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"messenger\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_contract(CrossDomainMessenger)1008\"},{\"astId\":1006,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"otherBridge\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_contract(StandardBridge)1009\"},{\"astId\":1007,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_array(t_uint256)45_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)45_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[45]\",\"numberOfBytes\":\"1440\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes30\":{\"encoding\":\"inplace\",\"label\":\"bytes30\",\"numberOfBytes\":\"30\"},\"t_contract(CrossDomainMessenger)1008\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_contract(StandardBridge)1009\":{\"encoding\":\"inplace\",\"label\":\"contract StandardBridge\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var StandardBridgeStorageLayout = new(solc.StorageLayout) var StandardBridgeDeployedBin = "0x" + func init() { if err := json.Unmarshal([]byte(StandardBridgeStorageLayoutJSON), StandardBridgeStorageLayout); err != nil { panic(err) @@ -22,4 +23,5 @@ func init() { layouts["StandardBridge"] = StandardBridgeStorageLayout deployedBytecodes["StandardBridge"] = StandardBridgeDeployedBin + immutableReferences["StandardBridge"] = false } diff --git a/op-bindings/bindings/storagesetter.go b/op-bindings/bindings/storagesetter.go index 91d46a33c011..72f36d8cfd2d 100644 --- a/op-bindings/bindings/storagesetter.go +++ b/op-bindings/bindings/storagesetter.go @@ -28,10 +28,16 @@ var ( _ = event.NewSubscription ) +// StorageSetterSlot is an auto generated low-level Go binding around an user-defined struct. +type StorageSetterSlot struct { + Key [32]byte + Value [32]byte +} + // StorageSetterMetaData contains all meta data concerning the StorageSetter contract. var StorageSetterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_slot\",\"type\":\"bytes32\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_slot\",\"type\":\"bytes32\"}],\"name\":\"getBytes32\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_slot\",\"type\":\"bytes32\"}],\"name\":\"getUint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_slot\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_slot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_value\",\"type\":\"bytes32\"}],\"name\":\"setBytes32\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_slot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"setUint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061025a806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063a6ed563e1161005b578063a6ed563e1461011c578063bd02d0f51461011c578063ca446dd914610138578063e2a4853a146100bf57600080fd5b806321f8a721146100825780634e91db08146100bf57806354fd4d50146100d3575b600080fd5b610095610090366004610156565b610146565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100d16100cd36600461016f565b9055565b005b61010f6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100b69190610191565b61012a610090366004610156565b6040519081526020016100b6565b6100d16100cd366004610204565b6000610150825490565b92915050565b60006020828403121561016857600080fd5b5035919050565b6000806040838503121561018257600080fd5b50508035926020909101359150565b600060208083528351808285015260005b818110156101be578581018301518582016040015282016101a2565b818111156101d0576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000806040838503121561021757600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811461024257600080fd5b80915050925092905056fea164736f6c634300080f000a", + ABI: "[{\"type\":\"function\",\"name\":\"getAddress\",\"inputs\":[{\"name\":\"_slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBool\",\"inputs\":[{\"name\":\"_slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"value_\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBytes32\",\"inputs\":[{\"name\":\"_slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"value_\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getUint\",\"inputs\":[{\"name\":\"_slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"value_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setAddress\",\"inputs\":[{\"name\":\"_slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_address\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setBool\",\"inputs\":[{\"name\":\"_slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_value\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setBytes32\",\"inputs\":[{\"name\":\"slots\",\"type\":\"tuple[]\",\"internalType\":\"structStorageSetter.Slot[]\",\"components\":[{\"name\":\"key\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"value\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setBytes32\",\"inputs\":[{\"name\":\"_slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_value\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setUint\",\"inputs\":[{\"name\":\"_slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"}]", + Bin: "0x608060405234801561001057600080fd5b5061046a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063a6ed563e11610076578063bd02d0f51161005b578063bd02d0f51461018e578063ca446dd9146101b8578063e2a4853a1461011557600080fd5b8063a6ed563e1461018e578063abfdcced146101aa57600080fd5b80634e91db08116100a75780634e91db081461011557806354fd4d50146101275780637ae1cfca1461017057600080fd5b80630528afe2146100c357806321f8a721146100d8575b600080fd5b6100d66100d1366004610239565b6101c6565b005b6100eb6100e63660046102ae565b610229565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100d66101233660046102c7565b9055565b6101636040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161010c91906102e9565b61017e6100e63660046102ae565b604051901515815260200161010c565b61019c6100e63660046102ae565b60405190815260200161010c565b6100d661012336600461035c565b6100d6610123366004610391565b8060005b81811015610223576102118484838181106101e7576101e76103cf565b90506040020160000135858584818110610203576102036103cf565b905060400201602001359055565b8061021b816103fe565b9150506101ca565b50505050565b6000610233825490565b92915050565b6000806020838503121561024c57600080fd5b823567ffffffffffffffff8082111561026457600080fd5b818501915085601f83011261027857600080fd5b81358181111561028757600080fd5b8660208260061b850101111561029c57600080fd5b60209290920196919550909350505050565b6000602082840312156102c057600080fd5b5035919050565b600080604083850312156102da57600080fd5b50508035926020909101359150565b600060208083528351808285015260005b81811015610316578581018301518582016040015282016102fa565b81811115610328576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000806040838503121561036f57600080fd5b823591506020830135801515811461038657600080fd5b809150509250929050565b600080604083850312156103a457600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811461038657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610456577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a", } // StorageSetterABI is the input ABI used to generate the binding from. @@ -203,7 +209,7 @@ func (_StorageSetter *StorageSetterTransactorRaw) Transact(opts *bind.TransactOp // GetAddress is a free data retrieval call binding the contract method 0x21f8a721. // -// Solidity: function getAddress(bytes32 _slot) view returns(address) +// Solidity: function getAddress(bytes32 _slot) view returns(address addr_) func (_StorageSetter *StorageSetterCaller) GetAddress(opts *bind.CallOpts, _slot [32]byte) (common.Address, error) { var out []interface{} err := _StorageSetter.contract.Call(opts, &out, "getAddress", _slot) @@ -220,21 +226,52 @@ func (_StorageSetter *StorageSetterCaller) GetAddress(opts *bind.CallOpts, _slot // GetAddress is a free data retrieval call binding the contract method 0x21f8a721. // -// Solidity: function getAddress(bytes32 _slot) view returns(address) +// Solidity: function getAddress(bytes32 _slot) view returns(address addr_) func (_StorageSetter *StorageSetterSession) GetAddress(_slot [32]byte) (common.Address, error) { return _StorageSetter.Contract.GetAddress(&_StorageSetter.CallOpts, _slot) } // GetAddress is a free data retrieval call binding the contract method 0x21f8a721. // -// Solidity: function getAddress(bytes32 _slot) view returns(address) +// Solidity: function getAddress(bytes32 _slot) view returns(address addr_) func (_StorageSetter *StorageSetterCallerSession) GetAddress(_slot [32]byte) (common.Address, error) { return _StorageSetter.Contract.GetAddress(&_StorageSetter.CallOpts, _slot) } +// GetBool is a free data retrieval call binding the contract method 0x7ae1cfca. +// +// Solidity: function getBool(bytes32 _slot) view returns(bool value_) +func (_StorageSetter *StorageSetterCaller) GetBool(opts *bind.CallOpts, _slot [32]byte) (bool, error) { + var out []interface{} + err := _StorageSetter.contract.Call(opts, &out, "getBool", _slot) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetBool is a free data retrieval call binding the contract method 0x7ae1cfca. +// +// Solidity: function getBool(bytes32 _slot) view returns(bool value_) +func (_StorageSetter *StorageSetterSession) GetBool(_slot [32]byte) (bool, error) { + return _StorageSetter.Contract.GetBool(&_StorageSetter.CallOpts, _slot) +} + +// GetBool is a free data retrieval call binding the contract method 0x7ae1cfca. +// +// Solidity: function getBool(bytes32 _slot) view returns(bool value_) +func (_StorageSetter *StorageSetterCallerSession) GetBool(_slot [32]byte) (bool, error) { + return _StorageSetter.Contract.GetBool(&_StorageSetter.CallOpts, _slot) +} + // GetBytes32 is a free data retrieval call binding the contract method 0xa6ed563e. // -// Solidity: function getBytes32(bytes32 _slot) view returns(bytes32) +// Solidity: function getBytes32(bytes32 _slot) view returns(bytes32 value_) func (_StorageSetter *StorageSetterCaller) GetBytes32(opts *bind.CallOpts, _slot [32]byte) ([32]byte, error) { var out []interface{} err := _StorageSetter.contract.Call(opts, &out, "getBytes32", _slot) @@ -251,21 +288,21 @@ func (_StorageSetter *StorageSetterCaller) GetBytes32(opts *bind.CallOpts, _slot // GetBytes32 is a free data retrieval call binding the contract method 0xa6ed563e. // -// Solidity: function getBytes32(bytes32 _slot) view returns(bytes32) +// Solidity: function getBytes32(bytes32 _slot) view returns(bytes32 value_) func (_StorageSetter *StorageSetterSession) GetBytes32(_slot [32]byte) ([32]byte, error) { return _StorageSetter.Contract.GetBytes32(&_StorageSetter.CallOpts, _slot) } // GetBytes32 is a free data retrieval call binding the contract method 0xa6ed563e. // -// Solidity: function getBytes32(bytes32 _slot) view returns(bytes32) +// Solidity: function getBytes32(bytes32 _slot) view returns(bytes32 value_) func (_StorageSetter *StorageSetterCallerSession) GetBytes32(_slot [32]byte) ([32]byte, error) { return _StorageSetter.Contract.GetBytes32(&_StorageSetter.CallOpts, _slot) } // GetUint is a free data retrieval call binding the contract method 0xbd02d0f5. // -// Solidity: function getUint(bytes32 _slot) view returns(uint256) +// Solidity: function getUint(bytes32 _slot) view returns(uint256 value_) func (_StorageSetter *StorageSetterCaller) GetUint(opts *bind.CallOpts, _slot [32]byte) (*big.Int, error) { var out []interface{} err := _StorageSetter.contract.Call(opts, &out, "getUint", _slot) @@ -282,14 +319,14 @@ func (_StorageSetter *StorageSetterCaller) GetUint(opts *bind.CallOpts, _slot [3 // GetUint is a free data retrieval call binding the contract method 0xbd02d0f5. // -// Solidity: function getUint(bytes32 _slot) view returns(uint256) +// Solidity: function getUint(bytes32 _slot) view returns(uint256 value_) func (_StorageSetter *StorageSetterSession) GetUint(_slot [32]byte) (*big.Int, error) { return _StorageSetter.Contract.GetUint(&_StorageSetter.CallOpts, _slot) } // GetUint is a free data retrieval call binding the contract method 0xbd02d0f5. // -// Solidity: function getUint(bytes32 _slot) view returns(uint256) +// Solidity: function getUint(bytes32 _slot) view returns(uint256 value_) func (_StorageSetter *StorageSetterCallerSession) GetUint(_slot [32]byte) (*big.Int, error) { return _StorageSetter.Contract.GetUint(&_StorageSetter.CallOpts, _slot) } @@ -346,25 +383,67 @@ func (_StorageSetter *StorageSetterTransactorSession) SetAddress(_slot [32]byte, return _StorageSetter.Contract.SetAddress(&_StorageSetter.TransactOpts, _slot, _address) } -// SetBytes32 is a paid mutator transaction binding the contract method 0x4e91db08. +// SetBool is a paid mutator transaction binding the contract method 0xabfdcced. +// +// Solidity: function setBool(bytes32 _slot, bool _value) returns() +func (_StorageSetter *StorageSetterTransactor) SetBool(opts *bind.TransactOpts, _slot [32]byte, _value bool) (*types.Transaction, error) { + return _StorageSetter.contract.Transact(opts, "setBool", _slot, _value) +} + +// SetBool is a paid mutator transaction binding the contract method 0xabfdcced. +// +// Solidity: function setBool(bytes32 _slot, bool _value) returns() +func (_StorageSetter *StorageSetterSession) SetBool(_slot [32]byte, _value bool) (*types.Transaction, error) { + return _StorageSetter.Contract.SetBool(&_StorageSetter.TransactOpts, _slot, _value) +} + +// SetBool is a paid mutator transaction binding the contract method 0xabfdcced. +// +// Solidity: function setBool(bytes32 _slot, bool _value) returns() +func (_StorageSetter *StorageSetterTransactorSession) SetBool(_slot [32]byte, _value bool) (*types.Transaction, error) { + return _StorageSetter.Contract.SetBool(&_StorageSetter.TransactOpts, _slot, _value) +} + +// SetBytes32 is a paid mutator transaction binding the contract method 0x0528afe2. +// +// Solidity: function setBytes32((bytes32,bytes32)[] slots) returns() +func (_StorageSetter *StorageSetterTransactor) SetBytes32(opts *bind.TransactOpts, slots []StorageSetterSlot) (*types.Transaction, error) { + return _StorageSetter.contract.Transact(opts, "setBytes32", slots) +} + +// SetBytes32 is a paid mutator transaction binding the contract method 0x0528afe2. +// +// Solidity: function setBytes32((bytes32,bytes32)[] slots) returns() +func (_StorageSetter *StorageSetterSession) SetBytes32(slots []StorageSetterSlot) (*types.Transaction, error) { + return _StorageSetter.Contract.SetBytes32(&_StorageSetter.TransactOpts, slots) +} + +// SetBytes32 is a paid mutator transaction binding the contract method 0x0528afe2. +// +// Solidity: function setBytes32((bytes32,bytes32)[] slots) returns() +func (_StorageSetter *StorageSetterTransactorSession) SetBytes32(slots []StorageSetterSlot) (*types.Transaction, error) { + return _StorageSetter.Contract.SetBytes32(&_StorageSetter.TransactOpts, slots) +} + +// SetBytes320 is a paid mutator transaction binding the contract method 0x4e91db08. // // Solidity: function setBytes32(bytes32 _slot, bytes32 _value) returns() -func (_StorageSetter *StorageSetterTransactor) SetBytes32(opts *bind.TransactOpts, _slot [32]byte, _value [32]byte) (*types.Transaction, error) { - return _StorageSetter.contract.Transact(opts, "setBytes32", _slot, _value) +func (_StorageSetter *StorageSetterTransactor) SetBytes320(opts *bind.TransactOpts, _slot [32]byte, _value [32]byte) (*types.Transaction, error) { + return _StorageSetter.contract.Transact(opts, "setBytes320", _slot, _value) } -// SetBytes32 is a paid mutator transaction binding the contract method 0x4e91db08. +// SetBytes320 is a paid mutator transaction binding the contract method 0x4e91db08. // // Solidity: function setBytes32(bytes32 _slot, bytes32 _value) returns() -func (_StorageSetter *StorageSetterSession) SetBytes32(_slot [32]byte, _value [32]byte) (*types.Transaction, error) { - return _StorageSetter.Contract.SetBytes32(&_StorageSetter.TransactOpts, _slot, _value) +func (_StorageSetter *StorageSetterSession) SetBytes320(_slot [32]byte, _value [32]byte) (*types.Transaction, error) { + return _StorageSetter.Contract.SetBytes320(&_StorageSetter.TransactOpts, _slot, _value) } -// SetBytes32 is a paid mutator transaction binding the contract method 0x4e91db08. +// SetBytes320 is a paid mutator transaction binding the contract method 0x4e91db08. // // Solidity: function setBytes32(bytes32 _slot, bytes32 _value) returns() -func (_StorageSetter *StorageSetterTransactorSession) SetBytes32(_slot [32]byte, _value [32]byte) (*types.Transaction, error) { - return _StorageSetter.Contract.SetBytes32(&_StorageSetter.TransactOpts, _slot, _value) +func (_StorageSetter *StorageSetterTransactorSession) SetBytes320(_slot [32]byte, _value [32]byte) (*types.Transaction, error) { + return _StorageSetter.Contract.SetBytes320(&_StorageSetter.TransactOpts, _slot, _value) } // SetUint is a paid mutator transaction binding the contract method 0xe2a4853a. diff --git a/op-bindings/bindings/storagesetter_more.go b/op-bindings/bindings/storagesetter_more.go index c7315ea6721d..8c1defd7b800 100644 --- a/op-bindings/bindings/storagesetter_more.go +++ b/op-bindings/bindings/storagesetter_more.go @@ -13,7 +13,8 @@ const StorageSetterStorageLayoutJSON = "{\"storage\":null,\"types\":{}}" var StorageSetterStorageLayout = new(solc.StorageLayout) -var StorageSetterDeployedBin = "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063a6ed563e1161005b578063a6ed563e1461011c578063bd02d0f51461011c578063ca446dd914610138578063e2a4853a146100bf57600080fd5b806321f8a721146100825780634e91db08146100bf57806354fd4d50146100d3575b600080fd5b610095610090366004610156565b610146565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100d16100cd36600461016f565b9055565b005b61010f6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100b69190610191565b61012a610090366004610156565b6040519081526020016100b6565b6100d16100cd366004610204565b6000610150825490565b92915050565b60006020828403121561016857600080fd5b5035919050565b6000806040838503121561018257600080fd5b50508035926020909101359150565b600060208083528351808285015260005b818110156101be578581018301518582016040015282016101a2565b818111156101d0576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000806040838503121561021757600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811461024257600080fd5b80915050925092905056fea164736f6c634300080f000a" +var StorageSetterDeployedBin = "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c8063a6ed563e11610076578063bd02d0f51161005b578063bd02d0f51461018e578063ca446dd9146101b8578063e2a4853a1461011557600080fd5b8063a6ed563e1461018e578063abfdcced146101aa57600080fd5b80634e91db08116100a75780634e91db081461011557806354fd4d50146101275780637ae1cfca1461017057600080fd5b80630528afe2146100c357806321f8a721146100d8575b600080fd5b6100d66100d1366004610239565b6101c6565b005b6100eb6100e63660046102ae565b610229565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100d66101233660046102c7565b9055565b6101636040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161010c91906102e9565b61017e6100e63660046102ae565b604051901515815260200161010c565b61019c6100e63660046102ae565b60405190815260200161010c565b6100d661012336600461035c565b6100d6610123366004610391565b8060005b81811015610223576102118484838181106101e7576101e76103cf565b90506040020160000135858584818110610203576102036103cf565b905060400201602001359055565b8061021b816103fe565b9150506101ca565b50505050565b6000610233825490565b92915050565b6000806020838503121561024c57600080fd5b823567ffffffffffffffff8082111561026457600080fd5b818501915085601f83011261027857600080fd5b81358181111561028757600080fd5b8660208260061b850101111561029c57600080fd5b60209290920196919550909350505050565b6000602082840312156102c057600080fd5b5035919050565b600080604083850312156102da57600080fd5b50508035926020909101359150565b600060208083528351808285015260005b81811015610316578581018301518582016040015282016102fa565b81811115610328576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000806040838503121561036f57600080fd5b823591506020830135801515811461038657600080fd5b809150509250929050565b600080604083850312156103a457600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811461038657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610456577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(StorageSetterStorageLayoutJSON), StorageSetterStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["StorageSetter"] = StorageSetterStorageLayout deployedBytecodes["StorageSetter"] = StorageSetterDeployedBin + immutableReferences["StorageSetter"] = false } diff --git a/op-bindings/bindings/superchainconfig.go b/op-bindings/bindings/superchainconfig.go new file mode 100644 index 000000000000..d71a17956eb5 --- /dev/null +++ b/op-bindings/bindings/superchainconfig.go @@ -0,0 +1,966 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// SuperchainConfigMetaData contains all meta data concerning the SuperchainConfig contract. +var SuperchainConfigMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"GUARDIAN_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PAUSED_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"guardian\",\"inputs\":[],\"outputs\":[{\"name\":\"guardian_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_guardian\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_paused\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"_identifier\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"paused_\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ConfigUpdate\",\"inputs\":[{\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumSuperchainConfig.UpdateType\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"identifier\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b506200001f60008062000025565b62000361565b600054610100900460ff1615808015620000465750600054600160ff909116105b8062000076575062000063306200019460201b620005fd1760201c565b15801562000076575060005460ff166001145b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff19166001179055801562000102576000805461ff0019166101001790555b6200010d83620001a3565b81156200014857604080518082019091526012815271125b9a5d1a585b1a5e995c881c185d5cd95960721b6020820152620001489062000248565b80156200018f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b620001e9620001d460017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69620002cf565b60001b82620002cb60201b620006191760201c565b6000604080516001600160a01b03841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb910160408051601f19818403018152908290526200023d9162000345565b60405180910390a250565b6200028f6200027960017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7620002cf565b60001b6001620002cb60201b620006191760201c565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea2838181604051620002c0919062000345565b60405180910390a150565b9055565b600082821015620002f057634e487b7160e01b600052601160045260246000fd5b500390565b6000815180845260005b818110156200031d57602081850181015186830182015201620002ff565b8181111562000330576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006200035a6020830184620002f5565b9392505050565b61096b80620003716000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", +} + +// SuperchainConfigABI is the input ABI used to generate the binding from. +// Deprecated: Use SuperchainConfigMetaData.ABI instead. +var SuperchainConfigABI = SuperchainConfigMetaData.ABI + +// SuperchainConfigBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SuperchainConfigMetaData.Bin instead. +var SuperchainConfigBin = SuperchainConfigMetaData.Bin + +// DeploySuperchainConfig deploys a new Ethereum contract, binding an instance of SuperchainConfig to it. +func DeploySuperchainConfig(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SuperchainConfig, error) { + parsed, err := SuperchainConfigMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SuperchainConfigBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &SuperchainConfig{SuperchainConfigCaller: SuperchainConfigCaller{contract: contract}, SuperchainConfigTransactor: SuperchainConfigTransactor{contract: contract}, SuperchainConfigFilterer: SuperchainConfigFilterer{contract: contract}}, nil +} + +// SuperchainConfig is an auto generated Go binding around an Ethereum contract. +type SuperchainConfig struct { + SuperchainConfigCaller // Read-only binding to the contract + SuperchainConfigTransactor // Write-only binding to the contract + SuperchainConfigFilterer // Log filterer for contract events +} + +// SuperchainConfigCaller is an auto generated read-only Go binding around an Ethereum contract. +type SuperchainConfigCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SuperchainConfigTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SuperchainConfigTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SuperchainConfigFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SuperchainConfigFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// SuperchainConfigSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type SuperchainConfigSession struct { + Contract *SuperchainConfig // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SuperchainConfigCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type SuperchainConfigCallerSession struct { + Contract *SuperchainConfigCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// SuperchainConfigTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type SuperchainConfigTransactorSession struct { + Contract *SuperchainConfigTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// SuperchainConfigRaw is an auto generated low-level Go binding around an Ethereum contract. +type SuperchainConfigRaw struct { + Contract *SuperchainConfig // Generic contract binding to access the raw methods on +} + +// SuperchainConfigCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SuperchainConfigCallerRaw struct { + Contract *SuperchainConfigCaller // Generic read-only contract binding to access the raw methods on +} + +// SuperchainConfigTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SuperchainConfigTransactorRaw struct { + Contract *SuperchainConfigTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewSuperchainConfig creates a new instance of SuperchainConfig, bound to a specific deployed contract. +func NewSuperchainConfig(address common.Address, backend bind.ContractBackend) (*SuperchainConfig, error) { + contract, err := bindSuperchainConfig(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &SuperchainConfig{SuperchainConfigCaller: SuperchainConfigCaller{contract: contract}, SuperchainConfigTransactor: SuperchainConfigTransactor{contract: contract}, SuperchainConfigFilterer: SuperchainConfigFilterer{contract: contract}}, nil +} + +// NewSuperchainConfigCaller creates a new read-only instance of SuperchainConfig, bound to a specific deployed contract. +func NewSuperchainConfigCaller(address common.Address, caller bind.ContractCaller) (*SuperchainConfigCaller, error) { + contract, err := bindSuperchainConfig(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &SuperchainConfigCaller{contract: contract}, nil +} + +// NewSuperchainConfigTransactor creates a new write-only instance of SuperchainConfig, bound to a specific deployed contract. +func NewSuperchainConfigTransactor(address common.Address, transactor bind.ContractTransactor) (*SuperchainConfigTransactor, error) { + contract, err := bindSuperchainConfig(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &SuperchainConfigTransactor{contract: contract}, nil +} + +// NewSuperchainConfigFilterer creates a new log filterer instance of SuperchainConfig, bound to a specific deployed contract. +func NewSuperchainConfigFilterer(address common.Address, filterer bind.ContractFilterer) (*SuperchainConfigFilterer, error) { + contract, err := bindSuperchainConfig(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &SuperchainConfigFilterer{contract: contract}, nil +} + +// bindSuperchainConfig binds a generic wrapper to an already deployed contract. +func bindSuperchainConfig(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SuperchainConfigABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SuperchainConfig *SuperchainConfigRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SuperchainConfig.Contract.SuperchainConfigCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SuperchainConfig *SuperchainConfigRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SuperchainConfig.Contract.SuperchainConfigTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SuperchainConfig *SuperchainConfigRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SuperchainConfig.Contract.SuperchainConfigTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_SuperchainConfig *SuperchainConfigCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SuperchainConfig.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_SuperchainConfig *SuperchainConfigTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SuperchainConfig.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_SuperchainConfig *SuperchainConfigTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SuperchainConfig.Contract.contract.Transact(opts, method, params...) +} + +// GUARDIANSLOT is a free data retrieval call binding the contract method 0xc23a451a. +// +// Solidity: function GUARDIAN_SLOT() view returns(bytes32) +func (_SuperchainConfig *SuperchainConfigCaller) GUARDIANSLOT(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _SuperchainConfig.contract.Call(opts, &out, "GUARDIAN_SLOT") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GUARDIANSLOT is a free data retrieval call binding the contract method 0xc23a451a. +// +// Solidity: function GUARDIAN_SLOT() view returns(bytes32) +func (_SuperchainConfig *SuperchainConfigSession) GUARDIANSLOT() ([32]byte, error) { + return _SuperchainConfig.Contract.GUARDIANSLOT(&_SuperchainConfig.CallOpts) +} + +// GUARDIANSLOT is a free data retrieval call binding the contract method 0xc23a451a. +// +// Solidity: function GUARDIAN_SLOT() view returns(bytes32) +func (_SuperchainConfig *SuperchainConfigCallerSession) GUARDIANSLOT() ([32]byte, error) { + return _SuperchainConfig.Contract.GUARDIANSLOT(&_SuperchainConfig.CallOpts) +} + +// PAUSEDSLOT is a free data retrieval call binding the contract method 0x7fbf7b6a. +// +// Solidity: function PAUSED_SLOT() view returns(bytes32) +func (_SuperchainConfig *SuperchainConfigCaller) PAUSEDSLOT(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _SuperchainConfig.contract.Call(opts, &out, "PAUSED_SLOT") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// PAUSEDSLOT is a free data retrieval call binding the contract method 0x7fbf7b6a. +// +// Solidity: function PAUSED_SLOT() view returns(bytes32) +func (_SuperchainConfig *SuperchainConfigSession) PAUSEDSLOT() ([32]byte, error) { + return _SuperchainConfig.Contract.PAUSEDSLOT(&_SuperchainConfig.CallOpts) +} + +// PAUSEDSLOT is a free data retrieval call binding the contract method 0x7fbf7b6a. +// +// Solidity: function PAUSED_SLOT() view returns(bytes32) +func (_SuperchainConfig *SuperchainConfigCallerSession) PAUSEDSLOT() ([32]byte, error) { + return _SuperchainConfig.Contract.PAUSEDSLOT(&_SuperchainConfig.CallOpts) +} + +// Guardian is a free data retrieval call binding the contract method 0x452a9320. +// +// Solidity: function guardian() view returns(address guardian_) +func (_SuperchainConfig *SuperchainConfigCaller) Guardian(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SuperchainConfig.contract.Call(opts, &out, "guardian") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Guardian is a free data retrieval call binding the contract method 0x452a9320. +// +// Solidity: function guardian() view returns(address guardian_) +func (_SuperchainConfig *SuperchainConfigSession) Guardian() (common.Address, error) { + return _SuperchainConfig.Contract.Guardian(&_SuperchainConfig.CallOpts) +} + +// Guardian is a free data retrieval call binding the contract method 0x452a9320. +// +// Solidity: function guardian() view returns(address guardian_) +func (_SuperchainConfig *SuperchainConfigCallerSession) Guardian() (common.Address, error) { + return _SuperchainConfig.Contract.Guardian(&_SuperchainConfig.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool paused_) +func (_SuperchainConfig *SuperchainConfigCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _SuperchainConfig.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool paused_) +func (_SuperchainConfig *SuperchainConfigSession) Paused() (bool, error) { + return _SuperchainConfig.Contract.Paused(&_SuperchainConfig.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool paused_) +func (_SuperchainConfig *SuperchainConfigCallerSession) Paused() (bool, error) { + return _SuperchainConfig.Contract.Paused(&_SuperchainConfig.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_SuperchainConfig *SuperchainConfigCaller) Version(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _SuperchainConfig.contract.Call(opts, &out, "version") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_SuperchainConfig *SuperchainConfigSession) Version() (string, error) { + return _SuperchainConfig.Contract.Version(&_SuperchainConfig.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_SuperchainConfig *SuperchainConfigCallerSession) Version() (string, error) { + return _SuperchainConfig.Contract.Version(&_SuperchainConfig.CallOpts) +} + +// Initialize is a paid mutator transaction binding the contract method 0x400ada75. +// +// Solidity: function initialize(address _guardian, bool _paused) returns() +func (_SuperchainConfig *SuperchainConfigTransactor) Initialize(opts *bind.TransactOpts, _guardian common.Address, _paused bool) (*types.Transaction, error) { + return _SuperchainConfig.contract.Transact(opts, "initialize", _guardian, _paused) +} + +// Initialize is a paid mutator transaction binding the contract method 0x400ada75. +// +// Solidity: function initialize(address _guardian, bool _paused) returns() +func (_SuperchainConfig *SuperchainConfigSession) Initialize(_guardian common.Address, _paused bool) (*types.Transaction, error) { + return _SuperchainConfig.Contract.Initialize(&_SuperchainConfig.TransactOpts, _guardian, _paused) +} + +// Initialize is a paid mutator transaction binding the contract method 0x400ada75. +// +// Solidity: function initialize(address _guardian, bool _paused) returns() +func (_SuperchainConfig *SuperchainConfigTransactorSession) Initialize(_guardian common.Address, _paused bool) (*types.Transaction, error) { + return _SuperchainConfig.Contract.Initialize(&_SuperchainConfig.TransactOpts, _guardian, _paused) +} + +// Pause is a paid mutator transaction binding the contract method 0x6da66355. +// +// Solidity: function pause(string _identifier) returns() +func (_SuperchainConfig *SuperchainConfigTransactor) Pause(opts *bind.TransactOpts, _identifier string) (*types.Transaction, error) { + return _SuperchainConfig.contract.Transact(opts, "pause", _identifier) +} + +// Pause is a paid mutator transaction binding the contract method 0x6da66355. +// +// Solidity: function pause(string _identifier) returns() +func (_SuperchainConfig *SuperchainConfigSession) Pause(_identifier string) (*types.Transaction, error) { + return _SuperchainConfig.Contract.Pause(&_SuperchainConfig.TransactOpts, _identifier) +} + +// Pause is a paid mutator transaction binding the contract method 0x6da66355. +// +// Solidity: function pause(string _identifier) returns() +func (_SuperchainConfig *SuperchainConfigTransactorSession) Pause(_identifier string) (*types.Transaction, error) { + return _SuperchainConfig.Contract.Pause(&_SuperchainConfig.TransactOpts, _identifier) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_SuperchainConfig *SuperchainConfigTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SuperchainConfig.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_SuperchainConfig *SuperchainConfigSession) Unpause() (*types.Transaction, error) { + return _SuperchainConfig.Contract.Unpause(&_SuperchainConfig.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_SuperchainConfig *SuperchainConfigTransactorSession) Unpause() (*types.Transaction, error) { + return _SuperchainConfig.Contract.Unpause(&_SuperchainConfig.TransactOpts) +} + +// SuperchainConfigConfigUpdateIterator is returned from FilterConfigUpdate and is used to iterate over the raw logs and unpacked data for ConfigUpdate events raised by the SuperchainConfig contract. +type SuperchainConfigConfigUpdateIterator struct { + Event *SuperchainConfigConfigUpdate // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SuperchainConfigConfigUpdateIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SuperchainConfigConfigUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SuperchainConfigConfigUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SuperchainConfigConfigUpdateIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SuperchainConfigConfigUpdateIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SuperchainConfigConfigUpdate represents a ConfigUpdate event raised by the SuperchainConfig contract. +type SuperchainConfigConfigUpdate struct { + UpdateType uint8 + Data []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterConfigUpdate is a free log retrieval operation binding the contract event 0x7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb. +// +// Solidity: event ConfigUpdate(uint8 indexed updateType, bytes data) +func (_SuperchainConfig *SuperchainConfigFilterer) FilterConfigUpdate(opts *bind.FilterOpts, updateType []uint8) (*SuperchainConfigConfigUpdateIterator, error) { + + var updateTypeRule []interface{} + for _, updateTypeItem := range updateType { + updateTypeRule = append(updateTypeRule, updateTypeItem) + } + + logs, sub, err := _SuperchainConfig.contract.FilterLogs(opts, "ConfigUpdate", updateTypeRule) + if err != nil { + return nil, err + } + return &SuperchainConfigConfigUpdateIterator{contract: _SuperchainConfig.contract, event: "ConfigUpdate", logs: logs, sub: sub}, nil +} + +// WatchConfigUpdate is a free log subscription operation binding the contract event 0x7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb. +// +// Solidity: event ConfigUpdate(uint8 indexed updateType, bytes data) +func (_SuperchainConfig *SuperchainConfigFilterer) WatchConfigUpdate(opts *bind.WatchOpts, sink chan<- *SuperchainConfigConfigUpdate, updateType []uint8) (event.Subscription, error) { + + var updateTypeRule []interface{} + for _, updateTypeItem := range updateType { + updateTypeRule = append(updateTypeRule, updateTypeItem) + } + + logs, sub, err := _SuperchainConfig.contract.WatchLogs(opts, "ConfigUpdate", updateTypeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SuperchainConfigConfigUpdate) + if err := _SuperchainConfig.contract.UnpackLog(event, "ConfigUpdate", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseConfigUpdate is a log parse operation binding the contract event 0x7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb. +// +// Solidity: event ConfigUpdate(uint8 indexed updateType, bytes data) +func (_SuperchainConfig *SuperchainConfigFilterer) ParseConfigUpdate(log types.Log) (*SuperchainConfigConfigUpdate, error) { + event := new(SuperchainConfigConfigUpdate) + if err := _SuperchainConfig.contract.UnpackLog(event, "ConfigUpdate", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SuperchainConfigInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the SuperchainConfig contract. +type SuperchainConfigInitializedIterator struct { + Event *SuperchainConfigInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SuperchainConfigInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SuperchainConfigInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SuperchainConfigInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SuperchainConfigInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SuperchainConfigInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SuperchainConfigInitialized represents a Initialized event raised by the SuperchainConfig contract. +type SuperchainConfigInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SuperchainConfig *SuperchainConfigFilterer) FilterInitialized(opts *bind.FilterOpts) (*SuperchainConfigInitializedIterator, error) { + + logs, sub, err := _SuperchainConfig.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &SuperchainConfigInitializedIterator{contract: _SuperchainConfig.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SuperchainConfig *SuperchainConfigFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *SuperchainConfigInitialized) (event.Subscription, error) { + + logs, sub, err := _SuperchainConfig.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SuperchainConfigInitialized) + if err := _SuperchainConfig.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SuperchainConfig *SuperchainConfigFilterer) ParseInitialized(log types.Log) (*SuperchainConfigInitialized, error) { + event := new(SuperchainConfigInitialized) + if err := _SuperchainConfig.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SuperchainConfigPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the SuperchainConfig contract. +type SuperchainConfigPausedIterator struct { + Event *SuperchainConfigPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SuperchainConfigPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SuperchainConfigPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SuperchainConfigPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SuperchainConfigPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SuperchainConfigPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SuperchainConfigPaused represents a Paused event raised by the SuperchainConfig contract. +type SuperchainConfigPaused struct { + Identifier string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0xc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea28381. +// +// Solidity: event Paused(string identifier) +func (_SuperchainConfig *SuperchainConfigFilterer) FilterPaused(opts *bind.FilterOpts) (*SuperchainConfigPausedIterator, error) { + + logs, sub, err := _SuperchainConfig.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &SuperchainConfigPausedIterator{contract: _SuperchainConfig.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0xc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea28381. +// +// Solidity: event Paused(string identifier) +func (_SuperchainConfig *SuperchainConfigFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *SuperchainConfigPaused) (event.Subscription, error) { + + logs, sub, err := _SuperchainConfig.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SuperchainConfigPaused) + if err := _SuperchainConfig.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParsePaused is a log parse operation binding the contract event 0xc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea28381. +// +// Solidity: event Paused(string identifier) +func (_SuperchainConfig *SuperchainConfigFilterer) ParsePaused(log types.Log) (*SuperchainConfigPaused, error) { + event := new(SuperchainConfigPaused) + if err := _SuperchainConfig.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// SuperchainConfigUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the SuperchainConfig contract. +type SuperchainConfigUnpausedIterator struct { + Event *SuperchainConfigUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SuperchainConfigUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SuperchainConfigUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SuperchainConfigUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SuperchainConfigUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SuperchainConfigUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// SuperchainConfigUnpaused represents a Unpaused event raised by the SuperchainConfig contract. +type SuperchainConfigUnpaused struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0xa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d16933. +// +// Solidity: event Unpaused() +func (_SuperchainConfig *SuperchainConfigFilterer) FilterUnpaused(opts *bind.FilterOpts) (*SuperchainConfigUnpausedIterator, error) { + + logs, sub, err := _SuperchainConfig.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &SuperchainConfigUnpausedIterator{contract: _SuperchainConfig.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0xa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d16933. +// +// Solidity: event Unpaused() +func (_SuperchainConfig *SuperchainConfigFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *SuperchainConfigUnpaused) (event.Subscription, error) { + + logs, sub, err := _SuperchainConfig.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SuperchainConfigUnpaused) + if err := _SuperchainConfig.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUnpaused is a log parse operation binding the contract event 0xa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d16933. +// +// Solidity: event Unpaused() +func (_SuperchainConfig *SuperchainConfigFilterer) ParseUnpaused(log types.Log) (*SuperchainConfigUnpaused, error) { + event := new(SuperchainConfigUnpaused) + if err := _SuperchainConfig.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-bindings/bindings/superchainconfig_more.go b/op-bindings/bindings/superchainconfig_more.go new file mode 100644 index 000000000000..681b98446961 --- /dev/null +++ b/op-bindings/bindings/superchainconfig_more.go @@ -0,0 +1,27 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "encoding/json" + + "github.com/ethereum-optimism/optimism/op-bindings/solc" +) + +const SuperchainConfigStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/SuperchainConfig.sol:SuperchainConfig\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/SuperchainConfig.sol:SuperchainConfig\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" + +var SuperchainConfigStorageLayout = new(solc.StorageLayout) + +var SuperchainConfigDeployedBin = "0x608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a" + + +func init() { + if err := json.Unmarshal([]byte(SuperchainConfigStorageLayoutJSON), SuperchainConfigStorageLayout); err != nil { + panic(err) + } + + layouts["SuperchainConfig"] = SuperchainConfigStorageLayout + deployedBytecodes["SuperchainConfig"] = SuperchainConfigDeployedBin + immutableReferences["SuperchainConfig"] = false +} diff --git a/op-bindings/bindings/systemconfig.go b/op-bindings/bindings/systemconfig.go index d70740b9c8fc..7a8b5b34772f 100644 --- a/op-bindings/bindings/systemconfig.go +++ b/op-bindings/bindings/systemconfig.go @@ -50,8 +50,8 @@ type SystemConfigAddresses struct { // SystemConfigMetaData contains all meta data concerning the SystemConfig contract. var SystemConfigMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"enumSystemConfig.UpdateType\",\"name\":\"updateType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"ConfigUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BATCH_INBOX_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L1_CROSS_DOMAIN_MESSENGER_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L1_ERC_721_BRIDGE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L1_STANDARD_BRIDGE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_OUTPUT_ORACLE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPTIMISM_PORTAL_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UNSAFE_BLOCK_SIGNER_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batchInbox\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batcherHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_scalar\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_batcherHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"_unsafeBlockSigner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}],\"internalType\":\"structResourceMetering.ResourceConfig\",\"name\":\"_config\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_startBlock\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_batchInbox\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"l1CrossDomainMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1ERC721Bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1StandardBridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l2OutputOracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismPortal\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismMintableERC20Factory\",\"type\":\"address\"}],\"internalType\":\"structSystemConfig.Addresses\",\"name\":\"_addresses\",\"type\":\"tuple\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1CrossDomainMessenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1ERC721Bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1StandardBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2OutputOracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"optimismMintableERC20Factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"optimismPortal\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"overhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resourceConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}],\"internalType\":\"structResourceMetering.ResourceConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"scalar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_batcherHash\",\"type\":\"bytes32\"}],\"name\":\"setBatcherHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_scalar\",\"type\":\"uint256\"}],\"name\":\"setGasConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"}],\"name\":\"setGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}],\"internalType\":\"structResourceMetering.ResourceConfig\",\"name\":\"_config\",\"type\":\"tuple\"}],\"name\":\"setResourceConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_unsafeBlockSigner\",\"type\":\"address\"}],\"name\":\"setUnsafeBlockSigner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unsafeBlockSigner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b506040805160c080820183526001808352602080840182905260028486015260006060808601829052608080870183905260a08088018490528851968701895283875293860183905296850182905284018190529483018590528201849052620000909361dead93909283928392909183919060001990839062000096565b62000ccc565b600054600390610100900460ff16158015620000b9575060005460ff8083169116105b620001225760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620001406200043a565b6200014b8b620004a2565b620001568862000521565b620001628a8a62000573565b6200016d87620005d7565b620001788662000674565b620001be620001a960017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59862000ba9565b60001b84620006dc60201b62000d211760201c565b62000208620001ef60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063762000ba9565b60001b8360000151620006dc60201b62000d211760201c565b620002526200023960017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a862000ba9565b60001b8360200151620006dc60201b62000d211760201c565b6200029c6200028360017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637762000ba9565b60001b8360400151620006dc60201b62000d211760201c565b620002e6620002cd60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a687181662000ba9565b60001b8360600151620006dc60201b62000d211760201c565b620003306200031760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad62000ba9565b60001b8360800151620006dc60201b62000d211760201c565b6200037a6200036160017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d62000ba9565b60001b8360a00151620006dc60201b62000d211760201c565b6200038584620006e0565b62000390856200070d565b6200039a62000a51565b6001600160401b0316876001600160401b03161015620003ec5760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b600054610100900460ff16620004965760405162461bcd60e51b815260206004820152602b60248201526000805160206200285f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000119565b620004a062000a7e565b565b620004ac62000ae5565b6001600160a01b038116620005135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000119565b6200051e8162000b41565b50565b60678190556040805160208082018490528251808303909101815290820190915260005b60006000805160206200283f8339815191528360405162000567919062000bc3565b60405180910390a35050565b60658290556066819055604080516020810184905290810182905260009060600160408051601f198184030181529190529050600160006000805160206200283f83398151915283604051620005ca919062000bc3565b60405180910390a3505050565b620005e162000a51565b6001600160401b0316816001600160401b03161015620006335760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b606880546001600160401b0319166001600160401b038316908117909155604080516020808201939093528151808203909301835281019052600262000545565b620006ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0882620006dc60201b62000d211760201c565b604080516001600160a01b03831660208201526000910160408051601f198184030181529190529050600362000545565b9055565b8015801590620006f05750606a54155b15620006fb57606a55565b606a546000036200051e5743606a5550565b8060a001516001600160801b0316816060015163ffffffff1611156200079c5760405162461bcd60e51b815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840162000119565b6001816040015160ff16116200080d5760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201526e65206c6172676572207468616e203160881b606482015260840162000119565b606854608082015182516001600160401b03909216916200082f919062000c1b565b63ffffffff161115620008745760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b6000816020015160ff1611620008e55760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201526e06965722063616e6e6f74206265203608c1b606482015260840162000119565b8051602082015163ffffffff82169160ff909116906200090790829062000c46565b62000913919062000c78565b63ffffffff16146200098e5760405162461bcd60e51b815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840162000119565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff96871664ffffffffff199095169490941764010000000060ff948516021764ffffffffff60281b191665010000000000939092169290920263ffffffff60301b19161766010000000000009185169190910217600160501b600160f01b0319166a01000000000000000000009390941692909202600160701b600160f01b03191692909217600160701b6001600160801b0390921691909102179055565b60695460009062000a799063ffffffff6a010000000000000000000082048116911662000ca7565b905090565b600054610100900460ff1662000ada5760405162461bcd60e51b815260206004820152602b60248201526000805160206200285f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000119565b620004a03362000b41565b6033546001600160a01b03163314620004a05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000119565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052601160045260246000fd5b60008282101562000bbe5762000bbe62000b93565b500390565b600060208083528351808285015260005b8181101562000bf25785810183015185820160400152820162000bd4565b8181111562000c05576000604083870101525b50601f01601f1916929092016040019392505050565b600063ffffffff80831681851680830382111562000c3d5762000c3d62000b93565b01949350505050565b600063ffffffff8084168062000c6c57634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b600063ffffffff8083168185168183048111821515161562000c9e5762000c9e62000b93565b02949350505050565b60006001600160401b0382811684821680830382111562000c3d5762000c3d62000b93565b611b438062000cdc6000396000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c8063935f029e1161012a578063cc731b02116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610575578063fd32aa0f1461057d578063ffa1ad741461058557600080fd5b8063f45e65d814610558578063f68016b71461056157600080fd5b8063cc731b0214610400578063dac6e63a14610534578063e81b2c6d1461053c578063f2fde38b1461054557600080fd5b8063bc49ce5f116100f9578063bc49ce5f146103ca578063c4e8ddfa146103d2578063c71973f6146103da578063c9b26f61146103ed57600080fd5b8063935f029e146103945780639b7d7f0a146103a7578063a7119869146103af578063b40a817c146103b757600080fd5b80634add321d116101bd57806354fd4d501161018c57806361d157681161017157806361d1576814610366578063715018a61461036e5780638da5cb5b1461037657600080fd5b806354fd4d50146103155780635d73369c1461035e57600080fd5b80634add321d146102b25780634d9f1559146102d35780634f16540b146102db5780635228a6ac1461030257600080fd5b806318d13918116101f957806318d139181461028457806319f5cea8146102995780631fd19ee1146102a157806348cd4cb1146102a957600080fd5b806306c926571461022b578063078f29cf146102465780630a49cb03146102735780630c18c1621461027b575b600080fd5b61023361058d565b6040519081526020015b60405180910390f35b61024e6105bb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023d565b61024e6105f4565b61023360655481565b610297610292366004611677565b610624565b005b610233610638565b61024e610663565b610233606a5481565b6102ba61068d565b60405167ffffffffffffffff909116815260200161023d565b61024e6106b3565b6102337f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b610297610310366004611807565b6106e3565b6103516040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b60405161023d91906119aa565b610233610a79565b610233610aa4565b610297610acf565b60335473ffffffffffffffffffffffffffffffffffffffff1661024e565b6102976103a23660046119bd565b610ae3565b61024e610af9565b61024e610b29565b6102976103c53660046119df565b610b59565b610233610b6a565b61024e610b95565b6102976103e83660046119fa565b610bc5565b6102976103fb366004611a16565b610bd6565b6104c46040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b60405161023d9190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61024e610be7565b61023360675481565b610297610553366004611677565b610c17565b61023360665481565b6068546102ba9067ffffffffffffffff1681565b610233610ccb565b610233610cf6565b610233600081565b6105b860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b81565b60006105ef6105eb60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b5490565b905090565b60006105ef6105eb60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b61062c610d25565b61063581610da6565b50565b6105b860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60006105ef7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b6069546000906105ef9063ffffffff6a0100000000000000000000820481169116611a75565b60006105ef6105eb60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b600054600390610100900460ff16158015610705575060005460ff8083169116105b610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556107cf610e63565b6107d88b610c17565b6107e188610f02565b6107eb8a8a610f2a565b6107f487610fbb565b6107fd86610da6565b61083061082b60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b849055565b61086461085e60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b83519055565b61089b61089260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60208401519055565b6108d26108c960017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b60408401519055565b61090961090060017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b60608401519055565b61094061093760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b60808401519055565b61097761096e60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60a08401519055565b61098084611099565b610989856110c3565b61099161068d565b67ffffffffffffffff168767ffffffffffffffff161015610a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b6105b860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b6105b860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b610ad7610d25565b610ae16000611537565b565b610aeb610d25565b610af58282610f2a565b5050565b60006105ef6105eb60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60006105ef6105eb60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b610b61610d25565b61063581610fbb565b6105b860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b60006105ef6105eb60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b610bcd610d25565b610635816110c3565b610bde610d25565b61063581610f02565b60006105ef6105eb60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b610c1f610d25565b73ffffffffffffffffffffffffffffffffffffffff8116610cc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161078d565b61063581611537565b6105b860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b6105b860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161078d565b610dcf7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610e5791906119aa565b60405180910390a35050565b600054610100900460ff16610efa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae16115ae565b6067819055604080516020808201849052825180830390910181529082019091526000610e26565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae91906119aa565b60405180910390a3505050565b610fc361068d565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610e26565b80158015906110a85750606a54155b156110b257606a55565b606a546000036106355743606a5550565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611173576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840161078d565b6001816040015160ff161161120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e20310000000000000000000000000000000000606482015260840161078d565b6068546080820151825167ffffffffffffffff9092169161122b9190611aa1565b63ffffffff161115611299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b6000816020015160ff1611611330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f7420626520300000000000000000000000000000000000606482015260840161078d565b8051602082015163ffffffff82169160ff90911690611350908290611ac0565b61135a9190611b0a565b63ffffffff16146113ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840161078d565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae133611537565b803573ffffffffffffffffffffffffffffffffffffffff8116811461167257600080fd5b919050565b60006020828403121561168957600080fd5b6116928261164e565b9392505050565b803567ffffffffffffffff8116811461167257600080fd5b60405160c0810167ffffffffffffffff811182821017156116fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff8116811461167257600080fd5b803560ff8116811461167257600080fd5b600060c0828403121561173857600080fd5b60405160c0810181811067ffffffffffffffff82111715611782577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061179183611701565b815261179f60208401611715565b60208201526117b060408401611715565b60408201526117c160608401611701565b60608201526117d260808401611701565b608082015260a08301356fffffffffffffffffffffffffffffffff811681146117fa57600080fd5b60a0919091015292915050565b6000806000806000806000806000808a8c0361028081121561182857600080fd5b6118318c61164e565b9a5060208c0135995060408c0135985060608c0135975061185460808d01611699565b965061186260a08d0161164e565b95506118718d60c08e01611726565b94506101808c013593506118886101a08d0161164e565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe40820112156118ba57600080fd5b506118c36116b1565b6118d06101c08d0161164e565b81526118df6101e08d0161164e565b60208201526118f16102008d0161164e565b60408201526119036102208d0161164e565b60608201526119156102408d0161164e565b60808201526119276102608d0161164e565b60a0820152809150509295989b9194979a5092959850565b6000815180845260005b8181101561196557602081850181015186830182015201611949565b81811115611977576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611692602083018461193f565b600080604083850312156119d057600080fd5b50508035926020909101359150565b6000602082840312156119f157600080fd5b61169282611699565b600060c08284031215611a0c57600080fd5b6116928383611726565b600060208284031215611a2857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611a7057611a70611a2f565b500390565b600067ffffffffffffffff808316818516808303821115611a9857611a98611a2f565b01949350505050565b600063ffffffff808316818516808303821115611a9857611a98611a2f565b600063ffffffff80841680611afe577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611b2d57611b2d611a2f565b0294935050505056fea164736f6c634300080f000a53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77001d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"BATCH_INBOX_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L1_CROSS_DOMAIN_MESSENGER_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L1_ERC_721_BRIDGE_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L1_STANDARD_BRIDGE_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L2_OUTPUT_ORACLE_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OPTIMISM_PORTAL_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"START_BLOCK_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UNSAFE_BLOCK_SIGNER_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"batchInbox\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"batcherHash\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasLimit\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_overhead\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_scalar\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_batcherHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_gasLimit\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_unsafeBlockSigner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_config\",\"type\":\"tuple\",\"internalType\":\"structResourceMetering.ResourceConfig\",\"components\":[{\"name\":\"maxResourceLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"elasticityMultiplier\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"minimumBaseFee\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"systemTxMaxGas\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"maximumBaseFee\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]},{\"name\":\"_batchInbox\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_addresses\",\"type\":\"tuple\",\"internalType\":\"structSystemConfig.Addresses\",\"components\":[{\"name\":\"l1CrossDomainMessenger\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1ERC721Bridge\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1StandardBridge\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l2OutputOracle\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismPortal\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismMintableERC20Factory\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l1CrossDomainMessenger\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1ERC721Bridge\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1StandardBridge\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l2OutputOracle\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"minimumGasLimit\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"optimismMintableERC20Factory\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"optimismPortal\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"overhead\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resourceConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structResourceMetering.ResourceConfig\",\"components\":[{\"name\":\"maxResourceLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"elasticityMultiplier\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"minimumBaseFee\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"systemTxMaxGas\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"maximumBaseFee\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"scalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setBatcherHash\",\"inputs\":[{\"name\":\"_batcherHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setGasConfig\",\"inputs\":[{\"name\":\"_overhead\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_scalar\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setGasLimit\",\"inputs\":[{\"name\":\"_gasLimit\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setResourceConfig\",\"inputs\":[{\"name\":\"_config\",\"type\":\"tuple\",\"internalType\":\"structResourceMetering.ResourceConfig\",\"components\":[{\"name\":\"maxResourceLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"elasticityMultiplier\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"minimumBaseFee\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"systemTxMaxGas\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"maximumBaseFee\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setUnsafeBlockSigner\",\"inputs\":[{\"name\":\"_unsafeBlockSigner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startBlock\",\"inputs\":[],\"outputs\":[{\"name\":\"startBlock_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unsafeBlockSigner\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"ConfigUpdate\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumSystemConfig.UpdateType\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", + Bin: "0x60806040523480156200001157600080fd5b506200004962000032600160008051602062002a4783398151915262000c39565b60001b600019620000c960201b62000e061760201c565b6040805160c080820183526001808352602080840182905260028486015260006060808601829052608080870183905260a08088018490528851968701895283875293860183905296850182905284018190529483018590528201849052620000c39361dead9390928392839290918391908290620000cd565b62000d5c565b9055565b600054610100900460ff1615808015620000ee5750600054600160ff909116105b806200011e57506200010b30620004df60201b62000e0a1760201c565b1580156200011e575060005460ff166001145b620001875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015620001ab576000805461ff0019166101001790555b620001b5620004ee565b620001c08a62000556565b620001cb87620005d5565b620001d7898962000627565b620001e2866200068b565b620002197f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0886620000c960201b62000e061760201c565b6200025f6200024a60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59862000c39565b60001b84620000c960201b62000e061760201c565b620002a96200029060017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063762000c39565b60001b8360000151620000c960201b62000e061760201c565b620002f3620002da60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a862000c39565b60001b8360200151620000c960201b62000e061760201c565b6200033d6200032460017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637762000c39565b60001b8360400151620000c960201b62000e061760201c565b620003876200036e60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a687181662000c39565b60001b8360600151620000c960201b62000e061760201c565b620003d1620003b860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad62000c39565b60001b8360800151620000c960201b62000e061760201c565b6200041b6200040260017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d62000c39565b60001b8360a00151620000c960201b62000e061760201c565b6200042562000728565b620004308462000799565b6200043a62000add565b6001600160401b0316866001600160401b031610156200048c5760405162461bcd60e51b815260206004820152601f6024820152600080516020620029e783398151915260448201526064016200017e565b8015620004d3576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b6001600160a01b03163b151590565b600054610100900460ff166200054a5760405162461bcd60e51b815260206004820152602b602482015260008051602062002a2783398151915260448201526a6e697469616c697a696e6760a81b60648201526084016200017e565b6200055462000b0a565b565b6200056062000b71565b6001600160a01b038116620005c75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016200017e565b620005d28162000bcd565b50565b60678190556040805160208082018490528251808303909101815290820190915260005b600060008051602062002a07833981519152836040516200061b919062000c53565b60405180910390a35050565b60658290556066819055604080516020810184905290810182905260009060600160408051601f1981840301815291905290506001600060008051602062002a07833981519152836040516200067e919062000c53565b60405180910390a3505050565b6200069562000add565b6001600160401b0316816001600160401b03161015620006e75760405162461bcd60e51b815260206004820152601f6024820152600080516020620029e783398151915260448201526064016200017e565b606880546001600160401b0319166001600160401b0383169081179091556040805160208082019390935281518082039093018352810190526002620005f9565b6200075c62000748600160008051602062002a4783398151915262000c39565b60001b62000c1f60201b62000e261760201c565b60000362000554576200055462000784600160008051602062002a4783398151915262000c39565b60001b43620000c960201b62000e061760201c565b8060a001516001600160801b0316816060015163ffffffff161115620008285760405162461bcd60e51b815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d61782062617365000000000000000000000060648201526084016200017e565b6001816040015160ff1611620008995760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201526e65206c6172676572207468616e203160881b60648201526084016200017e565b606854608082015182516001600160401b0390921691620008bb919062000cab565b63ffffffff161115620009005760405162461bcd60e51b815260206004820152601f6024820152600080516020620029e783398151915260448201526064016200017e565b6000816020015160ff1611620009715760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201526e06965722063616e6e6f74206265203608c1b60648201526084016200017e565b8051602082015163ffffffff82169160ff909116906200099390829062000cd6565b6200099f919062000d08565b63ffffffff161462000a1a5760405162461bcd60e51b815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d697400000000000000000060648201526084016200017e565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff96871664ffffffffff199095169490941764010000000060ff948516021764ffffffffff60281b191665010000000000939092169290920263ffffffff60301b19161766010000000000009185169190910217600160501b600160f01b0319166a01000000000000000000009390941692909202600160701b600160f01b03191692909217600160701b6001600160801b0390921691909102179055565b60695460009062000b059063ffffffff6a010000000000000000000082048116911662000d37565b905090565b600054610100900460ff1662000b665760405162461bcd60e51b815260206004820152602b602482015260008051602062002a2783398151915260448201526a6e697469616c697a696e6760a81b60648201526084016200017e565b620005543362000bcd565b6033546001600160a01b03163314620005545760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200017e565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b5490565b634e487b7160e01b600052601160045260246000fd5b60008282101562000c4e5762000c4e62000c23565b500390565b600060208083528351808285015260005b8181101562000c825785810183015185820160400152820162000c64565b8181111562000c95576000604083870101525b50601f01601f1916929092016040019392505050565b600063ffffffff80831681851680830382111562000ccd5762000ccd62000c23565b01949350505050565b600063ffffffff8084168062000cfc57634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b600063ffffffff8083168185168183048111821515161562000d2e5762000d2e62000c23565b02949350505050565b60006001600160401b0382811684821680830382111562000ccd5762000ccd62000c23565b611c7b8062000d6c6000396000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c8063935f029e11610145578063dac6e63a116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610597578063fd32aa0f1461059f578063ffa1ad74146105a757600080fd5b8063f45e65d81461057a578063f68016b71461058357600080fd5b8063dac6e63a1461054e578063e0e2016d14610556578063e81b2c6d1461055e578063f2fde38b1461056757600080fd5b8063bc49ce5f11610114578063c71973f6116100f9578063c71973f6146103f4578063c9b26f6114610407578063cc731b021461041a57600080fd5b8063bc49ce5f146103e4578063c4e8ddfa146103ec57600080fd5b8063935f029e146103ae5780639b7d7f0a146103c1578063a7119869146103c9578063b40a817c146103d157600080fd5b806348cd4cb1116101d857806354fd4d50116101a757806361d157681161018c57806361d1576814610380578063715018a6146103885780638da5cb5b1461039057600080fd5b806354fd4d501461032f5780635d73369c1461037857600080fd5b806348cd4cb1146102d75780634add321d146102df5780634d9f1559146103005780634f16540b1461030857600080fd5b80630c18c162116102145780630c18c162146102ab57806318d13918146102b457806319f5cea8146102c75780631fd19ee1146102cf57600080fd5b806306c9265714610246578063078f29cf146102615780630a49cb031461028e5780630bbb796814610296575b600080fd5b61024e6105af565b6040519081526020015b60405180910390f35b6102696105dd565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610258565b610269610616565b6102a96102a4366004611928565b610646565b005b61024e60655481565b6102a96102c2366004611a55565b610a44565b61024e610a58565b610269610a83565b61024e610aad565b6102e7610add565b60405167ffffffffffffffff9091168152602001610258565b610269610b03565b61024e7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b61036b6040518060400160405280600681526020017f312e31322e30000000000000000000000000000000000000000000000000000081525081565b6040516102589190611ae2565b61024e610b33565b61024e610b5e565b6102a9610b89565b60335473ffffffffffffffffffffffffffffffffffffffff16610269565b6102a96103bc366004611af5565b610b9d565b610269610bb3565b610269610be3565b6102a96103df366004611b17565b610c13565b61024e610c24565b610269610c4f565b6102a9610402366004611b32565b610c7f565b6102a9610415366004611b4e565b610c90565b6104de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102589190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b610269610ca1565b61024e610cd1565b61024e60675481565b6102a9610575366004611a55565b610cfc565b61024e60665481565b6068546102e79067ffffffffffffffff1681565b61024e610db0565b61024e610ddb565b61024e600081565b6105da60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b81565b600061061161060d60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b5490565b905090565b600061061161060d60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b600054610100900460ff16158080156106665750600054600160ff909116105b806106805750303b158015610680575060005460ff166001145b610711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561076f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610777610e2a565b6107808a610cfc565b61078987610ec9565b6107938989610f2a565b61079c86610fbb565b6107c57f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b6107f86107f360017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b849055565b61082c61082660017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b83519055565b61086361085a60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b60208401519055565b61089a61089160017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b60408401519055565b6108d16108c860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b60608401519055565b6109086108ff60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b60808401519055565b61093f61093660017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b60a08401519055565b610947611099565b61095084611101565b610958610add565b67ffffffffffffffff168667ffffffffffffffff1610156109d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b8015610a3857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b610a4c611575565b610a55816115f6565b50565b6105da60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b60006106117f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b600061061161060d60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b6069546000906106119063ffffffff6a0100000000000000000000820481169116611bad565b600061061161060d60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b6105da60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b6105da60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b610b91611575565b610b9b600061167a565b565b610ba5611575565b610baf8282610f2a565b5050565b600061061161060d60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b600061061161060d60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b610c1b611575565b610a5581610fbb565b6105da60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b600061061161060d60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b610c87611575565b610a5581611101565b610c98611575565b610a5581610ec9565b600061061161060d60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b6105da60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b610d04611575565b73ffffffffffffffffffffffffffffffffffffffff8116610da7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610708565b610a558161167a565b6105da60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b6105da60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b5490565b600054610100900460ff16610ec1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610708565b610b9b6116f1565b60678190556040805160208082018490528251808303909101815290820190915260005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610f1e9190611ae2565b60405180910390a35050565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae9190611ae2565b60405180910390a3505050565b610fc3610add565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610eed565b6110c761060d60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b600003610b9b57610b9b6110fc60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b439055565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff1611156111b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610708565b6001816040015160ff1611611248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610708565b6068546080820151825167ffffffffffffffff909216916112699190611bd9565b63ffffffff1611156112d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b6000816020015160ff161161136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610708565b8051602082015163ffffffff82169160ff9091169061138e908290611bf8565b6113989190611c42565b63ffffffff161461142b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610708565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610b9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610708565b61161f7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290506003610eed565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610708565b610b9b3361167a565b803573ffffffffffffffffffffffffffffffffffffffff811681146117b557600080fd5b919050565b803567ffffffffffffffff811681146117b557600080fd5b60405160c0810167ffffffffffffffff8111828210171561181c577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff811681146117b557600080fd5b803560ff811681146117b557600080fd5b600060c0828403121561185957600080fd5b60405160c0810181811067ffffffffffffffff821117156118a3577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050806118b283611822565b81526118c060208401611836565b60208201526118d160408401611836565b60408201526118e260608401611822565b60608201526118f360808401611822565b608082015260a08301356fffffffffffffffffffffffffffffffff8116811461191b57600080fd5b60a0919091015292915050565b6000806000806000806000806000898b0361026081121561194857600080fd5b6119518b611791565b995060208b0135985060408b0135975060608b0135965061197460808c016117ba565b955061198260a08c01611791565b94506119918c60c08d01611847565b93506119a06101808c01611791565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60820112156119d257600080fd5b506119db6117d2565b6119e86101a08c01611791565b81526119f76101c08c01611791565b6020820152611a096101e08c01611791565b6040820152611a1b6102008c01611791565b6060820152611a2d6102208c01611791565b6080820152611a3f6102408c01611791565b60a0820152809150509295985092959850929598565b600060208284031215611a6757600080fd5b611a7082611791565b9392505050565b6000815180845260005b81811015611a9d57602081850181015186830182015201611a81565b81811115611aaf576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611a706020830184611a77565b60008060408385031215611b0857600080fd5b50508035926020909101359150565b600060208284031215611b2957600080fd5b611a70826117ba565b600060c08284031215611b4457600080fd5b611a708383611847565b600060208284031215611b6057600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611ba857611ba8611b67565b500390565b600067ffffffffffffffff808316818516808303821115611bd057611bd0611b67565b01949350505050565b600063ffffffff808316818516808303821115611bd057611bd0611b67565b600063ffffffff80841680611c36577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611c6557611c65611b67565b0294935050505056fea164736f6c634300080f000a53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77001d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069a11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0", } // SystemConfigABI is the input ABI used to generate the binding from. @@ -438,6 +438,37 @@ func (_SystemConfig *SystemConfigCallerSession) OPTIMISMPORTALSLOT() ([32]byte, return _SystemConfig.Contract.OPTIMISMPORTALSLOT(&_SystemConfig.CallOpts) } +// STARTBLOCKSLOT is a free data retrieval call binding the contract method 0xe0e2016d. +// +// Solidity: function START_BLOCK_SLOT() view returns(bytes32) +func (_SystemConfig *SystemConfigCaller) STARTBLOCKSLOT(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _SystemConfig.contract.Call(opts, &out, "START_BLOCK_SLOT") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// STARTBLOCKSLOT is a free data retrieval call binding the contract method 0xe0e2016d. +// +// Solidity: function START_BLOCK_SLOT() view returns(bytes32) +func (_SystemConfig *SystemConfigSession) STARTBLOCKSLOT() ([32]byte, error) { + return _SystemConfig.Contract.STARTBLOCKSLOT(&_SystemConfig.CallOpts) +} + +// STARTBLOCKSLOT is a free data retrieval call binding the contract method 0xe0e2016d. +// +// Solidity: function START_BLOCK_SLOT() view returns(bytes32) +func (_SystemConfig *SystemConfigCallerSession) STARTBLOCKSLOT() ([32]byte, error) { + return _SystemConfig.Contract.STARTBLOCKSLOT(&_SystemConfig.CallOpts) +} + // UNSAFEBLOCKSIGNERSLOT is a free data retrieval call binding the contract method 0x4f16540b. // // Solidity: function UNSAFE_BLOCK_SIGNER_SLOT() view returns(bytes32) @@ -936,7 +967,7 @@ func (_SystemConfig *SystemConfigCallerSession) Scalar() (*big.Int, error) { // StartBlock is a free data retrieval call binding the contract method 0x48cd4cb1. // -// Solidity: function startBlock() view returns(uint256) +// Solidity: function startBlock() view returns(uint256 startBlock_) func (_SystemConfig *SystemConfigCaller) StartBlock(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} err := _SystemConfig.contract.Call(opts, &out, "startBlock") @@ -953,14 +984,14 @@ func (_SystemConfig *SystemConfigCaller) StartBlock(opts *bind.CallOpts) (*big.I // StartBlock is a free data retrieval call binding the contract method 0x48cd4cb1. // -// Solidity: function startBlock() view returns(uint256) +// Solidity: function startBlock() view returns(uint256 startBlock_) func (_SystemConfig *SystemConfigSession) StartBlock() (*big.Int, error) { return _SystemConfig.Contract.StartBlock(&_SystemConfig.CallOpts) } // StartBlock is a free data retrieval call binding the contract method 0x48cd4cb1. // -// Solidity: function startBlock() view returns(uint256) +// Solidity: function startBlock() view returns(uint256 startBlock_) func (_SystemConfig *SystemConfigCallerSession) StartBlock() (*big.Int, error) { return _SystemConfig.Contract.StartBlock(&_SystemConfig.CallOpts) } @@ -1027,25 +1058,25 @@ func (_SystemConfig *SystemConfigCallerSession) Version() (string, error) { return _SystemConfig.Contract.Version(&_SystemConfig.CallOpts) } -// Initialize is a paid mutator transaction binding the contract method 0x5228a6ac. +// Initialize is a paid mutator transaction binding the contract method 0x0bbb7968. // -// Solidity: function initialize(address _owner, uint256 _overhead, uint256 _scalar, bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, (uint32,uint8,uint8,uint32,uint32,uint128) _config, uint256 _startBlock, address _batchInbox, (address,address,address,address,address,address) _addresses) returns() -func (_SystemConfig *SystemConfigTransactor) Initialize(opts *bind.TransactOpts, _owner common.Address, _overhead *big.Int, _scalar *big.Int, _batcherHash [32]byte, _gasLimit uint64, _unsafeBlockSigner common.Address, _config ResourceMeteringResourceConfig, _startBlock *big.Int, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) { - return _SystemConfig.contract.Transact(opts, "initialize", _owner, _overhead, _scalar, _batcherHash, _gasLimit, _unsafeBlockSigner, _config, _startBlock, _batchInbox, _addresses) +// Solidity: function initialize(address _owner, uint256 _overhead, uint256 _scalar, bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, (uint32,uint8,uint8,uint32,uint32,uint128) _config, address _batchInbox, (address,address,address,address,address,address) _addresses) returns() +func (_SystemConfig *SystemConfigTransactor) Initialize(opts *bind.TransactOpts, _owner common.Address, _overhead *big.Int, _scalar *big.Int, _batcherHash [32]byte, _gasLimit uint64, _unsafeBlockSigner common.Address, _config ResourceMeteringResourceConfig, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) { + return _SystemConfig.contract.Transact(opts, "initialize", _owner, _overhead, _scalar, _batcherHash, _gasLimit, _unsafeBlockSigner, _config, _batchInbox, _addresses) } -// Initialize is a paid mutator transaction binding the contract method 0x5228a6ac. +// Initialize is a paid mutator transaction binding the contract method 0x0bbb7968. // -// Solidity: function initialize(address _owner, uint256 _overhead, uint256 _scalar, bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, (uint32,uint8,uint8,uint32,uint32,uint128) _config, uint256 _startBlock, address _batchInbox, (address,address,address,address,address,address) _addresses) returns() -func (_SystemConfig *SystemConfigSession) Initialize(_owner common.Address, _overhead *big.Int, _scalar *big.Int, _batcherHash [32]byte, _gasLimit uint64, _unsafeBlockSigner common.Address, _config ResourceMeteringResourceConfig, _startBlock *big.Int, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) { - return _SystemConfig.Contract.Initialize(&_SystemConfig.TransactOpts, _owner, _overhead, _scalar, _batcherHash, _gasLimit, _unsafeBlockSigner, _config, _startBlock, _batchInbox, _addresses) +// Solidity: function initialize(address _owner, uint256 _overhead, uint256 _scalar, bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, (uint32,uint8,uint8,uint32,uint32,uint128) _config, address _batchInbox, (address,address,address,address,address,address) _addresses) returns() +func (_SystemConfig *SystemConfigSession) Initialize(_owner common.Address, _overhead *big.Int, _scalar *big.Int, _batcherHash [32]byte, _gasLimit uint64, _unsafeBlockSigner common.Address, _config ResourceMeteringResourceConfig, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) { + return _SystemConfig.Contract.Initialize(&_SystemConfig.TransactOpts, _owner, _overhead, _scalar, _batcherHash, _gasLimit, _unsafeBlockSigner, _config, _batchInbox, _addresses) } -// Initialize is a paid mutator transaction binding the contract method 0x5228a6ac. +// Initialize is a paid mutator transaction binding the contract method 0x0bbb7968. // -// Solidity: function initialize(address _owner, uint256 _overhead, uint256 _scalar, bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, (uint32,uint8,uint8,uint32,uint32,uint128) _config, uint256 _startBlock, address _batchInbox, (address,address,address,address,address,address) _addresses) returns() -func (_SystemConfig *SystemConfigTransactorSession) Initialize(_owner common.Address, _overhead *big.Int, _scalar *big.Int, _batcherHash [32]byte, _gasLimit uint64, _unsafeBlockSigner common.Address, _config ResourceMeteringResourceConfig, _startBlock *big.Int, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) { - return _SystemConfig.Contract.Initialize(&_SystemConfig.TransactOpts, _owner, _overhead, _scalar, _batcherHash, _gasLimit, _unsafeBlockSigner, _config, _startBlock, _batchInbox, _addresses) +// Solidity: function initialize(address _owner, uint256 _overhead, uint256 _scalar, bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, (uint32,uint8,uint8,uint32,uint32,uint128) _config, address _batchInbox, (address,address,address,address,address,address) _addresses) returns() +func (_SystemConfig *SystemConfigTransactorSession) Initialize(_owner common.Address, _overhead *big.Int, _scalar *big.Int, _batcherHash [32]byte, _gasLimit uint64, _unsafeBlockSigner common.Address, _config ResourceMeteringResourceConfig, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) { + return _SystemConfig.Contract.Initialize(&_SystemConfig.TransactOpts, _owner, _overhead, _scalar, _batcherHash, _gasLimit, _unsafeBlockSigner, _config, _batchInbox, _addresses) } // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. diff --git a/op-bindings/bindings/systemconfig_more.go b/op-bindings/bindings/systemconfig_more.go index 994e2ef69a26..1e0d4de714d5 100644 --- a/op-bindings/bindings/systemconfig_more.go +++ b/op-bindings/bindings/systemconfig_more.go @@ -9,11 +9,12 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const SystemConfigStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1003,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1005,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"overhead\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_uint256\"},{\"astId\":1006,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"scalar\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_uint256\"},{\"astId\":1007,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"batcherHash\",\"offset\":0,\"slot\":\"103\",\"type\":\"t_bytes32\"},{\"astId\":1008,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"gasLimit\",\"offset\":0,\"slot\":\"104\",\"type\":\"t_uint64\"},{\"astId\":1009,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"_resourceConfig\",\"offset\":0,\"slot\":\"105\",\"type\":\"t_struct(ResourceConfig)1011_storage\"},{\"astId\":1010,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"startBlock\",\"offset\":0,\"slot\":\"106\",\"type\":\"t_uint256\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_struct(ResourceConfig)1011_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ResourceMetering.ResourceConfig\",\"numberOfBytes\":\"32\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" +const SystemConfigStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1003,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":1005,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"overhead\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_uint256\"},{\"astId\":1006,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"scalar\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_uint256\"},{\"astId\":1007,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"batcherHash\",\"offset\":0,\"slot\":\"103\",\"type\":\"t_bytes32\"},{\"astId\":1008,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"gasLimit\",\"offset\":0,\"slot\":\"104\",\"type\":\"t_uint64\"},{\"astId\":1009,\"contract\":\"src/L1/SystemConfig.sol:SystemConfig\",\"label\":\"_resourceConfig\",\"offset\":0,\"slot\":\"105\",\"type\":\"t_struct(ResourceConfig)1010_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_struct(ResourceConfig)1010_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ResourceMetering.ResourceConfig\",\"numberOfBytes\":\"32\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" var SystemConfigStorageLayout = new(solc.StorageLayout) -var SystemConfigDeployedBin = "0x608060405234801561001057600080fd5b50600436106102265760003560e01c8063935f029e1161012a578063cc731b02116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610575578063fd32aa0f1461057d578063ffa1ad741461058557600080fd5b8063f45e65d814610558578063f68016b71461056157600080fd5b8063cc731b0214610400578063dac6e63a14610534578063e81b2c6d1461053c578063f2fde38b1461054557600080fd5b8063bc49ce5f116100f9578063bc49ce5f146103ca578063c4e8ddfa146103d2578063c71973f6146103da578063c9b26f61146103ed57600080fd5b8063935f029e146103945780639b7d7f0a146103a7578063a7119869146103af578063b40a817c146103b757600080fd5b80634add321d116101bd57806354fd4d501161018c57806361d157681161017157806361d1576814610366578063715018a61461036e5780638da5cb5b1461037657600080fd5b806354fd4d50146103155780635d73369c1461035e57600080fd5b80634add321d146102b25780634d9f1559146102d35780634f16540b146102db5780635228a6ac1461030257600080fd5b806318d13918116101f957806318d139181461028457806319f5cea8146102995780631fd19ee1146102a157806348cd4cb1146102a957600080fd5b806306c926571461022b578063078f29cf146102465780630a49cb03146102735780630c18c1621461027b575b600080fd5b61023361058d565b6040519081526020015b60405180910390f35b61024e6105bb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023d565b61024e6105f4565b61023360655481565b610297610292366004611677565b610624565b005b610233610638565b61024e610663565b610233606a5481565b6102ba61068d565b60405167ffffffffffffffff909116815260200161023d565b61024e6106b3565b6102337f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b610297610310366004611807565b6106e3565b6103516040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b60405161023d91906119aa565b610233610a79565b610233610aa4565b610297610acf565b60335473ffffffffffffffffffffffffffffffffffffffff1661024e565b6102976103a23660046119bd565b610ae3565b61024e610af9565b61024e610b29565b6102976103c53660046119df565b610b59565b610233610b6a565b61024e610b95565b6102976103e83660046119fa565b610bc5565b6102976103fb366004611a16565b610bd6565b6104c46040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b60405161023d9190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61024e610be7565b61023360675481565b610297610553366004611677565b610c17565b61023360665481565b6068546102ba9067ffffffffffffffff1681565b610233610ccb565b610233610cf6565b610233600081565b6105b860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b81565b60006105ef6105eb60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b5490565b905090565b60006105ef6105eb60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b61062c610d25565b61063581610da6565b50565b6105b860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60006105ef7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b6069546000906105ef9063ffffffff6a0100000000000000000000820481169116611a75565b60006105ef6105eb60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b600054600390610100900460ff16158015610705575060005460ff8083169116105b610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556107cf610e63565b6107d88b610c17565b6107e188610f02565b6107eb8a8a610f2a565b6107f487610fbb565b6107fd86610da6565b61083061082b60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b849055565b61086461085e60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b83519055565b61089b61089260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60208401519055565b6108d26108c960017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b60408401519055565b61090961090060017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b60608401519055565b61094061093760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b60808401519055565b61097761096e60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60a08401519055565b61098084611099565b610989856110c3565b61099161068d565b67ffffffffffffffff168767ffffffffffffffff161015610a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b6105b860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b6105b860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b610ad7610d25565b610ae16000611537565b565b610aeb610d25565b610af58282610f2a565b5050565b60006105ef6105eb60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60006105ef6105eb60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b610b61610d25565b61063581610fbb565b6105b860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b60006105ef6105eb60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b610bcd610d25565b610635816110c3565b610bde610d25565b61063581610f02565b60006105ef6105eb60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b610c1f610d25565b73ffffffffffffffffffffffffffffffffffffffff8116610cc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161078d565b61063581611537565b6105b860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b6105b860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161078d565b610dcf7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610e5791906119aa565b60405180910390a35050565b600054610100900460ff16610efa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae16115ae565b6067819055604080516020808201849052825180830390910181529082019091526000610e26565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae91906119aa565b60405180910390a3505050565b610fc361068d565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610e26565b80158015906110a85750606a54155b156110b257606a55565b606a546000036106355743606a5550565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611173576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840161078d565b6001816040015160ff161161120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e20310000000000000000000000000000000000606482015260840161078d565b6068546080820151825167ffffffffffffffff9092169161122b9190611aa1565b63ffffffff161115611299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b6000816020015160ff1611611330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f7420626520300000000000000000000000000000000000606482015260840161078d565b8051602082015163ffffffff82169160ff90911690611350908290611ac0565b61135a9190611b0a565b63ffffffff16146113ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840161078d565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae133611537565b803573ffffffffffffffffffffffffffffffffffffffff8116811461167257600080fd5b919050565b60006020828403121561168957600080fd5b6116928261164e565b9392505050565b803567ffffffffffffffff8116811461167257600080fd5b60405160c0810167ffffffffffffffff811182821017156116fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff8116811461167257600080fd5b803560ff8116811461167257600080fd5b600060c0828403121561173857600080fd5b60405160c0810181811067ffffffffffffffff82111715611782577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061179183611701565b815261179f60208401611715565b60208201526117b060408401611715565b60408201526117c160608401611701565b60608201526117d260808401611701565b608082015260a08301356fffffffffffffffffffffffffffffffff811681146117fa57600080fd5b60a0919091015292915050565b6000806000806000806000806000808a8c0361028081121561182857600080fd5b6118318c61164e565b9a5060208c0135995060408c0135985060608c0135975061185460808d01611699565b965061186260a08d0161164e565b95506118718d60c08e01611726565b94506101808c013593506118886101a08d0161164e565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe40820112156118ba57600080fd5b506118c36116b1565b6118d06101c08d0161164e565b81526118df6101e08d0161164e565b60208201526118f16102008d0161164e565b60408201526119036102208d0161164e565b60608201526119156102408d0161164e565b60808201526119276102608d0161164e565b60a0820152809150509295989b9194979a5092959850565b6000815180845260005b8181101561196557602081850181015186830182015201611949565b81811115611977576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611692602083018461193f565b600080604083850312156119d057600080fd5b50508035926020909101359150565b6000602082840312156119f157600080fd5b61169282611699565b600060c08284031215611a0c57600080fd5b6116928383611726565b600060208284031215611a2857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611a7057611a70611a2f565b500390565b600067ffffffffffffffff808316818516808303821115611a9857611a98611a2f565b01949350505050565b600063ffffffff808316818516808303821115611a9857611a98611a2f565b600063ffffffff80841680611afe577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611b2d57611b2d611a2f565b0294935050505056fea164736f6c634300080f000a" +var SystemConfigDeployedBin = "0x608060405234801561001057600080fd5b50600436106102415760003560e01c8063935f029e11610145578063dac6e63a116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610597578063fd32aa0f1461059f578063ffa1ad74146105a757600080fd5b8063f45e65d81461057a578063f68016b71461058357600080fd5b8063dac6e63a1461054e578063e0e2016d14610556578063e81b2c6d1461055e578063f2fde38b1461056757600080fd5b8063bc49ce5f11610114578063c71973f6116100f9578063c71973f6146103f4578063c9b26f6114610407578063cc731b021461041a57600080fd5b8063bc49ce5f146103e4578063c4e8ddfa146103ec57600080fd5b8063935f029e146103ae5780639b7d7f0a146103c1578063a7119869146103c9578063b40a817c146103d157600080fd5b806348cd4cb1116101d857806354fd4d50116101a757806361d157681161018c57806361d1576814610380578063715018a6146103885780638da5cb5b1461039057600080fd5b806354fd4d501461032f5780635d73369c1461037857600080fd5b806348cd4cb1146102d75780634add321d146102df5780634d9f1559146103005780634f16540b1461030857600080fd5b80630c18c162116102145780630c18c162146102ab57806318d13918146102b457806319f5cea8146102c75780631fd19ee1146102cf57600080fd5b806306c9265714610246578063078f29cf146102615780630a49cb031461028e5780630bbb796814610296575b600080fd5b61024e6105af565b6040519081526020015b60405180910390f35b6102696105dd565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610258565b610269610616565b6102a96102a4366004611928565b610646565b005b61024e60655481565b6102a96102c2366004611a55565b610a44565b61024e610a58565b610269610a83565b61024e610aad565b6102e7610add565b60405167ffffffffffffffff9091168152602001610258565b610269610b03565b61024e7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b61036b6040518060400160405280600681526020017f312e31322e30000000000000000000000000000000000000000000000000000081525081565b6040516102589190611ae2565b61024e610b33565b61024e610b5e565b6102a9610b89565b60335473ffffffffffffffffffffffffffffffffffffffff16610269565b6102a96103bc366004611af5565b610b9d565b610269610bb3565b610269610be3565b6102a96103df366004611b17565b610c13565b61024e610c24565b610269610c4f565b6102a9610402366004611b32565b610c7f565b6102a9610415366004611b4e565b610c90565b6104de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102589190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b610269610ca1565b61024e610cd1565b61024e60675481565b6102a9610575366004611a55565b610cfc565b61024e60665481565b6068546102e79067ffffffffffffffff1681565b61024e610db0565b61024e610ddb565b61024e600081565b6105da60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b81565b600061061161060d60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b5490565b905090565b600061061161060d60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b600054610100900460ff16158080156106665750600054600160ff909116105b806106805750303b158015610680575060005460ff166001145b610711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561076f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610777610e2a565b6107808a610cfc565b61078987610ec9565b6107938989610f2a565b61079c86610fbb565b6107c57f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b6107f86107f360017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b849055565b61082c61082660017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b83519055565b61086361085a60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b60208401519055565b61089a61089160017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b60408401519055565b6108d16108c860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b60608401519055565b6109086108ff60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b60808401519055565b61093f61093660017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b60a08401519055565b610947611099565b61095084611101565b610958610add565b67ffffffffffffffff168667ffffffffffffffff1610156109d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b8015610a3857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b610a4c611575565b610a55816115f6565b50565b6105da60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b60006106117f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b600061061161060d60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b6069546000906106119063ffffffff6a0100000000000000000000820481169116611bad565b600061061161060d60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b6105da60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b6105da60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b610b91611575565b610b9b600061167a565b565b610ba5611575565b610baf8282610f2a565b5050565b600061061161060d60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b600061061161060d60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b610c1b611575565b610a5581610fbb565b6105da60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b600061061161060d60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b610c87611575565b610a5581611101565b610c98611575565b610a5581610ec9565b600061061161060d60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b6105da60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b610d04611575565b73ffffffffffffffffffffffffffffffffffffffff8116610da7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610708565b610a558161167a565b6105da60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b6105da60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b5490565b600054610100900460ff16610ec1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610708565b610b9b6116f1565b60678190556040805160208082018490528251808303909101815290820190915260005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610f1e9190611ae2565b60405180910390a35050565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae9190611ae2565b60405180910390a3505050565b610fc3610add565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610eed565b6110c761060d60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b600003610b9b57610b9b6110fc60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b439055565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff1611156111b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610708565b6001816040015160ff1611611248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610708565b6068546080820151825167ffffffffffffffff909216916112699190611bd9565b63ffffffff1611156112d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b6000816020015160ff161161136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610708565b8051602082015163ffffffff82169160ff9091169061138e908290611bf8565b6113989190611c42565b63ffffffff161461142b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610708565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610b9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610708565b61161f7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290506003610eed565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610708565b610b9b3361167a565b803573ffffffffffffffffffffffffffffffffffffffff811681146117b557600080fd5b919050565b803567ffffffffffffffff811681146117b557600080fd5b60405160c0810167ffffffffffffffff8111828210171561181c577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff811681146117b557600080fd5b803560ff811681146117b557600080fd5b600060c0828403121561185957600080fd5b60405160c0810181811067ffffffffffffffff821117156118a3577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050806118b283611822565b81526118c060208401611836565b60208201526118d160408401611836565b60408201526118e260608401611822565b60608201526118f360808401611822565b608082015260a08301356fffffffffffffffffffffffffffffffff8116811461191b57600080fd5b60a0919091015292915050565b6000806000806000806000806000898b0361026081121561194857600080fd5b6119518b611791565b995060208b0135985060408b0135975060608b0135965061197460808c016117ba565b955061198260a08c01611791565b94506119918c60c08d01611847565b93506119a06101808c01611791565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60820112156119d257600080fd5b506119db6117d2565b6119e86101a08c01611791565b81526119f76101c08c01611791565b6020820152611a096101e08c01611791565b6040820152611a1b6102008c01611791565b6060820152611a2d6102208c01611791565b6080820152611a3f6102408c01611791565b60a0820152809150509295985092959850929598565b600060208284031215611a6757600080fd5b611a7082611791565b9392505050565b6000815180845260005b81811015611a9d57602081850181015186830182015201611a81565b81811115611aaf576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611a706020830184611a77565b60008060408385031215611b0857600080fd5b50508035926020909101359150565b600060208284031215611b2957600080fd5b611a70826117ba565b600060c08284031215611b4457600080fd5b611a708383611847565b600060208284031215611b6057600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611ba857611ba8611b67565b500390565b600067ffffffffffffffff808316818516808303821115611bd057611bd0611b67565b01949350505050565b600063ffffffff808316818516808303821115611bd057611bd0611b67565b600063ffffffff80841680611c36577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611c6557611c65611b67565b0294935050505056fea164736f6c634300080f000a" + func init() { if err := json.Unmarshal([]byte(SystemConfigStorageLayoutJSON), SystemConfigStorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["SystemConfig"] = SystemConfigStorageLayout deployedBytecodes["SystemConfig"] = SystemConfigDeployedBin + immutableReferences["SystemConfig"] = false } diff --git a/op-bindings/bindings/weth9.go b/op-bindings/bindings/weth9.go index b3e980e88b1d..179a58ffb5f4 100644 --- a/op-bindings/bindings/weth9.go +++ b/op-bindings/bindings/weth9.go @@ -30,8 +30,8 @@ var ( // WETH9MetaData contains all meta data concerning the WETH9 contract. var WETH9MetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158207b86b1da46ae4fe6bf82103d311d208fa14a840526450c8a035fc216470b364f64736f6c63430005110032", + ABI: "[{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"allowance\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"guy\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"decimals\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deposit\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalSupply\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transfer\",\"inputs\":[{\"name\":\"dst\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"src\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"dst\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[{\"name\":\"wad\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"src\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"guy\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Deposit\",\"inputs\":[{\"name\":\"dst\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"src\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"dst\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdrawal\",\"inputs\":[{\"name\":\"src\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"wad\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", + Bin: "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158208cdf9e0c522e49d36150a8c7a071369551180dfcf54934aa47b2d43732920e8e64736f6c63430005110032", } // WETH9ABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/weth9_more.go b/op-bindings/bindings/weth9_more.go index b4a95723776f..91efa104067d 100644 --- a/op-bindings/bindings/weth9_more.go +++ b/op-bindings/bindings/weth9_more.go @@ -13,7 +13,8 @@ const WETH9StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src var WETH9StorageLayout = new(solc.StorageLayout) -var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158207b86b1da46ae4fe6bf82103d311d208fa14a840526450c8a035fc216470b364f64736f6c63430005110032" +var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158208cdf9e0c522e49d36150a8c7a071369551180dfcf54934aa47b2d43732920e8e64736f6c63430005110032" + func init() { if err := json.Unmarshal([]byte(WETH9StorageLayoutJSON), WETH9StorageLayout); err != nil { @@ -22,4 +23,5 @@ func init() { layouts["WETH9"] = WETH9StorageLayout deployedBytecodes["WETH9"] = WETH9DeployedBin + immutableReferences["WETH9"] = false } diff --git a/op-bindings/bindingspreview/optimismportal2.go b/op-bindings/bindingspreview/optimismportal2.go new file mode 100644 index 000000000000..2afddfb9e1ea --- /dev/null +++ b/op-bindings/bindingspreview/optimismportal2.go @@ -0,0 +1,1612 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindingspreview + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// TypesOutputRootProof is an auto generated low-level Go binding around an user-defined struct. +type TypesOutputRootProof struct { + Version [32]byte + StateRoot [32]byte + MessagePasserStorageRoot [32]byte + LatestBlockhash [32]byte +} + +// TypesWithdrawalTransaction is an auto generated low-level Go binding around an user-defined struct. +type TypesWithdrawalTransaction struct { + Nonce *big.Int + Sender common.Address + Target common.Address + Value *big.Int + GasLimit *big.Int + Data []byte +} + +// OptimismPortal2MetaData contains all meta data concerning the OptimismPortal2 contract. +var OptimismPortal2MetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_proofMaturityDelaySeconds\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_disputeGameFinalityDelaySeconds\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_initialRespectedGameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"GUARDIAN\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"SYSTEM_CONFIG\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractSystemConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blacklistDisputeGame\",\"inputs\":[{\"name\":\"_disputeGame\",\"type\":\"address\",\"internalType\":\"contractIDisputeGame\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"checkWithdrawal\",\"inputs\":[{\"name\":\"_withdrawalHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"depositTransaction\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_gasLimit\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_isCreation\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"disputeGameBlacklist\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIDisputeGame\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"disputeGameFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractDisputeGameFactory\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"disputeGameFinalityDelaySeconds\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"donateETH\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"finalizeWithdrawalTransaction\",\"inputs\":[{\"name\":\"_tx\",\"type\":\"tuple\",\"internalType\":\"structTypes.WithdrawalTransaction\",\"components\":[{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"finalizedWithdrawals\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"guardian\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_disputeGameFactory\",\"type\":\"address\",\"internalType\":\"contractDisputeGameFactory\"},{\"name\":\"_systemConfig\",\"type\":\"address\",\"internalType\":\"contractSystemConfig\"},{\"name\":\"_superchainConfig\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l2Sender\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"minimumGasLimit\",\"inputs\":[{\"name\":\"_byteCount\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"params\",\"inputs\":[],\"outputs\":[{\"name\":\"prevBaseFee\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"prevBoughtGas\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"prevBlockNum\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proofMaturityDelaySeconds\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proveWithdrawalTransaction\",\"inputs\":[{\"name\":\"_tx\",\"type\":\"tuple\",\"internalType\":\"structTypes.WithdrawalTransaction\",\"components\":[{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"gasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"_disputeGameIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_outputRootProof\",\"type\":\"tuple\",\"internalType\":\"structTypes.OutputRootProof\",\"components\":[{\"name\":\"version\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stateRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"latestBlockhash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\",\"internalType\":\"bytes[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"provenWithdrawals\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"disputeGameProxy\",\"type\":\"address\",\"internalType\":\"contractIDisputeGame\"},{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"respectedGameType\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"GameType\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"respectedGameTypeUpdatedAt\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setRespectedGameType\",\"inputs\":[{\"name\":\"_gameType\",\"type\":\"uint32\",\"internalType\":\"GameType\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"superchainConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractSuperchainConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"systemConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractSystemConfig\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TransactionDeposited\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"opaqueData\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalFinalized\",\"inputs\":[{\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"success\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalProven\",\"inputs\":[{\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", + Bin: "0x60c06040523480156200001157600080fd5b5060405162005e7938038062005e798339810160408190526200003491620002d3565b608083905260a0829052603b805463ffffffff191663ffffffff831617905562000061600080806200006a565b50505062000317565b600054610100900460ff16158080156200008b5750600054600160ff909116105b80620000bb5750620000a8306200020560201b620022f11760201c565b158015620000bb575060005460ff166001145b620001245760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000148576000805461ff0019166101001790555b603880546001600160a01b03199081166001600160a01b03878116919091179092556037805490911685831617905560358054610100600160a81b0319166101008584160217905560325416620001ae57603280546001600160a01b03191661dead1790555b620001b862000214565b8015620001ff576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff16620002815760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016200011b565b600154600160c01b90046001600160401b0316600003620002d15760408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b02176001555b565b600080600060608486031215620002e957600080fd5b8351925060208401519150604084015163ffffffff811681146200030c57600080fd5b809150509250925092565b60805160a051615b2e6200034b6000396000818161045201526119ae01526000818161050c015261161f0152615b2e6000f3fe6080604052600436106101a55760003560e01c80638b4c40b0116100e1578063bf653a5c1161008a578063e965084c11610064578063e965084c146105f1578063e9e05c421461068d578063f0498750146106a0578063f2b4e617146106cb57600080fd5b8063bf653a5c146104fd578063c0c53b8b14610530578063cff0ab961461055057600080fd5b80639bf62d82116100bb5780639bf62d8214610480578063a14238e7146104ad578063a35d99df146104dd57600080fd5b80638b4c40b0146101ca5780638c3152e914610423578063952b27971461044357600080fd5b80634fd0434c1161014e578063724c184c11610128578063724c184c146103ae5780637af1906d146103c35780637d6be8dc146103e35780637fc485041461040357600080fd5b80634fd0434c1461030157806354fd4d50146103435780635c975abb1461039957600080fd5b8063452a93201161017f578063452a93201461028c57806345884d32146102a15780634870496f146102e157600080fd5b806333d7e2bd146101d157806335e80ab3146102285780633c9f397c1461025a57600080fd5b366101cc576101ca3334620186a06000604051806020016040528060008152506106f8565b005b600080fd5b3480156101dd57600080fd5b506037546101fe9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561023457600080fd5b506035546101fe90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561026657600080fd5b50603b546102779063ffffffff1681565b60405163ffffffff909116815260200161021f565b34801561029857600080fd5b506101fe610993565b3480156102ad57600080fd5b506102d16102bc366004614ecb565b603a6020526000908152604090205460ff1681565b604051901515815260200161021f565b3480156102ed57600080fd5b506101ca6102fc3660046150a3565b610a2b565b34801561030d57600080fd5b50603b5461032a90640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161021f565b34801561034f57600080fd5b5061038c6040518060400160405280600581526020017f332e332e3000000000000000000000000000000000000000000000000000000081525081565b60405161021f91906151f5565b3480156103a557600080fd5b506102d161129c565b3480156103ba57600080fd5b506101fe61132f565b3480156103cf57600080fd5b506101ca6103de366004615208565b611339565b3480156103ef57600080fd5b506101ca6103fe366004614ecb565b611b61565b34801561040f57600080fd5b506101ca61041e366004615233565b611c72565b34801561042f57600080fd5b506101ca61043e366004615250565b611da8565b34801561044f57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405190815260200161021f565b34801561048c57600080fd5b506032546101fe9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104b957600080fd5b506102d16104c8366004615208565b60336020526000908152604090205460ff1681565b3480156104e957600080fd5b5061032a6104f83660046152a3565b612085565b34801561050957600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610472565b34801561053c57600080fd5b506101ca61054b3660046152c0565b6120a4565b34801561055c57600080fd5b506001546105b8906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161021f565b3480156105fd57600080fd5b5061065861060c366004615208565b60396020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161021f565b6101ca61069b366004615319565b6106f8565b3480156106ac57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101fe565b3480156106d757600080fd5b506038546101fe9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905083156107af5773ffffffffffffffffffffffffffffffffffffffff8716156107af57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6107b98351612085565b67ffffffffffffffff168567ffffffffffffffff16101561085c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c000000000000000000000000000000000000000000000000000000000060648201526084016107a6565b6201d4c0835111156108ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c61726765000060448201526064016107a6565b333281146108eb575033731111000000000000000000000000000000001111015b60003488888888604051602001610906959493929190615398565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161097691906151f5565b60405180910390a4505061098a828261230d565b50505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2691906153fd565b905090565b610a3361129c565b15610a9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a207061757365640000000000000000000060448201526064016107a6565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610b59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e74726163740060648201526084016107a6565b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa158015610bcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf1919061541a565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c67919061545c565b603b5490915060ff848116911614610d01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a20696e76616c69642067616d652074797060448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084016107a6565b610d18610d1336889003880188615475565b61263a565b8114610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084016107a6565b6000610db189612696565b60008181526039602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff81168084527401000000000000000000000000000000000000000090910467ffffffffffffffff169183018290529293509091901580610ea0575060018173ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8d919061550a565b6002811115610e9e57610e9e6154db565b145b80610ed0575073ffffffffffffffffffffffffffffffffffffffff81166000908152603a602052604090205460ff165b80610f635750603b5463ffffffff1660ff16610f5d8273ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f54919061552b565b63ffffffff1690565b60ff1614155b611015576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152606060248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e2c20616e642074686560648201527f206f6c6420646973707574652067616d65206973206e6f7420696e76616c6964608482015260a4016107a6565b60408051602081018590526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506110de9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152906110d48b8d615548565b8d604001356126c6565b61116a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f66000000000000000000000000000060648201526084016107a6565b60405180604001604052808773ffffffffffffffffffffffffffffffffffffffff1681526020014267ffffffffffffffff168152506039600086815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050508b6040015173ffffffffffffffffffffffffffffffffffffffff168c6020015173ffffffffffffffffffffffffffffffffffffffff16857f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6260405160405180910390a4505050505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2691906155cc565b6000610a26610993565b600081815260396020908152604080832081518083018352905473ffffffffffffffffffffffffffffffffffffffff81168083527401000000000000000000000000000000000000000090910467ffffffffffffffff1682850152808552603a90935292205460ff161561142f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652068617360448201527f206265656e20626c61636b6c697374656400000000000000000000000000000060648201526084016107a6565b816020015167ffffffffffffffff166000036114cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e20796574000000000000000000000000000060648201526084016107a6565b600061154e8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561151d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154191906155e9565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff161161161d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4016107a6565b7f0000000000000000000000000000000000000000000000000000000000000000836020015167ffffffffffffffff16426116589190615635565b116116e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d61747572656420796574000000000000000000000060648201526084016107a6565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611732573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611756919061550a565b6002811115611767576117676154db565b146117f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f686173206e6f74206265656e2066696e616c697a65642079657400000000000060648201526084016107a6565b603b5463ffffffff1660ff1661184e8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f30573d6000803e3d6000fd5b60ff16146118de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a20696e76616c69642067616d652074797060448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084016107a6565b603b5467ffffffffffffffff640100000000909104811690821610156119ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a4016107a6565b7f0000000000000000000000000000000000000000000000000000000000000000611a1b8373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561151d573d6000803e3d6000fd5b611a2f9067ffffffffffffffff1642615635565b11611abc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d6761700000000000000000000000000000000000000000000060648201526084016107a6565b60008481526033602052604090205460ff1615611b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a6564000000000000000000000060648201526084016107a6565b50505050565b611b69610993565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4f7074696d69736d506f7274616c3a206f6e6c7920746865206775617264696160448201527f6e2063616e20626c61636b6c69737420646973707574652067616d657300000060648201526084016107a6565b73ffffffffffffffffffffffffffffffffffffffff166000908152603a6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b611c7a610993565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4f7074696d69736d506f7274616c3a206f6e6c7920746865206775617264696160448201527f6e2063616e2073657420746865207265737065637465642067616d652074797060648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016107a6565b603b805463ffffffff929092167fffffffffffffffffffffffffffffffffffffffff000000000000000000000000909216919091176401000000004267ffffffffffffffff1602179055565b565b611db061129c565b15611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a207061757365640000000000000000000060448201526064016107a6565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14611ec0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e0060648201526084016107a6565b6000611ecb82612696565b9050611ed681611339565b600081815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558301516080840151606085015160a0860151611f78939291906126ea565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611fdd90841515815260200190565b60405180910390a280158015611ff35750326001145b15612080576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f640000000000000000000000000000000000000000000000000000000000000060648201526084016107a6565b505050565b600061209282601061564c565b61209e9061520861567c565b92915050565b600054610100900460ff16158080156120c45750600054600160ff909116105b806120de5750303b1580156120de575060005460ff166001145b61216a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107a6565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156121c857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100858416021790556032541661228157603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b612289612748565b8015611b5b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090612343907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615635565b9050600061234f61285b565b90506000816020015160ff16826000015163ffffffff1661237091906156d7565b905082156124a7576001546000906123a7908390700100000000000000000000000000000000900467ffffffffffffffff1661573f565b90506000836040015160ff16836123be91906157b3565b6001546123de9084906fffffffffffffffffffffffffffffffff166157b3565b6123e891906156d7565b600154909150600090612439906124129084906fffffffffffffffffffffffffffffffff1661586f565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff1661291c565b905060018611156124685761246561241282876040015160ff1660018a6124609190615635565b61293b565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906124da908490700100000000000000000000000000000000900467ffffffffffffffff1661567c565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156125bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d6974000060648201526084016107a6565b6001546000906125e9906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166158e3565b905060006125fb48633b9aca00612990565b6126059083615920565b905060005a6126149088615635565b9050808211156126305761263061262b8284615635565b6129a7565b5050505050505050565b60008160000151826020015183604001518460600151604051602001612679949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097612679979096959101615934565b6000806126d2866129d0565b90506126e081868686612a02565b9695505050505050565b60008060006126fa866000612a32565b905080612730576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166127df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107a6565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff16600003611da65760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156128f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2691906159a1565b600061293161292b8585612a50565b83612a60565b90505b9392505050565b6000670de0b6b3a764000061297c61295385836156d7565b61296590670de0b6b3a764000061573f565b61297785670de0b6b3a76400006157b3565b612a6f565b61298690866157b3565b61293191906156d7565b6000818310156129a05781612934565b5090919050565b6000805a90505b825a6129ba9083615635565b1015612080576129c982615a5d565b91506129ae565b606081805190602001206040516020016129ec91815260200190565b6040516020818303038152906040529050919050565b6000612a2984612a13878686612aa0565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129a05781612934565b60008183126129a05781612934565b6000612934670de0b6b3a764000083612a878661351e565b612a9191906157b3565b612a9b91906156d7565b613762565b60606000845111612b0d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b6579000000000000000000000060448201526064016107a6565b6000612b18846139a1565b90506000612b2586613a8d565b9050600084604051602001612b3c91815260200190565b60405160208183030381529060405290506000805b8451811015613495576000858281518110612b6e57612b6e615a95565b602002602001015190508451831115612c09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e67746800000000000000000000000000000000000060648201526084016107a6565b82600003612cc25780518051602091820120604051612c5792612c3192910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612cbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016107a6565b612e19565b805151602011612d785780518051602091820120604051612cec92612c3192910190815260200190565b612cbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016107a6565b805184516020808701919091208251919092012014612e19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016107a6565b612e2560106001615ac4565b816020015151036130015784518303612f9957612e5f8160200151601081518110612e5257612e52615a95565b6020026020010151613af0565b96506000875111612ef2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e636829000000000060648201526084016107a6565b60018651612f009190615635565b8214612f8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e63682900000000000060648201526084016107a6565b505050505050612934565b6000858481518110612fad57612fad615a95565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612fd857612fd8615a95565b60200260200101519050612feb81613c50565b9550612ff8600186615ac4565b94505050613482565b6002816020015151036133fa57600061301982613c75565b905060008160008151811061303057613030615a95565b016020015160f81c90506000613047600283615adc565b613052906002615afe565b90506000613063848360ff16613c99565b905060006130718a89613c99565b9050600061307f8383613ccf565b905080835114613111576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b657900000000000060648201526084016107a6565b60ff851660021480613126575060ff85166003145b1561331557808251146131bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e64657200000060648201526084016107a6565b6131d58760200151600181518110612e5257612e52615a95565b9c5060008d5111613268576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c656166290000000000000060648201526084016107a6565b60018c516132769190615635565b8814613304576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c65616629000000000000000060648201526084016107a6565b505050505050505050505050612934565b60ff85161580613328575060ff85166001145b1561336757613354876020015160018151811061334757613347615a95565b6020026020010151613c50565b9950613360818a615ac4565b98506133ef565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016107a6565b505050505050613482565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016107a6565b508061348d81615a5d565b915050612b51565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e747300000000000000000000000000000000000000000000000000000060648201526084016107a6565b6000808213613589576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016107a6565b6000606061359684613d83565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361379357506000919050565b680755bf798b4a1bf1e58212613805576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016107a6565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156139bf576139bf614ee8565b604051908082528060200260200182016040528015613a0457816020015b60408051808201909152606080825260208201528152602001906001900390816139dd5790505b50915060005b81811015613a86576040518060400160405280858381518110613a2f57613a2f615a95565b60200260200101518152602001613a5e868481518110613a5157613a51615a95565b6020026020010151613e59565b815250838281518110613a7357613a73615a95565b6020908102919091010152600101613a0a565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613ae5578060011b82018184015160001a8060041c8253600f811660018301535050600101613ab7565b509295945050505050565b60606000806000613b0085613e6c565b919450925090506000816001811115613b1b57613b1b6154db565b14613ba8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d0000000000000060648201526084016107a6565b613bb28284615ac4565b855114613c41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e64657200000000000000000000000060648201526084016107a6565b612a29856020015184846148d9565b60606020826000015110613c6c57613c6782613af0565b61209e565b61209e8261496d565b606061209e613c948360200151600081518110612e5257612e52615a95565b613a8d565b606082518210613cb8575060408051602081019091526000815261209e565b6129348383848651613cca9190615635565b614983565b6000808251845110613ce2578251613ce5565b83515b90505b8082108015613d6c5750828281518110613d0457613d04615a95565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613d4357613d43615a95565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613d7c57816001019150613ce8565b5092915050565b6000808211613dee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016107a6565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061209e613e6783614b5b565b614c44565b600080600080846000015111613f2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a4016107a6565b6020840151805160001a607f8111613f4f5760006001600094509450945050506148d2565b60b7811161415d576000613f64608083615635565b90508087600001511161401f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a4016107a6565b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214158061409857507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b61414a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a4016107a6565b50600195509350600092506148d2915050565b60bf81116144ab57600061417260b783615635565b90508087600001511161422d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a4016107a6565b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361430b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a4016107a6565b600184015160088302610100031c603781116143cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a4016107a6565b6143d98184615ac4565b89511161448e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a4016107a6565b614499836001615ac4565b97509550600094506148d29350505050565b60f7811161458c5760006144c060c083615635565b90508087600001511161457b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a4016107a6565b6001955093508492506148d2915050565b600061459960f783615635565b905080876000015111614654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a4016107a6565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614732576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a4016107a6565b600184015160088302610100031c603781116147f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a4016107a6565b6148008184615ac4565b8951116148b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a4016107a6565b6148c0836001615ac4565b97509550600194506148d29350505050565b9193909250565b60608167ffffffffffffffff8111156148f4576148f4614ee8565b6040519080825280601f01601f19166020018201604052801561491e576020820181803683370190505b50905081156129345760006149338486615ac4565b90506020820160005b8481101561495457828101518282015260200161493c565b84811115614963576000858301525b5050509392505050565b606061209e8260200151600084600001516148d9565b60608182601f0110156149f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016107a6565b828284011015614a5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016107a6565b81830184511015614acb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016107a6565b606082158015614aea5760405191506000825260208201604052614b52565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614b23578051835260209283019201614b0b565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201526000825111614c26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a4016107a6565b50604080518082019091528151815260209182019181019190915290565b60606000806000614c5485613e6c565b919450925090506001816001811115614c6f57614c6f6154db565b14614cfc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d000000000000000060648201526084016107a6565b8451614d088385615ac4565b14614d95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e646572000000000000000000000000000060648201526084016107a6565b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614dac5790505093506000835b8651811015614e9a57600080614e1f6040518060400160405280858c60000151614e039190615635565b8152602001858c60200151614e189190615ac4565b9052613e6c565b509150915060405180604001604052808383614e3b9190615ac4565b8152602001848b60200151614e509190615ac4565b815250888581518110614e6557614e65615a95565b6020908102919091010152614e7b600185615ac4565b9350614e878183615ac4565b614e919084615ac4565b92505050614dd9565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614ec857600080fd5b50565b600060208284031215614edd57600080fd5b813561293481614ea6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5e57614f5e614ee8565b604052919050565b600082601f830112614f7757600080fd5b813567ffffffffffffffff811115614f9157614f91614ee8565b614fc260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f17565b818152846020838601011115614fd757600080fd5b816020850160208301376000918101602001919091529392505050565b600060c0828403121561500657600080fd5b60405160c0810167ffffffffffffffff828210818311171561502a5761502a614ee8565b81604052829350843583526020850135915061504582614ea6565b8160208401526040850135915061505b82614ea6565b816040840152606085013560608401526080850135608084015260a085013591508082111561508957600080fd5b5061509685828601614f66565b60a0830152505092915050565b600080600080600085870360e08112156150bc57600080fd5b863567ffffffffffffffff808211156150d457600080fd5b6150e08a838b01614ff4565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561511957600080fd5b60408901955060c089013592508083111561513357600080fd5b828901925089601f84011261514757600080fd5b823591508082111561515857600080fd5b508860208260051b840101111561516e57600080fd5b959894975092955050506020019190565b60005b8381101561519a578181015183820152602001615182565b83811115611b5b5750506000910152565b600081518084526151c381602086016020860161517f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061293460208301846151ab565b60006020828403121561521a57600080fd5b5035919050565b63ffffffff81168114614ec857600080fd5b60006020828403121561524557600080fd5b813561293481615221565b60006020828403121561526257600080fd5b813567ffffffffffffffff81111561527957600080fd5b61528584828501614ff4565b949350505050565b67ffffffffffffffff81168114614ec857600080fd5b6000602082840312156152b557600080fd5b81356129348161528d565b6000806000606084860312156152d557600080fd5b83356152e081614ea6565b925060208401356152f081614ea6565b9150604084013561530081614ea6565b809150509250925092565b8015158114614ec857600080fd5b600080600080600060a0868803121561533157600080fd5b853561533c81614ea6565b94506020860135935060408601356153538161528d565b925060608601356153638161530b565b9150608086013567ffffffffffffffff81111561537f57600080fd5b61538b88828901614f66565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516153ec81604985016020870161517f565b919091016049019695505050505050565b60006020828403121561540f57600080fd5b815161293481614ea6565b60008060006060848603121561542f57600080fd5b835161543a81615221565b602085015190935061544b8161528d565b604085015190925061530081614ea6565b60006020828403121561546e57600080fd5b5051919050565b60006080828403121561548757600080fd5b6040516080810181811067ffffffffffffffff821117156154aa576154aa614ee8565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561551c57600080fd5b81516003811061293457600080fd5b60006020828403121561553d57600080fd5b815161293481615221565b600067ffffffffffffffff8084111561556357615563614ee8565b8360051b6020615574818301614f17565b86815291850191818101903684111561558c57600080fd5b865b848110156155c0578035868111156155a65760008081fd5b6155b236828b01614f66565b84525091830191830161558e565b50979650505050505050565b6000602082840312156155de57600080fd5b81516129348161530b565b6000602082840312156155fb57600080fd5b81516129348161528d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561564757615647615606565b500390565b600067ffffffffffffffff8083168185168183048111821515161561567357615673615606565b02949350505050565b600067ffffffffffffffff80831681851680830382111561569f5761569f615606565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826156e6576156e66156a8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561573a5761573a615606565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561577957615779615606565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156157ad576157ad615606565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156157f4576157f4615606565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561582f5761582f615606565b6000871292508782058712848416161561584b5761584b615606565b8785058712818416161561586157615861615606565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156158a9576158a9615606565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156158dd576158dd615606565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561591b5761591b615606565b500290565b60008261592f5761592f6156a8565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261597f60c08301846151ab565b98975050505050505050565b805160ff8116811461599c57600080fd5b919050565b600060c082840312156159b357600080fd5b60405160c0810181811067ffffffffffffffff821117156159d6576159d6614ee8565b60405282516159e481615221565b81526159f26020840161598b565b6020820152615a036040840161598b565b60408201526060830151615a1681615221565b60608201526080830151615a2981615221565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615a5157600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615a8e57615a8e615606565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008219821115615ad757615ad7615606565b500190565b600060ff831680615aef57615aef6156a8565b8060ff84160691505092915050565b600060ff821660ff841680821015615b1857615b18615606565b9003939250505056fea164736f6c634300080f000a", +} + +// OptimismPortal2ABI is the input ABI used to generate the binding from. +// Deprecated: Use OptimismPortal2MetaData.ABI instead. +var OptimismPortal2ABI = OptimismPortal2MetaData.ABI + +// OptimismPortal2Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use OptimismPortal2MetaData.Bin instead. +var OptimismPortal2Bin = OptimismPortal2MetaData.Bin + +// DeployOptimismPortal2 deploys a new Ethereum contract, binding an instance of OptimismPortal2 to it. +func DeployOptimismPortal2(auth *bind.TransactOpts, backend bind.ContractBackend, _proofMaturityDelaySeconds *big.Int, _disputeGameFinalityDelaySeconds *big.Int, _initialRespectedGameType uint32) (common.Address, *types.Transaction, *OptimismPortal2, error) { + parsed, err := OptimismPortal2MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OptimismPortal2Bin), backend, _proofMaturityDelaySeconds, _disputeGameFinalityDelaySeconds, _initialRespectedGameType) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &OptimismPortal2{OptimismPortal2Caller: OptimismPortal2Caller{contract: contract}, OptimismPortal2Transactor: OptimismPortal2Transactor{contract: contract}, OptimismPortal2Filterer: OptimismPortal2Filterer{contract: contract}}, nil +} + +// OptimismPortal2 is an auto generated Go binding around an Ethereum contract. +type OptimismPortal2 struct { + OptimismPortal2Caller // Read-only binding to the contract + OptimismPortal2Transactor // Write-only binding to the contract + OptimismPortal2Filterer // Log filterer for contract events +} + +// OptimismPortal2Caller is an auto generated read-only Go binding around an Ethereum contract. +type OptimismPortal2Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OptimismPortal2Transactor is an auto generated write-only Go binding around an Ethereum contract. +type OptimismPortal2Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OptimismPortal2Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type OptimismPortal2Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OptimismPortal2Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type OptimismPortal2Session struct { + Contract *OptimismPortal2 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// OptimismPortal2CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type OptimismPortal2CallerSession struct { + Contract *OptimismPortal2Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// OptimismPortal2TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type OptimismPortal2TransactorSession struct { + Contract *OptimismPortal2Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// OptimismPortal2Raw is an auto generated low-level Go binding around an Ethereum contract. +type OptimismPortal2Raw struct { + Contract *OptimismPortal2 // Generic contract binding to access the raw methods on +} + +// OptimismPortal2CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type OptimismPortal2CallerRaw struct { + Contract *OptimismPortal2Caller // Generic read-only contract binding to access the raw methods on +} + +// OptimismPortal2TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type OptimismPortal2TransactorRaw struct { + Contract *OptimismPortal2Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewOptimismPortal2 creates a new instance of OptimismPortal2, bound to a specific deployed contract. +func NewOptimismPortal2(address common.Address, backend bind.ContractBackend) (*OptimismPortal2, error) { + contract, err := bindOptimismPortal2(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OptimismPortal2{OptimismPortal2Caller: OptimismPortal2Caller{contract: contract}, OptimismPortal2Transactor: OptimismPortal2Transactor{contract: contract}, OptimismPortal2Filterer: OptimismPortal2Filterer{contract: contract}}, nil +} + +// NewOptimismPortal2Caller creates a new read-only instance of OptimismPortal2, bound to a specific deployed contract. +func NewOptimismPortal2Caller(address common.Address, caller bind.ContractCaller) (*OptimismPortal2Caller, error) { + contract, err := bindOptimismPortal2(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OptimismPortal2Caller{contract: contract}, nil +} + +// NewOptimismPortal2Transactor creates a new write-only instance of OptimismPortal2, bound to a specific deployed contract. +func NewOptimismPortal2Transactor(address common.Address, transactor bind.ContractTransactor) (*OptimismPortal2Transactor, error) { + contract, err := bindOptimismPortal2(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OptimismPortal2Transactor{contract: contract}, nil +} + +// NewOptimismPortal2Filterer creates a new log filterer instance of OptimismPortal2, bound to a specific deployed contract. +func NewOptimismPortal2Filterer(address common.Address, filterer bind.ContractFilterer) (*OptimismPortal2Filterer, error) { + contract, err := bindOptimismPortal2(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OptimismPortal2Filterer{contract: contract}, nil +} + +// bindOptimismPortal2 binds a generic wrapper to an already deployed contract. +func bindOptimismPortal2(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(OptimismPortal2ABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OptimismPortal2 *OptimismPortal2Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismPortal2.Contract.OptimismPortal2Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OptimismPortal2 *OptimismPortal2Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismPortal2.Contract.OptimismPortal2Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_OptimismPortal2 *OptimismPortal2Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismPortal2.Contract.OptimismPortal2Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OptimismPortal2 *OptimismPortal2CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OptimismPortal2.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OptimismPortal2 *OptimismPortal2TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismPortal2.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_OptimismPortal2 *OptimismPortal2TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OptimismPortal2.Contract.contract.Transact(opts, method, params...) +} + +// GUARDIAN is a free data retrieval call binding the contract method 0x724c184c. +// +// Solidity: function GUARDIAN() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Caller) GUARDIAN(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "GUARDIAN") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GUARDIAN is a free data retrieval call binding the contract method 0x724c184c. +// +// Solidity: function GUARDIAN() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Session) GUARDIAN() (common.Address, error) { + return _OptimismPortal2.Contract.GUARDIAN(&_OptimismPortal2.CallOpts) +} + +// GUARDIAN is a free data retrieval call binding the contract method 0x724c184c. +// +// Solidity: function GUARDIAN() view returns(address) +func (_OptimismPortal2 *OptimismPortal2CallerSession) GUARDIAN() (common.Address, error) { + return _OptimismPortal2.Contract.GUARDIAN(&_OptimismPortal2.CallOpts) +} + +// SYSTEMCONFIG is a free data retrieval call binding the contract method 0xf0498750. +// +// Solidity: function SYSTEM_CONFIG() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Caller) SYSTEMCONFIG(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "SYSTEM_CONFIG") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SYSTEMCONFIG is a free data retrieval call binding the contract method 0xf0498750. +// +// Solidity: function SYSTEM_CONFIG() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Session) SYSTEMCONFIG() (common.Address, error) { + return _OptimismPortal2.Contract.SYSTEMCONFIG(&_OptimismPortal2.CallOpts) +} + +// SYSTEMCONFIG is a free data retrieval call binding the contract method 0xf0498750. +// +// Solidity: function SYSTEM_CONFIG() view returns(address) +func (_OptimismPortal2 *OptimismPortal2CallerSession) SYSTEMCONFIG() (common.Address, error) { + return _OptimismPortal2.Contract.SYSTEMCONFIG(&_OptimismPortal2.CallOpts) +} + +// CheckWithdrawal is a free data retrieval call binding the contract method 0x7af1906d. +// +// Solidity: function checkWithdrawal(bytes32 _withdrawalHash) view returns() +func (_OptimismPortal2 *OptimismPortal2Caller) CheckWithdrawal(opts *bind.CallOpts, _withdrawalHash [32]byte) error { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "checkWithdrawal", _withdrawalHash) + + if err != nil { + return err + } + + return err + +} + +// CheckWithdrawal is a free data retrieval call binding the contract method 0x7af1906d. +// +// Solidity: function checkWithdrawal(bytes32 _withdrawalHash) view returns() +func (_OptimismPortal2 *OptimismPortal2Session) CheckWithdrawal(_withdrawalHash [32]byte) error { + return _OptimismPortal2.Contract.CheckWithdrawal(&_OptimismPortal2.CallOpts, _withdrawalHash) +} + +// CheckWithdrawal is a free data retrieval call binding the contract method 0x7af1906d. +// +// Solidity: function checkWithdrawal(bytes32 _withdrawalHash) view returns() +func (_OptimismPortal2 *OptimismPortal2CallerSession) CheckWithdrawal(_withdrawalHash [32]byte) error { + return _OptimismPortal2.Contract.CheckWithdrawal(&_OptimismPortal2.CallOpts, _withdrawalHash) +} + +// DisputeGameBlacklist is a free data retrieval call binding the contract method 0x45884d32. +// +// Solidity: function disputeGameBlacklist(address ) view returns(bool) +func (_OptimismPortal2 *OptimismPortal2Caller) DisputeGameBlacklist(opts *bind.CallOpts, arg0 common.Address) (bool, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "disputeGameBlacklist", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// DisputeGameBlacklist is a free data retrieval call binding the contract method 0x45884d32. +// +// Solidity: function disputeGameBlacklist(address ) view returns(bool) +func (_OptimismPortal2 *OptimismPortal2Session) DisputeGameBlacklist(arg0 common.Address) (bool, error) { + return _OptimismPortal2.Contract.DisputeGameBlacklist(&_OptimismPortal2.CallOpts, arg0) +} + +// DisputeGameBlacklist is a free data retrieval call binding the contract method 0x45884d32. +// +// Solidity: function disputeGameBlacklist(address ) view returns(bool) +func (_OptimismPortal2 *OptimismPortal2CallerSession) DisputeGameBlacklist(arg0 common.Address) (bool, error) { + return _OptimismPortal2.Contract.DisputeGameBlacklist(&_OptimismPortal2.CallOpts, arg0) +} + +// DisputeGameFactory is a free data retrieval call binding the contract method 0xf2b4e617. +// +// Solidity: function disputeGameFactory() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Caller) DisputeGameFactory(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "disputeGameFactory") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// DisputeGameFactory is a free data retrieval call binding the contract method 0xf2b4e617. +// +// Solidity: function disputeGameFactory() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Session) DisputeGameFactory() (common.Address, error) { + return _OptimismPortal2.Contract.DisputeGameFactory(&_OptimismPortal2.CallOpts) +} + +// DisputeGameFactory is a free data retrieval call binding the contract method 0xf2b4e617. +// +// Solidity: function disputeGameFactory() view returns(address) +func (_OptimismPortal2 *OptimismPortal2CallerSession) DisputeGameFactory() (common.Address, error) { + return _OptimismPortal2.Contract.DisputeGameFactory(&_OptimismPortal2.CallOpts) +} + +// DisputeGameFinalityDelaySeconds is a free data retrieval call binding the contract method 0x952b2797. +// +// Solidity: function disputeGameFinalityDelaySeconds() view returns(uint256) +func (_OptimismPortal2 *OptimismPortal2Caller) DisputeGameFinalityDelaySeconds(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "disputeGameFinalityDelaySeconds") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// DisputeGameFinalityDelaySeconds is a free data retrieval call binding the contract method 0x952b2797. +// +// Solidity: function disputeGameFinalityDelaySeconds() view returns(uint256) +func (_OptimismPortal2 *OptimismPortal2Session) DisputeGameFinalityDelaySeconds() (*big.Int, error) { + return _OptimismPortal2.Contract.DisputeGameFinalityDelaySeconds(&_OptimismPortal2.CallOpts) +} + +// DisputeGameFinalityDelaySeconds is a free data retrieval call binding the contract method 0x952b2797. +// +// Solidity: function disputeGameFinalityDelaySeconds() view returns(uint256) +func (_OptimismPortal2 *OptimismPortal2CallerSession) DisputeGameFinalityDelaySeconds() (*big.Int, error) { + return _OptimismPortal2.Contract.DisputeGameFinalityDelaySeconds(&_OptimismPortal2.CallOpts) +} + +// FinalizedWithdrawals is a free data retrieval call binding the contract method 0xa14238e7. +// +// Solidity: function finalizedWithdrawals(bytes32 ) view returns(bool) +func (_OptimismPortal2 *OptimismPortal2Caller) FinalizedWithdrawals(opts *bind.CallOpts, arg0 [32]byte) (bool, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "finalizedWithdrawals", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// FinalizedWithdrawals is a free data retrieval call binding the contract method 0xa14238e7. +// +// Solidity: function finalizedWithdrawals(bytes32 ) view returns(bool) +func (_OptimismPortal2 *OptimismPortal2Session) FinalizedWithdrawals(arg0 [32]byte) (bool, error) { + return _OptimismPortal2.Contract.FinalizedWithdrawals(&_OptimismPortal2.CallOpts, arg0) +} + +// FinalizedWithdrawals is a free data retrieval call binding the contract method 0xa14238e7. +// +// Solidity: function finalizedWithdrawals(bytes32 ) view returns(bool) +func (_OptimismPortal2 *OptimismPortal2CallerSession) FinalizedWithdrawals(arg0 [32]byte) (bool, error) { + return _OptimismPortal2.Contract.FinalizedWithdrawals(&_OptimismPortal2.CallOpts, arg0) +} + +// Guardian is a free data retrieval call binding the contract method 0x452a9320. +// +// Solidity: function guardian() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Caller) Guardian(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "guardian") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Guardian is a free data retrieval call binding the contract method 0x452a9320. +// +// Solidity: function guardian() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Session) Guardian() (common.Address, error) { + return _OptimismPortal2.Contract.Guardian(&_OptimismPortal2.CallOpts) +} + +// Guardian is a free data retrieval call binding the contract method 0x452a9320. +// +// Solidity: function guardian() view returns(address) +func (_OptimismPortal2 *OptimismPortal2CallerSession) Guardian() (common.Address, error) { + return _OptimismPortal2.Contract.Guardian(&_OptimismPortal2.CallOpts) +} + +// L2Sender is a free data retrieval call binding the contract method 0x9bf62d82. +// +// Solidity: function l2Sender() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Caller) L2Sender(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "l2Sender") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// L2Sender is a free data retrieval call binding the contract method 0x9bf62d82. +// +// Solidity: function l2Sender() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Session) L2Sender() (common.Address, error) { + return _OptimismPortal2.Contract.L2Sender(&_OptimismPortal2.CallOpts) +} + +// L2Sender is a free data retrieval call binding the contract method 0x9bf62d82. +// +// Solidity: function l2Sender() view returns(address) +func (_OptimismPortal2 *OptimismPortal2CallerSession) L2Sender() (common.Address, error) { + return _OptimismPortal2.Contract.L2Sender(&_OptimismPortal2.CallOpts) +} + +// MinimumGasLimit is a free data retrieval call binding the contract method 0xa35d99df. +// +// Solidity: function minimumGasLimit(uint64 _byteCount) pure returns(uint64) +func (_OptimismPortal2 *OptimismPortal2Caller) MinimumGasLimit(opts *bind.CallOpts, _byteCount uint64) (uint64, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "minimumGasLimit", _byteCount) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// MinimumGasLimit is a free data retrieval call binding the contract method 0xa35d99df. +// +// Solidity: function minimumGasLimit(uint64 _byteCount) pure returns(uint64) +func (_OptimismPortal2 *OptimismPortal2Session) MinimumGasLimit(_byteCount uint64) (uint64, error) { + return _OptimismPortal2.Contract.MinimumGasLimit(&_OptimismPortal2.CallOpts, _byteCount) +} + +// MinimumGasLimit is a free data retrieval call binding the contract method 0xa35d99df. +// +// Solidity: function minimumGasLimit(uint64 _byteCount) pure returns(uint64) +func (_OptimismPortal2 *OptimismPortal2CallerSession) MinimumGasLimit(_byteCount uint64) (uint64, error) { + return _OptimismPortal2.Contract.MinimumGasLimit(&_OptimismPortal2.CallOpts, _byteCount) +} + +// Params is a free data retrieval call binding the contract method 0xcff0ab96. +// +// Solidity: function params() view returns(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) +func (_OptimismPortal2 *OptimismPortal2Caller) Params(opts *bind.CallOpts) (struct { + PrevBaseFee *big.Int + PrevBoughtGas uint64 + PrevBlockNum uint64 +}, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "params") + + outstruct := new(struct { + PrevBaseFee *big.Int + PrevBoughtGas uint64 + PrevBlockNum uint64 + }) + if err != nil { + return *outstruct, err + } + + outstruct.PrevBaseFee = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.PrevBoughtGas = *abi.ConvertType(out[1], new(uint64)).(*uint64) + outstruct.PrevBlockNum = *abi.ConvertType(out[2], new(uint64)).(*uint64) + + return *outstruct, err + +} + +// Params is a free data retrieval call binding the contract method 0xcff0ab96. +// +// Solidity: function params() view returns(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) +func (_OptimismPortal2 *OptimismPortal2Session) Params() (struct { + PrevBaseFee *big.Int + PrevBoughtGas uint64 + PrevBlockNum uint64 +}, error) { + return _OptimismPortal2.Contract.Params(&_OptimismPortal2.CallOpts) +} + +// Params is a free data retrieval call binding the contract method 0xcff0ab96. +// +// Solidity: function params() view returns(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) +func (_OptimismPortal2 *OptimismPortal2CallerSession) Params() (struct { + PrevBaseFee *big.Int + PrevBoughtGas uint64 + PrevBlockNum uint64 +}, error) { + return _OptimismPortal2.Contract.Params(&_OptimismPortal2.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_OptimismPortal2 *OptimismPortal2Caller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_OptimismPortal2 *OptimismPortal2Session) Paused() (bool, error) { + return _OptimismPortal2.Contract.Paused(&_OptimismPortal2.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_OptimismPortal2 *OptimismPortal2CallerSession) Paused() (bool, error) { + return _OptimismPortal2.Contract.Paused(&_OptimismPortal2.CallOpts) +} + +// ProofMaturityDelaySeconds is a free data retrieval call binding the contract method 0xbf653a5c. +// +// Solidity: function proofMaturityDelaySeconds() view returns(uint256) +func (_OptimismPortal2 *OptimismPortal2Caller) ProofMaturityDelaySeconds(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "proofMaturityDelaySeconds") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ProofMaturityDelaySeconds is a free data retrieval call binding the contract method 0xbf653a5c. +// +// Solidity: function proofMaturityDelaySeconds() view returns(uint256) +func (_OptimismPortal2 *OptimismPortal2Session) ProofMaturityDelaySeconds() (*big.Int, error) { + return _OptimismPortal2.Contract.ProofMaturityDelaySeconds(&_OptimismPortal2.CallOpts) +} + +// ProofMaturityDelaySeconds is a free data retrieval call binding the contract method 0xbf653a5c. +// +// Solidity: function proofMaturityDelaySeconds() view returns(uint256) +func (_OptimismPortal2 *OptimismPortal2CallerSession) ProofMaturityDelaySeconds() (*big.Int, error) { + return _OptimismPortal2.Contract.ProofMaturityDelaySeconds(&_OptimismPortal2.CallOpts) +} + +// ProvenWithdrawals is a free data retrieval call binding the contract method 0xe965084c. +// +// Solidity: function provenWithdrawals(bytes32 ) view returns(address disputeGameProxy, uint64 timestamp) +func (_OptimismPortal2 *OptimismPortal2Caller) ProvenWithdrawals(opts *bind.CallOpts, arg0 [32]byte) (struct { + DisputeGameProxy common.Address + Timestamp uint64 +}, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "provenWithdrawals", arg0) + + outstruct := new(struct { + DisputeGameProxy common.Address + Timestamp uint64 + }) + if err != nil { + return *outstruct, err + } + + outstruct.DisputeGameProxy = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.Timestamp = *abi.ConvertType(out[1], new(uint64)).(*uint64) + + return *outstruct, err + +} + +// ProvenWithdrawals is a free data retrieval call binding the contract method 0xe965084c. +// +// Solidity: function provenWithdrawals(bytes32 ) view returns(address disputeGameProxy, uint64 timestamp) +func (_OptimismPortal2 *OptimismPortal2Session) ProvenWithdrawals(arg0 [32]byte) (struct { + DisputeGameProxy common.Address + Timestamp uint64 +}, error) { + return _OptimismPortal2.Contract.ProvenWithdrawals(&_OptimismPortal2.CallOpts, arg0) +} + +// ProvenWithdrawals is a free data retrieval call binding the contract method 0xe965084c. +// +// Solidity: function provenWithdrawals(bytes32 ) view returns(address disputeGameProxy, uint64 timestamp) +func (_OptimismPortal2 *OptimismPortal2CallerSession) ProvenWithdrawals(arg0 [32]byte) (struct { + DisputeGameProxy common.Address + Timestamp uint64 +}, error) { + return _OptimismPortal2.Contract.ProvenWithdrawals(&_OptimismPortal2.CallOpts, arg0) +} + +// RespectedGameType is a free data retrieval call binding the contract method 0x3c9f397c. +// +// Solidity: function respectedGameType() view returns(uint32) +func (_OptimismPortal2 *OptimismPortal2Caller) RespectedGameType(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "respectedGameType") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// RespectedGameType is a free data retrieval call binding the contract method 0x3c9f397c. +// +// Solidity: function respectedGameType() view returns(uint32) +func (_OptimismPortal2 *OptimismPortal2Session) RespectedGameType() (uint32, error) { + return _OptimismPortal2.Contract.RespectedGameType(&_OptimismPortal2.CallOpts) +} + +// RespectedGameType is a free data retrieval call binding the contract method 0x3c9f397c. +// +// Solidity: function respectedGameType() view returns(uint32) +func (_OptimismPortal2 *OptimismPortal2CallerSession) RespectedGameType() (uint32, error) { + return _OptimismPortal2.Contract.RespectedGameType(&_OptimismPortal2.CallOpts) +} + +// RespectedGameTypeUpdatedAt is a free data retrieval call binding the contract method 0x4fd0434c. +// +// Solidity: function respectedGameTypeUpdatedAt() view returns(uint64) +func (_OptimismPortal2 *OptimismPortal2Caller) RespectedGameTypeUpdatedAt(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "respectedGameTypeUpdatedAt") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// RespectedGameTypeUpdatedAt is a free data retrieval call binding the contract method 0x4fd0434c. +// +// Solidity: function respectedGameTypeUpdatedAt() view returns(uint64) +func (_OptimismPortal2 *OptimismPortal2Session) RespectedGameTypeUpdatedAt() (uint64, error) { + return _OptimismPortal2.Contract.RespectedGameTypeUpdatedAt(&_OptimismPortal2.CallOpts) +} + +// RespectedGameTypeUpdatedAt is a free data retrieval call binding the contract method 0x4fd0434c. +// +// Solidity: function respectedGameTypeUpdatedAt() view returns(uint64) +func (_OptimismPortal2 *OptimismPortal2CallerSession) RespectedGameTypeUpdatedAt() (uint64, error) { + return _OptimismPortal2.Contract.RespectedGameTypeUpdatedAt(&_OptimismPortal2.CallOpts) +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Caller) SuperchainConfig(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "superchainConfig") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Session) SuperchainConfig() (common.Address, error) { + return _OptimismPortal2.Contract.SuperchainConfig(&_OptimismPortal2.CallOpts) +} + +// SuperchainConfig is a free data retrieval call binding the contract method 0x35e80ab3. +// +// Solidity: function superchainConfig() view returns(address) +func (_OptimismPortal2 *OptimismPortal2CallerSession) SuperchainConfig() (common.Address, error) { + return _OptimismPortal2.Contract.SuperchainConfig(&_OptimismPortal2.CallOpts) +} + +// SystemConfig is a free data retrieval call binding the contract method 0x33d7e2bd. +// +// Solidity: function systemConfig() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Caller) SystemConfig(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "systemConfig") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SystemConfig is a free data retrieval call binding the contract method 0x33d7e2bd. +// +// Solidity: function systemConfig() view returns(address) +func (_OptimismPortal2 *OptimismPortal2Session) SystemConfig() (common.Address, error) { + return _OptimismPortal2.Contract.SystemConfig(&_OptimismPortal2.CallOpts) +} + +// SystemConfig is a free data retrieval call binding the contract method 0x33d7e2bd. +// +// Solidity: function systemConfig() view returns(address) +func (_OptimismPortal2 *OptimismPortal2CallerSession) SystemConfig() (common.Address, error) { + return _OptimismPortal2.Contract.SystemConfig(&_OptimismPortal2.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_OptimismPortal2 *OptimismPortal2Caller) Version(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _OptimismPortal2.contract.Call(opts, &out, "version") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_OptimismPortal2 *OptimismPortal2Session) Version() (string, error) { + return _OptimismPortal2.Contract.Version(&_OptimismPortal2.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_OptimismPortal2 *OptimismPortal2CallerSession) Version() (string, error) { + return _OptimismPortal2.Contract.Version(&_OptimismPortal2.CallOpts) +} + +// BlacklistDisputeGame is a paid mutator transaction binding the contract method 0x7d6be8dc. +// +// Solidity: function blacklistDisputeGame(address _disputeGame) returns() +func (_OptimismPortal2 *OptimismPortal2Transactor) BlacklistDisputeGame(opts *bind.TransactOpts, _disputeGame common.Address) (*types.Transaction, error) { + return _OptimismPortal2.contract.Transact(opts, "blacklistDisputeGame", _disputeGame) +} + +// BlacklistDisputeGame is a paid mutator transaction binding the contract method 0x7d6be8dc. +// +// Solidity: function blacklistDisputeGame(address _disputeGame) returns() +func (_OptimismPortal2 *OptimismPortal2Session) BlacklistDisputeGame(_disputeGame common.Address) (*types.Transaction, error) { + return _OptimismPortal2.Contract.BlacklistDisputeGame(&_OptimismPortal2.TransactOpts, _disputeGame) +} + +// BlacklistDisputeGame is a paid mutator transaction binding the contract method 0x7d6be8dc. +// +// Solidity: function blacklistDisputeGame(address _disputeGame) returns() +func (_OptimismPortal2 *OptimismPortal2TransactorSession) BlacklistDisputeGame(_disputeGame common.Address) (*types.Transaction, error) { + return _OptimismPortal2.Contract.BlacklistDisputeGame(&_OptimismPortal2.TransactOpts, _disputeGame) +} + +// DepositTransaction is a paid mutator transaction binding the contract method 0xe9e05c42. +// +// Solidity: function depositTransaction(address _to, uint256 _value, uint64 _gasLimit, bool _isCreation, bytes _data) payable returns() +func (_OptimismPortal2 *OptimismPortal2Transactor) DepositTransaction(opts *bind.TransactOpts, _to common.Address, _value *big.Int, _gasLimit uint64, _isCreation bool, _data []byte) (*types.Transaction, error) { + return _OptimismPortal2.contract.Transact(opts, "depositTransaction", _to, _value, _gasLimit, _isCreation, _data) +} + +// DepositTransaction is a paid mutator transaction binding the contract method 0xe9e05c42. +// +// Solidity: function depositTransaction(address _to, uint256 _value, uint64 _gasLimit, bool _isCreation, bytes _data) payable returns() +func (_OptimismPortal2 *OptimismPortal2Session) DepositTransaction(_to common.Address, _value *big.Int, _gasLimit uint64, _isCreation bool, _data []byte) (*types.Transaction, error) { + return _OptimismPortal2.Contract.DepositTransaction(&_OptimismPortal2.TransactOpts, _to, _value, _gasLimit, _isCreation, _data) +} + +// DepositTransaction is a paid mutator transaction binding the contract method 0xe9e05c42. +// +// Solidity: function depositTransaction(address _to, uint256 _value, uint64 _gasLimit, bool _isCreation, bytes _data) payable returns() +func (_OptimismPortal2 *OptimismPortal2TransactorSession) DepositTransaction(_to common.Address, _value *big.Int, _gasLimit uint64, _isCreation bool, _data []byte) (*types.Transaction, error) { + return _OptimismPortal2.Contract.DepositTransaction(&_OptimismPortal2.TransactOpts, _to, _value, _gasLimit, _isCreation, _data) +} + +// DonateETH is a paid mutator transaction binding the contract method 0x8b4c40b0. +// +// Solidity: function donateETH() payable returns() +func (_OptimismPortal2 *OptimismPortal2Transactor) DonateETH(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismPortal2.contract.Transact(opts, "donateETH") +} + +// DonateETH is a paid mutator transaction binding the contract method 0x8b4c40b0. +// +// Solidity: function donateETH() payable returns() +func (_OptimismPortal2 *OptimismPortal2Session) DonateETH() (*types.Transaction, error) { + return _OptimismPortal2.Contract.DonateETH(&_OptimismPortal2.TransactOpts) +} + +// DonateETH is a paid mutator transaction binding the contract method 0x8b4c40b0. +// +// Solidity: function donateETH() payable returns() +func (_OptimismPortal2 *OptimismPortal2TransactorSession) DonateETH() (*types.Transaction, error) { + return _OptimismPortal2.Contract.DonateETH(&_OptimismPortal2.TransactOpts) +} + +// FinalizeWithdrawalTransaction is a paid mutator transaction binding the contract method 0x8c3152e9. +// +// Solidity: function finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes) _tx) returns() +func (_OptimismPortal2 *OptimismPortal2Transactor) FinalizeWithdrawalTransaction(opts *bind.TransactOpts, _tx TypesWithdrawalTransaction) (*types.Transaction, error) { + return _OptimismPortal2.contract.Transact(opts, "finalizeWithdrawalTransaction", _tx) +} + +// FinalizeWithdrawalTransaction is a paid mutator transaction binding the contract method 0x8c3152e9. +// +// Solidity: function finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes) _tx) returns() +func (_OptimismPortal2 *OptimismPortal2Session) FinalizeWithdrawalTransaction(_tx TypesWithdrawalTransaction) (*types.Transaction, error) { + return _OptimismPortal2.Contract.FinalizeWithdrawalTransaction(&_OptimismPortal2.TransactOpts, _tx) +} + +// FinalizeWithdrawalTransaction is a paid mutator transaction binding the contract method 0x8c3152e9. +// +// Solidity: function finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes) _tx) returns() +func (_OptimismPortal2 *OptimismPortal2TransactorSession) FinalizeWithdrawalTransaction(_tx TypesWithdrawalTransaction) (*types.Transaction, error) { + return _OptimismPortal2.Contract.FinalizeWithdrawalTransaction(&_OptimismPortal2.TransactOpts, _tx) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc0c53b8b. +// +// Solidity: function initialize(address _disputeGameFactory, address _systemConfig, address _superchainConfig) returns() +func (_OptimismPortal2 *OptimismPortal2Transactor) Initialize(opts *bind.TransactOpts, _disputeGameFactory common.Address, _systemConfig common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _OptimismPortal2.contract.Transact(opts, "initialize", _disputeGameFactory, _systemConfig, _superchainConfig) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc0c53b8b. +// +// Solidity: function initialize(address _disputeGameFactory, address _systemConfig, address _superchainConfig) returns() +func (_OptimismPortal2 *OptimismPortal2Session) Initialize(_disputeGameFactory common.Address, _systemConfig common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _OptimismPortal2.Contract.Initialize(&_OptimismPortal2.TransactOpts, _disputeGameFactory, _systemConfig, _superchainConfig) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc0c53b8b. +// +// Solidity: function initialize(address _disputeGameFactory, address _systemConfig, address _superchainConfig) returns() +func (_OptimismPortal2 *OptimismPortal2TransactorSession) Initialize(_disputeGameFactory common.Address, _systemConfig common.Address, _superchainConfig common.Address) (*types.Transaction, error) { + return _OptimismPortal2.Contract.Initialize(&_OptimismPortal2.TransactOpts, _disputeGameFactory, _systemConfig, _superchainConfig) +} + +// ProveWithdrawalTransaction is a paid mutator transaction binding the contract method 0x4870496f. +// +// Solidity: function proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes) _tx, uint256 _disputeGameIndex, (bytes32,bytes32,bytes32,bytes32) _outputRootProof, bytes[] _withdrawalProof) returns() +func (_OptimismPortal2 *OptimismPortal2Transactor) ProveWithdrawalTransaction(opts *bind.TransactOpts, _tx TypesWithdrawalTransaction, _disputeGameIndex *big.Int, _outputRootProof TypesOutputRootProof, _withdrawalProof [][]byte) (*types.Transaction, error) { + return _OptimismPortal2.contract.Transact(opts, "proveWithdrawalTransaction", _tx, _disputeGameIndex, _outputRootProof, _withdrawalProof) +} + +// ProveWithdrawalTransaction is a paid mutator transaction binding the contract method 0x4870496f. +// +// Solidity: function proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes) _tx, uint256 _disputeGameIndex, (bytes32,bytes32,bytes32,bytes32) _outputRootProof, bytes[] _withdrawalProof) returns() +func (_OptimismPortal2 *OptimismPortal2Session) ProveWithdrawalTransaction(_tx TypesWithdrawalTransaction, _disputeGameIndex *big.Int, _outputRootProof TypesOutputRootProof, _withdrawalProof [][]byte) (*types.Transaction, error) { + return _OptimismPortal2.Contract.ProveWithdrawalTransaction(&_OptimismPortal2.TransactOpts, _tx, _disputeGameIndex, _outputRootProof, _withdrawalProof) +} + +// ProveWithdrawalTransaction is a paid mutator transaction binding the contract method 0x4870496f. +// +// Solidity: function proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes) _tx, uint256 _disputeGameIndex, (bytes32,bytes32,bytes32,bytes32) _outputRootProof, bytes[] _withdrawalProof) returns() +func (_OptimismPortal2 *OptimismPortal2TransactorSession) ProveWithdrawalTransaction(_tx TypesWithdrawalTransaction, _disputeGameIndex *big.Int, _outputRootProof TypesOutputRootProof, _withdrawalProof [][]byte) (*types.Transaction, error) { + return _OptimismPortal2.Contract.ProveWithdrawalTransaction(&_OptimismPortal2.TransactOpts, _tx, _disputeGameIndex, _outputRootProof, _withdrawalProof) +} + +// SetRespectedGameType is a paid mutator transaction binding the contract method 0x7fc48504. +// +// Solidity: function setRespectedGameType(uint32 _gameType) returns() +func (_OptimismPortal2 *OptimismPortal2Transactor) SetRespectedGameType(opts *bind.TransactOpts, _gameType uint32) (*types.Transaction, error) { + return _OptimismPortal2.contract.Transact(opts, "setRespectedGameType", _gameType) +} + +// SetRespectedGameType is a paid mutator transaction binding the contract method 0x7fc48504. +// +// Solidity: function setRespectedGameType(uint32 _gameType) returns() +func (_OptimismPortal2 *OptimismPortal2Session) SetRespectedGameType(_gameType uint32) (*types.Transaction, error) { + return _OptimismPortal2.Contract.SetRespectedGameType(&_OptimismPortal2.TransactOpts, _gameType) +} + +// SetRespectedGameType is a paid mutator transaction binding the contract method 0x7fc48504. +// +// Solidity: function setRespectedGameType(uint32 _gameType) returns() +func (_OptimismPortal2 *OptimismPortal2TransactorSession) SetRespectedGameType(_gameType uint32) (*types.Transaction, error) { + return _OptimismPortal2.Contract.SetRespectedGameType(&_OptimismPortal2.TransactOpts, _gameType) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_OptimismPortal2 *OptimismPortal2Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OptimismPortal2.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_OptimismPortal2 *OptimismPortal2Session) Receive() (*types.Transaction, error) { + return _OptimismPortal2.Contract.Receive(&_OptimismPortal2.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_OptimismPortal2 *OptimismPortal2TransactorSession) Receive() (*types.Transaction, error) { + return _OptimismPortal2.Contract.Receive(&_OptimismPortal2.TransactOpts) +} + +// OptimismPortal2InitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the OptimismPortal2 contract. +type OptimismPortal2InitializedIterator struct { + Event *OptimismPortal2Initialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OptimismPortal2InitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OptimismPortal2Initialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OptimismPortal2Initialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OptimismPortal2InitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OptimismPortal2InitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OptimismPortal2Initialized represents a Initialized event raised by the OptimismPortal2 contract. +type OptimismPortal2Initialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_OptimismPortal2 *OptimismPortal2Filterer) FilterInitialized(opts *bind.FilterOpts) (*OptimismPortal2InitializedIterator, error) { + + logs, sub, err := _OptimismPortal2.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &OptimismPortal2InitializedIterator{contract: _OptimismPortal2.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_OptimismPortal2 *OptimismPortal2Filterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *OptimismPortal2Initialized) (event.Subscription, error) { + + logs, sub, err := _OptimismPortal2.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OptimismPortal2Initialized) + if err := _OptimismPortal2.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_OptimismPortal2 *OptimismPortal2Filterer) ParseInitialized(log types.Log) (*OptimismPortal2Initialized, error) { + event := new(OptimismPortal2Initialized) + if err := _OptimismPortal2.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// OptimismPortal2TransactionDepositedIterator is returned from FilterTransactionDeposited and is used to iterate over the raw logs and unpacked data for TransactionDeposited events raised by the OptimismPortal2 contract. +type OptimismPortal2TransactionDepositedIterator struct { + Event *OptimismPortal2TransactionDeposited // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OptimismPortal2TransactionDepositedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OptimismPortal2TransactionDeposited) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OptimismPortal2TransactionDeposited) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OptimismPortal2TransactionDepositedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OptimismPortal2TransactionDepositedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OptimismPortal2TransactionDeposited represents a TransactionDeposited event raised by the OptimismPortal2 contract. +type OptimismPortal2TransactionDeposited struct { + From common.Address + To common.Address + Version *big.Int + OpaqueData []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransactionDeposited is a free log retrieval operation binding the contract event 0xb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32. +// +// Solidity: event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData) +func (_OptimismPortal2 *OptimismPortal2Filterer) FilterTransactionDeposited(opts *bind.FilterOpts, from []common.Address, to []common.Address, version []*big.Int) (*OptimismPortal2TransactionDepositedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + var versionRule []interface{} + for _, versionItem := range version { + versionRule = append(versionRule, versionItem) + } + + logs, sub, err := _OptimismPortal2.contract.FilterLogs(opts, "TransactionDeposited", fromRule, toRule, versionRule) + if err != nil { + return nil, err + } + return &OptimismPortal2TransactionDepositedIterator{contract: _OptimismPortal2.contract, event: "TransactionDeposited", logs: logs, sub: sub}, nil +} + +// WatchTransactionDeposited is a free log subscription operation binding the contract event 0xb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32. +// +// Solidity: event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData) +func (_OptimismPortal2 *OptimismPortal2Filterer) WatchTransactionDeposited(opts *bind.WatchOpts, sink chan<- *OptimismPortal2TransactionDeposited, from []common.Address, to []common.Address, version []*big.Int) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + var versionRule []interface{} + for _, versionItem := range version { + versionRule = append(versionRule, versionItem) + } + + logs, sub, err := _OptimismPortal2.contract.WatchLogs(opts, "TransactionDeposited", fromRule, toRule, versionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OptimismPortal2TransactionDeposited) + if err := _OptimismPortal2.contract.UnpackLog(event, "TransactionDeposited", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransactionDeposited is a log parse operation binding the contract event 0xb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32. +// +// Solidity: event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData) +func (_OptimismPortal2 *OptimismPortal2Filterer) ParseTransactionDeposited(log types.Log) (*OptimismPortal2TransactionDeposited, error) { + event := new(OptimismPortal2TransactionDeposited) + if err := _OptimismPortal2.contract.UnpackLog(event, "TransactionDeposited", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// OptimismPortal2WithdrawalFinalizedIterator is returned from FilterWithdrawalFinalized and is used to iterate over the raw logs and unpacked data for WithdrawalFinalized events raised by the OptimismPortal2 contract. +type OptimismPortal2WithdrawalFinalizedIterator struct { + Event *OptimismPortal2WithdrawalFinalized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OptimismPortal2WithdrawalFinalizedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OptimismPortal2WithdrawalFinalized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OptimismPortal2WithdrawalFinalized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OptimismPortal2WithdrawalFinalizedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OptimismPortal2WithdrawalFinalizedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OptimismPortal2WithdrawalFinalized represents a WithdrawalFinalized event raised by the OptimismPortal2 contract. +type OptimismPortal2WithdrawalFinalized struct { + WithdrawalHash [32]byte + Success bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdrawalFinalized is a free log retrieval operation binding the contract event 0xdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b. +// +// Solidity: event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success) +func (_OptimismPortal2 *OptimismPortal2Filterer) FilterWithdrawalFinalized(opts *bind.FilterOpts, withdrawalHash [][32]byte) (*OptimismPortal2WithdrawalFinalizedIterator, error) { + + var withdrawalHashRule []interface{} + for _, withdrawalHashItem := range withdrawalHash { + withdrawalHashRule = append(withdrawalHashRule, withdrawalHashItem) + } + + logs, sub, err := _OptimismPortal2.contract.FilterLogs(opts, "WithdrawalFinalized", withdrawalHashRule) + if err != nil { + return nil, err + } + return &OptimismPortal2WithdrawalFinalizedIterator{contract: _OptimismPortal2.contract, event: "WithdrawalFinalized", logs: logs, sub: sub}, nil +} + +// WatchWithdrawalFinalized is a free log subscription operation binding the contract event 0xdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b. +// +// Solidity: event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success) +func (_OptimismPortal2 *OptimismPortal2Filterer) WatchWithdrawalFinalized(opts *bind.WatchOpts, sink chan<- *OptimismPortal2WithdrawalFinalized, withdrawalHash [][32]byte) (event.Subscription, error) { + + var withdrawalHashRule []interface{} + for _, withdrawalHashItem := range withdrawalHash { + withdrawalHashRule = append(withdrawalHashRule, withdrawalHashItem) + } + + logs, sub, err := _OptimismPortal2.contract.WatchLogs(opts, "WithdrawalFinalized", withdrawalHashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OptimismPortal2WithdrawalFinalized) + if err := _OptimismPortal2.contract.UnpackLog(event, "WithdrawalFinalized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseWithdrawalFinalized is a log parse operation binding the contract event 0xdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b. +// +// Solidity: event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success) +func (_OptimismPortal2 *OptimismPortal2Filterer) ParseWithdrawalFinalized(log types.Log) (*OptimismPortal2WithdrawalFinalized, error) { + event := new(OptimismPortal2WithdrawalFinalized) + if err := _OptimismPortal2.contract.UnpackLog(event, "WithdrawalFinalized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// OptimismPortal2WithdrawalProvenIterator is returned from FilterWithdrawalProven and is used to iterate over the raw logs and unpacked data for WithdrawalProven events raised by the OptimismPortal2 contract. +type OptimismPortal2WithdrawalProvenIterator struct { + Event *OptimismPortal2WithdrawalProven // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OptimismPortal2WithdrawalProvenIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OptimismPortal2WithdrawalProven) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OptimismPortal2WithdrawalProven) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OptimismPortal2WithdrawalProvenIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OptimismPortal2WithdrawalProvenIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OptimismPortal2WithdrawalProven represents a WithdrawalProven event raised by the OptimismPortal2 contract. +type OptimismPortal2WithdrawalProven struct { + WithdrawalHash [32]byte + From common.Address + To common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdrawalProven is a free log retrieval operation binding the contract event 0x67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f62. +// +// Solidity: event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to) +func (_OptimismPortal2 *OptimismPortal2Filterer) FilterWithdrawalProven(opts *bind.FilterOpts, withdrawalHash [][32]byte, from []common.Address, to []common.Address) (*OptimismPortal2WithdrawalProvenIterator, error) { + + var withdrawalHashRule []interface{} + for _, withdrawalHashItem := range withdrawalHash { + withdrawalHashRule = append(withdrawalHashRule, withdrawalHashItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _OptimismPortal2.contract.FilterLogs(opts, "WithdrawalProven", withdrawalHashRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &OptimismPortal2WithdrawalProvenIterator{contract: _OptimismPortal2.contract, event: "WithdrawalProven", logs: logs, sub: sub}, nil +} + +// WatchWithdrawalProven is a free log subscription operation binding the contract event 0x67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f62. +// +// Solidity: event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to) +func (_OptimismPortal2 *OptimismPortal2Filterer) WatchWithdrawalProven(opts *bind.WatchOpts, sink chan<- *OptimismPortal2WithdrawalProven, withdrawalHash [][32]byte, from []common.Address, to []common.Address) (event.Subscription, error) { + + var withdrawalHashRule []interface{} + for _, withdrawalHashItem := range withdrawalHash { + withdrawalHashRule = append(withdrawalHashRule, withdrawalHashItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _OptimismPortal2.contract.WatchLogs(opts, "WithdrawalProven", withdrawalHashRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OptimismPortal2WithdrawalProven) + if err := _OptimismPortal2.contract.UnpackLog(event, "WithdrawalProven", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseWithdrawalProven is a log parse operation binding the contract event 0x67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f62. +// +// Solidity: event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to) +func (_OptimismPortal2 *OptimismPortal2Filterer) ParseWithdrawalProven(log types.Log) (*OptimismPortal2WithdrawalProven, error) { + event := new(OptimismPortal2WithdrawalProven) + if err := _OptimismPortal2.contract.UnpackLog(event, "WithdrawalProven", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-bindings/bindingspreview/optimismportal2_more.go b/op-bindings/bindingspreview/optimismportal2_more.go new file mode 100644 index 000000000000..e3116244ee04 --- /dev/null +++ b/op-bindings/bindingspreview/optimismportal2_more.go @@ -0,0 +1,27 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindingspreview + +import ( + "encoding/json" + + "github.com/ethereum-optimism/optimism/op-bindings/solc" +) + +const OptimismPortal2StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"params\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_struct(ResourceParams)1021_storage\"},{\"astId\":1003,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_array(t_uint256)48_storage\"},{\"astId\":1004,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"l2Sender\",\"offset\":0,\"slot\":\"50\",\"type\":\"t_address\"},{\"astId\":1005,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"finalizedWithdrawals\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1006,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"spacer_52_0_32\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_bytes32\"},{\"astId\":1007,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"spacer_53_0_1\",\"offset\":0,\"slot\":\"53\",\"type\":\"t_bool\"},{\"astId\":1008,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"superchainConfig\",\"offset\":1,\"slot\":\"53\",\"type\":\"t_contract(SuperchainConfig)1018\"},{\"astId\":1009,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"spacer_54_0_20\",\"offset\":0,\"slot\":\"54\",\"type\":\"t_address\"},{\"astId\":1010,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"systemConfig\",\"offset\":0,\"slot\":\"55\",\"type\":\"t_contract(SystemConfig)1019\"},{\"astId\":1011,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"disputeGameFactory\",\"offset\":0,\"slot\":\"56\",\"type\":\"t_contract(DisputeGameFactory)1016\"},{\"astId\":1012,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"provenWithdrawals\",\"offset\":0,\"slot\":\"57\",\"type\":\"t_mapping(t_bytes32,t_struct(ProvenWithdrawal)1020_storage)\"},{\"astId\":1013,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"disputeGameBlacklist\",\"offset\":0,\"slot\":\"58\",\"type\":\"t_mapping(t_contract(IDisputeGame)1017,t_bool)\"},{\"astId\":1014,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"respectedGameType\",\"offset\":0,\"slot\":\"59\",\"type\":\"t_userDefinedValueType(GameType)1022\"},{\"astId\":1015,\"contract\":\"src/L1/OptimismPortal2.sol:OptimismPortal2\",\"label\":\"respectedGameTypeUpdatedAt\",\"offset\":4,\"slot\":\"59\",\"type\":\"t_uint64\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)48_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[48]\",\"numberOfBytes\":\"1536\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_contract(DisputeGameFactory)1016\":{\"encoding\":\"inplace\",\"label\":\"contract DisputeGameFactory\",\"numberOfBytes\":\"20\"},\"t_contract(IDisputeGame)1017\":{\"encoding\":\"inplace\",\"label\":\"contract IDisputeGame\",\"numberOfBytes\":\"20\"},\"t_contract(SuperchainConfig)1018\":{\"encoding\":\"inplace\",\"label\":\"contract SuperchainConfig\",\"numberOfBytes\":\"20\"},\"t_contract(SystemConfig)1019\":{\"encoding\":\"inplace\",\"label\":\"contract SystemConfig\",\"numberOfBytes\":\"20\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_mapping(t_bytes32,t_struct(ProvenWithdrawal)1020_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e struct OptimismPortal2.ProvenWithdrawal)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_struct(ProvenWithdrawal)1020_storage\"},\"t_mapping(t_contract(IDisputeGame)1017,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(contract IDisputeGame =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_contract(IDisputeGame)1017\",\"value\":\"t_bool\"},\"t_struct(ProvenWithdrawal)1020_storage\":{\"encoding\":\"inplace\",\"label\":\"struct OptimismPortal2.ProvenWithdrawal\",\"numberOfBytes\":\"32\"},\"t_struct(ResourceParams)1021_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ResourceMetering.ResourceParams\",\"numberOfBytes\":\"32\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"},\"t_userDefinedValueType(GameType)1022\":{\"encoding\":\"inplace\",\"label\":\"GameType\",\"numberOfBytes\":\"4\"}}}" + +var OptimismPortal2StorageLayout = new(solc.StorageLayout) + +var OptimismPortal2DeployedBin = "0x6080604052600436106101a55760003560e01c80638b4c40b0116100e1578063bf653a5c1161008a578063e965084c11610064578063e965084c146105f1578063e9e05c421461068d578063f0498750146106a0578063f2b4e617146106cb57600080fd5b8063bf653a5c146104fd578063c0c53b8b14610530578063cff0ab961461055057600080fd5b80639bf62d82116100bb5780639bf62d8214610480578063a14238e7146104ad578063a35d99df146104dd57600080fd5b80638b4c40b0146101ca5780638c3152e914610423578063952b27971461044357600080fd5b80634fd0434c1161014e578063724c184c11610128578063724c184c146103ae5780637af1906d146103c35780637d6be8dc146103e35780637fc485041461040357600080fd5b80634fd0434c1461030157806354fd4d50146103435780635c975abb1461039957600080fd5b8063452a93201161017f578063452a93201461028c57806345884d32146102a15780634870496f146102e157600080fd5b806333d7e2bd146101d157806335e80ab3146102285780633c9f397c1461025a57600080fd5b366101cc576101ca3334620186a06000604051806020016040528060008152506106f8565b005b600080fd5b3480156101dd57600080fd5b506037546101fe9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561023457600080fd5b506035546101fe90610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561026657600080fd5b50603b546102779063ffffffff1681565b60405163ffffffff909116815260200161021f565b34801561029857600080fd5b506101fe610993565b3480156102ad57600080fd5b506102d16102bc366004614ecb565b603a6020526000908152604090205460ff1681565b604051901515815260200161021f565b3480156102ed57600080fd5b506101ca6102fc3660046150a3565b610a2b565b34801561030d57600080fd5b50603b5461032a90640100000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161021f565b34801561034f57600080fd5b5061038c6040518060400160405280600581526020017f332e332e3000000000000000000000000000000000000000000000000000000081525081565b60405161021f91906151f5565b3480156103a557600080fd5b506102d161129c565b3480156103ba57600080fd5b506101fe61132f565b3480156103cf57600080fd5b506101ca6103de366004615208565b611339565b3480156103ef57600080fd5b506101ca6103fe366004614ecb565b611b61565b34801561040f57600080fd5b506101ca61041e366004615233565b611c72565b34801561042f57600080fd5b506101ca61043e366004615250565b611da8565b34801561044f57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405190815260200161021f565b34801561048c57600080fd5b506032546101fe9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104b957600080fd5b506102d16104c8366004615208565b60336020526000908152604090205460ff1681565b3480156104e957600080fd5b5061032a6104f83660046152a3565b612085565b34801561050957600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610472565b34801561053c57600080fd5b506101ca61054b3660046152c0565b6120a4565b34801561055c57600080fd5b506001546105b8906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff928316602085015291169082015260600161021f565b3480156105fd57600080fd5b5061065861060c366004615208565b60396020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900467ffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835267ffffffffffffffff90911660208301520161021f565b6101ca61069b366004615319565b6106f8565b3480156106ac57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101fe565b3480156106d757600080fd5b506038546101fe9073ffffffffffffffffffffffffffffffffffffffff1681565b8260005a905083156107af5773ffffffffffffffffffffffffffffffffffffffff8716156107af57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6107b98351612085565b67ffffffffffffffff168567ffffffffffffffff16101561085c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c000000000000000000000000000000000000000000000000000000000060648201526084016107a6565b6201d4c0835111156108ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c61726765000060448201526064016107a6565b333281146108eb575033731111000000000000000000000000000000001111015b60003488888888604051602001610906959493929190615398565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161097691906151f5565b60405180910390a4505061098a828261230d565b50505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2691906153fd565b905090565b610a3361129c565b15610a9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a207061757365640000000000000000000060448201526064016107a6565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610b59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e74726163740060648201526084016107a6565b6038546040517fbb8aa1fc00000000000000000000000000000000000000000000000000000000815260048101869052600091829173ffffffffffffffffffffffffffffffffffffffff9091169063bb8aa1fc90602401606060405180830381865afa158015610bcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf1919061541a565b925050915060008173ffffffffffffffffffffffffffffffffffffffff1663bcef3b556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c67919061545c565b603b5490915060ff848116911614610d01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a20696e76616c69642067616d652074797060448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084016107a6565b610d18610d1336889003880188615475565b61263a565b8114610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084016107a6565b6000610db189612696565b60008181526039602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff81168084527401000000000000000000000000000000000000000090910467ffffffffffffffff169183018290529293509091901580610ea0575060018173ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8d919061550a565b6002811115610e9e57610e9e6154db565b145b80610ed0575073ffffffffffffffffffffffffffffffffffffffff81166000908152603a602052604090205460ff165b80610f635750603b5463ffffffff1660ff16610f5d8273ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f54919061552b565b63ffffffff1690565b60ff1614155b611015576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152606060248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e2c20616e642074686560648201527f206f6c6420646973707574652067616d65206973206e6f7420696e76616c6964608482015260a4016107a6565b60408051602081018590526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506110de9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152906110d48b8d615548565b8d604001356126c6565b61116a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f66000000000000000000000000000060648201526084016107a6565b60405180604001604052808773ffffffffffffffffffffffffffffffffffffffff1681526020014267ffffffffffffffff168152506039600086815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050508b6040015173ffffffffffffffffffffffffffffffffffffffff168c6020015173ffffffffffffffffffffffffffffffffffffffff16857f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f6260405160405180910390a4505050505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2691906155cc565b6000610a26610993565b600081815260396020908152604080832081518083018352905473ffffffffffffffffffffffffffffffffffffffff81168083527401000000000000000000000000000000000000000090910467ffffffffffffffff1682850152808552603a90935292205460ff161561142f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652068617360448201527f206265656e20626c61636b6c697374656400000000000000000000000000000060648201526084016107a6565b816020015167ffffffffffffffff166000036114cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e20796574000000000000000000000000000060648201526084016107a6565b600061154e8273ffffffffffffffffffffffffffffffffffffffff1663cf09e0d06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561151d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154191906155e9565b67ffffffffffffffff1690565b90508067ffffffffffffffff16836020015167ffffffffffffffff161161161d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e20646973707574652067616d65206372656160648201527f74696f6e2074696d657374616d70000000000000000000000000000000000000608482015260a4016107a6565b7f0000000000000000000000000000000000000000000000000000000000000000836020015167ffffffffffffffff16426116589190615635565b116116e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c20686173206e6f74206d61747572656420796574000000000000000000000060648201526084016107a6565b60028273ffffffffffffffffffffffffffffffffffffffff1663200d2ed26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611732573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611756919061550a565b6002811115611767576117676154db565b146117f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f686173206e6f74206265656e2066696e616c697a65642079657400000000000060648201526084016107a6565b603b5463ffffffff1660ff1661184e8373ffffffffffffffffffffffffffffffffffffffff1663bbdc02db6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f30573d6000803e3d6000fd5b60ff16146118de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a20696e76616c69642067616d652074797060448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084016107a6565b603b5467ffffffffffffffff640100000000909104811690821610156119ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a20646973707574652067616d652063726560448201527f61746564206265666f7265207265737065637465642067616d6520747970652060648201527f7761732075706461746564000000000000000000000000000000000000000000608482015260a4016107a6565b7f0000000000000000000000000000000000000000000000000000000000000000611a1b8373ffffffffffffffffffffffffffffffffffffffff166319effeb46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561151d573d6000803e3d6000fd5b611a2f9067ffffffffffffffff1642615635565b11611abc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f696e206169722d6761700000000000000000000000000000000000000000000060648201526084016107a6565b60008481526033602052604090205460ff1615611b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a6564000000000000000000000060648201526084016107a6565b50505050565b611b69610993565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4f7074696d69736d506f7274616c3a206f6e6c7920746865206775617264696160448201527f6e2063616e20626c61636b6c69737420646973707574652067616d657300000060648201526084016107a6565b73ffffffffffffffffffffffffffffffffffffffff166000908152603a6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b611c7a610993565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4f7074696d69736d506f7274616c3a206f6e6c7920746865206775617264696160448201527f6e2063616e2073657420746865207265737065637465642067616d652074797060648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016107a6565b603b805463ffffffff929092167fffffffffffffffffffffffffffffffffffffffff000000000000000000000000909216919091176401000000004267ffffffffffffffff1602179055565b565b611db061129c565b15611e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a207061757365640000000000000000000060448201526064016107a6565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14611ec0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e0060648201526084016107a6565b6000611ecb82612696565b9050611ed681611339565b600081815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908401516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558301516080840151606085015160a0860151611f78939291906126ea565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611fdd90841515815260200190565b60405180910390a280158015611ff35750326001145b15612080576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f640000000000000000000000000000000000000000000000000000000000000060648201526084016107a6565b505050565b600061209282601061564c565b61209e9061520861567c565b92915050565b600054610100900460ff16158080156120c45750600054600160ff909116105b806120de5750303b1580156120de575060005460ff166001145b61216a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107a6565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156121c857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff16610100858416021790556032541661228157603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b612289612748565b8015611b5b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090612343907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615635565b9050600061234f61285b565b90506000816020015160ff16826000015163ffffffff1661237091906156d7565b905082156124a7576001546000906123a7908390700100000000000000000000000000000000900467ffffffffffffffff1661573f565b90506000836040015160ff16836123be91906157b3565b6001546123de9084906fffffffffffffffffffffffffffffffff166157b3565b6123e891906156d7565b600154909150600090612439906124129084906fffffffffffffffffffffffffffffffff1661586f565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff1661291c565b905060018611156124685761246561241282876040015160ff1660018a6124609190615635565b61293b565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548691906010906124da908490700100000000000000000000000000000000900467ffffffffffffffff1661567c565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156125bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d6974000060648201526084016107a6565b6001546000906125e9906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166158e3565b905060006125fb48633b9aca00612990565b6126059083615920565b905060005a6126149088615635565b9050808211156126305761263061262b8284615635565b6129a7565b5050505050505050565b60008160000151826020015183604001518460600151604051602001612679949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097612679979096959101615934565b6000806126d2866129d0565b90506126e081868686612a02565b9695505050505050565b60008060006126fa866000612a32565b905080612730576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166127df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107a6565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff16600003611da65760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156128f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2691906159a1565b600061293161292b8585612a50565b83612a60565b90505b9392505050565b6000670de0b6b3a764000061297c61295385836156d7565b61296590670de0b6b3a764000061573f565b61297785670de0b6b3a76400006157b3565b612a6f565b61298690866157b3565b61293191906156d7565b6000818310156129a05781612934565b5090919050565b6000805a90505b825a6129ba9083615635565b1015612080576129c982615a5d565b91506129ae565b606081805190602001206040516020016129ec91815260200190565b6040516020818303038152906040529050919050565b6000612a2984612a13878686612aa0565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156129a05781612934565b60008183126129a05781612934565b6000612934670de0b6b3a764000083612a878661351e565b612a9191906157b3565b612a9b91906156d7565b613762565b60606000845111612b0d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b6579000000000000000000000060448201526064016107a6565b6000612b18846139a1565b90506000612b2586613a8d565b9050600084604051602001612b3c91815260200190565b60405160208183030381529060405290506000805b8451811015613495576000858281518110612b6e57612b6e615a95565b602002602001015190508451831115612c09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e67746800000000000000000000000000000000000060648201526084016107a6565b82600003612cc25780518051602091820120604051612c5792612c3192910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612cbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016107a6565b612e19565b805151602011612d785780518051602091820120604051612cec92612c3192910190815260200190565b612cbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016107a6565b805184516020808701919091208251919092012014612e19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016107a6565b612e2560106001615ac4565b816020015151036130015784518303612f9957612e5f8160200151601081518110612e5257612e52615a95565b6020026020010151613af0565b96506000875111612ef2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e636829000000000060648201526084016107a6565b60018651612f009190615635565b8214612f8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e63682900000000000060648201526084016107a6565b505050505050612934565b6000858481518110612fad57612fad615a95565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612fd857612fd8615a95565b60200260200101519050612feb81613c50565b9550612ff8600186615ac4565b94505050613482565b6002816020015151036133fa57600061301982613c75565b905060008160008151811061303057613030615a95565b016020015160f81c90506000613047600283615adc565b613052906002615afe565b90506000613063848360ff16613c99565b905060006130718a89613c99565b9050600061307f8383613ccf565b905080835114613111576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b657900000000000060648201526084016107a6565b60ff851660021480613126575060ff85166003145b1561331557808251146131bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e64657200000060648201526084016107a6565b6131d58760200151600181518110612e5257612e52615a95565b9c5060008d5111613268576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c656166290000000000000060648201526084016107a6565b60018c516132769190615635565b8814613304576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c65616629000000000000000060648201526084016107a6565b505050505050505050505050612934565b60ff85161580613328575060ff85166001145b1561336757613354876020015160018151811061334757613347615a95565b6020026020010151613c50565b9950613360818a615ac4565b98506133ef565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016107a6565b505050505050613482565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016107a6565b508061348d81615a5d565b915050612b51565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e747300000000000000000000000000000000000000000000000000000060648201526084016107a6565b6000808213613589576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016107a6565b6000606061359684613d83565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361379357506000919050565b680755bf798b4a1bf1e58212613805576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016107a6565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156139bf576139bf614ee8565b604051908082528060200260200182016040528015613a0457816020015b60408051808201909152606080825260208201528152602001906001900390816139dd5790505b50915060005b81811015613a86576040518060400160405280858381518110613a2f57613a2f615a95565b60200260200101518152602001613a5e868481518110613a5157613a51615a95565b6020026020010151613e59565b815250838281518110613a7357613a73615a95565b6020908102919091010152600101613a0a565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613ae5578060011b82018184015160001a8060041c8253600f811660018301535050600101613ab7565b509295945050505050565b60606000806000613b0085613e6c565b919450925090506000816001811115613b1b57613b1b6154db565b14613ba8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d0000000000000060648201526084016107a6565b613bb28284615ac4565b855114613c41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e64657200000000000000000000000060648201526084016107a6565b612a29856020015184846148d9565b60606020826000015110613c6c57613c6782613af0565b61209e565b61209e8261496d565b606061209e613c948360200151600081518110612e5257612e52615a95565b613a8d565b606082518210613cb8575060408051602081019091526000815261209e565b6129348383848651613cca9190615635565b614983565b6000808251845110613ce2578251613ce5565b83515b90505b8082108015613d6c5750828281518110613d0457613d04615a95565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613d4357613d43615a95565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613d7c57816001019150613ce8565b5092915050565b6000808211613dee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016107a6565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061209e613e6783614b5b565b614c44565b600080600080846000015111613f2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a4016107a6565b6020840151805160001a607f8111613f4f5760006001600094509450945050506148d2565b60b7811161415d576000613f64608083615635565b90508087600001511161401f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a4016107a6565b6001838101517fff0000000000000000000000000000000000000000000000000000000000000016908214158061409857507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b61414a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a4016107a6565b50600195509350600092506148d2915050565b60bf81116144ab57600061417260b783615635565b90508087600001511161422d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a4016107a6565b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361430b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a4016107a6565b600184015160088302610100031c603781116143cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a4016107a6565b6143d98184615ac4565b89511161448e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a4016107a6565b614499836001615ac4565b97509550600094506148d29350505050565b60f7811161458c5760006144c060c083615635565b90508087600001511161457b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a4016107a6565b6001955093508492506148d2915050565b600061459960f783615635565b905080876000015111614654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a4016107a6565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614732576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a4016107a6565b600184015160088302610100031c603781116147f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a4016107a6565b6148008184615ac4565b8951116148b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a4016107a6565b6148c0836001615ac4565b97509550600194506148d29350505050565b9193909250565b60608167ffffffffffffffff8111156148f4576148f4614ee8565b6040519080825280601f01601f19166020018201604052801561491e576020820181803683370190505b50905081156129345760006149338486615ac4565b90506020820160005b8481101561495457828101518282015260200161493c565b84811115614963576000858301525b5050509392505050565b606061209e8260200151600084600001516148d9565b60608182601f0110156149f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016107a6565b828284011015614a5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016107a6565b81830184511015614acb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016107a6565b606082158015614aea5760405191506000825260208201604052614b52565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614b23578051835260209283019201614b0b565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201526000825111614c26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a4016107a6565b50604080518082019091528151815260209182019181019190915290565b60606000806000614c5485613e6c565b919450925090506001816001811115614c6f57614c6f6154db565b14614cfc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d000000000000000060648201526084016107a6565b8451614d088385615ac4565b14614d95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e646572000000000000000000000000000060648201526084016107a6565b604080516020808252610420820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081614dac5790505093506000835b8651811015614e9a57600080614e1f6040518060400160405280858c60000151614e039190615635565b8152602001858c60200151614e189190615ac4565b9052613e6c565b509150915060405180604001604052808383614e3b9190615ac4565b8152602001848b60200151614e509190615ac4565b815250888581518110614e6557614e65615a95565b6020908102919091010152614e7b600185615ac4565b9350614e878183615ac4565b614e919084615ac4565b92505050614dd9565b50845250919392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114614ec857600080fd5b50565b600060208284031215614edd57600080fd5b813561293481614ea6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614f5e57614f5e614ee8565b604052919050565b600082601f830112614f7757600080fd5b813567ffffffffffffffff811115614f9157614f91614ee8565b614fc260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614f17565b818152846020838601011115614fd757600080fd5b816020850160208301376000918101602001919091529392505050565b600060c0828403121561500657600080fd5b60405160c0810167ffffffffffffffff828210818311171561502a5761502a614ee8565b81604052829350843583526020850135915061504582614ea6565b8160208401526040850135915061505b82614ea6565b816040840152606085013560608401526080850135608084015260a085013591508082111561508957600080fd5b5061509685828601614f66565b60a0830152505092915050565b600080600080600085870360e08112156150bc57600080fd5b863567ffffffffffffffff808211156150d457600080fd5b6150e08a838b01614ff4565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08401121561511957600080fd5b60408901955060c089013592508083111561513357600080fd5b828901925089601f84011261514757600080fd5b823591508082111561515857600080fd5b508860208260051b840101111561516e57600080fd5b959894975092955050506020019190565b60005b8381101561519a578181015183820152602001615182565b83811115611b5b5750506000910152565b600081518084526151c381602086016020860161517f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061293460208301846151ab565b60006020828403121561521a57600080fd5b5035919050565b63ffffffff81168114614ec857600080fd5b60006020828403121561524557600080fd5b813561293481615221565b60006020828403121561526257600080fd5b813567ffffffffffffffff81111561527957600080fd5b61528584828501614ff4565b949350505050565b67ffffffffffffffff81168114614ec857600080fd5b6000602082840312156152b557600080fd5b81356129348161528d565b6000806000606084860312156152d557600080fd5b83356152e081614ea6565b925060208401356152f081614ea6565b9150604084013561530081614ea6565b809150509250925092565b8015158114614ec857600080fd5b600080600080600060a0868803121561533157600080fd5b853561533c81614ea6565b94506020860135935060408601356153538161528d565b925060608601356153638161530b565b9150608086013567ffffffffffffffff81111561537f57600080fd5b61538b88828901614f66565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516153ec81604985016020870161517f565b919091016049019695505050505050565b60006020828403121561540f57600080fd5b815161293481614ea6565b60008060006060848603121561542f57600080fd5b835161543a81615221565b602085015190935061544b8161528d565b604085015190925061530081614ea6565b60006020828403121561546e57600080fd5b5051919050565b60006080828403121561548757600080fd5b6040516080810181811067ffffffffffffffff821117156154aa576154aa614ee8565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006020828403121561551c57600080fd5b81516003811061293457600080fd5b60006020828403121561553d57600080fd5b815161293481615221565b600067ffffffffffffffff8084111561556357615563614ee8565b8360051b6020615574818301614f17565b86815291850191818101903684111561558c57600080fd5b865b848110156155c0578035868111156155a65760008081fd5b6155b236828b01614f66565b84525091830191830161558e565b50979650505050505050565b6000602082840312156155de57600080fd5b81516129348161530b565b6000602082840312156155fb57600080fd5b81516129348161528d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561564757615647615606565b500390565b600067ffffffffffffffff8083168185168183048111821515161561567357615673615606565b02949350505050565b600067ffffffffffffffff80831681851680830382111561569f5761569f615606565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826156e6576156e66156a8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561573a5761573a615606565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561577957615779615606565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156157ad576157ad615606565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156157f4576157f4615606565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561582f5761582f615606565b6000871292508782058712848416161561584b5761584b615606565b8785058712818416161561586157615861615606565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156158a9576158a9615606565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156158dd576158dd615606565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561591b5761591b615606565b500290565b60008261592f5761592f6156a8565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261597f60c08301846151ab565b98975050505050505050565b805160ff8116811461599c57600080fd5b919050565b600060c082840312156159b357600080fd5b60405160c0810181811067ffffffffffffffff821117156159d6576159d6614ee8565b60405282516159e481615221565b81526159f26020840161598b565b6020820152615a036040840161598b565b60408201526060830151615a1681615221565b60608201526080830151615a2981615221565b608082015260a08301516fffffffffffffffffffffffffffffffff81168114615a5157600080fd5b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615a8e57615a8e615606565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008219821115615ad757615ad7615606565b500190565b600060ff831680615aef57615aef6156a8565b8060ff84160691505092915050565b600060ff821660ff841680821015615b1857615b18615606565b9003939250505056fea164736f6c634300080f000a" + + +func init() { + if err := json.Unmarshal([]byte(OptimismPortal2StorageLayoutJSON), OptimismPortal2StorageLayout); err != nil { + panic(err) + } + + layouts["OptimismPortal2"] = OptimismPortal2StorageLayout + deployedBytecodes["OptimismPortal2"] = OptimismPortal2DeployedBin + immutableReferences["OptimismPortal2"] = true +} diff --git a/op-bindings/bindingspreview/registry.go b/op-bindings/bindingspreview/registry.go new file mode 100644 index 000000000000..179f5761f025 --- /dev/null +++ b/op-bindings/bindingspreview/registry.go @@ -0,0 +1,128 @@ +package bindingspreview + +import ( + "fmt" + "strings" + + "github.com/ethereum-optimism/superchain-registry/superchain" + + "github.com/ethereum-optimism/optimism/op-bindings/solc" + "github.com/ethereum/go-ethereum/common" +) + +// layouts represents the set of storage layouts. It is populated in an init function. +var layouts = make(map[string]*solc.StorageLayout) + +// deployedBytecodes represents the set of deployed bytecodes. It is populated +// in an init function. +var deployedBytecodes = make(map[string]string) + +var initBytecodes = make(map[string]string) +var deploymentSalts = make(map[string]string) +var deployers = make(map[string]string) + +// immutableReferences represents the set of immutable references. It is populated +// in an init function. +var immutableReferences = make(map[string]bool) + +// Create2DeployerCodeHash represents the codehash of the Create2Deployer contract. +var Create2DeployerCodeHash = common.HexToHash("0xb0550b5b431e30d38000efb7107aaa0ade03d48a7198a140edda9d27134468b2") + +func init() { + code, err := superchain.LoadContractBytecode(superchain.Hash(Create2DeployerCodeHash)) + if err != nil { + panic(err) + } + deployedBytecodes["Create2Deployer"] = common.Bytes2Hex(code) +} + +// GetStorageLayout returns the storage layout of a contract by name. +func GetStorageLayout(name string) (*solc.StorageLayout, error) { + layout := layouts[name] + if layout == nil { + return nil, fmt.Errorf("%s: storage layout not found", name) + } + return layout, nil +} + +// GetDeployedBytecode returns the deployed bytecode of a contract by name. +func GetDeployedBytecode(name string) ([]byte, error) { + bc := deployedBytecodes[name] + if bc == "" { + return nil, fmt.Errorf("%s: deployed bytecode not found", name) + } + + if !isHex(bc) { + return nil, fmt.Errorf("%s: invalid deployed bytecode", name) + } + + return common.FromHex(bc), nil +} + +// HasImmutableReferences returns the immutable references of a contract by name. +func HasImmutableReferences(name string) (bool, error) { + has, ok := immutableReferences[name] + if !ok { + return false, fmt.Errorf("%s: immutable reference not found", name) + } + return has, nil +} + +func GetInitBytecode(name string) ([]byte, error) { + bc := initBytecodes[name] + if bc == "" { + return nil, fmt.Errorf("%s: init bytecode not found", name) + } + + if !isHex(bc) { + return nil, fmt.Errorf("%s: invalid init bytecode", name) + } + + return common.FromHex(bc), nil +} + +func GetDeployerAddress(name string) ([]byte, error) { + addr := deployers[name] + if addr == "" { + return nil, fmt.Errorf("%s: deployer address not found", name) + } + + if !common.IsHexAddress(addr) { + return nil, fmt.Errorf("%s: invalid deployer address", name) + } + + return common.FromHex(addr), nil +} + +func GetDeploymentSalt(name string) ([]byte, error) { + salt := deploymentSalts[name] + if salt == "" { + return nil, fmt.Errorf("%s: deployment salt not found", name) + } + + if !isHex(salt) { + return nil, fmt.Errorf("%s: invalid deployment salt", name) + } + + return common.FromHex(salt), nil +} + +// isHexCharacter returns bool of c being a valid hexadecimal. +func isHexCharacter(c byte) bool { + return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') +} + +// isHex validates whether each byte is valid hexadecimal string. +func isHex(str string) bool { + if len(str)%2 != 0 { + return false + } + str = strings.TrimPrefix(str, "0x") + + for _, c := range []byte(str) { + if !isHexCharacter(c) { + return false + } + } + return true +} diff --git a/op-bindings/cmd/main.go b/op-bindings/cmd/main.go new file mode 100644 index 000000000000..8c14f4fcda1d --- /dev/null +++ b/op-bindings/cmd/main.go @@ -0,0 +1,236 @@ +package main + +import ( + "fmt" + "os" + + "github.com/ethereum-optimism/optimism/op-bindings/bindgen" + "github.com/ethereum-optimism/optimism/op-bindings/etherscan" + op_service "github.com/ethereum-optimism/optimism/op-service" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" +) + +const ( + // Base Flags + MetadataOutFlagName = "metadata-out" + BindingsPackageNameFlagName = "bindings-package" + ContractsListFlagName = "contracts-list" + + // Local Contracts Flags + SourceMapsListFlagName = "source-maps-list" + ForgeArtifactsFlagName = "forge-artifacts" + + // Remote Contracts Flags + EtherscanApiKeyEthFlagName = "etherscan.apikey.eth" + EtherscanApiKeyOpFlagName = "etherscan.apikey.op" + RpcUrlEthFlagName = "rpc.url.eth" + RpcUrlOpFlagName = "rpc.url.op" +) + +func main() { + oplog.SetupDefaults() + + app := &cli.App{ + Name: "BindGen", + Usage: "Generate contract bindings using Foundry artifacts and/or remotely sourced contract data", + Commands: []*cli.Command{ + { + Name: "generate", + Usage: "Generate contract bindings", + Flags: baseFlags(), + Subcommands: []*cli.Command{ + { + Name: "all", + Usage: "Generate bindings for local and remote contracts", + Flags: append(localFlags(), remoteFlags()...), + Action: generateBindings, + }, + { + Name: "local", + Usage: "Generate bindings for locally sourced contracts", + Flags: localFlags(), + Action: generateBindings, + }, + { + Name: "remote", + Usage: "Generate bindings for remotely sourced contracts", + Flags: remoteFlags(), + Action: generateBindings, + }, + }, + }, + }, + } + + if err := app.Run(os.Args); err != nil { + log.Crit("BindGen error", "error", err.Error()) + } +} + +func setupLogger(c *cli.Context) log.Logger { + logger := oplog.NewLogger(oplog.AppOut(c), oplog.ReadCLIConfig(c)) + oplog.SetGlobalLogHandler(logger.Handler()) + return logger +} + +func generateBindings(c *cli.Context) error { + logger := setupLogger(c) + + switch c.Command.Name { + case "all": + localBindingsGenerator, err := parseConfigLocal(logger, c) + if err != nil { + return err + } + if err := localBindingsGenerator.GenerateBindings(); err != nil { + return fmt.Errorf("error generating local bindings: %w", err) + } + + remoteBindingsGenerator, err := parseConfigRemote(logger, c) + if err != nil { + return err + } + if err := remoteBindingsGenerator.GenerateBindings(); err != nil { + return fmt.Errorf("error generating remote bindings: %w", err) + } + + return nil + case "local": + localBindingsGenerator, err := parseConfigLocal(logger, c) + if err != nil { + return err + } + if err := localBindingsGenerator.GenerateBindings(); err != nil { + return fmt.Errorf("error generating local bindings: %w", err) + } + return nil + case "remote": + remoteBindingsGenerator, err := parseConfigRemote(logger, c) + if err != nil { + return err + } + if err := remoteBindingsGenerator.GenerateBindings(); err != nil { + return fmt.Errorf("error generating remote bindings: %w", err) + } + return nil + default: + return fmt.Errorf("unknown command: %s", c.Command.Name) + } +} + +func parseConfigBase(logger log.Logger, c *cli.Context) (bindgen.BindGenGeneratorBase, error) { + cwd, err := os.Getwd() + if err != nil { + return bindgen.BindGenGeneratorBase{}, err + } + + monoRepoPath, err := op_service.FindMonorepoRoot(cwd) + if err != nil { + return bindgen.BindGenGeneratorBase{}, err + } + + return bindgen.BindGenGeneratorBase{ + MetadataOut: c.String(MetadataOutFlagName), + BindingsPackageName: c.String(BindingsPackageNameFlagName), + MonorepoBasePath: monoRepoPath, + ContractsListPath: c.String(ContractsListFlagName), + Logger: logger, + }, nil +} + +func parseConfigLocal(logger log.Logger, c *cli.Context) (bindgen.BindGenGeneratorLocal, error) { + baseConfig, err := parseConfigBase(logger, c) + if err != nil { + return bindgen.BindGenGeneratorLocal{}, err + } + return bindgen.BindGenGeneratorLocal{ + BindGenGeneratorBase: baseConfig, + SourceMapsList: c.String(SourceMapsListFlagName), + ForgeArtifactsPath: c.String(ForgeArtifactsFlagName), + }, nil +} + +func parseConfigRemote(logger log.Logger, c *cli.Context) (bindgen.BindGenGeneratorRemote, error) { + baseConfig, err := parseConfigBase(logger, c) + if err != nil { + return bindgen.BindGenGeneratorRemote{}, err + } + generator := bindgen.BindGenGeneratorRemote{ + BindGenGeneratorBase: baseConfig, + } + + generator.ContractDataClients.Eth = etherscan.NewEthereumClient(c.String(EtherscanApiKeyEthFlagName)) + generator.ContractDataClients.Op = etherscan.NewOptimismClient(c.String(EtherscanApiKeyOpFlagName)) + + if generator.RpcClients.Eth, err = ethclient.Dial(c.String(RpcUrlEthFlagName)); err != nil { + return bindgen.BindGenGeneratorRemote{}, fmt.Errorf("error initializing Ethereum client: %w", err) + } + if generator.RpcClients.Op, err = ethclient.Dial(c.String(RpcUrlOpFlagName)); err != nil { + return bindgen.BindGenGeneratorRemote{}, fmt.Errorf("error initializing Optimism client: %w", err) + } + return generator, nil +} + +func baseFlags() []cli.Flag { + baseFlags := []cli.Flag{ + &cli.StringFlag{ + Name: MetadataOutFlagName, + Usage: "Output directory to put contract metadata files in", + Required: true, + }, + &cli.StringFlag{ + Name: BindingsPackageNameFlagName, + Usage: "Go package name given to generated bindings", + Required: true, + }, + &cli.StringFlag{ + Name: ContractsListFlagName, + Usage: "Path to file containing list of contract names to generate bindings for", + Required: true, + }, + } + + return append(baseFlags, oplog.CLIFlags("bindgen")...) +} + +func localFlags() []cli.Flag { + return []cli.Flag{ + &cli.StringFlag{ + Name: SourceMapsListFlagName, + Usage: "Comma-separated list of contracts to generate source-maps for", + }, + &cli.StringFlag{ + Name: ForgeArtifactsFlagName, + Usage: "Path to forge-artifacts directory, containing compiled contract artifacts", + Required: true, + }, + } +} + +func remoteFlags() []cli.Flag { + return []cli.Flag{ + &cli.StringFlag{ + Name: EtherscanApiKeyEthFlagName, + Usage: "API key to make queries to Etherscan for Ethereum", + Required: true, + }, + &cli.StringFlag{ + Name: EtherscanApiKeyOpFlagName, + Usage: "API key to make queries to Etherscan for Optimism", + Required: true, + }, + &cli.StringFlag{ + Name: RpcUrlEthFlagName, + Usage: "RPC URL (with API key if required) to query Ethereum", + Required: true, + }, + &cli.StringFlag{ + Name: RpcUrlOpFlagName, + Usage: "RPC URL (with API key if required) to query Optimism", + Required: true, + }, + } +} diff --git a/op-bindings/etherscan/client.go b/op-bindings/etherscan/client.go new file mode 100644 index 000000000000..5d94a4cdd859 --- /dev/null +++ b/op-bindings/etherscan/client.go @@ -0,0 +1,221 @@ +package etherscan + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "time" + + "github.com/ethereum-optimism/optimism/op-service/retry" +) + +type client struct { + baseUrl string + httpClient *http.Client +} + +type apiResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Result json.RawMessage `json:"result"` +} + +type rpcResponse struct { + JsonRpc string `json:"jsonrpc"` + Id int `json:"id"` + Result json.RawMessage `json:"result"` +} + +type Transaction struct { + Hash string `json:"hash"` + Input string `json:"input"` + To string `json:"to"` +} + +const apiMaxRetries = 3 +const apiRetryDelay = time.Duration(2) * time.Second +const errRateLimited = "Max rate limit reached" + +func NewClient(baseUrl, apiKey string) *client { + return &client{ + baseUrl: baseUrl + "/api?apikey=" + apiKey + "&", + httpClient: &http.Client{ + Timeout: time.Second * 10, + }, + } +} + +func NewEthereumClient(apiKey string) *client { + return NewClient("https://api.etherscan.io", apiKey) +} + +func NewOptimismClient(apiKey string) *client { + return NewClient("https://api-optimistic.etherscan.io", apiKey) +} + +func (c *client) fetch(ctx context.Context, url string) ([]byte, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, err + } + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return body, nil +} + +func (c *client) fetchEtherscanApi(ctx context.Context, url string) (apiResponse, error) { + return retry.Do[apiResponse](ctx, apiMaxRetries, retry.Fixed(apiRetryDelay), func() (apiResponse, error) { + body, err := c.fetch(ctx, url) + if err != nil { + return apiResponse{}, err + } + + var response apiResponse + err = json.Unmarshal(body, &response) + if err != nil { + return apiResponse{}, fmt.Errorf("failed to unmarshal as apiResponse: %w", err) + } + + if response.Message != "OK" { + var resultString string + err = json.Unmarshal(response.Result, &resultString) + if err != nil { + return apiResponse{}, fmt.Errorf("response for %s not OK, returned message: %s", url, response.Message) + } + + if resultString == errRateLimited { + return apiResponse{}, errors.New(errRateLimited) + } + + return apiResponse{}, fmt.Errorf("there was an issue with the Etherscan request to %s, received response: %v", url, response) + } + + return response, nil + }) +} + +func (c *client) fetchEtherscanRpc(ctx context.Context, url string) (rpcResponse, error) { + return retry.Do[rpcResponse](ctx, apiMaxRetries, retry.Fixed(apiRetryDelay), func() (rpcResponse, error) { + body, err := c.fetch(ctx, url) + if err != nil { + return rpcResponse{}, err + } + + var response rpcResponse + err = json.Unmarshal(body, &response) + if err != nil { + return rpcResponse{}, fmt.Errorf("failed to unmarshal as rpcResponse: %w", err) + } + + var resultString string + _ = json.Unmarshal(response.Result, &resultString) + if resultString == errRateLimited { + return rpcResponse{}, errors.New(errRateLimited) + } + + return response, nil + }) +} + +func (c *client) FetchAbi(ctx context.Context, address string) (string, error) { + params := url.Values{} + params.Set("address", address) + url := constructUrl(c.baseUrl, "getabi", "contract", params) + response, err := c.fetchEtherscanApi(ctx, url) + if err != nil { + return "", err + } + + var abi string + err = json.Unmarshal(response.Result, &abi) + if err != nil { + return "", fmt.Errorf("API response result is not expected ABI string: %w", err) + } + + return abi, nil +} + +func (c *client) FetchDeployedBytecode(ctx context.Context, address string) (string, error) { + params := url.Values{} + params.Set("address", address) + url := constructUrl(c.baseUrl, "eth_getCode", "proxy", params) + response, err := c.fetchEtherscanRpc(ctx, url) + if err != nil { + return "", fmt.Errorf("error fetching deployed bytecode: %w", err) + } + + var bytecode string + err = json.Unmarshal(response.Result, &bytecode) + if err != nil { + return "", errors.New("API response result is not expected bytecode string") + } + + return bytecode, nil +} + +func (c *client) FetchDeploymentTxHash(ctx context.Context, address string) (string, error) { + params := url.Values{} + params.Set("contractaddresses", address) + url := constructUrl(c.baseUrl, "getcontractcreation", "contract", params) + response, err := c.fetchEtherscanApi(ctx, url) + if err != nil { + return "", err + } + + var results []struct { + Hash string `json:"txHash"` + } + err = json.Unmarshal(response.Result, &results) + if err != nil { + return "", fmt.Errorf("failed to unmarshal API response as []txInfo: %w", err) + } + + if len(results) == 0 { + return "", fmt.Errorf("API response result is an empty array") + } + + return results[0].Hash, nil +} + +func (c *client) FetchDeploymentTx(ctx context.Context, txHash string) (Transaction, error) { + params := url.Values{} + params.Set("txHash", txHash) + params.Set("tag", "latest") + url := constructUrl(c.baseUrl, "eth_getTransactionByHash", "proxy", params) + response, err := c.fetchEtherscanRpc(ctx, url) + if err != nil { + return Transaction{}, err + } + + resultBytes, err := json.Marshal(response.Result) + if err != nil { + return Transaction{}, fmt.Errorf("failed to marshal Result into JSON: %w", err) + } + + var tx Transaction + err = json.Unmarshal(resultBytes, &tx) + if err != nil { + return Transaction{}, fmt.Errorf("API response result is not expected txInfo struct: %w", err) + } + + return tx, nil +} + +func constructUrl(baseUrl, action, module string, params url.Values) string { + params.Set("action", action) + params.Set("module", module) + queryFragment := params.Encode() + return baseUrl + queryFragment +} diff --git a/op-bindings/foundry/artifact.go b/op-bindings/foundry/artifact.go index 85337ac4452e..6f2ca4e838ba 100644 --- a/op-bindings/foundry/artifact.go +++ b/op-bindings/foundry/artifact.go @@ -9,7 +9,7 @@ import ( // Artifact represents a foundry compilation artifact. // The Abi is specifically left as a json.RawMessage because -// round trip marshaling/unmarshaling of the abi.ABI type +// round trip marshaling/unmarshalling of the abi.ABI type // causes issues. type Artifact struct { Abi json.RawMessage `json:"abi"` diff --git a/op-bindings/gen/main.go b/op-bindings/gen/main.go deleted file mode 100644 index 991195ed78b7..000000000000 --- a/op-bindings/gen/main.go +++ /dev/null @@ -1,229 +0,0 @@ -package main - -import ( - "encoding/json" - "errors" - "flag" - "log" - "os" - "os/exec" - "path" - "path/filepath" - "regexp" - "strings" - "text/template" - - "github.com/ethereum-optimism/optimism/op-bindings/ast" - "github.com/ethereum-optimism/optimism/op-bindings/foundry" -) - -type flags struct { - ForgeArtifacts string - Contracts string - SourceMaps string - OutDir string - Package string - MonorepoBase string -} - -type data struct { - Name string - StorageLayout string - DeployedBin string - Package string - DeployedSourceMap string -} - -func main() { - var f flags - flag.StringVar(&f.ForgeArtifacts, "forge-artifacts", "", "Forge artifacts directory, to load sourcemaps from, if available") - flag.StringVar(&f.OutDir, "out", "", "Output directory to put code in") - flag.StringVar(&f.Contracts, "contracts", "artifacts.json", "Path to file containing list of contracts to generate bindings for") - flag.StringVar(&f.SourceMaps, "source-maps", "", "Comma-separated list of contracts to generate source-maps for") - flag.StringVar(&f.Package, "package", "artifacts", "Go package name") - flag.StringVar(&f.MonorepoBase, "monorepo-base", "", "Base of the monorepo") - flag.Parse() - - if f.MonorepoBase == "" { - log.Fatal("must provide -monorepo-base") - } - log.Printf("Using monorepo base %s\n", f.MonorepoBase) - - contractData, err := os.ReadFile(f.Contracts) - if err != nil { - log.Fatal("error reading contract list: %w\n", err) - } - contracts := []string{} - if err := json.Unmarshal(contractData, &contracts); err != nil { - log.Fatal("error parsing contract list: %w\n", err) - } - - sourceMaps := strings.Split(f.SourceMaps, ",") - sourceMapsSet := make(map[string]struct{}) - for _, k := range sourceMaps { - sourceMapsSet[k] = struct{}{} - } - - if len(contracts) == 0 { - log.Fatalf("must define a list of contracts") - } - - t := template.Must(template.New("artifact").Parse(tmpl)) - - // Make a temp dir to hold all the inputs for abigen - dir, err := os.MkdirTemp("", "op-bindings") - if err != nil { - log.Fatal(err) - } - log.Printf("Using package %s\n", f.Package) - - defer os.RemoveAll(dir) - log.Printf("created temp dir %s\n", dir) - - // If some contracts have the same name then the path to their - // artifact depends on their full import path. Scan over all artifacts - // and hold a mapping from the contract name to the contract path. - // Walk walks the directory deterministically, so the later instance - // of the contract with the same name will be used - re := regexp.MustCompile(`\.\d+\.\d+\.\d+`) - artifactPaths := make(map[string]string) - if err := filepath.Walk(f.ForgeArtifacts, - func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if strings.HasSuffix(path, ".json") { - base := filepath.Base(path) - name := strings.TrimSuffix(base, ".json") - - // remove the compiler version from the name - sanitized := re.ReplaceAllString(name, "") - if _, ok := artifactPaths[sanitized]; !ok { - artifactPaths[sanitized] = path - } - } - return nil - }); err != nil { - log.Fatal(err) - } - - for _, name := range contracts { - log.Printf("generating code for %s\n", name) - - artifactPath := path.Join(f.ForgeArtifacts, name+".sol", name+".json") - forgeArtifactData, err := os.ReadFile(artifactPath) - if errors.Is(err, os.ErrNotExist) { - log.Printf("cannot find forge-artifact for %s at standard path %s, trying %s\n", name, artifactPath, artifactPaths[name]) - artifactPath = artifactPaths[name] - forgeArtifactData, err = os.ReadFile(artifactPath) - if errors.Is(err, os.ErrNotExist) { - log.Fatalf("cannot find forge-artifact of %q\n", name) - } - } - - log.Printf("using forge-artifact %s\n", artifactPath) - var artifact foundry.Artifact - if err := json.Unmarshal(forgeArtifactData, &artifact); err != nil { - log.Fatalf("failed to parse forge artifact of %q: %v\n", name, err) - } - - rawAbi := artifact.Abi - if err != nil { - log.Fatalf("error marshaling abi: %v\n", err) - } - abiFile := path.Join(dir, name+".abi") - if err := os.WriteFile(abiFile, rawAbi, 0o600); err != nil { - log.Fatalf("error writing file: %v\n", err) - } - rawBytecode := artifact.Bytecode.Object.String() - if err != nil { - log.Fatalf("error marshaling bytecode: %v\n", err) - } - bytecodeFile := path.Join(dir, name+".bin") - if err := os.WriteFile(bytecodeFile, []byte(rawBytecode), 0o600); err != nil { - log.Fatalf("error writing file: %v\n", err) - } - - cwd, err := os.Getwd() - if err != nil { - log.Fatalf("error getting cwd: %v\n", err) - } - - lowerName := strings.ToLower(name) - outFile := path.Join(cwd, f.Package, lowerName+".go") - - cmd := exec.Command("abigen", "--abi", abiFile, "--bin", bytecodeFile, "--pkg", f.Package, "--type", name, "--out", outFile) - cmd.Stdout = os.Stdout - - if err := cmd.Run(); err != nil { - log.Fatalf("error running abigen: %v\n", err) - } - - storage := artifact.StorageLayout - canonicalStorage := ast.CanonicalizeASTIDs(&storage, f.MonorepoBase) - ser, err := json.Marshal(canonicalStorage) - if err != nil { - log.Fatalf("error marshaling storage: %v\n", err) - } - serStr := strings.Replace(string(ser), "\"", "\\\"", -1) - - deployedSourceMap := "" - if _, ok := sourceMapsSet[name]; ok { - deployedSourceMap = artifact.DeployedBytecode.SourceMap - } - - d := data{ - Name: name, - StorageLayout: serStr, - DeployedBin: artifact.DeployedBytecode.Object.String(), - Package: f.Package, - DeployedSourceMap: deployedSourceMap, - } - - fname := filepath.Join(f.OutDir, strings.ToLower(name)+"_more.go") - outfile, err := os.OpenFile( - fname, - os.O_RDWR|os.O_CREATE|os.O_TRUNC, - 0o600, - ) - if err != nil { - log.Fatalf("error opening %s: %v\n", fname, err) - } - - if err := t.Execute(outfile, d); err != nil { - log.Fatalf("error writing template %s: %v", outfile.Name(), err) - } - outfile.Close() - log.Printf("wrote file %s\n", outfile.Name()) - } -} - -var tmpl = `// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package {{.Package}} - -import ( - "encoding/json" - - "github.com/ethereum-optimism/optimism/op-bindings/solc" -) - -const {{.Name}}StorageLayoutJSON = "{{.StorageLayout}}" - -var {{.Name}}StorageLayout = new(solc.StorageLayout) - -var {{.Name}}DeployedBin = "{{.DeployedBin}}" -{{if .DeployedSourceMap}} -var {{.Name}}DeployedSourceMap = "{{.DeployedSourceMap}}" -{{end}} -func init() { - if err := json.Unmarshal([]byte({{.Name}}StorageLayoutJSON), {{.Name}}StorageLayout); err != nil { - panic(err) - } - - layouts["{{.Name}}"] = {{.Name}}StorageLayout - deployedBytecodes["{{.Name}}"] = {{.Name}}DeployedBin -} -` diff --git a/op-bindings/hardhat/types.go b/op-bindings/hardhat/types.go index 8e8e86fca166..9dd3a3629828 100644 --- a/op-bindings/hardhat/types.go +++ b/op-bindings/hardhat/types.go @@ -2,6 +2,7 @@ package hardhat import ( "encoding/json" + "strings" "github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum/go-ethereum/accounts/abi" @@ -14,7 +15,7 @@ type Deployment struct { Name string Abi abi.ABI `json:"abi"` Address common.Address `json:"address"` - Args []any `json:"args"` + Args []interface{} `json:"-"` Bytecode hexutil.Bytes `json:"bytecode"` DeployedBytecode hexutil.Bytes `json:"deployedBytecode"` Devdoc json.RawMessage `json:"devdoc"` @@ -26,6 +27,61 @@ type Deployment struct { Userdoc json.RawMessage `json:"userdoc"` } +// UnmarshalJSON is a custom unmarshaler for Deployment, handling the Args field. This changed recently +// when `foundry` migrated to `alloy` types, and now the Args field within the contract artifact has +// a different serialization format. +// +// This custom unmarshaller should be removed when this is fixed upstream. +// +// Old Example: +// ``` +// "args": [ +// +// "0xCE9FeE676767A25feb9722986148Fcd87085a14e", +// "OVM_L1CrossDomainMessenger" +// +// ], +// ``` +// +// New Example: +// ``` +// "args": "[\"0x45ce2021212883d655348778aC99707d63D49aBc\",\"\\OVM_L1CrossDomainMessenger\\\"]" +// ``` +func (d *Deployment) UnmarshalJSON(data []byte) error { + // Create a type alias to prevent recursion + type DeploymentAlias Deployment + + // Unmarshal all fields except for `Args` + var alias DeploymentAlias + if err := json.Unmarshal(data, &alias); err != nil { + return err + } + + // Unmarshal `Args` manually. + tmp := struct { + Args json.RawMessage `json:"args"` + }{} + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + // Strip the `args` string of escapes and quotes. + stripped := strings.ReplaceAll(strings.Trim(string(tmp.Args), "\""), "\\", "") + + // Unmarshal the stripped version of the `args` field. + var args []interface{} + if err := json.Unmarshal([]byte(stripped), &args); err != nil { + return err + } + + // Set the `Args` field in the `Deployment` to the correctly unmarshaled value + alias.Args = args + + // Assign the unmarshaled alias back to the original struct + *d = Deployment(alias) + return nil +} + // Receipt represents the receipt held in a hardhat-deploy // artifact file type Receipt struct { diff --git a/op-bindings/predeploys/addresses.go b/op-bindings/predeploys/addresses.go index f5622f27546b..6d1b75e3bf4c 100644 --- a/op-bindings/predeploys/addresses.go +++ b/op-bindings/predeploys/addresses.go @@ -25,6 +25,17 @@ const ( L1FeeVault = "0x420000000000000000000000000000000000001a" SchemaRegistry = "0x4200000000000000000000000000000000000020" EAS = "0x4200000000000000000000000000000000000021" + Create2Deployer = "0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2" + MultiCall3 = "0xcA11bde05977b3631167028862bE2a173976CA11" + Safe_v130 = "0x69f4D1788e39c87893C980c06EdF4b7f686e2938" + SafeL2_v130 = "0xfb1bffC9d739B8D520DaF37dF666da4C687191EA" + MultiSendCallOnly_v130 = "0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B" + SafeSingletonFactory = "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7" + DeterministicDeploymentProxy = "0x4e59b44847b379578588920cA78FbF26c0B4956C" + MultiSend_v130 = "0x998739BFdAAdde7C933B942a68053933098f9EDa" + Permit2 = "0x000000000022D473030F116dDEE9F6B43aC78BA3" + SenderCreator = "0x7fc98430eaedbb6070b35b39d798725049088348" + EntryPoint = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" ) var ( @@ -47,39 +58,94 @@ var ( L1FeeVaultAddr = common.HexToAddress(L1FeeVault) SchemaRegistryAddr = common.HexToAddress(SchemaRegistry) EASAddr = common.HexToAddress(EAS) + Create2DeployerAddr = common.HexToAddress(Create2Deployer) + MultiCall3Addr = common.HexToAddress(MultiCall3) + Safe_v130Addr = common.HexToAddress(Safe_v130) + SafeL2_v130Addr = common.HexToAddress(SafeL2_v130) + MultiSendCallOnly_v130Addr = common.HexToAddress(MultiSendCallOnly_v130) + SafeSingletonFactoryAddr = common.HexToAddress(SafeSingletonFactory) + DeterministicDeploymentProxyAddr = common.HexToAddress(DeterministicDeploymentProxy) + MultiSend_v130Addr = common.HexToAddress(MultiSend_v130) + Permit2Addr = common.HexToAddress(Permit2) + SenderCreatorAddr = common.HexToAddress(SenderCreator) + EntryPointAddr = common.HexToAddress(EntryPoint) - Predeploys = make(map[string]*common.Address) + Predeploys = make(map[string]*Predeploy) + PredeploysByAddress = make(map[common.Address]*Predeploy) ) -// IsProxied returns true for predeploys that will sit behind a proxy contract -func IsProxied(predeployAddr common.Address) bool { - switch predeployAddr { - case WETH9Addr: - case GovernanceTokenAddr: - default: - return true +func init() { + Predeploys["L2ToL1MessagePasser"] = &Predeploy{Address: L2ToL1MessagePasserAddr} + Predeploys["DeployerWhitelist"] = &Predeploy{Address: DeployerWhitelistAddr} + Predeploys["WETH9"] = &Predeploy{Address: WETH9Addr, ProxyDisabled: true} + Predeploys["L2CrossDomainMessenger"] = &Predeploy{Address: L2CrossDomainMessengerAddr} + Predeploys["L2StandardBridge"] = &Predeploy{Address: L2StandardBridgeAddr} + Predeploys["SequencerFeeVault"] = &Predeploy{Address: SequencerFeeVaultAddr} + Predeploys["OptimismMintableERC20Factory"] = &Predeploy{Address: OptimismMintableERC20FactoryAddr} + Predeploys["L1BlockNumber"] = &Predeploy{Address: L1BlockNumberAddr} + Predeploys["GasPriceOracle"] = &Predeploy{Address: GasPriceOracleAddr} + Predeploys["L1Block"] = &Predeploy{Address: L1BlockAddr} + Predeploys["GovernanceToken"] = &Predeploy{ + Address: GovernanceTokenAddr, + ProxyDisabled: true, + Enabled: func(config DeployConfig) bool { + return config.GovernanceEnabled() + }, + } + Predeploys["LegacyMessagePasser"] = &Predeploy{Address: LegacyMessagePasserAddr} + Predeploys["L2ERC721Bridge"] = &Predeploy{Address: L2ERC721BridgeAddr} + Predeploys["OptimismMintableERC721Factory"] = &Predeploy{Address: OptimismMintableERC721FactoryAddr} + Predeploys["ProxyAdmin"] = &Predeploy{Address: ProxyAdminAddr} + Predeploys["BaseFeeVault"] = &Predeploy{Address: BaseFeeVaultAddr} + Predeploys["L1FeeVault"] = &Predeploy{Address: L1FeeVaultAddr} + Predeploys["SchemaRegistry"] = &Predeploy{Address: SchemaRegistryAddr} + Predeploys["EAS"] = &Predeploy{Address: EASAddr} + Predeploys["Create2Deployer"] = &Predeploy{ + Address: Create2DeployerAddr, + ProxyDisabled: true, + } + Predeploys["MultiCall3"] = &Predeploy{ + Address: MultiCall3Addr, + ProxyDisabled: true, + } + Predeploys["Safe_v130"] = &Predeploy{ + Address: Safe_v130Addr, + ProxyDisabled: true, + } + Predeploys["SafeL2_v130"] = &Predeploy{ + Address: SafeL2_v130Addr, + ProxyDisabled: true, + } + Predeploys["MultiSendCallOnly_v130"] = &Predeploy{ + Address: MultiSendCallOnly_v130Addr, + ProxyDisabled: true, + } + Predeploys["SafeSingletonFactory"] = &Predeploy{ + Address: SafeSingletonFactoryAddr, + ProxyDisabled: true, + } + Predeploys["DeterministicDeploymentProxy"] = &Predeploy{ + Address: DeterministicDeploymentProxyAddr, + ProxyDisabled: true, + } + Predeploys["MultiSend_v130"] = &Predeploy{ + Address: MultiSend_v130Addr, + ProxyDisabled: true, + } + Predeploys["Permit2"] = &Predeploy{ + Address: Permit2Addr, + ProxyDisabled: true, + } + Predeploys["SenderCreator"] = &Predeploy{ + Address: SenderCreatorAddr, + ProxyDisabled: true, + } + Predeploys["EntryPoint"] = &Predeploy{ + Address: EntryPointAddr, + ProxyDisabled: true, } - return false -} -func init() { - Predeploys["L2ToL1MessagePasser"] = &L2ToL1MessagePasserAddr - Predeploys["DeployerWhitelist"] = &DeployerWhitelistAddr - Predeploys["WETH9"] = &WETH9Addr - Predeploys["L2CrossDomainMessenger"] = &L2CrossDomainMessengerAddr - Predeploys["L2StandardBridge"] = &L2StandardBridgeAddr - Predeploys["SequencerFeeVault"] = &SequencerFeeVaultAddr - Predeploys["OptimismMintableERC20Factory"] = &OptimismMintableERC20FactoryAddr - Predeploys["L1BlockNumber"] = &L1BlockNumberAddr - Predeploys["GasPriceOracle"] = &GasPriceOracleAddr - Predeploys["L1Block"] = &L1BlockAddr - Predeploys["GovernanceToken"] = &GovernanceTokenAddr - Predeploys["LegacyMessagePasser"] = &LegacyMessagePasserAddr - Predeploys["L2ERC721Bridge"] = &L2ERC721BridgeAddr - Predeploys["OptimismMintableERC721Factory"] = &OptimismMintableERC721FactoryAddr - Predeploys["ProxyAdmin"] = &ProxyAdminAddr - Predeploys["BaseFeeVault"] = &BaseFeeVaultAddr - Predeploys["L1FeeVault"] = &L1FeeVaultAddr - Predeploys["SchemaRegistry"] = &SchemaRegistryAddr - Predeploys["EAS"] = &EASAddr + for _, predeploy := range Predeploys { + PredeploysByAddress[predeploy.Address] = predeploy + } } diff --git a/op-bindings/predeploys/addresses_test.go b/op-bindings/predeploys/addresses_test.go index 8a0f8f6006ab..44556e6432a8 100644 --- a/op-bindings/predeploys/addresses_test.go +++ b/op-bindings/predeploys/addresses_test.go @@ -16,6 +16,10 @@ func TestGethAddresses(t *testing.T) { require.Equal(t, L1BlockAddr, types.L1BlockAddr) } +func uintToHash(v uint) common.Hash { + return common.BigToHash(new(big.Int).SetUint64(uint64(v))) +} + // TestL1BlockSlots ensures that the storage layout of the L1Block // contract matches the hardcoded values in `op-geth`. func TestL1BlockSlots(t *testing.T) { @@ -23,18 +27,34 @@ func TestL1BlockSlots(t *testing.T) { require.NoError(t, err) var l1BaseFeeSlot, overHeadSlot, scalarSlot common.Hash + var l1BaseFeeScalarSlot, l1BlobBaseFeeScalarSlot, blobBaseFeeSlot common.Hash // new in Ecotone + var l1BaseFeeScalarOffset, l1BlobBaseFeeScalarOffset uint // new in Ecotone for _, entry := range layout.Storage { switch entry.Label { case "l1FeeOverhead": - overHeadSlot = common.BigToHash(big.NewInt(int64(entry.Slot))) + overHeadSlot = uintToHash(entry.Slot) case "l1FeeScalar": - scalarSlot = common.BigToHash(big.NewInt(int64(entry.Slot))) + scalarSlot = uintToHash(entry.Slot) case "basefee": - l1BaseFeeSlot = common.BigToHash(big.NewInt(int64(entry.Slot))) + l1BaseFeeSlot = uintToHash(entry.Slot) + case "blobBaseFee": + blobBaseFeeSlot = uintToHash(entry.Slot) + case "baseFeeScalar": + l1BaseFeeScalarSlot = uintToHash(entry.Slot) + l1BaseFeeScalarOffset = entry.Offset + case "blobBaseFeeScalar": + l1BlobBaseFeeScalarSlot = uintToHash(entry.Slot) + l1BlobBaseFeeScalarOffset = entry.Offset } } require.Equal(t, types.OverheadSlot, overHeadSlot) require.Equal(t, types.ScalarSlot, scalarSlot) require.Equal(t, types.L1BaseFeeSlot, l1BaseFeeSlot) + // new in Ecotone + require.Equal(t, types.L1BlobBaseFeeSlot, blobBaseFeeSlot) + require.Equal(t, types.L1FeeScalarsSlot, l1BaseFeeScalarSlot) + require.Equal(t, types.L1FeeScalarsSlot, l1BlobBaseFeeScalarSlot) + require.Equal(t, uint(types.BaseFeeScalarSlotOffset), l1BaseFeeScalarOffset) + require.Equal(t, uint(types.BlobBaseFeeScalarSlotOffset), l1BlobBaseFeeScalarOffset) } diff --git a/op-bindings/predeploys/eip4788.go b/op-bindings/predeploys/eip4788.go new file mode 100644 index 000000000000..de934e9bced2 --- /dev/null +++ b/op-bindings/predeploys/eip4788.go @@ -0,0 +1,16 @@ +package predeploys + +import "github.com/ethereum/go-ethereum/common" + +// EIP-4788 defines a deterministic deployment transaction that deploys the beacon-block-roots contract. +// To embed the contract in genesis, we want the deployment-result, not the contract-creation tx input code. +// Since the contract deployment result is deterministic and the same across every chain, +// the bytecode can be easily verified by comparing it with chains like Goerli. +// During deployment it does not modify any contract storage, the storage starts empty. +// See https://goerli.etherscan.io/tx/0xdf52c2d3bbe38820fff7b5eaab3db1b91f8e1412b56497d88388fb5d4ea1fde0 +// And https://eips.ethereum.org/EIPS/eip-4788 +var ( + EIP4788ContractAddr = common.HexToAddress("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") + EIP4788ContractCode = common.FromHex("0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500") + EIP4788ContractCodeHash = common.HexToHash("0xf57acd40259872606d76197ef052f3d35588dadf919ee1f0e3cb9b62d3f4b02c") +) diff --git a/op-bindings/predeploys/predeploy.go b/op-bindings/predeploys/predeploy.go new file mode 100644 index 000000000000..d031040eda2f --- /dev/null +++ b/op-bindings/predeploys/predeploy.go @@ -0,0 +1,16 @@ +package predeploys + +import ( + "github.com/ethereum/go-ethereum/common" +) + +type DeployConfig interface { + GovernanceEnabled() bool + CanyonTime(genesisTime uint64) *uint64 +} + +type Predeploy struct { + Address common.Address + ProxyDisabled bool + Enabled func(config DeployConfig) bool +} diff --git a/op-bootnode/Dockerfile b/op-bootnode/Dockerfile index 45d73a29c8a9..7fa8b12223e4 100644 --- a/op-bootnode/Dockerfile +++ b/op-bootnode/Dockerfile @@ -10,6 +10,8 @@ COPY ./op-bootnode /app/op-bootnode COPY ./op-bindings /app/op-bindings COPY ./op-node /app/op-node COPY ./op-service /app/op-service +COPY ./op-plasma /app/op-plasma +COPY ./op-conductor /app/op-conductor COPY ./op-aws-sdk /app/op-aws-sdk COPY ./go.mod /app/go.mod COPY ./go.sum /app/go.sum diff --git a/op-bootnode/bootnode/entrypoint.go b/op-bootnode/bootnode/entrypoint.go index b629ca453b87..0dcf356fa1f3 100644 --- a/op-bootnode/bootnode/entrypoint.go +++ b/op-bootnode/bootnode/entrypoint.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" opnode "github.com/ethereum-optimism/optimism/op-node" "github.com/ethereum-optimism/optimism/op-node/metrics" @@ -20,11 +21,12 @@ import ( oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" "github.com/ethereum-optimism/optimism/op-service/opio" + oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" ) type gossipNoop struct{} -func (g *gossipNoop) OnUnsafeL2Payload(_ context.Context, _ peer.ID, _ *eth.ExecutionPayload) error { +func (g *gossipNoop) OnUnsafeL2Payload(_ context.Context, _ peer.ID, _ *eth.ExecutionPayloadEnvelope) error { return nil } @@ -36,19 +38,19 @@ func (g *gossipConfig) P2PSequencerAddress() common.Address { type l2Chain struct{} -func (l *l2Chain) PayloadByNumber(_ context.Context, _ uint64) (*eth.ExecutionPayload, error) { - return nil, nil +func (l *l2Chain) PayloadByNumber(_ context.Context, _ uint64) (*eth.ExecutionPayloadEnvelope, error) { + return nil, errors.New("P2P req/resp is not supported in bootnodes") } func Main(cliCtx *cli.Context) error { log.Info("Initializing bootnode") logCfg := oplog.ReadCLIConfig(cliCtx) logger := oplog.NewLogger(oplog.AppOut(cliCtx), logCfg) - oplog.SetGlobalLogHandler(logger.GetHandler()) + oplog.SetGlobalLogHandler(logger.Handler()) m := metrics.NewMetrics("default") ctx := context.Background() - config, err := opnode.NewRollupConfig(logger, cliCtx) + config, err := opnode.NewRollupConfigFromCLI(logger, cliCtx) if err != nil { return err } @@ -60,8 +62,12 @@ func Main(cliCtx *cli.Context) error { if err != nil { return fmt.Errorf("failed to load p2p config: %w", err) } + if p2pConfig.EnableReqRespSync { + logger.Warn("req-resp sync is enabled, bootnode does not support this feature") + p2pConfig.EnableReqRespSync = false + } - p2pNode, err := p2p.NewNodeP2P(ctx, config, logger, p2pConfig, &gossipNoop{}, &l2Chain{}, &gossipConfig{}, m) + p2pNode, err := p2p.NewNodeP2P(ctx, config, logger, p2pConfig, &gossipNoop{}, &l2Chain{}, &gossipConfig{}, m, false) if err != nil || p2pNode == nil { return err } @@ -69,6 +75,29 @@ func Main(cliCtx *cli.Context) error { return fmt.Errorf("uninitialized discovery service") } + rpcCfg := oprpc.ReadCLIConfig(cliCtx) + if err := rpcCfg.Check(); err != nil { + return fmt.Errorf("failed to validate RPC config") + } + rpcServer := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, "", oprpc.WithLogger(logger)) + if rpcCfg.EnableAdmin { + logger.Info("Admin RPC enabled but does nothing for the bootnode") + } + rpcServer.AddAPI(rpc.API{ + Namespace: p2p.NamespaceRPC, + Version: "", + Service: p2p.NewP2PAPIBackend(p2pNode, logger, m), + Authenticated: false, + }) + if err := rpcServer.Start(); err != nil { + return fmt.Errorf("failed to start the RPC server") + } + defer func() { + if err := rpcServer.Stop(); err != nil { + log.Error("failed to stop RPC server", "err", err) + } + }() + go p2pNode.DiscoveryProcess(ctx, logger, config, p2pConfig.TargetPeers()) metricsCfg := opmetrics.ReadCLIConfig(cliCtx) diff --git a/op-bootnode/flags/flags.go b/op-bootnode/flags/flags.go index 6abe12092fb9..5fbe0d538b33 100644 --- a/op-bootnode/flags/flags.go +++ b/op-bootnode/flags/flags.go @@ -1,43 +1,25 @@ package flags import ( - "fmt" - "strings" + "github.com/urfave/cli/v2" - "github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-node/flags" - opservice "github.com/ethereum-optimism/optimism/op-service" + opflags "github.com/ethereum-optimism/optimism/op-service/flags" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - "github.com/urfave/cli/v2" + oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" ) const envVarPrefix = "OP_BOOTNODE" -func prefixEnvVars(name string) []string { - return opservice.PrefixEnvVar(envVarPrefix, name) -} - -var ( - RollupConfig = &cli.StringFlag{ - Name: flags.RollupConfig.Name, - Usage: "Rollup chain parameters", - EnvVars: prefixEnvVars("ROLLUP_CONFIG"), - } - Network = &cli.StringFlag{ - Name: flags.Network.Name, - Usage: fmt.Sprintf("Predefined network selection. Available networks: %s", strings.Join(chaincfg.AvailableNetworks(), ", ")), - EnvVars: prefixEnvVars("NETWORK"), - } -) - var Flags = []cli.Flag{ - RollupConfig, - Network, + opflags.CLINetworkFlag(envVarPrefix, ""), + opflags.CLIRollupConfigFlag(envVarPrefix, ""), } func init() { Flags = append(Flags, flags.P2PFlags(envVarPrefix)...) Flags = append(Flags, opmetrics.CLIFlags(envVarPrefix)...) Flags = append(Flags, oplog.CLIFlags(envVarPrefix)...) + Flags = append(Flags, oprpc.CLIFlags(envVarPrefix)...) } diff --git a/op-chain-ops/Makefile b/op-chain-ops/Makefile index 7a017a4fb59a..1e39aca41694 100644 --- a/op-chain-ops/Makefile +++ b/op-chain-ops/Makefile @@ -1,7 +1,11 @@ -all: check-l2 +op-version-check: + go build -o ./bin/op-version-check ./cmd/op-version-check/main.go -check-l2: - go build -o ./bin/check-l2 ./cmd/check-l2/main.go +ecotone-scalar: + go build -o ./bin/ecotone-scalar ./cmd/ecotone-scalar/main.go + +receipt-reference-builder: + go build -o ./bin/receipt-reference-builder ./cmd/receipt-reference-builder/*.go test: go test ./... @@ -12,4 +16,4 @@ fuzz: go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzAliasing ./crossdomain go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzVersionedNonce ./crossdomain -.PHONY: check-l2 test fuzz +.PHONY: test fuzz diff --git a/op-chain-ops/README.md b/op-chain-ops/README.md index 56aa6cc28328..a40232fe7d17 100644 --- a/op-chain-ops/README.md +++ b/op-chain-ops/README.md @@ -2,24 +2,51 @@ This package contains utilities for working with chain state. -## check-l2 +## op-version-check -The `check-l2` binary is used for verifying that an OP Stack L2 -has been configured correctly. It iterates over all 2048 predeployed -proxies to make sure they are configured correctly with the correct -proxy admin address. After that, it checks that all [predeploys](../op-bindings/predeploys/addresses.go) -are configured and aliased correctly. Additional contract-specific -checks ensure configuration like ownership, version, and storage -is set correctly for the predeploys. +A CLI tool for determining which contract versions are deployed for +chains in a superchain. It will output a JSON file that contains a +list of each chain's versions. It is assumed that the implementations +that are being checked have already been deployed and their contract +addresses exist inside of the `superchain-registry` repository. It is +also assumed that the semantic version file in the `superchain-registry` +has been updated. The tool will output the semantic versioning to +determine which contract versions are deployed. + +### Configuration + +#### L1 RPC URL + +The L1 RPC URL is used to determine which superchain to target. All +L2s that are not based on top of the L1 chain that corresponds to the +L1 RPC URL are filtered out from being checked. It also is used to +double check that the data in the `superchain-registry` is correct. + +#### Chain IDs + +A list of L2 chain IDs can be passed that will be used to filter which +L2 chains will have their versions checked. Omitting this argument will +result in all chains in the superchain being considered. + +#### Deploy Config + +The path to the `deploy-config` directory in the contracts package. +Since multiple L2 networks may be considered in the check, the `deploy-config` +directory must be passed and then the particular deploy config files will +be read out of the directory as needed. + +#### Outfile + +The file that the versions should be written to. If omitted, the file +will be written to stdout #### Usage -It can be built and run using the [Makefile](./Makefile) `check-l2` target. -Run `make check-l2` to create a binary in [./bin/check-l2](./bin/check-l2) -that can be executed by providing the `--l1-rpc-url` and `--l2-rpc-url` flags. +It can be built and run using the [Makefile](./Makefile) `op-version-check` +target. Run `make op-version-check` to create a binary in [./bin/op-version-check](./bin/op-version-check) +that can be executed, optionally providing the `--l1-rpc-url`, `--chain-ids`, +`--superchain-target`, and `--outfile` flags. ```sh -./bin/check-l2 \ - --l2-rpc-url http://localhost:9545 \ - --l1-rpc-url http://localhost:8545 +./bin/op-version-check ``` diff --git a/op-chain-ops/cmd/check-canyon/main.go b/op-chain-ops/cmd/check-canyon/main.go new file mode 100644 index 000000000000..deb5270ed639 --- /dev/null +++ b/op-chain-ops/cmd/check-canyon/main.go @@ -0,0 +1,277 @@ +package main + +import ( + "bytes" + "context" + "errors" + "flag" + "fmt" + "math/big" + "os" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/eth" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/mattn/go-isatty" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/trie" +) + +func CalcBaseFee(parent eth.BlockInfo, elasticity uint64, canyonActive bool) *big.Int { + denomUint := uint64(50) + if canyonActive { + denomUint = uint64(250) + } + parentGasTarget := parent.GasLimit() / elasticity + // If the parent gasUsed is the same as the target, the baseFee remains unchanged. + if parent.GasUsed() == parentGasTarget { + return new(big.Int).Set(parent.BaseFee()) + } + + var ( + num = new(big.Int) + denom = new(big.Int) + ) + + if parent.GasUsed() > parentGasTarget { + // If the parent block used more gas than its target, the baseFee should increase. + // max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator) + num.SetUint64(parent.GasUsed() - parentGasTarget) + num.Mul(num, parent.BaseFee()) + num.Div(num, denom.SetUint64(parentGasTarget)) + num.Div(num, denom.SetUint64(denomUint)) + baseFeeDelta := math.BigMax(num, common.Big1) + + return num.Add(parent.BaseFee(), baseFeeDelta) + } else { + // Otherwise if the parent block used less gas than its target, the baseFee should decrease. + // max(0, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator) + num.SetUint64(parentGasTarget - parent.GasUsed()) + num.Mul(num, parent.BaseFee()) + num.Div(num, denom.SetUint64(parentGasTarget)) + num.Div(num, denom.SetUint64(denomUint)) + baseFee := num.Sub(parent.BaseFee(), num) + + return math.BigMax(baseFee, common.Big0) + } +} + +func ManuallyEncodeReceipts(receipts types.Receipts, canyonActive bool) [][]byte { + v := uint64(1) + for _, receipt := range receipts { + if receipt.Type == types.DepositTxType { + if canyonActive { + receipt.DepositReceiptVersion = &v + } else { + receipt.DepositReceiptVersion = nil + } + + } + } + var out [][]byte + for i := range receipts { + var buf bytes.Buffer + receipts.EncodeIndex(i, &buf) + out = append(out, buf.Bytes()) + } + return out +} + +type rawReceipts [][]byte + +func (s rawReceipts) Len() int { return len(s) } +func (s rawReceipts) EncodeIndex(i int, w *bytes.Buffer) { + w.Write(s[i]) +} +func HashList(list [][]byte) common.Hash { + hasher := trie.NewStackTrie(nil) + return types.DeriveSha(rawReceipts(list), hasher) +} + +type L2Client interface { + BlockByNumber(context.Context, *big.Int) (*types.Block, error) + CodeAt(context.Context, common.Address, *big.Int) ([]byte, error) + InfoByNumber(context.Context, uint64) (eth.BlockInfo, error) + FetchReceipts(context.Context, common.Hash) (eth.BlockInfo, types.Receipts, error) +} + +type Client struct { + *ethclient.Client + *sources.L1Client +} + +type Args struct { + Number uint64 + Elasticity uint64 + Client L2Client +} + +func ValidateReceipts(ctx Args, canyonActive bool) error { + block, err := ctx.Client.InfoByNumber(context.Background(), ctx.Number) + if err != nil { + return err + } + + _, receipts, err := ctx.Client.FetchReceipts(context.Background(), block.Hash()) + if err != nil { + return err + } + + have := block.ReceiptHash() + want := HashList(ManuallyEncodeReceipts(receipts, canyonActive)) + + if have != want { + return fmt.Errorf("Receipts do not look correct. canyonActive: %v. have: %v, want: %v", canyonActive, have, want) + } + + return nil +} + +func Validate1559Params(ctx Args, canyonActive bool) error { + block, err := ctx.Client.InfoByNumber(context.Background(), ctx.Number) + if err != nil { + return err + } + + parent, err := ctx.Client.InfoByNumber(context.Background(), ctx.Number-1) + if err != nil { + return err + } + + want := CalcBaseFee(parent, ctx.Elasticity, canyonActive) + have := block.BaseFee() + + if have.Cmp(want) != 0 { + return fmt.Errorf("BaseFee does not match. canyonActive: %v. have: %v, want: %v", canyonActive, have, want) + } + + return nil +} + +func ValidateWithdrawals(ctx Args, canyonActive bool) error { + block, err := ctx.Client.BlockByNumber(context.Background(), new(big.Int).SetUint64(ctx.Number)) + if err != nil { + return err + } + + if canyonActive && block.Withdrawals() == nil { + return errors.New("No nonwithdrawals in a canyon block") + } else if canyonActive && len(block.Withdrawals()) > 0 { + return errors.New("Withdrawals length is not zero in a canyon block") + } else if !canyonActive && block.Withdrawals() != nil { + return errors.New("Withdrawals in a pre-canyon block") + } + return nil +} + +func ValidateCreate2Deployer(ctx Args, canyonActive bool) error { + addr := common.HexToAddress("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2") + code, err := ctx.Client.CodeAt(context.Background(), addr, new(big.Int).SetUint64(ctx.Number)) + if err != nil { + return err + } + codeHash := crypto.Keccak256Hash(code) + expectedCodeHash := common.HexToHash("0xb0550b5b431e30d38000efb7107aaa0ade03d48a7198a140edda9d27134468b2") + + if canyonActive && codeHash != expectedCodeHash { + return fmt.Errorf("Canyon active but code hash does not match. have: %v, want: %v", codeHash, expectedCodeHash) + } else if !canyonActive && codeHash == expectedCodeHash { + return fmt.Errorf("Canyon not active but code hashes do match. codeHash: %v", codeHash) + } + + return nil +} + +// CheckActivation takes a function f which determines in a specific block follows the rules of a fork. +func CheckActivation(f func(Args, bool) error, ctx Args, forkActivated bool, valid *bool) { + if err := f(ctx, forkActivated); err != nil { + log.Error("Block did not follow fork rules", "err", err) + *valid = false + } +} + +// CheckInactivation takes a function f which determines in a specific block follows the rules of a fork. +// It passes the oppose value of forkActivated & asserts that an error is returned. +func CheckInactivation(f func(Args, bool) error, ctx Args, forkActivated bool, valid *bool) { + if err := f(ctx, !forkActivated); err == nil { + log.Error("Block followed the wrong side of the fork rules") + *valid = false + } +} + +func main() { + color := isatty.IsTerminal(os.Stderr.Fd()) + handler := log.NewTerminalHandler(os.Stderr, color) + oplog.SetGlobalLogHandler(handler) + logger := log.NewLogger(handler) + + // Define the flag variables + var ( + canyonActive bool + number uint64 + elasticity uint64 + rpcURL string + ) + + valid := true + + // Define and parse the command-line flags + flag.BoolVar(&canyonActive, "canyon", false, "Set this flag to assert canyon behavior") + flag.Uint64Var(&number, "number", 31, "Block number to check") + flag.Uint64Var(&elasticity, "elasticity", 6, "Specify the EIP-1559 elasticity. 6 on mainnet/sepolia. 10 on goerli") + flag.StringVar(&rpcURL, "rpc-url", "http://localhost:8545", "Specify the L2 ETH RPC URL") + + // Parse the command-line arguments + flag.Parse() + + l2RPC, err := client.NewRPC(context.Background(), logger, rpcURL, client.WithDialBackoff(10)) + if err != nil { + log.Crit("Error creating RPC", "err", err) + } + c := &rollup.Config{SeqWindowSize: 10} + l2Cfg := sources.L1ClientDefaultConfig(c, true, sources.RPCKindBasic) + sourceClient, err := sources.NewL1Client(l2RPC, logger, nil, l2Cfg) + if err != nil { + log.Crit("Error creating RPC", "err", err) + } + ethClient, err := ethclient.Dial(rpcURL) + if err != nil { + log.Crit("Error creating RPC", "err", err) + } + + client := Client{ethClient, sourceClient} + + ctx := Args{ + Number: number, + Elasticity: elasticity, + Client: client, + } + + CheckActivation(ValidateReceipts, ctx, canyonActive, &valid) + CheckInactivation(ValidateReceipts, ctx, canyonActive, &valid) + + CheckActivation(Validate1559Params, ctx, canyonActive, &valid) + // Don't check in-activation for 1559 b/c at low basefees the two cannot be differentiated + + CheckActivation(ValidateWithdrawals, ctx, canyonActive, &valid) + CheckInactivation(ValidateWithdrawals, ctx, canyonActive, &valid) + + CheckActivation(ValidateCreate2Deployer, ctx, canyonActive, &valid) + CheckInactivation(ValidateCreate2Deployer, ctx, canyonActive, &valid) + + if !valid { + os.Exit(1) + } else if canyonActive { + log.Info(fmt.Sprintf("Successfully validated block %v as a Canyon block", number)) + } else { + log.Info(fmt.Sprintf("Successfully validated block %v as a Pre-Canyon block", number)) + } +} diff --git a/op-chain-ops/cmd/check-delta/aggregate-channels.sh b/op-chain-ops/cmd/check-delta/aggregate-channels.sh new file mode 100755 index 000000000000..e788ddc651af --- /dev/null +++ b/op-chain-ops/cmd/check-delta/aggregate-channels.sh @@ -0,0 +1,103 @@ +#!/bin/bash +set -uo pipefail + +# Check if a directory path is provided +# Directory must contain the output of batch_decoder's reassemble command, which are channels in json form +if [ -z "${1:-}" ]; then + echo "Usage: $0 /path/to/directory" + exit 1 +fi + +# Check if jq is installed +if ! command -v jq &> /dev/null; then + echo "Error: jq is not installed" + exit 1 +fi + +directory_path=$1 +# Check if directory exists and is not empty +if [ ! -d "$directory_path" ] || [ -z "$(ls -A "$directory_path")" ]; then + echo "Error: Directory does not exist or is empty" + exit 1 +fi + +invalid_json_count=0 +invalid_jsons=() + +not_ready_channel_count=0 +not_ready_channels=() +ready_channel_count=0 + +span_batch_count=0 +singular_batch_count=0 + +channels_with_invalid_batches=() + +# shellcheck disable=SC2016 +batch_type_counter_jq_script='reduce .batch_types[] as $batch_type ( + {"span_batch_count": 0, "singular_batch_count": 0}; + if $batch_type == 1 then + .span_batch_count += 1 + else + .singular_batch_count += 1 + end) | .span_batch_count, .singular_batch_count' + +# Loop over every .json file in the specified directory +for file in "$directory_path"/*.json; do + # check file is valid json + if ! jq empty "$file" 2>/dev/null; then + ((invalid_json_count++)) + invalid_jsons+=("$file") + continue + fi + # check channels are ready + if [ "$(jq -r ".is_ready" "$file")" == "false" ] ; then + # not ready channel have no batches so invalid_batches field is always false + ((not_ready_channel_count++)) + not_ready_channels+=("$file") + continue + else + ((ready_channel_count++)) + fi + # check channels contain invalid batches + if [ "$(jq -r ".invalid_batches" "$file")" == "true" ] ; then + channels_with_invalid_batches+=("$file") + fi + # count singular batch count and span batch count + jq_result=$(jq "$batch_type_counter_jq_script" "$file") + # shellcheck disable=SC2162 + read span_batch_count_per_channel singular_batch_count_per_channel <<< "$jq_result" + span_batch_count=$((span_batch_count+span_batch_count_per_channel)) + singular_batch_count=$((singular_batch_count+singular_batch_count_per_channel)) +done + +# Display the counts +echo "Singular batch count: $singular_batch_count" +echo "Span batch count: $span_batch_count" +echo "Ready channel count: $ready_channel_count" +echo "Not ready channel count: $not_ready_channel_count" +echo "Invalid json count: $invalid_json_count" + +# Display the files which are invalid jsons +if [ ${#invalid_jsons[@]} -gt 0 ]; then + echo "Invalid jsons" + printf '[*] %s\n' "${invalid_jsons[@]}" +else + echo "All processed channels are valid jsons." +fi + +# Display the files which are channels not ready +if [ ${#not_ready_channels[@]} -gt 0 ]; then + echo "Not ready channels" + printf '[*] %s\n' "${not_ready_channels[@]}" +else + echo "All processed channels are ready." +fi + +# Display the files including invalid batches +if [ ${#channels_with_invalid_batches[@]} -gt 0 ]; then + echo "Channels with invalid batches" + printf '[*] %s\n' "${channels_with_invalid_batches[@]}" +else + echo "All processed ready channels contain valid batches." +fi diff --git a/op-chain-ops/cmd/check-deploy-config/main.go b/op-chain-ops/cmd/check-deploy-config/main.go index 68659cfc7bdc..599f91611e01 100644 --- a/op-chain-ops/cmd/check-deploy-config/main.go +++ b/op-chain-ops/cmd/check-deploy-config/main.go @@ -9,11 +9,13 @@ import ( "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" + oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum/go-ethereum/log" ) func main() { - log.Root().SetHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(isatty.IsTerminal(os.Stderr.Fd())))) + color := isatty.IsTerminal(os.Stderr.Fd()) + oplog.SetGlobalLogHandler(log.NewTerminalHandler(os.Stderr, color)) app := &cli.App{ Name: "check-deploy-config", diff --git a/op-chain-ops/cmd/check-derivation/main.go b/op-chain-ops/cmd/check-derivation/main.go new file mode 100644 index 000000000000..499b128f8767 --- /dev/null +++ b/op-chain-ops/cmd/check-derivation/main.go @@ -0,0 +1,431 @@ +package main + +import ( + "context" + "crypto/ecdsa" + "errors" + "fmt" + "math/big" + "math/rand" + "os" + "time" + + clients2 "github.com/ethereum-optimism/optimism/op-chain-ops/clients" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/eth" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/retry" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testutils" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/mattn/go-isatty" + "github.com/urfave/cli/v2" +) + +func main() { + color := isatty.IsTerminal(os.Stderr.Fd()) + oplog.SetGlobalLogHandler(log.NewTerminalHandler(os.Stderr, color)) + + app := cli.NewApp() + app.Name = "check-derivation" + app.Usage = "Optimism derivation checker" + app.Commands = []*cli.Command{ + { + Name: "detect-l2-reorg", + Usage: "Detects unsafe block reorg", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "l2-rpc-url", + Value: "http://127.0.0.1:9545", + Usage: "L2 RPC URL", + EnvVars: []string{"L2_RPC_URL"}, + }, + &cli.DurationFlag{ + Name: "polling-interval", + Value: time.Millisecond * 500, + Usage: "Polling interval", + }, + }, + Action: detectL2Reorg, + }, + { + Name: "check-consolidation", + Usage: "Checks consolidation", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "l2-rpc-url", + Value: "http://127.0.0.1:9545", + Usage: "L2 RPC URL", + EnvVars: []string{"L2_RPC_URL"}, + }, + &cli.DurationFlag{ + Name: "polling-interval", + Value: time.Millisecond * 1000, + Usage: "Polling interval", + }, + &cli.StringFlag{ + Name: "private-key", + Value: "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", + Usage: "Private key for signing L2 transactions. " + + "Default: devnet pre-funded account", + }, + &cli.IntFlag{ + Name: "tx-count", + Value: 4, + Usage: "Number of transactions to send. Minimum value is 4 for checking every tx type.", + }, + &cli.Uint64Flag{ + Name: "l2-chain-id", + Value: 901, + Usage: "L2 chain ID", + }, + }, + Action: checkConsolidation, + }, + } + + if err := app.Run(os.Args); err != nil { + log.Crit("error checking l2", "err", err) + } +} + +func newClientsFromContext(cliCtx *cli.Context) (*ethclient.Client, *sources.EthClient, error) { + clients, err := clients2.NewClientsFromContext(cliCtx) + if err != nil { + return nil, nil, err + } + ethClCfg := sources.EthClientConfig{ + MaxRequestsPerBatch: 10, + MaxConcurrentRequests: 10, + ReceiptsCacheSize: 10, + TransactionsCacheSize: 10, + HeadersCacheSize: 10, + PayloadsCacheSize: 10, + TrustRPC: false, + MustBePostMerge: true, + RPCProviderKind: sources.RPCKindStandard, + MethodResetDuration: time.Minute, + } + cl := ethclient.NewClient(clients.L2RpcClient) + ethCl, err := sources.NewEthClient(client.NewBaseRPCClient(clients.L2RpcClient), log.Root(), nil, ðClCfg) + if err != nil { + return nil, nil, err + } + return cl, ethCl, nil +} + +func getHead(ctx context.Context, client *sources.EthClient, label eth.BlockLabel) (eth.BlockID, common.Hash, error) { + return retry.Do2(ctx, 10, &retry.FixedStrategy{Dur: 100 * time.Millisecond}, func() (eth.BlockID, common.Hash, error) { + ctx, cancel := context.WithTimeout(ctx, 3*time.Second) + defer cancel() + + blockInfo, err := client.InfoByLabel(ctx, label) + if err != nil { + return eth.BlockID{}, common.Hash{}, err + } + return eth.BlockID{Hash: blockInfo.Hash(), Number: blockInfo.NumberU64()}, blockInfo.ParentHash(), nil + }) +} + +func getUnsafeHead(ctx context.Context, client *sources.EthClient) (eth.BlockID, common.Hash, error) { + return getHead(ctx, client, eth.Unsafe) +} + +func getSafeHead(ctx context.Context, client *sources.EthClient) (eth.BlockID, common.Hash, error) { + return getHead(ctx, client, eth.Safe) +} + +func checkReorg(blockMap map[uint64]common.Hash, number uint64, hash common.Hash) { + prevHash, ok := blockMap[number] + if ok { + if prevHash != hash { + log.Error("Unsafe head reorg", "blockNum:", number, + "prevHash", prevHash.String(), "currHash", hash.String()) + } + } +} + +// detectL2Reorg polls safe heads and detects l2 unsafe block reorg. +func detectL2Reorg(cliCtx *cli.Context) error { + ctx := context.Background() + _, ethCl, err := newClientsFromContext(cliCtx) + if err != nil { + return err + } + + pollingInterval := cliCtx.Duration("polling-interval") + // blockMap maps blockNumber to blockHash + blockMap := make(map[uint64]common.Hash) + var prevUnsafeHeadNum uint64 + for { + unsafeHeadBlockId, parentHash, err := getUnsafeHead(ctx, ethCl) + if err != nil { + return fmt.Errorf("failed to fetch unsafe head: %w", err) + } + checkReorg(blockMap, unsafeHeadBlockId.Number-1, parentHash) + checkReorg(blockMap, unsafeHeadBlockId.Number, unsafeHeadBlockId.Hash) + + if unsafeHeadBlockId.Number > prevUnsafeHeadNum { + log.Info("Fetched Unsafe block", "blockNum", unsafeHeadBlockId.Number, "hash", unsafeHeadBlockId.Hash.String()) + } + + blockMap[unsafeHeadBlockId.Number-1] = parentHash + blockMap[unsafeHeadBlockId.Number] = unsafeHeadBlockId.Hash + prevUnsafeHeadNum = unsafeHeadBlockId.Number + time.Sleep(pollingInterval) + } +} + +// getRandomAddress returns vanity address of the form 0x000000000000000000000000[random 32 bits][prefix] +// example: 0x00000000000000000000000030bd3402deadbeef +func getRandomAddress(rng *rand.Rand, prefix uint64) common.Address { + var vanity uint64 = prefix + (uint64(rng.Uint32()) << 32) + return common.HexToAddress(fmt.Sprintf("0x%X", vanity)) +} + +func getPrivateKey(cliCtx *cli.Context) (*ecdsa.PrivateKey, error) { + privateKey, err := crypto.HexToECDSA(cliCtx.String("private-key")) + if err != nil { + return nil, fmt.Errorf("invalid private key: %w", err) + } + return privateKey, nil +} + +func getSenderAddress(privateKey *ecdsa.PrivateKey) (common.Address, error) { + publicKey := privateKey.Public() + publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) + if !ok { + return common.Address{}, fmt.Errorf("error casting public key to ECDSA") + } + from := crypto.PubkeyToAddress(*publicKeyECDSA) + return from, nil +} + +// getRandomSignedTransaction returns signed tx which sends 1 wei to random address +func getRandomSignedTransaction(ctx context.Context, ethClient *ethclient.Client, rng *rand.Rand, from common.Address, privateKey *ecdsa.PrivateKey, chainId *big.Int, txType int, protected bool) (*types.Transaction, error) { + randomAddress := getRandomAddress(rng, 0xDEADBEEF) + amount := big.NewInt(1) + nonce, err := ethClient.PendingNonceAt(ctx, from) + if err != nil { + return nil, fmt.Errorf("failed to get nonce: %w", err) + } + + gasPrice, err := ethClient.SuggestGasPrice(ctx) + if err != nil { + return nil, fmt.Errorf("failed to suggest gas price: %w", err) + } + data := testutils.RandomData(rng, 10) + var txData types.TxData + switch txType { + case types.LegacyTxType: + gasLimit, err := core.IntrinsicGas(data, nil, false, true, true, false) + if err != nil { + return nil, fmt.Errorf("failed to get intrinsicGas: %w", err) + } + txData = &types.LegacyTx{ + Nonce: nonce, + GasPrice: gasPrice, + Gas: gasLimit, + To: &randomAddress, + Value: amount, + Data: data, + } + case types.AccessListTxType: + accessList := types.AccessList{types.AccessTuple{ + Address: randomAddress, + StorageKeys: []common.Hash{common.HexToHash("0x1234")}, + }} + gasLimit, err := core.IntrinsicGas(data, accessList, false, true, true, false) + if err != nil { + return nil, fmt.Errorf("failed to get intrinsicGas: %w", err) + } + txData = &types.AccessListTx{ + ChainID: chainId, + Nonce: nonce, + GasPrice: gasPrice, + Gas: gasLimit, + To: &randomAddress, + Value: amount, + AccessList: accessList, + Data: data, + } + case types.DynamicFeeTxType: + gasLimit, err := core.IntrinsicGas(data, nil, false, true, true, false) + if err != nil { + return nil, fmt.Errorf("failed to get intrinsicGas: %w", err) + } + gasTipCap, err := ethClient.SuggestGasTipCap(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get gas tip cap: %w", err) + } + txData = &types.DynamicFeeTx{ + ChainID: chainId, + Nonce: nonce, + GasTipCap: gasTipCap, + GasFeeCap: gasPrice, + Gas: gasLimit, + To: &randomAddress, + Value: amount, + Data: data, + } + default: + return nil, fmt.Errorf("unsupported tx type: %d", txType) + } + + tx := types.NewTx(txData) + + signer := types.NewLondonSigner(chainId) + if !protected { + if txType == types.LegacyTxType { + signer = types.HomesteadSigner{} + } else { + return nil, errors.New("typed tx cannot be unprotected") + } + } + + signedTx, err := types.SignTx(tx, signer, privateKey) + if err != nil { + return nil, fmt.Errorf("failed to sign transaction: %w", err) + } + return signedTx, nil +} + +// confirmTransaction polls receipts to confirm transaction is included in the block. +func confirmTransaction(ctx context.Context, ethClient *ethclient.Client, l2BlockTime uint64, txHash common.Hash) (eth.BlockID, error) { + var retryCount uint64 + for { + receipt, _ := ethClient.TransactionReceipt(ctx, txHash) + if retryCount > 30 { + return eth.BlockID{}, fmt.Errorf("transaction confirmation failure: txHash: %s", txHash.String()) + } + if receipt == nil { + log.Info("Waiting for transaction receipt", "txHash", txHash.String()) + retryCount++ + // wait at least l2 block time + time.Sleep(time.Duration(l2BlockTime) * time.Second) + continue + } + block := eth.BlockID{ + Hash: receipt.BlockHash, + Number: receipt.BlockNumber.Uint64(), + } + log.Info("Transaction receipt found", "block", block, "status", receipt.Status) + return block, nil + } +} + +// checkConsolidation sends transactions and ensures them to be included in unsafe block. +// Then polls safe head to check unsafe blocks which includes sent tx are consolidated. +func checkConsolidation(cliCtx *cli.Context) error { + ctx := context.Background() + cl, ethCl, err := newClientsFromContext(cliCtx) + if err != nil { + return err + } + pollingInterval := cliCtx.Duration("polling-interval") + privateKey, err := getPrivateKey(cliCtx) + if err != nil { + return err + } + from, err := getSenderAddress(privateKey) + if err != nil { + return err + } + txCount := cliCtx.Int("tx-count") + if txCount < 4 { + return fmt.Errorf("tx count %d is too low. requires minimum 4 txs to test all tx types", txCount) + } + l2ChainID := new(big.Int).SetUint64(cliCtx.Uint64("l2-chain-id")) + l2BlockTime := uint64(2) + rollupCfg, err := rollup.LoadOPStackRollupConfig(l2ChainID.Uint64()) + if err == nil { + l2BlockTime = rollupCfg.BlockTime + } else { + log.Warn("Superchain config not loaded", "l2-chain-id", l2ChainID) + log.Warn("Using default config", "l2-block-time", l2BlockTime) + } + rng := rand.New(rand.NewSource(1337)) + // txMap maps txHash to blockID + txMap := make(map[common.Hash]eth.BlockID) + // Submit random txs for each tx types + for i := 0; i < txCount; i++ { + txType := types.LegacyTxType + protected := true + // Generate all tx types alternately + switch i % 4 { + case 0: + protected = false // legacy unprotected TX (Homestead) + case 1: + // legacy protected TX + case 2: + txType = types.AccessListTxType + case 3: + txType = types.DynamicFeeTxType + } + tx, err := getRandomSignedTransaction(ctx, cl, rng, from, privateKey, l2ChainID, txType, protected) + if err != nil { + return err + } + err = cl.SendTransaction(ctx, tx) + if err != nil { + return fmt.Errorf("failed to send transaction: %w", err) + } + log.Info("Sent transaction", "txType", txType, "protected", protected) + txHash := tx.Hash() + blockId, err := confirmTransaction(ctx, cl, l2BlockTime, txHash) + if err != nil { + return err + } + txMap[txHash] = blockId + } + lastSafeHeadNum := uint64(0) + numChecked := 0 + failed := false + for { + safeHeadBlockId, _, err := getSafeHead(ctx, ethCl) + if err != nil { + return fmt.Errorf("failed to fetch safe head: %w", err) + } + log.Info("Fetched Safe head", "blockNum", safeHeadBlockId.Number, "hash", safeHeadBlockId.Hash.String(), "remainingTxCount", txCount-numChecked) + + for txHash, blockId := range txMap { + if lastSafeHeadNum < blockId.Number && safeHeadBlockId.Number >= blockId.Number { + safeBlockHash := safeHeadBlockId.Hash + if safeHeadBlockId.Number != blockId.Number { + safeBlock, err := retry.Do(ctx, 10, &retry.FixedStrategy{Dur: 100 * time.Millisecond}, func() (*types.Block, error) { + return cl.BlockByNumber(ctx, new(big.Int).SetUint64(blockId.Number)) + }) + if err != nil { + return fmt.Errorf("failed to fetch block by number: %w", err) + } + safeBlockHash = safeBlock.Hash() + } + if safeBlockHash == blockId.Hash { + log.Info("Transaction included at safe block", "block", blockId, "txHash", txHash.String()) + } else { + log.Error("Transaction included block is reorged", "blockNum", blockId.Number, "prevHash", blockId.Hash, "currBlock", safeBlockHash, "txHash", txHash.String()) + failed = true + } + numChecked++ + } + } + if numChecked == txCount { + if failed { + log.Error("Failed") + } else { + log.Info("Succeeded") + } + break + } + lastSafeHeadNum = safeHeadBlockId.Number + time.Sleep(pollingInterval) + } + return nil +} diff --git a/op-chain-ops/cmd/check-ecotone/main.go b/op-chain-ops/cmd/check-ecotone/main.go new file mode 100644 index 000000000000..507a20d211a3 --- /dev/null +++ b/op-chain-ops/cmd/check-ecotone/main.go @@ -0,0 +1,887 @@ +package main + +import ( + "context" + "crypto/ecdsa" + "crypto/rand" + "encoding/binary" + "errors" + "fmt" + "math/big" + "os" + "strings" + "time" + + "github.com/holiman/uint256" + "github.com/urfave/cli/v2" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + op_service "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/eth" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/opio" + "github.com/ethereum-optimism/optimism/op-service/retry" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/txmgr" +) + +func main() { + app := cli.NewApp() + app.Name = "check-ecotone" + app.Usage = "Check Ecotone upgrade results." + app.Description = "Check Ecotone upgrade results." + app.Action = func(c *cli.Context) error { + return errors.New("see sub-commands") + } + app.Writer = os.Stdout + app.ErrWriter = os.Stderr + app.Commands = []*cli.Command{ + { + Name: "cancun", + Subcommands: []*cli.Command{ + makeCommand("eip-1153-tstore", checkEIP1153), + makeCommand("eip-4844-blobhash", checkBlobDataHash), + makeCommand("eip-4844-precompile", check4844Precompile), + makeCommand("eip-5656-mcopy", checkMcopy), + makeCommand("eip-6780-selfdestruct", checkSelfdestruct), + makeCommand("eip-4844-blobtx", checkBlobTxDenial), + makeCommand("eip-4788-root", checkBeaconBlockRoot), + makeCommand("eip-4788-contract", check4788Contract), + makeCommand("all", checkAllCancun), + }, + Flags: makeFlags(), + Action: makeCommandAction(checkAllCancun), + }, + makeCommand("upgrade", checkUpgradeTxs), + { + Name: "contracts", + Subcommands: []*cli.Command{ + makeCommand("l1block", checkL1Block), + makeCommand("gpo", checkGPO), + }, + }, + makeCommand("fees", checkL1Fees), + makeCommand("all", checkALL), + { + Name: "gen-key", + Action: func(c *cli.Context) error { + key, err := crypto.GenerateKey() + if err != nil { + return err + } + fmt.Println("address: " + crypto.PubkeyToAddress(key.PublicKey).String()) + return crypto.SaveECDSA("hotkey.txt", key) + }, + }, + } + + err := app.Run(os.Args) + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Application failed: %v\n", err) + os.Exit(1) + } +} + +type actionEnv struct { + log log.Logger + l1 *ethclient.Client + l2 *ethclient.Client + rollupCl *sources.RollupClient + key *ecdsa.PrivateKey + addr common.Address + gasUsed uint64 + l1GasUsed uint64 +} + +func (ae *actionEnv) RecordGasUsed(rec *types.Receipt) { + ae.gasUsed += rec.GasUsed + ae.l1GasUsed += rec.L1GasUsed.Uint64() + ae.log.Debug("Recorded tx receipt gas", "gas_used", rec.GasUsed, "l1_gas_used", rec.L1GasUsed) +} + +type CheckAction func(ctx context.Context, env *actionEnv) error + +var ( + prefix = "CHECK_ECOTONE" + EndpointL1 = &cli.StringFlag{ + Name: "l1", + Usage: "L1 execution RPC endpoint", + EnvVars: op_service.PrefixEnvVar(prefix, "L1"), + Value: "http://localhost:8545", + } + EndpointL2 = &cli.StringFlag{ + Name: "l2", + Usage: "L2 execution RPC endpoint", + EnvVars: op_service.PrefixEnvVar(prefix, "L2"), + Value: "http://localhost:9545", + } + EndpointRollup = &cli.StringFlag{ + Name: "rollup", + Usage: "L2 rollup-node RPC endpoint", + EnvVars: op_service.PrefixEnvVar(prefix, "ROLLUP"), + Value: "http://localhost:5545", + } + AccountKey = &cli.StringFlag{ + Name: "account", + Usage: "Private key (hex-formatted string) of test account to perform test txs with", + EnvVars: op_service.PrefixEnvVar(prefix, "ACCOUNT"), + } +) + +func makeFlags() []cli.Flag { + flags := []cli.Flag{ + EndpointL1, + EndpointL2, + EndpointRollup, + AccountKey, + } + return append(flags, oplog.CLIFlags(prefix)...) +} + +func makeCommand(name string, fn CheckAction) *cli.Command { + return &cli.Command{ + Name: name, + Action: makeCommandAction(fn), + Flags: cliapp.ProtectFlags(makeFlags()), + } +} + +func makeCommandAction(fn CheckAction) func(c *cli.Context) error { + return func(c *cli.Context) error { + logCfg := oplog.ReadCLIConfig(c) + logger := oplog.NewLogger(c.App.Writer, logCfg) + + c.Context = opio.CancelOnInterrupt(c.Context) + l1Cl, err := ethclient.DialContext(c.Context, c.String(EndpointL1.Name)) + if err != nil { + return fmt.Errorf("failed to dial L1 RPC: %w", err) + } + l2Cl, err := ethclient.DialContext(c.Context, c.String(EndpointL2.Name)) + if err != nil { + return fmt.Errorf("failed to dial L2 RPC: %w", err) + } + rollupCl, err := dial.DialRollupClientWithTimeout(c.Context, time.Second*20, logger, c.String(EndpointRollup.Name)) + if err != nil { + return fmt.Errorf("failed to dial rollup node RPC: %w", err) + } + key, err := crypto.HexToECDSA(c.String(AccountKey.Name)) + if err != nil { + return fmt.Errorf("failed to parse test private key: %w", err) + } + if err := fn(c.Context, &actionEnv{ + log: logger, + l1: l1Cl, + l2: l2Cl, + rollupCl: rollupCl, + key: key, + addr: crypto.PubkeyToAddress(key.PublicKey), + }); err != nil { + return fmt.Errorf("command error: %w", err) + } + return nil + } +} + +// assuming a 0 (fail) or non-zero (success) on the stack, this performs a revert or self-destruct +func conditionalCode(data []byte) []byte { + suffix := []byte{ + // add jump dest + byte(vm.PUSH4), + 0xff, 0xff, 0xff, 0xff, + byte(vm.JUMPI), + // error case + byte(vm.PUSH0), + byte(vm.PUSH0), + byte(vm.REVERT), + // success case + byte(vm.JUMPDEST), + byte(vm.CALLER), + byte(vm.SELFDESTRUCT), + byte(vm.STOP), + } + binary.BigEndian.PutUint32(suffix[1:5], uint32(len(data))+9) + out := make([]byte, 0, len(data)+len(suffix)) + out = append(out, data...) + out = append(out, suffix...) + return out +} + +func checkEIP1153(ctx context.Context, env *actionEnv) error { + input := conditionalCode([]byte{ + // store 0xc0ffee at 0x42 + byte(vm.PUSH3), + 0xc0, 0xff, 0xee, + byte(vm.PUSH1), + 0x42, + byte(vm.TSTORE), + // retrieve it + byte(vm.PUSH1), + 0x42, + byte(vm.TLOAD), + // check value + byte(vm.PUSH3), + 0xc0, 0xff, 0xee, + byte(vm.EQ), + }) + if err := execTx(ctx, nil, input, false, env); err != nil { + return err + } + env.log.Info("eip-1153 transient storage test: success") + return nil +} + +func checkBlobDataHash(ctx context.Context, env *actionEnv) error { + // revert on non-blob tx + input := []byte{ + byte(vm.BLOBHASH), + } + if err := execTx(ctx, nil, input, true, env); err != nil { + return err + } + env.log.Info("4844 blob-data-hash test: success") + return nil +} + +// Deploy a contract that calls the EIP-4844 blob verification precompile with valid proof, +// and check if it verifies the proof successfully. +func check4844Precompile(ctx context.Context, env *actionEnv) error { + var x eth.Blob + if err := x.FromData(eth.Data("remember ethers phoenix")); err != nil { + return fmt.Errorf("failed to construct blob: %w", err) + } + commitment, err := x.ComputeKZGCommitment() + if err != nil { + return fmt.Errorf("failed to compute commitment: %w", err) + } + point := kzg4844.Point{} + proof, claim, err := kzg4844.ComputeProof(kzg4844.Blob(x), point) + if err != nil { + return fmt.Errorf("failed to compute proof: %w", err) + } + versionedHash := eth.KZGToVersionedHash(commitment) + + var inner []byte + mstore32 := func(v []byte, offset uint8) { + if len(v) != 32 { + panic("invalid v") + } + inner = append(inner, byte(vm.PUSH32)) + inner = append(inner, v...) + inner = append(inner, byte(vm.PUSH1), offset, byte(vm.MSTORE)) + } + + // prepare input in memory, following EIP-4844: + // versioned_hash = input[:32] + // z = input[32:64] + // y = input[64:96] + // commitment = input[96:144] + // proof = input[144:192] + // + // the call verify p(z) = y + mstore32(versionedHash[:], 0) // versioned hash + mstore32(point[:], 32) // z + mstore32(claim[:], 64) // y + mstore32(commitment[0:32], 96) + mstore32(append(append([]byte{}, commitment[32:48]...), proof[0:16]...), 96+32) + mstore32(proof[16:48], 144+16) + env.log.Info(fmt.Sprintf("4844 precompile test: verifying p(%x) == %x for commitment %x proof %x", point[:], claim[:], commitment[:], proof[:])) + + inner = append(inner, []byte{ + byte(vm.PUSH0), // retSize + byte(vm.PUSH0), // retOffset + byte(vm.PUSH1), // argsSize + byte(192), + byte(vm.PUSH0), // argsOffset + byte(vm.PUSH1), // precompile address + byte(0x0A), + byte(vm.GAS), // gas (supply all gas) + byte(vm.STATICCALL), // run call + // 0 will be on stack if call reverts, 1 otherwise + // now get the return-data size, and multiply it. To ensure size == 0 counts as failed call. + byte(vm.RETURNDATASIZE), + byte(vm.MUL), + }...) + + input := conditionalCode(inner) + if err := execTx(ctx, nil, input, false, env); err != nil { + return fmt.Errorf("precompile check failed: %w", err) + } + env.log.Info("eip-4844 precompile test: success") + return nil +} + +func check4788Contract(ctx context.Context, env *actionEnv) error { + head, err := env.l2.HeaderByNumber(ctx, nil) + if err != nil { + return err + } + // reverts on all-0 time input + if err := execTx(ctx, &predeploys.EIP4788ContractAddr, make([]byte, 32), true, env); err != nil { + return fmt.Errorf("expected revert on empty input: %w", err) + } + + conf, err := env.rollupCl.RollupConfig(ctx) + if err != nil { + return fmt.Errorf("config retrieval failed: %w", err) + } + t := head.Time + alignment := head.Time % conf.BlockTime + for i := 0; i < 20; i++ { + ti := t - uint64(i) + if !conf.IsEcotone(ti) { + continue + } + env.log.Info("Beacon block root query timestamp", "query_timestamp", ti) + // revert when timestamp doesn't exist (when not aligned it won't exist), + // or when we call it at the activation block and the contract was newly deployed + // (the beacon block root is processed at the start of the block, + // but the contract might not exist yet, during activation). + revert := ti%conf.BlockTime != alignment + if conf.IsEcotoneActivationBlock(ti) { + // if the contract already existed, then we deployed the nonce=1 contract during upgrade + code, err := env.l2.CodeAt(ctx, crypto.CreateAddress(derive.EIP4788From, 1), nil) + if err != nil { + return fmt.Errorf("failed to check code: %w", err) + } + revert = revert || len(code) == 0 + } + input := new(uint256.Int).SetUint64(ti).Bytes32() + if err := execTx(ctx, &predeploys.EIP4788ContractAddr, input[:], revert, env); err != nil { + return fmt.Errorf("failed at t = %d", ti) + } + } + env.log.Info("eip-4788 beacon block-roots contract test: success") + return nil +} + +func checkMcopy(ctx context.Context, env *actionEnv) error { + input := conditionalCode([]byte{ + // push info & mstore it + byte(vm.PUSH3), + 0xc0, 0xff, 0xee, + byte(vm.PUSH0), // store at 0 + byte(vm.MSTORE), + // copy the memory + byte(vm.PUSH1), // length + 0x2, // only copy the C0FF part + byte(vm.PUSH1), // src + 32 - 3, // right-aligned bytes3 + byte(vm.PUSH1), // dst + 0x42, + byte(vm.MCOPY), + byte(vm.PUSH1), // copy from destination + 0x42 - (32 - 3), // a little to the left, so it's left-padded + byte(vm.MLOAD), // load the memory from copied location + // check if it matches, with zero 3rd byte + byte(vm.PUSH3), + 0xc0, 0xff, 0x00, + byte(vm.EQ), + }) + if err := execTx(ctx, nil, input, false, env); err != nil { + return err + } + env.log.Info("eip-5656 mcopy test: success") + return nil +} + +func checkSelfdestruct(ctx context.Context, env *actionEnv) error { + input := conditionalCode([]byte{ + // prepare code in memory + byte(vm.PUSH2), // value + byte(vm.CALLER), + byte(vm.SELFDESTRUCT), + byte(vm.PUSH1), // offset + byte(vm.MSTORE), + // create contract + byte(vm.PUSH1), // size, just a 2 byte contract + 2, + byte(vm.PUSH0), // ETH value + byte(vm.PUSH0), // offset + byte(vm.CREATE), // pushes address on stack. Contract will immediately self-destruct + byte(vm.EXTCODESIZE), // size should be 0 + byte(vm.ISZERO), // check that it is + }) + if err := execTx(ctx, nil, input, false, env); err != nil { + return err + } + env.log.Info("eip-6780 self-destruct test: success") + return nil +} + +func execTx(ctx context.Context, to *common.Address, data []byte, expectRevert bool, env *actionEnv) error { + nonce, err := env.l2.PendingNonceAt(ctx, env.addr) + if err != nil { + return fmt.Errorf("pending nonce retrieval failed: %w", err) + } + head, err := env.l2.HeaderByNumber(context.Background(), nil) + if err != nil { + return fmt.Errorf("failed to retrieve head header: %w", err) + } + + tip := big.NewInt(params.GWei) + maxFee := new(big.Int).Mul(head.BaseFee, big.NewInt(2)) + maxFee = maxFee.Add(maxFee, tip) + + chainID, err := env.l2.ChainID(ctx) + if err != nil { + return fmt.Errorf("failed to get chainID: %w", err) + } + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainID, Nonce: nonce, + GasTipCap: tip, GasFeeCap: maxFee, Gas: 500000, To: to, Data: data, + }) + signer := types.NewCancunSigner(chainID) + signedTx, err := types.SignTx(tx, signer, env.key) + if err != nil { + return fmt.Errorf("failed to sign tx: %w", err) + } + + env.log.Info("sending tx", "txhash", signedTx.Hash(), "to", to, "data", hexutil.Bytes(data)) + if err := env.l2.SendTransaction(ctx, signedTx); err != nil { + return fmt.Errorf("failed to send tx: %w", err) + } + for i := 0; i < 30; i++ { + env.log.Info("checking confirmation...", "txhash", signedTx.Hash()) + receipt, err := env.l2.TransactionReceipt(context.Background(), signedTx.Hash()) + if err != nil { + if strings.Contains(err.Error(), "not found") { + env.log.Info("not found yet, waiting...") + time.Sleep(time.Second) + continue + } else { + return fmt.Errorf("error while checking tx receipt: %w", err) + } + } + env.RecordGasUsed(receipt) + if expectRevert { + if receipt.Status == types.ReceiptStatusFailed { + env.log.Info("tx reverted as expected", "txhash", signedTx.Hash()) + return nil + } else { + return fmt.Errorf("tx %s unexpectedly completed without revert", signedTx.Hash()) + } + } else { + if receipt.Status == types.ReceiptStatusSuccessful { + env.log.Info("tx confirmed", "txhash", signedTx.Hash()) + return nil + } else { + return fmt.Errorf("tx %s failed", signedTx.Hash()) + } + } + } + return fmt.Errorf("failed to confirm tx: %s", signedTx.Hash()) +} + +func checkBlobTxDenial(ctx context.Context, env *actionEnv) error { + // verify we cannot submit a blob tx to RPC + var blob eth.Blob + _, err := rand.Read(blob[:]) + if err != nil { + return fmt.Errorf("failed randomnes: %w", err) + } + // get the field-elements into a valid range + for i := 0; i < 4096; i++ { + blob[32*i] &= 0b0011_1111 + } + sidecar, blobHashes, err := txmgr.MakeSidecar([]*eth.Blob{&blob}) + if err != nil { + return fmt.Errorf("failed to make sidecar: %w", err) + } + latestHeader, err := env.l1.HeaderByNumber(ctx, nil) + if err != nil { + return fmt.Errorf("failed to get header: %w", err) + } + if latestHeader.ExcessBlobGas == nil { + return fmt.Errorf("the L1 block %s (time %d) is not ecotone yet", latestHeader.Hash(), latestHeader.Time) + } + blobBaseFee := eip4844.CalcBlobFee(*latestHeader.ExcessBlobGas) + blobFeeCap := new(uint256.Int).Mul(uint256.NewInt(2), uint256.MustFromBig(blobBaseFee)) + if blobFeeCap.Lt(uint256.NewInt(params.GWei)) { // ensure we meet 1 gwei geth tx-pool minimum + blobFeeCap = uint256.NewInt(params.GWei) + } + gasTipCap := big.NewInt(2 * params.GWei) + gasFeeCap := new(big.Int).Add(gasTipCap, new(big.Int).Mul(latestHeader.BaseFee, big.NewInt(2))) + + nonce, err := env.l2.PendingNonceAt(ctx, env.addr) + if err != nil { + return fmt.Errorf("failed to get pending nonce: %w", err) + } + rollupCfg, err := env.rollupCl.RollupConfig(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve rollup config: %w", err) + } + txData := &types.BlobTx{ + To: rollupCfg.BatchInboxAddress, + Data: nil, + Gas: params.TxGas, // intrinsic gas only + BlobHashes: blobHashes, + Sidecar: sidecar, + ChainID: uint256.MustFromBig(rollupCfg.L2ChainID), + GasTipCap: uint256.MustFromBig(gasTipCap), + GasFeeCap: uint256.MustFromBig(gasFeeCap), + BlobFeeCap: blobFeeCap, + Value: uint256.NewInt(0), + Nonce: nonce, + } + // bypass signer filter by creating it manually and using the L2 chain ID + signer := types.NewCancunSigner(rollupCfg.L2ChainID) + tx, err := types.SignNewTx(env.key, signer, txData) + if err != nil { + return fmt.Errorf("failed to sign blob tx: %w", err) + } + err = env.l2.SendTransaction(ctx, tx) + if err == nil { + return errors.New("expected tx error, but got none") + } + if !strings.Contains(err.Error(), "transaction type not supported") { + return fmt.Errorf("unexpected tx submission error: %w", err) + } + env.log.Info("blob-tx denial test: success") + return nil +} + +func checkBeaconBlockRoot(ctx context.Context, env *actionEnv) error { + latest, err := env.l2.HeaderByNumber(ctx, nil) + if err != nil { + return fmt.Errorf("failed to get latest block: %w", err) + } + if latest.ParentBeaconRoot == nil { + return fmt.Errorf("block %d misses beacon block root", latest.Number) + } + beaconBlockRootsContract, err := env.l2.CodeAt(ctx, predeploys.EIP4788ContractAddr, nil) + if err != nil { + return fmt.Errorf("failed to retrieve beacon block root contract code: %w", err) + } + codeHash := crypto.Keccak256Hash(beaconBlockRootsContract) + if codeHash != predeploys.EIP4788ContractCodeHash { + return fmt.Errorf("unexpected 4788 contract code: %w", err) + } + + rollupCfg, err := env.rollupCl.RollupConfig(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve rollup config: %w", err) + } + l2RPC := client.NewBaseRPCClient(env.l2.Client()) + l2EthCl, err := sources.NewL2Client(l2RPC, env.log, nil, + sources.L2ClientDefaultConfig(rollupCfg, false)) + if err != nil { + return fmt.Errorf("failed to create eth client") + } + result, err := l2EthCl.GetProof(ctx, predeploys.EIP4788ContractAddr, nil, eth.Unsafe) + if err != nil { + return fmt.Errorf("failed to get account proof to inspect storage-root") + } + if result.StorageHash == types.EmptyRootHash { + return fmt.Errorf("expected contract storage to be set, but got none (%s)", + result.StorageHash) + } + + payload, err := l2EthCl.PayloadByLabel(ctx, eth.Unsafe) + if err != nil { + return fmt.Errorf("failed to get head ref: %w", err) + } + if payload.ParentBeaconBlockRoot == nil { + return fmt.Errorf("payload %s misses parent beacon block root", payload.ExecutionPayload.ID()) + } + headRef, err := derive.PayloadToBlockRef(rollupCfg, payload.ExecutionPayload) + if err != nil { + return fmt.Errorf("failed to convert to block-ref: %w", err) + } + l1Header, err := retry.Do(ctx, 5, retry.Fixed(time.Second*12), func() (*types.Header, error) { + env.log.Info("retrieving L1 origin...", "l1", headRef.L1Origin) + return env.l1.HeaderByHash(ctx, headRef.L1Origin.Hash) + }) + if err != nil { + return fmt.Errorf("failed to retrieve L1 origin %s of L2 block %s: %w", headRef.L1Origin, headRef, err) + } + var l1ParentBeaconBlockRoot common.Hash // zero before Dencun activates on L1 + if l1Header.ParentBeaconRoot != nil { + l1ParentBeaconBlockRoot = *l1Header.ParentBeaconRoot + } + if l1ParentBeaconBlockRoot != *payload.ParentBeaconBlockRoot { + return fmt.Errorf("parent beacon block root mismatch, L1: %s, L2: %s", + l1ParentBeaconBlockRoot, *payload.ParentBeaconBlockRoot) + } + env.log.Info("beacon-block-root block-content test: success") + return nil +} + +func checkAllCancun(ctx context.Context, env *actionEnv) error { + if err := checkEIP1153(ctx, env); err != nil { + return fmt.Errorf("eip-1153 error: %w", err) + } + if err := checkBlobDataHash(ctx, env); err != nil { + return fmt.Errorf("eip-4844 blobhash error: %w", err) + } + if err := check4844Precompile(ctx, env); err != nil { + return fmt.Errorf("eip-4844 precompile error: %w", err) + } + if err := checkMcopy(ctx, env); err != nil { + return fmt.Errorf("eip-5656 mcopy error: %w", err) + } + if err := checkSelfdestruct(ctx, env); err != nil { + return fmt.Errorf("eip-6780 selfdestruct error: %w", err) + } + if err := checkBlobTxDenial(ctx, env); err != nil { + return fmt.Errorf("eip-4844 blob-tx denial error: %w", err) + } + if err := checkBeaconBlockRoot(ctx, env); err != nil { + return fmt.Errorf("eip-4788 beacon-block-roots error: %w", err) + } + if err := check4788Contract(ctx, env); err != nil { + return fmt.Errorf("eip-4788 contract check error: %w", err) + } + env.log.Info("completed Cancun feature tests successfully") + return nil +} + +func checkUpgradeTxs(ctx context.Context, env *actionEnv) error { + rollupCfg, err := env.rollupCl.RollupConfig(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve rollup config: %w", err) + } + + activationBlockNum := rollupCfg.Genesis.L2.Number + + ((*rollupCfg.EcotoneTime - rollupCfg.Genesis.L2Time) / rollupCfg.BlockTime) + env.log.Info("upgrade block num", "num", activationBlockNum) + l2RPC := client.NewBaseRPCClient(env.l2.Client()) + l2EthCl, err := sources.NewL2Client(l2RPC, env.log, nil, + sources.L2ClientDefaultConfig(rollupCfg, false)) + if err != nil { + return fmt.Errorf("failed to create eth client") + } + activBlock, txs, err := l2EthCl.InfoAndTxsByNumber(ctx, activationBlockNum) + if err != nil { + return fmt.Errorf("failed to get activation block: %w", err) + } + if len(txs) < 7 { + return fmt.Errorf("expected at least 7 txs in Ecotone activation block, but got %d", len(txs)) + } + for i, tx := range txs { + if !tx.IsDepositTx() { + return fmt.Errorf("unexpected non-deposit tx in activation block, index %d, hash %s", i, tx.Hash()) + } + } + _, receipts, err := l2EthCl.FetchReceipts(ctx, activBlock.Hash()) + if err != nil { + return fmt.Errorf("failed to fetch receipts of activation block: %w", err) + } + for i, rec := range receipts { + if rec.Status != types.ReceiptStatusSuccessful { + return fmt.Errorf("failed tx receipt: %d", i) + } + switch i { + case 1, 2, 6: // 2 implementations + 4788 contract deployment + if rec.ContractAddress == (common.Address{}) { + return fmt.Errorf("expected contract deployment, but got none") + } + case 3, 4, 5: // proxy upgrades and setEcotone call + if rec.ContractAddress != (common.Address{}) { + return fmt.Errorf("unexpected contract deployment") + } + } + } + env.log.Info("upgrade-txs receipts test: success") + return nil +} + +func checkL1Block(ctx context.Context, env *actionEnv) error { + cl, err := bindings.NewL1Block(predeploys.L1BlockAddr, env.l2) + if err != nil { + return fmt.Errorf("failed to create bindings around L1Block contract: %w", err) + } + blobBaseFee, err := cl.BlobBaseFee(nil) + if err != nil { + return fmt.Errorf("failed to get blob basfee from L1Block contract: %w", err) + } + if big.NewInt(0).Cmp(blobBaseFee) == 0 { + return errors.New("blob basefee must never be 0, EIP specifies minimum of 1") + } + env.log.Info("l1-block-info test: success") + return nil +} + +func checkGPO(ctx context.Context, env *actionEnv) error { + cl, err := bindings.NewGasPriceOracle(predeploys.GasPriceOracleAddr, env.l2) + if err != nil { + return fmt.Errorf("failed to create bindings around L1Block contract: %w", err) + } + _, err = cl.Overhead(nil) + if err == nil || !strings.Contains(err.Error(), "revert") { + return fmt.Errorf("expected revert on legacy overhead attribute acccess, but got %w", err) + } + _, err = cl.Scalar(nil) + if err == nil || !strings.Contains(err.Error(), "revert") { + return fmt.Errorf("expected revert on legacy scalar attribute acccess, but got %w", err) + } + isEcotone, err := cl.IsEcotone(nil) + if err != nil { + return fmt.Errorf("failed to get ecotone status: %w", err) + } + if !isEcotone { + return fmt.Errorf("GPO is not set to ecotone: %w", err) + } + blobBaseFeeScalar, err := cl.BlobBaseFeeScalar(nil) + if err != nil { + return fmt.Errorf("unable to get blob basefee scalar: %w", err) + } + if blobBaseFeeScalar == 0 { + env.log.Warn("blob basefee scalar is set to 0. SystemConfig needs to emit scalar change to update.") + } + env.log.Info("GPO test: success") + return nil +} + +func checkL1Fees(ctx context.Context, env *actionEnv) error { + rollupCfg, err := env.rollupCl.RollupConfig(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve rollup config: %w", err) + } + env.log.Info("making test tx", "addr", env.addr) + nonce, err := env.l2.PendingNonceAt(ctx, env.addr) + if err != nil { + return fmt.Errorf("failed to get pending nonce: %w", err) + } + env.log.Info("retrieved account nonce", "nonce", nonce) + l2RPC := client.NewBaseRPCClient(env.l2.Client()) + l2EthCl, err := sources.NewL2Client(l2RPC, env.log, nil, + sources.L2ClientDefaultConfig(rollupCfg, false)) + if err != nil { + return fmt.Errorf("failed to create eth client: %w", err) + } + head, err := env.l2.HeaderByNumber(ctx, nil) + if err != nil { + return fmt.Errorf("failed to get head: %w", err) + } + gasTip := big.NewInt(2 * params.GWei) + gasMaxFee := new(big.Int).Add( + new(big.Int).Mul(big.NewInt(2), head.BaseFee), gasTip) + to := common.Address{1, 2, 3, 5} + txData := &types.DynamicFeeTx{ + ChainID: rollupCfg.L2ChainID, + Nonce: nonce, + GasTipCap: gasTip, + GasFeeCap: gasMaxFee, + Gas: params.TxGas + 100, // some margin for the calldata + To: &to, + Value: big.NewInt(3 * params.GWei), + Data: []byte("hello"), + AccessList: nil, + } + tx, err := types.SignNewTx(env.key, types.NewLondonSigner(txData.ChainID), txData) + if err != nil { + return fmt.Errorf("failed to sign test tx: %w", err) + } + env.log.Info("signed tx", "txhash", tx.Hash()) + if err := env.l2.SendTransaction(ctx, tx); err != nil { + return fmt.Errorf("failed to send test tx: %w", err) + } + receipt, err := retry.Do(ctx, 20, retry.Fixed(time.Second*2), func() (*types.Receipt, error) { + return env.l2.TransactionReceipt(ctx, tx.Hash()) + }) + if err != nil { + return fmt.Errorf("failed to confirm tx %s timely: %w", tx.Hash(), err) + } + env.RecordGasUsed(receipt) + if receipt.Status != types.ReceiptStatusSuccessful { + return fmt.Errorf("transaction failed, L1 gas used: %d", receipt.L1GasUsed) + } + env.log.Info("got receipt", "hash", tx.Hash(), "block", receipt.BlockHash) + if receipt.FeeScalar != nil { + return fmt.Errorf("expected fee scalar attribute to be deprecated, but got %v", receipt.FeeScalar) + } + payload, err := l2EthCl.PayloadByHash(ctx, receipt.BlockHash) + if err != nil { + return fmt.Errorf("failed to get head ref: %w", err) + } + headRef, err := derive.PayloadToBlockRef(rollupCfg, payload.ExecutionPayload) + if err != nil { + return fmt.Errorf("failed to convert to block-ref: %w", err) + } + l1Header, err := retry.Do(ctx, 5, retry.Fixed(time.Second*12), func() (*types.Header, error) { + env.log.Info("retrieving L1 origin...", "l1", headRef.L1Origin) + return env.l1.HeaderByHash(ctx, headRef.L1Origin.Hash) + }) + if err != nil { + return fmt.Errorf("failed to retrieve L1 origin %s of L2 block %s: %w", headRef.L1Origin, headRef, err) + } + if receipt.L1GasPrice.Cmp(l1Header.BaseFee) != 0 { + return fmt.Errorf("L1 gas price does not include blob fee component: %d != %d", receipt.L1GasPrice, l1Header.BaseFee) + } + rawTx, err := tx.MarshalBinary() + if err != nil { + return fmt.Errorf("failed to encode tx: %w", err) + } + var zero, nonZero uint64 + for _, b := range rawTx { + if b == 0 { + zero += 1 + } else { + nonZero += 1 + } + } + expectedCalldataGas := zero*4 + nonZero*16 + env.log.Info("expecting fees", "calldatagas", expectedCalldataGas) + env.log.Info("paid fees", "l1_fee", receipt.L1Fee, "l1_basefee", receipt.L1GasPrice) + if new(big.Int).SetUint64(expectedCalldataGas).Cmp(receipt.L1GasUsed) != 0 { + return fmt.Errorf("expected %d L1 gas, but only spent %d", expectedCalldataGas, receipt.L1GasUsed) + } + if big.NewInt(0).Cmp(receipt.L1Fee) >= 0 { + return fmt.Errorf("calculated to low L1 fee: %d", receipt.L1Fee) + } + env.log.Info("L1 fees test: success") + return nil +} + +func checkALL(ctx context.Context, env *actionEnv) error { + bal, err := env.l2.BalanceAt(ctx, env.addr, nil) + if err != nil { + return fmt.Errorf("failed to check balance of account: %w", err) + } + env.log.Info("starting checks, tx account", "addr", env.addr, "balance_wei", bal) + + if err := checkAllCancun(ctx, env); err != nil { + return fmt.Errorf("failed: Cancun error: %w", err) + } + if err := checkUpgradeTxs(ctx, env); err != nil { + return fmt.Errorf("failed: Upgrade-tx error: %w", err) + } + if err := checkL1Block(ctx, env); err != nil { + return fmt.Errorf("failed: L1Block contract error: %w", err) + } + if err := checkGPO(ctx, env); err != nil { + return fmt.Errorf("failed: GPO contract error: %w", err) + } + if err := checkL1Fees(ctx, env); err != nil { + return fmt.Errorf("failed: L1 fees error: %w", err) + } + + finbal, err := env.l2.BalanceAt(ctx, env.addr, nil) + if err != nil { + return fmt.Errorf("failed to check final balance of account: %w", err) + } + env.log.Info("completed all tests successfully!", + "addr", env.addr, "balance_wei", finbal, + "spent_wei", new(big.Int).Sub(bal, finbal), + "gas_used_total", env.gasUsed, + "l1_gas_used_total", env.l1GasUsed, + ) + + return nil +} diff --git a/op-chain-ops/cmd/check-l2/main.go b/op-chain-ops/cmd/check-l2/main.go deleted file mode 100644 index c4ba3f7d881e..000000000000 --- a/op-chain-ops/cmd/check-l2/main.go +++ /dev/null @@ -1,920 +0,0 @@ -package main - -import ( - "bytes" - "context" - "errors" - "fmt" - "math/big" - "os" - - "golang.org/x/sync/errgroup" - - "github.com/mattn/go-isatty" - "github.com/urfave/cli/v2" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-bindings/predeploys" - "github.com/ethereum-optimism/optimism/op-chain-ops/clients" - "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/log" -) - -var defaultCrossDomainMessageSender = common.HexToAddress("0x000000000000000000000000000000000000dead") - -// Default script for checking that L2 has been configured correctly. This should be extended in the future -// to pull in L1 deploy artifacts and assert that the L2 state is consistent with the L1 state. -func main() { - log.Root().SetHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(isatty.IsTerminal(os.Stderr.Fd())))) - - app := &cli.App{ - Name: "check-l2", - Usage: "Check that an OP Stack L2 has been configured correctly", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "l1-rpc-url", - Value: "http://127.0.0.1:8545", - Usage: "L1 RPC URL", - EnvVars: []string{"L1_RPC_URL"}, - }, - &cli.StringFlag{ - Name: "l2-rpc-url", - Value: "http://127.0.0.1:9545", - Usage: "L2 RPC URL", - EnvVars: []string{"L2_RPC_URL"}, - }, - }, - Action: entrypoint, - } - - if err := app.Run(os.Args); err != nil { - log.Crit("error checking l2", "err", err) - } -} - -// entrypoint is the entrypoint for the check-l2 script -func entrypoint(ctx *cli.Context) error { - clients, err := clients.NewClientsFromContext(ctx) - if err != nil { - return err - } - - log.Info("Checking predeploy proxy config") - g := new(errgroup.Group) - - // Check that all proxies are configured correctly - // Do this in parallel but not too quickly to allow for - // querying against rate limiting RPC backends - count := uint64(2048) - for i := uint64(0); i < count; i++ { - i := i - if i%4 == 0 { - log.Info("Checking proxy", "index", i, "total", count) - if err := g.Wait(); err != nil { - return err - } - } - g.Go(func() error { - return checkPredeploy(clients.L2Client, i) - }) - } - - if err := g.Wait(); err != nil { - return err - } - log.Info("All predeploy proxies are set correctly") - - // Check that all of the defined predeploys are set up correctly - for name, addr := range predeploys.Predeploys { - log.Info("Checking predeploy", "name", name, "address", addr.Hex()) - if err := checkPredeployConfig(clients.L2Client, name); err != nil { - return err - } - } - return nil -} - -// checkPredeploy ensures that the predeploy at index i has the correct proxy admin set -func checkPredeploy(client *ethclient.Client, i uint64) error { - bigAddr := new(big.Int).Or(genesis.BigL2PredeployNamespace, new(big.Int).SetUint64(i)) - addr := common.BigToAddress(bigAddr) - if !predeploys.IsProxied(addr) { - return nil - } - admin, err := getEIP1967AdminAddress(client, addr) - if err != nil { - return err - } - if admin != predeploys.ProxyAdminAddr { - return fmt.Errorf("%s does not have correct proxy admin set", addr) - } - return nil -} - -// checkPredeployConfig checks that the defined predeploys are configured correctly -func checkPredeployConfig(client *ethclient.Client, name string) error { - predeploy := predeploys.Predeploys[name] - if predeploy == nil { - return fmt.Errorf("unknown predeploy %s", name) - } - p := *predeploy - - g := new(errgroup.Group) - if predeploys.IsProxied(p) { - // Check that an implementation is set. If the implementation has been upgraded, - // it will be considered non-standard. Ensure that there is code set at the implementation. - g.Go(func() error { - impl, err := getEIP1967ImplementationAddress(client, p) - if err != nil { - return err - } - log.Info(name, "implementation", impl.Hex()) - standardImpl, err := genesis.AddressToCodeNamespace(p) - if err != nil { - return err - } - if impl != standardImpl { - log.Warn("%s does not have the standard implementation", name) - } - implCode, err := client.CodeAt(context.Background(), impl, nil) - if err != nil { - return err - } - if len(implCode) == 0 { - return fmt.Errorf("%s implementation is not deployed", name) - } - return nil - }) - - // Ensure that the code is set to the proxy bytecode as expected - g.Go(func() error { - proxyCode, err := client.CodeAt(context.Background(), p, nil) - if err != nil { - return err - } - proxy, err := bindings.GetDeployedBytecode("Proxy") - if err != nil { - return err - } - if !bytes.Equal(proxyCode, proxy) { - return fmt.Errorf("%s does not have the standard proxy code", name) - } - return nil - }) - } - - // Check the predeploy specific config is correct - g.Go(func() error { - switch p { - case predeploys.LegacyMessagePasserAddr: - if err := checkLegacyMessagePasser(p, client); err != nil { - return err - } - - case predeploys.DeployerWhitelistAddr: - if err := checkDeployerWhitelist(p, client); err != nil { - return err - } - - case predeploys.L2CrossDomainMessengerAddr: - if err := checkL2CrossDomainMessenger(p, client); err != nil { - return err - } - - case predeploys.GasPriceOracleAddr: - if err := checkGasPriceOracle(p, client); err != nil { - return err - } - - case predeploys.L2StandardBridgeAddr: - if err := checkL2StandardBridge(p, client); err != nil { - return err - } - - case predeploys.SequencerFeeVaultAddr: - if err := checkSequencerFeeVault(p, client); err != nil { - return err - } - - case predeploys.OptimismMintableERC20FactoryAddr: - if err := checkOptimismMintableERC20Factory(p, client); err != nil { - return err - } - - case predeploys.L1BlockNumberAddr: - if err := checkL1BlockNumber(p, client); err != nil { - return err - } - - case predeploys.L1BlockAddr: - if err := checkL1Block(p, client); err != nil { - return err - } - - case predeploys.WETH9Addr: - if err := checkWETH9(p, client); err != nil { - return err - } - - case predeploys.GovernanceTokenAddr: - if err := checkGovernanceToken(p, client); err != nil { - return err - } - - case predeploys.L2ERC721BridgeAddr: - if err := checkL2ERC721Bridge(p, client); err != nil { - return err - } - - case predeploys.OptimismMintableERC721FactoryAddr: - if err := checkOptimismMintableERC721Factory(p, client); err != nil { - return err - } - - case predeploys.ProxyAdminAddr: - if err := checkProxyAdmin(p, client); err != nil { - return err - } - - case predeploys.BaseFeeVaultAddr: - if err := checkBaseFeeVault(p, client); err != nil { - return err - } - - case predeploys.L1FeeVaultAddr: - if err := checkL1FeeVault(p, client); err != nil { - return err - } - - case predeploys.L2ToL1MessagePasserAddr: - if err := checkL2ToL1MessagePasser(p, client); err != nil { - return err - } - - case predeploys.SchemaRegistryAddr: - if err := checkSchemaRegistry(p, client); err != nil { - return err - } - - case predeploys.EASAddr: - if err := checkEAS(p, client); err != nil { - return err - } - } - return nil - }) - - if err := g.Wait(); err != nil { - return err - } - - return nil -} - -func checkL2ToL1MessagePasser(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewL2ToL1MessagePasser(addr, client) - if err != nil { - return err - } - messageVersion, err := contract.MESSAGEVERSION(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2ToL1MessagePasser", "MESSAGE_VERSION", messageVersion) - - messageNonce, err := contract.MessageNonce(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2ToL1MessagePasser", "MESSAGE_NONCE", messageNonce) - return nil -} - -func checkL1FeeVault(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewL1FeeVault(addr, client) - if err != nil { - return err - } - recipient, err := contract.RECIPIENT(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L1FeeVault", "RECIPIENT", recipient.Hex()) - if recipient == (common.Address{}) { - return errors.New("RECIPIENT should not be address(0)") - } - - minWithdrawalAmount, err := contract.MINWITHDRAWALAMOUNT(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L1FeeVault", "MIN_WITHDRAWAL_AMOUNT", minWithdrawalAmount) - - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L1FeeVault version", "version", version) - return nil -} - -func checkBaseFeeVault(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewBaseFeeVault(addr, client) - if err != nil { - return err - } - recipient, err := contract.RECIPIENT(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("BaseFeeVault", "RECIPIENT", recipient.Hex()) - if recipient == (common.Address{}) { - return errors.New("RECIPIENT should not be address(0)") - } - - minWithdrawalAmount, err := contract.MINWITHDRAWALAMOUNT(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("BaseFeeVault", "MIN_WITHDRAWAL_AMOUNT", minWithdrawalAmount) - - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("BaseFeeVault version", "version", version) - return nil -} - -func checkProxyAdmin(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewProxyAdmin(addr, client) - if err != nil { - return err - } - - owner, err := contract.Owner(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("ProxyAdmin", "owner", owner.Hex()) - if owner == (common.Address{}) { - return errors.New("ProxyAdmin.owner is zero address") - } - - addressManager, err := contract.AddressManager(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("ProxyAdmin", "addressManager", addressManager.Hex()) - return nil -} - -func checkOptimismMintableERC721Factory(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewOptimismMintableERC721Factory(addr, client) - if err != nil { - return err - } - bridge, err := contract.BRIDGE(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("OptimismMintableERC721Factory", "BRIDGE", bridge.Hex()) - if bridge == (common.Address{}) { - return errors.New("OptimismMintableERC721Factory.BRIDGE is zero address") - } - - remoteChainID, err := contract.REMOTECHAINID(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("OptimismMintableERC721Factory", "REMOTE_CHAIN_ID", remoteChainID) - - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("OptimismMintableERC721Factory version", "version", version) - return nil -} - -func checkL2ERC721Bridge(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewL2ERC721Bridge(addr, client) - if err != nil { - return err - } - messenger, err := contract.MESSENGER(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2ERC721Bridge", "MESSENGER", messenger.Hex()) - if messenger == (common.Address{}) { - return errors.New("L2ERC721Bridge.MESSENGER is zero address") - } - - otherBridge, err := contract.OTHERBRIDGE(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2ERC721Bridge", "OTHERBRIDGE", otherBridge.Hex()) - if otherBridge == (common.Address{}) { - return errors.New("L2ERC721Bridge.OTHERBRIDGE is zero address") - } - - initialized, err := getInitialized("L2ERC721Bridge", addr, client) - if err != nil { - return err - } - log.Info("L2ERC721Bridge", "_initialized", initialized) - - initializing, err := getInitializing("L2ERC721Bridge", addr, client) - if err != nil { - return err - } - log.Info("L2ERC721Bridge", "_initializing", initializing) - - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2ERC721Bridge version", "version", version) - return nil -} - -func checkGovernanceToken(addr common.Address, client *ethclient.Client) error { - code, err := client.CodeAt(context.Background(), addr, nil) - if err != nil { - return err - } - - if len(code) > 0 { - // This should also check the owner - contract, err := bindings.NewERC20(addr, client) - if err != nil { - return err - } - name, err := contract.Name(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("GovernanceToken", "name", name) - symbol, err := contract.Symbol(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("GovernanceToken", "symbol", symbol) - totalSupply, err := contract.TotalSupply(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("GovernanceToken", "totalSupply", totalSupply) - } else { - log.Info("No code at GovernanceToken") - } - return nil -} - -func checkWETH9(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewWETH9(addr, client) - if err != nil { - return err - } - name, err := contract.Name(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("WETH9", "name", name) - if name != "Wrapped Ether" { - return fmt.Errorf("WETH9 name should be 'Wrapped Ether', got %s", name) - } - - symbol, err := contract.Symbol(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("WETH9", "symbol", symbol) - if symbol != "WETH" { - return fmt.Errorf("WETH9 symbol should be 'WETH', got %s", symbol) - } - - decimals, err := contract.Decimals(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("WETH9", "decimals", decimals) - if decimals != 18 { - return fmt.Errorf("WETH9 decimals should be 18, got %d", decimals) - } - return nil -} - -func checkL1Block(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewL1Block(addr, client) - if err != nil { - return err - } - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L1Block version", "version", version) - return nil -} - -func checkL1BlockNumber(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewL1BlockNumber(addr, client) - if err != nil { - return err - } - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L1BlockNumber version", "version", version) - return nil -} - -func checkOptimismMintableERC20Factory(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewOptimismMintableERC20Factory(addr, client) - if err != nil { - return err - } - - bridgeLegacy, err := contract.BRIDGE(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("OptimismMintableERC20Factory", "BRIDGE", bridgeLegacy.Hex()) - if bridgeLegacy == (common.Address{}) { - return errors.New("OptimismMintableERC20Factory.BRIDGE is zero address") - } - - bridge, err := contract.Bridge(&bind.CallOpts{}) - if err != nil { - return err - } - if bridge == (common.Address{}) { - return errors.New("OptimismMintableERC20Factory.bridge is zero address") - } - log.Info("OptimismMintableERC20Factory", "bridge", bridge.Hex()) - - initialized, err := getInitialized("OptimismMintableERC20Factory", addr, client) - if err != nil { - return err - } - log.Info("OptimismMintableERC20Factory", "_initialized", initialized) - - initializing, err := getInitializing("OptimismMintableERC20Factory", addr, client) - if err != nil { - return err - } - log.Info("OptimismMintableERC20Factory", "_initializing", initializing) - - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("OptimismMintableERC20Factory version", "version", version) - return nil -} - -func checkSequencerFeeVault(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewSequencerFeeVault(addr, client) - if err != nil { - return err - } - recipient, err := contract.RECIPIENT(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("SequencerFeeVault", "RECIPIENT", recipient.Hex()) - if recipient == (common.Address{}) { - return errors.New("RECIPIENT should not be address(0)") - } - - l1FeeWallet, err := contract.L1FeeWallet(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("SequencerFeeVault", "l1FeeWallet", l1FeeWallet.Hex()) - - minWithdrawalAmount, err := contract.MINWITHDRAWALAMOUNT(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("SequencerFeeVault", "MIN_WITHDRAWAL_AMOUNT", minWithdrawalAmount) - - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("SequencerFeeVault version", "version", version) - return nil -} - -func checkL2StandardBridge(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewL2StandardBridge(addr, client) - if err != nil { - return err - } - otherBridge, err := contract.OTHERBRIDGE(&bind.CallOpts{}) - if err != nil { - return err - } - if otherBridge == (common.Address{}) { - return errors.New("OTHERBRIDGE should not be address(0)") - } - log.Info("L2StandardBridge", "OTHERBRIDGE", otherBridge.Hex()) - - messenger, err := contract.MESSENGER(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2StandardBridge", "MESSENGER", messenger.Hex()) - if messenger != predeploys.L2CrossDomainMessengerAddr { - return fmt.Errorf("L2StandardBridge MESSENGER should be %s, got %s", predeploys.L2CrossDomainMessengerAddr, messenger) - } - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - - initialized, err := getInitialized("L2StandardBridge", addr, client) - if err != nil { - return err - } - log.Info("L2StandardBridge", "_initialized", initialized) - - initializing, err := getInitializing("L2StandardBridge", addr, client) - if err != nil { - return err - } - log.Info("L2StandardBridge", "_initializing", initializing) - - log.Info("L2StandardBridge version", "version", version) - return nil -} - -func checkGasPriceOracle(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewGasPriceOracle(addr, client) - if err != nil { - return err - } - decimals, err := contract.DECIMALS(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("GasPriceOracle", "DECIMALS", decimals) - if decimals.Cmp(big.NewInt(6)) != 0 { - return fmt.Errorf("GasPriceOracle decimals should be 6, got %v", decimals) - } - - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("GasPriceOracle version", "version", version) - return nil -} - -func checkL2CrossDomainMessenger(addr common.Address, client *ethclient.Client) error { - slot, err := client.StorageAt(context.Background(), addr, common.Hash{31: 0xcc}, nil) - if err != nil { - return err - } - if common.BytesToAddress(slot) != defaultCrossDomainMessageSender { - return fmt.Errorf("Expected xDomainMsgSender to be %s, got %s", defaultCrossDomainMessageSender, addr) - } - - contract, err := bindings.NewL2CrossDomainMessenger(addr, client) - if err != nil { - return err - } - - otherMessenger, err := contract.OTHERMESSENGER(&bind.CallOpts{}) - if err != nil { - return err - } - if otherMessenger == (common.Address{}) { - return errors.New("OTHERMESSENGER should not be address(0)") - } - log.Info("L2CrossDomainMessenger", "OTHERMESSENGER", otherMessenger.Hex()) - - l1CrossDomainMessenger, err := contract.L1CrossDomainMessenger(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "l1CrossDomainMessenger", l1CrossDomainMessenger.Hex()) - - messageVersion, err := contract.MESSAGEVERSION(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "MESSAGE_VERSION", messageVersion) - minGasCallDataOverhead, err := contract.MINGASCALLDATAOVERHEAD(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "MIN_GAS_CALLDATA_OVERHEAD", minGasCallDataOverhead) - - relayConstantOverhead, err := contract.RELAYCONSTANTOVERHEAD(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "RELAY_CONSTANT_OVERHEAD", relayConstantOverhead) - - minGasDynamicsOverheadDenominator, err := contract.MINGASDYNAMICOVERHEADDENOMINATOR(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR", minGasDynamicsOverheadDenominator) - - minGasDynamicsOverheadNumerator, err := contract.MINGASDYNAMICOVERHEADNUMERATOR(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR", minGasDynamicsOverheadNumerator) - - relayCallOverhead, err := contract.RELAYCALLOVERHEAD(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "RELAY_CALL_OVERHEAD", relayCallOverhead) - - relayReservedGas, err := contract.RELAYRESERVEDGAS(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "RELAY_RESERVED_GAS", relayReservedGas) - - relayGasCheckBuffer, err := contract.RELAYGASCHECKBUFFER(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "RELAY_GAS_CHECK_BUFFER", relayGasCheckBuffer) - - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - - initialized, err := getInitialized("L2CrossDomainMessenger", addr, client) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "_initialized", initialized) - - initializing, err := getInitializing("L2CrossDomainMessenger", addr, client) - if err != nil { - return err - } - log.Info("L2CrossDomainMessenger", "_initializing", initializing) - - log.Info("L2CrossDomainMessenger version", "version", version) - return nil -} - -func checkLegacyMessagePasser(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewLegacyMessagePasser(addr, client) - if err != nil { - return err - } - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("LegacyMessagePasser version", "version", version) - return nil -} - -func checkDeployerWhitelist(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewDeployerWhitelist(addr, client) - if err != nil { - return err - } - owner, err := contract.Owner(&bind.CallOpts{}) - if err != nil { - return err - } - if owner != (common.Address{}) { - return fmt.Errorf("DeployerWhitelist owner should be set to address(0)") - } - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("DeployerWhitelist version", "version", version) - return nil -} - -func checkSchemaRegistry(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewSchemaRegistry(addr, client) - if err != nil { - return err - } - - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("SchemaRegistry version", "version", version) - return nil -} - -func checkEAS(addr common.Address, client *ethclient.Client) error { - contract, err := bindings.NewEAS(addr, client) - if err != nil { - return err - } - - registry, err := contract.GetSchemaRegistry(&bind.CallOpts{}) - if err != nil { - return err - } - if registry != predeploys.SchemaRegistryAddr { - return fmt.Errorf("Incorrect registry address %s", registry) - } - log.Info("EAS", "registry", registry) - - version, err := contract.Version(&bind.CallOpts{}) - if err != nil { - return err - } - log.Info("EAS version", "version", version) - return nil -} - -func getEIP1967AdminAddress(client *ethclient.Client, addr common.Address) (common.Address, error) { - slot, err := client.StorageAt(context.Background(), addr, genesis.AdminSlot, nil) - if err != nil { - return common.Address{}, err - } - admin := common.BytesToAddress(slot) - return admin, nil -} - -func getEIP1967ImplementationAddress(client *ethclient.Client, addr common.Address) (common.Address, error) { - slot, err := client.StorageAt(context.Background(), addr, genesis.ImplementationSlot, nil) - if err != nil { - return common.Address{}, err - } - impl := common.BytesToAddress(slot) - return impl, nil -} - -// getInitialized will get the initialized value in storage of a contract. -// This is an incrementing number that starts at 1 and increments each time that -// the contract is upgraded. -func getInitialized(name string, addr common.Address, client *ethclient.Client) (*big.Int, error) { - value, err := getStorageValue(name, "_initialized", addr, client) - if err != nil { - return nil, err - } - return new(big.Int).SetBytes(value), nil -} - -// getInitializing will get the _initializing value in storage of a contract. -func getInitializing(name string, addr common.Address, client *ethclient.Client) (bool, error) { - value, err := getStorageValue(name, "_initializing", addr, client) - if err != nil { - return false, err - } - if len(value) != 1 { - return false, fmt.Errorf("Unexpected length for _initializing: %d", len(value)) - } - return value[0] == 1, nil -} - -// getStorageValue will get the value of a named storage slot in a contract. It isn't smart about -// automatically converting from a byte slice to a type, it is the caller's responsibility to do that. -func getStorageValue(name, entryName string, addr common.Address, client *ethclient.Client) ([]byte, error) { - layout, err := bindings.GetStorageLayout(name) - if err != nil { - return nil, err - } - entry, err := layout.GetStorageLayoutEntry(entryName) - if err != nil { - return nil, err - } - typ, err := layout.GetStorageLayoutType(entry.Type) - if err != nil { - return nil, err - } - slot := common.BigToHash(big.NewInt(int64(entry.Slot))) - value, err := client.StorageAt(context.Background(), addr, slot, nil) - if err != nil { - return nil, err - } - if entry.Offset+typ.NumberOfBytes > uint(len(value)) { - return nil, fmt.Errorf("value length is too short") - } - // Swap the endianness - slice := common.CopyBytes(value) - for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 { - slice[i], slice[j] = slice[j], slice[i] - } - return slice[entry.Offset : entry.Offset+typ.NumberOfBytes], nil -} diff --git a/op-chain-ops/cmd/ecotone-scalar/README.md b/op-chain-ops/cmd/ecotone-scalar/README.md new file mode 100644 index 000000000000..2f533eea7b7f --- /dev/null +++ b/op-chain-ops/cmd/ecotone-scalar/README.md @@ -0,0 +1,20 @@ +# ecotone-scalar + +A CLI tool for computing the value of `scalar` to use after the Ecotone upgrade in a call to +`setGasConfig(scalar, overhead)` of the L1 `SystemConfigProxy` contract. After the Ecotone upgrade, the +overhead parameter is ignored, and the scalar parameter encodes a versioned `bytes32` that allows +configuring the base fee scalar and blob base fee scalars separately. + +#### Usage + +Build and run using the [Makefile](../../Makefile) `ecotone-scalar` target. Inside of `/op-chain-ops`, run: +```sh +make ecotone-scalar +``` +to create a binary in [../../bin/ecotone-scalar](../../bin/ecotone-scalar) that can +be executed, providing the `--scalar` and `--blob-scalar` flags to specify the base bee scalar and +blob base fee parameters respectively, for example: + +```sh +./bin/ecotone-scalar --scalar=7600 --blob-scalar=862000 +``` diff --git a/op-chain-ops/cmd/ecotone-scalar/main.go b/op-chain-ops/cmd/ecotone-scalar/main.go new file mode 100644 index 000000000000..53ee823fc0bc --- /dev/null +++ b/op-chain-ops/cmd/ecotone-scalar/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "encoding/binary" + "flag" + "fmt" + "math" + "math/big" + "os" +) + +func main() { + var scalar, blobScalar uint + flag.UintVar(&scalar, "scalar", 0, "base fee scalar value for the gas config (uint32)") + flag.UintVar(&blobScalar, "blob-scalar", 0, "blob base fee scalar value for the gas config (uint32)") + flag.Parse() + + if scalar > math.MaxUint32 { + fmt.Fprintln(flag.CommandLine.Output(), "scalar out of uint32 range") + flag.Usage() + os.Exit(2) + } + if blobScalar > math.MaxUint32 { + fmt.Fprintln(flag.CommandLine.Output(), "blob-scalar out of uint32 range") + flag.Usage() + os.Exit(2) + } + + var n [32]byte + n[0] = 1 // version + binary.BigEndian.PutUint32(n[32-4:], uint32(scalar)) + binary.BigEndian.PutUint32(n[32-8:], uint32(blobScalar)) + i := new(big.Int).SetBytes(n[:]) + + fmt.Println("# base fee scalar :", scalar) + fmt.Println("# blob base fee scalar:", blobScalar) + fmt.Printf("# v1 hex encoding : 0x%x\n", n[:]) + fmt.Println("# uint value for the 'scalar' parameter in SystemConfigProxy.setGasConfig():") + fmt.Println(i) +} diff --git a/op-chain-ops/cmd/op-simulate/main.go b/op-chain-ops/cmd/op-simulate/main.go new file mode 100644 index 000000000000..04d9e5fe94f0 --- /dev/null +++ b/op-chain-ops/cmd/op-simulate/main.go @@ -0,0 +1,304 @@ +package main + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io/fs" + "math/big" + "os" + "path" + "time" + + "github.com/pkg/profile" + "github.com/urfave/cli/v2" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/beacon" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + gstate "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + tracelogger "github.com/ethereum/go-ethereum/eth/tracers/logger" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" + + op_service "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/cliapp" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/opio" +) + +var EnvPrefix = "OP_SIMULATE" + +var ( + RPCFlag = &cli.StringFlag{ + Name: "rpc", + Usage: "RPC endpoint to fetch prestate from", + EnvVars: op_service.PrefixEnvVar(EnvPrefix, "RPC"), + Required: true, + } + TxFlag = &cli.StringFlag{ + Name: "tx", + Usage: "Transaction hash to trace and simulate", + EnvVars: op_service.PrefixEnvVar(EnvPrefix, "TX"), + Required: true, + } + ProfFlag = &cli.BoolFlag{ + Name: "profile", + Usage: "profile the tx processing", + EnvVars: op_service.PrefixEnvVar(EnvPrefix, "PROFILE"), + Required: false, + } +) + +func main() { + flags := []cli.Flag{ + RPCFlag, TxFlag, ProfFlag, + } + flags = append(flags, oplog.CLIFlags(EnvPrefix)...) + + app := cli.NewApp() + app.Name = "op-simulate" + app.Usage = "Simulate a tx locally." + app.Description = "Fetch a tx from an RPC and simulate it locally." + app.Flags = cliapp.ProtectFlags(flags) + app.Action = mainAction + app.Writer = os.Stdout + app.ErrWriter = os.Stderr + err := app.Run(os.Args) + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Application failed: %v", err) + os.Exit(1) + } +} + +func mainAction(c *cli.Context) error { + ctx := opio.CancelOnInterrupt(c.Context) + logCfg := oplog.ReadCLIConfig(c) + logger := oplog.NewLogger(c.App.Writer, logCfg) + + endpoint := c.String(RPCFlag.Name) + cl, err := rpc.DialContext(ctx, endpoint) + if err != nil { + return fmt.Errorf("failed to dial RPC %q: %w", endpoint, err) + } + txHashStr := c.String(TxFlag.Name) + var txHash common.Hash + if err := txHash.UnmarshalText([]byte(txHashStr)); err != nil { + return fmt.Errorf("invalid tx hash: %q", txHashStr) + } + prestatesDir := "." + if err := fetchPrestate(ctx, cl, prestatesDir, txHash); err != nil { + return fmt.Errorf("failed to prepare prestate: %w", err) + } + chainConfig, err := fetchChainConfig(ctx, cl) + if err != nil { + return fmt.Errorf("failed to get chain config: %w", err) + } + tx, err := fetchTx(ctx, cl, txHash) + if err != nil { + return fmt.Errorf("failed to get TX: %w", err) + } + rec, err := fetchReceipt(ctx, cl, txHash) + if err != nil { + return fmt.Errorf("failed to get receipt: %w", err) + } + header, err := fetchHeader(ctx, cl, rec.BlockHash) + if err != nil { + return fmt.Errorf("failed to get block header: %w", err) + } + doProfile := c.Bool(ProfFlag.Name) + if err := simulate(ctx, logger, chainConfig, prestateTraceFile(prestatesDir, txHash), tx, header, doProfile); err != nil { + return fmt.Errorf("failed to simulate tx: %w", err) + } + return nil +} + +// TraceConfig is different than Geth TraceConfig, quicknode sin't flexible +type TraceConfig struct { + *tracelogger.Config + Tracer string `json:"tracer"` + Timeout *string `json:"timeout"` + // Config specific to given tracer. Note struct logger + // config are historically embedded in main object. + TracerConfig json.RawMessage +} + +func prestateTraceFile(dir string, txHash common.Hash) string { + return path.Join(dir, "prestate_"+txHash.String()+".json") +} + +func fetchPrestate(ctx context.Context, cl *rpc.Client, dir string, txHash common.Hash) error { + dest := prestateTraceFile(dir, txHash) + // check cache + _, err := os.Stat(dest) + if err == nil { + // already known file + return nil + } + if !errors.Is(err, fs.ErrNotExist) { + return fmt.Errorf("failed to check prestate file %q: %w", dest, err) + } + var result json.RawMessage + if err := cl.CallContext(ctx, &result, "debug_traceTransaction", txHash, TraceConfig{ + Config: &tracelogger.Config{ + EnableMemory: false, + DisableStack: true, + DisableStorage: true, + EnableReturnData: false, + Debug: false, + Limit: 0, + Overrides: nil, + }, + Tracer: "prestateTracer", + Timeout: nil, + TracerConfig: nil, + }); err != nil { + return fmt.Errorf("failed to retrieve prestate trace: %w", err) + } + if err := os.WriteFile(dest, result, 0644); err != nil { + return fmt.Errorf("failed to write prestate trace: %w", err) + } + return nil +} + +func fetchChainConfig(ctx context.Context, cl *rpc.Client) (*params.ChainConfig, error) { + // first try the chain-ID RPC, this is widely available on any RPC provider. + var idResult hexutil.Big + if err := cl.CallContext(ctx, &idResult, "eth_chainId"); err != nil { + return nil, fmt.Errorf("failed to retrieve chain ID: %w", err) + } + // if we recognize the chain ID, we can get the chain config + id := (*big.Int)(&idResult) + if id.IsUint64() { + cfg, err := params.LoadOPStackChainConfig(id.Uint64()) + if err == nil { + return cfg, nil + } + // ignore error, try to fetch chain config in full + } + // if not already recognized, then fetch the chain config manually + var config params.ChainConfig + if err := cl.CallContext(ctx, &config, "eth_chainConfig"); err != nil { + return nil, fmt.Errorf("failed to retrieve chain config: %w", err) + } + return &config, nil +} + +func fetchTx(ctx context.Context, cl *rpc.Client, txHash common.Hash) (*types.Transaction, error) { + tx, pending, err := ethclient.NewClient(cl).TransactionByHash(ctx, txHash) + if pending { + return nil, fmt.Errorf("tx %s is still pending", txHash) + } + return tx, err +} + +func fetchReceipt(ctx context.Context, cl *rpc.Client, txHash common.Hash) (*types.Receipt, error) { + return ethclient.NewClient(cl).TransactionReceipt(ctx, txHash) +} + +func fetchHeader(ctx context.Context, cl *rpc.Client, blockHash common.Hash) (*types.Header, error) { + return ethclient.NewClient(cl).HeaderByHash(ctx, blockHash) +} + +type DumpAccount struct { + Balance hexutil.Big `json:"balance"` + Nonce uint64 `json:"nonce"` + Code hexutil.Bytes `json:"code,omitempty"` + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` +} + +func readDump(prestatePath string) (map[common.Address]DumpAccount, error) { + f, err := os.Open(prestatePath) + if err != nil { + return nil, fmt.Errorf("failed to load state data: %w", err) + } + var out map[common.Address]DumpAccount + if err := json.NewDecoder(f).Decode(&out); err != nil { + return nil, fmt.Errorf("failed to decode state data: %w", err) + } + return out, nil +} + +type simChainContext struct { + eng consensus.Engine + head *types.Header +} + +func (d *simChainContext) Engine() consensus.Engine { + return d.eng +} + +func (d *simChainContext) GetHeader(h common.Hash, n uint64) *types.Header { + if n == d.head.Number.Uint64() { + return d.head + } + panic(fmt.Errorf("header retrieval not supported, cannot fetch %s %d", h, n)) +} + +func simulate(ctx context.Context, logger log.Logger, conf *params.ChainConfig, + prestatePath string, tx *types.Transaction, header *types.Header, doProfile bool) error { + memDB := rawdb.NewMemoryDatabase() + stateDB := gstate.NewDatabase(memDB) + state, err := gstate.New(types.EmptyRootHash, stateDB, nil) + if err != nil { + return fmt.Errorf("failed to create in-memory state: %w", err) + } + dump, err := readDump(prestatePath) + if err != nil { + return fmt.Errorf("failed to read prestate: %w", err) + } + for addr, acc := range dump { + state.CreateAccount(addr) + state.SetBalance(addr, new(big.Int).Set((*big.Int)(&acc.Balance))) + state.SetNonce(addr, acc.Nonce) + state.SetCode(addr, acc.Code) + state.SetStorage(addr, acc.Storage) + } + + // load prestate data into memory db state + _, err = state.Commit(header.Number.Uint64()-1, true) + if err != nil { + return fmt.Errorf("failed to write state data to underlying DB: %w", err) + } + + rules := conf.Rules(header.Number, true, header.Time) + signer := types.MakeSigner(conf, header.Number, header.Time) + sender, err := signer.Sender(tx) + if err != nil { + return fmt.Errorf("failed to get tx sender: %w", err) + } + // prepare the state + precompiles := vm.ActivePrecompiles(rules) + state.Prepare(rules, sender, header.Coinbase, tx.To(), precompiles, tx.AccessList()) + state.SetTxContext(tx.Hash(), 0) + + cCtx := &simChainContext{eng: beacon.NewFaker(), head: header} + gp := core.GasPool(tx.Gas()) + usedGas := uint64(0) + vmConfig := vm.Config{} + + if doProfile { + prof := profile.Start(profile.NoShutdownHook, profile.ProfilePath("."), profile.CPUProfile) + defer prof.Stop() + } + + // run the transaction + start := time.Now() + receipt, err := core.ApplyTransaction(conf, cCtx, &sender, &gp, state, header, tx, &usedGas, vmConfig) + if err != nil { + return fmt.Errorf("failed to apply tx: %w", err) + } + end := time.Since(start) + logger.Info("processed tx", "elapsed", end, + "ok", receipt.Status == types.ReceiptStatusSuccessful, "logs", len(receipt.Logs)) + + return nil +} diff --git a/op-chain-ops/cmd/op-upgrade-mcp/README.md b/op-chain-ops/cmd/op-upgrade-mcp/README.md new file mode 100644 index 000000000000..4d95f1e93d4a --- /dev/null +++ b/op-chain-ops/cmd/op-upgrade-mcp/README.md @@ -0,0 +1,3 @@ +# op-upgrade-mcp + +One off CLI tooling for the mcp upgrade diff --git a/op-chain-ops/cmd/op-upgrade-mcp/main.go b/op-chain-ops/cmd/op-upgrade-mcp/main.go new file mode 100644 index 000000000000..2dd2dc8ca90d --- /dev/null +++ b/op-chain-ops/cmd/op-upgrade-mcp/main.go @@ -0,0 +1,225 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "os" + + "github.com/ethereum/go-ethereum/log" + "github.com/mattn/go-isatty" + "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/op-chain-ops/clients" + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" + "github.com/ethereum-optimism/optimism/op-chain-ops/safe" + "github.com/ethereum-optimism/optimism/op-chain-ops/upgrades" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + + "github.com/ethereum-optimism/superchain-registry/superchain" +) + +// deployments contains the L1 addresses of the contracts that are being upgraded to. +// Note that the key is the L2 chain id. This is because the L1 contracts must be specific +// for a particular OP Stack chain and cannot currently be used by multiple chains. +var deployments = map[uint64]superchain.ImplementationList{ + // OP Mainnet + 10: { + L1CrossDomainMessenger: superchain.VersionedContract{ + Version: "2.3.0", + Address: superchain.HexToAddress("0xD3494713A5cfaD3F5359379DfA074E2Ac8C6Fd65"), + }, + L1ERC721Bridge: superchain.VersionedContract{ + Version: "2.1.0", + Address: superchain.HexToAddress("0xAE2AF01232a6c4a4d3012C5eC5b1b35059caF10d"), + }, + L1StandardBridge: superchain.VersionedContract{ + Version: "2.1.0", + Address: superchain.HexToAddress("0x64B5a5Ed26DCb17370Ff4d33a8D503f0fbD06CfF"), + }, + OptimismPortal: superchain.VersionedContract{ + Version: "2.5.0", + Address: superchain.HexToAddress("0x2D778797049FE9259d947D1ED8e5442226dFB589"), + }, + SystemConfig: superchain.VersionedContract{ + Version: "1.12.0", + Address: superchain.HexToAddress("0xba2492e52F45651B60B8B38d4Ea5E2390C64Ffb1"), + }, + L2OutputOracle: superchain.VersionedContract{ + Version: "1.8.0", + Address: superchain.HexToAddress("0xF243BEd163251380e78068d317ae10f26042B292"), + }, + OptimismMintableERC20Factory: superchain.VersionedContract{ + Version: "1.9.0", + Address: superchain.HexToAddress("0xE01efbeb1089D1d1dB9c6c8b135C934C0734c846"), + }, + }, + // OP Sepolia + 11155420: { + L1CrossDomainMessenger: superchain.VersionedContract{ + Version: "2.3.0", + Address: superchain.HexToAddress("0xD3494713A5cfaD3F5359379DfA074E2Ac8C6Fd65"), + }, + L1ERC721Bridge: superchain.VersionedContract{ + Version: "2.1.0", + Address: superchain.HexToAddress("0xAE2AF01232a6c4a4d3012C5eC5b1b35059caF10d"), + }, + L1StandardBridge: superchain.VersionedContract{ + Version: "2.1.0", + Address: superchain.HexToAddress("0x64B5a5Ed26DCb17370Ff4d33a8D503f0fbD06CfF"), + }, + OptimismPortal: superchain.VersionedContract{ + Version: "2.5.0", + Address: superchain.HexToAddress("0x2D778797049FE9259d947D1ED8e5442226dFB589"), + }, + SystemConfig: superchain.VersionedContract{ + Version: "1.12.0", + Address: superchain.HexToAddress("0xba2492e52F45651B60B8B38d4Ea5E2390C64Ffb1"), + }, + L2OutputOracle: superchain.VersionedContract{ + Version: "1.8.0", + Address: superchain.HexToAddress("0xF243BEd163251380e78068d317ae10f26042B292"), + }, + OptimismMintableERC20Factory: superchain.VersionedContract{ + Version: "1.9.0", + Address: superchain.HexToAddress("0xE01efbeb1089D1d1dB9c6c8b135C934C0734c846"), + }, + }, +} + +func main() { + color := isatty.IsTerminal(os.Stderr.Fd()) + oplog.SetGlobalLogHandler(log.NewTerminalHandler(os.Stderr, color)) + + app := &cli.App{ + Name: "op-upgrade", + Usage: "Build transactions useful for upgrading the Superchain", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "l1-rpc-url", + Value: "http://127.0.0.1:8545", + Usage: "L1 RPC URL, the chain ID will be used to determine the superchain", + Required: true, + EnvVars: []string{"L1_RPC_URL"}, + }, + &cli.StringFlag{ + Name: "l2-rpc-url", + Value: "http://127.0.0.1:9545", + Usage: "L2 RPC URL", + Required: true, + EnvVars: []string{"L2_RPC_URL"}, + }, + &cli.PathFlag{ + Name: "deploy-config", + Usage: "The path to the deploy config file", + Required: true, + EnvVars: []string{"DEPLOY_CONFIG"}, + }, + &cli.PathFlag{ + Name: "outfile", + Usage: "The file to write the output to. If not specified, output is written to stdout", + EnvVars: []string{"OUTFILE"}, + }, + }, + Action: entrypoint, + } + + if err := app.Run(os.Args); err != nil { + log.Crit("error op-upgrade", "err", err) + } +} + +// entrypoint contains the main logic of the script +func entrypoint(ctx *cli.Context) error { + config, err := genesis.NewDeployConfig(ctx.Path("deploy-config")) + if err != nil { + return err + } + if err := config.Check(); err != nil { + return fmt.Errorf("error checking deploy config: %w", err) + } + + clients, err := clients.NewClients(ctx.String("l1-rpc-url"), ctx.String("l2-rpc-url")) + if err != nil { + return fmt.Errorf("cannot create RPC clients: %w", err) + } + if clients.L1Client == nil { + return errors.New("Cannot create L1 client") + } + if clients.L2Client == nil { + return errors.New("Cannot create L2 client") + } + + l1ChainID, err := clients.L1Client.ChainID(ctx.Context) + if err != nil { + return fmt.Errorf("cannot fetch L1 chain ID: %w", err) + } + l2ChainID, err := clients.L2Client.ChainID(ctx.Context) + if err != nil { + return fmt.Errorf("cannot fetch L2 chain ID: %w", err) + } + + log.Info("connected to chains", "l1-chain-id", l1ChainID, "l2-chain-id", l2ChainID) + + // Create a batch of transactions + batch := safe.Batch{} + + list, ok := deployments[l2ChainID.Uint64()] + if !ok { + return fmt.Errorf("no implementations for chain ID %d", l2ChainID) + } + + proxyAddresses, ok := superchain.Addresses[l2ChainID.Uint64()] + if !ok { + return fmt.Errorf("no proxy addresses for chain ID %d", l2ChainID) + } + + chainConfig, ok := superchain.OPChains[l2ChainID.Uint64()] + if !ok { + return fmt.Errorf("no chain config for chain ID %d", l2ChainID) + } + + log.Info("Upgrading to the following versions") + log.Info("L1CrossDomainMessenger", "version", list.L1CrossDomainMessenger.Version, "address", list.L1CrossDomainMessenger.Address) + log.Info("L1ERC721Bridge", "version", list.L1ERC721Bridge.Version, "address", list.L1ERC721Bridge.Address) + log.Info("L1StandardBridge", "version", list.L1StandardBridge.Version, "address", list.L1StandardBridge.Address) + log.Info("L2OutputOracle", "version", list.L2OutputOracle.Version, "address", list.L2OutputOracle.Address) + log.Info("OptimismMintableERC20Factory", "version", list.OptimismMintableERC20Factory.Version, "address", list.OptimismMintableERC20Factory.Address) + log.Info("OptimismPortal", "version", list.OptimismPortal.Version, "address", list.OptimismPortal.Address) + log.Info("SystemConfig", "version", list.SystemConfig.Version, "address", list.SystemConfig.Address) + + if err := upgrades.CheckL1(ctx.Context, &list, clients.L1Client); err != nil { + return fmt.Errorf("error checking L1 contracts: %w", err) + } + + // Build the batch + if err := upgrades.L1(&batch, list, *proxyAddresses, config, chainConfig, clients.L1Client); err != nil { + return fmt.Errorf("cannot build L1 upgrade batch: %w", err) + } + + // Write the batch to disk or stdout + if outfile := ctx.Path("outfile"); outfile != "" { + if err := writeJSON(outfile, batch); err != nil { + return err + } + } else { + data, err := json.MarshalIndent(batch, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + } + return nil +} + +func writeJSON(outfile string, input interface{}) error { + f, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o666) + if err != nil { + return err + } + defer f.Close() + + enc := json.NewEncoder(f) + enc.SetIndent("", " ") + return enc.Encode(input) +} diff --git a/op-chain-ops/cmd/op-upgrade/main.go b/op-chain-ops/cmd/op-upgrade/main.go index aec5c07addfb..36e0d4111a01 100644 --- a/op-chain-ops/cmd/op-upgrade/main.go +++ b/op-chain-ops/cmd/op-upgrade/main.go @@ -18,12 +18,15 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-chain-ops/safe" "github.com/ethereum-optimism/optimism/op-chain-ops/upgrades" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" + oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/superchain-registry/superchain" ) func main() { - log.Root().SetHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(isatty.IsTerminal(os.Stderr.Fd())))) + color := isatty.IsTerminal(os.Stderr.Fd()) + oplog.SetGlobalLogHandler(log.NewTerminalHandler(os.Stderr, color)) app := &cli.App{ Name: "op-upgrade", @@ -78,11 +81,16 @@ func entrypoint(ctx *cli.Context) error { } superchainName := ctx.String("superchain-target") - if superchainName == "" { - superchainName, err = toSuperchainName(l1ChainID.Uint64()) - if err != nil { - return err - } + sc, ok := superchain.Superchains[superchainName] + if !ok { + return fmt.Errorf("superchain name %s not registered", superchainName) + } + + declaredChainID := sc.Config.L1.ChainID + + if declaredChainID != l1ChainID.Uint64() { + return fmt.Errorf("superchain %s has chainID %d, but the l1-rpc-url returned a chainId of %d", + superchainName, declaredChainID, l1ChainID.Uint64()) } chainIDs := ctx.Uint64Slice("chain-ids") @@ -112,7 +120,7 @@ func entrypoint(ctx *cli.Context) error { name, _ := toDeployConfigName(chainConfig) config, err := genesis.NewDeployConfigWithNetwork(name, deployConfig) if err != nil { - log.Warn("Cannot find deploy config for network", "name", chainConfig.Name, "deploy-config-name", name, "path", deployConfig) + log.Warn("Cannot find deploy config for network", "name", chainConfig.Name, "deploy-config-name", name, "path", deployConfig, "err", err) } if config != nil { @@ -167,14 +175,14 @@ func entrypoint(ctx *cli.Context) error { log.Info("L2OutputOracle", "version", versions.L2OutputOracle, "address", addresses.L2OutputOracleProxy) log.Info("OptimismMintableERC20Factory", "version", versions.OptimismMintableERC20Factory, "address", addresses.OptimismMintableERC20FactoryProxy) log.Info("OptimismPortal", "version", versions.OptimismPortal, "address", addresses.OptimismPortalProxy) - log.Info("SystemConfig", "version", versions.SystemConfig, "address", chainConfig.SystemConfigAddr) + log.Info("SystemConfig", "version", versions.SystemConfig, "address", addresses.SystemConfigProxy) implementations, ok := superchain.Implementations[l1ChainID.Uint64()] if !ok { return fmt.Errorf("no implementations for chain ID %d", l1ChainID.Uint64()) } - list, err := implementations.Resolve(superchain.SuperchainSemver) + list, err := implementations.Resolve(superchain.SuperchainSemver[superchainName]) if err != nil { return err } @@ -202,7 +210,7 @@ func entrypoint(ctx *cli.Context) error { // Write the batch to disk or stdout if outfile := ctx.Path("outfile"); outfile != "" { - if err := writeJSON(outfile, batch); err != nil { + if err := jsonutil.WriteJSON(outfile, batch, 0o666); err != nil { return err } } else { @@ -240,30 +248,3 @@ func toDeployConfigName(cfg *superchain.ChainConfig) (string, error) { } return "", fmt.Errorf("unsupported chain name %s", cfg.Name) } - -// toSuperchainName turns a base layer chain id into a superchain -// network name. -func toSuperchainName(chainID uint64) (string, error) { - if chainID == 1 { - return "mainnet", nil - } - if chainID == 5 { - return "goerli", nil - } - if chainID == 11155111 { - return "sepolia", nil - } - return "", fmt.Errorf("unsupported chain ID %d", chainID) -} - -func writeJSON(outfile string, input interface{}) error { - f, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o666) - if err != nil { - return err - } - defer f.Close() - - enc := json.NewEncoder(f) - enc.SetIndent("", " ") - return enc.Encode(input) -} diff --git a/op-chain-ops/cmd/op-version-check/README.md b/op-chain-ops/cmd/op-version-check/README.md new file mode 100644 index 000000000000..29e5f08ab4de --- /dev/null +++ b/op-chain-ops/cmd/op-version-check/README.md @@ -0,0 +1,48 @@ +# op-version-check + +A CLI tool for determining which contract versions are deployed for +chains in a superchain. It will output a JSON file that contains a +list of each chain's versions. It is assumed that the implementations +that are being checked have already been deployed and their contract +addresses exist inside of the `superchain-registry` repository. It is +also assumed that the semantic version file in the `superchain-registry` +has been updated. The tool will output the semantic versioning to +determine which contract versions are deployed. + +### Configuration + +#### L1 RPC URL + +The L1 RPC URL is used to determine which superchain to target. All +L2s that are not based on top of the L1 chain that corresponds to the +L1 RPC URL are filtered out from being checked. It also is used to +double check that the data in the `superchain-registry` is correct. + +#### Chain IDs + +A list of L2 chain IDs can be passed that will be used to filter which +L2 chains will have their versions checked. Omitting this argument will +result in all chains in the superchain being considered. + +#### Deploy Config + +The path to the `deploy-config` directory in the contracts package. +Since multiple L2 networks may be considered in the check, the `deploy-config` +directory must be passed and then the particular deploy config files will +be read out of the directory as needed. + +#### Outfile + +The file that the versions should be written to. If omitted, the file +will be written to stdout + +#### Usage + +It can be built and run using the [Makefile](../../Makefile) `op-version-check` +target. Run `make op-version-check` to create a binary in [../../bin/op-version-check](../../bin/op-version-check) +that can be executed, optionally providing the `--l1-rpc-url`, `--chain-ids`, +`--superchain-target`, and `--outfile` flags. + +```sh +./bin/op-version-check +``` diff --git a/op-chain-ops/cmd/op-version-check/main.go b/op-chain-ops/cmd/op-version-check/main.go new file mode 100644 index 000000000000..163ff8599ef5 --- /dev/null +++ b/op-chain-ops/cmd/op-version-check/main.go @@ -0,0 +1,169 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "os" + + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/mattn/go-isatty" + "github.com/urfave/cli/v2" + "golang.org/x/exp/maps" + + "github.com/ethereum-optimism/optimism/op-chain-ops/upgrades" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + + "github.com/ethereum-optimism/superchain-registry/superchain" +) + +type Contract struct { + Version string `yaml:"version"` + Address superchain.Address `yaml:"address"` +} + +type ChainVersionCheck struct { + Name string `yaml:"name"` + ChainID uint64 `yaml:"chain_id"` + Contracts map[string]Contract `yaml:"contracts"` +} + +func main() { + color := isatty.IsTerminal(os.Stderr.Fd()) + oplog.SetGlobalLogHandler(log.NewTerminalHandler(os.Stderr, color)) + + app := &cli.App{ + Name: "op-version-check", + Usage: "Determine which contract versions are deployed for chains in a superchain", + Flags: []cli.Flag{ + &cli.StringSliceFlag{ + Name: "l1-rpc-urls", + Usage: "L1 RPC URLs, the chain ID will be used to determine the superchain", + EnvVars: []string{"L1_RPC_URLS"}, + }, + &cli.StringSliceFlag{ + Name: "l2-rpc-urls", + Usage: "L2 RPC URLs, corresponding to chains to check versions for. Corresponds to all chains if empty", + EnvVars: []string{"L2_RPC_URLS"}, + }, + &cli.PathFlag{ + Name: "outfile", + Usage: "The file to write the output to. If not specified, output is written to stdout", + EnvVars: []string{"OUTFILE"}, + }, + }, + Action: entrypoint, + } + + if err := app.Run(os.Args); err != nil { + log.Crit("error op-version-check", "err", err) + } +} + +// entrypoint contains the main logic of the script +func entrypoint(ctx *cli.Context) error { + l1RPCURLs := ctx.StringSlice("l1-rpc-urls") + l2RPCURLs := ctx.StringSlice("l2-rpc-urls") + + var l2ChainIDs []uint64 + + // If no L2 RPC URLs are specified, we check all chains for the L1 RPC URL + if len(l2RPCURLs) == 0 { + l2ChainIDs = maps.Keys(superchain.OPChains) + } else { + for _, l2RPCURL := range l2RPCURLs { + client, err := ethclient.Dial(l2RPCURL) + if err != nil { + return errors.New("cannot create L2 client") + } + + l2ChainID, err := client.ChainID(ctx.Context) + if err != nil { + return fmt.Errorf("cannot fetch L2 chain ID: %w", err) + } + + l2ChainIDs = append(l2ChainIDs, l2ChainID.Uint64()) + } + } + + output := []ChainVersionCheck{} + + for _, l2ChainID := range l2ChainIDs { + chainConfig := superchain.OPChains[l2ChainID] + + if chainConfig.ChainID != l2ChainID { + return fmt.Errorf("mismatched chain IDs: %d != %d", chainConfig.ChainID, l2ChainID) + } + + for _, l1RPCURL := range l1RPCURLs { + client, err := ethclient.Dial(l1RPCURL) + if err != nil { + return errors.New("cannot create L1 client") + } + + l1ChainID, err := client.ChainID(ctx.Context) + if err != nil { + return fmt.Errorf("cannot fetch L1 chain ID: %w", err) + } + + sc, ok := superchain.Superchains[chainConfig.Superchain] + if !ok { + return fmt.Errorf("superchain name %s not registered", chainConfig.Superchain) + } + + declaredL1ChainID := sc.Config.L1.ChainID + + if l1ChainID.Uint64() != declaredL1ChainID { + // L2 corresponds to a different superchain than L1, skip + log.Info("Ignoring L1/L2", "l1-chain-id", l1ChainID, "l2-chain-id", l2ChainID) + continue + } + + log.Info(chainConfig.Name, "l1-chain-id", l1ChainID, "l2-chain-id", l2ChainID) + + log.Info("Detecting on chain contracts") + // Tracking the individual addresses can be deprecated once the system is upgraded + // to the new contracts where the system config has a reference to each address. + addresses, ok := superchain.Addresses[l2ChainID] + if !ok { + return fmt.Errorf("no addresses for chain ID %d", l2ChainID) + } + versions, err := upgrades.GetContractVersions(ctx.Context, addresses, chainConfig, client) + if err != nil { + return fmt.Errorf("error getting contract versions: %w", err) + } + + contracts := make(map[string]Contract) + + contracts["AddressManager"] = Contract{Version: "null", Address: addresses.AddressManager} + contracts["L1CrossDomainMessenger"] = Contract{Version: versions.L1CrossDomainMessenger, Address: addresses.L1CrossDomainMessengerProxy} + contracts["L1ERC721Bridge"] = Contract{Version: versions.L1ERC721Bridge, Address: addresses.L1ERC721BridgeProxy} + contracts["L1StandardBridge"] = Contract{Version: versions.L1ERC721Bridge, Address: addresses.L1StandardBridgeProxy} + contracts["L2OutputOracle"] = Contract{Version: versions.L2OutputOracle, Address: addresses.L2OutputOracleProxy} + contracts["OptimismMintableERC20Factory"] = Contract{Version: versions.OptimismMintableERC20Factory, Address: addresses.OptimismMintableERC20FactoryProxy} + contracts["OptimismPortal"] = Contract{Version: versions.OptimismPortal, Address: addresses.OptimismPortalProxy} + contracts["SystemConfig"] = Contract{Version: versions.SystemConfig, Address: addresses.SystemConfigProxy} + contracts["ProxyAdmin"] = Contract{Version: "null", Address: addresses.ProxyAdmin} + + output = append(output, ChainVersionCheck{Name: chainConfig.Name, ChainID: l2ChainID, Contracts: contracts}) + + log.Info("Successfully processed contract versions", "chain", chainConfig.Name, "l1-chain-id", l1ChainID, "l2-chain-id", l2ChainID) + break + } + } + // Write contract versions to disk or stdout + if outfile := ctx.Path("outfile"); outfile != "" { + if err := jsonutil.WriteJSON(outfile, output, 0o666); err != nil { + return err + } + } else { + data, err := json.MarshalIndent(output, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + } + return nil +} diff --git a/op-chain-ops/cmd/protocol-version/main.go b/op-chain-ops/cmd/protocol-version/main.go index 7c4487437daa..a5bd6b434921 100644 --- a/op-chain-ops/cmd/protocol-version/main.go +++ b/op-chain-ops/cmd/protocol-version/main.go @@ -7,12 +7,14 @@ import ( "github.com/mattn/go-isatty" "github.com/urfave/cli/v2" + "golang.org/x/exp/slog" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" opservice "github.com/ethereum-optimism/optimism/op-service" + oplog "github.com/ethereum-optimism/optimism/op-service/log" ) const EnvPrefix = "OP_CHAIN_OPS_PROTOCOL_VERSION" @@ -51,7 +53,8 @@ var ( ) func main() { - log.Root().SetHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(isatty.IsTerminal(os.Stderr.Fd())))) + color := isatty.IsTerminal(os.Stderr.Fd()) + oplog.SetGlobalLogHandler(log.NewTerminalHandlerWithLevel(os.Stdout, slog.LevelDebug, color)) app := &cli.App{ Name: "protocol-version", diff --git a/op-chain-ops/cmd/receipt-reference-builder/README.md b/op-chain-ops/cmd/receipt-reference-builder/README.md new file mode 100644 index 000000000000..dea2aaa3a085 --- /dev/null +++ b/op-chain-ops/cmd/receipt-reference-builder/README.md @@ -0,0 +1,39 @@ +# Receipt Reference Tool + +Receipt Reference Tool is a data-pulling tool for operational use by Superchain operators of chains which have Post-Bedrock-Pre-Canyon activity. + +## Data Collection + +### Pull +The `pull` subcommand manages a collection of workers to request blocks from an RPC endpoint, and then checks each block for deposit transactions. Those transactions are built up into an aggregate data structure and written. + +### Merge +The `merge` subcommand targets an array of files, confirms that there is no gap in the processed block ranges, and then merges the aggregates into a single file. + +### Convert +The `convert` subcommand targets a single file and writes it as a new file in the requested format. + +### Print +`print` is a debug subcommand to read in a file and print it to screen. + +## Data Spec +The output data of this tool is an "aggregate". Each aggregate contains the following attributes +- Start Block, End Block +- Chain ID +- Results Map: + - Key of BlockNumber + - Value of Nonces as a slice + +Transaction Nonces are inserted to the value slice in the order they appear in the block. Transaction Nonces are only included if they are related to a user deposit. +Blocks which contain no deposit transactions have no key in the data. + +Users of this data can easily find if the data is appropriate for their network (using ChainID), covers a given block (using Start and End), and provides the nonces for user deposits. + +## Best Practices +This tool is designed with a static range of blocks in mind, the size of which is about 10 Million blocks. In order to get such a large body of data in one place, this tool is built for parallel execution and retries. + +To maximize parallel efficiency, a higher number of `-workers` can utilize more RPC requests per second. Additionally `-batch-size` can be increased to group more RPC requests together per network exchange. I am using 5 workers with 100 requests per batch. + +To avoid wasteful abandon of work already done, errors which are encountered by workers are noted, but do not stop the aggregation process. Jobs which fail are reinserted into the work queue with no maximum retry, and workers back off when encountering failures. This is all to allow an RPC endpoint to become temporarily unavailalbe while letting aggregation stay persistent. + +Even at high speed, collecting this much data can take several hours. You may benefit from planning a collection of smaller-sized runs, merging them with the `merge` subcommand as they become available. diff --git a/op-chain-ops/cmd/receipt-reference-builder/convert.go b/op-chain-ops/cmd/receipt-reference-builder/convert.go new file mode 100644 index 000000000000..79bf51d1b81b --- /dev/null +++ b/op-chain-ops/cmd/receipt-reference-builder/convert.go @@ -0,0 +1,46 @@ +package main + +import ( + "errors" + + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" +) + +var convertCommand = &cli.Command{ + Name: "convert", + Usage: "convert an aggregate from one format to another", + Flags: []cli.Flag{FilesFlag, OutputFlag, InputFormatFlag, OutputFormatFlag}, + Action: convert, +} + +func convert(ctx *cli.Context) error { + log := log.New() + files := ctx.StringSlice("files") + if len(files) != 1 { + return errors.New("only one file is supported") + } + + if ctx.String("input-format") == ctx.String("output-format") { + log.Info("no conversion needed. specify different input and output formats") + return nil + } + + r := formats[ctx.String("input-format")] + w := formats[ctx.String("output-format")] + + for _, f := range files { + a, err := r.readAggregate(f) + if err != nil { + log.Error("failed to read aggregate", "file", f, "err", err) + return err + } + err = w.writeAggregate(a, ctx.String("output")) + if err != nil { + log.Error("failed to write aggregate", "file", f, "err", err) + return err + } + + } + return nil +} diff --git a/op-chain-ops/cmd/receipt-reference-builder/main.go b/op-chain-ops/cmd/receipt-reference-builder/main.go new file mode 100644 index 000000000000..0418e92193e7 --- /dev/null +++ b/op-chain-ops/cmd/receipt-reference-builder/main.go @@ -0,0 +1,112 @@ +package main + +import ( + "os" + "time" + + "github.com/mattn/go-isatty" + "github.com/urfave/cli/v2" + "golang.org/x/exp/slog" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + opservice "github.com/ethereum-optimism/optimism/op-service" + oplog "github.com/ethereum-optimism/optimism/op-service/log" +) + +const EnvPrefix = "OP_CHAIN_OPS_RECEIPT_REFERENCE_BUILDER" + +var ( + StartFlag = &cli.Uint64Flag{ + Name: "start", + Usage: "the first block to include in data collection. INCLUSIVE", + } + EndFlag = &cli.Uint64Flag{ + Name: "end", + Usage: "the last block of the collection range. EXCLUSIVE", + } + RPCURLFlag = &cli.StringFlag{ + Name: "rpc-url", + Usage: "RPC URL to connect to", + EnvVars: opservice.PrefixEnvVar(EnvPrefix, "RPC_URL"), + } + BackoffFlag = &cli.DurationFlag{ + Name: "backoff", + Value: 30 * time.Second, + Usage: "how long to wait when a worker errors before retrying", + } + WorkerFlag = &cli.Uint64Flag{ + Name: "workers", + Value: 1, + Usage: "how many workers to use to fetch txs", + } + BatchSizeFlag = &cli.Uint64Flag{ + Name: "batch-size", + Value: 50, + Usage: "how many blocks to batch together for each worker", + } + OutputFlag = &cli.StringFlag{ + Name: "output", + Aliases: []string{"o"}, + Usage: "the file to write the results to", + } + FilesFlag = &cli.StringSliceFlag{ + Name: "files", + Aliases: []string{"f"}, + Usage: "the set of files to merge", + } + InputFormatFlag = &cli.StringFlag{ + Name: "input-format", + Aliases: []string{"if"}, + Value: "json", + Usage: "the format to read aggregate files: json, gob", + } + OutputFormatFlag = &cli.StringFlag{ + Name: "output-format", + Aliases: []string{"of"}, + Value: "json", + Usage: "the format to write the results in. Options: json, gob", + } + formats = map[string]aggregateReaderWriter{ + "json": jsonAggregateReaderWriter{}, + "gob": gobAggregateReaderWriter{}, + } + systemAddress = common.HexToAddress("0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001") + depositType = uint8(126) +) + +func main() { + color := isatty.IsTerminal(os.Stderr.Fd()) + oplog.SetGlobalLogHandler(log.NewTerminalHandlerWithLevel(os.Stdout, slog.LevelDebug, color)) + + app := &cli.App{ + Name: "receipt-reference-builder", + Usage: "Used to generate reference data for deposit receipts of pre-canyon blocks", + Flags: []cli.Flag{}, + Writer: os.Stdout, + } + + app.Commands = []*cli.Command{ + pullCommand, + mergeCommand, + convertCommand, + printCommand, + } + + if err := app.Run(os.Args); err != nil { + log.Crit("critical error", "err", err) + } +} + +type result struct { + BlockNumber uint64 `json:"blockNumber"` + Nonces []uint64 `json:"nonces"` +} + +type aggregate struct { + Results map[uint64][]uint64 `json:"results"` + ChainID uint64 `json:"chainId"` + First uint64 `json:"start"` + Last uint64 `json:"end"` +} diff --git a/op-chain-ops/cmd/receipt-reference-builder/merge.go b/op-chain-ops/cmd/receipt-reference-builder/merge.go new file mode 100644 index 000000000000..a269af2ae4b1 --- /dev/null +++ b/op-chain-ops/cmd/receipt-reference-builder/merge.go @@ -0,0 +1,105 @@ +package main + +import ( + "errors" + "sort" + + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" +) + +var mergeCommand = &cli.Command{ + Name: "merge", + Usage: "Merge one or more output files into a single file. Later files take precedence per key", + Flags: []cli.Flag{FilesFlag, OutputFlag, InputFormatFlag, OutputFormatFlag}, + Action: merge, +} + +// merge merges one or more files into a single file +func merge(ctx *cli.Context) error { + log := log.New() + files := ctx.StringSlice("files") + if len(files) < 2 { + return errors.New("need at least two files to merge") + } + + log.Info("merging", "files", files) + reader, ok := formats[ctx.String("input-format")] + if !ok { + log.Error("Invalid Input Format. Defaulting to JSON", "Format", ctx.String("input-format")) + reader = formats["json"] + } + writer, ok := formats[ctx.String("output-format")] + if !ok { + log.Error("Invalid Output Format. Defaulting to JSON", "Format", ctx.String("output-format")) + writer = formats["json"] + } + + aggregates := []aggregate{} + for _, f := range files { + a, err := reader.readAggregate(f) + if err != nil { + log.Error("failed to read aggregate", "file", f, "err", err) + return err + } + aggregates = append(aggregates, a) + } + + // sort the aggregates by first block + sort.Sort(ByFirst(aggregates)) + + // check that the block ranges don't have a gap + err := checkBlockRanges(aggregates) + if err != nil { + log.Error("error evaluating block ranges", "err", err) + return err + } + + // merge the aggregates + merged := aggregates[0] + log.Info("aggregates info", "aggs", aggregates, "len", len(aggregates)) + for _, a := range aggregates[1:] { + merged = mergeAggregates(merged, a, log) + } + + // write the merged aggregate + err = writer.writeAggregate(merged, ctx.String("output")) + if err != nil { + log.Error("failed to write aggregate", "err", err) + return err + } + + return nil +} + +type ByFirst []aggregate + +func (a ByFirst) Len() int { return len(a) } +func (a ByFirst) Less(i, j int) bool { return a[i].First < a[j].First } +func (a ByFirst) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// checkBlockRanges checks that the block ranges don't have a gap +// this function assumes the aggregates are sorted by first block +func checkBlockRanges(aggregates []aggregate) error { + last := aggregates[0].Last + for _, a := range aggregates[1:] { + if a.First > last+1 { + return errors.New("gap in block ranges") + } + last = a.Last + } + return nil +} + +// mergeAggregates merges two aggregates +// this function assumes the aggregates are sorted by first block +func mergeAggregates(a1, a2 aggregate, log log.Logger) aggregate { + log.Info("merging", "a1", a1, "a2", a2) + // merge the results + for k, v := range a2.Results { + a1.Results[k] = v + } + a1.Last = a2.Last + log.Info("result", "aggregate", a1) + return a1 +} diff --git a/op-chain-ops/cmd/receipt-reference-builder/print.go b/op-chain-ops/cmd/receipt-reference-builder/print.go new file mode 100644 index 000000000000..4b823eac3b58 --- /dev/null +++ b/op-chain-ops/cmd/receipt-reference-builder/print.go @@ -0,0 +1,28 @@ +package main + +import ( + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" +) + +var printCommand = &cli.Command{ + Name: "print", + Usage: "read an aggregate file and print it to stdout", + Flags: []cli.Flag{FilesFlag, InputFormatFlag}, + Action: print, +} + +func print(ctx *cli.Context) error { + log := log.New() + files := ctx.StringSlice("files") + r := formats[ctx.String("input-format")] + for _, f := range files { + a, err := r.readAggregate(f) + if err != nil { + log.Error("failed to read aggregate", "file", f, "err", err) + return err + } + log.Info("aggregate", "aggregate", a) + } + return nil +} diff --git a/op-chain-ops/cmd/receipt-reference-builder/pull.go b/op-chain-ops/cmd/receipt-reference-builder/pull.go new file mode 100644 index 000000000000..d6fa95eef33c --- /dev/null +++ b/op-chain-ops/cmd/receipt-reference-builder/pull.go @@ -0,0 +1,362 @@ +package main + +import ( + "context" + "errors" + "io" + "sync" + "time" + + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" + "github.com/urfave/cli/v2" +) + +var pullCommand = &cli.Command{ + Name: "pull", + Usage: "Pull a range of blocks and extract nonces from all user deposits", + Flags: []cli.Flag{StartFlag, EndFlag, RPCURLFlag, WorkerFlag, OutputFlag, BackoffFlag, BatchSizeFlag, OutputFormatFlag}, + Action: pull, +} + +var MaxBatchSize uint64 = 100 + +// pull will pull a range of blocks and extract nonces from all user deposits +// it will start a number of workers to process blocks +// and runs an aggregation to collect the results +func pull(ctx *cli.Context) error { + timeout := 1 * time.Minute + log := log.New() + // create a new client + c, err := dial.DialEthClientWithTimeout( + ctx.Context, + timeout, + log, + ctx.String("rpc-url"), + ) + if err != nil { + log.Error("Failed to dial rollup client", "Err", err) + return err + } + + cid, err := c.ChainID(ctx.Context) + if err != nil { + log.Error("Failed to Get Chain ID", "Err", err) + return err + } + chainID := cid.Uint64() + + // record start time + startT := time.Now() + + resultChan := make(chan result) + errorChan := make(chan error) + + start := ctx.Uint64("start") + end := ctx.Uint64("end") + workers := ctx.Uint64("workers") + batchSize := ctx.Uint64("batch-size") + writer, ok := formats[ctx.String("output-format")] + if !ok { + log.Error("Invalid Output Format. Defaulting to JSON", "Format", ctx.String("output-format")) + writer = formats["json"] + } + + if batchSize > MaxBatchSize { + log.Warn("Batch Size Too Large, Reducing", "BatchSize", batchSize, "MaxBatchSize", MaxBatchSize) + batchSize = MaxBatchSize + } + + log.Info("Starting", "First", start, "Last", end, "Workers", workers, "BatchSize", batchSize) + + // first cut the work into ranges for batching + // and load the work into a channel + if batchSize > end-start { + log.Info("More Batch Size Than Required", "BatchSize", batchSize, "Blocks", end-start) + batchSize = end - start + } + batches := toBatches(start, end, batchSize) + workChan := make(chan batchRange, len(batches)) + for _, b := range batches { + workChan <- b + } + retryWorkChan := make(chan batchRange, len(batches)) + + // set the number of workers to the number of batches if there are more workers than batches + if workers > uint64(len(batches)) { + log.Info("More Workers Than Batches", "Workers", workers, "Batches", len(batches)) + workers = uint64(len(batches)) + } + + // start workers + wg := &sync.WaitGroup{} + for id := uint64(0); id < workers; id++ { + wg.Add(1) + go startWorker( + id, ctx, c, + workChan, + retryWorkChan, + resultChan, + errorChan, + log, + wg) + } + + // start a worker-waiter to end the aggregation + done := make(chan struct{}) + go func() { + wg.Wait() + log.Info("All Workers Finished") + done <- struct{}{} + }() + + // aggregate until the done signal is received + aggregateResults, err := startAggregator(resultChan, errorChan, done, log) + if err != nil { + log.Error("Errors Encountered During Aggregation. All Jobs Retried to Completion") + } + aggregateResults.First = start + aggregateResults.Last = end + aggregateResults.ChainID = chainID + + err = writer.writeAggregate(aggregateResults, ctx.String("output")) + if err != nil { + log.Error("Failed to Write Aggregate Results", "Err", err) + return err + } + + log.Info("Finished", "Duration", time.Since(startT)) + + return nil +} + +type batchRange struct { + Start uint64 + End uint64 +} + +// toBatches is a helper function to split a single large range into smaller batches +func toBatches(start, end, size uint64) []batchRange { + batches := []batchRange{} + for i := start; i < end; i += size { + if i+size > end { + batches = append(batches, batchRange{i, end}) + } else { + batches = append(batches, batchRange{i, i + size}) + } + } + return batches +} + +// splitBatchRange will split a batch range into two smaller ranges +// it is used to reduce pressure from large batches dynamically +func splitBatchRange(b batchRange) []batchRange { + size := b.End - b.Start + if size < 2 { + return []batchRange{b} + } + half := size / 2 + return []batchRange{ + {b.Start, b.Start + half}, + {b.Start + half, b.End}, + } +} + +// startAggregator will aggregate the results of the workers and return the aggregation once done +// it will receive results on the results channel, and chooses to include them in the aggregation if they are not empty +// it logs errors from the error channel and joins them as part of the return +func startAggregator(results chan result, errorChan chan error, done chan struct{}, log log.Logger) (aggregate, error) { + aggregateResults := aggregate{ + Results: make(map[uint64][]uint64), + } + var errs error + handled := 0 + errCount := 0 + for { + select { + case r := <-results: + handled += 1 + if len(r.Nonces) > 0 { + log.Info("Block Has Deposit Transactions", "Block", r.BlockNumber, "Nonces", r.Nonces, "Handled", handled) + aggregateResults.Results[r.BlockNumber] = r.Nonces + } + case err := <-errorChan: + log.Error("Got Error", "Err", err) + errCount += 1 + errs = errors.Join(errs, err) + case <-done: + // drain the results channel + // this is not very DRY, but it is the simplest way to do this + for len(results) > 0 { + r := <-results + handled += 1 + if len(r.Nonces) > 0 { + log.Info("Block Has Deposit Transactions", "Block", r.BlockNumber, "Nonces", r.Nonces, "Handled", handled) + aggregateResults.Results[r.BlockNumber] = r.Nonces + } + } + log.Info("Finished Aggregation", "ResultsHandled", handled, "ResultsMatched", len(aggregateResults.Results)) + return aggregateResults, errs + } + } +} + +// startWorker will start a worker to process blocks. +// callers should set up the wait group and call this function as a goroutine +// each worker will process blocks until the work channel is empty +// if the worker fails to process a work item, it will be returned to the work channel and the worker will sleep for the backoff duration +// workers return results to the results channel, from which they will be aggregated +func startWorker( + id uint64, + ctx *cli.Context, + c *ethclient.Client, + workChan chan batchRange, + retryWorkChan chan batchRange, + resultsChan chan result, + errorsChan chan error, + log log.Logger, + wg *sync.WaitGroup) { + + defer wg.Done() + log.Info("Starting Worker", "ID", id) + for { + select { + case <-ctx.Context.Done(): + log.Info("Context Done") + return + // retry work is work that has been tried at least once. it is prioritized equally to new work + case b := <-retryWorkChan: + log.Info("Got Retry Work", "Start", b.Start, "End", b.End) + doWork(*ctx, b, resultsChan, errorsChan, retryWorkChan, c, log) + case b := <-workChan: + log.Info("Got Work", "Start", b.Start, "End", b.End) + doWork(*ctx, b, resultsChan, errorsChan, retryWorkChan, c, log) + default: + log.Info("No More Work") + return + } + } +} + +func doWork(ctx cli.Context, b batchRange, resultsChan chan result, errorChan chan error, retryChan chan batchRange, c *ethclient.Client, log log.Logger) { + results, err := processBlockRange(ctx.Context, c, b, log) + if err != nil { + log.Error("Failed to Process Blocks") + errorChan <- err + newWork := splitBatchRange(b) + for _, w := range newWork { + retryChan <- w + } + log.Warn("Returned Failed Work to Retry Channel. Sleeping for Backoff Duration", "Backoff", ctx.Duration("backoff"), "Start", b.Start, "End", b.End) + time.Sleep(ctx.Duration("backoff")) + } else { + for _, r := range results { + resultsChan <- r + } + } +} + +// processBlockRange will process a range of blocks for user deposits +// it takes a batchRange and constructs a batchRPC request for the blocks +// it then processes each block's transactions for user deposits +// a list of results is returned for each block +func processBlockRange( + ctx context.Context, + c *ethclient.Client, + br batchRange, + log log.Logger) ([]result, error) { + + // turn the batch range into a list of block numbers + nums := []rpc.BlockNumber{} + for i := br.Start; i < br.End; i++ { + nums = append(nums, rpc.BlockNumber(i)) + } + + // get all blocks in the batch range + blocks, err := batchBlockByNumber(ctx, c, nums) + if err != nil { + log.Error("Failed to Get Batched Blocks", "Err", err) + return []result{}, err + } + log.Info("Got Blocks", "NumBlocks", len(blocks)) + + results := []result{} + // process each block for user deposits + for i := 0; i < len(blocks); i++ { + b := blocks[i] + matches := 0 + blockNumber := b.BlockID().Number + res := result{ + BlockNumber: blockNumber, + Nonces: []uint64{}, + } + // process each transaction in the block + for j := 0; j < len(b.Transactions); j++ { + tx := b.Transactions[j] + ok, err := checkTransaction(ctx, c, *tx, log) + if err != nil { + log.Error("Failed to Check Tx", "Err", err) + return []result{}, err + } + // if the transaction matches the criteria, add it to the results + if ok { + matches += 1 + res.Nonces = append(res.Nonces, *tx.EffectiveNonce()) + } + } + log.Info("Processed Block", "Block", blockNumber, "TxCount", len(b.Transactions), "UserDeposits", matches) + results = append(results, res) + } + return results, nil +} + +// batchBlockByNumber will batch a list of block numbers into a single batch rpc request +// it uses the iterative batch call to make the request +// and returns the results +func batchBlockByNumber(ctx context.Context, c *ethclient.Client, blockNumbers []rpc.BlockNumber) ([]*sources.RPCBlock, error) { + makeBlockByNumberRequest := func(blockNumber rpc.BlockNumber) (*sources.RPCBlock, rpc.BatchElem) { + out := new(sources.RPCBlock) + return out, rpc.BatchElem{ + Method: "eth_getBlockByNumber", + Args: []any{blockNumber, true}, + Result: &out, + } + } + batchReq := batching.NewIterativeBatchCall[rpc.BlockNumber, *sources.RPCBlock]( + blockNumbers, + makeBlockByNumberRequest, + c.Client().BatchCallContext, + c.Client().CallContext, + int(MaxBatchSize), + ) + for { + if err := batchReq.Fetch(ctx); err == io.EOF { + break + } else if err != nil { + log.Warn("Failed to Fetch Blocks", "Err", err, "Start", blockNumbers[0], "End", blockNumbers[len(blockNumbers)-1]) + return nil, err + } + } + return batchReq.Result() +} + +// checkTransaction will check if a transaction is a user deposit, and not initiated by the system address +func checkTransaction(ctx context.Context, c *ethclient.Client, tx types.Transaction, log log.Logger) (bool, error) { + from, err := types.Sender(types.LatestSignerForChainID(tx.ChainId()), &tx) + if err != nil { + log.Error("Failed to Get Sender", "Err", err) + return false, err + } + // we are filtering for deposit transactions which are not system transactions + if tx.Type() == depositType && + from != systemAddress { + log.Info("Got Transaction", "From", from, "Nonce", *tx.EffectiveNonce(), "Type", tx.Type()) + return true, nil + } + return false, nil +} diff --git a/op-chain-ops/cmd/receipt-reference-builder/readwrite.go b/op-chain-ops/cmd/receipt-reference-builder/readwrite.go new file mode 100644 index 000000000000..d556227c245e --- /dev/null +++ b/op-chain-ops/cmd/receipt-reference-builder/readwrite.go @@ -0,0 +1,78 @@ +package main + +import ( + "encoding/gob" + "encoding/json" + "fmt" + "os" +) + +type aggregateReaderWriter interface { + writeAggregate(a aggregate, o string) error + readAggregate(f string) (aggregate, error) +} + +type jsonAggregateReaderWriter struct{} + +// writeAggregate writes the aggregate to a file in json format +// if the output file is not specified, it will create a file based on the block range +func (w jsonAggregateReaderWriter) writeAggregate(a aggregate, o string) error { + if o == "" { + o = fmt.Sprintf("%d.%d-%d.json", a.ChainID, a.First, a.Last) + } + // write the results to a file + aggregateJson, err := json.Marshal(a) + if err != nil { + return err + } + err = os.WriteFile(o, aggregateJson, 0644) + return err +} + +// readAggregate reads the aggregate from a file in json format +func (w jsonAggregateReaderWriter) readAggregate(f string) (aggregate, error) { + // read the file + aggregateJson, err := os.ReadFile(f) + if err != nil { + return aggregate{}, err + } + var a aggregate + err = json.Unmarshal(aggregateJson, &a) + if err != nil { + return aggregate{}, err + } + return a, nil +} + +type gobAggregateReaderWriter struct{} + +// writeAggregate writes the aggregate to a file in gob format +// if the output file is not specified, it will creeate a file based on the block range +func (w gobAggregateReaderWriter) writeAggregate(a aggregate, o string) error { + if o == "" { + o = fmt.Sprintf("%d.%d-%d.gob", a.ChainID, a.First, a.Last) + } + file, err := os.Create(o) + if err != nil { + return err + } + defer file.Close() + + encoder := gob.NewEncoder(file) + err = encoder.Encode(&a) + return err +} + +// readAggregate reads the aggregate from a file in gob format +func (w gobAggregateReaderWriter) readAggregate(f string) (aggregate, error) { + file, err := os.Open(f) + if err != nil { + return aggregate{}, err + } + defer file.Close() + + a := aggregate{} + decoder := gob.NewDecoder(file) + err = decoder.Decode(&a) + return a, err +} diff --git a/op-chain-ops/cmd/registry-data/main.go b/op-chain-ops/cmd/registry-data/main.go index 75fc78dd93c5..1f33d65db8db 100644 --- a/op-chain-ops/cmd/registry-data/main.go +++ b/op-chain-ops/cmd/registry-data/main.go @@ -12,6 +12,7 @@ import ( opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/jsonutil" + oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" @@ -52,7 +53,8 @@ var ( ) func main() { - log.Root().SetHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(isatty.IsTerminal(os.Stderr.Fd())))) + color := isatty.IsTerminal(os.Stderr.Fd()) + oplog.SetGlobalLogHandler(log.NewTerminalHandler(os.Stderr, color)) app := &cli.App{ Name: "registry-data", diff --git a/op-chain-ops/crossdomain/legacy_withdrawal.go b/op-chain-ops/crossdomain/legacy_withdrawal.go index 1a6b6abb4f15..ac2ec3602867 100644 --- a/op-chain-ops/crossdomain/legacy_withdrawal.go +++ b/op-chain-ops/crossdomain/legacy_withdrawal.go @@ -41,7 +41,7 @@ func NewLegacyWithdrawal(msgSender, target, sender common.Address, data []byte, } } -// Encode will serialze the Withdrawal in the legacy format so that it +// Encode will serialize the Withdrawal in the legacy format so that it // is suitable for hashing. This assumes that the message is being withdrawn // through the standard optimism cross domain messaging system by hashing in // the L2CrossDomainMessenger address. diff --git a/op-chain-ops/crossdomain/legacy_withdrawal_test.go b/op-chain-ops/crossdomain/legacy_withdrawal_test.go index fb490cb0ffa6..72bd27583d5f 100644 --- a/op-chain-ops/crossdomain/legacy_withdrawal_test.go +++ b/op-chain-ops/crossdomain/legacy_withdrawal_test.go @@ -86,7 +86,7 @@ func init() { if err := readStateDiffs(); err != nil { panic(err) } - // Initialze the message passer ABI + // Initialize the message passer ABI var err error passMessage, err = abi.JSON(strings.NewReader(passMessageABI)) if err != nil { diff --git a/op-chain-ops/crossdomain/testdata/trace.sh b/op-chain-ops/crossdomain/testdata/trace.sh index c188d34f4e43..a2c6308782b7 100755 --- a/op-chain-ops/crossdomain/testdata/trace.sh +++ b/op-chain-ops/crossdomain/testdata/trace.sh @@ -12,19 +12,19 @@ TRACES=$DIR/call-traces RECEIPTS=$DIR/receipts DIFFS=$DIR/state-diffs -mkdir -p $TRACES -mkdir -p $RECEIPTS -mkdir -p $DIFFS +mkdir -p "$TRACES" +mkdir -p "$RECEIPTS" +mkdir -p "$DIFFS" cast rpc \ debug_traceTransaction \ - $HASH \ - '{"tracer": "callTracer"}' | jq > $TRACES/$HASH.json + "$HASH" \ + '{"tracer": "callTracer"}' | jq > "$TRACES"/"$HASH".json -cast receipt $HASH --json | jq > $RECEIPTS/$HASH.json +cast receipt "$HASH" --json | jq > "$RECEIPTS"/"$HASH".json cast rpc \ debug_traceTransaction \ - $HASH \ - '{"tracer": "prestateTracer"}' | jq > $DIFFS/$HASH.json + "$HASH" \ + '{"tracer": "prestateTracer"}' | jq > "$DIFFS"/"$HASH".json diff --git a/op-chain-ops/deployer/deployer.go b/op-chain-ops/deployer/deployer.go index 79ac040eaf0a..429bf6470723 100644 --- a/op-chain-ops/deployer/deployer.go +++ b/op-chain-ops/deployer/deployer.go @@ -2,9 +2,11 @@ package deployer import ( "context" + "errors" "fmt" "math/big" + "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" @@ -32,6 +34,11 @@ type Constructor struct { Args []interface{} } +type SuperchainPredeploy struct { + Name string + CodeHash common.Hash +} + type Deployment struct { Name string Bytecode hexutil.Bytes @@ -42,19 +49,28 @@ type Deployer func(*backends.SimulatedBackend, *bind.TransactOpts, Constructor) // NewL1Backend returns a SimulatedBackend suitable for L1. It has // the latest L1 hardforks enabled. -func NewL1Backend() *backends.SimulatedBackend { - return NewBackendWithGenesisTimestamp(0, true) +func NewL1Backend() (*backends.SimulatedBackend, error) { + backend, err := NewBackendWithGenesisTimestamp(ChainID, 0, true, nil) + return backend, err } // NewL2Backend returns a SimulatedBackend suitable for L2. // It has the latest L2 hardforks enabled. -func NewL2Backend() *backends.SimulatedBackend { - return NewBackendWithGenesisTimestamp(0, false) +func NewL2Backend() (*backends.SimulatedBackend, error) { + backend, err := NewBackendWithGenesisTimestamp(ChainID, 0, false, nil) + return backend, err } -func NewBackendWithGenesisTimestamp(ts uint64, shanghai bool) *backends.SimulatedBackend { +// NewL2BackendWithChainIDAndPredeploys returns a SimulatedBackend suitable for L2. +// It has the latest L2 hardforks enabled, and allows for the configuration of the network's chain ID and predeploys. +func NewL2BackendWithChainIDAndPredeploys(chainID *big.Int, predeploys map[string]*common.Address) (*backends.SimulatedBackend, error) { + backend, err := NewBackendWithGenesisTimestamp(chainID, 0, false, predeploys) + return backend, err +} + +func NewBackendWithGenesisTimestamp(chainID *big.Int, ts uint64, shanghai bool, predeploys map[string]*common.Address) (*backends.SimulatedBackend, error) { chainConfig := params.ChainConfig{ - ChainID: ChainID, + ChainID: chainID, HomesteadBlock: big.NewInt(0), DAOForkBlock: nil, DAOForkSupport: false, @@ -82,6 +98,21 @@ func NewBackendWithGenesisTimestamp(ts uint64, shanghai bool) *backends.Simulate chainConfig.ShanghaiTime = u64ptr(0) } + alloc := core.GenesisAlloc{ + crypto.PubkeyToAddress(TestKey.PublicKey): core.GenesisAccount{ + Balance: thousandETH, + }, + } + for name, address := range predeploys { + bytecode, err := bindings.GetDeployedBytecode(name) + if err != nil { + return nil, err + } + alloc[*address] = core.GenesisAccount{ + Code: bytecode, + } + } + return backends.NewSimulatedBackendWithOpts( backends.WithCacheConfig(&core.CacheConfig{ Preimages: true, @@ -90,13 +121,11 @@ func NewBackendWithGenesisTimestamp(ts uint64, shanghai bool) *backends.Simulate Config: &chainConfig, Timestamp: ts, Difficulty: big.NewInt(0), - Alloc: core.GenesisAlloc{ - crypto.PubkeyToAddress(TestKey.PublicKey): {Balance: thousandETH}, - }, - GasLimit: 15000000, + Alloc: alloc, + GasLimit: 30_000_000, }), backends.WithConsensus(beacon.New(ethash.NewFaker())), - ) + ), nil } func Deploy(backend *backends.SimulatedBackend, constructors []Constructor, cb Deployer) ([]Deployment, error) { @@ -145,6 +174,95 @@ func Deploy(backend *backends.SimulatedBackend, constructors []Constructor, cb D return results, nil } +// DeployWithDeterministicDeployer deploys a smart contract on a simulated Ethereum blockchain using a deterministic deployment proxy (Arachnid's). +// +// Parameters: +// - backend: A pointer to backends.SimulatedBackend, representing the simulated Ethereum blockchain. +// Expected to have Arachnid's proxy deployer predeploys at 0x4e59b44847b379578588920cA78FbF26c0B4956C, NewL2BackendWithChainIDAndPredeploys handles this for you. +// - contractName: A string representing the name of the contract to be deployed. +// +// Returns: +// - []byte: The deployed bytecode of the contract. +// - error: An error object indicating any issues encountered during the deployment process. +// +// The function logs a fatal error and exits if there are any issues with transaction mining, if the deployment fails, +// or if the deployed bytecode is not found at the computed address. +func DeployWithDeterministicDeployer(backend *backends.SimulatedBackend, contractName string) ([]byte, error) { + opts, err := bind.NewKeyedTransactorWithChainID(TestKey, backend.Blockchain().Config().ChainID) + if err != nil { + return nil, err + } + + deployerAddress, err := bindings.GetDeployerAddress(contractName) + if err != nil { + return nil, err + } + + deploymentSalt, err := bindings.GetDeploymentSalt(contractName) + if err != nil { + return nil, err + } + + initBytecode, err := bindings.GetInitBytecode(contractName) + if err != nil { + return nil, err + } + + transactor, err := bindings.NewDeterministicDeploymentProxyTransactor(common.BytesToAddress(deployerAddress), backend) + if err != nil { + return nil, fmt.Errorf("failed to initialize deployment proxy transactor at %s: %w", deployerAddress, err) + } + + tx, err := transactor.Fallback(opts, append(deploymentSalt, initBytecode...)) + if err != nil { + return nil, err + } + + backend.Commit() + + receipt, err := bind.WaitMined(context.Background(), backend, tx) + if err != nil { + return nil, fmt.Errorf("failed to get transaction receipt: %w", err) + } + if receipt.Status == 0 { + return nil, errors.New("failed to deploy contract using proxy deployer") + } + + address := create2Address( + deployerAddress, + deploymentSalt, + initBytecode, + ) + + code, _ := backend.CodeAt(context.Background(), address, nil) + if len(code) == 0 { + return nil, fmt.Errorf("no code found for %s at: %s", contractName, address) + } + + return code, nil +} + func u64ptr(n uint64) *uint64 { return &n } + +// create2Address computes the Ethereum address for a contract created using the CREATE2 opcode. +// +// The CREATE2 opcode allows for more deterministic address generation in Ethereum, as it computes the +// address based on the creator's address, a salt value, and the contract's initialization code. +// +// Parameters: +// - creatorAddress: A byte slice representing the address of the account creating the contract. +// - salt: A byte slice representing the salt used in the address generation process. This can be any 32-byte value. +// - initCode: A byte slice representing the contract's initialization bytecode. +// +// Returns: +// - common.Address: The Ethereum address calculated using the CREATE2 opcode logic. +func create2Address(creatorAddress, salt, initCode []byte) common.Address { + payload := append([]byte{0xff}, creatorAddress...) + payload = append(payload, salt...) + initCodeHash := crypto.Keccak256(initCode) + payload = append(payload, initCodeHash...) + + return common.BytesToAddress(crypto.Keccak256(payload)[12:]) +} diff --git a/op-chain-ops/deployer/deployer_test.go b/op-chain-ops/deployer/deployer_test.go new file mode 100644 index 000000000000..0c937a768f9b --- /dev/null +++ b/op-chain-ops/deployer/deployer_test.go @@ -0,0 +1,62 @@ +package deployer + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +func TestCreate2Address(t *testing.T) { + tests := []struct { + name string + creatorAddress []byte + salt []byte + initCode []byte + expectedAddress common.Address + }{ + { + name: "SafeL2", + creatorAddress: common.HexToAddress("0x4e59b44847b379578588920cA78FbF26c0B4956C").Bytes(), + salt: common.FromHex("0000000000000000000000000000000000000000000000000000000000000000"), + expectedAddress: common.HexToAddress("0x3E5c63644E683549055b9Be8653de26E0B4CD36E"), + }, + { + name: "MultiSendCallOnly", + creatorAddress: common.HexToAddress("0x4e59b44847b379578588920cA78FbF26c0B4956C").Bytes(), + salt: common.FromHex("0000000000000000000000000000000000000000000000000000000000000000"), + expectedAddress: common.HexToAddress("0x40A2aCCbd92BCA938b02010E17A5b8929b49130D"), + }, + { + name: "MultiSend", + creatorAddress: common.HexToAddress("0x4e59b44847b379578588920cA78FbF26c0B4956C").Bytes(), + salt: common.FromHex("0000000000000000000000000000000000000000000000000000000000000000"), + expectedAddress: common.HexToAddress("0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761"), + }, + { + name: "Permit2", + creatorAddress: common.HexToAddress("0x4e59b44847b379578588920cA78FbF26c0B4956C").Bytes(), + salt: common.FromHex("0000000000000000000000000000000000000000d3af2663da51c10215000000"), + expectedAddress: common.HexToAddress("0x000000000022D473030F116dDEE9F6B43aC78BA3"), + }, + { + name: "EntryPoint", + creatorAddress: common.HexToAddress("0x4e59b44847b379578588920cA78FbF26c0B4956C").Bytes(), + salt: common.FromHex("0000000000000000000000000000000000000000000000000000000000000000"), + expectedAddress: common.HexToAddress("0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"), + }, + } + + for _, test := range tests { + var err error + test.initCode, err = getInitCode(test.name) + if err != nil { + t.Error(err) + } + + t.Run(test.name, func(t *testing.T) { + if got := create2Address(test.creatorAddress, test.salt, test.initCode); got != test.expectedAddress { + t.Errorf("expected: %x, want: %x", got, test.expectedAddress) + } + }) + } +} diff --git a/op-chain-ops/deployer/testdata.go b/op-chain-ops/deployer/testdata.go new file mode 100644 index 000000000000..c7b802a139dc --- /dev/null +++ b/op-chain-ops/deployer/testdata.go @@ -0,0 +1,24 @@ +package deployer + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" +) + +func getInitCode(contractName string) ([]byte, error) { + switch contractName { + case "SafeL2": + return common.FromHex("608060405234801561001057600080fd5b506001600481905550615cf880620000296000396000f3fe6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506126fc565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b810190808035906020019092919080359060200190929190505050612732565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b81019080803590602001909291905050506127b9565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506127d1565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612b63565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612c9d565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612edc565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612f01565b005b348015610d3457600080fd5b50610d3d612f90565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613139565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061313f565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613161565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff16906020019092919050505061331f565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613447565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613639565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506137d8565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613805565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b96565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613c1a565b005b34801561148957600080fd5b5061149261428c565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614296565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061443e565b005b3480156116a457600080fd5b506116ad61449f565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061451d565b005b34801561174a57600080fd5b50611753614950565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614989565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612b63565b5b5050565b611bd2604182614a2c90919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614a66565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614a2c90919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614a9590919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614a9590919063ffffffff16565b614a9590919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b60007fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183600181111561266b57fe5b8152602001828103825284818151815260200191508051906020019080838360005b838110156126a857808201518184015260208101905061268d565b50505050905090810190601f1680156126d55780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a16126f285858585614ab4565b9050949350505050565b6000606061270c868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561275057600080fd5b506040519080825280601f01601f1916602001820160405280156127835781602001600182028036833780820191505090505b50905060005b838110156127ae57808501548060208302602085010152508080600101915050612789565b508091505092915050565b60076020528060005260406000206000915090505481565b6127d9614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156128435750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b6128b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146129b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612b6b614989565b600354811115612be3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612c5a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000606060055433600454604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612d5057fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184810384528e8e82818152602001925080828437600081840152601f19601f820116905080830192505050848103835286818151815260200191508051906020019080838360005b83811015612e0a578082015181840152602081019050612def565b50505050905090810190601f168015612e375780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b83811015612e70578082015181840152602081019050612e55565b50505050905090810190601f168015612e9d5780820380516001836020036101000a031916815260200191505b509f5050505050505050505050505050505060405180910390a1612eca8d8d8d8d8d8d8d8d8d8d8d614c9a565b9150509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111612f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612f8a84848484611bbe565b50505050565b6060600060035467ffffffffffffffff81118015612fad57600080fd5b50604051908082528060200260200182016040528015612fdc5781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613130578083838151811061308757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050613046565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6131ac8a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050896151d7565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146131ea576131e9846156d7565b5b6132388787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615706565b60008211156132525761325082600060018685615941565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a9050613376878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615b47565b61337f57600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561340c5780820151818401526020810190506133f1565b50505050905090810190601f1680156134395780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561346257600080fd5b506040519080825280602002602001820160405280156134915781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156135645750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561356f57508482105b1561362a578084838151811061358157fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506134fa565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561373b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b60006137ed8c8c8c8c8c8c8c8c8c8c8c614296565b8051906020012090509b9a5050505050505050505050565b61380d614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156138775750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b6138e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146139e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613b9e614989565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613c22614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c8c5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613cc457503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613d36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613e37576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613ea15750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b613f13576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614013576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561432757fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6143b361449f565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b614446614989565b61444f816156d7565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6144cd6125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b614525614989565b8060016003540310156145a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561460a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b61467c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461477c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1806004541461494b5761494a81612b63565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614a2a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614a3f5760009050614a60565b6000828402905082848281614a5057fe5b0414614a5b57600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614aaa57600080fd5b8091505092915050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015614b7f5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b614bf1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b614bfe858585855a615b47565b90508015614c4e573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a2614c92565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000806000614cb48e8e8e8e8e8e8e8e8e8e600554614296565b905060056000815480929190600101919050555080805190602001209150614cdd828286612f01565b506000614ce8615b93565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614614ece578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115614d8b57fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015614e5d578082015181840152602081019050614e42565b50505050905090810190601f168015614e8a5780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015614eb557600080fd5b505af1158015614ec9573d6000803e3d6000fd5b505050505b6101f4614ef56109c48b01603f60408d0281614ee657fe5b04615bc490919063ffffffff16565b015a1015614f6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a9050614fd48f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d14614fc9578e614fcf565b6109c45a035b615b47565b9350614fe95a82615bde90919063ffffffff16565b90508380614ff8575060008a14155b80615004575060008814155b615076576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808911156150905761508d828b8b8b8b615941565b90505b84156150da577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a161511a565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146151c6578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b1580156151ad57600080fd5b505af11580156151c1573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b60006004541461524f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b81518111156152c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600181101561533d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b835181101561564357600084828151811061535d57fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153d15750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561540957503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561544157508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b6154b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146155b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550809250508080600101915050615346565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615808576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461593d576158ca8260008360015a615b47565b61593c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461597e5782615980565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615a98576159ea3a86106159c7573a6159c9565b855b6159dc888a614a9590919063ffffffff16565b614a2c90919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615a93576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615b3d565b615abd85615aaf888a614a9590919063ffffffff16565b614a2c90919063ffffffff16565b9150615aca848284615bfe565b615b3c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600180811115615b5557fe5b836001811115615b6157fe5b1415615b7a576000808551602087018986f49050615b8a565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015615bd45781615bd6565b825b905092915050565b600082821115615bed57600080fd5b600082840390508091505092915050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d60008114615ca55760208114615cad5760009350615cb8565b819350615cb8565b600051158215171593505b505050939250505056fea2646970667358221220047fac33099ca576d1c4f1ac6a8abdb0396e42ad6a397d2cb2f4dc1624cc0c5b64736f6c63430007060033"), nil + case "MultiSendCallOnly": + return common.FromHex("608060405234801561001057600080fd5b5061019a806100206000396000f3fe60806040526004361061001e5760003560e01c80638d80ff0a14610023575b600080fd5b6100dc6004803603602081101561003957600080fd5b810190808035906020019064010000000081111561005657600080fd5b82018360208201111561006857600080fd5b8035906020019184600183028401116401000000008311171561008a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100de565b005b805160205b8181101561015f578083015160f81c6001820184015160601c60158301850151603584018601516055850187016000856000811461012857600181146101385761013d565b6000808585888a5af1915061013d565b600080fd5b50600081141561014c57600080fd5b82605501870196505050505050506100e3565b50505056fea264697066735822122035246402746c96964495cae5b36461fd44dfb89f8e6cf6f6b8d60c0aa89f414864736f6c63430007060033"), nil + case "MultiSend": + return common.FromHex("60a060405234801561001057600080fd5b503073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b8152505060805160601c6102756100646000398060e052506102756000f3fe60806040526004361061001e5760003560e01c80638d80ff0a14610023575b600080fd5b6100dc6004803603602081101561003957600080fd5b810190808035906020019064010000000081111561005657600080fd5b82018360208201111561006857600080fd5b8035906020019184600183028401116401000000008311171561008a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100de565b005b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161415610183576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806102106030913960400191505060405180910390fd5b805160205b8181101561020a578083015160f81c6001820184015160601c6015830185015160358401860151605585018701600085600081146101cd57600181146101dd576101e8565b6000808585888a5af191506101e8565b6000808585895af491505b5060008114156101f757600080fd5b8260550187019650505050505050610188565b50505056fe4d756c746953656e642073686f756c64206f6e6c792062652063616c6c6564207669612064656c656761746563616c6ca26469706673582212205c784303626eec02b71940b551976170b500a8a36cc5adcbeb2c19751a76d05464736f6c63430007060033"), nil + case "Permit2": + return common.FromHex("60c0346100bb574660a052602081017f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a60408301524660608301523060808301526080825260a082019180831060018060401b038411176100a557826040525190206080526123c090816100c1823960805181611b47015260a05181611b210152f35b634e487b7160e01b600052604160045260246000fd5b600080fdfe6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000003611b69577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a"), nil + case "EntryPoint": + return common.FromHex("60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033"), nil + default: + return nil, fmt.Errorf("no initialization byte code available for contract: %s", contractName) + } +} diff --git a/op-chain-ops/genesis/config.go b/op-chain-ops/genesis/config.go index ebf5045b9e69..9ff847b421f7 100644 --- a/op-chain-ops/genesis/config.go +++ b/op-chain-ops/genesis/config.go @@ -18,7 +18,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum-optimism/optimism/op-bindings/hardhat" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-chain-ops/immutables" "github.com/ethereum-optimism/optimism/op-chain-ops/state" @@ -27,11 +26,6 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" ) -// initialzedValue represents the `Initializable` contract value. It should be kept in -// sync with the constant in `Constants.sol`. -// https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/libraries/Constants.sol -const initializedValue = 3 - var ( ErrInvalidDeployConfig = errors.New("invalid deploy config") ErrInvalidImmutablesConfig = errors.New("invalid immutables config") @@ -117,10 +111,19 @@ type DeployConfig struct { L2GenesisRegolithTimeOffset *hexutil.Uint64 `json:"l2GenesisRegolithTimeOffset,omitempty"` // L2GenesisCanyonTimeOffset is the number of seconds after genesis block that Canyon hard fork activates. // Set it to 0 to activate at genesis. Nil to disable Canyon. - L2GenesisCanyonTimeOffset *hexutil.Uint64 `json:"L2GenesisCanyonTimeOffset,omitempty"` - // L2GenesisSpanBatchTimeOffset is the number of seconds after genesis block that Span Batch hard fork activates. - // Set it to 0 to activate at genesis. Nil to disable SpanBatch. - L2GenesisSpanBatchTimeOffset *hexutil.Uint64 `json:"l2GenesisSpanBatchTimeOffset,omitempty"` + L2GenesisCanyonTimeOffset *hexutil.Uint64 `json:"l2GenesisCanyonTimeOffset,omitempty"` + // L2GenesisDeltaTimeOffset is the number of seconds after genesis block that Delta hard fork activates. + // Set it to 0 to activate at genesis. Nil to disable Delta. + L2GenesisDeltaTimeOffset *hexutil.Uint64 `json:"l2GenesisDeltaTimeOffset,omitempty"` + // L2GenesisEcotoneTimeOffset is the number of seconds after genesis block that Ecotone hard fork activates. + // Set it to 0 to activate at genesis. Nil to disable Ecotone. + L2GenesisEcotoneTimeOffset *hexutil.Uint64 `json:"l2GenesisEcotoneTimeOffset,omitempty"` + // L2GenesisFjordTimeOffset is the number of seconds after genesis block that Fjord hard fork activates. + // Set it to 0 to activate at genesis. Nil to disable Fjord. + L2GenesisFjordTimeOffset *hexutil.Uint64 `json:"l2GenesisFjordTimeOffset,omitempty"` + // L2GenesisInteropTimeOffset is the number of seconds after genesis block that the Interop hard fork activates. + // Set it to 0 to activate at genesis. Nil to disable Interop. + L2GenesisInteropTimeOffset *hexutil.Uint64 `json:"l2GenesisInteropTimeOffset,omitempty"` // L2GenesisBlockExtraData is configurable extradata. Will default to []byte("BEDROCK") if left unspecified. L2GenesisBlockExtraData []byte `json:"l2GenesisBlockExtraData"` // ProxyAdminOwner represents the owner of the ProxyAdmin predeploy on L2. @@ -128,8 +131,8 @@ type DeployConfig struct { // FinalSystemOwner is the owner of the system on L1. Any L1 contract that is ownable has // this account set as its owner. FinalSystemOwner common.Address `json:"finalSystemOwner"` - // PortalGuardian represents the GUARDIAN account in the OptimismPortal. Has the ability to pause withdrawals. - PortalGuardian common.Address `json:"portalGuardian"` + // SuperchainConfigGuardian represents the GUARDIAN account in the SuperchainConfig. Has the ability to pause withdrawals. + SuperchainConfigGuardian common.Address `json:"superchainConfigGuardian"` // BaseFeeVaultRecipient represents the recipient of fees accumulated in the BaseFeeVault. // Can be an account on L1 or L2, depending on the BaseFeeVaultWithdrawalNetwork value. BaseFeeVaultRecipient common.Address `json:"baseFeeVaultRecipient"` @@ -195,10 +198,6 @@ type DeployConfig struct { // FaultGameAbsolutePrestate is the absolute prestate of Cannon. This is computed // by generating a proof from the 0th -> 1st instruction and grabbing the prestate from // the output JSON. All honest challengers should agree on the setup state of the program. - // TODO(clabby): Right now, the build of the `op-program` is nondeterministic, meaning that - // the binary must be distributed in order for honest actors to agree. In the future, we'll - // look to make the build deterministic so that users may build Cannon / the `op-program` - // from source. FaultGameAbsolutePrestate common.Hash `json:"faultGameAbsolutePrestate"` // FaultGameMaxDepth is the maximum depth of the position tree within the fault dispute game. // `2^{FaultGameMaxDepth}` is how many instructions the execution trace bisection game @@ -209,6 +208,18 @@ type DeployConfig struct { // game can run for before it is ready to be resolved. Each side receives half of this value // on their chess clock at the inception of the dispute. FaultGameMaxDuration uint64 `json:"faultGameMaxDuration"` + // FaultGameGenesisBlock is the block number for genesis. + FaultGameGenesisBlock uint64 `json:"faultGameGenesisBlock"` + // FaultGameGenesisOutputRoot is the output root for the genesis block. + FaultGameGenesisOutputRoot common.Hash `json:"faultGameGenesisOutputRoot"` + // FaultGameSplitDepth is the depth at which the fault dispute game splits from output roots to execution trace claims. + FaultGameSplitDepth uint64 `json:"faultGameSplitDepth"` + // FaultGameWithdrawalDelay is the number of seconds that users must wait before withdrawing ETH from a fault game. + FaultGameWithdrawalDelay uint64 `json:"faultGameWithdrawalDelay"` + // PreimageOracleMinProposalSize is the minimum number of bytes that a large preimage oracle proposal can be. + PreimageOracleMinProposalSize uint64 `json:"preimageOracleMinProposalSize"` + // PreimageOracleChallengePeriod is the number of seconds that challengers have to challenge a large preimage proposal. + PreimageOracleChallengePeriod uint64 `json:"preimageOracleChallengePeriod"` // FundDevAccounts configures whether or not to fund the dev accounts. Should only be used // during devnet deployments. FundDevAccounts bool `json:"fundDevAccounts"` @@ -220,6 +231,36 @@ type DeployConfig struct { // RequiredProtocolVersion indicates the protocol version that // nodes are recommended to adopt, to stay in sync with the network. RecommendedProtocolVersion params.ProtocolVersion `json:"recommendedProtocolVersion"` + // ProofMaturityDelaySeconds is the number of seconds that a proof must be + // mature before it can be used to finalize a withdrawal. + ProofMaturityDelaySeconds uint64 `json:"proofMaturityDelaySeconds"` + // DisputeGameFinalityDelaySeconds is an additional number of seconds a + // dispute game must wait before it can be used to finalize a withdrawal. + DisputeGameFinalityDelaySeconds uint64 `json:"disputeGameFinalityDelaySeconds"` + // RespectedGameType is the dispute game type that the OptimismPortal + // contract will respect for finalizing withdrawals. + RespectedGameType uint32 `json:"respectedGameType"` + // UseFaultProofs is a flag that indicates if the system is using fault + // proofs instead of the older output oracle mechanism. + UseFaultProofs bool `json:"useFaultProofs"` + + // UsePlasma is a flag that indicates if the system is using op-plasma + UsePlasma bool `json:"usePlasma"` + // DAChallengeWindow represents the block interval during which the availability of a data commitment can be challenged. + DAChallengeWindow uint64 `json:"daChallengeWindow"` + // DAResolveWindow represents the block interval during which a data availability challenge can be resolved. + DAResolveWindow uint64 `json:"daResolveWindow"` + // DABondSize represents the required bond size to initiate a data availability challenge. + DABondSize uint64 `json:"daBondSize"` + // DAResolverRefundPercentage represents the percentage of the resolving cost to be refunded to the resolver + // such as 100 means 100% refund. + DAResolverRefundPercentage uint64 `json:"daResolverRefundPercentage"` + + // DAChallengeProxy represents the L1 address of the DataAvailabilityChallenge contract. + DAChallengeProxy common.Address `json:"daChallengeProxy"` + + // When Cancun activates. Relative to L1 genesis. + L1CancunTimeOffset *hexutil.Uint64 `json:"l1CancunTimeOffset,omitempty"` } // Copy will deeply copy the DeployConfig. This does a JSON roundtrip to copy @@ -257,8 +298,8 @@ func (d *DeployConfig) Check() error { if d.L2OutputOracleStartingBlockNumber == 0 { log.Warn("L2OutputOracleStartingBlockNumber is 0, should only be 0 for fresh chains") } - if d.PortalGuardian == (common.Address{}) { - return fmt.Errorf("%w: PortalGuardian cannot be address(0)", ErrInvalidDeployConfig) + if d.SuperchainConfigGuardian == (common.Address{}) { + return fmt.Errorf("%w: SuperchainConfigGuardian cannot be address(0)", ErrInvalidDeployConfig) } if d.MaxSequencerDrift == 0 { return fmt.Errorf("%w: MaxSequencerDrift cannot be 0", ErrInvalidDeployConfig) @@ -355,6 +396,57 @@ func (d *DeployConfig) Check() error { if d.L1BlockTime < d.L2BlockTime { return fmt.Errorf("L2 block time (%d) is larger than L1 block time (%d)", d.L2BlockTime, d.L1BlockTime) } + if d.RequiredProtocolVersion == (params.ProtocolVersion{}) { + log.Warn("RequiredProtocolVersion is empty") + } + if d.RecommendedProtocolVersion == (params.ProtocolVersion{}) { + log.Warn("RecommendedProtocolVersion is empty") + } + if d.ProofMaturityDelaySeconds == 0 { + log.Warn("ProofMaturityDelaySeconds is 0") + } + if d.DisputeGameFinalityDelaySeconds == 0 { + log.Warn("DisputeGameFinalityDelaySeconds is 0") + } + if d.UsePlasma { + if d.DAChallengeWindow == 0 { + return fmt.Errorf("%w: DAChallengeWindow cannot be 0 when using plasma mode", ErrInvalidDeployConfig) + } + if d.DAResolveWindow == 0 { + return fmt.Errorf("%w: DAResolveWindow cannot be 0 when using plasma mode", ErrInvalidDeployConfig) + } + if d.DAChallengeProxy == (common.Address{}) { + return fmt.Errorf("%w: DAChallengeContract cannot be empty when using plasma mode", ErrInvalidDeployConfig) + } + } + // checkFork checks that fork A is before or at the same time as fork B + checkFork := func(a, b *hexutil.Uint64, aName, bName string) error { + if a == nil && b == nil { + return nil + } + if a == nil && b != nil { + return fmt.Errorf("fork %s set (to %d), but prior fork %s missing", bName, *b, aName) + } + if a != nil && b == nil { + return nil + } + if *a > *b { + return fmt.Errorf("fork %s set to %d, but prior fork %s has higher offset %d", bName, *b, aName, *a) + } + return nil + } + if err := checkFork(d.L2GenesisRegolithTimeOffset, d.L2GenesisCanyonTimeOffset, "regolith", "canyon"); err != nil { + return err + } + if err := checkFork(d.L2GenesisCanyonTimeOffset, d.L2GenesisDeltaTimeOffset, "canyon", "delta"); err != nil { + return err + } + if err := checkFork(d.L2GenesisDeltaTimeOffset, d.L2GenesisEcotoneTimeOffset, "delta", "ecotone"); err != nil { + return err + } + if err := checkFork(d.L2GenesisEcotoneTimeOffset, d.L2GenesisFjordTimeOffset, "ecotone", "fjord"); err != nil { + return err + } return nil } @@ -388,95 +480,74 @@ func (d *DeployConfig) SetDeployments(deployments *L1Deployments) { d.L1ERC721BridgeProxy = deployments.L1ERC721BridgeProxy d.SystemConfigProxy = deployments.SystemConfigProxy d.OptimismPortalProxy = deployments.OptimismPortalProxy + d.DAChallengeProxy = deployments.DataAvailabilityChallengeProxy } -// GetDeployedAddresses will get the deployed addresses of deployed L1 contracts -// required for the L2 genesis creation. Legacy systems use the `Proxy__` prefix -// while modern systems use the `Proxy` suffix. First check for the legacy -// deployments so that this works with upgrading a system. -func (d *DeployConfig) GetDeployedAddresses(hh *hardhat.Hardhat) error { - var err error +func (d *DeployConfig) GovernanceEnabled() bool { + return d.EnableGovernance +} - if d.L1StandardBridgeProxy == (common.Address{}) { - var l1StandardBridgeProxyDeployment *hardhat.Deployment - l1StandardBridgeProxyDeployment, err = hh.GetDeployment("Proxy__OVM_L1StandardBridge") - if errors.Is(err, hardhat.ErrCannotFindDeployment) { - l1StandardBridgeProxyDeployment, err = hh.GetDeployment("L1StandardBridgeProxy") - if err != nil { - return err - } - } - d.L1StandardBridgeProxy = l1StandardBridgeProxyDeployment.Address +func (d *DeployConfig) RegolithTime(genesisTime uint64) *uint64 { + if d.L2GenesisRegolithTimeOffset == nil { + return nil } - - if d.L1CrossDomainMessengerProxy == (common.Address{}) { - var l1CrossDomainMessengerProxyDeployment *hardhat.Deployment - l1CrossDomainMessengerProxyDeployment, err = hh.GetDeployment("Proxy__OVM_L1CrossDomainMessenger") - if errors.Is(err, hardhat.ErrCannotFindDeployment) { - l1CrossDomainMessengerProxyDeployment, err = hh.GetDeployment("L1CrossDomainMessengerProxy") - if err != nil { - return err - } - } - d.L1CrossDomainMessengerProxy = l1CrossDomainMessengerProxyDeployment.Address + v := uint64(0) + if offset := *d.L2GenesisRegolithTimeOffset; offset > 0 { + v = genesisTime + uint64(offset) } + return &v +} - if d.L1ERC721BridgeProxy == (common.Address{}) { - // There is no legacy deployment of this contract - l1ERC721BridgeProxyDeployment, err := hh.GetDeployment("L1ERC721BridgeProxy") - if err != nil { - return err - } - d.L1ERC721BridgeProxy = l1ERC721BridgeProxyDeployment.Address +func (d *DeployConfig) CanyonTime(genesisTime uint64) *uint64 { + if d.L2GenesisCanyonTimeOffset == nil { + return nil } - - if d.SystemConfigProxy == (common.Address{}) { - systemConfigProxyDeployment, err := hh.GetDeployment("SystemConfigProxy") - if err != nil { - return err - } - d.SystemConfigProxy = systemConfigProxyDeployment.Address + v := uint64(0) + if offset := *d.L2GenesisCanyonTimeOffset; offset > 0 { + v = genesisTime + uint64(offset) } + return &v +} - if d.OptimismPortalProxy == (common.Address{}) { - optimismPortalProxyDeployment, err := hh.GetDeployment("OptimismPortalProxy") - if err != nil { - return err - } - d.OptimismPortalProxy = optimismPortalProxyDeployment.Address +func (d *DeployConfig) DeltaTime(genesisTime uint64) *uint64 { + if d.L2GenesisDeltaTimeOffset == nil { + return nil } - - return nil + v := uint64(0) + if offset := *d.L2GenesisDeltaTimeOffset; offset > 0 { + v = genesisTime + uint64(offset) + } + return &v } -func (d *DeployConfig) RegolithTime(genesisTime uint64) *uint64 { - if d.L2GenesisRegolithTimeOffset == nil { +func (d *DeployConfig) EcotoneTime(genesisTime uint64) *uint64 { + if d.L2GenesisEcotoneTimeOffset == nil { return nil } v := uint64(0) - if offset := *d.L2GenesisRegolithTimeOffset; offset > 0 { + if offset := *d.L2GenesisEcotoneTimeOffset; offset > 0 { v = genesisTime + uint64(offset) } return &v } -func (d *DeployConfig) CanyonTime(genesisTime uint64) *uint64 { - if d.L2GenesisCanyonTimeOffset == nil { +func (d *DeployConfig) FjordTime(genesisTime uint64) *uint64 { + if d.L2GenesisFjordTimeOffset == nil { return nil } v := uint64(0) - if offset := *d.L2GenesisCanyonTimeOffset; offset > 0 { + if offset := *d.L2GenesisFjordTimeOffset; offset > 0 { v = genesisTime + uint64(offset) } return &v } -func (d *DeployConfig) SpanBatchTime(genesisTime uint64) *uint64 { - if d.L2GenesisSpanBatchTimeOffset == nil { +func (d *DeployConfig) InteropTime(genesisTime uint64) *uint64 { + if d.L2GenesisInteropTimeOffset == nil { return nil } v := uint64(0) - if offset := *d.L2GenesisSpanBatchTimeOffset; offset > 0 { + if offset := *d.L2GenesisInteropTimeOffset; offset > 0 { v = genesisTime + uint64(offset) } return &v @@ -520,7 +591,14 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Block, l2GenesisBlockHas L1SystemConfigAddress: d.SystemConfigProxy, RegolithTime: d.RegolithTime(l1StartBlock.Time()), CanyonTime: d.CanyonTime(l1StartBlock.Time()), - SpanBatchTime: d.SpanBatchTime(l1StartBlock.Time()), + DeltaTime: d.DeltaTime(l1StartBlock.Time()), + EcotoneTime: d.EcotoneTime(l1StartBlock.Time()), + FjordTime: d.FjordTime(l1StartBlock.Time()), + InteropTime: d.InteropTime(l1StartBlock.Time()), + UsePlasma: d.UsePlasma, + DAChallengeAddress: d.DAChallengeProxy, + DAChallengeWindow: d.DAChallengeWindow, + DAResolveWindow: d.DAResolveWindow, Fermat: d.Fermat, }, nil } @@ -574,6 +652,8 @@ type L1Deployments struct { SystemConfigProxy common.Address `json:"SystemConfigProxy"` ProtocolVersions common.Address `json:"ProtocolVersions"` ProtocolVersionsProxy common.Address `json:"ProtocolVersionsProxy"` + DataAvailabilityChallenge common.Address `json:"DataAvailabilityChallenge"` + DataAvailabilityChallengeProxy common.Address `json:"DataAvailabilityChallengeProxy"` } // GetName will return the name of the contract given an address. @@ -591,7 +671,7 @@ func (d *L1Deployments) GetName(addr common.Address) string { } // Check will ensure that the L1Deployments are sane -func (d *L1Deployments) Check() error { +func (d *L1Deployments) Check(deployConfig *DeployConfig) error { val := reflect.ValueOf(d) if val.Kind() == reflect.Ptr { val = val.Elem() @@ -599,7 +679,14 @@ func (d *L1Deployments) Check() error { for i := 0; i < val.NumField(); i++ { name := val.Type().Field(i).Name // Skip the non production ready contracts - if name == "DisputeGameFactory" || name == "DisputeGameFactoryProxy" || name == "BlockOracle" { + if name == "DisputeGameFactory" || + name == "DisputeGameFactoryProxy" || + name == "BlockOracle" { + continue + } + if !deployConfig.UsePlasma && + (name == "DataAvailabilityChallenge" || + name == "DataAvailabilityChallengeProxy") { continue } if val.Field(i).Interface().(common.Address) == (common.Address{}) { @@ -644,7 +731,7 @@ func NewL1Deployments(path string) (*L1Deployments, error) { var deployments L1Deployments if err := json.Unmarshal(file, &deployments); err != nil { - return nil, fmt.Errorf("cannot unmarshal L1 deployements: %w", err) + return nil, fmt.Errorf("cannot unmarshal L1 deployments: %w", err) } return &deployments, nil @@ -657,72 +744,141 @@ func NewStateDump(path string) (*gstate.Dump, error) { return nil, fmt.Errorf("dump at %s not found: %w", path, err) } - var dump gstate.Dump - if err := json.Unmarshal(file, &dump); err != nil { + var fdump ForgeDump + if err := json.Unmarshal(file, &fdump); err != nil { return nil, fmt.Errorf("cannot unmarshal dump: %w", err) } + dump := (gstate.Dump)(fdump) return &dump, nil } +// ForgeDump is a simple alias for state.Dump that can read "nonce" as a hex string. +// It appears as if updates to foundry have changed the serialization of the state dump. +type ForgeDump gstate.Dump + +func (d *ForgeDump) UnmarshalJSON(b []byte) error { + type forgeDumpAccount struct { + Balance string `json:"balance"` + Nonce hexutil.Uint64 `json:"nonce"` + Root hexutil.Bytes `json:"root"` + CodeHash hexutil.Bytes `json:"codeHash"` + Code hexutil.Bytes `json:"code,omitempty"` + Storage map[common.Hash]string `json:"storage,omitempty"` + Address *common.Address `json:"address,omitempty"` + AddressHash hexutil.Bytes `json:"key,omitempty"` + } + type forgeDump struct { + Root string `json:"root"` + Accounts map[common.Address]forgeDumpAccount `json:"accounts"` + } + var dump forgeDump + if err := json.Unmarshal(b, &dump); err != nil { + return err + } + + d.Root = dump.Root + d.Accounts = make(map[string]gstate.DumpAccount) + for addr, acc := range dump.Accounts { + d.Accounts[addr.String()] = gstate.DumpAccount{ + Balance: acc.Balance, + Nonce: (uint64)(acc.Nonce), + Root: acc.Root, + CodeHash: acc.CodeHash, + Code: acc.Code, + Storage: acc.Storage, + Address: acc.Address, + AddressHash: acc.AddressHash, + } + } + return nil +} + // NewL2ImmutableConfig will create an ImmutableConfig given an instance of a // DeployConfig and a block. -func NewL2ImmutableConfig(config *DeployConfig, block *types.Block) (immutables.ImmutableConfig, error) { - immutable := make(immutables.ImmutableConfig) - +func NewL2ImmutableConfig(config *DeployConfig, block *types.Block) (*immutables.PredeploysImmutableConfig, error) { if config.L1StandardBridgeProxy == (common.Address{}) { - return immutable, fmt.Errorf("L1StandardBridgeProxy cannot be address(0): %w", ErrInvalidImmutablesConfig) + return nil, fmt.Errorf("L1StandardBridgeProxy cannot be address(0): %w", ErrInvalidImmutablesConfig) } if config.L1CrossDomainMessengerProxy == (common.Address{}) { - return immutable, fmt.Errorf("L1CrossDomainMessengerProxy cannot be address(0): %w", ErrInvalidImmutablesConfig) + return nil, fmt.Errorf("L1CrossDomainMessengerProxy cannot be address(0): %w", ErrInvalidImmutablesConfig) } if config.L1ERC721BridgeProxy == (common.Address{}) { - return immutable, fmt.Errorf("L1ERC721BridgeProxy cannot be address(0): %w", ErrInvalidImmutablesConfig) + return nil, fmt.Errorf("L1ERC721BridgeProxy cannot be address(0): %w", ErrInvalidImmutablesConfig) } if config.SequencerFeeVaultRecipient == (common.Address{}) { - return immutable, fmt.Errorf("SequencerFeeVaultRecipient cannot be address(0): %w", ErrInvalidImmutablesConfig) + return nil, fmt.Errorf("SequencerFeeVaultRecipient cannot be address(0): %w", ErrInvalidImmutablesConfig) } if config.BaseFeeVaultRecipient == (common.Address{}) { - return immutable, fmt.Errorf("BaseFeeVaultRecipient cannot be address(0): %w", ErrInvalidImmutablesConfig) + return nil, fmt.Errorf("BaseFeeVaultRecipient cannot be address(0): %w", ErrInvalidImmutablesConfig) } if config.L1FeeVaultRecipient == (common.Address{}) { - return immutable, fmt.Errorf("L1FeeVaultRecipient cannot be address(0): %w", ErrInvalidImmutablesConfig) + return nil, fmt.Errorf("L1FeeVaultRecipient cannot be address(0): %w", ErrInvalidImmutablesConfig) + } + + cfg := immutables.PredeploysImmutableConfig{ + L2ToL1MessagePasser: struct{}{}, + DeployerWhitelist: struct{}{}, + WETH9: struct{}{}, + L2CrossDomainMessenger: struct{}{}, + L2StandardBridge: struct{}{}, + SequencerFeeVault: struct { + Recipient common.Address + MinWithdrawalAmount *big.Int + WithdrawalNetwork uint8 + }{ + Recipient: config.SequencerFeeVaultRecipient, + MinWithdrawalAmount: (*big.Int)(config.SequencerFeeVaultMinimumWithdrawalAmount), + WithdrawalNetwork: config.SequencerFeeVaultWithdrawalNetwork.ToUint8(), + }, + L1BlockNumber: struct{}{}, + GasPriceOracle: struct{}{}, + L1Block: struct{}{}, + GovernanceToken: struct{}{}, + LegacyMessagePasser: struct{}{}, + L2ERC721Bridge: struct{}{}, + OptimismMintableERC721Factory: struct { + Bridge common.Address + RemoteChainId *big.Int + }{ + Bridge: predeploys.L2ERC721BridgeAddr, + RemoteChainId: new(big.Int).SetUint64(config.L1ChainID), + }, + OptimismMintableERC20Factory: struct{}{}, + ProxyAdmin: struct{}{}, + BaseFeeVault: struct { + Recipient common.Address + MinWithdrawalAmount *big.Int + WithdrawalNetwork uint8 + }{ + Recipient: config.BaseFeeVaultRecipient, + MinWithdrawalAmount: (*big.Int)(config.BaseFeeVaultMinimumWithdrawalAmount), + WithdrawalNetwork: config.BaseFeeVaultWithdrawalNetwork.ToUint8(), + }, + L1FeeVault: struct { + Recipient common.Address + MinWithdrawalAmount *big.Int + WithdrawalNetwork uint8 + }{ + Recipient: config.L1FeeVaultRecipient, + MinWithdrawalAmount: (*big.Int)(config.L1FeeVaultMinimumWithdrawalAmount), + WithdrawalNetwork: config.L1FeeVaultWithdrawalNetwork.ToUint8(), + }, + SchemaRegistry: struct{}{}, + EAS: struct { + Name string + }{ + Name: "EAS", + }, + Create2Deployer: struct{}{}, } - immutable["L2StandardBridge"] = immutables.ImmutableValues{ - "otherBridge": config.L1StandardBridgeProxy, - } - immutable["L2CrossDomainMessenger"] = immutables.ImmutableValues{ - "otherMessenger": config.L1CrossDomainMessengerProxy, - } - immutable["L2ERC721Bridge"] = immutables.ImmutableValues{ - "messenger": predeploys.L2CrossDomainMessengerAddr, - "otherBridge": config.L1ERC721BridgeProxy, - } - immutable["OptimismMintableERC721Factory"] = immutables.ImmutableValues{ - "bridge": predeploys.L2ERC721BridgeAddr, - "remoteChainId": new(big.Int).SetUint64(config.L1ChainID), - } - immutable["SequencerFeeVault"] = immutables.ImmutableValues{ - "recipient": config.SequencerFeeVaultRecipient, - "minimumWithdrawalAmount": config.SequencerFeeVaultMinimumWithdrawalAmount, - "withdrawalNetwork": config.SequencerFeeVaultWithdrawalNetwork.ToUint8(), + if err := cfg.Check(); err != nil { + return nil, err } - immutable["L1FeeVault"] = immutables.ImmutableValues{ - "recipient": config.L1FeeVaultRecipient, - "minimumWithdrawalAmount": config.L1FeeVaultMinimumWithdrawalAmount, - "withdrawalNetwork": config.L1FeeVaultWithdrawalNetwork.ToUint8(), - } - immutable["BaseFeeVault"] = immutables.ImmutableValues{ - "recipient": config.BaseFeeVaultRecipient, - "minimumWithdrawalAmount": config.BaseFeeVaultMinimumWithdrawalAmount, - "withdrawalNetwork": config.BaseFeeVaultWithdrawalNetwork.ToUint8(), - } - - return immutable, nil + return &cfg, nil } -// NewL2StorageConfig will create a StorageConfig given an instance of a -// Hardhat and a DeployConfig. +// NewL2StorageConfig will create a StorageConfig given an instance of a DeployConfig and genesis block. func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.StorageConfig, error) { storage := make(state.StorageConfig) @@ -746,16 +902,29 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage "msgNonce": 0, } storage["L2CrossDomainMessenger"] = state.StorageValues{ - "_initialized": initializedValue, + "_initialized": 1, "_initializing": false, "xDomainMsgSender": "0x000000000000000000000000000000000000dEaD", "msgNonce": 0, + "otherMessenger": config.L1CrossDomainMessengerProxy, } storage["L2StandardBridge"] = state.StorageValues{ - "_initialized": initializedValue, + "_initialized": 1, + "_initializing": false, + "otherBridge": config.L1StandardBridgeProxy, + "messenger": predeploys.L2CrossDomainMessengerAddr, + } + storage["L2ERC721Bridge"] = state.StorageValues{ + "_initialized": 1, "_initializing": false, + "otherBridge": config.L1ERC721BridgeProxy, "messenger": predeploys.L2CrossDomainMessengerAddr, } + storage["OptimismMintableERC20Factory"] = state.StorageValues{ + "_initialized": 1, + "_initializing": false, + "bridge": predeploys.L2StandardBridgeAddr, + } storage["L1Block"] = state.StorageValues{ "number": block.Number(), "timestamp": block.Time(), @@ -785,16 +954,6 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage storage["ProxyAdmin"] = state.StorageValues{ "_owner": config.ProxyAdminOwner, } - storage["L2ERC721Bridge"] = state.StorageValues{ - "messenger": predeploys.L2CrossDomainMessengerAddr, - "_initialized": initializedValue, - "_initializing": false, - } - storage["OptimismMintableERC20Factory"] = state.StorageValues{ - "bridge": predeploys.L2StandardBridgeAddr, - "_initialized": initializedValue, - "_initializing": false, - } return storage, nil } diff --git a/op-chain-ops/genesis/genesis.go b/op-chain-ops/genesis/genesis.go index 15ba0edc313f..917c12b40fd8 100644 --- a/op-chain-ops/genesis/genesis.go +++ b/op-chain-ops/genesis/genesis.go @@ -64,6 +64,9 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro RegolithTime: config.RegolithTime(block.Time()), CanyonTime: config.CanyonTime(block.Time()), ShanghaiTime: config.CanyonTime(block.Time()), + CancunTime: config.EcotoneTime(block.Time()), + EcotoneTime: config.EcotoneTime(block.Time()), + InteropTime: config.InteropTime(block.Time()), Fermat: config.Fermat, Optimism: ¶ms.OptimismConfig{ EIP1559Denominator: eip1559Denom, @@ -95,7 +98,7 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro return nil, fmt.Errorf("transition block extradata too long: %d", size) } - return &core.Genesis{ + genesis := &core.Genesis{ Config: &optimismChainConfig, Nonce: uint64(config.L2GenesisBlockNonce), Timestamp: block.Time(), @@ -109,7 +112,14 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro ParentHash: config.L2GenesisBlockParentHash, BaseFee: baseFee.ToInt(), Alloc: map[common.Address]core.GenesisAccount{}, - }, nil + } + + if optimismChainConfig.IsEcotone(genesis.Timestamp) { + genesis.BlobGasUsed = u64ptr(0) + genesis.ExcessBlobGas = u64ptr(0) + } + + return genesis, nil } // NewL1Genesis will create a new L1 genesis config @@ -135,6 +145,8 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) { LondonBlock: big.NewInt(0), ArrowGlacierBlock: big.NewInt(0), GrayGlacierBlock: big.NewInt(0), + ShanghaiTime: nil, + CancunTime: nil, } extraData := make([]byte, 0) @@ -151,6 +163,7 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) { chainConfig.TerminalTotalDifficulty = big.NewInt(0) chainConfig.TerminalTotalDifficultyPassed = true chainConfig.ShanghaiTime = u64ptr(0) + chainConfig.CancunTime = u64ptr(0) } gasLimit := config.L1GenesisBlockGasLimit @@ -169,6 +182,10 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) { if timestamp == 0 { timestamp = hexutil.Uint64(time.Now().Unix()) } + if !config.L1UseClique && config.L1CancunTimeOffset != nil { + cancunTime := uint64(timestamp) + uint64(*config.L1CancunTimeOffset) + chainConfig.CancunTime = &cancunTime + } return &core.Genesis{ Config: &chainConfig, diff --git a/op-chain-ops/genesis/helpers.go b/op-chain-ops/genesis/helpers.go index ab577e9f8ebe..475b597cccb3 100644 --- a/op-chain-ops/genesis/helpers.go +++ b/op-chain-ops/genesis/helpers.go @@ -18,13 +18,13 @@ var ( codeNamespace = common.HexToAddress("0xc0D3C0d3C0d3C0D3c0d3C0d3c0D3C0d3c0d30000") // l2PredeployNamespace represents the namespace of L2 predeploys l2PredeployNamespace = common.HexToAddress("0x4200000000000000000000000000000000000000") - // bigL2PredeployNamespace represents the predeploy namespace as a big.Int + // BigL2PredeployNamespace represents the predeploy namespace as a big.Int BigL2PredeployNamespace = new(big.Int).SetBytes(l2PredeployNamespace.Bytes()) // bigCodeNamespace represents the predeploy namespace as a big.Int - bigCodeNameSpace = new(big.Int).SetBytes(codeNamespace.Bytes()) - // implementationSlot represents the EIP 1967 implementation storage slot + bigCodeNamespace = new(big.Int).SetBytes(codeNamespace.Bytes()) + // ImplementationSlot represents the EIP 1967 implementation storage slot ImplementationSlot = common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc") - // implementationSlot represents the EIP 1967 admin storage slot + // AdminSlot represents the EIP 1967 admin storage slot AdminSlot = common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103") ) @@ -69,7 +69,7 @@ func AddressToCodeNamespace(addr common.Address) (common.Address, error) { return common.Address{}, fmt.Errorf("cannot handle non predeploy: %s", addr) } bigAddress := new(big.Int).SetBytes(addr[18:]) - num := new(big.Int).Or(bigCodeNameSpace, bigAddress) + num := new(big.Int).Or(bigCodeNamespace, bigAddress) return common.BigToAddress(num), nil } diff --git a/op-chain-ops/genesis/layer_one.go b/op-chain-ops/genesis/layer_one.go index 40d1c96f9014..f697fdbc0a4d 100644 --- a/op-chain-ops/genesis/layer_one.go +++ b/op-chain-ops/genesis/layer_one.go @@ -1,7 +1,6 @@ package genesis import ( - "errors" "fmt" "math/big" @@ -9,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core" gstate "github.com/ethereum/go-ethereum/core/state" @@ -44,7 +44,7 @@ func init() { // all of the state required for an Optimism network to function. // It is expected that the dump contains all of the required state to bootstrap // the L1 chain. -func BuildL1DeveloperGenesis(config *DeployConfig, dump *gstate.Dump, l1Deployments *L1Deployments, postProcess bool) (*core.Genesis, error) { +func BuildL1DeveloperGenesis(config *DeployConfig, dump *gstate.Dump, l1Deployments *L1Deployments) (*core.Genesis, error) { log.Info("Building developer L1 genesis block") genesis, err := NewL1Genesis(config) if err != nil { @@ -56,7 +56,16 @@ func BuildL1DeveloperGenesis(config *DeployConfig, dump *gstate.Dump, l1Deployme SetPrecompileBalances(memDB) if dump != nil { - for address, account := range dump.Accounts { + for addrstr, account := range dump.Accounts { + if !common.IsHexAddress(addrstr) { + // Changes in https://github.com/ethereum/go-ethereum/pull/28504 + // add accounts to the Dump with "pre()" as key + // if the address itself is nil. + // So depending on how `dump` was created, this might be a + // pre-image key, which we skip. + continue + } + address := common.HexToAddress(addrstr) name := "" if l1Deployments != nil { if n := l1Deployments.GetName(address); n != "" { @@ -67,7 +76,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig, dump *gstate.Dump, l1Deployme memDB.CreateAccount(address) memDB.SetNonce(address, account.Nonce) - balance, ok := new(big.Int).SetString(account.Balance, 10) + balance, ok := math.ParseBig256(account.Balance) if !ok { return nil, fmt.Errorf("failed to parse balance for %s", address) } @@ -78,49 +87,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig, dump *gstate.Dump, l1Deployme memDB.SetState(address, key, common.HexToHash(value)) } } - - // This should only be used if we are expecting Optimism specific state to be set - if postProcess { - if err := PostProcessL1DeveloperGenesis(memDB, l1Deployments); err != nil { - return nil, fmt.Errorf("failed to post process L1 developer genesis: %w", err) - } - } } return memDB.Genesis(), nil } - -// PostProcessL1DeveloperGenesis will apply post processing to the L1 genesis -// state. This is required to handle edge cases in the genesis generation. -// `block.number` is used during deployment and without specifically setting -// the value to 0, it will cause underflow reverts for deposits in testing. -func PostProcessL1DeveloperGenesis(stateDB *state.MemoryStateDB, deployments *L1Deployments) error { - log.Info("Post processing state") - - if stateDB == nil { - return errors.New("cannot post process nil stateDB") - } - if deployments == nil { - return errors.New("cannot post process dump with nil deployments") - } - - if !stateDB.Exist(deployments.OptimismPortalProxy) { - return fmt.Errorf("portal proxy doesn't exist at %s", deployments.OptimismPortalProxy) - } - - layout, err := bindings.GetStorageLayout("OptimismPortal") - if err != nil { - return errors.New("failed to get storage layout for OptimismPortal") - } - - entry, err := layout.GetStorageLayoutEntry("params") - if err != nil { - return errors.New("failed to get storage layout entry for OptimismPortal.params") - } - slot := common.BigToHash(big.NewInt(int64(entry.Slot))) - - stateDB.SetState(deployments.OptimismPortalProxy, slot, common.Hash{}) - log.Info("Post process update", "address", deployments.OptimismPortalProxy, "slot", slot.Hex(), "value", common.Hash{}.Hex()) - - return nil -} diff --git a/op-chain-ops/genesis/layer_one_test.go b/op-chain-ops/genesis/layer_one_test.go index be328632f9da..ba8a8f0c0fa1 100644 --- a/op-chain-ops/genesis/layer_one_test.go +++ b/op-chain-ops/genesis/layer_one_test.go @@ -43,7 +43,7 @@ func TestBuildL1DeveloperGenesis(t *testing.T) { deployments, err := NewL1Deployments("testdata/deploy.json") require.NoError(t, err) - genesis, err := BuildL1DeveloperGenesis(config, dump, nil, false) + genesis, err := BuildL1DeveloperGenesis(config, dump, nil) require.NoError(t, err) sim := backends.NewSimulatedBackend( diff --git a/op-chain-ops/genesis/layer_two.go b/op-chain-ops/genesis/layer_two.go index a728d30132ef..3b2bf85e1a3b 100644 --- a/op-chain-ops/genesis/layer_two.go +++ b/op-chain-ops/genesis/layer_two.go @@ -2,18 +2,24 @@ package genesis import ( "fmt" + "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" "github.com/ethereum-optimism/optimism/op-chain-ops/immutables" + "github.com/ethereum-optimism/optimism/op-chain-ops/squash" "github.com/ethereum-optimism/optimism/op-chain-ops/state" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" ) -// BuildL2DeveloperGenesis will build the L2 genesis block. +// BuildL2Genesis will build the L2 genesis block. func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Genesis, error) { genspec, err := NewL2Genesis(config, l1StartBlock) if err != nil { @@ -33,7 +39,7 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene return nil, err } - immutable, err := NewL2ImmutableConfig(config, l1StartBlock) + immutableConfig, err := NewL2ImmutableConfig(config, l1StartBlock) if err != nil { return nil, err } @@ -44,31 +50,62 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene return nil, err } - // Set up the implementations - deployResults, err := immutables.BuildOptimism(immutable) + // Set up the implementations that contain immutables + deployResults, err := immutables.Deploy(immutableConfig) if err != nil { return nil, err } for name, predeploy := range predeploys.Predeploys { - addr := *predeploy - if addr == predeploys.GovernanceTokenAddr && !config.EnableGovernance { - // there is no governance token configured, so skip the governance token predeploy - log.Warn("Governance is not enabled, skipping governance token predeploy.") + if predeploy.Enabled != nil && !predeploy.Enabled(config) { + log.Warn("Skipping disabled predeploy.", "name", name, "address", predeploy.Address) continue } - codeAddr := addr - if predeploys.IsProxied(addr) { - codeAddr, err = AddressToCodeNamespace(addr) + + codeAddr := predeploy.Address + switch name { + case "Permit2": + deployerAddressBytes, err := bindings.GetDeployerAddress(name) if err != nil { - return nil, fmt.Errorf("error converting to code namespace: %w", err) + return nil, err + } + deployerAddress := common.BytesToAddress(deployerAddressBytes) + predeploys := map[string]*common.Address{ + "DeterministicDeploymentProxy": &deployerAddress, } + backend, err := deployer.NewL2BackendWithChainIDAndPredeploys( + new(big.Int).SetUint64(config.L2ChainID), + predeploys, + ) + if err != nil { + return nil, err + } + deployedBin, err := deployer.DeployWithDeterministicDeployer(backend, name) + if err != nil { + return nil, err + } + deployResults[name] = deployedBin + fallthrough + case "MultiCall3", "Create2Deployer", "Safe_v130", + "SafeL2_v130", "MultiSendCallOnly_v130", "SafeSingletonFactory", + "DeterministicDeploymentProxy", "MultiSend_v130", "SenderCreator", "EntryPoint": db.CreateAccount(codeAddr) - db.SetState(addr, ImplementationSlot, eth.AddressAsLeftPaddedHash(codeAddr)) - log.Info("Set proxy", "name", name, "address", addr, "implementation", codeAddr) - } else { - db.DeleteState(addr, AdminSlot) + default: + if !predeploy.ProxyDisabled { + codeAddr, err = AddressToCodeNamespace(predeploy.Address) + if err != nil { + return nil, fmt.Errorf("error converting to code namespace: %w", err) + } + db.CreateAccount(codeAddr) + db.SetState(predeploy.Address, ImplementationSlot, eth.AddressAsLeftPaddedHash(codeAddr)) + log.Info("Set proxy", "name", name, "address", predeploy.Address, "implementation", codeAddr) + } + } + + if predeploy.ProxyDisabled && db.Exist(predeploy.Address) { + db.DeleteState(predeploy.Address, AdminSlot) } - if err := setupPredeploy(db, deployResults, storage, name, addr, codeAddr); err != nil { + + if err := setupPredeploy(db, deployResults, storage, name, predeploy.Address, codeAddr); err != nil { return nil, err } code := db.GetCode(codeAddr) @@ -77,5 +114,25 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene } } + if err := PerformUpgradeTxs(db); err != nil { + return nil, fmt.Errorf("failed to perform upgrade txs: %w", err) + } + return db.Genesis(), nil } + +func PerformUpgradeTxs(db *state.MemoryStateDB) error { + // Only the Ecotone upgrade is performed with upgrade-txs. + if !db.Genesis().Config.IsEcotone(db.Genesis().Timestamp) { + return nil + } + sim := squash.NewSimulator(db) + ecotone, err := derive.EcotoneNetworkUpgradeTransactions() + if err != nil { + return fmt.Errorf("failed to build ecotone upgrade txs: %w", err) + } + if err := sim.AddUpgradeTxs(ecotone); err != nil { + return fmt.Errorf("failed to apply ecotone upgrade txs: %w", err) + } + return nil +} diff --git a/op-chain-ops/genesis/layer_two_test.go b/op-chain-ops/genesis/layer_two_test.go index f941a982fddc..2dcf835d3126 100644 --- a/op-chain-ops/genesis/layer_two_test.go +++ b/op-chain-ops/genesis/layer_two_test.go @@ -48,14 +48,14 @@ func testBuildL2Genesis(t *testing.T, config *genesis.DeployConfig) *core.Genesi require.NoError(t, err) for name, predeploy := range predeploys.Predeploys { - addr := *predeploy + addr := predeploy.Address account, ok := gen.Alloc[addr] require.Equal(t, true, ok, name) require.Greater(t, len(account.Code), 0) adminSlot, ok := account.Storage[genesis.AdminSlot] - isProxy := predeploys.IsProxied(addr) || + isProxy := !predeploy.ProxyDisabled || (!config.EnableGovernance && addr == predeploys.GovernanceTokenAddr) if isProxy { require.Equal(t, true, ok, name) @@ -73,6 +73,10 @@ func testBuildL2Genesis(t *testing.T, config *genesis.DeployConfig) *core.Genesi require.Equal(t, common.Big1, gen.Alloc[addr].Balance) } + create2Deployer := gen.Alloc[predeploys.Create2DeployerAddr] + codeHash := crypto.Keccak256Hash(create2Deployer.Code) + require.Equal(t, codeHash, bindings.Create2DeployerCodeHash) + if writeFile { file, _ := json.MarshalIndent(gen, "", " ") _ = os.WriteFile("genesis.json", file, 0644) @@ -86,7 +90,7 @@ func TestBuildL2MainnetGenesis(t *testing.T) { config.EnableGovernance = true config.FundDevAccounts = false gen := testBuildL2Genesis(t, config) - require.Equal(t, 2322, len(gen.Alloc)) + require.Equal(t, 2333, len(gen.Alloc)) } func TestBuildL2MainnetNoGovernanceGenesis(t *testing.T) { @@ -95,5 +99,5 @@ func TestBuildL2MainnetNoGovernanceGenesis(t *testing.T) { config.EnableGovernance = false config.FundDevAccounts = false gen := testBuildL2Genesis(t, config) - require.Equal(t, 2322, len(gen.Alloc)) + require.Equal(t, 2333, len(gen.Alloc)) } diff --git a/op-chain-ops/genesis/setters.go b/op-chain-ops/genesis/setters.go index 7f7172a55cd8..5b17a2bbbb9a 100644 --- a/op-chain-ops/genesis/setters.go +++ b/op-chain-ops/genesis/setters.go @@ -55,8 +55,7 @@ func setProxies(db vm.StateDB, proxyAdminAddr common.Address, namespace *big.Int } // SetPrecompileBalances will set a single wei at each precompile address. -// This is an optimization to make calling them cheaper. This should only -// be used for devnets. +// This is an optimization to make calling them cheaper. func SetPrecompileBalances(db vm.StateDB) { for i := 0; i < PrecompileCount; i++ { addr := common.BytesToAddress([]byte{byte(i)}) diff --git a/op-chain-ops/genesis/testdata/allocs-l1.json b/op-chain-ops/genesis/testdata/allocs-l1.json index 5581316987c6..b103f8a387f1 100644 --- a/op-chain-ops/genesis/testdata/allocs-l1.json +++ b/op-chain-ops/genesis/testdata/allocs-l1.json @@ -2,63 +2,63 @@ "root": "c09d26bbbfff36314c8d562387f54768cc0d82b1ad5d2f8544c45e9a1b73cd82", "accounts": { "0x0000000000000000000000000000000000000001": { - "balance": "1", + "balance": "0x1", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "key": "0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d" }, "0x0000000000000000000000000000000000000002": { - "balance": "1", + "balance": "0x1", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "key": "0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62" }, "0x0000000000000000000000000000000000000003": { - "balance": "1", + "balance": "0x1", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "key": "0x5b70e80538acdabd6137353b0f9d8d149f4dba91e8be2e7946e409bfdbe685b9" }, "0x0000000000000000000000000000000000000004": { - "balance": "1", + "balance": "0x1", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "key": "0xa876da518a393dbd067dc72abfa08d475ed6447fca96d92ec3f9e7eba503ca61" }, "0x0000000000000000000000000000000000000005": { - "balance": "1", + "balance": "0x1", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "key": "0x421df1fa259221d02aa4956eb0d35ace318ca24c0a33a64c1af96cf67cf245b6" }, "0x0000000000000000000000000000000000000006": { - "balance": "1", + "balance": "0x1", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "key": "0x689802d6ed1a28b049e9d4fe5334c5902fd9bc00c42821c82f82ee2da10be908" }, "0x0000000000000000000000000000000000000007": { - "balance": "1", + "balance": "0x1", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "key": "0x8c3ab0970b73895b8c9959bae685c3a19f45eb5ad89d42b52a340ec4ac204d19" }, "0x0000000000000000000000000000000000000008": { - "balance": "1", + "balance": "0x1", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "key": "0x471703c5eda8644a64cec152c58f5aacec93d72fb0bfa705f0473f9043a8357c" }, "0x0000000000000000000000000000000000000009": { - "balance": "1", + "balance": "0x1", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", @@ -72,7 +72,7 @@ "key": "0x5e0651590c81426aa5f87b57e050b06ca0e3d1c7506a54ace1e923c08eda1d62" }, "0x36f4e85652236f9edaeba78bbe9d8c2b55ac5809": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0xaab9666c577be40942a2a1b7db7f1ef1e1a208ea6b7e33c906221efb78cc11c5", "codeHash": "0xaebd68b2a785d0af4b7e1f3e600efde438efa83b08f2ad8bcd9287322f396e5f", @@ -87,7 +87,7 @@ "key": "0xc5cde3f9919e46021264f96610e62970e8aa910e6457059ce4bfb1c48b16b59a" }, "0x4562938d6831437f37dd1bf5bbb7fe7a5f080eac": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x3e8b25f39fd713daed2a41f440a2ffecf3e7a153bd7a230d053f36740f656433", "codeHash": "0x3f41be62f844a58153179eed8f6e351351a8a0b293f01383671e7ec136b3e40e", @@ -99,7 +99,7 @@ "key": "0xf16b24c51b2548da7804641166342e8b8662bebf66987ef3eb12dd7950821b74" }, "0x48204903b06a64e3c44b0260f875497ea5316a02": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x408e9cd8a46cccdf81d7735aa9c93b5a97608fcc38000c6c8311e6d614c9cfc6", "codeHash": "0x1f958654ab06a152993e7a0ae7b6dbb0d4b19265cc9337b8789fe1353bd9dc35", @@ -112,7 +112,7 @@ "key": "0x2c94e39eab7e93ae2c81f6d3b7d4b3d6a6ffeb09b6493d7bb1642b2d00c2cf60" }, "0x6fb1869d7141c97cf28668fa0a338bdc892f53c0": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x4c966b8eb461b1db77f4842a16a91b766d03a7f2699edfa8f25d23028b511260", "codeHash": "0xc7b46fc754979c0fd29ec7105b045a5705d172da4364b24a72e42e586906056f", @@ -124,7 +124,7 @@ "key": "0xe1a3b9b8f8403a487cd74384f01166a39e6b0740fb9cf546795fa82c12e0a716" }, "0x73317009f4fadafcda357f3a082c7b68f5f8732f": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0xdc2d8e78c5f46669754c0498c50471e7944dd5787b3acdbcb53858469ad4e1d3", "codeHash": "0x1f958654ab06a152993e7a0ae7b6dbb0d4b19265cc9337b8789fe1353bd9dc35", @@ -144,7 +144,7 @@ "key": "0xfbb20b1dbf403bf022cfca8b23242ebe79dc06744e9d5233cb6db43454746315" }, "0x7aeb97910d4070426c00e820de4137d6d2adf0ad": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x5577b03f1a10efe1b976be229362e61ffc19859e866c7ca0d9e4887bc87b0800", "codeHash": "0x23ff3128727914b22a2753aafff02d897826166b869a027a11b851863d379ddf", @@ -156,7 +156,7 @@ "key": "0xd0a446c0ce66b5c711436c39fbeae531a05e9d698f32ddc8cd48d17fbe95feb0" }, "0x7ec3b539c97c98d503fb4fee3dd4ee885dc192cd": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0x0d625098e698c6d3b38ed38c3f00ea28361dc94fbf0e6cfd4c1ebc121cd9daac", @@ -164,7 +164,7 @@ "key": "0xd409335fac8e9e86a7a66c3720b403889062892385e5f09b7af7c5bee4f326fd" }, "0x7f325df611b236ee3ef469da4a74f776c787d1b3": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x821e2556a290c86405f8160a2d662042a431ba456b9db265c79bb837c04be5f0", "codeHash": "0x8e91bdb75050d4b44b5fc5c557c6f3455bfc4b76686fd72d9087b51a3200aecf", @@ -175,7 +175,7 @@ "key": "0x7a0724a3db73dfc6e99d843345c7746c79a0f615a36e22824ad91209feb9cf81" }, "0x87658463f96977fc95a068f1a206d2c0cf2db575": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0x3bb571c9d6063b9c50dcf6f602d428dfd633dca39aba9ec607d4ce0505a362d5", @@ -183,7 +183,7 @@ "key": "0xbd5530d2a017fd01a7edb9efa8656fd9c2d34523524628fdfd649f3222cec07c" }, "0x9a7ecb1c67f88396d252725f3259e9d8027f1562": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0x8b9df5a9eb6bb3280671bbc79f735d9d7009f8c0590c5cd0bc75a8e928068606", @@ -191,7 +191,7 @@ "key": "0x26ac7e215c5b48eb9f6162a5e7022d185b54b55d6d706b30e2777e9c6e06d565" }, "0xa051f227da1f5f1eecbfcdcd7316ce299a233760": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x4bed30661c4ccc61a7009910d1386ad6903216e2275b55589afb851dcb70c294", "codeHash": "0x1f958654ab06a152993e7a0ae7b6dbb0d4b19265cc9337b8789fe1353bd9dc35", @@ -203,7 +203,7 @@ "key": "0xd8522a36052aeae781dd8c38910969dc4f51b91541455ac64a0936b69d848e6e" }, "0xa88b2060478401a52532814edde6819d101802e2": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x68f4106f36ca6cb79380dcf1851f76be5dca9c34a9223a82032ccbba38eeb51a", "codeHash": "0x06643e7d44538ba353995b6b77634e1c5bd1282ae7902f2b1aceaec97cf572ed", @@ -217,7 +217,7 @@ "key": "0xdc2621e436cbec9ae124870f5ab25b65494a5accb952b75a94fda87636f6cd14" }, "0xb8d5d0fa6e413b5de72c38a0a187731171b4f341": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x0ad3da5fea1ef359038ec861ffa336c2364bc170d36b136f0e8535f6cd29e283", "codeHash": "0x3921774d36fd85d9e41c25a60635dfe0f0e5d2162afb93292db8bb80c81ece78", @@ -231,7 +231,7 @@ "key": "0x212f20473e051f38a3e883e04c615db86c000c11b7afcc5d9736f30c2a634a78" }, "0xcf1a8a7f273da1bd3112750cc3691b46c541e8b7": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0xa67b52462cb55b02cdc3b77317c72ba356565052daa741c56db173834086bf29", "codeHash": "0x1f958654ab06a152993e7a0ae7b6dbb0d4b19265cc9337b8789fe1353bd9dc35", @@ -246,7 +246,7 @@ "key": "0x81f151b659eee15d57be7e42c54519f089683a2663c2d73e920317ec91831100" }, "0xd16dba9f860146f08c9ee83b891c138667021ec9": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0xd71f41c241891e04095a92d2faafea7012de6d509ce9b855c4aad8523d3abe94", "codeHash": "0x1f958654ab06a152993e7a0ae7b6dbb0d4b19265cc9337b8789fe1353bd9dc35", @@ -258,7 +258,7 @@ "key": "0x3c75634c38fdffac6bd90c0b6feb19aef829f6f952f8331c21b7694d21c185de" }, "0xec466e9a46914507c484dcc5caba1db787e34913": { - "balance": "0", + "balance": "0x0", "nonce": 1, "root": "0x82c7f6f047f8e47468199468dab7c7bff9e01ed86ddf466e930363f12781776e", "codeHash": "0x30dd4c41053621e6ecb9d600526b682dcce4370e8c206f016e2ad0ff4ea6b6c8", @@ -276,4 +276,4 @@ "key": "0xb4791e53424376e737591737af96068778ec34c34df6df5bb044678dee3a2887" } } -} \ No newline at end of file +} diff --git a/op-chain-ops/genesis/testdata/test-deploy-config-devnet-l1.json b/op-chain-ops/genesis/testdata/test-deploy-config-devnet-l1.json index 063306869d24..b1a11aee2948 100644 --- a/op-chain-ops/genesis/testdata/test-deploy-config-devnet-l1.json +++ b/op-chain-ops/genesis/testdata/test-deploy-config-devnet-l1.json @@ -41,5 +41,8 @@ "enableGovernance": true, "governanceTokenSymbol": "OP", "governanceTokenName": "Optimism", - "governanceTokenOwner": "0x0000000000000000000000000000000000000333" + "governanceTokenOwner": "0x0000000000000000000000000000000000000333", + + "l2GenesisRegolithTimeOffset": "0x0", + "l2GenesisCanyonTimeOffset": "0x0" } diff --git a/op-chain-ops/genesis/testdata/test-deploy-config-full.json b/op-chain-ops/genesis/testdata/test-deploy-config-full.json index d2f7b980ddae..65390c661acc 100644 --- a/op-chain-ops/genesis/testdata/test-deploy-config-full.json +++ b/op-chain-ops/genesis/testdata/test-deploy-config-full.json @@ -21,7 +21,7 @@ "l1GenesisBlockGasLimit": "0x1c9c380", "l1GenesisBlockDifficulty": "0x1", "finalSystemOwner": "0xbcd4042de499d14e55001ccbb24a551f3b954096", - "portalGuardian": "0x0000000000000000000000000000000000000112", + "superchainConfigGuardian": "0x0000000000000000000000000000000000000112", "finalizationPeriodSeconds": 2, "l1GenesisBlockMixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "l1GenesisBlockCoinbase": "0x0000000000000000000000000000000000000000", @@ -68,7 +68,23 @@ "faultGameAbsolutePrestate": "0x0000000000000000000000000000000000000000000000000000000000000000", "faultGameMaxDepth": 63, "faultGameMaxDuration": 604800, + "faultGameGenesisBlock": 0, + "faultGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameSplitDepth": 0, + "faultGameWithdrawalDelay": 604800, + "preimageOracleMinProposalSize": 1800000, + "preimageOracleChallengePeriod": 86400, "systemConfigStartBlock": 0, "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", - "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "proofMaturityDelaySeconds": 12, + "disputeGameFinalityDelaySeconds": 6, + "respectedGameType": 0, + "useFaultProofs": false, + "usePlasma": false, + "daBondSize": 0, + "daChallengeProxy": "0x0000000000000000000000000000000000000000", + "daChallengeWindow": 0, + "daResolveWindow": 0, + "daResolverRefundPercentage": 0 } diff --git a/op-chain-ops/immutables/immutables.go b/op-chain-ops/immutables/immutables.go index c72afb8babce..ac945b77a337 100644 --- a/op-chain-ops/immutables/immutables.go +++ b/op-chain-ops/immutables/immutables.go @@ -1,60 +1,115 @@ package immutables import ( - "errors" "fmt" "math/big" + "reflect" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-bindings/predeploys" - "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" ) -// ImmutableValues represents the values to be set in immutable code. -// The key is the name of the variable and the value is the value to set in -// immutable code. -type ImmutableValues map[string]any +// PredeploysImmutableConfig represents the set of L2 predeploys. It includes all +// L2 predeploys - not just ones with immutable values. This is to be very explicit +// about the configuration of the predeploys. It is important that the inner struct +// fields are in the same order as the constructor arguments in the solidity code. +type PredeploysImmutableConfig struct { + L2ToL1MessagePasser struct{} + DeployerWhitelist struct{} + WETH9 struct{} + L2CrossDomainMessenger struct{} + L2StandardBridge struct{} + SequencerFeeVault struct { + Recipient common.Address + MinWithdrawalAmount *big.Int + WithdrawalNetwork uint8 + } + OptimismMintableERC20Factory struct{} + L1BlockNumber struct{} + GasPriceOracle struct{} + L1Block struct{} + GovernanceToken struct{} + LegacyMessagePasser struct{} + L2ERC721Bridge struct{} + OptimismMintableERC721Factory struct { + Bridge common.Address + RemoteChainId *big.Int + } + ProxyAdmin struct{} + BaseFeeVault struct { + Recipient common.Address + MinWithdrawalAmount *big.Int + WithdrawalNetwork uint8 + } + L1FeeVault struct { + Recipient common.Address + MinWithdrawalAmount *big.Int + WithdrawalNetwork uint8 + } + SchemaRegistry struct{} + EAS struct { + Name string + } + Create2Deployer struct{} + MultiCall3 struct{} + Safe_v130 struct{} + SafeL2_v130 struct{} + MultiSendCallOnly_v130 struct{} + SafeSingletonFactory struct{} + DeterministicDeploymentProxy struct{} + MultiSend_v130 struct{} + Permit2 struct{} + SenderCreator struct{} + EntryPoint struct{} +} -// ImmutableConfig represents the immutable configuration for the L2 predeploy -// contracts. -type ImmutableConfig map[string]ImmutableValues +// Check will ensure that the required fields are set on the config. +// An error returned by `GetImmutableReferences` means that the solc compiler +// output for the contract has no immutables in it. +func (c *PredeploysImmutableConfig) Check() error { + return c.ForEach(func(name string, values any) error { + val := reflect.ValueOf(values) + if val.NumField() == 0 { + return nil + } -// Check does a sanity check that the specific values that -// Optimism uses are set inside of the ImmutableConfig. -func (i ImmutableConfig) Check() error { - if _, ok := i["L2CrossDomainMessenger"]["otherMessenger"]; !ok { - return errors.New("L2CrossDomainMessenger otherMessenger not set") - } - if _, ok := i["L2StandardBridge"]["otherBridge"]; !ok { - return errors.New("L2StandardBridge otherBridge not set") - } - if _, ok := i["L2ERC721Bridge"]["messenger"]; !ok { - return errors.New("L2ERC721Bridge messenger not set") - } - if _, ok := i["L2ERC721Bridge"]["otherBridge"]; !ok { - return errors.New("L2ERC721Bridge otherBridge not set") - } - if _, ok := i["OptimismMintableERC721Factory"]["bridge"]; !ok { - return errors.New("OptimismMintableERC20Factory bridge not set") - } - if _, ok := i["OptimismMintableERC721Factory"]["remoteChainId"]; !ok { - return errors.New("OptimismMintableERC20Factory remoteChainId not set") - } - if _, ok := i["SequencerFeeVault"]["recipient"]; !ok { - return errors.New("SequencerFeeVault recipient not set") - } - if _, ok := i["L1FeeVault"]["recipient"]; !ok { - return errors.New("L1FeeVault recipient not set") - } - if _, ok := i["BaseFeeVault"]["recipient"]; !ok { - return errors.New("BaseFeeVault recipient not set") + has, err := bindings.HasImmutableReferences(name) + exists := err == nil && has + isZero := val.IsZero() + + // There are immutables defined in the solc output and + // the config is not empty. + if exists && !isZero { + return nil + } + // There are no immutables defined in the solc output and + // the config is empty + if !exists && isZero { + return nil + } + + return fmt.Errorf("invalid immutables config: field %s: %w", name, err) + }) +} + +// ForEach will iterate over each of the fields in the config and call the callback +// with the value of the field as well as the field's name. +func (c *PredeploysImmutableConfig) ForEach(cb func(string, any) error) error { + val := reflect.ValueOf(c).Elem() + typ := val.Type() + + for i := 0; i < val.NumField(); i++ { + field := val.Field(i) + internalVal := reflect.ValueOf(field.Interface()) + if err := cb(typ.Field(i).Name, internalVal.Interface()); err != nil { + return err + } } return nil } @@ -63,103 +118,55 @@ func (i ImmutableConfig) Check() error { // contracts so that the immutables can be set properly in the bytecode. type DeploymentResults map[string]hexutil.Bytes -// BuildOptimism will deploy the L2 predeploys so that their immutables are set -// correctly. -func BuildOptimism(immutable ImmutableConfig) (DeploymentResults, error) { - if err := immutable.Check(); err != nil { +// Deploy will deploy L2 predeploys that include immutables. This is to prevent the need +// for parsing the solc output to find the correct immutable offsets and splicing in the values. +// Skip any predeploys that do not have immutables as their bytecode will be directly inserted +// into the state. This does not currently support recursive structs. +func Deploy(config *PredeploysImmutableConfig) (DeploymentResults, error) { + if err := config.Check(); err != nil { return DeploymentResults{}, err } + deployments := make([]deployer.Constructor, 0) + + val := reflect.ValueOf(config).Elem() + typ := val.Type() + + for i := 0; i < val.NumField(); i++ { + field := val.Field(i) + if reflect.ValueOf(field.Interface()).IsZero() { + continue + } + + deployment := deployer.Constructor{ + Name: typ.Field(i).Name, + Args: []any{}, + } + + internalVal := reflect.ValueOf(field.Interface()) + for j := 0; j < internalVal.NumField(); j++ { + internalField := internalVal.Field(j) + deployment.Args = append(deployment.Args, internalField.Interface()) + } + + deployments = append(deployments, deployment) + } - deployments := []deployer.Constructor{ - { - Name: "GasPriceOracle", - }, - { - Name: "L1Block", - }, - { - Name: "L2CrossDomainMessenger", - Args: []interface{}{ - immutable["L2CrossDomainMessenger"]["otherMessenger"], - }, - }, - { - Name: "L2StandardBridge", - Args: []interface{}{ - immutable["L2StandardBridge"]["otherBridge"], - }, - }, - { - Name: "L2ToL1MessagePasser", - }, - { - Name: "SequencerFeeVault", - Args: []interface{}{ - immutable["SequencerFeeVault"]["recipient"], - immutable["SequencerFeeVault"]["minimumWithdrawalAmount"], - immutable["SequencerFeeVault"]["withdrawalNetwork"], - }, - }, - { - Name: "BaseFeeVault", - Args: []interface{}{ - immutable["BaseFeeVault"]["recipient"], - immutable["BaseFeeVault"]["minimumWithdrawalAmount"], - immutable["BaseFeeVault"]["withdrawalNetwork"], - }, - }, - { - Name: "L1FeeVault", - Args: []interface{}{ - immutable["L1FeeVault"]["recipient"], - immutable["L1FeeVault"]["minimumWithdrawalAmount"], - immutable["L1FeeVault"]["withdrawalNetwork"], - }, - }, - { - Name: "OptimismMintableERC20Factory", - }, - { - Name: "DeployerWhitelist", - }, - { - Name: "LegacyMessagePasser", - }, - { - Name: "L1BlockNumber", - }, - { - Name: "L2ERC721Bridge", - Args: []interface{}{ - immutable["L2ERC721Bridge"]["otherBridge"], - }, - }, - { - Name: "OptimismMintableERC721Factory", - Args: []interface{}{ - predeploys.L2ERC721BridgeAddr, - immutable["OptimismMintableERC721Factory"]["remoteChainId"], - }, - }, - { - Name: "LegacyERC20ETH", - }, - { - Name: "EAS", - }, - { - Name: "SchemaRegistry", - }, + results, err := deployContractsWithImmutables(deployments) + if err != nil { + return nil, fmt.Errorf("cannot deploy contracts with immutables: %w", err) } - return BuildL2(deployments) + return results, nil } -// BuildL2 will deploy contracts to a simulated backend so that their immutables +// deployContractsWithImmutables will deploy contracts to a simulated backend so that their immutables // can be properly set. The bytecode returned in the results is suitable to be // inserted into the state via state surgery. -func BuildL2(constructors []deployer.Constructor) (DeploymentResults, error) { - log.Info("Creating L2 state") - deployments, err := deployer.Deploy(deployer.NewL2Backend(), constructors, l2Deployer) +func deployContractsWithImmutables(constructors []deployer.Constructor) (DeploymentResults, error) { + backend, err := deployer.NewL2Backend() + if err != nil { + return nil, err + } + deployments, err := deployer.Deploy(backend, constructors, l2ImmutableDeployer) if err != nil { return nil, err } @@ -170,33 +177,21 @@ func BuildL2(constructors []deployer.Constructor) (DeploymentResults, error) { return results, nil } -func l2Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, deployment deployer.Constructor) (*types.Transaction, error) { +// l2ImmutableDeployer will deploy L2 predeploys that contain immutables to the simulated backend. +// It only needs to care about the predeploys that have immutables so that the deployed bytecode +// has the dynamic value set at the correct location in the bytecode. +func l2ImmutableDeployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, deployment deployer.Constructor) (*types.Transaction, error) { var tx *types.Transaction var recipient common.Address var minimumWithdrawalAmount *big.Int var withdrawalNetwork uint8 var err error + + if has, err := bindings.HasImmutableReferences(deployment.Name); err != nil || !has { + return nil, fmt.Errorf("%s does not have immutables: %w", deployment.Name, err) + } + switch deployment.Name { - case "GasPriceOracle": - _, tx, _, err = bindings.DeployGasPriceOracle(opts, backend) - case "L1Block": - // No arguments required for the L1Block contract - _, tx, _, err = bindings.DeployL1Block(opts, backend) - case "L2CrossDomainMessenger": - otherMessenger, ok := deployment.Args[0].(common.Address) - if !ok { - return nil, fmt.Errorf("invalid type for otherMessenger") - } - _, tx, _, err = bindings.DeployL2CrossDomainMessenger(opts, backend, otherMessenger) - case "L2StandardBridge": - otherBridge, ok := deployment.Args[0].(common.Address) - if !ok { - return nil, fmt.Errorf("invalid type for otherBridge") - } - _, tx, _, err = bindings.DeployL2StandardBridge(opts, backend, otherBridge) - case "L2ToL1MessagePasser": - // No arguments required for L2ToL1MessagePasser - _, tx, _, err = bindings.DeployL2ToL1MessagePasser(opts, backend) case "SequencerFeeVault": recipient, minimumWithdrawalAmount, withdrawalNetwork, err = prepareFeeVaultArguments(deployment) if err != nil { @@ -215,20 +210,6 @@ func l2Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep return nil, err } _, tx, _, err = bindings.DeployL1FeeVault(opts, backend, recipient, minimumWithdrawalAmount, withdrawalNetwork) - case "OptimismMintableERC20Factory": - _, tx, _, err = bindings.DeployOptimismMintableERC20Factory(opts, backend) - case "DeployerWhitelist": - _, tx, _, err = bindings.DeployDeployerWhitelist(opts, backend) - case "LegacyMessagePasser": - _, tx, _, err = bindings.DeployLegacyMessagePasser(opts, backend) - case "L1BlockNumber": - _, tx, _, err = bindings.DeployL1BlockNumber(opts, backend) - case "L2ERC721Bridge": - otherBridge, ok := deployment.Args[0].(common.Address) - if !ok { - return nil, fmt.Errorf("invalid type for otherBridge") - } - _, tx, _, err = bindings.DeployL2ERC721Bridge(opts, backend, otherBridge) case "OptimismMintableERC721Factory": bridge, ok := deployment.Args[0].(common.Address) if !ok { @@ -239,12 +220,8 @@ func l2Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep return nil, fmt.Errorf("invalid type for remoteChainId") } _, tx, _, err = bindings.DeployOptimismMintableERC721Factory(opts, backend, bridge, remoteChainId) - case "LegacyERC20ETH": - _, tx, _, err = bindings.DeployLegacyERC20ETH(opts, backend) case "EAS": _, tx, _, err = bindings.DeployEAS(opts, backend) - case "SchemaRegistry": - _, tx, _, err = bindings.DeploySchemaRegistry(opts, backend) default: return tx, fmt.Errorf("unknown contract: %s", deployment.Name) } @@ -252,12 +229,13 @@ func l2Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep return tx, err } +// prepareFeeVaultArguments is a helper function that parses the arguments for the fee vault contracts. func prepareFeeVaultArguments(deployment deployer.Constructor) (common.Address, *big.Int, uint8, error) { recipient, ok := deployment.Args[0].(common.Address) if !ok { return common.Address{}, nil, 0, fmt.Errorf("invalid type for recipient") } - minimumWithdrawalAmountHex, ok := deployment.Args[1].(*hexutil.Big) + minimumWithdrawalAmountHex, ok := deployment.Args[1].(*big.Int) if !ok { return common.Address{}, nil, 0, fmt.Errorf("invalid type for minimumWithdrawalAmount") } @@ -265,5 +243,5 @@ func prepareFeeVaultArguments(deployment deployer.Constructor) (common.Address, if !ok { return common.Address{}, nil, 0, fmt.Errorf("invalid type for withdrawalNetwork") } - return recipient, minimumWithdrawalAmountHex.ToInt(), withdrawalNetwork, nil + return recipient, minimumWithdrawalAmountHex, withdrawalNetwork, nil } diff --git a/op-chain-ops/immutables/immutables_test.go b/op-chain-ops/immutables/immutables_test.go index 389207d742e9..37a5f99bcc5a 100644 --- a/op-chain-ops/immutables/immutables_test.go +++ b/op-chain-ops/immutables/immutables_test.go @@ -2,79 +2,131 @@ package immutables_test import ( "math/big" + "reflect" "testing" + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-chain-ops/immutables" + "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" ) func TestBuildOptimism(t *testing.T) { - minimumWithdrawalAmountBig, _ := big.NewInt(0).SetString("8ac7230489e80000", 16) - minimumWithdrawalAmount := (*hexutil.Big)(minimumWithdrawalAmountBig) - results, err := immutables.BuildOptimism(immutables.ImmutableConfig{ - "L2StandardBridge": { - "otherBridge": common.HexToAddress("0x1234567890123456789012345678901234567890"), - }, - "L2CrossDomainMessenger": { - "otherMessenger": common.HexToAddress("0x1234567890123456789012345678901234567890"), - }, - "L2ERC721Bridge": { - "otherBridge": common.HexToAddress("0x1234567890123456789012345678901234567890"), - "messenger": common.HexToAddress("0x1234567890123456789012345678901234567890"), + cfg := immutables.PredeploysImmutableConfig{ + L2ToL1MessagePasser: struct{}{}, + DeployerWhitelist: struct{}{}, + WETH9: struct{}{}, + L2CrossDomainMessenger: struct{}{}, + L2StandardBridge: struct{}{}, + SequencerFeeVault: struct { + Recipient common.Address + MinWithdrawalAmount *big.Int + WithdrawalNetwork uint8 + }{ + Recipient: common.HexToAddress("0x1234567890123456789012345678901234567890"), + MinWithdrawalAmount: big.NewInt(100), + WithdrawalNetwork: 0, }, - "OptimismMintableERC721Factory": { - "remoteChainId": big.NewInt(1), - "bridge": common.HexToAddress("0x1234567890123456789012345678901234567890"), + L1BlockNumber: struct{}{}, + GasPriceOracle: struct{}{}, + L1Block: struct{}{}, + GovernanceToken: struct{}{}, + LegacyMessagePasser: struct{}{}, + L2ERC721Bridge: struct{}{}, + OptimismMintableERC721Factory: struct { + Bridge common.Address + RemoteChainId *big.Int + }{ + Bridge: predeploys.L2StandardBridgeAddr, + RemoteChainId: big.NewInt(1), }, - "SequencerFeeVault": { - "recipient": common.HexToAddress("0x1234567890123456789012345678901234567890"), - "minimumWithdrawalAmount": minimumWithdrawalAmount, - "withdrawalNetwork": uint8(0), + OptimismMintableERC20Factory: struct{}{}, + ProxyAdmin: struct{}{}, + BaseFeeVault: struct { + Recipient common.Address + MinWithdrawalAmount *big.Int + WithdrawalNetwork uint8 + }{ + Recipient: common.HexToAddress("0x1234567890123456789012345678901234567890"), + MinWithdrawalAmount: big.NewInt(200), + WithdrawalNetwork: 0, }, - "L1FeeVault": { - "recipient": common.HexToAddress("0x1234567890123456789012345678901234567890"), - "minimumWithdrawalAmount": minimumWithdrawalAmount, - "withdrawalNetwork": uint8(0), + L1FeeVault: struct { + Recipient common.Address + MinWithdrawalAmount *big.Int + WithdrawalNetwork uint8 + }{ + Recipient: common.HexToAddress("0x1234567890123456789012345678901234567890"), + MinWithdrawalAmount: big.NewInt(200), + WithdrawalNetwork: 1, }, - "BaseFeeVault": { - "recipient": common.HexToAddress("0x1234567890123456789012345678901234567890"), - "minimumWithdrawalAmount": minimumWithdrawalAmount, - "withdrawalNetwork": uint8(0), + SchemaRegistry: struct{}{}, + EAS: struct{ Name string }{ + Name: "EAS", }, - }) - require.Nil(t, err) + Create2Deployer: struct{}{}, + MultiCall3: struct{}{}, + Safe_v130: struct{}{}, + SafeL2_v130: struct{}{}, + MultiSendCallOnly_v130: struct{}{}, + SafeSingletonFactory: struct{}{}, + DeterministicDeploymentProxy: struct{}{}, + MultiSend_v130: struct{}{}, + Permit2: struct{}{}, + SenderCreator: struct{}{}, + EntryPoint: struct{}{}, + } + + require.NoError(t, cfg.Check()) + results, err := immutables.Deploy(&cfg) + require.NoError(t, err) require.NotNil(t, results) - contracts := map[string]bool{ - "GasPriceOracle": true, - "L1Block": true, - "L2CrossDomainMessenger": true, - "L2StandardBridge": true, - "L2ToL1MessagePasser": true, - "SequencerFeeVault": true, - "BaseFeeVault": true, - "L1FeeVault": true, - "OptimismMintableERC20Factory": true, - "DeployerWhitelist": true, - "LegacyMessagePasser": true, - "L1BlockNumber": true, - "L2ERC721Bridge": true, - "OptimismMintableERC721Factory": true, - "LegacyERC20ETH": true, - "EAS": true, - "SchemaRegistry": true, + // Build a mapping of all of the predeploys + all := map[string]bool{} + // Build a mapping of the predeploys with immutable config + withConfig := map[string]bool{} + + require.NoError(t, cfg.ForEach(func(name string, predeployConfig any) error { + all[name] = true + + // If a predeploy has no config, it needs to have no immutable references in the solc output. + if reflect.ValueOf(predeployConfig).IsZero() { + ref, _ := bindings.HasImmutableReferences(name) + require.Zero(t, ref, "found immutable reference for %s", name) + return nil + } + withConfig[name] = true + return nil + })) + + // Ensure that the PredeploysImmutableConfig is kept up to date + for name := range predeploys.Predeploys { + require.Truef(t, all[name], "predeploy %s not in set of predeploys", name) + + ref, err := bindings.HasImmutableReferences(name) + // If there is predeploy config, there should be an immutable reference + if withConfig[name] { + require.NoErrorf(t, err, "error getting immutable reference for %s", name) + require.NotZerof(t, ref, "no immutable reference for %s", name) + } else { + require.Zero(t, ref, "found immutable reference for %s", name) + } } - // Only the exact contracts that we care about are being - // modified - require.Equal(t, len(results), len(contracts)) + // Only the exact contracts that we care about are being modified + require.Equal(t, len(results), len(withConfig)) for name, bytecode := range results { // There is bytecode there require.Greater(t, len(bytecode), 0) // It is in the set of contracts that we care about - require.True(t, contracts[name]) + require.Truef(t, withConfig[name], "contract %s not in set of contracts", name) + // The immutable reference is present + ref, err := bindings.HasImmutableReferences(name) + require.NoErrorf(t, err, "cannot get immutable reference for %s", name) + require.NotZerof(t, ref, "contract %s has no immutable reference", name) } } diff --git a/op-chain-ops/squash/sim.go b/op-chain-ops/squash/sim.go new file mode 100644 index 000000000000..ae612dbc0d4f --- /dev/null +++ b/op-chain-ops/squash/sim.go @@ -0,0 +1,200 @@ +package squash + +import ( + "encoding/binary" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" + + "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-chain-ops/state" +) + +type staticChain struct { + startTime uint64 + blockTime uint64 +} + +func (d *staticChain) Engine() consensus.Engine { + return ethash.NewFullFaker() +} + +func (d *staticChain) GetHeader(h common.Hash, n uint64) *types.Header { + parentHash := common.Hash{0: 0xff} + binary.BigEndian.PutUint64(parentHash[1:], n-1) + return &types.Header{ + ParentHash: parentHash, + UncleHash: types.EmptyUncleHash, + Coinbase: common.Address{}, + Root: common.Hash{}, + TxHash: types.EmptyTxsHash, + ReceiptHash: types.EmptyReceiptsHash, + Bloom: types.Bloom{}, + Difficulty: big.NewInt(0), + Number: new(big.Int).SetUint64(n), + GasLimit: 30_000_000, + GasUsed: 0, + Time: d.startTime + n*d.blockTime, + Extra: nil, + MixDigest: common.Hash{}, + Nonce: types.BlockNonce{}, + BaseFee: big.NewInt(7), + WithdrawalsHash: &types.EmptyWithdrawalsHash, + } +} + +type simState struct { + *state.MemoryStateDB + snapshotIndex int + tempAccessList map[common.Address]map[common.Hash]struct{} +} + +var _ vm.StateDB = (*simState)(nil) + +func (db *simState) AddressInAccessList(addr common.Address) bool { + _, ok := db.tempAccessList[addr] + return ok +} + +func (db *simState) AddLog(log *types.Log) { + // no-op +} + +func (db *simState) GetCommittedState(addr common.Address, hash common.Hash) common.Hash { + // return the latest state, instead of the pre-tx state. + acc, ok := db.Genesis().Alloc[addr] + if !ok { + return common.Hash{} + } + return acc.Storage[hash] +} + +func (db *simState) AddSlotToAccessList(addr common.Address, slot common.Hash) { + // things like the fee-vault-address get marked as warm + m, ok := db.tempAccessList[addr] + if !ok { + m = make(map[common.Hash]struct{}) + db.tempAccessList[addr] = m + } + m[slot] = struct{}{} +} + +func (db *simState) SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool) { + m, addressOk := db.tempAccessList[addr] + if !addressOk { + return false, false + } + _, slotOk = m[slot] + return true, slotOk +} + +func (db *simState) GetRefund() uint64 { + return 0 +} + +func (db *simState) AddAddressToAccessList(addr common.Address) { + if _, ok := db.tempAccessList[addr]; !ok { + db.tempAccessList[addr] = make(map[common.Hash]struct{}) + } +} + +func (db *simState) RevertToSnapshot(int) { + panic("RevertToSnapshot not supported") +} + +func (db *simState) Snapshot() int { + db.snapshotIndex += 1 + return db.snapshotIndex +} + +// SquashSim wraps an op-chain-ops MemporyStateDB, +// and applies EVM-messages as if they all exist in the same infinite EVM block. +// The result is squashing all the EVM execution changes into the state. +type SquashSim struct { + chainConfig *params.ChainConfig + state *simState + evm *vm.EVM + signer types.Signer +} + +// AddMessage processes a message on top of the chain-state that is squashed into a genesis state allocation. +func (sim *SquashSim) AddMessage(msg *core.Message) (res *core.ExecutionResult, err error) { + defer func() { + if rErr := recover(); rErr != nil { + err = fmt.Errorf("critical error: %v", rErr) + } + }() + + // reset access-list + sim.state.tempAccessList = make(map[common.Address]map[common.Hash]struct{}) + + gp := new(core.GasPool) + gp.AddGas(30_000_000) + + rules := sim.evm.ChainConfig().Rules(sim.evm.Context.BlockNumber, true, sim.evm.Context.Time) + sim.evm.StateDB.Prepare(rules, msg.From, predeploys.SequencerFeeVaultAddr, msg.To, vm.ActivePrecompiles(rules), msg.AccessList) + if !sim.state.Exist(msg.From) { + sim.state.CreateAccount(msg.From) + } + return core.ApplyMessage(sim.evm, msg, gp) +} + +func (sim *SquashSim) BlockContext() *vm.BlockContext { + return &sim.evm.Context +} + +// AddUpgradeTxs traverses a list of encoded deposit transactions. +// These transactions should match what would be included in the live system upgrade. +// The resulting state changes are squashed together, such that the final state can then be used as genesis state. +func (sim *SquashSim) AddUpgradeTxs(txs []hexutil.Bytes) error { + for i, otx := range txs { + var tx types.Transaction + if err := tx.UnmarshalBinary(otx); err != nil { + return fmt.Errorf("failed to decode upgrade tx %d: %w", i, err) + } + msg, err := core.TransactionToMessage(&tx, sim.signer, sim.BlockContext().BaseFee) + if err != nil { + return fmt.Errorf("failed to turn upgrade tx %d into message: %w", i, err) + } + if !msg.IsDepositTx { + return fmt.Errorf("upgrade tx %d is not a depost", i) + } + if res, err := sim.AddMessage(msg); err != nil { + return fmt.Errorf("invalid upgrade tx %d, EVM invocation failed: %w", i, err) + } else { + if res.Err != nil { + return fmt.Errorf("failed to successfully execute upgrade tx %d: %w", i, err) + } + } + } + return nil +} + +func NewSimulator(db *state.MemoryStateDB) *SquashSim { + offsetBlocks := uint64(0) + genesisTime := uint64(17_000_000) + blockTime := uint64(2) + bc := &staticChain{startTime: genesisTime, blockTime: blockTime} + header := bc.GetHeader(common.Hash{}, genesisTime+offsetBlocks) + chainCfg := db.Genesis().Config + blockContext := core.NewEVMBlockContext(header, bc, nil, chainCfg, db) + vmCfg := vm.Config{} + signer := types.LatestSigner(db.Genesis().Config) + simDB := &simState{MemoryStateDB: db} + env := vm.NewEVM(blockContext, vm.TxContext{}, simDB, chainCfg, vmCfg) + + return &SquashSim{ + chainConfig: chainCfg, + state: simDB, + evm: env, + signer: signer, + } +} diff --git a/op-chain-ops/srcmap/solutil_test.go b/op-chain-ops/srcmap/solutil_test.go index 269f61efd531..e607d7e4ddc9 100644 --- a/op-chain-ops/srcmap/solutil_test.go +++ b/op-chain-ops/srcmap/solutil_test.go @@ -1,36 +1,29 @@ package srcmap import ( - "path" - "strings" "testing" - - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/stretchr/testify/require" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" ) func TestSourcemap(t *testing.T) { t.Skip("TODO(clabby): This test is disabled until source IDs have been added to foundry artifacts.") - contractsDir := "../../packages/contracts-bedrock" - sources := []string{path.Join(contractsDir, "src/cannon/MIPS.sol")} - for i, source := range sources { - sources[i] = path.Join(contractsDir, source) - } - - deployedByteCode := hexutil.MustDecode(bindings.MIPSDeployedBin) - srcMap, err := ParseSourceMap( - sources, - deployedByteCode, - bindings.MIPSDeployedSourceMap) - require.NoError(t, err) - - for i := 0; i < len(deployedByteCode); i++ { - info := srcMap.FormattedInfo(uint64(i)) - if strings.HasPrefix(info, "unknown") { - t.Fatalf("unexpected info: %q", info) - } - } + // contractsDir := "../../packages/contracts-bedrock" + // sources := []string{path.Join(contractsDir, "src/cannon/MIPS.sol")} + // for i, source := range sources { + // sources[i] = path.Join(contractsDir, source) + // } + // + // deployedByteCode := hexutil.MustDecode(bindings.MIPSDeployedBin) + // srcMap, err := ParseSourceMap( + // sources, + // deployedByteCode, + // bindings.MIPSDeployedSourceMap) + // require.NoError(t, err) + // + // for i := 0; i < len(deployedByteCode); i++ { + // info := srcMap.FormattedInfo(uint64(i)) + // if strings.HasPrefix(info, "unknown") { + // t.Fatalf("unexpected info: %q", info) + // } + // } } diff --git a/op-chain-ops/state/memory_db.go b/op-chain-ops/state/memory_db.go index 5e27ef448dcb..2e8c8470f839 100644 --- a/op-chain-ops/state/memory_db.go +++ b/op-chain-ops/state/memory_db.go @@ -16,7 +16,10 @@ import ( var _ vm.StateDB = (*MemoryStateDB)(nil) -var emptyCodeHash = crypto.Keccak256(nil) +var ( + emptyCodeHash = crypto.Keccak256(nil) + zeroAddr = common.Address{} +) // MemoryStateDB implements geth's StateDB interface // but operates on a core.Genesis so that a genesis.json @@ -28,7 +31,7 @@ type MemoryStateDB struct { func NewMemoryStateDB(genesis *core.Genesis) *MemoryStateDB { if genesis == nil { - genesis = core.DeveloperGenesisBlock(15_000_000, common.Address{}) + genesis = core.DeveloperGenesisBlock(15_000_000, &zeroAddr) } return &MemoryStateDB{ @@ -61,6 +64,10 @@ func (db *MemoryStateDB) CreateAccount(addr common.Address) { db.rw.Lock() defer db.rw.Unlock() + db.createAccount(addr) +} + +func (db *MemoryStateDB) createAccount(addr common.Address) { if _, ok := db.genesis.Alloc[addr]; !ok { db.genesis.Alloc[addr] = core.GenesisAccount{ Code: []byte{}, @@ -69,7 +76,6 @@ func (db *MemoryStateDB) CreateAccount(addr common.Address) { Nonce: 0, } } - } func (db *MemoryStateDB) SubBalance(addr common.Address, amount *big.Int) { @@ -165,6 +171,8 @@ func (db *MemoryStateDB) SetCode(addr common.Address, code []byte) { db.rw.Lock() defer db.rw.Unlock() + db.createAccount(addr) + account, ok := db.genesis.Alloc[addr] if !ok { return @@ -174,8 +182,8 @@ func (db *MemoryStateDB) SetCode(addr common.Address, code []byte) { } func (db *MemoryStateDB) GetCodeSize(addr common.Address) int { - db.rw.Lock() - defer db.rw.Unlock() + db.rw.RLock() + defer db.rw.RUnlock() account, ok := db.genesis.Alloc[addr] if !ok { @@ -227,6 +235,9 @@ func (db *MemoryStateDB) SetState(addr common.Address, key, value common.Hash) { } func (db *MemoryStateDB) DeleteState(addr common.Address, key common.Hash) { + db.rw.Lock() + defer db.rw.Unlock() + account, ok := db.genesis.Alloc[addr] if !ok { panic(fmt.Sprintf("%s not in state", addr)) diff --git a/op-chain-ops/state/state.go b/op-chain-ops/state/state.go index 96156f1c13c5..b3788081c0cf 100644 --- a/op-chain-ops/state/state.go +++ b/op-chain-ops/state/state.go @@ -73,6 +73,7 @@ func ComputeStorageSlots(layout *solc.StorageLayout, values StorageValues) ([]*E for _, entry := range layout.Storage { if label == entry.Label { target = entry + break } } if target.Label == "" { diff --git a/op-chain-ops/upgrades/check.go b/op-chain-ops/upgrades/check.go index 95cd3f770535..5eb4fc79c4b9 100644 --- a/op-chain-ops/upgrades/check.go +++ b/op-chain-ops/upgrades/check.go @@ -42,7 +42,7 @@ func CheckL1(ctx context.Context, list *superchain.ImplementationList, backend b // CheckVersionedContract will check that the version of the deployed contract matches // the artifact in the superchain registry. func CheckVersionedContract(ctx context.Context, contract superchain.VersionedContract, backend bind.ContractBackend) error { - addr := common.HexToAddress(contract.Address.String()) + addr := common.Address(contract.Address) code, err := backend.CodeAt(ctx, addr, nil) if err != nil { return err @@ -65,31 +65,31 @@ func GetContractVersions(ctx context.Context, addresses *superchain.AddressList, var versions superchain.ContractVersions var err error - versions.L1CrossDomainMessenger, err = getVersion(ctx, common.HexToAddress(addresses.L1CrossDomainMessengerProxy.String()), backend) + versions.L1CrossDomainMessenger, err = getVersion(ctx, common.Address(addresses.L1CrossDomainMessengerProxy), backend) if err != nil { return versions, fmt.Errorf("L1CrossDomainMessenger: %w", err) } - versions.L1ERC721Bridge, err = getVersion(ctx, common.HexToAddress(addresses.L1ERC721BridgeProxy.String()), backend) + versions.L1ERC721Bridge, err = getVersion(ctx, common.Address(addresses.L1ERC721BridgeProxy), backend) if err != nil { return versions, fmt.Errorf("L1ERC721Bridge: %w", err) } - versions.L1StandardBridge, err = getVersion(ctx, common.HexToAddress(addresses.L1StandardBridgeProxy.String()), backend) + versions.L1StandardBridge, err = getVersion(ctx, common.Address(addresses.L1StandardBridgeProxy), backend) if err != nil { return versions, fmt.Errorf("L1StandardBridge: %w", err) } - versions.L2OutputOracle, err = getVersion(ctx, common.HexToAddress(addresses.L2OutputOracleProxy.String()), backend) + versions.L2OutputOracle, err = getVersion(ctx, common.Address(addresses.L2OutputOracleProxy), backend) if err != nil { return versions, fmt.Errorf("L2OutputOracle: %w", err) } - versions.OptimismMintableERC20Factory, err = getVersion(ctx, common.HexToAddress(addresses.OptimismMintableERC20FactoryProxy.String()), backend) + versions.OptimismMintableERC20Factory, err = getVersion(ctx, common.Address(addresses.OptimismMintableERC20FactoryProxy), backend) if err != nil { return versions, fmt.Errorf("OptimismMintableERC20Factory: %w", err) } - versions.OptimismPortal, err = getVersion(ctx, common.HexToAddress(addresses.OptimismPortalProxy.String()), backend) + versions.OptimismPortal, err = getVersion(ctx, common.Address(addresses.OptimismPortalProxy), backend) if err != nil { return versions, fmt.Errorf("OptimismPortal: %w", err) } - versions.SystemConfig, err = getVersion(ctx, common.HexToAddress(chainConfig.SystemConfigAddr.String()), backend) + versions.SystemConfig, err = getVersion(ctx, common.Address(addresses.SystemConfigProxy), backend) if err != nil { return versions, fmt.Errorf("SystemConfig: %w", err) } diff --git a/op-chain-ops/upgrades/l1.go b/op-chain-ops/upgrades/l1.go index 8062e48d8fef..56383710e919 100644 --- a/op-chain-ops/upgrades/l1.go +++ b/op-chain-ops/upgrades/l1.go @@ -8,15 +8,30 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-chain-ops/safe" "github.com/ethereum-optimism/superchain-registry/superchain" ) -// upgradeAndCall represents the signature of the upgradeAndCall function -// on the ProxyAdmin contract. -const upgradeAndCall = "upgradeAndCall(address,address,bytes)" +const ( + // upgradeAndCall represents the signature of the upgradeAndCall function + // on the ProxyAdmin contract. + upgradeAndCall = "upgradeAndCall(address,address,bytes)" + + method = "setBytes32" +) + +var ( + // storageSetterAddr represents the address of the StorageSetter contract. + storageSetterAddr = common.HexToAddress("0xd81f43eDBCAcb4c29a9bA38a13Ee5d79278270cC") + + // superchainConfigProxy refers to the address of the Sepolia superchain config proxy. + // NOTE: this is currently hardcoded and we will need to move this to the superchain-registry + // and have 1 deployed for each superchain target. + superchainConfigProxy = common.HexToAddress("0xC2Be75506d5724086DEB7245bd260Cc9753911Be") +) // L1 will add calls for upgrading each of the L1 contracts. func L1(batch *safe.Batch, implementations superchain.ImplementationList, list superchain.AddressList, config *genesis.DeployConfig, chainConfig *superchain.ChainConfig, backend bind.ContractBackend) error { @@ -51,23 +66,74 @@ func L1CrossDomainMessenger(batch *safe.Batch, implementations superchain.Implem return err } + // 2 Step Upgrade + { + storageSetterABI, err := bindings.StorageSetterMetaData.GetAbi() + if err != nil { + return err + } + + input := []bindings.StorageSetterSlot{ + // https://github.com/ethereum-optimism/optimism/blob/86a96023ffd04d119296dff095d02fff79fa15de/packages/contracts-bedrock/.storage-layout#L11-L13 + { + Key: common.Hash{}, + Value: common.Hash{}, + }, + } + + calldata, err := storageSetterABI.Pack(method, input) + if err != nil { + return err + } + args := []any{ + common.Address(list.L1CrossDomainMessengerProxy), + storageSetterAddr, + calldata, + } + proxyAdmin := common.Address(list.ProxyAdmin) + if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { + return err + } + } + l1CrossDomainMessengerABI, err := bindings.L1CrossDomainMessengerMetaData.GetAbi() if err != nil { return err } - calldata, err := l1CrossDomainMessengerABI.Pack("initialize", common.HexToAddress(list.OptimismPortalProxy.String())) + l1CrossDomainMessenger, err := bindings.NewL1CrossDomainMessengerCaller(common.Address(list.L1CrossDomainMessengerProxy), backend) + if err != nil { + return err + } + optimismPortal, err := l1CrossDomainMessenger.PORTAL(&bind.CallOpts{}) + if err != nil { + return err + } + otherMessenger, err := l1CrossDomainMessenger.OTHERMESSENGER(&bind.CallOpts{}) + if err != nil { + return err + } + + if optimismPortal != common.Address(list.OptimismPortalProxy) { + return fmt.Errorf("Portal address doesn't match config") + } + + if otherMessenger != predeploys.L2CrossDomainMessengerAddr { + return fmt.Errorf("OtherMessenger address doesn't match config") + } + + calldata, err := l1CrossDomainMessengerABI.Pack("initialize", superchainConfigProxy, optimismPortal) if err != nil { return err } args := []any{ - common.HexToAddress(list.L1CrossDomainMessengerProxy.String()), - common.HexToAddress(implementations.L1CrossDomainMessenger.Address.String()), + common.Address(list.L1CrossDomainMessengerProxy), + common.Address(implementations.L1CrossDomainMessenger.Address), calldata, } - proxyAdmin := common.HexToAddress(list.ProxyAdmin.String()) + proxyAdmin := common.Address(list.ProxyAdmin) if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { return err } @@ -82,23 +148,74 @@ func L1ERC721Bridge(batch *safe.Batch, implementations superchain.Implementation return err } + // 2 Step Upgrade + { + storageSetterABI, err := bindings.StorageSetterMetaData.GetAbi() + if err != nil { + return err + } + + input := []bindings.StorageSetterSlot{ + // https://github.com/ethereum-optimism/optimism/blob/86a96023ffd04d119296dff095d02fff79fa15de/packages/contracts-bedrock/.storage-layout#L100-L102 + { + Key: common.Hash{}, + Value: common.Hash{}, + }, + } + + calldata, err := storageSetterABI.Pack(method, input) + if err != nil { + return fmt.Errorf("setBytes32: %w", err) + } + args := []any{ + common.Address(list.L1ERC721BridgeProxy), + storageSetterAddr, + calldata, + } + proxyAdmin := common.Address(list.ProxyAdmin) + if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { + return err + } + } + l1ERC721BridgeABI, err := bindings.L1ERC721BridgeMetaData.GetAbi() if err != nil { return err } - calldata, err := l1ERC721BridgeABI.Pack("initialize", common.HexToAddress(list.L1CrossDomainMessengerProxy.String())) + l1ERC721Bridge, err := bindings.NewL1ERC721BridgeCaller(common.Address(list.L1ERC721BridgeProxy), backend) + if err != nil { + return err + } + messenger, err := l1ERC721Bridge.Messenger(&bind.CallOpts{}) + if err != nil { + return err + } + otherBridge, err := l1ERC721Bridge.OtherBridge(&bind.CallOpts{}) + if err != nil { + return err + } + + if messenger != common.Address(list.L1CrossDomainMessengerProxy) { + return fmt.Errorf("Messenger address doesn't match config") + } + + if otherBridge != predeploys.L2ERC721BridgeAddr { + return fmt.Errorf("OtherBridge address doesn't match config") + } + + calldata, err := l1ERC721BridgeABI.Pack("initialize", messenger, superchainConfigProxy) if err != nil { return err } args := []any{ - common.HexToAddress(list.L1ERC721BridgeProxy.String()), - common.HexToAddress(implementations.L1ERC721Bridge.Address.String()), + common.Address(list.L1ERC721BridgeProxy), + common.Address(implementations.L1ERC721Bridge.Address), calldata, } - proxyAdmin := common.HexToAddress(list.ProxyAdmin.String()) + proxyAdmin := common.Address(list.ProxyAdmin) if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { return err } @@ -113,24 +230,32 @@ func L1StandardBridge(batch *safe.Batch, implementations superchain.Implementati return err } - // Add in OP Mainnet specific upgrade logic here - if chainConfig.ChainID == 10 { + // 2 Step Upgrade + { storageSetterABI, err := bindings.StorageSetterMetaData.GetAbi() if err != nil { return err } - calldata, err := storageSetterABI.Pack("setBytes32", common.Hash{}, common.Hash{}) + + input := []bindings.StorageSetterSlot{ + // https://github.com/ethereum-optimism/optimism/blob/86a96023ffd04d119296dff095d02fff79fa15de/packages/contracts-bedrock/.storage-layout#L36-L37 + { + Key: common.Hash{}, + Value: common.Hash{}, + }, + } + + calldata, err := storageSetterABI.Pack(method, input) if err != nil { return err } args := []any{ - common.HexToAddress(list.L1StandardBridgeProxy.String()), - common.HexToAddress("0xf30CE41cA2f24D28b95Eb861553dAc2948e0157F"), + common.Address(list.L1StandardBridgeProxy), + storageSetterAddr, calldata, } - proxyAdmin := common.HexToAddress(list.ProxyAdmin.String()) - sig := "upgradeAndCall(address,address,bytes)" - if err := batch.AddCall(proxyAdmin, common.Big0, sig, args, proxyAdminABI); err != nil { + proxyAdmin := common.Address(list.ProxyAdmin) + if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { return err } } @@ -140,18 +265,41 @@ func L1StandardBridge(batch *safe.Batch, implementations superchain.Implementati return err } - calldata, err := l1StandardBridgeABI.Pack("initialize", common.HexToAddress(list.L1CrossDomainMessengerProxy.String())) + l1StandardBridge, err := bindings.NewL1StandardBridgeCaller(common.Address(list.L1StandardBridgeProxy), backend) + if err != nil { + return err + } + + messenger, err := l1StandardBridge.MESSENGER(&bind.CallOpts{}) + if err != nil { + return err + } + + otherBridge, err := l1StandardBridge.OTHERBRIDGE(&bind.CallOpts{}) + if err != nil { + return err + } + + if messenger != common.Address(list.L1CrossDomainMessengerProxy) { + return fmt.Errorf("Messenger address doesn't match config") + } + + if otherBridge != predeploys.L2StandardBridgeAddr { + return fmt.Errorf("OtherBridge address doesn't match config") + } + + calldata, err := l1StandardBridgeABI.Pack("initialize", messenger, superchainConfigProxy) if err != nil { return err } args := []any{ - common.HexToAddress(list.L1StandardBridgeProxy.String()), - common.HexToAddress(implementations.L1StandardBridge.Address.String()), + common.Address(list.L1StandardBridgeProxy), + common.Address(implementations.L1StandardBridge.Address), calldata, } - proxyAdmin := common.HexToAddress(list.ProxyAdmin.String()) + proxyAdmin := common.Address(list.ProxyAdmin) if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { return err } @@ -166,59 +314,136 @@ func L2OutputOracle(batch *safe.Batch, implementations superchain.Implementation return err } + // 2 Step Upgrade + { + storageSetterABI, err := bindings.StorageSetterMetaData.GetAbi() + if err != nil { + return err + } + + input := []bindings.StorageSetterSlot{ + // https://github.com/ethereum-optimism/optimism/blob/86a96023ffd04d119296dff095d02fff79fa15de/packages/contracts-bedrock/.storage-layout#L50-L51 + { + Key: common.Hash{}, + Value: common.Hash{}, + }, + } + + calldata, err := storageSetterABI.Pack(method, input) + if err != nil { + return err + } + args := []any{ + common.Address(list.L2OutputOracleProxy), + storageSetterAddr, + calldata, + } + proxyAdmin := common.Address(list.ProxyAdmin) + if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { + return err + } + } + l2OutputOracleABI, err := bindings.L2OutputOracleMetaData.GetAbi() if err != nil { return err } - var l2OutputOracleStartingBlockNumber, l2OutputOracleStartingTimestamp *big.Int - var l2OutputOracleProposer, l2OutputOracleChallenger common.Address + l2OutputOracle, err := bindings.NewL2OutputOracleCaller(common.Address(list.L2OutputOracleProxy), backend) + if err != nil { + return err + } + + l2OutputOracleSubmissionInterval, err := l2OutputOracle.SUBMISSIONINTERVAL(&bind.CallOpts{}) + if err != nil { + return err + } + + l2BlockTime, err := l2OutputOracle.L2BLOCKTIME(&bind.CallOpts{}) + if err != nil { + return err + } + + l2OutputOracleStartingBlockNumber, err := l2OutputOracle.StartingBlockNumber(&bind.CallOpts{}) + if err != nil { + return err + } + + l2OutputOracleStartingTimestamp, err := l2OutputOracle.StartingTimestamp(&bind.CallOpts{}) + if err != nil { + return err + } + + l2OutputOracleProposer, err := l2OutputOracle.PROPOSER(&bind.CallOpts{}) + if err != nil { + return err + } + + l2OutputOracleChallenger, err := l2OutputOracle.CHALLENGER(&bind.CallOpts{}) + if err != nil { + return err + } + + finalizationPeriodSeconds, err := l2OutputOracle.FINALIZATIONPERIODSECONDS(&bind.CallOpts{}) + if err != nil { + return err + } + if config != nil { - l2OutputOracleStartingBlockNumber = new(big.Int).SetUint64(config.L2OutputOracleStartingBlockNumber) + if l2OutputOracleSubmissionInterval.Uint64() != config.L2OutputOracleSubmissionInterval { + return fmt.Errorf("L2OutputOracleSubmissionInterval address doesn't match config") + } + + if l2BlockTime.Uint64() != config.L2BlockTime { + return fmt.Errorf("L2BlockTime address doesn't match config") + } + + if l2OutputOracleStartingBlockNumber.Uint64() != config.L2OutputOracleStartingBlockNumber { + return fmt.Errorf("L2OutputOracleStartingBlockNumber address doesn't match config") + } + if config.L2OutputOracleStartingTimestamp < 0 { return fmt.Errorf("L2OutputOracleStartingTimestamp must be concrete") } - l2OutputOracleStartingTimestamp = new(big.Int).SetInt64(int64(config.L2OutputOracleStartingTimestamp)) - l2OutputOracleProposer = config.L2OutputOracleProposer - l2OutputOracleChallenger = config.L2OutputOracleChallenger - } else { - l2OutputOracle, err := bindings.NewL2OutputOracleCaller(common.HexToAddress(list.L2OutputOracleProxy.String()), backend) - if err != nil { - return err - } - l2OutputOracleStartingBlockNumber, err = l2OutputOracle.StartingBlockNumber(&bind.CallOpts{}) - if err != nil { - return err + + if int(l2OutputOracleStartingTimestamp.Int64()) != config.L2OutputOracleStartingTimestamp { + return fmt.Errorf("L2OutputOracleStartingTimestamp address doesn't match config") } - l2OutputOracleStartingTimestamp, err = l2OutputOracle.StartingTimestamp(&bind.CallOpts{}) - if err != nil { - return err + if l2OutputOracleProposer != config.L2OutputOracleProposer { + return fmt.Errorf("L2OutputOracleProposer address doesn't match config") } - l2OutputOracleProposer, err = l2OutputOracle.PROPOSER(&bind.CallOpts{}) - if err != nil { - return err + if l2OutputOracleChallenger != config.L2OutputOracleChallenger { + return fmt.Errorf("L2OutputOracleChallenger address doesn't match config") } - l2OutputOracleChallenger, err = l2OutputOracle.CHALLENGER(&bind.CallOpts{}) - if err != nil { - return err + if finalizationPeriodSeconds.Uint64() != config.FinalizationPeriodSeconds { + return fmt.Errorf("FinalizationPeriodSeconds address doesn't match config") } } - calldata, err := l2OutputOracleABI.Pack("initialize", l2OutputOracleStartingBlockNumber, l2OutputOracleStartingTimestamp, l2OutputOracleProposer, l2OutputOracleChallenger) + calldata, err := l2OutputOracleABI.Pack( + "initialize", + l2OutputOracleSubmissionInterval, + l2BlockTime, + l2OutputOracleStartingBlockNumber, + l2OutputOracleStartingTimestamp, + l2OutputOracleProposer, + l2OutputOracleChallenger, + finalizationPeriodSeconds, + ) if err != nil { return err } args := []any{ - common.HexToAddress(list.L2OutputOracleProxy.String()), - common.HexToAddress(implementations.L2OutputOracle.Address.String()), + common.Address(list.L2OutputOracleProxy), + common.Address(implementations.L2OutputOracle.Address), calldata, } - proxyAdmin := common.HexToAddress(list.ProxyAdmin.String()) + proxyAdmin := common.Address(list.ProxyAdmin) if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { return err } @@ -233,23 +458,67 @@ func OptimismMintableERC20Factory(batch *safe.Batch, implementations superchain. return err } + // 2 Step Upgrade + { + storageSetterABI, err := bindings.StorageSetterMetaData.GetAbi() + if err != nil { + return err + } + + input := []bindings.StorageSetterSlot{ + // https://github.com/ethereum-optimism/optimism/blob/86a96023ffd04d119296dff095d02fff79fa15de/packages/contracts-bedrock/.storage-layout#L287-L289 + { + Key: common.Hash{}, + Value: common.Hash{}, + }, + } + + calldata, err := storageSetterABI.Pack(method, input) + if err != nil { + return err + } + args := []any{ + common.Address(list.OptimismMintableERC20FactoryProxy), + storageSetterAddr, + calldata, + } + proxyAdmin := common.Address(list.ProxyAdmin) + if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { + return err + } + } + optimismMintableERC20FactoryABI, err := bindings.OptimismMintableERC20FactoryMetaData.GetAbi() if err != nil { return err } - calldata, err := optimismMintableERC20FactoryABI.Pack("initialize", common.HexToAddress(list.L1StandardBridgeProxy.String())) + optimismMintableERC20Factory, err := bindings.NewOptimismMintableERC20FactoryCaller(common.Address(list.OptimismMintableERC20FactoryProxy), backend) + if err != nil { + return err + } + + bridge, err := optimismMintableERC20Factory.BRIDGE(&bind.CallOpts{}) + if err != nil { + return err + } + + if bridge != common.Address(list.L1StandardBridgeProxy) { + return fmt.Errorf("Bridge address doesn't match config") + } + + calldata, err := optimismMintableERC20FactoryABI.Pack("initialize", bridge) if err != nil { return err } args := []any{ - common.HexToAddress(list.OptimismMintableERC20FactoryProxy.String()), - common.HexToAddress(implementations.OptimismMintableERC20Factory.Address.String()), + common.Address(list.OptimismMintableERC20FactoryProxy), + common.Address(implementations.OptimismMintableERC20Factory.Address), calldata, } - proxyAdmin := common.HexToAddress(list.ProxyAdmin.String()) + proxyAdmin := common.Address(list.ProxyAdmin) if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { return err } @@ -264,38 +533,74 @@ func OptimismPortal(batch *safe.Batch, implementations superchain.Implementation return err } - optimismPortalABI, err := bindings.OptimismPortalMetaData.GetAbi() - if err != nil { - return err - } - - var portalGuardian common.Address - if config != nil { - portalGuardian = config.PortalGuardian - } else { - optimismPortal, err := bindings.NewOptimismPortalCaller(common.HexToAddress(list.OptimismPortalProxy.String()), backend) + // 2 Step Upgrade + { + storageSetterABI, err := bindings.StorageSetterMetaData.GetAbi() if err != nil { return err } - guardian, err := optimismPortal.GUARDIAN(&bind.CallOpts{}) + + input := []bindings.StorageSetterSlot{ + // https://github.com/ethereum-optimism/optimism/blob/86a96023ffd04d119296dff095d02fff79fa15de/packages/contracts-bedrock/.storage-layout#L64-L65 + { + Key: common.Hash{}, + Value: common.Hash{}, + }, + } + + calldata, err := storageSetterABI.Pack(method, input) if err != nil { return err } - portalGuardian = guardian + args := []any{ + common.Address(list.OptimismPortalProxy), + storageSetterAddr, + calldata, + } + proxyAdmin := common.Address(list.ProxyAdmin) + if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { + return err + } + } + + optimismPortalABI, err := bindings.OptimismPortalMetaData.GetAbi() + if err != nil { + return err } - calldata, err := optimismPortalABI.Pack("initialize", common.HexToAddress(list.L2OutputOracleProxy.String()), portalGuardian, common.HexToAddress(chainConfig.SystemConfigAddr.String()), false) + optimismPortal, err := bindings.NewOptimismPortalCaller(common.Address(list.OptimismPortalProxy), backend) + if err != nil { + return err + } + l2OutputOracle, err := optimismPortal.L2ORACLE(&bind.CallOpts{}) + if err != nil { + return err + } + systemConfig, err := optimismPortal.SYSTEMCONFIG(&bind.CallOpts{}) + if err != nil { + return err + } + + if l2OutputOracle != common.Address(list.L2OutputOracleProxy) { + return fmt.Errorf("L2OutputOracle address doesn't match config") + } + + if systemConfig != common.Address(list.SystemConfigProxy) { + return fmt.Errorf("SystemConfig address doesn't match config") + } + + calldata, err := optimismPortalABI.Pack("initialize", l2OutputOracle, systemConfig, superchainConfigProxy) if err != nil { return err } args := []any{ - common.HexToAddress(list.OptimismPortalProxy.String()), - common.HexToAddress(implementations.OptimismPortal.Address.String()), + common.Address(list.OptimismPortalProxy), + common.Address(implementations.OptimismPortal.Address), calldata, } - proxyAdmin := common.HexToAddress(list.ProxyAdmin.String()) + proxyAdmin := common.Address(list.ProxyAdmin) if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { return err } @@ -310,80 +615,128 @@ func SystemConfig(batch *safe.Batch, implementations superchain.ImplementationLi return err } - systemConfigABI, err := bindings.SystemConfigMetaData.GetAbi() - if err != nil { - return err - } - - // If we want to be able to override these based on the values in the config, - // the logic below will need to be updated. Right now the logic prefers the - // on chain values over the offchain values. This to maintain backwards compatibility - // in the short term. - startBlock := big.NewInt(0) - batchInboxAddress := common.HexToAddress(chainConfig.BatchInboxAddr.String()) - - var gasPriceOracleOverhead, gasPriceOracleScalar *big.Int - var batcherHash common.Hash - var p2pSequencerAddress, finalSystemOwner common.Address - var l2GenesisBlockGasLimit uint64 - - if config != nil { - gasPriceOracleOverhead = new(big.Int).SetUint64(config.GasPriceOracleOverhead) - gasPriceOracleScalar = new(big.Int).SetUint64(config.GasPriceOracleScalar) - batcherHash = common.BytesToHash(config.BatchSenderAddress.Bytes()) - l2GenesisBlockGasLimit = uint64(config.L2GenesisBlockGasLimit) - startBlock = new(big.Int).SetUint64(config.SystemConfigStartBlock) - batchInboxAddress = config.BatchInboxAddress - p2pSequencerAddress = config.P2PSequencerAddress - finalSystemOwner = config.FinalSystemOwner - } else { - systemConfig, err := bindings.NewSystemConfigCaller(common.HexToAddress(chainConfig.SystemConfigAddr.String()), backend) - if err != nil { - return err - } - gasPriceOracleOverhead, err = systemConfig.Overhead(&bind.CallOpts{}) + // 2 Step Upgrade + { + storageSetterABI, err := bindings.StorageSetterMetaData.GetAbi() if err != nil { return err } - gasPriceOracleScalar, err = systemConfig.Scalar(&bind.CallOpts{}) - if err != nil { - return err + + startBlock := common.Hash{} + + if config != nil { + startBlock = common.BigToHash(new(big.Int).SetUint64(config.SystemConfigStartBlock)) } - batcherHash, err = systemConfig.BatcherHash(&bind.CallOpts{}) - if err != nil { - return err + + input := []bindings.StorageSetterSlot{ + // https://github.com/ethereum-optimism/optimism/blob/86a96023ffd04d119296dff095d02fff79fa15de/packages/contracts-bedrock/.storage-layout#L82-L83 + { + Key: common.Hash{}, + Value: common.Hash{}, + }, + // bytes32 public constant START_BLOCK_SLOT = bytes32(uint256(keccak256("systemconfig.startBlock")) - 1); + { + Key: common.HexToHash("0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f"), + Value: startBlock, + }, } - l2GenesisBlockGasLimit, err = systemConfig.GasLimit(&bind.CallOpts{}) + + calldata, err := storageSetterABI.Pack(method, input) if err != nil { return err } - // StartBlock is a new property, we want to explicitly set it to 0 if there is an error fetching it - systemConfigStartBlock, err := systemConfig.StartBlock(&bind.CallOpts{}) - if err != nil && systemConfigStartBlock != nil { - startBlock = systemConfigStartBlock - } - // BatchInboxAddress is a new property, we want to set it to the offchain value if there is an error fetching it - systemConfigBatchInboxAddress, err := systemConfig.BatchInbox(&bind.CallOpts{}) - if err != nil && systemConfigBatchInboxAddress != (common.Address{}) { - batchInboxAddress = systemConfigBatchInboxAddress - } - p2pSequencerAddress, err = systemConfig.UnsafeBlockSigner(&bind.CallOpts{}) - if err != nil { - return err + args := []any{ + common.Address(list.SystemConfigProxy), + storageSetterAddr, + calldata, } - finalSystemOwner, err = systemConfig.Owner(&bind.CallOpts{}) - if err != nil { + proxyAdmin := common.Address(list.ProxyAdmin) + if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { return err } } - addresses := bindings.SystemConfigAddresses{ - L1CrossDomainMessenger: common.HexToAddress(list.L1CrossDomainMessengerProxy.String()), - L1ERC721Bridge: common.HexToAddress(list.L1ERC721BridgeProxy.String()), - L1StandardBridge: common.HexToAddress(list.L1StandardBridgeProxy.String()), - L2OutputOracle: common.HexToAddress(list.L2OutputOracleProxy.String()), - OptimismPortal: common.HexToAddress(list.OptimismPortalProxy.String()), - OptimismMintableERC20Factory: common.HexToAddress(list.OptimismMintableERC20FactoryProxy.String()), + systemConfigABI, err := bindings.SystemConfigMetaData.GetAbi() + if err != nil { + return err + } + + systemConfig, err := bindings.NewSystemConfigCaller(common.Address(list.SystemConfigProxy), backend) + if err != nil { + return err + } + + gasPriceOracleOverhead, err := systemConfig.Overhead(&bind.CallOpts{}) + if err != nil { + return err + } + + gasPriceOracleScalar, err := systemConfig.Scalar(&bind.CallOpts{}) + if err != nil { + return err + } + + batcherHash, err := systemConfig.BatcherHash(&bind.CallOpts{}) + if err != nil { + return err + } + + l2GenesisBlockGasLimit, err := systemConfig.GasLimit(&bind.CallOpts{}) + if err != nil { + return err + } + + p2pSequencerAddress, err := systemConfig.UnsafeBlockSigner(&bind.CallOpts{}) + if err != nil { + return err + } + + finalSystemOwner, err := systemConfig.Owner(&bind.CallOpts{}) + if err != nil { + return err + } + + if gasPriceOracleOverhead.Uint64() != config.GasPriceOracleOverhead { + return fmt.Errorf("GasPriceOracleOverhead address doesn't match config") + } + if gasPriceOracleScalar.Uint64() != config.GasPriceOracleScalar { + return fmt.Errorf("GasPriceOracleScalar address doesn't match config") + } + if batcherHash != common.BytesToHash(config.BatchSenderAddress.Bytes()) { + return fmt.Errorf("BatchSenderAddress address doesn't match config") + } + if l2GenesisBlockGasLimit != uint64(config.L2GenesisBlockGasLimit) { + return fmt.Errorf("L2GenesisBlockGasLimit address doesn't match config") + } + if p2pSequencerAddress != config.P2PSequencerAddress { + return fmt.Errorf("P2PSequencerAddress address doesn't match config") + } + if finalSystemOwner != config.FinalSystemOwner { + return fmt.Errorf("FinalSystemOwner address doesn't match config") + } + + resourceConfig, err := systemConfig.ResourceConfig(&bind.CallOpts{}) + if err != nil { + return err + } + + if resourceConfig.MaxResourceLimit != genesis.DefaultResourceConfig.MaxResourceLimit { + return fmt.Errorf("DefaultResourceConfig MaxResourceLimit doesn't match contract MaxResourceLimit") + } + if resourceConfig.ElasticityMultiplier != genesis.DefaultResourceConfig.ElasticityMultiplier { + return fmt.Errorf("DefaultResourceConfig ElasticityMultiplier doesn't match contract ElasticityMultiplier") + } + if resourceConfig.BaseFeeMaxChangeDenominator != genesis.DefaultResourceConfig.BaseFeeMaxChangeDenominator { + return fmt.Errorf("DefaultResourceConfig BaseFeeMaxChangeDenominator doesn't match contract BaseFeeMaxChangeDenominator") + } + if resourceConfig.MinimumBaseFee != genesis.DefaultResourceConfig.MinimumBaseFee { + return fmt.Errorf("DefaultResourceConfig MinimumBaseFee doesn't match contract MinimumBaseFee") + } + if resourceConfig.SystemTxMaxGas != genesis.DefaultResourceConfig.SystemTxMaxGas { + return fmt.Errorf("DefaultResourceConfig SystemTxMaxGas doesn't match contract SystemTxMaxGas") + } + if resourceConfig.MaximumBaseFee.Cmp(genesis.DefaultResourceConfig.MaximumBaseFee) != 0 { + return fmt.Errorf("DefaultResourceConfig MaximumBaseFee doesn't match contract MaximumBaseFee") } calldata, err := systemConfigABI.Pack( @@ -395,21 +748,27 @@ func SystemConfig(batch *safe.Batch, implementations superchain.ImplementationLi l2GenesisBlockGasLimit, p2pSequencerAddress, genesis.DefaultResourceConfig, - startBlock, - batchInboxAddress, - addresses, + chainConfig.BatchInboxAddr, + bindings.SystemConfigAddresses{ + L1CrossDomainMessenger: common.Address(list.L1CrossDomainMessengerProxy), + L1ERC721Bridge: common.Address(list.L1ERC721BridgeProxy), + L1StandardBridge: common.Address(list.L1StandardBridgeProxy), + L2OutputOracle: common.Address(list.L2OutputOracleProxy), + OptimismPortal: common.Address(list.OptimismPortalProxy), + OptimismMintableERC20Factory: common.Address(list.OptimismMintableERC20FactoryProxy), + }, ) if err != nil { return err } args := []any{ - common.HexToAddress(chainConfig.SystemConfigAddr.String()), - common.HexToAddress(implementations.SystemConfig.Address.String()), + common.Address(list.SystemConfigProxy), + common.Address(implementations.SystemConfig.Address), calldata, } - proxyAdmin := common.HexToAddress(list.ProxyAdmin.String()) + proxyAdmin := common.Address(list.ProxyAdmin) if err := batch.AddCall(proxyAdmin, common.Big0, upgradeAndCall, args, proxyAdminABI); err != nil { return err } diff --git a/op-challenger/Makefile b/op-challenger/Makefile index eadb663e88cd..ef58c35a728b 100644 --- a/op-challenger/Makefile +++ b/op-challenger/Makefile @@ -10,6 +10,9 @@ LDFLAGS := -ldflags "$(LDFLAGSSTRING)" op-challenger: env GO111MODULE=on GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) go build -v $(LDFLAGS) -o ./bin/op-challenger ./cmd +fuzz: + go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzKeccak ./game/keccak/matrix + clean: rm bin/op-challenger @@ -19,20 +22,8 @@ test: visualize: ./scripts/visualize.sh -alphabet: - ./scripts/alphabet/init_game.sh - make alphabet-actors - -alphabet-actors: - @./scripts/parallel.sh \ - ./scripts/alphabet/mallory.sh 'mallory' \ - ./scripts/alphabet/charlie.sh 'charlie' - .PHONY: \ - clean \ op-challenger \ + clean \ test \ - lint \ - visualize \ - alphabet \ - alphabet-actors + visualize diff --git a/op-challenger/README.md b/op-challenger/README.md index d3bdc9039ee6..3d740dc5703e 100644 --- a/op-challenger/README.md +++ b/op-challenger/README.md @@ -1,50 +1,43 @@ # op-challenger -The `op-challenger` is a modular **op-stack** challenge agent -written in golang for dispute games including, but not limited to, attestation games, fault -games, and validity games. To learn more about dispute games, visit the -[fault proof specs](../specs/fault-proof.md). +The `op-challenger` is a modular **op-stack** challenge agent written in +golang for dispute games including, but not limited to,attestation games, +fault games, and validity games. To learn more about dispute games, visit +the [fault proof specs][proof-specs]. -## Quickstart - -First, clone this repo. Then run: - -```shell -cd op-challenger -make alphabet -``` +[proof-specs]: https://specs.optimism.io/experimental/fault-proof/index.html -This creates a local devnet, starts a dispute game using the simple alphabet trace type and runs two op-challenger -instances with differing views of the correct alphabet to play the game. +## Quickstart -Alternatively, you can build the `op-challenger` binary directly using the pre-configured -[Makefile](./Makefile) target by running `make build`, and then running `./bin/op-challenger --help` -to see a list of available options. +To build the `op-challenger`, run `make` (which executes the `make build` +[Makefile](./Makefile) target). To view a list of available commands and +options, run `./bin/op-challenger --help`. ## Usage -`op-challenger` is configurable via command line flags and environment variables. The help menu -shows the available config options and can be accessed by running `./op-challenger --help`. +`op-challenger` is configurable via command line flags and environment +variables. The help menu shows the available config options and can be +accessed by running `./op-challenger --help`. ### Running with Cannon on Local Devnet -To run `op-challenger` against the local devnet, first ensure the required components are built and the devnet is running. -From the top level of the repository run: - +To run `op-challenger` against the local devnet, first clean and run +the devnet from the root of the repository. ```shell make devnet-clean -make cannon-prestate op-challenger make devnet-up ``` -Then start `op-challenger` with: +Then build the `op-challenger` with `make op-challenger`. + +Run the `op-challenger` with: ```shell DISPUTE_GAME_FACTORY=$(jq -r .DisputeGameFactoryProxy .devnet/addresses.json) ./op-challenger/bin/op-challenger \ --trace-type cannon \ --l1-eth-rpc http://localhost:8545 \ + --rollup-rpc http://localhost:9546 \ --game-factory-address $DISPUTE_GAME_FACTORY \ - --agree-with-proposed-output=true \ --datadir temp/challenger-data \ --cannon-rollup-config .devnet/rollup.json \ --cannon-l2-genesis .devnet/genesis-l2.json \ @@ -57,74 +50,61 @@ DISPUTE_GAME_FACTORY=$(jq -r .DisputeGameFactoryProxy .devnet/addresses.json) --num-confirmations 1 ``` -The mnemonic and hd-path above is a prefunded address on the devnet. The challenger respond to any created games by -posting the correct trace as the counter-claim. The scripts below can then be used to create and interact with games. - -## Scripts +The mnemonic and hd-path above is a prefunded address on the devnet. +The challenger will monitor dispute games and respond to any invalid +claims by posting the correct trace as the counter-claim. The commands +below can then be used to create and interact with games. -The [scripts](scripts) directory contains a collection of scripts to assist with manually creating and playing games. -This are not intended to be used in production, only to support manual testing and to aid with understanding how -dispute games work. They also serve as examples of how to use `cast` to manually interact with the dispute game -contracts. +## Subcommands -### Understanding Revert Reasons +The `op-challenger` has a few subcommands to interact with on-chain +fault dispute games. The subcommands support game creation, performing +game moves, and viewing fault dispute game data. They should not be +used in production and are intended to provide convenient manual testing. -When actions performed by these scripts fails, they typically print a message that includes the -abi encoded revert reason provided by the contract. e.g. - -``` -Error: -(code: 3, message: execution reverted, data: Some(String("0x67fe1950"))) -``` - -The `cast 4byte` command can be used to decode these revert reasons. e.g. +### create-game ```shell -$ cast 4byte 0x67fe1950 -GameNotInProgress() +./bin/op-challenger create-game \ + --l1-eth-rpc \ + --game-address \ + --output-root \ + --l2-block-num \ + ... ``` -### Dependencies - -These scripts assume that the following tools are installed and available on the current `PATH`: - -* `cast` (https://book.getfoundry.sh/cast/) -* `jq` (https://jqlang.github.io/jq/) -* `bash` +Starts a new fault dispute game that disputes the latest output proposal +in the L2 output oracle. -### [create_game.sh](scripts/create_game.sh) - -```shell -./scripts/create_game.sh ... -``` - -Starts a new fault dispute game that disputes the latest output proposal in the L2 output oracle. - -* `RPC_URL` - the RPC endpoint of the L1 endpoint to use (e.g. `http://localhost:8545`). +* `L1_ETH_RPC` - the RPC endpoint of the L1 endpoint to use (e.g. `http://localhost:8545`). * `GAME_FACTORY_ADDRESS` - the address of the dispute game factory contract on L1. -* `ROOT_CLAIM` a hex encoded 32 byte hash to use as the root claim for the created game. - * The root claim must have the high-order byte set to the - invalid [VM status](../specs/cannon-fault-proof-vm.md#state-hash) (`0x01`) to indicate that the trace concludes - that the disputed output root is invalid. - e.g. `0x0146381068b59d2098495baa72ed2f773c1e09458610a7a208984859dff73add` -* `SIGNER_ARGS` the remaining args are past as arguments to `cast` when sending transactions. - These arguments must specify a way for `cast` to sign the transactions. +* `OUTPUT_ROOT` a hex encoded 32 byte hash that is used as the proposed output root. +* `L2_BLOCK_NUM` the L2 block number the proposed output root is from. +* `SIGNER_ARGS` the remaining args are past as arguments to `cast` when sending + transactions. These arguments must specify a way for `cast` to sign the transactions. See `cast send --help` for supported options. -Creating a dispute game requires sending two transactions. The first transaction creates a -checkpoint in the `BlockOracle` that records the L1 block that will be used as the L1 head -when generating the cannon execution trace. The second transaction then creates the actual -dispute game, specifying the disputed L2 block number and previously checkpointed L1 head block. +Optionally, you may specify the game type (aka "trace type") using the `--trace-type` +flag, which is set to the cannon trace type by default. + +### move -### [move.sh](scripts/move.sh) +The `move` subcommand can be run with either the `--attack` or `--defend` flag, +but not both. ```shell -./scripts/move.sh (attack|defend) ... +./bin/op-challenger move \ + --l1-eth-rpc \ + --game-address \ + --attack \ + --parent-index \ + --claim \ + ... ``` Performs a move to either attack or defend the latest claim in the specified game. -* `RPC_URL` - the RPC endpoint of the L1 endpoint to use (e.g. `http://localhost:8545`). +* `L1_ETH_RPC` - the RPC endpoint of the L1 endpoint to use (e.g. `http://localhost:8545`). * `GAME_ADDRESS` - the address of the dispute game to perform the move in. * `(attack|defend)` - the type of move to make. * `attack` indicates that the state hash in your local cannon trace differs to the state @@ -138,40 +118,47 @@ Performs a move to either attack or defend the latest claim in the specified gam These arguments must specify a way for `cast` to sign the transactions. See `cast send --help` for supported options. -### [resolve.sh](scripts/resolve.sh) +### resolve ```shell -./scripts/resolve.sh ... +./bin/op-challenger resolve \ + --l1-eth-rpc \ + --game-address \ + ... ``` -Resolves a dispute game. Note that this will fail if the dispute game has already been resolved -or if the clocks have not yet expired and further moves are possible. +Resolves a dispute game. Note that this will fail if the dispute game has already +been resolved or if the clocks have not yet expired and further moves are possible. If the game is resolved successfully, the result is printed. -* `RPC_URL` - the RPC endpoint of the L1 endpoint to use (e.g. `http://localhost:8545`). +* `L1_ETH_RPC` - the RPC endpoint of the L1 endpoint to use (e.g. `http://localhost:8545`). * `GAME_ADDRESS` - the address of the dispute game to resolve. * `SIGNER_ARGS` the remaining args are past as arguments to `cast` when sending transactions. These arguments must specify a way for `cast` to sign the transactions. See `cast send --help` for supported options. -### [list_games.sh](scripts/list_games.sh) +### list-games ```shell -./scripts/list_games.sh +./bin/op-challenger list-games \ + --l1-eth-rpc \ + --game-factory-address ``` Prints the games created by the game factory along with their current status. -* `RPC_URL` - the RPC endpoint of the L1 endpoint to use (e.g. `http://localhost:8545`). +* `L1_ETH_RPC` - the RPC endpoint of the L1 endpoint to use (e.g. `http://localhost:8545`). * `GAME_FACTORY_ADDRESS` - the address of the dispute game factory contract on L1. -### [list_claims.sh](scripts/list_claims.sh) +### list-claims ```shell -./scripts/list_claims.sh +./bin/op-challenger list-games \ + --l1-eth-rpc \ + --game-address ``` Prints the list of current claims in a dispute game. -* `RPC_URL` - the RPC endpoint of the L1 endpoint to use (e.g. `http://localhost:8545`). +* `L1_ETH_RPC` - the RPC endpoint of the L1 endpoint to use (e.g. `http://localhost:8545`). * `GAME_ADDRESS` - the address of the dispute game to list the move in. diff --git a/op-challenger/challenger.go b/op-challenger/challenger.go index d6b118fc73d4..574f27fc74ec 100644 --- a/op-challenger/challenger.go +++ b/op-challenger/challenger.go @@ -2,22 +2,18 @@ package op_challenger import ( "context" - "fmt" + + "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/game" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/cliapp" ) -// Main is the programmatic entry-point for running op-challenger -func Main(ctx context.Context, logger log.Logger, cfg *config.Config) error { +// Main is the programmatic entry-point for running op-challenger with a given configuration. +func Main(ctx context.Context, logger log.Logger, cfg *config.Config) (cliapp.Lifecycle, error) { if err := cfg.Check(); err != nil { - return err + return nil, err } - service, err := game.NewService(ctx, logger, cfg) - if err != nil { - return fmt.Errorf("failed to create the fault service: %w", err) - } - - return service.MonitorGame(ctx) + return game.NewService(ctx, logger, cfg) } diff --git a/op-challenger/challenger_test.go b/op-challenger/challenger_test.go index 617c7affefe9..666e656e2c0f 100644 --- a/op-challenger/challenger_test.go +++ b/op-challenger/challenger_test.go @@ -12,6 +12,7 @@ import ( func TestMainShouldReturnErrorWhenConfigInvalid(t *testing.T) { cfg := &config.Config{} - err := Main(context.Background(), testlog.Logger(t, log.LvlInfo), cfg) + app, err := Main(context.Background(), testlog.Logger(t, log.LevelInfo), cfg) require.ErrorIs(t, err, cfg.Check()) + require.Nil(t, app) } diff --git a/op-challenger/cmd/create_game.go b/op-challenger/cmd/create_game.go new file mode 100644 index 000000000000..7053b4eee3a8 --- /dev/null +++ b/op-challenger/cmd/create_game.go @@ -0,0 +1,85 @@ +package main + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-challenger/config" + "github.com/ethereum-optimism/optimism/op-challenger/flags" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + opservice "github.com/ethereum-optimism/optimism/op-service" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli/v2" +) + +var ( + TraceTypeFlag = &cli.StringFlag{ + Name: "trace-type", + Usage: "Trace types to support.", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "TRACE_TYPE"), + Value: config.TraceTypeCannon.String(), + } + OutputRootFlag = &cli.StringFlag{ + Name: "output-root", + Usage: "The output root for the fault dispute game.", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "OUTPUT_ROOT"), + } + L2BlockNumFlag = &cli.StringFlag{ + Name: "l2-block-num", + Usage: "The l2 block number for the game.", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "L2_BLOCK_NUM"), + } +) + +func CreateGame(ctx *cli.Context) error { + outputRoot := common.HexToHash(ctx.String(OutputRootFlag.Name)) + traceType := ctx.Uint64(TraceTypeFlag.Name) + l2BlockNum := ctx.Uint64(L2BlockNumFlag.Name) + + contract, txMgr, err := NewContractWithTxMgr[*contracts.DisputeGameFactoryContract](ctx, flags.FactoryAddressFlag.Name, contracts.NewDisputeGameFactoryContract) + if err != nil { + return fmt.Errorf("failed to create dispute game factory bindings: %w", err) + } + + txCandidate, err := contract.CreateTx(uint32(traceType), outputRoot, l2BlockNum) + if err != nil { + return fmt.Errorf("failed to create tx: %w", err) + } + + rct, err := txMgr.Send(context.Background(), txCandidate) + if err != nil { + return fmt.Errorf("failed to send tx: %w", err) + } + fmt.Printf("Sent create transaction with status %v, tx_hash: %s\n", rct.Status, rct.TxHash.String()) + + fetchedGameAddr, err := contract.GetGameFromParameters(context.Background(), uint32(traceType), outputRoot, l2BlockNum) + if err != nil { + return fmt.Errorf("failed to call games: %w", err) + } + fmt.Printf("Fetched Game Address: %s\n", fetchedGameAddr.String()) + + return nil +} + +func createGameFlags() []cli.Flag { + cliFlags := []cli.Flag{ + flags.L1EthRpcFlag, + flags.FactoryAddressFlag, + OutputRootFlag, + L2BlockNumFlag, + } + cliFlags = append(cliFlags, txmgr.CLIFlagsWithDefaults(flags.EnvVarPrefix, txmgr.DefaultChallengerFlagValues)...) + cliFlags = append(cliFlags, oplog.CLIFlags(flags.EnvVarPrefix)...) + return cliFlags +} + +var CreateGameCommand = &cli.Command{ + Name: "create-game", + Usage: "Creates a dispute game via the factory", + Description: "Creates a dispute game via the factory", + Action: CreateGame, + Flags: createGameFlags(), + Hidden: true, +} diff --git a/op-challenger/cmd/list_claims.go b/op-challenger/cmd/list_claims.go new file mode 100644 index 000000000000..6fb51a7e1bb7 --- /dev/null +++ b/op-challenger/cmd/list_claims.go @@ -0,0 +1,103 @@ +package main + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-challenger/flags" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/dial" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/urfave/cli/v2" +) + +var ( + GameAddressFlag = &cli.StringFlag{ + Name: "game-address", + Usage: "Address of the fault game contract.", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "GAME_ADDRESS"), + } +) + +func ListClaims(ctx *cli.Context) error { + logger, err := setupLogging(ctx) + if err != nil { + return err + } + rpcUrl := ctx.String(flags.L1EthRpcFlag.Name) + if rpcUrl == "" { + return fmt.Errorf("missing %v", flags.L1EthRpcFlag.Name) + } + gameAddr, err := opservice.ParseAddress(ctx.String(GameAddressFlag.Name)) + if err != nil { + return err + } + + l1Client, err := dial.DialEthClientWithTimeout(ctx.Context, dial.DefaultDialTimeout, logger, rpcUrl) + if err != nil { + return fmt.Errorf("failed to dial L1: %w", err) + } + defer l1Client.Close() + + caller := batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize) + contract, err := contracts.NewFaultDisputeGameContract(gameAddr, caller) + if err != nil { + return fmt.Errorf("failed to create dispute game bindings: %w", err) + } + return listClaims(ctx.Context, contract) +} + +func listClaims(ctx context.Context, game *contracts.FaultDisputeGameContract) error { + maxDepth, err := game.GetMaxGameDepth(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve max depth: %w", err) + } + splitDepth, err := game.GetSplitDepth(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve split depth: %w", err) + } + status, err := game.GetStatus(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve status: %w", err) + } + _, l2BlockNum, err := game.GetBlockRange(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve status: %w", err) + } + + claims, err := game.GetAllClaims(ctx, rpcblock.Latest) + if err != nil { + return fmt.Errorf("failed to retrieve claims: %w", err) + } + + info := fmt.Sprintf("Claim count: %v\n", len(claims)) + for i, claim := range claims { + pos := claim.Position + info = info + fmt.Sprintf("%v - Position: %v, Depth: %v, IndexAtDepth: %v Trace Index: %v, Value: %v, Countered: %v, ParentIndex: %v\n", + i, pos.ToGIndex(), pos.Depth(), pos.IndexAtDepth(), pos.TraceIndex(maxDepth), claim.Value.Hex(), claim.CounteredBy, claim.ParentContractIndex) + } + fmt.Printf("Status: %v - L2 Block: %v - Split Depth: %v - Max Depth: %v:\n%v\n", + status, l2BlockNum, splitDepth, maxDepth, info) + return nil +} + +func listClaimsFlags() []cli.Flag { + cliFlags := []cli.Flag{ + flags.L1EthRpcFlag, + GameAddressFlag, + } + cliFlags = append(cliFlags, oplog.CLIFlags("OP_CHALLENGER")...) + return cliFlags +} + +var ListClaimsCommand = &cli.Command{ + Name: "list-claims", + Usage: "List the claims in a dispute game", + Description: "Lists the claims in a dispute game", + Action: ListClaims, + Flags: listClaimsFlags(), + Hidden: true, +} diff --git a/op-challenger/cmd/list_games.go b/op-challenger/cmd/list_games.go new file mode 100644 index 000000000000..ce7ddb13cde9 --- /dev/null +++ b/op-challenger/cmd/list_games.go @@ -0,0 +1,119 @@ +package main + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/ethereum-optimism/optimism/op-challenger/flags" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/dial" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli/v2" +) + +func ListGames(ctx *cli.Context) error { + logger, err := setupLogging(ctx) + if err != nil { + return err + } + rpcUrl := ctx.String(flags.L1EthRpcFlag.Name) + if rpcUrl == "" { + return fmt.Errorf("missing %v", flags.L1EthRpcFlag.Name) + } + factoryAddr, err := opservice.ParseAddress(ctx.String(flags.FactoryAddressFlag.Name)) + if err != nil { + return err + } + + l1Client, err := dial.DialEthClientWithTimeout(ctx.Context, dial.DefaultDialTimeout, logger, rpcUrl) + if err != nil { + return fmt.Errorf("failed to dial L1: %w", err) + } + defer l1Client.Close() + + caller := batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize) + contract, err := contracts.NewDisputeGameFactoryContract(factoryAddr, caller) + if err != nil { + return fmt.Errorf("failed to create dispute game bindings: %w", err) + } + head, err := l1Client.HeaderByNumber(ctx.Context, nil) + if err != nil { + return fmt.Errorf("failed to retrieve current head block: %w", err) + } + return listGames(ctx.Context, caller, contract, head.Hash()) +} + +type gameInfo struct { + types.GameMetadata + claimCount uint64 + status types.GameStatus + err error +} + +func listGames(ctx context.Context, caller *batching.MultiCaller, factory *contracts.DisputeGameFactoryContract, block common.Hash) error { + games, err := factory.GetAllGames(ctx, block) + if err != nil { + return fmt.Errorf("failed to retrieve games: %w", err) + } + + infos := make([]*gameInfo, len(games)) + var wg sync.WaitGroup + for idx, game := range games { + gameContract, err := contracts.NewFaultDisputeGameContract(game.Proxy, caller) + if err != nil { + return fmt.Errorf("failed to bind game contract at %v: %w", game.Proxy, err) + } + info := gameInfo{GameMetadata: game} + infos[idx] = &info + gameProxy := game.Proxy + wg.Add(1) + go func() { + defer wg.Done() + claimCount, err := gameContract.GetClaimCount(ctx) + if err != nil { + info.err = fmt.Errorf("failed to retrieve claim count for game %v: %w", gameProxy, err) + return + } + info.claimCount = claimCount + status, err := gameContract.GetStatus(ctx) + if err != nil { + info.err = fmt.Errorf("failed to retrieve status for game %v: %w", gameProxy, err) + return + } + info.status = status + }() + } + wg.Wait() + for idx, game := range infos { + if game.err != nil { + return err + } + fmt.Printf("%v Game: %v Type: %v Created: %v Claims: %v Status: %v\n", + idx, game.Proxy, game.GameType, time.Unix(int64(game.Timestamp), 0), game.claimCount, game.status) + } + return nil +} + +func listGamesFlags() []cli.Flag { + cliFlags := []cli.Flag{ + flags.L1EthRpcFlag, + flags.FactoryAddressFlag, + } + cliFlags = append(cliFlags, oplog.CLIFlags("OP_CHALLENGER")...) + return cliFlags +} + +var ListGamesCommand = &cli.Command{ + Name: "list-games", + Usage: "List the games created by a dispute game factory", + Description: "Lists the games created by a dispute game factory", + Action: ListGames, + Flags: listGamesFlags(), + Hidden: true, +} diff --git a/op-challenger/cmd/main.go b/op-challenger/cmd/main.go index 7909b834ba9f..292959049dbd 100644 --- a/op-challenger/cmd/main.go +++ b/op-challenger/cmd/main.go @@ -4,16 +4,18 @@ import ( "context" "os" - op_challenger "github.com/ethereum-optimism/optimism/op-challenger" - opservice "github.com/ethereum-optimism/optimism/op-service" - "github.com/ethereum/go-ethereum/log" "github.com/urfave/cli/v2" + "github.com/ethereum/go-ethereum/log" + + challenger "github.com/ethereum-optimism/optimism/op-challenger" "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/flags" "github.com/ethereum-optimism/optimism/op-challenger/version" + opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/opio" ) var ( @@ -26,14 +28,15 @@ var VersionWithMeta = opservice.FormatVersion(version.Version, GitCommit, GitDat func main() { args := os.Args - if err := run(args, op_challenger.Main); err != nil { + ctx := opio.WithInterruptBlocker(context.Background()) + if err := run(ctx, args, challenger.Main); err != nil { log.Crit("Application failed", "err", err) } } -type ConfigAction func(ctx context.Context, log log.Logger, config *config.Config) error +type ConfiguredLifecycle func(ctx context.Context, log log.Logger, config *config.Config) (cliapp.Lifecycle, error) -func run(args []string, action ConfigAction) error { +func run(ctx context.Context, args []string, action ConfiguredLifecycle) error { oplog.SetupDefaults() app := cli.NewApp() @@ -42,25 +45,32 @@ func run(args []string, action ConfigAction) error { app.Name = "op-challenger" app.Usage = "Challenge outputs" app.Description = "Ensures that on chain outputs are correct." - app.Action = func(ctx *cli.Context) error { + app.Commands = []*cli.Command{ + ListGamesCommand, + ListClaimsCommand, + CreateGameCommand, + MoveCommand, + ResolveCommand, + } + app.Action = cliapp.LifecycleCmd(func(ctx *cli.Context, close context.CancelCauseFunc) (cliapp.Lifecycle, error) { logger, err := setupLogging(ctx) if err != nil { - return err + return nil, err } logger.Info("Starting op-challenger", "version", VersionWithMeta) cfg, err := flags.NewConfigFromCLI(ctx) if err != nil { - return err + return nil, err } return action(ctx.Context, logger, cfg) - } - return app.Run(args) + }) + return app.RunContext(ctx, args) } func setupLogging(ctx *cli.Context) (log.Logger, error) { logCfg := oplog.ReadCLIConfig(ctx) logger := oplog.NewLogger(oplog.AppOut(ctx), logCfg) - oplog.SetGlobalLogHandler(logger.GetHandler()) + oplog.SetGlobalLogHandler(logger.Handler()) return logger, nil } diff --git a/op-challenger/cmd/main_test.go b/op-challenger/cmd/main_test.go index 6c48087985b7..d8d5e0d4bce0 100644 --- a/op-challenger/cmd/main_test.go +++ b/op-challenger/cmd/main_test.go @@ -2,19 +2,24 @@ package main import ( "context" + "errors" "fmt" "testing" "time" - "github.com/ethereum-optimism/optimism/op-challenger/config" - "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" - "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/op-challenger/config" + "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/txmgr" ) var ( l1EthRpc = "http://example.com:8545" + l1Beacon = "http://example.com:9000" gameFactoryAddressValue = "0xbb00000000000000000000000000000000000000" cannonNetwork = "op-mainnet" otherCannonNetwork = "op-goerli" @@ -24,8 +29,6 @@ var ( datadir = "./test_data" cannonL2 = "http://example.com:9545" rollupRpc = "http://example.com:8555" - alphabetTrace = "abcdefghijz" - agreeWithProposedOutput = "true" ) func TestLogLevel(t *testing.T) { @@ -36,7 +39,7 @@ func TestLogLevel(t *testing.T) { for _, lvl := range []string{"trace", "debug", "info", "error", "crit"} { lvl := lvl t.Run("AcceptValid_"+lvl, func(t *testing.T) { - logger, _, err := runWithArgs(addRequiredArgs(config.TraceTypeAlphabet, "--log.level", lvl)) + logger, _, err := dryRunWithArgs(addRequiredArgs(config.TraceTypeAlphabet, "--log.level", lvl)) require.NoError(t, err) require.NotNil(t, logger) }) @@ -45,17 +48,17 @@ func TestLogLevel(t *testing.T) { func TestDefaultCLIOptionsMatchDefaultConfig(t *testing.T) { cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet)) - defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, true, datadir, config.TraceTypeAlphabet) + defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, datadir, config.TraceTypeAlphabet) // Add in the extra CLI options required when using alphabet trace type - defaultCfg.AlphabetTrace = alphabetTrace + defaultCfg.RollupRpc = rollupRpc require.Equal(t, defaultCfg, cfg) } func TestDefaultConfigIsValid(t *testing.T) { - cfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, true, datadir, config.TraceTypeAlphabet) + cfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, datadir, config.TraceTypeAlphabet) // Add in options that are required based on the specific trace type // To avoid needing to specify unused options, these aren't included in the params for NewConfig - cfg.AlphabetTrace = alphabetTrace + cfg.RollupRpc = rollupRpc require.NoError(t, cfg.Check()) } @@ -72,9 +75,23 @@ func TestL1ETHRPCAddress(t *testing.T) { }) } -func TestTraceType(t *testing.T) { +func TestL1Beacon(t *testing.T) { t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag trace-type is required", addRequiredArgsExcept("", "--trace-type")) + verifyArgsInvalid(t, "flag l1-beacon is required", addRequiredArgsExcept(config.TraceTypeAlphabet, "--l1-beacon")) + }) + + t.Run("Valid", func(t *testing.T) { + url := "http://example.com:8888" + cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--l1-beacon", "--l1-beacon="+url)) + require.Equal(t, url, cfg.L1Beacon) + }) +} + +func TestTraceType(t *testing.T) { + t.Run("Default", func(t *testing.T) { + expectedDefault := config.TraceTypeCannon + cfg := configForArgs(t, addRequiredArgsExcept(expectedDefault, "--trace-type")) + require.Equal(t, []config.TraceType{expectedDefault}, cfg.TraceTypes) }) for _, traceType := range config.TraceTypes { @@ -93,19 +110,19 @@ func TestTraceType(t *testing.T) { func TestMultipleTraceTypes(t *testing.T) { t.Run("WithAllOptions", func(t *testing.T) { argsMap := requiredArgs(config.TraceTypeCannon) - addRequiredOutputCannonArgs(argsMap) - addRequiredAlphabetArgs(argsMap) + addRequiredOutputArgs(argsMap) args := toArgList(argsMap) // Add extra trace types (cannon is already specified) args = append(args, - "--trace-type", config.TraceTypeOutputCannon.String(), "--trace-type", config.TraceTypeAlphabet.String()) + args = append(args, + "--trace-type", config.TraceTypePermissioned.String()) cfg := configForArgs(t, args) - require.Equal(t, []config.TraceType{config.TraceTypeCannon, config.TraceTypeOutputCannon, config.TraceTypeAlphabet}, cfg.TraceTypes) + require.Equal(t, []config.TraceType{config.TraceTypeCannon, config.TraceTypeAlphabet, config.TraceTypePermissioned}, cfg.TraceTypes) }) t.Run("WithSomeOptions", func(t *testing.T) { argsMap := requiredArgs(config.TraceTypeCannon) - addRequiredAlphabetArgs(argsMap) + addRequiredOutputArgs(argsMap) args := toArgList(argsMap) // Add extra trace types (cannon is already specified) args = append(args, @@ -164,24 +181,6 @@ func TestTxManagerFlagsSupported(t *testing.T) { require.Equal(t, uint64(7), cfg.TxMgrConfig.NumConfirmations) } -func TestAgreeWithProposedOutput(t *testing.T) { - t.Run("MustBeProvided", func(t *testing.T) { - verifyArgsInvalid(t, "flag agree-with-proposed-output is required", addRequiredArgsExcept(config.TraceTypeAlphabet, "--agree-with-proposed-output")) - }) - t.Run("Enabled", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--agree-with-proposed-output")) - require.True(t, cfg.AgreeWithProposedOutput) - }) - t.Run("EnabledWithArg", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--agree-with-proposed-output=true")) - require.True(t, cfg.AgreeWithProposedOutput) - }) - t.Run("Disabled", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--agree-with-proposed-output=false")) - require.False(t, cfg.AgreeWithProposedOutput) - }) -} - func TestMaxConcurrency(t *testing.T) { t.Run("Valid", func(t *testing.T) { expected := uint(345) @@ -204,6 +203,26 @@ func TestMaxConcurrency(t *testing.T) { }) } +func TestMaxPendingTx(t *testing.T) { + t.Run("Valid", func(t *testing.T) { + expected := uint64(345) + cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--max-pending-tx", "345")) + require.Equal(t, expected, cfg.MaxPendingTx) + }) + + t.Run("Zero", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--max-pending-tx", "0")) + require.Equal(t, uint64(0), cfg.MaxPendingTx) + }) + + t.Run("Invalid", func(t *testing.T) { + verifyArgsInvalid( + t, + "invalid value \"abc\" for flag -max-pending-tx", + addRequiredArgs(config.TraceTypeAlphabet, "--max-pending-tx", "abc")) + }) +} + func TestPollInterval(t *testing.T) { t.Run("UsesDefault", func(t *testing.T) { cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon)) @@ -224,131 +243,193 @@ func TestPollInterval(t *testing.T) { }) } -func TestCannonBin(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-bin")) - }) +func TestCannonRequiredArgs(t *testing.T) { + for _, traceType := range []config.TraceType{config.TraceTypeCannon, config.TraceTypePermissioned} { + traceType := traceType + t.Run(fmt.Sprintf("TestCannonBin-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-bin")) + }) + + t.Run("Required", func(t *testing.T) { + verifyArgsInvalid(t, "flag cannon-bin is required", addRequiredArgsExcept(traceType, "--cannon-bin")) + }) + + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-bin", "--cannon-bin=./cannon")) + require.Equal(t, "./cannon", cfg.CannonBin) + }) + }) - t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag cannon-bin is required", addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-bin")) - }) + t.Run(fmt.Sprintf("TestCannonServer-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-server")) + }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-bin", "--cannon-bin=./cannon")) - require.Equal(t, "./cannon", cfg.CannonBin) - }) -} + t.Run("Required", func(t *testing.T) { + verifyArgsInvalid(t, "flag cannon-server is required", addRequiredArgsExcept(traceType, "--cannon-server")) + }) -func TestCannonServer(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-server")) - }) + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-server", "--cannon-server=./op-program")) + require.Equal(t, "./op-program", cfg.CannonServer) + }) + }) - t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag cannon-server is required", addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-server")) - }) + t.Run(fmt.Sprintf("TestCannonAbsolutePrestate-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-prestate")) + }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-server", "--cannon-server=./op-program")) - require.Equal(t, "./op-program", cfg.CannonServer) - }) -} + t.Run("Required", func(t *testing.T) { + verifyArgsInvalid(t, "flag cannon-prestate is required", addRequiredArgsExcept(traceType, "--cannon-prestate")) + }) -func TestCannonAbsolutePrestate(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-prestate")) - }) + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-prestate", "--cannon-prestate=./pre.json")) + require.Equal(t, "./pre.json", cfg.CannonAbsolutePreState) + }) + }) - t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag cannon-prestate is required", addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-prestate")) - }) + t.Run(fmt.Sprintf("TestCannonL2-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-l2")) + }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-prestate", "--cannon-prestate=./pre.json")) - require.Equal(t, "./pre.json", cfg.CannonAbsolutePreState) - }) -} + t.Run("RequiredForCannonTrace", func(t *testing.T) { + verifyArgsInvalid(t, "flag cannon-l2 is required", addRequiredArgsExcept(traceType, "--cannon-l2")) + }) -func TestDataDir(t *testing.T) { - t.Run("RequiredForAlphabetTrace", func(t *testing.T) { - verifyArgsInvalid(t, "flag datadir is required", addRequiredArgsExcept(config.TraceTypeAlphabet, "--datadir")) - }) + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(traceType)) + require.Equal(t, cannonL2, cfg.CannonL2) + }) + }) - t.Run("RequiredForCannonTrace", func(t *testing.T) { - verifyArgsInvalid(t, "flag datadir is required", addRequiredArgsExcept(config.TraceTypeCannon, "--datadir")) - }) + t.Run(fmt.Sprintf("TestCannonSnapshotFreq-%v", traceType), func(t *testing.T) { + t.Run("UsesDefault", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(traceType)) + require.Equal(t, config.DefaultCannonSnapshotFreq, cfg.CannonSnapshotFreq) + }) + + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(traceType, "--cannon-snapshot-freq=1234")) + require.Equal(t, uint(1234), cfg.CannonSnapshotFreq) + }) + + t.Run("Invalid", func(t *testing.T) { + verifyArgsInvalid(t, "invalid value \"abc\" for flag -cannon-snapshot-freq", + addRequiredArgs(traceType, "--cannon-snapshot-freq=abc")) + }) + }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--datadir", "--datadir=/foo/bar/cannon")) - require.Equal(t, "/foo/bar/cannon", cfg.Datadir) - }) -} + t.Run(fmt.Sprintf("TestCannonInfoFreq-%v", traceType), func(t *testing.T) { + t.Run("UsesDefault", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(traceType)) + require.Equal(t, config.DefaultCannonInfoFreq, cfg.CannonInfoFreq) + }) + + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(traceType, "--cannon-info-freq=1234")) + require.Equal(t, uint(1234), cfg.CannonInfoFreq) + }) + + t.Run("Invalid", func(t *testing.T) { + verifyArgsInvalid(t, "invalid value \"abc\" for flag -cannon-info-freq", + addRequiredArgs(traceType, "--cannon-info-freq=abc")) + }) + }) -func TestRollupRpc(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--rollup-rpc")) - }) + t.Run(fmt.Sprintf("TestRequireEitherCannonNetworkOrRollupAndGenesis-%v", traceType), func(t *testing.T) { + verifyArgsInvalid( + t, + "flag cannon-network or cannon-rollup-config and cannon-l2-genesis is required", + addRequiredArgsExcept(traceType, "--cannon-network")) + verifyArgsInvalid( + t, + "flag cannon-network or cannon-rollup-config and cannon-l2-genesis is required", + addRequiredArgsExcept(traceType, "--cannon-network", "--cannon-rollup-config=rollup.json")) + verifyArgsInvalid( + t, + "flag cannon-network or cannon-rollup-config and cannon-l2-genesis is required", + addRequiredArgsExcept(traceType, "--cannon-network", "--cannon-l2-genesis=gensis.json")) + }) - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--rollup-rpc")) - }) + t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndRollup-%v", traceType), func(t *testing.T) { + verifyArgsInvalid( + t, + "flag cannon-network can not be used with cannon-rollup-config and cannon-l2-genesis", + addRequiredArgsExcept(traceType, "--cannon-network", + "--cannon-network", cannonNetwork, "--cannon-rollup-config=rollup.json")) + }) - t.Run("RequiredForOutputCannonTrace", func(t *testing.T) { - verifyArgsInvalid(t, "flag rollup-rpc is required", addRequiredArgsExcept(config.TraceTypeOutputCannon, "--rollup-rpc")) - }) + t.Run(fmt.Sprintf("TestCannonNetwork-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-network")) + }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(config.TraceTypeOutputCannon)) - require.Equal(t, rollupRpc, cfg.RollupRpc) - }) -} + t.Run("NotRequiredWhenRollupAndGenesIsSpecified", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-network", + "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) + }) -func TestCannonL2(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-l2")) - }) + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-network", "--cannon-network", otherCannonNetwork)) + require.Equal(t, otherCannonNetwork, cfg.CannonNetwork) + }) + }) - t.Run("RequiredForCannonTrace", func(t *testing.T) { - verifyArgsInvalid(t, "flag cannon-l2 is required", addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-l2")) - }) + t.Run(fmt.Sprintf("TestCannonRollupConfig-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-rollup-config")) + }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon)) - require.Equal(t, cannonL2, cfg.CannonL2) - }) + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) + require.Equal(t, "rollup.json", cfg.CannonRollupConfigPath) + }) + }) + + t.Run(fmt.Sprintf("TestCannonL2Genesis-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-l2-genesis")) + }) + + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) + require.Equal(t, "genesis.json", cfg.CannonL2GenesisPath) + }) + }) + } } -func TestCannonSnapshotFreq(t *testing.T) { - t.Run("UsesDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon)) - require.Equal(t, config.DefaultCannonSnapshotFreq, cfg.CannonSnapshotFreq) - }) +func TestDataDir(t *testing.T) { + for _, traceType := range config.TraceTypes { + traceType := traceType - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon, "--cannon-snapshot-freq=1234")) - require.Equal(t, uint(1234), cfg.CannonSnapshotFreq) - }) + t.Run(fmt.Sprintf("RequiredFor-%v", traceType), func(t *testing.T) { + verifyArgsInvalid(t, "flag datadir is required", addRequiredArgsExcept(traceType, "--datadir")) + }) + } - t.Run("Invalid", func(t *testing.T) { - verifyArgsInvalid(t, "invalid value \"abc\" for flag -cannon-snapshot-freq", - addRequiredArgs(config.TraceTypeCannon, "--cannon-snapshot-freq=abc")) + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--datadir", "--datadir=/foo/bar/cannon")) + require.Equal(t, "/foo/bar/cannon", cfg.Datadir) }) } -func TestCannonInfoFreq(t *testing.T) { - t.Run("UsesDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon)) - require.Equal(t, config.DefaultCannonInfoFreq, cfg.CannonInfoFreq) - }) +func TestRollupRpc(t *testing.T) { + for _, traceType := range config.TraceTypes { + traceType := traceType - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon, "--cannon-info-freq=1234")) - require.Equal(t, uint(1234), cfg.CannonInfoFreq) - }) + t.Run(fmt.Sprintf("RequiredFor-%v", traceType), func(t *testing.T) { + verifyArgsInvalid(t, "flag rollup-rpc is required", addRequiredArgsExcept(traceType, "--rollup-rpc")) + }) + } - t.Run("Invalid", func(t *testing.T) { - verifyArgsInvalid(t, "invalid value \"abc\" for flag -cannon-info-freq", - addRequiredArgs(config.TraceTypeCannon, "--cannon-info-freq=abc")) + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon)) + require.Equal(t, rollupRpc, cfg.RollupRpc) }) } @@ -364,92 +445,95 @@ func TestGameWindow(t *testing.T) { }) t.Run("ParsesDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--game-window=264h")) + cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--game-window=360h")) require.Equal(t, config.DefaultGameWindow, cfg.GameWindow) }) } -func TestRequireEitherCannonNetworkOrRollupAndGenesis(t *testing.T) { - verifyArgsInvalid( - t, - "flag cannon-network or cannon-rollup-config and cannon-l2-genesis is required", - addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-network")) - verifyArgsInvalid( - t, - "flag cannon-network or cannon-rollup-config and cannon-l2-genesis is required", - addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-network", "--cannon-rollup-config=rollup.json")) - verifyArgsInvalid( - t, - "flag cannon-network or cannon-rollup-config and cannon-l2-genesis is required", - addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-network", "--cannon-l2-genesis=gensis.json")) -} - -func TestMustNotSpecifyNetworkAndRollup(t *testing.T) { - verifyArgsInvalid( - t, - "flag cannon-network can not be used with cannon-rollup-config and cannon-l2-genesis", - addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-network", - "--cannon-network", cannonNetwork, "--cannon-rollup-config=rollup.json")) -} +func TestUnsafeAllowInvalidPrestate(t *testing.T) { + t.Run("DefaultsToFalse", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--unsafe-allow-invalid-prestate")) + require.False(t, cfg.AllowInvalidPrestate) + }) -func TestCannonNetwork(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-network")) + t.Run("EnabledWithNoValue", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon, "--unsafe-allow-invalid-prestate")) + require.True(t, cfg.AllowInvalidPrestate) }) - t.Run("NotRequiredWhenRollupAndGenesIsSpecified", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-network", - "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) + t.Run("EnabledWithTrue", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon, "--unsafe-allow-invalid-prestate=true")) + require.True(t, cfg.AllowInvalidPrestate) }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-network", "--cannon-network", otherCannonNetwork)) - require.Equal(t, otherCannonNetwork, cfg.CannonNetwork) + t.Run("DisabledWithFalse", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon, "--unsafe-allow-invalid-prestate=false")) + require.False(t, cfg.AllowInvalidPrestate) }) } -func TestCannonRollupConfig(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-rollup-config")) +func TestAdditionalBondClaimants(t *testing.T) { + t.Run("DefaultsToEmpty", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--additional-bond-claimants")) + require.Empty(t, cfg.AdditionalBondClaimants) }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) - require.Equal(t, "rollup.json", cfg.CannonRollupConfigPath) + t.Run("Valid-Single", func(t *testing.T) { + claimant := common.Address{0xaa} + cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--additional-bond-claimants", claimant.Hex())) + require.Contains(t, cfg.AdditionalBondClaimants, claimant) + require.Len(t, cfg.AdditionalBondClaimants, 1) }) -} -func TestCannonL2Genesis(t *testing.T) { - t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-l2-genesis")) + t.Run("Valid-Multiple", func(t *testing.T) { + claimant1 := common.Address{0xaa} + claimant2 := common.Address{0xbb} + claimant3 := common.Address{0xcc} + cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, + "--additional-bond-claimants", fmt.Sprintf("%v,%v,%v", claimant1.Hex(), claimant2.Hex(), claimant3.Hex()))) + require.Contains(t, cfg.AdditionalBondClaimants, claimant1) + require.Contains(t, cfg.AdditionalBondClaimants, claimant2) + require.Contains(t, cfg.AdditionalBondClaimants, claimant3) + require.Len(t, cfg.AdditionalBondClaimants, 3) }) - t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--cannon-network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) - require.Equal(t, "genesis.json", cfg.CannonL2GenesisPath) + t.Run("Invalid-Single", func(t *testing.T) { + verifyArgsInvalid(t, "invalid additional claimant", + addRequiredArgs(config.TraceTypeAlphabet, "--additional-bond-claimants", "nope")) + }) + + t.Run("Invalid-Multiple", func(t *testing.T) { + claimant1 := common.Address{0xaa} + claimant2 := common.Address{0xbb} + verifyArgsInvalid(t, "invalid additional claimant", + addRequiredArgs(config.TraceTypeAlphabet, "--additional-bond-claimants", fmt.Sprintf("%v,nope,%v", claimant1.Hex(), claimant2.Hex()))) }) } func verifyArgsInvalid(t *testing.T, messageContains string, cliArgs []string) { - _, _, err := runWithArgs(cliArgs) + _, _, err := dryRunWithArgs(cliArgs) require.ErrorContains(t, err, messageContains) } func configForArgs(t *testing.T, cliArgs []string) config.Config { - _, cfg, err := runWithArgs(cliArgs) + _, cfg, err := dryRunWithArgs(cliArgs) require.NoError(t, err) return cfg } -func runWithArgs(cliArgs []string) (log.Logger, config.Config, error) { +func dryRunWithArgs(cliArgs []string) (log.Logger, config.Config, error) { cfg := new(config.Config) var logger log.Logger fullArgs := append([]string{"op-challenger"}, cliArgs...) - err := run(fullArgs, func(ctx context.Context, log log.Logger, config *config.Config) error { + testErr := errors.New("dry-run") + err := run(context.Background(), fullArgs, func(ctx context.Context, log log.Logger, config *config.Config) (cliapp.Lifecycle, error) { logger = log cfg = config - return nil + return nil, testErr }) + if errors.Is(err, testErr) { // expected error + err = nil + } return logger, *cfg, err } @@ -467,38 +551,32 @@ func addRequiredArgsExcept(traceType config.TraceType, name string, optionalArgs func requiredArgs(traceType config.TraceType) map[string]string { args := map[string]string{ - "--agree-with-proposed-output": agreeWithProposedOutput, - "--l1-eth-rpc": l1EthRpc, - "--game-factory-address": gameFactoryAddressValue, - "--trace-type": traceType.String(), - "--datadir": datadir, + "--l1-eth-rpc": l1EthRpc, + "--l1-beacon": l1Beacon, + "--game-factory-address": gameFactoryAddressValue, + "--trace-type": traceType.String(), + "--datadir": datadir, } switch traceType { - case config.TraceTypeAlphabet: - addRequiredAlphabetArgs(args) - case config.TraceTypeCannon: + case config.TraceTypeCannon, config.TraceTypePermissioned: addRequiredCannonArgs(args) - case config.TraceTypeOutputCannon: - addRequiredOutputCannonArgs(args) + case config.TraceTypeAlphabet: + addRequiredOutputArgs(args) } return args } -func addRequiredAlphabetArgs(args map[string]string) { - args["--alphabet"] = alphabetTrace -} - -func addRequiredOutputCannonArgs(args map[string]string) { - addRequiredCannonArgs(args) - args["--rollup-rpc"] = rollupRpc -} - func addRequiredCannonArgs(args map[string]string) { args["--cannon-network"] = cannonNetwork args["--cannon-bin"] = cannonBin args["--cannon-server"] = cannonServer args["--cannon-prestate"] = cannonPreState args["--cannon-l2"] = cannonL2 + addRequiredOutputArgs(args) +} + +func addRequiredOutputArgs(args map[string]string) { + args["--rollup-rpc"] = rollupRpc } func toArgList(req map[string]string) []string { diff --git a/op-challenger/cmd/move.go b/op-challenger/cmd/move.go new file mode 100644 index 000000000000..a0854319ee7c --- /dev/null +++ b/op-challenger/cmd/move.go @@ -0,0 +1,99 @@ +package main + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-challenger/flags" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + opservice "github.com/ethereum-optimism/optimism/op-service" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli/v2" +) + +var ( + AttackFlag = &cli.BoolFlag{ + Name: "attack", + Usage: "An attack move. If true, the defend flag must not be set.", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "ATTACK"), + } + DefendFlag = &cli.BoolFlag{ + Name: "defend", + Usage: "A defending move. If true, the attack flag must not be set.", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "DEFEND"), + } + ParentIndexFlag = &cli.StringFlag{ + Name: "parent-index", + Usage: "The index of the claim to move on.", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "PARENT_INDEX"), + } + ClaimFlag = &cli.StringFlag{ + Name: "claim", + Usage: "The claim hash.", + EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "CLAIM"), + } +) + +func Move(ctx *cli.Context) error { + attack := ctx.Bool(AttackFlag.Name) + defend := ctx.Bool(DefendFlag.Name) + parentIndex := ctx.Uint64(ParentIndexFlag.Name) + claim := common.HexToHash(ctx.String(ClaimFlag.Name)) + + if attack && defend { + return fmt.Errorf("both attack and defense flags cannot be set") + } + + contract, txMgr, err := NewContractWithTxMgr[*contracts.FaultDisputeGameContract](ctx, GameAddressFlag.Name, contracts.NewFaultDisputeGameContract) + if err != nil { + return fmt.Errorf("failed to create dispute game bindings: %w", err) + } + + var tx txmgr.TxCandidate + if attack { + tx, err = contract.AttackTx(parentIndex, claim) + if err != nil { + return fmt.Errorf("failed to create attack tx: %w", err) + } + } else if defend { + tx, err = contract.DefendTx(parentIndex, claim) + if err != nil { + return fmt.Errorf("failed to create defense tx: %w", err) + } + } else { + return fmt.Errorf("either attack or defense flag must be set") + } + + rct, err := txMgr.Send(context.Background(), tx) + if err != nil { + return fmt.Errorf("failed to send tx: %w", err) + } + fmt.Printf("Sent tx with status: %v, hash: %s\n", rct.Status, rct.TxHash.String()) + + return nil +} + +func moveFlags() []cli.Flag { + cliFlags := []cli.Flag{ + flags.L1EthRpcFlag, + GameAddressFlag, + AttackFlag, + DefendFlag, + ParentIndexFlag, + ClaimFlag, + } + cliFlags = append(cliFlags, txmgr.CLIFlagsWithDefaults(flags.EnvVarPrefix, txmgr.DefaultChallengerFlagValues)...) + cliFlags = append(cliFlags, oplog.CLIFlags(flags.EnvVarPrefix)...) + return cliFlags +} + +var MoveCommand = &cli.Command{ + Name: "move", + Usage: "Creates and sends a move transaction to the dispute game", + Description: "Creates and sends a move transaction to the dispute game", + Action: Move, + Flags: moveFlags(), + Hidden: true, +} diff --git a/op-challenger/cmd/resolve.go b/op-challenger/cmd/resolve.go new file mode 100644 index 000000000000..5cbddffcbed3 --- /dev/null +++ b/op-challenger/cmd/resolve.go @@ -0,0 +1,52 @@ +package main + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-challenger/flags" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/urfave/cli/v2" +) + +func Resolve(ctx *cli.Context) error { + contract, txMgr, err := NewContractWithTxMgr[*contracts.FaultDisputeGameContract](ctx, GameAddressFlag.Name, contracts.NewFaultDisputeGameContract) + if err != nil { + return fmt.Errorf("failed to create dispute game bindings: %w", err) + } + + tx, err := contract.ResolveTx() + if err != nil { + return fmt.Errorf("failed to create resolve tx: %w", err) + } + + rct, err := txMgr.Send(context.Background(), tx) + if err != nil { + return fmt.Errorf("failed to send tx: %w", err) + } + + fmt.Printf("Sent resolve tx with status: %v, hash: %s\n", rct.Status, rct.TxHash.String()) + + return nil +} + +func resolveFlags() []cli.Flag { + cliFlags := []cli.Flag{ + flags.L1EthRpcFlag, + GameAddressFlag, + } + cliFlags = append(cliFlags, txmgr.CLIFlagsWithDefaults(flags.EnvVarPrefix, txmgr.DefaultChallengerFlagValues)...) + cliFlags = append(cliFlags, oplog.CLIFlags(flags.EnvVarPrefix)...) + return cliFlags +} + +var ResolveCommand = &cli.Command{ + Name: "resolve", + Usage: "Resolves the specified dispute game if possible", + Description: "Resolves the specified dispute game if possible", + Action: Resolve, + Flags: resolveFlags(), + Hidden: true, +} diff --git a/op-challenger/cmd/utils.go b/op-challenger/cmd/utils.go new file mode 100644 index 000000000000..e15a8bbd260d --- /dev/null +++ b/op-challenger/cmd/utils.go @@ -0,0 +1,76 @@ +package main + +import ( + "fmt" + + "github.com/ethereum-optimism/optimism/op-challenger/flags" + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli/v2" +) + +type ContractCreator[T any] func(common.Address, *batching.MultiCaller) (T, error) + +// NewContractWithTxMgr creates a new contract and a transaction manager. +func NewContractWithTxMgr[T any](ctx *cli.Context, flagName string, creator ContractCreator[T]) (T, txmgr.TxManager, error) { + var contract T + caller, txMgr, err := newClientsFromCLI(ctx) + if err != nil { + return contract, nil, err + } + + created, err := newContractFromCLI(ctx, flagName, caller, creator) + if err != nil { + return contract, nil, err + } + + return created, txMgr, nil +} + +// newContractFromCLI creates a new contract from the CLI context. +func newContractFromCLI[T any](ctx *cli.Context, flagName string, caller *batching.MultiCaller, creator ContractCreator[T]) (T, error) { + var contract T + gameAddr, err := opservice.ParseAddress(ctx.String(flagName)) + if err != nil { + return contract, err + } + + created, err := creator(gameAddr, caller) + if err != nil { + return contract, fmt.Errorf("failed to create dispute game bindings: %w", err) + } + + return created, nil +} + +// newClientsFromCLI creates a new caller and transaction manager from the CLI context. +func newClientsFromCLI(ctx *cli.Context) (*batching.MultiCaller, txmgr.TxManager, error) { + logger, err := setupLogging(ctx) + if err != nil { + return nil, nil, err + } + + rpcUrl := ctx.String(flags.L1EthRpcFlag.Name) + if rpcUrl == "" { + return nil, nil, fmt.Errorf("missing %v", flags.L1EthRpcFlag.Name) + } + + l1Client, err := dial.DialEthClientWithTimeout(ctx.Context, dial.DefaultDialTimeout, logger, rpcUrl) + if err != nil { + return nil, nil, fmt.Errorf("failed to dial L1: %w", err) + } + defer l1Client.Close() + + caller := batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize) + txMgrConfig := txmgr.ReadCLIConfig(ctx) + txMgr, err := txmgr.NewSimpleTxManager("challenger", logger, &metrics.NoopTxMetrics{}, txMgrConfig) + if err != nil { + return nil, nil, fmt.Errorf("failed to create the transaction manager: %w", err) + } + + return caller, txMgr, nil +} diff --git a/op-challenger/config/config.go b/op-challenger/config/config.go index 801a7433e3fd..d13c716b803f 100644 --- a/op-challenger/config/config.go +++ b/op-challenger/config/config.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/chaincfg" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) @@ -23,8 +23,8 @@ var ( ErrMissingCannonBin = errors.New("missing cannon bin") ErrMissingCannonServer = errors.New("missing cannon server") ErrMissingCannonAbsolutePreState = errors.New("missing cannon absolute pre-state") - ErrMissingAlphabetTrace = errors.New("missing alphabet trace") ErrMissingL1EthRPC = errors.New("missing l1 eth rpc url") + ErrMissingL1Beacon = errors.New("missing l1 beacon url") ErrMissingGameFactoryAddress = errors.New("missing game factory address") ErrMissingCannonSnapshotFreq = errors.New("missing cannon snapshot freq") ErrMissingCannonInfoFreq = errors.New("missing cannon info freq") @@ -41,22 +41,10 @@ type TraceType string const ( TraceTypeAlphabet TraceType = "alphabet" TraceTypeCannon TraceType = "cannon" - TraceTypeOutputCannon TraceType = "output_cannon" - - // Mainnet games - CannonFaultGameID = 0 - - // Devnet games - AlphabetFaultGameID = 255 + TraceTypePermissioned TraceType = "permissioned" ) -var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon, TraceTypeOutputCannon} - -// GameIdToString maps game IDs to their string representation. -var GameIdToString = map[uint8]string{ - CannonFaultGameID: "Cannon", - AlphabetFaultGameID: "Alphabet", -} +var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon, TraceTypePermissioned} func (t TraceType) String() string { return string(t) @@ -91,28 +79,31 @@ const ( DefaultCannonInfoFreq = uint(10_000_000) // DefaultGameWindow is the default maximum time duration in the past // that the challenger will look for games to progress. - // The default value is 11 days, which is a 4 day resolution buffer - // plus the 7 day game finalization window. - DefaultGameWindow = time.Duration(11 * 24 * time.Hour) + // The default value is 15 days, which is an 8 day resolution buffer + // and bond claiming buffer plus the 7 day game finalization window. + DefaultGameWindow = time.Duration(15 * 24 * time.Hour) + DefaultMaxPendingTx = 10 ) // Config is a well typed config that is parsed from the CLI params. // This also contains config options for auxiliary services. // It is used to initialize the challenger. type Config struct { - L1EthRpc string // L1 RPC Url - GameFactoryAddress common.Address // Address of the dispute game factory - GameAllowlist []common.Address // Allowlist of fault game addresses - GameWindow time.Duration // Maximum time duration to look for games to progress - AgreeWithProposedOutput bool // Temporary config if we agree or disagree with the posted output - Datadir string // Data Directory - MaxConcurrency uint // Maximum number of threads to use when progressing games - PollInterval time.Duration // Polling interval for latest-block subscription when using an HTTP RPC provider + L1EthRpc string // L1 RPC Url + L1Beacon string // L1 Beacon API Url + GameFactoryAddress common.Address // Address of the dispute game factory + GameAllowlist []common.Address // Allowlist of fault game addresses + GameWindow time.Duration // Maximum time duration to look for games to progress + Datadir string // Data Directory + MaxConcurrency uint // Maximum number of threads to use when progressing games + PollInterval time.Duration // Polling interval for latest-block subscription when using an HTTP RPC provider + AllowInvalidPrestate bool // Whether to allow responding to games where the prestate does not match - TraceTypes []TraceType // Type of traces supported + AdditionalBondClaimants []common.Address // List of addresses to claim bonds for in addition to the tx manager sender + + SelectiveClaimResolution bool // Whether to only resolve claims for the claimants in AdditionalBondClaimants union [TxSender.From()] - // Specific to the alphabet trace provider - AlphabetTrace string // String for the AlphabetTraceProvider + TraceTypes []TraceType // Type of traces supported // Specific to the output cannon trace type RollupRpc string @@ -128,6 +119,8 @@ type Config struct { CannonSnapshotFreq uint // Frequency of snapshots to create when executing cannon (in VM instructions) CannonInfoFreq uint // Frequency of cannon progress log messages (in VM instructions) + MaxPendingTx uint64 // Maximum number of pending transactions (0 == no limit) + TxMgrConfig txmgr.CLIConfig MetricsConfig opmetrics.CLIConfig PprofConfig oppprof.CLIConfig @@ -136,20 +129,21 @@ type Config struct { func NewConfig( gameFactoryAddress common.Address, l1EthRpc string, - agreeWithProposedOutput bool, + l1BeaconApi string, datadir string, supportedTraceTypes ...TraceType, ) Config { return Config{ L1EthRpc: l1EthRpc, + L1Beacon: l1BeaconApi, GameFactoryAddress: gameFactoryAddress, MaxConcurrency: uint(runtime.NumCPU()), PollInterval: DefaultPollInterval, - AgreeWithProposedOutput: agreeWithProposedOutput, - TraceTypes: supportedTraceTypes, + MaxPendingTx: DefaultMaxPendingTx, + TxMgrConfig: txmgr.NewCLIConfig(l1EthRpc, txmgr.DefaultChallengerFlagValues), MetricsConfig: opmetrics.DefaultCLIConfig(), PprofConfig: oppprof.DefaultCLIConfig(), @@ -170,6 +164,12 @@ func (c Config) Check() error { if c.L1EthRpc == "" { return ErrMissingL1EthRPC } + if c.L1Beacon == "" { + return ErrMissingL1Beacon + } + if c.RollupRpc == "" { + return ErrMissingRollupRpc + } if c.GameFactoryAddress == (common.Address{}) { return ErrMissingGameFactoryAddress } @@ -182,12 +182,7 @@ func (c Config) Check() error { if c.MaxConcurrency == 0 { return ErrMaxConcurrencyZero } - if c.TraceTypeEnabled(TraceTypeOutputCannon) { - if c.RollupRpc == "" { - return ErrMissingRollupRpc - } - } - if c.TraceTypeEnabled(TraceTypeCannon) || c.TraceTypeEnabled(TraceTypeOutputCannon) { + if c.TraceTypeEnabled(TraceTypeCannon) || c.TraceTypeEnabled(TraceTypePermissioned) { if c.CannonBin == "" { return ErrMissingCannonBin } @@ -225,9 +220,6 @@ func (c Config) Check() error { return ErrMissingCannonInfoFreq } } - if c.TraceTypeEnabled(TraceTypeAlphabet) && c.AlphabetTrace == "" { - return ErrMissingAlphabetTrace - } if err := c.TxMgrConfig.Check(); err != nil { return err } diff --git a/op-challenger/config/config_test.go b/op-challenger/config/config_test.go index c5d32db2eaa0..01210557c60d 100644 --- a/op-challenger/config/config_test.go +++ b/op-challenger/config/config_test.go @@ -1,6 +1,7 @@ package config import ( + "fmt" "runtime" "testing" @@ -12,8 +13,8 @@ import ( var ( validL1EthRpc = "http://localhost:8545" + validL1BeaconUrl = "http://localhost:9000" validGameFactoryAddress = common.Address{0x23} - validAlphabetTrace = "abcdefgh" validCannonBin = "./bin/cannon" validCannonOpProgramBin = "./bin/op-program" validCannonNetwork = "mainnet" @@ -21,24 +22,20 @@ var ( validDatadir = "/tmp/data" validCannonL2 = "http://localhost:9545" validRollupRpc = "http://localhost:8555" - agreeWithProposedOutput = true ) +var cannonTraceTypes = []TraceType{TraceTypeCannon, TraceTypePermissioned} + func validConfig(traceType TraceType) Config { - cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, agreeWithProposedOutput, validDatadir, traceType) - switch traceType { - case TraceTypeAlphabet: - cfg.AlphabetTrace = validAlphabetTrace - case TraceTypeCannon, TraceTypeOutputCannon: + cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, validL1BeaconUrl, validDatadir, traceType) + if traceType == TraceTypeCannon || traceType == TraceTypePermissioned { cfg.CannonBin = validCannonBin cfg.CannonServer = validCannonOpProgramBin cfg.CannonAbsolutePreState = validCannonAbsolutPreState cfg.CannonL2 = validCannonL2 cfg.CannonNetwork = validCannonNetwork } - if traceType == TraceTypeOutputCannon { - cfg.RollupRpc = validRollupRpc - } + cfg.RollupRpc = validRollupRpc return cfg } @@ -67,40 +64,112 @@ func TestL1EthRpcRequired(t *testing.T) { require.ErrorIs(t, config.Check(), ErrMissingL1EthRPC) } +func TestL1BeaconRequired(t *testing.T) { + config := validConfig(TraceTypeCannon) + config.L1Beacon = "" + require.ErrorIs(t, config.Check(), ErrMissingL1Beacon) +} + func TestGameFactoryAddressRequired(t *testing.T) { config := validConfig(TraceTypeCannon) config.GameFactoryAddress = common.Address{} require.ErrorIs(t, config.Check(), ErrMissingGameFactoryAddress) } +func TestSelectiveClaimResolutionNotRequired(t *testing.T) { + config := validConfig(TraceTypeCannon) + require.Equal(t, false, config.SelectiveClaimResolution) + require.NoError(t, config.Check()) +} + func TestGameAllowlistNotRequired(t *testing.T) { config := validConfig(TraceTypeCannon) config.GameAllowlist = []common.Address{} require.NoError(t, config.Check()) } -func TestAlphabetTraceRequired(t *testing.T) { - config := validConfig(TraceTypeAlphabet) - config.AlphabetTrace = "" - require.ErrorIs(t, config.Check(), ErrMissingAlphabetTrace) -} +func TestCannonRequiredArgs(t *testing.T) { + for _, traceType := range cannonTraceTypes { + traceType := traceType -func TestCannonBinRequired(t *testing.T) { - config := validConfig(TraceTypeCannon) - config.CannonBin = "" - require.ErrorIs(t, config.Check(), ErrMissingCannonBin) -} + t.Run(fmt.Sprintf("TestCannonBinRequired-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.CannonBin = "" + require.ErrorIs(t, config.Check(), ErrMissingCannonBin) + }) -func TestCannonServerRequired(t *testing.T) { - config := validConfig(TraceTypeCannon) - config.CannonServer = "" - require.ErrorIs(t, config.Check(), ErrMissingCannonServer) -} + t.Run(fmt.Sprintf("TestCannonServerRequired-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.CannonServer = "" + require.ErrorIs(t, config.Check(), ErrMissingCannonServer) + }) -func TestCannonAbsolutePreStateRequired(t *testing.T) { - config := validConfig(TraceTypeCannon) - config.CannonAbsolutePreState = "" - require.ErrorIs(t, config.Check(), ErrMissingCannonAbsolutePreState) + t.Run(fmt.Sprintf("TestCannonAbsolutePreStateRequired-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.CannonAbsolutePreState = "" + require.ErrorIs(t, config.Check(), ErrMissingCannonAbsolutePreState) + }) + + t.Run(fmt.Sprintf("TestCannonL2Required-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.CannonL2 = "" + require.ErrorIs(t, config.Check(), ErrMissingCannonL2) + }) + + t.Run(fmt.Sprintf("TestCannonSnapshotFreq-%v", traceType), func(t *testing.T) { + t.Run("MustNotBeZero", func(t *testing.T) { + cfg := validConfig(traceType) + cfg.CannonSnapshotFreq = 0 + require.ErrorIs(t, cfg.Check(), ErrMissingCannonSnapshotFreq) + }) + }) + + t.Run(fmt.Sprintf("TestCannonInfoFreq-%v", traceType), func(t *testing.T) { + t.Run("MustNotBeZero", func(t *testing.T) { + cfg := validConfig(traceType) + cfg.CannonInfoFreq = 0 + require.ErrorIs(t, cfg.Check(), ErrMissingCannonInfoFreq) + }) + }) + + t.Run(fmt.Sprintf("TestCannonNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) { + cfg := validConfig(traceType) + cfg.CannonNetwork = "" + cfg.CannonRollupConfigPath = "" + cfg.CannonL2GenesisPath = "genesis.json" + require.ErrorIs(t, cfg.Check(), ErrMissingCannonRollupConfig) + }) + + t.Run(fmt.Sprintf("TestCannonNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) { + cfg := validConfig(traceType) + cfg.CannonNetwork = "" + cfg.CannonRollupConfigPath = "foo.json" + cfg.CannonL2GenesisPath = "" + require.ErrorIs(t, cfg.Check(), ErrMissingCannonL2Genesis) + }) + + t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndRollup-%v", traceType), func(t *testing.T) { + cfg := validConfig(traceType) + cfg.CannonNetwork = validCannonNetwork + cfg.CannonRollupConfigPath = "foo.json" + cfg.CannonL2GenesisPath = "" + require.ErrorIs(t, cfg.Check(), ErrCannonNetworkAndRollupConfig) + }) + + t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndL2Genesis-%v", traceType), func(t *testing.T) { + cfg := validConfig(traceType) + cfg.CannonNetwork = validCannonNetwork + cfg.CannonRollupConfigPath = "" + cfg.CannonL2GenesisPath = "foo.json" + require.ErrorIs(t, cfg.Check(), ErrCannonNetworkAndL2Genesis) + }) + + t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) { + cfg := validConfig(traceType) + cfg.CannonNetwork = "unknown" + require.ErrorIs(t, cfg.Check(), ErrCannonNetworkUnknown) + }) + } } func TestDatadirRequired(t *testing.T) { @@ -130,90 +199,29 @@ func TestHttpPollInterval(t *testing.T) { } func TestRollupRpcRequired(t *testing.T) { - config := validConfig(TraceTypeOutputCannon) - config.RollupRpc = "" - require.ErrorIs(t, config.Check(), ErrMissingRollupRpc) -} - -func TestCannonL2Required(t *testing.T) { - config := validConfig(TraceTypeCannon) - config.CannonL2 = "" - require.ErrorIs(t, config.Check(), ErrMissingCannonL2) -} - -func TestCannonSnapshotFreq(t *testing.T) { - t.Run("MustNotBeZero", func(t *testing.T) { - cfg := validConfig(TraceTypeCannon) - cfg.CannonSnapshotFreq = 0 - require.ErrorIs(t, cfg.Check(), ErrMissingCannonSnapshotFreq) - }) -} - -func TestCannonInfoFreq(t *testing.T) { - t.Run("MustNotBeZero", func(t *testing.T) { - cfg := validConfig(TraceTypeCannon) - cfg.CannonInfoFreq = 0 - require.ErrorIs(t, cfg.Check(), ErrMissingCannonInfoFreq) - }) -} - -func TestCannonNetworkOrRollupConfigRequired(t *testing.T) { - cfg := validConfig(TraceTypeCannon) - cfg.CannonNetwork = "" - cfg.CannonRollupConfigPath = "" - cfg.CannonL2GenesisPath = "genesis.json" - require.ErrorIs(t, cfg.Check(), ErrMissingCannonRollupConfig) -} - -func TestCannonNetworkOrL2GenesisRequired(t *testing.T) { - cfg := validConfig(TraceTypeCannon) - cfg.CannonNetwork = "" - cfg.CannonRollupConfigPath = "foo.json" - cfg.CannonL2GenesisPath = "" - require.ErrorIs(t, cfg.Check(), ErrMissingCannonL2Genesis) -} - -func TestMustNotSpecifyNetworkAndRollup(t *testing.T) { - cfg := validConfig(TraceTypeCannon) - cfg.CannonNetwork = validCannonNetwork - cfg.CannonRollupConfigPath = "foo.json" - cfg.CannonL2GenesisPath = "" - require.ErrorIs(t, cfg.Check(), ErrCannonNetworkAndRollupConfig) -} - -func TestMustNotSpecifyNetworkAndL2Genesis(t *testing.T) { - cfg := validConfig(TraceTypeCannon) - cfg.CannonNetwork = validCannonNetwork - cfg.CannonRollupConfigPath = "" - cfg.CannonL2GenesisPath = "foo.json" - require.ErrorIs(t, cfg.Check(), ErrCannonNetworkAndL2Genesis) -} - -func TestNetworkMustBeValid(t *testing.T) { - cfg := validConfig(TraceTypeCannon) - cfg.CannonNetwork = "unknown" - require.ErrorIs(t, cfg.Check(), ErrCannonNetworkUnknown) + for _, traceType := range TraceTypes { + traceType := traceType + t.Run(traceType.String(), func(t *testing.T) { + config := validConfig(traceType) + config.RollupRpc = "" + require.ErrorIs(t, config.Check(), ErrMissingRollupRpc) + }) + } } -func TestRequireConfigForAllSupportedTraceTypes(t *testing.T) { +func TestRequireConfigForMultipleTraceTypes(t *testing.T) { cfg := validConfig(TraceTypeCannon) - cfg.TraceTypes = []TraceType{TraceTypeCannon, TraceTypeOutputCannon, TraceTypeAlphabet} + cfg.TraceTypes = []TraceType{TraceTypeCannon, TraceTypeAlphabet} // Set all required options and check its valid cfg.RollupRpc = validRollupRpc - cfg.AlphabetTrace = validAlphabetTrace require.NoError(t, cfg.Check()) - // Require output cannon specific args - cfg.RollupRpc = "" - require.ErrorIs(t, cfg.Check(), ErrMissingRollupRpc) - cfg.RollupRpc = validRollupRpc - // Require cannon specific args cfg.CannonL2 = "" require.ErrorIs(t, cfg.Check(), ErrMissingCannonL2) cfg.CannonL2 = validCannonL2 - // Require alphabet specific args - cfg.AlphabetTrace = "" - require.ErrorIs(t, cfg.Check(), ErrMissingAlphabetTrace) + // Require output cannon specific args + cfg.RollupRpc = "" + require.ErrorIs(t, cfg.Check(), ErrMissingRollupRpc) } diff --git a/op-challenger/flags/flags.go b/op-challenger/flags/flags.go index 4704cde41bfb..718cd5c00b20 100644 --- a/op-challenger/flags/flags.go +++ b/op-challenger/flags/flags.go @@ -15,16 +15,14 @@ import ( openum "github.com/ethereum-optimism/optimism/op-service/enum" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) -const ( - envVarPrefix = "OP_CHALLENGER" -) +const EnvVarPrefix = "OP_CHALLENGER" func prefixEnvVars(name string) []string { - return opservice.PrefixEnvVar(envVarPrefix, name) + return opservice.PrefixEnvVar(EnvVarPrefix, name) } var ( @@ -34,6 +32,16 @@ var ( Usage: "HTTP provider URL for L1.", EnvVars: prefixEnvVars("L1_ETH_RPC"), } + L1BeaconFlag = &cli.StringFlag{ + Name: "l1-beacon", + Usage: "Address of L1 Beacon API endpoint to use", + EnvVars: prefixEnvVars("L1_BEACON"), + } + RollupRpcFlag = &cli.StringFlag{ + Name: "rollup-rpc", + Usage: "HTTP provider URL for the rollup node", + EnvVars: prefixEnvVars("ROLLUP_RPC"), + } FactoryAddressFlag = &cli.StringFlag{ Name: "game-factory-address", Usage: "Address of the fault game factory contract.", @@ -49,11 +57,7 @@ var ( Name: "trace-type", Usage: "The trace types to support. Valid options: " + openum.EnumString(config.TraceTypes), EnvVars: prefixEnvVars("TRACE_TYPE"), - } - AgreeWithProposedOutputFlag = &cli.BoolFlag{ - Name: "agree-with-proposed-output", - Usage: "Temporary hardcoded flag if we agree or disagree with the proposed output.", - EnvVars: prefixEnvVars("AGREE_WITH_PROPOSED_OUTPUT"), + Value: cli.NewStringSlice(config.TraceTypeCannon.String()), } DatadirFlag = &cli.StringFlag{ Name: "datadir", @@ -67,21 +71,22 @@ var ( EnvVars: prefixEnvVars("MAX_CONCURRENCY"), Value: uint(runtime.NumCPU()), } + MaxPendingTransactionsFlag = &cli.Uint64Flag{ + Name: "max-pending-tx", + Usage: "The maximum number of pending transactions. 0 for no limit.", + Value: config.DefaultMaxPendingTx, + EnvVars: prefixEnvVars("MAX_PENDING_TX"), + } HTTPPollInterval = &cli.DurationFlag{ Name: "http-poll-interval", Usage: "Polling interval for latest-block subscription when using an HTTP RPC provider.", EnvVars: prefixEnvVars("HTTP_POLL_INTERVAL"), Value: config.DefaultPollInterval, } - RollupRpcFlag = &cli.StringFlag{ - Name: "rollup-rpc", - Usage: "HTTP provider URL for the rollup node", - EnvVars: prefixEnvVars("ROLLUP_RPC"), - } - AlphabetFlag = &cli.StringFlag{ - Name: "alphabet", - Usage: "Correct Alphabet Trace (alphabet trace type only)", - EnvVars: prefixEnvVars("ALPHABET"), + AdditionalBondClaimants = &cli.StringSliceFlag{ + Name: "additional-bond-claimants", + Usage: "List of addresses to claim bonds for, in addition to the configured transaction sender", + EnvVars: prefixEnvVars("ADDITIONAL_BOND_CLAIMANTS"), } CannonNetworkFlag = &cli.StringFlag{ Name: "cannon-network", @@ -134,28 +139,41 @@ var ( Value: config.DefaultCannonInfoFreq, } GameWindowFlag = &cli.DurationFlag{ - Name: "game-window", - Usage: "The time window which the challenger will look for games to progress.", + Name: "game-window", + Usage: "The time window which the challenger will look for games to progress and claim bonds. " + + "This should include a buffer for the challenger to claim bonds for games outside the maximum game duration.", EnvVars: prefixEnvVars("GAME_WINDOW"), Value: config.DefaultGameWindow, } + SelectiveClaimResolutionFlag = &cli.BoolFlag{ + Name: "selective-claim-resolution", + Usage: "Only resolve claims for the configured claimants", + EnvVars: prefixEnvVars("SELECTIVE_CLAIM_RESOLUTION"), + } + UnsafeAllowInvalidPrestate = &cli.BoolFlag{ + Name: "unsafe-allow-invalid-prestate", + Usage: "Allow responding to games where the absolute prestate is configured incorrectly. THIS IS UNSAFE!", + EnvVars: prefixEnvVars("UNSAFE_ALLOW_INVALID_PRESTATE"), + Hidden: true, // Hidden as this is an unsafe flag added only for testing purposes + } ) // requiredFlags are checked by [CheckRequired] var requiredFlags = []cli.Flag{ L1EthRpcFlag, FactoryAddressFlag, - TraceTypeFlag, - AgreeWithProposedOutputFlag, DatadirFlag, + RollupRpcFlag, + L1BeaconFlag, } // optionalFlags is a list of unchecked cli flags var optionalFlags = []cli.Flag{ + TraceTypeFlag, MaxConcurrencyFlag, + MaxPendingTransactionsFlag, HTTPPollInterval, - RollupRpcFlag, - AlphabetFlag, + AdditionalBondClaimants, GameAllowlistFlag, CannonNetworkFlag, CannonRollupConfigFlag, @@ -167,13 +185,15 @@ var optionalFlags = []cli.Flag{ CannonSnapshotFreqFlag, CannonInfoFreqFlag, GameWindowFlag, + SelectiveClaimResolutionFlag, + UnsafeAllowInvalidPrestate, } func init() { - optionalFlags = append(optionalFlags, oplog.CLIFlags(envVarPrefix)...) - optionalFlags = append(optionalFlags, txmgr.CLIFlagsWithDefaults(envVarPrefix, txmgr.DefaultChallengerFlagValues)...) - optionalFlags = append(optionalFlags, opmetrics.CLIFlags(envVarPrefix)...) - optionalFlags = append(optionalFlags, oppprof.CLIFlags(envVarPrefix)...) + optionalFlags = append(optionalFlags, oplog.CLIFlags(EnvVarPrefix)...) + optionalFlags = append(optionalFlags, txmgr.CLIFlagsWithDefaults(EnvVarPrefix, txmgr.DefaultChallengerFlagValues)...) + optionalFlags = append(optionalFlags, opmetrics.CLIFlags(EnvVarPrefix)...) + optionalFlags = append(optionalFlags, oppprof.CLIFlags(EnvVarPrefix)...) Flags = append(requiredFlags, optionalFlags...) } @@ -215,21 +235,11 @@ func CheckRequired(ctx *cli.Context, traceTypes []config.TraceType) error { } for _, traceType := range traceTypes { switch traceType { - case config.TraceTypeCannon: + case config.TraceTypeCannon, config.TraceTypePermissioned: if err := CheckCannonFlags(ctx); err != nil { return err } case config.TraceTypeAlphabet: - if !ctx.IsSet(AlphabetFlag.Name) { - return fmt.Errorf("flag %s is required", "alphabet") - } - case config.TraceTypeOutputCannon: - if err := CheckCannonFlags(ctx); err != nil { - return err - } - if !ctx.IsSet(RollupRpcFlag.Name) { - return fmt.Errorf("flag %s is required", RollupRpcFlag.Name) - } default: return fmt.Errorf("invalid trace type. must be one of %v", config.TraceTypes) } @@ -283,30 +293,43 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) { if maxConcurrency == 0 { return nil, fmt.Errorf("%v must not be 0", MaxConcurrencyFlag.Name) } + var claimants []common.Address + if ctx.IsSet(AdditionalBondClaimants.Name) { + for _, addrStr := range ctx.StringSlice(AdditionalBondClaimants.Name) { + claimant, err := opservice.ParseAddress(addrStr) + if err != nil { + return nil, fmt.Errorf("invalid additional claimant: %w", err) + } + claimants = append(claimants, claimant) + } + } return &config.Config{ // Required Flags - L1EthRpc: ctx.String(L1EthRpcFlag.Name), - TraceTypes: traceTypes, - GameFactoryAddress: gameFactoryAddress, - GameAllowlist: allowedGames, - GameWindow: ctx.Duration(GameWindowFlag.Name), - MaxConcurrency: maxConcurrency, - PollInterval: ctx.Duration(HTTPPollInterval.Name), - RollupRpc: ctx.String(RollupRpcFlag.Name), - AlphabetTrace: ctx.String(AlphabetFlag.Name), - CannonNetwork: ctx.String(CannonNetworkFlag.Name), - CannonRollupConfigPath: ctx.String(CannonRollupConfigFlag.Name), - CannonL2GenesisPath: ctx.String(CannonL2GenesisFlag.Name), - CannonBin: ctx.String(CannonBinFlag.Name), - CannonServer: ctx.String(CannonServerFlag.Name), - CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name), - Datadir: ctx.String(DatadirFlag.Name), - CannonL2: ctx.String(CannonL2Flag.Name), - CannonSnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name), - CannonInfoFreq: ctx.Uint(CannonInfoFreqFlag.Name), - AgreeWithProposedOutput: ctx.Bool(AgreeWithProposedOutputFlag.Name), - TxMgrConfig: txMgrConfig, - MetricsConfig: metricsConfig, - PprofConfig: pprofConfig, + L1EthRpc: ctx.String(L1EthRpcFlag.Name), + L1Beacon: ctx.String(L1BeaconFlag.Name), + TraceTypes: traceTypes, + GameFactoryAddress: gameFactoryAddress, + GameAllowlist: allowedGames, + GameWindow: ctx.Duration(GameWindowFlag.Name), + MaxConcurrency: maxConcurrency, + MaxPendingTx: ctx.Uint64(MaxPendingTransactionsFlag.Name), + PollInterval: ctx.Duration(HTTPPollInterval.Name), + AdditionalBondClaimants: claimants, + RollupRpc: ctx.String(RollupRpcFlag.Name), + CannonNetwork: ctx.String(CannonNetworkFlag.Name), + CannonRollupConfigPath: ctx.String(CannonRollupConfigFlag.Name), + CannonL2GenesisPath: ctx.String(CannonL2GenesisFlag.Name), + CannonBin: ctx.String(CannonBinFlag.Name), + CannonServer: ctx.String(CannonServerFlag.Name), + CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name), + Datadir: ctx.String(DatadirFlag.Name), + CannonL2: ctx.String(CannonL2Flag.Name), + CannonSnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name), + CannonInfoFreq: ctx.Uint(CannonInfoFreqFlag.Name), + TxMgrConfig: txMgrConfig, + MetricsConfig: metricsConfig, + PprofConfig: pprofConfig, + SelectiveClaimResolution: ctx.Bool(SelectiveClaimResolutionFlag.Name), + AllowInvalidPrestate: ctx.Bool(UnsafeAllowInvalidPrestate.Name), }, nil } diff --git a/op-challenger/flags/flags_test.go b/op-challenger/flags/flags_test.go index 60294bfefb0b..27a361ca900a 100644 --- a/op-challenger/flags/flags_test.go +++ b/op-challenger/flags/flags_test.go @@ -2,9 +2,14 @@ package flags import ( "reflect" + "slices" "strings" "testing" + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + + "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" ) @@ -12,12 +17,13 @@ import ( func TestUniqueFlags(t *testing.T) { seenCLI := make(map[string]struct{}) for _, flag := range Flags { - name := flag.Names()[0] - if _, ok := seenCLI[name]; ok { - t.Errorf("duplicate flag %s", name) - continue + for _, name := range flag.Names() { + if _, ok := seenCLI[name]; ok { + t.Errorf("duplicate flag %s", name) + continue + } + seenCLI[name] = struct{}{} } - seenCLI[name] = struct{}{} } } @@ -57,3 +63,30 @@ func envVarForFlag(flag cli.Flag) string { } return envVarValue.Index(0).String() } + +func TestEnvVarFormat(t *testing.T) { + for _, flag := range Flags { + flag := flag + flagName := flag.Names()[0] + + skippedFlags := []string{ + txmgr.FeeLimitMultiplierFlagName, + txmgr.TxSendTimeoutFlagName, + txmgr.TxNotInMempoolTimeoutFlagName, + } + + t.Run(flagName, func(t *testing.T) { + if slices.Contains(skippedFlags, flagName) { + t.Skipf("Skipping flag %v which is known to not have a standard flag name <-> env var conversion", flagName) + } + envFlagGetter, ok := flag.(interface { + GetEnvVars() []string + }) + envFlags := envFlagGetter.GetEnvVars() + require.True(t, ok, "must be able to cast the flag to an EnvVar interface") + require.Equal(t, 1, len(envFlags), "flags should have exactly one env var") + expectedEnvVar := opservice.FlagNameToEnvVarName(flagName, "OP_CHALLENGER") + require.Equal(t, expectedEnvVar, envFlags[0]) + }) + } +} diff --git a/op-challenger/game/fault/agent.go b/op-challenger/game/fault/agent.go index a650a3b2a095..f67ef57336ce 100644 --- a/op-challenger/game/fault/agent.go +++ b/op-challenger/game/fault/agent.go @@ -4,12 +4,14 @@ import ( "context" "errors" "fmt" + "slices" "sync" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/solver" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" ) @@ -18,37 +20,46 @@ import ( // For full op-challenger this means executing the transaction on chain. type Responder interface { CallResolve(ctx context.Context) (gameTypes.GameStatus, error) - Resolve(ctx context.Context) error + Resolve() error CallResolveClaim(ctx context.Context, claimIdx uint64) error - ResolveClaim(ctx context.Context, claimIdx uint64) error + ResolveClaim(claimIdx uint64) error PerformAction(ctx context.Context, action types.Action) error } type ClaimLoader interface { - FetchClaims(ctx context.Context) ([]types.Claim, error) + GetAllClaims(ctx context.Context, block rpcblock.Block) ([]types.Claim, error) } type Agent struct { - metrics metrics.Metricer - solver *solver.GameSolver - loader ClaimLoader - responder Responder - updater types.OracleUpdater - maxDepth int - agreeWithProposedOutput bool - log log.Logger + metrics metrics.Metricer + solver *solver.GameSolver + loader ClaimLoader + responder Responder + selective bool + claimants []common.Address + maxDepth types.Depth + log log.Logger } -func NewAgent(m metrics.Metricer, loader ClaimLoader, maxDepth int, trace types.TraceProvider, responder Responder, updater types.OracleUpdater, agreeWithProposedOutput bool, log log.Logger) *Agent { +func NewAgent( + m metrics.Metricer, + loader ClaimLoader, + maxDepth types.Depth, + trace types.TraceAccessor, + responder Responder, + log log.Logger, + selective bool, + claimants []common.Address, +) *Agent { return &Agent{ - metrics: m, - solver: solver.NewGameSolver(maxDepth, trace), - loader: loader, - responder: responder, - updater: updater, - maxDepth: maxDepth, - agreeWithProposedOutput: agreeWithProposedOutput, - log: log, + metrics: m, + solver: solver.NewGameSolver(maxDepth, trace), + loader: loader, + responder: responder, + selective: selective, + claimants: claimants, + maxDepth: maxDepth, + log: log, } } @@ -57,59 +68,56 @@ func (a *Agent) Act(ctx context.Context) error { if a.tryResolve(ctx) { return nil } + game, err := a.newGameFromContracts(ctx) if err != nil { return fmt.Errorf("create game from contracts: %w", err) } - // Calculate the actions to take actions, err := a.solver.CalculateNextActions(ctx, game) if err != nil { - log.Error("Failed to calculate all required moves", "err", err) + a.log.Error("Failed to calculate all required moves", "err", err) } - // Perform the actions + var wg sync.WaitGroup + wg.Add(len(actions)) for _, action := range actions { - log := a.log.New("action", action.Type, "is_attack", action.IsAttack, "parent", action.ParentIdx) - if action.Type == types.ActionTypeStep { - log = log.New("prestate", common.Bytes2Hex(action.PreState), "proof", common.Bytes2Hex(action.ProofData)) - } else { - log = log.New("value", action.Value) - } + go a.performAction(ctx, &wg, action) + } + wg.Wait() + return nil +} +func (a *Agent) performAction(ctx context.Context, wg *sync.WaitGroup, action types.Action) { + defer wg.Done() + actionLog := a.log.New("action", action.Type, "is_attack", action.IsAttack, "parent", action.ParentIdx) + if action.Type == types.ActionTypeStep { + containsOracleData := action.OracleData != nil + isLocal := containsOracleData && action.OracleData.IsLocal + actionLog = actionLog.New( + "prestate", common.Bytes2Hex(action.PreState), + "proof", common.Bytes2Hex(action.ProofData), + "containsOracleData", containsOracleData, + "isLocalPreimage", isLocal, + ) if action.OracleData != nil { - a.log.Info("Updating oracle data", "oracleKey", action.OracleData.OracleKey, "oracleData", action.OracleData.OracleData) - if err := a.updater.UpdateOracle(ctx, action.OracleData); err != nil { - return fmt.Errorf("failed to load oracle data: %w", err) - } - } - - switch action.Type { - case types.ActionTypeMove: - a.metrics.RecordGameMove() - case types.ActionTypeStep: - a.metrics.RecordGameStep() - } - log.Info("Performing action") - err := a.responder.PerformAction(ctx, action) - if err != nil { - log.Error("Action failed", "err", err) + actionLog = actionLog.New("oracleKey", common.Bytes2Hex(action.OracleData.OracleKey)) } + } else { + actionLog = actionLog.New("value", action.Value) } - return nil -} -// shouldResolve returns true if the agent should resolve the game. -// This method will return false if the game is still in progress. -func (a *Agent) shouldResolve(status gameTypes.GameStatus) bool { - expected := gameTypes.GameStatusDefenderWon - if a.agreeWithProposedOutput { - expected = gameTypes.GameStatusChallengerWon + switch action.Type { + case types.ActionTypeMove: + a.metrics.RecordGameMove() + case types.ActionTypeStep: + a.metrics.RecordGameStep() } - if expected != status { - a.log.Warn("Game will be lost", "expected", expected, "actual", status) + actionLog.Info("Performing action") + err := a.responder.PerformAction(ctx, action) + if err != nil { + actionLog.Error("Action failed", "err", err) } - return expected == status } // tryResolve resolves the game if it is in a winning state @@ -123,11 +131,8 @@ func (a *Agent) tryResolve(ctx context.Context) bool { if err != nil || status == gameTypes.GameStatusInProgress { return false } - if !a.shouldResolve(status) { - return true - } a.log.Info("Resolving game") - if err := a.responder.Resolve(ctx); err != nil { + if err := a.responder.Resolve(); err != nil { a.log.Error("Failed to resolve the game", "err", err) } return true @@ -136,7 +141,7 @@ func (a *Agent) tryResolve(ctx context.Context) bool { var errNoResolvableClaims = errors.New("no resolvable claims") func (a *Agent) tryResolveClaims(ctx context.Context) error { - claims, err := a.loader.FetchClaims(ctx) + claims, err := a.loader.GetAllClaims(ctx, rpcblock.Latest) if err != nil { return fmt.Errorf("failed to fetch claims: %w", err) } @@ -146,7 +151,16 @@ func (a *Agent) tryResolveClaims(ctx context.Context) error { var resolvableClaims []int64 for _, claim := range claims { - a.log.Debug("checking if claim is resolvable", "claimIdx", claim.ContractIndex) + if a.selective { + a.log.Trace("Selective claim resolution, checking if claim is incentivized", "claimIdx", claim.ContractIndex) + isUncounteredClaim := slices.Contains(a.claimants, claim.Claimant) && claim.CounteredBy == common.Address{} + ourCounter := slices.Contains(a.claimants, claim.CounteredBy) + if !isUncounteredClaim && !ourCounter { + a.log.Debug("Skipping claim to check resolution", "claimIdx", claim.ContractIndex) + continue + } + } + a.log.Trace("Checking if claim is resolvable", "claimIdx", claim.ContractIndex) if err := a.responder.CallResolveClaim(ctx, uint64(claim.ContractIndex)); err == nil { a.log.Info("Resolving claim", "claimIdx", claim.ContractIndex) resolvableClaims = append(resolvableClaims, int64(claim.ContractIndex)) @@ -163,7 +177,7 @@ func (a *Agent) tryResolveClaims(ctx context.Context) error { claimIdx := claimIdx go func() { defer wg.Done() - err := a.responder.ResolveClaim(ctx, uint64(claimIdx)) + err := a.responder.ResolveClaim(uint64(claimIdx)) if err != nil { a.log.Error("Failed to resolve claim", "err", err) } @@ -189,13 +203,13 @@ func (a *Agent) resolveClaims(ctx context.Context) error { // newGameFromContracts initializes a new game state from the state in the contract func (a *Agent) newGameFromContracts(ctx context.Context) (types.Game, error) { - claims, err := a.loader.FetchClaims(ctx) + claims, err := a.loader.GetAllClaims(ctx, rpcblock.Latest) if err != nil { return nil, fmt.Errorf("failed to fetch claims: %w", err) } if len(claims) == 0 { return nil, errors.New("no claims") } - game := types.NewGameState(a.agreeWithProposedOutput, claims, uint64(a.maxDepth)) + game := types.NewGameState(claims, a.maxDepth) return game, nil } diff --git a/op-challenger/game/fault/agent_test.go b/op-challenger/game/fault/agent_test.go index c6b1904c74b1..c1c3d22636b2 100644 --- a/op-challenger/game/fault/agent_test.go +++ b/op-challenger/game/fault/agent_test.go @@ -3,10 +3,15 @@ package fault import ( "context" "errors" + "math/big" + "sync" "testing" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test" @@ -17,88 +22,123 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -// TestShouldResolve tests the resolution logic. -func TestShouldResolve(t *testing.T) { - t.Run("AgreeWithProposedOutput", func(t *testing.T) { - agent, _, _ := setupTestAgent(t, true) - require.False(t, agent.shouldResolve(gameTypes.GameStatusDefenderWon)) - require.True(t, agent.shouldResolve(gameTypes.GameStatusChallengerWon)) - require.False(t, agent.shouldResolve(gameTypes.GameStatusInProgress)) - }) - - t.Run("DisagreeWithProposedOutput", func(t *testing.T) { - agent, _, _ := setupTestAgent(t, false) - require.True(t, agent.shouldResolve(gameTypes.GameStatusDefenderWon)) - require.False(t, agent.shouldResolve(gameTypes.GameStatusChallengerWon)) - require.False(t, agent.shouldResolve(gameTypes.GameStatusInProgress)) - }) +func TestDoNotMakeMovesWhenGameIsResolvable(t *testing.T) { + ctx := context.Background() + + tests := []struct { + name string + callResolveStatus gameTypes.GameStatus + }{ + { + name: "DefenderWon", + callResolveStatus: gameTypes.GameStatusDefenderWon, + }, + { + name: "ChallengerWon", + callResolveStatus: gameTypes.GameStatusChallengerWon, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + agent, claimLoader, responder := setupTestAgent(t) + responder.callResolveStatus = test.callResolveStatus + + require.NoError(t, agent.Act(ctx)) + + require.Equal(t, 1, responder.callResolveCount, "should check if game is resolvable") + require.Equal(t, 1, claimLoader.callCount, "should fetch claims once for resolveClaim") + + require.EqualValues(t, 1, responder.resolveCount, "should resolve winning game") + }) + } } -func TestDoNotMakeMovesWhenGameIsResolvable(t *testing.T) { +func createClaimsWithClaimants(t *testing.T, d types.Depth) []types.Claim { + claimBuilder := test.NewClaimBuilder(t, d, alphabet.NewTraceProvider(big.NewInt(0), d)) + rootClaim := claimBuilder.CreateRootClaim() + claim1 := rootClaim + claim1.Claimant = common.BigToAddress(big.NewInt(1)) + claim2 := claimBuilder.AttackClaim(claim1) + claim2.Claimant = common.BigToAddress(big.NewInt(2)) + claim3 := claimBuilder.AttackClaim(claim2) + claim3.Claimant = common.BigToAddress(big.NewInt(3)) + return []types.Claim{claim1, claim2, claim3} +} + +func TestAgent_SelectiveClaimResolution(t *testing.T) { ctx := context.Background() tests := []struct { - name string - agreeWithProposedOutput bool - callResolveStatus gameTypes.GameStatus - shouldResolve bool + name string + callResolveStatus gameTypes.GameStatus + selective bool + claimants []common.Address + claims []types.Claim + expectedResolveCount int }{ { - name: "Agree_Losing", - agreeWithProposedOutput: true, - callResolveStatus: gameTypes.GameStatusDefenderWon, - shouldResolve: false, + name: "NonSelectiveEmptyClaimants", + callResolveStatus: gameTypes.GameStatusDefenderWon, + selective: false, + claimants: []common.Address{}, + claims: createClaimsWithClaimants(t, types.Depth(4)), + expectedResolveCount: 3, }, { - name: "Agree_Winning", - agreeWithProposedOutput: true, - callResolveStatus: gameTypes.GameStatusChallengerWon, - shouldResolve: true, + name: "NonSelectiveWithClaimants", + callResolveStatus: gameTypes.GameStatusDefenderWon, + selective: false, + claimants: []common.Address{common.BigToAddress(big.NewInt(1))}, + claims: createClaimsWithClaimants(t, types.Depth(4)), + expectedResolveCount: 3, }, { - name: "Disagree_Losing", - agreeWithProposedOutput: false, - callResolveStatus: gameTypes.GameStatusChallengerWon, - shouldResolve: false, + name: "SelectiveEmptyClaimants", + callResolveStatus: gameTypes.GameStatusDefenderWon, + selective: true, + claimants: []common.Address{}, + claims: createClaimsWithClaimants(t, types.Depth(4)), }, { - name: "Disagree_Winning", - agreeWithProposedOutput: false, - callResolveStatus: gameTypes.GameStatusDefenderWon, - shouldResolve: true, + name: "SelectiveWithClaimants", + callResolveStatus: gameTypes.GameStatusDefenderWon, + selective: true, + claimants: []common.Address{common.BigToAddress(big.NewInt(1))}, + claims: createClaimsWithClaimants(t, types.Depth(4)), + expectedResolveCount: 1, }, } for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { - agent, claimLoader, responder := setupTestAgent(t, test.agreeWithProposedOutput) + agent, claimLoader, responder := setupTestAgent(t) + agent.selective = test.selective + agent.claimants = test.claimants + claimLoader.maxLoads = 1 + claimLoader.claims = test.claims responder.callResolveStatus = test.callResolveStatus require.NoError(t, agent.Act(ctx)) - require.Equal(t, 1, responder.callResolveCount, "should check if game is resolvable") - require.Equal(t, 1, claimLoader.callCount, "should fetch claims once for resolveClaim") - - if test.shouldResolve { - require.EqualValues(t, 1, responder.resolveCount, "should resolve winning game") - } else { - require.Zero(t, responder.resolveCount, "should not resolve losing game") - } + require.Equal(t, test.expectedResolveCount, responder.callResolveClaimCount, "should check if game is resolvable") + require.Equal(t, test.expectedResolveCount, responder.resolveClaimCount, "should check if game is resolvable") }) } } func TestLoadClaimsWhenGameNotResolvable(t *testing.T) { // Checks that if the game isn't resolvable, that the agent continues on to start checking claims - agent, claimLoader, responder := setupTestAgent(t, false) + agent, claimLoader, responder := setupTestAgent(t) responder.callResolveErr = errors.New("game is not resolvable") responder.callResolveClaimErr = errors.New("claim is not resolvable") - depth := 4 - claimBuilder := test.NewClaimBuilder(t, depth, alphabet.NewTraceProvider("abcdefg", uint64(depth))) + depth := types.Depth(4) + claimBuilder := test.NewClaimBuilder(t, depth, alphabet.NewTraceProvider(big.NewInt(0), depth)) claimLoader.claims = []types.Claim{ - claimBuilder.CreateRootClaim(true), + claimBuilder.CreateRootClaim(), } require.NoError(t, agent.Act(context.Background())) @@ -108,28 +148,32 @@ func TestLoadClaimsWhenGameNotResolvable(t *testing.T) { require.Zero(t, responder.resolveClaimCount, "should not send resolveClaim") } -func setupTestAgent(t *testing.T, agreeWithProposedOutput bool) (*Agent, *stubClaimLoader, *stubResponder) { - logger := testlog.Logger(t, log.LvlInfo) +func setupTestAgent(t *testing.T) (*Agent, *stubClaimLoader, *stubResponder) { + logger := testlog.Logger(t, log.LevelInfo) claimLoader := &stubClaimLoader{} - depth := 4 - trace := alphabet.NewTraceProvider("abcd", uint64(depth)) + depth := types.Depth(4) + provider := alphabet.NewTraceProvider(big.NewInt(0), depth) responder := &stubResponder{} - updater := &stubUpdater{} - agent := NewAgent(metrics.NoopMetrics, claimLoader, depth, trace, responder, updater, agreeWithProposedOutput, logger) + agent := NewAgent(metrics.NoopMetrics, claimLoader, depth, trace.NewSimpleTraceAccessor(provider), responder, logger, false, []common.Address{}) return agent, claimLoader, responder } type stubClaimLoader struct { callCount int + maxLoads int claims []types.Claim } -func (s *stubClaimLoader) FetchClaims(ctx context.Context) ([]types.Claim, error) { +func (s *stubClaimLoader) GetAllClaims(_ context.Context, _ rpcblock.Block) ([]types.Claim, error) { s.callCount++ + if s.callCount > s.maxLoads && s.maxLoads != 0 { + return []types.Claim{}, nil + } return s.claims, nil } type stubResponder struct { + l sync.Mutex callResolveCount int callResolveStatus gameTypes.GameStatus callResolveErr error @@ -143,21 +187,29 @@ type stubResponder struct { } func (s *stubResponder) CallResolve(ctx context.Context) (gameTypes.GameStatus, error) { + s.l.Lock() + defer s.l.Unlock() s.callResolveCount++ return s.callResolveStatus, s.callResolveErr } -func (s *stubResponder) Resolve(ctx context.Context) error { +func (s *stubResponder) Resolve() error { + s.l.Lock() + defer s.l.Unlock() s.resolveCount++ return s.resolveErr } func (s *stubResponder) CallResolveClaim(ctx context.Context, clainIdx uint64) error { + s.l.Lock() + defer s.l.Unlock() s.callResolveClaimCount++ return s.callResolveClaimErr } -func (s *stubResponder) ResolveClaim(ctx context.Context, clainIdx uint64) error { +func (s *stubResponder) ResolveClaim(clainIdx uint64) error { + s.l.Lock() + defer s.l.Unlock() s.resolveClaimCount++ return nil } @@ -165,10 +217,3 @@ func (s *stubResponder) ResolveClaim(ctx context.Context, clainIdx uint64) error func (s *stubResponder) PerformAction(ctx context.Context, response types.Action) error { return nil } - -type stubUpdater struct { -} - -func (s *stubUpdater) UpdateOracle(ctx context.Context, data *types.PreimageOracleData) error { - panic("Not implemented") -} diff --git a/op-challenger/game/fault/claims/claimer.go b/op-challenger/game/fault/claims/claimer.go new file mode 100644 index 000000000000..7e8fbd037ccf --- /dev/null +++ b/op-challenger/game/fault/claims/claimer.go @@ -0,0 +1,87 @@ +package claims + +import ( + "context" + "errors" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +type BondClaimMetrics interface { + RecordBondClaimed(amount uint64) +} + +type BondContract interface { + GetCredit(ctx context.Context, receipient common.Address) (*big.Int, types.GameStatus, error) + ClaimCredit(receipient common.Address) (txmgr.TxCandidate, error) +} + +type BondContractCreator func(game types.GameMetadata) (BondContract, error) + +type Claimer struct { + logger log.Logger + metrics BondClaimMetrics + contractCreator BondContractCreator + txSender types.TxSender + claimants []common.Address +} + +var _ BondClaimer = (*Claimer)(nil) + +func NewBondClaimer(l log.Logger, m BondClaimMetrics, contractCreator BondContractCreator, txSender types.TxSender, claimants ...common.Address) *Claimer { + return &Claimer{ + logger: l, + metrics: m, + contractCreator: contractCreator, + txSender: txSender, + claimants: claimants, + } +} + +func (c *Claimer) ClaimBonds(ctx context.Context, games []types.GameMetadata) (err error) { + for _, game := range games { + for _, claimant := range c.claimants { + err = errors.Join(err, c.claimBond(ctx, game, claimant)) + } + } + return err +} + +func (c *Claimer) claimBond(ctx context.Context, game types.GameMetadata, addr common.Address) error { + c.logger.Debug("Attempting to claim bonds for", "game", game.Proxy, "addr", addr) + + contract, err := c.contractCreator(game) + if err != nil { + return fmt.Errorf("failed to create bond contract bindings: %w", err) + } + credit, status, err := contract.GetCredit(ctx, addr) + if err != nil { + return fmt.Errorf("failed to get credit: %w", err) + } + + if status == types.GameStatusInProgress { + c.logger.Debug("Not claiming credit from in progress game", "game", game.Proxy, "addr", addr, "status", status) + return nil + } + if credit.Cmp(big.NewInt(0)) == 0 { + c.logger.Debug("No credit to claim", "game", game.Proxy, "addr", addr) + return nil + } + + candidate, err := contract.ClaimCredit(addr) + if err != nil { + return fmt.Errorf("failed to create credit claim tx: %w", err) + } + + if _, err = c.txSender.SendAndWait("claim credit", candidate); err != nil { + return fmt.Errorf("failed to claim credit: %w", err) + } + + c.metrics.RecordBondClaimed(credit.Uint64()) + return nil +} diff --git a/op-challenger/game/fault/claims/claimer_test.go b/op-challenger/game/fault/claims/claimer_test.go new file mode 100644 index 000000000000..8d157d16c9a3 --- /dev/null +++ b/op-challenger/game/fault/claims/claimer_test.go @@ -0,0 +1,157 @@ +package claims + +import ( + "context" + "errors" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var ( + mockTxMgrSendError = errors.New("mock tx mgr send error") +) + +func TestClaimer_ClaimBonds(t *testing.T) { + t.Run("MultipleBondClaimsSucceed", func(t *testing.T) { + gameAddr := common.HexToAddress("0x1234") + c, m, contract, txSender := newTestClaimer(t) + contract.credit[txSender.From()] = 1 + err := c.ClaimBonds(context.Background(), []types.GameMetadata{{Proxy: gameAddr}, {Proxy: gameAddr}, {Proxy: gameAddr}}) + require.NoError(t, err) + require.Equal(t, 3, txSender.sends) + require.Equal(t, 3, m.RecordBondClaimedCalls) + }) + + t.Run("BondClaimSucceeds", func(t *testing.T) { + gameAddr := common.HexToAddress("0x1234") + c, m, contract, txSender := newTestClaimer(t) + contract.credit[txSender.From()] = 1 + err := c.ClaimBonds(context.Background(), []types.GameMetadata{{Proxy: gameAddr}}) + require.NoError(t, err) + require.Equal(t, 1, txSender.sends) + require.Equal(t, 1, m.RecordBondClaimedCalls) + }) + + t.Run("BondClaimSucceedsForMultipleAddresses", func(t *testing.T) { + claimant1 := common.Address{0xaa} + claimant2 := common.Address{0xbb} + claimant3 := common.Address{0xcc} + gameAddr := common.HexToAddress("0x1234") + c, m, contract, txSender := newTestClaimer(t, claimant1, claimant2, claimant3) + contract.credit[claimant1] = 1 + contract.credit[claimant2] = 2 + contract.credit[claimant3] = 0 + err := c.ClaimBonds(context.Background(), []types.GameMetadata{{Proxy: gameAddr}}) + require.NoError(t, err) + require.Equal(t, 2, txSender.sends) + require.Equal(t, 2, m.RecordBondClaimedCalls) + }) + + t.Run("BondClaimSkippedForInProgressGame", func(t *testing.T) { + gameAddr := common.HexToAddress("0x1234") + c, m, contract, txSender := newTestClaimer(t) + contract.credit[txSender.From()] = 1 + contract.status = types.GameStatusInProgress + err := c.ClaimBonds(context.Background(), []types.GameMetadata{{Proxy: gameAddr}}) + require.NoError(t, err) + require.Equal(t, 0, txSender.sends) + require.Equal(t, 0, m.RecordBondClaimedCalls) + }) + + t.Run("BondClaimFails", func(t *testing.T) { + gameAddr := common.HexToAddress("0x1234") + c, m, contract, txSender := newTestClaimer(t) + txSender.sendFails = true + contract.credit[txSender.From()] = 1 + err := c.ClaimBonds(context.Background(), []types.GameMetadata{{Proxy: gameAddr}}) + require.ErrorIs(t, err, mockTxMgrSendError) + require.Equal(t, 1, txSender.sends) + require.Equal(t, 0, m.RecordBondClaimedCalls) + }) + + t.Run("ZeroCreditReturnsNil", func(t *testing.T) { + gameAddr := common.HexToAddress("0x1234") + c, m, contract, txSender := newTestClaimer(t) + contract.credit[txSender.From()] = 0 + err := c.ClaimBonds(context.Background(), []types.GameMetadata{{Proxy: gameAddr}}) + require.NoError(t, err) + require.Equal(t, 0, txSender.sends) + require.Equal(t, 0, m.RecordBondClaimedCalls) + }) + + t.Run("MultipleBondClaimFails", func(t *testing.T) { + gameAddr := common.HexToAddress("0x1234") + c, m, contract, txSender := newTestClaimer(t) + contract.credit[txSender.From()] = 1 + txSender.sendFails = true + err := c.ClaimBonds(context.Background(), []types.GameMetadata{{Proxy: gameAddr}, {Proxy: gameAddr}, {Proxy: gameAddr}}) + require.ErrorIs(t, err, mockTxMgrSendError) + require.Equal(t, 3, txSender.sends) + require.Equal(t, 0, m.RecordBondClaimedCalls) + }) +} + +func newTestClaimer(t *testing.T, claimants ...common.Address) (*Claimer, *mockClaimMetrics, *stubBondContract, *mockTxSender) { + logger := testlog.Logger(t, log.LvlDebug) + m := &mockClaimMetrics{} + txSender := &mockTxSender{} + bondContract := &stubBondContract{status: types.GameStatusChallengerWon, credit: make(map[common.Address]int64)} + contractCreator := func(game types.GameMetadata) (BondContract, error) { + return bondContract, nil + } + if len(claimants) == 0 { + claimants = []common.Address{txSender.From()} + } + c := NewBondClaimer(logger, m, contractCreator, txSender, claimants...) + return c, m, bondContract, txSender +} + +type mockClaimMetrics struct { + RecordBondClaimedCalls int +} + +func (m *mockClaimMetrics) RecordBondClaimed(amount uint64) { + m.RecordBondClaimedCalls++ +} + +type mockTxSender struct { + sends int + sendFails bool + statusFail bool +} + +func (s *mockTxSender) From() common.Address { + return common.HexToAddress("0x33333") +} + +func (s *mockTxSender) SendAndWait(_ string, _ ...txmgr.TxCandidate) ([]*ethtypes.Receipt, error) { + s.sends++ + if s.sendFails { + return nil, mockTxMgrSendError + } + if s.statusFail { + return []*ethtypes.Receipt{{Status: ethtypes.ReceiptStatusFailed}}, nil + } + return []*ethtypes.Receipt{{Status: ethtypes.ReceiptStatusSuccessful}}, nil +} + +type stubBondContract struct { + credit map[common.Address]int64 + status types.GameStatus +} + +func (s *stubBondContract) GetCredit(_ context.Context, addr common.Address) (*big.Int, types.GameStatus, error) { + return big.NewInt(s.credit[addr]), s.status, nil +} + +func (s *stubBondContract) ClaimCredit(_ common.Address) (txmgr.TxCandidate, error) { + return txmgr.TxCandidate{}, nil +} diff --git a/op-challenger/game/fault/claims/scheduler.go b/op-challenger/game/fault/claims/scheduler.go new file mode 100644 index 000000000000..17dbee301209 --- /dev/null +++ b/op-challenger/game/fault/claims/scheduler.go @@ -0,0 +1,77 @@ +package claims + +import ( + "context" + "sync" + + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum/go-ethereum/log" +) + +type BondClaimer interface { + ClaimBonds(ctx context.Context, games []types.GameMetadata) error +} + +type BondClaimScheduler struct { + log log.Logger + metrics BondClaimSchedulerMetrics + ch chan schedulerMessage + claimer BondClaimer + cancel func() + wg sync.WaitGroup +} + +type BondClaimSchedulerMetrics interface { + RecordBondClaimFailed() +} + +type schedulerMessage struct { + blockNumber uint64 + games []types.GameMetadata +} + +func NewBondClaimScheduler(logger log.Logger, metrics BondClaimSchedulerMetrics, claimer BondClaimer) *BondClaimScheduler { + return &BondClaimScheduler{ + log: logger, + metrics: metrics, + ch: make(chan schedulerMessage, 1), + claimer: claimer, + } +} + +func (s *BondClaimScheduler) Start(ctx context.Context) { + ctx, cancel := context.WithCancel(ctx) + s.cancel = cancel + s.wg.Add(1) + go s.run(ctx) +} + +func (s *BondClaimScheduler) Close() error { + s.cancel() + s.wg.Wait() + return nil +} + +func (s *BondClaimScheduler) run(ctx context.Context) { + defer s.wg.Done() + for { + select { + case <-ctx.Done(): + return + case msg := <-s.ch: + if err := s.claimer.ClaimBonds(ctx, msg.games); err != nil { + s.metrics.RecordBondClaimFailed() + s.log.Error("Failed to claim bonds", "blockNumber", msg.blockNumber, "err", err) + } + } + } +} + +func (s *BondClaimScheduler) Schedule(blockNumber uint64, games []types.GameMetadata) error { + select { + case s.ch <- schedulerMessage{blockNumber, games}: + default: + s.log.Trace("Skipping game bond claim while claiming in progress") + } + return nil +} diff --git a/op-challenger/game/fault/claims/scheduler_test.go b/op-challenger/game/fault/claims/scheduler_test.go new file mode 100644 index 000000000000..724189cb3f34 --- /dev/null +++ b/op-challenger/game/fault/claims/scheduler_test.go @@ -0,0 +1,99 @@ +package claims + +import ( + "context" + "errors" + "sync/atomic" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var mockClaimError = errors.New("mock claim error") + +func TestBondClaimScheduler_Schedule(t *testing.T) { + tests := []struct { + name string + claimErr error + games []types.GameMetadata + expectedMetricCalls int + expectedClaimCalls int + }{ + { + name: "SingleGame_Succeeds", + games: []types.GameMetadata{{}}, + expectedMetricCalls: 0, + expectedClaimCalls: 1, + }, + { + name: "SingleGame_Fails", + claimErr: mockClaimError, + games: []types.GameMetadata{{}}, + expectedMetricCalls: 1, + expectedClaimCalls: 1, + }, + { + name: "MultipleGames_Succeed", + games: []types.GameMetadata{{}, {}, {}}, + expectedMetricCalls: 0, + expectedClaimCalls: 1, + }, + { + name: "MultipleGames_Fails", + claimErr: mockClaimError, + games: []types.GameMetadata{{}, {}, {}}, + expectedMetricCalls: 1, + expectedClaimCalls: 1, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + ctx := context.Background() + scheduler, metrics, claimer := setupTestBondClaimScheduler(t) + claimer.claimErr = test.claimErr + scheduler.Start(ctx) + defer scheduler.Close() + + err := scheduler.Schedule(1, test.games) + require.NoError(t, err) + require.Eventually(t, func() bool { + return int(claimer.claimCalls.Load()) == test.expectedClaimCalls + }, 10*time.Second, 10*time.Millisecond) + require.Eventually(t, func() bool { + return int(metrics.failedCalls.Load()) == test.expectedMetricCalls + }, 10*time.Second, 10*time.Millisecond) + }) + } +} + +func setupTestBondClaimScheduler(t *testing.T) (*BondClaimScheduler, *stubMetrics, *stubClaimer) { + logger := testlog.Logger(t, log.LvlInfo) + metrics := &stubMetrics{} + claimer := &stubClaimer{} + scheduler := NewBondClaimScheduler(logger, metrics, claimer) + return scheduler, metrics, claimer +} + +type stubMetrics struct { + failedCalls atomic.Int64 +} + +func (s *stubMetrics) RecordBondClaimFailed() { + s.failedCalls.Add(1) +} + +type stubClaimer struct { + claimCalls atomic.Int64 + claimErr error +} + +func (s *stubClaimer) ClaimBonds(ctx context.Context, games []types.GameMetadata) error { + s.claimCalls.Add(1) + return s.claimErr +} diff --git a/op-challenger/game/fault/contracts/faultdisputegame.go b/op-challenger/game/fault/contracts/faultdisputegame.go new file mode 100644 index 000000000000..d7d3557bc093 --- /dev/null +++ b/op-challenger/game/fault/contracts/faultdisputegame.go @@ -0,0 +1,388 @@ +package contracts + +import ( + "context" + "fmt" + "math" + "math/big" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" +) + +var ( + methodGameDuration = "gameDuration" + methodMaxGameDepth = "maxGameDepth" + methodAbsolutePrestate = "absolutePrestate" + methodStatus = "status" + methodRootClaim = "rootClaim" + methodClaimCount = "claimDataLen" + methodClaim = "claimData" + methodL1Head = "l1Head" + methodResolve = "resolve" + methodResolveClaim = "resolveClaim" + methodAttack = "attack" + methodDefend = "defend" + methodStep = "step" + methodAddLocalData = "addLocalData" + methodVM = "vm" + methodStartingBlockNumber = "startingBlockNumber" + methodStartingRootHash = "startingRootHash" + methodSplitDepth = "splitDepth" + methodL2BlockNumber = "l2BlockNumber" + methodRequiredBond = "getRequiredBond" + methodClaimCredit = "claimCredit" + methodCredit = "credit" + methodWETH = "weth" +) + +type FaultDisputeGameContract struct { + multiCaller *batching.MultiCaller + contract *batching.BoundContract +} + +type Proposal struct { + L2BlockNumber *big.Int + OutputRoot common.Hash +} + +func NewFaultDisputeGameContract(addr common.Address, caller *batching.MultiCaller) (*FaultDisputeGameContract, error) { + contractAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to load fault dispute game ABI: %w", err) + } + + return &FaultDisputeGameContract{ + multiCaller: caller, + contract: batching.NewBoundContract(contractAbi, addr), + }, nil +} + +// GetBalance returns the total amount of ETH controlled by this contract. +// Note that the ETH is actually held by the DelayedWETH contract which may be shared by multiple games. +// Returns the balance and the address of the contract that actually holds the balance. +func (f *FaultDisputeGameContract) GetBalance(ctx context.Context, block rpcblock.Block) (*big.Int, common.Address, error) { + result, err := f.multiCaller.SingleCall(ctx, block, f.contract.Call(methodWETH)) + if err != nil { + return nil, common.Address{}, fmt.Errorf("failed to load weth address: %w", err) + } + wethAddr := result.GetAddress(0) + result, err = f.multiCaller.SingleCall(ctx, block, batching.NewBalanceCall(wethAddr)) + if err != nil { + return nil, common.Address{}, fmt.Errorf("failed to retrieve game balance: %w", err) + } + return result.GetBigInt(0), wethAddr, nil +} + +// GetBlockRange returns the block numbers of the absolute pre-state block (typically genesis or the bedrock activation block) +// and the post-state block (that the proposed output root is for). +func (f *FaultDisputeGameContract) GetBlockRange(ctx context.Context) (prestateBlock uint64, poststateBlock uint64, retErr error) { + results, err := f.multiCaller.Call(ctx, rpcblock.Latest, + f.contract.Call(methodStartingBlockNumber), + f.contract.Call(methodL2BlockNumber)) + if err != nil { + retErr = fmt.Errorf("failed to retrieve game block range: %w", err) + return + } + if len(results) != 2 { + retErr = fmt.Errorf("expected 2 results but got %v", len(results)) + return + } + prestateBlock = results[0].GetBigInt(0).Uint64() + poststateBlock = results[1].GetBigInt(0).Uint64() + return +} + +// GetGameMetadata returns the game's L1 head, L2 block number, root claim, status, and game duration. +func (f *FaultDisputeGameContract) GetGameMetadata(ctx context.Context, block rpcblock.Block) (common.Hash, uint64, common.Hash, gameTypes.GameStatus, uint64, error) { + results, err := f.multiCaller.Call(ctx, block, + f.contract.Call(methodL1Head), + f.contract.Call(methodL2BlockNumber), + f.contract.Call(methodRootClaim), + f.contract.Call(methodStatus), + f.contract.Call(methodGameDuration)) + if err != nil { + return common.Hash{}, 0, common.Hash{}, 0, 0, fmt.Errorf("failed to retrieve game metadata: %w", err) + } + if len(results) != 5 { + return common.Hash{}, 0, common.Hash{}, 0, 0, fmt.Errorf("expected 3 results but got %v", len(results)) + } + l1Head := results[0].GetHash(0) + l2BlockNumber := results[1].GetBigInt(0).Uint64() + rootClaim := results[2].GetHash(0) + status, err := gameTypes.GameStatusFromUint8(results[3].GetUint8(0)) + if err != nil { + return common.Hash{}, 0, common.Hash{}, 0, 0, fmt.Errorf("failed to convert game status: %w", err) + } + duration := results[4].GetUint64(0) + return l1Head, l2BlockNumber, rootClaim, status, duration, nil +} + +func (f *FaultDisputeGameContract) GetStartingRootHash(ctx context.Context) (common.Hash, error) { + startingRootHash, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodStartingRootHash)) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to retrieve genesis output root: %w", err) + } + return startingRootHash.GetHash(0), nil +} + +func (f *FaultDisputeGameContract) GetSplitDepth(ctx context.Context) (types.Depth, error) { + splitDepth, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodSplitDepth)) + if err != nil { + return 0, fmt.Errorf("failed to retrieve split depth: %w", err) + } + return types.Depth(splitDepth.GetBigInt(0).Uint64()), nil +} + +func (f *FaultDisputeGameContract) GetCredit(ctx context.Context, recipient common.Address) (*big.Int, gameTypes.GameStatus, error) { + results, err := f.multiCaller.Call(ctx, rpcblock.Latest, + f.contract.Call(methodCredit, recipient), + f.contract.Call(methodStatus)) + if err != nil { + return nil, gameTypes.GameStatusInProgress, err + } + if len(results) != 2 { + return nil, gameTypes.GameStatusInProgress, fmt.Errorf("expected 2 results but got %v", len(results)) + } + credit := results[0].GetBigInt(0) + status, err := gameTypes.GameStatusFromUint8(results[1].GetUint8(0)) + if err != nil { + return nil, gameTypes.GameStatusInProgress, fmt.Errorf("invalid game status %v: %w", status, err) + } + return credit, status, nil +} + +func (f *FaultDisputeGameContract) GetCredits(ctx context.Context, block rpcblock.Block, recipients ...common.Address) ([]*big.Int, error) { + calls := make([]batching.Call, 0, len(recipients)) + for _, recipient := range recipients { + calls = append(calls, f.contract.Call(methodCredit, recipient)) + } + results, err := f.multiCaller.Call(ctx, block, calls...) + if err != nil { + return nil, fmt.Errorf("failed to retrieve credit: %w", err) + } + credits := make([]*big.Int, 0, len(recipients)) + for _, result := range results { + credits = append(credits, result.GetBigInt(0)) + } + return credits, nil +} + +func (f *FaultDisputeGameContract) ClaimCredit(recipient common.Address) (txmgr.TxCandidate, error) { + call := f.contract.Call(methodClaimCredit, recipient) + return call.ToTxCandidate() +} + +func (f *FaultDisputeGameContract) GetRequiredBond(ctx context.Context, position types.Position) (*big.Int, error) { + bond, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodRequiredBond, position.ToGIndex())) + if err != nil { + return nil, fmt.Errorf("failed to retrieve required bond: %w", err) + } + return bond.GetBigInt(0), nil +} + +func (f *FaultDisputeGameContract) UpdateOracleTx(ctx context.Context, claimIdx uint64, data *types.PreimageOracleData) (txmgr.TxCandidate, error) { + if data.IsLocal { + return f.addLocalDataTx(claimIdx, data) + } + return f.addGlobalDataTx(ctx, data) +} + +func (f *FaultDisputeGameContract) addLocalDataTx(claimIdx uint64, data *types.PreimageOracleData) (txmgr.TxCandidate, error) { + call := f.contract.Call( + methodAddLocalData, + data.GetIdent(), + new(big.Int).SetUint64(claimIdx), + new(big.Int).SetUint64(uint64(data.OracleOffset)), + ) + return call.ToTxCandidate() +} + +func (f *FaultDisputeGameContract) addGlobalDataTx(ctx context.Context, data *types.PreimageOracleData) (txmgr.TxCandidate, error) { + oracle, err := f.GetOracle(ctx) + if err != nil { + return txmgr.TxCandidate{}, err + } + return oracle.AddGlobalDataTx(data) +} + +func (f *FaultDisputeGameContract) GetOracle(ctx context.Context) (*PreimageOracleContract, error) { + vm, err := f.vm(ctx) + if err != nil { + return nil, err + } + return vm.Oracle(ctx) +} + +func (f *FaultDisputeGameContract) GetGameDuration(ctx context.Context) (uint64, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGameDuration)) + if err != nil { + return 0, fmt.Errorf("failed to fetch game duration: %w", err) + } + return result.GetUint64(0), nil +} + +func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (types.Depth, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodMaxGameDepth)) + if err != nil { + return 0, fmt.Errorf("failed to fetch max game depth: %w", err) + } + return types.Depth(result.GetBigInt(0).Uint64()), nil +} + +func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodAbsolutePrestate)) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to fetch absolute prestate hash: %w", err) + } + return result.GetHash(0), nil +} + +func (f *FaultDisputeGameContract) GetL1Head(ctx context.Context) (common.Hash, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodL1Head)) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to fetch L1 head: %w", err) + } + return result.GetHash(0), nil +} + +func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.GameStatus, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodStatus)) + if err != nil { + return 0, fmt.Errorf("failed to fetch status: %w", err) + } + return gameTypes.GameStatusFromUint8(result.GetUint8(0)) +} + +func (f *FaultDisputeGameContract) GetClaimCount(ctx context.Context) (uint64, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodClaimCount)) + if err != nil { + return 0, fmt.Errorf("failed to fetch claim count: %w", err) + } + return result.GetBigInt(0).Uint64(), nil +} + +func (f *FaultDisputeGameContract) GetClaim(ctx context.Context, idx uint64) (types.Claim, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodClaim, new(big.Int).SetUint64(idx))) + if err != nil { + return types.Claim{}, fmt.Errorf("failed to fetch claim %v: %w", idx, err) + } + return f.decodeClaim(result, int(idx)), nil +} + +func (f *FaultDisputeGameContract) GetAllClaims(ctx context.Context, block rpcblock.Block) ([]types.Claim, error) { + results, err := batching.ReadArray(ctx, f.multiCaller, block, f.contract.Call(methodClaimCount), func(i *big.Int) *batching.ContractCall { + return f.contract.Call(methodClaim, i) + }) + if err != nil { + return nil, fmt.Errorf("failed to load claims: %w", err) + } + + var claims []types.Claim + for idx, result := range results { + claims = append(claims, f.decodeClaim(result, idx)) + } + return claims, nil +} + +func (f *FaultDisputeGameContract) vm(ctx context.Context) (*VMContract, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodVM)) + if err != nil { + return nil, fmt.Errorf("failed to fetch VM addr: %w", err) + } + vmAddr := result.GetAddress(0) + return NewVMContract(vmAddr, f.multiCaller) +} + +func (f *FaultDisputeGameContract) AttackTx(parentContractIndex uint64, pivot common.Hash) (txmgr.TxCandidate, error) { + call := f.contract.Call(methodAttack, new(big.Int).SetUint64(parentContractIndex), pivot) + return call.ToTxCandidate() +} + +func (f *FaultDisputeGameContract) DefendTx(parentContractIndex uint64, pivot common.Hash) (txmgr.TxCandidate, error) { + call := f.contract.Call(methodDefend, new(big.Int).SetUint64(parentContractIndex), pivot) + return call.ToTxCandidate() +} + +func (f *FaultDisputeGameContract) StepTx(claimIdx uint64, isAttack bool, stateData []byte, proof []byte) (txmgr.TxCandidate, error) { + call := f.contract.Call(methodStep, new(big.Int).SetUint64(claimIdx), isAttack, stateData, proof) + return call.ToTxCandidate() +} + +func (f *FaultDisputeGameContract) CallResolveClaim(ctx context.Context, claimIdx uint64) error { + call := f.resolveClaimCall(claimIdx) + _, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, call) + if err != nil { + return fmt.Errorf("failed to call resolve claim: %w", err) + } + return nil +} + +func (f *FaultDisputeGameContract) ResolveClaimTx(claimIdx uint64) (txmgr.TxCandidate, error) { + call := f.resolveClaimCall(claimIdx) + return call.ToTxCandidate() +} + +func (f *FaultDisputeGameContract) resolveClaimCall(claimIdx uint64) *batching.ContractCall { + return f.contract.Call(methodResolveClaim, new(big.Int).SetUint64(claimIdx)) +} + +func (f *FaultDisputeGameContract) CallResolve(ctx context.Context) (gameTypes.GameStatus, error) { + call := f.resolveCall() + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, call) + if err != nil { + return gameTypes.GameStatusInProgress, fmt.Errorf("failed to call resolve: %w", err) + } + return gameTypes.GameStatusFromUint8(result.GetUint8(0)) +} + +func (f *FaultDisputeGameContract) ResolveTx() (txmgr.TxCandidate, error) { + call := f.resolveCall() + return call.ToTxCandidate() +} + +func (f *FaultDisputeGameContract) resolveCall() *batching.ContractCall { + return f.contract.Call(methodResolve) +} + +// decodeClock decodes a uint128 into a Clock duration and timestamp. +func decodeClock(clock *big.Int) *types.Clock { + maxUint64 := new(big.Int).Add(new(big.Int).SetUint64(math.MaxUint64), big.NewInt(1)) + remainder := new(big.Int) + quotient, _ := new(big.Int).QuoRem(clock, maxUint64, remainder) + return types.NewClock(quotient.Uint64(), remainder.Uint64()) +} + +// packClock packs the Clock duration and timestamp into a uint128. +func packClock(c *types.Clock) *big.Int { + duration := new(big.Int).SetUint64(c.Duration) + encoded := new(big.Int).Lsh(duration, 64) + return new(big.Int).Or(encoded, new(big.Int).SetUint64(c.Timestamp)) +} + +func (f *FaultDisputeGameContract) decodeClaim(result *batching.CallResult, contractIndex int) types.Claim { + parentIndex := result.GetUint32(0) + counteredBy := result.GetAddress(1) + claimant := result.GetAddress(2) + bond := result.GetBigInt(3) + claim := result.GetHash(4) + position := result.GetBigInt(5) + clock := result.GetBigInt(6) + return types.Claim{ + ClaimData: types.ClaimData{ + Value: claim, + Position: types.NewPositionFromGIndex(position), + Bond: bond, + }, + CounteredBy: counteredBy, + Claimant: claimant, + Clock: decodeClock(clock), + ContractIndex: contractIndex, + ParentContractIndex: int(parentIndex), + } +} diff --git a/op-challenger/game/fault/contracts/faultdisputegame_test.go b/op-challenger/game/fault/contracts/faultdisputegame_test.go new file mode 100644 index 000000000000..0206ec7c7a2f --- /dev/null +++ b/op-challenger/game/fault/contracts/faultdisputegame_test.go @@ -0,0 +1,447 @@ +package contracts + +import ( + "context" + "math" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +var ( + fdgAddr = common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB") + vmAddr = common.HexToAddress("0x33332842371dFC380576ebb09Ae16Cb6B6c3333") + oracleAddr = common.HexToAddress("0x44442842371dFC380576ebb09Ae16Cb6B6ca4444") +) + +func TestSimpleGetters(t *testing.T) { + tests := []struct { + methodAlias string + method string + args []interface{} + result interface{} + expected interface{} // Defaults to expecting the same as result + call func(game *FaultDisputeGameContract) (any, error) + }{ + { + methodAlias: "status", + method: methodStatus, + result: types.GameStatusChallengerWon, + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetStatus(context.Background()) + }, + }, + { + methodAlias: "gameDuration", + method: methodGameDuration, + result: uint64(5566), + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetGameDuration(context.Background()) + }, + }, + { + methodAlias: "maxGameDepth", + method: methodMaxGameDepth, + result: big.NewInt(128), + expected: faultTypes.Depth(128), + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetMaxGameDepth(context.Background()) + }, + }, + { + methodAlias: "absolutePrestate", + method: methodAbsolutePrestate, + result: common.Hash{0xab}, + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetAbsolutePrestateHash(context.Background()) + }, + }, + { + methodAlias: "claimCount", + method: methodClaimCount, + result: big.NewInt(9876), + expected: uint64(9876), + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetClaimCount(context.Background()) + }, + }, + { + methodAlias: "l1Head", + method: methodL1Head, + result: common.Hash{0xdd, 0xbb}, + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetL1Head(context.Background()) + }, + }, + { + methodAlias: "resolve", + method: methodResolve, + result: types.GameStatusInProgress, + call: func(game *FaultDisputeGameContract) (any, error) { + return game.CallResolve(context.Background()) + }, + }, + } + for _, test := range tests { + test := test + t.Run(test.methodAlias, func(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + stubRpc.SetResponse(fdgAddr, test.method, rpcblock.Latest, nil, []interface{}{test.result}) + status, err := test.call(game) + require.NoError(t, err) + expected := test.expected + if expected == nil { + expected = test.result + } + require.Equal(t, expected, status) + }) + } +} + +func TestClock_EncodingDecoding(t *testing.T) { + t.Run("DurationAndTimestamp", func(t *testing.T) { + by := common.Hex2Bytes("00000000000000050000000000000002") + encoded := new(big.Int).SetBytes(by) + clock := decodeClock(encoded) + require.Equal(t, uint64(5), clock.Duration) + require.Equal(t, uint64(2), clock.Timestamp) + require.Equal(t, encoded, packClock(clock)) + }) + + t.Run("ZeroDuration", func(t *testing.T) { + by := common.Hex2Bytes("00000000000000000000000000000002") + encoded := new(big.Int).SetBytes(by) + clock := decodeClock(encoded) + require.Equal(t, uint64(0), clock.Duration) + require.Equal(t, uint64(2), clock.Timestamp) + require.Equal(t, encoded, packClock(clock)) + }) + + t.Run("ZeroTimestamp", func(t *testing.T) { + by := common.Hex2Bytes("00000000000000050000000000000000") + encoded := new(big.Int).SetBytes(by) + clock := decodeClock(encoded) + require.Equal(t, uint64(5), clock.Duration) + require.Equal(t, uint64(0), clock.Timestamp) + require.Equal(t, encoded, packClock(clock)) + }) + + t.Run("ZeroClock", func(t *testing.T) { + by := common.Hex2Bytes("00000000000000000000000000000000") + encoded := new(big.Int).SetBytes(by) + clock := decodeClock(encoded) + require.Equal(t, uint64(0), clock.Duration) + require.Equal(t, uint64(0), clock.Timestamp) + require.Equal(t, encoded.Uint64(), packClock(clock).Uint64()) + }) +} + +func TestGetOracleAddr(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + stubRpc.SetResponse(fdgAddr, methodVM, rpcblock.Latest, nil, []interface{}{vmAddr}) + stubRpc.SetResponse(vmAddr, methodOracle, rpcblock.Latest, nil, []interface{}{oracleAddr}) + + actual, err := game.GetOracle(context.Background()) + require.NoError(t, err) + require.Equal(t, oracleAddr, actual.Addr()) +} + +func TestGetClaim(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + idx := big.NewInt(2) + parentIndex := uint32(1) + counteredBy := common.Address{0x01} + claimant := common.Address{0x02} + bond := big.NewInt(5) + value := common.Hash{0xab} + position := big.NewInt(2) + clock := big.NewInt(1234) + stubRpc.SetResponse(fdgAddr, methodClaim, rpcblock.Latest, []interface{}{idx}, []interface{}{parentIndex, counteredBy, claimant, bond, value, position, clock}) + status, err := game.GetClaim(context.Background(), idx.Uint64()) + require.NoError(t, err) + require.Equal(t, faultTypes.Claim{ + ClaimData: faultTypes.ClaimData{ + Value: value, + Position: faultTypes.NewPositionFromGIndex(position), + Bond: bond, + }, + CounteredBy: counteredBy, + Claimant: claimant, + Clock: decodeClock(big.NewInt(1234)), + ContractIndex: int(idx.Uint64()), + ParentContractIndex: 1, + }, status) +} + +func TestGetAllClaims(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + claim0 := faultTypes.Claim{ + ClaimData: faultTypes.ClaimData{ + Value: common.Hash{0xaa}, + Position: faultTypes.NewPositionFromGIndex(big.NewInt(1)), + Bond: big.NewInt(5), + }, + CounteredBy: common.Address{0x01}, + Claimant: common.Address{0x02}, + Clock: decodeClock(big.NewInt(1234)), + ContractIndex: 0, + ParentContractIndex: math.MaxUint32, + } + claim1 := faultTypes.Claim{ + ClaimData: faultTypes.ClaimData{ + Value: common.Hash{0xab}, + Position: faultTypes.NewPositionFromGIndex(big.NewInt(2)), + Bond: big.NewInt(5), + }, + CounteredBy: common.Address{0x02}, + Claimant: common.Address{0x01}, + Clock: decodeClock(big.NewInt(4455)), + ContractIndex: 1, + ParentContractIndex: 0, + } + claim2 := faultTypes.Claim{ + ClaimData: faultTypes.ClaimData{ + Value: common.Hash{0xbb}, + Position: faultTypes.NewPositionFromGIndex(big.NewInt(6)), + Bond: big.NewInt(5), + }, + Claimant: common.Address{0x02}, + Clock: decodeClock(big.NewInt(7777)), + ContractIndex: 2, + ParentContractIndex: 1, + } + expectedClaims := []faultTypes.Claim{claim0, claim1, claim2} + block := rpcblock.ByNumber(42) + stubRpc.SetResponse(fdgAddr, methodClaimCount, block, nil, []interface{}{big.NewInt(int64(len(expectedClaims)))}) + for _, claim := range expectedClaims { + expectGetClaim(stubRpc, block, claim) + } + claims, err := game.GetAllClaims(context.Background(), block) + require.NoError(t, err) + require.Equal(t, expectedClaims, claims) +} + +func TestGetBalance(t *testing.T) { + wethAddr := common.Address{0x11, 0x55, 0x66} + balance := big.NewInt(9995877) + block := rpcblock.ByNumber(424) + stubRpc, game := setupFaultDisputeGameTest(t) + stubRpc.SetResponse(fdgAddr, methodWETH, block, nil, []interface{}{wethAddr}) + stubRpc.AddExpectedCall(batchingTest.NewGetBalanceCall(wethAddr, block, balance)) + + actualBalance, actualAddr, err := game.GetBalance(context.Background(), block) + require.NoError(t, err) + require.Equal(t, wethAddr, actualAddr) + require.Truef(t, balance.Cmp(actualBalance) == 0, "Expected balance %v but was %v", balance, actualBalance) +} + +func TestCallResolveClaim(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + stubRpc.SetResponse(fdgAddr, methodResolveClaim, rpcblock.Latest, []interface{}{big.NewInt(123)}, nil) + err := game.CallResolveClaim(context.Background(), 123) + require.NoError(t, err) +} + +func TestResolveClaimTxTest(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + stubRpc.SetResponse(fdgAddr, methodResolveClaim, rpcblock.Latest, []interface{}{big.NewInt(123)}, nil) + tx, err := game.ResolveClaimTx(123) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func TestResolveTx(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + stubRpc.SetResponse(fdgAddr, methodResolve, rpcblock.Latest, nil, nil) + tx, err := game.ResolveTx() + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func TestAttackTx(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + value := common.Hash{0xaa} + stubRpc.SetResponse(fdgAddr, methodAttack, rpcblock.Latest, []interface{}{big.NewInt(111), value}, nil) + tx, err := game.AttackTx(111, value) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func TestDefendTx(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + value := common.Hash{0xaa} + stubRpc.SetResponse(fdgAddr, methodDefend, rpcblock.Latest, []interface{}{big.NewInt(111), value}, nil) + tx, err := game.DefendTx(111, value) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func TestStepTx(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + stateData := []byte{1, 2, 3} + proofData := []byte{4, 5, 6, 7, 8, 9} + stubRpc.SetResponse(fdgAddr, methodStep, rpcblock.Latest, []interface{}{big.NewInt(111), true, stateData, proofData}, nil) + tx, err := game.StepTx(111, true, stateData, proofData) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func expectGetClaim(stubRpc *batchingTest.AbiBasedRpc, block rpcblock.Block, claim faultTypes.Claim) { + stubRpc.SetResponse( + fdgAddr, + methodClaim, + block, + []interface{}{big.NewInt(int64(claim.ContractIndex))}, + []interface{}{ + uint32(claim.ParentContractIndex), + claim.CounteredBy, + claim.Claimant, + claim.Bond, + claim.Value, + claim.Position.ToGIndex(), + packClock(claim.Clock), + }) +} + +func TestGetBlockRange(t *testing.T) { + stubRpc, contract := setupFaultDisputeGameTest(t) + expectedStart := uint64(65) + expectedEnd := uint64(102) + stubRpc.SetResponse(fdgAddr, methodStartingBlockNumber, rpcblock.Latest, nil, []interface{}{new(big.Int).SetUint64(expectedStart)}) + stubRpc.SetResponse(fdgAddr, methodL2BlockNumber, rpcblock.Latest, nil, []interface{}{new(big.Int).SetUint64(expectedEnd)}) + start, end, err := contract.GetBlockRange(context.Background()) + require.NoError(t, err) + require.Equal(t, expectedStart, start) + require.Equal(t, expectedEnd, end) +} + +func TestGetSplitDepth(t *testing.T) { + stubRpc, contract := setupFaultDisputeGameTest(t) + expectedSplitDepth := faultTypes.Depth(15) + stubRpc.SetResponse(fdgAddr, methodSplitDepth, rpcblock.Latest, nil, []interface{}{new(big.Int).SetUint64(uint64(expectedSplitDepth))}) + splitDepth, err := contract.GetSplitDepth(context.Background()) + require.NoError(t, err) + require.Equal(t, expectedSplitDepth, splitDepth) +} + +func TestGetGameMetadata(t *testing.T) { + stubRpc, contract := setupFaultDisputeGameTest(t) + expectedL1Head := common.Hash{0x0a, 0x0b} + expectedL2BlockNumber := uint64(123) + expectedGameDuration := uint64(456) + expectedRootClaim := common.Hash{0x01, 0x02} + expectedStatus := types.GameStatusChallengerWon + block := rpcblock.ByNumber(889) + stubRpc.SetResponse(fdgAddr, methodL1Head, block, nil, []interface{}{expectedL1Head}) + stubRpc.SetResponse(fdgAddr, methodL2BlockNumber, block, nil, []interface{}{new(big.Int).SetUint64(expectedL2BlockNumber)}) + stubRpc.SetResponse(fdgAddr, methodRootClaim, block, nil, []interface{}{expectedRootClaim}) + stubRpc.SetResponse(fdgAddr, methodStatus, block, nil, []interface{}{expectedStatus}) + stubRpc.SetResponse(fdgAddr, methodGameDuration, block, nil, []interface{}{expectedGameDuration}) + l1Head, l2BlockNumber, rootClaim, status, duration, err := contract.GetGameMetadata(context.Background(), block) + require.NoError(t, err) + require.Equal(t, expectedL1Head, l1Head) + require.Equal(t, expectedL2BlockNumber, l2BlockNumber) + require.Equal(t, expectedRootClaim, rootClaim) + require.Equal(t, expectedStatus, status) + require.Equal(t, expectedGameDuration, duration) +} + +func TestGetStartingRootHash(t *testing.T) { + stubRpc, contract := setupFaultDisputeGameTest(t) + expectedOutputRoot := common.HexToHash("0x1234") + stubRpc.SetResponse(fdgAddr, methodStartingRootHash, rpcblock.Latest, nil, []interface{}{expectedOutputRoot}) + startingOutputRoot, err := contract.GetStartingRootHash(context.Background()) + require.NoError(t, err) + require.Equal(t, expectedOutputRoot, startingOutputRoot) +} + +func TestFaultDisputeGame_UpdateOracleTx(t *testing.T) { + t.Run("Local", func(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + data := faultTypes.NewPreimageOracleData(common.Hash{0x01, 0xbc}.Bytes(), []byte{1, 2, 3, 4, 5, 6, 7}, 16) + claimIdx := uint64(6) + stubRpc.SetResponse(fdgAddr, methodAddLocalData, rpcblock.Latest, []interface{}{ + data.GetIdent(), + new(big.Int).SetUint64(claimIdx), + new(big.Int).SetUint64(uint64(data.OracleOffset)), + }, nil) + tx, err := game.UpdateOracleTx(context.Background(), claimIdx, data) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) + }) + + t.Run("Global", func(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + data := faultTypes.NewPreimageOracleData(common.Hash{0x02, 0xbc}.Bytes(), []byte{1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15}, 16) + claimIdx := uint64(6) + stubRpc.SetResponse(fdgAddr, methodVM, rpcblock.Latest, nil, []interface{}{vmAddr}) + stubRpc.SetResponse(vmAddr, methodOracle, rpcblock.Latest, nil, []interface{}{oracleAddr}) + stubRpc.SetResponse(oracleAddr, methodLoadKeccak256PreimagePart, rpcblock.Latest, []interface{}{ + new(big.Int).SetUint64(uint64(data.OracleOffset)), + data.GetPreimageWithoutSize(), + }, nil) + tx, err := game.UpdateOracleTx(context.Background(), claimIdx, data) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) + }) +} + +func TestFaultDisputeGame_GetCredit(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + addr := common.Address{0x01} + expectedCredit := big.NewInt(4284) + expectedStatus := types.GameStatusChallengerWon + stubRpc.SetResponse(fdgAddr, methodCredit, rpcblock.Latest, []interface{}{addr}, []interface{}{expectedCredit}) + stubRpc.SetResponse(fdgAddr, methodStatus, rpcblock.Latest, nil, []interface{}{expectedStatus}) + + actualCredit, actualStatus, err := game.GetCredit(context.Background(), addr) + require.NoError(t, err) + require.Equal(t, expectedCredit, actualCredit) + require.Equal(t, expectedStatus, actualStatus) +} + +func TestFaultDisputeGame_GetCredits(t *testing.T) { + stubRpc, game := setupFaultDisputeGameTest(t) + + block := rpcblock.ByNumber(482) + + addrs := []common.Address{{0x01}, {0x02}, {0x03}} + expected := []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(0)} + + for i, addr := range addrs { + stubRpc.SetResponse(fdgAddr, methodCredit, block, []interface{}{addr}, []interface{}{expected[i]}) + } + + actual, err := game.GetCredits(context.Background(), block, addrs...) + require.NoError(t, err) + require.Equal(t, len(expected), len(actual)) + for i := range expected { + require.Zerof(t, expected[i].Cmp(actual[i]), "expected: %v actual: %v", expected[i], actual[i]) + } +} + +func setupFaultDisputeGameTest(t *testing.T) (*batchingTest.AbiBasedRpc, *FaultDisputeGameContract) { + fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() + require.NoError(t, err) + + vmAbi, err := bindings.MIPSMetaData.GetAbi() + require.NoError(t, err) + oracleAbi, err := bindings.PreimageOracleMetaData.GetAbi() + require.NoError(t, err) + + stubRpc := batchingTest.NewAbiBasedRpc(t, fdgAddr, fdgAbi) + stubRpc.AddContract(vmAddr, vmAbi) + stubRpc.AddContract(oracleAddr, oracleAbi) + caller := batching.NewMultiCaller(stubRpc, batching.DefaultBatchSize) + game, err := NewFaultDisputeGameContract(fdgAddr, caller) + require.NoError(t, err) + return stubRpc, game +} diff --git a/op-challenger/game/fault/contracts/gamefactory.go b/op-challenger/game/fault/contracts/gamefactory.go new file mode 100644 index 000000000000..346a0eea7390 --- /dev/null +++ b/op-challenger/game/fault/contracts/gamefactory.go @@ -0,0 +1,152 @@ +package contracts + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" +) + +const ( + methodGameCount = "gameCount" + methodGameAtIndex = "gameAtIndex" + methodGameImpls = "gameImpls" + methodCreateGame = "create" + methodGames = "games" +) + +type DisputeGameFactoryContract struct { + multiCaller *batching.MultiCaller + contract *batching.BoundContract +} + +func NewDisputeGameFactoryContract(addr common.Address, caller *batching.MultiCaller) (*DisputeGameFactoryContract, error) { + factoryAbi, err := bindings.DisputeGameFactoryMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to load dispute game factory ABI: %w", err) + } + return &DisputeGameFactoryContract{ + multiCaller: caller, + contract: batching.NewBoundContract(factoryAbi, addr), + }, nil +} + +func (f *DisputeGameFactoryContract) GetGameFromParameters(ctx context.Context, traceType uint32, outputRoot common.Hash, l2BlockNum uint64) (common.Address, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGames, traceType, outputRoot, common.BigToHash(big.NewInt(int64(l2BlockNum))).Bytes())) + if err != nil { + return common.Address{}, fmt.Errorf("failed to fetch game from parameters: %w", err) + } + return result.GetAddress(0), nil +} + +func (f *DisputeGameFactoryContract) GetGameCount(ctx context.Context, blockHash common.Hash) (uint64, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.ByHash(blockHash), f.contract.Call(methodGameCount)) + if err != nil { + return 0, fmt.Errorf("failed to load game count: %w", err) + } + return result.GetBigInt(0).Uint64(), nil +} + +func (f *DisputeGameFactoryContract) GetGame(ctx context.Context, idx uint64, blockHash common.Hash) (types.GameMetadata, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.ByHash(blockHash), f.contract.Call(methodGameAtIndex, new(big.Int).SetUint64(idx))) + if err != nil { + return types.GameMetadata{}, fmt.Errorf("failed to load game %v: %w", idx, err) + } + return f.decodeGame(result), nil +} + +func (f *DisputeGameFactoryContract) GetGameImpl(ctx context.Context, gameType uint32) (common.Address, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGameImpls, gameType)) + if err != nil { + return common.Address{}, fmt.Errorf("failed to load game impl for type %v: %w", gameType, err) + } + return result.GetAddress(0), nil +} + +func (f *DisputeGameFactoryContract) GetGamesAtOrAfter(ctx context.Context, blockHash common.Hash, earliestTimestamp uint64) ([]types.GameMetadata, error) { + count, err := f.GetGameCount(ctx, blockHash) + if err != nil { + return nil, err + } + batchSize := uint64(f.multiCaller.BatchSize()) + rangeEnd := count + + var games []types.GameMetadata + for { + if rangeEnd == uint64(0) { + // rangeEnd is exclusive so if its 0 we've reached the end. + return games, nil + } + rangeStart := uint64(0) + if rangeEnd > batchSize { + rangeStart = rangeEnd - batchSize + } + calls := make([]batching.Call, 0, rangeEnd-rangeStart) + for i := rangeEnd - 1; ; i-- { + calls = append(calls, f.contract.Call(methodGameAtIndex, new(big.Int).SetUint64(i))) + // Break once we've added the last call to avoid underflow when rangeStart == 0 + if i == rangeStart { + break + } + } + + results, err := f.multiCaller.Call(ctx, rpcblock.ByHash(blockHash), calls...) + if err != nil { + return nil, fmt.Errorf("failed to fetch games: %w", err) + } + + for _, result := range results { + game := f.decodeGame(result) + if game.Timestamp < earliestTimestamp { + return games, nil + } + games = append(games, game) + } + rangeEnd = rangeStart + } +} + +func (f *DisputeGameFactoryContract) GetAllGames(ctx context.Context, blockHash common.Hash) ([]types.GameMetadata, error) { + count, err := f.GetGameCount(ctx, blockHash) + if err != nil { + return nil, err + } + + calls := make([]batching.Call, count) + for i := uint64(0); i < count; i++ { + calls[i] = f.contract.Call(methodGameAtIndex, new(big.Int).SetUint64(i)) + } + + results, err := f.multiCaller.Call(ctx, rpcblock.ByHash(blockHash), calls...) + if err != nil { + return nil, fmt.Errorf("failed to fetch games: %w", err) + } + + var games []types.GameMetadata + for _, result := range results { + games = append(games, f.decodeGame(result)) + } + return games, nil +} + +func (f *DisputeGameFactoryContract) CreateTx(traceType uint32, outputRoot common.Hash, l2BlockNum uint64) (txmgr.TxCandidate, error) { + call := f.contract.Call(methodCreateGame, traceType, outputRoot, common.BigToHash(big.NewInt(int64(l2BlockNum))).Bytes()) + return call.ToTxCandidate() +} + +func (f *DisputeGameFactoryContract) decodeGame(result *batching.CallResult) types.GameMetadata { + gameType := result.GetUint32(0) + timestamp := result.GetUint64(1) + proxy := result.GetAddress(2) + return types.GameMetadata{ + GameType: gameType, + Timestamp: timestamp, + Proxy: proxy, + } +} diff --git a/op-challenger/game/fault/contracts/gamefactory_test.go b/op-challenger/game/fault/contracts/gamefactory_test.go new file mode 100644 index 000000000000..f7f98760eebb --- /dev/null +++ b/op-challenger/game/fault/contracts/gamefactory_test.go @@ -0,0 +1,230 @@ +package contracts + +import ( + "context" + "fmt" + "math/big" + "slices" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +var ( + factoryAddr = common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB") + batchSize = 5 +) + +func TestDisputeGameFactorySimpleGetters(t *testing.T) { + blockHash := common.Hash{0xbb, 0xcd} + tests := []struct { + method string + args []interface{} + result interface{} + expected interface{} // Defaults to expecting the same as result + call func(game *DisputeGameFactoryContract) (any, error) + }{ + { + method: methodGameCount, + result: big.NewInt(9876), + expected: uint64(9876), + call: func(game *DisputeGameFactoryContract) (any, error) { + return game.GetGameCount(context.Background(), blockHash) + }, + }, + } + for _, test := range tests { + test := test + t.Run(test.method, func(t *testing.T) { + stubRpc, factory := setupDisputeGameFactoryTest(t) + stubRpc.SetResponse(factoryAddr, test.method, rpcblock.ByHash(blockHash), nil, []interface{}{test.result}) + status, err := test.call(factory) + require.NoError(t, err) + expected := test.expected + if expected == nil { + expected = test.result + } + require.Equal(t, expected, status) + }) + } +} + +func TestLoadGame(t *testing.T) { + blockHash := common.Hash{0xbb, 0xce} + stubRpc, factory := setupDisputeGameFactoryTest(t) + game0 := types.GameMetadata{ + GameType: 0, + Timestamp: 1234, + Proxy: common.Address{0xaa}, + } + game1 := types.GameMetadata{ + GameType: 1, + Timestamp: 5678, + Proxy: common.Address{0xbb}, + } + game2 := types.GameMetadata{ + GameType: 99, + Timestamp: 9988, + Proxy: common.Address{0xcc}, + } + expectedGames := []types.GameMetadata{game0, game1, game2} + for idx, expected := range expectedGames { + expectGetGame(stubRpc, idx, blockHash, expected) + actual, err := factory.GetGame(context.Background(), uint64(idx), blockHash) + require.NoError(t, err) + require.Equal(t, expected, actual) + } +} + +func TestGetAllGames(t *testing.T) { + blockHash := common.Hash{0xbb, 0xce} + stubRpc, factory := setupDisputeGameFactoryTest(t) + game0 := types.GameMetadata{ + GameType: 0, + Timestamp: 1234, + Proxy: common.Address{0xaa}, + } + game1 := types.GameMetadata{ + GameType: 1, + Timestamp: 5678, + Proxy: common.Address{0xbb}, + } + game2 := types.GameMetadata{ + GameType: 99, + Timestamp: 9988, + Proxy: common.Address{0xcc}, + } + + expectedGames := []types.GameMetadata{game0, game1, game2} + stubRpc.SetResponse(factoryAddr, methodGameCount, rpcblock.ByHash(blockHash), nil, []interface{}{big.NewInt(int64(len(expectedGames)))}) + for idx, expected := range expectedGames { + expectGetGame(stubRpc, idx, blockHash, expected) + } + actualGames, err := factory.GetAllGames(context.Background(), blockHash) + require.NoError(t, err) + require.Equal(t, expectedGames, actualGames) +} + +func TestGetAllGamesAtOrAfter(t *testing.T) { + tests := []struct { + gameCount int + earliestGameIdx int + }{ + {gameCount: batchSize * 4, earliestGameIdx: batchSize + 3}, + {gameCount: 0, earliestGameIdx: 0}, + {gameCount: batchSize * 2, earliestGameIdx: batchSize}, + {gameCount: batchSize * 2, earliestGameIdx: batchSize + 1}, + {gameCount: batchSize * 2, earliestGameIdx: batchSize - 1}, + {gameCount: batchSize * 2, earliestGameIdx: batchSize * 2}, + {gameCount: batchSize * 2, earliestGameIdx: batchSize*2 + 1}, + {gameCount: batchSize - 2, earliestGameIdx: batchSize - 3}, + } + for _, test := range tests { + test := test + t.Run(fmt.Sprintf("Count_%v_Start_%v", test.gameCount, test.earliestGameIdx), func(t *testing.T) { + blockHash := common.Hash{0xbb, 0xce} + stubRpc, factory := setupDisputeGameFactoryTest(t) + var allGames []types.GameMetadata + for i := 0; i < test.gameCount; i++ { + allGames = append(allGames, types.GameMetadata{ + GameType: uint32(i), + Timestamp: uint64(i), + Proxy: common.Address{byte(i)}, + }) + } + + stubRpc.SetResponse(factoryAddr, methodGameCount, rpcblock.ByHash(blockHash), nil, []interface{}{big.NewInt(int64(len(allGames)))}) + for idx, expected := range allGames { + expectGetGame(stubRpc, idx, blockHash, expected) + } + // Set an earliest timestamp that's in the middle of a batch + earliestTimestamp := uint64(test.earliestGameIdx) + actualGames, err := factory.GetGamesAtOrAfter(context.Background(), blockHash, earliestTimestamp) + require.NoError(t, err) + // Games come back in descending timestamp order + var expectedGames []types.GameMetadata + if test.earliestGameIdx < len(allGames) { + expectedGames = slices.Clone(allGames[test.earliestGameIdx:]) + } + slices.Reverse(expectedGames) + require.Equal(t, len(expectedGames), len(actualGames)) + if len(expectedGames) != 0 { + // Don't assert equal for empty arrays, we accept nil or empty array + require.Equal(t, expectedGames, actualGames) + } + }) + } +} + +func TestGetGameFromParameters(t *testing.T) { + stubRpc, factory := setupDisputeGameFactoryTest(t) + traceType := uint32(123) + outputRoot := common.Hash{0x01} + l2BlockNum := common.BigToHash(big.NewInt(456)).Bytes() + stubRpc.SetResponse( + factoryAddr, + methodGames, + rpcblock.Latest, + []interface{}{traceType, outputRoot, l2BlockNum}, + []interface{}{common.Address{0xaa}, uint64(1)}, + ) + addr, err := factory.GetGameFromParameters(context.Background(), traceType, outputRoot, uint64(456)) + require.NoError(t, err) + require.Equal(t, common.Address{0xaa}, addr) +} + +func TestGetGameImpl(t *testing.T) { + stubRpc, factory := setupDisputeGameFactoryTest(t) + gameType := uint32(3) + gameImplAddr := common.Address{0xaa} + stubRpc.SetResponse( + factoryAddr, + methodGameImpls, + rpcblock.Latest, + []interface{}{gameType}, + []interface{}{gameImplAddr}) + actual, err := factory.GetGameImpl(context.Background(), gameType) + require.NoError(t, err) + require.Equal(t, gameImplAddr, actual) +} + +func expectGetGame(stubRpc *batchingTest.AbiBasedRpc, idx int, blockHash common.Hash, game types.GameMetadata) { + stubRpc.SetResponse( + factoryAddr, + methodGameAtIndex, + rpcblock.ByHash(blockHash), + []interface{}{big.NewInt(int64(idx))}, + []interface{}{ + game.GameType, + game.Timestamp, + game.Proxy, + }) +} + +func TestCreateTx(t *testing.T) { + stubRpc, factory := setupDisputeGameFactoryTest(t) + traceType := uint32(123) + outputRoot := common.Hash{0x01} + l2BlockNum := common.BigToHash(big.NewInt(456)).Bytes() + stubRpc.SetResponse(factoryAddr, methodCreateGame, rpcblock.Latest, []interface{}{traceType, outputRoot, l2BlockNum}, nil) + tx, err := factory.CreateTx(traceType, outputRoot, uint64(456)) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func setupDisputeGameFactoryTest(t *testing.T) (*batchingTest.AbiBasedRpc, *DisputeGameFactoryContract) { + fdgAbi, err := bindings.DisputeGameFactoryMetaData.GetAbi() + require.NoError(t, err) + + stubRpc := batchingTest.NewAbiBasedRpc(t, factoryAddr, fdgAbi) + caller := batching.NewMultiCaller(stubRpc, batchSize) + factory, err := NewDisputeGameFactoryContract(factoryAddr, caller) + require.NoError(t, err) + return stubRpc, factory +} diff --git a/op-challenger/game/fault/contracts/oracle.go b/op-challenger/game/fault/contracts/oracle.go new file mode 100644 index 000000000000..4524034cffe9 --- /dev/null +++ b/op-challenger/game/fault/contracts/oracle.go @@ -0,0 +1,412 @@ +package contracts + +import ( + "context" + "encoding/binary" + "errors" + "fmt" + "math" + "math/big" + "sync/atomic" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/merkle" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + preimage "github.com/ethereum-optimism/optimism/op-preimage" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" +) + +const ( + methodInitLPP = "initLPP" + methodAddLeavesLPP = "addLeavesLPP" + methodSqueezeLPP = "squeezeLPP" + methodLoadKeccak256PreimagePart = "loadKeccak256PreimagePart" + methodLoadSha256PreimagePart = "loadSha256PreimagePart" + methodLoadBlobPreimagePart = "loadBlobPreimagePart" + methodLoadPrecompilePreimagePart = "loadPrecompilePreimagePart" + methodProposalCount = "proposalCount" + methodProposals = "proposals" + methodProposalMetadata = "proposalMetadata" + methodProposalBlocksLen = "proposalBlocksLen" + methodProposalBlocks = "proposalBlocks" + methodPreimagePartOk = "preimagePartOk" + methodMinProposalSize = "minProposalSize" + methodChallengeFirstLPP = "challengeFirstLPP" + methodChallengeLPP = "challengeLPP" + methodChallengePeriod = "challengePeriod" + methodGetTreeRootLPP = "getTreeRootLPP" + methodMinBondSizeLPP = "MIN_BOND_SIZE" +) + +var ( + ErrInvalidAddLeavesCall = errors.New("tx is not a valid addLeaves call") + ErrInvalidPreimageKey = errors.New("invalid preimage key") + ErrUnsupportedKeyType = errors.New("unsupported preimage key type") +) + +// PreimageOracleContract is a binding that works with contracts implementing the IPreimageOracle interface +type PreimageOracleContract struct { + addr common.Address + multiCaller *batching.MultiCaller + contract *batching.BoundContract + + // challengePeriod caches the challenge period from the contract once it has been loaded. + // 0 indicates the period has not been loaded yet. + challengePeriod atomic.Uint64 + // minBondSizeLPP caches the minimum bond size for large preimages from the contract once it has been loaded. + // 0 indicates the value has not been loaded yet. + minBondSizeLPP atomic.Uint64 +} + +// toPreimageOracleLeaf converts a Leaf to the contract [bindings.PreimageOracleLeaf] type. +func toPreimageOracleLeaf(l keccakTypes.Leaf) bindings.PreimageOracleLeaf { + return bindings.PreimageOracleLeaf{ + Input: l.Input[:], + Index: new(big.Int).SetUint64(l.Index), + StateCommitment: l.StateCommitment, + } +} + +func NewPreimageOracleContract(addr common.Address, caller *batching.MultiCaller) (*PreimageOracleContract, error) { + oracleAbi, err := bindings.PreimageOracleMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to load preimage oracle ABI: %w", err) + } + + return &PreimageOracleContract{ + addr: addr, + multiCaller: caller, + contract: batching.NewBoundContract(oracleAbi, addr), + }, nil +} + +func (c *PreimageOracleContract) Addr() common.Address { + return c.addr +} + +func (c *PreimageOracleContract) AddGlobalDataTx(data *types.PreimageOracleData) (txmgr.TxCandidate, error) { + if len(data.OracleKey) == 0 { + return txmgr.TxCandidate{}, ErrInvalidPreimageKey + } + keyType := preimage.KeyType(data.OracleKey[0]) + switch keyType { + case preimage.Keccak256KeyType: + call := c.contract.Call(methodLoadKeccak256PreimagePart, new(big.Int).SetUint64(uint64(data.OracleOffset)), data.GetPreimageWithoutSize()) + return call.ToTxCandidate() + case preimage.Sha256KeyType: + call := c.contract.Call(methodLoadSha256PreimagePart, new(big.Int).SetUint64(uint64(data.OracleOffset)), data.GetPreimageWithoutSize()) + return call.ToTxCandidate() + case preimage.BlobKeyType: + call := c.contract.Call(methodLoadBlobPreimagePart, + new(big.Int).SetUint64(data.BlobFieldIndex), + new(big.Int).SetBytes(data.GetPreimageWithoutSize()), + data.BlobCommitment, + data.BlobProof, + new(big.Int).SetUint64(uint64(data.OracleOffset))) + return call.ToTxCandidate() + case preimage.PrecompileKeyType: + call := c.contract.Call(methodLoadPrecompilePreimagePart, + new(big.Int).SetUint64(uint64(data.OracleOffset)), + data.GetPrecompileAddress(), + data.GetPrecompileInput()) + return call.ToTxCandidate() + default: + return txmgr.TxCandidate{}, fmt.Errorf("%w: %v", ErrUnsupportedKeyType, keyType) + } +} + +func (c *PreimageOracleContract) InitLargePreimage(uuid *big.Int, partOffset uint32, claimedSize uint32) (txmgr.TxCandidate, error) { + call := c.contract.Call(methodInitLPP, uuid, partOffset, claimedSize) + return call.ToTxCandidate() +} + +func (c *PreimageOracleContract) AddLeaves(uuid *big.Int, startingBlockIndex *big.Int, input []byte, commitments []common.Hash, finalize bool) (txmgr.TxCandidate, error) { + call := c.contract.Call(methodAddLeavesLPP, uuid, startingBlockIndex, input, commitments, finalize) + return call.ToTxCandidate() +} + +// MinLargePreimageSize returns the minimum size of a large preimage. +func (c *PreimageOracleContract) MinLargePreimageSize(ctx context.Context) (uint64, error) { + result, err := c.multiCaller.SingleCall(ctx, rpcblock.Latest, c.contract.Call(methodMinProposalSize)) + if err != nil { + return 0, fmt.Errorf("failed to fetch min lpp size bytes: %w", err) + } + return result.GetBigInt(0).Uint64(), nil +} + +// ChallengePeriod returns the challenge period for large preimages. +func (c *PreimageOracleContract) ChallengePeriod(ctx context.Context) (uint64, error) { + if period := c.challengePeriod.Load(); period != 0 { + return period, nil + } + result, err := c.multiCaller.SingleCall(ctx, rpcblock.Latest, c.contract.Call(methodChallengePeriod)) + if err != nil { + return 0, fmt.Errorf("failed to fetch challenge period: %w", err) + } + period := result.GetBigInt(0).Uint64() + c.challengePeriod.Store(period) + return period, nil +} + +func (c *PreimageOracleContract) CallSqueeze( + ctx context.Context, + claimant common.Address, + uuid *big.Int, + prestateMatrix keccakTypes.StateSnapshot, + preState keccakTypes.Leaf, + preStateProof merkle.Proof, + postState keccakTypes.Leaf, + postStateProof merkle.Proof, +) error { + call := c.contract.Call(methodSqueezeLPP, claimant, uuid, abiEncodeSnapshot(prestateMatrix), toPreimageOracleLeaf(preState), preStateProof, toPreimageOracleLeaf(postState), postStateProof) + _, err := c.multiCaller.SingleCall(ctx, rpcblock.Latest, call) + if err != nil { + return fmt.Errorf("failed to call squeeze: %w", err) + } + return nil +} + +func (c *PreimageOracleContract) Squeeze( + claimant common.Address, + uuid *big.Int, + prestateMatrix keccakTypes.StateSnapshot, + preState keccakTypes.Leaf, + preStateProof merkle.Proof, + postState keccakTypes.Leaf, + postStateProof merkle.Proof, +) (txmgr.TxCandidate, error) { + call := c.contract.Call( + methodSqueezeLPP, + claimant, + uuid, + abiEncodeSnapshot(prestateMatrix), + toPreimageOracleLeaf(preState), + preStateProof, + toPreimageOracleLeaf(postState), + postStateProof, + ) + return call.ToTxCandidate() +} + +func abiEncodeSnapshot(packedState keccakTypes.StateSnapshot) bindings.LibKeccakStateMatrix { + return bindings.LibKeccakStateMatrix{State: packedState} +} + +func (c *PreimageOracleContract) GetActivePreimages(ctx context.Context, blockHash common.Hash) ([]keccakTypes.LargePreimageMetaData, error) { + block := rpcblock.ByHash(blockHash) + results, err := batching.ReadArray(ctx, c.multiCaller, block, c.contract.Call(methodProposalCount), func(i *big.Int) *batching.ContractCall { + return c.contract.Call(methodProposals, i) + }) + if err != nil { + return nil, fmt.Errorf("failed to load claims: %w", err) + } + + var idents []keccakTypes.LargePreimageIdent + for _, result := range results { + idents = append(idents, c.decodePreimageIdent(result)) + } + + return c.GetProposalMetadata(ctx, block, idents...) +} + +func (c *PreimageOracleContract) GetProposalMetadata(ctx context.Context, block rpcblock.Block, idents ...keccakTypes.LargePreimageIdent) ([]keccakTypes.LargePreimageMetaData, error) { + var calls []batching.Call + for _, ident := range idents { + calls = append(calls, c.contract.Call(methodProposalMetadata, ident.Claimant, ident.UUID)) + } + results, err := c.multiCaller.Call(ctx, block, calls...) + if err != nil { + return nil, fmt.Errorf("failed to load proposal metadata: %w", err) + } + var proposals []keccakTypes.LargePreimageMetaData + for i, result := range results { + meta := metadata(result.GetBytes32(0)) + proposals = append(proposals, keccakTypes.LargePreimageMetaData{ + LargePreimageIdent: idents[i], + Timestamp: meta.timestamp(), + PartOffset: meta.partOffset(), + ClaimedSize: meta.claimedSize(), + BlocksProcessed: meta.blocksProcessed(), + BytesProcessed: meta.bytesProcessed(), + Countered: meta.countered(), + }) + } + return proposals, nil +} + +func (c *PreimageOracleContract) GetProposalTreeRoot(ctx context.Context, block rpcblock.Block, ident keccakTypes.LargePreimageIdent) (common.Hash, error) { + call := c.contract.Call(methodGetTreeRootLPP, ident.Claimant, ident.UUID) + result, err := c.multiCaller.SingleCall(ctx, block, call) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to get tree root: %w", err) + } + return result.GetHash(0), nil +} + +func (c *PreimageOracleContract) GetInputDataBlocks(ctx context.Context, block rpcblock.Block, ident keccakTypes.LargePreimageIdent) ([]uint64, error) { + results, err := batching.ReadArray(ctx, c.multiCaller, block, + c.contract.Call(methodProposalBlocksLen, ident.Claimant, ident.UUID), + func(i *big.Int) *batching.ContractCall { + return c.contract.Call(methodProposalBlocks, ident.Claimant, ident.UUID, i) + }) + if err != nil { + return nil, fmt.Errorf("failed to load proposal blocks: %w", err) + } + blockNums := make([]uint64, 0, len(results)) + for _, result := range results { + blockNums = append(blockNums, result.GetUint64(0)) + } + return blockNums, nil +} + +// DecodeInputData returns the UUID and [keccakTypes.InputData] being added to the preimage via a addLeavesLPP call. +// An [ErrInvalidAddLeavesCall] error is returned if the call is not a valid call to addLeavesLPP. +// Otherwise, the uuid and input data is returned. The raw data supplied is returned so long as it can be parsed. +// Specifically the length of the input data is not validated to ensure it is consistent with the number of commitments. +func (c *PreimageOracleContract) DecodeInputData(data []byte) (*big.Int, keccakTypes.InputData, error) { + method, args, err := c.contract.DecodeCall(data) + if errors.Is(err, batching.ErrUnknownMethod) { + return nil, keccakTypes.InputData{}, ErrInvalidAddLeavesCall + } else if err != nil { + return nil, keccakTypes.InputData{}, err + } + if method != methodAddLeavesLPP { + return nil, keccakTypes.InputData{}, fmt.Errorf("%w: %v", ErrInvalidAddLeavesCall, method) + } + uuid := args.GetBigInt(0) + // Arg 1 is the starting block index which we don't current use + input := args.GetBytes(2) + stateCommitments := args.GetBytes32Slice(3) + finalize := args.GetBool(4) + + commitments := make([]common.Hash, 0, len(stateCommitments)) + for _, c := range stateCommitments { + commitments = append(commitments, c) + } + return uuid, keccakTypes.InputData{ + Input: input, + Commitments: commitments, + Finalize: finalize, + }, nil +} + +func (c *PreimageOracleContract) GlobalDataExists(ctx context.Context, data *types.PreimageOracleData) (bool, error) { + call := c.contract.Call(methodPreimagePartOk, common.Hash(data.OracleKey), new(big.Int).SetUint64(uint64(data.OracleOffset))) + results, err := c.multiCaller.SingleCall(ctx, rpcblock.Latest, call) + if err != nil { + return false, fmt.Errorf("failed to get preimagePartOk: %w", err) + } + return results.GetBool(0), nil +} + +func (c *PreimageOracleContract) ChallengeTx(ident keccakTypes.LargePreimageIdent, challenge keccakTypes.Challenge) (txmgr.TxCandidate, error) { + var call *batching.ContractCall + if challenge.Prestate == (keccakTypes.Leaf{}) { + call = c.contract.Call( + methodChallengeFirstLPP, + ident.Claimant, + ident.UUID, + toPreimageOracleLeaf(challenge.Poststate), + challenge.PoststateProof) + } else { + call = c.contract.Call( + methodChallengeLPP, + ident.Claimant, + ident.UUID, + abiEncodeSnapshot(challenge.StateMatrix), + toPreimageOracleLeaf(challenge.Prestate), + challenge.PrestateProof, + toPreimageOracleLeaf(challenge.Poststate), + challenge.PoststateProof) + } + return call.ToTxCandidate() +} + +func (c *PreimageOracleContract) GetMinBondLPP(ctx context.Context) (*big.Int, error) { + if bondSize := c.minBondSizeLPP.Load(); bondSize != 0 { + return big.NewInt(int64(bondSize)), nil + } + result, err := c.multiCaller.SingleCall(ctx, rpcblock.Latest, c.contract.Call(methodMinBondSizeLPP)) + if err != nil { + return nil, fmt.Errorf("failed to fetch min bond size for LPPs: %w", err) + } + period := result.GetBigInt(0) + c.minBondSizeLPP.Store(period.Uint64()) + return period, nil +} + +func (c *PreimageOracleContract) decodePreimageIdent(result *batching.CallResult) keccakTypes.LargePreimageIdent { + return keccakTypes.LargePreimageIdent{ + Claimant: result.GetAddress(0), + UUID: result.GetBigInt(1), + } +} + +// metadata is the packed preimage metadata +// ┌─────────────┬────────────────────────────────────────────┐ +// │ Bit Offsets │ Description │ +// ├─────────────┼────────────────────────────────────────────┤ +// │ [0, 64) │ Timestamp (Finalized - All data available) │ +// │ [64, 96) │ Part Offset │ +// │ [96, 128) │ Claimed Size │ +// │ [128, 160) │ Blocks Processed (Inclusive of Padding) │ +// │ [160, 192) │ Bytes Processed (Non-inclusive of Padding) │ +// │ [192, 256) │ Countered │ +// └─────────────┴────────────────────────────────────────────┘ +type metadata [32]byte + +func (m *metadata) setTimestamp(timestamp uint64) { + binary.BigEndian.PutUint64(m[0:8], timestamp) +} + +func (m *metadata) timestamp() uint64 { + return binary.BigEndian.Uint64(m[0:8]) +} + +func (m *metadata) setPartOffset(value uint32) { + binary.BigEndian.PutUint32(m[8:12], value) +} + +func (m *metadata) partOffset() uint32 { + return binary.BigEndian.Uint32(m[8:12]) +} + +func (m *metadata) setClaimedSize(value uint32) { + binary.BigEndian.PutUint32(m[12:16], value) +} + +func (m *metadata) claimedSize() uint32 { + return binary.BigEndian.Uint32(m[12:16]) +} + +func (m *metadata) setBlocksProcessed(value uint32) { + binary.BigEndian.PutUint32(m[16:20], value) +} + +func (m *metadata) blocksProcessed() uint32 { + return binary.BigEndian.Uint32(m[16:20]) +} + +func (m *metadata) setBytesProcessed(value uint32) { + binary.BigEndian.PutUint32(m[20:24], value) +} + +func (m *metadata) bytesProcessed() uint32 { + return binary.BigEndian.Uint32(m[20:24]) +} + +func (m *metadata) setCountered(value bool) { + v := uint64(0) + if value { + v = math.MaxUint64 + } + binary.BigEndian.PutUint64(m[24:32], v) +} + +func (m *metadata) countered() bool { + return binary.BigEndian.Uint64(m[24:32]) != 0 +} diff --git a/op-challenger/game/fault/contracts/oracle_test.go b/op-challenger/game/fault/contracts/oracle_test.go new file mode 100644 index 000000000000..0a65b239aef4 --- /dev/null +++ b/op-challenger/game/fault/contracts/oracle_test.go @@ -0,0 +1,658 @@ +package contracts + +import ( + "context" + "fmt" + "math" + "math/big" + "math/rand" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/merkle" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + preimage "github.com/ethereum-optimism/optimism/op-preimage" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" + "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestPreimageOracleContract_AddGlobalDataTx(t *testing.T) { + t.Run("UnknownType", func(t *testing.T) { + _, oracle := setupPreimageOracleTest(t) + data := types.NewPreimageOracleData(common.Hash{0xcc}.Bytes(), make([]byte, 20), uint32(545)) + _, err := oracle.AddGlobalDataTx(data) + require.ErrorIs(t, err, ErrUnsupportedKeyType) + }) + + t.Run("Keccak256", func(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + data := types.NewPreimageOracleData(common.Hash{byte(preimage.Keccak256KeyType), 0xcc}.Bytes(), make([]byte, 20), uint32(545)) + stubRpc.SetResponse(oracleAddr, methodLoadKeccak256PreimagePart, rpcblock.Latest, []interface{}{ + new(big.Int).SetUint64(uint64(data.OracleOffset)), + data.GetPreimageWithoutSize(), + }, nil) + + tx, err := oracle.AddGlobalDataTx(data) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) + }) + + t.Run("Sha256", func(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + data := types.NewPreimageOracleData(common.Hash{byte(preimage.Sha256KeyType), 0xcc}.Bytes(), make([]byte, 20), uint32(545)) + stubRpc.SetResponse(oracleAddr, methodLoadSha256PreimagePart, rpcblock.Latest, []interface{}{ + new(big.Int).SetUint64(uint64(data.OracleOffset)), + data.GetPreimageWithoutSize(), + }, nil) + + tx, err := oracle.AddGlobalDataTx(data) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) + }) + + t.Run("Blob", func(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + fieldData := testutils.RandomData(rand.New(rand.NewSource(23)), 32) + data := types.NewPreimageOracleData(common.Hash{byte(preimage.BlobKeyType), 0xcc}.Bytes(), fieldData, uint32(545)) + stubRpc.SetResponse(oracleAddr, methodLoadBlobPreimagePart, rpcblock.Latest, []interface{}{ + new(big.Int).SetUint64(data.BlobFieldIndex), + new(big.Int).SetBytes(data.GetPreimageWithoutSize()), + data.BlobCommitment, + data.BlobProof, + new(big.Int).SetUint64(uint64(data.OracleOffset)), + }, nil) + + tx, err := oracle.AddGlobalDataTx(data) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) + }) + + t.Run("Precompile", func(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + input := testutils.RandomData(rand.New(rand.NewSource(23)), 200) + data := types.NewPreimageOracleData(common.Hash{byte(preimage.PrecompileKeyType), 0xcc}.Bytes(), input, uint32(545)) + stubRpc.SetResponse(oracleAddr, methodLoadPrecompilePreimagePart, rpcblock.Latest, []interface{}{ + new(big.Int).SetUint64(uint64(data.OracleOffset)), + data.GetPrecompileAddress(), + data.GetPrecompileInput(), + }, nil) + + tx, err := oracle.AddGlobalDataTx(data) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) + }) +} + +func TestPreimageOracleContract_ChallengePeriod(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + stubRpc.SetResponse(oracleAddr, methodChallengePeriod, rpcblock.Latest, + []interface{}{}, + []interface{}{big.NewInt(123)}, + ) + challengePeriod, err := oracle.ChallengePeriod(context.Background()) + require.NoError(t, err) + require.Equal(t, uint64(123), challengePeriod) + + // Should cache responses + stubRpc.ClearResponses() + challengePeriod, err = oracle.ChallengePeriod(context.Background()) + require.NoError(t, err) + require.Equal(t, uint64(123), challengePeriod) +} + +func TestPreimageOracleContract_MinLargePreimageSize(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + stubRpc.SetResponse(oracleAddr, methodMinProposalSize, rpcblock.Latest, + []interface{}{}, + []interface{}{big.NewInt(123)}, + ) + minProposalSize, err := oracle.MinLargePreimageSize(context.Background()) + require.NoError(t, err) + require.Equal(t, uint64(123), minProposalSize) +} + +func TestPreimageOracleContract_MinBondSizeLPP(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + stubRpc.SetResponse(oracleAddr, methodMinBondSizeLPP, rpcblock.Latest, + []interface{}{}, + []interface{}{big.NewInt(123)}, + ) + minBond, err := oracle.GetMinBondLPP(context.Background()) + require.NoError(t, err) + require.Equal(t, big.NewInt(123), minBond) + + // Should cache responses + stubRpc.ClearResponses() + minBond, err = oracle.GetMinBondLPP(context.Background()) + require.NoError(t, err) + require.Equal(t, big.NewInt(123), minBond) +} + +func TestPreimageOracleContract_PreimageDataExists(t *testing.T) { + t.Run("exists", func(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + data := types.NewPreimageOracleData(common.Hash{0xcc}.Bytes(), make([]byte, 20), 545) + stubRpc.SetResponse(oracleAddr, methodPreimagePartOk, rpcblock.Latest, + []interface{}{common.Hash(data.OracleKey), new(big.Int).SetUint64(uint64(data.OracleOffset))}, + []interface{}{true}, + ) + exists, err := oracle.GlobalDataExists(context.Background(), data) + require.NoError(t, err) + require.True(t, exists) + }) + t.Run("does not exist", func(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + data := types.NewPreimageOracleData(common.Hash{0xcc}.Bytes(), make([]byte, 20), 545) + stubRpc.SetResponse(oracleAddr, methodPreimagePartOk, rpcblock.Latest, + []interface{}{common.Hash(data.OracleKey), new(big.Int).SetUint64(uint64(data.OracleOffset))}, + []interface{}{false}, + ) + exists, err := oracle.GlobalDataExists(context.Background(), data) + require.NoError(t, err) + require.False(t, exists) + }) +} + +func TestPreimageOracleContract_InitLargePreimage(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + + uuid := big.NewInt(123) + partOffset := uint32(1) + claimedSize := uint32(2) + stubRpc.SetResponse(oracleAddr, methodInitLPP, rpcblock.Latest, []interface{}{ + uuid, + partOffset, + claimedSize, + }, nil) + + tx, err := oracle.InitLargePreimage(uuid, partOffset, claimedSize) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func TestPreimageOracleContract_AddLeaves(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + + uuid := big.NewInt(123) + startingBlockIndex := big.NewInt(0) + input := []byte{0x12} + commitments := []common.Hash{{0x34}} + finalize := true + stubRpc.SetResponse(oracleAddr, methodAddLeavesLPP, rpcblock.Latest, []interface{}{ + uuid, + startingBlockIndex, + input, + commitments, + finalize, + }, nil) + + tx, err := oracle.AddLeaves(uuid, startingBlockIndex, input, commitments, finalize) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func TestPreimageOracleContract_Squeeze(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + + claimant := common.Address{0x12} + uuid := big.NewInt(123) + preStateMatrix := keccakTypes.StateSnapshot{0, 1, 2, 3, 4} + preState := keccakTypes.Leaf{ + Input: [keccakTypes.BlockSize]byte{0x12}, + Index: 123, + StateCommitment: common.Hash{0x34}, + } + preStateProof := merkle.Proof{{0x34}} + postState := keccakTypes.Leaf{ + Input: [keccakTypes.BlockSize]byte{0x34}, + Index: 456, + StateCommitment: common.Hash{0x56}, + } + postStateProof := merkle.Proof{{0x56}} + stubRpc.SetResponse(oracleAddr, methodSqueezeLPP, rpcblock.Latest, []interface{}{ + claimant, + uuid, + abiEncodeSnapshot(preStateMatrix), + toPreimageOracleLeaf(preState), + preStateProof, + toPreimageOracleLeaf(postState), + postStateProof, + }, nil) + + tx, err := oracle.Squeeze(claimant, uuid, preStateMatrix, preState, preStateProof, postState, postStateProof) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func TestGetActivePreimages(t *testing.T) { + blockHash := common.Hash{0xaa} + _, oracle, proposals := setupPreimageOracleTestWithProposals(t, rpcblock.ByHash(blockHash)) + preimages, err := oracle.GetActivePreimages(context.Background(), blockHash) + require.NoError(t, err) + require.Equal(t, proposals, preimages) +} + +func TestGetProposalMetadata(t *testing.T) { + blockHash := common.Hash{0xaa} + block := rpcblock.ByHash(blockHash) + stubRpc, oracle, proposals := setupPreimageOracleTestWithProposals(t, block) + preimages, err := oracle.GetProposalMetadata( + context.Background(), + block, + proposals[0].LargePreimageIdent, + proposals[1].LargePreimageIdent, + proposals[2].LargePreimageIdent, + ) + require.NoError(t, err) + require.Equal(t, proposals, preimages) + + // Fetching a proposal that doesn't exist should return an empty metadata object. + ident := keccakTypes.LargePreimageIdent{Claimant: common.Address{0x12}, UUID: big.NewInt(123)} + meta := new(metadata) + stubRpc.SetResponse( + oracleAddr, + methodProposalMetadata, + block, + []interface{}{ident.Claimant, ident.UUID}, + []interface{}{meta}) + preimages, err = oracle.GetProposalMetadata(context.Background(), rpcblock.ByHash(blockHash), ident) + require.NoError(t, err) + require.Equal(t, []keccakTypes.LargePreimageMetaData{{LargePreimageIdent: ident}}, preimages) +} + +func TestGetProposalTreeRoot(t *testing.T) { + blockHash := common.Hash{0xaa} + expectedRoot := common.Hash{0xbb} + ident := keccakTypes.LargePreimageIdent{Claimant: common.Address{0x12}, UUID: big.NewInt(123)} + stubRpc, oracle := setupPreimageOracleTest(t) + stubRpc.SetResponse(oracleAddr, methodGetTreeRootLPP, rpcblock.ByHash(blockHash), + []interface{}{ident.Claimant, ident.UUID}, + []interface{}{expectedRoot}) + actualRoot, err := oracle.GetProposalTreeRoot(context.Background(), rpcblock.ByHash(blockHash), ident) + require.NoError(t, err) + require.Equal(t, expectedRoot, actualRoot) +} + +func setupPreimageOracleTestWithProposals(t *testing.T, block rpcblock.Block) (*batchingTest.AbiBasedRpc, *PreimageOracleContract, []keccakTypes.LargePreimageMetaData) { + stubRpc, oracle := setupPreimageOracleTest(t) + stubRpc.SetResponse( + oracleAddr, + methodProposalCount, + block, + []interface{}{}, + []interface{}{big.NewInt(3)}) + + preimage1 := keccakTypes.LargePreimageMetaData{ + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xaa}, + UUID: big.NewInt(1111), + }, + Timestamp: 1234, + PartOffset: 1, + ClaimedSize: 100, + BlocksProcessed: 10, + BytesProcessed: 100, + Countered: false, + } + preimage2 := keccakTypes.LargePreimageMetaData{ + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xbb}, + UUID: big.NewInt(2222), + }, + Timestamp: 2345, + PartOffset: 2, + ClaimedSize: 200, + BlocksProcessed: 20, + BytesProcessed: 200, + Countered: true, + } + preimage3 := keccakTypes.LargePreimageMetaData{ + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xcc}, + UUID: big.NewInt(3333), + }, + Timestamp: 0, + PartOffset: 3, + ClaimedSize: 300, + BlocksProcessed: 30, + BytesProcessed: 233, + Countered: false, + } + + proposals := []keccakTypes.LargePreimageMetaData{preimage1, preimage2, preimage3} + + for i, proposal := range proposals { + stubRpc.SetResponse( + oracleAddr, + methodProposals, + block, + []interface{}{big.NewInt(int64(i))}, + []interface{}{ + proposal.Claimant, + proposal.UUID, + }) + meta := new(metadata) + meta.setTimestamp(proposal.Timestamp) + meta.setPartOffset(proposal.PartOffset) + meta.setClaimedSize(proposal.ClaimedSize) + meta.setBlocksProcessed(proposal.BlocksProcessed) + meta.setBytesProcessed(proposal.BytesProcessed) + meta.setCountered(proposal.Countered) + stubRpc.SetResponse( + oracleAddr, + methodProposalMetadata, + block, + []interface{}{proposal.Claimant, proposal.UUID}, + []interface{}{meta}) + } + + return stubRpc, oracle, proposals +} + +func setupPreimageOracleTest(t *testing.T) (*batchingTest.AbiBasedRpc, *PreimageOracleContract) { + oracleAbi, err := bindings.PreimageOracleMetaData.GetAbi() + require.NoError(t, err) + + stubRpc := batchingTest.NewAbiBasedRpc(t, oracleAddr, oracleAbi) + oracleContract, err := NewPreimageOracleContract(oracleAddr, batching.NewMultiCaller(stubRpc, batching.DefaultBatchSize)) + require.NoError(t, err) + + return stubRpc, oracleContract +} + +func TestMetadata(t *testing.T) { + uint32Values := []uint32{0, 1, 2, 3252354, math.MaxUint32} + tests := []struct { + name string + setter func(meta *metadata, val uint32) + getter func(meta *metadata) uint32 + }{ + { + name: "partOffset", + setter: (*metadata).setPartOffset, + getter: (*metadata).partOffset, + }, + { + name: "claimedSize", + setter: (*metadata).setClaimedSize, + getter: (*metadata).claimedSize, + }, + { + name: "blocksProcessed", + setter: (*metadata).setBlocksProcessed, + getter: (*metadata).blocksProcessed, + }, + { + name: "bytesProcessed", + setter: (*metadata).setBytesProcessed, + getter: (*metadata).bytesProcessed, + }, + } + for _, test := range tests { + test := test + for _, value := range uint32Values { + value := value + t.Run(fmt.Sprintf("%v-%v", test.name, value), func(t *testing.T) { + meta := new(metadata) + require.Zero(t, test.getter(meta)) + test.setter(meta, value) + require.Equal(t, value, test.getter(meta)) + }) + } + } +} + +func TestMetadata_Timestamp(t *testing.T) { + values := []uint64{0, 1, 2, 3252354, math.MaxUint32, math.MaxUint32 + 1, math.MaxUint64} + var meta metadata + require.Zero(t, meta.timestamp()) + for _, value := range values { + meta.setTimestamp(value) + require.Equal(t, value, meta.timestamp()) + } +} + +func TestMetadata_Countered(t *testing.T) { + var meta metadata + require.False(t, meta.countered()) + meta.setCountered(true) + require.True(t, meta.countered()) + meta.setCountered(false) + require.False(t, meta.countered()) +} + +func TestGetInputDataBlocks(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + block := rpcblock.ByHash(common.Hash{0xaa}) + + preimage := keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xbb}, + UUID: big.NewInt(2222), + } + + stubRpc.SetResponse( + oracleAddr, + methodProposalBlocksLen, + block, + []interface{}{preimage.Claimant, preimage.UUID}, + []interface{}{big.NewInt(3)}) + + blockNums := []uint64{10, 35, 67} + + for i, blockNum := range blockNums { + stubRpc.SetResponse( + oracleAddr, + methodProposalBlocks, + block, + []interface{}{preimage.Claimant, preimage.UUID, big.NewInt(int64(i))}, + []interface{}{blockNum}) + } + + actual, err := oracle.GetInputDataBlocks(context.Background(), block, preimage) + require.NoError(t, err) + require.Len(t, actual, 3) + require.Equal(t, blockNums, actual) +} + +func TestDecodeInputData(t *testing.T) { + dataOfLength := func(len int) []byte { + data := make([]byte, len) + for i := range data { + data[i] = byte(i) + } + return data + } + ident := keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xaa}, + UUID: big.NewInt(1111), + } + _, oracle := setupPreimageOracleTest(t) + + tests := []struct { + name string + input []byte + inputData keccakTypes.InputData + expectedTxData string + expectedErr error + }{ + { + name: "UnknownMethod", + input: []byte{0xaa, 0xbb, 0xcc, 0xdd}, + expectedTxData: "aabbccdd", + expectedErr: ErrInvalidAddLeavesCall, + }, + { + name: "SingleInput", + inputData: keccakTypes.InputData{ + Input: dataOfLength(keccakTypes.BlockSize), + Commitments: []common.Hash{{0xaa}}, + Finalize: false, + }, + expectedTxData: "7917de1d0000000000000000000000000000000000000000000000000000000000000457000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000088000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848586870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001aa00000000000000000000000000000000000000000000000000000000000000", + }, + { + name: "MultipleInputs", + inputData: keccakTypes.InputData{ + Input: dataOfLength(2 * keccakTypes.BlockSize), + Commitments: []common.Hash{{0xaa}, {0xbb}}, + Finalize: false, + }, + expectedTxData: "7917de1d0000000000000000000000000000000000000000000000000000000000000457000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002aa00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000", + }, + { + name: "MultipleInputs-InputTooShort", + inputData: keccakTypes.InputData{ + Input: dataOfLength(2*keccakTypes.BlockSize - 10), + Commitments: []common.Hash{{0xaa}, {0xbb}}, + Finalize: false, + }, + expectedTxData: "7917de1d0000000000000000000000000000000000000000000000000000000000000457000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000106000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff00010203040500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002aa00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000", + }, + { + name: "MultipleInputs-FinalizeDoesNotPadInput", + inputData: keccakTypes.InputData{ + Input: dataOfLength(2*keccakTypes.BlockSize - 15), + Commitments: []common.Hash{{0xaa}, {0xbb}}, + Finalize: true, + }, + expectedTxData: "7917de1d0000000000000000000000000000000000000000000000000000000000000457000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000101000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002aa00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000", + }, + { + name: "MultipleInputs-FinalizePadding-FullBlock", + inputData: keccakTypes.InputData{ + Input: dataOfLength(2 * keccakTypes.BlockSize), + Commitments: []common.Hash{{0xaa}, {0xbb}}, + Finalize: true, + }, + expectedTxData: "7917de1d0000000000000000000000000000000000000000000000000000000000000457000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000110000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002aa00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000", + }, + { + name: "MultipleInputs-FinalizePadding-TrailingZeros", + inputData: keccakTypes.InputData{ + Input: make([]byte, 2*keccakTypes.BlockSize), + Commitments: []common.Hash{{0xaa}, {0xbb}}, + Finalize: true, + }, + expectedTxData: "7917de1d0000000000000000000000000000000000000000000000000000000000000457000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002aa00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000", + }, + { + name: "MultipleInputs-FinalizePadding-ShorterThanSingleBlock", + inputData: keccakTypes.InputData{ + Input: dataOfLength(keccakTypes.BlockSize - 5), + Commitments: []common.Hash{{0xaa}, {0xbb}}, + Finalize: true, + }, + expectedTxData: "7917de1d0000000000000000000000000000000000000000000000000000000000000457000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000083000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002aa00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000", + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + var input []byte + if len(test.input) > 0 { + input = test.input + } else { + input = toAddLeavesTxData(t, oracle, ident.UUID, test.inputData) + } + require.Equal(t, test.expectedTxData, common.Bytes2Hex(input), + "ABI has been changed. Add tests to ensure historic transactions can be parsed before updating expectedTxData") + uuid, leaves, err := oracle.DecodeInputData(input) + if test.expectedErr != nil { + require.ErrorIs(t, err, test.expectedErr) + } else { + require.NoError(t, err) + require.Equal(t, ident.UUID, uuid) + require.Equal(t, test.inputData, leaves) + } + }) + } +} + +func TestChallenge_First(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + + ident := keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xab}, + UUID: big.NewInt(4829), + } + challenge := keccakTypes.Challenge{ + StateMatrix: keccakTypes.StateSnapshot{1, 2, 3, 4, 5}, + Prestate: keccakTypes.Leaf{}, + Poststate: keccakTypes.Leaf{ + Input: [136]byte{5, 4, 3, 2, 1}, + Index: 0, + StateCommitment: common.Hash{0xbb}, + }, + PoststateProof: merkle.Proof{common.Hash{0x01}, common.Hash{0x02}}, + } + stubRpc.SetResponse(oracleAddr, methodChallengeFirstLPP, rpcblock.Latest, + []interface{}{ + ident.Claimant, ident.UUID, + bindings.PreimageOracleLeaf{ + Input: challenge.Poststate.Input[:], + Index: new(big.Int).SetUint64(challenge.Poststate.Index), + StateCommitment: challenge.Poststate.StateCommitment, + }, + challenge.PoststateProof, + }, + nil) + tx, err := oracle.ChallengeTx(ident, challenge) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func TestChallenge_NotFirst(t *testing.T) { + stubRpc, oracle := setupPreimageOracleTest(t) + + ident := keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xab}, + UUID: big.NewInt(4829), + } + challenge := keccakTypes.Challenge{ + StateMatrix: keccakTypes.StateSnapshot{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, + Prestate: keccakTypes.Leaf{ + Input: [136]byte{9, 8, 7, 6, 5}, + Index: 3, + StateCommitment: common.Hash{0xcc}, + }, + PrestateProof: merkle.Proof{common.Hash{0x01}, common.Hash{0x02}}, + Poststate: keccakTypes.Leaf{ + Input: [136]byte{5, 4, 3, 2, 1}, + Index: 4, + StateCommitment: common.Hash{0xbb}, + }, + PoststateProof: merkle.Proof{common.Hash{0x03}, common.Hash{0x04}}, + } + stubRpc.SetResponse(oracleAddr, methodChallengeLPP, rpcblock.Latest, + []interface{}{ + ident.Claimant, ident.UUID, + bindings.LibKeccakStateMatrix{State: challenge.StateMatrix}, + bindings.PreimageOracleLeaf{ + Input: challenge.Prestate.Input[:], + Index: new(big.Int).SetUint64(challenge.Prestate.Index), + StateCommitment: challenge.Prestate.StateCommitment, + }, + challenge.PrestateProof, + bindings.PreimageOracleLeaf{ + Input: challenge.Poststate.Input[:], + Index: new(big.Int).SetUint64(challenge.Poststate.Index), + StateCommitment: challenge.Poststate.StateCommitment, + }, + challenge.PoststateProof, + }, + nil) + tx, err := oracle.ChallengeTx(ident, challenge) + require.NoError(t, err) + stubRpc.VerifyTxCandidate(tx) +} + +func toAddLeavesTxData(t *testing.T, oracle *PreimageOracleContract, uuid *big.Int, inputData keccakTypes.InputData) []byte { + tx, err := oracle.AddLeaves(uuid, big.NewInt(1), inputData.Input, inputData.Commitments, inputData.Finalize) + require.NoError(t, err) + return tx.TxData +} diff --git a/op-challenger/game/fault/contracts/vm.go b/op-challenger/game/fault/contracts/vm.go new file mode 100644 index 000000000000..2fb354d89bd8 --- /dev/null +++ b/op-challenger/game/fault/contracts/vm.go @@ -0,0 +1,41 @@ +package contracts + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" +) + +const ( + methodOracle = "oracle" +) + +// VMContract is a binding that works with contracts implementing the IBigStepper interface +type VMContract struct { + multiCaller *batching.MultiCaller + contract *batching.BoundContract +} + +func NewVMContract(addr common.Address, caller *batching.MultiCaller) (*VMContract, error) { + mipsAbi, err := bindings.MIPSMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to load VM ABI: %w", err) + } + + return &VMContract{ + multiCaller: caller, + contract: batching.NewBoundContract(mipsAbi, addr), + }, nil +} + +func (c *VMContract) Oracle(ctx context.Context) (*PreimageOracleContract, error) { + results, err := c.multiCaller.SingleCall(ctx, rpcblock.Latest, c.contract.Call(methodOracle)) + if err != nil { + return nil, fmt.Errorf("failed to load oracle address: %w", err) + } + return NewPreimageOracleContract(results.GetAddress(0), c.multiCaller) +} diff --git a/op-challenger/game/fault/contracts/vm_test.go b/op-challenger/game/fault/contracts/vm_test.go new file mode 100644 index 000000000000..13758ccd6500 --- /dev/null +++ b/op-challenger/game/fault/contracts/vm_test.go @@ -0,0 +1,34 @@ +package contracts + +import ( + "context" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + preimage "github.com/ethereum-optimism/optimism/op-preimage" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestVMContract_Oracle(t *testing.T) { + vmAbi, err := bindings.MIPSMetaData.GetAbi() + require.NoError(t, err) + + stubRpc := batchingTest.NewAbiBasedRpc(t, vmAddr, vmAbi) + vmContract, err := NewVMContract(vmAddr, batching.NewMultiCaller(stubRpc, batching.DefaultBatchSize)) + require.NoError(t, err) + + stubRpc.SetResponse(vmAddr, methodOracle, rpcblock.Latest, nil, []interface{}{oracleAddr}) + + oracleContract, err := vmContract.Oracle(context.Background()) + require.NoError(t, err) + tx, err := oracleContract.AddGlobalDataTx(types.NewPreimageOracleData(common.Hash{byte(preimage.Keccak256KeyType)}.Bytes(), make([]byte, 20), 0)) + require.NoError(t, err) + // This test doesn't care about all the tx details, we just want to confirm the contract binding is using the + // correct address + require.Equal(t, &oracleAddr, tx.To) +} diff --git a/op-challenger/game/fault/loader.go b/op-challenger/game/fault/loader.go deleted file mode 100644 index 55bfbae90b5f..000000000000 --- a/op-challenger/game/fault/loader.go +++ /dev/null @@ -1,141 +0,0 @@ -package fault - -import ( - "context" - "math/big" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" -) - -// MinimalFaultDisputeGameCaller is a minimal interface around [bindings.FaultDisputeGameCaller]. -// This needs to be updated if the [bindings.FaultDisputeGameCaller] interface changes. -type MinimalFaultDisputeGameCaller interface { - ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int - }, error) - Status(opts *bind.CallOpts) (uint8, error) - ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) - MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error) - ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) -} - -// loader pulls in fault dispute game claim data periodically and over subscriptions. -type loader struct { - caller MinimalFaultDisputeGameCaller -} - -// NewLoader creates a new [loader]. -func NewLoader(caller MinimalFaultDisputeGameCaller) *loader { - return &loader{ - caller: caller, - } -} - -// NewLoaderFromBindings creates a new [loader] from a [bindings.FaultDisputeGameCaller]. -func NewLoaderFromBindings(fdgAddr common.Address, client bind.ContractCaller) (*loader, error) { - caller, err := bindings.NewFaultDisputeGameCaller(fdgAddr, client) - if err != nil { - return nil, err - } - return NewLoader(caller), nil -} - -// GetGameStatus returns the current game status. -func (l *loader) GetGameStatus(ctx context.Context) (gameTypes.GameStatus, error) { - status, err := l.caller.Status(&bind.CallOpts{Context: ctx}) - return gameTypes.GameStatus(status), err -} - -// GetClaimCount returns the number of claims in the game. -func (l *loader) GetClaimCount(ctx context.Context) (uint64, error) { - count, err := l.caller.ClaimDataLen(&bind.CallOpts{Context: ctx}) - if err != nil { - return 0, err - } - return count.Uint64(), nil -} - -// FetchGameDepth fetches the game depth from the fault dispute game. -func (l *loader) FetchGameDepth(ctx context.Context) (uint64, error) { - callOpts := bind.CallOpts{ - Context: ctx, - } - - gameDepth, err := l.caller.MAXGAMEDEPTH(&callOpts) - if err != nil { - return 0, err - } - - return gameDepth.Uint64(), nil -} - -// fetchClaim fetches a single [Claim] with a hydrated parent. -func (l *loader) fetchClaim(ctx context.Context, arrIndex uint64) (types.Claim, error) { - callOpts := bind.CallOpts{ - Context: ctx, - } - - fetchedClaim, err := l.caller.ClaimData(&callOpts, new(big.Int).SetUint64(arrIndex)) - if err != nil { - return types.Claim{}, err - } - - claim := types.Claim{ - ClaimData: types.ClaimData{ - Value: fetchedClaim.Claim, - Position: types.NewPositionFromGIndex(fetchedClaim.Position), - }, - Countered: fetchedClaim.Countered, - Clock: fetchedClaim.Clock.Uint64(), - ContractIndex: int(arrIndex), - ParentContractIndex: int(fetchedClaim.ParentIndex), - } - - return claim, nil -} - -// FetchClaims fetches all claims from the fault dispute game. -func (l *loader) FetchClaims(ctx context.Context) ([]types.Claim, error) { - // Get the current claim count. - claimCount, err := l.caller.ClaimDataLen(&bind.CallOpts{ - Context: ctx, - }) - if err != nil { - return nil, err - } - - // Fetch each claim and build a list. - claimList := make([]types.Claim, claimCount.Uint64()) - for i := uint64(0); i < claimCount.Uint64(); i++ { - claim, err := l.fetchClaim(ctx, i) - if err != nil { - return nil, err - } - claimList[i] = claim - } - - return claimList, nil -} - -// FetchAbsolutePrestateHash fetches the hashed absolute prestate from the fault dispute game. -func (l *loader) FetchAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { - callOpts := bind.CallOpts{ - Context: ctx, - } - - absolutePrestate, err := l.caller.ABSOLUTEPRESTATE(&callOpts) - if err != nil { - return common.Hash{}, err - } - - return absolutePrestate, nil -} diff --git a/op-challenger/game/fault/loader_test.go b/op-challenger/game/fault/loader_test.go deleted file mode 100644 index 886076373432..000000000000 --- a/op-challenger/game/fault/loader_test.go +++ /dev/null @@ -1,266 +0,0 @@ -package fault - -import ( - "context" - "fmt" - "math/big" - "testing" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" -) - -var ( - mockClaimDataError = fmt.Errorf("claim data errored") - mockClaimLenError = fmt.Errorf("claim len errored") - mockMaxGameDepthError = fmt.Errorf("max game depth errored") - mockPrestateError = fmt.Errorf("prestate errored") - mockStatusError = fmt.Errorf("status errored") -) - -// TestLoader_GetGameStatus tests fetching the game status. -func TestLoader_GetGameStatus(t *testing.T) { - tests := []struct { - name string - status uint8 - expectedError bool - }{ - { - name: "challenger won status", - status: uint8(gameTypes.GameStatusChallengerWon), - }, - { - name: "defender won status", - status: uint8(gameTypes.GameStatusDefenderWon), - }, - { - name: "in progress status", - status: uint8(gameTypes.GameStatusInProgress), - }, - { - name: "error bubbled up", - expectedError: true, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.status = test.status - mockCaller.statusError = test.expectedError - loader := NewLoader(mockCaller) - status, err := loader.GetGameStatus(context.Background()) - if test.expectedError { - require.ErrorIs(t, err, mockStatusError) - } else { - require.NoError(t, err) - require.Equal(t, gameTypes.GameStatus(test.status), status) - } - }) - } -} - -// TestLoader_FetchGameDepth tests fetching the game depth. -func TestLoader_FetchGameDepth(t *testing.T) { - t.Run("Succeeds", func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.maxGameDepth = 10 - loader := NewLoader(mockCaller) - depth, err := loader.FetchGameDepth(context.Background()) - require.NoError(t, err) - require.Equal(t, uint64(10), depth) - }) - - t.Run("Errors", func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.maxGameDepthError = true - loader := NewLoader(mockCaller) - depth, err := loader.FetchGameDepth(context.Background()) - require.ErrorIs(t, mockMaxGameDepthError, err) - require.Equal(t, depth, uint64(0)) - }) -} - -// TestLoader_FetchAbsolutePrestateHash tests fetching the absolute prestate hash. -func TestLoader_FetchAbsolutePrestateHash(t *testing.T) { - t.Run("Succeeds", func(t *testing.T) { - mockCaller := newMockCaller() - loader := NewLoader(mockCaller) - prestate, err := loader.FetchAbsolutePrestateHash(context.Background()) - require.NoError(t, err) - require.ElementsMatch(t, common.HexToHash("0xdEad"), prestate) - }) - - t.Run("Errors", func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.prestateError = true - loader := NewLoader(mockCaller) - prestate, err := loader.FetchAbsolutePrestateHash(context.Background()) - require.Error(t, err) - require.ElementsMatch(t, common.Hash{}, prestate) - }) -} - -// TestLoader_FetchClaims tests fetching claims. -func TestLoader_FetchClaims(t *testing.T) { - t.Run("Succeeds", func(t *testing.T) { - mockCaller := newMockCaller() - expectedClaims := mockCaller.returnClaims - loader := NewLoader(mockCaller) - claims, err := loader.FetchClaims(context.Background()) - require.NoError(t, err) - require.ElementsMatch(t, []types.Claim{ - { - ClaimData: types.ClaimData{ - Value: expectedClaims[0].Claim, - Position: types.NewPositionFromGIndex(expectedClaims[0].Position), - }, - Countered: false, - Clock: uint64(0), - ContractIndex: 0, - }, - { - ClaimData: types.ClaimData{ - Value: expectedClaims[1].Claim, - Position: types.NewPositionFromGIndex(expectedClaims[1].Position), - }, - Countered: false, - Clock: uint64(0), - ContractIndex: 1, - ParentContractIndex: 0, - }, - { - ClaimData: types.ClaimData{ - Value: expectedClaims[2].Claim, - Position: types.NewPositionFromGIndex(expectedClaims[2].Position), - }, - Countered: false, - Clock: uint64(0), - ContractIndex: 2, - ParentContractIndex: 1, - }, - }, claims) - }) - - t.Run("Claim Data Errors", func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.claimDataError = true - loader := NewLoader(mockCaller) - claims, err := loader.FetchClaims(context.Background()) - require.ErrorIs(t, err, mockClaimDataError) - require.Empty(t, claims) - }) - - t.Run("Claim Len Errors", func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.claimLenError = true - loader := NewLoader(mockCaller) - claims, err := loader.FetchClaims(context.Background()) - require.ErrorIs(t, err, mockClaimLenError) - require.Empty(t, claims) - }) -} - -type mockCaller struct { - claimDataError bool - claimLenError bool - maxGameDepthError bool - prestateError bool - statusError bool - maxGameDepth uint64 - currentIndex uint64 - status uint8 - returnClaims []struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int - } -} - -func newMockCaller() *mockCaller { - return &mockCaller{ - returnClaims: []struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int - }{ - { - Claim: [32]byte{0x00}, - Position: big.NewInt(1), - Countered: false, - Clock: big.NewInt(0), - }, - { - Claim: [32]byte{0x01}, - Position: big.NewInt(2), - Countered: false, - Clock: big.NewInt(0), - ParentIndex: 0, - }, - { - Claim: [32]byte{0x02}, - Position: big.NewInt(3), - Countered: false, - Clock: big.NewInt(0), - ParentIndex: 1, - }, - }, - } -} - -func (m *mockCaller) ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int -}, error) { - if m.claimDataError { - return struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int - }{}, mockClaimDataError - } - returnClaim := m.returnClaims[arg0.Uint64()] - m.currentIndex++ - return returnClaim, nil -} - -func (m *mockCaller) Status(opts *bind.CallOpts) (uint8, error) { - if m.statusError { - return 0, mockStatusError - } - return m.status, nil -} - -func (m *mockCaller) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) { - if m.claimLenError { - return big.NewInt(0), mockClaimLenError - } - return big.NewInt(int64(len(m.returnClaims))), nil -} - -func (m *mockCaller) MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error) { - if m.maxGameDepthError { - return nil, mockMaxGameDepthError - } - return big.NewInt(int64(m.maxGameDepth)), nil -} - -func (m *mockCaller) ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) { - if m.prestateError { - return [32]byte{}, mockPrestateError - } - return common.HexToHash("0xdEad"), nil -} diff --git a/op-challenger/game/fault/player.go b/op-challenger/game/fault/player.go index f3d1917cd8e0..bba42d8bc89d 100644 --- a/op-challenger/game/fault/player.go +++ b/op-challenger/game/fault/player.go @@ -1,59 +1,81 @@ package fault import ( - "bytes" "context" + "errors" "fmt" - "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-challenger/config" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/claims" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/preimages" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/responder" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" - "github.com/ethereum-optimism/optimism/op-service/txmgr" - "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" + gethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" ) type actor func(ctx context.Context) error type GameInfo interface { - GetGameStatus(context.Context) (gameTypes.GameStatus, error) + GetStatus(context.Context) (gameTypes.GameStatus, error) GetClaimCount(context.Context) (uint64, error) } +type SyncValidator interface { + ValidateNodeSynced(ctx context.Context, gameL1Head eth.BlockID) error +} + +type L1HeaderSource interface { + HeaderByHash(context.Context, common.Hash) (*gethTypes.Header, error) +} + type GamePlayer struct { - act actor - agreeWithProposedOutput bool - loader GameInfo - logger log.Logger - status gameTypes.GameStatus + act actor + loader GameInfo + logger log.Logger + syncValidator SyncValidator + prestateValidators []Validator + status gameTypes.GameStatus + gameL1Head eth.BlockID +} + +type GameContract interface { + preimages.PreimageGameContract + responder.GameContract + claims.BondContract + GameInfo + ClaimLoader + GetStatus(ctx context.Context) (gameTypes.GameStatus, error) + GetMaxGameDepth(ctx context.Context) (types.Depth, error) + GetOracle(ctx context.Context) (*contracts.PreimageOracleContract, error) + GetL1Head(ctx context.Context) (common.Hash, error) } -type resourceCreator func(addr common.Address, gameDepth uint64, dir string) (types.TraceProvider, types.OracleUpdater, error) +type resourceCreator func(ctx context.Context, logger log.Logger, gameDepth types.Depth, dir string) (types.TraceAccessor, error) func NewGamePlayer( ctx context.Context, + cl types.ClockReader, logger log.Logger, m metrics.Metricer, - cfg *config.Config, dir string, addr common.Address, - txMgr txmgr.TxManager, - client bind.ContractCaller, + txSender gameTypes.TxSender, + loader GameContract, + syncValidator SyncValidator, + validators []Validator, creator resourceCreator, + l1HeaderSource L1HeaderSource, + selective bool, + claimants []common.Address, ) (*GamePlayer, error) { logger = logger.New("game", addr) - contract, err := bindings.NewFaultDisputeGameCaller(addr, client) - if err != nil { - return nil, fmt.Errorf("failed to bind the fault dispute game contract: %w", err) - } - loader := NewLoader(contract) - - status, err := loader.GetGameStatus(ctx) + status, err := loader.GetStatus(ctx) if err != nil { return nil, fmt.Errorf("failed to fetch game status: %w", err) } @@ -61,10 +83,10 @@ func NewGamePlayer( logger.Info("Game already resolved", "status", status) // Game is already complete so skip creating the trace provider, loading game inputs etc. return &GamePlayer{ - logger: logger, - loader: loader, - agreeWithProposedOutput: cfg.AgreeWithProposedOutput, - status: status, + logger: logger, + loader: loader, + prestateValidators: validators, + status: status, // Act function does nothing because the game is already complete act: func(ctx context.Context) error { return nil @@ -72,34 +94,64 @@ func NewGamePlayer( }, nil } - gameDepth, err := loader.FetchGameDepth(ctx) + gameDepth, err := loader.GetMaxGameDepth(ctx) if err != nil { return nil, fmt.Errorf("failed to fetch the game depth: %w", err) } - provider, updater, err := creator(addr, gameDepth, dir) + accessor, err := creator(ctx, logger, gameDepth, dir) if err != nil { - return nil, fmt.Errorf("failed to create trace provider: %w", err) + return nil, fmt.Errorf("failed to create trace accessor: %w", err) } - if err := ValidateAbsolutePrestate(ctx, provider, loader); err != nil { - return nil, fmt.Errorf("failed to validate absolute prestate: %w", err) + oracle, err := loader.GetOracle(ctx) + if err != nil { + return nil, fmt.Errorf("failed to load oracle: %w", err) } - responder, err := responder.NewFaultResponder(logger, txMgr, addr) + l1HeadHash, err := loader.GetL1Head(ctx) + if err != nil { + return nil, fmt.Errorf("failed to load game L1 head: %w", err) + } + l1Header, err := l1HeaderSource.HeaderByHash(ctx, l1HeadHash) + if err != nil { + return nil, fmt.Errorf("failed to load L1 header %v: %w", l1HeadHash, err) + } + l1Head := eth.HeaderBlockID(l1Header) + + minLargePreimageSize, err := oracle.MinLargePreimageSize(ctx) + if err != nil { + return nil, fmt.Errorf("failed to load min large preimage size: %w", err) + } + direct := preimages.NewDirectPreimageUploader(logger, txSender, loader) + large := preimages.NewLargePreimageUploader(logger, cl, txSender, oracle) + uploader := preimages.NewSplitPreimageUploader(direct, large, minLargePreimageSize) + responder, err := responder.NewFaultResponder(logger, txSender, loader, uploader, oracle) if err != nil { return nil, fmt.Errorf("failed to create the responder: %w", err) } + agent := NewAgent(m, loader, gameDepth, accessor, responder, logger, selective, claimants) return &GamePlayer{ - act: NewAgent(m, loader, int(gameDepth), provider, responder, updater, cfg.AgreeWithProposedOutput, logger).Act, - agreeWithProposedOutput: cfg.AgreeWithProposedOutput, - loader: loader, - logger: logger, - status: status, + act: agent.Act, + loader: loader, + logger: logger, + status: status, + gameL1Head: l1Head, + syncValidator: syncValidator, + prestateValidators: validators, }, nil } +func (g *GamePlayer) ValidatePrestate(ctx context.Context) error { + for _, validator := range g.prestateValidators { + if err := validator.Validate(ctx); err != nil { + return fmt.Errorf("failed to validate prestate: %w", err) + } + } + return nil +} + func (g *GamePlayer) Status() gameTypes.GameStatus { return g.status } @@ -110,13 +162,20 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) gameTypes.GameStatus { g.logger.Trace("Skipping completed game") return g.status } + if err := g.syncValidator.ValidateNodeSynced(ctx, g.gameL1Head); errors.Is(err, ErrNotInSync) { + g.logger.Warn("Local node not sufficiently up to date", "err", err) + return g.status + } else if err != nil { + g.logger.Error("Could not check local node was in sync", "err", err) + return g.status + } g.logger.Trace("Checking if actions are required") if err := g.act(ctx); err != nil { g.logger.Error("Error when acting on game", "err", err) } - status, err := g.loader.GetGameStatus(ctx) + status, err := g.loader.GetStatus(ctx) if err != nil { - g.logger.Warn("Unable to retrieve game status", "err", err) + g.logger.Error("Unable to retrieve game status", "err", err) return gameTypes.GameStatusInProgress } g.logGameStatus(ctx, status) @@ -134,35 +193,5 @@ func (g *GamePlayer) logGameStatus(ctx context.Context, status gameTypes.GameSta g.logger.Info("Game info", "claims", claimCount, "status", status) return } - var expectedStatus gameTypes.GameStatus - if g.agreeWithProposedOutput { - expectedStatus = gameTypes.GameStatusChallengerWon - } else { - expectedStatus = gameTypes.GameStatusDefenderWon - } - if expectedStatus == status { - g.logger.Info("Game won", "status", status) - } else { - g.logger.Error("Game lost", "status", status) - } -} - -type PrestateLoader interface { - FetchAbsolutePrestateHash(ctx context.Context) (common.Hash, error) -} - -// ValidateAbsolutePrestate validates the absolute prestate of the fault game. -func ValidateAbsolutePrestate(ctx context.Context, trace types.TraceProvider, loader PrestateLoader) error { - providerPrestateHash, err := trace.AbsolutePreStateCommitment(ctx) - if err != nil { - return fmt.Errorf("failed to get the trace provider's absolute prestate: %w", err) - } - onchainPrestate, err := loader.FetchAbsolutePrestateHash(ctx) - if err != nil { - return fmt.Errorf("failed to get the onchain absolute prestate: %w", err) - } - if !bytes.Equal(providerPrestateHash[:], onchainPrestate[:]) { - return fmt.Errorf("trace provider's absolute prestate does not match onchain absolute prestate: Provider: %s | Chain %s", providerPrestateHash.Hex(), onchainPrestate.Hex()) - } - return nil + g.logger.Info("Game resolved", "status", status) } diff --git a/op-challenger/game/fault/player_test.go b/op-challenger/game/fault/player_test.go index 3ed906c94f62..0c662ac63883 100644 --- a/op-challenger/game/fault/player_test.go +++ b/op-challenger/game/fault/player_test.go @@ -6,101 +6,80 @@ import ( "fmt" "testing" - "github.com/ethereum-optimism/optimism/cannon/mipsevm" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" ) -var ( - mockTraceProviderError = fmt.Errorf("mock trace provider error") - mockLoaderError = fmt.Errorf("mock loader error") -) +var mockValidatorError = fmt.Errorf("mock validator error") func TestProgressGame_LogErrorFromAct(t *testing.T) { - handler, game, actor := setupProgressGameTest(t, true) + handler, game, actor, _ := setupProgressGameTest(t) actor.actErr = errors.New("boom") status := game.ProgressGame(context.Background()) - require.Equal(t, gameTypes.GameStatusInProgress, status) + require.Equal(t, types.GameStatusInProgress, status) require.Equal(t, 1, actor.callCount, "should perform next actions") - errLog := handler.FindLog(log.LvlError, "Error when acting on game") + levelFilter := testlog.NewLevelFilter(log.LevelError) + msgFilter := testlog.NewMessageFilter("Error when acting on game") + errLog := handler.FindLog(levelFilter, msgFilter) require.NotNil(t, errLog, "should log error") - require.Equal(t, actor.actErr, errLog.GetContextValue("err")) + require.Equal(t, actor.actErr, errLog.AttrValue("err")) // Should still log game status - msg := handler.FindLog(log.LvlInfo, "Game info") + levelFilter = testlog.NewLevelFilter(log.LevelInfo) + msgFilter = testlog.NewMessageFilter("Game info") + msg := handler.FindLog(levelFilter, msgFilter) require.NotNil(t, msg) - require.Equal(t, uint64(1), msg.GetContextValue("claims")) + require.Equal(t, uint64(1), msg.AttrValue("claims")) } func TestProgressGame_LogGameStatus(t *testing.T) { tests := []struct { - name string - status gameTypes.GameStatus - agreeWithOutput bool - logLevel log.Lvl - logMsg string + name string + status types.GameStatus + logMsg string }{ { - name: "GameLostAsDefender", - status: gameTypes.GameStatusChallengerWon, - agreeWithOutput: false, - logLevel: log.LvlError, - logMsg: "Game lost", - }, - { - name: "GameLostAsChallenger", - status: gameTypes.GameStatusDefenderWon, - agreeWithOutput: true, - logLevel: log.LvlError, - logMsg: "Game lost", + name: "ChallengerWon", + status: types.GameStatusChallengerWon, + logMsg: "Game resolved", }, { - name: "GameWonAsDefender", - status: gameTypes.GameStatusDefenderWon, - agreeWithOutput: false, - logLevel: log.LvlInfo, - logMsg: "Game won", + name: "DefenderWon", + status: types.GameStatusDefenderWon, + logMsg: "Game resolved", }, { - name: "GameWonAsChallenger", - status: gameTypes.GameStatusChallengerWon, - agreeWithOutput: true, - logLevel: log.LvlInfo, - logMsg: "Game won", - }, - { - name: "GameInProgress", - status: gameTypes.GameStatusInProgress, - agreeWithOutput: true, - logLevel: log.LvlInfo, - logMsg: "Game info", + name: "GameInProgress", + status: types.GameStatusInProgress, + logMsg: "Game info", }, } for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { - handler, game, gameState := setupProgressGameTest(t, test.agreeWithOutput) + handler, game, gameState, _ := setupProgressGameTest(t) gameState.status = test.status status := game.ProgressGame(context.Background()) require.Equal(t, 1, gameState.callCount, "should perform next actions") require.Equal(t, test.status, status) - errLog := handler.FindLog(test.logLevel, test.logMsg) + levelFilter := testlog.NewLevelFilter(log.LevelInfo) + msgFilter := testlog.NewMessageFilter(test.logMsg) + errLog := handler.FindLog(levelFilter, msgFilter) require.NotNil(t, errLog, "should log game result") - require.Equal(t, test.status, errLog.GetContextValue("status")) + require.Equal(t, test.status, errLog.AttrValue("status")) }) } } func TestDoNotActOnCompleteGame(t *testing.T) { - for _, status := range []gameTypes.GameStatus{gameTypes.GameStatusChallengerWon, gameTypes.GameStatusDefenderWon} { + for _, status := range []types.GameStatus{types.GameStatusChallengerWon, types.GameStatusDefenderWon} { t.Run(status.String(), func(t *testing.T) { - _, game, gameState := setupProgressGameTest(t, true) + _, game, gameState, _ := setupProgressGameTest(t) gameState.status = status fetched := game.ProgressGame(context.Background()) @@ -115,61 +94,100 @@ func TestDoNotActOnCompleteGame(t *testing.T) { } } -// TestValidateAbsolutePrestate tests that the absolute prestate is validated -// correctly by the service component. -func TestValidateAbsolutePrestate(t *testing.T) { - t.Run("ValidPrestates", func(t *testing.T) { - prestate := []byte{0x00, 0x01, 0x02, 0x03} - prestateHash := crypto.Keccak256(prestate) - prestateHash[0] = mipsevm.VMStatusUnfinished - mockTraceProvider := newMockTraceProvider(false, prestate) - mockLoader := newMockPrestateLoader(false, common.BytesToHash(prestateHash)) - err := ValidateAbsolutePrestate(context.Background(), mockTraceProvider, mockLoader) - require.NoError(t, err) - }) - - t.Run("TraceProviderErrors", func(t *testing.T) { - prestate := []byte{0x00, 0x01, 0x02, 0x03} - mockTraceProvider := newMockTraceProvider(true, prestate) - mockLoader := newMockPrestateLoader(false, common.BytesToHash(prestate)) - err := ValidateAbsolutePrestate(context.Background(), mockTraceProvider, mockLoader) - require.ErrorIs(t, err, mockTraceProviderError) - }) - - t.Run("LoaderErrors", func(t *testing.T) { - prestate := []byte{0x00, 0x01, 0x02, 0x03} - mockTraceProvider := newMockTraceProvider(false, prestate) - mockLoader := newMockPrestateLoader(true, common.BytesToHash(prestate)) - err := ValidateAbsolutePrestate(context.Background(), mockTraceProvider, mockLoader) - require.ErrorIs(t, err, mockLoaderError) - }) - - t.Run("PrestateMismatch", func(t *testing.T) { - mockTraceProvider := newMockTraceProvider(false, []byte{0x00, 0x01, 0x02, 0x03}) - mockLoader := newMockPrestateLoader(false, common.BytesToHash([]byte{0x00})) - err := ValidateAbsolutePrestate(context.Background(), mockTraceProvider, mockLoader) - require.Error(t, err) - }) +func TestValidateLocalNodeSync(t *testing.T) { + _, game, gameState, syncValidator := setupProgressGameTest(t) + + game.ProgressGame(context.Background()) + require.Equal(t, 1, gameState.callCount, "acts when in sync") + + syncValidator.result = errors.New("boom") + game.ProgressGame(context.Background()) + require.Equal(t, 1, gameState.callCount, "does not act when not in sync") +} + +func TestValidatePrestate(t *testing.T) { + tests := []struct { + name string + validators []Validator + errors bool + }{ + { + name: "SingleValidator", + validators: []Validator{&mockValidator{}}, + errors: false, + }, + { + name: "MultipleValidators", + validators: []Validator{&mockValidator{}, &mockValidator{}}, + errors: false, + }, + { + name: "SingleValidator_Errors", + validators: []Validator{&mockValidator{true}}, + errors: true, + }, + { + name: "MultipleValidators_Errors", + validators: []Validator{&mockValidator{}, &mockValidator{true}}, + errors: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + player := &GamePlayer{ + prestateValidators: test.validators, + } + err := player.ValidatePrestate(context.Background()) + if test.errors { + require.ErrorIs(t, err, mockValidatorError) + } else { + require.NoError(t, err) + } + }) + } +} + +var _ Validator = (*mockValidator)(nil) + +type mockValidator struct { + err bool } -func setupProgressGameTest(t *testing.T, agreeWithProposedRoot bool) (*testlog.CapturingHandler, *GamePlayer, *stubGameState) { - logger := testlog.Logger(t, log.LvlDebug) - handler := &testlog.CapturingHandler{ - Delegate: logger.GetHandler(), +func (m *mockValidator) Validate(_ context.Context) error { + if m.err { + return mockValidatorError } - logger.SetHandler(handler) + return nil +} + +func setupProgressGameTest(t *testing.T) (*testlog.CapturingHandler, *GamePlayer, *stubGameState, *stubSyncValidator) { + logger, logs := testlog.CaptureLogger(t, log.LevelDebug) gameState := &stubGameState{claimCount: 1} + syncValidator := &stubSyncValidator{} game := &GamePlayer{ - act: gameState.Act, - agreeWithProposedOutput: agreeWithProposedRoot, - loader: gameState, - logger: logger, + act: gameState.Act, + loader: gameState, + logger: logger, + syncValidator: syncValidator, + gameL1Head: eth.BlockID{ + Hash: common.Hash{0x1a}, + Number: 32, + }, } - return handler, game, gameState + return logs, game, gameState, syncValidator +} + +type stubSyncValidator struct { + result error +} + +func (s *stubSyncValidator) ValidateNodeSynced(_ context.Context, _ eth.BlockID) error { + return s.result } type stubGameState struct { - status gameTypes.GameStatus + status types.GameStatus claimCount uint64 callCount int actErr error @@ -181,7 +199,7 @@ func (s *stubGameState) Act(ctx context.Context) error { return s.actErr } -func (s *stubGameState) GetGameStatus(ctx context.Context) (gameTypes.GameStatus, error) { +func (s *stubGameState) GetStatus(ctx context.Context) (types.GameStatus, error) { return s.status, nil } @@ -189,54 +207,6 @@ func (s *stubGameState) GetClaimCount(ctx context.Context) (uint64, error) { return s.claimCount, nil } -type mockTraceProvider struct { - prestateErrors bool - prestate []byte -} - -func newMockTraceProvider(prestateErrors bool, prestate []byte) *mockTraceProvider { - return &mockTraceProvider{ - prestateErrors: prestateErrors, - prestate: prestate, - } -} -func (m *mockTraceProvider) Get(ctx context.Context, i types.Position) (common.Hash, error) { - panic("not implemented") -} -func (m *mockTraceProvider) GetStepData(ctx context.Context, i types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) { - panic("not implemented") -} -func (m *mockTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, error) { - if m.prestateErrors { - return nil, mockTraceProviderError - } - return m.prestate, nil -} -func (m *mockTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (common.Hash, error) { - prestate, err := m.AbsolutePreState(ctx) - if err != nil { - return common.Hash{}, err - } - - hash := common.BytesToHash(crypto.Keccak256(prestate)) - hash[0] = mipsevm.VMStatusUnfinished - return hash, nil -} - -type mockLoader struct { - prestateError bool - prestate common.Hash -} - -func newMockPrestateLoader(prestateError bool, prestate common.Hash) *mockLoader { - return &mockLoader{ - prestateError: prestateError, - prestate: prestate, - } -} -func (m *mockLoader) FetchAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { - if m.prestateError { - return common.Hash{}, mockLoaderError - } - return m.prestate, nil +func (s *stubGameState) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { + return common.Hash{}, s.Err } diff --git a/op-challenger/game/fault/preimages/direct.go b/op-challenger/game/fault/preimages/direct.go new file mode 100644 index 000000000000..24c1f51e25fd --- /dev/null +++ b/op-challenger/game/fault/preimages/direct.go @@ -0,0 +1,45 @@ +package preimages + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/log" +) + +var _ PreimageUploader = (*DirectPreimageUploader)(nil) + +type PreimageGameContract interface { + UpdateOracleTx(ctx context.Context, claimIdx uint64, data *types.PreimageOracleData) (txmgr.TxCandidate, error) +} + +// DirectPreimageUploader uploads the provided [types.PreimageOracleData] +// directly to the PreimageOracle contract in a single transaction. +type DirectPreimageUploader struct { + log log.Logger + + txSender gameTypes.TxSender + contract PreimageGameContract +} + +func NewDirectPreimageUploader(logger log.Logger, txSender gameTypes.TxSender, contract PreimageGameContract) *DirectPreimageUploader { + return &DirectPreimageUploader{logger, txSender, contract} +} + +func (d *DirectPreimageUploader) UploadPreimage(ctx context.Context, claimIdx uint64, data *types.PreimageOracleData) error { + if data == nil { + return ErrNilPreimageData + } + d.log.Info("Updating oracle data", "key", fmt.Sprintf("%x", data.OracleKey)) + candidate, err := d.contract.UpdateOracleTx(ctx, claimIdx, data) + if err != nil { + return fmt.Errorf("failed to create pre-image oracle tx: %w", err) + } + if _, err := d.txSender.SendAndWait("populate pre-image oracle", candidate); err != nil { + return fmt.Errorf("failed to populate pre-image oracle: %w", err) + } + return nil +} diff --git a/op-challenger/game/fault/preimages/direct_test.go b/op-challenger/game/fault/preimages/direct_test.go new file mode 100644 index 000000000000..473334237fc7 --- /dev/null +++ b/op-challenger/game/fault/preimages/direct_test.go @@ -0,0 +1,95 @@ +package preimages + +import ( + "context" + "errors" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var ( + mockUpdateOracleTxError = errors.New("mock update oracle tx error") + mockTxMgrSendError = errors.New("mock tx mgr send error") + mockInitLPPError = errors.New("mock init LPP error") +) + +func TestDirectPreimageUploader_UploadPreimage(t *testing.T) { + t.Run("UpdateOracleTxFails", func(t *testing.T) { + oracle, txMgr, contract := newTestDirectPreimageUploader(t) + contract.updateFails = true + err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{}) + require.ErrorIs(t, err, mockUpdateOracleTxError) + require.Equal(t, 1, contract.updateCalls) + require.Equal(t, 0, txMgr.sends) // verify that the tx was not sent + }) + + t.Run("SendFails", func(t *testing.T) { + oracle, txMgr, contract := newTestDirectPreimageUploader(t) + txMgr.sendFails = true + err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{}) + require.ErrorIs(t, err, mockTxMgrSendError) + require.Equal(t, 1, contract.updateCalls) + require.Equal(t, 1, txMgr.sends) + }) + + t.Run("NilPreimageData", func(t *testing.T) { + oracle, _, _ := newTestDirectPreimageUploader(t) + err := oracle.UploadPreimage(context.Background(), 0, nil) + require.ErrorIs(t, err, ErrNilPreimageData) + }) + + t.Run("Success", func(t *testing.T) { + oracle, _, contract := newTestDirectPreimageUploader(t) + err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{}) + require.NoError(t, err) + require.Equal(t, 1, contract.updateCalls) + }) +} + +func newTestDirectPreimageUploader(t *testing.T) (*DirectPreimageUploader, *mockTxSender, *mockPreimageGameContract) { + logger := testlog.Logger(t, log.LevelError) + txMgr := &mockTxSender{} + contract := &mockPreimageGameContract{} + return NewDirectPreimageUploader(logger, txMgr, contract), txMgr, contract +} + +type mockPreimageGameContract struct { + updateCalls int + updateFails bool +} + +func (s *mockPreimageGameContract) UpdateOracleTx(_ context.Context, _ uint64, _ *types.PreimageOracleData) (txmgr.TxCandidate, error) { + s.updateCalls++ + if s.updateFails { + return txmgr.TxCandidate{}, mockUpdateOracleTxError + } + return txmgr.TxCandidate{}, nil +} + +type mockTxSender struct { + sends int + sendFails bool + statusFail bool +} + +func (s *mockTxSender) From() common.Address { + return common.Address{} +} + +func (s *mockTxSender) SendAndWait(_ string, _ ...txmgr.TxCandidate) ([]*ethtypes.Receipt, error) { + s.sends++ + if s.sendFails { + return nil, mockTxMgrSendError + } + if s.statusFail { + return []*ethtypes.Receipt{{Status: ethtypes.ReceiptStatusFailed}}, nil + } + return []*ethtypes.Receipt{{Status: ethtypes.ReceiptStatusSuccessful}}, nil +} diff --git a/op-challenger/game/fault/preimages/large.go b/op-challenger/game/fault/preimages/large.go new file mode 100644 index 000000000000..47fa47e804f7 --- /dev/null +++ b/op-challenger/game/fault/preimages/large.go @@ -0,0 +1,196 @@ +package preimages + +import ( + "bytes" + "context" + "encoding/binary" + "errors" + "fmt" + "io" + "math/big" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/matrix" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" +) + +var _ PreimageUploader = (*LargePreimageUploader)(nil) + +// ErrChallengePeriodNotOver is returned when the challenge period is not over. +var ErrChallengePeriodNotOver = errors.New("challenge period not over") + +// MaxBlocksPerChunk is the maximum number of keccak blocks per chunk. +const MaxBlocksPerChunk = 300 + +// MaxChunkSize is the maximum size of a preimage chunk in bytes. +// Notice, the max chunk size must be a multiple of the leaf size. +// The max chunk size is roughly 0.04MB to avoid memory expansion. +const MaxChunkSize = MaxBlocksPerChunk * keccakTypes.BlockSize + +// LargePreimageUploader handles uploading large preimages by +// streaming the merkleized preimage to the PreimageOracle contract, +// tightly packed across multiple transactions. +type LargePreimageUploader struct { + log log.Logger + + clock types.ClockReader + txSender gameTypes.TxSender + contract PreimageOracleContract +} + +func NewLargePreimageUploader(logger log.Logger, cl types.ClockReader, txSender gameTypes.TxSender, contract PreimageOracleContract) *LargePreimageUploader { + return &LargePreimageUploader{logger, cl, txSender, contract} +} + +func (p *LargePreimageUploader) UploadPreimage(ctx context.Context, parent uint64, data *types.PreimageOracleData) error { + p.log.Debug("Upload large preimage", "key", hexutil.Bytes(data.OracleKey)) + stateMatrix, calls, err := p.splitCalls(data) + if err != nil { + return fmt.Errorf("failed to split preimage into chunks for data with oracle offset %d: %w", data.OracleOffset, err) + } + + uuid := NewUUID(p.txSender.From(), data) + + // Fetch the current metadata for this preimage data, if it exists. + ident := keccakTypes.LargePreimageIdent{Claimant: p.txSender.From(), UUID: uuid} + metadata, err := p.contract.GetProposalMetadata(ctx, rpcblock.Latest, ident) + if err != nil { + return fmt.Errorf("failed to get pre-image oracle metadata: %w", err) + } + + // The proposal is not initialized if the queried metadata has a claimed size of 0. + if len(metadata) == 1 && metadata[0].ClaimedSize == 0 { + err = p.initLargePreimage(uuid, data.OracleOffset, uint32(len(data.GetPreimageWithoutSize()))) + if err != nil { + return fmt.Errorf("failed to initialize large preimage with uuid: %s: %w", uuid, err) + } + } + + // Filter out any chunks that have already been uploaded to the Preimage Oracle. + if len(metadata) > 0 { + numSkip := metadata[0].BytesProcessed / MaxChunkSize + calls = calls[numSkip:] + // If the timestamp is non-zero, the preimage has been finalized. + if metadata[0].Timestamp != 0 { + calls = calls[len(calls):] + } + } + + err = p.addLargePreimageData(uuid, calls) + if err != nil { + return fmt.Errorf("failed to add leaves to large preimage with uuid: %s: %w", uuid, err) + } + + return p.Squeeze(ctx, uuid, stateMatrix) +} + +// NewUUID generates a new unique identifier for the preimage by hashing the +// concatenated preimage data, preimage offset, and sender address. +func NewUUID(sender common.Address, data *types.PreimageOracleData) *big.Int { + offset := make([]byte, 4) + binary.LittleEndian.PutUint32(offset, data.OracleOffset) + concatenated := append(data.GetPreimageWithoutSize(), offset...) + concatenated = append(concatenated, sender.Bytes()...) + hash := crypto.Keccak256Hash(concatenated) + return hash.Big() +} + +// splitChunks splits the preimage data into chunks of size [MaxChunkSize] (except the last chunk). +// It also returns the state matrix and the data for the squeeze call if possible. +func (p *LargePreimageUploader) splitCalls(data *types.PreimageOracleData) (*matrix.StateMatrix, []keccakTypes.InputData, error) { + // Split the preimage data into chunks of size [MaxChunkSize] (except the last chunk). + stateMatrix := matrix.NewStateMatrix() + var calls []keccakTypes.InputData + in := bytes.NewReader(data.GetPreimageWithoutSize()) + for { + call, err := stateMatrix.AbsorbUpTo(in, MaxChunkSize) + if errors.Is(err, io.EOF) { + calls = append(calls, call) + break + } else if err != nil { + return nil, nil, fmt.Errorf("failed to absorb data: %w", err) + } + calls = append(calls, call) + } + return stateMatrix, calls, nil +} + +func (p *LargePreimageUploader) Squeeze(ctx context.Context, uuid *big.Int, stateMatrix *matrix.StateMatrix) error { + prestateMatrix := stateMatrix.PrestateMatrix() + prestate, prestateProof := stateMatrix.PrestateWithProof() + poststate, poststateProof := stateMatrix.PoststateWithProof() + challengePeriod, err := p.contract.ChallengePeriod(ctx) + if err != nil { + return fmt.Errorf("failed to get challenge period: %w", err) + } + currentTimestamp := p.clock.Now().Unix() + ident := keccakTypes.LargePreimageIdent{Claimant: p.txSender.From(), UUID: uuid} + metadata, err := p.contract.GetProposalMetadata(ctx, rpcblock.Latest, ident) + if err != nil { + return fmt.Errorf("failed to get pre-image oracle metadata: %w", err) + } + if len(metadata) == 0 || metadata[0].ClaimedSize == 0 { + return fmt.Errorf("no metadata found for pre-image oracle with uuid: %s", uuid) + } + if uint64(currentTimestamp) < metadata[0].Timestamp+challengePeriod { + return ErrChallengePeriodNotOver + } + if err := p.contract.CallSqueeze(ctx, p.txSender.From(), uuid, prestateMatrix, prestate, prestateProof, poststate, poststateProof); err != nil { + p.log.Warn("Expected a successful squeeze call", "metadataTimestamp", metadata[0].Timestamp, "currentTimestamp", currentTimestamp, "err", err) + return fmt.Errorf("failed to call squeeze: %w", err) + } + p.log.Info("Squeezing large preimage", "uuid", uuid) + tx, err := p.contract.Squeeze(p.txSender.From(), uuid, prestateMatrix, prestate, prestateProof, poststate, poststateProof) + if err != nil { + return fmt.Errorf("failed to create pre-image oracle tx: %w", err) + } + if _, err := p.txSender.SendAndWait("squeeze large preimage", tx); err != nil { + return fmt.Errorf("failed to populate pre-image oracle: %w", err) + } + return nil +} + +// initLargePreimage initializes the large preimage proposal. +// This method *must* be called before adding any leaves. +func (p *LargePreimageUploader) initLargePreimage(uuid *big.Int, partOffset uint32, claimedSize uint32) error { + p.log.Info("Init large preimage upload", "uuid", uuid, "partOffset", partOffset, "size", claimedSize) + candidate, err := p.contract.InitLargePreimage(uuid, partOffset, claimedSize) + if err != nil { + return fmt.Errorf("failed to create pre-image oracle tx: %w", err) + } + bond, err := p.contract.GetMinBondLPP(context.Background()) + if err != nil { + return fmt.Errorf("failed to get min bond for large preimage proposal: %w", err) + } + candidate.Value = bond + if _, err := p.txSender.SendAndWait("init large preimage", candidate); err != nil { + return fmt.Errorf("failed to populate pre-image oracle: %w", err) + } + return nil +} + +// addLargePreimageData adds data to the large preimage proposal. +// This method **must** be called after calling [initLargePreimage]. +// SAFETY: submits transactions in a [Queue] for latency while preserving submission order. +func (p *LargePreimageUploader) addLargePreimageData(uuid *big.Int, chunks []keccakTypes.InputData) error { + txs := make([]txmgr.TxCandidate, len(chunks)) + blocksProcessed := int64(0) + for i, chunk := range chunks { + tx, err := p.contract.AddLeaves(uuid, big.NewInt(blocksProcessed), chunk.Input, chunk.Commitments, chunk.Finalize) + if err != nil { + return fmt.Errorf("failed to create pre-image oracle tx: %w", err) + } + blocksProcessed += int64(len(chunk.Input) / keccakTypes.BlockSize) + txs[i] = tx + } + p.log.Info("Adding large preimage leaves", "uuid", uuid, "blocksProcessed", blocksProcessed, "txs", len(txs)) + _, err := p.txSender.SendAndWait("add leaf to large preimage", txs...) + return err +} diff --git a/op-challenger/game/fault/preimages/large_test.go b/op-challenger/game/fault/preimages/large_test.go new file mode 100644 index 000000000000..1913e5a6a47d --- /dev/null +++ b/op-challenger/game/fault/preimages/large_test.go @@ -0,0 +1,351 @@ +package preimages + +import ( + "bytes" + "context" + "encoding/binary" + "errors" + "io" + "math/big" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/matrix" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/merkle" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + preimage "github.com/ethereum-optimism/optimism/op-preimage" + "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var ( + mockChallengePeriod = uint64(10000000) + mockAddLeavesError = errors.New("mock add leaves error") + mockSqueezeError = errors.New("mock squeeze error") + mockSqueezeCallError = errors.New("mock squeeze call error") +) + +func TestLargePreimageUploader_NewUUID(t *testing.T) { + tests := []struct { + name string + data *types.PreimageOracleData + expectedUUID *big.Int + }{ + { + name: "EmptyOracleData", + data: makePreimageData([]byte{}, 0), + expectedUUID: new(big.Int).SetBytes(common.FromHex("827b659bbda2a0bdecce2c91b8b68462545758f3eba2dbefef18e0daf84f5ccd")), + }, + { + name: "OracleDataAndOffset_Control", + data: makePreimageData([]byte{1, 2, 3}, 0x010203), + expectedUUID: new(big.Int).SetBytes(common.FromHex("641e230bcf3ade8c71b7e591d210184cdb190e853f61ba59a1411c3b7aca9890")), + }, + { + name: "OracleDataAndOffset_DifferentOffset", + data: makePreimageData([]byte{1, 2, 3}, 0x010204), + expectedUUID: new(big.Int).SetBytes(common.FromHex("aec56de44401325420e5793f72b777e3e547778de7d8344004b31be086a3136d")), + }, + { + name: "OracleDataAndOffset_DifferentData", + data: makePreimageData([]byte{1, 2, 3, 4}, 0x010203), + expectedUUID: new(big.Int).SetBytes(common.FromHex("ca38aa17d56805cf26376a050c2c7b15b6be4e709bc422a1c679fe21aa6aa8c7")), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + oracle, _, _, _ := newTestLargePreimageUploader(t) + uuid := NewUUID(oracle.txSender.From(), test.data) + require.Equal(t, test.expectedUUID, uuid) + }) + } +} + +func TestLargePreimageUploader_UploadPreimage_EdgeCases(t *testing.T) { + t.Run("InitFails", func(t *testing.T) { + oracle, _, _, contract := newTestLargePreimageUploader(t) + contract.initFails = true + data := mockPreimageOracleData() + err := oracle.UploadPreimage(context.Background(), 0, data) + require.ErrorIs(t, err, mockInitLPPError) + require.Equal(t, 1, contract.initCalls) + }) + + t.Run("AddLeavesFails", func(t *testing.T) { + oracle, _, _, contract := newTestLargePreimageUploader(t) + contract.addFails = true + data := mockPreimageOracleData() + err := oracle.UploadPreimage(context.Background(), 0, data) + require.ErrorIs(t, err, mockAddLeavesError) + require.Equal(t, 1, contract.addCalls) + }) + + t.Run("NoBytesProcessed", func(t *testing.T) { + oracle, _, _, contract := newTestLargePreimageUploader(t) + data := mockPreimageOracleData() + contract.claimedSize = uint32(len(data.GetPreimageWithoutSize())) + err := oracle.UploadPreimage(context.Background(), 0, data) + require.NoError(t, err) + require.Equal(t, 1, contract.initCalls) + require.Equal(t, 6, contract.addCalls) + require.Equal(t, data.GetPreimageWithoutSize(), contract.addData) + }) + + t.Run("AlreadyInitialized", func(t *testing.T) { + oracle, _, _, contract := newTestLargePreimageUploader(t) + data := mockPreimageOracleData() + contract.initialized = true + contract.claimedSize = uint32(len(data.GetPreimageWithoutSize())) + err := oracle.UploadPreimage(context.Background(), 0, data) + require.NoError(t, err) + require.Equal(t, 0, contract.initCalls) + require.Equal(t, 6, contract.addCalls) + }) + + t.Run("ChallengePeriodNotElapsed", func(t *testing.T) { + oracle, cl, _, contract := newTestLargePreimageUploader(t) + data := mockPreimageOracleData() + contract.bytesProcessed = 5*MaxChunkSize + 1 + contract.claimedSize = uint32(len(data.GetPreimageWithoutSize())) + contract.timestamp = uint64(cl.Now().Unix()) + err := oracle.UploadPreimage(context.Background(), 0, data) + require.ErrorIs(t, err, ErrChallengePeriodNotOver) + require.Equal(t, 0, contract.squeezeCalls) + // Squeeze should be called once the challenge period has elapsed. + cl.AdvanceTime(time.Duration(mockChallengePeriod) * time.Second) + err = oracle.UploadPreimage(context.Background(), 0, data) + require.NoError(t, err) + require.Equal(t, 1, contract.squeezeCalls) + }) + + t.Run("SqueezeCallFails", func(t *testing.T) { + oracle, _, _, contract := newTestLargePreimageUploader(t) + data := mockPreimageOracleData() + contract.bytesProcessed = 5*MaxChunkSize + 1 + contract.timestamp = 123 + contract.claimedSize = uint32(len(data.GetPreimageWithoutSize())) + contract.squeezeCallFails = true + err := oracle.UploadPreimage(context.Background(), 0, data) + require.ErrorIs(t, err, mockSqueezeCallError) + require.Equal(t, 0, contract.squeezeCalls) + }) + + t.Run("SqueezeFails", func(t *testing.T) { + oracle, _, _, contract := newTestLargePreimageUploader(t) + data := mockPreimageOracleData() + contract.bytesProcessed = 5*MaxChunkSize + 1 + contract.timestamp = 123 + contract.claimedSize = uint32(len(data.GetPreimageWithoutSize())) + contract.squeezeFails = true + err := oracle.UploadPreimage(context.Background(), 0, data) + require.ErrorIs(t, err, mockSqueezeError) + require.Equal(t, 1, contract.squeezeCalls) + }) + + t.Run("AllBytesProcessed", func(t *testing.T) { + oracle, _, _, contract := newTestLargePreimageUploader(t) + data := mockPreimageOracleData() + contract.bytesProcessed = 5*MaxChunkSize + 1 + contract.timestamp = 123 + contract.claimedSize = uint32(len(data.GetPreimageWithoutSize())) + err := oracle.UploadPreimage(context.Background(), 0, data) + require.NoError(t, err) + require.Equal(t, 0, contract.initCalls) + require.Equal(t, 0, contract.addCalls) + require.Empty(t, contract.addData) + }) +} + +func mockPreimageOracleData() *types.PreimageOracleData { + fullLeaf := make([]byte, keccakTypes.BlockSize) + for i := 0; i < keccakTypes.BlockSize; i++ { + fullLeaf[i] = byte(i) + } + oracleData := make([]byte, 5*MaxBlocksPerChunk) + for i := 0; i < 5*MaxBlocksPerChunk; i++ { + oracleData = append(oracleData, fullLeaf...) + } + // Add a single byte to the end to make sure the last leaf is not processed. + oracleData = append(oracleData, byte(1)) + return makePreimageData(oracleData, 0) +} + +func makePreimageData(pre []byte, offset uint32) *types.PreimageOracleData { + key := preimage.Keccak256Key(crypto.Keccak256Hash(pre)).PreimageKey() + // add the length prefix + preimage := make([]byte, 0, 8+len(pre)) + preimage = binary.BigEndian.AppendUint64(preimage, uint64(len(pre))) + preimage = append(preimage, pre...) + return types.NewPreimageOracleData(key[:], preimage, offset) +} + +func TestLargePreimageUploader_UploadPreimage_Succeeds(t *testing.T) { + fullLeaf := new([keccakTypes.BlockSize]byte) + for i := 0; i < keccakTypes.BlockSize; i++ { + fullLeaf[i] = byte(i) + } + chunk := make([]byte, 0, MaxChunkSize) + for i := 0; i < MaxBlocksPerChunk; i++ { + chunk = append(chunk, fullLeaf[:]...) + } + tests := []struct { + name string + input []byte + addCalls int + prestateLeaf keccakTypes.Leaf + poststateLeaf keccakTypes.Leaf + }{ + { + name: "FullLeaf", + input: fullLeaf[:], + addCalls: 1, + }, + { + name: "MultipleLeaves", + input: append(fullLeaf[:], append(fullLeaf[:], fullLeaf[:]...)...), + addCalls: 1, + }, + { + name: "MultipleLeavesUnaligned", + input: append(fullLeaf[:], append(fullLeaf[:], byte(9))...), + addCalls: 1, + }, + { + name: "MultipleChunks", + input: append(chunk, append(fullLeaf[:], fullLeaf[:]...)...), + addCalls: 2, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + oracle, _, _, contract := newTestLargePreimageUploader(t) + data := makePreimageData(test.input, 0) + err := oracle.UploadPreimage(context.Background(), 0, data) + require.NoError(t, err) + require.Equal(t, test.addCalls, contract.addCalls) + // There must always be at least one init and squeeze call + // for successful large preimage upload calls. + require.Equal(t, 1, contract.initCalls) + require.Equal(t, 1, contract.squeezeCalls) + + // Use the StateMatrix to determine the expected leaves so it includes padding correctly. + // We rely on the unit tests for StateMatrix to confirm that it does the right thing. + s := matrix.NewStateMatrix() + _, err = s.AbsorbUpTo(bytes.NewReader(test.input), keccakTypes.BlockSize*10000) + require.ErrorIs(t, err, io.EOF) + prestate, _ := s.PrestateWithProof() + poststate, _ := s.PoststateWithProof() + require.Equal(t, prestate, contract.squeezePrestate) + require.Equal(t, poststate, contract.squeezePoststate) + }) + } +} + +func newTestLargePreimageUploader(t *testing.T) (*LargePreimageUploader, *clock.AdvancingClock, *mockTxSender, *mockPreimageOracleContract) { + logger := testlog.Logger(t, log.LevelError) + cl := clock.NewAdvancingClock(time.Second) + cl.Start() + txSender := &mockTxSender{} + contract := &mockPreimageOracleContract{ + addData: make([]byte, 0), + } + return NewLargePreimageUploader(logger, cl, txSender, contract), cl, txSender, contract +} + +type mockPreimageOracleContract struct { + initCalls int + initFails bool + initialized bool + claimedSize uint32 + bytesProcessed int + timestamp uint64 + addCalls int + addFails bool + addData []byte + squeezeCalls int + squeezeFails bool + squeezeCallFails bool + squeezeCallClaimSize uint32 + squeezePrestate keccakTypes.Leaf + squeezePoststate keccakTypes.Leaf +} + +func (s *mockPreimageOracleContract) InitLargePreimage(_ *big.Int, _ uint32, _ uint32) (txmgr.TxCandidate, error) { + s.initCalls++ + if s.initFails { + return txmgr.TxCandidate{}, mockInitLPPError + } + return txmgr.TxCandidate{}, nil +} + +func (s *mockPreimageOracleContract) AddLeaves(_ *big.Int, _ *big.Int, input []byte, _ []common.Hash, _ bool) (txmgr.TxCandidate, error) { + s.addCalls++ + s.addData = append(s.addData, input...) + if s.addFails { + return txmgr.TxCandidate{}, mockAddLeavesError + } + return txmgr.TxCandidate{}, nil +} + +func (s *mockPreimageOracleContract) Squeeze(_ common.Address, _ *big.Int, _ keccakTypes.StateSnapshot, prestate keccakTypes.Leaf, _ merkle.Proof, poststate keccakTypes.Leaf, _ merkle.Proof) (txmgr.TxCandidate, error) { + s.squeezeCalls++ + s.squeezePrestate = prestate + s.squeezePoststate = poststate + if s.squeezeFails { + return txmgr.TxCandidate{}, mockSqueezeError + } + return txmgr.TxCandidate{}, nil +} + +func (s *mockPreimageOracleContract) ChallengePeriod(_ context.Context) (uint64, error) { + return mockChallengePeriod, nil +} + +func (s *mockPreimageOracleContract) GetProposalMetadata(_ context.Context, _ rpcblock.Block, idents ...keccakTypes.LargePreimageIdent) ([]keccakTypes.LargePreimageMetaData, error) { + if s.squeezeCallClaimSize > 0 { + metadata := make([]keccakTypes.LargePreimageMetaData, 0) + for _, ident := range idents { + metadata = append(metadata, keccakTypes.LargePreimageMetaData{ + LargePreimageIdent: ident, + ClaimedSize: s.squeezeCallClaimSize, + BytesProcessed: uint32(s.bytesProcessed), + Timestamp: s.timestamp, + }) + } + return metadata, nil + } + if s.initialized || s.bytesProcessed > 0 { + metadata := make([]keccakTypes.LargePreimageMetaData, 0) + for _, ident := range idents { + metadata = append(metadata, keccakTypes.LargePreimageMetaData{ + LargePreimageIdent: ident, + ClaimedSize: s.claimedSize, + BytesProcessed: uint32(s.bytesProcessed), + Timestamp: s.timestamp, + }) + } + return metadata, nil + } + s.squeezeCallClaimSize = 1 + return []keccakTypes.LargePreimageMetaData{{LargePreimageIdent: idents[0]}}, nil +} + +func (s *mockPreimageOracleContract) GetMinBondLPP(_ context.Context) (*big.Int, error) { + return big.NewInt(0), nil +} + +func (s *mockPreimageOracleContract) CallSqueeze(_ context.Context, _ common.Address, _ *big.Int, _ keccakTypes.StateSnapshot, _ keccakTypes.Leaf, _ merkle.Proof, _ keccakTypes.Leaf, _ merkle.Proof) error { + if s.squeezeCallFails { + return mockSqueezeCallError + } + return nil +} diff --git a/op-challenger/game/fault/preimages/split.go b/op-challenger/game/fault/preimages/split.go new file mode 100644 index 000000000000..84541c7feb6e --- /dev/null +++ b/op-challenger/game/fault/preimages/split.go @@ -0,0 +1,33 @@ +package preimages + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" +) + +var _ PreimageUploader = (*SplitPreimageUploader)(nil) + +// SplitPreimageUploader routes preimage uploads to the appropriate uploader +// based on the size of the preimage. +type SplitPreimageUploader struct { + largePreimageSizeThreshold uint64 + directUploader PreimageUploader + largeUploader PreimageUploader +} + +func NewSplitPreimageUploader(directUploader PreimageUploader, largeUploader PreimageUploader, minLargePreimageSize uint64) *SplitPreimageUploader { + return &SplitPreimageUploader{minLargePreimageSize, directUploader, largeUploader} +} + +func (s *SplitPreimageUploader) UploadPreimage(ctx context.Context, parent uint64, data *types.PreimageOracleData) error { + if data == nil { + return ErrNilPreimageData + } + // Always route local preimage uploads to the direct uploader. + if data.IsLocal || uint64(len(data.GetPreimageWithoutSize())) < s.largePreimageSizeThreshold { + return s.directUploader.UploadPreimage(ctx, parent, data) + } else { + return s.largeUploader.UploadPreimage(ctx, parent, data) + } +} diff --git a/op-challenger/game/fault/preimages/split_test.go b/op-challenger/game/fault/preimages/split_test.go new file mode 100644 index 000000000000..fbecdc06467c --- /dev/null +++ b/op-challenger/game/fault/preimages/split_test.go @@ -0,0 +1,70 @@ +package preimages + +import ( + "context" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/stretchr/testify/require" +) + +var mockLargePreimageSizeThreshold = uint64(100) + +func TestSplitPreimageUploader_UploadPreimage(t *testing.T) { + t.Run("DirectUploadSucceeds", func(t *testing.T) { + oracle, direct, large := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold) + err := oracle.UploadPreimage(context.Background(), 0, makePreimageData(nil, 0)) + require.NoError(t, err) + require.Equal(t, 1, direct.updates) + require.Equal(t, 0, large.updates) + }) + + t.Run("LocalDataUploadSucceeds", func(t *testing.T) { + oracle, direct, large := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold) + err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{IsLocal: true}) + require.NoError(t, err) + require.Equal(t, 1, direct.updates) + require.Equal(t, 0, large.updates) + }) + + t.Run("MaxSizeDirectUploadSucceeds", func(t *testing.T) { + oracle, direct, large := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold) + err := oracle.UploadPreimage(context.Background(), 0, makePreimageData(make([]byte, mockLargePreimageSizeThreshold-1), 0)) + require.NoError(t, err) + require.Equal(t, 1, direct.updates) + require.Equal(t, 0, large.updates) + }) + + t.Run("LargeUploadSucceeds", func(t *testing.T) { + oracle, direct, large := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold) + err := oracle.UploadPreimage(context.Background(), 0, makePreimageData(make([]byte, mockLargePreimageSizeThreshold), 0)) + require.NoError(t, err) + require.Equal(t, 1, large.updates) + require.Equal(t, 0, direct.updates) + }) + + t.Run("NilPreimageOracleData", func(t *testing.T) { + oracle, _, _ := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold) + err := oracle.UploadPreimage(context.Background(), 0, nil) + require.ErrorIs(t, err, ErrNilPreimageData) + }) +} + +type mockPreimageUploader struct { + updates int + uploadFails bool +} + +func (s *mockPreimageUploader) UploadPreimage(ctx context.Context, parent uint64, data *types.PreimageOracleData) error { + s.updates++ + if s.uploadFails { + return mockUpdateOracleTxError + } + return nil +} + +func newTestSplitPreimageUploader(t *testing.T, threshold uint64) (*SplitPreimageUploader, *mockPreimageUploader, *mockPreimageUploader) { + direct := &mockPreimageUploader{} + large := &mockPreimageUploader{} + return NewSplitPreimageUploader(direct, large, threshold), direct, large +} diff --git a/op-challenger/game/fault/preimages/types.go b/op-challenger/game/fault/preimages/types.go new file mode 100644 index 000000000000..45665d5fc94e --- /dev/null +++ b/op-challenger/game/fault/preimages/types.go @@ -0,0 +1,33 @@ +package preimages + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/merkle" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" +) + +var ErrNilPreimageData = fmt.Errorf("cannot upload nil preimage data") + +// PreimageUploader is responsible for posting preimages. +type PreimageUploader interface { + // UploadPreimage uploads the provided preimage. + UploadPreimage(ctx context.Context, claimIdx uint64, data *types.PreimageOracleData) error +} + +// PreimageOracleContract is the interface for interacting with the PreimageOracle contract. +type PreimageOracleContract interface { + InitLargePreimage(uuid *big.Int, partOffset uint32, claimedSize uint32) (txmgr.TxCandidate, error) + AddLeaves(uuid *big.Int, startingBlockIndex *big.Int, input []byte, commitments []common.Hash, finalize bool) (txmgr.TxCandidate, error) + Squeeze(claimant common.Address, uuid *big.Int, prestateMatrix keccakTypes.StateSnapshot, preState keccakTypes.Leaf, preStateProof merkle.Proof, postState keccakTypes.Leaf, postStateProof merkle.Proof) (txmgr.TxCandidate, error) + CallSqueeze(ctx context.Context, claimant common.Address, uuid *big.Int, prestateMatrix keccakTypes.StateSnapshot, preState keccakTypes.Leaf, preStateProof merkle.Proof, postState keccakTypes.Leaf, postStateProof merkle.Proof) error + GetProposalMetadata(ctx context.Context, block rpcblock.Block, idents ...keccakTypes.LargePreimageIdent) ([]keccakTypes.LargePreimageMetaData, error) + ChallengePeriod(ctx context.Context) (uint64, error) + GetMinBondLPP(ctx context.Context) (*big.Int, error) +} diff --git a/op-challenger/game/fault/register.go b/op-challenger/game/fault/register.go index 26816907695e..936cb7145af2 100644 --- a/op-challenger/game/fault/register.go +++ b/op-challenger/game/fault/register.go @@ -5,62 +5,240 @@ import ( "fmt" "github.com/ethereum-optimism/optimism/op-challenger/config" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/claims" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" - "github.com/ethereum-optimism/optimism/op-service/txmgr" - "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" ) -var ( - cannonGameType = uint8(0) - alphabetGameType = uint8(255) -) +type CloseFunc func() type Registry interface { - RegisterGameType(gameType uint8, creator scheduler.PlayerCreator) + RegisterGameType(gameType uint32, creator scheduler.PlayerCreator) + RegisterBondContract(gameType uint32, creator claims.BondContractCreator) +} + +type OracleRegistry interface { + RegisterOracle(oracle keccakTypes.LargePreimageOracle) +} + +type RollupClient interface { + outputs.OutputRollupClient + SyncStatusProvider } func RegisterGameTypes( - registry Registry, ctx context.Context, + cl faultTypes.ClockReader, logger log.Logger, m metrics.Metricer, cfg *config.Config, - txMgr txmgr.TxManager, - client bind.ContractCaller, -) { + registry Registry, + oracles OracleRegistry, + rollupClient RollupClient, + txSender types.TxSender, + gameFactory *contracts.DisputeGameFactoryContract, + caller *batching.MultiCaller, + l1HeaderSource L1HeaderSource, + selective bool, + claimants []common.Address, +) (CloseFunc, error) { + var closer CloseFunc + var l2Client *ethclient.Client + if cfg.TraceTypeEnabled(config.TraceTypeCannon) || cfg.TraceTypeEnabled(config.TraceTypePermissioned) { + l2, err := ethclient.DialContext(ctx, cfg.CannonL2) + if err != nil { + return nil, fmt.Errorf("dial l2 client %v: %w", cfg.CannonL2, err) + } + l2Client = l2 + closer = l2Client.Close + } + syncValidator := newSyncStatusValidator(rollupClient) + if cfg.TraceTypeEnabled(config.TraceTypeCannon) { - resourceCreator := func(addr common.Address, gameDepth uint64, dir string) (faultTypes.TraceProvider, faultTypes.OracleUpdater, error) { - provider, err := cannon.NewTraceProvider(ctx, logger, m, cfg, client, dir, addr, gameDepth) - if err != nil { - return nil, nil, fmt.Errorf("create cannon trace provider: %w", err) - } - updater, err := cannon.NewOracleUpdater(ctx, logger, txMgr, addr, client) - if err != nil { - return nil, nil, fmt.Errorf("failed to create the cannon updater: %w", err) - } - return provider, updater, nil + if err := registerCannon(faultTypes.CannonGameType, registry, oracles, ctx, cl, logger, m, cfg, syncValidator, rollupClient, txSender, gameFactory, caller, l2Client, l1HeaderSource, selective, claimants); err != nil { + return nil, fmt.Errorf("failed to register cannon game type: %w", err) } - playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { - return NewGamePlayer(ctx, logger, m, cfg, dir, game.Proxy, txMgr, client, resourceCreator) + } + if cfg.TraceTypeEnabled(config.TraceTypePermissioned) { + if err := registerCannon(faultTypes.PermissionedGameType, registry, oracles, ctx, cl, logger, m, cfg, syncValidator, rollupClient, txSender, gameFactory, caller, l2Client, l1HeaderSource, selective, claimants); err != nil { + return nil, fmt.Errorf("failed to register permissioned cannon game type: %w", err) } - registry.RegisterGameType(cannonGameType, playerCreator) } if cfg.TraceTypeEnabled(config.TraceTypeAlphabet) { - resourceCreator := func(addr common.Address, gameDepth uint64, dir string) (faultTypes.TraceProvider, faultTypes.OracleUpdater, error) { - provider := alphabet.NewTraceProvider(cfg.AlphabetTrace, gameDepth) - updater := alphabet.NewOracleUpdater(logger) - return provider, updater, nil + if err := registerAlphabet(registry, oracles, ctx, cl, logger, m, syncValidator, rollupClient, txSender, gameFactory, caller, l1HeaderSource, selective, claimants); err != nil { + return nil, fmt.Errorf("failed to register alphabet game type: %w", err) + } + } + return closer, nil +} + +func registerAlphabet( + registry Registry, + oracles OracleRegistry, + ctx context.Context, + cl faultTypes.ClockReader, + logger log.Logger, + m metrics.Metricer, + syncValidator SyncValidator, + rollupClient RollupClient, + txSender types.TxSender, + gameFactory *contracts.DisputeGameFactoryContract, + caller *batching.MultiCaller, + l1HeaderSource L1HeaderSource, + selective bool, + claimants []common.Address, +) error { + playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { + contract, err := contracts.NewFaultDisputeGameContract(game.Proxy, caller) + if err != nil { + return nil, err + } + oracle, err := contract.GetOracle(ctx) + if err != nil { + return nil, fmt.Errorf("failed to load oracle for game %v: %w", game.Proxy, err) + } + oracles.RegisterOracle(oracle) + prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) + if err != nil { + return nil, err + } + splitDepth, err := contract.GetSplitDepth(ctx) + if err != nil { + return nil, err + } + l1Head, err := loadL1Head(contract, ctx, l1HeaderSource) + if err != nil { + return nil, err + } + prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock) + creator := func(ctx context.Context, logger log.Logger, gameDepth faultTypes.Depth, dir string) (faultTypes.TraceAccessor, error) { + accessor, err := outputs.NewOutputAlphabetTraceAccessor(logger, m, prestateProvider, rollupClient, l1Head, splitDepth, prestateBlock, poststateBlock) + if err != nil { + return nil, err + } + return accessor, nil } - playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { - return NewGamePlayer(ctx, logger, m, cfg, dir, game.Proxy, txMgr, client, resourceCreator) + prestateValidator := NewPrestateValidator("alphabet", contract.GetAbsolutePrestateHash, alphabet.PrestateProvider) + startingValidator := NewPrestateValidator("output root", contract.GetStartingRootHash, prestateProvider) + return NewGamePlayer(ctx, cl, logger, m, dir, game.Proxy, txSender, contract, syncValidator, []Validator{prestateValidator, startingValidator}, creator, l1HeaderSource, selective, claimants) + } + err := registerOracle(ctx, oracles, gameFactory, caller, faultTypes.AlphabetGameType) + if err != nil { + return err + } + registry.RegisterGameType(faultTypes.AlphabetGameType, playerCreator) + + contractCreator := func(game types.GameMetadata) (claims.BondContract, error) { + return contracts.NewFaultDisputeGameContract(game.Proxy, caller) + } + registry.RegisterBondContract(faultTypes.AlphabetGameType, contractCreator) + return nil +} + +func registerOracle(ctx context.Context, oracles OracleRegistry, gameFactory *contracts.DisputeGameFactoryContract, caller *batching.MultiCaller, gameType uint32) error { + implAddr, err := gameFactory.GetGameImpl(ctx, gameType) + if err != nil { + return fmt.Errorf("failed to load implementation for game type %v: %w", gameType, err) + } + contract, err := contracts.NewFaultDisputeGameContract(implAddr, caller) + if err != nil { + return err + } + oracle, err := contract.GetOracle(ctx) + if err != nil { + return fmt.Errorf("failed to load oracle address: %w", err) + } + oracles.RegisterOracle(oracle) + return nil +} + +func registerCannon( + gameType uint32, + registry Registry, + oracles OracleRegistry, + ctx context.Context, + cl faultTypes.ClockReader, + logger log.Logger, + m metrics.Metricer, + cfg *config.Config, + syncValidator SyncValidator, + rollupClient outputs.OutputRollupClient, + txSender types.TxSender, + gameFactory *contracts.DisputeGameFactoryContract, + caller *batching.MultiCaller, + l2Client cannon.L2HeaderSource, + l1HeaderSource L1HeaderSource, + selective bool, + claimants []common.Address, +) error { + cannonPrestateProvider := cannon.NewPrestateProvider(cfg.CannonAbsolutePreState) + playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { + contract, err := contracts.NewFaultDisputeGameContract(game.Proxy, caller) + if err != nil { + return nil, err + } + oracle, err := contract.GetOracle(ctx) + if err != nil { + return nil, fmt.Errorf("failed to load oracle for game %v: %w", game.Proxy, err) + } + oracles.RegisterOracle(oracle) + prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) + if err != nil { + return nil, err + } + splitDepth, err := contract.GetSplitDepth(ctx) + if err != nil { + return nil, fmt.Errorf("failed to load split depth: %w", err) + } + l1HeadID, err := loadL1Head(contract, ctx, l1HeaderSource) + if err != nil { + return nil, err + } + prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock) + creator := func(ctx context.Context, logger log.Logger, gameDepth faultTypes.Depth, dir string) (faultTypes.TraceAccessor, error) { + accessor, err := outputs.NewOutputCannonTraceAccessor(logger, m, cfg, l2Client, prestateProvider, rollupClient, dir, l1HeadID, splitDepth, prestateBlock, poststateBlock) + if err != nil { + return nil, err + } + return accessor, nil } - registry.RegisterGameType(alphabetGameType, playerCreator) + prestateValidator := NewPrestateValidator("cannon", contract.GetAbsolutePrestateHash, cannonPrestateProvider) + startingValidator := NewPrestateValidator("output root", contract.GetStartingRootHash, prestateProvider) + return NewGamePlayer(ctx, cl, logger, m, dir, game.Proxy, txSender, contract, syncValidator, []Validator{prestateValidator, startingValidator}, creator, l1HeaderSource, selective, claimants) + } + err := registerOracle(ctx, oracles, gameFactory, caller, gameType) + if err != nil { + return err + } + registry.RegisterGameType(gameType, playerCreator) + + contractCreator := func(game types.GameMetadata) (claims.BondContract, error) { + return contracts.NewFaultDisputeGameContract(game.Proxy, caller) + } + registry.RegisterBondContract(gameType, contractCreator) + return nil +} + +func loadL1Head(contract *contracts.FaultDisputeGameContract, ctx context.Context, l1HeaderSource L1HeaderSource) (eth.BlockID, error) { + l1Head, err := contract.GetL1Head(ctx) + if err != nil { + return eth.BlockID{}, fmt.Errorf("failed to load L1 head: %w", err) + } + l1Header, err := l1HeaderSource.HeaderByHash(ctx, l1Head) + if err != nil { + return eth.BlockID{}, fmt.Errorf("failed to load L1 header: %w", err) } + return eth.HeaderBlockID(l1Header), nil } diff --git a/op-challenger/game/fault/responder/abi_test.go b/op-challenger/game/fault/responder/abi_test.go deleted file mode 100644 index 1c550e6da3b5..000000000000 --- a/op-challenger/game/fault/responder/abi_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package responder - -import ( - "math/big" - "testing" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/params" - "github.com/stretchr/testify/require" -) - -// setupFaultDisputeGame deploys the FaultDisputeGame contract to a simulated backend -func setupFaultDisputeGame() (common.Address, *bind.TransactOpts, *backends.SimulatedBackend, *bindings.FaultDisputeGame, error) { - privateKey, err := crypto.GenerateKey() - from := crypto.PubkeyToAddress(privateKey.PublicKey) - if err != nil { - return common.Address{}, nil, nil, nil, err - } - opts, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1337)) - if err != nil { - return common.Address{}, nil, nil, nil, err - } - backend := backends.NewSimulatedBackend( - core.GenesisAlloc{from: {Balance: big.NewInt(params.Ether)}}, - 50_000_000, - ) - - blockHashOracle, _, _, err := bindings.DeployBlockOracle(opts, backend) - if err != nil { - return common.Address{}, nil, nil, nil, err - } - - _, _, contract, err := bindings.DeployFaultDisputeGame( - opts, - backend, - uint8(0), // Game Type ID - [32]byte{0x01}, // Absolute Prestate Claim - big.NewInt(15), // Max Game Depth - uint64(604800), // 7 days - common.Address{0xdd}, // VM - common.Address{0xee}, // L2OutputOracle (Not used in Alphabet Game) - blockHashOracle, // Block hash oracle - ) - if err != nil { - return common.Address{}, nil, nil, nil, err - } - return from, opts, backend, contract, nil -} - -// TestBuildFaultDefendData ensures that the manual ABI packing is the same as going through the bound contract. -func TestBuildFaultDefendData(t *testing.T) { - _, opts, _, contract, err := setupFaultDisputeGame() - require.NoError(t, err) - - resp, _ := newTestFaultResponder(t) - - data, err := resp.buildFaultDefendData(1, [32]byte{0x02, 0x03}) - require.NoError(t, err) - - opts.GasLimit = 100_000 - tx, err := contract.Defend(opts, big.NewInt(1), [32]byte{0x02, 0x03}) - require.NoError(t, err) - - require.Equal(t, data, tx.Data()) -} - -// TestBuildFaultAttackData ensures that the manual ABI packing is the same as going through the bound contract. -func TestBuildFaultAttackData(t *testing.T) { - _, opts, _, contract, err := setupFaultDisputeGame() - require.NoError(t, err) - - resp, _ := newTestFaultResponder(t) - - data, err := resp.buildFaultAttackData(1, [32]byte{0x02, 0x03}) - require.NoError(t, err) - - opts.GasLimit = 100_000 - tx, err := contract.Attack(opts, big.NewInt(1), [32]byte{0x02, 0x03}) - require.NoError(t, err) - - require.Equal(t, data, tx.Data()) -} - -// TestBuildFaultStepData ensures that the manual ABI packing is the same as going through the bound contract. -func TestBuildFaultStepData(t *testing.T) { - _, opts, _, contract, err := setupFaultDisputeGame() - require.NoError(t, err) - - resp, _ := newTestFaultResponder(t) - - data, err := resp.buildStepTxData(2, false, []byte{0x01}, []byte{0x02}) - require.NoError(t, err) - - opts.GasLimit = 100_000 - tx, err := contract.Step(opts, big.NewInt(2), false, []byte{0x01}, []byte{0x02}) - require.NoError(t, err) - - require.Equal(t, data, tx.Data()) -} diff --git a/op-challenger/game/fault/responder/responder.go b/op-challenger/game/fault/responder/responder.go index 07350b3e22c4..fbeddc5b622c 100644 --- a/op-challenger/game/fault/responder/responder.go +++ b/op-challenger/game/fault/responder/responder.go @@ -2,171 +2,136 @@ package responder import ( "context" + "errors" + "fmt" "math/big" - "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/preimages" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/txmgr" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" ) -// FaultResponder implements the [Responder] interface to send onchain transactions. -type FaultResponder struct { - log log.Logger +type GameContract interface { + CallResolve(ctx context.Context) (gameTypes.GameStatus, error) + ResolveTx() (txmgr.TxCandidate, error) + CallResolveClaim(ctx context.Context, claimIdx uint64) error + ResolveClaimTx(claimIdx uint64) (txmgr.TxCandidate, error) + AttackTx(parentContractIndex uint64, pivot common.Hash) (txmgr.TxCandidate, error) + DefendTx(parentContractIndex uint64, pivot common.Hash) (txmgr.TxCandidate, error) + StepTx(claimIdx uint64, isAttack bool, stateData []byte, proof []byte) (txmgr.TxCandidate, error) + GetRequiredBond(ctx context.Context, position types.Position) (*big.Int, error) +} - txMgr txmgr.TxManager +type Oracle interface { + GlobalDataExists(ctx context.Context, data *types.PreimageOracleData) (bool, error) +} - fdgAddr common.Address - fdgAbi *abi.ABI +// FaultResponder implements the [Responder] interface to send onchain transactions. +type FaultResponder struct { + log log.Logger + sender gameTypes.TxSender + contract GameContract + uploader preimages.PreimageUploader + oracle Oracle } // NewFaultResponder returns a new [FaultResponder]. -func NewFaultResponder(logger log.Logger, txManagr txmgr.TxManager, fdgAddr common.Address) (*FaultResponder, error) { - fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() - if err != nil { - return nil, err - } +func NewFaultResponder(logger log.Logger, sender gameTypes.TxSender, contract GameContract, uploader preimages.PreimageUploader, oracle Oracle) (*FaultResponder, error) { return &FaultResponder{ - log: logger, - txMgr: txManagr, - fdgAddr: fdgAddr, - fdgAbi: fdgAbi, + log: logger, + sender: sender, + contract: contract, + uploader: uploader, + oracle: oracle, }, nil } -// buildFaultDefendData creates the transaction data for the Defend function. -func (r *FaultResponder) buildFaultDefendData(parentContractIndex int, pivot [32]byte) ([]byte, error) { - return r.fdgAbi.Pack( - "defend", - big.NewInt(int64(parentContractIndex)), - pivot, - ) -} - -// buildFaultAttackData creates the transaction data for the Attack function. -func (r *FaultResponder) buildFaultAttackData(parentContractIndex int, pivot [32]byte) ([]byte, error) { - return r.fdgAbi.Pack( - "attack", - big.NewInt(int64(parentContractIndex)), - pivot, - ) -} - -// buildResolveData creates the transaction data for the Resolve function. -func (r *FaultResponder) buildResolveData() ([]byte, error) { - return r.fdgAbi.Pack("resolve") -} - // CallResolve determines if the resolve function on the fault dispute game contract // would succeed. Returns the game status if the call would succeed, errors otherwise. func (r *FaultResponder) CallResolve(ctx context.Context) (gameTypes.GameStatus, error) { - txData, err := r.buildResolveData() - if err != nil { - return gameTypes.GameStatusInProgress, err - } - res, err := r.txMgr.Call(ctx, ethereum.CallMsg{ - To: &r.fdgAddr, - Data: txData, - }, nil) - if err != nil { - return gameTypes.GameStatusInProgress, err - } - var status uint8 - if err = r.fdgAbi.UnpackIntoInterface(&status, "resolve", res); err != nil { - return gameTypes.GameStatusInProgress, err - } - return gameTypes.GameStatusFromUint8(status) + return r.contract.CallResolve(ctx) } // Resolve executes a resolve transaction to resolve a fault dispute game. -func (r *FaultResponder) Resolve(ctx context.Context) error { - txData, err := r.buildResolveData() +func (r *FaultResponder) Resolve() error { + candidate, err := r.contract.ResolveTx() if err != nil { return err } - return r.sendTxAndWait(ctx, txData) -} - -// buildResolveClaimData creates the transaction data for the ResolveClaim function. -func (r *FaultResponder) buildResolveClaimData(claimIdx uint64) ([]byte, error) { - return r.fdgAbi.Pack("resolveClaim", big.NewInt(int64(claimIdx))) + return r.sendTxAndWait("resolve game", candidate) } // CallResolveClaim determines if the resolveClaim function on the fault dispute game contract // would succeed. func (r *FaultResponder) CallResolveClaim(ctx context.Context, claimIdx uint64) error { - txData, err := r.buildResolveClaimData(claimIdx) - if err != nil { - return err - } - _, err = r.txMgr.Call(ctx, ethereum.CallMsg{ - To: &r.fdgAddr, - Data: txData, - }, nil) - return err + return r.contract.CallResolveClaim(ctx, claimIdx) } // ResolveClaim executes a resolveClaim transaction to resolve a fault dispute game. -func (r *FaultResponder) ResolveClaim(ctx context.Context, claimIdx uint64) error { - txData, err := r.buildResolveClaimData(claimIdx) +func (r *FaultResponder) ResolveClaim(claimIdx uint64) error { + candidate, err := r.contract.ResolveClaimTx(claimIdx) if err != nil { return err } - return r.sendTxAndWait(ctx, txData) + return r.sendTxAndWait("resolve claim", candidate) } func (r *FaultResponder) PerformAction(ctx context.Context, action types.Action) error { - var txData []byte + if action.OracleData != nil { + var preimageExists bool + var err error + if !action.OracleData.IsLocal { + preimageExists, err = r.oracle.GlobalDataExists(ctx, action.OracleData) + if err != nil { + return fmt.Errorf("failed to check if preimage exists: %w", err) + } + } + // Always upload local preimages + if !preimageExists { + err := r.uploader.UploadPreimage(ctx, uint64(action.ParentIdx), action.OracleData) + if errors.Is(err, preimages.ErrChallengePeriodNotOver) { + r.log.Debug("Large Preimage Squeeze failed, challenge period not over") + return nil + } else if err != nil { + return fmt.Errorf("failed to upload preimage: %w", err) + } + } + } + var candidate txmgr.TxCandidate var err error switch action.Type { case types.ActionTypeMove: + var movePos types.Position if action.IsAttack { - txData, err = r.buildFaultAttackData(action.ParentIdx, action.Value) + movePos = action.ParentPosition.Attack() + candidate, err = r.contract.AttackTx(uint64(action.ParentIdx), action.Value) } else { - txData, err = r.buildFaultDefendData(action.ParentIdx, action.Value) + movePos = action.ParentPosition.Defend() + candidate, err = r.contract.DefendTx(uint64(action.ParentIdx), action.Value) } + + bondValue, err := r.contract.GetRequiredBond(ctx, movePos) + if err != nil { + return err + } + candidate.Value = bondValue case types.ActionTypeStep: - txData, err = r.buildStepTxData(uint64(action.ParentIdx), action.IsAttack, action.PreState, action.ProofData) + candidate, err = r.contract.StepTx(uint64(action.ParentIdx), action.IsAttack, action.PreState, action.ProofData) } if err != nil { return err } - return r.sendTxAndWait(ctx, txData) + return r.sendTxAndWait("perform action", candidate) } // sendTxAndWait sends a transaction through the [txmgr] and waits for a receipt. // This sets the tx GasLimit to 0, performing gas estimation online through the [txmgr]. -func (r *FaultResponder) sendTxAndWait(ctx context.Context, txData []byte) error { - receipt, err := r.txMgr.Send(ctx, txmgr.TxCandidate{ - To: &r.fdgAddr, - TxData: txData, - GasLimit: 0, - }) - if err != nil { - return err - } - if receipt.Status == ethtypes.ReceiptStatusFailed { - r.log.Error("Responder tx successfully published but reverted", "tx_hash", receipt.TxHash) - } else { - r.log.Debug("Responder tx successfully published", "tx_hash", receipt.TxHash) - } - return nil -} - -// buildStepTxData creates the transaction data for the step function. -func (r *FaultResponder) buildStepTxData(claimIdx uint64, isAttack bool, stateData []byte, proof []byte) ([]byte, error) { - return r.fdgAbi.Pack( - "step", - big.NewInt(int64(claimIdx)), - isAttack, - stateData, - proof, - ) +func (r *FaultResponder) sendTxAndWait(purpose string, candidate txmgr.TxCandidate) error { + _, err := r.sender.SendAndWait(purpose, candidate) + return err } diff --git a/op-challenger/game/fault/responder/responder_test.go b/op-challenger/game/fault/responder/responder_test.go index facb1ad2d33a..a2be0bab9ad3 100644 --- a/op-challenger/game/fault/responder/responder_test.go +++ b/op-challenger/game/fault/responder/responder_test.go @@ -6,13 +6,11 @@ import ( "math/big" "testing" - "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/txmgr" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" @@ -21,53 +19,45 @@ import ( ) var ( - mockFdgAddress = common.HexToAddress("0x1234") - mockSendError = errors.New("mock send error") - mockCallError = errors.New("mock call error") + mockPreimageUploadErr = errors.New("mock preimage upload error") + mockSendError = errors.New("mock send error") + mockCallError = errors.New("mock call error") + mockOracleExistsError = errors.New("mock oracle exists error") ) // TestCallResolve tests the [Responder.CallResolve]. func TestCallResolve(t *testing.T) { t.Run("SendFails", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) - mockTxMgr.callFails = true + responder, _, contract, _, _ := newTestFaultResponder(t) + contract.callFails = true status, err := responder.CallResolve(context.Background()) require.ErrorIs(t, err, mockCallError) require.Equal(t, gameTypes.GameStatusInProgress, status) - require.Equal(t, 0, mockTxMgr.calls) - }) - - t.Run("UnpackFails", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) - mockTxMgr.callBytes = []byte{0x00, 0x01} - status, err := responder.CallResolve(context.Background()) - require.Error(t, err) - require.Equal(t, gameTypes.GameStatusInProgress, status) - require.Equal(t, 1, mockTxMgr.calls) + require.Equal(t, 0, contract.calls) }) t.Run("Success", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) + responder, _, contract, _, _ := newTestFaultResponder(t) status, err := responder.CallResolve(context.Background()) require.NoError(t, err) require.Equal(t, gameTypes.GameStatusInProgress, status) - require.Equal(t, 1, mockTxMgr.calls) + require.Equal(t, 1, contract.calls) }) } // TestResolve tests the [Responder.Resolve] method. func TestResolve(t *testing.T) { t.Run("SendFails", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) + responder, mockTxMgr, _, _, _ := newTestFaultResponder(t) mockTxMgr.sendFails = true - err := responder.Resolve(context.Background()) + err := responder.Resolve() require.ErrorIs(t, err, mockSendError) require.Equal(t, 0, mockTxMgr.sends) }) t.Run("Success", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) - err := responder.Resolve(context.Background()) + responder, mockTxMgr, _, _, _ := newTestFaultResponder(t) + err := responder.Resolve() require.NoError(t, err) require.Equal(t, 1, mockTxMgr.sends) }) @@ -75,33 +65,33 @@ func TestResolve(t *testing.T) { func TestCallResolveClaim(t *testing.T) { t.Run("SendFails", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) - mockTxMgr.callFails = true + responder, _, contract, _, _ := newTestFaultResponder(t) + contract.callFails = true err := responder.CallResolveClaim(context.Background(), 0) require.ErrorIs(t, err, mockCallError) - require.Equal(t, 0, mockTxMgr.calls) + require.Equal(t, 0, contract.calls) }) t.Run("Success", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) + responder, _, contract, _, _ := newTestFaultResponder(t) err := responder.CallResolveClaim(context.Background(), 0) require.NoError(t, err) - require.Equal(t, 1, mockTxMgr.calls) + require.Equal(t, 1, contract.calls) }) } func TestResolveClaim(t *testing.T) { t.Run("SendFails", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) + responder, mockTxMgr, _, _, _ := newTestFaultResponder(t) mockTxMgr.sendFails = true - err := responder.ResolveClaim(context.Background(), 0) + err := responder.ResolveClaim(0) require.ErrorIs(t, err, mockSendError) require.Equal(t, 0, mockTxMgr.sends) }) t.Run("Success", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) - err := responder.ResolveClaim(context.Background(), 0) + responder, mockTxMgr, _, _, _ := newTestFaultResponder(t) + err := responder.ResolveClaim(0) require.NoError(t, err) require.Equal(t, 1, mockTxMgr.sends) }) @@ -110,7 +100,7 @@ func TestResolveClaim(t *testing.T) { // TestRespond tests the [Responder.Respond] method. func TestPerformAction(t *testing.T) { t.Run("send fails", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) + responder, mockTxMgr, _, _, _ := newTestFaultResponder(t) mockTxMgr.sendFails = true err := responder.PerformAction(context.Background(), types.Action{ Type: types.ActionTypeMove, @@ -123,7 +113,7 @@ func TestPerformAction(t *testing.T) { }) t.Run("sends response", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) + responder, mockTxMgr, _, _, _ := newTestFaultResponder(t) err := responder.PerformAction(context.Background(), types.Action{ Type: types.ActionTypeMove, ParentIdx: 123, @@ -135,7 +125,7 @@ func TestPerformAction(t *testing.T) { }) t.Run("attack", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) + responder, mockTxMgr, contract, _, _ := newTestFaultResponder(t) action := types.Action{ Type: types.ActionTypeMove, ParentIdx: 123, @@ -145,18 +135,13 @@ func TestPerformAction(t *testing.T) { err := responder.PerformAction(context.Background(), action) require.NoError(t, err) - // Pack the tx data manually. - fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() - require.NoError(t, err) - expected, err := fdgAbi.Pack("attack", big.NewInt(int64(action.ParentIdx)), action.Value) - require.NoError(t, err) - require.Len(t, mockTxMgr.sent, 1) - require.Equal(t, expected, mockTxMgr.sent[0].TxData) + require.EqualValues(t, []interface{}{uint64(action.ParentIdx), action.Value}, contract.attackArgs) + require.Equal(t, ([]byte)("attack"), mockTxMgr.sent[0].TxData) }) t.Run("defend", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) + responder, mockTxMgr, contract, _, _ := newTestFaultResponder(t) action := types.Action{ Type: types.ActionTypeMove, ParentIdx: 123, @@ -166,18 +151,13 @@ func TestPerformAction(t *testing.T) { err := responder.PerformAction(context.Background(), action) require.NoError(t, err) - // Pack the tx data manually. - fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() - require.NoError(t, err) - expected, err := fdgAbi.Pack("defend", big.NewInt(int64(action.ParentIdx)), action.Value) - require.NoError(t, err) - require.Len(t, mockTxMgr.sent, 1) - require.Equal(t, expected, mockTxMgr.sent[0].TxData) + require.EqualValues(t, []interface{}{uint64(action.ParentIdx), action.Value}, contract.defendArgs) + require.Equal(t, ([]byte)("defend"), mockTxMgr.sent[0].TxData) }) t.Run("step", func(t *testing.T) { - responder, mockTxMgr := newTestFaultResponder(t) + responder, mockTxMgr, contract, _, _ := newTestFaultResponder(t) action := types.Action{ Type: types.ActionTypeStep, ParentIdx: 123, @@ -188,65 +168,254 @@ func TestPerformAction(t *testing.T) { err := responder.PerformAction(context.Background(), action) require.NoError(t, err) - // Pack the tx data manually. - fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() + require.Len(t, mockTxMgr.sent, 1) + require.EqualValues(t, []interface{}{uint64(action.ParentIdx), action.IsAttack, action.PreState, action.ProofData}, contract.stepArgs) + require.Equal(t, ([]byte)("step"), mockTxMgr.sent[0].TxData) + }) + + t.Run("stepWithLocalOracleData", func(t *testing.T) { + responder, mockTxMgr, contract, uploader, oracle := newTestFaultResponder(t) + action := types.Action{ + Type: types.ActionTypeStep, + ParentIdx: 123, + IsAttack: true, + PreState: []byte{1, 2, 3}, + ProofData: []byte{4, 5, 6}, + OracleData: &types.PreimageOracleData{ + IsLocal: true, + }, + } + err := responder.PerformAction(context.Background(), action) require.NoError(t, err) - expected, err := fdgAbi.Pack("step", big.NewInt(int64(action.ParentIdx)), true, action.PreState, action.ProofData) + + require.Len(t, mockTxMgr.sent, 1) + require.Nil(t, contract.updateOracleArgs) // mock uploader returns nil + require.Equal(t, ([]byte)("step"), mockTxMgr.sent[0].TxData) + require.Equal(t, 1, uploader.updates) + require.Equal(t, 0, oracle.existCalls) + }) + + t.Run("stepWithGlobalOracleData", func(t *testing.T) { + responder, mockTxMgr, contract, uploader, oracle := newTestFaultResponder(t) + action := types.Action{ + Type: types.ActionTypeStep, + ParentIdx: 123, + IsAttack: true, + PreState: []byte{1, 2, 3}, + ProofData: []byte{4, 5, 6}, + OracleData: &types.PreimageOracleData{ + IsLocal: false, + }, + } + err := responder.PerformAction(context.Background(), action) require.NoError(t, err) require.Len(t, mockTxMgr.sent, 1) - require.Equal(t, expected, mockTxMgr.sent[0].TxData) + require.Nil(t, contract.updateOracleArgs) // mock uploader returns nil + require.Equal(t, ([]byte)("step"), mockTxMgr.sent[0].TxData) + require.Equal(t, 1, uploader.updates) + require.Equal(t, 1, oracle.existCalls) + }) + + t.Run("stepWithOracleDataAndUploadFails", func(t *testing.T) { + responder, mockTxMgr, contract, uploader, _ := newTestFaultResponder(t) + uploader.uploadFails = true + action := types.Action{ + Type: types.ActionTypeStep, + ParentIdx: 123, + IsAttack: true, + PreState: []byte{1, 2, 3}, + ProofData: []byte{4, 5, 6}, + OracleData: &types.PreimageOracleData{ + IsLocal: true, + }, + } + err := responder.PerformAction(context.Background(), action) + require.ErrorIs(t, err, mockPreimageUploadErr) + require.Len(t, mockTxMgr.sent, 0) + require.Nil(t, contract.updateOracleArgs) // mock uploader returns nil + require.Equal(t, 1, uploader.updates) + }) + + t.Run("stepWithOracleDataAndGlobalPreimageAlreadyExists", func(t *testing.T) { + responder, mockTxMgr, contract, uploader, oracle := newTestFaultResponder(t) + oracle.existsResult = true + action := types.Action{ + Type: types.ActionTypeStep, + ParentIdx: 123, + IsAttack: true, + PreState: []byte{1, 2, 3}, + ProofData: []byte{4, 5, 6}, + OracleData: &types.PreimageOracleData{ + IsLocal: false, + }, + } + err := responder.PerformAction(context.Background(), action) + require.Nil(t, err) + require.Len(t, mockTxMgr.sent, 1) + require.Nil(t, contract.updateOracleArgs) // mock uploader returns nil + require.Equal(t, 0, uploader.updates) + require.Equal(t, 1, oracle.existCalls) + }) + + t.Run("stepWithOracleDataAndGlobalPreimageExistsFails", func(t *testing.T) { + responder, mockTxMgr, contract, uploader, oracle := newTestFaultResponder(t) + oracle.existsFails = true + action := types.Action{ + Type: types.ActionTypeStep, + ParentIdx: 123, + IsAttack: true, + PreState: []byte{1, 2, 3}, + ProofData: []byte{4, 5, 6}, + OracleData: &types.PreimageOracleData{ + IsLocal: false, + }, + } + err := responder.PerformAction(context.Background(), action) + require.ErrorIs(t, err, mockOracleExistsError) + require.Len(t, mockTxMgr.sent, 0) + require.Nil(t, contract.updateOracleArgs) // mock uploader returns nil + require.Equal(t, 0, uploader.updates) + require.Equal(t, 1, oracle.existCalls) }) } -func newTestFaultResponder(t *testing.T) (*FaultResponder, *mockTxManager) { - log := testlog.Logger(t, log.LvlError) +func newTestFaultResponder(t *testing.T) (*FaultResponder, *mockTxManager, *mockContract, *mockPreimageUploader, *mockOracle) { + log := testlog.Logger(t, log.LevelError) mockTxMgr := &mockTxManager{} - responder, err := NewFaultResponder(log, mockTxMgr, mockFdgAddress) + contract := &mockContract{} + uploader := &mockPreimageUploader{} + oracle := &mockOracle{} + responder, err := NewFaultResponder(log, mockTxMgr, contract, uploader, oracle) require.NoError(t, err) - return responder, mockTxMgr + return responder, mockTxMgr, contract, uploader, oracle +} + +type mockPreimageUploader struct { + updates int + uploadFails bool +} + +func (m *mockPreimageUploader) UploadPreimage(ctx context.Context, parent uint64, data *types.PreimageOracleData) error { + m.updates++ + if m.uploadFails { + return mockPreimageUploadErr + } + return nil +} + +type mockOracle struct { + existCalls int + existsResult bool + existsFails bool +} + +func (m *mockOracle) GlobalDataExists(ctx context.Context, data *types.PreimageOracleData) (bool, error) { + m.existCalls++ + if m.existsFails { + return false, mockOracleExistsError + } + return m.existsResult, nil } type mockTxManager struct { from common.Address sends int sent []txmgr.TxCandidate - calls int sendFails bool - callFails bool - callBytes []byte } -func (m *mockTxManager) Send(ctx context.Context, candidate txmgr.TxCandidate) (*ethtypes.Receipt, error) { - if m.sendFails { - return nil, mockSendError +func (m *mockTxManager) SendAndWait(_ string, txs ...txmgr.TxCandidate) ([]*ethtypes.Receipt, error) { + rcpts := make([]*ethtypes.Receipt, 0, len(txs)) + for _, tx := range txs { + if m.sendFails { + return nil, mockSendError + } + m.sends++ + m.sent = append(m.sent, tx) + rcpts = append(rcpts, ethtypes.NewReceipt( + []byte{}, + false, + 0, + )) } - m.sends++ - m.sent = append(m.sent, candidate) - return ethtypes.NewReceipt( - []byte{}, - false, - 0, - ), nil + return rcpts, nil } -func (m *mockTxManager) Call(_ context.Context, _ ethereum.CallMsg, _ *big.Int) ([]byte, error) { +func (m *mockTxManager) BlockNumber(_ context.Context) (uint64, error) { + panic("not implemented") +} + +func (m *mockTxManager) From() common.Address { + return m.from +} + +func (m *mockTxManager) Close() { +} + +type mockContract struct { + calls int + callFails bool + attackArgs []interface{} + defendArgs []interface{} + stepArgs []interface{} + updateOracleClaimIdx uint64 + updateOracleArgs *types.PreimageOracleData +} + +func (m *mockContract) CallResolve(_ context.Context) (gameTypes.GameStatus, error) { if m.callFails { - return nil, mockCallError + return gameTypes.GameStatusInProgress, mockCallError } m.calls++ - if m.callBytes != nil { - return m.callBytes, nil + return gameTypes.GameStatusInProgress, nil +} + +func (m *mockContract) ResolveTx() (txmgr.TxCandidate, error) { + return txmgr.TxCandidate{}, nil +} + +func (m *mockContract) CallResolveClaim(_ context.Context, _ uint64) error { + if m.callFails { + return mockCallError } - return common.Hex2Bytes( - "0000000000000000000000000000000000000000000000000000000000000000", - ), nil + m.calls++ + return nil } -func (m *mockTxManager) BlockNumber(ctx context.Context) (uint64, error) { - panic("not implemented") +func (m *mockContract) ResolveClaimTx(_ uint64) (txmgr.TxCandidate, error) { + return txmgr.TxCandidate{}, nil } -func (m *mockTxManager) From() common.Address { - return m.from +func (m *mockContract) AttackTx(parentClaimId uint64, claim common.Hash) (txmgr.TxCandidate, error) { + m.attackArgs = []interface{}{parentClaimId, claim} + return txmgr.TxCandidate{TxData: ([]byte)("attack")}, nil +} + +func (m *mockContract) DefendTx(parentClaimId uint64, claim common.Hash) (txmgr.TxCandidate, error) { + m.defendArgs = []interface{}{parentClaimId, claim} + return txmgr.TxCandidate{TxData: ([]byte)("defend")}, nil +} + +func (m *mockContract) StepTx(claimIdx uint64, isAttack bool, stateData []byte, proofData []byte) (txmgr.TxCandidate, error) { + m.stepArgs = []interface{}{claimIdx, isAttack, stateData, proofData} + return txmgr.TxCandidate{TxData: ([]byte)("step")}, nil +} + +func (m *mockContract) UpdateOracleTx(_ context.Context, claimIdx uint64, data *types.PreimageOracleData) (txmgr.TxCandidate, error) { + m.updateOracleClaimIdx = claimIdx + m.updateOracleArgs = data + return txmgr.TxCandidate{TxData: ([]byte)("updateOracle")}, nil +} + +func (m *mockContract) GetRequiredBond(_ context.Context, position types.Position) (*big.Int, error) { + return big.NewInt(5), nil +} + +func (m *mockContract) GetCredit(_ context.Context, _ common.Address) (*big.Int, error) { + return big.NewInt(5), nil +} + +func (m *mockContract) ClaimCredit(_ common.Address) (txmgr.TxCandidate, error) { + return txmgr.TxCandidate{TxData: ([]byte)("claimCredit")}, nil } diff --git a/op-challenger/game/fault/solver/actors.go b/op-challenger/game/fault/solver/actors.go new file mode 100644 index 000000000000..309569ea6213 --- /dev/null +++ b/op-challenger/game/fault/solver/actors.go @@ -0,0 +1,136 @@ +package solver + +import ( + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" +) + +type actor interface { + Apply(t *testing.T, game types.Game, correctTrace types.TraceProvider) (types.Game, bool) +} + +type actorFn func(t *testing.T, game types.Game, correctTrace types.TraceProvider) (types.Game, bool) + +func (a actorFn) Apply(t *testing.T, game types.Game, correctTrace types.TraceProvider) (types.Game, bool) { + return a(t, game, correctTrace) +} + +type builderFn func(builder *test.GameBuilder) bool + +func (a builderFn) Apply(t *testing.T, game types.Game, correctTrace types.TraceProvider) (types.Game, bool) { + builder := test.NewGameBuilderFromGame(t, correctTrace, game) + done := a(builder) + return builder.Game, done +} + +func combineActors(actors ...actor) actor { + return actorFn(func(t *testing.T, game types.Game, correctTrace types.TraceProvider) (types.Game, bool) { + done := true + for _, actor := range actors { + newGame, actorDone := actor.Apply(t, game, correctTrace) + game = newGame + done = done && actorDone + } + return game, done + }) +} + +var doNothingActor builderFn = func(builder *test.GameBuilder) bool { + return true +} + +var correctAttackLastClaim = respondLastClaim(func(seq *test.GameBuilderSeq) { + seq.Attack() +}) + +var correctDefendLastClaim = respondLastClaim(func(seq *test.GameBuilderSeq) { + if seq.IsRoot() { + // Must attack the root + seq.Attack() + } else { + seq.Defend() + } +}) + +var incorrectAttackLastClaim = respondLastClaim(func(seq *test.GameBuilderSeq) { + seq.Attack(test.WithValue(common.Hash{0xaa})) +}) + +var incorrectDefendLastClaim = respondLastClaim(func(seq *test.GameBuilderSeq) { + if seq.IsRoot() { + // Must attack the root + seq.Attack(test.WithValue(common.Hash{0xdd})) + } else { + seq.Defend(test.WithValue(common.Hash{0xdd})) + } +}) + +var attackEverythingCorrect = respondAllClaims(func(seq *test.GameBuilderSeq) { + seq.Attack() +}) + +var defendEverythingCorrect = respondAllClaims(func(seq *test.GameBuilderSeq) { + if seq.IsRoot() { + // Must attack root + seq.Attack() + } else { + seq.Defend() + } +}) + +var attackEverythingIncorrect = respondAllClaims(func(seq *test.GameBuilderSeq) { + seq.Attack(test.WithValue(common.Hash{0xaa})) +}) + +var defendEverythingIncorrect = respondAllClaims(func(seq *test.GameBuilderSeq) { + if seq.IsRoot() { + // Must attack root + seq.Attack(test.WithValue(common.Hash{0xbb})) + } else { + seq.Defend(test.WithValue(common.Hash{0xbb})) + } +}) + +var exhaustive = respondAllClaims(func(seq *test.GameBuilderSeq) { + seq.Attack() + seq.Attack(test.WithValue(common.Hash{0xaa})) + if !seq.IsRoot() { + seq.Defend() + seq.Defend(test.WithValue(common.Hash{0xdd})) + } +}) + +func respondLastClaim(respond func(seq *test.GameBuilderSeq)) builderFn { + return func(builder *test.GameBuilder) bool { + seq := seqFromLastClaim(builder) + if seq.IsMaxDepth() { + // Can't counter the leaf claim + return true + } + respond(seq) + return false + } +} + +func respondAllClaims(respond func(seq *test.GameBuilderSeq)) builderFn { + return func(builder *test.GameBuilder) bool { + startingCount := len(builder.Game.Claims()) + for _, claim := range builder.Game.Claims() { + if claim.Depth() == builder.Game.MaxDepth() { + continue + } + respond(builder.SeqFrom(claim)) + } + finalCount := len(builder.Game.Claims()) + return finalCount == startingCount + } +} + +func seqFromLastClaim(builder *test.GameBuilder) *test.GameBuilderSeq { + claims := builder.Game.Claims() + claim := claims[len(claims)-1] + return builder.SeqFrom(claim) +} diff --git a/op-challenger/game/fault/solver/game_rules_test.go b/op-challenger/game/fault/solver/game_rules_test.go new file mode 100644 index 000000000000..44eb998ef3c6 --- /dev/null +++ b/op-challenger/game/fault/solver/game_rules_test.go @@ -0,0 +1,91 @@ +package solver + +import ( + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/resolution" + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/transform" + disputeTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func verifyGameRules(t *testing.T, game types.Game, rootClaimCorrect bool) { + actualResult, claimTree, resolvedGame := gameResult(game) + + verifyExpectedGameResult(t, rootClaimCorrect, actualResult) + + verifyNoChallengerClaimsWereSuccessfullyCountered(t, resolvedGame) + verifyChallengerAlwaysWinsParentBond(t, resolvedGame) + verifyChallengerNeverCountersAClaimTwice(t, claimTree) +} + +// verifyExpectedGameResult verifies that valid output roots are successfully defended and invalid roots are challenged +// Rationale: Ensures the game always and only allows valid output roots to be finalized. +func verifyExpectedGameResult(t *testing.T, rootClaimCorrect bool, actualResult gameTypes.GameStatus) { + expectedResult := gameTypes.GameStatusChallengerWon + if rootClaimCorrect { + expectedResult = gameTypes.GameStatusDefenderWon + } + require.Equalf(t, expectedResult, actualResult, "Game should resolve correctly expected %v but was %v", expectedResult, actualResult) +} + +// verifyNoChallengerClaimsWereSuccessfullyCountered verifies the challenger didn't lose any of its bonds +// Note that this also forbids the challenger losing a bond to itself since it shouldn't challenge its own claims +// Rationale: If honest actors lose their bond, it indicates that incentive compatibility is broken because honest actors +// lose money. +func verifyNoChallengerClaimsWereSuccessfullyCountered(t *testing.T, resolvedGame types.Game) { + for _, claim := range resolvedGame.Claims() { + if claim.Claimant != challengerAddr { + continue + } + if claim.CounteredBy != (common.Address{}) { + t.Fatalf("Challenger posted claim %v but it was countered by someone else:\n%v", claim.ContractIndex, printClaim(claim, resolvedGame)) + } + } +} + +// verifyChallengerAlwaysWinsParentBond verifies that the challenger is always allocated the bond of any parent claim it +// counters. +// Rationale: If an honest action does not win the bond for countering a claim, incentive compatibility is broken because +// honest actors are not being paid to perform their job (or the challenger is posting unnecessary claims) +func verifyChallengerAlwaysWinsParentBond(t *testing.T, resolvedGame types.Game) { + for _, claim := range resolvedGame.Claims() { + if claim.Claimant != challengerAddr { + continue + } + parent, err := resolvedGame.GetParent(claim) + require.NoErrorf(t, err, "Failed to get parent of claim %v", claim.ContractIndex) + require.Equal(t, challengerAddr, parent.CounteredBy, + "Expected claim %v to have challenger as its claimant because of counter claim %v", parent.ContractIndex, claim.ContractIndex) + } +} + +// verifyChallengerNeverCountersAClaimTwice verifies that the challenger never posts more than one counter to a claim +// Rationale: The parent claim bond is only intended to cover costs of a single counter claim so incentive compatibility +// is broken if the challenger needs to post multiple claims. Or if the claim wasn't required, the challenger is just +// wasting money posting unnecessary claims. +func verifyChallengerNeverCountersAClaimTwice(t *testing.T, tree *disputeTypes.BidirectionalTree) { + for _, claim := range tree.Claims { + challengerCounterCount := 0 + for _, child := range claim.Children { + if child.Claim.Claimant != challengerAddr { + continue + } + challengerCounterCount++ + } + require.LessOrEqualf(t, challengerCounterCount, 1, "Found multiple honest counters to claim %v", claim.Claim.ContractIndex) + } +} + +func gameResult(game types.Game) (gameTypes.GameStatus, *disputeTypes.BidirectionalTree, types.Game) { + tree := transform.CreateBidirectionalTree(game.Claims()) + result := resolution.Resolve(tree) + resolvedClaims := make([]types.Claim, 0, len(tree.Claims)) + for _, claim := range tree.Claims { + resolvedClaims = append(resolvedClaims, *claim.Claim) + } + return result, tree, types.NewGameState(resolvedClaims, game.MaxDepth()) +} diff --git a/op-challenger/game/fault/solver/game_solver.go b/op-challenger/game/fault/solver/game_solver.go index e957bcb48f96..7c10d005c2e3 100644 --- a/op-challenger/game/fault/solver/game_solver.go +++ b/op-challenger/game/fault/solver/game_solver.go @@ -2,84 +2,96 @@ package solver import ( "context" - "errors" "fmt" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" ) type GameSolver struct { claimSolver *claimSolver } -func NewGameSolver(gameDepth int, trace types.TraceProvider) *GameSolver { +func NewGameSolver(gameDepth types.Depth, trace types.TraceAccessor) *GameSolver { return &GameSolver{ claimSolver: newClaimSolver(gameDepth, trace), } } +func (s *GameSolver) AgreeWithRootClaim(ctx context.Context, game types.Game) (bool, error) { + return s.claimSolver.agreeWithClaim(ctx, game, game.Claims()[0]) +} + func (s *GameSolver) CalculateNextActions(ctx context.Context, game types.Game) ([]types.Action, error) { - var errs []error + agreeWithRootClaim, err := s.AgreeWithRootClaim(ctx, game) + if err != nil { + return nil, fmt.Errorf("failed to determine if root claim is correct: %w", err) + } var actions []types.Action + agreedClaims := newHonestClaimTracker() + if agreeWithRootClaim { + agreedClaims.AddHonestClaim(types.Claim{}, game.Claims()[0]) + } for _, claim := range game.Claims() { var action *types.Action - var err error - if uint64(claim.Depth()) == game.MaxDepth() { - action, err = s.calculateStep(ctx, game, claim) + if claim.Depth() == game.MaxDepth() { + action, err = s.calculateStep(ctx, game, claim, agreedClaims) } else { - action, err = s.calculateMove(ctx, game, claim) + action, err = s.calculateMove(ctx, game, claim, agreedClaims) } if err != nil { - errs = append(errs, err) - continue + // Unable to continue iterating claims safely because we may not have tracked the required honest moves + // for this claim which affects the response to later claims. + // Any actions we've already identified are still safe to apply. + return actions, fmt.Errorf("failed to determine response to claim %v: %w", claim.ContractIndex, err) } if action == nil { continue } actions = append(actions, *action) } - return actions, errors.Join(errs...) + return actions, nil } -func (s *GameSolver) calculateStep(ctx context.Context, game types.Game, claim types.Claim) (*types.Action, error) { - if claim.Countered { - return nil, nil - } - if game.AgreeWithClaimLevel(claim) { - return nil, nil - } - step, err := s.claimSolver.AttemptStep(ctx, game, claim) - if errors.Is(err, ErrStepIgnoreInvalidPath) { +func (s *GameSolver) calculateStep(ctx context.Context, game types.Game, claim types.Claim, agreedClaims *honestClaimTracker) (*types.Action, error) { + if claim.CounteredBy != (common.Address{}) { return nil, nil } + step, err := s.claimSolver.AttemptStep(ctx, game, claim, agreedClaims) if err != nil { return nil, err } + if step == nil { + return nil, nil + } return &types.Action{ - Type: types.ActionTypeStep, - ParentIdx: step.LeafClaim.ContractIndex, - IsAttack: step.IsAttack, - PreState: step.PreState, - ProofData: step.ProofData, - OracleData: step.OracleData, + Type: types.ActionTypeStep, + ParentIdx: step.LeafClaim.ContractIndex, + ParentPosition: step.LeafClaim.Position, + IsAttack: step.IsAttack, + PreState: step.PreState, + ProofData: step.ProofData, + OracleData: step.OracleData, }, nil } -func (s *GameSolver) calculateMove(ctx context.Context, game types.Game, claim types.Claim) (*types.Action, error) { - if game.AgreeWithClaimLevel(claim) { - return nil, nil - } - move, err := s.claimSolver.NextMove(ctx, claim, game) +func (s *GameSolver) calculateMove(ctx context.Context, game types.Game, claim types.Claim, honestClaims *honestClaimTracker) (*types.Action, error) { + move, err := s.claimSolver.NextMove(ctx, claim, game, honestClaims) if err != nil { return nil, fmt.Errorf("failed to calculate next move for claim index %v: %w", claim.ContractIndex, err) } - if move == nil || game.IsDuplicate(*move) { + if move == nil { + return nil, nil + } + honestClaims.AddHonestClaim(claim, *move) + if game.IsDuplicate(*move) { return nil, nil } return &types.Action{ - Type: types.ActionTypeMove, - IsAttack: !game.DefendsParent(*move), - ParentIdx: move.ParentContractIndex, - Value: move.Value, + Type: types.ActionTypeMove, + IsAttack: !game.DefendsParent(*move), + ParentIdx: move.ParentContractIndex, + ParentPosition: claim.Position, + Value: move.Value, }, nil } diff --git a/op-challenger/game/fault/solver/game_solver_test.go b/op-challenger/game/fault/solver/game_solver_test.go index c1e6699e53bf..49a808c685db 100644 --- a/op-challenger/game/fault/solver/game_solver_test.go +++ b/op-challenger/game/fault/solver/game_solver_test.go @@ -3,101 +3,173 @@ package solver import ( "context" "encoding/hex" + "fmt" + "math/big" "testing" faulttest "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) func TestCalculateNextActions(t *testing.T) { - maxDepth := 4 - claimBuilder := faulttest.NewAlphabetClaimBuilder(t, maxDepth) + maxDepth := types.Depth(6) + startingL2BlockNumber := big.NewInt(0) + claimBuilder := faulttest.NewAlphabetClaimBuilder(t, startingL2BlockNumber, maxDepth) tests := []struct { - name string - agreeWithOutputRoot bool - rootClaimCorrect bool - setupGame func(builder *faulttest.GameBuilder) + name string + rootClaimCorrect bool + setupGame func(builder *faulttest.GameBuilder) }{ { - name: "AttackRootClaim", - agreeWithOutputRoot: true, + name: "AttackRootClaim", setupGame: func(builder *faulttest.GameBuilder) { builder.Seq().ExpectAttack() }, }, - { - name: "DoNotAttackRootClaimWhenDisagreeWithOutputRoot", - agreeWithOutputRoot: false, - setupGame: func(builder *faulttest.GameBuilder) {}, - }, - { - // Note: The fault dispute game contract should prevent a correct root claim from actually being posted - // But for completeness, test we ignore it so we don't get sucked into playing an unwinnable game. - name: "DoNotAttackCorrectRootClaim_AgreeWithOutputRoot", - agreeWithOutputRoot: true, - rootClaimCorrect: true, - setupGame: func(builder *faulttest.GameBuilder) {}, - }, { // Note: The fault dispute game contract should prevent a correct root claim from actually being posted // But for completeness, test we ignore it so we don't get sucked into playing an unwinnable game. - name: "DoNotAttackCorrectRootClaim_DisagreeWithOutputRoot", - agreeWithOutputRoot: false, - rootClaimCorrect: true, - setupGame: func(builder *faulttest.GameBuilder) {}, + name: "DoNotAttackCorrectRootClaim_AgreeWithOutputRoot", + rootClaimCorrect: true, + setupGame: func(builder *faulttest.GameBuilder) {}, }, { - name: "DoNotPerformDuplicateMoves", - agreeWithOutputRoot: true, + name: "DoNotPerformDuplicateMoves", setupGame: func(builder *faulttest.GameBuilder) { // Expected move has already been made. - builder.Seq().AttackCorrect() + builder.Seq().Attack() }, }, { - name: "RespondToAllClaimsAtDisagreeingLevel", - agreeWithOutputRoot: true, + name: "RespondToAllClaimsAtDisagreeingLevel", setupGame: func(builder *faulttest.GameBuilder) { - honestClaim := builder.Seq().AttackCorrect() - honestClaim.AttackCorrect().ExpectDefend() - honestClaim.DefendCorrect().ExpectDefend() - honestClaim.Attack(common.Hash{0xaa}).ExpectAttack() - honestClaim.Attack(common.Hash{0xbb}).ExpectAttack() - honestClaim.Defend(common.Hash{0xcc}).ExpectAttack() - honestClaim.Defend(common.Hash{0xdd}).ExpectAttack() + honestClaim := builder.Seq().Attack() + honestClaim.Attack().ExpectDefend() + honestClaim.Defend().ExpectDefend() + honestClaim.Attack(faulttest.WithValue(common.Hash{0xaa})).ExpectAttack() + honestClaim.Attack(faulttest.WithValue(common.Hash{0xbb})).ExpectAttack() + honestClaim.Defend(faulttest.WithValue(common.Hash{0xcc})).ExpectAttack() + honestClaim.Defend(faulttest.WithValue(common.Hash{0xdd})).ExpectAttack() }, }, { - name: "StepAtMaxDepth", - agreeWithOutputRoot: true, + name: "StepAtMaxDepth", setupGame: func(builder *faulttest.GameBuilder) { lastHonestClaim := builder.Seq(). - AttackCorrect(). - AttackCorrect(). - DefendCorrect() - lastHonestClaim.AttackCorrect().ExpectStepDefend() - lastHonestClaim.Attack(common.Hash{0xdd}).ExpectStepAttack() + Attack(). + Attack(). + Defend(). + Defend(). + Defend() + lastHonestClaim.Attack().ExpectStepDefend() + lastHonestClaim.Attack(faulttest.WithValue(common.Hash{0xdd})).ExpectStepAttack() }, }, { - name: "PoisonedPreState", - agreeWithOutputRoot: true, + name: "PoisonedPreState", setupGame: func(builder *faulttest.GameBuilder) { // A claim hash that has no pre-image maliciousStateHash := common.Hash{0x01, 0xaa} // Dishonest actor counters their own claims to set up a situation with an invalid prestate // The honest actor should ignore path created by the dishonest actor, only supporting its own attack on the root claim - honestMove := builder.Seq().AttackCorrect() // This expected action is the winning move. - dishonestMove := honestMove.Attack(maliciousStateHash) + honestMove := builder.Seq().Attack() // This expected action is the winning move. + dishonestMove := honestMove.Attack(faulttest.WithValue(maliciousStateHash)) // The expected action by the honest actor dishonestMove.ExpectAttack() // The honest actor will ignore this poisoned path dishonestMove. - Defend(maliciousStateHash). - Attack(maliciousStateHash) + Defend(faulttest.WithValue(maliciousStateHash)). + Attack(faulttest.WithValue(maliciousStateHash)) + }, + }, + { + name: "Freeloader-ValidClaimAtInvalidAttackPosition", + setupGame: func(builder *faulttest.GameBuilder) { + builder.Seq(). + Attack(). // Honest response to invalid root + Defend().ExpectDefend(). // Defender agrees at this point, we should defend + Attack().ExpectDefend() // Freeloader attacks instead of defends + }, + }, + { + name: "Freeloader-InvalidClaimAtInvalidAttackPosition", + setupGame: func(builder *faulttest.GameBuilder) { + builder.Seq(). + Attack(). // Honest response to invalid root + Defend().ExpectDefend(). // Defender agrees at this point, we should defend + Attack(faulttest.WithValue(common.Hash{0xbb})).ExpectAttack() // Freeloader attacks with wrong claim instead of defends + }, + }, + { + name: "Freeloader-InvalidClaimAtValidDefensePosition", + setupGame: func(builder *faulttest.GameBuilder) { + builder.Seq(). + Attack(). // Honest response to invalid root + Defend().ExpectDefend(). // Defender agrees at this point, we should defend + Defend(faulttest.WithValue(common.Hash{0xbb})).ExpectAttack() // Freeloader defends with wrong claim, we should attack + }, + }, + { + name: "Freeloader-InvalidClaimAtValidAttackPosition", + setupGame: func(builder *faulttest.GameBuilder) { + builder.Seq(). + Attack(). // Honest response to invalid root + Defend(faulttest.WithValue(common.Hash{0xaa})).ExpectAttack(). // Defender disagrees at this point, we should attack + Attack(faulttest.WithValue(common.Hash{0xbb})).ExpectAttack() // Freeloader attacks with wrong claim instead of defends + }, + }, + { + name: "Freeloader-InvalidClaimAtInvalidDefensePosition", + setupGame: func(builder *faulttest.GameBuilder) { + builder.Seq(). + Attack(). // Honest response to invalid root + Defend(faulttest.WithValue(common.Hash{0xaa})).ExpectAttack(). // Defender disagrees at this point, we should attack + Defend(faulttest.WithValue(common.Hash{0xbb})) // Freeloader defends with wrong claim but we must not respond to avoid poisoning + }, + }, + { + name: "Freeloader-ValidClaimAtInvalidAttackPosition-RespondingToDishonestButCorrectAttack", + setupGame: func(builder *faulttest.GameBuilder) { + builder.Seq(). + Attack(). // Honest response to invalid root + Attack().ExpectDefend(). // Defender attacks with correct value, we should defend + Attack().ExpectDefend() // Freeloader attacks with wrong claim, we should defend + }, + }, + { + name: "Freeloader-DoNotCounterOwnClaim", + setupGame: func(builder *faulttest.GameBuilder) { + builder.Seq(). + Attack(). // Honest response to invalid root + Attack().ExpectDefend(). // Defender attacks with correct value, we should defend + Attack(). // Freeloader attacks instead, we should defend + Defend() // We do defend and we shouldn't counter our own claim + }, + }, + { + name: "Freeloader-ContinueDefendingAgainstFreeloader", + setupGame: func(builder *faulttest.GameBuilder) { + builder.Seq(). // invalid root + Attack(). // Honest response to invalid root + Attack().ExpectDefend(). // Defender attacks with correct value, we should defend + Attack(). // Freeloader attacks instead, we should defend + Defend(). // We do defend + Attack(faulttest.WithValue(common.Hash{0xaa})). // freeloader attacks our defense, we should attack + ExpectAttack() + }, + }, + { + name: "Freeloader-FreeloaderCountersRootClaim", + setupGame: func(builder *faulttest.GameBuilder) { + builder.Seq(). + ExpectAttack(). // Honest response to invalid root + Attack(faulttest.WithValue(common.Hash{0xaa})). // freeloader + ExpectAttack() // Honest response to freeloader }, }, } @@ -105,29 +177,161 @@ func TestCalculateNextActions(t *testing.T) { for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { - builder := claimBuilder.GameBuilder(test.agreeWithOutputRoot, test.rootClaimCorrect) + builder := claimBuilder.GameBuilder(faulttest.WithInvalidValue(!test.rootClaimCorrect)) test.setupGame(builder) game := builder.Game - for i, claim := range game.Claims() { - t.Logf("Claim %v: Pos: %v TraceIdx: %v ParentIdx: %v, Countered: %v, Value: %v", - i, claim.Position.ToGIndex(), claim.Position.TraceIndex(maxDepth), claim.ParentContractIndex, claim.Countered, claim.Value) - } - solver := NewGameSolver(maxDepth, claimBuilder.CorrectTraceProvider()) - actions, err := solver.CalculateNextActions(context.Background(), game) - require.NoError(t, err) - for i, action := range actions { - t.Logf("Move %v: Type: %v, ParentIdx: %v, Attack: %v, Value: %v, PreState: %v, ProofData: %v", - i, action.Type, action.ParentIdx, action.IsAttack, action.Value, hex.EncodeToString(action.PreState), hex.EncodeToString(action.ProofData)) - // Check that every move the solver returns meets the generic validation rules - require.NoError(t, checkRules(game, action), "Attempting to perform invalid action") - } + solver := NewGameSolver(maxDepth, trace.NewSimpleTraceAccessor(claimBuilder.CorrectTraceProvider())) + postState, actions := runStep(t, solver, game, claimBuilder.CorrectTraceProvider()) for i, action := range builder.ExpectedActions { t.Logf("Expect %v: Type: %v, ParentIdx: %v, Attack: %v, Value: %v, PreState: %v, ProofData: %v", i, action.Type, action.ParentIdx, action.IsAttack, action.Value, hex.EncodeToString(action.PreState), hex.EncodeToString(action.ProofData)) require.Containsf(t, actions, action, "Expected claim %v missing", i) } require.Len(t, actions, len(builder.ExpectedActions), "Incorrect number of actions") + + verifyGameRules(t, postState, test.rootClaimCorrect) }) } } + +func runStep(t *testing.T, solver *GameSolver, game types.Game, correctTraceProvider types.TraceProvider) (types.Game, []types.Action) { + actions, err := solver.CalculateNextActions(context.Background(), game) + require.NoError(t, err) + + postState := applyActions(game, challengerAddr, actions) + + for i, action := range actions { + t.Logf("Move %v: Type: %v, ParentIdx: %v, Attack: %v, Value: %v, PreState: %v, ProofData: %v", + i, action.Type, action.ParentIdx, action.IsAttack, action.Value, hex.EncodeToString(action.PreState), hex.EncodeToString(action.ProofData)) + // Check that every move the solver returns meets the generic validation rules + require.NoError(t, checkRules(game, action, correctTraceProvider), "Attempting to perform invalid action") + } + return postState, actions +} + +func TestMultipleRounds(t *testing.T) { + t.Parallel() + tests := []struct { + name string + actor actor + }{ + { + name: "SingleRoot", + actor: doNothingActor, + }, + { + name: "LinearAttackCorrect", + actor: correctAttackLastClaim, + }, + { + name: "LinearDefendCorrect", + actor: correctDefendLastClaim, + }, + { + name: "LinearAttackIncorrect", + actor: incorrectAttackLastClaim, + }, + { + name: "LinearDefendInorrect", + actor: incorrectDefendLastClaim, + }, + { + name: "LinearDefendIncorrectDefendCorrect", + actor: combineActors(incorrectDefendLastClaim, correctDefendLastClaim), + }, + { + name: "LinearAttackIncorrectDefendCorrect", + actor: combineActors(incorrectAttackLastClaim, correctDefendLastClaim), + }, + { + name: "LinearDefendIncorrectDefendIncorrect", + actor: combineActors(incorrectDefendLastClaim, incorrectDefendLastClaim), + }, + { + name: "LinearAttackIncorrectDefendIncorrect", + actor: combineActors(incorrectAttackLastClaim, incorrectDefendLastClaim), + }, + { + name: "AttackEverythingCorrect", + actor: attackEverythingCorrect, + }, + { + name: "DefendEverythingCorrect", + actor: defendEverythingCorrect, + }, + { + name: "AttackEverythingIncorrect", + actor: attackEverythingIncorrect, + }, + { + name: "DefendEverythingIncorrect", + actor: defendEverythingIncorrect, + }, + { + name: "Exhaustive", + actor: exhaustive, + }, + } + for _, test := range tests { + test := test + for _, rootClaimCorrect := range []bool{true, false} { + rootClaimCorrect := rootClaimCorrect + t.Run(fmt.Sprintf("%v-%v", test.name, rootClaimCorrect), func(t *testing.T) { + t.Parallel() + + maxDepth := types.Depth(6) + startingL2BlockNumber := big.NewInt(50) + claimBuilder := faulttest.NewAlphabetClaimBuilder(t, startingL2BlockNumber, maxDepth) + builder := claimBuilder.GameBuilder(faulttest.WithInvalidValue(!rootClaimCorrect)) + game := builder.Game + + correctTrace := claimBuilder.CorrectTraceProvider() + solver := NewGameSolver(maxDepth, trace.NewSimpleTraceAccessor(correctTrace)) + + roundNum := 0 + done := false + for !done { + t.Logf("------ ROUND %v ------", roundNum) + game, _ = runStep(t, solver, game, correctTrace) + verifyGameRules(t, game, rootClaimCorrect) + + game, done = test.actor.Apply(t, game, correctTrace) + roundNum++ + } + }) + } + } +} + +func applyActions(game types.Game, claimant common.Address, actions []types.Action) types.Game { + claims := game.Claims() + for _, action := range actions { + switch action.Type { + case types.ActionTypeMove: + newPosition := action.ParentPosition.Attack() + if !action.IsAttack { + newPosition = action.ParentPosition.Defend() + } + claim := types.Claim{ + ClaimData: types.ClaimData{ + Value: action.Value, + Bond: big.NewInt(0), + Position: newPosition, + }, + Claimant: claimant, + Clock: nil, + ContractIndex: len(claims), + ParentContractIndex: action.ParentIdx, + } + claims = append(claims, claim) + case types.ActionTypeStep: + counteredClaim := claims[action.ParentIdx] + counteredClaim.CounteredBy = claimant + claims[action.ParentIdx] = counteredClaim + default: + panic(fmt.Errorf("unknown move type: %v", action.Type)) + } + } + return types.NewGameState(claims, game.MaxDepth()) +} diff --git a/op-challenger/game/fault/solver/honest_claims.go b/op-challenger/game/fault/solver/honest_claims.go new file mode 100644 index 000000000000..e340815a64b1 --- /dev/null +++ b/op-challenger/game/fault/solver/honest_claims.go @@ -0,0 +1,36 @@ +package solver + +import "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + +type honestClaimTracker struct { + // agreed tracks the existing claims in the game that the honest actor would make + // The claims may not yet have been made so are tracked by ClaimID not ContractIndex + agreed map[types.ClaimID]bool + + // counters tracks the counter claim for a claim by contract index. + // The counter claim may not yet be part of the game state (ie it may be a move the honest actor is planning to make) + counters map[types.ClaimID]types.Claim +} + +func newHonestClaimTracker() *honestClaimTracker { + return &honestClaimTracker{ + agreed: make(map[types.ClaimID]bool), + counters: make(map[types.ClaimID]types.Claim), + } +} + +func (a *honestClaimTracker) AddHonestClaim(parent types.Claim, claim types.Claim) { + a.agreed[claim.ID()] = true + if parent != (types.Claim{}) { + a.counters[parent.ID()] = claim + } +} + +func (a *honestClaimTracker) IsHonest(claim types.Claim) bool { + return a.agreed[claim.ID()] +} + +func (a *honestClaimTracker) HonestCounter(parent types.Claim) (types.Claim, bool) { + counter, ok := a.counters[parent.ID()] + return counter, ok +} diff --git a/op-challenger/game/fault/solver/honest_claims_test.go b/op-challenger/game/fault/solver/honest_claims_test.go new file mode 100644 index 000000000000..7b06e2635659 --- /dev/null +++ b/op-challenger/game/fault/solver/honest_claims_test.go @@ -0,0 +1,38 @@ +package solver + +import ( + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/stretchr/testify/require" +) + +func TestHonestClaimTracker_RootClaim(t *testing.T) { + tracker := newHonestClaimTracker() + builder := test.NewAlphabetClaimBuilder(t, big.NewInt(3), 4) + + claim := builder.Seq().Get() + require.False(t, tracker.IsHonest(claim)) + + tracker.AddHonestClaim(types.Claim{}, claim) + require.True(t, tracker.IsHonest(claim)) +} + +func TestHonestClaimTracker_ChildClaim(t *testing.T) { + tracker := newHonestClaimTracker() + builder := test.NewAlphabetClaimBuilder(t, big.NewInt(3), 4) + + seq := builder.Seq().Attack().Defend() + parent := seq.Get() + child := seq.Attack().Get() + require.Zero(t, child.ContractIndex, "should work for claims that are not in the game state yet") + + tracker.AddHonestClaim(parent, child) + require.False(t, tracker.IsHonest(parent)) + require.True(t, tracker.IsHonest(child)) + counter, ok := tracker.HonestCounter(parent) + require.True(t, ok) + require.Equal(t, child, counter) +} diff --git a/op-challenger/game/fault/solver/rules.go b/op-challenger/game/fault/solver/rules.go index 627d7d50f3de..5a77ca5869a5 100644 --- a/op-challenger/game/fault/solver/rules.go +++ b/op-challenger/game/fault/solver/rules.go @@ -1,42 +1,64 @@ package solver import ( + "bytes" + "context" "errors" "fmt" + "math/big" + "slices" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" ) -type actionRule func(game types.Game, action types.Action) error +var challengerAddr = common.Address(bytes.Repeat([]byte{0xaa}, 20)) + +type actionRule func(game types.Game, action types.Action, correctTrace types.TraceProvider) error var rules = []actionRule{ parentMustExist, onlyStepAtMaxDepth, onlyMoveBeforeMaxDepth, doNotDuplicateExistingMoves, + doNotStepAlreadyCounteredClaims, doNotDefendRootClaim, + avoidPoisonedPrestate, + detectPoisonedStepPrestate, + detectFailedStep, + doNotCounterSelf, +} + +func printClaim(claim types.Claim, game types.Game) string { + return fmt.Sprintf("Claim %v: Pos: %v TraceIdx: %v Depth: %v IndexAtDepth: %v ParentIdx: %v Value: %v Claimant: %v CounteredBy: %v", + claim.ContractIndex, claim.Position.ToGIndex(), claim.Position.TraceIndex(game.MaxDepth()), claim.Position.Depth(), claim.Position.IndexAtDepth(), claim.ParentContractIndex, claim.Value, claim.Claimant, claim.CounteredBy) } -func checkRules(game types.Game, action types.Action) error { +func checkRules(game types.Game, action types.Action, correctTrace types.TraceProvider) error { var errs []error for _, rule := range rules { - errs = append(errs, rule(game, action)) + errs = append(errs, rule(game, action, correctTrace)) } return errors.Join(errs...) } -func parentMustExist(game types.Game, action types.Action) error { +// parentMustExist checks that every action performed has a valid parent claim +// Rationale: The action would be rejected by the contracts +func parentMustExist(game types.Game, action types.Action, _ types.TraceProvider) error { if len(game.Claims()) <= action.ParentIdx || action.ParentIdx < 0 { return fmt.Errorf("parent claim %v does not exist in game with %v claims", action.ParentIdx, len(game.Claims())) } return nil } -func onlyStepAtMaxDepth(game types.Game, action types.Action) error { +// onlyStepAtMaxDepth verifies that step actions are only performed against leaf claims +// Rationale: The action would be rejected by the contracts +func onlyStepAtMaxDepth(game types.Game, action types.Action, _ types.TraceProvider) error { if action.Type == types.ActionTypeStep { return nil } - parentDepth := uint64(game.Claims()[action.ParentIdx].Position.Depth()) + parentDepth := game.Claims()[action.ParentIdx].Position.Depth() if parentDepth >= game.MaxDepth() { return fmt.Errorf("parent at max depth (%v) but attempting to perform %v action instead of step", parentDepth, action.Type) @@ -44,11 +66,13 @@ func onlyStepAtMaxDepth(game types.Game, action types.Action) error { return nil } -func onlyMoveBeforeMaxDepth(game types.Game, action types.Action) error { +// onlyMoveBeforeMaxDepth verifies that move actions are not performed against leaf claims +// Rationale: The action would be rejected by the contracts +func onlyMoveBeforeMaxDepth(game types.Game, action types.Action, _ types.TraceProvider) error { if action.Type == types.ActionTypeMove { return nil } - parentDepth := uint64(game.Claims()[action.ParentIdx].Position.Depth()) + parentDepth := game.Claims()[action.ParentIdx].Position.Depth() if parentDepth < game.MaxDepth() { return fmt.Errorf("parent (%v) not at max depth (%v) but attempting to perform %v action instead of move", parentDepth, game.MaxDepth(), action.Type) @@ -56,7 +80,9 @@ func onlyMoveBeforeMaxDepth(game types.Game, action types.Action) error { return nil } -func doNotDuplicateExistingMoves(game types.Game, action types.Action) error { +// doNotDuplicateExistingMoves verifies that the challenger doesn't attempt to post a duplicate claim +// Rationale: The action would be rejected by the contracts +func doNotDuplicateExistingMoves(game types.Game, action types.Action, _ types.TraceProvider) error { newClaimData := types.ClaimData{ Value: action.Value, Position: resultingPosition(game, action), @@ -67,13 +93,180 @@ func doNotDuplicateExistingMoves(game types.Game, action types.Action) error { return nil } -func doNotDefendRootClaim(game types.Game, action types.Action) error { +// doNotStepAlreadyCounteredClaims checks the challenger does not attempt to call step on already countered claims +// Rationale: The step call is redundant and a waste of gas +func doNotStepAlreadyCounteredClaims(game types.Game, action types.Action, _ types.TraceProvider) error { + claim := game.Claims()[action.ParentIdx] + if claim.CounteredBy != (common.Address{}) { + return fmt.Errorf("attempting to step already countered claim: %v", claim.ContractIndex) + } + return nil +} + +// doNotDefendRootClaim checks the challenger doesn't attempt to defend the root claim +// Rationale: The action would be rejected by the contracts +func doNotDefendRootClaim(game types.Game, action types.Action, _ types.TraceProvider) error { if game.Claims()[action.ParentIdx].IsRootPosition() && !action.IsAttack { return fmt.Errorf("defending the root claim at idx %v", action.ParentIdx) } return nil } +// doNotCounterSelf checks the challenger doesn't counter its own claims +// Rationale: The challenger should not disagree with itself +func doNotCounterSelf(game types.Game, action types.Action, _ types.TraceProvider) error { + claim := game.Claims()[action.ParentIdx] + if claim.Claimant == challengerAddr { + return fmt.Errorf("countering own claim at idx %v", action.ParentIdx) + } + return nil +} + +// avoidPoisonedPrestate checks the challenger does not perform a move that results in a claim where the ancestor +// with the largest trace index less than the new claim's trace index is invalid. +// Rationale: If such a claim were posted, an attacker could attack with invalid values down to max depth and setup a +// step call which uses the invalid claim as the pre-state. The challenger could not call step because it does not have +// the preimage of the invalid state. If the attacker should call step, they could provide a carefully crafted state +// that allows it to successfully step against the challenger's claim. +func avoidPoisonedPrestate(game types.Game, action types.Action, correctTrace types.TraceProvider) error { + if action.Type == types.ActionTypeStep { + return nil + } + ancestors := "" + movePosition := resultingPosition(game, action) + honestTraceIndex := movePosition.TraceIndex(game.MaxDepth()) + // Walk back up the claims and find the claim with highest trace index < honestTraceIndex + claim := game.Claims()[action.ParentIdx] + var preStateClaim types.Claim + for { + ancestors += printClaim(claim, game) + "\n" + claimTraceIdx := claim.TraceIndex(game.MaxDepth()) + if claimTraceIdx.Cmp(honestTraceIndex) < 0 { // Check it's left of the honest claim + if preStateClaim == (types.Claim{}) || claimTraceIdx.Cmp(preStateClaim.TraceIndex(game.MaxDepth())) > 0 { + preStateClaim = claim + } + } + if claim.IsRoot() { + break + } + parent, err := game.GetParent(claim) + if err != nil { + return fmt.Errorf("no parent of claim %v: %w", claim.ContractIndex, err) + } + claim = parent + } + if preStateClaim == (types.Claim{}) { + // No claim to the left of the honest claim, so can't have been poisoned + return nil + } + correctValue, err := correctTrace.Get(context.Background(), preStateClaim.Position) + if err != nil { + return fmt.Errorf("failed to get correct trace at position %v: %w", preStateClaim.Position, err) + } + if correctValue != preStateClaim.Value { + err = fmt.Errorf("prestate poisoned claim %v has invalid prestate and is left of honest claim countering %v at trace index %v", preStateClaim.ContractIndex, action.ParentIdx, honestTraceIndex) + return err + } + return nil +} + +// detectFailedStep checks that step actions will succeed. +// Rationale: The action would be rejected by the contracts +// +// INVARIANT: If a step is an attack, the poststate is valid if the step produces +// +// the same poststate hash as the parent claim's value. +// If a step is a defense: +// 1. If the parent claim and the found post state agree with each other +// (depth diff % 2 == 0), the step is valid if it produces the same +// state hash as the post state's claim. +// 2. If the parent claim and the found post state disagree with each other +// (depth diff % 2 != 0), the parent cannot be countered unless the step +// produces the same state hash as `postState.claim`. +func detectFailedStep(game types.Game, action types.Action, correctTrace types.TraceProvider) error { + if action.Type != types.ActionTypeStep { + // An invalid post state is not an issue if we are moving, only if the honest challenger has to call step. + return nil + } + position := resultingPosition(game, action) + if position.Depth() != game.MaxDepth() { + // Not at max depth yet + return nil + } + honestTraceIndex := position.TraceIndex(game.MaxDepth()) + poststateIndex := honestTraceIndex + if !action.IsAttack { + poststateIndex = new(big.Int).Add(honestTraceIndex, big.NewInt(1)) + } + // Walk back up the claims and find the claim required post state index + claim := game.Claims()[action.ParentIdx] + poststateClaim, ok := game.AncestorWithTraceIndex(claim, poststateIndex) + if !ok { + return fmt.Errorf("did not find required poststate at %v to counter claim %v", poststateIndex, action.ParentIdx) + } + correctValue, err := correctTrace.Get(context.Background(), poststateClaim.Position) + if err != nil { + return fmt.Errorf("failed to get correct trace at position %v: %w", poststateClaim.Position, err) + } + validStep := correctValue == poststateClaim.Value + parentPostAgree := (claim.Depth()-poststateClaim.Depth())%2 == 0 + if parentPostAgree == validStep { + return fmt.Errorf("failed step against claim at %v using poststate from claim %v post state is correct? %v parentPostAgree? %v", + action.ParentIdx, poststateClaim.ContractIndex, validStep, parentPostAgree) + } + return nil +} + +// detectPoisonedStepPrestate checks that: +// 1. step actions performed by the challenger always have a valid prestate +// 2. move actions that create a claim a max depth would have a valid prestate if they are attacked +// 3. the actual prestate provided matches the prestate claim's commitment +// Rationale: A step against an invalid prestate will fail because the preimage of the prestate claim is unknown +// and claims at max depth with an invalid prestate could be stepped against because the prestate is invalid so a VM +// step will not result in the correct post-state. +func detectPoisonedStepPrestate(game types.Game, action types.Action, correctTrace types.TraceProvider) error { + position := resultingPosition(game, action) + if position.Depth() != game.MaxDepth() { + // Not at max depth yet + return nil + } + honestTraceIndex := position.TraceIndex(game.MaxDepth()) + prestateIndex := honestTraceIndex + // If we're performing a move to post a leaf claim, assume the attacker will try to attack it from their + // poisoned prestate + if action.IsAttack || action.Type == types.ActionTypeMove { + prestateIndex = new(big.Int).Sub(prestateIndex, big.NewInt(1)) + } + if prestateIndex.Cmp(big.NewInt(0)) < 0 { + // Absolute prestate is not poisoned + return nil + } + // Walk back up the claims and find the claim with highest trace index < honestTraceIndex + claim := game.Claims()[action.ParentIdx] + preStateClaim, ok := game.AncestorWithTraceIndex(claim, prestateIndex) + if !ok { + return fmt.Errorf("performing step against claim %v with no prestate available at %v", claim.ContractIndex, prestateIndex) + } + correctValue, err := correctTrace.Get(context.Background(), preStateClaim.Position) + if err != nil { + return fmt.Errorf("failed to get correct trace at position %v: %w", preStateClaim.Position, err) + } + if correctValue != preStateClaim.Value { + if action.Type == types.ActionTypeStep { + return fmt.Errorf("stepping from poisoned prestate at claim %v when countering %v", preStateClaim.ContractIndex, action.ParentIdx) + } else { + return fmt.Errorf("posting leaf claim with poisoned prestate from claim %v when countering %v", preStateClaim.ContractIndex, action.ParentIdx) + } + } + if action.Type == types.ActionTypeStep { + prestateHash := crypto.Keccak256Hash(action.PreState) + if !slices.Equal(prestateHash[1:], preStateClaim.Value[1:]) { + return fmt.Errorf("prestate hash %v does not match expected prestate claim %v from claim %v", prestateHash, preStateClaim.Value, preStateClaim.ContractIndex) + } + } + return nil +} + func resultingPosition(game types.Game, action types.Action) types.Position { parentPos := game.Claims()[action.ParentIdx].Position if action.Type == types.ActionTypeStep { diff --git a/op-challenger/game/fault/solver/solver.go b/op-challenger/game/fault/solver/solver.go index 264787dab7b5..4292754c23e4 100644 --- a/op-challenger/game/fault/solver/solver.go +++ b/op-challenger/game/fault/solver/solver.go @@ -7,60 +7,77 @@ import ( "fmt" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum/go-ethereum/common" ) var ( - ErrStepNonLeafNode = errors.New("cannot step on non-leaf claims") - ErrStepAgreedClaim = errors.New("cannot step on claims we agree with") - ErrStepIgnoreInvalidPath = errors.New("cannot step on claims that dispute invalid paths") + ErrStepNonLeafNode = errors.New("cannot step on non-leaf claims") ) // claimSolver uses a [TraceProvider] to determine the moves to make in a dispute game. type claimSolver struct { - trace types.TraceProvider - gameDepth int + trace types.TraceAccessor + gameDepth types.Depth } // newClaimSolver creates a new [claimSolver] using the provided [TraceProvider]. -func newClaimSolver(gameDepth int, traceProvider types.TraceProvider) *claimSolver { +func newClaimSolver(gameDepth types.Depth, trace types.TraceAccessor) *claimSolver { return &claimSolver{ - traceProvider, + trace, gameDepth, } } +func (s *claimSolver) shouldCounter(game types.Game, claim types.Claim, honestClaims *honestClaimTracker) (bool, error) { + // Do not counter honest claims + if honestClaims.IsHonest(claim) { + return false, nil + } + + if claim.IsRoot() { + // Always counter the root claim if it is not honest + return true, nil + } + + parent, err := game.GetParent(claim) + if err != nil { + return false, fmt.Errorf("no parent for claim %v: %w", claim.ContractIndex, err) + } + + // Counter all claims that are countering an honest claim + if honestClaims.IsHonest(parent) { + return true, nil + } + + counter, hasCounter := honestClaims.HonestCounter(parent) + // Do not respond to any claim countering a claim the honest actor ignored + if !hasCounter { + return false, nil + } + + // Do not counter sibling to an honest claim that are right of the honest claim. + honestIdx := counter.TraceIndex(game.MaxDepth()) + claimIdx := claim.TraceIndex(game.MaxDepth()) + return claimIdx.Cmp(honestIdx) <= 0, nil +} + // NextMove returns the next move to make given the current state of the game. -func (s *claimSolver) NextMove(ctx context.Context, claim types.Claim, game types.Game) (*types.Claim, error) { +func (s *claimSolver) NextMove(ctx context.Context, claim types.Claim, game types.Game, honestClaims *honestClaimTracker) (*types.Claim, error) { if claim.Depth() == s.gameDepth { return nil, types.ErrGameDepthReached } - // Before challenging this claim, first check that the move wasn't warranted. - // If the parent claim is on a dishonest path, then we would have moved against it anyways. So we don't move. - // Avoiding dishonest paths ensures that there's always a valid claim available to support ours during step. - if !claim.IsRoot() { - parent, err := game.GetParent(claim) - if err != nil { - return nil, err - } - agreeWithParent, err := s.agreeWithClaimPath(ctx, game, parent) - if err != nil { - return nil, err - } - if !agreeWithParent { - return nil, nil - } - } - - agree, err := s.agreeWithClaim(ctx, claim.ClaimData) - if err != nil { - return nil, err + if counter, err := s.shouldCounter(game, claim, honestClaims); err != nil { + return nil, fmt.Errorf("failed to determine if claim should be countered: %w", err) + } else if !counter { + return nil, nil } - if agree { - return s.defend(ctx, claim) + + if agree, err := s.agreeWithClaim(ctx, game, claim); err != nil { + return nil, err + } else if agree { + return s.defend(ctx, game, claim) } else { - return s.attack(ctx, claim) + return s.attack(ctx, game, claim) } } @@ -72,51 +89,41 @@ type StepData struct { OracleData *types.PreimageOracleData } -// AttemptStep determines what step should occur for a given leaf claim. +// AttemptStep determines what step, if any, should occur for a given leaf claim. // An error will be returned if the claim is not at the max depth. -// Returns ErrStepIgnoreInvalidPath if the claim disputes an invalid path -func (s *claimSolver) AttemptStep(ctx context.Context, game types.Game, claim types.Claim) (StepData, error) { +// Returns nil, nil if no step should be performed. +func (s *claimSolver) AttemptStep(ctx context.Context, game types.Game, claim types.Claim, honestClaims *honestClaimTracker) (*StepData, error) { if claim.Depth() != s.gameDepth { - return StepData{}, ErrStepNonLeafNode + return nil, ErrStepNonLeafNode } - // Step only on claims that dispute a valid path - parent, err := game.GetParent(claim) - if err != nil { - return StepData{}, err - } - parentValid, err := s.agreeWithClaimPath(ctx, game, parent) - if err != nil { - return StepData{}, err - } - if !parentValid { - return StepData{}, ErrStepIgnoreInvalidPath + if counter, err := s.shouldCounter(game, claim, honestClaims); err != nil { + return nil, fmt.Errorf("failed to determine if claim should be countered: %w", err) + } else if !counter { + return nil, nil } - claimCorrect, err := s.agreeWithClaim(ctx, claim.ClaimData) + claimCorrect, err := s.agreeWithClaim(ctx, game, claim) if err != nil { - return StepData{}, err + return nil, err } - var preState []byte - var proofData []byte - var oracleData *types.PreimageOracleData + var position types.Position if !claimCorrect { // Attack the claim by executing step index, so we need to get the pre-state of that index - preState, proofData, oracleData, err = s.trace.GetStepData(ctx, claim.Position) - if err != nil { - return StepData{}, err - } + position = claim.Position } else { - // We agree with the claim so Defend and use this claim as the starting point to - // execute the step after. Thus we need the pre-state of the next step. - preState, proofData, oracleData, err = s.trace.GetStepData(ctx, claim.MoveRight()) - if err != nil { - return StepData{}, err - } + // Defend and use this claim as the starting point to execute the step after. + // Thus, we need the pre-state of the next step. + position = claim.Position.MoveRight() } - return StepData{ + preState, proofData, oracleData, err := s.trace.GetStepData(ctx, game, claim, position) + if err != nil { + return nil, err + } + + return &StepData{ LeafClaim: claim, IsAttack: !claimCorrect, PreState: preState, @@ -126,9 +133,9 @@ func (s *claimSolver) AttemptStep(ctx context.Context, game types.Game, claim ty } // attack returns a response that attacks the claim. -func (s *claimSolver) attack(ctx context.Context, claim types.Claim) (*types.Claim, error) { +func (s *claimSolver) attack(ctx context.Context, game types.Game, claim types.Claim) (*types.Claim, error) { position := claim.Attack() - value, err := s.traceAtPosition(ctx, position) + value, err := s.trace.Get(ctx, game, claim, position) if err != nil { return nil, fmt.Errorf("attack claim: %w", err) } @@ -139,12 +146,12 @@ func (s *claimSolver) attack(ctx context.Context, claim types.Claim) (*types.Cla } // defend returns a response that defends the claim. -func (s *claimSolver) defend(ctx context.Context, claim types.Claim) (*types.Claim, error) { +func (s *claimSolver) defend(ctx context.Context, game types.Game, claim types.Claim) (*types.Claim, error) { if claim.IsRoot() { return nil, nil } position := claim.Defend() - value, err := s.traceAtPosition(ctx, position) + value, err := s.trace.Get(ctx, game, claim, position) if err != nil { return nil, fmt.Errorf("defend claim: %w", err) } @@ -155,38 +162,7 @@ func (s *claimSolver) defend(ctx context.Context, claim types.Claim) (*types.Cla } // agreeWithClaim returns true if the claim is correct according to the internal [TraceProvider]. -func (s *claimSolver) agreeWithClaim(ctx context.Context, claim types.ClaimData) (bool, error) { - ourValue, err := s.traceAtPosition(ctx, claim.Position) +func (s *claimSolver) agreeWithClaim(ctx context.Context, game types.Game, claim types.Claim) (bool, error) { + ourValue, err := s.trace.Get(ctx, game, claim, claim.Position) return bytes.Equal(ourValue[:], claim.Value[:]), err } - -// traceAtPosition returns the [common.Hash] from internal [TraceProvider] at the given [Position]. -func (s *claimSolver) traceAtPosition(ctx context.Context, p types.Position) (common.Hash, error) { - return s.trace.Get(ctx, p) -} - -// agreeWithClaimPath returns true if the every other claim in the path to root is correct according to the internal [TraceProvider]. -func (s *claimSolver) agreeWithClaimPath(ctx context.Context, game types.Game, claim types.Claim) (bool, error) { - agree, err := s.agreeWithClaim(ctx, claim.ClaimData) - if err != nil { - return false, err - } - if !agree { - return false, nil - } - if claim.IsRoot() { - return true, nil - } - parent, err := game.GetParent(claim) - if err != nil { - return false, fmt.Errorf("failed to get parent of claim %v: %w", claim.ContractIndex, err) - } - if parent.IsRoot() { - return true, nil - } - grandParent, err := game.GetParent(parent) - if err != nil { - return false, err - } - return s.agreeWithClaimPath(ctx, game, grandParent) -} diff --git a/op-challenger/game/fault/solver/solver_test.go b/op-challenger/game/fault/solver/solver_test.go index 764a81b1962e..96755b843634 100644 --- a/op-challenger/game/fault/solver/solver_test.go +++ b/op-challenger/game/fault/solver/solver_test.go @@ -6,14 +6,16 @@ import ( "testing" faulttest "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) func TestAttemptStep(t *testing.T) { - maxDepth := 3 - claimBuilder := faulttest.NewAlphabetClaimBuilder(t, maxDepth) + maxDepth := types.Depth(3) + startingL2BlockNumber := big.NewInt(0) + claimBuilder := faulttest.NewAlphabetClaimBuilder(t, startingL2BlockNumber, maxDepth) // Last accessible leaf is the second last trace index // The root node is used for the last trace index and can only be attacked. @@ -25,6 +27,7 @@ func TestAttemptStep(t *testing.T) { name string agreeWithOutputRoot bool expectedErr error + expectNoStep bool expectAttack bool expectPreState []byte expectProofData []byte @@ -39,9 +42,9 @@ func TestAttemptStep(t *testing.T) { expectedOracleData: claimBuilder.CorrectOracleData(common.Big0), setupGame: func(builder *faulttest.GameBuilder) { builder.Seq(). - Attack(common.Hash{0xaa}). - AttackCorrect(). - Attack(common.Hash{0xbb}) + Attack(faulttest.WithValue(common.Hash{0xaa})). + Attack(). + Attack(faulttest.WithValue(common.Hash{0xbb})) }, }, { @@ -52,9 +55,9 @@ func TestAttemptStep(t *testing.T) { expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(1)), setupGame: func(builder *faulttest.GameBuilder) { builder.Seq(). - Attack(common.Hash{0xaa}). - AttackCorrect(). - AttackCorrect() + Attack(faulttest.WithValue(common.Hash{0xaa})). + Attack(). + Attack() }, }, { @@ -65,9 +68,9 @@ func TestAttemptStep(t *testing.T) { expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(4)), setupGame: func(builder *faulttest.GameBuilder) { builder.Seq(). - AttackCorrect(). - DefendCorrect(). - Attack(common.Hash{0xaa}) + Attack(). + Defend(). + Attack(faulttest.WithValue(common.Hash{0xaa})) }, }, { @@ -78,9 +81,9 @@ func TestAttemptStep(t *testing.T) { expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(5)), setupGame: func(builder *faulttest.GameBuilder) { builder.Seq(). - AttackCorrect(). - DefendCorrect(). - AttackCorrect() + Attack(). + Defend(). + Attack() }, }, { @@ -91,9 +94,9 @@ func TestAttemptStep(t *testing.T) { expectedOracleData: claimBuilder.CorrectOracleData(lastLeafTraceIndex), setupGame: func(builder *faulttest.GameBuilder) { builder.Seq(). - AttackCorrect(). - DefendCorrect(). - Defend(common.Hash{0xaa}) + Attack(). + Defend(). + Defend(faulttest.WithValue(common.Hash{0xaa})) }, }, { @@ -104,15 +107,15 @@ func TestAttemptStep(t *testing.T) { expectedOracleData: claimBuilder.CorrectOracleData(lastLeafTraceIndexPlusOne), setupGame: func(builder *faulttest.GameBuilder) { builder.Seq(). - AttackCorrect(). - DefendCorrect(). - DefendCorrect() + Attack(). + Defend(). + Defend() }, }, { name: "CannotStepNonLeaf", setupGame: func(builder *faulttest.GameBuilder) { - builder.Seq().AttackCorrect().AttackCorrect() + builder.Seq().Attack().Attack() }, expectedErr: ErrStepNonLeafNode, agreeWithOutputRoot: true, @@ -121,22 +124,22 @@ func TestAttemptStep(t *testing.T) { name: "CannotStepAgreedNode", setupGame: func(builder *faulttest.GameBuilder) { builder.Seq(). - AttackCorrect(). - Attack(common.Hash{0xaa}). - AttackCorrect() + Attack(). + Attack(faulttest.WithValue(common.Hash{0xaa})). + Attack() }, - expectedErr: ErrStepIgnoreInvalidPath, + expectNoStep: true, agreeWithOutputRoot: true, }, { name: "CannotStepInvalidPath", setupGame: func(builder *faulttest.GameBuilder) { builder.Seq(). - Attack(common.Hash{0xaa}). - Attack(common.Hash{0xbb}). - Attack(common.Hash{0xcc}) + Attack(faulttest.WithValue(common.Hash{0xaa})). + Attack(faulttest.WithValue(common.Hash{0xbb})). + Attack(faulttest.WithValue(common.Hash{0xcc})) }, - expectedErr: ErrStepIgnoreInvalidPath, + expectNoStep: true, agreeWithOutputRoot: true, }, { @@ -147,11 +150,11 @@ func TestAttemptStep(t *testing.T) { expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(4)), setupGame: func(builder *faulttest.GameBuilder) { builder.Seq(). - AttackCorrect(). - DefendCorrect(). - DefendCorrect() + Attack(). + Defend(). + Defend() }, - expectedErr: ErrStepIgnoreInvalidPath, + expectNoStep: true, agreeWithOutputRoot: true, }, } @@ -159,26 +162,35 @@ func TestAttemptStep(t *testing.T) { for _, tableTest := range tests { tableTest := tableTest t.Run(tableTest.name, func(t *testing.T) { - builder := claimBuilder.GameBuilder(tableTest.agreeWithOutputRoot, !tableTest.agreeWithOutputRoot) + builder := claimBuilder.GameBuilder(faulttest.WithInvalidValue(tableTest.agreeWithOutputRoot)) tableTest.setupGame(builder) - alphabetSolver := newClaimSolver(maxDepth, claimBuilder.CorrectTraceProvider()) + alphabetSolver := newClaimSolver(maxDepth, trace.NewSimpleTraceAccessor(claimBuilder.CorrectTraceProvider())) game := builder.Game claims := game.Claims() lastClaim := claims[len(claims)-1] - step, err := alphabetSolver.AttemptStep(ctx, game, lastClaim) - if tableTest.expectedErr == nil { - require.NoError(t, err) + agreedClaims := newHonestClaimTracker() + if tableTest.agreeWithOutputRoot { + agreedClaims.AddHonestClaim(types.Claim{}, claims[0]) + } + if (lastClaim.Depth()%2 == 0) == tableTest.agreeWithOutputRoot { + parentClaim := claims[lastClaim.ParentContractIndex] + grandParentClaim := claims[parentClaim.ParentContractIndex] + agreedClaims.AddHonestClaim(grandParentClaim, parentClaim) + } + step, err := alphabetSolver.AttemptStep(ctx, game, lastClaim, agreedClaims) + require.ErrorIs(t, err, tableTest.expectedErr) + if !tableTest.expectNoStep && tableTest.expectedErr == nil { + require.NotNil(t, step) require.Equal(t, lastClaim, step.LeafClaim) require.Equal(t, tableTest.expectAttack, step.IsAttack) require.Equal(t, tableTest.expectPreState, step.PreState) require.Equal(t, tableTest.expectProofData, step.ProofData) require.Equal(t, tableTest.expectedOracleData.IsLocal, step.OracleData.IsLocal) require.Equal(t, tableTest.expectedOracleData.OracleKey, step.OracleData.OracleKey) - require.Equal(t, tableTest.expectedOracleData.OracleData, step.OracleData.OracleData) + require.Equal(t, tableTest.expectedOracleData.GetPreimageWithSize(), step.OracleData.GetPreimageWithSize()) require.Equal(t, tableTest.expectedOracleData.OracleOffset, step.OracleData.OracleOffset) } else { - require.ErrorIs(t, err, tableTest.expectedErr) - require.Equal(t, StepData{}, step) + require.Nil(t, step) } }) } diff --git a/op-challenger/game/fault/sync.go b/op-challenger/game/fault/sync.go new file mode 100644 index 000000000000..ec0a8104080f --- /dev/null +++ b/op-challenger/game/fault/sync.go @@ -0,0 +1,36 @@ +package fault + +import ( + "context" + "errors" + "fmt" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +var ErrNotInSync = errors.New("local node too far behind") + +type SyncStatusProvider interface { + SyncStatus(context.Context) (*eth.SyncStatus, error) +} + +type syncStatusValidator struct { + statusProvider SyncStatusProvider +} + +func newSyncStatusValidator(statusProvider SyncStatusProvider) *syncStatusValidator { + return &syncStatusValidator{ + statusProvider: statusProvider, + } +} + +func (s *syncStatusValidator) ValidateNodeSynced(ctx context.Context, gameL1Head eth.BlockID) error { + syncStatus, err := s.statusProvider.SyncStatus(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve local node sync status: %w", err) + } + if syncStatus.CurrentL1.Number <= gameL1Head.Number { + return fmt.Errorf("%w require L1 block above %v but at %v", ErrNotInSync, gameL1Head.Number, syncStatus.CurrentL1.Number) + } + return nil +} diff --git a/op-challenger/game/fault/sync_test.go b/op-challenger/game/fault/sync_test.go new file mode 100644 index 000000000000..9099f52aeb81 --- /dev/null +++ b/op-challenger/game/fault/sync_test.go @@ -0,0 +1,83 @@ +package fault + +import ( + "context" + "errors" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/stretchr/testify/require" +) + +func TestSyncStatusProvider(t *testing.T) { + requestErr := errors.New("boom") + tests := []struct { + name string + gameL1Head eth.BlockID + syncStatus *eth.SyncStatus + statusReqErr error + expected error + }{ + { + name: "ErrorFetchingStatus", + gameL1Head: eth.BlockID{Number: 100}, + syncStatus: nil, + statusReqErr: requestErr, + expected: requestErr, + }, + { + name: "CurrentL1BelowGameL1Head", + gameL1Head: eth.BlockID{Number: 100}, + syncStatus: ð.SyncStatus{ + CurrentL1: eth.L1BlockRef{ + Number: 99, + }, + }, + statusReqErr: nil, + expected: ErrNotInSync, + }, + { + name: "CurrentL1EqualToGameL1Head", + gameL1Head: eth.BlockID{Number: 100}, + syncStatus: ð.SyncStatus{ + CurrentL1: eth.L1BlockRef{ + Number: 100, + }, + }, + statusReqErr: nil, + expected: ErrNotInSync, + }, + { + name: "CurrentL1AboveGameL1Head", + gameL1Head: eth.BlockID{Number: 100}, + syncStatus: ð.SyncStatus{ + CurrentL1: eth.L1BlockRef{ + Number: 101, + }, + }, + statusReqErr: nil, + expected: nil, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + provider := &stubSyncStatusProvider{ + status: test.syncStatus, + err: test.statusReqErr, + } + validator := newSyncStatusValidator(provider) + err := validator.ValidateNodeSynced(context.Background(), test.gameL1Head) + require.ErrorIs(t, err, test.expected) + }) + } +} + +type stubSyncStatusProvider struct { + status *eth.SyncStatus + err error +} + +func (s *stubSyncStatusProvider) SyncStatus(_ context.Context) (*eth.SyncStatus, error) { + return s.status, s.err +} diff --git a/op-challenger/game/fault/test/alphabet.go b/op-challenger/game/fault/test/alphabet.go index 3ae75c0943e5..9aa129d221c8 100644 --- a/op-challenger/game/fault/test/alphabet.go +++ b/op-challenger/game/fault/test/alphabet.go @@ -2,28 +2,29 @@ package test import ( "context" + "math/big" "testing" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" ) -func NewAlphabetWithProofProvider(t *testing.T, maxDepth int, oracleError error) *alphabetWithProofProvider { +func NewAlphabetWithProofProvider(t *testing.T, startingL2BlockNumber *big.Int, maxDepth types.Depth, oracleError error) *alphabetWithProofProvider { return &alphabetWithProofProvider{ - alphabet.NewTraceProvider("abcdefghijklmnopqrstuvwxyz", uint64(maxDepth)), - uint64(maxDepth), + alphabet.NewTraceProvider(startingL2BlockNumber, maxDepth), + maxDepth, oracleError, } } -func NewAlphabetClaimBuilder(t *testing.T, maxDepth int) *ClaimBuilder { - alphabetProvider := NewAlphabetWithProofProvider(t, maxDepth, nil) +func NewAlphabetClaimBuilder(t *testing.T, startingL2BlockNumber *big.Int, maxDepth types.Depth) *ClaimBuilder { + alphabetProvider := NewAlphabetWithProofProvider(t, startingL2BlockNumber, maxDepth, nil) return NewClaimBuilder(t, maxDepth, alphabetProvider) } type alphabetWithProofProvider struct { *alphabet.AlphabetTraceProvider - depth uint64 + depth types.Depth OracleError error } @@ -32,7 +33,7 @@ func (a *alphabetWithProofProvider) GetStepData(ctx context.Context, i types.Pos if err != nil { return nil, nil, nil, err } - traceIndex := i.TraceIndex(int(a.depth)).Uint64() - data := types.NewPreimageOracleData(0, []byte{byte(traceIndex)}, []byte{byte(traceIndex - 1)}, uint32(traceIndex-1)) + traceIndex := i.TraceIndex(a.depth).Uint64() + data := types.NewPreimageOracleData([]byte{byte(traceIndex)}, []byte{byte(traceIndex - 1)}, uint32(traceIndex-1)) return preimage, []byte{byte(traceIndex - 1)}, data, nil } diff --git a/op-challenger/game/fault/test/claim_builder.go b/op-challenger/game/fault/test/claim_builder.go index 7bb6e19b7c49..36bfd1b4d8fc 100644 --- a/op-challenger/game/fault/test/claim_builder.go +++ b/op-challenger/game/fault/test/claim_builder.go @@ -10,15 +10,66 @@ import ( "github.com/stretchr/testify/require" ) +var DefaultClaimant = common.Address{0xba, 0xdb, 0xad, 0xba, 0xdb, 0xad} + +type claimCfg struct { + value common.Hash + invalidValue bool + claimant common.Address + parentIdx int +} + +func newClaimCfg(opts ...ClaimOpt) *claimCfg { + cfg := &claimCfg{} + for _, opt := range opts { + opt.Apply(cfg) + } + return cfg +} + +type ClaimOpt interface { + Apply(cfg *claimCfg) +} + +type claimOptFn func(cfg *claimCfg) + +func (c claimOptFn) Apply(cfg *claimCfg) { + c(cfg) +} + +func WithValue(value common.Hash) ClaimOpt { + return claimOptFn(func(cfg *claimCfg) { + cfg.value = value + }) +} + +func WithInvalidValue(invalid bool) ClaimOpt { + return claimOptFn(func(cfg *claimCfg) { + cfg.invalidValue = invalid + }) +} + +func WithClaimant(claimant common.Address) ClaimOpt { + return claimOptFn(func(cfg *claimCfg) { + cfg.claimant = claimant + }) +} + +func WithParent(claim types.Claim) ClaimOpt { + return claimOptFn(func(cfg *claimCfg) { + cfg.parentIdx = claim.ContractIndex + }) +} + // ClaimBuilder is a test utility to enable creating claims in a wide range of situations type ClaimBuilder struct { require *require.Assertions - maxDepth int + maxDepth types.Depth correct types.TraceProvider } // NewClaimBuilder creates a new [ClaimBuilder]. -func NewClaimBuilder(t *testing.T, maxDepth int, provider types.TraceProvider) *ClaimBuilder { +func NewClaimBuilder(t *testing.T, maxDepth types.Depth, provider types.TraceProvider) *ClaimBuilder { return &ClaimBuilder{ require: require.New(t), maxDepth: maxDepth, @@ -65,75 +116,44 @@ func (c *ClaimBuilder) incorrectClaim(pos types.Position) common.Hash { return common.BigToHash(pos.TraceIndex(c.maxDepth)) } -func (c *ClaimBuilder) claim(pos types.Position, correct bool) common.Hash { - if correct { - return c.CorrectClaimAtPosition(pos) - } else { - return c.incorrectClaim(pos) - } -} - -func (c *ClaimBuilder) CreateRootClaim(correct bool) types.Claim { - value := c.claim(types.NewPositionFromGIndex(big.NewInt(1)), correct) +func (c *ClaimBuilder) claim(pos types.Position, opts ...ClaimOpt) types.Claim { + cfg := newClaimCfg(opts...) claim := types.Claim{ ClaimData: types.ClaimData{ - Value: value, - Position: types.NewPosition(0, common.Big0), + Position: pos, }, + Claimant: DefaultClaimant, + } + if cfg.claimant != (common.Address{}) { + claim.Claimant = cfg.claimant + } + if cfg.value != (common.Hash{}) { + claim.Value = cfg.value + } else if cfg.invalidValue { + claim.Value = c.incorrectClaim(pos) + } else { + claim.Value = c.CorrectClaimAtPosition(pos) } + claim.ParentContractIndex = cfg.parentIdx return claim } -func (c *ClaimBuilder) CreateLeafClaim(traceIndex *big.Int, correct bool) types.Claim { - pos := types.NewPosition(c.maxDepth, traceIndex) - return types.Claim{ - ClaimData: types.ClaimData{ - Value: c.claim(pos, correct), - Position: pos, - }, - } +func (c *ClaimBuilder) CreateRootClaim(opts ...ClaimOpt) types.Claim { + pos := types.NewPositionFromGIndex(big.NewInt(1)) + return c.claim(pos, opts...) } -func (c *ClaimBuilder) AttackClaim(claim types.Claim, correct bool) types.Claim { - pos := claim.Position.Attack() - return types.Claim{ - ClaimData: types.ClaimData{ - Value: c.claim(pos, correct), - Position: pos, - }, - ParentContractIndex: claim.ContractIndex, - } +func (c *ClaimBuilder) CreateLeafClaim(traceIndex *big.Int, opts ...ClaimOpt) types.Claim { + pos := types.NewPosition(c.maxDepth, traceIndex) + return c.claim(pos, opts...) } -func (c *ClaimBuilder) AttackClaimWithValue(claim types.Claim, value common.Hash) types.Claim { +func (c *ClaimBuilder) AttackClaim(claim types.Claim, opts ...ClaimOpt) types.Claim { pos := claim.Position.Attack() - return types.Claim{ - ClaimData: types.ClaimData{ - Value: value, - Position: pos, - }, - ParentContractIndex: claim.ContractIndex, - } + return c.claim(pos, append([]ClaimOpt{WithParent(claim)}, opts...)...) } -func (c *ClaimBuilder) DefendClaim(claim types.Claim, correct bool) types.Claim { +func (c *ClaimBuilder) DefendClaim(claim types.Claim, opts ...ClaimOpt) types.Claim { pos := claim.Position.Defend() - return types.Claim{ - ClaimData: types.ClaimData{ - Value: c.claim(pos, correct), - Position: pos, - }, - ParentContractIndex: claim.ContractIndex, - } -} - -func (c *ClaimBuilder) DefendClaimWithValue(claim types.Claim, value common.Hash) types.Claim { - pos := claim.Position.Defend() - return types.Claim{ - ClaimData: types.ClaimData{ - Value: value, - Position: pos, - }, - ParentContractIndex: claim.ContractIndex, - } + return c.claim(pos, append([]ClaimOpt{WithParent(claim)}, opts...)...) } diff --git a/op-challenger/game/fault/test/game_builder.go b/op-challenger/game/fault/test/game_builder.go index c474b393daf8..331d59c60be0 100644 --- a/op-challenger/game/fault/test/game_builder.go +++ b/op-challenger/game/fault/test/game_builder.go @@ -2,23 +2,30 @@ package test import ( "math/big" + "testing" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum/go-ethereum/common" ) type GameBuilder struct { - builder *ClaimBuilder - Game types.Game - ExpectedActions []types.Action - agreeWithOutputRoot bool + builder *ClaimBuilder + Game types.Game + ExpectedActions []types.Action } -func (c *ClaimBuilder) GameBuilder(agreeWithOutputRoot bool, rootCorrect bool) *GameBuilder { +func NewGameBuilderFromGame(t *testing.T, provider types.TraceProvider, game types.Game) *GameBuilder { + claimBuilder := NewClaimBuilder(t, game.MaxDepth(), provider) return &GameBuilder{ - builder: c, - agreeWithOutputRoot: agreeWithOutputRoot, - Game: types.NewGameState(agreeWithOutputRoot, []types.Claim{c.CreateRootClaim(rootCorrect)}, uint64(c.maxDepth)), + builder: claimBuilder, + Game: types.NewGameState(game.Claims(), game.MaxDepth()), + } +} + +func (c *ClaimBuilder) GameBuilder(rootOpts ...ClaimOpt) *GameBuilder { + return &GameBuilder{ + builder: c, + Game: types.NewGameState([]types.Claim{c.CreateRootClaim(rootOpts...)}, c.maxDepth), } } @@ -29,23 +36,39 @@ type GameBuilderSeq struct { } func (g *GameBuilder) Seq() *GameBuilderSeq { + return g.SeqFrom(g.Game.Claims()[0]) +} + +func (g *GameBuilder) SeqFrom(claim types.Claim) *GameBuilderSeq { return &GameBuilderSeq{ gameBuilder: g, builder: g.builder, - lastClaim: g.Game.Claims()[0], + lastClaim: claim, } } +func (g *GameBuilderSeq) IsMaxDepth() bool { + return g.lastClaim.Depth() == g.gameBuilder.Game.MaxDepth() +} + +func (g *GameBuilderSeq) IsRoot() bool { + return g.lastClaim.IsRoot() +} + // addClaimToGame replaces the game being built with a new instance that has claim as the latest claim. // The ContractIndex in claim is updated with its position in the game's claim array. +// Does nothing if the claim already exists func (s *GameBuilderSeq) addClaimToGame(claim *types.Claim) { + if s.gameBuilder.Game.IsDuplicate(*claim) { + return + } claim.ContractIndex = len(s.gameBuilder.Game.Claims()) claims := append(s.gameBuilder.Game.Claims(), *claim) - s.gameBuilder.Game = types.NewGameState(s.gameBuilder.agreeWithOutputRoot, claims, uint64(s.builder.maxDepth)) + s.gameBuilder.Game = types.NewGameState(claims, s.builder.maxDepth) } -func (s *GameBuilderSeq) AttackCorrect() *GameBuilderSeq { - claim := s.builder.AttackClaim(s.lastClaim, true) +func (s *GameBuilderSeq) Attack(opts ...ClaimOpt) *GameBuilderSeq { + claim := s.builder.AttackClaim(s.lastClaim, opts...) s.addClaimToGame(&claim) return &GameBuilderSeq{ gameBuilder: s.gameBuilder, @@ -54,8 +77,8 @@ func (s *GameBuilderSeq) AttackCorrect() *GameBuilderSeq { } } -func (s *GameBuilderSeq) Attack(value common.Hash) *GameBuilderSeq { - claim := s.builder.AttackClaimWithValue(s.lastClaim, value) +func (s *GameBuilderSeq) Defend(opts ...ClaimOpt) *GameBuilderSeq { + claim := s.builder.DefendClaim(s.lastClaim, opts...) s.addClaimToGame(&claim) return &GameBuilderSeq{ gameBuilder: s.gameBuilder, @@ -64,34 +87,26 @@ func (s *GameBuilderSeq) Attack(value common.Hash) *GameBuilderSeq { } } -func (s *GameBuilderSeq) DefendCorrect() *GameBuilderSeq { - claim := s.builder.DefendClaim(s.lastClaim, true) - s.addClaimToGame(&claim) - return &GameBuilderSeq{ - gameBuilder: s.gameBuilder, - builder: s.builder, - lastClaim: claim, - } -} - -func (s *GameBuilderSeq) Defend(value common.Hash) *GameBuilderSeq { - claim := s.builder.DefendClaimWithValue(s.lastClaim, value) - s.addClaimToGame(&claim) - return &GameBuilderSeq{ - gameBuilder: s.gameBuilder, - builder: s.builder, - lastClaim: claim, +func (s *GameBuilderSeq) Step(opts ...ClaimOpt) { + cfg := newClaimCfg(opts...) + claimant := DefaultClaimant + if cfg.claimant != (common.Address{}) { + claimant = cfg.claimant } + claims := s.gameBuilder.Game.Claims() + claims[len(claims)-1].CounteredBy = claimant + s.gameBuilder.Game = types.NewGameState(claims, s.builder.maxDepth) } func (s *GameBuilderSeq) ExpectAttack() *GameBuilderSeq { newPos := s.lastClaim.Position.Attack() value := s.builder.CorrectClaimAtPosition(newPos) s.gameBuilder.ExpectedActions = append(s.gameBuilder.ExpectedActions, types.Action{ - Type: types.ActionTypeMove, - ParentIdx: s.lastClaim.ContractIndex, - IsAttack: true, - Value: value, + Type: types.ActionTypeMove, + ParentIdx: s.lastClaim.ContractIndex, + ParentPosition: s.lastClaim.Position, + IsAttack: true, + Value: value, }) return s } @@ -100,10 +115,11 @@ func (s *GameBuilderSeq) ExpectDefend() *GameBuilderSeq { newPos := s.lastClaim.Position.Defend() value := s.builder.CorrectClaimAtPosition(newPos) s.gameBuilder.ExpectedActions = append(s.gameBuilder.ExpectedActions, types.Action{ - Type: types.ActionTypeMove, - ParentIdx: s.lastClaim.ContractIndex, - IsAttack: false, - Value: value, + Type: types.ActionTypeMove, + ParentIdx: s.lastClaim.ContractIndex, + ParentPosition: s.lastClaim.Position, + IsAttack: false, + Value: value, }) return s } @@ -111,12 +127,13 @@ func (s *GameBuilderSeq) ExpectDefend() *GameBuilderSeq { func (s *GameBuilderSeq) ExpectStepAttack() *GameBuilderSeq { traceIdx := s.lastClaim.TraceIndex(s.builder.maxDepth) s.gameBuilder.ExpectedActions = append(s.gameBuilder.ExpectedActions, types.Action{ - Type: types.ActionTypeStep, - ParentIdx: s.lastClaim.ContractIndex, - IsAttack: true, - PreState: s.builder.CorrectPreState(traceIdx), - ProofData: s.builder.CorrectProofData(traceIdx), - OracleData: s.builder.CorrectOracleData(traceIdx), + Type: types.ActionTypeStep, + ParentIdx: s.lastClaim.ContractIndex, + ParentPosition: s.lastClaim.Position, + IsAttack: true, + PreState: s.builder.CorrectPreState(traceIdx), + ProofData: s.builder.CorrectProofData(traceIdx), + OracleData: s.builder.CorrectOracleData(traceIdx), }) return s } @@ -124,12 +141,13 @@ func (s *GameBuilderSeq) ExpectStepAttack() *GameBuilderSeq { func (s *GameBuilderSeq) ExpectStepDefend() *GameBuilderSeq { traceIdx := new(big.Int).Add(s.lastClaim.TraceIndex(s.builder.maxDepth), big.NewInt(1)) s.gameBuilder.ExpectedActions = append(s.gameBuilder.ExpectedActions, types.Action{ - Type: types.ActionTypeStep, - ParentIdx: s.lastClaim.ContractIndex, - IsAttack: false, - PreState: s.builder.CorrectPreState(traceIdx), - ProofData: s.builder.CorrectProofData(traceIdx), - OracleData: s.builder.CorrectOracleData(traceIdx), + Type: types.ActionTypeStep, + ParentIdx: s.lastClaim.ContractIndex, + ParentPosition: s.lastClaim.Position, + IsAttack: false, + PreState: s.builder.CorrectPreState(traceIdx), + ProofData: s.builder.CorrectProofData(traceIdx), + OracleData: s.builder.CorrectOracleData(traceIdx), }) return s } diff --git a/op-challenger/game/fault/test/seq_builder.go b/op-challenger/game/fault/test/seq_builder.go index 1a02b9b52dbe..4863604b6ed9 100644 --- a/op-challenger/game/fault/test/seq_builder.go +++ b/op-challenger/game/fault/test/seq_builder.go @@ -12,24 +12,24 @@ type SequenceBuilder struct { // Seq starts building a claim by following a sequence of attack and defend moves from the root // The returned SequenceBuilder can be used to add additional moves. e.g: // claim := Seq(true).Attack(false).Attack(true).Defend(true).Get() -func (c *ClaimBuilder) Seq(rootCorrect bool) *SequenceBuilder { - claim := c.CreateRootClaim(rootCorrect) +func (c *ClaimBuilder) Seq(rootOpts ...ClaimOpt) *SequenceBuilder { + claim := c.CreateRootClaim(rootOpts...) return &SequenceBuilder{ builder: c, lastClaim: claim, } } -func (s *SequenceBuilder) Attack(correct bool) *SequenceBuilder { - claim := s.builder.AttackClaim(s.lastClaim, correct) +func (s *SequenceBuilder) Attack(opts ...ClaimOpt) *SequenceBuilder { + claim := s.builder.AttackClaim(s.lastClaim, opts...) return &SequenceBuilder{ builder: s.builder, lastClaim: claim, } } -func (s *SequenceBuilder) Defend(correct bool) *SequenceBuilder { - claim := s.builder.DefendClaim(s.lastClaim, correct) +func (s *SequenceBuilder) Defend(opts ...ClaimOpt) *SequenceBuilder { + claim := s.builder.DefendClaim(s.lastClaim, opts...) return &SequenceBuilder{ builder: s.builder, lastClaim: claim, diff --git a/op-challenger/game/fault/trace/access.go b/op-challenger/game/fault/trace/access.go new file mode 100644 index 000000000000..be42b6d81232 --- /dev/null +++ b/op-challenger/game/fault/trace/access.go @@ -0,0 +1,43 @@ +package trace + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" +) + +func NewSimpleTraceAccessor(trace types.TraceProvider) *Accessor { + selector := func(_ context.Context, _ types.Game, _ types.Claim, _ types.Position) (types.TraceProvider, error) { + return trace, nil + } + return NewAccessor(selector) +} + +type ProviderSelector func(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (types.TraceProvider, error) + +func NewAccessor(selector ProviderSelector) *Accessor { + return &Accessor{selector} +} + +type Accessor struct { + selector ProviderSelector +} + +func (t *Accessor) Get(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (common.Hash, error) { + provider, err := t.selector(ctx, game, ref, pos) + if err != nil { + return common.Hash{}, err + } + return provider.Get(ctx, pos) +} + +func (t *Accessor) GetStepData(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) { + provider, err := t.selector(ctx, game, ref, pos) + if err != nil { + return nil, nil, nil, err + } + return provider.GetStepData(ctx, pos) +} + +var _ types.TraceAccessor = (*Accessor)(nil) diff --git a/op-challenger/game/fault/trace/access_test.go b/op-challenger/game/fault/trace/access_test.go new file mode 100644 index 000000000000..df63cabcf587 --- /dev/null +++ b/op-challenger/game/fault/trace/access_test.go @@ -0,0 +1,70 @@ +package trace + +import ( + "context" + "fmt" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/stretchr/testify/require" +) + +func TestAccessor_UsesSelector(t *testing.T) { + ctx := context.Background() + depth := types.Depth(4) + provider1 := test.NewAlphabetWithProofProvider(t, big.NewInt(0), depth, nil) + provider2 := alphabet.NewTraceProvider(big.NewInt(0), depth) + claim := types.Claim{} + game := types.NewGameState([]types.Claim{claim}, depth) + pos1 := types.NewPositionFromGIndex(big.NewInt(4)) + pos2 := types.NewPositionFromGIndex(big.NewInt(6)) + + accessor := &Accessor{ + selector: func(ctx context.Context, actualGame types.Game, ref types.Claim, pos types.Position) (types.TraceProvider, error) { + require.Equal(t, game, actualGame) + require.Equal(t, claim, ref) + + if pos == pos1 { + return provider1, nil + } else if pos == pos2 { + return provider2, nil + } + return nil, fmt.Errorf("incorrect position requested: %v", pos) + }, + } + + t.Run("Get", func(t *testing.T) { + actual, err := accessor.Get(ctx, game, claim, pos1) + require.NoError(t, err) + expected, err := provider1.Get(ctx, pos1) + require.NoError(t, err) + require.Equal(t, expected, actual) + + actual, err = accessor.Get(ctx, game, claim, pos2) + require.NoError(t, err) + expected, err = provider2.Get(ctx, pos2) + require.NoError(t, err) + require.Equal(t, expected, actual) + }) + + t.Run("GetStepData", func(t *testing.T) { + actualPrestate, actualProofData, actualPreimageData, err := accessor.GetStepData(ctx, game, claim, pos1) + require.NoError(t, err) + expectedPrestate, expectedProofData, expectedPreimageData, err := provider1.GetStepData(ctx, pos1) + require.NoError(t, err) + require.Equal(t, expectedPrestate, actualPrestate) + require.Equal(t, expectedProofData, actualProofData) + require.Equal(t, expectedPreimageData, actualPreimageData) + + actualPrestate, actualProofData, actualPreimageData, err = accessor.GetStepData(ctx, game, claim, pos2) + require.NoError(t, err) + expectedPrestate, expectedProofData, expectedPreimageData, err = provider2.GetStepData(ctx, pos2) + require.NoError(t, err) + require.Equal(t, expectedPrestate, actualPrestate) + require.Equal(t, expectedProofData, actualProofData) + require.Equal(t, expectedPreimageData, actualPreimageData) + }) +} diff --git a/op-challenger/game/fault/trace/alphabet/prestate.go b/op-challenger/game/fault/trace/alphabet/prestate.go new file mode 100644 index 000000000000..0820b689122e --- /dev/null +++ b/op-challenger/game/fault/trace/alphabet/prestate.go @@ -0,0 +1,29 @@ +package alphabet + +import ( + "context" + "math/big" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +var absolutePrestate = common.FromHex("0000000000000000000000000000000000000000000000000000000000000060") +var absolutePrestateInt = new(big.Int).SetBytes(absolutePrestate) + +var _ types.PrestateProvider = (*alphabetPrestateProvider)(nil) + +// PrestateProvider provides the alphabet VM prestate +var PrestateProvider = &alphabetPrestateProvider{} + +// alphabetPrestateProvider is a stateless [PrestateProvider] that +// uses a pre-determined, fixed pre-state hash. +type alphabetPrestateProvider struct{} + +func (ap *alphabetPrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { + hash := common.BytesToHash(crypto.Keccak256(absolutePrestate)) + hash[0] = mipsevm.VMStatusUnfinished + return hash, nil +} diff --git a/op-challenger/game/fault/trace/alphabet/prestate_test.go b/op-challenger/game/fault/trace/alphabet/prestate_test.go new file mode 100644 index 000000000000..bac7f46d2299 --- /dev/null +++ b/op-challenger/game/fault/trace/alphabet/prestate_test.go @@ -0,0 +1,17 @@ +package alphabet + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestAlphabetPrestateProvider_AbsolutePreStateCommitment_Succeeds(t *testing.T) { + provider := alphabetPrestateProvider{} + hash, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + expected := common.HexToHash("0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98") + require.Equal(t, expected, hash) +} diff --git a/op-challenger/game/fault/trace/alphabet/provider.go b/op-challenger/game/fault/trace/alphabet/provider.go index 929764250736..6cae7154ed76 100644 --- a/op-challenger/game/fault/trace/alphabet/provider.go +++ b/op-challenger/game/fault/trace/alphabet/provider.go @@ -3,63 +3,71 @@ package alphabet import ( "context" "errors" + "fmt" "math/big" - "strings" + + preimage "github.com/ethereum-optimism/optimism/op-preimage" "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" ) +const ( + L2ClaimBlockNumberLocalIndex = 4 +) + var ( ErrIndexTooLarge = errors.New("index is larger than the maximum index") ) -// AlphabetTraceProvider is a [TraceProvider] that provides claims for specific -// indices in the given trace. +var _ types.TraceProvider = (*AlphabetTraceProvider)(nil) + +// AlphabetTraceProvider is a [TraceProvider] that monotonically increments +// the starting l2 block number as the claim value. type AlphabetTraceProvider struct { - state []string - depth uint64 - maxLen uint64 + alphabetPrestateProvider + startingBlockNumber *big.Int + depth types.Depth + maxLen uint64 } // NewTraceProvider returns a new [AlphabetProvider]. -func NewTraceProvider(state string, depth uint64) *AlphabetTraceProvider { +func NewTraceProvider(startingBlockNumber *big.Int, depth types.Depth) *AlphabetTraceProvider { return &AlphabetTraceProvider{ - state: strings.Split(state, ""), - depth: depth, - maxLen: uint64(1 << depth), + startingBlockNumber: startingBlockNumber, + depth: depth, + maxLen: 1 << depth, } } -func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, i types.Position) ([]byte, []byte, *types.PreimageOracleData, error) { - traceIndex := i.TraceIndex(int(ap.depth)) +func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, pos types.Position) ([]byte, []byte, *types.PreimageOracleData, error) { + traceIndex := pos.TraceIndex(ap.depth) + key := preimage.LocalIndexKey(L2ClaimBlockNumberLocalIndex).PreimageKey() + preimageData := types.NewPreimageOracleData(key[:], ap.startingBlockNumber.Bytes(), 0) if traceIndex.Cmp(common.Big0) == 0 { - prestate, err := ap.AbsolutePreState(ctx) - if err != nil { - return nil, nil, nil, err - } - return prestate, []byte{}, nil, nil - } - // We want the pre-state which is the value prior to the one requested - traceIndex = traceIndex.Sub(traceIndex, big.NewInt(1)) - // The index cannot be larger than the maximum index as computed by the depth. - if traceIndex.Cmp(big.NewInt(int64(ap.maxLen))) >= 0 { - return nil, nil, nil, ErrIndexTooLarge + return absolutePrestate, []byte{}, preimageData, nil } - // We extend the deepest hash to the maximum depth if the trace is not expansive. - if traceIndex.Cmp(big.NewInt(int64(len(ap.state)))) >= 0 { - return ap.GetStepData(ctx, types.NewPosition(int(ap.depth), big.NewInt(int64(len(ap.state))))) + if traceIndex.Cmp(new(big.Int).SetUint64(ap.maxLen)) > 0 { + return nil, nil, nil, fmt.Errorf("%w depth: %v index: %v max: %v", ErrIndexTooLarge, ap.depth, traceIndex, ap.maxLen) } - return BuildAlphabetPreimage(traceIndex, ap.state[traceIndex.Uint64()]), []byte{}, nil, nil + initialTraceIndex := new(big.Int).Lsh(ap.startingBlockNumber, 4) + initialClaim := new(big.Int).Add(absolutePrestateInt, initialTraceIndex) + newTraceIndex := new(big.Int).Add(initialTraceIndex, traceIndex) + newClaim := new(big.Int).Add(initialClaim, traceIndex) + return BuildAlphabetPreimage(newTraceIndex, newClaim), []byte{}, preimageData, nil } // Get returns the claim value at the given index in the trace. func (ap *AlphabetTraceProvider) Get(ctx context.Context, i types.Position) (common.Hash, error) { + if i.Depth() > ap.depth { + return common.Hash{}, fmt.Errorf("%w depth: %v max: %v", ErrIndexTooLarge, i.Depth(), ap.depth) + } // Step data returns the pre-state, so add 1 to get the state for index i - ti := i.TraceIndex(int(ap.depth)) - postPosition := types.NewPosition(int(ap.depth), new(big.Int).Add(ti, big.NewInt(1))) + ti := i.TraceIndex(ap.depth) + postPosition := types.NewPosition(ap.depth, new(big.Int).Add(ti, big.NewInt(1))) claimBytes, _, _, err := ap.GetStepData(ctx, postPosition) if err != nil { return common.Hash{}, err @@ -67,24 +75,9 @@ func (ap *AlphabetTraceProvider) Get(ctx context.Context, i types.Position) (com return alphabetStateHash(claimBytes), nil } -// AbsolutePreState returns the absolute pre-state for the alphabet trace. -func (ap *AlphabetTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, error) { - return common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000060"), nil -} - -func (ap *AlphabetTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (common.Hash, error) { - prestate, err := ap.AbsolutePreState(ctx) - if err != nil { - return common.Hash{}, err - } - hash := common.BytesToHash(crypto.Keccak256(prestate)) - hash[0] = mipsevm.VMStatusUnfinished - return hash, nil -} - -// BuildAlphabetPreimage constructs the claim bytes for the index and state item. -func BuildAlphabetPreimage(i *big.Int, letter string) []byte { - return append(i.FillBytes(make([]byte, 32)), LetterToBytes(letter)...) +// BuildAlphabetPreimage constructs the claim bytes for the index and claim. +func BuildAlphabetPreimage(traceIndex *big.Int, claim *big.Int) []byte { + return append(traceIndex.FillBytes(make([]byte, 32)), claim.FillBytes(make([]byte, 32))...) } func alphabetStateHash(state []byte) common.Hash { @@ -92,10 +85,3 @@ func alphabetStateHash(state []byte) common.Hash { h[0] = mipsevm.VMStatusInvalid return h } - -// LetterToBytes converts a letter to a 32 byte array -func LetterToBytes(letter string) []byte { - out := make([]byte, 32) - out[31] = byte(letter[0]) - return out -} diff --git a/op-challenger/game/fault/trace/alphabet/provider_test.go b/op-challenger/game/fault/trace/alphabet/provider_test.go index e3ec3cc3dce9..5ef68b822bf8 100644 --- a/op-challenger/game/fault/trace/alphabet/provider_test.go +++ b/op-challenger/game/fault/trace/alphabet/provider_test.go @@ -2,23 +2,75 @@ package alphabet import ( "context" + "fmt" "math/big" "testing" + preimage "github.com/ethereum-optimism/optimism/op-preimage" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) -func alphabetClaim(index *big.Int, letter string) common.Hash { - return alphabetStateHash(BuildAlphabetPreimage(index, letter)) +func alphabetClaim(index *big.Int, claim *big.Int) common.Hash { + return alphabetStateHash(BuildAlphabetPreimage(index, claim)) } -// TestAlphabetProvider_Get_ClaimsByTraceIndex tests the [fault.AlphabetProvider] Get function. +func TestAlphabetProvider_Prestate(t *testing.T) { + depth := types.Depth(4) + startingL2BlockNumber := big.NewInt(2) + + // Actual preimage values generated by the solidity AlphabetVM at each step. + expectedPrestates := []string{ + "0000000000000000000000000000000000000000000000000000000000000060", + "00000000000000000000000000000000000000000000000000000000000000210000000000000000000000000000000000000000000000000000000000000081", + "00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000082", + "00000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000083", + "00000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000084", + "00000000000000000000000000000000000000000000000000000000000000250000000000000000000000000000000000000000000000000000000000000085", + } + + ap := NewTraceProvider(startingL2BlockNumber, depth) + + for i, expected := range expectedPrestates { + i, expected := i, expected + t.Run(fmt.Sprintf("Step_%v", i), func(t *testing.T) { + result, _, _, err := ap.GetStepData(context.Background(), types.NewPosition(4, big.NewInt(int64(i)))) + require.NoError(t, err) + require.Equalf(t, expected, common.Bytes2Hex(result), "Incorrect prestate at trace index %v", i) + }) + } +} + +func TestAlphabetProvider_GetStepData_MaxLen(t *testing.T) { + depth := types.Depth(4) + startingL2BlockNumber := big.NewInt(2) + ap := NewTraceProvider(startingL2BlockNumber, depth) + + // Step data for the max position is allowed + maxLen := int64(1 << depth) + maxPos := types.NewPosition(4, big.NewInt(maxLen)) + result, _, _, err := ap.GetStepData(context.Background(), maxPos) + require.NoError(t, err) + expected := "00000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000090" + require.Equal(t, expected, common.Bytes2Hex(result)) + + // Cannot step on a position greater than the max. + oobPos := types.NewPosition(4, big.NewInt(int64(1< 0 { - // TODO(client-pod#104): Replace the LocalContext `0` argument below with the correct local context. - oracleData = types.NewPreimageOracleData(0, proof.OracleKey, proof.OracleValue, proof.OracleOffset) + oracleData, err := p.preimageLoader.LoadPreimage(proof) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to load preimage: %w", err) } return value, data, oracleData, nil } -func (p *CannonTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, error) { +func (p *CannonTraceProvider) absolutePreState() ([]byte, error) { state, err := parseState(p.prestate) if err != nil { return nil, fmt.Errorf("cannot load absolute pre-state: %w", err) @@ -137,8 +123,8 @@ func (p *CannonTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, err return state.EncodeWitness(), nil } -func (p *CannonTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (common.Hash, error) { - state, err := p.AbsolutePreState(ctx) +func (p *CannonTraceProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { + state, err := p.absolutePreState() if err != nil { return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) } @@ -175,9 +161,9 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*proofDa file, err = ioutil.OpenDecompressed(path) if errors.Is(err, os.ErrNotExist) { // Expected proof wasn't generated, check if we reached the end of execution - state, err := parseState(filepath.Join(p.dir, finalState)) + state, err := p.finalState() if err != nil { - return nil, fmt.Errorf("cannot read final state: %w", err) + return nil, err } if state.Exited && state.Step <= i { p.logger.Warn("Requested proof was after the program exited", "proof", i, "last", state.Step) @@ -220,6 +206,14 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*proofDa return &proof, nil } +func (c *CannonTraceProvider) finalState() (*mipsevm.State, error) { + state, err := parseState(filepath.Join(c.dir, finalState)) + if err != nil { + return nil, fmt.Errorf("cannot read final state: %w", err) + } + return state, nil +} + type diskStateCacheObj struct { Step uint64 `json:"step"` } @@ -251,3 +245,69 @@ func writeLastStep(dir string, proof *proofData, step uint64) error { } return nil } + +// CannonTraceProviderForTest is a CannonTraceProvider that can find the step referencing the preimage read +// Only to be used for testing +type CannonTraceProviderForTest struct { + *CannonTraceProvider +} + +type preimageOpts []string + +type PreimageOpt func() preimageOpts + +func PreimageLoad(key preimage.Key, offset uint32) PreimageOpt { + return func() preimageOpts { + return []string{"--stop-at-preimage", fmt.Sprintf("%v@%v", common.Hash(key.PreimageKey()).Hex(), offset)} + } +} + +func FirstPreimageLoadOfType(preimageType string) PreimageOpt { + return func() preimageOpts { + return []string{"--stop-at-preimage-type", preimageType} + } +} + +func FirstKeccakPreimageLoad() PreimageOpt { + return FirstPreimageLoadOfType("keccak") +} + +func FirstPrecompilePreimageLoad() PreimageOpt { + return FirstPreimageLoadOfType("precompile") +} + +func PreimageLargerThan(size int) PreimageOpt { + return func() preimageOpts { + return []string{"--stop-at-preimage-larger-than", strconv.Itoa(size)} + } +} + +func NewTraceProviderForTest(logger log.Logger, m CannonMetricer, cfg *config.Config, localInputs LocalGameInputs, dir string, gameDepth types.Depth) *CannonTraceProviderForTest { + p := &CannonTraceProvider{ + logger: logger, + dir: dir, + prestate: cfg.CannonAbsolutePreState, + generator: NewExecutor(logger, m, cfg, localInputs), + gameDepth: gameDepth, + preimageLoader: newPreimageLoader(kvstore.NewDiskKV(preimageDir(dir)).Get), + } + return &CannonTraceProviderForTest{p} +} + +func (p *CannonTraceProviderForTest) FindStep(ctx context.Context, start uint64, preimage PreimageOpt) (uint64, error) { + // Run cannon to find the step that meets the preimage conditions + if err := p.generator.(*Executor).generateProof(ctx, p.dir, start, math.MaxUint64, preimage()...); err != nil { + return 0, fmt.Errorf("generate cannon trace (until preimage read): %w", err) + } + // Load the step from the state cannon finished with + state, err := p.finalState() + if err != nil { + return 0, fmt.Errorf("failed to load final state: %w", err) + } + // Check we didn't get to the end of the trace without finding the preimage read we were looking for + if state.Exited { + return 0, fmt.Errorf("preimage read not found: %w", io.EOF) + } + // The state is the post-state so the step we want to execute to read the preimage is step - 1. + return state.Step - 1, nil +} diff --git a/op-challenger/game/fault/trace/cannon/provider_test.go b/op-challenger/game/fault/trace/cannon/provider_test.go index 30f926bf0ca3..a98b59adf6e8 100644 --- a/op-challenger/game/fault/trace/cannon/provider_test.go +++ b/op-challenger/game/fault/trace/cannon/provider_test.go @@ -25,7 +25,7 @@ import ( var testData embed.FS func PositionFromTraceIndex(provider *CannonTraceProvider, idx *big.Int) types.Position { - return types.NewPosition(int(provider.gameDepth), idx) + return types.NewPosition(provider.gameDepth, idx) } func TestGet(t *testing.T) { @@ -84,9 +84,9 @@ func TestGetStepData(t *testing.T) { provider, generator := setupWithTestData(t, dataDir, prestate) value, proof, data, err := provider.GetStepData(context.Background(), PositionFromTraceIndex(provider, new(big.Int))) require.NoError(t, err) - expected := common.Hex2Bytes("b8f068de604c85ea0e2acd437cdb47add074a2d70b81d018390c504b71fe26f400000000000000000000000000000000000000000000000000000000000000000000000000") + expected := common.FromHex("b8f068de604c85ea0e2acd437cdb47add074a2d70b81d018390c504b71fe26f400000000000000000000000000000000000000000000000000000000000000000000000000") require.Equal(t, expected, value) - expectedProof := common.Hex2Bytes("08028e3c0000000000000000000000003c01000a24210b7c00200008000000008fa40004") + expectedProof := common.FromHex("08028e3c0000000000000000000000003c01000a24210b7c00200008000000008fa40004") require.Equal(t, expectedProof, proof) // TODO: Need to add some oracle data require.Nil(t, data) @@ -124,7 +124,7 @@ func TestGetStepData(t *testing.T) { require.EqualValues(t, generator.proof.StateData, preimage) require.EqualValues(t, generator.proof.ProofData, proof) - expectedData := types.NewPreimageOracleData(0, generator.proof.OracleKey, generator.proof.OracleValue, generator.proof.OracleOffset) + expectedData := types.NewPreimageOracleData(generator.proof.OracleKey, generator.proof.OracleValue, generator.proof.OracleOffset) require.EqualValues(t, expectedData, data) }) @@ -207,65 +207,15 @@ func TestGetStepData(t *testing.T) { provider, generator := setupWithTestData(t, dataDir, prestate) value, proof, data, err := provider.GetStepData(context.Background(), PositionFromTraceIndex(provider, big.NewInt(2))) require.NoError(t, err) - expected := common.Hex2Bytes("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc") + expected := common.FromHex("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc") require.Equal(t, expected, value) - expectedProof := common.Hex2Bytes("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd") + expectedProof := common.FromHex("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd") require.Equal(t, expectedProof, proof) require.Empty(t, generator.generated) require.Nil(t, data) }) } -func TestAbsolutePreState(t *testing.T) { - dataDir := t.TempDir() - - prestate := "state.json" - - t.Run("StateUnavailable", func(t *testing.T) { - provider, _ := setupWithTestData(t, "/dir/does/not/exist", prestate) - _, err := provider.AbsolutePreState(context.Background()) - require.ErrorIs(t, err, os.ErrNotExist) - }) - - t.Run("InvalidStateFile", func(t *testing.T) { - setupPreState(t, dataDir, "invalid.json") - provider, _ := setupWithTestData(t, dataDir, prestate) - _, err := provider.AbsolutePreState(context.Background()) - require.ErrorContains(t, err, "invalid mipsevm state") - }) - - t.Run("ExpectedAbsolutePreState", func(t *testing.T) { - setupPreState(t, dataDir, "state.json") - provider, _ := setupWithTestData(t, dataDir, prestate) - preState, err := provider.AbsolutePreState(context.Background()) - require.NoError(t, err) - state := mipsevm.State{ - Memory: mipsevm.NewMemory(), - PreimageKey: common.HexToHash("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"), - PreimageOffset: 0, - PC: 0, - NextPC: 1, - LO: 0, - HI: 0, - Heap: 0, - ExitCode: 0, - Exited: false, - Step: 0, - Registers: [32]uint32{}, - } - require.Equal(t, []byte(state.EncodeWitness()), preState) - }) -} - -func setupPreState(t *testing.T, dataDir string, filename string) { - srcDir := filepath.Join("test_data") - path := filepath.Join(srcDir, filename) - file, err := testData.ReadFile(path) - require.NoErrorf(t, err, "reading %v", path) - err = os.WriteFile(filepath.Join(dataDir, "state.json"), file, 0o644) - require.NoErrorf(t, err, "writing %v", path) -} - func setupTestData(t *testing.T) (string, string) { srcDir := filepath.Join("test_data", "proofs") entries, err := testData.ReadDir(srcDir) @@ -285,7 +235,7 @@ func setupTestData(t *testing.T) (string, string) { func setupWithTestData(t *testing.T, dataDir string, prestate string) (*CannonTraceProvider, *stubGenerator) { generator := &stubGenerator{} return &CannonTraceProvider{ - logger: testlog.Logger(t, log.LvlInfo), + logger: testlog.Logger(t, log.LevelInfo), dir: dataDir, generator: generator, prestate: filepath.Join(dataDir, prestate), diff --git a/op-challenger/game/fault/trace/cannon/updater.go b/op-challenger/game/fault/trace/cannon/updater.go deleted file mode 100644 index f684689ce83f..000000000000 --- a/op-challenger/game/fault/trace/cannon/updater.go +++ /dev/null @@ -1,154 +0,0 @@ -package cannon - -import ( - "context" - "fmt" - "math/big" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-service/txmgr" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" -) - -// cannonUpdater is a [types.OracleUpdater] that exposes a method -// to update onchain cannon oracles with required data. -type cannonUpdater struct { - log log.Logger - txMgr txmgr.TxManager - - fdgAbi abi.ABI - fdgAddr common.Address - - preimageOracleAbi abi.ABI - preimageOracleAddr common.Address -} - -// NewOracleUpdater returns a new updater. The pre-image oracle address is loaded from the fault dispute game. -func NewOracleUpdater( - ctx context.Context, - logger log.Logger, - txMgr txmgr.TxManager, - fdgAddr common.Address, - client bind.ContractCaller, -) (*cannonUpdater, error) { - gameCaller, err := bindings.NewFaultDisputeGameCaller(fdgAddr, client) - if err != nil { - return nil, fmt.Errorf("create caller for game %v: %w", fdgAddr, err) - } - opts := &bind.CallOpts{Context: ctx} - vm, err := gameCaller.VM(opts) - if err != nil { - return nil, fmt.Errorf("failed to load VM address from game %v: %w", fdgAddr, err) - } - mipsCaller, err := bindings.NewMIPSCaller(vm, client) - if err != nil { - return nil, fmt.Errorf("failed to create MIPS caller for address %v: %w", vm, err) - } - oracleAddr, err := mipsCaller.Oracle(opts) - if err != nil { - return nil, fmt.Errorf("failed to load pre-image oracle address from game %v: %w", fdgAddr, err) - } - return NewOracleUpdaterWithOracle(logger, txMgr, fdgAddr, oracleAddr) -} - -// NewOracleUpdaterWithOracle returns a new updater using a specified pre-image oracle address. -func NewOracleUpdaterWithOracle( - logger log.Logger, - txMgr txmgr.TxManager, - fdgAddr common.Address, - preimageOracleAddr common.Address, -) (*cannonUpdater, error) { - fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() - if err != nil { - return nil, err - } - preimageOracleAbi, err := bindings.PreimageOracleMetaData.GetAbi() - if err != nil { - return nil, err - } - - return &cannonUpdater{ - log: logger, - txMgr: txMgr, - - fdgAbi: *fdgAbi, - fdgAddr: fdgAddr, - - preimageOracleAbi: *preimageOracleAbi, - preimageOracleAddr: preimageOracleAddr, - }, nil -} - -// UpdateOracle updates the oracle with the given data. -func (u *cannonUpdater) UpdateOracle(ctx context.Context, data *types.PreimageOracleData) error { - if data.IsLocal { - return u.sendLocalOracleData(ctx, data) - } - return u.sendGlobalOracleData(ctx, data) -} - -// sendLocalOracleData sends the local oracle data to the [txmgr]. -func (u *cannonUpdater) sendLocalOracleData(ctx context.Context, data *types.PreimageOracleData) error { - txData, err := u.BuildLocalOracleData(data) - if err != nil { - return fmt.Errorf("local oracle tx data build: %w", err) - } - return u.sendTxAndWait(ctx, u.fdgAddr, txData) -} - -// sendGlobalOracleData sends the global oracle data to the [txmgr]. -func (u *cannonUpdater) sendGlobalOracleData(ctx context.Context, data *types.PreimageOracleData) error { - txData, err := u.BuildGlobalOracleData(data) - if err != nil { - return fmt.Errorf("global oracle tx data build: %w", err) - } - return u.sendTxAndWait(ctx, u.fdgAddr, txData) -} - -// BuildLocalOracleData takes the local preimage key and data -// and creates tx data to load the key, data pair into the -// PreimageOracle contract from the FaultDisputeGame contract call. -func (u *cannonUpdater) BuildLocalOracleData(data *types.PreimageOracleData) ([]byte, error) { - return u.fdgAbi.Pack( - "addLocalData", - data.GetIdent(), - big.NewInt(int64(data.LocalContext)), - big.NewInt(int64(data.OracleOffset)), - ) -} - -// BuildGlobalOracleData takes the global preimage key and data -// and creates tx data to load the key, data pair into the -// PreimageOracle contract. -func (u *cannonUpdater) BuildGlobalOracleData(data *types.PreimageOracleData) ([]byte, error) { - return u.preimageOracleAbi.Pack( - "loadKeccak256PreimagePart", - big.NewInt(int64(data.OracleOffset)), - data.GetPreimageWithoutSize(), - ) -} - -// sendTxAndWait sends a transaction through the [txmgr] and waits for a receipt. -// This sets the tx GasLimit to 0, performing gas estimation online through the [txmgr]. -func (u *cannonUpdater) sendTxAndWait(ctx context.Context, addr common.Address, txData []byte) error { - receipt, err := u.txMgr.Send(ctx, txmgr.TxCandidate{ - To: &addr, - TxData: txData, - GasLimit: 0, - }) - if err != nil { - return err - } - if receipt.Status == ethtypes.ReceiptStatusFailed { - u.log.Error("Responder tx successfully published but reverted", "tx_hash", receipt.TxHash) - } else { - u.log.Debug("Responder tx successfully published", "tx_hash", receipt.TxHash) - } - return nil -} diff --git a/op-challenger/game/fault/trace/cannon/updater_test.go b/op-challenger/game/fault/trace/cannon/updater_test.go deleted file mode 100644 index 9dca886079cd..000000000000 --- a/op-challenger/game/fault/trace/cannon/updater_test.go +++ /dev/null @@ -1,146 +0,0 @@ -package cannon - -import ( - "context" - "errors" - "math/big" - "testing" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-service/testlog" - - "github.com/ethereum-optimism/optimism/op-service/txmgr" - "github.com/ethereum/go-ethereum" - ethtypes "github.com/ethereum/go-ethereum/core/types" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - - "github.com/stretchr/testify/require" -) - -var ( - mockFdgAddress = common.HexToAddress("0x1234") - mockPreimageOracleAddress = common.HexToAddress("0x12345") - mockSendError = errors.New("mock send error") -) - -type mockTxManager struct { - from common.Address - sends int - failedSends int - sendFails bool -} - -func (m *mockTxManager) Send(ctx context.Context, candidate txmgr.TxCandidate) (*ethtypes.Receipt, error) { - if m.sendFails { - m.failedSends++ - return nil, mockSendError - } - m.sends++ - return ethtypes.NewReceipt( - []byte{}, - false, - 0, - ), nil -} - -func (m *mockTxManager) Call(_ context.Context, _ ethereum.CallMsg, _ *big.Int) ([]byte, error) { - panic("not implemented") -} - -func (m *mockTxManager) BlockNumber(ctx context.Context) (uint64, error) { - panic("not implemented") -} - -func (m *mockTxManager) From() common.Address { - return m.from -} - -func newTestCannonUpdater(t *testing.T, sendFails bool) (*cannonUpdater, *mockTxManager) { - logger := testlog.Logger(t, log.LvlInfo) - txMgr := &mockTxManager{ - from: mockFdgAddress, - sendFails: sendFails, - } - updater, err := NewOracleUpdaterWithOracle(logger, txMgr, mockFdgAddress, mockPreimageOracleAddress) - require.NoError(t, err) - return updater, txMgr -} - -// TestCannonUpdater_UpdateOracle tests the [cannonUpdater] -// UpdateOracle function. -func TestCannonUpdater_UpdateOracle(t *testing.T) { - t.Run("succeeds", func(t *testing.T) { - updater, mockTxMgr := newTestCannonUpdater(t, false) - require.NoError(t, updater.UpdateOracle(context.Background(), &types.PreimageOracleData{ - OracleKey: common.Hash{0xaa}.Bytes(), - OracleData: common.Hex2Bytes("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"), - })) - require.Equal(t, 1, mockTxMgr.sends) - }) - - t.Run("send fails", func(t *testing.T) { - updater, mockTxMgr := newTestCannonUpdater(t, true) - require.Error(t, updater.UpdateOracle(context.Background(), &types.PreimageOracleData{ - OracleKey: common.Hash{0xaa}.Bytes(), - OracleData: common.Hex2Bytes("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"), - })) - require.Equal(t, 1, mockTxMgr.failedSends) - }) -} - -// TestCannonUpdater_BuildLocalOracleData tests the [cannonUpdater] -// builds a valid tx candidate for a local oracle update. -func TestCannonUpdater_BuildLocalOracleData(t *testing.T) { - updater, _ := newTestCannonUpdater(t, false) - oracleData := &types.PreimageOracleData{ - OracleKey: common.Hex2Bytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), - OracleData: common.Hex2Bytes("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"), - OracleOffset: 7, - } - - txData, err := updater.BuildLocalOracleData(oracleData) - require.NoError(t, err) - - fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() - require.NoError(t, err) - addLocalDataBytes4 := fdgAbi.Methods["addLocalData"].ID[:4] - - // Pack the tx data manually. - var expected []byte - expected = append(expected, addLocalDataBytes4...) - expected = append(expected, common.Hex2Bytes("00aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")...) - expected = append(expected, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")...) - expected = append(expected, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000007")...) - - require.Equal(t, expected, txData) -} - -// TestCannonUpdater_BuildGlobalOracleData tests the [cannonUpdater] -// builds a valid tx candidate for a global oracle update. -func TestCannonUpdater_BuildGlobalOracleData(t *testing.T) { - updater, _ := newTestCannonUpdater(t, false) - oracleData := &types.PreimageOracleData{ - OracleKey: common.Hex2Bytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), - OracleData: common.Hex2Bytes("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"), - OracleOffset: 7, - } - - txData, err := updater.BuildGlobalOracleData(oracleData) - require.NoError(t, err) - - var loadKeccak256PreimagePartBytes4 = crypto.Keccak256([]byte("loadKeccak256PreimagePart(uint256,bytes)"))[:4] - - // Pack the tx data manually. - var expected []byte - expected = append(expected, loadKeccak256PreimagePartBytes4...) - expected = append(expected, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000007")...) - expected = append(expected, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")...) - expected = append(expected, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000018")...) - expected = append(expected, common.Hex2Bytes("cccccccccccccccccccccccccccccccccccccccccccccccc0000000000000000")...) - - require.Equal(t, expected, txData) -} diff --git a/op-challenger/game/fault/trace/outputs/output_alphabet.go b/op-challenger/game/fault/trace/outputs/output_alphabet.go new file mode 100644 index 000000000000..22b0fc762f83 --- /dev/null +++ b/op-challenger/game/fault/trace/outputs/output_alphabet.go @@ -0,0 +1,35 @@ +package outputs + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/metrics" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +func NewOutputAlphabetTraceAccessor( + logger log.Logger, + m metrics.Metricer, + prestateProvider types.PrestateProvider, + rollupClient OutputRollupClient, + l1Head eth.BlockID, + splitDepth types.Depth, + prestateBlock uint64, + poststateBlock uint64, +) (*trace.Accessor, error) { + outputProvider := NewTraceProvider(logger, prestateProvider, rollupClient, l1Head, splitDepth, prestateBlock, poststateBlock) + alphabetCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) { + provider := alphabet.NewTraceProvider(agreed.L2BlockNumber, depth) + return provider, nil + } + cache := NewProviderCache(m, "output_alphabet_provider", alphabetCreator) + selector := split.NewSplitProviderSelector(outputProvider, splitDepth, OutputRootSplitAdapter(outputProvider, cache.GetOrCreate)) + return trace.NewAccessor(selector), nil +} diff --git a/op-challenger/game/fault/trace/outputs/output_cannon.go b/op-challenger/game/fault/trace/outputs/output_cannon.go new file mode 100644 index 000000000000..03c2bfb902e5 --- /dev/null +++ b/op-challenger/game/fault/trace/outputs/output_cannon.go @@ -0,0 +1,48 @@ +package outputs + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/ethereum-optimism/optimism/op-challenger/config" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/metrics" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +func NewOutputCannonTraceAccessor( + logger log.Logger, + m metrics.Metricer, + cfg *config.Config, + l2Client cannon.L2HeaderSource, + prestateProvider types.PrestateProvider, + rollupClient OutputRollupClient, + dir string, + l1Head eth.BlockID, + splitDepth types.Depth, + prestateBlock uint64, + poststateBlock uint64, +) (*trace.Accessor, error) { + outputProvider := NewTraceProvider(logger, prestateProvider, rollupClient, l1Head, splitDepth, prestateBlock, poststateBlock) + cannonCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) { + logger := logger.New("pre", agreed.OutputRoot, "post", claimed.OutputRoot, "localContext", localContext) + subdir := filepath.Join(dir, localContext.Hex()) + localInputs, err := cannon.FetchLocalInputsFromProposals(ctx, l1Head.Hash, l2Client, agreed, claimed) + if err != nil { + return nil, fmt.Errorf("failed to fetch cannon local inputs: %w", err) + } + provider := cannon.NewTraceProvider(logger, m, cfg, localInputs, subdir, depth) + return provider, nil + } + + cache := NewProviderCache(m, "output_cannon_provider", cannonCreator) + selector := split.NewSplitProviderSelector(outputProvider, splitDepth, OutputRootSplitAdapter(outputProvider, cache.GetOrCreate)) + return trace.NewAccessor(selector), nil +} diff --git a/op-challenger/game/fault/trace/outputs/prestate.go b/op-challenger/game/fault/trace/outputs/prestate.go new file mode 100644 index 000000000000..086cba796087 --- /dev/null +++ b/op-challenger/game/fault/trace/outputs/prestate.go @@ -0,0 +1,35 @@ +package outputs + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" +) + +var _ types.PrestateProvider = (*OutputPrestateProvider)(nil) + +type OutputPrestateProvider struct { + prestateBlock uint64 + rollupClient OutputRollupClient +} + +func NewPrestateProvider(rollupClient OutputRollupClient, prestateBlock uint64) *OutputPrestateProvider { + return &OutputPrestateProvider{ + prestateBlock: prestateBlock, + rollupClient: rollupClient, + } +} + +func (o *OutputPrestateProvider) AbsolutePreStateCommitment(ctx context.Context) (hash common.Hash, err error) { + return o.outputAtBlock(ctx, o.prestateBlock) +} + +func (o *OutputPrestateProvider) outputAtBlock(ctx context.Context, block uint64) (common.Hash, error) { + output, err := o.rollupClient.OutputAtBlock(ctx, block) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to fetch output at block %v: %w", block, err) + } + return common.Hash(output.OutputRoot), nil +} diff --git a/op-challenger/game/fault/trace/outputs/prestate_test.go b/op-challenger/game/fault/trace/outputs/prestate_test.go new file mode 100644 index 000000000000..0b497ee5e872 --- /dev/null +++ b/op-challenger/game/fault/trace/outputs/prestate_test.go @@ -0,0 +1,47 @@ +package outputs + +import ( + "context" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/stretchr/testify/require" +) + +func newOutputPrestateProvider(t *testing.T, prestateBlock uint64) (*OutputPrestateProvider, *stubRollupClient) { + rollupClient := &stubRollupClient{ + outputs: map[uint64]*eth.OutputResponse{ + prestateBlock: { + OutputRoot: eth.Bytes32(prestateOutputRoot), + }, + 101: { + OutputRoot: eth.Bytes32(firstOutputRoot), + }, + poststateBlock: { + OutputRoot: eth.Bytes32(poststateOutputRoot), + }, + }, + } + return &OutputPrestateProvider{ + rollupClient: rollupClient, + prestateBlock: prestateBlock, + }, rollupClient +} + +func TestAbsolutePreStateCommitment(t *testing.T) { + var prestateBlock = uint64(100) + + t.Run("FailedToFetchOutput", func(t *testing.T) { + provider, rollupClient := newOutputPrestateProvider(t, prestateBlock) + rollupClient.errorsOnPrestateFetch = true + _, err := provider.AbsolutePreStateCommitment(context.Background()) + require.ErrorIs(t, err, errNoOutputAtBlock) + }) + + t.Run("ReturnsCorrectPrestateOutput", func(t *testing.T) { + provider, _ := newOutputPrestateProvider(t, prestateBlock) + value, err := provider.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + require.Equal(t, value, prestateOutputRoot) + }) +} diff --git a/op-challenger/game/fault/trace/outputs/provider.go b/op-challenger/game/fault/trace/outputs/provider.go index 4d20c2a1e64a..d2da7fd45a52 100644 --- a/op-challenger/game/fault/trace/outputs/provider.go +++ b/op-challenger/game/fault/trace/outputs/provider.go @@ -2,88 +2,102 @@ package outputs import ( "context" + "errors" "fmt" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-service/dial" "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" ) var ( - GetStepDataErr = fmt.Errorf("GetStepData not supported") - AbsolutePreStateErr = fmt.Errorf("AbsolutePreState not supported") + ErrGetStepData = errors.New("GetStepData not supported") + ErrIndexTooBig = errors.New("trace index is greater than max uint64") ) var _ types.TraceProvider = (*OutputTraceProvider)(nil) type OutputRollupClient interface { OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) + SafeHeadAtL1Block(ctx context.Context, l1BlockNum uint64) (*eth.SafeHeadResponse, error) } // OutputTraceProvider is a [types.TraceProvider] implementation that uses // output roots for given L2 Blocks as a trace. type OutputTraceProvider struct { + types.PrestateProvider logger log.Logger - rollupClient OutputRollupClient + rollupProvider OutputRollupClient prestateBlock uint64 poststateBlock uint64 - gameDepth uint64 -} - -func NewTraceProvider(ctx context.Context, logger log.Logger, rollupRpc string, gameDepth, prestateBlock, poststateBlock uint64) (*OutputTraceProvider, error) { - rollupClient, err := dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, logger, rollupRpc) - if err != nil { - return nil, err - } - return NewTraceProviderFromInputs(logger, rollupClient, gameDepth, prestateBlock, poststateBlock), nil + l1Head eth.BlockID + gameDepth types.Depth } -func NewTraceProviderFromInputs(logger log.Logger, rollupClient OutputRollupClient, gameDepth, prestateBlock, poststateBlock uint64) *OutputTraceProvider { +func NewTraceProvider(logger log.Logger, prestateProvider types.PrestateProvider, rollupProvider OutputRollupClient, l1Head eth.BlockID, gameDepth types.Depth, prestateBlock, poststateBlock uint64) *OutputTraceProvider { return &OutputTraceProvider{ - logger: logger, - rollupClient: rollupClient, - prestateBlock: prestateBlock, - poststateBlock: poststateBlock, - gameDepth: gameDepth, + PrestateProvider: prestateProvider, + logger: logger, + rollupProvider: rollupProvider, + prestateBlock: prestateBlock, + poststateBlock: poststateBlock, + l1Head: l1Head, + gameDepth: gameDepth, } } -func (o *OutputTraceProvider) Get(ctx context.Context, pos types.Position) (common.Hash, error) { - traceIndex := pos.TraceIndex(int(o.gameDepth)) +// ClaimedBlockNumber returns the block number for a position restricted only by the claimed L2 block number. +// The returned block number may be after the safe head reached by processing batch data up to the game's L1 head +func (o *OutputTraceProvider) ClaimedBlockNumber(pos types.Position) (uint64, error) { + traceIndex := pos.TraceIndex(o.gameDepth) if !traceIndex.IsUint64() { - return common.Hash{}, fmt.Errorf("trace index %v is greater than max uint64", traceIndex) + return 0, fmt.Errorf("%w: %v", ErrIndexTooBig, traceIndex) } + outputBlock := traceIndex.Uint64() + o.prestateBlock + 1 if outputBlock > o.poststateBlock { outputBlock = o.poststateBlock } - output, err := o.rollupClient.OutputAtBlock(ctx, outputBlock) + return outputBlock, nil +} + +// HonestBlockNumber returns the block number for a position in the game restricted to the minimum of the claimed L2 +// block number or the safe head reached by processing batch data up to the game's L1 head. +// This is used when posting honest output roots to ensure that only roots supported by L1 data are posted +func (o *OutputTraceProvider) HonestBlockNumber(ctx context.Context, pos types.Position) (uint64, error) { + outputBlock, err := o.ClaimedBlockNumber(pos) if err != nil { - o.logger.Error("Failed to fetch output", "blockNumber", outputBlock, "err", err) - return common.Hash{}, err + return 0, err } - return common.Hash(output.OutputRoot), nil + resp, err := o.rollupProvider.SafeHeadAtL1Block(ctx, o.l1Head.Number) + if err != nil { + return 0, fmt.Errorf("failed to get safe head at L1 block %v: %w", o.l1Head, err) + } + maxSafeHead := resp.SafeHead.Number + if outputBlock > maxSafeHead { + outputBlock = maxSafeHead + } + return outputBlock, nil } -// AbsolutePreStateCommitment returns the absolute prestate at the configured prestateBlock. -func (o *OutputTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (hash common.Hash, err error) { - output, err := o.rollupClient.OutputAtBlock(ctx, o.prestateBlock) +func (o *OutputTraceProvider) Get(ctx context.Context, pos types.Position) (common.Hash, error) { + outputBlock, err := o.HonestBlockNumber(ctx, pos) if err != nil { - o.logger.Error("Failed to fetch output", "blockNumber", o.prestateBlock, "err", err) return common.Hash{}, err } - return common.Hash(output.OutputRoot), nil + return o.outputAtBlock(ctx, outputBlock) } -// AbsolutePreState is not supported in the [OutputTraceProvider]. -func (o *OutputTraceProvider) AbsolutePreState(ctx context.Context) (preimage []byte, err error) { - return nil, AbsolutePreStateErr +// GetStepData is not supported in the [OutputTraceProvider]. +func (o *OutputTraceProvider) GetStepData(_ context.Context, _ types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) { + return nil, nil, nil, ErrGetStepData } -// GetStepData is not supported in the [OutputTraceProvider]. -func (o *OutputTraceProvider) GetStepData(ctx context.Context, pos types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) { - return nil, nil, nil, GetStepDataErr +func (o *OutputTraceProvider) outputAtBlock(ctx context.Context, block uint64) (common.Hash, error) { + output, err := o.rollupProvider.OutputAtBlock(ctx, block) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to fetch output at block %v: %w", block, err) + } + return common.Hash(output.OutputRoot), nil } diff --git a/op-challenger/game/fault/trace/outputs/provider_cache.go b/op-challenger/game/fault/trace/outputs/provider_cache.go new file mode 100644 index 000000000000..ff694a45aedc --- /dev/null +++ b/op-challenger/game/fault/trace/outputs/provider_cache.go @@ -0,0 +1,36 @@ +package outputs + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-service/sources/caching" + "github.com/ethereum/go-ethereum/common" +) + +type ProviderCache struct { + cache *caching.LRUCache[common.Hash, types.TraceProvider] + creator ProposalTraceProviderCreator +} + +func (c *ProviderCache) GetOrCreate(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) { + provider, ok := c.cache.Get(localContext) + if ok { + return provider, nil + } + provider, err := c.creator(ctx, localContext, depth, agreed, claimed) + if err != nil { + return nil, err + } + c.cache.Add(localContext, provider) + return provider, nil +} + +func NewProviderCache(m caching.Metrics, metricsLabel string, creator ProposalTraceProviderCreator) *ProviderCache { + cache := caching.NewLRUCache[common.Hash, types.TraceProvider](m, metricsLabel, 100) + return &ProviderCache{ + cache: cache, + creator: creator, + } +} diff --git a/op-challenger/game/fault/trace/outputs/provider_cache_test.go b/op-challenger/game/fault/trace/outputs/provider_cache_test.go new file mode 100644 index 000000000000..edf869dcba99 --- /dev/null +++ b/op-challenger/game/fault/trace/outputs/provider_cache_test.go @@ -0,0 +1,77 @@ +package outputs + +import ( + "context" + "errors" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/metrics" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestProviderCache(t *testing.T) { + agreed := contracts.Proposal{ + L2BlockNumber: big.NewInt(34), + OutputRoot: common.Hash{0xaa}, + } + claimed := contracts.Proposal{ + L2BlockNumber: big.NewInt(35), + OutputRoot: common.Hash{0xcc}, + } + depth := types.Depth(6) + var createdProvider types.TraceProvider + creator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) { + createdProvider = alphabet.NewTraceProvider(big.NewInt(0), depth) + return createdProvider, nil + } + localContext1 := common.Hash{0xdd} + localContext2 := common.Hash{0xee} + + cache := NewProviderCache(metrics.NoopMetrics, "test", creator) + + // Create on first call + provider1, err := cache.GetOrCreate(context.Background(), localContext1, depth, agreed, claimed) + require.NoError(t, err) + require.Same(t, createdProvider, provider1, "should return created trace provider") + + // Return the cached provider on subsequent calls. + createdProvider = nil + cached, err := cache.GetOrCreate(context.Background(), localContext1, depth, agreed, claimed) + require.NoError(t, err) + require.Same(t, provider1, cached, "should return exactly the same instance from cache") + require.Nil(t, createdProvider) + + // Create a new provider when the local context is different + createdProvider = nil + otherProvider, err := cache.GetOrCreate(context.Background(), localContext2, depth, agreed, claimed) + require.NoError(t, err) + require.Same(t, otherProvider, createdProvider, "should return newly created trace provider") + require.NotSame(t, otherProvider, provider1, "should not use cached provider for different local context") +} + +func TestProviderCache_DoNotCacheErrors(t *testing.T) { + callCount := 0 + providerErr := errors.New("boom") + creator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) { + callCount++ + return nil, providerErr + } + localContext1 := common.Hash{0xdd} + + cache := NewProviderCache(metrics.NoopMetrics, "test", creator) + provider, err := cache.GetOrCreate(context.Background(), localContext1, 6, contracts.Proposal{}, contracts.Proposal{}) + require.Nil(t, provider) + require.ErrorIs(t, err, providerErr) + require.Equal(t, 1, callCount) + + // Should call the creator again on the second attempt + provider, err = cache.GetOrCreate(context.Background(), localContext1, 6, contracts.Proposal{}, contracts.Proposal{}) + require.Nil(t, provider) + require.ErrorIs(t, err, providerErr) + require.Equal(t, 2, callCount) +} diff --git a/op-challenger/game/fault/trace/outputs/provider_test.go b/op-challenger/game/fault/trace/outputs/provider_test.go index c84b7c859138..c4e154ff17c3 100644 --- a/op-challenger/game/fault/trace/outputs/provider_test.go +++ b/op-challenger/game/fault/trace/outputs/provider_test.go @@ -2,14 +2,15 @@ package outputs import ( "context" + "errors" "fmt" + "math" "math/big" "testing" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" @@ -18,44 +19,33 @@ import ( var ( prestateBlock = uint64(100) poststateBlock = uint64(200) - gameDepth = uint64(7) // 128 leaf nodes + gameDepth = types.Depth(7) // 128 leaf nodes prestateOutputRoot = common.HexToHash("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") firstOutputRoot = common.HexToHash("0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") poststateOutputRoot = common.HexToHash("0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc") + errNoOutputAtBlock = errors.New("no output at block") ) func TestGet(t *testing.T) { - t.Run("PrePrestateErrors", func(t *testing.T) { - provider, _ := setupWithTestData(t, 0, poststateBlock) - _, err := provider.Get(context.Background(), types.NewPosition(1, common.Big0)) - require.ErrorAs(t, fmt.Errorf("no output at block %d", 1), &err) - }) - t.Run("ErrorsTraceIndexOutOfBounds", func(t *testing.T) { - deepGame := uint64(64) + deepGame := types.Depth(164) provider, _ := setupWithTestData(t, prestateBlock, poststateBlock, deepGame) pos := types.NewPosition(0, big.NewInt(0)) _, err := provider.Get(context.Background(), pos) - require.ErrorAs(t, fmt.Errorf("trace index %v is greater than max uint64", pos.TraceIndex(int(deepGame))), &err) - }) - - t.Run("MisconfiguredPoststateErrors", func(t *testing.T) { - provider, _ := setupWithTestData(t, 0, 0) - _, err := provider.Get(context.Background(), types.NewPosition(1, common.Big0)) - require.ErrorAs(t, fmt.Errorf("no output at block %d", 0), &err) + require.ErrorIs(t, err, ErrIndexTooBig) }) t.Run("FirstBlockAfterPrestate", func(t *testing.T) { provider, _ := setupWithTestData(t, prestateBlock, poststateBlock) - value, err := provider.Get(context.Background(), types.NewPositionFromGIndex(big.NewInt(128))) + value, err := provider.Get(context.Background(), types.NewPosition(gameDepth, big.NewInt(0))) require.NoError(t, err) require.Equal(t, firstOutputRoot, value) }) t.Run("MissingOutputAtBlock", func(t *testing.T) { provider, _ := setupWithTestData(t, prestateBlock, poststateBlock) - _, err := provider.Get(context.Background(), types.NewPositionFromGIndex(big.NewInt(129))) - require.ErrorAs(t, fmt.Errorf("no output at block %d", prestateBlock+2), &err) + _, err := provider.Get(context.Background(), types.NewPosition(gameDepth, big.NewInt(1))) + require.ErrorIs(t, err, errNoOutputAtBlock) }) t.Run("PostStateBlock", func(t *testing.T) { @@ -73,36 +63,96 @@ func TestGet(t *testing.T) { }) } -func TestAbsolutePreStateCommitment(t *testing.T) { - t.Run("FailedToFetchOutput", func(t *testing.T) { - provider, rollupClient := setupWithTestData(t, prestateBlock, poststateBlock) - rollupClient.errorsOnPrestateFetch = true - _, err := provider.AbsolutePreStateCommitment(context.Background()) - require.ErrorAs(t, fmt.Errorf("no output at block %d", prestateBlock), &err) +func TestHonestBlockNumber(t *testing.T) { + tests := []struct { + name string + pos types.Position + expected uint64 + maxSafeHead uint64 + }{ + {"FirstBlockAfterPrestate", types.NewPosition(gameDepth, big.NewInt(0)), prestateBlock + 1, math.MaxUint64}, + {"PostStateBlock", types.NewPositionFromGIndex(big.NewInt(228)), poststateBlock, math.MaxUint64}, + {"AfterPostStateBlock", types.NewPositionFromGIndex(big.NewInt(229)), poststateBlock, math.MaxUint64}, + {"Root", types.NewPositionFromGIndex(big.NewInt(1)), poststateBlock, math.MaxUint64}, + {"MiddleNode1", types.NewPosition(gameDepth-1, big.NewInt(2)), 106, math.MaxUint64}, + {"MiddleNode2", types.NewPosition(gameDepth-1, big.NewInt(3)), 108, math.MaxUint64}, + {"Leaf1", types.NewPosition(gameDepth, big.NewInt(1)), prestateBlock + 2, math.MaxUint64}, + {"Leaf2", types.NewPosition(gameDepth, big.NewInt(2)), prestateBlock + 3, math.MaxUint64}, + + {"RestrictedHead-UnderLimit", types.NewPosition(gameDepth, big.NewInt(48)), prestateBlock + 49, prestateBlock + 50}, + {"RestrictedHead-EqualLimit", types.NewPosition(gameDepth, big.NewInt(49)), prestateBlock + 50, prestateBlock + 50}, + {"RestrictedHead-OverLimit", types.NewPosition(gameDepth, big.NewInt(50)), prestateBlock + 50, prestateBlock + 50}, + {"RestrictedHead-PastPostState", types.NewPosition(gameDepth, big.NewInt(1000)), prestateBlock + 50, prestateBlock + 50}, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + provider, stubRollupClient := setupWithTestData(t, prestateBlock, poststateBlock) + stubRollupClient.maxSafeHead = test.maxSafeHead + actual, err := provider.HonestBlockNumber(context.Background(), test.pos) + require.NoError(t, err) + require.Equal(t, test.expected, actual) + }) + } + + t.Run("ErrorsTraceIndexOutOfBounds", func(t *testing.T) { + deepGame := types.Depth(164) + provider, _ := setupWithTestData(t, prestateBlock, poststateBlock, deepGame) + pos := types.NewPosition(0, big.NewInt(0)) + _, err := provider.HonestBlockNumber(context.Background(), pos) + require.ErrorIs(t, err, ErrIndexTooBig) }) +} - t.Run("ReturnsCorrectPrestateOutput", func(t *testing.T) { - provider, _ := setupWithTestData(t, prestateBlock, poststateBlock) - value, err := provider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - require.Equal(t, value, prestateOutputRoot) +func TestClaimedBlockNumber(t *testing.T) { + tests := []struct { + name string + pos types.Position + expected uint64 + maxSafeHead uint64 + }{ + {"FirstBlockAfterPrestate", types.NewPosition(gameDepth, big.NewInt(0)), prestateBlock + 1, math.MaxUint64}, + {"PostStateBlock", types.NewPositionFromGIndex(big.NewInt(228)), poststateBlock, math.MaxUint64}, + {"AfterPostStateBlock", types.NewPositionFromGIndex(big.NewInt(229)), poststateBlock, math.MaxUint64}, + {"Root", types.NewPositionFromGIndex(big.NewInt(1)), poststateBlock, math.MaxUint64}, + {"MiddleNode1", types.NewPosition(gameDepth-1, big.NewInt(2)), 106, math.MaxUint64}, + {"MiddleNode2", types.NewPosition(gameDepth-1, big.NewInt(3)), 108, math.MaxUint64}, + {"Leaf1", types.NewPosition(gameDepth, big.NewInt(1)), prestateBlock + 2, math.MaxUint64}, + {"Leaf2", types.NewPosition(gameDepth, big.NewInt(2)), prestateBlock + 3, math.MaxUint64}, + + {"RestrictedHead-UnderLimit", types.NewPosition(gameDepth, big.NewInt(48)), prestateBlock + 49, prestateBlock + 50}, + {"RestrictedHead-EqualLimit", types.NewPosition(gameDepth, big.NewInt(49)), prestateBlock + 50, prestateBlock + 50}, + {"RestrictedHead-OverLimit", types.NewPosition(gameDepth, big.NewInt(50)), prestateBlock + 51, prestateBlock + 50}, + {"RestrictedHead-PastPostState", types.NewPosition(gameDepth, big.NewInt(300)), poststateBlock, prestateBlock + 50}, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + provider, stubRollupClient := setupWithTestData(t, prestateBlock, poststateBlock) + stubRollupClient.maxSafeHead = test.maxSafeHead + actual, err := provider.ClaimedBlockNumber(test.pos) + require.NoError(t, err) + require.Equal(t, test.expected, actual) + }) + } + + t.Run("ErrorsTraceIndexOutOfBounds", func(t *testing.T) { + deepGame := types.Depth(164) + provider, _ := setupWithTestData(t, prestateBlock, poststateBlock, deepGame) + pos := types.NewPosition(0, big.NewInt(0)) + _, err := provider.ClaimedBlockNumber(pos) + require.ErrorIs(t, err, ErrIndexTooBig) }) } func TestGetStepData(t *testing.T) { provider, _ := setupWithTestData(t, prestateBlock, poststateBlock) _, _, _, err := provider.GetStepData(context.Background(), types.NewPosition(1, common.Big0)) - require.ErrorIs(t, err, GetStepDataErr) + require.ErrorIs(t, err, ErrGetStepData) } -func TestAbsolutePreState(t *testing.T) { - provider, _ := setupWithTestData(t, prestateBlock, poststateBlock) - _, err := provider.AbsolutePreState(context.Background()) - require.ErrorIs(t, err, AbsolutePreStateErr) -} - -func setupWithTestData(t *testing.T, prestateBlock, poststateBlock uint64, customGameDepth ...uint64) (*OutputTraceProvider, *stubRollupClient) { - rollupClient := stubRollupClient{ +func setupWithTestData(t *testing.T, prestateBlock, poststateBlock uint64, customGameDepth ...types.Depth) (*OutputTraceProvider, *stubRollupClient) { + rollupClient := &stubRollupClient{ outputs: map[uint64]*eth.OutputResponse{ prestateBlock: { OutputRoot: eth.Bytes32(prestateOutputRoot), @@ -114,29 +164,40 @@ func setupWithTestData(t *testing.T, prestateBlock, poststateBlock uint64, custo OutputRoot: eth.Bytes32(poststateOutputRoot), }, }, + maxSafeHead: math.MaxUint64, } inputGameDepth := gameDepth if len(customGameDepth) > 0 { inputGameDepth = customGameDepth[0] } return &OutputTraceProvider{ - logger: testlog.Logger(t, log.LvlInfo), - rollupClient: &rollupClient, + logger: testlog.Logger(t, log.LevelInfo), + rollupProvider: rollupClient, prestateBlock: prestateBlock, poststateBlock: poststateBlock, gameDepth: inputGameDepth, - }, &rollupClient + }, rollupClient } type stubRollupClient struct { errorsOnPrestateFetch bool outputs map[uint64]*eth.OutputResponse + maxSafeHead uint64 } -func (s *stubRollupClient) OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) { +func (s *stubRollupClient) OutputAtBlock(_ context.Context, blockNum uint64) (*eth.OutputResponse, error) { output, ok := s.outputs[blockNum] if !ok || s.errorsOnPrestateFetch { - return nil, fmt.Errorf("no output at block %d", blockNum) + return nil, fmt.Errorf("%w: %d", errNoOutputAtBlock, blockNum) } return output, nil } + +func (s *stubRollupClient) SafeHeadAtL1Block(_ context.Context, l1BlockNum uint64) (*eth.SafeHeadResponse, error) { + return ð.SafeHeadResponse{ + SafeHead: eth.BlockID{ + Number: s.maxSafeHead, + Hash: common.Hash{0x11}, + }, + }, nil +} diff --git a/op-challenger/game/fault/trace/outputs/split_adapter.go b/op-challenger/game/fault/trace/outputs/split_adapter.go new file mode 100644 index 000000000000..2d77ec9e627a --- /dev/null +++ b/op-challenger/game/fault/trace/outputs/split_adapter.go @@ -0,0 +1,78 @@ +package outputs + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +type ProposalTraceProviderCreator func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) + +func OutputRootSplitAdapter(topProvider *OutputTraceProvider, creator ProposalTraceProviderCreator) split.ProviderCreator { + return func(ctx context.Context, depth types.Depth, pre types.Claim, post types.Claim) (types.TraceProvider, error) { + localContext := CreateLocalContext(pre, post) + agreed, disputed, err := FetchProposals(ctx, topProvider, pre, post) + if err != nil { + return nil, err + } + return creator(ctx, localContext, depth, agreed, disputed) + } +} + +func FetchProposals(ctx context.Context, topProvider *OutputTraceProvider, pre types.Claim, post types.Claim) (contracts.Proposal, contracts.Proposal, error) { + usePrestateBlock := pre == (types.Claim{}) + var agreed contracts.Proposal + if usePrestateBlock { + prestateRoot, err := topProvider.AbsolutePreStateCommitment(ctx) + if err != nil { + return contracts.Proposal{}, contracts.Proposal{}, fmt.Errorf("failed to retrieve absolute prestate output root: %w", err) + } + agreed = contracts.Proposal{ + L2BlockNumber: new(big.Int).SetUint64(topProvider.prestateBlock), + OutputRoot: prestateRoot, + } + } else { + preBlockNum, err := topProvider.HonestBlockNumber(ctx, pre.Position) + if err != nil { + return contracts.Proposal{}, contracts.Proposal{}, fmt.Errorf("unable to calculate pre-claim block number: %w", err) + } + agreed = contracts.Proposal{ + L2BlockNumber: new(big.Int).SetUint64(preBlockNum), + OutputRoot: pre.Value, + } + } + postBlockNum, err := topProvider.ClaimedBlockNumber(post.Position) + if err != nil { + return contracts.Proposal{}, contracts.Proposal{}, fmt.Errorf("unable to calculate post-claim block number: %w", err) + } + claimed := contracts.Proposal{ + L2BlockNumber: new(big.Int).SetUint64(postBlockNum), + OutputRoot: post.Value, + } + return agreed, claimed, nil +} + +func CreateLocalContext(pre types.Claim, post types.Claim) common.Hash { + return crypto.Keccak256Hash(localContextPreimage(pre, post)) +} + +func localContextPreimage(pre types.Claim, post types.Claim) []byte { + encodeClaim := func(c types.Claim) []byte { + data := make([]byte, 64) + copy(data[0:32], c.Value.Bytes()) + c.Position.ToGIndex().FillBytes(data[32:]) + return data + } + var data []byte + if pre != (types.Claim{}) { + data = encodeClaim(pre) + } + data = append(data, encodeClaim(post)...) + return data +} diff --git a/op-challenger/game/fault/trace/outputs/split_adapter_test.go b/op-challenger/game/fault/trace/outputs/split_adapter_test.go new file mode 100644 index 000000000000..8eabc520def7 --- /dev/null +++ b/op-challenger/game/fault/trace/outputs/split_adapter_test.go @@ -0,0 +1,228 @@ +package outputs + +import ( + "context" + "errors" + "math" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var creatorError = errors.New("captured args") + +func TestOutputRootSplitAdapter(t *testing.T) { + tests := []struct { + name string + preTraceIndex int64 + postTraceIndex int64 + expectedAgreedBlockNum int64 + expectedClaimedBlockNum int64 + }{ + { + name: "middleOfBlockRange", + preTraceIndex: 5, + postTraceIndex: 9, + expectedAgreedBlockNum: 26, + expectedClaimedBlockNum: 30, + }, + { + name: "beyondPostBlock", + preTraceIndex: 5, + postTraceIndex: 50, + expectedAgreedBlockNum: 26, + expectedClaimedBlockNum: 40, + }, + { + name: "firstBlock", + preTraceIndex: 0, + postTraceIndex: 1, + expectedAgreedBlockNum: 21, + expectedClaimedBlockNum: 22, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + topDepth := types.Depth(10) + adapter, creator := setupAdapterTest(t, topDepth) + preClaim := types.Claim{ + ClaimData: types.ClaimData{ + Value: common.Hash{0xaa}, + Position: types.NewPosition(topDepth, big.NewInt(test.preTraceIndex)), + }, + ContractIndex: 3, + ParentContractIndex: 2, + } + postClaim := types.Claim{ + ClaimData: types.ClaimData{ + Value: common.Hash{0xbb}, + Position: types.NewPosition(topDepth, big.NewInt(test.postTraceIndex)), + }, + ContractIndex: 7, + ParentContractIndex: 1, + } + + expectedAgreed := contracts.Proposal{ + L2BlockNumber: big.NewInt(test.expectedAgreedBlockNum), + OutputRoot: preClaim.Value, + } + expectedClaimed := contracts.Proposal{ + L2BlockNumber: big.NewInt(test.expectedClaimedBlockNum), + OutputRoot: postClaim.Value, + } + + _, err := adapter(context.Background(), 5, preClaim, postClaim) + require.ErrorIs(t, err, creatorError) + require.Equal(t, CreateLocalContext(preClaim, postClaim), creator.localContext) + require.Equal(t, expectedAgreed, creator.agreed) + require.Equal(t, expectedClaimed, creator.claimed) + }) + } +} + +func TestOutputRootSplitAdapter_FromAbsolutePrestate(t *testing.T) { + topDepth := types.Depth(10) + adapter, creator := setupAdapterTest(t, topDepth) + + postClaim := types.Claim{ + ClaimData: types.ClaimData{ + Value: common.Hash{0xbb}, + Position: types.NewPosition(topDepth, big.NewInt(0)), + }, + ContractIndex: 7, + ParentContractIndex: 1, + } + + expectedAgreed := contracts.Proposal{ + L2BlockNumber: big.NewInt(20), + OutputRoot: prestateOutputRoot, // Absolute prestate output root + } + expectedClaimed := contracts.Proposal{ + L2BlockNumber: big.NewInt(21), + OutputRoot: postClaim.Value, + } + + _, err := adapter(context.Background(), 5, types.Claim{}, postClaim) + require.ErrorIs(t, err, creatorError) + require.Equal(t, CreateLocalContext(types.Claim{}, postClaim), creator.localContext) + require.Equal(t, expectedAgreed, creator.agreed) + require.Equal(t, expectedClaimed, creator.claimed) +} + +func setupAdapterTest(t *testing.T, topDepth types.Depth) (split.ProviderCreator, *capturingCreator) { + prestateBlock := uint64(20) + poststateBlock := uint64(40) + creator := &capturingCreator{} + l1Head := eth.BlockID{ + Hash: common.Hash{0x11, 0x11}, + Number: 11, + } + rollupClient := &stubRollupClient{ + outputs: map[uint64]*eth.OutputResponse{ + prestateBlock: { + OutputRoot: eth.Bytes32(prestateOutputRoot), + }, + }, + maxSafeHead: math.MaxUint64, + } + prestateProvider := &stubPrestateProvider{ + absolutePrestate: prestateOutputRoot, + } + topProvider := NewTraceProvider(testlog.Logger(t, log.LevelInfo), prestateProvider, rollupClient, l1Head, topDepth, prestateBlock, poststateBlock) + adapter := OutputRootSplitAdapter(topProvider, creator.Create) + return adapter, creator +} + +type capturingCreator struct { + localContext common.Hash + agreed contracts.Proposal + claimed contracts.Proposal +} + +func (c *capturingCreator) Create(_ context.Context, localContext common.Hash, _ types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) { + c.localContext = localContext + c.agreed = agreed + c.claimed = claimed + return nil, creatorError +} + +func TestCreateLocalContext(t *testing.T) { + tests := []struct { + name string + preValue common.Hash + prePosition types.Position + postValue common.Hash + postPosition types.Position + expected []byte + }{ + { + name: "PreAndPost", + preValue: common.HexToHash("abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"), + prePosition: types.NewPositionFromGIndex(big.NewInt(2)), + postValue: common.HexToHash("cc00000000000000000000000000000000000000000000000000000000000000"), + postPosition: types.NewPositionFromGIndex(big.NewInt(3)), + expected: common.FromHex("abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567890000000000000000000000000000000000000000000000000000000000000002cc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003"), + }, + { + name: "LargePositions", + preValue: common.HexToHash("abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"), + prePosition: types.NewPositionFromGIndex(new(big.Int).SetBytes(common.FromHex("cbcdef0123456789abcdef0123456789abcdef0123456789abcdef012345678c"))), + postValue: common.HexToHash("dd00000000000000000000000000000000000000000000000000000000000000"), + postPosition: types.NewPositionFromGIndex(new(big.Int).SetUint64(math.MaxUint64)), + expected: common.FromHex("abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789cbcdef0123456789abcdef0123456789abcdef0123456789abcdef012345678cdd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff"), + }, + { + name: "AbsolutePreState", + preValue: common.Hash{}, + prePosition: types.Position{}, + postValue: common.HexToHash("cc00000000000000000000000000000000000000000000000000000000000000"), + postPosition: types.NewPositionFromGIndex(big.NewInt(3)), + expected: common.FromHex("cc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003"), + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + pre := types.Claim{ + ClaimData: types.ClaimData{ + Value: test.preValue, + Position: test.prePosition, + }, + } + post := types.Claim{ + ClaimData: types.ClaimData{ + Value: test.postValue, + Position: test.postPosition, + }, + } + actualPreimage := localContextPreimage(pre, post) + require.Equal(t, test.expected, actualPreimage) + localContext := CreateLocalContext(pre, post) + require.Equal(t, crypto.Keccak256Hash(test.expected), localContext) + }) + } +} + +type stubPrestateProvider struct { + errorsOnAbsolutePrestateFetch bool + absolutePrestate common.Hash +} + +func (s *stubPrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { + if s.errorsOnAbsolutePrestateFetch { + return common.Hash{}, errNoOutputAtBlock + } + return s.absolutePrestate, nil +} diff --git a/op-challenger/game/fault/trace/split/provider.go b/op-challenger/game/fault/trace/split/provider.go deleted file mode 100644 index 6d61c8ab9a13..000000000000 --- a/op-challenger/game/fault/trace/split/provider.go +++ /dev/null @@ -1,72 +0,0 @@ -package split - -import ( - "context" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" -) - -var _ types.TraceProvider = (*SplitTraceProvider)(nil) - -// SplitTraceProvider is a [types.TraceProvider] implementation that -// routes requests to the correct internal trace provider based on the -// depth of the requested trace. -type SplitTraceProvider struct { - logger log.Logger - topProvider types.TraceProvider - bottomProvider types.TraceProvider - topDepth uint64 -} - -// NewTraceProvider creates a new [SplitTraceProvider] instance. -// The [topDepth] parameter specifies the depth at which the internal -// [types.TraceProvider] should be switched. -func NewTraceProvider(logger log.Logger, topProvider types.TraceProvider, bottomProvider types.TraceProvider, topDepth uint64) *SplitTraceProvider { - return &SplitTraceProvider{ - logger: logger, - topProvider: topProvider, - bottomProvider: bottomProvider, - topDepth: topDepth, - } -} - -func (s *SplitTraceProvider) providerForDepth(depth uint64) (uint64, types.TraceProvider) { - if depth <= s.topDepth { - return 0, s.topProvider - } - return s.topDepth, s.bottomProvider -} - -// Get routes the Get request to the internal [types.TraceProvider] that -// that serves the trace index at the depth. -func (s *SplitTraceProvider) Get(ctx context.Context, pos types.Position) (common.Hash, error) { - ancestorDepth, provider := s.providerForDepth(uint64(pos.Depth())) - relativePosition, err := pos.RelativeToAncestorAtDepth(ancestorDepth) - if err != nil { - return common.Hash{}, err - } - return provider.Get(ctx, relativePosition) -} - -// AbsolutePreStateCommitment returns the absolute prestate from the lowest internal [types.TraceProvider] -func (s *SplitTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (hash common.Hash, err error) { - return s.bottomProvider.AbsolutePreStateCommitment(ctx) -} - -// AbsolutePreState routes the AbsolutePreState request to the lowest internal [types.TraceProvider]. -func (s *SplitTraceProvider) AbsolutePreState(ctx context.Context) (preimage []byte, err error) { - return s.bottomProvider.AbsolutePreState(ctx) -} - -// GetStepData routes the GetStepData request to the lowest internal [types.TraceProvider]. -func (s *SplitTraceProvider) GetStepData(ctx context.Context, pos types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) { - ancestorDepth, provider := s.providerForDepth(uint64(pos.Depth())) - relativePosition, err := pos.RelativeToAncestorAtDepth(ancestorDepth) - if err != nil { - return nil, nil, nil, err - } - return provider.GetStepData(ctx, relativePosition) -} diff --git a/op-challenger/game/fault/trace/split/provider_test.go b/op-challenger/game/fault/trace/split/provider_test.go deleted file mode 100644 index 2845bfc66cb4..000000000000 --- a/op-challenger/game/fault/trace/split/provider_test.go +++ /dev/null @@ -1,149 +0,0 @@ -package split - -import ( - "context" - "errors" - "math/big" - "testing" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-service/testlog" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/stretchr/testify/require" -) - -var ( - mockGetError = errors.New("mock get error") - mockOutput = common.HexToHash("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") - mockCommitment = common.HexToHash("0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") -) - -func TestGet(t *testing.T) { - t.Run("ErrorBubblesUp", func(t *testing.T) { - mockOutputProvider := mockTraceProvider{getError: mockGetError} - splitProvider := newSplitTraceProvider(t, &mockOutputProvider, nil, 40) - _, err := splitProvider.Get(context.Background(), types.NewPosition(1, common.Big0)) - require.ErrorIs(t, err, mockGetError) - }) - - t.Run("ReturnsCorrectOutputFromTopProvider", func(t *testing.T) { - mockOutputProvider := mockTraceProvider{getOutput: mockOutput} - splitProvider := newSplitTraceProvider(t, &mockOutputProvider, &mockTraceProvider{}, 40) - output, err := splitProvider.Get(context.Background(), types.NewPosition(6, big.NewInt(3))) - require.NoError(t, err) - expectedGIndex := types.NewPosition(6, big.NewInt(3)).ToGIndex() - require.Equal(t, common.BigToHash(expectedGIndex), output) - }) - - t.Run("ReturnsCorrectOutputWithMultipleProviders", func(t *testing.T) { - bottomProvider := mockTraceProvider{getOutput: mockOutput} - splitProvider := newSplitTraceProvider(t, &mockTraceProvider{}, &bottomProvider, 40) - output, err := splitProvider.Get(context.Background(), types.NewPosition(42, big.NewInt(17))) - require.NoError(t, err) - expectedGIndex := types.NewPosition(2, big.NewInt(1)).ToGIndex() - require.Equal(t, common.BigToHash(expectedGIndex), output) - }) -} - -func TestAbsolutePreStateCommitment(t *testing.T) { - t.Run("ErrorBubblesUp", func(t *testing.T) { - mockOutputProvider := mockTraceProvider{absolutePreStateCommitmentError: mockGetError} - splitProvider := newSplitTraceProvider(t, nil, &mockOutputProvider, 40) - _, err := splitProvider.AbsolutePreStateCommitment(context.Background()) - require.ErrorIs(t, err, mockGetError) - }) - - t.Run("ReturnsCorrectOutput", func(t *testing.T) { - mockOutputProvider := mockTraceProvider{absolutePreStateCommitment: mockCommitment} - splitProvider := newSplitTraceProvider(t, nil, &mockOutputProvider, 40) - output, err := splitProvider.AbsolutePreStateCommitment(context.Background()) - require.NoError(t, err) - require.Equal(t, mockCommitment, output) - }) -} - -func TestAbsolutePreState(t *testing.T) { - t.Run("ErrorBubblesUp", func(t *testing.T) { - mockOutputProvider := mockTraceProvider{absolutePreStateError: mockGetError} - splitProvider := newSplitTraceProvider(t, nil, &mockOutputProvider, 40) - _, err := splitProvider.AbsolutePreState(context.Background()) - require.ErrorIs(t, err, mockGetError) - }) - - t.Run("ReturnsCorrectPreimageData", func(t *testing.T) { - expectedPreimage := []byte{1, 2, 3, 4} - mockOutputProvider := mockTraceProvider{preImageData: expectedPreimage} - splitProvider := newSplitTraceProvider(t, nil, &mockOutputProvider, 40) - output, err := splitProvider.AbsolutePreState(context.Background()) - require.NoError(t, err) - require.Equal(t, expectedPreimage, output) - }) -} - -func TestGetStepData(t *testing.T) { - t.Run("ErrorBubblesUp", func(t *testing.T) { - mockOutputProvider := mockTraceProvider{getStepDataError: mockGetError} - splitProvider := newSplitTraceProvider(t, &mockOutputProvider, nil, 40) - _, _, _, err := splitProvider.GetStepData(context.Background(), types.NewPosition(0, common.Big0)) - require.ErrorIs(t, err, mockGetError) - }) - - t.Run("ReturnsCorrectStepData", func(t *testing.T) { - expectedStepData := []byte{1, 2, 3, 4} - mockOutputProvider := mockTraceProvider{stepPrestateData: expectedStepData} - splitProvider := newSplitTraceProvider(t, nil, &mockOutputProvider, 40) - output, _, _, err := splitProvider.GetStepData(context.Background(), types.NewPosition(41, common.Big0)) - require.NoError(t, err) - require.Equal(t, expectedStepData, output) - }) -} - -type mockTraceProvider struct { - getOutput common.Hash - getError error - absolutePreStateCommitmentError error - absolutePreStateCommitment common.Hash - absolutePreStateError error - preImageData []byte - getStepDataError error - stepPrestateData []byte -} - -func newSplitTraceProvider(t *testing.T, tp *mockTraceProvider, bp *mockTraceProvider, topDepth uint64) SplitTraceProvider { - return SplitTraceProvider{ - logger: testlog.Logger(t, log.LvlInfo), - topProvider: tp, - bottomProvider: bp, - topDepth: topDepth, - } -} - -func (m *mockTraceProvider) Get(ctx context.Context, pos types.Position) (common.Hash, error) { - if m.getError != nil { - return common.Hash{}, m.getError - } - return common.BigToHash(pos.ToGIndex()), nil -} - -func (m *mockTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (hash common.Hash, err error) { - if m.absolutePreStateCommitmentError != nil { - return common.Hash{}, m.absolutePreStateCommitmentError - } - return m.absolutePreStateCommitment, nil -} - -func (m *mockTraceProvider) AbsolutePreState(ctx context.Context) (preimage []byte, err error) { - if m.absolutePreStateError != nil { - return []byte{}, m.absolutePreStateError - } - return m.preImageData, nil -} - -func (m *mockTraceProvider) GetStepData(ctx context.Context, pos types.Position) ([]byte, []byte, *types.PreimageOracleData, error) { - if m.getStepDataError != nil { - return nil, nil, nil, m.getStepDataError - } - return m.stepPrestateData, nil, nil, nil -} diff --git a/op-challenger/game/fault/trace/split/split.go b/op-challenger/game/fault/trace/split/split.go new file mode 100644 index 000000000000..91b16b9087de --- /dev/null +++ b/op-challenger/game/fault/trace/split/split.go @@ -0,0 +1,92 @@ +package split + +import ( + "context" + "errors" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" +) + +var ( + errRefClaimNotDeepEnough = errors.New("reference claim is not deep enough") +) + +type ProviderCreator func(ctx context.Context, depth types.Depth, pre types.Claim, post types.Claim) (types.TraceProvider, error) + +func NewSplitProviderSelector(topProvider types.TraceProvider, topDepth types.Depth, bottomProviderCreator ProviderCreator) trace.ProviderSelector { + return func(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (types.TraceProvider, error) { + if pos.Depth() <= topDepth { + return topProvider, nil + } + if ref.Position.Depth() < topDepth { + return nil, fmt.Errorf("%w, claim depth: %v, depth required: %v", errRefClaimNotDeepEnough, ref.Position.Depth(), topDepth) + } + + // Find the ancestor claim at the leaf level for the top game. + topLeaf, err := findAncestorAtDepth(game, ref, topDepth) + if err != nil { + return nil, err + } + + var pre, post types.Claim + // If pos is to the right of the leaf from the top game, we must be defending that output root + // otherwise, we're attacking it. + if pos.TraceIndex(pos.Depth()).Cmp(topLeaf.TraceIndex(pos.Depth())) > 0 { + // Defending the top leaf claim, so use it as the pre-claim and find the post + pre = topLeaf + postTraceIdx := new(big.Int).Add(pre.TraceIndex(topDepth), big.NewInt(1)) + post, err = findAncestorWithTraceIndex(game, topLeaf, topDepth, postTraceIdx) + if err != nil { + return nil, fmt.Errorf("failed to find post claim: %w", err) + } + } else { + // Attacking the top leaf claim, so use it as the post-claim and find the pre + post = topLeaf + postTraceIdx := post.TraceIndex(topDepth) + if postTraceIdx.Cmp(big.NewInt(0)) == 0 { + pre = types.Claim{} + } else { + preTraceIdx := new(big.Int).Sub(postTraceIdx, big.NewInt(1)) + pre, err = findAncestorWithTraceIndex(game, topLeaf, topDepth, preTraceIdx) + if err != nil { + return nil, fmt.Errorf("failed to find pre claim: %w", err) + } + } + } + // The top game runs from depth 0 to split depth *inclusive*. + // The - 1 here accounts for the fact that the split depth is included in the top game. + bottomDepth := game.MaxDepth() - topDepth - 1 + provider, err := bottomProviderCreator(ctx, bottomDepth, pre, post) + if err != nil { + return nil, err + } + // Translate such that the root of the bottom game is the level below the top game leaf + return trace.Translate(provider, topDepth+1), nil + } +} + +func findAncestorAtDepth(game types.Game, claim types.Claim, depth types.Depth) (types.Claim, error) { + for claim.Depth() > depth { + parent, err := game.GetParent(claim) + if err != nil { + return types.Claim{}, fmt.Errorf("failed to find ancestor at depth %v: %w", depth, err) + } + claim = parent + } + return claim, nil +} + +func findAncestorWithTraceIndex(game types.Game, ref types.Claim, depth types.Depth, traceIdx *big.Int) (types.Claim, error) { + candidate := ref + for candidate.TraceIndex(depth).Cmp(traceIdx) != 0 { + parent, err := game.GetParent(candidate) + if err != nil { + return types.Claim{}, fmt.Errorf("failed to get parent of claim %v: %w", candidate.ContractIndex, err) + } + candidate = parent + } + return candidate, nil +} diff --git a/op-challenger/game/fault/trace/split/split_test.go b/op-challenger/game/fault/trace/split/split_test.go new file mode 100644 index 000000000000..fb47932455d0 --- /dev/null +++ b/op-challenger/game/fault/trace/split/split_test.go @@ -0,0 +1,325 @@ +package split + +import ( + "context" + "fmt" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/stretchr/testify/require" +) + +const ( + gameDepth = 7 + splitDepth = 3 +) + +func TestUseTopProvider(t *testing.T) { + ctx := context.Background() + topProvider, selector, gameBuilder := setupAlphabetSplitSelector(t) + + ref := gameBuilder.Game.Claims()[0] + + pos := ref.Position + for pos.Depth() <= splitDepth { + provider, err := selector(ctx, gameBuilder.Game, ref, ref.Position) + require.NoError(t, err) + require.Same(t, topProvider, provider) + _, err = topProvider.Get(ctx, pos) + require.NoError(t, err, "should be able to use provider for position") + pos = pos.Attack() + } +} + +func TestErrorWhenRefAboveTopGameLeafButPositionInBottom(t *testing.T) { + ctx := context.Background() + _, selector, gameBuilder := setupAlphabetSplitSelector(t) + + // Generate claims at depths up to but not including the leaf of the top providers + createClaimsToDepth(gameBuilder, splitDepth-1) + for _, ref := range gameBuilder.Game.Claims() { + pos := types.NewPosition(splitDepth+1, big.NewInt(0)) + provider, err := selector(ctx, gameBuilder.Game, ref, pos) + require.ErrorIsf(t, err, errRefClaimNotDeepEnough, "should not get provider with ref claim at depth: %v", ref.Depth()) + require.Nil(t, provider) + } +} + +func TestTranslatePositionsForBottomProvider(t *testing.T) { + tests := []struct { + name string + setup func(t *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) + }{ + // There are 4 leaf nodes that can be accessed in the top tree of depth 3: 8, 10, 12, 14 + // Then you can attack and defend any of those to challenge all blocks + {"attackTopLeafGIndex8", attackTopLeafGIndex8}, + {"defendTopLeafGIndex8", defendTopLeafGIndex8}, + {"attackTopLeafGIndex10", attackTopLeafGIndex10}, + {"defendTopLeafGIndex10", defendTopLeafGIndex10}, + {"attackTopLeafGIndex12", attackTopLeafGIndex12}, + {"defendTopLeafGIndex12", defendTopLeafGIndex12}, + {"attackTopLeafGIndex14", attackTopLeafGIndex14}, + {"attackTopLeafGIndex14", defendTopLeafGIndex14}, + } + for _, tCase := range tests { + tCase := tCase + t.Run(tCase.name, func(t *testing.T) { + _, selector, gameBuilder := setupAlphabetSplitSelector(t) + ref, pos, _, _ := tCase.setup(t, gameBuilder) + provider, err := selector(context.Background(), gameBuilder.Game, ref, pos) + require.NoError(t, err) + + claimPos := pos + localClaimPos := types.NewPositionFromGIndex(big.NewInt(1)) + requireSameValue(t, provider, claimPos, asBottomTraceProvider(t, provider).AlphabetTraceProvider, localClaimPos) + requireSameValue(t, provider, claimPos.Attack(), asBottomTraceProvider(t, provider).AlphabetTraceProvider, localClaimPos.Attack()) + requireSameValue(t, provider, claimPos.Attack().Defend(), asBottomTraceProvider(t, provider).AlphabetTraceProvider, localClaimPos.Attack().Defend()) + }) + } +} + +func requireSameValue(t *testing.T, a types.TraceProvider, aPos types.Position, b types.TraceProvider, bPos types.Position) { + // Check Get returns the same results + aValue, err := a.Get(context.Background(), aPos) + require.NoError(t, err) + bValue, err := b.Get(context.Background(), bPos) + require.NoError(t, err) + require.Equal(t, aValue, bValue) + + // Check GetStepData returns the same results + aPrestate, aProofData, aPreimageData, err := a.GetStepData(context.Background(), aPos) + require.NoError(t, err) + bPrestate, bProofData, bPreimageData, err := b.GetStepData(context.Background(), bPos) + require.NoError(t, err) + require.Equal(t, aPrestate, bPrestate) + require.Equal(t, aProofData, bProofData) + require.Equal(t, aPreimageData, bPreimageData) +} + +func TestBottomProviderAttackingTopLeaf(t *testing.T) { + tests := []struct { + name string + setup func(t *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) + }{ + // There are 4 leaf nodes that can be accessed in the top tree of depth 3: 8, 10, 12, 14 + // Then you can attack and defend any of those to challenge all blocks + // We can then use these setups to test any other reference claim descending from what these setup since + // that whole subtree should have the same pre and post claim from the top provider. + {"attackTopLeafGIndex8", attackTopLeafGIndex8}, + {"defendTopLeafGIndex8", defendTopLeafGIndex8}, + {"attackTopLeafGIndex10", attackTopLeafGIndex10}, + {"defendTopLeafGIndex10", defendTopLeafGIndex10}, + {"attackTopLeafGIndex12", attackTopLeafGIndex12}, + {"defendTopLeafGIndex12", defendTopLeafGIndex12}, + {"attackTopLeafGIndex14", attackTopLeafGIndex14}, + {"attackTopLeafGIndex14", defendTopLeafGIndex14}, + } + for _, tCase := range tests { + tCase := tCase + t.Run(tCase.name, func(t *testing.T) { + _, selector, gameBuilder := setupAlphabetSplitSelector(t) + + ref, pos, expectedPre, expectedPost := tCase.setup(t, gameBuilder) + + runTest := func(ref types.Claim, pos types.Position) { + t.Run(fmt.Sprintf("Ref-d%vi%v_Pos-d%vi%v", ref.Depth(), ref.IndexAtDepth(), pos.Depth(), pos.IndexAtDepth()), func(t *testing.T) { + provider, err := selector(context.Background(), gameBuilder.Game, ref, pos) + require.NoError(t, err) + requireBottomProviderForClaims(t, provider, expectedPre, expectedPost) + }) + } + + // Check we get the same pre and post for any reference claim lower in the game + var testDescendantClaims func(ref types.Claim, pos types.Position) + testDescendantClaims = func(ref types.Claim, pos types.Position) { + // For each reference claim, check it works with the claim position, or attacking or defending the claim + runTest(ref, pos) + runTest(ref, pos.Attack()) + runTest(ref, pos.Defend()) + if pos.Depth() >= gameDepth { + return + } + + // If the ref is the leaf of the top claim, ensure we respect whether the test is setup + // to attack or defend the top leaf claim. + if ref.Depth() != splitDepth || !pos.RightOf(ref.Position) { + gameBuilder.SeqFrom(ref).Attack() + attackRef := latestClaim(gameBuilder) + testDescendantClaims(attackRef, attackRef.Position) + } + if ref.Depth() != splitDepth || pos.RightOf(ref.Position) { + gameBuilder.SeqFrom(ref).Defend() + defendRef := latestClaim(gameBuilder) + testDescendantClaims(defendRef, defendRef.Position) + } + } + testDescendantClaims(ref, pos) + }) + } +} + +func attackTopLeafGIndex8(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) { + // Generate claims down to the top provider's leaf + seq := gameBuilder.Seq() // gindex 1, trace 7 + seq = seq.Attack() // gindex 2, trace 3 + seq = seq.Attack() // gindex 4, trace 1 + seq.Attack() // gindex 8, trace 0 + expectPost = latestClaim(gameBuilder) + + // No pre-claim as the first output root is being challenged. + expectPre = types.Claim{} + + ref = latestClaim(gameBuilder) + pos = ref.Position.Attack() + return +} + +func defendTopLeafGIndex8(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) { + // Generate claims down to the top provider's leaf + seq := gameBuilder.Seq() // gindex 1, trace 7 + seq = seq.Attack() // gindex 2, trace 3 + seq = seq.Attack() // gindex 4, trace 1 + expectPost = latestClaim(gameBuilder) + seq.Attack() // gindex 8, trace 0 + expectPre = latestClaim(gameBuilder) + + ref = latestClaim(gameBuilder) + pos = ref.Position.Defend() + return +} + +func attackTopLeafGIndex10(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) { + seq := gameBuilder.Seq() // gindex 1, trace 7 + seq = seq.Attack() // gindex 2, trace 3 + seq = seq.Attack() // gindex 4, trace 1 + expectPre = latestClaim(gameBuilder) + seq.Defend() // gindex 10, trace 2 + expectPost = latestClaim(gameBuilder) + + ref = latestClaim(gameBuilder) + pos = ref.Position.Attack() + return +} + +func defendTopLeafGIndex10(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) { + seq := gameBuilder.Seq() // gindex 1, trace 7 + seq = seq.Attack() // gindex 2, trace 3 + expectPost = latestClaim(gameBuilder) + seq = seq.Attack() // gindex 4, trace 1 + seq.Defend() // gindex 10, trace 2 + expectPre = latestClaim(gameBuilder) + + ref = latestClaim(gameBuilder) + pos = ref.Position.Defend() + return +} + +func attackTopLeafGIndex12(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) { + seq := gameBuilder.Seq() // gindex 1, trace 7 + seq = seq.Attack() // gindex 2, trace 3 + expectPre = latestClaim(gameBuilder) + seq = seq.Defend() // gindex 6, trace 5 + seq.Attack() // gindex 12, trace 4 + expectPost = latestClaim(gameBuilder) + + ref = latestClaim(gameBuilder) + pos = ref.Position.Attack() + return +} + +func defendTopLeafGIndex12(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) { + seq := gameBuilder.Seq() // gindex 1, trace 7 + seq = seq.Attack() // gindex 2, trace 3 + seq = seq.Defend() // gindex 6, trace 5 + expectPost = latestClaim(gameBuilder) + seq.Attack() // gindex 12, trace 4 + expectPre = latestClaim(gameBuilder) + + ref = latestClaim(gameBuilder) + pos = ref.Position.Defend() + return +} + +func attackTopLeafGIndex14(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) { + seq := gameBuilder.Seq() // gindex 1, trace 7 + seq = seq.Attack() // gindex 2, trace 3 + seq = seq.Defend() // gindex 6, trace 5 + expectPre = latestClaim(gameBuilder) + seq.Defend() // gindex 14, trace 6 + expectPost = latestClaim(gameBuilder) + + ref = latestClaim(gameBuilder) + pos = ref.Position.Attack() + return +} + +func defendTopLeafGIndex14(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) { + seq := gameBuilder.Seq() // gindex 1, trace 7 + expectPost = latestClaim(gameBuilder) + seq = seq.Attack() // gindex 2, trace 3 + seq = seq.Defend() // gindex 6, trace 5 + seq.Defend() // gindex 14, trace 6 + expectPre = latestClaim(gameBuilder) + + ref = latestClaim(gameBuilder) + pos = ref.Position.Defend() + return +} + +func latestClaim(gameBuilder *test.GameBuilder) types.Claim { + return gameBuilder.Game.Claims()[len(gameBuilder.Game.Claims())-1] +} + +func createClaimsToDepth(gameBuilder *test.GameBuilder, depth int) { + seq := gameBuilder.Seq() + for i := 0; i < depth; i++ { + seq = seq.Attack() + } +} + +func requireBottomProviderForClaims(t *testing.T, actual types.TraceProvider, expectedPre types.Claim, expectedPost types.Claim) { + if expectedPre != (types.Claim{}) { + require.Equal(t, + new(big.Int).Add(expectedPre.TraceIndex(splitDepth), big.NewInt(1)), + expectedPost.TraceIndex(splitDepth), + "should expect adjacent top level trace indices") + } + + bottomProvider := asBottomTraceProvider(t, actual) + require.Equal(t, expectedPre, bottomProvider.pre, "Incorrect pre claim") + require.Equal(t, expectedPost, bottomProvider.post, "Incorrect post claim") +} + +func asBottomTraceProvider(t *testing.T, actual types.TraceProvider) *bottomTraceProvider { + translatingProvider, ok := actual.(*trace.TranslatingProvider) + require.True(t, ok) + bottomProvider, ok := translatingProvider.Original().(*bottomTraceProvider) + require.True(t, ok) + return bottomProvider +} + +func setupAlphabetSplitSelector(t *testing.T) (*alphabet.AlphabetTraceProvider, trace.ProviderSelector, *test.GameBuilder) { + top := alphabet.NewTraceProvider(big.NewInt(0), splitDepth) + bottomCreator := func(ctx context.Context, depth types.Depth, pre types.Claim, post types.Claim) (types.TraceProvider, error) { + return &bottomTraceProvider{ + pre: pre, + post: post, + AlphabetTraceProvider: alphabet.NewTraceProvider(big.NewInt(0), depth), + }, nil + } + selector := NewSplitProviderSelector(top, splitDepth, bottomCreator) + + claimBuilder := test.NewAlphabetClaimBuilder(t, big.NewInt(0), gameDepth) + gameBuilder := claimBuilder.GameBuilder() + return top, selector, gameBuilder +} + +type bottomTraceProvider struct { + pre types.Claim + post types.Claim + *alphabet.AlphabetTraceProvider +} diff --git a/op-challenger/game/fault/trace/translate.go b/op-challenger/game/fault/trace/translate.go new file mode 100644 index 000000000000..38d0435b6dc1 --- /dev/null +++ b/op-challenger/game/fault/trace/translate.go @@ -0,0 +1,49 @@ +package trace + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum/go-ethereum/common" +) + +type TranslatingProvider struct { + rootDepth types.Depth + provider types.TraceProvider +} + +// Translate returns a new TraceProvider that translates any requested positions before passing them on to the +// specified provider. +// The translation is done such that the root node for provider is at rootDepth. +func Translate(provider types.TraceProvider, rootDepth types.Depth) types.TraceProvider { + return &TranslatingProvider{ + rootDepth: rootDepth, + provider: provider, + } +} + +func (p *TranslatingProvider) Original() types.TraceProvider { + return p.provider +} + +func (p *TranslatingProvider) Get(ctx context.Context, pos types.Position) (common.Hash, error) { + relativePos, err := pos.RelativeToAncestorAtDepth(p.rootDepth) + if err != nil { + return common.Hash{}, err + } + return p.provider.Get(ctx, relativePos) +} + +func (p *TranslatingProvider) GetStepData(ctx context.Context, pos types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) { + relativePos, err := pos.RelativeToAncestorAtDepth(p.rootDepth) + if err != nil { + return nil, nil, nil, err + } + return p.provider.GetStepData(ctx, relativePos) +} + +func (p *TranslatingProvider) AbsolutePreStateCommitment(ctx context.Context) (hash common.Hash, err error) { + return p.provider.AbsolutePreStateCommitment(ctx) +} + +var _ types.TraceProvider = (*TranslatingProvider)(nil) diff --git a/op-challenger/game/fault/trace/translate_test.go b/op-challenger/game/fault/trace/translate_test.go new file mode 100644 index 000000000000..321579890ce3 --- /dev/null +++ b/op-challenger/game/fault/trace/translate_test.go @@ -0,0 +1,60 @@ +package trace + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/stretchr/testify/require" +) + +func TestTranslate(t *testing.T) { + orig := alphabet.NewTraceProvider(big.NewInt(0), 4) + translated := Translate(orig, 3) + // All nodes on the first translated layer, map to GIndex 1 + for i := int64(8); i <= 15; i++ { + requireSameValue(t, orig, 1, translated, i) + } + // Nodes on the second translated layer map to GIndex 2 and 3 alternately + for i := int64(16); i <= 31; i += 2 { + requireSameValue(t, orig, 2, translated, i) + requireSameValue(t, orig, 3, translated, i+1) + } + // Nodes on the third translated layer map to GIndex 4, 5, 6 and 7 + for i := int64(32); i <= 61; i += 4 { + requireSameValue(t, orig, 4, translated, i) + requireSameValue(t, orig, 5, translated, i+1) + requireSameValue(t, orig, 6, translated, i+2) + requireSameValue(t, orig, 7, translated, i+3) + } +} + +func requireSameValue(t *testing.T, a types.TraceProvider, aGIdx int64, b types.TraceProvider, bGIdx int64) { + // Check Get returns the same results + aValue, err := a.Get(context.Background(), types.NewPositionFromGIndex(big.NewInt(aGIdx))) + require.NoError(t, err) + bValue, err := b.Get(context.Background(), types.NewPositionFromGIndex(big.NewInt(bGIdx))) + require.NoError(t, err) + require.Equal(t, aValue, bValue) + + // Check GetStepData returns the same results + aPrestate, aProofData, aPreimageData, err := a.GetStepData(context.Background(), types.NewPositionFromGIndex(big.NewInt(aGIdx))) + require.NoError(t, err) + bPrestate, bProofData, bPreimageData, err := b.GetStepData(context.Background(), types.NewPositionFromGIndex(big.NewInt(bGIdx))) + require.NoError(t, err) + require.Equal(t, aPrestate, bPrestate) + require.Equal(t, aProofData, bProofData) + require.Equal(t, aPreimageData, bPreimageData) +} + +func TestTranslate_AbsolutePreStateCommitment(t *testing.T) { + orig := alphabet.NewTraceProvider(big.NewInt(0), 4) + translated := Translate(orig, 3) + origValue, err := orig.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + translatedValue, err := translated.AbsolutePreStateCommitment(context.Background()) + require.NoError(t, err) + require.Equal(t, origValue, translatedValue) +} diff --git a/op-challenger/game/fault/types/actions.go b/op-challenger/game/fault/types/actions.go index 92670f0ca9a7..c6631f80e40a 100644 --- a/op-challenger/game/fault/types/actions.go +++ b/op-challenger/game/fault/types/actions.go @@ -14,9 +14,10 @@ const ( ) type Action struct { - Type ActionType - ParentIdx int - IsAttack bool + Type ActionType + ParentIdx int + ParentPosition Position + IsAttack bool // Moves Value common.Hash diff --git a/op-challenger/game/fault/types/game.go b/op-challenger/game/fault/types/game.go index 2f6fd994c2f3..20bd6e2bff00 100644 --- a/op-challenger/game/fault/types/game.go +++ b/op-challenger/game/fault/types/game.go @@ -3,15 +3,9 @@ package types import ( "errors" "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" ) var ( - // ErrClaimExists is returned when a claim already exists in the game state. - ErrClaimExists = errors.New("claim exists in game state") - // ErrClaimNotFound is returned when a claim does not exist in the game state. ErrClaimNotFound = errors.New("claim not found in game state") ) @@ -33,60 +27,52 @@ type Game interface { IsDuplicate(claim Claim) bool // AgreeWithClaimLevel returns if the game state agrees with the provided claim level. - AgreeWithClaimLevel(claim Claim) bool - - MaxDepth() uint64 -} + AgreeWithClaimLevel(claim Claim, agreeWithRootClaim bool) bool -type claimID common.Hash + MaxDepth() Depth -func computeClaimID(claim Claim) claimID { - return claimID(crypto.Keccak256Hash( - claim.Position.ToGIndex().Bytes(), - claim.Value.Bytes(), - big.NewInt(int64(claim.ParentContractIndex)).Bytes(), - )) + // AncestorWithTraceIndex finds the ancestor of claim with trace index idx if present. + // Returns the claim and true if the ancestor is found, or Claim{}, false if not. + AncestorWithTraceIndex(claim Claim, idx *big.Int) (Claim, bool) } // gameState is a struct that represents the state of a dispute game. // The game state implements the [Game] interface. type gameState struct { - agreeWithProposedOutput bool // claims is the list of claims in the same order as the contract claims []Claim - claimIDs map[claimID]bool - depth uint64 + claimIDs map[ClaimID]bool + depth Depth } // NewGameState returns a new game state. // The provided [Claim] is used as the root node. -func NewGameState(agreeWithProposedOutput bool, claims []Claim, depth uint64) *gameState { - claimIDs := make(map[claimID]bool) +func NewGameState(claims []Claim, depth Depth) *gameState { + claimIDs := make(map[ClaimID]bool) for _, claim := range claims { - claimIDs[computeClaimID(claim)] = true + claimIDs[claim.ID()] = true } return &gameState{ - agreeWithProposedOutput: agreeWithProposedOutput, - claims: claims, - claimIDs: claimIDs, - depth: depth, + claims: claims, + claimIDs: claimIDs, + depth: depth, } } // AgreeWithClaimLevel returns if the game state agrees with the provided claim level. -func (g *gameState) AgreeWithClaimLevel(claim Claim) bool { +func (g *gameState) AgreeWithClaimLevel(claim Claim, agreeWithRootClaim bool) bool { isOddLevel := claim.Depth()%2 == 1 // If we agree with the proposed output, we agree with odd levels // If we disagree with the proposed output, we agree with the root claim level & even levels - if g.agreeWithProposedOutput { - return isOddLevel - } else { + if agreeWithRootClaim { return !isOddLevel + } else { + return isOddLevel } } func (g *gameState) IsDuplicate(claim Claim) bool { - return g.claimIDs[computeClaimID(claim)] + return g.claimIDs[claim.ID()] } func (g *gameState) Claims() []Claim { @@ -94,7 +80,7 @@ func (g *gameState) Claims() []Claim { return append([]Claim(nil), g.claims...) } -func (g *gameState) MaxDepth() uint64 { +func (g *gameState) MaxDepth() Depth { return g.depth } @@ -124,3 +110,19 @@ func (g *gameState) getParent(claim Claim) *Claim { parent := g.claims[claim.ParentContractIndex] return &parent } + +func (g *gameState) AncestorWithTraceIndex(claim Claim, idx *big.Int) (Claim, bool) { + for { + if claim.Position.TraceIndex(g.depth).Cmp(idx) == 0 { + return claim, true + } + if claim.IsRoot() { + return Claim{}, false + } + next := g.getParent(claim) + if next == nil { + return Claim{}, false + } + claim = *next + } +} diff --git a/op-challenger/game/fault/types/game_test.go b/op-challenger/game/fault/types/game_test.go index 22ef7e0d5504..cad4b5c856bd 100644 --- a/op-challenger/game/fault/types/game_test.go +++ b/op-challenger/game/fault/types/game_test.go @@ -51,7 +51,7 @@ func createTestClaims() (Claim, Claim, Claim, Claim) { func TestIsDuplicate(t *testing.T) { root, top, middle, bottom := createTestClaims() - g := NewGameState(false, []Claim{root, top}, testMaxDepth) + g := NewGameState([]Claim{root, top}, testMaxDepth) // Root + Top should be duplicates require.True(t, g.IsDuplicate(root)) @@ -66,7 +66,7 @@ func TestGame_Claims(t *testing.T) { // Setup the game state. root, top, middle, bottom := createTestClaims() expected := []Claim{root, top, middle, bottom} - g := NewGameState(false, expected, testMaxDepth) + g := NewGameState(expected, testMaxDepth) // Validate claim pairs. actual := g.Claims() @@ -111,7 +111,7 @@ func TestGame_DefendsParent(t *testing.T) { }, { name: "RootDoesntDefend", - game: NewGameState(false, []Claim{ + game: NewGameState([]Claim{ { ClaimData: ClaimData{ Position: NewPositionFromGIndex(big.NewInt(0)), @@ -131,6 +131,92 @@ func TestGame_DefendsParent(t *testing.T) { } } +func TestAncestorWithTraceIndex(t *testing.T) { + depth := Depth(4) + claims := []Claim{ + { + ClaimData: ClaimData{ + Position: NewPositionFromGIndex(big.NewInt(0)), + }, + ContractIndex: 0, + ParentContractIndex: 0, + }, + } + addClaimAtPos := func(parent Claim, pos Position) Claim { + claim := Claim{ + ClaimData: ClaimData{ + Position: pos, + }, + ParentContractIndex: parent.ContractIndex, + ContractIndex: len(claims), + } + claims = append(claims, claim) + return claim + } + attack := func(claim Claim) Claim { + return addClaimAtPos(claim, claim.Position.Attack()) + } + defend := func(claim Claim) Claim { + return addClaimAtPos(claim, claim.Position.Defend()) + } + // Create a variety of paths to leaf nodes + attack(attack(attack(attack(claims[0])))) + defend(defend(defend(defend(claims[0])))) + defend(attack(defend(attack(claims[0])))) + attack(defend(attack(defend(claims[0])))) + attack(attack(defend(defend(claims[0])))) + defend(defend(attack(attack(claims[0])))) + + game := NewGameState(claims, depth) + // Every claim should be able to find the root's trace index + for _, claim := range claims { + actual, ok := game.AncestorWithTraceIndex(claim, claims[0].TraceIndex(depth)) + require.True(t, ok) + require.Equal(t, claims[0], actual) + } + + // Leaf claims should be able to find the trace index before and after + for _, claim := range game.Claims() { + if claim.Depth() != depth { + // Only leaf nodes are guaranteed to have the pre and post states available + continue + } + claimIdx := claim.TraceIndex(depth) + + actual, ok := game.AncestorWithTraceIndex(claim, claimIdx) + require.True(t, ok) + require.Equal(t, claim, actual, "Should get leaf claim for its own trace index") + + // The right most claim doesn't have + if claim.IndexAtDepth().Cmp(big.NewInt(30)) < 0 { + idx := new(big.Int).Add(claimIdx, big.NewInt(1)) + actual, ok = game.AncestorWithTraceIndex(claim, idx) + require.Truef(t, ok, "Should find claim with next trace index for claim %v index at depth %v", claim.ContractIndex, claim.IndexAtDepth()) + require.Equalf(t, idx, actual.TraceIndex(depth), "Should find claim with next trace index for claim %v index at depth %v", claim.ContractIndex, claim.IndexAtDepth()) + } + + if claimIdx.Cmp(big.NewInt(0)) == 0 { + continue + } + idx := new(big.Int).Sub(claimIdx, big.NewInt(1)) + actual, ok = game.AncestorWithTraceIndex(claim, idx) + require.True(t, ok) + require.Equal(t, idx, actual.TraceIndex(depth), "Should find claim with previous trace index") + } + + actual, ok := game.AncestorWithTraceIndex(claims[0], big.NewInt(0)) + require.False(t, ok) + require.Equal(t, Claim{}, actual) + + actual, ok = game.AncestorWithTraceIndex(claims[1], big.NewInt(1)) + require.False(t, ok) + require.Equal(t, Claim{}, actual) + + actual, ok = game.AncestorWithTraceIndex(claims[3], big.NewInt(1)) + require.True(t, ok) + require.Equal(t, claims[3], actual) +} + func buildGameWithClaim(claimGIndex *big.Int, parentGIndex *big.Int) *gameState { parentClaim := Claim{ ClaimData: ClaimData{ @@ -145,5 +231,5 @@ func buildGameWithClaim(claimGIndex *big.Int, parentGIndex *big.Int) *gameState ContractIndex: 1, ParentContractIndex: 0, } - return NewGameState(false, []Claim{parentClaim, claim}, testMaxDepth) + return NewGameState([]Claim{parentClaim, claim}, testMaxDepth) } diff --git a/op-challenger/game/fault/types/position.go b/op-challenger/game/fault/types/position.go index 56beaa32de10..85d1b1ccd750 100644 --- a/op-challenger/game/fault/types/position.go +++ b/op-challenger/game/fault/types/position.go @@ -9,22 +9,28 @@ import ( ) var ( - ErrPositionDepthTooSmall = errors.New("Position depth is too small") + ErrPositionDepthTooSmall = errors.New("position depth is too small") ) +// Depth is the depth of a position in a game tree where the root level has +// depth 0, the root's children have depth 1, their children have depth 2, and +// so on. +type Depth uint64 + // Position is a golang wrapper around the dispute game Position type. type Position struct { - depth int + depth Depth indexAtDepth *big.Int } -func NewPosition(depth int, indexAtDepth *big.Int) Position { +func NewPosition(depth Depth, indexAtDepth *big.Int) Position { return Position{ depth: depth, indexAtDepth: indexAtDepth, } } +// NewPositionFromGIndex creates a new Position given a generalized index. func NewPositionFromGIndex(x *big.Int) Position { depth := bigMSB(x) withoutMSB := new(big.Int).Not(new(big.Int).Lsh(big.NewInt(1), uint(depth))) @@ -32,6 +38,10 @@ func NewPositionFromGIndex(x *big.Int) Position { return NewPosition(depth, indexAtDepth) } +func (p Position) String() string { + return fmt.Sprintf("Position(depth: %v, indexAtDepth: %v)", p.depth, p.indexAtDepth) +} + func (p Position) MoveRight() Position { return Position{ depth: p.depth, @@ -41,17 +51,17 @@ func (p Position) MoveRight() Position { // RelativeToAncestorAtDepth returns a new position for a subtree. // [ancestor] is the depth of the subtree root node. -func (p Position) RelativeToAncestorAtDepth(ancestor uint64) (Position, error) { - if ancestor > uint64(p.depth) { +func (p Position) RelativeToAncestorAtDepth(ancestor Depth) (Position, error) { + if ancestor > p.depth { return Position{}, ErrPositionDepthTooSmall } - newPosDepth := uint64(p.depth) - ancestor + newPosDepth := p.depth - ancestor nodesAtDepth := 1 << newPosDepth newIndexAtDepth := new(big.Int).Mod(p.indexAtDepth, big.NewInt(int64(nodesAtDepth))) - return NewPosition(int(newPosDepth), newIndexAtDepth), nil + return NewPosition(newPosDepth, newIndexAtDepth), nil } -func (p Position) Depth() int { +func (p Position) Depth() Depth { return p.depth } @@ -66,13 +76,13 @@ func (p Position) IsRootPosition() bool { return p.depth == 0 && common.Big0.Cmp(p.indexAtDepth) == 0 } -func (p Position) lshIndex(amount int) *big.Int { +func (p Position) lshIndex(amount Depth) *big.Int { return new(big.Int).Lsh(p.IndexAtDepth(), uint(amount)) } // TraceIndex calculates the what the index of the claim value would be inside the trace. // It is equivalent to going right until the final depth has been reached. -func (p Position) TraceIndex(maxDepth int) *big.Int { +func (p Position) TraceIndex(maxDepth Depth) *big.Int { // When we go right, we do a shift left and set the bottom bit to be 1. // To do this in a single step, do all the shifts at once & or in all 1s for the bottom bits. rd := maxDepth - p.depth @@ -123,7 +133,7 @@ func (p Position) Defend() Position { return p.parent().move(true).move(false) } -func (p Position) Print(maxDepth int) { +func (p Position) Print(maxDepth Depth) { fmt.Printf("GIN: %4b\tTrace Position is %4b\tTrace Depth is: %d\tTrace Index is: %d\n", p.ToGIndex(), p.indexAtDepth, p.depth, p.TraceIndex(maxDepth)) } @@ -132,11 +142,11 @@ func (p Position) ToGIndex() *big.Int { } // bigMSB returns the index of the most significant bit -func bigMSB(x *big.Int) int { +func bigMSB(x *big.Int) Depth { if x.Cmp(big.NewInt(0)) == 0 { return 0 } - out := 0 + out := Depth(0) for ; x.Cmp(big.NewInt(0)) != 0; out++ { x = new(big.Int).Rsh(x, 1) } diff --git a/op-challenger/game/fault/types/position_test.go b/op-challenger/game/fault/types/position_test.go index 42d62fdaf575..c7bb210a6202 100644 --- a/op-challenger/game/fault/types/position_test.go +++ b/op-challenger/game/fault/types/position_test.go @@ -1,6 +1,7 @@ package types import ( + "fmt" "math" "math/big" "testing" @@ -17,7 +18,7 @@ func TestBigMSB(t *testing.T) { require.True(t, ok) tests := []struct { input *big.Int - expected int + expected Depth }{ {bi(0), 0}, {bi(1), 0}, @@ -38,65 +39,58 @@ func TestBigMSB(t *testing.T) { } } -type testNodeInfo struct { - GIndex *big.Int - Depth int - MaxDepth int - IndexAtDepth *big.Int - TraceIndex *big.Int - AttackGIndex *big.Int // 0 indicates attack is not possible from this node - DefendGIndex *big.Int // 0 indicates defend is not possible from this node -} +func TestGindexPositionConversions(t *testing.T) { + tests := []struct { + gindex *big.Int + expectedPosition Position + }{ + {bi(1), NewPosition(0, bi(0))}, -var treeNodes = []testNodeInfo{ - {GIndex: bi(1), Depth: 0, MaxDepth: 4, IndexAtDepth: bi(0), TraceIndex: bi(15), AttackGIndex: bi(2)}, - - {GIndex: bi(2), Depth: 1, MaxDepth: 4, IndexAtDepth: bi(0), TraceIndex: bi(7), AttackGIndex: bi(4), DefendGIndex: bi(6)}, - {GIndex: bi(3), Depth: 1, MaxDepth: 4, IndexAtDepth: bi(1), TraceIndex: bi(15), AttackGIndex: bi(6)}, - - {GIndex: bi(4), Depth: 2, MaxDepth: 4, IndexAtDepth: bi(0), TraceIndex: bi(3), AttackGIndex: bi(8), DefendGIndex: bi(10)}, - {GIndex: bi(5), Depth: 2, MaxDepth: 4, IndexAtDepth: bi(1), TraceIndex: bi(7), AttackGIndex: bi(10)}, - {GIndex: bi(6), Depth: 2, MaxDepth: 4, IndexAtDepth: bi(2), TraceIndex: bi(11), AttackGIndex: bi(12), DefendGIndex: bi(14)}, - {GIndex: bi(7), Depth: 2, MaxDepth: 4, IndexAtDepth: bi(3), TraceIndex: bi(15), AttackGIndex: bi(14)}, - - {GIndex: bi(8), Depth: 3, MaxDepth: 4, IndexAtDepth: bi(0), TraceIndex: bi(1), AttackGIndex: bi(16), DefendGIndex: bi(18)}, - {GIndex: bi(9), Depth: 3, MaxDepth: 4, IndexAtDepth: bi(1), TraceIndex: bi(3), AttackGIndex: bi(18)}, - {GIndex: bi(10), Depth: 3, MaxDepth: 4, IndexAtDepth: bi(2), TraceIndex: bi(5), AttackGIndex: bi(20), DefendGIndex: bi(22)}, - {GIndex: bi(11), Depth: 3, MaxDepth: 4, IndexAtDepth: bi(3), TraceIndex: bi(7), AttackGIndex: bi(22)}, - {GIndex: bi(12), Depth: 3, MaxDepth: 4, IndexAtDepth: bi(4), TraceIndex: bi(9), AttackGIndex: bi(24), DefendGIndex: bi(26)}, - {GIndex: bi(13), Depth: 3, MaxDepth: 4, IndexAtDepth: bi(5), TraceIndex: bi(11), AttackGIndex: bi(26)}, - {GIndex: bi(14), Depth: 3, MaxDepth: 4, IndexAtDepth: bi(6), TraceIndex: bi(13), AttackGIndex: bi(28), DefendGIndex: bi(30)}, - {GIndex: bi(15), Depth: 3, MaxDepth: 4, IndexAtDepth: bi(7), TraceIndex: bi(15), AttackGIndex: bi(30)}, - - {GIndex: bi(16), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(0), TraceIndex: bi(0)}, - {GIndex: bi(17), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(1), TraceIndex: bi(1)}, - {GIndex: bi(18), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(2), TraceIndex: bi(2)}, - {GIndex: bi(19), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(3), TraceIndex: bi(3)}, - {GIndex: bi(20), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(4), TraceIndex: bi(4)}, - {GIndex: bi(21), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(5), TraceIndex: bi(5)}, - {GIndex: bi(22), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(6), TraceIndex: bi(6)}, - {GIndex: bi(23), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(7), TraceIndex: bi(7)}, - {GIndex: bi(24), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(8), TraceIndex: bi(8)}, - {GIndex: bi(25), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(9), TraceIndex: bi(9)}, - {GIndex: bi(26), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(10), TraceIndex: bi(10)}, - {GIndex: bi(27), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(11), TraceIndex: bi(11)}, - {GIndex: bi(28), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(12), TraceIndex: bi(12)}, - {GIndex: bi(29), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(13), TraceIndex: bi(13)}, - {GIndex: bi(30), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(14), TraceIndex: bi(14)}, - {GIndex: bi(31), Depth: 4, MaxDepth: 4, IndexAtDepth: bi(15), TraceIndex: bi(15)}, - - {GIndex: bi(0).Mul(bi(math.MaxInt64), bi(2)), Depth: 63, MaxDepth: 64, IndexAtDepth: bi(9223372036854775806), TraceIndex: bi(0).Sub(bi(0).Mul(bi(math.MaxInt64), bi(2)), bi(1))}, -} + {bi(2), NewPosition(1, bi(0))}, + {bi(3), NewPosition(1, bi(1))}, + + {bi(4), NewPosition(2, bi(0))}, + {bi(5), NewPosition(2, bi(1))}, + {bi(6), NewPosition(2, bi(2))}, + {bi(7), NewPosition(2, bi(3))}, + + {bi(8), NewPosition(3, bi(0))}, + {bi(9), NewPosition(3, bi(1))}, + {bi(10), NewPosition(3, bi(2))}, + {bi(11), NewPosition(3, bi(3))}, + {bi(12), NewPosition(3, bi(4))}, + {bi(13), NewPosition(3, bi(5))}, + {bi(14), NewPosition(3, bi(6))}, + {bi(15), NewPosition(3, bi(7))}, -// TestGINConversions does To & From the generalized index on the treeNodesMaxDepth4 data -func TestGINConversions(t *testing.T) { - for _, test := range treeNodes { - from := NewPositionFromGIndex(test.GIndex) - pos := NewPosition(test.Depth, test.IndexAtDepth) - require.EqualValuesf(t, pos.Depth(), from.Depth(), "From GIndex %v vs pos %v", from.Depth(), pos.Depth()) - require.Zerof(t, pos.IndexAtDepth().Cmp(from.IndexAtDepth()), "From GIndex %v vs pos %v", from.IndexAtDepth(), pos.IndexAtDepth()) - to := pos.ToGIndex() - require.Equal(t, test.GIndex, to) + {bi(16), NewPosition(4, bi(0))}, + {bi(17), NewPosition(4, bi(1))}, + {bi(18), NewPosition(4, bi(2))}, + {bi(19), NewPosition(4, bi(3))}, + {bi(20), NewPosition(4, bi(4))}, + {bi(21), NewPosition(4, bi(5))}, + {bi(22), NewPosition(4, bi(6))}, + {bi(23), NewPosition(4, bi(7))}, + {bi(24), NewPosition(4, bi(8))}, + {bi(25), NewPosition(4, bi(9))}, + {bi(26), NewPosition(4, bi(10))}, + {bi(27), NewPosition(4, bi(11))}, + {bi(28), NewPosition(4, bi(12))}, + {bi(29), NewPosition(4, bi(13))}, + {bi(30), NewPosition(4, bi(14))}, + {bi(31), NewPosition(4, bi(15))}, + + {bi(1023), NewPosition(9, bi(511))}, + {bi(1024), NewPosition(10, bi(0))}, + } + for _, test := range tests { + t.Run(fmt.Sprintf("convert gindex=%s to Position", test.gindex.String()), func(t *testing.T) { + positionActual := NewPositionFromGIndex(test.gindex) + require.EqualValuesf(t, test.expectedPosition.Depth(), positionActual.Depth(), "expected depth=%s, got=%s", test.expectedPosition.Depth(), positionActual.Depth()) + require.Zerof(t, test.expectedPosition.IndexAtDepth().Cmp(positionActual.IndexAtDepth()), "expected indexAtDepth=%s, got=%s", test.expectedPosition.IndexAtDepth(), positionActual.IndexAtDepth()) + gindex := positionActual.ToGIndex() + require.Truef(t, gindex.Cmp(test.gindex) == 0, "expected gindex=%s, got=%s", test.gindex.String(), gindex.String()) + }) } } @@ -107,34 +101,102 @@ func TestTraceIndexOfRootWithLargeDepth(t *testing.T) { require.Equal(t, traceIdx, actual) } -// TestTraceIndex creates the position & then tests the trace index function on the treeNodesMaxDepth4 data +// TestTraceIndex creates the position & then tests the trace index function. func TestTraceIndex(t *testing.T) { - for _, test := range treeNodes { - pos := NewPosition(test.Depth, test.IndexAtDepth) - result := pos.TraceIndex(test.MaxDepth) - require.Equal(t, test.TraceIndex, result) + tests := []struct { + depth Depth + indexAtDepth *big.Int + maxDepth Depth + traceIndexExpected *big.Int + }{ + {depth: 0, indexAtDepth: bi(0), maxDepth: 4, traceIndexExpected: bi(15)}, + + {depth: 1, indexAtDepth: bi(0), maxDepth: 4, traceIndexExpected: bi(7)}, + {depth: 1, indexAtDepth: bi(1), maxDepth: 4, traceIndexExpected: bi(15)}, + + {depth: 2, indexAtDepth: bi(0), maxDepth: 4, traceIndexExpected: bi(3)}, + {depth: 2, indexAtDepth: bi(1), maxDepth: 4, traceIndexExpected: bi(7)}, + {depth: 2, indexAtDepth: bi(2), maxDepth: 4, traceIndexExpected: bi(11)}, + {depth: 2, indexAtDepth: bi(3), maxDepth: 4, traceIndexExpected: bi(15)}, + + {depth: 3, indexAtDepth: bi(0), maxDepth: 4, traceIndexExpected: bi(1)}, + {depth: 3, indexAtDepth: bi(1), maxDepth: 4, traceIndexExpected: bi(3)}, + {depth: 3, indexAtDepth: bi(2), maxDepth: 4, traceIndexExpected: bi(5)}, + {depth: 3, indexAtDepth: bi(3), maxDepth: 4, traceIndexExpected: bi(7)}, + {depth: 3, indexAtDepth: bi(4), maxDepth: 4, traceIndexExpected: bi(9)}, + {depth: 3, indexAtDepth: bi(5), maxDepth: 4, traceIndexExpected: bi(11)}, + {depth: 3, indexAtDepth: bi(6), maxDepth: 4, traceIndexExpected: bi(13)}, + {depth: 3, indexAtDepth: bi(7), maxDepth: 4, traceIndexExpected: bi(15)}, + + {depth: 4, indexAtDepth: bi(0), maxDepth: 4, traceIndexExpected: bi(0)}, + {depth: 4, indexAtDepth: bi(1), maxDepth: 4, traceIndexExpected: bi(1)}, + {depth: 4, indexAtDepth: bi(2), maxDepth: 4, traceIndexExpected: bi(2)}, + {depth: 4, indexAtDepth: bi(3), maxDepth: 4, traceIndexExpected: bi(3)}, + {depth: 4, indexAtDepth: bi(4), maxDepth: 4, traceIndexExpected: bi(4)}, + {depth: 4, indexAtDepth: bi(5), maxDepth: 4, traceIndexExpected: bi(5)}, + {depth: 4, indexAtDepth: bi(6), maxDepth: 4, traceIndexExpected: bi(6)}, + {depth: 4, indexAtDepth: bi(7), maxDepth: 4, traceIndexExpected: bi(7)}, + {depth: 4, indexAtDepth: bi(8), maxDepth: 4, traceIndexExpected: bi(8)}, + {depth: 4, indexAtDepth: bi(9), maxDepth: 4, traceIndexExpected: bi(9)}, + {depth: 4, indexAtDepth: bi(10), maxDepth: 4, traceIndexExpected: bi(10)}, + {depth: 4, indexAtDepth: bi(11), maxDepth: 4, traceIndexExpected: bi(11)}, + {depth: 4, indexAtDepth: bi(12), maxDepth: 4, traceIndexExpected: bi(12)}, + {depth: 4, indexAtDepth: bi(13), maxDepth: 4, traceIndexExpected: bi(13)}, + {depth: 4, indexAtDepth: bi(14), maxDepth: 4, traceIndexExpected: bi(14)}, + {depth: 4, indexAtDepth: bi(15), maxDepth: 4, traceIndexExpected: bi(15)}, + + {depth: 63, indexAtDepth: bi(9223372036854775806), maxDepth: 64, traceIndexExpected: bi(0).Sub(bi(0).Mul(bi(math.MaxInt64), bi(2)), bi(1))}, + } + for _, test := range tests { + require.Equal(t, test.traceIndexExpected, NewPosition(test.depth, test.indexAtDepth).TraceIndex(test.maxDepth)) } } func TestAttack(t *testing.T) { - for _, test := range treeNodes { - if test.AttackGIndex == nil || test.AttackGIndex.Cmp(big.NewInt(0)) == 0 { - continue - } - pos := NewPosition(test.Depth, test.IndexAtDepth) + tests := []struct { + startGIndex *big.Int + attackGIndex *big.Int + }{ + {bi(1), bi(2)}, + {bi(2), bi(4)}, + {bi(3), bi(6)}, + {bi(4), bi(8)}, + {bi(5), bi(10)}, + {bi(6), bi(12)}, + {bi(7), bi(14)}, + {bi(8), bi(16)}, + {bi(9), bi(18)}, + {bi(10), bi(20)}, + {bi(11), bi(22)}, + {bi(12), bi(24)}, + {bi(13), bi(26)}, + {bi(14), bi(28)}, + {bi(15), bi(30)}, + } + for _, test := range tests { + pos := NewPositionFromGIndex(test.startGIndex) result := pos.Attack() - require.Equalf(t, test.AttackGIndex, result.ToGIndex(), "Attack from GIndex %v", pos.ToGIndex()) + require.Equalf(t, test.attackGIndex, result.ToGIndex(), "attacking GIndex %s, expected=%s, got=%s", test.startGIndex, test.attackGIndex, result.ToGIndex()) } } func TestDefend(t *testing.T) { - for _, test := range treeNodes { - if test.DefendGIndex == nil || test.DefendGIndex.Cmp(big.NewInt(0)) == 0 { - continue - } - pos := NewPosition(test.Depth, test.IndexAtDepth) + tests := []struct { + startGIndex *big.Int + defendGIndex *big.Int + }{ + {bi(2), bi(6)}, + {bi(4), bi(10)}, + {bi(6), bi(14)}, + {bi(8), bi(18)}, + {bi(10), bi(22)}, + {bi(12), bi(26)}, + {bi(14), bi(30)}, + } + for _, test := range tests { + pos := NewPositionFromGIndex(test.startGIndex) result := pos.Defend() - require.Equalf(t, test.DefendGIndex, result.ToGIndex(), "Defend from GIndex %v", pos.ToGIndex()) + require.Equalf(t, test.defendGIndex, result.ToGIndex(), "defending GIndex %s, expected=%s, got=%s", test.startGIndex, test.defendGIndex, result.ToGIndex()) } } @@ -145,11 +207,106 @@ func TestRelativeToAncestorAtDepth(t *testing.T) { require.ErrorIs(t, err, ErrPositionDepthTooSmall) }) - t.Run("Success", func(t *testing.T) { - pos := NewPosition(2, big.NewInt(1)) - expectedRelativePosition := NewPosition(1, big.NewInt(1)) - relativePosition, err := pos.RelativeToAncestorAtDepth(1) - require.NoError(t, err) - require.Equal(t, expectedRelativePosition, relativePosition) - }) + tests := []struct { + gindex int64 + newRootDepth Depth + expectedGIndex int64 + }{ + {gindex: 5, newRootDepth: 1, expectedGIndex: 3}, + + // Depth 0 (should return position unchanged) + {gindex: 1, newRootDepth: 0, expectedGIndex: 1}, + {gindex: 2, newRootDepth: 0, expectedGIndex: 2}, + + // Depth 1 + {gindex: 2, newRootDepth: 1, expectedGIndex: 1}, + {gindex: 3, newRootDepth: 1, expectedGIndex: 1}, + {gindex: 4, newRootDepth: 1, expectedGIndex: 2}, + {gindex: 5, newRootDepth: 1, expectedGIndex: 3}, + {gindex: 6, newRootDepth: 1, expectedGIndex: 2}, + {gindex: 7, newRootDepth: 1, expectedGIndex: 3}, + {gindex: 8, newRootDepth: 1, expectedGIndex: 4}, + {gindex: 9, newRootDepth: 1, expectedGIndex: 5}, + {gindex: 10, newRootDepth: 1, expectedGIndex: 6}, + {gindex: 11, newRootDepth: 1, expectedGIndex: 7}, + {gindex: 12, newRootDepth: 1, expectedGIndex: 4}, + {gindex: 13, newRootDepth: 1, expectedGIndex: 5}, + {gindex: 14, newRootDepth: 1, expectedGIndex: 6}, + {gindex: 15, newRootDepth: 1, expectedGIndex: 7}, + {gindex: 16, newRootDepth: 1, expectedGIndex: 8}, + {gindex: 17, newRootDepth: 1, expectedGIndex: 9}, + {gindex: 18, newRootDepth: 1, expectedGIndex: 10}, + {gindex: 19, newRootDepth: 1, expectedGIndex: 11}, + {gindex: 20, newRootDepth: 1, expectedGIndex: 12}, + {gindex: 21, newRootDepth: 1, expectedGIndex: 13}, + {gindex: 22, newRootDepth: 1, expectedGIndex: 14}, + {gindex: 23, newRootDepth: 1, expectedGIndex: 15}, + {gindex: 24, newRootDepth: 1, expectedGIndex: 8}, + {gindex: 25, newRootDepth: 1, expectedGIndex: 9}, + {gindex: 26, newRootDepth: 1, expectedGIndex: 10}, + {gindex: 27, newRootDepth: 1, expectedGIndex: 11}, + {gindex: 28, newRootDepth: 1, expectedGIndex: 12}, + {gindex: 29, newRootDepth: 1, expectedGIndex: 13}, + {gindex: 30, newRootDepth: 1, expectedGIndex: 14}, + {gindex: 31, newRootDepth: 1, expectedGIndex: 15}, + + // Depth 2 + {gindex: 4, newRootDepth: 2, expectedGIndex: 1}, + {gindex: 5, newRootDepth: 2, expectedGIndex: 1}, + {gindex: 6, newRootDepth: 2, expectedGIndex: 1}, + {gindex: 7, newRootDepth: 2, expectedGIndex: 1}, + {gindex: 8, newRootDepth: 2, expectedGIndex: 2}, + {gindex: 9, newRootDepth: 2, expectedGIndex: 3}, + {gindex: 10, newRootDepth: 2, expectedGIndex: 2}, + {gindex: 11, newRootDepth: 2, expectedGIndex: 3}, + {gindex: 12, newRootDepth: 2, expectedGIndex: 2}, + {gindex: 13, newRootDepth: 2, expectedGIndex: 3}, + {gindex: 14, newRootDepth: 2, expectedGIndex: 2}, + {gindex: 15, newRootDepth: 2, expectedGIndex: 3}, + } + + for _, test := range tests { + test := test + t.Run(fmt.Sprintf("From %v SplitAt %v", test.gindex, test.newRootDepth), func(t *testing.T) { + pos := NewPositionFromGIndex(big.NewInt(test.gindex)) + expectedRelativePosition := NewPositionFromGIndex(big.NewInt(test.expectedGIndex)) + relativePosition, err := pos.RelativeToAncestorAtDepth(test.newRootDepth) + require.NoError(t, err) + require.Equal(t, expectedRelativePosition.ToGIndex(), relativePosition.ToGIndex()) + }) + } +} + +func TestRelativeMoves(t *testing.T) { + tests := []func(pos Position) Position{ + func(pos Position) Position { + return pos.Attack() + }, + func(pos Position) Position { + return pos.Defend() + }, + func(pos Position) Position { + return pos.Attack().Attack() + }, + func(pos Position) Position { + return pos.Defend().Defend() + }, + func(pos Position) Position { + return pos.Attack().Defend() + }, + func(pos Position) Position { + return pos.Defend().Attack() + }, + } + for _, test := range tests { + test := test + t.Run("", func(t *testing.T) { + expectedRelativePosition := test(NewPositionFromGIndex(big.NewInt(1))) + relative := NewPositionFromGIndex(big.NewInt(3)) + start := test(relative) + relativePosition, err := start.RelativeToAncestorAtDepth(relative.Depth()) + require.NoError(t, err) + require.Equal(t, expectedRelativePosition.ToGIndex(), relativePosition.ToGIndex()) + }) + } } diff --git a/op-challenger/game/fault/types/types.go b/op-challenger/game/fault/types/types.go index 68497a377e66..2e3d2c42f391 100644 --- a/op-challenger/game/fault/types/types.go +++ b/op-challenger/game/fault/types/types.go @@ -4,22 +4,39 @@ import ( "context" "errors" "math/big" + "time" + preimage "github.com/ethereum-optimism/optimism/op-preimage" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" ) var ( ErrGameDepthReached = errors.New("game depth reached") ) +const ( + CannonGameType uint32 = 0 + PermissionedGameType uint32 = 1 + AlphabetGameType uint32 = 255 +) + +type ClockReader interface { + Now() time.Time +} + // PreimageOracleData encapsulates the preimage oracle data // to load into the onchain oracle. type PreimageOracleData struct { IsLocal bool - LocalContext uint64 OracleKey []byte - OracleData []byte + oracleData []byte OracleOffset uint32 + + // 4844 blob data + BlobFieldIndex uint64 + BlobCommitment []byte + BlobProof []byte } // GetIdent returns the ident for the preimage oracle data. @@ -29,20 +46,44 @@ func (p *PreimageOracleData) GetIdent() *big.Int { // GetPreimageWithoutSize returns the preimage for the preimage oracle data. func (p *PreimageOracleData) GetPreimageWithoutSize() []byte { - return p.OracleData[8:] + return p.oracleData[8:] +} + +// GetPreimageWithSize returns the preimage with its length prefix. +func (p *PreimageOracleData) GetPreimageWithSize() []byte { + return p.oracleData +} + +func (p *PreimageOracleData) GetPrecompileAddress() common.Address { + return common.BytesToAddress(p.oracleData[8:28]) +} + +func (p *PreimageOracleData) GetPrecompileInput() []byte { + return p.oracleData[28:] } // NewPreimageOracleData creates a new [PreimageOracleData] instance. -func NewPreimageOracleData(lctx uint64, key []byte, data []byte, offset uint32) *PreimageOracleData { +func NewPreimageOracleData(key []byte, data []byte, offset uint32) *PreimageOracleData { return &PreimageOracleData{ - IsLocal: len(key) > 0 && key[0] == byte(1), - LocalContext: lctx, + IsLocal: len(key) > 0 && key[0] == byte(preimage.LocalKeyType), OracleKey: key, - OracleData: data, + oracleData: data, OracleOffset: offset, } } +func NewPreimageOracleBlobData(key []byte, data []byte, offset uint32, fieldIndex uint64, commitment []byte, proof []byte) *PreimageOracleData { + return &PreimageOracleData{ + IsLocal: false, + OracleKey: key, + oracleData: data, + OracleOffset: offset, + BlobFieldIndex: fieldIndex, + BlobCommitment: commitment, + BlobProof: proof, + } +} + // StepCallData encapsulates the data needed to perform a step. type StepCallData struct { ClaimIndex uint64 @@ -51,14 +92,28 @@ type StepCallData struct { Proof []byte } -// OracleUpdater is a generic interface for updating oracles. -type OracleUpdater interface { - // UpdateOracle updates the oracle with the given data. - UpdateOracle(ctx context.Context, data *PreimageOracleData) error +// TraceAccessor defines an interface to request data from a TraceProvider with additional context for the game position. +// This can be used to implement split games where lower layers of the game may have different values depending on claims +// at higher levels in the game. +type TraceAccessor interface { + // Get returns the claim value at the requested position, evaluated in the context of the specified claim (ref). + Get(ctx context.Context, game Game, ref Claim, pos Position) (common.Hash, error) + + // GetStepData returns the data required to execute the step at the specified position, + // evaluated in the context of the specified claim (ref). + GetStepData(ctx context.Context, game Game, ref Claim, pos Position) (prestate []byte, proofData []byte, preimageData *PreimageOracleData, err error) +} + +// PrestateProvider defines an interface to request the absolute prestate. +type PrestateProvider interface { + // AbsolutePreStateCommitment is the commitment of the pre-image value of the trace that transitions to the trace value at index 0 + AbsolutePreStateCommitment(ctx context.Context) (hash common.Hash, err error) } // TraceProvider is a generic way to get a claim value at a specific step in the trace. type TraceProvider interface { + PrestateProvider + // Get returns the claim value at the requested index. // Get(i) = Keccak256(GetPreimage(i)) Get(ctx context.Context, i Position) (common.Hash, error) @@ -68,17 +123,12 @@ type TraceProvider interface { // and any pre-image data that needs to be loaded into the oracle prior to execution (may be nil) // The prestate returned from GetStepData for trace 10 should be the pre-image of the claim from trace 9 GetStepData(ctx context.Context, i Position) (prestate []byte, proofData []byte, preimageData *PreimageOracleData, err error) - - // AbsolutePreState is the pre-image value of the trace that transitions to the trace value at index 0 - AbsolutePreState(ctx context.Context) (preimage []byte, err error) - - // AbsolutePreStateCommitment is the commitment of the pre-image value of the trace that transitions to the trace value at index 0 - AbsolutePreStateCommitment(ctx context.Context) (hash common.Hash, err error) } // ClaimData is the core of a claim. It must be unique inside a specific game. type ClaimData struct { Value common.Hash + Bond *big.Int Position } @@ -89,25 +139,68 @@ func (c *ClaimData) ValueBytes() [32]byte { return responseArr } +type ClaimID common.Hash + // Claim extends ClaimData with information about the relationship between two claims. // It uses ClaimData to break cyclicity without using pointers. // If the position of the game is Depth 0, IndexAtDepth 0 it is the root claim // and the Parent field is empty & meaningless. type Claim struct { ClaimData - // WARN: Countered is a mutable field in the FaultDisputeGame contract + // WARN: CounteredBy is a mutable field in the FaultDisputeGame contract // and rely on it for determining whether to step on leaf claims. // When caching is implemented for the Challenger, this will need // to be changed/removed to avoid invalid/stale contract state. - Countered bool - Clock uint64 + CounteredBy common.Address + Claimant common.Address + Clock *Clock // Location of the claim & it's parent inside the contract. Does not exist // for claims that have not made it to the contract. ContractIndex int ParentContractIndex int } +func (c Claim) ID() ClaimID { + return ClaimID(crypto.Keccak256Hash( + c.Position.ToGIndex().Bytes(), + c.Value.Bytes(), + big.NewInt(int64(c.ParentContractIndex)).Bytes(), + )) +} + // IsRoot returns true if this claim is the root claim. func (c *Claim) IsRoot() bool { return c.Position.IsRootPosition() } + +// ChessTime returns the amount of time accumulated in the chess clock. +// Does not assume the claim is countered and uses the specified time +// to calculate the time since the claim was posted. +func (c *Claim) ChessTime(now time.Time) time.Duration { + timeSince := int64(0) + if now.Unix() > int64(c.Clock.Timestamp) { + timeSince = now.Unix() - int64(c.Clock.Timestamp) + } + return time.Duration(c.Clock.Duration) + time.Duration(timeSince) +} + +// Clock is a packed uint128 with the upper 64 bits being the +// duration and the lower 64 bits being the timestamp. +// ┌────────────┬────────────────┐ +// │ Bits │ Value │ +// ├────────────┼────────────────┤ +// │ [0, 64) │ Duration │ +// │ [64, 128) │ Timestamp │ +// └────────────┴────────────────┘ +type Clock struct { + Duration uint64 + Timestamp uint64 +} + +// NewClock creates a new Clock instance. +func NewClock(duration uint64, timestamp uint64) *Clock { + return &Clock{ + Duration: duration, + Timestamp: timestamp, + } +} diff --git a/op-challenger/game/fault/types/types_test.go b/op-challenger/game/fault/types/types_test.go index a155612481fb..8ea40ab67790 100644 --- a/op-challenger/game/fault/types/types_test.go +++ b/op-challenger/game/fault/types/types_test.go @@ -3,26 +3,81 @@ package types import ( "math/big" "testing" + "time" "github.com/stretchr/testify/require" ) +func TestClaim_RemainingDuration(t *testing.T) { + tests := []struct { + name string + duration uint64 + timestamp uint64 + now int64 + expected uint64 + }{ + { + name: "AllZeros", + duration: 0, + timestamp: 0, + now: 0, + expected: 0, + }, + { + name: "ZeroTimestamp", + duration: 5, + timestamp: 0, + now: 0, + expected: 5, + }, + { + name: "ZeroTimestampWithNow", + duration: 5, + timestamp: 0, + now: 10, + expected: 15, + }, + { + name: "ZeroNow", + duration: 5, + timestamp: 10, + now: 0, + expected: 5, + }, + { + name: "ValidTimeSinze", + duration: 20, + timestamp: 10, + now: 15, + expected: 25, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + claim := &Claim{ + Clock: NewClock(test.duration, test.timestamp), + } + require.Equal(t, time.Duration(test.expected), claim.ChessTime(time.Unix(test.now, 0))) + }) + } +} + func TestNewPreimageOracleData(t *testing.T) { t.Run("LocalData", func(t *testing.T) { - data := NewPreimageOracleData(1, []byte{1, 2, 3}, []byte{4, 5, 6}, 7) + data := NewPreimageOracleData([]byte{1, 2, 3}, []byte{4, 5, 6}, 7) require.True(t, data.IsLocal) - require.Equal(t, uint64(1), data.LocalContext) require.Equal(t, []byte{1, 2, 3}, data.OracleKey) - require.Equal(t, []byte{4, 5, 6}, data.OracleData) + require.Equal(t, []byte{4, 5, 6}, data.GetPreimageWithSize()) require.Equal(t, uint32(7), data.OracleOffset) }) t.Run("GlobalData", func(t *testing.T) { - data := NewPreimageOracleData(1, []byte{0, 2, 3}, []byte{4, 5, 6}, 7) + data := NewPreimageOracleData([]byte{0, 2, 3}, []byte{4, 5, 6}, 7) require.False(t, data.IsLocal) - require.Equal(t, uint64(1), data.LocalContext) require.Equal(t, []byte{0, 2, 3}, data.OracleKey) - require.Equal(t, []byte{4, 5, 6}, data.OracleData) + require.Equal(t, []byte{4, 5, 6}, data.GetPreimageWithSize()) require.Equal(t, uint32(7), data.OracleOffset) }) } diff --git a/op-challenger/game/fault/validator.go b/op-challenger/game/fault/validator.go new file mode 100644 index 000000000000..93d9d3dca461 --- /dev/null +++ b/op-challenger/game/fault/validator.go @@ -0,0 +1,50 @@ +package fault + +import ( + "bytes" + "context" + "fmt" + + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" +) + +type PrestateLoader = func(ctx context.Context) (common.Hash, error) + +type Validator interface { + Validate(ctx context.Context) error +} + +var _ Validator = (*PrestateValidator)(nil) + +type PrestateValidator struct { + valueName string + load PrestateLoader + provider types.PrestateProvider +} + +func NewPrestateValidator(valueName string, contractProvider PrestateLoader, localProvider types.PrestateProvider) *PrestateValidator { + return &PrestateValidator{ + valueName: valueName, + load: contractProvider, + provider: localProvider, + } +} + +func (v *PrestateValidator) Validate(ctx context.Context) error { + prestateHash, err := v.load(ctx) + if err != nil { + return fmt.Errorf("failed to get prestate hash from loader: %w", err) + } + prestateCommitment, err := v.provider.AbsolutePreStateCommitment(ctx) + if err != nil { + return fmt.Errorf("failed to fetch provider's prestate hash: %w", err) + } + if !bytes.Equal(prestateCommitment[:], prestateHash[:]) { + return fmt.Errorf("%v %w: Provider: %s | Contract: %s", + v.valueName, gameTypes.ErrInvalidPrestate, prestateCommitment.Hex(), prestateHash.Hex()) + } + return nil +} diff --git a/op-challenger/game/fault/validator_test.go b/op-challenger/game/fault/validator_test.go new file mode 100644 index 000000000000..6782e2651b46 --- /dev/null +++ b/op-challenger/game/fault/validator_test.go @@ -0,0 +1,92 @@ +package fault + +import ( + "context" + "fmt" + "testing" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" +) + +var ( + prestate = []byte{0x00, 0x01, 0x02, 0x03} + mockProviderError = fmt.Errorf("mock provider error") + mockLoaderError = fmt.Errorf("mock loader error") +) + +func TestValidate(t *testing.T) { + t.Run("ValidPrestates", func(t *testing.T) { + prestateHash := crypto.Keccak256(prestate) + prestateHash[0] = mipsevm.VMStatusUnfinished + player := &PrestateValidator{ + load: newMockPrestateLoader(false, common.BytesToHash(prestateHash)), + provider: newMockPrestateProvider(false, prestate), + } + err := player.Validate(context.Background()) + require.NoError(t, err) + }) + + t.Run("ProviderErrors", func(t *testing.T) { + player := &PrestateValidator{ + load: newMockPrestateLoader(false, common.BytesToHash(prestate)), + provider: newMockPrestateProvider(true, prestate), + } + err := player.Validate(context.Background()) + require.ErrorIs(t, err, mockProviderError) + }) + + t.Run("LoaderErrors", func(t *testing.T) { + player := &PrestateValidator{ + load: newMockPrestateLoader(true, common.BytesToHash(prestate)), + provider: newMockPrestateProvider(false, prestate), + } + err := player.Validate(context.Background()) + require.ErrorIs(t, err, mockLoaderError) + }) + + t.Run("PrestateMismatch", func(t *testing.T) { + player := &PrestateValidator{ + load: newMockPrestateLoader(false, common.BytesToHash([]byte{0x00})), + provider: newMockPrestateProvider(false, prestate), + } + err := player.Validate(context.Background()) + require.ErrorIs(t, err, gameTypes.ErrInvalidPrestate) + }) +} + +var _ types.PrestateProvider = (*mockPrestateProvider)(nil) + +type mockPrestateProvider struct { + prestateErrors bool + prestate []byte +} + +func newMockPrestateProvider(prestateErrors bool, prestate []byte) *mockPrestateProvider { + return &mockPrestateProvider{ + prestateErrors: prestateErrors, + prestate: prestate, + } +} + +func (m *mockPrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { + if m.prestateErrors { + return common.Hash{}, mockProviderError + } + hash := common.BytesToHash(crypto.Keccak256(m.prestate)) + hash[0] = mipsevm.VMStatusUnfinished + return hash, nil +} + +func newMockPrestateLoader(prestateError bool, prestate common.Hash) PrestateLoader { + return func(ctx context.Context) (common.Hash, error) { + if prestateError { + return common.Hash{}, mockLoaderError + } + return prestate, nil + } +} diff --git a/op-challenger/game/keccak/challenger.go b/op-challenger/game/keccak/challenger.go new file mode 100644 index 000000000000..362c432e3150 --- /dev/null +++ b/op-challenger/game/keccak/challenger.go @@ -0,0 +1,91 @@ +package keccak + +import ( + "context" + "errors" + "fmt" + "sync" + + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/matrix" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +type Oracle interface { + VerifierPreimageOracle + ChallengeTx(ident keccakTypes.LargePreimageIdent, challenge keccakTypes.Challenge) (txmgr.TxCandidate, error) +} + +type ChallengeMetrics interface { + RecordPreimageChallenged() + RecordPreimageChallengeFailed() +} + +type Verifier interface { + CreateChallenge(ctx context.Context, blockHash common.Hash, oracle VerifierPreimageOracle, preimage keccakTypes.LargePreimageMetaData) (keccakTypes.Challenge, error) +} + +type Sender interface { + SendAndWait(txPurpose string, txs ...txmgr.TxCandidate) ([]*types.Receipt, error) +} + +type PreimageChallenger struct { + log log.Logger + metrics ChallengeMetrics + verifier Verifier + sender Sender +} + +func NewPreimageChallenger(logger log.Logger, metrics ChallengeMetrics, verifier Verifier, sender Sender) *PreimageChallenger { + return &PreimageChallenger{ + log: logger, + metrics: metrics, + verifier: verifier, + sender: sender, + } +} + +func (c *PreimageChallenger) Challenge(ctx context.Context, blockHash common.Hash, oracle Oracle, preimages []keccakTypes.LargePreimageMetaData) error { + var txLock sync.Mutex + var wg sync.WaitGroup + var txs []txmgr.TxCandidate + for _, preimage := range preimages { + preimage := preimage + wg.Add(1) + go func() { + defer wg.Done() + logger := c.log.New("oracle", oracle.Addr(), "claimant", preimage.Claimant, "uuid", preimage.UUID) + challenge, err := c.verifier.CreateChallenge(ctx, blockHash, oracle, preimage) + if errors.Is(err, matrix.ErrValid) { + logger.Debug("Preimage is valid") + return + } else if err != nil { + logger.Error("Failed to verify large preimage", "err", err) + return + } + logger.Info("Challenging preimage", "block", challenge.Poststate.Index) + tx, err := oracle.ChallengeTx(preimage.LargePreimageIdent, challenge) + if err != nil { + logger.Error("Failed to create challenge transaction", "err", err) + return + } + txLock.Lock() + defer txLock.Unlock() + txs = append(txs, tx) + }() + } + wg.Wait() + c.log.Debug("Created preimage challenge transactions", "count", len(txs)) + if len(txs) > 0 { + _, err := c.sender.SendAndWait("challenge preimages", txs...) + if err != nil { + c.metrics.RecordPreimageChallengeFailed() + return fmt.Errorf("failed to send challenge txs: %w", err) + } + c.metrics.RecordPreimageChallenged() + } + return nil +} diff --git a/op-challenger/game/keccak/challenger_test.go b/op-challenger/game/keccak/challenger_test.go new file mode 100644 index 000000000000..0c9c0424034a --- /dev/null +++ b/op-challenger/game/keccak/challenger_test.go @@ -0,0 +1,175 @@ +package keccak + +import ( + "context" + "errors" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/matrix" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestChallenge(t *testing.T) { + preimages := []keccakTypes.LargePreimageMetaData{ + { + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xff, 0x00}, + UUID: big.NewInt(0), + }, + }, + { + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xff, 0x01}, + UUID: big.NewInt(1), + }, + }, + { + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xff, 0x02}, + UUID: big.NewInt(2), + }, + }, + } + + logger := testlog.Logger(t, log.LevelInfo) + + t.Run("SendChallenges", func(t *testing.T) { + verifier, sender, oracle, challenger := setupChallengerTest(logger) + verifier.challenges[preimages[1].LargePreimageIdent] = keccakTypes.Challenge{StateMatrix: keccakTypes.StateSnapshot{0x01}} + verifier.challenges[preimages[2].LargePreimageIdent] = keccakTypes.Challenge{StateMatrix: keccakTypes.StateSnapshot{0x02}} + err := challenger.Challenge(context.Background(), common.Hash{0xaa}, oracle, preimages) + require.NoError(t, err) + + // Should send the two challenges before returning + require.Len(t, sender.sent, 1, "Should send a single batch of transactions") + for ident, challenge := range verifier.challenges { + tx, err := oracle.ChallengeTx(ident, challenge) + require.NoError(t, err) + require.Contains(t, sender.sent[0], tx) + } + }) + + t.Run("ReturnErrorWhenSendingFails", func(t *testing.T) { + verifier, sender, oracle, challenger := setupChallengerTest(logger) + verifier.challenges[preimages[1].LargePreimageIdent] = keccakTypes.Challenge{StateMatrix: keccakTypes.StateSnapshot{0x01}} + sender.err = errors.New("boom") + err := challenger.Challenge(context.Background(), common.Hash{0xaa}, oracle, preimages) + require.ErrorIs(t, err, sender.err) + }) + + t.Run("LogErrorWhenCreateTxFails", func(t *testing.T) { + logger, logs := testlog.CaptureLogger(t, log.LevelInfo) + + verifier, _, oracle, challenger := setupChallengerTest(logger) + verifier.challenges[preimages[1].LargePreimageIdent] = keccakTypes.Challenge{StateMatrix: keccakTypes.StateSnapshot{0x01}} + oracle.err = errors.New("boom") + err := challenger.Challenge(context.Background(), common.Hash{0xaa}, oracle, preimages) + require.NoError(t, err) + + levelFilter := testlog.NewLevelFilter(log.LevelError) + msgFilter := testlog.NewMessageFilter("Failed to create challenge transaction") + errLog := logs.FindLog(levelFilter, msgFilter) + require.ErrorIs(t, errLog.AttrValue("err").(error), oracle.err) + }) + + t.Run("LogErrorWhenVerifierFails", func(t *testing.T) { + logger, logs := testlog.CaptureLogger(t, log.LevelInfo) + + verifier, _, oracle, challenger := setupChallengerTest(logger) + verifier.challenges[preimages[1].LargePreimageIdent] = keccakTypes.Challenge{StateMatrix: keccakTypes.StateSnapshot{0x01}} + verifier.err = errors.New("boom") + err := challenger.Challenge(context.Background(), common.Hash{0xaa}, oracle, preimages) + require.NoError(t, err) + + levelFilter := testlog.NewLevelFilter(log.LevelError) + msgFilter := testlog.NewMessageFilter("Failed to verify large preimage") + errLog := logs.FindLog(levelFilter, msgFilter) + require.ErrorIs(t, errLog.AttrValue("err").(error), verifier.err) + }) + + t.Run("DoNotLogErrValid", func(t *testing.T) { + logger, logs := testlog.CaptureLogger(t, log.LevelInfo) + + _, _, oracle, challenger := setupChallengerTest(logger) + // All preimages are valid + err := challenger.Challenge(context.Background(), common.Hash{0xaa}, oracle, preimages) + require.NoError(t, err) + + levelFilter := testlog.NewLevelFilter(log.LevelError) + msgFilter := testlog.NewMessageFilter("Failed to verify large preimage") + errLog := logs.FindLog(levelFilter, msgFilter) + require.Nil(t, errLog) + + levelFilter = testlog.NewLevelFilter(log.LevelDebug) + msgFilter = testlog.NewMessageFilter("Preimage is valid") + dbgLog := logs.FindLog(levelFilter, msgFilter) + require.NotNil(t, dbgLog) + }) +} + +func setupChallengerTest(logger log.Logger) (*stubVerifier, *stubSender, *stubChallengerOracle, *PreimageChallenger) { + verifier := &stubVerifier{ + challenges: make(map[keccakTypes.LargePreimageIdent]keccakTypes.Challenge), + } + sender := &stubSender{} + oracle := &stubChallengerOracle{} + metrics := &mockChallengeMetrics{} + challenger := NewPreimageChallenger(logger, metrics, verifier, sender) + return verifier, sender, oracle, challenger +} + +type mockChallengeMetrics struct{} + +func (m *mockChallengeMetrics) RecordPreimageChallenged() {} +func (m *mockChallengeMetrics) RecordPreimageChallengeFailed() {} + +type stubVerifier struct { + challenges map[keccakTypes.LargePreimageIdent]keccakTypes.Challenge + err error +} + +func (s *stubVerifier) CreateChallenge(_ context.Context, _ common.Hash, _ VerifierPreimageOracle, preimage keccakTypes.LargePreimageMetaData) (keccakTypes.Challenge, error) { + if s.err != nil { + return keccakTypes.Challenge{}, s.err + } + challenge, ok := s.challenges[preimage.LargePreimageIdent] + if !ok { + return keccakTypes.Challenge{}, matrix.ErrValid + } + return challenge, nil +} + +type stubSender struct { + err error + sent [][]txmgr.TxCandidate +} + +func (s *stubSender) SendAndWait(_ string, txs ...txmgr.TxCandidate) ([]*types.Receipt, error) { + if s.err != nil { + return nil, s.err + } + s.sent = append(s.sent, txs) + return nil, nil +} + +type stubChallengerOracle struct { + stubOracle + err error +} + +func (s *stubChallengerOracle) ChallengeTx(ident keccakTypes.LargePreimageIdent, challenge keccakTypes.Challenge) (txmgr.TxCandidate, error) { + if s.err != nil { + return txmgr.TxCandidate{}, s.err + } + return txmgr.TxCandidate{ + To: &ident.Claimant, + TxData: append(ident.UUID.Bytes(), challenge.StateMatrix.Pack()...), + }, nil +} diff --git a/op-challenger/game/keccak/fetcher/fetcher.go b/op-challenger/game/keccak/fetcher/fetcher.go new file mode 100644 index 000000000000..755f96b164f3 --- /dev/null +++ b/op-challenger/game/keccak/fetcher/fetcher.go @@ -0,0 +1,116 @@ +package fetcher + +import ( + "context" + "errors" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +var ( + ErrNoLeavesFound = errors.New("no leaves found in block") +) + +type L1Source interface { + BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) + TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) + ChainID(ctx context.Context) (*big.Int, error) +} + +type Oracle interface { + Addr() common.Address + GetInputDataBlocks(ctx context.Context, block rpcblock.Block, ident keccakTypes.LargePreimageIdent) ([]uint64, error) + DecodeInputData(data []byte) (*big.Int, keccakTypes.InputData, error) +} + +type InputFetcher struct { + log log.Logger + source L1Source +} + +func (f *InputFetcher) FetchInputs(ctx context.Context, blockHash common.Hash, oracle Oracle, ident keccakTypes.LargePreimageIdent) ([]keccakTypes.InputData, error) { + blockNums, err := oracle.GetInputDataBlocks(ctx, rpcblock.ByHash(blockHash), ident) + if err != nil { + return nil, fmt.Errorf("failed to retrieve leaf block nums: %w", err) + } + chainID, err := f.source.ChainID(ctx) + if err != nil { + return nil, fmt.Errorf("failed to retrieve L1 chain ID: %w", err) + } + signer := types.LatestSignerForChainID(chainID) + var inputs []keccakTypes.InputData + for _, blockNum := range blockNums { + foundRelevantTx := false + block, err := f.source.BlockByNumber(ctx, new(big.Int).SetUint64(blockNum)) + if err != nil { + return nil, fmt.Errorf("failed getting tx for block %v: %w", blockNum, err) + } + for _, tx := range block.Transactions() { + inputData, err := f.extractRelevantLeavesFromTx(ctx, oracle, signer, tx, ident) + if err != nil { + return nil, err + } + if inputData != nil { + foundRelevantTx = true + inputs = append(inputs, *inputData) + } + } + if !foundRelevantTx { + // The contract said there was a relevant transaction in this block that we failed to find. + // There was either a reorg or the extraction logic is broken. + // Either way, abort this attempt to validate the preimage. + return nil, fmt.Errorf("%w %v", ErrNoLeavesFound, blockNum) + } + } + return inputs, nil +} + +func (f *InputFetcher) extractRelevantLeavesFromTx(ctx context.Context, oracle Oracle, signer types.Signer, tx *types.Transaction, ident keccakTypes.LargePreimageIdent) (*keccakTypes.InputData, error) { + if tx.To() == nil || *tx.To() != oracle.Addr() { + f.log.Trace("Skip tx with incorrect to addr", "tx", tx.Hash(), "expected", oracle.Addr(), "actual", tx.To()) + return nil, nil + } + uuid, inputData, err := oracle.DecodeInputData(tx.Data()) + if errors.Is(err, contracts.ErrInvalidAddLeavesCall) { + f.log.Trace("Skip tx with invalid call data", "tx", tx.Hash(), "err", err) + return nil, nil + } else if err != nil { + return nil, err + } + if uuid.Cmp(ident.UUID) != 0 { + f.log.Trace("Skip tx with incorrect UUID", "tx", tx.Hash(), "expected", ident.UUID, "actual", uuid) + return nil, nil + } + sender, err := signer.Sender(tx) + if err != nil { + f.log.Trace("Skipping transaction with invalid sender", "tx", tx.Hash(), "err", err) + return nil, nil + } + if sender != ident.Claimant { + f.log.Trace("Skipping transaction with incorrect sender", "tx", tx.Hash(), "expected", ident.Claimant, "actual", sender) + return nil, nil + } + rcpt, err := f.source.TransactionReceipt(ctx, tx.Hash()) + if err != nil { + return nil, fmt.Errorf("failed to retrieve receipt for tx %v: %w", tx.Hash(), err) + } + if rcpt.Status != types.ReceiptStatusSuccessful { + f.log.Trace("Skipping transaction with failed receipt status", "tx", tx.Hash(), "status", rcpt.Status) + return nil, nil + } + return &inputData, nil +} + +func NewPreimageFetcher(logger log.Logger, source L1Source) *InputFetcher { + return &InputFetcher{ + log: logger, + source: source, + } +} diff --git a/op-challenger/game/keccak/fetcher/fetcher_test.go b/op-challenger/game/keccak/fetcher/fetcher_test.go new file mode 100644 index 000000000000..c236712c8466 --- /dev/null +++ b/op-challenger/game/keccak/fetcher/fetcher_test.go @@ -0,0 +1,300 @@ +package fetcher + +import ( + "context" + "crypto/ecdsa" + "errors" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var ( + oracleAddr = common.Address{0x99, 0x98} + privKey, _ = crypto.GenerateKey() + ident = keccakTypes.LargePreimageIdent{ + Claimant: crypto.PubkeyToAddress(privKey.PublicKey), + UUID: big.NewInt(888), + } + chainID = big.NewInt(123) + blockHash = common.Hash{0xdd} + input1 = keccakTypes.InputData{ + Input: []byte{0xbb, 0x11}, + Commitments: []common.Hash{{0xcc, 0x11}}, + } + input2 = keccakTypes.InputData{ + Input: []byte{0xbb, 0x22}, + Commitments: []common.Hash{{0xcc, 0x22}}, + } + input3 = keccakTypes.InputData{ + Input: []byte{0xbb, 0x33}, + Commitments: []common.Hash{{0xcc, 0x33}}, + } + input4 = keccakTypes.InputData{ + Input: []byte{0xbb, 0x44}, + Commitments: []common.Hash{{0xcc, 0x44}}, + Finalize: true, + } +) + +func TestFetchLeaves_NoBlocks(t *testing.T) { + fetcher, oracle, _ := setupFetcherTest(t) + oracle.leafBlocks = []uint64{} + leaves, err := fetcher.FetchInputs(context.Background(), blockHash, oracle, ident) + require.NoError(t, err) + require.Empty(t, leaves) +} + +func TestFetchLeaves_SingleTx(t *testing.T) { + fetcher, oracle, l1Source := setupFetcherTest(t) + blockNum := uint64(7) + oracle.leafBlocks = []uint64{blockNum} + l1Source.txs[blockNum] = types.Transactions{oracle.txForInput(ValidTx, input1)} + inputs, err := fetcher.FetchInputs(context.Background(), blockHash, oracle, ident) + require.NoError(t, err) + require.Equal(t, []keccakTypes.InputData{input1}, inputs) +} + +func TestFetchLeaves_MultipleBlocksAndLeaves(t *testing.T) { + fetcher, oracle, l1Source := setupFetcherTest(t) + block1 := uint64(7) + block2 := uint64(15) + block3 := uint64(20) + oracle.leafBlocks = []uint64{block1, block2, block3} + l1Source.txs[block1] = types.Transactions{oracle.txForInput(ValidTx, input1)} + l1Source.txs[block2] = types.Transactions{oracle.txForInput(ValidTx, input2)} + l1Source.txs[block3] = types.Transactions{oracle.txForInput(ValidTx, input3), oracle.txForInput(ValidTx, input4)} + inputs, err := fetcher.FetchInputs(context.Background(), blockHash, oracle, ident) + require.NoError(t, err) + require.Equal(t, []keccakTypes.InputData{input1, input2, input3, input4}, inputs) +} + +func TestFetchLeaves_SkipTxToWrongContract(t *testing.T) { + fetcher, oracle, l1Source := setupFetcherTest(t) + blockNum := uint64(7) + oracle.leafBlocks = []uint64{blockNum} + // Valid tx but to a different contract + tx1 := oracle.txForInput(WithToAddr(common.Address{0x88, 0x99, 0x11}), input2) + // Valid tx but without a to addr + tx2 := oracle.txForInput(WithoutToAddr(), input2) + // Valid tx to the correct contract + tx3 := oracle.txForInput(ValidTx, input1) + l1Source.txs[blockNum] = types.Transactions{tx1, tx2, tx3} + inputs, err := fetcher.FetchInputs(context.Background(), blockHash, oracle, ident) + require.NoError(t, err) + require.Equal(t, []keccakTypes.InputData{input1}, inputs) +} + +func TestFetchLeaves_SkipTxWithDifferentUUID(t *testing.T) { + fetcher, oracle, l1Source := setupFetcherTest(t) + blockNum := uint64(7) + oracle.leafBlocks = []uint64{blockNum} + // Valid tx but with a different UUID + tx1 := oracle.txForInput(WithUUID(big.NewInt(874927294)), input2) + // Valid tx + tx2 := oracle.txForInput(ValidTx, input1) + l1Source.txs[blockNum] = types.Transactions{tx1, tx2} + inputs, err := fetcher.FetchInputs(context.Background(), blockHash, oracle, ident) + require.NoError(t, err) + require.Equal(t, []keccakTypes.InputData{input1}, inputs) +} + +func TestFetchLeaves_SkipTxWithInvalidCall(t *testing.T) { + fetcher, oracle, l1Source := setupFetcherTest(t) + blockNum := uint64(7) + oracle.leafBlocks = []uint64{blockNum} + // Call to preimage oracle but fails to decode + tx1 := oracle.txForInput(WithInvalidData(), input2) + // Valid tx + tx2 := oracle.txForInput(ValidTx, input1) + l1Source.txs[blockNum] = types.Transactions{tx1, tx2} + inputs, err := fetcher.FetchInputs(context.Background(), blockHash, oracle, ident) + require.NoError(t, err) + require.Equal(t, []keccakTypes.InputData{input1}, inputs) +} + +func TestFetchLeaves_SkipTxWithInvalidSender(t *testing.T) { + fetcher, oracle, l1Source := setupFetcherTest(t) + blockNum := uint64(7) + oracle.leafBlocks = []uint64{blockNum} + // Call to preimage oracle with different Chain ID + tx1 := oracle.txForInput(WithChainID(big.NewInt(992)), input3) + // Call to preimage oracle with wrong sender + wrongKey, _ := crypto.GenerateKey() + tx2 := oracle.txForInput(WithPrivKey(wrongKey), input4) + // Valid tx + tx3 := oracle.txForInput(ValidTx, input1) + l1Source.txs[blockNum] = types.Transactions{tx1, tx2, tx3} + inputs, err := fetcher.FetchInputs(context.Background(), blockHash, oracle, ident) + require.NoError(t, err) + require.Equal(t, []keccakTypes.InputData{input1}, inputs) +} + +func TestFetchLeaves_SkipTxWithReceiptStatusFail(t *testing.T) { + fetcher, oracle, l1Source := setupFetcherTest(t) + blockNum := uint64(7) + oracle.leafBlocks = []uint64{blockNum} + // Valid call to the preimage oracle but that reverted + tx1 := oracle.txForInput(ValidTx, input2) + l1Source.rcptStatus[tx1.Hash()] = types.ReceiptStatusFailed + // Valid tx + tx2 := oracle.txForInput(ValidTx, input1) + l1Source.txs[blockNum] = types.Transactions{tx1, tx2} + inputs, err := fetcher.FetchInputs(context.Background(), blockHash, oracle, ident) + require.NoError(t, err) + require.Equal(t, []keccakTypes.InputData{input1}, inputs) +} + +func TestFetchLeaves_ErrorsWhenNoValidLeavesInBlock(t *testing.T) { + fetcher, oracle, l1Source := setupFetcherTest(t) + blockNum := uint64(7) + oracle.leafBlocks = []uint64{blockNum} + // Irrelevant call + tx1 := oracle.txForInput(WithUUID(big.NewInt(492)), input2) + l1Source.rcptStatus[tx1.Hash()] = types.ReceiptStatusFailed + l1Source.txs[blockNum] = types.Transactions{tx1} + _, err := fetcher.FetchInputs(context.Background(), blockHash, oracle, ident) + require.ErrorIs(t, err, ErrNoLeavesFound) +} + +func setupFetcherTest(t *testing.T) (*InputFetcher, *stubOracle, *stubL1Source) { + oracle := &stubOracle{ + txInputs: make(map[byte]keccakTypes.InputData), + } + l1Source := &stubL1Source{ + txs: make(map[uint64]types.Transactions), + rcptStatus: make(map[common.Hash]uint64), + } + fetcher := NewPreimageFetcher(testlog.Logger(t, log.LevelTrace), l1Source) + return fetcher, oracle, l1Source +} + +type stubOracle struct { + nextTxId byte + leafBlocks []uint64 + txInputs map[byte]keccakTypes.InputData +} + +func (o *stubOracle) Addr() common.Address { + return oracleAddr +} + +func (o *stubOracle) GetInputDataBlocks(_ context.Context, _ rpcblock.Block, _ keccakTypes.LargePreimageIdent) ([]uint64, error) { + return o.leafBlocks, nil +} + +func (o *stubOracle) DecodeInputData(data []byte) (*big.Int, keccakTypes.InputData, error) { + if len(data) == 0 { + return nil, keccakTypes.InputData{}, contracts.ErrInvalidAddLeavesCall + } + input, ok := o.txInputs[data[0]] + if !ok { + return nil, keccakTypes.InputData{}, contracts.ErrInvalidAddLeavesCall + } + uuid := ident.UUID + // WithUUID appends custom UUIDs to the tx data + if len(data) > 1 { + uuid = new(big.Int).SetBytes(data[1:]) + } + return uuid, input, nil +} + +type TxModifier func(tx *types.DynamicFeeTx) *ecdsa.PrivateKey + +var ValidTx TxModifier = func(_ *types.DynamicFeeTx) *ecdsa.PrivateKey { + return privKey +} + +func WithToAddr(addr common.Address) TxModifier { + return func(tx *types.DynamicFeeTx) *ecdsa.PrivateKey { + tx.To = &addr + return privKey + } +} + +func WithoutToAddr() TxModifier { + return func(tx *types.DynamicFeeTx) *ecdsa.PrivateKey { + tx.To = nil + return privKey + } +} + +func WithUUID(uuid *big.Int) TxModifier { + return func(tx *types.DynamicFeeTx) *ecdsa.PrivateKey { + tx.Data = append(tx.Data, uuid.Bytes()...) + return privKey + } +} + +func WithInvalidData() TxModifier { + return func(tx *types.DynamicFeeTx) *ecdsa.PrivateKey { + tx.Data = []byte{} + return privKey + } +} + +func WithChainID(id *big.Int) TxModifier { + return func(tx *types.DynamicFeeTx) *ecdsa.PrivateKey { + tx.ChainID = id + return privKey + } +} + +func WithPrivKey(key *ecdsa.PrivateKey) TxModifier { + return func(tx *types.DynamicFeeTx) *ecdsa.PrivateKey { + return key + } +} + +func (o *stubOracle) txForInput(txMod TxModifier, input keccakTypes.InputData) *types.Transaction { + id := o.nextTxId + o.nextTxId++ + o.txInputs[id] = input + inner := &types.DynamicFeeTx{ + ChainID: chainID, + Nonce: 1, + To: &oracleAddr, + Value: big.NewInt(0), + GasTipCap: big.NewInt(1), + GasFeeCap: big.NewInt(2), + Gas: 3, + Data: []byte{id}, + } + key := txMod(inner) + tx := types.MustSignNewTx(key, types.LatestSignerForChainID(inner.ChainID), inner) + return tx +} + +type stubL1Source struct { + txs map[uint64]types.Transactions + rcptStatus map[common.Hash]uint64 +} + +func (s *stubL1Source) ChainID(_ context.Context) (*big.Int, error) { + return chainID, nil +} + +func (s *stubL1Source) BlockByNumber(_ context.Context, number *big.Int) (*types.Block, error) { + txs, ok := s.txs[number.Uint64()] + if !ok { + return nil, errors.New("not found") + } + return (&types.Block{}).WithBody(txs, nil), nil +} + +func (s *stubL1Source) TransactionReceipt(_ context.Context, txHash common.Hash) (*types.Receipt, error) { + rcptStatus, ok := s.rcptStatus[txHash] + if !ok { + rcptStatus = types.ReceiptStatusSuccessful + } + return &types.Receipt{Status: rcptStatus}, nil +} diff --git a/op-challenger/game/keccak/matrix/immediateeof_test.go b/op-challenger/game/keccak/matrix/immediateeof_test.go new file mode 100644 index 000000000000..27d0410d8cae --- /dev/null +++ b/op-challenger/game/keccak/matrix/immediateeof_test.go @@ -0,0 +1,66 @@ +package matrix + +import ( + "errors" + "fmt" + "io" + "math/rand" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/stretchr/testify/require" +) + +type sameCallEOFReader struct { + idx int + data []byte +} + +// newSameCallEOFReader returns an io.Reader that returns io.EOF in the same call that returns the final byte of data. +// This is valid as per io.Reader: +// An instance of this general case is that a Reader returning +// a non-zero number of bytes at the end of the input stream may +// return either err == EOF or err == nil. The next Read should +// return 0, EOF. +func newSameCallEOFReader(data []byte) *sameCallEOFReader { + return &sameCallEOFReader{data: data} +} + +func (i *sameCallEOFReader) Read(out []byte) (int, error) { + end := min(len(i.data), i.idx+len(out)) + n := copy(out, i.data[i.idx:end]) + i.idx += n + if i.idx >= len(i.data) { + return n, io.EOF + } + return n, nil +} + +func TestImmediateEofReader(t *testing.T) { + rng := rand.New(rand.NewSource(223)) + data := testutils.RandomData(rng, 100) + + batchSizes := []int{1, 2, 3, 5, 10, 33, 99, 100, 101} + for _, size := range batchSizes { + size := size + t.Run(fmt.Sprintf("Size-%v", size), func(t *testing.T) { + + reader := &sameCallEOFReader{data: data} + out := make([]byte, size) + actual := make([]byte, 0, len(data)) + for { + n, err := reader.Read(out) + actual = append(actual, out[:n]...) + if errors.Is(err, io.EOF) { + break + } else { + require.NoError(t, err) + } + } + require.Equal(t, data, actual) + n, err := reader.Read(out) + require.Zero(t, n) + require.ErrorIs(t, err, io.EOF) + }) + } +} diff --git a/op-challenger/game/keccak/matrix/keccak.go b/op-challenger/game/keccak/matrix/keccak.go new file mode 100644 index 000000000000..d1243cacf6d6 --- /dev/null +++ b/op-challenger/game/keccak/matrix/keccak.go @@ -0,0 +1,674 @@ +// Copyright (c) 2009 The Go Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This code is taken from the standard golang.org/x/crypto module + +package matrix + +import ( + "encoding/binary" + "math/bits" +) + +// NewLegacyKeccak256 creates a new Keccak-256 hash. +// +// Only use this function if you require compatibility with an existing cryptosystem +// that uses non-standard padding. All other users should use New256 instead. +func newLegacyKeccak256() *state { + return &state{rate: 136, outputLen: 32, dsbyte: 0x01} +} + +var ( + xorIn = xorInGeneric + copyOut = copyOutGeneric +) + +// xorInGeneric xors the bytes in buf into the state; it +// makes no non-portable assumptions about memory layout +// or alignment. +func xorInGeneric(d *state, buf []byte) { + n := len(buf) / 8 + + for i := 0; i < n; i++ { + a := binary.LittleEndian.Uint64(buf) + d.a[i] ^= a + buf = buf[8:] + } +} + +// copyOutGeneric copies uint64s to a byte buffer. +func copyOutGeneric(d *state, b []byte) { + for i := 0; len(b) >= 8; i++ { + binary.LittleEndian.PutUint64(b, d.a[i]) + b = b[8:] + } +} + +// spongeDirection indicates the direction bytes are flowing through the sponge. +type spongeDirection int + +const ( + // spongeAbsorbing indicates that the sponge is absorbing input. + spongeAbsorbing spongeDirection = iota + // spongeSqueezing indicates that the sponge is being squeezed. + spongeSqueezing +) + +const ( + // maxRate is the maximum size of the internal buffer. SHAKE-256 + // currently needs the largest buffer. + maxRate = 168 +) + +// A storageBuf is an aligned array of maxRate bytes. +type storageBuf [maxRate]byte + +func (b *storageBuf) asBytes() *[maxRate]byte { + return (*[maxRate]byte)(b) +} + +type state struct { + // Generic sponge components. + a [25]uint64 // main state of the hash + buf []byte // points into storage + rate int // the number of bytes of state to use + + // dsbyte contains the "domain separation" bits and the first bit of + // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the + // SHA-3 and SHAKE functions by appending bitstrings to the message. + // Using a little-endian bit-ordering convention, these are "01" for SHA-3 + // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the + // padding rule from section 5.1 is applied to pad the message to a multiple + // of the rate, which involves adding a "1" bit, zero or more "0" bits, and + // a final "1" bit. We merge the first "1" bit from the padding into dsbyte, + // giving 00000110b (0x06) and 00011111b (0x1f). + // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf + // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and + // Extendable-Output Functions (May 2014)" + dsbyte byte + + storage storageBuf + + // Specific to SHA-3 and SHAKE. + outputLen int // the default output size in bytes + state spongeDirection // whether the sponge is absorbing or squeezing +} + +// BlockSize returns the rate of sponge underlying this hash function. +func (d *state) BlockSize() int { return d.rate } + +// Size returns the output size of the hash function in bytes. +func (d *state) Size() int { return d.outputLen } + +// Reset clears the internal state by zeroing the sponge state and +// the byte buffer, and setting Sponge.state to absorbing. +func (d *state) Reset() { + // Zero the permutation's state. + for i := range d.a { + d.a[i] = 0 + } + d.state = spongeAbsorbing + d.buf = d.storage.asBytes()[:0] +} + +func (d *state) clone() *state { + ret := *d + if ret.state == spongeAbsorbing { + ret.buf = ret.storage.asBytes()[:len(ret.buf)] + } else { + ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate] + } + + return &ret +} + +// permute applies the KeccakF-1600 permutation. It handles +// any input-output buffering. +func (d *state) permute() { + switch d.state { + case spongeAbsorbing: + // If we're absorbing, we need to xor the input into the state + // before applying the permutation. + xorIn(d, d.buf) + d.buf = d.storage.asBytes()[:0] + keccakF1600(&d.a) + case spongeSqueezing: + // If we're squeezing, we need to apply the permutation before + // copying more output. + keccakF1600(&d.a) + d.buf = d.storage.asBytes()[:d.rate] + copyOut(d, d.buf) + } +} + +// pads appends the domain separation bits in dsbyte, applies +// the multi-bitrate 10..1 padding rule, and permutes the state. +func (d *state) padAndPermute(dsbyte byte) { + if d.buf == nil { + d.buf = d.storage.asBytes()[:0] + } + // Pad with this instance's domain-separator bits. We know that there's + // at least one byte of space in d.buf because, if it were full, + // permute would have been called to empty it. dsbyte also contains the + // first one bit for the padding. See the comment in the state struct. + d.buf = append(d.buf, dsbyte) + zerosStart := len(d.buf) + d.buf = d.storage.asBytes()[:d.rate] + for i := zerosStart; i < d.rate; i++ { + d.buf[i] = 0 + } + // This adds the final one bit for the padding. Because of the way that + // bits are numbered from the LSB upwards, the final bit is the MSB of + // the last byte. + d.buf[d.rate-1] ^= 0x80 + // Apply the permutation + d.permute() + d.state = spongeSqueezing + d.buf = d.storage.asBytes()[:d.rate] + copyOut(d, d.buf) +} + +// Write absorbs more data into the hash's state. It panics if any +// output has already been read. +func (d *state) Write(p []byte) (written int, err error) { + if d.state != spongeAbsorbing { + panic("sha3: Write after Read") + } + if d.buf == nil { + d.buf = d.storage.asBytes()[:0] + } + written = len(p) + + for len(p) > 0 { + if len(d.buf) == 0 && len(p) >= d.rate { + // The fast path; absorb a full "rate" bytes of input and apply the permutation. + xorIn(d, p[:d.rate]) + p = p[d.rate:] + keccakF1600(&d.a) + } else { + // The slow path; buffer the input until we can fill the sponge, and then xor it in. + todo := d.rate - len(d.buf) + if todo > len(p) { + todo = len(p) + } + d.buf = append(d.buf, p[:todo]...) + p = p[todo:] + + // If the sponge is full, apply the permutation. + if len(d.buf) == d.rate { + d.permute() + } + } + } + + return +} + +// Read squeezes an arbitrary number of bytes from the sponge. +func (d *state) Read(out []byte) (n int, err error) { + // If we're still absorbing, pad and apply the permutation. + if d.state == spongeAbsorbing { + d.padAndPermute(d.dsbyte) + } + + n = len(out) + + // Now, do the squeezing. + for len(out) > 0 { + n := copy(out, d.buf) + d.buf = d.buf[n:] + out = out[n:] + + // Apply the permutation if we've squeezed the sponge dry. + if len(d.buf) == 0 { + d.permute() + } + } + + return +} + +// Sum applies padding to the hash state and then squeezes out the desired +// number of output bytes. It panics if any output has already been read. +func (d *state) Sum(in []byte) []byte { + if d.state != spongeAbsorbing { + panic("sha3: Sum after Read") + } + + // Make a copy of the original hash so that caller can keep writing + // and summing. + dup := d.clone() + hash := make([]byte, dup.outputLen, 64) // explicit cap to allow stack allocation + _, _ = dup.Read(hash) + return append(in, hash...) +} + +// rc stores the round constants for use in the ι step. +var rc = [24]uint64{ + 0x0000000000000001, + 0x0000000000008082, + 0x800000000000808A, + 0x8000000080008000, + 0x000000000000808B, + 0x0000000080000001, + 0x8000000080008081, + 0x8000000000008009, + 0x000000000000008A, + 0x0000000000000088, + 0x0000000080008009, + 0x000000008000000A, + 0x000000008000808B, + 0x800000000000008B, + 0x8000000000008089, + 0x8000000000008003, + 0x8000000000008002, + 0x8000000000000080, + 0x000000000000800A, + 0x800000008000000A, + 0x8000000080008081, + 0x8000000000008080, + 0x0000000080000001, + 0x8000000080008008, +} + +// keccakF1600 applies the Keccak permutation to a 1600b-wide +// state represented as a slice of 25 uint64s. +func keccakF1600(a *[25]uint64) { + // Implementation translated from Keccak-inplace.c + // in the keccak reference code. + var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64 + + for i := 0; i < 24; i += 4 { + // Combines the 5 steps in each round into 2 steps. + // Unrolls 4 rounds per loop and spreads some steps across rounds. + + // Round 1 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[6] ^ d1 + bc1 = bits.RotateLeft64(t, 44) + t = a[12] ^ d2 + bc2 = bits.RotateLeft64(t, 43) + t = a[18] ^ d3 + bc3 = bits.RotateLeft64(t, 21) + t = a[24] ^ d4 + bc4 = bits.RotateLeft64(t, 14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i] + a[6] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc2 = bits.RotateLeft64(t, 3) + t = a[16] ^ d1 + bc3 = bits.RotateLeft64(t, 45) + t = a[22] ^ d2 + bc4 = bits.RotateLeft64(t, 61) + t = a[3] ^ d3 + bc0 = bits.RotateLeft64(t, 28) + t = a[9] ^ d4 + bc1 = bits.RotateLeft64(t, 20) + a[10] = bc0 ^ (bc2 &^ bc1) + a[16] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc4 = bits.RotateLeft64(t, 18) + t = a[1] ^ d1 + bc0 = bits.RotateLeft64(t, 1) + t = a[7] ^ d2 + bc1 = bits.RotateLeft64(t, 6) + t = a[13] ^ d3 + bc2 = bits.RotateLeft64(t, 25) + t = a[19] ^ d4 + bc3 = bits.RotateLeft64(t, 8) + a[20] = bc0 ^ (bc2 &^ bc1) + a[1] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc1 = bits.RotateLeft64(t, 36) + t = a[11] ^ d1 + bc2 = bits.RotateLeft64(t, 10) + t = a[17] ^ d2 + bc3 = bits.RotateLeft64(t, 15) + t = a[23] ^ d3 + bc4 = bits.RotateLeft64(t, 56) + t = a[4] ^ d4 + bc0 = bits.RotateLeft64(t, 27) + a[5] = bc0 ^ (bc2 &^ bc1) + a[11] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc3 = bits.RotateLeft64(t, 41) + t = a[21] ^ d1 + bc4 = bits.RotateLeft64(t, 2) + t = a[2] ^ d2 + bc0 = bits.RotateLeft64(t, 62) + t = a[8] ^ d3 + bc1 = bits.RotateLeft64(t, 55) + t = a[14] ^ d4 + bc2 = bits.RotateLeft64(t, 39) + a[15] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + // Round 2 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[16] ^ d1 + bc1 = bits.RotateLeft64(t, 44) + t = a[7] ^ d2 + bc2 = bits.RotateLeft64(t, 43) + t = a[23] ^ d3 + bc3 = bits.RotateLeft64(t, 21) + t = a[14] ^ d4 + bc4 = bits.RotateLeft64(t, 14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1] + a[16] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc2 = bits.RotateLeft64(t, 3) + t = a[11] ^ d1 + bc3 = bits.RotateLeft64(t, 45) + t = a[2] ^ d2 + bc4 = bits.RotateLeft64(t, 61) + t = a[18] ^ d3 + bc0 = bits.RotateLeft64(t, 28) + t = a[9] ^ d4 + bc1 = bits.RotateLeft64(t, 20) + a[20] = bc0 ^ (bc2 &^ bc1) + a[11] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc4 = bits.RotateLeft64(t, 18) + t = a[6] ^ d1 + bc0 = bits.RotateLeft64(t, 1) + t = a[22] ^ d2 + bc1 = bits.RotateLeft64(t, 6) + t = a[13] ^ d3 + bc2 = bits.RotateLeft64(t, 25) + t = a[4] ^ d4 + bc3 = bits.RotateLeft64(t, 8) + a[15] = bc0 ^ (bc2 &^ bc1) + a[6] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc1 = bits.RotateLeft64(t, 36) + t = a[1] ^ d1 + bc2 = bits.RotateLeft64(t, 10) + t = a[17] ^ d2 + bc3 = bits.RotateLeft64(t, 15) + t = a[8] ^ d3 + bc4 = bits.RotateLeft64(t, 56) + t = a[24] ^ d4 + bc0 = bits.RotateLeft64(t, 27) + a[10] = bc0 ^ (bc2 &^ bc1) + a[1] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc3 = bits.RotateLeft64(t, 41) + t = a[21] ^ d1 + bc4 = bits.RotateLeft64(t, 2) + t = a[12] ^ d2 + bc0 = bits.RotateLeft64(t, 62) + t = a[3] ^ d3 + bc1 = bits.RotateLeft64(t, 55) + t = a[19] ^ d4 + bc2 = bits.RotateLeft64(t, 39) + a[5] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + // Round 3 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[11] ^ d1 + bc1 = bits.RotateLeft64(t, 44) + t = a[22] ^ d2 + bc2 = bits.RotateLeft64(t, 43) + t = a[8] ^ d3 + bc3 = bits.RotateLeft64(t, 21) + t = a[19] ^ d4 + bc4 = bits.RotateLeft64(t, 14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2] + a[11] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc2 = bits.RotateLeft64(t, 3) + t = a[1] ^ d1 + bc3 = bits.RotateLeft64(t, 45) + t = a[12] ^ d2 + bc4 = bits.RotateLeft64(t, 61) + t = a[23] ^ d3 + bc0 = bits.RotateLeft64(t, 28) + t = a[9] ^ d4 + bc1 = bits.RotateLeft64(t, 20) + a[15] = bc0 ^ (bc2 &^ bc1) + a[1] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc4 = bits.RotateLeft64(t, 18) + t = a[16] ^ d1 + bc0 = bits.RotateLeft64(t, 1) + t = a[2] ^ d2 + bc1 = bits.RotateLeft64(t, 6) + t = a[13] ^ d3 + bc2 = bits.RotateLeft64(t, 25) + t = a[24] ^ d4 + bc3 = bits.RotateLeft64(t, 8) + a[5] = bc0 ^ (bc2 &^ bc1) + a[16] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc1 = bits.RotateLeft64(t, 36) + t = a[6] ^ d1 + bc2 = bits.RotateLeft64(t, 10) + t = a[17] ^ d2 + bc3 = bits.RotateLeft64(t, 15) + t = a[3] ^ d3 + bc4 = bits.RotateLeft64(t, 56) + t = a[14] ^ d4 + bc0 = bits.RotateLeft64(t, 27) + a[20] = bc0 ^ (bc2 &^ bc1) + a[6] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc3 = bits.RotateLeft64(t, 41) + t = a[21] ^ d1 + bc4 = bits.RotateLeft64(t, 2) + t = a[7] ^ d2 + bc0 = bits.RotateLeft64(t, 62) + t = a[18] ^ d3 + bc1 = bits.RotateLeft64(t, 55) + t = a[4] ^ d4 + bc2 = bits.RotateLeft64(t, 39) + a[10] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + // Round 4 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[1] ^ d1 + bc1 = bits.RotateLeft64(t, 44) + t = a[2] ^ d2 + bc2 = bits.RotateLeft64(t, 43) + t = a[3] ^ d3 + bc3 = bits.RotateLeft64(t, 21) + t = a[4] ^ d4 + bc4 = bits.RotateLeft64(t, 14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3] + a[1] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc2 = bits.RotateLeft64(t, 3) + t = a[6] ^ d1 + bc3 = bits.RotateLeft64(t, 45) + t = a[7] ^ d2 + bc4 = bits.RotateLeft64(t, 61) + t = a[8] ^ d3 + bc0 = bits.RotateLeft64(t, 28) + t = a[9] ^ d4 + bc1 = bits.RotateLeft64(t, 20) + a[5] = bc0 ^ (bc2 &^ bc1) + a[6] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc4 = bits.RotateLeft64(t, 18) + t = a[11] ^ d1 + bc0 = bits.RotateLeft64(t, 1) + t = a[12] ^ d2 + bc1 = bits.RotateLeft64(t, 6) + t = a[13] ^ d3 + bc2 = bits.RotateLeft64(t, 25) + t = a[14] ^ d4 + bc3 = bits.RotateLeft64(t, 8) + a[10] = bc0 ^ (bc2 &^ bc1) + a[11] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc1 = bits.RotateLeft64(t, 36) + t = a[16] ^ d1 + bc2 = bits.RotateLeft64(t, 10) + t = a[17] ^ d2 + bc3 = bits.RotateLeft64(t, 15) + t = a[18] ^ d3 + bc4 = bits.RotateLeft64(t, 56) + t = a[19] ^ d4 + bc0 = bits.RotateLeft64(t, 27) + a[15] = bc0 ^ (bc2 &^ bc1) + a[16] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc3 = bits.RotateLeft64(t, 41) + t = a[21] ^ d1 + bc4 = bits.RotateLeft64(t, 2) + t = a[22] ^ d2 + bc0 = bits.RotateLeft64(t, 62) + t = a[23] ^ d3 + bc1 = bits.RotateLeft64(t, 55) + t = a[24] ^ d4 + bc2 = bits.RotateLeft64(t, 39) + a[20] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + } +} diff --git a/op-challenger/game/keccak/matrix/matrix.go b/op-challenger/game/keccak/matrix/matrix.go new file mode 100644 index 000000000000..8227045dab7d --- /dev/null +++ b/op-challenger/game/keccak/matrix/matrix.go @@ -0,0 +1,241 @@ +package matrix + +import ( + "errors" + "fmt" + "io" + + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/merkle" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +// StateMatrix implements a stateful keccak sponge with the ability to create state commitments after each permutation +type StateMatrix struct { + s *state + //prestateMatrix is the state matrix snapshot after processing prestateLeaf but before processing poststateLeaf + prestateMatrix types.StateSnapshot + // prestateLeaf is the last prestate leaf. + // Used to retrieve the prestate to squeeze. + prestateLeaf types.Leaf + // poststateLeaf is the last poststate leaf. + // Used to retrieve the poststate to squeeze. + poststateLeaf types.Leaf + // merkleTree is the internal [merkle.BinaryMerkleTree] used to generate proofs + merkleTree *merkle.BinaryMerkleTree +} + +var ( + ErrInvalidMaxLen = errors.New("invalid max length to absorb") + ErrIncorrectCommitmentCount = errors.New("incorrect number of commitments for input length") + ErrValid = errors.New("state commitments are valid") +) + +// Challenge creates a [types.Challenge] to invalidate the provided preimage data if possible. +// [ErrValid] is returned if the provided inputs are valid and no challenge can be created. +func Challenge(data io.Reader, commitments []common.Hash) (types.Challenge, error) { + s := NewStateMatrix() + lastValidState := s.StateSnapshot() + var lastValidLeaf types.Leaf + var firstInvalidLeaf types.Leaf + for i := 0; ; i++ { + if i >= len(commitments) { + // There should have been more commitments. + // The contracts should prevent this so it can't be challenged, return an error + return types.Challenge{}, ErrIncorrectCommitmentCount + } + claimedCommitment := commitments[i] + _, err := s.absorbNextLeafInput(data, func() common.Hash { return claimedCommitment }) + isEOF := errors.Is(err, io.EOF) + if err != nil && !isEOF { + return types.Challenge{}, fmt.Errorf("failed to verify inputs: %w", err) + } + validCommitment := s.StateCommitment() + + if firstInvalidLeaf == (types.Leaf{}) { + if validCommitment != claimedCommitment { + lastValidLeaf = s.prestateLeaf + firstInvalidLeaf = s.poststateLeaf + } else { + lastValidState = s.StateSnapshot() + } + } + if isEOF { + if i < len(commitments)-1 { + // We got too many commitments + // The contracts should prevent this so it can't be challenged, return an error + return types.Challenge{}, ErrIncorrectCommitmentCount + } + break + } + } + if firstInvalidLeaf != (types.Leaf{}) { + var prestateProof merkle.Proof + if lastValidLeaf != (types.Leaf{}) { + prestateProof = s.merkleTree.ProofAtIndex(lastValidLeaf.Index) + } + poststateProof := s.merkleTree.ProofAtIndex(firstInvalidLeaf.Index) + return types.Challenge{ + StateMatrix: lastValidState, + Prestate: lastValidLeaf, + PrestateProof: prestateProof, + Poststate: firstInvalidLeaf, + PoststateProof: poststateProof, + }, nil + } + return types.Challenge{}, ErrValid +} + +// NewStateMatrix creates a new state matrix initialized with the initial, zero keccak block. +func NewStateMatrix() *StateMatrix { + return &StateMatrix{ + s: newLegacyKeccak256(), + merkleTree: merkle.NewBinaryMerkleTree(), + } +} + +// StateCommitment returns the state commitment for the current state matrix. +// Additional data may be absorbed after calling this method. +func (d *StateMatrix) StateCommitment() common.Hash { + return crypto.Keccak256Hash(d.StateSnapshot().Pack()) +} + +func (d *StateMatrix) StateSnapshot() types.StateSnapshot { + var snap types.StateSnapshot + copy(snap[:], d.s.a[:]) + return snap +} + +// newLeafWithPadding creates a new [Leaf] from inputs, padding the input to the [BlockSize]. +func (d *StateMatrix) newLeafWithPadding(input []byte, index uint64, commitment common.Hash, final bool) types.Leaf { + var paddedInput [types.BlockSize]byte + copy(paddedInput[:], input) + + if final { + pad(input, &paddedInput, d.s.dsbyte) + } + return types.Leaf{ + Input: paddedInput, + Index: index, + StateCommitment: commitment, + } +} + +func pad(input []byte, paddedInput *[types.BlockSize]byte, dsbyte byte) { + // Pad with this instance's domain-separator bits. We know that there's + // at least one more byte of space in paddedInput because, if it were full, + // this wouldn't be the last block and the padding would be in the next block. + // dsbyte also contains the first one bit for the padding. See the comment in the state struct. + paddedInput[len(input)] = dsbyte + // The remaining bytes are already zeros since paddedInput is a new array. + // This adds the final one bit for the padding. Because of the way that + // bits are numbered from the LSB upwards, the final bit is the MSB of + // the last byte. + paddedInput[types.BlockSize-1] ^= 0x80 +} + +func (d *StateMatrix) AbsorbUpTo(in io.Reader, maxLen int) (types.InputData, error) { + if maxLen < types.BlockSize || maxLen%types.BlockSize != 0 { + return types.InputData{}, ErrInvalidMaxLen + } + input := make([]byte, 0, maxLen) + commitments := make([]common.Hash, 0, maxLen/types.BlockSize) + for len(input)+types.BlockSize <= maxLen { + readData, err := d.absorbNextLeafInput(in, d.StateCommitment) + if errors.Is(err, io.EOF) { + input = append(input, readData...) + commitments = append(commitments, d.StateCommitment()) + return types.InputData{ + Input: input, + Commitments: commitments, + Finalize: true, + }, io.EOF + } else if err != nil { + return types.InputData{}, err + } + input = append(input, readData...) + commitments = append(commitments, d.StateCommitment()) + } + + return types.InputData{ + Input: input, + Commitments: commitments, + Finalize: false, + }, nil +} + +func (d *StateMatrix) PrestateMatrix() types.StateSnapshot { + return d.prestateMatrix +} + +// PrestateWithProof returns the prestate leaf with its merkle proof. +func (d *StateMatrix) PrestateWithProof() (types.Leaf, merkle.Proof) { + proof := d.merkleTree.ProofAtIndex(d.prestateLeaf.Index) + return d.prestateLeaf, proof +} + +// PoststateWithProof returns the poststate leaf with its merkle proof. +func (d *StateMatrix) PoststateWithProof() (types.Leaf, merkle.Proof) { + proof := d.merkleTree.ProofAtIndex(d.poststateLeaf.Index) + return d.poststateLeaf, proof +} + +// absorbNextLeafInput reads up to [BlockSize] bytes from in and absorbs them into the state matrix. +// If EOF is reached while reading, the state matrix is finalized and [io.EOF] is returned. +func (d *StateMatrix) absorbNextLeafInput(in io.Reader, stateCommitment func() common.Hash) ([]byte, error) { + data := make([]byte, types.BlockSize) + read := 0 + final := false + for read < types.BlockSize { + n, err := in.Read(data[read:]) + if errors.Is(err, io.EOF) { + read += n + final = true + break + } else if err != nil { + return nil, err + } + read += n + } + input := data[:read] + // Don't add the padding if we read a full block of input data, even if we reached EOF. + // Just absorb the full block and return so the caller can capture the state commitment after the block + // The next call will read no data from the Reader (already at EOF) and so add the final padding as an + // additional block. We can then return EOF to indicate there are no further blocks. + final = final && len(input) < types.BlockSize + d.prestateMatrix = d.StateSnapshot() + d.absorbLeafInput(input, final) + commitment := stateCommitment() + if d.poststateLeaf == (types.Leaf{}) { + d.prestateLeaf = types.Leaf{} + d.poststateLeaf = d.newLeafWithPadding(input, 0, commitment, final) + } else { + d.prestateLeaf = d.poststateLeaf + d.poststateLeaf = d.newLeafWithPadding(input, d.prestateLeaf.Index+1, commitment, final) + } + d.merkleTree.AddLeaf(d.poststateLeaf.Hash()) + if final { + return input, io.EOF + } + return input, nil +} + +// absorbLeafInput absorbs the specified data into the keccak sponge. +// If final is true, the data is padded to the required length, otherwise it must be exactly [types.BlockSize] bytes. +func (d *StateMatrix) absorbLeafInput(data []byte, final bool) { + if !final && len(data) != types.BlockSize { + panic("sha3: Incorrect leaf data length") + } + _, _ = d.s.Write(data[:]) + if final { + d.s.padAndPermute(d.s.dsbyte) + } +} + +// Hash finalizes the keccak permutation and returns the final hash. +// No further leaves can be absorbed after this is called +func (d *StateMatrix) Hash() (h common.Hash) { + _, _ = d.s.Read(h[:]) + return h +} diff --git a/op-challenger/game/keccak/matrix/matrix_test.go b/op-challenger/game/keccak/matrix/matrix_test.go new file mode 100644 index 000000000000..7be4631a0c99 --- /dev/null +++ b/op-challenger/game/keccak/matrix/matrix_test.go @@ -0,0 +1,436 @@ +package matrix + +import ( + "bytes" + _ "embed" + "encoding/json" + "errors" + "fmt" + "io" + "math/rand" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/merkle" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" +) + +//go:embed testdata/commitments.json +var refTests []byte + +func TestStateCommitment(t *testing.T) { + tests := []struct { + expectedPacked string + matrix []uint64 // Automatically padded with 0s to the required length + }{ + { + expectedPacked: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + }, + { + expectedPacked: "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000019", + matrix: []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, + }, + { + expectedPacked: "000000000000000000000000000000000000000000000000ffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + matrix: []uint64{18446744073709551615}, + }, + } + for _, test := range tests { + test := test + t.Run("", func(t *testing.T) { + state := NewStateMatrix() + copy(state.s.a[:], test.matrix) + expected := crypto.Keccak256Hash(common.FromHex(test.expectedPacked)) + actual := state.StateCommitment() + require.Equal(t, test.expectedPacked, common.Bytes2Hex(state.StateSnapshot().Pack())) + require.Equal(t, expected, actual) + }) + } +} + +type testData struct { + Input []byte `json:"input"` + Commitments []common.Hash `json:"commitments"` + PrestateLeaf []byte `json:"prestateLeaf"` + PoststateLeaf []byte `json:"poststateLeaf"` +} + +func TestAbsorbNextLeaf_ReferenceCommitments(t *testing.T) { + var tests []testData + require.NoError(t, json.Unmarshal(refTests, &tests)) + + for i, test := range tests { + test := test + t.Run(fmt.Sprintf("Ref-%v-%v", i, len(test.Input)), func(t *testing.T) { + prevLeaf := types.Leaf{} + s := NewStateMatrix() + commitments := []common.Hash{s.StateCommitment()} + in := bytes.NewReader(test.Input) + for { + readData, err := s.absorbNextLeafInput(in, s.StateCommitment) + isEOF := errors.Is(err, io.EOF) + if !isEOF { + // Shouldn't get any error except EOF + require.NoError(t, err) + } + prestate, _ := s.PrestateWithProof() + poststate, _ := s.PoststateWithProof() + require.Equal(t, prevLeaf, prestate, "Prestate should be the previous post state") + require.Equal(t, poststate.Input[:len(readData)], readData, "Post state should have returned input data") + prevLeaf = poststate + commitments = append(commitments, s.StateCommitment()) + if isEOF { + break + } + } + actual := s.Hash() + expected := crypto.Keccak256Hash(test.Input) + require.Equal(t, expected, actual) + require.Equal(t, test.Commitments, commitments) + + prestate, _ := s.PrestateWithProof() + var expectedPre [types.BlockSize]byte + copy(expectedPre[:], test.PrestateLeaf) + require.Equal(t, expectedPre, prestate.Input, "Final prestate") + poststate, _ := s.PoststateWithProof() + var expectedPost [types.BlockSize]byte + copy(expectedPost[:], test.PoststateLeaf) + require.Equal(t, expectedPost, poststate.Input, "Final poststate") + }) + } +} + +func TestAbsorbUpTo_ReferenceCommitments(t *testing.T) { + var tests []testData + require.NoError(t, json.Unmarshal(refTests, &tests)) + + for i, test := range tests { + test := test + t.Run(fmt.Sprintf("Ref-%v", i), func(t *testing.T) { + s := NewStateMatrix() + commitments := []common.Hash{s.StateCommitment()} + in := bytes.NewReader(test.Input) + for { + input, err := s.AbsorbUpTo(in, types.BlockSize*3) + if errors.Is(err, io.EOF) { + commitments = append(commitments, input.Commitments...) + break + } + // Shouldn't get any error except EOF + require.NoError(t, err) + commitments = append(commitments, input.Commitments...) + } + actual := s.Hash() + expected := crypto.Keccak256Hash(test.Input) + require.Equal(t, expected, actual) + require.Equal(t, test.Commitments, commitments) + }) + } +} + +func TestAbsorbUpTo_ReferenceCommitments_SameCallEOF(t *testing.T) { + var tests []testData + require.NoError(t, json.Unmarshal(refTests, &tests)) + + for i, test := range tests { + test := test + t.Run(fmt.Sprintf("Ref-%v", i), func(t *testing.T) { + s := NewStateMatrix() + commitments := []common.Hash{s.StateCommitment()} + in := newSameCallEOFReader(test.Input) + for { + input, err := s.AbsorbUpTo(in, types.BlockSize*3) + if errors.Is(err, io.EOF) { + commitments = append(commitments, input.Commitments...) + break + } + // Shouldn't get any error except EOF + require.NoError(t, err) + commitments = append(commitments, input.Commitments...) + } + actual := s.Hash() + expected := crypto.Keccak256Hash(test.Input) + require.Equal(t, expected, actual) + require.Equal(t, test.Commitments, commitments) + }) + } +} + +func TestAbsorbUpTo_LimitsDataRead(t *testing.T) { + s := NewStateMatrix() + data := testutils.RandomData(rand.New(rand.NewSource(2424)), types.BlockSize*6+20) + in := bytes.NewReader(data) + // Should fully read the first four leaves worth + inputData, err := s.AbsorbUpTo(in, types.BlockSize*4) + require.NoError(t, err) + require.Equal(t, data[0:types.BlockSize*4], inputData.Input) + require.Len(t, inputData.Commitments, 4) + require.False(t, inputData.Finalize) + + // Should read the remaining data and return EOF + inputData, err = s.AbsorbUpTo(in, types.BlockSize*10) + require.ErrorIs(t, err, io.EOF) + require.Equal(t, data[types.BlockSize*4:], inputData.Input) + require.Len(t, inputData.Commitments, 3, "2 full leaves plus the final partial leaf") + require.True(t, inputData.Finalize) +} + +func TestAbsorbUpTo_InvalidLengths(t *testing.T) { + s := NewStateMatrix() + lengths := []int{-types.BlockSize, -1, 0, 1, types.BlockSize - 1, types.BlockSize + 1, 2*types.BlockSize + 1} + for _, length := range lengths { + _, err := s.AbsorbUpTo(bytes.NewReader(nil), length) + require.ErrorIsf(t, err, ErrInvalidMaxLen, "Should get invalid length for length %v", length) + } +} + +func TestMatrix_absorbNextLeaf(t *testing.T) { + fullLeaf := make([]byte, types.BlockSize) + for i := 0; i < types.BlockSize; i++ { + fullLeaf[i] = byte(i) + } + tests := []struct { + name string + input []byte + leafInputs [][]byte + errs []error + }{ + { + name: "empty", + input: []byte{}, + leafInputs: [][]byte{{}}, + errs: []error{io.EOF}, + }, + { + name: "single", + input: fullLeaf, + leafInputs: [][]byte{fullLeaf}, + errs: []error{io.EOF}, + }, + { + name: "single-overflow", + input: append(fullLeaf, byte(9)), + leafInputs: [][]byte{fullLeaf, {byte(9)}}, + errs: []error{nil, io.EOF}, + }, + { + name: "double", + input: append(fullLeaf, fullLeaf...), + leafInputs: [][]byte{fullLeaf, fullLeaf}, + errs: []error{nil, io.EOF}, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + state := NewStateMatrix() + in := bytes.NewReader(test.input) + for i, leaf := range test.leafInputs { + buf, err := state.absorbNextLeafInput(in, state.StateCommitment) + if errors.Is(err, io.EOF) { + require.Equal(t, test.errs[i], err) + break + } + require.NoError(t, err) + require.Equal(t, leaf, buf) + } + }) + } +} + +func TestVerifyPreimage_ReferenceCommitments(t *testing.T) { + var tests []testData + require.NoError(t, json.Unmarshal(refTests, &tests)) + + for i, test := range tests { + test := test + t.Run(fmt.Sprintf("Ref-%v", i), func(t *testing.T) { + // Exclude the empty state commitment + challenge, err := Challenge(bytes.NewReader(test.Input), test.Commitments[1:]) + require.ErrorIs(t, err, ErrValid) + require.Equal(t, types.Challenge{}, challenge) + }) + } +} + +func TestVerifyPreimage_ReferenceCommitments_SameCallEOF(t *testing.T) { + var tests []testData + require.NoError(t, json.Unmarshal(refTests, &tests)) + + for i, test := range tests { + test := test + t.Run(fmt.Sprintf("Ref-%v", i), func(t *testing.T) { + // Exclude the empty state commitment + challenge, err := Challenge(newSameCallEOFReader(test.Input), test.Commitments[1:]) + require.ErrorIs(t, err, ErrValid) + require.Equal(t, types.Challenge{}, challenge) + }) + } +} + +func TestVerifyPreimage(t *testing.T) { + preimage := testutils.RandomData(rand.New(rand.NewSource(2323)), 1024) + validCommitments := func() []common.Hash { + valid, err := NewStateMatrix().AbsorbUpTo(bytes.NewReader(preimage), 1000*types.BlockSize) + require.ErrorIs(t, err, io.EOF, "Should read all preimage data") + return valid.Commitments + } + leafData := func(idx int) (out [types.BlockSize]byte) { + end := min((idx+1)*types.BlockSize, len(preimage)) + input := preimage[idx*types.BlockSize : end] + copy(out[:], input) + if len(input) < types.BlockSize { + pad(input, &out, newLegacyKeccak256().dsbyte) + } + return + } + // merkleTree creates the final merkle tree after including all leaves. + merkleTree := func(commitments []common.Hash) *merkle.BinaryMerkleTree { + m := merkle.NewBinaryMerkleTree() + for i, commitment := range commitments { + leaf := types.Leaf{ + Input: leafData(i), + Index: uint64(i), + StateCommitment: commitment, + } + m.AddLeaf(leaf.Hash()) + } + return m + } + + challengeLeaf := func(commitments []common.Hash, invalidIdx int) types.Challenge { + invalidLeafStart := invalidIdx * types.BlockSize + s := NewStateMatrix() + _, err := s.AbsorbUpTo(bytes.NewReader(preimage), invalidLeafStart) + require.NoError(t, err) + + fullMerkle := merkleTree(commitments) + prestateLeaf := leafData(invalidIdx - 1) + poststateLeaf := leafData(invalidIdx) + return types.Challenge{ + StateMatrix: s.StateSnapshot(), + Prestate: types.Leaf{ + Input: prestateLeaf, + Index: uint64(invalidIdx - 1), + StateCommitment: commitments[invalidIdx-1], + }, + PrestateProof: fullMerkle.ProofAtIndex(uint64(invalidIdx - 1)), + + Poststate: types.Leaf{ + Input: poststateLeaf, + Index: uint64(invalidIdx), + StateCommitment: commitments[invalidIdx], + }, + PoststateProof: fullMerkle.ProofAtIndex(uint64(invalidIdx)), + } + } + + type testInputs struct { + name string + commitments func() []common.Hash + expected types.Challenge + expectedErr error + } + + poststateLeaf := leafData(0) + tests := []testInputs{ + { + name: "Valid", + commitments: validCommitments, + expectedErr: ErrValid, + }, + func() testInputs { + incorrectFirstCommitment := validCommitments() + incorrectFirstCommitment[0] = common.Hash{0xaa} + return testInputs{ + name: "IncorrectFirstLeaf", + commitments: func() []common.Hash { + return incorrectFirstCommitment + }, + expected: types.Challenge{ + StateMatrix: NewStateMatrix().StateSnapshot(), + Prestate: types.Leaf{}, + Poststate: types.Leaf{ + Input: poststateLeaf, + Index: 0, + StateCommitment: common.Hash{0xaa}, + }, + PoststateProof: merkleTree(incorrectFirstCommitment).ProofAtIndex(0), + }, + } + }(), + } + + for i := 1; i < len(preimage)/types.BlockSize; i++ { + commitments := validCommitments() + commitments[i] = common.Hash{0xaa} + tests = append(tests, testInputs{ + name: fmt.Sprintf("Incorrect-%v", i), + commitments: func() []common.Hash { + return commitments + }, + expected: challengeLeaf(commitments, i), + }) + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + challenge, err := Challenge(bytes.NewReader(preimage), test.commitments()) + require.ErrorIs(t, err, test.expectedErr) + require.Equal(t, test.expected.StateMatrix, challenge.StateMatrix, "Correct state matrix") + require.Equal(t, test.expected.Prestate, challenge.Prestate, "Correct prestate") + if test.expected.Prestate != (types.Leaf{}) { + require.Equal(t, test.expected.Prestate.StateCommitment, crypto.Keccak256Hash(challenge.StateMatrix.Pack()), "Prestate matches leaf commitment") + } + require.Equal(t, test.expected.PrestateProof, challenge.PrestateProof, "Correct prestate proof") + require.Equal(t, test.expected.Poststate, challenge.Poststate, "Correct poststate") + require.Equal(t, test.expected.PoststateProof, challenge.PoststateProof, "Correct poststate proof") + require.Equal(t, test.expected, challenge, "Challenge correct overall") + }) + } +} + +func TestVerifyPreimage_DataMultipleOfBlockSize(t *testing.T) { + preimage := testutils.RandomData(rand.New(rand.NewSource(2323)), 5*types.BlockSize) + valid, err := NewStateMatrix().AbsorbUpTo(bytes.NewReader(preimage), 1000*types.BlockSize) + require.ErrorIs(t, err, io.EOF, "Should read all preimage data") + + _, err = Challenge(bytes.NewReader(preimage), valid.Commitments) + require.ErrorIs(t, err, ErrValid) +} + +func TestVerifyPreimage_TooManyCommitments(t *testing.T) { + data := []byte{1} + valid, err := NewStateMatrix().AbsorbUpTo(bytes.NewReader(data[:]), 10*types.BlockSize) + require.ErrorIs(t, err, io.EOF) + commitments := append(valid.Commitments, common.Hash{0xaa}) + _, err = Challenge(bytes.NewReader(data), commitments) + require.ErrorIs(t, err, ErrIncorrectCommitmentCount) +} + +func TestVerifyPreimage_TooFewCommitments(t *testing.T) { + data := [types.BlockSize * 3]byte{} + valid, err := NewStateMatrix().AbsorbUpTo(bytes.NewReader(data[:]), 10*types.BlockSize) + require.ErrorIs(t, err, io.EOF) + commitments := valid.Commitments[:len(valid.Commitments)-1] + _, err = Challenge(bytes.NewReader(data[:]), commitments) + require.ErrorIs(t, err, ErrIncorrectCommitmentCount) +} + +func FuzzKeccak(f *testing.F) { + f.Fuzz(func(t *testing.T, number, time uint64, data []byte) { + s := NewStateMatrix() + for i := 0; i < len(data); i += types.BlockSize { + end := min(i+types.BlockSize, len(data)) + s.absorbLeafInput(data[i:end], end == len(data)) + } + actual := s.Hash() + expected := crypto.Keccak256Hash(data) + require.Equal(t, expected, actual) + }) +} diff --git a/op-challenger/game/keccak/matrix/testdata/commitments.json b/op-challenger/game/keccak/matrix/testdata/commitments.json new file mode 100644 index 000000000000..c94b29261495 --- /dev/null +++ b/op-challenger/game/keccak/matrix/testdata/commitments.json @@ -0,0 +1,1093 @@ +[ + { + "input": "kYbKyRm02RR58P+t8WPE/UNL4zmr4XIe3qfMfFwRZVWlpzgDSmAXGNhqCGJZivDoNDRM1zrLaPAk5Ol8dAyi3shQgLHaBur7TLczzwxS9b8rU7WKPhTMsK+zblk3ps19yKixxPMjzMA5L70JOy0ng7/ZoJJhMuHC7TD1SYL5LEA=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x87d8548924b20b95fe1ed923236c44d2f98b8dc7a3c8c378e4193cc2745b1e8d" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "kYbKyRm02RR58P+t8WPE/UNL4zmr4XIe3qfMfFwRZVWlpzgDSmAXGNhqCGJZivDoNDRM1zrLaPAk5Ol8dAyi3shQgLHaBur7TLczzwxS9b8rU7WKPhTMsK+zblk3ps19yKixxPMjzMA5L70JOy0ng7/ZoJJhMuHC7TD1SYL5LEABAAAAAAAAgA==" + }, + { + "input": null, + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xb87c3be3d5bf2230e08186014204ab2d4e5eb457ec9e95fd4a703f9f97b8c49a" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "d2w7VVWNxlrhpX8iaT9gU3dqU/LStT7JDOxkPmKDpdExTm23fLcfou2UP+1koHU2XOlRU3gyde/InQA2axIOqmaWn7oU+Zyt8yChgn0fbY6icCcf3ILIKneVRxQQYef6lX7gloDl65pA85pQYZxSfAOIfqrMsAkWoebxmJsoTLSsCHSGrdlE8Cy9hzyNjx2MwnjwTc/GIrX+cpbEfnRXHTQSYrwHjILe57MaJ5EuVA==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x74df6384655843a30a8064467ece134524f68d18ca2e2290e0cd6f1c159d901b", + "0xb0729c23d40d7d05656a9c0af18caf4234b2d51f7b11f8ad091fb6c6c5f41788" + ], + "prestateLeaf": "d2w7VVWNxlrhpX8iaT9gU3dqU/LStT7JDOxkPmKDpdExTm23fLcfou2UP+1koHU2XOlRU3gyde/InQA2axIOqmaWn7oU+Zyt8yChgn0fbY6icCcf3ILIKneVRxQQYef6lX7gloDl65pA85pQYZxSfAOIfqrMsAkWoebxmJsoTLSsCHSGrdlE8A==", + "poststateLeaf": "LL2HPI2PHYzCePBNz8Yitf5ylsR+dFcdNBJivAeMgt7nsxonkS5UAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "QbjuDum/N3hGQLgqXL+MCiPEUrt4bF+xejAngdRK3D8IOKnZfk6TaiGMdsG8vg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xafaa5d998cf20052dea34066e466691f3a59af8a6143b7ff5626f87cb76f820b" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "QbjuDum/N3hGQLgqXL+MCiPEUrt4bF+xejAngdRK3D8IOKnZfk6TaiGMdsG8vgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "PaMoGKkQH3/NFs0YYsAG2u80tRrxq+flLSff0yCFhe5akRB8t03nLlhPgofL80CDBxC0Yc5hGj7bxMVgg4mfjLQ8tKjfxYK99F+IO9cq5cqxHS/QMSQ97KgyNUVb89PB2JwdDuqbCe+RnioFR1MpKyroSJpfmFPt+icQ/OZs6bVKqCw2TnALoheU/9r8MMDWW9NdHzf72ZZJC8UPa86dhESNMnL5VYv27wZibh8FaNw5oAFmEg2C8NBn2RsIkn9yEBD7M1YVA/7QDJghK7iVYhy5x7Hhd+VFikbBmgbWJKG1TQuNc5T1+iYS90GOvOHBwFbJB4/C4b5gUAaJcc7Y4V3/nUPhVMGHj+PA5emMS3J/9Qt43RzJa0/fn0LtCH4mvx73Ll6a91iINQ==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xccd955f751642425fd9b3bf7785da8c9f6e9d55027d1048ade2b9f0a3071860b", + "0xf77a4c6e252daf3f67bbe40f3275aa854418b0e0afb389bfc4425899898b1953", + "0xf3402153d5503ec0a32cff2b3590764fb284d15f77a6688a6f5d0fc579c7f64a" + ], + "prestateLeaf": "F5T/2vwwwNZb010fN/vZlkkLxQ9rzp2ERI0ycvlVi/bvBmJuHwVo3DmgAWYSDYLw0GfZGwiSf3IQEPszVhUD/tAMmCEruJViHLnHseF35UWKRsGaBtYkobVNC41zlPX6JhL3QY684cHAVskHj8LhvmBQBolxztjhXf+dQ+FUwYeP48Dl6YxLcg==", + "poststateLeaf": "f/ULeN0cyWtP359C7Qh+Jr8e9y5emvdYiDUBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "vKG+6yYjKSdPcwd7e0iBfiwk7dek86+aVEoSgpkf9IdxiukoQFjZsx4XiOHcwv4=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xc59f075e03c34088cfe44693f1260a94c0ebb6075b07c00875d0c2c072a87708" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "vKG+6yYjKSdPcwd7e0iBfiwk7dek86+aVEoSgpkf9IdxiukoQFjZsx4XiOHcwv4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "8qf1VUYedwv+s6Swd3mfEOvga7Hq/DGOXlV/zZucPT1IdXnG119li9Q+ELxWLSMXD4T4TKoeQnyOXr0t7sNLguKzca1Ra5+iZKCWsDQD77wGJgjh+rVw93NupUjHOtRYyixRVBHe/NrsQIy248NZc5B7fc7XcND3wFDk6gsqiXWmoSdu7ak6n23IruOGlZ5K1ZhlXh5ax1Z3YDfdJQSFbeGcQg0RVg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x73aa7c55e21e7d1da31e759983a2d81d88ad9306b45e1448c8cc7fbbd8f48e57", + "0x640dd808bb3264f28233d889b062c26fe80cf4477946dc0162cfb3033aa92cee" + ], + "prestateLeaf": "8qf1VUYedwv+s6Swd3mfEOvga7Hq/DGOXlV/zZucPT1IdXnG119li9Q+ELxWLSMXD4T4TKoeQnyOXr0t7sNLguKzca1Ra5+iZKCWsDQD77wGJgjh+rVw93NupUjHOtRYyixRVBHe/NrsQIy248NZc5B7fc7XcND3wFDk6gsqiXWmoSdu7ak6nw==", + "poststateLeaf": "bciu44aVnkrVmGVeHlrHVndgN90lBIVt4ZxCDRFWAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "3MZjvdJnTVg343pKZjz1OVl1yY8e+Tg8tKM4lPZHys+s0w4R8f6n1Iz7k00DCF3GLQDk96PaNBlGoLZBYjp5EXqXwj/o2q0gYz9wZXxDP0Lkkqo24PRExtAtIPUmVMKOtjpsQ9hnZtAap9fI1CYcokU0ub+HwsB6aZcekWEJHCbfiQKt2eojkVRs/6TGWfyhSo1CB5jZh42btX9NcPY0+NvfcVk+pM34GGgrH//bMDx952t6MxwgN3CevaJMybeZAKzikCvAZU/xj9mPD1WY5tW+YKN1/YoRRba6mSDKkAcYv3PZXk/mfLISvXD1wlIJVjCwffN0d7nhXzha7tXpdkkx4r9/TdwaXMkWFuEBN1Xd0yPRWTELFos=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xf483f22d3ab0f7ed87d97b62150f67e41ea771c0c3cdb6187d041756d3e93aaf", + "0x86a10716ffd3208dc77e6ccc5b7a614c9e0543db2058dec6e3878605237a63d2", + "0x9ae0878d45796e55b8b866a1c91672b921aee33964af6351f8221c996058e03b" + ], + "prestateLeaf": "VGz/pMZZ/KFKjUIHmNmHjZu1f01w9jT4299xWT6kzfgYaCsf/9swPH3na3ozHCA3cJ69okzJt5kArOKQK8BlT/GP2Y8PVZjm1b5go3X9ihFFtrqZIMqQBxi/c9leT+Z8shK9cPXCUglWMLB983R3ueFfOFru1el2STHiv39N3BpcyRYW4QE3VQ==", + "poststateLeaf": "3dMj0VkxCxaLAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "3EMdZkAwjohNpPLE/zR6nAXNkEk4DP0eNuXjKgQ0hDtQ2mdnsbCCwJ3Lih8qsVTyGRNc/xfZHc/ChlntAvTunU92p0JJvP7TMnyAZUPmmqGWtvk1vne2KbDXV0sD/sfhMG5cW8vHt8XGq7S/2GsljPjUjZyHV2Gg0s0G/r4W/FPrMw/GNNKKP9GQXfSDnqoUYRdJEtnz8rWi1w==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x5ef96af187147cc0ab594b8989269a10417a1aaa8dc382cf82ca5febba03d2da", + "0xef1e1ebbd234ac51de0fc268f182b1b5b9d27f98d5052d59aed0fa8e0bcb6b5a" + ], + "prestateLeaf": "3EMdZkAwjohNpPLE/zR6nAXNkEk4DP0eNuXjKgQ0hDtQ2mdnsbCCwJ3Lih8qsVTyGRNc/xfZHc/ChlntAvTunU92p0JJvP7TMnyAZUPmmqGWtvk1vne2KbDXV0sD/sfhMG5cW8vHt8XGq7S/2GsljPjUjZyHV2Gg0s0G/r4W/FPrMw/GNNKKPw==", + "poststateLeaf": "0ZBd9IOeqhRhF0kS2fPytaLXAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "JU9To00l+wzr7e2q+IGxvyanpdY8nI/LPGy9YJye2BlWkUPvDyXBSWwKzNML9rgCtNwvfMp49Yv0dkEjuOsijZaOi1OVB+uTFrw2NHaoK6t94riJLLyGFo3ObYsTFxXVYqdRUv3y8dqOyrJ2bA9rXmnExDFvLSkqE7grxQ6rW3MuiMGaLsjObw7L+yOey2P5K8GSnjgnvSl1PSFdTvcW0XwNiUmxF9mj/CLl0VLj0+tcp7PTOL+rGda+ERID35cNSxAqiy37r1RD0Aku5e3A9KlRW6XY8HtitjgbUgkyncd/+i49XLMOy6Z7+VRHW5ySOMQzBM4aZF0494wo8+hnYkyOQF4uzQdqp1nE5fAmpwG6ZBS1Il2d1IulXjjdcY+wTCBzWQZoRnxxYbU=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xc2244d44050cd1bf8c48ef1fd151118e24d0f4d055c6f8e2d9380393ecf536db", + "0x4217f2d70fe289c61f167410b02f0e21cea079e677abc7211e3419acfbfbb68f", + "0xbd91622393a0ce9bff67d7746746e9510fc00f9333d76461c17cdfa3dbfeca1f" + ], + "prestateLeaf": "Dsv7I57LY/krwZKeOCe9KXU9IV1O9xbRfA2JSbEX2aP8IuXRUuPT61yns9M4v6sZ1r4REgPflw1LECqLLfuvVEPQCS7l7cD0qVFbpdjwe2K2OBtSCTKdx3/6Lj1csw7Lpnv5VEdbnJI4xDMEzhpkXTj3jCjz6GdiTI5AXi7NB2qnWcTl8CanAQ==", + "poststateLeaf": "umQUtSJdndSLpV443XGPsEwgc1kGaEZ8cWG1AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "U+4ryEt1iB943t/XSZVdzLlwakB+Y+hPoG9iSrjOiyfL08ir1RT5PgquCmGzHi6wz6h+F5NnmByCJym79jxR9kfWm2I1B03pT0YwqfX6Z3t2RRDbG68VVK9vffAb+8tyReLczU+rF+PjF4KPhBeKIjHJ/D1QapCnCpq5wwVMOGixw7qr+SNPamMjg/KbVCNI9oaxDlyoXJy1cG3WlsU2OXRpUX0Ny/58kR70fXyjLIEADP7VRgz2M5k74W4PWd5XzssOnajYJ32tgAMLdje3NGyupp5c10LZjO3F2tks7POoMmzdNPrlkgXnfmwPsj7e8+Dq14LHVPOVWIMw9dpx+T+empmJNCLXNdkQni0ONijwtKc5iARcIe4NB6l0q0YiEw3w3MjK8E5BKG1j5w5CIx1MIfuUc/4yp842Geiv08u/4yhBIPgEUtdGqdQc1J3hDZfWgs/434158ANQG8kbE9Fcr0/phrlh5+fIkW1tVKrtwrmNG/YCE35gVLKd6pJ+MBG1WIN30f1yiNfde9HU20fjcV8Zw90ir1GYr1PNchXGG/FuvDrLkd6m2IbDNzsQuijBCRxefsjcJsnhuZgs3WkSCaRr6q9ka0o1yUQKigfYLR/ern3rF4G+dOlV3zh6Vm832UPqRP5J/VNYjVqajjx4MALzQ7OkIDGr8T/Hb2cKxMFWc5xoEf7yZgAGC2N5jyQUSw==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xc0f0ab359c32b6aa50a73d3aeaec405c311434e1029ab5b4069cce69bc621047", + "0xab029840421422083410d3ea591cc1d6d7f987e11fd1fb41673e4886cc7f9ec0", + "0xec87dfbf5373bbf99dde1e23353bedfa596df7887141406cc75a7788c75b1725", + "0x26d05dcd547e9c12fd9372c7a72a756d43eab9b1b184f573e87200e516f5199b" + ], + "prestateLeaf": "8LSnOYgEXCHuDQepdKtGIhMN8NzIyvBOQShtY+cOQiMdTCH7lHP+MqfONhnor9PLv+MoQSD4BFLXRqnUHNSd4Q2X1oLP+N+NefADUBvJGxPRXK9P6Ya5YefnyJFtbVSq7cK5jRv2AhN+YFSyneqSfjARtViDd9H9cojX3XvR1NtH43FfGcPdIg==", + "poststateLeaf": "r1GYr1PNchXGG/FuvDrLkd6m2IbDNzsQuijBCRxefsjcJsnhuZgs3WkSCaRr6q9ka0o1yUQKigfYLR/ern3rF4G+dOlV3zh6Vm832UPqRP5J/VNYjVqajjx4MALzQ7OkIDGr8T/Hb2cKxMFWc5xoEf7yZgAGC2N5jyQUSwEAAAAAAAAAAAAAgA==" + }, + { + "input": "ivixMAmdy1yLuqm6Z95ZCzFzPgJJwLbWxMLLECdqYwqyjscxsa55NlLoGIA6wdMUNjEYHifxsmhXRhfvu9vPS3nXJ0oLzvnwLtHp8nZJHfGfcVttccT3c5ODPLaxYArShpMIbeBOu7Cp5BrYt3WnjoWkdpvlD0SJex8VP4mz/XJ0bTt2/xyJg8GSQbyxQn+GzCnpUKDPPK9L8s+Fh/1tCYdzbX+YzCeW9+8vXkoVTQ9QrrPBxgU=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x89271427bd0052876b950a60146c74fa471497eaa803e2c24c4a358c768019a0", + "0x41235a392b38e63d2cad93c5a5cd4f9cd4caecfbd9ef0459dc4a17c2893f37a4" + ], + "prestateLeaf": "ivixMAmdy1yLuqm6Z95ZCzFzPgJJwLbWxMLLECdqYwqyjscxsa55NlLoGIA6wdMUNjEYHifxsmhXRhfvu9vPS3nXJ0oLzvnwLtHp8nZJHfGfcVttccT3c5ODPLaxYArShpMIbeBOu7Cp5BrYt3WnjoWkdpvlD0SJex8VP4mz/XJ0bTt2/xyJgw==", + "poststateLeaf": "wZJBvLFCf4bMKelQoM88r0vyz4WH/W0Jh3Ntf5jMJ5b37y9eShVND1Cus8HGBQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "Ck5zoYOAXqv3Uh/+JT/v86YSU9pO47Tg0RttlXad8wZnXyOVT6XqyFT+LpDufiRtYLWctKgbSOYGm/kH3UNbLDRdCItm6aCom/0HJ++ZvhUu8dX1FG1S4P+Jr/kNuokvOgHFTlQhrp5sIzD9jOqPSemxWmXhjbRbU5LuSz53AHxg/OshWA1CokEDDfH+2DrEBVDnqXHXBXKL3McudqosDj/jU1NW50GVlX4ZGjyZLYF5jxVfIDz4vFzW6uThNoTyJ+6jMWl1m93FSylA8bFtq3sxz9yMYnKFESv7YvsQND5EpwnoGfWK9ff1OHLv3XSY7AQv5igZpOkA2rBOdJFT0KH+kj9SKxPH/SnZgIjlNVbCALMgt81ZTtBS1CioTPIx2eAKKiEjn8ESVA1O5oTP7fxF1xvtj/gM1M0dOhY+u4c7jnWmcIDCVyXhBqgTkrhPqJ8eKXdTF/p5cmjs34gjF8TFIL7+", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xbc47fa6d888b9725f9d5c4d7b586161e7fc0fac8049df9b36d39dac2f5a6c738", + "0xfa87ab1b88d828bca2748721f15f86f725edf0d3f578e172a013cb2e8d6fec00", + "0x13921647e516ba9af4a595fb8141525a79c78c1f00fb7837a07682871efe1289" + ], + "prestateLeaf": "QQMN8f7YOsQFUOepcdcFcovcxy52qiwOP+NTU1bnQZWVfhkaPJktgXmPFV8gPPi8XNbq5OE2hPIn7qMxaXWb3cVLKUDxsW2rezHP3IxicoURK/ti+xA0PkSnCegZ9Yr19/U4cu/ddJjsBC/mKBmk6QDasE50kVPQof6SP1IrE8f9KdmAiOU1Vg==", + "poststateLeaf": "wgCzILfNWU7QUtQoqEzyMdngCiohI5/BElQNTuaEz+38Rdcb7Y/4DNTNHToWPruHO451pnCAwlcl4QaoE5K4T6ifHil3Uxf6eXJo7N+IIxfExSC+/gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "6HjAPGpmaPGPLCx9xAj1Vhl8nKdgpXryqReIbBsNyxDJuqaJW5D0Te4+UWi2yYdbAy6fQPmq73XVG+N3sVHNt7vbKXNrVvSpoCS4m+p0PsFNztulo15r/gxcNeCaI9IKf+m8D0TSNFYYfOhF4k1aZS+74bWrcgYuOmeqv6XgdWR7mL9UjK6+AZryeUyEChjqydX8JGK8soYWOWNrTzV2u6GizHeOCFed8cZ4mXhdEjzlAcKjKxEO24f8qih37sI+6V6WokMW6+E/LZqQ/VxaUqMfTjQVoJ/RRsS79jBAoJ1yi5/oCu+3kHE3leNMMN7aJ+8nnDxuG+jW7ckYdNcjCFoSQLibTGxIbUPixXY4ZCDenuELGETWRy2wFuZllZBD+sRyLtcHPGREFO98GIgfNGBN3u+iCgY6jw2LRWUCkeLtzwWvx7WU4tTWDm3NYqhCQFuo1pH4ttX/ah/RnD+nt8tmdgwKcLeV+pOvNO/MAyBKNi9qbtmMexH8nXyC1immp0u3eVfhJ2DjWGAto43k904V7KJuUDnrlYkikK0sGX/w/qVUfPJFhjaFvF2bSDGAvywCQ53sO8ZgCTWUn66kkDgEpudtLQ==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x60fd3e6b5913fc082a47e438c988fefe3da4322870d961d27d330b6d3f7f02e0", + "0xaea0c1b37e1e2705800f5b90a14284a9bc7eca441368b493516961b3a98e1a13", + "0x341f062f82ad17beb00c8a01a18b17783cf2987fbf3174f768ca42a5a19069e4", + "0xc6f3092dbe89d9406fc98aeb99de16f69c9045dcda1f9f72f81537c0e26ab71a" + ], + "prestateLeaf": "3p7hCxhE1kctsBbmZZWQQ/rEci7XBzxkRBTvfBiIHzRgTd7vogoGOo8Ni0VlApHi7c8Fr8e1lOLU1g5tzWKoQkBbqNaR+LbV/2of0Zw/p7fLZnYMCnC3lfqTrzTvzAMgSjYvam7ZjHsR/J18gtYppqdLt3lX4Sdg41hgLaON5PdOFeyiblA56w==", + "poststateLeaf": "lYkikK0sGX/w/qVUfPJFhjaFvF2bSDGAvywCQ53sO8ZgCTWUn66kkDgEpudtLQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "+CYzcP/9LE+EdqOG+9a5RTQG00FP7wvzuwEsw/yuTYI+xxGehPkz9n5YKlJ3BrjkX3jQv2jKM98fMEvSkiJ2+u1sB66qmILE0m/4SDeSRXVphqrP758vExOEsL7NHEgBVd7IvslUFU7gSMZ0+ee1ee0CD8i51lBcpP7rQK3kheu+6RuNTQK+8SJ+bpWgzYqpXisZGIXDefKhANcQWDs+dg4xo/y9FyluuECVtzSGQxwDCLmZDfvKXLozcl+f8wMbRE2MXNMwVYefP6uy0/GgEXIDkwPH4o9dv65JBnlTyUDBEIdB/fbEJRneWTOxOl+SyRz8FLNCkygP953Efo0fcXpKjbIrzuROgxyI+3Amm0Hsj5Zl34RErO1p33m8NBnMK6jBHeXcWp/40tZTmF1j2TE8xyzt76cC9ancmkoipvVCUmyp3S1XWUQZWVrSCdY7QPLXcG81AsdoCwlOe7ZpL5h/b8AZ3wr6ccu3qjYtmfsRLkwA+oUTsNJ6Xr/cRUKhumCdDU0+CLuo6UuNTq4DNPVJNUF4XtFjMh/UsR4GfOts7SBtXjOQgIJf6YAl0S3Cl1bhR9g2hvZyuXxK8kTfwg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x49837749118bd52989e66683b0c390e648d6bd14617a48db4fb0ac3c23fa6002", + "0x38c6d5cbf76e73a3fb3f8c056e936dccf9e8b2fe6379cebd58a5bd3358e0da52", + "0xe0d2db8687a4e0f0e475fc73a6b4d01b4c2798588940c476313111c3e2eab19d", + "0xeec6ab48f1d2149b86dfa43a21ebce258f2dee0f29cc3b133cf94f8eda6f2cb7" + ], + "prestateLeaf": "7I+WZd+ERKztad95vDQZzCuowR3l3Fqf+NLWU5hdY9kxPMcs7e+nAvWp3JpKIqb1QlJsqd0tV1lEGVla0gnWO0Dy13BvNQLHaAsJTnu2aS+Yf2/AGd8K+nHLt6o2LZn7ES5MAPqFE7DSel6/3EVCobpgnQ1NPgi7qOlLjU6uAzT1STVBeF7RYw==", + "poststateLeaf": "Mh/UsR4GfOts7SBtXjOQgIJf6YAl0S3Cl1bhR9g2hvZyuXxK8kTfwgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "V+Je3MC72y9Nj/ndRQ22pHbmfIk3L04GyLRx1y8NdQ8MW/VDtk4DFoJytmVgYMhgk14XRGrdjnRV6qZjElRbxhYkKOCVPMlHfFSLRuJywuMrbZD/ED4enQkcwGBbc0y4xD7SGMxmAN/xe3s115EKb7CmMd1OJKgFXtWCxjqZw3+cTMckBaTamyAhF2wZOFqLCiwACHeaSNuxEfr4tnKt0/WORdepDMBFHQQ2PyyRV6rSpX/wC9n9hTipbADlW+UCoiM0ohC9s+4D89xUWElcl+e0EsomsKduFctgqrExO9O5qkY8buHJZWViNKvpoTaRBfeYCaiGh/rHOBzyC5wfp5gloXw7vOkWV1pB", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x1f98ad3e4862403d0ab27479c5949c3e68f715806316dad1139287ae00e9e936", + "0xe25797a6a442516c9fe6adff1104f7238df721e74f26494958ac5d0cfcbdad54" + ], + "prestateLeaf": "V+Je3MC72y9Nj/ndRQ22pHbmfIk3L04GyLRx1y8NdQ8MW/VDtk4DFoJytmVgYMhgk14XRGrdjnRV6qZjElRbxhYkKOCVPMlHfFSLRuJywuMrbZD/ED4enQkcwGBbc0y4xD7SGMxmAN/xe3s115EKb7CmMd1OJKgFXtWCxjqZw3+cTMckBaTamw==", + "poststateLeaf": "ICEXbBk4WosKLAAId5pI27ER+vi2cq3T9Y5F16kMwEUdBDY/LJFXqtKlf/AL2f2FOKlsAOVb5QKiIzSiEL2z7gPz3FRYSVyX57QSyiawp24Vy2CqsTE707mqRjxu4cllZWI0q+mhNpEF95gJqIaH+sc4HPILnB+nmCWhfDu86RZXWkEBAAAAgA==" + }, + { + "input": "RyWgwd+Qr5ZO+DBrEHeoHOYKkGSv27AC8AUv7u2tGD8nb4x63hVOAvXbiJNrHqz/hiKCN0PS04CHDVDuugALETTnNJbBzxsXxFQut7x1sQgTrfMI9ZYusMnUgKZU8qgNk0b1QYWEbTOvaCLpMQ9oeyjJbMqIv8X9eqZx8vwKreJvKEa7WWJIxCaLqhMme2Lyq7So2I9YGpAgo5QRbxHSAARLIdtUA66lE37l1Fx+JNlwcl4GD30X1sU9GUdZOtzSHyowWzjz0actn3rjVSmGaOuS3Ah2/gvjQYWC7i3M81anjhdV/2ZCY94AYpr9Lqs+kMxE+nAoBNmJfBoJTZBJrIPqigbSouhH0ijV/5TbuMwfAUQfxSI5ZXQMwdxGwuBImixeglEtxvaYqyM9OJz8n3RHlO8rbSIR8yxShm2SAMn3ry/GoRH5xlxUbLdWN/Q965PJUv0KDi8Vovdj+5ic1XCyLUvWV84ptZyiel+UZdb/CS9YHoPkbcp/GWQIvAUWpNg493eNfwbuZqI=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x9306fc1d963a177e83f4294d9eb3925accaed510895a1e3f574891cf55129601", + "0xe2c0e7a580553e21a6a6871769ab80e27077320bc12104b8292fe3e42f753b75", + "0x4927ece860e24003c45d18f0baec468dfd68e61eaef117b9568e2bada6743903" + ], + "prestateLeaf": "JouqEyZ7YvKrtKjYj1gakCCjlBFvEdIABEsh21QDrqUTfuXUXH4k2XByXgYPfRfWxT0ZR1k63NIfKjBbOPPRpy2feuNVKYZo65LcCHb+C+NBhYLuLczzVqeOF1X/ZkJj3gBimv0uqz6QzET6cCgE2Yl8GglNkEmsg+qKBtKi6EfSKNX/lNu4zA==", + "poststateLeaf": "HwFEH8UiOWV0DMHcRsLgSJosXoJRLcb2mKsjPTic/J90R5TvK20iEfMsUoZtkgDJ968vxqER+cZcVGy3Vjf0PeuTyVL9Cg4vFaL3Y/uYnNVwsi1L1lfOKbWconpflGXW/wkvWB6D5G3KfxlkCLwFFqTYOPd3jX8G7maiAQAAAAAAAAAAAAAAgA==" + }, + { + "input": "7uyV3gHKCTWno05X0NsqCo+ecSbBndWk2chOcOj9/OEdE2e8xZA9D2PwsHc0Pa/kD7Kz44HRg9tZ2x12S9+8tyrX1Xt3qSVa/rgq9tCp2pK47d/ErS2uMN+7z6Q5YjoCb8opZhOVJYMQ1ydyjfKHklPbkWwe5fxZ8kyX7v1om9RgetMEJC6N++NZA8EiTg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x6aa1207bbebcbdb562d89afcb3cc5eedd746af84a099ee5782d39c02a444c866", + "0xbebbf678447f96212658092d091eb3460ab4f40fd714c02f2526dc79e0853f74" + ], + "prestateLeaf": "7uyV3gHKCTWno05X0NsqCo+ecSbBndWk2chOcOj9/OEdE2e8xZA9D2PwsHc0Pa/kD7Kz44HRg9tZ2x12S9+8tyrX1Xt3qSVa/rgq9tCp2pK47d/ErS2uMN+7z6Q5YjoCb8opZhOVJYMQ1ydyjfKHklPbkWwe5fxZ8kyX7v1om9RgetMEJC6N+w==", + "poststateLeaf": "41kDwSJOAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "TOjxDmmIhy7Mlq4a4V11/CFNbv8NeLrJ7cCi9m2fT537JagWJiMdobTVLNuN71dEO8ER074q5m93RkHwt7oJ73+iTUWGiYgfU5yo6hAIK8kV+Z/lL2p7SGza+xJkbTnrR5lfeNyhynrWGL+TqR54y5ZustFTvDEVWCTk87RjXYUHzseDkYE3JP8AHxKQzZgc3GCTsDjmrtzd1SkKb0s9uF15CfGJqAx+wryGlfkeWrAhf72hp5YGH8Umo5onUBWPvWQyRzHUFKv6LX92kGsJ5t9l9iSuYK6rSmMeTYM3LNM2V2S+vGreS+kzLWa1yJlaiQqN0mEJwdvSzTxbBwt6C4y76+hGmY3Puq7fzN5esJEdsXQh1JBjxG3bGZ2JsJHUF9xaxLN5XVRnMNwykHCW/AV4GYNVlB5tJvwY6bKORgvcf5pZN3iw5QZUVlc8a7KEoyA7e1PxSQiulTp1Jx5tD8WJkSFr8Yh3Ce5Pm6H+48LY4AZV2cWIbsq1FJAPMMxcmejnGxN1sG27SLP/HS/7YOJfclRTPy+ZR7DGcwBwj/TKWpWW/OTlMVv2mPrJVUvTD7qQ53PXdJM1FYQRMolHHFEK4ggJO7n12eyDqKR+aHZYLED8Izt8hUrpzAOTstFX3iov0wEr5N38ldQ2stYA7d/X", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x91bc28ac308d1ac17d009f234d35738e9b1692439304b54459d3a2495eb3b616", + "0x07c48b7c309b8cff89cd1c96f7596ebd1218f588aac8238f5f81704780e4ad93", + "0x43673747aca7a3e7428f4ed0702b099e4cb6b3a07b9d876cfe26c93827c7c48a", + "0xf9cd4a3c8e8110e3d72dd2196cddfb4e7f7c0cb487743ab4b0d7c27e9dbb203a" + ], + "prestateLeaf": "HbF0IdSQY8Rt2xmdibCR1BfcWsSzeV1UZzDcMpBwlvwFeBmDVZQebSb8GOmyjkYL3H+aWTd4sOUGVFZXPGuyhKMgO3tT8UkIrpU6dScebQ/FiZEha/GIdwnuT5uh/uPC2OAGVdnFiG7KtRSQDzDMXJno5xsTdbBtu0iz/x0v+2DiX3JUUz8vmQ==", + "poststateLeaf": "R7DGcwBwj/TKWpWW/OTlMVv2mPrJVUvTD7qQ53PXdJM1FYQRMolHHFEK4ggJO7n12eyDqKR+aHZYLED8Izt8hUrpzAOTstFX3iov0wEr5N38ldQ2stYA7d/XAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "AvTCu82tHn4vqAeJvRF0D0ZzROQvXqApfQS8wMMPGYeMKMoxv1ylmcZVy8449joQXyI/MCvRBw9ifmRPvvQrz6hAEFrrc9vnVeOGZ3JO4kqqwtXCsBk0uWdX54fTJwKltF79gR2FUWv6jdub+vIPPc/2GNV24VwrYCLJKM3ngc/V6MjklLR2SUufmcU13Nz1GZrNegoEwXzq3SjSX7Jy+UBMaD3OIqwB6TP83BHVlgDGSmyROUcFtXs/P7xakgS4ehCQImklzuDO9DRdMOHM8QVG+7Ru5liTcdnLHGZmuw9w15xzukp3lcBz9r0YE4JpNp88jHSRWy9je1YLiQZqCzsezJTZayTV+PDg7yhzknV7I9ilh9F2Km715Uq8mfqLoSu3P8jhFV6TpfxdbTsf//GiOj2vn50p1OTpw4szVojg3zKFM8LBIsnBlZlhjehSik5/UgXkXidGxftAIgs8QpK1ZM9+Egq77myavndGABvf4Jdj4evZPxg/7lbfF5M5NMRta3z2EL7F", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x7ecf008045f77c20bef4585b6fd642c26fe09f2f56a5acb504cfd4bce2e3fadc", + "0x253fb668c2363e1f74df922439adbe18e4825be8bf1f900b13c63fdee66855c5", + "0x9280e4e10b784a59a620a6e7f6486dc9191529cb19ecb76a909cd99797f269c4" + ], + "prestateLeaf": "S5+ZxTXc3PUZms16CgTBfOrdKNJfsnL5QExoPc4irAHpM/zcEdWWAMZKbJE5RwW1ez8/vFqSBLh6EJAiaSXO4M70NF0w4czxBUb7tG7mWJNx2cscZma7D3DXnHO6SneVwHP2vRgTgmk2nzyMdJFbL2N7VguJBmoLOx7MlNlrJNX48ODvKHOSdQ==", + "poststateLeaf": "eyPYpYfRdipu9eVKvJn6i6Ertz/I4RVek6X8XW07H//xojo9r5+dKdTk6cOLM1aI4N8yhTPCwSLJwZWZYY3oUopOf1IF5F4nRsX7QCILPEKStWTPfhIKu+5smr53RgAb3+CXY+Hr2T8YP+5W3xeTOTTEbWt89hC+xQEAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "KxErXRtL1JhC7Tl36SnTA6yN1kPJ+FHWHd9Qw3EL1nx7/WjXd3adHalOH+IoiUE8avgcjU0OswihibvyaphqgjYW4aFleB50E4ezd6d6mh5uWbXJM1NXdmUH8BBwCmLoJokM8lv16OJSqavrVRUEcY8Ldl09pmg83KO4wRxjhVe20DUWBnTXztMNlx4HaAcKN7Y67KZQ3m9Oos+CdAL75Wytioo0WVYhef2zg2ZdreOePOACaK+6alFL81Iki/C8Uja2v+YjX8YUs0AsfOpWOZL/Fn8p7BizAwYj", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x8a396ea38a21ce7e46777864c464f655b0774045c084d8aa04d5f62ce1ceea4d", + "0xf72e61753fd7f471e01d8ad73e725b8251d981ff03161a9b21c195b59bb9e05d" + ], + "prestateLeaf": "KxErXRtL1JhC7Tl36SnTA6yN1kPJ+FHWHd9Qw3EL1nx7/WjXd3adHalOH+IoiUE8avgcjU0OswihibvyaphqgjYW4aFleB50E4ezd6d6mh5uWbXJM1NXdmUH8BBwCmLoJokM8lv16OJSqavrVRUEcY8Ldl09pmg83KO4wRxjhVe20DUWBnTXzg==", + "poststateLeaf": "0w2XHgdoBwo3tjrsplDeb06iz4J0AvvlbK2KijRZViF5/bODZl2t45484AJor7pqUUvzUiSL8LxSNra/5iNfxhSzQCx86lY5kv8WfynsGLMDBiMBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "XCg8YCiTI2f46kIaq7zPtH6/qXjsCjjTqJ9T8OIRWrxk7S44HcXD/V72OryGTkghwWJEaZGE3h8iSOeimpclxuVoHl2lgucVrja/U9cqgJryH3pMiikQnrIxRiWLdVfrkYK9F98iNxwd3cbZMYd6MfH620ISHBek84dz4+Ae+aeyLlUd/CKwHZ1CZYOymLaRvlkviy7vhqq9Fyrf1FYXg+bp/gLUxup9cNsX1Q1/OVbieyhOFd39rXJ6ACxWfGZCMPJ+Wuse7ngKebZ2he+G96hX2dUWGSOYxsiozqoP9kg=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x3840877367d901f1bf14f3d589aed7e83948595e0222868a08b59873cb9230df", + "0x4ea862d23c02f1a6cc17dbf5ecf1822fa357304128fb6d2edb82a640b0a3ee09" + ], + "prestateLeaf": "XCg8YCiTI2f46kIaq7zPtH6/qXjsCjjTqJ9T8OIRWrxk7S44HcXD/V72OryGTkghwWJEaZGE3h8iSOeimpclxuVoHl2lgucVrja/U9cqgJryH3pMiikQnrIxRiWLdVfrkYK9F98iNxwd3cbZMYd6MfH620ISHBek84dz4+Ae+aeyLlUd/CKwHQ==", + "poststateLeaf": "nUJlg7KYtpG+WS+LLu+Gqr0XKt/UVheD5un+AtTG6n1w2xfVDX85VuJ7KE4V3f2tcnoALFZ8ZkIw8n5a6x7ueAp5tnaF74b3qFfZ1RYZI5jGyKjOqg/2SAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "3tCzFeEQ/cLtfrIrf3xDuG3HIlg3bn9sOR4FFzYSjPqma9CORBkKrq1myqUT5/WFkFRB+6zj/17Kbl/T0M6BWTgQZktrDpup+xCiU2m7ZKqvYImjW1X638odReqVo6XdrC6NyFn9YE/ssHioUKX5FMs3X4+TLi9UmW3brrNfrkw+lum704sAPctDtMwh/LVPapDfhqZlG+f6yTrmp3D6oBLqwcrAMNjIJ5LRJHsI31XG9/Pcd99qCPyg/xzcObVq9XyDg5vX22dSDe204eesHUyfsc1z7Et6MQY99MW83Lp1CGKJc7EgDgj3", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x2b345b6138b0af72126dacf2bb933135ec22d9927e66905753ed4dd7673fbcc7", + "0x14b3d8fae959461ff1a0682c7e82d63477b4a1bdd83fd7425ae51bd1df4b3188" + ], + "prestateLeaf": "3tCzFeEQ/cLtfrIrf3xDuG3HIlg3bn9sOR4FFzYSjPqma9CORBkKrq1myqUT5/WFkFRB+6zj/17Kbl/T0M6BWTgQZktrDpup+xCiU2m7ZKqvYImjW1X638odReqVo6XdrC6NyFn9YE/ssHioUKX5FMs3X4+TLi9UmW3brrNfrkw+lum704sAPQ==", + "poststateLeaf": "y0O0zCH8tU9qkN+GpmUb5/rJOuancPqgEurBysAw2MgnktEkewjfVcb389x332oI/KD/HNw5tWr1fIODm9fbZ1IN7bTh56wdTJ+xzXPsS3oxBj30xbzcunUIYolzsSAOCPcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "bfAo9s0t5LyD6E/FL3YItSp7iHRxZsByDcTBKVGLTTYZUOEWd5PDCX0J5GgN82XcwfW8zko0e/ejkOrDk0fvVefhLAD8pcG17MbtQ4wnZ8yKUSAZjA5LMA1gz8MpSMsDWt77ZNb2HXGeHNL8BWu7WhuGzm8d2GpSNCm0b7IpY6mBi1m8LNByXyxkHauXXkNgK4qM/gMHWwsPsW7V344EtcM5YjhT6rfboO1zuAF2udqcZblSuHEQmq8psLJj0mj7t2EPY+p1yxmax8zkfG5qlJUNY+jOTiACzMGGFBOh373aC1MrrVd+Et0BX6IC+k46gZT/jIs2MBMeKl/0NGG0urvHvayTLJXYJEKzplvyDaR7PrUSdxprJIQHfrZe9LnOlZe4PIw1LHo2vrbJ+9TJPR3izoeeUPeIIQjSSG28NzJ5Iar+86ZdSTEI/LnXEaAYSvQ7X28ShxZuHThkWxi9q8pdEv9BWXc=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x70ca6cbbd65222ea5e90b0c595d1cf55b423e1503dd07edaffc5a4a8babf3004", + "0x9e04f3082de4ecf1669b7cb0b458a8cafe452a424b395808cc2262236b71b729", + "0x115b8dba0fc4524995038e8e06953799cefd0119c75b306020ec53f884480e8b" + ], + "prestateLeaf": "LGQdq5deQ2Arioz+AwdbCw+xbtXfjgS1wzliOFPqt9ug7XO4AXa52pxluVK4cRCarymwsmPSaPu3YQ9j6nXLGZrHzOR8bmqUlQ1j6M5OIALMwYYUE6HfvdoLUyutV34S3QFfogL6TjqBlP+MizYwEx4qX/Q0YbS6u8e9rJMsldgkQrOmW/INpA==", + "poststateLeaf": "ez61EncaaySEB362XvS5zpWXuDyMNSx6Nr62yfvUyT0d4s6HnlD3iCEI0khtvDcyeSGq/vOmXUkxCPy51xGgGEr0O19vEocWbh04ZFsYvavKXRL/QVl3AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "Fn/bjMz27Pmo0ojZ1PbO1pulKlSVEA3NkoaIXezePMDDWhuLfbwngufLxwoyPb3cDAg8JZWXaE0O+liog7xV0p99KYUVOf2bmXcc/Yx1P40ikNkJT2zhhUoqaPBgBAsfSvw0eGBNmTer5Io/sjCdAaY46UnAVG0m303QSc7seGgY52p3Q+p0fblbjieR0iDmtStbnmeRMoc1CybVEWrkUM8mhnoHGzP8fe5i5BIOhGdOEhFEfNr/E128wwTjRYP80nAPZO2vx3sSIrYBl1uAAxglTZd1qqY8ds3LRAT7ioZSImxJgoGwQhaZ2g8zGBFRQlXu", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x5bb3fd28f16cf712e71ef328668bddb7304a23900d57281146e3d11379f787a1", + "0xfa09386208b45515b49b97f859070db73d59b4d5a701ac3925c9ffc65c5648a5" + ], + "prestateLeaf": "Fn/bjMz27Pmo0ojZ1PbO1pulKlSVEA3NkoaIXezePMDDWhuLfbwngufLxwoyPb3cDAg8JZWXaE0O+liog7xV0p99KYUVOf2bmXcc/Yx1P40ikNkJT2zhhUoqaPBgBAsfSvw0eGBNmTer5Io/sjCdAaY46UnAVG0m303QSc7seGgY52p3Q+p0fQ==", + "poststateLeaf": "uVuOJ5HSIOa1K1ueZ5EyhzULJtURauRQzyaGegcbM/x97mLkEg6EZ04SEUR82v8TXbzDBONFg/zScA9k7a/HexIitgGXW4ADGCVNl3Wqpjx2zctEBPuKhlIibEmCgbBCFpnaDzMYEVFCVe4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "aKNFw0pM0XmPQULBOYhXDEpG7xyGpTPpLKWdfAqcx/TsA8M5fxeCyWV01nQK", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xd587c1123b4ff0fa464810067afb76c630d2f55e699e10c87c0a0ef9b8066fb7" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "aKNFw0pM0XmPQULBOYhXDEpG7xyGpTPpLKWdfAqcx/TsA8M5fxeCyWV01nQKAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "1AjkmC7TXNJh/LirlVsFxMYFLR0QNB4Wiwi16JAepiRK42RpxBrbhNPOIJFX16r+vK31OWgJwxlCQamOACegcfgDYj6dRhQolfOFs8rccy7bYLsvUA8wgg1LBs4iQ6GJgZHkpaOq83zxZSqiZ+wNyhBH7ZRayhkti1XAbO3zZxJaG/RHfP3JKs6m/VOA7A47/unOIwaZjIsJZPLJABJ+wAhAXNQLQlgL+Tt9JWPr4mWW3d+K5iMNG4R7VJC8Y9MPVWX1P1/h64bToqRj4ELOp8nxsbDmEEnPmXpm", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x7c5a831165523b98e237daa7ec4f137fd85b4dd3e667bc49064cc31965129850", + "0x61fd8ed7abeb89608f8e48309f153b8885b4b4e4bea4c3b7e2c318b977737092" + ], + "prestateLeaf": "1AjkmC7TXNJh/LirlVsFxMYFLR0QNB4Wiwi16JAepiRK42RpxBrbhNPOIJFX16r+vK31OWgJwxlCQamOACegcfgDYj6dRhQolfOFs8rccy7bYLsvUA8wgg1LBs4iQ6GJgZHkpaOq83zxZSqiZ+wNyhBH7ZRayhkti1XAbO3zZxJaG/RHfP3JKg==", + "poststateLeaf": "zqb9U4DsDjv+6c4jBpmMiwlk8skAEn7ACEBc1AtCWAv5O30lY+viZZbd34rmIw0bhHtUkLxj0w9VZfU/X+HrhtOipGPgQs6nyfGxsOYQSc+ZemYBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "7GzH5TVEhQ==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x1a1f489ba334d4068d05ea8347fd83a14a73082101f8d2daba09553485e73c60" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "7GzH5TVEhQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "x9xGIRFaMdQq0l4MEJbBDSzCSTZLsd/0UkOSiHtALhd75Gi/c7ObBdk=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x1811020a0424b78b1697b9cfaf67ea339be0988c5bfa859725bfbb0aec7ed76a" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "x9xGIRFaMdQq0l4MEJbBDSzCSTZLsd/0UkOSiHtALhd75Gi/c7ObBdkBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "O3mF1GL0vHkl1aZEKundwta4m+07cngnlLAtOOlhZA2n9NVQHvffMRc7kgg1zs9nUWNPUcj+O994cRWgMC1k", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xdf980f53d2c8527c8438791243c129bd2aadb23872502fa0e4447e1b0b2202c3" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "O3mF1GL0vHkl1aZEKundwta4m+07cngnlLAtOOlhZA2n9NVQHvffMRc7kgg1zs9nUWNPUcj+O994cRWgMC1kAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "h0RMltv7EyhwfqVLrCEDhVvTJ1tNmbM+C0InbnQY+Kk5eUWfMUMHvUqR/Qgmg9aLlmoFROkcUpfH4AcMm0eFlxnav5yoWlJJmkLKR0CWUAT1jhsxkLOVqpNPWKRvl1IZSpgPW2Czp9SlYP7Z7yfrIovxoNM3qjNWiiXQIqmxl9rKXcXNY/jo0jla8avWXD7lIF7HbE0IWxNTqSwGc111TQUMrzRyonNz2uwW+2YzC4hrwJzkUfAe98pc7qWDv5iJyOU6iPhymXr1Rgead3DRgE6gpdOrVwWqLpUFajhk8LVKH0muEVsQqkSL3/RkuxyYJ1SdbZG0FD70wiGSTBlY", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xfa1bafcf85ada822d18184fbc939be33cd6bea9203d763a6baba6daa13e925c0", + "0x175913e44136b3a8b1eeb4ecd8544a12d5d79b98885c2453c7823a958245953c" + ], + "prestateLeaf": "h0RMltv7EyhwfqVLrCEDhVvTJ1tNmbM+C0InbnQY+Kk5eUWfMUMHvUqR/Qgmg9aLlmoFROkcUpfH4AcMm0eFlxnav5yoWlJJmkLKR0CWUAT1jhsxkLOVqpNPWKRvl1IZSpgPW2Czp9SlYP7Z7yfrIovxoNM3qjNWiiXQIqmxl9rKXcXNY/jo0g==", + "poststateLeaf": "OVrxq9ZcPuUgXsdsTQhbE1OpLAZzXXVNBQyvNHKic3Pa7Bb7ZjMLiGvAnORR8B73ylzupYO/mInI5TqI+HKZevVGB5p3cNGATqCl06tXBaoulQVqOGTwtUofSa4RWxCqRIvf9GS7HJgnVJ1tkbQUPvTCIZJMGVgBAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "Gy9pBTkfOeD0fUr8zbC58w5zP6YqVJZGv52nGLRXSlBlWeJLI35GmP219qhBhPZipJID71G+Hmjea/IB/N4poRzxS+9Ky/7wQNWMOadc/d+VVADXPu71Cy9IV3w=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x85baa18bcb8dac402216a7c99c6bb508bfc96caabdfc83c7bccc0898a0389910" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "Gy9pBTkfOeD0fUr8zbC58w5zP6YqVJZGv52nGLRXSlBlWeJLI35GmP219qhBhPZipJID71G+Hmjea/IB/N4poRzxS+9Ky/7wQNWMOadc/d+VVADXPu71Cy9IV3wBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "JstIxj+GOiDJaEtSsZLg0MDSvXRLEFo3DhAkyInR0UA/i+s4R4YYvGUw0TCGsWsGepVPFYbTK+iivctM8ayPPEQGsFCVbKj78kG2QiOswmFy57L/8HhNatetUY9cwMDXwUY+z/7pEsh7GjfL9Sb60HKJ6a+imgyxiUbYdbx06mLfwRy8O4xn0ZoUZKacGvR6XXfnKkBx6EZnQ4X/CmRJGEMyDtm9f+386hlnYVyrZKgGh0C8NiLh++Op1jSYUJzCDkSet1ZFVXo1pAEzSCR3cueBzR1M6GM=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xe3d55fc5170899ae0ca36a90920c6ca338608f4a5dcd8d93e44e234f36917d68", + "0x159eaff490f4841410fe8eded5148778aa5ecbd0fb1bd908f992a85b36e9a613" + ], + "prestateLeaf": "JstIxj+GOiDJaEtSsZLg0MDSvXRLEFo3DhAkyInR0UA/i+s4R4YYvGUw0TCGsWsGepVPFYbTK+iivctM8ayPPEQGsFCVbKj78kG2QiOswmFy57L/8HhNatetUY9cwMDXwUY+z/7pEsh7GjfL9Sb60HKJ6a+imgyxiUbYdbx06mLfwRy8O4xn0Q==", + "poststateLeaf": "mhRkppwa9Hpdd+cqQHHoRmdDhf8KZEkYQzIO2b1/7fzqGWdhXKtkqAaHQLw2IuH746nWNJhQnMIORJ63VkVVejWkATNIJHdy54HNHUzoYwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "/tWP3uV4e9CVYkPJL8Z4kw==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xf38cdf1a78988c925677b1078d433a759ca4500334818977f2a480532921d78d" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "/tWP3uV4e9CVYkPJL8Z4kwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "bQHlLQQAa9z8oay/nSDVQJURbG/WJkpRBmzYuxfSn7gtd2BWzMxBYegXsaZ4HtpSOIYfRJQX6q2dASJI+naNH3BcUgbcn63G1XeyaZdEptndY0d2JqnWQjMEsurhZE+xJYhdv3PISfZxeSbxCiL1xE3vPfqbJ8zz//E1C+DSnHMfOc91tf09bBBgrqsfUyarZkYoT91m8mTZhEHfXE6Go0lEe4xuKugeArM3XIvcaen/q0i2Om3mh6dddYaOVtpy1tuevw==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xddcb88fe5a9d0df55e4c94569523b05b58eb515ca6114674f61e9721c8357f7e", + "0x4781cefa8e8bdb384f677c4a87ffd201f31980eea5ed4c321b5770bd6d5bb9b0" + ], + "prestateLeaf": "bQHlLQQAa9z8oay/nSDVQJURbG/WJkpRBmzYuxfSn7gtd2BWzMxBYegXsaZ4HtpSOIYfRJQX6q2dASJI+naNH3BcUgbcn63G1XeyaZdEptndY0d2JqnWQjMEsurhZE+xJYhdv3PISfZxeSbxCiL1xE3vPfqbJ8zz//E1C+DSnHMfOc91tf09bA==", + "poststateLeaf": "EGCuqx9TJqtmRihP3WbyZNmEQd9cToajSUR7jG4q6B4Cszdci9xp6f+rSLY6beaHp111ho5W2nLW256/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "evoB", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x38859b60e7bc24fc4fb617ce269ca5eb01359eaf45a40b0b50f9248cf0904a32" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "evoBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "tC4HUMrXZ3p1UM4PpGTSYOjLWuLb9BUCGwbTU317sa/az2/NlC7+96kJyL+NVS7+b010XdHKFtS5RcuANAgyqSEwSvV3pTA0wmUymaERp2yEVlwfWwLz7/COl10+rLOft//Q48PVuYxqswRCpbWC570Jfz6RPAX9CZtbIe7+9Jzxfp4hIPlqC4dBuiGoIAuRu7U3jssEYLjtjlWTn5Kip9VYyYyzhMshcYQwOsvm6nIGe2aD9DtqICEaPCAu3mUEIKZ3B1BlyiEkMk3RoTI0n00PxgzKnSZ/MgdyjKoAhV8OyN/8PJJvNB3Jhqiblb+pVhP/DYilY5eFJ3Oy3YpPZcknzX9GwirQP+jWr4N7spt0c8Wzssi0cHXOxLkcy5MuHMrvkcI5lih5HQyzo3Z9rSS5apDdidANjar368I4f9HwPquq9+WRA90qf9dhFp6KlZotH4LzrHyIbPSshpIhgwg1bnVq15PICPT29MSH2I/LrS+RWnNS3A==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xbc688ec6014c19982e8950edc434aab78dda6c284b8bf6685c1ba6199c65005f", + "0x837c62188c9acc191b9860e11d5607ebf25715bb4ed725b62eb0051bf7842420", + "0xd4cb178f83a9174a2f984aab73b0d599f288cb7c8df9ea7643194f63456c0a1c" + ], + "prestateLeaf": "h0G6IaggC5G7tTeOywRguO2OVZOfkqKn1VjJjLOEyyFxhDA6y+bqcgZ7ZoP0O2ogIRo8IC7eZQQgpncHUGXKISQyTdGhMjSfTQ/GDMqdJn8yB3KMqgCFXw7I3/w8km80HcmGqJuVv6lWE/8NiKVjl4Unc7Ldik9lySfNf0bCKtA/6Navg3uymw==", + "poststateLeaf": "dHPFs7LItHB1zsS5HMuTLhzK75HCOZYoeR0Ms6N2fa0kuWqQ3YnQDY2q9+vCOH/R8D6rqvflkQPdKn/XYRaeipWaLR+C86x8iGz0rIaSIYMINW51ateTyAj09vTEh9iPy60vkVpzUtwBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "EC+6W9qOHpBbkZ4bddtI5XLTkI+RqMvwGV30CdmjcFck/tJGV+6slQu/zD7YqL/hSHCZiqV+uzfN7qohYLSv6SRgnRDcnvcOT5Cjpg8asRH8ZRjBxahqXnVIlY9nOIYoyu+HqMUFm6TJNorPTtiIpUMW1waBYDOFhEBEtAAdS9U80jrf3WmhVBOCVURwQSveLHzZNdZxIHzyOFmZEkijELI/m3Ob/isfh5udJMk0yRTXq6jO+bATgzPegfRjaxSIA8l527VNR/MEuopKB6Cfza9TgWdTn04hk3koxI8BvExOxBI5a2SUm6ZKbI63QgbaTkif+NDIS5GZkIrGPaO4Dyk2gxFAzPWnoBVmAr3TO4BnXdelxSb80ROee74zVVOqQbEAE+caMjXOHCXQZY25grC9ufY4iqMNQRKAiUg=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xbe64214360727aaf82768e2c8c6eea5f5fbca0f0a6a8a5d4bbeb2aaa999cd9b5", + "0xdcc702820b8512ab42e85ecbed1c1ad91bda6f27dc3d5c62c01c5e2cf6b55f58", + "0x4bc0af92dea76212482183a6822c450d3dd2babf0451f14fe107b4a4bb962a50" + ], + "prestateLeaf": "E4JVRHBBK94sfNk11nEgfPI4WZkSSKMQsj+bc5v+Kx+Hm50kyTTJFNerqM75sBODM96B9GNrFIgDyXnbtU1H8wS6ikoHoJ/Nr1OBZ1OfTiGTeSjEjwG8TE7EEjlrZJSbpkpsjrdCBtpOSJ/40MhLkZmQisY9o7gPKTaDEUDM9aegFWYCvdM7gA==", + "poststateLeaf": "Z13XpcUm/NETnnu+M1VTqkGxABPnGjI1zhwl0GWNuYKwvbn2OIqjDUESgIlIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "ZeDJP67Sw5nYOdhdEIfRUVZL1fFstyMtPOsqF5UYQzOBhgH8dpwpjuvcN6/O1uhtGhFWwbljx/jcazFF2BWfBWf3eC0LWHRMPUiiD6OLrV6k+zrS2yWxqGkulIDOndPUaVeFKZWNSAEi19zmckdy5ItruOIDgo/fBDsH9Nvz/2Wk8j2HkuE+EE+nR9Y9M4fnH79BZk0iTqaDCjwO6bxcfX7yWOHJiWcK6Dl+9fP/Ol24E73andCsbzjcqRs3", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x1bfaf14d73c3d16d6277777e30253e43da7ae876a245749379bc2870f8f9fc35", + "0xfcfc506a0bca1c16ff13fcf14c7f4f1efd72cfd3d74aa17e61ddcbcfe56258a9" + ], + "prestateLeaf": "ZeDJP67Sw5nYOdhdEIfRUVZL1fFstyMtPOsqF5UYQzOBhgH8dpwpjuvcN6/O1uhtGhFWwbljx/jcazFF2BWfBWf3eC0LWHRMPUiiD6OLrV6k+zrS2yWxqGkulIDOndPUaVeFKZWNSAEi19zmckdy5ItruOIDgo/fBDsH9Nvz/2Wk8j2HkuE+EA==", + "poststateLeaf": "T6dH1j0zh+cfv0FmTSJOpoMKPA7pvFx9fvJY4cmJZwroOX718/86XbgTvdqd0KxvONypGzcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "+2Sm8j0qq7iqM0k3evWER+e28ZIHbQYaXV79/6cPAkBd1pcuCsA2rsFHJ4YE60RtUviaiDKZmn+yrEd23ZET2De0Ws+eYO/V+D/qldWvL8LI87BSuy62adDjq6bO6e5sEKsopovHiJDYq1LALR+EqOftQPvAT4/xC8yoFEC/rV/k81QmGJ4cpmG0zYOJpIeAZJ+D85AFCDv1M/yj0tVVdhYmcQCobbvUMy7EblzJZs5ZFnuJ78D/6LH50Ldy4H37AJH3pptsV80D0vvPQU5zdVfUA4swUYSQqRw9KGrtjGQgCCHHLrSQzFcMbpvtDsZFb56ix/JWGLKLVVGbA1btq80RH90EFG5IcXo7VyIqGnDQIPJW8hQk1vAluokZ9dciBhkVrsvg5mg4f4clZ7TN0G/uXBzkF9mzjRo4qvGHyIRYqL94kWMZHT8EkeQ27tcXf49hBkBA9ftF66MzMrOiiPaESYhCCyOFHI6iIy7587FfDDUGE0wkNbafxkvZtgJ7e1s20Dtu3d0aDUH1szIrWIvrfRpe7mbP6/+/9EXMwOK23lC+MCm/ykuK3Px8l5jHIEvj/0ZMlIn5OWjTAEY4G1c=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x65815809d69250b67f6ec42c96f375fde201e879ed394d318a2840592535ab68", + "0x6c2d4ce7ac4605c324e7a23628a3846b98d28af41db84680d8a598670dee9928", + "0x40bce7b1abce938dc4f8b76c8dca3dd2740096a8e1f511bca4c6ade3fe730220", + "0x8181226e378240f61866948ba6984e16009879643db599225dc170b05b584bec" + ], + "prestateLeaf": "0CDyVvIUJNbwJbqJGfXXIgYZFa7L4OZoOH+HJWe0zdBv7lwc5BfZs40aOKrxh8iEWKi/eJFjGR0/BJHkNu7XF3+PYQZAQPX7ReujMzKzooj2hEmIQgsjhRyOoiMu+fOxXww1BhNMJDW2n8ZL2bYCe3tbNtA7bt3dGg1B9bMyK1iL630aXu5mzw==", + "poststateLeaf": "6/+/9EXMwOK23lC+MCm/ykuK3Px8l5jHIEvj/0ZMlIn5OWjTAEY4G1cBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "L+x6UWa4Rgm5LHUcwpki2J9NtnTVoIGMbYopms9v/U0bicETMtSC15rxm0KvOSkekklULQLz5CrvoFl8ikQKV8tTnedD5UWWjtP40Qs0MCDUJVzbdNZKzQaPY40vO4bMt7A4wv+1tRtM+eH1RkEhvil/lpZd9diiMxFkjKt3EFZ9uxD3r0KGtFmdwPCXec12tcT42t2yucXEPVFJu3zhggp76H7FPeO8GjAHN/paoNq3wNsIIHfmPXyWaQrq7I+cMd5J5eDRKoct4ZjALXXGT1+5QLIGWctzxq3jMCz7vP6XUlRqUOntEtkliCK/7e0S1ELzlG0=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x8587343e3e6c2059a0335c44fc19a11bf63cb0790e3eb8e57173ef54bfd363b2", + "0xf38b109226bec4ec6685d4253e00c26c72aabb581b2376ecf07a475b559733c3" + ], + "prestateLeaf": "L+x6UWa4Rgm5LHUcwpki2J9NtnTVoIGMbYopms9v/U0bicETMtSC15rxm0KvOSkekklULQLz5CrvoFl8ikQKV8tTnedD5UWWjtP40Qs0MCDUJVzbdNZKzQaPY40vO4bMt7A4wv+1tRtM+eH1RkEhvil/lpZd9diiMxFkjKt3EFZ9uxD3r0KGtA==", + "poststateLeaf": "WZ3A8Jd5zXa1xPja3bK5xcQ9UUm7fOGCCnvofsU947waMAc3+lqg2rfA2wggd+Y9fJZpCursj5wx3knl4NEqhy3hmMAtdcZPX7lAsgZZy3PGreMwLPu8/pdSVGpQ6e0S2SWIIr/t7RLUQvOUbQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "SBpvZe6U4DpWPmgdDCMRTdWN3kLWrzjM6uKzA2/08baRIUhYguRJeP12DgO6O7XYMyzJMPffzpoqtbEBcdneMLjP+V/qt+sA36RDAyPusmMgx1tX6kA22+ddJyF4AxQEyh3gEjiMFBj+RAu27qiP22hdBlQDbkzwfMjkf7MqWJ/JqrBZXkkUIn9eCEKci7llGB44Vd0In7nssZ5XnMIq/wWV8NlUABr5IQEMstGWVN1ujOTl9ATinpFGqaKSmcXsEiOkDRuBJ3IAyPzbjPv2jDwfon63IIWa3gWTKkhXN03n/Wkx7YaoLiI1/NNU3i+4sJp8j0YWTJJUcuMYRkN6H+o/3bIS+TB//GO4vj66MPHWK+bpGZgv7dslUpowS7c9+DRIF2peKR6SV0zhMzdfjghPafu32/e/FsD5kbs6YY/5oRuFHqYgCobjJxyrEdMdVoE1/ug4OnC/TywE8krvpmCNrlNvH+YJ5I9/BIFOsg9PObjX5gxnJb4Ziu/+2B3phg5K7IGen+yTp61qwmZZxQMCWr4cc4/x1/c1uDcA15UIBO44ezvtfevdt4VQJCVMcbkSbZOIEBirKgY1a24uFFfy7IKLa2EDFWSyZxLwwBPbI4OM4UqltlNs2UN2soTAK15ODQ==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xb967f1c88e6409034042352fd9457edd5242011eb3bb311f79e8dcff2fb7ece4", + "0x422817ae854712d4b23180f01303cbe6eb53d13152059619433a38999cdc32aa", + "0xdc0935a99ce5cbe914c53d7a83d7cd735ad3b8d8bc4b833ad411cc815f3dec98", + "0xe46d6fcd0fd03eb50aa8d43420f3234a15387cbac907c9fbdde1a914a01e624c" + ], + "prestateLeaf": "1ivm6RmYL+3bJVKaMEu3Pfg0SBdqXikekldM4TM3X44IT2n7t9v3vxbA+ZG7OmGP+aEbhR6mIAqG4yccqxHTHVaBNf7oODpwv08sBPJK76Zgja5Tbx/mCeSPfwSBTrIPTzm41+YMZyW+GYrv/tgd6YYOSuyBnp/sk6etasJmWcUDAlq+HHOP8Q==", + "poststateLeaf": "1/c1uDcA15UIBO44ezvtfevdt4VQJCVMcbkSbZOIEBirKgY1a24uFFfy7IKLa2EDFWSyZxLwwBPbI4OM4UqltlNs2UN2soTAK15ODQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "2QJIWbRUBBG2N/NWq/0sBTi+1xV17LSEombqPr1d1B/e+PRV7KV7a4ztE6rAwCfaFXzb8O/muDh3Wkcs29q+0FSkdVrJEUWH77XEvrjg3j/thC4ARnE/Usy7b/+MDdJl+0p/7uuF+bUbYsF6NgJT4WHqDSiGBs5ZGiwPe8gBiDX2HEyLQDQDEAtcAVbLI8on23epD9/cCS91UygxKYrx1CZyfRYLYEKZ9LyH0ltmll0AqGRvQHuCHq/obtlnW+wfw9Pg+E/0dzMX/B0ESCIKBTgLFLCTupSvV4rwYxo7yHYcAvIKD67HECyncSqp6yVSbsxavmNzlWgo4sfjOhWmPGUsQSb5gmw+5gccDOWmTouTVQ7tOkP8A4n3UpUM04qDQtgbhSWSuxtJ9bb0wPtavJVb1fsZ7N/zb0URAG3M5Kye7ZtDYDwhgEjS4+MBb3DbBilViAuIM6D7fHXpdkSi67TOMmoCz0JWaaNPuWuHxVixPckB2uE8M6cXSNkUVyHsWi1+VVJqHq+bLTSSt76F+EBAICDCtGpmoAxcYWZIXU8xfDG4osgoAyROyR5z18m6Me4Llcw=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x5ad3e588bc4e1176b34088fef035587577c589936a98ab49905bc4bddfc99b67", + "0x90f85be195450bb1744d71057b67c90c1b75bb59d8cf4c3bdea1e757f28f7655", + "0xa284918096cb63f386d38a9493583da530c7937ed570c5f6bfc952c99ac76959", + "0x6597135748dd127cc5f095c2da3b7a28a78aa67b4e1fc218ec090defc1201fc0" + ], + "prestateLeaf": "k1UO7TpD/AOJ91KVDNOKg0LYG4UlkrsbSfW29MD7WryVW9X7Gezf829FEQBtzOSsnu2bQ2A8IYBI0uPjAW9w2wYpVYgLiDOg+3x16XZEouu0zjJqAs9CVmmjT7lrh8VYsT3JAdrhPDOnF0jZFFch7FotflVSah6vmy00kre+hfhAQCAgwrRqZg==", + "poststateLeaf": "oAxcYWZIXU8xfDG4osgoAyROyR5z18m6Me4LlcwBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "Nn2tikbbV4mNX+t5FfPtWH+fYknuGvo/rC2dAmatoA6PAOCuRlWM5ogABBwX+LAXjJeNX5AL/L6TRcz4UGNLsyo/1V4ZNQe5+NPQxeh/2470e5z3QsvL27C+ZM7kOHXOXjcNEA7+0ikU9bDXxOIRxjni7KmEW7SGA8XItKI8HV0QlDaW5b9irY/nNVJz5kXHlR1scXVTQrLAjT37kWlvuZd8Ue/5bknPdH3Ix5Gvk9zGpthAmwBpmVAXCF3BWiZtLCJE+aP9tSiWCn+ezb83mmHTktLrar+xWZYXSf82cIIzgkPnPiWL0xz59QV+PoXfh/74/ICRCSyzGiMkDD+eDGdsiu7Qox9KFkLSvxUQ5hKLZwcZIldTMGL0XOdGxRNjx6BQIvzCZ6ns2d3V+pBjm9QUiJiwCasxzExWOU/2sVMPXCaQx0BWZ9W8Su/VIsZsLtYIsNyFs65/OXMsH/3o5/F5zKg1fyxWfyFki2WmBP2LJpelqFrWoKe0UPMYCsVTuGkgOQtJPFA5f/4VKNdaYXguvCoC0DDx1cn0qcuaKGvqW2MsuCCteT8tBBy1x9KLivPmSxMJrgvHAi7rQYOhovkPdB7/", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x209bb0d076f9195391f7ed900a4d8c788cc9bf114a1c0c467f5555920b061a70", + "0xf5b1c844495f0396f5418e9eb4e487d26f70f0e464c83670e8efba62f2af843e", + "0x6555bc7af8c1790ace374c7ae84e169d4acde81319606c6ac37fa846014e2ace", + "0xc2e9d0bc1c81d6860da30267bf89552a542ece90ed5aac3cc6da5bd1ee114aa1" + ], + "prestateLeaf": "i2cHGSJXUzBi9FznRsUTY8egUCL8wmep7Nnd1fqQY5vUFIiYsAmrMcxMVjlP9rFTD1wmkMdAVmfVvErv1SLGbC7WCLDchbOufzlzLB/96OfxecyoNX8sVn8hZItlpgT9iyaXpaha1qCntFDzGArFU7hpIDkLSTxQOX/+FSjXWmF4LrwqAtAw8Q==", + "poststateLeaf": "1cn0qcuaKGvqW2MsuCCteT8tBBy1x9KLivPmSxMJrgvHAi7rQYOhovkPdB7/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "sKUc0bS3vxziYuLSVP+8vjktAy0msieRxuSg0iLcAUuY03cmnnGtdmwOKwfuF2sHLGMDos8IwPbULHApG/i49Y3JAF4iRBWmppjET9h2cKwXgF83mrzd7Zd1bh7f/nz70AGPgfwuRVCYPRruYO36Lbynwg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x932653825685e7a4719f711e5de643e9325e3e584f4b1f4f173a1d8914f087ef" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "sKUc0bS3vxziYuLSVP+8vjktAy0msieRxuSg0iLcAUuY03cmnnGtdmwOKwfuF2sHLGMDos8IwPbULHApG/i49Y3JAF4iRBWmppjET9h2cKwXgF83mrzd7Zd1bh7f/nz70AGPgfwuRVCYPRruYO36LbynwgEAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "iCvCPAopIESMi+Hl25arOaBs3JhDP9dQJg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x2a05292281cbe8bb141e10a2199e10229ea3b1c049f9c3837090109a6c2c2ecc" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "iCvCPAopIESMi+Hl25arOaBs3JhDP9dQJgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "0Q32kVEATjV2f/Cc0dbx3q+SNfict2QIVg8omyeC1HVF5Q203mKtvn8AH+QrgdMblbSwlGNS9QzCnqG1nnL3RER16Nb8DP8e9r+iLNtBeOFehZTn1KN/1ijJPHZNvJrvDwM5dwh9EMX1ctTG8Byoc3UG/+gZR+gmEQLxO0nQcsgHPzt6+ycmnOxjSEXOzCPltEAzAL9hkcz6fq6+m6TxC88wYP9/bW9QaZ7b0zX1i8Uw+mV5PXl8wnBdOPjRvVAQORtgrMP8VTQJO22AuUwSkz5x3amjKwSzzck1OZhpkrCaUDfRCHkMbntJTG00XNTJYzW2nJEU1Fxt6H1106wqX7MfYmWGhyQFHbz/nyu8Ry72f/4k6AuM+mtv75ST3UzpuQsG3OAYiejOiNM8dBoNP7jlU71SX+CmyGEPUP8OZ+hzY3JGIV7R/gYKIlf/EUCh4Ia12ulV1wQYy4WXCimRZeb93WsDmwaQRPzLwPDWqVmaiabpIgu6YkxTnmKs9fjKiCfVk3qn+P0ozfesw2wC2ZzlwfEu1/wqaaI/D/g0B3w5XkdcCj0jcynsocZxcRKD5K0xHtsk1fW6WBaJahzdCbze52YfGEd6pjdqIkC1pWBNCBOzzHxdAdy2uLkO06VLUXrfqi7NhGFx/A//0mAwrYBvZg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x0612e664e63ff3bb719e78e5b85386d0dec52681cfaf54d349d977c8a280e4fb", + "0x022de869c20a4d79405b04d2e0a220a3221bd4a6b4c4193470167a01e38255d4", + "0x7c6e00e7a3f0b65becc63b04d3666ce3223bc97cb3cdd9b5a541bebc2d6bcf39", + "0x5d9ccd2eecf274c471a3402b8f702ba8da1f9658c33c218ee6415ddbdb6b0fac" + ], + "prestateLeaf": "9n/+JOgLjPprb++Uk91M6bkLBtzgGInozojTPHQaDT+45VO9Ul/gpshhD1D/Dmfoc2NyRiFe0f4GCiJX/xFAoeCGtdrpVdcEGMuFlwopkWXm/d1rA5sGkET8y8Dw1qlZmomm6SILumJMU55irPX4yogn1ZN6p/j9KM33rMNsAtmc5cHxLtf8Kg==", + "poststateLeaf": "aaI/D/g0B3w5XkdcCj0jcynsocZxcRKD5K0xHtsk1fW6WBaJahzdCbze52YfGEd6pjdqIkC1pWBNCBOzzHxdAdy2uLkO06VLUXrfqi7NhGFx/A//0mAwrYBvZgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "NIvaQ23RKSRtOnN9vQ/eEvXlDlYOTTy9STSkj6bTYU9dIQEZy8rHsgD+UkPF8anrPL0ZUdMQ5S7mAa0VB4/vDfB8Kl9H5j3jISJWQEY8HaCuc9JsS1PyLxROveE=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xf4fd54da2d9deebfb13c263519bc96a75981aec25cfb546c9de7705284ae6c07" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "NIvaQ23RKSRtOnN9vQ/eEvXlDlYOTTy9STSkj6bTYU9dIQEZy8rHsgD+UkPF8anrPL0ZUdMQ5S7mAa0VB4/vDfB8Kl9H5j3jISJWQEY8HaCuc9JsS1PyLxROveEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "WJq3C6/ENKsK+af/2LODE86sRiOi2eX+Mkro7gDG2NdmasXjRH0RpFhKyL73WFEeGYbAaO5f4E/zHCrXGfYZyyarF0LZHNBq8TkvrsojRRhVmGbnn4axeDtUdJq+Hd2eQAem4mgKo6UnuY8aqizBlyJ58mR6KFSOG093KapJ55umKtTD1yvwroBss+KQfT2ZKYfEKDPK1e+iASvyeaYcR5lACt1pUMbnoDjmgg776vW0lITGXIijVQ8U7KWwrKi5k0qgxcpJgEAB5IHQUf4z/hWlLWCpvYlKmVNDKQVVTkrXEXArYXorV/SkjMijQrfZT1AO1e9Z4WDXVJ2l5g9KQVfOpuveOMiFV3/wuvRXVf70bAS+NdJKjq1ybTnauagyZcmMDdkgwZNikg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x9410877f4fdd218916c30132d71ad536abd51dd03b167c8883f42f0859db47f8", + "0x526b5b02a339336494f78a1640c5ba2c7d7c4c6c710866660dee1fbd740fa3da", + "0x696dd9436f075634f1169564bb051a3f285ddabaa3e849ac8b8793644311c0cc" + ], + "prestateLeaf": "gGyz4pB9PZkph8QoM8rV76IBK/J5phxHmUAK3WlQxuegOOaCDvvq9bSUhMZciKNVDxTspbCsqLmTSqDFykmAQAHkgdBR/jP+FaUtYKm9iUqZU0MpBVVOStcRcCtheitX9KSMyKNCt9lPUA7V71nhYNdUnaXmD0pBV86m6944yIVXf/C69FdV/g==", + "poststateLeaf": "9GwEvjXSSo6tcm052rmoMmXJjA3ZIMGTYpIBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "ZWavHk6IjAS6FtSg9Qg0/c66sfYSTd8ER1pOY+RfR4csyVA8hTFGr6qhOijQjiOzhgUyhZ5Fh8qz0bHMVcxradAbUTZWgb42FrrLUxQptkt8dXZL/Q6phalrTgbWQ5+96ibUGN35fp7PGywHBjlfua4R6/PMBh+hB/8e+Yw63JIZEo2cCYkDp8vMVsIAXkcXD2N8EnIogwhabH3m4XzTvg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x69f77a980ff49e17ec1d6f7b5a139c639ee8992e0eb984828230ef8c053ceae3", + "0x9cd3406f0032d6c07706ebf760890230207d0450a82a711a4d0d927f58dae176" + ], + "prestateLeaf": "ZWavHk6IjAS6FtSg9Qg0/c66sfYSTd8ER1pOY+RfR4csyVA8hTFGr6qhOijQjiOzhgUyhZ5Fh8qz0bHMVcxradAbUTZWgb42FrrLUxQptkt8dXZL/Q6phalrTgbWQ5+96ibUGN35fp7PGywHBjlfua4R6/PMBh+hB/8e+Yw63JIZEo2cCYkDpw==", + "poststateLeaf": "y8xWwgBeRxcPY3wSciiDCFpsfebhfNO+AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "9B9WjYRHM8VA/jKZMRck7bmaKpBidrMIUDcXfze1p7pTFpDN2z4ypMC/qtKkHTVCKFxR9Nb3OkatpLc7L3Zb3mGxgRnL9Z3oviZBQcOwAlgbrnEDnMStOStYHz+FoFWIcvBTblRBdviyQP/eD548mirFH2ldUm/0OVk1ESw336R2lZjz+f2puqfz2eRG9az/4C0qY2FYH2KMzrsdM18sGfOZjf9ptIS47Q8BccZJm/QshiofxA+lGzjI16iJPdAEKEKn+rZ2mcgU+DqOoZBXLqM09+5xW9oIMnAHrN8JLC2xC8cIExVAjFvPK7ePTMIn8mC958AvxYS9H6fmocZqPqbJp1FH/8H0NzNcZvyIFYMNHD4jfX3Y1b6Q6FAY/gIpmZ91PyeOmoNHiRPgGiCvsBULJPLMdSr1iCgeVWwZ/ZmCiaKopqElo9q1BAPaLLBzLm0Ev/1CjQlp4tXvKcLtgcvmU6/7N7xQ4qE7tLEc1q62XUjXBgPorL+HyK52mKN9Ezuuey0rmrtx8qClcggg1LL+yAk2Vw25F4uwRHc9/jbv468ejPRGc/vOgU7hpqi8q5aYtsKcP4DB7k9+DbwViyVHOuYO+BKXYw0SAKF0cptWjYXzSCYNabym/jOMpiJpAF4OzH9acQGVFOV+fIEEwLp/GIPvy3/QAYsoKrnkVq/2dznCLVdLMYZuFdfWd55T", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xa9075e08f50b532bf7d6b052d069f6912a004996b9e8267427e50051abd7eeeb", + "0x622ef2b8079f03d64180a9a075edb64a30a6749de2ca75ea95f7aea3b73036b4", + "0x28ad78f57bf70f4a719bf2425675f92b0a455058db0ea2d80758ec35232f67c8", + "0x0481c175877e232f0950033b43560e873846692d8680038ca0fe78edd4f99300" + ], + "prestateLeaf": "DRw+I3192NW+kOhQGP4CKZmfdT8njpqDR4kT4Bogr7AVCyTyzHUq9YgoHlVsGf2ZgomiqKahJaPatQQD2iywcy5tBL/9Qo0JaeLV7ynC7YHL5lOv+ze8UOKhO7SxHNautl1I1wYD6Ky/h8iudpijfRM7rnstK5q7cfKgpXIIINSy/sgJNlcNuQ==", + "poststateLeaf": "F4uwRHc9/jbv468ejPRGc/vOgU7hpqi8q5aYtsKcP4DB7k9+DbwViyVHOuYO+BKXYw0SAKF0cptWjYXzSCYNabym/jOMpiJpAF4OzH9acQGVFOV+fIEEwLp/GIPvy3/QAYsoKrnkVq/2dznCLVdLMYZuFdfWd55TAQAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "owc1BQ5UPycfsH2vPF8uvab49MBYxShWUNX2a3eL/IhA1Z+4OVXjj2pHNa6ojDeNmMh3hF6Y9g2lfENfNWYlLjFyB5FtVcQH87J/qQNHFW6l/WyUxD63YanQRZBs+t6MhyYHOSjfFdh/cGfXRgq57jeeQFlaVQez00hKrWKP3j5HPd0xe8ujwj684kT4aJs8024CHmzFG8YaR0N12SEjYZ80GifHAu8Yr16pfTezBBtlvrnwScH53fpJpRhECOrNZYM4anrxniTWCr2In03wvwGoPiYyQBWIrdQqwSL77qd7/xr90Lgx1GN3aSrr5T4Os4eI7c3lUz3dBm5u2fSWCORB3iRWTYeRLL7+CxX0aVv3FCYP2ILFpBw+ARsNPF3ixCXGPMup8sDUWata79q06TSKNJkJB1kYtrLq7yDr8shi4RGVxeDE9XvrXCKyAvPndIVWyqGzBU6RihuN+AZXtIlodwXnxBOT2m61YYO7w0Md61Dau5BeTAdqcxjTEfI+YCbSztCVsDGPRg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xcbdf37a7133ed5a200a3fad2902cd9bc1c4dec85d29cc1a83867217940d0d114", + "0xfed99f21455221b33517e24fcd4c26288a62348960c6da111ac49e9059aa2b1d", + "0xb8c1db5a6337825b6233ce1435766d364a7f2f6b2dab42ea06b24a9af485a916" + ], + "prestateLeaf": "PrziRPhomzzTbgIebMUbxhpHQ3XZISNhnzQaJ8cC7xivXql9N7MEG2W+ufBJwfnd+kmlGEQI6s1lgzhqevGeJNYKvYifTfC/Aag+JjJAFYit1CrBIvvup3v/Gv3QuDHUY3dpKuvlPg6zh4jtzeVTPd0Gbm7Z9JYI5EHeJFZNh5Esvv4LFfRpWw==", + "poststateLeaf": "9xQmD9iCxaQcPgEbDTxd4sQlxjzLqfLA1FmrWu/atOk0ijSZCQdZGLay6u8g6/LIYuERlcXgxPV761wisgLz53SFVsqhswVOkYobjfgGV7SJaHcF58QTk9putWGDu8NDHetQ2ruQXkwHanMY0xHyPmAm0s7QlbAxj0YBAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "YmDfFJIJu992WScmzsVyne6MajcLV+PAuHQjjeqJffVgEfJQF5F63v7SVo2qm3F70XGO6LGinr8bUrXd/PKZp75uTG3THIudOg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x759c2672c3bad10c418cbecf4d7562dba49569dfea68ffcb444d7660591e2d7d" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "YmDfFJIJu992WScmzsVyne6MajcLV+PAuHQjjeqJffVgEfJQF5F63v7SVo2qm3F70XGO6LGinr8bUrXd/PKZp75uTG3THIudOgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "TlqhRie7Nhwexw1cmkr0hATHvGmCOnB8i9ftoZMSzbAS/165lmc0rlMZ447NSXcz3NIe11btVQziiaCWa9v4EOJsrrN6b+TPcHao380s+qpWskkRjkxb8iFLIpgiOnty6/uENcyPjlVG3Ll+MT+ICas+Xua9cQweWhn2NrOWU5Q5rvRJu/YiUAzuyE1m3WCNR+VayoqtOYCot7ehD3QBUyHx/zPXSgLiYoFNxdEfmm46AEeXjpZoCYvLm2CBALOt", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x28c1a0012cbe44f3fb5ed2feccbd1fa7aae1f76234c1a8dc19ef694bad386c55", + "0xcde2358bf74c4718abbb00ab46ee37162b743cb879145dd598861253bdbd607b" + ], + "prestateLeaf": "TlqhRie7Nhwexw1cmkr0hATHvGmCOnB8i9ftoZMSzbAS/165lmc0rlMZ447NSXcz3NIe11btVQziiaCWa9v4EOJsrrN6b+TPcHao380s+qpWskkRjkxb8iFLIpgiOnty6/uENcyPjlVG3Ll+MT+ICas+Xua9cQweWhn2NrOWU5Q5rvRJu/YiUA==", + "poststateLeaf": "DO7ITWbdYI1H5VrKiq05gKi3t6EPdAFTIfH/M9dKAuJigU3F0R+abjoAR5eOlmgJi8ubYIEAs60BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "gKWk0Np+a/dx780AIKKk56s351Mse9BugFfE0VVhqhSwR4NSyqoHio77lhavHgnRAcMLLJXhjTAIZ4lg+0+L0iN2z4jTg+SfcDe5rBLN5E16a8c+0+ezxQ/L6MWOlfp4sHHIcBo/HGF0YRiTcx42pBF+pW3BNSobeB3EXPWuKDloNXpOXj0sgNcV2KtBGfEnjcnySaTEqeHtEWDy2o/h5MTc3on1DPcLKihAQLvQ9GLphQ8Vt2kl4qEsyuta6YczVzQUHKy86ft90ksQwq7EAWsK1jyDCbtlgjoTV21ZxW+7ZN4IJPEcSEZ1wZqbvIffvm2S9GyuxTQB+WVI4pfaBuLRs7cTn14F4aZQdoynjIdi1tQnFynhgt6i51GaKbNQaQTennUT6OHHR27psec9grrM4g9rP4iQpwhN3NA0TUkKWewZnF1HLdT8sHjIgcl/m/juYV8qSM8pg10zQ4igltSy28ercGVATyR8I2Ec9TyWJl0k/9Nb4Nbubm1/ihXcKj2M7vrz3qCX0FCZ0rtkV6TJEkH1zzHeNvMHJHs6", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x164fec47c39000332e03169d3f0d740846ee98a365a839fd75dc244d4ebf72ce", + "0x7824bccd36d6084e91e3602f58d6c1326872ffb714e9eb277b6744a9827ee4f0", + "0x1e2bfc61a776eda7628befbc415539254225bb9393d147911a85f3b4f3ac8a97", + "0xe7cdcbf0dad6b72f51f1fee83827cb0bca75da17ff1178abd13ec30c28d67512" + ], + "prestateLeaf": "YtbUJxcp4YLeoudRmimzUGkE3p51E+jhx0du6bHnPYK6zOIPaz+IkKcITdzQNE1JClnsGZxdRy3U/LB4yIHJf5v47mFfKkjPKYNdM0OIoJbUstvHq3BlQE8kfCNhHPU8liZdJP/TW+DW7m5tf4oV3Co9jO76896gl9BQmdK7ZFekyRJB9c8x3g==", + "poststateLeaf": "NvMHJHs6AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "XUhVEs9TzsmGyDuTIzwiSfzBvUfuFL1az6WNUYUwrx1x+5eAlN4vNxu53vMsPyzxsNs5bdR51KrDOC4cMB+ruK+ScuqtroI4AH3HIZT4mJeDOZnQHQXwumlybeeumFxL4MWq8YlFe15lUeRbVLlOXPuvWb7D2K2eGout3LFWEJ2jhfyQKgBiE8bUxTRX0MbJwoyR3LOOraDdtJWnomR5rdDqKwvtSjzBRmkHErNfVngifWgxz21H/JpM/FcEuHVWyoVUON2vMO7VY49DtNzX3mnVODXaIfiuxUx9tNt/qKiru5ds51w/7Mi/4MAx/VQQljOBzukf6fSo3IQR/VIr/oNZD8jS+/rTU9wxcbu6f0GstkKbJ3FmZm2/sRh/tmW3M+aMdHewQWUkH3n/z7CWJmh9Eb+1h6oCQ55we2ZsaxK0DFa+7YB6WpCVPg7AJe4iE7caMvDByi+w3VmbfLQknySPxShXdqCaIQPc53sFLrnHNSQWIium8o7KKU2DB4mPHO3atulp1MwoleLYD8FApfV4Qawoe0/22EGcWrlKFV7X3bS44jzNv/A2PiUUgE/Z34ND+Ofw5z9J4l9Ndc39vG0D/r+nGaL7zaeJ7MV7pQE+xZc6P5K4R1+Q+s+eVh16vsscYybG", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xab67a1d5b80bd313522dfb9ab7e5f5134da2a78e13c4cbd21915014bf2c9f820", + "0x7e524169ad08838f7119b4bd41062fdbbd856fe06ab23be337cbbfa7617c3312", + "0x353f3fc5a7ae59224bcc68262145bb94fb94f9ebed52f9c9dbc5439fab5b1fcc", + "0xc407900eb6a3f77e774a60251244f5e9fae95765de26f48869a834bbe7c5f847" + ], + "prestateLeaf": "rLZCmydxZmZtv7EYf7ZltzPmjHR3sEFlJB95/8+wliZofRG/tYeqAkOecHtmbGsStAxWvu2AelqQlT4OwCXuIhO3GjLwwcovsN1Zm3y0JJ8kj8UoV3agmiED3Od7BS65xzUkFiIrpvKOyilNgweJjxzt2rbpadTMKJXi2A/BQKX1eEGsKHtP9g==", + "poststateLeaf": "2EGcWrlKFV7X3bS44jzNv/A2PiUUgE/Z34ND+Ofw5z9J4l9Ndc39vG0D/r+nGaL7zaeJ7MV7pQE+xZc6P5K4R1+Q+s+eVh16vsscYybGAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "OkvbSQAYhLTM/S40CwkShoqc/doQKJuRniWw25qw0ATH9AGBMrIH4GQmBhBJ21JF+DXKHbaX0hiDUo5sRiyPhUNLC3WiHB58XzKUr2R3TCFy1G8f1ufiJSl0tiVEuPUo7EHVB9J8WXz/O97Icsakb5jrzYiLSdsy0Pc82A/tfTZBPuhC4HZ5jhqVetBiRoW8HdS6/dLSioR7XyXUP18KEn9+GC+/QvLpl/bvVRnnvmXpXM/h68d0+cfI5yVvvKZccaAHZcwmkLSC6Sm39Lh3TTM5ETt9Y2nB1kVD2K+02E7Q6pvC61Sm9sVGRSTylcCCLO1HnCQyN50U0HpJwNkC0svtIOfQCnN25I6Mice/rD0sWPkxaEGTJjnYVLY+14+yEhsSRfJPAacUfkmV4QFhFd1bD+PWmRWe3y2C97zwFp2P6i9WANfG/WV1HxXibjJSasmkdb32mHDBa/XFR+A5uDMdprOoJDKS", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x6a9c620efe67cd187c9f5885cc2c58d9b359246302be95baf2364c508398d59d", + "0xc9f347ba036d7973cd36ee090a73da7a99331f913b962292912b5c64bed6711a", + "0x961ed6a2ceb428015ef02f857d420a6e858daee2ba77a7bd025d9ca785ea4725" + ], + "prestateLeaf": "GpV60GJGhbwd1Lr90tKKhHtfJdQ/XwoSf34YL79C8umX9u9VGee+Zelcz+Hrx3T5x8jnJW+8plxxoAdlzCaQtILpKbf0uHdNMzkRO31jacHWRUPYr7TYTtDqm8LrVKb2xUZFJPKVwIIs7UecJDI3nRTQeknA2QLSy+0g59AKc3bkjoyJx7+sPQ==", + "poststateLeaf": "LFj5MWhBkyY52FS2PtePshIbEkXyTwGnFH5JleEBYRXdWw/j1pkVnt8tgve88Badj+ovVgDXxv1ldR8V4m4yUmrJpHW99phwwWv1xUfgObgzHaazqCQykgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "Dni8xdY2FY53gk916B/zgDq3IuWYwhZ2NCTGNBSp7F4a/peabO3eHNz3/j/lD3a4nG8CIZ5/NeS52OhCAo4ie7iS2SkEt0hLmoXOXHg6WRM7BEFFymqBjnr3R7gj26Uht93NNYK9+UuaW1kW4+s4ZvmyVHPPZ9I4hSIaSjg2r3l3/ZVnCgD640AxwtJL/kGZSjjlU5Snhmkn+X911AofeDbyZB4K70P+9fbGKYsKJCVF7VMP/EBmLNlTryt12Us3k7ddtMF1NJzk8xDamkYrmJZNjf3ol3kYr9qdbd5JkBdOObnc9b5m898vqXQWCmS6LcThuy5+QM0y8lDBEScuQag/xKboULbjwcYBur0Ci5ua+d0H4/xlDmNMI+ruuB+B+G14+P+xPPjK2Iu9b93K38K+yZvTPh21tdvj/4njdAMp2w3C0S4tM/XNQVHZLFwuDR6mMzMUj1M9u2rZNU607qL32thrYE/gDavvDUJ1EcKTtHefUbxPYTBwZ5STNTGImenbSCu3wWdNieRmtujsLXSr6vYgqHtF6K8cyqOaOQwb6D1J/ilxZhD0cNWqQEJOnKjIcw3MhjQjSz13Zqy4Kz4BgfZYiVqfsoMW3sW7233jtPR5tmMe3G2kDppZbMmrlak8ooiKstiYKwMR4XvKKQVJyhjj5M9LheuzBvH8fol9wihZWOBdvz5s3RvqDWQkikwMDHxSrRRkwVO7weEK", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x9236647f7e834b5ef526146639f3e19a91a5e84f2f6a0483b11389a644cedf68", + "0xe3e0db33b1016c4a1e2cd90fa3cdd7268a70a17cfa801b8112bf9da81e9dff6e", + "0x31b580ad3e4eab83a0cefe3b5f580325e02cc9698dfd892c1f89dc881103edb3", + "0x619db25a967f481df1824cba2a713b7f0e256f74be84aa09b1a80fdc51c20aa6" + ], + "prestateLeaf": "mvndB+P8ZQ5jTCPq7rgfgfhtePj/sTz4ytiLvW/dyt/Cvsmb0z4dtbXb4/+J43QDKdsNwtEuLTP1zUFR2SxcLg0epjMzFI9TPbtq2TVOtO6i99rYa2BP4A2r7w1CdRHCk7R3n1G8T2EwcGeUkzUxiJnp20grt8FnTYnkZrbo7C10q+r2IKh7RQ==", + "poststateLeaf": "6K8cyqOaOQwb6D1J/ilxZhD0cNWqQEJOnKjIcw3MhjQjSz13Zqy4Kz4BgfZYiVqfsoMW3sW7233jtPR5tmMe3G2kDppZbMmrlak8ooiKstiYKwMR4XvKKQVJyhjj5M9LheuzBvH8fol9wihZWOBdvz5s3RvqDWQkikwMDHxSrRRkwVO7weEKgQ==" + }, + { + "input": "548ML89LjxGqzaKfXD2+DzRe/n4KnhoXHQQxl245B4A6Jd1kIisZ7ZtlgMFIsrRI4SHYo56gPUeNQKKZS1tnkbhwz4Be7FJgaNhy8qmaR1lrPMmGNG3yK0OZbDoZPWWKEnGYwb0wXIXKykd2OeD+V1FEVIb1varcqD6e31UxjH2sKNfbfb2LJj/OC2L5Lg91Qs6L188Wb63WNt+B8c7ArvbgwKwMLVfFcBwwKJjez6MsuiY7nADjs6i/PhTXrkQQKTF5WWzbHpOtCpBAGEF+TjPD0V3V3eAkz7tcvl1PaAcF63i7f5whXYhhpng/QWrxSKjYBFp1E1fcTATM9+O49z7f6AebERcv34sspmYXZE+Hs6HLE0oMnYHOPUOf91qT29khKLbW2DIYZgd8TR/xnL8u6aLZY3dED9cKpUNtJxX2aLN+2gX+O5rZ5MC8816oBTtBmT7eph2HVrPdJODSGtmQ+QU55DORHur9tss1uf+cy3mKtwY+Y7xDmTsA", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xfe5251befacdee21746ad860d05e7b49c23a954a731a7ae61f1a02e6408e66ba", + "0x45bcd5f51777f3ab924800b6671cd928b96287806ba19fbf9f90d1aa8f50774a", + "0x5d4d865d850c9cea52df84142bc0ee4599e586103df653530d5204e265061ca4" + ], + "prestateLeaf": "P84LYvkuD3VCzovXzxZvrdY234HxzsCu9uDArAwtV8VwHDAomN7Poyy6JjucAOOzqL8+FNeuRBApMXlZbNsek60KkEAYQX5OM8PRXdXd4CTPu1y+XU9oBwXreLt/nCFdiGGmeD9BavFIqNgEWnUTV9xMBMz347j3Pt/oB5sRFy/fiyymZhdkTw==", + "poststateLeaf": "h7OhyxNKDJ2Bzj1Dn/dak9vZISi21tgyGGYHfE0f8Zy/Lumi2WN3RA/XCqVDbScV9mizftoF/jua2eTAvPNeqAU7QZk+3qYdh1az3STg0hrZkPkFOeQzkR7q/bbLNbn/nMt5ircGPmO8Q5k7AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "ugu7GzhFq70GgrGQSZEFItW0+khpzmPODUEXabcK2KJPgynWcsBBeW0vNfySTjgOiz6pPaoAvoOf/PokycT6t5fd1A8qHbV+yowAzHElFEJXHjUntFCxI9PNJcJo8758kELCR8R9YKBXZVjmF+M87WWg6/g+d9dpj5AL32dU7kQmLkPu5kaxL7hJRTOlzBJQrMNz7G/BWPJJ0GNbFhvrc2YZIL/LGPCt4OZEHFjG90RRXa9w+cWjZHS/QHAGufVSswFDt52O8/XB0KbI2MWpltbOz2+lCg+M6h19Fx0f47i90BlLymMVi5CZRJ5DhlPkuG3KVo0rUrGEcuizcx7HifIbf45PHOdT8HYvxKedmXCq5MsLd1Ohh9WjzCwaCuql9kc1jBW5OzoFWKnaDGlaCyJqeI1lQBz8FqBHYQi5w8DH/m1ZV7T9StMH1qndmcyNJyMlxhGmGU8QmYBR7hnDTnJpeNkRK6l8LEwcjfen1JXhWy78M98bqZxZiArQBmYImtO1YG7LHhftULixizOxezWO9xaSPZBXh5a7pQ==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xe72dc36a1aa4e46b0ad98ecca057473bbb1cd8af95eeaa11718fde0b652d7c00", + "0xd76c62cf7bfb075bde0ca1f3559e20ea16ff017bf9d8c56dd6a7b5d25b0d4c96", + "0x6e8fb71d0bea05ea7d8426b3169b2ad5c59d13679139ea6cf80c27db4def900c", + "0xff0fda4e3f43d1c1cdcc59bde8114efff8959d1aec78910020892f6786a11f3d" + ], + "prestateLeaf": "quTLC3dToYfVo8wsGgrqpfZHNYwVuTs6BVip2gxpWgsianiNZUAc/BagR2EIucPAx/5tWVe0/UrTB9ap3ZnMjScjJcYRphlPEJmAUe4Zw05yaXjZESupfCxMHI33p9SV4Vsu/DPfG6mcWYgK0AZmCJrTtWBuyx4X7VC4sYszsXs1jvcWkj2QVw==", + "poststateLeaf": "h5a7pQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "iO4gx/gywUBIM+L59hSKkEPKdj5hVnhQGPcTRscZ10xBbdpZW6xIvZtsCGxmFXa85MP9X37X7ysMtUvspHBYeU8sVGl0GbGb3oxD1Eb9JBGDs1BGPnkDqWeikVfMEaE3HeqrDaxHhGOOLLCT2kM+mWKhAM1NlO4CD/1YuITSyfPlygI0bP5NuhjRe46vVaJpxa0dbByZNvX9dWqk6TQ7hb6ui5eOhtjeN0nw5rxyHPZXn2JTBZGfD0WRI3vDi+97DxziWq/Hl7xJUql1fYiq1X6BYevrMcO16ORcJUY9Q9LtLw+aq38xbQCrtYZv9PqjHjMLG38Lj5pqFi+PiacaDEsWYHk8JmC6VWMkVGP42uWncKlI4vBO+S/7G5VVuJociI8Bmu0Io0Tr7S/NaERIqC9y4SSN7UPzqtpHhQexlfYdnl41UsBzTrDwhdoHyDHuDNnRRB7vTIRnV1ejNX3F72XyrhB2q5fWza2ex+Iz9op7ldop7x3jJjl5PVSmPP0a5QhOW6k+TWtDrujqFaqk9Vuz9Qq27bj51nLNzbMzM57kupnIKNrHr3Hr/W8FdqXmU8UWCI5cX3lBxg/ywNVpvE5JV3C/vfXcfS5vFm4zJS5Gbg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x3465128281e0960e6d11814935dece2d58fe79fd3ae0dc9aa1fedb23190adcea", + "0x956bddcb7caf1472e24289ec253118a9a946cfec3faa43d9cdfb3583c6428c02", + "0x256986bdf9066db60f75792c65aa192e846df14a3478a7881238b66b458a81be", + "0x9db4b75e27b3bb292bdd450030a1b43d0f6be658fe6d59c711f534d97afa964d" + ], + "prestateLeaf": "p3CpSOLwTvkv+xuVVbiaHIiPAZrtCKNE6+0vzWhESKgvcuEkje1D86raR4UHsZX2HZ5eNVLAc06w8IXaB8gx7gzZ0UQe70yEZ1dXozV9xe9l8q4QdquX1s2tnsfiM/aKe5XaKe8d4yY5eT1Upjz9GuUITlupPk1rQ67o6hWqpPVbs/UKtu24+Q==", + "poststateLeaf": "1nLNzbMzM57kupnIKNrHr3Hr/W8FdqXmU8UWCI5cX3lBxg/ywNVpvE5JV3C/vfXcfS5vFm4zJS5GbgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "VLPu7ILgq9sB+QMzMPf+iYHuoTT2uKjjcs3QJwJGZOlTXBqUZClVaii3BV/rI/iDshbTrWefG4rD5CaLBqcdYTM4JXt1DnnK2S1C77rFTkM6dkN+q2juKQJNDIxGDxcgztKPzmksK47yLnCwxEDbA9E5mKDjnBwCcnfsqbKjg6o2/9LJu1xlj0q0urR3TMCBl+/FaIJmiQ==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xbf4fd89b077bf39077318ff9f2eb126cb04c2b3ef6f9f3f1bfb2204e367f731e", + "0xb669198808b22cc2e730d88fee059c96b9d13057b509b4b26cb625a04e75432e" + ], + "prestateLeaf": "VLPu7ILgq9sB+QMzMPf+iYHuoTT2uKjjcs3QJwJGZOlTXBqUZClVaii3BV/rI/iDshbTrWefG4rD5CaLBqcdYTM4JXt1DnnK2S1C77rFTkM6dkN+q2juKQJNDIxGDxcgztKPzmksK47yLnCwxEDbA9E5mKDjnBwCcnfsqbKjg6o2/9LJu1xljw==", + "poststateLeaf": "SrS6tHdMwIGX78VogmaJAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "iaA3KhRXBhnFjkR2szfpxFslTINxAiauR6ZS41N7Tyfnk5iczJHJmjmPvWLUVbsoFWwbBvGkVPPJSyYV8z6Ll+CzQJmR", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xe2a777a8bffe0bbba1ad4d89515f6eaa9440c7d843b5543ce53cf15cdd7dc4ef" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "iaA3KhRXBhnFjkR2szfpxFslTINxAiauR6ZS41N7Tyfnk5iczJHJmjmPvWLUVbsoFWwbBvGkVPPJSyYV8z6Ll+CzQJmRAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "X/hVerdH6C8Evfr1bjZ7xBxsFQN1t/PSrXv64Au/vEZMz68f9T7p9OopxElulNEjA/UlijpVs0H81HF29eAyyfqvKojBH6dhCjhMij2DErMGLenHXanHzN6u2LKVv1o1+tCusG7Rw6bzbTsq0Ee95bOfvzfO27/kpJtBFN+5rhm01rez85tb1bEmkgx6Uf18hKF4WES4zUmdE1MEhcClMJEfQy6ZR8NA3x1qRYhUq9r3xmhN1+vFC+YDX0hdTWuCJg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xead8ca105740b9ddb7988299eb5f06b4dcae604c5b0d08a2cdc8695be973f1f9", + "0x053b8f8c5638392c64f158efd55ccb268671ff1cadfa6b919f23f4c58722ddbe" + ], + "prestateLeaf": "X/hVerdH6C8Evfr1bjZ7xBxsFQN1t/PSrXv64Au/vEZMz68f9T7p9OopxElulNEjA/UlijpVs0H81HF29eAyyfqvKojBH6dhCjhMij2DErMGLenHXanHzN6u2LKVv1o1+tCusG7Rw6bzbTsq0Ee95bOfvzfO27/kpJtBFN+5rhm01rez85tb1Q==", + "poststateLeaf": "sSaSDHpR/XyEoXhYRLjNSZ0TUwSFwKUwkR9DLplHw0DfHWpFiFSr2vfGaE3X68UL5gNfSF1Na4ImAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "CeiQEBsTzUss2uuNs6R4kez3liQg+cPLxmbI4+TE19MAHKQ78tPctAoZ3otdXalXdNWwpX1JnWlFGINd+p0g99Vbk718CS349DY5mBwMh11sOmiSRMG5TGE7d9XqSIK+5X8II7vMrcikfvhImOj1+qcVpMYMAiCceIfbnqAeS55Av+SZSDYWUnrVVZ/UBJcHeMqLmFGsJnyulwQIAvPbKPO+qY0IV8LOY8tA6NXF0aIWaSY9izGrb3pvEGOO36uaDzoYEJ6QbN9BCKUq18LtmfjqrEWfl4exdt/twKzFRWcf5MsKUkaBQyFS7mU8Lp49hs9eELETw7Tv67y+QmsWquDOoFNbGRzsclXtkoNTGJOASap3eNKvuLb3DHd5vUidqU0+6/P18dyGjJ+0JWqO", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x8cda77b99eb425ea9850550203a6525ecfefce976537ec8841cd5094ea3f5ae9", + "0xf7cbceee65f235eec33ca84440f300aecc1c83e265086d562c226065939f1b0f", + "0xf3db4825d2244a11f679202c1b476faa6467b60faeaf220b760c90799c4fc041" + ], + "prestateLeaf": "etVVn9QElwd4youYUawmfK6XBAgC89so876pjQhXws5jy0Do1cXRohZpJj2LMatvem8QY47fq5oPOhgQnpBs30EIpSrXwu2Z+OqsRZ+Xh7F23+3ArMVFZx/kywpSRoFDIVLuZTwunj2Gz14QsRPDtO/rvL5Caxaq4M6gU1sZHOxyVe2Sg1MYkw==", + "poststateLeaf": "gEmqd3jSr7i29wx3eb1InalNPuvz9fHchoyftCVqjgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "T43pAryJO7P0xU/AXcqoGcNUCxUvdZ+t+IhKI6wU821towh4/f3ykzeiOyIf4PpQ252B5CjHQzkTf4i6Tvayioo+ZwvFl7Cbt42y3apjZQExrwpCsb/NFfmw328/us91lMipJmcHox7JPPQKibW8KFa6IhseC1msQ7h8V1c1LPnr+TE4NrsfTcI+rB5mSS4YG8F+Kpi+S5OR2C8qx4NbZ7IWIpIZIxKFV28xTtl5LH837MZqYWQigiZexEpvRC4Cua6WTstsNUihbjjElElZPdZhFFLwvpG5uDUEnyt6fm+mJZkLDJG52stPIOIi0YVhkXLVln784zUUXJGWDQGg+ub+vEh2zJ+BYYsUeHUjtnfclH/s66XWtOkTMCs+rt0Kw8lJ4SX8MFDb0yjRt4HhmhyVNfU1VOxkm/Z7ad36ycQ8UOJp+qrqPr5Rk4y7RqJzKj/Fro8mJu2lanKbeYLIPsSgLwrl2rPhbUal7rHstS0UzWLxqPE9EmKikDJ6OJmSQpfF5GOuhRGoWM8NVwwt612f9xEMirXrzUzbNPgBoUibr596HzTr/m4H86gu/wVTNK7v0xMEk//6yOIKy4P3CzROI5jSHTECoNN+8Zw2rHuxctHl/rYic+4qaP2EYNKXF0EV5cJdIqvgApxbz2abAdC+Rqw5ZNYQ+O5JDy4/y7O6WB0vgsx5XXdhM8S+0gTq", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xc5f4a649be4a2f0cc9248d8ddefeee3ab3220c4d063a611eb7aad752cecba852", + "0x325134ff3a1fb7cbea02c70bf9fe234aeffb339e6c72f355f307c3f2464e9154", + "0xc11dd00fa0ecb786e18159660c847a90fcdfe098738e2b15996b2ccbf7960b06", + "0x8a645af9f6900d64a16558ad878421f6557221476f78b44ae7b03e3d2e0304dd" + ], + "prestateLeaf": "3JR/7Oul1rTpEzArPq7dCsPJSeEl/DBQ29Mo0beB4ZoclTX1NVTsZJv2e2nd+snEPFDiafqq6j6+UZOMu0aicyo/xa6PJibtpWpym3mCyD7EoC8K5dqz4W1Gpe6x7LUtFM1i8ajxPRJiopAyejiZkkKXxeRjroURqFjPDVcMLetdn/cRDIq16w==", + "poststateLeaf": "zUzbNPgBoUibr596HzTr/m4H86gu/wVTNK7v0xMEk//6yOIKy4P3CzROI5jSHTECoNN+8Zw2rHuxctHl/rYic+4qaP2EYNKXF0EV5cJdIqvgApxbz2abAdC+Rqw5ZNYQ+O5JDy4/y7O6WB0vgsx5XXdhM8S+0gTqAQAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "E8ftDm2vrPzfRJ12Iqh62rOORhMZ1BZOGxer0msLFmHUFVOorUGWfbvJHZFHVP1oRGbqlHdr05MpakpXoi+ZNSubKu/zPEAvi0veKZAm/bDzpR7rvTIaIs23pSnq35DfjT/0Xw7ksNsVlu6ZfsS0FPm26RcuOPBiYO9V8/Gq6aAvhSwDmuV33ntGNRwuCm3CZOuA72AwMJtl1LKWVsk+IV8VfVXwitp7SvDDT5e0m970/UnG/o9M9RjSRZbTWLeZfcuYH4iEi0GvvZhywJA5LIn9qg8ixhrrxbO4sl1Sto+BY4BfA4M9/bDyONN+osuVlnh5R9ovFdSqyH+nqAve6lWntoap4B1Dfgu306E7gHT1q2+9HCGrQs9puzi02qSgNCfj+RQHsdGBRgzrruXUjKx+PZV74+Wh3IwPCCwTvQvYkU/Weu8QZoP/bYpgdBJ1AVtiVI1/RTOg", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x27a30ccd006cc8547173c85181c75f532dd71c50fb6c7e57f1da58b0555b0546", + "0x540375311f1657dd7140d32f2e60d54e53b335ae54539ba511fda8d8c57b74eb", + "0xeb893e6229e028b2c510d874435c751039360b203368fa4c75114cfaf39b3c8a" + ], + "prestateLeaf": "e0Y1HC4KbcJk64DvYDAwm2XUspZWyT4hXxV9VfCK2ntK8MNPl7Sb3vT9Scb+j0z1GNJFltNYt5l9y5gfiISLQa+9mHLAkDksif2qDyLGGuvFs7iyXVK2j4FjgF8Dgz39sPI4036iy5WWeHlH2i8V1KrIf6eoC97qVae2hqngHUN+C7fToTuAdA==", + "poststateLeaf": "9atvvRwhq0LPabs4tNqkoDQn4/kUB7HRgUYM667l1Iysfj2Ve+PlodyMDwgsE70L2JFP1nrvEGaD/22KYHQSdQFbYlSNf0UzoAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "aCjoLgKIwqWlW8lhM5bxPyX5Qlipms9rSCj8uLfm6YkYbudeyCaevudHxjcCFWDzmNN4+j/6iNI2dbkQpmrulFvviU5Vn2WlmQSU5D0PvjysOviISM8Tz4PUrdvNxUfIfczgIyFhAG7hKUhi56PtZ9qkYw/I6paRhex8sVqmuei89vswG9SbLkVYU7iOOU/GgeNCfZSM", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xe9a9ed50c10f5da4e10231ad4122859ad7a4849aac33887fd6929feebb34239f", + "0xccddec19638af750e06720249e99c099c6ea622134ec8a20503013e10d2fb163" + ], + "prestateLeaf": "aCjoLgKIwqWlW8lhM5bxPyX5Qlipms9rSCj8uLfm6YkYbudeyCaevudHxjcCFWDzmNN4+j/6iNI2dbkQpmrulFvviU5Vn2WlmQSU5D0PvjysOviISM8Tz4PUrdvNxUfIfczgIyFhAG7hKUhi56PtZ9qkYw/I6paRhex8sVqmuei89vswG9SbLg==", + "poststateLeaf": "RVhTuI45T8aB40J9lIwBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "2EWBx+PqSowDuumM8eRw5jMnkK54s+tRd5qlGO6RlsR099f8Nz2regoK81zbOwFnDaLJuWMpSi0lQayfwydkZvMz5Nili00eh1d16VxCuvM4OugCz2QxaikZ3SMHiNcVStO4asCZbN2dcZpihuZSNyVScd4VvLEoPk6EZnWaEeAVV14xjfoPgT2iwwVzmrGk8sqjQJGKeYBpcbkpKa4BQqUsonxMCmTngb9p5hU9fkg4uKhVnTOV+R/1QDvhnpxbIQkSn7/oDGqQZ6H4VbR8oB7kMswhED5dQBFmF/VXvVpdwcF5fj0LMF20QIWzs8cn9o2YTS7AZJtOvFBWxBXjzhsXYDFpRI+uiOdP5lgIGDq5L03HvXa591o71hzPfmjyR8Y=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x7261444591a7e2089579fd29293a60dd750951cdb884ba12c741a159b8682d4f", + "0x7a9ea07151ca7ca8cea49e9831f91986136303705ed5589d03a9b3101e569b99", + "0x5e8282b46e4352cb1e56e9f5a0a08ddacb112cc8e85192ed906ab67445235202" + ], + "prestateLeaf": "PaLDBXOasaTyyqNAkYp5gGlxuSkprgFCpSyifEwKZOeBv2nmFT1+SDi4qFWdM5X5H/VAO+GenFshCRKfv+gMapBnofhVtHygHuQyzCEQPl1AEWYX9Ve9Wl3BwXl+PQswXbRAhbOzxyf2jZhNLsBkm068UFbEFePOGxdgMWlEj66I50/mWAgYOg==", + "poststateLeaf": "uS9Nx712ufdaO9Ycz35o8kfGAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "wAA1Mt5xqAbr0sTMUomvimo+WbCHDEiS+pWu+eQGgnXxDWmOmuVqwaA5N4fMefoy2e1ROvyuStbgImQ7TRSaVOJQjT7wgEjoh8K5//MlSbuNFQZnWsAltKhlibYqDV3dl+gUdz3ya0wj2Rv+bp5CgQ1DdBcct+uPD1AeLHWzE+iHDpcTUpyvZ7RFw5ZFcM0zVLObx1UDl1eTmQCWqJDNjunwTmd+msSNX7B4ot6XgR1ox5sBQyqCSLbZ+VeN3fuHzX659WQbXaYGpBE8/xBE9iYBhRMm9jYGY8ycDQVNh/5WYzvB5BX/biu0yv0M9bW/cUd7FzYZGhgVuYznR4Qi+G+HkQ7dncKk5e5PqsduTi3iA6UEOO9Oqpg5jH1MkUoi5d4yrxcdjdAuQdM/J+UQbkQ7CgH+IW3R0wZivS8UepXi7rLazScJKHL/+nZgtI/IRFl6GGvPOYUXmCmWRwzMiON1KXqzon3mKSaIb35O+uJwreK9UjkijgJJuZlRXeubMQD3I+9hSQSGrY3Zm0sVtmR2a8nboqiS0hCn9zwq+NfBnzGr2Tn9lG302auqr3hZ3ESfSYpcrcyD+yu+dRhHwIIHYLbl+Uydkc0+/llyEmEOg1QsJuHac7HPeXEX94hDhKLVey/ZVYLOe+xYPhuLilzQwqt9AorjFGtsogEWmSaO3sfjj+pOiYg=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xeed8dddc6a60a05bb1ba49d0bd7b7aa120ea8ee2757e59e8954b71502d83e295", + "0xd9e75a98f4ae520b38436ca9bf464d6f26768bad4afedcb9f7af183eccce01e3", + "0x1a7e9bdb037a90170457843bfa64b4e1442f83c1b383bd1f31878599d8d6250c", + "0xae40f2bf7d42e665ab60a5ca75ffa1515014aefd3c13f1161cc432e5b6ebad27" + ], + "prestateLeaf": "4gOlBDjvTqqYOYx9TJFKIuXeMq8XHY3QLkHTPyflEG5EOwoB/iFt0dMGYr0vFHqV4u6y2s0nCShy//p2YLSPyERZehhrzzmFF5gplkcMzIjjdSl6s6J95ikmiG9+TvricK3ivVI5Io4CSbmZUV3rmzEA9yPvYUkEhq2N2ZtLFbZkdmvJ26Kokg==", + "poststateLeaf": "0hCn9zwq+NfBnzGr2Tn9lG302auqr3hZ3ESfSYpcrcyD+yu+dRhHwIIHYLbl+Uydkc0+/llyEmEOg1QsJuHac7HPeXEX94hDhKLVey/ZVYLOe+xYPhuLilzQwqt9AorjFGtsogEWmSaO3sfjj+pOiYgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "Qvy7rQFYakrZWqUKvpTKDtWYg24HYfPSRdE+KrTXeNPq5K1J/7VvR38m6DuUtaVhVcn/d6QRQRRS5RTIDLrUQ1crIWaQ8XmMqNaFKZlBytIGvLpdDWuJ2XydRkPYYChqnH+nSpvJNfAYYKK4K4UY1JNXPjiAOP0jXvWi3oOwEz3brl84/dFPG3IO3dVHJtSzYF63YZ7UXlpJV2MP9q84GwbKirkZthc5IFv7BzOX2AXNIXNDEVkMz1oyytJGK2mlRKLNljapNmo4eAbzHKC4bF4T4ah2O8wpPiUXoWlrQex7wuAnBYGdLS6l3e8mE+Gsd0mEW7vFYKotLAepsHwbPwJ7ESGmDBxbMzicKswWKWyexEL6LpwqcFAcc6Gmiho2D1BOOqpKaApZnWowBk8HFdA2EPjaXycGIxhyftQtMV019XX6hzz93Xt4d4PS0fWfj/ViuFopU/JO3cimvzHqo7tgP8LkiHUlNDF3xnzzn8OpVtvkB7rKAx0tMRWtG+TzvBKKElyr16cYQUX+wd2/u6QBIIx45Vz5z/GzHRXP3nCuFwxNQKhXr0v6KcnGW2QfQRX2LN4PPSk5znTS8Q2R9SgBu4Kjq5sKON5zym8LW8fKOH0Nmheb1Q==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x60c9a594932bdc77815923284197c8032d96af34174bbd71ca0373b4ff58f678", + "0x945dfe1b90dad1ac86ddf5b8f27d8a8faaa6ba396113167510fb60cd088ede07", + "0xf52616b7f35617b69013c8a9485507bda0753fef7eac1b1bff8d93574de672fb", + "0x72ecc86dd75d9c5c7b1f964dd4a664a8a258a34d0b11f2d97dabaa5d4bb8ad55" + ], + "prestateLeaf": "nsRC+i6cKnBQHHOhpooaNg9QTjqqSmgKWZ1qMAZPBxXQNhD42l8nBiMYcn7ULTFdNfV1+oc8/d17eHeD0tH1n4/1YrhaKVPyTt3Ipr8x6qO7YD/C5Ih1JTQxd8Z885/DqVbb5Ae6ygMdLTEVrRvk87wSihJcq9enGEFF/sHdv7ukASCMeOVc+Q==", + "poststateLeaf": "z/GzHRXP3nCuFwxNQKhXr0v6KcnGW2QfQRX2LN4PPSk5znTS8Q2R9SgBu4Kjq5sKON5zym8LW8fKOH0Nmheb1QEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "8DTi9g8t1UVGL22HRPz6nazHrn1f/hKJghZqGDvIVodeI6eld/nUqc4EUOgcn6QAMP1ukAqK+vezIt+T6mNTSxiAf/3wTkmduX3FskhRJ8Iler8Ux1TaZhGMk4WPFbc85DUxrndqKlMsDUgSg9lPcl6KwZ6TVFKT5dIsDXSL+82geDhAyPWs3QKYcnbyJDjoN84NXjxYX/CkZOuvLi4Gf7f3VwtHM18YR6zB07hzIucsKxW2yRaMOQe4cfd0QwODs8qhxJdackMRIpDLFzVdvuglBNdrYjmIwYJtGMK5VFOJYUN3BwC3BlmZ5o9BUzDHZguVtUI2Be2fIH4HtQNnHnxZbNAZGEwoZEfc7IlAOIWu6Gy9ihCaey2Ny+xAAgC866WybS51v9QEKzfG02En0G0qxvTQI6yS16NjKFfAP06LgshjC5sZBSg35YGvlCIe/sNlLivxtJjZwx1btzp2xv/cCOOsYx7OycOQl9w9uqYdFnU1W93VErvuBDgR6+jYpyHUvguDt2SZWA3G4pf+tpS3ng2JsOjjvOVs8buGYKZeUHnfz6p9IfvFpBYu7xY4XOIY3ECTr10Kp0sOGRlBxecJ3FJwIEG8B4+dqLNO5I4AY3KjMsiWd2IPzAUN/iyOIw==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x91a22b73667e7daf8bae65680d26f92820c825105c6c5c7680e5439dd596dcd1", + "0x598fae2025414a8902bc1d75b443d7d00745e0723a1668b0d321b4d8cd22c4e4", + "0xadc78b18886ac722fd3fba10b4e2570e25eac9c438cfce45b7dbfb439b6681b9", + "0xaf0b22baaec8e6e9491ab8186ff1f262f1bf51394d61d3c1d1cef3f84796e78d" + ], + "prestateLeaf": "ruhsvYoQmnstjcvsQAIAvOulsm0udb/UBCs3xtNhJ9BtKsb00COsktejYyhXwD9Oi4LIYwubGQUoN+WBr5QiHv7DZS4r8bSY2cMdW7c6dsb/3AjjrGMezsnDkJfcPbqmHRZ1NVvd1RK77gQ4Eevo2Kch1L4Lg7dkmVgNxuKX/raUt54NibDo4w==", + "poststateLeaf": "vOVs8buGYKZeUHnfz6p9IfvFpBYu7xY4XOIY3ECTr10Kp0sOGRlBxecJ3FJwIEG8B4+dqLNO5I4AY3KjMsiWd2IPzAUN/iyOIwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "hgb6TGeZKH9EF6P843QwlJxc7JJQpBM9n5w64QSXa3VCFyrYQp3Ep/xSbgXRdIaVQVOu/yzHE1siHjhYZNCR5o1go61dlkWOULFrmfIhsFnFKbllrm8KInzHlenysEhxAMFrDr5+vfZizD0Tt/8JIMkzGy9zUfEjgRSr67dE4Do9HMznfMkgnnfO69/wlZsePVbKR/KoS8keVY/oqaDsCt6EXppCIOdX3s+uel4pWhuNEM15IxCZO3LnOTVRI+lHga7deq0xLZjDHshQVGJhX2BQn7Dey6ZBItRdF8RMNxtKaFnsV+fII5NJ/IrAl6rEPkkoyLShZX8B65Gami0QkBLHQaD1OOopE6fJjUCJCni9Ew3avacWGcA5W+Gvprv3a+budPDTTlvctGY/MWF1B2bCnCv+1lXusDfvN8Yi0a56CGabuIsk0BKlClHCcmxyxmrlswbQZ/ZRjoPHW0W2pOta7p9odDJg79cvJYEgNKn+JW99vKtb3PDXb/gsdVD/OQ+pR4RKUZNBw9YKzyFCnY/lX5jlNSb+RFyyLCBVSm3GvDIm5RTVSnQ5G0fkBZDSmLjCCIU2C3qMQoWHlx79IQfG8+BGNamo9txUgPSZDcq05RRVHLXLNg==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x99c8ecba39d9f433fb397768d380ec2231ce81b1fe7c61e58e71e31d3048dc2d", + "0x9eff473185e3c9d53c21e858e1660b72696628953521d6755e77ca29cb3740a0", + "0xd937a37fe13016d30a8722a08c3271f875a625186bca9949fda3234c96288317", + "0xb1b8222b6a4010a9f5c0773954556ddab87e7f144ef784144e84b793219ef7ec" + ], + "prestateLeaf": "vRMN2r2nFhnAOVvhr6a792vm7nTw005b3LRmPzFhdQdmwpwr/tZV7rA37zfGItGueghmm7iLJNASpQpRwnJscsZq5bMG0Gf2UY6Dx1tFtqTrWu6faHQyYO/XLyWBIDSp/iVvfbyrW9zw12/4LHVQ/zkPqUeESlGTQcPWCs8hQp2P5V+Y5TUm/g==", + "poststateLeaf": "RFyyLCBVSm3GvDIm5RTVSnQ5G0fkBZDSmLjCCIU2C3qMQoWHlx79IQfG8+BGNamo9txUgPSZDcq05RRVHLXLNgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "qa3vm4/HuDuyj8khkZxhXKZvFhhxiGOW47bfybP4mndme0Aek0OdIq6kExKRWSbRN/ZarQ7685YsovxpEq44G1IERrGbVHAcJjiwarh/+8NVYNACr2wb19TRdEGFPRDlLmV2/qurj0h0uZ7IMp0wEhAbY6sXHdaOWO/NZlt0BZIoYWtkJ9ihNWASQgqCBOMoFiVag6wNyeamX6rnw4NgAIZ0KhhP8ahHZo5Tw0UVFvD+HKErSlgUmJHJBpgwFKtHSs8ViTCYFyXGjdGuWRn+LUNHNbcSehCaV0QVy0pXczeYpU/inUvku1NanAZVQV7C8G/yAvBr+tWWrSqSgw==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x667dd12200a0c28ab5d704010fbf9c93efe8f431ba264112d8e505cc9ad494af", + "0xc7f3a3e75dfa75b48ddf293608c2f6fb6697cd51a2dbd4ba3e8d987c86f50426" + ], + "prestateLeaf": "qa3vm4/HuDuyj8khkZxhXKZvFhhxiGOW47bfybP4mndme0Aek0OdIq6kExKRWSbRN/ZarQ7685YsovxpEq44G1IERrGbVHAcJjiwarh/+8NVYNACr2wb19TRdEGFPRDlLmV2/qurj0h0uZ7IMp0wEhAbY6sXHdaOWO/NZlt0BZIoYWtkJ9ihNQ==", + "poststateLeaf": "YBJCCoIE4ygWJVqDrA3J5qZfqufDg2AAhnQqGE/xqEdmjlPDRRUW8P4coStKWBSYkckGmDAUq0dKzxWJMJgXJcaN0a5ZGf4tQ0c1txJ6EJpXRBXLSldzN5ilT+KdS+S7U1qcBlVBXsLwb/IC8Gv61ZatKpKDAQAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "GJNvpfWnfXEBn+maEIEAP1HR6sP0guRY4m902PH+sf4XrP1cUCcbxAgMQZKbhZXkvPf5q0J2Gn++UAwvVto3ORTlv0qGT366PYAkBZsw2BXFVC6CVCFqsm2iarYI1f2aoUM/wbQlzW7eBrhvPvxNLgt4rnhX2RS85mEqocaA2Ud6qBwPAlvkUsSGQjB0zlylLd3OO7IA3LeLzsdF3xldlgcrEd6WjKr2yZyNxFJnaDn0fTI=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xea78fd5eba89918cf126ce1268f142622b39d1e9c1fd9d60771e8db8468f9e83", + "0x15e000fd4ec88a4d5617d54fc6c4649ffc00c517559b2634b3eb0d9e877ddaf8" + ], + "prestateLeaf": "GJNvpfWnfXEBn+maEIEAP1HR6sP0guRY4m902PH+sf4XrP1cUCcbxAgMQZKbhZXkvPf5q0J2Gn++UAwvVto3ORTlv0qGT366PYAkBZsw2BXFVC6CVCFqsm2iarYI1f2aoUM/wbQlzW7eBrhvPvxNLgt4rnhX2RS85mEqocaA2Ud6qBwPAlvkUg==", + "poststateLeaf": "xIZCMHTOXKUt3c47sgDct4vOx0XfGV2WBysR3paMqvbJnI3EUmdoOfR9MgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "AKxthvJXDO1M+B5i5mYyidmHRAP7jB/1bRMCGz0GmTC0gMq9Dbq91Rdmf8ldoYZXMx9VrzrVCchNVeIaJVGIhMgs5UUwPjtKBjItuhSkctd9k1NYFQBgJc2mPMb7H+d/VmyoiegxKdi5Vh4VTr83N+EKyZDdwb8JKRB7D1wMM7r55No7k2fMANLFOT+VSPzg70WPpaY5HEd1uR5IQ9OnXNjdZBv7wKmk1q9AUIpqgrSK+r2V9d49qaPXyX+XzkNqsWLV3a6dxJ9QG1JqD25RLsUUS0i12TZh0jpdkeHP7FP4R7LPUEODXVroI5+bYNSlRVe7OwNrDk+htHkHKODS0+FBVfulr6qYqoAUBEa0XL/veJdMgjGDh+HTD0x46E7PtjzTwmBMS1H7Vh5ErVaQtDx7iLY9N7moJqI1heBDheMiEDil98Xhmqj3IUncZ1uJfWDqrESS8hwah6WJrP7elcBWaqVI4DFhy8KMtUkeXqd6iV7nycVjbtD02+T/uEFT0V9qzd4zWA+wrvGxitlsrIwcMw==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xb8cd587689045570423cd43026a2f2739adb54b24b56e7f85bd9fe851c454d26", + "0x7f1a5e9247f9c215ec0c2a34cd80e1931b96eed90dded0707e4c2772d6a2b2be", + "0xd40445f4d71545e4bed22b752ca2110e6c9bb3da8af4abfd31554332f2f2658e" + ], + "prestateLeaf": "0sU5P5VI/ODvRY+lpjkcR3W5HkhD06dc2N1kG/vAqaTWr0BQimqCtIr6vZX13j2po9fJf5fOQ2qxYtXdrp3En1AbUmoPblEuxRRLSLXZNmHSOl2R4c/sU/hHss9QQ4NdWugjn5tg1KVFV7s7A2sOT6G0eQco4NLT4UFV+6WvqpiqgBQERrRcvw==", + "poststateLeaf": "73iXTIIxg4fh0w9MeOhOz7Y808JgTEtR+1YeRK1WkLQ8e4i2PTe5qCaiNYXgQ4XjIhA4pffF4Zqo9yFJ3GdbiX1g6qxEkvIcGoeliaz+3pXAVmqlSOAxYcvCjLVJHl6neole58nFY27Q9Nvk/7hBU9Ffas3eM1gPsK7xsYrZbKyMHDMBAAAAgA==" + }, + { + "input": "d900eUWWrZtBabto65ygKjqnV/jGt+IfbH8GS+AxWdgUIpGGArTHTIUzmZhsMtssGWDMWdsugOjLbD1yhls8RJwRAF8soTs3rhSmphVFOn6KPIc4lyDpPBckmxItmGlk5uP9+JbcyPY4F5I05UAkmtnuoyYMvPyurSCsCPdhwALOXckHdEDSGjaRqY+rugGthFbFICxQXL89u27AhOO7uAtsfle430nfUawwhrr7Kvzfo6UYSQur5TkZGaZS29jvhfY+yR3H+c2U5k2oUfOOLK1QEBNT1WcQ6gywypQwRCQLbV5D73/OBatPjOiKx5KAHU3AdHzt8/0+Ej7G6p+fVeWnoasKALs1dX7I3MUuPPGqZRYrySJLPotrEyFj0ZrNZkzzPhO40Wy+J3mFj7INUvfQSfSFOWa6b+YRrxOJ4tI8fpnzciM1y/Rx64mYOCOQxnBP50Yn4is5RLseJYzSCKTl8yBqyHydCvEqOoBGqcJvtkQmNFTctVfNK4oAXIRxeAYkvRA69Q/xSnBFtKZY+Zid0BlrKeUuT3YJSU+agpGJC0Imiy8ufl6/k1m9B+oKng==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x7e80cac4eef5ab4b93c9e40f44770c65651613c8cca6839c872515ac2de12d82", + "0x2ec375aedfc478bef69a5f4d9d74359cdfe51ca01698b179212b5b7a538fbe12", + "0xd99eaaa52afb616a2959621233062e8c1ba07fea58f34d00beab630442df1c89", + "0xc24b6beb031f922de9b4c4a48ce28bd3b32982126d4104bfd0dabfaf48dfb56c" + ], + "prestateLeaf": "qmUWK8kiSz6LaxMhY9GazWZM8z4TuNFsvid5hY+yDVL30En0hTlmum/mEa8TieLSPH6Z83IjNcv0ceuJmDgjkMZwT+dGJ+IrOUS7HiWM0gik5fMgash8nQrxKjqARqnCb7ZEJjRU3LVXzSuKAFyEcXgGJL0QOvUP8UpwRbSmWPmYndAZaynlLg==", + "poststateLeaf": "T3YJSU+agpGJC0Imiy8ufl6/k1m9B+oKngEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "96g+NaYbWNY8fhK355lnCK0TarKbCBPF/3c0Kp/cF9H1/CncnguutxlZHcJbAiN0IeW10CXmDQSK7gnlIF57tv2fvdaviKJ19s9dlIHjVbWckLcm3kwkfaXZEffsPHFototrK+04ODDNiO+ONvKPANCsi10R11D2RlLJ6JavAVxFUliiLnfVgN8OPHkoG1o5z+LQcYtqoQI+iBCFXoqPq/2ielSTbHn2XbAi9rlZEFRKovLqGB5TOvjZTd0M1yMvEgd9BJjJJ/4=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x8e4daa5e0393a3e6afe66e2d9ccf0684a559f41c5d113d0adf9a27d46fc7c44b", + "0x557b27463478dbaeed224211344a3d1800a9aee66c3587ea633c214388014a2a" + ], + "prestateLeaf": "96g+NaYbWNY8fhK355lnCK0TarKbCBPF/3c0Kp/cF9H1/CncnguutxlZHcJbAiN0IeW10CXmDQSK7gnlIF57tv2fvdaviKJ19s9dlIHjVbWckLcm3kwkfaXZEffsPHFototrK+04ODDNiO+ONvKPANCsi10R11D2RlLJ6JavAVxFUliiLnfVgA==", + "poststateLeaf": "3w48eSgbWjnP4tBxi2qhAj6IEIVeio+r/aJ6VJNsefZdsCL2uVkQVEqi8uoYHlM6+NlN3QzXIy8SB30EmMkn/gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "naVpEVoOzteWfeK9u0WSh79jh1i+pl3BlBXzrAiSCnl+gO+IAGE4FszQN4aVfZGdBodkAQlLNsBmG7Or725IFhcHJ+E82JlLRg9kpMKHtTl5UHvqPZ/hVv2XCZfj9le0df5lz0e2Lsp0XGEReYz42q4fkjxWOLa3rFwkVQgaePf2tgwIwrPd48iweP0hwbOcgFfWVrn5g0Ui53uwKa8KCjmKeuGsSJKGR1TxTAb98mFs5SVzUPE7ajmErHfe1A4JVqSD98D/9IG/OnRYzPidCZytI8WhBwfA3235dO2Q9k11Pg42QO6wfbsdRF8dJ8jCc1zJNQ==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xa74f9004e2958c050a01134b23c268d4c10871ce1f5910d6f67a5224fdaaa077", + "0x925b929b966d69070e5b9dd4571730f52833440c82d21b032759d39c6b2a380d" + ], + "prestateLeaf": "naVpEVoOzteWfeK9u0WSh79jh1i+pl3BlBXzrAiSCnl+gO+IAGE4FszQN4aVfZGdBodkAQlLNsBmG7Or725IFhcHJ+E82JlLRg9kpMKHtTl5UHvqPZ/hVv2XCZfj9le0df5lz0e2Lsp0XGEReYz42q4fkjxWOLa3rFwkVQgaePf2tgwIwrPd4w==", + "poststateLeaf": "yLB4/SHBs5yAV9ZWufmDRSLne7AprwoKOYp64axIkoZHVPFMBv3yYWzlJXNQ8TtqOYSsd97UDglWpIP3wP/0gb86dFjM+J0JnK0jxaEHB8Dfbfl07ZD2TXU+DjZA7rB9ux1EXx0nyMJzXMk1AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "b9X5EOqu99dYeLiCgE7ihEmhbhQoo7AQHkRuQ6Js9yGGxvYQDGhVMuo+g2ay56ViV0lmEMsW/15x6o5RMVHeX7ScDfuu22aGhKPo5AGnKj44OaLeUogqLsNp7q40CMTBZH1bkXgHiOGvs+GU7ZAPEuWwKwvKXkbnMSAnD8ybu1eQiAdTGDXglqUI4e7qhDuapIBaVPuUYMnmBc3580o9f3mYP4NCQwcJGafH9B4ToPppHYdjcT6dcTYOp01eMoiKzTsE6nDEIa/atPusKgajDk82L53RuEQBMRmAPGisPISbEog8l8kN+gRfmv/RnRNGUcbUhRUWSKsAo1EtpZOhh4U1aBj1WUAQ/SfnPh9cBUqrqvR4DvJawwxheHuaKi2rzT1esbQhuxT+W+iUdo6pRXJGXiTAvEyippY366NaHUZDR9vN03iU/ryJYkKp3KYyOGZ3AZV0py20gwh8kQXfoc5gVpH24BOrv6MT", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x43937b0f787a47a32041578337614b4c322750e68a582e8f0ebb39a09551a876", + "0x934d1b6297160f8a3b5975d2be38e7789a593e4074f0f8c536aa3644dc0bfea3", + "0xc9b69ea06a2fce42e1ece4b565badc6ce0a7dc9937d13373c57e2bdd19c7b921" + ], + "prestateLeaf": "pQjh7uqEO5qkgFpU+5RgyeYFzfnzSj1/eZg/g0JDBwkZp8f0HhOg+mkdh2NxPp1xNg6nTV4yiIrNOwTqcMQhr9q0+6wqBqMOTzYvndG4RAExGYA8aKw8hJsSiDyXyQ36BF+a/9GdE0ZRxtSFFRZIqwCjUS2lk6GHhTVoGPVZQBD9J+c+H1wFSg==", + "poststateLeaf": "q6r0eA7yWsMMYXh7miotq809XrG0IbsU/lvolHaOqUVyRl4kwLxMoqaWN+ujWh1GQ0fbzdN4lP68iWJCqdymMjhmdwGVdKcttIMIfJEF36HOYFaR9uATq7+jEwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "wCn84Ysh1rI+gqpuVqxHuCSePXQZxFjuSX9VWfGVoSh0PUy0geNnEObkVqE2U48nLt92YPJSgmKFw/JQ7l0XS1teRVBmVWQ1oXtxxp38FDdEZUHui7GKI22m55tbLmDOA3TaX/UgjemQWS3vtEJPO1c4B0GZhepYJvYNIyi83Fjgn26tRFT43Bg4qY4X2vrpMt8kGtLeuoQDFZV2KH4hmEyWlkii3loaclTqwctZTO9Wor6543ynogCm71Sedw80lE13+wOPTbi/Q2Rj0xgGPeim8d+YQ+io8z0gEuL0wh3xBFugxMqe7PjHELq5sHzGkWaHKTmBBUrstI30eacUT67xwwyvWcMY8QoBRoql8IpwQY3i", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x77ed1b9215130e26e30bb32940f10803564d21eaf3c34813a88b3620f52925ff", + "0x6a3c76ccc0da597941e5336c78c7e74359d0172c76f4ed01eb4c17687758a873", + "0x9395db5326d485ca6b249b9d2cae2d71abb6b5a06c5bcf337d886bee66abf4df" + ], + "prestateLeaf": "GDipjhfa+uky3yQa0t66hAMVlXYofiGYTJaWSKLeWhpyVOrBy1lM71aivrnjfKeiAKbvVJ53DzSUTXf7A49NuL9DZGPTGAY96Kbx35hD6KjzPSAS4vTCHfEEW6DEyp7s+McQurmwfMaRZocpOYEFSuy0jfR5pxRPrvHDDK9ZwxjxCgFGiqXwig==", + "poststateLeaf": "cEGN4gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "6ig8b6H7sUxHcjRDPImXIbLVndahV896pfdMqOe391tOFBOOiZFn6Kzfm/qFrwab3NQvNNc2xcVI3XxA0qDKyRK2WnzkZ7XR1Hrz5Tctr7h5rUy1COhwV/76kNICQ5TktETPDI5EXt0j7II/C2zxDSJHvTU7/IGuhG5rSQ5H5b+Xnb9z2I4mpqy+Gye8KOihYFMl5atGDyGReKO3lUe6Au7wE1/n/YaMCbLcc/0E6pxsqOqkgiIKoKhlVHPPfMXwtg81a0fY0sYz5fmoxJmGExLmTRz61eGb2SYsvBtx", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x969ac4305a9133683ee676aaf8df9c9d0d6ff69d9f84f93ded06ae5ebb63af27", + "0x69408a441399bb046f0422718652ac8c2a61649041458ec5ed52f4f50bc2af5e" + ], + "prestateLeaf": "6ig8b6H7sUxHcjRDPImXIbLVndahV896pfdMqOe391tOFBOOiZFn6Kzfm/qFrwab3NQvNNc2xcVI3XxA0qDKyRK2WnzkZ7XR1Hrz5Tctr7h5rUy1COhwV/76kNICQ5TktETPDI5EXt0j7II/C2zxDSJHvTU7/IGuhG5rSQ5H5b+Xnb9z2I4mpg==", + "poststateLeaf": "rL4bJ7wo6KFgUyXlq0YPIZF4o7eVR7oC7vATX+f9howJstxz/QTqnGyo6qSCIgqgqGVUc898xfC2DzVrR9jSxjPl+ajEmYYTEuZNHPrV4ZvZJiy8G3EBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "s+gSK/z1Yq6vS7gHZ46TwA4nI4PEEfp3bFQ49VMpa8gBa8sVQJbUvo6yVTk6zuLfkj6tXqYtUyN8jQfH3E6dEy92OlrXqH5u44bYWljAawyOiEV87fUAe5Cun3moBFNpt++w+6l0r4WulyHSi+WIroNSXdSIas8wKBHb5JNwi+6x/4Zg9aZQ0A0ZweBLp3+LHX3SpYSvEzni8xxsSC+rhAl4CQhlMUIrZ1wMorsdgCOthcbNXrKtfpa875ZY0cacjXutXimuzbudNOes+6f2y+8=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x66145485300432cafb0f5c1387c5cf90e275dcd905c24348107bedc231ba690f", + "0x7388d16dff1dedd7e404403daaeed4df3a9bdb3baa81c586662624f13dfa56bb" + ], + "prestateLeaf": "s+gSK/z1Yq6vS7gHZ46TwA4nI4PEEfp3bFQ49VMpa8gBa8sVQJbUvo6yVTk6zuLfkj6tXqYtUyN8jQfH3E6dEy92OlrXqH5u44bYWljAawyOiEV87fUAe5Cun3moBFNpt++w+6l0r4WulyHSi+WIroNSXdSIas8wKBHb5JNwi+6x/4Zg9aZQ0A==", + "poststateLeaf": "DRnB4Eunf4sdfdKlhK8TOeLzHGxIL6uECXgJCGUxQitnXAyiux2AI62Fxs1esq1+lrzvlljRxpyNe61eKa7Nu50056z7p/bL7wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "mM4wTpKyOkZgpKod6R3xAcVeU0tiiklnVLM+vGmInIc0MnLiDjuNBTlIhm+6zZW5xYgVk5aOWWXb1MQjFcDEKfZLkn9SUVFjy01ISZlM9dppiUMFjSDjnzbEgKPE3lBuOJ+wfy/S+T7NNOxGboy+4HJbasw9CeK0orJTGpa8CAD97ZF8tVmhLvLQHfPQB8Be8ighEFl9lh5wFLbIzaiBHQdYSKSZRJUL3Rl/T1Bt7KLCLevgfszkxs/JWxA5woclF3ugsFZOg76RCeUVp0c=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x32f7beadef18e590ffe82aa5e8d36005de9bcb0e7e78a0c68381eacc4947e9bc", + "0x75f2eebd6c67f78c7a6804b8c4d7637d12be4f35f505b4359e89e7bec6e52ec4" + ], + "prestateLeaf": "mM4wTpKyOkZgpKod6R3xAcVeU0tiiklnVLM+vGmInIc0MnLiDjuNBTlIhm+6zZW5xYgVk5aOWWXb1MQjFcDEKfZLkn9SUVFjy01ISZlM9dppiUMFjSDjnzbEgKPE3lBuOJ+wfy/S+T7NNOxGboy+4HJbasw9CeK0orJTGpa8CAD97ZF8tVmhLg==", + "poststateLeaf": "8tAd89AHwF7yKCEQWX2WHnAUtsjNqIEdB1hIpJlElQvdGX9PUG3sosIt6+B+zOTGz8lbEDnChyUXe6CwVk6DvpEJ5RWnRwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "fXxLDLxHCvA4pJ5lr6+oXvZGW1UrxF0hDPn3pSkL7R7PHWCoW3AZ0N0t7kqIniKqjULZZ/ARy5fj4sXQhRWwJFRVSFs+hYmW3OXAUrrX2OIUAsPjj1q/Ooak5BzMFZ0INZgH5Nc2dGJTdnkatSf5yB3OWpTbx8zEhemmEBbQZIn2RpOC1S7kw9+bSl+hhT40Pn0H6bzrowytyMJZonr4d9Z7pPw/cEG0oxP0bflw380hAtB7aW3LX8qf/OpYRr4Ihwfj2eu0+ZkRLzHhZ2tqfqw1q7fVbryfpFij2edKyzKlzV1DLAplTUGNVdrV1NyVgWvny0MUAiSJJWPeRZXKqehiP4+myA1nDKuXYYgWlJLmPCJSoWjGEkDxltZGByDaLNkFC+eW25XQ2OMbdfzC2N3u60c7/cr2CPbiHzAhVZg/Wl8s5cDJMwTA8b38W3yks3QJGDCtgahuK5jUlWPRn88Ew3rz3NQ2l2fC4X3ZCteKYQFUDDX8IE/WeVeAmcH6yvoOEUM=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xa363a494c41749fa34acbfe0db3a4123732d2ee07bb972035424a4fbb757a992", + "0xb4ba5242df70b066f1fdea7bd089ed021a3ddbf6a8cd7a755aec642983c7946c", + "0xe1582c446cf455e06911c8bc76c3201fd3fd37c14241919f6aaab0e50d0393b1" + ], + "prestateLeaf": "35tKX6GFPjQ+fQfpvOujDK3Iwlmievh31nuk/D9wQbSjE/Rt+XDfzSEC0Htpbctfyp/86lhGvgiHB+PZ67T5mREvMeFna2p+rDWrt9VuvJ+kWKPZ50rLMqXNXUMsCmVNQY1V2tXU3JWBa+fLQxQCJIklY95Flcqp6GI/j6bIDWcMq5dhiBaUkg==", + "poststateLeaf": "5jwiUqFoxhJA8ZbWRgcg2izZBQvnltuV0NjjG3X8wtjd7utHO/3K9gj24h8wIVWYP1pfLOXAyTMEwPG9/Ft8pLN0CRgwrYGobiuY1JVj0Z/PBMN689zUNpdnwuF92QrXimEBVAw1/CBP1nlXgJnB+sr6DhFDAQAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "BC+MRlxbvGUWnKSyfDm/ivblXLU9B8lijzAPSyuyDdTkYBZ/FSK4+2SMFmtm8KTghrh5OEvpwDz+NYX+y9wcxWFGBxy4zmC5QAmAZO78bJ0wSMdodhKgjE7JcPsUPgMuMGpvAa3TOQ==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x6b0b2b4094f608f73c61f68be51329aff2fb0a5179de2b9b9467bfe9c3cdbe83" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "BC+MRlxbvGUWnKSyfDm/ivblXLU9B8lijzAPSyuyDdTkYBZ/FSK4+2SMFmtm8KTghrh5OEvpwDz+NYX+y9wcxWFGBxy4zmC5QAmAZO78bJ0wSMdodhKgjE7JcPsUPgMuMGpvAa3TOQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "3L2fS5vNMdKj6LqS47x4oHrNhIIxLe9WYJ8inef4jgT/WXKUwlXH3SH1x9WDtYYD2A==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x202223f2c589349b4674f6a6e32bf2ade3d3134b59a5c7c663117ecc87fa1455" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "3L2fS5vNMdKj6LqS47x4oHrNhIIxLe9WYJ8inef4jgT/WXKUwlXH3SH1x9WDtYYD2AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "+1FoFm7ydb3xXIdbfSHG7FduytLO9fpgdX43FT+x7FtCbosJEV75Q81gxdLJ8JMMS3/Cxyk0dnEE7f/kI8tiaCdpoFMbXVSPETE+VhpYh3tqUsPx3XvxPp3UnsTT6QwXSWshkw==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x6c7492b6bf953a71885ecd61168a95fc2e6d73ee46df0bf5ef3a366a34c364d3" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "+1FoFm7ydb3xXIdbfSHG7FduytLO9fpgdX43FT+x7FtCbosJEV75Q81gxdLJ8JMMS3/Cxyk0dnEE7f/kI8tiaCdpoFMbXVSPETE+VhpYh3tqUsPx3XvxPp3UnsTT6QwXSWshkwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "3NaoqHhyoYC9jYZUqLHxpGgV4QbDipeCZ8KMnYabEON2SusALPKdC6RsHpTor+9WiZGPVCzoIVL7uDeHQJqY1VQEYtpFjOhrrFzKQbTdgk1cVDGBR0lq6ePoElwQk8dbnXLuKtFoxm1dwXWXP1GTPup292cFh1z48m/uVunD53XXUmegojcj/z0XyOdUaPMQ/bK69bFNcwtoD3ZlfGukiNllk7jy59i3dK2KhabV2AaQjGJV6GZZmUku3reZ7E8nw536tqEUb0FcOCtXTjCyhFT5KyBzuDUR4w5MbNWj04L5TnRgZheADM3xb1XdBUrHYJNNCpDUKCUnYrHZrc4KEgCi+q/KppcvbvcBOAE8hoceshGtczZDXEdeycCZ", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x01cbae12168f2f42f20bc0e26d21447f6e272d77ebea52b645f594b57fb2b6f7", + "0x0392329f9ca01abab9d2b1cade00e7f99d0fcae8cee9f22c77b7adf1b4681432", + "0x16938f33e76b533c425af0f345683dbc3f3d06abcef46ed196da3012aba4ff7e" + ], + "prestateLeaf": "PRfI51Ro8xD9srr1sU1zC2gPdmV8a6SI2WWTuPLn2Ld0rYqFptXYBpCMYlXoZlmZSS7et5nsTyfDnfq2oRRvQVw4K1dOMLKEVPkrIHO4NRHjDkxs1aPTgvlOdGBmF4AMzfFvVd0FSsdgk00KkNQoJSdisdmtzgoSAKL6r8qmly9u9wE4ATyGhw==", + "poststateLeaf": "HrIRrXM2Q1xHXsnAmQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "bos9QTnn1rzgaPL0vtnPW9Jr1bj31IF1UGb7alBiDWiyNMWfXo+vlXuCdCKkVIn1kpB0ETLS05ZThUpi0rwMB85JRI9jYIiaZtqHECqmODDmi8HgMxNH8Tf3M9WEc2E4sN47vB6LJa7sZOgIfviCHla7LIUI6PCFNXMz6yg/eUNtQbA11qplkdP1LmRTOrw3Ry309S9eWmqkaVfDjzG94kpvM5yHl73JMdXVp/v0vCxFuuIM2EIVnaHbGbK2ggqwaHFIHXdSN2VQ/2O5TbG7gxEdxy/LWjV8RuttAbF1SAxEE5bXGiz6p1bkpLwcIzMTcdLSMjwwBgd2/1auF8Vm3NnAO+Rqnw==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x91d6e1afd0a075888cc2d5b5e693bdda3803325e39fbd6336ce9bc005c2d96e8", + "0x948020ab27061f5f45c46affe3be5203860745491d71540e2b860330c0dd57ec" + ], + "prestateLeaf": "bos9QTnn1rzgaPL0vtnPW9Jr1bj31IF1UGb7alBiDWiyNMWfXo+vlXuCdCKkVIn1kpB0ETLS05ZThUpi0rwMB85JRI9jYIiaZtqHECqmODDmi8HgMxNH8Tf3M9WEc2E4sN47vB6LJa7sZOgIfviCHla7LIUI6PCFNXMz6yg/eUNtQbA11qplkQ==", + "poststateLeaf": "0/UuZFM6vDdHLfT1L15aaqRpV8OPMb3iSm8znIeXvckx1dWn+/S8LEW64gzYQhWdodsZsraCCrBocUgdd1I3ZVD/Y7lNsbuDER3HL8taNXxG620BsXVIDEQTltcaLPqnVuSkvBwjMxNx0tIyPDAGB3b/Vq4XxWbc2cA75GqfAQAAAAAAAAAAgA==" + }, + { + "input": "6SaxxD+YGI1vnZPnjyTUukGwlnv+6mi+kr0tPJNb+byqdsnp3EmNiZotRPcjKv0mSrN2QlaSgVvtpd1QeM61kh/HHzPqeyY+yl5q8oNTlh75uxskT6MdhHH0348dNg+jR2PkDEXArgnB+l036KgkH42p7RC8eX9fSvXEWnA/9y/khnGRJcfxPqXhFOSlGtFPbI/b4Ia1wmPRwUN80iNxypnlEWgyfClqvaftdOiWDlKOnzzBR3G0ZB1j7/AzKS0Z70K2nVOKtO7oYjMb17Puu3zVIpka2uh6iwLwa58wZlX4Wt2BG+r98k263zW90XyrYt00m6E8diC3B+t/7j0rt9gV6rlBbY6F/c8cIRENxBqWXcc3iemFBr/LYLI=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xec846a6c4315bc6e764fb641a2afe9f15d5eb1861714c76af033da30c15b04b2", + "0x6fb5d7ce201d34f801ad591867e189294147d20f911077e1952d0b071bd3fa31", + "0x0128bf2377b1952f0146ff7ae00ece8c7d6688cbc6c7cf2418a43bedc1fe5b38" + ], + "prestateLeaf": "peEU5KUa0U9sj9vghrXCY9HBQ3zSI3HKmeURaDJ8KWq9p+106JYOUo6fPMFHcbRkHWPv8DMpLRnvQradU4q07uhiMxvXs+67fNUimRra6HqLAvBrnzBmVfha3YEb6v3yTbrfNb3RfKti3TSboTx2ILcH63/uPSu32BXquUFtjoX9zxwhEQ3EGg==", + "poststateLeaf": "ll3HN4nphQa/y2CyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "7HvyePr04PVkmE4UxQQoYO5qwGyrIYsGY0wmtlMaQ7p6ahwsCXxYL+1Rc7a9lz/oRaRmmhHt5DW6RFtBukhXe2ISy1ftItb82fmikh+Byu1fvJlVfkLfl5dzhoeXv8UHEroxoDNZnhOnt9/saECxkKX9Hp3y9wERFy3uXJzu68I+6tLcK7yRb6ZPAFlJgc8NFfYwu0SaXbV6HUPt50c0EqXs2B4vrxNdiJ5JPDm8a/bw6TB03dEZ7En2cbAYpTyrFjOTws2NdjWqkW1WH+RrSCSNiNSsbEEC6RIEfEss45JL28Ny9YjAnjwl31jpIkH1eY7SO5zuvKsxloZ8NeBTJeaiPu6MfO9WjO1HMi9usfe5IbjNT/Gsc+mcBFszP/6NHcyQYhR4qPNfOf5xp9wNjVYGOTSu5iQUPDfDgEEbTA6BiWIGnLIVT3xkWRcUGVoKM4cct7RHAie38r4/RMhQzfyEQ+Hjz1bZi/+DrXfUFyS6Cvn8G1eHcPXRUHZ+dLy2GzICgTLkTPbbTk8SgvepgdFIJPwGJgkSCYEvpWStEon41UiOP4ojQX4OFGwFrZ/wCdCGAKMB0Wa24Mww9n3ulrdRa95weEg=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xa26cbc2a66287c2836fa49ff8aa3f3aa1e0e5287d772f3b68304ae8b9b204a35", + "0x0cec7fa9e32761ef269f706014f5ca47b83388f58abf405cb3d4b58616b561a0", + "0x34751c222f5447e5ce41d6f871bf218a1e7e270ddf360d0a200f1bf523d36e5f", + "0xa6cada596a1452764f92fc089941d8205a08c8ce544d084eef7f65ce9c208b3e" + ], + "prestateLeaf": "uSG4zU/xrHPpnARbMz/+jR3MkGIUeKjzXzn+cafcDY1WBjk0ruYkFDw3w4BBG0wOgYliBpyyFU98ZFkXFBlaCjOHHLe0RwInt/K+P0TIUM38hEPh489W2Yv/g6131Bckugr5/BtXh3D10VB2fnS8thsyAoEy5Ez2205PEoL3qYHRSCT8BiYJEg==", + "poststateLeaf": "CYEvpWStEon41UiOP4ojQX4OFGwFrZ/wCdCGAKMB0Wa24Mww9n3ulrdRa95weEgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "ul0dLBs/YmNE/uyOROGboezkmoislGftlZIN22FEHY+3nJzijZvf5hUnIeUjR34oGMXa8SIfAmPVhcM5MT3XIR6ZsZSs1Xg2Q4gsIz+lIdlke9uLi01KCa5+2ut8Um+3u9co+h9X/vM4Iwwmz43xaOVUlb6zn+4rBq3gAbFrxq3OrpYJJpfnxMnXp5qdYqQjH1vUYdYlrQKYYZKQHw8TVKHZZ2z/EV0XyqrUTzO6TRFRGNxcYtV8/OX5ErC3PF0FCoOat2iX3wgsptUNB3DhK9LuFu9G6/RJDOhfw/Ehps79yLjFYAwSyKi+OL874MkGgUsTiUTElF/EFAAfuB53aJHYPdEQi2Z6Zw74Ezzvh3oKQtp/Q/dShwyJ1/uZj2xdnfqwTWdI66ZcNNVT+PWTtLANTpFiJtgiy7f4f7xqWh0tcDqDFxwbQrzrdh+U3Mm7EZjQjACGLkCB1VNUn14JFuDnxfOnpqRQgdrzdFWmzsX/JFl4i8uCN4aYNCe1f38wMVb2d+1DqIzL20fIuMc7CjX/u+hojwRQZSTwDCLo9xMjB5sEFYu/NI8QyUNvx18pXkkLWIvvL8BYFkhB/lpzc9NMY6HCM5kV3Odk0u8FIHRm9B+Slj3gf//H5DbbU30pu3tJ9FAv9HkDs1U=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x258c3147665aaf5c5fc7c739f6c01e58759a0516ea1e3d084a03275ae29732a6", + "0x2879dc29eb40af28eb88ed17c047548bedbf6dcab331ba8b6c050fe6803892a1", + "0x85ad14cf814e5cf867611f6222ceb3f2c82dba3f6b1af34ecd236a1d8d9959ef", + "0x60e4344aa77bf92735092f446229eb16a0e91ccf7351c9a9e8b207632861a936" + ], + "prestateLeaf": "CkLaf0P3UocMidf7mY9sXZ36sE1nSOumXDTVU/j1k7SwDU6RYibYIsu3+H+8alodLXA6gxccG0K863YflNzJuxGY0IwAhi5AgdVTVJ9eCRbg58Xzp6akUIHa83RVps7F/yRZeIvLgjeGmDQntX9/MDFW9nftQ6iMy9tHyLjHOwo1/7voaI8EUA==", + "poststateLeaf": "ZSTwDCLo9xMjB5sEFYu/NI8QyUNvx18pXkkLWIvvL8BYFkhB/lpzc9NMY6HCM5kV3Odk0u8FIHRm9B+Slj3gf//H5DbbU30pu3tJ9FAv9HkDs1UBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "5AOpWwV0q9zthtbxpvpnf/utrQl1riNtoHTJPRm2uWgO6XaJlJQNKMXa", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x5f19fac317da21422bb1f587b1dff8f3df060092fdbfdd227271e3bb3fc182fb" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "5AOpWwV0q9zthtbxpvpnf/utrQl1riNtoHTJPRm2uWgO6XaJlJQNKMXaAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "svQ4eiNJWQvSsDd6UeZ9Vtc4B7u8MwMnxWdNmlP6LtqRbUIflXt3qcub8ceF9a37f10jXztRn/ey1pexOjfxxtCbyXKLjNGVLw0VdpgBK6D0cnPJsLuJEqZz7dgObU2Q4lY9rATN9ENjIu+QRW5s6kNiaaZwO7FC4xp6u9s0fnQBb9J46ORA5vBIclmqArka0tHUlGCVh4wm888oSMyKCpfGbyjRJotodRi+2JC6UVcAemTUqmO9ckw6pGZzupdgpD6HCsAHhATZIufyS4Uu+gzEzbCJjUz4aS0DvxItfw3LrNJnwv2pwqvstnxcx4N1loLN6N10yZ2qftCdhiv/Ci/DMf3wqn8ZhNOt9fXwMWF0EmhJznNMG+Hyej8g4/nuTMzwx/WcwATTsx0JJicXPDXphVOIYEw9lJlWnQ==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0x52311ccdc69e2b3309a674bf5475cd132d2c32ed815028115cafd0f497ea6eb8", + "0x5108714c345510560c7e8ad860626f648555dde85c5ff3c1bb9dac1b4b440481", + "0x09c7f822bffa5ef1ac75cad13f6b2741bbe5e5ce34a347d16bf7e1b48b8c7687" + ], + "prestateLeaf": "8EhyWaoCuRrS0dSUYJWHjCbzzyhIzIoKl8ZvKNEmi2h1GL7YkLpRVwB6ZNSqY71yTDqkZnO6l2CkPocKwAeEBNki5/JLhS76DMTNsImNTPhpLQO/Ei1/Dcus0mfC/anCq+y2fFzHg3WWgs3o3XTJnap+0J2GK/8KL8Mx/fCqfxmE06319fAxYQ==", + "poststateLeaf": "dBJoSc5zTBvh8no/IOP57kzM8Mf1nMAE07MdCSYnFzw16YVTiGBMPZSZVp0BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "XTleBrkuE5hWTQJFJRFhD12lyVTeV9AXaG/EaSuKhyAjK1EWJGArTmr/+vXyPgm7Wnc3TVRD32GpQIl3o/6bg9nHQ119M2lXyw6mAyypwl5IhmzIns1D3nhgrZJ+9Nz68SRWJ84oLv0Mm33ZHLAoCYmpGqFL4IIWPg96Ds5UHzF8bbEF2SAiYV3LLmGs1sblREH8+yYCCRSwgW9m65lYsDDvM7+QqauLXaOxWEQJcW8zA9G+U402rkB4q26uXxUkUcEsXGWW6d6qyE2uG8C54BWb2eYaaYVC+rWFdIUwJaXJvD7jJhFIj36NsjxZdX2Wckt6j3s2EmNiQwQNJgPqyHd/1cLANrekOoGKWOVm7P/LNpDEoxHntBvh7MVnEorJ", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xc34e8c6768cdd7c7cce28f8547e33f113191da57e3691db60e1ee55800fe96b0", + "0x0ac6cedb22f964162bf1a543d006b8d232af6a3f44076cbe30772f9f28c27a95", + "0x0809ac2786ade5f79fa427a0377b89ec99ac109ff230ec81bb4d609bcf7fd954" + ], + "prestateLeaf": "XcsuYazWxuVEQfz7JgIJFLCBb2brmViwMO8zv5Cpq4tdo7FYRAlxbzMD0b5TjTauQHirbq5fFSRRwSxcZZbp3qrITa4bwLngFZvZ5hpphUL6tYV0hTAlpcm8PuMmEUiPfo2yPFl1fZZyS3qPezYSY2JDBA0mA+rId3/VwsA2t6Q6gYpY5Wbs/w==", + "poststateLeaf": "yzaQxKMR57Qb4ezFZxKKyQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "eCmovNYrO+YV73aWboXDY/ToIZIp6UfGwIarwJunhPk8EVjTQb3x5K8BPPMG5KRLbTh12+Pu31HC2xXyg7F+SmHbXmt+Uog9FXvnrI9emRAk", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xd517103b16c5e12cca833ae2cc160e3d11c59c20aa380cfa5284aa10bdf4709a" + ], + "prestateLeaf": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "poststateLeaf": "eCmovNYrO+YV73aWboXDY/ToIZIp6UfGwIarwJunhPk8EVjTQb3x5K8BPPMG5KRLbTh12+Pu31HC2xXyg7F+SmHbXmt+Uog9FXvnrI9emRAkAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "uY3e1GKA8n27JPlxrOmwzav0R8hB2C1oQbUTsZVf17ImDpTqC2e0aeBUOvA+xfyOEUiVoAhF8zd2EfZdt1PG9U+3kOYhLyNKzmjvzosHvIHRw6W8NXqrd0RsmW4i1OLAzJyxbwHvH5G55VVdE1WTmWh/uWC/ww1JDMuUd9n+QddNQng8Q9lxAzhZ8PQMefc9a7fe/XBinzIBtnd2A6kkGa0zd7uoEbElMcrwqBEkDhteq1ykSOE/WDk4xcazJZqt4eMIj6asb5YTLr5EZQXtS1StsS6KiMZmiowo6rBtHCkpwGHN5Vx3whCG1BPw1l3ZRsYq09YM++DF7krB/rf/VxZGvS1T1UUX5v64dSj9PfR2Hm46qnB3eiA+5vwYAA0m7n+Rb6tSKVgpG/FnMXR29PH86EDxNWSzVIa9yFFhRReIW/BHlV7saXrb3A6Ff8UxQxcpcgMMdYDttUeQ7g==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xcdd63146e8f5f65947495f8051b4696f73b6dcf5965519736f223e4cafb50b4e", + "0x7633254742d3f1fb964adde4a6b281aacbe57b38ccfd3032a0fb8d8ccf1352ed", + "0x8a08eb0d9beec9bd41f5244566b9d8c524e89a9b22dc0f33504fbbe3dd5eed20" + ], + "prestateLeaf": "OFnw9Ax59z1rt979cGKfMgG2d3YDqSQZrTN3u6gRsSUxyvCoESQOG16rXKRI4T9YOTjFxrMlmq3h4wiPpqxvlhMuvkRlBe1LVK2xLoqIxmaKjCjqsG0cKSnAYc3lXHfCEIbUE/DWXdlGxirT1gz74MXuSsH+t/9XFka9LVPVRRfm/rh1KP099A==", + "poststateLeaf": "dh5uOqpwd3ogPub8GAANJu5/kW+rUilYKRvxZzF0dvTx/OhA8TVks1SGvchRYUUXiFvwR5Ve7Gl629wOhX/FMUMXKXIDDHWA7bVHkO4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "l55l8M4SnsMkcXMGROaphUDY4YUoIyj1d4c/9n3Oym78zfdrkHlgmId6gEeOwUsh0VJ3ja8OH42qiHP10gmKlkXLaWdmJBXQTrT/ygJt7FLJzpqmsSC082JcGT8EHbktfLmRtyKa7mNZjgVsZvxEOcR/fCnF23QnW3qB9gy7Z9odXlqrOka01yBXgPIvcWutRK1M6pq/BRZ9WrXg6uatCZcgE7VhSvAqVq7IWWoA9bKzPlDcWqrwKmIgmGY6gA8J83LbX9Pw4lyvj7AO9rJg4hvuRbbWDeMva2DjzBZsw/66T+CQ5htuevS35DWEVBsEcnPjBdEtWS5dqOiNl72levHJIbfM3RQ/pmhhPd87CmEX9AUeRZ1RFmHB6k7I+ZPZF5IO0+y9Vug67oXUSBmo1onZLKRdbiEuClHf9mbh4Ms=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xf9df249199350922bdb3d0d66ad8348746df540c87f092b006ae68637b8af765", + "0x5d6cbc50af5573059040f81bb9855d2685660e5caa57b88126a9ef7beccb8e26", + "0x40d0dc4e0214f314b8114d49e6b3ba842433c341390d7a63ad9be12ad76697ce" + ], + "prestateLeaf": "IFeA8i9xa61ErUzqmr8FFn1ateDq5q0JlyATtWFK8CpWrshZagD1srM+UNxaqvAqYiCYZjqADwnzcttf0/DiXK+PsA72smDiG+5FttYN4y9rYOPMFmzD/rpP4JDmG2569LfkNYRUGwRyc+MF0S1ZLl2o6I2XvaV68ckht8zdFD+maGE93zsKYQ==", + "poststateLeaf": "F/QFHkWdURZhwepOyPmT2ReSDtPsvVboOu6F1EgZqNaJ2SykXW4hLgpR3/Zm4eDLAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "pisVHfcf8JErfu8ZBb1hDtca67kfmzBHQU4ls3/oeZ7EN0mGnmHN/wUvrHqNyS+32HnH5duO/MiyN5kGH1IqY8IVLEjXF84WfbZsupoXyuDvvkYjPEwVlVAer0vCRkugw9Z8X2DctMcRq9Tc3xLTEPel2+jLCceyzbJvvUNjFqh4CWT1zqpqQCgRYfzo1+hDV554ifwMhbrWCrAam+CvGzmvNZ8+AJ6VIdbTPiSCOywS+/UIzz0=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xcd4659f1f12afa5949b88198029fc204f63a18d6d4b00c4f8c216019cda7653c", + "0x55b83209b05d78020837a302f30f74151e1c871be2ae0f43d6e3d239a05a6416" + ], + "prestateLeaf": "pisVHfcf8JErfu8ZBb1hDtca67kfmzBHQU4ls3/oeZ7EN0mGnmHN/wUvrHqNyS+32HnH5duO/MiyN5kGH1IqY8IVLEjXF84WfbZsupoXyuDvvkYjPEwVlVAer0vCRkugw9Z8X2DctMcRq9Tc3xLTEPel2+jLCceyzbJvvUNjFqh4CWT1zqpqQA==", + "poststateLeaf": "KBFh/OjX6ENXnniJ/AyFutYKsBqb4K8bOa81nz4AnpUh1tM+JII7LBL79QjPPQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "O8NUg0KaDo18ybTKajXM/sgqEYS37+lewPhGV/2sMAX6bu6pD+hu97cVqUkoazqhtXPFvnwPFy/jQjR+LFOXFZvvjCRgFRQvzzKOb8DJ0fqCRLgr9kiHN9LpqHXVhyHhhlRkem0+AIzvEmyqbgj5pbDQsr0gtBBZYN/IwUYeggMVEhM/rDKEiLf1Z5E/xs1a5ukkKJwXBVAioEmG81qwOBn9FqHWIrclhCUpqZRfRIZPp8ZXl64RTSIXhGibMujQipVQuXUsAOd4QE4HjirdI9SfzsLMesYimfC/eedEkhjL0z9+sjhgp5wJY84LBiNI6ZwrzNGke/zdySctbfKbgj2q6ECX3jy6lbeiNThEdLfO1t+IHM7rijOlNw/r8Up3YgH5ExUuuAOUJ5B8OuPXyMfnl484FISrdt0XGpNJpS66b1XHmf7p3TmFLlnO7/23uN57KiNdpe0RaB8R+Y5IzmcWrzR67wcbjbBTbjbAD6w1QIWVx6iUVSfciQIgw7WdYK1C6PXxUMEflpAnV0POZSMu++sbYrxJhlGArYgVbSH4i93eENLOJytOfnKXYzirqsHyCjHa55FqYBqC4ogkXXHBIzE90x9n2bNpc2IHYXIUfDcrkZSQFBnyze2uRsYx8dBXi+Pd2pLSFc3l0WnUCRXc4LCMFKEKWy/6fPHAUTy569sNCQd1E19Fx96UAQOsLRAtiHKp9XwCQYFhnPY2j61MYnsnV1Eh+cBc4J8ofY4mK4r7OBY9ze9+qrP95CCxyDJUIHDzDySR05MlXTJwwmA1a2X4r45shLLgZEF6EWsLwSvibme0tjvzczsfIwNGAmvg2gx4Uajr6kBelBRAobURalVBBx0SLghEjf1pXftmDkmRJipoV7tUVNK4tYEm5VVAZ95AA98=", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xbedfbe751c8d3913a76bb030bdcad312ce8c70aeabfaefcf491dafe740946ca5", + "0x74393cbd5f8764be54385a8c7f9442358ae2580f33aebc2597ffa42949172a34", + "0xc881ce64585de627f538376cae9513ca5f4efaa2ab255ce3fa5b15e890223982", + "0xa6ad654807a4f8de3b78d7fa389dc3bd31bbbb5bef24e8e8174f75c6f9ac5c6d", + "0xf6785ff09114b843cccff1e119100ca5ec235725ef2763573e1f3063bf48b886", + "0x20642552f0e7ef28ff28252b3839f0fa323f46792bd103baa9778684f737cda3" + ], + "prestateLeaf": "rUxieydXUSH5wFzgnyh9jiYrivs4Fj3N736qs/3kILHIMlQgcPMPJJHTkyVdMnDCYDVrZfivjmyEsuBkQXoRawvBK+JuZ7S2O/NzOx8jA0YCa+DaDHhRqOvqQF6UFEChtRFqVUEHHRIuCESN/Wld+2YOSZEmKmhXu1RU0ri1gSblVUBn3kAD3w==", + "poststateLeaf": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA==" + }, + { + "input": "O8NUg0KaDo18ybTKajXM/sgqEYS37+lewPhGV/2sMAX6bu6pD+hu97cVqUkoazqhtXPFvnwPFy/jQjR+LFOXFZvvjCRgFRQvzzKOb8DJ0fqCRLgr9kiHN9LpqHXVhyHhhlRkem0+AIzvEmyqbgj5pbDQsr0gtBBZYN/IwUYeggMVEhM/rDKEiLf1Z5E/xs1a5ukkKJwXBVAioEmG81qwOBn9FqHWIrclhCUpqZRfRIZPp8ZXl64RTSIXhGibMujQipVQuXUsAOd4QE4HjirdI9SfzsLMesYimfC/eedEkhjL0z9+sjhgp5wJY84LBiNI6ZwrzNGke/zdySctbfKbgj2q6ECX3jy6lbeiNThEdLfO1t+IHM7rijOlNw/r8Up3YgH5ExUuuAOUJ5B8OuPXyMfnl484FISrdt0XGpNJpS66b1XHmf7p3TmFLlnO7/23uN57KiNdpe0RaB8R+Y5IzmcWrzR67wcbjbBTbjbAD6w1QIWVx6iUVSfciQIgw7WdYK1C6PXxUMEflpAnV0POZSMu++sbYrxJhlGArYgVbSH4i93eENLOJytOfnKXYzirqsHyCjHa55FqYBqC4ogkXXHBIzE90x9n2bNpc2IHYXIUfDcrkZSQFBnyze2uRsYx8dBXi+Pd2pLSFc3l0WnUCRXc4LCMFKEKWy/6fPHAUTy569sNCQd1E19Fx96UAQOsLRAtiHKp9XwCQYFhnPY2j61MYnsnV1Eh+cBc4J8ofY4mK4r7OBY9ze9+qrP95CCxyDJUIHDzDySR05MlXTJwwmA1a2X4r45shLLgZEF6EWsLwSvibme0tjvzczsfIwNGAmvg2gx4Uajr6kBelBRAobURalVBBx0SLghEjf1pXftmDkmRJipoV7tUVNK4tYEm5VVAZ95AAw==", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xbedfbe751c8d3913a76bb030bdcad312ce8c70aeabfaefcf491dafe740946ca5", + "0x74393cbd5f8764be54385a8c7f9442358ae2580f33aebc2597ffa42949172a34", + "0xc881ce64585de627f538376cae9513ca5f4efaa2ab255ce3fa5b15e890223982", + "0xa6ad654807a4f8de3b78d7fa389dc3bd31bbbb5bef24e8e8174f75c6f9ac5c6d", + "0x71ca4f0903770f2035f3650a40ac8b23d00aaffd7b155a8be5bd02ff1c944181" + ], + "prestateLeaf": "hlGArYgVbSH4i93eENLOJytOfnKXYzirqsHyCjHa55FqYBqC4ogkXXHBIzE90x9n2bNpc2IHYXIUfDcrkZSQFBnyze2uRsYx8dBXi+Pd2pLSFc3l0WnUCRXc4LCMFKEKWy/6fPHAUTy569sNCQd1E19Fx96UAQOsLRAtiHKp9XwCQYFhnPY2jw==", + "poststateLeaf": "rUxieydXUSH5wFzgnyh9jiYrivs4Fj3N736qs/3kILHIMlQgcPMPJJHTkyVdMnDCYDVrZfivjmyEsuBkQXoRawvBK+JuZ7S2O/NzOx8jA0YCa+DaDHhRqOvqQF6UFEChtRFqVUEHHRIuCESN/Wld+2YOSZEmKmhXu1RU0ri1gSblVUBn3kADgQ==" + }, + { + "input": "O8NUg0KaDo18ybTKajXM/sgqEYS37+lewPhGV/2sMAX6bu6pD+hu97cVqUkoazqhtXPFvnwPFy/jQjR+LFOXFZvvjCRgFRQvzzKOb8DJ0fqCRLgr9kiHN9LpqHXVhyHhhlRkem0+AIzvEmyqbgj5pbDQsr0gtBBZYN/IwUYeggMVEhM/rDKEiLf1Z5E/xs1a5ukkKJwXBVAioEmG81qwOBn9FqHWIrclhCUpqZRfRIZPp8ZXl64RTSIXhGibMujQipVQuXUsAOd4QE4HjirdI9SfzsLMesYimfC/eedEkhjL0z9+sjhgp5wJY84LBiNI6ZwrzNGke/zdySctbfKbgj2q6ECX3jy6lbeiNThEdLfO1t+IHM7rijOlNw/r8Up3YgH5ExUuuAOUJ5B8OuPXyMfnl484FISrdt0XGpNJpS66b1XHmf7p3TmFLlnO7/23uN57KiNdpe0RaB8R+Y5IzmcWrzR67wcbjbBTbjbAD6w1QIWVx6iUVSfciQIgw7WdYK1C6PXxUMEflpAnV0POZSMu++sbYrxJhlGArYgVbSH4i93eENLOJytOfnKXYzirqsHyCjHa55FqYBqC4ogkXXHBIzE90x9n2bNpc2IHYXIUfDcrkZSQFBnyze2uRsYx8dBXi+Pd2pLSFc3l0WnUCRXc4LCMFKEKWy/6fPHAUTy569sNCQd1E19Fx96UAQOsLRAtiHKp9XwCQYFhnPY2j61MYnsnV1Eh+cBc4J8ofY4mK4r7OBY9ze9+qrP95CCxyDJUIHDzDySR05MlXTJwwmA1a2X4r45shLLgZEF6EWsLwSvibme0tjvzczsfIwNGAmvg2gx4Uajr6kBelBRAobURalVBBx0SLghEjf1pXftmDkmRJipoV7tUVNK4tYEm5VVAZ95A", + "commitments": [ + "0xee0a1a26c607ab52c6308165995365f7951a185fccca4b76c847b8860d9fea7a", + "0xbedfbe751c8d3913a76bb030bdcad312ce8c70aeabfaefcf491dafe740946ca5", + "0x74393cbd5f8764be54385a8c7f9442358ae2580f33aebc2597ffa42949172a34", + "0xc881ce64585de627f538376cae9513ca5f4efaa2ab255ce3fa5b15e890223982", + "0xa6ad654807a4f8de3b78d7fa389dc3bd31bbbb5bef24e8e8174f75c6f9ac5c6d", + "0x8c3c5310bc148f9c71d9c0a8771479fb87c6fd9d9595ba60ded7b8eba1d6a483" + ], + "prestateLeaf": "hlGArYgVbSH4i93eENLOJytOfnKXYzirqsHyCjHa55FqYBqC4ogkXXHBIzE90x9n2bNpc2IHYXIUfDcrkZSQFBnyze2uRsYx8dBXi+Pd2pLSFc3l0WnUCRXc4LCMFKEKWy/6fPHAUTy569sNCQd1E19Fx96UAQOsLRAtiHKp9XwCQYFhnPY2jw==", + "poststateLeaf": "rUxieydXUSH5wFzgnyh9jiYrivs4Fj3N736qs/3kILHIMlQgcPMPJJHTkyVdMnDCYDVrZfivjmyEsuBkQXoRawvBK+JuZ7S2O/NzOx8jA0YCa+DaDHhRqOvqQF6UFEChtRFqVUEHHRIuCESN/Wld+2YOSZEmKmhXu1RU0ri1gSblVUBn3kABgA==" + } +] diff --git a/op-challenger/game/keccak/merkle/testdata/proofs.json b/op-challenger/game/keccak/merkle/testdata/proofs.json new file mode 100644 index 000000000000..cf319a4aab25 --- /dev/null +++ b/op-challenger/game/keccak/merkle/testdata/proofs.json @@ -0,0 +1,177 @@ +[ + { + "name": "NoLeaves", + "rootHash": "0x2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f", + "leafCount": 0, + "index": 0, + "proofs": [] + }, + { + "name": "SingleLeaf", + "rootHash": "0x8285ae2d9ccfc8021051c1ea3dfa5ba8219605d0e28c941f1bc174822eda1154", + "leafCount": 1, + "index": 0, + "proofs": [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", + "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", + "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", + "0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344", + "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", + "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", + "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", + "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", + "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", + "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", + "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", + "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", + "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", + "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", + "0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2" + ] + }, + { + "name": "TwoLeaves", + "rootHash": "0x2f27513ae8b07634c3ac408e55e7b4b6d0dc400e3fa9b2165607d61a84625608", + "leafCount": 2, + "index": 1, + "proofs": [ + "0xff00000000000000000000000000000000000000000000000000000000000000", + "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", + "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", + "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", + "0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344", + "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", + "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", + "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", + "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", + "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", + "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", + "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", + "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", + "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", + "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", + "0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2" + ] + }, + { + "name": "SingleLeaf", + "rootHash": "0x8285ae2d9ccfc8021051c1ea3dfa5ba8219605d0e28c941f1bc174822eda1154", + "leafCount": 1, + "index": 1, + "proofs": [ + "0xff00000000000000000000000000000000000000000000000000000000000000", + "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", + "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", + "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", + "0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344", + "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", + "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", + "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", + "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", + "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", + "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", + "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", + "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", + "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", + "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", + "0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2" + ] + }, + { + "name": "PartialTree", + "rootHash": "0x72cdab4557ab96d1246b76e49b1d1a582662ebfceafe2f9c2922304d4fb9db33", + "leafCount": 20, + "index": 10, + "proofs": [ + "0xff0b000000000000000000000000000000000000000000000000000000000000", + "0xa68dfd9074d20ce110c771102e62f17a85ae562a56149e112dd4fecb6cbd8f52", + "0x892339d3cfe686a15b728211f6a3e4f21cf4ee128b152664c90f231f5a9f8333", + "0xd8ca500dee0f1f7334075ebef1e979652b70355c56e09b74d50c87e31e675ddb", + "0x0c9a9c89e79e068154f6c2b9b827cd4f3972e035542ebb68d68b9120e757626c", + "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", + "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", + "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", + "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", + "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", + "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", + "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", + "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", + "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", + "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", + "0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2" + ] + }, + { + "name": "PartialTree", + "rootHash": "0x72cdab4557ab96d1246b76e49b1d1a582662ebfceafe2f9c2922304d4fb9db33", + "leafCount": 20, + "index": 11, + "proofs": [ + "0xff0a000000000000000000000000000000000000000000000000000000000000", + "0xa68dfd9074d20ce110c771102e62f17a85ae562a56149e112dd4fecb6cbd8f52", + "0x892339d3cfe686a15b728211f6a3e4f21cf4ee128b152664c90f231f5a9f8333", + "0xd8ca500dee0f1f7334075ebef1e979652b70355c56e09b74d50c87e31e675ddb", + "0x0c9a9c89e79e068154f6c2b9b827cd4f3972e035542ebb68d68b9120e757626c", + "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", + "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", + "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", + "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", + "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", + "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", + "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", + "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", + "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", + "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", + "0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2" + ] + }, + { + "name": "PartialTree", + "rootHash": "0x9c089c06e4f93c68d74fdfef9255cb75f78b053dabb43749d20e21aa8330092c", + "leafCount": 65535, + "index": 65533, + "proofs": [ + "0xfffc000000000000000000000000000000000000000000000000000000000000", + "0xf52ca96368ae7189a9a33f0efefd1b0a2a2c208c8dca11a2b1066fe99a6582c5", + "0x6a9b869f709b2d34940a0bbe9eea3d502f1e918a4490eb890f1727d6843c055d", + "0x02f7a2dbcc9b3d6780f7f72aafd200af423ba438d45c535d2d4e333e43ce98fc", + "0x84952e81b8cba49f78e4ee1ef684936b09c1b851ecbe03382afecc04fb98b305", + "0x2f9e97e47493214948c70a6b818145a7e9cd84f7ceab384b179559730d7efbac", + "0x3414ae9dd358c60fae6b4010fc90af715bcc5d0fdd55cefd5370277de456c4b8", + "0x04c3b7e470a22c856003970d95b7015f284a0a09c8bc18e1da02078ded445d58", + "0x417e698fd035c879670c381d7bb0815ce67fb854625e502984ae8e2436ede0a9", + "0x042abe5eb9668a197d5389e4b225c474a7646950279cbd6d326db073ea120266", + "0x34f6ea610e918f37226300a42b22f702f3dd7bd7ae17e9dcb6e7374906b83aef", + "0x1c050824157972417b2931f6018ed24e3fe7fedf7c5a502eb26710501d5379d2", + "0x529067b7c2a065d285b931d19fd85ad35eb0abf89c1ed40ca836ace2c7ddad9e", + "0xfd4d4328beb216713b978c561d4acde2ffe400c60d4b6abe21940c0cff2bf0bc", + "0x9b4a92fefca8b04570c15e329cbc6c953dbe30e06607d985882f35fb8cfd986a", + "0x6ec52bd9024705f2c1bd913c43550f5c2b3fbba19dee077b4da6aa6cd90d1c3f" + ] + }, + { + "name": "FullTree", + "rootHash": "0x9c089c06e4f93c68d74fdfef9255cb75f78b053dabb43749d20e21aa8330092c", + "leafCount": 65535, + "index": 65534, + "proofs": [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x65cf5d60111a84456933bd43218230c6235995be88b274e196e8ffcb88927db6", + "0x6a9b869f709b2d34940a0bbe9eea3d502f1e918a4490eb890f1727d6843c055d", + "0x02f7a2dbcc9b3d6780f7f72aafd200af423ba438d45c535d2d4e333e43ce98fc", + "0x84952e81b8cba49f78e4ee1ef684936b09c1b851ecbe03382afecc04fb98b305", + "0x2f9e97e47493214948c70a6b818145a7e9cd84f7ceab384b179559730d7efbac", + "0x3414ae9dd358c60fae6b4010fc90af715bcc5d0fdd55cefd5370277de456c4b8", + "0x04c3b7e470a22c856003970d95b7015f284a0a09c8bc18e1da02078ded445d58", + "0x417e698fd035c879670c381d7bb0815ce67fb854625e502984ae8e2436ede0a9", + "0x042abe5eb9668a197d5389e4b225c474a7646950279cbd6d326db073ea120266", + "0x34f6ea610e918f37226300a42b22f702f3dd7bd7ae17e9dcb6e7374906b83aef", + "0x1c050824157972417b2931f6018ed24e3fe7fedf7c5a502eb26710501d5379d2", + "0x529067b7c2a065d285b931d19fd85ad35eb0abf89c1ed40ca836ace2c7ddad9e", + "0xfd4d4328beb216713b978c561d4acde2ffe400c60d4b6abe21940c0cff2bf0bc", + "0x9b4a92fefca8b04570c15e329cbc6c953dbe30e06607d985882f35fb8cfd986a", + "0x6ec52bd9024705f2c1bd913c43550f5c2b3fbba19dee077b4da6aa6cd90d1c3f" + ] + } +] diff --git a/op-challenger/game/keccak/merkle/tree.go b/op-challenger/game/keccak/merkle/tree.go new file mode 100644 index 000000000000..16a6c02218b0 --- /dev/null +++ b/op-challenger/game/keccak/merkle/tree.go @@ -0,0 +1,154 @@ +package merkle + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +// BinaryMerkleTreeDepth is the depth of the merkle tree. +const BinaryMerkleTreeDepth = 16 + +// Proof is a list of [common.Hash]s that prove the merkle inclusion of a leaf. +// These are the sibling hashes of the leaf's path from the root to the leaf. +type Proof [BinaryMerkleTreeDepth]common.Hash + +var ( + // MaxLeafCount is the maximum number of leaves in the merkle tree. + MaxLeafCount = 1<= uint64(MaxLeafCount) { + panic("proof index out of bounds") + } + + levelNode := m.walkDownToLeafCount(index + 1) + for height := 0; height < BinaryMerkleTreeDepth; height++ { + if levelNode.Parent.IsLeftChild(levelNode) { + if levelNode.Parent.Right == nil { + proof[height] = common.Hash{} + } else { + proof[height] = levelNode.Parent.Right.Label + } + } else { + if levelNode.Parent.Left == nil { + proof[height] = common.Hash{} + } else { + proof[height] = levelNode.Parent.Left.Label + } + } + levelNode = levelNode.Parent + } + + return proof +} diff --git a/op-challenger/game/keccak/merkle/tree_test.go b/op-challenger/game/keccak/merkle/tree_test.go new file mode 100644 index 000000000000..3fa5f83ddce2 --- /dev/null +++ b/op-challenger/game/keccak/merkle/tree_test.go @@ -0,0 +1,78 @@ +package merkle + +import ( + _ "embed" + "encoding/json" + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +//go:embed testdata/proofs.json +var refTests []byte + +type testData struct { + Name string `json:"name"` + LeafCount uint64 `json:"leafCount"` + RootHash common.Hash `json:"rootHash"` + Index uint64 `json:"index"` + Proofs Proof `json:"proofs"` +} + +func TestBinaryMerkleTree_AddLeaf(t *testing.T) { + var tests []testData + require.NoError(t, json.Unmarshal(refTests, &tests)) + + for i, test := range tests { + test := test + t.Run(fmt.Sprintf("%s-LeafCount-%v-Ref-%v", test.Name, test.LeafCount, i), func(t *testing.T) { + tree := NewBinaryMerkleTree() + expectedLeafHash := zeroHashes[BinaryMerkleTreeDepth-1] + for i := 0; i < int(test.LeafCount); i++ { + expectedLeafHash = leafHash(i) + tree.AddLeaf(expectedLeafHash) + } + leaf := tree.walkDownToLeafCount(tree.LeafCount) + require.Equal(t, expectedLeafHash, leaf.Label) + }) + } +} + +func TestBinaryMerkleTree_RootHash(t *testing.T) { + var tests []testData + require.NoError(t, json.Unmarshal(refTests, &tests)) + + for i, test := range tests { + test := test + t.Run(fmt.Sprintf("%s-LeafCount-%v-Ref-%v", test.Name, test.LeafCount, i), func(t *testing.T) { + tree := NewBinaryMerkleTree() + for i := 0; i < int(test.LeafCount); i++ { + tree.AddLeaf(leafHash(i)) + } + require.Equal(t, test.RootHash, tree.RootHash()) + }) + } +} + +func TestBinaryMerkleTree_ProofAtIndex(t *testing.T) { + var tests []testData + require.NoError(t, json.Unmarshal(refTests, &tests)) + + for i, test := range tests { + test := test + t.Run(fmt.Sprintf("%s-Index-%v-Ref-%v", test.Name, test.LeafCount, i), func(t *testing.T) { + tree := NewBinaryMerkleTree() + for i := 0; i < int(test.LeafCount); i++ { + tree.AddLeaf(leafHash(i)) + } + proof := tree.ProofAtIndex(test.Index) + require.Equal(t, test.Proofs, proof) + }) + } +} + +func leafHash(idx int) common.Hash { + return common.Hash{0xff, byte(idx)} +} diff --git a/op-challenger/game/keccak/scheduler.go b/op-challenger/game/keccak/scheduler.go new file mode 100644 index 000000000000..e9d8cb583be4 --- /dev/null +++ b/op-challenger/game/keccak/scheduler.go @@ -0,0 +1,108 @@ +package keccak + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +type Challenger interface { + Challenge(ctx context.Context, blockHash common.Hash, oracle Oracle, preimages []keccakTypes.LargePreimageMetaData) error +} + +type OracleSource interface { + Oracles() []keccakTypes.LargePreimageOracle +} + +type LargePreimageScheduler struct { + log log.Logger + cl faultTypes.ClockReader + ch chan common.Hash + oracles OracleSource + challenger Challenger + cancel func() + wg sync.WaitGroup +} + +func NewLargePreimageScheduler( + logger log.Logger, + cl faultTypes.ClockReader, + oracleSource OracleSource, + challenger Challenger) *LargePreimageScheduler { + return &LargePreimageScheduler{ + log: logger, + cl: cl, + ch: make(chan common.Hash, 1), + oracles: oracleSource, + challenger: challenger, + } +} + +func (s *LargePreimageScheduler) Start(ctx context.Context) { + ctx, cancel := context.WithCancel(ctx) + s.cancel = cancel + s.wg.Add(1) + go s.run(ctx) +} + +func (s *LargePreimageScheduler) Close() error { + s.cancel() + s.wg.Wait() + return nil +} + +func (s *LargePreimageScheduler) run(ctx context.Context) { + defer s.wg.Done() + for { + select { + case <-ctx.Done(): + return + case blockHash := <-s.ch: + if err := s.verifyPreimages(ctx, blockHash); err != nil { + s.log.Error("Failed to verify large preimages", "blockHash", blockHash, "err", err) + } + } + } +} + +func (s *LargePreimageScheduler) Schedule(blockHash common.Hash, _ uint64) error { + select { + case s.ch <- blockHash: + default: + s.log.Trace("Skipping preimage check while already processing") + } + return nil +} + +func (s *LargePreimageScheduler) verifyPreimages(ctx context.Context, blockHash common.Hash) error { + var err error + for _, oracle := range s.oracles.Oracles() { + err = errors.Join(err, s.verifyOraclePreimages(ctx, oracle, blockHash)) + } + return err +} + +func (s *LargePreimageScheduler) verifyOraclePreimages(ctx context.Context, oracle keccakTypes.LargePreimageOracle, blockHash common.Hash) error { + preimages, err := oracle.GetActivePreimages(ctx, blockHash) + if err != nil { + return err + } + period, err := oracle.ChallengePeriod(ctx) + if err != nil { + return fmt.Errorf("failed to load challenge period: %w", err) + } + toVerify := make([]keccakTypes.LargePreimageMetaData, 0, len(preimages)) + for _, preimage := range preimages { + if preimage.ShouldVerify(s.cl.Now(), time.Duration(period)*time.Second) { + toVerify = append(toVerify, preimage) + } + } + return s.challenger.Challenge(ctx, blockHash, oracle, toVerify) +} diff --git a/op-challenger/game/keccak/scheduler_test.go b/op-challenger/game/keccak/scheduler_test.go new file mode 100644 index 000000000000..067fc5d93065 --- /dev/null +++ b/op-challenger/game/keccak/scheduler_test.go @@ -0,0 +1,141 @@ +package keccak + +import ( + "context" + "errors" + "math/big" + "sync" + "testing" + "time" + + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var stubChallengePeriod = uint64(3600) + +func TestScheduleNextCheck(t *testing.T) { + ctx := context.Background() + currentTimestamp := uint64(1240) + logger := testlog.Logger(t, log.LevelInfo) + preimage1 := keccakTypes.LargePreimageMetaData{ // Incomplete so won't be verified + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xab}, + UUID: big.NewInt(111), + }, + } + preimage2 := keccakTypes.LargePreimageMetaData{ // Already countered so won't be verified + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xab}, + UUID: big.NewInt(222), + }, + Timestamp: currentTimestamp - 10, + Countered: true, + } + preimage3 := keccakTypes.LargePreimageMetaData{ + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0xdd}, + UUID: big.NewInt(333), + }, + Timestamp: currentTimestamp - 10, + } + oracle := &stubOracle{ + images: []keccakTypes.LargePreimageMetaData{preimage1, preimage2, preimage3}, + } + cl := clock.NewDeterministicClock(time.Unix(int64(currentTimestamp), 0)) + challenger := &stubChallenger{} + scheduler := NewLargePreimageScheduler(logger, cl, OracleSourceArray{oracle}, challenger) + scheduler.Start(ctx) + defer scheduler.Close() + err := scheduler.Schedule(common.Hash{0xaa}, 3) + require.NoError(t, err) + require.Eventually(t, func() bool { + return oracle.GetPreimagesCount() == 1 + }, 10*time.Second, 10*time.Millisecond) + require.Eventually(t, func() bool { + verified := challenger.Checked() + t.Logf("Checked preimages: %v", verified) + return len(verified) == 1 && verified[0] == preimage3 + }, 10*time.Second, 10*time.Millisecond, "Did not verify preimage") +} + +type stubOracle struct { + m sync.Mutex + addr common.Address + getPreimagesCount int + images []keccakTypes.LargePreimageMetaData + treeRoots map[keccakTypes.LargePreimageIdent]common.Hash +} + +func (s *stubOracle) ChallengePeriod(_ context.Context) (uint64, error) { + return stubChallengePeriod, nil +} + +func (s *stubOracle) GetInputDataBlocks(_ context.Context, _ rpcblock.Block, _ keccakTypes.LargePreimageIdent) ([]uint64, error) { + panic("not supported") +} + +func (s *stubOracle) DecodeInputData(_ []byte) (*big.Int, keccakTypes.InputData, error) { + panic("not supported") +} + +func (s *stubOracle) Addr() common.Address { + return s.addr +} + +func (s *stubOracle) GetActivePreimages(_ context.Context, _ common.Hash) ([]keccakTypes.LargePreimageMetaData, error) { + s.m.Lock() + defer s.m.Unlock() + s.getPreimagesCount++ + return s.images, nil +} + +func (s *stubOracle) GetPreimagesCount() int { + s.m.Lock() + defer s.m.Unlock() + return s.getPreimagesCount +} + +func (s *stubOracle) ChallengeTx(_ keccakTypes.LargePreimageIdent, _ keccakTypes.Challenge) (txmgr.TxCandidate, error) { + panic("not supported") +} + +func (s *stubOracle) GetProposalTreeRoot(_ context.Context, _ rpcblock.Block, ident keccakTypes.LargePreimageIdent) (common.Hash, error) { + root, ok := s.treeRoots[ident] + if ok { + return root, nil + } + return common.Hash{}, errors.New("unknown tree root") +} + +type stubChallenger struct { + m sync.Mutex + checked []keccakTypes.LargePreimageMetaData +} + +func (s *stubChallenger) Challenge(_ context.Context, _ common.Hash, _ Oracle, preimages []keccakTypes.LargePreimageMetaData) error { + s.m.Lock() + defer s.m.Unlock() + s.checked = append(s.checked, preimages...) + return nil +} + +func (s *stubChallenger) Checked() []keccakTypes.LargePreimageMetaData { + s.m.Lock() + defer s.m.Unlock() + v := make([]keccakTypes.LargePreimageMetaData, len(s.checked)) + copy(v, s.checked) + return v +} + +type OracleSourceArray []keccakTypes.LargePreimageOracle + +func (o OracleSourceArray) Oracles() []keccakTypes.LargePreimageOracle { + return o +} diff --git a/op-challenger/game/keccak/types/types.go b/op-challenger/game/keccak/types/types.go new file mode 100644 index 000000000000..9c423a7a10ca --- /dev/null +++ b/op-challenger/game/keccak/types/types.go @@ -0,0 +1,107 @@ +package types + +import ( + "context" + "math/big" + "time" + + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/merkle" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" +) + +// BlockSize is the size in bytes required for leaf data. +const BlockSize = 136 + +// Leaf is the keccak state matrix added to the large preimage merkle tree. +type Leaf struct { + // Input is the data absorbed for the block, exactly 136 bytes + Input [BlockSize]byte + // Index of the block in the absorption process + Index uint64 + // StateCommitment is the hash of the internal state after absorbing the input. + StateCommitment common.Hash +} + +// Hash returns the hash of the leaf data. That is the +// bytewise concatenation of the input, index, and state commitment. +func (l Leaf) Hash() common.Hash { + concatted := make([]byte, 0, 136+32+32) + concatted = append(concatted, l.Input[:]...) + concatted = append(concatted, math.U256Bytes(new(big.Int).SetUint64(l.Index))...) + concatted = append(concatted, l.StateCommitment.Bytes()...) + return crypto.Keccak256Hash(concatted) +} + +// InputData is a contiguous segment of preimage data. +type InputData struct { + // Input is the preimage data. + // When Finalize is false, len(Input) must equal len(Commitments)*BlockSize + // When Finalize is true, len(Input) must be between len(Commitments - 1)*BlockSize and len(Commitments)*BlockSize + Input []byte + // Commitments are the keccak commitments for each leaf in the chunk. + Commitments []common.Hash + // Finalize indicates whether the chunk is the final chunk. + Finalize bool +} + +type LargePreimageIdent struct { + Claimant common.Address + UUID *big.Int +} + +type LargePreimageMetaData struct { + LargePreimageIdent + + // Timestamp is the time at which the proposal first became fully available. + // 0 when not all data is available yet + Timestamp uint64 + PartOffset uint32 + ClaimedSize uint32 + BlocksProcessed uint32 + BytesProcessed uint32 + Countered bool +} + +// ShouldVerify returns true if the preimage upload is complete, has not yet been countered, and the +// challenge period has not yet elapsed. +func (m LargePreimageMetaData) ShouldVerify(now time.Time, ignoreAfter time.Duration) bool { + return m.Timestamp > 0 && !m.Countered && m.Timestamp+uint64(ignoreAfter.Seconds()) > uint64(now.Unix()) +} + +type StateSnapshot [25]uint64 + +// Pack packs the state in to the solidity ABI encoding required for the state matrix +func (s StateSnapshot) Pack() []byte { + buf := make([]byte, 0, len(s)*32) + for _, v := range s { + buf = append(buf, math.U256Bytes(new(big.Int).SetUint64(v))...) + } + return buf +} + +type Challenge struct { + // StateMatrix is the packed state matrix preimage of the StateCommitment in Prestate + StateMatrix StateSnapshot + + // Prestate is the valid leaf immediately prior to the first invalid leaf + Prestate Leaf + PrestateProof merkle.Proof + + // Poststate is the first invalid leaf in the preimage. The challenge claims that this leaf is invalid. + Poststate Leaf + PoststateProof merkle.Proof +} + +type LargePreimageOracle interface { + Addr() common.Address + GetActivePreimages(ctx context.Context, blockHash common.Hash) ([]LargePreimageMetaData, error) + GetInputDataBlocks(ctx context.Context, block rpcblock.Block, ident LargePreimageIdent) ([]uint64, error) + GetProposalTreeRoot(ctx context.Context, block rpcblock.Block, ident LargePreimageIdent) (common.Hash, error) + DecodeInputData(data []byte) (*big.Int, InputData, error) + ChallengeTx(ident LargePreimageIdent, challenge Challenge) (txmgr.TxCandidate, error) + ChallengePeriod(ctx context.Context) (uint64, error) +} diff --git a/op-challenger/game/keccak/types/types_test.go b/op-challenger/game/keccak/types/types_test.go new file mode 100644 index 000000000000..b8a34021c2f7 --- /dev/null +++ b/op-challenger/game/keccak/types/types_test.go @@ -0,0 +1,64 @@ +package types + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestShouldVerify(t *testing.T) { + tests := []struct { + name string + timestamp uint64 + countered bool + now int64 + expected bool + }{ + { + name: "IgnoreNotFinalizedAndNotCountered", + timestamp: 0, + countered: false, + now: 100, + expected: false, + }, + { + name: "VerifyFinalizedAndNotCountered", + timestamp: 50, + countered: false, + now: 100, + expected: true, + }, + { + name: "IgnoreFinalizedAndCountered", + timestamp: 50, + countered: true, + now: 100, + expected: false, + }, + { + name: "IgnoreNotFinalizedAndCountered", + timestamp: 0, + countered: true, + now: 100, + expected: false, + }, + { + name: "IgnoreFinalizedBeforeTimeWindowAndNotCountered", + timestamp: 50, + countered: false, + now: 50 + int64((2 * time.Hour).Seconds()), + expected: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + metadata := LargePreimageMetaData{ + Timestamp: test.timestamp, + Countered: test.countered, + } + require.Equal(t, test.expected, metadata.ShouldVerify(time.Unix(test.now, 0), 1*time.Hour)) + }) + } +} diff --git a/op-challenger/game/keccak/verifier.go b/op-challenger/game/keccak/verifier.go new file mode 100644 index 000000000000..026462b127e0 --- /dev/null +++ b/op-challenger/game/keccak/verifier.go @@ -0,0 +1,81 @@ +package keccak + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/fetcher" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/matrix" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + lru "github.com/hashicorp/golang-lru/v2" +) + +const validPreimageCacheSize = 500 + +type VerifierPreimageOracle interface { + fetcher.Oracle + GetProposalTreeRoot(ctx context.Context, block rpcblock.Block, ident keccakTypes.LargePreimageIdent) (common.Hash, error) +} + +type Fetcher interface { + FetchInputs(ctx context.Context, blockHash common.Hash, oracle fetcher.Oracle, ident keccakTypes.LargePreimageIdent) ([]keccakTypes.InputData, error) +} + +type PreimageVerifier struct { + log log.Logger + fetcher Fetcher + + // knownValid caches the merkle tree roots that have been confirmed as valid. + // Invalid roots are not cached as those preimages will be ignored once the challenge is processed. + knownValid *lru.Cache[common.Hash, bool] +} + +func NewPreimageVerifier(logger log.Logger, fetcher Fetcher) *PreimageVerifier { + // Can't error because size is hard coded + cache, _ := lru.New[common.Hash, bool](validPreimageCacheSize) + return &PreimageVerifier{ + log: logger, + fetcher: fetcher, + knownValid: cache, + } +} + +func (v *PreimageVerifier) CreateChallenge(ctx context.Context, blockHash common.Hash, oracle VerifierPreimageOracle, preimage keccakTypes.LargePreimageMetaData) (keccakTypes.Challenge, error) { + root, err := oracle.GetProposalTreeRoot(ctx, rpcblock.ByHash(blockHash), preimage.LargePreimageIdent) + if err != nil { + return keccakTypes.Challenge{}, fmt.Errorf("failed to get proposal merkle root: %w", err) + } + if valid, ok := v.knownValid.Get(root); ok && valid { + // We've already determined that the keccak transition is valid. + // Note that the merkle tree may have been validated by a different proposal but since the tree root + // commits to all the input data and the resulting keccak state matrix, any other proposal with the same + // root must also have the same inputs and correctly applied keccak. + // It is possible that this proposal can't be squeezed because the claimed data length doesn't match the + // actual length but the contracts enforce that and it can't be challenged on that basis. + return keccakTypes.Challenge{}, matrix.ErrValid + } + inputs, err := v.fetcher.FetchInputs(ctx, blockHash, oracle, preimage.LargePreimageIdent) + if err != nil { + return keccakTypes.Challenge{}, fmt.Errorf("failed to fetch leaves: %w", err) + } + readers := make([]io.Reader, 0, len(inputs)) + var commitments []common.Hash + for _, input := range inputs { + readers = append(readers, bytes.NewReader(input.Input)) + commitments = append(commitments, input.Commitments...) + } + challenge, err := matrix.Challenge(io.MultiReader(readers...), commitments) + if errors.Is(err, matrix.ErrValid) { + v.knownValid.Add(root, true) + return keccakTypes.Challenge{}, err + } else if err != nil { + return keccakTypes.Challenge{}, fmt.Errorf("failed to create challenge: %w", err) + } + return challenge, nil +} diff --git a/op-challenger/game/keccak/verifier_test.go b/op-challenger/game/keccak/verifier_test.go new file mode 100644 index 000000000000..fdf7bf062df7 --- /dev/null +++ b/op-challenger/game/keccak/verifier_test.go @@ -0,0 +1,164 @@ +package keccak + +import ( + "bytes" + "context" + "errors" + "io" + "math/big" + "math/rand" + "sync/atomic" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/fetcher" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/matrix" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestVerify(t *testing.T) { + logger := testlog.Logger(t, log.LevelInfo) + tests := []struct { + name string + inputs func() []keccakTypes.InputData + expectedErr error + }{ + { + name: "Valid-SingleInput", + inputs: func() []keccakTypes.InputData { return validInputs(t, 1) }, + expectedErr: matrix.ErrValid, + }, + { + name: "Valid-MultipleInputs", + inputs: func() []keccakTypes.InputData { return validInputs(t, 3) }, + expectedErr: matrix.ErrValid, + }, + { + name: "Invalid-FirstCommitment", + inputs: func() []keccakTypes.InputData { + inputs := validInputs(t, 1) + inputs[0].Commitments[0] = common.Hash{0xaa} + return inputs + }, + expectedErr: nil, + }, + { + name: "Invalid-MiddleCommitment", + inputs: func() []keccakTypes.InputData { + inputs := validInputs(t, 1) + inputs[0].Commitments[1] = common.Hash{0xaa} + return inputs + }, + expectedErr: nil, + }, + { + name: "Invalid-LastCommitment", + inputs: func() []keccakTypes.InputData { + inputs := validInputs(t, 3) + inputs[2].Commitments[len(inputs[2].Commitments)-1] = common.Hash{0xaa} + return inputs + }, + expectedErr: nil, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + fetcher := &stubFetcher{ + inputs: test.inputs(), + } + verifier := NewPreimageVerifier(logger, fetcher) + preimage := keccakTypes.LargePreimageMetaData{} + oracle := &stubOracle{ + treeRoots: map[keccakTypes.LargePreimageIdent]common.Hash{ + preimage.LargePreimageIdent: {0xde}, + }, + } + challenge, err := verifier.CreateChallenge(context.Background(), common.Hash{0xff}, oracle, preimage) + require.ErrorIs(t, err, test.expectedErr) + if err == nil { + // Leave checking the validity of the challenge to the StateMatrix tests + // Just confirm that we got a non-zero challenge + require.NotEqual(t, keccakTypes.Challenge{}, challenge) + } else { + require.Equal(t, keccakTypes.Challenge{}, challenge) + } + }) + } +} + +func TestCacheValidRoots(t *testing.T) { + logger := testlog.Logger(t, log.LvlInfo) + fetcher := &stubFetcher{ + inputs: validInputs(t, 1), + } + verifier := NewPreimageVerifier(logger, fetcher) + preimage1 := keccakTypes.LargePreimageMetaData{ + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0x12}, + UUID: big.NewInt(1), + }, + } + preimage2 := keccakTypes.LargePreimageMetaData{ + LargePreimageIdent: keccakTypes.LargePreimageIdent{ + Claimant: common.Address{0x23}, + UUID: big.NewInt(2), + }, + } + oracle := &stubOracle{ + treeRoots: map[keccakTypes.LargePreimageIdent]common.Hash{ + preimage1.LargePreimageIdent: {0xde}, + preimage2.LargePreimageIdent: {0xde}, + }, + } + challenge, err := verifier.CreateChallenge(context.Background(), common.Hash{0xff}, oracle, preimage1) + require.ErrorIs(t, err, matrix.ErrValid) + require.Equal(t, keccakTypes.Challenge{}, challenge, "Should be valid") + require.EqualValues(t, 1, fetcher.fetchCount.Load(), "Should fetch data and validate") + + // Should cache the validity + challenge, err = verifier.CreateChallenge(context.Background(), common.Hash{0xee}, oracle, preimage1) + require.ErrorIs(t, err, matrix.ErrValid) + require.Equal(t, keccakTypes.Challenge{}, challenge, "Should be valid") + require.EqualValues(t, 1, fetcher.fetchCount.Load(), "Should use cached validity") + + // Should cache the validity across different challenges + challenge, err = verifier.CreateChallenge(context.Background(), common.Hash{0xee}, oracle, preimage2) + require.ErrorIs(t, err, matrix.ErrValid) + require.Equal(t, keccakTypes.Challenge{}, challenge, "Should be valid") + require.EqualValues(t, 1, fetcher.fetchCount.Load(), "Should use cached validity") +} + +func validInputs(t *testing.T, inputCount int) []keccakTypes.InputData { + chunkSize := 2 * keccakTypes.BlockSize + data := testutils.RandomData(rand.New(rand.NewSource(4444)), inputCount*chunkSize) + var calls []keccakTypes.InputData + in := bytes.NewReader(data) + s := matrix.NewStateMatrix() + for { + call, err := s.AbsorbUpTo(in, chunkSize) + if !errors.Is(err, io.EOF) { + require.NoError(t, err) + } + calls = append(calls, call) + if errors.Is(err, io.EOF) { + break + } + } + return calls +} + +type stubFetcher struct { + inputs []keccakTypes.InputData + fetchCount atomic.Int64 +} + +func (s *stubFetcher) FetchInputs(_ context.Context, _ common.Hash, _ fetcher.Oracle, _ keccakTypes.LargePreimageIdent) ([]keccakTypes.InputData, error) { + s.fetchCount.Add(1) + return s.inputs, nil +} diff --git a/op-challenger/game/loader/game_loader.go b/op-challenger/game/loader/game_loader.go deleted file mode 100644 index d5afee62ebc0..000000000000 --- a/op-challenger/game/loader/game_loader.go +++ /dev/null @@ -1,70 +0,0 @@ -package loader - -import ( - "context" - "errors" - "fmt" - "math/big" - - "github.com/ethereum-optimism/optimism/op-challenger/game/types" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" -) - -var ( - ErrMissingBlockNumber = errors.New("game loader missing block number") -) - -// MinimalDisputeGameFactoryCaller is a minimal interface around [bindings.DisputeGameFactoryCaller]. -// This needs to be updated if the [bindings.DisputeGameFactoryCaller] interface changes. -type MinimalDisputeGameFactoryCaller interface { - GameCount(opts *bind.CallOpts) (*big.Int, error) - GameAtIndex(opts *bind.CallOpts, _index *big.Int) (struct { - GameType uint8 - Timestamp uint64 - Proxy common.Address - }, error) -} - -type GameLoader struct { - caller MinimalDisputeGameFactoryCaller -} - -// NewGameLoader creates a new services that can be used to fetch on chain dispute games. -func NewGameLoader(caller MinimalDisputeGameFactoryCaller) *GameLoader { - return &GameLoader{ - caller: caller, - } -} - -// FetchAllGamesAtBlock fetches all dispute games from the factory at a given block number. -func (l *GameLoader) FetchAllGamesAtBlock(ctx context.Context, earliestTimestamp uint64, blockNumber *big.Int) ([]types.GameMetadata, error) { - if blockNumber == nil { - return nil, ErrMissingBlockNumber - } - callOpts := &bind.CallOpts{ - Context: ctx, - BlockNumber: blockNumber, - } - gameCount, err := l.caller.GameCount(callOpts) - if err != nil { - return nil, fmt.Errorf("failed to fetch game count: %w", err) - } - - games := make([]types.GameMetadata, 0) - if gameCount.Uint64() == 0 { - return games, nil - } - for i := gameCount.Uint64(); i > 0; i-- { - game, err := l.caller.GameAtIndex(callOpts, big.NewInt(int64(i-1))) - if err != nil { - return nil, fmt.Errorf("failed to fetch game at index %d: %w", i, err) - } - if game.Timestamp < earliestTimestamp { - break - } - games = append(games, game) - } - - return games, nil -} diff --git a/op-challenger/game/loader/game_loader_test.go b/op-challenger/game/loader/game_loader_test.go deleted file mode 100644 index 1c6959be3b85..000000000000 --- a/op-challenger/game/loader/game_loader_test.go +++ /dev/null @@ -1,178 +0,0 @@ -package loader - -import ( - "context" - "errors" - "math/big" - "testing" - - "github.com/ethereum-optimism/optimism/op-challenger/game/types" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" -) - -var ( - gameCountErr = errors.New("game count error") - gameIndexErr = errors.New("game index error") -) - -// TestGameLoader_FetchAllGames tests that the game loader correctly fetches all games. -func TestGameLoader_FetchAllGames(t *testing.T) { - t.Parallel() - - tests := []struct { - name string - caller *mockMinimalDisputeGameFactoryCaller - earliest uint64 - blockNumber *big.Int - expectedErr error - expectedLen int - }{ - { - name: "success", - caller: newMockMinimalDisputeGameFactoryCaller(10, false, false), - blockNumber: big.NewInt(1), - expectedLen: 10, - }, - { - name: "expired game ignored", - caller: newMockMinimalDisputeGameFactoryCaller(10, false, false), - earliest: 500, - blockNumber: big.NewInt(1), - expectedLen: 5, - }, - { - name: "game count error", - caller: newMockMinimalDisputeGameFactoryCaller(10, true, false), - blockNumber: big.NewInt(1), - expectedErr: gameCountErr, - }, - { - name: "game index error", - caller: newMockMinimalDisputeGameFactoryCaller(10, false, true), - blockNumber: big.NewInt(1), - expectedErr: gameIndexErr, - }, - { - name: "no games", - caller: newMockMinimalDisputeGameFactoryCaller(0, false, false), - blockNumber: big.NewInt(1), - }, - { - name: "missing block number", - caller: newMockMinimalDisputeGameFactoryCaller(0, false, false), - expectedErr: ErrMissingBlockNumber, - }, - } - - for _, test := range tests { - test := test - - t.Run(test.name, func(t *testing.T) { - t.Parallel() - - loader := NewGameLoader(test.caller) - games, err := loader.FetchAllGamesAtBlock(context.Background(), test.earliest, test.blockNumber) - require.ErrorIs(t, err, test.expectedErr) - require.Len(t, games, test.expectedLen) - expectedGames := test.caller.games - expectedGames = expectedGames[len(expectedGames)-test.expectedLen:] - if test.expectedErr != nil { - expectedGames = make([]types.GameMetadata, 0) - } - require.ElementsMatch(t, expectedGames, translateGames(games)) - }) - } -} - -func generateMockGames(count uint64) []types.GameMetadata { - games := make([]types.GameMetadata, count) - - for i := uint64(0); i < count; i++ { - games[i] = types.GameMetadata{ - Proxy: common.BigToAddress(big.NewInt(int64(i))), - Timestamp: i * 100, - } - } - - return games -} - -func translateGames(games []types.GameMetadata) []types.GameMetadata { - translated := make([]types.GameMetadata, len(games)) - - for i, game := range games { - translated[i] = translateFaultDisputeGame(game) - } - - return translated -} - -func translateFaultDisputeGame(game types.GameMetadata) types.GameMetadata { - return types.GameMetadata{ - Proxy: game.Proxy, - Timestamp: game.Timestamp, - } -} - -func generateMockGameErrors(count uint64, injectErrors bool) []bool { - errors := make([]bool, count) - - if injectErrors { - for i := uint64(0); i < count; i++ { - errors[i] = true - } - } - - return errors -} - -type mockMinimalDisputeGameFactoryCaller struct { - gameCountErr bool - indexErrors []bool - gameCount uint64 - games []types.GameMetadata -} - -func newMockMinimalDisputeGameFactoryCaller(count uint64, gameCountErr bool, indexErrors bool) *mockMinimalDisputeGameFactoryCaller { - return &mockMinimalDisputeGameFactoryCaller{ - indexErrors: generateMockGameErrors(count, indexErrors), - gameCountErr: gameCountErr, - gameCount: count, - games: generateMockGames(count), - } -} - -func (m *mockMinimalDisputeGameFactoryCaller) GameCount(opts *bind.CallOpts) (*big.Int, error) { - if m.gameCountErr { - return nil, gameCountErr - } - - return big.NewInt(int64(m.gameCount)), nil -} - -func (m *mockMinimalDisputeGameFactoryCaller) GameAtIndex(opts *bind.CallOpts, _index *big.Int) (struct { - GameType uint8 - Timestamp uint64 - Proxy common.Address -}, error) { - index := _index.Uint64() - if m.indexErrors[index] { - return struct { - GameType uint8 - Timestamp uint64 - Proxy common.Address - }{}, gameIndexErr - } - - return struct { - GameType uint8 - Timestamp uint64 - Proxy common.Address - }{ - GameType: m.games[index].GameType, - Timestamp: m.games[index].Timestamp, - Proxy: m.games[index].Proxy, - }, nil -} diff --git a/op-challenger/game/monitor.go b/op-challenger/game/monitor.go index a8c9c694b20c..fe263a661692 100644 --- a/op-challenger/game/monitor.go +++ b/op-challenger/game/monitor.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "math/big" + "sync" "time" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" @@ -23,23 +23,39 @@ type blockNumberFetcher func(ctx context.Context) (uint64, error) // gameSource loads information about the games available to play type gameSource interface { - FetchAllGamesAtBlock(ctx context.Context, earliest uint64, blockNumber *big.Int) ([]types.GameMetadata, error) + GetGamesAtOrAfter(ctx context.Context, blockHash common.Hash, earliestTimestamp uint64) ([]types.GameMetadata, error) +} + +type RWClock interface { + SetTime(uint64) + Now() time.Time } type gameScheduler interface { - Schedule([]types.GameMetadata) error + Schedule([]types.GameMetadata, uint64) error +} + +type preimageScheduler interface { + Schedule(blockHash common.Hash, blockNumber uint64) error +} + +type claimer interface { + Schedule(blockNumber uint64, games []types.GameMetadata) error } type gameMonitor struct { logger log.Logger - clock clock.Clock + clock RWClock source gameSource scheduler gameScheduler + preimages preimageScheduler gameWindow time.Duration + claimer claimer fetchBlockNumber blockNumberFetcher allowedGames []common.Address l1HeadsSub ethereum.Subscription l1Source *headSource + runState sync.Mutex } type MinimalSubscriber interface { @@ -56,10 +72,12 @@ func (s *headSource) SubscribeNewHead(ctx context.Context, ch chan<- *ethTypes.H func newGameMonitor( logger log.Logger, - cl clock.Clock, + cl RWClock, source gameSource, scheduler gameScheduler, + preimages preimageScheduler, gameWindow time.Duration, + claimer claimer, fetchBlockNumber blockNumberFetcher, allowedGames []common.Address, l1Source MinimalSubscriber, @@ -68,8 +86,10 @@ func newGameMonitor( logger: logger, clock: cl, scheduler: scheduler, + preimages: preimages, source: source, gameWindow: gameWindow, + claimer: claimer, fetchBlockNumber: fetchBlockNumber, allowedGames: allowedGames, l1Source: &headSource{inner: l1Source}, @@ -88,20 +108,9 @@ func (m *gameMonitor) allowedGame(game common.Address) bool { return false } -func (m *gameMonitor) minGameTimestamp() uint64 { - if m.gameWindow.Seconds() == 0 { - return 0 - } - // time: "To compute t-d for a duration d, use t.Add(-d)." - // https://pkg.go.dev/time#Time.Sub - if m.clock.Now().Unix() > int64(m.gameWindow.Seconds()) { - return uint64(m.clock.Now().Add(-m.gameWindow).Unix()) - } - return 0 -} - -func (m *gameMonitor) progressGames(ctx context.Context, blockNum uint64) error { - games, err := m.source.FetchAllGamesAtBlock(ctx, m.minGameTimestamp(), new(big.Int).SetUint64(blockNum)) +func (m *gameMonitor) progressGames(ctx context.Context, blockHash common.Hash, blockNumber uint64) error { + minGameTimestamp := clock.MinCheckedTimestamp(m.clock, m.gameWindow) + games, err := m.source.GetGamesAtOrAfter(ctx, blockHash, minGameTimestamp) if err != nil { return fmt.Errorf("failed to load games: %w", err) } @@ -113,7 +122,10 @@ func (m *gameMonitor) progressGames(ctx context.Context, blockNum uint64) error } gamesToPlay = append(gamesToPlay, game) } - if err := m.scheduler.Schedule(gamesToPlay); errors.Is(err, scheduler.ErrBusy) { + if err := m.claimer.Schedule(blockNumber, gamesToPlay); err != nil { + return fmt.Errorf("failed to schedule bond claims: %w", err) + } + if err := m.scheduler.Schedule(gamesToPlay, blockNumber); errors.Is(err, scheduler.ErrBusy) { m.logger.Info("Scheduler still busy with previous update") } else if err != nil { return fmt.Errorf("failed to schedule games: %w", err) @@ -122,13 +134,19 @@ func (m *gameMonitor) progressGames(ctx context.Context, blockNum uint64) error } func (m *gameMonitor) onNewL1Head(ctx context.Context, sig eth.L1BlockRef) { - if err := m.progressGames(ctx, sig.Number); err != nil { + m.clock.SetTime(sig.Time) + if err := m.progressGames(ctx, sig.Hash, sig.Number); err != nil { m.logger.Error("Failed to progress games", "err", err) } + if err := m.preimages.Schedule(sig.Hash, sig.Number); err != nil { + m.logger.Error("Failed to validate large preimages", "err", err) + } } -func (m *gameMonitor) resubscribeFunction(ctx context.Context) event.ResubscribeErrFunc { - return func(innerCtx context.Context, err error) (event.Subscription, error) { +func (m *gameMonitor) resubscribeFunction() event.ResubscribeErrFunc { + // The ctx is cancelled as soon as the subscription is returned, + // but is only used to create the subscription, and does not affect the returned subscription. + return func(ctx context.Context, err error) (event.Subscription, error) { if err != nil { m.logger.Warn("resubscribing after failed L1 subscription", "err", err) } @@ -136,18 +154,21 @@ func (m *gameMonitor) resubscribeFunction(ctx context.Context) event.Resubscribe } } -func (m *gameMonitor) MonitorGames(ctx context.Context) error { - m.l1HeadsSub = event.ResubscribeErr(time.Second*10, m.resubscribeFunction(ctx)) - for { - select { - case <-ctx.Done(): - m.l1HeadsSub.Unsubscribe() - return nil - case err, ok := <-m.l1HeadsSub.Err(): - if !ok { - return err - } - m.logger.Error("L1 subscription error", "err", err) - } +func (m *gameMonitor) StartMonitoring() { + m.runState.Lock() + defer m.runState.Unlock() + if m.l1HeadsSub != nil { + return // already started + } + m.l1HeadsSub = event.ResubscribeErr(time.Second*10, m.resubscribeFunction()) +} + +func (m *gameMonitor) StopMonitoring() { + m.runState.Lock() + defer m.runState.Unlock() + if m.l1HeadsSub == nil { + return // already stopped } + m.l1HeadsSub.Unsubscribe() + m.l1HeadsSub = nil } diff --git a/op-challenger/game/monitor_test.go b/op-challenger/game/monitor_test.go index 7295fdb74a3d..e4fe24e5b799 100644 --- a/op-challenger/game/monitor_test.go +++ b/op-challenger/game/monitor_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math/big" + "sync" "testing" "time" @@ -19,39 +20,13 @@ import ( "github.com/ethereum-optimism/optimism/op-service/clock" ) -func TestMonitorMinGameTimestamp(t *testing.T) { - t.Parallel() - - t.Run("zero game window returns zero", func(t *testing.T) { - monitor, _, _, _ := setupMonitorTest(t, []common.Address{}) - monitor.gameWindow = time.Duration(0) - require.Equal(t, monitor.minGameTimestamp(), uint64(0)) - }) - - t.Run("non-zero game window with zero clock", func(t *testing.T) { - monitor, _, _, _ := setupMonitorTest(t, []common.Address{}) - monitor.gameWindow = time.Minute - monitor.clock = clock.NewDeterministicClock(time.Unix(0, 0)) - require.Equal(t, monitor.minGameTimestamp(), uint64(0)) - }) - - t.Run("minimum computed correctly", func(t *testing.T) { - monitor, _, _, _ := setupMonitorTest(t, []common.Address{}) - monitor.gameWindow = time.Minute - frozen := time.Unix(int64(time.Hour.Seconds()), 0) - monitor.clock = clock.NewDeterministicClock(frozen) - expected := uint64(frozen.Add(-time.Minute).Unix()) - require.Equal(t, monitor.minGameTimestamp(), expected) - }) -} - // TestMonitorGames tests that the monitor can handle a new head event // and resubscribe to new heads if the subscription errors. func TestMonitorGames(t *testing.T) { t.Run("Schedules games", func(t *testing.T) { addr1 := common.Address{0xaa} addr2 := common.Address{0xbb} - monitor, source, sched, mockHeadSource := setupMonitorTest(t, []common.Address{}) + monitor, source, sched, mockHeadSource, preimages, _ := setupMonitorTest(t, []common.Address{}) source.games = []types.GameMetadata{newFDG(addr1, 9999), newFDG(addr2, 9999)} ctx, cancel := context.WithCancel(context.Background()) @@ -60,15 +35,16 @@ func TestMonitorGames(t *testing.T) { go func() { headerNotSent := true for { - if len(sched.scheduled) >= 1 { + if len(sched.Scheduled()) >= 1 { break } - if mockHeadSource.sub == nil { + sub := mockHeadSource.Sub() + if sub == nil { continue } if headerNotSent { select { - case mockHeadSource.sub.headers <- ðtypes.Header{ + case sub.headers <- ðtypes.Header{ Number: big.NewInt(1), }: headerNotSent = false @@ -80,20 +56,22 @@ func TestMonitorGames(t *testing.T) { // Just to avoid a tight loop time.Sleep(100 * time.Millisecond) } - mockHeadSource.err = fmt.Errorf("eth subscribe test error") + mockHeadSource.SetErr(fmt.Errorf("eth subscribe test error")) cancel() }() - err := monitor.MonitorGames(ctx) - require.NoError(t, err) - require.Len(t, sched.scheduled, 1) - require.Equal(t, []common.Address{addr1, addr2}, sched.scheduled[0]) + monitor.StartMonitoring() + <-ctx.Done() + monitor.StopMonitoring() + require.Len(t, sched.Scheduled(), 1) + require.Equal(t, []common.Address{addr1, addr2}, sched.Scheduled()[0]) + require.GreaterOrEqual(t, preimages.ScheduleCount(), 1, "Should schedule preimage checks") }) t.Run("Resubscribes on error", func(t *testing.T) { addr1 := common.Address{0xaa} addr2 := common.Address{0xbb} - monitor, source, sched, mockHeadSource := setupMonitorTest(t, []common.Address{}) + monitor, source, sched, mockHeadSource, preimages, _ := setupMonitorTest(t, []common.Address{}) source.games = []types.GameMetadata{newFDG(addr1, 9999), newFDG(addr2, 9999)} ctx, cancel := context.WithCancel(context.Background()) @@ -102,19 +80,20 @@ func TestMonitorGames(t *testing.T) { go func() { // Wait for the subscription to be created waitErr := wait.For(context.Background(), 5*time.Second, func() (bool, error) { - return mockHeadSource.sub != nil, nil + return mockHeadSource.Sub() != nil, nil }) require.NoError(t, waitErr) - mockHeadSource.sub.errChan <- fmt.Errorf("test error") + mockHeadSource.Sub().errChan <- fmt.Errorf("test error") for { - if len(sched.scheduled) >= 1 { + if len(sched.Scheduled()) >= 1 { break } - if mockHeadSource.sub == nil { + sub := mockHeadSource.Sub() + if sub == nil { continue } select { - case mockHeadSource.sub.headers <- ðtypes.Header{ + case sub.headers <- ðtypes.Header{ Number: big.NewInt(1), }: case <-ctx.Done(): @@ -125,40 +104,43 @@ func TestMonitorGames(t *testing.T) { time.Sleep(100 * time.Millisecond) } require.NoError(t, waitErr) - mockHeadSource.err = fmt.Errorf("eth subscribe test error") + mockHeadSource.SetErr(fmt.Errorf("eth subscribe test error")) cancel() }() - err := monitor.MonitorGames(ctx) - require.NoError(t, err) - require.NotEmpty(t, sched.scheduled) // We might get more than one update scheduled. - require.Equal(t, []common.Address{addr1, addr2}, sched.scheduled[0]) + monitor.StartMonitoring() + <-ctx.Done() + monitor.StopMonitoring() + require.NotEmpty(t, sched.Scheduled()) // We might get more than one update scheduled. + require.Equal(t, []common.Address{addr1, addr2}, sched.Scheduled()[0]) + require.GreaterOrEqual(t, preimages.ScheduleCount(), 1, "Should schedule preimage checks") }) } func TestMonitorCreateAndProgressGameAgents(t *testing.T) { - monitor, source, sched, _ := setupMonitorTest(t, []common.Address{}) + monitor, source, sched, _, _, _ := setupMonitorTest(t, []common.Address{}) addr1 := common.Address{0xaa} addr2 := common.Address{0xbb} source.games = []types.GameMetadata{newFDG(addr1, 9999), newFDG(addr2, 9999)} - require.NoError(t, monitor.progressGames(context.Background(), uint64(1))) + require.NoError(t, monitor.progressGames(context.Background(), common.Hash{0x01}, 0)) - require.Len(t, sched.scheduled, 1) - require.Equal(t, []common.Address{addr1, addr2}, sched.scheduled[0]) + require.Len(t, sched.Scheduled(), 1) + require.Equal(t, []common.Address{addr1, addr2}, sched.Scheduled()[0]) } func TestMonitorOnlyScheduleSpecifiedGame(t *testing.T) { addr1 := common.Address{0xaa} addr2 := common.Address{0xbb} - monitor, source, sched, _ := setupMonitorTest(t, []common.Address{addr2}) + monitor, source, sched, _, _, stubClaimer := setupMonitorTest(t, []common.Address{addr2}) source.games = []types.GameMetadata{newFDG(addr1, 9999), newFDG(addr2, 9999)} - require.NoError(t, monitor.progressGames(context.Background(), uint64(1))) + require.NoError(t, monitor.progressGames(context.Background(), common.Hash{0x01}, 0)) - require.Len(t, sched.scheduled, 1) - require.Equal(t, []common.Address{addr2}, sched.scheduled[0]) + require.Len(t, sched.Scheduled(), 1) + require.Equal(t, []common.Address{addr2}, sched.Scheduled()[0]) + require.Equal(t, 1, stubClaimer.scheduledGames) } func newFDG(proxy common.Address, timestamp uint64) types.GameMetadata { @@ -171,8 +153,8 @@ func newFDG(proxy common.Address, timestamp uint64) types.GameMetadata { func setupMonitorTest( t *testing.T, allowedGames []common.Address, -) (*gameMonitor, *stubGameSource, *stubScheduler, *mockNewHeadSource) { - logger := testlog.Logger(t, log.LvlDebug) +) (*gameMonitor, *stubGameSource, *stubScheduler, *mockNewHeadSource, *stubPreimageScheduler, *mockScheduler) { + logger := testlog.Logger(t, log.LevelDebug) source := &stubGameSource{} i := uint64(1) fetchBlockNum := func(ctx context.Context) (uint64, error) { @@ -180,30 +162,55 @@ func setupMonitorTest( return i, nil } sched := &stubScheduler{} + preimages := &stubPreimageScheduler{} mockHeadSource := &mockNewHeadSource{} + stubClaimer := &mockScheduler{} monitor := newGameMonitor( logger, - clock.SystemClock, + clock.NewSimpleClock(), source, sched, + preimages, time.Duration(0), + stubClaimer, fetchBlockNum, allowedGames, mockHeadSource, ) - return monitor, source, sched, mockHeadSource + return monitor, source, sched, mockHeadSource, preimages, stubClaimer } type mockNewHeadSource struct { + sync.Mutex sub *mockSubscription err error } +func (m *mockNewHeadSource) Sub() *mockSubscription { + m.Lock() + defer m.Unlock() + return m.sub +} + +func (m *mockNewHeadSource) SetSub(sub *mockSubscription) { + m.Lock() + defer m.Unlock() + m.sub = sub +} + +func (m *mockNewHeadSource) SetErr(err error) { + m.Lock() + defer m.Unlock() + m.err = err +} + func (m *mockNewHeadSource) EthSubscribe( - ctx context.Context, + _ context.Context, ch any, - args ...any, + _ ...any, ) (ethereum.Subscription, error) { + m.Lock() + defer m.Unlock() errChan := make(chan error) m.sub = &mockSubscription{errChan, (ch).(chan<- *ethtypes.Header)} if m.err != nil { @@ -212,6 +219,16 @@ func (m *mockNewHeadSource) EthSubscribe( return m.sub, nil } +type mockScheduler struct { + scheduleErr error + scheduledGames int +} + +func (m *mockScheduler) Schedule(_ uint64, games []types.GameMetadata) error { + m.scheduledGames += len(games) + return m.scheduleErr +} + type mockSubscription struct { errChan chan error headers chan<- *ethtypes.Header @@ -224,22 +241,35 @@ func (m *mockSubscription) Err() <-chan error { } type stubGameSource struct { - games []types.GameMetadata + fetchErr error + games []types.GameMetadata } -func (s *stubGameSource) FetchAllGamesAtBlock( - ctx context.Context, - earliest uint64, - blockNumber *big.Int, +func (s *stubGameSource) GetGamesAtOrAfter( + _ context.Context, + _ common.Hash, + _ uint64, ) ([]types.GameMetadata, error) { + if s.fetchErr != nil { + return nil, s.fetchErr + } return s.games, nil } type stubScheduler struct { + sync.Mutex scheduled [][]common.Address } -func (s *stubScheduler) Schedule(games []types.GameMetadata) error { +func (s *stubScheduler) Scheduled() [][]common.Address { + s.Lock() + defer s.Unlock() + return s.scheduled +} + +func (s *stubScheduler) Schedule(games []types.GameMetadata, blockNumber uint64) error { + s.Lock() + defer s.Unlock() var addrs []common.Address for _, game := range games { addrs = append(addrs, game.Proxy) @@ -247,3 +277,21 @@ func (s *stubScheduler) Schedule(games []types.GameMetadata) error { s.scheduled = append(s.scheduled, addrs) return nil } + +type stubPreimageScheduler struct { + sync.Mutex + scheduleCount int +} + +func (s *stubPreimageScheduler) Schedule(_ common.Hash, _ uint64) error { + s.Lock() + defer s.Unlock() + s.scheduleCount++ + return nil +} + +func (s *stubPreimageScheduler) ScheduleCount() int { + s.Lock() + defer s.Unlock() + return s.scheduleCount +} diff --git a/op-challenger/game/registry/oracles.go b/op-challenger/game/registry/oracles.go new file mode 100644 index 000000000000..9ee107990280 --- /dev/null +++ b/op-challenger/game/registry/oracles.go @@ -0,0 +1,32 @@ +package registry + +import ( + "sync" + + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum/go-ethereum/common" + "golang.org/x/exp/maps" +) + +type OracleRegistry struct { + l sync.Mutex + oracles map[common.Address]keccakTypes.LargePreimageOracle +} + +func NewOracleRegistry() *OracleRegistry { + return &OracleRegistry{ + oracles: make(map[common.Address]keccakTypes.LargePreimageOracle), + } +} + +func (r *OracleRegistry) RegisterOracle(oracle keccakTypes.LargePreimageOracle) { + r.l.Lock() + defer r.l.Unlock() + r.oracles[oracle.Addr()] = oracle +} + +func (r *OracleRegistry) Oracles() []keccakTypes.LargePreimageOracle { + r.l.Lock() + defer r.l.Unlock() + return maps.Values(r.oracles) +} diff --git a/op-challenger/game/registry/oracles_test.go b/op-challenger/game/registry/oracles_test.go new file mode 100644 index 000000000000..8e14fa4f5137 --- /dev/null +++ b/op-challenger/game/registry/oracles_test.go @@ -0,0 +1,56 @@ +package registry + +import ( + "context" + "math/big" + "testing" + + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestDeduplicateOracles(t *testing.T) { + registry := NewOracleRegistry() + oracleA := stubPreimageOracle{0xaa} + oracleB := stubPreimageOracle{0xbb} + registry.RegisterOracle(oracleA) + registry.RegisterOracle(oracleB) + registry.RegisterOracle(oracleB) + oracles := registry.Oracles() + require.Len(t, oracles, 2) + require.Contains(t, oracles, oracleA) + require.Contains(t, oracles, oracleB) +} + +type stubPreimageOracle common.Address + +func (s stubPreimageOracle) ChallengePeriod(_ context.Context) (uint64, error) { + panic("not supported") +} + +func (s stubPreimageOracle) GetProposalTreeRoot(_ context.Context, _ rpcblock.Block, _ keccakTypes.LargePreimageIdent) (common.Hash, error) { + panic("not supported") +} + +func (s stubPreimageOracle) ChallengeTx(_ keccakTypes.LargePreimageIdent, _ keccakTypes.Challenge) (txmgr.TxCandidate, error) { + panic("not supported") +} + +func (s stubPreimageOracle) GetInputDataBlocks(_ context.Context, _ rpcblock.Block, _ keccakTypes.LargePreimageIdent) ([]uint64, error) { + panic("not supported") +} + +func (s stubPreimageOracle) DecodeInputData(_ []byte) (*big.Int, keccakTypes.InputData, error) { + panic("not supported") +} + +func (s stubPreimageOracle) Addr() common.Address { + return common.Address(s) +} + +func (s stubPreimageOracle) GetActivePreimages(_ context.Context, _ common.Hash) ([]keccakTypes.LargePreimageMetaData, error) { + return nil, nil +} diff --git a/op-challenger/game/registry/registry.go b/op-challenger/game/registry/registry.go index 8f9b71d21388..d6713a918ddc 100644 --- a/op-challenger/game/registry/registry.go +++ b/op-challenger/game/registry/registry.go @@ -4,33 +4,41 @@ import ( "errors" "fmt" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/claims" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" "github.com/ethereum-optimism/optimism/op-challenger/game/types" ) -var ( - ErrUnsupportedGameType = errors.New("unsupported game type") -) +var ErrUnsupportedGameType = errors.New("unsupported game type") type GameTypeRegistry struct { - types map[uint8]scheduler.PlayerCreator + types map[uint32]scheduler.PlayerCreator + bondCreators map[uint32]claims.BondContractCreator } func NewGameTypeRegistry() *GameTypeRegistry { return &GameTypeRegistry{ - types: make(map[uint8]scheduler.PlayerCreator), + types: make(map[uint32]scheduler.PlayerCreator), + bondCreators: make(map[uint32]claims.BondContractCreator), } } // RegisterGameType registers a scheduler.PlayerCreator to use for a specific game type. // Panics if the same game type is registered multiple times, since this indicates a significant programmer error. -func (r *GameTypeRegistry) RegisterGameType(gameType uint8, creator scheduler.PlayerCreator) { +func (r *GameTypeRegistry) RegisterGameType(gameType uint32, creator scheduler.PlayerCreator) { if _, ok := r.types[gameType]; ok { panic(fmt.Errorf("duplicate creator registered for game type: %v", gameType)) } r.types[gameType] = creator } +func (r *GameTypeRegistry) RegisterBondContract(gameType uint32, creator claims.BondContractCreator) { + if _, ok := r.bondCreators[gameType]; ok { + panic(fmt.Errorf("duplicate bond contract registered for game type: %v", gameType)) + } + r.bondCreators[gameType] = creator +} + // CreatePlayer creates a new game player for the given game, using the specified directory for persisting data. func (r *GameTypeRegistry) CreatePlayer(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { creator, ok := r.types[game.GameType] @@ -39,3 +47,11 @@ func (r *GameTypeRegistry) CreatePlayer(game types.GameMetadata, dir string) (sc } return creator(game, dir) } + +func (r *GameTypeRegistry) CreateBondContract(game types.GameMetadata) (claims.BondContract, error) { + creator, ok := r.bondCreators[game.GameType] + if !ok { + return nil, fmt.Errorf("%w: %v", ErrUnsupportedGameType, game.GameType) + } + return creator(game) +} diff --git a/op-challenger/game/registry/registry_test.go b/op-challenger/game/registry/registry_test.go index 9f8c81b85d99..0c6fbd9870c0 100644 --- a/op-challenger/game/registry/registry_test.go +++ b/op-challenger/game/registry/registry_test.go @@ -1,11 +1,16 @@ package registry import ( + "context" + "math/big" "testing" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/claims" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler/test" "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) @@ -38,3 +43,42 @@ func TestPanicsOnDuplicateGameType(t *testing.T) { registry.RegisterGameType(0, creator) }) } + +func TestBondContracts(t *testing.T) { + t.Run("UnknownGameType", func(t *testing.T) { + registry := NewGameTypeRegistry() + contract, err := registry.CreateBondContract(types.GameMetadata{GameType: 0}) + require.ErrorIs(t, err, ErrUnsupportedGameType) + require.Nil(t, contract) + }) + t.Run("KnownGameType", func(t *testing.T) { + registry := NewGameTypeRegistry() + expected := &stubBondContract{} + registry.RegisterBondContract(0, func(game types.GameMetadata) (claims.BondContract, error) { + return expected, nil + }) + creator, err := registry.CreateBondContract(types.GameMetadata{GameType: 0}) + require.NoError(t, err) + require.Same(t, expected, creator) + }) + t.Run("PanicsOnDuplicate", func(t *testing.T) { + registry := NewGameTypeRegistry() + creator := func(game types.GameMetadata) (claims.BondContract, error) { + return nil, nil + } + registry.RegisterBondContract(0, creator) + require.Panics(t, func() { + registry.RegisterBondContract(0, creator) + }) + }) +} + +type stubBondContract struct{} + +func (s *stubBondContract) GetCredit(ctx context.Context, receipient common.Address) (*big.Int, types.GameStatus, error) { + panic("not supported") +} + +func (s *stubBondContract) ClaimCredit(receipient common.Address) (txmgr.TxCandidate, error) { + panic("not supported") +} diff --git a/op-challenger/game/scheduler/coordinator.go b/op-challenger/game/scheduler/coordinator.go index 3d4cac3a4372..63a2dd74f2fe 100644 --- a/op-challenger/game/scheduler/coordinator.go +++ b/op-challenger/game/scheduler/coordinator.go @@ -16,10 +16,18 @@ var errUnknownGame = errors.New("unknown game") type PlayerCreator func(game types.GameMetadata, dir string) (GamePlayer, error) +type CoordinatorMetricer interface { + RecordActedL1Block(n uint64) + RecordGamesStatus(inProgress, defenderWon, challengerWon int) + RecordGameUpdateScheduled() + RecordGameUpdateCompleted() +} + type gameState struct { - player GamePlayer - inflight bool - status types.GameStatus + player GamePlayer + inflight bool + lastProcessedBlockNum uint64 + status types.GameStatus } // coordinator manages the set of current games, queues games to be played (on separate worker threads) and @@ -33,10 +41,15 @@ type coordinator struct { resultQueue <-chan job logger log.Logger - m SchedulerMetricer + m CoordinatorMetricer createPlayer PlayerCreator states map[common.Address]*gameState disk DiskManager + + allowInvalidPrestate bool + + // lastScheduledBlockNum is the highest block number that the coordinator has seen and scheduled jobs. + lastScheduledBlockNum uint64 } // schedule takes the current list of games to attempt to progress, filters out games that have previous @@ -44,7 +57,7 @@ type coordinator struct { // To avoid deadlock, it may process results from the inbound resultQueue while adding jobs to the outbound jobQueue. // Returns an error if a game couldn't be scheduled because of an error. It will continue attempting to progress // all games even if an error occurs with one game. -func (c *coordinator) schedule(ctx context.Context, games []types.GameMetadata) error { +func (c *coordinator) schedule(ctx context.Context, games []types.GameMetadata, blockNumber uint64) error { // First remove any game states we no longer require for addr, state := range c.states { if !state.inflight && !slices.ContainsFunc(games, func(candidate types.GameMetadata) bool { @@ -63,7 +76,7 @@ func (c *coordinator) schedule(ctx context.Context, games []types.GameMetadata) // Otherwise, results may start being processed before all games are recorded, resulting in existing // data directories potentially being deleted for games that are required. for _, game := range games { - if j, err := c.createJob(game); err != nil { + if j, err := c.createJob(ctx, game, blockNumber); err != nil { errs = append(errs, fmt.Errorf("failed to create job for game %v: %w", game.Proxy, err)) } else if j != nil { jobs = append(jobs, *j) @@ -85,6 +98,13 @@ func (c *coordinator) schedule(ctx context.Context, games []types.GameMetadata) } c.m.RecordGamesStatus(gamesInProgress, gamesDefenderWon, gamesChallengerWon) + lowestProcessedBlockNum := blockNumber + for _, state := range c.states { + lowestProcessedBlockNum = min(lowestProcessedBlockNum, state.lastProcessedBlockNum) + } + c.lastScheduledBlockNum = blockNumber + c.m.RecordActedL1Block(lowestProcessedBlockNum) + // Finally, enqueue the jobs for _, j := range jobs { if err := c.enqueueJob(ctx, j); err != nil { @@ -96,14 +116,16 @@ func (c *coordinator) schedule(ctx context.Context, games []types.GameMetadata) // createJob updates the state for the specified game and returns the job to enqueue for it, if any // Returns (nil, nil) when there is no error and no job to enqueue -func (c *coordinator) createJob(game types.GameMetadata) (*job, error) { +func (c *coordinator) createJob(ctx context.Context, game types.GameMetadata, blockNumber uint64) (*job, error) { state, ok := c.states[game.Proxy] if !ok { - state = &gameState{} + // This is the first time we're seeing this game, so its last processed block + // is the last block the coordinator processed (it didn't exist yet). + state = &gameState{lastProcessedBlockNum: c.lastScheduledBlockNum} c.states[game.Proxy] = state } if state.inflight { - c.logger.Debug("Not rescheduling already in-flight game", "game", game) + c.logger.Debug("Not rescheduling already in-flight game", "game", game.Proxy) return nil, nil } // Create the player separately to the state so we retry creating it if it fails on the first attempt. @@ -112,15 +134,21 @@ func (c *coordinator) createJob(game types.GameMetadata) (*job, error) { if err != nil { return nil, fmt.Errorf("failed to create game player: %w", err) } + if err := player.ValidatePrestate(ctx); err != nil { + if !c.allowInvalidPrestate || !errors.Is(err, types.ErrInvalidPrestate) { + return nil, fmt.Errorf("failed to validate prestate: %w", err) + } + c.logger.Error("Invalid prestate", "game", game.Proxy, "err", err) + } state.player = player state.status = player.Status() } state.inflight = true if state.status != types.GameStatusInProgress { - c.logger.Debug("Not rescheduling resolved game", "game", game, "status", state.status) + c.logger.Debug("Not rescheduling resolved game", "game", game.Proxy, "status", state.status) return nil, nil } - return &job{addr: game.Proxy, player: state.player, status: state.status}, nil + return newJob(blockNumber, game.Proxy, state.player, state.status), nil } func (c *coordinator) enqueueJob(ctx context.Context, j job) error { @@ -145,6 +173,7 @@ func (c *coordinator) processResult(j job) error { } state.inflight = false state.status = j.status + state.lastProcessedBlockNum = j.block c.deleteResolvedGameFiles() c.m.RecordGameUpdateCompleted() return nil @@ -162,14 +191,15 @@ func (c *coordinator) deleteResolvedGameFiles() { } } -func newCoordinator(logger log.Logger, m SchedulerMetricer, jobQueue chan<- job, resultQueue <-chan job, createPlayer PlayerCreator, disk DiskManager) *coordinator { +func newCoordinator(logger log.Logger, m CoordinatorMetricer, jobQueue chan<- job, resultQueue <-chan job, createPlayer PlayerCreator, disk DiskManager, allowInvalidPrestate bool) *coordinator { return &coordinator{ - logger: logger, - m: m, - jobQueue: jobQueue, - resultQueue: resultQueue, - createPlayer: createPlayer, - disk: disk, - states: make(map[common.Address]*gameState), + logger: logger, + m: m, + jobQueue: jobQueue, + resultQueue: resultQueue, + createPlayer: createPlayer, + disk: disk, + states: make(map[common.Address]*gameState), + allowInvalidPrestate: allowInvalidPrestate, } } diff --git a/op-challenger/game/scheduler/coordinator_test.go b/op-challenger/game/scheduler/coordinator_test.go index 697a84df20a9..5686b1dae9a4 100644 --- a/op-challenger/game/scheduler/coordinator_test.go +++ b/op-challenger/game/scheduler/coordinator_test.go @@ -7,7 +7,6 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler/test" "github.com/ethereum-optimism/optimism/op-challenger/game/types" - "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -16,12 +15,12 @@ import ( ) func TestScheduleNewGames(t *testing.T) { - c, workQueue, _, games, disk := setupCoordinatorTest(t, 10) + c, workQueue, _, games, disk, _ := setupCoordinatorTest(t, 10) gameAddr1 := common.Address{0xaa} gameAddr2 := common.Address{0xbb} gameAddr3 := common.Address{0xcc} ctx := context.Background() - require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2, gameAddr3))) + require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2, gameAddr3), 0)) require.Len(t, workQueue, 3, "should schedule job for each game") require.Len(t, games.created, 3, "should have created players") @@ -37,39 +36,75 @@ func TestScheduleNewGames(t *testing.T) { } func TestSkipSchedulingInflightGames(t *testing.T) { - c, workQueue, _, _, _ := setupCoordinatorTest(t, 10) + c, workQueue, _, _, _, _ := setupCoordinatorTest(t, 10) gameAddr1 := common.Address{0xaa} ctx := context.Background() // Schedule the game once - require.NoError(t, c.schedule(ctx, asGames(gameAddr1))) + require.NoError(t, c.schedule(ctx, asGames(gameAddr1), 0)) require.Len(t, workQueue, 1, "should schedule game") // And then attempt to schedule again - require.NoError(t, c.schedule(ctx, asGames(gameAddr1))) + require.NoError(t, c.schedule(ctx, asGames(gameAddr1), 0)) require.Len(t, workQueue, 1, "should not reschedule in-flight game") } func TestExitWhenContextDoneWhileSchedulingJob(t *testing.T) { // No space in buffer to schedule a job - c, workQueue, _, _, _ := setupCoordinatorTest(t, 0) + c, workQueue, _, _, _, _ := setupCoordinatorTest(t, 0) gameAddr1 := common.Address{0xaa} ctx, cancel := context.WithCancel(context.Background()) cancel() // Context is cancelled // Should not block because the context is done. - err := c.schedule(ctx, asGames(gameAddr1)) + err := c.schedule(ctx, asGames(gameAddr1), 0) require.ErrorIs(t, err, context.Canceled) require.Empty(t, workQueue, "should not have been able to schedule game") } +func TestSchedule_PrestateValidationErrors(t *testing.T) { + c, _, _, games, _, _ := setupCoordinatorTest(t, 10) + games.PrestateErr = types.ErrInvalidPrestate + gameAddr1 := common.Address{0xaa} + ctx := context.Background() + + err := c.schedule(ctx, asGames(gameAddr1), 0) + require.Error(t, err) +} + +func TestSchedule_SkipPrestateValidationErrors(t *testing.T) { + c, _, _, games, _, logs := setupCoordinatorTest(t, 10) + c.allowInvalidPrestate = true + games.PrestateErr = types.ErrInvalidPrestate + gameAddr1 := common.Address{0xaa} + ctx := context.Background() + + err := c.schedule(ctx, asGames(gameAddr1), 0) + require.NoError(t, err) + errLog := logs.FindLog(testlog.NewLevelFilter(log.LevelError), testlog.NewMessageFilter("Invalid prestate")) + require.NotNil(t, errLog) + require.Equal(t, errLog.AttrValue("game"), gameAddr1) + require.Equal(t, errLog.AttrValue("err"), games.PrestateErr) +} + +func TestSchedule_PrestateValidationFailure(t *testing.T) { + c, _, _, games, _, _ := setupCoordinatorTest(t, 10) + c.allowInvalidPrestate = true + games.PrestateErr = fmt.Errorf("failed to fetch prestate") + gameAddr1 := common.Address{0xaa} + ctx := context.Background() + + err := c.schedule(ctx, asGames(gameAddr1), 0) + require.ErrorIs(t, err, games.PrestateErr) +} + func TestScheduleGameAgainAfterCompletion(t *testing.T) { - c, workQueue, _, _, _ := setupCoordinatorTest(t, 10) + c, workQueue, _, _, _, _ := setupCoordinatorTest(t, 10) gameAddr1 := common.Address{0xaa} ctx := context.Background() // Schedule the game once - require.NoError(t, c.schedule(ctx, asGames(gameAddr1))) + require.NoError(t, c.schedule(ctx, asGames(gameAddr1), 0)) require.Len(t, workQueue, 1, "should schedule game") // Read the job @@ -80,18 +115,18 @@ func TestScheduleGameAgainAfterCompletion(t *testing.T) { require.NoError(t, c.processResult(j)) // And then attempt to schedule again - require.NoError(t, c.schedule(ctx, asGames(gameAddr1))) + require.NoError(t, c.schedule(ctx, asGames(gameAddr1), 0)) require.Len(t, workQueue, 1, "should reschedule completed game") } func TestResultForUnknownGame(t *testing.T) { - c, _, _, _, _ := setupCoordinatorTest(t, 10) + c, _, _, _, _, _ := setupCoordinatorTest(t, 10) err := c.processResult(job{addr: common.Address{0xaa}}) require.ErrorIs(t, err, errUnknownGame) } func TestProcessResultsWhileJobQueueFull(t *testing.T) { - c, workQueue, resultQueue, games, disk := setupCoordinatorTest(t, 0) + c, workQueue, resultQueue, games, disk, _ := setupCoordinatorTest(t, 0) gameAddr1 := common.Address{0xaa} gameAddr2 := common.Address{0xbb} gameAddr3 := common.Address{0xcc} @@ -114,7 +149,7 @@ func TestProcessResultsWhileJobQueueFull(t *testing.T) { // Even though work queue length is only 1, should be able to schedule all three games // by reading and processing results - require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2, gameAddr3))) + require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2, gameAddr3), 0)) require.Len(t, games.created, 3, "should have created 3 games") loop: @@ -133,14 +168,14 @@ loop: } func TestDeleteDataForResolvedGames(t *testing.T) { - c, workQueue, _, _, disk := setupCoordinatorTest(t, 10) + c, workQueue, _, _, disk, _ := setupCoordinatorTest(t, 10) gameAddr1 := common.Address{0xaa} gameAddr2 := common.Address{0xbb} gameAddr3 := common.Address{0xcc} ctx := context.Background() // First get game 3 marked as resolved - require.NoError(t, c.schedule(ctx, asGames(gameAddr3))) + require.NoError(t, c.schedule(ctx, asGames(gameAddr3), 0)) require.Len(t, workQueue, 1) j := <-workQueue j.status = types.GameStatusDefenderWon @@ -149,7 +184,7 @@ func TestDeleteDataForResolvedGames(t *testing.T) { disk.DirForGame(gameAddr3) games := asGames(gameAddr1, gameAddr2, gameAddr3) - require.NoError(t, c.schedule(ctx, games)) + require.NoError(t, c.schedule(ctx, games, 0)) // The work queue should only contain jobs for games 1 and 2 // A resolved game should not be scheduled for an update. @@ -172,8 +207,102 @@ func TestDeleteDataForResolvedGames(t *testing.T) { require.True(t, disk.gameDirExists[gameAddr3], "game 3 data should be preserved (inflight)") } +func TestSchedule_RecordActedL1Block(t *testing.T) { + c, workQueue, _, _, _, _ := setupCoordinatorTest(t, 10) + gameAddr3 := common.Address{0xcc} + ctx := context.Background() + + // The first game should be tracked + require.NoError(t, c.schedule(ctx, asGames(gameAddr3), 1)) + + // Process the result + require.Len(t, workQueue, 1) + j := <-workQueue + j.status = types.GameStatusDefenderWon + require.NoError(t, c.processResult(j)) + + // Schedule so that the metric is updated + require.NoError(t, c.schedule(ctx, asGames(gameAddr3), 2)) + + // Verify that the block number is recorded by the metricer as acted upon + require.Equal(t, uint64(1), c.m.(*stubSchedulerMetrics).actedL1Blocks) +} + +func TestSchedule_RecordActedL1BlockMultipleGames(t *testing.T) { + c, workQueue, _, _, _, _ := setupCoordinatorTest(t, 10) + gameAddr1 := common.Address{0xaa} + gameAddr2 := common.Address{0xbb} + gameAddr3 := common.Address{0xcc} + ctx := context.Background() + + games := asGames(gameAddr1, gameAddr2, gameAddr3) + require.NoError(t, c.schedule(ctx, games, 1)) + require.Len(t, workQueue, 3) + + // Game 1 progresses and is still in progress + // Game 2 progresses and is now resolved + // Game 3 hasn't yet progressed (update is still in flight) + var game3Job job + for i := 0; i < len(games); i++ { + require.Equal(t, uint64(0), c.m.(*stubSchedulerMetrics).actedL1Blocks) + j := <-workQueue + if j.addr == gameAddr2 { + j.status = types.GameStatusDefenderWon + } + if j.addr != gameAddr3 { + require.NoError(t, c.processResult(j)) + } else { + game3Job = j + } + } + + // Schedule so that the metric is updated + require.NoError(t, c.schedule(ctx, games, 2)) + + // Verify that block 1 isn't yet complete + require.Equal(t, uint64(0), c.m.(*stubSchedulerMetrics).actedL1Blocks) + + // Complete processing game 3 + require.NoError(t, c.processResult(game3Job)) + + // Schedule so that the metric is updated + require.NoError(t, c.schedule(ctx, games, 3)) + + // Verify that block 1 is now complete + require.Equal(t, uint64(1), c.m.(*stubSchedulerMetrics).actedL1Blocks) +} + +func TestSchedule_RecordActedL1BlockNewGame(t *testing.T) { + c, workQueue, _, _, _, _ := setupCoordinatorTest(t, 10) + gameAddr1 := common.Address{0xaa} + gameAddr2 := common.Address{0xbb} + gameAddr3 := common.Address{0xcc} + ctx := context.Background() + + require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2), 1)) + require.Len(t, workQueue, 2) + + // Game 1 progresses and is still in progress + // Game 2 progresses and is now resolved + // Game 3 doesn't exist yet + for i := 0; i < 2; i++ { + require.Equal(t, uint64(0), c.m.(*stubSchedulerMetrics).actedL1Blocks) + j := <-workQueue + if j.addr == gameAddr2 { + j.status = types.GameStatusDefenderWon + } + require.NoError(t, c.processResult(j)) + } + + // Schedule next block with game 3 now created + require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2, gameAddr3), 2)) + + // Verify that block 1 is now complete + require.Equal(t, uint64(1), c.m.(*stubSchedulerMetrics).actedL1Blocks) +} + func TestDoNotDeleteDataForGameThatFailedToCreatePlayer(t *testing.T) { - c, workQueue, _, games, disk := setupCoordinatorTest(t, 10) + c, workQueue, _, games, disk, _ := setupCoordinatorTest(t, 10) gameAddr1 := common.Address{0xaa} gameAddr2 := common.Address{0xbb} ctx := context.Background() @@ -181,7 +310,7 @@ func TestDoNotDeleteDataForGameThatFailedToCreatePlayer(t *testing.T) { games.creationFails = gameAddr1 gameList := asGames(gameAddr1, gameAddr2) - err := c.schedule(ctx, gameList) + err := c.schedule(ctx, gameList, 0) require.Error(t, err) // Game 1 won't be scheduled because the player failed to be created @@ -195,7 +324,7 @@ func TestDoNotDeleteDataForGameThatFailedToCreatePlayer(t *testing.T) { // Should create player for game 1 next time its scheduled games.creationFails = common.Address{} - require.NoError(t, c.schedule(ctx, gameList)) + require.NoError(t, c.schedule(ctx, gameList, 0)) require.Len(t, workQueue, len(gameList), "should schedule all games") j := <-workQueue @@ -204,7 +333,7 @@ func TestDoNotDeleteDataForGameThatFailedToCreatePlayer(t *testing.T) { } func TestDropOldGameStates(t *testing.T) { - c, workQueue, _, _, _ := setupCoordinatorTest(t, 10) + c, workQueue, _, _, _, _ := setupCoordinatorTest(t, 10) gameAddr1 := common.Address{0xaa} gameAddr2 := common.Address{0xbb} gameAddr3 := common.Address{0xcc} @@ -212,7 +341,7 @@ func TestDropOldGameStates(t *testing.T) { ctx := context.Background() // Start tracking game 1, 2 and 3 - require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2, gameAddr3))) + require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2, gameAddr3), 0)) require.Len(t, workQueue, 3, "should schedule games") // Complete processing of games 1 and 2, leaving 3 in flight @@ -220,7 +349,7 @@ func TestDropOldGameStates(t *testing.T) { require.NoError(t, c.processResult(<-workQueue)) // Next update only has games 2 and 4 - require.NoError(t, c.schedule(ctx, asGames(gameAddr2, gameAddr4))) + require.NoError(t, c.schedule(ctx, asGames(gameAddr2, gameAddr4), 0)) require.NotContains(t, c.states, gameAddr1, "should drop state for game 1") require.Contains(t, c.states, gameAddr2, "should keep state for game 2 (still active)") @@ -228,8 +357,8 @@ func TestDropOldGameStates(t *testing.T) { require.Contains(t, c.states, gameAddr4, "should create state for game 4") } -func setupCoordinatorTest(t *testing.T, bufferSize int) (*coordinator, <-chan job, chan job, *createdGames, *stubDiskManager) { - logger := testlog.Logger(t, log.LvlInfo) +func setupCoordinatorTest(t *testing.T, bufferSize int) (*coordinator, <-chan job, chan job, *createdGames, *stubDiskManager, *testlog.CapturingHandler) { + logger, logs := testlog.CaptureLogger(t, log.LevelInfo) workQueue := make(chan job, bufferSize) resultQueue := make(chan job, bufferSize) games := &createdGames{ @@ -237,8 +366,8 @@ func setupCoordinatorTest(t *testing.T, bufferSize int) (*coordinator, <-chan jo created: make(map[common.Address]*test.StubGamePlayer), } disk := &stubDiskManager{gameDirExists: make(map[common.Address]bool)} - c := newCoordinator(logger, metrics.NoopMetrics, workQueue, resultQueue, games.CreateGame, disk) - return c, workQueue, resultQueue, games, disk + c := newCoordinator(logger, &stubSchedulerMetrics{}, workQueue, resultQueue, games.CreateGame, disk, false) + return c, workQueue, resultQueue, games, disk, logs } type createdGames struct { @@ -246,6 +375,7 @@ type createdGames struct { createCompleted common.Address creationFails common.Address created map[common.Address]*test.StubGamePlayer + PrestateErr error } func (c *createdGames) CreateGame(fdg types.GameMetadata, dir string) (GamePlayer, error) { @@ -265,10 +395,25 @@ func (c *createdGames) CreateGame(fdg types.GameMetadata, dir string) (GamePlaye StatusValue: status, Dir: dir, } + if c.PrestateErr != nil { + game.PrestateErr = c.PrestateErr + } c.created[addr] = game return game, nil } +type stubSchedulerMetrics struct { + actedL1Blocks uint64 +} + +func (s *stubSchedulerMetrics) RecordActedL1Block(n uint64) { + s.actedL1Blocks = n +} + +func (s *stubSchedulerMetrics) RecordGamesStatus(_, _, _ int) {} +func (s *stubSchedulerMetrics) RecordGameUpdateScheduled() {} +func (s *stubSchedulerMetrics) RecordGameUpdateCompleted() {} + type stubDiskManager struct { gameDirExists map[common.Address]bool deletedDirs []common.Address diff --git a/op-challenger/game/scheduler/scheduler.go b/op-challenger/game/scheduler/scheduler.go index b8a1ee6f694b..b0e0e1ebbe52 100644 --- a/op-challenger/game/scheduler/scheduler.go +++ b/op-challenger/game/scheduler/scheduler.go @@ -12,6 +12,7 @@ import ( var ErrBusy = errors.New("busy scheduling previous update") type SchedulerMetricer interface { + RecordActedL1Block(n uint64) RecordGamesStatus(inProgress, defenderWon, challengerWon int) RecordGameUpdateScheduled() RecordGameUpdateCompleted() @@ -21,19 +22,24 @@ type SchedulerMetricer interface { DecIdleExecutors() } +type blockGames struct { + blockNumber uint64 + games []types.GameMetadata +} + type Scheduler struct { logger log.Logger coordinator *coordinator m SchedulerMetricer maxConcurrency uint - scheduleQueue chan []types.GameMetadata + scheduleQueue chan blockGames jobQueue chan job resultQueue chan job wg sync.WaitGroup cancel func() } -func NewScheduler(logger log.Logger, m SchedulerMetricer, disk DiskManager, maxConcurrency uint, createPlayer PlayerCreator) *Scheduler { +func NewScheduler(logger log.Logger, m SchedulerMetricer, disk DiskManager, maxConcurrency uint, createPlayer PlayerCreator, allowInvalidPrestate bool) *Scheduler { // Size job and results queues to be fairly small so backpressure is applied early // but with enough capacity to keep the workers busy jobQueue := make(chan job, maxConcurrency*2) @@ -41,12 +47,12 @@ func NewScheduler(logger log.Logger, m SchedulerMetricer, disk DiskManager, maxC // scheduleQueue has a size of 1 so backpressure quickly propagates to the caller // allowing them to potentially skip update cycles. - scheduleQueue := make(chan []types.GameMetadata, 1) + scheduleQueue := make(chan blockGames, 1) return &Scheduler{ logger: logger, m: m, - coordinator: newCoordinator(logger, m, jobQueue, resultQueue, createPlayer, disk), + coordinator: newCoordinator(logger, m, jobQueue, resultQueue, createPlayer, disk, allowInvalidPrestate), maxConcurrency: maxConcurrency, scheduleQueue: scheduleQueue, jobQueue: jobQueue, @@ -84,9 +90,9 @@ func (s *Scheduler) Close() error { return nil } -func (s *Scheduler) Schedule(games []types.GameMetadata) error { +func (s *Scheduler) Schedule(games []types.GameMetadata, blockNumber uint64) error { select { - case s.scheduleQueue <- games: + case s.scheduleQueue <- blockGames{blockNumber: blockNumber, games: games}: return nil default: return ErrBusy @@ -99,8 +105,8 @@ func (s *Scheduler) loop(ctx context.Context) { select { case <-ctx.Done(): return - case games := <-s.scheduleQueue: - if err := s.coordinator.schedule(ctx, games); err != nil { + case blockGames := <-s.scheduleQueue: + if err := s.coordinator.schedule(ctx, blockGames.games, blockGames.blockNumber); err != nil { s.logger.Error("Failed to schedule game updates", "err", err) } case j := <-s.resultQueue: diff --git a/op-challenger/game/scheduler/scheduler_test.go b/op-challenger/game/scheduler/scheduler_test.go index 3635f1c7b37f..7d02ac9023ee 100644 --- a/op-challenger/game/scheduler/scheduler_test.go +++ b/op-challenger/game/scheduler/scheduler_test.go @@ -14,14 +14,14 @@ import ( ) func TestSchedulerProcessesGames(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) ctx := context.Background() createPlayer := func(g types.GameMetadata, dir string) (GamePlayer, error) { return &test.StubGamePlayer{}, nil } removeExceptCalls := make(chan []common.Address) disk := &trackingDiskManager{removeExceptCalls: removeExceptCalls} - s := NewScheduler(logger, metrics.NoopMetrics, disk, 2, createPlayer) + s := NewScheduler(logger, metrics.NoopMetrics, disk, 2, createPlayer, false) s.Start(ctx) gameAddr1 := common.Address{0xaa} @@ -29,7 +29,7 @@ func TestSchedulerProcessesGames(t *testing.T) { gameAddr3 := common.Address{0xcc} games := asGames(gameAddr1, gameAddr2, gameAddr3) - require.NoError(t, s.Schedule(games)) + require.NoError(t, s.Schedule(games, 0)) // All jobs should be executed and completed, the last step being to clean up disk resources for i := 0; i < len(games); i++ { @@ -43,19 +43,19 @@ func TestSchedulerProcessesGames(t *testing.T) { } func TestReturnBusyWhenScheduleQueueFull(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) createPlayer := func(game types.GameMetadata, dir string) (GamePlayer, error) { return &test.StubGamePlayer{}, nil } removeExceptCalls := make(chan []common.Address) disk := &trackingDiskManager{removeExceptCalls: removeExceptCalls} - s := NewScheduler(logger, metrics.NoopMetrics, disk, 2, createPlayer) + s := NewScheduler(logger, metrics.NoopMetrics, disk, 2, createPlayer, false) // Scheduler not started - first call fills the queue - require.NoError(t, s.Schedule(asGames(common.Address{0xaa}))) + require.NoError(t, s.Schedule(asGames(common.Address{0xaa}), 0)) // Second call should return busy - err := s.Schedule(asGames(common.Address{0xaa})) + err := s.Schedule(asGames(common.Address{0xaa}), 0) require.ErrorIs(t, err, ErrBusy) } diff --git a/op-challenger/game/scheduler/test/stub_player.go b/op-challenger/game/scheduler/test/stub_player.go index b465d0c34f0c..fd1e325d6eed 100644 --- a/op-challenger/game/scheduler/test/stub_player.go +++ b/op-challenger/game/scheduler/test/stub_player.go @@ -12,6 +12,11 @@ type StubGamePlayer struct { ProgressCount int StatusValue types.GameStatus Dir string + PrestateErr error +} + +func (g *StubGamePlayer) ValidatePrestate(_ context.Context) error { + return g.PrestateErr } func (g *StubGamePlayer) ProgressGame(_ context.Context) types.GameStatus { diff --git a/op-challenger/game/scheduler/types.go b/op-challenger/game/scheduler/types.go index 8228401fe6c6..8eccbc10f068 100644 --- a/op-challenger/game/scheduler/types.go +++ b/op-challenger/game/scheduler/types.go @@ -9,6 +9,7 @@ import ( ) type GamePlayer interface { + ValidatePrestate(ctx context.Context) error ProgressGame(ctx context.Context) types.GameStatus Status() types.GameStatus } @@ -19,7 +20,17 @@ type DiskManager interface { } type job struct { + block uint64 addr common.Address player GamePlayer status types.GameStatus } + +func newJob(block uint64, addr common.Address, player GamePlayer, status types.GameStatus) *job { + return &job{ + block: block, + addr: addr, + player: player, + status: status, + } +} diff --git a/op-challenger/game/scheduler/worker_test.go b/op-challenger/game/scheduler/worker_test.go index 330c553dde9d..976893671430 100644 --- a/op-challenger/game/scheduler/worker_test.go +++ b/op-challenger/game/scheduler/worker_test.go @@ -3,6 +3,7 @@ package scheduler import ( "context" "sync" + "sync/atomic" "testing" "time" @@ -28,21 +29,21 @@ func TestWorkerShouldProcessJobsUntilContextDone(t *testing.T) { player: &test.StubGamePlayer{StatusValue: types.GameStatusInProgress}, } waitErr := wait.For(context.Background(), 100*time.Millisecond, func() (bool, error) { - return ms.activeCalls >= 1, nil + return ms.activeCalls.Load() >= 1, nil }) require.NoError(t, waitErr) - require.Equal(t, ms.activeCalls, 1) - require.Equal(t, ms.idleCalls, 1) + require.EqualValues(t, ms.activeCalls.Load(), 1) + require.EqualValues(t, ms.idleCalls.Load(), 1) in <- job{ player: &test.StubGamePlayer{StatusValue: types.GameStatusDefenderWon}, } waitErr = wait.For(context.Background(), 100*time.Millisecond, func() (bool, error) { - return ms.activeCalls >= 2, nil + return ms.activeCalls.Load() >= 2, nil }) require.NoError(t, waitErr) - require.Equal(t, ms.activeCalls, 2) - require.Equal(t, ms.idleCalls, 2) + require.EqualValues(t, ms.activeCalls.Load(), 2) + require.EqualValues(t, ms.idleCalls.Load(), 2) result1 := readWithTimeout(t, out) result2 := readWithTimeout(t, out) @@ -56,16 +57,16 @@ func TestWorkerShouldProcessJobsUntilContextDone(t *testing.T) { } type metricSink struct { - activeCalls int - idleCalls int + activeCalls atomic.Int32 + idleCalls atomic.Int32 } func (m *metricSink) ThreadActive() { - m.activeCalls++ + m.activeCalls.Add(1) } func (m *metricSink) ThreadIdle() { - m.idleCalls++ + m.idleCalls.Add(1) } func readWithTimeout[T any](t *testing.T, ch <-chan T) T { diff --git a/op-challenger/game/service.go b/op-challenger/game/service.go index 986e950ee2da..34d51261b733 100644 --- a/op-challenger/game/service.go +++ b/op-challenger/game/service.go @@ -4,23 +4,33 @@ import ( "context" "errors" "fmt" + "io" + "sync/atomic" + + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/fetcher" + "github.com/ethereum-optimism/optimism/op-challenger/sender" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" - "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/game/fault" - "github.com/ethereum-optimism/optimism/op-challenger/game/loader" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/claims" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" "github.com/ethereum-optimism/optimism/op-challenger/game/registry" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-challenger/version" - opClient "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/clock" "github.com/ethereum-optimism/optimism/op-service/dial" "github.com/ethereum-optimism/optimism/op-service/httputil" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/oppprof" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/txmgr" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/log" ) type Service struct { @@ -29,101 +39,282 @@ type Service struct { monitor *gameMonitor sched *scheduler.Scheduler - pprofSrv *httputil.HTTPServer - metricsSrv *httputil.HTTPServer + faultGamesCloser fault.CloseFunc + + preimages *keccak.LargePreimageScheduler + + txMgr *txmgr.SimpleTxManager + txSender *sender.TxSender + + cl *clock.SimpleClock + + claimants []common.Address + claimer *claims.BondClaimScheduler + + factoryContract *contracts.DisputeGameFactoryContract + registry *registry.GameTypeRegistry + oracles *registry.OracleRegistry + rollupClient *sources.RollupClient + + l1Client *ethclient.Client + pollClient client.RPC + + pprofService *oppprof.Service + metricsSrv *httputil.HTTPServer + + balanceMetricer io.Closer + + stopped atomic.Bool } -func (s *Service) Stop(ctx context.Context) error { - var result error - if s.sched != nil { - result = errors.Join(result, s.sched.Close()) +// NewService creates a new Service. +func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*Service, error) { + s := &Service{ + cl: clock.NewSimpleClock(), + logger: logger, + metrics: metrics.NewMetrics(), } - if s.pprofSrv != nil { - result = errors.Join(result, s.pprofSrv.Stop(ctx)) + + if err := s.initFromConfig(ctx, cfg); err != nil { + // upon initialization error we can try to close any of the service components that may have started already. + return nil, errors.Join(fmt.Errorf("failed to init challenger game service: %w", err), s.Stop(ctx)) } - if s.metricsSrv != nil { - result = errors.Join(result, s.metricsSrv.Stop(ctx)) + + return s, nil +} + +func (s *Service) initFromConfig(ctx context.Context, cfg *config.Config) error { + if err := s.initTxManager(ctx, cfg); err != nil { + return fmt.Errorf("failed to init tx manager: %w", err) } - return result + s.initClaimants(cfg) + if err := s.initL1Client(ctx, cfg); err != nil { + return fmt.Errorf("failed to init l1 client: %w", err) + } + if err := s.initRollupClient(ctx, cfg); err != nil { + return fmt.Errorf("failed to init rollup client: %w", err) + } + if err := s.initPollClient(ctx, cfg); err != nil { + return fmt.Errorf("failed to init poll client: %w", err) + } + if err := s.initPProf(&cfg.PprofConfig); err != nil { + return fmt.Errorf("failed to init profiling: %w", err) + } + if err := s.initMetricsServer(&cfg.MetricsConfig); err != nil { + return fmt.Errorf("failed to init metrics server: %w", err) + } + if err := s.initFactoryContract(cfg); err != nil { + return fmt.Errorf("failed to create factory contract bindings: %w", err) + } + if err := s.registerGameTypes(ctx, cfg); err != nil { + return fmt.Errorf("failed to register game types: %w", err) + } + if err := s.initBondClaims(); err != nil { + return fmt.Errorf("failed to init bond claiming: %w", err) + } + if err := s.initScheduler(cfg); err != nil { + return fmt.Errorf("failed to init scheduler: %w", err) + } + if err := s.initLargePreimages(); err != nil { + return fmt.Errorf("failed to init large preimage scheduler: %w", err) + } + + s.initMonitor(cfg) + + s.metrics.RecordInfo(version.SimpleWithMeta) + s.metrics.RecordUp() + return nil } -// NewService creates a new Service. -func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*Service, error) { - cl := clock.SystemClock - m := metrics.NewMetrics() - txMgr, err := txmgr.NewSimpleTxManager("challenger", logger, &m.TxMetrics, cfg.TxMgrConfig) +func (s *Service) initClaimants(cfg *config.Config) { + claimants := []common.Address{s.txSender.From()} + s.claimants = append(claimants, cfg.AdditionalBondClaimants...) +} + +func (s *Service) initTxManager(ctx context.Context, cfg *config.Config) error { + txMgr, err := txmgr.NewSimpleTxManager("challenger", s.logger, s.metrics, cfg.TxMgrConfig) if err != nil { - return nil, fmt.Errorf("failed to create the transaction manager: %w", err) + return fmt.Errorf("failed to create the transaction manager: %w", err) } + s.txMgr = txMgr + s.txSender = sender.NewTxSender(ctx, s.logger, txMgr, cfg.MaxPendingTx) + return nil +} - l1Client, err := dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, logger, cfg.L1EthRpc) +func (s *Service) initL1Client(ctx context.Context, cfg *config.Config) error { + l1Client, err := dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, s.logger, cfg.L1EthRpc) if err != nil { - return nil, fmt.Errorf("failed to dial L1: %w", err) + return fmt.Errorf("failed to dial L1: %w", err) } + s.l1Client = l1Client + return nil +} - s := &Service{ - logger: logger, - metrics: m, +func (s *Service) initPollClient(ctx context.Context, cfg *config.Config) error { + pollClient, err := client.NewRPCWithClient(ctx, s.logger, cfg.L1EthRpc, client.NewBaseRPCClient(s.l1Client.Client()), cfg.PollInterval) + if err != nil { + return fmt.Errorf("failed to create RPC client: %w", err) } + s.pollClient = pollClient + return nil +} - pprofConfig := cfg.PprofConfig - if pprofConfig.Enabled { - logger.Debug("starting pprof", "addr", pprofConfig.ListenAddr, "port", pprofConfig.ListenPort) - pprofSrv, err := oppprof.StartServer(pprofConfig.ListenAddr, pprofConfig.ListenPort) - if err != nil { - return nil, errors.Join(fmt.Errorf("failed to start pprof server: %w", err), s.Stop(ctx)) - } - s.pprofSrv = pprofSrv - logger.Info("started pprof server", "addr", pprofSrv.Addr()) +func (s *Service) initPProf(cfg *oppprof.CLIConfig) error { + s.pprofService = oppprof.New( + cfg.ListenEnabled, + cfg.ListenAddr, + cfg.ListenPort, + cfg.ProfileType, + cfg.ProfileDir, + cfg.ProfileFilename, + ) + + if err := s.pprofService.Start(); err != nil { + return fmt.Errorf("failed to start pprof service: %w", err) } - metricsCfg := cfg.MetricsConfig - if metricsCfg.Enabled { - logger.Debug("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort) - metricsSrv, err := m.Start(metricsCfg.ListenAddr, metricsCfg.ListenPort) - if err != nil { - return nil, errors.Join(fmt.Errorf("failed to start metrics server: %w", err), s.Stop(ctx)) - } - logger.Info("started metrics server", "addr", metricsSrv.Addr()) - s.metricsSrv = metricsSrv - m.StartBalanceMetrics(ctx, logger, l1Client, txMgr.From()) + return nil +} + +func (s *Service) initMetricsServer(cfg *opmetrics.CLIConfig) error { + if !cfg.Enabled { + return nil + } + s.logger.Debug("starting metrics server", "addr", cfg.ListenAddr, "port", cfg.ListenPort) + m, ok := s.metrics.(opmetrics.RegistryMetricer) + if !ok { + return fmt.Errorf("metrics were enabled, but metricer %T does not expose registry for metrics-server", s.metrics) + } + metricsSrv, err := opmetrics.StartServer(m.Registry(), cfg.ListenAddr, cfg.ListenPort) + if err != nil { + return fmt.Errorf("failed to start metrics server: %w", err) } + s.logger.Info("started metrics server", "addr", metricsSrv.Addr()) + s.metricsSrv = metricsSrv + s.balanceMetricer = s.metrics.StartBalanceMetrics(s.logger, s.l1Client, s.txSender.From()) + return nil +} - factoryContract, err := bindings.NewDisputeGameFactory(cfg.GameFactoryAddress, l1Client) +func (s *Service) initFactoryContract(cfg *config.Config) error { + factoryContract, err := contracts.NewDisputeGameFactoryContract(cfg.GameFactoryAddress, + batching.NewMultiCaller(s.l1Client.Client(), batching.DefaultBatchSize)) if err != nil { - return nil, errors.Join(fmt.Errorf("failed to bind the fault dispute game factory contract: %w", err), s.Stop(ctx)) + return fmt.Errorf("failed to bind the fault dispute game factory contract: %w", err) } - loader := loader.NewGameLoader(factoryContract) + s.factoryContract = factoryContract + return nil +} - gameTypeRegistry := registry.NewGameTypeRegistry() - fault.RegisterGameTypes(gameTypeRegistry, ctx, logger, m, cfg, txMgr, l1Client) +func (s *Service) initBondClaims() error { + claimer := claims.NewBondClaimer(s.logger, s.metrics, s.registry.CreateBondContract, s.txSender, s.claimants...) + s.claimer = claims.NewBondClaimScheduler(s.logger, s.metrics, claimer) + return nil +} - disk := newDiskManager(cfg.Datadir) - s.sched = scheduler.NewScheduler( - logger, - m, - disk, - cfg.MaxConcurrency, - gameTypeRegistry.CreatePlayer) - - pollClient, err := opClient.NewRPCWithClient(ctx, logger, cfg.L1EthRpc, opClient.NewBaseRPCClient(l1Client.(*ethclient.Client).Client()), cfg.PollInterval) +func (s *Service) initRollupClient(ctx context.Context, cfg *config.Config) error { + if cfg.RollupRpc == "" { + return nil + } + rollupClient, err := dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, s.logger, cfg.RollupRpc) if err != nil { - return nil, errors.Join(fmt.Errorf("failed to create RPC client: %w", err), s.Stop(ctx)) + return err } - s.monitor = newGameMonitor(logger, cl, loader, s.sched, cfg.GameWindow, l1Client.BlockNumber, cfg.GameAllowlist, pollClient) + s.rollupClient = rollupClient + return nil +} - m.RecordInfo(version.SimpleWithMeta) - m.RecordUp() +func (s *Service) registerGameTypes(ctx context.Context, cfg *config.Config) error { + gameTypeRegistry := registry.NewGameTypeRegistry() + oracles := registry.NewOracleRegistry() + caller := batching.NewMultiCaller(s.l1Client.Client(), batching.DefaultBatchSize) + closer, err := fault.RegisterGameTypes(ctx, s.cl, s.logger, s.metrics, cfg, gameTypeRegistry, oracles, s.rollupClient, s.txSender, s.factoryContract, caller, s.l1Client, cfg.SelectiveClaimResolution, s.claimants) + if err != nil { + return err + } + s.faultGamesCloser = closer + s.registry = gameTypeRegistry + s.oracles = oracles + return nil +} - return s, nil +func (s *Service) initScheduler(cfg *config.Config) error { + disk := newDiskManager(cfg.Datadir) + s.sched = scheduler.NewScheduler(s.logger, s.metrics, disk, cfg.MaxConcurrency, s.registry.CreatePlayer, cfg.AllowInvalidPrestate) + return nil +} + +func (s *Service) initLargePreimages() error { + fetcher := fetcher.NewPreimageFetcher(s.logger, s.l1Client) + verifier := keccak.NewPreimageVerifier(s.logger, fetcher) + challenger := keccak.NewPreimageChallenger(s.logger, s.metrics, verifier, s.txSender) + s.preimages = keccak.NewLargePreimageScheduler(s.logger, s.cl, s.oracles, challenger) + return nil } -// MonitorGame monitors the fault dispute game and attempts to progress it. -func (s *Service) MonitorGame(ctx context.Context) error { +func (s *Service) initMonitor(cfg *config.Config) { + s.monitor = newGameMonitor(s.logger, s.cl, s.factoryContract, s.sched, s.preimages, cfg.GameWindow, s.claimer, s.l1Client.BlockNumber, cfg.GameAllowlist, s.pollClient) +} + +func (s *Service) Start(ctx context.Context) error { + s.logger.Info("starting scheduler") s.sched.Start(ctx) - err := s.monitor.MonitorGames(ctx) - // The other ctx is the close-trigger. - // We need to refactor Service more to allow for graceful/force-shutdown granularity. - err = errors.Join(err, s.Stop(context.Background())) - return err + s.claimer.Start(ctx) + s.preimages.Start(ctx) + s.logger.Info("starting monitoring") + s.monitor.StartMonitoring() + s.logger.Info("challenger game service start completed") + return nil +} + +func (s *Service) Stopped() bool { + return s.stopped.Load() +} + +func (s *Service) Stop(ctx context.Context) error { + s.logger.Info("stopping challenger game service") + + var result error + if s.sched != nil { + if err := s.sched.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close scheduler: %w", err)) + } + } + if s.monitor != nil { + s.monitor.StopMonitoring() + } + if s.faultGamesCloser != nil { + s.faultGamesCloser() + } + if s.pprofService != nil { + if err := s.pprofService.Stop(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close pprof server: %w", err)) + } + } + if s.balanceMetricer != nil { + if err := s.balanceMetricer.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err)) + } + } + + if s.txMgr != nil { + s.txMgr.Close() + } + + if s.rollupClient != nil { + s.rollupClient.Close() + } + if s.pollClient != nil { + s.pollClient.Close() + } + if s.l1Client != nil { + s.l1Client.Close() + } + if s.metricsSrv != nil { + if err := s.metricsSrv.Stop(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close metrics server: %w", err)) + } + } + s.stopped.Store(true) + s.logger.Info("stopped challenger game service", "err", result) + return result } diff --git a/op-challenger/game/types/types.go b/op-challenger/game/types/types.go index d69c757b27b3..5e831e73f9ca 100644 --- a/op-challenger/game/types/types.go +++ b/op-challenger/game/types/types.go @@ -1,11 +1,16 @@ package types import ( + "errors" "fmt" + "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" ) +var ErrInvalidPrestate = errors.New("absolute prestate does not match") + type GameStatus uint8 const ( @@ -37,7 +42,12 @@ func GameStatusFromUint8(i uint8) (GameStatus, error) { } type GameMetadata struct { - GameType uint8 + GameType uint32 Timestamp uint64 Proxy common.Address } + +type TxSender interface { + From() common.Address + SendAndWait(txPurpose string, txs ...txmgr.TxCandidate) ([]*ethtypes.Receipt, error) +} diff --git a/op-challenger/metrics/metrics.go b/op-challenger/metrics/metrics.go index 85a722201d2f..9383a45fedc2 100644 --- a/op-challenger/metrics/metrics.go +++ b/op-challenger/metrics/metrics.go @@ -1,10 +1,11 @@ package metrics import ( - "context" + "io" - "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/sources/caching" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" "github.com/prometheus/client_golang/prometheus" @@ -19,13 +20,26 @@ type Metricer interface { RecordInfo(version string) RecordUp() + StartBalanceMetrics(l log.Logger, client *ethclient.Client, account common.Address) io.Closer + // Record Tx metrics txmetrics.TxMetricer + // Record cache metrics + caching.Metrics + + RecordActedL1Block(n uint64) + RecordGameStep() RecordGameMove() RecordCannonExecutionTime(t float64) + RecordPreimageChallenged() + RecordPreimageChallengeFailed() + + RecordBondClaimFailed() + RecordBondClaimed(amount uint64) + RecordGamesStatus(inProgress, defenderWon, challengerWon int) RecordGameUpdateScheduled() @@ -37,6 +51,9 @@ type Metricer interface { DecIdleExecutors() } +// Metrics implementation must implement RegistryMetricer to allow the metrics server to work. +var _ opmetrics.RegistryMetricer = (*Metrics)(nil) + type Metrics struct { ns string registry *prometheus.Registry @@ -44,11 +61,21 @@ type Metrics struct { txmetrics.TxMetrics + *opmetrics.CacheMetrics + info prometheus.GaugeVec up prometheus.Gauge executors prometheus.GaugeVec + bondClaimFailures prometheus.Counter + bondsClaimed prometheus.Counter + + preimageChallenged prometheus.Counter + preimageChallengeFailed prometheus.Counter + + highestActedL1Block prometheus.Gauge + moves prometheus.Counter steps prometheus.Counter @@ -58,6 +85,10 @@ type Metrics struct { inflightGames prometheus.Gauge } +func (m *Metrics) Registry() *prometheus.Registry { + return m.registry +} + var _ Metricer = (*Metrics)(nil) func NewMetrics() *Metrics { @@ -71,6 +102,8 @@ func NewMetrics() *Metrics { TxMetrics: txmetrics.MakeTxMetrics(Namespace, factory), + CacheMetrics: opmetrics.NewCacheMetrics(factory, Namespace, "provider_cache", "Provider cache"), + info: *factory.NewGaugeVec(prometheus.GaugeOpts{ Namespace: Namespace, Name: "info", @@ -108,6 +141,26 @@ func NewMetrics() *Metrics { []float64{1.0, 10.0}, prometheus.ExponentialBuckets(30.0, 2.0, 14)...), }), + bondClaimFailures: factory.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, + Name: "claim_failures", + Help: "Number of bond claims that failed", + }), + bondsClaimed: factory.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, + Name: "bonds", + Help: "Number of bonds claimed by the challenge agent", + }), + preimageChallenged: factory.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, + Name: "preimage_challenged", + Help: "Number of preimages challenged by the challenger", + }), + preimageChallengeFailed: factory.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, + Name: "preimage_challenge_failed", + Help: "Number of preimage challenges that failed", + }), trackedGames: *factory.NewGaugeVec(prometheus.GaugeOpts{ Namespace: Namespace, Name: "tracked_games", @@ -115,6 +168,11 @@ func NewMetrics() *Metrics { }, []string{ "status", }), + highestActedL1Block: factory.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, + Name: "highest_acted_l1_block", + Help: "Highest L1 block acted on by the challenger", + }), inflightGames: factory.NewGauge(prometheus.GaugeOpts{ Namespace: Namespace, Name: "inflight_games", @@ -127,13 +185,12 @@ func (m *Metrics) Start(host string, port int) (*httputil.HTTPServer, error) { return opmetrics.StartServer(m.registry, host, port) } -func (m *Metrics) StartBalanceMetrics(ctx context.Context, l log.Logger, client client.Client, account common.Address) { - // TODO(7684): util was refactored to close, but ctx is still being used by caller for shutdown - balanceMetric := opmetrics.LaunchBalanceMetrics(l, m.registry, m.ns, client, account) - go func() { - <-ctx.Done() - _ = balanceMetric.Close() - }() +func (m *Metrics) StartBalanceMetrics( + l log.Logger, + client *ethclient.Client, + account common.Address, +) io.Closer { + return opmetrics.LaunchBalanceMetrics(l, m.registry, m.ns, client, account) } // RecordInfo sets a pseudo-metric that contains versioning and @@ -160,6 +217,22 @@ func (m *Metrics) RecordGameStep() { m.steps.Add(1) } +func (m *Metrics) RecordPreimageChallenged() { + m.preimageChallenged.Add(1) +} + +func (m *Metrics) RecordPreimageChallengeFailed() { + m.preimageChallengeFailed.Add(1) +} + +func (m *Metrics) RecordBondClaimFailed() { + m.bondClaimFailures.Add(1) +} + +func (m *Metrics) RecordBondClaimed(amount uint64) { + m.bondsClaimed.Add(float64(amount)) +} + func (m *Metrics) RecordCannonExecutionTime(t float64) { m.cannonExecutionTime.Observe(t) } @@ -186,6 +259,10 @@ func (m *Metrics) RecordGamesStatus(inProgress, defenderWon, challengerWon int) m.trackedGames.WithLabelValues("challenger_won").Set(float64(challengerWon)) } +func (m *Metrics) RecordActedL1Block(n uint64) { + m.highestActedL1Block.Set(float64(n)) +} + func (m *Metrics) RecordGameUpdateScheduled() { m.inflightGames.Add(1) } diff --git a/op-challenger/metrics/noop.go b/op-challenger/metrics/noop.go index 9737a5d7ccd3..e14620ef320d 100644 --- a/op-challenger/metrics/noop.go +++ b/op-challenger/metrics/noop.go @@ -1,6 +1,12 @@ package metrics import ( + "io" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" ) @@ -8,6 +14,10 @@ type NoopMetricsImpl struct { txmetrics.NoopTxMetrics } +func (i *NoopMetricsImpl) StartBalanceMetrics(l log.Logger, client *ethclient.Client, account common.Address) io.Closer { + return nil +} + var NoopMetrics Metricer = new(NoopMetricsImpl) func (*NoopMetricsImpl) RecordInfo(version string) {} @@ -16,6 +26,14 @@ func (*NoopMetricsImpl) RecordUp() {} func (*NoopMetricsImpl) RecordGameMove() {} func (*NoopMetricsImpl) RecordGameStep() {} +func (*NoopMetricsImpl) RecordActedL1Block(_ uint64) {} + +func (*NoopMetricsImpl) RecordPreimageChallenged() {} +func (*NoopMetricsImpl) RecordPreimageChallengeFailed() {} + +func (*NoopMetricsImpl) RecordBondClaimFailed() {} +func (*NoopMetricsImpl) RecordBondClaimed(uint64) {} + func (*NoopMetricsImpl) RecordCannonExecutionTime(t float64) {} func (*NoopMetricsImpl) RecordGamesStatus(inProgress, defenderWon, challengerWon int) {} @@ -27,3 +45,6 @@ func (*NoopMetricsImpl) IncActiveExecutors() {} func (*NoopMetricsImpl) DecActiveExecutors() {} func (*NoopMetricsImpl) IncIdleExecutors() {} func (*NoopMetricsImpl) DecIdleExecutors() {} + +func (*NoopMetricsImpl) CacheAdd(_ string, _ int, _ bool) {} +func (*NoopMetricsImpl) CacheGet(_ string, _ bool) {} diff --git a/op-challenger/scripts/alphabet/charlie.sh b/op-challenger/scripts/alphabet/charlie.sh deleted file mode 100755 index 526fb15876c9..000000000000 --- a/op-challenger/scripts/alphabet/charlie.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SOURCE_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) -CHALLENGER_DIR=$(echo ${SOURCE_DIR%/*/*}) -MONOREPO_DIR=$(echo ${SOURCE_DIR%/*/*/*}) - -# Check that the fault game address file exists -FAULT_GAME_ADDR_FILE="$CHALLENGER_DIR/.fault-game-address" -if [[ ! -f "$FAULT_GAME_ADDR_FILE" ]]; then - echo "Game not initialized, exiting..." - exit 1 -fi - -# Charlie's Address: 0xF45B7537828CB2fffBC69996B054c2Aaf36DC778 -CHARLIE_KEY="74feb147d72bfae943e6b4e483410933d9e447d5dc47d52432dcc2c1454dabb7" - -DISPUTE_GAME_PROXY=$(jq -r .DisputeGameFactoryProxy $MONOREPO_DIR/.devnet/addresses.json) -FAULT_GAME_ADDRESS=$(cat $FAULT_GAME_ADDR_FILE) -echo "Fault dispute game address: $FAULT_GAME_ADDRESS" - -DATADIR=`mktemp -d` -trap cleanup SIGINT -cleanup(){ - rm -rf "${DATADIR}" -} - -$CHALLENGER_DIR/bin/op-challenger \ - --l1-eth-rpc http://localhost:8545 \ - --trace-type="alphabet" \ - --alphabet "abcdefgh" \ - --datadir "${DATADIR}" \ - --game-factory-address $DISPUTE_GAME_PROXY \ - --game-allowlist $FAULT_GAME_ADDRESS \ - --private-key $CHARLIE_KEY \ - --num-confirmations 1 \ - --metrics.enabled --metrics.port=7304 \ - --pprof.enabled --pprof.port=6064 \ - --agree-with-proposed-output=true diff --git a/op-challenger/scripts/alphabet/init_game.sh b/op-challenger/scripts/alphabet/init_game.sh deleted file mode 100755 index 5a0db7b02540..000000000000 --- a/op-challenger/scripts/alphabet/init_game.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -SOURCE_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) -CHALLENGER_DIR=$(echo ${SOURCE_DIR%/*/*}) -MONOREPO_DIR=$(echo ${SOURCE_DIR%/*/*/*}) - -cd $CHALLENGER_DIR -make - -cd $MONOREPO_DIR -make devnet-clean -make cannon-prestate -make devnet-up - -DEVNET_SPONSOR="ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -DISPUTE_GAME_FACTORY=$(jq -r .DisputeGameFactoryProxy $MONOREPO_DIR/.devnet/addresses.json) - -echo "----------------------------------------------------------------" -echo " Dispute Game Factory at $DISPUTE_GAME_FACTORY" -echo "----------------------------------------------------------------" - -L2_OUTPUT_ORACLE_PROXY=$(jq -r .L2OutputOracleProxy $MONOREPO_DIR/.devnet/addresses.json) - -echo "----------------------------------------------------------------" -echo " L2 Output Oracle Proxy at $L2_OUTPUT_ORACLE_PROXY" -echo "----------------------------------------------------------------" - -BLOCK_ORACLE_PROXY=$(jq -r .BlockOracle $MONOREPO_DIR/.devnet/addresses.json) - -echo "----------------------------------------------------------------" -echo " Block Oracle Proxy at $BLOCK_ORACLE_PROXY" -echo "----------------------------------------------------------------" - -CHARLIE_ADDRESS="0xF45B7537828CB2fffBC69996B054c2Aaf36DC778" -CHARLIE_KEY="74feb147d72bfae943e6b4e483410933d9e447d5dc47d52432dcc2c1454dabb7" - -MALLORY_ADDRESS="0x4641c704a6c743f73ee1f36C7568Fbf4b80681e4" -MALLORY_KEY="28d7045146193f5f4eeb151c4843544b1b0d30a7ac1680c845a416fac65a7715" - -echo "----------------------------------------------------------------" -echo " - Fetching balance of the sponsor" -echo " - Balance: $(cast balance 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)" -echo "----------------------------------------------------------------" - -echo "Funding Charlie" -cast send $CHARLIE_ADDRESS --value 5ether --private-key $DEVNET_SPONSOR - -echo "Funding Mallory" -cast send $MALLORY_ADDRESS --value 5ether --private-key $DEVNET_SPONSOR - -# Loop and wait until there are at least 2 outputs in the l2 output oracle -echo "Waiting until 2 output proposals are in the l2 output oracle..." -echo "NOTE: This may show errors if no output proposals are in the oracle yet." -while [[ $(cast call $L2_OUTPUT_ORACLE_PROXY "latestOutputIndex()" | cast to-dec) -lt 2 ]] -do - echo "[BLOCK: $(cast block-number)] Waiting for output proposals..." - sleep 2 -done - -# Root claim commits to the entire trace. -# Alphabet game claim construction: keccak256(abi.encode(trace_index, trace[trace_index])) -ROOT_CLAIM=$(cast keccak $(cast abi-encode "f(uint256,uint256)" 15 122)) -# Replace the first byte of the claim with the invalid vm status indicator -ROOT_CLAIM="0x01${ROOT_CLAIM:4:60}" - -GAME_TYPE=255 ${SOURCE_DIR}/../create_game.sh http://localhost:8545 "${DISPUTE_GAME_FACTORY}" "${ROOT_CLAIM}" --private-key "${DEVNET_SPONSOR}" diff --git a/op-challenger/scripts/alphabet/mallory.sh b/op-challenger/scripts/alphabet/mallory.sh deleted file mode 100755 index 55f46d4ed2fc..000000000000 --- a/op-challenger/scripts/alphabet/mallory.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SOURCE_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) -CHALLENGER_DIR=$(echo ${SOURCE_DIR%/*/*}) -MONOREPO_DIR=$(echo ${SOURCE_DIR%/*/*/*}) - -# Check that the fault game address file exists -FAULT_GAME_ADDR_FILE="$CHALLENGER_DIR/.fault-game-address" -if [[ ! -f "$FAULT_GAME_ADDR_FILE" ]]; then - echo "Game not initialized, exiting..." - exit 1 -fi - -# Mallory's Address: 0x4641c704a6c743f73ee1f36C7568Fbf4b80681e4 -MALLORY_KEY="28d7045146193f5f4eeb151c4843544b1b0d30a7ac1680c845a416fac65a7715" - -DISPUTE_GAME_PROXY=$(jq -r .DisputeGameFactoryProxy $MONOREPO_DIR/.devnet/addresses.json) -FAULT_GAME_ADDRESS=$(cat $FAULT_GAME_ADDR_FILE) -echo "Fault dispute game address: $FAULT_GAME_ADDRESS" - -DATADIR=`mktemp -d` -trap cleanup SIGINT -cleanup(){ - rm -rf "${DATADIR}" -} - -$CHALLENGER_DIR/bin/op-challenger \ - --l1-eth-rpc http://localhost:8545 \ - --trace-type="alphabet" \ - --alphabet "abcdexyz" \ - --datadir "${DATADIR}" \ - --game-factory-address $DISPUTE_GAME_PROXY \ - --game-allowlist $FAULT_GAME_ADDRESS \ - --private-key $MALLORY_KEY \ - --num-confirmations 1 \ - --metrics.enabled --metrics.port=7305 \ - --pprof.enabled --pprof.port=6065 \ - --agree-with-proposed-output=false diff --git a/op-challenger/scripts/create_game.sh b/op-challenger/scripts/create_game.sh deleted file mode 100755 index 151c7cc81aa3..000000000000 --- a/op-challenger/scripts/create_game.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SOURCE_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) -CHALLENGER_DIR=$(echo ${SOURCE_DIR%/*}) -MONOREPO_DIR=$(echo ${CHALLENGER_DIR%/*}) - -# ./create_game.sh -RPC=${1:?Must specify RPC address} -FACTORY_ADDR=${2:?Must specify factory address} -ROOT_CLAIM=${3:?Must specify root claim} -SIGNER_ARGS="${@:4}" - -# Default to Cannon Fault game type -GAME_TYPE=${GAME_TYPE:-0} - -# Get the fault dispute game implementation addr -GAME_IMPL_ADDR=$(cast call --rpc-url "${RPC}" "${FACTORY_ADDR}" 'gameImpls(uint8) returns(address)' "${GAME_TYPE}") -echo "Fault dispute game impl: ${GAME_IMPL_ADDR}" - -# Get the L2 output oracle address -L2OO_ADDR=$(cast call --rpc-url "${RPC}" "${GAME_IMPL_ADDR}" 'L2_OUTPUT_ORACLE() returns(address)') -echo "L2OO: ${L2OO_ADDR}" - -# Get the block oracle address -BLOCK_ORACLE_ADDR=$(cast call --rpc-url "${RPC}" "${GAME_IMPL_ADDR}" 'BLOCK_ORACLE() returns(address)') -echo "Block Oracle: ${BLOCK_ORACLE_ADDR}" - -# Get the L2 block number of the latest output proposal. This is the proposal that will be disputed by the created game. -L2_BLOCK_NUM=$(cast call --rpc-url "${RPC}" "${L2OO_ADDR}" 'latestBlockNumber() public view returns (uint256)') -echo "L2 Block Number: ${L2_BLOCK_NUM}" - -# Create a checkpoint in the block oracle to commit to the current L1 head. -# This defines the L1 head that will be used in the dispute game. -echo "Checkpointing the block oracle..." -L1_CHECKPOINT=$(cast send --rpc-url "${RPC}" ${SIGNER_ARGS} "${BLOCK_ORACLE_ADDR}" "checkpoint()" --json | jq -r '.logs[0].topics[1]' | cast to-dec) -echo "L1 Checkpoint: $L1_CHECKPOINT" - -# Fault dispute game extra data is calculated as follows. -# abi.encode(uint256(l2_block_number), uint256(l1 checkpoint)) -EXTRA_DATA=$(cast abi-encode "f(uint256,uint256)" "${L2_BLOCK_NUM}" "${L1_CHECKPOINT}") - -echo "Initializing the game" -FAULT_GAME_DATA=$(cast send --rpc-url "${RPC}" ${SIGNER_ARGS} "${FACTORY_ADDR}" "create(uint8,bytes32,bytes) returns(address)" "${GAME_TYPE}" "${ROOT_CLAIM}" "${EXTRA_DATA}" --json) - -# Extract the address of the newly created game from the receipt logs. -FAULT_GAME_ADDRESS=$(echo "${FAULT_GAME_DATA}" | jq -r '.logs[0].topics[1]' | cast parse-bytes32-address) -echo "Fault game address: ${FAULT_GAME_ADDRESS}" -echo "${FAULT_GAME_ADDRESS}" > $CHALLENGER_DIR/.fault-game-address diff --git a/op-challenger/scripts/list_claims.sh b/op-challenger/scripts/list_claims.sh deleted file mode 100755 index 0e79c2958d6c..000000000000 --- a/op-challenger/scripts/list_claims.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -RPC=${1:?Must specify RPC address} -GAME_ADDR=${2:?Must specify fault dispute game address} - -COUNT=$(cast call --rpc-url "${RPC}" "${GAME_ADDR}" 'claimDataLen() returns(uint256)') -echo "Claim count: ${COUNT}" -((COUNT=COUNT-1)) -for i in $(seq 0 "${COUNT}") -do - CLAIM=$(cast call --rpc-url "${RPC}" "${GAME_ADDR}" 'claimData(uint256) returns(uint32 parentIndex, bool countered, bytes32 claim, uint128 position, uint128 clock)' "${i}") - SAVEIFS=$IFS # Save current IFS (Internal Field Separator) - IFS=$'\n' # Change IFS to newline char - CLAIM=($CLAIM) # split the string into an array by the same name - IFS=$SAVEIFS # Restore original IFS - - echo "${i} Parent: ${CLAIM[0]} Countered: ${CLAIM[1]} Claim: ${CLAIM[2]} Position: ${CLAIM[3]} Clock ${CLAIM[4]}" -done diff --git a/op-challenger/scripts/list_games.sh b/op-challenger/scripts/list_games.sh deleted file mode 100755 index 6a00f8ac9c5a..000000000000 --- a/op-challenger/scripts/list_games.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -RPC=${1:?Must specify RPC address} -FACTORY_ADDR=${2:?Must specify dispute game factory address} - -COUNT=$(cast call --rpc-url "${RPC}" "${FACTORY_ADDR}" 'gameCount() returns(uint256)') -echo "Game count: ${COUNT}" -if [[ "${COUNT}" == "0" ]] -then - exit -fi -((COUNT=COUNT-1)) -for i in $(seq 0 "${COUNT}") -do - GAME=$(cast call --rpc-url "${RPC}" "${FACTORY_ADDR}" 'gameAtIndex(uint256) returns(uint8, uint64, address)' "${i}") - - SAVEIFS=$IFS # Save current IFS (Internal Field Separator) - IFS=$'\n' # Change IFS to newline char - GAME=($GAME) # split the string into an array by the same name - IFS=$SAVEIFS # Restore original IFS - - GAME_ADDR="${GAME[2]}" - CLAIMS=$(cast call --rpc-url "${RPC}" "${GAME_ADDR}" "claimDataLen() returns(uint256)") - STATUS=$(cast call --rpc-url "${RPC}" "${GAME_ADDR}" "status() return(uint8)" | cast to-dec) - if [[ "${STATUS}" == "0" ]] - then - STATUS="In Progress" - elif [[ "${STATUS}" == "1" ]] - then - STATUS="Challenger Wins" - elif [[ "${STATUS}" == "2" ]] - then - STATUS="Defender Wins" - fi - echo "${i} Game: ${GAME_ADDR} Type: ${GAME[0]} Created: ${GAME[1]} Claims: ${CLAIMS} Status: ${STATUS}" -done diff --git a/op-challenger/scripts/move.sh b/op-challenger/scripts/move.sh deleted file mode 100755 index 06c6794283c8..000000000000 --- a/op-challenger/scripts/move.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -set -euo pipefail - -RPC=${1:?Must specify RPC URL} -GAME_ADDR=${2:?Must specify game address} -ACTION=${3:?Must specify attack or defend} -PARENT_INDEX=${4:?Must specify parent index. Use latest to counter the latest claim added to the game.} -CLAIM=${5:?Must specify claim hash} -SIGNER_ARGS="${@:6}" - -if [[ "${ACTION}" != "attack" && "${ACTION}" != "defend" ]] -then - echo "Action must be either attack or defend" - exit 1 -fi - -if [[ "${PARENT_INDEX}" == "latest" ]] -then - # Fetch the index of the most recent claim made. - PARENT_INDEX=$(cast call --rpc-url "${RPC}" "${GAME_ADDR}" 'claimDataLen() returns(uint256)') - ((PARENT_INDEX=PARENT_INDEX-1)) -fi - -# Perform the move. -cast send --rpc-url "${RPC}" ${SIGNER_ARGS} "${GAME_ADDR}" "$ACTION(uint256,bytes32)" "${PARENT_INDEX}" "${CLAIM}" diff --git a/op-challenger/scripts/parallel.sh b/op-challenger/scripts/parallel.sh deleted file mode 100755 index 1d0e19cbcc57..000000000000 --- a/op-challenger/scripts/parallel.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -# set -x - -trap killgroup SIGINT - -killgroup(){ - echo killing... - kill 0 -} - -$1 | sed "s/^/[$2] /" & -$3 | sed "s/^/[$4] /" & -wait diff --git a/op-challenger/scripts/resolve.sh b/op-challenger/scripts/resolve.sh deleted file mode 100755 index 7ccb09837db7..000000000000 --- a/op-challenger/scripts/resolve.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -set -euo pipefail - -RPC=${1:?Must specify RPC URL} -GAME_ADDR=${2:?Must specify game address} -SIGNER_ARGS="${@:3}" - -# Perform the move. -RESULT_DATA=$(cast send --rpc-url "${RPC}" ${SIGNER_ARGS} "${GAME_ADDR}" "resolve()" --json) -RESULT=$(echo "${RESULT_DATA}" | jq -r '.logs[0].topics[1]' | cast to-dec) - -if [[ "${RESULT}" == "0" ]] -then - RESULT="In Progress" -elif [[ "${RESULT}" == "1" ]] -then - RESULT="Challenger Wins" -elif [[ "${RESULT}" == "2" ]] -then - RESULT="Defender Wins" -fi - -echo "Result: $RESULT" diff --git a/op-challenger/scripts/visualize.sh b/op-challenger/scripts/visualize.sh deleted file mode 100755 index 828756a646eb..000000000000 --- a/op-challenger/scripts/visualize.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -RPC="${1:?Must specify RPC address}" -FAULT_GAME_ADDRESS="${2:?Must specify game address}" - -DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) -DIR=$(echo ${DIR%/*/*}) -cd $DIR/packages/contracts-bedrock - -forge script scripts/FaultDisputeGameViz.s.sol \ - --sig "remote(address)" $FAULT_GAME_ADDRESS \ - --fork-url "$RPC" - -mv dispute_game.svg "$dir" diff --git a/op-challenger/sender/sender.go b/op-challenger/sender/sender.go new file mode 100644 index 000000000000..01f77c6b9780 --- /dev/null +++ b/op-challenger/sender/sender.go @@ -0,0 +1,56 @@ +package sender + +import ( + "context" + "errors" + + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +type TxSender struct { + log log.Logger + + txMgr txmgr.TxManager + queue *txmgr.Queue[int] +} + +func NewTxSender(ctx context.Context, logger log.Logger, txMgr txmgr.TxManager, maxPending uint64) *TxSender { + queue := txmgr.NewQueue[int](ctx, txMgr, maxPending) + return &TxSender{ + log: logger, + txMgr: txMgr, + queue: queue, + } +} + +func (s *TxSender) From() common.Address { + return s.txMgr.From() +} + +func (s *TxSender) SendAndWait(txPurpose string, txs ...txmgr.TxCandidate) ([]*types.Receipt, error) { + receiptsCh := make(chan txmgr.TxReceipt[int], len(txs)) + for i, tx := range txs { + s.queue.Send(i, tx, receiptsCh) + } + receipts := make([]*types.Receipt, len(txs)) + completed := 0 + var errs []error + for completed < len(txs) { + rcpt := <-receiptsCh + receipts[rcpt.ID] = rcpt.Receipt + completed++ + if rcpt.Err != nil { + errs = append(errs, rcpt.Err) + } else if rcpt.Receipt != nil { + if rcpt.Receipt.Status != types.ReceiptStatusSuccessful { + s.log.Error("Transaction published but reverted", "tx_hash", rcpt.Receipt.TxHash, "purpose", txPurpose) + } else { + s.log.Debug("Transaction successfully published", "tx_hash", rcpt.Receipt.TxHash, "purpose", txPurpose) + } + } + } + return receipts, errors.Join(errs...) +} diff --git a/op-challenger/sender/sender_test.go b/op-challenger/sender/sender_test.go new file mode 100644 index 000000000000..16dacf6173af --- /dev/null +++ b/op-challenger/sender/sender_test.go @@ -0,0 +1,145 @@ +package sender + +import ( + "context" + "fmt" + "sync" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" +) + +func TestSendAndWait(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + txMgr := &stubTxMgr{sending: make(map[byte]chan *types.Receipt)} + sender := NewTxSender(ctx, testlog.Logger(t, log.LevelInfo), txMgr, 5) + + tx := func(i byte) txmgr.TxCandidate { + return txmgr.TxCandidate{TxData: []byte{i}} + } + + sendAsync := func(txs ...txmgr.TxCandidate) chan []*types.Receipt { + ch := make(chan []*types.Receipt, 1) + go func() { + rcpts, err := sender.SendAndWait("testing", txs...) + require.NoError(t, err) + ch <- rcpts + close(ch) + }() + return ch + } + + wait := func(ch chan []*types.Receipt) []*types.Receipt { + select { + case rcpts := <-ch: + return rcpts + case <-ctx.Done(): + require.FailNow(t, "Timeout waiting for receipt") + return nil + } + } + + batch1 := sendAsync(tx(1), tx(2), tx(3)) + batch2 := sendAsync(tx(4), tx(5)) + require.Eventually(t, func() bool { + return txMgr.sentCount() == 5 + }, 10*time.Second, 1*time.Millisecond, "Wait for first transactions to send") + + require.Len(t, batch1, 0, "Should not have completed batch1") + require.Len(t, batch2, 0, "Should not have completed batch2") + + // Send a third batch after the first set have started sending to avoid races + batch3 := sendAsync(tx(6)) + require.Len(t, batch3, 0, "Should not have completed batch3") + + // Sends the 6th tx after one of the previous ones completes + txMgr.txSuccess(tx(5)) + require.Eventually(t, func() bool { + return txMgr.sentCount() == 6 + }, 10*time.Second, 1*time.Millisecond, "Wait for final transaction to send") + require.Len(t, batch1, 0, "Should not have completed batch1") + require.Len(t, batch2, 0, "Should not have completed batch2") + require.Len(t, batch3, 0, "Should not have completed batch3") + + // Batches complete as soon as they are sent + txMgr.txSuccess(tx(6)) + require.Len(t, wait(batch3), 1, "Batch3 should complete") + require.Len(t, batch1, 0, "Should not have completed batch1") + require.Len(t, batch2, 0, "Should not have completed batch2") + + txMgr.txSuccess(tx(2)) + txMgr.txSuccess(tx(3)) + require.Len(t, batch1, 0, "Should not have completed batch1") + require.Len(t, batch2, 0, "Should not have completed batch2") + + txMgr.txSuccess(tx(1)) + require.Len(t, wait(batch1), 3, "Batch1 should complete") + require.Len(t, batch2, 0, "Should not have completed batch2") + + txMgr.txSuccess(tx(4)) + require.Len(t, wait(batch2), 2, "Batch2 should complete") +} + +type stubTxMgr struct { + m sync.Mutex + sending map[byte]chan *types.Receipt +} + +func (s *stubTxMgr) IsClosed() bool { + return false +} + +func (s *stubTxMgr) Send(ctx context.Context, candidate txmgr.TxCandidate) (*types.Receipt, error) { + ch := s.recordTx(candidate) + return <-ch, nil +} + +func (s *stubTxMgr) recordTx(candidate txmgr.TxCandidate) chan *types.Receipt { + s.m.Lock() + defer s.m.Unlock() + id := candidate.TxData[0] + if _, ok := s.sending[id]; ok { + // Shouldn't happen if tests are well written, but double check... + panic("Sending duplicate transaction") + } + ch := make(chan *types.Receipt, 1) + s.sending[id] = ch + return ch +} + +func (s *stubTxMgr) txSuccess(candidate txmgr.TxCandidate) { + s.m.Lock() + defer s.m.Unlock() + ch, ok := s.sending[candidate.TxData[0]] + if !ok { + // Shouldn't happen if tests are well written, but double check... + panic(fmt.Sprintf("Completing unknown transaction: %v Known: %v", candidate.TxData[0], maps.Keys(s.sending))) + } + ch <- &types.Receipt{Status: types.ReceiptStatusSuccessful} + close(ch) +} + +func (s *stubTxMgr) sentCount() int { + s.m.Lock() + defer s.m.Unlock() + return len(s.sending) +} + +func (s *stubTxMgr) From() common.Address { + panic("unsupported") +} + +func (s *stubTxMgr) BlockNumber(_ context.Context) (uint64, error) { + panic("unsupported") +} + +func (s *stubTxMgr) Close() { +} diff --git a/op-conductor/.gitignore b/op-conductor/.gitignore new file mode 100644 index 000000000000..ba077a4031ad --- /dev/null +++ b/op-conductor/.gitignore @@ -0,0 +1 @@ +bin diff --git a/op-conductor/Dockerfile b/op-conductor/Dockerfile new file mode 100644 index 000000000000..5423628ea75e --- /dev/null +++ b/op-conductor/Dockerfile @@ -0,0 +1,9 @@ +ARG OP_STACK_GO_BUILDER=us-docker.pkg.dev/oplabs-tools-artifacts/images/op-stack-go:latest +FROM $OP_STACK_GO_BUILDER as builder +# See "make golang-docker" and /ops/docker/op-stack-go + +FROM alpine:3.18 + +COPY --from=builder /usr/local/bin/op-conductor /usr/local/bin/op-conductor + +CMD ["op-conductor"] diff --git a/op-conductor/Makefile b/op-conductor/Makefile new file mode 100644 index 000000000000..e858cfb594ba --- /dev/null +++ b/op-conductor/Makefile @@ -0,0 +1,26 @@ +GITCOMMIT ?= $(shell git rev-parse HEAD) +GITDATE ?= $(shell git show -s --format='%ct') +VERSION := v0.0.0 + +LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT) +LDFLAGSSTRING +=-X main.GitDate=$(GITDATE) +LDFLAGSSTRING +=-X main.Version=$(VERSION) +LDFLAGS := -ldflags "$(LDFLAGSSTRING)" + +op-conductor: + env GO111MODULE=on GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) go build -v $(LDFLAGS) -o ./bin/op-conductor ./cmd + +clean: + rm bin/op-conductor + +test: + go test -v ./... + +generate-mocks: + go generate ./... + +.PHONY: \ + op-conductor \ + clean \ + test \ + generate-mocks diff --git a/op-conductor/README.md b/op-conductor/README.md new file mode 100644 index 000000000000..8cb3afcfe34a --- /dev/null +++ b/op-conductor/README.md @@ -0,0 +1,38 @@ +# op-conductor + +op-conductor is an auxiliary service designed to enhance the reliability and availability of a sequencer in +high-availability setups, thereby minimizing the risks associated with single point of failure. +It is important to note, however, that this design does not incorporate Byzantine fault tolerance. +This means it operates under the assumption that all participating nodes are honest. + +## Summary + +The design will provide below guarantees: + +1. No unsafe reorgs +2. No unsafe head stall during network partition +3. 100% uptime with no more than 1 node failure (for a standard 3 node setup) + +## Design + +![op-conductor architecture](./assets/op-conductor.svg) +On a high level, op-conductor serves the following functions: + +1. serves as a (raft) consensus layer participant to determine + 1. leader of the sequencers + 2. store latest unsafe block within its state machine. +2. serves rpc requests for + 1. admin rpc for manual recovery scenarios such as stop leadership vote, remove itself from cluster, etc + 2. health rpc for op-node to determine if it should allow publish txs / unsafe blocks +3. monitor sequencer (op-node) health +4. control loop => control sequencer (op-node) status (start / stop) based on different scenarios + +### Conductor State Transition + +![conductor state transition](./assets/op-conductor-state-transition.svg) + +Helpful tips: +To better understand the graph, focus on one node at a time, understand what can be transitioned to this current state and how it can transition to other states. +This way you could understand how we handle the state transitions. + +This is initial version of README, more details will be added later. diff --git a/op-conductor/assets/op-conductor-state-transition.svg b/op-conductor/assets/op-conductor-state-transition.svg new file mode 100644 index 000000000000..b9e0544524e1 --- /dev/null +++ b/op-conductor/assets/op-conductor-state-transition.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/op-conductor/assets/op-conductor.svg b/op-conductor/assets/op-conductor.svg new file mode 100644 index 000000000000..5b3e50b5f17f --- /dev/null +++ b/op-conductor/assets/op-conductor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/op-conductor/client/mocks/SequencerControl.go b/op-conductor/client/mocks/SequencerControl.go new file mode 100644 index 000000000000..7e48f6dbf0df --- /dev/null +++ b/op-conductor/client/mocks/SequencerControl.go @@ -0,0 +1,306 @@ +// Code generated by mockery v2.39.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + common "github.com/ethereum/go-ethereum/common" + + eth "github.com/ethereum-optimism/optimism/op-service/eth" + + mock "github.com/stretchr/testify/mock" +) + +// SequencerControl is an autogenerated mock type for the SequencerControl type +type SequencerControl struct { + mock.Mock +} + +type SequencerControl_Expecter struct { + mock *mock.Mock +} + +func (_m *SequencerControl) EXPECT() *SequencerControl_Expecter { + return &SequencerControl_Expecter{mock: &_m.Mock} +} + +// LatestUnsafeBlock provides a mock function with given fields: ctx +func (_m *SequencerControl) LatestUnsafeBlock(ctx context.Context) (eth.BlockInfo, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for LatestUnsafeBlock") + } + + var r0 eth.BlockInfo + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (eth.BlockInfo, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) eth.BlockInfo); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(eth.BlockInfo) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SequencerControl_LatestUnsafeBlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestUnsafeBlock' +type SequencerControl_LatestUnsafeBlock_Call struct { + *mock.Call +} + +// LatestUnsafeBlock is a helper method to define mock.On call +// - ctx context.Context +func (_e *SequencerControl_Expecter) LatestUnsafeBlock(ctx interface{}) *SequencerControl_LatestUnsafeBlock_Call { + return &SequencerControl_LatestUnsafeBlock_Call{Call: _e.mock.On("LatestUnsafeBlock", ctx)} +} + +func (_c *SequencerControl_LatestUnsafeBlock_Call) Run(run func(ctx context.Context)) *SequencerControl_LatestUnsafeBlock_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *SequencerControl_LatestUnsafeBlock_Call) Return(_a0 eth.BlockInfo, _a1 error) *SequencerControl_LatestUnsafeBlock_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *SequencerControl_LatestUnsafeBlock_Call) RunAndReturn(run func(context.Context) (eth.BlockInfo, error)) *SequencerControl_LatestUnsafeBlock_Call { + _c.Call.Return(run) + return _c +} + +// PostUnsafePayload provides a mock function with given fields: ctx, payload +func (_m *SequencerControl) PostUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { + ret := _m.Called(ctx, payload) + + if len(ret) == 0 { + panic("no return value specified for PostUnsafePayload") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *eth.ExecutionPayloadEnvelope) error); ok { + r0 = rf(ctx, payload) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SequencerControl_PostUnsafePayload_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PostUnsafePayload' +type SequencerControl_PostUnsafePayload_Call struct { + *mock.Call +} + +// PostUnsafePayload is a helper method to define mock.On call +// - ctx context.Context +// - payload *eth.ExecutionPayloadEnvelope +func (_e *SequencerControl_Expecter) PostUnsafePayload(ctx interface{}, payload interface{}) *SequencerControl_PostUnsafePayload_Call { + return &SequencerControl_PostUnsafePayload_Call{Call: _e.mock.On("PostUnsafePayload", ctx, payload)} +} + +func (_c *SequencerControl_PostUnsafePayload_Call) Run(run func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope)) *SequencerControl_PostUnsafePayload_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*eth.ExecutionPayloadEnvelope)) + }) + return _c +} + +func (_c *SequencerControl_PostUnsafePayload_Call) Return(_a0 error) *SequencerControl_PostUnsafePayload_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *SequencerControl_PostUnsafePayload_Call) RunAndReturn(run func(context.Context, *eth.ExecutionPayloadEnvelope) error) *SequencerControl_PostUnsafePayload_Call { + _c.Call.Return(run) + return _c +} + +// SequencerActive provides a mock function with given fields: ctx +func (_m *SequencerControl) SequencerActive(ctx context.Context) (bool, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for SequencerActive") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) bool); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SequencerControl_SequencerActive_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SequencerActive' +type SequencerControl_SequencerActive_Call struct { + *mock.Call +} + +// SequencerActive is a helper method to define mock.On call +// - ctx context.Context +func (_e *SequencerControl_Expecter) SequencerActive(ctx interface{}) *SequencerControl_SequencerActive_Call { + return &SequencerControl_SequencerActive_Call{Call: _e.mock.On("SequencerActive", ctx)} +} + +func (_c *SequencerControl_SequencerActive_Call) Run(run func(ctx context.Context)) *SequencerControl_SequencerActive_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *SequencerControl_SequencerActive_Call) Return(_a0 bool, _a1 error) *SequencerControl_SequencerActive_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *SequencerControl_SequencerActive_Call) RunAndReturn(run func(context.Context) (bool, error)) *SequencerControl_SequencerActive_Call { + _c.Call.Return(run) + return _c +} + +// StartSequencer provides a mock function with given fields: ctx, hash +func (_m *SequencerControl) StartSequencer(ctx context.Context, hash common.Hash) error { + ret := _m.Called(ctx, hash) + + if len(ret) == 0 { + panic("no return value specified for StartSequencer") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) error); ok { + r0 = rf(ctx, hash) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SequencerControl_StartSequencer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StartSequencer' +type SequencerControl_StartSequencer_Call struct { + *mock.Call +} + +// StartSequencer is a helper method to define mock.On call +// - ctx context.Context +// - hash common.Hash +func (_e *SequencerControl_Expecter) StartSequencer(ctx interface{}, hash interface{}) *SequencerControl_StartSequencer_Call { + return &SequencerControl_StartSequencer_Call{Call: _e.mock.On("StartSequencer", ctx, hash)} +} + +func (_c *SequencerControl_StartSequencer_Call) Run(run func(ctx context.Context, hash common.Hash)) *SequencerControl_StartSequencer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(common.Hash)) + }) + return _c +} + +func (_c *SequencerControl_StartSequencer_Call) Return(_a0 error) *SequencerControl_StartSequencer_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *SequencerControl_StartSequencer_Call) RunAndReturn(run func(context.Context, common.Hash) error) *SequencerControl_StartSequencer_Call { + _c.Call.Return(run) + return _c +} + +// StopSequencer provides a mock function with given fields: ctx +func (_m *SequencerControl) StopSequencer(ctx context.Context) (common.Hash, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for StopSequencer") + } + + var r0 common.Hash + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (common.Hash, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) common.Hash); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Hash) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SequencerControl_StopSequencer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StopSequencer' +type SequencerControl_StopSequencer_Call struct { + *mock.Call +} + +// StopSequencer is a helper method to define mock.On call +// - ctx context.Context +func (_e *SequencerControl_Expecter) StopSequencer(ctx interface{}) *SequencerControl_StopSequencer_Call { + return &SequencerControl_StopSequencer_Call{Call: _e.mock.On("StopSequencer", ctx)} +} + +func (_c *SequencerControl_StopSequencer_Call) Run(run func(ctx context.Context)) *SequencerControl_StopSequencer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *SequencerControl_StopSequencer_Call) Return(_a0 common.Hash, _a1 error) *SequencerControl_StopSequencer_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *SequencerControl_StopSequencer_Call) RunAndReturn(run func(context.Context) (common.Hash, error)) *SequencerControl_StopSequencer_Call { + _c.Call.Return(run) + return _c +} + +// NewSequencerControl creates a new instance of SequencerControl. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewSequencerControl(t interface { + mock.TestingT + Cleanup(func()) +}) *SequencerControl { + mock := &SequencerControl{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/op-conductor/client/sequencer.go b/op-conductor/client/sequencer.go new file mode 100644 index 000000000000..1099c84dbea0 --- /dev/null +++ b/op-conductor/client/sequencer.go @@ -0,0 +1,61 @@ +package client + +import ( + "context" + + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources" +) + +// SequencerControl defines the interface for controlling the sequencer. +// +//go:generate mockery --name SequencerControl --output mocks/ --with-expecter=true +type SequencerControl interface { + StartSequencer(ctx context.Context, hash common.Hash) error + StopSequencer(ctx context.Context) (common.Hash, error) + SequencerActive(ctx context.Context) (bool, error) + LatestUnsafeBlock(ctx context.Context) (eth.BlockInfo, error) + PostUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error +} + +// NewSequencerControl creates a new SequencerControl instance. +func NewSequencerControl(exec *sources.EthClient, node *sources.RollupClient) SequencerControl { + return &sequencerController{ + exec: exec, + node: node, + } +} + +type sequencerController struct { + exec *sources.EthClient + node *sources.RollupClient +} + +var _ SequencerControl = (*sequencerController)(nil) + +// LatestUnsafeBlock implements SequencerControl. +func (s *sequencerController) LatestUnsafeBlock(ctx context.Context) (eth.BlockInfo, error) { + return s.exec.InfoByLabel(ctx, eth.Unsafe) +} + +// StartSequencer implements SequencerControl. +func (s *sequencerController) StartSequencer(ctx context.Context, hash common.Hash) error { + return s.node.StartSequencer(ctx, hash) +} + +// StopSequencer implements SequencerControl. +func (s *sequencerController) StopSequencer(ctx context.Context) (common.Hash, error) { + return s.node.StopSequencer(ctx) +} + +// SequencerActive implements SequencerControl. +func (s *sequencerController) SequencerActive(ctx context.Context) (bool, error) { + return s.node.SequencerActive(ctx) +} + +// PostUnsafePayload implements SequencerControl. +func (s *sequencerController) PostUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { + return s.node.PostUnsafePayload(ctx, payload) +} diff --git a/op-conductor/cmd/main.go b/op-conductor/cmd/main.go new file mode 100644 index 000000000000..508ffe220df0 --- /dev/null +++ b/op-conductor/cmd/main.go @@ -0,0 +1,61 @@ +package main + +import ( + "context" + "fmt" + "os" + + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/op-conductor/conductor" + "github.com/ethereum-optimism/optimism/op-conductor/flags" + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/cliapp" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/opio" +) + +var ( + Version = "v0.0.1" + GitCommit = "" + GitDate = "" +) + +func main() { + oplog.SetupDefaults() + + app := cli.NewApp() + app.Flags = cliapp.ProtectFlags(flags.Flags) + app.Version = opservice.FormatVersion(Version, GitCommit, GitDate, "") + app.Name = "op-conductor" + app.Usage = "Optimism Sequencer Conductor Service" + app.Description = "op-conductor help sequencer to run in highly available mode" + app.Action = cliapp.LifecycleCmd(OpConductorMain) + app.Commands = []*cli.Command{} + + ctx := opio.WithInterruptBlocker(context.Background()) + err := app.RunContext(ctx, os.Args) + if err != nil { + log.Crit("Application failed", "message", err) + } +} + +func OpConductorMain(ctx *cli.Context, closeApp context.CancelCauseFunc) (cliapp.Lifecycle, error) { + logCfg := oplog.ReadCLIConfig(ctx) + log := oplog.NewLogger(oplog.AppOut(ctx), logCfg) + oplog.SetGlobalLogHandler(log.Handler()) + opservice.ValidateEnvVars(flags.EnvVarPrefix, flags.Flags, log) + + cfg, err := conductor.NewConfig(ctx, log) + if err != nil { + return nil, fmt.Errorf("failed to read config: %w", err) + } + + c, err := conductor.New(ctx.Context, cfg, log, Version) + if err != nil { + return nil, fmt.Errorf("failed to create conductor: %w", err) + } + + return c, nil +} diff --git a/op-conductor/conductor/config.go b/op-conductor/conductor/config.go new file mode 100644 index 000000000000..ad65a0e34cc3 --- /dev/null +++ b/op-conductor/conductor/config.go @@ -0,0 +1,159 @@ +package conductor + +import ( + "fmt" + "math" + + "github.com/ethereum/go-ethereum/log" + "github.com/pkg/errors" + "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/op-conductor/flags" + opnode "github.com/ethereum-optimism/optimism/op-node" + "github.com/ethereum-optimism/optimism/op-node/rollup" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/oppprof" + oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" +) + +type Config struct { + // ConsensusAddr is the address to listen for consensus connections. + ConsensusAddr string + + // ConsensusPort is the port to listen for consensus connections. + ConsensusPort int + + // RaftServerID is the unique ID for this server used by raft consensus. + RaftServerID string + + // RaftStorageDir is the directory to store raft data. + RaftStorageDir string + + // RaftBootstrap is true if this node should bootstrap a new raft cluster. + RaftBootstrap bool + + // NodeRPC is the HTTP provider URL for op-node. + NodeRPC string + + // ExecutionRPC is the HTTP provider URL for execution layer. + ExecutionRPC string + + // Paused is true if the conductor should start in a paused state. + Paused bool + + // HealthCheck is the health check configuration. + HealthCheck HealthCheckConfig + + // RollupCfg is the rollup config. + RollupCfg rollup.Config + + // RPCEnableProxy is true if the sequencer RPC proxy should be enabled. + RPCEnableProxy bool + + LogConfig oplog.CLIConfig + MetricsConfig opmetrics.CLIConfig + PprofConfig oppprof.CLIConfig + RPC oprpc.CLIConfig +} + +// Check validates the CLIConfig. +func (c *Config) Check() error { + if c.ConsensusAddr == "" { + return fmt.Errorf("missing consensus address") + } + if c.ConsensusPort < 0 || c.ConsensusPort > math.MaxUint16 { + return fmt.Errorf("invalid RPC port") + } + if c.RaftServerID == "" { + return fmt.Errorf("missing raft server ID") + } + if c.RaftStorageDir == "" { + return fmt.Errorf("missing raft storage directory") + } + if c.NodeRPC == "" { + return fmt.Errorf("missing node RPC") + } + if c.ExecutionRPC == "" { + return fmt.Errorf("missing geth RPC") + } + if err := c.HealthCheck.Check(); err != nil { + return errors.Wrap(err, "invalid health check config") + } + if err := c.RollupCfg.Check(); err != nil { + return errors.Wrap(err, "invalid rollup config") + } + if err := c.MetricsConfig.Check(); err != nil { + return errors.Wrap(err, "invalid metrics config") + } + if err := c.PprofConfig.Check(); err != nil { + return errors.Wrap(err, "invalid pprof config") + } + if err := c.RPC.Check(); err != nil { + return errors.Wrap(err, "invalid rpc config") + } + return nil +} + +// NewConfig parses the Config from the provided flags or environment variables. +func NewConfig(ctx *cli.Context, log log.Logger) (*Config, error) { + if err := flags.CheckRequired(ctx); err != nil { + return nil, errors.Wrap(err, "missing required flags") + } + + rollupCfg, err := opnode.NewRollupConfigFromCLI(log, ctx) + if err != nil { + return nil, errors.Wrap(err, "failed to load rollup config") + } + + return &Config{ + ConsensusAddr: ctx.String(flags.ConsensusAddr.Name), + ConsensusPort: ctx.Int(flags.ConsensusPort.Name), + RaftBootstrap: ctx.Bool(flags.RaftBootstrap.Name), + RaftServerID: ctx.String(flags.RaftServerID.Name), + RaftStorageDir: ctx.String(flags.RaftStorageDir.Name), + NodeRPC: ctx.String(flags.NodeRPC.Name), + ExecutionRPC: ctx.String(flags.ExecutionRPC.Name), + Paused: ctx.Bool(flags.Paused.Name), + HealthCheck: HealthCheckConfig{ + Interval: ctx.Uint64(flags.HealthCheckInterval.Name), + UnsafeInterval: ctx.Uint64(flags.HealthCheckUnsafeInterval.Name), + SafeInterval: ctx.Uint64(flags.HealthCheckSafeInterval.Name), + MinPeerCount: ctx.Uint64(flags.HealthCheckMinPeerCount.Name), + }, + RollupCfg: *rollupCfg, + RPCEnableProxy: ctx.Bool(flags.RPCEnableProxy.Name), + LogConfig: oplog.ReadCLIConfig(ctx), + MetricsConfig: opmetrics.ReadCLIConfig(ctx), + PprofConfig: oppprof.ReadCLIConfig(ctx), + RPC: oprpc.ReadCLIConfig(ctx), + }, nil +} + +// HealthCheckConfig defines health check configuration. +type HealthCheckConfig struct { + // Interval is the interval (in seconds) to check the health of the sequencer. + Interval uint64 + + // UnsafeInterval is the interval allowed between unsafe head and now in seconds. + UnsafeInterval uint64 + + // SafeInterval is the interval between safe head progression measured in seconds. + SafeInterval uint64 + + // MinPeerCount is the minimum number of peers required for the sequencer to be healthy. + MinPeerCount uint64 +} + +func (c *HealthCheckConfig) Check() error { + if c.Interval == 0 { + return fmt.Errorf("missing health check interval") + } + if c.SafeInterval == 0 { + return fmt.Errorf("missing safe interval") + } + if c.MinPeerCount == 0 { + return fmt.Errorf("missing minimum peer count") + } + return nil +} diff --git a/op-conductor/conductor/service.go b/op-conductor/conductor/service.go new file mode 100644 index 000000000000..4775d8a48836 --- /dev/null +++ b/op-conductor/conductor/service.go @@ -0,0 +1,722 @@ +package conductor + +import ( + "context" + "fmt" + "math/rand" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/raft" + "github.com/pkg/errors" + + "github.com/ethereum-optimism/optimism/op-conductor/client" + "github.com/ethereum-optimism/optimism/op-conductor/consensus" + "github.com/ethereum-optimism/optimism/op-conductor/health" + conductorrpc "github.com/ethereum-optimism/optimism/op-conductor/rpc" + opp2p "github.com/ethereum-optimism/optimism/op-node/p2p" + "github.com/ethereum-optimism/optimism/op-node/rollup/driver" + "github.com/ethereum-optimism/optimism/op-service/cliapp" + opclient "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/eth" + oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" + "github.com/ethereum-optimism/optimism/op-service/sources" +) + +var ( + ErrResumeTimeout = errors.New("timeout to resume conductor") + ErrPauseTimeout = errors.New("timeout to pause conductor") + ErrUnsafeHeadMismarch = errors.New("unsafe head mismatch") + ErrUnableToRetrieveUnsafeHeadFromConsensus = errors.New("unable to retrieve unsafe head from consensus") +) + +// New creates a new OpConductor instance. +func New(ctx context.Context, cfg *Config, log log.Logger, version string) (*OpConductor, error) { + return NewOpConductor(ctx, cfg, log, version, nil, nil, nil) +} + +// NewOpConductor creates a new OpConductor instance. +func NewOpConductor( + ctx context.Context, + cfg *Config, + log log.Logger, + version string, + ctrl client.SequencerControl, + cons consensus.Consensus, + hmon health.HealthMonitor, +) (*OpConductor, error) { + if err := cfg.Check(); err != nil { + return nil, errors.Wrap(err, "invalid config") + } + + oc := &OpConductor{ + log: log, + version: version, + cfg: cfg, + pauseCh: make(chan struct{}), + pauseDoneCh: make(chan struct{}), + resumeCh: make(chan struct{}), + resumeDoneCh: make(chan struct{}), + actionCh: make(chan struct{}, 1), + ctrl: ctrl, + cons: cons, + hmon: hmon, + } + oc.loopActionFn = oc.loopAction + + // explicitly set all atomic.Bool values + oc.leader.Store(false) // upon start, it should not be the leader unless specified otherwise by raft bootstrap, in that case, it'll receive a leadership update from consensus. + oc.healthy.Store(true) // default to healthy unless reported otherwise by health monitor. + oc.seqActive.Store(false) // explicitly set to false by default, the real value will be reported after sequencer control initialization. + oc.paused.Store(cfg.Paused) + oc.stopped.Store(false) + + // do not rely on the default context, use a dedicated context for shutdown. + oc.shutdownCtx, oc.shutdownCancel = context.WithCancel(context.Background()) + + err := oc.init(ctx) + if err != nil { + log.Error("failed to initialize OpConductor", "err", err) + // ensure we always close the resources if we fail to initialize the conductor. + closeErr := oc.Stop(ctx) + if closeErr != nil { + err = multierror.Append(err, closeErr) + } + return nil, err + } + oc.prevState = NewState(oc.leader.Load(), oc.healthy.Load(), oc.seqActive.Load()) + + return oc, nil +} + +func (c *OpConductor) init(ctx context.Context) error { + c.log.Info("initializing OpConductor", "version", c.version) + if err := c.initSequencerControl(ctx); err != nil { + return errors.Wrap(err, "failed to initialize sequencer control") + } + if err := c.initConsensus(ctx); err != nil { + return errors.Wrap(err, "failed to initialize consensus") + } + if err := c.initHealthMonitor(ctx); err != nil { + return errors.Wrap(err, "failed to initialize health monitor") + } + if err := c.initRPCServer(ctx); err != nil { + return errors.Wrap(err, "failed to initialize rpc server") + } + return nil +} + +func (c *OpConductor) initSequencerControl(ctx context.Context) error { + if c.ctrl != nil { + return nil + } + + ec, err := opclient.NewRPC(ctx, c.log, c.cfg.ExecutionRPC) + if err != nil { + return errors.Wrap(err, "failed to create geth rpc client") + } + execCfg := sources.L2ClientDefaultConfig(&c.cfg.RollupCfg, true) + // TODO: Add metrics tracer here. tracked by https://github.com/ethereum-optimism/protocol-quest/issues/45 + exec, err := sources.NewEthClient(ec, c.log, nil, &execCfg.EthClientConfig) + if err != nil { + return errors.Wrap(err, "failed to create geth client") + } + + nc, err := opclient.NewRPC(ctx, c.log, c.cfg.NodeRPC) + if err != nil { + return errors.Wrap(err, "failed to create node rpc client") + } + node := sources.NewRollupClient(nc) + c.ctrl = client.NewSequencerControl(exec, node) + + return c.updateSequencerActiveStatus() +} + +func (c *OpConductor) initConsensus(ctx context.Context) error { + if c.cons != nil { + return nil + } + + serverAddr := fmt.Sprintf("%s:%d", c.cfg.ConsensusAddr, c.cfg.ConsensusPort) + cons, err := consensus.NewRaftConsensus(c.log, c.cfg.RaftServerID, serverAddr, c.cfg.RaftStorageDir, c.cfg.RaftBootstrap, &c.cfg.RollupCfg) + if err != nil { + return errors.Wrap(err, "failed to create raft consensus") + } + c.cons = cons + c.leaderUpdateCh = c.cons.LeaderCh() + return nil +} + +func (c *OpConductor) initHealthMonitor(ctx context.Context) error { + if c.hmon != nil { + return nil + } + + nc, err := opclient.NewRPC(ctx, c.log, c.cfg.NodeRPC) + if err != nil { + return errors.Wrap(err, "failed to create node rpc client") + } + node := sources.NewRollupClient(nc) + + pc, err := rpc.DialContext(ctx, c.cfg.NodeRPC) + if err != nil { + return errors.Wrap(err, "failed to create p2p rpc client") + } + p2p := opp2p.NewClient(pc) + + c.hmon = health.NewSequencerHealthMonitor( + c.log, + c.cfg.HealthCheck.Interval, + c.cfg.HealthCheck.UnsafeInterval, + c.cfg.HealthCheck.SafeInterval, + c.cfg.HealthCheck.MinPeerCount, + &c.cfg.RollupCfg, + node, + p2p, + ) + c.healthUpdateCh = c.hmon.Subscribe() + + return nil +} + +func (oc *OpConductor) initRPCServer(ctx context.Context) error { + server := oprpc.NewServer( + oc.cfg.RPC.ListenAddr, + oc.cfg.RPC.ListenPort, + oc.version, + oprpc.WithLogger(oc.log), + ) + api := conductorrpc.NewAPIBackend(oc.log, oc) + server.AddAPI(rpc.API{ + Namespace: conductorrpc.RPCNamespace, + Version: oc.version, + Service: api, + }) + + if oc.cfg.RPCEnableProxy { + execClient, err := dial.DialEthClientWithTimeout(ctx, 1*time.Minute, oc.log, oc.cfg.ExecutionRPC) + if err != nil { + return errors.Wrap(err, "failed to create execution rpc client") + } + executionProxy := conductorrpc.NewExecutionProxyBackend(oc.log, oc, execClient) + server.AddAPI(rpc.API{ + Namespace: conductorrpc.ExecutionRPCNamespace, + Service: executionProxy, + }) + + nodeClient, err := dial.DialRollupClientWithTimeout(ctx, 1*time.Minute, oc.log, oc.cfg.NodeRPC) + if err != nil { + return errors.Wrap(err, "failed to create node rpc client") + } + nodeProxy := conductorrpc.NewNodeProxyBackend(oc.log, oc, nodeClient) + server.AddAPI(rpc.API{ + Namespace: conductorrpc.NodeRPCNamespace, + Service: nodeProxy, + }) + + nodeAdminProxy := conductorrpc.NewNodeAdminProxyBackend(oc.log, oc, nodeClient) + server.AddAPI(rpc.API{ + Namespace: conductorrpc.NodeAdminRPCNamespace, + Service: nodeAdminProxy, + }) + } + + oc.rpcServer = server + return nil +} + +// OpConductor represents a full conductor instance and its resources, it does: +// 1. performs health checks on sequencer +// 2. participate in consensus protocol for leader election +// 3. and control sequencer state based on leader, sequencer health and sequencer active status. +// +// OpConductor has three states: +// 1. running: it is running normally, which executes control loop and participates in leader election. +// 2. paused: control loop (sequencer start/stop) is paused, but it still participates in leader election, and receives health updates. +// 3. stopped: it is stopped, which means it is not participating in leader election and control loop. OpConductor cannot be started again from stopped mode. +type OpConductor struct { + log log.Logger + version string + cfg *Config + + ctrl client.SequencerControl + cons consensus.Consensus + hmon health.HealthMonitor + + leader atomic.Bool + seqActive atomic.Bool + healthy atomic.Bool + hcerr error // error from health check + prevState *state + + healthUpdateCh <-chan error + leaderUpdateCh <-chan bool + loopActionFn func() // loopActionFn defines the logic to be executed inside control loop. + + wg sync.WaitGroup + pauseCh chan struct{} + pauseDoneCh chan struct{} + resumeCh chan struct{} + resumeDoneCh chan struct{} + actionCh chan struct{} + paused atomic.Bool + stopped atomic.Bool + shutdownCtx context.Context + shutdownCancel context.CancelFunc + + rpcServer *oprpc.Server +} + +type state struct { + leader, healthy, active bool +} + +// NewState creates a new state instance. +func NewState(leader, healthy, active bool) *state { + return &state{ + leader: leader, + healthy: healthy, + active: active, + } +} + +func (s *state) Equal(other *state) bool { + return s.leader == other.leader && s.healthy == other.healthy && s.active == other.active +} + +var _ cliapp.Lifecycle = (*OpConductor)(nil) + +// Start implements cliapp.Lifecycle. +func (oc *OpConductor) Start(ctx context.Context) error { + oc.log.Info("starting OpConductor") + + if err := oc.hmon.Start(); err != nil { + return errors.Wrap(err, "failed to start health monitor") + } + + oc.log.Info("starting JSON-RPC server") + if err := oc.rpcServer.Start(); err != nil { + return errors.Wrap(err, "failed to start JSON-RPC server") + } + + oc.wg.Add(1) + go oc.loop() + + oc.log.Info("OpConductor started") + return nil +} + +// Stop implements cliapp.Lifecycle. +func (oc *OpConductor) Stop(ctx context.Context) error { + if oc.Stopped() { + oc.log.Info("OpConductor already stopped") + return nil + } + + oc.log.Info("stopping OpConductor") + var result *multierror.Error + + // close control loop + oc.shutdownCancel() + oc.wg.Wait() + + if oc.rpcServer != nil { + if err := oc.rpcServer.Stop(); err != nil { + result = multierror.Append(result, errors.Wrap(err, "failed to stop rpc server")) + } + } + + // stop health check + if oc.hmon != nil { + if err := oc.hmon.Stop(); err != nil { + result = multierror.Append(result, errors.Wrap(err, "failed to stop health monitor")) + } + } + + if oc.cons != nil { + if err := oc.cons.Shutdown(); err != nil { + result = multierror.Append(result, errors.Wrap(err, "failed to shutdown consensus")) + } + } + + if result.ErrorOrNil() != nil { + oc.log.Error("failed to stop OpConductor", "err", result.ErrorOrNil()) + return result.ErrorOrNil() + } + + oc.stopped.Store(true) + oc.log.Info("OpConductor stopped") + return nil +} + +// Stopped implements cliapp.Lifecycle. +func (oc *OpConductor) Stopped() bool { + return oc.stopped.Load() +} + +// Pause pauses the control loop of OpConductor, but still allows it to participate in leader election. +func (oc *OpConductor) Pause(ctx context.Context) error { + select { + case oc.pauseCh <- struct{}{}: + <-oc.pauseDoneCh + return nil + case <-ctx.Done(): + return ErrPauseTimeout + } +} + +// Resume resumes the control loop of OpConductor. +func (oc *OpConductor) Resume(ctx context.Context) error { + err := oc.updateSequencerActiveStatus() + if err != nil { + return errors.Wrap(err, "cannot resume because failed to get sequencer active status") + } + + select { + case oc.resumeCh <- struct{}{}: + <-oc.resumeDoneCh + return nil + case <-ctx.Done(): + return ErrResumeTimeout + } +} + +// Paused returns true if OpConductor is paused. +func (oc *OpConductor) Paused() bool { + return oc.paused.Load() +} + +func (oc *OpConductor) HTTPEndpoint() string { + if oc.rpcServer == nil { + return "" + } + return fmt.Sprintf("http://%s", oc.rpcServer.Endpoint()) +} + +// Leader returns true if OpConductor is the leader. +func (oc *OpConductor) Leader(_ context.Context) bool { + return oc.cons.Leader() +} + +// LeaderWithID returns the current leader's server ID and address. +func (oc *OpConductor) LeaderWithID(_ context.Context) *consensus.ServerInfo { + return oc.cons.LeaderWithID() +} + +// AddServerAsVoter adds a server as a voter to the cluster. +func (oc *OpConductor) AddServerAsVoter(_ context.Context, id string, addr string) error { + return oc.cons.AddVoter(id, addr) +} + +// AddServerAsNonvoter adds a server as a non-voter to the cluster. non-voter will not participate in leader election. +func (oc *OpConductor) AddServerAsNonvoter(_ context.Context, id string, addr string) error { + return oc.cons.AddNonVoter(id, addr) +} + +// RemoveServer removes a server from the cluster. +func (oc *OpConductor) RemoveServer(_ context.Context, id string) error { + return oc.cons.RemoveServer(id) +} + +// TransferLeader transfers leadership to another server. +func (oc *OpConductor) TransferLeader(_ context.Context) error { + return oc.cons.TransferLeader() +} + +// TransferLeaderToServer transfers leadership to a specific server. +func (oc *OpConductor) TransferLeaderToServer(_ context.Context, id string, addr string) error { + return oc.cons.TransferLeaderTo(id, addr) +} + +// CommitUnsafePayload commits a unsafe payload (latest head) to the cluster FSM. +func (oc *OpConductor) CommitUnsafePayload(_ context.Context, payload *eth.ExecutionPayloadEnvelope) error { + return oc.cons.CommitUnsafePayload(payload) +} + +// SequencerHealthy returns true if sequencer is healthy. +func (oc *OpConductor) SequencerHealthy(_ context.Context) bool { + return oc.healthy.Load() +} + +// ClusterMembership returns current cluster's membership information. +func (oc *OpConductor) ClusterMembership(_ context.Context) ([]*consensus.ServerInfo, error) { + return oc.cons.ClusterMembership() +} + +// LatestUnsafePayload returns the latest unsafe payload envelope from FSM. +func (oc *OpConductor) LatestUnsafePayload(_ context.Context) *eth.ExecutionPayloadEnvelope { + return oc.cons.LatestUnsafePayload() +} + +func (oc *OpConductor) loop() { + defer oc.wg.Done() + + for { + select { + case <-oc.shutdownCtx.Done(): + return + default: + oc.loopActionFn() + } + } +} + +func (oc *OpConductor) loopAction() { + select { + case healthy := <-oc.healthUpdateCh: + oc.handleHealthUpdate(healthy) + case leader := <-oc.leaderUpdateCh: + oc.handleLeaderUpdate(leader) + case <-oc.pauseCh: + oc.paused.Store(true) + oc.pauseDoneCh <- struct{}{} + case <-oc.resumeCh: + oc.paused.Store(false) + oc.resumeDoneCh <- struct{}{} + // queue an action to make sure sequencer is in the desired state after resume. + oc.queueAction() + case <-oc.shutdownCtx.Done(): + return + case <-oc.actionCh: + oc.action() + } +} + +func (oc *OpConductor) queueAction() { + select { + case oc.actionCh <- struct{}{}: + default: + // do nothing if there's an action queued already, this is fine because whenever an action is executed, + // it is guaranteed to have the latest status and bring the sequencer to the desired state. + } +} + +// handleLeaderUpdate handles leadership update from consensus. +func (oc *OpConductor) handleLeaderUpdate(leader bool) { + oc.log.Info("Leadership status changed", "server", oc.cons.ServerID(), "leader", leader) + + oc.leader.Store(leader) + oc.queueAction() +} + +// handleHealthUpdate handles health update from health monitor. +func (oc *OpConductor) handleHealthUpdate(hcerr error) { + oc.log.Debug("received health update", "server", oc.cons.ServerID(), "error", hcerr) + healthy := hcerr == nil + if !healthy { + oc.log.Error("Sequencer is unhealthy", "server", oc.cons.ServerID(), "err", hcerr) + // always queue an action if it's unhealthy, it could be an no-op in the handler. + oc.queueAction() + } + + if healthy != oc.healthy.Load() { + // queue an action if health status changed. + oc.queueAction() + } + + oc.healthy.Store(healthy) + oc.hcerr = hcerr +} + +// action tries to bring the sequencer to the desired state, a retry will be queued if any action failed. +func (oc *OpConductor) action() { + if oc.Paused() { + return + } + + var err error + status := NewState(oc.leader.Load(), oc.healthy.Load(), oc.seqActive.Load()) + oc.log.Debug("entering action with status", "status", status) + + // exhaust all cases below for completeness, 3 state, 8 cases. + switch { + case !status.leader && !status.healthy && !status.active: + // if follower is not healthy and not sequencing, just log an error + oc.log.Error("server (follower) is not healthy", "server", oc.cons.ServerID()) + case !status.leader && !status.healthy && status.active: + // sequencer is not leader, not healthy, but it is sequencing, stop it + err = oc.stopSequencer() + case !status.leader && status.healthy && !status.active: + // normal follower, do nothing + case !status.leader && status.healthy && status.active: + // stop sequencer, this happens when current server steps down as leader. + err = oc.stopSequencer() + case status.leader && !status.healthy && !status.active: + // There are 2 scenarios we need to handle: + // 1. current node is follower, active sequencer became unhealthy and started the leadership transfer process. + // however if leadership transfer took longer than the time for health monitor to treat the node as unhealthy, + // then basically the entire network is stalled and we need to start sequencing in this case. + if !oc.prevState.leader && !oc.prevState.active { + _, _, cerr := oc.compareUnsafeHead(oc.shutdownCtx) + if cerr == nil && !errors.Is(oc.hcerr, health.ErrSequencerConnectionDown) { + // if unsafe in consensus is the same as unsafe in op-node, then it is scenario #1 and we should start sequencer. + err = oc.startSequencer() + break + } + } + + // 2. for other cases, we should try to transfer leader to another node. + // for example, if follower became a leader and unhealthy at the same time (just unhealthy itself), then we should transfer leadership. + err = oc.transferLeader() + case status.leader && !status.healthy && status.active: + // There are two scenarios we need to handle here: + // 1. we're transitioned from case status.leader && !status.healthy && !status.active, see description above + // then we should continue to sequence blocks and try to bring ourselves back to healthy state. + // note: we need to also make sure that the health error is not due to ErrSequencerConnectionDown + // because in this case, we should stop sequencing and transfer leadership to other nodes. + if oc.prevState.leader && !oc.prevState.healthy && !oc.prevState.active && !errors.Is(oc.hcerr, health.ErrSequencerConnectionDown) { + err = errors.New("waiting for sequencing to become healthy by itself") + break + } + + // 2. we're here becasuse an healthy leader became unhealthy itself + // then we should try to stop sequencing locally and transfer leadership. + var result *multierror.Error + // Try to stop sequencer first, but since sequencer is not healthy, we may not be able to stop it. + // In this case, it's fine to continue to try to transfer leadership to another server. This is safe because + // 1. if leadership transfer succeeded, then we'll retry and enter case !status.leader && status.healthy && status.active, which will try to stop sequencer. + // 2. even if the retry continues to fail and current server stays in active sequencing mode, it would be safe because our hook in op-node will prevent it from committing any new blocks to the network via p2p (if it's not leader any more) + if e := oc.stopSequencer(); e != nil { + result = multierror.Append(result, e) + } + // try to transfer leadership to another server despite if sequencer is stopped or not. There are 4 scenarios here: + // 1. [sequencer stopped, leadership transfer succeeded] which is the happy case and we handed over sequencing to another server. + // 2. [sequencer stopped, leadership transfer failed] we'll enter into case status.leader && !status.healthy && !status.active and retry transfer leadership. + // 3. [sequencer active, leadership transfer succeeded] we'll enter into case !status.leader && status.healthy && status.active and retry stop sequencer. + // 4. [sequencer active, leadership transfer failed] we're in the same state and will retry here again. + if e := oc.transferLeader(); e != nil { + result = multierror.Append(result, e) + } + err = result.ErrorOrNil() + case status.leader && status.healthy && !status.active: + // start sequencer + err = oc.startSequencer() + case status.leader && status.healthy && status.active: + // normal leader, do nothing + } + + oc.log.Debug("exiting action with status and error", "status", status, "err", err) + if err != nil { + oc.log.Error("failed to execute step, queueing another one to retry", "err", err) + // randomly sleep for 0-200ms to avoid excessive retry + time.Sleep(time.Duration(rand.Intn(200)) * time.Millisecond) + oc.queueAction() + return + } + + if !status.Equal(oc.prevState) { + oc.log.Info("state changed", "prev_state", oc.prevState, "new_state", status) + oc.prevState = status + } +} + +// transferLeader tries to transfer leadership to another server. +func (oc *OpConductor) transferLeader() error { + // TransferLeader here will do round robin to try to transfer leadership to the next healthy node. + oc.log.Info("transferring leadership", "server", oc.cons.ServerID()) + err := oc.cons.TransferLeader() + if err == nil { + oc.leader.Store(false) + return nil // success + } + + switch { + case errors.Is(err, raft.ErrNotLeader): + // This node is not the leader, do nothing. + oc.log.Warn("cannot transfer leadership since current server is not the leader") + return nil + default: + oc.log.Error("failed to transfer leadership", "err", err) + return err + } +} + +func (oc *OpConductor) stopSequencer() error { + oc.log.Info("stopping sequencer", "server", oc.cons.ServerID(), "leader", oc.leader.Load(), "healthy", oc.healthy.Load(), "active", oc.seqActive.Load()) + + _, err := oc.ctrl.StopSequencer(context.Background()) + if err != nil { + if strings.Contains(err.Error(), driver.ErrSequencerAlreadyStopped.Error()) { + oc.log.Warn("sequencer already stopped.", "err", err) + } else { + return errors.Wrap(err, "failed to stop sequencer") + } + } + + oc.seqActive.Store(false) + return nil +} + +func (oc *OpConductor) startSequencer() error { + ctx := context.Background() + + // When starting sequencer, we need to make sure that the current node has the latest unsafe head from the consensus protocol + // If not, then we wait for the unsafe head to catch up or gossip it to op-node manually from op-conductor. + unsafeInCons, unsafeInNode, err := oc.compareUnsafeHead(ctx) + // if there's a mismatch, try to post the unsafe head to op-node + if err != nil { + if errors.Is(err, ErrUnsafeHeadMismarch) && uint64(unsafeInCons.ExecutionPayload.BlockNumber)-unsafeInNode.NumberU64() == 1 { + // tries to post the unsafe head to op-node when head is only 1 block behind (most likely due to gossip delay) + if innerErr := oc.ctrl.PostUnsafePayload(ctx, unsafeInCons); innerErr != nil { + oc.log.Error("failed to post unsafe head payload envelope to op-node", "err", innerErr) + } + } + return err + } + + oc.log.Info("starting sequencer", "server", oc.cons.ServerID(), "leader", oc.leader.Load(), "healthy", oc.healthy.Load(), "active", oc.seqActive.Load()) + if err = oc.ctrl.StartSequencer(ctx, unsafeInCons.ExecutionPayload.BlockHash); err != nil { + // cannot directly compare using Errors.Is because the error is returned from an JSON RPC server which lost its type. + if !strings.Contains(err.Error(), driver.ErrSequencerAlreadyStarted.Error()) { + return fmt.Errorf("failed to start sequencer: %w", err) + } else { + oc.log.Warn("sequencer already started.", "err", err) + } + } + + oc.seqActive.Store(true) + return nil +} + +func (oc *OpConductor) compareUnsafeHead(ctx context.Context) (*eth.ExecutionPayloadEnvelope, eth.BlockInfo, error) { + unsafeInCons := oc.cons.LatestUnsafePayload() + if unsafeInCons == nil { + return nil, nil, ErrUnableToRetrieveUnsafeHeadFromConsensus + } + + unsafeInNode, err := oc.ctrl.LatestUnsafeBlock(ctx) + if err != nil { + return unsafeInCons, nil, errors.Wrap(err, "failed to get latest unsafe block from EL during compareUnsafeHead phase") + } + + oc.log.Debug("comparing unsafe head", "consensus", unsafeInCons.ExecutionPayload.BlockNumber, "node", unsafeInNode.NumberU64()) + if unsafeInCons.ExecutionPayload.BlockHash != unsafeInNode.Hash() { + oc.log.Warn( + "latest unsafe block in consensus is not the same as the one in op-node", + "consensus_hash", unsafeInCons.ExecutionPayload.BlockHash, + "consensus_block_num", unsafeInCons.ExecutionPayload.BlockNumber, + "node_hash", unsafeInNode.Hash(), + "node_block_num", unsafeInNode.NumberU64(), + ) + + return unsafeInCons, unsafeInNode, ErrUnsafeHeadMismarch + } + + return unsafeInCons, unsafeInNode, nil +} + +func (oc *OpConductor) updateSequencerActiveStatus() error { + active, err := oc.ctrl.SequencerActive(oc.shutdownCtx) + if err != nil { + return errors.Wrap(err, "failed to get sequencer active status") + } + oc.log.Info("sequencer active status updated", "active", active) + oc.seqActive.Store(active) + return nil +} diff --git a/op-conductor/conductor/service_test.go b/op-conductor/conductor/service_test.go new file mode 100644 index 000000000000..9f61ed90ba18 --- /dev/null +++ b/op-conductor/conductor/service_test.go @@ -0,0 +1,728 @@ +package conductor + +import ( + "context" + "errors" + "math/big" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" + "github.com/hashicorp/go-multierror" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/suite" + + clientmocks "github.com/ethereum-optimism/optimism/op-conductor/client/mocks" + consensusmocks "github.com/ethereum-optimism/optimism/op-conductor/consensus/mocks" + "github.com/ethereum-optimism/optimism/op-conductor/health" + healthmocks "github.com/ethereum-optimism/optimism/op-conductor/health/mocks" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" +) + +func mockConfig(t *testing.T) Config { + now := uint64(time.Now().Unix()) + return Config{ + ConsensusAddr: "127.0.0.1", + ConsensusPort: 50050, + RaftServerID: "SequencerA", + RaftStorageDir: "/tmp/raft", + RaftBootstrap: false, + NodeRPC: "http://node:8545", + ExecutionRPC: "http://geth:8545", + Paused: false, + HealthCheck: HealthCheckConfig{ + Interval: 1, + UnsafeInterval: 3, + SafeInterval: 5, + MinPeerCount: 1, + }, + RollupCfg: rollup.Config{ + Genesis: rollup.Genesis{ + L1: eth.BlockID{ + Hash: [32]byte{1, 2}, + Number: 100, + }, + L2: eth.BlockID{ + Hash: [32]byte{2, 3}, + Number: 0, + }, + L2Time: now, + SystemConfig: eth.SystemConfig{ + BatcherAddr: [20]byte{1}, + Overhead: [32]byte{1}, + Scalar: [32]byte{1}, + GasLimit: 30000000, + }, + }, + BlockTime: 2, + MaxSequencerDrift: 600, + SeqWindowSize: 3600, + ChannelTimeout: 300, + L1ChainID: big.NewInt(1), + L2ChainID: big.NewInt(2), + RegolithTime: &now, + CanyonTime: &now, + BatchInboxAddress: [20]byte{1, 2}, + DepositContractAddress: [20]byte{2, 3}, + L1SystemConfigAddress: [20]byte{3, 4}, + ProtocolVersionsAddress: [20]byte{4, 5}, + }, + RPCEnableProxy: false, + } +} + +type OpConductorTestSuite struct { + suite.Suite + + conductor *OpConductor + healthUpdateCh chan error + leaderUpdateCh chan bool + + ctx context.Context + err error + log log.Logger + cfg Config + version string + ctrl *clientmocks.SequencerControl + cons *consensusmocks.Consensus + hmon *healthmocks.HealthMonitor + + syncEnabled bool // syncEnabled controls whether synchronization is enabled for test actions. + next chan struct{} // next is used to signal when the next action in the test can proceed. + wg sync.WaitGroup // wg ensures that test actions are completed before moving on. +} + +func (s *OpConductorTestSuite) SetupSuite() { + s.ctx = context.Background() + s.log = testlog.Logger(s.T(), log.LevelDebug) + s.cfg = mockConfig(s.T()) + s.version = "v0.0.1" + s.next = make(chan struct{}, 1) +} + +func (s *OpConductorTestSuite) SetupTest() { + // initialize for every test so that method call count starts from 0 + s.ctrl = &clientmocks.SequencerControl{} + s.cons = &consensusmocks.Consensus{} + s.hmon = &healthmocks.HealthMonitor{} + s.cons.EXPECT().ServerID().Return("SequencerA") + + conductor, err := NewOpConductor(s.ctx, &s.cfg, s.log, s.version, s.ctrl, s.cons, s.hmon) + s.NoError(err) + s.conductor = conductor + + s.healthUpdateCh = make(chan error, 1) + s.hmon.EXPECT().Start().Return(nil) + s.conductor.healthUpdateCh = s.healthUpdateCh + + s.leaderUpdateCh = make(chan bool, 1) + s.conductor.leaderUpdateCh = s.leaderUpdateCh + + s.err = errors.New("error") + s.syncEnabled = false // default to no sync, turn it on by calling s.enableSynchronization() +} + +func (s *OpConductorTestSuite) TearDownTest() { + s.hmon.EXPECT().Stop().Return(nil) + s.cons.EXPECT().Shutdown().Return(nil) + + if s.syncEnabled { + s.wg.Add(1) + s.next <- struct{}{} + } + s.NoError(s.conductor.Stop(s.ctx)) + s.True(s.conductor.Stopped()) +} + +func (s *OpConductorTestSuite) startConductor() { + err := s.conductor.Start(s.ctx) + s.NoError(err) + s.False(s.conductor.Stopped()) +} + +// enableSynchronization wraps conductor actionFn with extra synchronization logic +// so that we could control the execution of actionFn and observe the internal state transition in between. +func (s *OpConductorTestSuite) enableSynchronization() { + s.syncEnabled = true + s.conductor.loopActionFn = func() { + <-s.next + s.conductor.loopAction() + s.wg.Done() + } + s.startConductor() +} + +func (s *OpConductorTestSuite) disableSynchronization() { + s.syncEnabled = false + s.startConductor() +} + +func (s *OpConductorTestSuite) execute(fn func()) { + s.wg.Add(1) + if fn != nil { + fn() + } + s.next <- struct{}{} + s.wg.Wait() +} + +func updateStatusAndExecuteAction[T any](s *OpConductorTestSuite, ch chan T, status T) { + fn := func() { + ch <- status + } + s.execute(fn) // this executes status update + s.executeAction() +} + +func (s *OpConductorTestSuite) updateLeaderStatusAndExecuteAction(status bool) { + updateStatusAndExecuteAction[bool](s, s.leaderUpdateCh, status) +} + +func (s *OpConductorTestSuite) updateHealthStatusAndExecuteAction(status error) { + updateStatusAndExecuteAction[error](s, s.healthUpdateCh, status) +} + +func (s *OpConductorTestSuite) executeAction() { + s.execute(nil) +} + +// Scenario 1: pause -> resume -> stop +func (s *OpConductorTestSuite) TestControlLoop1() { + s.disableSynchronization() + + // Pause + err := s.conductor.Pause(s.ctx) + s.NoError(err) + s.True(s.conductor.Paused()) + + // Send health update, make sure it can still be consumed. + s.healthUpdateCh <- nil + s.healthUpdateCh <- nil + + // Resume + s.ctrl.EXPECT().SequencerActive(mock.Anything).Return(false, nil) + err = s.conductor.Resume(s.ctx) + s.NoError(err) + s.False(s.conductor.Paused()) + + // Stop + s.hmon.EXPECT().Stop().Return(nil) + s.cons.EXPECT().Shutdown().Return(nil) + err = s.conductor.Stop(s.ctx) + s.NoError(err) + s.True(s.conductor.Stopped()) +} + +// Scenario 2: pause -> pause -> resume -> resume +func (s *OpConductorTestSuite) TestControlLoop2() { + s.disableSynchronization() + + // Pause + err := s.conductor.Pause(s.ctx) + s.NoError(err) + s.True(s.conductor.Paused()) + + // Pause again, this shouldn't block or cause any other issues + err = s.conductor.Pause(s.ctx) + s.NoError(err) + s.True(s.conductor.Paused()) + + // Resume + s.ctrl.EXPECT().SequencerActive(mock.Anything).Return(false, nil) + err = s.conductor.Resume(s.ctx) + s.NoError(err) + s.False(s.conductor.Paused()) + + // Resume + err = s.conductor.Resume(s.ctx) + s.NoError(err) + s.False(s.conductor.Paused()) + + // Stop + s.hmon.EXPECT().Stop().Return(nil) + s.cons.EXPECT().Shutdown().Return(nil) + err = s.conductor.Stop(s.ctx) + s.NoError(err) + s.True(s.conductor.Stopped()) +} + +// Scenario 3: pause -> stop +func (s *OpConductorTestSuite) TestControlLoop3() { + s.disableSynchronization() + + // Pause + err := s.conductor.Pause(s.ctx) + s.NoError(err) + s.True(s.conductor.Paused()) + + // Stop + s.hmon.EXPECT().Stop().Return(nil) + s.cons.EXPECT().Shutdown().Return(nil) + err = s.conductor.Stop(s.ctx) + s.NoError(err) + s.True(s.conductor.Stopped()) +} + +// In this test, we have a follower that is not healthy and not sequencing, it becomes leader through election. +// But since it does not have the same unsafe head as in consensus. We expect it to transfer leadership to another node. +// [follower, not healthy, not sequencing] -- become leader --> [leader, not healthy, not sequencing] -- transfer leadership --> [follower, not healthy, not sequencing] +func (s *OpConductorTestSuite) TestScenario1() { + s.enableSynchronization() + + // set initial state + s.conductor.leader.Store(false) + s.conductor.healthy.Store(false) + s.conductor.seqActive.Store(false) + s.conductor.hcerr = health.ErrSequencerNotHealthy + s.conductor.prevState = &state{ + leader: false, + healthy: false, + active: false, + } + + // unsafe in consensus is different than unsafe in node. + mockPayload := ð.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + BlockNumber: 2, + BlockHash: [32]byte{4, 5, 6}, + }, + } + mockBlockInfo := &testutils.MockBlockInfo{ + InfoNum: 1, + InfoHash: [32]byte{1, 2, 3}, + } + s.cons.EXPECT().TransferLeader().Return(nil) + s.cons.EXPECT().LatestUnsafePayload().Return(mockPayload).Times(1) + s.ctrl.EXPECT().LatestUnsafeBlock(mock.Anything).Return(mockBlockInfo, nil).Times(1) + + // become leader + s.updateLeaderStatusAndExecuteAction(true) + + // expect to transfer leadership, go back to [follower, not healthy, not sequencing] + s.False(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) + s.Equal(health.ErrSequencerNotHealthy, s.conductor.hcerr) + s.Equal(&state{ + leader: true, + healthy: false, + active: false, + }, s.conductor.prevState) + s.cons.AssertNumberOfCalls(s.T(), "TransferLeader", 1) +} + +// In this test, we have a follower that is not healthy and not sequencing. it becomes healthy and we expect it to stay as follower and not start sequencing. +// [follower, not healthy, not sequencing] -- become healthy --> [follower, healthy, not sequencing] +func (s *OpConductorTestSuite) TestScenario2() { + s.enableSynchronization() + + // set initial state + s.conductor.leader.Store(false) + s.conductor.healthy.Store(false) + s.conductor.seqActive.Store(false) + + // become healthy + s.updateHealthStatusAndExecuteAction(nil) + + // expect to stay as follower, go to [follower, healthy, not sequencing] + s.False(s.conductor.leader.Load()) + s.True(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) +} + +// In this test, we have a follower that is healthy and not sequencing, we send a leader update to it and expect it to start sequencing. +// [follower, healthy, not sequencing] -- become leader --> [leader, healthy, sequencing] +func (s *OpConductorTestSuite) TestScenario3() { + s.enableSynchronization() + + mockPayload := ð.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + BlockNumber: 1, + Timestamp: hexutil.Uint64(time.Now().Unix()), + BlockHash: [32]byte{1, 2, 3}, + }, + } + + mockBlockInfo := &testutils.MockBlockInfo{ + InfoNum: 1, + InfoHash: [32]byte{1, 2, 3}, + } + s.cons.EXPECT().LatestUnsafePayload().Return(mockPayload).Times(1) + s.ctrl.EXPECT().LatestUnsafeBlock(mock.Anything).Return(mockBlockInfo, nil).Times(1) + s.ctrl.EXPECT().StartSequencer(mock.Anything, mock.Anything).Return(nil).Times(1) + + // [follower, healthy, not sequencing] + s.False(s.conductor.leader.Load()) + s.True(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) + + // become leader + s.updateLeaderStatusAndExecuteAction(true) + + // [leader, healthy, sequencing] + s.True(s.conductor.leader.Load()) + s.True(s.conductor.healthy.Load()) + s.True(s.conductor.seqActive.Load()) + s.ctrl.AssertCalled(s.T(), "StartSequencer", mock.Anything, mock.Anything) + s.ctrl.AssertCalled(s.T(), "LatestUnsafeBlock", mock.Anything) +} + +// This test setup is the same as Scenario 3, the difference is that scenario 3 is all happy case and in this test, we try to exhaust all the error cases. +// [follower, healthy, not sequencing] -- become leader, unsafe head does not match, retry, eventually succeed --> [leader, healthy, sequencing] +func (s *OpConductorTestSuite) TestScenario4() { + s.enableSynchronization() + + // unsafe in consensus is 1 block ahead of unsafe in sequencer, we try to post the unsafe payload to sequencer and return error to allow retry + // this is normal because the latest unsafe (in consensus) might not arrive at sequencer through p2p yet + mockPayload := ð.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + BlockNumber: 2, + Timestamp: hexutil.Uint64(time.Now().Unix()), + BlockHash: [32]byte{1, 2, 3}, + }, + } + + mockBlockInfo := &testutils.MockBlockInfo{ + InfoNum: 1, + InfoHash: [32]byte{2, 3, 4}, + } + s.cons.EXPECT().LatestUnsafePayload().Return(mockPayload).Times(1) + s.ctrl.EXPECT().LatestUnsafeBlock(mock.Anything).Return(mockBlockInfo, nil).Times(1) + s.ctrl.EXPECT().PostUnsafePayload(mock.Anything, mock.Anything).Return(nil).Times(1) + + s.updateLeaderStatusAndExecuteAction(true) + + // [leader, healthy, not sequencing] + s.True(s.conductor.leader.Load()) + s.True(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) + s.ctrl.AssertNotCalled(s.T(), "StartSequencer", mock.Anything, mock.Anything) + s.ctrl.AssertNumberOfCalls(s.T(), "LatestUnsafeBlock", 1) + s.ctrl.AssertNumberOfCalls(s.T(), "PostUnsafePayload", 1) + s.cons.AssertNumberOfCalls(s.T(), "LatestUnsafePayload", 1) + + // unsafe caught up, we try to start sequencer at specified block and succeeds + mockBlockInfo.InfoNum = 2 + mockBlockInfo.InfoHash = [32]byte{1, 2, 3} + s.cons.EXPECT().LatestUnsafePayload().Return(mockPayload).Times(1) + s.ctrl.EXPECT().LatestUnsafeBlock(mock.Anything).Return(mockBlockInfo, nil).Times(1) + s.ctrl.EXPECT().StartSequencer(mock.Anything, mockBlockInfo.InfoHash).Return(nil).Times(1) + + s.executeAction() + + // [leader, healthy, sequencing] + s.True(s.conductor.leader.Load()) + s.True(s.conductor.healthy.Load()) + s.True(s.conductor.seqActive.Load()) + s.ctrl.AssertNumberOfCalls(s.T(), "LatestUnsafeBlock", 2) + s.ctrl.AssertNumberOfCalls(s.T(), "PostUnsafePayload", 1) + s.ctrl.AssertNumberOfCalls(s.T(), "StartSequencer", 1) + s.cons.AssertNumberOfCalls(s.T(), "LatestUnsafePayload", 2) +} + +// In this test, we have a follower that is healthy and not sequencing, we send a unhealthy update to it and expect it to stay as follower and not start sequencing. +// [follower, healthy, not sequencing] -- become unhealthy --> [follower, not healthy, not sequencing] +func (s *OpConductorTestSuite) TestScenario5() { + s.enableSynchronization() + + // set initial state + s.conductor.leader.Store(false) + s.conductor.healthy.Store(true) + s.conductor.seqActive.Store(false) + + // become unhealthy + s.updateHealthStatusAndExecuteAction(health.ErrSequencerNotHealthy) + + // expect to stay as follower, go to [follower, not healthy, not sequencing] + s.False(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) +} + +// In this test, we have a leader that is healthy and sequencing, we send a leader update to it and expect it to stop sequencing. +// [leader, healthy, sequencing] -- step down as leader --> [follower, healthy, not sequencing] +func (s *OpConductorTestSuite) TestScenario6() { + s.enableSynchronization() + + // set initial state + s.conductor.leader.Store(true) + s.conductor.healthy.Store(true) + s.conductor.seqActive.Store(true) + + s.ctrl.EXPECT().StopSequencer(mock.Anything).Return(common.Hash{}, nil).Times(1) + + // step down as leader + s.updateLeaderStatusAndExecuteAction(false) + + // expect to stay as follower, go to [follower, healthy, not sequencing] + s.False(s.conductor.leader.Load()) + s.True(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) + s.ctrl.AssertCalled(s.T(), "StopSequencer", mock.Anything) +} + +// In this test, we have a leader that is healthy and sequencing, we send a unhealthy update to it and expect it to stop sequencing and transfer leadership. +// 1. [leader, healthy, sequencing] -- become unhealthy --> +// 2. [leader, unhealthy, sequencing] -- stop sequencing, transfer leadership --> [follower, unhealthy, not sequencing] +func (s *OpConductorTestSuite) TestScenario7() { + s.enableSynchronization() + + // set initial state + s.conductor.leader.Store(true) + s.conductor.healthy.Store(true) + s.conductor.seqActive.Store(true) + + s.cons.EXPECT().TransferLeader().Return(nil).Times(1) + s.ctrl.EXPECT().StopSequencer(mock.Anything).Return(common.Hash{}, nil).Times(1) + + // become unhealthy + s.updateHealthStatusAndExecuteAction(health.ErrSequencerNotHealthy) + + // expect to step down as leader and stop sequencing + s.False(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) + s.ctrl.AssertCalled(s.T(), "StopSequencer", mock.Anything) + s.cons.AssertCalled(s.T(), "TransferLeader") +} + +// In this test, we have a leader that is healthy and sequencing, we send a unhealthy update to it and expect it to stop sequencing and transfer leadership. +// However, the action we needed to take failed temporarily, so we expect it to retry until it succeeds. +// 1. [leader, healthy, sequencing] -- become unhealthy --> +// 2. [leader, unhealthy, sequencing] -- stop sequencing failed, transfer leadership failed, retry --> +// 3. [leader, unhealthy, sequencing] -- stop sequencing succeeded, transfer leadership failed, retry --> +// 4. [leader, unhealthy, not sequencing] -- transfer leadership succeeded --> +// 5. [follower, unhealthy, not sequencing] +func (s *OpConductorTestSuite) TestFailureAndRetry1() { + s.enableSynchronization() + + // set initial state + s.conductor.leader.Store(true) + s.conductor.healthy.Store(true) + s.conductor.seqActive.Store(true) + s.conductor.prevState = &state{ + leader: true, + healthy: true, + active: true, + } + + // step 1 & 2: become unhealthy, stop sequencing failed, transfer leadership failed + s.cons.EXPECT().TransferLeader().Return(s.err).Times(1) + s.ctrl.EXPECT().StopSequencer(mock.Anything).Return(common.Hash{}, s.err).Times(1) + + s.updateHealthStatusAndExecuteAction(health.ErrSequencerNotHealthy) + + s.True(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.True(s.conductor.seqActive.Load()) + s.Equal(health.ErrSequencerNotHealthy, s.conductor.hcerr) + s.Equal(&state{ + leader: true, + healthy: true, + active: true, + }, s.conductor.prevState) + s.ctrl.AssertNumberOfCalls(s.T(), "StopSequencer", 1) + s.cons.AssertNumberOfCalls(s.T(), "TransferLeader", 1) + + // step 3: [leader, unhealthy, sequencing] -- stop sequencing succeeded, transfer leadership failed, retry + s.ctrl.EXPECT().StopSequencer(mock.Anything).Return(common.Hash{}, nil).Times(1) + s.cons.EXPECT().TransferLeader().Return(s.err).Times(1) + + s.executeAction() + + s.True(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) + s.Equal(health.ErrSequencerNotHealthy, s.conductor.hcerr) + s.Equal(&state{ + leader: true, + healthy: true, + active: true, + }, s.conductor.prevState) + s.ctrl.AssertNumberOfCalls(s.T(), "StopSequencer", 2) + s.cons.AssertNumberOfCalls(s.T(), "TransferLeader", 2) + + // step 4: [leader, unhealthy, not sequencing] -- transfer leadership succeeded + s.cons.EXPECT().TransferLeader().Return(nil).Times(1) + + s.executeAction() + + // [follower, unhealthy, not sequencing] + s.False(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) + s.Equal(health.ErrSequencerNotHealthy, s.conductor.hcerr) + s.Equal(&state{ + leader: true, + healthy: false, + active: false, + }, s.conductor.prevState) + s.ctrl.AssertNumberOfCalls(s.T(), "StopSequencer", 2) + s.cons.AssertNumberOfCalls(s.T(), "TransferLeader", 3) +} + +// In this test, we have a leader that is healthy and sequencing, we send a unhealthy update to it and expect it to stop sequencing and transfer leadership. +// However, the action we needed to take failed temporarily, so we expect it to retry until it succeeds. +// 1. [leader, healthy, sequencing] -- become unhealthy --> +// 2. [leader, unhealthy, sequencing] -- stop sequencing failed, transfer leadership succeeded, retry --> +// 3. [follower, unhealthy, sequencing] -- stop sequencing succeeded --> +// 4. [follower, unhealthy, not sequencing] +func (s *OpConductorTestSuite) TestFailureAndRetry2() { + s.enableSynchronization() + + // set initial state + s.conductor.leader.Store(true) + s.conductor.healthy.Store(true) + s.conductor.seqActive.Store(true) + s.conductor.prevState = &state{ + leader: true, + healthy: true, + active: true, + } + + // step 1 & 2: become unhealthy, stop sequencing failed, transfer leadership succeeded, retry + s.cons.EXPECT().TransferLeader().Return(nil).Times(1) + s.ctrl.EXPECT().StopSequencer(mock.Anything).Return(common.Hash{}, s.err).Times(1) + + s.updateHealthStatusAndExecuteAction(health.ErrSequencerNotHealthy) + + s.False(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.True(s.conductor.seqActive.Load()) + s.Equal(health.ErrSequencerNotHealthy, s.conductor.hcerr) + s.Equal(&state{ + leader: true, + healthy: true, + active: true, + }, s.conductor.prevState) + s.ctrl.AssertNumberOfCalls(s.T(), "StopSequencer", 1) + s.cons.AssertNumberOfCalls(s.T(), "TransferLeader", 1) + + // step 3: [follower, unhealthy, sequencing] -- stop sequencing succeeded + s.ctrl.EXPECT().StopSequencer(mock.Anything).Return(common.Hash{}, nil).Times(1) + + s.executeAction() + + s.False(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) + s.Equal(&state{ + leader: false, + healthy: false, + active: true, + }, s.conductor.prevState) + s.ctrl.AssertNumberOfCalls(s.T(), "StopSequencer", 2) + s.cons.AssertNumberOfCalls(s.T(), "TransferLeader", 1) +} + +// In this test, we have a follower that is unhealthy (due to active sequencer not producing blocks) +// Then leadership transfer happened, and the follower became leader. We expect it to start sequencing and catch up eventually. +// 1. [follower, healthy, not sequencing] -- become unhealthy --> +// 2. [follower, unhealthy, not sequencing] -- gained leadership --> +// 3. [leader, unhealthy, not sequencing] -- start sequencing --> +// 4. [leader, unhealthy, sequencing] -> become healthy again --> +// 5. [leader, healthy, sequencing] +func (s *OpConductorTestSuite) TestFailureAndRetry3() { + s.enableSynchronization() + + // set initial state, healthy follower + s.conductor.leader.Store(false) + s.conductor.healthy.Store(true) + s.conductor.seqActive.Store(false) + s.conductor.prevState = &state{ + leader: false, + healthy: true, + active: false, + } + + s.log.Info("1. become unhealthy") + s.updateHealthStatusAndExecuteAction(health.ErrSequencerNotHealthy) + + s.False(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.False(s.conductor.seqActive.Load()) + s.Equal(&state{ + leader: false, + healthy: false, + active: false, + }, s.conductor.prevState) + + s.log.Info("2 & 3. gained leadership, start sequencing") + mockPayload := ð.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + BlockNumber: 1, + BlockHash: [32]byte{1, 2, 3}, + }, + } + mockBlockInfo := &testutils.MockBlockInfo{ + InfoNum: 1, + InfoHash: [32]byte{1, 2, 3}, + } + s.cons.EXPECT().LatestUnsafePayload().Return(mockPayload).Times(2) + s.ctrl.EXPECT().LatestUnsafeBlock(mock.Anything).Return(mockBlockInfo, nil).Times(2) + s.ctrl.EXPECT().StartSequencer(mock.Anything, mockBlockInfo.InfoHash).Return(nil).Times(1) + + s.updateLeaderStatusAndExecuteAction(true) + + s.True(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.True(s.conductor.seqActive.Load()) + s.Equal(&state{ + leader: true, + healthy: false, + active: false, + }, s.conductor.prevState) + s.cons.AssertNumberOfCalls(s.T(), "LatestUnsafePayload", 2) + s.ctrl.AssertNumberOfCalls(s.T(), "LatestUnsafeBlock", 2) + s.ctrl.AssertNumberOfCalls(s.T(), "StartSequencer", 1) + + s.log.Info("4. stay unhealthy for a bit while catching up") + s.updateHealthStatusAndExecuteAction(health.ErrSequencerNotHealthy) + + s.True(s.conductor.leader.Load()) + s.False(s.conductor.healthy.Load()) + s.True(s.conductor.seqActive.Load()) + s.Equal(&state{ + leader: true, + healthy: false, + active: false, + }, s.conductor.prevState) + + s.log.Info("5. become healthy again") + s.updateHealthStatusAndExecuteAction(nil) + + // need to use eventually here because starting from step 4, the loop is gonna queue an action and retry until it became healthy again. + // use eventually here avoids the situation where health update is consumed after the action is executed. + s.Eventually(func() bool { + res := s.conductor.leader.Load() == true && + s.conductor.healthy.Load() == true && + s.conductor.seqActive.Load() == true && + s.conductor.prevState.Equal(&state{ + leader: true, + healthy: true, + active: true, + }) + if !res { + s.executeAction() + } + return res + }, 2*time.Second, 100*time.Millisecond) +} + +func (s *OpConductorTestSuite) TestHandleInitError() { + // This will cause an error in the init function, which should cause the conductor to stop successfully without issues. + _, err := New(s.ctx, &s.cfg, s.log, s.version) + _, ok := err.(*multierror.Error) + // error should not be a multierror, this means that init failed, but Stop() succeeded, which is what we expect. + s.False(ok) +} + +func TestControlLoop(t *testing.T) { + suite.Run(t, new(OpConductorTestSuite)) +} diff --git a/op-conductor/consensus/iface.go b/op-conductor/consensus/iface.go new file mode 100644 index 000000000000..7134eef5a273 --- /dev/null +++ b/op-conductor/consensus/iface.go @@ -0,0 +1,69 @@ +package consensus + +import ( + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +// ServerSuffrage determines whether a Server in a Configuration gets a vote. +type ServerSuffrage int + +const ( + // Voter is a server whose vote is counted in elections. + Voter ServerSuffrage = iota + // Nonvoter is a server that receives log entries but is not considered for + // elections or commitment purposes. + Nonvoter +) + +func (s ServerSuffrage) String() string { + switch s { + case Voter: + return "Voter" + case Nonvoter: + return "Nonvoter" + } + return "ServerSuffrage" +} + +// ServerInfo defines the server information. +type ServerInfo struct { + ID string `json:"id"` + Addr string `json:"addr"` + Suffrage ServerSuffrage `json:"suffrage"` +} + +// Consensus defines the consensus interface for leadership election. +// +//go:generate mockery --name Consensus --output mocks/ --with-expecter=true +type Consensus interface { + // AddVoter adds a voting member into the cluster, voter is eligible to become leader. + AddVoter(id, addr string) error + // AddNonVoter adds a non-voting member into the cluster, non-voter is not eligible to become leader. + AddNonVoter(id, addr string) error + // DemoteVoter demotes a voting member into a non-voting member, if leader is being demoted, it will cause a new leader election. + DemoteVoter(id string) error + // RemoveServer removes a member (both voter or non-voter) from the cluster, if leader is being removed, it will cause a new leader election. + RemoveServer(id string) error + // LeaderCh returns a channel that will be notified when leadership status changes (true = leader, false = follower) + LeaderCh() <-chan bool + // Leader returns if it is the leader of the cluster. + Leader() bool + // LeaderWithID returns the leader's server ID and address. + LeaderWithID() *ServerInfo + // ServerID returns the server ID of the consensus. + ServerID() string + // TransferLeader triggers leadership transfer to another member in the cluster. + TransferLeader() error + // TransferLeaderTo triggers leadership transfer to a specific member in the cluster. + TransferLeaderTo(id, addr string) error + // ClusterMembership returns the current cluster membership configuration. + ClusterMembership() ([]*ServerInfo, error) + + // CommitPayload commits latest unsafe payload to the FSM. + CommitUnsafePayload(payload *eth.ExecutionPayloadEnvelope) error + // LatestUnsafeBlock returns the latest unsafe payload from FSM. + LatestUnsafePayload() *eth.ExecutionPayloadEnvelope + + // Shutdown shuts down the consensus protocol client. + Shutdown() error +} diff --git a/op-conductor/consensus/mocks/Consensus.go b/op-conductor/consensus/mocks/Consensus.go new file mode 100644 index 000000000000..e85ad0410013 --- /dev/null +++ b/op-conductor/consensus/mocks/Consensus.go @@ -0,0 +1,694 @@ +// Code generated by mockery v2.39.1. DO NOT EDIT. + +package mocks + +import ( + consensus "github.com/ethereum-optimism/optimism/op-conductor/consensus" + eth "github.com/ethereum-optimism/optimism/op-service/eth" + + mock "github.com/stretchr/testify/mock" +) + +// Consensus is an autogenerated mock type for the Consensus type +type Consensus struct { + mock.Mock +} + +type Consensus_Expecter struct { + mock *mock.Mock +} + +func (_m *Consensus) EXPECT() *Consensus_Expecter { + return &Consensus_Expecter{mock: &_m.Mock} +} + +// AddNonVoter provides a mock function with given fields: id, addr +func (_m *Consensus) AddNonVoter(id string, addr string) error { + ret := _m.Called(id, addr) + + if len(ret) == 0 { + panic("no return value specified for AddNonVoter") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string, string) error); ok { + r0 = rf(id, addr) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Consensus_AddNonVoter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddNonVoter' +type Consensus_AddNonVoter_Call struct { + *mock.Call +} + +// AddNonVoter is a helper method to define mock.On call +// - id string +// - addr string +func (_e *Consensus_Expecter) AddNonVoter(id interface{}, addr interface{}) *Consensus_AddNonVoter_Call { + return &Consensus_AddNonVoter_Call{Call: _e.mock.On("AddNonVoter", id, addr)} +} + +func (_c *Consensus_AddNonVoter_Call) Run(run func(id string, addr string)) *Consensus_AddNonVoter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string)) + }) + return _c +} + +func (_c *Consensus_AddNonVoter_Call) Return(_a0 error) *Consensus_AddNonVoter_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_AddNonVoter_Call) RunAndReturn(run func(string, string) error) *Consensus_AddNonVoter_Call { + _c.Call.Return(run) + return _c +} + +// AddVoter provides a mock function with given fields: id, addr +func (_m *Consensus) AddVoter(id string, addr string) error { + ret := _m.Called(id, addr) + + if len(ret) == 0 { + panic("no return value specified for AddVoter") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string, string) error); ok { + r0 = rf(id, addr) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Consensus_AddVoter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddVoter' +type Consensus_AddVoter_Call struct { + *mock.Call +} + +// AddVoter is a helper method to define mock.On call +// - id string +// - addr string +func (_e *Consensus_Expecter) AddVoter(id interface{}, addr interface{}) *Consensus_AddVoter_Call { + return &Consensus_AddVoter_Call{Call: _e.mock.On("AddVoter", id, addr)} +} + +func (_c *Consensus_AddVoter_Call) Run(run func(id string, addr string)) *Consensus_AddVoter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string)) + }) + return _c +} + +func (_c *Consensus_AddVoter_Call) Return(_a0 error) *Consensus_AddVoter_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_AddVoter_Call) RunAndReturn(run func(string, string) error) *Consensus_AddVoter_Call { + _c.Call.Return(run) + return _c +} + +// ClusterMembership provides a mock function with given fields: +func (_m *Consensus) ClusterMembership() ([]*consensus.ServerInfo, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for ClusterMembership") + } + + var r0 []*consensus.ServerInfo + var r1 error + if rf, ok := ret.Get(0).(func() ([]*consensus.ServerInfo, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() []*consensus.ServerInfo); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*consensus.ServerInfo) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Consensus_ClusterMembership_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ClusterMembership' +type Consensus_ClusterMembership_Call struct { + *mock.Call +} + +// ClusterMembership is a helper method to define mock.On call +func (_e *Consensus_Expecter) ClusterMembership() *Consensus_ClusterMembership_Call { + return &Consensus_ClusterMembership_Call{Call: _e.mock.On("ClusterMembership")} +} + +func (_c *Consensus_ClusterMembership_Call) Run(run func()) *Consensus_ClusterMembership_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Consensus_ClusterMembership_Call) Return(_a0 []*consensus.ServerInfo, _a1 error) *Consensus_ClusterMembership_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Consensus_ClusterMembership_Call) RunAndReturn(run func() ([]*consensus.ServerInfo, error)) *Consensus_ClusterMembership_Call { + _c.Call.Return(run) + return _c +} + +// CommitUnsafePayload provides a mock function with given fields: payload +func (_m *Consensus) CommitUnsafePayload(payload *eth.ExecutionPayloadEnvelope) error { + ret := _m.Called(payload) + + if len(ret) == 0 { + panic("no return value specified for CommitUnsafePayload") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*eth.ExecutionPayloadEnvelope) error); ok { + r0 = rf(payload) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Consensus_CommitUnsafePayload_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CommitUnsafePayload' +type Consensus_CommitUnsafePayload_Call struct { + *mock.Call +} + +// CommitUnsafePayload is a helper method to define mock.On call +// - payload *eth.ExecutionPayloadEnvelope +func (_e *Consensus_Expecter) CommitUnsafePayload(payload interface{}) *Consensus_CommitUnsafePayload_Call { + return &Consensus_CommitUnsafePayload_Call{Call: _e.mock.On("CommitUnsafePayload", payload)} +} + +func (_c *Consensus_CommitUnsafePayload_Call) Run(run func(payload *eth.ExecutionPayloadEnvelope)) *Consensus_CommitUnsafePayload_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*eth.ExecutionPayloadEnvelope)) + }) + return _c +} + +func (_c *Consensus_CommitUnsafePayload_Call) Return(_a0 error) *Consensus_CommitUnsafePayload_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_CommitUnsafePayload_Call) RunAndReturn(run func(*eth.ExecutionPayloadEnvelope) error) *Consensus_CommitUnsafePayload_Call { + _c.Call.Return(run) + return _c +} + +// DemoteVoter provides a mock function with given fields: id +func (_m *Consensus) DemoteVoter(id string) error { + ret := _m.Called(id) + + if len(ret) == 0 { + panic("no return value specified for DemoteVoter") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(id) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Consensus_DemoteVoter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DemoteVoter' +type Consensus_DemoteVoter_Call struct { + *mock.Call +} + +// DemoteVoter is a helper method to define mock.On call +// - id string +func (_e *Consensus_Expecter) DemoteVoter(id interface{}) *Consensus_DemoteVoter_Call { + return &Consensus_DemoteVoter_Call{Call: _e.mock.On("DemoteVoter", id)} +} + +func (_c *Consensus_DemoteVoter_Call) Run(run func(id string)) *Consensus_DemoteVoter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *Consensus_DemoteVoter_Call) Return(_a0 error) *Consensus_DemoteVoter_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_DemoteVoter_Call) RunAndReturn(run func(string) error) *Consensus_DemoteVoter_Call { + _c.Call.Return(run) + return _c +} + +// LatestUnsafePayload provides a mock function with given fields: +func (_m *Consensus) LatestUnsafePayload() *eth.ExecutionPayloadEnvelope { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for LatestUnsafePayload") + } + + var r0 *eth.ExecutionPayloadEnvelope + if rf, ok := ret.Get(0).(func() *eth.ExecutionPayloadEnvelope); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*eth.ExecutionPayloadEnvelope) + } + } + + return r0 +} + +// Consensus_LatestUnsafePayload_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LatestUnsafePayload' +type Consensus_LatestUnsafePayload_Call struct { + *mock.Call +} + +// LatestUnsafePayload is a helper method to define mock.On call +func (_e *Consensus_Expecter) LatestUnsafePayload() *Consensus_LatestUnsafePayload_Call { + return &Consensus_LatestUnsafePayload_Call{Call: _e.mock.On("LatestUnsafePayload")} +} + +func (_c *Consensus_LatestUnsafePayload_Call) Run(run func()) *Consensus_LatestUnsafePayload_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Consensus_LatestUnsafePayload_Call) Return(_a0 *eth.ExecutionPayloadEnvelope) *Consensus_LatestUnsafePayload_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_LatestUnsafePayload_Call) RunAndReturn(run func() *eth.ExecutionPayloadEnvelope) *Consensus_LatestUnsafePayload_Call { + _c.Call.Return(run) + return _c +} + +// Leader provides a mock function with given fields: +func (_m *Consensus) Leader() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Leader") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// Consensus_Leader_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Leader' +type Consensus_Leader_Call struct { + *mock.Call +} + +// Leader is a helper method to define mock.On call +func (_e *Consensus_Expecter) Leader() *Consensus_Leader_Call { + return &Consensus_Leader_Call{Call: _e.mock.On("Leader")} +} + +func (_c *Consensus_Leader_Call) Run(run func()) *Consensus_Leader_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Consensus_Leader_Call) Return(_a0 bool) *Consensus_Leader_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_Leader_Call) RunAndReturn(run func() bool) *Consensus_Leader_Call { + _c.Call.Return(run) + return _c +} + +// LeaderCh provides a mock function with given fields: +func (_m *Consensus) LeaderCh() <-chan bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for LeaderCh") + } + + var r0 <-chan bool + if rf, ok := ret.Get(0).(func() <-chan bool); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan bool) + } + } + + return r0 +} + +// Consensus_LeaderCh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LeaderCh' +type Consensus_LeaderCh_Call struct { + *mock.Call +} + +// LeaderCh is a helper method to define mock.On call +func (_e *Consensus_Expecter) LeaderCh() *Consensus_LeaderCh_Call { + return &Consensus_LeaderCh_Call{Call: _e.mock.On("LeaderCh")} +} + +func (_c *Consensus_LeaderCh_Call) Run(run func()) *Consensus_LeaderCh_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Consensus_LeaderCh_Call) Return(_a0 <-chan bool) *Consensus_LeaderCh_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_LeaderCh_Call) RunAndReturn(run func() <-chan bool) *Consensus_LeaderCh_Call { + _c.Call.Return(run) + return _c +} + +// LeaderWithID provides a mock function with given fields: +func (_m *Consensus) LeaderWithID() *consensus.ServerInfo { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for LeaderWithID") + } + + var r0 *consensus.ServerInfo + if rf, ok := ret.Get(0).(func() *consensus.ServerInfo); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*consensus.ServerInfo) + } + } + + return r0 +} + +// Consensus_LeaderWithID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LeaderWithID' +type Consensus_LeaderWithID_Call struct { + *mock.Call +} + +// LeaderWithID is a helper method to define mock.On call +func (_e *Consensus_Expecter) LeaderWithID() *Consensus_LeaderWithID_Call { + return &Consensus_LeaderWithID_Call{Call: _e.mock.On("LeaderWithID")} +} + +func (_c *Consensus_LeaderWithID_Call) Run(run func()) *Consensus_LeaderWithID_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Consensus_LeaderWithID_Call) Return(_a0 *consensus.ServerInfo) *Consensus_LeaderWithID_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_LeaderWithID_Call) RunAndReturn(run func() *consensus.ServerInfo) *Consensus_LeaderWithID_Call { + _c.Call.Return(run) + return _c +} + +// RemoveServer provides a mock function with given fields: id +func (_m *Consensus) RemoveServer(id string) error { + ret := _m.Called(id) + + if len(ret) == 0 { + panic("no return value specified for RemoveServer") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(id) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Consensus_RemoveServer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveServer' +type Consensus_RemoveServer_Call struct { + *mock.Call +} + +// RemoveServer is a helper method to define mock.On call +// - id string +func (_e *Consensus_Expecter) RemoveServer(id interface{}) *Consensus_RemoveServer_Call { + return &Consensus_RemoveServer_Call{Call: _e.mock.On("RemoveServer", id)} +} + +func (_c *Consensus_RemoveServer_Call) Run(run func(id string)) *Consensus_RemoveServer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *Consensus_RemoveServer_Call) Return(_a0 error) *Consensus_RemoveServer_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_RemoveServer_Call) RunAndReturn(run func(string) error) *Consensus_RemoveServer_Call { + _c.Call.Return(run) + return _c +} + +// ServerID provides a mock function with given fields: +func (_m *Consensus) ServerID() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for ServerID") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// Consensus_ServerID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ServerID' +type Consensus_ServerID_Call struct { + *mock.Call +} + +// ServerID is a helper method to define mock.On call +func (_e *Consensus_Expecter) ServerID() *Consensus_ServerID_Call { + return &Consensus_ServerID_Call{Call: _e.mock.On("ServerID")} +} + +func (_c *Consensus_ServerID_Call) Run(run func()) *Consensus_ServerID_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Consensus_ServerID_Call) Return(_a0 string) *Consensus_ServerID_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_ServerID_Call) RunAndReturn(run func() string) *Consensus_ServerID_Call { + _c.Call.Return(run) + return _c +} + +// Shutdown provides a mock function with given fields: +func (_m *Consensus) Shutdown() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Shutdown") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Consensus_Shutdown_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Shutdown' +type Consensus_Shutdown_Call struct { + *mock.Call +} + +// Shutdown is a helper method to define mock.On call +func (_e *Consensus_Expecter) Shutdown() *Consensus_Shutdown_Call { + return &Consensus_Shutdown_Call{Call: _e.mock.On("Shutdown")} +} + +func (_c *Consensus_Shutdown_Call) Run(run func()) *Consensus_Shutdown_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Consensus_Shutdown_Call) Return(_a0 error) *Consensus_Shutdown_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_Shutdown_Call) RunAndReturn(run func() error) *Consensus_Shutdown_Call { + _c.Call.Return(run) + return _c +} + +// TransferLeader provides a mock function with given fields: +func (_m *Consensus) TransferLeader() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for TransferLeader") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Consensus_TransferLeader_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferLeader' +type Consensus_TransferLeader_Call struct { + *mock.Call +} + +// TransferLeader is a helper method to define mock.On call +func (_e *Consensus_Expecter) TransferLeader() *Consensus_TransferLeader_Call { + return &Consensus_TransferLeader_Call{Call: _e.mock.On("TransferLeader")} +} + +func (_c *Consensus_TransferLeader_Call) Run(run func()) *Consensus_TransferLeader_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Consensus_TransferLeader_Call) Return(_a0 error) *Consensus_TransferLeader_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_TransferLeader_Call) RunAndReturn(run func() error) *Consensus_TransferLeader_Call { + _c.Call.Return(run) + return _c +} + +// TransferLeaderTo provides a mock function with given fields: id, addr +func (_m *Consensus) TransferLeaderTo(id string, addr string) error { + ret := _m.Called(id, addr) + + if len(ret) == 0 { + panic("no return value specified for TransferLeaderTo") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string, string) error); ok { + r0 = rf(id, addr) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Consensus_TransferLeaderTo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TransferLeaderTo' +type Consensus_TransferLeaderTo_Call struct { + *mock.Call +} + +// TransferLeaderTo is a helper method to define mock.On call +// - id string +// - addr string +func (_e *Consensus_Expecter) TransferLeaderTo(id interface{}, addr interface{}) *Consensus_TransferLeaderTo_Call { + return &Consensus_TransferLeaderTo_Call{Call: _e.mock.On("TransferLeaderTo", id, addr)} +} + +func (_c *Consensus_TransferLeaderTo_Call) Run(run func(id string, addr string)) *Consensus_TransferLeaderTo_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string)) + }) + return _c +} + +func (_c *Consensus_TransferLeaderTo_Call) Return(_a0 error) *Consensus_TransferLeaderTo_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Consensus_TransferLeaderTo_Call) RunAndReturn(run func(string, string) error) *Consensus_TransferLeaderTo_Call { + _c.Call.Return(run) + return _c +} + +// NewConsensus creates a new instance of Consensus. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewConsensus(t interface { + mock.TestingT + Cleanup(func()) +}) *Consensus { + mock := &Consensus{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/op-conductor/consensus/raft.go b/op-conductor/consensus/raft.go new file mode 100644 index 000000000000..37d9ac69d70a --- /dev/null +++ b/op-conductor/consensus/raft.go @@ -0,0 +1,245 @@ +package consensus + +import ( + "bytes" + "fmt" + "net" + "os" + "path/filepath" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/hashicorp/raft" + boltdb "github.com/hashicorp/raft-boltdb" + "github.com/pkg/errors" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +const defaultTimeout = 5 * time.Second + +var _ Consensus = (*RaftConsensus)(nil) + +// RaftConsensus implements Consensus using raft protocol. +type RaftConsensus struct { + log log.Logger + rollupCfg *rollup.Config + + serverID raft.ServerID + r *raft.Raft + + unsafeTracker *unsafeHeadTracker +} + +// NewRaftConsensus creates a new RaftConsensus instance. +func NewRaftConsensus(log log.Logger, serverID, serverAddr, storageDir string, bootstrap bool, rollupCfg *rollup.Config) (*RaftConsensus, error) { + rc := raft.DefaultConfig() + rc.LocalID = raft.ServerID(serverID) + + baseDir := filepath.Join(storageDir, serverID) + if _, err := os.Stat(baseDir); os.IsNotExist(err) { + if err := os.MkdirAll(baseDir, 0o755); err != nil { + return nil, fmt.Errorf("error creating storage dir: %w", err) + } + } + + var err error + logStorePath := filepath.Join(baseDir, "raft-log.db") + logStore, err := boltdb.NewBoltStore(logStorePath) + if err != nil { + return nil, fmt.Errorf(`boltdb.NewBoltStore(%q): %w`, logStorePath, err) + } + + stableStorePath := filepath.Join(baseDir, "raft-stable.db") + stableStore, err := boltdb.NewBoltStore(stableStorePath) + if err != nil { + return nil, fmt.Errorf(`boltdb.NewBoltStore(%q): %w`, stableStorePath, err) + } + + snapshotStore, err := raft.NewFileSnapshotStoreWithLogger(baseDir, 1, rc.Logger) + if err != nil { + return nil, fmt.Errorf(`raft.NewFileSnapshotStore(%q): %w`, baseDir, err) + } + + addr, err := net.ResolveTCPAddr("tcp", serverAddr) + if err != nil { + return nil, errors.Wrap(err, "failed to resolve tcp address") + } + + maxConnPool := 10 + timeout := 5 * time.Second + bindAddr := fmt.Sprintf("0.0.0.0:%d", addr.Port) + transport, err := raft.NewTCPTransportWithLogger(bindAddr, addr, maxConnPool, timeout, rc.Logger) + if err != nil { + return nil, errors.Wrap(err, "failed to create raft tcp transport") + } + + fsm := &unsafeHeadTracker{} + + r, err := raft.NewRaft(rc, fsm, logStore, stableStore, snapshotStore, transport) + if err != nil { + log.Error("failed to create raft", "err", err) + return nil, errors.Wrap(err, "failed to create raft") + } + + // If bootstrap = true, start raft in bootstrap mode, this will allow the current node to elect itself as leader when there's no other participants + // and allow other nodes to join the cluster. + if bootstrap { + cfg := raft.Configuration{ + Servers: []raft.Server{ + { + ID: rc.LocalID, + Address: raft.ServerAddress(serverAddr), + Suffrage: raft.Voter, + }, + }, + } + + f := r.BootstrapCluster(cfg) + if err := f.Error(); err != nil { + return nil, errors.Wrap(err, "failed to bootstrap raft cluster") + } + } + + return &RaftConsensus{ + log: log, + r: r, + serverID: raft.ServerID(serverID), + unsafeTracker: fsm, + rollupCfg: rollupCfg, + }, nil +} + +// AddNonVoter implements Consensus, it tries to add a non-voting member into the cluster. +func (rc *RaftConsensus) AddNonVoter(id string, addr string) error { + if err := rc.r.AddNonvoter(raft.ServerID(id), raft.ServerAddress(addr), 0, defaultTimeout).Error(); err != nil { + rc.log.Error("failed to add non-voter", "id", id, "addr", addr, "err", err) + return err + } + return nil +} + +// AddVoter implements Consensus, it tries to add a voting member into the cluster. +func (rc *RaftConsensus) AddVoter(id string, addr string) error { + if err := rc.r.AddVoter(raft.ServerID(id), raft.ServerAddress(addr), 0, defaultTimeout).Error(); err != nil { + rc.log.Error("failed to add voter", "id", id, "addr", addr, "err", err) + return err + } + return nil +} + +// DemoteVoter implements Consensus, it tries to demote a voting member into a non-voting member in the cluster. +func (rc *RaftConsensus) DemoteVoter(id string) error { + if err := rc.r.DemoteVoter(raft.ServerID(id), 0, defaultTimeout).Error(); err != nil { + rc.log.Error("failed to demote voter", "id", id, "err", err) + return err + } + return nil +} + +// Leader implements Consensus, it returns true if it is the leader of the cluster. +func (rc *RaftConsensus) Leader() bool { + _, id := rc.r.LeaderWithID() + return id == rc.serverID +} + +// LeaderWithID implements Consensus, it returns the leader's server ID and address. +func (rc *RaftConsensus) LeaderWithID() *ServerInfo { + addr, id := rc.r.LeaderWithID() + return &ServerInfo{ + ID: string(id), + Addr: string(addr), + Suffrage: Voter, // leader will always be Voter + } +} + +// LeaderCh implements Consensus, it returns a channel that will be notified when leadership status changes (true = leader, false = follower). +func (rc *RaftConsensus) LeaderCh() <-chan bool { + return rc.r.LeaderCh() +} + +// RemoveServer implements Consensus, it tries to remove a member (both voter or non-voter) from the cluster, if leader is being removed, it will cause a new leader election. +func (rc *RaftConsensus) RemoveServer(id string) error { + if err := rc.r.RemoveServer(raft.ServerID(id), 0, defaultTimeout).Error(); err != nil { + rc.log.Error("failed to remove voter", "id", id, "err", err) + return err + } + return nil +} + +// ServerID implements Consensus, it returns the server ID of the current server. +func (rc *RaftConsensus) ServerID() string { + return string(rc.serverID) +} + +// TransferLeader implements Consensus, it triggers leadership transfer to another member in the cluster. +func (rc *RaftConsensus) TransferLeader() error { + if err := rc.r.LeadershipTransfer().Error(); err != nil { + // Expected error if not leader + if errors.Is(err, raft.ErrNotLeader) { + return nil + } + + rc.log.Error("failed to transfer leadership", "err", err) + return err + } + return nil +} + +// TransferLeaderTo implements Consensus, it triggers leadership transfer to a specific member in the cluster. +func (rc *RaftConsensus) TransferLeaderTo(id string, addr string) error { + if err := rc.r.LeadershipTransferToServer(raft.ServerID(id), raft.ServerAddress(addr)).Error(); err != nil { + rc.log.Error("failed to transfer leadership to server", "id", id, "addr", addr, "err", err) + return err + } + return nil +} + +// Shutdown implements Consensus, it shuts down the consensus protocol client. +func (rc *RaftConsensus) Shutdown() error { + if err := rc.r.Shutdown().Error(); err != nil { + rc.log.Error("failed to shutdown raft", "err", err) + return err + } + return nil +} + +// CommitUnsafePayload implements Consensus, it commits latest unsafe payload to the cluster FSM. +func (rc *RaftConsensus) CommitUnsafePayload(payload *eth.ExecutionPayloadEnvelope) error { + var buf bytes.Buffer + if _, err := payload.MarshalSSZ(&buf); err != nil { + return errors.Wrap(err, "failed to marshal payload envelope") + } + + f := rc.r.Apply(buf.Bytes(), defaultTimeout) + if err := f.Error(); err != nil { + return errors.Wrap(err, "failed to apply payload envelope") + } + + return nil +} + +// LatestUnsafePayload implements Consensus, it returns the latest unsafe payload from FSM. +func (rc *RaftConsensus) LatestUnsafePayload() *eth.ExecutionPayloadEnvelope { + payload := rc.unsafeTracker.UnsafeHead() + return payload +} + +// ClusterMembership implements Consensus, it returns the current cluster membership configuration. +func (rc *RaftConsensus) ClusterMembership() ([]*ServerInfo, error) { + var future raft.ConfigurationFuture + if future = rc.r.GetConfiguration(); future.Error() != nil { + return nil, future.Error() + } + + var servers []*ServerInfo + for _, srv := range future.Configuration().Servers { + servers = append(servers, &ServerInfo{ + ID: string(srv.ID), + Addr: string(srv.Address), + Suffrage: ServerSuffrage(srv.Suffrage), + }) + } + return servers, nil +} diff --git a/op-conductor/consensus/raft_fsm.go b/op-conductor/consensus/raft_fsm.go new file mode 100644 index 000000000000..7333fb8f2a44 --- /dev/null +++ b/op-conductor/consensus/raft_fsm.go @@ -0,0 +1,102 @@ +package consensus + +import ( + "bytes" + "fmt" + "io" + "sync" + + "github.com/ethereum/go-ethereum/log" + "github.com/hashicorp/raft" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +var _ raft.FSM = (*unsafeHeadTracker)(nil) + +// unsafeHeadTracker implements raft.FSM for storing unsafe head payload into raft consensus layer. +type unsafeHeadTracker struct { + mtx sync.RWMutex + unsafeHead *eth.ExecutionPayloadEnvelope +} + +// Apply implements raft.FSM, it applies the latest change (latest unsafe head payload) to FSM. +func (t *unsafeHeadTracker) Apply(l *raft.Log) interface{} { + if l.Data == nil || len(l.Data) == 0 { + return fmt.Errorf("log data is nil or empty") + } + + data := ð.ExecutionPayloadEnvelope{} + if err := data.UnmarshalSSZ(uint32(len(l.Data)), bytes.NewReader(l.Data)); err != nil { + return err + } + + t.mtx.Lock() + defer t.mtx.Unlock() + if t.unsafeHead == nil || t.unsafeHead.ExecutionPayload.BlockNumber < data.ExecutionPayload.BlockNumber { + t.unsafeHead = data + } + + return nil +} + +// Restore implements raft.FSM, it restores state from snapshot. +func (t *unsafeHeadTracker) Restore(snapshot io.ReadCloser) error { + var buf bytes.Buffer + n, err := io.Copy(&buf, snapshot) + snapshot.Close() + if err != nil { + return fmt.Errorf("error reading snapshot data: %w", err) + } + + data := ð.ExecutionPayloadEnvelope{} + if err := data.UnmarshalSSZ(uint32(n), bytes.NewReader(buf.Bytes())); err != nil { + return fmt.Errorf("error unmarshalling snapshot: %w", err) + } + + t.mtx.Lock() + defer t.mtx.Unlock() + t.unsafeHead = data + return nil +} + +// Snapshot implements raft.FSM, it creates a snapshot of the current state. +func (t *unsafeHeadTracker) Snapshot() (raft.FSMSnapshot, error) { + t.mtx.RLock() + defer t.mtx.RUnlock() + + return &snapshot{ + unsafeHead: t.unsafeHead, + }, nil +} + +// UnsafeHead returns the latest unsafe head payload. +func (t *unsafeHeadTracker) UnsafeHead() *eth.ExecutionPayloadEnvelope { + t.mtx.RLock() + defer t.mtx.RUnlock() + + return t.unsafeHead +} + +var _ raft.FSMSnapshot = (*snapshot)(nil) + +type snapshot struct { + log log.Logger + unsafeHead *eth.ExecutionPayloadEnvelope +} + +// Persist implements raft.FSMSnapshot, it writes the snapshot to the given sink. +func (s *snapshot) Persist(sink raft.SnapshotSink) error { + if _, err := s.unsafeHead.MarshalSSZ(sink); err != nil { + if cerr := sink.Cancel(); cerr != nil { + s.log.Error("error cancelling snapshot sink", "error", cerr) + } + return fmt.Errorf("error writing data to sink: %w", err) + } + + return sink.Close() +} + +// Release implements raft.FSMSnapshot. +// We don't really need to do anything within Release as the snapshot is not gonna change after creation, and we don't hold any reference to closable resources. +func (s *snapshot) Release() {} diff --git a/op-conductor/consensus/raft_fsm_test.go b/op-conductor/consensus/raft_fsm_test.go new file mode 100644 index 000000000000..4f390d17e555 --- /dev/null +++ b/op-conductor/consensus/raft_fsm_test.go @@ -0,0 +1,100 @@ +package consensus + +import ( + "bytes" + "io" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/hashicorp/raft" + "github.com/pkg/errors" + "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type Bytes32 [32]byte + +func createPayloadEnvelope() *eth.ExecutionPayloadEnvelope { + hash := common.HexToHash("0x12345") + one := hexutil.Uint64(1) + return ð.ExecutionPayloadEnvelope{ + ParentBeaconBlockRoot: &hash, + ExecutionPayload: ð.ExecutionPayload{ + BlockNumber: eth.Uint64Quantity(222), + BlockHash: common.HexToHash("0x888"), + Withdrawals: &types.Withdrawals{{Index: 1, Validator: 2, Address: common.HexToAddress("0x123"), Amount: 3}}, + ExcessBlobGas: &one, + BlobGasUsed: &one, + }} +} +func TestUnsafeHeadTracker(t *testing.T) { + tracker := &unsafeHeadTracker{ + unsafeHead: createPayloadEnvelope(), + } + + t.Run("Apply", func(t *testing.T) { + data := createPayloadEnvelope() + + var buf bytes.Buffer + _, err := data.MarshalSSZ(&buf) + require.NoError(t, err) + + l := raft.Log{Data: buf.Bytes()} + require.Nil(t, tracker.Apply(&l)) + require.Equal(t, hexutil.Uint64(222), tracker.unsafeHead.ExecutionPayload.BlockNumber) + }) + + t.Run("Restore", func(t *testing.T) { + data := createPayloadEnvelope() + + mrc, err := NewMockReadCloser(data) + require.NoError(t, err) + err = tracker.Restore(mrc) + require.NoError(t, err) + require.Equal(t, hexutil.Uint64(222), tracker.unsafeHead.ExecutionPayload.BlockNumber) + }) +} + +type mockReadCloser struct { + currentPosition int + data *eth.ExecutionPayloadEnvelope + buffer []byte +} + +func NewMockReadCloser(data *eth.ExecutionPayloadEnvelope) (*mockReadCloser, error) { + mrc := &mockReadCloser{ + currentPosition: 0, + data: data, + buffer: make([]byte, 0), + } + + var buf bytes.Buffer + if _, err := data.MarshalSSZ(&buf); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal execution payload envelope") + } + mrc.buffer = buf.Bytes() + + return mrc, nil +} + +func (m *mockReadCloser) Read(p []byte) (n int, err error) { + if m.currentPosition >= len(m.buffer) { + return 0, io.EOF + } + + end := m.currentPosition + len(p) + if end > len(m.buffer) { + end = len(m.buffer) + err = io.EOF + } + n = copy(p, m.buffer[m.currentPosition:end]) + m.currentPosition = end + return n, err +} + +func (m *mockReadCloser) Close() error { + return nil +} diff --git a/op-conductor/consensus/raft_test.go b/op-conductor/consensus/raft_test.go new file mode 100644 index 000000000000..775e0a77847f --- /dev/null +++ b/op-conductor/consensus/raft_test.go @@ -0,0 +1,75 @@ +package consensus + +import ( + "os" + "testing" + "time" + + "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" + "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" +) + +func TestCommitAndRead(t *testing.T) { + log := testlog.Logger(t, log.LevelInfo) + serverID := "SequencerA" + serverAddr := "127.0.0.1:0" + bootstrap := true + now := uint64(time.Now().Unix()) + rollupCfg := &rollup.Config{ + CanyonTime: &now, + } + storageDir := "/tmp/sequencerA" + if err := os.RemoveAll(storageDir); err != nil { + t.Fatal(err) + } + + cons, err := NewRaftConsensus(log, serverID, serverAddr, storageDir, bootstrap, rollupCfg) + require.NoError(t, err) + + // wait till it became leader + <-cons.LeaderCh() + + // eth.BlockV1 + payload := ð.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + BlockNumber: 1, + Timestamp: hexutil.Uint64(now - 20), + Transactions: []eth.Data{}, + ExtraData: []byte{}, + }, + } + + err = cons.CommitUnsafePayload(payload) + // ExecutionPayloadEnvelope is expected to fail when unmarshalling a blockV1 + require.Error(t, err) + + // eth.BlockV3 + one := hexutil.Uint64(1) + hash := common.HexToHash("0x12345") + payload = ð.ExecutionPayloadEnvelope{ + ParentBeaconBlockRoot: &hash, + ExecutionPayload: ð.ExecutionPayload{ + BlockNumber: 2, + Timestamp: hexutil.Uint64(time.Now().Unix()), + Transactions: []eth.Data{}, + ExtraData: []byte{}, + Withdrawals: &types.Withdrawals{}, + ExcessBlobGas: &one, + BlobGasUsed: &one, + }, + } + + err = cons.CommitUnsafePayload(payload) + // ExecutionPayloadEnvelope is expected to succeed when unmarshalling a blockV3 + require.NoError(t, err) + + unsafeHead := cons.LatestUnsafePayload() + require.Equal(t, payload, unsafeHead) +} diff --git a/op-conductor/flags/flags.go b/op-conductor/flags/flags.go new file mode 100644 index 000000000000..c16de5c645db --- /dev/null +++ b/op-conductor/flags/flags.go @@ -0,0 +1,129 @@ +package flags + +import ( + "fmt" + + "github.com/urfave/cli/v2" + + opservice "github.com/ethereum-optimism/optimism/op-service" + opflags "github.com/ethereum-optimism/optimism/op-service/flags" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/oppprof" + oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" +) + +const EnvVarPrefix = "OP_CONDUCTOR" + +var ( + ConsensusAddr = &cli.StringFlag{ + Name: "consensus.addr", + Usage: "Address to listen for consensus connections", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "CONSENSUS_ADDR"), + Value: "127.0.0.1", + } + ConsensusPort = &cli.IntFlag{ + Name: "consensus.port", + Usage: "Port to listen for consensus connections", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "CONSENSUS_PORT"), + Value: 50050, + } + RaftBootstrap = &cli.BoolFlag{ + Name: "raft.bootstrap", + Usage: "If this node should bootstrap a new raft cluster", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "RAFT_BOOTSTRAP"), + Value: false, + } + RaftServerID = &cli.StringFlag{ + Name: "raft.server.id", + Usage: "Unique ID for this server used by raft consensus", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "RAFT_SERVER_ID"), + } + RaftStorageDir = &cli.StringFlag{ + Name: "raft.storage.dir", + Usage: "Directory to store raft data", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "RAFT_STORAGE_DIR"), + } + NodeRPC = &cli.StringFlag{ + Name: "node.rpc", + Usage: "HTTP provider URL for op-node", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "NODE_RPC"), + } + ExecutionRPC = &cli.StringFlag{ + Name: "execution.rpc", + Usage: "HTTP provider URL for execution layer", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "EXECUTION_RPC"), + } + HealthCheckInterval = &cli.Uint64Flag{ + Name: "healthcheck.interval", + Usage: "Interval between health checks", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "HEALTHCHECK_INTERVAL"), + } + HealthCheckUnsafeInterval = &cli.Uint64Flag{ + Name: "healthcheck.unsafe-interval", + Usage: "Interval allowed between unsafe head and now measured in seconds", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "HEALTHCHECK_UNSAFE_INTERVAL"), + } + HealthCheckSafeInterval = &cli.Uint64Flag{ + Name: "healthcheck.safe-interval", + Usage: "Interval between safe head progression measured in seconds", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "HEALTHCHECK_SAFE_INTERVAL"), + } + HealthCheckMinPeerCount = &cli.Uint64Flag{ + Name: "healthcheck.min-peer-count", + Usage: "Minimum number of peers required to be considered healthy", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "HEALTHCHECK_MIN_PEER_COUNT"), + } + Paused = &cli.BoolFlag{ + Name: "paused", + Usage: "Whether the conductor is paused", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "PAUSED"), + Value: false, + } + RPCEnableProxy = &cli.BoolFlag{ + Name: "rpc.enable-proxy", + Usage: "Enable the RPC proxy to underlying sequencer services", + EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "RPC_ENABLE_PROXY"), + Value: true, + } +) + +var requiredFlags = []cli.Flag{ + ConsensusAddr, + ConsensusPort, + RaftServerID, + RaftStorageDir, + NodeRPC, + ExecutionRPC, + HealthCheckInterval, + HealthCheckUnsafeInterval, + HealthCheckSafeInterval, + HealthCheckMinPeerCount, +} + +var optionalFlags = []cli.Flag{ + Paused, + RPCEnableProxy, + RaftBootstrap, +} + +func init() { + optionalFlags = append(optionalFlags, oprpc.CLIFlags(EnvVarPrefix)...) + optionalFlags = append(optionalFlags, oplog.CLIFlags(EnvVarPrefix)...) + optionalFlags = append(optionalFlags, opmetrics.CLIFlags(EnvVarPrefix)...) + optionalFlags = append(optionalFlags, oppprof.CLIFlags(EnvVarPrefix)...) + optionalFlags = append(optionalFlags, opflags.CLIFlags(EnvVarPrefix, "")...) + + Flags = append(requiredFlags, optionalFlags...) +} + +var Flags []cli.Flag + +func CheckRequired(ctx *cli.Context) error { + for _, f := range requiredFlags { + if !ctx.IsSet(f.Names()[0]) { + return fmt.Errorf("flag %s is required", f.Names()[0]) + } + } + return opflags.CheckRequiredXor(ctx) +} diff --git a/op-conductor/flags/flags_test.go b/op-conductor/flags/flags_test.go new file mode 100644 index 000000000000..812d9afb6400 --- /dev/null +++ b/op-conductor/flags/flags_test.go @@ -0,0 +1,88 @@ +package flags + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" + "github.com/urfave/cli/v2" + + opservice "github.com/ethereum-optimism/optimism/op-service" +) + +// TestOptionalFlagsDontSetRequired asserts that all flags deemed optional set +// the Required field to false. +func TestOptionalFlagsDontSetRequired(t *testing.T) { + for _, flag := range optionalFlags { + reqFlag, ok := flag.(cli.RequiredFlag) + require.True(t, ok) + require.False(t, reqFlag.IsRequired()) + } +} + +// TestUniqueFlags asserts that all flag names are unique, to avoid accidental conflicts between the many flags. +func TestUniqueFlags(t *testing.T) { + seenCLI := make(map[string]struct{}) + for _, flag := range Flags { + name := flag.Names()[0] + if _, ok := seenCLI[name]; ok { + t.Errorf("duplicate flag %s", name) + continue + } + seenCLI[name] = struct{}{} + } +} + +// TestBetaFlags test that all flags starting with "beta." have "BETA_" in the env var, and vice versa. +func TestBetaFlags(t *testing.T) { + for _, flag := range Flags { + envFlag, ok := flag.(interface { + GetEnvVars() []string + }) + if !ok || len(envFlag.GetEnvVars()) == 0 { // skip flags without env-var support + continue + } + name := flag.Names()[0] + envName := envFlag.GetEnvVars()[0] + if strings.HasPrefix(name, "beta.") { + require.Contains(t, envName, "BETA_", "%q flag must contain BETA in env var to match \"beta.\" flag name", name) + } + if strings.Contains(envName, "BETA_") { + require.True(t, strings.HasPrefix(name, "beta."), "%q flag must start with \"beta.\" in flag name to match \"BETA_\" env var", name) + } + } +} + +func TestHasEnvVar(t *testing.T) { + for _, flag := range Flags { + flag := flag + flagName := flag.Names()[0] + + t.Run(flagName, func(t *testing.T) { + envFlagGetter, ok := flag.(interface { + GetEnvVars() []string + }) + envFlags := envFlagGetter.GetEnvVars() + require.True(t, ok, "must be able to cast the flag to an EnvVar interface") + require.Equal(t, 1, len(envFlags), "flags should have exactly one env var") + }) + } +} + +func TestEnvVarFormat(t *testing.T) { + for _, flag := range Flags { + flag := flag + flagName := flag.Names()[0] + + t.Run(flagName, func(t *testing.T) { + envFlagGetter, ok := flag.(interface { + GetEnvVars() []string + }) + envFlags := envFlagGetter.GetEnvVars() + require.True(t, ok, "must be able to cast the flag to an EnvVar interface") + require.Equal(t, 1, len(envFlags), "flags should have exactly one env var") + expectedEnvVar := opservice.FlagNameToEnvVarName(flagName, "OP_CONDUCTOR") + require.Equal(t, expectedEnvVar, envFlags[0]) + }) + } +} diff --git a/op-conductor/health/mocks/HealthMonitor.go b/op-conductor/health/mocks/HealthMonitor.go new file mode 100644 index 000000000000..de85b716f739 --- /dev/null +++ b/op-conductor/health/mocks/HealthMonitor.go @@ -0,0 +1,169 @@ +// Code generated by mockery v2.39.1. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// HealthMonitor is an autogenerated mock type for the HealthMonitor type +type HealthMonitor struct { + mock.Mock +} + +type HealthMonitor_Expecter struct { + mock *mock.Mock +} + +func (_m *HealthMonitor) EXPECT() *HealthMonitor_Expecter { + return &HealthMonitor_Expecter{mock: &_m.Mock} +} + +// Start provides a mock function with given fields: +func (_m *HealthMonitor) Start() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Start") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// HealthMonitor_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start' +type HealthMonitor_Start_Call struct { + *mock.Call +} + +// Start is a helper method to define mock.On call +func (_e *HealthMonitor_Expecter) Start() *HealthMonitor_Start_Call { + return &HealthMonitor_Start_Call{Call: _e.mock.On("Start")} +} + +func (_c *HealthMonitor_Start_Call) Run(run func()) *HealthMonitor_Start_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *HealthMonitor_Start_Call) Return(_a0 error) *HealthMonitor_Start_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *HealthMonitor_Start_Call) RunAndReturn(run func() error) *HealthMonitor_Start_Call { + _c.Call.Return(run) + return _c +} + +// Stop provides a mock function with given fields: +func (_m *HealthMonitor) Stop() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Stop") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// HealthMonitor_Stop_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Stop' +type HealthMonitor_Stop_Call struct { + *mock.Call +} + +// Stop is a helper method to define mock.On call +func (_e *HealthMonitor_Expecter) Stop() *HealthMonitor_Stop_Call { + return &HealthMonitor_Stop_Call{Call: _e.mock.On("Stop")} +} + +func (_c *HealthMonitor_Stop_Call) Run(run func()) *HealthMonitor_Stop_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *HealthMonitor_Stop_Call) Return(_a0 error) *HealthMonitor_Stop_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *HealthMonitor_Stop_Call) RunAndReturn(run func() error) *HealthMonitor_Stop_Call { + _c.Call.Return(run) + return _c +} + +// Subscribe provides a mock function with given fields: +func (_m *HealthMonitor) Subscribe() <-chan error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Subscribe") + } + + var r0 <-chan error + if rf, ok := ret.Get(0).(func() <-chan error); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan error) + } + } + + return r0 +} + +// HealthMonitor_Subscribe_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Subscribe' +type HealthMonitor_Subscribe_Call struct { + *mock.Call +} + +// Subscribe is a helper method to define mock.On call +func (_e *HealthMonitor_Expecter) Subscribe() *HealthMonitor_Subscribe_Call { + return &HealthMonitor_Subscribe_Call{Call: _e.mock.On("Subscribe")} +} + +func (_c *HealthMonitor_Subscribe_Call) Run(run func()) *HealthMonitor_Subscribe_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *HealthMonitor_Subscribe_Call) Return(_a0 <-chan error) *HealthMonitor_Subscribe_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *HealthMonitor_Subscribe_Call) RunAndReturn(run func() <-chan error) *HealthMonitor_Subscribe_Call { + _c.Call.Return(run) + return _c +} + +// NewHealthMonitor creates a new instance of HealthMonitor. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewHealthMonitor(t interface { + mock.TestingT + Cleanup(func()) +}) *HealthMonitor { + mock := &HealthMonitor{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/op-conductor/health/monitor.go b/op-conductor/health/monitor.go new file mode 100644 index 000000000000..7a541e7b3876 --- /dev/null +++ b/op-conductor/health/monitor.go @@ -0,0 +1,198 @@ +package health + +import ( + "context" + "errors" + "sync" + "time" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-node/p2p" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/dial" +) + +var ( + ErrSequencerNotHealthy = errors.New("sequencer is not healthy") + ErrSequencerConnectionDown = errors.New("cannot connect to sequencer rpc endpoints") +) + +// HealthMonitor defines the interface for monitoring the health of the sequencer. +// +//go:generate mockery --name HealthMonitor --output mocks/ --with-expecter=true +type HealthMonitor interface { + // Subscribe returns a channel that will be notified for every health check. + Subscribe() <-chan error + // Start starts the health check. + Start() error + // Stop stops the health check. + Stop() error +} + +// NewSequencerHealthMonitor creates a new sequencer health monitor. +// interval is the interval between health checks measured in seconds. +// safeInterval is the interval between safe head progress measured in seconds. +// minPeerCount is the minimum number of peers required for the sequencer to be healthy. +func NewSequencerHealthMonitor(log log.Logger, interval, unsafeInterval, safeInterval, minPeerCount uint64, rollupCfg *rollup.Config, node dial.RollupClientInterface, p2p p2p.API) HealthMonitor { + return &SequencerHealthMonitor{ + log: log, + done: make(chan struct{}), + interval: interval, + healthUpdateCh: make(chan error), + rollupCfg: rollupCfg, + unsafeInterval: unsafeInterval, + safeInterval: safeInterval, + minPeerCount: minPeerCount, + timeProviderFn: currentTimeProvicer, + node: node, + p2p: p2p, + } +} + +// SequencerHealthMonitor monitors sequencer health. +type SequencerHealthMonitor struct { + log log.Logger + done chan struct{} + wg sync.WaitGroup + + rollupCfg *rollup.Config + unsafeInterval uint64 + safeInterval uint64 + minPeerCount uint64 + interval uint64 + healthUpdateCh chan error + lastSeenUnsafeNum uint64 + lastSeenUnsafeTime uint64 + + timeProviderFn func() uint64 + + node dial.RollupClientInterface + p2p p2p.API +} + +var _ HealthMonitor = (*SequencerHealthMonitor)(nil) + +// Start implements HealthMonitor. +func (hm *SequencerHealthMonitor) Start() error { + hm.log.Info("starting health monitor") + hm.wg.Add(1) + go hm.loop() + + hm.log.Info("health monitor started") + return nil +} + +// Stop implements HealthMonitor. +func (hm *SequencerHealthMonitor) Stop() error { + hm.log.Info("stopping health monitor") + close(hm.done) + hm.wg.Wait() + + hm.log.Info("health monitor stopped") + return nil +} + +// Subscribe implements HealthMonitor. +func (hm *SequencerHealthMonitor) Subscribe() <-chan error { + return hm.healthUpdateCh +} + +func (hm *SequencerHealthMonitor) loop() { + defer hm.wg.Done() + + duration := time.Duration(hm.interval) * time.Second + ticker := time.NewTicker(duration) + defer ticker.Stop() + + for { + select { + case <-hm.done: + return + case <-ticker.C: + hm.healthUpdateCh <- hm.healthCheck() + } + } +} + +// healthCheck checks the health of the sequencer by 3 criteria: +// 1. unsafe head is progressing per block time +// 2. unsafe head is not too far behind now (measured by unsafeInterval) +// 3. safe head is progressing every configured batch submission interval +// 4. peer count is above the configured minimum +func (hm *SequencerHealthMonitor) healthCheck() error { + ctx := context.Background() + status, err := hm.node.SyncStatus(ctx) + if err != nil { + hm.log.Error("health monitor failed to get sync status", "err", err) + return ErrSequencerConnectionDown + } + + now := hm.timeProviderFn() + + var timeDiff, blockDiff, expectedBlocks uint64 + if hm.lastSeenUnsafeNum != 0 { + timeDiff = now - hm.lastSeenUnsafeTime + blockDiff = status.UnsafeL2.Number - hm.lastSeenUnsafeNum + // how many blocks do we expect to see, minus 1 to account for edge case with respect to time. + // for example, if diff = 2.001s and block time = 2s, expecting to see 1 block could potentially cause sequencer to be considered unhealthy. + expectedBlocks = timeDiff / hm.rollupCfg.BlockTime + if expectedBlocks > 0 { + expectedBlocks-- + } + } + if status.UnsafeL2.Number > hm.lastSeenUnsafeNum { + hm.lastSeenUnsafeNum = status.UnsafeL2.Number + hm.lastSeenUnsafeTime = now + } + + if timeDiff > hm.rollupCfg.BlockTime && expectedBlocks > blockDiff { + hm.log.Error( + "unsafe head is not progressing as expected", + "now", now, + "unsafe_head_num", status.UnsafeL2.Number, + "last_seen_unsafe_num", hm.lastSeenUnsafeNum, + "last_seen_unsafe_time", hm.lastSeenUnsafeTime, + "unsafe_interval", hm.unsafeInterval, + ) + return ErrSequencerNotHealthy + } + + if now-status.UnsafeL2.Time > hm.unsafeInterval { + hm.log.Error( + "unsafe head is not progressing as expected", + "now", now, + "unsafe_head_num", status.UnsafeL2.Number, + "unsafe_head_time", status.UnsafeL2.Time, + "unsafe_interval", hm.unsafeInterval, + ) + return ErrSequencerNotHealthy + } + + if now-status.SafeL2.Time > hm.safeInterval { + hm.log.Error( + "safe head is not progressing as expected", + "now", now, + "safe_head_num", status.SafeL2.Number, + "safe_head_time", status.SafeL2.Time, + "safe_interval", hm.safeInterval, + ) + return ErrSequencerNotHealthy + } + + stats, err := hm.p2p.PeerStats(ctx) + if err != nil { + hm.log.Error("health monitor failed to get peer stats", "err", err) + return ErrSequencerConnectionDown + } + if uint64(stats.Connected) < hm.minPeerCount { + hm.log.Error("peer count is below minimum", "connected", stats.Connected, "minPeerCount", hm.minPeerCount) + return ErrSequencerNotHealthy + } + + return nil +} + +func currentTimeProvicer() uint64 { + return uint64(time.Now().Unix()) +} diff --git a/op-conductor/health/monitor_test.go b/op-conductor/health/monitor_test.go new file mode 100644 index 000000000000..0384e5b4b0b5 --- /dev/null +++ b/op-conductor/health/monitor_test.go @@ -0,0 +1,217 @@ +package health + +import ( + "context" + "testing" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/suite" + + "github.com/ethereum-optimism/optimism/op-node/p2p" + p2pMocks "github.com/ethereum-optimism/optimism/op-node/p2p/mocks" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" +) + +const ( + unhealthyPeerCount = 0 + minPeerCount = 1 + healthyPeerCount = 2 + blockTime = 2 +) + +type HealthMonitorTestSuite struct { + suite.Suite + + log log.Logger + interval uint64 + minPeerCount uint64 + rollupCfg *rollup.Config +} + +func (s *HealthMonitorTestSuite) SetupSuite() { + s.log = testlog.Logger(s.T(), log.LevelDebug) + s.interval = 1 + s.minPeerCount = minPeerCount + s.rollupCfg = &rollup.Config{ + BlockTime: blockTime, + } +} + +func (s *HealthMonitorTestSuite) SetupMonitor( + now, unsafeInterval, safeInterval uint64, + mockRollupClient *testutils.MockRollupClient, + mockP2P *p2pMocks.API, +) *SequencerHealthMonitor { + tp := &timeProvider{now: now} + if mockP2P == nil { + mockP2P = &p2pMocks.API{} + ps1 := &p2p.PeerStats{ + Connected: healthyPeerCount, + } + mockP2P.EXPECT().PeerStats(context.Background()).Return(ps1, nil) + } + monitor := &SequencerHealthMonitor{ + log: s.log, + done: make(chan struct{}), + interval: s.interval, + healthUpdateCh: make(chan error), + rollupCfg: s.rollupCfg, + unsafeInterval: unsafeInterval, + safeInterval: safeInterval, + minPeerCount: s.minPeerCount, + timeProviderFn: tp.Now, + node: mockRollupClient, + p2p: mockP2P, + } + err := monitor.Start() + s.NoError(err) + return monitor +} + +func (s *HealthMonitorTestSuite) TestUnhealthyLowPeerCount() { + s.T().Parallel() + now := uint64(time.Now().Unix()) + + rc := &testutils.MockRollupClient{} + ss1 := mockSyncStatus(now-1, 1, now-3, 0) + rc.ExpectSyncStatus(ss1, nil) + rc.ExpectSyncStatus(ss1, nil) + + pc := &p2pMocks.API{} + ps1 := &p2p.PeerStats{ + Connected: unhealthyPeerCount, + } + pc.EXPECT().PeerStats(context.Background()).Return(ps1, nil).Times(1) + + monitor := s.SetupMonitor(now, 60, 60, rc, pc) + + healthUpdateCh := monitor.Subscribe() + healthy := <-healthUpdateCh + s.NotNil(healthy) + + s.NoError(monitor.Stop()) +} + +func (s *HealthMonitorTestSuite) TestUnhealthyUnsafeHeadNotProgressing() { + s.T().Parallel() + now := uint64(time.Now().Unix()) + + rc := &testutils.MockRollupClient{} + ss1 := mockSyncStatus(now, 5, now-8, 1) + for i := 0; i < 6; i++ { + rc.ExpectSyncStatus(ss1, nil) + } + + monitor := s.SetupMonitor(now, 60, 60, rc, nil) + healthUpdateCh := monitor.Subscribe() + + for i := 0; i < 5; i++ { + healthy := <-healthUpdateCh + if i < 4 { + s.Nil(healthy) + s.Equal(now, monitor.lastSeenUnsafeTime) + s.Equal(uint64(5), monitor.lastSeenUnsafeNum) + } else { + s.NotNil(healthy) + } + } + + s.NoError(monitor.Stop()) +} + +func (s *HealthMonitorTestSuite) TestUnhealthySafeHeadNotProgressing() { + s.T().Parallel() + now := uint64(time.Now().Unix()) + + rc := &testutils.MockRollupClient{} + rc.ExpectSyncStatus(mockSyncStatus(now, 1, now, 1), nil) + rc.ExpectSyncStatus(mockSyncStatus(now, 1, now, 1), nil) + rc.ExpectSyncStatus(mockSyncStatus(now+2, 2, now, 1), nil) + rc.ExpectSyncStatus(mockSyncStatus(now+2, 2, now, 1), nil) + rc.ExpectSyncStatus(mockSyncStatus(now+4, 3, now, 1), nil) + rc.ExpectSyncStatus(mockSyncStatus(now+4, 3, now, 1), nil) + + monitor := s.SetupMonitor(now, 60, 3, rc, nil) + healthUpdateCh := monitor.Subscribe() + + for i := 0; i < 5; i++ { + healthy := <-healthUpdateCh + if i < 4 { + s.Nil(healthy) + } else { + s.NotNil(healthy) + } + } + + s.NoError(monitor.Stop()) +} + +func (s *HealthMonitorTestSuite) TestHealthyWithUnsafeLag() { + s.T().Parallel() + now := uint64(time.Now().Unix()) + + rc := &testutils.MockRollupClient{} + // although unsafe has lag of 20 seconds, it's within the configured unsafe interval + // and it is advancing every block time, so it should be considered safe. + rc.ExpectSyncStatus(mockSyncStatus(now-10, 1, now, 1), nil) + rc.ExpectSyncStatus(mockSyncStatus(now-10, 1, now, 1), nil) + rc.ExpectSyncStatus(mockSyncStatus(now-8, 2, now, 1), nil) + rc.ExpectSyncStatus(mockSyncStatus(now-8, 2, now, 1), nil) + + monitor := s.SetupMonitor(now, 60, 60, rc, nil) + healthUpdateCh := monitor.Subscribe() + + // confirm initial state + s.Zero(monitor.lastSeenUnsafeNum) + s.Zero(monitor.lastSeenUnsafeTime) + + // confirm state after first check + healthy := <-healthUpdateCh + s.Nil(healthy) + lastSeenUnsafeTime := monitor.lastSeenUnsafeTime + s.NotZero(monitor.lastSeenUnsafeTime) + s.Equal(uint64(1), monitor.lastSeenUnsafeNum) + + healthy = <-healthUpdateCh + s.Nil(healthy) + s.Equal(lastSeenUnsafeTime, monitor.lastSeenUnsafeTime) + s.Equal(uint64(1), monitor.lastSeenUnsafeNum) + + healthy = <-healthUpdateCh + s.Nil(healthy) + s.Equal(lastSeenUnsafeTime+2, monitor.lastSeenUnsafeTime) + s.Equal(uint64(2), monitor.lastSeenUnsafeNum) + + s.NoError(monitor.Stop()) +} + +func mockSyncStatus(unsafeTime, unsafeNum, safeTime, safeNum uint64) *eth.SyncStatus { + return ð.SyncStatus{ + UnsafeL2: eth.L2BlockRef{ + Time: unsafeTime, + Number: unsafeNum, + }, + SafeL2: eth.L2BlockRef{ + Time: safeTime, + Number: safeNum, + }, + } +} + +func TestHealthMonitor(t *testing.T) { + suite.Run(t, new(HealthMonitorTestSuite)) +} + +type timeProvider struct { + now uint64 +} + +func (tp *timeProvider) Now() uint64 { + now := tp.now + tp.now++ + return now +} diff --git a/op-conductor/rpc/api.go b/op-conductor/rpc/api.go new file mode 100644 index 000000000000..4d85d6fe17fd --- /dev/null +++ b/op-conductor/rpc/api.go @@ -0,0 +1,68 @@ +package rpc + +import ( + "context" + "errors" + + "github.com/ethereum/go-ethereum/rpc" + + "github.com/ethereum-optimism/optimism/op-conductor/consensus" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +var ErrNotLeader = errors.New("refusing to proxy request to non-leader sequencer") + +// API defines the interface for the op-conductor API. +type API interface { + // Pause pauses op-conductor. + Pause(ctx context.Context) error + // Resume resumes op-conductor. + Resume(ctx context.Context) error + // SequencerHealthy returns true if the sequencer is healthy. + SequencerHealthy(ctx context.Context) (bool, error) + + // Consensus related APIs + // Leader returns true if the server is the leader. + Leader(ctx context.Context) (bool, error) + // LeaderWithID returns the current leader's server info. + LeaderWithID(ctx context.Context) (*consensus.ServerInfo, error) + // AddServerAsVoter adds a server as a voter to the cluster. + AddServerAsVoter(ctx context.Context, id string, addr string) error + // AddServerAsNonvoter adds a server as a non-voter to the cluster. non-voter will not participate in leader election. + AddServerAsNonvoter(ctx context.Context, id string, addr string) error + // RemoveServer removes a server from the cluster. + RemoveServer(ctx context.Context, id string) error + // TransferLeader transfers leadership to another server. + TransferLeader(ctx context.Context) error + // TransferLeaderToServer transfers leadership to a specific server. + TransferLeaderToServer(ctx context.Context, id string, addr string) error + // ClusterMembership returns the current cluster membership configuration. + ClusterMembership(ctx context.Context) ([]*consensus.ServerInfo, error) + + // APIs called by op-node + // Active returns true if op-conductor is active. + Active(ctx context.Context) (bool, error) + // CommitUnsafePayload commits a unsafe payload (latest head) to the consensus layer. + CommitUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error +} + +// ExecutionProxyAPI defines the methods proxied to the execution rpc backend +// This should include all methods that are called by op-batcher or op-proposer +type ExecutionProxyAPI interface { + GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) +} + +// NodeProxyAPI defines the methods proxied to the node rpc backend +// This should include all methods that are called by op-batcher or op-proposer +type NodeProxyAPI interface { + OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) + SyncStatus(ctx context.Context) (*eth.SyncStatus, error) + RollupConfig(ctx context.Context) (*rollup.Config, error) +} + +// NodeProxyAPI defines the methods proxied to the node rpc backend +// This should include all methods that are called by op-batcher or op-proposer +type NodeAdminProxyAPI interface { + SequencerActive(ctx context.Context) (bool, error) +} diff --git a/op-conductor/rpc/backend.go b/op-conductor/rpc/backend.go new file mode 100644 index 000000000000..64c2635da9c6 --- /dev/null +++ b/op-conductor/rpc/backend.go @@ -0,0 +1,113 @@ +package rpc + +import ( + "context" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-conductor/consensus" + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type conductor interface { + Pause(ctx context.Context) error + Resume(ctx context.Context) error + Paused() bool + Stopped() bool + SequencerHealthy(ctx context.Context) bool + + Leader(ctx context.Context) bool + LeaderWithID(ctx context.Context) *consensus.ServerInfo + AddServerAsVoter(ctx context.Context, id string, addr string) error + AddServerAsNonvoter(ctx context.Context, id string, addr string) error + RemoveServer(ctx context.Context, id string) error + TransferLeader(ctx context.Context) error + TransferLeaderToServer(ctx context.Context, id string, addr string) error + CommitUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error + ClusterMembership(ctx context.Context) ([]*consensus.ServerInfo, error) +} + +// APIBackend is the backend implementation of the API. +// TODO: (https://github.com/ethereum-optimism/protocol-quest/issues/45) Add metrics tracer here. +// TODO: (https://github.com/ethereum-optimism/protocol-quest/issues/44) add tests after e2e setup. +type APIBackend struct { + log log.Logger + con conductor +} + +// NewAPIBackend creates a new APIBackend instance. +func NewAPIBackend(log log.Logger, con conductor) *APIBackend { + return &APIBackend{ + log: log, + con: con, + } +} + +var _ API = (*APIBackend)(nil) + +// Active implements API. +func (api *APIBackend) Active(_ context.Context) (bool, error) { + return !api.con.Stopped() && !api.con.Paused(), nil +} + +// AddServerAsNonvoter implements API. +func (api *APIBackend) AddServerAsNonvoter(ctx context.Context, id string, addr string) error { + return api.con.AddServerAsNonvoter(ctx, id, addr) +} + +// AddServerAsVoter implements API. +func (api *APIBackend) AddServerAsVoter(ctx context.Context, id string, addr string) error { + return api.con.AddServerAsVoter(ctx, id, addr) +} + +// CommitUnsafePayload implements API. +func (api *APIBackend) CommitUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { + return api.con.CommitUnsafePayload(ctx, payload) +} + +// Leader implements API, returns true if current conductor is leader of the cluster. +func (api *APIBackend) Leader(ctx context.Context) (bool, error) { + return api.con.Leader(ctx), nil +} + +// LeaderWithID implements API, returns the leader's server ID and address (not necessarily the current conductor). +func (api *APIBackend) LeaderWithID(ctx context.Context) (*consensus.ServerInfo, error) { + return api.con.LeaderWithID(ctx), nil +} + +// Pause implements API. +func (api *APIBackend) Pause(ctx context.Context) error { + return api.con.Pause(ctx) +} + +// RemoveServer implements API. +func (api *APIBackend) RemoveServer(ctx context.Context, id string) error { + return api.con.RemoveServer(ctx, id) +} + +// Resume implements API. +func (api *APIBackend) Resume(ctx context.Context) error { + return api.con.Resume(ctx) +} + +// TransferLeader implements API. With Raft implementation, a successful call does not mean that leadership transfer is complete +// It just means that leadership transfer is in progress (current leader has initiated a new leader election round and stepped down as leader) +func (api *APIBackend) TransferLeader(ctx context.Context) error { + return api.con.TransferLeader(ctx) +} + +// TransferLeaderToServer implements API. With Raft implementation, a successful call does not mean that leadership transfer is complete +// It just means that leadership transfer is in progress (current leader has initiated a new leader election round and stepped down as leader) +func (api *APIBackend) TransferLeaderToServer(ctx context.Context, id string, addr string) error { + return api.con.TransferLeaderToServer(ctx, id, addr) +} + +// SequencerHealthy implements API. +func (api *APIBackend) SequencerHealthy(ctx context.Context) (bool, error) { + return api.con.SequencerHealthy(ctx), nil +} + +// ClusterMembership implements API. +func (api *APIBackend) ClusterMembership(ctx context.Context) ([]*consensus.ServerInfo, error) { + return api.con.ClusterMembership(ctx) +} diff --git a/op-conductor/rpc/client.go b/op-conductor/rpc/client.go new file mode 100644 index 000000000000..6a20b02a4215 --- /dev/null +++ b/op-conductor/rpc/client.go @@ -0,0 +1,108 @@ +package rpc + +import ( + "context" + + "github.com/ethereum/go-ethereum/rpc" + + "github.com/ethereum-optimism/optimism/op-conductor/consensus" + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +var RPCNamespace = "conductor" + +// APIClient provides a client for calling API methods. +type APIClient struct { + c *rpc.Client +} + +var _ API = (*APIClient)(nil) + +// NewAPIClient creates a new APIClient instance. +func NewAPIClient(c *rpc.Client) *APIClient { + return &APIClient{c: c} +} + +func prefixRPC(method string) string { + return RPCNamespace + "_" + method +} + +// Active implements API. +func (c *APIClient) Active(ctx context.Context) (bool, error) { + var active bool + err := c.c.CallContext(ctx, &active, prefixRPC("active")) + return active, err +} + +// AddServerAsNonvoter implements API. +func (c *APIClient) AddServerAsNonvoter(ctx context.Context, id string, addr string) error { + return c.c.CallContext(ctx, nil, prefixRPC("addServerAsNonvoter"), id, addr) +} + +// AddServerAsVoter implements API. +func (c *APIClient) AddServerAsVoter(ctx context.Context, id string, addr string) error { + return c.c.CallContext(ctx, nil, prefixRPC("addServerAsVoter"), id, addr) +} + +// Close closes the underlying RPC client. +func (c *APIClient) Close() { + c.c.Close() +} + +// CommitUnsafePayload implements API. +func (c *APIClient) CommitUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { + return c.c.CallContext(ctx, nil, prefixRPC("commitUnsafePayload"), payload) +} + +// Leader implements API. +func (c *APIClient) Leader(ctx context.Context) (bool, error) { + var leader bool + err := c.c.CallContext(ctx, &leader, prefixRPC("leader")) + return leader, err +} + +// LeaderWithID implements API. +func (c *APIClient) LeaderWithID(ctx context.Context) (*consensus.ServerInfo, error) { + var info *consensus.ServerInfo + err := c.c.CallContext(ctx, &info, prefixRPC("leaderWithID")) + return info, err +} + +// Pause implements API. +func (c *APIClient) Pause(ctx context.Context) error { + return c.c.CallContext(ctx, nil, prefixRPC("pause")) +} + +// RemoveServer implements API. +func (c *APIClient) RemoveServer(ctx context.Context, id string) error { + return c.c.CallContext(ctx, nil, prefixRPC("removeServer"), id) +} + +// Resume implements API. +func (c *APIClient) Resume(ctx context.Context) error { + return c.c.CallContext(ctx, nil, prefixRPC("resume")) +} + +// TransferLeader implements API. +func (c *APIClient) TransferLeader(ctx context.Context) error { + return c.c.CallContext(ctx, nil, prefixRPC("transferLeader")) +} + +// TransferLeaderToServer implements API. +func (c *APIClient) TransferLeaderToServer(ctx context.Context, id string, addr string) error { + return c.c.CallContext(ctx, nil, prefixRPC("transferLeaderToServer"), id, addr) +} + +// SequencerHealthy implements API. +func (c *APIClient) SequencerHealthy(ctx context.Context) (bool, error) { + var healthy bool + err := c.c.CallContext(ctx, &healthy, prefixRPC("sequencerHealthy")) + return healthy, err +} + +// ClusterMembership implements API. +func (c *APIClient) ClusterMembership(ctx context.Context) ([]*consensus.ServerInfo, error) { + var info []*consensus.ServerInfo + err := c.c.CallContext(ctx, &info, prefixRPC("clusterMembership")) + return info, err +} diff --git a/op-conductor/rpc/execution_proxy.go b/op-conductor/rpc/execution_proxy.go new file mode 100644 index 000000000000..fc3b6662a493 --- /dev/null +++ b/op-conductor/rpc/execution_proxy.go @@ -0,0 +1,40 @@ +package rpc + +import ( + "context" + + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" +) + +var ExecutionRPCNamespace = "eth" + +// ExecutionProxyBackend implements an execution rpc proxy with a leadership check before each call. +type ExecutionProxyBackend struct { + log log.Logger + con conductor + client *ethclient.Client +} + +var _ ExecutionProxyAPI = (*ExecutionProxyBackend)(nil) + +func NewExecutionProxyBackend(log log.Logger, con conductor, client *ethclient.Client) *ExecutionProxyBackend { + return &ExecutionProxyBackend{ + log: log, + con: con, + client: client, + } +} + +func (api *ExecutionProxyBackend) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { + var result map[string]interface{} + err := api.client.Client().Call(&result, "eth_getBlockByNumber", number, fullTx) + if err != nil { + return nil, err + } + if !api.con.Leader(ctx) { + return nil, ErrNotLeader + } + return result, nil +} diff --git a/op-conductor/rpc/node_admin_proxy.go b/op-conductor/rpc/node_admin_proxy.go new file mode 100644 index 000000000000..a2365d4c611a --- /dev/null +++ b/op-conductor/rpc/node_admin_proxy.go @@ -0,0 +1,40 @@ +package rpc + +import ( + "context" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-service/sources" +) + +var NodeAdminRPCNamespace = "admin" + +// NodeAdminProxyAPI implements a node admin rpc proxy with a leadership check to make sure only leader returns the result. +type NodeAdminProxyBackend struct { + log log.Logger + con conductor + client *sources.RollupClient +} + +var _ NodeAdminProxyAPI = (*NodeAdminProxyBackend)(nil) + +// NewNodeAdminProxyBackend creates a new NodeAdminProxyBackend instance. +func NewNodeAdminProxyBackend(log log.Logger, con conductor, client *sources.RollupClient) NodeAdminProxyAPI { + return &NodeAdminProxyBackend{ + log: log, + con: con, + client: client, + } +} + +func (api *NodeAdminProxyBackend) SequencerActive(ctx context.Context) (bool, error) { + active, err := api.client.SequencerActive(ctx) + if err != nil { + return false, err + } + if !api.con.Leader(ctx) { + return false, ErrNotLeader + } + return active, err +} diff --git a/op-conductor/rpc/node_proxy.go b/op-conductor/rpc/node_proxy.go new file mode 100644 index 000000000000..786167812b11 --- /dev/null +++ b/op-conductor/rpc/node_proxy.go @@ -0,0 +1,63 @@ +package rpc + +import ( + "context" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources" +) + +var NodeRPCNamespace = "optimism" + +// NodeProxyBackend implements a node rpc proxy with a leadership check before each call. +type NodeProxyBackend struct { + log log.Logger + con conductor + client *sources.RollupClient +} + +var _ NodeProxyAPI = (*NodeProxyBackend)(nil) + +func NewNodeProxyBackend(log log.Logger, con conductor, client *sources.RollupClient) *NodeProxyBackend { + return &NodeProxyBackend{ + log: log, + con: con, + client: client, + } +} + +func (api *NodeProxyBackend) SyncStatus(ctx context.Context) (*eth.SyncStatus, error) { + status, err := api.client.SyncStatus(ctx) + if err != nil { + return nil, err + } + if !api.con.Leader(ctx) { + return nil, ErrNotLeader + } + return status, err +} + +func (api *NodeProxyBackend) OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) { + output, err := api.client.OutputAtBlock(ctx, blockNum) + if err != nil { + return nil, err + } + if !api.con.Leader(ctx) { + return nil, ErrNotLeader + } + return output, nil +} + +func (api *NodeProxyBackend) RollupConfig(ctx context.Context) (*rollup.Config, error) { + config, err := api.client.RollupConfig(ctx) + if err != nil { + return nil, err + } + if !api.con.Leader(ctx) { + return nil, ErrNotLeader + } + return config, nil +} diff --git a/op-conductor/run_test_100times.sh b/op-conductor/run_test_100times.sh new file mode 100755 index 000000000000..5d7500c44e20 --- /dev/null +++ b/op-conductor/run_test_100times.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +for i in {1..100}; do + echo "=======================" + echo "Running iteration $i" + if ! gotestsum -- -run 'TestControlLoop' ./... --count=1 --timeout=5s -race; then + echo "Test failed" + exit 1 + fi +done diff --git a/op-dispute-mon/.gitignore b/op-dispute-mon/.gitignore new file mode 100644 index 000000000000..ba077a4031ad --- /dev/null +++ b/op-dispute-mon/.gitignore @@ -0,0 +1 @@ +bin diff --git a/op-dispute-mon/Dockerfile b/op-dispute-mon/Dockerfile new file mode 100644 index 000000000000..a2b8fe627b27 --- /dev/null +++ b/op-dispute-mon/Dockerfile @@ -0,0 +1,9 @@ +ARG OP_STACK_GO_BUILDER=us-docker.pkg.dev/oplabs-tools-artifacts/images/op-stack-go:latest +FROM $OP_STACK_GO_BUILDER as builder +# See "make golang-docker" and /ops/docker/op-stack-go + +FROM alpine:3.18 + +COPY --from=builder /usr/local/bin/op-dispute-mon /usr/local/bin/op-dispute-mon + +CMD ["op-dispute-mon"] diff --git a/op-dispute-mon/Dockerfile.dockerignore b/op-dispute-mon/Dockerfile.dockerignore new file mode 100644 index 000000000000..4f26140750a0 --- /dev/null +++ b/op-dispute-mon/Dockerfile.dockerignore @@ -0,0 +1,2 @@ +# ignore everything but the dockerfile, the op-stack-go base image performs the build +* diff --git a/op-dispute-mon/Makefile b/op-dispute-mon/Makefile new file mode 100644 index 000000000000..e7b8edfa0d41 --- /dev/null +++ b/op-dispute-mon/Makefile @@ -0,0 +1,20 @@ +GITCOMMIT ?= $(shell git rev-parse HEAD) +GITDATE ?= $(shell git show -s --format='%ct') +VERSION := v0.0.0 + +LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT) +LDFLAGSSTRING +=-X main.GitDate=$(GITDATE) +LDFLAGSSTRING +=-X main.Version=$(VERSION) +LDFLAGS := -ldflags "$(LDFLAGSSTRING)" + +op-dispute-mon: + env GO111MODULE=on GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) go build -v $(LDFLAGS) -o ./bin/op-dispute-mon ./cmd +.PHONY: op-dispute-mon + +clean: + rm bin/op-dispute-mon +.PHONY: clean + +test: + go test -v ./... +.PHONY: test diff --git a/op-dispute-mon/README.md b/op-dispute-mon/README.md new file mode 100644 index 000000000000..0a2a847a29e0 --- /dev/null +++ b/op-dispute-mon/README.md @@ -0,0 +1,20 @@ +# op-dispute-mon + +The `op-dispute-mon` is an off-chain service to monitor dispute games. + +## Quickstart + +Clone this repo. Then run: + +```shell +make op-dispute-mon +``` + +This will build the `op-dispute-mon` binary which can be run with +`./op-dispute-mon/bin/op-dispute-mon`. + +## Usage + +`op-dispute-mon` is configurable via command line flags and environment variables. The help menu +shows the available config options and can be accessed by running `./op-dispute-mon --help`. + diff --git a/op-dispute-mon/cmd/main.go b/op-dispute-mon/cmd/main.go new file mode 100644 index 000000000000..4b2c1f46bd17 --- /dev/null +++ b/op-dispute-mon/cmd/main.go @@ -0,0 +1,69 @@ +package main + +import ( + "context" + "os" + + "github.com/urfave/cli/v2" + + "github.com/ethereum/go-ethereum/log" + + monitor "github.com/ethereum-optimism/optimism/op-dispute-mon" + "github.com/ethereum-optimism/optimism/op-dispute-mon/config" + "github.com/ethereum-optimism/optimism/op-dispute-mon/flags" + "github.com/ethereum-optimism/optimism/op-dispute-mon/version" + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/cliapp" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/opio" +) + +var ( + GitCommit = "" + GitDate = "" +) + +// VersionWithMeta holds the textual version string including the metadata. +var VersionWithMeta = opservice.FormatVersion(version.Version, GitCommit, GitDate, version.Meta) + +func main() { + args := os.Args + ctx := opio.WithInterruptBlocker(context.Background()) + if err := run(ctx, args, monitor.Main); err != nil { + log.Crit("Application failed", "err", err) + } +} + +type ConfiguredLifecycle func(ctx context.Context, log log.Logger, config *config.Config) (cliapp.Lifecycle, error) + +func run(ctx context.Context, args []string, action ConfiguredLifecycle) error { + oplog.SetupDefaults() + + app := cli.NewApp() + app.Version = VersionWithMeta + app.Flags = cliapp.ProtectFlags(flags.Flags) + app.Name = "op-dispute-mon" + app.Usage = "Monitor dispute games" + app.Description = "Monitors output proposals and dispute games." + app.Action = cliapp.LifecycleCmd(func(ctx *cli.Context, close context.CancelCauseFunc) (cliapp.Lifecycle, error) { + logger, err := setupLogging(ctx) + if err != nil { + return nil, err + } + logger.Info("Starting op-dispute-mon", "version", VersionWithMeta) + + cfg, err := flags.NewConfigFromCLI(ctx) + if err != nil { + return nil, err + } + return action(ctx.Context, logger, cfg) + }) + return app.RunContext(ctx, args) +} + +func setupLogging(ctx *cli.Context) (log.Logger, error) { + logCfg := oplog.ReadCLIConfig(ctx) + logger := oplog.NewLogger(oplog.AppOut(ctx), logCfg) + oplog.SetGlobalLogHandler(logger.Handler()) + return logger, nil +} diff --git a/op-dispute-mon/config/config.go b/op-dispute-mon/config/config.go new file mode 100644 index 000000000000..5dc0f62408af --- /dev/null +++ b/op-dispute-mon/config/config.go @@ -0,0 +1,74 @@ +package config + +import ( + "errors" + "fmt" + "time" + + opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/oppprof" + + "github.com/ethereum/go-ethereum/common" +) + +var ( + ErrMissingL1EthRPC = errors.New("missing l1 eth rpc url") + ErrMissingGameFactoryAddress = errors.New("missing game factory address") + ErrMissingRollupRpc = errors.New("missing rollup rpc url") +) + +const ( + // DefaultGameWindow is the default maximum time duration in the past + // to look for games to monitor. The default value is 11 days, which + // is a 4 day resolution buffer plus the 7 day game finalization window. + DefaultGameWindow = time.Duration(11 * 24 * time.Hour) + // DefaultMonitorInterval is the default interval at which the dispute + // monitor will check for new games to monitor. + DefaultMonitorInterval = time.Second * 30 +) + +// Config is a well typed config that is parsed from the CLI params. +// It also contains config options for auxiliary services. +type Config struct { + L1EthRpc string // L1 RPC Url + GameFactoryAddress common.Address // Address of the dispute game factory + RollupRpc string // The rollup node RPC URL. + + MonitorInterval time.Duration // Frequency to check for new games to monitor. + GameWindow time.Duration // Maximum window to look for games to monitor. + + MetricsConfig opmetrics.CLIConfig + PprofConfig oppprof.CLIConfig +} + +func NewConfig(gameFactoryAddress common.Address, l1EthRpc string) Config { + return Config{ + L1EthRpc: l1EthRpc, + GameFactoryAddress: gameFactoryAddress, + + MonitorInterval: DefaultMonitorInterval, + GameWindow: DefaultGameWindow, + + MetricsConfig: opmetrics.DefaultCLIConfig(), + PprofConfig: oppprof.DefaultCLIConfig(), + } +} + +func (c Config) Check() error { + if c.L1EthRpc == "" { + return ErrMissingL1EthRPC + } + if c.RollupRpc == "" { + return ErrMissingRollupRpc + } + if c.GameFactoryAddress == (common.Address{}) { + return ErrMissingGameFactoryAddress + } + if err := c.MetricsConfig.Check(); err != nil { + return fmt.Errorf("metrics config: %w", err) + } + if err := c.PprofConfig.Check(); err != nil { + return fmt.Errorf("pprof config: %w", err) + } + return nil +} diff --git a/op-dispute-mon/config/config_test.go b/op-dispute-mon/config/config_test.go new file mode 100644 index 000000000000..d2d2ffbbdc6b --- /dev/null +++ b/op-dispute-mon/config/config_test.go @@ -0,0 +1,43 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" +) + +var ( + validL1EthRpc = "http://localhost:8545" + validGameFactoryAddress = common.Address{0x23} + validRollupRpc = "http://localhost:8555" +) + +func validConfig() Config { + cfg := NewConfig(validGameFactoryAddress, validL1EthRpc) + cfg.RollupRpc = validRollupRpc + return cfg +} + +func TestValidConfigIsValid(t *testing.T) { + require.NoError(t, validConfig().Check()) +} + +func TestL1EthRpcRequired(t *testing.T) { + config := validConfig() + config.L1EthRpc = "" + require.ErrorIs(t, config.Check(), ErrMissingL1EthRPC) +} + +func TestGameFactoryAddressRequired(t *testing.T) { + config := validConfig() + config.GameFactoryAddress = common.Address{} + require.ErrorIs(t, config.Check(), ErrMissingGameFactoryAddress) +} + +func TestRollupRpcRequired(t *testing.T) { + config := validConfig() + config.RollupRpc = "" + require.ErrorIs(t, config.Check(), ErrMissingRollupRpc) +} diff --git a/op-dispute-mon/flags/flags.go b/op-dispute-mon/flags/flags.go new file mode 100644 index 000000000000..e314c7acd1f4 --- /dev/null +++ b/op-dispute-mon/flags/flags.go @@ -0,0 +1,113 @@ +package flags + +import ( + "fmt" + + "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/op-dispute-mon/config" + opservice "github.com/ethereum-optimism/optimism/op-service" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/oppprof" +) + +const ( + envVarPrefix = "OP_DISPUTE_MON" +) + +func prefixEnvVars(name string) []string { + return opservice.PrefixEnvVar(envVarPrefix, name) +} + +var ( + // Required Flags + L1EthRpcFlag = &cli.StringFlag{ + Name: "l1-eth-rpc", + Usage: "HTTP provider URL for L1.", + EnvVars: prefixEnvVars("L1_ETH_RPC"), + } + FactoryAddressFlag = &cli.StringFlag{ + Name: "game-factory-address", + Usage: "Address of the fault game factory contract.", + EnvVars: prefixEnvVars("GAME_FACTORY_ADDRESS"), + } + // Optional Flags + RollupRpcFlag = &cli.StringFlag{ + Name: "rollup-rpc", + Usage: "HTTP provider URL for the rollup node", + EnvVars: prefixEnvVars("ROLLUP_RPC"), + } + MonitorIntervalFlag = &cli.DurationFlag{ + Name: "monitor-interval", + Usage: "The interval at which the dispute monitor will check for new games to monitor.", + EnvVars: prefixEnvVars("MONITOR_INTERVAL"), + Value: config.DefaultMonitorInterval, + } + GameWindowFlag = &cli.DurationFlag{ + Name: "game-window", + Usage: "The time window which the monitor will consider games to report on. " + + "This should include a bond claim buffer for games outside the maximum game duration.", + EnvVars: prefixEnvVars("GAME_WINDOW"), + Value: config.DefaultGameWindow, + } +) + +// requiredFlags are checked by [CheckRequired] +var requiredFlags = []cli.Flag{ + L1EthRpcFlag, + FactoryAddressFlag, +} + +// optionalFlags is a list of unchecked cli flags +var optionalFlags = []cli.Flag{ + RollupRpcFlag, + MonitorIntervalFlag, + GameWindowFlag, +} + +func init() { + optionalFlags = append(optionalFlags, oplog.CLIFlags(envVarPrefix)...) + optionalFlags = append(optionalFlags, opmetrics.CLIFlags(envVarPrefix)...) + optionalFlags = append(optionalFlags, oppprof.CLIFlags(envVarPrefix)...) + + Flags = append(requiredFlags, optionalFlags...) +} + +// Flags contains the list of configuration options available to the binary. +var Flags []cli.Flag + +func CheckRequired(ctx *cli.Context) error { + for _, f := range requiredFlags { + if !ctx.IsSet(f.Names()[0]) { + return fmt.Errorf("flag %s is required", f.Names()[0]) + } + } + return nil +} + +// NewConfigFromCLI parses the Config from the provided flags or environment variables. +func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) { + if err := CheckRequired(ctx); err != nil { + return nil, err + } + gameFactoryAddress, err := opservice.ParseAddress(ctx.String(FactoryAddressFlag.Name)) + if err != nil { + return nil, err + } + + metricsConfig := opmetrics.ReadCLIConfig(ctx) + pprofConfig := oppprof.ReadCLIConfig(ctx) + + return &config.Config{ + L1EthRpc: ctx.String(L1EthRpcFlag.Name), + GameFactoryAddress: gameFactoryAddress, + + RollupRpc: ctx.String(RollupRpcFlag.Name), + MonitorInterval: ctx.Duration(MonitorIntervalFlag.Name), + GameWindow: ctx.Duration(GameWindowFlag.Name), + + MetricsConfig: metricsConfig, + PprofConfig: pprofConfig, + }, nil +} diff --git a/op-dispute-mon/flags/flags_test.go b/op-dispute-mon/flags/flags_test.go new file mode 100644 index 000000000000..31881e0eab86 --- /dev/null +++ b/op-dispute-mon/flags/flags_test.go @@ -0,0 +1,82 @@ +package flags + +import ( + "fmt" + "reflect" + "strings" + "testing" + + opservice "github.com/ethereum-optimism/optimism/op-service" + + "github.com/stretchr/testify/require" + "github.com/urfave/cli/v2" +) + +// TestUniqueFlags asserts that all flag names are unique, to avoid accidental conflicts between the many flags. +func TestUniqueFlags(t *testing.T) { + seenCLI := make(map[string]struct{}) + for _, flag := range Flags { + for _, name := range flag.Names() { + if _, ok := seenCLI[name]; ok { + t.Errorf("duplicate flag %s", name) + continue + } + seenCLI[name] = struct{}{} + } + } +} + +// TestUniqueEnvVars asserts that all flag env vars are unique, to avoid accidental conflicts between the many flags. +func TestUniqueEnvVars(t *testing.T) { + seenCLI := make(map[string]struct{}) + for _, flag := range Flags { + envVar := envVarForFlag(flag) + if _, ok := seenCLI[envVar]; envVar != "" && ok { + t.Errorf("duplicate flag env var %s", envVar) + continue + } + seenCLI[envVar] = struct{}{} + } +} + +func TestCorrectEnvVarPrefix(t *testing.T) { + for _, flag := range Flags { + envVar := envVarForFlag(flag) + if envVar == "" { + t.Errorf("Failed to find EnvVar for flag %v", flag.Names()[0]) + } + if !strings.HasPrefix(envVar, fmt.Sprintf("%s_", envVarPrefix)) { + t.Errorf("Flag %v env var (%v) does not start with %s_", flag.Names()[0], envVar, envVarPrefix) + } + if strings.Contains(envVar, "__") { + t.Errorf("Flag %v env var (%v) has duplicate underscores", flag.Names()[0], envVar) + } + } +} + +func envVarForFlag(flag cli.Flag) string { + values := reflect.ValueOf(flag) + envVarValue := values.Elem().FieldByName("EnvVars") + if envVarValue == (reflect.Value{}) || envVarValue.Len() == 0 { + return "" + } + return envVarValue.Index(0).String() +} + +func TestEnvVarFormat(t *testing.T) { + for _, flag := range Flags { + flag := flag + flagName := flag.Names()[0] + + t.Run(flagName, func(t *testing.T) { + envFlagGetter, ok := flag.(interface { + GetEnvVars() []string + }) + envFlags := envFlagGetter.GetEnvVars() + require.True(t, ok, "must be able to cast the flag to an EnvVar interface") + require.Equal(t, 1, len(envFlags), "flags should have exactly one env var") + expectedEnvVar := opservice.FlagNameToEnvVarName(flagName, envVarPrefix) + require.Equal(t, expectedEnvVar, envFlags[0]) + }) + } +} diff --git a/op-dispute-mon/metrics/metrics.go b/op-dispute-mon/metrics/metrics.go new file mode 100644 index 000000000000..0491df5933bb --- /dev/null +++ b/op-dispute-mon/metrics/metrics.go @@ -0,0 +1,249 @@ +package metrics + +import ( + "fmt" + "io" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/sources/caching" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/prometheus/client_golang/prometheus" + + "github.com/ethereum-optimism/optimism/op-service/httputil" + opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" +) + +const Namespace = "op_dispute_mon" + +type GameAgreementStatus uint8 + +const ( + // In progress + AgreeChallengerAhead GameAgreementStatus = iota + DisagreeChallengerAhead + AgreeDefenderAhead + DisagreeDefenderAhead + + // Completed + AgreeDefenderWins + DisagreeDefenderWins + AgreeChallengerWins + DisagreeChallengerWins +) + +type Metricer interface { + RecordInfo(version string) + RecordUp() + + RecordClaimResolutionDelayMax(delay float64) + + RecordOutputFetchTime(timestamp float64) + + RecordGameAgreement(status GameAgreementStatus, count int) + + RecordBondCollateral(addr common.Address, required *big.Int, available *big.Int) + + caching.Metrics +} + +// Metrics implementation must implement RegistryMetricer to allow the metrics server to work. +var _ opmetrics.RegistryMetricer = (*Metrics)(nil) + +type Metrics struct { + ns string + registry *prometheus.Registry + factory opmetrics.Factory + + *opmetrics.CacheMetrics + + info prometheus.GaugeVec + up prometheus.Gauge + + lastOutputFetch prometheus.Gauge + + claimResolutionDelayMax prometheus.Gauge + + gamesAgreement prometheus.GaugeVec + + requiredCollateral prometheus.GaugeVec + availableCollateral prometheus.GaugeVec +} + +func (m *Metrics) Registry() *prometheus.Registry { + return m.registry +} + +var _ Metricer = (*Metrics)(nil) + +func NewMetrics() *Metrics { + registry := opmetrics.NewRegistry() + factory := opmetrics.With(registry) + + return &Metrics{ + ns: Namespace, + registry: registry, + factory: factory, + + CacheMetrics: opmetrics.NewCacheMetrics(factory, Namespace, "provider_cache", "Provider cache"), + + info: *factory.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: Namespace, + Name: "info", + Help: "Pseudo-metric tracking version and config info", + }, []string{ + "version", + }), + up: factory.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, + Name: "up", + Help: "1 if the op-challenger has finished starting up", + }), + lastOutputFetch: factory.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, + Name: "last_output_fetch", + Help: "Timestamp of the last output fetch", + }), + claimResolutionDelayMax: factory.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, + Name: "claim_resolution_delay_max", + Help: "Maximum claim resolution delay in seconds", + }), + gamesAgreement: *factory.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: Namespace, + Name: "games_agreement", + Help: "Number of games broken down by whether the result agrees with the reference node", + }, []string{ + "status", + "completion", + "result_correctness", + "root_agreement", + }), + requiredCollateral: *factory.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: Namespace, + Name: "bond_collateral_required", + Help: "Required collateral (ETH) to cover outstanding bonds and credits", + }, []string{ + // Address of the DelayedWETH contract in use. This is a limited set as only permissioned actors can deploy + // additional DelayedWETH contracts to be used by dispute games + "delayedWETH", + "balance", + }), + availableCollateral: *factory.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: Namespace, + Name: "bond_collateral_available", + Help: "Available collateral (ETH) to cover outstanding bonds and credits", + }, []string{ + // Address of the DelayedWETH contract in use. This is a limited set as only permissioned actors can deploy + // additional DelayedWETH contracts to be used by dispute games + "delayedWETH", + "balance", + }), + } +} + +func (m *Metrics) Start(host string, port int) (*httputil.HTTPServer, error) { + return opmetrics.StartServer(m.registry, host, port) +} + +func (m *Metrics) StartBalanceMetrics( + l log.Logger, + client *ethclient.Client, + account common.Address, +) io.Closer { + return opmetrics.LaunchBalanceMetrics(l, m.registry, m.ns, client, account) +} + +// RecordInfo sets a pseudo-metric that contains versioning and +// config info for the op-proposer. +func (m *Metrics) RecordInfo(version string) { + m.info.WithLabelValues(version).Set(1) +} + +// RecordUp sets the up metric to 1. +func (m *Metrics) RecordUp() { + prometheus.MustRegister() + m.up.Set(1) +} + +func (m *Metrics) RecordClaimResolutionDelayMax(delay float64) { + m.claimResolutionDelayMax.Set(delay) +} + +func (m *Metrics) Document() []opmetrics.DocumentedMetric { + return m.factory.Document() +} + +func (m *Metrics) RecordOutputFetchTime(timestamp float64) { + m.lastOutputFetch.Set(timestamp) +} + +func (m *Metrics) RecordGameAgreement(status GameAgreementStatus, count int) { + m.gamesAgreement.WithLabelValues(labelValuesFor(status)...).Set(float64(count)) +} + +func (m *Metrics) RecordBondCollateral(addr common.Address, required *big.Int, available *big.Int) { + balance := "sufficient" + if required.Cmp(available) > 0 { + balance = "insufficient" + } + m.requiredCollateral.WithLabelValues(addr.Hex(), balance).Set(weiToEther(required)) + m.availableCollateral.WithLabelValues(addr.Hex(), balance).Set(weiToEther(available)) +} + +const ( + inProgress = true + correct = true + agree = true +) + +func labelValuesFor(status GameAgreementStatus) []string { + asStrings := func(status string, inProgress bool, correct bool, agree bool) []string { + inProgressStr := "in_progress" + if !inProgress { + inProgressStr = "complete" + } + correctStr := "correct" + if !correct { + correctStr = "incorrect" + } + agreeStr := "agree" + if !agree { + agreeStr = "disagree" + } + return []string{status, inProgressStr, correctStr, agreeStr} + } + switch status { + case AgreeChallengerAhead: + return asStrings("agree_challenger_ahead", inProgress, !correct, agree) + case DisagreeChallengerAhead: + return asStrings("disagree_challenger_ahead", inProgress, correct, !agree) + case AgreeDefenderAhead: + return asStrings("agree_defender_ahead", inProgress, correct, agree) + case DisagreeDefenderAhead: + return asStrings("disagree_defender_ahead", inProgress, !correct, !agree) + + // Completed + case AgreeDefenderWins: + return asStrings("agree_defender_wins", !inProgress, correct, agree) + case DisagreeDefenderWins: + return asStrings("disagree_defender_wins", !inProgress, !correct, !agree) + case AgreeChallengerWins: + return asStrings("agree_challenger_wins", !inProgress, !correct, agree) + case DisagreeChallengerWins: + return asStrings("disagree_challenger_wins", !inProgress, correct, !agree) + default: + panic(fmt.Errorf("unknown game agreement status: %v", status)) + } +} + +// weiToEther divides the wei value by 10^18 to get a number in ether as a float64 +func weiToEther(wei *big.Int) float64 { + num := new(big.Rat).SetInt(wei) + denom := big.NewRat(params.Ether, 1) + num = num.Quo(num, denom) + f, _ := num.Float64() + return f +} diff --git a/op-dispute-mon/metrics/noop.go b/op-dispute-mon/metrics/noop.go new file mode 100644 index 000000000000..9a3625610140 --- /dev/null +++ b/op-dispute-mon/metrics/noop.go @@ -0,0 +1,25 @@ +package metrics + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" +) + +type NoopMetricsImpl struct{} + +var NoopMetrics Metricer = new(NoopMetricsImpl) + +func (*NoopMetricsImpl) RecordInfo(version string) {} +func (*NoopMetricsImpl) RecordUp() {} + +func (*NoopMetricsImpl) CacheAdd(_ string, _ int, _ bool) {} +func (*NoopMetricsImpl) CacheGet(_ string, _ bool) {} + +func (*NoopMetricsImpl) RecordClaimResolutionDelayMax(delay float64) {} + +func (*NoopMetricsImpl) RecordOutputFetchTime(timestamp float64) {} + +func (*NoopMetricsImpl) RecordGameAgreement(status GameAgreementStatus, count int) {} + +func (i *NoopMetricsImpl) RecordBondCollateral(_ common.Address, _ *big.Int, _ *big.Int) {} diff --git a/op-dispute-mon/mon/bonds/collateral.go b/op-dispute-mon/mon/bonds/collateral.go new file mode 100644 index 000000000000..67d15cbe1f10 --- /dev/null +++ b/op-dispute-mon/mon/bonds/collateral.go @@ -0,0 +1,43 @@ +package bonds + +import ( + "context" + "fmt" + "math/big" + + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "golang.org/x/exp/maps" +) + +type BondContract interface { + GetCredits(ctx context.Context, block rpcblock.Block, recipients ...common.Address) ([]*big.Int, error) +} + +// CalculateRequiredCollateral determines the minimum balance required for a fault dispute game contract in order +// to pay the outstanding bonds and credits. +// It returns the sum of unpaid bonds from claims, plus the sum of allocated but unclaimed credits. +func CalculateRequiredCollateral(ctx context.Context, contract BondContract, blockHash common.Hash, claims []faultTypes.Claim) (*big.Int, error) { + unpaidBonds := big.NewInt(0) + recipients := make(map[common.Address]bool) + for _, claim := range claims { + if monTypes.ResolvedBondAmount.Cmp(claim.Bond) != 0 { + unpaidBonds = new(big.Int).Add(unpaidBonds, claim.Bond) + } + recipients[claim.Claimant] = true + if claim.CounteredBy != (common.Address{}) { + recipients[claim.CounteredBy] = true + } + } + + credits, err := contract.GetCredits(ctx, rpcblock.ByHash(blockHash), maps.Keys(recipients)...) + if err != nil { + return nil, fmt.Errorf("failed to load credits: %w", err) + } + for _, credit := range credits { + unpaidBonds = new(big.Int).Add(unpaidBonds, credit) + } + return unpaidBonds, nil +} diff --git a/op-dispute-mon/mon/bonds/collateral_test.go b/op-dispute-mon/mon/bonds/collateral_test.go new file mode 100644 index 000000000000..7445a6076315 --- /dev/null +++ b/op-dispute-mon/mon/bonds/collateral_test.go @@ -0,0 +1,64 @@ +package bonds + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestCalculateRequiredCollateral(t *testing.T) { + claims := []types.Claim{ + { + ClaimData: types.ClaimData{ + Bond: monTypes.ResolvedBondAmount, + }, + Claimant: common.Address{0x01}, + CounteredBy: common.Address{0x02}, + }, + { + ClaimData: types.ClaimData{ + Bond: big.NewInt(5), + }, + Claimant: common.Address{0x03}, + CounteredBy: common.Address{}, + }, + { + ClaimData: types.ClaimData{ + Bond: big.NewInt(7), + }, + Claimant: common.Address{0x03}, + CounteredBy: common.Address{}, + }, + } + contract := &stubBondContract{ + credits: map[common.Address]*big.Int{ + {0x01}: big.NewInt(3), + {0x03}: big.NewInt(8), + }, + } + collateral, err := CalculateRequiredCollateral(context.Background(), contract, common.Hash{0xab}, claims) + require.NoError(t, err) + require.Equal(t, collateral.Int64(), int64(5+7+3+8)) +} + +type stubBondContract struct { + credits map[common.Address]*big.Int +} + +func (s *stubBondContract) GetCredits(_ context.Context, _ rpcblock.Block, recipients ...common.Address) ([]*big.Int, error) { + results := make([]*big.Int, len(recipients)) + for i, recipient := range recipients { + credit, ok := s.credits[recipient] + if !ok { + credit = big.NewInt(0) + } + results[i] = credit + } + return results, nil +} diff --git a/op-dispute-mon/mon/bonds/monitor.go b/op-dispute-mon/mon/bonds/monitor.go new file mode 100644 index 000000000000..a84d8a4f62ee --- /dev/null +++ b/op-dispute-mon/mon/bonds/monitor.go @@ -0,0 +1,33 @@ +package bonds + +import ( + "math/big" + + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/transform" + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +type BondMetrics interface { + RecordBondCollateral(addr common.Address, required *big.Int, available *big.Int) +} + +type Bonds struct { + logger log.Logger + metrics BondMetrics +} + +func NewBonds(logger log.Logger, metrics BondMetrics) *Bonds { + return &Bonds{ + logger: logger, + metrics: metrics, + } +} + +func (b *Bonds) CheckBonds(games []*types.EnrichedGameData) { + data := transform.CalculateRequiredCollateral(games) + for addr, collateral := range data { + b.metrics.RecordBondCollateral(addr, collateral.Required, collateral.Actual) + } +} diff --git a/op-dispute-mon/mon/bonds/monitor_test.go b/op-dispute-mon/mon/bonds/monitor_test.go new file mode 100644 index 000000000000..1cf5f65a7cff --- /dev/null +++ b/op-dispute-mon/mon/bonds/monitor_test.go @@ -0,0 +1,59 @@ +package bonds + +import ( + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/transform" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestCheckBonds(t *testing.T) { + weth1 := common.Address{0x1a} + weth1Balance := big.NewInt(4200) + weth2 := common.Address{0x2b} + weth2Balance := big.NewInt(6000) + game1 := &monTypes.EnrichedGameData{ + Credits: map[common.Address]*big.Int{ + common.Address{0x01}: big.NewInt(2), + }, + WETHContract: weth1, + ETHCollateral: weth1Balance, + } + game2 := &monTypes.EnrichedGameData{ + Credits: map[common.Address]*big.Int{ + common.Address{0x01}: big.NewInt(46), + }, + WETHContract: weth2, + ETHCollateral: weth2Balance, + } + + logger := testlog.Logger(t, log.LvlInfo) + metrics := &stubBondMetrics{recorded: make(map[common.Address]transform.Collateral)} + bonds := NewBonds(logger, metrics) + + bonds.CheckBonds([]*monTypes.EnrichedGameData{game1, game2}) + + require.Len(t, metrics.recorded, 2) + require.Contains(t, metrics.recorded, weth1) + require.Contains(t, metrics.recorded, weth2) + require.Equal(t, metrics.recorded[weth1].Required.Uint64(), uint64(2)) + require.Equal(t, metrics.recorded[weth1].Actual.Uint64(), weth1Balance.Uint64()) + require.Equal(t, metrics.recorded[weth2].Required.Uint64(), uint64(46)) + require.Equal(t, metrics.recorded[weth2].Actual.Uint64(), weth2Balance.Uint64()) +} + +type stubBondMetrics struct { + recorded map[common.Address]transform.Collateral +} + +func (s *stubBondMetrics) RecordBondCollateral(addr common.Address, required *big.Int, available *big.Int) { + s.recorded[addr] = transform.Collateral{ + Required: required, + Actual: available, + } +} diff --git a/op-dispute-mon/mon/extract/balance_enricher.go b/op-dispute-mon/mon/extract/balance_enricher.go new file mode 100644 index 000000000000..42cc5b8ccafe --- /dev/null +++ b/op-dispute-mon/mon/extract/balance_enricher.go @@ -0,0 +1,33 @@ +package extract + +import ( + "context" + "fmt" + "math/big" + + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" +) + +var _ Enricher = (*BalanceEnricher)(nil) + +type BalanceCaller interface { + GetBalance(context.Context, rpcblock.Block) (*big.Int, common.Address, error) +} + +type BalanceEnricher struct{} + +func NewBalanceEnricher() *BalanceEnricher { + return &BalanceEnricher{} +} + +func (b *BalanceEnricher) Enrich(ctx context.Context, block rpcblock.Block, caller GameCaller, game *monTypes.EnrichedGameData) error { + balance, holdingAddr, err := caller.GetBalance(ctx, block) + if err != nil { + return fmt.Errorf("failed to fetch balance: %w", err) + } + game.ETHCollateral = balance + game.WETHContract = holdingAddr + return nil +} diff --git a/op-dispute-mon/mon/extract/balance_enricher_test.go b/op-dispute-mon/mon/extract/balance_enricher_test.go new file mode 100644 index 000000000000..28ce644d5f2f --- /dev/null +++ b/op-dispute-mon/mon/extract/balance_enricher_test.go @@ -0,0 +1,33 @@ +package extract + +import ( + "context" + "errors" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestBalanceEnricher(t *testing.T) { + t.Run("GetBalanceError", func(t *testing.T) { + enricher := NewBalanceEnricher() + caller := &mockGameCaller{balanceErr: errors.New("nope")} + game := &types.EnrichedGameData{} + err := enricher.Enrich(context.Background(), rpcblock.Latest, caller, game) + require.ErrorIs(t, err, caller.balanceErr) + }) + + t.Run("GetBalanceSuccess", func(t *testing.T) { + enricher := NewBalanceEnricher() + caller := &mockGameCaller{balance: big.NewInt(84242), balanceAddr: common.Address{0xdd}} + game := &types.EnrichedGameData{} + err := enricher.Enrich(context.Background(), rpcblock.Latest, caller, game) + require.NoError(t, err) + require.Equal(t, game.WETHContract, caller.balanceAddr) + require.Equal(t, game.ETHCollateral, caller.balance) + }) +} diff --git a/op-dispute-mon/mon/extract/bond_enricher.go b/op-dispute-mon/mon/extract/bond_enricher.go new file mode 100644 index 000000000000..ec3659f92859 --- /dev/null +++ b/op-dispute-mon/mon/extract/bond_enricher.go @@ -0,0 +1,51 @@ +package extract + +import ( + "context" + "errors" + "fmt" + "math/big" + + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "golang.org/x/exp/maps" +) + +var _ Enricher = (*BondEnricher)(nil) + +var ErrIncorrectCreditCount = errors.New("incorrect credit count") + +type BondCaller interface { + GetCredits(context.Context, rpcblock.Block, ...common.Address) ([]*big.Int, error) +} + +type BondEnricher struct{} + +func NewBondEnricher() *BondEnricher { + return &BondEnricher{} +} + +func (b *BondEnricher) Enrich(ctx context.Context, block rpcblock.Block, caller GameCaller, game *monTypes.EnrichedGameData) error { + recipients := make(map[common.Address]bool) + for _, claim := range game.Claims { + recipients[claim.Claimant] = true + if claim.CounteredBy != (common.Address{}) { + recipients[claim.CounteredBy] = true + } + } + + recipientAddrs := maps.Keys(recipients) + credits, err := caller.GetCredits(ctx, block, recipientAddrs...) + if err != nil { + return err + } + if len(credits) != len(recipientAddrs) { + return fmt.Errorf("%w, requested %v values but got %v", ErrIncorrectCreditCount, len(recipientAddrs), len(credits)) + } + game.Credits = make(map[common.Address]*big.Int) + for i, credit := range credits { + game.Credits[recipientAddrs[i]] = credit + } + return nil +} diff --git a/op-dispute-mon/mon/extract/bond_enricher_test.go b/op-dispute-mon/mon/extract/bond_enricher_test.go new file mode 100644 index 000000000000..29daecb8bade --- /dev/null +++ b/op-dispute-mon/mon/extract/bond_enricher_test.go @@ -0,0 +1,87 @@ +package extract + +import ( + "context" + "errors" + "math/big" + "testing" + + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestBondEnricher(t *testing.T) { + makeGame := func() *monTypes.EnrichedGameData { + return &monTypes.EnrichedGameData{ + Claims: []faultTypes.Claim{ + { + ClaimData: faultTypes.ClaimData{ + Bond: monTypes.ResolvedBondAmount, + }, + Claimant: common.Address{0x01}, + CounteredBy: common.Address{0x02}, + }, + { + ClaimData: faultTypes.ClaimData{ + Bond: big.NewInt(5), + }, + Claimant: common.Address{0x03}, + CounteredBy: common.Address{}, + }, + { + ClaimData: faultTypes.ClaimData{ + Bond: big.NewInt(7), + }, + Claimant: common.Address{0x03}, + CounteredBy: common.Address{}, + }, + }, + } + } + + t.Run("GetCreditsFails", func(t *testing.T) { + enricher := NewBondEnricher() + caller := &mockGameCaller{creditsErr: errors.New("nope")} + game := makeGame() + err := enricher.Enrich(context.Background(), rpcblock.Latest, caller, game) + require.ErrorIs(t, err, caller.creditsErr) + }) + + t.Run("GetCreditsWrongNumberOfResults", func(t *testing.T) { + enricher := NewBondEnricher() + caller := &mockGameCaller{extraCredit: []*big.Int{big.NewInt(4)}} + game := makeGame() + err := enricher.Enrich(context.Background(), rpcblock.Latest, caller, game) + require.ErrorIs(t, err, ErrIncorrectCreditCount) + }) + + t.Run("GetCreditsSuccess", func(t *testing.T) { + game := makeGame() + expectedRecipients := []common.Address{ + game.Claims[0].Claimant, + game.Claims[0].CounteredBy, + game.Claims[1].Claimant, + // Claim 1 CounteredBy is unset + // Claim 2 Claimant is same as claim 1 Claimant + // Claim 2 CounteredBy is unset + } + enricher := NewBondEnricher() + expectedCredits := map[common.Address]*big.Int{ + expectedRecipients[0]: big.NewInt(10), + expectedRecipients[1]: big.NewInt(20), + expectedRecipients[2]: big.NewInt(30), + } + caller := &mockGameCaller{credits: expectedCredits} + err := enricher.Enrich(context.Background(), rpcblock.Latest, caller, game) + require.NoError(t, err) + + require.Equal(t, len(expectedRecipients), len(caller.requestedCredits)) + for _, recipient := range expectedRecipients { + require.Contains(t, caller.requestedCredits, recipient) + } + require.Equal(t, expectedCredits, game.Credits) + }) +} diff --git a/op-dispute-mon/mon/extract/caller.go b/op-dispute-mon/mon/extract/caller.go new file mode 100644 index 000000000000..caa92ae90902 --- /dev/null +++ b/op-dispute-mon/mon/extract/caller.go @@ -0,0 +1,53 @@ +package extract + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/caching" +) + +const metricsLabel = "game_caller_creator" + +type GameCaller interface { + GetGameMetadata(context.Context, rpcblock.Block) (common.Hash, uint64, common.Hash, types.GameStatus, uint64, error) + GetAllClaims(context.Context, rpcblock.Block) ([]faultTypes.Claim, error) + BondCaller + BalanceCaller +} + +type GameCallerCreator struct { + cache *caching.LRUCache[common.Address, *contracts.FaultDisputeGameContract] + caller *batching.MultiCaller +} + +func NewGameCallerCreator(m caching.Metrics, caller *batching.MultiCaller) *GameCallerCreator { + return &GameCallerCreator{ + caller: caller, + cache: caching.NewLRUCache[common.Address, *contracts.FaultDisputeGameContract](m, metricsLabel, 100), + } +} + +func (g *GameCallerCreator) CreateContract(game types.GameMetadata) (GameCaller, error) { + if fdg, ok := g.cache.Get(game.Proxy); ok { + return fdg, nil + } + switch game.GameType { + case faultTypes.CannonGameType, faultTypes.AlphabetGameType: + fdg, err := contracts.NewFaultDisputeGameContract(game.Proxy, g.caller) + if err != nil { + return nil, fmt.Errorf("failed to create FaultDisputeGameContract: %w", err) + } + g.cache.Add(game.Proxy, fdg) + return fdg, nil + default: + return nil, fmt.Errorf("unsupported game type: %d", game.GameType) + } +} diff --git a/op-dispute-mon/mon/extract/caller_test.go b/op-dispute-mon/mon/extract/caller_test.go new file mode 100644 index 000000000000..ffd0ba924bc3 --- /dev/null +++ b/op-dispute-mon/mon/extract/caller_test.go @@ -0,0 +1,81 @@ +package extract + +import ( + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" + "github.com/stretchr/testify/require" +) + +var ( + fdgAddr = common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB") +) + +func TestMetadataCreator_CreateContract(t *testing.T) { + tests := []struct { + name string + game types.GameMetadata + expectedErr error + }{ + { + name: "validCannonGameType", + game: types.GameMetadata{GameType: faultTypes.CannonGameType, Proxy: fdgAddr}, + }, + { + name: "validAlphabetGameType", + game: types.GameMetadata{GameType: faultTypes.AlphabetGameType, Proxy: fdgAddr}, + }, + { + name: "InvalidGameType", + game: types.GameMetadata{GameType: 2, Proxy: fdgAddr}, + expectedErr: fmt.Errorf("unsupported game type: 2"), + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + caller, metrics := setupMetadataLoaderTest(t) + creator := NewGameCallerCreator(metrics, caller) + _, err := creator.CreateContract(test.game) + require.Equal(t, test.expectedErr, err) + if test.expectedErr == nil { + require.Equal(t, 1, metrics.cacheAddCalls) + require.Equal(t, 1, metrics.cacheGetCalls) + } + _, err = creator.CreateContract(test.game) + require.Equal(t, test.expectedErr, err) + if test.expectedErr == nil { + require.Equal(t, 1, metrics.cacheAddCalls) + require.Equal(t, 2, metrics.cacheGetCalls) + } + }) + } +} + +func setupMetadataLoaderTest(t *testing.T) (*batching.MultiCaller, *mockCacheMetrics) { + fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() + require.NoError(t, err) + stubRpc := batchingTest.NewAbiBasedRpc(t, fdgAddr, fdgAbi) + caller := batching.NewMultiCaller(stubRpc, batching.DefaultBatchSize) + return caller, &mockCacheMetrics{} +} + +type mockCacheMetrics struct { + cacheAddCalls int + cacheGetCalls int +} + +func (m *mockCacheMetrics) CacheAdd(_ string, _ int, _ bool) { + m.cacheAddCalls++ +} +func (m *mockCacheMetrics) CacheGet(_ string, _ bool) { + m.cacheGetCalls++ +} diff --git a/op-dispute-mon/mon/extract/extractor.go b/op-dispute-mon/mon/extract/extractor.go new file mode 100644 index 000000000000..fa211a32a1eb --- /dev/null +++ b/op-dispute-mon/mon/extract/extractor.go @@ -0,0 +1,89 @@ +package extract + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" +) + +type CreateGameCaller func(game gameTypes.GameMetadata) (GameCaller, error) +type FactoryGameFetcher func(ctx context.Context, blockHash common.Hash, earliestTimestamp uint64) ([]gameTypes.GameMetadata, error) + +type Enricher interface { + Enrich(ctx context.Context, block rpcblock.Block, caller GameCaller, game *monTypes.EnrichedGameData) error +} + +type Extractor struct { + logger log.Logger + createContract CreateGameCaller + fetchGames FactoryGameFetcher + enrichers []Enricher +} + +func NewExtractor(logger log.Logger, creator CreateGameCaller, fetchGames FactoryGameFetcher, enrichers ...Enricher) *Extractor { + return &Extractor{ + logger: logger, + createContract: creator, + fetchGames: fetchGames, + enrichers: enrichers, + } +} + +func (e *Extractor) Extract(ctx context.Context, blockHash common.Hash, minTimestamp uint64) ([]*monTypes.EnrichedGameData, error) { + games, err := e.fetchGames(ctx, blockHash, minTimestamp) + if err != nil { + return nil, fmt.Errorf("failed to load games: %w", err) + } + return e.enrichGames(ctx, blockHash, games), nil +} + +func (e *Extractor) enrichGames(ctx context.Context, blockHash common.Hash, games []gameTypes.GameMetadata) []*monTypes.EnrichedGameData { + var enrichedGames []*monTypes.EnrichedGameData + for _, game := range games { + caller, err := e.createContract(game) + if err != nil { + e.logger.Error("Failed to create game caller", "err", err) + continue + } + l1Head, l2BlockNum, rootClaim, status, duration, err := caller.GetGameMetadata(ctx, rpcblock.ByHash(blockHash)) + if err != nil { + e.logger.Error("Failed to fetch game metadata", "err", err) + continue + } + claims, err := caller.GetAllClaims(ctx, rpcblock.ByHash(blockHash)) + if err != nil { + e.logger.Error("Failed to fetch game claims", "err", err) + continue + } + enrichedGame := &monTypes.EnrichedGameData{ + GameMetadata: game, + L1Head: l1Head, + L2BlockNumber: l2BlockNum, + RootClaim: rootClaim, + Status: status, + Duration: duration, + Claims: claims, + } + if err := e.applyEnrichers(ctx, blockHash, caller, enrichedGame); err != nil { + e.logger.Error("Failed to enrich game", "err", err) + continue + } + enrichedGames = append(enrichedGames, enrichedGame) + } + return enrichedGames +} + +func (e *Extractor) applyEnrichers(ctx context.Context, blockHash common.Hash, caller GameCaller, game *monTypes.EnrichedGameData) error { + for _, enricher := range e.enrichers { + if err := enricher.Enrich(ctx, rpcblock.ByHash(blockHash), caller, game); err != nil { + return err + } + } + return nil +} diff --git a/op-dispute-mon/mon/extract/extractor_test.go b/op-dispute-mon/mon/extract/extractor_test.go new file mode 100644 index 000000000000..83264baa4b9e --- /dev/null +++ b/op-dispute-mon/mon/extract/extractor_test.go @@ -0,0 +1,242 @@ +package extract + +import ( + "context" + "errors" + "math/big" + "testing" + + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/stretchr/testify/require" + + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +var mockRootClaim = common.HexToHash("0x1234") + +func TestExtractor_Extract(t *testing.T) { + t.Run("FetchGamesError", func(t *testing.T) { + extractor, _, games, _ := setupExtractorTest(t) + games.err = errors.New("boom") + _, err := extractor.Extract(context.Background(), common.Hash{}, 0) + require.ErrorIs(t, err, games.err) + require.Equal(t, 1, games.calls) + }) + + t.Run("CreateGameErrorLog", func(t *testing.T) { + extractor, creator, games, logs := setupExtractorTest(t) + games.games = []gameTypes.GameMetadata{{}} + creator.err = errors.New("boom") + enriched, err := extractor.Extract(context.Background(), common.Hash{}, 0) + require.NoError(t, err) + require.Len(t, enriched, 0) + require.Equal(t, 1, games.calls) + require.Equal(t, 1, creator.calls) + require.Equal(t, 0, creator.caller.metadataCalls) + require.Equal(t, 0, creator.caller.claimsCalls) + verifyLogs(t, logs, 1, 0, 0, 0) + }) + + t.Run("MetadataFetchErrorLog", func(t *testing.T) { + extractor, creator, games, logs := setupExtractorTest(t) + games.games = []gameTypes.GameMetadata{{}} + creator.caller.metadataErr = errors.New("boom") + enriched, err := extractor.Extract(context.Background(), common.Hash{}, 0) + require.NoError(t, err) + require.Len(t, enriched, 0) + require.Equal(t, 1, games.calls) + require.Equal(t, 1, creator.calls) + require.Equal(t, 1, creator.caller.metadataCalls) + require.Equal(t, 0, creator.caller.claimsCalls) + verifyLogs(t, logs, 0, 1, 0, 0) + }) + + t.Run("ClaimsFetchErrorLog", func(t *testing.T) { + extractor, creator, games, logs := setupExtractorTest(t) + games.games = []gameTypes.GameMetadata{{}} + creator.caller.claimsErr = errors.New("boom") + enriched, err := extractor.Extract(context.Background(), common.Hash{}, 0) + require.NoError(t, err) + require.Len(t, enriched, 0) + require.Equal(t, 1, games.calls) + require.Equal(t, 1, creator.calls) + require.Equal(t, 1, creator.caller.metadataCalls) + require.Equal(t, 1, creator.caller.claimsCalls) + verifyLogs(t, logs, 0, 0, 1, 0) + }) + + t.Run("Success", func(t *testing.T) { + extractor, creator, games, _ := setupExtractorTest(t) + games.games = []gameTypes.GameMetadata{{}} + enriched, err := extractor.Extract(context.Background(), common.Hash{}, 0) + require.NoError(t, err) + require.Len(t, enriched, 1) + require.Equal(t, 1, games.calls) + require.Equal(t, 1, creator.calls) + require.Equal(t, 1, creator.caller.metadataCalls) + require.Equal(t, 1, creator.caller.claimsCalls) + }) + + t.Run("EnricherFails", func(t *testing.T) { + enricher := &mockEnricher{err: errors.New("whoops")} + extractor, _, games, logs := setupExtractorTest(t, enricher) + games.games = []gameTypes.GameMetadata{{}} + enriched, err := extractor.Extract(context.Background(), common.Hash{}, 0) + require.NoError(t, err) + l := logs.FindLogs(testlog.NewMessageFilter("Failed to enrich game")) + require.Len(t, l, 1, "Should have logged error") + require.Len(t, enriched, 0, "Should not return games that failed to enrich") + }) + + t.Run("EnricherSuccess", func(t *testing.T) { + enricher := &mockEnricher{} + extractor, _, games, _ := setupExtractorTest(t, enricher) + games.games = []gameTypes.GameMetadata{{}} + enriched, err := extractor.Extract(context.Background(), common.Hash{}, 0) + require.NoError(t, err) + require.Len(t, enriched, 1) + require.Equal(t, 1, enricher.calls) + }) + + t.Run("MultipleEnrichersMultipleGames", func(t *testing.T) { + enricher1 := &mockEnricher{} + enricher2 := &mockEnricher{} + extractor, _, games, _ := setupExtractorTest(t, enricher1, enricher2) + games.games = []gameTypes.GameMetadata{{}, {}} + enriched, err := extractor.Extract(context.Background(), common.Hash{}, 0) + require.NoError(t, err) + require.Len(t, enriched, 2) + require.Equal(t, 2, enricher1.calls) + require.Equal(t, 2, enricher2.calls) + }) +} + +func verifyLogs(t *testing.T, logs *testlog.CapturingHandler, createErr int, metadataErr int, claimsErr int, durationErr int) { + errorLevelFilter := testlog.NewLevelFilter(log.LevelError) + createMessageFilter := testlog.NewMessageFilter("Failed to create game caller") + l := logs.FindLogs(errorLevelFilter, createMessageFilter) + require.Len(t, l, createErr) + fetchMessageFilter := testlog.NewMessageFilter("Failed to fetch game metadata") + l = logs.FindLogs(errorLevelFilter, fetchMessageFilter) + require.Len(t, l, metadataErr) + claimsMessageFilter := testlog.NewMessageFilter("Failed to fetch game claims") + l = logs.FindLogs(errorLevelFilter, claimsMessageFilter) + require.Len(t, l, claimsErr) + durationMessageFilter := testlog.NewMessageFilter("Failed to fetch game duration") + l = logs.FindLogs(errorLevelFilter, durationMessageFilter) + require.Len(t, l, durationErr) +} + +func setupExtractorTest(t *testing.T, enrichers ...Enricher) (*Extractor, *mockGameCallerCreator, *mockGameFetcher, *testlog.CapturingHandler) { + logger, capturedLogs := testlog.CaptureLogger(t, log.LvlDebug) + games := &mockGameFetcher{} + caller := &mockGameCaller{rootClaim: mockRootClaim} + creator := &mockGameCallerCreator{caller: caller} + extractor := NewExtractor( + logger, + creator.CreateGameCaller, + games.FetchGames, + enrichers..., + ) + return extractor, creator, games, capturedLogs +} + +type mockGameFetcher struct { + calls int + err error + games []gameTypes.GameMetadata +} + +func (m *mockGameFetcher) FetchGames(_ context.Context, _ common.Hash, _ uint64) ([]gameTypes.GameMetadata, error) { + m.calls++ + if m.err != nil { + return nil, m.err + } + return m.games, nil +} + +type mockGameCallerCreator struct { + calls int + err error + caller *mockGameCaller +} + +func (m *mockGameCallerCreator) CreateGameCaller(_ gameTypes.GameMetadata) (GameCaller, error) { + m.calls++ + if m.err != nil { + return nil, m.err + } + return m.caller, nil +} + +type mockGameCaller struct { + metadataCalls int + metadataErr error + claimsCalls int + claimsErr error + rootClaim common.Hash + claims []faultTypes.Claim + requestedCredits []common.Address + creditsErr error + credits map[common.Address]*big.Int + extraCredit []*big.Int + balanceErr error + balance *big.Int + balanceAddr common.Address +} + +func (m *mockGameCaller) GetGameMetadata(_ context.Context, _ rpcblock.Block) (common.Hash, uint64, common.Hash, types.GameStatus, uint64, error) { + m.metadataCalls++ + if m.metadataErr != nil { + return common.Hash{}, 0, common.Hash{}, 0, 0, m.metadataErr + } + return common.Hash{0xaa}, 0, mockRootClaim, 0, 0, nil +} + +func (m *mockGameCaller) GetAllClaims(_ context.Context, _ rpcblock.Block) ([]faultTypes.Claim, error) { + m.claimsCalls++ + if m.claimsErr != nil { + return nil, m.claimsErr + } + return m.claims, nil +} + +func (m *mockGameCaller) GetCredits(_ context.Context, _ rpcblock.Block, recipients ...common.Address) ([]*big.Int, error) { + m.requestedCredits = recipients + if m.creditsErr != nil { + return nil, m.creditsErr + } + response := make([]*big.Int, 0, len(recipients)) + for _, recipient := range recipients { + credit, ok := m.credits[recipient] + if !ok { + credit = big.NewInt(0) + } + response = append(response, credit) + } + response = append(response, m.extraCredit...) + return response, nil +} + +func (m *mockGameCaller) GetBalance(_ context.Context, _ rpcblock.Block) (*big.Int, common.Address, error) { + if m.balanceErr != nil { + return nil, common.Address{}, m.balanceErr + } + return m.balance, m.balanceAddr, nil +} + +type mockEnricher struct { + err error + calls int +} + +func (m *mockEnricher) Enrich(_ context.Context, _ rpcblock.Block, _ GameCaller, _ *monTypes.EnrichedGameData) error { + m.calls++ + return m.err +} diff --git a/op-dispute-mon/mon/extract/head_enricher.go b/op-dispute-mon/mon/extract/head_enricher.go new file mode 100644 index 000000000000..943e648f771d --- /dev/null +++ b/op-dispute-mon/mon/extract/head_enricher.go @@ -0,0 +1,34 @@ +package extract + +import ( + "context" + "fmt" + + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +var _ Enricher = (*L1HeadBlockNumEnricher)(nil) + +type BlockFetcher interface { + HeaderByHash(ctx context.Context, block common.Hash) (*types.Header, error) +} + +type L1HeadBlockNumEnricher struct { + client BlockFetcher +} + +func NewL1HeadBlockNumEnricher(client BlockFetcher) *L1HeadBlockNumEnricher { + return &L1HeadBlockNumEnricher{client: client} +} + +func (e *L1HeadBlockNumEnricher) Enrich(ctx context.Context, _ rpcblock.Block, _ GameCaller, game *monTypes.EnrichedGameData) error { + header, err := e.client.HeaderByHash(ctx, game.L1Head) + if err != nil { + return fmt.Errorf("failed to retrieve header for L1 head block %v: %w", game.L1Head, err) + } + game.L1HeadNum = header.Number.Uint64() + return nil +} diff --git a/op-dispute-mon/mon/extract/head_enricher_test.go b/op-dispute-mon/mon/extract/head_enricher_test.go new file mode 100644 index 000000000000..c0cb03b86b7a --- /dev/null +++ b/op-dispute-mon/mon/extract/head_enricher_test.go @@ -0,0 +1,49 @@ +package extract + +import ( + "context" + "errors" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + gethTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" +) + +func TestL1HeadEnricher(t *testing.T) { + t.Run("HeaderError", func(t *testing.T) { + client := &stubBlockFetcher{err: errors.New("boom")} + enricher := NewL1HeadBlockNumEnricher(client) + caller := &mockGameCaller{} + game := &types.EnrichedGameData{} + err := enricher.Enrich(context.Background(), rpcblock.Latest, caller, game) + require.ErrorIs(t, err, client.err) + }) + + t.Run("GetBalanceSuccess", func(t *testing.T) { + client := &stubBlockFetcher{num: 5000} + enricher := NewL1HeadBlockNumEnricher(client) + caller := &mockGameCaller{} + game := &types.EnrichedGameData{} + err := enricher.Enrich(context.Background(), rpcblock.Latest, caller, game) + require.NoError(t, err) + require.Equal(t, client.num, game.L1HeadNum) + }) +} + +type stubBlockFetcher struct { + num uint64 + err error +} + +func (s *stubBlockFetcher) HeaderByHash(_ context.Context, _ common.Hash) (*gethTypes.Header, error) { + if s.err != nil { + return nil, s.err + } + return &gethTypes.Header{ + Number: new(big.Int).SetUint64(s.num), + }, nil +} diff --git a/op-dispute-mon/mon/forecast.go b/op-dispute-mon/mon/forecast.go new file mode 100644 index 000000000000..b82a27a0129d --- /dev/null +++ b/op-dispute-mon/mon/forecast.go @@ -0,0 +1,138 @@ +package mon + +import ( + "context" + "errors" + "fmt" + + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-dispute-mon/metrics" + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/resolution" + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/transform" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum/go-ethereum/log" +) + +var ( + ErrRootAgreement = errors.New("failed to check root agreement") +) + +type OutputValidator interface { + CheckRootAgreement(ctx context.Context, l1HeadNum uint64, l2BlockNum uint64, root common.Hash) (bool, common.Hash, error) +} + +type ForecastMetrics interface { + RecordClaimResolutionDelayMax(delay float64) + RecordGameAgreement(status metrics.GameAgreementStatus, count int) +} + +type forecast struct { + logger log.Logger + metrics ForecastMetrics + validator OutputValidator +} + +func newForecast(logger log.Logger, metrics ForecastMetrics, validator OutputValidator) *forecast { + return &forecast{ + logger: logger, + metrics: metrics, + validator: validator, + } +} + +func (f *forecast) Forecast(ctx context.Context, games []*monTypes.EnrichedGameData) { + batch := monTypes.ForecastBatch{} + for _, game := range games { + if err := f.forecastGame(ctx, game, &batch); err != nil { + f.logger.Error("Failed to forecast game", "err", err) + } + } + f.recordBatch(batch) +} + +func (f *forecast) recordBatch(batch monTypes.ForecastBatch) { + f.metrics.RecordGameAgreement(metrics.AgreeDefenderWins, batch.AgreeDefenderWins) + f.metrics.RecordGameAgreement(metrics.DisagreeDefenderWins, batch.DisagreeDefenderWins) + f.metrics.RecordGameAgreement(metrics.AgreeChallengerWins, batch.AgreeChallengerWins) + f.metrics.RecordGameAgreement(metrics.DisagreeChallengerWins, batch.DisagreeChallengerWins) + + f.metrics.RecordGameAgreement(metrics.AgreeChallengerAhead, batch.AgreeChallengerAhead) + f.metrics.RecordGameAgreement(metrics.DisagreeChallengerAhead, batch.DisagreeChallengerAhead) + f.metrics.RecordGameAgreement(metrics.AgreeDefenderAhead, batch.AgreeDefenderAhead) + f.metrics.RecordGameAgreement(metrics.DisagreeDefenderAhead, batch.DisagreeDefenderAhead) +} + +func (f *forecast) forecastGame(ctx context.Context, game *monTypes.EnrichedGameData, metrics *monTypes.ForecastBatch) error { + // Check the root agreement. + agreement, expected, err := f.validator.CheckRootAgreement(ctx, game.L1HeadNum, game.L2BlockNumber, game.RootClaim) + if err != nil { + return fmt.Errorf("%w: %w", ErrRootAgreement, err) + } + + expectedResult := types.GameStatusDefenderWon + if !agreement { + expectedResult = types.GameStatusChallengerWon + } + + if game.Status != types.GameStatusInProgress { + if game.Status != expectedResult { + f.logger.Error("Unexpected game result", + "game", game.Proxy, "blockNum", game.L2BlockNumber, + "expectedResult", expectedResult, "actualResult", game.Status, + "rootClaim", game.RootClaim, "correctClaim", expected) + } + switch game.Status { + case types.GameStatusDefenderWon: + if agreement { + metrics.AgreeDefenderWins++ + } else { + metrics.DisagreeDefenderWins++ + } + case types.GameStatusChallengerWon: + if agreement { + metrics.AgreeChallengerWins++ + } else { + metrics.DisagreeChallengerWins++ + } + } + return nil + } + + // Create the bidirectional tree of claims. + tree := transform.CreateBidirectionalTree(game.Claims) + + // Compute the resolution status of the game. + forecastStatus := resolution.Resolve(tree) + + if agreement { + // If we agree with the output root proposal, the Defender should win, defending that claim. + if forecastStatus == types.GameStatusChallengerWon { + metrics.AgreeChallengerAhead++ + f.logger.Warn("Forecasting unexpected game result", "status", forecastStatus, + "game", game.Proxy, "blockNum", game.L2BlockNumber, + "rootClaim", game.RootClaim, "expected", expected) + } else { + metrics.AgreeDefenderAhead++ + f.logger.Debug("Forecasting expected game result", "status", forecastStatus, + "game", game.Proxy, "blockNum", game.L2BlockNumber, + "rootClaim", game.RootClaim, "expected", expected) + } + } else { + // If we disagree with the output root proposal, the Challenger should win, challenging that claim. + if forecastStatus == types.GameStatusDefenderWon { + metrics.DisagreeDefenderAhead++ + f.logger.Warn("Forecasting unexpected game result", "status", forecastStatus, + "game", game.Proxy, "blockNum", game.L2BlockNumber, + "rootClaim", game.RootClaim, "expected", expected) + } else { + metrics.DisagreeChallengerAhead++ + f.logger.Debug("Forecasting expected game result", "status", forecastStatus, + "game", game.Proxy, "blockNum", game.L2BlockNumber, + "rootClaim", game.RootClaim, "expected", expected) + } + } + + return nil +} diff --git a/op-dispute-mon/mon/forecast_test.go b/op-dispute-mon/mon/forecast_test.go new file mode 100644 index 000000000000..16a97f0fee1a --- /dev/null +++ b/op-dispute-mon/mon/forecast_test.go @@ -0,0 +1,332 @@ +package mon + +import ( + "context" + "errors" + "fmt" + "math" + "math/big" + "testing" + + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-dispute-mon/metrics" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var ( + failedForecastLog = "Failed to forecast game" + lostGameLog = "Unexpected game result" + unexpectedResultLog = "Forecasting unexpected game result" + expectedResultLog = "Forecasting expected game result" +) + +func TestForecast_Forecast_BasicTests(t *testing.T) { + t.Parallel() + + t.Run("NoGames", func(t *testing.T) { + forecast, _, rollup, logs := setupForecastTest(t) + forecast.Forecast(context.Background(), []*monTypes.EnrichedGameData{}) + require.Equal(t, 0, rollup.calls) + levelFilter := testlog.NewLevelFilter(log.LevelError) + messageFilter := testlog.NewMessageFilter(failedForecastLog) + require.Nil(t, logs.FindLog(levelFilter, messageFilter)) + }) + + t.Run("RollupFetchFails", func(t *testing.T) { + forecast, _, rollup, logs := setupForecastTest(t) + rollup.err = errors.New("boom") + forecast.Forecast(context.Background(), []*monTypes.EnrichedGameData{{}}) + require.Equal(t, 1, rollup.calls) + levelFilter := testlog.NewLevelFilter(log.LevelError) + messageFilter := testlog.NewMessageFilter(failedForecastLog) + l := logs.FindLog(levelFilter, messageFilter) + require.NotNil(t, l) + err := l.AttrValue("err") + expectedErr := fmt.Errorf("%w: %w", ErrRootAgreement, rollup.err) + require.Equal(t, expectedErr, err) + }) + + t.Run("ChallengerWonGame_Agree", func(t *testing.T) { + forecast, m, _, logs := setupForecastTest(t) + expectedGame := monTypes.EnrichedGameData{Status: types.GameStatusChallengerWon, RootClaim: mockRootClaim} + forecast.Forecast(context.Background(), []*monTypes.EnrichedGameData{&expectedGame}) + l := logs.FindLog(testlog.NewLevelFilter(log.LevelError), testlog.NewMessageFilter(lostGameLog)) + require.NotNil(t, l) + require.Equal(t, expectedGame.Proxy, l.AttrValue("game")) + require.Equal(t, types.GameStatusDefenderWon, l.AttrValue("expectedResult")) + require.Equal(t, types.GameStatusChallengerWon, l.AttrValue("actualResult")) + + expectedMetrics := zeroGameAgreement() + expectedMetrics[metrics.AgreeChallengerWins] = 1 + require.Equal(t, expectedMetrics, m.gameAgreement) + }) + + t.Run("ChallengerWonGame_Disagree", func(t *testing.T) { + forecast, m, _, logs := setupForecastTest(t) + expectedGame := monTypes.EnrichedGameData{Status: types.GameStatusChallengerWon, RootClaim: common.Hash{0xbb}} + forecast.Forecast(context.Background(), []*monTypes.EnrichedGameData{&expectedGame}) + l := logs.FindLog(testlog.NewLevelFilter(log.LevelError), testlog.NewMessageFilter(lostGameLog)) + require.Nil(t, l) + + expectedMetrics := zeroGameAgreement() + expectedMetrics[metrics.DisagreeChallengerWins] = 1 + require.Equal(t, expectedMetrics, m.gameAgreement) + }) + + t.Run("DefenderWonGame_Agree", func(t *testing.T) { + forecast, m, _, logs := setupForecastTest(t) + expectedGame := monTypes.EnrichedGameData{Status: types.GameStatusDefenderWon, RootClaim: mockRootClaim} + forecast.Forecast(context.Background(), []*monTypes.EnrichedGameData{&expectedGame}) + l := logs.FindLog(testlog.NewLevelFilter(log.LevelError), testlog.NewMessageFilter(lostGameLog)) + require.Nil(t, l) + + expectedMetrics := zeroGameAgreement() + expectedMetrics[metrics.AgreeDefenderWins] = 1 + require.Equal(t, expectedMetrics, m.gameAgreement) + }) + + t.Run("DefenderWonGame_Disagree", func(t *testing.T) { + forecast, m, _, logs := setupForecastTest(t) + expectedGame := monTypes.EnrichedGameData{Status: types.GameStatusDefenderWon, RootClaim: common.Hash{0xbb}} + forecast.Forecast(context.Background(), []*monTypes.EnrichedGameData{&expectedGame}) + l := logs.FindLog(testlog.NewLevelFilter(log.LevelError), testlog.NewMessageFilter(lostGameLog)) + require.NotNil(t, l) + require.Equal(t, expectedGame.Proxy, l.AttrValue("game")) + require.Equal(t, types.GameStatusChallengerWon, l.AttrValue("expectedResult")) + require.Equal(t, types.GameStatusDefenderWon, l.AttrValue("actualResult")) + + expectedMetrics := zeroGameAgreement() + expectedMetrics[metrics.DisagreeDefenderWins] = 1 + require.Equal(t, expectedMetrics, m.gameAgreement) + }) + + t.Run("SingleGame", func(t *testing.T) { + forecast, _, rollup, logs := setupForecastTest(t) + forecast.Forecast(context.Background(), []*monTypes.EnrichedGameData{{}}) + require.Equal(t, 1, rollup.calls) + require.Nil(t, logs.FindLog(testlog.NewLevelFilter(log.LevelError), testlog.NewMessageFilter(failedForecastLog))) + }) + + t.Run("MultipleGames", func(t *testing.T) { + forecast, _, rollup, logs := setupForecastTest(t) + forecast.Forecast(context.Background(), []*monTypes.EnrichedGameData{{}, {}, {}}) + require.Equal(t, 3, rollup.calls) + require.Nil(t, logs.FindLog(testlog.NewLevelFilter(log.LevelError), testlog.NewMessageFilter(failedForecastLog))) + }) +} + +func TestForecast_Forecast_EndLogs(t *testing.T) { + t.Parallel() + + t.Run("AgreeDefenderWins", func(t *testing.T) { + forecast, _, rollup, logs := setupForecastTest(t) + games := []*monTypes.EnrichedGameData{{ + Status: types.GameStatusInProgress, + RootClaim: mockRootClaim, + Claims: createDeepClaimList()[:1], + }} + forecast.Forecast(context.Background(), games) + require.Equal(t, 1, rollup.calls) + levelFilter := testlog.NewLevelFilter(log.LevelError) + messageFilter := testlog.NewMessageFilter(failedForecastLog) + require.Nil(t, logs.FindLog(levelFilter, messageFilter)) + levelFilter = testlog.NewLevelFilter(log.LevelDebug) + messageFilter = testlog.NewMessageFilter(expectedResultLog) + l := logs.FindLog(levelFilter, messageFilter) + require.NotNil(t, l) + require.Equal(t, mockRootClaim, l.AttrValue("rootClaim")) + require.Equal(t, mockRootClaim, l.AttrValue("expected")) + require.Equal(t, types.GameStatusDefenderWon, l.AttrValue("status")) + }) + + t.Run("AgreeChallengerWins", func(t *testing.T) { + forecast, _, rollup, logs := setupForecastTest(t) + games := []*monTypes.EnrichedGameData{{ + Status: types.GameStatusInProgress, + RootClaim: mockRootClaim, + Claims: createDeepClaimList()[:2], + }} + forecast.Forecast(context.Background(), games) + require.Equal(t, 1, rollup.calls) + levelFilter := testlog.NewLevelFilter(log.LevelError) + messageFilter := testlog.NewMessageFilter(failedForecastLog) + require.Nil(t, logs.FindLog(levelFilter, messageFilter)) + levelFilter = testlog.NewLevelFilter(log.LevelWarn) + messageFilter = testlog.NewMessageFilter(unexpectedResultLog) + l := logs.FindLog(levelFilter, messageFilter) + require.NotNil(t, l) + require.Equal(t, mockRootClaim, l.AttrValue("rootClaim")) + require.Equal(t, mockRootClaim, l.AttrValue("expected")) + require.Equal(t, types.GameStatusChallengerWon, l.AttrValue("status")) + }) + + t.Run("DisagreeChallengerWins", func(t *testing.T) { + forecast, _, rollup, logs := setupForecastTest(t) + forecast.Forecast(context.Background(), []*monTypes.EnrichedGameData{{ + Status: types.GameStatusInProgress, + Claims: createDeepClaimList()[:2], + }}) + require.Equal(t, 1, rollup.calls) + levelFilter := testlog.NewLevelFilter(log.LevelError) + messageFilter := testlog.NewMessageFilter(failedForecastLog) + require.Nil(t, logs.FindLog(levelFilter, messageFilter)) + levelFilter = testlog.NewLevelFilter(log.LevelDebug) + messageFilter = testlog.NewMessageFilter(expectedResultLog) + l := logs.FindLog(levelFilter, messageFilter) + require.NotNil(t, l) + require.Equal(t, common.Hash{}, l.AttrValue("rootClaim")) + require.Equal(t, mockRootClaim, l.AttrValue("expected")) + require.Equal(t, types.GameStatusChallengerWon, l.AttrValue("status")) + }) + + t.Run("DisagreeDefenderWins", func(t *testing.T) { + forecast, _, rollup, logs := setupForecastTest(t) + forecast.Forecast(context.Background(), []*monTypes.EnrichedGameData{{ + Status: types.GameStatusInProgress, + Claims: createDeepClaimList()[:1], + }}) + require.Equal(t, 1, rollup.calls) + levelFilter := testlog.NewLevelFilter(log.LevelError) + messageFilter := testlog.NewMessageFilter(failedForecastLog) + require.Nil(t, logs.FindLog(levelFilter, messageFilter)) + levelFilter = testlog.NewLevelFilter(log.LevelWarn) + messageFilter = testlog.NewMessageFilter(unexpectedResultLog) + l := logs.FindLog(levelFilter, messageFilter) + require.NotNil(t, l) + require.Equal(t, common.Hash{}, l.AttrValue("rootClaim")) + require.Equal(t, mockRootClaim, l.AttrValue("expected")) + require.Equal(t, types.GameStatusDefenderWon, l.AttrValue("status")) + }) +} + +func TestForecast_Forecast_MultipleGames(t *testing.T) { + forecast, _, rollup, logs := setupForecastTest(t) + gameStatus := []types.GameStatus{ + types.GameStatusChallengerWon, + types.GameStatusInProgress, + types.GameStatusInProgress, + types.GameStatusDefenderWon, + types.GameStatusInProgress, + types.GameStatusInProgress, + types.GameStatusDefenderWon, + types.GameStatusChallengerWon, + types.GameStatusChallengerWon, + } + claims := [][]faultTypes.Claim{ + createDeepClaimList()[:1], + createDeepClaimList()[:2], + createDeepClaimList()[:2], + createDeepClaimList()[:1], + createDeepClaimList()[:1], + createDeepClaimList()[:1], + createDeepClaimList()[:1], + createDeepClaimList()[:1], + createDeepClaimList()[:1], + } + rootClaims := []common.Hash{ + {}, + {}, + mockRootClaim, + {}, + {}, + mockRootClaim, + {}, + {}, + {}, + } + games := make([]*monTypes.EnrichedGameData, 9) + for i := range games { + games[i] = &monTypes.EnrichedGameData{ + Status: gameStatus[i], + Claims: claims[i], + RootClaim: rootClaims[i], + } + } + forecast.Forecast(context.Background(), games) + require.Equal(t, len(games), rollup.calls) + levelFilter := testlog.NewLevelFilter(log.LevelError) + messageFilter := testlog.NewMessageFilter(failedForecastLog) + require.Nil(t, logs.FindLog(levelFilter, messageFilter)) +} + +func setupForecastTest(t *testing.T) (*forecast, *mockForecastMetrics, *stubOutputValidator, *testlog.CapturingHandler) { + logger, capturedLogs := testlog.CaptureLogger(t, log.LvlDebug) + validator := &stubOutputValidator{} + metrics := &mockForecastMetrics{ + gameAgreement: zeroGameAgreement(), + } + return newForecast(logger, metrics, validator), metrics, validator, capturedLogs +} + +func zeroGameAgreement() map[metrics.GameAgreementStatus]int { + return map[metrics.GameAgreementStatus]int{ + metrics.AgreeChallengerAhead: 0, + metrics.DisagreeChallengerAhead: 0, + metrics.AgreeDefenderAhead: 0, + metrics.DisagreeDefenderAhead: 0, + metrics.AgreeDefenderWins: 0, + metrics.DisagreeDefenderWins: 0, + metrics.AgreeChallengerWins: 0, + metrics.DisagreeChallengerWins: 0, + } +} + +type mockForecastMetrics struct { + gameAgreement map[metrics.GameAgreementStatus]int + claimResolutionDelayMax float64 +} + +func (m *mockForecastMetrics) RecordGameAgreement(status metrics.GameAgreementStatus, count int) { + m.gameAgreement[status] = count +} + +func (m *mockForecastMetrics) RecordClaimResolutionDelayMax(delay float64) { + m.claimResolutionDelayMax = delay +} + +func createDeepClaimList() []faultTypes.Claim { + return []faultTypes.Claim{ + { + ClaimData: faultTypes.ClaimData{ + Position: faultTypes.NewPosition(0, big.NewInt(0)), + }, + ContractIndex: 0, + ParentContractIndex: math.MaxInt64, + Claimant: common.HexToAddress("0x111111"), + }, + { + ClaimData: faultTypes.ClaimData{ + Position: faultTypes.NewPosition(1, big.NewInt(0)), + }, + ContractIndex: 1, + ParentContractIndex: 0, + Claimant: common.HexToAddress("0x222222"), + }, + { + ClaimData: faultTypes.ClaimData{ + Position: faultTypes.NewPosition(2, big.NewInt(0)), + }, + ContractIndex: 2, + ParentContractIndex: 1, + Claimant: common.HexToAddress("0x111111"), + }, + } +} + +type stubOutputValidator struct { + calls int + err error +} + +func (s *stubOutputValidator) CheckRootAgreement(_ context.Context, _ uint64, _ uint64, rootClaim common.Hash) (bool, common.Hash, error) { + s.calls++ + if s.err != nil { + return false, common.Hash{}, s.err + } + return rootClaim == mockRootClaim, mockRootClaim, nil +} diff --git a/op-dispute-mon/mon/monitor.go b/op-dispute-mon/mon/monitor.go new file mode 100644 index 000000000000..5e8fe55df2df --- /dev/null +++ b/op-dispute-mon/mon/monitor.go @@ -0,0 +1,128 @@ +package mon + +import ( + "context" + "fmt" + "math/big" + "time" + + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/clock" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +type Forecast func(ctx context.Context, games []*types.EnrichedGameData) +type Bonds func(games []*types.EnrichedGameData) +type BlockHashFetcher func(ctx context.Context, number *big.Int) (common.Hash, error) +type BlockNumberFetcher func(ctx context.Context) (uint64, error) +type Extract func(ctx context.Context, blockHash common.Hash, minTimestamp uint64) ([]*types.EnrichedGameData, error) +type RecordClaimResolutionDelayMax func([]*types.EnrichedGameData) + +type gameMonitor struct { + logger log.Logger + clock clock.Clock + + done chan struct{} + ctx context.Context + cancel context.CancelFunc + + gameWindow time.Duration + monitorInterval time.Duration + + delays RecordClaimResolutionDelayMax + forecast Forecast + bonds Bonds + extract Extract + fetchBlockHash BlockHashFetcher + fetchBlockNumber BlockNumberFetcher +} + +func newGameMonitor( + ctx context.Context, + logger log.Logger, + cl clock.Clock, + monitorInterval time.Duration, + gameWindow time.Duration, + delays RecordClaimResolutionDelayMax, + forecast Forecast, + bonds Bonds, + extract Extract, + fetchBlockNumber BlockNumberFetcher, + fetchBlockHash BlockHashFetcher, +) *gameMonitor { + return &gameMonitor{ + logger: logger, + clock: cl, + ctx: ctx, + done: make(chan struct{}), + monitorInterval: monitorInterval, + gameWindow: gameWindow, + delays: delays, + forecast: forecast, + bonds: bonds, + extract: extract, + fetchBlockNumber: fetchBlockNumber, + fetchBlockHash: fetchBlockHash, + } +} + +func (m *gameMonitor) monitorGames() error { + blockNumber, err := m.fetchBlockNumber(m.ctx) + if err != nil { + return fmt.Errorf("failed to fetch block number: %w", err) + } + m.logger.Debug("Fetched block number", "blockNumber", blockNumber) + blockHash, err := m.fetchBlockHash(context.Background(), new(big.Int).SetUint64(blockNumber)) + if err != nil { + return fmt.Errorf("failed to fetch block hash: %w", err) + } + minGameTimestamp := clock.MinCheckedTimestamp(m.clock, m.gameWindow) + enrichedGames, err := m.extract(m.ctx, blockHash, minGameTimestamp) + if err != nil { + return fmt.Errorf("failed to load games: %w", err) + } + m.delays(enrichedGames) + m.forecast(m.ctx, enrichedGames) + m.bonds(enrichedGames) + return nil +} + +func (m *gameMonitor) loop() { + ticker := m.clock.NewTicker(m.monitorInterval) + defer ticker.Stop() + for { + select { + case <-ticker.Ch(): + if err := m.monitorGames(); err != nil { + m.logger.Error("Failed to monitor games", "err", err) + } + case <-m.done: + m.logger.Info("Stopping game monitor") + return + } + } +} + +func (m *gameMonitor) StartMonitoring() { + // Setup the cancellation only if it's not already set. + // This prevents overwriting the context and cancel function + // if, for example, this function is called multiple times. + if m.cancel == nil { + ctx, cancel := context.WithCancel(m.ctx) + m.ctx = ctx + m.cancel = cancel + } + m.logger.Info("Starting game monitor") + go m.loop() +} + +func (m *gameMonitor) StopMonitoring() { + m.logger.Info("Stopping game monitor") + if m.cancel != nil { + m.cancel() + m.cancel = nil + } + close(m.done) +} diff --git a/op-dispute-mon/mon/monitor_test.go b/op-dispute-mon/mon/monitor_test.go new file mode 100644 index 000000000000..6127d145fbef --- /dev/null +++ b/op-dispute-mon/mon/monitor_test.go @@ -0,0 +1,181 @@ +package mon + +import ( + "context" + "errors" + "math/big" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var ( + mockErr = errors.New("mock error") +) + +func TestMonitor_MonitorGames(t *testing.T) { + t.Parallel() + + t.Run("FailedFetchBlocknumber", func(t *testing.T) { + monitor, _, _, _, _ := setupMonitorTest(t) + boom := errors.New("boom") + monitor.fetchBlockNumber = func(ctx context.Context) (uint64, error) { + return 0, boom + } + err := monitor.monitorGames() + require.ErrorIs(t, err, boom) + }) + + t.Run("FailedFetchBlockHash", func(t *testing.T) { + monitor, _, _, _, _ := setupMonitorTest(t) + boom := errors.New("boom") + monitor.fetchBlockHash = func(ctx context.Context, number *big.Int) (common.Hash, error) { + return common.Hash{}, boom + } + err := monitor.monitorGames() + require.ErrorIs(t, err, boom) + }) + + t.Run("MonitorsWithNoGames", func(t *testing.T) { + monitor, factory, forecast, delays, bonds := setupMonitorTest(t) + factory.games = []*monTypes.EnrichedGameData{} + err := monitor.monitorGames() + require.NoError(t, err) + require.Equal(t, 1, forecast.calls) + require.Equal(t, 1, delays.calls) + require.Equal(t, 1, bonds.calls) + }) + + t.Run("MonitorsMultipleGames", func(t *testing.T) { + monitor, factory, forecast, delays, bonds := setupMonitorTest(t) + factory.games = []*monTypes.EnrichedGameData{{}, {}, {}} + err := monitor.monitorGames() + require.NoError(t, err) + require.Equal(t, 1, forecast.calls) + require.Equal(t, 1, delays.calls) + require.Equal(t, 1, bonds.calls) + }) +} + +func TestMonitor_StartMonitoring(t *testing.T) { + t.Run("MonitorsGames", func(t *testing.T) { + addr1 := common.Address{0xaa} + addr2 := common.Address{0xbb} + monitor, factory, forecaster, _, _ := setupMonitorTest(t) + factory.games = []*monTypes.EnrichedGameData{newEnrichedGameData(addr1, 9999), newEnrichedGameData(addr2, 9999)} + factory.maxSuccess = len(factory.games) // Only allow two successful fetches + + monitor.StartMonitoring() + require.Eventually(t, func() bool { + return forecaster.calls >= 2 + }, time.Second, 50*time.Millisecond) + monitor.StopMonitoring() + require.Equal(t, len(factory.games), forecaster.calls) // Each game's status is recorded twice + }) + + t.Run("FailsToFetchGames", func(t *testing.T) { + monitor, factory, forecaster, _, _ := setupMonitorTest(t) + factory.fetchErr = errors.New("boom") + + monitor.StartMonitoring() + require.Eventually(t, func() bool { + return factory.calls > 0 + }, time.Second, 50*time.Millisecond) + monitor.StopMonitoring() + require.Equal(t, 0, forecaster.calls) + }) +} + +func newEnrichedGameData(proxy common.Address, timestamp uint64) *monTypes.EnrichedGameData { + return &monTypes.EnrichedGameData{ + GameMetadata: types.GameMetadata{ + Proxy: proxy, + Timestamp: timestamp, + }, + Status: types.GameStatusInProgress, + } +} + +func setupMonitorTest(t *testing.T) (*gameMonitor, *mockExtractor, *mockForecast, *mockDelayCalculator, *mockBonds) { + logger := testlog.Logger(t, log.LvlDebug) + fetchBlockNum := func(ctx context.Context) (uint64, error) { + return 1, nil + } + fetchBlockHash := func(ctx context.Context, number *big.Int) (common.Hash, error) { + return common.Hash{}, nil + } + monitorInterval := 100 * time.Millisecond + cl := clock.NewAdvancingClock(10 * time.Millisecond) + cl.Start() + extractor := &mockExtractor{} + forecast := &mockForecast{} + bonds := &mockBonds{} + delays := &mockDelayCalculator{} + monitor := newGameMonitor( + context.Background(), + logger, + cl, + monitorInterval, + 10*time.Second, + delays.RecordClaimResolutionDelayMax, + forecast.Forecast, + bonds.CheckBonds, + extractor.Extract, + fetchBlockNum, + fetchBlockHash, + ) + return monitor, extractor, forecast, delays, bonds +} + +type mockDelayCalculator struct { + calls int +} + +func (m *mockDelayCalculator) RecordClaimResolutionDelayMax(games []*monTypes.EnrichedGameData) { + m.calls++ +} + +type mockForecast struct { + calls int +} + +func (m *mockForecast) Forecast(ctx context.Context, games []*monTypes.EnrichedGameData) { + m.calls++ +} + +type mockBonds struct { + calls int +} + +func (m *mockBonds) CheckBonds(_ []*monTypes.EnrichedGameData) { + m.calls++ +} + +type mockExtractor struct { + fetchErr error + calls int + maxSuccess int + games []*monTypes.EnrichedGameData +} + +func (m *mockExtractor) Extract( + _ context.Context, + _ common.Hash, + _ uint64, +) ([]*monTypes.EnrichedGameData, error) { + m.calls++ + if m.fetchErr != nil { + return nil, m.fetchErr + } + if m.calls > m.maxSuccess && m.maxSuccess != 0 { + return nil, mockErr + } + return m.games, nil +} diff --git a/op-dispute-mon/mon/resolution/delay.go b/op-dispute-mon/mon/resolution/delay.go new file mode 100644 index 000000000000..5067f3aa7f95 --- /dev/null +++ b/op-dispute-mon/mon/resolution/delay.go @@ -0,0 +1,52 @@ +package resolution + +import ( + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/clock" +) + +type DelayMetrics interface { + RecordClaimResolutionDelayMax(delay float64) +} + +type DelayCalculator struct { + metrics DelayMetrics + clock clock.Clock +} + +func NewDelayCalculator(metrics DelayMetrics, clock clock.Clock) *DelayCalculator { + return &DelayCalculator{ + metrics: metrics, + clock: clock, + } +} + +func (d *DelayCalculator) RecordClaimResolutionDelayMax(games []*monTypes.EnrichedGameData) { + var maxDelay uint64 = 0 + for _, game := range games { + maxDelay = max(d.getMaxResolutionDelay(game), maxDelay) + } + d.metrics.RecordClaimResolutionDelayMax(float64(maxDelay)) +} + +func (d *DelayCalculator) getMaxResolutionDelay(game *monTypes.EnrichedGameData) uint64 { + var maxDelay uint64 = 0 + for _, claim := range game.Claims { + maxDelay = max(d.getOverflowTime(game.Duration, &claim), maxDelay) + } + return maxDelay +} + +func (d *DelayCalculator) getOverflowTime(maxGameDuration uint64, claim *types.Claim) uint64 { + // If the bond amount is the max uint128 value, the claim is resolved. + if monTypes.ResolvedBondAmount.Cmp(claim.ClaimData.Bond) == 0 { + return 0 + } + maxChessTime := maxGameDuration / 2 + accumulatedTime := uint64(claim.ChessTime(d.clock.Now())) + if accumulatedTime < maxChessTime { + return 0 + } + return accumulatedTime - maxChessTime +} diff --git a/op-dispute-mon/mon/resolution/delay_test.go b/op-dispute-mon/mon/resolution/delay_test.go new file mode 100644 index 000000000000..355a846e7c9d --- /dev/null +++ b/op-dispute-mon/mon/resolution/delay_test.go @@ -0,0 +1,181 @@ +package resolution + +import ( + "math/big" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/stretchr/testify/require" +) + +var ( + maxGameDuration = uint64(960) + frozen = time.Unix(int64(time.Hour.Seconds()), 0) +) + +func TestDelayCalculator_getOverflowTime(t *testing.T) { + t.Run("NoClock", func(t *testing.T) { + d, metrics, _ := setupDelayCalculatorTest(t) + claim := &types.Claim{ + ClaimData: types.ClaimData{ + Bond: monTypes.ResolvedBondAmount, + }, + } + delay := d.getOverflowTime(maxGameDuration, claim) + require.Equal(t, uint64(0), delay) + require.Equal(t, 0, metrics.calls) + }) + + t.Run("RemainingTime", func(t *testing.T) { + d, metrics, cl := setupDelayCalculatorTest(t) + duration := uint64(3 * 60) + timestamp := uint64(cl.Now().Add(-time.Minute).Unix()) + claim := &types.Claim{ + ClaimData: types.ClaimData{ + Bond: big.NewInt(5), + }, + Clock: types.NewClock(duration, timestamp), + } + delay := d.getOverflowTime(maxGameDuration, claim) + require.Equal(t, uint64(0), delay) + require.Equal(t, 0, metrics.calls) + }) + + t.Run("OverflowTime", func(t *testing.T) { + d, metrics, cl := setupDelayCalculatorTest(t) + duration := maxGameDuration / 2 + timestamp := uint64(cl.Now().Add(4 * -time.Minute).Unix()) + claim := &types.Claim{ + ClaimData: types.ClaimData{ + Bond: big.NewInt(5), + }, + Clock: types.NewClock(duration, timestamp), + } + delay := d.getOverflowTime(maxGameDuration, claim) + require.Equal(t, uint64(240), delay) + require.Equal(t, 0, metrics.calls) + }) +} + +func TestDelayCalculator_getMaxResolutionDelay(t *testing.T) { + tests := []struct { + name string + claims []types.Claim + want uint64 + }{ + {"NoClaims", []types.Claim{}, 0}, + {"SingleClaim", createClaimList()[:1], 180}, + {"MultipleClaims", createClaimList()[:2], 300}, + {"ClaimsWithMaxUint128", createClaimList(), 300}, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + d, metrics, _ := setupDelayCalculatorTest(t) + game := &monTypes.EnrichedGameData{ + Claims: test.claims, + Duration: maxGameDuration, + } + got := d.getMaxResolutionDelay(game) + require.Equal(t, 0, metrics.calls) + require.Equal(t, test.want, got) + }) + } +} + +func TestDelayCalculator_RecordClaimResolutionDelayMax(t *testing.T) { + tests := []struct { + name string + games []*monTypes.EnrichedGameData + want float64 + }{ + {"NoGames", createGameWithClaimsList()[:0], 0}, + {"SingleGame", createGameWithClaimsList()[:1], 180}, + {"MultipleGames", createGameWithClaimsList()[:2], 300}, + {"ClaimsWithMaxUint128", createGameWithClaimsList(), 300}, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + d, metrics, _ := setupDelayCalculatorTest(t) + d.RecordClaimResolutionDelayMax(test.games) + require.Equal(t, 1, metrics.calls) + require.Equal(t, test.want, metrics.maxDelay) + }) + } +} + +func setupDelayCalculatorTest(t *testing.T) (*DelayCalculator, *mockDelayMetrics, *clock.DeterministicClock) { + metrics := &mockDelayMetrics{} + cl := clock.NewDeterministicClock(frozen) + return NewDelayCalculator(metrics, cl), metrics, cl +} + +func createGameWithClaimsList() []*monTypes.EnrichedGameData { + return []*monTypes.EnrichedGameData{ + { + Claims: createClaimList()[:1], + Duration: maxGameDuration, + }, + { + Claims: createClaimList()[:2], + Duration: maxGameDuration, + }, + { + Claims: createClaimList(), + Duration: maxGameDuration, + }, + } +} + +func createClaimList() []types.Claim { + newClock := func(multiplier int) *types.Clock { + duration := maxGameDuration / 2 + timestamp := uint64(frozen.Add(-time.Minute * time.Duration(multiplier)).Unix()) + return types.NewClock(duration, timestamp) + } + return []types.Claim{ + { + ClaimData: types.ClaimData{ + Bond: big.NewInt(5), + }, + Clock: newClock(3), + }, + { + ClaimData: types.ClaimData{ + Bond: big.NewInt(10), + }, + Clock: newClock(5), + }, + { + ClaimData: types.ClaimData{ + Bond: big.NewInt(100), + }, + Clock: newClock(2), + }, + { + // This claim should be skipped because it's resolved. + ClaimData: types.ClaimData{ + Bond: monTypes.ResolvedBondAmount, + }, + Clock: newClock(10), + }, + } +} + +type mockDelayMetrics struct { + calls int + maxDelay float64 +} + +func (m *mockDelayMetrics) RecordClaimResolutionDelayMax(delay float64) { + m.calls++ + if delay > m.maxDelay { + m.maxDelay = delay + } +} diff --git a/op-dispute-mon/mon/resolution/resolver.go b/op-dispute-mon/mon/resolution/resolver.go new file mode 100644 index 000000000000..a27ebaadac63 --- /dev/null +++ b/op-dispute-mon/mon/resolution/resolver.go @@ -0,0 +1,36 @@ +package resolution + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" +) + +// Resolve iterates backwards over the bidirectional tree, iteratively +// checking the leftmost counter of each claim, and updating the claim's counter +// claimant. Once the root claim is reached, the resolution game status is returned. +func Resolve(tree *monTypes.BidirectionalTree) gameTypes.GameStatus { + for i := len(tree.Claims) - 1; i >= 0; i-- { + claim := tree.Claims[i] + counterClaimant := claim.Claim.CounteredBy + var leftmostCounter *big.Int + for _, child := range claim.Children { + if child.Claim.CounteredBy != (common.Address{}) { + continue // Ignore countered claims + } + if leftmostCounter == nil || child.Claim.Position.IndexAtDepth().Cmp(leftmostCounter) < 0 { + counterClaimant = child.Claim.Claimant + leftmostCounter = child.Claim.Position.IndexAtDepth() + } + } + claim.Claim.CounteredBy = counterClaimant + } + if (len(tree.Claims) == 0 || tree.Claims[0].Claim.CounteredBy == common.Address{}) { + return gameTypes.GameStatusDefenderWon + } else { + return gameTypes.GameStatusChallengerWon + } +} diff --git a/op-dispute-mon/mon/resolution/resolver_test.go b/op-dispute-mon/mon/resolution/resolver_test.go new file mode 100644 index 000000000000..d949b2285ce5 --- /dev/null +++ b/op-dispute-mon/mon/resolution/resolver_test.go @@ -0,0 +1,169 @@ +package resolution + +import ( + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test" + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/transform" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" +) + +func TestResolver_Resolve(t *testing.T) { + t.Run("NoClaims", func(t *testing.T) { + tree := transform.CreateBidirectionalTree([]faultTypes.Claim{}) + status := Resolve(tree) + require.Equal(t, gameTypes.GameStatusDefenderWon, status) + }) + + t.Run("SingleRootClaim", func(t *testing.T) { + builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 4).GameBuilder() + tree := transform.CreateBidirectionalTree(builder.Game.Claims()) + tree.Claims[0].Claim.CounteredBy = common.Address{} + status := Resolve(tree) + require.Equal(t, gameTypes.GameStatusDefenderWon, status) + }) + + t.Run("ManyClaims_ChallengerWon", func(t *testing.T) { + builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder() + builder.Seq(). // Defender winning + Attack(). // Challenger winning + Attack(). // Defender winning + Defend(). // Challenger winning + Defend(). // Defender winning + Attack() // Challenger winning + tree := transform.CreateBidirectionalTree(builder.Game.Claims()) + status := Resolve(tree) + require.Equal(t, gameTypes.GameStatusChallengerWon, status) + }) + + t.Run("ManyClaims_DefenderWon", func(t *testing.T) { + builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder() + builder.Seq(). // Defender winning + Attack(). // Challenger winning + Attack(). // Defender winning + Defend(). // Challenger winning + Defend() // Defender winning + tree := transform.CreateBidirectionalTree(builder.Game.Claims()) + status := Resolve(tree) + require.Equal(t, gameTypes.GameStatusDefenderWon, status) + }) + + t.Run("MultipleBranches_ChallengerWon", func(t *testing.T) { + builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder() + forkPoint := builder.Seq(). // Defender winning + Attack(). // Challenger winning + Attack() // Defender winning + forkPoint. + Defend(). // Challenger winning + Defend(). // Defender winning + Attack() // Challenger winning + forkPoint.Defend(test.WithValue(common.Hash{0xbb})). // Challenger winning + Defend(). // Defender winning + Attack(). // Challenger winning + Step() // Defender winning + forkPoint.Defend(test.WithValue(common.Hash{0xcc})). // Challenger winning + Defend() // Defender winning + tree := transform.CreateBidirectionalTree(builder.Game.Claims()) + status := Resolve(tree) + // First fork has an uncountered claim with challenger winning so that invalidates the parent and wins the game + require.Equal(t, gameTypes.GameStatusChallengerWon, status) + }) + + t.Run("MultipleBranches_DefenderWon", func(t *testing.T) { + builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder() + forkPoint := builder.Seq(). // Defender winning + Attack(). // Challenger winning + Attack() // Defender winning + forkPoint. + Defend(). // Challenger winning + Defend() // Defender winning + forkPoint.Defend(test.WithValue(common.Hash{0xbb})). // Challenger winning + Defend(). // Defender winning + Attack(). // Challenger winning + Step() // Defender winning + forkPoint.Defend(test.WithValue(common.Hash{0xcc})). // Challenger winning + Defend() // Defender winning + + tree := transform.CreateBidirectionalTree(builder.Game.Claims()) + status := Resolve(tree) + // Defender won all forks + require.Equal(t, gameTypes.GameStatusDefenderWon, status) + }) + + t.Run("UseLeftMostUncounteredClaim", func(t *testing.T) { + builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder() + expectedRootCounteredBy := common.Address{0xaa} + forkPoint := builder.Seq(). // Defender winning + Attack(test.WithClaimant(expectedRootCounteredBy)). // Challenger winning + Attack() // Defender winning + + // Left most child of forkPoint, but has been countered + forkPoint. + Attack(test.WithValue(common.Hash{0xaa}), test.WithClaimant(common.Address{0xbb})). + Defend() + + // Uncountered child, but not leftmost + forkPoint. + Defend(test.WithValue(common.Hash{0xbb}), test.WithClaimant(common.Address{0xcc})). // Challenger winning + Defend(). // Defender winning + Defend() // Challenger winning + + // Left most child that is ultimately uncountered and should be used as CounteredBy + expectedCounteredBy := common.Address{0xdd} + forkPoint. + Attack(test.WithClaimant(expectedCounteredBy)). + Defend(). + Defend() + + // Uncountered child, + forkPoint. + Defend(test.WithClaimant(common.Address{0xee})). // Challenger winning + Defend(). // Defender winning + Defend() // Challenger winning + tree := transform.CreateBidirectionalTree(builder.Game.Claims()) + status := Resolve(tree) + // Defender won all forks + require.Equal(t, gameTypes.GameStatusChallengerWon, status) + forkPointClaim := tree.Claims[2].Claim + require.Equal(t, expectedCounteredBy, forkPointClaim.CounteredBy) + require.Equal(t, expectedRootCounteredBy, tree.Claims[0].Claim.CounteredBy) + }) + + t.Run("SteppedClaimed_ChallengerWon", func(t *testing.T) { + builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 4).GameBuilder() + builder.Seq(). // Defender winning + Attack(). // Challenger winning + Attack(). // Defender winning + Defend(). // Challenger winning + Defend(). // Defender winning + Step() // Challenger winning + claims := builder.Game.Claims() + // Successful step so mark as countered + claims[len(claims)-1].CounteredBy = common.Address{0xaa} + tree := transform.CreateBidirectionalTree(claims) + status := Resolve(tree) + require.Equal(t, gameTypes.GameStatusChallengerWon, status) + }) + + t.Run("SteppedClaimed_DefenderWon", func(t *testing.T) { + builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder() + builder.Seq(). // Defender winning + Attack(). // Challenger winning + Attack(). // Defender winning + Defend(). // Challenger winning + Defend(). // Defender winning + Attack(). // Challenger winning + Step() // Defender winning + claims := builder.Game.Claims() + // Successful step so mark as countered + claims[len(claims)-1].CounteredBy = common.Address{0xaa} + tree := transform.CreateBidirectionalTree(claims) + status := Resolve(tree) + require.Equal(t, gameTypes.GameStatusDefenderWon, status) + }) +} diff --git a/op-dispute-mon/mon/service.go b/op-dispute-mon/mon/service.go new file mode 100644 index 000000000000..593917781e35 --- /dev/null +++ b/op-dispute-mon/mon/service.go @@ -0,0 +1,248 @@ +package mon + +import ( + "context" + "errors" + "fmt" + "math/big" + "sync/atomic" + + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/bonds" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-dispute-mon/config" + "github.com/ethereum-optimism/optimism/op-dispute-mon/metrics" + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/extract" + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/resolution" + "github.com/ethereum-optimism/optimism/op-dispute-mon/version" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/httputil" + opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/oppprof" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" +) + +type Service struct { + logger log.Logger + metrics metrics.Metricer + monitor *gameMonitor + + factoryContract *contracts.DisputeGameFactoryContract + + cl clock.Clock + + delays *resolution.DelayCalculator + extractor *extract.Extractor + forecast *forecast + bonds *bonds.Bonds + game *extract.GameCallerCreator + rollupClient *sources.RollupClient + validator *outputValidator + + l1Client *ethclient.Client + + pprofService *oppprof.Service + metricsSrv *httputil.HTTPServer + + stopped atomic.Bool +} + +// NewService creates a new Service. +func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*Service, error) { + s := &Service{ + cl: clock.SystemClock, + logger: logger, + metrics: metrics.NewMetrics(), + } + + if err := s.initFromConfig(ctx, cfg); err != nil { + return nil, errors.Join(fmt.Errorf("failed to init service: %w", err), s.Stop(ctx)) + } + + return s, nil +} + +func (s *Service) initFromConfig(ctx context.Context, cfg *config.Config) error { + if err := s.initL1Client(ctx, cfg); err != nil { + return fmt.Errorf("failed to init l1 client: %w", err) + } + if err := s.initPProf(&cfg.PprofConfig); err != nil { + return fmt.Errorf("failed to init profiling: %w", err) + } + if err := s.initMetricsServer(&cfg.MetricsConfig); err != nil { + return fmt.Errorf("failed to init metrics server: %w", err) + } + if err := s.initFactoryContract(cfg); err != nil { + return fmt.Errorf("failed to create factory contract bindings: %w", err) + } + if err := s.initOutputRollupClient(ctx, cfg); err != nil { + return fmt.Errorf("failed to init rollup client: %w", err) + } + + s.initOutputValidator() // Must be called before initForecast + s.initGameCallerCreator() // Must be called before initForecast + + s.initDelayCalculator() + s.initExtractor() + + s.initForecast(cfg) + s.initBonds() + + s.initMonitor(ctx, cfg) // Monitor must be initialized last + + s.metrics.RecordInfo(version.SimpleWithMeta) + s.metrics.RecordUp() + + return nil +} + +func (s *Service) initOutputValidator() { + s.validator = newOutputValidator(s.logger, s.metrics, s.rollupClient) +} + +func (s *Service) initGameCallerCreator() { + s.game = extract.NewGameCallerCreator(s.metrics, batching.NewMultiCaller(s.l1Client.Client(), batching.DefaultBatchSize)) +} + +func (s *Service) initDelayCalculator() { + s.delays = resolution.NewDelayCalculator(s.metrics, s.cl) +} + +func (s *Service) initExtractor() { + s.extractor = extract.NewExtractor(s.logger, s.game.CreateContract, s.factoryContract.GetGamesAtOrAfter, + extract.NewBondEnricher(), + extract.NewBalanceEnricher(), + extract.NewL1HeadBlockNumEnricher(s.l1Client), + ) +} + +func (s *Service) initForecast(cfg *config.Config) { + s.forecast = newForecast(s.logger, s.metrics, s.validator) +} + +func (s *Service) initBonds() { + s.bonds = bonds.NewBonds(s.logger, s.metrics) +} + +func (s *Service) initOutputRollupClient(ctx context.Context, cfg *config.Config) error { + outputRollupClient, err := dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, s.logger, cfg.RollupRpc) + if err != nil { + return fmt.Errorf("failed to dial rollup client: %w", err) + } + s.rollupClient = outputRollupClient + return nil +} + +func (s *Service) initL1Client(ctx context.Context, cfg *config.Config) error { + l1Client, err := dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, s.logger, cfg.L1EthRpc) + if err != nil { + return fmt.Errorf("failed to dial L1: %w", err) + } + s.l1Client = l1Client + return nil +} + +func (s *Service) initPProf(cfg *oppprof.CLIConfig) error { + s.pprofService = oppprof.New( + cfg.ListenEnabled, + cfg.ListenAddr, + cfg.ListenPort, + cfg.ProfileType, + cfg.ProfileDir, + cfg.ProfileFilename, + ) + + if err := s.pprofService.Start(); err != nil { + return fmt.Errorf("failed to start pprof service: %w", err) + } + + return nil +} + +func (s *Service) initMetricsServer(cfg *opmetrics.CLIConfig) error { + if !cfg.Enabled { + return nil + } + s.logger.Debug("starting metrics server", "addr", cfg.ListenAddr, "port", cfg.ListenPort) + m, ok := s.metrics.(opmetrics.RegistryMetricer) + if !ok { + return fmt.Errorf("metrics were enabled, but metricer %T does not expose registry for metrics-server", s.metrics) + } + metricsSrv, err := opmetrics.StartServer(m.Registry(), cfg.ListenAddr, cfg.ListenPort) + if err != nil { + return fmt.Errorf("failed to start metrics server: %w", err) + } + s.logger.Info("started metrics server", "addr", metricsSrv.Addr()) + s.metricsSrv = metricsSrv + return nil +} + +func (s *Service) initFactoryContract(cfg *config.Config) error { + factoryContract, err := contracts.NewDisputeGameFactoryContract(cfg.GameFactoryAddress, + batching.NewMultiCaller(s.l1Client.Client(), batching.DefaultBatchSize)) + if err != nil { + return fmt.Errorf("failed to bind the fault dispute game factory contract: %w", err) + } + s.factoryContract = factoryContract + return nil +} + +func (s *Service) initMonitor(ctx context.Context, cfg *config.Config) { + blockHashFetcher := func(ctx context.Context, blockNumber *big.Int) (common.Hash, error) { + block, err := s.l1Client.BlockByNumber(ctx, blockNumber) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to fetch block by number: %w", err) + } + return block.Hash(), nil + } + s.monitor = newGameMonitor( + ctx, + s.logger, + s.cl, + cfg.MonitorInterval, + cfg.GameWindow, + s.delays.RecordClaimResolutionDelayMax, + s.forecast.Forecast, + s.bonds.CheckBonds, + s.extractor.Extract, + s.l1Client.BlockNumber, + blockHashFetcher, + ) +} + +func (s *Service) Start(ctx context.Context) error { + s.logger.Info("Starting scheduler") + s.logger.Info("Starting monitoring") + s.monitor.StartMonitoring() + s.logger.Info("Dispute monitor game service start completed") + return nil +} + +func (s *Service) Stopped() bool { + return s.stopped.Load() +} + +func (s *Service) Stop(ctx context.Context) error { + s.logger.Info("Stopping dispute mon service") + + var result error + if s.pprofService != nil { + if err := s.pprofService.Stop(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close pprof server: %w", err)) + } + } + if s.metricsSrv != nil { + if err := s.metricsSrv.Stop(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close metrics server: %w", err)) + } + } + s.stopped.Store(true) + s.logger.Info("stopped dispute mon service", "err", result) + return result +} diff --git a/op-dispute-mon/mon/transform/collateral.go b/op-dispute-mon/mon/transform/collateral.go new file mode 100644 index 000000000000..14263f2641f8 --- /dev/null +++ b/op-dispute-mon/mon/transform/collateral.go @@ -0,0 +1,50 @@ +package transform + +import ( + "math/big" + + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum/go-ethereum/common" +) + +type Collateral struct { + // Required is the amount of collateral required to pay out bonds. + Required *big.Int + + // Actual is the amount of collateral actually head by the DelayedWETH contract + Actual *big.Int +} + +// CalculateRequiredCollateral determines the minimum balance required for each DelayedWETH contract used by a set +// of dispute games. +// Returns a map of DelayedWETH contract address to collateral data (required and actual amounts) +func CalculateRequiredCollateral(games []*monTypes.EnrichedGameData) map[common.Address]Collateral { + result := make(map[common.Address]Collateral) + for _, game := range games { + collateral, ok := result[game.WETHContract] + if !ok { + collateral = Collateral{ + Required: big.NewInt(0), + Actual: game.ETHCollateral, + } + } + gameRequired := requiredCollateralForGame(game) + collateral.Required = new(big.Int).Add(collateral.Required, gameRequired) + result[game.WETHContract] = collateral + } + return result +} + +func requiredCollateralForGame(game *monTypes.EnrichedGameData) *big.Int { + required := big.NewInt(0) + for _, claim := range game.Claims { + if monTypes.ResolvedBondAmount.Cmp(claim.Bond) != 0 { + required = new(big.Int).Add(required, claim.Bond) + } + } + + for _, unclaimedCredit := range game.Credits { + required = new(big.Int).Add(required, unclaimedCredit) + } + return required +} diff --git a/op-dispute-mon/mon/transform/collateral_test.go b/op-dispute-mon/mon/transform/collateral_test.go new file mode 100644 index 000000000000..96dc64967765 --- /dev/null +++ b/op-dispute-mon/mon/transform/collateral_test.go @@ -0,0 +1,104 @@ +package transform + +import ( + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestCalculateRequiredCollateral(t *testing.T) { + weth1 := common.Address{0x1a} + weth1Balance := big.NewInt(4200) + weth2 := common.Address{0x2b} + weth2Balance := big.NewInt(6000) + game1 := &monTypes.EnrichedGameData{ + Claims: []types.Claim{ + { + ClaimData: types.ClaimData{ + Bond: monTypes.ResolvedBondAmount, + }, + Claimant: common.Address{0x01}, + CounteredBy: common.Address{0x02}, + }, + { + ClaimData: types.ClaimData{ + Bond: big.NewInt(5), + }, + Claimant: common.Address{0x03}, + CounteredBy: common.Address{}, + }, + { + ClaimData: types.ClaimData{ + Bond: big.NewInt(7), + }, + Claimant: common.Address{0x03}, + CounteredBy: common.Address{}, + }, + }, + Credits: map[common.Address]*big.Int{ + common.Address{0x01}: big.NewInt(2), + common.Address{0x04}: big.NewInt(3), + }, + WETHContract: weth1, + ETHCollateral: weth1Balance, + } + game2 := &monTypes.EnrichedGameData{ + Claims: []types.Claim{ + { + ClaimData: types.ClaimData{ + Bond: monTypes.ResolvedBondAmount, + }, + Claimant: common.Address{0x01}, + CounteredBy: common.Address{0x02}, + }, + { + ClaimData: types.ClaimData{ + Bond: big.NewInt(6), + }, + Claimant: common.Address{0x03}, + CounteredBy: common.Address{}, + }, + { + ClaimData: types.ClaimData{ + Bond: big.NewInt(9), + }, + Claimant: common.Address{0x03}, + CounteredBy: common.Address{}, + }, + }, + Credits: map[common.Address]*big.Int{ + common.Address{0x01}: big.NewInt(4), + common.Address{0x04}: big.NewInt(1), + }, + WETHContract: weth1, + ETHCollateral: weth1Balance, + } + game3 := &monTypes.EnrichedGameData{ + Claims: []types.Claim{ + { + ClaimData: types.ClaimData{ + Bond: big.NewInt(23), + }, + Claimant: common.Address{0x03}, + CounteredBy: common.Address{}, + }, + }, + Credits: map[common.Address]*big.Int{ + common.Address{0x01}: big.NewInt(46), + }, + WETHContract: weth2, + ETHCollateral: weth2Balance, + } + actual := CalculateRequiredCollateral([]*monTypes.EnrichedGameData{game1, game2, game3}) + require.Len(t, actual, 2) + require.Contains(t, actual, weth1) + require.Contains(t, actual, weth2) + require.Equal(t, actual[weth1].Required.Uint64(), uint64(5+7+2+3+6+9+4+1)) + require.Equal(t, actual[weth1].Actual.Uint64(), weth1Balance.Uint64()) + require.Equal(t, actual[weth2].Required.Uint64(), uint64(23+46)) + require.Equal(t, actual[weth2].Actual.Uint64(), weth2Balance.Uint64()) +} diff --git a/op-dispute-mon/mon/transform/tree.go b/op-dispute-mon/mon/transform/tree.go new file mode 100644 index 000000000000..e9bcff71c50a --- /dev/null +++ b/op-dispute-mon/mon/transform/tree.go @@ -0,0 +1,28 @@ +package transform + +import ( + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types" +) + +// CreateBidirectionalTree walks backwards through the list of claims and creates a bidirectional +// tree of claims. The root claim must be at index 0. The tree is returned as a flat array so it +// can be easily traversed following the resolution process. +func CreateBidirectionalTree(claims []types.Claim) *monTypes.BidirectionalTree { + claimMap := make(map[int]*monTypes.BidirectionalClaim) + res := make([]*monTypes.BidirectionalClaim, 0, len(claims)) + for _, claim := range claims { + claim := claim + bidirectionalClaim := &monTypes.BidirectionalClaim{ + Claim: &claim, + } + claimMap[claim.ContractIndex] = bidirectionalClaim + if !claim.IsRoot() { + // SAFETY: the parent must exist in the list prior to the current claim. + parent := claimMap[claim.ParentContractIndex] + parent.Children = append(parent.Children, bidirectionalClaim) + } + res = append(res, bidirectionalClaim) + } + return &monTypes.BidirectionalTree{Claims: res} +} diff --git a/op-dispute-mon/mon/transform/tree_test.go b/op-dispute-mon/mon/transform/tree_test.go new file mode 100644 index 000000000000..dba36ec25608 --- /dev/null +++ b/op-dispute-mon/mon/transform/tree_test.go @@ -0,0 +1,80 @@ +package transform + +import ( + "math" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" +) + +func TestResolver_CreateBidirectionalTree(t *testing.T) { + t.Run("SingleClaim", func(t *testing.T) { + claims := createDeepClaimList()[:1] + claims[0].CounteredBy = common.Address{} + tree := CreateBidirectionalTree(claims) + require.Len(t, tree.Claims, 1) + require.Equal(t, claims[0], *tree.Claims[0].Claim) + require.Empty(t, tree.Claims[0].Children) + }) + + t.Run("MultipleClaims", func(t *testing.T) { + claims := createDeepClaimList()[:2] + claims[1].CounteredBy = common.Address{} + tree := CreateBidirectionalTree(claims) + require.Len(t, tree.Claims, 2) + require.Equal(t, claims[0], *tree.Claims[0].Claim) + require.Len(t, tree.Claims[0].Children, 1) + require.Equal(t, claims[1], *tree.Claims[0].Children[0].Claim) + require.Equal(t, claims[1], *tree.Claims[1].Claim) + require.Empty(t, tree.Claims[1].Children) + }) + + t.Run("MultipleClaimsAndChildren", func(t *testing.T) { + claims := createDeepClaimList() + tree := CreateBidirectionalTree(claims) + require.Len(t, tree.Claims, 3) + require.Equal(t, claims[0], *tree.Claims[0].Claim) + require.Len(t, tree.Claims[0].Children, 1) + require.Equal(t, tree.Claims[0].Children[0], tree.Claims[1]) + require.Equal(t, claims[1], *tree.Claims[1].Claim) + require.Len(t, tree.Claims[1].Children, 1) + require.Equal(t, tree.Claims[1].Children[0], tree.Claims[2]) + require.Equal(t, claims[2], *tree.Claims[2].Claim) + require.Empty(t, tree.Claims[2].Children) + }) +} + +func createDeepClaimList() []types.Claim { + return []types.Claim{ + { + ClaimData: types.ClaimData{ + Position: types.NewPosition(0, big.NewInt(0)), + }, + ContractIndex: 0, + CounteredBy: common.HexToAddress("0x222222"), + ParentContractIndex: math.MaxInt64, + Claimant: common.HexToAddress("0x111111"), + }, + { + ClaimData: types.ClaimData{ + Position: types.NewPosition(1, big.NewInt(0)), + }, + CounteredBy: common.HexToAddress("0x111111"), + ContractIndex: 1, + ParentContractIndex: 0, + Claimant: common.HexToAddress("0x222222"), + }, + { + ClaimData: types.ClaimData{ + Position: types.NewPosition(2, big.NewInt(0)), + }, + ContractIndex: 2, + ParentContractIndex: 1, + Claimant: common.HexToAddress("0x111111"), + }, + } +} diff --git a/op-dispute-mon/mon/types/types.go b/op-dispute-mon/mon/types/types.go new file mode 100644 index 000000000000..c7232cc8f18b --- /dev/null +++ b/op-dispute-mon/mon/types/types.go @@ -0,0 +1,57 @@ +package types + +import ( + "math/big" + + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum/go-ethereum/common" +) + +// ResolvedBondAmount is the uint128 value where a bond is considered claimed. +var ResolvedBondAmount = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 128), big.NewInt(1)) + +type EnrichedGameData struct { + types.GameMetadata + L1Head common.Hash + L1HeadNum uint64 + L2BlockNumber uint64 + RootClaim common.Hash + Status types.GameStatus + Duration uint64 + Claims []faultTypes.Claim + + // Credits records the paid out bonds for the game, keyed by recipient. + Credits map[common.Address]*big.Int + + // WETHContract is the address of the DelayedWETH contract used by this game + // The contract is potentially shared by multiple games. + WETHContract common.Address + + // ETHCollateral is the ETH balance of the (potentially shared) WETHContract + // This ETH balance will be used to pay out any bonds required by the games that use the same DelayedWETH contract. + ETHCollateral *big.Int +} + +// BidirectionalTree is a tree of claims represented as a flat list of claims. +// This keeps the tree structure identical to how claims are stored in the contract. +type BidirectionalTree struct { + Claims []*BidirectionalClaim +} + +type BidirectionalClaim struct { + Claim *faultTypes.Claim + Children []*BidirectionalClaim +} + +type ForecastBatch struct { + AgreeDefenderAhead int + DisagreeDefenderAhead int + AgreeChallengerAhead int + DisagreeChallengerAhead int + + AgreeDefenderWins int + DisagreeDefenderWins int + AgreeChallengerWins int + DisagreeChallengerWins int +} diff --git a/op-dispute-mon/mon/types/types_test.go b/op-dispute-mon/mon/types/types_test.go new file mode 100644 index 000000000000..1958be239954 --- /dev/null +++ b/op-dispute-mon/mon/types/types_test.go @@ -0,0 +1,11 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestMaxValue(t *testing.T) { + require.Equal(t, ResolvedBondAmount.String(), "340282366920938463463374607431768211455") +} diff --git a/op-dispute-mon/mon/validator.go b/op-dispute-mon/mon/validator.go new file mode 100644 index 000000000000..32e1e879db5d --- /dev/null +++ b/op-dispute-mon/mon/validator.go @@ -0,0 +1,67 @@ +package mon + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type OutputRollupClient interface { + OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) + SafeHeadAtL1Block(ctx context.Context, blockNum uint64) (*eth.SafeHeadResponse, error) +} + +type OutputMetrics interface { + RecordOutputFetchTime(float64) +} + +type outputValidator struct { + log log.Logger + metrics OutputMetrics + client OutputRollupClient +} + +func newOutputValidator(logger log.Logger, metrics OutputMetrics, client OutputRollupClient) *outputValidator { + return &outputValidator{ + log: logger, + metrics: metrics, + client: client, + } +} + +// CheckRootAgreement validates the specified root claim against the output at the given block number. +func (o *outputValidator) CheckRootAgreement(ctx context.Context, l1HeadNum uint64, l2BlockNum uint64, rootClaim common.Hash) (bool, common.Hash, error) { + output, err := o.client.OutputAtBlock(ctx, l2BlockNum) + if err != nil { + // string match as the error comes from the remote server so we can't use Errors.Is sadly. + if strings.Contains(err.Error(), "not found") { + // Output root doesn't exist, so we must disagree with it. + return false, common.Hash{}, nil + } + return false, common.Hash{}, fmt.Errorf("failed to get output at block: %w", err) + } + o.metrics.RecordOutputFetchTime(float64(time.Now().Unix())) + expected := common.Hash(output.OutputRoot) + rootMatches := rootClaim == expected + if !rootMatches { + return false, expected, nil + } + + // If the root matches, also check that l2 block is safe at the L1 head + safeHead, err := o.client.SafeHeadAtL1Block(ctx, l1HeadNum) + if err != nil { + o.log.Warn("Unable to verify proposed block was safe", "l1HeadNum", l1HeadNum, "l2BlockNum", l2BlockNum, "err", err) + // If safe head data isn't available, assume the output root was safe + // Avoids making the dispute mon dependent on safe head db being available + // + return true, expected, nil + } + isSafe := safeHead.SafeHead.Number >= l2BlockNum + return isSafe, expected, nil +} diff --git a/op-dispute-mon/mon/validator_test.go b/op-dispute-mon/mon/validator_test.go new file mode 100644 index 000000000000..5b395bee98f9 --- /dev/null +++ b/op-dispute-mon/mon/validator_test.go @@ -0,0 +1,139 @@ +package mon + +import ( + "context" + "errors" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +var ( + mockRootClaim = common.HexToHash("0x10") +) + +func TestDetector_CheckRootAgreement(t *testing.T) { + t.Parallel() + + t.Run("OutputFetchFails", func(t *testing.T) { + validator, rollup, metrics := setupOutputValidatorTest(t) + rollup.outputErr = errors.New("boom") + agree, fetched, err := validator.CheckRootAgreement(context.Background(), 100, 0, mockRootClaim) + require.ErrorIs(t, err, rollup.outputErr) + require.Equal(t, common.Hash{}, fetched) + require.False(t, agree) + require.Zero(t, metrics.fetchTime) + }) + + t.Run("OutputMismatch_Safe", func(t *testing.T) { + validator, _, metrics := setupOutputValidatorTest(t) + agree, fetched, err := validator.CheckRootAgreement(context.Background(), 100, 0, common.Hash{}) + require.NoError(t, err) + require.Equal(t, mockRootClaim, fetched) + require.False(t, agree) + require.NotZero(t, metrics.fetchTime) + }) + + t.Run("OutputMatches_Safe", func(t *testing.T) { + validator, _, metrics := setupOutputValidatorTest(t) + agree, fetched, err := validator.CheckRootAgreement(context.Background(), 200, 0, mockRootClaim) + require.NoError(t, err) + require.Equal(t, mockRootClaim, fetched) + require.True(t, agree) + require.NotZero(t, metrics.fetchTime) + }) + + t.Run("OutputMismatch_NotSafe", func(t *testing.T) { + validator, client, metrics := setupOutputValidatorTest(t) + client.safeHeadNum = 99 + agree, fetched, err := validator.CheckRootAgreement(context.Background(), 100, 0, common.Hash{}) + require.NoError(t, err) + require.Equal(t, mockRootClaim, fetched) + require.False(t, agree) + require.NotZero(t, metrics.fetchTime) + }) + + t.Run("OutputMatches_SafeHeadError", func(t *testing.T) { + validator, client, metrics := setupOutputValidatorTest(t) + client.safeHeadErr = errors.New("boom") + agree, fetched, err := validator.CheckRootAgreement(context.Background(), 200, 0, mockRootClaim) + require.NoError(t, err) + require.Equal(t, mockRootClaim, fetched) + require.True(t, agree) // Assume safe if we can't retrieve the safe head so monitoring isn't dependent on safe head db + require.NotZero(t, metrics.fetchTime) + }) + + t.Run("OutputMismatch_SafeHeadError", func(t *testing.T) { + validator, client, metrics := setupOutputValidatorTest(t) + client.safeHeadErr = errors.New("boom") + agree, fetched, err := validator.CheckRootAgreement(context.Background(), 100, 0, common.Hash{}) + require.NoError(t, err) + require.Equal(t, mockRootClaim, fetched) + require.False(t, agree) // Not agreed because the root doesn't match + require.NotZero(t, metrics.fetchTime) + }) + + t.Run("OutputMatches_NotSafe", func(t *testing.T) { + validator, client, metrics := setupOutputValidatorTest(t) + client.safeHeadNum = 99 + agree, fetched, err := validator.CheckRootAgreement(context.Background(), 200, 100, mockRootClaim) + require.NoError(t, err) + require.Equal(t, mockRootClaim, fetched) + require.False(t, agree) + require.NotZero(t, metrics.fetchTime) + }) + + t.Run("OutputNotFound", func(t *testing.T) { + validator, rollup, metrics := setupOutputValidatorTest(t) + // This crazy error is what we actually get back from the API + rollup.outputErr = errors.New("failed to get L2 block ref with sync status: failed to determine L2BlockRef of height 42984924, could not get payload: not found") + agree, fetched, err := validator.CheckRootAgreement(context.Background(), 100, 42984924, mockRootClaim) + require.NoError(t, err) + require.Equal(t, common.Hash{}, fetched) + require.False(t, agree) + require.Zero(t, metrics.fetchTime) + }) +} + +func setupOutputValidatorTest(t *testing.T) (*outputValidator, *stubRollupClient, *stubOutputMetrics) { + logger := testlog.Logger(t, log.LvlInfo) + client := &stubRollupClient{safeHeadNum: 99999999999} + metrics := &stubOutputMetrics{} + validator := newOutputValidator(logger, metrics, client) + return validator, client, metrics +} + +type stubOutputMetrics struct { + fetchTime float64 +} + +func (s *stubOutputMetrics) RecordOutputFetchTime(fetchTime float64) { + s.fetchTime = fetchTime +} + +type stubRollupClient struct { + blockNum uint64 + outputErr error + safeHeadErr error + safeHeadNum uint64 +} + +func (s *stubRollupClient) OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) { + s.blockNum = blockNum + return ð.OutputResponse{OutputRoot: eth.Bytes32(mockRootClaim)}, s.outputErr +} + +func (s *stubRollupClient) SafeHeadAtL1Block(_ context.Context, _ uint64) (*eth.SafeHeadResponse, error) { + if s.safeHeadErr != nil { + return nil, s.safeHeadErr + } + return ð.SafeHeadResponse{ + SafeHead: eth.BlockID{ + Number: s.safeHeadNum, + }, + }, nil +} diff --git a/op-dispute-mon/monitor.go b/op-dispute-mon/monitor.go new file mode 100644 index 000000000000..42e82b3d7c77 --- /dev/null +++ b/op-dispute-mon/monitor.go @@ -0,0 +1,18 @@ +package monitor + +import ( + "context" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-dispute-mon/config" + "github.com/ethereum-optimism/optimism/op-dispute-mon/mon" + "github.com/ethereum-optimism/optimism/op-service/cliapp" +) + +func Main(ctx context.Context, logger log.Logger, cfg *config.Config) (cliapp.Lifecycle, error) { + if err := cfg.Check(); err != nil { + return nil, err + } + return mon.NewService(ctx, logger, cfg) +} diff --git a/op-dispute-mon/monitor_test.go b/op-dispute-mon/monitor_test.go new file mode 100644 index 000000000000..6a8896d114e0 --- /dev/null +++ b/op-dispute-mon/monitor_test.go @@ -0,0 +1,18 @@ +package monitor + +import ( + "context" + "testing" + + "github.com/ethereum-optimism/optimism/op-dispute-mon/config" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestMainShouldReturnErrorWhenConfigInvalid(t *testing.T) { + cfg := &config.Config{} + app, err := Main(context.Background(), testlog.Logger(t, log.LvlInfo), cfg) + require.ErrorIs(t, err, cfg.Check()) + require.Nil(t, app) +} diff --git a/op-dispute-mon/version/version.go b/op-dispute-mon/version/version.go new file mode 100644 index 000000000000..834fc089b19e --- /dev/null +++ b/op-dispute-mon/version/version.go @@ -0,0 +1,14 @@ +package version + +var ( + Version = "v0.1.0" + Meta = "dev" +) + +var SimpleWithMeta = func() string { + v := Version + if Meta != "" { + v += "-" + Meta + } + return v +}() diff --git a/op-e2e/Makefile b/op-e2e/Makefile index 5f92b5e458c0..5d1876dfb120 100644 --- a/op-e2e/Makefile +++ b/op-e2e/Makefile @@ -1,8 +1,8 @@ # Generally, JUNIT_FILE is set in CI but may be specified to an arbitrary file location to emulate CI locally ifdef JUNIT_FILE - go_test = OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=false gotestsum --format=standard-verbose --junitfile=$(JUNIT_FILE) -- + go_test = OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=false gotestsum --format=standard-verbose --junitfile=$(JUNIT_FILE) -- -failfast # Note: -parallel must be set to match the number of cores in the resource class - go_test_flags = -timeout=20m -parallel=8 + go_test_flags = -timeout=60m -parallel=8 else go_test = go test go_test_flags = -v @@ -16,12 +16,24 @@ test-external-%: pre-test $(go_test) $(go_test_flags) --externalL2 ./external_$*/ test-ws: pre-test - $(go_test) $(go_test_flags) ./... + $(go_test) $(go_test_flags) . ./e2eutils/... .PHONY: test-ws +test-actions: pre-test + $(go_test) $(go_test_flags) ./actions +.PHONY: test-actions + test-http: pre-test - OP_E2E_USE_HTTP=true $(go_test) $(go_test_flags) ./... -.PHONY: test-ws + OP_E2E_USE_HTTP=true $(go_test) $(go_test_flags) . ./e2eutils/... +.PHONY: test-http + +test-cannon: pre-test + OP_E2E_CANNON_ENABLED=true $(go_test) $(go_test_flags) ./faultproofs +.PHONY: test-cannon + +test-fault-proofs: pre-test + $(go_test) $(go_test_flags) ./faultproofs +.PHONY: test-faultproofs cannon-prestate: make -C .. cannon-prestate diff --git a/op-e2e/README.md b/op-e2e/README.md index c64024f1be5d..28fdb06dad1b 100644 --- a/op-e2e/README.md +++ b/op-e2e/README.md @@ -19,3 +19,16 @@ runtime, but others cannot be changed or else it will result in broken tests. Any changes to `devnetL1.json` should result in rebuilding the `.devnet` artifacts before the new values will be present in the `op-e2e` tests. + +## Running tests +Consult the [Makefile](./Makefile) in this directory. Run, e.g.: + +```bash +make test-http +``` + +### Troubleshooting +If you encounter errors: +* ensure you have the latest version of foundry installed: `pnpm update:foundry` +* try deleting the `packages/contracts-bedrock/forge-artifacts` directory +* if the above step doesn't fix the error, try `pnpm clean` diff --git a/op-e2e/actions/action.go b/op-e2e/actions/action.go index 53b710a44e21..551ab58d9632 100644 --- a/op-e2e/actions/action.go +++ b/op-e2e/actions/action.go @@ -2,26 +2,12 @@ package actions import ( "context" - "os" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" ) -var enableParallelTesting bool = true - -func init() { - if os.Getenv("OP_E2E_DISABLE_PARALLEL") == "true" { - enableParallelTesting = false - } -} - -func parallel(t e2eutils.TestingBase) { - t.Helper() - if enableParallelTesting { - t.Parallel() - } -} - // Testing is an interface to Go-like testing, // extended with a context getter for the test runner to shut down individual actions without interrupting the test, // and a signaling function for when an invalid action is hit. @@ -69,7 +55,8 @@ type StatefulTesting interface { // NewDefaultTesting returns a new testing obj, and enables parallel test execution. // Returns an interface, we're likely changing the behavior here as we build more action tests. func NewDefaultTesting(tb e2eutils.TestingBase) StatefulTesting { - parallel(tb) + op_e2e.InitParallel(tb) + return &defaultTesting{ TestingBase: tb, ctx: context.Background(), diff --git a/op-e2e/actions/blocktime_test.go b/op-e2e/actions/blocktime_test.go index 2f3cf8d46381..90a38be9a337 100644 --- a/op-e2e/actions/blocktime_test.go +++ b/op-e2e/actions/blocktime_test.go @@ -6,25 +6,52 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" ) -// TestBatchInLastPossibleBlocks tests that the derivation pipeline +// TestBlockTimeBatchType run each blocktime-related test case in singular batch mode and span batch mode. +func TestBlockTimeBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, deltaTimeOffset *hexutil.Uint64) + }{ + {"BatchInLastPossibleBlocks", BatchInLastPossibleBlocks}, + {"LargeL1Gaps", LargeL1Gaps}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + deltaTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &deltaTimeOffset) + }) + } +} + +// BatchInLastPossibleBlocks tests that the derivation pipeline // accepts a batch that is included in the last possible L1 block // where there are also no other batches included in the sequence // window. // This is a regression test against the bug fixed in PR #4566 -func TestBatchInLastPossibleBlocks(gt *testing.T) { +func BatchInLastPossibleBlocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + applyDeltaTimeOffset(dp, deltaTimeOffset) dp.DeployConfig.SequencerWindowSize = 4 dp.DeployConfig.L2BlockTime = 2 sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) sd, _, miner, sequencer, sequencerEngine, _, _, batcher := setupReorgTestActors(t, dp, sd, log) @@ -116,7 +143,7 @@ func TestBatchInLastPossibleBlocks(gt *testing.T) { verifyChainStateOnSequencer(12, 23, 11, 17, 8) } -// TestLargeL1Gaps tests the case that there is a gap between two L1 blocks which +// LargeL1Gaps tests the case that there is a gap between two L1 blocks which // is larger than the sequencer drift. // This test has the following parameters: // L1 Block time: 4s. L2 Block time: 2s. Sequencer Drift: 32s @@ -127,15 +154,16 @@ func TestBatchInLastPossibleBlocks(gt *testing.T) { // Then it generates 3 more L1 blocks. // At this point it can verify that the batches where properly generated. // Note: It batches submits when possible. -func TestLargeL1Gaps(gt *testing.T) { +func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp.DeployConfig.L1BlockTime = 4 dp.DeployConfig.L2BlockTime = 2 dp.DeployConfig.SequencerWindowSize = 4 dp.DeployConfig.MaxSequencerDrift = 32 + applyDeltaTimeOffset(dp, deltaTimeOffset) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) sd, _, miner, sequencer, sequencerEngine, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) diff --git a/op-e2e/actions/dencun_fork_test.go b/op-e2e/actions/dencun_fork_test.go new file mode 100644 index 000000000000..5e0f1706cb31 --- /dev/null +++ b/op-e2e/actions/dencun_fork_test.go @@ -0,0 +1,259 @@ +package actions + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "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" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" + "github.com/ethereum-optimism/optimism/op-service/testlog" +) + +func TestDencunL1ForkAfterGenesis(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + offset := hexutil.Uint64(24) + dp.DeployConfig.L1CancunTimeOffset = &offset + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelDebug) + _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + + l1Head := miner.l1Chain.CurrentBlock() + require.False(t, sd.L1Cfg.Config.IsCancun(l1Head.Number, l1Head.Time), "Cancun not active yet") + require.Nil(t, l1Head.ExcessBlobGas, "Cancun blob gas not in header") + + // start op-nodes + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // build empty L1 blocks, crossing the fork boundary + miner.ActL1SetFeeRecipient(common.Address{'A', 0}) + miner.ActEmptyBlock(t) + miner.ActEmptyBlock(t) // Cancun activates here + miner.ActEmptyBlock(t) + // verify Cancun is active + l1Head = miner.l1Chain.CurrentBlock() + require.True(t, sd.L1Cfg.Config.IsCancun(l1Head.Number, l1Head.Time), "Cancun active") + require.NotNil(t, l1Head.ExcessBlobGas, "Cancun blob gas in header") + + // build L2 chain up to and including L2 blocks referencing Cancun L1 blocks + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + miner.ActL1StartBlock(12)(t) + batcher.ActSubmitAll(t) + miner.ActL1IncludeTx(batcher.batcherAddr)(t) + miner.ActL1EndBlock(t) + + // sync verifier + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + // verify verifier accepted Cancun L1 inputs + require.Equal(t, l1Head.Hash(), verifier.SyncStatus().SafeL2.L1Origin.Hash, "verifier synced L1 chain that includes Cancun headers") + require.Equal(t, sequencer.SyncStatus().UnsafeL2, verifier.SyncStatus().UnsafeL2, "verifier and sequencer agree") +} + +func TestDencunL1ForkAtGenesis(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + offset := hexutil.Uint64(0) + dp.DeployConfig.L1CancunTimeOffset = &offset + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelDebug) + _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + + l1Head := miner.l1Chain.CurrentBlock() + require.True(t, sd.L1Cfg.Config.IsCancun(l1Head.Number, l1Head.Time), "Cancun active at genesis") + require.NotNil(t, l1Head.ExcessBlobGas, "Cancun blob gas in header") + + // start op-nodes + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // build empty L1 blocks + miner.ActL1SetFeeRecipient(common.Address{'A', 0}) + miner.ActEmptyBlock(t) + miner.ActEmptyBlock(t) + + // verify Cancun is still active + l1Head = miner.l1Chain.CurrentBlock() + require.True(t, sd.L1Cfg.Config.IsCancun(l1Head.Number, l1Head.Time), "Cancun active") + require.NotNil(t, l1Head.ExcessBlobGas, "Cancun blob gas in header") + + // build L2 chain + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + miner.ActL1StartBlock(12)(t) + batcher.ActSubmitAll(t) + miner.ActL1IncludeTx(batcher.batcherAddr)(t) + miner.ActL1EndBlock(t) + + // sync verifier + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + // verify verifier accepted Cancun L1 inputs + require.Equal(t, l1Head.Hash(), verifier.SyncStatus().SafeL2.L1Origin.Hash, "verifier synced L1 chain that includes Cancun headers") + require.Equal(t, sequencer.SyncStatus().UnsafeL2, verifier.SyncStatus().UnsafeL2, "verifier and sequencer agree") +} + +func verifyPreEcotoneBlock(gt *testing.T, header *types.Header) { + require.Nil(gt, header.ParentBeaconRoot) + require.Nil(gt, header.ExcessBlobGas) + require.Nil(gt, header.BlobGasUsed) +} + +func verifyEcotoneBlock(gt *testing.T, header *types.Header) { + require.NotNil(gt, header.ParentBeaconRoot) + require.NotNil(gt, header.ExcessBlobGas) + require.Equal(gt, *header.ExcessBlobGas, uint64(0)) + require.NotNil(gt, header.BlobGasUsed) + require.Equal(gt, *header.BlobGasUsed, uint64(0)) +} + +func TestDencunL2ForkAfterGenesis(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + + cancunOffset := hexutil.Uint64(0) + dp.DeployConfig.L1CancunTimeOffset = &cancunOffset + // This test wil fork on the second block + offset := hexutil.Uint64(dp.DeployConfig.L2BlockTime * 2) + dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset + dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset + + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelDebug) + _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) + + // start op-nodes + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Genesis block is pre-ecotone + verifyPreEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + + // Block before fork block + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + verifyPreEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + + // Fork block is ecotone + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + + // Blocks post fork have Ecotone properties + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) +} + +func TestDencunL2ForkAtGenesis(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + offset := hexutil.Uint64(0) + dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset + dp.DeployConfig.L1CancunTimeOffset = &offset + dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset + dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset + + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelDebug) + _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) + + // start op-nodes + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Genesis block has ecotone properties + verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + + // Blocks post fork have Ecotone properties + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) +} + +func aliceSimpleBlobTx(t Testing, dp *e2eutils.DeployParams) *types.Transaction { + txData := transactions.CreateEmptyBlobTx(true, dp.DeployConfig.L2ChainID) + // Manual signer creation, so we can sign a blob tx on the chain, + // even though we have disabled cancun signer support in Ecotone. + signer := types.NewCancunSigner(txData.ChainID.ToBig()) + tx, err := types.SignNewTx(dp.Secrets.Alice, signer, txData) + require.NoError(t, err, "must sign tx") + return tx +} + +func newEngine(t Testing, sd *e2eutils.SetupData, log log.Logger) *L2Engine { + jwtPath := e2eutils.WriteDefaultJWT(t) + return NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) +} + +// TestDencunBlobTxRPC tries to send a Blob tx to the L2 engine via RPC, it should not be accepted. +func TestDencunBlobTxRPC(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + offset := hexutil.Uint64(0) + dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset + dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset + dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset + + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelDebug) + engine := newEngine(t, sd, log) + cl := engine.EthClient() + tx := aliceSimpleBlobTx(t, dp) + err := cl.SendTransaction(context.Background(), tx) + require.ErrorContains(t, err, "transaction type not supported") +} + +// TestDencunBlobTxInTxPool tries to insert a blob tx directly into the tx pool, it should not be accepted. +func TestDencunBlobTxInTxPool(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + offset := hexutil.Uint64(0) + dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset + dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset + dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset + + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelDebug) + engine := newEngine(t, sd, log) + tx := aliceSimpleBlobTx(t, dp) + errs := engine.eth.TxPool().Add([]*types.Transaction{tx}, true, true) + require.ErrorContains(t, errs[0], "transaction type not supported") +} + +// TestDencunBlobTxInclusion tries to send a Blob tx to the L2 engine, it should not be accepted. +func TestDencunBlobTxInclusion(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + offset := hexutil.Uint64(0) + dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset + dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset + dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset + + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelDebug) + + _, engine, sequencer := setupSequencerTest(t, sd, log) + sequencer.ActL2PipelineFull(t) + + tx := aliceSimpleBlobTx(t, dp) + + sequencer.ActL2StartBlock(t) + err := engine.engineApi.IncludeTx(tx, dp.Addresses.Alice) + require.ErrorContains(t, err, "invalid L2 block (tx 1): failed to apply transaction to L2 block (tx 1): transaction type not supported") +} diff --git a/op-e2e/actions/ecotone_fork_test.go b/op-e2e/actions/ecotone_fork_test.go new file mode 100644 index 000000000000..4cadbdafce08 --- /dev/null +++ b/op-e2e/actions/ecotone_fork_test.go @@ -0,0 +1,259 @@ +package actions + +import ( + "context" + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "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/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/testlog" +) + +var ( + l1BlockCodeHash = common.HexToHash("0xc88a313aa75dc4fbf0b6850d9f9ae41e04243b7008cf3eadb29256d4a71c1dfd") + gasPriceOracleCodeHash = common.HexToHash("0x8b71360ea773b4cfaf1ae6d2bd15464a4e1e2e360f786e475f63aeaed8da0ae5") +) + +// verifyCodeHashMatches checks that the has of the code at the given address matches the expected code-hash. +// It also sanity-checks that the code is not empty: we should never deploy empty contract codes. +// Returns the contract code +func verifyCodeHashMatches(t Testing, client *ethclient.Client, address common.Address, expectedCodeHash common.Hash) []byte { + code, err := client.CodeAt(context.Background(), address, nil) + require.NoError(t, err) + require.NotEmpty(t, code) + codeHash := crypto.Keccak256Hash(code) + require.Equal(t, expectedCodeHash, codeHash) + return code +} + +func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + genesisBlock := hexutil.Uint64(0) + ecotoneOffset := hexutil.Uint64(2) + + dp.DeployConfig.L1CancunTimeOffset = &genesisBlock // can be removed once Cancun on L1 is the default + + // Activate all forks at genesis, and schedule Ecotone the block after + dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &ecotoneOffset + require.NoError(t, dp.DeployConfig.Check(), "must have valid config") + + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelDebug) + _, _, miner, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) + ethCl := engine.EthClient() + + // start op-nodes + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Get gas price from oracle + gasPriceOracle, err := bindings.NewGasPriceOracleCaller(predeploys.GasPriceOracleAddr, ethCl) + require.NoError(t, err) + + scalar, err := gasPriceOracle.Scalar(nil) + require.NoError(t, err) + require.True(t, scalar.Cmp(big.NewInt(0)) > 0, "scalar must start non-zero") + require.True(t, scalar.Cmp(new(big.Int).SetUint64(dp.DeployConfig.GasPriceOracleScalar)) == 0, "must match deploy config") + + // Get current implementations addresses (by slot) for L1Block + GasPriceOracle + initialGasPriceOracleAddress, err := ethCl.StorageAt(context.Background(), predeploys.GasPriceOracleAddr, genesis.ImplementationSlot, nil) + require.NoError(t, err) + initialL1BlockAddress, err := ethCl.StorageAt(context.Background(), predeploys.L1BlockAddr, genesis.ImplementationSlot, nil) + require.NoError(t, err) + + // Build to the ecotone block + sequencer.ActBuildL2ToEcotone(t) + + // get latest block + latestBlock, err := ethCl.BlockByNumber(context.Background(), nil) + require.NoError(t, err) + require.Equal(t, sequencer.L2Unsafe().Number, latestBlock.Number().Uint64()) + + transactions := latestBlock.Transactions() + // L1Block: 1 set-L1-info + 2 deploys + 2 upgradeTo + 1 enable ecotone on GPO + 1 4788 deploy + // See [derive.EcotoneNetworkUpgradeTransactions] + require.Equal(t, 7, len(transactions)) + + l1Info, err := derive.L1BlockInfoFromBytes(sd.RollupCfg, latestBlock.Time(), transactions[0].Data()) + require.NoError(t, err) + require.Equal(t, derive.L1InfoBedrockLen, len(transactions[0].Data())) + require.Nil(t, l1Info.BlobBaseFee) + + // All transactions are successful + for i := 1; i < 7; i++ { + txn := transactions[i] + receipt, err := ethCl.TransactionReceipt(context.Background(), txn.Hash()) + require.NoError(t, err) + require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) + require.NotEmpty(t, txn.Data(), "upgrade tx must provide input data") + } + + expectedL1BlockAddress := crypto.CreateAddress(derive.L1BlockDeployerAddress, 0) + expectedGasPriceOracleAddress := crypto.CreateAddress(derive.GasPriceOracleDeployerAddress, 0) + + // Gas Price Oracle Proxy is updated + updatedGasPriceOracleAddress, err := ethCl.StorageAt(context.Background(), predeploys.GasPriceOracleAddr, genesis.ImplementationSlot, latestBlock.Number()) + require.NoError(t, err) + require.Equal(t, expectedGasPriceOracleAddress, common.BytesToAddress(updatedGasPriceOracleAddress)) + require.NotEqualf(t, initialGasPriceOracleAddress, updatedGasPriceOracleAddress, "Gas Price Oracle Proxy address should have changed") + verifyCodeHashMatches(t, ethCl, expectedGasPriceOracleAddress, gasPriceOracleCodeHash) + + // L1Block Proxy is updated + updatedL1BlockAddress, err := ethCl.StorageAt(context.Background(), predeploys.L1BlockAddr, genesis.ImplementationSlot, latestBlock.Number()) + require.NoError(t, err) + require.Equal(t, expectedL1BlockAddress, common.BytesToAddress(updatedL1BlockAddress)) + require.NotEqualf(t, initialL1BlockAddress, updatedL1BlockAddress, "L1Block Proxy address should have changed") + verifyCodeHashMatches(t, ethCl, expectedL1BlockAddress, l1BlockCodeHash) + + _, err = gasPriceOracle.Scalar(nil) + require.ErrorContains(t, err, "scalar() is deprecated") + + cost, err := gasPriceOracle.GetL1Fee(nil, []byte{0, 1, 2, 3, 4}) + require.NoError(t, err) + // The L1 info tx does not get included until after the Ecotone upgrade. + // The scalars are thus empty during activation, and only deposits are included, so the L1 fee is unused. + require.True(t, cost.IsUint64()) + require.Equal(t, cost.Uint64(), uint64(0), "expecting zero scalars within activation block") + + // Check that Ecotone was activated + isEcotone, err := gasPriceOracle.IsEcotone(nil) + require.NoError(t, err) + require.True(t, isEcotone) + + // 4788 contract is deployed + expected4788Address := crypto.CreateAddress(derive.EIP4788From, 0) + require.Equal(t, predeploys.EIP4788ContractAddr, expected4788Address) + code := verifyCodeHashMatches(t, ethCl, predeploys.EIP4788ContractAddr, predeploys.EIP4788ContractCodeHash) + require.Equal(t, predeploys.EIP4788ContractCode, code) + // Test that the beacon-block-root has been set + checkBeaconBlockRoot := func(timestamp uint64, expectedHash common.Hash, expectedTime uint64, msg string) { + historyBufferLength := uint64(8191) + rootIdx := common.BigToHash(new(big.Int).SetUint64((timestamp % historyBufferLength) + historyBufferLength)) + timeIdx := common.BigToHash(new(big.Int).SetUint64(timestamp % historyBufferLength)) + + rootValue, err := ethCl.StorageAt(context.Background(), predeploys.EIP4788ContractAddr, rootIdx, nil) + require.NoError(t, err) + require.Equal(t, expectedHash, common.BytesToHash(rootValue), msg) + + timeValue, err := ethCl.StorageAt(context.Background(), predeploys.EIP4788ContractAddr, timeIdx, nil) + require.NoError(t, err) + timeBig := new(big.Int).SetBytes(timeValue) + require.True(t, timeBig.IsUint64()) + require.Equal(t, expectedTime, timeBig.Uint64(), msg) + } + // The header will always have the beacon-block-root, at the very start. + require.NotNil(t, latestBlock.BeaconRoot()) + require.Equal(t, *latestBlock.BeaconRoot(), common.Hash{}, + "L1 genesis block has zeroed parent-beacon-block-root, since it has no parent block, and that propagates into L2") + // The first block is an exception in upgrade-networks, + // since the beacon-block root contract isn't there at Ecotone activation, + // and the beacon-block-root insertion is processed at the start of the block before deposit txs. + // If the contract was permissionlessly deployed before, the contract storage will be updated however. + checkBeaconBlockRoot(latestBlock.Time(), common.Hash{}, 0, "ecotone activation block has no data yet (since contract wasn't there)") + + // Build empty L2 block, to pass ecotone activation + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + + // Test the L2 block after activation: it should have data in the contract storage now + latestBlock, err = ethCl.BlockByNumber(context.Background(), nil) + require.NoError(t, err) + require.NotNil(t, latestBlock.BeaconRoot()) + firstBeaconBlockRoot := *latestBlock.BeaconRoot() + checkBeaconBlockRoot(latestBlock.Time(), *latestBlock.BeaconRoot(), latestBlock.Time(), "post-activation") + + // require.again, now that we are past activation + _, err = gasPriceOracle.Scalar(nil) + require.ErrorContains(t, err, "scalar() is deprecated") + + // test if the migrated scalar matches the deploy config + basefeeScalar, err := gasPriceOracle.BaseFeeScalar(nil) + require.NoError(t, err) + require.True(t, uint64(basefeeScalar) == dp.DeployConfig.GasPriceOracleScalar, "must match deploy config") + + cost, err = gasPriceOracle.GetL1Fee(nil, []byte{0, 1, 2, 3, 4}) + require.NoError(t, err) + // The GPO getL1Fee contract returns the L1 fee with approximate signature overhead pre-included, + // like the pre-regolith L1 fee. We do the full fee check below. Just sanity check it is not zero anymore first. + require.Greater(t, cost.Uint64(), uint64(0), "expecting non-zero scalars after activation block") + + // Get L1Block info + l1Block, err := bindings.NewL1BlockCaller(predeploys.L1BlockAddr, ethCl) + require.NoError(t, err) + l1BlockInfo, err := l1Block.Timestamp(nil) + require.NoError(t, err) + require.Greater(t, l1BlockInfo, uint64(0)) + + l1OriginBlock, err := miner.EthClient().BlockByHash(context.Background(), sequencer.L2Unsafe().L1Origin.Hash) + require.NoError(t, err) + l1Basefee, err := l1Block.Basefee(nil) + require.NoError(t, err) + require.Equal(t, l1OriginBlock.BaseFee().Uint64(), l1Basefee.Uint64(), "basefee must match") + + // calldataGas*(l1BaseFee*16*l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar)/16e6 + // _getCalldataGas in GPO adds the cost of 68 non-zero bytes for signature/rlp overhead. + calldataGas := big.NewInt(4*16 + 1*4 + 68*16) + expectedL1Fee := new(big.Int).Mul(calldataGas, l1Basefee) + expectedL1Fee = expectedL1Fee.Mul(expectedL1Fee, big.NewInt(16)) + expectedL1Fee = expectedL1Fee.Mul(expectedL1Fee, new(big.Int).SetUint64(uint64(basefeeScalar))) + expectedL1Fee = expectedL1Fee.Div(expectedL1Fee, big.NewInt(16e6)) + require.Equal(t, expectedL1Fee, cost, "expecting cost based on regular base fee scalar alone") + + // build forward, incorporate new L1 data + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + + // Contract storage should be updated now, different than before + latestBlock, err = ethCl.BlockByNumber(context.Background(), nil) + require.NoError(t, err) + require.NotNil(t, latestBlock.BeaconRoot()) + require.NotEqual(t, firstBeaconBlockRoot, *latestBlock.BeaconRoot()) + checkBeaconBlockRoot(latestBlock.Time(), *latestBlock.BeaconRoot(), latestBlock.Time(), "updates on new L1 data") +} + +// TestEcotoneBeforeL1 tests that the L2 Ecotone fork can activate before L1 Dencun does +func TestEcotoneBeforeL1(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + offset := hexutil.Uint64(0) + farOffset := hexutil.Uint64(10000) + dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset + dp.DeployConfig.L1CancunTimeOffset = &farOffset // L1 Dencun will not be active at genesis + dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset + dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset + + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelDebug) + _, _, _, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) + + // start op-nodes + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Genesis block has ecotone properties + verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) + + // Blocks post fork have Ecotone properties + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + verifyEcotoneBlock(gt, engine.l2Chain.CurrentBlock()) +} diff --git a/op-e2e/actions/eip4844_test.go b/op-e2e/actions/eip4844_test.go new file mode 100644 index 000000000000..ddab21d48b47 --- /dev/null +++ b/op-e2e/actions/eip4844_test.go @@ -0,0 +1,185 @@ +package actions + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "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" + + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + "github.com/ethereum-optimism/optimism/op-service/testlog" +) + +func setupEIP4844Test(t Testing, log log.Logger) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine) { + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + genesisActivation := hexutil.Uint64(0) + dp.DeployConfig.L1CancunTimeOffset = &genesisActivation + dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisActivation + dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisActivation + dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisActivation + + sd := e2eutils.Setup(t, dp, defaultAlloc) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + miner.ActL1SetFeeRecipient(common.Address{'A'}) + sequencer.ActL2PipelineFull(t) + verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + return sd, dp, miner, sequencer, seqEngine, verifier, verifEngine +} + +func setupBatcher(t Testing, log log.Logger, sd *e2eutils.SetupData, dp *e2eutils.DeployParams, miner *L1Miner, + sequencer *L2Sequencer, engine *L2Engine, daType batcherFlags.DataAvailabilityType, +) *L2Batcher { + return NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + DataAvailabilityType: daType, + }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) +} + +func TestEIP4844DataAvailability(gt *testing.T) { + t := NewDefaultTesting(gt) + + log := testlog.Logger(t, log.LevelDebug) + sd, dp, miner, sequencer, seqEngine, verifier, _ := setupEIP4844Test(t, log) + + batcher := setupBatcher(t, log, sd, dp, miner, sequencer, seqEngine, batcherFlags.BlobsType) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // build empty L1 block + miner.ActEmptyBlock(t) + // finalize it, so the L1 geth blob pool doesn't log errors about missing finality + miner.ActL1SafeNext(t) + miner.ActL1FinalizeNext(t) + + // Create L2 blocks, and reference the L1 head as origin + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + + // submit all new L2 blocks + batcher.ActSubmitAll(t) + batchTx := batcher.LastSubmitted + require.Equal(t, uint8(types.BlobTxType), batchTx.Type(), "batch tx must be blob-tx") + + // new L1 block with L2 batch + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTxByHash(batchTx.Hash())(t) + miner.ActL1EndBlock(t) + + // verifier picks up the L2 chain that was submitted + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Safe(), sequencer.L2Unsafe(), "verifier syncs from sequencer via L1") + require.NotEqual(t, sequencer.L2Safe(), sequencer.L2Unsafe(), "sequencer has not processed L1 yet") +} + +func TestEIP4844MultiBlobs(gt *testing.T) { + t := NewDefaultTesting(gt) + + log := testlog.Logger(t, log.LevelDebug) + sd, dp, miner, sequencer, seqEngine, verifier, _ := setupEIP4844Test(t, log) + + batcher := setupBatcher(t, log, sd, dp, miner, sequencer, seqEngine, batcherFlags.BlobsType) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // build empty L1 block + miner.ActEmptyBlock(t) + // finalize it, so the L1 geth blob pool doesn't log errors about missing finality + miner.ActL1SafeNext(t) + miner.ActL1FinalizeNext(t) + + // Create L2 blocks, and reference the L1 head as origin + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + + // submit all new L2 blocks + batcher.ActSubmitAllMultiBlobs(t, 6) + batchTx := batcher.LastSubmitted + require.Equal(t, uint8(types.BlobTxType), batchTx.Type(), "batch tx must be blob-tx") + require.Len(t, batchTx.BlobTxSidecar().Blobs, 6) + + // new L1 block with L2 batch + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTxByHash(batchTx.Hash())(t) + miner.ActL1EndBlock(t) + + // verifier picks up the L2 chain that was submitted + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Safe(), sequencer.L2Unsafe(), "verifier syncs from sequencer via L1") + require.NotEqual(t, sequencer.L2Safe(), sequencer.L2Unsafe(), "sequencer has not processed L1 yet") +} + +func TestEIP4844DataAvailabilitySwitch(gt *testing.T) { + t := NewDefaultTesting(gt) + + log := testlog.Logger(t, log.LevelDebug) + sd, dp, miner, sequencer, seqEngine, verifier, _ := setupEIP4844Test(t, log) + + oldBatcher := setupBatcher(t, log, sd, dp, miner, sequencer, seqEngine, batcherFlags.CalldataType) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // build empty L1 block + miner.ActEmptyBlock(t) + // finalize it, so the L1 geth blob pool doesn't log errors about missing finality + miner.ActL1SafeNext(t) + miner.ActL1FinalizeNext(t) + + // Create L2 blocks, and reference the L1 head as origin + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + + // submit all new L2 blocks, with legacy calldata DA + oldBatcher.ActSubmitAll(t) + batchTx := oldBatcher.LastSubmitted + require.Equal(t, uint8(types.DynamicFeeTxType), batchTx.Type(), "batch tx must be eip1559 tx") + + // new L1 block with L2 batch + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTxByHash(batchTx.Hash())(t) + miner.ActL1EndBlock(t) + + // verifier picks up the L2 chain that was submitted + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Safe(), sequencer.L2Unsafe(), "verifier syncs from sequencer via L1") + require.NotEqual(t, sequencer.L2Safe(), sequencer.L2Unsafe(), "sequencer has not processed L1 yet") + + newBatcher := setupBatcher(t, log, sd, dp, miner, sequencer, seqEngine, batcherFlags.BlobsType) + + // build empty L1 block + miner.ActEmptyBlock(t) + + // Create L2 blocks, and reference the L1 head as origin + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + + // submit all new L2 blocks, now with Blobs DA! + newBatcher.ActSubmitAll(t) + batchTx = newBatcher.LastSubmitted + + // new L1 block with L2 batch + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTxByHash(batchTx.Hash())(t) + miner.ActL1EndBlock(t) + + require.Equal(t, uint8(types.BlobTxType), batchTx.Type(), "batch tx must be blob-tx") + + // verifier picks up the L2 chain that was submitted + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Safe(), sequencer.L2Unsafe(), "verifier syncs from sequencer via L1") + require.NotEqual(t, sequencer.L2Safe(), sequencer.L2Unsafe(), "sequencer has not processed L1 yet") +} diff --git a/op-e2e/actions/garbage_channel_out.go b/op-e2e/actions/garbage_channel_out.go index 34056abdf714..41a290570ea9 100644 --- a/op-e2e/actions/garbage_channel_out.go +++ b/op-e2e/actions/garbage_channel_out.go @@ -54,7 +54,7 @@ type Writer interface { type ChannelOutIface interface { ID() derive.ChannelID Reset() error - AddBlock(block *types.Block) (uint64, error) + AddBlock(rollupCfg *rollup.Config, block *types.Block) (uint64, error) ReadyBytes() int Flush() error Close() error @@ -138,11 +138,11 @@ func (co *GarbageChannelOut) Reset() error { // error that it returns is ErrTooManyRLPBytes. If this error // is returned, the channel should be closed and a new one // should be made. -func (co *GarbageChannelOut) AddBlock(block *types.Block) (uint64, error) { +func (co *GarbageChannelOut) AddBlock(rollupCfg *rollup.Config, block *types.Block) (uint64, error) { if co.closed { return 0, errors.New("already closed") } - batch, err := blockToBatch(block) + batch, err := blockToBatch(rollupCfg, block) if err != nil { return 0, err } @@ -207,10 +207,10 @@ func (co *GarbageChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) (uint1 // Fixed overhead: 32 + 8 + 2 + 4 + 1 = 47 bytes. // Add one extra byte for the version byte (for the entire L1 tx though) maxDataSize := maxSize - 47 - 1 - if maxDataSize > uint64(co.buf.Len()) { + if maxDataSize >= uint64(co.buf.Len()) { maxDataSize = uint64(co.buf.Len()) // If we are closed & will not spill past the current frame - // mark it is the final frame of the channel. + // mark it as the final frame of the channel. if co.closed { f.IsLast = true } @@ -234,7 +234,7 @@ func (co *GarbageChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) (uint1 } // blockToBatch transforms a block into a batch object that can easily be RLP encoded. -func blockToBatch(block *types.Block) (*derive.BatchData, error) { +func blockToBatch(rollupCfg *rollup.Config, block *types.Block) (*derive.BatchData, error) { opaqueTxs := make([]hexutil.Bytes, 0, len(block.Transactions())) for i, tx := range block.Transactions() { if tx.Type() == types.DepositTxType { @@ -250,7 +250,7 @@ func blockToBatch(block *types.Block) (*derive.BatchData, error) { if l1InfoTx.Type() != types.DepositTxType { return nil, derive.ErrNotDepositTx } - l1Info, err := derive.L1InfoDepositTxData(l1InfoTx.Data()) + l1Info, err := derive.L1BlockInfoFromBytes(rollupCfg, block.Time(), l1InfoTx.Data()) if err != nil { return nil, fmt.Errorf("could not parse the L1 Info deposit: %w", err) } diff --git a/op-e2e/actions/l1_miner.go b/op-e2e/actions/l1_miner.go index dac4f2f3f81a..66c365669387 100644 --- a/op-e2e/actions/l1_miner.go +++ b/op-e2e/actions/l1_miner.go @@ -3,20 +3,29 @@ package actions import ( "math/big" + "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/trie" - "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/eth" ) // L1Miner wraps a L1Replica with instrumented block building ability. type L1Miner struct { L1Replica + blobStore *e2eutils.BlobsStore + // L1 block building preferences prefCoinbase common.Address @@ -29,6 +38,8 @@ type L1Miner struct { l1Receipts []*types.Receipt // collect receipts of ongoing building l1Building bool l1TxFailed []*types.Transaction // log of failed transactions which could not be included + // sidecars that come with the transactions + l1BuildingBlobSidecars []*types.BlobTxSidecar } // NewL1Miner creates a new L1Replica that can also build blocks. @@ -36,6 +47,7 @@ func NewL1Miner(t Testing, log log.Logger, genesis *core.Genesis) *L1Miner { rep := NewL1Replica(t, log, genesis) return &L1Miner{ L1Replica: *rep, + blobStore: e2eutils.NewBlobStore(), } } @@ -46,6 +58,10 @@ func NewL1MinerWithPort(t Testing, log log.Logger, genesis *core.Genesis, port i } } +func (s *L1Miner) BlobStore() derive.L1BlobsFetcher { + return s.blobStore +} + // ActL1StartBlock returns an action to build a new L1 block on top of the head block, // with timeDelta added to the head block time. func (s *L1Miner) ActL1StartBlock(timeDelta uint64) Action { @@ -83,6 +99,12 @@ func (s *L1Miner) ActL1StartBlock(timeDelta uint64) Action { if s.l1Cfg.Config.IsShanghai(header.Number, header.Time) { header.WithdrawalsHash = &types.EmptyWithdrawalsHash } + if s.l1Cfg.Config.IsCancun(header.Number, header.Time) { + header.BlobGasUsed = new(uint64) + header.ExcessBlobGas = new(uint64) + root := crypto.Keccak256Hash([]byte("fake-beacon-block-root"), header.Number.Bytes()) + header.ParentBeaconRoot = &root + } s.l1Building = true s.l1BuildingHeader = header @@ -90,6 +112,7 @@ func (s *L1Miner) ActL1StartBlock(timeDelta uint64) Action { s.l1Receipts = make([]*types.Receipt, 0) s.l1Transactions = make([]*types.Transaction, 0) s.pendingIndices = make(map[common.Address]uint64) + s.l1BuildingBlobSidecars = make([]*types.BlobTxSidecar, 0) s.l1GasPool = new(core.GasPool).AddGas(header.GasLimit) } @@ -111,6 +134,22 @@ func (s *L1Miner) ActL1IncludeTx(from common.Address) Action { } } +// ActL1IncludeTxByHash tries to include a tx by tx-hash. +func (s *L1Miner) ActL1IncludeTxByHash(txHash common.Hash) Action { + return func(t Testing) { + if !s.l1Building { + t.InvalidAction("no tx inclusion when not building l1 block") + return + } + tx := s.eth.TxPool().Get(txHash) + require.NotNil(t, tx, "cannot find tx %s", txHash) + s.IncludeTx(t, tx) + from, err := s.l1Signer.Sender(tx) + require.NoError(t, err) + s.pendingIndices[from] = s.pendingIndices[from] + 1 // won't retry the tx + } +} + func (s *L1Miner) IncludeTx(t Testing, tx *types.Transaction) { from, err := s.l1Signer.Sender(tx) require.NoError(t, err) @@ -124,13 +163,21 @@ func (s *L1Miner) IncludeTx(t Testing, tx *types.Transaction) { } s.l1BuildingState.SetTxContext(tx.Hash(), len(s.l1Transactions)) receipt, err := core.ApplyTransaction(s.l1Cfg.Config, s.l1Chain, &s.l1BuildingHeader.Coinbase, - s.l1GasPool, s.l1BuildingState, s.l1BuildingHeader, tx, &s.l1BuildingHeader.GasUsed, *s.l1Chain.GetVMConfig()) + s.l1GasPool, s.l1BuildingState, s.l1BuildingHeader, tx.WithoutBlobTxSidecar(), &s.l1BuildingHeader.GasUsed, *s.l1Chain.GetVMConfig()) if err != nil { s.l1TxFailed = append(s.l1TxFailed, tx) t.Fatalf("failed to apply transaction to L1 block (tx %d): %v", len(s.l1Transactions), err) } s.l1Receipts = append(s.l1Receipts, receipt) - s.l1Transactions = append(s.l1Transactions, tx) + s.l1Transactions = append(s.l1Transactions, tx.WithoutBlobTxSidecar()) + if tx.Type() == types.BlobTxType { + require.True(t, s.l1Cfg.Config.IsCancun(s.l1BuildingHeader.Number, s.l1BuildingHeader.Time), "L1 must be cancun to process blob tx") + sidecar := tx.BlobTxSidecar() + if sidecar != nil { + s.l1BuildingBlobSidecars = append(s.l1BuildingBlobSidecars, sidecar) + } + *s.l1BuildingHeader.BlobGasUsed += receipt.BlobGasUsed + } } func (s *L1Miner) ActL1SetFeeRecipient(coinbase common.Address) { @@ -154,6 +201,19 @@ func (s *L1Miner) ActL1EndBlock(t Testing) { if s.l1Cfg.Config.IsShanghai(s.l1BuildingHeader.Number, s.l1BuildingHeader.Time) { block = block.WithWithdrawals(make([]*types.Withdrawal, 0)) } + if s.l1Cfg.Config.IsCancun(s.l1BuildingHeader.Number, s.l1BuildingHeader.Time) { + parent := s.l1Chain.GetHeaderByHash(s.l1BuildingHeader.ParentHash) + var ( + parentExcessBlobGas uint64 + parentBlobGasUsed uint64 + ) + if parent.ExcessBlobGas != nil { + parentExcessBlobGas = *parent.ExcessBlobGas + parentBlobGasUsed = *parent.BlobGasUsed + } + excessBlobGas := eip4844.CalcExcessBlobGas(parentExcessBlobGas, parentBlobGasUsed) + s.l1BuildingHeader.ExcessBlobGas = &excessBlobGas + } // Write state changes to db root, err := s.l1BuildingState.Commit(s.l1BuildingHeader.Number.Uint64(), s.l1Cfg.Config.IsEIP158(s.l1BuildingHeader.Number)) @@ -163,7 +223,13 @@ func (s *L1Miner) ActL1EndBlock(t Testing) { if err := s.l1BuildingState.Database().TrieDB().Commit(root, false); err != nil { t.Fatalf("l1 trie write error: %v", err) } - + // now that the blob txs are in a canonical block, flush them to the blob store + for _, sidecar := range s.l1BuildingBlobSidecars { + for i, h := range sidecar.BlobHashes() { + blob := (*eth.Blob)(&sidecar.Blobs[i]) + s.blobStore.StoreBlob(block.Hash(), h, blob) + } + } _, err = s.l1Chain.InsertChain(types.Blocks{block}) if err != nil { t.Fatalf("failed to insert block into l1 chain") diff --git a/op-e2e/actions/l1_miner_test.go b/op-e2e/actions/l1_miner_test.go index b149cfd778c3..10e4c0c5498c 100644 --- a/op-e2e/actions/l1_miner_test.go +++ b/op-e2e/actions/l1_miner_test.go @@ -17,7 +17,7 @@ func TestL1Miner_BuildBlock(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner := NewL1Miner(t, log, sd.L1Cfg) t.Cleanup(func() { _ = miner.Close() diff --git a/op-e2e/actions/l1_replica.go b/op-e2e/actions/l1_replica.go index e137a1778c2b..a531218df3c7 100644 --- a/op-e2e/actions/l1_replica.go +++ b/op-e2e/actions/l1_replica.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/txpool/blobpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/ethconfig" @@ -51,6 +52,11 @@ func NewL1Replica(t Testing, log log.Logger, genesis *core.Genesis) *L1Replica { NetworkId: genesis.Config.ChainID.Uint64(), Genesis: genesis, RollupDisableTxPoolGossip: true, + BlobPool: blobpool.Config{ + Datadir: t.TempDir(), + Datacap: blobpool.DefaultConfig.Datacap, + PriceBump: blobpool.DefaultConfig.PriceBump, + }, } nodeCfg := &node.Config{ Name: "l1-geth", diff --git a/op-e2e/actions/l1_replica_test.go b/op-e2e/actions/l1_replica_test.go index fa12159f7ea6..7e9b65cfac86 100644 --- a/op-e2e/actions/l1_replica_test.go +++ b/op-e2e/actions/l1_replica_test.go @@ -34,7 +34,7 @@ func TestL1Replica_ActL1RPCFail(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) replica := NewL1Replica(t, log, sd.L1Cfg) t.Cleanup(func() { _ = replica.Close() @@ -56,7 +56,7 @@ func TestL1Replica_ActL1Sync(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) genesisBlock := sd.L1Cfg.ToBlock() consensus := beacon.New(ethash.NewFaker()) db := rawdb.NewMemoryDatabase() diff --git a/op-e2e/actions/l2_batcher.go b/op-e2e/actions/l2_batcher.go index 7431e7985bda..908eb9b4f6b3 100644 --- a/op-e2e/actions/l2_batcher.go +++ b/op-e2e/actions/l2_batcher.go @@ -8,18 +8,26 @@ import ( "io" "math/big" + "github.com/holiman/uint256" + "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - "github.com/stretchr/testify/require" + "github.com/ethereum-optimism/optimism/op-batcher/batcher" "github.com/ethereum-optimism/optimism/op-batcher/compressor" + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + plasma "github.com/ethereum-optimism/optimism/op-plasma" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/txmgr" ) type SyncStatusAPI interface { @@ -36,6 +44,10 @@ type L1TxAPI interface { SendTransaction(ctx context.Context, tx *types.Transaction) error } +type PlasmaInputSetter interface { + SetInput(ctx context.Context, img []byte) (plasma.Keccak256Commitment, error) +} + type BatcherCfg struct { // Limit the size of txs MinL1TxSize uint64 @@ -44,6 +56,37 @@ type BatcherCfg struct { BatcherKey *ecdsa.PrivateKey GarbageCfg *GarbageChannelCfg + + ForceSubmitSingularBatch bool + ForceSubmitSpanBatch bool + UsePlasma bool + + DataAvailabilityType batcherFlags.DataAvailabilityType + PlasmaDA PlasmaInputSetter +} + +func DefaultBatcherCfg(dp *e2eutils.DeployParams) *BatcherCfg { + return &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + DataAvailabilityType: batcherFlags.CalldataType, + } +} + +func PlasmaBatcherCfg(dp *e2eutils.DeployParams, plasmaDa PlasmaInputSetter) *BatcherCfg { + return &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + DataAvailabilityType: batcherFlags.CalldataType, + PlasmaDA: plasmaDa, + UsePlasma: true, + } +} + +type L2BlockRefs interface { + L2BlockRefByHash(ctx context.Context, hash common.Hash) (eth.L2BlockRef, error) } // L2Batcher buffers and submits L2 batches to L1. @@ -59,24 +102,28 @@ type L2Batcher struct { syncStatusAPI SyncStatusAPI l2 BlocksAPI l1 L1TxAPI + engCl L2BlockRefs l1Signer types.Signer l2ChannelOut ChannelOutIface l2Submitting bool // when the channel out is being submitted, and not safe to write to without resetting - l2BufferedBlock eth.BlockID - l2SubmittedBlock eth.BlockID + l2BufferedBlock eth.L2BlockRef + l2SubmittedBlock eth.L2BlockRef l2BatcherCfg *BatcherCfg batcherAddr common.Address + + LastSubmitted *types.Transaction } -func NewL2Batcher(log log.Logger, rollupCfg *rollup.Config, batcherCfg *BatcherCfg, api SyncStatusAPI, l1 L1TxAPI, l2 BlocksAPI) *L2Batcher { +func NewL2Batcher(log log.Logger, rollupCfg *rollup.Config, batcherCfg *BatcherCfg, api SyncStatusAPI, l1 L1TxAPI, l2 BlocksAPI, engCl L2BlockRefs) *L2Batcher { return &L2Batcher{ log: log, rollupCfg: rollupCfg, syncStatusAPI: api, l1: l1, l2: l2, + engCl: engCl, l2BatcherCfg: batcherCfg, l1Signer: types.LatestSignerForChainID(rollupCfg.L1ChainID), batcherAddr: crypto.PubkeyToAddress(batcherCfg.BatcherKey.PublicKey), @@ -103,31 +150,39 @@ func (s *L2Batcher) Buffer(t Testing) error { syncStatus, err := s.syncStatusAPI.SyncStatus(t.Ctx()) require.NoError(t, err, "no sync status error") // If we just started, start at safe-head - if s.l2SubmittedBlock == (eth.BlockID{}) { + if s.l2SubmittedBlock == (eth.L2BlockRef{}) { s.log.Info("Starting batch-submitter work at safe-head", "safe", syncStatus.SafeL2) - s.l2SubmittedBlock = syncStatus.SafeL2.ID() - s.l2BufferedBlock = syncStatus.SafeL2.ID() + s.l2SubmittedBlock = syncStatus.SafeL2 + s.l2BufferedBlock = syncStatus.SafeL2 s.l2ChannelOut = nil } // If it's lagging behind, catch it up. if s.l2SubmittedBlock.Number < syncStatus.SafeL2.Number { s.log.Warn("last submitted block lagged behind L2 safe head: batch submission will continue from the safe head now", "last", s.l2SubmittedBlock, "safe", syncStatus.SafeL2) - s.l2SubmittedBlock = syncStatus.SafeL2.ID() - s.l2BufferedBlock = syncStatus.SafeL2.ID() + s.l2SubmittedBlock = syncStatus.SafeL2 + s.l2BufferedBlock = syncStatus.SafeL2 s.l2ChannelOut = nil } // Add the next unsafe block to the channel if s.l2BufferedBlock.Number >= syncStatus.UnsafeL2.Number { if s.l2BufferedBlock.Number > syncStatus.UnsafeL2.Number || s.l2BufferedBlock.Hash != syncStatus.UnsafeL2.Hash { s.log.Error("detected a reorg in L2 chain vs previous buffered information, resetting to safe head now", "safe_head", syncStatus.SafeL2) - s.l2SubmittedBlock = syncStatus.SafeL2.ID() - s.l2BufferedBlock = syncStatus.SafeL2.ID() + s.l2SubmittedBlock = syncStatus.SafeL2 + s.l2BufferedBlock = syncStatus.SafeL2 s.l2ChannelOut = nil } else { s.log.Info("nothing left to submit") return nil } } + block, err := s.l2.BlockByNumber(t.Ctx(), big.NewInt(int64(s.l2BufferedBlock.Number+1))) + require.NoError(t, err, "need l2 block %d from sync status", s.l2SubmittedBlock.Number+1) + if block.ParentHash() != s.l2BufferedBlock.Hash { + s.log.Error("detected a reorg in L2 chain vs previous submitted information, resetting to safe head now", "safe_head", syncStatus.SafeL2) + s.l2SubmittedBlock = syncStatus.SafeL2 + s.l2BufferedBlock = syncStatus.SafeL2 + s.l2ChannelOut = nil + } // Create channel if we don't have one yet if s.l2ChannelOut == nil { var ch ChannelOutIface @@ -135,28 +190,34 @@ func (s *L2Batcher) Buffer(t Testing) error { ch, err = NewGarbageChannelOut(s.l2BatcherCfg.GarbageCfg) } else { c, e := compressor.NewRatioCompressor(compressor.Config{ - TargetFrameSize: s.l2BatcherCfg.MaxL1TxSize, - TargetNumFrames: 1, + TargetOutputSize: batcher.MaxDataSize(1, s.l2BatcherCfg.MaxL1TxSize), ApproxComprRatio: 1, }) require.NoError(t, e, "failed to create compressor") - ch, err = derive.NewChannelOut(derive.SingularBatchType, c, nil) + + var batchType uint = derive.SingularBatchType + var spanBatchBuilder *derive.SpanBatchBuilder = nil + + if s.l2BatcherCfg.ForceSubmitSingularBatch && s.l2BatcherCfg.ForceSubmitSpanBatch { + t.Fatalf("ForceSubmitSingularBatch and ForceSubmitSpanBatch cannot be set to true at the same time") + } else if s.l2BatcherCfg.ForceSubmitSingularBatch { + // use SingularBatchType + } else if s.l2BatcherCfg.ForceSubmitSpanBatch || s.rollupCfg.IsDelta(block.Time()) { + // If both ForceSubmitSingularBatch and ForceSubmitSpanbatch are false, use SpanBatch automatically if Delta HF is activated. + batchType = derive.SpanBatchType + spanBatchBuilder = derive.NewSpanBatchBuilder(s.rollupCfg.Genesis.L2Time, s.rollupCfg.L2ChainID) + } + ch, err = derive.NewChannelOut(batchType, c, spanBatchBuilder) } require.NoError(t, err, "failed to create channel") s.l2ChannelOut = ch } - block, err := s.l2.BlockByNumber(t.Ctx(), big.NewInt(int64(s.l2BufferedBlock.Number+1))) - require.NoError(t, err, "need l2 block %d from sync status", s.l2SubmittedBlock.Number+1) - if block.ParentHash() != s.l2BufferedBlock.Hash { - s.log.Error("detected a reorg in L2 chain vs previous submitted information, resetting to safe head now", "safe_head", syncStatus.SafeL2) - s.l2SubmittedBlock = syncStatus.SafeL2.ID() - s.l2BufferedBlock = syncStatus.SafeL2.ID() - s.l2ChannelOut = nil - } - if _, err := s.l2ChannelOut.AddBlock(block); err != nil { // should always succeed + if _, err := s.l2ChannelOut.AddBlock(s.rollupCfg, block); err != nil { // should always succeed return err } - s.l2BufferedBlock = eth.ToBlockID(block) + ref, err := s.engCl.L2BlockRefByHash(t.Ctx(), block.Hash()) + require.NoError(t, err, "failed to get L2BlockRef") + s.l2BufferedBlock = ref return nil } @@ -188,6 +249,13 @@ func (s *L2Batcher) ActL2BatchSubmit(t Testing, txOpts ...func(tx *types.Dynamic t.Fatalf("failed to output channel data to frame: %v", err) } + payload := data.Bytes() + if s.l2BatcherCfg.UsePlasma { + comm, err := s.l2BatcherCfg.PlasmaDA.SetInput(t.Ctx(), payload) + require.NoError(t, err, "failed to set input for plasma") + payload = comm.TxData() + } + nonce, err := s.l1.PendingNonceAt(t.Ctx(), s.batcherAddr) require.NoError(t, err, "need batcher nonce") @@ -196,26 +264,137 @@ func (s *L2Batcher) ActL2BatchSubmit(t Testing, txOpts ...func(tx *types.Dynamic require.NoError(t, err, "need l1 pending header for gas price estimation") gasFeeCap := new(big.Int).Add(gasTipCap, new(big.Int).Mul(pendingHeader.BaseFee, big.NewInt(2))) - rawTx := &types.DynamicFeeTx{ - ChainID: s.rollupCfg.L1ChainID, - Nonce: nonce, - To: &s.rollupCfg.BatchInboxAddress, - GasTipCap: gasTipCap, - GasFeeCap: gasFeeCap, - Data: data.Bytes(), + var txData types.TxData + if s.l2BatcherCfg.DataAvailabilityType == batcherFlags.CalldataType { + rawTx := &types.DynamicFeeTx{ + ChainID: s.rollupCfg.L1ChainID, + Nonce: nonce, + To: &s.rollupCfg.BatchInboxAddress, + GasTipCap: gasTipCap, + GasFeeCap: gasFeeCap, + Data: payload, + } + for _, opt := range txOpts { + opt(rawTx) + } + + gas, err := core.IntrinsicGas(rawTx.Data, nil, false, true, true, false) + require.NoError(t, err, "need to compute intrinsic gas") + rawTx.Gas = gas + txData = rawTx + } else if s.l2BatcherCfg.DataAvailabilityType == batcherFlags.BlobsType { + var b eth.Blob + require.NoError(t, b.FromData(payload), "must turn data into blob") + sidecar, blobHashes, err := txmgr.MakeSidecar([]*eth.Blob{&b}) + require.NoError(t, err) + require.NotNil(t, pendingHeader.ExcessBlobGas, "need L1 header with 4844 properties") + blobBaseFee := eip4844.CalcBlobFee(*pendingHeader.ExcessBlobGas) + blobFeeCap := new(uint256.Int).Mul(uint256.NewInt(2), uint256.MustFromBig(blobBaseFee)) + if blobFeeCap.Lt(uint256.NewInt(params.GWei)) { // ensure we meet 1 gwei geth tx-pool minimum + blobFeeCap = uint256.NewInt(params.GWei) + } + txData = &types.BlobTx{ + To: s.rollupCfg.BatchInboxAddress, + Data: nil, + Gas: params.TxGas, // intrinsic gas only + BlobHashes: blobHashes, + Sidecar: sidecar, + ChainID: uint256.MustFromBig(s.rollupCfg.L1ChainID), + GasTipCap: uint256.MustFromBig(gasTipCap), + GasFeeCap: uint256.MustFromBig(gasFeeCap), + BlobFeeCap: blobFeeCap, + Value: uint256.NewInt(0), + Nonce: nonce, + } + } else { + t.Fatalf("unrecognized DA type: %q", string(s.l2BatcherCfg.DataAvailabilityType)) } - for _, opt := range txOpts { - opt(rawTx) + + tx, err := types.SignNewTx(s.l2BatcherCfg.BatcherKey, s.l1Signer, txData) + require.NoError(t, err, "need to sign tx") + + err = s.l1.SendTransaction(t.Ctx(), tx) + require.NoError(t, err, "need to send tx") + s.LastSubmitted = tx +} + +func (s *L2Batcher) ActL2BatchSubmitMultiBlob(t Testing, numBlobs int) { + if s.l2BatcherCfg.DataAvailabilityType != batcherFlags.BlobsType { + t.InvalidAction("ActL2BatchSubmitMultiBlob only available for Blobs DA type") + return + } else if numBlobs > 6 || numBlobs < 1 { + t.InvalidAction("invalid number of blobs %d, must be within [1,6]", numBlobs) } - gas, err := core.IntrinsicGas(rawTx.Data, nil, false, true, true, false) - require.NoError(t, err, "need to compute intrinsic gas") - rawTx.Gas = gas - tx, err := types.SignNewTx(s.l2BatcherCfg.BatcherKey, s.l1Signer, rawTx) + // Don't run this action if there's no data to submit + if s.l2ChannelOut == nil { + t.InvalidAction("need to buffer data first, cannot batch submit with empty buffer") + return + } + + // Collect the output frames into blobs + blobs := make([]*eth.Blob, numBlobs) + for i := 0; i < numBlobs; i++ { + data := new(bytes.Buffer) + data.WriteByte(derive.DerivationVersion0) + // write only a few bytes to all but the last blob + l := uint64(derive.FrameV0OverHeadSize + 4) // 4 bytes content + if i == numBlobs-1 { + // write remaining channel to last frame + // subtract one, to account for the version byte + l = s.l2BatcherCfg.MaxL1TxSize - 1 + } + if _, err := s.l2ChannelOut.OutputFrame(data, l); err == io.EOF { + s.l2Submitting = false + if i < numBlobs-1 { + t.Fatalf("failed to fill up %d blobs, only filled %d", numBlobs, i+1) + } + s.l2ChannelOut = nil + } else if err != nil { + s.l2Submitting = false + t.Fatalf("failed to output channel data to frame: %v", err) + } + + blobs[i] = new(eth.Blob) + require.NoError(t, blobs[i].FromData(data.Bytes()), "must turn data into blob") + } + + nonce, err := s.l1.PendingNonceAt(t.Ctx(), s.batcherAddr) + require.NoError(t, err, "need batcher nonce") + + gasTipCap := big.NewInt(2 * params.GWei) + pendingHeader, err := s.l1.HeaderByNumber(t.Ctx(), big.NewInt(-1)) + require.NoError(t, err, "need l1 pending header for gas price estimation") + gasFeeCap := new(big.Int).Add(gasTipCap, new(big.Int).Mul(pendingHeader.BaseFee, big.NewInt(2))) + + sidecar, blobHashes, err := txmgr.MakeSidecar(blobs) + require.NoError(t, err) + require.NotNil(t, pendingHeader.ExcessBlobGas, "need L1 header with 4844 properties") + blobBaseFee := eip4844.CalcBlobFee(*pendingHeader.ExcessBlobGas) + blobFeeCap := new(uint256.Int).Mul(uint256.NewInt(2), uint256.MustFromBig(blobBaseFee)) + if blobFeeCap.Lt(uint256.NewInt(params.GWei)) { // ensure we meet 1 gwei geth tx-pool minimum + blobFeeCap = uint256.NewInt(params.GWei) + } + txData := &types.BlobTx{ + To: s.rollupCfg.BatchInboxAddress, + Data: nil, + Gas: params.TxGas, // intrinsic gas only + BlobHashes: blobHashes, + Sidecar: sidecar, + ChainID: uint256.MustFromBig(s.rollupCfg.L1ChainID), + GasTipCap: uint256.MustFromBig(gasTipCap), + GasFeeCap: uint256.MustFromBig(gasFeeCap), + BlobFeeCap: blobFeeCap, + Value: uint256.NewInt(0), + Nonce: nonce, + } + + tx, err := types.SignNewTx(s.l2BatcherCfg.BatcherKey, s.l1Signer, txData) require.NoError(t, err, "need to sign tx") err = s.l1.SendTransaction(t.Ctx(), tx) require.NoError(t, err, "need to send tx") + s.LastSubmitted = tx } // ActL2BatchSubmitGarbage constructs a malformed channel frame and submits it to the @@ -314,3 +493,9 @@ func (s *L2Batcher) ActSubmitAll(t Testing) { s.ActL2ChannelClose(t) s.ActL2BatchSubmit(t) } + +func (s *L2Batcher) ActSubmitAllMultiBlobs(t Testing, numBlobs int) { + s.ActBufferAll(t) + s.ActL2ChannelClose(t) + s.ActL2BatchSubmitMultiBlob(t, numBlobs) +} diff --git a/op-e2e/actions/l2_batcher_test.go b/op-e2e/actions/l2_batcher_test.go index aa986dcd80cc..82dd4bccacec 100644 --- a/op-e2e/actions/l2_batcher_test.go +++ b/op-e2e/actions/l2_batcher_test.go @@ -1,18 +1,20 @@ package actions import ( - "crypto/rand" "errors" "math/big" + "math/rand" "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" @@ -20,7 +22,57 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func TestBatcher(gt *testing.T) { +// TestL2BatcherBatchType run each batcher-related test case in singular batch mode and span batch mode. +func TestL2BatcherBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, deltaTimeOffset *hexutil.Uint64) + }{ + {"NormalBatcher", NormalBatcher}, + {"L2Finalization", L2Finalization}, + {"L2FinalizationWithSparseL1", L2FinalizationWithSparseL1}, + {"GarbageBatch", GarbageBatch}, + {"ExtendedTimeWithoutL1Batches", ExtendedTimeWithoutL1Batches}, + {"BigL2Txs", BigL2Txs}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + deltaTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &deltaTimeOffset) + }) + } +} + +// applyDeltaTimeOffset adjusts fork configuration to not conflict with the delta overrides +func applyDeltaTimeOffset(dp *e2eutils.DeployParams, deltaTimeOffset *hexutil.Uint64) { + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset + // configure Ecotone to not be before Delta accidentally + if dp.DeployConfig.L2GenesisEcotoneTimeOffset != nil { + if deltaTimeOffset == nil { + dp.DeployConfig.L2GenesisEcotoneTimeOffset = nil + } else if *dp.DeployConfig.L2GenesisEcotoneTimeOffset < *deltaTimeOffset { + dp.DeployConfig.L2GenesisEcotoneTimeOffset = deltaTimeOffset + } + } + // configure Fjord to not be before Delta accidentally + if dp.DeployConfig.L2GenesisFjordTimeOffset != nil { + if deltaTimeOffset == nil { + dp.DeployConfig.L2GenesisFjordTimeOffset = nil + } else if *dp.DeployConfig.L2GenesisFjordTimeOffset < *deltaTimeOffset { + dp.DeployConfig.L2GenesisFjordTimeOffset = deltaTimeOffset + } + } +} + +func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) @@ -29,17 +81,15 @@ func TestBatcher(gt *testing.T) { L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) + applyDeltaTimeOffset(dp, deltaTimeOffset) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) rollupSeqCl := sequencer.RollupClient() - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) // Alice makes a L2 tx cl := seqEngine.EthClient() @@ -55,7 +105,7 @@ func TestBatcher(gt *testing.T) { To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), }) - require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + require.NoError(t, cl.SendTransaction(t.Ctx(), tx)) sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) @@ -97,11 +147,12 @@ func TestBatcher(gt *testing.T) { require.NotNil(t, vTx) } -func TestL2Finalization(gt *testing.T) { +func L2Finalization(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + applyDeltaTimeOffset(dp, deltaTimeOffset) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner, engine, sequencer := setupSequencerTest(t, sd, log) sequencer.ActL2PipelineFull(t) @@ -133,11 +184,8 @@ func TestL2Finalization(gt *testing.T) { require.Equal(t, uint64(1), sequencer.SyncStatus().FinalizedL1.Number) require.Equal(t, uint64(0), sequencer.SyncStatus().FinalizedL2.Number, "L2 block has to be included on L1 before it can be finalized") - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) heightToSubmit := sequencer.SyncStatus().UnsafeL2.Number @@ -202,12 +250,13 @@ func TestL2Finalization(gt *testing.T) { require.Equal(t, heightToSubmit, sequencer.SyncStatus().FinalizedL2.Number, "unknown/bad finalized L1 blocks are ignored") } -// TestL2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal -func TestL2FinalizationWithSparseL1(gt *testing.T) { +// L2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal +func L2FinalizationWithSparseL1(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + applyDeltaTimeOffset(dp, deltaTimeOffset) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner, engine, sequencer := setupSequencerTest(t, sd, log) sequencer.ActL2PipelineFull(t) @@ -219,11 +268,8 @@ func TestL2FinalizationWithSparseL1(gt *testing.T) { startStatus := sequencer.SyncStatus() require.Less(t, startStatus.SafeL2.Number, startStatus.UnsafeL2.Number, "sequencer has unsafe L2 block") - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) batcher.ActSubmitAll(t) // include in L1 @@ -258,25 +304,22 @@ func TestL2FinalizationWithSparseL1(gt *testing.T) { require.Equal(t, finalStatus.FinalizedL2.Number, finalStatus.UnsafeL2.Number, "sequencer submitted its L2 block and it finalized") } -// TestGarbageBatch tests the behavior of an invalid/malformed output channel frame containing +// GarbageBatch tests the behavior of an invalid/malformed output channel frame containing // valid batches being submitted to the batch inbox. These batches should always be rejected // and the safe L2 head should remain unaltered. -func TestGarbageBatch(gt *testing.T) { +func GarbageBatch(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) p := defaultRollupTestParams dp := e2eutils.MakeDeployParams(t, p) + applyDeltaTimeOffset(dp, deltaTimeOffset) for _, garbageKind := range GarbageKinds { sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlError) + log := testlog.Logger(t, log.LevelError) miner, engine, sequencer := setupSequencerTest(t, sd, log) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) - batcherCfg := &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - } + batcherCfg := DefaultBatcherCfg(dp) if garbageKind == MALFORM_RLP || garbageKind == INVALID_COMPRESSION { // If the garbage kind is `INVALID_COMPRESSION` or `MALFORM_RLP`, use the `actions` packages @@ -287,7 +330,7 @@ func TestGarbageBatch(gt *testing.T) { } } - batcher := NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) @@ -340,7 +383,7 @@ func TestGarbageBatch(gt *testing.T) { } } -func TestExtendedTimeWithoutL1Batches(gt *testing.T) { +func ExtendedTimeWithoutL1Batches(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) @@ -349,17 +392,15 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) { L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) + applyDeltaTimeOffset(dp, deltaTimeOffset) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlError) + log := testlog.Logger(t, log.LevelError) miner, engine, sequencer := setupSequencerTest(t, sd, log) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) @@ -386,7 +427,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) { require.Equal(t, sequencer.L2Unsafe(), sequencer.L2Safe(), "same for sequencer") } -// TestBigL2Txs tests a high-throughput case with constrained batcher: +// BigL2Txs tests a high-throughput case with constrained batcher: // - Fill 40 L2 blocks to near max-capacity, with txs of 120 KB each // - Buffer the L2 blocks into channels together as much as possible, submit data-txs only when necessary // (just before crossing the max RLP channel size) @@ -398,7 +439,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) { // The goal of this test is to quickly run through an otherwise very slow process of submitting and including lots of data. // This does not test the batcher code, but is really focused at testing the batcher utils // and channel-decoding verifier code in the derive package. -func TestBigL2Txs(gt *testing.T) { +func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 100, @@ -407,17 +448,19 @@ func TestBigL2Txs(gt *testing.T) { L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) + applyDeltaTimeOffset(dp, deltaTimeOffset) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlInfo) + log := testlog.Logger(t, log.LevelInfo) miner, engine, sequencer := setupSequencerTest(t, sd, log) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 40_000, // try a small batch size, to force the data to be split between more frames - BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient()) + MinL1TxSize: 0, + MaxL1TxSize: 40_000, // try a small batch size, to force the data to be split between more frames + BatcherKey: dp.Secrets.Batcher, + DataAvailabilityType: batcherFlags.CalldataType, + }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) @@ -431,6 +474,8 @@ func TestBigL2Txs(gt *testing.T) { tx.GasFeeCap = e2eutils.Ether(1) // be very generous with basefee, since we're spamming L1 } + rng := rand.New(rand.NewSource(555)) + // build many L2 blocks filled to the brim with large txs of random data for i := 0; i < 40; i++ { aliceNonce, err := cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) @@ -447,7 +492,7 @@ func TestBigL2Txs(gt *testing.T) { require.NoError(t, err) signer := types.LatestSigner(sd.L2Cfg.Config) data := make([]byte, 120_000) // very large L2 txs, as large as the tx-pool will accept - _, err := rand.Read(data[:]) // fill with random bytes, to make compression ineffective + _, err := rng.Read(data[:]) // fill with random bytes, to make compression ineffective require.NoError(t, err) gas, err := core.IntrinsicGas(data, nil, false, true, true, false) require.NoError(t, err) @@ -464,13 +509,13 @@ func TestBigL2Txs(gt *testing.T) { Value: big.NewInt(0), Data: data, }) - require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + require.NoError(t, cl.SendTransaction(t.Ctx(), tx)) engine.ActL2IncludeTx(dp.Addresses.Alice)(t) } sequencer.ActL2EndBlock(t) for batcher.l2BufferedBlock.Number < sequencer.SyncStatus().UnsafeL2.Number { // if we run out of space, close the channel and submit all the txs - if err := batcher.Buffer(t); errors.Is(err, derive.ErrTooManyRLPBytes) { + if err := batcher.Buffer(t); errors.Is(err, derive.ErrTooManyRLPBytes) || errors.Is(err, derive.CompressorFullErr) { log.Info("flushing filled channel to batch txs", "id", batcher.l2ChannelOut.ID()) batcher.ActL2ChannelClose(t) for batcher.l2ChannelOut != nil { diff --git a/op-e2e/actions/l2_engine.go b/op-e2e/actions/l2_engine.go index d1230ec8b7c5..910f487fb7c0 100644 --- a/op-e2e/actions/l2_engine.go +++ b/op-e2e/actions/l2_engine.go @@ -18,6 +18,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum-optimism/optimism/op-node/rollup" @@ -50,7 +51,7 @@ type EngineOption func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error func NewL2Engine(t Testing, log log.Logger, genesis *core.Genesis, rollupGenesisL1 eth.BlockID, jwtPath string, options ...EngineOption) *L2Engine { n, ethBackend, apiBackend := newBackend(t, genesis, jwtPath, options) - engineApi := engineapi.NewL2EngineAPI(log, apiBackend) + engineApi := engineapi.NewL2EngineAPI(log, apiBackend, ethBackend.Downloader()) chain := ethBackend.BlockChain() genesisBlock := chain.Genesis() eng := &L2Engine{ @@ -131,6 +132,20 @@ func (e *engineApiBackend) Genesis() *core.Genesis { return e.genesis } +func (s *L2Engine) Enode() *enode.Node { + return s.node.Server().LocalNode().Node() +} + +func (s *L2Engine) AddPeers(peers ...*enode.Node) { + for _, en := range peers { + s.node.Server().AddPeer(en) + } +} + +func (s *L2Engine) PeerCount() int { + return s.node.Server().PeerCount() +} + func (s *L2Engine) EthClient() *ethclient.Client { cl := s.node.Attach() return ethclient.NewClient(cl) @@ -159,13 +174,13 @@ func (e *L2Engine) EngineClient(t Testing, cfg *rollup.Config) *sources.EngineCl return l2Cl } -// ActL2RPCFail makes the next L2 RPC request fail -func (e *L2Engine) ActL2RPCFail(t Testing) { +// ActL2RPCFail makes the next L2 RPC request fail with given error +func (e *L2Engine) ActL2RPCFail(t Testing, err error) { if e.failL2RPC != nil { // already set to fail? t.InvalidAction("already set a mock L2 rpc error") return } - e.failL2RPC = errors.New("mock L2 RPC error") + e.failL2RPC = err } // ActL2IncludeTx includes the next transaction from the given address in the block that is being built diff --git a/op-e2e/actions/l2_engine_test.go b/op-e2e/actions/l2_engine_test.go index fc48a49e5262..36e146c282a6 100644 --- a/op-e2e/actions/l2_engine_test.go +++ b/op-e2e/actions/l2_engine_test.go @@ -1,6 +1,7 @@ package actions import ( + "errors" "math/big" "testing" @@ -30,7 +31,7 @@ func TestL2EngineAPI(gt *testing.T) { jwtPath := e2eutils.WriteDefaultJWT(t) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) genesisBlock := sd.L2Cfg.ToBlock() consensus := beacon.New(ethash.NewFaker()) db := rawdb.NewMemoryDatabase() @@ -50,7 +51,7 @@ func TestL2EngineAPI(gt *testing.T) { require.NoError(t, err) // apply the payload - status, err := l2Cl.NewPayload(t.Ctx(), payloadA) + status, err := l2Cl.NewPayload(t.Ctx(), payloadA, nil) require.NoError(t, err) require.Equal(t, status.Status, eth.ExecutionValid) require.Equal(t, genesisBlock.Hash(), engine.l2Chain.CurrentBlock().Hash(), "processed payloads are not immediately canonical") @@ -73,7 +74,7 @@ func TestL2EngineAPI(gt *testing.T) { require.NoError(t, err) // apply the payload - status, err = l2Cl.NewPayload(t.Ctx(), payloadB) + status, err = l2Cl.NewPayload(t.Ctx(), payloadB, nil) require.NoError(t, err) require.Equal(t, status.Status, eth.ExecutionValid) require.Equal(t, payloadA.BlockHash, engine.l2Chain.CurrentBlock().Hash(), "processed payloads are not immediately canonical") @@ -94,7 +95,7 @@ func TestL2EngineAPIBlockBuilding(gt *testing.T) { jwtPath := e2eutils.WriteDefaultJWT(t) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) genesisBlock := sd.L2Cfg.ToBlock() db := rawdb.NewMemoryDatabase() tdb := trie.NewDatabase(db, &trie.Config{HashDB: hashdb.Defaults}) @@ -154,12 +155,13 @@ func TestL2EngineAPIBlockBuilding(gt *testing.T) { engine.ActL2IncludeTx(dp.Addresses.Alice)(t) } - payload, err := l2Cl.GetPayload(t.Ctx(), *fcRes.PayloadID) + envelope, err := l2Cl.GetPayload(t.Ctx(), eth.PayloadInfo{ID: *fcRes.PayloadID, Timestamp: uint64(nextBlockTime)}) + payload := envelope.ExecutionPayload require.NoError(t, err) require.Equal(t, parent.Hash(), payload.ParentHash, "block builds on parent block") // apply the payload - status, err := l2Cl.NewPayload(t.Ctx(), payload) + status, err := l2Cl.NewPayload(t.Ctx(), payload, nil) require.NoError(t, err) require.Equal(t, status.Status, eth.ExecutionValid) require.Equal(t, parent.Hash(), engine.l2Chain.CurrentBlock().Hash(), "processed payloads are not immediately canonical") @@ -188,15 +190,16 @@ func TestL2EngineAPIFail(gt *testing.T) { jwtPath := e2eutils.WriteDefaultJWT(t) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) // mock an RPC failure - engine.ActL2RPCFail(t) + mockErr := errors.New("mock L2 RPC error") + engine.ActL2RPCFail(t, mockErr) // check RPC failure l2Cl, err := sources.NewL2Client(engine.RPCClient(), log, nil, sources.L2ClientDefaultConfig(sd.RollupCfg, false)) require.NoError(t, err) _, err = l2Cl.InfoByLabel(t.Ctx(), eth.Unsafe) - require.ErrorContains(t, err, "mock") + require.ErrorIs(t, err, mockErr) head, err := l2Cl.InfoByLabel(t.Ctx(), eth.Unsafe) require.NoError(t, err) require.Equal(gt, sd.L2Cfg.ToBlock().Hash(), head.Hash(), "expecting engine to start at genesis") diff --git a/op-e2e/actions/l2_proposer.go b/op-e2e/actions/l2_proposer.go index 5eae624915f8..660bc71b4b20 100644 --- a/op-e2e/actions/l2_proposer.go +++ b/op-e2e/actions/l2_proposer.go @@ -18,27 +18,35 @@ import ( "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-proposer/metrics" "github.com/ethereum-optimism/optimism/op-proposer/proposer" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) type ProposerCfg struct { - OutputOracleAddr common.Address - ProposerKey *ecdsa.PrivateKey - AllowNonFinalized bool + OutputOracleAddr *common.Address + DisputeGameFactoryAddr *common.Address + ProposalInterval time.Duration + DisputeGameType uint32 + ProposerKey *ecdsa.PrivateKey + AllowNonFinalized bool } type L2Proposer struct { - log log.Logger - l1 *ethclient.Client - driver *proposer.L2OutputSubmitter - contract *bindings.L2OutputOracleCaller - address common.Address - privKey *ecdsa.PrivateKey - contractAddr common.Address - lastTx common.Hash + log log.Logger + l1 *ethclient.Client + driver *proposer.L2OutputSubmitter + l2OutputOracle *bindings.L2OutputOracleCaller + l2OutputOracleAddr *common.Address + disputeGameFactory *bindings.DisputeGameFactoryCaller + disputeGameFactoryAddr *common.Address + address common.Address + privKey *ecdsa.PrivateKey + lastTx common.Hash } type fakeTxMgr struct { @@ -48,46 +56,71 @@ type fakeTxMgr struct { func (f fakeTxMgr) From() common.Address { return f.from } -func (f fakeTxMgr) Call(_ context.Context, _ ethereum.CallMsg, _ *big.Int) ([]byte, error) { - panic("unimplemented") -} + func (f fakeTxMgr) BlockNumber(_ context.Context) (uint64, error) { panic("unimplemented") } + func (f fakeTxMgr) Send(_ context.Context, _ txmgr.TxCandidate) (*types.Receipt, error) { panic("unimplemented") } +func (f fakeTxMgr) Close() { +} + +func (f fakeTxMgr) IsClosed() bool { + return false +} + func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Client, rollupCl *sources.RollupClient) *L2Proposer { - proposerCfg := proposer.Config{ - L2OutputOracleAddr: cfg.OutputOracleAddr, - PollInterval: time.Second, - NetworkTimeout: time.Second, - L1Client: l1, - RollupClient: rollupCl, - AllowNonFinalized: cfg.AllowNonFinalized, - // We use custom signing here instead of using the transaction manager. - TxManager: fakeTxMgr{from: crypto.PubkeyToAddress(cfg.ProposerKey.PublicKey)}, + proposerConfig := proposer.ProposerConfig{ + PollInterval: time.Second, + NetworkTimeout: time.Second, + ProposalInterval: cfg.ProposalInterval, + L2OutputOracleAddr: cfg.OutputOracleAddr, + DisputeGameFactoryAddr: cfg.DisputeGameFactoryAddr, + DisputeGameType: cfg.DisputeGameType, + AllowNonFinalized: cfg.AllowNonFinalized, } - - dr, err := proposer.NewL2OutputSubmitter(proposerCfg, log, metrics.NoopMetrics) + rollupProvider, err := dial.NewStaticL2RollupProviderFromExistingRollup(rollupCl) require.NoError(t, err) - contract, err := bindings.NewL2OutputOracleCaller(cfg.OutputOracleAddr, l1) + driverSetup := proposer.DriverSetup{ + Log: log, + Metr: metrics.NoopMetrics, + Cfg: proposerConfig, + Txmgr: fakeTxMgr{from: crypto.PubkeyToAddress(cfg.ProposerKey.PublicKey)}, + L1Client: l1, + RollupProvider: rollupProvider, + } + + dr, err := proposer.NewL2OutputSubmitter(driverSetup) require.NoError(t, err) address := crypto.PubkeyToAddress(cfg.ProposerKey.PublicKey) - proposer, err := contract.PROPOSER(&bind.CallOpts{}) - require.NoError(t, err) - require.Equal(t, proposer, address, "PROPOSER must be the proposer's address") + + var l2OutputOracle *bindings.L2OutputOracleCaller + var disputeGameFactory *bindings.DisputeGameFactoryCaller + if e2eutils.UseFPAC() { + disputeGameFactory, err = bindings.NewDisputeGameFactoryCaller(*cfg.DisputeGameFactoryAddr, l1) + require.NoError(t, err) + } else { + l2OutputOracle, err := bindings.NewL2OutputOracleCaller(*cfg.OutputOracleAddr, l1) + require.NoError(t, err) + proposer, err := l2OutputOracle.PROPOSER(&bind.CallOpts{}) + require.NoError(t, err) + require.Equal(t, proposer, address, "PROPOSER must be the proposer's address") + } return &L2Proposer{ - log: log, - l1: l1, - driver: dr, - contract: contract, - address: address, - privKey: cfg.ProposerKey, - contractAddr: cfg.OutputOracleAddr, + log: log, + l1: l1, + driver: dr, + l2OutputOracle: l2OutputOracle, + l2OutputOracleAddr: cfg.OutputOracleAddr, + disputeGameFactory: disputeGameFactory, + disputeGameFactoryAddr: cfg.DisputeGameFactoryAddr, + address: address, + privKey: cfg.ProposerKey, } } @@ -103,9 +136,16 @@ func (p *L2Proposer) sendTx(t Testing, data []byte) { nonce, err := p.l1.NonceAt(t.Ctx(), p.address, nil) require.NoError(t, err) + var addr common.Address + if e2eutils.UseFPAC() { + addr = *p.disputeGameFactoryAddr + } else { + addr = *p.l2OutputOracleAddr + } + gasLimit, err := estimateGasPending(t.Ctx(), p.l1, ethereum.CallMsg{ From: p.address, - To: &p.contractAddr, + To: &addr, GasFeeCap: gasFeeCap, GasTipCap: gasTipCap, Data: data, @@ -114,7 +154,7 @@ func (p *L2Proposer) sendTx(t Testing, data []byte) { rawTx := &types.DynamicFeeTx{ Nonce: nonce, - To: &p.contractAddr, + To: &addr, Data: data, GasFeeCap: gasFeeCap, GasTipCap: gasTipCap, @@ -126,7 +166,6 @@ func (p *L2Proposer) sendTx(t Testing, data []byte) { require.NoError(t, err, "need to sign tx") err = p.l1.SendTransaction(t.Ctx(), tx) - log.Info("Proposer sent tx", "hash", tx.Hash(), "to", p.contractAddr) require.NoError(t, err, "need to send tx") p.lastTx = tx.Hash() @@ -165,21 +204,56 @@ func toCallArg(msg ethereum.CallMsg) interface{} { return arg } +func (p *L2Proposer) fetchNextOutput(t Testing) (*eth.OutputResponse, bool, error) { + if e2eutils.UseFPAC() { + blockNumber, err := p.driver.FetchCurrentBlockNumber(t.Ctx()) + if err != nil { + return nil, false, err + } + + output, _, err := p.driver.FetchOutput(t.Ctx(), blockNumber) + if err != nil { + return nil, false, err + } + + encodedBlockNumber := make([]byte, 32) + copy(encodedBlockNumber[32-len(blockNumber.Bytes()):], blockNumber.Bytes()) + game, err := p.disputeGameFactory.Games(&bind.CallOpts{}, p.driver.Cfg.DisputeGameType, output.OutputRoot, encodedBlockNumber) + if err != nil { + return nil, false, err + } + if game.Timestamp != 0 { + return nil, false, nil + } + + return output, true, nil + } else { + return p.driver.FetchNextOutputInfo(t.Ctx()) + } +} + func (p *L2Proposer) CanPropose(t Testing) bool { - _, shouldPropose, err := p.driver.FetchNextOutputInfo(t.Ctx()) + _, shouldPropose, err := p.fetchNextOutput(t) require.NoError(t, err) return shouldPropose } func (p *L2Proposer) ActMakeProposalTx(t Testing) { - output, shouldPropose, err := p.driver.FetchNextOutputInfo(t.Ctx()) + output, shouldPropose, err := p.fetchNextOutput(t) + require.NoError(t, err) + if !shouldPropose { return } - require.NoError(t, err) - txData, err := p.driver.ProposeL2OutputTxData(output) - require.NoError(t, err) + var txData []byte + if e2eutils.UseFPAC() { + txData, _, err = p.driver.ProposeL2OutputDGFTxData(output) + require.NoError(t, err) + } else { + txData, err = p.driver.ProposeL2OutputTxData(output) + require.NoError(t, err) + } // Note: Use L1 instead of the output submitter's transaction manager because // this is non-blocking while the txmgr is blocking & deadlocks the tests diff --git a/op-e2e/actions/l2_proposer_test.go b/op-e2e/actions/l2_proposer_test.go index 5e1f51a33db5..5143b58e7c5f 100644 --- a/op-e2e/actions/l2_proposer_test.go +++ b/op-e2e/actions/l2_proposer_test.go @@ -1,38 +1,76 @@ package actions import ( + "math/big" "testing" + "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "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" "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/bindingspreview" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func TestProposer(gt *testing.T) { +// TestProposerBatchType run each proposer-related test case in singular batch mode and span batch mode. +func TestProposerBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, deltaTimeOffset *hexutil.Uint64) + }{ + {"RunProposerTest", RunProposerTest}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + deltaTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &deltaTimeOffset) + }) + } +} + +func RunProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) rollupSeqCl := sequencer.RollupClient() - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) - proposer := NewL2Proposer(t, log, &ProposerCfg{ - OutputOracleAddr: sd.DeploymentsL1.L2OutputOracleProxy, - ProposerKey: dp.Secrets.Proposer, - AllowNonFinalized: false, - }, miner.EthClient(), sequencer.RollupClient()) + var proposer *L2Proposer + if e2eutils.UseFPAC() { + proposer = NewL2Proposer(t, log, &ProposerCfg{ + DisputeGameFactoryAddr: &sd.DeploymentsL1.DisputeGameFactoryProxy, + ProposalInterval: 6 * time.Second, + DisputeGameType: 0, + ProposerKey: dp.Secrets.Proposer, + AllowNonFinalized: true, + }, miner.EthClient(), rollupSeqCl) + } else { + proposer = NewL2Proposer(t, log, &ProposerCfg{ + OutputOracleAddr: &sd.DeploymentsL1.L2OutputOracleProxy, + ProposerKey: dp.Secrets.Proposer, + AllowNonFinalized: false, + }, miner.EthClient(), rollupSeqCl) + } // L1 block miner.ActEmptyBlock(t) @@ -71,17 +109,41 @@ func TestProposer(gt *testing.T) { } // check that L1 stored the expected output root - outputOracleContract, err := bindings.NewL2OutputOracle(sd.DeploymentsL1.L2OutputOracleProxy, miner.EthClient()) - require.NoError(t, err) - blockNumber, err := outputOracleContract.LatestBlockNumber(&bind.CallOpts{}) - require.NoError(t, err) - require.Greater(t, int64(blockNumber.Uint64()), int64(0), "latest block number must be greater than 0") - block, err := seqEngine.EthClient().BlockByNumber(t.Ctx(), blockNumber) - require.NoError(t, err) - outputOnL1, err := outputOracleContract.GetL2OutputAfter(&bind.CallOpts{}, blockNumber) - require.NoError(t, err) - require.Less(t, block.Time(), outputOnL1.Timestamp.Uint64(), "output is registered with L1 timestamp of proposal tx, past L2 block") - outputComputed, err := sequencer.RollupClient().OutputAtBlock(t.Ctx(), blockNumber.Uint64()) - require.NoError(t, err) - require.Equal(t, eth.Bytes32(outputOnL1.OutputRoot), outputComputed.OutputRoot, "output roots must match") + if e2eutils.UseFPAC() { + optimismPortal2Contract, err := bindingspreview.NewOptimismPortal2(sd.DeploymentsL1.OptimismPortalProxy, miner.EthClient()) + require.NoError(t, err) + respectedGameType, err := optimismPortal2Contract.RespectedGameType(&bind.CallOpts{}) + require.NoError(t, err) + disputeGameFactoryContract, err := bindings.NewDisputeGameFactory(sd.DeploymentsL1.DisputeGameFactoryProxy, miner.EthClient()) + require.NoError(t, err) + gameCount, err := disputeGameFactoryContract.GameCount(&bind.CallOpts{}) + require.NoError(t, err) + require.Greater(t, gameCount.Uint64(), uint64(0), "game count must be greater than 0") + latestGames, err := disputeGameFactoryContract.FindLatestGames(&bind.CallOpts{}, respectedGameType, new(big.Int).Sub(gameCount, common.Big1), common.Big1) + require.NoError(t, err) + require.Greater(t, len(latestGames), 0, "latest games must be greater than 0") + latestGame := latestGames[0] + gameBlockNumber := new(big.Int) + gameBlockNumber.SetBytes(latestGame.ExtraData[0:32]) + block, err := seqEngine.EthClient().BlockByNumber(t.Ctx(), gameBlockNumber) + require.NoError(t, err) + require.Less(t, block.Time(), latestGame.Timestamp, "output is registered with L1 timestamp of proposal tx, past L2 block") + outputComputed, err := sequencer.RollupClient().OutputAtBlock(t.Ctx(), gameBlockNumber.Uint64()) + require.NoError(t, err) + require.Equal(t, eth.Bytes32(latestGame.RootClaim), outputComputed.OutputRoot, "output roots must match") + } else { + outputOracleContract, err := bindings.NewL2OutputOracle(sd.DeploymentsL1.L2OutputOracleProxy, miner.EthClient()) + require.NoError(t, err) + blockNumber, err := outputOracleContract.LatestBlockNumber(&bind.CallOpts{}) + require.NoError(t, err) + require.Greater(t, int64(blockNumber.Uint64()), int64(0), "latest block number must be greater than 0") + block, err := seqEngine.EthClient().BlockByNumber(t.Ctx(), blockNumber) + require.NoError(t, err) + outputOnL1, err := outputOracleContract.GetL2OutputAfter(&bind.CallOpts{}, blockNumber) + require.NoError(t, err) + require.Less(t, block.Time(), outputOnL1.Timestamp.Uint64(), "output is registered with L1 timestamp of proposal tx, past L2 block") + outputComputed, err := sequencer.RollupClient().OutputAtBlock(t.Ctx(), blockNumber.Uint64()) + require.NoError(t, err) + require.Equal(t, eth.Bytes32(outputOnL1.OutputRoot), outputComputed.OutputRoot, "output roots must match") + } } diff --git a/op-e2e/actions/l2_sequencer.go b/op-e2e/actions/l2_sequencer.go index 625356f4bca6..c1c93cf74dec 100644 --- a/op-e2e/actions/l2_sequencer.go +++ b/op-e2e/actions/l2_sequencer.go @@ -4,11 +4,14 @@ import ( "context" "errors" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/op-node/metrics" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/async" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/driver" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" @@ -40,8 +43,9 @@ type L2Sequencer struct { mockL1OriginSelector *MockL1OriginSelector } -func NewL2Sequencer(t Testing, log log.Logger, l1 derive.L1Fetcher, eng L2API, cfg *rollup.Config, seqConfDepth uint64) *L2Sequencer { - ver := NewL2Verifier(t, log, l1, eng, cfg, &sync.Config{}) +func NewL2Sequencer(t Testing, log log.Logger, l1 derive.L1Fetcher, blobSrc derive.L1BlobsFetcher, + plasmaSrc derive.PlasmaInputFetcher, eng L2API, cfg *rollup.Config, seqConfDepth uint64) *L2Sequencer { + ver := NewL2Verifier(t, log, l1, blobSrc, plasmaSrc, eng, cfg, &sync.Config{}, safedb.Disabled) attrBuilder := derive.NewFetchingAttributesBuilder(cfg, l1, eng) seqConfDepthL1 := driver.NewConfDepth(seqConfDepth, ver.l1State.L1Head, l1) l1OriginSelector := &MockL1OriginSelector{ @@ -49,7 +53,7 @@ func NewL2Sequencer(t Testing, log log.Logger, l1 derive.L1Fetcher, eng L2API, c } return &L2Sequencer{ L2Verifier: *ver, - sequencer: driver.NewSequencer(log, cfg, ver.derivation, attrBuilder, l1OriginSelector, metrics.NoopMetrics), + sequencer: driver.NewSequencer(log, cfg, ver.engine, attrBuilder, l1OriginSelector, metrics.NoopMetrics), mockL1OriginSelector: l1OriginSelector, failL2GossipUnsafeBlock: nil, } @@ -94,7 +98,7 @@ func (s *L2Sequencer) ActL2EndBlock(t Testing) { } s.l2Building = false - _, err := s.sequencer.CompleteBuildingBlock(t.Ctx()) + _, err := s.sequencer.CompleteBuildingBlock(t.Ctx(), async.NoOpGossiper{}, &conductor.NoOpConductor{}) // TODO: there may be legitimate temporary errors here, if we mock engine API RPC-failure. // For advanced tests we can catch those and print a warning instead. require.NoError(t, err) @@ -104,7 +108,7 @@ func (s *L2Sequencer) ActL2EndBlock(t Testing) { // ActL2KeepL1Origin makes the sequencer use the current L1 origin, even if the next origin is available. func (s *L2Sequencer) ActL2KeepL1Origin(t Testing) { - parent := s.derivation.UnsafeL2Head() + parent := s.engine.UnsafeL2Head() // force old origin, for testing purposes oldOrigin, err := s.l1.L1BlockRefByHash(t.Ctx(), parent.L1Origin.Hash) require.NoError(t, err, "failed to get current origin: %s", parent.L1Origin) @@ -113,7 +117,7 @@ func (s *L2Sequencer) ActL2KeepL1Origin(t Testing) { // ActBuildToL1Head builds empty blocks until (incl.) the L1 head becomes the L2 origin func (s *L2Sequencer) ActBuildToL1Head(t Testing) { - for s.derivation.UnsafeL2Head().L1Origin.Number < s.l1State.L1Head().Number { + for s.engine.UnsafeL2Head().L1Origin.Number < s.l1State.L1Head().Number { s.ActL2PipelineFull(t) s.ActL2StartBlock(t) s.ActL2EndBlock(t) @@ -122,7 +126,7 @@ func (s *L2Sequencer) ActBuildToL1Head(t Testing) { // ActBuildToL1HeadUnsafe builds empty blocks until (incl.) the L1 head becomes the L1 origin of the L2 head func (s *L2Sequencer) ActBuildToL1HeadUnsafe(t Testing) { - for s.derivation.UnsafeL2Head().L1Origin.Number < s.l1State.L1Head().Number { + for s.engine.UnsafeL2Head().L1Origin.Number < s.l1State.L1Head().Number { // Note: the derivation pipeline does not run, we are just sequencing a block on top of the existing L2 chain. s.ActL2StartBlock(t) s.ActL2EndBlock(t) @@ -133,7 +137,7 @@ func (s *L2Sequencer) ActBuildToL1HeadUnsafe(t Testing) { func (s *L2Sequencer) ActBuildToL1HeadExcl(t Testing) { for { s.ActL2PipelineFull(t) - nextOrigin, err := s.mockL1OriginSelector.FindL1Origin(t.Ctx(), s.derivation.UnsafeL2Head()) + nextOrigin, err := s.mockL1OriginSelector.FindL1Origin(t.Ctx(), s.engine.UnsafeL2Head()) require.NoError(t, err) if nextOrigin.Number >= s.l1State.L1Head().Number { break @@ -147,7 +151,7 @@ func (s *L2Sequencer) ActBuildToL1HeadExcl(t Testing) { func (s *L2Sequencer) ActBuildToL1HeadExclUnsafe(t Testing) { for { // Note: the derivation pipeline does not run, we are just sequencing a block on top of the existing L2 chain. - nextOrigin, err := s.mockL1OriginSelector.FindL1Origin(t.Ctx(), s.derivation.UnsafeL2Head()) + nextOrigin, err := s.mockL1OriginSelector.FindL1Origin(t.Ctx(), s.engine.UnsafeL2Head()) require.NoError(t, err) if nextOrigin.Number >= s.l1State.L1Head().Number { break @@ -157,9 +161,16 @@ func (s *L2Sequencer) ActBuildToL1HeadExclUnsafe(t Testing) { } } -func (s *L2Sequencer) ActBuildL2ToRegolith(t Testing) { - require.NotNil(t, s.rollupCfg.RegolithTime, "cannot activate Regolith when it is not scheduled") - for s.L2Unsafe().Time < *s.rollupCfg.RegolithTime { +func (s *L2Sequencer) ActBuildL2ToTime(t Testing, target uint64) { + for s.L2Unsafe().Time < target { + s.ActL2StartBlock(t) + s.ActL2EndBlock(t) + } +} + +func (s *L2Sequencer) ActBuildL2ToEcotone(t Testing) { + require.NotNil(t, s.rollupCfg.EcotoneTime, "cannot activate Ecotone when it is not scheduled") + for s.L2Unsafe().Time < *s.rollupCfg.EcotoneTime { s.ActL2StartBlock(t) s.ActL2EndBlock(t) } diff --git a/op-e2e/actions/l2_sequencer_test.go b/op-e2e/actions/l2_sequencer_test.go index 654787cd8268..1bcf4c4d0cff 100644 --- a/op-e2e/actions/l2_sequencer_test.go +++ b/op-e2e/actions/l2_sequencer_test.go @@ -5,6 +5,10 @@ import ( "testing" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/common" @@ -12,10 +16,27 @@ import ( "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + plasma "github.com/ethereum-optimism/optimism/op-plasma" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" ) +func EngineWithP2P() EngineOption { + return func(ethCfg *ethconfig.Config, nodeCfg *node.Config) error { + p2pKey, err := crypto.GenerateKey() + if err != nil { + return err + } + nodeCfg.P2P = p2p.Config{ + MaxPeers: 100, + NoDiscovery: true, + ListenAddr: "127.0.0.1:0", + PrivateKey: p2pKey, + } + return nil + } +} + func setupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger) (*L1Miner, *L2Engine, *L2Sequencer) { jwtPath := e2eutils.WriteDefaultJWT(t) @@ -23,11 +44,11 @@ func setupSequencerTest(t Testing, sd *e2eutils.SetupData, log log.Logger) (*L1M l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) require.NoError(t, err) - engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) + engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, EngineWithP2P()) l2Cl, err := sources.NewEngineClient(engine.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) - sequencer := NewL2Sequencer(t, log, l1F, l2Cl, sd.RollupCfg, 0) + sequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), plasma.Disabled, l2Cl, sd.RollupCfg, 0) return miner, engine, sequencer } @@ -41,7 +62,7 @@ func TestL2Sequencer_SequencerDrift(gt *testing.T) { } dp := e2eutils.MakeDeployParams(t, p) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner, engine, sequencer := setupSequencerTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) @@ -109,7 +130,7 @@ func TestL2Sequencer_SequencerOnlyReorg(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner, _, sequencer := setupSequencerTest(t, sd, log) // Sequencer at first only recognizes the genesis as safe. diff --git a/op-e2e/actions/l2_verifier.go b/op-e2e/actions/l2_verifier.go index 1340210d197e..305f161e8d06 100644 --- a/op-e2e/actions/l2_verifier.go +++ b/op-e2e/actions/l2_verifier.go @@ -33,6 +33,7 @@ type L2Verifier struct { } // L2 rollup + engine *derive.EngineController derivation *derive.DerivationPipeline l1 derive.L1Fetcher @@ -57,14 +58,21 @@ type L2API interface { OutputV0AtBlock(ctx context.Context, blockHash common.Hash) (*eth.OutputV0, error) } -func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, eng L2API, cfg *rollup.Config, syncCfg *sync.Config) *L2Verifier { +type safeDB interface { + derive.SafeHeadListener + node.SafeDBReader +} + +func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, blobsSrc derive.L1BlobsFetcher, plasmaSrc derive.PlasmaInputFetcher, eng L2API, cfg *rollup.Config, syncCfg *sync.Config, safeHeadListener safeDB) *L2Verifier { metrics := &testutils.TestDerivationMetrics{} - pipeline := derive.NewDerivationPipeline(log, cfg, l1, eng, metrics, syncCfg) + engine := derive.NewEngineController(eng, log, metrics, cfg, syncCfg.SyncMode) + pipeline := derive.NewDerivationPipeline(log, cfg, l1, blobsSrc, plasmaSrc, eng, engine, metrics, syncCfg, safeHeadListener) pipeline.Reset() rollupNode := &L2Verifier{ log: log, eng: eng, + engine: engine, derivation: pipeline, l1: l1, l1State: driver.NewL1State(log, metrics), @@ -81,7 +89,7 @@ func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, eng L2API, cf apis := []rpc.API{ { Namespace: "optimism", - Service: node.NewNodeAPI(cfg, eng, backend, log, m), + Service: node.NewNodeAPI(cfg, eng, backend, safeHeadListener, log, m), Public: true, Authenticated: false, }, @@ -127,20 +135,28 @@ func (s *l2VerifierBackend) SequencerActive(ctx context.Context) (bool, error) { return false, nil } +func (s *l2VerifierBackend) OnUnsafeL2Payload(ctx context.Context, envelope *eth.ExecutionPayloadEnvelope) error { + return nil +} + func (s *L2Verifier) L2Finalized() eth.L2BlockRef { - return s.derivation.Finalized() + return s.engine.Finalized() } func (s *L2Verifier) L2Safe() eth.L2BlockRef { - return s.derivation.SafeL2Head() + return s.engine.SafeL2Head() +} + +func (s *L2Verifier) L2PendingSafe() eth.L2BlockRef { + return s.engine.PendingSafeL2Head() } func (s *L2Verifier) L2Unsafe() eth.L2BlockRef { - return s.derivation.UnsafeL2Head() + return s.engine.UnsafeL2Head() } -func (s *L2Verifier) EngineSyncTarget() eth.L2BlockRef { - return s.derivation.EngineSyncTarget() +func (s *L2Verifier) L2BackupUnsafe() eth.L2BlockRef { + return s.engine.BackupUnsafeL2Head() } func (s *L2Verifier) SyncStatus() *eth.SyncStatus { @@ -153,8 +169,7 @@ func (s *L2Verifier) SyncStatus() *eth.SyncStatus { UnsafeL2: s.L2Unsafe(), SafeL2: s.L2Safe(), FinalizedL2: s.L2Finalized(), - UnsafeL2SyncTarget: s.derivation.UnsafeL2SyncTarget(), - EngineSyncTarget: s.EngineSyncTarget(), + PendingSafeL2: s.L2PendingSafe(), } } @@ -211,7 +226,7 @@ func (s *L2Verifier) ActL2PipelineStep(t Testing) { s.l2PipelineIdle = false err := s.derivation.Step(t.Ctx()) - if err == io.EOF || (err != nil && errors.Is(err, derive.EngineP2PSyncing)) { + if err == io.EOF || (err != nil && errors.Is(err, derive.EngineELSyncing)) { s.l2PipelineIdle = true return } else if err != nil && errors.Is(err, derive.NotEnoughData) { @@ -228,6 +243,8 @@ func (s *L2Verifier) ActL2PipelineStep(t Testing) { return } else if err != nil && errors.Is(err, derive.ErrCritical) { t.Fatalf("derivation failed critically: %v", err) + } else if err != nil { + t.Fatalf("derivation failed: %v", err) } else { return } @@ -241,8 +258,18 @@ func (s *L2Verifier) ActL2PipelineFull(t Testing) { } // ActL2UnsafeGossipReceive creates an action that can receive an unsafe execution payload, like gossipsub -func (s *L2Verifier) ActL2UnsafeGossipReceive(payload *eth.ExecutionPayload) Action { +func (s *L2Verifier) ActL2UnsafeGossipReceive(payload *eth.ExecutionPayloadEnvelope) Action { return func(t Testing) { s.derivation.AddUnsafePayload(payload) } } + +// ActL2InsertUnsafePayload creates an action that can insert an unsafe execution payload +func (s *L2Verifier) ActL2InsertUnsafePayload(payload *eth.ExecutionPayloadEnvelope) Action { + return func(t Testing) { + ref, err := derive.PayloadToBlockRef(s.rollupCfg, payload.ExecutionPayload) + require.NoError(t, err) + err = s.engine.InsertUnsafePayload(t.Ctx(), payload, ref) + require.NoError(t, err) + } +} diff --git a/op-e2e/actions/l2_verifier_test.go b/op-e2e/actions/l2_verifier_test.go index 5116b0cc32e7..6fe70a3e6fb4 100644 --- a/op-e2e/actions/l2_verifier_test.go +++ b/op-e2e/actions/l2_verifier_test.go @@ -3,6 +3,8 @@ package actions import ( "testing" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" + plasma "github.com/ethereum-optimism/optimism/op-plasma" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" @@ -13,18 +15,40 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func setupVerifier(t Testing, sd *e2eutils.SetupData, log log.Logger, l1F derive.L1Fetcher, syncCfg *sync.Config) (*L2Engine, *L2Verifier) { +type verifierCfg struct { + safeHeadListener safeDB +} + +type VerifierOpt func(opts *verifierCfg) + +func WithSafeHeadListener(l safeDB) VerifierOpt { + return func(opts *verifierCfg) { + opts.safeHeadListener = l + } +} + +func defaultVerifierCfg() *verifierCfg { + return &verifierCfg{ + safeHeadListener: safedb.Disabled, + } +} + +func setupVerifier(t Testing, sd *e2eutils.SetupData, log log.Logger, l1F derive.L1Fetcher, blobSrc derive.L1BlobsFetcher, syncCfg *sync.Config, opts ...VerifierOpt) (*L2Engine, *L2Verifier) { + cfg := defaultVerifierCfg() + for _, opt := range opts { + opt(cfg) + } jwtPath := e2eutils.WriteDefaultJWT(t) - engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) + engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath, EngineWithP2P()) engCl := engine.EngineClient(t, sd.RollupCfg) - verifier := NewL2Verifier(t, log, l1F, engCl, sd.RollupCfg, syncCfg) + verifier := NewL2Verifier(t, log, l1F, blobSrc, plasma.Disabled, engCl, sd.RollupCfg, syncCfg, cfg.safeHeadListener) return engine, verifier } func setupVerifierOnlyTest(t Testing, sd *e2eutils.SetupData, log log.Logger) (*L1Miner, *L2Engine, *L2Verifier) { miner := NewL1Miner(t, log, sd.L1Cfg) l1Cl := miner.L1Client(t, sd.RollupCfg) - engine, verifier := setupVerifier(t, sd, log, l1Cl, &sync.Config{}) + engine, verifier := setupVerifier(t, sd, log, l1Cl, miner.BlobStore(), &sync.Config{}) return miner, engine, verifier } @@ -38,7 +62,7 @@ func TestL2Verifier_SequenceWindow(gt *testing.T) { } dp := e2eutils.MakeDeployParams(t, p) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner, engine, verifier := setupVerifierOnlyTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) diff --git a/op-e2e/actions/plasma_test.go b/op-e2e/actions/plasma_test.go new file mode 100644 index 000000000000..f8bc24188a52 --- /dev/null +++ b/op-e2e/actions/plasma_test.go @@ -0,0 +1,624 @@ +package actions + +import ( + "math/big" + "math/rand" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + plasma "github.com/ethereum-optimism/optimism/op-plasma" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +// Devnet allocs should have plasma mode enabled for these tests to pass + +// L2PlasmaDA is a test harness for manipulating plasma DA state. +type L2PlasmaDA struct { + log log.Logger + storage *plasma.DAErrFaker + daMgr *plasma.DA + plasmaCfg plasma.Config + contract *bindings.DataAvailabilityChallenge + batcher *L2Batcher + sequencer *L2Sequencer + engine *L2Engine + engCl *sources.EngineClient + sd *e2eutils.SetupData + dp *e2eutils.DeployParams + miner *L1Miner + alice *CrossLayerUser + lastComm []byte + lastCommBn uint64 +} + +type PlasmaParam func(p *e2eutils.TestParams) + +func NewL2PlasmaDA(t Testing, params ...PlasmaParam) *L2PlasmaDA { + p := &e2eutils.TestParams{ + MaxSequencerDrift: 40, + SequencerWindowSize: 120, + ChannelTimeout: 120, + L1BlockTime: 12, + UsePlasma: true, + } + for _, apply := range params { + apply(p) + } + log := testlog.Logger(t, log.LvlDebug) + + dp := e2eutils.MakeDeployParams(t, p) + sd := e2eutils.Setup(t, dp, defaultAlloc) + + require.True(t, sd.RollupCfg.UsePlasma) + + miner := NewL1Miner(t, log, sd.L1Cfg) + l1Client := miner.EthClient() + + jwtPath := e2eutils.WriteDefaultJWT(t) + engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath) + engCl := engine.EngineClient(t, sd.RollupCfg) + + storage := &plasma.DAErrFaker{Client: plasma.NewMockDAClient(log)} + + l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindBasic)) + require.NoError(t, err) + + plasmaCfg, err := sd.RollupCfg.PlasmaConfig() + require.NoError(t, err) + + daMgr := plasma.NewPlasmaDAWithStorage(log, plasmaCfg, storage, &plasma.NoopMetrics{}) + + sequencer := NewL2Sequencer(t, log, l1F, nil, daMgr, engCl, sd.RollupCfg, 0) + miner.ActL1SetFeeRecipient(common.Address{'A'}) + sequencer.ActL2PipelineFull(t) + + batcher := NewL2Batcher(log, sd.RollupCfg, PlasmaBatcherCfg(dp, storage), sequencer.RollupClient(), l1Client, engine.EthClient(), engCl) + + addresses := e2eutils.CollectAddresses(sd, dp) + cl := engine.EthClient() + l2UserEnv := &BasicUserEnv[*L2Bindings]{ + EthCl: cl, + Signer: types.LatestSigner(sd.L2Cfg.Config), + AddressCorpora: addresses, + Bindings: NewL2Bindings(t, cl, engine.GethClient()), + } + alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) + alice.L2.SetUserEnv(l2UserEnv) + + contract, err := bindings.NewDataAvailabilityChallenge(sd.RollupCfg.DAChallengeAddress, l1Client) + require.NoError(t, err) + + challengeWindow, err := contract.ChallengeWindow(nil) + require.NoError(t, err) + require.Equal(t, plasmaCfg.ChallengeWindow, challengeWindow.Uint64()) + + resolveWindow, err := contract.ResolveWindow(nil) + require.NoError(t, err) + require.Equal(t, plasmaCfg.ResolveWindow, resolveWindow.Uint64()) + + return &L2PlasmaDA{ + log: log, + storage: storage, + daMgr: daMgr, + plasmaCfg: plasmaCfg, + contract: contract, + batcher: batcher, + sequencer: sequencer, + engine: engine, + engCl: engCl, + sd: sd, + dp: dp, + miner: miner, + alice: alice, + } +} + +func (a *L2PlasmaDA) StorageClient() *plasma.DAErrFaker { + return a.storage +} + +func (a *L2PlasmaDA) NewVerifier(t Testing) *L2Verifier { + jwtPath := e2eutils.WriteDefaultJWT(t) + engine := NewL2Engine(t, a.log, a.sd.L2Cfg, a.sd.RollupCfg.Genesis.L1, jwtPath) + engCl := engine.EngineClient(t, a.sd.RollupCfg) + l1F, err := sources.NewL1Client(a.miner.RPCClient(), a.log, nil, sources.L1ClientDefaultConfig(a.sd.RollupCfg, false, sources.RPCKindBasic)) + require.NoError(t, err) + + daMgr := plasma.NewPlasmaDAWithStorage(a.log, a.plasmaCfg, a.storage, &plasma.NoopMetrics{}) + + verifier := NewL2Verifier(t, a.log, l1F, nil, daMgr, engCl, a.sd.RollupCfg, &sync.Config{}, safedb.Disabled) + + return verifier +} + +func (a *L2PlasmaDA) ActSequencerIncludeTx(t Testing) { + a.alice.L2.ActResetTxOpts(t) + a.alice.L2.ActSetTxToAddr(&a.dp.Addresses.Bob)(t) + a.alice.L2.ActMakeTx(t) + + a.sequencer.ActL2PipelineFull(t) + + a.sequencer.ActL2StartBlock(t) + a.engine.ActL2IncludeTx(a.alice.Address())(t) + a.sequencer.ActL2EndBlock(t) +} + +func (a *L2PlasmaDA) ActNewL2Tx(t Testing) { + a.ActSequencerIncludeTx(t) + + a.batcher.ActL2BatchBuffer(t) + a.batcher.ActL2ChannelClose(t) + a.batcher.ActL2BatchSubmit(t, func(tx *types.DynamicFeeTx) { + // skip txdata version byte + a.lastComm = tx.Data[1:] + }) + + a.miner.ActL1StartBlock(12)(t) + a.miner.ActL1IncludeTx(a.dp.Addresses.Batcher)(t) + a.miner.ActL1EndBlock(t) + + a.lastCommBn = a.miner.l1Chain.CurrentBlock().Number.Uint64() +} + +func (a *L2PlasmaDA) ActDeleteLastInput(t Testing) { + require.NoError(t, a.storage.Client.DeleteData(a.lastComm)) +} + +func (a *L2PlasmaDA) ActChallengeLastInput(t Testing) { + a.ActChallengeInput(t, a.lastComm, a.lastCommBn) + + a.log.Info("challenged last input", "block", a.lastCommBn) +} + +func (a *L2PlasmaDA) ActChallengeInput(t Testing, comm []byte, bn uint64) { + bondValue, err := a.contract.BondSize(&bind.CallOpts{}) + require.NoError(t, err) + + txOpts, err := bind.NewKeyedTransactorWithChainID(a.dp.Secrets.Alice, a.sd.L1Cfg.Config.ChainID) + require.NoError(t, err) + + txOpts.Value = bondValue + _, err = a.contract.Deposit(txOpts) + require.NoError(t, err) + + a.miner.ActL1StartBlock(12)(t) + a.miner.ActL1IncludeTx(a.alice.Address())(t) + a.miner.ActL1EndBlock(t) + + txOpts, err = bind.NewKeyedTransactorWithChainID(a.dp.Secrets.Alice, a.sd.L1Cfg.Config.ChainID) + require.NoError(t, err) + + _, err = a.contract.Challenge(txOpts, big.NewInt(int64(bn)), comm) + require.NoError(t, err) + + a.miner.ActL1StartBlock(12)(t) + a.miner.ActL1IncludeTx(a.alice.Address())(t) + a.miner.ActL1EndBlock(t) +} + +func (a *L2PlasmaDA) ActExpireLastInput(t Testing) { + reorgWindow := a.plasmaCfg.ResolveWindow + a.plasmaCfg.ChallengeWindow + for a.miner.l1Chain.CurrentBlock().Number.Uint64() <= a.lastCommBn+reorgWindow { + a.miner.ActL1StartBlock(12)(t) + a.miner.ActL1EndBlock(t) + } +} + +func (a *L2PlasmaDA) ActResolveInput(t Testing, comm []byte, input []byte, bn uint64) { + txOpts, err := bind.NewKeyedTransactorWithChainID(a.dp.Secrets.Alice, a.sd.L1Cfg.Config.ChainID) + require.NoError(t, err) + + _, err = a.contract.Resolve(txOpts, big.NewInt(int64(bn)), comm, input) + require.NoError(t, err) + + a.miner.ActL1StartBlock(12)(t) + a.miner.ActL1IncludeTx(a.alice.Address())(t) + a.miner.ActL1EndBlock(t) +} + +func (a *L2PlasmaDA) ActResolveLastChallenge(t Testing) { + // remove derivation byte prefix + input, err := a.storage.GetInput(t.Ctx(), a.lastComm[1:]) + require.NoError(t, err) + + a.ActResolveInput(t, a.lastComm, input, a.lastCommBn) +} + +func (a *L2PlasmaDA) ActL1Blocks(t Testing, n uint64) { + for i := uint64(0); i < n; i++ { + a.miner.ActL1StartBlock(12)(t) + a.miner.ActL1EndBlock(t) + } +} + +func (a *L2PlasmaDA) GetLastTxBlock(t Testing) *types.Block { + rcpt, err := a.engine.EthClient().TransactionReceipt(t.Ctx(), a.alice.L2.lastTxHash) + require.NoError(t, err) + blk, err := a.engine.EthClient().BlockByHash(t.Ctx(), rcpt.BlockHash) + require.NoError(t, err) + return blk +} + +func (a *L2PlasmaDA) ActL1Finalized(t Testing) { + latest := a.miner.l1Chain.CurrentBlock().Number.Uint64() + a.miner.ActL1Safe(t, latest) + a.miner.ActL1Finalize(t, latest) + a.sequencer.ActL1FinalizedSignal(t) +} + +// Commitment is challenged but never resolved, chain reorgs when challenge window expires. +func TestPlasma_ChallengeExpired(gt *testing.T) { + if !e2eutils.UsePlasma() { + gt.Skip("Plasma is not enabled") + } + + t := NewDefaultTesting(gt) + harness := NewL2PlasmaDA(t) + + // generate enough initial l1 blocks to have a finalized head. + harness.ActL1Blocks(t, 5) + + // Include a new l2 transaction, submitting an input commitment to the l1. + harness.ActNewL2Tx(t) + + // Challenge the input commitment on the l1 challenge contract. + harness.ActChallengeLastInput(t) + + blk := harness.GetLastTxBlock(t) + + // catch up the sequencer derivation pipeline with the new l1 blocks. + harness.sequencer.ActL2PipelineFull(t) + + // create enough l1 blocks to expire the resolve window. + harness.ActExpireLastInput(t) + + // catch up the sequencer derivation pipeline with the new l1 blocks. + harness.sequencer.ActL2PipelineFull(t) + + // the L1 finalized signal should trigger plasma to finalize the engine queue. + harness.ActL1Finalized(t) + + // move one more block for engine controller to update. + harness.ActL1Blocks(t, 1) + harness.sequencer.ActL2PipelineFull(t) + + // get new block with same number to compare + newBlk, err := harness.engine.EthClient().BlockByNumber(t.Ctx(), blk.Number()) + require.NoError(t, err) + + // reorg happened even though data was available + require.NotEqual(t, blk.Hash(), newBlk.Hash()) + + // now delete the data from the storage service so it is not available at all + // to the verifier derivation pipeline. + harness.ActDeleteLastInput(t) + + syncStatus := harness.sequencer.SyncStatus() + + // verifier is able to sync with expired missing data + verifier := harness.NewVerifier(t) + verifier.ActL2PipelineFull(t) + verifier.ActL1FinalizedSignal(t) + + verifSyncStatus := verifier.SyncStatus() + + require.Equal(t, syncStatus.FinalizedL2, verifSyncStatus.FinalizedL2) +} + +// Commitment is challenged after sequencer derived the chain but data disappears. A verifier +// derivation pipeline stalls until the challenge is resolved and then resumes with data from the contract. +func TestPlasma_ChallengeResolved(gt *testing.T) { + if !e2eutils.UsePlasma() { + gt.Skip("Plasma is not enabled") + } + + t := NewDefaultTesting(gt) + harness := NewL2PlasmaDA(t) + + // include a new l2 transaction, submitting an input commitment to the l1. + harness.ActNewL2Tx(t) + + // generate 3 l1 blocks. + harness.ActL1Blocks(t, 3) + + // challenge the input commitment for that l2 transaction on the l1 challenge contract. + harness.ActChallengeLastInput(t) + + // catch up sequencer derivation pipeline. + // this syncs the latest event within the AltDA manager. + harness.sequencer.ActL2PipelineFull(t) + + // resolve the challenge on the l1 challenge contract. + harness.ActResolveLastChallenge(t) + + // catch up the sequencer derivation pipeline with the new l1 blocks. + // this syncs the resolved status and input data within the AltDA manager. + harness.sequencer.ActL2PipelineFull(t) + + // finalize l1 + harness.ActL1Finalized(t) + + // delete the data from the storage service so it is not available at all + // to the verifier derivation pipeline. + harness.ActDeleteLastInput(t) + + syncStatus := harness.sequencer.SyncStatus() + + // new verifier is able to sync and resolve the input from calldata + verifier := harness.NewVerifier(t) + verifier.ActL2PipelineFull(t) + verifier.ActL1FinalizedSignal(t) + + verifSyncStatus := verifier.SyncStatus() + + require.Equal(t, syncStatus.SafeL2, verifSyncStatus.SafeL2) +} + +// DA storage service goes offline while sequencer keeps making blocks. When storage comes back online, it should be able to catch up. +func TestPlasma_StorageError(gt *testing.T) { + if !e2eutils.UsePlasma() { + gt.Skip("Plasma is not enabled") + } + + t := NewDefaultTesting(gt) + harness := NewL2PlasmaDA(t) + + // include a new l2 transaction, submitting an input commitment to the l1. + harness.ActNewL2Tx(t) + + txBlk := harness.GetLastTxBlock(t) + + // mock a storage client error when trying to get the pre-image. + // this simulates the storage service going offline for example. + harness.storage.ActGetPreImageFail() + + // try to derive the l2 chain from the submitted inputs commitments. + // the storage call will fail the first time then succeed. + harness.sequencer.ActL2PipelineFull(t) + + // sequencer derivation was able to sync to latest l1 origin + syncStatus := harness.sequencer.SyncStatus() + require.Equal(t, uint64(1), syncStatus.SafeL2.Number) + require.Equal(t, txBlk.Hash(), syncStatus.SafeL2.Hash) +} + +// L1 chain reorgs a resolved challenge so it expires instead causing +// the l2 chain to reorg as well. +func TestPlasma_ChallengeReorg(gt *testing.T) { + if !e2eutils.UsePlasma() { + gt.Skip("Plasma is not enabled") + } + + t := NewDefaultTesting(gt) + harness := NewL2PlasmaDA(t) + + // New L2 tx added to a batch and committed to L1 + harness.ActNewL2Tx(t) + + // add a buffer of L1 blocks + harness.ActL1Blocks(t, 3) + + // challenge the input commitment + harness.ActChallengeLastInput(t) + + // keep track of the block where the L2 tx was included + blk := harness.GetLastTxBlock(t) + + // progress derivation pipeline + harness.sequencer.ActL2PipelineFull(t) + + // resolve the challenge so pipeline can progress + harness.ActResolveLastChallenge(t) + + // derivation marks the challenge as resolve, chain is not impacted + harness.sequencer.ActL2PipelineFull(t) + + // Rewind the L1, essentially reorging the challenge resolution + harness.miner.ActL1RewindToParent(t) + + // Now the L1 chain advances without the challenge resolution + // so the challenge is expired. + harness.ActExpireLastInput(t) + + // derivation pipeline reorgs the commitment out of the chain + harness.sequencer.ActL2PipelineFull(t) + + newBlk, err := harness.engine.EthClient().BlockByNumber(t.Ctx(), blk.Number()) + require.NoError(t, err) + + // confirm the reorg did happen + require.NotEqual(t, blk.Hash(), newBlk.Hash()) +} + +// Sequencer stalls as data is not available, batcher keeps posting, untracked commitments are +// challenged and resolved, then sequencer resumes and catches up. +func TestPlasma_SequencerStalledMultiChallenges(gt *testing.T) { + if !e2eutils.UsePlasma() { + gt.Skip("Plasma is not enabled") + } + + t := NewDefaultTesting(gt) + a := NewL2PlasmaDA(t) + + // generate some initial L1 blocks. + a.ActL1Blocks(t, 5) + a.sequencer.ActL1HeadSignal(t) + + // create a new tx on l2 and commit it to l1 + a.ActNewL2Tx(t) + + // keep track of the related commitment + comm1 := a.lastComm + input1, err := a.storage.GetInput(t.Ctx(), comm1[1:]) + bn1 := a.lastCommBn + require.NoError(t, err) + + // delete it from the DA provider so the pipeline cannot verify it + a.ActDeleteLastInput(t) + + // build more empty l2 unsafe blocks as the l1 origin progresses + a.ActL1Blocks(t, 10) + a.sequencer.ActBuildToL1HeadUnsafe(t) + + // build another L2 block without advancing derivation + a.alice.L2.ActResetTxOpts(t) + a.alice.L2.ActSetTxToAddr(&a.dp.Addresses.Bob)(t) + a.alice.L2.ActMakeTx(t) + + a.sequencer.ActL2StartBlock(t) + a.engine.ActL2IncludeTx(a.alice.Address())(t) + a.sequencer.ActL2EndBlock(t) + + a.batcher.ActL2BatchBuffer(t) + a.batcher.ActL2ChannelClose(t) + a.batcher.ActL2BatchSubmit(t, func(tx *types.DynamicFeeTx) { + a.lastComm = tx.Data[1:] + }) + + // include it in L1 + a.miner.ActL1StartBlock(120)(t) + a.miner.ActL1IncludeTx(a.dp.Addresses.Batcher)(t) + a.miner.ActL1EndBlock(t) + + a.sequencer.ActL1HeadSignal(t) + + unsafe := a.sequencer.L2Unsafe() + unsafeBlk, err := a.engine.EthClient().BlockByHash(t.Ctx(), unsafe.Hash) + require.NoError(t, err) + + // advance the pipeline until it errors out as it is still stuck + // on deriving the first commitment + for i := 0; i < 3; i++ { + a.sequencer.ActL2PipelineStep(t) + } + + // keep track of the second commitment + comm2 := a.lastComm + _, err = a.storage.GetInput(t.Ctx(), comm2[1:]) + require.NoError(t, err) + a.lastCommBn = a.miner.l1Chain.CurrentBlock().Number.Uint64() + + // ensure the second commitment is distinct from the first + require.NotEqual(t, comm1, comm2) + + // challenge the last commitment while the pipeline is stuck on the first + a.ActChallengeLastInput(t) + + // resolve the latest commitment before the first one is event challenged. + a.ActResolveLastChallenge(t) + + // now we delete it to force the pipeline to resolve the second commitment + // from the challenge data. + a.ActDeleteLastInput(t) + + // finally challenge the first commitment + a.ActChallengeInput(t, comm1, bn1) + + // resolve it immediately so we can resume derivation + a.ActResolveInput(t, comm1, input1, bn1) + + // pipeline can go on + a.sequencer.ActL2PipelineFull(t) + + // verify that the chain did not reorg out + safeBlk, err := a.engine.EthClient().BlockByNumber(t.Ctx(), unsafeBlk.Number()) + require.NoError(t, err) + require.Equal(t, unsafeBlk.Hash(), safeBlk.Hash()) +} + +// Verify that finalization happens based on plasma DA windows. +// based on l2_batcher_test.go L2Finalization +func TestPlasma_Finalization(gt *testing.T) { + if !e2eutils.UsePlasma() { + gt.Skip("Plasma is not enabled") + } + t := NewDefaultTesting(gt) + a := NewL2PlasmaDA(t) + + // build L1 block #1 + a.ActL1Blocks(t, 1) + a.miner.ActL1SafeNext(t) + + // Fill with l2 blocks up to the L1 head + a.sequencer.ActL1HeadSignal(t) + a.sequencer.ActBuildToL1Head(t) + + a.sequencer.ActL2PipelineFull(t) + a.sequencer.ActL1SafeSignal(t) + require.Equal(t, uint64(1), a.sequencer.SyncStatus().SafeL1.Number) + + // add L1 block #2 + a.ActL1Blocks(t, 1) + a.miner.ActL1SafeNext(t) + a.miner.ActL1FinalizeNext(t) + a.sequencer.ActL1HeadSignal(t) + a.sequencer.ActBuildToL1Head(t) + + // Catch up derivation + a.sequencer.ActL2PipelineFull(t) + a.sequencer.ActL1FinalizedSignal(t) + a.sequencer.ActL1SafeSignal(t) + + // commit all the l2 blocks to L1 + a.batcher.ActSubmitAll(t) + a.miner.ActL1StartBlock(12)(t) + a.miner.ActL1IncludeTx(a.dp.Addresses.Batcher)(t) + a.miner.ActL1EndBlock(t) + + // verify + a.sequencer.ActL2PipelineFull(t) + + // fill with more unsafe L2 blocks + a.sequencer.ActL1HeadSignal(t) + a.sequencer.ActBuildToL1Head(t) + + // submit those blocks too, block #4 + a.batcher.ActSubmitAll(t) + a.miner.ActL1StartBlock(12)(t) + a.miner.ActL1IncludeTx(a.dp.Addresses.Batcher)(t) + a.miner.ActL1EndBlock(t) + + // add some more L1 blocks #5, #6 + a.miner.ActEmptyBlock(t) + a.miner.ActEmptyBlock(t) + + // and more unsafe L2 blocks + a.sequencer.ActL1HeadSignal(t) + a.sequencer.ActBuildToL1Head(t) + + // move safe/finalize markers: finalize the L1 chain block with the first batch, but not the second + a.miner.ActL1SafeNext(t) // #2 -> #3 + a.miner.ActL1SafeNext(t) // #3 -> #4 + a.miner.ActL1FinalizeNext(t) // #1 -> #2 + a.miner.ActL1FinalizeNext(t) // #2 -> #3 + + // L1 safe and finalized as expected + a.sequencer.ActL2PipelineFull(t) + a.sequencer.ActL1FinalizedSignal(t) + a.sequencer.ActL1SafeSignal(t) + a.sequencer.ActL1HeadSignal(t) + require.Equal(t, uint64(6), a.sequencer.SyncStatus().HeadL1.Number) + require.Equal(t, uint64(4), a.sequencer.SyncStatus().SafeL1.Number) + require.Equal(t, uint64(3), a.sequencer.SyncStatus().FinalizedL1.Number) + // l2 cannot finalize yet as the challenge window is not passed + require.Equal(t, uint64(0), a.sequencer.SyncStatus().FinalizedL2.Number) + + // expire the challenge window so these blocks can no longer be challenged + a.ActL1Blocks(t, a.plasmaCfg.ChallengeWindow) + + // advance derivation and finalize plasma via the L1 signal + a.sequencer.ActL2PipelineFull(t) + a.ActL1Finalized(t) + + // given 12s l1 time and 1s l2 time, l2 should be 12 * 3 = 36 blocks finalized + require.Equal(t, uint64(36), a.sequencer.SyncStatus().FinalizedL2.Number) +} diff --git a/op-e2e/actions/reorg_test.go b/op-e2e/actions/reorg_test.go index bf8cf8a92ba5..1b4edbaf9cfe 100644 --- a/op-e2e/actions/reorg_test.go +++ b/op-e2e/actions/reorg_test.go @@ -7,6 +7,7 @@ import ( "testing" "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/eth/ethconfig" "github.com/ethereum/go-ethereum/log" @@ -15,17 +16,19 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + plasma "github.com/ethereum-optimism/optimism/op-plasma" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func setupReorgTest(t Testing, config *e2eutils.TestParams) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) { +func setupReorgTest(t Testing, config *e2eutils.TestParams, deltaTimeOffset *hexutil.Uint64) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) { dp := e2eutils.MakeDeployParams(t, config) + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) return setupReorgTestActors(t, dp, sd, log) } @@ -34,19 +37,45 @@ func setupReorgTestActors(t Testing, dp *e2eutils.DeployParams, sd *e2eutils.Set miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) sequencer.ActL2PipelineFull(t) - verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) rollupSeqCl := sequencer.RollupClient() - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) return sd, dp, miner, sequencer, seqEngine, verifier, verifEngine, batcher } -func TestReorgOrphanBlock(gt *testing.T) { +// TestReorgBatchType run each reorg-related test case in singular batch mode and span batch mode. +func TestReorgBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, deltaTimeOffset *hexutil.Uint64) + }{ + {"ReorgOrphanBlock", ReorgOrphanBlock}, + {"ReorgFlipFlop", ReorgFlipFlop}, + {"DeepReorg", DeepReorg}, + {"RestartOpGeth", RestartOpGeth}, + {"ConflictingL2Blocks", ConflictingL2Blocks}, + {"SyncAfterReorg", SyncAfterReorg}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + deltaTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &deltaTimeOffset) + }) + } +} + +func ReorgOrphanBlock(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams) + sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams, deltaTimeOffset) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) sequencer.ActL2PipelineFull(t) @@ -112,9 +141,9 @@ func TestReorgOrphanBlock(gt *testing.T) { require.Equal(t, verifier.L2Safe(), sequencer.L2Safe(), "verifier and sequencer see same safe L2 block, while only verifier dealt with the orphan and replay") } -func TestReorgFlipFlop(gt *testing.T) { +func ReorgFlipFlop(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams) + sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams, deltaTimeOffset) minerCl := miner.L1Client(t, sd.RollupCfg) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) checkVerifEngine := func() { @@ -189,8 +218,16 @@ func TestReorgFlipFlop(gt *testing.T) { verifier.ActL2PipelineFull(t) require.Equal(t, sd.RollupCfg.Genesis.L1, verifier.L2Safe().L1Origin, "expected to be back at genesis origin after losing A0 and A1") - require.NotZero(t, verifier.L2Safe().Number, "still preserving old L2 blocks that did not reference reorged L1 chain (assuming more than one L2 block per L1 block)") - require.Equal(t, verifier.L2Safe(), verifier.L2Unsafe(), "head is at safe block after L1 reorg") + if sd.RollupCfg.DeltaTime == nil { + // before delta hard fork + require.NotZero(t, verifier.L2Safe().Number, "still preserving old L2 blocks that did not reference reorged L1 chain (assuming more than one L2 block per L1 block)") + require.Equal(t, verifier.L2Safe(), verifier.L2Unsafe(), "head is at safe block after L1 reorg") + } else { + // after delta hard fork + require.Zero(t, verifier.L2Safe().Number, "safe head is at genesis block because span batch referenced reorged L1 chain is not accepted") + require.Equal(t, verifier.L2Unsafe().ID(), sequencer.L2Unsafe().ParentID(), "head is at the highest unsafe block that references canonical L1 chain(genesis block)") + batcher.l2BufferedBlock = eth.L2BlockRef{} // must reset batcher to resubmit blocks included in the last batch + } checkVerifEngine() // and sync the sequencer, then build some new L2 blocks, up to and including with L1 origin B2 @@ -210,6 +247,7 @@ func TestReorgFlipFlop(gt *testing.T) { verifier.ActL1HeadSignal(t) verifier.ActL2PipelineFull(t) require.Equal(t, verifier.L2Safe().L1Origin, blockB2.ID(), "B2 is the L1 origin of verifier now") + require.Equal(t, verifier.L2Unsafe(), sequencer.L2Unsafe(), "verifier unsafe head is reorged along sequencer") checkVerifEngine() // Flop back to chain A! @@ -290,7 +328,7 @@ func TestReorgFlipFlop(gt *testing.T) { // 12. Sync the verifier and assert that the L2 safe head L1 origin has caught up with chain B // 13. Ensure that the parent L2 block of the block that contains Alice's transaction still exists // after the L2 has re-derived from chain B. -// 14. Ensure that the L2 block that contained Alice's transction before the reorg no longer exists. +// 14. Ensure that the L2 block that contained Alice's transaction before the reorg no longer exists. // // Chain A // - 61 blocks total @@ -324,7 +362,7 @@ func TestReorgFlipFlop(gt *testing.T) { // Verifier // - Unsafe head is 62 // - Safe head is 42 -func TestDeepReorg(gt *testing.T) { +func DeepReorg(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) // Create actor and verification engine client @@ -333,7 +371,7 @@ func TestDeepReorg(gt *testing.T) { SequencerWindowSize: 20, ChannelTimeout: 120, L1BlockTime: 4, - }) + }, deltaTimeOffset) minerCl := miner.L1Client(t, sd.RollupCfg) l2Client := seqEngine.EthClient() verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) @@ -344,7 +382,7 @@ func TestDeepReorg(gt *testing.T) { } // Set up alice - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) addresses := e2eutils.CollectAddresses(sd, dp) l2UserEnv := &BasicUserEnv[*L2Bindings]{ EthCl: l2Client, @@ -557,9 +595,9 @@ type rpcWrapper struct { client.RPC } -// TestRestartOpGeth tests that the sequencer can restart its execution engine without rollup-node restart, +// RestartOpGeth tests that the sequencer can restart its execution engine without rollup-node restart, // including recovering the finalized/safe state of L2 chain without reorging. -func TestRestartOpGeth(gt *testing.T) { +func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dbPath := path.Join(t.TempDir(), "testdb") dbOption := func(_ *ethconfig.Config, nodeCfg *node.Config) error { @@ -567,8 +605,9 @@ func TestRestartOpGeth(gt *testing.T) { return nil } dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) jwtPath := e2eutils.WriteDefaultJWT(t) // L1 miner := NewL1Miner(t, log, sd.L1Cfg) @@ -579,13 +618,10 @@ func TestRestartOpGeth(gt *testing.T) { engRpc := &rpcWrapper{seqEng.RPCClient()} l2Cl, err := sources.NewEngineClient(engRpc, log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) - sequencer := NewL2Sequencer(t, log, l1F, l2Cl, sd.RollupCfg, 0) + sequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), plasma.Disabled, l2Cl, sd.RollupCfg, 0) - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) // start sequencer.ActL2PipelineFull(t) @@ -651,14 +687,15 @@ func TestRestartOpGeth(gt *testing.T) { require.Equal(t, statusBeforeRestart.SafeL2, sequencer.L2Safe(), "expecting the safe block to catch up to what it was before shutdown after syncing from L1, and not be stuck at the finalized block") } -// TestConflictingL2Blocks tests that a second copy of the sequencer stack cannot introduce an alternative +// ConflictingL2Blocks tests that a second copy of the sequencer stack cannot introduce an alternative // L2 block (compared to something already secured by the first sequencer): // the alt block is not synced by the verifier, in unsafe and safe sync modes. -func TestConflictingL2Blocks(gt *testing.T) { +func ConflictingL2Blocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) sd, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) @@ -669,12 +706,9 @@ func TestConflictingL2Blocks(gt *testing.T) { require.NoError(t, err) l1F, err := sources.NewL1Client(miner.RPCClient(), log, nil, sources.L1ClientDefaultConfig(sd.RollupCfg, false, sources.RPCKindStandard)) require.NoError(t, err) - altSequencer := NewL2Sequencer(t, log, l1F, altSeqEngCl, sd.RollupCfg, 0) - altBatcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, altSequencer.RollupClient(), miner.EthClient(), altSeqEng.EthClient()) + altSequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), plasma.Disabled, altSeqEngCl, sd.RollupCfg, 0) + altBatcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + altSequencer.RollupClient(), miner.EthClient(), altSeqEng.EthClient(), altSeqEng.EngineClient(t, sd.RollupCfg)) // And set up user Alice, using the alternative sequencer endpoint l2Cl := altSeqEng.EthClient() @@ -762,3 +796,108 @@ func TestConflictingL2Blocks(gt *testing.T) { require.Equal(t, verifier.L2Unsafe(), altSequencer.L2Unsafe(), "alt-sequencer gets back in harmony with verifier by reorging out its conflicting data") require.Equal(t, sequencer.L2Unsafe(), altSequencer.L2Unsafe(), "and gets back in harmony with original sequencer") } + +func SyncAfterReorg(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { + t := NewDefaultTesting(gt) + testingParams := e2eutils.TestParams{ + MaxSequencerDrift: 60, + SequencerWindowSize: 4, + ChannelTimeout: 2, + L1BlockTime: 12, + } + sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := setupReorgTest(t, &testingParams, deltaTimeOffset) + l2Client := seqEngine.EthClient() + log := testlog.Logger(t, log.LevelDebug) + addresses := e2eutils.CollectAddresses(sd, dp) + l2UserEnv := &BasicUserEnv[*L2Bindings]{ + EthCl: l2Client, + Signer: types.LatestSigner(sd.L2Cfg.Config), + AddressCorpora: addresses, + Bindings: NewL2Bindings(t, l2Client, seqEngine.GethClient()), + } + alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) + alice.L2.SetUserEnv(l2UserEnv) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // build empty L1 block: A0 + miner.ActL1SetFeeRecipient(common.Address{'A', 0}) + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + for sequencer.engine.UnsafeL2Head().L1Origin.Number < sequencer.l1State.L1Head().Number { + // build L2 blocks until the L1 origin is the current L1 head(A0) + sequencer.ActL2PipelineFull(t) + sequencer.ActL2StartBlock(t) + if sequencer.engine.UnsafeL2Head().Number == 11 { + // include a user tx at L2 block #12 to make a state transition + alice.L2.ActResetTxOpts(t) + alice.L2.ActSetTxToAddr(&dp.Addresses.Bob)(t) + alice.L2.ActMakeTx(t) + // Include the tx in the block we're making + seqEngine.ActL2IncludeTx(alice.Address())(t) + } + sequencer.ActL2EndBlock(t) + } + // submit all new L2 blocks: #1 ~ #12 + batcher.ActSubmitAll(t) + + // build an L1 block included batch TX: A1 + miner.ActL1SetFeeRecipient(common.Address{'A', 1}) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) + miner.ActL1EndBlock(t) + + for i := 2; i < 6; i++ { + // build L2 blocks until the L1 origin is the current L1 head + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + // submt all new L2 blocks + batcher.ActSubmitAll(t) + + // build an L1 block included batch TX: A2 ~ A5 + miner.ActL1SetFeeRecipient(common.Address{'A', byte(i)}) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) + miner.ActL1EndBlock(t) + } + + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + // capture current L2 safe head + submittedSafeHead := sequencer.L2Safe().ID() + + // build L2 blocks until the L1 origin is the current L1 head(A5) + sequencer.ActBuildToL1Head(t) + batcher.ActSubmitAll(t) + + // build an L1 block included batch TX: A6 + miner.ActL1SetFeeRecipient(common.Address{'A', 6}) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) + miner.ActL1EndBlock(t) + + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + // reorg L1 + miner.ActL1RewindToParent(t) // undo A6 + miner.ActL1SetFeeRecipient(common.Address{'B', 6}) // build B6 + miner.ActEmptyBlock(t) + miner.ActL1SetFeeRecipient(common.Address{'B', 7}) // build B7 + miner.ActEmptyBlock(t) + + // sequencer and verifier detect L1 reorg + // derivation pipeline is reset + // safe head may be reset to block #11 + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + // sequencer and verifier must derive all submitted batches and reach to the captured block + require.Equal(t, sequencer.L2Safe().ID(), submittedSafeHead) + require.Equal(t, verifier.L2Safe().ID(), submittedSafeHead) +} diff --git a/op-e2e/actions/safedb_test.go b/op-e2e/actions/safedb_test.go new file mode 100644 index 000000000000..9fd570fa79f5 --- /dev/null +++ b/op-e2e/actions/safedb_test.go @@ -0,0 +1,140 @@ +package actions + +import ( + "context" + "testing" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestRecordSafeHeadUpdates(gt *testing.T) { + t := NewDefaultTesting(gt) + sd, miner, sequencer, verifier, verifierEng, batcher := setupSafeDBTest(t, defaultRollupTestParams) + verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // build empty L1 block + miner.ActEmptyBlock(t) + + // Create L2 blocks, and reference the L1 head as origin + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + + // submit all new L2 blocks + batcher.ActSubmitAll(t) + + // new L1 block with L2 batch + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) + batchTx := miner.l1Transactions[0] + miner.ActL1EndBlock(t) + + // verifier picks up the L2 chain that was submitted + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Safe(), sequencer.L2Unsafe(), "verifier syncs from sequencer via L1") + require.NotEqual(t, sequencer.L2Safe(), sequencer.L2Unsafe(), "sequencer has not processed L1 yet") + + // Verify the safe head is recorded + l1Head := miner.l1Chain.CurrentBlock() + firstSafeHeadUpdateL1Block := l1Head.Number.Uint64() + response, err := verifier.RollupClient().SafeHeadAtL1Block(context.Background(), firstSafeHeadUpdateL1Block) + require.NoError(t, err) + require.Equal(t, eth.HeaderBlockID(l1Head), response.L1Block) + require.Equal(t, verifier.L2Unsafe().ID(), response.SafeHead) + + // Should get the same result for anything after that L1 block too + response, err = verifier.RollupClient().SafeHeadAtL1Block(context.Background(), firstSafeHeadUpdateL1Block+1) + require.NoError(t, err) + require.Equal(t, eth.HeaderBlockID(l1Head), response.L1Block) + require.Equal(t, verifier.L2Unsafe().ID(), response.SafeHead) + + // Only genesis is safe at this point + response, err = verifier.RollupClient().SafeHeadAtL1Block(context.Background(), firstSafeHeadUpdateL1Block-1) + require.NoError(t, err) + require.Equal(t, eth.HeaderBlockID(miner.l1Chain.Genesis().Header()), response.L1Block) + require.Equal(t, sd.RollupCfg.Genesis.L2, response.SafeHead) + + // orphan the L1 block that included the batch tx, and build a new different L1 block + miner.ActL1RewindToParent(t) + miner.ActL1SetFeeRecipient(common.Address{'B'}) + miner.ActEmptyBlock(t) + miner.ActEmptyBlock(t) // needs to be a longer chain for reorg to be applied. + + // sync verifier again. The L1 reorg excluded the batch, so now the previous L2 chain should be unsafe again. + // However, the L2 chain can still be canonical later, since it did not reference the reorged L1 block + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Safe(), sequencer.L2Safe(), "verifier rewinds safe when L1 reorgs out batch") + ref, err := verifEngClient.L2BlockRefByLabel(t.Ctx(), eth.Safe) + require.NoError(t, err) + require.Equal(t, verifier.L2Safe(), ref, "verifier engine matches rollup client") + + // The safe head has been reorged so the record should have been deleted, leaving us back with just genesis safe + response, err = verifier.RollupClient().SafeHeadAtL1Block(context.Background(), firstSafeHeadUpdateL1Block) + require.NoError(t, err) + require.Equal(t, eth.HeaderBlockID(miner.l1Chain.Genesis().Header()), response.L1Block) + require.Equal(t, sd.RollupCfg.Genesis.L2, response.SafeHead) + + // Now replay the batch tx in a new L1 block + miner.ActL1StartBlock(12)(t) + miner.ActL1SetFeeRecipient(common.Address{'C'}) + // note: the geth tx pool reorgLoop is too slow (responds to chain head events, but async), + // and there's no way to manually trigger runReorg, so we re-insert it ourselves. + require.NoError(t, miner.eth.TxPool().Add([]*types.Transaction{batchTx}, true, true)[0]) + // need to re-insert previously included tx into the block + miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) + miner.ActL1EndBlock(t) + + // sync the verifier again: now it should be safe again + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Safe(), sequencer.L2Unsafe(), "verifier syncs from sequencer via replayed batch on L1") + ref, err = verifEngClient.L2BlockRefByLabel(t.Ctx(), eth.Safe) + require.NoError(t, err) + require.Equal(t, verifier.L2Safe(), ref, "verifier engine matches rollup client") + + // Verify the safe head is recorded again + l1Head = miner.l1Chain.CurrentBlock() + firstSafeHeadUpdateL1Block = l1Head.Number.Uint64() + response, err = verifier.RollupClient().SafeHeadAtL1Block(context.Background(), firstSafeHeadUpdateL1Block) + require.NoError(t, err) + require.Equal(t, eth.HeaderBlockID(l1Head), response.L1Block) + require.Equal(t, verifier.L2Unsafe().ID(), response.SafeHead) +} + +func setupSafeDBTest(t Testing, config *e2eutils.TestParams) (*e2eutils.SetupData, *L1Miner, *L2Sequencer, *L2Verifier, *L2Engine, *L2Batcher) { + dp := e2eutils.MakeDeployParams(t, config) + + sd := e2eutils.Setup(t, dp, defaultAlloc) + logger := testlog.Logger(t, log.LevelDebug) + + return setupSafeDBTestActors(t, dp, sd, logger) +} + +func setupSafeDBTestActors(t Testing, dp *e2eutils.DeployParams, sd *e2eutils.SetupData, log log.Logger) (*e2eutils.SetupData, *L1Miner, *L2Sequencer, *L2Verifier, *L2Engine, *L2Batcher) { + dir := t.TempDir() + db, err := safedb.NewSafeDB(log, dir) + require.NoError(t, err) + t.Cleanup(func() { + _ = db.Close() + }) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + miner.ActL1SetFeeRecipient(common.Address{'A'}) + sequencer.ActL2PipelineFull(t) + verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}, WithSafeHeadListener(db)) + rollupSeqCl := sequencer.RollupClient() + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + return sd, miner, sequencer, verifier, verifEngine, batcher +} diff --git a/op-e2e/actions/span_batch_test.go b/op-e2e/actions/span_batch_test.go new file mode 100644 index 000000000000..ce3a48fd2386 --- /dev/null +++ b/op-e2e/actions/span_batch_test.go @@ -0,0 +1,714 @@ +package actions + +import ( + "crypto/ecdsa" + crand "crypto/rand" + "fmt" + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + "github.com/ethereum-optimism/optimism/op-service/testlog" +) + +// TestDropSpanBatchBeforeHardfork tests behavior of op-node before Delta hardfork. +// op-node must drop SpanBatch before Delta hardfork. +func TestDropSpanBatchBeforeHardfork(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + dp := e2eutils.MakeDeployParams(t, p) + // do not activate Delta hardfork for verifier + dp.DeployConfig.L2GenesisDeltaTimeOffset = nil + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelError) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + rollupSeqCl := sequencer.RollupClient() + + // Force batcher to submit SpanBatches to L1. + batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + ForceSubmitSpanBatch: true, + DataAvailabilityType: batcherFlags.CalldataType, + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + + // Alice makes a L2 tx + cl := seqEngine.EthClient() + n, err := cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + signer := types.LatestSigner(sd.L2Cfg.Config) + tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: n, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + Gas: params.TxGas, + To: &dp.Addresses.Bob, + Value: e2eutils.Ether(2), + }) + require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Make L2 block + sequencer.ActL2StartBlock(t) + seqEngine.ActL2IncludeTx(dp.Addresses.Alice)(t) + sequencer.ActL2EndBlock(t) + + // batch submit to L1. batcher should submit span batches. + batcher.ActL2BatchBuffer(t) + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + // confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + bl := miner.l1Chain.CurrentBlock() + log.Info("bl", "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + + // Now make enough L1 blocks that the verifier will have to derive a L2 block + // It will also eagerly derive the block from the batcher + for i := uint64(0); i < sd.RollupCfg.SeqWindowSize; i++ { + miner.ActL1StartBlock(12)(t) + miner.ActL1EndBlock(t) + } + + // try to sync verifier from L1 batch. but verifier should drop every span batch. + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, uint64(1), verifier.SyncStatus().SafeL2.L1Origin.Number) + + verifCl := verifEngine.EthClient() + for i := int64(1); i < int64(verifier.L2Safe().Number); i++ { + block, _ := verifCl.BlockByNumber(t.Ctx(), big.NewInt(i)) + require.NoError(t, err) + // because verifier drops every span batch, it should generate empty blocks. + // so every block has only L1 attribute deposit transaction. + require.Equal(t, block.Transactions().Len(), 1) + } + // check that the tx from alice is not included in verifier's chain + _, _, err = verifCl.TransactionByHash(t.Ctx(), tx.Hash()) + require.ErrorIs(t, err, ethereum.NotFound) +} + +// TestHardforkMiddleOfSpanBatch tests behavior of op-node Delta hardfork. +// If Delta activation time is in the middle of time range of a SpanBatch, op-node must drop the batch. +func TestHardforkMiddleOfSpanBatch(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + dp := e2eutils.MakeDeployParams(t, p) + + // Activate HF in the middle of the first epoch + deltaOffset := hexutil.Uint64(6) + dp.DeployConfig.L2GenesisDeltaTimeOffset = &deltaOffset + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelError) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + minerCl := miner.EthClient() + rollupSeqCl := sequencer.RollupClient() + + // Force batcher to submit SpanBatches to L1. + batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + ForceSubmitSpanBatch: true, + DataAvailabilityType: batcherFlags.CalldataType, + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + + // Alice makes a L2 tx + cl := seqEngine.EthClient() + n, err := cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + signer := types.LatestSigner(sd.L2Cfg.Config) + tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: n, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + Gas: params.TxGas, + To: &dp.Addresses.Bob, + Value: e2eutils.Ether(2), + }) + require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + + // Make a L2 block with the TX + sequencer.ActL2StartBlock(t) + seqEngine.ActL2IncludeTx(dp.Addresses.Alice)(t) + sequencer.ActL2EndBlock(t) + + // HF is not activated yet + unsafeOriginNum := new(big.Int).SetUint64(sequencer.L2Unsafe().L1Origin.Number) + unsafeHeader, err := minerCl.HeaderByNumber(t.Ctx(), unsafeOriginNum) + require.NoError(t, err) + require.False(t, sd.RollupCfg.IsDelta(unsafeHeader.Time)) + + // Make L2 blocks until the next epoch + sequencer.ActBuildToL1Head(t) + + // HF is activated for the last unsafe block + unsafeOriginNum = new(big.Int).SetUint64(sequencer.L2Unsafe().L1Origin.Number) + unsafeHeader, err = minerCl.HeaderByNumber(t.Ctx(), unsafeOriginNum) + require.NoError(t, err) + require.True(t, sd.RollupCfg.IsDelta(unsafeHeader.Time)) + + // Batch submit to L1. batcher should submit span batches. + batcher.ActSubmitAll(t) + + // Confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + bl := miner.l1Chain.CurrentBlock() + log.Info("bl", "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + + // Now make enough L1 blocks that the verifier will have to derive a L2 block + // It will also eagerly derive the block from the batcher + for i := uint64(0); i < sd.RollupCfg.SeqWindowSize; i++ { + miner.ActL1StartBlock(12)(t) + miner.ActL1EndBlock(t) + } + + // Try to sync verifier from L1 batch. but verifier should drop every span batch. + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, uint64(2), verifier.SyncStatus().SafeL2.L1Origin.Number) + + verifCl := verifEngine.EthClient() + for i := int64(1); i < int64(verifier.L2Safe().Number); i++ { + block, _ := verifCl.BlockByNumber(t.Ctx(), big.NewInt(i)) + require.NoError(t, err) + // Because verifier drops every span batch, it should generate empty blocks. + // So every block has only L1 attribute deposit transaction. + require.Equal(t, block.Transactions().Len(), 1) + } + // Check that the tx from alice is not included in verifier's chain + _, _, err = verifCl.TransactionByHash(t.Ctx(), tx.Hash()) + require.ErrorIs(t, err, ethereum.NotFound) +} + +// TestAcceptSingularBatchAfterHardfork tests behavior of op-node after Delta hardfork. +// op-node must accept SingularBatch after Delta hardfork. +func TestAcceptSingularBatchAfterHardfork(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + minTs := hexutil.Uint64(0) + dp := e2eutils.MakeDeployParams(t, p) + + // activate Delta hardfork for verifier. + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelError) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + rollupSeqCl := sequencer.RollupClient() + + // Force batcher to submit SingularBatches to L1. + batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + ForceSubmitSingularBatch: true, + DataAvailabilityType: batcherFlags.CalldataType, + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + + // Alice makes a L2 tx + cl := seqEngine.EthClient() + n, err := cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + signer := types.LatestSigner(sd.L2Cfg.Config) + tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: n, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + Gas: params.TxGas, + To: &dp.Addresses.Bob, + Value: e2eutils.Ether(2), + }) + require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Make L2 block + sequencer.ActL2StartBlock(t) + seqEngine.ActL2IncludeTx(dp.Addresses.Alice)(t) + sequencer.ActL2EndBlock(t) + + // batch submit to L1. batcher should submit singular batches. + batcher.ActL2BatchBuffer(t) + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + // confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + bl := miner.l1Chain.CurrentBlock() + log.Info("bl", "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + + // Now make enough L1 blocks that the verifier will have to derive a L2 block + // It will also eagerly derive the block from the batcher + for i := uint64(0); i < sd.RollupCfg.SeqWindowSize; i++ { + miner.ActL1StartBlock(12)(t) + miner.ActL1EndBlock(t) + } + + // sync verifier from L1 batch in otherwise empty sequence window + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, uint64(1), verifier.SyncStatus().SafeL2.L1Origin.Number) + + // check that the tx from alice made it into the L2 chain + verifCl := verifEngine.EthClient() + vTx, isPending, err := verifCl.TransactionByHash(t.Ctx(), tx.Hash()) + require.NoError(t, err) + require.False(t, isPending) + require.NotNil(t, vTx) +} + +// TestMixOfBatchesAfterHardfork tests behavior of op-node after Delta hardfork. +// op-node must accept SingularBatch and SpanBatch in sequence. +func TestMixOfBatchesAfterHardfork(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + minTs := hexutil.Uint64(0) + dp := e2eutils.MakeDeployParams(t, p) + + // Activate Delta hardfork for verifier. + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelError) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + rollupSeqCl := sequencer.RollupClient() + seqEngCl := seqEngine.EthClient() + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + miner.ActEmptyBlock(t) + + var txHashes [4]common.Hash + for i := 0; i < 4; i++ { + // Alice makes a L2 tx + n, err := seqEngCl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + signer := types.LatestSigner(sd.L2Cfg.Config) + tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: n, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + Gas: params.TxGas, + To: &dp.Addresses.Bob, + Value: e2eutils.Ether(2), + }) + require.NoError(gt, seqEngCl.SendTransaction(t.Ctx(), tx)) + txHashes[i] = tx.Hash() + + // Make L2 block + sequencer.ActL1HeadSignal(t) + sequencer.ActL2StartBlock(t) + seqEngine.ActL2IncludeTx(dp.Addresses.Alice)(t) + sequencer.ActL2EndBlock(t) + sequencer.ActBuildToL1Head(t) + + // Select batcher mode + batcherCfg := BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + ForceSubmitSpanBatch: i%2 == 0, // Submit SpanBatch for odd numbered batches + ForceSubmitSingularBatch: i%2 == 1, // Submit SingularBatch for even numbered batches + DataAvailabilityType: batcherFlags.CalldataType, + } + batcher := NewL2Batcher(log, sd.RollupCfg, &batcherCfg, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + // Submit all new blocks + batcher.ActSubmitAll(t) + + // Confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + } + + // Now make enough L1 blocks that the verifier will have to derive a L2 block + // It will also eagerly derive the block from the batcher + for i := uint64(0); i < sd.RollupCfg.SeqWindowSize; i++ { + miner.ActL1StartBlock(12)(t) + miner.ActL1EndBlock(t) + } + + // Sync verifier from L1 batch in otherwise empty sequence window + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, uint64(5), verifier.SyncStatus().SafeL2.L1Origin.Number) + + // Check that the tx from alice made it into the L2 chain + verifCl := verifEngine.EthClient() + for _, txHash := range txHashes { + vTx, isPending, err := verifCl.TransactionByHash(t.Ctx(), txHash) + require.NoError(t, err) + require.False(t, isPending) + require.NotNil(t, vTx) + } +} + +// TestSpanBatchEmptyChain tests derivation of empty chain using SpanBatch. +func TestSpanBatchEmptyChain(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + dp := e2eutils.MakeDeployParams(t, p) + minTs := hexutil.Uint64(0) + // Activate Delta hardfork + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelError) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + + rollupSeqCl := sequencer.RollupClient() + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + // Make 1200 empty L2 blocks (L1BlockTime / L2BlockTime * 100) + for i := 0; i < 100; i++ { + sequencer.ActBuildToL1Head(t) + + if i%10 == 9 { + // batch submit to L1 + batcher.ActSubmitAll(t) + + // Since the unsafe head could be changed due to the reorg during derivation, save the current unsafe head. + unsafeHead := sequencer.L2Unsafe().ID() + + // confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + + // After derivation pipeline, the safe head must be same as latest unsafe head + // i.e. There must be no reorg during derivation pipeline. + require.Equal(t, sequencer.L2Safe().ID(), unsafeHead) + } else { + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + } + } + + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + require.Equal(t, sequencer.L2Unsafe(), sequencer.L2Safe()) + require.Equal(t, verifier.L2Unsafe(), verifier.L2Safe()) + require.Equal(t, sequencer.L2Safe(), verifier.L2Safe()) +} + +// TestSpanBatchLowThroughputChain tests derivation of low-throughput chain using SpanBatch. +func TestSpanBatchLowThroughputChain(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + dp := e2eutils.MakeDeployParams(t, p) + minTs := hexutil.Uint64(0) + // Activate Delta hardfork + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelError) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) + + rollupSeqCl := sequencer.RollupClient() + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + cl := seqEngine.EthClient() + + const numTestUsers = 5 + var privKeys [numTestUsers]*ecdsa.PrivateKey + var addrs [numTestUsers]common.Address + for i := 0; i < numTestUsers; i++ { + // Create a new test account + privateKey, err := dp.Secrets.Wallet.PrivateKey(accounts.Account{ + URL: accounts.URL{ + Path: fmt.Sprintf("m/44'/60'/0'/0/%d", 10+i), + }, + }) + privKeys[i] = privateKey + addr := crypto.PubkeyToAddress(privateKey.PublicKey) + require.NoError(t, err) + addrs[i] = addr + } + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + miner.ActEmptyBlock(t) + totalTxCount := 0 + // Make 600 L2 blocks (L1BlockTime / L2BlockTime * 50) including 1~3 txs + for i := 0; i < 50; i++ { + for sequencer.engine.UnsafeL2Head().L1Origin.Number < sequencer.l1State.L1Head().Number { + sequencer.ActL2StartBlock(t) + // fill the block with random number of L2 txs + for j := 0; j < rand.Intn(3); j++ { + userIdx := totalTxCount % numTestUsers + signer := types.LatestSigner(sd.L2Cfg.Config) + data := make([]byte, rand.Intn(100)) + _, err := crand.Read(data[:]) // fill with random bytes + require.NoError(t, err) + gas, err := core.IntrinsicGas(data, nil, false, true, true, false) + require.NoError(t, err) + baseFee := seqEngine.l2Chain.CurrentBlock().BaseFee + nonce, err := cl.PendingNonceAt(t.Ctx(), addrs[userIdx]) + require.NoError(t, err) + tx := types.MustSignNewTx(privKeys[userIdx], signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: nonce, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(new(big.Int).Mul(baseFee, big.NewInt(2)), big.NewInt(2*params.GWei)), + Gas: gas, + To: &dp.Addresses.Bob, + Value: big.NewInt(0), + Data: data, + }) + require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + seqEngine.ActL2IncludeTx(addrs[userIdx])(t) + totalTxCount += 1 + } + sequencer.ActL2EndBlock(t) + } + + if i%10 == 9 { + // batch submit to L1 + batcher.ActSubmitAll(t) + + // Since the unsafe head could be changed due to the reorg during derivation, save the current unsafe head. + unsafeHead := sequencer.L2Unsafe().ID() + + // confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + + // After derivation pipeline, the safe head must be same as latest unsafe head + // i.e. There must be no reorg during derivation pipeline. + require.Equal(t, sequencer.L2Safe().ID(), unsafeHead) + } else { + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + } + } + + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + require.Equal(t, sequencer.L2Unsafe(), sequencer.L2Safe()) + require.Equal(t, verifier.L2Unsafe(), verifier.L2Safe()) + require.Equal(t, sequencer.L2Safe(), verifier.L2Safe()) +} + +func TestBatchEquivalence(gt *testing.T) { + t := NewDefaultTesting(gt) + log := testlog.Logger(t, log.LevelError) + + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + // Delta activated deploy config + dp := e2eutils.MakeDeployParams(t, p) + minTs := hexutil.Uint64(0) + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + sdDeltaActivated := e2eutils.Setup(t, dp, defaultAlloc) + + // Delta deactivated deploy config + rcfg := *sdDeltaActivated.RollupCfg + rcfg.DeltaTime = nil + sdDeltaDeactivated := &e2eutils.SetupData{ + L1Cfg: sdDeltaActivated.L1Cfg, + L2Cfg: sdDeltaActivated.L2Cfg, + RollupCfg: &rcfg, + DeploymentsL1: sdDeltaActivated.DeploymentsL1, + } + + // Setup sequencer + miner, seqEngine, sequencer := setupSequencerTest(t, sdDeltaActivated, log) + rollupSeqCl := sequencer.RollupClient() + seqEngCl := seqEngine.EthClient() + + // Setup Delta activated spanVerifier + _, spanVerifier := setupVerifier(t, sdDeltaActivated, log, miner.L1Client(t, sdDeltaActivated.RollupCfg), miner.BlobStore(), &sync.Config{}) + + // Setup Delta deactivated spanVerifier + _, singularVerifier := setupVerifier(t, sdDeltaDeactivated, log, miner.L1Client(t, sdDeltaDeactivated.RollupCfg), miner.BlobStore(), &sync.Config{}) + + // Setup SpanBatcher + spanBatcher := NewL2Batcher(log, sdDeltaActivated.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + ForceSubmitSpanBatch: true, + DataAvailabilityType: batcherFlags.CalldataType, + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sdDeltaActivated.RollupCfg)) + + // Setup SingularBatcher + singularBatcher := NewL2Batcher(log, sdDeltaDeactivated.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + ForceSubmitSingularBatch: true, + DataAvailabilityType: batcherFlags.CalldataType, + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sdDeltaDeactivated.RollupCfg)) + + const numTestUsers = 5 + var privKeys [numTestUsers]*ecdsa.PrivateKey + var addrs [numTestUsers]common.Address + for i := 0; i < numTestUsers; i++ { + // Create a new test account + privateKey, err := dp.Secrets.Wallet.PrivateKey(accounts.Account{ + URL: accounts.URL{ + Path: fmt.Sprintf("m/44'/60'/0'/0/%d", 10+i), + }, + }) + privKeys[i] = privateKey + addr := crypto.PubkeyToAddress(privateKey.PublicKey) + require.NoError(t, err) + addrs[i] = addr + } + + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + totalTxCount := 0 + // Build random blocks + for sequencer.engine.UnsafeL2Head().L1Origin.Number < sequencer.l1State.L1Head().Number { + sequencer.ActL2StartBlock(t) + // fill the block with random number of L2 txs + for j := 0; j < rand.Intn(3); j++ { + userIdx := totalTxCount % numTestUsers + signer := types.LatestSigner(sdDeltaActivated.L2Cfg.Config) + data := make([]byte, rand.Intn(100)) + _, err := crand.Read(data[:]) // fill with random bytes + require.NoError(t, err) + gas, err := core.IntrinsicGas(data, nil, false, true, true, false) + require.NoError(t, err) + baseFee := seqEngine.l2Chain.CurrentBlock().BaseFee + nonce, err := seqEngCl.PendingNonceAt(t.Ctx(), addrs[userIdx]) + require.NoError(t, err) + tx := types.MustSignNewTx(privKeys[userIdx], signer, &types.DynamicFeeTx{ + ChainID: sdDeltaActivated.L2Cfg.Config.ChainID, + Nonce: nonce, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(new(big.Int).Mul(baseFee, big.NewInt(2)), big.NewInt(2*params.GWei)), + Gas: gas, + To: &dp.Addresses.Bob, + Value: big.NewInt(0), + Data: data, + }) + require.NoError(gt, seqEngCl.SendTransaction(t.Ctx(), tx)) + seqEngine.ActL2IncludeTx(addrs[userIdx])(t) + totalTxCount += 1 + } + sequencer.ActL2EndBlock(t) + } + + // Submit SpanBatch + spanBatcher.ActSubmitAll(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + // Run derivation pipeline for verifiers + spanVerifier.ActL1HeadSignal(t) + spanVerifier.ActL2PipelineFull(t) + singularVerifier.ActL1HeadSignal(t) + singularVerifier.ActL2PipelineFull(t) + + // Delta activated spanVerifier must be synced + require.Equal(t, spanVerifier.L2Safe(), sequencer.L2Unsafe()) + // Delta deactivated spanVerifier could not derive SpanBatch + require.Equal(t, singularVerifier.L2Safe().Number, uint64(0)) + + // Submit SingularBatches + singularBatcher.ActSubmitAll(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + // Run derivation pipeline for verifiers + spanVerifier.ActL1HeadSignal(t) + spanVerifier.ActL2PipelineFull(t) + singularVerifier.ActL1HeadSignal(t) + singularVerifier.ActL2PipelineFull(t) + + // Delta deactivated spanVerifier must be synced + require.Equal(t, spanVerifier.L2Safe(), singularVerifier.L2Safe()) +} diff --git a/op-e2e/actions/sync_test.go b/op-e2e/actions/sync_test.go index 07321859579f..9dd1ee838413 100644 --- a/op-e2e/actions/sync_test.go +++ b/op-e2e/actions/sync_test.go @@ -2,23 +2,61 @@ package actions import ( "errors" + "math/big" "math/rand" "testing" + "time" + "github.com/ethereum-optimism/optimism/op-batcher/compressor" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" ) -func TestDerivationWithFlakyL1RPC(gt *testing.T) { +// TestSyncBatchType run each sync test case in singular batch mode and span batch mode. +func TestSyncBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, deltaTimeOffset *hexutil.Uint64) + }{ + {"DerivationWithFlakyL1RPC", DerivationWithFlakyL1RPC}, + {"FinalizeWhileSyncing", FinalizeWhileSyncing}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + deltaTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &deltaTimeOffset) + }) + } +} + +func DerivationWithFlakyL1RPC(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create + log := testlog.Logger(t, log.LevelError) // mute all the temporary derivation errors that we forcefully create _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) rng := rand.New(rand.NewSource(1234)) @@ -53,11 +91,12 @@ func TestDerivationWithFlakyL1RPC(gt *testing.T) { require.Equal(t, sequencer.L2Unsafe(), verifier.L2Safe(), "verifier is synced") } -func TestFinalizeWhileSyncing(gt *testing.T) { +func FinalizeWhileSyncing(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create + log := testlog.Logger(t, log.LevelError) // mute all the temporary derivation errors that we forcefully create _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) sequencer.ActL2PipelineFull(t) @@ -96,11 +135,12 @@ func TestFinalizeWhileSyncing(gt *testing.T) { require.Less(t, verifierStartStatus.FinalizedL2.Number, verifier.SyncStatus().FinalizedL2.Number, "verifier finalized L2 blocks during sync") } +// TestUnsafeSync tests that a verifier properly imports unsafe blocks via gossip. func TestUnsafeSync(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlInfo) + log := testlog.Logger(t, log.LevelInfo) sd, _, _, sequencer, seqEng, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) @@ -119,50 +159,919 @@ func TestUnsafeSync(gt *testing.T) { verifier.ActL2UnsafeGossipReceive(seqHead)(t) // Handle unsafe payload verifier.ActL2PipelineFull(t) - // Verifier must advance its unsafe head and engine sync target. + // Verifier must advance its unsafe head. require.Equal(t, sequencer.L2Unsafe().Hash, verifier.L2Unsafe().Hash) - // Check engine sync target updated. - require.Equal(t, sequencer.L2Unsafe().Hash, sequencer.EngineSyncTarget().Hash) - require.Equal(t, verifier.L2Unsafe().Hash, verifier.EngineSyncTarget().Hash) } } -func TestEngineP2PSync(gt *testing.T) { +func TestBackupUnsafe(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + minTs := hexutil.Uint64(0) + // Activate Delta hardfork + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + dp.DeployConfig.L2BlockTime = 2 + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LvlInfo) + _, dp, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + l2Cl := seqEng.EthClient() + seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) + require.NoError(t, err) + + rng := rand.New(rand.NewSource(1234)) + signer := types.LatestSigner(sd.L2Cfg.Config) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Create block A1 ~ A5 + for i := 0; i < 5; i++ { + // Build a L2 block + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + + // Notify new L2 block to verifier by unsafe gossip + seqHead, err := seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + verifier.ActL2UnsafeGossipReceive(seqHead)(t) + } + + seqHead, err := seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + // eventually correct hash for A5 + targetUnsafeHeadHash := seqHead.ExecutionPayload.BlockHash + + // only advance unsafe head to A5 + require.Equal(t, sequencer.L2Unsafe().Number, uint64(5)) + require.Equal(t, sequencer.L2Safe().Number, uint64(0)) + + // Handle unsafe payload + verifier.ActL2PipelineFull(t) + // only advance unsafe head to A5 + require.Equal(t, verifier.L2Unsafe().Number, uint64(5)) + require.Equal(t, verifier.L2Safe().Number, uint64(0)) + + c, e := compressor.NewRatioCompressor(compressor.Config{ + TargetOutputSize: 128_000, + ApproxComprRatio: 1, + }) + require.NoError(t, e) + spanBatchBuilder := derive.NewSpanBatchBuilder(sd.RollupCfg.Genesis.L2Time, sd.RollupCfg.L2ChainID) + // Create new span batch channel + channelOut, err := derive.NewChannelOut(derive.SpanBatchType, c, spanBatchBuilder) + require.NoError(t, err) + + for i := uint64(1); i <= sequencer.L2Unsafe().Number; i++ { + block, err := l2Cl.BlockByNumber(t.Ctx(), new(big.Int).SetUint64(i)) + require.NoError(t, err) + if i == 2 { + // Make block B2 as an valid block different with unsafe block + // Alice makes a L2 tx + n, err := l2Cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + validTx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: n, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + Gas: params.TxGas, + To: &dp.Addresses.Bob, + Value: e2eutils.Ether(2), + }) + block = block.WithBody([]*types.Transaction{block.Transactions()[0], validTx}, []*types.Header{}) + } + if i == 3 { + // Make block B3 as an invalid block + invalidTx := testutils.RandomTx(rng, big.NewInt(100), signer) + block = block.WithBody([]*types.Transaction{block.Transactions()[0], invalidTx}, []*types.Header{}) + } + // Add A1, B2, B3, B4, B5 into the channel + _, err = channelOut.AddBlock(sd.RollupCfg, block) + require.NoError(t, err) + } + + // Submit span batch(A1, B2, invalid B3, B4, B5) + batcher.l2ChannelOut = channelOut + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + // let sequencer process invalid span batch + sequencer.ActL1HeadSignal(t) + // before stepping, make sure backupUnsafe is empty + require.Equal(t, eth.L2BlockRef{}, sequencer.L2BackupUnsafe()) + // pendingSafe must not be advanced as well + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(0)) + // Preheat engine queue and consume A1 from batch + for i := 0; i < 4; i++ { + sequencer.ActL2PipelineStep(t) + } + // A1 is valid original block so pendingSafe is advanced + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(1)) + require.Equal(t, sequencer.L2Unsafe().Number, uint64(5)) + // backupUnsafe is still empty + require.Equal(t, eth.L2BlockRef{}, sequencer.L2BackupUnsafe()) + + // Process B2 + sequencer.ActL2PipelineStep(t) + sequencer.ActL2PipelineStep(t) + // B2 is valid different block, triggering unsafe chain reorg + require.Equal(t, sequencer.L2Unsafe().Number, uint64(2)) + // B2 is valid different block, triggering unsafe block backup + require.Equal(t, targetUnsafeHeadHash, sequencer.L2BackupUnsafe().Hash) + // B2 is valid different block, so pendingSafe is advanced + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(2)) + // try to process invalid leftovers: B3, B4, B5 + sequencer.ActL2PipelineFull(t) + // backupUnsafe is used because A3 is invalid. Check backupUnsafe is emptied after used + require.Equal(t, eth.L2BlockRef{}, sequencer.L2BackupUnsafe()) + + // check pendingSafe is reset + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(0)) + // check backupUnsafe is applied + require.Equal(t, sequencer.L2Unsafe().Hash, targetUnsafeHeadHash) + require.Equal(t, sequencer.L2Unsafe().Number, uint64(5)) + // safe head cannot be advanced because batch contained invalid blocks + require.Equal(t, sequencer.L2Safe().Number, uint64(0)) + + // let verifier process invalid span batch + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + // safe head cannot be advanced, while unsafe head not changed + require.Equal(t, verifier.L2Unsafe().Number, uint64(5)) + require.Equal(t, verifier.L2Safe().Number, uint64(0)) + require.Equal(t, verifier.L2Unsafe().Hash, targetUnsafeHeadHash) + + // Build and submit a span batch with A1 ~ A5 + batcher.ActSubmitAll(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + // let sequencer process valid span batch + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + + // safe/unsafe head must be advanced + require.Equal(t, sequencer.L2Unsafe().Number, uint64(5)) + require.Equal(t, sequencer.L2Safe().Number, uint64(5)) + require.Equal(t, sequencer.L2Safe().Hash, targetUnsafeHeadHash) + // check backupUnsafe is emptied after consolidation + require.Equal(t, eth.L2BlockRef{}, sequencer.L2BackupUnsafe()) + + // let verifier process valid span batch + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + // safe and unsafe head must be advanced + require.Equal(t, verifier.L2Unsafe().Number, uint64(5)) + require.Equal(t, verifier.L2Safe().Number, uint64(5)) + require.Equal(t, verifier.L2Safe().Hash, targetUnsafeHeadHash) + // check backupUnsafe is emptied after consolidation + require.Equal(t, eth.L2BlockRef{}, verifier.L2BackupUnsafe()) +} + +func TestBackupUnsafeReorgForkChoiceInputError(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + minTs := hexutil.Uint64(0) + // Activate Delta hardfork + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + dp.DeployConfig.L2BlockTime = 2 + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LvlInfo) + _, dp, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + l2Cl := seqEng.EthClient() + seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) + require.NoError(t, err) + + rng := rand.New(rand.NewSource(1234)) + signer := types.LatestSigner(sd.L2Cfg.Config) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Create block A1 ~ A5 + for i := 0; i < 5; i++ { + // Build a L2 block + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + + // Notify new L2 block to verifier by unsafe gossip + seqHead, err := seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + verifier.ActL2UnsafeGossipReceive(seqHead)(t) + } + + seqHead, err := seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + // eventually correct hash for A5 + targetUnsafeHeadHash := seqHead.ExecutionPayload.BlockHash + + // only advance unsafe head to A5 + require.Equal(t, sequencer.L2Unsafe().Number, uint64(5)) + require.Equal(t, sequencer.L2Safe().Number, uint64(0)) + + // Handle unsafe payload + verifier.ActL2PipelineFull(t) + // only advance unsafe head to A5 + require.Equal(t, verifier.L2Unsafe().Number, uint64(5)) + require.Equal(t, verifier.L2Safe().Number, uint64(0)) + + c, e := compressor.NewRatioCompressor(compressor.Config{ + TargetOutputSize: 128_000, + ApproxComprRatio: 1, + }) + require.NoError(t, e) + spanBatchBuilder := derive.NewSpanBatchBuilder(sd.RollupCfg.Genesis.L2Time, sd.RollupCfg.L2ChainID) + // Create new span batch channel + channelOut, err := derive.NewChannelOut(derive.SpanBatchType, c, spanBatchBuilder) + require.NoError(t, err) + + for i := uint64(1); i <= sequencer.L2Unsafe().Number; i++ { + block, err := l2Cl.BlockByNumber(t.Ctx(), new(big.Int).SetUint64(i)) + require.NoError(t, err) + if i == 2 { + // Make block B2 as an valid block different with unsafe block + // Alice makes a L2 tx + n, err := l2Cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + validTx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: n, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + Gas: params.TxGas, + To: &dp.Addresses.Bob, + Value: e2eutils.Ether(2), + }) + block = block.WithBody([]*types.Transaction{block.Transactions()[0], validTx}, []*types.Header{}) + } + if i == 3 { + // Make block B3 as an invalid block + invalidTx := testutils.RandomTx(rng, big.NewInt(100), signer) + block = block.WithBody([]*types.Transaction{block.Transactions()[0], invalidTx}, []*types.Header{}) + } + // Add A1, B2, B3, B4, B5 into the channel + _, err = channelOut.AddBlock(sd.RollupCfg, block) + require.NoError(t, err) + } + + // Submit span batch(A1, B2, invalid B3, B4, B5) + batcher.l2ChannelOut = channelOut + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + // let sequencer process invalid span batch + sequencer.ActL1HeadSignal(t) + // before stepping, make sure backupUnsafe is empty + require.Equal(t, eth.L2BlockRef{}, sequencer.L2BackupUnsafe()) + // pendingSafe must not be advanced as well + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(0)) + // Preheat engine queue and consume A1 from batch + for i := 0; i < 4; i++ { + sequencer.ActL2PipelineStep(t) + } + // A1 is valid original block so pendingSafe is advanced + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(1)) + require.Equal(t, sequencer.L2Unsafe().Number, uint64(5)) + // backupUnsafe is still empty + require.Equal(t, eth.L2BlockRef{}, sequencer.L2BackupUnsafe()) + + // Process B2 + sequencer.ActL2PipelineStep(t) + sequencer.ActL2PipelineStep(t) + // B2 is valid different block, triggering unsafe chain reorg + require.Equal(t, sequencer.L2Unsafe().Number, uint64(2)) + // B2 is valid different block, triggering unsafe block backup + require.Equal(t, targetUnsafeHeadHash, sequencer.L2BackupUnsafe().Hash) + // B2 is valid different block, so pendingSafe is advanced + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(2)) + + // B3 is invalid block + // NextAttributes is called + sequencer.ActL2PipelineStep(t) + // forceNextSafeAttributes is called + sequencer.ActL2PipelineStep(t) + // mock forkChoiceUpdate error while restoring previous unsafe chain using backupUnsafe. + seqEng.ActL2RPCFail(t, eth.InputError{Inner: errors.New("mock L2 RPC error"), Code: eth.InvalidForkchoiceState}) + + // TryBackupUnsafeReorg is called + sequencer.ActL2PipelineStep(t) + + // try to process invalid leftovers: B4, B5 + sequencer.ActL2PipelineFull(t) + + // backupUnsafe is not used because forkChoiceUpdate returned an error. + // Check backupUnsafe is emptied. + require.Equal(t, eth.L2BlockRef{}, sequencer.L2BackupUnsafe()) + + // check pendingSafe is reset + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(0)) + // unsafe head is not restored due to forkchoiceUpdate error in TryBackupUnsafeReorg + require.Equal(t, sequencer.L2Unsafe().Number, uint64(2)) + // safe head cannot be advanced because batch contained invalid blocks + require.Equal(t, sequencer.L2Safe().Number, uint64(0)) +} + +func TestBackupUnsafeReorgForkChoiceNotInputError(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + minTs := hexutil.Uint64(0) + // Activate Delta hardfork + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + dp.DeployConfig.L2BlockTime = 2 sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlInfo) + _, dp, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + l2Cl := seqEng.EthClient() + seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) + require.NoError(t, err) + + rng := rand.New(rand.NewSource(1234)) + signer := types.LatestSigner(sd.L2Cfg.Config) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Create block A1 ~ A5 + for i := 0; i < 5; i++ { + // Build a L2 block + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + + // Notify new L2 block to verifier by unsafe gossip + seqHead, err := seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + verifier.ActL2UnsafeGossipReceive(seqHead)(t) + } + + seqHead, err := seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + // eventually correct hash for A5 + targetUnsafeHeadHash := seqHead.ExecutionPayload.BlockHash + + // only advance unsafe head to A5 + require.Equal(t, sequencer.L2Unsafe().Number, uint64(5)) + require.Equal(t, sequencer.L2Safe().Number, uint64(0)) + + // Handle unsafe payload + verifier.ActL2PipelineFull(t) + // only advance unsafe head to A5 + require.Equal(t, verifier.L2Unsafe().Number, uint64(5)) + require.Equal(t, verifier.L2Safe().Number, uint64(0)) + + c, e := compressor.NewRatioCompressor(compressor.Config{ + TargetOutputSize: 128_000, + ApproxComprRatio: 1, + }) + require.NoError(t, e) + spanBatchBuilder := derive.NewSpanBatchBuilder(sd.RollupCfg.Genesis.L2Time, sd.RollupCfg.L2ChainID) + // Create new span batch channel + channelOut, err := derive.NewChannelOut(derive.SpanBatchType, c, spanBatchBuilder) + require.NoError(t, err) + + for i := uint64(1); i <= sequencer.L2Unsafe().Number; i++ { + block, err := l2Cl.BlockByNumber(t.Ctx(), new(big.Int).SetUint64(i)) + require.NoError(t, err) + if i == 2 { + // Make block B2 as an valid block different with unsafe block + // Alice makes a L2 tx + n, err := l2Cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + validTx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: n, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + Gas: params.TxGas, + To: &dp.Addresses.Bob, + Value: e2eutils.Ether(2), + }) + block = block.WithBody([]*types.Transaction{block.Transactions()[0], validTx}, []*types.Header{}) + } + if i == 3 { + // Make block B3 as an invalid block + invalidTx := testutils.RandomTx(rng, big.NewInt(100), signer) + block = block.WithBody([]*types.Transaction{block.Transactions()[0], invalidTx}, []*types.Header{}) + } + // Add A1, B2, B3, B4, B5 into the channel + _, err = channelOut.AddBlock(sd.RollupCfg, block) + require.NoError(t, err) + } + + // Submit span batch(A1, B2, invalid B3, B4, B5) + batcher.l2ChannelOut = channelOut + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + // let sequencer process invalid span batch + sequencer.ActL1HeadSignal(t) + // before stepping, make sure backupUnsafe is empty + require.Equal(t, eth.L2BlockRef{}, sequencer.L2BackupUnsafe()) + // pendingSafe must not be advanced as well + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(0)) + // Preheat engine queue and consume A1 from batch + for i := 0; i < 4; i++ { + sequencer.ActL2PipelineStep(t) + } + // A1 is valid original block so pendingSafe is advanced + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(1)) + require.Equal(t, sequencer.L2Unsafe().Number, uint64(5)) + // backupUnsafe is still empty + require.Equal(t, eth.L2BlockRef{}, sequencer.L2BackupUnsafe()) + + // Process B2 + sequencer.ActL2PipelineStep(t) + sequencer.ActL2PipelineStep(t) + // B2 is valid different block, triggering unsafe chain reorg + require.Equal(t, sequencer.L2Unsafe().Number, uint64(2)) + // B2 is valid different block, triggering unsafe block backup + require.Equal(t, targetUnsafeHeadHash, sequencer.L2BackupUnsafe().Hash) + // B2 is valid different block, so pendingSafe is advanced + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(2)) + + // B3 is invalid block + // NextAttributes is called + sequencer.ActL2PipelineStep(t) + // forceNextSafeAttributes is called + sequencer.ActL2PipelineStep(t) + + serverErrCnt := 2 + for i := 0; i < serverErrCnt; i++ { + // mock forkChoiceUpdate failure while restoring previous unsafe chain using backupUnsafe. + seqEng.ActL2RPCFail(t, engine.GenericServerError) + // TryBackupUnsafeReorg is called - forkChoiceUpdate returns GenericServerError so retry + sequencer.ActL2PipelineStep(t) + // backupUnsafeHead not emptied yet + require.Equal(t, targetUnsafeHeadHash, sequencer.L2BackupUnsafe().Hash) + } + // now forkchoice succeeds + // try to process invalid leftovers: B4, B5 + sequencer.ActL2PipelineFull(t) + + // backupUnsafe is used because forkChoiceUpdate eventually succeeded. + // Check backupUnsafe is emptied. + require.Equal(t, eth.L2BlockRef{}, sequencer.L2BackupUnsafe()) + + // check pendingSafe is reset + require.Equal(t, sequencer.L2PendingSafe().Number, uint64(0)) + // check backupUnsafe is applied + require.Equal(t, sequencer.L2Unsafe().Hash, targetUnsafeHeadHash) + require.Equal(t, sequencer.L2Unsafe().Number, uint64(5)) + // safe head cannot be advanced because batch contained invalid blocks + require.Equal(t, sequencer.L2Safe().Number, uint64(0)) +} + +// TestELSync tests that a verifier will have the EL import the full chain from the sequencer +// when passed a single unsafe block. op-geth can either snap sync or full sync here. +func TestELSync(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelInfo) miner, seqEng, sequencer := setupSequencerTest(t, sd, log) // Enable engine P2P sync - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{EngineSync: true}) + verEng, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{SyncMode: sync.ELSync}) seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) require.NoError(t, err) sequencer.ActL2PipelineFull(t) - verifier.ActL2PipelineFull(t) - verifierUnsafeHead := verifier.L2Unsafe() + // Build 10 L1 blocks on the sequencer + for i := 0; i < 10; i++ { + // Build a L2 block + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + } + + // Wait longer to peer. This tests flakes or takes a long time when the op-geth instances are not able to peer. + verEng.AddPeers(seqEng.Enode()) + + // Insert it on the verifier + seqHead, err := seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + seqStart, err := seqEngCl.PayloadByNumber(t.Ctx(), 1) + require.NoError(t, err) + verifier.ActL2InsertUnsafePayload(seqHead)(t) + + require.Eventually(t, + func() bool { + return seqEng.PeerCount() > 0 && verEng.PeerCount() > 0 + }, + 120*time.Second, 1500*time.Millisecond, + "Sequencer & Verifier must peer with each other for snap sync to work", + ) + + // Expect snap sync to download & execute the entire chain + // Verify this by checking that the verifier has the correct value for block 1 + require.Eventually(t, + func() bool { + block, err := verifier.eng.L2BlockRefByNumber(t.Ctx(), 1) + if err != nil { + return false + } + return seqStart.ExecutionPayload.BlockHash == block.Hash + }, + 60*time.Second, 1500*time.Millisecond, + "verifier did not snap sync", + ) +} - // Build a L2 block. This block will not be gossiped to verifier, so verifier can not advance chain by itself. +// TestELSyncTransitionstoCL tests that a verifier which starts with EL sync can switch back to a proper CL sync. +// It takes a sequencer & verifier through the following: +// 1. Build 10 unsafe blocks on the sequencer +// 2. Snap sync those blocks to the verifier +// 3. Build & insert 1 unsafe block from the sequencer to the verifier to end snap sync +// 4. Batch submit everything +// 5. Build 10 more unsafe blocks on the sequencer +// 6. Gossip in the highest block to the verifier. **Expect that it does not snap sync** +// 7. Then gossip the rest of the blocks to the verifier. Once this is complete it should pick up all of the unsafe blocks. +// Prior to this PR, the test would fail at this point. +// 8. Create 1 more block & batch submit everything & assert that the verifier picked up those blocks +func TestELSyncTransitionstoCL(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + sd := e2eutils.Setup(t, dp, defaultAlloc) + logger := testlog.Logger(t, log.LevelInfo) + + captureLog, captureLogHandler := testlog.CaptureLogger(t, log.LevelInfo) + + miner, seqEng, sequencer := setupSequencerTest(t, sd, logger) + batcher := NewL2Batcher(logger, sd.RollupCfg, DefaultBatcherCfg(dp), sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) + // Enable engine P2P sync + verEng, verifier := setupVerifier(t, sd, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{SyncMode: sync.ELSync}) + + seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), logger, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) + require.NoError(t, err) + + miner.ActEmptyBlock(t) + sequencer.ActL2PipelineFull(t) + + // Build 10 L1 blocks on the sequencer + for i := 0; i < 10; i++ { + // Build a L2 block + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + } + + // Wait longer to peer. This tests flakes or takes a long time when the op-geth instances are not able to peer. + verEng.AddPeers(seqEng.Enode()) + + // Insert it on the verifier + seqHead, err := seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + seqStart, err := seqEngCl.PayloadByNumber(t.Ctx(), 1) + require.NoError(t, err) + verifier.ActL2InsertUnsafePayload(seqHead)(t) + + require.Eventually(t, + func() bool { + return seqEng.PeerCount() > 0 && verEng.PeerCount() > 0 + }, + 120*time.Second, 1500*time.Millisecond, + "Sequencer & Verifier must peer with each other for snap sync to work", + ) + + // Expect snap sync to download & execute the entire chain + // Verify this by checking that the verifier has the correct value for block 1 + require.Eventually(t, + func() bool { + block, err := verifier.eng.L2BlockRefByNumber(t.Ctx(), 1) + if err != nil { + return false + } + return seqStart.ExecutionPayload.BlockHash == block.Hash + }, + 60*time.Second, 1500*time.Millisecond, + "verifier did not snap sync", + ) + // Despite downloading the blocks, it has not finished finalizing + _, err = verifier.eng.L2BlockRefByLabel(t.Ctx(), "safe") + require.ErrorIs(t, err, ethereum.NotFound) + + // Insert a block on the verifier to end snap sync sequencer.ActL2StartBlock(t) sequencer.ActL2EndBlock(t) + seqHead, err = seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + verifier.ActL2InsertUnsafePayload(seqHead)(t) + + // Check that safe + finalized are there + id, err := verifier.eng.L2BlockRefByLabel(t.Ctx(), eth.Safe) + require.Equal(t, uint64(11), id.Number) + require.NoError(t, err) + id, err = verifier.eng.L2BlockRefByLabel(t.Ctx(), eth.Finalized) + require.Equal(t, uint64(11), id.Number) + require.NoError(t, err) + // Batch submit everything + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + batcher.ActSubmitAll(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Verify that the batch submitted blocks are there now + id, err = sequencer.eng.L2BlockRefByLabel(t.Ctx(), eth.Safe) + require.NoError(t, err) + require.Equal(t, uint64(12), id.Number) + id, err = verifier.eng.L2BlockRefByLabel(t.Ctx(), eth.Safe) + require.NoError(t, err) + require.Equal(t, uint64(12), id.Number) + + // Build another 10 L1 blocks on the sequencer for i := 0; i < 10; i++ { // Build a L2 block sequencer.ActL2StartBlock(t) sequencer.ActL2EndBlock(t) - // Notify new L2 block to verifier by unsafe gossip - seqHead, err := seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + } + + // Now pass payloads to the derivation pipeline + // This is a little hacky that we have to manually switch between InsertBlock + // and UnsafeGossipReceive in the tests + seqHead, err = seqEngCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + verifier.ActL2UnsafeGossipReceive(seqHead)(t) + verifier.ActL2PipelineFull(t) + // Verify that the derivation pipeline did not request a sync to the new head. This is the core of the test, but a little fragile. + record := captureLogHandler.FindLog(testlog.NewMessageFilter("Forkchoice requested sync to new head"), testlog.NewAttributesFilter("number", "22")) + require.Nil(t, record, "The verifier should not request to sync to block number 22 because it is in CL mode, not EL mode at this point.") + + for i := 13; i < 23; i++ { + seqHead, err = seqEngCl.PayloadByNumber(t.Ctx(), uint64(i)) require.NoError(t, err) verifier.ActL2UnsafeGossipReceive(seqHead)(t) - // Handle unsafe payload - verifier.ActL2PipelineFull(t) - // Verifier must advance only engine sync target. - require.NotEqual(t, sequencer.L2Unsafe().Hash, verifier.L2Unsafe().Hash) - require.NotEqual(t, verifier.L2Unsafe().Hash, verifier.EngineSyncTarget().Hash) - require.Equal(t, verifier.L2Unsafe().Hash, verifierUnsafeHead.Hash) - require.Equal(t, sequencer.L2Unsafe().Hash, verifier.EngineSyncTarget().Hash) + } + verifier.ActL2PipelineFull(t) + + // Verify that the unsafe blocks are there now + // This was failing prior to PR 9661 because op-node would attempt to immediately insert blocks into the EL inside the engine queue. op-geth + // would not be able to fetch the second range of blocks & it would wipe out the unsafe payloads queue because op-node thought that it had a + // higher unsafe block but op-geth did not. + id, err = verifier.eng.L2BlockRefByLabel(t.Ctx(), eth.Unsafe) + require.NoError(t, err) + require.Equal(t, uint64(22), id.Number) + + // Create 1 more block & batch submit everything + sequencer.ActL2StartBlock(t) + sequencer.ActL2EndBlock(t) + batcher.ActSubmitAll(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Verify that the batch submitted blocks are there now + id, err = sequencer.eng.L2BlockRefByLabel(t.Ctx(), eth.Safe) + require.NoError(t, err) + require.Equal(t, uint64(23), id.Number) + id, err = verifier.eng.L2BlockRefByLabel(t.Ctx(), eth.Safe) + require.NoError(t, err) + require.Equal(t, uint64(23), id.Number) +} + +func TestInvalidPayloadInSpanBatch(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + minTs := hexutil.Uint64(0) + // Activate Delta hardfork + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + dp.DeployConfig.L2BlockTime = 2 + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelInfo) + _, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + l2Cl := seqEng.EthClient() + rng := rand.New(rand.NewSource(1234)) + signer := types.LatestSigner(sd.L2Cfg.Config) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + c, e := compressor.NewRatioCompressor(compressor.Config{ + TargetOutputSize: 128_000, + ApproxComprRatio: 1, + }) + require.NoError(t, e) + spanBatchBuilder := derive.NewSpanBatchBuilder(sd.RollupCfg.Genesis.L2Time, sd.RollupCfg.L2ChainID) + // Create new span batch channel + channelOut, err := derive.NewChannelOut(derive.SpanBatchType, c, spanBatchBuilder) + require.NoError(t, err) + + // Create block A1 ~ A12 for L1 block #0 ~ #2 + miner.ActEmptyBlock(t) + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1HeadUnsafe(t) + + for i := uint64(1); i <= sequencer.L2Unsafe().Number; i++ { + block, err := l2Cl.BlockByNumber(t.Ctx(), new(big.Int).SetUint64(i)) + require.NoError(t, err) + if i == 8 { + // Make block A8 as an invalid block + invalidTx := testutils.RandomTx(rng, big.NewInt(100), signer) + block = block.WithBody([]*types.Transaction{block.Transactions()[0], invalidTx}, []*types.Header{}) + } + // Add A1 ~ A12 into the channel + _, err = channelOut.AddBlock(sd.RollupCfg, block) + require.NoError(t, err) + } + + // Submit span batch(A1, ..., A7, invalid A8, A9, ..., A12) + batcher.l2ChannelOut = channelOut + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + miner.ActL1SafeNext(t) + miner.ActL1FinalizeNext(t) + + // After the verifier processed the span batch, only unsafe head should be advanced to A7. + // Safe head is not updated because the span batch is not fully processed. + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Unsafe().Number, uint64(7)) + require.Equal(t, verifier.L2Safe().Number, uint64(0)) + + // Create new span batch channel + c, e = compressor.NewRatioCompressor(compressor.Config{ + TargetOutputSize: 128_000, + ApproxComprRatio: 1, + }) + require.NoError(t, e) + spanBatchBuilder = derive.NewSpanBatchBuilder(sd.RollupCfg.Genesis.L2Time, sd.RollupCfg.L2ChainID) + channelOut, err = derive.NewChannelOut(derive.SpanBatchType, c, spanBatchBuilder) + require.NoError(t, err) + + for i := uint64(1); i <= sequencer.L2Unsafe().Number; i++ { + block, err := l2Cl.BlockByNumber(t.Ctx(), new(big.Int).SetUint64(i)) + require.NoError(t, err) + if i == 1 { + // Create valid TX + aliceNonce, err := seqEng.EthClient().PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + data := make([]byte, rand.Intn(100)) + gas, err := core.IntrinsicGas(data, nil, false, true, true, false) + require.NoError(t, err) + baseFee := seqEng.l2Chain.CurrentBlock().BaseFee + tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: aliceNonce, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(new(big.Int).Mul(baseFee, big.NewInt(2)), big.NewInt(2*params.GWei)), + Gas: gas, + To: &dp.Addresses.Bob, + Value: big.NewInt(0), + Data: data, + }) + // Create valid new block B1 at the same height as A1 + block = block.WithBody([]*types.Transaction{block.Transactions()[0], tx}, []*types.Header{}) + } + // Add B1, A2 ~ A12 into the channel + _, err = channelOut.AddBlock(sd.RollupCfg, block) + require.NoError(t, err) + } + // Submit span batch(B1, A2, ... A12) + batcher.l2ChannelOut = channelOut + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + miner.ActL1SafeNext(t) + miner.ActL1FinalizeNext(t) + + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + // verifier should advance its unsafe and safe head to the height of A12. + require.Equal(t, verifier.L2Unsafe().Number, uint64(12)) + require.Equal(t, verifier.L2Safe().Number, uint64(12)) +} + +func TestSpanBatchAtomicity_Consolidation(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + minTs := hexutil.Uint64(0) + // Activate Delta hardfork + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + dp.DeployConfig.L2BlockTime = 2 + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelInfo) + _, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) + require.NoError(t, err) + + targetHeadNumber := uint64(6) // L1 block time / L2 block time + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Create 6 blocks + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1HeadUnsafe(t) + require.Equal(t, sequencer.L2Unsafe().Number, targetHeadNumber) + + // Gossip unsafe blocks to the verifier + for i := uint64(1); i <= sequencer.L2Unsafe().Number; i++ { + seqHead, err := seqEngCl.PayloadByNumber(t.Ctx(), i) + require.NoError(t, err) + verifier.ActL2UnsafeGossipReceive(seqHead)(t) + } + verifier.ActL2PipelineFull(t) + + // Check if the verifier's unsafe sync is done + require.Equal(t, sequencer.L2Unsafe().Hash, verifier.L2Unsafe().Hash) + + // Build and submit a span batch with 6 blocks + batcher.ActSubmitAll(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + // Start verifier safe sync + verifier.ActL1HeadSignal(t) + verifier.l2PipelineIdle = false + for !verifier.l2PipelineIdle { + verifier.ActL2PipelineStep(t) + if verifier.L2PendingSafe().Number < targetHeadNumber { + // If the span batch is not fully processed, the safe head must not advance. + require.Equal(t, verifier.L2Safe().Number, uint64(0)) + } else { + // Once the span batch is fully processed, the safe head must advance to the end of span batch. + require.Equal(t, verifier.L2Safe().Number, targetHeadNumber) + require.Equal(t, verifier.L2Safe(), verifier.L2PendingSafe()) + } + // The unsafe head must not be changed + require.Equal(t, verifier.L2Unsafe(), sequencer.L2Unsafe()) + } +} + +func TestSpanBatchAtomicity_ForceAdvance(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + minTs := hexutil.Uint64(0) + // Activate Delta hardfork + dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + dp.DeployConfig.L2BlockTime = 2 + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LevelInfo) + _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + + targetHeadNumber := uint64(6) // L1 block time / L2 block time + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Unsafe().Number, uint64(0)) + + // Create 6 blocks + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1HeadUnsafe(t) + require.Equal(t, sequencer.L2Unsafe().Number, targetHeadNumber) + + // Build and submit a span batch with 6 blocks + batcher.ActSubmitAll(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + // Start verifier safe sync + verifier.ActL1HeadSignal(t) + verifier.l2PipelineIdle = false + for !verifier.l2PipelineIdle { + verifier.ActL2PipelineStep(t) + if verifier.L2PendingSafe().Number < targetHeadNumber { + // If the span batch is not fully processed, the safe head must not advance. + require.Equal(t, verifier.L2Safe().Number, uint64(0)) + } else { + // Once the span batch is fully processed, the safe head must advance to the end of span batch. + require.Equal(t, verifier.L2Safe().Number, targetHeadNumber) + require.Equal(t, verifier.L2Safe(), verifier.L2PendingSafe()) + } + // The unsafe head and the pending safe head must be the same + require.Equal(t, verifier.L2Unsafe(), verifier.L2PendingSafe()) } } diff --git a/op-e2e/actions/system_config_test.go b/op-e2e/actions/system_config_test.go index f857c8633841..19cf24ba3ea8 100644 --- a/op-e2e/actions/system_config_test.go +++ b/op-e2e/actions/system_config_test.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "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" "github.com/stretchr/testify/require" @@ -19,34 +20,57 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -// TestBatcherKeyRotation tests that batcher A can operate, then be replaced with batcher B, then ignore old batcher A, +// TestSystemConfigBatchType run each system config-related test case in singular batch mode and span batch mode. +func TestSystemConfigBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, deltaTimeOffset *hexutil.Uint64) + }{ + {"BatcherKeyRotation", BatcherKeyRotation}, + {"GPOParamsChange", GPOParamsChange}, + {"GasLimitChange", GasLimitChange}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + deltaTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &deltaTimeOffset) + }) + } +} + +// BatcherKeyRotation tests that batcher A can operate, then be replaced with batcher B, then ignore old batcher A, // and that the change to batcher B is reverted properly upon reorg of L1. -func TestBatcherKeyRotation(gt *testing.T) { +func BatcherKeyRotation(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp.DeployConfig.L2BlockTime = 2 + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) miner.ActL1SetFeeRecipient(common.Address{'A'}) sequencer.ActL2PipelineFull(t) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) rollupSeqCl := sequencer.RollupClient() // the default batcher - batcherA := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient()) + batcherA := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) // a batcher with a new key - batcherB := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Bob, - }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient()) + altCfg := *DefaultBatcherCfg(dp) + altCfg.BatcherKey = dp.Secrets.Bob + batcherB := NewL2Batcher(log, sd.RollupCfg, &altCfg, + rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) @@ -107,9 +131,9 @@ func TestBatcherKeyRotation(gt *testing.T) { // 12 new L2 blocks: 5 with origin before L1 block with batch, 6 with origin of L1 block // with batch, 1 with new origin that changed the batcher for i := 0; i <= 12; i++ { - payload, err := engCl.PayloadByNumber(t.Ctx(), sequencer.L2Safe().Number+uint64(i)) + envelope, err := engCl.PayloadByNumber(t.Ctx(), sequencer.L2Safe().Number+uint64(i)) require.NoError(t, err) - ref, err := derive.PayloadToBlockRef(payload, &sd.RollupCfg.Genesis) + ref, err := derive.PayloadToBlockRef(sd.RollupCfg, envelope.ExecutionPayload) require.NoError(t, err) if i < 6 { require.Equal(t, ref.L1Origin.Number, cfgChangeL1BlockNum-2) @@ -120,7 +144,7 @@ func TestBatcherKeyRotation(gt *testing.T) { } else { require.Equal(t, ref.L1Origin.Number, cfgChangeL1BlockNum) require.Equal(t, ref.SequenceNumber, uint64(0), "first L2 block with this origin") - sysCfg, err := derive.PayloadToSystemConfig(payload, sd.RollupCfg) + sysCfg, err := derive.PayloadToSystemConfig(sd.RollupCfg, envelope.ExecutionPayload) require.NoError(t, err) require.Equal(t, dp.Addresses.Bob, sysCfg.BatcherAddr, "bob should be batcher now") } @@ -198,21 +222,20 @@ func TestBatcherKeyRotation(gt *testing.T) { require.Equal(t, sequencer.L2Unsafe(), verifier.L2Unsafe(), "verifier synced") } -// TestGPOParamsChange tests that the GPO params can be updated to adjust fees of L2 transactions, +// GPOParamsChange tests that the GPO params can be updated to adjust fees of L2 transactions, // and that the L1 data fees to the L2 transaction are applied correctly before, during and after the GPO update in L2. -func TestGPOParamsChange(gt *testing.T) { +func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { //todo temporarily skip this test gt.SkipNow() + t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), seqEngine.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + sequencer.RollupClient(), miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) alice := NewBasicUser[any](log, dp.Secrets.Alice, rand.New(rand.NewSource(1234))) alice.SetUserEnv(&BasicUserEnv[any]{ @@ -278,9 +301,9 @@ func TestGPOParamsChange(gt *testing.T) { sequencer.ActBuildToL1HeadExcl(t) engCl := seqEngine.EngineClient(t, sd.RollupCfg) - payload, err := engCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + envelope, err := engCl.PayloadByLabel(t.Ctx(), eth.Unsafe) require.NoError(t, err) - sysCfg, err := derive.PayloadToSystemConfig(payload, sd.RollupCfg) + sysCfg, err := derive.PayloadToSystemConfig(sd.RollupCfg, envelope.ExecutionPayload) require.NoError(t, err) require.Equal(t, sd.RollupCfg.Genesis.SystemConfig, sysCfg, "still have genesis system config before we adopt the L1 block with GPO change") @@ -291,9 +314,9 @@ func TestGPOParamsChange(gt *testing.T) { seqEngine.ActL2IncludeTx(dp.Addresses.Alice)(t) sequencer.ActL2EndBlock(t) - payload, err = engCl.PayloadByLabel(t.Ctx(), eth.Unsafe) + envelope, err = engCl.PayloadByLabel(t.Ctx(), eth.Unsafe) require.NoError(t, err) - sysCfg, err = derive.PayloadToSystemConfig(payload, sd.RollupCfg) + sysCfg, err = derive.PayloadToSystemConfig(sd.RollupCfg, envelope.ExecutionPayload) require.NoError(t, err) require.Equal(t, eth.Bytes32(common.BigToHash(big.NewInt(1000))), sysCfg.Overhead, "overhead changed") require.Equal(t, eth.Bytes32(common.BigToHash(big.NewInt(2_300_000))), sysCfg.Scalar, "scalar changed") @@ -328,20 +351,18 @@ func TestGPOParamsChange(gt *testing.T) { require.Equal(t, "2.3", receipt.FeeScalar.String(), "2_300_000 divided by 6 decimals = float(2.3)") } -// TestGasLimitChange tests that the gas limit can be configured to L1, +// GasLimitChange tests that the gas limit can be configured to L1, // and that the L2 changes the gas limit instantly at the exact block that adopts the L1 origin with // the gas limit change event. And checks if a verifier node can reproduce the same gas limit change. -func TestGasLimitChange(gt *testing.T) { +func GasLimitChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), seqEngine.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + sequencer.RollupClient(), miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) miner.ActEmptyBlock(t) @@ -384,7 +405,7 @@ func TestGasLimitChange(gt *testing.T) { miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) miner.ActL1EndBlock(t) - _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), &sync.Config{}) verifier.ActL2PipelineFull(t) require.Equal(t, sequencer.L2Unsafe(), verifier.L2Safe(), "verifier stays in sync, even with gaslimit changes") diff --git a/op-e2e/actions/user.go b/op-e2e/actions/user.go index 5e5780fb1f97..726f53ad472c 100644 --- a/op-e2e/actions/user.go +++ b/op-e2e/actions/user.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" "math/rand" + "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -18,17 +19,22 @@ import ( "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/bindingspreview" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" + e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/ethereum-optimism/optimism/op-e2e/config" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/withdrawals" ) type L1Bindings struct { // contract bindings - OptimismPortal *bindings.OptimismPortal - - L2OutputOracle *bindings.L2OutputOracle + OptimismPortal *bindings.OptimismPortal + L2OutputOracle *bindings.L2OutputOracle + OptimismPortal2 *bindingspreview.OptimismPortal2 + DisputeGameFactory *bindings.DisputeGameFactory } func NewL1Bindings(t Testing, l1Cl *ethclient.Client) *L1Bindings { @@ -38,9 +44,17 @@ func NewL1Bindings(t Testing, l1Cl *ethclient.Client) *L1Bindings { l2OutputOracle, err := bindings.NewL2OutputOracle(config.L1Deployments.L2OutputOracleProxy, l1Cl) require.NoError(t, err) + optimismPortal2, err := bindingspreview.NewOptimismPortal2(config.L1Deployments.OptimismPortalProxy, l1Cl) + require.NoError(t, err) + + disputeGameFactory, err := bindings.NewDisputeGameFactory(config.L1Deployments.DisputeGameFactoryProxy, l1Cl) + require.NoError(t, err) + return &L1Bindings{ - OptimismPortal: optimismPortal, - L2OutputOracle: l2OutputOracle, + OptimismPortal: optimismPortal, + L2OutputOracle: l2OutputOracle, + OptimismPortal2: optimismPortal2, + DisputeGameFactory: disputeGameFactory, } } @@ -392,39 +406,89 @@ func (s *CrossLayerUser) Address() common.Address { return s.L1.address } -// ActCompleteWithdrawal creates a L1 proveWithdrawal tx for latest withdrawal. -// The tx hash is remembered as the last L1 tx, to check as L1 actor. -func (s *CrossLayerUser) ActProveWithdrawal(t Testing) { - s.L1.lastTxHash = s.ProveWithdrawal(t, s.lastL2WithdrawalTxHash) -} - -// ProveWithdrawal creates a L1 proveWithdrawal tx for the given L2 withdrawal tx, returning the tx hash. -func (s *CrossLayerUser) ProveWithdrawal(t Testing, l2TxHash common.Hash) common.Hash { - // Figure out when our withdrawal was included - receipt := s.L2.CheckReceipt(t, true, l2TxHash) +func (s *CrossLayerUser) getLatestWithdrawalParams(t Testing) (*withdrawals.ProvenWithdrawalParameters, error) { + receipt := s.L2.CheckReceipt(t, true, s.lastL2WithdrawalTxHash) l2WithdrawalBlock, err := s.L2.env.EthCl.BlockByNumber(t.Ctx(), receipt.BlockNumber) require.NoError(t, err) - // Figure out what the Output oracle on L1 has seen so far - l2OutputBlockNr, err := s.L1.env.Bindings.L2OutputOracle.LatestBlockNumber(&bind.CallOpts{}) - require.NoError(t, err) - l2OutputBlock, err := s.L2.env.EthCl.BlockByNumber(t.Ctx(), l2OutputBlockNr) - require.NoError(t, err) - l2OutputIndex, err := s.L1.env.Bindings.L2OutputOracle.GetL2OutputIndexAfter(&bind.CallOpts{}, l2OutputBlockNr) - require.NoError(t, err) + var l2OutputBlockNr *big.Int + var l2OutputBlock *types.Block + if e2eutils.UseFPAC() { + latestGame, err := withdrawals.FindLatestGame(t.Ctx(), &s.L1.env.Bindings.DisputeGameFactory.DisputeGameFactoryCaller, &s.L1.env.Bindings.OptimismPortal2.OptimismPortal2Caller) + require.NoError(t, err) + l2OutputBlockNr = new(big.Int).SetBytes(latestGame.ExtraData[0:32]) + l2OutputBlock, err = s.L2.env.EthCl.BlockByNumber(t.Ctx(), l2OutputBlockNr) + require.NoError(t, err) + } else { + l2OutputBlockNr, err = s.L1.env.Bindings.L2OutputOracle.LatestBlockNumber(&bind.CallOpts{}) + require.NoError(t, err) + l2OutputBlock, err = s.L2.env.EthCl.BlockByNumber(t.Ctx(), l2OutputBlockNr) + require.NoError(t, err) + } - // Check if the L2 output is even old enough to include the withdrawal if l2OutputBlock.NumberU64() < l2WithdrawalBlock.NumberU64() { - t.InvalidAction("the latest L2 output is %d and is not past L2 block %d that includes the withdrawal yet, no withdrawal can be proved yet", l2OutputBlock.NumberU64(), l2WithdrawalBlock.NumberU64()) - return common.Hash{} + return nil, fmt.Errorf("the latest L2 output is %d and is not past L2 block %d that includes the withdrawal yet, no withdrawal can be proved yet", l2OutputBlock.NumberU64(), l2WithdrawalBlock.NumberU64()) + } + + if !e2eutils.UseFPAC() { + finalizationPeriod, err := s.L1.env.Bindings.L2OutputOracle.FINALIZATIONPERIODSECONDS(&bind.CallOpts{}) + require.NoError(t, err) + l1Head, err := s.L1.env.EthCl.HeaderByNumber(t.Ctx(), nil) + require.NoError(t, err) + + if l2OutputBlock.Time()+finalizationPeriod.Uint64() >= l1Head.Time { + return nil, fmt.Errorf("L2 output block %d (time %d) is not past finalization period %d from L2 block %d (time %d) at head %d (time %d)", l2OutputBlock.NumberU64(), l2OutputBlock.Time(), finalizationPeriod.Uint64(), l2WithdrawalBlock.NumberU64(), l2WithdrawalBlock.Time(), l1Head.Number.Uint64(), l1Head.Time) + } } - // We generate a proof for the latest L2 output, which shouldn't require archive-node data if it's recent enough. header, err := s.L2.env.EthCl.HeaderByNumber(t.Ctx(), l2OutputBlockNr) require.NoError(t, err) - params, err := withdrawals.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header, &s.L1.env.Bindings.L2OutputOracle.L2OutputOracleCaller) + params, err := e2e.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header, &s.L1.env.Bindings.L2OutputOracle.L2OutputOracleCaller, &s.L1.env.Bindings.DisputeGameFactory.DisputeGameFactoryCaller, &s.L1.env.Bindings.OptimismPortal2.OptimismPortal2Caller) require.NoError(t, err) + return ¶ms, nil +} + +func (s *CrossLayerUser) getDisputeGame(t Testing, params withdrawals.ProvenWithdrawalParameters) (*bindings.FaultDisputeGame, error) { + wd := crossdomain.Withdrawal{ + Nonce: params.Nonce, + Sender: ¶ms.Sender, + Target: ¶ms.Target, + Value: params.Value, + GasLimit: params.GasLimit, + Data: params.Data, + } + + portal2, err := bindingspreview.NewOptimismPortal2(config.L1Deployments.OptimismPortalProxy, s.L1.env.EthCl) + require.Nil(t, err) + + wdHash, err := wd.Hash() + require.Nil(t, err) + + game, err := portal2.ProvenWithdrawals(&bind.CallOpts{}, wdHash) + require.Nil(t, err) + require.NotNil(t, game, "withdrawal should be proven") + + proxy, err := bindings.NewFaultDisputeGame(game.DisputeGameProxy, s.L1.env.EthCl) + require.Nil(t, err) + + return proxy, nil +} + +// ActCompleteWithdrawal creates a L1 proveWithdrawal tx for latest withdrawal. +// The tx hash is remembered as the last L1 tx, to check as L1 actor. +func (s *CrossLayerUser) ActProveWithdrawal(t Testing) { + s.L1.lastTxHash = s.ProveWithdrawal(t, s.lastL2WithdrawalTxHash) +} + +// ProveWithdrawal creates a L1 proveWithdrawal tx for the given L2 withdrawal tx, returning the tx hash. +func (s *CrossLayerUser) ProveWithdrawal(t Testing, l2TxHash common.Hash) common.Hash { + params, err := s.getLatestWithdrawalParams(t) + if err != nil { + t.InvalidAction("cannot prove withdrawal: %v", err) + return common.Hash{} + } + // Create the prove tx tx, err := s.L1.env.Bindings.OptimismPortal.ProveWithdrawalTransaction( &s.L1.txOpts, @@ -436,7 +500,7 @@ func (s *CrossLayerUser) ProveWithdrawal(t Testing, l2TxHash common.Hash) common GasLimit: params.GasLimit, Data: params.Data, }, - l2OutputIndex, + params.L2OutputIndex, params.OutputRootProof, params.WithdrawalProof, ) @@ -458,44 +522,12 @@ func (s *CrossLayerUser) ActCompleteWithdrawal(t Testing) { // CompleteWithdrawal creates a L1 withdrawal finalization tx for the given L2 withdrawal tx, returning the tx hash. // It's an invalid action to attempt to complete a withdrawal that has not passed the L1 finalization period yet func (s *CrossLayerUser) CompleteWithdrawal(t Testing, l2TxHash common.Hash) common.Hash { - finalizationPeriod, err := s.L1.env.Bindings.L2OutputOracle.FINALIZATIONPERIODSECONDS(&bind.CallOpts{}) - require.NoError(t, err) - - // Figure out when our withdrawal was included - receipt := s.L2.CheckReceipt(t, true, l2TxHash) - l2WithdrawalBlock, err := s.L2.env.EthCl.BlockByNumber(t.Ctx(), receipt.BlockNumber) - require.NoError(t, err) - - // Figure out what the Output oracle on L1 has seen so far - l2OutputBlockNr, err := s.L1.env.Bindings.L2OutputOracle.LatestBlockNumber(&bind.CallOpts{}) - require.NoError(t, err) - l2OutputBlock, err := s.L2.env.EthCl.BlockByNumber(t.Ctx(), l2OutputBlockNr) - require.NoError(t, err) - - // Check if the L2 output is even old enough to include the withdrawal - if l2OutputBlock.NumberU64() < l2WithdrawalBlock.NumberU64() { - t.InvalidAction("the latest L2 output is %d and is not past L2 block %d that includes the withdrawal yet, no withdrawal can be completed yet", l2OutputBlock.NumberU64(), l2WithdrawalBlock.NumberU64()) - return common.Hash{} - } - - l1Head, err := s.L1.env.EthCl.HeaderByNumber(t.Ctx(), nil) - require.NoError(t, err) - - // Check if the withdrawal may be completed yet - if l2OutputBlock.Time()+finalizationPeriod.Uint64() >= l1Head.Time { - t.InvalidAction("withdrawal tx %s was included in L2 block %d (time %d) but L1 only knows of L2 proposal %d (time %d) at head %d (time %d) which has not reached output confirmation yet (period is %d)", - l2TxHash, l2WithdrawalBlock.NumberU64(), l2WithdrawalBlock.Time(), l2OutputBlock.NumberU64(), l2OutputBlock.Time(), l1Head.Number.Uint64(), l1Head.Time, finalizationPeriod.Uint64()) + params, err := s.getLatestWithdrawalParams(t) + if err != nil { + t.InvalidAction("cannot complete withdrawal: %v", err) return common.Hash{} } - // We generate a proof for the latest L2 output, which shouldn't require archive-node data if it's recent enough. - // Note that for the `FinalizeWithdrawalTransaction` function, this proof isn't needed. We simply use some of the - // params for the `WithdrawalTransaction` type generated in the bindings. - header, err := s.L2.env.EthCl.HeaderByNumber(t.Ctx(), l2OutputBlockNr) - require.NoError(t, err) - params, err := withdrawals.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header, &s.L1.env.Bindings.L2OutputOracle.L2OutputOracleCaller) - require.NoError(t, err) - // Create the withdrawal tx tx, err := s.L1.env.Bindings.OptimismPortal.FinalizeWithdrawalTransaction( &s.L1.txOpts, @@ -515,3 +547,57 @@ func (s *CrossLayerUser) CompleteWithdrawal(t Testing, l2TxHash common.Hash) com require.NoError(t, err, "must send finalize tx") return tx.Hash() } + +// ActResolveClaim creates a L1 resolveClaim tx for the latest withdrawal. +func (s *CrossLayerUser) ActResolveClaim(t Testing) { + s.L1.lastTxHash = s.ResolveClaim(t, s.lastL2WithdrawalTxHash) +} + +// ResolveClaim creates a L1 resolveClaim tx for the given L2 withdrawal tx, returning the tx hash. +func (s *CrossLayerUser) ResolveClaim(t Testing, l2TxHash common.Hash) common.Hash { + params, err := s.getLatestWithdrawalParams(t) + if err != nil { + t.InvalidAction("cannot resolve claim: %v", err) + return common.Hash{} + } + + game, err := s.getDisputeGame(t, *params) + require.NoError(t, err) + + expiry, err := game.GameDuration(&bind.CallOpts{}) + require.Nil(t, err) + + time.Sleep(time.Duration(expiry) * time.Second) + resolveClaimTx, err := game.ResolveClaim(&s.L1.txOpts, common.Big0) + require.Nil(t, err) + + err = s.L1.env.EthCl.SendTransaction(t.Ctx(), resolveClaimTx) + require.Nil(t, err) + return resolveClaimTx.Hash() +} + +// ActResolve creates a L1 resolve tx for the latest withdrawal. +// Resolve is different than resolving a claim, the root claim must be resolved first and then +// the game itself can be resolved. +func (s *CrossLayerUser) ActResolve(t Testing) { + s.L1.lastTxHash = s.Resolve(t, s.lastL2WithdrawalTxHash) +} + +// Resolve creates a L1 resolve tx for the given L2 withdrawal tx, returning the tx hash. +func (s *CrossLayerUser) Resolve(t Testing, l2TxHash common.Hash) common.Hash { + params, err := s.getLatestWithdrawalParams(t) + if err != nil { + t.InvalidAction("cannot resolve game: %v", err) + return common.Hash{} + } + + game, err := s.getDisputeGame(t, *params) + require.NoError(t, err) + + resolveTx, err := game.Resolve(&s.L1.txOpts) + require.Nil(t, err) + + err = s.L1.env.EthCl.SendTransaction(t.Ctx(), resolveTx) + require.Nil(t, err) + return resolveTx.Hash() +} diff --git a/op-e2e/actions/user_test.go b/op-e2e/actions/user_test.go index c63918cdaec1..b6f3f370ee27 100644 --- a/op-e2e/actions/user_test.go +++ b/op-e2e/actions/user_test.go @@ -1,8 +1,10 @@ package actions import ( + "fmt" "math/rand" "testing" + "time" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -13,13 +15,41 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -type regolithScheduledTest struct { - name string - regolithTime *hexutil.Uint64 - activateRegolith bool +type hardforkScheduledTest struct { + regolithTime *hexutil.Uint64 + canyonTime *hexutil.Uint64 + deltaTime *hexutil.Uint64 + ecotoneTime *hexutil.Uint64 + fjordTime *hexutil.Uint64 + runToFork string } -// TestCrossLayerUser tests that common actions of the CrossLayerUser actor work in various regolith configurations: +func (tc *hardforkScheduledTest) SetFork(fork string, v uint64) { + *tc.fork(fork) = (*hexutil.Uint64)(&v) +} + +func (tc *hardforkScheduledTest) GetFork(fork string) *uint64 { + return (*uint64)(*tc.fork(fork)) +} + +func (tc *hardforkScheduledTest) fork(fork string) **hexutil.Uint64 { + switch fork { + case "fjord": + return &tc.fjordTime + case "ecotone": + return &tc.ecotoneTime + case "delta": + return &tc.deltaTime + case "canyon": + return &tc.canyonTime + case "regolith": + return &tc.regolithTime + default: + panic(fmt.Errorf("unrecognized fork: %s", fork)) + } +} + +// TestCrossLayerUser tests that common actions of the CrossLayerUser actor work in various hardfork configurations: // - transact on L1 // - transact on L2 // - deposit on L1 @@ -28,44 +58,97 @@ type regolithScheduledTest struct { // - wait 1 week + 1 second // - finalize withdrawal on L1 func TestCrossLayerUser(t *testing.T) { - zeroTime := hexutil.Uint64(0) - futureTime := hexutil.Uint64(20) - farFutureTime := hexutil.Uint64(2000) - tests := []regolithScheduledTest{ - {name: "NoRegolith", regolithTime: nil, activateRegolith: false}, - {name: "NotYetRegolith", regolithTime: &farFutureTime, activateRegolith: false}, - {name: "RegolithAtGenesis", regolithTime: &zeroTime, activateRegolith: true}, - {name: "RegolithAfterGenesis", regolithTime: &futureTime, activateRegolith: true}, + futureTime := uint64(20) + farFutureTime := uint64(2000) + + forks := []string{ + "regolith", + "canyon", + "delta", + "ecotone", + "fjord", } - for _, test := range tests { - test := test // Use a fixed reference as the tests run in parallel - t.Run(test.name, func(gt *testing.T) { - runCrossLayerUserTest(gt, test) + for i, fork := range forks { + i := i + fork := fork + t.Run("fork_"+fork, func(t *testing.T) { + t.Run("at_genesis", func(t *testing.T) { + tc := hardforkScheduledTest{} + for _, f := range forks[:i+1] { // activate, all up to and incl this fork, at genesis + tc.SetFork(f, 0) + } + runCrossLayerUserTest(t, tc) + }) + t.Run("after_genesis", func(t *testing.T) { + tc := hardforkScheduledTest{} + for _, f := range forks[:i] { // activate, all up to this fork, at genesis + tc.SetFork(f, 0) + } + // activate this fork after genesis + tc.SetFork(fork, futureTime) + tc.runToFork = fork + runCrossLayerUserTest(t, tc) + }) + t.Run("not_yet", func(t *testing.T) { + tc := hardforkScheduledTest{} + for _, f := range forks[:i] { // activate, all up to this fork, at genesis + tc.SetFork(f, 0) + } + // activate this fork later + tc.SetFork(fork, farFutureTime) + if i > 0 { + tc.runToFork = forks[i-1] + } + runCrossLayerUserTest(t, tc) + }) }) } } -func runCrossLayerUserTest(gt *testing.T, test regolithScheduledTest) { +func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + // This overwrites all deploy-config settings, + // so even when the deploy-config defaults change, we test the right transitions. dp.DeployConfig.L2GenesisRegolithTimeOffset = test.regolithTime + dp.DeployConfig.L2GenesisCanyonTimeOffset = test.canyonTime + dp.DeployConfig.L2GenesisDeltaTimeOffset = test.deltaTime + dp.DeployConfig.L2GenesisEcotoneTimeOffset = test.ecotoneTime + dp.DeployConfig.L2GenesisFjordTimeOffset = test.fjordTime + + if test.canyonTime != nil { + require.Zero(t, uint64(*test.canyonTime)%uint64(dp.DeployConfig.L2BlockTime), "canyon fork must be aligned") + } + if test.ecotoneTime != nil { + require.Zero(t, uint64(*test.ecotoneTime)%uint64(dp.DeployConfig.L2BlockTime), "ecotone fork must be aligned") + } + sd := e2eutils.Setup(t, dp, defaultAlloc) - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) require.Equal(t, dp.Secrets.Addresses().Batcher, dp.DeployConfig.BatchSenderAddress) require.Equal(t, dp.Secrets.Addresses().Proposer, dp.DeployConfig.L2OutputOracleProposer) miner, seqEngine, seq := setupSequencerTest(t, sd, log) - batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ - MinL1TxSize: 0, - MaxL1TxSize: 128_000, - BatcherKey: dp.Secrets.Batcher, - }, seq.RollupClient(), miner.EthClient(), seqEngine.EthClient()) - proposer := NewL2Proposer(t, log, &ProposerCfg{ - OutputOracleAddr: sd.DeploymentsL1.L2OutputOracleProxy, - ProposerKey: dp.Secrets.Proposer, - AllowNonFinalized: true, - }, miner.EthClient(), seq.RollupClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, DefaultBatcherCfg(dp), + seq.RollupClient(), miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + + var proposer *L2Proposer + if e2eutils.UseFPAC() { + proposer = NewL2Proposer(t, log, &ProposerCfg{ + DisputeGameFactoryAddr: &sd.DeploymentsL1.DisputeGameFactoryProxy, + ProposalInterval: 6 * time.Second, + DisputeGameType: 0, + ProposerKey: dp.Secrets.Proposer, + AllowNonFinalized: true, + }, miner.EthClient(), seq.RollupClient()) + } else { + proposer = NewL2Proposer(t, log, &ProposerCfg{ + OutputOracleAddr: &sd.DeploymentsL1.L2OutputOracleProxy, + ProposerKey: dp.Secrets.Proposer, + AllowNonFinalized: true, + }, miner.EthClient(), seq.RollupClient()) + } // need to start derivation before we can make L2 blocks seq.ActL2PipelineFull(t) @@ -97,16 +180,18 @@ func runCrossLayerUserTest(gt *testing.T, test regolithScheduledTest) { seq.ActL2StartBlock(t) seq.ActL2EndBlock(t) - if test.activateRegolith { - // advance L2 enough to activate regolith fork - seq.ActBuildL2ToRegolith(t) + if test.runToFork != "" { + forkTime := test.GetFork(test.runToFork) + require.NotNil(t, forkTime, "fork we are running up to must be configured") + // advance L2 enough to activate the fork we are running up to + seq.ActBuildL2ToTime(t, *forkTime) } // Check Regolith is active or not by confirming the system info tx is not a system tx infoTx, err := l2Cl.TransactionInBlock(t.Ctx(), seq.L2Unsafe().Hash, 0) require.NoError(t, err) require.True(t, infoTx.IsDepositTx()) // Should only be a system tx if regolith is not enabled - require.Equal(t, !test.activateRegolith, infoTx.IsSystemTx()) + require.Equal(t, !seq.rollupCfg.IsRegolith(seq.L2Unsafe().Time), infoTx.IsSystemTx()) // regular L2 tx, in new L2 block alice.L2.ActResetTxOpts(t) @@ -194,6 +279,25 @@ func runCrossLayerUserTest(gt *testing.T, test regolithScheduledTest) { miner.ActL1StartBlock(13)(t) miner.ActL1EndBlock(t) + // If using FPAC we need to resolve the game + if e2eutils.UseFPAC() { + // Resolve the root claim + alice.ActResolveClaim(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(alice.Address())(t) + miner.ActL1EndBlock(t) + // Resolve the game + alice.L1.ActCheckReceiptStatusOfLastTx(true)(t) + alice.ActResolve(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(alice.Address())(t) + miner.ActL1EndBlock(t) + // Create an empty block to pass the air-gap window + alice.L1.ActCheckReceiptStatusOfLastTx(true)(t) + miner.ActL1StartBlock(13)(t) + miner.ActL1EndBlock(t) + } + // make the L1 finalize withdrawal tx alice.ActCompleteWithdrawal(t) // include completed withdrawal in new L1 block @@ -208,5 +312,5 @@ func runCrossLayerUserTest(gt *testing.T, test regolithScheduledTest) { require.NoError(t, err) require.True(t, infoTx.IsDepositTx()) // Should only be a system tx if regolith is not enabled - require.Equal(t, !test.activateRegolith, infoTx.IsSystemTx()) + require.Equal(t, !seq.rollupCfg.IsRegolith(seq.L2Unsafe().Time), infoTx.IsSystemTx()) } diff --git a/op-e2e/bridge_test.go b/op-e2e/bridge_test.go index 9c5ab46c52a5..d3092d1a6e48 100644 --- a/op-e2e/bridge_test.go +++ b/op-e2e/bridge_test.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/receipts" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" @@ -30,13 +31,13 @@ func TestERC20BridgeDeposits(t *testing.T) { require.Nil(t, err, "Error starting up system") defer sys.Close() - log := testlog.Logger(t, log.LvlInfo) + log := testlog.Logger(t, log.LevelInfo) log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) l1Client := sys.Clients["l1"] l2Client := sys.Clients["sequencer"] - opts, err := bind.NewKeyedTransactorWithChainID(sys.cfg.Secrets.Alice, cfg.L1ChainIDBig()) + opts, err := bind.NewKeyedTransactorWithChainID(sys.Cfg.Secrets.Alice, cfg.L1ChainIDBig()) require.Nil(t, err) // Deploy WETH9 @@ -57,23 +58,17 @@ func TestERC20BridgeDeposits(t *testing.T) { require.Equal(t, big.NewInt(params.Ether), wethBalance) // Deploy L2 WETH9 - l2Opts, err := bind.NewKeyedTransactorWithChainID(sys.cfg.Secrets.Alice, cfg.L2ChainIDBig()) + l2Opts, err := bind.NewKeyedTransactorWithChainID(sys.Cfg.Secrets.Alice, cfg.L2ChainIDBig()) require.NoError(t, err) optimismMintableTokenFactory, err := bindings.NewOptimismMintableERC20Factory(predeploys.OptimismMintableERC20FactoryAddr, l2Client) require.NoError(t, err) tx, err = optimismMintableTokenFactory.CreateOptimismMintableERC20(l2Opts, weth9Address, "L2-WETH", "L2-WETH") require.NoError(t, err) - _, err = wait.ForReceiptOK(context.Background(), l2Client, tx.Hash()) + rcpt, err := wait.ForReceiptOK(context.Background(), l2Client, tx.Hash()) require.NoError(t, err) - // Get the deployment event to have access to the L2 WETH9 address - it, err := optimismMintableTokenFactory.FilterOptimismMintableERC20Created(&bind.FilterOpts{Start: 0}, nil, nil) - require.NoError(t, err) - var event *bindings.OptimismMintableERC20FactoryOptimismMintableERC20Created - for it.Next() { - event = it.Event - } - require.NotNil(t, event) + event, err := receipts.FindLog(rcpt.Logs, optimismMintableTokenFactory.ParseOptimismMintableERC20Created) + require.NoError(t, err, "Should emit ERC20Created event") // Approve WETH9 with the bridge tx, err = WETH9.Approve(opts, cfg.L1Deployments.L1StandardBridgeProxy, new(big.Int).SetUint64(math.MaxUint64)) @@ -97,13 +92,8 @@ func TestERC20BridgeDeposits(t *testing.T) { portal, err := bindings.NewOptimismPortal(cfg.L1Deployments.OptimismPortalProxy, l1Client) require.NoError(t, err) - depIt, err := portal.FilterTransactionDeposited(&bind.FilterOpts{Start: 0}, nil, nil, nil) - require.NoError(t, err) - var depositEvent *bindings.OptimismPortalTransactionDeposited - for depIt.Next() { - depositEvent = depIt.Event - } - require.NotNil(t, depositEvent) + depositEvent, err := receipts.FindLog(depositReceipt.Logs, portal.ParseTransactionDeposited) + require.NoError(t, err, "Should emit deposit event") depositTx, err := derive.UnmarshalDepositLogEvent(&depositEvent.Raw) require.NoError(t, err) diff --git a/op-e2e/build_helper.go b/op-e2e/build_helper.go index 24c1be94c1d1..b84240135c68 100644 --- a/op-e2e/build_helper.go +++ b/op-e2e/build_helper.go @@ -2,8 +2,8 @@ package op_e2e import ( "context" - "os" "os/exec" + "strings" "testing" "time" @@ -17,9 +17,10 @@ func BuildOpProgramClient(t *testing.T) string { defer cancel() cmd := exec.CommandContext(ctx, "make", "op-program-client") cmd.Dir = "../op-program" - cmd.Stdout = os.Stdout // for debugging - cmd.Stderr = os.Stderr // for debugging - require.NoError(t, cmd.Run(), "Failed to build op-program-client") + var out strings.Builder + cmd.Stdout = &out + cmd.Stderr = &out + require.NoErrorf(t, cmd.Run(), "Failed to build op-program-client: %v", &out) t.Log("Built op-program-client successfully") return "../op-program/bin/op-program-client" } diff --git a/op-e2e/config/init.go b/op-e2e/config/init.go index 80e21761b08c..4d7a0a7f432c 100644 --- a/op-e2e/config/init.go +++ b/op-e2e/config/init.go @@ -10,19 +10,33 @@ import ( "testing" "time" + "golang.org/x/exp/slog" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-e2e/external" + op_service "github.com/ethereum-optimism/optimism/op-service" oplog "github.com/ethereum-optimism/optimism/op-service/log" ) +// legacy geth log levels - the geth command line --verbosity flag wasn't +// migrated to use slog's numerical levels. +const ( + LegacyLevelCrit = iota + LegacyLevelError + LegacyLevelWarn + LegacyLevelInfo + LegacyLevelDebug + LegacyLevelTrace +) + var ( // All of the following variables are set in the init function // and read from JSON files on disk that are generated by the - // foundry deploy script. The are globally exported to be used + // foundry deploy script. These are globally exported to be used // in end to end tests. // L1Allocs represents the L1 genesis block state. @@ -38,7 +52,7 @@ var ( // ExternalL2TestParms is additional metadata for executing external L2 // tests. ExternalL2TestParms external.TestParms - // EthNodeVerbosity is the level of verbosity to output + // EthNodeVerbosity is the (legacy geth) level of verbosity to output EthNodeVerbosity int ) @@ -49,7 +63,7 @@ func init() { if err != nil { panic(err) } - root, err := findMonorepoRoot(cwd) + root, err := op_service.FindMonorepoRoot(cwd) if err != nil { panic(err) } @@ -62,26 +76,29 @@ func init() { flag.StringVar(&l1DeploymentsPath, "l1-deployments", defaultL1DeploymentsPath, "") flag.StringVar(&deployConfigPath, "deploy-config", defaultDeployConfigPath, "") flag.StringVar(&externalL2, "externalL2", "", "Enable tests with external L2") - flag.IntVar(&EthNodeVerbosity, "ethLogVerbosity", int(log.LvlInfo), "The level of verbosity to use for the eth node logs") + flag.IntVar(&EthNodeVerbosity, "ethLogVerbosity", LegacyLevelInfo, "The (legacy geth) level of verbosity to use for the eth node logs") testing.Init() // Register test flags before parsing flag.Parse() // Setup global logger - lvl := log.Lvl(EthNodeVerbosity) - if lvl < log.LvlCrit { - log.Root().SetHandler(log.DiscardHandler()) - } else if lvl > log.LvlTrace { // clip to trace level - lvl = log.LvlTrace + lvl := log.FromLegacyLevel(EthNodeVerbosity) + var handler slog.Handler + if lvl > log.LevelCrit { + handler = log.DiscardHandler() + } else { + if lvl < log.LevelTrace { // clip to trace level + lvl = log.LevelTrace + } + // We cannot attach a testlog logger, + // because the global logger is shared between different independent parallel tests. + // Tests that write to a testlogger of another finished test fail. + handler = oplog.NewLogHandler(os.Stdout, oplog.CLIConfig{ + Level: lvl, + Color: false, // some CI logs do not handle colors well + Format: oplog.FormatTerminal, + }) } - // We cannot attach a testlog logger, - // because the global logger is shared between different independent parallel tests. - // Tests that write to a testlogger of another finished test fail. - h := oplog.NewLogHandler(os.Stdout, oplog.CLIConfig{ - Level: lvl, - Color: false, // some CI logs do not handle colors well - Format: oplog.FormatTerminal, - }) - oplog.SetGlobalLogHandler(h) + oplog.SetGlobalLogHandler(handler) if err := allExist(l1AllocsPath, l1DeploymentsPath, deployConfigPath); err != nil { return @@ -158,25 +175,3 @@ func allExist(filenames ...string) error { } return nil } - -// findMonorepoRoot will recursively search upwards for a go.mod file. -// This depends on the structure of the monorepo having a go.mod file at the root. -func findMonorepoRoot(startDir string) (string, error) { - dir, err := filepath.Abs(startDir) - if err != nil { - return "", err - } - for { - modulePath := filepath.Join(dir, "go.mod") - if _, err := os.Stat(modulePath); err == nil { - return dir, nil - } - parentDir := filepath.Dir(dir) - // Check if we reached the filesystem root - if parentDir == dir { - break - } - dir = parentDir - } - return "", fmt.Errorf("monorepo root not found") -} diff --git a/op-e2e/deposit_test.go b/op-e2e/deposit_test.go index 6a6ee774b508..15377060f555 100644 --- a/op-e2e/deposit_test.go +++ b/op-e2e/deposit_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -16,13 +18,13 @@ import ( func TestMintOnRevertedDeposit(t *testing.T) { InitParallel(t) cfg := DefaultSystemConfig(t) - + delete(cfg.Nodes, "verifier") sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") defer sys.Close() l1Client := sys.Clients["l1"] - l2Verif := sys.Clients["verifier"] + l2Verif := sys.Clients["sequencer"] // create signer aliceKey := cfg.Secrets.Alice @@ -51,14 +53,15 @@ func TestMintOnRevertedDeposit(t *testing.T) { }) // Confirm balance - ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) - endBalance, err := l2Verif.BalanceAt(ctx, fromAddr, nil) + ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second) + endBalance, err := wait.ForBalanceChange(ctx, l2Verif, fromAddr, startBalance) cancel() require.Nil(t, err) + ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) toAddrBalance, err := l2Verif.BalanceAt(ctx, toAddr, nil) - require.NoError(t, err) cancel() + require.NoError(t, err) diff := new(big.Int) diff = diff.Sub(endBalance, startBalance) diff --git a/op-e2e/e2eutils/batcher/batcher.go b/op-e2e/e2eutils/batcher/batcher.go new file mode 100644 index 000000000000..8f3e273dfbeb --- /dev/null +++ b/op-e2e/e2eutils/batcher/batcher.go @@ -0,0 +1,56 @@ +package batcher + +import ( + "context" + "crypto/ecdsa" + "math/big" + "math/rand" + "testing" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/testutils" + gethTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" +) + +type Helper struct { + t *testing.T + privKey *ecdsa.PrivateKey + rollupCfg *rollup.Config + l1Client *ethclient.Client +} + +func NewHelper(t *testing.T, privKey *ecdsa.PrivateKey, rollupCfg *rollup.Config, l1Client *ethclient.Client) *Helper { + return &Helper{ + t: t, + privKey: privKey, + rollupCfg: rollupCfg, + l1Client: l1Client, + } +} + +func (h *Helper) SendLargeInvalidBatch(ctx context.Context) { + nonce, err := h.l1Client.PendingNonceAt(ctx, crypto.PubkeyToAddress(h.privKey.PublicKey)) + require.NoError(h.t, err, "Should get next batcher nonce") + + maxTxDataSize := 131072 // As per the Ethereum spec. + data := testutils.RandomData(rand.New(rand.NewSource(9849248)), maxTxDataSize-200) + tx := gethTypes.MustSignNewTx(h.privKey, h.rollupCfg.L1Signer(), &gethTypes.DynamicFeeTx{ + ChainID: h.rollupCfg.L1ChainID, + Nonce: nonce, + GasTipCap: big.NewInt(1 * params.GWei), + GasFeeCap: big.NewInt(10 * params.GWei), + Gas: 5_000_000, + To: &h.rollupCfg.BatchInboxAddress, + Value: big.NewInt(0), + Data: data, + }) + err = h.l1Client.SendTransaction(ctx, tx) + require.NoError(h.t, err, "Should send large batch transaction") + _, err = wait.ForReceiptOK(ctx, h.l1Client, tx.Hash()) + require.NoError(h.t, err, "Tx should be ok") +} diff --git a/op-e2e/e2eutils/blobs.go b/op-e2e/e2eutils/blobs.go new file mode 100644 index 000000000000..730aae1d94c5 --- /dev/null +++ b/op-e2e/e2eutils/blobs.go @@ -0,0 +1,49 @@ +package e2eutils + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +// BlobsStore is a simple in-memory store of blobs, for testing purposes +type BlobsStore struct { + // blockhash -> blob versioned hash -> blob + blobs map[common.Hash]map[common.Hash]*eth.Blob +} + +func NewBlobStore() *BlobsStore { + return &BlobsStore{blobs: make(map[common.Hash]map[common.Hash]*eth.Blob)} +} + +func (store *BlobsStore) StoreBlob(blockHash common.Hash, versionedHash common.Hash, blob *eth.Blob) { + m, ok := store.blobs[blockHash] + if !ok { + m = make(map[common.Hash]*eth.Blob) + store.blobs[blockHash] = m + } + m[versionedHash] = blob +} + +func (store *BlobsStore) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { + out := make([]*eth.Blob, 0, len(hashes)) + m, ok := store.blobs[ref.Hash] + if !ok { + return nil, fmt.Errorf("no blobs known with given time: %w", ethereum.NotFound) + } + for _, h := range hashes { + b, ok := m[h.Hash] + if !ok { + return nil, fmt.Errorf("blob %d %s is not in store: %w", h.Index, h.Hash, ethereum.NotFound) + } + out = append(out, b) + } + return out, nil +} + +var _ derive.L1BlobsFetcher = (*BlobsStore)(nil) diff --git a/op-e2e/e2eutils/challenger/helper.go b/op-e2e/e2eutils/challenger/helper.go index fd5bb9a77e51..a662aff560fb 100644 --- a/op-e2e/e2eutils/challenger/helper.go +++ b/op-e2e/e2eutils/challenger/helper.go @@ -11,25 +11,33 @@ import ( "testing" "time" - op_challenger "github.com/ethereum-optimism/optimism/op-challenger" + "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/log" + + challenger "github.com/ethereum-optimism/optimism/op-challenger" "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/cliapp" "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/log" - "github.com/stretchr/testify/require" ) +type EndpointProvider interface { + NodeEndpoint(name string) string + L1BeaconEndpoint() string +} + type Helper struct { log log.Logger t *testing.T require *require.Assertions dir string - cancel func() - errors chan error + chl cliapp.Lifecycle } type Option func(config2 *config.Config) @@ -52,84 +60,116 @@ func WithPrivKey(key *ecdsa.PrivateKey) Option { } } -func WithAgreeProposedOutput(agree bool) Option { +func WithPollInterval(pollInterval time.Duration) Option { return func(c *config.Config) { - c.AgreeWithProposedOutput = agree + c.PollInterval = pollInterval } } -func WithAlphabet(alphabet string) Option { - return func(c *config.Config) { - c.TraceTypes = append(c.TraceTypes, config.TraceTypeAlphabet) - c.AlphabetTrace = alphabet +// findMonorepoRoot finds the relative path to the monorepo root +// Different tests might be nested in subdirectories of the op-e2e dir. +func findMonorepoRoot(t *testing.T) string { + path := "./" + // Only search up 5 directories + // Avoids infinite recursion if the root isn't found for some reason + for i := 0; i < 5; i++ { + _, err := os.Stat(path + "op-e2e") + if errors.Is(err, os.ErrNotExist) { + path = path + "../" + continue + } + require.NoErrorf(t, err, "Failed to stat %v even though it existed", path) + return path } + t.Fatalf("Could not find monorepo root, trying up to %v", path) + return "" } -func WithPollInterval(pollInterval time.Duration) Option { - return func(c *config.Config) { - c.PollInterval = pollInterval - } +func applyCannonConfig( + c *config.Config, + t *testing.T, + rollupCfg *rollup.Config, + l2Genesis *core.Genesis, + l2Endpoint string, +) { + require := require.New(t) + c.CannonL2 = l2Endpoint + root := findMonorepoRoot(t) + c.CannonBin = root + "cannon/bin/cannon" + c.CannonServer = root + "op-program/bin/op-program" + c.CannonAbsolutePreState = root + "op-program/bin/prestate.json" + c.CannonSnapshotFreq = 10_000_000 + + genesisBytes, err := json.Marshal(l2Genesis) + require.NoError(err, "marshall l2 genesis config") + genesisFile := filepath.Join(c.Datadir, "l2-genesis.json") + require.NoError(os.WriteFile(genesisFile, genesisBytes, 0o644)) + c.CannonL2GenesisPath = genesisFile + + rollupBytes, err := json.Marshal(rollupCfg) + require.NoError(err, "marshall rollup config") + rollupFile := filepath.Join(c.Datadir, "rollup.json") + require.NoError(os.WriteFile(rollupFile, rollupBytes, 0o644)) + c.CannonRollupConfigPath = rollupFile } func WithCannon( t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis, + rollupEndpoint string, l2Endpoint string, ) Option { return func(c *config.Config) { - require := require.New(t) c.TraceTypes = append(c.TraceTypes, config.TraceTypeCannon) - c.CannonL2 = l2Endpoint - c.CannonBin = "../cannon/bin/cannon" - c.CannonServer = "../op-program/bin/op-program" - c.CannonAbsolutePreState = "../op-program/bin/prestate.json" - c.CannonSnapshotFreq = 10_000_000 - - genesisBytes, err := json.Marshal(l2Genesis) - require.NoError(err, "marshall l2 genesis config") - genesisFile := filepath.Join(c.Datadir, "l2-genesis.json") - require.NoError(os.WriteFile(genesisFile, genesisBytes, 0644)) - c.CannonL2GenesisPath = genesisFile - - rollupBytes, err := json.Marshal(rollupCfg) - require.NoError(err, "marshall rollup config") - rollupFile := filepath.Join(c.Datadir, "rollup.json") - require.NoError(os.WriteFile(rollupFile, rollupBytes, 0644)) - c.CannonRollupConfigPath = rollupFile - } -} - -func NewChallenger(t *testing.T, ctx context.Context, l1Endpoint string, name string, options ...Option) *Helper { - log := testlog.Logger(t, log.LvlDebug).New("role", name) - log.Info("Creating challenger", "l1", l1Endpoint) - cfg := NewChallengerConfig(t, l1Endpoint, options...) - - errCh := make(chan error, 1) - ctx, cancel := context.WithCancel(ctx) - go func() { - defer close(errCh) - errCh <- op_challenger.Main(ctx, log, cfg) - }() + c.RollupRpc = rollupEndpoint + applyCannonConfig(c, t, rollupCfg, l2Genesis, l2Endpoint) + } +} + +func WithAlphabet(rollupEndpoint string) Option { + return func(c *config.Config) { + c.TraceTypes = append(c.TraceTypes, config.TraceTypeAlphabet) + c.RollupRpc = rollupEndpoint + } +} + +func NewChallenger(t *testing.T, ctx context.Context, sys EndpointProvider, name string, options ...Option) *Helper { + log := testlog.Logger(t, log.LevelDebug).New("role", name) + log.Info("Creating challenger") + cfg := NewChallengerConfig(t, sys, options...) + chl, err := challenger.Main(ctx, log, cfg) + require.NoError(t, err, "must init challenger") + require.NoError(t, chl.Start(ctx), "must start challenger") + return &Helper{ log: log, t: t, require: require.New(t), dir: cfg.Datadir, - cancel: cancel, - errors: errCh, + chl: chl, } } -func NewChallengerConfig(t *testing.T, l1Endpoint string, options ...Option) *config.Config { +func NewChallengerConfig(t *testing.T, sys EndpointProvider, options ...Option) *config.Config { // Use the NewConfig method to ensure we pick up any defaults that are set. - cfg := config.NewConfig(common.Address{}, l1Endpoint, true, t.TempDir()) + l1Endpoint := sys.NodeEndpoint("l1") + l1Beacon := sys.L1BeaconEndpoint() + cfg := config.NewConfig(common.Address{}, l1Endpoint, l1Beacon, t.TempDir()) + // The devnet can't set the absolute prestate output root because the contracts are deployed in L1 genesis + // before the L2 genesis is known. + cfg.AllowInvalidPrestate = true cfg.TxMgrConfig.NumConfirmations = 1 cfg.TxMgrConfig.ReceiptQueryInterval = 1 * time.Second if cfg.MaxConcurrency > 4 { // Limit concurrency to something more reasonable when there are also multiple tests executing in parallel cfg.MaxConcurrency = 4 } + cfg.MetricsConfig = metrics.CLIConfig{ + Enabled: true, + ListenAddr: "127.0.0.1", + ListenPort: 0, // Find any available port (avoids conflicts) + } for _, option := range options { option(&cfg) } @@ -156,16 +196,9 @@ func NewChallengerConfig(t *testing.T, l1Endpoint string, options ...Option) *co } func (h *Helper) Close() error { - h.cancel() - select { - case <-time.After(1 * time.Minute): - return errors.New("timed out while stopping challenger") - case err := <-h.errors: - if !errors.Is(err, context.Canceled) { - return err - } - return nil - } + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + return h.chl.Stop(ctx) } type GameAddr interface { diff --git a/op-e2e/e2eutils/disputegame/alphabet_helper.go b/op-e2e/e2eutils/disputegame/alphabet_helper.go index 8c179034e1ad..228dc52f4ba2 100644 --- a/op-e2e/e2eutils/disputegame/alphabet_helper.go +++ b/op-e2e/e2eutils/disputegame/alphabet_helper.go @@ -2,42 +2,36 @@ package disputegame import ( "context" + "math/big" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" ) type AlphabetGameHelper struct { FaultGameHelper - claimedAlphabet string } -func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, l1Endpoint string, name string, options ...challenger.Option) *challenger.Helper { +func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, sys challenger.EndpointProvider, name string, options ...challenger.Option) *challenger.Helper { opts := []challenger.Option{ challenger.WithFactoryAddress(g.factoryAddr), challenger.WithGameAddress(g.addr), - // By default the challenger agrees with the root claim (thus disagrees with the proposed output) - // This can be overridden by passing in options - challenger.WithAlphabet(g.claimedAlphabet), - challenger.WithAgreeProposedOutput(false), + challenger.WithAlphabet(g.system.RollupEndpoint("sequencer")), } opts = append(opts, options...) - c := challenger.NewChallenger(g.t, ctx, l1Endpoint, name, opts...) + c := challenger.NewChallenger(g.t, ctx, sys, name, opts...) g.t.Cleanup(func() { _ = c.Close() }) return c } -func (g *AlphabetGameHelper) CreateHonestActor(alphabetTrace string, depth uint64) *HonestHelper { +func (g *AlphabetGameHelper) CreateHonestActor(alphabetTrace string, depth types.Depth) *HonestHelper { return &HonestHelper{ t: g.t, require: g.require, game: &g.FaultGameHelper, - correctTrace: alphabet.NewTraceProvider(alphabetTrace, depth), + correctTrace: alphabet.NewTraceProvider(big.NewInt(0), depth), } } - -func (g *AlphabetGameHelper) CreateDishonestHelper(alphabetTrace string, depth uint64, defender bool) *DishonestHelper { - return newDishonestHelper(&g.FaultGameHelper, g.CreateHonestActor(alphabetTrace, depth), defender) -} diff --git a/op-e2e/e2eutils/disputegame/cannon_helper.go b/op-e2e/e2eutils/disputegame/cannon_helper.go deleted file mode 100644 index 8f633acec30a..000000000000 --- a/op-e2e/e2eutils/disputegame/cannon_helper.go +++ /dev/null @@ -1,54 +0,0 @@ -package disputegame - -import ( - "context" - "path/filepath" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon" - "github.com/ethereum-optimism/optimism/op-challenger/metrics" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" - "github.com/ethereum-optimism/optimism/op-node/rollup" - "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/log" -) - -type CannonGameHelper struct { - FaultGameHelper -} - -func (g *CannonGameHelper) StartChallenger(ctx context.Context, rollupCfg *rollup.Config, l2Genesis *core.Genesis, l1Endpoint string, l2Endpoint string, name string, options ...challenger.Option) *challenger.Helper { - opts := []challenger.Option{ - challenger.WithCannon(g.t, rollupCfg, l2Genesis, l2Endpoint), - challenger.WithFactoryAddress(g.factoryAddr), - challenger.WithGameAddress(g.addr), - } - opts = append(opts, options...) - c := challenger.NewChallenger(g.t, ctx, l1Endpoint, name, opts...) - g.t.Cleanup(func() { - _ = c.Close() - }) - return c -} - -func (g *CannonGameHelper) CreateHonestActor(ctx context.Context, rollupCfg *rollup.Config, l2Genesis *core.Genesis, l1Client bind.ContractCaller, l1Endpoint string, l2Endpoint string, options ...challenger.Option) *HonestHelper { - opts := []challenger.Option{ - challenger.WithCannon(g.t, rollupCfg, l2Genesis, l2Endpoint), - challenger.WithFactoryAddress(g.factoryAddr), - challenger.WithGameAddress(g.addr), - } - opts = append(opts, options...) - cfg := challenger.NewChallengerConfig(g.t, l1Endpoint, opts...) - logger := testlog.Logger(g.t, log.LvlInfo).New("role", "CorrectTrace") - maxDepth := g.MaxDepth(ctx) - provider, err := cannon.NewTraceProvider(ctx, logger, metrics.NoopMetrics, cfg, l1Client, filepath.Join(cfg.Datadir, "honest"), g.addr, uint64(maxDepth)) - g.require.NoError(err, "create cannon trace provider") - - return &HonestHelper{ - t: g.t, - require: g.require, - game: &g.FaultGameHelper, - correctTrace: provider, - } -} diff --git a/op-e2e/e2eutils/disputegame/claim_helper.go b/op-e2e/e2eutils/disputegame/claim_helper.go new file mode 100644 index 000000000000..eff88db4240a --- /dev/null +++ b/op-e2e/e2eutils/disputegame/claim_helper.go @@ -0,0 +1,133 @@ +package disputegame + +import ( + "context" + "fmt" + "slices" + "time" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +type ClaimHelper struct { + require *require.Assertions + game *OutputGameHelper + index int64 + parentIndex uint32 + position types.Position + claim common.Hash +} + +func newClaimHelper(game *OutputGameHelper, idx int64, claim ContractClaim) *ClaimHelper { + return &ClaimHelper{ + require: game.require, + game: game, + index: idx, + parentIndex: claim.ParentIndex, + position: types.NewPositionFromGIndex(claim.Position), + claim: claim.Claim, + } +} + +func (c *ClaimHelper) AgreesWithOutputRoot() bool { + return c.position.Depth()%2 == 0 +} + +func (c *ClaimHelper) IsRootClaim() bool { + return c.position.IsRootPosition() +} + +func (c *ClaimHelper) IsOutputRoot(ctx context.Context) bool { + splitDepth := c.game.SplitDepth(ctx) + return c.position.Depth() <= splitDepth +} + +func (c *ClaimHelper) IsOutputRootLeaf(ctx context.Context) bool { + splitDepth := c.game.SplitDepth(ctx) + return c.position.Depth() == splitDepth +} + +func (c *ClaimHelper) IsBottomGameRoot(ctx context.Context) bool { + splitDepth := c.game.SplitDepth(ctx) + return c.position.Depth() == splitDepth+1 +} + +func (c *ClaimHelper) IsMaxDepth(ctx context.Context) bool { + maxDepth := c.game.MaxDepth(ctx) + return c.position.Depth() == maxDepth +} + +func (c *ClaimHelper) Depth() types.Depth { + return c.position.Depth() +} + +// WaitForCounterClaim waits for the claim to be countered by another claim being posted. +// It returns a helper for the claim that countered this one. +func (c *ClaimHelper) WaitForCounterClaim(ctx context.Context, ignoreClaims ...*ClaimHelper) *ClaimHelper { + timeout := defaultTimeout + if c.IsOutputRootLeaf(ctx) { + // This is the first claim we need to run cannon on, so give it more time + timeout = timeout * 2 + } + counterIdx, counterClaim := c.game.waitForClaim(ctx, timeout, fmt.Sprintf("failed to find claim with parent idx %v", c.index), func(claimIdx int64, claim ContractClaim) bool { + return int64(claim.ParentIndex) == c.index && !containsClaim(claimIdx, ignoreClaims) + }) + return newClaimHelper(c.game, counterIdx, counterClaim) +} + +// WaitForCountered waits until the claim is countered either by a child claim or by a step call. +func (c *ClaimHelper) WaitForCountered(ctx context.Context) { + timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + err := wait.For(timedCtx, time.Second, func() (bool, error) { + latestData := c.game.getClaim(ctx, c.index) + return latestData.CounteredBy != common.Address{}, nil + }) + if err != nil { // Avoid waiting time capturing game data when there's no error + c.require.NoErrorf(err, "Claim %v was not countered\n%v", c.index, c.game.gameData(ctx)) + } +} + +func (c *ClaimHelper) RequireCorrectOutputRoot(ctx context.Context) { + c.require.True(c.IsOutputRoot(ctx), "Should not expect a valid output root in the bottom game") + expected, err := c.game.correctOutputProvider.Get(ctx, c.position) + c.require.NoError(err, "Failed to get correct output root") + c.require.Equalf(expected, c.claim, "Should have correct output root in claim %v and position %v", c.index, c.position) +} + +func (c *ClaimHelper) Attack(ctx context.Context, value common.Hash, opts ...MoveOpt) *ClaimHelper { + c.game.Attack(ctx, c.index, value, opts...) + return c.WaitForCounterClaim(ctx) +} + +func (c *ClaimHelper) Defend(ctx context.Context, value common.Hash, opts ...MoveOpt) *ClaimHelper { + c.game.Defend(ctx, c.index, value, opts...) + return c.WaitForCounterClaim(ctx) +} + +func (c *ClaimHelper) RequireDifferentClaimValue(other *ClaimHelper) { + c.require.NotEqual(c.claim, other.claim, "should have posted different claims") +} + +func (c *ClaimHelper) RequireOnlyCounteredBy(ctx context.Context, expected ...*ClaimHelper) { + claims := c.game.getAllClaims(ctx) + for idx, claim := range claims { + if int64(claim.ParentIndex) != c.index { + // Doesn't counter this claim, so ignore + continue + } + if !containsClaim(int64(idx), expected) { + // Found a countering claim not in the expected list. Fail. + c.require.FailNowf("Found unexpected countering claim", "Parent claim index: %v Game state:\n%v", c.index, c.game.gameData(ctx)) + } + } +} + +func containsClaim(claimIdx int64, haystack []*ClaimHelper) bool { + return slices.ContainsFunc(haystack, func(candidate *ClaimHelper) bool { + return candidate.index == claimIdx + }) +} diff --git a/op-e2e/e2eutils/disputegame/dishonest_helper.go b/op-e2e/e2eutils/disputegame/dishonest_helper.go index 6b6f1912c18e..1b5798a06f50 100644 --- a/op-e2e/e2eutils/disputegame/dishonest_helper.go +++ b/op-e2e/e2eutils/disputegame/dishonest_helper.go @@ -9,63 +9,21 @@ import ( "github.com/ethereum/go-ethereum/common" ) -type dishonestClaim struct { - ParentIndex int64 - IsAttack bool - Valid bool -} - type DishonestHelper struct { - *FaultGameHelper - *HonestHelper - claims map[dishonestClaim]bool + *OutputGameHelper + *OutputHonestHelper defender bool } -func newDishonestHelper(g *FaultGameHelper, correctTrace *HonestHelper, defender bool) *DishonestHelper { - return &DishonestHelper{g, correctTrace, make(map[dishonestClaim]bool), defender} -} - -func (t *DishonestHelper) Attack(ctx context.Context, claimIndex int64) { - c := dishonestClaim{claimIndex, true, false} - if t.claims[c] { - return - } - t.claims[c] = true - t.FaultGameHelper.Attack(ctx, claimIndex, common.Hash{byte(claimIndex)}) -} - -func (t *DishonestHelper) Defend(ctx context.Context, claimIndex int64) { - c := dishonestClaim{claimIndex, false, false} - if t.claims[c] { - return - } - t.claims[c] = true - t.FaultGameHelper.Defend(ctx, claimIndex, common.Hash{byte(claimIndex)}) -} - -func (t *DishonestHelper) AttackCorrect(ctx context.Context, claimIndex int64) { - c := dishonestClaim{claimIndex, true, true} - if t.claims[c] { - return - } - t.claims[c] = true - t.HonestHelper.Attack(ctx, claimIndex) -} - -func (t *DishonestHelper) DefendCorrect(ctx context.Context, claimIndex int64) { - c := dishonestClaim{claimIndex, false, true} - if t.claims[c] { - return - } - t.claims[c] = true - t.HonestHelper.Defend(ctx, claimIndex) +func newDishonestHelper(g *OutputGameHelper, correctTrace *OutputHonestHelper, defender bool) *DishonestHelper { + return &DishonestHelper{g, correctTrace, defender} } // ExhaustDishonestClaims makes all possible significant moves (mod honest challenger's) in a game. // It is very inefficient and should NOT be used on games with large depths -func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context) { +func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context, rootClaim *ClaimHelper) { depth := d.MaxDepth(ctx) + splitDepth := d.SplitDepth(ctx) move := func(claimIndex int64, claimData ContractClaim) { // dishonest level, valid attack @@ -76,26 +34,26 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context) { // honest level, invalid defense pos := types.NewPositionFromGIndex(claimData.Position) - if int64(pos.Depth()) == depth { + if pos.Depth() == depth { return } d.LogGameData(ctx) - d.FaultGameHelper.t.Logf("Dishonest moves against claimIndex %d", claimIndex) + d.OutputGameHelper.t.Logf("Dishonest moves against claimIndex %d", claimIndex) agreeWithLevel := d.defender == (pos.Depth()%2 == 0) if !agreeWithLevel { - d.AttackCorrect(ctx, claimIndex) - if claimIndex != 0 { - d.DefendCorrect(ctx, claimIndex) + d.OutputHonestHelper.Attack(ctx, claimIndex, WithIgnoreDuplicates()) + if claimIndex != 0 && pos.Depth() != splitDepth+1 { + d.OutputHonestHelper.Defend(ctx, claimIndex, WithIgnoreDuplicates()) } } - d.Attack(ctx, claimIndex) - if claimIndex != 0 { - d.Defend(ctx, claimIndex) + d.OutputGameHelper.Attack(ctx, claimIndex, common.Hash{byte(claimIndex)}, WithIgnoreDuplicates()) + if claimIndex != 0 && pos.Depth() != splitDepth+1 { + d.OutputGameHelper.Defend(ctx, claimIndex, common.Hash{byte(claimIndex)}, WithIgnoreDuplicates()) } } - var numClaimsSeen int64 + numClaimsSeen := rootClaim.index for { // Use a short timeout since we don't know the challenger will respond, // and this is only designed for the alphabet game where the response should be fast. @@ -105,12 +63,11 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context) { // There's nothing to respond to. break } - d.FaultGameHelper.require.NoError(err) + d.OutputGameHelper.require.NoError(err) - for i := numClaimsSeen; i < newCount; i++ { + for ; numClaimsSeen < newCount; numClaimsSeen++ { claimData := d.getClaim(ctx, numClaimsSeen) move(numClaimsSeen, claimData) - numClaimsSeen++ } } } diff --git a/op-e2e/e2eutils/disputegame/game_helper.go b/op-e2e/e2eutils/disputegame/game_helper.go index 6ce31f2f9c76..b23d54e6a101 100644 --- a/op-e2e/e2eutils/disputegame/game_helper.go +++ b/op-e2e/e2eutils/disputegame/game_helper.go @@ -8,7 +8,6 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -18,8 +17,6 @@ import ( "github.com/stretchr/testify/require" ) -const defaultTimeout = 5 * time.Minute - type FaultGameHelper struct { t *testing.T require *require.Assertions @@ -28,6 +25,7 @@ type FaultGameHelper struct { game *bindings.FaultDisputeGame factoryAddr common.Address addr common.Address + system DisputeSystem } func (g *FaultGameHelper) Addr() common.Address { @@ -35,7 +33,7 @@ func (g *FaultGameHelper) Addr() common.Address { } func (g *FaultGameHelper) GameDuration(ctx context.Context) time.Duration { - duration, err := g.game.GAMEDURATION(&bind.CallOpts{Context: ctx}) + duration, err := g.game.GameDuration(&bind.CallOpts{Context: ctx}) g.require.NoError(err, "failed to get game duration") return time.Duration(duration) * time.Second } @@ -44,31 +42,26 @@ func (g *FaultGameHelper) GameDuration(ctx context.Context) time.Duration { // This does not check that the number of claims is exactly the specified count to avoid intermittent failures // where a challenger posts an additional claim before this method sees the number of claims it was waiting for. func (g *FaultGameHelper) WaitForClaimCount(ctx context.Context, count int64) { - ctx, cancel := context.WithTimeout(ctx, defaultTimeout) + timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) defer cancel() - err := wait.For(ctx, time.Second, func() (bool, error) { - actual, err := g.game.ClaimDataLen(&bind.CallOpts{Context: ctx}) + err := wait.For(timedCtx, time.Second, func() (bool, error) { + actual, err := g.game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) if err != nil { return false, err } g.t.Log("Waiting for claim count", "current", actual, "expected", count, "game", g.addr) return actual.Cmp(big.NewInt(count)) >= 0, nil }) - g.require.NoErrorf(err, "Did not find expected claim count %v", count) -} - -type ContractClaim struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int + if err != nil { + g.LogGameData(ctx) + g.require.NoErrorf(err, "Did not find expected claim count %v", count) + } } -func (g *FaultGameHelper) MaxDepth(ctx context.Context) int64 { - depth, err := g.game.MAXGAMEDEPTH(&bind.CallOpts{Context: ctx}) +func (g *FaultGameHelper) MaxDepth(ctx context.Context) types.Depth { + depth, err := g.game.MaxGameDepth(&bind.CallOpts{Context: ctx}) g.require.NoError(err, "Failed to load game depth") - return depth.Int64() + return types.Depth(depth.Uint64()) } func (g *FaultGameHelper) waitForClaim(ctx context.Context, errorMsg string, predicate func(claim ContractClaim) bool) { @@ -148,7 +141,7 @@ func (g *FaultGameHelper) getClaimPosition(ctx context.Context, claimIdx int64) return types.NewPositionFromGIndex(g.getClaim(ctx, claimIdx).Position) } -func (g *FaultGameHelper) WaitForClaimAtDepth(ctx context.Context, depth int) { +func (g *FaultGameHelper) WaitForClaimAtDepth(ctx context.Context, depth types.Depth) { g.waitForClaim( ctx, fmt.Sprintf("Could not find claim depth %v", depth), @@ -165,7 +158,7 @@ func (g *FaultGameHelper) WaitForClaimAtMaxDepth(ctx context.Context, countered fmt.Sprintf("Could not find claim depth %v with countered=%v", maxDepth, countered), func(claim ContractClaim) bool { pos := types.NewPositionFromGIndex(claim.Position) - return int64(pos.Depth()) == maxDepth && claim.Countered == countered + return pos.Depth() == maxDepth && (claim.CounteredBy != common.Address{}) == countered }) } @@ -174,7 +167,7 @@ func (g *FaultGameHelper) WaitForAllClaimsCountered(ctx context.Context) { ctx, "Did not find all claims countered", func(claim ContractClaim) bool { - return !claim.Countered + return claim.CounteredBy == common.Address{} }) } @@ -250,18 +243,12 @@ func (g *FaultGameHelper) WaitForInactivity(ctx context.Context, numInactiveBloc } } -// Mover is a function that either attacks or defends the claim at parentClaimIdx -type Mover func(parentClaimIdx int64) - -// Stepper is a function that attempts to perform a step against the claim at parentClaimIdx -type Stepper func(parentClaimIdx int64) - // DefendRootClaim uses the supplied Mover to perform moves in an attempt to defend the root claim. // It is assumed that the output root being disputed is valid and that an honest op-challenger is already running. // When the game has reached the maximum depth it waits for the honest challenger to counter the leaf claim with step. -func (g *FaultGameHelper) DefendRootClaim(ctx context.Context, performMove Mover) { +func (g *FaultGameHelper) DefendRootClaim(ctx context.Context, performMove func(parentClaimIdx int64)) { maxDepth := g.MaxDepth(ctx) - for claimCount := int64(1); claimCount < maxDepth; { + for claimCount := int64(1); types.Depth(claimCount) < maxDepth; { g.LogGameData(ctx) claimCount++ // Wait for the challenger to counter @@ -281,9 +268,9 @@ func (g *FaultGameHelper) DefendRootClaim(ctx context.Context, performMove Mover // It is assumed that the output root being disputed is invalid and that an honest op-challenger is already running. // When the game has reached the maximum depth it calls the Stepper to attempt to counter the leaf claim. // Since the output root is invalid, it should not be possible for the Stepper to call step successfully. -func (g *FaultGameHelper) ChallengeRootClaim(ctx context.Context, performMove Mover, attemptStep Stepper) { +func (g *FaultGameHelper) ChallengeRootClaim(ctx context.Context, performMove func(parentClaimIdx int64), attemptStep Stepper) { maxDepth := g.MaxDepth(ctx) - for claimCount := int64(1); claimCount < maxDepth; { + for claimCount := int64(1); types.Depth(claimCount) < maxDepth; { g.LogGameData(ctx) // Perform our move performMove(claimCount - 1) @@ -300,12 +287,13 @@ func (g *FaultGameHelper) ChallengeRootClaim(ctx context.Context, performMove Mo g.LogGameData(ctx) // It's on us to call step if we want to win but shouldn't be possible - attemptStep(maxDepth) + attemptStep(int64(maxDepth)) } func (g *FaultGameHelper) WaitForNewClaim(ctx context.Context, checkPoint int64) (int64, error) { return g.waitForNewClaim(ctx, checkPoint, defaultTimeout) } + func (g *FaultGameHelper) waitForNewClaim(ctx context.Context, checkPoint int64, timeout time.Duration) (int64, error) { timedCtx, cancel := context.WithTimeout(ctx, timeout) defer cancel() @@ -335,10 +323,6 @@ func (g *FaultGameHelper) Defend(ctx context.Context, claimIdx int64, claim comm g.require.NoError(err, "Defend transaction was not OK") } -type ErrWithData interface { - ErrorData() interface{} -} - // StepFails attempts to call step and verifies that it fails with ValidStep() func (g *FaultGameHelper) StepFails(claimIdx int64, isAttack bool, stateData []byte, proof []byte) { g.t.Logf("Attempting step against claim %v isAttack: %v", claimIdx, isAttack) @@ -356,28 +340,9 @@ func (g *FaultGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) { g.require.NoError(err, "ResolveClaim transaction was not OK") } -// ResolveAllClaims resolves all subgames -// This function does not resolve the game. That's the responsibility of challengers -func (g *FaultGameHelper) ResolveAllClaims(ctx context.Context) { - loader := fault.NewLoader(g.game) - claims, err := loader.FetchClaims(ctx) - g.require.NoError(err, "Failed to fetch claims") - subgames := make(map[int]bool) - for i := len(claims) - 1; i > 0; i-- { - subgames[claims[i].ParentContractIndex] = true - // Subgames containing only one node are implicitly resolved - // i.e. uncountered and claims at MAX_DEPTH - if !subgames[i] { - continue - } - g.ResolveClaim(ctx, int64(i)) - } - g.ResolveClaim(ctx, 0) -} - func (g *FaultGameHelper) gameData(ctx context.Context) string { opts := &bind.CallOpts{Context: ctx} - maxDepth := int(g.MaxDepth(ctx)) + maxDepth := g.MaxDepth(ctx) claimCount, err := g.game.ClaimDataLen(opts) info := fmt.Sprintf("Claim count: %v\n", claimCount) g.require.NoError(err, "Fetching claim count") @@ -387,7 +352,7 @@ func (g *FaultGameHelper) gameData(ctx context.Context) string { pos := types.NewPositionFromGIndex(claim.Position) info = info + fmt.Sprintf("%v - Position: %v, Depth: %v, IndexAtDepth: %v Trace Index: %v, Value: %v, Countered: %v, ParentIndex: %v\n", - i, claim.Position.Int64(), pos.Depth(), pos.IndexAtDepth(), pos.TraceIndex(maxDepth), common.Hash(claim.Claim).Hex(), claim.Countered, claim.ParentIndex) + i, claim.Position.Int64(), pos.Depth(), pos.IndexAtDepth(), pos.TraceIndex(maxDepth), common.Hash(claim.Claim).Hex(), claim.CounteredBy, claim.ParentIndex) } status, err := g.game.Status(opts) g.require.NoError(err, "Load game status") diff --git a/op-e2e/e2eutils/disputegame/helper.go b/op-e2e/e2eutils/disputegame/helper.go index 7e08592502f5..291baa09374a 100644 --- a/op-e2e/e2eutils/disputegame/helper.go +++ b/op-e2e/e2eutils/disputegame/helper.go @@ -8,19 +8,19 @@ import ( "testing" "time" - "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/l2oo" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame/preimage" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -31,14 +31,11 @@ import ( "github.com/stretchr/testify/require" ) -const alphabetGameType uint8 = 255 -const cannonGameType uint8 = 0 -const alphabetGameDepth = 4 - -var lastAlphabetTraceIndex = big.NewInt(1< targetTraceIndex { + g.t.Logf("Bisecting: Attack incorrectly for step") + return claim.Attack(ctx, common.Hash{0xdd}) + } else if execClaimPosition.TraceIndex(execDepth).Uint64()+1 == targetTraceIndex { + g.t.Logf("Bisecting: Defend incorrectly for step") + return claim.Defend(ctx, common.Hash{0xcc}) + } else { + newPosition := execClaimPosition.Defend() + correct, err := provider.Get(ctx, newPosition) + g.require.NoError(err) + g.t.Logf("Bisecting: Defend correctly for step at newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + return claim.Defend(ctx, correct) + } + } + + // Attack or Defend depending on whether the claim we're responding to is to the left or right of the trace index + // Induce the honest challenger to attack or defend depending on whether our new position will be to the left or right of the trace index + if execClaimPosition.TraceIndex(execDepth).Uint64() < targetTraceIndex && claim.Depth() != splitDepth+1 { + newPosition := execClaimPosition.Defend() + if newPosition.TraceIndex(execDepth).Uint64() < targetTraceIndex { + g.t.Logf("Bisecting: Defend correct. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + correct, err := provider.Get(ctx, newPosition) + g.require.NoError(err) + return claim.Defend(ctx, correct) + } else { + g.t.Logf("Bisecting: Defend incorrect. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + return claim.Defend(ctx, common.Hash{0xaa}) + } + } else { + newPosition := execClaimPosition.Attack() + if newPosition.TraceIndex(execDepth).Uint64() < targetTraceIndex { + g.t.Logf("Bisecting: Attack correct. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + correct, err := provider.Get(ctx, newPosition) + g.require.NoError(err) + return claim.Attack(ctx, correct) + } else { + g.t.Logf("Bisecting: Attack incorrect. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + return claim.Attack(ctx, common.Hash{0xbb}) + } + } + } + + g.LogGameData(ctx) + // Initial bisect to put us on defense + mover := bisectTraceIndex(outputRootClaim) + leafClaim := g.DefendClaim(ctx, mover, bisectTraceIndex, WithoutWaitingForStep()) + + // Validate that the preimage was loaded correctly + g.require.NoError(preimageCheck(provider, targetTraceIndex)) + + // Now the preimage is available wait for the step call to succeed. + leafClaim.WaitForCountered(ctx) + g.LogGameData(ctx) +} + +func (g *OutputCannonGameHelper) VerifyPreimage(ctx context.Context, outputRootClaim *ClaimHelper, preimageKey preimage.Key) { + execDepth := g.ExecDepth(ctx) + + // Identifying the first state transition that loads a global preimage + provider, localContext := g.createCannonTraceProvider(ctx, "sequencer", outputRootClaim, challenger.WithPrivKey(deployer.TestKey)) + start := uint64(0) + found := false + for offset := uint32(0); ; offset += 4 { + preimageOpt := cannon.PreimageLoad(preimageKey, offset) + g.t.Logf("Searching for step with key %x and offset %v", preimageKey.PreimageKey(), offset) + targetTraceIndex, err := provider.FindStep(ctx, start, preimageOpt) + if errors.Is(err, io.EOF) { + // Did not find any more reads + g.require.True(found, "Should have found at least one preimage read") + g.t.Logf("Searching for step with key %x and offset %v did not find another read", preimageKey.PreimageKey(), offset) + return + } + g.require.NoError(err, "Failed to find step that loads requested preimage") + start = targetTraceIndex + found = true + + g.t.Logf("Target trace index: %v", targetTraceIndex) + pos := types.NewPosition(execDepth, new(big.Int).SetUint64(targetTraceIndex)) + g.require.Equal(targetTraceIndex, pos.TraceIndex(execDepth).Uint64()) + + prestate, proof, oracleData, err := provider.GetStepData(ctx, pos) + g.require.NoError(err, "Failed to get step data") + g.require.NotNil(oracleData, "Should have had required preimage oracle data") + g.require.Equal(common.Hash(preimageKey.PreimageKey()).Bytes(), oracleData.OracleKey, "Must have correct preimage key") + + tx, err := g.game.AddLocalData(g.opts, + oracleData.GetIdent(), + big.NewInt(outputRootClaim.index), + new(big.Int).SetUint64(uint64(oracleData.OracleOffset))) + g.require.NoError(err) + _, err = wait.ForReceiptOK(ctx, g.client, tx.Hash()) + g.require.NoError(err) + + expectedPostState, err := provider.Get(ctx, pos) + g.require.NoError(err, "Failed to get expected post state") + + callOpts := &bind.CallOpts{Context: ctx} + vmAddr, err := g.game.Vm(callOpts) + g.require.NoError(err, "Failed to get VM address") + + abi, err := bindings.MIPSMetaData.GetAbi() + g.require.NoError(err, "Failed to load MIPS ABI") + caller := batching.NewMultiCaller(g.client.Client(), batching.DefaultBatchSize) + result, err := caller.SingleCall(ctx, rpcblock.Latest, &batching.ContractCall{ + Abi: abi, + Addr: vmAddr, + Method: "step", + Args: []interface{}{ + prestate, proof, localContext, + }, + From: g.addr, + }) + g.require.NoError(err, "Failed to call step") + actualPostState := result.GetBytes32(0) + g.require.Equal(expectedPostState, common.Hash(actualPostState)) + } +} + +func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context, l2Node string, outputRootClaim *ClaimHelper, options ...challenger.Option) (*cannon.CannonTraceProviderForTest, common.Hash) { + splitDepth := g.SplitDepth(ctx) + g.require.EqualValues(outputRootClaim.Depth(), splitDepth+1, "outputRootClaim must be the root of an execution game") + + logger := testlog.Logger(g.t, log.LevelInfo).New("role", "CannonTraceProvider", "game", g.addr) + opt := g.defaultChallengerOptions(l2Node) + opt = append(opt, options...) + cfg := challenger.NewChallengerConfig(g.t, g.system, opt...) + + caller := batching.NewMultiCaller(g.system.NodeClient("l1").Client(), batching.DefaultBatchSize) + l2Client := g.system.NodeClient(l2Node) + contract, err := contracts.NewFaultDisputeGameContract(g.addr, caller) + g.require.NoError(err, "Failed to create game contact") + + prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) + g.require.NoError(err, "Failed to load block range") + rollupClient := g.system.RollupClient(l2Node) + prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock) + l1Head := g.getL1Head(ctx) + outputProvider := outputs.NewTraceProvider(logger, prestateProvider, rollupClient, l1Head, splitDepth, prestateBlock, poststateBlock) + + var localContext common.Hash + selector := split.NewSplitProviderSelector(outputProvider, splitDepth, func(ctx context.Context, depth types.Depth, pre types.Claim, post types.Claim) (types.TraceProvider, error) { + agreed, disputed, err := outputs.FetchProposals(ctx, outputProvider, pre, post) + g.require.NoError(err) + g.t.Logf("Using trace between blocks %v and %v\n", agreed.L2BlockNumber, disputed.L2BlockNumber) + localInputs, err := cannon.FetchLocalInputsFromProposals(ctx, l1Head.Hash, l2Client, agreed, disputed) + g.require.NoError(err, "Failed to fetch local inputs") + localContext = outputs.CreateLocalContext(pre, post) + dir := filepath.Join(cfg.Datadir, "cannon-trace") + subdir := filepath.Join(dir, localContext.Hex()) + return cannon.NewTraceProviderForTest(logger, metrics.NoopMetrics, cfg, localInputs, subdir, g.MaxDepth(ctx)-splitDepth-1), nil + }) + + claims, err := contract.GetAllClaims(ctx, rpcblock.Latest) + g.require.NoError(err) + game := types.NewGameState(claims, g.MaxDepth(ctx)) + + provider, err := selector(ctx, game, game.Claims()[outputRootClaim.parentIndex], outputRootClaim.position) + g.require.NoError(err) + translatingProvider := provider.(*trace.TranslatingProvider) + return translatingProvider.Original().(*cannon.CannonTraceProviderForTest), localContext +} + +func (g *OutputCannonGameHelper) defaultChallengerOptions(l2Node string) []challenger.Option { + return []challenger.Option{ + challenger.WithCannon(g.t, g.system.RollupCfg(), g.system.L2Genesis(), g.system.RollupEndpoint(l2Node), g.system.NodeEndpoint(l2Node)), + challenger.WithFactoryAddress(g.factoryAddr), + challenger.WithGameAddress(g.addr), + } +} diff --git a/op-e2e/e2eutils/disputegame/output_game_helper.go b/op-e2e/e2eutils/disputegame/output_game_helper.go new file mode 100644 index 000000000000..42ee42c8f3fc --- /dev/null +++ b/op-e2e/e2eutils/disputegame/output_game_helper.go @@ -0,0 +1,759 @@ +package disputegame + +import ( + "context" + "crypto/ecdsa" + "fmt" + "math/big" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/preimages" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + preimage "github.com/ethereum-optimism/optimism/op-preimage" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + gethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/stretchr/testify/require" +) + +const defaultTimeout = 5 * time.Minute + +type OutputGameHelper struct { + t *testing.T + require *require.Assertions + client *ethclient.Client + opts *bind.TransactOpts + game *bindings.FaultDisputeGame + factoryAddr common.Address + addr common.Address + correctOutputProvider *outputs.OutputTraceProvider + system DisputeSystem +} + +type moveCfg struct { + opts *bind.TransactOpts + ignoreDupes bool +} + +type MoveOpt interface { + Apply(cfg *moveCfg) +} + +type moveOptFn func(c *moveCfg) + +func (f moveOptFn) Apply(c *moveCfg) { + f(c) +} + +func WithTransactOpts(opts *bind.TransactOpts) MoveOpt { + return moveOptFn(func(c *moveCfg) { + c.opts = opts + }) +} + +func WithIgnoreDuplicates() MoveOpt { + return moveOptFn(func(c *moveCfg) { + c.ignoreDupes = true + }) +} + +func (g *OutputGameHelper) Addr() common.Address { + return g.addr +} + +func (g *OutputGameHelper) SplitDepth(ctx context.Context) types.Depth { + splitDepth, err := g.game.SplitDepth(&bind.CallOpts{Context: ctx}) + g.require.NoError(err, "failed to load split depth") + return types.Depth(splitDepth.Uint64()) +} + +func (g *OutputGameHelper) ExecDepth(ctx context.Context) types.Depth { + return g.MaxDepth(ctx) - g.SplitDepth(ctx) - 1 +} + +func (g *OutputGameHelper) L2BlockNum(ctx context.Context) uint64 { + blockNum, err := g.game.L2BlockNumber(&bind.CallOpts{Context: ctx}) + g.require.NoError(err, "failed to load l2 block number") + return blockNum.Uint64() +} + +func (g *OutputGameHelper) StartingBlockNum(ctx context.Context) uint64 { + blockNum, err := g.game.StartingBlockNumber(&bind.CallOpts{Context: ctx}) + g.require.NoError(err, "failed to load starting block number") + return blockNum.Uint64() +} + +func (g *OutputGameHelper) DisputeLastBlock(ctx context.Context) *ClaimHelper { + return g.DisputeBlock(ctx, g.L2BlockNum(ctx)) +} + +// DisputeBlock posts claims from both the honest and dishonest actor to progress the output root part of the game +// through to the split depth and the claims are setup such that the last block in the game range is the block +// to execute cannon on. ie the first block the honest and dishonest actors disagree about is the l2 block of the game. +func (g *OutputGameHelper) DisputeBlock(ctx context.Context, disputeBlockNum uint64) *ClaimHelper { + dishonestValue := g.GetClaimValue(ctx, 0) + correctRootClaim := g.correctOutputRoot(ctx, types.NewPositionFromGIndex(big.NewInt(1))) + rootIsValid := dishonestValue == correctRootClaim + if rootIsValid { + // Ensure that the dishonest actor is actually posting invalid roots. + // Otherwise, the honest challenger will defend our counter and ruin everything. + dishonestValue = common.Hash{0xff, 0xff, 0xff} + } + pos := types.NewPositionFromGIndex(big.NewInt(1)) + getClaimValue := func(parentClaim *ClaimHelper, claimPos types.Position) common.Hash { + claimBlockNum, err := g.correctOutputProvider.ClaimedBlockNumber(claimPos) + g.require.NoError(err, "failed to calculate claim block number") + if claimBlockNum < disputeBlockNum { + // Use the correct output root for all claims prior to the dispute block number + // This pushes the game to dispute the last block in the range + return g.correctOutputRoot(ctx, claimPos) + } + if rootIsValid == parentClaim.AgreesWithOutputRoot() { + // We are responding to a parent claim that agrees with a valid root, so we're being dishonest + return dishonestValue + } else { + // Otherwise we must be the honest actor so use the correct root + return g.correctOutputRoot(ctx, claimPos) + } + } + + claim := g.RootClaim(ctx) + for !claim.IsOutputRootLeaf(ctx) { + parentClaimBlockNum, err := g.correctOutputProvider.ClaimedBlockNumber(pos) + g.require.NoError(err, "failed to calculate parent claim block number") + if parentClaimBlockNum >= disputeBlockNum { + pos = pos.Attack() + claim = claim.Attack(ctx, getClaimValue(claim, pos)) + } else { + pos = pos.Defend() + claim = claim.Defend(ctx, getClaimValue(claim, pos)) + } + } + return claim +} + +func (g *OutputGameHelper) RootClaim(ctx context.Context) *ClaimHelper { + claim := g.getClaim(ctx, 0) + return newClaimHelper(g, 0, claim) +} + +func (g *OutputGameHelper) WaitForCorrectOutputRoot(ctx context.Context, claimIdx int64) { + g.WaitForClaimCount(ctx, claimIdx+1) + claim := g.getClaim(ctx, claimIdx) + output := g.correctOutputRoot(ctx, types.NewPositionFromGIndex(claim.Position)) + g.require.EqualValuesf(output, claim.Claim, "Incorrect output root at claim %v at position %v", claimIdx, claim.Position.Uint64()) +} + +func (g *OutputGameHelper) correctOutputRoot(ctx context.Context, pos types.Position) common.Hash { + outputRoot, err := g.correctOutputProvider.Get(ctx, pos) + g.require.NoErrorf(err, "Failed to get correct output for position %v", pos) + return outputRoot +} + +func (g *OutputGameHelper) GameDuration(ctx context.Context) time.Duration { + duration, err := g.game.GameDuration(&bind.CallOpts{Context: ctx}) + g.require.NoError(err, "failed to get game duration") + return time.Duration(duration) * time.Second +} + +func (g *OutputGameHelper) WaitForNoAvailableCredit(ctx context.Context, addr common.Address) { + timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + err := wait.For(timedCtx, time.Second, func() (bool, error) { + bal, err := g.game.Credit(&bind.CallOpts{Context: timedCtx}, addr) + if err != nil { + return false, err + } + g.t.Log("Waiting for zero available credit", "current", bal, "addr", addr) + return bal.Cmp(big.NewInt(0)) == 0, nil + }) + if err != nil { + g.LogGameData(ctx) + g.require.NoError(err, "Failed to wait for zero available credit") + } +} + +func (g *OutputGameHelper) AvailableCredit(ctx context.Context, addr common.Address) *big.Int { + credit, err := g.game.Credit(&bind.CallOpts{Context: ctx}, addr) + g.require.NoErrorf(err, "Failed to fetch available credit for %v", addr) + return credit +} + +func (g *OutputGameHelper) CreditUnlockDuration(ctx context.Context) time.Duration { + weth, err := g.game.Weth(&bind.CallOpts{Context: ctx}) + g.require.NoError(err, "Failed to get WETH contract") + contract, err := bindings.NewDelayedWETH(weth, g.client) + g.require.NoError(err) + period, err := contract.Delay(&bind.CallOpts{Context: ctx}) + g.require.NoError(err, "Failed to get WETH unlock period") + float, _ := period.Float64() + return time.Duration(float) * time.Second +} + +func (g *OutputGameHelper) WethBalance(ctx context.Context, addr common.Address) *big.Int { + weth, err := g.game.Weth(&bind.CallOpts{Context: ctx}) + g.require.NoError(err, "Failed to get WETH contract") + contract, err := bindings.NewDelayedWETH(weth, g.client) + g.require.NoError(err) + balance, err := contract.BalanceOf(&bind.CallOpts{Context: ctx}, addr) + g.require.NoError(err, "Failed to get WETH balance") + return balance +} + +// WaitForClaimCount waits until there are at least count claims in the game. +// This does not check that the number of claims is exactly the specified count to avoid intermittent failures +// where a challenger posts an additional claim before this method sees the number of claims it was waiting for. +func (g *OutputGameHelper) WaitForClaimCount(ctx context.Context, count int64) { + timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + err := wait.For(timedCtx, time.Second, func() (bool, error) { + actual, err := g.game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) + if err != nil { + return false, err + } + g.t.Log("Waiting for claim count", "current", actual, "expected", count, "game", g.addr) + return actual.Cmp(big.NewInt(count)) >= 0, nil + }) + if err != nil { + g.LogGameData(ctx) + g.require.NoErrorf(err, "Did not find expected claim count %v", count) + } +} + +type ContractClaim struct { + ParentIndex uint32 + CounteredBy common.Address + Claimant common.Address + Bond *big.Int + Claim [32]byte + Position *big.Int + Clock *big.Int +} + +func (g *OutputGameHelper) MaxDepth(ctx context.Context) types.Depth { + depth, err := g.game.MaxGameDepth(&bind.CallOpts{Context: ctx}) + g.require.NoError(err, "Failed to load game depth") + return types.Depth(depth.Uint64()) +} + +func (g *OutputGameHelper) waitForClaim(ctx context.Context, timeout time.Duration, errorMsg string, predicate func(claimIdx int64, claim ContractClaim) bool) (int64, ContractClaim) { + timedCtx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + var matchedClaim ContractClaim + var matchClaimIdx int64 + err := wait.For(timedCtx, time.Second, func() (bool, error) { + count, err := g.game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) + if err != nil { + return false, fmt.Errorf("retrieve number of claims: %w", err) + } + // Search backwards because the new claims are at the end and more likely the ones we want. + for i := count.Int64() - 1; i >= 0; i-- { + claimData, err := g.game.ClaimData(&bind.CallOpts{Context: timedCtx}, big.NewInt(i)) + if err != nil { + return false, fmt.Errorf("retrieve claim %v: %w", i, err) + } + if predicate(i, claimData) { + matchClaimIdx = i + matchedClaim = claimData + return true, nil + } + } + return false, nil + }) + if err != nil { // Avoid waiting time capturing game data when there's no error + g.require.NoErrorf(err, "%v\n%v", errorMsg, g.gameData(ctx)) + } + return matchClaimIdx, matchedClaim +} + +func (g *OutputGameHelper) waitForNoClaim(ctx context.Context, errorMsg string, predicate func(claim ContractClaim) bool) { + timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + err := wait.For(timedCtx, time.Second, func() (bool, error) { + count, err := g.game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) + if err != nil { + return false, fmt.Errorf("retrieve number of claims: %w", err) + } + // Search backwards because the new claims are at the end and more likely the ones we will fail on. + for i := count.Int64() - 1; i >= 0; i-- { + claimData, err := g.game.ClaimData(&bind.CallOpts{Context: timedCtx}, big.NewInt(i)) + if err != nil { + return false, fmt.Errorf("retrieve claim %v: %w", i, err) + } + if predicate(claimData) { + return false, nil + } + } + return true, nil + }) + if err != nil { // Avoid waiting time capturing game data when there's no error + g.require.NoErrorf(err, "%v\n%v", errorMsg, g.gameData(ctx)) + } +} + +func (g *OutputGameHelper) GetClaimValue(ctx context.Context, claimIdx int64) common.Hash { + g.WaitForClaimCount(ctx, claimIdx+1) + claim := g.getClaim(ctx, claimIdx) + return claim.Claim +} + +func (g *OutputGameHelper) getAllClaims(ctx context.Context) []ContractClaim { + count := g.getClaimCount(ctx) + var claims []ContractClaim + for i := int64(0); i < count; i++ { + claims = append(claims, g.getClaim(ctx, i)) + } + return claims +} + +// getClaim retrieves the claim data for a specific index. +// Note that it is deliberately not exported as tests should use WaitForClaim to avoid race conditions. +func (g *OutputGameHelper) getClaim(ctx context.Context, claimIdx int64) ContractClaim { + claimData, err := g.game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) + if err != nil { + g.require.NoErrorf(err, "retrieve claim %v", claimIdx) + } + return claimData +} + +func (g *OutputGameHelper) WaitForClaimAtDepth(ctx context.Context, depth types.Depth) { + g.waitForClaim( + ctx, + defaultTimeout, + fmt.Sprintf("Could not find claim depth %v", depth), + func(_ int64, claim ContractClaim) bool { + pos := types.NewPositionFromGIndex(claim.Position) + return pos.Depth() == depth + }) +} + +func (g *OutputGameHelper) WaitForClaimAtMaxDepth(ctx context.Context, countered bool) { + maxDepth := g.MaxDepth(ctx) + g.waitForClaim( + ctx, + defaultTimeout, + fmt.Sprintf("Could not find claim depth %v with countered=%v", maxDepth, countered), + func(_ int64, claim ContractClaim) bool { + pos := types.NewPositionFromGIndex(claim.Position) + return pos.Depth() == maxDepth && (claim.CounteredBy != common.Address{}) == countered + }) +} + +func (g *OutputGameHelper) WaitForAllClaimsCountered(ctx context.Context) { + g.waitForNoClaim( + ctx, + "Did not find all claims countered", + func(claim ContractClaim) bool { + return claim.CounteredBy == common.Address{} + }) +} + +func (g *OutputGameHelper) Resolve(ctx context.Context) { + ctx, cancel := context.WithTimeout(ctx, time.Minute) + defer cancel() + tx, err := g.game.Resolve(g.opts) + g.require.NoError(err) + _, err = wait.ForReceiptOK(ctx, g.client, tx.Hash()) + g.require.NoError(err) +} + +func (g *OutputGameHelper) Status(ctx context.Context) Status { + status, err := g.game.Status(&bind.CallOpts{Context: ctx}) + g.require.NoError(err) + return Status(status) +} + +func (g *OutputGameHelper) WaitForGameStatus(ctx context.Context, expected Status) { + g.t.Logf("Waiting for game %v to have status %v", g.addr, expected) + timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + err := wait.For(timedCtx, time.Second, func() (bool, error) { + ctx, cancel := context.WithTimeout(timedCtx, 30*time.Second) + defer cancel() + status, err := g.game.Status(&bind.CallOpts{Context: ctx}) + if err != nil { + return false, fmt.Errorf("game status unavailable: %w", err) + } + g.t.Logf("Game %v has state %v, waiting for state %v", g.addr, Status(status), expected) + return expected == Status(status), nil + }) + g.require.NoErrorf(err, "wait for game status. Game state: \n%v", g.gameData(ctx)) +} + +func (g *OutputGameHelper) WaitForInactivity(ctx context.Context, numInactiveBlocks int, untilGameEnds bool) { + g.t.Logf("Waiting for game %v to have no activity for %v blocks", g.addr, numInactiveBlocks) + headCh := make(chan *gethtypes.Header, 100) + headSub, err := g.client.SubscribeNewHead(ctx, headCh) + g.require.NoError(err) + defer headSub.Unsubscribe() + + var lastActiveBlock uint64 + for { + if untilGameEnds && g.Status(ctx) != StatusInProgress { + break + } + select { + case head := <-headCh: + if lastActiveBlock == 0 { + lastActiveBlock = head.Number.Uint64() + continue + } else if lastActiveBlock+uint64(numInactiveBlocks) < head.Number.Uint64() { + return + } + block, err := g.client.BlockByNumber(ctx, head.Number) + g.require.NoError(err) + numActions := 0 + for _, tx := range block.Transactions() { + if tx.To().Hex() == g.addr.Hex() { + numActions++ + } + } + if numActions != 0 { + g.t.Logf("Game %v has %v actions in block %d. Resetting inactivity timeout", g.addr, numActions, block.NumberU64()) + lastActiveBlock = head.Number.Uint64() + } + case err := <-headSub.Err(): + g.require.NoError(err) + case <-ctx.Done(): + g.require.Fail("Context canceled", ctx.Err()) + } + } +} + +// Mover is a function that either attacks or defends the claim at parentClaimIdx +type Mover func(parent *ClaimHelper) *ClaimHelper + +// Stepper is a function that attempts to perform a step against the claim at parentClaimIdx +type Stepper func(parentClaimIdx int64) + +type defendClaimCfg struct { + skipWaitingForStep bool +} + +type DefendClaimOpt func(cfg *defendClaimCfg) + +func WithoutWaitingForStep() DefendClaimOpt { + return func(cfg *defendClaimCfg) { + cfg.skipWaitingForStep = true + } +} + +// DefendClaim uses the supplied Mover to perform moves in an attempt to defend the supplied claim. +// It is assumed that the specified claim is invalid and that an honest op-challenger is already running. +// When the game has reached the maximum depth it waits for the honest challenger to counter the leaf claim with step. +// Returns the final leaf claim +func (g *OutputGameHelper) DefendClaim(ctx context.Context, claim *ClaimHelper, performMove Mover, opts ...DefendClaimOpt) *ClaimHelper { + g.t.Logf("Defending claim %v at depth %v", claim.index, claim.Depth()) + cfg := &defendClaimCfg{} + for _, opt := range opts { + opt(cfg) + } + for !claim.IsMaxDepth(ctx) { + g.LogGameData(ctx) + // Wait for the challenger to counter + claim = claim.WaitForCounterClaim(ctx) + g.LogGameData(ctx) + + // Respond with our own move + claim = performMove(claim) + } + + if !cfg.skipWaitingForStep { + claim.WaitForCountered(ctx) + } + return claim +} + +// ChallengeClaim uses the supplied functions to perform moves and steps in an attempt to challenge the supplied claim. +// It is assumed that the claim being disputed is valid and that an honest op-challenger is already running. +// When the game has reached the maximum depth it calls the Stepper to attempt to counter the leaf claim. +// Since the output root is valid, it should not be possible for the Stepper to call step successfully. +func (g *OutputGameHelper) ChallengeClaim(ctx context.Context, claim *ClaimHelper, performMove Mover, attemptStep Stepper) { + for !claim.IsMaxDepth(ctx) { + g.LogGameData(ctx) + // Perform our move + claim = performMove(claim) + + // Wait for the challenger to counter + g.LogGameData(ctx) + claim = claim.WaitForCounterClaim(ctx) + } + + // Confirm the game has reached max depth and the last claim hasn't been countered + g.WaitForClaimAtMaxDepth(ctx, false) + g.LogGameData(ctx) + + // It's on us to call step if we want to win but shouldn't be possible + attemptStep(claim.index) +} + +func (g *OutputGameHelper) getClaimCount(ctx context.Context) int64 { + claimCount, err := g.game.ClaimDataLen(&bind.CallOpts{Context: ctx}) + g.require.NoError(err, "Failed to get current claim count") + return claimCount.Int64() +} + +func (g *OutputGameHelper) WaitForNewClaim(ctx context.Context, checkPoint int64) (int64, error) { + return g.waitForNewClaim(ctx, checkPoint, defaultTimeout) +} + +func (g *OutputGameHelper) waitForNewClaim(ctx context.Context, checkPoint int64, timeout time.Duration) (int64, error) { + timedCtx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + var newClaimLen int64 + err := wait.For(timedCtx, time.Second, func() (bool, error) { + actual, err := g.game.ClaimDataLen(&bind.CallOpts{Context: ctx}) + if err != nil { + return false, err + } + newClaimLen = actual.Int64() + return actual.Cmp(big.NewInt(checkPoint)) > 0, nil + }) + return newClaimLen, err +} + +func (g *OutputGameHelper) moveCfg(opts ...MoveOpt) *moveCfg { + cfg := &moveCfg{ + opts: g.opts, + } + for _, opt := range opts { + opt.Apply(cfg) + } + return cfg +} + +func (g *OutputGameHelper) Attack(ctx context.Context, claimIdx int64, claim common.Hash, opts ...MoveOpt) { + g.t.Logf("Attacking claim %v with value %v", claimIdx, claim) + cfg := g.moveCfg(opts...) + + claimData, err := g.game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) + g.require.NoError(err, "Failed to get claim data") + pos := types.NewPositionFromGIndex(claimData.Position) + attackPos := pos.Attack() + transactOpts := g.makeBondedTransactOpts(ctx, pos.Attack().ToGIndex(), cfg.opts) + + err = g.sendMove(ctx, func() (*gethtypes.Transaction, error) { + return g.game.Attack(transactOpts, big.NewInt(claimIdx), claim) + }) + if err != nil { + if cfg.ignoreDupes && g.hasClaim(ctx, claimIdx, attackPos, claim) { + return + } + g.require.NoErrorf(err, "Defend transaction failed. Game state: \n%v", g.gameData(ctx)) + } +} + +func (g *OutputGameHelper) Defend(ctx context.Context, claimIdx int64, claim common.Hash, opts ...MoveOpt) { + g.t.Logf("Defending claim %v with value %v", claimIdx, claim) + cfg := g.moveCfg(opts...) + + claimData, err := g.game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) + g.require.NoError(err, "Failed to get claim data") + pos := types.NewPositionFromGIndex(claimData.Position) + defendPos := pos.Defend() + transactOpts := g.makeBondedTransactOpts(ctx, defendPos.ToGIndex(), cfg.opts) + + err = g.sendMove(ctx, func() (*gethtypes.Transaction, error) { + return g.game.Defend(transactOpts, big.NewInt(claimIdx), claim) + }) + if err != nil { + if cfg.ignoreDupes && g.hasClaim(ctx, claimIdx, defendPos, claim) { + return + } + g.require.NoErrorf(err, "Defend transaction failed. Game state: \n%v", g.gameData(ctx)) + } +} + +func (g *OutputGameHelper) hasClaim(ctx context.Context, parentIdx int64, pos types.Position, value common.Hash) bool { + claims := g.getAllClaims(ctx) + for _, claim := range claims { + if int64(claim.ParentIndex) == parentIdx && claim.Position.Cmp(pos.ToGIndex()) == 0 && claim.Claim == value { + return true + } + } + return false +} + +func (g *OutputGameHelper) sendMove(ctx context.Context, send func() (*gethtypes.Transaction, error)) error { + tx, err := send() + if err != nil { + return fmt.Errorf("transaction did not send: %w", err) + } + _, err = wait.ForReceiptOK(ctx, g.client, tx.Hash()) + if err != nil { + return fmt.Errorf("transaction was not ok: %w", err) + } + return nil +} + +func (g *OutputGameHelper) makeBondedTransactOpts(ctx context.Context, pos *big.Int, opts *bind.TransactOpts) *bind.TransactOpts { + bopts := *opts + bond, err := g.game.GetRequiredBond(&bind.CallOpts{Context: ctx}, pos) + g.require.NoError(err, "Failed to get required bond") + bopts.Value = bond + return &bopts +} + +type ErrWithData interface { + ErrorData() interface{} +} + +// StepFails attempts to call step and verifies that it fails with ValidStep() +func (g *OutputGameHelper) StepFails(claimIdx int64, isAttack bool, stateData []byte, proof []byte) { + g.t.Logf("Attempting step against claim %v isAttack: %v", claimIdx, isAttack) + _, err := g.game.Step(g.opts, big.NewInt(claimIdx), isAttack, stateData, proof) + errData, ok := err.(ErrWithData) + g.require.Truef(ok, "Error should provide ErrorData method: %v", err) + g.require.Equal("0xfb4e40dd", errData.ErrorData(), "Revert reason should be abi encoded ValidStep()") +} + +// ResolveClaim resolves a single subgame +func (g *OutputGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) { + tx, err := g.game.ResolveClaim(g.opts, big.NewInt(claimIdx)) + g.require.NoError(err, "ResolveClaim transaction did not send") + _, err = wait.ForReceiptOK(ctx, g.client, tx.Hash()) + g.require.NoError(err, "ResolveClaim transaction was not OK") +} + +// ChallengePeriod returns the challenge period fetched from the PreimageOracle contract. +// The returned uint64 value is the number of seconds for the challenge period. +func (g *OutputGameHelper) ChallengePeriod(ctx context.Context) uint64 { + oracle := g.oracle(ctx) + period, err := oracle.ChallengePeriod(ctx) + g.require.NoError(err, "Failed to get challenge period") + return period +} + +// WaitForChallengePeriodStart waits for the challenge period to start for a given large preimage claim. +func (g *OutputGameHelper) WaitForChallengePeriodStart(ctx context.Context, sender common.Address, data *types.PreimageOracleData) { + timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + err := wait.For(timedCtx, time.Second, func() (bool, error) { + ctx, cancel := context.WithTimeout(timedCtx, 30*time.Second) + defer cancel() + timestamp := g.ChallengePeriodStartTime(ctx, sender, data) + g.t.Log("Waiting for challenge period start", "timestamp", timestamp, "key", data.OracleKey, "game", g.addr) + return timestamp > 0, nil + }) + if err != nil { + g.LogGameData(ctx) + g.require.NoErrorf(err, "Failed to get challenge start period for preimage data %v", data) + } +} + +// ChallengePeriodStartTime returns the start time of the challenge period for a given large preimage claim. +// If the returned start time is 0, the challenge period has not started. +func (g *OutputGameHelper) ChallengePeriodStartTime(ctx context.Context, sender common.Address, data *types.PreimageOracleData) uint64 { + oracle := g.oracle(ctx) + uuid := preimages.NewUUID(sender, data) + metadata, err := oracle.GetProposalMetadata(ctx, rpcblock.Latest, keccakTypes.LargePreimageIdent{ + Claimant: sender, + UUID: uuid, + }) + g.require.NoError(err, "Failed to get proposal metadata") + if len(metadata) == 0 { + return 0 + } + return metadata[0].Timestamp +} + +func (g *OutputGameHelper) waitForPreimageInOracle(ctx context.Context, data *types.PreimageOracleData) { + timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + oracle := g.oracle(ctx) + err := wait.For(timedCtx, time.Second, func() (bool, error) { + g.t.Logf("Waiting for preimage (%v) to be present in oracle", common.Bytes2Hex(data.OracleKey)) + return oracle.GlobalDataExists(ctx, data) + }) + g.require.NoErrorf(err, "Did not find preimage (%v) in oracle", common.Bytes2Hex(data.OracleKey)) +} + +func (g *OutputGameHelper) uploadPreimage(ctx context.Context, data *types.PreimageOracleData, privateKey *ecdsa.PrivateKey) { + oracle := g.oracle(ctx) + boundOracle, err := bindings.NewPreimageOracle(oracle.Addr(), g.client) + g.require.NoError(err) + var tx *gethtypes.Transaction + switch data.OracleKey[0] { + case byte(preimage.PrecompileKeyType): + tx, err = boundOracle.LoadPrecompilePreimagePart( + g.opts, + new(big.Int).SetUint64(uint64(data.OracleOffset)), + data.GetPrecompileAddress(), + data.GetPrecompileInput(), + ) + default: + tx, err = boundOracle.LoadKeccak256PreimagePart(g.opts, new(big.Int).SetUint64(uint64(data.OracleOffset)), data.GetPreimageWithoutSize()) + } + g.require.NoError(err, "Failed to load preimage part") + _, err = wait.ForReceiptOK(ctx, g.client, tx.Hash()) + g.require.NoError(err) +} + +func (g *OutputGameHelper) oracle(ctx context.Context) *contracts.PreimageOracleContract { + caller := batching.NewMultiCaller(g.system.NodeClient("l1").Client(), batching.DefaultBatchSize) + contract, err := contracts.NewFaultDisputeGameContract(g.addr, caller) + g.require.NoError(err, "Failed to create game contract") + oracle, err := contract.GetOracle(ctx) + g.require.NoError(err, "Failed to create oracle contract") + return oracle +} + +func (g *OutputGameHelper) gameData(ctx context.Context) string { + opts := &bind.CallOpts{Context: ctx} + maxDepth := g.MaxDepth(ctx) + splitDepth := g.SplitDepth(ctx) + claimCount, err := g.game.ClaimDataLen(opts) + info := fmt.Sprintf("Claim count: %v\n", claimCount) + g.require.NoError(err, "Fetching claim count") + for i := int64(0); i < claimCount.Int64(); i++ { + claim, err := g.game.ClaimData(opts, big.NewInt(i)) + g.require.NoErrorf(err, "Fetch claim %v", i) + + pos := types.NewPositionFromGIndex(claim.Position) + extra := "" + if pos.Depth() <= splitDepth { + blockNum, err := g.correctOutputProvider.ClaimedBlockNumber(pos) + if err != nil { + } else { + extra = fmt.Sprintf("Block num: %v", blockNum) + } + } + info = info + fmt.Sprintf("%v - Position: %v, Depth: %v, IndexAtDepth: %v Trace Index: %v, ClaimHash: %v, Countered By: %v, ParentIndex: %v Claimant: %v Bond: %v %v\n", + i, claim.Position.Int64(), pos.Depth(), pos.IndexAtDepth(), pos.TraceIndex(maxDepth), common.Hash(claim.Claim).Hex(), claim.CounteredBy, claim.ParentIndex, claim.Claimant, claim.Bond, extra) + } + l2BlockNum := g.L2BlockNum(ctx) + status, err := g.game.Status(opts) + g.require.NoError(err, "Load game status") + return fmt.Sprintf("Game %v - %v - L2 Block: %v - Split Depth: %v - Max Depth: %v:\n%v\n", + g.addr, Status(status), l2BlockNum, splitDepth, maxDepth, info) +} + +func (g *OutputGameHelper) LogGameData(ctx context.Context) { + g.t.Log(g.gameData(ctx)) +} + +func (g *OutputGameHelper) Credit(ctx context.Context, addr common.Address) *big.Int { + opts := &bind.CallOpts{Context: ctx} + amt, err := g.game.Credit(opts, addr) + g.require.NoError(err) + return amt +} + +func (g *OutputGameHelper) getL1Head(ctx context.Context) eth.BlockID { + l1HeadHash, err := g.game.L1Head(&bind.CallOpts{Context: ctx}) + g.require.NoError(err, "Failed to load L1 head") + l1Header, err := g.client.HeaderByHash(ctx, l1HeadHash) + g.require.NoError(err, "Failed to load L1 header") + l1Head := eth.HeaderBlockID(l1Header) + return l1Head +} diff --git a/op-e2e/e2eutils/disputegame/output_honest_helper.go b/op-e2e/e2eutils/disputegame/output_honest_helper.go new file mode 100644 index 000000000000..9258dfd797e4 --- /dev/null +++ b/op-e2e/e2eutils/disputegame/output_honest_helper.go @@ -0,0 +1,102 @@ +package disputegame + +import ( + "context" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/stretchr/testify/require" +) + +type OutputHonestHelper struct { + t *testing.T + require *require.Assertions + game *OutputGameHelper + contract *contracts.FaultDisputeGameContract + correctTrace types.TraceAccessor +} + +func (h *OutputHonestHelper) CounterClaim(ctx context.Context, claim *ClaimHelper, opts ...MoveOpt) *ClaimHelper { + game, target := h.loadState(ctx, claim.index) + value, err := h.correctTrace.Get(ctx, game, target, target.Position) + h.require.NoErrorf(err, "Failed to determine correct claim at position %v with g index %v", target.Position, target.Position.ToGIndex()) + if value == claim.claim { + return h.DefendClaim(ctx, claim, opts...) + } else { + return h.AttackClaim(ctx, claim, opts...) + } +} + +func (h *OutputHonestHelper) AttackClaim(ctx context.Context, claim *ClaimHelper, opts ...MoveOpt) *ClaimHelper { + h.Attack(ctx, claim.index, opts...) + return claim.WaitForCounterClaim(ctx) +} + +func (h *OutputHonestHelper) DefendClaim(ctx context.Context, claim *ClaimHelper, opts ...MoveOpt) *ClaimHelper { + h.Defend(ctx, claim.index, opts...) + return claim.WaitForCounterClaim(ctx) +} + +func (h *OutputHonestHelper) Attack(ctx context.Context, claimIdx int64, opts ...MoveOpt) { + // Ensure the claim exists + h.game.WaitForClaimCount(ctx, claimIdx+1) + + ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + defer cancel() + + game, claim := h.loadState(ctx, claimIdx) + attackPos := claim.Position.Attack() + h.t.Logf("Attacking claim %v at position %v with g index %v", claimIdx, attackPos, attackPos.ToGIndex()) + value, err := h.correctTrace.Get(ctx, game, claim, attackPos) + h.require.NoErrorf(err, "Get correct claim at position %v with g index %v", attackPos, attackPos.ToGIndex()) + h.t.Log("Performing attack") + h.game.Attack(ctx, claimIdx, value, opts...) + h.t.Log("Attack complete") +} + +func (h *OutputHonestHelper) Defend(ctx context.Context, claimIdx int64, opts ...MoveOpt) { + // Ensure the claim exists + h.game.WaitForClaimCount(ctx, claimIdx+1) + + ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + defer cancel() + game, claim := h.loadState(ctx, claimIdx) + defendPos := claim.Position.Defend() + value, err := h.correctTrace.Get(ctx, game, claim, defendPos) + h.game.require.NoErrorf(err, "Get correct claim at position %v with g index %v", defendPos, defendPos.ToGIndex()) + h.game.Defend(ctx, claimIdx, value, opts...) +} + +func (h *OutputHonestHelper) StepClaimFails(ctx context.Context, claim *ClaimHelper, isAttack bool) { + h.StepFails(ctx, claim.index, isAttack) +} + +func (h *OutputHonestHelper) StepFails(ctx context.Context, claimIdx int64, isAttack bool) { + // Ensure the claim exists + h.game.WaitForClaimCount(ctx, claimIdx+1) + + ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + defer cancel() + + game, claim := h.loadState(ctx, claimIdx) + pos := claim.Position + if !isAttack { + // If we're defending, then the step will be from the trace to the next one + pos = pos.MoveRight() + } + prestate, proofData, _, err := h.correctTrace.GetStepData(ctx, game, claim, pos) + h.require.NoError(err, "Get step data") + h.game.StepFails(claimIdx, isAttack, prestate, proofData) +} + +func (h *OutputHonestHelper) loadState(ctx context.Context, claimIdx int64) (types.Game, types.Claim) { + claims, err := h.contract.GetAllClaims(ctx, rpcblock.Latest) + h.require.NoError(err, "Failed to load claims from game") + game := types.NewGameState(claims, h.game.MaxDepth(ctx)) + + claim := game.Claims()[claimIdx] + return game, claim +} diff --git a/op-e2e/e2eutils/disputegame/preimage/preimage_helper.go b/op-e2e/e2eutils/disputegame/preimage/preimage_helper.go new file mode 100644 index 000000000000..f124add19d63 --- /dev/null +++ b/op-e2e/e2eutils/disputegame/preimage/preimage_helper.go @@ -0,0 +1,139 @@ +package preimage + +import ( + "bytes" + "context" + "errors" + "io" + "math/big" + "math/rand" + "sync/atomic" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/preimages" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/matrix" + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/stretchr/testify/require" +) + +const MinPreimageSize = 10000 + +type Helper struct { + t *testing.T + require *require.Assertions + client *ethclient.Client + opts *bind.TransactOpts + oracleBindings *bindings.PreimageOracle + oracle *contracts.PreimageOracleContract + uuidProvider atomic.Int64 +} + +func NewHelper(t *testing.T, opts *bind.TransactOpts, client *ethclient.Client, addr common.Address) *Helper { + require := require.New(t) + oracleBindings, err := bindings.NewPreimageOracle(addr, client) + require.NoError(err) + + oracle, err := contracts.NewPreimageOracleContract(addr, batching.NewMultiCaller(client.Client(), batching.DefaultBatchSize)) + require.NoError(err) + return &Helper{ + t: t, + require: require, + client: client, + opts: opts, + oracleBindings: oracleBindings, + oracle: oracle, + } +} + +type InputModifier func(startBlock uint64, input *types.InputData) + +func WithReplacedCommitment(idx uint64, value common.Hash) InputModifier { + return func(startBlock uint64, input *types.InputData) { + if startBlock > idx { + return + } + if startBlock+uint64(len(input.Commitments)) < idx { + return + } + input.Commitments[idx-startBlock] = value + } +} + +func WithLastCommitment(value common.Hash) InputModifier { + return func(startBlock uint64, input *types.InputData) { + if input.Finalize { + input.Commitments[len(input.Commitments)-1] = value + } + } +} + +// UploadLargePreimage inits the preimage upload and uploads the leaves, starting the challenge period. +// Squeeze is not called by this method as the challenge period has not yet elapsed. +func (h *Helper) UploadLargePreimage(ctx context.Context, dataSize int, modifiers ...InputModifier) types.LargePreimageIdent { + data := testutils.RandomData(rand.New(rand.NewSource(1234)), dataSize) + s := matrix.NewStateMatrix() + uuid := big.NewInt(h.uuidProvider.Add(1)) + bondValue, err := h.oracleBindings.MINBONDSIZE(&bind.CallOpts{}) + h.require.NoError(err) + h.opts.Value = bondValue + tx, err := h.oracleBindings.InitLPP(h.opts, uuid, 32, uint32(len(data))) + h.require.NoError(err) + _, err = wait.ForReceiptOK(ctx, h.client, tx.Hash()) + h.require.NoError(err) + h.opts.Value = big.NewInt(0) + + startBlock := big.NewInt(0) + totalBlocks := len(data) / types.BlockSize + in := bytes.NewReader(data) + for { + inputData, err := s.AbsorbUpTo(in, preimages.MaxChunkSize) + if !errors.Is(err, io.EOF) { + h.require.NoError(err) + } + for _, modifier := range modifiers { + modifier(startBlock.Uint64(), &inputData) + } + commitments := make([][32]byte, len(inputData.Commitments)) + for i, commitment := range inputData.Commitments { + commitments[i] = commitment + } + h.t.Logf("Uploading %v parts of preimage %v starting at block %v of about %v Finalize: %v", len(commitments), uuid.Uint64(), startBlock.Uint64(), totalBlocks, inputData.Finalize) + tx, err := h.oracleBindings.AddLeavesLPP(h.opts, uuid, startBlock, inputData.Input, commitments, inputData.Finalize) + h.require.NoError(err) + _, err = wait.ForReceiptOK(ctx, h.client, tx.Hash()) + h.require.NoError(err) + startBlock = new(big.Int).Add(startBlock, big.NewInt(int64(len(inputData.Commitments)))) + if inputData.Finalize { + break + } + } + + return types.LargePreimageIdent{ + Claimant: h.opts.From, + UUID: uuid, + } +} + +func (h *Helper) WaitForChallenged(ctx context.Context, ident types.LargePreimageIdent) { + timedCtx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + err := wait.For(timedCtx, time.Second, func() (bool, error) { + metadata, err := h.oracle.GetProposalMetadata(ctx, rpcblock.Latest, ident) + if err != nil { + return false, err + } + h.require.Len(metadata, 1) + return metadata[0].Countered, nil + }) + h.require.NoError(err, "Preimage was not challenged") +} diff --git a/op-e2e/e2eutils/fakebeacon/blobs.go b/op-e2e/e2eutils/fakebeacon/blobs.go new file mode 100644 index 000000000000..1f77e3d5a3f8 --- /dev/null +++ b/op-e2e/e2eutils/fakebeacon/blobs.go @@ -0,0 +1,207 @@ +package fakebeacon + +import ( + "encoding/binary" + "encoding/json" + "errors" + "fmt" + "io/fs" + "net" + "net/http" + "os" + "path/filepath" + "strconv" + "strings" + "sync" + "time" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/log" +) + +// FakeBeacon presents a beacon-node in testing, without leading any chain-building. +// This merely serves a fake beacon API, and holds on to blocks, +// to complement the actual block-building to happen in testing (e.g. through the fake consensus geth module). +type FakeBeacon struct { + log log.Logger + + // directory to store blob contents in after the blobs are persisted in a block + blobsDir string + blobsLock sync.Mutex + + beaconSrv *http.Server + beaconAPIListener net.Listener + + genesisTime uint64 + blockTime uint64 +} + +func NewBeacon(log log.Logger, blobsDir string, genesisTime uint64, blockTime uint64) *FakeBeacon { + return &FakeBeacon{ + log: log, + blobsDir: blobsDir, + genesisTime: genesisTime, + blockTime: blockTime, + } +} + +func (f *FakeBeacon) Start(addr string) error { + listener, err := net.Listen("tcp", addr) + if err != nil { + return fmt.Errorf("failed to open tcp listener for http beacon api server: %w", err) + } + f.beaconAPIListener = listener + + mux := new(http.ServeMux) + mux.HandleFunc("/eth/v1/beacon/genesis", func(w http.ResponseWriter, r *http.Request) { + err := json.NewEncoder(w).Encode(ð.APIGenesisResponse{Data: eth.ReducedGenesisData{GenesisTime: eth.Uint64String(f.genesisTime)}}) + if err != nil { + f.log.Error("genesis handler err", "err", err) + } + }) + mux.HandleFunc("/eth/v1/config/spec", func(w http.ResponseWriter, r *http.Request) { + err := json.NewEncoder(w).Encode(ð.APIConfigResponse{Data: eth.ReducedConfigData{SecondsPerSlot: eth.Uint64String(f.blockTime)}}) + if err != nil { + f.log.Error("config handler err", "err", err) + } + }) + mux.HandleFunc("/eth/v1/beacon/blob_sidecars/", func(w http.ResponseWriter, r *http.Request) { + blockID := strings.TrimPrefix(r.URL.Path, "/eth/v1/beacon/blob_sidecars/") + slot, err := strconv.ParseUint(blockID, 10, 64) + if err != nil { + f.log.Error("could not parse block id from request", "url", r.URL.Path, "err", err) + w.WriteHeader(http.StatusBadRequest) + return + } + bundle, err := f.LoadBlobsBundle(slot) + if err != nil { + f.log.Error("failed to load blobs bundle", "slot", slot) + w.WriteHeader(http.StatusInternalServerError) + return + } + + query := r.URL.Query() + rawIndices := query["indices"] + indices := make([]uint64, 0, len(bundle.Blobs)) + if len(rawIndices) == 0 { + // request is for all blobs + for i := range bundle.Blobs { + indices = append(indices, uint64(i)) + } + } else { + for _, raw := range rawIndices { + ix, err := strconv.ParseUint(raw, 10, 64) + if err != nil { + f.log.Error("could not parse index from request", "url", r.URL) + w.WriteHeader(http.StatusBadRequest) + return + } + indices = append(indices, ix) + } + } + + var mockBeaconBlockRoot [32]byte + mockBeaconBlockRoot[0] = 42 + binary.LittleEndian.PutUint64(mockBeaconBlockRoot[32-8:], slot) + sidecars := make([]*eth.APIBlobSidecar, len(indices)) + for i, ix := range indices { + if ix >= uint64(len(bundle.Blobs)) { + f.log.Error("blob index from request is out of range", "url", r.URL) + w.WriteHeader(http.StatusBadRequest) + return + } + sidecars[i] = ð.APIBlobSidecar{ + Index: eth.Uint64String(ix), + KZGCommitment: eth.Bytes48(bundle.Commitments[ix]), + KZGProof: eth.Bytes48(bundle.Proofs[ix]), + SignedBlockHeader: eth.SignedBeaconBlockHeader{ + Message: eth.BeaconBlockHeader{ + StateRoot: mockBeaconBlockRoot, + Slot: eth.Uint64String(slot), + }, + }, + } + copy(sidecars[i].Blob[:], bundle.Blobs[ix]) + } + if err := json.NewEncoder(w).Encode(ð.APIGetBlobSidecarsResponse{Data: sidecars}); err != nil { + f.log.Error("blobs handler err", "err", err) + } + }) + mux.HandleFunc("/eth/v1/node/version", func(w http.ResponseWriter, r *http.Request) { + err := json.NewEncoder(w).Encode(ð.APIVersionResponse{Data: eth.VersionInformation{Version: "fakebeacon 1.2.3"}}) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + f.log.Error("version handler err", "err", err) + } else { + w.WriteHeader(http.StatusOK) + } + }) + f.beaconSrv = &http.Server{ + Handler: mux, + ReadTimeout: time.Second * 20, + ReadHeaderTimeout: time.Second * 20, + WriteTimeout: time.Second * 20, + IdleTimeout: time.Second * 20, + } + go func() { + if err := f.beaconSrv.Serve(f.beaconAPIListener); err != nil && !errors.Is(err, http.ErrServerClosed) { + f.log.Error("failed to start fake-pos beacon server for blobs testing", "err", err) + } + }() + return nil +} + +func (f *FakeBeacon) StoreBlobsBundle(slot uint64, bundle *engine.BlobsBundleV1) error { + data, err := json.Marshal(bundle) + if err != nil { + return fmt.Errorf("failed to encode blobs bundle of slot %d: %w", slot, err) + } + + f.blobsLock.Lock() + defer f.blobsLock.Unlock() + bundlePath := fmt.Sprintf("blobs_bundle_%d.json", slot) + if err := os.MkdirAll(f.blobsDir, 0755); err != nil { + return fmt.Errorf("failed to create dir for blob storage: %w", err) + } + err = os.WriteFile(filepath.Join(f.blobsDir, bundlePath), data, 0755) + if err != nil { + return fmt.Errorf("failed to write blobs bundle of slot %d: %w", slot, err) + } + return nil +} + +func (f *FakeBeacon) LoadBlobsBundle(slot uint64) (*engine.BlobsBundleV1, error) { + f.blobsLock.Lock() + defer f.blobsLock.Unlock() + bundlePath := fmt.Sprintf("blobs_bundle_%d.json", slot) + data, err := os.ReadFile(filepath.Join(f.blobsDir, bundlePath)) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return nil, fmt.Errorf("no blobs bundle found for slot %d (%q): %w", slot, bundlePath, ethereum.NotFound) + } else { + return nil, fmt.Errorf("failed to read blobs bundle of slot %d (%q): %w", slot, bundlePath, err) + } + } + var out engine.BlobsBundleV1 + if err := json.Unmarshal(data, &out); err != nil { + return nil, fmt.Errorf("failed to decode blobs bundle of slot %d (%q): %w", slot, bundlePath, err) + } + return &out, nil +} + +func (f *FakeBeacon) Close() error { + var out error + if f.beaconSrv != nil { + out = errors.Join(out, f.beaconSrv.Close()) + } + if f.beaconAPIListener != nil { + out = errors.Join(out, f.beaconAPIListener.Close()) + } + return out +} + +func (f *FakeBeacon) BeaconAddr() string { + return "http://" + f.beaconAPIListener.Addr().String() +} diff --git a/op-e2e/e2eutils/geth/fakepos.go b/op-e2e/e2eutils/geth/fakepos.go index 51ec48eb15d6..b46f2dc59f9c 100644 --- a/op-e2e/e2eutils/geth/fakepos.go +++ b/op-e2e/e2eutils/geth/fakepos.go @@ -1,6 +1,8 @@ package geth import ( + "encoding/binary" + "math/big" "math/rand" "time" @@ -8,15 +10,21 @@ import ( "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/catalyst" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-service/clock" + opeth "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testutils" ) +type Beacon interface { + StoreBlobsBundle(slot uint64, bundle *engine.BlobsBundleV1) error +} + // fakePoS is a testing-only utility to attach to Geth, // to build a fake proof-of-stake L1 chain with fixed block time and basic lagging safe/finalized blocks. type fakePoS struct { @@ -32,6 +40,14 @@ type fakePoS struct { engineAPI *catalyst.ConsensusAPI sub ethereum.Subscription + + beacon Beacon +} + +func (f *fakePoS) FakeBeaconBlockRoot(time uint64) common.Hash { + var dat [8]byte + binary.LittleEndian.PutUint64(dat[:], time) + return crypto.Keccak256Hash(dat[:]) } func (f *fakePoS) Start() error { @@ -81,16 +97,29 @@ func (f *fakePoS) Start() error { Amount: uint64(withdrawalsRNG.Intn(50_000_000_000) + 1), } } - res, err := f.engineAPI.ForkchoiceUpdatedV2(engine.ForkchoiceStateV1{ - HeadBlockHash: head.Hash(), - SafeBlockHash: safe.Hash(), - FinalizedBlockHash: finalized.Hash(), - }, &engine.PayloadAttributes{ + attrs := &engine.PayloadAttributes{ Timestamp: newBlockTime, Random: common.Hash{}, SuggestedFeeRecipient: head.Coinbase, Withdrawals: withdrawals, - }) + } + parentBeaconBlockRoot := f.FakeBeaconBlockRoot(head.Time) // parent beacon block root + isCancun := f.eth.BlockChain().Config().IsCancun(new(big.Int).SetUint64(head.Number.Uint64()+1), newBlockTime) + if isCancun { + attrs.BeaconRoot = &parentBeaconBlockRoot + } + fcState := engine.ForkchoiceStateV1{ + HeadBlockHash: head.Hash(), + SafeBlockHash: safe.Hash(), + FinalizedBlockHash: finalized.Hash(), + } + var err error + var res engine.ForkChoiceResponse + if isCancun { + res, err = f.engineAPI.ForkchoiceUpdatedV3(fcState, attrs) + } else { + res, err = f.engineAPI.ForkchoiceUpdatedV2(fcState, attrs) + } if err != nil { f.log.Error("failed to start building L1 block", "err", err) continue @@ -109,16 +138,47 @@ func (f *fakePoS) Start() error { tim.Stop() return nil } - envelope, err := f.engineAPI.GetPayloadV2(*res.PayloadID) + envelope, err := f.engineAPI.GetPayloadV3(*res.PayloadID) if err != nil { f.log.Error("failed to finish building L1 block", "err", err) continue } - if _, err := f.engineAPI.NewPayloadV2(*envelope.ExecutionPayload); err != nil { - f.log.Error("failed to insert built L1 block", "err", err) + + blobHashes := make([]common.Hash, 0) // must be non-nil even when empty, due to geth engine API checks + for _, commitment := range envelope.BlobsBundle.Commitments { + if len(commitment) != 48 { + f.log.Error("got malformed kzg commitment from engine", "commitment", commitment) + break + } + blobHashes = append(blobHashes, opeth.KZGToVersionedHash(*(*[48]byte)(commitment))) + } + if len(blobHashes) != len(envelope.BlobsBundle.Commitments) { + f.log.Error("invalid or incomplete blob data", "collected", len(blobHashes), "engine", len(envelope.BlobsBundle.Commitments)) continue } - if _, err := f.engineAPI.ForkchoiceUpdatedV2(engine.ForkchoiceStateV1{ + if isCancun { + if _, err := f.engineAPI.NewPayloadV3(*envelope.ExecutionPayload, blobHashes, &parentBeaconBlockRoot); err != nil { + f.log.Error("failed to insert built L1 block", "err", err) + continue + } + } else { + if _, err := f.engineAPI.NewPayloadV2(*envelope.ExecutionPayload); err != nil { + f.log.Error("failed to insert built L1 block", "err", err) + continue + } + } + if envelope.BlobsBundle != nil { + slot := (envelope.ExecutionPayload.Timestamp - f.eth.BlockChain().Genesis().Time()) / f.blockTime + if f.beacon == nil { + f.log.Error("no blobs storage available") + continue + } + if err := f.beacon.StoreBlobsBundle(slot, envelope.BlobsBundle); err != nil { + f.log.Error("failed to persist blobs-bundle of block, not making block canonical now", "err", err) + continue + } + } + if _, err := f.engineAPI.ForkchoiceUpdatedV3(engine.ForkchoiceStateV1{ HeadBlockHash: envelope.ExecutionPayload.BlockHash, SafeBlockHash: safe.Hash(), FinalizedBlockHash: finalized.Hash(), diff --git a/op-e2e/e2eutils/geth/find.go b/op-e2e/e2eutils/geth/find.go new file mode 100644 index 000000000000..6d86659a4c1d --- /dev/null +++ b/op-e2e/e2eutils/geth/find.go @@ -0,0 +1,50 @@ +package geth + +import ( + "context" + "errors" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" +) + +var ErrNotFound = errors.New("not found") + +// FindBlock finds the first block for which the predicate [pred] matches +// and returns it. It starts at [from] and iterates until [to], inclusively, +// using the provided [client]. It supports both search directions, forwards +// and backwards. +func FindBlock(client *ethclient.Client, + from, to int, timeout time.Duration, + pred func(*types.Block) (bool, error), +) (*types.Block, error) { + dir := 1 + if from > to { + dir = -1 + } + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + for n := from; ; n += dir { + b, err := client.BlockByNumber(ctx, big.NewInt(int64(n))) + if err != nil { + return nil, fmt.Errorf("fetching block[%d]: %w", n, err) + } + ok, err := pred(b) + if err != nil { + return nil, fmt.Errorf("predicate error[%d]: %w", n, err) + } else if ok { + return b, nil + } + + // include n in range + if n == to { + break + } + } + + return nil, ErrNotFound +} diff --git a/op-e2e/e2eutils/geth/geth.go b/op-e2e/e2eutils/geth/geth.go index ad02eac36f6f..fc8660acf943 100644 --- a/op-e2e/e2eutils/geth/geth.go +++ b/op-e2e/e2eutils/geth/geth.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/txpool/blobpool" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/catalyst" "github.com/ethereum/go-ethereum/eth/ethconfig" @@ -21,10 +22,15 @@ import ( _ "github.com/ethereum/go-ethereum/eth/tracers/native" ) -func InitL1(chainID uint64, blockTime uint64, genesis *core.Genesis, c clock.Clock, opts ...GethOption) (*node.Node, *eth.Ethereum, error) { +func InitL1(chainID uint64, blockTime uint64, genesis *core.Genesis, c clock.Clock, blobPoolDir string, beaconSrv Beacon, opts ...GethOption) (*node.Node, *eth.Ethereum, error) { ethConfig := ðconfig.Config{ NetworkId: chainID, Genesis: genesis, + BlobPool: blobpool.Config{ + Datadir: blobPoolDir, + Datacap: blobpool.DefaultConfig.Datacap, + PriceBump: blobpool.DefaultConfig.PriceBump, + }, } nodeConfig := &node.Config{ Name: "l1-geth", @@ -53,6 +59,7 @@ func InitL1(chainID uint64, blockTime uint64, genesis *core.Genesis, c clock.Clo finalizedDistance: 8, safeDistance: 4, engineAPI: catalyst.NewConsensusAPI(l1Eth), + beacon: beaconSrv, }) return l1Node, l1Eth, nil diff --git a/op-e2e/e2eutils/geth/wait.go b/op-e2e/e2eutils/geth/wait.go index 7d113d28c30c..76398178ac0f 100644 --- a/op-e2e/e2eutils/geth/wait.go +++ b/op-e2e/e2eutils/geth/wait.go @@ -7,11 +7,13 @@ import ( "math/big" "time" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rpc" ) var ( @@ -19,7 +21,7 @@ var ( errTimeout = errors.New("timeout") ) -func WaitForL1OriginOnL2(l1BlockNum uint64, client *ethclient.Client, timeout time.Duration) (*types.Block, error) { +func WaitForL1OriginOnL2(rollupCfg *rollup.Config, l1BlockNum uint64, client *ethclient.Client, timeout time.Duration) (*types.Block, error) { timeoutCh := time.After(timeout) ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() @@ -38,7 +40,7 @@ func WaitForL1OriginOnL2(l1BlockNum uint64, client *ethclient.Client, timeout ti if err != nil { return nil, err } - l1Info, err := derive.L1InfoDepositTxData(block.Transactions()[0].Data()) + l1Info, err := derive.L1BlockInfoFromBytes(rollupCfg, block.Time(), block.Transactions()[0].Data()) if err != nil { return nil, err } @@ -80,7 +82,6 @@ func WaitForTransaction(hash common.Hash, client *ethclient.Client, timeout time } func WaitForBlock(number *big.Int, client *ethclient.Client, timeout time.Duration) (*types.Block, error) { - timeoutCh := time.After(timeout) ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() @@ -99,8 +100,43 @@ func WaitForBlock(number *big.Int, client *ethclient.Client, timeout time.Durati } case err := <-headSub.Err(): return nil, fmt.Errorf("error in head subscription: %w", err) - case <-timeoutCh: - return nil, errTimeout + case <-ctx.Done(): + return nil, ctx.Err() + } + } +} + +func WaitForBlockToBeFinalized(number *big.Int, client *ethclient.Client, timeout time.Duration) (*types.Block, error) { + return waitForBlockTag(number, client, timeout, rpc.FinalizedBlockNumber) +} + +func WaitForBlockToBeSafe(number *big.Int, client *ethclient.Client, timeout time.Duration) (*types.Block, error) { + return waitForBlockTag(number, client, timeout, rpc.SafeBlockNumber) +} + +// waitForBlockTag polls for a block number to reach the specified tag & then returns that block at the number. +func waitForBlockTag(number *big.Int, client *ethclient.Client, timeout time.Duration, tag rpc.BlockNumber) (*types.Block, error) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + // Wait for it to be finalized. Poll every half second. + ticker := time.NewTicker(500 * time.Millisecond) + defer ticker.Stop() + + tagBigInt := big.NewInt(tag.Int64()) + + for { + select { + case <-ticker.C: + block, err := client.BlockByNumber(ctx, tagBigInt) + if err != nil { + return nil, err + } + if block != nil && block.NumberU64() >= number.Uint64() { + return client.BlockByNumber(ctx, number) + } + case <-ctx.Done(): + return nil, ctx.Err() } } } diff --git a/op-e2e/e2eutils/l2oo/helper.go b/op-e2e/e2eutils/l2oo/helper.go deleted file mode 100644 index 47676e7c6fb6..000000000000 --- a/op-e2e/e2eutils/l2oo/helper.go +++ /dev/null @@ -1,130 +0,0 @@ -package l2oo - -import ( - "context" - "crypto/ecdsa" - "math/big" - "testing" - "time" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" - "github.com/ethereum-optimism/optimism/op-node/rollup" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/stretchr/testify/require" -) - -type L2OOHelper struct { - t *testing.T - require *require.Assertions - client *ethclient.Client - l2oo *bindings.L2OutputOracle - - // Nil when read-only - transactOpts *bind.TransactOpts - rollupCfg *rollup.Config -} - -func NewL2OOHelperReadOnly(t *testing.T, deployments *genesis.L1Deployments, client *ethclient.Client) *L2OOHelper { - require := require.New(t) - l2oo, err := bindings.NewL2OutputOracle(deployments.L2OutputOracleProxy, client) - require.NoError(err, "Error creating l2oo bindings") - - return &L2OOHelper{ - t: t, - require: require, - client: client, - l2oo: l2oo, - } -} - -func NewL2OOHelper(t *testing.T, deployments *genesis.L1Deployments, client *ethclient.Client, proposerKey *ecdsa.PrivateKey, rollupCfg *rollup.Config) *L2OOHelper { - h := NewL2OOHelperReadOnly(t, deployments, client) - - chainID, err := client.ChainID(context.Background()) - h.require.NoError(err, "Failed to get chain ID") - transactOpts, err := bind.NewKeyedTransactorWithChainID(proposerKey, chainID) - h.require.NoError(err) - h.transactOpts = transactOpts - h.rollupCfg = rollupCfg - return h -} - -// WaitForProposals waits until there are at least the specified number of proposals in the output oracle -// Returns the index of the latest output proposal -func (h *L2OOHelper) WaitForProposals(ctx context.Context, req int64) uint64 { - ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) - defer cancel() - opts := &bind.CallOpts{Context: ctx} - latestOutputIndex, err := wait.AndGet( - ctx, - time.Second, - func() (*big.Int, error) { - index, err := h.l2oo.LatestOutputIndex(opts) - if err != nil { - h.t.Logf("Could not get latest output index: %v", err.Error()) - return nil, nil - } - h.t.Logf("Latest output index: %v", index) - return index, nil - }, - func(index *big.Int) bool { - return index != nil && index.Cmp(big.NewInt(req-1)) >= 0 - }) - h.require.NoErrorf(err, "Did not get %v output roots", req) - return latestOutputIndex.Uint64() -} - -func (h *L2OOHelper) GetL2Output(ctx context.Context, idx uint64) bindings.TypesOutputProposal { - output, err := h.l2oo.GetL2Output(&bind.CallOpts{Context: ctx}, new(big.Int).SetUint64(idx)) - h.require.NoErrorf(err, "Failed to get output root at index: %v", idx) - return output -} - -func (h *L2OOHelper) GetL2OutputAfter(ctx context.Context, l2BlockNum uint64) bindings.TypesOutputProposal { - opts := &bind.CallOpts{Context: ctx} - outputIdx, err := h.l2oo.GetL2OutputIndexAfter(opts, new(big.Int).SetUint64(l2BlockNum)) - h.require.NoError(err, "Fetch challenged output index") - output, err := h.l2oo.GetL2Output(opts, outputIdx) - h.require.NoError(err, "Fetch challenged output") - return output -} - -func (h *L2OOHelper) GetL2OutputBefore(ctx context.Context, l2BlockNum uint64) bindings.TypesOutputProposal { - opts := &bind.CallOpts{Context: ctx} - latestBlockNum, err := h.l2oo.LatestBlockNumber(opts) - h.require.NoError(err, "Failed to get latest output root block number") - var outputIdx *big.Int - if latestBlockNum.Uint64() < l2BlockNum { - outputIdx, err = h.l2oo.LatestOutputIndex(opts) - h.require.NoError(err, "Failed to get latest output index") - } else { - outputIdx, err = h.l2oo.GetL2OutputIndexAfter(opts, new(big.Int).SetUint64(l2BlockNum)) - h.require.NoErrorf(err, "Failed to get output index after block %v", l2BlockNum) - h.require.NotZerof(outputIdx.Uint64(), "No l2 output before block %v", l2BlockNum) - outputIdx = new(big.Int).Sub(outputIdx, common.Big1) - } - return h.GetL2Output(ctx, outputIdx.Uint64()) -} - -func (h *L2OOHelper) PublishNextOutput(ctx context.Context, outputRoot common.Hash) { - h.require.NotNil(h.transactOpts, "Can't publish outputs from a read only L2OOHelper") - nextBlockNum, err := h.l2oo.NextBlockNumber(&bind.CallOpts{Context: ctx}) - h.require.NoError(err, "Should get next block number") - - genesis := h.rollupCfg.Genesis - targetTimestamp := genesis.L2Time + ((nextBlockNum.Uint64() - genesis.L2.Number) * h.rollupCfg.BlockTime) - timedCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - defer cancel() - h.require.NoErrorf( - wait.ForBlockWithTimestamp(timedCtx, h.client, targetTimestamp), - "Wait for L1 block with timestamp >= %v", targetTimestamp) - - tx, err := h.l2oo.ProposeL2Output(h.transactOpts, outputRoot, nextBlockNum, [32]byte{}, common.Big0) - h.require.NoErrorf(err, "Failed to propose output root for l2 block number %v", nextBlockNum) - _, err = wait.ForReceiptOK(ctx, h.client, tx.Hash()) - h.require.NoErrorf(err, "Proposal for l2 block %v failed", nextBlockNum) -} diff --git a/op-e2e/e2eutils/receipts/logs.go b/op-e2e/e2eutils/receipts/logs.go new file mode 100644 index 000000000000..51f2c184aac1 --- /dev/null +++ b/op-e2e/e2eutils/receipts/logs.go @@ -0,0 +1,25 @@ +package receipts + +import ( + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/core/types" +) + +// FindLog searches the array of logs (typically retrieved from a receipt) to find one that can be parsed by the +// supplied parser (usually the Parse function from generated bindings for a contract). +// e.g. receipts.FindLog(receipt.Logs, optimismPortal.ParseTransactionDeposited) +// Either the first parsable event is returned or an error with the parse failures. +func FindLog[T any](logs []*types.Log, parser func(types.Log) (T, error)) (T, error) { + var errs error + for i, l := range logs { + parsed, err := parser(*l) + if err == nil { + return parsed, nil + } + errs = errors.Join(errs, fmt.Errorf("parse log %v: %w", i, err)) + } + var noMatch T + return noMatch, fmt.Errorf("no matching log found: %w", errs) +} diff --git a/op-e2e/e2eutils/setup.go b/op-e2e/e2eutils/setup.go index bf6cea93e52a..a417060a7399 100644 --- a/op-e2e/e2eutils/setup.go +++ b/op-e2e/e2eutils/setup.go @@ -44,6 +44,7 @@ type TestParams struct { SequencerWindowSize uint64 ChannelTimeout uint64 L1BlockTime uint64 + UsePlasma bool } func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams { @@ -57,9 +58,8 @@ func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams { deployConfig.SequencerWindowSize = tp.SequencerWindowSize deployConfig.ChannelTimeout = tp.ChannelTimeout deployConfig.L1BlockTime = tp.L1BlockTime - deployConfig.L2GenesisRegolithTimeOffset = nil - deployConfig.L2GenesisCanyonTimeOffset = CanyonTimeOffset() - deployConfig.L2GenesisSpanBatchTimeOffset = SpanBatchTimeOffset() + deployConfig.UsePlasma = tp.UsePlasma + ApplyDeployConfigForks(deployConfig) require.NoError(t, deployConfig.Check()) require.Equal(t, addresses.Batcher, deployConfig.BatchSenderAddress) @@ -105,9 +105,9 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) * require.NoError(t, deployConf.Check()) l1Deployments := config.L1Deployments.Copy() - require.NoError(t, l1Deployments.Check()) + require.NoError(t, l1Deployments.Check(deployConf)) - l1Genesis, err := genesis.BuildL1DeveloperGenesis(deployConf, config.L1Allocs, l1Deployments, true) + l1Genesis, err := genesis.BuildL1DeveloperGenesis(deployConf, config.L1Allocs, l1Deployments) require.NoError(t, err, "failed to create l1 genesis") if alloc.PrefundTestUsers { for _, addr := range deployParams.Addresses.All() { @@ -159,7 +159,14 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) * L1SystemConfigAddress: deployConf.SystemConfigProxy, RegolithTime: deployConf.RegolithTime(uint64(deployConf.L1GenesisBlockTimestamp)), CanyonTime: deployConf.CanyonTime(uint64(deployConf.L1GenesisBlockTimestamp)), - SpanBatchTime: deployConf.SpanBatchTime(uint64(deployConf.L1GenesisBlockTimestamp)), + DeltaTime: deployConf.DeltaTime(uint64(deployConf.L1GenesisBlockTimestamp)), + EcotoneTime: deployConf.EcotoneTime(uint64(deployConf.L1GenesisBlockTimestamp)), + FjordTime: deployConf.FjordTime(uint64(deployConf.L1GenesisBlockTimestamp)), + InteropTime: deployConf.InteropTime(uint64(deployConf.L1GenesisBlockTimestamp)), + DAChallengeAddress: l1Deployments.DataAvailabilityChallengeProxy, + DAChallengeWindow: deployConf.DAChallengeWindow, + DAResolveWindow: deployConf.DAResolveWindow, + UsePlasma: deployConf.UsePlasma, } require.NoError(t, rollupCfg.Check()) @@ -186,18 +193,28 @@ func SystemConfigFromDeployConfig(deployConfig *genesis.DeployConfig) eth.System } } -func SpanBatchTimeOffset() *hexutil.Uint64 { - if os.Getenv("OP_E2E_USE_SPAN_BATCH") == "true" { - offset := hexutil.Uint64(0) - return &offset +func ApplyDeployConfigForks(deployConfig *genesis.DeployConfig) { + isFjord := os.Getenv("OP_E2E_USE_FJORD") == "true" + isEcotone := isFjord || os.Getenv("OP_E2E_USE_ECOTONE") == "true" + isDelta := isEcotone || os.Getenv("OP_E2E_USE_DELTA") == "true" + if isDelta { + deployConfig.L2GenesisDeltaTimeOffset = new(hexutil.Uint64) } - return nil + if isEcotone { + deployConfig.L2GenesisEcotoneTimeOffset = new(hexutil.Uint64) + } + if isFjord { + deployConfig.L2GenesisFjordTimeOffset = new(hexutil.Uint64) + } + // Canyon and lower is activated by default + deployConfig.L2GenesisCanyonTimeOffset = new(hexutil.Uint64) + deployConfig.L2GenesisRegolithTimeOffset = new(hexutil.Uint64) } -func CanyonTimeOffset() *hexutil.Uint64 { - if os.Getenv("OP_E2E_USE_CANYON") == "true" { - offset := hexutil.Uint64(0) - return &offset - } - return nil +func UseFPAC() bool { + return os.Getenv("OP_E2E_USE_FPAC") == "true" +} + +func UsePlasma() bool { + return os.Getenv("OP_E2E_USE_PLASMA") == "true" } diff --git a/op-e2e/e2eutils/transactions/blobs.go b/op-e2e/e2eutils/transactions/blobs.go new file mode 100644 index 000000000000..980c357a1b68 --- /dev/null +++ b/op-e2e/e2eutils/transactions/blobs.go @@ -0,0 +1,53 @@ +package transactions + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/holiman/uint256" +) + +var ( + emptyBlob kzg4844.Blob + emptyBlobCommit kzg4844.Commitment + emptyBlobProof kzg4844.Proof +) + +func init() { + var err error + emptyBlob = kzg4844.Blob{} + emptyBlobCommit, err = kzg4844.BlobToCommitment(emptyBlob) + if err != nil { + panic("failed to create empty blob commitment: " + err.Error()) + } + emptyBlobProof, err = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit) + if err != nil { + panic("failed to create empty blob proof: " + err.Error()) + } +} + +// with thanks to fjl +// https://github.com/ethereum/go-ethereum/commit/2a6beb6a39d7cb3c5906dd4465d65da6efcc73cd +func CreateEmptyBlobTx(withSidecar bool, chainID uint64) *types.BlobTx { + sidecar := &types.BlobTxSidecar{ + Blobs: []kzg4844.Blob{emptyBlob}, + Commitments: []kzg4844.Commitment{emptyBlobCommit}, + Proofs: []kzg4844.Proof{emptyBlobProof}, + } + blobTx := &types.BlobTx{ + ChainID: uint256.NewInt(chainID), + Nonce: 0, + GasTipCap: uint256.NewInt(2200000000000), + GasFeeCap: uint256.NewInt(5000000000000), + Gas: 25000, + To: common.Address{0x03, 0x04, 0x05}, + Value: uint256.NewInt(99), + Data: make([]byte, 50), + BlobFeeCap: uint256.NewInt(150000000000), + BlobHashes: sidecar.BlobHashes(), + } + if withSidecar { + blobTx.Sidecar = sidecar + } + return blobTx +} diff --git a/op-e2e/e2eutils/transactions/gas.go b/op-e2e/e2eutils/transactions/gas.go index 4ce5e84e0f87..84e13aec25a5 100644 --- a/op-e2e/e2eutils/transactions/gas.go +++ b/op-e2e/e2eutils/transactions/gas.go @@ -17,14 +17,15 @@ type TxBuilder func(opts *bind.TransactOpts) (*types.Transaction, error) // NoSend=false and GasLimit including the requested padding. func PadGasEstimate(opts *bind.TransactOpts, paddingFactor float64, builder TxBuilder) (*types.Transaction, error) { // Take a copy of the opts to avoid mutating the original - o := *opts + oCopy := *opts + o := &oCopy o.NoSend = true - tx, err := builder(&o) + tx, err := builder(o) if err != nil { return nil, fmt.Errorf("failed to estimate gas: %w", err) } gas := float64(tx.Gas()) * paddingFactor o.GasLimit = uint64(gas) o.NoSend = false - return builder(&o) + return builder(o) } diff --git a/op-e2e/e2eutils/wait/blocks.go b/op-e2e/e2eutils/wait/blocks.go index dd6ef178cd41..9617c71a69b3 100644 --- a/op-e2e/e2eutils/wait/blocks.go +++ b/op-e2e/e2eutils/wait/blocks.go @@ -7,6 +7,10 @@ import ( "time" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources" ) // BlockCaller is a subset of the [ethclient.Client] interface @@ -18,20 +22,21 @@ type BlockCaller interface { func ForBlock(ctx context.Context, client BlockCaller, n uint64) error { for { - if ctx.Done() != nil { + select { + case <-ctx.Done(): return ctx.Err() + default: + height, err := client.BlockNumber(ctx) + if err != nil { + return err + } + if height < n { + time.Sleep(500 * time.Millisecond) + continue + } + return nil } - height, err := client.BlockNumber(ctx) - if err != nil { - return err - } - if height < n { - time.Sleep(500 * time.Millisecond) - continue - } - break } - return nil } func ForBlockWithTimestamp(ctx context.Context, client BlockCaller, target uint64) error { @@ -57,3 +62,62 @@ func ForNextBlock(ctx context.Context, client BlockCaller) error { } return ForBlock(ctx, client, current+1) } + +func ForProcessingFullBatch(ctx context.Context, rollupCl *sources.RollupClient) error { + _, err := AndGet(ctx, time.Second, func() (*eth.SyncStatus, error) { + return rollupCl.SyncStatus(ctx) + }, func(syncStatus *eth.SyncStatus) bool { + return syncStatus.PendingSafeL2 == syncStatus.SafeL2 + }) + return err +} + +func ForUnsafeBlock(ctx context.Context, rollupCl *sources.RollupClient, n uint64) error { + ctx, cancel := context.WithTimeout(ctx, 60*time.Second) + defer cancel() + + _, err := AndGet(ctx, time.Second, func() (*eth.SyncStatus, error) { + return rollupCl.SyncStatus(ctx) + }, func(syncStatus *eth.SyncStatus) bool { + return syncStatus.UnsafeL2.Number >= n + }) + return err +} + +func ForSafeBlock(ctx context.Context, rollupClient *sources.RollupClient, n uint64) error { + ctx, cancel := context.WithTimeout(ctx, 60*time.Second) + defer cancel() + _, err := AndGet(ctx, time.Second, func() (*eth.SyncStatus, error) { + return rollupClient.SyncStatus(ctx) + }, func(syncStatus *eth.SyncStatus) bool { + return syncStatus.SafeL2.Number >= n + }) + return err +} + +func ForNextSafeBlock(ctx context.Context, client BlockCaller) (*types.Block, error) { + safeBlockNumber := big.NewInt(rpc.SafeBlockNumber.Int64()) + current, err := client.BlockByNumber(ctx, safeBlockNumber) + if err != nil { + return nil, err + } + + // Long timeout so we don't have to care what the block time is. If the test passes this will complete early anyway. + ctx, cancel := context.WithTimeout(ctx, 60*time.Second) + defer cancel() + for { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + next, err := client.BlockByNumber(ctx, safeBlockNumber) + if err != nil { + return nil, err + } + if next.NumberU64() > current.NumberU64() { + return next, nil + } + time.Sleep(500 * time.Millisecond) + } + } +} diff --git a/op-e2e/e2eutils/wait/waits.go b/op-e2e/e2eutils/wait/waits.go index 92bc6ae621d2..bb0e8f097c50 100644 --- a/op-e2e/e2eutils/wait/waits.go +++ b/op-e2e/e2eutils/wait/waits.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "math/big" + "os" "time" "github.com/ethereum/go-ethereum" @@ -13,6 +15,22 @@ import ( "github.com/ethereum/go-ethereum/ethclient" ) +func ForBalanceChange(ctx context.Context, client *ethclient.Client, address common.Address, initial *big.Int) (*big.Int, error) { + ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + defer cancel() + + return AndGet[*big.Int]( + ctx, + 100*time.Millisecond, + func() (*big.Int, error) { + return client.BalanceAt(ctx, address, nil) + }, + func(b *big.Int) bool { + return b.Cmp(initial) != 0 + }, + ) +} + func ForReceiptOK(ctx context.Context, client *ethclient.Client, hash common.Hash) (*types.Receipt, error) { return ForReceipt(ctx, client, hash, types.ReceiptStatusSuccessful) } @@ -36,6 +54,9 @@ func ForReceipt(ctx context.Context, client *ethclient.Client, hash common.Hash, continue } } + if errors.Is(err, os.ErrDeadlineExceeded) { + continue + } if err != nil { return nil, fmt.Errorf("failed to get receipt: %w", err) } diff --git a/op-e2e/e2eutils/wait/withdrawals.go b/op-e2e/e2eutils/wait/withdrawals.go index 2774ab12b57c..35c8f3005111 100644 --- a/op-e2e/e2eutils/wait/withdrawals.go +++ b/op-e2e/e2eutils/wait/withdrawals.go @@ -7,6 +7,9 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/bindingspreview" + "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" + "github.com/ethereum-optimism/optimism/op-node/withdrawals" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" @@ -16,6 +19,8 @@ import ( // This function polls and can block for a very long time if used on mainnet. // This returns the block number to use for proof generation. func ForOutputRootPublished(ctx context.Context, client *ethclient.Client, l2OutputOracleAddr common.Address, l2BlockNumber *big.Int) (uint64, error) { + ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + defer cancel() l2BlockNumber = new(big.Int).Set(l2BlockNumber) // Don't clobber caller owned l2BlockNumber opts := &bind.CallOpts{Context: ctx} @@ -69,3 +74,58 @@ func ForFinalizationPeriod(ctx context.Context, client *ethclient.Client, l1Prov return header.Time > targetTimestamp.Uint64(), nil }) } + +// ForGamePublished waits until a game is published on L1 for the given l2BlockNumber. +func ForGamePublished(ctx context.Context, client *ethclient.Client, optimismPortalAddr common.Address, disputeGameFactoryAddr common.Address, l2BlockNumber *big.Int) (uint64, error) { + ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + defer cancel() + l2BlockNumber = new(big.Int).Set(l2BlockNumber) // Don't clobber caller owned l2BlockNumber + + optimismPortal2Contract, err := bindingspreview.NewOptimismPortal2Caller(optimismPortalAddr, client) + if err != nil { + return 0, err + } + + disputeGameFactoryContract, err := bindings.NewDisputeGameFactoryCaller(disputeGameFactoryAddr, client) + if err != nil { + return 0, err + } + + getL2BlockFromLatestGame := func() (*big.Int, error) { + latestGame, err := withdrawals.FindLatestGame(ctx, disputeGameFactoryContract, optimismPortal2Contract) + if err != nil { + return big.NewInt(-1), nil + } + + gameBlockNumber := new(big.Int).SetBytes(latestGame.ExtraData[0:32]) + return gameBlockNumber, nil + } + outputBlockNum, err := AndGet(ctx, time.Second, getL2BlockFromLatestGame, func(latest *big.Int) bool { + return latest.Cmp(l2BlockNumber) >= 0 + }) + if err != nil { + return 0, err + } + return outputBlockNum.Uint64(), nil +} + +// ForWithdrawalCheck waits until the withdrawal check in the portal succeeds. +func ForWithdrawalCheck(ctx context.Context, client *ethclient.Client, withdrawal crossdomain.Withdrawal, optimismPortalAddr common.Address) error { + ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + defer cancel() + opts := &bind.CallOpts{Context: ctx} + portal, err := bindingspreview.NewOptimismPortal2Caller(optimismPortalAddr, client) + if err != nil { + return fmt.Errorf("create portal caller: %w", err) + } + + return For(ctx, time.Second, func() (bool, error) { + wdHash, err := withdrawal.Hash() + if err != nil { + return false, fmt.Errorf("hash withdrawal: %w", err) + } + + err = portal.CheckWithdrawal(opts, wdHash) + return err == nil, nil + }) +} diff --git a/op-e2e/eip4844_test.go b/op-e2e/eip4844_test.go new file mode 100644 index 000000000000..5b5cc1d5308e --- /dev/null +++ b/op-e2e/eip4844_test.go @@ -0,0 +1,195 @@ +package op_e2e + +import ( + "context" + "math/big" + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" + + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + gethutils "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" +) + +// TestSystem4844E2E runs the SystemE2E test with 4844 enabled on L1, +// and active on the rollup in the op-batcher and verifier. +func TestSystem4844E2E(t *testing.T) { + t.Run("single-blob", func(t *testing.T) { testSystem4844E2E(t, false) }) + t.Run("multi-blob", func(t *testing.T) { testSystem4844E2E(t, true) }) +} + +func testSystem4844E2E(t *testing.T, multiBlob bool) { + InitParallel(t) + + cfg := DefaultSystemConfig(t) + cfg.DataAvailabilityType = batcherFlags.BlobsType + const maxBlobs = 6 + var maxL1TxSize int + if multiBlob { + cfg.BatcherTargetNumFrames = 6 + cfg.BatcherUseMaxTxSizeForBlobs = true + // leads to 6 blobs for an L2 block with a user tx with 400 random bytes + // while all other L2 blocks take 1 blob (deposit tx) + maxL1TxSize = derive.FrameV0OverHeadSize + 100 + cfg.BatcherMaxL1TxSizeBytes = uint64(maxL1TxSize) + } + + genesisActivation := hexutil.Uint64(0) + cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation + cfg.DeployConfig.L2GenesisDeltaTimeOffset = &genesisActivation + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisActivation + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + defer sys.Close() + + log := testlog.Logger(t, log.LevelInfo) + log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) + + l1Client := sys.Clients["l1"] + l2Seq := sys.Clients["sequencer"] + l2Verif := sys.Clients["verifier"] + + // Transactor Account + ethPrivKey := cfg.Secrets.Alice + + // Send Transaction & wait for success + fromAddr := cfg.Secrets.Addresses().Alice + log.Info("alice", "addr", fromAddr) + + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + startBalance, err := l2Verif.BalanceAt(ctx, fromAddr, nil) + require.NoError(t, err) + + // Send deposit transaction + opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig()) + require.NoError(t, err) + mintAmount := big.NewInt(1_000_000_000_000) + opts.Value = mintAmount + SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *DepositTxOpts) {}) + + // Confirm balance + ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + endBalance, err := wait.ForBalanceChange(ctx, l2Verif, fromAddr, startBalance) + require.NoError(t, err) + + diff := new(big.Int).Sub(endBalance, startBalance) + require.Equal(t, mintAmount, diff, "Did not get expected balance change") + + // Submit TX to L2 sequencer node + receipt := SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { + opts.Value = big.NewInt(1_000_000_000) + opts.Nonce = 1 // Already have deposit + opts.ToAddr = &common.Address{0xff, 0xff} + // put some random data in the tx to make it fill up 6 blobs (multi-blob case) + opts.Data = testutils.RandomData(rand.New(rand.NewSource(420)), 400) + opts.Gas, err = core.IntrinsicGas(opts.Data, nil, false, true, true, false) + require.NoError(t, err) + opts.VerifyOnClients(l2Verif) + }) + + // Verify blocks match after batch submission on verifiers and sequencers + verifBlock, err := l2Verif.BlockByNumber(context.Background(), receipt.BlockNumber) + require.NoError(t, err) + require.Equal(t, verifBlock.Hash(), receipt.BlockHash, "must be same block") + seqBlock, err := l2Seq.BlockByNumber(context.Background(), receipt.BlockNumber) + require.NoError(t, err) + require.Equal(t, seqBlock.Hash(), receipt.BlockHash, "must be same block") + require.Equal(t, verifBlock.NumberU64(), seqBlock.NumberU64(), "Verifier and sequencer blocks not the same after including a batch tx") + require.Equal(t, verifBlock.ParentHash(), seqBlock.ParentHash(), "Verifier and sequencer blocks parent hashes not the same after including a batch tx") + require.Equal(t, verifBlock.Hash(), seqBlock.Hash(), "Verifier and sequencer blocks not the same after including a batch tx") + + rollupRPCClient, err := rpc.DialContext(context.Background(), sys.RollupNodes["sequencer"].HTTPEndpoint()) + require.NoError(t, err) + rollupClient := sources.NewRollupClient(client.NewBaseRPCClient(rollupRPCClient)) + // basic check that sync status works + seqStatus, err := rollupClient.SyncStatus(context.Background()) + require.NoError(t, err) + require.LessOrEqual(t, seqBlock.NumberU64(), seqStatus.UnsafeL2.Number) + // basic check that version endpoint works + seqVersion, err := rollupClient.Version(context.Background()) + require.NoError(t, err) + require.NotEqual(t, "", seqVersion) + + // quick check that the batch submitter works + require.Eventually(t, func() bool { + // wait for chain to be marked as "safe" (i.e. confirm batch-submission works) + stat, err := rollupClient.SyncStatus(context.Background()) + require.NoError(t, err) + return stat.SafeL2.Number >= receipt.BlockNumber.Uint64() + }, time.Second*20, time.Second, "expected L2 to be batch-submitted and labeled as safe") + + // check that the L2 tx is still canonical + seqBlock, err = l2Seq.BlockByNumber(context.Background(), receipt.BlockNumber) + require.NoError(t, err) + require.Equal(t, seqBlock.Hash(), receipt.BlockHash, "receipt block must match canonical block at tx inclusion height") + + // find L1 block that contained the blob(s) batch tx + tip, err := l1Client.HeaderByNumber(context.Background(), nil) + require.NoError(t, err) + var blobTx *types.Transaction + blobBlock, err := gethutils.FindBlock(l1Client, int(tip.Number.Int64()), 0, 5*time.Second, + func(b *types.Block) (bool, error) { + for _, tx := range b.Transactions() { + if tx.Type() != types.BlobTxType { + continue + } + // expect to find at least one tx with multiple blobs in multi-blob case + if !multiBlob || len(tx.BlobHashes()) > 1 { + blobTx = tx + return true, nil + } + } + return false, nil + }) + require.NoError(t, err) + + numBlobs := len(blobTx.BlobHashes()) + if !multiBlob { + require.NotZero(t, numBlobs, "single-blob: expected to find L1 blob tx") + } else { + require.Equal(t, maxBlobs, numBlobs, "multi-blob: expected to find L1 blob tx with 6 blobs") + // blob tx should have filled up all but last blob + bcl := sys.L1BeaconHTTPClient() + hashes := toIndexedBlobHashes(blobTx.BlobHashes()...) + sidecars, err := bcl.BeaconBlobSideCars(context.Background(), false, sys.L1Slot(blobBlock.Time()), hashes) + require.NoError(t, err) + require.Len(t, sidecars.Data, maxBlobs) + for i := 0; i < maxBlobs-1; i++ { + data, err := sidecars.Data[i].Blob.ToData() + require.NoError(t, err) + require.Len(t, data, maxL1TxSize) + } + // last blob should only be partially filled + data, err := sidecars.Data[maxBlobs-1].Blob.ToData() + require.NoError(t, err) + require.Less(t, len(data), maxL1TxSize) + } +} + +func toIndexedBlobHashes(hs ...common.Hash) []eth.IndexedBlobHash { + hashes := make([]eth.IndexedBlobHash, 0, len(hs)) + for i, hash := range hs { + hashes = append(hashes, eth.IndexedBlobHash{Index: uint64(i), Hash: hash}) + } + return hashes +} diff --git a/op-e2e/external.go b/op-e2e/external.go index 0efdf4deb600..df960d583983 100644 --- a/op-e2e/external.go +++ b/op-e2e/external.go @@ -24,6 +24,8 @@ type ExternalRunner struct { BinPath string Genesis *core.Genesis JWTPath string + // 4844: a datadir specifically for tx-pool blobs + BlobPoolPath string } type ExternalEthClient struct { diff --git a/op-e2e/external_geth/README.md b/op-e2e/external_geth/README.md index 07550d1c00ef..7438fb037f3b 100644 --- a/op-e2e/external_geth/README.md +++ b/op-e2e/external_geth/README.md @@ -29,7 +29,7 @@ the binary to be rebuilt before executing the tests. ## Arguments *--config * The config path is a required argument, it points to a JSON -file which contains details of the L2 environment to bring up (including the +file that contains details of the L2 environment to bring up (including the `genesis.json` path, the chain ID, the JWT path, and a ready file path). See the data structures in `op-e2e/external/config.go` for more details. @@ -53,7 +53,7 @@ details. ## Generalization -This shim is included to help document an demonstrate the usage of the +This shim is included to help document and demonstrates the usage of the external ethereum process e2e test execution. It is configured to execute in CI to help ensure that the tests remain compatible with external clients. diff --git a/op-e2e/external_geth/main.go b/op-e2e/external_geth/main.go index 15a378076d79..dc965131f94e 100644 --- a/op-e2e/external_geth/main.go +++ b/op-e2e/external_geth/main.go @@ -2,12 +2,15 @@ package main import ( "encoding/json" + "errors" "flag" "fmt" "os" "os/exec" + "os/signal" "path/filepath" "strconv" + "syscall" "time" "github.com/ethereum-optimism/optimism/op-e2e/external" @@ -67,11 +70,39 @@ func run(configPath string) error { } fmt.Printf("================== op-geth shim awaiting termination ==========================\n") + + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + select { + case <-sigs: + fmt.Printf("================== op-geth shim caught signal, killing ==========================\n") + sess.session.Terminate() + return awaitExit(sess.session) case <-sess.session.Exited: - return fmt.Errorf("geth exited") + return fmt.Errorf("geth exited with code %d", sess.session.ExitCode()) case <-time.After(30 * time.Minute): - return fmt.Errorf("exiting after 30 minute timeout") + fmt.Printf("================== op-geth shim timed out, killing ==========================\n") + sess.session.Terminate() + if err := awaitExit(sess.session); err != nil { + fmt.Printf("error killing geth: %v\n", err) + } + return errors.New("geth timed out after 30 minutes") + } +} + +func awaitExit(sess *gexec.Session) error { + select { + case <-sess.Exited: + return nil + case <-time.After(5 * time.Second): + sess.Kill() + select { + case <-sess.Exited: + return nil + case <-time.After(30 * time.Second): + return fmt.Errorf("exiting after 30 second timeout") + } } } diff --git a/op-e2e/external_geth/main_test.go b/op-e2e/external_geth/main_test.go index b1f09b580672..85f4218f90b1 100644 --- a/op-e2e/external_geth/main_test.go +++ b/op-e2e/external_geth/main_test.go @@ -33,7 +33,7 @@ func TestShim(t *testing.T) { require.NoError(t, err) require.FileExists(t, "op-geth") - config.EthNodeVerbosity = 4 + config.EthNodeVerbosity = config.LegacyLevelDebug ec := (&e2e.ExternalRunner{ Name: "TestShim", diff --git a/op-e2e/faultproof_test.go b/op-e2e/faultproof_test.go deleted file mode 100644 index b63216c4ea0f..000000000000 --- a/op-e2e/faultproof_test.go +++ /dev/null @@ -1,606 +0,0 @@ -package op_e2e - -import ( - "context" - "math/big" - "testing" - "time" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" - l2oo2 "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/l2oo" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/stretchr/testify/require" -) - -func TestMultipleCannonGames(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(0)) - - ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) - t.Cleanup(sys.Close) - - gameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client) - // Start a challenger with the correct alphabet trace - challenger := gameFactory.StartChallenger(ctx, sys.NodeEndpoint("l1"), "TowerDefense", - challenger.WithCannon(t, sys.RollupConfig, sys.L2GenesisCfg, sys.NodeEndpoint("sequencer")), - challenger.WithPrivKey(sys.cfg.Secrets.Alice), - challenger.WithAgreeProposedOutput(true), - ) - - game1 := gameFactory.StartCannonGame(ctx, common.Hash{0x01, 0xaa}) - game2 := gameFactory.StartCannonGame(ctx, common.Hash{0x01, 0xbb}) - - game1.WaitForClaimCount(ctx, 2) - game2.WaitForClaimCount(ctx, 2) - - game1Claim := game1.GetClaimValue(ctx, 1) - game2Claim := game2.GetClaimValue(ctx, 1) - require.NotEqual(t, game1Claim, game2Claim, "games should have different cannon traces") - - // Check that the helper finds the game directories correctly - challenger.VerifyGameDataExists(game1, game2) - - // Push both games down to the step function - maxDepth := game1.MaxDepth(ctx) - for claimCount := int64(1); claimCount <= maxDepth; { - // Challenger should respond to both games - claimCount++ - game1.WaitForClaimCount(ctx, claimCount) - game2.WaitForClaimCount(ctx, claimCount) - - // Progress both games - game1.Defend(ctx, claimCount-1, common.Hash{0xaa}) - game2.Defend(ctx, claimCount-1, common.Hash{0xaa}) - claimCount++ - } - - game1.WaitForClaimAtMaxDepth(ctx, true) - game2.WaitForClaimAtMaxDepth(ctx, true) - - gameDuration := game1.GameDuration(ctx) - sys.TimeTravelClock.AdvanceTime(gameDuration) - require.NoError(t, wait.ForNextBlock(ctx, l1Client)) - - game1.WaitForInactivity(ctx, 10, true) - game2.WaitForInactivity(ctx, 10, true) - game1.LogGameData(ctx) - game2.LogGameData(ctx) - require.EqualValues(t, disputegame.StatusChallengerWins, game1.Status(ctx)) - require.EqualValues(t, disputegame.StatusChallengerWins, game2.Status(ctx)) - - // Check that the game directories are removed - challenger.WaitForGameDataDeletion(ctx, game1, game2) -} - -func TestMultipleGameTypes(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(0)) - - ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) - t.Cleanup(sys.Close) - - gameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client) - // Start a challenger with both cannon and alphabet support - gameFactory.StartChallenger(ctx, sys.NodeEndpoint("l1"), "TowerDefense", - challenger.WithCannon(t, sys.RollupConfig, sys.L2GenesisCfg, sys.NodeEndpoint("sequencer")), - challenger.WithAlphabet(disputegame.CorrectAlphabet), - challenger.WithPrivKey(sys.cfg.Secrets.Alice), - challenger.WithAgreeProposedOutput(true), - ) - - game1 := gameFactory.StartCannonGame(ctx, common.Hash{0x01, 0xaa}) - game2 := gameFactory.StartAlphabetGame(ctx, "xyzabc") - - // Wait for the challenger to respond to both games - game1.WaitForClaimCount(ctx, 2) - game2.WaitForClaimCount(ctx, 2) - game1Response := game1.GetClaimValue(ctx, 1) - game2Response := game2.GetClaimValue(ctx, 1) - // The alphabet game always posts the same traces, so if they're different they can't both be from the alphabet. - require.NotEqual(t, game1Response, game2Response, "should have posted different claims") - // Now check they aren't both just from different cannon games by confirming the alphabet value. - correctAlphabet := alphabet.NewTraceProvider(disputegame.CorrectAlphabet, uint64(game2.MaxDepth(ctx))) - expectedClaim, err := correctAlphabet.Get(ctx, types.NewPositionFromGIndex(big.NewInt(1)).Attack()) - require.NoError(t, err) - require.Equal(t, expectedClaim, game2Response) - // We don't confirm the cannon value because generating the correct claim is expensive - // Just being different is enough to confirm the challenger isn't just playing two alphabet games incorrectly -} - -func TestChallengerCompleteDisputeGame(t *testing.T) { - InitParallel(t, UseExecutor(1), UsesCannon) - - tests := []struct { - name string - rootClaimAlphabet string - otherAlphabet string - expectedResult disputegame.Status - expectStep bool - }{ - { - name: "ChallengerWins_DefenseStep", - rootClaimAlphabet: "abcdexyz", - otherAlphabet: disputegame.CorrectAlphabet, - expectedResult: disputegame.StatusChallengerWins, - expectStep: true, - }, - { - name: "DefenderWins_DefenseStep", - rootClaimAlphabet: disputegame.CorrectAlphabet, - otherAlphabet: "abcdexyz", - expectedResult: disputegame.StatusDefenderWins, - expectStep: false, - }, - { - name: "ChallengerWins_AttackStep", - rootClaimAlphabet: "abcdefghzyx", - otherAlphabet: disputegame.CorrectAlphabet, - expectedResult: disputegame.StatusChallengerWins, - expectStep: true, - }, - { - name: "DefenderWins_AttackStep", - rootClaimAlphabet: disputegame.CorrectAlphabet, - otherAlphabet: "abcdexyz", - expectedResult: disputegame.StatusDefenderWins, - expectStep: false, - }, - { - name: "DefenderIncorrectAtTraceZero", - rootClaimAlphabet: "zyxwvut", - otherAlphabet: disputegame.CorrectAlphabet, - expectedResult: disputegame.StatusChallengerWins, - expectStep: true, - }, - { - name: "ChallengerIncorrectAtTraceZero", - rootClaimAlphabet: disputegame.CorrectAlphabet, - otherAlphabet: "zyxwvut", - expectedResult: disputegame.StatusDefenderWins, - expectStep: false, - }, - { - name: "DefenderIncorrectAtLastTraceIndex", - rootClaimAlphabet: "abcdefghijklmnoz", - otherAlphabet: disputegame.CorrectAlphabet, - expectedResult: disputegame.StatusChallengerWins, - expectStep: true, - }, - { - name: "ChallengerIncorrectAtLastTraceIndex", - rootClaimAlphabet: disputegame.CorrectAlphabet, - otherAlphabet: "abcdefghijklmnoz", - expectedResult: disputegame.StatusDefenderWins, - expectStep: false, - }, - } - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - InitParallel(t, UseExecutor(1), UsesCannon) - - ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) - t.Cleanup(sys.Close) - - disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client) - game := disputeGameFactory.StartAlphabetGame(ctx, test.rootClaimAlphabet) - require.NotNil(t, game) - gameDuration := game.GameDuration(ctx) - - game.StartChallenger(ctx, sys.NodeEndpoint("l1"), "Defender", - challenger.WithAgreeProposedOutput(false), - challenger.WithPrivKey(sys.cfg.Secrets.Mallory), - ) - - game.StartChallenger(ctx, sys.NodeEndpoint("l1"), "Challenger", - // Agree with the proposed output, so disagree with the root claim - challenger.WithAgreeProposedOutput(true), - challenger.WithAlphabet(test.otherAlphabet), - challenger.WithPrivKey(sys.cfg.Secrets.Alice), - ) - - // Wait for a claim at the maximum depth that has been countered to indicate we're ready to resolve the game - game.WaitForClaimAtMaxDepth(ctx, test.expectStep) - - sys.TimeTravelClock.AdvanceTime(gameDuration) - require.NoError(t, wait.ForNextBlock(ctx, l1Client)) - - game.WaitForInactivity(ctx, 10, true) - game.LogGameData(ctx) - require.EqualValues(t, test.expectedResult, game.Status(ctx)) - }) - } -} - -func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { - InitParallel(t, UseExecutor(1), UsesCannon) - - testCase := func(t *testing.T, isRootCorrect bool) { - ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) - t.Cleanup(sys.Close) - - disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client) - rootClaimedAlphabet := disputegame.CorrectAlphabet - if !isRootCorrect { - rootClaimedAlphabet = "abcdexyz" - } - game := disputeGameFactory.StartAlphabetGame(ctx, rootClaimedAlphabet) - require.NotNil(t, game) - gameDuration := game.GameDuration(ctx) - - // Start honest challenger - game.StartChallenger(ctx, sys.NodeEndpoint("l1"), "Challenger", - challenger.WithAgreeProposedOutput(!isRootCorrect), - challenger.WithAlphabet(disputegame.CorrectAlphabet), - challenger.WithPrivKey(sys.cfg.Secrets.Alice), - // Ensures the challenger responds to all claims before test timeout - challenger.WithPollInterval(time.Millisecond*400), - ) - - // Start dishonest challenger - dishonestHelper := game.CreateDishonestHelper(disputegame.CorrectAlphabet, 4, !isRootCorrect) - dishonestHelper.ExhaustDishonestClaims(ctx) - - // Wait until we've reached max depth before checking for inactivity - game.WaitForClaimAtDepth(ctx, int(game.MaxDepth(ctx))) - - // Wait for 4 blocks of no challenger responses. The challenger may still be stepping on invalid claims at max depth - game.WaitForInactivity(ctx, 4, false) - - sys.TimeTravelClock.AdvanceTime(gameDuration) - require.NoError(t, wait.ForNextBlock(ctx, l1Client)) - - expectedStatus := disputegame.StatusChallengerWins - if isRootCorrect { - expectedStatus = disputegame.StatusDefenderWins - } - game.WaitForInactivity(ctx, 10, true) - game.LogGameData(ctx) - require.EqualValues(t, expectedStatus, game.Status(ctx)) - } - - t.Run("RootCorrect", func(t *testing.T) { - InitParallel(t, UseExecutor(1), UsesCannon) - testCase(t, true) - }) - t.Run("RootIncorrect", func(t *testing.T) { - InitParallel(t, UseExecutor(1), UsesCannon) - testCase(t, false) - }) -} - -func TestCannonDisputeGame(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(1)) - - tests := []struct { - name string - defendClaimCount int64 - }{ - {"StepFirst", 0}, - {"StepMiddle", 28}, - {"StepInExtension", 2}, - } - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - InitParallel(t, UseExecutor(1), UsesCannon) - - ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) - t.Cleanup(sys.Close) - - disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client) - game := disputeGameFactory.StartCannonGame(ctx, common.Hash{0x01, 0xaa}) - require.NotNil(t, game) - game.LogGameData(ctx) - - game.StartChallenger(ctx, sys.RollupConfig, sys.L2GenesisCfg, sys.NodeEndpoint("l1"), sys.NodeEndpoint("sequencer"), "Challenger", - // Agree with the proposed output, so disagree with the root claim - challenger.WithAgreeProposedOutput(true), - challenger.WithPrivKey(sys.cfg.Secrets.Alice), - ) - - game.DefendRootClaim( - ctx, - func(parentClaimIdx int64) { - if parentClaimIdx+1 == test.defendClaimCount { - game.Defend(ctx, parentClaimIdx, common.Hash{byte(parentClaimIdx)}) - } else { - game.Attack(ctx, parentClaimIdx, common.Hash{byte(parentClaimIdx)}) - } - }) - - sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) - require.NoError(t, wait.ForNextBlock(ctx, l1Client)) - - game.WaitForInactivity(ctx, 10, true) - game.LogGameData(ctx) - require.EqualValues(t, disputegame.StatusChallengerWins, game.Status(ctx)) - }) - } -} - -func TestCannonDefendStep(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(1)) - - ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) - t.Cleanup(sys.Close) - - disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client) - game := disputeGameFactory.StartCannonGame(ctx, common.Hash{0x01, 0xaa}) - require.NotNil(t, game) - game.LogGameData(ctx) - - l1Endpoint := sys.NodeEndpoint("l1") - l2Endpoint := sys.NodeEndpoint("sequencer") - game.StartChallenger(ctx, sys.RollupConfig, sys.L2GenesisCfg, l1Endpoint, l2Endpoint, "Challenger", - // Agree with the proposed output, so disagree with the root claim - challenger.WithAgreeProposedOutput(true), - challenger.WithPrivKey(sys.cfg.Secrets.Alice), - ) - - correctTrace := game.CreateHonestActor(ctx, sys.RollupConfig, sys.L2GenesisCfg, l1Client, l1Endpoint, l2Endpoint, - challenger.WithPrivKey(sys.cfg.Secrets.Mallory), - ) - - game.DefendRootClaim(ctx, func(parentClaimIdx int64) { - // Post invalid claims for most steps to get down into the early part of the trace - if parentClaimIdx < 27 { - game.Attack(ctx, parentClaimIdx, common.Hash{byte(parentClaimIdx)}) - } else { - // Post our own counter but using the correct hash in low levels to force a defense step - correctTrace.Attack(ctx, parentClaimIdx) - } - }) - - sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) - require.NoError(t, wait.ForNextBlock(ctx, l1Client)) - - game.WaitForInactivity(ctx, 10, true) - game.LogGameData(ctx) - require.EqualValues(t, disputegame.StatusChallengerWins, game.Status(ctx)) -} - -func TestCannonProposedOutputRootInvalid(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(0)) - // honestStepsFail attempts to perform both an attack and defend step using the correct trace. - honestStepsFail := func(ctx context.Context, game *disputegame.CannonGameHelper, correctTrace *disputegame.HonestHelper, parentClaimIdx int64) { - // Attack step should fail - correctTrace.StepFails(ctx, parentClaimIdx, true) - // Defending should fail too - correctTrace.StepFails(ctx, parentClaimIdx, false) - } - tests := []struct { - // name is the name of the test - name string - - // outputRoot is the invalid output root to propose - outputRoot common.Hash - - // performMove is called to respond to each claim posted by the honest op-challenger. - // It should either attack or defend the claim at parentClaimIdx - performMove func(ctx context.Context, game *disputegame.CannonGameHelper, correctTrace *disputegame.HonestHelper, parentClaimIdx int64) - - // performStep is called once the maximum game depth is reached. It should perform a step to counter the - // claim at parentClaimIdx. Since the proposed output root is invalid, the step call should always revert. - performStep func(ctx context.Context, game *disputegame.CannonGameHelper, correctTrace *disputegame.HonestHelper, parentClaimIdx int64) - }{ - { - name: "AttackWithCorrectTrace", - outputRoot: common.Hash{0xab}, - performMove: func(ctx context.Context, game *disputegame.CannonGameHelper, correctTrace *disputegame.HonestHelper, parentClaimIdx int64) { - // Attack everything but oddly using the correct hash. - correctTrace.Attack(ctx, parentClaimIdx) - }, - performStep: honestStepsFail, - }, - { - name: "DefendWithCorrectTrace", - outputRoot: common.Hash{0xab}, - performMove: func(ctx context.Context, game *disputegame.CannonGameHelper, correctTrace *disputegame.HonestHelper, parentClaimIdx int64) { - // Can only attack the root claim - if parentClaimIdx == 0 { - correctTrace.Attack(ctx, parentClaimIdx) - return - } - // Otherwise, defend everything using the correct hash. - correctTrace.Defend(ctx, parentClaimIdx) - }, - performStep: honestStepsFail, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - InitParallel(t, UseExecutor(0)) - - ctx := context.Background() - sys, l1Client, game, correctTrace := setupDisputeGameForInvalidOutputRoot(t, test.outputRoot) - t.Cleanup(sys.Close) - - // Now maliciously play the game and it should be impossible to win - game.ChallengeRootClaim(ctx, - func(parentClaimIdx int64) { - test.performMove(ctx, game, correctTrace, parentClaimIdx) - }, - func(parentClaimIdx int64) { - test.performStep(ctx, game, correctTrace, parentClaimIdx) - }) - - // Time travel past when the game will be resolvable. - sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) - require.NoError(t, wait.ForNextBlock(ctx, l1Client)) - - game.WaitForInactivity(ctx, 10, true) - game.LogGameData(ctx) - require.EqualValues(t, disputegame.StatusDefenderWins, game.Status(ctx)) - }) - } -} - -func TestCannonPoisonedPostState(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(0)) - - ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) - t.Cleanup(sys.Close) - - l1Endpoint := sys.NodeEndpoint("l1") - l2Endpoint := sys.NodeEndpoint("sequencer") - - disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client) - game, correctTrace := disputeGameFactory.StartCannonGameWithCorrectRoot(ctx, sys.RollupConfig, sys.L2GenesisCfg, l1Endpoint, l2Endpoint, - challenger.WithPrivKey(sys.cfg.Secrets.Mallory), - ) - require.NotNil(t, game) - game.LogGameData(ctx) - - // Honest first attack at "honest" level - correctTrace.Attack(ctx, 0) - - // Honest defense at "dishonest" level - correctTrace.Defend(ctx, 1) - - // Dishonest attack at "honest" level - honest move would be to ignore - game.Attack(ctx, 2, common.Hash{0x03, 0xaa}) - - // Honest attack at "dishonest" level - honest move would be to ignore - correctTrace.Attack(ctx, 3) - - // Start the honest challenger - game.StartChallenger(ctx, sys.RollupConfig, sys.L2GenesisCfg, l1Endpoint, l2Endpoint, "Honest", - // Agree with the proposed output, so disagree with the root claim - challenger.WithAgreeProposedOutput(true), - challenger.WithPrivKey(sys.cfg.Secrets.Bob), - ) - - // Start dishonest challenger that posts correct claims - // It participates in the subgame root the honest claim index 4 - func() { - claimCount := int64(5) - depth := game.MaxDepth(ctx) - for { - game.LogGameData(ctx) - claimCount++ - // Wait for the challenger to counter - game.WaitForClaimCount(ctx, claimCount) - - // Respond with our own move - correctTrace.Defend(ctx, claimCount-1) - claimCount++ - game.WaitForClaimCount(ctx, claimCount) - - // Defender moves last. If we're at max depth, then we're done - pos := game.GetClaimPosition(ctx, claimCount-1) - if int64(pos.Depth()) == depth { - break - } - } - }() - - // Wait for the challenger to drive the subgame at 4 to the leaf node, which should be countered - game.WaitForClaimAtMaxDepth(ctx, true) - - // Time travel past when the game will be resolvable. - sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) - require.NoError(t, wait.ForNextBlock(ctx, l1Client)) - - game.WaitForInactivity(ctx, 10, true) - game.LogGameData(ctx) - require.EqualValues(t, disputegame.StatusChallengerWins, game.Status(ctx)) -} - -// setupDisputeGameForInvalidOutputRoot sets up an L2 chain with at least one valid output root followed by an invalid output root. -// A cannon dispute game is started to dispute the invalid output root with the correct root claim provided. -// An honest challenger is run to defend the root claim (ie disagree with the invalid output root). -func setupDisputeGameForInvalidOutputRoot(t *testing.T, outputRoot common.Hash) (*System, *ethclient.Client, *disputegame.CannonGameHelper, *disputegame.HonestHelper) { - ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) - - l2oo := l2oo2.NewL2OOHelper(t, sys.cfg.L1Deployments, l1Client, sys.cfg.Secrets.Proposer, sys.RollupConfig) - - // Wait for one valid output root to be submitted - l2oo.WaitForProposals(ctx, 1) - - // Stop the honest output submitter so we can publish invalid outputs - sys.L2OutputSubmitter.Stop() - sys.L2OutputSubmitter = nil - - // Submit an invalid output root - l2oo.PublishNextOutput(ctx, outputRoot) - - l1Endpoint := sys.NodeEndpoint("l1") - l2Endpoint := sys.NodeEndpoint("sequencer") - - // Dispute the new output root by creating a new game with the correct cannon trace. - disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client) - game, correctTrace := disputeGameFactory.StartCannonGameWithCorrectRoot(ctx, sys.RollupConfig, sys.L2GenesisCfg, l1Endpoint, l2Endpoint, - challenger.WithPrivKey(sys.cfg.Secrets.Mallory), - ) - require.NotNil(t, game) - - // Start the honest challenger - game.StartChallenger(ctx, sys.RollupConfig, sys.L2GenesisCfg, l1Endpoint, l2Endpoint, "Defender", - // Disagree with the proposed output, so agree with the (correct) root claim - challenger.WithAgreeProposedOutput(false), - challenger.WithPrivKey(sys.cfg.Secrets.Mallory), - ) - return sys, l1Client, game, correctTrace -} - -func TestCannonChallengeWithCorrectRoot(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(0)) - ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) - t.Cleanup(sys.Close) - - l1Endpoint := sys.NodeEndpoint("l1") - l2Endpoint := sys.NodeEndpoint("sequencer") - - disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client) - game, correctTrace := disputeGameFactory.StartCannonGameWithCorrectRoot(ctx, sys.RollupConfig, sys.L2GenesisCfg, l1Endpoint, l2Endpoint, - challenger.WithPrivKey(sys.cfg.Secrets.Mallory), - ) - require.NotNil(t, game) - game.LogGameData(ctx) - - game.StartChallenger(ctx, sys.RollupConfig, sys.L2GenesisCfg, l1Endpoint, l2Endpoint, "Challenger", - // Agree with the proposed output, so disagree with the root claim - challenger.WithAgreeProposedOutput(true), - challenger.WithPrivKey(sys.cfg.Secrets.Alice), - ) - - game.DefendRootClaim(ctx, func(parentClaimIdx int64) { - // Defend everything because we have the same trace as the honest proposer - correctTrace.Defend(ctx, parentClaimIdx) - }) - - sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) - require.NoError(t, wait.ForNextBlock(ctx, l1Client)) - - game.WaitForInactivity(ctx, 10, true) - game.LogGameData(ctx) - require.EqualValues(t, disputegame.StatusChallengerWins, game.Status(ctx)) -} - -func startFaultDisputeSystem(t *testing.T) (*System, *ethclient.Client) { - cfg := DefaultSystemConfig(t) - delete(cfg.Nodes, "verifier") - cfg.DeployConfig.SequencerWindowSize = 4 - cfg.DeployConfig.FinalizationPeriodSeconds = 2 - cfg.SupportL1TimeTravel = true - cfg.DeployConfig.L2OutputOracleSubmissionInterval = 1 - cfg.NonFinalizedProposals = true // Submit output proposals asap - sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") - return sys, sys.Clients["l1"] -} diff --git a/op-e2e/faultproofs/challenge_preimage_test.go b/op-e2e/faultproofs/challenge_preimage_test.go new file mode 100644 index 000000000000..f071580b51ae --- /dev/null +++ b/op-e2e/faultproofs/challenge_preimage_test.go @@ -0,0 +1,68 @@ +package faultproofs + +import ( + "context" + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame/preimage" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestChallengeLargePreimages_ChallengeFirst(t *testing.T) { + op_e2e.InitParallel(t) + ctx := context.Background() + sys, _ := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + disputeGameFactory.StartChallenger(ctx, "Challenger", + challenger.WithAlphabet(sys.RollupEndpoint("sequencer")), + challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + preimageHelper := disputeGameFactory.PreimageHelper(ctx) + ident := preimageHelper.UploadLargePreimage(ctx, preimage.MinPreimageSize, + preimage.WithReplacedCommitment(0, common.Hash{0xaa})) + + require.NotEqual(t, ident.Claimant, common.Address{}) + + preimageHelper.WaitForChallenged(ctx, ident) +} + +func TestChallengeLargePreimages_ChallengeMiddle(t *testing.T) { + op_e2e.InitParallel(t) + ctx := context.Background() + sys, _ := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + disputeGameFactory.StartChallenger(ctx, "Challenger", + challenger.WithAlphabet(sys.RollupEndpoint("sequencer")), + challenger.WithPrivKey(sys.Cfg.Secrets.Mallory)) + preimageHelper := disputeGameFactory.PreimageHelper(ctx) + ident := preimageHelper.UploadLargePreimage(ctx, preimage.MinPreimageSize, + preimage.WithReplacedCommitment(10, common.Hash{0xaa})) + + require.NotEqual(t, ident.Claimant, common.Address{}) + + preimageHelper.WaitForChallenged(ctx, ident) +} + +func TestChallengeLargePreimages_ChallengeLast(t *testing.T) { + op_e2e.InitParallel(t) + ctx := context.Background() + sys, _ := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + disputeGameFactory.StartChallenger(ctx, "Challenger", + challenger.WithAlphabet(sys.RollupEndpoint("sequencer")), + challenger.WithPrivKey(sys.Cfg.Secrets.Mallory)) + preimageHelper := disputeGameFactory.PreimageHelper(ctx) + ident := preimageHelper.UploadLargePreimage(ctx, preimage.MinPreimageSize, + preimage.WithLastCommitment(common.Hash{0xaa})) + + require.NotEqual(t, ident.Claimant, common.Address{}) + + preimageHelper.WaitForChallenged(ctx, ident) +} diff --git a/op-e2e/faultproofs/multi_test.go b/op-e2e/faultproofs/multi_test.go new file mode 100644 index 000000000000..0db4167cf492 --- /dev/null +++ b/op-e2e/faultproofs/multi_test.go @@ -0,0 +1,41 @@ +package faultproofs + +import ( + "context" + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" + "github.com/ethereum/go-ethereum/common" +) + +func TestMultipleGameTypes(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, _ := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + gameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + + game1 := gameFactory.StartOutputCannonGame(ctx, "sequencer", 1, common.Hash{0x01, 0xaa}) + game2 := gameFactory.StartOutputAlphabetGame(ctx, "sequencer", 1, common.Hash{0xbb}) + latestClaim1 := game1.DisputeLastBlock(ctx) + latestClaim2 := game2.DisputeLastBlock(ctx) + + // Start a challenger with both cannon and alphabet support + gameFactory.StartChallenger(ctx, "TowerDefense", + challenger.WithCannon(t, sys.RollupConfig, sys.L2GenesisCfg, sys.RollupEndpoint("sequencer"), sys.NodeEndpoint("sequencer")), + challenger.WithAlphabet(sys.RollupEndpoint("sequencer")), + challenger.WithPrivKey(sys.Cfg.Secrets.Alice), + ) + + // Wait for the challenger to respond to both games + counter1 := latestClaim1.WaitForCounterClaim(ctx) + counter2 := latestClaim2.WaitForCounterClaim(ctx) + // The alphabet game always posts the same traces, so if they're different they can't both be from the alphabet. + // We're contesting the same block with different VMs, so if the challenger was just playing two cannon or alphabet + // games the responses would be equal. + counter1.RequireDifferentClaimValue(counter2) +} diff --git a/op-e2e/faultproofs/output_alphabet_test.go b/op-e2e/faultproofs/output_alphabet_test.go new file mode 100644 index 000000000000..e87049b9c2e9 --- /dev/null +++ b/op-e2e/faultproofs/output_alphabet_test.go @@ -0,0 +1,296 @@ +package faultproofs + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-chain-ops/deployer" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestOutputAlphabetGame_ChallengerWins(t *testing.T) { + op_e2e.InitParallel(t) + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputAlphabetGame(ctx, "sequencer", 3, common.Hash{0xff}) + correctTrace := game.CreateHonestActor(ctx, "sequencer") + game.LogGameData(ctx) + + opts := challenger.WithPrivKey(sys.Cfg.Secrets.Alice) + game.StartChallenger(ctx, "sequencer", "Challenger", opts) + game.LogGameData(ctx) + + // Challenger should post an output root to counter claims down to the leaf level of the top game + claim := game.RootClaim(ctx) + for claim.IsOutputRoot(ctx) && !claim.IsOutputRootLeaf(ctx) { + if claim.AgreesWithOutputRoot() { + // If the latest claim agrees with the output root, expect the honest challenger to counter it + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + claim.RequireCorrectOutputRoot(ctx) + } else { + // Otherwise we should counter + claim = claim.Attack(ctx, common.Hash{0xaa}) + game.LogGameData(ctx) + } + } + + // Wait for the challenger to post the first claim in the cannon trace + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + + // Attack the root of the alphabet trace subgame + claim = correctTrace.AttackClaim(ctx, claim) + for !claim.IsMaxDepth(ctx) { + if claim.AgreesWithOutputRoot() { + // If the latest claim supports the output root, wait for the honest challenger to respond + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + } else { + // Otherwise we need to counter the honest claim + claim = correctTrace.AttackClaim(ctx, claim) + game.LogGameData(ctx) + } + } + // Challenger should be able to call step and counter the leaf claim. + claim.WaitForCountered(ctx) + game.LogGameData(ctx) + + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) + game.LogGameData(ctx) +} + +func TestOutputAlphabetGame_ReclaimBond(t *testing.T) { + op_e2e.InitParallel(t) + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputAlphabetGame(ctx, "sequencer", 3, common.Hash{0xff}) + game.LogGameData(ctx) + + // The dispute game should have a zero balance + balance := game.WethBalance(ctx, game.Addr()) + require.Zero(t, balance.Uint64()) + + alice := sys.Cfg.Secrets.Addresses().Alice + + // Grab the root claim + claim := game.RootClaim(ctx) + opts := challenger.WithPrivKey(sys.Cfg.Secrets.Alice) + game.StartChallenger(ctx, "sequencer", "Challenger", opts) + game.LogGameData(ctx) + + // Perform a few moves + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + claim = claim.Attack(ctx, common.Hash{}) + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + claim = claim.Attack(ctx, common.Hash{}) + game.LogGameData(ctx) + _ = claim.WaitForCounterClaim(ctx) + + // Expect posted claims so the game balance is non-zero + balance = game.WethBalance(ctx, game.Addr()) + require.Truef(t, balance.Cmp(big.NewInt(0)) > 0, "Expected game balance to be above zero") + + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) + game.LogGameData(ctx) + + // Expect Alice's credit to be non-zero + // But it can't be claimed right now since there is a delay on the weth unlock + require.Truef(t, game.AvailableCredit(ctx, alice).Cmp(big.NewInt(0)) > 0, "Expected alice credit to be above zero") + + // The actor should have no credit available because all its bonds were paid to Alice. + actorCredit := game.AvailableCredit(ctx, deployer.TestAddress) + require.True(t, actorCredit.Cmp(big.NewInt(0)) == 0, "Expected alice available credit to be zero") + + // Advance the time past the weth unlock delay + sys.TimeTravelClock.AdvanceTime(game.CreditUnlockDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + // Wait for alice to have no available credit + // aka, wait for the challenger to claim its credit + game.WaitForNoAvailableCredit(ctx, alice) + + // The dispute game delayed weth balance should be zero since it's all claimed + require.True(t, game.WethBalance(ctx, game.Addr()).Cmp(big.NewInt(0)) == 0) +} + +func TestOutputAlphabetGame_ValidOutputRoot(t *testing.T) { + op_e2e.InitParallel(t) + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputAlphabetGameWithCorrectRoot(ctx, "sequencer", 2) + correctTrace := game.CreateHonestActor(ctx, "sequencer") + game.LogGameData(ctx) + claim := game.DisputeLastBlock(ctx) + // Invalid root claim of the alphabet game + claim = claim.Attack(ctx, common.Hash{0x01}) + + opts := challenger.WithPrivKey(sys.Cfg.Secrets.Alice) + game.StartChallenger(ctx, "sequencer", "Challenger", opts) + + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + for !claim.IsMaxDepth(ctx) { + // Dishonest actor always attacks with the correct trace + claim = correctTrace.AttackClaim(ctx, claim) + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + } + + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + game.WaitForGameStatus(ctx, disputegame.StatusDefenderWins) +} + +func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { + op_e2e.InitParallel(t) + + testCase := func(t *testing.T, isRootCorrect bool) { + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + var game *disputegame.OutputAlphabetGameHelper + if isRootCorrect { + game = disputeGameFactory.StartOutputAlphabetGameWithCorrectRoot(ctx, "sequencer", 1) + } else { + game = disputeGameFactory.StartOutputAlphabetGame(ctx, "sequencer", 1, common.Hash{0xaa, 0xbb, 0xcc}) + } + claim := game.DisputeLastBlock(ctx) + + game.LogGameData(ctx) + + // Start honest challenger + game.StartChallenger(ctx, "sequencer", "Challenger", + challenger.WithAlphabet(sys.RollupEndpoint("sequencer")), + challenger.WithPrivKey(sys.Cfg.Secrets.Alice), + // Ensures the challenger responds to all claims before test timeout + challenger.WithPollInterval(time.Millisecond*400), + ) + + if isRootCorrect { + // Attack the correct output root with an invalid alphabet trace + claim = claim.Attack(ctx, common.Hash{0x01}) + } else { + // Wait for the challenger to counter the invalid output root + claim = claim.WaitForCounterClaim(ctx) + } + + // Start dishonest challenger + dishonestHelper := game.CreateDishonestHelper(ctx, "sequencer", !isRootCorrect) + dishonestHelper.ExhaustDishonestClaims(ctx, claim) + + // Wait until we've reached max depth before checking for inactivity + game.WaitForClaimAtDepth(ctx, game.MaxDepth(ctx)) + + // Wait for 4 blocks of no challenger responses. The challenger may still be stepping on invalid claims at max depth + game.WaitForInactivity(ctx, 4, false) + + gameDuration := game.GameDuration(ctx) + sys.TimeTravelClock.AdvanceTime(gameDuration) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + expectedStatus := disputegame.StatusChallengerWins + if isRootCorrect { + expectedStatus = disputegame.StatusDefenderWins + } + game.WaitForGameStatus(ctx, expectedStatus) + game.LogGameData(ctx) + } + + t.Run("RootCorrect", func(t *testing.T) { + op_e2e.InitParallel(t) + testCase(t, true) + }) + t.Run("RootIncorrect", func(t *testing.T) { + op_e2e.InitParallel(t) + testCase(t, false) + }) +} + +func TestOutputAlphabetGame_FreeloaderEarnsNothing(t *testing.T) { + op_e2e.InitParallel(t) + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + freeloaderOpts, err := bind.NewKeyedTransactorWithChainID(sys.Cfg.Secrets.Mallory, sys.Cfg.L1ChainIDBig()) + require.Nil(t, err) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputAlphabetGameWithCorrectRoot(ctx, "sequencer", 2) + correctTrace := game.CreateHonestActor(ctx, "sequencer") + game.LogGameData(ctx) + claim := game.DisputeLastBlock(ctx) + // Invalid root claim of the alphabet game + claim = claim.Attack(ctx, common.Hash{0x01}) + + // Chronology of claims: + // dishonest root claim: + // - honest counter + // - dishonest + // - freeloader + // - honest + // - freeloader + // The freeloader must be positioned leftmost (gindex positioning) or at the same position as honest claims. + + // honest counter + claim = correctTrace.AttackClaim(ctx, claim) + + var freeloaders []*disputegame.ClaimHelper + + // dishonest + dishonest := correctTrace.AttackClaim(ctx, claim) + + freeloaders = append(freeloaders, correctTrace.AttackClaim(ctx, dishonest, disputegame.WithTransactOpts(freeloaderOpts))) + freeloaders = append(freeloaders, dishonest.Attack(ctx, common.Hash{0x02}, disputegame.WithTransactOpts(freeloaderOpts))) + freeloaders = append(freeloaders, dishonest.Defend(ctx, common.Hash{0x03}, disputegame.WithTransactOpts(freeloaderOpts))) + + // Ensure freeloaders respond before the honest challenger + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + dishonest.WaitForCounterClaim(ctx, freeloaders...) + + // Freeloaders after the honest challenger + freeloaders = append(freeloaders, dishonest.Attack(ctx, common.Hash{0x04}, disputegame.WithTransactOpts(freeloaderOpts))) + freeloaders = append(freeloaders, dishonest.Defend(ctx, common.Hash{0x05}, disputegame.WithTransactOpts(freeloaderOpts))) + + for _, freeloader := range freeloaders { + if freeloader.IsMaxDepth(ctx) { + freeloader.WaitForCountered(ctx) + } else { + freeloader.WaitForCounterClaim(ctx) + } + } + + game.LogGameData(ctx) + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + game.WaitForGameStatus(ctx, disputegame.StatusDefenderWins) + + amt := game.Credit(ctx, freeloaderOpts.From) + require.True(t, amt.BitLen() == 0, "freeloaders should not be rewarded") +} diff --git a/op-e2e/faultproofs/output_cannon_test.go b/op-e2e/faultproofs/output_cannon_test.go new file mode 100644 index 000000000000..6aed7c041e34 --- /dev/null +++ b/op-e2e/faultproofs/output_cannon_test.go @@ -0,0 +1,786 @@ +package faultproofs + +import ( + "context" + "fmt" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame/preimage" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/require" +) + +func TestOutputCannonGame(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 4, common.Hash{0x01}) + game.LogGameData(ctx) + + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + game.LogGameData(ctx) + + // Challenger should post an output root to counter claims down to the leaf level of the top game + claim := game.RootClaim(ctx) + for claim.IsOutputRoot(ctx) && !claim.IsOutputRootLeaf(ctx) { + if claim.AgreesWithOutputRoot() { + // If the latest claim agrees with the output root, expect the honest challenger to counter it + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + claim.RequireCorrectOutputRoot(ctx) + } else { + // Otherwise we should counter + claim = claim.Attack(ctx, common.Hash{0xaa}) + game.LogGameData(ctx) + } + } + + // Wait for the challenger to post the first claim in the cannon trace + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + + // Attack the root of the cannon trace subgame + claim = claim.Attack(ctx, common.Hash{0x00, 0xcc}) + for !claim.IsMaxDepth(ctx) { + if claim.AgreesWithOutputRoot() { + // If the latest claim supports the output root, wait for the honest challenger to respond + claim = claim.WaitForCounterClaim(ctx) + game.LogGameData(ctx) + } else { + // Otherwise we need to counter the honest claim + claim = claim.Defend(ctx, common.Hash{0x00, 0xdd}) + game.LogGameData(ctx) + } + } + // Challenger should be able to call step and counter the leaf claim. + claim.WaitForCountered(ctx) + game.LogGameData(ctx) + + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) +} + +func TestOutputCannon_ChallengeAllZeroClaim(t *testing.T) { + // The dishonest actor always posts claims with all zeros. + op_e2e.InitParallel(t, op_e2e.UsesCannon) + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 3, common.Hash{}) + game.LogGameData(ctx) + + claim := game.DisputeLastBlock(ctx) + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + game.DefendClaim(ctx, claim, func(parent *disputegame.ClaimHelper) *disputegame.ClaimHelper { + if parent.IsBottomGameRoot(ctx) { + return parent.Attack(ctx, common.Hash{}) + } + return parent.Defend(ctx, common.Hash{}) + }) + + game.LogGameData(ctx) + + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) + game.LogGameData(ctx) +} + +func TestOutputCannon_PublishCannonRootClaim(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + tests := []struct { + disputeL2BlockNumber uint64 + }{ + {7}, // Post-state output root is invalid + {8}, // Post-state output root is valid + } + for _, test := range tests { + test := test + t.Run(fmt.Sprintf("Dispute_%v", test.disputeL2BlockNumber), func(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, _ := startFaultDisputeSystem(t) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", test.disputeL2BlockNumber, common.Hash{0x01}) + game.DisputeLastBlock(ctx) + game.LogGameData(ctx) + + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + splitDepth := game.SplitDepth(ctx) + game.WaitForClaimAtDepth(ctx, splitDepth+1) + }) + } +} + +func TestOutputCannonDisputeGame(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + tests := []struct { + name string + defendClaimDepth types.Depth + }{ + {"StepFirst", 0}, + {"StepMiddle", 28}, + {"StepInExtension", 1}, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 1, common.Hash{0x01, 0xaa}) + require.NotNil(t, game) + game.LogGameData(ctx) + + outputClaim := game.DisputeLastBlock(ctx) + splitDepth := game.SplitDepth(ctx) + + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + game.DefendClaim( + ctx, + outputClaim, + func(claim *disputegame.ClaimHelper) *disputegame.ClaimHelper { + if claim.Depth()+1 == splitDepth+test.defendClaimDepth { + return claim.Defend(ctx, common.Hash{byte(claim.Depth())}) + } else { + return claim.Attack(ctx, common.Hash{byte(claim.Depth())}) + } + }) + + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + game.LogGameData(ctx) + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) + }) + } +} + +func TestOutputCannonDefendStep(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 1, common.Hash{0x01, 0xaa}) + require.NotNil(t, game) + outputRootClaim := game.DisputeLastBlock(ctx) + game.LogGameData(ctx) + + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + correctTrace := game.CreateHonestActor(ctx, "sequencer", challenger.WithPrivKey(sys.Cfg.Secrets.Mallory)) + + maxDepth := game.MaxDepth(ctx) + game.DefendClaim(ctx, outputRootClaim, func(claim *disputegame.ClaimHelper) *disputegame.ClaimHelper { + // Post invalid claims for most steps to get down into the early part of the trace + if claim.Depth() < maxDepth-3 { + return claim.Attack(ctx, common.Hash{0xaa}) + } else { + // Post our own counter but using the correct hash in low levels to force a defense step + return correctTrace.AttackClaim(ctx, claim) + } + }) + + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + game.WaitForInactivity(ctx, 10, true) + game.LogGameData(ctx) + require.EqualValues(t, disputegame.StatusChallengerWins, game.Status(ctx)) +} + +func TestOutputCannonStepWithLargePreimage(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, _ := startFaultDisputeSystem(t, withBatcherStopped()) + t.Cleanup(sys.Close) + + // Manually send a tx from the correct batcher key to the batcher input with very large (invalid) data + // This forces op-program to load a large preimage. + sys.BatcherHelper().SendLargeInvalidBatch(ctx) + + require.NoError(t, sys.BatchSubmitter.Start(ctx)) + + safeHead, err := wait.ForNextSafeBlock(ctx, sys.NodeClient("sequencer")) + require.NoError(t, err, "Batcher should resume submitting valid batches") + + l2BlockNumber := safeHead.NumberU64() + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + // Dispute any block - it will have to read the L1 batches to see if the block is reached + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", l2BlockNumber, common.Hash{0x01, 0xaa}) + require.NotNil(t, game) + outputRootClaim := game.DisputeBlock(ctx, l2BlockNumber) + game.LogGameData(ctx) + + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + // Wait for the honest challenger to dispute the outputRootClaim. + // This creates a root of an execution game that we challenge by + // coercing a step at a preimage trace index. + outputRootClaim = outputRootClaim.WaitForCounterClaim(ctx) + + game.LogGameData(ctx) + // Now the honest challenger is positioned as the defender of the + // execution game. We then move to challenge it to induce a large preimage load. + sender := sys.Cfg.Secrets.Addresses().Alice + preimageLoadCheck := game.CreateStepLargePreimageLoadCheck(ctx, sender) + game.ChallengeToPreimageLoad(ctx, outputRootClaim, sys.Cfg.Secrets.Alice, cannon.PreimageLargerThan(preimage.MinPreimageSize), preimageLoadCheck, false) + // The above method already verified the image was uploaded and step called successfully + // So we don't waste time resolving the game - that's tested elsewhere. +} + +func TestOutputCannonStepWithPreimage(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + testPreimageStep := func(t *testing.T, preimageType cannon.PreimageOpt, preloadPreimage bool) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, _ := startFaultDisputeSystem(t, withBlobBatches()) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 1, common.Hash{0x01, 0xaa}) + require.NotNil(t, game) + outputRootClaim := game.DisputeLastBlock(ctx) + game.LogGameData(ctx) + + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + // Wait for the honest challenger to dispute the outputRootClaim. This creates a root of an execution game that we challenge by coercing + // a step at a preimage trace index. + outputRootClaim = outputRootClaim.WaitForCounterClaim(ctx) + + // Now the honest challenger is positioned as the defender of the execution game + // We then move to challenge it to induce a preimage load + preimageLoadCheck := game.CreateStepPreimageLoadCheck(ctx) + game.ChallengeToPreimageLoad(ctx, outputRootClaim, sys.Cfg.Secrets.Alice, preimageType, preimageLoadCheck, preloadPreimage) + // The above method already verified the image was uploaded and step called successfully + // So we don't waste time resolving the game - that's tested elsewhere. + } + + preimageConditions := []string{"keccak", "sha256", "blob"} + for _, preimageType := range preimageConditions { + preimageType := preimageType + t.Run("non-existing preimage-"+preimageType, func(t *testing.T) { + testPreimageStep(t, cannon.FirstPreimageLoadOfType(preimageType), false) + }) + } + // Only test pre-existing images with one type to save runtime + t.Run("preimage already exists", func(t *testing.T) { + testPreimageStep(t, cannon.FirstKeccakPreimageLoad(), true) + }) +} + +func TestOutputCannonStepWithKZGPointEvaluation(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + testPreimageStep := func(t *testing.T, preloadPreimage bool) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, _ := startFaultDisputeSystem(t, withEcotone()) + t.Cleanup(sys.Close) + + // NOTE: Flake prevention + // Ensure that the L1 origin including the point eval tx isn't on the genesis epoch. + safeBlock, err := sys.Clients["sequencer"].BlockByNumber(ctx, big.NewInt(int64(rpc.SafeBlockNumber))) + require.NoError(t, err) + require.NoError(t, wait.ForSafeBlock(ctx, sys.RollupClient("sequencer"), safeBlock.NumberU64()+3)) + + receipt := sendKZGPointEvaluationTx(t, sys, "sequencer", sys.Cfg.Secrets.Alice) + precompileBlock := receipt.BlockNumber + t.Logf("KZG Point Evaluation block number: %d", precompileBlock) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", precompileBlock.Uint64(), common.Hash{0x01, 0xaa}) + require.NotNil(t, game) + outputRootClaim := game.DisputeLastBlock(ctx) + game.LogGameData(ctx) + + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + // Wait for the honest challenger to dispute the outputRootClaim. This creates a root of an execution game that we challenge by coercing + // a step at a preimage trace index. + outputRootClaim = outputRootClaim.WaitForCounterClaim(ctx) + + // Now the honest challenger is positioned as the defender of the execution game + // We then move to challenge it to induce a preimage load + preimageLoadCheck := game.CreateStepPreimageLoadCheck(ctx) + game.ChallengeToPreimageLoad(ctx, outputRootClaim, sys.Cfg.Secrets.Alice, cannon.FirstPrecompilePreimageLoad(), preimageLoadCheck, preloadPreimage) + // The above method already verified the image was uploaded and step called successfully + // So we don't waste time resolving the game - that's tested elsewhere. + } + + t.Run("non-existing preimage", func(t *testing.T) { + testPreimageStep(t, false) + }) + t.Run("preimage already exists", func(t *testing.T) { + testPreimageStep(t, true) + }) +} + +func TestOutputCannonProposedOutputRootValid(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + // honestStepsFail attempts to perform both an attack and defend step using the correct trace. + honestStepsFail := func(ctx context.Context, game *disputegame.OutputCannonGameHelper, correctTrace *disputegame.OutputHonestHelper, parentClaimIdx int64) { + // Attack step should fail + correctTrace.StepFails(ctx, parentClaimIdx, true) + // Defending should fail too + correctTrace.StepFails(ctx, parentClaimIdx, false) + } + tests := []struct { + // name is the name of the test + name string + + // performMove is called to respond to each claim posted by the honest op-challenger. + // It should either attack or defend the claim at parentClaimIdx + performMove func(ctx context.Context, game *disputegame.OutputCannonGameHelper, correctTrace *disputegame.OutputHonestHelper, claim *disputegame.ClaimHelper) *disputegame.ClaimHelper + + // performStep is called once the maximum game depth is reached. It should perform a step to counter the + // claim at parentClaimIdx. Since the proposed output root is invalid, the step call should always revert. + performStep func(ctx context.Context, game *disputegame.OutputCannonGameHelper, correctTrace *disputegame.OutputHonestHelper, parentClaimIdx int64) + }{ + { + name: "AttackWithCorrectTrace", + performMove: func(ctx context.Context, game *disputegame.OutputCannonGameHelper, correctTrace *disputegame.OutputHonestHelper, claim *disputegame.ClaimHelper) *disputegame.ClaimHelper { + // Attack everything but oddly using the correct hash. + // Except the root of the cannon game must have an invalid VM status code. + if claim.IsOutputRootLeaf(ctx) { + return claim.Attack(ctx, common.Hash{0x01}) + } + return correctTrace.AttackClaim(ctx, claim) + }, + performStep: honestStepsFail, + }, + { + name: "DefendWithCorrectTrace", + performMove: func(ctx context.Context, game *disputegame.OutputCannonGameHelper, correctTrace *disputegame.OutputHonestHelper, claim *disputegame.ClaimHelper) *disputegame.ClaimHelper { + // Can only attack the root claim or the first cannon claim + if claim.IsRootClaim() { + return correctTrace.AttackClaim(ctx, claim) + } + // The root of the cannon game must have an invalid VM status code + // Attacking ensure we're running the cannon trace between two different blocks + // instead of being in the trace extension of the output root bisection + if claim.IsOutputRootLeaf(ctx) { + return claim.Attack(ctx, common.Hash{0x01}) + } + // Otherwise, defend everything using the correct hash. + return correctTrace.DefendClaim(ctx, claim) + }, + performStep: honestStepsFail, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGameWithCorrectRoot(ctx, "sequencer", 1) + correctTrace := game.CreateHonestActor(ctx, "sequencer", challenger.WithPrivKey(sys.Cfg.Secrets.Mallory)) + + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + // Now maliciously play the game and it should be impossible to win + game.ChallengeClaim(ctx, + game.RootClaim(ctx), + func(claim *disputegame.ClaimHelper) *disputegame.ClaimHelper { + return test.performMove(ctx, game, correctTrace, claim) + }, + func(parentClaimIdx int64) { + test.performStep(ctx, game, correctTrace, parentClaimIdx) + }) + + // Time travel past when the game will be resolvable. + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + game.WaitForInactivity(ctx, 10, true) + game.LogGameData(ctx) + require.EqualValues(t, disputegame.StatusDefenderWins, game.Status(ctx)) + }) + } +} + +func TestOutputCannonPoisonedPostState(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + // Root claim is dishonest + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 1, common.Hash{0xaa}) + correctTrace := game.CreateHonestActor(ctx, "sequencer", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + // Honest first attack at "honest" level + claim := correctTrace.AttackClaim(ctx, game.RootClaim(ctx)) + + // Honest defense at "dishonest" level + claim = correctTrace.DefendClaim(ctx, claim) + + // Dishonest attack at "honest" level - honest move would be to ignore + claimToIgnore1 := claim.Attack(ctx, common.Hash{0x03, 0xaa}) + + // Honest attack at "dishonest" level - honest move would be to ignore + claimToIgnore2 := correctTrace.AttackClaim(ctx, claimToIgnore1) + game.LogGameData(ctx) + + // Start the honest challenger + game.StartChallenger(ctx, "sequencer", "Honest", challenger.WithPrivKey(sys.Cfg.Secrets.Bob)) + + // Start dishonest challenger that posts correct claims + for { + game.LogGameData(ctx) + // Wait for the challenger to counter + // Note that we need to ignore claimToIgnore1 which already counters this... + claim = claim.WaitForCounterClaim(ctx, claimToIgnore1) + + // Respond with our own move + if claim.IsBottomGameRoot(ctx) { + // Root of the cannon game must have the right VM status code (so it can't be honest). + // Note this occurs when there are splitDepth + 4 claims because there are multiple forks in this game. + claim = claim.Attack(ctx, common.Hash{0x01}) + } else { + claim = correctTrace.DefendClaim(ctx, claim) + } + + // Defender moves last. If we're at max depth, then we're done + if claim.IsMaxDepth(ctx) { + break + } + } + + // Wait for the challenger to call step + claim.WaitForCountered(ctx) + // Verify that the challenger didn't challenge our poisoned claims + claimToIgnore1.RequireOnlyCounteredBy(ctx, claimToIgnore2) + claimToIgnore2.RequireOnlyCounteredBy(ctx /* nothing */) + + // Time travel past when the game will be resolvable. + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + game.LogGameData(ctx) + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) +} + +func TestDisputeOutputRootBeyondProposedBlock_ValidOutputRoot(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + // Root claim is dishonest + game := disputeGameFactory.StartOutputCannonGameWithCorrectRoot(ctx, "sequencer", 1) + correctTrace := game.CreateHonestActor(ctx, "sequencer", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + // Start the honest challenger + game.StartChallenger(ctx, "sequencer", "Honest", challenger.WithPrivKey(sys.Cfg.Secrets.Bob)) + + claim := game.RootClaim(ctx) + // Attack the output root + claim = correctTrace.AttackClaim(ctx, claim) + // Wait for the challenger to respond + claim = claim.WaitForCounterClaim(ctx) + // Then defend until the split depth to force the game into the extension part of the output root bisection + // ie. the output root we wind up disputing is theoretically for a block after block number 1 + for !claim.IsOutputRootLeaf(ctx) { + claim = correctTrace.DefendClaim(ctx, claim) + claim = claim.WaitForCounterClaim(ctx) + } + game.LogGameData(ctx) + // At this point we've reached the bottom of the output root bisection and every claim + // will have the same, valid, output root. We now need to post a cannon trace root that claims its invalid. + claim = claim.Defend(ctx, common.Hash{0x01, 0xaa}) + // Now defend with the correct trace + for { + game.LogGameData(ctx) + claim = claim.WaitForCounterClaim(ctx) + if claim.IsMaxDepth(ctx) { + break + } + claim = correctTrace.DefendClaim(ctx, claim) + } + // Should not be able to step either attacking or defending + correctTrace.StepClaimFails(ctx, claim, true) + correctTrace.StepClaimFails(ctx, claim, false) + + // Time travel past when the game will be resolvable. + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + game.WaitForGameStatus(ctx, disputegame.StatusDefenderWins) + game.LogGameData(ctx) +} + +func TestDisputeOutputRootBeyondProposedBlock_InvalidOutputRoot(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + // Root claim is dishonest + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 1, common.Hash{0xaa}) + correctTrace := game.CreateHonestActor(ctx, "sequencer", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + // Start the honest challenger + game.StartChallenger(ctx, "sequencer", "Honest", challenger.WithPrivKey(sys.Cfg.Secrets.Bob)) + + claim := game.RootClaim(ctx) + // Wait for the honest challenger to counter the root + claim = claim.WaitForCounterClaim(ctx) + // Then defend until the split depth to force the game into the extension part of the output root bisection + // ie. the output root we wind up disputing is theoretically for a block after block number 1 + // The dishonest actor challenges with the correct roots + for claim.IsOutputRoot(ctx) { + claim = correctTrace.DefendClaim(ctx, claim) + claim = claim.WaitForCounterClaim(ctx) + } + game.LogGameData(ctx) + // Now defend with the correct trace + for !claim.IsMaxDepth(ctx) { + game.LogGameData(ctx) + if claim.IsBottomGameRoot(ctx) { + claim = correctTrace.AttackClaim(ctx, claim) + } else { + claim = correctTrace.DefendClaim(ctx, claim) + } + if !claim.IsMaxDepth(ctx) { + // Have to attack the root of the cannon trace + claim = claim.WaitForCounterClaim(ctx) + } + } + + // Wait for our final claim to be countered by the challenger calling step + claim.WaitForCountered(ctx) + + // Time travel past when the game will be resolvable. + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) + game.LogGameData(ctx) +} + +func TestDisputeOutputRoot_ChangeClaimedOutputRoot(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, l1Client := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + // Root claim is dishonest + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 1, common.Hash{0xaa}) + correctTrace := game.CreateHonestActor(ctx, "sequencer", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + // Start the honest challenger + game.StartChallenger(ctx, "sequencer", "Honest", challenger.WithPrivKey(sys.Cfg.Secrets.Bob)) + + claim := game.RootClaim(ctx) + // Wait for the honest challenger to counter the root + claim = claim.WaitForCounterClaim(ctx) + + // Then attack every claim until the leaf of output root bisection + for { + claim = claim.Attack(ctx, common.Hash{0xbb}) + claim = claim.WaitForCounterClaim(ctx) + if claim.Depth() == game.SplitDepth(ctx)-1 { + // Post the correct output root as the leaf. + // This is for block 1 which is what the original output root was for too + claim = correctTrace.AttackClaim(ctx, claim) + // Challenger should post the first cannon trace + claim = claim.WaitForCounterClaim(ctx) + break + } + } + + game.LogGameData(ctx) + + // Now defend with the correct trace + for !claim.IsMaxDepth(ctx) { + game.LogGameData(ctx) + if claim.IsBottomGameRoot(ctx) { + claim = correctTrace.AttackClaim(ctx, claim) + } else { + claim = correctTrace.DefendClaim(ctx, claim) + } + if !claim.IsMaxDepth(ctx) { + // Have to attack the root of the cannon trace + claim = claim.WaitForCounterClaim(ctx) + } + } + + // Wait for our final claim to be countered by the challenger calling step + claim.WaitForCountered(ctx) + + // Time travel past when the game will be resolvable. + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) + game.LogGameData(ctx) +} + +func TestInvalidateUnsafeProposal(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + ctx := context.Background() + + tests := []struct { + name string + strategy func(correctTrace *disputegame.OutputHonestHelper, parent *disputegame.ClaimHelper) *disputegame.ClaimHelper + }{ + { + name: "Attack", + strategy: func(correctTrace *disputegame.OutputHonestHelper, parent *disputegame.ClaimHelper) *disputegame.ClaimHelper { + return correctTrace.AttackClaim(ctx, parent) + }, + }, + { + name: "Defend", + strategy: func(correctTrace *disputegame.OutputHonestHelper, parent *disputegame.ClaimHelper) *disputegame.ClaimHelper { + return correctTrace.DefendClaim(ctx, parent) + }, + }, + { + name: "Counter", + strategy: func(correctTrace *disputegame.OutputHonestHelper, parent *disputegame.ClaimHelper) *disputegame.ClaimHelper { + return correctTrace.CounterClaim(ctx, parent) + }, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + sys, l1Client := startFaultDisputeSystem(t, withSequencerWindowSize(100000), withBatcherStopped()) + t.Cleanup(sys.Close) + + blockNum := uint64(1) + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + // Root claim is _dishonest_ because the required data is not available on L1 + game := disputeGameFactory.StartOutputCannonGameWithCorrectRoot(ctx, "sequencer", blockNum, disputegame.WithUnsafeProposal()) + + correctTrace := game.CreateHonestActor(ctx, "sequencer", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + // Start the honest challenger + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Bob)) + + game.DefendClaim(ctx, game.RootClaim(ctx), func(parent *disputegame.ClaimHelper) *disputegame.ClaimHelper { + if parent.IsBottomGameRoot(ctx) { + return correctTrace.AttackClaim(ctx, parent) + } + return test.strategy(correctTrace, parent) + }) + + // Time travel past when the game will be resolvable. + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) + game.LogGameData(ctx) + }) + } +} + +func TestInvalidateProposalForFutureBlock(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + ctx := context.Background() + + tests := []struct { + name string + strategy func(correctTrace *disputegame.OutputHonestHelper, parent *disputegame.ClaimHelper) *disputegame.ClaimHelper + }{ + { + name: "Attack", + strategy: func(correctTrace *disputegame.OutputHonestHelper, parent *disputegame.ClaimHelper) *disputegame.ClaimHelper { + return correctTrace.AttackClaim(ctx, parent) + }, + }, + { + name: "Defend", + strategy: func(correctTrace *disputegame.OutputHonestHelper, parent *disputegame.ClaimHelper) *disputegame.ClaimHelper { + return correctTrace.DefendClaim(ctx, parent) + }, + }, + { + name: "Counter", + strategy: func(correctTrace *disputegame.OutputHonestHelper, parent *disputegame.ClaimHelper) *disputegame.ClaimHelper { + return correctTrace.CounterClaim(ctx, parent) + }, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + sys, l1Client := startFaultDisputeSystem(t, withSequencerWindowSize(100000)) + t.Cleanup(sys.Close) + + farFutureBlockNum := uint64(10_000_000) + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + // Root claim is _dishonest_ because the required data is not available on L1 + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", farFutureBlockNum, common.Hash{0xaa}, disputegame.WithFutureProposal()) + + correctTrace := game.CreateHonestActor(ctx, "sequencer", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + // Start the honest challenger + game.StartChallenger(ctx, "sequencer", "Honest", challenger.WithPrivKey(sys.Cfg.Secrets.Bob)) + + game.DefendClaim(ctx, game.RootClaim(ctx), func(parent *disputegame.ClaimHelper) *disputegame.ClaimHelper { + if parent.IsBottomGameRoot(ctx) { + return correctTrace.AttackClaim(ctx, parent) + } + return test.strategy(correctTrace, parent) + }) + + // Time travel past when the game will be resolvable. + sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx)) + require.NoError(t, wait.ForNextBlock(ctx, l1Client)) + + game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) + game.LogGameData(ctx) + }) + } +} diff --git a/op-e2e/faultproofs/precompile_test.go b/op-e2e/faultproofs/precompile_test.go new file mode 100644 index 000000000000..388fc6aeba52 --- /dev/null +++ b/op-e2e/faultproofs/precompile_test.go @@ -0,0 +1,170 @@ +package faultproofs + +import ( + "context" + "encoding/json" + "fmt" + "math" + "path/filepath" + "testing" + + "github.com/ethereum-optimism/optimism/cannon/mipsevm" + "github.com/ethereum-optimism/optimism/op-challenger/config" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon" + "github.com/ethereum-optimism/optimism/op-challenger/metrics" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/ioutil" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/require" +) + +func TestPrecompiles(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + // precompile test vectors copied from go-ethereum + tests := []struct { + name string + address common.Address + input []byte + }{ + { + name: "ecrecover", + address: common.BytesToAddress([]byte{0x01}), + input: common.FromHex("18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549"), + }, + { + name: "sha256", + address: common.BytesToAddress([]byte{0x02}), + input: common.FromHex("68656c6c6f20776f726c64"), + }, + { + name: "ripemd160", + address: common.BytesToAddress([]byte{0x03}), + input: common.FromHex("68656c6c6f20776f726c64"), + }, + { + name: "bn256Pairing", + address: common.BytesToAddress([]byte{0x08}), + input: common.FromHex("1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa"), + }, + { + name: "blake2F", + address: common.BytesToAddress([]byte{0x09}), + input: common.FromHex("0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001"), + }, + { + name: "kzgPointEvaluation", + address: common.BytesToAddress([]byte{0x0a}), + input: common.FromHex("01e798154708fe7789429634053cbf9f99b619f9f084048927333fce637f549b564c0a11a0f704f4fc3e8acfe0f8245f0ad1347b378fbf96e206da11a5d3630624d25032e67a7e6a4910df5834b8fe70e6bcfeeac0352434196bdf4b2485d5a18f59a8d2a1a625a17f3fea0fe5eb8c896db3764f3185481bc22f91b4aaffcca25f26936857bc3a7c2539ea8ec3a952b7873033e038326e87ed3e1276fd140253fa08e9fc25fb2d9a98527fc22a2c9612fbeafdad446cbc7bcdbdcd780af2c16a"), + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + ctx := context.Background() + cfg := op_e2e.DefaultSystemConfig(t) + // We don't need a verifier - just the sequencer is enough + delete(cfg.Nodes, "verifier") + // Use a small sequencer window size to avoid test timeout while waiting for empty blocks + // But not too small to ensure that our claim and subsequent state change is published + cfg.DeployConfig.SequencerWindowSize = 16 + minTs := hexutil.Uint64(0) + cfg.DeployConfig.L2GenesisDeltaTimeOffset = &minTs + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &minTs + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + defer sys.Close() + + log := testlog.Logger(t, log.LevelInfo) + log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) + + l1Client := sys.Clients["l1"] + l2Seq := sys.Clients["sequencer"] + rollupRPCClient, err := rpc.DialContext(context.Background(), sys.RollupNodes["sequencer"].HTTPEndpoint()) + require.Nil(t, err) + rollupClient := sources.NewRollupClient(client.NewBaseRPCClient(rollupRPCClient)) + + aliceKey := cfg.Secrets.Alice + + t.Log("Capture current L2 head as agreed starting point") + latestBlock, err := l2Seq.BlockByNumber(ctx, nil) + require.NoError(t, err) + agreedL2Output, err := rollupClient.OutputAtBlock(ctx, latestBlock.NumberU64()) + require.NoError(t, err, "could not retrieve l2 agreed block") + l2Head := agreedL2Output.BlockRef.Hash + l2OutputRoot := agreedL2Output.OutputRoot + + receipt := op_e2e.SendL2Tx(t, cfg, l2Seq, aliceKey, func(opts *op_e2e.TxOpts) { + opts.Gas = 1_000_000 + opts.ToAddr = &test.address + opts.Nonce = 0 + opts.Data = test.input + }) + + t.Log("Determine L2 claim") + l2ClaimBlockNumber := receipt.BlockNumber + l2Output, err := rollupClient.OutputAtBlock(ctx, l2ClaimBlockNumber.Uint64()) + require.NoError(t, err, "could not get expected output") + l2Claim := l2Output.OutputRoot + + t.Log("Determine L1 head that includes all batches required for L2 claim block") + require.NoError(t, wait.ForSafeBlock(ctx, rollupClient, l2ClaimBlockNumber.Uint64())) + l1HeadBlock, err := l1Client.BlockByNumber(ctx, nil) + require.NoError(t, err, "get l1 head block") + l1Head := l1HeadBlock.Hash() + + inputs := cannon.LocalGameInputs{ + L1Head: l1Head, + L2Head: l2Head, + L2Claim: common.Hash(l2Claim), + L2OutputRoot: common.Hash(l2OutputRoot), + L2BlockNumber: l2ClaimBlockNumber, + } + runCannon(t, ctx, sys, inputs, "sequencer") + }) + } +} + +func runCannon(t *testing.T, ctx context.Context, sys *op_e2e.System, inputs cannon.LocalGameInputs, l2Node string) { + l1Endpoint := sys.NodeEndpoint("l1") + l1Beacon := sys.L1BeaconEndpoint() + cannonOpts := challenger.WithCannon(t, sys.RollupCfg(), sys.L2Genesis(), sys.RollupEndpoint(l2Node), sys.NodeEndpoint(l2Node)) + dir := t.TempDir() + proofsDir := filepath.Join(dir, "cannon-proofs") + cfg := config.NewConfig(common.Address{}, l1Endpoint, l1Beacon, dir) + cannonOpts(&cfg) + + logger := testlog.Logger(t, log.LevelInfo).New("role", "cannon") + executor := cannon.NewExecutor(logger, metrics.NoopMetrics, &cfg, inputs) + + t.Log("Running cannon") + err := executor.GenerateProof(ctx, proofsDir, math.MaxUint) + require.NoError(t, err, "failed to generate proof") + + state, err := parseState(filepath.Join(proofsDir, "final.json.gz")) + require.NoError(t, err, "failed to parse state") + t.Logf("Completed in %d steps", state.Step) +} + +func parseState(path string) (*mipsevm.State, error) { + file, err := ioutil.OpenDecompressed(path) + if err != nil { + return nil, fmt.Errorf("cannot open state file (%v): %w", path, err) + } + defer file.Close() + var state mipsevm.State + err = json.NewDecoder(file).Decode(&state) + if err != nil { + return nil, fmt.Errorf("invalid mipsevm state (%v): %w", path, err) + } + return &state, nil +} diff --git a/op-e2e/faultproofs/preimages_test.go b/op-e2e/faultproofs/preimages_test.go new file mode 100644 index 000000000000..fd6032b83fa1 --- /dev/null +++ b/op-e2e/faultproofs/preimages_test.go @@ -0,0 +1,53 @@ +package faultproofs + +import ( + "context" + "fmt" + "testing" + + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" + preimage "github.com/ethereum-optimism/optimism/op-preimage" + "github.com/ethereum-optimism/optimism/op-program/client" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestLocalPreimages(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + tests := []struct { + key preimage.Key + }{ + {key: client.L1HeadLocalIndex}, + {key: client.L2OutputRootLocalIndex}, + {key: client.L2ClaimLocalIndex}, + {key: client.L2ClaimBlockNumberLocalIndex}, + // We don't check client.L2ChainIDLocalIndex because e2e tests use a custom chain configuration + // which requires using a custom chain ID indicator so op-program will load the full rollup config and + // genesis from the preimage oracle + } + for _, test := range tests { + test := test + t.Run(fmt.Sprintf("preimage-%v", test.key), func(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon) + + ctx := context.Background() + sys, _ := startFaultDisputeSystem(t) + t.Cleanup(sys.Close) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 3, common.Hash{0x01, 0xaa}) + require.NotNil(t, game) + claim := game.DisputeLastBlock(ctx) + + // Create the root of the cannon trace. + claim = claim.Attack(ctx, common.Hash{0x01}) + + game.LogGameData(ctx) + + game.VerifyPreimage(ctx, claim, test.key) + + game.LogGameData(ctx) + }) + } +} diff --git a/op-e2e/faultproofs/util.go b/op-e2e/faultproofs/util.go new file mode 100644 index 000000000000..804c8f307a02 --- /dev/null +++ b/op-e2e/faultproofs/util.go @@ -0,0 +1,74 @@ +package faultproofs + +import ( + "crypto/ecdsa" + "testing" + + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + op_e2e "github.com/ethereum-optimism/optimism/op-e2e" + "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/ethclient" + "github.com/stretchr/testify/require" +) + +type faultDisputeConfigOpts func(cfg *op_e2e.SystemConfig) + +func withBatcherStopped() faultDisputeConfigOpts { + return func(cfg *op_e2e.SystemConfig) { + cfg.DisableBatcher = true + } +} + +func withBlobBatches() faultDisputeConfigOpts { + return func(cfg *op_e2e.SystemConfig) { + cfg.DataAvailabilityType = batcherFlags.BlobsType + + genesisActivation := hexutil.Uint64(0) + cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation + cfg.DeployConfig.L2GenesisDeltaTimeOffset = &genesisActivation + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisActivation + } +} + +func withEcotone() faultDisputeConfigOpts { + return func(cfg *op_e2e.SystemConfig) { + genesisActivation := hexutil.Uint64(0) + cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation + cfg.DeployConfig.L2GenesisDeltaTimeOffset = &genesisActivation + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisActivation + } +} + +func withSequencerWindowSize(size uint64) faultDisputeConfigOpts { + return func(cfg *op_e2e.SystemConfig) { + cfg.DeployConfig.SequencerWindowSize = size + } +} + +func startFaultDisputeSystem(t *testing.T, opts ...faultDisputeConfigOpts) (*op_e2e.System, *ethclient.Client) { + cfg := op_e2e.DefaultSystemConfig(t) + delete(cfg.Nodes, "verifier") + for _, opt := range opts { + opt(&cfg) + } + cfg.Nodes["sequencer"].SafeDBPath = t.TempDir() + cfg.DeployConfig.SequencerWindowSize = 4 + cfg.DeployConfig.FinalizationPeriodSeconds = 2 + cfg.SupportL1TimeTravel = true + cfg.DeployConfig.L2OutputOracleSubmissionInterval = 1 + cfg.NonFinalizedProposals = true // Submit output proposals asap + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + return sys, sys.Clients["l1"] +} + +func sendKZGPointEvaluationTx(t *testing.T, sys *op_e2e.System, l2Node string, privateKey *ecdsa.PrivateKey) *types.Receipt { + return op_e2e.SendL2Tx(t, sys.Cfg, sys.Clients[l2Node], privateKey, func(opts *op_e2e.TxOpts) { + precompile := common.BytesToAddress([]byte{0x0a}) + opts.Gas = 100_000 + opts.ToAddr = &precompile + opts.Data = common.FromHex("01e798154708fe7789429634053cbf9f99b619f9f084048927333fce637f549b564c0a11a0f704f4fc3e8acfe0f8245f0ad1347b378fbf96e206da11a5d3630624d25032e67a7e6a4910df5834b8fe70e6bcfeeac0352434196bdf4b2485d5a18f59a8d2a1a625a17f3fea0fe5eb8c896db3764f3185481bc22f91b4aaffcca25f26936857bc3a7c2539ea8ec3a952b7873033e038326e87ed3e1276fd140253fa08e9fc25fb2d9a98527fc22a2c9612fbeafdad446cbc7bcdbdcd780af2c16a") + }) +} diff --git a/op-e2e/helper.go b/op-e2e/helper.go index 3c8d411b1292..e9e53deac8b1 100644 --- a/op-e2e/helper.go +++ b/op-e2e/helper.go @@ -1,55 +1,79 @@ package op_e2e import ( + "crypto/md5" "os" "strconv" - "testing" + "strings" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" ) var enableParallelTesting bool = os.Getenv("OP_E2E_DISABLE_PARALLEL") != "true" -type testopts struct { - executor uint64 -} - -func InitParallel(t *testing.T, args ...func(t *testing.T, opts *testopts)) { +func InitParallel(t e2eutils.TestingBase, args ...func(t e2eutils.TestingBase)) { t.Helper() if enableParallelTesting { t.Parallel() } - - opts := &testopts{} for _, arg := range args { - arg(t, opts) + arg(t) } - checkExecutor(t, opts.executor) + autoAllocateExecutor(t) +} + +// isSubTest determines if the test is a sub-test or top level test. +// It does this by checking if the test name contains / +// This is not a particularly great way check, but appears to be the only option currently. +func isSubTest(t e2eutils.TestingBase) bool { + return strings.Contains(t.Name(), "/") } -func UsesCannon(t *testing.T, opts *testopts) { +func autoAllocateExecutor(t e2eutils.TestingBase) { + if isSubTest(t) { + // Always run subtests, they only start on the same executor as their parent. + return + } + info := getExecutorInfo(t) + tName := t.Name() + tHash := md5.Sum([]byte(tName)) + executor := uint64(tHash[0]) % info.total + checkExecutor(t, info, executor) +} + +func UsesCannon(t e2eutils.TestingBase) { if os.Getenv("OP_E2E_CANNON_ENABLED") == "false" { t.Skip("Skipping cannon test") } } -// UseExecutor allows manually splitting tests between circleci executors -// -// Tests default to run on the first executor but can be moved to the second with: -// InitParallel(t, UseExecutor(1)) -// Any tests assigned to an executor greater than the number available automatically use the last executor. -// Executor indexes start from 0 -func UseExecutor(assignedIdx uint64) func(t *testing.T, opts *testopts) { - return func(t *testing.T, opts *testopts) { - opts.executor = assignedIdx +func SkipOnFPAC(t e2eutils.TestingBase) { + if e2eutils.UseFPAC() { + t.Skip("Skipping test for FPAC") + } +} + +func SkipOnNotFPAC(t e2eutils.TestingBase) { + if !e2eutils.UseFPAC() { + t.Skip("Skipping test for non-FPAC") } } -func checkExecutor(t *testing.T, assignedIdx uint64) { +type executorInfo struct { + total uint64 + idx uint64 + splitInUse bool +} + +func getExecutorInfo(t e2eutils.TestingBase) executorInfo { + var info executorInfo envTotal := os.Getenv("CIRCLE_NODE_TOTAL") envIdx := os.Getenv("CIRCLE_NODE_INDEX") if envTotal == "" || envIdx == "" { // Not using test splitting, so ignore assigned executor - t.Logf("Running test. Test splitting not in use.") - return + t.Logf("Test splitting not in use.") + info.total = 1 + return info } total, err := strconv.ParseUint(envTotal, 10, 0) if err != nil { @@ -59,13 +83,26 @@ func checkExecutor(t *testing.T, assignedIdx uint64) { if err != nil { t.Fatalf("Could not parse CIRCLE_NODE_INDEX env var %v: %v", envIdx, err) } - if assignedIdx >= total && idx == total-1 { - t.Logf("Running test. Current executor (%v) is the last executor and assigned executor (%v) >= total executors (%v).", idx, assignedIdx, total) + + info.total = total + info.idx = idx + info.splitInUse = true + return info +} + +func checkExecutor(t e2eutils.TestingBase, info executorInfo, assignedIdx uint64) { + if !info.splitInUse { + t.Logf("Test splitting not in use.") + return + } + + if assignedIdx >= info.total && info.idx == info.total-1 { + t.Logf("Running test. Current executor (%v) is the last executor and assigned executor (%v) >= total executors (%v).", info.idx, assignedIdx, info.total) return } - if idx == assignedIdx { - t.Logf("Running test. Assigned executor (%v) matches current executor (%v) of total (%v)", assignedIdx, idx, total) + if info.idx == assignedIdx { + t.Logf("Running test. Assigned executor (%v) matches current executor (%v) of total (%v)", assignedIdx, info.idx, info.total) return } - t.Skipf("Skipping test. Assigned executor %v, current executor %v of total %v", assignedIdx, idx, total) + t.Skipf("Skipping test. Assigned executor %v, current executor %v of total %v", assignedIdx, info.idx, info.total) } diff --git a/op-e2e/l1_beacon_client_test.go b/op-e2e/l1_beacon_client_test.go new file mode 100644 index 000000000000..09cdd4c592d2 --- /dev/null +++ b/op-e2e/l1_beacon_client_test.go @@ -0,0 +1,32 @@ +package op_e2e + +import ( + "context" + "testing" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/fakebeacon" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestGetVersion(t *testing.T) { + InitParallel(t) + + l := testlog.Logger(t, log.LevelInfo) + + beaconApi := fakebeacon.NewBeacon(l, t.TempDir(), uint64(0), uint64(0)) + t.Cleanup(func() { + _ = beaconApi.Close() + }) + require.NoError(t, beaconApi.Start("127.0.0.1:0")) + + beaconCfg := sources.L1BeaconClientConfig{FetchAllSidecars: false} + cl := sources.NewL1BeaconClient(sources.NewBeaconHTTPClient(client.NewBasicHTTPClient(beaconApi.BeaconAddr(), l)), beaconCfg) + + version, err := cl.GetVersion(context.Background()) + require.NoError(t, err) + require.Equal(t, "fakebeacon 1.2.3", version) +} diff --git a/op-e2e/op_geth.go b/op-e2e/op_geth.go index 6b7eef31b48b..4afe487bffd1 100644 --- a/op-e2e/op_geth.go +++ b/op-e2e/op_geth.go @@ -18,6 +18,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" + "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/ethclient" @@ -47,12 +48,13 @@ type OpGeth struct { L1Head eth.BlockInfo L2Head *eth.ExecutionPayload sequenceNum uint64 + lgr log.Logger } func NewOpGeth(t *testing.T, ctx context.Context, cfg *SystemConfig) (*OpGeth, error) { - logger := testlog.Logger(t, log.LvlCrit) + logger := testlog.Logger(t, log.LevelCrit) - l1Genesis, err := genesis.BuildL1DeveloperGenesis(cfg.DeployConfig, config.L1Allocs, config.L1Deployments, true) + l1Genesis, err := genesis.BuildL1DeveloperGenesis(cfg.DeployConfig, config.L1Allocs, config.L1Deployments) require.Nil(t, err) l1Block := l1Genesis.ToBlock() @@ -91,14 +93,17 @@ func NewOpGeth(t *testing.T, ctx context.Context, cfg *SystemConfig) (*OpGeth, e auth := rpc.WithHTTPAuth(gn.NewJWTAuth(cfg.JWTSecret)) l2Node, err := client.NewRPC(ctx, logger, node.WSAuthEndpoint(), client.WithGethRPCOptions(auth)) - require.Nil(t, err) + require.NoError(t, err) // Finally create the engine client + rollupCfg, err := cfg.DeployConfig.RollupConfig(l1Block, l2GenesisBlock.Hash(), l2GenesisBlock.NumberU64()) + require.NoError(t, err) + rollupCfg.Genesis = rollupGenesis l2Engine, err := sources.NewEngineClient( l2Node, logger, nil, - sources.EngineClientDefaultConfig(&rollup.Config{Genesis: rollupGenesis}), + sources.EngineClientDefaultConfig(rollupCfg), ) require.Nil(t, err) @@ -117,18 +122,21 @@ func NewOpGeth(t *testing.T, ctx context.Context, cfg *SystemConfig) (*OpGeth, e L2ChainConfig: l2Genesis.Config, L1Head: eth.BlockToInfo(l1Block), L2Head: genesisPayload, + lgr: logger, }, nil } func (d *OpGeth) Close() { - _ = d.node.Close() + if err := d.node.Close(); err != nil { + d.lgr.Error("error closing node", "err", err) + } d.l2Engine.Close() d.L2Client.Close() } // AddL2Block Appends a new L2 block to the current chain including the specified transactions // The L1Info transaction is automatically prepended to the created block -func (d *OpGeth) AddL2Block(ctx context.Context, txs ...*types.Transaction) (*eth.ExecutionPayload, error) { +func (d *OpGeth) AddL2Block(ctx context.Context, txs ...*types.Transaction) (*eth.ExecutionPayloadEnvelope, error) { attrs, err := d.CreatePayloadAttributes(txs...) if err != nil { return nil, err @@ -138,7 +146,9 @@ func (d *OpGeth) AddL2Block(ctx context.Context, txs ...*types.Transaction) (*et return nil, err } - payload, err := d.l2Engine.GetPayload(ctx, *res.PayloadID) + envelope, err := d.l2Engine.GetPayload(ctx, eth.PayloadInfo{ID: *res.PayloadID, Timestamp: uint64(attrs.Timestamp)}) + payload := envelope.ExecutionPayload + if err != nil { return nil, err } @@ -146,7 +156,7 @@ func (d *OpGeth) AddL2Block(ctx context.Context, txs ...*types.Transaction) (*et return nil, errors.New("required transactions were not included") } - status, err := d.l2Engine.NewPayload(ctx, payload) + status, err := d.l2Engine.NewPayload(ctx, payload, envelope.ParentBeaconBlockRoot) if err != nil { return nil, err } @@ -167,7 +177,7 @@ func (d *OpGeth) AddL2Block(ctx context.Context, txs ...*types.Transaction) (*et } d.L2Head = payload d.sequenceNum = d.sequenceNum + 1 - return payload, nil + return envelope, nil } // StartBlockBuilding begins block building for the specified PayloadAttributes by sending a engine_forkChoiceUpdated call. @@ -194,8 +204,7 @@ func (d *OpGeth) StartBlockBuilding(ctx context.Context, attrs *eth.PayloadAttri // CreatePayloadAttributes creates a valid PayloadAttributes containing a L1Info deposit transaction followed by the supplied transactions. func (d *OpGeth) CreatePayloadAttributes(txs ...*types.Transaction) (*eth.PayloadAttributes, error) { timestamp := d.L2Head.Timestamp + 2 - regolith := d.L2ChainConfig.IsRegolith(uint64(timestamp)) - l1Info, err := derive.L1InfoDepositBytes(d.sequenceNum, d.L1Head, d.SystemConfig, regolith) + l1Info, err := derive.L1InfoDepositBytes(d.l2Engine.RollupConfig(), d.SystemConfig, d.sequenceNum, d.L1Head, uint64(timestamp)) if err != nil { return nil, err } @@ -215,12 +224,18 @@ func (d *OpGeth) CreatePayloadAttributes(txs ...*types.Transaction) (*eth.Payloa withdrawals = &types.Withdrawals{} } + var parentBeaconBlockRoot *common.Hash + if d.L2ChainConfig.IsEcotone(uint64(timestamp)) { + parentBeaconBlockRoot = d.L1Head.ParentBeaconRoot() + } + attrs := eth.PayloadAttributes{ - Timestamp: timestamp, - Transactions: txBytes, - NoTxPool: true, - GasLimit: (*eth.Uint64Quantity)(&d.SystemConfig.GasLimit), - Withdrawals: withdrawals, + Timestamp: timestamp, + Transactions: txBytes, + NoTxPool: true, + GasLimit: (*eth.Uint64Quantity)(&d.SystemConfig.GasLimit), + Withdrawals: withdrawals, + ParentBeaconBlockRoot: parentBeaconBlockRoot, } return &attrs, nil } diff --git a/op-e2e/op_geth_test.go b/op-e2e/op_geth_test.go index 230e99914ee0..03a1f8c4234e 100644 --- a/op-e2e/op_geth_test.go +++ b/op-e2e/op_geth_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum" @@ -53,7 +54,7 @@ func TestTxGasSameAsBlockGasLimit(t *testing.T) { require.Nil(t, err, "Error starting up system") defer sys.Close() - ethPrivKey := sys.cfg.Secrets.Alice + ethPrivKey := sys.Cfg.Secrets.Alice tx := types.MustSignNewTx(ethPrivKey, types.LatestSignerForChainID(cfg.L2ChainIDBig()), &types.DynamicFeeTx{ ChainID: cfg.L2ChainIDBig(), Gas: 29_999_999, @@ -195,14 +196,16 @@ func TestGethOnlyPendingBlockIsLatest(t *testing.T) { time.Sleep(time.Second * 4) // conservatively wait 4 seconds, CI might lag during block building. // retrieve the block - payload, err := opGeth.l2Engine.GetPayload(ctx, *res.PayloadID) + envelope, err := opGeth.l2Engine.GetPayload(ctx, eth.PayloadInfo{ID: *res.PayloadID, Timestamp: uint64(attrs.Timestamp)}) require.NoError(t, err) + + payload := envelope.ExecutionPayload checkPending("retrieved", 0) require.Len(t, payload.Transactions, 2, "must include L1 info tx and tx from alice") checkPendingBalance() // process the block - status, err := opGeth.l2Engine.NewPayload(ctx, payload) + status, err := opGeth.l2Engine.NewPayload(ctx, payload, envelope.ParentBeaconBlockRoot) require.NoError(t, err) require.Equal(t, eth.ExecutionValid, status.Status) checkPending("processed", 0) @@ -220,7 +223,6 @@ func TestGethOnlyPendingBlockIsLatest(t *testing.T) { } func TestPreregolith(t *testing.T) { - InitParallel(t) futureTimestamp := hexutil.Uint64(4) tests := []struct { name string @@ -259,11 +261,11 @@ func TestPreregolith(t *testing.T) { IsSystemTransaction: false, }) - block, err := opGeth.AddL2Block(ctx, depositTx) + envelope, err := opGeth.AddL2Block(ctx, depositTx) require.NoError(t, err) // L1Info tx should report 0 gas used - infoTx, err := opGeth.L2Client.TransactionInBlock(ctx, block.BlockHash, 0) + infoTx, err := opGeth.L2Client.TransactionInBlock(ctx, envelope.ExecutionPayload.BlockHash, 0) require.NoError(t, err) infoRcpt, err := opGeth.L2Client.TransactionReceipt(ctx, infoTx.Hash()) require.NoError(t, err) @@ -393,7 +395,8 @@ func TestPreregolith(t *testing.T) { require.NoError(t, err) defer opGeth.Close() - systemTx, err := derive.L1InfoDeposit(1, opGeth.L1Head, opGeth.SystemConfig, false) + rollupCfg := rollup.Config{} + systemTx, err := derive.L1InfoDeposit(&rollupCfg, opGeth.SystemConfig, 1, opGeth.L1Head, 0) systemTx.IsSystemTransaction = true require.NoError(t, err) @@ -404,7 +407,6 @@ func TestPreregolith(t *testing.T) { } func TestRegolith(t *testing.T) { - InitParallel(t) tests := []struct { name string regolithTime hexutil.Uint64 @@ -448,11 +450,11 @@ func TestRegolith(t *testing.T) { IsSystemTransaction: false, }) - block, err := opGeth.AddL2Block(ctx, depositTx) + envelope, err := opGeth.AddL2Block(ctx, depositTx) require.NoError(t, err) // L1Info tx should report actual gas used, not 0 or the tx gas limit - infoTx, err := opGeth.L2Client.TransactionInBlock(ctx, block.BlockHash, 0) + infoTx, err := opGeth.L2Client.TransactionInBlock(ctx, envelope.ExecutionPayload.BlockHash, 0) require.NoError(t, err) infoRcpt, err := opGeth.L2Client.TransactionReceipt(ctx, infoTx.Hash()) require.NoError(t, err) @@ -589,7 +591,8 @@ func TestRegolith(t *testing.T) { test.activateRegolith(ctx, opGeth) - systemTx, err := derive.L1InfoDeposit(1, opGeth.L1Head, opGeth.SystemConfig, false) + rollupCfg := rollup.Config{} + systemTx, err := derive.L1InfoDeposit(&rollupCfg, opGeth.SystemConfig, 1, opGeth.L1Head, 0) systemTx.IsSystemTransaction = true require.NoError(t, err) @@ -721,7 +724,6 @@ func TestRegolith(t *testing.T) { } func TestPreCanyon(t *testing.T) { - InitParallel(t) futureTimestamp := hexutil.Uint64(4) tests := []struct { @@ -748,7 +750,7 @@ func TestPreCanyon(t *testing.T) { b, err := opGeth.AddL2Block(ctx) require.NoError(t, err) - assert.Nil(t, b.Withdrawals, "should not have withdrawals") + assert.Nil(t, b.ExecutionPayload.Withdrawals, "should not have withdrawals") l1Block, err := opGeth.L2Client.BlockByNumber(ctx, nil) require.Nil(t, err) @@ -785,19 +787,16 @@ func TestPreCanyon(t *testing.T) { assert.Equal(t, types.ReceiptStatusFailed, receipt.Status) }) } - } func TestCanyon(t *testing.T) { - InitParallel(t) - tests := []struct { - name string - canyonTime hexutil.Uint64 - activeCanyon func(ctx context.Context, opGeth *OpGeth) + name string + canyonTime hexutil.Uint64 + activateCanyon func(ctx context.Context, opGeth *OpGeth) }{ - {name: "ActivateAtGenesis", canyonTime: 0, activeCanyon: func(ctx context.Context, opGeth *OpGeth) {}}, - {name: "ActivateAfterGenesis", canyonTime: 2, activeCanyon: func(ctx context.Context, opGeth *OpGeth) { + {name: "ActivateAtGenesis", canyonTime: 0, activateCanyon: func(ctx context.Context, opGeth *OpGeth) {}}, + {name: "ActivateAfterGenesis", canyonTime: 2, activateCanyon: func(ctx context.Context, opGeth *OpGeth) { // Adding this block advances us to the fork time. _, err := opGeth.AddL2Block(ctx) require.NoError(t, err) @@ -811,6 +810,7 @@ func TestCanyon(t *testing.T) { s := hexutil.Uint64(0) cfg.DeployConfig.L2GenesisRegolithTimeOffset = &s cfg.DeployConfig.L2GenesisCanyonTimeOffset = &test.canyonTime + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = nil ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -819,11 +819,11 @@ func TestCanyon(t *testing.T) { require.NoError(t, err) defer opGeth.Close() - test.activeCanyon(ctx, opGeth) + test.activateCanyon(ctx, opGeth) b, err := opGeth.AddL2Block(ctx) require.NoError(t, err) - assert.Equal(t, *b.Withdrawals, types.Withdrawals{}) + assert.Equal(t, *b.ExecutionPayload.Withdrawals, types.Withdrawals{}) l1Block, err := opGeth.L2Client.BlockByNumber(ctx, nil) require.Nil(t, err) @@ -834,6 +834,7 @@ func TestCanyon(t *testing.T) { InitParallel(t) cfg := DefaultSystemConfig(t) cfg.DeployConfig.L2GenesisCanyonTimeOffset = &test.canyonTime + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = nil ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -861,3 +862,155 @@ func TestCanyon(t *testing.T) { }) } } + +func TestPreEcotone(t *testing.T) { + futureTimestamp := hexutil.Uint64(4) + + tests := []struct { + name string + ecotoneTime *hexutil.Uint64 + }{ + {name: "EcotoneNotScheduled"}, + {name: "EcotoneNotYetActive", ecotoneTime: &futureTimestamp}, + } + for _, test := range tests { + test := test + + t.Run(fmt.Sprintf("NilParentBeaconRoot_%s", test.name), func(t *testing.T) { + InitParallel(t) + cfg := DefaultSystemConfig(t) + cfg.DeployConfig.L2GenesisCanyonTimeOffset = test.ecotoneTime + + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + opGeth, err := NewOpGeth(t, ctx, &cfg) + require.NoError(t, err) + defer opGeth.Close() + + b, err := opGeth.AddL2Block(ctx) + require.NoError(t, err) + assert.Nil(t, b.ParentBeaconBlockRoot) + + l2Block, err := opGeth.L2Client.BlockByNumber(ctx, nil) + require.NoError(t, err) + assert.Nil(t, l2Block.Header().ParentBeaconRoot) + }) + + t.Run(fmt.Sprintf("RejectTstoreTxn%s", test.name), func(t *testing.T) { + InitParallel(t) + cfg := DefaultSystemConfig(t) + cfg.DeployConfig.L2GenesisCanyonTimeOffset = test.ecotoneTime + + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + opGeth, err := NewOpGeth(t, ctx, &cfg) + require.NoError(t, err) + defer opGeth.Close() + + tstoreTxn := types.NewTx(&types.DepositTx{ + From: cfg.Secrets.Addresses().Alice, + Value: big.NewInt(params.Ether), + Gas: 1000001, + Data: []byte{ + byte(vm.PUSH1), + byte(vm.PUSH2), + byte(vm.TSTORE), + }, + IsSystemTransaction: false, + }) + + _, err = opGeth.AddL2Block(ctx, tstoreTxn) + require.NoError(t, err) + + receipt, err := opGeth.L2Client.TransactionReceipt(ctx, tstoreTxn.Hash()) + require.NoError(t, err) + assert.Equal(t, types.ReceiptStatusFailed, receipt.Status) + }) + } +} + +func TestEcotone(t *testing.T) { + tests := []struct { + name string + ecotoneTime hexutil.Uint64 + activateEcotone func(ctx context.Context, opGeth *OpGeth) + }{ + {name: "ActivateAtGenesis", ecotoneTime: 0, activateEcotone: func(ctx context.Context, opGeth *OpGeth) {}}, + {name: "ActivateAfterGenesis", ecotoneTime: 2, activateEcotone: func(ctx context.Context, opGeth *OpGeth) { + // Adding this block advances us to the fork time. + _, err := opGeth.AddL2Block(ctx) + require.NoError(t, err) + }}, + } + for _, test := range tests { + test := test + t.Run(fmt.Sprintf("HashParentBeaconBlockRoot_%s", test.name), func(t *testing.T) { + InitParallel(t) + cfg := DefaultSystemConfig(t) + s := hexutil.Uint64(0) + cfg.DeployConfig.L2GenesisCanyonTimeOffset = &s + cfg.DeployConfig.L2GenesisDeltaTimeOffset = &s + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &test.ecotoneTime + + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + opGeth, err := NewOpGeth(t, ctx, &cfg) + require.NoError(t, err) + defer opGeth.Close() + + test.activateEcotone(ctx, opGeth) + + b, err := opGeth.AddL2Block(ctx) + require.NoError(t, err) + require.NotNil(t, b.ParentBeaconBlockRoot) + assert.Equal(t, b.ParentBeaconBlockRoot, opGeth.L1Head.ParentBeaconRoot()) + + l2Block, err := opGeth.L2Client.BlockByNumber(ctx, nil) + require.NoError(t, err) + assert.NotNil(t, l2Block.Header().ParentBeaconRoot) + assert.Equal(t, l2Block.Header().ParentBeaconRoot, opGeth.L1Head.ParentBeaconRoot()) + }) + + t.Run(fmt.Sprintf("TstoreTxn%s", test.name), func(t *testing.T) { + InitParallel(t) + cfg := DefaultSystemConfig(t) + s := hexutil.Uint64(0) + cfg.DeployConfig.L2GenesisCanyonTimeOffset = &s + cfg.DeployConfig.L2GenesisDeltaTimeOffset = &s + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &test.ecotoneTime + + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + opGeth, err := NewOpGeth(t, ctx, &cfg) + require.NoError(t, err) + defer opGeth.Close() + + tstoreTxn := types.NewTx(&types.DepositTx{ + From: cfg.Secrets.Addresses().Alice, + Value: big.NewInt(params.Ether), + Gas: 1000001, + Data: []byte{ + byte(vm.PUSH1), 0x01, + byte(vm.PUSH1), 0x01, + byte(vm.TSTORE), + byte(vm.PUSH0), + }, + IsSystemTransaction: false, + }) + + _, err = opGeth.AddL2Block(ctx, tstoreTxn) + require.NoError(t, err) + + _, err = opGeth.AddL2Block(ctx, tstoreTxn) + require.NoError(t, err) + + receipt, err := opGeth.L2Client.TransactionReceipt(ctx, tstoreTxn.Hash()) + require.NoError(t, err) + assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) + }) + } +} diff --git a/op-e2e/sequencer_failover_setup.go b/op-e2e/sequencer_failover_setup.go new file mode 100644 index 000000000000..fbc3e1a9e7e8 --- /dev/null +++ b/op-e2e/sequencer_failover_setup.go @@ -0,0 +1,438 @@ +package op_e2e + +import ( + "context" + "fmt" + "math/rand" + "net" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/require" + + bss "github.com/ethereum-optimism/optimism/op-batcher/batcher" + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" + con "github.com/ethereum-optimism/optimism/op-conductor/conductor" + conrpc "github.com/ethereum-optimism/optimism/op-conductor/rpc" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + rollupNode "github.com/ethereum-optimism/optimism/op-node/node" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-node/rollup/driver" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/testlog" +) + +const ( + Sequencer1Name = "sequencer1" + Sequencer2Name = "sequencer2" + Sequencer3Name = "sequencer3" + VerifierName = "verifier" + + localhost = "127.0.0.1" +) + +type conductor struct { + service *con.OpConductor + client conrpc.API + consensusPort int + rpcPort int +} + +func (c *conductor) ConsensusEndpoint() string { + return fmt.Sprintf("%s:%d", localhost, c.consensusPort) +} + +func (c *conductor) RPCEndpoint() string { + return fmt.Sprintf("http://%s:%d", localhost, c.rpcPort) +} + +func setupSequencerFailoverTest(t *testing.T) (*System, map[string]*conductor) { + InitParallel(t) + ctx := context.Background() + + conductorRpcPorts := map[string]int{ + Sequencer1Name: findAvailablePort(t), + Sequencer2Name: findAvailablePort(t), + Sequencer3Name: findAvailablePort(t), + } + + // 3 sequencers, 1 verifier, 1 active sequencer. + cfg := sequencerFailoverSystemConfig(t, conductorRpcPorts) + sys, err := cfg.Start(t) + require.NoError(t, err) + + // 3 conductors that connects to 1 sequencer each. + conductors := make(map[string]*conductor) + + // initialize all conductors in paused mode + conductorCfgs := []struct { + name string + port int + bootstrap bool + }{ + {Sequencer1Name, conductorRpcPorts[Sequencer1Name], true}, // one in bootstrap mode so that we can form a cluster. + {Sequencer2Name, conductorRpcPorts[Sequencer2Name], false}, + {Sequencer3Name, conductorRpcPorts[Sequencer3Name], false}, + } + for _, cfg := range conductorCfgs { + cfg := cfg + nodePRC := sys.RollupNodes[cfg.name].HTTPEndpoint() + engineRPC := sys.EthInstances[cfg.name].HTTPEndpoint() + conductors[cfg.name] = setupConductor(t, cfg.name, t.TempDir(), nodePRC, engineRPC, cfg.port, cfg.bootstrap, *sys.RollupConfig) + } + + // form a cluster + c1 := conductors[Sequencer1Name] + c2 := conductors[Sequencer2Name] + c3 := conductors[Sequencer3Name] + + require.NoError(t, waitForLeadership(t, c1)) + require.NoError(t, c1.client.AddServerAsVoter(ctx, Sequencer2Name, c2.ConsensusEndpoint())) + require.NoError(t, c1.client.AddServerAsVoter(ctx, Sequencer3Name, c3.ConsensusEndpoint())) + require.True(t, leader(t, ctx, c1)) + require.False(t, leader(t, ctx, c2)) + require.False(t, leader(t, ctx, c3)) + + // start sequencing on leader + lid, _ := findLeader(t, conductors) + unsafeHead, err := sys.Clients[lid].BlockByNumber(ctx, nil) + require.NoError(t, err) + require.Equal(t, uint64(0), unsafeHead.NumberU64()) + require.NoError(t, sys.RollupClient(lid).StartSequencer(ctx, unsafeHead.Hash())) + + // 1 batcher that listens to all 3 sequencers, in started mode. + setupBatcher(t, sys, conductors) + + // weirdly, batcher does not submit a batch until unsafe block 9. + // It became normal after that and submits a batch every L1 block (2s) per configuration. + // Since our health monitor checks on safe head progression, wait for batcher to become normal before proceeding. + _, err = wait.ForNextSafeBlock(ctx, sys.Clients[Sequencer1Name]) + require.NoError(t, err) + _, err = wait.ForNextSafeBlock(ctx, sys.Clients[Sequencer1Name]) + require.NoError(t, err) + + // make sure conductor reports all sequencers as healthy, this means they're syncing correctly. + require.Eventually(t, func() bool { + return healthy(t, ctx, c1) && + healthy(t, ctx, c2) && + healthy(t, ctx, c3) + }, 30*time.Second, 500*time.Millisecond, "Expected sequencers to become healthy") + + // unpause all conductors + require.NoError(t, c1.client.Resume(ctx)) + require.NoError(t, c2.client.Resume(ctx)) + require.NoError(t, c3.client.Resume(ctx)) + + // final check, make sure everything is in the right place + require.True(t, conductorActive(t, ctx, c1)) + require.True(t, conductorActive(t, ctx, c2)) + require.True(t, conductorActive(t, ctx, c3)) + + require.True(t, sequencerActive(t, ctx, sys.RollupClient(Sequencer1Name))) + require.False(t, sequencerActive(t, ctx, sys.RollupClient(Sequencer2Name))) + require.False(t, sequencerActive(t, ctx, sys.RollupClient(Sequencer3Name))) + + require.True(t, healthy(t, ctx, c1)) + require.True(t, healthy(t, ctx, c2)) + require.True(t, healthy(t, ctx, c3)) + + return sys, conductors +} + +func setupConductor( + t *testing.T, + serverID, dir, nodeRPC, engineRPC string, + rpcPort int, + bootstrap bool, + rollupCfg rollup.Config, +) *conductor { + // it's unfortunate that it is not possible to pass 0 as consensus port and get back the actual assigned port from raft implementation. + // So we find an available port and pass it in to avoid test flakiness (avoid port already in use error). + consensusPort := findAvailablePort(t) + cfg := con.Config{ + ConsensusAddr: localhost, + ConsensusPort: consensusPort, + RaftServerID: serverID, + RaftStorageDir: dir, + RaftBootstrap: bootstrap, + NodeRPC: nodeRPC, + ExecutionRPC: engineRPC, + Paused: true, + HealthCheck: con.HealthCheckConfig{ + Interval: 1, // per test setup, l2 block time is 1s. + MinPeerCount: 2, // per test setup, each sequencer has 2 peers + // CI is unstable in terms of the delay between now and the head time + // so we set the unsafe interval to 30s to avoid flakiness. + // This is fine because there's a progression check within health monitor to check progression. + UnsafeInterval: 30, + SafeInterval: 30, + }, + RollupCfg: rollupCfg, + RPCEnableProxy: true, + LogConfig: oplog.CLIConfig{ + Level: log.LevelInfo, + Color: false, + }, + RPC: oprpc.CLIConfig{ + ListenAddr: localhost, + ListenPort: rpcPort, + }, + } + + ctx := context.Background() + service, err := con.New(ctx, &cfg, testlog.Logger(t, log.LevelInfo), "0.0.1") + require.NoError(t, err) + err = service.Start(ctx) + require.NoError(t, err) + + rawClient, err := rpc.DialContext(ctx, service.HTTPEndpoint()) + require.NoError(t, err) + client := conrpc.NewAPIClient(rawClient) + + return &conductor{ + service: service, + client: client, + consensusPort: consensusPort, + rpcPort: rpcPort, + } +} + +func setupBatcher(t *testing.T, sys *System, conductors map[string]*conductor) { + // enable active sequencer follow mode. + // in sequencer HA, all batcher / proposer requests will be proxied by conductor so that we can make sure + // that requests are always handled by leader. + l2EthRpc := strings.Join([]string{ + conductors[Sequencer1Name].RPCEndpoint(), + conductors[Sequencer2Name].RPCEndpoint(), + conductors[Sequencer3Name].RPCEndpoint(), + }, ",") + rollupRpc := strings.Join([]string{ + conductors[Sequencer1Name].RPCEndpoint(), + conductors[Sequencer2Name].RPCEndpoint(), + conductors[Sequencer3Name].RPCEndpoint(), + }, ",") + batcherCLIConfig := &bss.CLIConfig{ + L1EthRpc: sys.EthInstances["l1"].WSEndpoint(), + L2EthRpc: l2EthRpc, + RollupRpc: rollupRpc, + MaxPendingTransactions: 0, + MaxChannelDuration: 1, + MaxL1TxSize: 120_000, + TargetNumFrames: 1, + ApproxComprRatio: 0.4, + SubSafetyMargin: 4, + PollInterval: 1 * time.Second, + TxMgrConfig: newTxMgrConfig(sys.EthInstances["l1"].WSEndpoint(), sys.Cfg.Secrets.Batcher), + LogConfig: oplog.CLIConfig{ + Level: log.LevelDebug, + Format: oplog.FormatText, + }, + Stopped: false, + BatchType: derive.SpanBatchType, + DataAvailabilityType: batcherFlags.CalldataType, + ActiveSequencerCheckDuration: 0, + } + + batcher, err := bss.BatcherServiceFromCLIConfig(context.Background(), "0.0.1", batcherCLIConfig, sys.Cfg.Loggers["batcher"]) + require.NoError(t, err) + err = batcher.Start(context.Background()) + require.NoError(t, err) + sys.BatchSubmitter = batcher +} + +func sequencerFailoverSystemConfig(t *testing.T, ports map[string]int) SystemConfig { + cfg := DefaultSystemConfig(t) + delete(cfg.Nodes, "sequencer") + cfg.Nodes[Sequencer1Name] = sequencerCfg(ports[Sequencer1Name]) + cfg.Nodes[Sequencer2Name] = sequencerCfg(ports[Sequencer2Name]) + cfg.Nodes[Sequencer3Name] = sequencerCfg(ports[Sequencer3Name]) + + delete(cfg.Loggers, "sequencer") + cfg.Loggers[Sequencer1Name] = testlog.Logger(t, log.LevelInfo).New("role", Sequencer1Name) + cfg.Loggers[Sequencer2Name] = testlog.Logger(t, log.LevelInfo).New("role", Sequencer2Name) + cfg.Loggers[Sequencer3Name] = testlog.Logger(t, log.LevelInfo).New("role", Sequencer3Name) + + cfg.P2PTopology = map[string][]string{ + Sequencer1Name: {Sequencer2Name, Sequencer3Name}, + Sequencer2Name: {Sequencer3Name, VerifierName}, + Sequencer3Name: {VerifierName, Sequencer1Name}, + VerifierName: {Sequencer1Name, Sequencer2Name}, + } + offset := hexutil.Uint64(0) + cfg.DeployConfig.L2GenesisDeltaTimeOffset = &offset + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &offset + + return cfg +} + +func sequencerCfg(rpcPort int) *rollupNode.Config { + return &rollupNode.Config{ + Driver: driver.Config{ + VerifierConfDepth: 0, + SequencerConfDepth: 0, + SequencerEnabled: true, + SequencerStopped: true, + }, + // Submitter PrivKey is set in system start for rollup nodes where sequencer = true + RPC: rollupNode.RPCConfig{ + ListenAddr: localhost, + ListenPort: 0, + EnableAdmin: true, + }, + L1EpochPollInterval: time.Second * 2, + RuntimeConfigReloadInterval: time.Minute * 10, + ConfigPersistence: &rollupNode.DisabledConfigPersistence{}, + Sync: sync.Config{SyncMode: sync.CLSync}, + ConductorEnabled: true, + ConductorRpc: fmt.Sprintf("http://%s:%d", localhost, rpcPort), + ConductorRpcTimeout: 1 * time.Second, + } +} + +func waitForLeadership(t *testing.T, c *conductor) error { + condition := func() (bool, error) { + isLeader, err := c.client.Leader(context.Background()) + if err != nil { + return false, err + } + return isLeader, nil + } + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + return wait.For(ctx, 1*time.Second, condition) +} + +func waitForLeadershipChange(t *testing.T, prev *conductor, prevID string, conductors map[string]*conductor, sys *System) string { + condition := func() (bool, error) { + isLeader, err := prev.client.Leader(context.Background()) + if err != nil { + return false, err + } + return !isLeader, nil + } + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + err := wait.For(ctx, 1*time.Second, condition) + require.NoError(t, err) + + ensureOnlyOneLeader(t, sys, conductors) + newLeader, err := prev.client.LeaderWithID(ctx) + require.NoError(t, err) + require.NotEmpty(t, newLeader.ID) + require.NotEqual(t, prevID, newLeader.ID, "Expected a new leader") + require.NoError(t, waitForSequencerStatusChange(t, sys.RollupClient(newLeader.ID), true)) + + return newLeader.ID +} + +func waitForSequencerStatusChange(t *testing.T, rollupClient *sources.RollupClient, active bool) error { + condition := func() (bool, error) { + isActive, err := rollupClient.SequencerActive(context.Background()) + if err != nil { + return false, err + } + return isActive == active, nil + } + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + return wait.For(ctx, 1*time.Second, condition) +} + +func leader(t *testing.T, ctx context.Context, con *conductor) bool { + leader, err := con.client.Leader(ctx) + require.NoError(t, err) + return leader +} + +func healthy(t *testing.T, ctx context.Context, con *conductor) bool { + healthy, err := con.client.SequencerHealthy(ctx) + require.NoError(t, err) + return healthy +} + +func conductorActive(t *testing.T, ctx context.Context, con *conductor) bool { + active, err := con.client.Active(ctx) + require.NoError(t, err) + return active +} + +func sequencerActive(t *testing.T, ctx context.Context, rollupClient *sources.RollupClient) bool { + active, err := rollupClient.SequencerActive(ctx) + require.NoError(t, err) + return active +} + +func findAvailablePort(t *testing.T) int { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + for { + select { + case <-ctx.Done(): + t.Error("Failed to find available port") + default: + // private / ephemeral ports are in the range 49152-65535 + port := rand.Intn(65535-49152) + 49152 + addr := fmt.Sprintf("127.0.0.1:%d", port) + l, err := net.Listen("tcp", addr) + if err == nil { + l.Close() // Close the listener and return the port if it's available + return port + } + } + } +} + +func findLeader(t *testing.T, conductors map[string]*conductor) (string, *conductor) { + for id, con := range conductors { + if leader(t, context.Background(), con) { + return id, con + } + } + return "", nil +} + +func findFollower(t *testing.T, conductors map[string]*conductor) (string, *conductor) { + for id, con := range conductors { + if !leader(t, context.Background(), con) { + return id, con + } + } + return "", nil +} + +func ensureOnlyOneLeader(t *testing.T, sys *System, conductors map[string]*conductor) { + condition := func() (bool, error) { + leaders := 0 + ctx := context.Background() + for name, con := range conductors { + leader, err := con.client.Leader(ctx) + if err != nil { + continue + } + active, err := sys.RollupClient(name).SequencerActive(ctx) + if err != nil { + continue + } + + if leader && active { + leaders++ + } + } + return leaders == 1, nil + } + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + require.NoError(t, wait.For(ctx, 1*time.Second, condition)) +} diff --git a/op-e2e/sequencer_failover_test.go b/op-e2e/sequencer_failover_test.go new file mode 100644 index 000000000000..a07266e533dc --- /dev/null +++ b/op-e2e/sequencer_failover_test.go @@ -0,0 +1,166 @@ +package op_e2e + +import ( + "context" + "sort" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/op-conductor/consensus" +) + +// [Category: Initial Setup] +// In this test, we test that we can successfully setup a working cluster. +func TestSequencerFailover_SetupCluster(t *testing.T) { + sys, conductors := setupSequencerFailoverTest(t) + defer sys.Close() + + require.Equal(t, 3, len(conductors), "Expected 3 conductors") + for _, con := range conductors { + require.NotNil(t, con, "Expected conductor to be non-nil") + } +} + +// [Category: conductor rpc] +// In this test, we test all rpcs exposed by conductor. +func TestSequencerFailover_ConductorRPC(t *testing.T) { + ctx := context.Background() + sys, conductors := setupSequencerFailoverTest(t) + defer sys.Close() + + // SequencerHealthy, Leader, AddServerAsVoter are used in setup already. + + // Test ClusterMembership + t.Log("Testing ClusterMembership") + c1 := conductors[Sequencer1Name] + c2 := conductors[Sequencer2Name] + c3 := conductors[Sequencer3Name] + membership, err := c1.client.ClusterMembership(ctx) + require.NoError(t, err) + require.Equal(t, 3, len(membership), "Expected 3 members in cluster") + ids := make([]string, 0) + for _, member := range membership { + ids = append(ids, member.ID) + require.Equal(t, consensus.Voter, member.Suffrage, "Expected all members to be voters") + } + sort.Strings(ids) + require.Equal(t, []string{Sequencer1Name, Sequencer2Name, Sequencer3Name}, ids, "Expected all sequencers to be in cluster") + + // Test Active & Pause & Resume + t.Log("Testing Active & Pause & Resume") + active, err := c1.client.Active(ctx) + require.NoError(t, err) + require.True(t, active, "Expected conductor to be active") + + err = c1.client.Pause(ctx) + require.NoError(t, err) + active, err = c1.client.Active(ctx) + require.NoError(t, err) + require.False(t, active, "Expected conductor to be paused") + + err = c1.client.Resume(ctx) + require.NoError(t, err) + active, err = c1.client.Active(ctx) + require.NoError(t, err) + require.True(t, active, "Expected conductor to be active") + + t.Log("Testing LeaderWithID") + leader1, err := c1.client.LeaderWithID(ctx) + require.NoError(t, err) + leader2, err := c2.client.LeaderWithID(ctx) + require.NoError(t, err) + leader3, err := c3.client.LeaderWithID(ctx) + require.NoError(t, err) + require.Equal(t, leader1.ID, leader2.ID, "Expected leader ID to be the same") + require.Equal(t, leader1.ID, leader3.ID, "Expected leader ID to be the same") + + t.Log("Testing TransferLeader") + lid, leader := findLeader(t, conductors) + err = leader.client.TransferLeader(ctx) + require.NoError(t, err, "Expected leader to transfer leadership to another node") + _ = waitForLeadershipChange(t, leader, lid, conductors, sys) + + // old leader now became follower, we're trying to transfer leadership directly back to it. + t.Log("Testing TransferLeaderToServer") + fid, follower := lid, leader + lid, leader = findLeader(t, conductors) + err = leader.client.TransferLeaderToServer(ctx, fid, follower.ConsensusEndpoint()) + require.NoError(t, err, "Expected leader to transfer leadership to follower") + newID := waitForLeadershipChange(t, leader, lid, conductors, sys) + require.Equal(t, fid, newID, "Expected leader to transfer to %s", fid) + + leader = follower + + // Test AddServerAsNonvoter, do not start a new sequencer just for this purpose, use Sequencer3's rpc to start conductor. + // This is fine as this mainly tests conductor's ability to add itself into the raft consensus cluster as a nonvoter. + t.Log("Testing AddServerAsNonvoter") + nonvoter := setupConductor( + t, VerifierName, t.TempDir(), + sys.RollupEndpoint(Sequencer3Name), + sys.NodeEndpoint(Sequencer3Name), + findAvailablePort(t), + false, + *sys.RollupConfig, + ) + + err = leader.client.AddServerAsNonvoter(ctx, VerifierName, nonvoter.ConsensusEndpoint()) + require.NoError(t, err, "Expected leader to add non-voter") + membership, err = leader.client.ClusterMembership(ctx) + require.NoError(t, err) + require.Equal(t, 4, len(membership), "Expected 4 members in cluster") + require.Equal(t, consensus.Nonvoter, membership[3].Suffrage, "Expected last member to be non-voter") + + t.Log("Testing RemoveServer, call remove on follower, expected to fail") + lid, leader = findLeader(t, conductors) + fid, follower = findFollower(t, conductors) + err = follower.client.RemoveServer(ctx, lid) + require.ErrorContains(t, err, "node is not the leader", "Expected follower to fail to remove leader") + membership, err = c1.client.ClusterMembership(ctx) + require.NoError(t, err) + require.Equal(t, 4, len(membership), "Expected 4 members in cluster") + + t.Log("Testing RemoveServer, call remove on leader, expect non-voter to be removed") + err = leader.client.RemoveServer(ctx, VerifierName) + require.NoError(t, err, "Expected leader to remove non-voter") + membership, err = c1.client.ClusterMembership(ctx) + require.NoError(t, err) + require.Equal(t, 3, len(membership), "Expected 2 members in cluster after removal") + require.NotContains(t, membership, VerifierName, "Expected follower to be removed from cluster") + + t.Log("Testing RemoveServer, call remove on leader, expect voter to be removed") + err = leader.client.RemoveServer(ctx, fid) + require.NoError(t, err, "Expected leader to remove follower") + membership, err = c1.client.ClusterMembership(ctx) + require.NoError(t, err) + require.Equal(t, 2, len(membership), "Expected 2 members in cluster after removal") + require.NotContains(t, membership, fid, "Expected follower to be removed from cluster") +} + +// [Category: Sequencer Failover] +// Test that the sequencer can successfully failover to a new sequencer once the active sequencer goes down. +func TestSequencerFailover_ActiveSequencerDown(t *testing.T) { + sys, conductors := setupSequencerFailoverTest(t) + defer sys.Close() + + ctx := context.Background() + leaderId, leader := findLeader(t, conductors) + err := sys.RollupNodes[leaderId].Stop(ctx) // Stop the current leader sequencer + require.NoError(t, err) + + // The leadership change should occur with no errors + newID := waitForLeadershipChange(t, leader, leaderId, conductors, sys) + require.NotEqual(t, leaderId, newID, "Expected leader to change") + + // Confirm the new leader is different from the old leader + newLeaderId, _ := findLeader(t, conductors) + require.NotEqual(t, leaderId, newLeaderId, "Expected leader to change") + + // Check that the sequencer is healthy + require.True(t, healthy(t, ctx, conductors[newLeaderId])) + + // Check if the new leader is sequencing + active, err := sys.RollupClient(newLeaderId).SequencerActive(ctx) + require.NoError(t, err) + require.True(t, active, "Expected new leader to be sequencing") +} diff --git a/op-e2e/setup.go b/op-e2e/setup.go index dc6b0e2e9627..6715a385b486 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -12,11 +12,13 @@ import ( "path" "sort" "strings" + "sync/atomic" "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/batcher" ds "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/sync" + dsSync "github.com/ipfs/go-datastore/sync" ic "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" @@ -37,11 +39,12 @@ import ( "github.com/ethereum/go-ethereum/rpc" bss "github.com/ethereum-optimism/optimism/op-batcher/batcher" - "github.com/ethereum-optimism/optimism/op-batcher/compressor" + batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-e2e/config" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/fakebeacon" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-node/metrics" @@ -51,10 +54,12 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/driver" - proposermetrics "github.com/ethereum-optimism/optimism/op-proposer/metrics" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" l2os "github.com/ethereum-optimism/optimism/op-proposer/proposer" "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/ethereum-optimism/optimism/op-service/dial" "github.com/ethereum-optimism/optimism/op-service/eth" oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/sources" @@ -62,9 +67,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/txmgr" ) -var ( - testingJWTSecret = [32]byte{123} -) +var testingJWTSecret = [32]byte{123} func newTxMgrConfig(l1Addr string, privKey *ecdsa.PrivateKey) txmgr.CLIConfig { return txmgr.CLIConfig{ @@ -87,11 +90,10 @@ func DefaultSystemConfig(t *testing.T) SystemConfig { require.NoError(t, err) deployConfig := config.DeployConfig.Copy() deployConfig.L1GenesisBlockTimestamp = hexutil.Uint64(time.Now().Unix()) - deployConfig.L2GenesisCanyonTimeOffset = e2eutils.CanyonTimeOffset() - deployConfig.L2GenesisSpanBatchTimeOffset = e2eutils.SpanBatchTimeOffset() + e2eutils.ApplyDeployConfigForks(deployConfig) require.NoError(t, deployConfig.Check(), "Deploy config is invalid, do you need to run make devnet-allocs?") l1Deployments := config.L1Deployments.Copy() - require.NoError(t, l1Deployments.Check()) + require.NoError(t, l1Deployments.Check(deployConfig)) require.Equal(t, secrets.Addresses().Batcher, deployConfig.BatchSenderAddress) require.Equal(t, secrets.Addresses().SequencerP2P, deployConfig.P2PSequencerAddress) @@ -111,6 +113,7 @@ func DefaultSystemConfig(t *testing.T) SystemConfig { L1InfoPredeployAddress: predeploys.L1BlockAddr, JWTFilePath: writeDefaultJWT(t), JWTSecret: testingJWTSecret, + BlobsPath: t.TempDir(), Nodes: map[string]*rollupNode.Config{ "sequencer": { Driver: driver.Config{ @@ -127,6 +130,7 @@ func DefaultSystemConfig(t *testing.T) SystemConfig { L1EpochPollInterval: time.Second * 2, RuntimeConfigReloadInterval: time.Minute * 10, ConfigPersistence: &rollupNode.DisabledConfigPersistence{}, + Sync: sync.Config{SyncMode: sync.CLSync}, }, "verifier": { Driver: driver.Config{ @@ -137,19 +141,22 @@ func DefaultSystemConfig(t *testing.T) SystemConfig { L1EpochPollInterval: time.Second * 4, RuntimeConfigReloadInterval: time.Minute * 10, ConfigPersistence: &rollupNode.DisabledConfigPersistence{}, + Sync: sync.Config{SyncMode: sync.CLSync}, }, }, Loggers: map[string]log.Logger{ - "verifier": testlog.Logger(t, log.LvlInfo).New("role", "verifier"), - "sequencer": testlog.Logger(t, log.LvlInfo).New("role", "sequencer"), - "batcher": testlog.Logger(t, log.LvlInfo).New("role", "batcher"), - "proposer": testlog.Logger(t, log.LvlCrit).New("role", "proposer"), + "verifier": testlog.Logger(t, log.LevelInfo).New("role", "verifier"), + "sequencer": testlog.Logger(t, log.LevelInfo).New("role", "sequencer"), + "batcher": testlog.Logger(t, log.LevelInfo).New("role", "batcher"), + "proposer": testlog.Logger(t, log.LevelCrit).New("role", "proposer"), }, - GethOptions: map[string][]geth.GethOption{}, - P2PTopology: nil, // no P2P connectivity by default - NonFinalizedProposals: false, - ExternalL2Shim: config.ExternalL2Shim, - BatcherTargetL1TxSizeBytes: 100_000, + GethOptions: map[string][]geth.GethOption{}, + P2PTopology: nil, // no P2P connectivity by default + NonFinalizedProposals: false, + ExternalL2Shim: config.ExternalL2Shim, + DataAvailabilityType: batcherFlags.CalldataType, + MaxPendingTransactions: 1, + BatcherTargetNumFrames: 1, } } @@ -177,6 +184,8 @@ type SystemConfig struct { JWTFilePath string JWTSecret [32]byte + BlobsPath string + Premine map[common.Address]*big.Int Nodes map[string]*rollupNode.Config // Per node config. Don't use populate rollup.Config Loggers map[string]log.Logger @@ -200,11 +209,26 @@ type SystemConfig struct { // Explicitly disable batcher, for tests that rely on unsafe L2 payloads DisableBatcher bool - // Target L1 tx size for the batcher transactions - BatcherTargetL1TxSizeBytes uint64 + // Configure data-availability type that is used by the batcher. + DataAvailabilityType batcherFlags.DataAvailabilityType + + // Max L1 tx size for the batcher transactions + BatcherMaxL1TxSizeBytes uint64 + + // Target number of frames to create per channel. Can be used to create + // multi-blob transactions. + // Default is 1 if unset. + BatcherTargetNumFrames int + + // whether to actually use BatcherMaxL1TxSizeBytes for blobs, insteaf of max blob size + BatcherUseMaxTxSizeForBlobs bool // SupportL1TimeTravel determines if the L1 node supports quickly skipping forward in time SupportL1TimeTravel bool + + // MaxPendingTransactions determines how many transactions the batcher will try to send + // concurrently. 0 means unlimited. + MaxPendingTransactions uint64 } type GethInstance struct { @@ -243,7 +267,7 @@ type EthInstance interface { } type System struct { - cfg SystemConfig + Cfg SystemConfig RollupConfig *rollup.Config @@ -254,40 +278,124 @@ type System struct { Clients map[string]*ethclient.Client RawClients map[string]*rpc.Client RollupNodes map[string]*rollupNode.OpNode - L2OutputSubmitter *l2os.L2OutputSubmitter + L2OutputSubmitter *l2os.ProposerService BatchSubmitter *bss.BatcherService Mocknet mocknet.Mocknet + L1BeaconAPIAddr string + // TimeTravelClock is nil unless SystemConfig.SupportL1TimeTravel was set to true // It provides access to the clock instance used by the L1 node. Calling TimeTravelClock.AdvanceBy // allows tests to quickly time travel L1 into the future. // Note that this time travel may occur in a single block, creating a very large difference in the Time // on sequential blocks. TimeTravelClock *clock.AdvancingClock + + t *testing.T + closed atomic.Bool + + // rollupClients caches the lazily created RollupClient instances so they can be reused and closed + rollupClients map[string]*sources.RollupClient +} + +// AdvanceTime advances the system clock by the given duration. +// If the [System.TimeTravelClock] is nil, this is a no-op. +func (sys *System) AdvanceTime(d time.Duration) { + if sys.TimeTravelClock != nil { + sys.TimeTravelClock.AdvanceTime(d) + } +} + +func (sys *System) L1BeaconEndpoint() string { + return sys.L1BeaconAPIAddr +} + +func (sys *System) L1BeaconHTTPClient() *sources.BeaconHTTPClient { + logger := testlog.Logger(sys.t, log.LevelInfo).New("component", "beaconClient") + return sources.NewBeaconHTTPClient(client.NewBasicHTTPClient(sys.L1BeaconEndpoint(), logger)) } func (sys *System) NodeEndpoint(name string) string { return selectEndpoint(sys.EthInstances[name]) } +func (sys *System) NodeClient(name string) *ethclient.Client { + return sys.Clients[name] +} + +func (sys *System) RollupEndpoint(name string) string { + return sys.RollupNodes[name].HTTPEndpoint() +} + +func (sys *System) RollupClient(name string) *sources.RollupClient { + client, ok := sys.rollupClients[name] + if ok { + return client + } + logger := testlog.Logger(sys.t, log.LevelInfo).New("rollupClient", name) + endpoint := sys.RollupEndpoint(name) + client, err := dial.DialRollupClientWithTimeout(context.Background(), 30*time.Second, logger, endpoint) + require.NoErrorf(sys.t, err, "Failed to dial rollup client %v", name) + sys.rollupClients[name] = client + return client +} + +func (sys *System) L1Deployments() *genesis.L1Deployments { + return sys.Cfg.L1Deployments +} + +func (sys *System) RollupCfg() *rollup.Config { + return sys.RollupConfig +} + +func (sys *System) L2Genesis() *core.Genesis { + return sys.L2GenesisCfg +} + +func (sys *System) L1Slot(l1Timestamp uint64) uint64 { + return (l1Timestamp - uint64(sys.Cfg.DeployConfig.L1GenesisBlockTimestamp)) / + sys.Cfg.DeployConfig.L1BlockTime +} + func (sys *System) Close() { + if !sys.closed.CompareAndSwap(false, true) { + // Already closed. + return + } postCtx, postCancel := context.WithCancel(context.Background()) postCancel() // immediate shutdown, no allowance for idling + var combinedErr error if sys.L2OutputSubmitter != nil { - sys.L2OutputSubmitter.Stop() + if err := sys.L2OutputSubmitter.Kill(); err != nil && !errors.Is(err, l2os.ErrAlreadyStopped) { + combinedErr = errors.Join(combinedErr, fmt.Errorf("stop L2OutputSubmitter: %w", err)) + } } if sys.BatchSubmitter != nil { - _ = sys.BatchSubmitter.Kill() + if err := sys.BatchSubmitter.Kill(); err != nil && !errors.Is(err, bss.ErrAlreadyStopped) { + combinedErr = errors.Join(combinedErr, fmt.Errorf("stop BatchSubmitter: %w", err)) + } } - for _, node := range sys.RollupNodes { - _ = node.Stop(postCtx) + for name, node := range sys.RollupNodes { + if err := node.Stop(postCtx); err != nil && !errors.Is(err, rollupNode.ErrAlreadyClosed) { + combinedErr = errors.Join(combinedErr, fmt.Errorf("stop rollup node %v: %w", name, err)) + } + } + for name, ei := range sys.EthInstances { + if err := ei.Close(); err != nil && !errors.Is(err, node.ErrNodeStopped) { + combinedErr = errors.Join(combinedErr, fmt.Errorf("stop EthInstance %v: %w", name, err)) + } } - for _, ei := range sys.EthInstances { - ei.Close() + for _, client := range sys.rollupClients { + client.Close() } - sys.Mocknet.Close() + if sys.Mocknet != nil { + if err := sys.Mocknet.Close(); err != nil { + combinedErr = errors.Join(combinedErr, fmt.Errorf("stop Mocknet: %w", err)) + } + } + require.NoError(sys.t, combinedErr, "Failed to stop system") } type systemConfigHook func(sCfg *SystemConfig, s *System) @@ -328,25 +436,16 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste } sys := &System{ - cfg: cfg, - EthInstances: make(map[string]EthInstance), - Clients: make(map[string]*ethclient.Client), - RawClients: make(map[string]*rpc.Client), - RollupNodes: make(map[string]*rollupNode.OpNode), - } - didErrAfterStart := false - defer func() { - if didErrAfterStart { - postCtx, postCancel := context.WithCancel(context.Background()) - postCancel() // immediate shutdown, no allowance for idling - for _, node := range sys.RollupNodes { - _ = node.Stop(postCtx) - } - for _, ei := range sys.EthInstances { - ei.Close() - } - } - }() + t: t, + Cfg: cfg, + EthInstances: make(map[string]EthInstance), + Clients: make(map[string]*ethclient.Client), + RawClients: make(map[string]*rpc.Client), + RollupNodes: make(map[string]*rollupNode.OpNode), + rollupClients: make(map[string]*sources.RollupClient), + } + // Automatically stop the system at the end of the test + t.Cleanup(sys.Close) c := clock.SystemClock if cfg.SupportL1TimeTravel { @@ -358,7 +457,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste return nil, err } - l1Genesis, err := genesis.BuildL1DeveloperGenesis(cfg.DeployConfig, config.L1Allocs, config.L1Deployments, true) + l1Genesis, err := genesis.BuildL1DeveloperGenesis(cfg.DeployConfig, config.L1Allocs, config.L1Deployments) if err != nil { return nil, err } @@ -426,7 +525,10 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste L1SystemConfigAddress: cfg.DeployConfig.SystemConfigProxy, RegolithTime: cfg.DeployConfig.RegolithTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)), CanyonTime: cfg.DeployConfig.CanyonTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)), - SpanBatchTime: cfg.DeployConfig.SpanBatchTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)), + DeltaTime: cfg.DeployConfig.DeltaTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)), + EcotoneTime: cfg.DeployConfig.EcotoneTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)), + FjordTime: cfg.DeployConfig.FjordTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)), + InteropTime: cfg.DeployConfig.InteropTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)), ProtocolVersionsAddress: cfg.L1Deployments.ProtocolVersionsProxy, } } @@ -436,8 +538,20 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste } sys.RollupConfig = &defaultConfig + // Create a fake Beacon node to hold on to blobs created by the L1 miner, and to serve them to L2 + bcn := fakebeacon.NewBeacon(testlog.Logger(t, log.LevelInfo).New("role", "l1_cl"), + path.Join(cfg.BlobsPath, "l1_cl"), l1Genesis.Timestamp, cfg.DeployConfig.L1BlockTime) + t.Cleanup(func() { + _ = bcn.Close() + }) + require.NoError(t, bcn.Start("127.0.0.1:0")) + beaconApiAddr := bcn.BeaconAddr() + require.NotEmpty(t, beaconApiAddr, "beacon API listener must be up") + sys.L1BeaconAPIAddr = beaconApiAddr + // Initialize nodes - l1Node, l1Backend, err := geth.InitL1(cfg.DeployConfig.L1ChainID, cfg.DeployConfig.L1BlockTime, l1Genesis, c, cfg.GethOptions["l1"]...) + l1Node, l1Backend, err := geth.InitL1(cfg.DeployConfig.L1ChainID, cfg.DeployConfig.L1BlockTime, l1Genesis, c, + path.Join(cfg.BlobsPath, "l1_el"), bcn, cfg.GethOptions["l1"]...) if err != nil { return nil, err } @@ -447,7 +561,6 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste } err = l1Node.Start() if err != nil { - didErrAfterStart = true return nil, err } @@ -464,7 +577,6 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste } err = gethInst.Node.Start() if err != nil { - didErrAfterStart = true return nil, err } ethClient = gethInst @@ -485,13 +597,11 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste // Configure connections to L1 and L2 for rollup nodes. // TODO: refactor testing to allow use of in-process rpc connections instead // of only websockets (which are required for external eth client tests). - for name, rollupCfg := range cfg.Nodes { - configureL1(rollupCfg, sys.EthInstances["l1"]) - configureL2(rollupCfg, sys.EthInstances[name], cfg.JWTSecret) - - rollupCfg.L2Sync = &rollupNode.PreparedL2SyncEndpoint{ - Client: nil, - TrustRPC: false, + for name, nodeCfg := range cfg.Nodes { + configureL1(nodeCfg, sys.EthInstances["l1"]) + configureL2(nodeCfg, sys.EthInstances[name], cfg.JWTSecret) + if sys.RollupConfig.EcotoneTime != nil { + nodeCfg.Beacon = &rollupNode.L1BeaconEndpointConfig{BeaconAddr: sys.L1BeaconAPIAddr} } } @@ -500,7 +610,6 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste defer cancel() l1Srv, err := l1Node.RPCHandler() if err != nil { - didErrAfterStart = true return nil, err } rawL1Client := rpc.DialInProc(l1Srv) @@ -510,7 +619,6 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste for name, ethInst := range sys.EthInstances { rawClient, err := rpc.DialContext(ctx, ethInst.WSEndpoint()) if err != nil { - didErrAfterStart = true return nil, err } client := ethclient.NewClient(rawClient) @@ -572,8 +680,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste } // Don't log state snapshots in test output - snapLog := log.New() - snapLog.SetHandler(log.DiscardHandler()) + snapLog := log.NewLogger(log.DiscardHandler()) // Rollup nodes @@ -617,13 +724,11 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste } node, err := rollupNode.New(context.Background(), &c, l, snapLog, "", metrics.NewMetrics("")) if err != nil { - didErrAfterStart = true return nil, err } cycle = node err = node.Start(context.Background()) if err != nil { - didErrAfterStart = true return nil, err } sys.RollupNodes[name] = node @@ -660,54 +765,81 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste } // L2Output Submitter - sys.L2OutputSubmitter, err = l2os.NewL2OutputSubmitterFromCLIConfig(l2os.CLIConfig{ - L1EthRpc: sys.EthInstances["l1"].WSEndpoint(), - RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(), - L2OOAddress: config.L1Deployments.L2OutputOracleProxy.Hex(), - PollInterval: 50 * time.Millisecond, - TxMgrConfig: newTxMgrConfig(sys.EthInstances["l1"].WSEndpoint(), cfg.Secrets.Proposer), - AllowNonFinalized: cfg.NonFinalizedProposals, - LogConfig: oplog.CLIConfig{ - Level: log.LvlInfo, - Format: oplog.FormatText, - }, - }, sys.cfg.Loggers["proposer"], proposermetrics.NoopMetrics) + var proposerCLIConfig *l2os.CLIConfig + if e2eutils.UseFPAC() { + proposerCLIConfig = &l2os.CLIConfig{ + L1EthRpc: sys.EthInstances["l1"].WSEndpoint(), + RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(), + DGFAddress: config.L1Deployments.DisputeGameFactoryProxy.Hex(), + ProposalInterval: 6 * time.Second, + DisputeGameType: 0, + PollInterval: 50 * time.Millisecond, + TxMgrConfig: newTxMgrConfig(sys.EthInstances["l1"].WSEndpoint(), cfg.Secrets.Proposer), + AllowNonFinalized: cfg.NonFinalizedProposals, + LogConfig: oplog.CLIConfig{ + Level: log.LvlInfo, + Format: oplog.FormatText, + }, + } + } else { + proposerCLIConfig = &l2os.CLIConfig{ + L1EthRpc: sys.EthInstances["l1"].WSEndpoint(), + RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(), + L2OOAddress: config.L1Deployments.L2OutputOracleProxy.Hex(), + PollInterval: 50 * time.Millisecond, + TxMgrConfig: newTxMgrConfig(sys.EthInstances["l1"].WSEndpoint(), cfg.Secrets.Proposer), + AllowNonFinalized: cfg.NonFinalizedProposals, + LogConfig: oplog.CLIConfig{ + Level: log.LvlInfo, + Format: oplog.FormatText, + }, + } + } + proposer, err := l2os.ProposerServiceFromCLIConfig(context.Background(), "0.0.1", proposerCLIConfig, sys.Cfg.Loggers["proposer"]) if err != nil { return nil, fmt.Errorf("unable to setup l2 output submitter: %w", err) } - - if err := sys.L2OutputSubmitter.Start(); err != nil { + if err := proposer.Start(context.Background()); err != nil { return nil, fmt.Errorf("unable to start l2 output submitter: %w", err) } + sys.L2OutputSubmitter = proposer - batchType := derive.SingularBatchType - if os.Getenv("OP_E2E_USE_SPAN_BATCH") == "true" { + var batchType uint = derive.SingularBatchType + if cfg.DeployConfig.L2GenesisDeltaTimeOffset != nil && *cfg.DeployConfig.L2GenesisDeltaTimeOffset == hexutil.Uint64(0) { batchType = derive.SpanBatchType } + // batcher defaults if unset + batcherMaxL1TxSizeBytes := cfg.BatcherMaxL1TxSizeBytes + if batcherMaxL1TxSizeBytes == 0 { + batcherMaxL1TxSizeBytes = 120_000 + } + batcherTargetNumFrames := cfg.BatcherTargetNumFrames + if batcherTargetNumFrames == 0 { + batcherTargetNumFrames = 1 + } batcherCLIConfig := &bss.CLIConfig{ - L1EthRpc: sys.EthInstances["l1"].WSEndpoint(), - L2EthRpc: sys.EthInstances["sequencer"].WSEndpoint(), - RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(), - MaxPendingTransactions: 0, - MaxChannelDuration: 1, - MaxL1TxSize: 240_000, - CompressorConfig: compressor.CLIConfig{ - TargetL1TxSizeBytes: cfg.BatcherTargetL1TxSizeBytes, - TargetNumFrames: 1, - ApproxComprRatio: 0.4, - }, - SubSafetyMargin: 4, - PollInterval: 50 * time.Millisecond, - TxMgrConfig: newTxMgrConfig(sys.EthInstances["l1"].WSEndpoint(), cfg.Secrets.Batcher), + L1EthRpc: sys.EthInstances["l1"].WSEndpoint(), + L2EthRpc: sys.EthInstances["sequencer"].WSEndpoint(), + RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(), + MaxPendingTransactions: cfg.MaxPendingTransactions, + MaxChannelDuration: 1, + MaxL1TxSize: batcherMaxL1TxSizeBytes, + TestUseMaxTxSizeForBlobs: cfg.BatcherUseMaxTxSizeForBlobs, + TargetNumFrames: int(batcherTargetNumFrames), + ApproxComprRatio: 0.4, + SubSafetyMargin: 4, + PollInterval: 50 * time.Millisecond, + TxMgrConfig: newTxMgrConfig(sys.EthInstances["l1"].WSEndpoint(), cfg.Secrets.Batcher), LogConfig: oplog.CLIConfig{ - Level: log.LvlInfo, + Level: log.LevelInfo, Format: oplog.FormatText, }, - Stopped: sys.cfg.DisableBatcher, // Batch submitter may be enabled later - BatchType: uint(batchType), + Stopped: sys.Cfg.DisableBatcher, // Batch submitter may be enabled later + BatchType: batchType, + DataAvailabilityType: sys.Cfg.DataAvailabilityType, } // Batch Submitter - batcher, err := bss.BatcherServiceFromCLIConfig(context.Background(), "0.0.1", batcherCLIConfig, sys.cfg.Loggers["batcher"]) + batcher, err := bss.BatcherServiceFromCLIConfig(context.Background(), "0.0.1", batcherCLIConfig, sys.Cfg.Loggers["batcher"]) if err != nil { return nil, fmt.Errorf("failed to setup batch submitter: %w", err) } @@ -756,7 +888,7 @@ func (sys *System) newMockNetPeer() (host.Host, error) { _ = ps.AddPrivKey(p, sk) _ = ps.AddPubKey(p, sk.GetPublic()) - ds := sync.MutexWrap(ds.NewMapDatastore()) + ds := dsSync.MutexWrap(ds.NewMapDatastore()) eps, err := store.NewExtendedPeerstore(context.Background(), log.Root(), clock.SystemClock, ps, ds, 24*time.Hour) if err != nil { return nil, err @@ -764,6 +896,10 @@ func (sys *System) newMockNetPeer() (host.Host, error) { return sys.Mocknet.AddPeerWithPeerstore(p, eps) } +func (sys *System) BatcherHelper() *batcher.Helper { + return batcher.NewHelper(sys.t, sys.Cfg.Secrets.Batcher, sys.RollupConfig, sys.NodeClient("l1")) +} + func UseHTTP() bool { return os.Getenv("OP_E2E_USE_HTTP") == "true" } @@ -785,6 +921,7 @@ func configureL1(rollupNodeCfg *rollupNode.Config, l1Node EthInstance) { RateLimit: 0, BatchSize: 20, HttpPollInterval: time.Millisecond * 100, + MaxConcurrency: 10, } } diff --git a/op-e2e/system_adminrpc_test.go b/op-e2e/system_adminrpc_test.go index 99a4dbf3c364..e7c0af673b84 100644 --- a/op-e2e/system_adminrpc_test.go +++ b/op-e2e/system_adminrpc_test.go @@ -2,16 +2,19 @@ package op_e2e import ( "context" + "math/big" "testing" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/require" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-node/node" "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rpc" - "github.com/stretchr/testify/require" ) func TestStopStartSequencer(t *testing.T) { @@ -172,6 +175,45 @@ func TestLoadSequencerStateOnStarted_Started(t *testing.T) { assertPersistedSequencerState(t, stateFile, node.StateStarted) } +func TestPostUnsafePayload(t *testing.T) { + InitParallel(t) + ctx := context.Background() + + cfg := DefaultSystemConfig(t) + cfg.Nodes["verifier"].RPC.EnableAdmin = true + cfg.DisableBatcher = true + + sys, err := cfg.Start(t) + require.NoError(t, err) + defer sys.Close() + + l2Seq := sys.Clients["sequencer"] + l2Ver := sys.Clients["verifier"] + rollupClient := sys.RollupClient("verifier") + + require.NoError(t, wait.ForBlock(ctx, l2Seq, 2), "Chain did not advance after starting sequencer") + verBlock, err := l2Ver.BlockByNumber(ctx, nil) + require.NoError(t, err) + require.Equal(t, uint64(0), verBlock.NumberU64(), "Verifier should not have advanced any blocks since p2p & batcher are not enabled") + + blockNumberOne, err := l2Seq.BlockByNumber(ctx, big.NewInt(1)) + require.NoError(t, err) + payload, err := eth.BlockAsPayload(blockNumberOne, sys.RollupConfig.CanyonTime) + require.NoError(t, err) + err = rollupClient.PostUnsafePayload(ctx, ð.ExecutionPayloadEnvelope{ExecutionPayload: payload}) + require.NoError(t, err) + require.NoError(t, wait.ForUnsafeBlock(ctx, rollupClient, 1), "Chain did not advance after posting payload") + + // Test validation + blockNumberTwo, err := l2Seq.BlockByNumber(ctx, big.NewInt(2)) + require.NoError(t, err) + payload, err = eth.BlockAsPayload(blockNumberTwo, sys.RollupConfig.CanyonTime) + require.NoError(t, err) + payload.BlockHash = common.Hash{0xaa} + err = rollupClient.PostUnsafePayload(ctx, ð.ExecutionPayloadEnvelope{ExecutionPayload: payload}) + require.ErrorContains(t, err, "payload has bad block hash") +} + func assertPersistedSequencerState(t *testing.T, stateFile string, expected node.RunningState) { configReader := node.NewConfigPersistence(stateFile) state, err := configReader.SequencerState() diff --git a/op-e2e/system_fpp_test.go b/op-e2e/system_fpp_test.go index b4a20bc086e1..4da5f75ca51c 100644 --- a/op-e2e/system_fpp_test.go +++ b/op-e2e/system_fpp_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum-optimism/optimism/op-program/client/driver" opp "github.com/ethereum-optimism/optimism/op-program/host" @@ -15,25 +16,62 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" "github.com/stretchr/testify/require" ) func TestVerifyL2OutputRoot(t *testing.T) { - testVerifyL2OutputRoot(t, false) + testVerifyL2OutputRoot(t, false, false) +} + +func TestVerifyL2OutputRootSpanBatch(t *testing.T) { + testVerifyL2OutputRoot(t, false, true) } func TestVerifyL2OutputRootDetached(t *testing.T) { - testVerifyL2OutputRoot(t, true) + testVerifyL2OutputRoot(t, true, false) +} + +func TestVerifyL2OutputRootDetachedSpanBatch(t *testing.T) { + testVerifyL2OutputRoot(t, true, true) } func TestVerifyL2OutputRootEmptyBlock(t *testing.T) { - testVerifyL2OutputRootEmptyBlock(t, false) + testVerifyL2OutputRootEmptyBlock(t, false, false) +} + +func TestVerifyL2OutputRootEmptyBlockSpanBatch(t *testing.T) { + testVerifyL2OutputRootEmptyBlock(t, false, true) } func TestVerifyL2OutputRootEmptyBlockDetached(t *testing.T) { - testVerifyL2OutputRootEmptyBlock(t, true) + testVerifyL2OutputRootEmptyBlock(t, true, false) +} + +func TestVerifyL2OutputRootEmptyBlockDetachedSpanBatch(t *testing.T) { + testVerifyL2OutputRootEmptyBlock(t, true, true) +} + +func applySpanBatchActivation(active bool, dp *genesis.DeployConfig) { + if active { + // Activate delta hard fork + minTs := hexutil.Uint64(0) + dp.L2GenesisDeltaTimeOffset = &minTs + // readjust other activations + if dp.L2GenesisEcotoneTimeOffset != nil { + dp.L2GenesisEcotoneTimeOffset = &minTs + } + if dp.L2GenesisFjordTimeOffset != nil { + dp.L2GenesisFjordTimeOffset = &minTs + } + } else { + // cancel delta and any later hardfork activations + dp.L2GenesisDeltaTimeOffset = nil + dp.L2GenesisEcotoneTimeOffset = nil + dp.L2GenesisFjordTimeOffset = nil + } } // TestVerifyL2OutputRootEmptyBlock asserts that the program can verify the output root of an empty block @@ -46,7 +84,7 @@ func TestVerifyL2OutputRootEmptyBlockDetached(t *testing.T) { // - reboot the batch submitter // - update the state root via a tx // - run program -func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) { +func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActivated bool) { InitParallel(t) ctx := context.Background() @@ -56,12 +94,13 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) { // Use a small sequencer window size to avoid test timeout while waiting for empty blocks // But not too small to ensure that our claim and subsequent state change is published cfg.DeployConfig.SequencerWindowSize = 16 + applySpanBatchActivation(spanBatchActivated, cfg.DeployConfig) sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") defer sys.Close() - log := testlog.Logger(t, log.LvlInfo) + log := testlog.Logger(t, log.LevelInfo) log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) l1Client := sys.Clients["l1"] @@ -100,7 +139,7 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) { t.Log("Wait for sequencer to catch up with last submitted batch") l1HeadNum, err := l1Client.BlockNumber(ctx) require.NoError(t, err) - _, err = geth.WaitForL1OriginOnL2(l1HeadNum, l2Seq, 30*time.Second) + _, err = geth.WaitForL1OriginOnL2(sys.RollupConfig, l1HeadNum, l2Seq, 30*time.Second) require.NoError(t, err) // Get the current safe head now that the batcher is stopped @@ -147,19 +186,20 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) { }) } -func testVerifyL2OutputRoot(t *testing.T, detached bool) { +func testVerifyL2OutputRoot(t *testing.T, detached bool, spanBatchActivated bool) { InitParallel(t) ctx := context.Background() cfg := DefaultSystemConfig(t) // We don't need a verifier - just the sequencer is enough delete(cfg.Nodes, "verifier") + applySpanBatchActivation(spanBatchActivated, cfg.DeployConfig) sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") defer sys.Close() - log := testlog.Logger(t, log.LvlInfo) + log := testlog.Logger(t, log.LevelInfo) log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) l1Client := sys.Clients["l1"] @@ -252,14 +292,15 @@ func testFaultProofProgramScenario(t *testing.T, ctx context.Context, sys *Syste // Check the FPP confirms the expected output t.Log("Running fault proof in fetching mode") - log := testlog.Logger(t, log.LvlInfo) + log := testlog.Logger(t, log.LevelInfo) err := opp.FaultProofProgram(ctx, log, fppConfig) require.NoError(t, err) t.Log("Shutting down network") // Shutdown the nodes from the actual chain. Should now be able to run using only the pre-fetched data. require.NoError(t, sys.BatchSubmitter.Kill()) - sys.L2OutputSubmitter.Stop() + err = sys.L2OutputSubmitter.Driver().StopL2OutputSubmitting() + require.NoError(t, err) sys.L2OutputSubmitter = nil for _, node := range sys.EthInstances { node.Close() diff --git a/op-e2e/system_test.go b/op-e2e/system_test.go index 4089d25b5f4f..21938483fadf 100644 --- a/op-e2e/system_test.go +++ b/op-e2e/system_test.go @@ -10,11 +10,13 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/ethconfig" @@ -31,6 +33,8 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-e2e/config" + gethutils "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-node/metrics" rollupNode "github.com/ethereum-optimism/optimism/op-node/node" @@ -39,12 +43,37 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup/driver" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/eth" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" ) +// TestSystemBatchType run each system e2e test case in singular batch mode and span batch mode. +// If the test case tests batch submission and advancing safe head, it should be tested in both singular and span batch mode. +func TestSystemBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, deltaTimeOffset *hexutil.Uint64) + }{ + {"StopStartBatcher", StopStartBatcher}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + deltaTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &deltaTimeOffset) + }) + } +} + func TestMain(m *testing.M) { if config.ExternalL2Shim != "" { fmt.Println("Running tests with external L2 process adapter at ", config.ExternalL2Shim) @@ -62,7 +91,7 @@ func TestMain(m *testing.M) { } func TestL2OutputSubmitter(t *testing.T) { - InitParallel(t) + InitParallel(t, SkipOnFPAC) cfg := DefaultSystemConfig(t) cfg.NonFinalizedProposals = true // speed up the time till we see output proposals @@ -114,7 +143,7 @@ func TestL2OutputSubmitter(t *testing.T) { // // NOTE: This assertion will change once the L2 output format is // finalized. - ctx, cancel := context.WithTimeout(context.Background(), time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() l2Output, err := rollupClient.OutputAtBlock(ctx, l2ooBlockNumber.Uint64()) require.Nil(t, err) @@ -130,6 +159,121 @@ func TestL2OutputSubmitter(t *testing.T) { } } +func TestL2OutputSubmitterFPAC(t *testing.T) { + InitParallel(t, SkipOnNotFPAC) + + cfg := DefaultSystemConfig(t) + cfg.NonFinalizedProposals = true // speed up the time till we see output proposals + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + defer sys.Close() + + l1Client := sys.Clients["l1"] + + rollupRPCClient, err := rpc.DialContext(context.Background(), sys.RollupNodes["sequencer"].HTTPEndpoint()) + require.Nil(t, err) + rollupClient := sources.NewRollupClient(client.NewBaseRPCClient(rollupRPCClient)) + + disputeGameFactory, err := bindings.NewDisputeGameFactoryCaller(cfg.L1Deployments.DisputeGameFactoryProxy, l1Client) + require.Nil(t, err) + + initialGameCount, err := disputeGameFactory.GameCount(&bind.CallOpts{}) + require.Nil(t, err) + + l2Verif := sys.Clients["verifier"] + _, err = geth.WaitForBlock(big.NewInt(6), l2Verif, 10*time.Duration(cfg.DeployConfig.L2BlockTime)*time.Second) + require.Nil(t, err) + + timeoutCh := time.After(15 * time.Second) + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + for { + latestGameCount, err := disputeGameFactory.GameCount(&bind.CallOpts{}) + require.Nil(t, err) + + if latestGameCount.Cmp(initialGameCount) > 0 { + committedL2Output, err := disputeGameFactory.GameAtIndex(&bind.CallOpts{}, new(big.Int).Sub(latestGameCount, common.Big1)) + require.Nil(t, err) + proxy, err := bindings.NewFaultDisputeGameCaller(committedL2Output.Proxy, l1Client) + require.Nil(t, err) + committedOutputRoot, err := proxy.RootClaim(&bind.CallOpts{}) + require.Nil(t, err) + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + extradata, err := proxy.ExtraData(&bind.CallOpts{}) + require.Nil(t, err) + gameBlockNumber := new(big.Int).SetBytes(extradata[0:32]) + l2Output, err := rollupClient.OutputAtBlock(ctx, gameBlockNumber.Uint64()) + require.Nil(t, err) + require.Equal(t, l2Output.OutputRoot[:], committedOutputRoot[:]) + break + } + + select { + case <-timeoutCh: + t.Fatalf("State root oracle not updated") + case <-ticker.C: + } + } +} + +func TestSystemE2EDencunAtGenesis(t *testing.T) { + InitParallel(t) + + cfg := DefaultSystemConfig(t) + genesisActivation := hexutil.Uint64(0) + cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + defer sys.Close() + runE2ESystemTest(t, sys) + head, err := sys.Clients["l1"].BlockByNumber(context.Background(), big.NewInt(0)) + require.NoError(t, err) + require.NotNil(t, head.ExcessBlobGas(), "L1 is building dencun blocks since genesis") +} + +// TestSystemE2EDencunAtGenesis tests if L2 finalizes when blobs are present on L1 +func TestSystemE2EDencunAtGenesisWithBlobs(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + InitParallel(t) + + cfg := DefaultSystemConfig(t) + // cancun is on from genesis: + genesisActivation := hexutil.Uint64(0) + cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation // i.e. turn cancun on at genesis time + 0 + + sys, err := cfg.Start(t) + require.Nil(t, err, "Error starting up system") + defer sys.Close() + + // send a blob-containing txn on l1 + ethPrivKey := sys.Cfg.Secrets.Alice + txData := transactions.CreateEmptyBlobTx(true, sys.Cfg.L1ChainIDBig().Uint64()) + tx := types.MustSignNewTx(ethPrivKey, types.LatestSignerForChainID(cfg.L1ChainIDBig()), txData) + // send blob-containing txn + sendCtx, sendCancel := context.WithTimeout(context.Background(), 15*time.Second) + defer sendCancel() + + l1Client := sys.Clients["l1"] + err = l1Client.SendTransaction(sendCtx, tx) + require.NoError(t, err, "Sending L1 empty blob tx") + // Wait for transaction on L1 + blockContainsBlob, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash()) + require.Nil(t, err, "Waiting for blob tx on L1") + // end sending blob-containing txns on l1 + l2Client := sys.Clients["sequencer"] + finalizedBlock, err := gethutils.WaitForL1OriginOnL2(sys.RollupConfig, blockContainsBlob.BlockNumber.Uint64(), l2Client, 30*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) + require.Nil(t, err, "Waiting for L1 origin of blob tx on L2") + finalizationTimeout := 30 * time.Duration(cfg.DeployConfig.L1BlockTime) * time.Second + _, err = gethutils.WaitForBlockToBeSafe(finalizedBlock.Header().Number, l2Client, finalizationTimeout) + require.Nil(t, err, "Waiting for safety of L2 block") +} + // TestSystemE2E sets up a L1 Geth node, a rollup node, and a L2 geth node and then confirms that L1 deposits are reflected on L2. // All nodes are run in process (but are the full nodes, not mocked or stubbed). func TestSystemE2E(t *testing.T) { @@ -139,9 +283,12 @@ func TestSystemE2E(t *testing.T) { sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") + runE2ESystemTest(t, sys) defer sys.Close() +} - log := testlog.Logger(t, log.LvlInfo) +func runE2ESystemTest(t *testing.T, sys *System) { + log := testlog.Logger(t, log.LevelInfo) log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) l1Client := sys.Clients["l1"] @@ -149,10 +296,10 @@ func TestSystemE2E(t *testing.T) { l2Verif := sys.Clients["verifier"] // Transactor Account - ethPrivKey := sys.cfg.Secrets.Alice + ethPrivKey := sys.Cfg.Secrets.Alice // Send Transaction & wait for success - fromAddr := sys.cfg.Secrets.Addresses().Alice + fromAddr := sys.Cfg.Secrets.Addresses().Alice ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() @@ -160,16 +307,17 @@ func TestSystemE2E(t *testing.T) { require.Nil(t, err) // Send deposit transaction - opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig()) + opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, sys.Cfg.L1ChainIDBig()) require.Nil(t, err) mintAmount := big.NewInt(1_000_000_000_000) opts.Value = mintAmount - SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *DepositTxOpts) {}) + SendDepositTx(t, sys.Cfg, l1Client, l2Verif, opts, func(l2Opts *DepositTxOpts) {}) // Confirm balance ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second) defer cancel() - endBalance, err := l2Verif.BalanceAt(ctx, fromAddr, nil) + + endBalance, err := wait.ForBalanceChange(ctx, l2Verif, fromAddr, startBalance) require.Nil(t, err) diff := new(big.Int) @@ -177,7 +325,7 @@ func TestSystemE2E(t *testing.T) { require.Equal(t, mintAmount, diff, "Did not get expected balance change") // Submit TX to L2 sequencer node - receipt := SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { + receipt := SendL2Tx(t, sys.Cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { opts.Value = big.NewInt(1_000_000_000) opts.Nonce = 1 // Already have deposit opts.ToAddr = &common.Address{0xff, 0xff} @@ -223,7 +371,7 @@ func TestConfirmationDepth(t *testing.T) { require.Nil(t, err, "Error starting up system") defer sys.Close() - log := testlog.Logger(t, log.LvlInfo) + log := testlog.Logger(t, log.LevelInfo) log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) l1Client := sys.Clients["l1"] @@ -235,7 +383,7 @@ func TestConfirmationDepth(t *testing.T) { <-time.After(time.Duration((cfg.DeployConfig.SequencerWindowSize+verConfDepth+3)*cfg.DeployConfig.L1BlockTime) * time.Second) // within a second, get both L1 and L2 verifier and sequencer block heads - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() l1Head, err := l1Client.BlockByNumber(ctx, nil) require.NoError(t, err) @@ -244,11 +392,11 @@ func TestConfirmationDepth(t *testing.T) { l2VerHead, err := l2Verif.BlockByNumber(ctx, nil) require.NoError(t, err) - seqInfo, err := derive.L1InfoDepositTxData(l2SeqHead.Transactions()[0].Data()) + seqInfo, err := derive.L1BlockInfoFromBytes(sys.RollupConfig, l2SeqHead.Time(), l2SeqHead.Transactions()[0].Data()) require.NoError(t, err) require.LessOrEqual(t, seqInfo.Number+seqConfDepth, l1Head.NumberU64(), "the seq L2 head block should have an origin older than the L1 head block by at least the sequencer conf depth") - verInfo, err := derive.L1InfoDepositTxData(l2VerHead.Transactions()[0].Data()) + verInfo, err := derive.L1BlockInfoFromBytes(sys.RollupConfig, l2VerHead.Time(), l2VerHead.Transactions()[0].Data()) require.NoError(t, err) require.LessOrEqual(t, verInfo.Number+verConfDepth, l1Head.NumberU64(), "the ver L2 head block should have an origin older than the L1 head block by at least the verifier conf depth") } @@ -281,14 +429,14 @@ func TestPendingGasLimit(t *testing.T) { require.Nil(t, err, "Error starting up system") defer sys.Close() - log := testlog.Logger(t, log.LvlInfo) + log := testlog.Logger(t, log.LevelInfo) log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time) l2Verif := sys.Clients["verifier"] l2Seq := sys.Clients["sequencer"] checkGasLimit := func(client *ethclient.Client, number *big.Int, expected uint64) *types.Header { - ctx, cancel := context.WithTimeout(context.Background(), time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) header, err := client.HeaderByNumber(ctx, number) cancel() require.NoError(t, err) @@ -325,17 +473,8 @@ func TestFinalize(t *testing.T) { l2Seq := sys.Clients["sequencer"] - // as configured in the extra geth lifecycle in testing setup - const finalizedDistance = 8 - // Wait enough time for L1 to finalize and L2 to confirm its data in finalized L1 blocks - time.Sleep(time.Duration((finalizedDistance+6)*cfg.DeployConfig.L1BlockTime) * time.Second) - - // fetch the finalizes head of geth - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) - defer cancel() - l2Finalized, err := l2Seq.BlockByNumber(ctx, big.NewInt(int64(rpc.FinalizedBlockNumber))) - require.NoError(t, err) - + l2Finalized, err := geth.WaitForBlockToBeFinalized(big.NewInt(12), l2Seq, 1*time.Minute) + require.NoError(t, err, "must be able to fetch a finalized L2 block") require.NotZerof(t, l2Finalized.NumberU64(), "must have finalized L2 block") } @@ -376,7 +515,7 @@ func TestMissingBatchE2E(t *testing.T) { require.Nil(t, err, "Waiting for block on verifier") // Assert that the transaction is not found on the verifier - ctx, cancel := context.WithTimeout(context.Background(), time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() _, err = l2Verif.TransactionReceipt(ctx, receipt.TxHash) require.Equal(t, ethereum.NotFound, err, "Found transaction in verifier when it should not have been included") @@ -386,7 +525,7 @@ func TestMissingBatchE2E(t *testing.T) { require.Nil(t, err, "timeout waiting for L2 reorg on sequencer safe head") // Assert that the reconciliation process did an L2 reorg on the sequencer to remove the invalid block - ctx2, cancel := context.WithTimeout(context.Background(), time.Second) + ctx2, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() block, err := l2Seq.BlockByNumber(ctx2, receipt.BlockNumber) if err != nil { @@ -396,9 +535,9 @@ func TestMissingBatchE2E(t *testing.T) { } } -func L1InfoFromState(ctx context.Context, contract *bindings.L1Block, l2Number *big.Int) (derive.L1BlockInfo, error) { +func L1InfoFromState(ctx context.Context, contract *bindings.L1Block, l2Number *big.Int, ecotone bool) (*derive.L1BlockInfo, error) { var err error - var out derive.L1BlockInfo + out := &derive.L1BlockInfo{} opts := bind.CallOpts{ BlockNumber: l2Number, Context: ctx, @@ -406,48 +545,70 @@ func L1InfoFromState(ctx context.Context, contract *bindings.L1Block, l2Number * out.Number, err = contract.Number(&opts) if err != nil { - return derive.L1BlockInfo{}, fmt.Errorf("failed to get number: %w", err) + return nil, fmt.Errorf("failed to get number: %w", err) } out.Time, err = contract.Timestamp(&opts) if err != nil { - return derive.L1BlockInfo{}, fmt.Errorf("failed to get timestamp: %w", err) + return nil, fmt.Errorf("failed to get timestamp: %w", err) } out.BaseFee, err = contract.Basefee(&opts) if err != nil { - return derive.L1BlockInfo{}, fmt.Errorf("failed to get timestamp: %w", err) + return nil, fmt.Errorf("failed to get base fee: %w", err) } blockHashBytes, err := contract.Hash(&opts) if err != nil { - return derive.L1BlockInfo{}, fmt.Errorf("failed to get block hash: %w", err) + return nil, fmt.Errorf("failed to get block hash: %w", err) } out.BlockHash = common.BytesToHash(blockHashBytes[:]) out.SequenceNumber, err = contract.SequenceNumber(&opts) if err != nil { - return derive.L1BlockInfo{}, fmt.Errorf("failed to get sequence number: %w", err) + return nil, fmt.Errorf("failed to get sequence number: %w", err) } - overhead, err := contract.L1FeeOverhead(&opts) - if err != nil { - return derive.L1BlockInfo{}, fmt.Errorf("failed to get l1 fee overhead: %w", err) - } - out.L1FeeOverhead = eth.Bytes32(common.BigToHash(overhead)) + if !ecotone { + overhead, err := contract.L1FeeOverhead(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get l1 fee overhead: %w", err) + } + out.L1FeeOverhead = eth.Bytes32(common.BigToHash(overhead)) - scalar, err := contract.L1FeeScalar(&opts) - if err != nil { - return derive.L1BlockInfo{}, fmt.Errorf("failed to get l1 fee scalar: %w", err) + scalar, err := contract.L1FeeScalar(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get l1 fee scalar: %w", err) + } + out.L1FeeScalar = eth.Bytes32(common.BigToHash(scalar)) } - out.L1FeeScalar = eth.Bytes32(common.BigToHash(scalar)) batcherHash, err := contract.BatcherHash(&opts) if err != nil { - return derive.L1BlockInfo{}, fmt.Errorf("failed to get batch sender: %w", err) + return nil, fmt.Errorf("failed to get batch sender: %w", err) } out.BatcherAddr = common.BytesToAddress(batcherHash[:]) + if ecotone { + blobBaseFeeScalar, err := contract.BlobBaseFeeScalar(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get blob basefee scalar: %w", err) + } + out.BlobBaseFeeScalar = blobBaseFeeScalar + + baseFeeScalar, err := contract.BaseFeeScalar(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get basefee scalar: %w", err) + } + out.BaseFeeScalar = baseFeeScalar + + blobBaseFee, err := contract.BlobBaseFee(&opts) + if err != nil { + return nil, fmt.Errorf("failed to get blob basefee: %w", err) + } + out.BlobBaseFee = blobBaseFee + } + return out, nil } @@ -472,11 +633,11 @@ func TestSystemMockP2P(t *testing.T) { var published, received []common.Hash seqTracer, verifTracer := new(FnTracer), new(FnTracer) - seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayload) { - published = append(published, payload.BlockHash) + seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { + published = append(published, payload.ExecutionPayload.BlockHash) } - verifTracer.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) { - received = append(received, payload.BlockHash) + verifTracer.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { + received = append(received, payload.ExecutionPayload.BlockHash) } cfg.Nodes["sequencer"].Tracer = seqTracer cfg.Nodes["verifier"].Tracer = verifTracer @@ -525,86 +686,16 @@ func TestSystemMockP2P(t *testing.T) { // Verify that everything that was received was published require.GreaterOrEqual(t, len(published), len(received)) - require.ElementsMatch(t, received, published[:len(received)]) + require.Subset(t, published, received) // Verify that the tx was received via p2p require.Contains(t, received, receiptSeq.BlockHash) } -// TestSystemRPCAltSync sets up a L1 Geth node, a rollup node, and a L2 geth node and then confirms that -// the nodes can sync L2 blocks before they are confirmed on L1. -// -// Test steps: -// 1. Spin up the nodes (P2P is disabled on the verifier) -// 2. Send a transaction to the sequencer. -// 3. Wait for the TX to be mined on the sequencer chain. -// 5. Wait for the verifier to detect a gap in the payload queue vs. the unsafe head -// 6. Wait for the RPC sync method to grab the block from the sequencer over RPC and insert it into the verifier's unsafe chain. -// 7. Wait for the verifier to sync the unsafe chain into the safe chain. -// 8. Verify that the TX is included in the verifier's safe chain. -func TestSystemRPCAltSync(t *testing.T) { - InitParallel(t) - - cfg := DefaultSystemConfig(t) - // the default is nil, but this may change in the future. - // This test must ensure the blocks are not synced via Gossip, but instead via the alt RPC based sync. - cfg.P2PTopology = nil - // Disable batcher, so there will not be any L1 data to sync from - cfg.DisableBatcher = true - - var published, received []string - seqTracer, verifTracer := new(FnTracer), new(FnTracer) - // The sequencer still publishes the blocks to the tracer, even if they do not reach the network due to disabled P2P - seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayload) { - published = append(published, payload.ID().String()) - } - // Blocks are now received via the RPC based alt-sync method - verifTracer.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) { - received = append(received, payload.ID().String()) - } - cfg.Nodes["sequencer"].Tracer = seqTracer - cfg.Nodes["verifier"].Tracer = verifTracer - - sys, err := cfg.Start(t, SystemConfigOption{ - key: "afterRollupNodeStart", - role: "sequencer", - action: func(sCfg *SystemConfig, system *System) { - cfg.Nodes["verifier"].L2Sync = &rollupNode.PreparedL2SyncEndpoint{ - Client: client.NewBaseRPCClient(system.RawClients["sequencer"]), - } - }, - }) - require.Nil(t, err, "Error starting up system") - defer sys.Close() - - l2Seq := sys.Clients["sequencer"] - l2Verif := sys.Clients["verifier"] - - // Transactor Account - ethPrivKey := cfg.Secrets.Alice - - // Submit a TX to L2 sequencer node - receiptSeq := SendL2Tx(t, cfg, l2Seq, ethPrivKey, func(opts *TxOpts) { - opts.ToAddr = &common.Address{0xff, 0xff} - opts.Value = big.NewInt(1_000_000_000) - - // Wait for alt RPC sync to pick up the blocks on the sequencer chain - opts.VerifyOnClients(l2Verif) - }) - - // Sometimes we get duplicate blocks on the sequencer which makes this test flaky - published = slices.Compact(published) - received = slices.Compact(received) - - // Verify that the tx was received via RPC sync (P2P is disabled) - require.Contains(t, received, eth.BlockID{Hash: receiptSeq.BlockHash, Number: receiptSeq.BlockNumber.Uint64()}.String()) - - // Verify that everything that was received was published - require.GreaterOrEqual(t, len(published), len(received)) - require.ElementsMatch(t, received, published[:len(received)]) -} - func TestSystemP2PAltSync(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + InitParallel(t) cfg := DefaultSystemConfig(t) @@ -628,8 +719,8 @@ func TestSystemP2PAltSync(t *testing.T) { }, L1EpochPollInterval: time.Second * 4, } - cfg.Loggers["alice"] = testlog.Logger(t, log.LvlInfo).New("role", "alice") - cfg.Loggers["bob"] = testlog.Logger(t, log.LvlInfo).New("role", "bob") + cfg.Loggers["alice"] = testlog.Logger(t, log.LevelInfo).New("role", "alice") + cfg.Loggers["bob"] = testlog.Logger(t, log.LevelInfo).New("role", "bob") // connect the nodes cfg.P2PTopology = map[string][]string{ @@ -646,8 +737,8 @@ func TestSystemP2PAltSync(t *testing.T) { var published []string seqTracer := new(FnTracer) // The sequencer still publishes the blocks to the tracer, even if they do not reach the network due to disabled P2P - seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayload) { - published = append(published, payload.ID().String()) + seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { + published = append(published, payload.ExecutionPayload.ID().String()) } // Blocks are now received via the RPC based alt-sync method cfg.Nodes["sequencer"].Tracer = seqTracer @@ -672,9 +763,8 @@ func TestSystemP2PAltSync(t *testing.T) { time.Sleep(time.Second * 10) // set up our syncer node, connect it to alice/bob - cfg.Loggers["syncer"] = testlog.Logger(t, log.LvlInfo).New("role", "syncer") - snapLog := log.New() - snapLog.SetHandler(log.DiscardHandler()) + cfg.Loggers["syncer"] = testlog.Logger(t, log.LevelInfo).New("role", "syncer") + snapLog := log.NewLogger(log.DiscardHandler()) // Create a peer, and hook up alice and bob h, err := sys.newMockNetPeer() @@ -687,7 +777,6 @@ func TestSystemP2PAltSync(t *testing.T) { // Configure the new rollup node that'll be syncing var syncedPayloads []string syncNodeCfg := &rollupNode.Config{ - L2Sync: &rollupNode.PreparedL2SyncEndpoint{Client: nil}, Driver: driver.Config{VerifierConfDepth: 0}, Rollup: *sys.RollupConfig, P2PSigner: nil, @@ -701,8 +790,8 @@ func TestSystemP2PAltSync(t *testing.T) { Pprof: oppprof.CLIConfig{}, L1EpochPollInterval: time.Second * 10, Tracer: &FnTracer{ - OnUnsafeL2PayloadFn: func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) { - syncedPayloads = append(syncedPayloads, payload.ID().String()) + OnUnsafeL2PayloadFn: func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { + syncedPayloads = append(syncedPayloads, payload.ExecutionPayload.ID().String()) }, }, } @@ -713,10 +802,13 @@ func TestSystemP2PAltSync(t *testing.T) { configureL2(syncNodeCfg, syncerL2Engine, cfg.JWTSecret) - syncerNode, err := rollupNode.New(context.Background(), syncNodeCfg, cfg.Loggers["syncer"], snapLog, "", metrics.NewMetrics("")) + syncerNode, err := rollupNode.New(ctx, syncNodeCfg, cfg.Loggers["syncer"], snapLog, "", metrics.NewMetrics("")) require.NoError(t, err) - err = syncerNode.Start(context.Background()) + err = syncerNode.Start(ctx) require.NoError(t, err) + defer func() { + require.NoError(t, syncerNode.Stop(ctx)) + }() // connect alice and bob to our new syncer node _, err = sys.Mocknet.ConnectPeers(sys.RollupNodes["alice"].P2P().Host().ID(), syncerNode.P2P().Host().ID()) @@ -728,7 +820,7 @@ func TestSystemP2PAltSync(t *testing.T) { l2Verif := ethclient.NewClient(rpc) // It may take a while to sync, but eventually we should see the sequenced data show up - receiptVerif, err := geth.WaitForTransaction(receiptSeq.TxHash, l2Verif, 100*time.Duration(sys.RollupConfig.BlockTime)*time.Second) + receiptVerif, err := wait.ForReceiptOK(ctx, l2Verif, receiptSeq.TxHash) require.Nil(t, err, "Waiting for L2 tx on verifier") require.Equal(t, receiptSeq, receiptVerif) @@ -738,7 +830,7 @@ func TestSystemP2PAltSync(t *testing.T) { // Verify that everything that was received was published require.GreaterOrEqual(t, len(published), len(syncedPayloads)) - require.ElementsMatch(t, syncedPayloads, published[:len(syncedPayloads)]) + require.Subset(t, published, syncedPayloads) } // TestSystemDenseTopology sets up a dense p2p topology with 3 verifier nodes and 1 sequencer node. @@ -769,8 +861,8 @@ func TestSystemDenseTopology(t *testing.T) { }, L1EpochPollInterval: time.Second * 4, } - cfg.Loggers["verifier2"] = testlog.Logger(t, log.LvlInfo).New("role", "verifier") - cfg.Loggers["verifier3"] = testlog.Logger(t, log.LvlInfo).New("role", "verifier") + cfg.Loggers["verifier2"] = testlog.Logger(t, log.LevelInfo).New("role", "verifier") + cfg.Loggers["verifier3"] = testlog.Logger(t, log.LevelInfo).New("role", "verifier") // connect the nodes cfg.P2PTopology = map[string][]string{ @@ -791,17 +883,17 @@ func TestSystemDenseTopology(t *testing.T) { var published, received1, received2, received3 []common.Hash seqTracer, verifTracer, verifTracer2, verifTracer3 := new(FnTracer), new(FnTracer), new(FnTracer), new(FnTracer) - seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayload) { - published = append(published, payload.BlockHash) + seqTracer.OnPublishL2PayloadFn = func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { + published = append(published, payload.ExecutionPayload.BlockHash) } - verifTracer.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) { - received1 = append(received1, payload.BlockHash) + verifTracer.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { + received1 = append(received1, payload.ExecutionPayload.BlockHash) } - verifTracer2.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) { - received2 = append(received2, payload.BlockHash) + verifTracer2.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { + received2 = append(received2, payload.ExecutionPayload.BlockHash) } - verifTracer3.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) { - received3 = append(received3, payload.BlockHash) + verifTracer3.OnUnsafeL2PayloadFn = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { + received3 = append(received3, payload.ExecutionPayload.BlockHash) } cfg.Nodes["sequencer"].Tracer = seqTracer cfg.Nodes["verifier"].Tracer = verifTracer @@ -874,14 +966,16 @@ func TestL1InfoContract(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() - fillInfoLists := func(start *types.Block, contract *bindings.L1Block, client *ethclient.Client) ([]derive.L1BlockInfo, []derive.L1BlockInfo) { - var txList, stateList []derive.L1BlockInfo + fillInfoLists := func(start *types.Block, contract *bindings.L1Block, client *ethclient.Client) ([]*derive.L1BlockInfo, []*derive.L1BlockInfo) { + var txList, stateList []*derive.L1BlockInfo for b := start; ; { - var infoFromTx derive.L1BlockInfo - require.NoError(t, infoFromTx.UnmarshalBinary(b.Transactions()[0].Data())) + var infoFromTx *derive.L1BlockInfo + infoFromTx, err := derive.L1BlockInfoFromBytes(sys.RollupConfig, b.Time(), b.Transactions()[0].Data()) + require.NoError(t, err) txList = append(txList, infoFromTx) - infoFromState, err := L1InfoFromState(ctx, contract, b.Number()) + ecotone := sys.RollupConfig.IsEcotone(b.Time()) && !sys.RollupConfig.IsEcotoneActivationBlock(b.Time()) + infoFromState, err := L1InfoFromState(ctx, contract, b.Number(), ecotone) require.Nil(t, err) stateList = append(stateList, infoFromState) @@ -897,21 +991,33 @@ func TestL1InfoContract(t *testing.T) { l1InfosFromSequencerTransactions, l1InfosFromSequencerState := fillInfoLists(endSeqBlock, seqL1Info, l2Seq) l1InfosFromVerifierTransactions, l1InfosFromVerifierState := fillInfoLists(endVerifBlock, verifL1Info, l2Verif) - l1blocks := make(map[common.Hash]derive.L1BlockInfo) + l1blocks := make(map[common.Hash]*derive.L1BlockInfo) maxL1Hash := l1InfosFromSequencerTransactions[0].BlockHash for h := maxL1Hash; ; { b, err := l1Client.BlockByHash(ctx, h) require.Nil(t, err) - l1blocks[h] = derive.L1BlockInfo{ + l1blocks[h] = &derive.L1BlockInfo{ Number: b.NumberU64(), Time: b.Time(), BaseFee: b.BaseFee(), BlockHash: h, SequenceNumber: 0, // ignored, will be overwritten BatcherAddr: sys.RollupConfig.Genesis.SystemConfig.BatcherAddr, - L1FeeOverhead: sys.RollupConfig.Genesis.SystemConfig.Overhead, - L1FeeScalar: sys.RollupConfig.Genesis.SystemConfig.Scalar, + } + if sys.RollupConfig.IsEcotone(b.Time()) && !sys.RollupConfig.IsEcotoneActivationBlock(b.Time()) { + blobBaseFeeScalar, baseFeeScalar, err := sys.RollupConfig.Genesis.SystemConfig.EcotoneScalars() + require.NoError(t, err) + l1blocks[h].BlobBaseFeeScalar = blobBaseFeeScalar + l1blocks[h].BaseFeeScalar = baseFeeScalar + if excess := b.ExcessBlobGas(); excess != nil { + l1blocks[h].BlobBaseFee = eip4844.CalcBlobFee(*excess) + } else { + l1blocks[h].BlobBaseFee = big.NewInt(1) + } + } else { + l1blocks[h].L1FeeOverhead = sys.RollupConfig.Genesis.SystemConfig.Overhead + l1blocks[h].L1FeeScalar = sys.RollupConfig.Genesis.SystemConfig.Scalar } h = b.ParentHash() @@ -920,7 +1026,7 @@ func TestL1InfoContract(t *testing.T) { } } - checkInfoList := func(name string, list []derive.L1BlockInfo) { + checkInfoList := func(name string, list []*derive.L1BlockInfo) { for _, info := range list { if expected, ok := l1blocks[info.BlockHash]; ok { expected.SequenceNumber = info.SequenceNumber // the seq nr is not part of the L1 info we know in advance, so we ignore it. @@ -935,10 +1041,9 @@ func TestL1InfoContract(t *testing.T) { checkInfoList("On sequencer with state", l1InfosFromSequencerState) checkInfoList("On verifier with tx", l1InfosFromVerifierTransactions) checkInfoList("On verifier with state", l1InfosFromVerifierState) - } -// calcGasFees determines the actual cost of the transaction given a specific basefee +// calcGasFees determines the actual cost of the transaction given a specific base fee // This does not include the L1 data fee charged from L2 transactions. func calcGasFees(gasUsed uint64, gasTipCap *big.Int, gasFeeCap *big.Int, baseFee *big.Int) *big.Int { x := new(big.Int).Add(gasTipCap, baseFee) @@ -977,9 +1082,9 @@ func TestWithdrawals(t *testing.T) { require.Nil(t, err) // Start L2 balance - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - startBalance, err := l2Verif.BalanceAt(ctx, fromAddr, nil) + startBalanceBeforeDeposit, err := l2Verif.BalanceAt(ctx, fromAddr, nil) require.Nil(t, err) // Send deposit tx @@ -990,19 +1095,19 @@ func TestWithdrawals(t *testing.T) { }) // Confirm L2 balance - ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - endBalance, err := l2Verif.BalanceAt(ctx, fromAddr, nil) + endBalanceAfterDeposit, err := wait.ForBalanceChange(ctx, l2Verif, fromAddr, startBalanceBeforeDeposit) require.Nil(t, err) diff := new(big.Int) - diff = diff.Sub(endBalance, startBalance) + diff = diff.Sub(endBalanceAfterDeposit, startBalanceBeforeDeposit) require.Equal(t, mintAmount, diff, "Did not get expected balance change after mint") // Start L2 balance for withdrawal - ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - startBalance, err = l2Seq.BalanceAt(ctx, fromAddr, nil) + startBalanceBeforeWithdrawal, err := l2Seq.BalanceAt(ctx, fromAddr, nil) require.Nil(t, err) withdrawAmount := big.NewInt(500_000_000_000) @@ -1012,44 +1117,50 @@ func TestWithdrawals(t *testing.T) { }) // Verify L2 balance after withdrawal - ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() header, err := l2Verif.HeaderByNumber(ctx, receipt.BlockNumber) require.Nil(t, err) - ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - endBalance, err = l2Verif.BalanceAt(ctx, fromAddr, nil) + endBalanceAfterWithdrawal, err := wait.ForBalanceChange(ctx, l2Seq, fromAddr, startBalanceBeforeWithdrawal) require.Nil(t, err) // Take fee into account - diff = new(big.Int).Sub(startBalance, endBalance) + diff = new(big.Int).Sub(startBalanceBeforeWithdrawal, endBalanceAfterWithdrawal) fees := calcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee) fees = fees.Add(fees, receipt.L1Fee) diff = diff.Sub(diff, fees) require.Equal(t, withdrawAmount, diff) // Take start balance on L1 - ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - startBalance, err = l1Client.BalanceAt(ctx, fromAddr, nil) + startBalanceBeforeFinalize, err := l1Client.BalanceAt(ctx, fromAddr, nil) require.Nil(t, err) - proveReceipt, finalizeReceipt := ProveAndFinalizeWithdrawal(t, cfg, l1Client, sys.EthInstances["verifier"], ethPrivKey, receipt) + proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := ProveAndFinalizeWithdrawal(t, cfg, sys, "verifier", ethPrivKey, receipt) // Verify balance after withdrawal - ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - endBalance, err = l1Client.BalanceAt(ctx, fromAddr, nil) + endBalanceAfterFinalize, err := wait.ForBalanceChange(ctx, l1Client, fromAddr, startBalanceBeforeFinalize) require.Nil(t, err) // Ensure that withdrawal - gas fees are added to the L1 balance // Fun fact, the fee is greater than the withdrawal amount // NOTE: The gas fees include *both* the ProveWithdrawalTransaction and FinalizeWithdrawalTransaction transactions. - diff = new(big.Int).Sub(endBalance, startBalance) + diff = new(big.Int).Sub(endBalanceAfterFinalize, startBalanceBeforeFinalize) proveFee := new(big.Int).Mul(new(big.Int).SetUint64(proveReceipt.GasUsed), proveReceipt.EffectiveGasPrice) finalizeFee := new(big.Int).Mul(new(big.Int).SetUint64(finalizeReceipt.GasUsed), finalizeReceipt.EffectiveGasPrice) fees = new(big.Int).Add(proveFee, finalizeFee) + if e2eutils.UseFPAC() { + resolveClaimFee := new(big.Int).Mul(new(big.Int).SetUint64(resolveClaimReceipt.GasUsed), resolveClaimReceipt.EffectiveGasPrice) + resolveFee := new(big.Int).Mul(new(big.Int).SetUint64(resolveReceipt.GasUsed), resolveReceipt.EffectiveGasPrice) + fees = new(big.Int).Add(fees, resolveClaimFee) + fees = new(big.Int).Add(fees, resolveFee) + } withdrawAmount = withdrawAmount.Sub(withdrawAmount, fees) require.Equal(t, withdrawAmount, diff) } @@ -1074,13 +1185,43 @@ func (sga *stateGetterAdapter) GetState(addr common.Address, key common.Hash) co func TestFees(t *testing.T) { //todo temporarily skip this test t.SkipNow() - InitParallel(t) - cfg := DefaultSystemConfig(t) - // This test only works with these config values modified - cfg.DeployConfig.L2GenesisRegolithTimeOffset = nil - cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) + t.Run("pre-regolith", func(t *testing.T) { + InitParallel(t) + cfg := DefaultSystemConfig(t) + cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) + + cfg.DeployConfig.L2GenesisRegolithTimeOffset = nil + cfg.DeployConfig.L2GenesisCanyonTimeOffset = nil + cfg.DeployConfig.L2GenesisDeltaTimeOffset = nil + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = nil + testFees(t, cfg) + }) + t.Run("regolith", func(t *testing.T) { + InitParallel(t) + cfg := DefaultSystemConfig(t) + cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) + + cfg.DeployConfig.L2GenesisRegolithTimeOffset = new(hexutil.Uint64) + cfg.DeployConfig.L2GenesisCanyonTimeOffset = nil + cfg.DeployConfig.L2GenesisDeltaTimeOffset = nil + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = nil + testFees(t, cfg) + }) + t.Run("ecotone", func(t *testing.T) { + InitParallel(t) + cfg := DefaultSystemConfig(t) + cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7)) + + cfg.DeployConfig.L2GenesisRegolithTimeOffset = new(hexutil.Uint64) + cfg.DeployConfig.L2GenesisCanyonTimeOffset = new(hexutil.Uint64) + cfg.DeployConfig.L2GenesisDeltaTimeOffset = new(hexutil.Uint64) + cfg.DeployConfig.L2GenesisEcotoneTimeOffset = new(hexutil.Uint64) + testFees(t, cfg) + }) +} +func testFees(t *testing.T, cfg SystemConfig) { sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") defer sys.Close() @@ -1089,13 +1230,7 @@ func TestFees(t *testing.T) { l2Verif := sys.Clients["verifier"] l1 := sys.Clients["l1"] - config := ¶ms.ChainConfig{ - Optimism: ¶ms.OptimismConfig{ - EIP1559Elasticity: cfg.DeployConfig.EIP1559Elasticity, - EIP1559Denominator: cfg.DeployConfig.EIP1559Denominator, - }, - BedrockBlock: big.NewInt(0), - } + config := sys.L2Genesis().Config sga := &stateGetterAdapter{ ctx: context.Background(), @@ -1116,16 +1251,25 @@ func TestFees(t *testing.T) { gpoContract, err := bindings.NewGasPriceOracle(predeploys.GasPriceOracleAddr, l2Seq) require.Nil(t, err) - overhead, err := gpoContract.Overhead(&bind.CallOpts{}) - require.Nil(t, err, "reading gpo overhead") + if !sys.RollupConfig.IsEcotone(sys.L2GenesisCfg.Timestamp) { + overhead, err := gpoContract.Overhead(&bind.CallOpts{}) + require.Nil(t, err, "reading gpo overhead") + require.Equal(t, overhead.Uint64(), cfg.DeployConfig.GasPriceOracleOverhead, "wrong gpo overhead") + + scalar, err := gpoContract.Scalar(&bind.CallOpts{}) + require.Nil(t, err, "reading gpo scalar") + require.Equal(t, scalar.Uint64(), cfg.DeployConfig.GasPriceOracleScalar, "wrong gpo scalar") + } else { + _, err := gpoContract.Overhead(&bind.CallOpts{}) + require.ErrorContains(t, err, "deprecated") + _, err = gpoContract.Scalar(&bind.CallOpts{}) + require.ErrorContains(t, err, "deprecated") + } + decimals, err := gpoContract.Decimals(&bind.CallOpts{}) require.Nil(t, err, "reading gpo decimals") - scalar, err := gpoContract.Scalar(&bind.CallOpts{}) - require.Nil(t, err, "reading gpo scalar") - require.Equal(t, overhead.Uint64(), cfg.DeployConfig.GasPriceOracleOverhead, "wrong gpo overhead") require.Equal(t, decimals.Uint64(), uint64(6), "wrong gpo decimals") - require.Equal(t, scalar.Uint64(), cfg.DeployConfig.GasPriceOracleScalar, "wrong gpo scalar") // BaseFee Recipient baseFeeRecipientStartBalance, err := l2Seq.BalanceAt(context.Background(), predeploys.BaseFeeVaultAddr, big.NewInt(rpc.EarliestBlockNumber.Int64())) @@ -1205,20 +1349,35 @@ func TestFees(t *testing.T) { bytes, err := tx.MarshalBinary() require.Nil(t, err) - l1Fee := l1CostFn(receipt.BlockNumber.Uint64(), header.Time, tx.RollupDataGas(), tx.IsSystemTx()) + l1Fee := l1CostFn(tx.RollupCostData(), header.Time) require.Equalf(t, l1Fee, l1FeeRecipientDiff, "L1 fee mismatch: start balance %v, end balance %v", l1FeeRecipientStartBalance, l1FeeRecipientEndBalance) + gpoEcotone, err := gpoContract.IsEcotone(nil) + require.NoError(t, err) + require.Equal(t, sys.RollupConfig.IsEcotone(header.Time), gpoEcotone, "GPO and chain must have same ecotone view") + gpoL1Fee, err := gpoContract.GetL1Fee(&bind.CallOpts{}, bytes) require.Nil(t, err) - require.Equal(t, l1Fee, gpoL1Fee, "GPO reports L1 fee mismatch") + + adjustedGPOFee := gpoL1Fee + if sys.RollupConfig.IsRegolith(header.Time) { + // if post-regolith, adjust the GPO fee by removing the overhead it adds because of signature data + artificialGPOOverhead := big.NewInt(68 * 16) // it adds 68 bytes to cover signature and RLP data + l1BaseFee := big.NewInt(7) // we assume the L1 basefee is the minimum, 7 + // in our case we already include that, so we subtract it, to do a 1:1 comparison + adjustedGPOFee = new(big.Int).Sub(gpoL1Fee, new(big.Int).Mul(artificialGPOOverhead, l1BaseFee)) + } + require.Equal(t, l1Fee, adjustedGPOFee, "GPO reports L1 fee mismatch") require.Equal(t, receipt.L1Fee, l1Fee, "l1 fee in receipt is correct") - require.Equal(t, - new(big.Float).Mul( - new(big.Float).SetInt(l1Header.BaseFee), - new(big.Float).Mul(new(big.Float).SetInt(receipt.L1GasUsed), receipt.FeeScalar), - ), - new(big.Float).SetInt(receipt.L1Fee), "fee field in receipt matches gas used times scalar times basefee") + if !sys.RollupConfig.IsEcotone(header.Time) { // FeeScalar receipt attribute is removed as of Ecotone + require.Equal(t, + new(big.Float).Mul( + new(big.Float).SetInt(l1Header.BaseFee), + new(big.Float).Mul(new(big.Float).SetInt(receipt.L1GasUsed), receipt.FeeScalar), + ), + new(big.Float).SetInt(receipt.L1Fee), "fee field in receipt matches gas used times scalar times base fee") + } // Calculate total fee baseFeeRecipientDiff.Add(baseFeeRecipientDiff, coinbaseDiff) @@ -1228,16 +1387,17 @@ func TestFees(t *testing.T) { require.Equal(t, balanceDiff, totalFee, "balances should add up") } -func TestStopStartBatcher(t *testing.T) { +func StopStartBatcher(t *testing.T, deltaTimeOffset *hexutil.Uint64) { InitParallel(t) cfg := DefaultSystemConfig(t) + cfg.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") + require.NoError(t, err, "Error starting up system") defer sys.Close() rollupRPCClient, err := rpc.DialContext(context.Background(), sys.RollupNodes["verifier"].HTTPEndpoint()) - require.Nil(t, err) + require.NoError(t, err) rollupClient := sources.NewRollupClient(client.NewBaseRPCClient(rollupRPCClient)) l2Seq := sys.Clients["sequencer"] @@ -1245,7 +1405,7 @@ func TestStopStartBatcher(t *testing.T) { // retrieve the initial sync status seqStatus, err := rollupClient.SyncStatus(context.Background()) - require.Nil(t, err) + require.NoError(t, err) nonce := uint64(0) sendTx := func() *types.Receipt { @@ -1264,23 +1424,24 @@ func TestStopStartBatcher(t *testing.T) { // wait until the block the tx was first included in shows up in the safe chain on the verifier safeBlockInclusionDuration := time.Duration(6*cfg.DeployConfig.L1BlockTime) * time.Second _, err = geth.WaitForBlock(receipt.BlockNumber, l2Verif, safeBlockInclusionDuration) - require.Nil(t, err, "Waiting for block on verifier") + require.NoError(t, err, "Waiting for block on verifier") + require.NoError(t, wait.ForProcessingFullBatch(context.Background(), rollupClient)) // ensure the safe chain advances newSeqStatus, err := rollupClient.SyncStatus(context.Background()) - require.Nil(t, err) + require.NoError(t, err) require.Greater(t, newSeqStatus.SafeL2.Number, seqStatus.SafeL2.Number, "Safe chain did not advance") // stop the batch submission err = sys.BatchSubmitter.Driver().StopBatchSubmitting(context.Background()) - require.Nil(t, err) + require.NoError(t, err) // wait for any old safe blocks being submitted / derived time.Sleep(safeBlockInclusionDuration) // get the initial sync status seqStatus, err = rollupClient.SyncStatus(context.Background()) - require.Nil(t, err) + require.NoError(t, err) // send another tx sendTx() @@ -1288,12 +1449,12 @@ func TestStopStartBatcher(t *testing.T) { // ensure that the safe chain does not advance while the batcher is stopped newSeqStatus, err = rollupClient.SyncStatus(context.Background()) - require.Nil(t, err) + require.NoError(t, err) require.Equal(t, newSeqStatus.SafeL2.Number, seqStatus.SafeL2.Number, "Safe chain advanced while batcher was stopped") // start the batch submission err = sys.BatchSubmitter.Driver().StartBatchSubmitting() - require.Nil(t, err) + require.NoError(t, err) time.Sleep(safeBlockInclusionDuration) // send a third tx @@ -1301,11 +1462,12 @@ func TestStopStartBatcher(t *testing.T) { // wait until the block the tx was first included in shows up in the safe chain on the verifier _, err = geth.WaitForBlock(receipt.BlockNumber, l2Verif, safeBlockInclusionDuration) - require.Nil(t, err, "Waiting for block on verifier") + require.NoError(t, err, "Waiting for block on verifier") + require.NoError(t, wait.ForProcessingFullBatch(context.Background(), rollupClient)) // ensure that the safe chain advances after restarting the batcher newSeqStatus, err = rollupClient.SyncStatus(context.Background()) - require.Nil(t, err) + require.NoError(t, err) require.Greater(t, newSeqStatus.SafeL2.Number, seqStatus.SafeL2.Number, "Safe chain did not advance after batcher was restarted") } @@ -1313,26 +1475,28 @@ func TestBatcherMultiTx(t *testing.T) { InitParallel(t) cfg := DefaultSystemConfig(t) - cfg.BatcherTargetL1TxSizeBytes = 2 // ensures that batcher txs are as small as possible + cfg.MaxPendingTransactions = 0 // no limit on parallel txs + // ensures that batcher txs are as small as possible + cfg.BatcherMaxL1TxSizeBytes = derive.FrameV0OverHeadSize + 1 /*version bytes*/ + 1 cfg.DisableBatcher = true sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") + require.NoError(t, err, "Error starting up system") defer sys.Close() l1Client := sys.Clients["l1"] l2Seq := sys.Clients["sequencer"] _, err = geth.WaitForBlock(big.NewInt(10), l2Seq, time.Duration(cfg.DeployConfig.L2BlockTime*15)*time.Second) - require.Nil(t, err, "Waiting for L2 blocks") + require.NoError(t, err, "Waiting for L2 blocks") - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() l1Number, err := l1Client.BlockNumber(ctx) - require.Nil(t, err) + require.NoError(t, err) // start batch submission err = sys.BatchSubmitter.Driver().StartBatchSubmitting() - require.Nil(t, err) + require.NoError(t, err) totalTxCount := 0 // wait for up to 10 L1 blocks, usually only 3 is required, but it's @@ -1340,7 +1504,7 @@ func TestBatcherMultiTx(t *testing.T) { // so we wait additional blocks. for i := int64(0); i < 10; i++ { block, err := geth.WaitForBlock(big.NewInt(int64(l1Number)+i), l1Client, time.Duration(cfg.DeployConfig.L1BlockTime*5)*time.Second) - require.Nil(t, err, "Waiting for l1 blocks") + require.NoError(t, err, "Waiting for l1 blocks") totalTxCount += len(block.Transactions()) if totalTxCount >= 10 { @@ -1352,7 +1516,7 @@ func TestBatcherMultiTx(t *testing.T) { } func latestBlock(t *testing.T, client *ethclient.Client) uint64 { - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() blockAfter, err := client.BlockNumber(ctx) require.Nil(t, err, "Error getting latest block") @@ -1548,7 +1712,7 @@ func TestRequiredProtocolVersionChangeAndHalt(t *testing.T) { // Checking if the engine is down is not trivial in op-e2e. // In op-geth we have halting tests covering the Engine API, in op-e2e we instead check if the API stops. _, err = retry.Do(context.Background(), 10, retry.Fixed(time.Second*10), func() (struct{}, error) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) _, err := sys.Clients["verifier"].ChainID(ctx) cancel() if err != nil && !errors.Is(err, ctx.Err()) { // waiting for client to stop responding to chainID requests diff --git a/op-e2e/system_tob_test.go b/op-e2e/system_tob_test.go index 7e183cb8247e..c043b2d350b5 100644 --- a/op-e2e/system_tob_test.go +++ b/op-e2e/system_tob_test.go @@ -11,11 +11,14 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/bindingspreview" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" - "github.com/ethereum-optimism/optimism/op-node/withdrawals" "github.com/ethereum-optimism/optimism/op-service/testutils/fuzzerutils" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/abi" @@ -33,6 +36,9 @@ import ( // TestGasPriceOracleFeeUpdates checks that the gas price oracle cannot be locked by mis-configuring parameters. func TestGasPriceOracleFeeUpdates(t *testing.T) { + ctx, ctxCancel := context.WithCancel(context.Background()) + defer ctxCancel() + InitParallel(t) // Define our values to set in the GasPriceOracle (we set them high to see if it can lock L2 or stop bindings // from updating the prices once again. @@ -66,16 +72,15 @@ func TestGasPriceOracleFeeUpdates(t *testing.T) { txTimeoutDuration := 10 * time.Duration(cfg.DeployConfig.L1BlockTime) * time.Second // Update the gas config, wait for it to show up on L2, & verify that it was set as intended - opts.Context, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) + opts.Context, cancel = context.WithTimeout(ctx, txTimeoutDuration) tx, err := sysconfig.SetGasConfig(opts, overheadValue, scalarValue) cancel() require.Nil(t, err, "sending overhead update tx") - receipt, err := geth.WaitForTransaction(tx.Hash(), l1Client, txTimeoutDuration) - require.Nil(t, err, "waiting for sysconfig set gas config update tx") - require.Equal(t, receipt.Status, types.ReceiptStatusSuccessful, "transaction failed") + receipt, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash()) + require.Nil(t, err, "Waiting for sysconfig set gas config update tx") - _, err = geth.WaitForL1OriginOnL2(receipt.BlockNumber.Uint64(), l2Seq, txTimeoutDuration) + _, err = geth.WaitForL1OriginOnL2(sys.RollupConfig, receipt.BlockNumber.Uint64(), l2Seq, txTimeoutDuration) require.NoError(t, err, "waiting for L2 block to include the sysconfig update") gpoOverhead, err := gpoContract.Overhead(&bind.CallOpts{}) @@ -98,11 +103,10 @@ func TestGasPriceOracleFeeUpdates(t *testing.T) { cancel() require.Nil(t, err, "sending overhead update tx") - receipt, err = geth.WaitForTransaction(tx.Hash(), l1Client, txTimeoutDuration) - require.Nil(t, err, "waiting for sysconfig set gas config update tx") - require.Equal(t, receipt.Status, types.ReceiptStatusSuccessful, "transaction failed") + receipt, err = wait.ForReceiptOK(ctx, l1Client, tx.Hash()) + require.Nil(t, err, "Waiting for sysconfig set gas config update tx") - _, err = geth.WaitForL1OriginOnL2(receipt.BlockNumber.Uint64(), l2Seq, txTimeoutDuration) + _, err = geth.WaitForL1OriginOnL2(sys.RollupConfig, receipt.BlockNumber.Uint64(), l2Seq, txTimeoutDuration) require.NoError(t, err, "waiting for L2 block to include the sysconfig update") gpoOverhead, err = gpoContract.Overhead(&bind.CallOpts{}) @@ -132,7 +136,7 @@ func TestL2SequencerRPCDepositTx(t *testing.T) { // Obtain our sequencer, verifier, and transactor keypair. l2Seq := sys.Clients["sequencer"] l2Verif := sys.Clients["verifier"] - txSigningKey := sys.cfg.Secrets.Alice + txSigningKey := sys.Cfg.Secrets.Alice require.Nil(t, err) // Create a deposit tx to send over RPC. @@ -292,7 +296,7 @@ func TestMixedDepositValidity(t *testing.T) { } // Create our random provider - randomProvider := rand.New(rand.NewSource(time.Now().Unix())) + randomProvider := rand.New(rand.NewSource(1452)) // Now we create a number of deposits from each transactor for i := 0; i < depositTxCount; i++ { @@ -394,10 +398,14 @@ func TestMixedWithdrawalValidity(t *testing.T) { for i := 0; i <= 8; i++ { i := i // avoid loop var capture t.Run(fmt.Sprintf("withdrawal test#%d", i+1), func(t *testing.T) { + ctx, bgCancel := context.WithCancel(context.Background()) + defer bgCancel() + InitParallel(t) // Create our system configuration, funding all accounts we created for L1/L2, and start it cfg := DefaultSystemConfig(t) + cfg.Nodes["sequencer"].SafeDBPath = t.TempDir() cfg.DeployConfig.L2BlockTime = 2 require.LessOrEqual(t, cfg.DeployConfig.FinalizationPeriodSeconds, uint64(6)) require.Equal(t, cfg.DeployConfig.FundDevAccounts, true) @@ -442,6 +450,12 @@ func TestMixedWithdrawalValidity(t *testing.T) { require.NoError(t, err) require.Equal(t, cfg.DeployConfig.FinalizationPeriodSeconds, finalizationPeriod.Uint64()) + disputeGameFactory, err := bindings.NewDisputeGameFactoryCaller(cfg.L1Deployments.DisputeGameFactoryProxy, l1Client) + require.NoError(t, err) + + optimismPortal2, err := bindingspreview.NewOptimismPortal2Caller(cfg.L1Deployments.OptimismPortalProxy, l1Client) + require.NoError(t, err) + // Create a struct used to track our transactors and their transactions sent. type TestAccountState struct { Account *TestAccount @@ -470,15 +484,15 @@ func TestMixedWithdrawalValidity(t *testing.T) { require.NoError(t, err) // Obtain the transactor's starting balance on L1. - ctx, cancel := context.WithTimeout(context.Background(), txTimeoutDuration) - transactor.ExpectedL1Balance, err = l1Client.BalanceAt(ctx, transactor.Account.L1Opts.From, nil) - cancel() + txCtx, txCancel := context.WithTimeout(context.Background(), txTimeoutDuration) + transactor.ExpectedL1Balance, err = l1Client.BalanceAt(txCtx, transactor.Account.L1Opts.From, nil) + txCancel() require.NoError(t, err) // Obtain the transactor's starting balance on L2. - ctx, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) - transactor.ExpectedL2Balance, err = l2Verif.BalanceAt(ctx, transactor.Account.L2Opts.From, nil) - cancel() + txCtx, txCancel = context.WithTimeout(context.Background(), txTimeoutDuration) + transactor.ExpectedL2Balance, err = l2Verif.BalanceAt(txCtx, transactor.Account.L2Opts.From, nil) + txCancel() require.NoError(t, err) // Bind to the L2-L1 message passer @@ -505,23 +519,20 @@ func TestMixedWithdrawalValidity(t *testing.T) { require.Nil(t, err, "sending initiate withdraw tx") t.Logf("Waiting for tx %s to be in sequencer", tx.Hash().Hex()) - receiptSeq, err := geth.WaitForTransaction(tx.Hash(), l2Seq, txTimeoutDuration) + receiptSeq, err := wait.ForReceiptOK(ctx, l2Seq, tx.Hash()) require.Nil(t, err, "withdrawal initiated on L2 sequencer") - require.Equal(t, receiptSeq.Status, types.ReceiptStatusSuccessful, "transaction failed") verifierTip, err := l2Verif.BlockByNumber(context.Background(), nil) require.Nil(t, err) t.Logf("Waiting for tx %s to be in verifier. Verifier tip is %s:%d. Included in sequencer in block %s:%d", tx.Hash().Hex(), verifierTip.Hash().Hex(), verifierTip.NumberU64(), receiptSeq.BlockHash.Hex(), receiptSeq.BlockNumber) - // Wait for the transaction to appear in L2 verifier - receipt, err := geth.WaitForTransaction(tx.Hash(), l2Verif, txTimeoutDuration) + receipt, err := wait.ForReceiptOK(ctx, l2Verif, tx.Hash()) require.Nilf(t, err, "withdrawal tx %s not found in verifier. included in block %s:%d", tx.Hash().Hex(), receiptSeq.BlockHash.Hex(), receiptSeq.BlockNumber) - require.Equal(t, receipt.Status, types.ReceiptStatusSuccessful, "transaction failed") // Obtain the header for the block containing the transaction (used to calculate gas fees) - ctx, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) - header, err := l2Verif.HeaderByNumber(ctx, receipt.BlockNumber) - cancel() + txCtx, txCancel = context.WithTimeout(context.Background(), txTimeoutDuration) + header, err := l2Verif.HeaderByNumber(txCtx, receipt.BlockNumber) + txCancel() require.Nil(t, err) // Calculate gas fees for the withdrawal in L2 to later adjust our balance. @@ -534,35 +545,38 @@ func TestMixedWithdrawalValidity(t *testing.T) { transactor.ExpectedL2Nonce = transactor.ExpectedL2Nonce + 1 // Wait for the finalization period, then we can finalize this withdrawal. - ctx, cancel = context.WithTimeout(context.Background(), 40*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) require.NotEqual(t, cfg.L1Deployments.L2OutputOracleProxy, common.Address{}) - blockNumber, err := wait.ForOutputRootPublished(ctx, l1Client, cfg.L1Deployments.L2OutputOracleProxy, receipt.BlockNumber) - cancel() + var blockNumber uint64 + if e2eutils.UseFPAC() { + blockNumber, err = wait.ForGamePublished(ctx, l1Client, cfg.L1Deployments.OptimismPortalProxy, cfg.L1Deployments.DisputeGameFactoryProxy, receipt.BlockNumber) + } else { + blockNumber, err = wait.ForOutputRootPublished(ctx, l1Client, cfg.L1Deployments.L2OutputOracleProxy, receipt.BlockNumber) + } require.Nil(t, err) - ctx, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) header, err = l2Verif.HeaderByNumber(ctx, new(big.Int).SetUint64(blockNumber)) - cancel() require.Nil(t, err) rpcClient, err := rpc.Dial(sys.EthInstances["verifier"].WSEndpoint()) require.Nil(t, err) proofCl := gethclient.New(rpcClient) receiptCl := ethclient.NewClient(rpcClient) + blockCl := ethclient.NewClient(rpcClient) // Now create the withdrawal - params, err := withdrawals.ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, tx.Hash(), header, l2OutputOracle) + params, err := ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, blockCl, tx.Hash(), header, l2OutputOracle, disputeGameFactory, optimismPortal2) require.Nil(t, err) // Obtain our withdrawal parameters - withdrawalTransaction := &bindings.TypesWithdrawalTransaction{ + withdrawal := crossdomain.Withdrawal{ Nonce: params.Nonce, - Sender: params.Sender, - Target: params.Target, + Sender: ¶ms.Sender, + Target: ¶ms.Target, Value: params.Value, GasLimit: params.GasLimit, Data: params.Data, } + withdrawalTransaction := withdrawal.WithdrawalTransaction() l2OutputIndexParam := params.L2OutputIndex outputRootProofParam := params.OutputRootProof withdrawalProofParam := params.WithdrawalProof @@ -625,7 +639,7 @@ func TestMixedWithdrawalValidity(t *testing.T) { // Prove withdrawal. This checks the proof so we only finalize if this succeeds tx, err = depositContract.ProveWithdrawalTransaction( transactor.Account.L1Opts, - *withdrawalTransaction, + withdrawalTransaction, l2OutputIndexParam, outputRootProofParam, withdrawalProofParam, @@ -639,15 +653,19 @@ func TestMixedWithdrawalValidity(t *testing.T) { } else { require.NoError(t, err) - receipt, err = geth.WaitForTransaction(tx.Hash(), l1Client, txTimeoutDuration) - require.Nil(t, err, "finalize withdrawal") - require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) + if e2eutils.UseFPAC() { + // Start a challenger to resolve claims and games once the clock expires + factoryHelper := disputegame.NewFactoryHelper(t, ctx, sys) + factoryHelper.StartChallenger(ctx, "Challenger", + challenger.WithCannon(t, sys.RollupConfig, sys.L2GenesisCfg, sys.RollupEndpoint("sequencer"), sys.NodeEndpoint("sequencer")), + challenger.WithPrivKey(sys.Cfg.Secrets.Mallory)) + } + receipt, err = wait.ForReceiptOK(ctx, l1Client, tx.Hash()) + require.NoError(t, err, "finalize withdrawal") // Verify balance after withdrawal - ctx, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) header, err = l1Client.HeaderByNumber(ctx, receipt.BlockNumber) - cancel() - require.Nil(t, err) + require.NoError(t, err) // Ensure that withdrawal - gas fees are added to the L1 balance // Fun fact, the fee is greater than the withdrawal amount @@ -657,20 +675,24 @@ func TestMixedWithdrawalValidity(t *testing.T) { transactor.ExpectedL1Nonce++ // Ensure that our withdrawal was proved successfully - proveReceipt, err := geth.WaitForTransaction(tx.Hash(), l1Client, 3*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) - require.Nil(t, err, "prove withdrawal") - require.Equal(t, types.ReceiptStatusSuccessful, proveReceipt.Status) + _, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash()) + require.NoError(t, err, "prove withdrawal") // Wait for finalization and then create the Finalized Withdrawal Transaction - ctx, cancel = context.WithTimeout(context.Background(), 45*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) - defer cancel() - err = wait.ForFinalizationPeriod(ctx, l1Client, header.Number, cfg.L1Deployments.L2OutputOracleProxy) - require.Nil(t, err) + ctx, withdrawalCancel := context.WithTimeout(context.Background(), 60*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) + defer withdrawalCancel() + if e2eutils.UseFPAC() { + err = wait.ForWithdrawalCheck(ctx, l1Client, withdrawal, cfg.L1Deployments.OptimismPortalProxy) + require.NoError(t, err) + } else { + err = wait.ForFinalizationPeriod(ctx, l1Client, header.Number, cfg.L1Deployments.L2OutputOracleProxy) + require.NoError(t, err) + } // Finalize withdrawal _, err = depositContract.FinalizeWithdrawalTransaction( transactor.Account.L1Opts, - *withdrawalTransaction, + withdrawalTransaction, ) require.NoError(t, err) } @@ -678,39 +700,27 @@ func TestMixedWithdrawalValidity(t *testing.T) { // At the end, assert our account balance/nonce states. // Obtain the L2 sequencer account balance - ctx, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) endL1Balance, err := l1Client.BalanceAt(ctx, transactor.Account.L1Opts.From, nil) - cancel() require.NoError(t, err) // Obtain the L1 account nonce - ctx, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) endL1Nonce, err := l1Client.NonceAt(ctx, transactor.Account.L1Opts.From, nil) - cancel() require.NoError(t, err) // Obtain the L2 sequencer account balance - ctx, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) endL2SeqBalance, err := l2Seq.BalanceAt(ctx, transactor.Account.L1Opts.From, nil) - cancel() require.NoError(t, err) // Obtain the L2 sequencer account nonce - ctx, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) endL2SeqNonce, err := l2Seq.NonceAt(ctx, transactor.Account.L1Opts.From, nil) - cancel() require.NoError(t, err) // Obtain the L2 verifier account balance - ctx, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) endL2VerifBalance, err := l2Verif.BalanceAt(ctx, transactor.Account.L1Opts.From, nil) - cancel() require.NoError(t, err) // Obtain the L2 verifier account nonce - ctx, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) endL2VerifNonce, err := l2Verif.NonceAt(ctx, transactor.Account.L1Opts.From, nil) - cancel() require.NoError(t, err) // TODO: Check L1 balance as well here. We avoided this due to time constraints as it seems L1 fees diff --git a/op-e2e/tracer.go b/op-e2e/tracer.go index 37977177babc..217c1762082a 100644 --- a/op-e2e/tracer.go +++ b/op-e2e/tracer.go @@ -11,8 +11,8 @@ import ( type FnTracer struct { OnNewL1HeadFn func(ctx context.Context, sig eth.L1BlockRef) - OnUnsafeL2PayloadFn func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) - OnPublishL2PayloadFn func(ctx context.Context, payload *eth.ExecutionPayload) + OnUnsafeL2PayloadFn func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) + OnPublishL2PayloadFn func(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) } func (n *FnTracer) OnNewL1Head(ctx context.Context, sig eth.L1BlockRef) { @@ -21,13 +21,13 @@ func (n *FnTracer) OnNewL1Head(ctx context.Context, sig eth.L1BlockRef) { } } -func (n *FnTracer) OnUnsafeL2Payload(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) { +func (n *FnTracer) OnUnsafeL2Payload(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { if n.OnUnsafeL2PayloadFn != nil { n.OnUnsafeL2PayloadFn(ctx, from, payload) } } -func (n *FnTracer) OnPublishL2Payload(ctx context.Context, payload *eth.ExecutionPayload) { +func (n *FnTracer) OnPublishL2Payload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { if n.OnPublishL2PayloadFn != nil { n.OnPublishL2PayloadFn(ctx, payload) } diff --git a/op-e2e/tx_helper.go b/op-e2e/tx_helper.go index eb07e80703e8..2c930801ad1a 100644 --- a/op-e2e/tx_helper.go +++ b/op-e2e/tx_helper.go @@ -7,8 +7,9 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -40,16 +41,17 @@ func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l require.Nil(t, err, "with deposit tx") // Wait for transaction on L1 - l1Receipt, err := geth.WaitForTransaction(tx.Hash(), l1Client, 10*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + l1Receipt, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash()) require.Nil(t, err, "Waiting for deposit tx on L1") // Wait for transaction to be included on L2 reconstructedDep, err := derive.UnmarshalDepositLogEvent(l1Receipt.Logs[0]) require.NoError(t, err, "Could not reconstruct L2 Deposit") tx = types.NewTx(reconstructedDep) - l2Receipt, err := geth.WaitForTransaction(tx.Hash(), l2Client, 10*time.Duration(cfg.DeployConfig.L2BlockTime)*time.Second) - require.NoError(t, err) - require.Equal(t, l2Opts.ExpectedStatus, l2Receipt.Status, "l2 transaction status") + l2Receipt, err := wait.ForReceipt(ctx, l2Client, tx.Hash(), l2Opts.ExpectedStatus) + require.NoError(t, err, "Waiting for deposit tx on L2") return l2Receipt } @@ -90,19 +92,20 @@ func SendL2Tx(t *testing.T, cfg SystemConfig, l2Client *ethclient.Client, privKe GasTipCap: opts.GasTipCap, GasFeeCap: opts.GasFeeCap, Gas: opts.Gas, + Data: opts.Data, }) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() err := l2Client.SendTransaction(ctx, tx) require.NoError(t, err, "Sending L2 tx") - receipt, err := geth.WaitForTransaction(tx.Hash(), l2Client, 10*time.Duration(cfg.DeployConfig.L2BlockTime)*time.Second) + receipt, err := wait.ForReceiptOK(ctx, l2Client, tx.Hash()) require.NoError(t, err, "Waiting for L2 tx") require.Equal(t, opts.ExpectedStatus, receipt.Status, "TX should have expected status") for i, client := range opts.VerifyClients { t.Logf("Waiting for tx %v on verification client %d", tx.Hash(), i) - receiptVerif, err := geth.WaitForTransaction(tx.Hash(), client, 10*time.Duration(cfg.DeployConfig.L2BlockTime)*time.Second) + receiptVerif, err := wait.ForReceiptOK(ctx, client, tx.Hash()) require.NoErrorf(t, err, "Waiting for L2 tx on verification client %d", i) require.Equalf(t, receipt, receiptVerif, "Receipts should be the same on sequencer and verification client %d", i) } diff --git a/op-e2e/withdrawal_helper.go b/op-e2e/withdrawal_helper.go index 90617db1ac66..f0457d105db0 100644 --- a/op-e2e/withdrawal_helper.go +++ b/op-e2e/withdrawal_helper.go @@ -8,8 +8,11 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/bindingspreview" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain" "github.com/ethereum-optimism/optimism/op-e2e/config" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-node/withdrawals" @@ -18,10 +21,13 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient/gethclient" - "github.com/ethereum/go-ethereum/rpc" "github.com/stretchr/testify/require" ) +type ClientProvider interface { + NodeClient(name string) *ethclient.Client +} + func SendWithdrawal(t *testing.T, cfg SystemConfig, l2Client *ethclient.Client, privKey *ecdsa.PrivateKey, applyOpts WithdrawalTxOptsFn) (*types.Transaction, *types.Receipt) { opts := defaultWithdrawalTxOpts() applyOpts(opts) @@ -79,24 +85,31 @@ func defaultWithdrawalTxOpts() *WithdrawalTxOpts { } } -func ProveAndFinalizeWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l2Node EthInstance, ethPrivKey *ecdsa.PrivateKey, l2WithdrawalReceipt *types.Receipt) (*types.Receipt, *types.Receipt) { - params, proveReceipt := ProveWithdrawal(t, cfg, l1Client, l2Node, ethPrivKey, l2WithdrawalReceipt) - finalizeReceipt := FinalizeWithdrawal(t, cfg, l1Client, ethPrivKey, proveReceipt, params) - return proveReceipt, finalizeReceipt +func ProveAndFinalizeWithdrawal(t *testing.T, cfg SystemConfig, clients ClientProvider, l2NodeName string, ethPrivKey *ecdsa.PrivateKey, l2WithdrawalReceipt *types.Receipt) (*types.Receipt, *types.Receipt, *types.Receipt, *types.Receipt) { + params, proveReceipt := ProveWithdrawal(t, cfg, clients, l2NodeName, ethPrivKey, l2WithdrawalReceipt) + finalizeReceipt, resolveClaimReceipt, resolveReceipt := FinalizeWithdrawal(t, cfg, clients.NodeClient("l1"), ethPrivKey, proveReceipt, params) + return proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt } -func ProveWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l2Node EthInstance, ethPrivKey *ecdsa.PrivateKey, l2WithdrawalReceipt *types.Receipt) (withdrawals.ProvenWithdrawalParameters, *types.Receipt) { +func ProveWithdrawal(t *testing.T, cfg SystemConfig, clients ClientProvider, l2NodeName string, ethPrivKey *ecdsa.PrivateKey, l2WithdrawalReceipt *types.Receipt) (withdrawals.ProvenWithdrawalParameters, *types.Receipt) { // Get l2BlockNumber for proof generation ctx, cancel := context.WithTimeout(context.Background(), 40*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) defer cancel() - blockNumber, err := wait.ForOutputRootPublished(ctx, l1Client, config.L1Deployments.L2OutputOracleProxy, l2WithdrawalReceipt.BlockNumber) - require.Nil(t, err) + l1Client := clients.NodeClient("l1") + var blockNumber uint64 + var err error + if e2eutils.UseFPAC() { + blockNumber, err = wait.ForGamePublished(ctx, l1Client, config.L1Deployments.OptimismPortalProxy, config.L1Deployments.DisputeGameFactoryProxy, l2WithdrawalReceipt.BlockNumber) + require.Nil(t, err) + } else { + blockNumber, err = wait.ForOutputRootPublished(ctx, l1Client, config.L1Deployments.L2OutputOracleProxy, l2WithdrawalReceipt.BlockNumber) + require.Nil(t, err) + } - rpcClient, err := rpc.Dial(l2Node.WSEndpoint()) - require.Nil(t, err) - proofCl := gethclient.New(rpcClient) - receiptCl := ethclient.NewClient(rpcClient) + receiptCl := clients.NodeClient(l2NodeName) + blockCl := clients.NodeClient(l2NodeName) + proofCl := gethclient.New(receiptCl.Client()) ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() @@ -104,11 +117,16 @@ func ProveWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, header, err := receiptCl.HeaderByNumber(ctx, new(big.Int).SetUint64(blockNumber)) require.Nil(t, err) - // Now create withdrawal oracle, err := bindings.NewL2OutputOracleCaller(config.L1Deployments.L2OutputOracleProxy, l1Client) require.Nil(t, err) - params, err := withdrawals.ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, l2WithdrawalReceipt.TxHash, header, oracle) + factory, err := bindings.NewDisputeGameFactoryCaller(config.L1Deployments.DisputeGameFactoryProxy, l1Client) + require.Nil(t, err) + + portal2, err := bindingspreview.NewOptimismPortal2Caller(config.L1Deployments.OptimismPortalProxy, l1Client) + require.Nil(t, err) + + params, err := ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, blockCl, l2WithdrawalReceipt.TxHash, header, oracle, factory, portal2) require.Nil(t, err) portal, err := bindings.NewOptimismPortal(config.L1Deployments.OptimismPortalProxy, l1Client) @@ -141,35 +159,84 @@ func ProveWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, return params, proveReceipt } -func FinalizeWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, privKey *ecdsa.PrivateKey, withdrawalProofReceipt *types.Receipt, params withdrawals.ProvenWithdrawalParameters) *types.Receipt { +func ProveWithdrawalParameters(ctx context.Context, proofCl withdrawals.ProofClient, l2ReceiptCl withdrawals.ReceiptClient, l2BlockCl withdrawals.BlockClient, txHash common.Hash, header *types.Header, l2OutputOracleContract *bindings.L2OutputOracleCaller, disputeGameFactoryContract *bindings.DisputeGameFactoryCaller, optimismPortal2Contract *bindingspreview.OptimismPortal2Caller) (withdrawals.ProvenWithdrawalParameters, error) { + if e2eutils.UseFPAC() { + return withdrawals.ProveWithdrawalParametersFPAC(ctx, proofCl, l2ReceiptCl, l2BlockCl, txHash, disputeGameFactoryContract, optimismPortal2Contract) + } else { + return withdrawals.ProveWithdrawalParameters(ctx, proofCl, l2ReceiptCl, l2BlockCl, txHash, header, l2OutputOracleContract) + } +} + +func FinalizeWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, privKey *ecdsa.PrivateKey, withdrawalProofReceipt *types.Receipt, params withdrawals.ProvenWithdrawalParameters) (*types.Receipt, *types.Receipt, *types.Receipt) { // Wait for finalization and then create the Finalized Withdrawal Transaction ctx, cancel := context.WithTimeout(context.Background(), 30*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) defer cancel() - err := wait.ForFinalizationPeriod(ctx, l1Client, withdrawalProofReceipt.BlockNumber, config.L1Deployments.L2OutputOracleProxy) - require.Nil(t, err) + wd := crossdomain.Withdrawal{ + Nonce: params.Nonce, + Sender: ¶ms.Sender, + Target: ¶ms.Target, + Value: params.Value, + GasLimit: params.GasLimit, + Data: params.Data, + } opts, err := bind.NewKeyedTransactorWithChainID(privKey, cfg.L1ChainIDBig()) require.Nil(t, err) + + var resolveClaimReceipt *types.Receipt + var resolveReceipt *types.Receipt + if e2eutils.UseFPAC() { + portal2, err := bindingspreview.NewOptimismPortal2(config.L1Deployments.OptimismPortalProxy, l1Client) + require.Nil(t, err) + + wdHash, err := wd.Hash() + require.Nil(t, err) + + game, err := portal2.ProvenWithdrawals(&bind.CallOpts{}, wdHash) + require.Nil(t, err) + require.NotNil(t, game, "withdrawal should be proven") + + proxy, err := bindings.NewFaultDisputeGame(game.DisputeGameProxy, l1Client) + require.Nil(t, err) + + expiry, err := proxy.GameDuration(&bind.CallOpts{}) + require.Nil(t, err) + + time.Sleep(time.Duration(expiry) * time.Second) + resolveClaimTx, err := proxy.ResolveClaim(opts, common.Big0) + require.Nil(t, err) + + resolveClaimReceipt, err = wait.ForReceiptOK(ctx, l1Client, resolveClaimTx.Hash()) + require.Nil(t, err, "resolve claim") + require.Equal(t, types.ReceiptStatusSuccessful, resolveClaimReceipt.Status) + + resolveTx, err := proxy.Resolve(opts) + require.Nil(t, err) + + resolveReceipt, err = wait.ForReceiptOK(ctx, l1Client, resolveTx.Hash()) + require.Nil(t, err, "resolve") + require.Equal(t, types.ReceiptStatusSuccessful, resolveReceipt.Status) + } + + if e2eutils.UseFPAC() { + err := wait.ForWithdrawalCheck(ctx, l1Client, wd, config.L1Deployments.OptimismPortalProxy) + require.Nil(t, err) + } else { + err := wait.ForFinalizationPeriod(ctx, l1Client, withdrawalProofReceipt.BlockNumber, config.L1Deployments.L2OutputOracleProxy) + require.Nil(t, err) + } + portal, err := bindings.NewOptimismPortal(config.L1Deployments.OptimismPortalProxy, l1Client) require.Nil(t, err) + // Finalize withdrawal - tx, err := portal.FinalizeWithdrawalTransaction( - opts, - bindings.TypesWithdrawalTransaction{ - Nonce: params.Nonce, - Sender: params.Sender, - Target: params.Target, - Value: params.Value, - GasLimit: params.GasLimit, - Data: params.Data, - }, - ) + tx, err := portal.FinalizeWithdrawalTransaction(opts, wd.WithdrawalTransaction()) require.Nil(t, err) // Ensure that our withdrawal was finalized successfully - finalizeReceipt, err := geth.WaitForTransaction(tx.Hash(), l1Client, 3*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) + finalizeReceipt, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash()) require.Nil(t, err, "finalize withdrawal") require.Equal(t, types.ReceiptStatusSuccessful, finalizeReceipt.Status) - return finalizeReceipt + return finalizeReceipt, resolveClaimReceipt, resolveReceipt } diff --git a/op-exporter/.gitignore b/op-exporter/.gitignore deleted file mode 100644 index 10cfd60097ae..000000000000 --- a/op-exporter/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -op_exporter -.env \ No newline at end of file diff --git a/op-exporter/CHANGELOG.md b/op-exporter/CHANGELOG.md deleted file mode 100644 index 5fe8819eb1a5..000000000000 --- a/op-exporter/CHANGELOG.md +++ /dev/null @@ -1,32 +0,0 @@ -# @eth-optimism/op-exporter - -## 0.5.5 - -### Patch Changes - -- [#7450](https://github.com/ethereum-optimism/optimism/pull/7450) [`ac90e16a7`](https://github.com/ethereum-optimism/optimism/commit/ac90e16a7f85c4f73661ae6023135c3d00421c1e) Thanks [@roninjin10](https://github.com/roninjin10)! - Updated dev dependencies related to testing that is causing audit tooling to report failures - -## 0.5.4 - -### Patch Changes - -- 160f4c3d: Update docker image to use golang 1.18.0 - -## 0.5.3 - -### Patch Changes - -- 673bfcc4: Fixes panic caused by version initialized to nil -- c7e6bed3: Added version metrics - -## 0.5.2 - -### Patch Changes - -- 5877f230: force rebuild - -## 0.5.1 - -### Patch Changes - -- 3f563420: Cleanup op-exporter CI, renamed package diff --git a/op-exporter/Dockerfile b/op-exporter/Dockerfile deleted file mode 100644 index f9207dab71be..000000000000 --- a/op-exporter/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM golang:1.20.7-alpine3.18 as builder - -# build from root of repo -COPY ./op-exporter /app - -WORKDIR /app/ -RUN apk --no-cache add make bash jq git -RUN make build - -FROM alpine:3.18 -RUN apk --no-cache add ca-certificates -WORKDIR /root/ -COPY --from=builder /app/op-exporter /usr/local/bin/ -ENTRYPOINT ["op-exporter"] -CMD ["--help"] diff --git a/op-exporter/Makefile b/op-exporter/Makefile deleted file mode 100644 index 4880c7316243..000000000000 --- a/op-exporter/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -SHELL := /bin/bash - -ifndef VERSION -VERSION := `jq .version package.json ` -endif -ifndef GITCOMMIT -GITCOMMIT := `git rev-parse HEAD` -endif -ifndef BUILDDATE -BUILDDATE := `date +%Y-%m-%d` -endif - -LDFLAGSSTRING :=-X github.com/ethereum-optimism/op-exporter/version.Version=$(VERSION) -LDFLAGSSTRING +=-X github.com/ethereum-optimism/op-exporter/version.GitCommit=$(GITCOMMIT) -LDFLAGSSTRING +=-X github.com/ethereum-optimism/op-exporter/version.BuildDate=$(BUILDDATE) - -LDFLAGS :=-ldflags "$(LDFLAGSSTRING)" - -.PHONY: all build - -all: build - -# Build binary -build: - CGO_ENABLED=0 go build $(LDFLAGS) - -lint: - golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./... diff --git a/op-exporter/README.md b/op-exporter/README.md deleted file mode 100644 index 038996f9dff8..000000000000 --- a/op-exporter/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# op_exporter - -A prometheus exporter to collect information from an Optimism node and serve metrics for collection - -## Usage - -``` -make build && ./op_exporter --rpc.provider="https://kovan-sequencer.optimism.io" --label.network="kovan" -``` - -## Health endpoint `/health` - -Returns json describing the health of the sequencer based on the time since a block height update. - -``` -$ curl http://localhost:9100/health -{ "healthy": "false" } -``` - -## Metrics endpoint `/metrics` - -``` -# HELP op_gasPrice Gas price. -# TYPE op_gasPrice gauge -op_gasPrice{layer="layer1",network="kovan"} 6.9e+09 -op_gasPrice{layer="layer2",network="kovan"} 1 -``` diff --git a/op-exporter/collector.go b/op-exporter/collector.go deleted file mode 100644 index 6aedbed71949..000000000000 --- a/op-exporter/collector.go +++ /dev/null @@ -1,55 +0,0 @@ -package main - -import ( - "github.com/prometheus/client_golang/prometheus" -) - -//Define the metrics we wish to expose -var ( - gasBaseFeeMetric = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "op_baseFee", - Help: "Gas base fee."}, - []string{"network", "layer"}, - ) - gasUsedMetric = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "op_gasUsed", - Help: "Gas Used."}, - []string{"network", "layer"}, - ) - gasPrice = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "op_gasPrice", - Help: "Gas price."}, - []string{"network", "layer"}, - ) - blockNumber = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "op_blocknumber", - Help: "Current block number."}, - []string{"network", "layer"}, - ) - healthySequencer = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "op_healthy_sequencer", - Help: "Is the sequencer healthy?"}, - []string{"network"}, - ) - opExporterVersion = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "op_exporter_version", - Help: "Verion of the op-exporter software"}, - []string{"version", "commit", "goVersion", "buildDate"}, - ) -) - -func init() { - //Register metrics with prometheus - prometheus.MustRegister(gasPrice) - prometheus.MustRegister(blockNumber) - prometheus.MustRegister(healthySequencer) - prometheus.MustRegister(opExporterVersion) - prometheus.MustRegister(gasBaseFeeMetric) - prometheus.MustRegister(gasUsedMetric) -} diff --git a/op-exporter/go.mod b/op-exporter/go.mod deleted file mode 100644 index 0fe7d7a141f2..000000000000 --- a/op-exporter/go.mod +++ /dev/null @@ -1,50 +0,0 @@ -module github.com/ethereum-optimism/optimism/op-exporter - -go 1.20 - -require ( - github.com/ethereum/go-ethereum v1.12.1 - github.com/prometheus/client_golang v1.14.0 - github.com/sirupsen/logrus v1.7.0 - github.com/ybbus/jsonrpc v2.1.2+incompatible - gopkg.in/alecthomas/kingpin.v2 v2.2.6 - k8s.io/apimachinery v0.21.2 - k8s.io/client-go v0.21.2 -) - -require ( - github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect - github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-logr/logr v0.4.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa // indirect - github.com/googleapis/gnostic v0.4.1 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/onsi/gomega v1.16.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.39.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/oauth2 v0.3.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.28.1 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/api v0.21.2 // indirect - k8s.io/klog/v2 v2.8.0 // indirect - k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.1.0 // indirect - sigs.k8s.io/yaml v1.2.0 // indirect -) diff --git a/op-exporter/go.sum b/op-exporter/go.sum deleted file mode 100644 index 3e468bb97a33..000000000000 --- a/op-exporter/go.sum +++ /dev/null @@ -1,496 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.12.1 h1:1kXDPxhLfyySuQYIfRxVBGYuaHdxNNxevA73vjIwsgk= -github.com/ethereum/go-ethereum v1.12.1/go.mod h1:zKetLweqBR8ZS+1O9iJWI8DvmmD2NzD19apjEWDCsnw= -github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= -github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= -github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/ybbus/jsonrpc v2.1.2+incompatible h1:V4mkE9qhbDQ92/MLMIhlhMSbz8jNXdagC3xBR5NDwaQ= -github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= -golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.21.2 h1:vz7DqmRsXTCSa6pNxXwQ1IYeAZgdIsua+DZU+o+SX3Y= -k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU= -k8s.io/apimachinery v0.21.2 h1:vezUc/BHqWlQDnZ+XkrpXSmnANSLbpnlpwo0Lhk0gpc= -k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= -k8s.io/client-go v0.21.2 h1:Q1j4L/iMN4pTw6Y4DWppBoUxgKO8LbffEMVEV00MUp0= -k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= -k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= -sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/op-exporter/k8sClient/main.go b/op-exporter/k8sClient/main.go deleted file mode 100644 index 196a8f06f84a..000000000000 --- a/op-exporter/k8sClient/main.go +++ /dev/null @@ -1,20 +0,0 @@ -package k8sClient - -import ( - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" -) - -func Newk8sClient() (client *kubernetes.Clientset, err error) { - // creates the in-cluster config - config, err := rest.InClusterConfig() - if err != nil { - panic(err.Error()) - } - // creates the clientset - client, err = kubernetes.NewForConfig(config) - if err != nil { - panic(err.Error()) - } - return client, nil -} diff --git a/op-exporter/main.go b/op-exporter/main.go deleted file mode 100644 index 65b8930733f7..000000000000 --- a/op-exporter/main.go +++ /dev/null @@ -1,282 +0,0 @@ -package main - -import ( - "context" - "fmt" - "io/ioutil" - "net/http" - "os" - "strings" - "sync" - "time" - - "github.com/ethereum-optimism/optimism/op-exporter/k8sClient" - "github.com/ethereum-optimism/optimism/op-exporter/version" - - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/prometheus/client_golang/prometheus/promhttp" - log "github.com/sirupsen/logrus" - "github.com/ybbus/jsonrpc" - "gopkg.in/alecthomas/kingpin.v2" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" -) - -var UnknownStatus = "UNKNOWN" - -var ( - listenAddress = kingpin.Flag( - "web.listen-address", - "Address on which to expose metrics and web interface.", - ).Default(":9100").String() - rpcProvider = kingpin.Flag( - "rpc.provider", - "Address for RPC provider.", - ).Default("http://127.0.0.1:8545").String() - networkLabel = kingpin.Flag( - "label.network", - "Label to apply to the metrics to identify the network.", - ).Default("mainnet").String() - versionFlag = kingpin.Flag( - "version", - "Display binary version.", - ).Default("False").Bool() - unhealthyTimePeriod = kingpin.Flag( - "wait.minutes", - "Number of minutes to wait for the next block before marking provider unhealthy.", - ).Default("10").Int() - sequencerPollingSeconds = kingpin.Flag( - "sequencer.polling", - "Number of seconds to wait between sequencer polling cycles.", - ).Default("30").Int() - enableK8sQuery = kingpin.Flag( - "k8s.enable", - "Enable kubernetes info lookup.", - ).Default("false").Bool() - enableRollUpGasPrices = kingpin.Flag( - "rollUpGasPrices.enable", - "Enable rollUpGasPrices info lookup.", - ).Default("false").Bool() - enableGasBaseFee = kingpin.Flag( - "gaseBaseFee.enable", - "Enable gaseBaseFee info lookup.", - ).Default("false").Bool() -) - -type healthCheck struct { - mu *sync.RWMutex - height uint64 - healthy bool - updateTime time.Time - allowedMethods []string - version *string -} - -type getBlockByNumberResponse struct { - BaseFeePerGas string `json:"baseFeePerGas"` - GasUsed string `json:"gasUsed"` -} - -func healthHandler(health *healthCheck) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - health.mu.RLock() - defer health.mu.RUnlock() - w.Write([]byte(fmt.Sprintf(`{ "healthy": "%t", "version": "%s" }`, health.healthy, *health.version))) - } -} - -func main() { - kingpin.HelpFlag.Short('h') - kingpin.Parse() - if *versionFlag { - fmt.Printf("(version=%s, gitcommit=%s)\n", version.Version, version.GitCommit) - fmt.Printf("(go=%s, date=%s)\n", version.GoVersion, version.BuildDate) - os.Exit(0) - } - log.Infoln("exporter config", *listenAddress, *rpcProvider, *networkLabel) - log.Infoln("Starting op_exporter", version.Info()) - log.Infoln("Build context", version.BuildContext()) - opExporterVersion.WithLabelValues( - strings.Trim(version.Version, "\""), version.GitCommit, version.GoVersion, version.BuildDate).Inc() - health := healthCheck{ - mu: new(sync.RWMutex), - height: 0, - healthy: false, - updateTime: time.Now(), - allowedMethods: nil, - version: &UnknownStatus, - } - http.Handle("/metrics", promhttp.Handler()) - http.Handle("/health", healthHandler(&health)) - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(` - OP Exporter - -

OP Exporter

-

Metrics

-

Health

- - `)) - }) - go getBlockNumber(&health) - - if *enableRollUpGasPrices { - go getRollupGasPrices() - } - - if *enableGasBaseFee { - go getBaseFee() - } - - if *enableK8sQuery { - client, err := k8sClient.Newk8sClient() - if err != nil { - log.Fatal(err) - } - go getSequencerVersion(&health, client) - } - log.Infoln("Listening on", *listenAddress) - if err := http.ListenAndServe(*listenAddress, nil); err != nil { - log.Fatal(err) - } - -} - -func getSequencerVersion(health *healthCheck, client *kubernetes.Clientset) { - ns, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") - if err != nil { - log.Fatalf("Unable to read namespace file: %s", err) - } - ticker := time.NewTicker(30 * time.Second) - for { - <-ticker.C - getOpts := metav1.GetOptions{ - TypeMeta: metav1.TypeMeta{}, - ResourceVersion: "", - } - sequencerStatefulSet, err := client.AppsV1().StatefulSets(string(ns)).Get(context.TODO(), "sequencer", getOpts) - if err != nil { - health.version = &UnknownStatus - log.Errorf("Unable to retrieve a sequencer StatefulSet: %s", err) - continue - } - for _, c := range sequencerStatefulSet.Spec.Template.Spec.Containers { - log.Infof("Checking container %s", c.Name) - switch { - case c.Name == "sequencer": - log.Infof("The sequencer version is: %s", c.Image) - health.version = &c.Image - default: - log.Infof("Unable to find the sequencer container in the statefulset?!?") - } - } - - } -} - -func getBlockNumber(health *healthCheck) { - rpcClient := jsonrpc.NewClientWithOpts(*rpcProvider, &jsonrpc.RPCClientOpts{}) - var blockNumberResponse *string - for { - if err := rpcClient.CallFor(&blockNumberResponse, "eth_blockNumber"); err != nil { - health.mu.Lock() - health.healthy = false - health.mu.Unlock() - log.Warnln("Error calling eth_blockNumber, setting unhealthy", err) - } else { - log.Infoln("Got block number: ", *blockNumberResponse) - health.mu.Lock() - currentHeight, err := hexutil.DecodeUint64(*blockNumberResponse) - blockNumber.WithLabelValues( - *networkLabel, "layer2").Set(float64(currentHeight)) - if err != nil { - log.Warnln("Error decoding block height", err) - continue - } - lastHeight := health.height - // If the currentHeight is the same as the lastHeight, check that - // the unhealthyTimePeriod has passed and update health.healthy - if currentHeight == lastHeight { - currentTime := time.Now() - lastTime := health.updateTime - log.Warnln(fmt.Sprintf("Heights are the same, %v, %v", currentTime, lastTime)) - if lastTime.Add(time.Duration(*unhealthyTimePeriod) * time.Minute).Before(currentTime) { - health.healthy = false - log.Warnln("Heights are the same for the unhealthyTimePeriod, setting unhealthy") - } - } else { - log.Warnln("New block height detected, setting healthy") - health.height = currentHeight - health.updateTime = time.Now() - health.healthy = true - } - if health.healthy { - healthySequencer.WithLabelValues( - *networkLabel).Set(1) - } else { - healthySequencer.WithLabelValues( - *networkLabel).Set(0) - } - - health.mu.Unlock() - } - time.Sleep(time.Duration(*sequencerPollingSeconds) * time.Second) - } -} - -func getBaseFee() { - rpcClient := jsonrpc.NewClientWithOpts(*rpcProvider, &jsonrpc.RPCClientOpts{}) - var getBlockByNumbeResponse *getBlockByNumberResponse - for { - if err := rpcClient.CallFor(&getBlockByNumbeResponse, "eth_getBlockByNumber", "latest", false); err != nil { - log.Errorln("Error calling eth_getBlockByNumber", err) - } else { - log.Infoln("Got baseFee response: ", *getBlockByNumbeResponse) - baseFeePerGas, err := hexutil.DecodeUint64(getBlockByNumbeResponse.BaseFeePerGas) - if err != nil { - log.Warnln("Error converting baseFeePerGas " + getBlockByNumbeResponse.BaseFeePerGas) - } - gasBaseFeeMetric.WithLabelValues( - *networkLabel, "layer2").Set(float64(baseFeePerGas)) - - gasUsed, err := hexutil.DecodeUint64(getBlockByNumbeResponse.GasUsed) - if err != nil { - log.Warnln("Error converting gasUsed " + getBlockByNumbeResponse.GasUsed) - } - gasUsedMetric.WithLabelValues( - *networkLabel, "layer2").Set(float64(gasUsed)) - } - time.Sleep(time.Duration(*sequencerPollingSeconds) * time.Second) - - } -} - -func getRollupGasPrices() { - rpcClient := jsonrpc.NewClientWithOpts(*rpcProvider, &jsonrpc.RPCClientOpts{}) - var rollupGasPrices *GetRollupGasPrices - for { - if err := rpcClient.CallFor(&rollupGasPrices, "rollup_gasPrices"); err != nil { - log.Warnln("Error calling rollup_gasPrices", err) - } else { - l1GasPriceString := rollupGasPrices.L1GasPrice - l1GasPrice, err := hexutil.DecodeUint64(l1GasPriceString) - if err != nil { - log.Warnln("Error converting gasPrice " + l1GasPriceString) - } - gasPrice.WithLabelValues( - *networkLabel, "layer1").Set(float64(l1GasPrice)) - l2GasPriceString := rollupGasPrices.L2GasPrice - l2GasPrice, err := hexutil.DecodeUint64(l2GasPriceString) - if err != nil { - log.Warnln("Error converting gasPrice " + l2GasPriceString) - } - gasPrice.WithLabelValues( - *networkLabel, "layer2").Set(float64(l2GasPrice)) - log.Infoln("Got L1 gas string: ", l1GasPriceString) - log.Infoln("Got L1 gas prices: ", l1GasPrice) - log.Infoln("Got L2 gas string: ", l2GasPriceString) - log.Infoln("Got L2 gas prices: ", l2GasPrice) - } - time.Sleep(time.Duration(30) * time.Second) - } -} diff --git a/op-exporter/package.json b/op-exporter/package.json deleted file mode 100644 index f37678356df9..000000000000 --- a/op-exporter/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@eth-optimism/op-exporter", - "version": "0.5.5", - "private": true, - "devDependencies": {} -} diff --git a/op-exporter/rpc.go b/op-exporter/rpc.go deleted file mode 100644 index f6bc9b13968a..000000000000 --- a/op-exporter/rpc.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -// GetRollupGasPrices returns the rpc `rollup_gasPrices` status -type GetRollupGasPrices struct { - L1GasPrice string `json:"l1GasPrice"` - L2GasPrice string `json:"l2GasPrice"` -} - -type GetBlockNumber struct { - BlockNumber string `json:"result"` -} diff --git a/op-exporter/version/version.go b/op-exporter/version/version.go deleted file mode 100644 index 9e90dc62aa32..000000000000 --- a/op-exporter/version/version.go +++ /dev/null @@ -1,21 +0,0 @@ -package version - -import ( - "fmt" - "runtime" -) - -var ( - Version string - GitCommit string - BuildDate string - GoVersion = runtime.Version() -) - -func Info() string { - return fmt.Sprintf("(version=%s, gitcommit=%s)", Version, GitCommit) -} - -func BuildContext() string { - return fmt.Sprintf("(go=%s, date=%s)", GoVersion, BuildDate) -} diff --git a/op-heartbeat/Makefile b/op-heartbeat/Makefile index 03daf6b05bec..f1efa74c37df 100644 --- a/op-heartbeat/Makefile +++ b/op-heartbeat/Makefile @@ -19,5 +19,4 @@ test: .PHONY: \ clean \ op-heartbeat \ - test \ - lint + test diff --git a/op-heartbeat/config.go b/op-heartbeat/config.go index 7b9308cd6e10..6f78f4265fb9 100644 --- a/op-heartbeat/config.go +++ b/op-heartbeat/config.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum-optimism/optimism/op-heartbeat/flags" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" "github.com/urfave/cli/v2" ) diff --git a/op-heartbeat/service.go b/op-heartbeat/service.go index fdb8202c1d1e..55305fde591a 100644 --- a/op-heartbeat/service.go +++ b/op-heartbeat/service.go @@ -23,7 +23,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/httputil" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" ) const ( @@ -39,7 +39,7 @@ func Main(version string) func(ctx *cli.Context) error { } l := oplog.NewLogger(oplog.AppOut(cliCtx), cfg.Log) - oplog.SetGlobalLogHandler(l.GetHandler()) + oplog.SetGlobalLogHandler(l.Handler()) l.Info("starting heartbeat monitor", "version", version) srv, err := Start(cliCtx.Context, l, cfg, version) @@ -60,13 +60,14 @@ func Main(version string) func(ctx *cli.Context) error { } type HeartbeatService struct { - pprof, metrics, http *httputil.HTTPServer + metrics, http *httputil.HTTPServer + pprofService *oppprof.Service } func (hs *HeartbeatService) Stop(ctx context.Context) error { var result error - if hs.pprof != nil { - result = errors.Join(result, hs.pprof.Stop(ctx)) + if hs.pprofService != nil { + result = errors.Join(result, hs.pprofService.Stop(ctx)) } if hs.metrics != nil { result = errors.Join(result, hs.metrics.Stop(ctx)) @@ -93,14 +94,17 @@ func Start(ctx context.Context, l log.Logger, cfg Config, version string) (*Hear } pprofCfg := cfg.Pprof - if pprofCfg.Enabled { - l.Debug("starting pprof", "addr", pprofCfg.ListenAddr, "port", pprofCfg.ListenPort) - pprofSrv, err := oppprof.StartServer(pprofCfg.ListenAddr, pprofCfg.ListenPort) - if err != nil { - return nil, errors.Join(fmt.Errorf("failed to start pprof server: %w", err), hs.Stop(ctx)) - } - l.Info("started pprof server", "addr", pprofSrv.Addr()) - hs.pprof = pprofSrv + hs.pprofService = oppprof.New( + pprofCfg.ListenEnabled, + pprofCfg.ListenAddr, + pprofCfg.ListenPort, + pprofCfg.ProfileType, + pprofCfg.ProfileDir, + pprofCfg.ProfileFilename, + ) + + if err := hs.pprofService.Start(); err != nil { + return nil, fmt.Errorf("failed to start pprof service: %w", err) } metrics := NewMetrics(registry) diff --git a/op-node/.gitignore b/op-node/.gitignore index ba077a4031ad..cf23cfa08d5b 100644 --- a/op-node/.gitignore +++ b/op-node/.gitignore @@ -1 +1,6 @@ bin + +# config files +genesis.json +jwt.txt +rollup.json diff --git a/op-node/Dockerfile b/op-node/Dockerfile index 78d0b453ddfd..8089733389f7 100644 --- a/op-node/Dockerfile +++ b/op-node/Dockerfile @@ -10,6 +10,8 @@ COPY ./op-node /app/op-node COPY ./op-chain-ops /app/op-chain-ops COPY ./op-service /app/op-service COPY ./op-bindings /app/op-bindings +COPY ./op-plasma /app/op-plasma +COPY ./op-conductor /app/op-conductor COPY ./op-aws-sdk /app/op-aws-sdk COPY ./go.mod /app/go.mod COPY ./go.sum /app/go.sum diff --git a/op-node/Makefile b/op-node/Makefile index ea2b2544acfa..9fd7c71b0310 100644 --- a/op-node/Makefile +++ b/op-node/Makefile @@ -18,7 +18,8 @@ test: go test -v ./... fuzz: - go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzL1InfoRoundTrip ./rollup/derive + go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzL1InfoBedrockRoundTrip ./rollup/derive + go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzL1InfoEcotoneRoundTrip ./rollup/derive go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzL1InfoAgainstContract ./rollup/derive go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzUnmarshallLogEvent ./rollup/derive go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzParseFrames ./rollup/derive @@ -38,6 +39,4 @@ generate-mocks: op-node \ clean \ test \ - lint \ - fuzz \ - generate-mocks + fuzz diff --git a/op-node/README.md b/op-node/README.md index 1a7cc05adcfb..fa190535a452 100644 --- a/op-node/README.md +++ b/op-node/README.md @@ -1,6 +1,6 @@ # op-node -This is the reference implementation of the [rollup-node spec](../specs/rollup-node.md). +This is the reference implementation of the [rollup-node spec](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/rollup-node.md). ## Compiling diff --git a/op-node/chaincfg/chains.go b/op-node/chaincfg/chains.go index 991c5b055dbd..360fa279e678 100644 --- a/op-node/chaincfg/chains.go +++ b/op-node/chaincfg/chains.go @@ -91,7 +91,7 @@ var NetworksByName = map[string]rollup.Config{ var NetworksByChainId = map[string]rollup.Config{ "204": OPBNBMainnet, "5611": OPBNBTestnet, - "1322": OPBNBQANet, + "2484": OPBNBQANet, } func GetRollupConfigByNetwork(name string) (rollup.Config, error) { @@ -180,16 +180,16 @@ var OPBNBTestnet = rollup.Config{ var OPBNBQANet = rollup.Config{ Genesis: rollup.Genesis{ L1: eth.BlockID{ - Hash: common.HexToHash("0x3db93722c9951fe1da25dd652c6e2367674a97161df2acea322e915cab0d58ba"), - Number: 742038, + Hash: common.HexToHash("0xd8b84c6811ad3eb68ad578e12312f797d84c59a97993a1f230409c1644fcb3d2"), + Number: 373422, }, L2: eth.BlockID{ - Hash: common.HexToHash("0x1cba296441b55cf9b5b306b6aef43e68e9aeff2450d68c391dec448604cf3baf"), + Hash: common.HexToHash("0xe182e685b1ec05ca55f2374cb3a190d1ae8f3e196acb55a69efd61536fc3983f"), Number: 0, }, - L2Time: 1704856150, + L2Time: 1714291718, SystemConfig: eth.SystemConfig{ - BatcherAddr: common.HexToAddress("0xe309831c77d5fb5f189dd97c598e26e5c014f2d6"), + BatcherAddr: common.HexToAddress("0xbd6353a2e43a0d8eaa370b2eceb80481bc5c4094"), Overhead: eth.Bytes32(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000834")), Scalar: eth.Bytes32(common.HexToHash("0x00000000000000000000000000000000000000000000000000000000000f4240")), GasLimit: 100000000, @@ -200,14 +200,16 @@ var OPBNBQANet = rollup.Config{ SeqWindowSize: 14400, ChannelTimeout: 1200, L1ChainID: big.NewInt(714), - L2ChainID: big.NewInt(1322), - BatchInboxAddress: common.HexToAddress("0xff00000000000000000000000000000000001322"), - DepositContractAddress: common.HexToAddress("0xb7cdbce0b1f153b4cb2acc36aeb4d9d2cdda1132"), - L1SystemConfigAddress: common.HexToAddress("0x6a2607255801095b23256a341b24d31275fe2438"), + L2ChainID: big.NewInt(2484), + BatchInboxAddress: common.HexToAddress("0xff00000000000000000000000000000000001484"), + DepositContractAddress: common.HexToAddress("0xb22e158785dbfb055edddb24ad97b4e7c51a6624"), + L1SystemConfigAddress: common.HexToAddress("0xbf05c7e8ac1bd5ed042618762a7442f726ecae0b"), RegolithTime: u64Ptr(0), - // Fermat: big.NewInt(3615117), - // TODO update timestamp - SnowTime: nil, + Fermat: big.NewInt(0), + SnowTime: u64Ptr(1714993200), // May-06-2024 11:00 AM +UTC + CanyonTime: u64Ptr(1714993800), // May-06-2024 11:10 AM +UTC + DeltaTime: u64Ptr(1714994400), // May-06-2024 11:20 AM +UTC + EcotoneTime: u64Ptr(1714995000), // May-06-2024 11:30 AM +UTC } func u64Ptr(v uint64) *uint64 { diff --git a/op-node/chaincfg/chains_test.go b/op-node/chaincfg/chains_test.go index 5b887c318681..66fbc45c796b 100644 --- a/op-node/chaincfg/chains_test.go +++ b/op-node/chaincfg/chains_test.go @@ -20,10 +20,11 @@ import ( // This test ensures no op-node config-loading behavior changes before // the superchain-registry is no longer deemed experimental. func TestGetRollupConfig(t *testing.T) { - var configsByName = map[string]rollup.Config{ - "goerli": goerliCfg, - "mainnet": mainnetCfg, - "sepolia": sepoliaCfg, + configsByName := map[string]rollup.Config{ + "goerli": goerliCfg, + "mainnet": mainnetCfg, + "sepolia": sepoliaCfg, + "oplabs-devnet-0-sepolia-dev-0": sepoliaDev0Cfg, } for name, expectedCfg := range configsByName { @@ -62,6 +63,9 @@ var mainnetCfg = rollup.Config{ DepositContractAddress: common.HexToAddress("0xbEb5Fc579115071764c7423A4f12eDde41f106Ed"), L1SystemConfigAddress: common.HexToAddress("0x229047fed2591dbec1eF1118d64F7aF3dB9EB290"), RegolithTime: u64Ptr(0), + CanyonTime: u64Ptr(1704992401), + DeltaTime: u64Ptr(1708560000), + EcotoneTime: u64Ptr(1710374401), ProtocolVersionsAddress: common.HexToAddress("0x8062AbC286f5e7D9428a0Ccb9AbD71e50d93b935"), } @@ -94,6 +98,8 @@ var goerliCfg = rollup.Config{ L1SystemConfigAddress: common.HexToAddress("0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60"), RegolithTime: u64Ptr(1679079600), CanyonTime: u64Ptr(1699981200), + DeltaTime: u64Ptr(1703116800), + EcotoneTime: u64Ptr(1707238800), ProtocolVersionsAddress: common.HexToAddress("0x0C24F5098774aA366827D667494e9F889f7cFc08"), } @@ -126,5 +132,41 @@ var sepoliaCfg = rollup.Config{ L1SystemConfigAddress: common.HexToAddress("0x034edd2a225f7f429a63e0f1d2084b9e0a93b538"), RegolithTime: u64Ptr(0), CanyonTime: u64Ptr(1699981200), + DeltaTime: u64Ptr(1703203200), + EcotoneTime: u64Ptr(1708534800), ProtocolVersionsAddress: common.HexToAddress("0x79ADD5713B383DAa0a138d3C4780C7A1804a8090"), } + +var sepoliaDev0Cfg = rollup.Config{ + Genesis: rollup.Genesis{ + L1: eth.BlockID{ + Hash: common.HexToHash("0x5639be97000fec7131a880b19b664cae43f975c773f628a08a9bb658c2a68df0"), + Number: 5173577, + }, + L2: eth.BlockID{ + Hash: common.HexToHash("0x027ae1f4f9a441f9c8a01828f3b6d05803a0f524c07e09263264a38b755f804b"), + Number: 0, + }, + L2Time: 1706484048, + SystemConfig: eth.SystemConfig{ + BatcherAddr: common.HexToAddress("0x19cc7073150d9f5888f09e0e9016d2a39667df14"), + Overhead: eth.Bytes32(common.HexToHash("0x00000000000000000000000000000000000000000000000000000000000000bc")), + Scalar: eth.Bytes32(common.HexToHash("0x00000000000000000000000000000000000000000000000000000000000a6fe0")), + GasLimit: 30000000, + }, + }, + BlockTime: 2, + MaxSequencerDrift: 600, + SeqWindowSize: 3600, + ChannelTimeout: 300, + L1ChainID: big.NewInt(11155111), + L2ChainID: big.NewInt(11155421), + BatchInboxAddress: common.HexToAddress("0xff00000000000000000000000000000011155421"), + DepositContractAddress: common.HexToAddress("0x76114bd29dFcC7a9892240D317E6c7C2A281Ffc6"), + L1SystemConfigAddress: common.HexToAddress("0xa6b72407e2dc9EBF84b839B69A24C88929cf20F7"), + RegolithTime: u64Ptr(0), + CanyonTime: u64Ptr(0), + DeltaTime: u64Ptr(0), + EcotoneTime: u64Ptr(1706634000), + ProtocolVersionsAddress: common.HexToAddress("0x252CbE9517F731C618961D890D534183822dcC8d"), +} diff --git a/op-node/cmd/batch_decoder/README.md b/op-node/cmd/batch_decoder/README.md index 522725359a78..7e85c24d8729 100644 --- a/op-node/cmd/batch_decoder/README.md +++ b/op-node/cmd/batch_decoder/README.md @@ -7,7 +7,7 @@ by looking at what batches were submitted on L1. The `batch_decoder` tool is designed to be simple & flexible. It offloads as much data analysis as possible to other tools. It is built around manipulating JSON on disk. The first stage is to -fetch all transaction which are sent to a batch inbox address. Those transactions are decoded into +fetch all transactions which are sent to a batch inbox address. Those transactions are decoded into frames in that step & information about them is recorded. After transactions are fetched the frames are re-assembled into channels in a second step that does not touch the network. @@ -24,13 +24,18 @@ the transaction hash. `batch_decoder reassemble` goes through all of the found frames in the cache & then turns them into channels. It then stores the channels with metadata on disk where the file name is the Channel ID. +Each channel can contain multiple batches. +If the batch is span batch, `batch_decoder` derives span batch using `L2BlockTime`, `L2GenesisTime`, and `L2ChainID`. +These arguments can be provided to the binary using flags. + +If the batch is a singular batch, `batch_decoder` does not derive and stores the batch as is. ### Force Close `batch_decoder force-close` will create a transaction data that can be sent from the batcher address to the batch inbox address which will force close the given channels. This will allow future channels to -be read without waiting for the channel timeout. It uses uses the results from `batch_decoder fetch` to +be read without waiting for the channel timeout. It uses the results from `batch_decoder fetch` to create the close transaction because the transaction it creates for a specific channel requires information about if the channel has been closed or not. If it has been closed already but is missing specific frames those frames need to be generated differently than simply closing the channel. @@ -45,7 +50,7 @@ those frames need to be generated differently than simply closing the channel. jq . $JSON_FILE # Print the number of valid & invalid transactions -jq .valid_data $TX_DIR/* | sort | uniq -c +jq .valid_data $TX_DIR/* | sort | uniq -c # Select all transactions that have invalid data & then print the transaction hash jq "select(.valid_data == false)|.tx.hash" $TX_DIR diff --git a/op-node/cmd/batch_decoder/main.go b/op-node/cmd/batch_decoder/main.go index 74522c05472d..e71099c0f30e 100644 --- a/op-node/cmd/batch_decoder/main.go +++ b/op-node/cmd/batch_decoder/main.go @@ -4,11 +4,13 @@ import ( "context" "fmt" "log" + "math/big" "os" "time" "github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/fetch" "github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/reassemble" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" @@ -77,7 +79,7 @@ func main() { End: uint64(cliCtx.Int("end")), ChainID: chainID, BatchSenders: map[common.Address]struct{}{ - common.HexToAddress(cliCtx.String("sender")): struct{}{}, + common.HexToAddress(cliCtx.String("sender")): {}, }, BatchInbox: common.HexToAddress(cliCtx.String("inbox")), OutDirectory: cliCtx.String("out"), @@ -92,13 +94,8 @@ func main() { }, { Name: "reassemble", - Usage: "Reassembles channels from fetched batches", + Usage: "Reassembles channels from fetched batch transactions and decode batches", Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "inbox", - Value: "0xff00000000000000000000000000000000000420", - Usage: "Batch Inbox Address", - }, &cli.StringFlag{ Name: "in", Value: "/tmp/batch_decoder/transactions_cache", @@ -109,12 +106,60 @@ func main() { Value: "/tmp/batch_decoder/channel_cache", Usage: "Cache directory for the found channels", }, + &cli.Uint64Flag{ + Name: "l2-chain-id", + Value: 10, + Usage: "L2 chain id for span batch derivation. Default value from op-mainnet.", + }, + &cli.Uint64Flag{ + Name: "l2-genesis-timestamp", + Value: 1686068903, + Usage: "L2 genesis time for span batch derivation. Default value from op-mainnet. " + + "Superchain-registry prioritized when given value is inconsistent.", + }, + &cli.Uint64Flag{ + Name: "l2-block-time", + Value: 2, + Usage: "L2 block time for span batch derivation. Default value from op-mainnet. " + + "Superchain-registry prioritized when given value is inconsistent.", + }, + &cli.StringFlag{ + Name: "inbox", + Value: "0xFF00000000000000000000000000000000000010", + Usage: "Batch Inbox Address. Default value from op-mainnet. " + + "Superchain-registry prioritized when given value is inconsistent.", + }, }, Action: func(cliCtx *cli.Context) error { + var ( + L2GenesisTime uint64 = cliCtx.Uint64("l2-genesis-timestamp") + L2BlockTime uint64 = cliCtx.Uint64("l2-block-time") + BatchInboxAddress common.Address = common.HexToAddress(cliCtx.String("inbox")) + ) + L2ChainID := new(big.Int).SetUint64(cliCtx.Uint64("l2-chain-id")) + rollupCfg, err := rollup.LoadOPStackRollupConfig(L2ChainID.Uint64()) + if err == nil { + // prioritize superchain config + if L2GenesisTime != rollupCfg.Genesis.L2Time { + L2GenesisTime = rollupCfg.Genesis.L2Time + fmt.Printf("L2GenesisTime overridden: %v\n", L2GenesisTime) + } + if L2BlockTime != rollupCfg.BlockTime { + L2BlockTime = rollupCfg.BlockTime + fmt.Printf("L2BlockTime overridden: %v\n", L2BlockTime) + } + if BatchInboxAddress != rollupCfg.BatchInboxAddress { + BatchInboxAddress = rollupCfg.BatchInboxAddress + fmt.Printf("BatchInboxAddress overridden: %v\n", BatchInboxAddress) + } + } config := reassemble.Config{ - BatchInbox: common.HexToAddress(cliCtx.String("inbox")), - InDirectory: cliCtx.String("in"), - OutDirectory: cliCtx.String("out"), + BatchInbox: BatchInboxAddress, + InDirectory: cliCtx.String("in"), + OutDirectory: cliCtx.String("out"), + L2ChainID: L2ChainID, + L2GenesisTime: L2GenesisTime, + L2BlockTime: L2BlockTime, } reassemble.Channels(config) return nil diff --git a/op-node/cmd/batch_decoder/reassemble/reassemble.go b/op-node/cmd/batch_decoder/reassemble/reassemble.go index adab7a9cdc8d..e8ced61cce6d 100644 --- a/op-node/cmd/batch_decoder/reassemble/reassemble.go +++ b/op-node/cmd/batch_decoder/reassemble/reassemble.go @@ -5,13 +5,11 @@ import ( "fmt" "io" "log" + "math/big" "os" "path" "sort" - "github.com/ethereum-optimism/optimism/op-node/chaincfg" - "github.com/ethereum-optimism/optimism/op-node/rollup" - "github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/fetch" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -24,7 +22,8 @@ type ChannelWithMetadata struct { InvalidFrames bool `json:"invalid_frames"` InvalidBatches bool `json:"invalid_batches"` Frames []FrameWithMetadata `json:"frames"` - Batches []derive.BatchData `json:"batches"` + Batches []derive.Batch `json:"batches"` + BatchTypes []int `json:"batch_types"` } type FrameWithMetadata struct { @@ -36,9 +35,12 @@ type FrameWithMetadata struct { } type Config struct { - BatchInbox common.Address - InDirectory string - OutDirectory string + BatchInbox common.Address + InDirectory string + OutDirectory string + L2ChainID *big.Int + L2GenesisTime uint64 + L2BlockTime uint64 } func LoadFrames(directory string, inbox common.Address) []FrameWithMetadata { @@ -68,9 +70,8 @@ func Channels(config Config) { for _, frame := range frames { framesByChannel[frame.Frame.ID] = append(framesByChannel[frame.Frame.ID], frame) } - cfg := chaincfg.Mainnet for id, frames := range framesByChannel { - ch := processFrames(cfg, id, frames) + ch := processFrames(config, id, frames) filename := path.Join(config.OutDirectory, fmt.Sprintf("%s.json", id.String())) if err := writeChannel(ch, filename); err != nil { log.Fatal(err) @@ -88,7 +89,7 @@ func writeChannel(ch ChannelWithMetadata, filename string) error { return enc.Encode(ch) } -func processFrames(cfg *rollup.Config, id derive.ChannelID, frames []FrameWithMetadata) ChannelWithMetadata { +func processFrames(cfg Config, id derive.ChannelID, frames []FrameWithMetadata) ChannelWithMetadata { ch := derive.NewChannel(id, eth.L1BlockRef{Number: frames[0].InclusionBlock}) invalidFrame := false @@ -104,17 +105,39 @@ func processFrames(cfg *rollup.Config, id derive.ChannelID, frames []FrameWithMe } } - var batches []derive.BatchData + var batches []derive.Batch + var batchTypes []int invalidBatches := false if ch.IsReady() { br, err := derive.BatchReader(ch.Reader()) if err == nil { - for batch, err := br(); err != io.EOF; batch, err = br() { + for batchData, err := br(); err != io.EOF; batchData, err = br() { if err != nil { - fmt.Printf("Error reading batch for channel %v. Err: %v\n", id.String(), err) + fmt.Printf("Error reading batchData for channel %v. Err: %v\n", id.String(), err) invalidBatches = true } else { - batches = append(batches, *batch) + batchType := batchData.GetBatchType() + batchTypes = append(batchTypes, int(batchType)) + switch batchType { + case derive.SingularBatchType: + singularBatch, err := derive.GetSingularBatch(batchData) + if err != nil { + invalidBatches = true + fmt.Printf("Error converting singularBatch from batchData for channel %v. Err: %v\n", id.String(), err) + } + // singularBatch will be nil when errored + batches = append(batches, singularBatch) + case derive.SpanBatchType: + spanBatch, err := derive.DeriveSpanBatch(batchData, cfg.L2BlockTime, cfg.L2GenesisTime, cfg.L2ChainID) + if err != nil { + invalidBatches = true + fmt.Printf("Error deriving spanBatch from batchData for channel %v. Err: %v\n", id.String(), err) + } + // spanBatch will be nil when errored + batches = append(batches, spanBatch) + default: + fmt.Printf("unrecognized batch type: %d for channel %v.\n", batchData.GetBatchType(), id.String()) + } } } } else { @@ -131,6 +154,7 @@ func processFrames(cfg *rollup.Config, id derive.ChannelID, frames []FrameWithMe InvalidFrames: invalidFrame, InvalidBatches: invalidBatches, Batches: batches, + BatchTypes: batchTypes, } } diff --git a/op-node/cmd/batch_decoder/script.sh b/op-node/cmd/batch_decoder/script.sh index 2d3936c0b66f..073bb23cecbe 100755 --- a/op-node/cmd/batch_decoder/script.sh +++ b/op-node/cmd/batch_decoder/script.sh @@ -1,3 +1,4 @@ -echo $1 -jq '.frames[] | {timestamp, inclusion_block}' $1 -jq '.batches[]|.Timestamp' $1 +#!/usr/bin/env bash +echo "$1" +jq '.frames[] | {timestamp, inclusion_block}' "$1" +jq '.batches[]|.Timestamp' "$1" diff --git a/op-node/cmd/genesis/cmd.go b/op-node/cmd/genesis/cmd.go index f5e8ebd872b3..360f7ecb59dc 100644 --- a/op-node/cmd/genesis/cmd.go +++ b/op-node/cmd/genesis/cmd.go @@ -7,43 +7,79 @@ import ( "fmt" "math/big" "os" - "path/filepath" "github.com/urfave/cli/v2" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum-optimism/optimism/op-bindings/hardhat" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" + "github.com/ethereum-optimism/optimism/op-service/jsonutil" +) + +var ( + l1RPCFlag = &cli.StringFlag{ + Name: "l1-rpc", + Usage: "RPC URL for an Ethereum L1 node. Cannot be used with --l1-starting-block", + } + l1StartingBlockFlag = &cli.PathFlag{ + Name: "l1-starting-block", + Usage: "Path to a JSON file containing the L1 starting block. Overrides the need for using an L1 RPC to fetch the block. Cannot be used with --l1-rpc", + } + deployConfigFlag = &cli.PathFlag{ + Name: "deploy-config", + Usage: "Path to deploy config file", + Required: true, + } + l1DeploymentsFlag = &cli.PathFlag{ + Name: "l1-deployments", + Usage: "Path to L1 deployments JSON file as in superchain-registry", + Required: true, + } + outfileL2Flag = &cli.PathFlag{ + Name: "outfile.l2", + Usage: "Path to L2 genesis output file", + } + outfileRollupFlag = &cli.PathFlag{ + Name: "outfile.rollup", + Usage: "Path to rollup output file", + } + + l1AllocsFlag = &cli.StringFlag{ + Name: "l1-allocs", + Usage: "Path to L1 genesis state dump", + } + outfileL1Flag = &cli.StringFlag{ + Name: "outfile.l1", + Usage: "Path to L1 genesis output file", + } + + l1Flags = []cli.Flag{ + deployConfigFlag, + l1AllocsFlag, + l1DeploymentsFlag, + outfileL1Flag, + } + + l2Flags = []cli.Flag{ + l1RPCFlag, + l1StartingBlockFlag, + deployConfigFlag, + l1DeploymentsFlag, + outfileL2Flag, + outfileRollupFlag, + } ) var Subcommands = cli.Commands{ { Name: "l1", Usage: "Generates a L1 genesis state file", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "deploy-config", - Usage: "Path to hardhat deploy config file", - Required: true, - }, - &cli.StringFlag{ - Name: "l1-allocs", - Usage: "Path to L1 genesis state dump", - }, - &cli.StringFlag{ - Name: "l1-deployments", - Usage: "Path to L1 deployments file", - }, - &cli.StringFlag{ - Name: "outfile.l1", - Usage: "Path to L1 genesis output file", - }, - }, + Flags: l1Flags, Action: func(ctx *cli.Context) error { deployConfig := ctx.String("deploy-config") config, err := genesis.NewDeployConfig(deployConfig) @@ -80,81 +116,84 @@ var Subcommands = cli.Commands{ } } - l1Genesis, err := genesis.BuildL1DeveloperGenesis(config, dump, deployments, true) + l1Genesis, err := genesis.BuildL1DeveloperGenesis(config, dump, deployments) if err != nil { return err } - return writeGenesisFile(ctx.String("outfile.l1"), l1Genesis) + return jsonutil.WriteJSON(ctx.String("outfile.l1"), l1Genesis, 0o666) }, }, { Name: "l2", Usage: "Generates an L2 genesis file and rollup config suitable for a deployed network", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "l1-rpc", - Usage: "L1 RPC URL", - }, - &cli.StringFlag{ - Name: "deploy-config", - Usage: "Path to deploy config file", - }, - &cli.StringFlag{ - Name: "deployment-dir", - Usage: "Path to network deployment directory", - }, - &cli.StringFlag{ - Name: "outfile.l2", - Usage: "Path to L2 genesis output file", - }, - &cli.StringFlag{ - Name: "outfile.rollup", - Usage: "Path to rollup output file", - }, - }, + Description: "Generating the L2 genesis depends on knowledge of L1 contract addresses for the bridge to be secure. " + + "A deploy config and either a deployment directory or an L1 deployments file are used to create the L2 genesis. " + + "The deploy directory and L1 deployments file are generated by the L1 contract deployments. " + + "An L1 starting block is necessary, it can either be fetched dynamically using config in the deploy config " + + "or it can be provided as a JSON file.", + Flags: l2Flags, Action: func(ctx *cli.Context) error { - deployConfig := ctx.String("deploy-config") + deployConfig := ctx.Path("deploy-config") log.Info("Deploy config", "path", deployConfig) config, err := genesis.NewDeployConfig(deployConfig) if err != nil { return err } - deployDir := ctx.String("deployment-dir") - if deployDir == "" { - return errors.New("Must specify --deployment-dir") - } + l1Deployments := ctx.Path("l1-deployments") + l1StartBlockPath := ctx.Path("l1-starting-block") + l1RPC := ctx.String("l1-rpc") - log.Info("Deployment directory", "path", deployDir) - depPath, network := filepath.Split(deployDir) - hh, err := hardhat.New(network, nil, []string{depPath}) - if err != nil { - return err + if l1StartBlockPath == "" && l1RPC == "" { + return errors.New("must specify either --l1-starting-block or --l1-rpc") } - - // Read the appropriate deployment addresses from disk - if err := config.GetDeployedAddresses(hh); err != nil { - return err + if l1StartBlockPath != "" && l1RPC != "" { + return errors.New("cannot specify both --l1-starting-block and --l1-rpc") } - client, err := ethclient.Dial(ctx.String("l1-rpc")) + deployments, err := genesis.NewL1Deployments(l1Deployments) if err != nil { - return fmt.Errorf("cannot dial %s: %w", ctx.String("l1-rpc"), err) + return fmt.Errorf("cannot read L1 deployments at %s: %w", l1Deployments, err) } + config.SetDeployments(deployments) var l1StartBlock *types.Block - if config.L1StartingBlockTag == nil { - l1StartBlock, err = client.BlockByNumber(context.Background(), nil) - tag := rpc.BlockNumberOrHashWithHash(l1StartBlock.Hash(), true) - config.L1StartingBlockTag = (*genesis.MarshalableRPCBlockNumberOrHash)(&tag) - } else if config.L1StartingBlockTag.BlockHash != nil { - l1StartBlock, err = client.BlockByHash(context.Background(), *config.L1StartingBlockTag.BlockHash) - } else if config.L1StartingBlockTag.BlockNumber != nil { - l1StartBlock, err = client.BlockByNumber(context.Background(), big.NewInt(config.L1StartingBlockTag.BlockNumber.Int64())) + if l1StartBlockPath != "" { + if l1StartBlock, err = readBlockJSON(l1StartBlockPath); err != nil { + return fmt.Errorf("cannot read L1 starting block at %s: %w", l1StartBlockPath, err) + } } - if err != nil { - return fmt.Errorf("error getting l1 start block: %w", err) + + if l1RPC != "" { + client, err := ethclient.Dial(l1RPC) + if err != nil { + return fmt.Errorf("cannot dial %s: %w", l1RPC, err) + } + + if config.L1StartingBlockTag == nil { + l1StartBlock, err = client.BlockByNumber(context.Background(), nil) + if err != nil { + return fmt.Errorf("cannot fetch latest block: %w", err) + } + tag := rpc.BlockNumberOrHashWithHash(l1StartBlock.Hash(), true) + config.L1StartingBlockTag = (*genesis.MarshalableRPCBlockNumberOrHash)(&tag) + } else if config.L1StartingBlockTag.BlockHash != nil { + l1StartBlock, err = client.BlockByHash(context.Background(), *config.L1StartingBlockTag.BlockHash) + if err != nil { + return fmt.Errorf("cannot fetch block by hash: %w", err) + } + } else if config.L1StartingBlockTag.BlockNumber != nil { + l1StartBlock, err = client.BlockByNumber(context.Background(), big.NewInt(config.L1StartingBlockTag.BlockNumber.Int64())) + if err != nil { + return fmt.Errorf("cannot fetch block by number: %w", err) + } + } + } + + // Ensure that there is a starting L1 block + if l1StartBlock == nil { + return errors.New("no starting L1 block") } // Sanity check the config. Do this after filling in the L1StartingBlockTag @@ -180,22 +219,62 @@ var Subcommands = cli.Commands{ return fmt.Errorf("generated rollup config does not pass validation: %w", err) } - if err := writeGenesisFile(ctx.String("outfile.l2"), l2Genesis); err != nil { + if err := jsonutil.WriteJSON(ctx.String("outfile.l2"), l2Genesis, 0o666); err != nil { return err } - return writeGenesisFile(ctx.String("outfile.rollup"), rollupConfig) + return jsonutil.WriteJSON(ctx.String("outfile.rollup"), rollupConfig, 0o666) }, }, } -func writeGenesisFile(outfile string, input any) error { - f, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o755) +// rpcBlock represents the JSON serialization of a block from an Ethereum RPC. +type rpcBlock struct { + Hash common.Hash `json:"hash"` + Transactions []rpcTransaction `json:"transactions"` + UncleHashes []common.Hash `json:"uncles"` + Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` +} + +// rpcTransaction represents the JSON serialization of a transaction from an Ethereum RPC. +type rpcTransaction struct { + tx *types.Transaction + txExtraInfo +} + +// txExtraInfo includes extra information about a transaction that is returned from +// and Ethereum RPC endpoint. +type txExtraInfo struct { + BlockNumber *string `json:"blockNumber,omitempty"` + BlockHash *common.Hash `json:"blockHash,omitempty"` + From *common.Address `json:"from,omitempty"` +} + +// readBlockJSON will read a JSON file from disk containing a serialized block. +// This logic can break if the block format changes but there is no modular way +// to turn a block into JSON in go-ethereum. +func readBlockJSON(path string) (*types.Block, error) { + raw, err := os.ReadFile(path) if err != nil { - return err + return nil, fmt.Errorf("block file at %s not found: %w", path, err) + } + + var header types.Header + if err := json.Unmarshal(raw, &header); err != nil { + return nil, fmt.Errorf("cannot unmarshal block: %w", err) } - defer f.Close() - enc := json.NewEncoder(f) - enc.SetIndent("", " ") - return enc.Encode(input) + var body rpcBlock + if err := json.Unmarshal(raw, &body); err != nil { + return nil, err + } + + if len(body.UncleHashes) > 0 { + return nil, fmt.Errorf("cannot unmarshal block with uncles") + } + + txs := make([]*types.Transaction, len(body.Transactions)) + for i, tx := range body.Transactions { + txs[i] = tx.tx + } + return types.NewBlockWithHeader(&header).WithBody(txs, nil).WithWithdrawals(body.Withdrawals), nil } diff --git a/op-node/cmd/main.go b/op-node/cmd/main.go index 04896c88d23b..f70e89fda6cb 100644 --- a/op-node/cmd/main.go +++ b/op-node/cmd/main.go @@ -13,6 +13,7 @@ import ( opnode "github.com/ethereum-optimism/optimism/op-node" "github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-node/cmd/genesis" + "github.com/ethereum-optimism/optimism/op-node/cmd/networks" "github.com/ethereum-optimism/optimism/op-node/cmd/p2p" "github.com/ethereum-optimism/optimism/op-node/flags" "github.com/ethereum-optimism/optimism/op-node/metrics" @@ -22,6 +23,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/cliapp" oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/metrics/doc" + "github.com/ethereum-optimism/optimism/op-service/opio" ) var ( @@ -57,9 +59,14 @@ func main() { Name: "doc", Subcommands: doc.NewSubcommands(metrics.NewMetrics("default")), }, + { + Name: "networks", + Subcommands: networks.Subcommands, + }, } - err := app.Run(os.Args) + ctx := opio.WithInterruptBlocker(context.Background()) + err := app.RunContext(ctx, os.Args) if err != nil { log.Crit("Application failed", "message", err) } @@ -68,8 +75,9 @@ func main() { func RollupNodeMain(ctx *cli.Context, closeApp context.CancelCauseFunc) (cliapp.Lifecycle, error) { logCfg := oplog.ReadCLIConfig(ctx) log := oplog.NewLogger(oplog.AppOut(ctx), logCfg) - oplog.SetGlobalLogHandler(log.GetHandler()) + oplog.SetGlobalLogHandler(log.Handler()) opservice.ValidateEnvVars(flags.EnvVarPrefix, flags.Flags, log) + opservice.WarnOnDeprecatedFlags(ctx, flags.DeprecatedFlags, log) m := metrics.NewMetrics("default") if err := opaws.KeyManager(context.Background(), ctx, opaws.OP_NODE_P2P_SEQUENCER_KEY); err != nil { return nil, err diff --git a/op-node/cmd/networks/cmd.go b/op-node/cmd/networks/cmd.go new file mode 100644 index 000000000000..aa30681a97fb --- /dev/null +++ b/op-node/cmd/networks/cmd.go @@ -0,0 +1,45 @@ +package networks + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/urfave/cli/v2" + + opnode "github.com/ethereum-optimism/optimism/op-node" + "github.com/ethereum-optimism/optimism/op-node/flags" + opflags "github.com/ethereum-optimism/optimism/op-service/flags" + oplog "github.com/ethereum-optimism/optimism/op-service/log" +) + +var Subcommands = []*cli.Command{ + { + Name: "dump-rollup-config", + Usage: "Dumps network configs", + Flags: []cli.Flag{ + opflags.CLINetworkFlag(flags.EnvVarPrefix, ""), + }, + Action: func(ctx *cli.Context) error { + logCfg := oplog.ReadCLIConfig(ctx) + logger := oplog.NewLogger(oplog.AppOut(ctx), logCfg) + + network := ctx.String(opflags.NetworkFlagName) + if network == "" { + return errors.New("must specify a network name") + } + + rCfg, err := opnode.NewRollupConfigFromCLI(logger, ctx) + if err != nil { + return err + } + + out, err := json.MarshalIndent(rCfg, "", " ") + if err != nil { + return err + } + fmt.Println(string(out)) + return nil + }, + }, +} diff --git a/op-node/cmd/stateviz/assets/index.html b/op-node/cmd/stateviz/assets/index.html deleted file mode 100644 index 73388f3f077f..000000000000 --- a/op-node/cmd/stateviz/assets/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - -
-
-
-
- - - - - - - - - diff --git a/op-node/cmd/stateviz/assets/main.js b/op-node/cmd/stateviz/assets/main.js deleted file mode 100644 index d713cd4797e5..000000000000 --- a/op-node/cmd/stateviz/assets/main.js +++ /dev/null @@ -1,125 +0,0 @@ -function prettyHex(hash) { - return `${hash.slice(0, 8)}..${hash.slice(56)}`; -} - -// return a light-ish hue -function colorCode(hash) { - const code = parseInt(hash.slice(60), 16); - const h = code % 361; - const s = code % 101; - let l = code % 101; - // yeah this is biased but it's good enough - if (l < 30) { - l += 30; - } - return `hsl(${h}, ${s}%, ${l}%)`; -} - -async function fetchLogs() { - const response = await fetch("/logs"); - return await response.json(); -} - -function tooltipFormat(v) { - var out = "" - out += `
` - out += `hash: ${v["hash"]}
` - out += `num: ${v["number"]}
` - out += `parent: ${v["parentHash"]}
` - out += `time: ${v["timestamp"]}
` - if(v.hasOwnProperty("l1origin")) { - out += `L1 hash: ${v["l1origin"]["hash"]}
` - out += `L1 num: ${v["l1origin"]["number"]}
` - out += `seq: ${v["sequenceNumber"]}
` - } - out += `
` - return out -} - -async function pageTable() { - const logs = await fetchLogs(); - if (logs.length === 0) { - return - } - - const dataEl = $(`
`); - $("#logs").append(dataEl); - - let numCols = 0 - if (logs.length !== 0) { - numCols = logs[0].length - } - const paginationEl = $(``) - $("#logs").append(paginationEl) - paginationEl.pagination({ - dataSource: logs, - pageSize: 40, - showGoInput: true, - showGoButton: true, - callback: (data, pagination) => { - let tables = [] - for (var i = 0; i < numCols; i++) { - // TODO: Fix grid overflow with more than 2 rollup drivers - let html = '
'; - html += ` - - - - - - - - - - - - `; - html += ""; - - // TODO: it'll also be useful to indicate which rollup driver updated its state for the given timestamp - for (const record of data) { - const e = record[i]; - if (e === undefined) { - // this column has reached its end - break - } - // outer stringify in title attribute escapes the content and adds the quotes for the html to be valid - // inner stringify in - - // TODO: click to copy full hash - html += ` - - - - - - - `; - } - html += ""; - html += "
${data[0][i].engine_addr}
TimestampL1HeadL1CurrentL2HeadL2SafeL2FinalizedHead
- ${e.t} - - ${prettyHex(e.l1Head.hash)} - - ${prettyHex(e.l1Current.hash)} - - ${prettyHex(e.l2Head.hash)} - - ${prettyHex(e.l2Safe.hash)} - - ${prettyHex(e.l2FinalizedHead.hash)} -
"; - tables.push(html); - } - - const html = tables.join("\n"); - dataEl.html(html); - $('[data-toggle="tooltip"]').tooltip(); - } - }) -} - -(async () => { - pageTable() -})() diff --git a/op-node/cmd/stateviz/main.go b/op-node/cmd/stateviz/main.go deleted file mode 100644 index 8479984361bd..000000000000 --- a/op-node/cmd/stateviz/main.go +++ /dev/null @@ -1,244 +0,0 @@ -package main - -import ( - "bufio" - "compress/gzip" - "embed" - "encoding/json" - "errors" - "flag" - "fmt" - "io" - "io/fs" - "net" - "net/http" - "os" - "strconv" - "strings" - "sync" - "time" - - "github.com/ethereum-optimism/optimism/op-service/eth" - ophttp "github.com/ethereum-optimism/optimism/op-service/httputil" - "github.com/ethereum/go-ethereum/log" -) - -var ( - snapshot = flag.String("snapshot", "", "path to snapshot log") - listenAddr = flag.String("addr", "", "listen address of webserver") - refresh = flag.Duration("refresh", 10*time.Second, "snapshot refresh rate") -) - -var ( - entries map[string][]SnapshotState - entriesMutex sync.Mutex - - assetFS fs.FS -) - -type SnapshotState struct { - Timestamp string `json:"t"` - EngineAddr string `json:"engine_addr"` - Event string `json:"event"` // event name - L1Head eth.L1BlockRef `json:"l1Head"` // what we see as head on L1 - L1Current eth.L1BlockRef `json:"l1Current"` // l1 block that the derivation is currently using - L2Head eth.L2BlockRef `json:"l2Head"` // l2 block that was last optimistically accepted (unsafe head) - L2Safe eth.L2BlockRef `json:"l2Safe"` // l2 block that was last derived - L2FinalizedHead eth.BlockID `json:"l2FinalizedHead"` // l2 block that is irreversible -} - -func (e *SnapshotState) UnmarshalJSON(data []byte) error { - t := struct { - Timestamp string `json:"t"` - EngineAddr string `json:"engine_addr"` - Event string `json:"event"` - L1Head json.RawMessage `json:"l1Head"` - L1Current json.RawMessage `json:"l1Current"` - L2Head json.RawMessage `json:"l2Head"` - L2Safe json.RawMessage `json:"l2Safe"` - L2FinalizedHead json.RawMessage `json:"l2FinalizedHead"` - }{} - if err := json.Unmarshal(data, &t); err != nil { - return err - } - e.Timestamp = t.Timestamp - e.EngineAddr = t.EngineAddr - e.Event = t.Event - - unquote := func(d json.RawMessage) []byte { - s, _ := strconv.Unquote(string(d)) - return []byte(s) - } - - if err := json.Unmarshal(unquote(t.L1Head), &e.L1Head); err != nil { - return err - } - if err := json.Unmarshal(unquote(t.L1Current), &e.L1Current); err != nil { - return err - } - if err := json.Unmarshal(unquote(t.L2Head), &e.L2Head); err != nil { - return err - } - if err := json.Unmarshal(unquote(t.L2Safe), &e.L2Safe); err != nil { - return err - } - if err := json.Unmarshal(unquote(t.L2FinalizedHead), &e.L2FinalizedHead); err != nil { - return err - } - return nil -} - -//go:embed assets -var embeddedAssets embed.FS - -func main() { - flag.Parse() - - log.Root().SetHandler( - log.LvlFilterHandler(log.LvlDebug, log.StreamHandler(os.Stdout, log.TerminalFormat(true))), - ) - - if *snapshot == "" { - log.Crit("missing required -snapshot flag") - } - - sub, err := fs.Sub(embeddedAssets, "assets") - if err != nil { - log.Crit("Failed to open asset directory", "message", err) - } - assetFS = sub - - go func() { - ticker := time.NewTicker(*refresh) - defer ticker.Stop() - for range ticker.C { - // TODO: incremental load - log.Info("loading snapshot...") - if err := loadSnapshot(); err != nil { - log.Error("failed to load snapshot", "err", err) - } - } - }() - - runServer() -} - -func loadSnapshot() error { - file, err := os.Open(*snapshot) - if err != nil { - return fmt.Errorf("%w: failed to open snapshot file", err) - } - defer file.Close() - - tempEntries := make(map[string][]SnapshotState) - scanner := bufio.NewScanner(file) - for scanner.Scan() { - var entry SnapshotState - if err := json.Unmarshal([]byte(scanner.Text()), &entry); err != nil { - return fmt.Errorf("%w: failed to decode snapshot log", err) - } - - tempEntries[entry.EngineAddr] = append(tempEntries[entry.EngineAddr], entry) - } - if err := scanner.Err(); err != nil { - return fmt.Errorf("%w: failed to scan snapshot file", err) - } - - entriesMutex.Lock() - entries = tempEntries - entriesMutex.Unlock() - - return nil -} - -func runServer() { - l, err := net.Listen("tcp", *listenAddr) - if err != nil { - log.Crit("Failed to listen on address", "message", err) - } - - mux := http.NewServeMux() - mux.Handle("/", http.FileServer(http.FS(assetFS))) - mux.HandleFunc("/logs", makeGzipHandler(logsHandler)) - - log.Info("running webserver...") - httpServer := ophttp.NewHttpServer(mux) - if err := httpServer.Serve(l); err != nil && !errors.Is(err, http.ErrServerClosed) { - log.Crit("http server failed", "message", err) - } -} - -type gzipResponseWriter struct { - io.Writer - http.ResponseWriter -} - -func (w gzipResponseWriter) Write(b []byte) (int, error) { - return w.Writer.Write(b) -} - -func makeGzipHandler(fn http.HandlerFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { - fn(w, r) - return - } - w.Header().Set("Content-Encoding", "gzip") - gz := gzip.NewWriter(w) - defer gz.Close() - gzr := gzipResponseWriter{Writer: gz, ResponseWriter: w} - fn(gzr, r) - } -} - -func logsHandler(w http.ResponseWriter, r *http.Request) { - var output [][]SnapshotState - - entriesMutex.Lock() - // shallow copy so we can update the SnapshotState slice head - entriesCopy := make(map[string][]SnapshotState) - for k, v := range entries { - entriesCopy[k] = v - } - entriesMutex.Unlock() - - // sort log entries and zip em up - // Each record/row contains SnapshotStates for each rollup driver - // Note that we assume each SnapshotState slice is sorted by the timestamp - for { - var min *SnapshotState - var minKey string - for k, v := range entriesCopy { - if len(v) == 0 { - continue - } - if min == nil || v[0].Timestamp < min.Timestamp { - min = &v[0] - minKey = k - } - } - - if min == nil { - break - } - - entriesCopy[minKey] = entriesCopy[minKey][1:] - - rec := make([]SnapshotState, 0, len(entriesCopy)) - rec = append(rec, *min) - for k, v := range entriesCopy { - if k != minKey && len(v) != 0 { - newEntry := v[0] - newEntry.Timestamp = min.Timestamp - rec = append(rec, newEntry) - } - } - output = append(output, rec) - } - - w.Header().Set("Content-Type", "application/json") - w.Header().Set("Cache-Control", "public, max-age=100000") - if err := json.NewEncoder(w).Encode(output); err != nil { - log.Warn("failed to encode logs", "message", err) - } -} diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go index 6913907c0267..bbc5fefe01f8 100644 --- a/op-node/flags/flags.go +++ b/op-node/flags/flags.go @@ -2,21 +2,38 @@ package flags import ( "fmt" - "strings" "time" - "github.com/ethereum-optimism/optimism/op-node/chaincfg" + "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + plasma "github.com/ethereum-optimism/optimism/op-plasma" openum "github.com/ethereum-optimism/optimism/op-service/enum" + opflags "github.com/ethereum-optimism/optimism/op-service/flags" oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/oppprof" "github.com/ethereum-optimism/optimism/op-service/sources" - - "github.com/urfave/cli/v2" ) // Flags const EnvVarPrefix = "OP_NODE" +const ( + RollupCategory = "1. ROLLUP" + L1RPCCategory = "2. L1 RPC" + SequencerCategory = "3. SEQUENCER" + OperationsCategory = "4. LOGGING, METRICS, DEBUGGING, AND API" + P2PCategory = "5. PEER-TO-PEER" + PlasmaCategory = "6. PLASMA (EXPERIMENTAL)" + MiscCategory = "7. MISC" +) + +func init() { + cli.HelpFlag.(*cli.BoolFlag).Category = MiscCategory + cli.VersionFlag.(*cli.BoolFlag).Category = MiscCategory +} + func prefixEnvVars(name string) []string { return []string{EnvVarPrefix + "_" + name} } @@ -24,53 +41,105 @@ func prefixEnvVars(name string) []string { var ( /* Required Flags */ L1NodeAddr = &cli.StringFlag{ - Name: "l1", - Usage: "Address of L1 User JSON-RPC endpoint to use (eth namespace required). Multiple alternative addresses are supported, separated by commas, and the first address is used by default", - Value: "http://127.0.0.1:8545", - EnvVars: prefixEnvVars("L1_ETH_RPC"), + Name: "l1", + Usage: "Address of L1 User JSON-RPC endpoint to use (eth namespace required). Multiple alternative addresses are supported, separated by commas, and the first address is used by default", + Value: "http://127.0.0.1:8545", + EnvVars: prefixEnvVars("L1_ETH_RPC"), + Category: RollupCategory, } L2EngineAddr = &cli.StringFlag{ - Name: "l2", - Usage: "Address of L2 Engine JSON-RPC endpoints to use (engine and eth namespace required)", - EnvVars: prefixEnvVars("L2_ENGINE_RPC"), + Name: "l2", + Usage: "Address of L2 Engine JSON-RPC endpoints to use (engine and eth namespace required)", + EnvVars: prefixEnvVars("L2_ENGINE_RPC"), + Category: RollupCategory, } - RollupConfig = &cli.StringFlag{ - Name: "rollup.config", - Usage: "Rollup chain parameters", - EnvVars: prefixEnvVars("ROLLUP_CONFIG"), + L2EngineJWTSecret = &cli.StringFlag{ + Name: "l2.jwt-secret", + Usage: "Path to JWT secret key. Keys are 32 bytes, hex encoded in a file. A new key will be generated if the file is empty.", + EnvVars: prefixEnvVars("L2_ENGINE_AUTH"), + Value: "", + Destination: new(string), + Category: RollupCategory, } - Network = &cli.StringFlag{ - Name: "network", - Usage: fmt.Sprintf("Predefined network selection. Available networks: %s", strings.Join(chaincfg.AvailableNetworks(), ", ")), - EnvVars: prefixEnvVars("NETWORK"), + BeaconAddr = &cli.StringFlag{ + Name: "l1.beacon", + Usage: "Address of L1 Beacon-node HTTP endpoint to use.", + Required: false, + EnvVars: prefixEnvVars("L1_BEACON"), + Category: RollupCategory, } /* Optional Flags */ + BeaconHeader = &cli.StringFlag{ + Name: "l1.beacon-header", + Usage: "Optional HTTP header to add to all requests to the L1 Beacon endpoint. Format: 'X-Key: Value'", + Required: false, + EnvVars: prefixEnvVars("L1_BEACON_HEADER"), + Category: L1RPCCategory, + } + BeaconArchiverAddr = &cli.StringFlag{ + Name: "l1.beacon-archiver", + Usage: "Address of L1 Beacon-node compatible HTTP endpoint to use. This is used to fetch blobs that the --l1.beacon does not have (i.e expired blobs).", + Required: false, + EnvVars: prefixEnvVars("L1_BEACON_ARCHIVER"), + Category: L1RPCCategory, + } + BeaconCheckIgnore = &cli.BoolFlag{ + Name: "l1.beacon.ignore", + Usage: "When false, halts op-node startup if the healthcheck to the Beacon-node endpoint fails.", + Required: false, + Value: false, + EnvVars: prefixEnvVars("L1_BEACON_IGNORE"), + Category: L1RPCCategory, + } + BeaconFetchAllSidecars = &cli.BoolFlag{ + Name: "l1.beacon.fetch-all-sidecars", + Usage: "If true, all sidecars are fetched and filtered locally. Workaround for buggy Beacon nodes.", + Required: false, + Value: false, + EnvVars: prefixEnvVars("L1_BEACON_FETCH_ALL_SIDECARS"), + Category: L1RPCCategory, + } + SyncModeFlag = &cli.GenericFlag{ + Name: "syncmode", + Usage: fmt.Sprintf("Blockchain sync mode (options: %s)", openum.EnumString(sync.ModeStrings)), + EnvVars: prefixEnvVars("SYNCMODE"), + Value: func() *sync.Mode { + out := sync.CLSync + return &out + }(), + Category: RollupCategory, + } RPCListenAddr = &cli.StringFlag{ - Name: "rpc.addr", - Usage: "RPC listening address", - EnvVars: prefixEnvVars("RPC_ADDR"), - Value: "127.0.0.1", + Name: "rpc.addr", + Usage: "RPC listening address", + EnvVars: prefixEnvVars("RPC_ADDR"), + Value: "127.0.0.1", + Category: OperationsCategory, } RPCListenPort = &cli.IntFlag{ - Name: "rpc.port", - Usage: "RPC listening port", - EnvVars: prefixEnvVars("RPC_PORT"), - Value: 9545, // Note: op-service/rpc/cli.go uses 8545 as the default. + Name: "rpc.port", + Usage: "RPC listening port", + EnvVars: prefixEnvVars("RPC_PORT"), + Value: 9545, // Note: op-service/rpc/cli.go uses 8545 as the default. + Category: OperationsCategory, } RPCEnableAdmin = &cli.BoolFlag{ - Name: "rpc.enable-admin", - Usage: "Enable the admin API (experimental)", - EnvVars: prefixEnvVars("RPC_ENABLE_ADMIN"), + Name: "rpc.enable-admin", + Usage: "Enable the admin API (experimental)", + EnvVars: prefixEnvVars("RPC_ENABLE_ADMIN"), + Category: OperationsCategory, } RPCAdminPersistence = &cli.StringFlag{ - Name: "rpc.admin-state", - Usage: "File path used to persist state changes made via the admin API so they persist across restarts. Disabled if not set.", - EnvVars: prefixEnvVars("RPC_ADMIN_STATE"), + Name: "rpc.admin-state", + Usage: "File path used to persist state changes made via the admin API so they persist across restarts. Disabled if not set.", + EnvVars: prefixEnvVars("RPC_ADMIN_STATE"), + Category: OperationsCategory, } L1TrustRPC = &cli.BoolFlag{ - Name: "l1.trustrpc", - Usage: "Trust the L1 RPC, sync faster at risk of malicious/buggy RPC providing bad or inconsistent L1 data", - EnvVars: prefixEnvVars("L1_TRUST_RPC"), + Name: "l1.trustrpc", + Usage: "Trust the L1 RPC, sync faster at risk of malicious/buggy RPC providing bad or inconsistent L1 data", + EnvVars: prefixEnvVars("L1_TRUST_RPC"), + Category: L1RPCCategory, } L1RPCProviderKind = &cli.GenericFlag{ Name: "l1.rpckind", @@ -81,172 +150,174 @@ var ( out := sources.RPCKindStandard return &out }(), + Category: L1RPCCategory, } L1RethDBPath = &cli.StringFlag{ Name: "l1.rethdb", Usage: "The L1 RethDB path, used to fetch receipts for L1 blocks. Only applicable when using the `reth_db` RPC kind with `l1.rpckind`.", EnvVars: prefixEnvVars("L1_RETHDB"), - Required: false, Hidden: true, + Category: L1RPCCategory, + } + L1RPCMaxConcurrency = &cli.IntFlag{ + Name: "l1.max-concurrency", + Usage: "Maximum number of concurrent RPC requests to make to the L1 RPC provider.", + EnvVars: prefixEnvVars("L1_MAX_CONCURRENCY"), + Value: 10, + Category: L1RPCCategory, } L1RPCRateLimit = &cli.Float64Flag{ - Name: "l1.rpc-rate-limit", - Usage: "Optional self-imposed global rate-limit on L1 RPC requests, specified in requests / second. Disabled if set to 0.", - EnvVars: prefixEnvVars("L1_RPC_RATE_LIMIT"), - Value: 0, + Name: "l1.rpc-rate-limit", + Usage: "Optional self-imposed global rate-limit on L1 RPC requests, specified in requests / second. Disabled if set to 0.", + EnvVars: prefixEnvVars("L1_RPC_RATE_LIMIT"), + Value: 0, + Category: L1RPCCategory, } L1RPCMaxBatchSize = &cli.IntFlag{ - Name: "l1.rpc-max-batch-size", - Usage: "Maximum number of RPC requests to bundle, e.g. during L1 blocks receipt fetching. The L1 RPC rate limit counts this as N items, but allows it to burst at once.", - EnvVars: prefixEnvVars("L1_RPC_MAX_BATCH_SIZE"), - Value: 20, + Name: "l1.rpc-max-batch-size", + Usage: "Maximum number of RPC requests to bundle, e.g. during L1 blocks receipt fetching. The L1 RPC rate limit counts this as N items, but allows it to burst at once.", + EnvVars: prefixEnvVars("L1_RPC_MAX_BATCH_SIZE"), + Value: 20, + Category: L1RPCCategory, } L1HTTPPollInterval = &cli.DurationFlag{ - Name: "l1.http-poll-interval", - Usage: "Polling interval for latest-block subscription when using an HTTP RPC provider. Ignored for other types of RPC endpoints.", - EnvVars: prefixEnvVars("L1_HTTP_POLL_INTERVAL"), - Value: time.Second * 3, - } - L2EngineJWTSecret = &cli.StringFlag{ - Name: "l2.jwt-secret", - Usage: "Path to JWT secret key. Keys are 32 bytes, hex encoded in a file. A new key will be generated if left empty.", - EnvVars: prefixEnvVars("L2_ENGINE_AUTH"), - Required: false, - Value: "", - Destination: new(string), + Name: "l1.http-poll-interval", + Usage: "Polling interval for latest-block subscription when using an HTTP RPC provider. Ignored for other types of RPC endpoints.", + EnvVars: prefixEnvVars("L1_HTTP_POLL_INTERVAL"), + Value: time.Second * 3, + Category: L1RPCCategory, } VerifierL1Confs = &cli.Uint64Flag{ Name: "verifier.l1-confs", Usage: "Number of L1 blocks to keep distance from the L1 head before deriving L2 data from. Reorgs are supported, but may be slow to perform.", EnvVars: prefixEnvVars("VERIFIER_L1_CONFS"), - Required: false, Value: 15, + Category: L1RPCCategory, } SequencerEnabledFlag = &cli.BoolFlag{ - Name: "sequencer.enabled", - Usage: "Enable sequencing of new L2 blocks. A separate batch submitter has to be deployed to publish the data for verifiers.", - EnvVars: prefixEnvVars("SEQUENCER_ENABLED"), + Name: "sequencer.enabled", + Usage: "Enable sequencing of new L2 blocks. A separate batch submitter has to be deployed to publish the data for verifiers.", + EnvVars: prefixEnvVars("SEQUENCER_ENABLED"), + Category: SequencerCategory, } SequencerStoppedFlag = &cli.BoolFlag{ - Name: "sequencer.stopped", - Usage: "Initialize the sequencer in a stopped state. The sequencer can be started using the admin_startSequencer RPC", - EnvVars: prefixEnvVars("SEQUENCER_STOPPED"), + Name: "sequencer.stopped", + Usage: "Initialize the sequencer in a stopped state. The sequencer can be started using the admin_startSequencer RPC", + EnvVars: prefixEnvVars("SEQUENCER_STOPPED"), + Category: SequencerCategory, } SequencerMaxSafeLagFlag = &cli.Uint64Flag{ Name: "sequencer.max-safe-lag", Usage: "Maximum number of L2 blocks for restricting the distance between L2 safe and unsafe. Disabled if 0.", EnvVars: prefixEnvVars("SEQUENCER_MAX_SAFE_LAG"), - Required: false, Value: 0, + Category: SequencerCategory, } SequencerPriorityFlag = &cli.BoolFlag{ Name: "sequencer.priority", Usage: "Enable sequencer step takes precedence over other steps.", EnvVars: prefixEnvVars("SEQUENCER_PRIORITY"), + Category: SequencerCategory, } SequencerL1Confs = &cli.Uint64Flag{ Name: "sequencer.l1-confs", Usage: "Number of L1 blocks to keep distance from the L1 head as a sequencer for picking an L1 origin.", EnvVars: prefixEnvVars("SEQUENCER_L1_CONFS"), - Required: false, Value: 15, + Category: SequencerCategory, } L1EpochPollIntervalFlag = &cli.DurationFlag{ Name: "l1.epoch-poll-interval", Usage: "Poll interval for retrieving new L1 epoch updates such as safe and finalized block changes. Disabled if 0 or negative.", EnvVars: prefixEnvVars("L1_EPOCH_POLL_INTERVAL"), - Required: false, Value: time.Second * 3 * 15, + Category: L1RPCCategory, } RuntimeConfigReloadIntervalFlag = &cli.DurationFlag{ Name: "l1.runtime-config-reload-interval", Usage: "Poll interval for reloading the runtime config, useful when config events are not being picked up. Disabled if 0 or negative.", EnvVars: prefixEnvVars("L1_RUNTIME_CONFIG_RELOAD_INTERVAL"), - Required: false, Value: time.Minute * 10, + Category: L1RPCCategory, } MetricsEnabledFlag = &cli.BoolFlag{ - Name: "metrics.enabled", - Usage: "Enable the metrics server", - EnvVars: prefixEnvVars("METRICS_ENABLED"), + Name: "metrics.enabled", + Usage: "Enable the metrics server", + EnvVars: prefixEnvVars("METRICS_ENABLED"), + Category: OperationsCategory, } MetricsAddrFlag = &cli.StringFlag{ - Name: "metrics.addr", - Usage: "Metrics listening address", - Value: "0.0.0.0", // TODO(CLI-4159): Switch to 127.0.0.1 - EnvVars: prefixEnvVars("METRICS_ADDR"), + Name: "metrics.addr", + Usage: "Metrics listening address", + Value: "0.0.0.0", // TODO(CLI-4159): Switch to 127.0.0.1 + EnvVars: prefixEnvVars("METRICS_ADDR"), + Category: OperationsCategory, } MetricsPortFlag = &cli.IntFlag{ - Name: "metrics.port", - Usage: "Metrics listening port", - Value: 7300, - EnvVars: prefixEnvVars("METRICS_PORT"), - } - PprofEnabledFlag = &cli.BoolFlag{ - Name: "pprof.enabled", - Usage: "Enable the pprof server", - EnvVars: prefixEnvVars("PPROF_ENABLED"), - } - PprofAddrFlag = &cli.StringFlag{ - Name: "pprof.addr", - Usage: "pprof listening address", - Value: "0.0.0.0", // TODO(CLI-4159): Switch to 127.0.0.1 - EnvVars: prefixEnvVars("PPROF_ADDR"), - } - PprofPortFlag = &cli.IntFlag{ - Name: "pprof.port", - Usage: "pprof listening port", - Value: 6060, - EnvVars: prefixEnvVars("PPROF_PORT"), + Name: "metrics.port", + Usage: "Metrics listening port", + Value: 7300, + EnvVars: prefixEnvVars("METRICS_PORT"), + Category: OperationsCategory, } SnapshotLog = &cli.StringFlag{ - Name: "snapshotlog.file", - Usage: "Path to the snapshot log file", - EnvVars: prefixEnvVars("SNAPSHOT_LOG"), + Name: "snapshotlog.file", + Usage: "Path to the snapshot log file", + EnvVars: prefixEnvVars("SNAPSHOT_LOG"), + Category: OperationsCategory, } HeartbeatEnabledFlag = &cli.BoolFlag{ - Name: "heartbeat.enabled", - Usage: "Enables or disables heartbeating", - EnvVars: prefixEnvVars("HEARTBEAT_ENABLED"), + Name: "heartbeat.enabled", + Usage: "Enables or disables heartbeating", + EnvVars: prefixEnvVars("HEARTBEAT_ENABLED"), + Category: OperationsCategory, } HeartbeatMonikerFlag = &cli.StringFlag{ - Name: "heartbeat.moniker", - Usage: "Sets a moniker for this node", - EnvVars: prefixEnvVars("HEARTBEAT_MONIKER"), + Name: "heartbeat.moniker", + Usage: "Sets a moniker for this node", + EnvVars: prefixEnvVars("HEARTBEAT_MONIKER"), + Category: OperationsCategory, } HeartbeatURLFlag = &cli.StringFlag{ - Name: "heartbeat.url", - Usage: "Sets the URL to heartbeat to", - EnvVars: prefixEnvVars("HEARTBEAT_URL"), - Value: "https://heartbeat.optimism.io", - } - BackupL2UnsafeSyncRPC = &cli.StringFlag{ - Name: "l2.backup-unsafe-sync-rpc", - Usage: "Set the backup L2 unsafe sync RPC endpoint.", - EnvVars: prefixEnvVars("L2_BACKUP_UNSAFE_SYNC_RPC"), - Required: false, + Name: "heartbeat.url", + Usage: "Sets the URL to heartbeat to", + EnvVars: prefixEnvVars("HEARTBEAT_URL"), + Value: "https://heartbeat.optimism.io", + Category: OperationsCategory, } - BackupL2UnsafeSyncRPCTrustRPC = &cli.StringFlag{ - Name: "l2.backup-unsafe-sync-rpc.trustrpc", - Usage: "Like l1.trustrpc, configure if response data from the RPC needs to be verified, e.g. blockhash computation." + - "This does not include checks if the blockhash is part of the canonical chain.", - EnvVars: prefixEnvVars("L2_BACKUP_UNSAFE_SYNC_RPC_TRUST_RPC"), - Required: false, + RollupHalt = &cli.StringFlag{ + Name: "rollup.halt", + Usage: "Opt-in option to halt on incompatible protocol version requirements of the given level (major/minor/patch/none), as signaled onchain in L1", + EnvVars: prefixEnvVars("ROLLUP_HALT"), + Category: RollupCategory, } + RollupLoadProtocolVersions = &cli.BoolFlag{ + Name: "rollup.load-protocol-versions", + Usage: "Load protocol versions from the superchain L1 ProtocolVersions contract (if available), and report in logs and metrics", + EnvVars: prefixEnvVars("ROLLUP_LOAD_PROTOCOL_VERSIONS"), + Category: RollupCategory, + } + SafeDBPath = &cli.StringFlag{ + Name: "safedb.path", + Usage: "File path used to persist safe head update data. Disabled if not set.", + EnvVars: prefixEnvVars("SAFEDB_PATH"), + Category: OperationsCategory, + } + /* Deprecated Flags */ L2EngineSyncEnabled = &cli.BoolFlag{ - Name: "l2.engine-sync", - Usage: "Enables or disables execution engine P2P sync", - EnvVars: prefixEnvVars("L2_ENGINE_SYNC_ENABLED"), - Required: false, - Value: true, + Name: "l2.engine-sync", + Usage: "WARNING: Deprecated. Use --syncmode=execution-layer instead", + EnvVars: prefixEnvVars("L2_ENGINE_SYNC_ENABLED"), + Value: false, + Hidden: true, } SkipSyncStartCheck = &cli.BoolFlag{ Name: "l2.skip-sync-start-check", Usage: "Skip sanity check of consistency of L1 origins of the unsafe L2 blocks when determining the sync-starting point. " + "This defers the L1-origin verification, and is recommended to use in when utilizing l2.engine-sync", - EnvVars: prefixEnvVars("L2_SKIP_SYNC_START_CHECK"), - Required: false, - Value: true, + EnvVars: prefixEnvVars("L2_SKIP_SYNC_START_CHECK"), + Value: false, + Hidden: true, } BetaExtraNetworks = &cli.BoolFlag{ Name: "beta.extra-networks", @@ -254,40 +325,63 @@ var ( EnvVars: prefixEnvVars("BETA_EXTRA_NETWORKS"), Hidden: true, // hidden, this is deprecated, the flag is not used anymore. } - RollupHalt = &cli.StringFlag{ - Name: "rollup.halt", - Usage: "Opt-in option to halt on incompatible protocol version requirements of the given level (major/minor/patch/none), as signaled onchain in L1", - EnvVars: prefixEnvVars("ROLLUP_HALT"), - } - RollupLoadProtocolVersions = &cli.BoolFlag{ - Name: "rollup.load-protocol-versions", - Usage: "Load protocol versions from the superchain L1 ProtocolVersions contract (if available), and report in logs and metrics", - EnvVars: prefixEnvVars("ROLLUP_LOAD_PROTOCOL_VERSIONS"), + BackupL2UnsafeSyncRPC = &cli.StringFlag{ + Name: "l2.backup-unsafe-sync-rpc", + Usage: "Set the backup L2 unsafe sync RPC endpoint.", + EnvVars: prefixEnvVars("L2_BACKUP_UNSAFE_SYNC_RPC"), + Hidden: true, } - CanyonOverrideFlag = &cli.Uint64Flag{ - Name: "override.canyon", - Usage: "Manually specify the Canyon fork timestamp, overriding the bundled setting", - EnvVars: prefixEnvVars("OVERRIDE_CANYON"), - Hidden: false, + BackupL2UnsafeSyncRPCTrustRPC = &cli.StringFlag{ + Name: "l2.backup-unsafe-sync-rpc.trustrpc", + Usage: "Like l1.trustrpc, configure if response data from the RPC needs to be verified, e.g. blockhash computation." + + "This does not include checks if the blockhash is part of the canonical chain.", + EnvVars: prefixEnvVars("L2_BACKUP_UNSAFE_SYNC_RPC_TRUST_RPC"), + Hidden: true, + } + ConductorEnabledFlag = &cli.BoolFlag{ + Name: "conductor.enabled", + Usage: "Enable the conductor service", + EnvVars: prefixEnvVars("CONDUCTOR_ENABLED"), + Value: false, + Category: SequencerCategory, + } + ConductorRpcFlag = &cli.StringFlag{ + Name: "conductor.rpc", + Usage: "Conductor service rpc endpoint", + EnvVars: prefixEnvVars("CONDUCTOR_RPC"), + Value: "http://127.0.0.1:8547", + Category: SequencerCategory, + } + ConductorRpcTimeoutFlag = &cli.DurationFlag{ + Name: "conductor.rpc-timeout", + Usage: "Conductor service rpc timeout", + EnvVars: prefixEnvVars("CONDUCTOR_RPC_TIMEOUT"), + Value: time.Second * 1, + Category: SequencerCategory, } ) var requiredFlags = []cli.Flag{ L1NodeAddr, L2EngineAddr, + L2EngineJWTSecret, } var optionalFlags = []cli.Flag{ + BeaconAddr, + BeaconHeader, + BeaconArchiverAddr, + BeaconCheckIgnore, + BeaconFetchAllSidecars, + SyncModeFlag, RPCListenAddr, RPCListenPort, - RollupConfig, - Network, L1TrustRPC, L1RPCProviderKind, L1RPCRateLimit, L1RPCMaxBatchSize, + L1RPCMaxConcurrency, L1HTTPPollInterval, - L2EngineJWTSecret, VerifierL1Confs, SequencerEnabledFlag, SequencerStoppedFlag, @@ -301,30 +395,39 @@ var optionalFlags = []cli.Flag{ MetricsEnabledFlag, MetricsAddrFlag, MetricsPortFlag, - PprofEnabledFlag, - PprofAddrFlag, - PprofPortFlag, SnapshotLog, HeartbeatEnabledFlag, HeartbeatMonikerFlag, HeartbeatURLFlag, - BackupL2UnsafeSyncRPC, - BackupL2UnsafeSyncRPCTrustRPC, - L2EngineSyncEnabled, - SkipSyncStartCheck, - BetaExtraNetworks, RollupHalt, RollupLoadProtocolVersions, - CanyonOverrideFlag, L1RethDBPath, + ConductorEnabledFlag, + ConductorRpcFlag, + ConductorRpcTimeoutFlag, + SafeDBPath, +} + +var DeprecatedFlags = []cli.Flag{ + L2EngineSyncEnabled, + SkipSyncStartCheck, + BetaExtraNetworks, + BackupL2UnsafeSyncRPC, + BackupL2UnsafeSyncRPCTrustRPC, + // Deprecated P2P Flags are added at the init step } // Flags contains the list of configuration options available to the binary. var Flags []cli.Flag func init() { + DeprecatedFlags = append(DeprecatedFlags, deprecatedP2PFlags(EnvVarPrefix)...) optionalFlags = append(optionalFlags, P2PFlags(EnvVarPrefix)...) - optionalFlags = append(optionalFlags, oplog.CLIFlags(EnvVarPrefix)...) + optionalFlags = append(optionalFlags, oplog.CLIFlagsWithCategory(EnvVarPrefix, OperationsCategory)...) + optionalFlags = append(optionalFlags, oppprof.CLIFlagsWithCategory(EnvVarPrefix, OperationsCategory)...) + optionalFlags = append(optionalFlags, DeprecatedFlags...) + optionalFlags = append(optionalFlags, opflags.CLIFlags(EnvVarPrefix, RollupCategory)...) + optionalFlags = append(optionalFlags, plasma.CLIFlags(EnvVarPrefix, PlasmaCategory)...) Flags = append(requiredFlags, optionalFlags...) } @@ -334,5 +437,5 @@ func CheckRequired(ctx *cli.Context) error { return fmt.Errorf("flag %s is required", f.Names()[0]) } } - return nil + return opflags.CheckRequiredXor(ctx) } diff --git a/op-node/flags/flags_test.go b/op-node/flags/flags_test.go index c45b72d9ee8c..90884bd32f30 100644 --- a/op-node/flags/flags_test.go +++ b/op-node/flags/flags_test.go @@ -1,10 +1,12 @@ package flags import ( + "slices" "strings" "testing" - "github.com/stretchr/testify/assert" + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" ) @@ -23,12 +25,13 @@ func TestOptionalFlagsDontSetRequired(t *testing.T) { func TestUniqueFlags(t *testing.T) { seenCLI := make(map[string]struct{}) for _, flag := range Flags { - name := flag.Names()[0] - if _, ok := seenCLI[name]; ok { - t.Errorf("duplicate flag %s", name) - continue + for _, name := range flag.Names() { + if _, ok := seenCLI[name]; ok { + t.Errorf("duplicate flag %s", name) + continue + } + seenCLI[name] = struct{}{} } - seenCLI[name] = struct{}{} } } @@ -44,10 +47,90 @@ func TestBetaFlags(t *testing.T) { name := flag.Names()[0] envName := envFlag.GetEnvVars()[0] if strings.HasPrefix(name, "beta.") { - assert.Contains(t, envName, "BETA_", "%q flag must contain BETA in env var to match \"beta.\" flag name", name) + require.Contains(t, envName, "BETA_", "%q flag must contain BETA in env var to match \"beta.\" flag name", name) } if strings.Contains(envName, "BETA_") { - assert.True(t, strings.HasPrefix(name, "beta."), "%q flag must start with \"beta.\" in flag name to match \"BETA_\" env var", name) + require.True(t, strings.HasPrefix(name, "beta."), "%q flag must start with \"beta.\" in flag name to match \"BETA_\" env var", name) } } } + +func TestDeprecatedFlagsAreHidden(t *testing.T) { + for _, flag := range DeprecatedFlags { + flag := flag + flagName := flag.Names()[0] + + t.Run(flagName, func(t *testing.T) { + + visibleFlag, ok := flag.(interface { + IsVisible() bool + }) + require.True(t, ok, "Need to case the flag to the correct format") + require.False(t, visibleFlag.IsVisible()) + }) + } +} + +func TestHasEnvVar(t *testing.T) { + for _, flag := range Flags { + flag := flag + flagName := flag.Names()[0] + + t.Run(flagName, func(t *testing.T) { + if flagName == PeerScoringName || flagName == PeerScoreBandsName || flagName == TopicScoringName { + t.Skipf("Skipping flag %v which is known to have no env vars", flagName) + } + envFlagGetter, ok := flag.(interface { + GetEnvVars() []string + }) + envFlags := envFlagGetter.GetEnvVars() + require.True(t, ok, "must be able to cast the flag to an EnvVar interface") + require.Equal(t, 1, len(envFlags), "flags should have exactly one env var") + }) + } +} + +func TestEnvVarFormat(t *testing.T) { + for _, flag := range Flags { + flag := flag + flagName := flag.Names()[0] + + skippedFlags := []string{ + L1NodeAddr.Name, + L2EngineAddr.Name, + L2EngineJWTSecret.Name, + L1TrustRPC.Name, + L1RPCProviderKind.Name, + SnapshotLog.Name, + BackupL2UnsafeSyncRPC.Name, + BackupL2UnsafeSyncRPCTrustRPC.Name, + "p2p.scoring", + "p2p.ban.peers", + "p2p.ban.threshold", + "p2p.ban.duration", + "p2p.listen.tcp", + "p2p.listen.udp", + "p2p.useragent", + "p2p.gossip.mesh.lo", + "p2p.gossip.mesh.floodpublish", + "l2.engine-sync", + } + + t.Run(flagName, func(t *testing.T) { + if slices.Contains(skippedFlags, flagName) { + t.Skipf("Skipping flag %v which is known to not have a standard flag name <-> env var conversion", flagName) + } + if flagName == PeerScoringName || flagName == PeerScoreBandsName || flagName == TopicScoringName { + t.Skipf("Skipping flag %v which is known to have no env vars", flagName) + } + envFlagGetter, ok := flag.(interface { + GetEnvVars() []string + }) + envFlags := envFlagGetter.GetEnvVars() + require.True(t, ok, "must be able to cast the flag to an EnvVar interface") + require.Equal(t, 1, len(envFlags), "flags should have exactly one env var") + expectedEnvVar := opservice.FlagNameToEnvVarName(flagName, "OP_NODE") + require.Equal(t, expectedEnvVar, envFlags[0]) + }) + } +} diff --git a/op-node/flags/p2p_flags.go b/op-node/flags/p2p_flags.go index 303d95a2d61b..1489a811801b 100644 --- a/op-node/flags/p2p_flags.go +++ b/op-node/flags/p2p_flags.go @@ -53,8 +53,36 @@ var ( GossipMeshDlazyName = "p2p.gossip.mesh.dlazy" GossipFloodPublishName = "p2p.gossip.mesh.floodpublish" SyncReqRespName = "p2p.sync.req-resp" + P2PPingName = "p2p.ping" ) +func deprecatedP2PFlags(envPrefix string) []cli.Flag { + return []cli.Flag{ + &cli.StringFlag{ + Name: PeerScoringName, + Usage: fmt.Sprintf("Deprecated: Use %v instead", ScoringName), + Required: false, + Hidden: true, + Category: P2PCategory, + }, + &cli.StringFlag{ + Name: PeerScoreBandsName, + Usage: "Deprecated. This option is ignored and is only present for backwards compatibility.", + Required: false, + Value: "", + Hidden: true, + Category: P2PCategory, + }, + &cli.StringFlag{ + Name: TopicScoringName, + Usage: fmt.Sprintf("Deprecated: Use %v instead", ScoringName), + Required: false, + Hidden: true, + Category: P2PCategory, + }, + } +} + // None of these flags are strictly required. // Some are hidden if they are too technical, or not recommended. func P2PFlags(envPrefix string) []cli.Flag { @@ -64,12 +92,14 @@ func P2PFlags(envPrefix string) []cli.Flag { Usage: "Completely disable the P2P stack", Required: false, EnvVars: p2pEnv(envPrefix, "DISABLE"), + Category: P2PCategory, }, &cli.BoolFlag{ Name: NoDiscoveryName, Usage: "Disable Discv5 (node discovery)", Required: false, EnvVars: p2pEnv(envPrefix, "NO_DISCOVERY"), + Category: P2PCategory, }, &cli.StringFlag{ Name: ScoringName, @@ -77,19 +107,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: "light", EnvVars: p2pEnv(envPrefix, "PEER_SCORING"), - }, - &cli.StringFlag{ - Name: PeerScoringName, - Usage: fmt.Sprintf("Deprecated: Use %v instead", ScoringName), - Required: false, - Hidden: true, - }, - &cli.StringFlag{ - Name: PeerScoreBandsName, - Usage: "Deprecated. This option is ignored and is only present for backwards compatibility.", - Required: false, - Value: "", - Hidden: true, + Category: P2PCategory, }, &cli.BoolFlag{ // Banning Flag - whether or not we want to act on the scoring @@ -98,6 +116,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Value: true, Required: false, EnvVars: p2pEnv(envPrefix, "PEER_BANNING"), + Category: P2PCategory, }, &cli.Float64Flag{ Name: BanningThresholdName, @@ -105,6 +124,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: -100, EnvVars: p2pEnv(envPrefix, "PEER_BANNING_THRESHOLD"), + Category: P2PCategory, }, &cli.DurationFlag{ Name: BanningDurationName, @@ -112,12 +132,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 1 * time.Hour, EnvVars: p2pEnv(envPrefix, "PEER_BANNING_DURATION"), - }, - &cli.StringFlag{ - Name: TopicScoringName, - Usage: fmt.Sprintf("Deprecated: Use %v instead", ScoringName), - Required: false, - Hidden: true, + Category: P2PCategory, }, &cli.StringFlag{ Name: P2PPrivPathName, @@ -127,6 +142,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Value: "opnode_p2p_priv.txt", EnvVars: p2pEnv(envPrefix, "PRIV_PATH"), TakesFile: true, + Category: P2PCategory, }, &cli.StringFlag{ // sometimes it may be ok to not persist the peer priv key as file, and instead pass it directly. @@ -136,6 +152,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Hidden: true, Value: "", EnvVars: p2pEnv(envPrefix, "PRIV_RAW"), + Category: P2PCategory, }, &cli.StringFlag{ Name: ListenIPName, @@ -143,6 +160,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: "0.0.0.0", EnvVars: p2pEnv(envPrefix, "LISTEN_IP"), + Category: P2PCategory, }, &cli.UintFlag{ Name: ListenTCPPortName, @@ -150,6 +168,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 9003, EnvVars: p2pEnv(envPrefix, "LISTEN_TCP_PORT"), + Category: P2PCategory, }, &cli.UintFlag{ Name: ListenUDPPortName, @@ -157,6 +176,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 9003, // can simply match the TCP libp2p port EnvVars: p2pEnv(envPrefix, "LISTEN_UDP_PORT"), + Category: P2PCategory, }, &cli.StringFlag{ Name: AdvertiseIPName, @@ -164,8 +184,9 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, // Ignored by default, nodes can discover their own external IP in the happy case, // by communicating with bootnodes. Fixed IP is recommended for faster bootstrap though. - Value: "", - EnvVars: p2pEnv(envPrefix, "ADVERTISE_IP"), + Value: "", + EnvVars: p2pEnv(envPrefix, "ADVERTISE_IP"), + Category: P2PCategory, }, &cli.UintFlag{ Name: AdvertiseTCPPortName, @@ -173,6 +194,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 0, EnvVars: p2pEnv(envPrefix, "ADVERTISE_TCP"), + Category: P2PCategory, }, &cli.UintFlag{ Name: AdvertiseUDPPortName, @@ -180,6 +202,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 0, EnvVars: p2pEnv(envPrefix, "ADVERTISE_UDP"), + Category: P2PCategory, }, &cli.StringFlag{ Name: BootnodesName, @@ -187,19 +210,23 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: "", EnvVars: p2pEnv(envPrefix, "BOOTNODES"), + Category: P2PCategory, }, &cli.StringFlag{ - Name: StaticPeersName, - Usage: "Comma-separated multiaddr-format peer list. Static connections to make and maintain, these peers will be regarded as trusted.", + Name: StaticPeersName, + Usage: "Comma-separated multiaddr-format peer list. Static connections to make and maintain, these peers will be regarded as trusted. " + + "Addresses of the local peer are ignored. Duplicate/Alternative addresses for the same peer all apply, but only a single connection per peer is maintained.", Required: false, Value: "", EnvVars: p2pEnv(envPrefix, "STATIC"), + Category: P2PCategory, }, &cli.StringFlag{ Name: NetRestrictName, Usage: "Comma-separated list of CIDR masks. P2P will only try to connect on these networks", Required: false, EnvVars: p2pEnv(envPrefix, "NETRESTRICT"), + Category: P2PCategory, }, &cli.StringFlag{ Name: HostMuxName, @@ -208,6 +235,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: "yamux,mplex", EnvVars: p2pEnv(envPrefix, "MUX"), + Category: P2PCategory, }, &cli.StringFlag{ Name: HostSecurityName, @@ -216,6 +244,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: "noise", EnvVars: p2pEnv(envPrefix, "SECURITY"), + Category: P2PCategory, }, &cli.UintFlag{ Name: PeersLoName, @@ -223,6 +252,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 20, EnvVars: p2pEnv(envPrefix, "PEERS_LO"), + Category: P2PCategory, }, &cli.UintFlag{ Name: PeersHiName, @@ -230,6 +260,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 30, EnvVars: p2pEnv(envPrefix, "PEERS_HI"), + Category: P2PCategory, }, &cli.DurationFlag{ Name: PeersGraceName, @@ -237,12 +268,14 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 30 * time.Second, EnvVars: p2pEnv(envPrefix, "PEERS_GRACE"), + Category: P2PCategory, }, &cli.BoolFlag{ Name: NATName, Usage: "Enable NAT traversal with PMP/UPNP devices to learn external IP.", Required: false, EnvVars: p2pEnv(envPrefix, "NAT"), + Category: P2PCategory, }, &cli.StringFlag{ Name: UserAgentName, @@ -251,6 +284,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: "optimism", EnvVars: p2pEnv(envPrefix, "AGENT"), + Category: P2PCategory, }, &cli.DurationFlag{ Name: TimeoutNegotiationName, @@ -259,6 +293,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 10 * time.Second, EnvVars: p2pEnv(envPrefix, "TIMEOUT_NEGOTIATION"), + Category: P2PCategory, }, &cli.DurationFlag{ Name: TimeoutAcceptName, @@ -267,6 +302,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 10 * time.Second, EnvVars: p2pEnv(envPrefix, "TIMEOUT_ACCEPT"), + Category: P2PCategory, }, &cli.DurationFlag{ Name: TimeoutDialName, @@ -275,6 +311,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: 10 * time.Second, EnvVars: p2pEnv(envPrefix, "TIMEOUT_DIAL"), + Category: P2PCategory, }, &cli.StringFlag{ Name: PeerstorePathName, @@ -285,6 +322,7 @@ func P2PFlags(envPrefix string) []cli.Flag { TakesFile: true, Value: "opnode_peerstore_db", EnvVars: p2pEnv(envPrefix, "PEERSTORE_PATH"), + Category: P2PCategory, }, &cli.StringFlag{ Name: DiscoveryPathName, @@ -293,6 +331,7 @@ func P2PFlags(envPrefix string) []cli.Flag { TakesFile: true, Value: "opnode_discovery_db", EnvVars: p2pEnv(envPrefix, "DISCOVERY_PATH"), + Category: P2PCategory, }, &cli.StringFlag{ Name: SequencerP2PKeyName, @@ -300,6 +339,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Value: "", EnvVars: p2pEnv(envPrefix, "SEQUENCER_KEY"), + Category: P2PCategory, }, &cli.UintFlag{ Name: GossipMeshDName, @@ -308,6 +348,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Hidden: true, Value: p2p.DefaultMeshD, EnvVars: p2pEnv(envPrefix, "GOSSIP_MESH_D"), + Category: P2PCategory, }, &cli.UintFlag{ Name: GossipMeshDloName, @@ -316,6 +357,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Hidden: true, Value: p2p.DefaultMeshDlo, EnvVars: p2pEnv(envPrefix, "GOSSIP_MESH_DLO"), + Category: P2PCategory, }, &cli.UintFlag{ Name: GossipMeshDhiName, @@ -324,6 +366,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Hidden: true, Value: p2p.DefaultMeshDhi, EnvVars: p2pEnv(envPrefix, "GOSSIP_MESH_DHI"), + Category: P2PCategory, }, &cli.UintFlag{ Name: GossipMeshDlazyName, @@ -332,6 +375,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Hidden: true, Value: p2p.DefaultMeshDlazy, EnvVars: p2pEnv(envPrefix, "GOSSIP_MESH_DLAZY"), + Category: P2PCategory, }, &cli.BoolFlag{ Name: GossipFloodPublishName, @@ -339,6 +383,7 @@ func P2PFlags(envPrefix string) []cli.Flag { Required: false, Hidden: true, EnvVars: p2pEnv(envPrefix, "GOSSIP_FLOOD_PUBLISH"), + Category: P2PCategory, }, &cli.BoolFlag{ Name: SyncReqRespName, @@ -346,6 +391,15 @@ func P2PFlags(envPrefix string) []cli.Flag { Value: true, Required: false, EnvVars: p2pEnv(envPrefix, "SYNC_REQ_RESP"), + Category: P2PCategory, + }, + &cli.BoolFlag{ + Name: P2PPingName, + Usage: "Enables P2P ping-pong background service", + Value: true, // on by default + Hidden: true, // hidden, only here to disable in case of bugs. + Required: false, + EnvVars: p2pEnv(envPrefix, "PING"), }, } } diff --git a/op-node/metrics/metrics.go b/op-node/metrics/metrics.go index 4c695ab99cac..22f4a2386a23 100644 --- a/op-node/metrics/metrics.go +++ b/op-node/metrics/metrics.go @@ -10,6 +10,8 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum-optimism/optimism/op-node/p2p/store" + plasma "github.com/ethereum-optimism/optimism/op-plasma" + ophttp "github.com/ethereum-optimism/optimism/op-service/httputil" "github.com/ethereum-optimism/optimism/op-service/metrics" @@ -41,11 +43,12 @@ type Metricer interface { RecordSequencingError() RecordPublishingError() RecordDerivationError() - RecordReceivedUnsafePayload(payload *eth.ExecutionPayload) + RecordReceivedUnsafePayload(payload *eth.ExecutionPayloadEnvelope) RecordRef(layer string, name string, num uint64, timestamp uint64, h common.Hash) RecordL1Ref(name string, ref eth.L1BlockRef) RecordL2Ref(name string, ref eth.L2BlockRef) RecordUnsafePayloadsBuffer(length uint64, memSize uint64, next eth.BlockID) + RecordDerivedBatches(batchType string) CountSequencedTxs(count int) RecordL1ReorgDepth(d uint64) RecordSequencerInconsistentL1Origin(from eth.BlockID, to eth.BlockID) @@ -97,6 +100,8 @@ type Metrics struct { PublishingErrors *metrics.Event L1UrlSwitchEvent *metrics.Event + DerivedBatches metrics.EventVec + P2PReqDurationSeconds *prometheus.HistogramVec P2PReqTotal *prometheus.CounterVec P2PPayloadByNumber *prometheus.GaugeVec @@ -125,6 +130,8 @@ type Metrics struct { TransactionsSequencedTotal prometheus.Counter + PlasmaMetrics plasma.Metricer + // Channel Bank Metrics headChannelOpenedEvent *metrics.Event channelTimedOutEvent *metrics.Event @@ -199,6 +206,8 @@ func NewMetrics(procName string) *Metrics { PublishingErrors: metrics.NewEvent(factory, ns, "", "publishing_errors", "p2p publishing errors"), L1UrlSwitchEvent: metrics.NewEvent(factory, ns, "", "l1_url_switch", "L1 URL switch events"), + DerivedBatches: metrics.NewEventVec(factory, ns, "", "derived_batches", "derived batches", []string{"type"}), + SequencerInconsistentL1Origin: metrics.NewEvent(factory, ns, "", "sequencer_inconsistent_l1_origin", "events when the sequencer selects an inconsistent L1 origin"), SequencerResets: metrics.NewEvent(factory, ns, "", "sequencer_resets", "sequencer resets"), @@ -237,7 +246,7 @@ func NewMetrics(procName string) *Metrics { PeerScores: factory.NewHistogramVec(prometheus.HistogramOpts{ Namespace: ns, Name: "peer_scores", - Help: "Histogram of currrently connected peer scores", + Help: "Histogram of currently connected peer scores", Buckets: []float64{-100, -40, -20, -10, -5, -2, -1, -0.5, -0.05, 0, 0.05, 0.5, 1, 2, 5, 10, 20, 40}, }, []string{"type"}), StreamCount: factory.NewGauge(prometheus.GaugeOpts{ @@ -394,6 +403,8 @@ func NewMetrics(procName string) *Metrics { "required", }), + PlasmaMetrics: plasma.MakeMetrics(ns, factory), + registry: registry, factory: factory, } @@ -453,9 +464,9 @@ func (m *Metrics) RecordDerivationError() { m.DerivationErrors.Record() } -func (m *Metrics) RecordReceivedUnsafePayload(payload *eth.ExecutionPayload) { +func (m *Metrics) RecordReceivedUnsafePayload(payload *eth.ExecutionPayloadEnvelope) { m.UnsafePayloads.Record() - m.RecordRef("l2", "received_payload", uint64(payload.BlockNumber), uint64(payload.Timestamp), payload.BlockHash) + m.RecordRef("l2", "received_payload", uint64(payload.ExecutionPayload.BlockNumber), uint64(payload.ExecutionPayload.Timestamp), payload.ExecutionPayload.BlockHash) } func (m *Metrics) RecordUnsafePayloadsBuffer(length uint64, memSize uint64, next eth.BlockID) { @@ -464,6 +475,10 @@ func (m *Metrics) RecordUnsafePayloadsBuffer(length uint64, memSize uint64, next m.UnsafePayloadsBufferMemSize.Set(float64(memSize)) } +func (m *Metrics) RecordDerivedBatches(batchType string) { + m.DerivedBatches.Record(batchType) +} + func (m *Metrics) CountSequencedTxs(count int) { m.TransactionsSequencedTotal.Add(float64(count)) } @@ -659,7 +674,7 @@ func (n *noopMetricer) RecordPublishingError() { func (n *noopMetricer) RecordDerivationError() { } -func (n *noopMetricer) RecordReceivedUnsafePayload(payload *eth.ExecutionPayload) { +func (n *noopMetricer) RecordReceivedUnsafePayload(payload *eth.ExecutionPayloadEnvelope) { } func (n *noopMetricer) RecordRef(layer string, name string, num uint64, timestamp uint64, h common.Hash) { @@ -674,6 +689,9 @@ func (n *noopMetricer) RecordL2Ref(name string, ref eth.L2BlockRef) { func (n *noopMetricer) RecordUnsafePayloadsBuffer(length uint64, memSize uint64, next eth.BlockID) { } +func (n *noopMetricer) RecordDerivedBatches(batchType string) { +} + func (n *noopMetricer) CountSequencedTxs(count int) { } diff --git a/op-node/node/api.go b/op-node/node/api.go index f105443f49d7..d6252c84540e 100644 --- a/op-node/node/api.go +++ b/op-node/node/api.go @@ -2,8 +2,10 @@ package node import ( "context" + "errors" "fmt" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" @@ -30,6 +32,11 @@ type driverClient interface { StartSequencer(ctx context.Context, blockHash common.Hash) error StopSequencer(context.Context) (common.Hash, error) SequencerActive(context.Context) (bool, error) + OnUnsafeL2Payload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error +} + +type SafeDBReader interface { + SafeHeadAtL1(ctx context.Context, l1BlockNum uint64) (l1 eth.BlockID, l2 eth.BlockID, err error) } type adminAPI struct { @@ -68,19 +75,37 @@ func (n *adminAPI) SequencerActive(ctx context.Context) (bool, error) { return n.dr.SequencerActive(ctx) } +// PostUnsafePayload is a special API that allow posting an unsafe payload to the L2 derivation pipeline. +// It should only be used by op-conductor for sequencer failover scenarios. +// TODO(ethereum-optimism/optimism#9064): op-conductor Dencun changes. +func (n *adminAPI) PostUnsafePayload(ctx context.Context, envelope *eth.ExecutionPayloadEnvelope) error { + recordDur := n.M.RecordRPCServerRequest("admin_postUnsafePayload") + defer recordDur() + + payload := envelope.ExecutionPayload + if actual, ok := envelope.CheckBlockHash(); !ok { + log.Error("payload has bad block hash", "bad_hash", payload.BlockHash.String(), "actual", actual.String()) + return fmt.Errorf("payload has bad block hash: %s, actual block hash is: %s", payload.BlockHash.String(), actual.String()) + } + + return n.dr.OnUnsafeL2Payload(ctx, envelope) +} + type nodeAPI struct { config *rollup.Config client l2EthClient dr driverClient + safeDB SafeDBReader log log.Logger m metrics.RPCMetricer } -func NewNodeAPI(config *rollup.Config, l2Client l2EthClient, dr driverClient, log log.Logger, m metrics.RPCMetricer) *nodeAPI { +func NewNodeAPI(config *rollup.Config, l2Client l2EthClient, dr driverClient, safeDB SafeDBReader, log log.Logger, m metrics.RPCMetricer) *nodeAPI { return &nodeAPI{ config: config, client: l2Client, dr: dr, + safeDB: safeDB, log: log, m: m, } @@ -109,6 +134,21 @@ func (n *nodeAPI) OutputAtBlock(ctx context.Context, number hexutil.Uint64) (*et }, nil } +func (n *nodeAPI) SafeHeadAtL1Block(ctx context.Context, number hexutil.Uint64) (*eth.SafeHeadResponse, error) { + recordDur := n.m.RecordRPCServerRequest("optimism_safeHeadAtL1Block") + defer recordDur() + l1Block, safeHead, err := n.safeDB.SafeHeadAtL1(ctx, uint64(number)) + if errors.Is(err, safedb.ErrNotFound) { + return nil, err + } else if err != nil { + return nil, fmt.Errorf("failed to get safe head at l1 block %s: %w", number, err) + } + return ð.SafeHeadResponse{ + L1Block: l1Block, + SafeHead: safeHead, + }, nil +} + func (n *nodeAPI) SyncStatus(ctx context.Context) (*eth.SyncStatus, error) { recordDur := n.m.RecordRPCServerRequest("optimism_syncStatus") defer recordDur() diff --git a/op-node/node/client.go b/op-node/node/client.go index 896e1938d1b7..d6776d85993c 100644 --- a/op-node/node/client.go +++ b/op-node/node/client.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "net/http" + "strings" "time" "github.com/ethereum-optimism/optimism/op-node/rollup" @@ -22,13 +24,6 @@ type L2EndpointSetup interface { Check() error } -type L2SyncEndpointSetup interface { - // Setup a RPC client to another L2 node to sync L2 blocks from. - // It may return a nil client with nil error if RPC based sync is not enabled. - Setup(ctx context.Context, log log.Logger, rollupCfg *rollup.Config) (cl client.RPC, rpcCfg *sources.SyncClientConfig, err error) - Check() error -} - type L1EndpointSetup interface { // Setup a RPC client to a L1 node to pull rollup input-data from. // The results of the RPC client may be trusted for faster processing, or strictly validated. @@ -37,8 +32,18 @@ type L1EndpointSetup interface { Check() error } +type L1BeaconEndpointSetup interface { + Setup(ctx context.Context, log log.Logger) (cl sources.BeaconClient, fb []sources.BlobSideCarsFetcher, err error) + // ShouldIgnoreBeaconCheck returns true if the Beacon-node version check should not halt startup. + ShouldIgnoreBeaconCheck() bool + ShouldFetchAllSidecars() bool + Check() error +} + type L2EndpointConfig struct { - L2EngineAddr string // Address of L2 Engine JSON-RPC endpoint to use (engine and eth namespace required) + // L2EngineAddr is the address of the L2 Engine JSON-RPC endpoint to use. The engine and eth + // namespaces must be enabled by the endpoint. + L2EngineAddr string // JWT secrets for L2 Engine API authentication during HTTP or initial Websocket communication. // Any value for an IPC connection. @@ -90,50 +95,6 @@ func (p *PreparedL2Endpoints) Setup(ctx context.Context, log log.Logger, rollupC return p.Client, sources.EngineClientDefaultConfig(rollupCfg), nil } -// L2SyncEndpointConfig contains configuration for the fallback sync endpoint -type L2SyncEndpointConfig struct { - // Address of the L2 RPC to use for backup sync, may be empty if RPC alt-sync is disabled. - L2NodeAddr string - TrustRPC bool -} - -var _ L2SyncEndpointSetup = (*L2SyncEndpointConfig)(nil) - -// Setup creates an RPC client to sync from. -// It will return nil without error if no sync method is configured. -func (cfg *L2SyncEndpointConfig) Setup(ctx context.Context, log log.Logger, rollupCfg *rollup.Config) (client.RPC, *sources.SyncClientConfig, error) { - if cfg.L2NodeAddr == "" { - return nil, nil, nil - } - l2Node, err := client.NewRPC(ctx, log, cfg.L2NodeAddr) - if err != nil { - return nil, nil, err - } - - return l2Node, sources.SyncClientDefaultConfig(rollupCfg, cfg.TrustRPC), nil -} - -func (cfg *L2SyncEndpointConfig) Check() error { - // empty addr is valid, as it is optional. - return nil -} - -type PreparedL2SyncEndpoint struct { - // RPC endpoint to use for syncing, may be nil if RPC alt-sync is disabled. - Client client.RPC - TrustRPC bool -} - -var _ L2SyncEndpointSetup = (*PreparedL2SyncEndpoint)(nil) - -func (cfg *PreparedL2SyncEndpoint) Setup(ctx context.Context, log log.Logger, rollupCfg *rollup.Config) (client.RPC, *sources.SyncClientConfig, error) { - return cfg.Client, sources.SyncClientDefaultConfig(rollupCfg, cfg.TrustRPC), nil -} - -func (cfg *PreparedL2SyncEndpoint) Check() error { - return nil -} - type L1EndpointConfig struct { L1NodeAddr string // Address of L1 User JSON-RPC endpoint to use (eth namespace required) @@ -152,6 +113,9 @@ type L1EndpointConfig struct { // BatchSize specifies the maximum batch-size, which also applies as L1 rate-limit burst amount (if set). BatchSize int + // MaxConcurrency specifies the maximum number of concurrent requests to the L1 RPC. + MaxConcurrency int + // HttpPollInterval specifies the interval between polling for the latest L1 block, // when the RPC is detected to be an HTTP type. // It is recommended to use websockets or IPC for efficient following of the changing block. @@ -168,6 +132,9 @@ func (cfg *L1EndpointConfig) Check() error { if cfg.RateLimit < 0 { return fmt.Errorf("rate limit cannot be negative") } + if cfg.MaxConcurrency < 1 { + return fmt.Errorf("max concurrent requests cannot be less than 1, was %d", cfg.MaxConcurrency) + } return nil } @@ -191,6 +158,7 @@ func (cfg *L1EndpointConfig) Setup(ctx context.Context, log log.Logger, rollupCf } rpcCfg := sources.L1ClientDefaultConfig(rollupCfg, cfg.L1TrustRPC, cfg.L1RPCKind) rpcCfg.MaxRequestsPerBatch = cfg.BatchSize + rpcCfg.MaxConcurrentRequests = cfg.MaxConcurrency return l1Node, rpcCfg, nil } @@ -204,6 +172,7 @@ func fallbackClientWrap(ctx context.Context, logger log.Logger, urlList []string }) rpcCfg := sources.L1ClientDefaultConfig(rollupCfg, cfg.L1TrustRPC, cfg.L1RPCKind) rpcCfg.MaxRequestsPerBatch = cfg.BatchSize + rpcCfg.MaxConcurrentRequests = cfg.MaxConcurrency return l1Node, rpcCfg, nil } @@ -227,3 +196,56 @@ func (cfg *PreparedL1Endpoint) Check() error { return nil } + +type L1BeaconEndpointConfig struct { + BeaconAddr string // Address of L1 User Beacon-API endpoint to use (beacon namespace required) + BeaconHeader string // Optional HTTP header for all requests to L1 Beacon + BeaconArchiverAddr string // Address of L1 User Beacon-API Archive endpoint to use for expired blobs (beacon namespace required) + BeaconCheckIgnore bool // When false, halt startup if the beacon version endpoint fails + BeaconFetchAllSidecars bool // Whether to fetch all blob sidecars and filter locally +} + +var _ L1BeaconEndpointSetup = (*L1BeaconEndpointConfig)(nil) + +func (cfg *L1BeaconEndpointConfig) Setup(ctx context.Context, log log.Logger) (cl sources.BeaconClient, fb []sources.BlobSideCarsFetcher, err error) { + var opts []client.BasicHTTPClientOption + if cfg.BeaconHeader != "" { + hdr, err := parseHTTPHeader(cfg.BeaconHeader) + if err != nil { + return nil, nil, fmt.Errorf("parsing beacon header: %w", err) + } + opts = append(opts, client.WithHeader(hdr)) + } + + a := client.NewBasicHTTPClient(cfg.BeaconAddr, log, opts...) + if cfg.BeaconArchiverAddr != "" { + b := client.NewBasicHTTPClient(cfg.BeaconArchiverAddr, log) + fb = append(fb, sources.NewBeaconHTTPClient(b)) + } + return sources.NewBeaconHTTPClient(a), fb, nil +} + +func (cfg *L1BeaconEndpointConfig) Check() error { + if cfg.BeaconAddr == "" && !cfg.BeaconCheckIgnore { + return errors.New("expected L1 Beacon API endpoint, but got none") + } + return nil +} + +func (cfg *L1BeaconEndpointConfig) ShouldIgnoreBeaconCheck() bool { + return cfg.BeaconCheckIgnore +} + +func (cfg *L1BeaconEndpointConfig) ShouldFetchAllSidecars() bool { + return cfg.BeaconFetchAllSidecars +} + +func parseHTTPHeader(headerStr string) (http.Header, error) { + h := make(http.Header, 1) + s := strings.SplitN(headerStr, ": ", 2) + if len(s) != 2 { + return nil, errors.New("invalid header format") + } + h.Add(s[0], s[1]) + return h, nil +} diff --git a/op-node/node/client_test.go b/op-node/node/client_test.go new file mode 100644 index 000000000000..a5ab75fc5630 --- /dev/null +++ b/op-node/node/client_test.go @@ -0,0 +1,62 @@ +package node + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParseHTTPHeader(t *testing.T) { + for _, test := range []struct { + desc string + str string + expHdr http.Header + expErr bool + }{ + { + desc: "err-empty", + expErr: true, + }, + { + desc: "err-no-colon", + str: "Key", + expErr: true, + }, + { + desc: "err-only-key", + str: "Key:", + expErr: true, + }, + { + desc: "err-no-space", + str: "Key:value", + expErr: true, + }, + { + desc: "valid", + str: "Key: value", + expHdr: http.Header{"Key": []string{"value"}}, + }, + { + desc: "valid-small", + str: "key: value", + expHdr: http.Header{"Key": []string{"value"}}, + }, + { + desc: "valid-spaces-colons", + str: "X-Key: a long value with spaces: and: colons", + expHdr: http.Header{"X-Key": []string{"a long value with spaces: and: colons"}}, + }, + } { + t.Run(test.desc, func(t *testing.T) { + h, err := parseHTTPHeader(test.str) + if test.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, test.expHdr, h) + } + }) + } +} diff --git a/op-node/node/comms.go b/op-node/node/comms.go index 47cd3a4c0310..f5bbab40331e 100644 --- a/op-node/node/comms.go +++ b/op-node/node/comms.go @@ -11,17 +11,17 @@ import ( // Tracer configures the OpNode to share events type Tracer interface { OnNewL1Head(ctx context.Context, sig eth.L1BlockRef) - OnUnsafeL2Payload(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) - OnPublishL2Payload(ctx context.Context, payload *eth.ExecutionPayload) + OnUnsafeL2Payload(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) + OnPublishL2Payload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) } type noOpTracer struct{} func (n noOpTracer) OnNewL1Head(ctx context.Context, sig eth.L1BlockRef) {} -func (n noOpTracer) OnUnsafeL2Payload(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) { +func (n noOpTracer) OnUnsafeL2Payload(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) { } -func (n noOpTracer) OnPublishL2Payload(ctx context.Context, payload *eth.ExecutionPayload) {} +func (n noOpTracer) OnPublishL2Payload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) {} var _ Tracer = (*noOpTracer)(nil) diff --git a/op-node/node/conductor.go b/op-node/node/conductor.go new file mode 100644 index 000000000000..938b9f28c5b1 --- /dev/null +++ b/op-node/node/conductor.go @@ -0,0 +1,87 @@ +package node + +import ( + "context" + "fmt" + "time" + + "github.com/ethereum-optimism/optimism/op-node/metrics" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/retry" + "github.com/ethereum/go-ethereum/log" + + conductorRpc "github.com/ethereum-optimism/optimism/op-conductor/rpc" +) + +// ConductorClient is a client for the op-conductor RPC service. +type ConductorClient struct { + cfg *Config + metrics *metrics.Metrics + log log.Logger + apiClient *conductorRpc.APIClient +} + +var _ conductor.SequencerConductor = &ConductorClient{} + +// NewConductorClient returns a new conductor client for the op-conductor RPC service. +func NewConductorClient(cfg *Config, log log.Logger, metrics *metrics.Metrics) *ConductorClient { + return &ConductorClient{cfg: cfg, metrics: metrics, log: log} +} + +// Initialize initializes the conductor client. +func (c *ConductorClient) initialize() error { + if c.apiClient != nil { + return nil + } + conductorRpcClient, err := dial.DialRPCClientWithTimeout(context.Background(), time.Minute*1, c.log, c.cfg.ConductorRpc) + if err != nil { + return fmt.Errorf("failed to dial conductor RPC: %w", err) + } + c.apiClient = conductorRpc.NewAPIClient(conductorRpcClient) + return nil +} + +// Leader returns true if this node is the leader sequencer. +func (c *ConductorClient) Leader(ctx context.Context) (bool, error) { + if err := c.initialize(); err != nil { + return false, err + } + ctx, cancel := context.WithTimeout(ctx, c.cfg.ConductorRpcTimeout) + defer cancel() + + isLeader, err := retry.Do(ctx, 2, retry.Fixed(50*time.Millisecond), func() (bool, error) { + record := c.metrics.RecordRPCClientRequest("conductor_leader") + result, err := c.apiClient.Leader(ctx) + record(err) + return result, err + }) + return isLeader, err +} + +// CommitUnsafePayload commits an unsafe payload to the conductor log. +func (c *ConductorClient) CommitUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { + if err := c.initialize(); err != nil { + return err + } + ctx, cancel := context.WithTimeout(ctx, c.cfg.ConductorRpcTimeout) + defer cancel() + + // extra bool return value is required for the generic, can be ignored. + _, err := retry.Do(ctx, 2, retry.Fixed(50*time.Millisecond), func() (bool, error) { + record := c.metrics.RecordRPCClientRequest("conductor_commitUnsafePayload") + err := c.apiClient.CommitUnsafePayload(ctx, payload) + record(err) + return true, err + }) + return err +} + +func (c *ConductorClient) Close() { + if c.apiClient == nil { + return + } + c.apiClient.Close() + c.apiClient = nil +} diff --git a/op-node/node/config.go b/op-node/node/config.go index cb970d5ebfd3..f0582acfa4e1 100644 --- a/op-node/node/config.go +++ b/op-node/node/config.go @@ -12,14 +12,16 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/driver" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + plasma "github.com/ethereum-optimism/optimism/op-plasma" + "github.com/ethereum-optimism/optimism/op-service/oppprof" "github.com/ethereum/go-ethereum/log" ) type Config struct { - L1 L1EndpointSetup - L2 L2EndpointSetup - L2Sync L2SyncEndpointSetup + L1 L1EndpointSetup + L2 L2EndpointSetup + + Beacon L1BeaconEndpointSetup Driver driver.Config @@ -42,6 +44,9 @@ type Config struct { ConfigPersistence ConfigPersistence + // Path to store safe head database. Disabled when set to empty string + SafeDBPath string + // RuntimeConfigReloadInterval defines the interval between runtime config reloads. // Disabled if <= 0. // Runtime config changes should be picked up from log-events, @@ -63,6 +68,14 @@ type Config struct { // [OPTIONAL] The reth DB path to read receipts from RethDBPath string + + // Conductor is used to determine this node is the leader sequencer. + ConductorEnabled bool + ConductorRpc string + ConductorRpcTimeout time.Duration + + // Plasma DA config + Plasma plasma.CLIConfig } type RPCConfig struct { @@ -119,12 +132,20 @@ func (cfg *Config) LoadPersisted(log log.Logger) error { // Check verifies that the given configuration makes sense func (cfg *Config) Check() error { - if err := cfg.L2.Check(); err != nil { + if err := cfg.L1.Check(); err != nil { return fmt.Errorf("l2 endpoint config error: %w", err) } - if err := cfg.L2Sync.Check(); err != nil { - return fmt.Errorf("sync config error: %w", err) + if err := cfg.L2.Check(); err != nil { + return fmt.Errorf("l2 endpoint config error: %w", err) } + // if cfg.Rollup.EcotoneTime != nil { + // if cfg.Beacon == nil { + // return fmt.Errorf("the Ecotone upgrade is scheduled but no L1 Beacon API endpoint is configured") + // } + // if err := cfg.Beacon.Check(); err != nil { + // return fmt.Errorf("misconfigured L1 Beacon API endpoint: %w", err) + // } + // } if err := cfg.Rollup.Check(); err != nil { return fmt.Errorf("rollup config error: %w", err) } @@ -142,5 +163,16 @@ func (cfg *Config) Check() error { if !(cfg.RollupHalt == "" || cfg.RollupHalt == "major" || cfg.RollupHalt == "minor" || cfg.RollupHalt == "patch") { return fmt.Errorf("invalid rollup halting option: %q", cfg.RollupHalt) } + if cfg.ConductorEnabled { + if state, _ := cfg.ConfigPersistence.SequencerState(); state != StateUnset { + return fmt.Errorf("config persistence must be disabled when conductor is enabled") + } + if !cfg.Driver.SequencerEnabled { + return fmt.Errorf("sequencer must be enabled when conductor is enabled") + } + } + if err := cfg.Plasma.Check(); err != nil { + return fmt.Errorf("plasma config error: %w", err) + } return nil } diff --git a/op-node/node/node.go b/op-node/node/node.go index c05eeb58854a..3da88cbdad58 100644 --- a/op-node/node/node.go +++ b/op-node/node/node.go @@ -4,11 +4,13 @@ import ( "context" "errors" "fmt" - "net" - "strconv" + "io" "sync/atomic" "time" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + plasma "github.com/ethereum-optimism/optimism/op-plasma" "github.com/ethereum-optimism/optimism/op-service/httputil" "github.com/hashicorp/go-multierror" @@ -21,15 +23,25 @@ import ( "github.com/ethereum-optimism/optimism/op-node/heartbeat" "github.com/ethereum-optimism/optimism/op-node/metrics" "github.com/ethereum-optimism/optimism/op-node/p2p" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-node/rollup/driver" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-node/version" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/eth" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/optimism/op-service/sources" ) +var ErrAlreadyClosed = errors.New("node is already closed") + +type closableSafeDB interface { + derive.SafeHeadListener + SafeDBReader + io.Closer +} + type OpNode struct { log log.Logger appVersion string @@ -42,17 +54,20 @@ type OpNode struct { l1Source *sources.L1Client // L1 Client to fetch data from l2Driver *driver.Driver // L2 Engine to Sync l2Source *sources.EngineClient // L2 Execution Engine RPC bindings - rpcSync *sources.SyncClient // Alt-sync RPC client, optional (may be nil) server *rpcServer // RPC server hosting the rollup-node API p2pNode *p2p.NodeP2P // P2P node functionality p2pSigner p2p.Signer // p2p gogssip application messages will be signed with this signer tracer Tracer // tracer to get events for testing/debugging runCfg *RuntimeConfig // runtime configurables + safeDB closableSafeDB + rollupHalt string // when to halt the rollup, disabled if empty - pprofSrv *httputil.HTTPServer - metricsSrv *httputil.HTTPServer + pprofService *oppprof.Service + metricsSrv *httputil.HTTPServer + + beacon *sources.L1BeaconClient // some resources cannot be stopped directly, like the p2p gossipsub router (not our design), // and depend on this ctx to be closed. @@ -110,15 +125,15 @@ func (n *OpNode) init(ctx context.Context, cfg *Config, snapshotLog log.Logger) if err := n.initL1(ctx, cfg); err != nil { return fmt.Errorf("failed to init L1: %w", err) } + if err := n.initL1BeaconAPI(ctx, cfg); err != nil { + return err + } if err := n.initL2(ctx, cfg, snapshotLog); err != nil { return fmt.Errorf("failed to init L2: %w", err) } if err := n.initRuntimeConfig(ctx, cfg); err != nil { // depends on L2, to signal initial runtime values to return fmt.Errorf("failed to init the runtime config: %w", err) } - if err := n.initRPCSync(ctx, cfg); err != nil { - return fmt.Errorf("failed to init RPC sync: %w", err) - } if err := n.initP2PSigner(ctx, cfg); err != nil { return fmt.Errorf("failed to init the P2P signer: %w", err) } @@ -126,7 +141,7 @@ func (n *OpNode) init(ctx context.Context, cfg *Config, snapshotLog log.Logger) return fmt.Errorf("failed to init the P2P stack: %w", err) } // Only expose the server at the end, ensuring all RPC backend components are initialized. - if err := n.initRPCServer(ctx, cfg); err != nil { + if err := n.initRPCServer(cfg); err != nil { return fmt.Errorf("failed to init the RPC server: %w", err) } if err := n.initMetricsServer(cfg); err != nil { @@ -136,7 +151,7 @@ func (n *OpNode) init(ctx context.Context, cfg *Config, snapshotLog log.Logger) n.metrics.RecordUp() n.initHeartbeat(cfg) if err := n.initPProf(cfg); err != nil { - return fmt.Errorf("failed to init pprof server: %w", err) + return fmt.Errorf("failed to init profiling: %w", err) } return nil } @@ -174,7 +189,7 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error { if err != nil { n.log.Warn("resubscribing after failed L1 subscription", "err", err) } - return eth.WatchHeadChanges(n.resourcesCtx, n.l1Source, n.OnNewL1Head) + return eth.WatchHeadChanges(ctx, n.l1Source, n.OnNewL1Head) }) if fallbackClient, ok := l1Node.(*sources.FallbackClient); ok { @@ -193,9 +208,9 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error { // Poll for the safe L1 block and finalized block, // which only change once per epoch at most and may be delayed. - n.l1SafeSub = eth.PollBlockChanges(n.resourcesCtx, n.log, n.l1Source, n.OnNewL1Safe, eth.Safe, + n.l1SafeSub = eth.PollBlockChanges(n.log, n.l1Source, n.OnNewL1Safe, eth.Safe, cfg.L1EpochPollInterval, time.Second*10) - n.l1FinalizedSub = eth.PollBlockChanges(n.resourcesCtx, n.log, n.l1Source, n.OnNewL1Finalized, eth.Finalized, + n.l1FinalizedSub = eth.PollBlockChanges(n.log, n.l1Source, n.OnNewL1Finalized, eth.Finalized, cfg.L1EpochPollInterval, time.Second*10) return nil } @@ -294,6 +309,71 @@ func (n *OpNode) initRuntimeConfig(ctx context.Context, cfg *Config) error { return nil } +func (n *OpNode) initL1BeaconAPI(ctx context.Context, cfg *Config) error { + // BSC use L1 client to fetch blobs + return nil + + // If Ecotone upgrade is not scheduled yet, then there is no need for a Beacon API. + if cfg.Rollup.EcotoneTime == nil { + return nil + } + // Once the Ecotone upgrade is scheduled, we must have initialized the Beacon API settings. + if cfg.Beacon == nil { + return fmt.Errorf("missing L1 Beacon Endpoint configuration: this API is mandatory for Ecotone upgrade at t=%d", *cfg.Rollup.EcotoneTime) + } + + // We always initialize a client. We will get an error on requests if the client does not work. + // This way the op-node can continue non-L1 functionality when the user chooses to ignore the Beacon API requirement. + beaconClient, fallbacks, err := cfg.Beacon.Setup(ctx, n.log) + if err != nil { + return fmt.Errorf("failed to setup L1 Beacon API client: %w", err) + } + beaconCfg := sources.L1BeaconClientConfig{ + FetchAllSidecars: cfg.Beacon.ShouldFetchAllSidecars(), + } + n.beacon = sources.NewL1BeaconClient(beaconClient, beaconCfg, fallbacks...) + + // Retry retrieval of the Beacon API version, to be more robust on startup against Beacon API connection issues. + beaconVersion, missingEndpoint, err := retry.Do2[string, bool](ctx, 5, retry.Exponential(), func() (string, bool, error) { + ctx, cancel := context.WithTimeout(ctx, time.Second*10) + defer cancel() + beaconVersion, err := n.beacon.GetVersion(ctx) + if err != nil { + if errors.Is(err, client.ErrNoEndpoint) { + return "", true, nil // don't return an error, we do not have to retry when there is a config issue. + } + return "", false, err + } + return beaconVersion, false, nil + }) + if missingEndpoint { + // Allow the user to continue if they explicitly ignore the requirement of the endpoint. + if cfg.Beacon.ShouldIgnoreBeaconCheck() { + n.log.Warn("This endpoint is required for the Ecotone upgrade, but is missing, and configured to be ignored. " + + "The node may be unable to retrieve EIP-4844 blobs data.") + return nil + } else { + // If the client tells us the endpoint was not configured, + // then explain why we need it, and what the user can do to ignore this. + n.log.Error("The Ecotone upgrade requires a L1 Beacon API endpoint, to retrieve EIP-4844 blobs data. " + + "This can be ignored with the --l1.beacon.ignore option, " + + "but the node may be unable to sync from L1 without this endpoint.") + return errors.New("missing L1 Beacon API endpoint") + } + } else if err != nil { + if cfg.Beacon.ShouldIgnoreBeaconCheck() { + n.log.Warn("Failed to check L1 Beacon API version, but configuration ignores results. "+ + "The node may be unable to retrieve EIP-4844 blobs data.", "err", err) + return nil + } else { + return fmt.Errorf("failed to check L1 Beacon API version: %w", err) + } + } else { + n.log.Info("Connected to L1 Beacon API, ready for EIP-4844 blobs retrieval.", "version", beaconVersion) + return nil + } +} + func (n *OpNode) initL2(ctx context.Context, cfg *Config, snapshotLog log.Logger) error { rpcClient, rpcCfg, err := cfg.L2.Setup(ctx, n.log, &cfg.Rollup) if err != nil { @@ -307,33 +387,37 @@ func (n *OpNode) initL2(ctx context.Context, cfg *Config, snapshotLog log.Logger return fmt.Errorf("failed to create Engine client: %w", err) } - if err := cfg.Rollup.ValidateL2Config(ctx, n.l2Source); err != nil { + if err := cfg.Rollup.ValidateL2Config(ctx, n.l2Source, cfg.Sync.SyncMode == sync.ELSync); err != nil { return err } - n.l2Driver = driver.NewDriver(&cfg.Driver, &cfg.Rollup, n.l2Source, n.l1Source, n, n, n.log, snapshotLog, n.metrics, cfg.ConfigPersistence, &cfg.Sync) - - return nil -} - -func (n *OpNode) initRPCSync(ctx context.Context, cfg *Config) error { - rpcSyncClient, rpcCfg, err := cfg.L2Sync.Setup(ctx, n.log, &cfg.Rollup) - if err != nil { - return fmt.Errorf("failed to setup L2 execution-engine RPC client for backup sync: %w", err) + var sequencerConductor conductor.SequencerConductor = &conductor.NoOpConductor{} + if cfg.ConductorEnabled { + sequencerConductor = NewConductorClient(cfg, n.log, n.metrics) } - if rpcSyncClient == nil { // if no RPC client is configured to sync from, then don't add the RPC sync client - return nil + + // if plasma is not explicitly activated in the node CLI, the config + any error will be ignored. + rpCfg, err := cfg.Rollup.PlasmaConfig() + if cfg.Plasma.Enabled && err != nil { + return fmt.Errorf("failed to get plasma config: %w", err) } - syncClient, err := sources.NewSyncClient(n.OnUnsafeL2Payload, rpcSyncClient, n.log, n.metrics.L2SourceCache, rpcCfg) - if err != nil { - return fmt.Errorf("failed to create sync client: %w", err) + plasmaDA := plasma.NewPlasmaDA(n.log, cfg.Plasma, rpCfg, n.metrics.PlasmaMetrics) + if cfg.SafeDBPath != "" { + n.log.Info("Safe head database enabled", "path", cfg.SafeDBPath) + safeDB, err := safedb.NewSafeDB(n.log, cfg.SafeDBPath) + if err != nil { + return fmt.Errorf("failed to create safe head database at %v: %w", cfg.SafeDBPath, err) + } + n.safeDB = safeDB + } else { + n.safeDB = safedb.Disabled } - n.rpcSync = syncClient + n.l2Driver = driver.NewDriver(&cfg.Driver, &cfg.Rollup, n.l2Source, n.l1Source, n.l1Source, n, n, n.log, snapshotLog, n.metrics, cfg.ConfigPersistence, n.safeDB, &cfg.Sync, sequencerConductor, plasmaDA) return nil } -func (n *OpNode) initRPCServer(ctx context.Context, cfg *Config) error { - server, err := newRPCServer(ctx, &cfg.RPC, &cfg.Rollup, n.l2Source.L2Client, n.l2Driver, n.log, n.appVersion, n.metrics) +func (n *OpNode) initRPCServer(cfg *Config) error { + server, err := newRPCServer(&cfg.RPC, &cfg.Rollup, n.l2Source.L2Client, n.l2Driver, n.safeDB, n.log, n.appVersion, n.metrics) if err != nil { return err } @@ -394,22 +478,26 @@ func (n *OpNode) initHeartbeat(cfg *Config) { } func (n *OpNode) initPProf(cfg *Config) error { - if !cfg.Pprof.Enabled { - return nil - } - log.Debug("starting pprof server", "addr", net.JoinHostPort(cfg.Pprof.ListenAddr, strconv.Itoa(cfg.Pprof.ListenPort))) - srv, err := oppprof.StartServer(cfg.Pprof.ListenAddr, cfg.Pprof.ListenPort) - if err != nil { - return err + n.pprofService = oppprof.New( + cfg.Pprof.ListenEnabled, + cfg.Pprof.ListenAddr, + cfg.Pprof.ListenPort, + cfg.Pprof.ProfileType, + cfg.Pprof.ProfileDir, + cfg.Pprof.ProfileFilename, + ) + + if err := n.pprofService.Start(); err != nil { + return fmt.Errorf("failed to start pprof service: %w", err) } - n.pprofSrv = srv - log.Info("started pprof server", "addr", srv.Addr()) + return nil } func (n *OpNode) initP2P(ctx context.Context, cfg *Config) error { if cfg.P2P != nil { - p2pNode, err := p2p.NewNodeP2P(n.resourcesCtx, &cfg.Rollup, n.log, cfg.P2P, n, n.l2Source, n.runCfg, n.metrics) + // TODO(protocol-quest/97): Use EL Sync instead of CL Alt sync for fetching missing blocks in the payload queue. + p2pNode, err := p2p.NewNodeP2P(n.resourcesCtx, &cfg.Rollup, n.log, cfg.P2P, n, n.l2Source, n.runCfg, n.metrics, false) if err != nil || p2pNode == nil { return err } @@ -434,22 +522,11 @@ func (n *OpNode) initP2PSigner(ctx context.Context, cfg *Config) error { func (n *OpNode) Start(ctx context.Context) error { n.log.Info("Starting execution engine driver") - // start driving engine: sync blocks by deriving them from L1 and driving them into the engine if err := n.l2Driver.Start(); err != nil { n.log.Error("Could not start a rollup node", "err", err) return err } - - // If the backup unsafe sync client is enabled, start its event loop - if n.rpcSync != nil { - if err := n.rpcSync.Start(); err != nil { - n.log.Error("Could not start the backup sync client", "err", err) - return err - } - n.log.Info("Started L2-RPC sync service") - } - log.Info("Rollup node started") return nil } @@ -492,46 +569,44 @@ func (n *OpNode) OnNewL1Finalized(ctx context.Context, sig eth.L1BlockRef) { } } -func (n *OpNode) PublishL2Payload(ctx context.Context, payload *eth.ExecutionPayload) error { - n.tracer.OnPublishL2Payload(ctx, payload) +func (n *OpNode) PublishL2Payload(ctx context.Context, envelope *eth.ExecutionPayloadEnvelope) error { + n.tracer.OnPublishL2Payload(ctx, envelope) // publish to p2p, if we are running p2p at all if n.p2pNode != nil { + payload := envelope.ExecutionPayload if n.p2pSigner == nil { return fmt.Errorf("node has no p2p signer, payload %s cannot be published", payload.ID()) } n.log.Info("Publishing signed execution payload on p2p", "id", payload.ID()) - return n.p2pNode.GossipOut().PublishL2Payload(ctx, payload, n.p2pSigner) + return n.p2pNode.GossipOut().PublishL2Payload(ctx, envelope, n.p2pSigner) } // if p2p is not enabled then we just don't publish the payload return nil } -func (n *OpNode) OnUnsafeL2Payload(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) error { +func (n *OpNode) OnUnsafeL2Payload(ctx context.Context, from peer.ID, envelope *eth.ExecutionPayloadEnvelope) error { // ignore if it's from ourselves if n.p2pNode != nil && from == n.p2pNode.Host().ID() { return nil } - n.tracer.OnUnsafeL2Payload(ctx, from, payload) + n.tracer.OnUnsafeL2Payload(ctx, from, envelope) - n.log.Info("Received signed execution payload from p2p", "id", payload.ID(), "peer", from) + n.log.Info("Received signed execution payload from p2p", "id", envelope.ExecutionPayload.ID(), "peer", from) // Pass on the event to the L2 Engine ctx, cancel := context.WithTimeout(ctx, time.Second*30) defer cancel() - if err := n.l2Driver.OnUnsafeL2Payload(ctx, payload); err != nil { - n.log.Warn("failed to notify engine driver of new L2 payload", "err", err, "id", payload.ID()) + if err := n.l2Driver.OnUnsafeL2Payload(ctx, envelope); err != nil { + n.log.Warn("failed to notify engine driver of new L2 payload", "err", err, "id", envelope.ExecutionPayload.ID()) } return nil } func (n *OpNode) RequestL2Range(ctx context.Context, start, end eth.L2BlockRef) error { - if n.rpcSync != nil { - return n.rpcSync.RequestL2Range(ctx, start, end) - } if n.p2pNode != nil && n.p2pNode.AltSyncEnabled() { if unixTimeStale(start.Time, 12*time.Hour) { n.log.Debug("ignoring request to sync L2 range, timestamp is too old for p2p", "start", start, "end", end, "start_time", start.Time) @@ -560,7 +635,7 @@ func (n *OpNode) RuntimeConfig() ReadonlyRuntimeConfig { // If the provided ctx is expired, the node will accelerate the stop where possible, but still fully close. func (n *OpNode) Stop(ctx context.Context) error { if n.closed.Load() { - return errors.New("node is already closed") + return ErrAlreadyClosed } var result *multierror.Error @@ -589,18 +664,25 @@ func (n *OpNode) Stop(ctx context.Context) error { if n.l1HeadsSub != nil { n.l1HeadsSub.Unsubscribe() } + // stop polling for L1 safe-head changes + if n.l1SafeSub != nil { + n.l1SafeSub.Unsubscribe() + } + // stop polling for L1 finalized-head changes + if n.l1FinalizedSub != nil { + n.l1FinalizedSub.Unsubscribe() + } // close L2 driver if n.l2Driver != nil { if err := n.l2Driver.Close(); err != nil { result = multierror.Append(result, fmt.Errorf("failed to close L2 engine driver cleanly: %w", err)) } + } - // If the L2 sync client is present & running, close it. - if n.rpcSync != nil { - if err := n.rpcSync.Close(); err != nil { - result = multierror.Append(result, fmt.Errorf("failed to close L2 engine backup sync client cleanly: %w", err)) - } + if n.safeDB != nil { + if err := n.safeDB.Close(); err != nil { + result = multierror.Append(result, fmt.Errorf("failed to close safe head db: %w", err)) } } @@ -635,8 +717,8 @@ func (n *OpNode) Stop(ctx context.Context) error { } // Close metrics and pprof only after we are done idling - if n.pprofSrv != nil { - if err := n.pprofSrv.Stop(ctx); err != nil { + if n.pprofService != nil { + if err := n.pprofService.Stop(ctx); err != nil { result = multierror.Append(result, fmt.Errorf("failed to close pprof server: %w", err)) } } diff --git a/op-node/node/safedb/disabled.go b/op-node/node/safedb/disabled.go new file mode 100644 index 000000000000..09ff5cf2433a --- /dev/null +++ b/op-node/node/safedb/disabled.go @@ -0,0 +1,36 @@ +package safedb + +import ( + "context" + "errors" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type DisabledDB struct{} + +var ( + Disabled = &DisabledDB{} + ErrNotEnabled = errors.New("safe head database not enabled") +) + +func (d *DisabledDB) Enabled() bool { + return false +} + +func (d *DisabledDB) SafeHeadUpdated(_ eth.L2BlockRef, _ eth.BlockID) error { + return nil +} + +func (d *DisabledDB) SafeHeadAtL1(_ context.Context, _ uint64) (l1 eth.BlockID, safeHead eth.BlockID, err error) { + err = ErrNotEnabled + return +} + +func (d *DisabledDB) SafeHeadReset(_ eth.L2BlockRef) error { + return nil +} + +func (d *DisabledDB) Close() error { + return nil +} diff --git a/op-node/node/safedb/safedb.go b/op-node/node/safedb/safedb.go new file mode 100644 index 000000000000..6b45411b7981 --- /dev/null +++ b/op-node/node/safedb/safedb.go @@ -0,0 +1,196 @@ +package safedb + +import ( + "context" + "encoding/binary" + "errors" + "fmt" + "math" + "slices" + "sync" + + "github.com/cockroachdb/pebble" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/log" +) + +var ( + ErrNotFound = errors.New("not found") + ErrInvalidEntry = errors.New("invalid db entry") +) + +const ( + // Keys are prefixed with a constant byte to allow us to differentiate different "columns" within the data + keyPrefixSafeByL1BlockNum byte = 0 +) + +var ( + safeByL1BlockNumKey = uint64Key{prefix: keyPrefixSafeByL1BlockNum} +) + +type uint64Key struct { + prefix byte +} + +func (c uint64Key) Of(num uint64) []byte { + key := make([]byte, 0, 9) + key = append(key, c.prefix) + key = binary.BigEndian.AppendUint64(key, num) + return key +} +func (c uint64Key) Max() []byte { + return c.Of(math.MaxUint64) +} + +func (c uint64Key) IterRange() *pebble.IterOptions { + return &pebble.IterOptions{ + LowerBound: c.Of(0), + UpperBound: c.Max(), + } +} + +type SafeDB struct { + // m ensures all read iterators are closed before closing the database by preventing concurrent read and write + // operations (with close considered a write operation). + m sync.RWMutex + log log.Logger + db *pebble.DB + + writeOpts *pebble.WriteOptions + + closed bool +} + +func safeByL1BlockNumValue(l1 eth.BlockID, l2 eth.BlockID) []byte { + val := make([]byte, 0, 72) + val = append(val, l1.Hash.Bytes()...) + val = append(val, l2.Hash.Bytes()...) + val = binary.BigEndian.AppendUint64(val, l2.Number) + return val +} + +func decodeSafeByL1BlockNum(key []byte, val []byte) (l1 eth.BlockID, l2 eth.BlockID, err error) { + if len(key) != 9 || len(val) != 72 || key[0] != keyPrefixSafeByL1BlockNum { + err = ErrInvalidEntry + return + } + copy(l1.Hash[:], val[:32]) + l1.Number = binary.BigEndian.Uint64(key[1:]) + copy(l2.Hash[:], val[32:64]) + l2.Number = binary.BigEndian.Uint64(val[64:]) + return +} + +func NewSafeDB(logger log.Logger, path string) (*SafeDB, error) { + db, err := pebble.Open(path, &pebble.Options{}) + if err != nil { + return nil, err + } + return &SafeDB{ + log: logger, + db: db, + writeOpts: &pebble.WriteOptions{Sync: true}, + }, nil +} + +func (d *SafeDB) Enabled() bool { + return true +} + +func (d *SafeDB) SafeHeadUpdated(safeHead eth.L2BlockRef, l1Head eth.BlockID) error { + d.m.Lock() + defer d.m.Unlock() + d.log.Info("Record safe head", "l2", safeHead.ID(), "l1", l1Head) + batch := d.db.NewBatch() + defer batch.Close() + if err := batch.Set(safeByL1BlockNumKey.Of(l1Head.Number), safeByL1BlockNumValue(l1Head, safeHead.ID()), d.writeOpts); err != nil { + return fmt.Errorf("failed to record safe head update: %w", err) + } + if err := batch.Commit(d.writeOpts); err != nil { + return fmt.Errorf("failed to commit safe head update: %w", err) + } + return nil +} + +func (d *SafeDB) SafeHeadReset(safeHead eth.L2BlockRef) error { + d.m.Lock() + defer d.m.Unlock() + iter, err := d.db.NewIter(safeByL1BlockNumKey.IterRange()) + if err != nil { + return fmt.Errorf("reset failed to create iterator: %w", err) + } + defer iter.Close() + if valid := iter.SeekGE(safeByL1BlockNumKey.Of(safeHead.L1Origin.Number)); !valid { + // Reached end of column without finding any entries to delete + return nil + } + for { + val, err := iter.ValueAndErr() + if err != nil { + return fmt.Errorf("reset failed to read entry: %w", err) + } + l1Block, l2Block, err := decodeSafeByL1BlockNum(iter.Key(), val) + if err != nil { + return fmt.Errorf("reset encountered invalid entry: %w", err) + } + if l2Block.Number >= safeHead.Number { + // Keep a copy of this key - it may be modified when calling Prev() + l1HeadKey := slices.Clone(iter.Key()) + hasPrevEntry := iter.Prev() + // Found the first entry that made the new safe head safe. + batch := d.db.NewBatch() + if err := batch.DeleteRange(l1HeadKey, safeByL1BlockNumKey.Max(), d.writeOpts); err != nil { + return fmt.Errorf("reset failed to delete entries after %v: %w", l1HeadKey, err) + } + + // If we reset to a safe head before the first entry, we don't know if the new safe head actually became + // safe in that L1 block or if it was just before our records start, so don't record it as safe at the + // specified L1 block. + if hasPrevEntry { + if err := batch.Set(l1HeadKey, safeByL1BlockNumValue(l1Block, safeHead.ID()), d.writeOpts); err != nil { + return fmt.Errorf("reset failed to record safe head update: %w", err) + } + } + if err := batch.Commit(d.writeOpts); err != nil { + return fmt.Errorf("reset failed to commit batch: %w", err) + } + return nil + } + if valid := iter.Next(); !valid { + // Reached end of column + return nil + } + } +} + +func (d *SafeDB) SafeHeadAtL1(ctx context.Context, l1BlockNum uint64) (l1Block eth.BlockID, safeHead eth.BlockID, err error) { + d.m.RLock() + defer d.m.RUnlock() + iter, err := d.db.NewIterWithContext(ctx, safeByL1BlockNumKey.IterRange()) + if err != nil { + return + } + defer iter.Close() + if valid := iter.SeekLT(safeByL1BlockNumKey.Of(l1BlockNum + 1)); !valid { + err = ErrNotFound + return + } + // Found an entry at or before the requested L1 block + val, err := iter.ValueAndErr() + if err != nil { + return + } + l1Block, safeHead, err = decodeSafeByL1BlockNum(iter.Key(), val) + return +} + +func (d *SafeDB) Close() error { + d.m.Lock() + defer d.m.Unlock() + if d.closed { + // Already closed + return nil + } + d.closed = true + return d.db.Close() +} diff --git a/op-node/node/safedb/safedb_test.go b/op-node/node/safedb/safedb_test.go new file mode 100644 index 000000000000..03fae503c0f3 --- /dev/null +++ b/op-node/node/safedb/safedb_test.go @@ -0,0 +1,369 @@ +package safedb + +import ( + "context" + "math" + "slices" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestStoreSafeHeads(t *testing.T) { + logger := testlog.Logger(t, log.LvlInfo) + dir := t.TempDir() + db, err := NewSafeDB(logger, dir) + require.NoError(t, err) + defer db.Close() + l2a := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xaa}, + Number: 20, + } + l2b := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xbb}, + Number: 25, + } + l1a := eth.BlockID{ + Hash: common.Hash{0x01, 0xaa}, + Number: 100, + } + l1b := eth.BlockID{ + Hash: common.Hash{0x01, 0xbb}, + Number: 150, + } + require.NoError(t, db.SafeHeadUpdated(l2a, l1a)) + require.NoError(t, db.SafeHeadUpdated(l2b, l1b)) + + verifySafeHeads := func(db *SafeDB) { + _, _, err = db.SafeHeadAtL1(context.Background(), l1a.Number-1) + require.ErrorIs(t, err, ErrNotFound) + + actualL1, actualL2, err := db.SafeHeadAtL1(context.Background(), l1a.Number) + require.NoError(t, err) + require.Equal(t, l1a, actualL1) + require.Equal(t, l2a.ID(), actualL2) + + actualL1, actualL2, err = db.SafeHeadAtL1(context.Background(), l1a.Number+1) + require.NoError(t, err) + require.Equal(t, l1a, actualL1) + require.Equal(t, l2a.ID(), actualL2) + + actualL1, actualL2, err = db.SafeHeadAtL1(context.Background(), l1b.Number) + require.NoError(t, err) + require.Equal(t, l1b, actualL1) + require.Equal(t, l2b.ID(), actualL2) + + actualL1, actualL2, err = db.SafeHeadAtL1(context.Background(), l1b.Number+1) + require.NoError(t, err) + require.Equal(t, l1b, actualL1) + require.Equal(t, l2b.ID(), actualL2) + } + // Verify loading the safe heads with the already open DB + verifySafeHeads(db) + + // Close the DB and open a new instance + require.NoError(t, db.Close()) + newDB, err := NewSafeDB(logger, dir) + require.NoError(t, err) + // Verify the data is reloaded correctly + verifySafeHeads(newDB) +} + +func TestSafeHeadAtL1_EmptyDatabase(t *testing.T) { + logger := testlog.Logger(t, log.LvlInfo) + dir := t.TempDir() + db, err := NewSafeDB(logger, dir) + require.NoError(t, err) + defer db.Close() + _, _, err = db.SafeHeadAtL1(context.Background(), 100) + require.ErrorIs(t, err, ErrNotFound) +} + +func TestTruncateOnSafeHeadReset(t *testing.T) { + logger := testlog.Logger(t, log.LvlInfo) + dir := t.TempDir() + db, err := NewSafeDB(logger, dir) + require.NoError(t, err) + defer db.Close() + + l2a := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xaa}, + Number: 20, + L1Origin: eth.BlockID{ + Number: 60, + }, + } + l2b := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xbb}, + Number: 22, + L1Origin: eth.BlockID{ + Number: 90, + }, + } + l2c := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xcc}, + Number: 25, + L1Origin: eth.BlockID{ + Number: 110, + }, + } + l2d := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xcc}, + Number: 30, + L1Origin: eth.BlockID{ + Number: 120, + }, + } + l1a := eth.BlockID{ + Hash: common.Hash{0x01, 0xaa}, + Number: 100, + } + l1b := eth.BlockID{ + Hash: common.Hash{0x01, 0xbb}, + Number: 150, + } + l1c := eth.BlockID{ + Hash: common.Hash{0x01, 0xcc}, + Number: 160, + } + + // Add some entries + require.NoError(t, db.SafeHeadUpdated(l2a, l1a)) + require.NoError(t, db.SafeHeadUpdated(l2c, l1b)) + require.NoError(t, db.SafeHeadUpdated(l2d, l1c)) + + // Then reset to between the two existing entries + require.NoError(t, db.SafeHeadReset(l2b)) + + // Only the reset safe head is now safe at the previous L1 block number + actualL1, actualL2, err := db.SafeHeadAtL1(context.Background(), l1b.Number) + require.NoError(t, err) + require.Equal(t, l1b, actualL1) + require.Equal(t, l2b.ID(), actualL2) + + actualL1, actualL2, err = db.SafeHeadAtL1(context.Background(), l1c.Number) + require.NoError(t, err) + require.Equal(t, l1b, actualL1) + require.Equal(t, l2b.ID(), actualL2) + + // l2a is still safe from its original update + actualL1, actualL2, err = db.SafeHeadAtL1(context.Background(), l1a.Number) + require.NoError(t, err) + require.Equal(t, l1a, actualL1) + require.Equal(t, l2a.ID(), actualL2) +} + +func TestTruncateOnSafeHeadReset_BeforeFirstEntry(t *testing.T) { + logger := testlog.Logger(t, log.LvlInfo) + dir := t.TempDir() + db, err := NewSafeDB(logger, dir) + require.NoError(t, err) + defer db.Close() + + l2b := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xbb}, + Number: 22, + L1Origin: eth.BlockID{ + Number: 90, + }, + } + l2c := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xcc}, + Number: 25, + L1Origin: eth.BlockID{ + Number: 110, + }, + } + l2d := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xcc}, + Number: 30, + L1Origin: eth.BlockID{ + Number: 120, + }, + } + l1a := eth.BlockID{ + Hash: common.Hash{0x01, 0xaa}, + Number: 100, + } + l1b := eth.BlockID{ + Hash: common.Hash{0x01, 0xbb}, + Number: 150, + } + l1c := eth.BlockID{ + Hash: common.Hash{0x01, 0xcc}, + Number: 160, + } + + // Add some entries + require.NoError(t, db.SafeHeadUpdated(l2c, l1b)) + require.NoError(t, db.SafeHeadUpdated(l2d, l1c)) + + // Then reset to between the two existing entries + require.NoError(t, db.SafeHeadReset(l2b)) + + // All entries got removed + _, _, err = db.SafeHeadAtL1(context.Background(), l1a.Number) + require.ErrorIs(t, err, ErrNotFound) + _, _, err = db.SafeHeadAtL1(context.Background(), l1b.Number) + require.ErrorIs(t, err, ErrNotFound) + _, _, err = db.SafeHeadAtL1(context.Background(), l1c.Number) + require.ErrorIs(t, err, ErrNotFound) +} + +func TestTruncateOnSafeHeadReset_AfterLastEntry(t *testing.T) { + logger := testlog.Logger(t, log.LvlInfo) + dir := t.TempDir() + db, err := NewSafeDB(logger, dir) + require.NoError(t, err) + defer db.Close() + + l2a := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xaa}, + Number: 20, + L1Origin: eth.BlockID{ + Number: 60, + }, + } + l2b := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xbb}, + Number: 22, + L1Origin: eth.BlockID{ + Number: 90, + }, + } + l2c := eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xcc}, + Number: 25, + L1Origin: eth.BlockID{ + Number: 110, + }, + } + l1a := eth.BlockID{ + Hash: common.Hash{0x01, 0xaa}, + Number: 100, + } + l1b := eth.BlockID{ + Hash: common.Hash{0x01, 0xbb}, + Number: 150, + } + l1c := eth.BlockID{ + Hash: common.Hash{0x01, 0xcc}, + Number: 160, + } + + // Add some entries + require.NoError(t, db.SafeHeadUpdated(l2a, l1a)) + require.NoError(t, db.SafeHeadUpdated(l2b, l1b)) + require.NoError(t, db.SafeHeadUpdated(l2c, l1c)) + + verifySafeHeads := func() { + // Everything is still safe + actualL1, actualL2, err := db.SafeHeadAtL1(context.Background(), l1a.Number) + require.NoError(t, err) + require.Equal(t, l1a, actualL1) + require.Equal(t, l2a.ID(), actualL2) + + // Everything is still safe + actualL1, actualL2, err = db.SafeHeadAtL1(context.Background(), l1b.Number) + require.NoError(t, err) + require.Equal(t, l1b, actualL1) + require.Equal(t, l2b.ID(), actualL2) + + // Everything is still safe + actualL1, actualL2, err = db.SafeHeadAtL1(context.Background(), l1c.Number) + require.NoError(t, err) + require.Equal(t, l1c, actualL1) + require.Equal(t, l2c.ID(), actualL2) + } + verifySafeHeads() + + // Then reset to an L2 block after all entries with an origin after all L1 entries + require.NoError(t, db.SafeHeadReset(eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xdd}, + Number: 30, + L1Origin: eth.BlockID{ + Number: l1c.Number + 1, + }, + })) + verifySafeHeads() + + // Then reset to an L2 block after all entries with an origin before some L1 entries + require.NoError(t, db.SafeHeadReset(eth.L2BlockRef{ + Hash: common.Hash{0x02, 0xdd}, + Number: 30, + L1Origin: eth.BlockID{ + Number: l1b.Number - 1, + }, + })) + verifySafeHeads() +} + +func TestKeysFollowNaturalByteOrdering(t *testing.T) { + vals := []uint64{0, 1, math.MaxUint32 - 1, math.MaxUint32, math.MaxUint32 + 1, math.MaxUint64 - 1, math.MaxUint64} + for i := 1; i < len(vals); i++ { + prev := safeByL1BlockNumKey.Of(vals[i-1]) + cur := safeByL1BlockNumKey.Of(vals[i]) + require.True(t, slices.Compare(prev, cur) < 0, "Expected %v key %x to be less than %v key %x", vals[i-1], prev, vals[i], cur) + } +} + +func TestDecodeSafeByL1BlockNum(t *testing.T) { + l1 := eth.BlockID{ + Hash: common.Hash{0x01}, + Number: 84298, + } + l2 := eth.BlockID{ + Hash: common.Hash{0x02}, + Number: 3224, + } + validKey := safeByL1BlockNumKey.Of(l1.Number) + validValue := safeByL1BlockNumValue(l1, l2) + + t.Run("Roundtrip", func(t *testing.T) { + actualL1, actualL2, err := decodeSafeByL1BlockNum(validKey, validValue) + require.NoError(t, err) + require.Equal(t, l1, actualL1) + require.Equal(t, l2, actualL2) + }) + + t.Run("ErrorOnEmptyKey", func(t *testing.T) { + _, _, err := decodeSafeByL1BlockNum([]byte{}, validValue) + require.ErrorIs(t, err, ErrInvalidEntry) + }) + + t.Run("ErrorOnTooShortKey", func(t *testing.T) { + _, _, err := decodeSafeByL1BlockNum([]byte{1, 2, 3, 4}, validValue) + require.ErrorIs(t, err, ErrInvalidEntry) + }) + + t.Run("ErrorOnTooLongKey", func(t *testing.T) { + _, _, err := decodeSafeByL1BlockNum(append(validKey, 2), validValue) + require.ErrorIs(t, err, ErrInvalidEntry) + }) + + t.Run("ErrorOnWrongKeyPrefix", func(t *testing.T) { + invalidKey := slices.Clone(validKey) + invalidKey[0] = 49 + _, _, err := decodeSafeByL1BlockNum(invalidKey, validValue) + require.ErrorIs(t, err, ErrInvalidEntry) + }) + + t.Run("ErrorOnEmptyValue", func(t *testing.T) { + _, _, err := decodeSafeByL1BlockNum(validKey, []byte{}) + require.ErrorIs(t, err, ErrInvalidEntry) + }) + + t.Run("ErrorOnTooShortValue", func(t *testing.T) { + _, _, err := decodeSafeByL1BlockNum(validKey, []byte{1, 2, 3, 4}) + require.ErrorIs(t, err, ErrInvalidEntry) + }) + + t.Run("ErrorOnTooLongValue", func(t *testing.T) { + _, _, err := decodeSafeByL1BlockNum(validKey, append(validKey, 2)) + require.ErrorIs(t, err, ErrInvalidEntry) + }) +} diff --git a/op-node/node/server.go b/op-node/node/server.go index ce94a1497f24..e1b1531b0142 100644 --- a/op-node/node/server.go +++ b/op-node/node/server.go @@ -27,8 +27,8 @@ type rpcServer struct { sources.L2Client } -func newRPCServer(ctx context.Context, rpcCfg *RPCConfig, rollupCfg *rollup.Config, l2Client l2EthClient, dr driverClient, log log.Logger, appVersion string, m metrics.Metricer) (*rpcServer, error) { - api := NewNodeAPI(rollupCfg, l2Client, dr, log.New("rpc", "node"), m) +func newRPCServer(rpcCfg *RPCConfig, rollupCfg *rollup.Config, l2Client l2EthClient, dr driverClient, safedb SafeDBReader, log log.Logger, appVersion string, m metrics.Metricer) (*rpcServer, error) { + api := NewNodeAPI(rollupCfg, l2Client, dr, safedb, log.New("rpc", "node"), m) // TODO: extend RPC config with options for WS, IPC and HTTP RPC connections endpoint := net.JoinHostPort(rpcCfg.ListenAddr, strconv.Itoa(rpcCfg.ListenPort)) r := &rpcServer{ diff --git a/op-node/node/server_test.go b/op-node/node/server_test.go index eda1c8252750..587befd6de80 100644 --- a/op-node/node/server_test.go +++ b/op-node/node/server_test.go @@ -7,13 +7,13 @@ import ( "testing" "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" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum-optimism/optimism/op-node/metrics" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/version" @@ -24,7 +24,7 @@ import ( ) func TestOutputAtBlock(t *testing.T) { - log := testlog.Logger(t, log.LvlError) + log := testlog.Logger(t, log.LevelError) // Test data for Merkle Patricia Trie: proof the eth2 deposit contract account contents (mainnet). headerTestData := ` @@ -98,10 +98,11 @@ func TestOutputAtBlock(t *testing.T) { l2Client.ExpectOutputV0AtBlock(common.HexToHash("0x8512bee03061475e4b069171f7b406097184f16b22c3f5c97c0abfc49591c524"), output, nil) drClient := &mockDriverClient{} + safeReader := &mockSafeDBReader{} status := randomSyncStatus(rand.New(rand.NewSource(123))) drClient.ExpectBlockRefWithStatus(0xdcdc89, ref, status, nil) - server, err := newRPCServer(context.Background(), rpcCfg, rollupCfg, l2Client, drClient, log, "0.0", metrics.NoopMetrics) + server, err := newRPCServer(rpcCfg, rollupCfg, l2Client, drClient, safeReader, log, "0.0", metrics.NoopMetrics) require.NoError(t, err) require.NoError(t, server.Start()) defer func() { @@ -122,12 +123,14 @@ func TestOutputAtBlock(t *testing.T) { require.Equal(t, *status, *out.Status) l2Client.Mock.AssertExpectations(t) drClient.Mock.AssertExpectations(t) + safeReader.Mock.AssertExpectations(t) } func TestVersion(t *testing.T) { - log := testlog.Logger(t, log.LvlError) + log := testlog.Logger(t, log.LevelError) l2Client := &testutils.MockL2Client{} drClient := &mockDriverClient{} + safeReader := &mockSafeDBReader{} rpcCfg := &RPCConfig{ ListenAddr: "localhost", ListenPort: 0, @@ -135,7 +138,7 @@ func TestVersion(t *testing.T) { rollupCfg := &rollup.Config{ // ignore other rollup config info in this test } - server, err := newRPCServer(context.Background(), rpcCfg, rollupCfg, l2Client, drClient, log, "0.0", metrics.NoopMetrics) + server, err := newRPCServer(rpcCfg, rollupCfg, l2Client, drClient, safeReader, log, "0.0", metrics.NoopMetrics) assert.NoError(t, err) assert.NoError(t, server.Start()) defer func() { @@ -161,15 +164,15 @@ func randomSyncStatus(rng *rand.Rand) *eth.SyncStatus { UnsafeL2: testutils.RandomL2BlockRef(rng), SafeL2: testutils.RandomL2BlockRef(rng), FinalizedL2: testutils.RandomL2BlockRef(rng), - UnsafeL2SyncTarget: testutils.RandomL2BlockRef(rng), - EngineSyncTarget: testutils.RandomL2BlockRef(rng), + PendingSafeL2: testutils.RandomL2BlockRef(rng), } } func TestSyncStatus(t *testing.T) { - log := testlog.Logger(t, log.LvlError) + log := testlog.Logger(t, log.LevelError) l2Client := &testutils.MockL2Client{} drClient := &mockDriverClient{} + safeReader := &mockSafeDBReader{} rng := rand.New(rand.NewSource(1234)) status := randomSyncStatus(rng) drClient.On("SyncStatus").Return(status) @@ -181,7 +184,7 @@ func TestSyncStatus(t *testing.T) { rollupCfg := &rollup.Config{ // ignore other rollup config info in this test } - server, err := newRPCServer(context.Background(), rpcCfg, rollupCfg, l2Client, drClient, log, "0.0", metrics.NoopMetrics) + server, err := newRPCServer(rpcCfg, rollupCfg, l2Client, drClient, safeReader, log, "0.0", metrics.NoopMetrics) assert.NoError(t, err) assert.NoError(t, server.Start()) defer func() { @@ -197,6 +200,52 @@ func TestSyncStatus(t *testing.T) { assert.Equal(t, status, out) } +func TestSafeHeadAtL1Block(t *testing.T) { + log := testlog.Logger(t, log.LevelError) + l2Client := &testutils.MockL2Client{} + drClient := &mockDriverClient{} + safeReader := &mockSafeDBReader{} + l1BlockNum := uint64(5223) + expectedL1 := eth.BlockID{ + Hash: common.Hash{0xdd}, + Number: l1BlockNum - 2, + } + expectedSafeHead := eth.BlockID{ + Hash: common.Hash{0xee}, + Number: 223, + } + expected := ð.SafeHeadResponse{ + L1Block: expectedL1, + SafeHead: expectedSafeHead, + } + safeReader.ExpectSafeHeadAtL1(l1BlockNum, expectedL1, expectedSafeHead, nil) + + rpcCfg := &RPCConfig{ + ListenAddr: "localhost", + ListenPort: 0, + } + rollupCfg := &rollup.Config{ + // ignore other rollup config info in this test + } + server, err := newRPCServer(rpcCfg, rollupCfg, l2Client, drClient, safeReader, log, "0.0", metrics.NoopMetrics) + require.NoError(t, err) + require.NoError(t, server.Start()) + defer func() { + require.NoError(t, server.Stop(context.Background())) + }() + + client, err := rpcclient.NewRPC(context.Background(), log, "http://"+server.Addr().String(), rpcclient.WithDialBackoff(3)) + require.NoError(t, err) + + var out *eth.SafeHeadResponse + err = client.CallContext(context.Background(), &out, "optimism_safeHeadAtL1Block", hexutil.Uint64(l1BlockNum).String()) + require.NoError(t, err) + require.Equal(t, expected, out) + l2Client.Mock.AssertExpectations(t) + drClient.Mock.AssertExpectations(t) + safeReader.Mock.AssertExpectations(t) +} + type mockDriverClient struct { mock.Mock } @@ -229,3 +278,20 @@ func (c *mockDriverClient) StopSequencer(ctx context.Context) (common.Hash, erro func (c *mockDriverClient) SequencerActive(ctx context.Context) (bool, error) { return c.Mock.MethodCalled("SequencerActive").Get(0).(bool), nil } + +func (c *mockDriverClient) OnUnsafeL2Payload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { + return c.Mock.MethodCalled("OnUnsafeL2Payload").Get(0).(error) +} + +type mockSafeDBReader struct { + mock.Mock +} + +func (m *mockSafeDBReader) SafeHeadAtL1(ctx context.Context, l1BlockNum uint64) (l1Hash eth.BlockID, l2Hash eth.BlockID, err error) { + r := m.Mock.MethodCalled("SafeHeadAtL1", l1BlockNum) + return r[0].(eth.BlockID), r[1].(eth.BlockID), *r[2].(*error) +} + +func (m *mockSafeDBReader) ExpectSafeHeadAtL1(l1BlockNum uint64, l1 eth.BlockID, safeHead eth.BlockID, err error) { + m.Mock.On("SafeHeadAtL1", l1BlockNum).Return(l1, safeHead, &err) +} diff --git a/op-node/p2p/app_scores.go b/op-node/p2p/app_scores.go index 06693868c3e2..be0fe7a7e95f 100644 --- a/op-node/p2p/app_scores.go +++ b/op-node/p2p/app_scores.go @@ -111,6 +111,7 @@ func (s *peerApplicationScorer) start() { go func() { defer s.done.Done() ticker := s.clock.NewTicker(s.params.DecayInterval) + defer ticker.Stop() for { select { case <-s.ctx.Done(): diff --git a/op-node/p2p/app_scores_test.go b/op-node/p2p/app_scores_test.go index 720b0c4babf5..337d8244c5ae 100644 --- a/op-node/p2p/app_scores_test.go +++ b/op-node/p2p/app_scores_test.go @@ -63,7 +63,7 @@ func (a *appScoreTestData) WaitForNextScoreBookUpdate(t *testing.T) stubScoreBoo func setupPeerApplicationScorerTest(t *testing.T, params *ApplicationScoreParams) (*appScoreTestData, *peerApplicationScorer) { data := &appScoreTestData{ ctx: context.Background(), - logger: testlog.Logger(t, log.LvlInfo), + logger: testlog.Logger(t, log.LevelInfo), clock: clock.NewDeterministicClock(time.UnixMilli(1000)), peers: []peer.ID{}, scorebook: &stubScoreBook{ diff --git a/op-node/p2p/cli/load_config.go b/op-node/p2p/cli/load_config.go index bc8aa268227d..424deecdddcf 100644 --- a/op-node/p2p/cli/load_config.go +++ b/op-node/p2p/cli/load_config.go @@ -65,6 +65,7 @@ func NewConfig(ctx *cli.Context, rollupCfg *rollup.Config) (*p2p.Config, error) } conf.EnableReqRespSync = ctx.Bool(flags.SyncReqRespName) + conf.EnablePingService = ctx.Bool(flags.P2PPingName) return conf, nil } diff --git a/op-node/p2p/cli/load_signer.go b/op-node/p2p/cli/load_signer.go index e8abfd9f87a1..7416fa76397a 100644 --- a/op-node/p2p/cli/load_signer.go +++ b/op-node/p2p/cli/load_signer.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + "strings" "github.com/ethereum/go-ethereum/crypto" "github.com/urfave/cli/v2" @@ -19,7 +20,7 @@ func LoadSignerSetup(ctx *cli.Context) (p2p.SignerSetup, error) { if key != "" { // Mnemonics are bad because they leak *all* keys when they leak. // Unencrypted keys from file are bad because they are easy to leak (and we are not checking file permissions). - priv, err := crypto.HexToECDSA(key) + priv, err := crypto.HexToECDSA(strings.TrimPrefix(key, "0x")) if err != nil { return nil, fmt.Errorf("failed to read batch submitter key: %w", err) } diff --git a/op-node/p2p/config.go b/op-node/p2p/config.go index a2281e2f073a..34a4acf97732 100644 --- a/op-node/p2p/config.go +++ b/op-node/p2p/config.go @@ -26,8 +26,20 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup" ) -// TODO add values -var DefaultBootnodes = []*enode.Node{} +var DefaultBootnodes = []*enode.Node{ + // OP Labs + enode.MustParse("enode://869d07b5932f17e8490990f75a3f94195e9504ddb6b85f7189e5a9c0a8fff8b00aecf6f3ac450ecba6cdabdb5858788a94bde2b613e0f2d82e9b395355f76d1a@34.65.67.101:30305"), + enode.MustParse("enode://2d4e7e9d48f4dd4efe9342706dd1b0024681bd4c3300d021f86fc75eab7865d4e0cbec6fbc883f011cfd6a57423e7e2f6e104baad2b744c3cafaec6bc7dc92c1@34.65.43.171:30305"), + enode.MustParse("enode://9d7a3efefe442351217e73b3a593bcb8efffb55b4807699972145324eab5e6b382152f8d24f6301baebbfb5ecd4127bd3faab2842c04cd432bdf50ba092f6645@34.65.109.126:30305"), + // Base + enode.MustParse("enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG"), + enode.MustParse("enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG"), + enode.MustParse("enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG"), + enode.MustParse("enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG"), + enode.MustParse("enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG"), + // Conduit + enode.MustParse("enode://9d7a3efefe442351217e73b3a593bcb8efffb55b4807699972145324eab5e6b382152f8d24f6301baebbfb5ecd4127bd3faab2842c04cd432bdf50ba092f6645@34.65.109.126:30305"), +} var OpBNBTestnet = big.NewInt(5611) @@ -134,6 +146,8 @@ type Config struct { Store ds.Batching EnableReqRespSync bool + + EnablePingService bool } func DefaultConnManager(conf *Config) (connmgr.ConnManager, error) { diff --git a/op-node/p2p/discovery.go b/op-node/p2p/discovery.go index 51ab9c398069..93a66ca33184 100644 --- a/op-node/p2p/discovery.go +++ b/op-node/p2p/discovery.go @@ -27,6 +27,7 @@ import ( "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/ethereum-optimism/optimism/op-node/p2p/store" "github.com/ethereum-optimism/optimism/op-node/rollup" ) @@ -355,10 +356,22 @@ func (n *NodeP2P) DiscoveryProcess(ctx context.Context, log log.Logger, cfg *rol if err != nil { continue } + + // record metadata to the peerstore if it is an extended peerstore + if eps, ok := pstore.(store.ExtendedPeerstore); ok { + _, err := eps.SetPeerMetadata(info.ID, store.PeerMetadata{ + ENR: found.String(), + OPStackID: dat.chainID, + }) + if err != nil { + log.Warn("failed to set peer metadata", "peer", info.ID, "err", err) + } + } // We add the addresses to the peerstore, and update the address TTL. //After that we stop using the address, assuming it may not be valid anymore (until we rediscover the node) pstore.AddAddrs(info.ID, info.Addrs, discoveredAddrTTL) _ = pstore.AddPubKey(info.ID, pub) + // Tag the peer, we'd rather have the connection manager prune away old peers, // or peers on different chains, or anyone we have not seen via discovery. // There is no tag score decay yet, so just set it to 42. diff --git a/op-node/p2p/gating/expiry.go b/op-node/p2p/gating/expiry.go index 73522f79acbc..e6f1662b3597 100644 --- a/op-node/p2p/gating/expiry.go +++ b/op-node/p2p/gating/expiry.go @@ -45,6 +45,19 @@ func AddBanExpiry(gater BlockingConnectionGater, store ExpiryStore, log log.Logg } } +func (g *ExpiryConnectionGater) UnblockPeer(p peer.ID) error { + if err := g.BlockingConnectionGater.UnblockPeer(p); err != nil { + log.Warn("failed to unblock peer from underlying gater", "method", "UnblockPeer", "peer_id", p, "err", err) + return err + } + if err := g.store.SetPeerBanExpiration(p, time.Time{}); err != nil { + log.Warn("failed to unblock peer from expiry gater", "method", "UnblockPeer", "peer_id", p, "err", err) + return err + } + g.m.RecordPeerUnban() + return nil +} + func (g *ExpiryConnectionGater) peerBanExpiryCheck(p peer.ID) (allow bool) { // if the peer is blocked, check if it's time to unblock expiry, err := g.store.GetPeerBanExpiration(p) @@ -52,7 +65,7 @@ func (g *ExpiryConnectionGater) peerBanExpiryCheck(p peer.ID) (allow bool) { return true // peer is allowed if it has not been banned } if err != nil { - g.log.Warn("failed to load peer-ban expiry time", "peer_id", p, "err", err) + g.log.Warn("failed to load peer-ban expiry time", "method", "peerBanExpiryCheck", "peer_id", p, "err", err) return false } if g.clock.Now().Before(expiry) { @@ -60,7 +73,7 @@ func (g *ExpiryConnectionGater) peerBanExpiryCheck(p peer.ID) (allow bool) { } g.log.Info("peer-ban expired, unbanning peer", "peer_id", p, "expiry", expiry) if err := g.store.SetPeerBanExpiration(p, time.Time{}); err != nil { - g.log.Warn("failed to unban peer", "peer_id", p, "err", err) + g.log.Warn("failed to unban peer", "method", "peerBanExpiryCheck", "peer_id", p, "err", err) return false // if we ignored the error, then the inner connection-gater would drop them } g.m.RecordPeerUnban() @@ -70,7 +83,7 @@ func (g *ExpiryConnectionGater) peerBanExpiryCheck(p peer.ID) (allow bool) { func (g *ExpiryConnectionGater) addrBanExpiryCheck(ma multiaddr.Multiaddr) (allow bool) { ip, err := manet.ToIP(ma) if err != nil { - g.log.Error("tried to check multi-addr with bad IP", "addr", ma) + g.log.Error("tried to check multi-addr with bad IP", "method", "addrBanExpiryCheck", "addr", ma) return false } // if just the IP is blocked, check if it's time to unblock @@ -79,15 +92,15 @@ func (g *ExpiryConnectionGater) addrBanExpiryCheck(ma multiaddr.Multiaddr) (allo return true // IP is allowed if it has not been banned } if err != nil { - g.log.Warn("failed to load IP-ban expiry time", "ip", ip, "err", err) + g.log.Warn("failed to load IP-ban expiry time", "method", "addrBanExpiryCheck", "ip", ip, "err", err) return false } if g.clock.Now().Before(expiry) { return false } - g.log.Info("IP-ban expired, unbanning IP", "ip", ip, "expiry", expiry) + g.log.Info("IP-ban expired, unbanning IP", "method", "addrBanExpiryCheck", "ip", ip, "expiry", expiry) if err := g.store.SetIPBanExpiration(ip, time.Time{}); err != nil { - g.log.Warn("failed to unban IP", "ip", ip, "err", err) + g.log.Warn("failed to unban IP", "method", "addrBanExpiryCheck", "ip", ip, "err", err) return false // if we ignored the error, then the inner connection-gater would drop them } g.m.RecordIPUnban() @@ -98,21 +111,39 @@ func (g *ExpiryConnectionGater) InterceptPeerDial(p peer.ID) (allow bool) { if !g.BlockingConnectionGater.InterceptPeerDial(p) { return false } - return g.peerBanExpiryCheck(p) + peerBan := g.peerBanExpiryCheck(p) + if !peerBan { + log.Warn("peer is temporarily banned", "method", "InterceptPeerDial", "peer_id", p) + } + return peerBan } func (g *ExpiryConnectionGater) InterceptAddrDial(id peer.ID, ma multiaddr.Multiaddr) (allow bool) { if !g.BlockingConnectionGater.InterceptAddrDial(id, ma) { return false } - return g.peerBanExpiryCheck(id) && g.addrBanExpiryCheck(ma) + peerBan := g.peerBanExpiryCheck(id) + if !peerBan { + log.Warn("peer id is temporarily banned", "method", "InterceptAddrDial", "peer_id", id, "multi_addr", ma) + return false + } + addrBan := g.addrBanExpiryCheck(ma) + if !addrBan { + log.Warn("peer address is temporarily banned", "method", "InterceptAddrDial", "peer_id", id, "multi_addr", ma) + return false + } + return true } func (g *ExpiryConnectionGater) InterceptAccept(mas network.ConnMultiaddrs) (allow bool) { if !g.BlockingConnectionGater.InterceptAccept(mas) { return false } - return g.addrBanExpiryCheck(mas.RemoteMultiaddr()) + addrBan := g.addrBanExpiryCheck(mas.RemoteMultiaddr()) + if !addrBan { + log.Warn("peer address is temporarily banned", "method", "InterceptAccept", "multi_addr", mas.RemoteMultiaddr()) + } + return addrBan } func (g *ExpiryConnectionGater) InterceptSecured(direction network.Direction, id peer.ID, mas network.ConnMultiaddrs) (allow bool) { @@ -125,5 +156,9 @@ func (g *ExpiryConnectionGater) InterceptSecured(direction network.Direction, id } // InterceptSecured is called after InterceptAccept, we already checked the addrs. // This leaves just the peer-ID expiry to check on inbound connections. - return g.peerBanExpiryCheck(id) + peerBan := g.peerBanExpiryCheck(id) + if !peerBan { + log.Warn("peer id is temporarily banned", "method", "InterceptSecured", "peer_id", id, "multi_addr", mas.RemoteMultiaddr()) + } + return peerBan } diff --git a/op-node/p2p/gating/expiry_test.go b/op-node/p2p/gating/expiry_test.go index b64085fe64fc..453e1d3fe2cb 100644 --- a/op-node/p2p/gating/expiry_test.go +++ b/op-node/p2p/gating/expiry_test.go @@ -20,7 +20,7 @@ import ( func expiryTestSetup(t *testing.T) (*clock.DeterministicClock, *mocks.ExpiryStore, *mocks.BlockingConnectionGater, *ExpiryConnectionGater) { mockGater := mocks.NewBlockingConnectionGater(t) - log := testlog.Logger(t, log.LvlError) + log := testlog.Logger(t, log.LevelError) cl := clock.NewDeterministicClock(time.Now()) mockExpiryStore := mocks.NewExpiryStore(t) gater := AddBanExpiry(mockGater, mockExpiryStore, log, cl, metrics.NoopMetrics) diff --git a/op-node/p2p/gating/scoring.go b/op-node/p2p/gating/scoring.go index 0e23e3fce655..8b0d305d2bb8 100644 --- a/op-node/p2p/gating/scoring.go +++ b/op-node/p2p/gating/scoring.go @@ -1,6 +1,7 @@ package gating import ( + "github.com/ethereum/go-ethereum/log" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" @@ -22,22 +23,43 @@ func AddScoring(gater BlockingConnectionGater, scores Scores, minScore float64) return &ScoringConnectionGater{BlockingConnectionGater: gater, scores: scores, minScore: minScore} } -func (g *ScoringConnectionGater) checkScore(p peer.ID) (allow bool) { +func (g *ScoringConnectionGater) checkScore(p peer.ID) (allow bool, score float64) { score, err := g.scores.GetPeerScore(p) if err != nil { - return false + return false, score } - return score >= g.minScore + return score >= g.minScore, score } func (g *ScoringConnectionGater) InterceptPeerDial(p peer.ID) (allow bool) { - return g.BlockingConnectionGater.InterceptPeerDial(p) && g.checkScore(p) + if !g.BlockingConnectionGater.InterceptPeerDial(p) { + return false + } + check, score := g.checkScore(p) + if !check { + log.Warn("peer has failed checkScore", "peer_id", p, "score", score, "min_score", g.minScore) + } + return check } func (g *ScoringConnectionGater) InterceptAddrDial(id peer.ID, ma multiaddr.Multiaddr) (allow bool) { - return g.BlockingConnectionGater.InterceptAddrDial(id, ma) && g.checkScore(id) + if !g.BlockingConnectionGater.InterceptAddrDial(id, ma) { + return false + } + check, score := g.checkScore(id) + if !check { + log.Warn("peer has failed checkScore", "peer_id", id, "score", score, "min_score", g.minScore) + } + return check } func (g *ScoringConnectionGater) InterceptSecured(dir network.Direction, id peer.ID, mas network.ConnMultiaddrs) (allow bool) { - return g.BlockingConnectionGater.InterceptSecured(dir, id, mas) && g.checkScore(id) + if !g.BlockingConnectionGater.InterceptSecured(dir, id, mas) { + return false + } + check, score := g.checkScore(id) + if !check { + log.Warn("peer has failed checkScore", "peer_id", id, "score", score, "min_score", g.minScore) + } + return check } diff --git a/op-node/p2p/gossip.go b/op-node/p2p/gossip.go index 784a9c1eac92..903c7598fa5b 100644 --- a/op-node/p2p/gossip.go +++ b/op-node/p2p/gossip.go @@ -74,10 +74,14 @@ func blocksTopicV2(cfg *rollup.Config) string { return fmt.Sprintf("/optimism/%s/1/blocks", cfg.L2ChainID.String()) } +func blocksTopicV3(cfg *rollup.Config) string { + return fmt.Sprintf("/optimism/%s/2/blocks", cfg.L2ChainID.String()) +} + // BuildSubscriptionFilter builds a simple subscription filter, // to help protect against peers spamming useless subscriptions. func BuildSubscriptionFilter(cfg *rollup.Config) pubsub.SubscriptionFilter { - return pubsub.NewAllowlistSubscriptionFilter(blocksTopicV1(cfg), blocksTopicV2(cfg)) // add more topics here in the future, if any. + return pubsub.NewAllowlistSubscriptionFilter(blocksTopicV1(cfg), blocksTopicV2(cfg), blocksTopicV3(cfg)) // add more topics here in the future, if any. } var msgBufPool = sync.Pool{New: func() any { @@ -286,13 +290,25 @@ func BuildBlocksValidator(log log.Logger, cfg *rollup.Config, runCfg GossipRunti return result } + var envelope eth.ExecutionPayloadEnvelope + // [REJECT] if the block encoding is not valid - var payload eth.ExecutionPayload - if err := payload.UnmarshalSSZ(blockVersion, uint32(len(payloadBytes)), bytes.NewReader(payloadBytes)); err != nil { - log.Warn("invalid payload", "err", err, "peer", id) - return pubsub.ValidationReject + if blockVersion == eth.BlockV3 { + if err := envelope.UnmarshalSSZ(uint32(len(payloadBytes)), bytes.NewReader(payloadBytes)); err != nil { + log.Warn("invalid envelope payload", "err", err, "peer", id) + return pubsub.ValidationReject + } + } else { + var payload eth.ExecutionPayload + if err := payload.UnmarshalSSZ(blockVersion, uint32(len(payloadBytes)), bytes.NewReader(payloadBytes)); err != nil { + log.Warn("invalid execution payload", "err", err, "peer", id) + return pubsub.ValidationReject + } + envelope = eth.ExecutionPayloadEnvelope{ExecutionPayload: &payload} } + payload := envelope.ExecutionPayload + // rounding down to seconds is fine here. now := uint64(time.Now().Unix()) @@ -309,26 +325,58 @@ func BuildBlocksValidator(log log.Logger, cfg *rollup.Config, runCfg GossipRunti } // [REJECT] if the `block_hash` in the `payload` is not valid - if actual, ok := payload.CheckBlockHash(); !ok { + if actual, ok := envelope.CheckBlockHash(); !ok { log.Warn("payload has bad block hash", "bad_hash", payload.BlockHash.String(), "actual", actual.String()) return pubsub.ValidationReject } // [REJECT] if a V1 Block has withdrawals - if blockVersion == eth.BlockV1 && payload.Withdrawals != nil { + if !blockVersion.HasWithdrawals() && payload.Withdrawals != nil { log.Warn("payload is on v1 topic, but has withdrawals", "bad_hash", payload.BlockHash.String()) return pubsub.ValidationReject } // [REJECT] if a V2 Block does not have withdrawals - if blockVersion == eth.BlockV2 && payload.Withdrawals == nil { - log.Warn("payload is on v2 topic, but does not have withdrawals", "bad_hash", payload.BlockHash.String()) + if blockVersion.HasWithdrawals() && payload.Withdrawals == nil { + log.Warn("payload is on v2/v3 topic, but does not have withdrawals", "bad_hash", payload.BlockHash.String()) return pubsub.ValidationReject } // [REJECT] if a V2 Block has non-empty withdrawals - if blockVersion == eth.BlockV2 && len(*payload.Withdrawals) != 0 { - log.Warn("payload is on v2 topic, but has non-empty withdrawals", "bad_hash", payload.BlockHash.String(), "withdrawal_count", len(*payload.Withdrawals)) + if blockVersion.HasWithdrawals() && len(*payload.Withdrawals) != 0 { + log.Warn("payload is on v2/v3 topic, but has non-empty withdrawals", "bad_hash", payload.BlockHash.String(), "withdrawal_count", len(*payload.Withdrawals)) + return pubsub.ValidationReject + } + + // [REJECT] if the block is on a topic <= V2 and has a blob gas value set + if !blockVersion.HasBlobProperties() && payload.BlobGasUsed != nil { + log.Warn("payload is on v1/v2 topic, but has blob gas used", "bad_hash", payload.BlockHash.String()) + return pubsub.ValidationReject + } + + // [REJECT] if the block is on a topic <= V2 and has an excess blob gas value set + if !blockVersion.HasBlobProperties() && payload.ExcessBlobGas != nil { + log.Warn("payload is on v1/v2 topic, but has excess blob gas", "bad_hash", payload.BlockHash.String()) + return pubsub.ValidationReject + } + + if blockVersion.HasBlobProperties() { + // [REJECT] if the block is on a topic >= V3 and has a blob gas used value that is not zero + if payload.BlobGasUsed == nil || (payload.BlobGasUsed != nil && *payload.BlobGasUsed != 0) { + log.Warn("payload is on v3 topic, but has non-zero blob gas used", "bad_hash", payload.BlockHash.String(), "blob_gas_used", payload.BlobGasUsed) + return pubsub.ValidationReject + } + + // [REJECT] if the block is on a topic >= V3 and has an excess blob gas value that is not zero + if payload.ExcessBlobGas == nil || (payload.ExcessBlobGas != nil && *payload.ExcessBlobGas != 0) { + log.Warn("payload is on v3 topic, but has non-zero excess blob gas", "bad_hash", payload.BlockHash.String(), "excess_blob_gas", payload.ExcessBlobGas) + return pubsub.ValidationReject + } + } + + // [REJECT] if the block is on a topic >= V3 and the parent beacon block root is nil + if blockVersion.HasParentBeaconBlockRoot() && envelope.ParentBeaconBlockRoot == nil { + log.Warn("payload is on v3 topic, but has nil parent beacon block root", "bad_hash", payload.BlockHash.String()) return pubsub.ValidationReject } @@ -353,7 +401,7 @@ func BuildBlocksValidator(log log.Logger, cfg *rollup.Config, runCfg GossipRunti seen.markSeen(payload.BlockHash) // remember the decoded payload for later usage in topic subscriber. - message.ValidatorData = &payload + message.ValidatorData = &envelope return pubsub.ValidationAccept } } @@ -388,18 +436,19 @@ func verifyBlockSignature(log log.Logger, cfg *rollup.Config, runCfg GossipRunti } type GossipIn interface { - OnUnsafeL2Payload(ctx context.Context, from peer.ID, msg *eth.ExecutionPayload) error + OnUnsafeL2Payload(ctx context.Context, from peer.ID, msg *eth.ExecutionPayloadEnvelope) error } type GossipTopicInfo interface { AllBlockTopicsPeers() []peer.ID BlocksTopicV1Peers() []peer.ID BlocksTopicV2Peers() []peer.ID + BlocksTopicV3Peers() []peer.ID } type GossipOut interface { GossipTopicInfo - PublishL2Payload(ctx context.Context, msg *eth.ExecutionPayload, signer Signer) error + PublishL2Payload(ctx context.Context, msg *eth.ExecutionPayloadEnvelope, signer Signer) error Close() error } @@ -429,6 +478,7 @@ type publisher struct { blocksV1 *blockTopic blocksV2 *blockTopic + blocksV3 *blockTopic runCfg GossipRuntimeConfig } @@ -451,7 +501,7 @@ func combinePeers(allPeers ...[]peer.ID) []peer.ID { } func (p *publisher) AllBlockTopicsPeers() []peer.ID { - return combinePeers(p.BlocksTopicV1Peers(), p.BlocksTopicV2Peers()) + return combinePeers(p.BlocksTopicV1Peers(), p.BlocksTopicV2Peers(), p.BlocksTopicV3Peers()) } func (p *publisher) BlocksTopicV1Peers() []peer.ID { @@ -462,7 +512,11 @@ func (p *publisher) BlocksTopicV2Peers() []peer.ID { return p.blocksV2.topic.ListPeers() } -func (p *publisher) PublishL2Payload(ctx context.Context, payload *eth.ExecutionPayload, signer Signer) error { +func (p *publisher) BlocksTopicV3Peers() []peer.ID { + return p.blocksV3.topic.ListPeers() +} + +func (p *publisher) PublishL2Payload(ctx context.Context, envelope *eth.ExecutionPayloadEnvelope, signer Signer) error { res := msgBufPool.Get().(*[]byte) buf := bytes.NewBuffer((*res)[:0]) defer func() { @@ -471,9 +525,17 @@ func (p *publisher) PublishL2Payload(ctx context.Context, payload *eth.Execution }() buf.Write(make([]byte, 65)) - if _, err := payload.MarshalSSZ(buf); err != nil { - return fmt.Errorf("failed to encoded execution payload to publish: %w", err) + + if envelope.ParentBeaconBlockRoot != nil { + if _, err := envelope.MarshalSSZ(buf); err != nil { + return fmt.Errorf("failed to encoded execution payload envelope to publish: %w", err) + } + } else { + if _, err := envelope.ExecutionPayload.MarshalSSZ(buf); err != nil { + return fmt.Errorf("failed to encoded execution payload to publish: %w", err) + } } + data := buf.Bytes() payloadData := data[65:] sig, err := signer.Sign(ctx, SigningDomainBlocksV1, p.cfg.L2ChainID, payloadData) @@ -486,7 +548,9 @@ func (p *publisher) PublishL2Payload(ctx context.Context, payload *eth.Execution // This also copies the data, freeing up the original buffer to go back into the pool out := snappy.Encode(nil, data) - if p.cfg.IsCanyon(uint64(payload.Timestamp)) { + if p.cfg.IsEcotone(uint64(envelope.ExecutionPayload.Timestamp)) { + return p.blocksV3.topic.Publish(ctx, out) + } else if p.cfg.IsCanyon(uint64(envelope.ExecutionPayload.Timestamp)) { return p.blocksV2.topic.Publish(ctx, out) } else { return p.blocksV1.topic.Publish(ctx, out) @@ -519,12 +583,21 @@ func JoinGossip(self peer.ID, ps *pubsub.PubSub, log log.Logger, cfg *rollup.Con return nil, fmt.Errorf("failed to setup blocks v2 p2p: %w", err) } + v3Logger := log.New("topic", "blocksV3") + blocksV3Validator := guardGossipValidator(log, logValidationResult(self, "validated blockv3", v3Logger, BuildBlocksValidator(v3Logger, cfg, runCfg, eth.BlockV3))) + blocksV3, err := newBlockTopic(p2pCtx, blocksTopicV3(cfg), ps, v3Logger, gossipIn, blocksV3Validator) + if err != nil { + p2pCancel() + return nil, fmt.Errorf("failed to setup blocks v3 p2p: %w", err) + } + return &publisher{ log: log, cfg: cfg, p2pCancel: p2pCancel, blocksV1: blocksV1, blocksV2: blocksV2, + blocksV3: blocksV3, runCfg: runCfg, }, nil } @@ -570,9 +643,9 @@ func newBlockTopic(ctx context.Context, topicId string, ps *pubsub.PubSub, log l type TopicSubscriber func(ctx context.Context, sub *pubsub.Subscription) type MessageHandler func(ctx context.Context, from peer.ID, msg any) error -func BlocksHandler(onBlock func(ctx context.Context, from peer.ID, msg *eth.ExecutionPayload) error) MessageHandler { +func BlocksHandler(onBlock func(ctx context.Context, from peer.ID, msg *eth.ExecutionPayloadEnvelope) error) MessageHandler { return func(ctx context.Context, from peer.ID, msg any) error { - payload, ok := msg.(*eth.ExecutionPayload) + payload, ok := msg.(*eth.ExecutionPayloadEnvelope) if !ok { return fmt.Errorf("expected topic validator to parse and validate data into execution payload, but got %T", msg) } @@ -601,7 +674,6 @@ func MakeSubscriber(log log.Logger, msgHandler MessageHandler) TopicSubscriber { } func LogTopicEvents(ctx context.Context, log log.Logger, evHandler *pubsub.TopicEventHandler) { - defer evHandler.Cancel() for { ev, err := evHandler.NextPeerEvent(ctx) if err != nil { diff --git a/op-node/p2p/gossip_test.go b/op-node/p2p/gossip_test.go index 0f47787d84ab..0833f270e40b 100644 --- a/op-node/p2p/gossip_test.go +++ b/op-node/p2p/gossip_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "io" "math/big" "testing" "time" @@ -30,7 +31,7 @@ import ( ) func TestGuardGossipValidator(t *testing.T) { - logger := testlog.Logger(t, log.LvlCrit) + logger := testlog.Logger(t, log.LevelCrit) val := guardGossipValidator(logger, func(ctx context.Context, id peer.ID, message *pubsub.Message) pubsub.ValidationResult { if id == "mallory" { panic("mallory was here") @@ -56,7 +57,7 @@ func TestCombinePeers(t *testing.T) { } func TestVerifyBlockSignature(t *testing.T) { - logger := testlog.Logger(t, log.LvlCrit) + logger := testlog.Logger(t, log.LevelCrit) cfg := &rollup.Config{ L2ChainID: big.NewInt(100), } @@ -100,7 +101,11 @@ func TestVerifyBlockSignature(t *testing.T) { }) } -func createSignedP2Payload(payload *eth.ExecutionPayload, signer Signer, l2ChainID *big.Int) ([]byte, error) { +type MarshalSSZ interface { + MarshalSSZ(w io.Writer) (n int, err error) +} + +func createSignedP2Payload(payload MarshalSSZ, signer Signer, l2ChainID *big.Int) ([]byte, error) { var buf bytes.Buffer buf.Write(make([]byte, 65)) if _, err := payload.MarshalSSZ(&buf); err != nil { @@ -119,6 +124,22 @@ func createSignedP2Payload(payload *eth.ExecutionPayload, signer Signer, l2Chain return snappy.Encode(nil, data), nil } +func createExecutionPayload(w types.Withdrawals, excessGas, gasUsed *uint64) *eth.ExecutionPayload { + return ð.ExecutionPayload{ + Timestamp: hexutil.Uint64(time.Now().Unix()), + Withdrawals: &w, + ExcessBlobGas: (*eth.Uint64Quantity)(excessGas), + BlobGasUsed: (*eth.Uint64Quantity)(gasUsed), + } +} + +func createEnvelope(h *common.Hash, w types.Withdrawals, excessGas, gasUsed *uint64) *eth.ExecutionPayloadEnvelope { + return ð.ExecutionPayloadEnvelope{ + ExecutionPayload: createExecutionPayload(w, excessGas, gasUsed), + ParentBeaconBlockRoot: h, + } +} + // TestBlockValidator does some very basic tests of the p2p block validation logic func TestBlockValidator(t *testing.T) { // Params Set 1: Create the validation function @@ -129,35 +150,61 @@ func TestBlockValidator(t *testing.T) { require.NoError(t, err) runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.SequencerP2P.PublicKey)} signer := &PreparedSigner{Signer: NewLocalSigner(secrets.SequencerP2P)} - - // valFnV1 := BuildBlocksValidator(testlog.Logger(t, log.LvlCrit), rollupCfg, runCfg, eth.BlockV1) - valFnV2 := BuildBlocksValidator(testlog.Logger(t, log.LvlCrit), cfg, runCfg, eth.BlockV2) - // Params Set 2: Call the validation function peerID := peer.ID("foo") - // Valid Case - payload := eth.ExecutionPayload{ - Timestamp: hexutil.Uint64(time.Now().Unix()), - Withdrawals: &types.Withdrawals{}, + v2Validator := BuildBlocksValidator(testlog.Logger(t, log.LevelCrit), cfg, runCfg, eth.BlockV2) + v3Validator := BuildBlocksValidator(testlog.Logger(t, log.LevelCrit), cfg, runCfg, eth.BlockV3) + + zero, one := uint64(0), uint64(1) + beaconHash := common.HexToHash("0x1234") + + payloadTests := []struct { + name string + validator pubsub.ValidatorEx + result pubsub.ValidationResult + payload *eth.ExecutionPayload + }{ + {"V2Valid", v2Validator, pubsub.ValidationAccept, createExecutionPayload(types.Withdrawals{}, nil, nil)}, + {"V2NonZeroWithdrawals", v2Validator, pubsub.ValidationReject, createExecutionPayload(types.Withdrawals{&types.Withdrawal{Index: 1, Validator: 1}}, nil, nil)}, + {"V2NonZeroBlobProperties", v2Validator, pubsub.ValidationReject, createExecutionPayload(types.Withdrawals{}, &zero, &zero)}, + {"V3RejectExecutionPayload", v3Validator, pubsub.ValidationReject, createExecutionPayload(types.Withdrawals{}, &zero, &zero)}, } - payload.BlockHash, _ = payload.CheckBlockHash() // hack to generate the block hash easily. - data, err := createSignedP2Payload(&payload, signer, cfg.L2ChainID) - require.NoError(t, err) - message := &pubsub.Message{Message: &pubsub_pb.Message{Data: data}} - res := valFnV2(context.TODO(), peerID, message) - require.Equal(t, res, pubsub.ValidationAccept) - - // Invalid because non-empty withdrawals when Canyon is active - payload = eth.ExecutionPayload{ - Timestamp: hexutil.Uint64(time.Now().Unix()), - Withdrawals: &types.Withdrawals{&types.Withdrawal{Index: 1, Validator: 1}}, + + for _, tt := range payloadTests { + test := tt + t.Run(fmt.Sprintf("ExecutionPayload_%s", test.name), func(t *testing.T) { + e := ð.ExecutionPayloadEnvelope{ExecutionPayload: test.payload} + test.payload.BlockHash, _ = e.CheckBlockHash() // hack to generate the block hash easily. + data, err := createSignedP2Payload(test.payload, signer, cfg.L2ChainID) + require.NoError(t, err) + message := &pubsub.Message{Message: &pubsub_pb.Message{Data: data}} + res := test.validator(context.TODO(), peerID, message) + require.Equal(t, res, test.result) + }) + } + + envelopeTests := []struct { + name string + validator pubsub.ValidatorEx + result pubsub.ValidationResult + payload *eth.ExecutionPayloadEnvelope + }{ + {"V3RejectNonZeroExcessGas", v3Validator, pubsub.ValidationReject, createEnvelope(&beaconHash, types.Withdrawals{}, &one, &zero)}, + {"V3RejectNonZeroBlobGasUsed", v3Validator, pubsub.ValidationReject, createEnvelope(&beaconHash, types.Withdrawals{}, &zero, &one)}, + {"V3RejectNonZeroBlobGasUsed", v3Validator, pubsub.ValidationReject, createEnvelope(&beaconHash, types.Withdrawals{}, &zero, &one)}, + {"V3Valid", v3Validator, pubsub.ValidationAccept, createEnvelope(&beaconHash, types.Withdrawals{}, &zero, &zero)}, } - payload.BlockHash, _ = payload.CheckBlockHash() - data, err = createSignedP2Payload(&payload, signer, cfg.L2ChainID) - require.NoError(t, err) - message = &pubsub.Message{Message: &pubsub_pb.Message{Data: data}} - res = valFnV2(context.TODO(), peerID, message) - require.Equal(t, res, pubsub.ValidationReject) + for _, tt := range envelopeTests { + test := tt + t.Run(fmt.Sprintf("ExecutionPayloadEnvelope_%s", test.name), func(t *testing.T) { + test.payload.ExecutionPayload.BlockHash, _ = test.payload.CheckBlockHash() // hack to generate the block hash easily. + data, err := createSignedP2Payload(test.payload, signer, cfg.L2ChainID) + require.NoError(t, err) + message := &pubsub.Message{Message: &pubsub_pb.Message{Data: data}} + res := test.validator(context.TODO(), peerID, message) + require.Equal(t, res, test.result) + }) + } } diff --git a/op-node/p2p/host.go b/op-node/p2p/host.go index 5396bed05d9c..584a42d0fe75 100644 --- a/op-node/p2p/host.go +++ b/op-node/p2p/host.go @@ -21,6 +21,7 @@ import ( "github.com/libp2p/go-libp2p/core/sec/insecure" basichost "github.com/libp2p/go-libp2p/p2p/host/basic" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" + "github.com/libp2p/go-libp2p/p2p/protocol/ping" "github.com/libp2p/go-libp2p/p2p/security/noise" tls "github.com/libp2p/go-libp2p/p2p/security/tls" "github.com/libp2p/go-libp2p/p2p/transport/tcp" @@ -52,6 +53,8 @@ type extraHost struct { staticPeers []*peer.AddrInfo + pinging *PingService + quitC chan struct{} } @@ -65,6 +68,9 @@ func (e *extraHost) ConnectionManager() connmgr.ConnManager { func (e *extraHost) Close() error { close(e.quitC) + if e.pinging != nil { + e.pinging.Close() + } return e.Host.Close() } @@ -229,13 +235,17 @@ func (conf *Config) Host(log log.Logger, reporter metrics.Reporter, metrics Host return nil, err } - staticPeers := make([]*peer.AddrInfo, len(conf.StaticPeers)) - for i, peerAddr := range conf.StaticPeers { + staticPeers := make([]*peer.AddrInfo, 0, len(conf.StaticPeers)) + for _, peerAddr := range conf.StaticPeers { addr, err := peer.AddrInfoFromP2pAddr(peerAddr) if err != nil { return nil, fmt.Errorf("bad peer address: %w", err) } - staticPeers[i] = addr + if addr.ID == h.ID() { + log.Info("Static-peer list contains address of local peer, ignoring the address.", "peer_id", addr.ID, "addrs", addr.Addrs) + continue + } + staticPeers = append(staticPeers, addr) } out := &extraHost{ @@ -245,6 +255,14 @@ func (conf *Config) Host(log log.Logger, reporter metrics.Reporter, metrics Host staticPeers: staticPeers, quitC: make(chan struct{}), } + + if conf.EnablePingService { + out.pinging = NewPingService(log, + func(ctx context.Context, peerID peer.ID) <-chan ping.Result { + return ping.Ping(ctx, h, peerID) + }, h.Network().Peers, clock.SystemClock) + } + out.initStaticPeers() if len(conf.StaticPeers) > 0 { go out.monitorStaticPeers() diff --git a/op-node/p2p/host_test.go b/op-node/p2p/host_test.go index 1a44c25664b0..a71372a08967 100644 --- a/op-node/p2p/host_test.go +++ b/op-node/p2p/host_test.go @@ -15,6 +15,7 @@ import ( "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" + ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" @@ -24,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum-optimism/optimism/op-node/metrics" + "github.com/ethereum-optimism/optimism/op-node/p2p/store" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" @@ -59,10 +61,10 @@ func TestingConfig(t *testing.T) *Config { func TestP2PSimple(t *testing.T) { confA := TestingConfig(t) confB := TestingConfig(t) - hostA, err := confA.Host(testlog.Logger(t, log.LvlError).New("host", "A"), nil, metrics.NoopMetrics) + hostA, err := confA.Host(testlog.Logger(t, log.LevelError).New("host", "A"), nil, metrics.NoopMetrics) require.NoError(t, err, "failed to launch host A") defer hostA.Close() - hostB, err := confB.Host(testlog.Logger(t, log.LvlError).New("host", "B"), nil, metrics.NoopMetrics) + hostB, err := confB.Host(testlog.Logger(t, log.LevelError).New("host", "B"), nil, metrics.NoopMetrics) require.NoError(t, err, "failed to launch host B") defer hostB.Close() err = hostA.Connect(context.Background(), peer.AddrInfo{ID: hostB.ID(), Addrs: hostB.Addrs()}) @@ -71,10 +73,10 @@ func TestP2PSimple(t *testing.T) { } type mockGossipIn struct { - OnUnsafeL2PayloadFn func(ctx context.Context, from peer.ID, msg *eth.ExecutionPayload) error + OnUnsafeL2PayloadFn func(ctx context.Context, from peer.ID, msg *eth.ExecutionPayloadEnvelope) error } -func (m *mockGossipIn) OnUnsafeL2Payload(ctx context.Context, from peer.ID, msg *eth.ExecutionPayload) error { +func (m *mockGossipIn) OnUnsafeL2Payload(ctx context.Context, from peer.ID, msg *eth.ExecutionPayloadEnvelope) error { if m.OnUnsafeL2PayloadFn != nil { return m.OnUnsafeL2PayloadFn(ctx, from, msg) } @@ -117,8 +119,8 @@ func TestP2PFull(t *testing.T) { runCfgA := &testutils.MockRuntimeConfig{P2PSeqAddress: common.Address{0x42}} runCfgB := &testutils.MockRuntimeConfig{P2PSeqAddress: common.Address{0x42}} - logA := testlog.Logger(t, log.LvlError).New("host", "A") - nodeA, err := NewNodeP2P(context.Background(), &rollup.Config{}, logA, &confA, &mockGossipIn{}, nil, runCfgA, metrics.NoopMetrics) + logA := testlog.Logger(t, log.LevelError).New("host", "A") + nodeA, err := NewNodeP2P(context.Background(), &rollup.Config{}, logA, &confA, &mockGossipIn{}, nil, runCfgA, metrics.NoopMetrics, false) require.NoError(t, err) defer nodeA.Close() @@ -139,15 +141,25 @@ func TestP2PFull(t *testing.T) { confB.StaticPeers, err = peer.AddrInfoToP2pAddrs(&peer.AddrInfo{ID: hostA.ID(), Addrs: hostA.Addrs()}) require.NoError(t, err) - logB := testlog.Logger(t, log.LvlError).New("host", "B") + // Add address of host B itself, it shouldn't connect or cause issues. + idB, err := peer.IDFromPublicKey(confB.Priv.GetPublic()) + require.NoError(t, err) + altAddrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/12345/p2p/" + idB.String()) + require.NoError(t, err) + confB.StaticPeers = append(confB.StaticPeers, altAddrB) + + logB := testlog.Logger(t, log.LevelError).New("host", "B") - nodeB, err := NewNodeP2P(context.Background(), &rollup.Config{}, logB, &confB, &mockGossipIn{}, nil, runCfgB, metrics.NoopMetrics) + nodeB, err := NewNodeP2P(context.Background(), &rollup.Config{}, logB, &confB, &mockGossipIn{}, nil, runCfgB, metrics.NoopMetrics, false) require.NoError(t, err) defer nodeB.Close() hostB := nodeB.Host() + require.True(t, nodeB.IsStatic(hostA.ID()), "node A must be static peer of node B") + require.False(t, nodeB.IsStatic(hostB.ID()), "node B must not be static peer of node B itself") + select { - case <-time.After(time.Second): + case <-time.After(30 * time.Second): t.Fatal("failed to connect new host") case c := <-conns: require.Equal(t, hostB.ID(), c.RemotePeer()) @@ -169,6 +181,17 @@ func TestP2PFull(t *testing.T) { require.Equal(t, []peer.ID{hostB.ID()}, blockedPeers) require.NoError(t, p2pClientA.UnblockPeer(ctx, hostB.ID())) + require.Error(t, p2pClientA.BlockAddr(ctx, nil)) + require.Error(t, p2pClientA.UnblockAddr(ctx, nil)) + require.Error(t, p2pClientA.BlockSubnet(ctx, nil)) + require.Error(t, p2pClientA.UnblockSubnet(ctx, nil)) + require.Error(t, p2pClientA.BlockPeer(ctx, "")) + require.Error(t, p2pClientA.UnblockPeer(ctx, "")) + require.Error(t, p2pClientA.ProtectPeer(ctx, "")) + require.Error(t, p2pClientA.UnprotectPeer(ctx, "")) + require.Error(t, p2pClientA.ConnectPeer(ctx, "")) + require.Error(t, p2pClientA.DisconnectPeer(ctx, "")) + require.NoError(t, p2pClientA.BlockAddr(ctx, net.IP{123, 123, 123, 123})) blockedIPs, err := p2pClientA.ListBlockedAddrs(ctx) require.NoError(t, err) @@ -196,11 +219,16 @@ func TestP2PFull(t *testing.T) { require.Equal(t, uint(1), stats.Connected) // disconnect + hostBId := hostB.ID().String() + peerDump, err = p2pClientA.Peers(ctx, false) + require.Nil(t, err) + data = peerDump.Peers[hostBId] + require.NotNil(t, data) require.NoError(t, p2pClientA.DisconnectPeer(ctx, hostB.ID())) peerDump, err = p2pClientA.Peers(ctx, false) require.Nil(t, err) - data = peerDump.Peers[hostB.ID().String()] - require.Equal(t, data.Connectedness, network.NotConnected) + data = peerDump.Peers[hostBId] + require.Nil(t, data) // reconnect addrsB, err := peer.AddrInfoToP2pAddrs(&peer.AddrInfo{ID: hostB.ID(), Addrs: hostB.Addrs()}) @@ -212,6 +240,8 @@ func TestP2PFull(t *testing.T) { } func TestDiscovery(t *testing.T) { + t.Skipf("skipping flaky test") + pA, _, err := crypto.GenerateSecp256k1Key(rand.Reader) require.NoError(t, err, "failed to generate new p2p priv key") pB, _, err := crypto.GenerateSecp256k1Key(rand.Reader) @@ -219,9 +249,9 @@ func TestDiscovery(t *testing.T) { pC, _, err := crypto.GenerateSecp256k1Key(rand.Reader) require.NoError(t, err, "failed to generate new p2p priv key") - logA := testlog.Logger(t, log.LvlError).New("host", "A") - logB := testlog.Logger(t, log.LvlError).New("host", "B") - logC := testlog.Logger(t, log.LvlError).New("host", "C") + logA := testlog.Logger(t, log.LevelError).New("host", "A") + logB := testlog.Logger(t, log.LevelError).New("host", "B") + logC := testlog.Logger(t, log.LevelError).New("host", "C") discDBA, err := enode.OpenDB("") // "" = memory db require.NoError(t, err) @@ -268,7 +298,7 @@ func TestDiscovery(t *testing.T) { resourcesCtx, resourcesCancel := context.WithCancel(context.Background()) defer resourcesCancel() - nodeA, err := NewNodeP2P(context.Background(), rollupCfg, logA, &confA, &mockGossipIn{}, nil, runCfgA, metrics.NoopMetrics) + nodeA, err := NewNodeP2P(context.Background(), rollupCfg, logA, &confA, &mockGossipIn{}, nil, runCfgA, metrics.NoopMetrics, false) require.NoError(t, err) defer nodeA.Close() hostA := nodeA.Host() @@ -283,7 +313,7 @@ func TestDiscovery(t *testing.T) { confB.DiscoveryDB = discDBC // Start B - nodeB, err := NewNodeP2P(context.Background(), rollupCfg, logB, &confB, &mockGossipIn{}, nil, runCfgB, metrics.NoopMetrics) + nodeB, err := NewNodeP2P(context.Background(), rollupCfg, logB, &confB, &mockGossipIn{}, nil, runCfgB, metrics.NoopMetrics, false) require.NoError(t, err) defer nodeB.Close() hostB := nodeB.Host() @@ -298,7 +328,7 @@ func TestDiscovery(t *testing.T) { }}) // Start C - nodeC, err := NewNodeP2P(context.Background(), rollupCfg, logC, &confC, &mockGossipIn{}, nil, runCfgC, metrics.NoopMetrics) + nodeC, err := NewNodeP2P(context.Background(), rollupCfg, logC, &confC, &mockGossipIn{}, nil, runCfgC, metrics.NoopMetrics, false) require.NoError(t, err) defer nodeC.Close() hostC := nodeC.Host() @@ -322,6 +352,26 @@ func TestDiscovery(t *testing.T) { peersOfB = append(peersOfB, c.RemotePeer()) } } + + // Check that among known connections (B-A, B-C), we have metadata + type mdcheck struct { + n1 *NodeP2P + n2 *NodeP2P + } + cases := []mdcheck{ + {nodeB, nodeA}, + {nodeB, nodeC}, + } + for _, c := range cases { + // make peerstore metadata available + eps, ok := c.n1.Host().Peerstore().(store.ExtendedPeerstore) + require.True(t, ok) + // confirm n1 has metadata about n2 + md, err := eps.GetPeerMetadata(c.n2.Host().ID()) + require.NoError(t, err) + require.NotEmpty(t, md.ENR) + require.Equal(t, uint64(901), md.OPStackID) + } } // Most tests should use mocknets instead of using the actual local host network diff --git a/op-node/p2p/mocks/API.go b/op-node/p2p/mocks/API.go new file mode 100644 index 000000000000..c9204cf287b4 --- /dev/null +++ b/op-node/p2p/mocks/API.go @@ -0,0 +1,853 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + enode "github.com/ethereum/go-ethereum/p2p/enode" + mock "github.com/stretchr/testify/mock" + + net "net" + + p2p "github.com/ethereum-optimism/optimism/op-node/p2p" + + peer "github.com/libp2p/go-libp2p/core/peer" +) + +// API is an autogenerated mock type for the API type +type API struct { + mock.Mock +} + +type API_Expecter struct { + mock *mock.Mock +} + +func (_m *API) EXPECT() *API_Expecter { + return &API_Expecter{mock: &_m.Mock} +} + +// BlockAddr provides a mock function with given fields: ctx, ip +func (_m *API) BlockAddr(ctx context.Context, ip net.IP) error { + ret := _m.Called(ctx, ip) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, net.IP) error); ok { + r0 = rf(ctx, ip) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// API_BlockAddr_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BlockAddr' +type API_BlockAddr_Call struct { + *mock.Call +} + +// BlockAddr is a helper method to define mock.On call +// - ctx context.Context +// - ip net.IP +func (_e *API_Expecter) BlockAddr(ctx interface{}, ip interface{}) *API_BlockAddr_Call { + return &API_BlockAddr_Call{Call: _e.mock.On("BlockAddr", ctx, ip)} +} + +func (_c *API_BlockAddr_Call) Run(run func(ctx context.Context, ip net.IP)) *API_BlockAddr_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(net.IP)) + }) + return _c +} + +func (_c *API_BlockAddr_Call) Return(_a0 error) *API_BlockAddr_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *API_BlockAddr_Call) RunAndReturn(run func(context.Context, net.IP) error) *API_BlockAddr_Call { + _c.Call.Return(run) + return _c +} + +// BlockPeer provides a mock function with given fields: ctx, p +func (_m *API) BlockPeer(ctx context.Context, p peer.ID) error { + ret := _m.Called(ctx, p) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, peer.ID) error); ok { + r0 = rf(ctx, p) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// API_BlockPeer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BlockPeer' +type API_BlockPeer_Call struct { + *mock.Call +} + +// BlockPeer is a helper method to define mock.On call +// - ctx context.Context +// - p peer.ID +func (_e *API_Expecter) BlockPeer(ctx interface{}, p interface{}) *API_BlockPeer_Call { + return &API_BlockPeer_Call{Call: _e.mock.On("BlockPeer", ctx, p)} +} + +func (_c *API_BlockPeer_Call) Run(run func(ctx context.Context, p peer.ID)) *API_BlockPeer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(peer.ID)) + }) + return _c +} + +func (_c *API_BlockPeer_Call) Return(_a0 error) *API_BlockPeer_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *API_BlockPeer_Call) RunAndReturn(run func(context.Context, peer.ID) error) *API_BlockPeer_Call { + _c.Call.Return(run) + return _c +} + +// BlockSubnet provides a mock function with given fields: ctx, ipnet +func (_m *API) BlockSubnet(ctx context.Context, ipnet *net.IPNet) error { + ret := _m.Called(ctx, ipnet) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *net.IPNet) error); ok { + r0 = rf(ctx, ipnet) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// API_BlockSubnet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BlockSubnet' +type API_BlockSubnet_Call struct { + *mock.Call +} + +// BlockSubnet is a helper method to define mock.On call +// - ctx context.Context +// - ipnet *net.IPNet +func (_e *API_Expecter) BlockSubnet(ctx interface{}, ipnet interface{}) *API_BlockSubnet_Call { + return &API_BlockSubnet_Call{Call: _e.mock.On("BlockSubnet", ctx, ipnet)} +} + +func (_c *API_BlockSubnet_Call) Run(run func(ctx context.Context, ipnet *net.IPNet)) *API_BlockSubnet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*net.IPNet)) + }) + return _c +} + +func (_c *API_BlockSubnet_Call) Return(_a0 error) *API_BlockSubnet_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *API_BlockSubnet_Call) RunAndReturn(run func(context.Context, *net.IPNet) error) *API_BlockSubnet_Call { + _c.Call.Return(run) + return _c +} + +// ConnectPeer provides a mock function with given fields: ctx, addr +func (_m *API) ConnectPeer(ctx context.Context, addr string) error { + ret := _m.Called(ctx, addr) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, addr) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// API_ConnectPeer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ConnectPeer' +type API_ConnectPeer_Call struct { + *mock.Call +} + +// ConnectPeer is a helper method to define mock.On call +// - ctx context.Context +// - addr string +func (_e *API_Expecter) ConnectPeer(ctx interface{}, addr interface{}) *API_ConnectPeer_Call { + return &API_ConnectPeer_Call{Call: _e.mock.On("ConnectPeer", ctx, addr)} +} + +func (_c *API_ConnectPeer_Call) Run(run func(ctx context.Context, addr string)) *API_ConnectPeer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *API_ConnectPeer_Call) Return(_a0 error) *API_ConnectPeer_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *API_ConnectPeer_Call) RunAndReturn(run func(context.Context, string) error) *API_ConnectPeer_Call { + _c.Call.Return(run) + return _c +} + +// DisconnectPeer provides a mock function with given fields: ctx, id +func (_m *API) DisconnectPeer(ctx context.Context, id peer.ID) error { + ret := _m.Called(ctx, id) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, peer.ID) error); ok { + r0 = rf(ctx, id) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// API_DisconnectPeer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DisconnectPeer' +type API_DisconnectPeer_Call struct { + *mock.Call +} + +// DisconnectPeer is a helper method to define mock.On call +// - ctx context.Context +// - id peer.ID +func (_e *API_Expecter) DisconnectPeer(ctx interface{}, id interface{}) *API_DisconnectPeer_Call { + return &API_DisconnectPeer_Call{Call: _e.mock.On("DisconnectPeer", ctx, id)} +} + +func (_c *API_DisconnectPeer_Call) Run(run func(ctx context.Context, id peer.ID)) *API_DisconnectPeer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(peer.ID)) + }) + return _c +} + +func (_c *API_DisconnectPeer_Call) Return(_a0 error) *API_DisconnectPeer_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *API_DisconnectPeer_Call) RunAndReturn(run func(context.Context, peer.ID) error) *API_DisconnectPeer_Call { + _c.Call.Return(run) + return _c +} + +// DiscoveryTable provides a mock function with given fields: ctx +func (_m *API) DiscoveryTable(ctx context.Context) ([]*enode.Node, error) { + ret := _m.Called(ctx) + + var r0 []*enode.Node + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]*enode.Node, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []*enode.Node); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*enode.Node) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// API_DiscoveryTable_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DiscoveryTable' +type API_DiscoveryTable_Call struct { + *mock.Call +} + +// DiscoveryTable is a helper method to define mock.On call +// - ctx context.Context +func (_e *API_Expecter) DiscoveryTable(ctx interface{}) *API_DiscoveryTable_Call { + return &API_DiscoveryTable_Call{Call: _e.mock.On("DiscoveryTable", ctx)} +} + +func (_c *API_DiscoveryTable_Call) Run(run func(ctx context.Context)) *API_DiscoveryTable_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *API_DiscoveryTable_Call) Return(_a0 []*enode.Node, _a1 error) *API_DiscoveryTable_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *API_DiscoveryTable_Call) RunAndReturn(run func(context.Context) ([]*enode.Node, error)) *API_DiscoveryTable_Call { + _c.Call.Return(run) + return _c +} + +// ListBlockedAddrs provides a mock function with given fields: ctx +func (_m *API) ListBlockedAddrs(ctx context.Context) ([]net.IP, error) { + ret := _m.Called(ctx) + + var r0 []net.IP + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]net.IP, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []net.IP); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]net.IP) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// API_ListBlockedAddrs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListBlockedAddrs' +type API_ListBlockedAddrs_Call struct { + *mock.Call +} + +// ListBlockedAddrs is a helper method to define mock.On call +// - ctx context.Context +func (_e *API_Expecter) ListBlockedAddrs(ctx interface{}) *API_ListBlockedAddrs_Call { + return &API_ListBlockedAddrs_Call{Call: _e.mock.On("ListBlockedAddrs", ctx)} +} + +func (_c *API_ListBlockedAddrs_Call) Run(run func(ctx context.Context)) *API_ListBlockedAddrs_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *API_ListBlockedAddrs_Call) Return(_a0 []net.IP, _a1 error) *API_ListBlockedAddrs_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *API_ListBlockedAddrs_Call) RunAndReturn(run func(context.Context) ([]net.IP, error)) *API_ListBlockedAddrs_Call { + _c.Call.Return(run) + return _c +} + +// ListBlockedPeers provides a mock function with given fields: ctx +func (_m *API) ListBlockedPeers(ctx context.Context) ([]peer.ID, error) { + ret := _m.Called(ctx) + + var r0 []peer.ID + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]peer.ID, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []peer.ID); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]peer.ID) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// API_ListBlockedPeers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListBlockedPeers' +type API_ListBlockedPeers_Call struct { + *mock.Call +} + +// ListBlockedPeers is a helper method to define mock.On call +// - ctx context.Context +func (_e *API_Expecter) ListBlockedPeers(ctx interface{}) *API_ListBlockedPeers_Call { + return &API_ListBlockedPeers_Call{Call: _e.mock.On("ListBlockedPeers", ctx)} +} + +func (_c *API_ListBlockedPeers_Call) Run(run func(ctx context.Context)) *API_ListBlockedPeers_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *API_ListBlockedPeers_Call) Return(_a0 []peer.ID, _a1 error) *API_ListBlockedPeers_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *API_ListBlockedPeers_Call) RunAndReturn(run func(context.Context) ([]peer.ID, error)) *API_ListBlockedPeers_Call { + _c.Call.Return(run) + return _c +} + +// ListBlockedSubnets provides a mock function with given fields: ctx +func (_m *API) ListBlockedSubnets(ctx context.Context) ([]*net.IPNet, error) { + ret := _m.Called(ctx) + + var r0 []*net.IPNet + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]*net.IPNet, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []*net.IPNet); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*net.IPNet) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// API_ListBlockedSubnets_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListBlockedSubnets' +type API_ListBlockedSubnets_Call struct { + *mock.Call +} + +// ListBlockedSubnets is a helper method to define mock.On call +// - ctx context.Context +func (_e *API_Expecter) ListBlockedSubnets(ctx interface{}) *API_ListBlockedSubnets_Call { + return &API_ListBlockedSubnets_Call{Call: _e.mock.On("ListBlockedSubnets", ctx)} +} + +func (_c *API_ListBlockedSubnets_Call) Run(run func(ctx context.Context)) *API_ListBlockedSubnets_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *API_ListBlockedSubnets_Call) Return(_a0 []*net.IPNet, _a1 error) *API_ListBlockedSubnets_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *API_ListBlockedSubnets_Call) RunAndReturn(run func(context.Context) ([]*net.IPNet, error)) *API_ListBlockedSubnets_Call { + _c.Call.Return(run) + return _c +} + +// PeerStats provides a mock function with given fields: ctx +func (_m *API) PeerStats(ctx context.Context) (*p2p.PeerStats, error) { + ret := _m.Called(ctx) + + var r0 *p2p.PeerStats + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*p2p.PeerStats, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *p2p.PeerStats); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*p2p.PeerStats) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// API_PeerStats_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PeerStats' +type API_PeerStats_Call struct { + *mock.Call +} + +// PeerStats is a helper method to define mock.On call +// - ctx context.Context +func (_e *API_Expecter) PeerStats(ctx interface{}) *API_PeerStats_Call { + return &API_PeerStats_Call{Call: _e.mock.On("PeerStats", ctx)} +} + +func (_c *API_PeerStats_Call) Run(run func(ctx context.Context)) *API_PeerStats_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *API_PeerStats_Call) Return(_a0 *p2p.PeerStats, _a1 error) *API_PeerStats_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *API_PeerStats_Call) RunAndReturn(run func(context.Context) (*p2p.PeerStats, error)) *API_PeerStats_Call { + _c.Call.Return(run) + return _c +} + +// Peers provides a mock function with given fields: ctx, connected +func (_m *API) Peers(ctx context.Context, connected bool) (*p2p.PeerDump, error) { + ret := _m.Called(ctx, connected) + + var r0 *p2p.PeerDump + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, bool) (*p2p.PeerDump, error)); ok { + return rf(ctx, connected) + } + if rf, ok := ret.Get(0).(func(context.Context, bool) *p2p.PeerDump); ok { + r0 = rf(ctx, connected) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*p2p.PeerDump) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, bool) error); ok { + r1 = rf(ctx, connected) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// API_Peers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Peers' +type API_Peers_Call struct { + *mock.Call +} + +// Peers is a helper method to define mock.On call +// - ctx context.Context +// - connected bool +func (_e *API_Expecter) Peers(ctx interface{}, connected interface{}) *API_Peers_Call { + return &API_Peers_Call{Call: _e.mock.On("Peers", ctx, connected)} +} + +func (_c *API_Peers_Call) Run(run func(ctx context.Context, connected bool)) *API_Peers_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(bool)) + }) + return _c +} + +func (_c *API_Peers_Call) Return(_a0 *p2p.PeerDump, _a1 error) *API_Peers_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *API_Peers_Call) RunAndReturn(run func(context.Context, bool) (*p2p.PeerDump, error)) *API_Peers_Call { + _c.Call.Return(run) + return _c +} + +// ProtectPeer provides a mock function with given fields: ctx, p +func (_m *API) ProtectPeer(ctx context.Context, p peer.ID) error { + ret := _m.Called(ctx, p) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, peer.ID) error); ok { + r0 = rf(ctx, p) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// API_ProtectPeer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProtectPeer' +type API_ProtectPeer_Call struct { + *mock.Call +} + +// ProtectPeer is a helper method to define mock.On call +// - ctx context.Context +// - p peer.ID +func (_e *API_Expecter) ProtectPeer(ctx interface{}, p interface{}) *API_ProtectPeer_Call { + return &API_ProtectPeer_Call{Call: _e.mock.On("ProtectPeer", ctx, p)} +} + +func (_c *API_ProtectPeer_Call) Run(run func(ctx context.Context, p peer.ID)) *API_ProtectPeer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(peer.ID)) + }) + return _c +} + +func (_c *API_ProtectPeer_Call) Return(_a0 error) *API_ProtectPeer_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *API_ProtectPeer_Call) RunAndReturn(run func(context.Context, peer.ID) error) *API_ProtectPeer_Call { + _c.Call.Return(run) + return _c +} + +// Self provides a mock function with given fields: ctx +func (_m *API) Self(ctx context.Context) (*p2p.PeerInfo, error) { + ret := _m.Called(ctx) + + var r0 *p2p.PeerInfo + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*p2p.PeerInfo, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *p2p.PeerInfo); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*p2p.PeerInfo) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// API_Self_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Self' +type API_Self_Call struct { + *mock.Call +} + +// Self is a helper method to define mock.On call +// - ctx context.Context +func (_e *API_Expecter) Self(ctx interface{}) *API_Self_Call { + return &API_Self_Call{Call: _e.mock.On("Self", ctx)} +} + +func (_c *API_Self_Call) Run(run func(ctx context.Context)) *API_Self_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *API_Self_Call) Return(_a0 *p2p.PeerInfo, _a1 error) *API_Self_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *API_Self_Call) RunAndReturn(run func(context.Context) (*p2p.PeerInfo, error)) *API_Self_Call { + _c.Call.Return(run) + return _c +} + +// UnblockAddr provides a mock function with given fields: ctx, ip +func (_m *API) UnblockAddr(ctx context.Context, ip net.IP) error { + ret := _m.Called(ctx, ip) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, net.IP) error); ok { + r0 = rf(ctx, ip) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// API_UnblockAddr_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UnblockAddr' +type API_UnblockAddr_Call struct { + *mock.Call +} + +// UnblockAddr is a helper method to define mock.On call +// - ctx context.Context +// - ip net.IP +func (_e *API_Expecter) UnblockAddr(ctx interface{}, ip interface{}) *API_UnblockAddr_Call { + return &API_UnblockAddr_Call{Call: _e.mock.On("UnblockAddr", ctx, ip)} +} + +func (_c *API_UnblockAddr_Call) Run(run func(ctx context.Context, ip net.IP)) *API_UnblockAddr_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(net.IP)) + }) + return _c +} + +func (_c *API_UnblockAddr_Call) Return(_a0 error) *API_UnblockAddr_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *API_UnblockAddr_Call) RunAndReturn(run func(context.Context, net.IP) error) *API_UnblockAddr_Call { + _c.Call.Return(run) + return _c +} + +// UnblockPeer provides a mock function with given fields: ctx, p +func (_m *API) UnblockPeer(ctx context.Context, p peer.ID) error { + ret := _m.Called(ctx, p) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, peer.ID) error); ok { + r0 = rf(ctx, p) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// API_UnblockPeer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UnblockPeer' +type API_UnblockPeer_Call struct { + *mock.Call +} + +// UnblockPeer is a helper method to define mock.On call +// - ctx context.Context +// - p peer.ID +func (_e *API_Expecter) UnblockPeer(ctx interface{}, p interface{}) *API_UnblockPeer_Call { + return &API_UnblockPeer_Call{Call: _e.mock.On("UnblockPeer", ctx, p)} +} + +func (_c *API_UnblockPeer_Call) Run(run func(ctx context.Context, p peer.ID)) *API_UnblockPeer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(peer.ID)) + }) + return _c +} + +func (_c *API_UnblockPeer_Call) Return(_a0 error) *API_UnblockPeer_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *API_UnblockPeer_Call) RunAndReturn(run func(context.Context, peer.ID) error) *API_UnblockPeer_Call { + _c.Call.Return(run) + return _c +} + +// UnblockSubnet provides a mock function with given fields: ctx, ipnet +func (_m *API) UnblockSubnet(ctx context.Context, ipnet *net.IPNet) error { + ret := _m.Called(ctx, ipnet) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *net.IPNet) error); ok { + r0 = rf(ctx, ipnet) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// API_UnblockSubnet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UnblockSubnet' +type API_UnblockSubnet_Call struct { + *mock.Call +} + +// UnblockSubnet is a helper method to define mock.On call +// - ctx context.Context +// - ipnet *net.IPNet +func (_e *API_Expecter) UnblockSubnet(ctx interface{}, ipnet interface{}) *API_UnblockSubnet_Call { + return &API_UnblockSubnet_Call{Call: _e.mock.On("UnblockSubnet", ctx, ipnet)} +} + +func (_c *API_UnblockSubnet_Call) Run(run func(ctx context.Context, ipnet *net.IPNet)) *API_UnblockSubnet_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*net.IPNet)) + }) + return _c +} + +func (_c *API_UnblockSubnet_Call) Return(_a0 error) *API_UnblockSubnet_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *API_UnblockSubnet_Call) RunAndReturn(run func(context.Context, *net.IPNet) error) *API_UnblockSubnet_Call { + _c.Call.Return(run) + return _c +} + +// UnprotectPeer provides a mock function with given fields: ctx, p +func (_m *API) UnprotectPeer(ctx context.Context, p peer.ID) error { + ret := _m.Called(ctx, p) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, peer.ID) error); ok { + r0 = rf(ctx, p) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// API_UnprotectPeer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UnprotectPeer' +type API_UnprotectPeer_Call struct { + *mock.Call +} + +// UnprotectPeer is a helper method to define mock.On call +// - ctx context.Context +// - p peer.ID +func (_e *API_Expecter) UnprotectPeer(ctx interface{}, p interface{}) *API_UnprotectPeer_Call { + return &API_UnprotectPeer_Call{Call: _e.mock.On("UnprotectPeer", ctx, p)} +} + +func (_c *API_UnprotectPeer_Call) Run(run func(ctx context.Context, p peer.ID)) *API_UnprotectPeer_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(peer.ID)) + }) + return _c +} + +func (_c *API_UnprotectPeer_Call) Return(_a0 error) *API_UnprotectPeer_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *API_UnprotectPeer_Call) RunAndReturn(run func(context.Context, peer.ID) error) *API_UnprotectPeer_Call { + _c.Call.Return(run) + return _c +} + +type mockConstructorTestingTNewAPI interface { + mock.TestingT + Cleanup(func()) +} + +// NewAPI creates a new instance of API. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewAPI(t mockConstructorTestingTNewAPI) *API { + mock := &API{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/op-node/p2p/monitor/peer_monitor_test.go b/op-node/p2p/monitor/peer_monitor_test.go index 6e18ac43f9c4..815e0531497c 100644 --- a/op-node/p2p/monitor/peer_monitor_test.go +++ b/op-node/p2p/monitor/peer_monitor_test.go @@ -18,7 +18,7 @@ import ( const testBanDuration = 2 * time.Hour func peerMonitorSetup(t *testing.T) (*PeerMonitor, *clock2.DeterministicClock, *mocks.PeerManager) { - l := testlog.Logger(t, log.LvlInfo) + l := testlog.Logger(t, log.LevelInfo) clock := clock2.NewDeterministicClock(time.UnixMilli(10000)) manager := mocks.NewPeerManager(t) monitor := NewPeerMonitor(context.Background(), l, clock, manager, -100, testBanDuration) diff --git a/op-node/p2p/node.go b/op-node/p2p/node.go index 9c4d3f4da082..b80801f7dbb5 100644 --- a/op-node/p2p/node.go +++ b/op-node/p2p/node.go @@ -52,12 +52,12 @@ type NodeP2P struct { // NewNodeP2P creates a new p2p node, and returns a reference to it. If the p2p is disabled, it returns nil. // If metrics are configured, a bandwidth monitor will be spawned in a goroutine. -func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, l2Chain L2Chain, runCfg GossipRuntimeConfig, metrics metrics.Metricer) (*NodeP2P, error) { +func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, l2Chain L2Chain, runCfg GossipRuntimeConfig, metrics metrics.Metricer, elSyncEnabled bool) (*NodeP2P, error) { if setup == nil { return nil, errors.New("p2p node cannot be created without setup") } var n NodeP2P - if err := n.init(resourcesCtx, rollupCfg, log, setup, gossipIn, l2Chain, runCfg, metrics); err != nil { + if err := n.init(resourcesCtx, rollupCfg, log, setup, gossipIn, l2Chain, runCfg, metrics, elSyncEnabled); err != nil { closeErr := n.Close() if closeErr != nil { log.Error("failed to close p2p after starting with err", "closeErr", closeErr, "err", err) @@ -70,7 +70,7 @@ func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log. return &n, nil } -func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, l2Chain L2Chain, runCfg GossipRuntimeConfig, metrics metrics.Metricer) error { +func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, l2Chain L2Chain, runCfg GossipRuntimeConfig, metrics metrics.Metricer, elSyncEnabled bool) error { bwc := p2pmetrics.NewBandwidthCounter() n.log = log @@ -105,7 +105,7 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l n.appScorer = &NoopApplicationScorer{} } // Activate the P2P req-resp sync if enabled by feature-flag. - if setup.ReqRespSyncEnabled() { + if setup.ReqRespSyncEnabled() && !elSyncEnabled { n.syncCl = NewSyncClient(log, rollupCfg, n.host.NewStream, gossipIn.OnUnsafeL2Payload, metrics, n.appScorer) n.host.Network().Notify(&network.NotifyBundle{ ConnectedF: func(nw network.Network, conn network.Conn) { diff --git a/op-node/p2p/peer_scorer_test.go b/op-node/p2p/peer_scorer_test.go index 9750c8cc57ff..d0bc6fe73e6f 100644 --- a/op-node/p2p/peer_scorer_test.go +++ b/op-node/p2p/peer_scorer_test.go @@ -30,7 +30,7 @@ type PeerScorerTestSuite struct { func (testSuite *PeerScorerTestSuite) SetupTest() { testSuite.mockStore = &p2pMocks.Peerstore{} testSuite.mockMetricer = &p2pMocks.ScoreMetrics{} - testSuite.logger = testlog.Logger(testSuite.T(), log.LvlError) + testSuite.logger = testlog.Logger(testSuite.T(), log.LevelError) } // TestPeerScorer runs the PeerScorerTestSuite. diff --git a/op-node/p2p/peer_scores_test.go b/op-node/p2p/peer_scores_test.go index 79feb4b62f1c..f7f8da6d5d27 100644 --- a/op-node/p2p/peer_scores_test.go +++ b/op-node/p2p/peer_scores_test.go @@ -1,4 +1,4 @@ -package p2p +package p2p_test import ( "context" @@ -8,15 +8,6 @@ import ( "testing" "time" - "github.com/ethereum-optimism/optimism/op-node/rollup" - - //nolint:all - "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds" - - p2pMocks "github.com/ethereum-optimism/optimism/op-node/p2p/mocks" - "github.com/ethereum-optimism/optimism/op-node/p2p/store" - "github.com/ethereum-optimism/optimism/op-service/clock" - testlog "github.com/ethereum-optimism/optimism/op-service/testlog" log "github.com/ethereum/go-ethereum/log" ds "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/sync" @@ -26,11 +17,20 @@ import ( peer "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/peerstore" bhost "github.com/libp2p/go-libp2p/p2p/host/blank" - tswarm "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" + //nolint:all + "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds" + tswarm "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + + p2p "github.com/ethereum-optimism/optimism/op-node/p2p" + p2pMocks "github.com/ethereum-optimism/optimism/op-node/p2p/mocks" + "github.com/ethereum-optimism/optimism/op-node/p2p/store" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/clock" + testlog "github.com/ethereum-optimism/optimism/op-service/testlog" ) // PeerScoresTestSuite tests peer parameterization. @@ -46,7 +46,7 @@ type PeerScoresTestSuite struct { func (testSuite *PeerScoresTestSuite) SetupTest() { testSuite.mockStore = &p2pMocks.Peerstore{} testSuite.mockMetricer = &p2pMocks.ScoreMetrics{} - testSuite.logger = testlog.Logger(testSuite.T(), log.LvlError) + testSuite.logger = testlog.Logger(testSuite.T(), log.LevelError) } // TestPeerScores runs the PeerScoresTestSuite. @@ -71,7 +71,7 @@ func (c *customPeerstoreNetwork) Close() error { // getNetHosts generates a slice of hosts using the [libp2p/go-libp2p] library. func getNetHosts(testSuite *PeerScoresTestSuite, ctx context.Context, n int) []host.Host { var out []host.Host - log := testlog.Logger(testSuite.T(), log.LvlError) + log := testlog.Logger(testSuite.T(), log.LevelError) for i := 0; i < n; i++ { swarm := tswarm.GenSwarm(testSuite.T()) eps, err := store.NewExtendedPeerstore(ctx, log, clock.SystemClock, swarm.Peerstore(), sync.MutexWrap(ds.NewMapDatastore()), 1*time.Hour) @@ -86,7 +86,7 @@ func getNetHosts(testSuite *PeerScoresTestSuite, ctx context.Context, n int) []h type discriminatingAppScorer struct { badPeer peer.ID - NoopApplicationScorer + p2p.NoopApplicationScorer } func (d *discriminatingAppScorer) ApplicationScore(id peer.ID) float64 { @@ -99,7 +99,7 @@ func (d *discriminatingAppScorer) ApplicationScore(id peer.ID) float64 { func newGossipSubs(testSuite *PeerScoresTestSuite, ctx context.Context, hosts []host.Host) []*pubsub.PubSub { var psubs []*pubsub.PubSub - logger := testlog.Logger(testSuite.T(), log.LvlCrit) + logger := testlog.Logger(testSuite.T(), log.LevelCrit) // For each host, create a default gossipsub router. for _, h := range hosts { @@ -112,11 +112,11 @@ func newGossipSubs(testSuite *PeerScoresTestSuite, ctx context.Context, hosts [] extPeerStore, err := store.NewExtendedPeerstore(context.Background(), logger, clock.SystemClock, peerStore, dataStore, 1*time.Hour) require.NoError(testSuite.T(), err) - scorer := NewScorer( + scorer := p2p.NewScorer( &rollup.Config{L2ChainID: big.NewInt(123)}, extPeerStore, testSuite.mockMetricer, &discriminatingAppScorer{badPeer: hosts[0].ID()}, logger) - opts = append(opts, ConfigurePeerScoring(&Config{ - ScoringParams: &ScoringParams{ + opts = append(opts, p2p.ConfigurePeerScoring(&p2p.Config{ + ScoringParams: &p2p.ScoringParams{ PeerScoring: pubsub.PeerScoreParams{ AppSpecificWeight: 1, DecayInterval: time.Second, diff --git a/op-node/p2p/pings.go b/op-node/p2p/pings.go new file mode 100644 index 000000000000..bae2630959f2 --- /dev/null +++ b/op-node/p2p/pings.go @@ -0,0 +1,134 @@ +package p2p + +import ( + "context" + "sync" + "time" + + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/p2p/protocol/ping" + "golang.org/x/time/rate" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-service/clock" +) + +const ( + pingRound = 3 * time.Minute + pingsPerSecond rate.Limit = 1 + pingsBurst = 10 +) + +type PingFn func(ctx context.Context, peerID peer.ID) <-chan ping.Result + +type PeersFn func() []peer.ID + +type PingService struct { + ping PingFn + peers PeersFn + + clock clock.Clock + + log log.Logger + + ctx context.Context + cancel context.CancelFunc + + trace func(work string) + + // to signal service completion + wg sync.WaitGroup +} + +func NewPingService(log log.Logger, ping PingFn, peers PeersFn, clock clock.Clock) *PingService { + ctx, cancel := context.WithCancel(context.Background()) + srv := &PingService{ + ping: ping, + peers: peers, + log: log, + clock: clock, + ctx: ctx, + cancel: cancel, + } + srv.wg.Add(1) + go srv.pingPeersBackground() + return srv +} + +func (p *PingService) Close() { + p.cancel() + p.wg.Wait() +} + +func (e *PingService) pingPeersBackground() { + defer e.wg.Done() + + tick := e.clock.NewTicker(pingRound) + defer tick.Stop() + + if e.trace != nil { + e.trace("started") + } + + for { + select { + case <-tick.Ch(): + e.pingPeers() + case <-e.ctx.Done(): + return + } + } +} + +func (e *PingService) pingPeers() { + if e.trace != nil { + e.trace("pingPeers start") + } + ctx, cancel := context.WithTimeout(e.ctx, pingRound) + defer cancel() + + // Wait group to wait for all pings to complete + var wg sync.WaitGroup + // Rate-limiter to help schedule the ping + // work without overwhelming ourselves. + rl := rate.NewLimiter(pingsPerSecond, pingsBurst) + + // iterate through the connected peers + for i, peerID := range e.peers() { + if e.ctx.Err() != nil { // stop if the service is closing or timing out + return + } + if ctx.Err() != nil { + e.log.Warn("failed to ping all peers", "pinged", i, "err", ctx.Err()) + return + } + if err := rl.Wait(ctx); err != nil { + // host may be getting closed, causing a parent ctx to close. + return + } + wg.Add(1) + go func(peerID peer.ID) { + e.pingPeer(ctx, peerID) + wg.Done() + }(peerID) + } + wg.Wait() + if e.trace != nil { + e.trace("pingPeers end") + } +} + +func (e *PingService) pingPeer(ctx context.Context, peerID peer.ID) { + results := e.ping(ctx, peerID) + // the results channel will be closed by the ping.Ping function upon context close / completion + res, ok := <-results + if !ok { + // timed out or completed before Pong + e.log.Warn("failed to ping peer, context cancelled", "peerID", peerID, "err", ctx.Err()) + } else if res.Error != nil { + e.log.Warn("failed to ping peer, communication error", "peerID", peerID, "err", res.Error) + } else { + e.log.Debug("ping-pong", "peerID", peerID, "rtt", res.RTT) + } +} diff --git a/op-node/p2p/pings_test.go b/op-node/p2p/pings_test.go new file mode 100644 index 000000000000..5db685dd7a18 --- /dev/null +++ b/op-node/p2p/pings_test.go @@ -0,0 +1,84 @@ +package p2p + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/stretchr/testify/require" + "golang.org/x/exp/slog" + + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/p2p/protocol/ping" + + "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/ethereum-optimism/optimism/op-service/testlog" +) + +func TestPingService(t *testing.T) { + peers := []peer.ID{"a", "b", "c"} + log, captLog := testlog.CaptureLogger(t, slog.LevelDebug) + + pingCount := 0 + pingFn := PingFn(func(ctx context.Context, peerID peer.ID) <-chan ping.Result { + out := make(chan ping.Result, 1) + switch pingCount % 3 { + case 0: + // success + out <- ping.Result{ + RTT: time.Millisecond * 10, + Error: nil, + } + case 1: + // fake timeout + case 2: + // error + out <- ping.Result{ + RTT: 0, + Error: errors.New("fake error"), + } + } + close(out) + pingCount += 1 + return out + }) + + fakeClock := clock.NewDeterministicClock(time.Now()) + peersFn := PeersFn(func() []peer.ID { + return peers + }) + + srv := NewPingService(log, pingFn, peersFn, fakeClock) + + trace := make(chan string) + srv.trace = func(work string) { + trace <- work + } + + // wait for ping service to get online + require.Equal(t, "started", <-trace) + fakeClock.AdvanceTime(pingRound) + // wait for first round to start and complete + require.Equal(t, "pingPeers start", <-trace) + require.Equal(t, "pingPeers end", <-trace) + // see if client has hit all 3 cases we simulated on the server-side + require.Equal(t, 3, pingCount, "pinged 3 peers") + require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("ping-pong")), "case 0") + require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("failed to ping peer, context cancelled")), "case 1") + require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("failed to ping peer, communication error")), "case 2") + captLog.Clear() + + // advance clock again to proceed to second round, and wait for the round to start and complete + fakeClock.AdvanceTime(pingRound) + require.Equal(t, "pingPeers start", <-trace) + require.Equal(t, "pingPeers end", <-trace) + // see if client has hit all 3 cases we simulated on the server-side + require.Equal(t, 6, pingCount, "pinged 3 peers again") + require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("ping-pong")), "case 0") + require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("failed to ping peer, context cancelled")), "case 1") + require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("failed to ping peer, communication error")), "case 2") + captLog.Clear() + + srv.Close() +} diff --git a/op-node/p2p/rpc_api.go b/op-node/p2p/rpc_api.go index b5c3c10e8c23..d5875eb5ef7d 100644 --- a/op-node/p2p/rpc_api.go +++ b/op-node/p2p/rpc_api.go @@ -5,11 +5,11 @@ import ( "net" "time" - "github.com/ethereum-optimism/optimism/op-node/p2p/store" + "github.com/ethereum/go-ethereum/p2p/enode" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" - "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum-optimism/optimism/op-node/p2p/store" ) type PeerInfo struct { @@ -20,8 +20,8 @@ type PeerInfo struct { ENR string `json:"ENR"` // might not always be known, e.g. if the peer connected us instead of us discovering them Addresses []string `json:"addresses"` // multi-addresses. may be mix of LAN / docker / external IPs. All of them are communicated. Protocols []string `json:"protocols"` // negotiated protocols list - //GossipScore float64 - //PeerScore float64 + // GossipScore float64 + // PeerScore float64 Connectedness network.Connectedness `json:"connectedness"` // "NotConnected", "Connected", "CanConnect" (gracefully disconnected), or "CannotConnect" (tried but failed) Direction network.Direction `json:"direction"` // "Unknown", "Inbound" (if the peer contacted us), "Outbound" (if we connected to them) Protected bool `json:"protected"` // Protected peers do not get @@ -41,6 +41,7 @@ type PeerDump struct { BannedSubnets []*net.IPNet `json:"bannedSubnets"` } +//go:generate mockery --name API --output mocks/ --with-expecter=true type API interface { Self(ctx context.Context) (*PeerInfo, error) Peers(ctx context.Context, connected bool) (*PeerDump, error) diff --git a/op-node/p2p/rpc_server.go b/op-node/p2p/rpc_server.go index e86952ebd56d..1a9c7fcb8f2b 100644 --- a/op-node/p2p/rpc_server.go +++ b/op-node/p2p/rpc_server.go @@ -36,6 +36,7 @@ var ( ErrDisabledDiscovery = errors.New("discovery disabled") ErrNoConnectionManager = errors.New("no connection manager") ErrNoConnectionGater = errors.New("no connection gater") + ErrInvalidRequest = errors.New("invalid request") ) type Node interface { @@ -115,6 +116,10 @@ func dumpPeer(id peer.ID, nw network.Network, pstore peerstore.Peerstore, connMg if dat, err := eps.GetPeerScores(id); err == nil { info.PeerScores = dat } + if md, err := eps.GetPeerMetadata(id); err == nil { + info.ENR = md.ENR + info.ChainID = md.OPStackID + } } if dat, err := pstore.Get(id, "ProtocolVersion"); err == nil { protocolVersion, ok := dat.(string) @@ -128,12 +133,6 @@ func dumpPeer(id peer.ID, nw network.Network, pstore peerstore.Peerstore, connMg info.UserAgent = agentVersion } } - if dat, err := pstore.Get(id, "ENR"); err == nil { - enodeData, ok := dat.(*enode.Node) - if ok { - info.ENR = enodeData.String() - } - } // include the /p2p/ address component in all of the addresses for convenience of the API user. p2pAddrs, err := peer.AddrInfoToP2pAddrs(&peer.AddrInfo{ID: id, Addrs: pstore.Addrs(id)}) if err == nil { @@ -152,12 +151,6 @@ func dumpPeer(id peer.ID, nw network.Network, pstore peerstore.Peerstore, connMg info.Direction = c.Stat().Direction break } - if dat, err := pstore.Get(id, "optimismChainID"); err == nil { - chID, ok := dat.(uint64) - if ok { - info.ChainID = chID - } - } info.Latency = pstore.LatencyEWMA(id) if connMgr != nil { info.Protected = connMgr.IsProtected(id, "") @@ -212,6 +205,7 @@ type PeerStats struct { Table uint `json:"table"` BlocksTopic uint `json:"blocksTopic"` BlocksTopicV2 uint `json:"blocksTopicV2"` + BlocksTopicV3 uint `json:"blocksTopicV3"` Banned uint `json:"banned"` Known uint `json:"known"` } @@ -228,6 +222,7 @@ func (s *APIBackend) PeerStats(_ context.Context) (*PeerStats, error) { Table: 0, BlocksTopic: uint(len(s.node.GossipOut().BlocksTopicV1Peers())), BlocksTopicV2: uint(len(s.node.GossipOut().BlocksTopicV2Peers())), + BlocksTopicV3: uint(len(s.node.GossipOut().BlocksTopicV3Peers())), Banned: 0, Known: uint(len(pstore.Peers())), } @@ -250,23 +245,31 @@ func (s *APIBackend) DiscoveryTable(_ context.Context) ([]*enode.Node, error) { } } -func (s *APIBackend) BlockPeer(_ context.Context, p peer.ID) error { +func (s *APIBackend) BlockPeer(_ context.Context, id peer.ID) error { recordDur := s.m.RecordRPCServerRequest("opp2p_blockPeer") + if err := id.Validate(); err != nil { + log.Warn("invalid peer ID", "method", "BlockPeer", "peer", id, "err", err) + return ErrInvalidRequest + } defer recordDur() if gater := s.node.ConnectionGater(); gater == nil { return ErrNoConnectionGater } else { - return gater.BlockPeer(p) + return gater.BlockPeer(id) } } -func (s *APIBackend) UnblockPeer(_ context.Context, p peer.ID) error { +func (s *APIBackend) UnblockPeer(_ context.Context, id peer.ID) error { recordDur := s.m.RecordRPCServerRequest("opp2p_unblockPeer") + if err := id.Validate(); err != nil { + log.Warn("invalid peer ID", "method", "UnblockPeer", "peer", id, "err", err) + return ErrInvalidRequest + } defer recordDur() if gater := s.node.ConnectionGater(); gater == nil { return ErrNoConnectionGater } else { - return gater.UnblockPeer(p) + return gater.UnblockPeer(id) } } @@ -284,6 +287,10 @@ func (s *APIBackend) ListBlockedPeers(_ context.Context) ([]peer.ID, error) { // Note: active connections to the IP address are not automatically closed. func (s *APIBackend) BlockAddr(_ context.Context, ip net.IP) error { recordDur := s.m.RecordRPCServerRequest("opp2p_blockAddr") + if ip == nil { + log.Warn("invalid IP", "method", "BlockAddr") + return ErrInvalidRequest + } defer recordDur() if gater := s.node.ConnectionGater(); gater == nil { return ErrNoConnectionGater @@ -294,6 +301,10 @@ func (s *APIBackend) BlockAddr(_ context.Context, ip net.IP) error { func (s *APIBackend) UnblockAddr(_ context.Context, ip net.IP) error { recordDur := s.m.RecordRPCServerRequest("opp2p_unblockAddr") + if ip == nil { + log.Warn("invalid IP", "method", "UnblockAddr") + return ErrInvalidRequest + } defer recordDur() if gater := s.node.ConnectionGater(); gater == nil { return ErrNoConnectionGater @@ -316,6 +327,10 @@ func (s *APIBackend) ListBlockedAddrs(_ context.Context) ([]net.IP, error) { // Note: active connections to the IP subnet are not automatically closed. func (s *APIBackend) BlockSubnet(_ context.Context, ipnet *net.IPNet) error { recordDur := s.m.RecordRPCServerRequest("opp2p_blockSubnet") + if ipnet == nil { + log.Warn("invalid IPNet", "method", "BlockSubnet") + return ErrInvalidRequest + } defer recordDur() if gater := s.node.ConnectionGater(); gater == nil { return ErrNoConnectionGater @@ -326,6 +341,10 @@ func (s *APIBackend) BlockSubnet(_ context.Context, ipnet *net.IPNet) error { func (s *APIBackend) UnblockSubnet(_ context.Context, ipnet *net.IPNet) error { recordDur := s.m.RecordRPCServerRequest("opp2p_unblockSubnet") + if ipnet == nil { + log.Warn("invalid IPNet", "method", "UnblockSubnet") + return ErrInvalidRequest + } defer recordDur() if gater := s.node.ConnectionGater(); gater == nil { return ErrNoConnectionGater @@ -344,24 +363,32 @@ func (s *APIBackend) ListBlockedSubnets(_ context.Context) ([]*net.IPNet, error) } } -func (s *APIBackend) ProtectPeer(_ context.Context, p peer.ID) error { +func (s *APIBackend) ProtectPeer(_ context.Context, id peer.ID) error { recordDur := s.m.RecordRPCServerRequest("opp2p_protectPeer") + if err := id.Validate(); err != nil { + log.Warn("invalid peer ID", "method", "ProtectPeer", "peer", id, "err", err) + return ErrInvalidRequest + } defer recordDur() if manager := s.node.ConnectionManager(); manager == nil { return ErrNoConnectionManager } else { - manager.Protect(p, "api-protected") + manager.Protect(id, "api-protected") return nil } } -func (s *APIBackend) UnprotectPeer(_ context.Context, p peer.ID) error { +func (s *APIBackend) UnprotectPeer(_ context.Context, id peer.ID) error { recordDur := s.m.RecordRPCServerRequest("opp2p_unprotectPeer") + if err := id.Validate(); err != nil { + log.Warn("invalid peer ID", "method", "UnprotectPeer", "peer", id, "err", err) + return ErrInvalidRequest + } defer recordDur() if manager := s.node.ConnectionManager(); manager == nil { return ErrNoConnectionManager } else { - manager.Unprotect(p, "api-protected") + manager.Unprotect(id, "api-protected") return nil } } @@ -383,6 +410,21 @@ func (s *APIBackend) ConnectPeer(ctx context.Context, addr string) error { func (s *APIBackend) DisconnectPeer(_ context.Context, id peer.ID) error { recordDur := s.m.RecordRPCServerRequest("opp2p_disconnectPeer") + if err := id.Validate(); err != nil { + log.Warn("invalid peer ID", "method", "DisconnectPeer", "peer", id, "err", err) + return ErrInvalidRequest + } defer recordDur() - return s.node.Host().Network().ClosePeer(id) + err := s.node.Host().Network().ClosePeer(id) + if err != nil { + return err + } + ps := s.node.Host().Peerstore() + ps.RemovePeer(id) + ps.ClearAddrs(id) + err = s.node.ConnectionGater().UnblockPeer(id) + if err != nil { + return fmt.Errorf("closed peer but failed to unblock: %w", err) + } + return nil } diff --git a/op-node/p2p/store/extended.go b/op-node/p2p/store/extended.go index 89e3be8581bd..d861ec7c20da 100644 --- a/op-node/p2p/store/extended.go +++ b/op-node/p2p/store/extended.go @@ -18,6 +18,7 @@ type extendedStore struct { *scoreBook *peerBanBook *ipBanBook + *metadataBook } func NewExtendedPeerstore(ctx context.Context, logger log.Logger, clock clock.Clock, ps peerstore.Peerstore, store ds.Batching, scoreRetention time.Duration) (ExtendedPeerstore, error) { @@ -40,17 +41,26 @@ func NewExtendedPeerstore(ctx context.Context, logger log.Logger, clock clock.Cl return nil, fmt.Errorf("create IP ban book: %w", err) } ib.startGC() + md, err := newMetadataBook(ctx, logger, clock, store) + if err != nil { + return nil, fmt.Errorf("create metadata book: %w", err) + } + md.startGC() return &extendedStore{ Peerstore: ps, CertifiedAddrBook: cab, scoreBook: sb, peerBanBook: pb, ipBanBook: ib, + metadataBook: md, }, nil } func (s *extendedStore) Close() error { s.scoreBook.Close() + s.peerBanBook.Close() + s.ipBanBook.Close() + s.metadataBook.Close() return s.Peerstore.Close() } diff --git a/op-node/p2p/store/gc_test.go b/op-node/p2p/store/gc_test.go index 68d8023b1bd5..650b5bb3cb4b 100644 --- a/op-node/p2p/store/gc_test.go +++ b/op-node/p2p/store/gc_test.go @@ -20,7 +20,7 @@ func TestScheduleGcPeriodically(t *testing.T) { // Wait for the gc background process to complete after cancelling the context bgTasks.Wait() }() - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) clock := clock.NewDeterministicClock(time.UnixMilli(5000)) called := make(chan struct{}, 10) diff --git a/op-node/p2p/store/iface.go b/op-node/p2p/store/iface.go index 4df44dbe2772..5961481bf28a 100644 --- a/op-node/p2p/store/iface.go +++ b/op-node/p2p/store/iface.go @@ -120,6 +120,13 @@ type IPBanStore interface { GetIPBanExpiration(ip net.IP) (time.Time, error) } +type MetadataStore interface { + // SetPeerMetadata sets the metadata for the specified peer + SetPeerMetadata(id peer.ID, md PeerMetadata) (PeerMetadata, error) + // GetPeerMetadata returns the metadata for the specified peer + GetPeerMetadata(id peer.ID) (PeerMetadata, error) +} + // ExtendedPeerstore defines a type-safe API to work with additional peer metadata based on a libp2p peerstore.Peerstore type ExtendedPeerstore interface { peerstore.Peerstore @@ -127,4 +134,5 @@ type ExtendedPeerstore interface { peerstore.CertifiedAddrBook PeerBanStore IPBanStore + MetadataStore } diff --git a/op-node/p2p/store/ip_ban_book_test.go b/op-node/p2p/store/ip_ban_book_test.go index 34bf37618258..24d3574e0c93 100644 --- a/op-node/p2p/store/ip_ban_book_test.go +++ b/op-node/p2p/store/ip_ban_book_test.go @@ -35,7 +35,7 @@ func TestRoundTripIPBan(t *testing.T) { func createMemoryIPBanBook(t *testing.T) *ipBanBook { store := sync.MutexWrap(ds.NewMapDatastore()) - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) c := clock.NewDeterministicClock(time.UnixMilli(100)) book, err := newIPBanBook(context.Background(), logger, c, store) require.NoError(t, err) diff --git a/op-node/p2p/store/mdbook.go b/op-node/p2p/store/mdbook.go new file mode 100644 index 000000000000..6c1362674956 --- /dev/null +++ b/op-node/p2p/store/mdbook.go @@ -0,0 +1,98 @@ +package store + +import ( + "context" + "encoding/json" + "sync/atomic" + "time" + + "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/ethereum/go-ethereum/log" + ds "github.com/ipfs/go-datastore" + "github.com/libp2p/go-libp2p/core/peer" +) + +const ( + mdCacheSize = 100 + mdRecordExpiration = time.Hour * 24 * 7 +) + +var metadataBase = ds.NewKey("/peers/md") + +// LastUpdate requires atomic update operations. Use the helper functions SetLastUpdated and LastUpdated to modify and access this field. +type metadataRecord struct { + LastUpdate int64 `json:"lastUpdate"` // unix timestamp in seconds + PeerMetadata PeerMetadata `json:"peerMetadata"` +} + +type PeerMetadata struct { + ENR string `json:"enr"` + OPStackID uint64 `json:"opStackID"` +} + +func (m *metadataRecord) SetLastUpdated(t time.Time) { + atomic.StoreInt64(&m.LastUpdate, t.Unix()) +} + +func (m *metadataRecord) LastUpdated() time.Time { + return time.Unix(atomic.LoadInt64(&m.LastUpdate), 0) +} + +func (m *metadataRecord) MarshalBinary() (data []byte, err error) { + return json.Marshal(m) +} + +func (m *metadataRecord) UnmarshalBinary(data []byte) error { + return json.Unmarshal(data, m) +} + +type metadataBook struct { + book *recordsBook[peer.ID, *metadataRecord] +} + +func newMetadataRecord() *metadataRecord { + return new(metadataRecord) +} + +func newMetadataBook(ctx context.Context, logger log.Logger, clock clock.Clock, store ds.Batching) (*metadataBook, error) { + book, err := newRecordsBook[peer.ID, *metadataRecord](ctx, logger, clock, store, mdCacheSize, mdRecordExpiration, metadataBase, newMetadataRecord, peerIDKey) + if err != nil { + return nil, err + } + return &metadataBook{book: book}, nil +} + +func (m *metadataBook) startGC() { + m.book.startGC() +} + +func (m *metadataBook) GetPeerMetadata(id peer.ID) (PeerMetadata, error) { + record, err := m.book.getRecord(id) + // If the record is not found, return an empty PeerMetadata + if err == UnknownRecordErr { + return PeerMetadata{}, nil + } + if err != nil { + return PeerMetadata{}, err + } + return record.PeerMetadata, nil +} + +// Apply simply overwrites the record with the new one. +// presently, metadata is only collected during peering, so this is fine. +// if in the future this data can be updated or expanded, this function will need to be updated. +func (md *metadataRecord) Apply(rec *metadataRecord) { + *rec = *md +} + +func (m *metadataBook) SetPeerMetadata(id peer.ID, md PeerMetadata) (PeerMetadata, error) { + rec := newMetadataRecord() + rec.PeerMetadata = md + rec.SetLastUpdated(m.book.clock.Now()) + v, err := m.book.SetRecord(id, rec) + return v.PeerMetadata, err +} + +func (m *metadataBook) Close() { + m.book.Close() +} diff --git a/op-node/p2p/store/peer_ban_book_test.go b/op-node/p2p/store/peer_ban_book_test.go index a9d0ce6c28b2..580dea3a3e8e 100644 --- a/op-node/p2p/store/peer_ban_book_test.go +++ b/op-node/p2p/store/peer_ban_book_test.go @@ -33,7 +33,7 @@ func TestRoundTripPeerBan(t *testing.T) { func createMemoryPeerBanBook(t *testing.T) *peerBanBook { store := sync.MutexWrap(ds.NewMapDatastore()) - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) c := clock.NewDeterministicClock(time.UnixMilli(100)) book, err := newPeerBanBook(context.Background(), logger, c, store) require.NoError(t, err) diff --git a/op-node/p2p/store/records_book.go b/op-node/p2p/store/records_book.go index 67bb4706591a..9afac37abfbb 100644 --- a/op-node/p2p/store/records_book.go +++ b/op-node/p2p/store/records_book.go @@ -94,7 +94,7 @@ func (d *recordsBook[K, V]) dsKey(key K) ds.Key { func (d *recordsBook[K, V]) deleteRecord(key K) error { d.cache.Remove(key) err := d.store.Delete(d.ctx, d.dsKey(key)) - if errors.Is(err, ds.ErrNotFound) { + if err == nil || errors.Is(err, ds.ErrNotFound) { return nil } return fmt.Errorf("failed to delete entry with key %v: %w", key, err) diff --git a/op-node/p2p/store/scorebook_test.go b/op-node/p2p/store/scorebook_test.go index 2ff398df9edf..29fa7a2fe303 100644 --- a/op-node/p2p/store/scorebook_test.go +++ b/op-node/p2p/store/scorebook_test.go @@ -165,7 +165,7 @@ func TestCloseCompletes(t *testing.T) { func TestPrune(t *testing.T) { ctx, cancelFunc := context.WithCancel(context.Background()) defer cancelFunc() - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) store := sync.MutexWrap(ds.NewMapDatastore()) clock := clock.NewDeterministicClock(time.UnixMilli(1000)) book, err := newScoreBook(ctx, logger, clock, store, 24*time.Hour) @@ -220,7 +220,7 @@ func TestPrune(t *testing.T) { func TestPruneMultipleBatches(t *testing.T) { ctx, cancelFunc := context.WithCancel(context.Background()) defer cancelFunc() - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) clock := clock.NewDeterministicClock(time.UnixMilli(1000)) book, err := newScoreBook(ctx, logger, clock, sync.MutexWrap(ds.NewMapDatastore()), 24*time.Hour) require.NoError(t, err) @@ -250,7 +250,7 @@ func TestPruneMultipleBatches(t *testing.T) { func TestIgnoreOutdatedScores(t *testing.T) { ctx, cancelFunc := context.WithCancel(context.Background()) defer cancelFunc() - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) clock := clock.NewDeterministicClock(time.UnixMilli(1000)) retentionPeriod := 24 * time.Hour book, err := newScoreBook(ctx, logger, clock, sync.MutexWrap(ds.NewMapDatastore()), retentionPeriod) @@ -289,7 +289,7 @@ func createMemoryStore(t *testing.T) ExtendedPeerstore { func createPeerstoreWithBacking(t *testing.T, store *sync.MutexDatastore) ExtendedPeerstore { ps, err := pstoreds.NewPeerstore(context.Background(), store, pstoreds.DefaultOpts()) require.NoError(t, err, "Failed to create peerstore") - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) c := clock.NewDeterministicClock(time.UnixMilli(100)) eps, err := NewExtendedPeerstore(context.Background(), logger, c, ps, store, 24*time.Hour) require.NoError(t, err) diff --git a/op-node/p2p/sync.go b/op-node/p2p/sync.go index 1318e03fcdad..5479101a4e86 100644 --- a/op-node/p2p/sync.go +++ b/op-node/p2p/sync.go @@ -82,7 +82,7 @@ func MakeStreamHandler(resourcesCtx context.Context, log log.Logger, fn requestH type newStreamFn func(ctx context.Context, peerId peer.ID, protocolId ...protocol.ID) (network.Stream, error) -type receivePayloadFn func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) error +type receivePayloadFn func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) error type rangeRequest struct { start uint64 @@ -90,7 +90,7 @@ type rangeRequest struct { } type syncResult struct { - payload *eth.ExecutionPayload + payload *eth.ExecutionPayloadEnvelope peer peer.ID } @@ -428,14 +428,14 @@ func (s *SyncClient) onRangeRequest(ctx context.Context, req rangeRequest) { } func (s *SyncClient) onQuarantineEvict(key common.Hash, value syncResult) { - delete(s.quarantineByNum, uint64(value.payload.BlockNumber)) + delete(s.quarantineByNum, uint64(value.payload.ExecutionPayload.BlockNumber)) s.metrics.PayloadsQuarantineSize(s.quarantine.Len()) if !s.trusted.Contains(key) { - s.log.Debug("evicting untrusted payload from quarantine", "id", value.payload.ID(), "peer", value.peer) + s.log.Debug("evicting untrusted payload from quarantine", "id", value.payload.ExecutionPayload.ID(), "peer", value.peer) // Down-score peer for having provided us a bad block that never turned out to be canonical s.appScorer.onRejectedPayload(value.peer) } else { - s.log.Debug("evicting trusted payload from quarantine", "id", value.payload.ID(), "peer", value.peer) + s.log.Debug("evicting trusted payload from quarantine", "id", value.payload.ExecutionPayload.ID(), "peer", value.peer) } } @@ -455,27 +455,28 @@ func (s *SyncClient) tryPromote(h common.Hash) { } func (s *SyncClient) promote(ctx context.Context, res syncResult) { - s.log.Debug("promoting p2p sync result", "payload", res.payload.ID(), "peer", res.peer) + s.log.Debug("promoting p2p sync result", "payload", res.payload.ExecutionPayload.ID(), "peer", res.peer) + if err := s.receivePayload(ctx, res.peer, res.payload); err != nil { s.log.Warn("failed to promote payload, receiver error", "err", err) return } - s.trusted.Add(res.payload.BlockHash, struct{}{}) - if s.quarantine.Remove(res.payload.BlockHash) { - s.log.Debug("promoted previously p2p-synced block from quarantine to main", "id", res.payload.ID()) + s.trusted.Add(res.payload.ExecutionPayload.BlockHash, struct{}{}) + if s.quarantine.Remove(res.payload.ExecutionPayload.BlockHash) { + s.log.Debug("promoted previously p2p-synced block from quarantine to main", "id", res.payload.ExecutionPayload.ID()) } else { - s.log.Debug("promoted new p2p-synced block to main", "id", res.payload.ID()) + s.log.Debug("promoted new p2p-synced block to main", "id", res.payload.ExecutionPayload.ID()) } // Mark parent block as trusted, so that we can promote it once we receive it / find it - s.trusted.Add(res.payload.ParentHash, struct{}{}) + s.trusted.Add(res.payload.ExecutionPayload.ParentHash, struct{}{}) // Try to promote the parent block too, if any: previous unverifiable data may now be canonical - s.tryPromote(res.payload.ParentHash) + s.tryPromote(res.payload.ExecutionPayload.ParentHash) // In case we don't have the parent, and what we have in quarantine is wrong, // clear what we buffered in favor of fetching something else. - if h, ok := s.quarantineByNum[uint64(res.payload.BlockNumber)-1]; ok { + if h, ok := s.quarantineByNum[uint64(res.payload.ExecutionPayload.BlockNumber)-1]; ok { s.quarantine.Remove(h) } } @@ -483,15 +484,16 @@ func (s *SyncClient) promote(ctx context.Context, res syncResult) { // onResult is exclusively called by the main loop, and has thus direct access to the request bookkeeping state. // This function verifies if the result is canonical, and either promotes the result or moves the result into quarantine. func (s *SyncClient) onResult(ctx context.Context, res syncResult) { - s.log.Debug("processing p2p sync result", "payload", res.payload.ID(), "peer", res.peer) + payload := res.payload.ExecutionPayload + s.log.Debug("processing p2p sync result", "payload", payload.ID(), "peer", res.peer) // Clean up the in-flight request, we have a result now. - delete(s.inFlight, uint64(res.payload.BlockNumber)) + delete(s.inFlight, uint64(payload.BlockNumber)) // Always put it in quarantine first. If promotion fails because the receiver is too busy, this functions as cache. - s.quarantine.Add(res.payload.BlockHash, res) - s.quarantineByNum[uint64(res.payload.BlockNumber)] = res.payload.BlockHash + s.quarantine.Add(payload.BlockHash, res) + s.quarantineByNum[uint64(payload.BlockNumber)] = payload.BlockHash s.metrics.PayloadsQuarantineSize(s.quarantine.Len()) // If we know this block is canonical, then promote it - if s.trusted.Contains(res.payload.BlockHash) { + if s.trusted.Contains(payload.BlockHash) { s.promote(ctx, res) } } @@ -608,8 +610,8 @@ func (s *SyncClient) doRequest(ctx context.Context, id peer.ID, expectedBlockNum return fmt.Errorf("failed to read version part of response: %w", err) } version := binary.LittleEndian.Uint32(versionData[:]) - if version != 0 { - return fmt.Errorf("unrecognized ExecutionPayload version: %d", version) + if version != 0 && version != 1 { + return fmt.Errorf("unrecognized version: %d", version) } // payload is SSZ encoded with Snappy framed compression r = snappy.NewReader(r) @@ -621,37 +623,58 @@ func (s *SyncClient) doRequest(ctx context.Context, id peer.ID, expectedBlockNum return fmt.Errorf("failed to read response: %w", err) } - expectedBlockTime := s.cfg.TimestampForBlock(expectedBlockNum) + envelope := ð.ExecutionPayloadEnvelope{} - blockVersion := eth.BlockV1 - if s.cfg.IsCanyon(expectedBlockTime) { - blockVersion = eth.BlockV2 - } - var res eth.ExecutionPayload - if err := res.UnmarshalSSZ(blockVersion, uint32(len(data)), bytes.NewReader(data)); err != nil { - return fmt.Errorf("failed to decode response: %w", err) + if version == 0 { + expectedBlockTime := s.cfg.TimestampForBlock(expectedBlockNum) + envelope, err = s.readExecutionPayload(data, expectedBlockTime) + if err != nil { + return err + } + } else if version == 1 { + if err := envelope.UnmarshalSSZ(uint32(len(data)), bytes.NewReader(data)); err != nil { + return fmt.Errorf("failed to decode execution payload envelope response: %w", err) + } + } else { + panic(fmt.Errorf("should have already filtered by version, but got: %d", version)) } if err := str.CloseRead(); err != nil { return fmt.Errorf("failed to close reading side") } - if err := verifyBlock(&res, expectedBlockNum); err != nil { + if err := verifyBlock(envelope, expectedBlockNum); err != nil { return fmt.Errorf("received execution payload is invalid: %w", err) } select { - case s.results <- syncResult{payload: &res, peer: id}: + case s.results <- syncResult{payload: envelope, peer: id}: case <-ctx.Done(): return fmt.Errorf("failed to process response, sync client is too busy: %w", err) } return nil } -func verifyBlock(payload *eth.ExecutionPayload, expectedNum uint64) error { +func (s *SyncClient) readExecutionPayload(data []byte, expectedTime uint64) (*eth.ExecutionPayloadEnvelope, error) { + blockVersion := eth.BlockV1 + if s.cfg.IsCanyon(expectedTime) { + blockVersion = eth.BlockV2 + } + + var res eth.ExecutionPayload + if err := res.UnmarshalSSZ(blockVersion, uint32(len(data)), bytes.NewReader(data)); err != nil { + return nil, fmt.Errorf("failed to decode response: %w", err) + } + + return ð.ExecutionPayloadEnvelope{ExecutionPayload: &res}, nil +} + +func verifyBlock(envelope *eth.ExecutionPayloadEnvelope, expectedNum uint64) error { + payload := envelope.ExecutionPayload + // verify L2 block if expectedNum != uint64(payload.BlockNumber) { return fmt.Errorf("received execution payload for block %d, but expected block %d", payload.BlockNumber, expectedNum) } - actual, ok := payload.CheckBlockHash() + actual, ok := envelope.CheckBlockHash() if !ok { // payload itself contains bad block hash return fmt.Errorf("received execution payload for block %d with bad block hash %s, expected %s", expectedNum, payload.BlockHash, actual) } @@ -665,7 +688,7 @@ type peerStat struct { } type L2Chain interface { - PayloadByNumber(ctx context.Context, number uint64) (*eth.ExecutionPayload, error) + PayloadByNumber(ctx context.Context, number uint64) (*eth.ExecutionPayloadEnvelope, error) } type ReqRespServerMetrics interface { @@ -791,7 +814,7 @@ func (srv *ReqRespServer) handleSyncRequest(ctx context.Context, stream network. return req, fmt.Errorf("cannot serve request for L2 block %d after max expected block (%v): %w", req, max, invalidRequestErr) } - payload, err := srv.l2.PayloadByNumber(ctx, req) + envelope, err := srv.l2.PayloadByNumber(ctx, req) if err != nil { if errors.Is(err, ethereum.NotFound) { return req, fmt.Errorf("peer requested unknown block by number: %w", err) @@ -803,18 +826,33 @@ func (srv *ReqRespServer) handleSyncRequest(ctx context.Context, stream network. // We set write deadline, if available, to safely write without blocking on a throttling peer connection _ = stream.SetWriteDeadline(time.Now().Add(serverWriteChunkTimeout)) - // 0 - resultCode: success = 0 - // 1:5 - version: 0 - var tmp [5]byte - if _, err := stream.Write(tmp[:]); err != nil { - return req, fmt.Errorf("failed to write response header data: %w", err) - } w := snappy.NewBufferedWriter(stream) - if _, err := payload.MarshalSSZ(w); err != nil { - return req, fmt.Errorf("failed to write payload to sync response: %w", err) + + if srv.cfg.IsEcotone(uint64(envelope.ExecutionPayload.Timestamp)) { + // 0 - resultCode: success = 0 + // 1:5 - version: 1 (little endian) + tmp := [5]byte{0, 1, 0, 0, 0} + if _, err := stream.Write(tmp[:]); err != nil { + return req, fmt.Errorf("failed to write response header data: %w", err) + } + if _, err := envelope.MarshalSSZ(w); err != nil { + return req, fmt.Errorf("failed to write payload to sync response: %w", err) + } + } else { + // 0 - resultCode: success = 0 + // 1:5 - version: 0 + var tmp [5]byte + if _, err := stream.Write(tmp[:]); err != nil { + return req, fmt.Errorf("failed to write response header data: %w", err) + } + if _, err := envelope.ExecutionPayload.MarshalSSZ(w); err != nil { + return req, fmt.Errorf("failed to write payload to sync response: %w", err) + } } + if err := w.Close(); err != nil { return req, fmt.Errorf("failed to finishing writing payload to sync response: %w", err) } + return req, nil } diff --git a/op-node/p2p/sync_test.go b/op-node/p2p/sync_test.go index 4144629e41cb..0c43778ce8f0 100644 --- a/op-node/p2p/sync_test.go +++ b/op-node/p2p/sync_test.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-node/metrics" @@ -23,9 +24,9 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -type mockPayloadFn func(n uint64) (*eth.ExecutionPayload, error) +type mockPayloadFn func(n uint64) (*eth.ExecutionPayloadEnvelope, error) -func (fn mockPayloadFn) PayloadByNumber(_ context.Context, number uint64) (*eth.ExecutionPayload, error) { +func (fn mockPayloadFn) PayloadByNumber(_ context.Context, number uint64) (*eth.ExecutionPayloadEnvelope, error) { return fn(number) } @@ -33,10 +34,10 @@ var _ L2Chain = mockPayloadFn(nil) type syncTestData struct { sync.RWMutex - payloads map[uint64]*eth.ExecutionPayload + payloads map[uint64]*eth.ExecutionPayloadEnvelope } -func (s *syncTestData) getPayload(i uint64) (payload *eth.ExecutionPayload, ok bool) { +func (s *syncTestData) getPayload(i uint64) (payload *eth.ExecutionPayloadEnvelope, ok bool) { s.RLock() defer s.RUnlock() payload, ok = s.payloads[i] @@ -49,20 +50,20 @@ func (s *syncTestData) deletePayload(i uint64) { delete(s.payloads, i) } -func (s *syncTestData) addPayload(payload *eth.ExecutionPayload) { +func (s *syncTestData) addPayload(payload *eth.ExecutionPayloadEnvelope) { s.Lock() defer s.Unlock() - s.payloads[uint64(payload.BlockNumber)] = payload + s.payloads[uint64(payload.ExecutionPayload.BlockNumber)] = payload } func (s *syncTestData) getBlockRef(i uint64) eth.L2BlockRef { s.RLock() defer s.RUnlock() return eth.L2BlockRef{ - Hash: s.payloads[i].BlockHash, - Number: uint64(s.payloads[i].BlockNumber), - ParentHash: s.payloads[i].ParentHash, - Time: uint64(s.payloads[i].Timestamp), + Hash: s.payloads[i].ExecutionPayload.BlockHash, + Number: uint64(s.payloads[i].ExecutionPayload.BlockNumber), + ParentHash: s.payloads[i].ExecutionPayload.ParentHash, + Time: uint64(s.payloads[i].ExecutionPayload.Timestamp), } } @@ -78,19 +79,42 @@ func setupSyncTestData(length uint64) (*rollup.Config, *syncTestData) { L2ChainID: big.NewInt(1234), } + ecotoneBlock := length / 2 + ecotoneTime := cfg.Genesis.L2Time + ecotoneBlock*cfg.BlockTime + cfg.EcotoneTime = &ecotoneTime + // create some simple fake test blocks - payloads := make(map[uint64]*eth.ExecutionPayload) - payloads[0] = ð.ExecutionPayload{ - Timestamp: eth.Uint64Quantity(cfg.Genesis.L2Time), + payloads := make(map[uint64]*eth.ExecutionPayloadEnvelope) + payloads[0] = ð.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + Timestamp: eth.Uint64Quantity(cfg.Genesis.L2Time), + }, } - payloads[0].BlockHash, _ = payloads[0].CheckBlockHash() + + payloads[0].ExecutionPayload.BlockHash, _ = payloads[0].CheckBlockHash() for i := uint64(1); i <= length; i++ { - payload := ð.ExecutionPayload{ - ParentHash: payloads[i-1].BlockHash, - BlockNumber: eth.Uint64Quantity(i), - Timestamp: eth.Uint64Quantity(cfg.Genesis.L2Time + i*cfg.BlockTime), + timestamp := cfg.Genesis.L2Time + i*cfg.BlockTime + payload := ð.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + ParentHash: payloads[i-1].ExecutionPayload.BlockHash, + BlockNumber: eth.Uint64Quantity(i), + Timestamp: eth.Uint64Quantity(timestamp), + }, + } + + if cfg.IsEcotone(timestamp) { + hash := common.BigToHash(big.NewInt(int64(i))) + payload.ParentBeaconBlockRoot = &hash + + zero := eth.Uint64Quantity(0) + payload.ExecutionPayload.ExcessBlobGas = &zero + payload.ExecutionPayload.BlobGasUsed = &zero + + w := types.Withdrawals{} + payload.ExecutionPayload.Withdrawals = &w } - payload.BlockHash, _ = payload.CheckBlockHash() + + payload.ExecutionPayload.BlockHash, _ = payload.CheckBlockHash() payloads[i] = payload } @@ -100,12 +124,12 @@ func setupSyncTestData(length uint64) (*rollup.Config, *syncTestData) { func TestSinglePeerSync(t *testing.T) { t.Parallel() // Takes a while, but can run in parallel - log := testlog.Logger(t, log.LvlError) + log := testlog.Logger(t, log.LevelError) cfg, payloads := setupSyncTestData(25) // Serving payloads: just load them from the map, if they exist - servePayload := mockPayloadFn(func(n uint64) (*eth.ExecutionPayload, error) { + servePayload := mockPayloadFn(func(n uint64) (*eth.ExecutionPayloadEnvelope, error) { p, ok := payloads.getPayload(n) if !ok { return nil, ethereum.NotFound @@ -114,8 +138,8 @@ func TestSinglePeerSync(t *testing.T) { }) // collect received payloads in a buffered channel, so we can verify we get everything - received := make(chan *eth.ExecutionPayload, 100) - receivePayload := receivePayloadFn(func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) error { + received := make(chan *eth.ExecutionPayloadEnvelope, 100) + receivePayload := receivePayloadFn(func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) error { received <- payload return nil }) @@ -150,26 +174,33 @@ func TestSinglePeerSync(t *testing.T) { // and wait for the sync results to come in (in reverse order) for i := uint64(19); i > 10; i-- { p := <-received - require.Equal(t, uint64(p.BlockNumber), i, "expecting payloads in order") - exp, ok := payloads.getPayload(uint64(p.BlockNumber)) + require.Equal(t, uint64(p.ExecutionPayload.BlockNumber), i, "expecting payloads in order") + exp, ok := payloads.getPayload(uint64(p.ExecutionPayload.BlockNumber)) require.True(t, ok, "expecting known payload") - require.Equal(t, exp.BlockHash, p.BlockHash, "expecting the correct payload") + require.Equal(t, exp.ExecutionPayload.BlockHash, p.ExecutionPayload.BlockHash, "expecting the correct payload") + + require.Equal(t, exp.ParentBeaconBlockRoot, p.ParentBeaconBlockRoot) + if cfg.IsEcotone(uint64(p.ExecutionPayload.Timestamp)) { + require.NotNil(t, p.ParentBeaconBlockRoot) + } else { + require.Nil(t, p.ParentBeaconBlockRoot) + } } } func TestMultiPeerSync(t *testing.T) { t.Parallel() // Takes a while, but can run in parallel - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) cfg, payloads := setupSyncTestData(100) // Buffered channel of all blocks requested from any client. requested := make(chan uint64, 100) - setupPeer := func(ctx context.Context, h host.Host) (*SyncClient, chan *eth.ExecutionPayload) { + setupPeer := func(ctx context.Context, h host.Host) (*SyncClient, chan *eth.ExecutionPayloadEnvelope) { // Serving payloads: just load them from the map, if they exist - servePayload := mockPayloadFn(func(n uint64) (*eth.ExecutionPayload, error) { + servePayload := mockPayloadFn(func(n uint64) (*eth.ExecutionPayloadEnvelope, error) { requested <- n p, ok := payloads.getPayload(n) if !ok { @@ -179,8 +210,8 @@ func TestMultiPeerSync(t *testing.T) { }) // collect received payloads in a buffered channel, so we can verify we get everything - received := make(chan *eth.ExecutionPayload, 100) - receivePayload := receivePayloadFn(func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) error { + received := make(chan *eth.ExecutionPayloadEnvelope, 100) + receivePayload := receivePayloadFn(func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) error { received <- payload return nil }) @@ -229,10 +260,11 @@ func TestMultiPeerSync(t *testing.T) { // With such large range to request we are going to hit the rate-limits of B and C, // but that means we'll balance the work between the peers. for i := uint64(89); i > 10; i-- { // wait for all payloads - p := <-recvA + e := <-recvA + p := e.ExecutionPayload exp, ok := payloads.getPayload(uint64(p.BlockNumber)) require.True(t, ok, "expecting known payload") - require.Equal(t, exp.BlockHash, p.BlockHash, "expecting the correct payload") + require.Equal(t, exp.ExecutionPayload.BlockHash, p.BlockHash, "expecting the correct payload") } // now see if B can sync a range, and fill the gap with a re-request @@ -241,9 +273,9 @@ func TestMultiPeerSync(t *testing.T) { require.NoError(t, clB.RequestL2Range(ctx, payloads.getBlockRef(20), payloads.getBlockRef(30))) for i := uint64(29); i > 25; i-- { p := <-recvB - exp, ok := payloads.getPayload(uint64(p.BlockNumber)) + exp, ok := payloads.getPayload(uint64(p.ExecutionPayload.BlockNumber)) require.True(t, ok, "expecting known payload") - require.Equal(t, exp.BlockHash, p.BlockHash, "expecting the correct payload") + require.Equal(t, exp.ExecutionPayload.BlockHash, p.ExecutionPayload.BlockHash, "expecting the correct payload") } // Wait for the request for block 25 to be made ctx, cancelFunc := context.WithTimeout(context.Background(), 30*time.Second) @@ -283,15 +315,21 @@ func TestMultiPeerSync(t *testing.T) { require.NoError(t, clB.RequestL2Range(ctx, payloads.getBlockRef(20), payloads.getBlockRef(26))) for i := uint64(25); i > 20; i-- { p := <-recvB - exp, ok := payloads.getPayload(uint64(p.BlockNumber)) + exp, ok := payloads.getPayload(uint64(p.ExecutionPayload.BlockNumber)) require.True(t, ok, "expecting known payload") - require.Equal(t, exp.BlockHash, p.BlockHash, "expecting the correct payload") + require.Equal(t, exp.ExecutionPayload.BlockHash, p.ExecutionPayload.BlockHash, "expecting the correct payload") + require.Equal(t, exp.ParentBeaconBlockRoot, p.ParentBeaconBlockRoot) + if cfg.IsEcotone(uint64(p.ExecutionPayload.Timestamp)) { + require.NotNil(t, p.ParentBeaconBlockRoot) + } else { + require.Nil(t, p.ParentBeaconBlockRoot) + } } } func TestNetworkNotifyAddPeerAndRemovePeer(t *testing.T) { t.Parallel() - log := testlog.Logger(t, log.LvlDebug) + log := testlog.Logger(t, log.LevelDebug) cfg, _ := setupSyncTestData(25) @@ -304,7 +342,7 @@ func TestNetworkNotifyAddPeerAndRemovePeer(t *testing.T) { require.NoError(t, err, "failed to launch host B") defer hostB.Close() - syncCl := NewSyncClient(log, cfg, hostA.NewStream, func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) error { + syncCl := NewSyncClient(log, cfg, hostA.NewStream, func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayloadEnvelope) error { return nil }, metrics.NoopMetrics, &NoopApplicationScorer{}) @@ -340,5 +378,4 @@ func TestNetworkNotifyAddPeerAndRemovePeer(t *testing.T) { <-waitChan _, peerBExist3 := syncCl.peers[hostB.ID()] require.True(t, !peerBExist3, "peerB should not exist in syncClient") - } diff --git a/op-node/rollup/async/asyncgossiper.go b/op-node/rollup/async/asyncgossiper.go new file mode 100644 index 000000000000..34ca8ea5659d --- /dev/null +++ b/op-node/rollup/async/asyncgossiper.go @@ -0,0 +1,161 @@ +package async + +import ( + "context" + "sync/atomic" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type AsyncGossiper interface { + Gossip(payload *eth.ExecutionPayloadEnvelope) + Get() *eth.ExecutionPayloadEnvelope + Clear() + Stop() + Start() +} + +// SimpleAsyncGossiper is a component that stores and gossips a single payload at a time +// it uses a separate goroutine to handle gossiping the payload asynchronously +// the payload can be accessed by the Get function to be reused when the payload was gossiped but not inserted +// exposed functions are synchronous, and block until the async routine is able to start handling the request +type SimpleAsyncGossiper struct { + running atomic.Bool + // channel to add new payloads to gossip + set chan *eth.ExecutionPayloadEnvelope + // channel to request getting the currently gossiping payload + get chan chan *eth.ExecutionPayloadEnvelope + // channel to request clearing the currently gossiping payload + clear chan struct{} + // channel to request stopping the handling loop + stop chan struct{} + + currentPayload *eth.ExecutionPayloadEnvelope + ctx context.Context + net Network + log log.Logger + metrics Metrics +} + +// To avoid import cycles, we define a new Network interface here +// this interface is compatable with driver.Network +type Network interface { + PublishL2Payload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error +} + +// To avoid import cycles, we define a new Metrics interface here +// this interface is compatable with driver.Metrics +type Metrics interface { + RecordPublishingError() +} + +func NewAsyncGossiper(ctx context.Context, net Network, log log.Logger, metrics Metrics) *SimpleAsyncGossiper { + return &SimpleAsyncGossiper{ + running: atomic.Bool{}, + set: make(chan *eth.ExecutionPayloadEnvelope), + get: make(chan chan *eth.ExecutionPayloadEnvelope), + clear: make(chan struct{}), + stop: make(chan struct{}), + + currentPayload: nil, + net: net, + ctx: ctx, + log: log, + metrics: metrics, + } +} + +// Gossip is a synchronous function to store and gossip a payload +// it blocks until the payload can be taken by the async routine +func (p *SimpleAsyncGossiper) Gossip(payload *eth.ExecutionPayloadEnvelope) { + p.set <- payload +} + +// Get is a synchronous function to get the currently held payload +// it blocks until the async routine is able to return the payload +func (p *SimpleAsyncGossiper) Get() *eth.ExecutionPayloadEnvelope { + c := make(chan *eth.ExecutionPayloadEnvelope) + p.get <- c + return <-c +} + +// Clear is a synchronous function to clear the currently gossiping payload +// it blocks until the signal to clear is picked up by the async routine +func (p *SimpleAsyncGossiper) Clear() { + p.clear <- struct{}{} +} + +// Stop is a synchronous function to stop the async routine +// it blocks until the async routine accepts the signal +func (p *SimpleAsyncGossiper) Stop() { + p.stop <- struct{}{} +} + +// Start starts the AsyncGossiper's gossiping loop on a separate goroutine +// each behavior of the loop is handled by a select case on a channel, plus an internal handler function call +func (p *SimpleAsyncGossiper) Start() { + // if the gossiping is already running, return + if p.running.Load() { + return + } + p.running.Store(true) + // else, start the handling loop + go func() { + defer p.running.Store(false) + for { + select { + // new payloads to be gossiped are found in the `set` channel + case payload := <-p.set: + p.gossip(p.ctx, payload) + // requests to get the current payload are found in the `get` channel + case c := <-p.get: + p.getPayload(c) + // requests to clear the current payload are found in the `clear` channel + case <-p.clear: + p.clearPayload() + // if the context is done, return + case <-p.stop: + return + } + } + }() +} + +// gossip is the internal handler function for gossiping the current payload +// and storing the payload in the async AsyncGossiper's state +// it is called by the Start loop when a new payload is set +// the payload is only stored if the publish is successful +func (p *SimpleAsyncGossiper) gossip(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) { + if err := p.net.PublishL2Payload(ctx, payload); err == nil { + p.currentPayload = payload + } else { + p.log.Warn("failed to publish newly created block", + "id", payload.ExecutionPayload.ID(), + "hash", payload.ExecutionPayload.BlockHash, + "err", err) + p.metrics.RecordPublishingError() + } +} + +// getPayload is the internal handler function for getting the current payload +// c is the channel the caller expects to receive the payload on +func (p *SimpleAsyncGossiper) getPayload(c chan *eth.ExecutionPayloadEnvelope) { + c <- p.currentPayload +} + +// clearPayload is the internal handler function for clearing the current payload +func (p *SimpleAsyncGossiper) clearPayload() { + p.currentPayload = nil +} + +// NoOpGossiper is a no-op implementation of AsyncGossiper +// it serves as a placeholder for when the AsyncGossiper is not needed +type NoOpGossiper struct{} + +func (NoOpGossiper) Gossip(payload *eth.ExecutionPayloadEnvelope) {} +func (NoOpGossiper) Get() *eth.ExecutionPayloadEnvelope { return nil } +func (NoOpGossiper) Clear() {} +func (NoOpGossiper) Stop() {} +func (NoOpGossiper) Start() {} diff --git a/op-node/rollup/async/asyncgossiper_test.go b/op-node/rollup/async/asyncgossiper_test.go new file mode 100644 index 000000000000..7942e2b2836c --- /dev/null +++ b/op-node/rollup/async/asyncgossiper_test.go @@ -0,0 +1,149 @@ +package async + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +type mockNetwork struct { + reqs []*eth.ExecutionPayloadEnvelope +} + +func (m *mockNetwork) PublishL2Payload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { + m.reqs = append(m.reqs, payload) + return nil +} + +type mockMetrics struct{} + +func (m *mockMetrics) RecordPublishingError() {} + +// TestAsyncGossiper tests the AsyncGossiper component +// because the component is small and simple, it is tested as a whole +// this test starts, runs, clears and stops the AsyncGossiper +// because the AsyncGossiper is run in an async component, it is tested with eventually +func TestAsyncGossiper(t *testing.T) { + m := &mockNetwork{} + // Create a new instance of AsyncGossiper + p := NewAsyncGossiper(context.Background(), m, log.New(), &mockMetrics{}) + + // Start the AsyncGossiper + p.Start() + + // Test that the AsyncGossiper is running within a short duration + require.Eventually(t, func() bool { + return p.running.Load() + }, 10*time.Second, 10*time.Millisecond) + + // send a payload + payload := ð.ExecutionPayload{ + BlockNumber: hexutil.Uint64(1), + } + envelope := ð.ExecutionPayloadEnvelope{ + ExecutionPayload: payload, + } + p.Gossip(envelope) + require.Eventually(t, func() bool { + // Test that the gossiper has content at all + return p.Get() == envelope && + // Test that the payload has been sent to the (mock) network + m.reqs[0] == envelope + }, 10*time.Second, 10*time.Millisecond) + + p.Clear() + require.Eventually(t, func() bool { + // Test that the gossiper has no payload + return p.Get() == nil + }, 10*time.Second, 10*time.Millisecond) + + // Stop the AsyncGossiper + p.Stop() + + // Test that the AsyncGossiper stops within a short duration + require.Eventually(t, func() bool { + return !p.running.Load() + }, 10*time.Second, 10*time.Millisecond) +} + +// TestAsyncGossiperLoop confirms that when called repeatedly, the AsyncGossiper holds the latest payload +// and sends all payloads to the network +func TestAsyncGossiperLoop(t *testing.T) { + m := &mockNetwork{} + // Create a new instance of AsyncGossiper + p := NewAsyncGossiper(context.Background(), m, log.New(), &mockMetrics{}) + + // Start the AsyncGossiper + p.Start() + + // Test that the AsyncGossiper is running within a short duration + require.Eventually(t, func() bool { + return p.running.Load() + }, 10*time.Second, 10*time.Millisecond) + + // send multiple payloads + for i := 0; i < 10; i++ { + payload := ð.ExecutionPayload{ + BlockNumber: hexutil.Uint64(i), + } + envelope := ð.ExecutionPayloadEnvelope{ + ExecutionPayload: payload, + } + p.Gossip(envelope) + require.Eventually(t, func() bool { + // Test that the gossiper has content at all + return p.Get() == envelope && + // Test that the payload has been sent to the (mock) network + m.reqs[len(m.reqs)-1] == envelope + }, 10*time.Second, 10*time.Millisecond) + } + require.Equal(t, 10, len(m.reqs)) + // Stop the AsyncGossiper + p.Stop() + // Test that the AsyncGossiper stops within a short duration + require.Eventually(t, func() bool { + return !p.running.Load() + }, 10*time.Second, 10*time.Millisecond) +} + +// failingNetwork is a mock network that always fails to publish +type failingNetwork struct{} + +func (f *failingNetwork) PublishL2Payload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { + return errors.New("failed to publish") +} + +// TestAsyncGossiperFailToPublish tests that the AsyncGossiper clears the stored payload if the network fails +func TestAsyncGossiperFailToPublish(t *testing.T) { + m := &failingNetwork{} + // Create a new instance of AsyncGossiper + p := NewAsyncGossiper(context.Background(), m, log.New(), &mockMetrics{}) + + // Start the AsyncGossiper + p.Start() + + // send a payload + payload := ð.ExecutionPayload{ + BlockNumber: hexutil.Uint64(1), + } + envelope := ð.ExecutionPayloadEnvelope{ + ExecutionPayload: payload, + } + p.Gossip(envelope) + // Rather than expect the payload to become available, we should never see it, due to the publish failure + require.Never(t, func() bool { + return p.Get() == envelope + }, 10*time.Second, 10*time.Millisecond) + // Stop the AsyncGossiper + p.Stop() + // Test that the AsyncGossiper stops within a short duration + require.Eventually(t, func() bool { + return !p.running.Load() + }, 10*time.Second, 10*time.Millisecond) +} diff --git a/op-node/rollup/conductor/conductor.go b/op-node/rollup/conductor/conductor.go new file mode 100644 index 000000000000..912b08cf071e --- /dev/null +++ b/op-node/rollup/conductor/conductor.go @@ -0,0 +1,31 @@ +package conductor + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +// SequencerConductor is an interface for the driver to communicate with the sequencer conductor. +// It is used to determine if the current node is the active sequencer, and to commit unsafe payloads to the conductor log. +type SequencerConductor interface { + Leader(ctx context.Context) (bool, error) + CommitUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error + Close() +} + +// NoOpConductor is a no-op conductor that assumes this node is the leader sequencer. +type NoOpConductor struct{} + +// Leader returns true if this node is the leader sequencer. NoOpConductor always returns true. +func (c *NoOpConductor) Leader(ctx context.Context) (bool, error) { + return true, nil +} + +// CommitUnsafePayload commits an unsafe payload to the conductor log. +func (c *NoOpConductor) CommitUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { + return nil +} + +// Close closes the conductor client. +func (c *NoOpConductor) Close() {} diff --git a/op-node/rollup/derive/attributes.go b/op-node/rollup/derive/attributes.go index 5a1f73e7f834..c542740e1d2c 100644 --- a/op-node/rollup/derive/attributes.go +++ b/op-node/rollup/derive/attributes.go @@ -32,21 +32,21 @@ type L1ReceiptsFetcher interface { type SystemConfigL2Fetcher interface { SystemConfigByL2Hash(ctx context.Context, hash common.Hash) (eth.SystemConfig, error) - CachePayloadByHash(payload *eth.ExecutionPayload) bool + CachePayloadByHash(payload *eth.ExecutionPayloadEnvelope) bool } // FetchingAttributesBuilder fetches inputs for the building of L2 payload attributes on the fly. type FetchingAttributesBuilder struct { - cfg *rollup.Config - l1 L1ReceiptsFetcher - l2 SystemConfigL2Fetcher + rollupCfg *rollup.Config + l1 L1ReceiptsFetcher + l2 SystemConfigL2Fetcher } -func NewFetchingAttributesBuilder(cfg *rollup.Config, l1 L1ReceiptsFetcher, l2 SystemConfigL2Fetcher) *FetchingAttributesBuilder { +func NewFetchingAttributesBuilder(rollupCfg *rollup.Config, l1 L1ReceiptsFetcher, l2 SystemConfigL2Fetcher) *FetchingAttributesBuilder { return &FetchingAttributesBuilder{ - cfg: cfg, - l1: l1, - l2: l2, + rollupCfg: rollupCfg, + l1: l1, + l2: l2, } } @@ -65,7 +65,7 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex return nil, NewTemporaryError(fmt.Errorf("failed to retrieve L2 parent block: %w", err)) } - // If the L1 origin changed this block, then we are in the first block of the epoch. In this + // If the L1 origin changed in 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 { @@ -79,13 +79,13 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex epoch, info.ParentHash(), l2Parent.L1Origin)) } - deposits, err := DeriveDeposits(receipts, ba.cfg.DepositContractAddress) + deposits, err := DeriveDeposits(receipts, ba.rollupCfg.DepositContractAddress) if err != nil { // deposits may never be ignored. Failing to process them is a critical error. return nil, NewCriticalError(fmt.Errorf("failed to derive some deposits: %w", err)) } // apply sysCfg changes - if err := UpdateSystemConfigWithL1Receipts(&sysConfig, receipts, ba.cfg); err != nil { + if err := UpdateSystemConfigWithL1Receipts(&sysConfig, receipts, ba.rollupCfg, info.Time()); err != nil { return nil, NewCriticalError(fmt.Errorf("failed to apply derived L1 sysCfg updates: %w", err)) } @@ -107,13 +107,13 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex // Calculate bsc block base fee var l1BaseFee *big.Int - if ba.cfg.IsSnow(l2Parent.Time + ba.cfg.BlockTime) { + if ba.rollupCfg.IsSnow(l2Parent.Time + ba.rollupCfg.BlockTime) { l1BaseFee, err = SnowL1GasPrice(ctx, ba, epoch) if err != nil { return nil, err } - } else if ba.cfg.IsFermat(big.NewInt(int64(l2Parent.Number + 1))) { - l1BaseFee = bsc.BaseFeeByNetworks(ba.cfg.L2ChainID) + } else if ba.rollupCfg.IsFermat(big.NewInt(int64(l2Parent.Number + 1))) { + l1BaseFee = bsc.BaseFeeByNetworks(ba.rollupCfg.L2ChainID) } else { _, transactions, err := ba.l1.InfoAndTxsByHash(ctx, epoch.Hash) if err != nil { @@ -124,26 +124,43 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex l1Info = bsc.NewBlockInfoBSCWrapper(l1Info, l1BaseFee) // Sanity check the L1 origin was correctly selected to maintain the time invariant between L1 and L2 - nextL2Time := l2Parent.Time + ba.cfg.BlockTime + nextL2Time := l2Parent.Time + ba.rollupCfg.BlockTime if nextL2Time < l1Info.Time() { return nil, NewResetError(fmt.Errorf("cannot build L2 block on top %s for time %d before L1 origin %s at time %d", l2Parent, nextL2Time, eth.ToBlockID(l1Info), l1Info.Time())) } - l1InfoTx, err := L1InfoDepositBytes(seqNumber, l1Info, sysConfig, ba.cfg.IsRegolith(nextL2Time)) + var upgradeTxs []hexutil.Bytes + if ba.rollupCfg.IsEcotoneActivationBlock(nextL2Time) { + upgradeTxs, err = EcotoneNetworkUpgradeTransactions() + if err != nil { + return nil, NewCriticalError(fmt.Errorf("failed to build ecotone network upgrade txs: %w", err)) + } + } + + l1InfoTx, err := L1InfoDepositBytes(ba.rollupCfg, sysConfig, seqNumber, l1Info, nextL2Time) if err != nil { return nil, NewCriticalError(fmt.Errorf("failed to create l1InfoTx: %w", err)) } - txs := make([]hexutil.Bytes, 0, 1+len(depositTxs)) + txs := make([]hexutil.Bytes, 0, 1+len(depositTxs)+len(upgradeTxs)) txs = append(txs, l1InfoTx) txs = append(txs, depositTxs...) + txs = append(txs, upgradeTxs...) var withdrawals *types.Withdrawals - if ba.cfg.IsCanyon(nextL2Time) { + if ba.rollupCfg.IsCanyon(nextL2Time) { withdrawals = &types.Withdrawals{} } + var parentBeaconRoot *common.Hash + if ba.rollupCfg.IsEcotone(nextL2Time) { + parentBeaconRoot = l1Info.ParentBeaconRoot() + if parentBeaconRoot == nil { // default to zero hash if there is no beacon-block-root available + parentBeaconRoot = new(common.Hash) + } + } + return ð.PayloadAttributes{ Timestamp: hexutil.Uint64(nextL2Time), PrevRandao: eth.Bytes32(l1Info.MixDigest()), @@ -152,10 +169,11 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex NoTxPool: true, GasLimit: (*eth.Uint64Quantity)(&sysConfig.GasLimit), Withdrawals: withdrawals, + ParentBeaconBlockRoot: parentBeaconRoot, }, nil } -func (ba *FetchingAttributesBuilder) CachePayloadByHash(payload *eth.ExecutionPayload) bool { +func (ba *FetchingAttributesBuilder) CachePayloadByHash(payload *eth.ExecutionPayloadEnvelope) bool { return ba.l2.CachePayloadByHash(payload) } diff --git a/op-node/rollup/derive/attributes_queue.go b/op-node/rollup/derive/attributes_queue.go index 45dd1c08bb66..9e6e108eafde 100644 --- a/op-node/rollup/derive/attributes_queue.go +++ b/op-node/rollup/derive/attributes_queue.go @@ -25,15 +25,16 @@ import ( type AttributesBuilder interface { PreparePayloadAttributes(ctx context.Context, l2Parent eth.L2BlockRef, epoch eth.BlockID) (attrs *eth.PayloadAttributes, err error) - CachePayloadByHash(payload *eth.ExecutionPayload) bool + CachePayloadByHash(payload *eth.ExecutionPayloadEnvelope) bool } type AttributesQueue struct { - log log.Logger - config *rollup.Config - builder AttributesBuilder - prev *BatchQueue - batch *SingularBatch + log log.Logger + config *rollup.Config + builder AttributesBuilder + prev *BatchQueue + batch *SingularBatch + isLastInSpan bool } func NewAttributesQueue(log log.Logger, cfg *rollup.Config, builder AttributesBuilder, prev *BatchQueue) *AttributesQueue { @@ -49,23 +50,26 @@ func (aq *AttributesQueue) Origin() eth.L1BlockRef { return aq.prev.Origin() } -func (aq *AttributesQueue) NextAttributes(ctx context.Context, l2SafeHead eth.L2BlockRef) (*eth.PayloadAttributes, error) { +func (aq *AttributesQueue) NextAttributes(ctx context.Context, parent eth.L2BlockRef) (*AttributesWithParent, error) { // Get a batch if we need it if aq.batch == nil { - batch, err := aq.prev.NextBatch(ctx, l2SafeHead) + batch, isLastInSpan, err := aq.prev.NextBatch(ctx, parent) if err != nil { return nil, err } aq.batch = batch + aq.isLastInSpan = isLastInSpan } // Actually generate the next attributes - if attrs, err := aq.createNextAttributes(ctx, aq.batch, l2SafeHead); err != nil { + if attrs, err := aq.createNextAttributes(ctx, aq.batch, parent); err != nil { return nil, err } else { // Clear out the local state once we will succeed + attr := AttributesWithParent{attrs, parent, aq.isLastInSpan} aq.batch = nil - return attrs, nil + aq.isLastInSpan = false + return &attr, nil } } @@ -100,5 +104,6 @@ func (aq *AttributesQueue) createNextAttributes(ctx context.Context, batch *Sing func (aq *AttributesQueue) Reset(ctx context.Context, _ eth.L1BlockRef, _ eth.SystemConfig) error { aq.batch = nil + aq.isLastInSpan = false // overwritten later, but set for consistency return io.EOF } diff --git a/op-node/rollup/derive/attributes_queue_test.go b/op-node/rollup/derive/attributes_queue_test.go index a159851ebbb2..2852845c5d0b 100644 --- a/op-node/rollup/derive/attributes_queue_test.go +++ b/op-node/rollup/derive/attributes_queue_test.go @@ -68,7 +68,8 @@ func TestAttributesQueue(t *testing.T) { l2Fetcher := &testutils.MockL2Client{} l2Fetcher.ExpectSystemConfigByL2Hash(safeHead.Hash, parentL1Cfg, nil) - l1InfoTx, err := L1InfoDepositBytes(safeHead.SequenceNumber+1, l1Info, expectedL1Cfg, false) + rollupCfg := rollup.Config{} + l1InfoTx, err := L1InfoDepositBytes(&rollupCfg, expectedL1Cfg, safeHead.SequenceNumber+1, l1Info, 0) require.NoError(t, err) attrs := eth.PayloadAttributes{ Timestamp: eth.Uint64Quantity(safeHead.Time + cfg.BlockTime), @@ -80,7 +81,7 @@ func TestAttributesQueue(t *testing.T) { } attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, l2Fetcher) - aq := NewAttributesQueue(testlog.Logger(t, log.LvlError), cfg, attrBuilder, nil) + aq := NewAttributesQueue(testlog.Logger(t, log.LevelError), cfg, attrBuilder, nil) actual, err := aq.createNextAttributes(context.Background(), &batch, safeHead) diff --git a/op-node/rollup/derive/attributes_test.go b/op-node/rollup/derive/attributes_test.go index 79a7b8f147eb..6748f500253b 100644 --- a/op-node/rollup/derive/attributes_test.go +++ b/op-node/rollup/derive/attributes_test.go @@ -115,7 +115,7 @@ func TestPreparePayloadAttributes(t *testing.T) { l1Info.InfoParentHash = l2Parent.L1Origin.Hash l1Info.InfoNum = l2Parent.L1Origin.Number + 1 epoch := l1Info.ID() - l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg, false) + l1InfoTx, err := L1InfoDepositBytes(cfg, testSysCfg, 0, l1Info, 0) require.NoError(t, err) l1Fetcher.ExpectFetchReceipts(epoch.Hash, l1Info, nil, nil) attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, l1CfgFetcher) @@ -152,7 +152,7 @@ func TestPreparePayloadAttributes(t *testing.T) { require.NoError(t, err) epoch := l1Info.ID() - l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg, false) + l1InfoTx, err := L1InfoDepositBytes(cfg, testSysCfg, 0, l1Info, 0) require.NoError(t, err) l2Txs := append(append(make([]eth.Data, 0), l1InfoTx), usedDepositTxs...) @@ -182,7 +182,7 @@ func TestPreparePayloadAttributes(t *testing.T) { l1Info.InfoNum = l2Parent.L1Origin.Number epoch := l1Info.ID() - l1InfoTx, err := L1InfoDepositBytes(l2Parent.SequenceNumber+1, l1Info, testSysCfg, false) + l1InfoTx, err := L1InfoDepositBytes(cfg, testSysCfg, l2Parent.SequenceNumber+1, l1Info, 0) require.NoError(t, err) l1Fetcher.ExpectInfoByHash(epoch.Hash, l1Info, nil) @@ -234,7 +234,11 @@ func TestPreparePayloadAttributes(t *testing.T) { l1Info.InfoTime = tc.l1Time epoch := l1Info.ID() - l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg, tc.regolith) + time := tc.regolithTime + if !tc.regolith { + time-- + } + l1InfoTx, err := L1InfoDepositBytes(cfg, testSysCfg, 0, l1Info, time) require.NoError(t, err) l1Fetcher.ExpectFetchReceipts(epoch.Hash, l1Info, nil, nil) attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, l1CfgFetcher) diff --git a/op-node/rollup/derive/batch.go b/op-node/rollup/derive/batch.go index 9f3563e79080..c58b7e340c44 100644 --- a/op-node/rollup/derive/batch.go +++ b/op-node/rollup/derive/batch.go @@ -26,7 +26,7 @@ var encodeBufferPool = sync.Pool{ const ( // SingularBatchType is the first version of Batch format, representing a single L2 block. SingularBatchType = 0 - // SpanBatchType is the Batch version used after SpanBatch hard fork, representing a span of L2 blocks. + // SpanBatchType is the Batch version used after Delta hard fork, representing a span of L2 blocks. SpanBatchType = 1 ) diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index 420e0ce928e5..4ac92bf04b8b 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -34,7 +34,7 @@ type NextBatchProvider interface { type SafeBlockFetcher interface { L2BlockRefByNumber(context.Context, uint64) (eth.L2BlockRef, error) - PayloadByNumber(context.Context, uint64) (*eth.ExecutionPayload, error) + PayloadByNumber(context.Context, uint64) (*eth.ExecutionPayloadEnvelope, error) } // BatchQueue contains a set of batches for every L1 block. @@ -78,40 +78,57 @@ func (bq *BatchQueue) Origin() eth.L1BlockRef { // popNextBatch pops the next batch from the current queued up span-batch nextSpan. // The queue must be non-empty, or the function will panic. -func (bq *BatchQueue) popNextBatch(safeL2Head eth.L2BlockRef) *SingularBatch { +func (bq *BatchQueue) popNextBatch(parent eth.L2BlockRef) *SingularBatch { if len(bq.nextSpan) == 0 { panic("popping non-existent span-batch, invalid state") } nextBatch := bq.nextSpan[0] bq.nextSpan = bq.nextSpan[1:] - // Must set ParentHash before return. we can use safeL2Head because the parentCheck is verified in CheckBatch(). - nextBatch.ParentHash = safeL2Head.Hash + // Must set ParentHash before return. we can use parent because the parentCheck is verified in CheckBatch(). + nextBatch.ParentHash = parent.Hash + bq.log.Debug("pop next batch from the cached span batch") return nextBatch } -func (bq *BatchQueue) maybeAdvanceEpoch(nextBatch *SingularBatch) { - if len(bq.l1Blocks) == 0 { - return - } - if nextBatch.GetEpochNum() == rollup.Epoch(bq.l1Blocks[0].Number)+1 { - // Advance epoch if necessary - bq.l1Blocks = bq.l1Blocks[1:] +// NextBatch return next valid batch upon the given safe head. +// It also returns the boolean that indicates if the batch is the last block in the batch. +func (bq *BatchQueue) NextBatch(ctx context.Context, parent eth.L2BlockRef) (*SingularBatch, bool, error) { + if len(bq.nextSpan) > 0 { + // There are cached singular batches derived from the span batch. + // Check if the next cached batch matches the given parent block. + if bq.nextSpan[0].Timestamp == parent.Time+bq.config.BlockTime { + // Pop first one and return. + nextBatch := bq.popNextBatch(parent) + // len(bq.nextSpan) == 0 means it's the last batch of the span. + return nextBatch, len(bq.nextSpan) == 0, nil + } else { + // Given parent block does not match the next batch. It means the previously returned batch is invalid. + // Drop cached batches and find another batch. + bq.log.Warn("parent block does not match the next batch. dropped cached batches", "parent", parent.ID(), "nextBatchTime", bq.nextSpan[0].GetTimestamp()) + bq.nextSpan = bq.nextSpan[:0] + } } -} -func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) (*SingularBatch, error) { - if len(bq.nextSpan) > 0 { - // If there are cached singular batches, pop first one and return. - nextBatch := bq.popNextBatch(safeL2Head) - bq.maybeAdvanceEpoch(nextBatch) - return nextBatch, nil + // If the epoch is advanced, update bq.l1Blocks + // Advancing epoch must be done after the pipeline successfully apply the entire span batch to the chain. + // Because the span batch can be reverted during processing the batch, then we must preserve existing l1Blocks + // to verify the epochs of the next candidate batch. + if len(bq.l1Blocks) > 0 && parent.L1Origin.Number > bq.l1Blocks[0].Number { + for i, l1Block := range bq.l1Blocks { + if parent.L1Origin.Number == l1Block.Number { + bq.l1Blocks = bq.l1Blocks[i:] + bq.log.Debug("Advancing internal L1 blocks", "next_epoch", bq.l1Blocks[0].ID(), "next_epoch_time", bq.l1Blocks[0].Time) + break + } + } + // If we can't find the origin of parent block, we have to advance bq.origin. } // Note: We use the origin that we will have to determine if it's behind. This is important // because it's the future origin that gets saved into the l1Blocks array. // We always update the origin of this stage if it is not the same so after the update code // runs, this is consistent. - originBehind := bq.prev.Origin().Number < safeL2Head.L1Origin.Number + originBehind := bq.prev.Origin().Number < parent.L1Origin.Number // Advance origin if needed // Note: The entire pipeline has the same origin @@ -134,29 +151,29 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) if batch, err := bq.prev.NextBatch(ctx); err == io.EOF { outOfData = true } else if err != nil { - return nil, err + return nil, false, err } else if !originBehind { - bq.AddBatch(ctx, batch, safeL2Head) + bq.AddBatch(ctx, batch, parent) } // Skip adding data unless we are up to date with the origin, but do fully // empty the previous stages if originBehind { if outOfData { - return nil, io.EOF + return nil, false, io.EOF } else { - return nil, NotEnoughData + return nil, false, NotEnoughData } } // Finally attempt to derive more batches - batch, err := bq.deriveNextBatch(ctx, outOfData, safeL2Head) + batch, err := bq.deriveNextBatch(ctx, outOfData, parent) if err == io.EOF && outOfData { - return nil, io.EOF + return nil, false, io.EOF } else if err == io.EOF { - return nil, NotEnoughData + return nil, false, NotEnoughData } else if err != nil { - return nil, err + return nil, false, err } var nextBatch *SingularBatch @@ -164,28 +181,29 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) case SingularBatchType: singularBatch, ok := batch.(*SingularBatch) if !ok { - return nil, NewCriticalError(errors.New("failed type assertion to SingularBatch")) + return nil, false, NewCriticalError(errors.New("failed type assertion to SingularBatch")) } nextBatch = singularBatch case SpanBatchType: spanBatch, ok := batch.(*SpanBatch) if !ok { - return nil, NewCriticalError(errors.New("failed type assertion to SpanBatch")) + return nil, false, NewCriticalError(errors.New("failed type assertion to SpanBatch")) } // If next batch is SpanBatch, convert it to SingularBatches. - singularBatches, err := spanBatch.GetSingularBatches(bq.l1Blocks, safeL2Head) + singularBatches, err := spanBatch.GetSingularBatches(bq.l1Blocks, parent) if err != nil { - return nil, NewCriticalError(err) + return nil, false, NewCriticalError(err) } bq.nextSpan = singularBatches // span-batches are non-empty, so the below pop is safe. - nextBatch = bq.popNextBatch(safeL2Head) + nextBatch = bq.popNextBatch(parent) default: - return nil, NewCriticalError(fmt.Errorf("unrecognized batch type: %d", batch.GetBatchType())) + return nil, false, NewCriticalError(fmt.Errorf("unrecognized batch type: %d", batch.GetBatchType())) } - bq.maybeAdvanceEpoch(nextBatch) - return nextBatch, nil + // If the nextBatch is derived from the span batch, len(bq.nextSpan) == 0 means it's the last batch of the span. + // For singular batches, len(bq.nextSpan) == 0 is always true. + return nextBatch, len(bq.nextSpan) == 0, nil } func (bq *BatchQueue) Reset(ctx context.Context, base eth.L1BlockRef, _ eth.SystemConfig) error { @@ -202,7 +220,7 @@ func (bq *BatchQueue) Reset(ctx context.Context, base eth.L1BlockRef, _ eth.Syst return io.EOF } -func (bq *BatchQueue) AddBatch(ctx context.Context, batch Batch, l2SafeHead eth.L2BlockRef) { +func (bq *BatchQueue) AddBatch(ctx context.Context, batch Batch, parent eth.L2BlockRef) { if len(bq.l1Blocks) == 0 { panic(fmt.Errorf("cannot add batch with timestamp %d, no origin was prepared", batch.GetTimestamp())) } @@ -210,7 +228,7 @@ func (bq *BatchQueue) AddBatch(ctx context.Context, batch Batch, l2SafeHead eth. L1InclusionBlock: bq.origin, Batch: batch, } - validity := CheckBatch(ctx, bq.config, bq.log, bq.l1Blocks, l2SafeHead, &data, bq.l2) + validity := CheckBatch(ctx, bq.config, bq.log, bq.l1Blocks, parent, &data, bq.l2) if validity == BatchDrop { return // if we do drop the batch, CheckBatch will log the drop reason with WARN level. } @@ -222,24 +240,24 @@ func (bq *BatchQueue) AddBatch(ctx context.Context, batch Batch, l2SafeHead eth. // following the validity rules imposed on consecutive batches, // based on currently available buffered batch and L1 origin information. // If no batch can be derived yet, then (nil, io.EOF) is returned. -func (bq *BatchQueue) deriveNextBatch(ctx context.Context, outOfData bool, l2SafeHead eth.L2BlockRef) (Batch, error) { +func (bq *BatchQueue) deriveNextBatch(ctx context.Context, outOfData bool, parent eth.L2BlockRef) (Batch, error) { if len(bq.l1Blocks) == 0 { return nil, NewCriticalError(errors.New("cannot derive next batch, no origin was prepared")) } epoch := bq.l1Blocks[0] - bq.log.Trace("Deriving the next batch", "epoch", epoch, "l2SafeHead", l2SafeHead, "outOfData", outOfData) + bq.log.Trace("Deriving the next batch", "epoch", epoch, "parent", parent, "outOfData", outOfData) // Note: epoch origin can now be one block ahead of the L2 Safe Head // This is in the case where we auto generate all batches in an epoch & advance the epoch // but don't advance the L2 Safe Head's epoch - if l2SafeHead.L1Origin != epoch.ID() && l2SafeHead.L1Origin.Number != epoch.Number-1 { - return nil, NewResetError(fmt.Errorf("buffered L1 chain epoch %s in batch queue does not match safe head origin %s", epoch, l2SafeHead.L1Origin)) + if parent.L1Origin != epoch.ID() && parent.L1Origin.Number != epoch.Number-1 { + return nil, NewResetError(fmt.Errorf("buffered L1 chain epoch %s in batch queue does not match safe head origin %s", epoch, parent.L1Origin)) } // Find the first-seen batch that matches all validity conditions. // We may not have sufficient information to proceed filtering, and then we stop. // There may be none: in that case we force-create an empty batch - nextTimestamp := l2SafeHead.Time + bq.config.BlockTime + nextTimestamp := parent.Time + bq.config.BlockTime var nextBatch *BatchWithL1InclusionBlock // Go over all batches, in order of inclusion, and find the first batch we can accept. @@ -247,15 +265,15 @@ func (bq *BatchQueue) deriveNextBatch(ctx context.Context, outOfData bool, l2Saf var remaining []*BatchWithL1InclusionBlock batchLoop: for i, batch := range bq.batches { - validity := CheckBatch(ctx, bq.config, bq.log.New("batch_index", i), bq.l1Blocks, l2SafeHead, batch, bq.l2) + validity := CheckBatch(ctx, bq.config, bq.log.New("batch_index", i), bq.l1Blocks, parent, batch, bq.l2) switch validity { case BatchFuture: remaining = append(remaining, batch) continue case BatchDrop: batch.Batch.LogContext(bq.log).Warn("Dropping batch", - "l2_safe_head", l2SafeHead.ID(), - "l2_safe_head_time", l2SafeHead.Time, + "parent", parent.ID(), + "parent_time", parent.Time, ) continue case BatchAccept: @@ -283,7 +301,7 @@ batchLoop: // i.e. if the sequence window expired, we create empty batches for the current epoch expiryEpoch := epoch.Number + bq.config.SeqWindowSize forceEmptyBatches := (expiryEpoch == bq.origin.Number && outOfData) || expiryEpoch < bq.origin.Number - firstOfEpoch := epoch.Number == l2SafeHead.L1Origin.Number+1 + firstOfEpoch := epoch.Number == parent.L1Origin.Number+1 bq.log.Trace("Potentially generating an empty batch", "expiryEpoch", expiryEpoch, "forceEmptyBatches", forceEmptyBatches, "nextTimestamp", nextTimestamp, @@ -306,7 +324,7 @@ batchLoop: if nextTimestamp < nextEpoch.Time || firstOfEpoch { bq.log.Info("Generating next batch", "epoch", epoch, "timestamp", nextTimestamp) return &SingularBatch{ - ParentHash: l2SafeHead.Hash, + ParentHash: parent.Hash, EpochNum: rollup.Epoch(epoch.Number), EpochHash: epoch.Hash, Timestamp: nextTimestamp, diff --git a/op-node/rollup/derive/batch_queue_test.go b/op-node/rollup/derive/batch_queue_test.go index 3580f78c40d6..f82a7520842a 100644 --- a/op-node/rollup/derive/batch_queue_test.go +++ b/op-node/rollup/derive/batch_queue_test.go @@ -73,7 +73,7 @@ func buildSpanBatches(t *testing.T, parent *eth.L2BlockRef, singularBatches []*S return spanBatches } -func getSpanBatchTime(batchType int) *uint64 { +func getDeltaTime(batchType int) *uint64 { minTs := uint64(0) if batchType == SpanBatchType { return &minTs @@ -86,7 +86,7 @@ func l1InfoDepositTx(t *testing.T, l1BlockNum uint64) hexutil.Bytes { Number: l1BlockNum, BaseFee: big.NewInt(0), } - infoData, err := l1Info.MarshalBinary() + infoData, err := l1Info.marshalBinaryBedrock() require.NoError(t, err) depositTx := &types.DepositTx{ Data: infoData, @@ -96,15 +96,17 @@ func l1InfoDepositTx(t *testing.T, l1BlockNum uint64) hexutil.Bytes { return txData } -func singularBatchToPayload(t *testing.T, batch *SingularBatch, blockNumber uint64) eth.ExecutionPayload { +func singularBatchToPayload(t *testing.T, batch *SingularBatch, blockNumber uint64) eth.ExecutionPayloadEnvelope { txs := []hexutil.Bytes{l1InfoDepositTx(t, uint64(batch.EpochNum))} txs = append(txs, batch.Transactions...) - return eth.ExecutionPayload{ - BlockHash: mockHash(batch.Timestamp, 2), - ParentHash: batch.ParentHash, - BlockNumber: hexutil.Uint64(blockNumber), - Timestamp: hexutil.Uint64(batch.Timestamp), - Transactions: txs, + return eth.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + BlockHash: mockHash(batch.Timestamp, 2), + ParentHash: batch.ParentHash, + BlockNumber: hexutil.Uint64(blockNumber), + Timestamp: hexutil.Uint64(batch.Timestamp), + Transactions: txs, + }, } } @@ -165,7 +167,7 @@ func TestBatchQueue(t *testing.T) { // when the safehead's origin is ahead of the pipeline's origin (as is after a reset). // This issue was fixed in https://github.com/ethereum-optimism/optimism/pull/3694 func BatchQueueNewOrigin(t *testing.T, batchType int) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) l1 := L1Chain([]uint64{10, 15, 20, 25}) safeHead := eth.L2BlockRef{ Hash: mockHash(10, 2), @@ -182,7 +184,7 @@ func BatchQueueNewOrigin(t *testing.T, batchType int) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 2, - SpanBatchTime: getSpanBatchTime(batchType), + DeltaTime: getDeltaTime(batchType), } input := &fakeBatchQueueInput{ @@ -197,7 +199,7 @@ func BatchQueueNewOrigin(t *testing.T, batchType int) { // Prev Origin: 0; Safehead Origin: 2; Internal Origin: 0 // Should return no data but keep the same origin - data, err := bq.NextBatch(context.Background(), safeHead) + data, _, err := bq.NextBatch(context.Background(), safeHead) require.Nil(t, data) require.Equal(t, io.EOF, err) require.Equal(t, []eth.L1BlockRef{l1[0]}, bq.l1Blocks) @@ -206,7 +208,7 @@ func BatchQueueNewOrigin(t *testing.T, batchType int) { // Prev Origin: 1; Safehead Origin: 2; Internal Origin: 0 // Should wipe l1blocks + advance internal origin input.origin = l1[1] - data, err = bq.NextBatch(context.Background(), safeHead) + data, _, err = bq.NextBatch(context.Background(), safeHead) require.Nil(t, data) require.Equal(t, io.EOF, err) require.Empty(t, bq.l1Blocks) @@ -215,7 +217,7 @@ func BatchQueueNewOrigin(t *testing.T, batchType int) { // Prev Origin: 2; Safehead Origin: 2; Internal Origin: 1 // Should add to l1Blocks + advance internal origin input.origin = l1[2] - data, err = bq.NextBatch(context.Background(), safeHead) + data, _, err = bq.NextBatch(context.Background(), safeHead) require.Nil(t, data) require.Equal(t, io.EOF, err) require.Equal(t, []eth.L1BlockRef{l1[2]}, bq.l1Blocks) @@ -225,7 +227,7 @@ func BatchQueueNewOrigin(t *testing.T, batchType int) { // BatchQueueEager adds a bunch of contiguous batches and asserts that // enough calls to `NextBatch` return all of those batches. func BatchQueueEager(t *testing.T, batchType int) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) l1 := L1Chain([]uint64{10, 20, 30}) chainId := big.NewInt(1234) safeHead := eth.L2BlockRef{ @@ -243,7 +245,7 @@ func BatchQueueEager(t *testing.T, batchType int) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 30, - SpanBatchTime: getSpanBatchTime(batchType), + DeltaTime: getDeltaTime(batchType), L2ChainID: chainId, } @@ -286,7 +288,7 @@ func BatchQueueEager(t *testing.T, batchType int) { input.origin = l1[1] for i := 0; i < len(expectedOutputBatches); i++ { - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, expectedOutputErrors[i]) if b == nil { require.Nil(t, expectedOutputBatches[i]) @@ -303,7 +305,7 @@ func BatchQueueEager(t *testing.T, batchType int) { // BatchQueueInvalidInternalAdvance asserts that we do not miss an epoch when generating batches. // This is a regression test for CLI-3378. func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { - log := testlog.Logger(t, log.LvlTrace) + log := testlog.Logger(t, log.LevelTrace) l1 := L1Chain([]uint64{10, 15, 20, 25, 30}) chainId := big.NewInt(1234) safeHead := eth.L2BlockRef{ @@ -321,7 +323,7 @@ func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 2, - SpanBatchTime: getSpanBatchTime(batchType), + DeltaTime: getDeltaTime(batchType), L2ChainID: chainId, } @@ -363,7 +365,7 @@ func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { // Load continuous batches for epoch 0 for i := 0; i < len(expectedOutputBatches); i++ { - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, expectedOutputErrors[i]) if b == nil { require.Nil(t, expectedOutputBatches[i]) @@ -378,20 +380,20 @@ func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { // Advance to origin 1. No forced batches yet. input.origin = l1[1] - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, io.EOF) require.Nil(t, b) // Advance to origin 2. No forced batches yet because we are still on epoch 0 // & have batches for epoch 0. input.origin = l1[2] - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, io.EOF) require.Nil(t, b) // Advance to origin 3. Should generate one empty batch. input.origin = l1[3] - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.NotNil(t, b) require.Equal(t, safeHead.Time+2, b.Timestamp) @@ -400,13 +402,13 @@ func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { safeHead.Time += 2 safeHead.Hash = mockHash(b.Timestamp, 2) safeHead.L1Origin = b.Epoch() - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, io.EOF) require.Nil(t, b) // Advance to origin 4. Should generate one empty batch. input.origin = l1[4] - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.NotNil(t, b) require.Equal(t, rollup.Epoch(2), b.EpochNum) @@ -415,14 +417,14 @@ func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { safeHead.Time += 2 safeHead.Hash = mockHash(b.Timestamp, 2) safeHead.L1Origin = b.Epoch() - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, io.EOF) require.Nil(t, b) } func BatchQueueMissing(t *testing.T, batchType int) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) l1 := L1Chain([]uint64{10, 15, 20, 25}) chainId := big.NewInt(1234) safeHead := eth.L2BlockRef{ @@ -440,7 +442,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 2, - SpanBatchTime: getSpanBatchTime(batchType), + DeltaTime: getDeltaTime(batchType), L2ChainID: chainId, } @@ -477,7 +479,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { _ = bq.Reset(context.Background(), l1[0], eth.SystemConfig{}) for i := 0; i < len(expectedOutputBatches); i++ { - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, NotEnoughData) require.Nil(t, b) } @@ -485,7 +487,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { // advance origin. Underlying stage still has no more inputBatches // This is not enough to auto advance yet input.origin = l1[1] - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, io.EOF) require.Nil(t, b) @@ -493,7 +495,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { input.origin = l1[2] // Check for a generated batch at t = 12 - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b.Timestamp, uint64(12)) require.Empty(t, b.Transactions) @@ -503,7 +505,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { safeHead.Hash = mockHash(b.Timestamp, 2) // Check for generated batch at t = 14 - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b.Timestamp, uint64(14)) require.Empty(t, b.Transactions) @@ -513,7 +515,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { safeHead.Hash = mockHash(b.Timestamp, 2) // Check for the inputted batch at t = 16 - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b, expectedOutputBatches[0]) require.Equal(t, rollup.Epoch(0), b.EpochNum) @@ -527,9 +529,9 @@ func BatchQueueMissing(t *testing.T, batchType int) { // Check for the generated batch at t = 18. This batch advances the epoch // Note: We need one io.EOF returned from the bq that advances the internal L1 Blocks view // before the batch will be auto generated - _, e = bq.NextBatch(context.Background(), safeHead) + _, _, e = bq.NextBatch(context.Background(), safeHead) require.Equal(t, e, io.EOF) - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b.Timestamp, uint64(18)) require.Empty(t, b.Transactions) @@ -539,7 +541,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { // BatchQueueAdvancedEpoch tests that batch queue derives consecutive valid batches with advancing epochs. // Batch queue's l1blocks list should be updated along epochs. func BatchQueueAdvancedEpoch(t *testing.T, batchType int) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) l1 := L1Chain([]uint64{0, 6, 12, 18, 24}) // L1 block time: 6s chainId := big.NewInt(1234) safeHead := eth.L2BlockRef{ @@ -557,7 +559,7 @@ func BatchQueueAdvancedEpoch(t *testing.T, batchType int) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 30, - SpanBatchTime: getSpanBatchTime(batchType), + DeltaTime: getDeltaTime(batchType), L2ChainID: chainId, } @@ -610,13 +612,12 @@ func BatchQueueAdvancedEpoch(t *testing.T, batchType int) { inputOriginNumber += 1 input.origin = l1[inputOriginNumber] } - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, expectedOutputErrors[i]) if b == nil { require.Nil(t, expectedOutput) } else { require.Equal(t, expectedOutput, b) - require.Equal(t, bq.l1Blocks[0].Number, uint64(b.EpochNum)) safeHead.Number += 1 safeHead.Time += cfg.BlockTime safeHead.Hash = mockHash(b.Timestamp, 2) @@ -627,7 +628,7 @@ func BatchQueueAdvancedEpoch(t *testing.T, batchType int) { // BatchQueueShuffle tests batch queue can reorder shuffled valid batches func BatchQueueShuffle(t *testing.T, batchType int) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) l1 := L1Chain([]uint64{0, 6, 12, 18, 24}) // L1 block time: 6s chainId := big.NewInt(1234) safeHead := eth.L2BlockRef{ @@ -645,7 +646,7 @@ func BatchQueueShuffle(t *testing.T, batchType int) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 30, - SpanBatchTime: getSpanBatchTime(batchType), + DeltaTime: getDeltaTime(batchType), L2ChainID: chainId, } @@ -706,7 +707,7 @@ func BatchQueueShuffle(t *testing.T, batchType int) { var e error for j := 0; j < len(expectedOutputBatches); j++ { // Multiple NextBatch() executions may be required because the order of input is shuffled - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) if !errors.Is(e, NotEnoughData) { break } @@ -716,7 +717,6 @@ func BatchQueueShuffle(t *testing.T, batchType int) { require.Nil(t, expectedOutput) } else { require.Equal(t, expectedOutput, b) - require.Equal(t, bq.l1Blocks[0].Number, uint64(b.EpochNum)) safeHead.Number += 1 safeHead.Time += cfg.BlockTime safeHead.Hash = mockHash(b.Timestamp, 2) @@ -726,7 +726,7 @@ func BatchQueueShuffle(t *testing.T, batchType int) { } func TestBatchQueueOverlappingSpanBatch(t *testing.T) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) l1 := L1Chain([]uint64{10, 20, 30}) chainId := big.NewInt(1234) safeHead := eth.L2BlockRef{ @@ -744,7 +744,7 @@ func TestBatchQueueOverlappingSpanBatch(t *testing.T) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 30, - SpanBatchTime: getSpanBatchTime(SpanBatchType), + DeltaTime: getDeltaTime(SpanBatchType), L2ChainID: chainId, } @@ -814,7 +814,7 @@ func TestBatchQueueOverlappingSpanBatch(t *testing.T) { input.origin = l1[1] for i := 0; i < len(expectedOutputBatches); i++ { - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, expectedOutputErrors[i]) if b == nil { require.Nil(t, expectedOutputBatches[i]) @@ -831,7 +831,7 @@ func TestBatchQueueOverlappingSpanBatch(t *testing.T) { } func TestBatchQueueComplex(t *testing.T) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) l1 := L1Chain([]uint64{0, 6, 12, 18, 24}) // L1 block time: 6s chainId := big.NewInt(1234) safeHead := eth.L2BlockRef{ @@ -849,7 +849,7 @@ func TestBatchQueueComplex(t *testing.T) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 30, - SpanBatchTime: getSpanBatchTime(SpanBatchType), + DeltaTime: getDeltaTime(SpanBatchType), L2ChainID: chainId, } @@ -928,7 +928,7 @@ func TestBatchQueueComplex(t *testing.T) { var e error for j := 0; j < len(expectedOutputBatches); j++ { // Multiple NextBatch() executions may be required because the order of input is shuffled - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) if !errors.Is(e, NotEnoughData) { break } @@ -938,7 +938,6 @@ func TestBatchQueueComplex(t *testing.T) { require.Nil(t, expectedOutput) } else { require.Equal(t, expectedOutput, b) - require.Equal(t, bq.l1Blocks[0].Number, uint64(b.EpochNum)) safeHead.Number += 1 safeHead.Time += cfg.BlockTime safeHead.Hash = mockHash(b.Timestamp, 2) @@ -948,3 +947,70 @@ func TestBatchQueueComplex(t *testing.T) { l2Client.Mock.AssertExpectations(t) } + +func TestBatchQueueResetSpan(t *testing.T) { + log := testlog.Logger(t, log.LevelCrit) + chainId := big.NewInt(1234) + l1 := L1Chain([]uint64{0, 4, 8}) + safeHead := eth.L2BlockRef{ + Hash: mockHash(0, 2), + Number: 0, + ParentHash: common.Hash{}, + Time: 0, + L1Origin: l1[0].ID(), + SequenceNumber: 0, + } + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L2Time: 10, + }, + BlockTime: 2, + MaxSequencerDrift: 600, + SeqWindowSize: 30, + DeltaTime: getDeltaTime(SpanBatchType), + L2ChainID: chainId, + } + + singularBatches := []*SingularBatch{ + b(cfg.L2ChainID, 2, l1[0]), + b(cfg.L2ChainID, 4, l1[1]), + b(cfg.L2ChainID, 6, l1[1]), + b(cfg.L2ChainID, 8, l1[2]), + } + + input := &fakeBatchQueueInput{ + batches: []Batch{NewSpanBatch(singularBatches)}, + errors: []error{nil}, + origin: l1[2], + } + l2Client := testutils.MockL2Client{} + bq := NewBatchQueue(log, cfg, input, &l2Client) + bq.l1Blocks = l1 // Set enough l1 blocks to derive span batch + + // This NextBatch() will derive the span batch, return the first singular batch and save rest of batches in span. + nextBatch, _, err := bq.NextBatch(context.Background(), safeHead) + require.NoError(t, err) + require.Equal(t, nextBatch, singularBatches[0]) + require.Equal(t, len(bq.nextSpan), len(singularBatches)-1) + // batch queue's epoch should not be advanced until the entire span batch is returned + require.Equal(t, bq.l1Blocks[0], l1[0]) + + // This NextBatch() will return the second singular batch. + safeHead.Number += 1 + safeHead.Time += cfg.BlockTime + safeHead.Hash = mockHash(nextBatch.Timestamp, 2) + safeHead.L1Origin = nextBatch.Epoch() + nextBatch, _, err = bq.NextBatch(context.Background(), safeHead) + require.NoError(t, err) + require.Equal(t, nextBatch, singularBatches[1]) + require.Equal(t, len(bq.nextSpan), len(singularBatches)-2) + // batch queue's epoch should not be advanced until the entire span batch is returned + require.Equal(t, bq.l1Blocks[0], l1[0]) + + // Call NextBatch() with stale safeHead. It means the second batch failed to be processed. + // Batch queue should drop the entire span batch. + nextBatch, _, err = bq.NextBatch(context.Background(), safeHead) + require.Nil(t, nextBatch) + require.ErrorIs(t, err, io.EOF) + require.Equal(t, len(bq.nextSpan), 0) +} diff --git a/op-node/rollup/derive/batch_test.go b/op-node/rollup/derive/batch_test.go index a5d438ebfec0..4668a7e035f7 100644 --- a/op-node/rollup/derive/batch_test.go +++ b/op-node/rollup/derive/batch_test.go @@ -19,7 +19,7 @@ import ( ) func RandomRawSpanBatch(rng *rand.Rand, chainId *big.Int) *RawSpanBatch { - blockCount := uint64(1 + rng.Int()&0xFF) + blockCount := uint64(4 + rng.Int()&0xFF) // at least 4 originBits := new(big.Int) for i := 0; i < int(blockCount); i++ { bit := uint(0) @@ -31,14 +31,24 @@ func RandomRawSpanBatch(rng *rand.Rand, chainId *big.Int) *RawSpanBatch { var blockTxCounts []uint64 totalblockTxCounts := uint64(0) for i := 0; i < int(blockCount); i++ { - blockTxCount := uint64(rng.Intn(16)) + blockTxCount := 1 + uint64(rng.Intn(16)) blockTxCounts = append(blockTxCounts, blockTxCount) totalblockTxCounts += blockTxCount } - signer := types.NewLondonSigner(chainId) + londonSigner := types.NewLondonSigner(chainId) var txs [][]byte for i := 0; i < int(totalblockTxCounts); i++ { - tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) + var tx *types.Transaction + switch i % 4 { + case 0: + tx = testutils.RandomLegacyTx(rng, types.HomesteadSigner{}) + case 1: + tx = testutils.RandomLegacyTx(rng, londonSigner) + case 2: + tx = testutils.RandomAccessListTx(rng, londonSigner) + case 3: + tx = testutils.RandomDynamicFeeTx(rng, londonSigner) + } rawTx, err := tx.MarshalBinary() if err != nil { panic("MarshalBinary:" + err.Error()) @@ -172,9 +182,7 @@ func TestBatchRoundTrip(t *testing.T) { err = dec.UnmarshalBinary(enc) require.NoError(t, err) if dec.GetBatchType() == SpanBatchType { - rawSpanBatch, ok := dec.inner.(*RawSpanBatch) - require.True(t, ok) - _, err := rawSpanBatch.derive(blockTime, genesisTimestamp, chainID) + _, err := DeriveSpanBatch(&dec, blockTime, genesisTimestamp, chainID) require.NoError(t, err) } require.Equal(t, batch, &dec, "Batch not equal test case %v", i) @@ -222,9 +230,7 @@ func TestBatchRoundTripRLP(t *testing.T) { err = dec.DecodeRLP(s) require.NoError(t, err) if dec.GetBatchType() == SpanBatchType { - rawSpanBatch, ok := dec.inner.(*RawSpanBatch) - require.True(t, ok) - _, err := rawSpanBatch.derive(blockTime, genesisTimestamp, chainID) + _, err = DeriveSpanBatch(&dec, blockTime, genesisTimestamp, chainID) require.NoError(t, err) } require.Equal(t, batch, &dec, "Batch not equal test case %v", i) diff --git a/op-node/rollup/derive/batches.go b/op-node/rollup/derive/batches.go index ee64eda4519c..1c70013d3ce9 100644 --- a/op-node/rollup/derive/batches.go +++ b/op-node/rollup/derive/batches.go @@ -47,10 +47,6 @@ func CheckBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1Block log.Error("failed type assertion to SpanBatch") return BatchDrop } - if !cfg.IsSpanBatch(batch.Batch.GetTimestamp()) { - log.Warn("received SpanBatch before SpanBatch hard fork") - return BatchDrop - } return checkSpanBatch(ctx, cfg, log, l1Blocks, l2SafeHead, spanBatch, batch.L1InclusionBlock, l2Fetcher) default: log.Warn("Unrecognized batch type: %d", batch.Batch.GetBatchType()) @@ -181,6 +177,20 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B } epoch := l1Blocks[0] + startEpochNum := uint64(batch.GetStartEpochNum()) + batchOrigin := epoch + if startEpochNum == batchOrigin.Number+1 { + if len(l1Blocks) < 2 { + log.Info("eager batch wants to advance epoch, but could not without more L1 blocks", "current_epoch", epoch.ID()) + return BatchUndecided + } + batchOrigin = l1Blocks[1] + } + if !cfg.IsDelta(batchOrigin.Time) { + log.Warn("received SpanBatch with L1 origin before Delta hard fork", "l1_origin", batchOrigin.ID(), "l1_origin_time", batchOrigin.Time) + return BatchDrop + } + nextTimestamp := l2SafeHead.Time + cfg.BlockTime if batch.GetTimestamp() > nextTimestamp { @@ -199,18 +209,18 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B if batch.GetTimestamp() < nextTimestamp { if batch.GetTimestamp() > l2SafeHead.Time { // batch timestamp cannot be between safe head and next timestamp - log.Warn("batch has misaligned timestamp") + log.Warn("batch has misaligned timestamp, block time is too short") return BatchDrop } if (l2SafeHead.Time-batch.GetTimestamp())%cfg.BlockTime != 0 { - log.Warn("batch has misaligned timestamp") + log.Warn("batch has misaligned timestamp, not overlapped exactly") return BatchDrop } parentNum = l2SafeHead.Number - (l2SafeHead.Time-batch.GetTimestamp())/cfg.BlockTime - 1 var err error parentBlock, err = l2Fetcher.L2BlockRefByNumber(ctx, parentNum) if err != nil { - log.Error("failed to fetch L2 block", "number", parentNum, "err", err) + log.Warn("failed to fetch L2 block", "number", parentNum, "err", err) // unable to validate the batch for now. retry later. return BatchUndecided } @@ -220,8 +230,6 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B return BatchDrop } - startEpochNum := uint64(batch.GetStartEpochNum()) - // Filter out batches that were included too late. if startEpochNum+cfg.SeqWindowSize < l1InclusionBlock.Number { log.Warn("batch was included too late, sequence window expired") @@ -332,11 +340,11 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B safeBlockNum := parentNum + i + 1 safeBlockPayload, err := l2Fetcher.PayloadByNumber(ctx, safeBlockNum) if err != nil { - log.Error("failed to fetch L2 block payload", "number", parentNum, "err", err) + log.Warn("failed to fetch L2 block payload", "number", parentNum, "err", err) // unable to validate the batch for now. retry later. return BatchUndecided } - safeBlockTxs := safeBlockPayload.Transactions + safeBlockTxs := safeBlockPayload.ExecutionPayload.Transactions batchTxs := batch.GetBlockTransactions(int(i)) // execution payload has deposit TXs, but batch does not. depositCount := 0 @@ -355,9 +363,9 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B return BatchDrop } } - safeBlockRef, err := PayloadToBlockRef(safeBlockPayload, &cfg.Genesis) + safeBlockRef, err := PayloadToBlockRef(cfg, safeBlockPayload.ExecutionPayload) if err != nil { - log.Error("failed to extract L2BlockRef from execution payload", "hash", safeBlockPayload.BlockHash, "err", err) + log.Error("failed to extract L2BlockRef from execution payload", "hash", safeBlockPayload.ExecutionPayload.BlockHash, "err", err) return BatchDrop } if safeBlockRef.L1Origin.Number != batch.GetBlockEpochNum(int(i)) { diff --git a/op-node/rollup/derive/batches_test.go b/op-node/rollup/derive/batches_test.go index a3948fa1a27a..2cef6c4c6c0b 100644 --- a/op-node/rollup/derive/batches_test.go +++ b/op-node/rollup/derive/batches_test.go @@ -13,34 +13,24 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testutils" - "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 ValidBatchTestCase struct { - Name string - L1Blocks []eth.L1BlockRef - L2SafeHead eth.L2BlockRef - Batch BatchWithL1InclusionBlock - Expected BatchValidity + Name string + L1Blocks []eth.L1BlockRef + L2SafeHead eth.L2BlockRef + Batch BatchWithL1InclusionBlock + Expected BatchValidity + ExpectedLog string // log message that must be included + NotExpectedLog string // log message that must not be included + DeltaTime *uint64 } -type SpanBatchHardForkTestCase struct { - Name string - L1Blocks []eth.L1BlockRef - L2SafeHead eth.L2BlockRef - Batch BatchWithL1InclusionBlock - Expected BatchValidity - SpanBatchTime uint64 -} - -var HashA = common.Hash{0x0a} -var HashB = common.Hash{0x0b} - -func TestValidSingularBatch(t *testing.T) { - conf := rollup.Config{ +func TestValidBatch(t *testing.T) { + defaultConf := rollup.Config{ Genesis: rollup.Genesis{ L2Time: 31, // a genesis time that itself does not align to make it more interesting }, @@ -48,9 +38,17 @@ func TestValidSingularBatch(t *testing.T) { SeqWindowSize: 4, MaxSequencerDrift: 6, // other config fields are ignored and can be left empty. + DeltaTime: nil, } rng := rand.New(rand.NewSource(1234)) + + minTs := uint64(0) + chainId := new(big.Int).SetUint64(rng.Uint64()) + signer := types.NewLondonSigner(chainId) + randTx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) + randTxData, _ := randTx.MarshalBinary() + l1A := testutils.RandomBlockRef(rng) l1B := eth.L1BlockRef{ Hash: testutils.RandomHash(rng), @@ -96,7 +94,7 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: l2A0.Number + 1, ParentHash: l2A0.Hash, - Time: l2A0.Time + conf.BlockTime, + Time: l2A0.Time + defaultConf.BlockTime, L1Origin: l1A.ID(), SequenceNumber: 1, } @@ -105,7 +103,7 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: l2A1.Number + 1, ParentHash: l2A1.Hash, - Time: l2A1.Time + conf.BlockTime, + Time: l2A1.Time + defaultConf.BlockTime, L1Origin: l1A.ID(), SequenceNumber: 2, } @@ -114,7 +112,7 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: l2A2.Number + 1, ParentHash: l2A2.Hash, - Time: l2A2.Time + conf.BlockTime, + Time: l2A2.Time + defaultConf.BlockTime, L1Origin: l1A.ID(), SequenceNumber: 3, } @@ -123,11 +121,29 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: l2A3.Number + 1, ParentHash: l2A3.Hash, - Time: l2A3.Time + conf.BlockTime, // 8 seconds larger than l1A0, 1 larger than origin + Time: l2A3.Time + defaultConf.BlockTime, // 8 seconds larger than l1A0, 1 larger than origin L1Origin: l1B.ID(), SequenceNumber: 0, } + l2B1 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2B0.Number + 1, + ParentHash: l2B0.Hash, + Time: l2B0.Time + defaultConf.BlockTime, + L1Origin: l1B.ID(), + SequenceNumber: 1, + } + + l2B2 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2B1.Number + 1, + ParentHash: l2B1.Hash, + Time: l2B1.Time + defaultConf.BlockTime, + L1Origin: l1B.ID(), + SequenceNumber: 2, + } + l1X := eth.L1BlockRef{ Hash: testutils.RandomHash(rng), Number: 42, @@ -150,7 +166,7 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: 1000, ParentHash: testutils.RandomHash(rng), - Time: 10_000 + 12 + 6 - 1, // add one block, and you get ahead of next l1 block by more than the drift + Time: 10_000 + 24 + 6 - 1, // add one block, and you get ahead of next l1 block by more than the drift L1Origin: l1X.ID(), SequenceNumber: 0, } @@ -158,16 +174,24 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: l2X0.Number + 1, ParentHash: l2X0.Hash, - Time: l2X0.Time + conf.BlockTime, // exceeds sequencer time drift, forced to be empty block + Time: l2X0.Time + defaultConf.BlockTime, // exceeds sequencer time drift, forced to be empty block L1Origin: l1Y.ID(), SequenceNumber: 0, } + l2Z0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2Y0.Number + 1, + ParentHash: l2Y0.Hash, + Time: l2Y0.Time + defaultConf.BlockTime, // exceeds sequencer time drift, forced to be empty block + L1Origin: l1Z.ID(), + SequenceNumber: 0, + } l2A4 := eth.L2BlockRef{ Hash: testutils.RandomHash(rng), Number: l2A3.Number + 1, ParentHash: l2A3.Hash, - Time: l2A3.Time + conf.BlockTime, // 4*2 = 8, higher than seq time drift + Time: l2A3.Time + defaultConf.BlockTime, // 4*2 = 8, higher than seq time drift L1Origin: l1A.ID(), SequenceNumber: 4, } @@ -179,7 +203,7 @@ func TestValidSingularBatch(t *testing.T) { Time: l2A4.Time + 1, // too late for l2A4 to adopt yet } - testCases := []ValidBatchTestCase{ + singularBatchTestCases := []ValidBatchTestCase{ { Name: "missing L1 info", L1Blocks: []eth.L1BlockRef{}, @@ -286,7 +310,7 @@ func TestValidSingularBatch(t *testing.T) { ParentHash: l2B0.Hash, // build on top of safe head to continue EpochNum: rollup.Epoch(l2A3.L1Origin.Number), // epoch A is no longer valid EpochHash: l2A3.L1Origin.Hash, - Timestamp: l2B0.Time + conf.BlockTime, // pass the timestamp check to get too epoch check + Timestamp: l2B0.Time + defaultConf.BlockTime, // pass the timestamp check to get too epoch check Transactions: nil, }, }, @@ -520,173 +544,14 @@ func TestValidSingularBatch(t *testing.T) { ParentHash: l2A2.Hash, EpochNum: rollup.Epoch(l2B0.L1Origin.Number), EpochHash: l2B0.L1Origin.Hash, - Timestamp: l2A2.Time + conf.BlockTime, + Timestamp: l2A2.Time + defaultConf.BlockTime, Transactions: nil, }, }, Expected: BatchDrop, }, } - - // Log level can be increased for debugging purposes - logger := testlog.Logger(t, log.LvlError) - - for _, testCase := range testCases { - t.Run(testCase.Name, func(t *testing.T) { - ctx := context.Background() - validity := CheckBatch(ctx, &conf, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, nil) - require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") - }) - } -} - -func TestValidSpanBatch(t *testing.T) { - minTs := uint64(0) - conf := rollup.Config{ - Genesis: rollup.Genesis{ - L2Time: 31, // a genesis time that itself does not align to make it more interesting - }, - BlockTime: 2, - SeqWindowSize: 4, - MaxSequencerDrift: 6, - SpanBatchTime: &minTs, - // other config fields are ignored and can be left empty. - } - - rng := rand.New(rand.NewSource(1234)) - chainId := new(big.Int).SetUint64(rng.Uint64()) - signer := types.NewLondonSigner(chainId) - randTx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - randTxData, _ := randTx.MarshalBinary() - l1A := testutils.RandomBlockRef(rng) - l1B := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1A.Number + 1, - ParentHash: l1A.Hash, - Time: l1A.Time + 7, - } - l1C := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1B.Number + 1, - ParentHash: l1B.Hash, - Time: l1B.Time + 7, - } - l1D := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1C.Number + 1, - ParentHash: l1C.Hash, - Time: l1C.Time + 7, - } - l1E := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1D.Number + 1, - ParentHash: l1D.Hash, - Time: l1D.Time + 7, - } - l1F := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1E.Number + 1, - ParentHash: l1E.Hash, - Time: l1E.Time + 7, - } - - l2A0 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: 100, - ParentHash: testutils.RandomHash(rng), - Time: l1A.Time, - L1Origin: l1A.ID(), - SequenceNumber: 0, - } - - l2A1 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A0.Number + 1, - ParentHash: l2A0.Hash, - Time: l2A0.Time + conf.BlockTime, - L1Origin: l1A.ID(), - SequenceNumber: 1, - } - - l2A2 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A1.Number + 1, - ParentHash: l2A1.Hash, - Time: l2A1.Time + conf.BlockTime, - L1Origin: l1A.ID(), - SequenceNumber: 2, - } - - l2A3 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A2.Number + 1, - ParentHash: l2A2.Hash, - Time: l2A2.Time + conf.BlockTime, - L1Origin: l1A.ID(), - SequenceNumber: 3, - } - - l2B0 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A3.Number + 1, - ParentHash: l2A3.Hash, - Time: l2A3.Time + conf.BlockTime, // 8 seconds larger than l1A0, 1 larger than origin - L1Origin: l1B.ID(), - SequenceNumber: 0, - } - - l1X := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: 42, - ParentHash: testutils.RandomHash(rng), - Time: 10_000, - } - l1Y := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1X.Number + 1, - ParentHash: l1X.Hash, - Time: l1X.Time + 12, - } - l1Z := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1Y.Number + 1, - ParentHash: l1Y.Hash, - Time: l1Y.Time + 12, - } - l2X0 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: 1000, - ParentHash: testutils.RandomHash(rng), - Time: 10_000 + 12 + 6 - 1, // add one block, and you get ahead of next l1 block by more than the drift - L1Origin: l1X.ID(), - SequenceNumber: 0, - } - l2Y0 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2X0.Number + 1, - ParentHash: l2X0.Hash, - Time: l2X0.Time + conf.BlockTime, // exceeds sequencer time drift, forced to be empty block - L1Origin: l1Y.ID(), - SequenceNumber: 0, - } - - l2A4 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A3.Number + 1, - ParentHash: l2A3.Hash, - Time: l2A3.Time + conf.BlockTime, // 4*2 = 8, higher than seq time drift - L1Origin: l1A.ID(), - SequenceNumber: 4, - } - - l1BLate := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1A.Number + 1, - ParentHash: l1A.Hash, - Time: l2A4.Time + 1, // too late for l2A4 to adopt yet - } - - testCases := []ValidBatchTestCase{ + spanBatchTestCases := []ValidBatchTestCase{ { Name: "missing L1 info", L1Blocks: []eth.L1BlockRef{}, @@ -703,7 +568,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchUndecided, + Expected: BatchUndecided, + ExpectedLog: "missing L1 block input, cannot proceed with batch checking", + DeltaTime: &minTs, }, { Name: "future timestamp", @@ -721,25 +588,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchFuture, - }, - { - Name: "old timestamp", - L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, - L2SafeHead: l2A0, - Batch: BatchWithL1InclusionBlock{ - L1InclusionBlock: l1B, - Batch: NewSpanBatch([]*SingularBatch{ - { - ParentHash: l2A1.ParentHash, - EpochNum: rollup.Epoch(l2A1.L1Origin.Number), - EpochHash: l2A1.L1Origin.Hash, - Timestamp: l2A0.Time, // repeating the same time - Transactions: nil, - }, - }), - }, - Expected: BatchDrop, + Expected: BatchFuture, + ExpectedLog: "received out-of-order batch for future processing after next batch", + DeltaTime: &minTs, }, { Name: "misaligned timestamp", @@ -757,7 +608,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "span batch has no new blocks after safe head", + DeltaTime: &minTs, }, { Name: "invalid parent block hash", @@ -775,7 +628,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "ignoring batch with mismatching parent hash", + DeltaTime: &minTs, }, { Name: "sequence window expired", @@ -793,7 +648,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch was included too late, sequence window expired", + DeltaTime: &minTs, }, { Name: "epoch too old, but good parent hash and timestamp", // repeat of now outdated l2A3 data @@ -806,18 +663,20 @@ func TestValidSpanBatch(t *testing.T) { ParentHash: l2B0.Hash, // build on top of safe head to continue EpochNum: rollup.Epoch(l2A3.L1Origin.Number), // epoch A is no longer valid EpochHash: l2A3.L1Origin.Hash, - Timestamp: l2B0.Time + conf.BlockTime, // pass the timestamp check to get too epoch check + Timestamp: l2B0.Time + defaultConf.BlockTime, // pass the timestamp check to get too epoch check Transactions: nil, }, { EpochNum: rollup.Epoch(l1B.Number), EpochHash: l1B.Hash, // pass the l1 origin check - Timestamp: l2B0.Time + conf.BlockTime*2, + Timestamp: l2B0.Time + defaultConf.BlockTime*2, Transactions: nil, }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "dropped batch, epoch is too old", + DeltaTime: &minTs, }, { Name: "insufficient L1 info for eager derivation", @@ -835,7 +694,36 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchUndecided, + Expected: BatchUndecided, + ExpectedLog: "eager batch wants to advance epoch, but could not without more L1 blocks", + DeltaTime: &minTs, + }, + { + Name: "insufficient L1 info for eager derivation - long span", + L1Blocks: []eth.L1BlockRef{l1A}, // don't know about l1B yet + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1C, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A3.ParentHash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + { + ParentHash: l2B0.ParentHash, + EpochNum: rollup.Epoch(l2B0.L1Origin.Number), + EpochHash: l2B0.L1Origin.Hash, + Timestamp: l2B0.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchUndecided, + ExpectedLog: "need more l1 blocks to check entire origins of span batch", + DeltaTime: &minTs, }, { Name: "epoch too new", @@ -853,7 +741,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch is for future epoch too far ahead, while it has the next timestamp, so it must be invalid", + DeltaTime: &minTs, }, { Name: "epoch hash wrong", @@ -871,7 +761,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch is for different L1 chain, epoch hash does not match", + DeltaTime: &minTs, }, { Name: "epoch hash wrong - long span", @@ -896,7 +788,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch is for different L1 chain, epoch hash does not match", + DeltaTime: &minTs, }, { Name: "sequencer time drift on same epoch with non-empty txs", @@ -914,7 +808,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch exceeded sequencer time drift, sequencer must adopt new L1 origin to include transactions again", + DeltaTime: &minTs, }, { Name: "sequencer time drift on same epoch with non-empty txs - long span", @@ -939,7 +835,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch exceeded sequencer time drift, sequencer must adopt new L1 origin to include transactions again", + DeltaTime: &minTs, }, { Name: "sequencer time drift on changing epoch with non-empty txs", @@ -957,7 +855,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch exceeded sequencer time drift, sequencer must adopt new L1 origin to include transactions again", + DeltaTime: &minTs, }, { Name: "sequencer time drift on same epoch with empty txs and late next epoch", @@ -975,7 +875,8 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchAccept, // accepted because empty & preserving L2 time invariant + Expected: BatchAccept, // accepted because empty & preserving L2 time invariant + DeltaTime: &minTs, }, { Name: "sequencer time drift on changing epoch with empty txs", @@ -991,9 +892,18 @@ func TestValidSpanBatch(t *testing.T) { Timestamp: l2Y0.Time, // valid, but more than 6 ahead of l1Y.Time Transactions: nil, }, + { + ParentHash: l2Z0.ParentHash, + EpochNum: rollup.Epoch(l2Z0.L1Origin.Number), + EpochHash: l2Z0.L1Origin.Hash, + Timestamp: l2Z0.Time, // valid, but more than 6 ahead of l1Y.Time + Transactions: nil, + }, }), }, - Expected: BatchAccept, // accepted because empty & still advancing epoch + Expected: BatchAccept, // accepted because empty & still advancing epoch + DeltaTime: &minTs, + NotExpectedLog: "continuing with empty batch before late L1 block to preserve L2 time invariant", }, { Name: "sequencer time drift on same epoch with empty txs and no next epoch in sight yet", @@ -1011,7 +921,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time + Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time + ExpectedLog: "without the next L1 origin we cannot determine yet if this empty batch that exceeds the time drift is still valid", + DeltaTime: &minTs, }, { Name: "sequencer time drift on same epoch with empty txs and no next epoch in sight yet - long span", @@ -1036,7 +948,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time + Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time + ExpectedLog: "without the next L1 origin we cannot determine yet if this empty batch that exceeds the time drift is still valid", + DeltaTime: &minTs, }, { Name: "sequencer time drift on same epoch with empty txs and but in-sight epoch that invalidates it", @@ -1054,7 +968,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, // dropped because it could have advanced the epoch to B + Expected: BatchDrop, // dropped because it could have advanced the epoch to B + ExpectedLog: "batch exceeded sequencer time drift without adopting next origin, and next L1 origin would have been valid", + DeltaTime: &minTs, }, { Name: "sequencer time drift on same epoch with empty txs and but in-sight epoch that invalidates it - long span", @@ -1079,7 +995,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, // dropped because it could have advanced the epoch to B + Expected: BatchDrop, // dropped because it could have advanced the epoch to B + ExpectedLog: "batch exceeded sequencer time drift without adopting next origin, and next L1 origin would have been valid", + DeltaTime: &minTs, }, { Name: "empty tx included", @@ -1099,7 +1017,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "transaction data must not be empty, but found empty tx", + DeltaTime: &minTs, }, { Name: "deposit tx included", @@ -1119,7 +1039,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "sequencers may not embed any deposits into batch data, but found tx that has one", + DeltaTime: &minTs, }, { Name: "valid batch same epoch", @@ -1137,7 +1059,8 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchAccept, + Expected: BatchAccept, + DeltaTime: &minTs, }, { Name: "valid batch changing epoch", @@ -1155,7 +1078,8 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchAccept, + Expected: BatchAccept, + DeltaTime: &minTs, }, { Name: "batch with L2 time before L1 time", @@ -1168,12 +1092,14 @@ func TestValidSpanBatch(t *testing.T) { ParentHash: l2A2.Hash, EpochNum: rollup.Epoch(l2B0.L1Origin.Number), EpochHash: l2B0.L1Origin.Hash, - Timestamp: l2A2.Time + conf.BlockTime, + Timestamp: l2A2.Time + defaultConf.BlockTime, Transactions: nil, }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "block timestamp is less than L1 origin timestamp", + DeltaTime: &minTs, }, { Name: "batch with L2 time before L1 time - long span", @@ -1193,12 +1119,14 @@ func TestValidSpanBatch(t *testing.T) { ParentHash: l2A2.Hash, EpochNum: rollup.Epoch(l2B0.L1Origin.Number), EpochHash: l2B0.L1Origin.Hash, - Timestamp: l2A2.Time + conf.BlockTime, + Timestamp: l2A2.Time + defaultConf.BlockTime, Transactions: nil, }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "block timestamp is less than L1 origin timestamp", + DeltaTime: &minTs, }, { Name: "valid overlapping batch", @@ -1223,7 +1151,8 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchAccept, + Expected: BatchAccept, + DeltaTime: &minTs, }, { Name: "longer overlapping batch", @@ -1255,7 +1184,8 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchAccept, + Expected: BatchAccept, + DeltaTime: &minTs, }, { Name: "fully overlapping batch", @@ -1280,7 +1210,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "span batch has no new blocks after safe head", + DeltaTime: &minTs, }, { Name: "overlapping batch with invalid parent hash", @@ -1305,7 +1237,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "ignoring batch with mismatching parent hash", + DeltaTime: &minTs, }, { Name: "overlapping batch with invalid origin number", @@ -1330,7 +1264,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "overlapped block's L1 origin number does not match", + DeltaTime: &minTs, }, { Name: "overlapping batch with invalid tx", @@ -1355,7 +1291,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "overlapped block's tx count does not match", + DeltaTime: &minTs, }, { Name: "overlapping batch l2 fetcher error", @@ -1387,89 +1325,91 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchUndecided, + Expected: BatchUndecided, + ExpectedLog: "failed to fetch L2 block", + DeltaTime: &minTs, }, - } - - // Log level can be increased for debugging purposes - logger := testlog.Logger(t, log.LvlError) - - l2Client := testutils.MockL2Client{} - var nilErr error - // will be return error for block #99 (parent of l2A0) - tempErr := errors.New("temp error") - l2Client.Mock.On("L2BlockRefByNumber", l2A0.Number-1).Times(9999).Return(eth.L2BlockRef{}, &tempErr) - l2Client.Mock.On("PayloadByNumber", l2A0.Number-1).Times(9999).Return(nil, &tempErr) - - // make payloads for L2 blocks and set as expected return value of MockL2Client - for _, l2Block := range []eth.L2BlockRef{l2A0, l2A1, l2A2, l2A3, l2A4, l2B0} { - l2Client.ExpectL2BlockRefByNumber(l2Block.Number, l2Block, nil) - txData := l1InfoDepositTx(t, l2Block.L1Origin.Number) - payload := eth.ExecutionPayload{ - ParentHash: l2Block.ParentHash, - BlockNumber: hexutil.Uint64(l2Block.Number), - Timestamp: hexutil.Uint64(l2Block.Time), - BlockHash: l2Block.Hash, - Transactions: []hexutil.Bytes{txData}, - } - l2Client.Mock.On("L2BlockRefByNumber", l2Block.Number).Times(9999).Return(l2Block, &nilErr) - l2Client.Mock.On("PayloadByNumber", l2Block.Number).Times(9999).Return(&payload, &nilErr) - } - - for _, testCase := range testCases { - t.Run(testCase.Name, func(t *testing.T) { - ctx := context.Background() - validity := CheckBatch(ctx, &conf, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, &l2Client) - require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") - }) - } -} - -func TestSpanBatchHardFork(t *testing.T) { - minTs := uint64(0) - conf := rollup.Config{ - Genesis: rollup.Genesis{ - L2Time: 31, // a genesis time that itself does not align to make it more interesting + { + Name: "short block time", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A0.Hash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A0.Time + 1, + Transactions: nil, + }, + { + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A1.Time + 1, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + ExpectedLog: "batch has misaligned timestamp, block time is too short", + DeltaTime: &minTs, + }, + { + Name: "misaligned batch", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A0.Hash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A0.Time - 1, + Transactions: nil, + }, + { + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + ExpectedLog: "batch has misaligned timestamp, not overlapped exactly", + DeltaTime: &minTs, + }, + { + Name: "failed to fetch overlapping block payload", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A3, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A2.Hash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + { + ParentHash: l2A3.Hash, + EpochNum: rollup.Epoch(l2B0.L1Origin.Number), + EpochHash: l2B0.L1Origin.Hash, + Timestamp: l2B0.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchUndecided, + ExpectedLog: "failed to fetch L2 block payload", + DeltaTime: &minTs, }, - BlockTime: 2, - SeqWindowSize: 4, - MaxSequencerDrift: 6, - SpanBatchTime: &minTs, - // other config fields are ignored and can be left empty. - } - - rng := rand.New(rand.NewSource(1234)) - chainId := new(big.Int).SetUint64(rng.Uint64()) - signer := types.NewLondonSigner(chainId) - randTx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - randTxData, _ := randTx.MarshalBinary() - l1A := testutils.RandomBlockRef(rng) - l1B := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1A.Number + 1, - ParentHash: l1A.Hash, - Time: l1A.Time + 7, - } - - l2A0 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: 100, - ParentHash: testutils.RandomHash(rng), - Time: l1A.Time, - L1Origin: l1A.ID(), - SequenceNumber: 0, - } - - l2A1 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A0.Number + 1, - ParentHash: l2A0.Hash, - Time: l2A0.Time + conf.BlockTime, - L1Origin: l1A.ID(), - SequenceNumber: 1, - } - - testCases := []SpanBatchHardForkTestCase{ { Name: "singular batch before hard fork", L1Blocks: []eth.L1BlockRef{l1A, l1B}, @@ -1484,8 +1424,8 @@ func TestSpanBatchHardFork(t *testing.T) { Transactions: []hexutil.Bytes{randTxData}, }, }, - SpanBatchTime: l2A1.Time + 2, - Expected: BatchAccept, + DeltaTime: &l1B.Time, + Expected: BatchAccept, }, { Name: "span batch before hard fork", @@ -1503,8 +1443,9 @@ func TestSpanBatchHardFork(t *testing.T) { }, }), }, - SpanBatchTime: l2A1.Time + 2, - Expected: BatchDrop, + DeltaTime: &l1B.Time, + Expected: BatchDrop, + ExpectedLog: "received SpanBatch with L1 origin before Delta hard fork", }, { Name: "singular batch after hard fork", @@ -1520,8 +1461,8 @@ func TestSpanBatchHardFork(t *testing.T) { Transactions: []hexutil.Bytes{randTxData}, }, }, - SpanBatchTime: l2A1.Time - 2, - Expected: BatchAccept, + DeltaTime: &l1A.Time, + Expected: BatchAccept, }, { Name: "span batch after hard fork", @@ -1539,21 +1480,170 @@ func TestSpanBatchHardFork(t *testing.T) { }, }), }, - SpanBatchTime: l2A1.Time - 2, - Expected: BatchAccept, + DeltaTime: &l1A.Time, + Expected: BatchAccept, }, } // Log level can be increased for debugging purposes - logger := testlog.Logger(t, log.LvlInfo) + logger, logs := testlog.CaptureLogger(t, log.LevelDebug) + + l2Client := testutils.MockL2Client{} + var nilErr error + tempErr := errors.New("temp error") + // will return an error for block #99 (parent of l2A0) + l2Client.Mock.On("L2BlockRefByNumber", l2A0.Number-1).Return(eth.L2BlockRef{}, &tempErr) + // will return an error for l2A3 + l2Client.Mock.On("PayloadByNumber", l2A3.Number).Return(ð.ExecutionPayloadEnvelope{}, &tempErr) + + // make payloads for L2 blocks and set as expected return value of MockL2Client + for _, l2Block := range []eth.L2BlockRef{l2A0, l2A1, l2A2, l2B0} { + l2Client.ExpectL2BlockRefByNumber(l2Block.Number, l2Block, nil) + txData := l1InfoDepositTx(t, l2Block.L1Origin.Number) + payload := eth.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + ParentHash: l2Block.ParentHash, + BlockNumber: hexutil.Uint64(l2Block.Number), + Timestamp: hexutil.Uint64(l2Block.Time), + BlockHash: l2Block.Hash, + Transactions: []hexutil.Bytes{txData}, + }, + } + l2Client.Mock.On("L2BlockRefByNumber", l2Block.Number).Return(l2Block, &nilErr) + l2Client.Mock.On("PayloadByNumber", l2Block.Number).Return(&payload, &nilErr) + } + + runTestCase := func(t *testing.T, testCase ValidBatchTestCase) { + ctx := context.Background() + rcfg := defaultConf + if testCase.DeltaTime != nil { + rcfg.DeltaTime = testCase.DeltaTime + } + validity := CheckBatch(ctx, &rcfg, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, &l2Client) + require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") + if expLog := testCase.ExpectedLog; expLog != "" { + // Check if ExpectedLog is contained in the log buffer + containsFilter := testlog.NewMessageContainsFilter(expLog) + if l := logs.FindLog(containsFilter); l == nil { + t.Errorf("Expected log message was not logged: %q", expLog) + } + } + if notExpLog := testCase.NotExpectedLog; notExpLog != "" { + // Check if NotExpectedLog is contained in the log buffer + containsFilter := testlog.NewMessageContainsFilter(notExpLog) + if l := logs.FindLog(containsFilter); l != nil { + t.Errorf("Unexpected log message containing %q was logged: %q", notExpLog, l.Message) + } + } + logs.Clear() + } + + // Run singular batch test cases + for _, testCase := range singularBatchTestCases { + t.Run("singular_"+testCase.Name, func(t *testing.T) { + runTestCase(t, testCase) + }) + } - for _, testCase := range testCases { - t.Run(testCase.Name, func(t *testing.T) { - rcfg := conf - rcfg.SpanBatchTime = &testCase.SpanBatchTime - ctx := context.Background() - validity := CheckBatch(ctx, &rcfg, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, nil) - require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") + // Run span batch test cases + for _, testCase := range spanBatchTestCases { + t.Run("span_"+testCase.Name, func(t *testing.T) { + runTestCase(t, testCase) }) } + + // ====== Test different TX for overlapping batches ====== + l2Client.ExpectL2BlockRefByNumber(l2B1.Number, l2B1, nil) + txData := l1InfoDepositTx(t, l2B1.L1Origin.Number) + randTx = testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) + randTxData, _ = randTx.MarshalBinary() + payload := eth.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + ParentHash: l2B0.Hash, + BlockNumber: hexutil.Uint64(l2B1.Number), + Timestamp: hexutil.Uint64(l2B1.Time), + BlockHash: l2B1.Hash, + Transactions: []hexutil.Bytes{txData, randTxData}, + }, + } + l2Client.Mock.On("PayloadByNumber", l2B1.Number).Return(&payload, &nilErr).Once() + + randTx = testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) + randTxData, _ = randTx.MarshalBinary() + differentTxtestCase := ValidBatchTestCase{ + Name: "different_tx_overlapping_batch", + L1Blocks: []eth.L1BlockRef{l1B}, + L2SafeHead: l2B1, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2B0.Hash, + EpochNum: rollup.Epoch(l2B1.L1Origin.Number), + EpochHash: l2B1.L1Origin.Hash, + Timestamp: l2B1.Time, + Transactions: []hexutil.Bytes{randTxData}, // Random generated TX that does not match overlapping block + }, + { + ParentHash: l2B1.Hash, + EpochNum: rollup.Epoch(l2B2.L1Origin.Number), + EpochHash: l2B2.L1Origin.Hash, + Timestamp: l2B2.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + ExpectedLog: "overlapped block's transaction does not match", + DeltaTime: &minTs, + } + + t.Run(differentTxtestCase.Name, func(t *testing.T) { + runTestCase(t, differentTxtestCase) + }) + + // ====== Test invalid TX for overlapping batches ====== + payload = eth.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + ParentHash: l2B0.Hash, + BlockNumber: hexutil.Uint64(l2B1.Number), + Timestamp: hexutil.Uint64(l2B1.Time), + BlockHash: l2B1.Hash, + // First TX is not a deposit TX. it will make error when extracting L2BlockRef from the payload + Transactions: []hexutil.Bytes{randTxData}, + }, + } + l2Client.Mock.On("PayloadByNumber", l2B1.Number).Return(&payload, &nilErr).Once() + + invalidTxTestCase := ValidBatchTestCase{ + Name: "invalid_tx_overlapping_batch", + L1Blocks: []eth.L1BlockRef{l1B}, + L2SafeHead: l2B1, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2B0.Hash, + EpochNum: rollup.Epoch(l2B1.L1Origin.Number), + EpochHash: l2B1.L1Origin.Hash, + Timestamp: l2B1.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + { + ParentHash: l2B1.Hash, + EpochNum: rollup.Epoch(l2B2.L1Origin.Number), + EpochHash: l2B2.L1Origin.Hash, + Timestamp: l2B2.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + ExpectedLog: "failed to extract L2BlockRef from execution payload", + DeltaTime: &minTs, + } + + t.Run(invalidTxTestCase.Name, func(t *testing.T) { + runTestCase(t, invalidTxTestCase) + }) } diff --git a/op-node/rollup/derive/blob_data_source.go b/op-node/rollup/derive/blob_data_source.go new file mode 100644 index 000000000000..7780b6065063 --- /dev/null +++ b/op-node/rollup/derive/blob_data_source.go @@ -0,0 +1,173 @@ +package derive + +import ( + "context" + "errors" + "fmt" + "io" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type blobOrCalldata struct { + // union type. exactly one of calldata or blob should be non-nil + blob *eth.Blob + calldata *eth.Data +} + +// BlobDataSource fetches blobs or calldata as appropriate and transforms them into usable rollup +// data. +type BlobDataSource struct { + data []blobOrCalldata + ref eth.L1BlockRef + batcherAddr common.Address + dsCfg DataSourceConfig + fetcher L1TransactionFetcher + blobsFetcher L1BlobsFetcher + log log.Logger +} + +// NewBlobDataSource creates a new blob data source. +func NewBlobDataSource(ctx context.Context, log log.Logger, dsCfg DataSourceConfig, fetcher L1TransactionFetcher, blobsFetcher L1BlobsFetcher, ref eth.L1BlockRef, batcherAddr common.Address) DataIter { + return &BlobDataSource{ + ref: ref, + dsCfg: dsCfg, + fetcher: fetcher, + log: log.New("origin", ref), + batcherAddr: batcherAddr, + blobsFetcher: blobsFetcher, + } +} + +// Next returns the next piece of batcher data, or an io.EOF error if no data remains. It returns +// ResetError if it cannot find the referenced block or a referenced blob, or TemporaryError for +// any other failure to fetch a block or blob. +func (ds *BlobDataSource) Next(ctx context.Context) (eth.Data, error) { + if ds.data == nil { + var err error + if ds.data, err = ds.open(ctx); err != nil { + return nil, err + } + } + + if len(ds.data) == 0 { + return nil, io.EOF + } + + next := ds.data[0] + ds.data = ds.data[1:] + if next.calldata != nil { + return *next.calldata, nil + } + + data, err := next.blob.ToData() + if err != nil { + ds.log.Error("ignoring blob due to parse failure", "err", err) + return ds.Next(ctx) + } + return data, nil +} + +// open fetches and returns the blob or calldata (as appropriate) from all valid batcher +// transactions in the referenced block. Returns an empty (non-nil) array if no batcher +// transactions are found. It returns ResetError if it cannot find the referenced block or a +// referenced blob, or TemporaryError for any other failure to fetch a block or blob. +func (ds *BlobDataSource) open(ctx context.Context) ([]blobOrCalldata, error) { + _, txs, err := ds.fetcher.InfoAndTxsByHash(ctx, ds.ref.Hash) + if err != nil { + if errors.Is(err, ethereum.NotFound) { + return nil, NewResetError(fmt.Errorf("failed to open blob data source: %w", err)) + } + return nil, NewTemporaryError(fmt.Errorf("failed to open blob data source: %w", err)) + } + + data, hashes := dataAndHashesFromTxs(txs, &ds.dsCfg, ds.batcherAddr) + + if len(hashes) == 0 { + // there are no blobs to fetch so we can return immediately + return data, nil + } + + // download the actual blob bodies corresponding to the indexed blob hashes + blobs, err := ds.blobsFetcher.GetBlobs(ctx, ds.ref, hashes) + if errors.Is(err, ethereum.NotFound) { + // If the L1 block was available, then the blobs should be available too. The only + // exception is if the blob retention window has expired, which we will ultimately handle + // by failing over to a blob archival service. + return nil, NewResetError(fmt.Errorf("failed to fetch blobs: %w", err)) + } else if err != nil { + return nil, NewTemporaryError(fmt.Errorf("failed to fetch blobs: %w", err)) + } + + // go back over the data array and populate the blob pointers + if err := fillBlobPointers(data, blobs); err != nil { + // this shouldn't happen unless there is a bug in the blobs fetcher + return nil, NewResetError(fmt.Errorf("failed to fill blob pointers: %w", err)) + } + return data, nil +} + +// dataAndHashesFromTxs extracts calldata and datahashes from the input transactions and returns them. It +// creates a placeholder blobOrCalldata element for each returned blob hash that must be populated +// by fillBlobPointers after blob bodies are retrieved. +func dataAndHashesFromTxs(txs types.Transactions, config *DataSourceConfig, batcherAddr common.Address) ([]blobOrCalldata, []eth.IndexedBlobHash) { + data := []blobOrCalldata{} + var hashes []eth.IndexedBlobHash + blobIndex := 0 // index of each blob in the block's blob sidecar + for _, tx := range txs { + // skip any non-batcher transactions + if !isValidBatchTx(tx, config.l1Signer, config.batchInboxAddress, batcherAddr) { + blobIndex += len(tx.BlobHashes()) + continue + } + // handle non-blob batcher transactions by extracting their calldata + if tx.Type() != types.BlobTxType { + calldata := eth.Data(tx.Data()) + data = append(data, blobOrCalldata{nil, &calldata}) + continue + } + // handle blob batcher transactions by extracting their blob hashes, ignoring any calldata. + if len(tx.Data()) > 0 { + log.Warn("blob tx has calldata, which will be ignored", "txhash", tx.Hash()) + } + for _, h := range tx.BlobHashes() { + idh := eth.IndexedBlobHash{ + Index: uint64(blobIndex), + Hash: h, + } + hashes = append(hashes, idh) + data = append(data, blobOrCalldata{nil, nil}) // will fill in blob pointers after we download them below + blobIndex += 1 + } + } + return data, hashes +} + +// fillBlobPointers goes back through the data array and fills in the pointers to the fetched blob +// bodies. There should be exactly one placeholder blobOrCalldata element for each blob, otherwise +// error is returned. +func fillBlobPointers(data []blobOrCalldata, blobs []*eth.Blob) error { + blobIndex := 0 + for i := range data { + if data[i].calldata != nil { + continue + } + if blobIndex >= len(blobs) { + return fmt.Errorf("didn't get enough blobs") + } + if blobs[blobIndex] == nil { + return fmt.Errorf("found a nil blob") + } + data[i].blob = blobs[blobIndex] + blobIndex++ + } + if blobIndex != len(blobs) { + return fmt.Errorf("got too many blobs") + } + return nil +} diff --git a/op-node/rollup/derive/blob_data_source_test.go b/op-node/rollup/derive/blob_data_source_test.go new file mode 100644 index 000000000000..aa9ef82cb991 --- /dev/null +++ b/op-node/rollup/derive/blob_data_source_test.go @@ -0,0 +1,137 @@ +package derive + +import ( + "crypto/ecdsa" + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testutils" +) + +func TestDataAndHashesFromTxs(t *testing.T) { + // test setup + rng := rand.New(rand.NewSource(12345)) + privateKey := testutils.InsecureRandomKey(rng) + publicKey, _ := privateKey.Public().(*ecdsa.PublicKey) + batcherAddr := crypto.PubkeyToAddress(*publicKey) + batchInboxAddr := testutils.RandomAddress(rng) + + chainId := new(big.Int).SetUint64(rng.Uint64()) + signer := types.NewCancunSigner(chainId) + config := DataSourceConfig{ + l1Signer: signer, + batchInboxAddress: batchInboxAddr, + } + + // create a valid non-blob batcher transaction and make sure it's picked up + txData := &types.LegacyTx{ + Nonce: rng.Uint64(), + GasPrice: new(big.Int).SetUint64(rng.Uint64()), + Gas: 2_000_000, + To: &batchInboxAddr, + Value: big.NewInt(10), + Data: testutils.RandomData(rng, rng.Intn(1000)), + } + calldataTx, _ := types.SignNewTx(privateKey, signer, txData) + txs := types.Transactions{calldataTx} + data, blobHashes := dataAndHashesFromTxs(txs, &config, batcherAddr) + require.Equal(t, 1, len(data)) + require.Equal(t, 0, len(blobHashes)) + + // create a valid blob batcher tx and make sure it's picked up + blobHash := testutils.RandomHash(rng) + blobTxData := &types.BlobTx{ + Nonce: rng.Uint64(), + Gas: 2_000_000, + To: batchInboxAddr, + Data: testutils.RandomData(rng, rng.Intn(1000)), + BlobHashes: []common.Hash{blobHash}, + } + blobTx, _ := types.SignNewTx(privateKey, signer, blobTxData) + txs = types.Transactions{blobTx} + data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr) + require.Equal(t, 1, len(data)) + require.Equal(t, 1, len(blobHashes)) + require.Nil(t, data[0].calldata) + + // try again with both the blob & calldata transactions and make sure both are picked up + txs = types.Transactions{blobTx, calldataTx} + data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr) + require.Equal(t, 2, len(data)) + require.Equal(t, 1, len(blobHashes)) + require.NotNil(t, data[1].calldata) + + // make sure blob tx to the batch inbox is ignored if not signed by the batcher + blobTx, _ = types.SignNewTx(testutils.RandomKey(), signer, blobTxData) + txs = types.Transactions{blobTx} + data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr) + require.Equal(t, 0, len(data)) + require.Equal(t, 0, len(blobHashes)) + + // make sure blob tx ignored if the tx isn't going to the batch inbox addr, even if the + // signature is valid. + blobTxData.To = testutils.RandomAddress(rng) + blobTx, _ = types.SignNewTx(privateKey, signer, blobTxData) + txs = types.Transactions{blobTx} + data, blobHashes = dataAndHashesFromTxs(txs, &config, batcherAddr) + require.Equal(t, 0, len(data)) + require.Equal(t, 0, len(blobHashes)) +} + +func TestFillBlobPointers(t *testing.T) { + blob := eth.Blob{} + rng := rand.New(rand.NewSource(1234)) + calldata := eth.Data{} + + for i := 0; i < 100; i++ { + // create a random length input data array w/ len = [0-10) + dataLen := rng.Intn(10) + data := make([]blobOrCalldata, dataLen) + + // pick some subset of those to be blobs, and the rest calldata + blobLen := 0 + if dataLen != 0 { + blobLen = rng.Intn(dataLen) + } + calldataLen := dataLen - blobLen + + // fill in the calldata entries at random indices + for j := 0; j < calldataLen; j++ { + randomIndex := rng.Intn(dataLen) + for data[randomIndex].calldata != nil { + randomIndex = (randomIndex + 1) % dataLen + } + data[randomIndex].calldata = &calldata + } + + // create the input blobs array and call fillBlobPointers on it + blobs := make([]*eth.Blob, blobLen) + for j := 0; j < blobLen; j++ { + blobs[j] = &blob + } + err := fillBlobPointers(data, blobs) + require.NoError(t, err) + + // check that we get the expected number of calldata vs blobs results + blobCount := 0 + calldataCount := 0 + for j := 0; j < dataLen; j++ { + if data[j].calldata != nil { + calldataCount++ + } + if data[j].blob != nil { + blobCount++ + } + } + require.Equal(t, blobLen, blobCount) + require.Equal(t, calldataLen, calldataCount) + } +} diff --git a/op-node/rollup/derive/calldata_source.go b/op-node/rollup/derive/calldata_source.go index ce914352be75..0a5d7915770d 100644 --- a/op-node/rollup/derive/calldata_source.go +++ b/op-node/rollup/derive/calldata_source.go @@ -11,81 +11,53 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/eth" ) -type DataIter interface { - Next(ctx context.Context) (eth.Data, error) -} - -type L1TransactionFetcher interface { - InfoAndTxsByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, types.Transactions, error) -} - -// DataSourceFactory readers raw transactions from a given block & then filters for -// batch submitter transactions. -// This is not a stage in the pipeline, but a wrapper for another stage in the pipeline -type DataSourceFactory struct { - log log.Logger - cfg *rollup.Config - fetcher L1TransactionFetcher -} - -func NewDataSourceFactory(log log.Logger, cfg *rollup.Config, fetcher L1TransactionFetcher) *DataSourceFactory { - return &DataSourceFactory{log: log, cfg: cfg, fetcher: fetcher} -} - -// OpenData returns a DataIter. This struct implements the `Next` function. -func (ds *DataSourceFactory) OpenData(ctx context.Context, id eth.BlockID, batcherAddr common.Address) DataIter { - return NewDataSource(ctx, ds.log, ds.cfg, ds.fetcher, id, batcherAddr) -} - -// DataSource is a fault tolerant approach to fetching data. +// CalldataSource is a fault tolerant approach to fetching data. // The constructor will never fail & it will instead re-attempt the fetcher // at a later point. -type DataSource struct { +type CalldataSource struct { // Internal state + data open bool data []eth.Data // Required to re-attempt fetching - id eth.BlockID - cfg *rollup.Config // TODO: `DataFromEVMTransactions` should probably not take the full config + ref eth.L1BlockRef + dsCfg DataSourceConfig fetcher L1TransactionFetcher log log.Logger batcherAddr common.Address } -// NewDataSource creates a new calldata source. It suppresses errors in fetching the L1 block if they occur. +// NewCalldataSource creates a new calldata source. It suppresses errors in fetching the L1 block if they occur. // If there is an error, it will attempt to fetch the result on the next call to `Next`. -func NewDataSource(ctx context.Context, log log.Logger, cfg *rollup.Config, fetcher L1TransactionFetcher, block eth.BlockID, batcherAddr common.Address) DataIter { - _, txs, err := fetcher.InfoAndTxsByHash(ctx, block.Hash) +func NewCalldataSource(ctx context.Context, log log.Logger, dsCfg DataSourceConfig, fetcher L1TransactionFetcher, ref eth.L1BlockRef, batcherAddr common.Address) DataIter { + _, txs, err := fetcher.InfoAndTxsByHash(ctx, ref.Hash) if err != nil { - return &DataSource{ + return &CalldataSource{ open: false, - id: block, - cfg: cfg, + ref: ref, + dsCfg: dsCfg, fetcher: fetcher, log: log, batcherAddr: batcherAddr, } - } else { - return &DataSource{ - open: true, - data: DataFromEVMTransactions(cfg, batcherAddr, txs, log.New("origin", block)), - } + } + return &CalldataSource{ + open: true, + data: DataFromEVMTransactions(dsCfg, batcherAddr, txs, log.New("origin", ref)), } } // Next returns the next piece of data if it has it. If the constructor failed, this // will attempt to reinitialize itself. If it cannot find the block it returns a ResetError // otherwise it returns a temporary error if fetching the block returns an error. -func (ds *DataSource) Next(ctx context.Context) (eth.Data, error) { +func (ds *CalldataSource) Next(ctx context.Context) (eth.Data, error) { if !ds.open { - if _, txs, err := ds.fetcher.InfoAndTxsByHash(ctx, ds.id.Hash); err == nil { + if _, txs, err := ds.fetcher.InfoAndTxsByHash(ctx, ds.ref.Hash); err == nil { ds.open = true - ds.data = DataFromEVMTransactions(ds.cfg, ds.batcherAddr, txs, log.New("origin", ds.id)) + ds.data = DataFromEVMTransactions(ds.dsCfg, ds.batcherAddr, txs, ds.log) } else if errors.Is(err, ethereum.NotFound) { return nil, NewResetError(fmt.Errorf("failed to open calldata source: %w", err)) } else { @@ -104,21 +76,10 @@ func (ds *DataSource) Next(ctx context.Context) (eth.Data, error) { // DataFromEVMTransactions filters all of the transactions and returns the calldata from transactions // that are sent to the batch inbox address from the batch sender address. // This will return an empty array if no valid transactions are found. -func DataFromEVMTransactions(config *rollup.Config, batcherAddr common.Address, txs types.Transactions, log log.Logger) []eth.Data { - var out []eth.Data - l1Signer := config.L1Signer() - for j, tx := range txs { - if to := tx.To(); to != nil && *to == config.BatchInboxAddress { - seqDataSubmitter, err := l1Signer.Sender(tx) // optimization: only derive sender if To is correct - if err != nil { - log.Warn("tx in inbox with invalid signature", "index", j, "err", err) - continue // bad signature, ignore - } - // some random L1 user might have sent a transaction to our batch inbox, ignore them - if seqDataSubmitter != batcherAddr { - log.Warn("tx in inbox with unauthorized submitter", "index", j, "err", err) - continue // not an authorized batch submitter, ignore - } +func DataFromEVMTransactions(dsCfg DataSourceConfig, batcherAddr common.Address, txs types.Transactions, log log.Logger) []eth.Data { + out := []eth.Data{} + for _, tx := range txs { + if isValidBatchTx(tx, dsCfg.l1Signer, dsCfg.batchInboxAddress, batcherAddr) { out = append(out, tx.Data()) } } diff --git a/op-node/rollup/derive/calldata_source_test.go b/op-node/rollup/derive/calldata_source_test.go index 9ec43aafef00..01b2616cca3f 100644 --- a/op-node/rollup/derive/calldata_source_test.go +++ b/op-node/rollup/derive/calldata_source_test.go @@ -121,7 +121,7 @@ func TestDataFromEVMTransactions(t *testing.T) { } } - out := DataFromEVMTransactions(cfg, batcherAddr, txs, testlog.Logger(t, log.LvlCrit)) + out := DataFromEVMTransactions(DataSourceConfig{cfg.L1Signer(), cfg.BatchInboxAddress, false}, batcherAddr, txs, testlog.Logger(t, log.LevelCrit)) require.ElementsMatch(t, expectedData, out) } diff --git a/op-node/rollup/derive/channel_bank_test.go b/op-node/rollup/derive/channel_bank_test.go index 495ce4426bb8..a4485834ece6 100644 --- a/op-node/rollup/derive/channel_bank_test.go +++ b/op-node/rollup/derive/channel_bank_test.go @@ -102,7 +102,7 @@ func TestChannelBankSimple(t *testing.T) { cfg := &rollup.Config{ChannelTimeout: 10} - cb := NewChannelBank(testlog.Logger(t, log.LvlCrit), cfg, input, nil, metrics.NoopMetrics) + cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, nil, metrics.NoopMetrics) // Load the first frame out, err := cb.NextData(context.Background()) @@ -146,7 +146,7 @@ func TestChannelBankInterleavedPreCanyon(t *testing.T) { cfg := &rollup.Config{ChannelTimeout: 10, CanyonTime: nil} - cb := NewChannelBank(testlog.Logger(t, log.LvlCrit), cfg, input, nil, metrics.NoopMetrics) + cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, nil, metrics.NoopMetrics) // Load a:0 out, err := cb.NextData(context.Background()) @@ -211,7 +211,7 @@ func TestChannelBankInterleaved(t *testing.T) { ct := uint64(0) cfg := &rollup.Config{ChannelTimeout: 10, CanyonTime: &ct} - cb := NewChannelBank(testlog.Logger(t, log.LvlCrit), cfg, input, nil, metrics.NoopMetrics) + cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, nil, metrics.NoopMetrics) // Load a:0 out, err := cb.NextData(context.Background()) @@ -271,7 +271,7 @@ func TestChannelBankDuplicates(t *testing.T) { cfg := &rollup.Config{ChannelTimeout: 10} - cb := NewChannelBank(testlog.Logger(t, log.LvlCrit), cfg, input, nil, metrics.NoopMetrics) + cb := NewChannelBank(testlog.Logger(t, log.LevelCrit), cfg, input, nil, metrics.NoopMetrics) // Load the first frame out, err := cb.NextData(context.Background()) diff --git a/op-node/rollup/derive/channel_in_reader.go b/op-node/rollup/derive/channel_in_reader.go index 24530b903e1f..ccbeccce469d 100644 --- a/op-node/rollup/derive/channel_in_reader.go +++ b/op-node/rollup/derive/channel_in_reader.go @@ -3,7 +3,6 @@ package derive import ( "bytes" "context" - "errors" "fmt" "io" @@ -92,24 +91,26 @@ func (cr *ChannelInReader) NextBatch(ctx context.Context) (Batch, error) { } switch batchData.GetBatchType() { case SingularBatchType: - singularBatch, ok := batchData.inner.(*SingularBatch) - if !ok { - return nil, NewCriticalError(errors.New("failed type assertion to SingularBatch")) + singularBatch, err := GetSingularBatch(batchData) + if err != nil { + return nil, err } + singularBatch.LogContext(cr.log).Debug("decoded singular batch from channel", "stage_origin", cr.Origin()) + cr.metrics.RecordDerivedBatches("singular") return singularBatch, nil case SpanBatchType: - if origin := cr.Origin(); !cr.cfg.IsSpanBatch(origin.Time) { + if origin := cr.Origin(); !cr.cfg.IsDelta(origin.Time) { + // Check hard fork activation with the L1 inclusion block time instead of the L1 origin block time. + // Therefore, even if the batch passed this rule, it can be dropped in the batch queue. + // This is just for early dropping invalid batches as soon as possible. return nil, NewTemporaryError(fmt.Errorf("cannot accept span batch in L1 block %s at time %d", origin, origin.Time)) } - rawSpanBatch, ok := batchData.inner.(*RawSpanBatch) - if !ok { - return nil, NewCriticalError(errors.New("failed type assertion to SpanBatch")) - } - // If the batch type is Span batch, derive block inputs from RawSpanBatch. - spanBatch, err := rawSpanBatch.derive(cr.cfg.BlockTime, cr.cfg.Genesis.L2Time, cr.cfg.L2ChainID) + spanBatch, err := DeriveSpanBatch(batchData, cr.cfg.BlockTime, cr.cfg.Genesis.L2Time, cr.cfg.L2ChainID) if err != nil { return nil, err } + spanBatch.LogContext(cr.log).Debug("decoded span batch from channel", "stage_origin", cr.Origin()) + cr.metrics.RecordDerivedBatches("span") return spanBatch, nil default: // error is bubbled up to user, but pipeline can skip the batch and continue after. diff --git a/op-node/rollup/derive/channel_out.go b/op-node/rollup/derive/channel_out.go index e932b9524ba7..52fd2fb36da0 100644 --- a/op-node/rollup/derive/channel_out.go +++ b/op-node/rollup/derive/channel_out.go @@ -16,12 +16,13 @@ import ( var ErrMaxFrameSizeTooSmall = errors.New("maxSize is too small to fit the fixed frame overhead") var ErrNotDepositTx = errors.New("first transaction in block is not a deposit tx") var ErrTooManyRLPBytes = errors.New("batch would cause RLP bytes to go over limit") +var ErrChannelOutAlreadyClosed = errors.New("channel-out already closed") // FrameV0OverHeadSize is the absolute minimum size of a frame. // This is the fixed overhead frame size, calculated as specified // in the [Frame Format] specs: 16 + 2 + 4 + 1 = 23 bytes. // -// [Frame Format]: https://github.com/ethereum-optimism/optimism/blob/develop/specs/derivation.md#frame-format +// [Frame Format]: https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/derivation.md#frame-format const FrameV0OverHeadSize = 23 var CompressorFullErr = errors.New("compressor is full") @@ -51,7 +52,7 @@ type Compressor interface { type ChannelOut interface { ID() ChannelID Reset() error - AddBlock(*types.Block) (uint64, error) + AddBlock(*rollup.Config, *types.Block) (uint64, error) AddSingularBatch(*SingularBatch, uint64) (uint64, error) InputBytes() int ReadyBytes() int @@ -117,12 +118,12 @@ func (co *SingularChannelOut) Reset() error { // and an error if there is a problem adding the block. The only sentinel error // that it returns is ErrTooManyRLPBytes. If this error is returned, the channel // should be closed and a new one should be made. -func (co *SingularChannelOut) AddBlock(block *types.Block) (uint64, error) { +func (co *SingularChannelOut) AddBlock(rollupCfg *rollup.Config, block *types.Block) (uint64, error) { if co.closed { - return 0, errors.New("already closed") + return 0, ErrChannelOutAlreadyClosed } - batch, l1Info, err := BlockToSingularBatch(block) + batch, l1Info, err := BlockToSingularBatch(rollupCfg, block) if err != nil { return 0, err } @@ -139,7 +140,7 @@ func (co *SingularChannelOut) AddBlock(block *types.Block) (uint64, error) { // the batch data with AddBlock. func (co *SingularChannelOut) AddSingularBatch(batch *SingularBatch, _ uint64) (uint64, error) { if co.closed { - return 0, errors.New("already closed") + return 0, ErrChannelOutAlreadyClosed } // We encode to a temporary buffer to determine the encoded length to @@ -183,7 +184,7 @@ func (co *SingularChannelOut) FullErr() error { func (co *SingularChannelOut) Close() error { if co.closed { - return errors.New("already closed") + return ErrChannelOutAlreadyClosed } co.closed = true return co.compress.Close() @@ -222,7 +223,11 @@ func (co *SingularChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) (uint } // BlockToSingularBatch transforms a block into a batch object that can easily be RLP encoded. -func BlockToSingularBatch(block *types.Block) (*SingularBatch, L1BlockInfo, error) { +func BlockToSingularBatch(rollupCfg *rollup.Config, block *types.Block) (*SingularBatch, *L1BlockInfo, error) { + if len(block.Transactions()) == 0 { + return nil, nil, fmt.Errorf("block %v has no transactions", block.Hash()) + } + opaqueTxs := make([]hexutil.Bytes, 0, len(block.Transactions())) for i, tx := range block.Transactions() { if tx.Type() == types.DepositTxType { @@ -230,18 +235,16 @@ func BlockToSingularBatch(block *types.Block) (*SingularBatch, L1BlockInfo, erro } otx, err := tx.MarshalBinary() if err != nil { - return nil, L1BlockInfo{}, fmt.Errorf("could not encode tx %v in block %v: %w", i, tx.Hash(), err) + return nil, nil, fmt.Errorf("could not encode tx %v in block %v: %w", i, tx.Hash(), err) } opaqueTxs = append(opaqueTxs, otx) } - if len(block.Transactions()) == 0 { - return nil, L1BlockInfo{}, fmt.Errorf("block %v has no transactions", block.Hash()) - } + l1InfoTx := block.Transactions()[0] if l1InfoTx.Type() != types.DepositTxType { - return nil, L1BlockInfo{}, ErrNotDepositTx + return nil, nil, ErrNotDepositTx } - l1Info, err := L1InfoDepositTxData(l1InfoTx.Data()) + l1Info, err := L1BlockInfoFromBytes(rollupCfg, block.Time(), l1InfoTx.Data()) if err != nil { return nil, l1Info, fmt.Errorf("could not parse the L1 Info deposit: %w", err) } @@ -319,10 +322,10 @@ func createEmptyFrame(id ChannelID, frame uint64, readyBytes int, closed bool, m // Copy data from the local buffer into the frame data buffer maxDataSize := maxSize - FrameV0OverHeadSize - if maxDataSize > uint64(readyBytes) { + if maxDataSize >= uint64(readyBytes) { maxDataSize = uint64(readyBytes) // If we are closed & will not spill past the current frame - // mark it is the final frame of the channel. + // mark it as the final frame of the channel. if closed { f.IsLast = true } diff --git a/op-node/rollup/derive/channel_out_test.go b/op-node/rollup/derive/channel_out_test.go index 0eef4a241c1b..7e6bc04cb06c 100644 --- a/op-node/rollup/derive/channel_out_test.go +++ b/op-node/rollup/derive/channel_out_test.go @@ -2,13 +2,21 @@ package derive import ( "bytes" + "io" "math/big" + "math/rand" "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/op-node/rollup" +) + +var ( + rollupCfg rollup.Config ) // basic implementation of the Compressor interface that does no compression @@ -40,7 +48,7 @@ func TestChannelOutAddBlock(t *testing.T) { }, nil, ) - _, err := cout.AddBlock(block) + _, err := cout.AddBlock(&rollupCfg, block) require.Error(t, err) require.Equal(t, ErrNotDepositTx, err) }) @@ -62,6 +70,27 @@ func TestOutputFrameSmallMaxSize(t *testing.T) { } } +func TestOutputFrameNoEmptyLastFrame(t *testing.T) { + cout, err := NewChannelOut(SingularBatchType, &nonCompressor{}, nil) + require.NoError(t, err) + + rng := rand.New(rand.NewSource(0x543331)) + chainID := big.NewInt(rng.Int63n(1000)) + txCount := 1 + singularBatch := RandomSingularBatch(rng, txCount, chainID) + + written, err := cout.AddSingularBatch(singularBatch, 0) + require.NoError(t, err) + + require.NoError(t, cout.Close()) + + var buf bytes.Buffer + // Output a frame which needs exactly `written` bytes. This frame is expected to be the last frame. + _, err = cout.OutputFrame(&buf, written+FrameV0OverHeadSize) + require.ErrorIs(t, err, io.EOF) + +} + // TestRLPByteLimit ensures that stream encoder is properly limiting the length. // It will decode the input if `len(input) <= inputLimit`. func TestRLPByteLimit(t *testing.T) { @@ -152,6 +181,6 @@ func TestForceCloseTxData(t *testing.T) { func TestBlockToBatchValidity(t *testing.T) { block := new(types.Block) - _, _, err := BlockToSingularBatch(block) + _, _, err := BlockToSingularBatch(&rollupCfg, block) require.ErrorContains(t, err, "has no transactions") } diff --git a/op-node/rollup/derive/data_source.go b/op-node/rollup/derive/data_source.go new file mode 100644 index 000000000000..2a1dbd7c00de --- /dev/null +++ b/op-node/rollup/derive/data_source.go @@ -0,0 +1,116 @@ +package derive + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + plasma "github.com/ethereum-optimism/optimism/op-plasma" + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type DataIter interface { + Next(ctx context.Context) (eth.Data, error) +} + +type L1TransactionFetcher interface { + InfoAndTxsByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, types.Transactions, error) +} + +type L1BlobsFetcher interface { + // GetBlobs fetches blobs that were confirmed in the given L1 block with the given indexed hashes. + GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) +} + +type PlasmaInputFetcher interface { + // GetInput fetches the input for the given commitment at the given block number from the DA storage service. + GetInput(ctx context.Context, l1 plasma.L1Fetcher, c plasma.Keccak256Commitment, blockId eth.BlockID) (eth.Data, error) + // AdvanceL1Origin advances the L1 origin to the given block number, syncing the DA challenge events. + AdvanceL1Origin(ctx context.Context, l1 plasma.L1Fetcher, blockId eth.BlockID) error + // Reset the challenge origin in case of L1 reorg + Reset(ctx context.Context, base eth.L1BlockRef, baseCfg eth.SystemConfig) error + // Notify L1 finalized head so plasma finality is always behind L1 + Finalize(ref eth.L1BlockRef) + // Set the engine finalization signal callback + OnFinalizedHeadSignal(f plasma.HeadSignalFn) +} + +// DataSourceFactory reads raw transactions from a given block & then filters for +// batch submitter transactions. +// This is not a stage in the pipeline, but a wrapper for another stage in the pipeline +type DataSourceFactory struct { + log log.Logger + dsCfg DataSourceConfig + fetcher L1Fetcher + blobsFetcher L1BlobsFetcher + plasmaFetcher PlasmaInputFetcher + ecotoneTime *uint64 +} + +func NewDataSourceFactory(log log.Logger, cfg *rollup.Config, fetcher L1Fetcher, blobsFetcher L1BlobsFetcher, plasmaFetcher PlasmaInputFetcher) *DataSourceFactory { + config := DataSourceConfig{ + l1Signer: cfg.L1Signer(), + batchInboxAddress: cfg.BatchInboxAddress, + plasmaEnabled: cfg.UsePlasma, + } + return &DataSourceFactory{ + log: log, + dsCfg: config, + fetcher: fetcher, + blobsFetcher: blobsFetcher, + plasmaFetcher: plasmaFetcher, + ecotoneTime: cfg.EcotoneTime, + } +} + +// OpenData returns the appropriate data source for the L1 block `ref`. +func (ds *DataSourceFactory) OpenData(ctx context.Context, ref eth.L1BlockRef, batcherAddr common.Address) (DataIter, error) { + // Creates a data iterator from blob or calldata source so we can forward it to the plasma source + // if enabled as it still requires an L1 data source for fetching input commmitments. + var src DataIter + if ds.ecotoneTime != nil && ref.Time >= *ds.ecotoneTime { + if ds.blobsFetcher == nil { + return nil, fmt.Errorf("ecotone upgrade active but beacon endpoint not configured") + } + src = NewBlobDataSource(ctx, ds.log, ds.dsCfg, ds.fetcher, ds.blobsFetcher, ref, batcherAddr) + } else { + src = NewCalldataSource(ctx, ds.log, ds.dsCfg, ds.fetcher, ref, batcherAddr) + } + if ds.dsCfg.plasmaEnabled { + // plasma([calldata | blobdata](l1Ref)) -> data + return NewPlasmaDataSource(ds.log, src, ds.fetcher, ds.plasmaFetcher, ref.ID()), nil + } + return src, nil +} + +// DataSourceConfig regroups the mandatory rollup.Config fields needed for DataFromEVMTransactions. +type DataSourceConfig struct { + l1Signer types.Signer + batchInboxAddress common.Address + plasmaEnabled bool +} + +// isValidBatchTx returns true if: +// 1. the transaction has a To() address that matches the batch inbox address, and +// 2. the transaction has a valid signature from the batcher address +func isValidBatchTx(tx *types.Transaction, l1Signer types.Signer, batchInboxAddr, batcherAddr common.Address) bool { + to := tx.To() + if to == nil || *to != batchInboxAddr { + return false + } + seqDataSubmitter, err := l1Signer.Sender(tx) // optimization: only derive sender if To is correct + if err != nil { + log.Warn("tx in inbox with invalid signature", "hash", tx.Hash(), "err", err) + return false + } + // some random L1 user might have sent a transaction to our batch inbox, ignore them + if seqDataSubmitter != batcherAddr { + log.Warn("tx in inbox with unauthorized submitter", "addr", seqDataSubmitter, "hash", tx.Hash(), "err", err) + return false + } + return true +} diff --git a/op-node/rollup/derive/deposit_source.go b/op-node/rollup/derive/deposit_source.go index cb1642318431..f7a9730ad026 100644 --- a/op-node/rollup/derive/deposit_source.go +++ b/op-node/rollup/derive/deposit_source.go @@ -13,8 +13,9 @@ type UserDepositSource struct { } const ( - UserDepositSourceDomain = 0 - L1InfoDepositSourceDomain = 1 + UserDepositSourceDomain = 0 + L1InfoDepositSourceDomain = 1 + UpgradeDepositSourceDomain = 2 ) func (dep *UserDepositSource) SourceHash() common.Hash { @@ -44,3 +45,21 @@ func (dep *L1InfoDepositSource) SourceHash() common.Hash { copy(domainInput[32:], depositIDHash[:]) return crypto.Keccak256Hash(domainInput[:]) } + +// UpgradeDepositSource implements the translation of upgrade-tx identity information to a deposit source-hash, +// which makes the deposit uniquely identifiable. +// System-upgrade transactions have their own domain for source-hashes, +// to not conflict with user-deposits or deposited L1 information. +// The intent identifies the upgrade-tx uniquely, in a human-readable way. +type UpgradeDepositSource struct { + Intent string +} + +func (dep *UpgradeDepositSource) SourceHash() common.Hash { + intentHash := crypto.Keccak256Hash([]byte(dep.Intent)) + + var domainInput [32 * 2]byte + binary.BigEndian.PutUint64(domainInput[32-8:32], UpgradeDepositSourceDomain) + copy(domainInput[32:], intentHash[:]) + return crypto.Keccak256Hash(domainInput[:]) +} diff --git a/op-node/rollup/derive/deposit_source_test.go b/op-node/rollup/derive/deposit_source_test.go new file mode 100644 index 000000000000..10fb7048a2a2 --- /dev/null +++ b/op-node/rollup/derive/deposit_source_test.go @@ -0,0 +1,36 @@ +package derive + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +// TestEcotone4788ContractSourceHash +// cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Ecotone: L1 Block Proxy Update")) +// # 0x18acb38c5ff1c238a7460ebc1b421fa49ec4874bdf1e0a530d234104e5e67dbc +func TestDeposit(t *testing.T) { + source := UpgradeDepositSource{ + Intent: "Ecotone: L1 Block Proxy Update", + } + + actual := source.SourceHash() + expected := "0x18acb38c5ff1c238a7460ebc1b421fa49ec4874bdf1e0a530d234104e5e67dbc" + + assert.Equal(t, expected, actual.Hex()) +} + +// TestEcotone4788ContractSourceHash tests that the source-hash of the 4788 deposit deployment tx is correct. +// As per specs, the hash is computed as: +// cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Ecotone: beacon block roots contract deployment")) +// # 0x69b763c48478b9dc2f65ada09b3d92133ec592ea715ec65ad6e7f3dc519dc00c +func TestEcotone4788ContractSourceHash(t *testing.T) { + source := UpgradeDepositSource{ + Intent: "Ecotone: beacon block roots contract deployment", + } + + actual := source.SourceHash() + expected := "0x69b763c48478b9dc2f65ada09b3d92133ec592ea715ec65ad6e7f3dc519dc00c" + + assert.Equal(t, expected, actual.Hex()) +} diff --git a/op-node/rollup/derive/ecotone_upgrade_transactions.go b/op-node/rollup/derive/ecotone_upgrade_transactions.go new file mode 100644 index 000000000000..7b0d885025af --- /dev/null +++ b/op-node/rollup/derive/ecotone_upgrade_transactions.go @@ -0,0 +1,159 @@ +package derive + +import ( + "bytes" + "fmt" + "math/big" + + "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/crypto" + + "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-service/solabi" +) + +const UpgradeToFuncSignature = "upgradeTo(address)" + +var ( + // known address w/ zero txns + L1BlockDeployerAddress = common.HexToAddress("0x4210000000000000000000000000000000000000") + GasPriceOracleDeployerAddress = common.HexToAddress("0x4210000000000000000000000000000000000001") + + newL1BlockAddress = crypto.CreateAddress(L1BlockDeployerAddress, 0) + newGasPriceOracleAddress = crypto.CreateAddress(GasPriceOracleDeployerAddress, 0) + + deployL1BlockSource = UpgradeDepositSource{Intent: "Ecotone: L1 Block Deployment"} + deployGasPriceOracleSource = UpgradeDepositSource{Intent: "Ecotone: Gas Price Oracle Deployment"} + updateL1BlockProxySource = UpgradeDepositSource{Intent: "Ecotone: L1 Block Proxy Update"} + updateGasPriceOracleSource = UpgradeDepositSource{Intent: "Ecotone: Gas Price Oracle Proxy Update"} + enableEcotoneSource = UpgradeDepositSource{Intent: "Ecotone: Gas Price Oracle Set Ecotone"} + beaconRootsSource = UpgradeDepositSource{Intent: "Ecotone: beacon block roots contract deployment"} + + enableEcotoneInput = crypto.Keccak256([]byte("setEcotone()"))[:4] + + EIP4788From = common.HexToAddress("0x0B799C86a49DEeb90402691F1041aa3AF2d3C875") + eip4788CreationData = common.FromHex("0x60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500") + UpgradeToFuncBytes4 = crypto.Keccak256([]byte(UpgradeToFuncSignature))[:4] + + l1BlockDeploymentBytecode = common.FromHex("0x608060405234801561001057600080fd5b5061053e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638381f58a11610097578063c598591811610066578063c598591814610229578063e591b28214610249578063e81b2c6d14610289578063f82061401461029257600080fd5b80638381f58a146101e35780638b239f73146101f75780639e8c496614610200578063b80777ea1461020957600080fd5b806354fd4d50116100d357806354fd4d50146101335780635cf249691461017c57806364ca23ef1461018557806368d5dca6146101b257600080fd5b8063015d8eb9146100fa57806309bd5a601461010f578063440a5e201461012b575b600080fd5b61010d61010836600461044c565b61029b565b005b61011860025481565b6040519081526020015b60405180910390f35b61010d6103da565b61016f6040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161012291906104be565b61011860015481565b6003546101999067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610122565b6003546101ce9068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610122565b6000546101999067ffffffffffffffff1681565b61011860055481565b61011860065481565b6000546101999068010000000000000000900467ffffffffffffffff1681565b6003546101ce906c01000000000000000000000000900463ffffffff1681565b61026473deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b61011860045481565b61011860075481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b3373deaddeaddeaddeaddeaddeaddeaddeaddead00011461040357633cc50b456000526004601cfd5b60043560801c60035560143560801c600055602435600155604435600755606435600255608435600455565b803567ffffffffffffffff8116811461044757600080fd5b919050565b600080600080600080600080610100898b03121561046957600080fd5b6104728961042f565b975061048060208a0161042f565b9650604089013595506060890135945061049c60808a0161042f565b979a969950949793969560a0850135955060c08501359460e001359350915050565b600060208083528351808285015260005b818110156104eb578581018301518582016040015282016104cf565b818111156104fd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a") + gasPriceOracleDeploymentBytecode = common.FromHex("0x608060405234801561001057600080fd5b50610fb5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806354fd4d5011610097578063de26c4a111610066578063de26c4a1146101da578063f45e65d8146101ed578063f8206140146101f5578063fe173b97146101cc57600080fd5b806354fd4d501461016657806368d5dca6146101af5780636ef25c3a146101cc578063c5985918146101d257600080fd5b8063313ce567116100d3578063313ce5671461012757806349948e0e1461012e5780634ef6e22414610141578063519b4bd31461015e57600080fd5b80630c18c162146100fa57806322b90ab3146101155780632e0f26251461011f575b600080fd5b6101026101fd565b6040519081526020015b60405180910390f35b61011d61031e565b005b610102600681565b6006610102565b61010261013c366004610b73565b610541565b60005461014e9060ff1681565b604051901515815260200161010c565b610102610565565b6101a26040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161010c9190610c42565b6101b76105c6565b60405163ffffffff909116815260200161010c565b48610102565b6101b761064b565b6101026101e8366004610b73565b6106ac565b610102610760565b610102610853565b6000805460ff1615610296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f47617350726963654f7261636c653a206f76657268656164282920697320646560448201527f707265636174656400000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610cb5565b905090565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663e591b2826040518163ffffffff1660e01b8152600401602060405180830381865afa15801561037d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a19190610cce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610481576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f47617350726963654f7261636c653a206f6e6c7920746865206465706f73697460448201527f6f72206163636f756e742063616e2073657420697345636f746f6e6520666c6160648201527f6700000000000000000000000000000000000000000000000000000000000000608482015260a40161028d565b60005460ff1615610514576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a2045636f746f6e6520616c72656164792060448201527f6163746976650000000000000000000000000000000000000000000000000000606482015260840161028d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000805460ff161561055c57610556826108b4565b92915050565b61055682610958565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff166368d5dca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610d04565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663c59859186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b6000806106b883610ab4565b60005490915060ff16156106cc5792915050565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074f9190610cb5565b6107599082610d59565b9392505050565b6000805460ff16156107f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a207363616c61722829206973206465707260448201527f6563617465640000000000000000000000000000000000000000000000000000606482015260840161028d565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663f82061406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b6000806108c083610ab4565b905060006108cc610565565b6108d461064b565b6108df906010610d71565b63ffffffff166108ef9190610d9d565b905060006108fb610853565b6109036105c6565b63ffffffff166109139190610d9d565b905060006109218284610d59565b61092b9085610d9d565b90506109396006600a610efa565b610944906010610d9d565b61094e9082610f06565b9695505050505050565b60008061096483610ab4565b9050600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109eb9190610cb5565b6109f3610565565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a769190610cb5565b610a809085610d59565b610a8a9190610d9d565b610a949190610d9d565b9050610aa26006600a610efa565b610aac9082610f06565b949350505050565b80516000908190815b81811015610b3757848181518110610ad757610ad7610f41565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016600003610b1757610b10600484610d59565b9250610b25565b610b22601084610d59565b92505b80610b2f81610f70565b915050610abd565b50610aac82610440610d59565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610b8557600080fd5b813567ffffffffffffffff80821115610b9d57600080fd5b818401915084601f830112610bb157600080fd5b813581811115610bc357610bc3610b44565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610c0957610c09610b44565b81604052828152876020848701011115610c2257600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b81811115610c81576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600060208284031215610cc757600080fd5b5051919050565b600060208284031215610ce057600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461075957600080fd5b600060208284031215610d1657600080fd5b815163ffffffff8116811461075957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610d6c57610d6c610d2a565b500190565b600063ffffffff80831681851681830481118215151615610d9457610d94610d2a565b02949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610dd557610dd5610d2a565b500290565b600181815b80851115610e3357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610e1957610e19610d2a565b80851615610e2657918102915b93841c9390800290610ddf565b509250929050565b600082610e4a57506001610556565b81610e5757506000610556565b8160018114610e6d5760028114610e7757610e93565b6001915050610556565b60ff841115610e8857610e88610d2a565b50506001821b610556565b5060208310610133831016604e8410600b8410161715610eb6575081810a610556565b610ec08383610dda565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610ef257610ef2610d2a565b029392505050565b60006107598383610e3b565b600082610f3c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610fa157610fa1610d2a565b506001019056fea164736f6c634300080f000a") +) + +func EcotoneNetworkUpgradeTransactions() ([]hexutil.Bytes, error) { + upgradeTxns := make([]hexutil.Bytes, 0, 6) + + deployL1BlockTransaction, err := types.NewTx(&types.DepositTx{ + SourceHash: deployL1BlockSource.SourceHash(), + From: L1BlockDeployerAddress, + To: nil, + Mint: big.NewInt(0), + Value: big.NewInt(0), + Gas: 375_000, + IsSystemTransaction: false, + Data: l1BlockDeploymentBytecode, + }).MarshalBinary() + + if err != nil { + return nil, err + } + + upgradeTxns = append(upgradeTxns, deployL1BlockTransaction) + + deployGasPriceOracle, err := types.NewTx(&types.DepositTx{ + SourceHash: deployGasPriceOracleSource.SourceHash(), + From: GasPriceOracleDeployerAddress, + To: nil, + Mint: big.NewInt(0), + Value: big.NewInt(0), + Gas: 1_000_000, + IsSystemTransaction: false, + Data: gasPriceOracleDeploymentBytecode, + }).MarshalBinary() + + if err != nil { + return nil, err + } + + upgradeTxns = append(upgradeTxns, deployGasPriceOracle) + + updateL1BlockProxy, err := types.NewTx(&types.DepositTx{ + SourceHash: updateL1BlockProxySource.SourceHash(), + From: common.Address{}, + To: &predeploys.L1BlockAddr, + Mint: big.NewInt(0), + Value: big.NewInt(0), + Gas: 50_000, + IsSystemTransaction: false, + Data: upgradeToCalldata(newL1BlockAddress), + }).MarshalBinary() + + if err != nil { + return nil, err + } + + upgradeTxns = append(upgradeTxns, updateL1BlockProxy) + + updateGasPriceOracleProxy, err := types.NewTx(&types.DepositTx{ + SourceHash: updateGasPriceOracleSource.SourceHash(), + From: common.Address{}, + To: &predeploys.GasPriceOracleAddr, + Mint: big.NewInt(0), + Value: big.NewInt(0), + Gas: 50_000, + IsSystemTransaction: false, + Data: upgradeToCalldata(newGasPriceOracleAddress), + }).MarshalBinary() + + if err != nil { + return nil, err + } + + upgradeTxns = append(upgradeTxns, updateGasPriceOracleProxy) + + enableEcotone, err := types.NewTx(&types.DepositTx{ + SourceHash: enableEcotoneSource.SourceHash(), + From: L1InfoDepositerAddress, + To: &predeploys.GasPriceOracleAddr, + Mint: big.NewInt(0), + Value: big.NewInt(0), + Gas: 80_000, + IsSystemTransaction: false, + Data: enableEcotoneInput, + }).MarshalBinary() + if err != nil { + return nil, err + } + upgradeTxns = append(upgradeTxns, enableEcotone) + + deployEIP4788, err := types.NewTx(&types.DepositTx{ + From: EIP4788From, + To: nil, // contract-deployment tx + Mint: big.NewInt(0), + Value: big.NewInt(0), + Gas: 0x3d090, // hex constant, as defined in EIP-4788 + Data: eip4788CreationData, + IsSystemTransaction: false, + SourceHash: beaconRootsSource.SourceHash(), + }).MarshalBinary() + + if err != nil { + return nil, err + } + + upgradeTxns = append(upgradeTxns, deployEIP4788) + + return upgradeTxns, nil +} + +func upgradeToCalldata(addr common.Address) []byte { + buf := bytes.NewBuffer(make([]byte, 0, 4+20)) + if err := solabi.WriteSignature(buf, UpgradeToFuncBytes4); err != nil { + panic(fmt.Errorf("failed to write upgradeTo signature data: %w", err)) + } + if err := solabi.WriteAddress(buf, addr); err != nil { + panic(fmt.Errorf("failed to write upgradeTo address data: %w", err)) + } + return buf.Bytes() +} diff --git a/op-node/rollup/derive/ecotone_upgrade_transactions_test.go b/op-node/rollup/derive/ecotone_upgrade_transactions_test.go new file mode 100644 index 000000000000..13f8f237bed2 --- /dev/null +++ b/op-node/rollup/derive/ecotone_upgrade_transactions_test.go @@ -0,0 +1,120 @@ +package derive + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" +) + +func TestSourcesMatchSpec(t *testing.T) { + for _, test := range []struct { + source UpgradeDepositSource + expectedHash string + }{ + { + source: deployL1BlockSource, + expectedHash: "0x877a6077205782ea15a6dc8699fa5ebcec5e0f4389f09cb8eda09488231346f8", + }, + { + source: deployGasPriceOracleSource, + expectedHash: "0xa312b4510adf943510f05fcc8f15f86995a5066bd83ce11384688ae20e6ecf42", + }, + { + source: updateL1BlockProxySource, + expectedHash: "0x18acb38c5ff1c238a7460ebc1b421fa49ec4874bdf1e0a530d234104e5e67dbc", + }, + { + source: updateGasPriceOracleSource, + expectedHash: "0xee4f9385eceef498af0be7ec5862229f426dec41c8d42397c7257a5117d9230a", + }, + { + source: enableEcotoneSource, + expectedHash: "0x0c1cb38e99dbc9cbfab3bb80863380b0905290b37eb3d6ab18dc01c1f3e75f93", + }, + { + source: beaconRootsSource, + expectedHash: "0x69b763c48478b9dc2f65ada09b3d92133ec592ea715ec65ad6e7f3dc519dc00c", + }, + } { + require.Equal(t, common.HexToHash(test.expectedHash), test.source.SourceHash()) + } +} + +func toDepositTxn(t *testing.T, data hexutil.Bytes) (common.Address, *types.Transaction) { + txn := new(types.Transaction) + err := txn.UnmarshalBinary(data) + require.NoError(t, err) + require.Truef(t, txn.IsDepositTx(), "expected deposit txn, got %v", txn.Type()) + require.False(t, txn.IsSystemTx()) + + signer := types.NewLondonSigner(big.NewInt(420)) + from, err := signer.Sender(txn) + require.NoError(t, err) + + return from, txn +} + +func TestEcotoneNetworkTransactions(t *testing.T) { + upgradeTxns, err := EcotoneNetworkUpgradeTransactions() + require.NoError(t, err) + require.Len(t, upgradeTxns, 6) + + deployL1BlockSender, deployL1Block := toDepositTxn(t, upgradeTxns[0]) + require.Equal(t, deployL1BlockSender, common.HexToAddress("0x4210000000000000000000000000000000000000")) + require.Equal(t, deployL1BlockSource.SourceHash(), deployL1Block.SourceHash()) + require.Nil(t, deployL1Block.To()) + require.Equal(t, uint64(375_000), deployL1Block.Gas()) + require.Equal(t, bindings.L1BlockMetaData.Bin, hexutil.Bytes(deployL1Block.Data()).String()) + + deployGasPriceOracleSender, deployGasPriceOracle := toDepositTxn(t, upgradeTxns[1]) + require.Equal(t, deployGasPriceOracleSender, common.HexToAddress("0x4210000000000000000000000000000000000001")) + require.Equal(t, deployGasPriceOracleSource.SourceHash(), deployGasPriceOracle.SourceHash()) + require.Nil(t, deployGasPriceOracle.To()) + require.Equal(t, uint64(1_000_000), deployGasPriceOracle.Gas()) + require.Equal(t, bindings.GasPriceOracleMetaData.Bin, hexutil.Bytes(deployGasPriceOracle.Data()).String()) + + updateL1BlockProxySender, updateL1BlockProxy := toDepositTxn(t, upgradeTxns[2]) + require.Equal(t, updateL1BlockProxySender, common.Address{}) + require.Equal(t, updateL1BlockProxySource.SourceHash(), updateL1BlockProxy.SourceHash()) + require.NotNil(t, updateL1BlockProxy.To()) + require.Equal(t, *updateL1BlockProxy.To(), common.HexToAddress("0x4200000000000000000000000000000000000015")) + require.Equal(t, uint64(50_000), updateL1BlockProxy.Gas()) + require.Equal(t, common.FromHex("0x3659cfe600000000000000000000000007dbe8500fc591d1852b76fee44d5a05e13097ff"), updateL1BlockProxy.Data()) + + updateGasPriceOracleSender, updateGasPriceOracle := toDepositTxn(t, upgradeTxns[3]) + require.Equal(t, updateGasPriceOracleSender, common.Address{}) + require.Equal(t, updateGasPriceOracleSource.SourceHash(), updateGasPriceOracle.SourceHash()) + require.NotNil(t, updateGasPriceOracle.To()) + require.Equal(t, *updateGasPriceOracle.To(), common.HexToAddress("0x420000000000000000000000000000000000000F")) + require.Equal(t, uint64(50_000), updateGasPriceOracle.Gas()) + require.Equal(t, common.FromHex("0x3659cfe6000000000000000000000000b528d11cc114e026f138fe568744c6d45ce6da7a"), updateGasPriceOracle.Data()) + + gpoSetEcotoneSender, gpoSetEcotone := toDepositTxn(t, upgradeTxns[4]) + require.Equal(t, gpoSetEcotoneSender, common.HexToAddress("0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001")) + require.Equal(t, enableEcotoneSource.SourceHash(), gpoSetEcotone.SourceHash()) + require.NotNil(t, gpoSetEcotone.To()) + require.Equal(t, *gpoSetEcotone.To(), common.HexToAddress("0x420000000000000000000000000000000000000F")) + require.Equal(t, uint64(80_000), gpoSetEcotone.Gas()) + require.Equal(t, common.FromHex("0x22b90ab3"), gpoSetEcotone.Data()) + + beaconRootsSender, beaconRoots := toDepositTxn(t, upgradeTxns[5]) + require.Equal(t, beaconRootsSender, common.HexToAddress("0x0B799C86a49DEeb90402691F1041aa3AF2d3C875")) + require.Equal(t, beaconRootsSource.SourceHash(), beaconRoots.SourceHash()) + require.Nil(t, beaconRoots.To()) + require.Equal(t, uint64(250_000), beaconRoots.Gas()) + require.Equal(t, eip4788CreationData, beaconRoots.Data()) + require.NotEmpty(t, beaconRoots.Data()) +} + +func TestEip4788Params(t *testing.T) { + require.Equal(t, EIP4788From, common.HexToAddress("0x0B799C86a49DEeb90402691F1041aa3AF2d3C875")) + require.Equal(t, eip4788CreationData, common.FromHex("0x60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500")) + require.NotEmpty(t, eip4788CreationData) +} diff --git a/op-node/rollup/derive/engine_consolidate.go b/op-node/rollup/derive/engine_consolidate.go index ecac3684e194..121a7403257a 100644 --- a/op-node/rollup/derive/engine_consolidate.go +++ b/op-node/rollup/derive/engine_consolidate.go @@ -9,12 +9,15 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/eth" ) // AttributesMatchBlock checks if the L2 attributes pre-inputs match the output // nil if it is a match. If err is not nil, the error contains the reason for the mismatch -func AttributesMatchBlock(attrs *eth.PayloadAttributes, parentHash common.Hash, block *eth.ExecutionPayload, l log.Logger) error { +func AttributesMatchBlock(rollupCfg *rollup.Config, attrs *eth.PayloadAttributes, parentHash common.Hash, envelope *eth.ExecutionPayloadEnvelope, l log.Logger) error { + block := envelope.ExecutionPayload + if parentHash != block.ParentHash { return fmt.Errorf("parent hash field does not match. expected: %v. got: %v", parentHash, block.ParentHash) } @@ -25,12 +28,22 @@ func AttributesMatchBlock(attrs *eth.PayloadAttributes, parentHash common.Hash, return fmt.Errorf("random field does not match. expected: %v. got: %v", attrs.PrevRandao, block.PrevRandao) } if len(attrs.Transactions) != len(block.Transactions) { + missingSafeHashes, missingUnsafeHashes, err := getMissingTxnHashes(l, attrs.Transactions, block.Transactions) + if err != nil { + l.Error("failed to get missing txn hashes", "err", err) + } else { + l.Error("mismatched hashes", + "missingSafeHashes", missingSafeHashes, + "missingUnsafeHashes", missingUnsafeHashes, + ) + } + return fmt.Errorf("transaction count does not match. expected: %d. got: %d", len(attrs.Transactions), len(block.Transactions)) } for i, otx := range attrs.Transactions { if expect := block.Transactions[i]; !bytes.Equal(otx, expect) { if i == 0 { - logL1InfoTxns(l, uint64(block.BlockNumber), uint64(block.Timestamp), otx, block.Transactions[i]) + logL1InfoTxns(rollupCfg, l, uint64(block.BlockNumber), uint64(block.Timestamp), otx, block.Transactions[i]) } return fmt.Errorf("transaction %d does not match. expected: %v. got: %v", i, expect, otx) } @@ -44,6 +57,24 @@ func AttributesMatchBlock(attrs *eth.PayloadAttributes, parentHash common.Hash, if withdrawalErr := checkWithdrawalsMatch(attrs.Withdrawals, block.Withdrawals); withdrawalErr != nil { return withdrawalErr } + if err := checkParentBeaconBlockRootMatch(attrs.ParentBeaconBlockRoot, envelope.ParentBeaconBlockRoot); err != nil { + return err + } + return nil +} + +func checkParentBeaconBlockRootMatch(attrRoot, blockRoot *common.Hash) error { + if blockRoot == nil { + if attrRoot != nil { + return fmt.Errorf("expected non-nil parent beacon block root %s but got nil", *attrRoot) + } + } else { + if attrRoot == nil { + return fmt.Errorf("expected nil parent beacon block root but got non-nil %s", *blockRoot) + } else if *blockRoot != *attrRoot { + return fmt.Errorf("parent beacon block root does not match. expected %s. got: %s", *attrRoot, *blockRoot) + } + } return nil } @@ -77,7 +108,7 @@ func checkWithdrawalsMatch(attrWithdrawals *types.Withdrawals, blockWithdrawals // logL1InfoTxns reports the values from the L1 info tx when they differ to aid // debugging. This check is the one that has been most frequently triggered. -func logL1InfoTxns(l log.Logger, l2Number, l2Timestamp uint64, safeTx, unsafeTx hexutil.Bytes) { +func logL1InfoTxns(rollupCfg *rollup.Config, l log.Logger, l2Number, l2Timestamp uint64, safeTx, unsafeTx hexutil.Bytes) { // First decode into *types.Transaction to get the tx data. var safeTxValue, unsafeTxValue types.Transaction errSafe := (&safeTxValue).UnmarshalBinary(safeTx) @@ -88,21 +119,79 @@ func logL1InfoTxns(l log.Logger, l2Number, l2Timestamp uint64, safeTx, unsafeTx } // Then decode the ABI encoded parameters - var safeInfo, unsafeInfo L1BlockInfo - errSafe = (&safeInfo).UnmarshalBinary(safeTxValue.Data()) - errUnsafe = (&unsafeInfo).UnmarshalBinary(unsafeTxValue.Data()) + safeInfo, errSafe := L1BlockInfoFromBytes(rollupCfg, l2Timestamp, safeTxValue.Data()) + unsafeInfo, errUnsafe := L1BlockInfoFromBytes(rollupCfg, l2Timestamp, unsafeTxValue.Data()) if errSafe != nil || errUnsafe != nil { l.Error("failed to umarshal l1 info", "errSafe", errSafe, "errUnsafe", errUnsafe) return } - l.Error("L1 Info transaction differs", "number", l2Number, "time", l2Timestamp, + l = l.New("number", l2Number, "time", l2Timestamp, "safe_l1_number", safeInfo.Number, "safe_l1_hash", safeInfo.BlockHash, "safe_l1_time", safeInfo.Time, "safe_seq_num", safeInfo.SequenceNumber, - "safe_l1_basefee", safeInfo.BaseFee, "safe_batcher_add", safeInfo.BlockHash, - "safe_gpo_scalar", safeInfo.L1FeeScalar, "safe_gpo_overhead", safeInfo.L1FeeOverhead, + "safe_l1_basefee", safeInfo.BaseFee, "safe_batcher_addr", safeInfo.BatcherAddr, "unsafe_l1_number", unsafeInfo.Number, "unsafe_l1_hash", unsafeInfo.BlockHash, "unsafe_l1_time", unsafeInfo.Time, "unsafe_seq_num", unsafeInfo.SequenceNumber, - "unsafe_l1_basefee", unsafeInfo.BaseFee, "unsafe_batcher_add", unsafeInfo.BlockHash, - "unsafe_gpo_scalar", unsafeInfo.L1FeeScalar, "unsafe_gpo_overhead", unsafeInfo.L1FeeOverhead) + "unsafe_l1_basefee", unsafeInfo.BaseFee, "unsafe_batcher_addr", unsafeInfo.BatcherAddr, + ) + if bytes.HasPrefix(safeTxValue.Data(), types.EcotoneL1AttributesSelector) { + l.Error("L1 Info transaction differs", + "safe_l1_blob_basefee", safeInfo.BlobBaseFee, + "safe_l1_basefee_scalar", safeInfo.BaseFeeScalar, + "safe_l1_blob_basefee_scalar", safeInfo.BlobBaseFeeScalar, + "unsafe_l1_blob_basefee", unsafeInfo.BlobBaseFee, + "unsafe_l1_basefee_scalar", unsafeInfo.BaseFeeScalar, + "unsafe_l1_blob_basefee_scalar", unsafeInfo.BlobBaseFeeScalar) + } else { + l.Error("L1 Info transaction differs", + "safe_gpo_scalar", safeInfo.L1FeeScalar, "safe_gpo_overhead", safeInfo.L1FeeOverhead, + "unsafe_gpo_scalar", unsafeInfo.L1FeeScalar, "unsafe_gpo_overhead", unsafeInfo.L1FeeOverhead) + } +} + +func getMissingTxnHashes(l log.Logger, safeTxns, unsafeTxns []hexutil.Bytes) ([]common.Hash, []common.Hash, error) { + safeTxnHashes := make(map[common.Hash]struct{}, len(safeTxns)) + unsafeTxnHashes := make(map[common.Hash]struct{}, len(unsafeTxns)) + + for _, tx := range safeTxns { + safeTxValue := &types.Transaction{} + errSafe := safeTxValue.UnmarshalBinary(tx) + if errSafe != nil { + return nil, nil, fmt.Errorf("failed to unmarshal safe tx: %w", errSafe) + } + + if _, ok := safeTxnHashes[safeTxValue.Hash()]; ok { + l.Warn("duplicate safe tx value hash detected", "safeTxValueHash", safeTxValue.Hash()) + } + safeTxnHashes[safeTxValue.Hash()] = struct{}{} + } + + for _, tx := range unsafeTxns { + unsafeTxValue := &types.Transaction{} + errUnsafe := unsafeTxValue.UnmarshalBinary(tx) + if errUnsafe != nil { + return nil, nil, fmt.Errorf("failed to unmarshal unsafe tx: %w", errUnsafe) + } + + if _, ok := unsafeTxnHashes[unsafeTxValue.Hash()]; ok { + l.Warn("duplicate unsafe tx value hash detected", "unsafeTxValueHash", unsafeTxValue.Hash()) + } + unsafeTxnHashes[unsafeTxValue.Hash()] = struct{}{} + } + + missingUnsafeHashes := []common.Hash{} + for hash := range safeTxnHashes { + if _, ok := unsafeTxnHashes[hash]; !ok { + missingUnsafeHashes = append(missingUnsafeHashes, hash) + } + } + + missingSafeHashes := []common.Hash{} + for hash := range unsafeTxnHashes { + if _, ok := safeTxnHashes[hash]; !ok { + missingSafeHashes = append(missingSafeHashes, hash) + } + } + + return missingSafeHashes, missingUnsafeHashes, nil } diff --git a/op-node/rollup/derive/engine_consolidate_test.go b/op-node/rollup/derive/engine_consolidate_test.go index 9b54d89ea604..f67c331d36f7 100644 --- a/op-node/rollup/derive/engine_consolidate_test.go +++ b/op-node/rollup/derive/engine_consolidate_test.go @@ -1,13 +1,209 @@ package derive import ( + "math/rand" "testing" - "github.com/stretchr/testify/require" + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" + "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" + "github.com/stretchr/testify/require" ) +var ( + validParentHash = common.HexToHash("0x123") + validTimestamp = eth.Uint64Quantity(123) + validParentBeaconRoot = common.HexToHash("0x456") + validPrevRandao = eth.Bytes32(common.HexToHash("0x789")) + validGasLimit = eth.Uint64Quantity(1000) + validWithdrawals = types.Withdrawals{} +) + +type args struct { + envelope *eth.ExecutionPayloadEnvelope + attrs *eth.PayloadAttributes + parentHash common.Hash +} + +func ecotoneArgs() args { + return args{ + envelope: ð.ExecutionPayloadEnvelope{ + ParentBeaconBlockRoot: &validParentBeaconRoot, + ExecutionPayload: ð.ExecutionPayload{ + ParentHash: validParentHash, + Timestamp: validTimestamp, + PrevRandao: validPrevRandao, + GasLimit: validGasLimit, + Withdrawals: &validWithdrawals, + }, + }, + attrs: ð.PayloadAttributes{ + Timestamp: validTimestamp, + PrevRandao: validPrevRandao, + GasLimit: &validGasLimit, + ParentBeaconBlockRoot: &validParentBeaconRoot, + Withdrawals: &validWithdrawals, + }, + parentHash: validParentHash, + } +} + +func canyonArgs() args { + args := ecotoneArgs() + args.attrs.ParentBeaconBlockRoot = nil + args.envelope.ParentBeaconBlockRoot = nil + return args +} + +func bedrockArgs() args { + args := ecotoneArgs() + args.attrs.Withdrawals = nil + args.envelope.ExecutionPayload.Withdrawals = nil + return args +} + +func ecotoneNoParentBeaconBlockRoot() args { + args := ecotoneArgs() + args.envelope.ParentBeaconBlockRoot = nil + return args +} + +func ecotoneUnexpectedParentBeaconBlockRoot() args { + args := ecotoneArgs() + args.attrs.ParentBeaconBlockRoot = nil + return args +} + +func ecotoneMismatchParentBeaconBlockRoot() args { + args := ecotoneArgs() + h := common.HexToHash("0xabc") + args.attrs.ParentBeaconBlockRoot = &h + return args +} + +func ecotoneMismatchParentBeaconBlockRootPtr() args { + args := ecotoneArgs() + cpy := *args.attrs.ParentBeaconBlockRoot + args.attrs.ParentBeaconBlockRoot = &cpy + return args +} + +func ecotoneNilParentBeaconBlockRoots() args { + args := ecotoneArgs() + args.attrs.ParentBeaconBlockRoot = nil + args.envelope.ParentBeaconBlockRoot = nil + return args +} + +func mismatchedParentHashArgs() args { + args := ecotoneArgs() + args.parentHash = common.HexToHash("0xabc") + return args +} + +func createMistmatchedPrevRandao() args { + args := ecotoneArgs() + args.attrs.PrevRandao = eth.Bytes32(common.HexToHash("0xabc")) + return args +} + +func createMismatchedGasLimit() args { + args := ecotoneArgs() + val := eth.Uint64Quantity(2000) + args.attrs.GasLimit = &val + return args +} + +func createNilGasLimit() args { + args := ecotoneArgs() + args.attrs.GasLimit = nil + return args +} + +func createMistmatchedTimestamp() args { + args := ecotoneArgs() + val := eth.Uint64Quantity(2000) + args.attrs.Timestamp = val + return args +} + +func TestAttributesMatch(t *testing.T) { + rollupCfg := &rollup.Config{} + + tests := []struct { + shouldMatch bool + args args + }{ + { + shouldMatch: true, + args: ecotoneArgs(), + }, + { + shouldMatch: true, + args: canyonArgs(), + }, + { + shouldMatch: true, + args: bedrockArgs(), + }, + { + shouldMatch: false, + args: mismatchedParentHashArgs(), + }, + { + shouldMatch: false, + args: ecotoneNoParentBeaconBlockRoot(), + }, + { + shouldMatch: false, + args: ecotoneUnexpectedParentBeaconBlockRoot(), + }, + { + shouldMatch: false, + args: ecotoneMismatchParentBeaconBlockRoot(), + }, + { + shouldMatch: true, + args: ecotoneMismatchParentBeaconBlockRootPtr(), + }, + { + shouldMatch: true, + args: ecotoneNilParentBeaconBlockRoots(), + }, + { + shouldMatch: false, + args: createMistmatchedPrevRandao(), + }, + { + shouldMatch: false, + args: createMismatchedGasLimit(), + }, + { + shouldMatch: false, + args: createNilGasLimit(), + }, + { + shouldMatch: false, + args: createMistmatchedTimestamp(), + }, + } + + for _, test := range tests { + err := AttributesMatchBlock(rollupCfg, test.args.attrs, test.args.parentHash, test.args.envelope, testlog.Logger(t, log.LevelInfo)) + if test.shouldMatch { + require.NoError(t, err) + } else { + require.Error(t, err) + } + } +} + func TestWithdrawalsMatch(t *testing.T) { tests := []struct { attrs *types.Withdrawals @@ -68,3 +264,126 @@ func TestWithdrawalsMatch(t *testing.T) { } } } + +func TestGetMissingTxnHashes(t *testing.T) { + depositTxs := make([]*types.Transaction, 5) + + for i := 0; i < len(depositTxs); i++ { + rng := rand.New(rand.NewSource(1234 + int64(i))) + safeDeposit := testutils.GenerateDeposit(testutils.RandomHash(rng), rng) + depositTxs[i] = types.NewTx(safeDeposit) + } + + tests := []struct { + safeTransactions []hexutil.Bytes + unsafeTransactions []hexutil.Bytes + expectedSafeMissingHashes []common.Hash + expectedUnsafeMissingHashes []common.Hash + expectErr bool + }{ + { + safeTransactions: []hexutil.Bytes{}, + unsafeTransactions: []hexutil.Bytes{depositTxToBytes(t, depositTxs[0])}, + expectedSafeMissingHashes: []common.Hash{depositTxs[0].Hash()}, + expectedUnsafeMissingHashes: []common.Hash{}, + expectErr: false, + }, + { + safeTransactions: []hexutil.Bytes{depositTxToBytes(t, depositTxs[0])}, + unsafeTransactions: []hexutil.Bytes{}, + expectedSafeMissingHashes: []common.Hash{}, + expectedUnsafeMissingHashes: []common.Hash{depositTxs[0].Hash()}, + expectErr: false, + }, + { + safeTransactions: []hexutil.Bytes{ + depositTxToBytes(t, depositTxs[0]), + }, + unsafeTransactions: []hexutil.Bytes{ + depositTxToBytes(t, depositTxs[0]), + depositTxToBytes(t, depositTxs[1]), + depositTxToBytes(t, depositTxs[2]), + }, + expectedSafeMissingHashes: []common.Hash{ + depositTxs[1].Hash(), + depositTxs[2].Hash(), + }, + expectedUnsafeMissingHashes: []common.Hash{}, + expectErr: false, + }, + { + safeTransactions: []hexutil.Bytes{ + depositTxToBytes(t, depositTxs[0]), + depositTxToBytes(t, depositTxs[1]), + depositTxToBytes(t, depositTxs[2]), + }, + unsafeTransactions: []hexutil.Bytes{ + depositTxToBytes(t, depositTxs[0]), + }, + expectedSafeMissingHashes: []common.Hash{}, + expectedUnsafeMissingHashes: []common.Hash{ + depositTxs[1].Hash(), + depositTxs[2].Hash(), + }, + expectErr: false, + }, + { + safeTransactions: []hexutil.Bytes{ + depositTxToBytes(t, depositTxs[0]), + depositTxToBytes(t, depositTxs[1]), + depositTxToBytes(t, depositTxs[2]), + }, + unsafeTransactions: []hexutil.Bytes{ + depositTxToBytes(t, depositTxs[2]), + depositTxToBytes(t, depositTxs[3]), + depositTxToBytes(t, depositTxs[4]), + }, + expectedSafeMissingHashes: []common.Hash{ + depositTxs[3].Hash(), + depositTxs[4].Hash(), + }, + expectedUnsafeMissingHashes: []common.Hash{ + depositTxs[0].Hash(), + depositTxs[1].Hash(), + }, + expectErr: false, + }, + { + safeTransactions: []hexutil.Bytes{{1, 2, 3}}, + unsafeTransactions: []hexutil.Bytes{}, + expectedSafeMissingHashes: []common.Hash{}, + expectedUnsafeMissingHashes: []common.Hash{}, + expectErr: true, + }, + { + safeTransactions: []hexutil.Bytes{}, + unsafeTransactions: []hexutil.Bytes{{1, 2, 3}}, + expectedSafeMissingHashes: []common.Hash{}, + expectedUnsafeMissingHashes: []common.Hash{}, + expectErr: true, + }, + } + + for _, test := range tests { + missingSafeHashes, missingUnsafeHashes, err := getMissingTxnHashes( + testlog.Logger(t, log.LevelError), + test.safeTransactions, + test.unsafeTransactions, + ) + + if test.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.ElementsMatch(t, test.expectedSafeMissingHashes, missingSafeHashes) + require.ElementsMatch(t, test.expectedUnsafeMissingHashes, missingUnsafeHashes) + } + } +} + +func depositTxToBytes(t *testing.T, tx *types.Transaction) hexutil.Bytes { + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + + return txBytes +} diff --git a/op-node/rollup/derive/engine_controller.go b/op-node/rollup/derive/engine_controller.go new file mode 100644 index 000000000000..a0417b3c05c4 --- /dev/null +++ b/op-node/rollup/derive/engine_controller.go @@ -0,0 +1,467 @@ +package derive + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/async" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +type syncStatusEnum int + +const ( + syncStatusCL syncStatusEnum = iota + // We transition between the 4 EL states linearly. We spend the majority of the time in the second & fourth. + // We only want to EL sync if there is no finalized block & once we finish EL sync we need to mark the last block + // as finalized so we can switch to consolidation + // TODO(protocol-quest/91): We can restart EL sync & still consolidate if there finalized blocks on the execution client if the + // execution client is running in archive mode. In some cases we may want to switch back from CL to EL sync, but that is complicated. + syncStatusWillStartEL // First if we are directed to EL sync, check that nothing has been finalized yet + syncStatusStartedEL // Perform our EL sync + syncStatusFinishedELButNotFinalized // EL sync is done, but we need to mark the final sync block as finalized + syncStatusFinishedEL // EL sync is done & we should be performing consolidation +) + +var errNoFCUNeeded = errors.New("no FCU call was needed") + +var _ EngineControl = (*EngineController)(nil) +var _ LocalEngineControl = (*EngineController)(nil) + +type ExecEngine interface { + GetPayload(ctx context.Context, payloadInfo eth.PayloadInfo) (*eth.ExecutionPayloadEnvelope, error) + ForkchoiceUpdate(ctx context.Context, state *eth.ForkchoiceState, attr *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error) + NewPayload(ctx context.Context, payload *eth.ExecutionPayload, parentBeaconBlockRoot *common.Hash) (*eth.PayloadStatusV1, error) + L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) +} + +type EngineController struct { + engine ExecEngine // Underlying execution engine RPC + log log.Logger + metrics Metrics + syncMode sync.Mode + syncStatus syncStatusEnum + rollupCfg *rollup.Config + elStart time.Time + clock clock.Clock + + // Block Head State + unsafeHead eth.L2BlockRef + pendingSafeHead eth.L2BlockRef // L2 block processed from the middle of a span batch, but not marked as the safe block yet. + safeHead eth.L2BlockRef + finalizedHead eth.L2BlockRef + backupUnsafeHead eth.L2BlockRef + needFCUCall bool + // Track when the rollup node changes the forkchoice to restore previous + // known unsafe chain. e.g. Unsafe Reorg caused by Invalid span batch. + // This update does not retry except engine returns non-input error + // because engine may forgot backupUnsafeHead or backupUnsafeHead is not part + // of the chain. + needFCUCallForBackupUnsafeReorg bool + + // Building State + buildingOnto eth.L2BlockRef + buildingInfo eth.PayloadInfo + buildingSafe bool + safeAttrs *AttributesWithParent +} + +func NewEngineController(engine ExecEngine, log log.Logger, metrics Metrics, rollupCfg *rollup.Config, syncMode sync.Mode) *EngineController { + syncStatus := syncStatusCL + if syncMode == sync.ELSync { + syncStatus = syncStatusWillStartEL + } + + return &EngineController{ + engine: engine, + log: log, + metrics: metrics, + rollupCfg: rollupCfg, + syncMode: syncMode, + syncStatus: syncStatus, + clock: clock.SystemClock, + } +} + +// State Getters + +func (e *EngineController) UnsafeL2Head() eth.L2BlockRef { + return e.unsafeHead +} + +func (e *EngineController) PendingSafeL2Head() eth.L2BlockRef { + return e.pendingSafeHead +} + +func (e *EngineController) SafeL2Head() eth.L2BlockRef { + return e.safeHead +} + +func (e *EngineController) Finalized() eth.L2BlockRef { + return e.finalizedHead +} + +func (e *EngineController) BackupUnsafeL2Head() eth.L2BlockRef { + return e.backupUnsafeHead +} + +func (e *EngineController) BuildingPayload() (eth.L2BlockRef, eth.PayloadID, bool) { + return e.buildingOnto, e.buildingInfo.ID, e.buildingSafe +} + +func (e *EngineController) IsEngineSyncing() bool { + return e.syncStatus == syncStatusWillStartEL || e.syncStatus == syncStatusStartedEL || e.syncStatus == syncStatusFinishedELButNotFinalized +} + +// Setters + +// SetFinalizedHead implements LocalEngineControl. +func (e *EngineController) SetFinalizedHead(r eth.L2BlockRef) { + e.metrics.RecordL2Ref("l2_finalized", r) + e.finalizedHead = r + e.needFCUCall = true +} + +// SetPendingSafeL2Head implements LocalEngineControl. +func (e *EngineController) SetPendingSafeL2Head(r eth.L2BlockRef) { + e.metrics.RecordL2Ref("l2_pending_safe", r) + e.pendingSafeHead = r +} + +// SetSafeHead implements LocalEngineControl. +func (e *EngineController) SetSafeHead(r eth.L2BlockRef) { + e.metrics.RecordL2Ref("l2_safe", r) + e.safeHead = r + e.needFCUCall = true +} + +// SetUnsafeHead implements LocalEngineControl. +func (e *EngineController) SetUnsafeHead(r eth.L2BlockRef) { + e.metrics.RecordL2Ref("l2_unsafe", r) + e.unsafeHead = r + e.needFCUCall = true +} + +// SetBackupUnsafeL2Head implements LocalEngineControl. +func (e *EngineController) SetBackupUnsafeL2Head(r eth.L2BlockRef, triggerReorg bool) { + e.metrics.RecordL2Ref("l2_backup_unsafe", r) + e.backupUnsafeHead = r + e.needFCUCallForBackupUnsafeReorg = triggerReorg +} + +// Engine Methods + +func (e *EngineController) StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *AttributesWithParent, updateSafe bool) (errType BlockInsertionErrType, err error) { + if e.IsEngineSyncing() { + return BlockInsertTemporaryErr, fmt.Errorf("engine is in progess of p2p sync") + } + if e.buildingInfo != (eth.PayloadInfo{}) { + e.log.Warn("did not finish previous block building, starting new building now", "prev_onto", e.buildingOnto, "prev_payload_id", e.buildingInfo.ID, "new_onto", parent) + // TODO(8841): maybe worth it to force-cancel the old payload ID here. + } + fc := eth.ForkchoiceState{ + HeadBlockHash: parent.Hash, + SafeBlockHash: e.safeHead.Hash, + FinalizedBlockHash: e.finalizedHead.Hash, + } + + id, errTyp, err := startPayload(ctx, e.engine, fc, attrs.attributes) + if err != nil { + return errTyp, err + } + + e.buildingInfo = eth.PayloadInfo{ID: id, Timestamp: uint64(attrs.attributes.Timestamp)} + e.buildingSafe = updateSafe + e.buildingOnto = parent + if updateSafe { + e.safeAttrs = attrs + } + + return BlockInsertOK, nil +} + +func (e *EngineController) ConfirmPayload(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (out *eth.ExecutionPayloadEnvelope, errTyp BlockInsertionErrType, err error) { + // don't create a BlockInsertPrestateErr if we have a cached gossip payload + if e.buildingInfo == (eth.PayloadInfo{}) && agossip.Get() == nil { + return nil, BlockInsertPrestateErr, fmt.Errorf("cannot complete payload building: not currently building a payload") + } + if p := agossip.Get(); p != nil && e.buildingOnto == (eth.L2BlockRef{}) { + e.log.Warn("Found reusable payload from async gossiper, and no block was being built. Reusing payload.", + "hash", p.ExecutionPayload.BlockHash, + "number", uint64(p.ExecutionPayload.BlockNumber), + "parent", p.ExecutionPayload.ParentHash) + } else if e.buildingOnto.Hash != e.unsafeHead.Hash { // E.g. when safe-attributes consolidation fails, it will drop the existing work. + e.log.Warn("engine is building block that reorgs previous unsafe head", "onto", e.buildingOnto, "unsafe", e.unsafeHead) + } + fc := eth.ForkchoiceState{ + HeadBlockHash: common.Hash{}, // gets overridden + SafeBlockHash: e.safeHead.Hash, + FinalizedBlockHash: e.finalizedHead.Hash, + } + // Update the safe head if the payload is built with the last attributes in the batch. + updateSafe := e.buildingSafe && e.safeAttrs != nil && e.safeAttrs.isLastInSpan + envelope, errTyp, err := confirmPayload(ctx, e.log, e.engine, fc, e.buildingInfo, updateSafe, agossip, sequencerConductor, e.metrics) + if err != nil { + return nil, errTyp, fmt.Errorf("failed to complete building on top of L2 chain %s, id: %s, error (%d): %w", e.buildingOnto, e.buildingInfo.ID, errTyp, err) + } + ref, err := PayloadToBlockRef(e.rollupCfg, envelope.ExecutionPayload) + if err != nil { + return nil, BlockInsertPayloadErr, NewResetError(fmt.Errorf("failed to decode L2 block ref from payload: %w", err)) + } + // Backup unsafeHead when new block is not built on original unsafe head. + if e.unsafeHead.Number >= ref.Number { + e.SetBackupUnsafeL2Head(e.unsafeHead, false) + } + e.unsafeHead = ref + + e.metrics.RecordL2Ref("l2_unsafe", ref) + if e.buildingSafe { + e.metrics.RecordL2Ref("l2_pending_safe", ref) + e.pendingSafeHead = ref + if updateSafe { + e.safeHead = ref + e.metrics.RecordL2Ref("l2_safe", ref) + // Remove backupUnsafeHead because this backup will be never used after consolidation. + e.SetBackupUnsafeL2Head(eth.L2BlockRef{}, false) + } + } + + e.resetBuildingState() + return envelope, BlockInsertOK, nil +} + +func (e *EngineController) CancelPayload(ctx context.Context, force bool) error { + if e.buildingInfo == (eth.PayloadInfo{}) { // only cancel if there is something to cancel. + return nil + } + // the building job gets wrapped up as soon as the payload is retrieved, there's no explicit cancel in the Engine API + e.log.Error("cancelling old block sealing job", "payload", e.buildingInfo.ID) + _, err := e.engine.GetPayload(ctx, e.buildingInfo) + if err != nil { + e.log.Error("failed to cancel block building job", "payload", e.buildingInfo.ID, "err", err) + if !force { + return err + } + } + e.resetBuildingState() + return nil +} + +func (e *EngineController) resetBuildingState() { + e.buildingInfo = eth.PayloadInfo{} + e.buildingOnto = eth.L2BlockRef{} + e.buildingSafe = false + e.safeAttrs = nil +} + +// Misc Setters only used by the engine queue + +// checkNewPayloadStatus checks returned status of engine_newPayloadV1 request for next unsafe payload. +// It returns true if the status is acceptable. +func (e *EngineController) checkNewPayloadStatus(status eth.ExecutePayloadStatus) bool { + if e.syncMode == sync.ELSync { + if status == eth.ExecutionValid && e.syncStatus == syncStatusStartedEL { + e.syncStatus = syncStatusFinishedELButNotFinalized + } + // Allow SYNCING and ACCEPTED if engine EL sync is enabled + return status == eth.ExecutionValid || status == eth.ExecutionSyncing || status == eth.ExecutionAccepted + } + return status == eth.ExecutionValid +} + +// checkForkchoiceUpdatedStatus checks returned status of engine_forkchoiceUpdatedV1 request for next unsafe payload. +// It returns true if the status is acceptable. +func (e *EngineController) checkForkchoiceUpdatedStatus(status eth.ExecutePayloadStatus) bool { + if e.syncMode == sync.ELSync { + if status == eth.ExecutionValid && e.syncStatus == syncStatusStartedEL { + e.syncStatus = syncStatusFinishedELButNotFinalized + } + // Allow SYNCING if engine P2P sync is enabled + return status == eth.ExecutionValid || status == eth.ExecutionSyncing + } + return status == eth.ExecutionValid +} + +// TryUpdateEngine attempts to update the engine with the current forkchoice state of the rollup node, +// this is a no-op if the nodes already agree on the forkchoice state. +func (e *EngineController) TryUpdateEngine(ctx context.Context) error { + if !e.needFCUCall { + return errNoFCUNeeded + } + if e.IsEngineSyncing() { + e.log.Warn("Attempting to update forkchoice state while EL syncing") + } + fc := eth.ForkchoiceState{ + HeadBlockHash: e.unsafeHead.Hash, + SafeBlockHash: e.safeHead.Hash, + FinalizedBlockHash: e.finalizedHead.Hash, + } + _, err := e.engine.ForkchoiceUpdate(ctx, &fc, nil) + if err != nil { + var inputErr eth.InputError + if errors.As(err, &inputErr) { + switch inputErr.Code { + case eth.InvalidForkchoiceState: + return NewResetError(fmt.Errorf("forkchoice update was inconsistent with engine, need reset to resolve: %w", inputErr.Unwrap())) + default: + return NewTemporaryError(fmt.Errorf("unexpected error code in forkchoice-updated response: %w", err)) + } + } else { + return NewTemporaryError(fmt.Errorf("failed to sync forkchoice with engine: %w", err)) + } + } + e.needFCUCall = false + return nil +} + +func (e *EngineController) InsertUnsafePayload(ctx context.Context, envelope *eth.ExecutionPayloadEnvelope, ref eth.L2BlockRef) error { + // Check if there is a finalized head once when doing EL sync. If so, transition to CL sync + if e.syncStatus == syncStatusWillStartEL { + b, err := e.engine.L2BlockRefByLabel(ctx, eth.Finalized) + isTransitionBlock := e.rollupCfg.Genesis.L2.Number != 0 && b.Hash == e.rollupCfg.Genesis.L2.Hash + if errors.Is(err, ethereum.NotFound) || isTransitionBlock { + e.syncStatus = syncStatusStartedEL + e.log.Info("Starting EL sync") + e.elStart = e.clock.Now() + } else if err == nil { + e.syncStatus = syncStatusFinishedEL + e.log.Info("Skipping EL sync and going straight to CL sync because there is a finalized block", "id", b.ID()) + return nil + } else { + return NewTemporaryError(fmt.Errorf("failed to fetch finalized head: %w", err)) + } + } + // Insert the payload & then call FCU + status, err := e.engine.NewPayload(ctx, envelope.ExecutionPayload, envelope.ParentBeaconBlockRoot) + if err != nil { + return NewTemporaryError(fmt.Errorf("failed to update insert payload: %w", err)) + } + if !e.checkNewPayloadStatus(status.Status) { + payload := envelope.ExecutionPayload + return NewTemporaryError(fmt.Errorf("cannot process unsafe payload: new - %v; parent: %v; err: %w", + payload.ID(), payload.ParentID(), eth.NewPayloadErr(payload, status))) + } + + // Mark the new payload as valid + fc := eth.ForkchoiceState{ + HeadBlockHash: envelope.ExecutionPayload.BlockHash, + SafeBlockHash: e.safeHead.Hash, + FinalizedBlockHash: e.finalizedHead.Hash, + } + if e.syncStatus == syncStatusFinishedELButNotFinalized { + fc.SafeBlockHash = envelope.ExecutionPayload.BlockHash + fc.FinalizedBlockHash = envelope.ExecutionPayload.BlockHash + e.SetSafeHead(ref) + e.SetFinalizedHead(ref) + } + fcRes, err := e.engine.ForkchoiceUpdate(ctx, &fc, nil) + if err != nil { + var inputErr eth.InputError + if errors.As(err, &inputErr) { + switch inputErr.Code { + case eth.InvalidForkchoiceState: + return NewResetError(fmt.Errorf("pre-unsafe-block forkchoice update was inconsistent with engine, need reset to resolve: %w", inputErr.Unwrap())) + default: + return NewTemporaryError(fmt.Errorf("unexpected error code in forkchoice-updated response: %w", err)) + } + } else { + return NewTemporaryError(fmt.Errorf("failed to update forkchoice to prepare for new unsafe payload: %w", err)) + } + } + if !e.checkForkchoiceUpdatedStatus(fcRes.PayloadStatus.Status) { + payload := envelope.ExecutionPayload + return NewTemporaryError(fmt.Errorf("cannot prepare unsafe chain for new payload: new - %v; parent: %v; err: %w", + payload.ID(), payload.ParentID(), eth.ForkchoiceUpdateErr(fcRes.PayloadStatus))) + } + e.SetUnsafeHead(ref) + e.needFCUCall = false + + if e.syncStatus == syncStatusFinishedELButNotFinalized { + e.log.Info("Finished EL sync", "sync_duration", e.clock.Since(e.elStart), "finalized_block", ref.ID().String()) + e.syncStatus = syncStatusFinishedEL + } + + return nil +} + +// shouldTryBackupUnsafeReorg checks reorging(restoring) unsafe head to backupUnsafeHead is needed. +// Returns boolean which decides to trigger FCU. +func (e *EngineController) shouldTryBackupUnsafeReorg() bool { + if !e.needFCUCallForBackupUnsafeReorg { + return false + } + // This method must be never called when EL sync. If EL sync is in progress, early return. + if e.IsEngineSyncing() { + e.log.Warn("Attempting to unsafe reorg using backupUnsafe while EL syncing") + return false + } + if e.BackupUnsafeL2Head() == (eth.L2BlockRef{}) { // sanity check backupUnsafeHead is there + e.log.Warn("Attempting to unsafe reorg using backupUnsafe even though it is empty") + e.SetBackupUnsafeL2Head(eth.L2BlockRef{}, false) + return false + } + return true +} + +// TryBackupUnsafeReorg attempts to reorg(restore) unsafe head to backupUnsafeHead. +// If succeeds, update current forkchoice state to the rollup node. +func (e *EngineController) TryBackupUnsafeReorg(ctx context.Context) (bool, error) { + if !e.shouldTryBackupUnsafeReorg() { + // Do not need to perform FCU. + return false, nil + } + // Only try FCU once because execution engine may forgot backupUnsafeHead + // or backupUnsafeHead is not part of the chain. + // Exception: Retry when forkChoiceUpdate returns non-input error. + e.needFCUCallForBackupUnsafeReorg = false + // Reorg unsafe chain. Safe/Finalized chain will not be updated. + e.log.Warn("trying to restore unsafe head", "backupUnsafe", e.backupUnsafeHead.ID(), "unsafe", e.unsafeHead.ID()) + fc := eth.ForkchoiceState{ + HeadBlockHash: e.backupUnsafeHead.Hash, + SafeBlockHash: e.safeHead.Hash, + FinalizedBlockHash: e.finalizedHead.Hash, + } + fcRes, err := e.engine.ForkchoiceUpdate(ctx, &fc, nil) + if err != nil { + var inputErr eth.InputError + if errors.As(err, &inputErr) { + e.SetBackupUnsafeL2Head(eth.L2BlockRef{}, false) + switch inputErr.Code { + case eth.InvalidForkchoiceState: + return true, NewResetError(fmt.Errorf("forkchoice update was inconsistent with engine, need reset to resolve: %w", inputErr.Unwrap())) + default: + return true, NewTemporaryError(fmt.Errorf("unexpected error code in forkchoice-updated response: %w", err)) + } + } else { + // Retry when forkChoiceUpdate returns non-input error. + // Do not reset backupUnsafeHead because it will be used again. + e.needFCUCallForBackupUnsafeReorg = true + return true, NewTemporaryError(fmt.Errorf("failed to sync forkchoice with engine: %w", err)) + } + } + if fcRes.PayloadStatus.Status == eth.ExecutionValid { + // Execution engine accepted the reorg. + e.log.Info("successfully reorged unsafe head using backupUnsafe", "unsafe", e.backupUnsafeHead.ID()) + e.SetUnsafeHead(e.BackupUnsafeL2Head()) + e.SetBackupUnsafeL2Head(eth.L2BlockRef{}, false) + return true, nil + } + e.SetBackupUnsafeL2Head(eth.L2BlockRef{}, false) + // Execution engine could not reorg back to previous unsafe head. + return true, NewTemporaryError(fmt.Errorf("cannot restore unsafe chain using backupUnsafe: err: %w", + eth.ForkchoiceUpdateErr(fcRes.PayloadStatus))) +} + +// ResetBuildingState implements LocalEngineControl. +func (e *EngineController) ResetBuildingState() { + e.resetBuildingState() +} diff --git a/op-node/rollup/derive/engine_queue.go b/op-node/rollup/derive/engine_queue.go index 2e3430341232..40be46440b78 100644 --- a/op-node/rollup/derive/engine_queue.go +++ b/op-node/rollup/derive/engine_queue.go @@ -13,32 +13,45 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/async" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/eth" ) -type attributesWithParent struct { - attributes *eth.PayloadAttributes - parent eth.L2BlockRef +type AttributesWithParent struct { + attributes *eth.PayloadAttributes + parent eth.L2BlockRef + isLastInSpan bool +} + +func NewAttributesWithParent(attributes *eth.PayloadAttributes, parent eth.L2BlockRef, isLastInSpan bool) *AttributesWithParent { + return &AttributesWithParent{attributes, parent, isLastInSpan} +} + +func (a *AttributesWithParent) Attributes() *eth.PayloadAttributes { + return a.attributes } type NextAttributesProvider interface { Origin() eth.L1BlockRef - NextAttributes(context.Context, eth.L2BlockRef) (*eth.PayloadAttributes, error) + NextAttributes(context.Context, eth.L2BlockRef) (*AttributesWithParent, error) } -type Engine interface { - GetPayload(ctx context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayload, error) - ForkchoiceUpdate(ctx context.Context, state *eth.ForkchoiceState, attr *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error) - NewPayload(ctx context.Context, payload *eth.ExecutionPayload) (*eth.PayloadStatusV1, error) - PayloadByHash(context.Context, common.Hash) (*eth.ExecutionPayload, error) - PayloadByNumber(context.Context, uint64) (*eth.ExecutionPayload, error) +type L2Source interface { + PayloadByHash(context.Context, common.Hash) (*eth.ExecutionPayloadEnvelope, error) + PayloadByNumber(context.Context, uint64) (*eth.ExecutionPayloadEnvelope, error) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) L2BlockRefByHash(ctx context.Context, l2Hash common.Hash) (eth.L2BlockRef, error) L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2BlockRef, error) SystemConfigL2Fetcher } +type Engine interface { + ExecEngine + L2Source +} + // EngineState provides a read-only interface of the forkchoice state properties of the L2 Engine. type EngineState interface { Finalized() eth.L2BlockRef @@ -54,9 +67,9 @@ type EngineControl interface { // StartPayload requests the engine to start building a block with the given attributes. // If updateSafe, the resulting block will be marked as a safe block. - StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *eth.PayloadAttributes, updateSafe bool) (errType BlockInsertionErrType, err error) + StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *AttributesWithParent, updateSafe bool) (errType BlockInsertionErrType, err error) // ConfirmPayload requests the engine to complete the current block. If no block is being built, or if it fails, an error is returned. - ConfirmPayload(ctx context.Context) (out *eth.ExecutionPayload, errTyp BlockInsertionErrType, err error) + ConfirmPayload(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (out *eth.ExecutionPayloadEnvelope, errTyp BlockInsertionErrType, err error) // CancelPayload requests the engine to stop building the current block without making it canonical. // This is optional, as the engine expires building jobs that are left uncompleted, but can still save resources. CancelPayload(ctx context.Context, force bool) error @@ -64,6 +77,43 @@ type EngineControl interface { BuildingPayload() (onto eth.L2BlockRef, id eth.PayloadID, safe bool) } +type LocalEngineControl interface { + EngineControl + ResetBuildingState() + IsEngineSyncing() bool + TryUpdateEngine(ctx context.Context) error + TryBackupUnsafeReorg(ctx context.Context) (bool, error) + InsertUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope, ref eth.L2BlockRef) error + + PendingSafeL2Head() eth.L2BlockRef + BackupUnsafeL2Head() eth.L2BlockRef + + SetUnsafeHead(eth.L2BlockRef) + SetSafeHead(eth.L2BlockRef) + SetFinalizedHead(eth.L2BlockRef) + SetPendingSafeL2Head(eth.L2BlockRef) + SetBackupUnsafeL2Head(block eth.L2BlockRef, triggerReorg bool) +} + +// SafeHeadListener is called when the safe head is updated. +// The safe head may advance by more than one block in a single update +// The l1Block specified is the first L1 block that includes sufficient information to derive the new safe head +type SafeHeadListener interface { + + // Enabled reports if this safe head listener is actively using the posted data. This allows the engine queue to + // optionally skip making calls that may be expensive to prepare. + // Callbacks may still be made if Enabled returns false but are not guaranteed. + Enabled() bool + + // SafeHeadUpdated indicates that the safe head has been updated in response to processing batch data + // The l1Block specified is the first L1 block containing all required batch data to derive newSafeHead + SafeHeadUpdated(newSafeHead eth.L2BlockRef, l1Block eth.BlockID) error + + // SafeHeadReset indicates that the derivation pipeline reset back to the specified safe head + // The L1 block that made the new safe head safe is unknown. + SafeHeadReset(resetSafeHead eth.L2BlockRef) error +} + // Max memory used for buffering unsafe payloads const maxUnsafePayloadsMemory = 500 * 1024 * 1024 @@ -86,6 +136,21 @@ const finalityLookback = 4*32 + 1 // We do not want to do this too often, since it requires fetching a L1 block by number, so no cache data. const finalityDelay = 64 +// calcFinalityLookback calculates the default finality lookback based on DA challenge window if plasma +// mode is activated or L1 finality lookback. +func calcFinalityLookback(cfg *rollup.Config) uint64 { + // in plasma mode the longest finality lookback is a commitment is challenged on the last block of + // the challenge window in which case it will be both challenge + resolve window. + if cfg.UsePlasma { + lkb := cfg.DAChallengeWindow + cfg.DAResolveWindow + 1 + // in the case only if the plasma windows are longer than the default finality lookback + if lkb > finalityLookback { + return lkb + } + } + return finalityLookback +} + type FinalityData struct { // The last L2 block that was fully derived and inserted into the L2 engine while processing this L1 block. L2Block eth.L2BlockRef @@ -99,22 +164,7 @@ type EngineQueue struct { log log.Logger cfg *rollup.Config - finalized eth.L2BlockRef - safeHead eth.L2BlockRef - unsafeHead eth.L2BlockRef - - // Target L2 block the engine is currently syncing to. - // If the engine p2p sync is enabled, it can be different with unsafeHead. Otherwise, it must be same with unsafeHead. - engineSyncTarget eth.L2BlockRef - - buildingOnto eth.L2BlockRef - buildingID eth.PayloadID - buildingSafe bool - - // Track when the rollup node changes the forkchoice without engine action, - // e.g. on a reset after a reorg, or after consolidating a block. - // This update may repeat if the engine returns a temporary error. - needForkchoiceUpdate bool + ec LocalEngineControl // finalizedL1 is the currently perceived finalized L1 block. // This may be ahead of the current traversed origin when syncing. @@ -124,13 +174,13 @@ type EngineQueue struct { triedFinalizeAt eth.L1BlockRef // The queued-up attributes - safeAttributes *attributesWithParent + safeAttributes *AttributesWithParent unsafePayloads *PayloadsQueue // queue of unsafe payloads, ordered by ascending block number, may have gaps and duplicates // Tracks which L2 blocks where last derived from which L1 block. At most finalityLookback large. finalityData []FinalityData - engine Engine + engine L2Source prev NextAttributesProvider origin eth.L1BlockRef // updated on resets, and whenever we read from the previous stage. @@ -140,22 +190,25 @@ type EngineQueue struct { l1Fetcher L1Fetcher syncCfg *sync.Config -} -var _ EngineControl = (*EngineQueue)(nil) + safeHeadNotifs SafeHeadListener // notified when safe head is updated + lastNotifiedSafeHead eth.L2BlockRef +} // NewEngineQueue creates a new EngineQueue, which should be Reset(origin) before use. -func NewEngineQueue(log log.Logger, cfg *rollup.Config, engine Engine, metrics Metrics, prev NextAttributesProvider, l1Fetcher L1Fetcher, syncCfg *sync.Config) *EngineQueue { +func NewEngineQueue(log log.Logger, cfg *rollup.Config, l2Source L2Source, engine LocalEngineControl, metrics Metrics, prev NextAttributesProvider, l1Fetcher L1Fetcher, syncCfg *sync.Config, safeHeadNotifs SafeHeadListener) *EngineQueue { return &EngineQueue{ log: log, cfg: cfg, - engine: engine, + ec: engine, + engine: l2Source, metrics: metrics, - finalityData: make([]FinalityData, 0, finalityLookback), - unsafePayloads: NewPayloadsQueue(maxUnsafePayloadsMemory, payloadMemSize), + finalityData: make([]FinalityData, 0, calcFinalityLookback(cfg)), + unsafePayloads: NewPayloadsQueue(log, maxUnsafePayloadsMemory, payloadMemSize), prev: prev, l1Fetcher: l1Fetcher, syncCfg: syncCfg, + safeHeadNotifs: safeHeadNotifs, } } @@ -168,34 +221,25 @@ func (eq *EngineQueue) SystemConfig() eth.SystemConfig { return eq.sysCfg } -func (eq *EngineQueue) SetUnsafeHead(head eth.L2BlockRef) { - eq.unsafeHead = head - eq.metrics.RecordL2Ref("l2_unsafe", head) -} - -func (eq *EngineQueue) SetEngineSyncTarget(head eth.L2BlockRef) { - eq.engineSyncTarget = head - eq.metrics.RecordL2Ref("l2_engineSyncTarget", head) -} - -func (eq *EngineQueue) AddUnsafePayload(payload *eth.ExecutionPayload) { - if payload == nil { +func (eq *EngineQueue) AddUnsafePayload(envelope *eth.ExecutionPayloadEnvelope) { + if envelope == nil { eq.log.Warn("cannot add nil unsafe payload") return } - if err := eq.unsafePayloads.Push(payload); err != nil { - eq.log.Warn("Could not add unsafe payload", "id", payload.ID(), "timestamp", uint64(payload.Timestamp), "err", err) + if err := eq.unsafePayloads.Push(envelope); err != nil { + eq.log.Warn("Could not add unsafe payload", "id", envelope.ExecutionPayload.ID(), "timestamp", uint64(envelope.ExecutionPayload.Timestamp), "err", err) return } p := eq.unsafePayloads.Peek() - eq.metrics.RecordUnsafePayloadsBuffer(uint64(eq.unsafePayloads.Len()), eq.unsafePayloads.MemSize(), p.ID()) - eq.log.Trace("Next unsafe payload to process", "next", p.ID(), "timestamp", uint64(p.Timestamp)) + eq.metrics.RecordUnsafePayloadsBuffer(uint64(eq.unsafePayloads.Len()), eq.unsafePayloads.MemSize(), p.ExecutionPayload.ID()) + eq.log.Trace("Next unsafe payload to process", "next", p.ExecutionPayload.ID(), "timestamp", uint64(p.ExecutionPayload.Timestamp)) } func (eq *EngineQueue) Finalize(l1Origin eth.L1BlockRef) { + prevFinalizedL1 := eq.finalizedL1 if l1Origin.Number < eq.finalizedL1.Number { - eq.log.Error("ignoring old L1 finalized block signal! Is the L1 provider corrupted?", "prev_finalized_l1", eq.finalizedL1, "signaled_finalized_l1", l1Origin) + eq.log.Error("ignoring old L1 finalized block signal! Is the L1 provider corrupted?", "prev_finalized_l1", prevFinalizedL1, "signaled_finalized_l1", l1Origin) return } @@ -214,7 +258,7 @@ func (eq *EngineQueue) Finalize(l1Origin eth.L1BlockRef) { } } - eq.log.Info("received L1 finality signal, but missing data for immediate L2 finalization", "prev_finalized_l1", eq.finalizedL1, "signaled_finalized_l1", l1Origin) + eq.log.Info("received L1 finality signal, but missing data for immediate L2 finalization", "prev_finalized_l1", prevFinalizedL1, "signaled_finalized_l1", l1Origin) } // FinalizedL1 identifies the L1 chain (incl.) that included and/or produced all the finalized L2 blocks. @@ -223,30 +267,39 @@ func (eq *EngineQueue) FinalizedL1() eth.L1BlockRef { return eq.finalizedL1 } -func (eq *EngineQueue) Finalized() eth.L2BlockRef { - return eq.finalized -} - -func (eq *EngineQueue) UnsafeL2Head() eth.L2BlockRef { - return eq.unsafeHead -} - -func (eq *EngineQueue) SafeL2Head() eth.L2BlockRef { - return eq.safeHead +// LowestQueuedUnsafeBlock returns the block +func (eq *EngineQueue) LowestQueuedUnsafeBlock() eth.L2BlockRef { + payload := eq.unsafePayloads.Peek() + if payload == nil { + return eth.L2BlockRef{} + } + ref, err := PayloadToBlockRef(eq.cfg, payload.ExecutionPayload) + if err != nil { + return eth.L2BlockRef{} + } + return ref } -func (eq *EngineQueue) EngineSyncTarget() eth.L2BlockRef { - return eq.engineSyncTarget +func (eq *EngineQueue) BackupUnsafeL2Head() eth.L2BlockRef { + return eq.ec.BackupUnsafeL2Head() } // Determine if the engine is syncing to the target block func (eq *EngineQueue) isEngineSyncing() bool { - return eq.unsafeHead.Hash != eq.engineSyncTarget.Hash + return eq.ec.IsEngineSyncing() } func (eq *EngineQueue) Step(ctx context.Context) error { - if eq.needForkchoiceUpdate { - return eq.tryUpdateEngine(ctx) + // If we don't need to call FCU to restore unsafeHead using backupUnsafe, keep going b/c + // this was a no-op(except correcting invalid state when backupUnsafe is empty but TryBackupUnsafeReorg called). + if fcuCalled, err := eq.ec.TryBackupUnsafeReorg(ctx); fcuCalled { + // If we needed to perform a network call, then we should yield even if we did not encounter an error. + return err + } + // If we don't need to call FCU, keep going b/c this was a no-op. If we needed to + // perform a network call, then we should yield even if we did not encounter an error. + if err := eq.ec.TryUpdateEngine(ctx); !errors.Is(err, errNoFCUNeeded) { + return err } // Trying unsafe payload should be done before safe attributes // It allows the unsafe head can move forward while the long-range consolidation is in progress. @@ -257,8 +310,8 @@ func (eq *EngineQueue) Step(ctx context.Context) error { // EOF error means we can't process the next unsafe payload. Then we should process next safe attributes. } if eq.isEngineSyncing() { - // Make pipeline first focus to sync unsafe blocks to engineSyncTarget - return EngineP2PSyncing + // The pipeline cannot move forwards if doing EL sync. + return EngineELSyncing } if eq.safeAttributes != nil { return eq.tryNextSafeAttributes(ctx) @@ -270,21 +323,22 @@ func (eq *EngineQueue) Step(ctx context.Context) error { return err } eq.origin = newOrigin - eq.postProcessSafeL2() // make sure we track the last L2 safe head for every new L1 block + // make sure we track the last L2 safe head for every new L1 block + if err := eq.postProcessSafeL2(); err != nil { + return err + } // try to finalize the L2 blocks we have synced so far (no-op if L1 finality is behind) if err := eq.tryFinalizePastL2Blocks(ctx); err != nil { return err } - if next, err := eq.prev.NextAttributes(ctx, eq.safeHead); err == io.EOF { + if next, err := eq.prev.NextAttributes(ctx, eq.ec.PendingSafeL2Head()); err == io.EOF { outOfData = true } else if err != nil { return err } else { - eq.safeAttributes = &attributesWithParent{ - attributes: next, - parent: eq.safeHead, - } - eq.log.Debug("Adding next safe attributes", "safe_head", eq.safeHead, "next", next) + eq.safeAttributes = next + eq.log.Debug("Adding next safe attributes", "safe_head", eq.ec.SafeL2Head(), + "pending_safe_head", eq.ec.PendingSafeL2Head(), "next", next) return NotEnoughData } @@ -302,7 +356,7 @@ func (eq *EngineQueue) verifyNewL1Origin(ctx context.Context, newOrigin eth.L1Bl if newOrigin == eq.origin { return nil } - unsafeOrigin := eq.unsafeHead.L1Origin + unsafeOrigin := eq.ec.UnsafeL2Head().L1Origin if newOrigin.Number == unsafeOrigin.Number && newOrigin.ID() != unsafeOrigin { return NewResetError(fmt.Errorf("l1 origin was inconsistent with l2 unsafe head origin, need reset to resolve: l1 origin: %v; unsafe origin: %v", newOrigin.ID(), unsafeOrigin)) @@ -368,30 +422,31 @@ func (eq *EngineQueue) tryFinalizeL2() { } eq.triedFinalizeAt = eq.origin // default to keep the same finalized block - finalizedL2 := eq.finalized + finalizedL2 := eq.ec.Finalized() // go through the latest inclusion data, and find the last L2 block that was derived from a finalized L1 block for _, fd := range eq.finalityData { if fd.L2Block.Number > finalizedL2.Number && fd.L1Block.Number <= eq.finalizedL1.Number { finalizedL2 = fd.L2Block - eq.needForkchoiceUpdate = true } } - eq.finalized = finalizedL2 - eq.metrics.RecordL2Ref("l2_finalized", finalizedL2) + eq.ec.SetFinalizedHead(finalizedL2) } // postProcessSafeL2 buffers the L1 block the safe head was fully derived from, // to finalize it once the L1 block, or later, finalizes. -func (eq *EngineQueue) postProcessSafeL2() { +func (eq *EngineQueue) postProcessSafeL2() error { + if err := eq.notifyNewSafeHead(eq.ec.SafeL2Head()); err != nil { + return err + } // prune finality data if necessary - if len(eq.finalityData) >= finalityLookback { - eq.finalityData = append(eq.finalityData[:0], eq.finalityData[1:finalityLookback]...) + if uint64(len(eq.finalityData)) >= calcFinalityLookback(eq.cfg) { + eq.finalityData = append(eq.finalityData[:0], eq.finalityData[1:calcFinalityLookback(eq.cfg)]...) } // remember the last L2 block that we fully derived from the given finality data if len(eq.finalityData) == 0 || eq.finalityData[len(eq.finalityData)-1].L1Block.Number < eq.origin.Number { // append entry for new L1 block eq.finalityData = append(eq.finalityData, FinalityData{ - L2Block: eq.safeHead, + L2Block: eq.ec.SafeL2Head(), L1Block: eq.origin.ID(), }) last := &eq.finalityData[len(eq.finalityData)-1] @@ -399,147 +454,82 @@ func (eq *EngineQueue) postProcessSafeL2() { } else { // if it's a new L2 block that was derived from the same latest L1 block, then just update the entry last := &eq.finalityData[len(eq.finalityData)-1] - if last.L2Block != eq.safeHead { // avoid logging if there are no changes - last.L2Block = eq.safeHead + if last.L2Block != eq.ec.SafeL2Head() { // avoid logging if there are no changes + last.L2Block = eq.ec.SafeL2Head() eq.log.Debug("updated finality-data", "last_l1", last.L1Block, "last_l2", last.L2Block) } } - eq.l1Fetcher.ClearReceiptsCacheBefore(eq.safeHead.L1Origin.Number) -} - -func (eq *EngineQueue) logSyncProgress(reason string) { - eq.log.Info("Sync progress", - "reason", reason, - "l2_finalized", eq.finalized, - "l2_safe", eq.safeHead, - "l2_unsafe", eq.unsafeHead, - "l2_engineSyncTarget", eq.engineSyncTarget, - "l2_time", eq.unsafeHead.Time, - "l1_derived", eq.origin, - ) + eq.l1Fetcher.ClearReceiptsCacheBefore(eq.ec.SafeL2Head().L1Origin.Number) + return nil } -// tryUpdateEngine attempts to update the engine with the current forkchoice state of the rollup node, -// this is a no-op if the nodes already agree on the forkchoice state. -func (eq *EngineQueue) tryUpdateEngine(ctx context.Context) error { - if eq.unsafeHead.Hash != eq.engineSyncTarget.Hash { - eq.log.Warn("Attempting to update forkchoice state while engine is P2P syncing") - } - fc := eth.ForkchoiceState{ - HeadBlockHash: eq.engineSyncTarget.Hash, - SafeBlockHash: eq.safeHead.Hash, - FinalizedBlockHash: eq.finalized.Hash, +// notifyNewSafeHead calls the safe head listener with the current safe head and l1 origin information. +func (eq *EngineQueue) notifyNewSafeHead(safeHead eth.L2BlockRef) error { + if eq.lastNotifiedSafeHead == safeHead { + // No change, no need to notify + return nil } - _, err := eq.engine.ForkchoiceUpdate(ctx, &fc, nil) - if err != nil { - var inputErr eth.InputError - if errors.As(err, &inputErr) { - switch inputErr.Code { - case eth.InvalidForkchoiceState: - return NewResetError(fmt.Errorf("forkchoice update was inconsistent with engine, need reset to resolve: %w", inputErr.Unwrap())) - default: - return NewTemporaryError(fmt.Errorf("unexpected error code in forkchoice-updated response: %w", err)) - } - } else { - return NewTemporaryError(fmt.Errorf("failed to sync forkchoice with engine: %w", err)) - } + if err := eq.safeHeadNotifs.SafeHeadUpdated(safeHead, eq.origin.ID()); err != nil { + // At this point our state is in a potentially inconsistent state as we've updated the safe head + // in the execution client but failed to post process it. Reset the pipeline so the safe head rolls back + // a little (it always rolls back at least 1 block) and then it will retry storing the entry + return NewResetError(fmt.Errorf("safe head notifications failed: %w", err)) } - eq.needForkchoiceUpdate = false + eq.lastNotifiedSafeHead = safeHead return nil } -// checkNewPayloadStatus checks returned status of engine_newPayloadV1 request for next unsafe payload. -// It returns true if the status is acceptable. -func (eq *EngineQueue) checkNewPayloadStatus(status eth.ExecutePayloadStatus) bool { - if eq.syncCfg.EngineSync { - // Allow SYNCING and ACCEPTED if engine P2P sync is enabled - return status == eth.ExecutionValid || status == eth.ExecutionSyncing || status == eth.ExecutionAccepted - } - return status == eth.ExecutionValid -} - -// checkForkchoiceUpdatedStatus checks returned status of engine_forkchoiceUpdatedV1 request for next unsafe payload. -// It returns true if the status is acceptable. -func (eq *EngineQueue) checkForkchoiceUpdatedStatus(status eth.ExecutePayloadStatus) bool { - if eq.syncCfg.EngineSync { - // Allow SYNCING if engine P2P sync is enabled - return status == eth.ExecutionValid || status == eth.ExecutionSyncing - } - return status == eth.ExecutionValid +func (eq *EngineQueue) logSyncProgress(reason string) { + eq.log.Info("Sync progress", + "reason", reason, + "l2_finalized", eq.ec.Finalized(), + "l2_safe", eq.ec.SafeL2Head(), + "l2_pending_safe", eq.ec.PendingSafeL2Head(), + "l2_unsafe", eq.ec.UnsafeL2Head(), + "l2_backup_unsafe", eq.ec.BackupUnsafeL2Head(), + "l2_time", eq.ec.UnsafeL2Head().Time, + "l1_derived", eq.origin, + ) } func (eq *EngineQueue) tryNextUnsafePayload(ctx context.Context) error { - first := eq.unsafePayloads.Peek() + firstEnvelope := eq.unsafePayloads.Peek() + first := firstEnvelope.ExecutionPayload - if uint64(first.BlockNumber) <= eq.safeHead.Number { - eq.log.Info("skipping unsafe payload, since it is older than safe head", "safe", eq.safeHead.ID(), "unsafe", first.ID(), "payload", first.ID()) + if uint64(first.BlockNumber) <= eq.ec.SafeL2Head().Number { + eq.log.Info("skipping unsafe payload, since it is older than safe head", "safe", eq.ec.SafeL2Head().ID(), "unsafe", first.ID(), "payload", first.ID()) eq.unsafePayloads.Pop() return nil } - if uint64(first.BlockNumber) <= eq.unsafeHead.Number { - eq.log.Info("skipping unsafe payload, since it is older than unsafe head", "unsafe", eq.unsafeHead.ID(), "unsafe_payload", first.ID()) + if uint64(first.BlockNumber) <= eq.ec.UnsafeL2Head().Number { + eq.log.Info("skipping unsafe payload, since it is older than unsafe head", "unsafe", eq.ec.UnsafeL2Head().ID(), "unsafe_payload", first.ID()) eq.unsafePayloads.Pop() return nil } // Ensure that the unsafe payload builds upon the current unsafe head - if !eq.syncCfg.EngineSync && first.ParentHash != eq.unsafeHead.Hash { - if uint64(first.BlockNumber) == eq.unsafeHead.Number+1 { - eq.log.Info("skipping unsafe payload, since it does not build onto the existing unsafe chain", "safe", eq.safeHead.ID(), "unsafe", first.ID(), "payload", first.ID()) + if first.ParentHash != eq.ec.UnsafeL2Head().Hash { + if uint64(first.BlockNumber) == eq.ec.UnsafeL2Head().Number+1 { + eq.log.Info("skipping unsafe payload, since it does not build onto the existing unsafe chain", "safe", eq.ec.SafeL2Head().ID(), "unsafe", first.ID(), "payload", first.ID()) eq.unsafePayloads.Pop() } return io.EOF // time to go to next stage if we cannot process the first unsafe payload } - ref, err := PayloadToBlockRef(first, &eq.cfg.Genesis) + ref, err := PayloadToBlockRef(eq.cfg, first) if err != nil { eq.log.Error("failed to decode L2 block ref from payload", "err", err) eq.unsafePayloads.Pop() return nil } - status, err := eq.engine.NewPayload(ctx, first) - if err != nil { - return NewTemporaryError(fmt.Errorf("failed to update insert payload: %w", err)) - } - if !eq.checkNewPayloadStatus(status.Status) { - eq.unsafePayloads.Pop() - return NewTemporaryError(fmt.Errorf("cannot process unsafe payload: new - %v; parent: %v; err: %w", - first.ID(), first.ParentID(), eth.NewPayloadErr(first, status))) - } - - // Mark the new payload as valid - fc := eth.ForkchoiceState{ - HeadBlockHash: first.BlockHash, - SafeBlockHash: eq.safeHead.Hash, // this should guarantee we do not reorg past the safe head - FinalizedBlockHash: eq.finalized.Hash, - } - fcRes, err := eq.engine.ForkchoiceUpdate(ctx, &fc, nil) - if err != nil { - var inputErr eth.InputError - if errors.As(err, &inputErr) { - switch inputErr.Code { - case eth.InvalidForkchoiceState: - return NewResetError(fmt.Errorf("pre-unsafe-block forkchoice update was inconsistent with engine, need reset to resolve: %w", inputErr.Unwrap())) - default: - return NewTemporaryError(fmt.Errorf("unexpected error code in forkchoice-updated response: %w", err)) - } - } else { - return NewTemporaryError(fmt.Errorf("failed to update forkchoice to prepare for new unsafe payload: %w", err)) - } - } - if !eq.checkForkchoiceUpdatedStatus(fcRes.PayloadStatus.Status) { + if err := eq.ec.InsertUnsafePayload(ctx, firstEnvelope, ref); errors.Is(err, ErrTemporary) { + eq.log.Debug("Temporary error while inserting unsafe payload", "hash", ref.Hash, "number", ref.Number, "timestamp", ref.Time, "l1Origin", ref.L1Origin) + return err + } else if err != nil { + eq.log.Warn("Dropping invalid unsafe payload", "hash", ref.Hash, "number", ref.Number, "timestamp", ref.Time, "l1Origin", ref.L1Origin) eq.unsafePayloads.Pop() - return NewTemporaryError(fmt.Errorf("cannot prepare unsafe chain for new payload: new - %v; parent: %v; err: %w", - first.ID(), first.ParentID(), eth.ForkchoiceUpdateErr(fcRes.PayloadStatus))) - } - - eq.engineSyncTarget = ref - eq.metrics.RecordL2Ref("l2_engineSyncTarget", ref) - // unsafeHead should be updated only if the payload status is VALID - if fcRes.PayloadStatus.Status == eth.ExecutionValid { - eq.unsafeHead = ref - eq.metrics.RecordL2Ref("l2_unsafe", ref) + return err } eq.unsafePayloads.Pop() eq.log.Trace("Executed unsafe payload", "hash", ref.Hash, "number", ref.Number, "timestamp", ref.Time, "l1Origin", ref.L1Origin) @@ -553,31 +543,29 @@ func (eq *EngineQueue) tryNextSafeAttributes(ctx context.Context) error { return nil } // validate the safe attributes before processing them. The engine may have completed processing them through other means. - if eq.safeHead != eq.safeAttributes.parent { - // Previously the attribute's parent was the safe head. If the safe head advances so safe head's parent is the same as the + if eq.ec.PendingSafeL2Head() != eq.safeAttributes.parent { + // Previously the attribute's parent was the pending safe head. If the pending safe head advances so pending safe head's parent is the same as the // attribute's parent then we need to cancel the attributes. - if eq.safeHead.ParentHash == eq.safeAttributes.parent.Hash { + if eq.ec.PendingSafeL2Head().ParentHash == eq.safeAttributes.parent.Hash { eq.log.Warn("queued safe attributes are stale, safehead progressed", - "safe_head", eq.safeHead, "safe_head_parent", eq.safeHead.ParentID(), "attributes_parent", eq.safeAttributes.parent) + "pending_safe_head", eq.ec.PendingSafeL2Head(), "pending_safe_head_parent", eq.ec.PendingSafeL2Head().ParentID(), + "attributes_parent", eq.safeAttributes.parent) eq.safeAttributes = nil return nil } // If something other than a simple advance occurred, perform a full reset - return NewResetError(fmt.Errorf("safe head changed to %s with parent %s, conflicting with queued safe attributes on top of %s", - eq.safeHead, eq.safeHead.ParentID(), eq.safeAttributes.parent)) + return NewResetError(fmt.Errorf("pending safe head changed to %s with parent %s, conflicting with queued safe attributes on top of %s", + eq.ec.PendingSafeL2Head(), eq.ec.PendingSafeL2Head().ParentID(), eq.safeAttributes.parent)) } - if eq.safeHead.Number < eq.unsafeHead.Number { + if eq.ec.PendingSafeL2Head().Number < eq.ec.UnsafeL2Head().Number { return eq.consolidateNextSafeAttributes(ctx) - } else if eq.safeHead.Number == eq.unsafeHead.Number { + } else if eq.ec.PendingSafeL2Head().Number == eq.ec.UnsafeL2Head().Number { return eq.forceNextSafeAttributes(ctx) } else { - // For some reason the unsafe head is behind the safe head. Log it, and correct it. - eq.log.Error("invalid sync state, unsafe head is behind safe head", "unsafe", eq.unsafeHead, "safe", eq.safeHead) - eq.unsafeHead = eq.safeHead - eq.engineSyncTarget = eq.safeHead - eq.metrics.RecordL2Ref("l2_unsafe", eq.unsafeHead) - eq.metrics.RecordL2Ref("l2_engineSyncTarget", eq.unsafeHead) + // For some reason the unsafe head is behind the pending safe head. Log it, and correct it. + eq.log.Error("invalid sync state, unsafe head is behind pending safe head", "unsafe", eq.ec.UnsafeL2Head(), "pending_safe", eq.ec.PendingSafeL2Head()) + eq.ec.SetUnsafeHead(eq.ec.PendingSafeL2Head()) return nil } } @@ -589,7 +577,7 @@ func (eq *EngineQueue) consolidateNextSafeAttributes(ctx context.Context) error ctx, cancel := context.WithTimeout(ctx, time.Second*10) defer cancel() - payload, err := eq.engine.PayloadByNumber(ctx, eq.safeHead.Number+1) + envelope, err := eq.engine.PayloadByNumber(ctx, eq.ec.PendingSafeL2Head().Number+1) if err != nil { if errors.Is(err, ethereum.NotFound) { // engine may have restarted, or inconsistent safe head. We need to reset @@ -597,21 +585,24 @@ func (eq *EngineQueue) consolidateNextSafeAttributes(ctx context.Context) error } return NewTemporaryError(fmt.Errorf("failed to get existing unsafe payload to compare against derived attributes from L1: %w", err)) } - if err := AttributesMatchBlock(eq.safeAttributes.attributes, eq.safeHead.Hash, payload, eq.log); err != nil { - eq.log.Warn("L2 reorg: existing unsafe block does not match derived attributes from L1", "err", err, "unsafe", eq.unsafeHead, "safe", eq.safeHead) + if err := AttributesMatchBlock(eq.cfg, eq.safeAttributes.attributes, eq.ec.PendingSafeL2Head().Hash, envelope, eq.log); err != nil { + eq.log.Warn("L2 reorg: existing unsafe block does not match derived attributes from L1", "err", err, "unsafe", eq.ec.UnsafeL2Head(), "pending_safe", eq.ec.PendingSafeL2Head(), "safe", eq.ec.SafeL2Head()) // geth cannot wind back a chain without reorging to a new, previously non-canonical, block return eq.forceNextSafeAttributes(ctx) } - ref, err := PayloadToBlockRef(payload, &eq.cfg.Genesis) + ref, err := PayloadToBlockRef(eq.cfg, envelope.ExecutionPayload) if err != nil { return NewResetError(fmt.Errorf("failed to decode L2 block ref from payload: %w", err)) } - eq.safeHead = ref - eq.needForkchoiceUpdate = true - eq.metrics.RecordL2Ref("l2_safe", ref) + eq.ec.SetPendingSafeL2Head(ref) + if eq.safeAttributes.isLastInSpan { + eq.ec.SetSafeHead(ref) + if err := eq.postProcessSafeL2(); err != nil { + return err + } + } // unsafe head stays the same, we did not reorg the chain. eq.safeAttributes = nil - eq.postProcessSafeL2() eq.logSyncProgress("reconciled with L1") return nil @@ -623,9 +614,10 @@ func (eq *EngineQueue) forceNextSafeAttributes(ctx context.Context) error { return nil } attrs := eq.safeAttributes.attributes - errType, err := eq.StartPayload(ctx, eq.safeHead, attrs, true) + lastInSpan := eq.safeAttributes.isLastInSpan + errType, err := eq.StartPayload(ctx, eq.ec.PendingSafeL2Head(), eq.safeAttributes, true) if err == nil { - _, errType, err = eq.ConfirmPayload(ctx) + _, errType, err = eq.ec.ConfirmPayload(ctx, async.NoOpGossiper{}, &conductor.NoOpConductor{}) } if err != nil { switch errType { @@ -649,109 +641,50 @@ func (eq *EngineQueue) forceNextSafeAttributes(ctx context.Context) error { // block is somehow invalid, there is nothing we can do to recover & we should exit. // TODO: Can this be triggered by an empty batch with invalid data (like parent hash or gas limit?) if len(attrs.Transactions) == depositCount { - eq.log.Error("deposit only block was invalid", "parent", eq.safeHead, "err", err) + eq.log.Error("deposit only block was invalid", "parent", eq.safeAttributes.parent, "err", err) return NewCriticalError(fmt.Errorf("failed to process block with only deposit transactions: %w", err)) } // drop the payload without inserting it eq.safeAttributes = nil + // Revert the pending safe head to the safe head. + eq.ec.SetPendingSafeL2Head(eq.ec.SafeL2Head()) // suppress the error b/c we want to retry with the next batch from the batch queue // If there is no valid batch the node will eventually force a deposit only block. If // the deposit only block fails, this will return the critical error above. - return nil + // Try to restore to previous known unsafe chain. + eq.ec.SetBackupUnsafeL2Head(eq.ec.BackupUnsafeL2Head(), true) + + return nil default: return NewCriticalError(fmt.Errorf("unknown InsertHeadBlock error type %d: %w", errType, err)) } } eq.safeAttributes = nil eq.logSyncProgress("processed safe block derived from L1") + if lastInSpan { + if err := eq.postProcessSafeL2(); err != nil { + return err + } + } return nil } -func (eq *EngineQueue) StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *eth.PayloadAttributes, updateSafe bool) (errType BlockInsertionErrType, err error) { - if eq.isEngineSyncing() { - return BlockInsertTemporaryErr, fmt.Errorf("engine is in progess of p2p sync") - } - if eq.buildingID != (eth.PayloadID{}) { - eq.log.Warn("did not finish previous block building, starting new building now", "prev_onto", eq.buildingOnto, "prev_payload_id", eq.buildingID, "new_onto", parent) - // TODO: maybe worth it to force-cancel the old payload ID here. - } - fc := eth.ForkchoiceState{ - HeadBlockHash: parent.Hash, - SafeBlockHash: eq.safeHead.Hash, - FinalizedBlockHash: eq.finalized.Hash, - } - id, errTyp, err := StartPayload(ctx, eq.engine, fc, attrs) - if err != nil { - return errTyp, err - } - eq.buildingID = id - eq.buildingSafe = updateSafe - eq.buildingOnto = parent - return BlockInsertOK, nil +func (eq *EngineQueue) StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *AttributesWithParent, updateSafe bool) (errType BlockInsertionErrType, err error) { + return eq.ec.StartPayload(ctx, parent, attrs, updateSafe) } -func (eq *EngineQueue) ConfirmPayload(ctx context.Context) (out *eth.ExecutionPayload, errTyp BlockInsertionErrType, err error) { - if eq.buildingID == (eth.PayloadID{}) { - return nil, BlockInsertPrestateErr, fmt.Errorf("cannot complete payload building: not currently building a payload") - } - if eq.buildingOnto.Hash != eq.unsafeHead.Hash { // E.g. when safe-attributes consolidation fails, it will drop the existing work. - eq.log.Warn("engine is building block that reorgs previous unsafe head", "onto", eq.buildingOnto, "unsafe", eq.unsafeHead) - } - fc := eth.ForkchoiceState{ - HeadBlockHash: common.Hash{}, // gets overridden - SafeBlockHash: eq.safeHead.Hash, - FinalizedBlockHash: eq.finalized.Hash, - } - payload, errTyp, err := ConfirmPayload(ctx, eq.log, eq.engine, fc, eq.buildingID, eq.buildingSafe, eq.metrics) - if err != nil { - return nil, errTyp, fmt.Errorf("failed to complete building on top of L2 chain %s, id: %s, error (%d): %w", eq.buildingOnto, eq.buildingID, errTyp, err) - } - ref, err := PayloadToBlockRef(payload, &eq.cfg.Genesis) - if err != nil { - return nil, BlockInsertPayloadErr, NewResetError(fmt.Errorf("failed to decode L2 block ref from payload: %w", err)) - } - - eq.unsafeHead = ref - eq.engineSyncTarget = ref - eq.metrics.RecordL2Ref("l2_unsafe", ref) - eq.metrics.RecordL2Ref("l2_engineSyncTarget", ref) - - if eq.buildingSafe { - eq.safeHead = ref - eq.postProcessSafeL2() - eq.metrics.RecordL2Ref("l2_safe", ref) - } - eq.resetBuildingState() - return payload, BlockInsertOK, nil +func (eq *EngineQueue) ConfirmPayload(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (out *eth.ExecutionPayloadEnvelope, errTyp BlockInsertionErrType, err error) { + return eq.ec.ConfirmPayload(ctx, agossip, sequencerConductor) } func (eq *EngineQueue) CancelPayload(ctx context.Context, force bool) error { - if eq.buildingID == (eth.PayloadID{}) { // only cancel if there is something to cancel. - return nil - } - // the building job gets wrapped up as soon as the payload is retrieved, there's no explicit cancel in the Engine API - eq.log.Error("cancelling old block sealing job", "payload", eq.buildingID) - _, err := eq.engine.GetPayload(ctx, eq.buildingID) - if err != nil { - eq.log.Error("failed to cancel block building job", "payload", eq.buildingID, "err", err) - if !force { - return err - } - } - eq.resetBuildingState() - return nil + return eq.ec.CancelPayload(ctx, force) } func (eq *EngineQueue) BuildingPayload() (onto eth.L2BlockRef, id eth.PayloadID, safe bool) { - return eq.buildingOnto, eq.buildingID, eq.buildingSafe -} - -func (eq *EngineQueue) resetBuildingState() { - eq.buildingID = eth.PayloadID{} - eq.buildingOnto = eth.L2BlockRef{} - eq.buildingSafe = false + return eq.ec.BuildingPayload() } // Reset walks the L2 chain backwards until it finds an L2 block whose L1 origin is canonical. @@ -800,22 +733,36 @@ func (eq *EngineQueue) Reset(ctx context.Context, _ eth.L1BlockRef, _ eth.System return NewTemporaryError(fmt.Errorf("failed to run pre fetch L1 receipts for L1 start block %s: %w", pipelineOrigin.ID(), err2)) } eq.log.Debug("Reset engine queue", "safeHead", safe, "unsafe", unsafe, "safe_timestamp", safe.Time, "unsafe_timestamp", unsafe.Time, "l1Origin", l1Origin) - eq.unsafeHead = unsafe - eq.engineSyncTarget = unsafe - eq.safeHead = safe + eq.ec.SetUnsafeHead(unsafe) + eq.ec.SetSafeHead(safe) + eq.ec.SetPendingSafeL2Head(safe) + eq.ec.SetFinalizedHead(finalized) + eq.ec.SetBackupUnsafeL2Head(eth.L2BlockRef{}, false) eq.safeAttributes = nil - eq.finalized = finalized - eq.resetBuildingState() - eq.needForkchoiceUpdate = true + eq.ec.ResetBuildingState() eq.finalityData = eq.finalityData[:0] // note: finalizedL1 and triedFinalizeAt do not reset, since these do not change between reorgs. // note: we do not clear the unsafe payloads queue; if the payloads are not applicable anymore the parent hash checks will clear out the old payloads. eq.origin = pipelineOrigin eq.sysCfg = l1Cfg - eq.metrics.RecordL2Ref("l2_finalized", finalized) - eq.metrics.RecordL2Ref("l2_safe", safe) - eq.metrics.RecordL2Ref("l2_unsafe", unsafe) - eq.metrics.RecordL2Ref("l2_engineSyncTarget", unsafe) + eq.lastNotifiedSafeHead = safe + if err := eq.safeHeadNotifs.SafeHeadReset(safe); err != nil { + return err + } + if eq.safeHeadNotifs.Enabled() && safe.Number == eq.cfg.Genesis.L2.Number && safe.Hash == eq.cfg.Genesis.L2.Hash { + // The rollup genesis block is always safe by definition. So if the pipeline resets this far back we know + // we will process all safe head updates and can record genesis as always safe from L1 genesis. + // Note that it is not safe to use cfg.Genesis.L1 here as it is the block immediately before the L2 genesis + // but the contracts may have been deployed earlier than that, allowing creating a dispute game + // with a L1 head prior to cfg.Genesis.L1 + l1Genesis, err := eq.l1Fetcher.L1BlockRefByNumber(ctx, 0) + if err != nil { + return fmt.Errorf("failed to retrieve L1 genesis: %w", err) + } + if err := eq.safeHeadNotifs.SafeHeadUpdated(safe, l1Genesis.ID()); err != nil { + return err + } + } eq.logSyncProgress("reset derivation work") return io.EOF } @@ -823,7 +770,7 @@ func (eq *EngineQueue) Reset(ctx context.Context, _ eth.L1BlockRef, _ eth.System // UnsafeL2SyncTarget retrieves the first queued-up L2 unsafe payload, or a zeroed reference if there is none. func (eq *EngineQueue) UnsafeL2SyncTarget() eth.L2BlockRef { if first := eq.unsafePayloads.Peek(); first != nil { - ref, err := PayloadToBlockRef(first, &eq.cfg.Genesis) + ref, err := PayloadToBlockRef(eq.cfg, first.ExecutionPayload) if err != nil { return eth.L2BlockRef{} } diff --git a/op-node/rollup/derive/engine_queue_test.go b/op-node/rollup/derive/engine_queue_test.go index b22e3f38336c..a482e01d4066 100644 --- a/op-node/rollup/derive/engine_queue_test.go +++ b/op-node/rollup/derive/engine_queue_test.go @@ -8,6 +8,7 @@ import ( "math/rand" "testing" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" "github.com/holiman/uint256" "github.com/stretchr/testify/require" @@ -16,6 +17,8 @@ import ( "github.com/ethereum-optimism/optimism/op-node/metrics" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/async" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" @@ -23,25 +26,26 @@ import ( ) type fakeAttributesQueue struct { - origin eth.L1BlockRef - attrs *eth.PayloadAttributes + origin eth.L1BlockRef + attrs *eth.PayloadAttributes + islastInSpan bool } func (f *fakeAttributesQueue) Origin() eth.L1BlockRef { return f.origin } -func (f *fakeAttributesQueue) NextAttributes(_ context.Context, _ eth.L2BlockRef) (*eth.PayloadAttributes, error) { +func (f *fakeAttributesQueue) NextAttributes(_ context.Context, safeHead eth.L2BlockRef) (*AttributesWithParent, error) { if f.attrs == nil { return nil, io.EOF } - return f.attrs, nil + return &AttributesWithParent{f.attrs, safeHead, f.islastInSpan}, nil } var _ NextAttributesProvider = (*fakeAttributesQueue)(nil) func TestEngineQueue_Finalize(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) rng := rand.New(rand.NewSource(1234)) @@ -249,37 +253,39 @@ func TestEngineQueue_Finalize(t *testing.T) { prev := &fakeAttributesQueue{} - eq := NewEngineQueue(logger, cfg, eng, metrics, prev, l1F, &sync.Config{}) + ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, sync.CLSync) + eq := NewEngineQueue(logger, cfg, eng, ec, metrics, prev, l1F, &sync.Config{}, safedb.Disabled) require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), io.EOF) - require.Equal(t, refB1, eq.SafeL2Head(), "L2 reset should go back to sequence window ago: blocks with origin E and D are not safe until we reconcile, C is extra, and B1 is the end we look for") + require.Equal(t, refB1, ec.SafeL2Head(), "L2 reset should go back to sequence window ago: blocks with origin E and D are not safe until we reconcile, C is extra, and B1 is the end we look for") require.Equal(t, refB, eq.Origin(), "Expecting to be set back derivation L1 progress to B") - require.Equal(t, refA1, eq.Finalized(), "A1 is recognized as finalized before we run any steps") + require.Equal(t, refA1, ec.Finalized(), "A1 is recognized as finalized before we run any steps") // now say C1 was included in D and became the new safe head eq.origin = refD prev.origin = refD - eq.safeHead = refC1 + eq.ec.SetSafeHead(refC1) l1F.ExpectClearReceiptsCacheBefore(refC1.L1Origin.Number) - eq.postProcessSafeL2() + require.NoError(t, eq.postProcessSafeL2()) // now say D0 was included in E and became the new safe head eq.origin = refE prev.origin = refE - eq.safeHead = refD0 + eq.ec.SetSafeHead(refD0) l1F.ExpectClearReceiptsCacheBefore(refD0.L1Origin.Number) - eq.postProcessSafeL2() + require.NoError(t, eq.postProcessSafeL2()) // let's finalize D (current L1), from which we fully derived C1 (it was safe head), but not D0 (included in E) eq.Finalize(refD) - require.Equal(t, refC1, eq.Finalized(), "C1 was included in finalized D, and should now be finalized") + require.Equal(t, refC1, ec.Finalized(), "C1 was included in finalized D, and should now be finalized") l1F.AssertExpectations(t) eng.AssertExpectations(t) } + func TestEngineQueue_ResetWhenUnsafeOriginNotCanonical(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) rng := rand.New(rand.NewSource(1234)) @@ -487,24 +493,24 @@ func TestEngineQueue_ResetWhenUnsafeOriginNotCanonical(t *testing.T) { prev := &fakeAttributesQueue{origin: refE} - eq := NewEngineQueue(logger, cfg, eng, metrics, prev, l1F, &sync.Config{}) + ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, sync.CLSync) + eq := NewEngineQueue(logger, cfg, eng, ec, metrics, prev, l1F, &sync.Config{}, safedb.Disabled) require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), io.EOF) - require.Equal(t, refB1, eq.SafeL2Head(), "L2 reset should go back to sequence window ago: blocks with origin E and D are not safe until we reconcile, C is extra, and B1 is the end we look for") + require.Equal(t, refB1, ec.SafeL2Head(), "L2 reset should go back to sequence window ago: blocks with origin E and D are not safe until we reconcile, C is extra, and B1 is the end we look for") require.Equal(t, refB, eq.Origin(), "Expecting to be set back derivation L1 progress to B") - require.Equal(t, refA1, eq.Finalized(), "A1 is recognized as finalized before we run any steps") + require.Equal(t, refA1, ec.Finalized(), "A1 is recognized as finalized before we run any steps") // First step after reset will do a fork choice update - require.True(t, eq.needForkchoiceUpdate) eng.ExpectForkchoiceUpdate(ð.ForkchoiceState{ - HeadBlockHash: eq.unsafeHead.Hash, - SafeBlockHash: eq.safeHead.Hash, - FinalizedBlockHash: eq.finalized.Hash, + HeadBlockHash: eq.ec.UnsafeL2Head().Hash, + SafeBlockHash: eq.ec.SafeL2Head().Hash, + FinalizedBlockHash: eq.ec.Finalized().Hash, }, nil, ð.ForkchoiceUpdatedResult{PayloadStatus: eth.PayloadStatusV1{Status: eth.ExecutionValid}}, nil) err := eq.Step(context.Background()) require.NoError(t, err) - require.Equal(t, refF.ID(), eq.unsafeHead.L1Origin, "should have refF as unsafe head origin") + require.Equal(t, refF.ID(), eq.ec.UnsafeL2Head().L1Origin, "should have refF as unsafe head origin") // L1 chain reorgs so new origin is at same slot as refF but on a different fork prev.origin = eth.L1BlockRef{ @@ -513,7 +519,6 @@ func TestEngineQueue_ResetWhenUnsafeOriginNotCanonical(t *testing.T) { ParentHash: refE.Hash, Time: refF.Time, } - eq.UnsafeL2Head() err = eq.Step(context.Background()) require.ErrorIs(t, err, ErrReset, "should reset pipeline due to mismatched origin") @@ -522,7 +527,7 @@ func TestEngineQueue_ResetWhenUnsafeOriginNotCanonical(t *testing.T) { } func TestVerifyNewL1Origin(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) rng := rand.New(rand.NewSource(1234)) @@ -827,28 +832,27 @@ func TestVerifyNewL1Origin(t *testing.T) { }, nil) prev := &fakeAttributesQueue{origin: refE} - eq := NewEngineQueue(logger, cfg, eng, metrics, prev, l1F, &sync.Config{}) + ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, sync.CLSync) + eq := NewEngineQueue(logger, cfg, eng, ec, metrics, prev, l1F, &sync.Config{}, safedb.Disabled) require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), io.EOF) - require.Equal(t, refB1, eq.SafeL2Head(), "L2 reset should go back to sequence window ago: blocks with origin E and D are not safe until we reconcile, C is extra, and B1 is the end we look for") + require.Equal(t, refB1, ec.SafeL2Head(), "L2 reset should go back to sequence window ago: blocks with origin E and D are not safe until we reconcile, C is extra, and B1 is the end we look for") require.Equal(t, refB, eq.Origin(), "Expecting to be set back derivation L1 progress to B") - require.Equal(t, refA1, eq.Finalized(), "A1 is recognized as finalized before we run any steps") + require.Equal(t, refA1, ec.Finalized(), "A1 is recognized as finalized before we run any steps") // First step after reset will do a fork choice update - require.True(t, eq.needForkchoiceUpdate) eng.ExpectForkchoiceUpdate(ð.ForkchoiceState{ - HeadBlockHash: eq.unsafeHead.Hash, - SafeBlockHash: eq.safeHead.Hash, - FinalizedBlockHash: eq.finalized.Hash, + HeadBlockHash: eq.ec.UnsafeL2Head().Hash, + SafeBlockHash: eq.ec.SafeL2Head().Hash, + FinalizedBlockHash: eq.ec.Finalized().Hash, }, nil, ð.ForkchoiceUpdatedResult{PayloadStatus: eth.PayloadStatusV1{Status: eth.ExecutionValid}}, nil) err := eq.Step(context.Background()) require.NoError(t, err) - require.Equal(t, refF.ID(), eq.unsafeHead.L1Origin, "should have refF as unsafe head origin") + require.Equal(t, refF.ID(), eq.ec.UnsafeL2Head().L1Origin, "should have refF as unsafe head origin") // L1 chain reorgs so new origin is at same slot as refF but on a different fork prev.origin = test.newOrigin - eq.UnsafeL2Head() if test.verifyPass { l1F.ExpectClearReceiptsCacheBefore(refB.Number) } @@ -866,7 +870,7 @@ func TestVerifyNewL1Origin(t *testing.T) { } func TestBlockBuildingRace(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) eng := &testutils.MockEngine{} rng := rand.New(rand.NewSource(1234)) @@ -929,8 +933,9 @@ func TestBlockBuildingRace(t *testing.T) { GasLimit: &gasLimit, } - prev := &fakeAttributesQueue{origin: refA, attrs: attrs} - eq := NewEngineQueue(logger, cfg, eng, metrics, prev, l1F, &sync.Config{}) + prev := &fakeAttributesQueue{origin: refA, attrs: attrs, islastInSpan: true} + ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, sync.CLSync) + eq := NewEngineQueue(logger, cfg, eng, ec, metrics, prev, l1F, &sync.Config{}, safedb.Disabled) require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), io.EOF) id := eth.PayloadID{0xff} @@ -966,7 +971,7 @@ func TestBlockBuildingRace(t *testing.T) { require.NotNil(t, eq.safeAttributes, "still have attributes") // Now allow the building to complete - a1InfoTx, err := L1InfoDepositBytes(refA1.SequenceNumber, &testutils.MockBlockInfo{ + a1InfoTx, err := L1InfoDepositBytes(cfg, cfg.Genesis.SystemConfig, refA1.SequenceNumber, &testutils.MockBlockInfo{ InfoHash: refA.Hash, InfoParentHash: refA.ParentHash, InfoCoinbase: common.Address{}, @@ -977,7 +982,7 @@ func TestBlockBuildingRace(t *testing.T) { InfoBaseFee: big.NewInt(7), InfoReceiptRoot: common.Hash{}, InfoGasUsed: 0, - }, cfg.Genesis.SystemConfig, false) + }, 0) require.NoError(t, err) payloadA1 := ð.ExecutionPayload{ @@ -992,14 +997,15 @@ func TestBlockBuildingRace(t *testing.T) { GasUsed: 0, Timestamp: eth.Uint64Quantity(refA1.Time), ExtraData: nil, - BaseFeePerGas: *uint256.NewInt(7), + BaseFeePerGas: eth.Uint256Quantity(*uint256.NewInt(7)), BlockHash: refA1.Hash, Transactions: []eth.Data{ a1InfoTx, }, } - eng.ExpectGetPayload(id, payloadA1, nil) - eng.ExpectNewPayload(payloadA1, ð.PayloadStatusV1{ + envelope := ð.ExecutionPayloadEnvelope{ExecutionPayload: payloadA1} + eng.ExpectGetPayload(id, envelope, nil) + eng.ExpectNewPayload(payloadA1, nil, ð.PayloadStatusV1{ Status: eth.ExecutionValid, LatestValidHash: &refA1.Hash, ValidationError: nil, @@ -1021,9 +1027,9 @@ func TestBlockBuildingRace(t *testing.T) { l1F.ExpectClearReceiptsCacheBefore(refA.Number) // Now complete the job, as external user of the engine - _, _, err = eq.ConfirmPayload(context.Background()) + _, _, err = eq.ConfirmPayload(context.Background(), async.NoOpGossiper{}, &conductor.NoOpConductor{}) require.NoError(t, err) - require.Equal(t, refA1, eq.SafeL2Head(), "safe head should have changed") + require.Equal(t, refA1, ec.SafeL2Head(), "safe head should have changed") require.NoError(t, eq.Step(context.Background())) require.Nil(t, eq.safeAttributes, "attributes should now be invalidated") @@ -1033,7 +1039,7 @@ func TestBlockBuildingRace(t *testing.T) { } func TestResetLoop(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) eng := &testutils.MockEngine{} l1F := &testutils.MockL1Source{} @@ -1101,30 +1107,38 @@ func TestResetLoop(t *testing.T) { l1F.ExpectL1BlockRefByHash(refA.Hash, refA, nil) l1F.ExpectGoOrUpdatePreFetchReceipts(context.Background(), refA.Number, nil) - prev := &fakeAttributesQueue{origin: refA, attrs: attrs} + prev := &fakeAttributesQueue{origin: refA, attrs: attrs, islastInSpan: true} - eq := NewEngineQueue(logger, cfg, eng, metrics.NoopMetrics, prev, l1F, &sync.Config{}) - eq.unsafeHead = refA2 - eq.engineSyncTarget = refA2 - eq.safeHead = refA1 - eq.finalized = refA0 + ec := NewEngineController(eng, logger, metrics.NoopMetrics, &rollup.Config{}, sync.CLSync) + eq := NewEngineQueue(logger, cfg, eng, ec, metrics.NoopMetrics, prev, l1F, &sync.Config{}, safedb.Disabled) + eq.ec.SetUnsafeHead(refA2) + eq.ec.SetSafeHead(refA1) + eq.ec.SetFinalizedHead(refA0) l1F.ExpectClearReceiptsCacheBefore(refA.Number) - // Qeueue up the safe attributes + // Queue up the safe attributes + // Expect a FCU after during the first step + preFc := ð.ForkchoiceState{ + HeadBlockHash: refA2.Hash, + SafeBlockHash: refA1.Hash, + FinalizedBlockHash: refA0.Hash, + } + eng.ExpectForkchoiceUpdate(preFc, nil, nil, nil) require.Nil(t, eq.safeAttributes) + require.ErrorIs(t, eq.Step(context.Background()), nil) require.ErrorIs(t, eq.Step(context.Background()), NotEnoughData) require.NotNil(t, eq.safeAttributes) - // Peform the reset + // Perform the reset require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), io.EOF) // Expect a FCU after the reset - preFc := ð.ForkchoiceState{ + postFc := ð.ForkchoiceState{ HeadBlockHash: refA2.Hash, SafeBlockHash: refA0.Hash, FinalizedBlockHash: refA0.Hash, } - eng.ExpectForkchoiceUpdate(preFc, nil, nil, nil) + eng.ExpectForkchoiceUpdate(postFc, nil, nil, nil) require.NoError(t, eq.Step(context.Background()), "clean forkchoice state after reset") l1F.ExpectClearReceiptsCacheBefore(refA.Number) @@ -1136,7 +1150,7 @@ func TestResetLoop(t *testing.T) { } func TestEngineQueue_StepPopOlderUnsafe(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LevelInfo) eng := &testutils.MockEngine{} l1F := &testutils.MockL1Source{} @@ -1184,7 +1198,7 @@ func TestEngineQueue_StepPopOlderUnsafe(t *testing.T) { L1Origin: refA.ID(), SequenceNumber: 2, } - payloadA1 := ð.ExecutionPayload{ + payloadA1 := ð.ExecutionPayloadEnvelope{ExecutionPayload: ð.ExecutionPayload{ ParentHash: refA1.ParentHash, FeeRecipient: common.Address{}, StateRoot: eth.Bytes32{}, @@ -1196,22 +1210,32 @@ func TestEngineQueue_StepPopOlderUnsafe(t *testing.T) { GasUsed: 0, Timestamp: eth.Uint64Quantity(refA1.Time), ExtraData: nil, - BaseFeePerGas: *uint256.NewInt(7), + BaseFeePerGas: eth.Uint256Quantity(*uint256.NewInt(7)), BlockHash: refA1.Hash, Transactions: []eth.Data{}, - } + }} prev := &fakeAttributesQueue{origin: refA} - eq := NewEngineQueue(logger, cfg, eng, metrics.NoopMetrics, prev, l1F, &sync.Config{}) - eq.unsafeHead = refA2 - eq.safeHead = refA0 - eq.finalized = refA0 + ec := NewEngineController(eng, logger, metrics.NoopMetrics, &rollup.Config{}, sync.CLSync) + eq := NewEngineQueue(logger, cfg, eng, ec, metrics.NoopMetrics, prev, l1F, &sync.Config{}, safedb.Disabled) + eq.ec.SetUnsafeHead(refA2) + eq.ec.SetSafeHead(refA0) + eq.ec.SetFinalizedHead(refA0) eq.AddUnsafePayload(payloadA1) - err := eq.Step(context.Background()) - require.NoError(t, err) + // First Step calls FCU + preFc := ð.ForkchoiceState{ + HeadBlockHash: refA2.Hash, + SafeBlockHash: refA0.Hash, + FinalizedBlockHash: refA0.Hash, + } + eng.ExpectForkchoiceUpdate(preFc, nil, nil, nil) + require.NoError(t, eq.Step(context.Background())) + + // Second Step pops the unsafe payload + require.NoError(t, eq.Step(context.Background())) require.Nil(t, eq.unsafePayloads.Peek(), "should pop the unsafe payload because it is too old") fmt.Println(eq.unsafePayloads.Peek()) @@ -1219,3 +1243,99 @@ func TestEngineQueue_StepPopOlderUnsafe(t *testing.T) { l1F.AssertExpectations(t) eng.AssertExpectations(t) } + +func TestPlasmaFinalityData(t *testing.T) { + logger := testlog.Logger(t, log.LevelInfo) + eng := &testutils.MockEngine{} + l1F := &testutils.MockL1Source{} + + rng := rand.New(rand.NewSource(1234)) + + refA := testutils.RandomBlockRef(rng) + refA0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: 0, + ParentHash: common.Hash{}, + Time: refA.Time, + L1Origin: refA.ID(), + SequenceNumber: 0, + } + + prev := &fakeAttributesQueue{origin: refA} + + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L1: refA.ID(), + L2: refA0.ID(), + L2Time: refA0.Time, + SystemConfig: eth.SystemConfig{ + BatcherAddr: common.Address{42}, + Overhead: [32]byte{123}, + Scalar: [32]byte{42}, + GasLimit: 20_000_000, + }, + }, + BlockTime: 1, + SeqWindowSize: 2, + UsePlasma: false, + DAChallengeWindow: 90, + DAResolveWindow: 90, + } + // shoud return l1 finality if plasma is not enabled + require.Equal(t, uint64(finalityLookback), calcFinalityLookback(cfg)) + + cfg.UsePlasma = true + expFinalityLookback := 181 + require.Equal(t, uint64(expFinalityLookback), calcFinalityLookback(cfg)) + + refA1 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: refA0.Number + 1, + ParentHash: refA0.Hash, + Time: refA0.Time + cfg.BlockTime, + L1Origin: refA.ID(), + SequenceNumber: 1, + } + + ec := NewEngineController(eng, logger, metrics.NoopMetrics, &rollup.Config{}, sync.CLSync) + + eq := NewEngineQueue(logger, cfg, eng, ec, metrics.NoopMetrics, prev, l1F, &sync.Config{}, safedb.Disabled) + require.Equal(t, expFinalityLookback, cap(eq.finalityData)) + + l1parent := refA + l2parent := refA1 + + ec.SetSafeHead(l2parent) + require.NoError(t, eq.postProcessSafeL2()) + + // advance over 200 l1 origins each time incrementing new l2 safe heads + // and post processing. + for i := uint64(0); i < 200; i++ { + require.NoError(t, eq.postProcessSafeL2()) + + l1parent = eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l1parent.Number + 1, + ParentHash: l1parent.Hash, + Time: l1parent.Time + 12, + } + eq.origin = l1parent + + for j := uint64(0); i < cfg.SeqWindowSize; i++ { + l2parent = eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2parent.Number + 1, + ParentHash: l2parent.Hash, + Time: l2parent.Time + cfg.BlockTime, + L1Origin: l1parent.ID(), + SequenceNumber: j, + } + ec.SetSafeHead(l2parent) + require.NoError(t, eq.postProcessSafeL2()) + } + } + + // finality data does not go over challenge + resolve windows + 1 capacity + // (prunes down to 180 then adds the extra 1 each time) + require.Equal(t, expFinalityLookback, len(eq.finalityData)) +} diff --git a/op-node/rollup/derive/engine_update.go b/op-node/rollup/derive/engine_update.go index 94a9542cb00e..d3e3c8bf1911 100644 --- a/op-node/rollup/derive/engine_update.go +++ b/op-node/rollup/derive/engine_update.go @@ -9,6 +9,8 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-node/rollup/async" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-service/eth" ) @@ -80,9 +82,9 @@ const ( BlockInsertPayloadErr ) -// StartPayload starts an execution payload building process in the provided Engine, with the given attributes. +// startPayload starts an execution payload building process in the provided Engine, with the given attributes. // The severity of the error is distinguished to determine whether the same payload attributes may be re-attempted later. -func StartPayload(ctx context.Context, eng Engine, fc eth.ForkchoiceState, attrs *eth.PayloadAttributes) (id eth.PayloadID, errType BlockInsertionErrType, err error) { +func startPayload(ctx context.Context, eng ExecEngine, fc eth.ForkchoiceState, attrs *eth.PayloadAttributes) (id eth.PayloadID, errType BlockInsertionErrType, err error) { fcRes, err := eng.ForkchoiceUpdate(ctx, &fc, attrs) if err != nil { var inputErr eth.InputError @@ -115,28 +117,57 @@ func StartPayload(ctx context.Context, eng Engine, fc eth.ForkchoiceState, attrs } } -// ConfirmPayload ends an execution payload building process in the provided Engine, and persists the payload as the canonical head. +// confirmPayload ends an execution payload building process in the provided Engine, and persists the payload as the canonical head. // If updateSafe is true, then the payload will also be recognized as safe-head at the same time. // The severity of the error is distinguished to determine whether the payload was valid and can become canonical. -func ConfirmPayload(ctx context.Context, log log.Logger, eng Engine, fc eth.ForkchoiceState, id eth.PayloadID, updateSafe bool, metrics Metrics) (out *eth.ExecutionPayload, errTyp BlockInsertionErrType, err error) { - start := time.Now() - payload, err := eng.GetPayload(ctx, id) +func confirmPayload( + ctx context.Context, + log log.Logger, + eng ExecEngine, + fc eth.ForkchoiceState, + payloadInfo eth.PayloadInfo, + updateSafe bool, + agossip async.AsyncGossiper, + sequencerConductor conductor.SequencerConductor, + metrics Metrics, +) (out *eth.ExecutionPayloadEnvelope, errTyp BlockInsertionErrType, err error) { + var envelope *eth.ExecutionPayloadEnvelope + // if the payload is available from the async gossiper, it means it was not yet imported, so we reuse it + if cached := agossip.Get(); cached != nil { + envelope = cached + // log a limited amount of information about the reused payload, more detailed logging happens later down + log.Debug("found uninserted payload from async gossiper, reusing it and bypassing engine", + "hash", envelope.ExecutionPayload.BlockHash, + "number", uint64(envelope.ExecutionPayload.BlockNumber), + "parent", envelope.ExecutionPayload.ParentHash, + "txs", len(envelope.ExecutionPayload.Transactions)) + } else { + start := time.Now() + envelope, err = eng.GetPayload(ctx, payloadInfo) + metrics.RecordSequencerStepTime("getPayload", time.Since(start)) + } if err != nil { // even if it is an input-error (unknown payload ID), it is temporary, since we will re-attempt the full payload building, not just the retrieval of the payload. return nil, BlockInsertTemporaryErr, fmt.Errorf("failed to get execution payload: %w", err) } - metrics.RecordSequencerStepTime("getPayload", time.Since(start)) - + payload := envelope.ExecutionPayload if err := sanityCheckPayload(payload); err != nil { return nil, BlockInsertPayloadErr, err } + if err := sequencerConductor.CommitUnsafePayload(ctx, envelope); err != nil { + return nil, BlockInsertTemporaryErr, fmt.Errorf("failed to commit unsafe payload to conductor: %w", err) + } + // begin gossiping as soon as possible + // agossip.Clear() will be called later if an non-temporary error is found, or if the payload is successfully inserted + agossip.Gossip(envelope) - start = time.Now() - status, err := eng.NewPayload(ctx, payload) + start := time.Now() + status, err := eng.NewPayload(ctx, payload, envelope.ParentBeaconBlockRoot) if err != nil { return nil, BlockInsertTemporaryErr, fmt.Errorf("failed to insert execution payload: %w", err) } if status.Status == eth.ExecutionInvalid || status.Status == eth.ExecutionInvalidBlockHash { + agossip.Clear() return nil, BlockInsertPayloadErr, eth.NewPayloadErr(payload, status) } if status.Status != eth.ExecutionValid { @@ -156,14 +187,17 @@ func ConfirmPayload(ctx context.Context, log log.Logger, eng Engine, fc eth.Fork switch inputErr.Code { case eth.InvalidForkchoiceState: // if we succeed to update the forkchoice pre-payload, but fail post-payload, then it is a payload error + agossip.Clear() return nil, BlockInsertPayloadErr, fmt.Errorf("post-block-creation forkchoice update was inconsistent with engine, need reset to resolve: %w", inputErr.Unwrap()) default: + agossip.Clear() return nil, BlockInsertPrestateErr, fmt.Errorf("unexpected error code in forkchoice-updated response: %w", err) } } else { return nil, BlockInsertTemporaryErr, fmt.Errorf("failed to make the new L2 block canonical via forkchoice: %w", err) } } + agossip.Clear() if fcRes.PayloadStatus.Status != eth.ExecutionValid { return nil, BlockInsertPayloadErr, eth.ForkchoiceUpdateErr(fcRes.PayloadStatus) } @@ -172,5 +206,5 @@ func ConfirmPayload(ctx context.Context, log log.Logger, eng Engine, fc eth.Fork "state_root", payload.StateRoot, "timestamp", uint64(payload.Timestamp), "parent", payload.ParentHash, "prev_randao", payload.PrevRandao, "fee_recipient", payload.FeeRecipient, "txs", len(payload.Transactions), "update_safe", updateSafe) - return payload, BlockInsertOK, nil + return envelope, BlockInsertOK, nil } diff --git a/op-node/rollup/derive/error.go b/op-node/rollup/derive/error.go index 929c93648df9..a09255144056 100644 --- a/op-node/rollup/derive/error.go +++ b/op-node/rollup/derive/error.go @@ -5,6 +5,23 @@ import ( "fmt" ) +var ( + ErrTypedTxTooShort = errors.New("typed transaction data too short") + + // NotEnoughData implies that the function currently does not have enough data to progress + // but if it is retried enough times, it will eventually return a real value or io.EOF + NotEnoughData = errors.New("not enough data") + + // EngineELSyncing implies that the execution engine is currently in progress of syncing. + EngineELSyncing = errors.New("engine is performing EL sync") + + // Sentinel errors, use these to get the severity of errors by calling + // errors.Is(err, ErrTemporary) for example. + ErrTemporary = NewTemporaryError(nil) + ErrReset = NewResetError(nil) + ErrCritical = NewCriticalError(nil) +) + // Level is the severity level of the error. type Level uint @@ -86,16 +103,3 @@ func NewResetError(err error) error { func NewCriticalError(err error) error { return NewError(err, LevelCritical) } - -// Sentinel errors, use these to get the severity of errors by calling -// errors.Is(err, ErrTemporary) for example. -var ErrTemporary = NewTemporaryError(nil) -var ErrReset = NewResetError(nil) -var ErrCritical = NewCriticalError(nil) - -// NotEnoughData implies that the function currently does not have enough data to progress -// but if it is retried enough times, it will eventually return a real value or io.EOF -var NotEnoughData = errors.New("not enough data") - -// EngineP2PSyncing implies that the execution engine is currently in progress of P2P sync. -var EngineP2PSyncing = errors.New("engine is P2P syncing") diff --git a/op-node/rollup/derive/frame.go b/op-node/rollup/derive/frame.go index e19ea9a03f96..0baa1e120a14 100644 --- a/op-node/rollup/derive/frame.go +++ b/op-node/rollup/derive/frame.go @@ -108,7 +108,7 @@ func (f *Frame) UnmarshalBinary(r ByteReader) error { // eofAsUnexpectedMissing converts an io.EOF in the error chain of err into an // io.ErrUnexpectedEOF. It should be used to convert intermediate io.EOF errors -// in unmarshaling code to achieve idiomatic error behavior. +// in unmarshalling code to achieve idiomatic error behavior. // Other errors are passed through unchanged. func eofAsUnexpectedMissing(err error) error { if errors.Is(err, io.EOF) { diff --git a/op-node/rollup/derive/fuzz_parsers_test.go b/op-node/rollup/derive/fuzz_parsers_test.go index 6e0e9ebe51b6..bf6bd5f9fd4f 100644 --- a/op-node/rollup/derive/fuzz_parsers_test.go +++ b/op-node/rollup/derive/fuzz_parsers_test.go @@ -43,8 +43,8 @@ func BytesToBigInt(b []byte) *big.Int { return new(big.Int).SetBytes(cap_byte_slice(b, 32)) } -// FuzzL1InfoRoundTrip checks that our encoder round trips properly -func FuzzL1InfoRoundTrip(f *testing.F) { +// FuzzL1InfoBedrockRoundTrip checks that our Bedrock l1 info encoder round trips properly +func FuzzL1InfoBedrockRoundTrip(f *testing.F) { f.Fuzz(func(t *testing.T, number, time uint64, baseFee, hash []byte, seqNumber uint64) { in := L1BlockInfo{ Number: number, @@ -53,12 +53,12 @@ func FuzzL1InfoRoundTrip(f *testing.F) { BlockHash: common.BytesToHash(hash), SequenceNumber: seqNumber, } - enc, err := in.MarshalBinary() + enc, err := in.marshalBinaryBedrock() if err != nil { t.Fatalf("Failed to marshal binary: %v", err) } var out L1BlockInfo - err = out.UnmarshalBinary(enc) + err = out.unmarshalBinaryBedrock(enc) if err != nil { t.Fatalf("Failed to unmarshal binary: %v", err) } @@ -69,9 +69,40 @@ func FuzzL1InfoRoundTrip(f *testing.F) { }) } -// FuzzL1InfoAgainstContract checks the custom marshalling functions against the contract -// bindings to ensure that our functions are up to date and match the bindings. -func FuzzL1InfoAgainstContract(f *testing.F) { +// FuzzL1InfoEcotoneRoundTrip checks that our Ecotone encoder round trips properly +func FuzzL1InfoEcotoneRoundTrip(f *testing.F) { + f.Fuzz(func(t *testing.T, number, time uint64, baseFee, blobBaseFee, hash []byte, seqNumber uint64, baseFeeScalar, blobBaseFeeScalar uint32) { + in := L1BlockInfo{ + Number: number, + Time: time, + BaseFee: BytesToBigInt(baseFee), + BlockHash: common.BytesToHash(hash), + SequenceNumber: seqNumber, + BlobBaseFee: BytesToBigInt(blobBaseFee), + BaseFeeScalar: baseFeeScalar, + BlobBaseFeeScalar: blobBaseFeeScalar, + } + enc, err := in.marshalBinaryEcotone() + if err != nil { + t.Fatalf("Failed to marshal binary: %v", err) + } + var out L1BlockInfo + err = out.unmarshalBinaryEcotone(enc) + if err != nil { + t.Fatalf("Failed to unmarshal binary: %v", err) + } + if !cmp.Equal(in, out, cmp.Comparer(testutils.BigEqual)) { + t.Fatalf("The data did not round trip correctly. in: %v. out: %v", in, out) + } + + }) +} + +// FuzzL1InfoAgainstContract checks the custom Bedrock L1 Info marshalling functions against the +// setL1BlockValues contract bindings to ensure that our functions are up to date and match the +// bindings. Note that we don't test setL1BlockValuesEcotone since it accepts only custom packed +// calldata and cannot be invoked using the generated bindings. +func FuzzL1InfoBedrockAgainstContract(f *testing.F) { f.Fuzz(func(t *testing.T, number, time uint64, baseFee, hash []byte, seqNumber uint64, batcherHash []byte, l1FeeOverhead []byte, l1FeeScalar []byte) { expected := L1BlockInfo{ Number: number, @@ -107,7 +138,7 @@ func FuzzL1InfoAgainstContract(f *testing.F) { // Check that our encoder produces the same value and that we // can decode the contract values exactly - enc, err := expected.MarshalBinary() + enc, err := expected.marshalBinaryBedrock() if err != nil { t.Fatalf("Failed to marshal binary: %v", err) } @@ -118,7 +149,7 @@ func FuzzL1InfoAgainstContract(f *testing.F) { } var actual L1BlockInfo - err = actual.UnmarshalBinary(tx.Data()) + err = actual.unmarshalBinaryBedrock(tx.Data()) if err != nil { t.Fatalf("Failed to unmarshal binary: %v", err) } diff --git a/op-node/rollup/derive/l1_block_info.go b/op-node/rollup/derive/l1_block_info.go index 83d8e0fe9bd3..4546c95bdb81 100644 --- a/op-node/rollup/derive/l1_block_info.go +++ b/op-node/rollup/derive/l1_block_info.go @@ -2,6 +2,7 @@ package derive import ( "bytes" + "encoding/binary" "errors" "fmt" "math/big" @@ -11,20 +12,24 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/solabi" ) const ( - L1InfoFuncSignature = "setL1BlockValues(uint64,uint64,uint256,bytes32,uint64,bytes32,uint256,uint256)" - L1InfoArguments = 8 - L1InfoLen = 4 + 32*L1InfoArguments + L1InfoFuncBedrockSignature = "setL1BlockValues(uint64,uint64,uint256,bytes32,uint64,bytes32,uint256,uint256)" + L1InfoFuncEcotoneSignature = "setL1BlockValuesEcotone()" + L1InfoArguments = 8 + L1InfoBedrockLen = 4 + 32*L1InfoArguments + L1InfoEcotoneLen = 4 + 32*5 // after Ecotone upgrade, args are packed into 5 32-byte slots ) var ( - L1InfoFuncBytes4 = crypto.Keccak256([]byte(L1InfoFuncSignature))[:4] - L1InfoDepositerAddress = common.HexToAddress("0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001") - L1BlockAddress = predeploys.L1BlockAddr + L1InfoFuncBedrockBytes4 = crypto.Keccak256([]byte(L1InfoFuncBedrockSignature))[:4] + L1InfoFuncEcotoneBytes4 = crypto.Keccak256([]byte(L1InfoFuncEcotoneSignature))[:4] + L1InfoDepositerAddress = common.HexToAddress("0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001") + L1BlockAddress = predeploys.L1BlockAddr ) const ( @@ -41,12 +46,17 @@ type L1BlockInfo struct { // i.e. when the actual L1 info was first introduced. SequenceNumber uint64 // BatcherHash version 0 is just the address with 0 padding to the left. - BatcherAddr common.Address - L1FeeOverhead eth.Bytes32 - L1FeeScalar eth.Bytes32 + BatcherAddr common.Address + + L1FeeOverhead eth.Bytes32 // ignored after Ecotone upgrade + L1FeeScalar eth.Bytes32 // ignored after Ecotone upgrade + + BlobBaseFee *big.Int // added by Ecotone upgrade + BaseFeeScalar uint32 // added by Ecotone upgrade + BlobBaseFeeScalar uint32 // added by Ecotone upgrade } -// Binary Format +// Bedrock Binary Format // +---------+--------------------------+ // | Bytes | Field | // +---------+--------------------------+ @@ -56,14 +66,14 @@ type L1BlockInfo struct { // | 32 | BaseFee | // | 32 | BlockHash | // | 32 | SequenceNumber | -// | 32 | BatcherAddr | +// | 32 | BatcherHash | // | 32 | L1FeeOverhead | // | 32 | L1FeeScalar | // +---------+--------------------------+ -func (info *L1BlockInfo) MarshalBinary() ([]byte, error) { - w := bytes.NewBuffer(make([]byte, 0, L1InfoLen)) - if err := solabi.WriteSignature(w, L1InfoFuncBytes4); err != nil { +func (info *L1BlockInfo) marshalBinaryBedrock() ([]byte, error) { + w := bytes.NewBuffer(make([]byte, 0, L1InfoBedrockLen)) + if err := solabi.WriteSignature(w, L1InfoFuncBedrockBytes4); err != nil { return nil, err } if err := solabi.WriteUint64(w, info.Number); err != nil { @@ -93,14 +103,14 @@ func (info *L1BlockInfo) MarshalBinary() ([]byte, error) { return w.Bytes(), nil } -func (info *L1BlockInfo) UnmarshalBinary(data []byte) error { - if len(data) != L1InfoLen { +func (info *L1BlockInfo) unmarshalBinaryBedrock(data []byte) error { + if len(data) != L1InfoBedrockLen { return fmt.Errorf("data is unexpected length: %d", len(data)) } reader := bytes.NewReader(data) var err error - if _, err := solabi.ReadAndValidateSignature(reader, L1InfoFuncBytes4); err != nil { + if _, err := solabi.ReadAndValidateSignature(reader, L1InfoFuncBedrockBytes4); err != nil { return err } if info.Number, err = solabi.ReadUint64(reader); err != nil { @@ -133,29 +143,158 @@ func (info *L1BlockInfo) UnmarshalBinary(data []byte) error { return nil } -// L1InfoDepositTxData is the inverse of L1InfoDeposit, to see where the L2 chain is derived from -func L1InfoDepositTxData(data []byte) (L1BlockInfo, error) { +// Ecotone Binary Format +// +---------+--------------------------+ +// | Bytes | Field | +// +---------+--------------------------+ +// | 4 | Function signature | +// | 4 | BaseFeeScalar | +// | 4 | BlobBaseFeeScalar | +// | 8 | SequenceNumber | +// | 8 | Timestamp | +// | 8 | L1BlockNumber | +// | 32 | BaseFee | +// | 32 | BlobBaseFee | +// | 32 | BlockHash | +// | 32 | BatcherHash | +// +---------+--------------------------+ + +func (info *L1BlockInfo) marshalBinaryEcotone() ([]byte, error) { + w := bytes.NewBuffer(make([]byte, 0, L1InfoEcotoneLen)) + if err := solabi.WriteSignature(w, L1InfoFuncEcotoneBytes4); err != nil { + return nil, err + } + if err := binary.Write(w, binary.BigEndian, info.BaseFeeScalar); err != nil { + return nil, err + } + if err := binary.Write(w, binary.BigEndian, info.BlobBaseFeeScalar); err != nil { + return nil, err + } + if err := binary.Write(w, binary.BigEndian, info.SequenceNumber); err != nil { + return nil, err + } + if err := binary.Write(w, binary.BigEndian, info.Time); err != nil { + return nil, err + } + if err := binary.Write(w, binary.BigEndian, info.Number); err != nil { + return nil, err + } + if err := solabi.WriteUint256(w, info.BaseFee); err != nil { + return nil, err + } + blobBasefee := info.BlobBaseFee + if blobBasefee == nil { + blobBasefee = big.NewInt(1) // set to 1, to match the min blob basefee as defined in EIP-4844 + } + if err := solabi.WriteUint256(w, blobBasefee); err != nil { + return nil, err + } + if err := solabi.WriteHash(w, info.BlockHash); err != nil { + return nil, err + } + // ABI encoding will perform the left-padding with zeroes to 32 bytes, matching the "batcherHash" SystemConfig format and version 0 byte. + if err := solabi.WriteAddress(w, info.BatcherAddr); err != nil { + return nil, err + } + return w.Bytes(), nil +} + +func (info *L1BlockInfo) unmarshalBinaryEcotone(data []byte) error { + if len(data) != L1InfoEcotoneLen { + return fmt.Errorf("data is unexpected length: %d", len(data)) + } + r := bytes.NewReader(data) + + var err error + if _, err := solabi.ReadAndValidateSignature(r, L1InfoFuncEcotoneBytes4); err != nil { + return err + } + if err := binary.Read(r, binary.BigEndian, &info.BaseFeeScalar); err != nil { + return fmt.Errorf("invalid ecotone l1 block info format") + } + if err := binary.Read(r, binary.BigEndian, &info.BlobBaseFeeScalar); err != nil { + return fmt.Errorf("invalid ecotone l1 block info format") + } + if err := binary.Read(r, binary.BigEndian, &info.SequenceNumber); err != nil { + return fmt.Errorf("invalid ecotone l1 block info format") + } + if err := binary.Read(r, binary.BigEndian, &info.Time); err != nil { + return fmt.Errorf("invalid ecotone l1 block info format") + } + if err := binary.Read(r, binary.BigEndian, &info.Number); err != nil { + return fmt.Errorf("invalid ecotone l1 block info format") + } + if info.BaseFee, err = solabi.ReadUint256(r); err != nil { + return err + } + if info.BlobBaseFee, err = solabi.ReadUint256(r); err != nil { + return err + } + if info.BlockHash, err = solabi.ReadHash(r); err != nil { + return err + } + // The "batcherHash" will be correctly parsed as address, since the version 0 and left-padding matches the ABI encoding format. + if info.BatcherAddr, err = solabi.ReadAddress(r); err != nil { + return err + } + if !solabi.EmptyReader(r) { + return errors.New("too many bytes") + } + return nil +} + +// isEcotoneButNotFirstBlock returns whether the specified block is subject to the Ecotone upgrade, +// but is not the actiation block itself. +func isEcotoneButNotFirstBlock(rollupCfg *rollup.Config, l2BlockTime uint64) bool { + return rollupCfg.IsEcotone(l2BlockTime) && !rollupCfg.IsEcotoneActivationBlock(l2BlockTime) +} + +// L1BlockInfoFromBytes is the inverse of L1InfoDeposit, to see where the L2 chain is derived from +func L1BlockInfoFromBytes(rollupCfg *rollup.Config, l2BlockTime uint64, data []byte) (*L1BlockInfo, error) { var info L1BlockInfo - err := info.UnmarshalBinary(data) - return info, err + if isEcotoneButNotFirstBlock(rollupCfg, l2BlockTime) { + return &info, info.unmarshalBinaryEcotone(data) + } + return &info, info.unmarshalBinaryBedrock(data) } // L1InfoDeposit creates a L1 Info deposit transaction based on the L1 block, // and the L2 block-height difference with the start of the epoch. -func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfig, regolith bool) (*types.DepositTx, error) { - infoDat := L1BlockInfo{ +func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, block eth.BlockInfo, l2BlockTime uint64) (*types.DepositTx, error) { + l1BlockInfo := L1BlockInfo{ Number: block.NumberU64(), Time: block.Time(), BaseFee: block.BaseFee(), BlockHash: block.Hash(), SequenceNumber: seqNumber, BatcherAddr: sysCfg.BatcherAddr, - L1FeeOverhead: sysCfg.Overhead, - L1FeeScalar: sysCfg.Scalar, } - data, err := infoDat.MarshalBinary() - if err != nil { - return nil, err + var data []byte + if isEcotoneButNotFirstBlock(rollupCfg, l2BlockTime) { + l1BlockInfo.BlobBaseFee = block.BlobBaseFee() + if l1BlockInfo.BlobBaseFee == nil { + // The L2 spec states to use the MIN_BLOB_GASPRICE from EIP-4844 if not yet active on L1. + l1BlockInfo.BlobBaseFee = big.NewInt(1) + } + blobBaseFeeScalar, baseFeeScalar, err := sysCfg.EcotoneScalars() + if err != nil { + return nil, err + } + l1BlockInfo.BlobBaseFeeScalar = blobBaseFeeScalar + l1BlockInfo.BaseFeeScalar = baseFeeScalar + out, err := l1BlockInfo.marshalBinaryEcotone() + if err != nil { + return nil, fmt.Errorf("failed to marshal Ecotone l1 block info: %w", err) + } + data = out + } else { + l1BlockInfo.L1FeeOverhead = sysCfg.Overhead + l1BlockInfo.L1FeeScalar = sysCfg.Scalar + out, err := l1BlockInfo.marshalBinaryBedrock() + if err != nil { + return nil, fmt.Errorf("failed to marshal Bedrock l1 block info: %w", err) + } + data = out } source := L1InfoDepositSource{ @@ -175,7 +314,7 @@ func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfi Data: data, } // With the regolith fork we disable the IsSystemTx functionality, and allocate real gas - if regolith { + if rollupCfg.IsRegolith(l2BlockTime) { out.IsSystemTransaction = false out.Gas = RegolithSystemTxGas } @@ -183,8 +322,8 @@ func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfi } // L1InfoDepositBytes returns a serialized L1-info attributes transaction. -func L1InfoDepositBytes(seqNumber uint64, l1Info eth.BlockInfo, sysCfg eth.SystemConfig, regolith bool) ([]byte, error) { - dep, err := L1InfoDeposit(seqNumber, l1Info, sysCfg, regolith) +func L1InfoDepositBytes(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, l1Info eth.BlockInfo, l2BlockTime uint64) ([]byte, error) { + dep, err := L1InfoDeposit(rollupCfg, sysCfg, seqNumber, l1Info, l2BlockTime) if err != nil { return nil, fmt.Errorf("failed to create L1 info tx: %w", err) } diff --git a/op-node/rollup/derive/l1_block_info_test.go b/op-node/rollup/derive/l1_block_info_test.go index ba3b68d0ef5f..e5c9253ce1c6 100644 --- a/op-node/rollup/derive/l1_block_info_test.go +++ b/op-node/rollup/derive/l1_block_info_test.go @@ -11,11 +11,15 @@ import ( "github.com/ethereum/go-ethereum/common" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testutils" ) -var _ eth.BlockInfo = (*testutils.MockBlockInfo)(nil) +var ( + MockDepositContractAddr = common.HexToAddress("0xdeadbeefdeadbeefdeadbeefdeadbeef00000000") + _ eth.BlockInfo = (*testutils.MockBlockInfo)(nil) +) type infoTest struct { name string @@ -33,8 +37,6 @@ func randomL1Cfg(rng *rand.Rand, l1Info eth.BlockInfo) eth.SystemConfig { } } -var MockDepositContractAddr = common.HexToAddress("0xdeadbeefdeadbeefdeadbeefdeadbeef00000000") - func TestParseL1InfoDepositTxData(t *testing.T) { randomSeqNr := func(rng *rand.Rand) uint64 { return rng.Uint64() @@ -60,15 +62,16 @@ func TestParseL1InfoDepositTxData(t *testing.T) { return 0 }}, } + var rollupCfg rollup.Config for i, testCase := range cases { t.Run(testCase.name, func(t *testing.T) { rng := rand.New(rand.NewSource(int64(1234 + i))) info := testCase.mkInfo(rng) l1Cfg := testCase.mkL1Cfg(rng, info) seqNr := testCase.seqNr(rng) - depTx, err := L1InfoDeposit(seqNr, info, l1Cfg, false) + depTx, err := L1InfoDeposit(&rollupCfg, l1Cfg, seqNr, info, 0) require.NoError(t, err) - res, err := L1InfoDepositTxData(depTx.Data) + res, err := L1BlockInfoFromBytes(&rollupCfg, info.Time(), depTx.Data) require.NoError(t, err, "expected valid deposit info") assert.Equal(t, res.Number, info.NumberU64()) assert.Equal(t, res.Time, info.Time()) @@ -82,33 +85,81 @@ func TestParseL1InfoDepositTxData(t *testing.T) { }) } t.Run("no data", func(t *testing.T) { - _, err := L1InfoDepositTxData(nil) + _, err := L1BlockInfoFromBytes(&rollupCfg, 0, nil) assert.Error(t, err) }) t.Run("not enough data", func(t *testing.T) { - _, err := L1InfoDepositTxData([]byte{1, 2, 3, 4}) + _, err := L1BlockInfoFromBytes(&rollupCfg, 0, []byte{1, 2, 3, 4}) assert.Error(t, err) }) t.Run("too much data", func(t *testing.T) { - _, err := L1InfoDepositTxData(make([]byte, 4+32+32+32+32+32+1)) + _, err := L1BlockInfoFromBytes(&rollupCfg, 0, make([]byte, 4+32+32+32+32+32+1)) assert.Error(t, err) }) t.Run("invalid selector", func(t *testing.T) { rng := rand.New(rand.NewSource(1234)) info := testutils.MakeBlockInfo(nil)(rng) - depTx, err := L1InfoDeposit(randomSeqNr(rng), info, randomL1Cfg(rng, info), false) + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 0) require.NoError(t, err) _, err = crand.Read(depTx.Data[0:4]) require.NoError(t, err) - _, err = L1InfoDepositTxData(depTx.Data) + _, err = L1BlockInfoFromBytes(&rollupCfg, info.Time(), depTx.Data) require.ErrorContains(t, err, "function signature") }) t.Run("regolith", func(t *testing.T) { rng := rand.New(rand.NewSource(1234)) info := testutils.MakeBlockInfo(nil)(rng) - depTx, err := L1InfoDeposit(randomSeqNr(rng), info, randomL1Cfg(rng, info), true) + zero := uint64(0) + rollupCfg := rollup.Config{ + RegolithTime: &zero, + } + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 0) + require.NoError(t, err) + require.False(t, depTx.IsSystemTransaction) + require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas)) + }) + t.Run("ecotone", func(t *testing.T) { + rng := rand.New(rand.NewSource(1234)) + info := testutils.MakeBlockInfo(nil)(rng) + zero := uint64(0) + rollupCfg := rollup.Config{ + RegolithTime: &zero, + EcotoneTime: &zero, + } + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 1) + require.NoError(t, err) + require.False(t, depTx.IsSystemTransaction) + require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas)) + require.Equal(t, L1InfoEcotoneLen, len(depTx.Data)) + }) + t.Run("first-block ecotone", func(t *testing.T) { + rng := rand.New(rand.NewSource(1234)) + info := testutils.MakeBlockInfo(nil)(rng) + zero := uint64(2) + rollupCfg := rollup.Config{ + RegolithTime: &zero, + EcotoneTime: &zero, + BlockTime: 2, + } + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 2) + require.NoError(t, err) + require.False(t, depTx.IsSystemTransaction) + require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas)) + require.Equal(t, L1InfoBedrockLen, len(depTx.Data)) + }) + t.Run("genesis-block ecotone", func(t *testing.T) { + rng := rand.New(rand.NewSource(1234)) + info := testutils.MakeBlockInfo(nil)(rng) + zero := uint64(0) + rollupCfg := rollup.Config{ + RegolithTime: &zero, + EcotoneTime: &zero, + BlockTime: 2, + } + depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 0) require.NoError(t, err) require.False(t, depTx.IsSystemTransaction) require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas)) + require.Equal(t, L1InfoEcotoneLen, len(depTx.Data)) }) } diff --git a/op-node/rollup/derive/l1_block_info_tob_test.go b/op-node/rollup/derive/l1_block_info_tob_test.go index b3e0fadb0253..d7c9f2f8931d 100644 --- a/op-node/rollup/derive/l1_block_info_tob_test.go +++ b/op-node/rollup/derive/l1_block_info_tob_test.go @@ -3,6 +3,7 @@ package derive import ( "testing" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testutils" "github.com/ethereum-optimism/optimism/op-service/testutils/fuzzerutils" @@ -25,13 +26,14 @@ func FuzzParseL1InfoDepositTxDataValid(f *testing.F) { typeProvider.Fuzz(&seqNr) var sysCfg eth.SystemConfig typeProvider.Fuzz(&sysCfg) + var rollupCfg rollup.Config // Create our deposit tx from our info - depTx, err := L1InfoDeposit(seqNr, &l1Info, sysCfg, false) + depTx, err := L1InfoDeposit(&rollupCfg, sysCfg, seqNr, &l1Info, 0) require.NoError(t, err, "error creating deposit tx from L1 info") // Get our info from out deposit tx - res, err := L1InfoDepositTxData(depTx.Data) + res, err := L1BlockInfoFromBytes(&rollupCfg, l1Info.InfoTime, depTx.Data) require.NoError(t, err, "expected valid deposit info") // Verify all parameters match in our round trip deriving operations @@ -50,9 +52,10 @@ func FuzzParseL1InfoDepositTxDataValid(f *testing.F) { // Reverse of the above test. Accepts a random byte string and attempts to extract L1Info from it, // then attempts to convert that info back into the tx data and compare it with the original input. func FuzzDecodeDepositTxDataToL1Info(f *testing.F) { + var rollupCfg rollup.Config f.Fuzz(func(t *testing.T, fuzzedData []byte) { // Get our info from out deposit tx - res, err := L1InfoDepositTxData(fuzzedData) + res, err := L1BlockInfoFromBytes(&rollupCfg, 0, fuzzedData) if err != nil { return } @@ -71,7 +74,7 @@ func FuzzDecodeDepositTxDataToL1Info(f *testing.F) { GasLimit: uint64(0), } - depTx, err := L1InfoDeposit(res.SequenceNumber, &l1Info, sysCfg, false) + depTx, err := L1InfoDeposit(&rollupCfg, sysCfg, res.SequenceNumber, &l1Info, 0) require.NoError(t, err, "error creating deposit tx from L1 info") require.Equal(t, depTx.Data, fuzzedData) }) @@ -81,10 +84,11 @@ func FuzzDecodeDepositTxDataToL1Info(f *testing.F) { // random L1 deposit tx info and derives a tx from it, then derives the info back from the tx, to ensure round-trip // derivation is upheld. This generates "invalid" data and ensures it always throws an error where expected. func FuzzParseL1InfoDepositTxDataBadLength(f *testing.F) { + var rollupCfg rollup.Config const expectedDepositTxDataLength = 4 + 32 + 32 + 32 + 32 + 32 f.Fuzz(func(t *testing.T, fuzzedData []byte) { // Derive a transaction from random fuzzed data - _, err := L1InfoDepositTxData(fuzzedData) + _, err := L1BlockInfoFromBytes(&rollupCfg, 0, fuzzedData) // If the data is null, or too short or too long, we expect an error if fuzzedData == nil || len(fuzzedData) != expectedDepositTxDataLength { diff --git a/op-node/rollup/derive/l1_retrieval.go b/op-node/rollup/derive/l1_retrieval.go index 586e125acc32..87b68b96522f 100644 --- a/op-node/rollup/derive/l1_retrieval.go +++ b/op-node/rollup/derive/l1_retrieval.go @@ -2,6 +2,7 @@ package derive import ( "context" + "fmt" "io" "github.com/ethereum/go-ethereum/common" @@ -11,7 +12,7 @@ import ( ) type DataAvailabilitySource interface { - OpenData(ctx context.Context, id eth.BlockID, batcherAddr common.Address) DataIter + OpenData(ctx context.Context, ref eth.L1BlockRef, batcherAddr common.Address) (DataIter, error) } type NextBlockProvider interface { @@ -53,7 +54,9 @@ func (l1r *L1Retrieval) NextData(ctx context.Context) ([]byte, error) { } else if err != nil { return nil, err } - l1r.datas = l1r.dataSrc.OpenData(ctx, next.ID(), l1r.prev.SystemConfig().BatcherAddr) + if l1r.datas, err = l1r.dataSrc.OpenData(ctx, next, l1r.prev.SystemConfig().BatcherAddr); err != nil { + return nil, fmt.Errorf("failed to open data source: %w", err) + } } l1r.log.Debug("fetching next piece of data") @@ -70,10 +73,13 @@ func (l1r *L1Retrieval) NextData(ctx context.Context) ([]byte, error) { } // Reset re-initializes the L1 Retrieval stage to block of it's `next` progress. -// Note that we open up the `l1r.datas` here because it is requires to maintain the +// Note that we open up the `l1r.datas` here because it is required to maintain the // internal invariants that later propagate up the derivation pipeline. func (l1r *L1Retrieval) Reset(ctx context.Context, base eth.L1BlockRef, sysCfg eth.SystemConfig) error { - l1r.datas = l1r.dataSrc.OpenData(ctx, base.ID(), sysCfg.BatcherAddr) + var err error + if l1r.datas, err = l1r.dataSrc.OpenData(ctx, base, sysCfg.BatcherAddr); err != nil { + return fmt.Errorf("failed to open data source: %w", err) + } l1r.log.Info("Reset of L1Retrieval done", "origin", base) return io.EOF } diff --git a/op-node/rollup/derive/l1_retrieval_test.go b/op-node/rollup/derive/l1_retrieval_test.go index e27cadbceb7f..8851957b43a1 100644 --- a/op-node/rollup/derive/l1_retrieval_test.go +++ b/op-node/rollup/derive/l1_retrieval_test.go @@ -35,13 +35,13 @@ type MockDataSource struct { mock.Mock } -func (m *MockDataSource) OpenData(ctx context.Context, id eth.BlockID, batcherAddr common.Address) DataIter { - out := m.Mock.MethodCalled("OpenData", id, batcherAddr) - return out[0].(DataIter) +func (m *MockDataSource) OpenData(ctx context.Context, ref eth.L1BlockRef, batcherAddr common.Address) (DataIter, error) { + out := m.Mock.MethodCalled("OpenData", ref, batcherAddr) + return out[0].(DataIter), nil } -func (m *MockDataSource) ExpectOpenData(id eth.BlockID, iter DataIter, batcherAddr common.Address) { - m.Mock.On("OpenData", id, batcherAddr).Return(iter) +func (m *MockDataSource) ExpectOpenData(ref eth.L1BlockRef, iter DataIter, batcherAddr common.Address) { + m.Mock.On("OpenData", ref, batcherAddr).Return(iter) } var _ DataAvailabilitySource = (*MockDataSource)(nil) @@ -89,10 +89,10 @@ func TestL1RetrievalReset(t *testing.T) { BatcherAddr: common.Address{42}, } - dataSrc.ExpectOpenData(a.ID(), &fakeDataIter{}, l1Cfg.BatcherAddr) + dataSrc.ExpectOpenData(a, &fakeDataIter{}, l1Cfg.BatcherAddr) defer dataSrc.AssertExpectations(t) - l1r := NewL1Retrieval(testlog.Logger(t, log.LvlError), dataSrc, nil) + l1r := NewL1Retrieval(testlog.Logger(t, log.LevelError), dataSrc, nil) // We assert that it opens up the correct data on a reset _ = l1r.Reset(context.Background(), a, l1Cfg) @@ -147,9 +147,9 @@ func TestL1RetrievalNextData(t *testing.T) { l1t := &MockL1Traversal{} l1t.ExpectNextL1Block(test.prevBlock, test.prevErr) dataSrc := &MockDataSource{} - dataSrc.ExpectOpenData(test.prevBlock.ID(), &fakeDataIter{data: test.datas, errs: test.datasErrs}, test.sysCfg.BatcherAddr) + dataSrc.ExpectOpenData(test.prevBlock, &fakeDataIter{data: test.datas, errs: test.datasErrs}, test.sysCfg.BatcherAddr) - ret := NewL1Retrieval(testlog.Logger(t, log.LvlCrit), dataSrc, l1t) + ret := NewL1Retrieval(testlog.Logger(t, log.LevelCrit), dataSrc, l1t) // If prevErr != nil we forced an error while getting data from the previous stage if test.openErr != nil { diff --git a/op-node/rollup/derive/l1_traversal.go b/op-node/rollup/derive/l1_traversal.go index f5386b7c9f11..84d2fbc9700f 100644 --- a/op-node/rollup/derive/l1_traversal.go +++ b/op-node/rollup/derive/l1_traversal.go @@ -76,9 +76,9 @@ func (l1t *L1Traversal) AdvanceL1Block(ctx context.Context) error { if err != nil { return NewTemporaryError(fmt.Errorf("failed to fetch receipts of L1 block %s (parent: %s) for L1 sysCfg update: %w", nextL1Origin, origin, err)) } - if err := UpdateSystemConfigWithL1Receipts(&l1t.sysCfg, receipts, l1t.cfg); err != nil { + if err := UpdateSystemConfigWithL1Receipts(&l1t.sysCfg, receipts, l1t.cfg, nextL1Origin.Time); err != nil { // the sysCfg changes should always be formatted correctly. - return NewCriticalError(fmt.Errorf("failed to update L1 sysCfg with receipts from block %s: %w", origin, err)) + return NewCriticalError(fmt.Errorf("failed to update L1 sysCfg with receipts from block %s: %w", nextL1Origin, err)) } l1t.block = nextL1Origin diff --git a/op-node/rollup/derive/l1_traversal_test.go b/op-node/rollup/derive/l1_traversal_test.go index 544b10e58cf8..1826562c789a 100644 --- a/op-node/rollup/derive/l1_traversal_test.go +++ b/op-node/rollup/derive/l1_traversal_test.go @@ -36,7 +36,7 @@ func TestL1TraversalNext(t *testing.T) { Genesis: rollup.Genesis{SystemConfig: l1Cfg}, L1SystemConfigAddress: sysCfgAddr, } - tr := NewL1Traversal(testlog.Logger(t, log.LvlError), cfg, nil) + tr := NewL1Traversal(testlog.Logger(t, log.LevelError), cfg, nil) _ = tr.Reset(context.Background(), a, l1Cfg) @@ -132,7 +132,7 @@ func TestL1TraversalAdvance(t *testing.T) { Genesis: rollup.Genesis{SystemConfig: test.initialL1Cfg}, L1SystemConfigAddress: sysCfgAddr, } - tr := NewL1Traversal(testlog.Logger(t, log.LvlError), cfg, src) + tr := NewL1Traversal(testlog.Logger(t, log.LevelError), cfg, src) // Load up the initial state with a reset _ = tr.Reset(context.Background(), test.startBlock, test.initialL1Cfg) diff --git a/op-node/rollup/derive/l2block_util.go b/op-node/rollup/derive/l2block_util.go index b141567989af..5946247c7dc6 100644 --- a/op-node/rollup/derive/l2block_util.go +++ b/op-node/rollup/derive/l2block_util.go @@ -25,11 +25,12 @@ type L2BlockRefSource interface { // L2BlockToBlockRef extracts the essential L2BlockRef information from an L2 // block ref source, falling back to genesis information if necessary. -func L2BlockToBlockRef(block L2BlockRefSource, genesis *rollup.Genesis) (eth.L2BlockRef, error) { +func L2BlockToBlockRef(rollupCfg *rollup.Config, block L2BlockRefSource) (eth.L2BlockRef, error) { hash, number := block.Hash(), block.NumberU64() var l1Origin eth.BlockID var sequenceNumber uint64 + genesis := &rollupCfg.Genesis if number == genesis.L2.Number { if hash != genesis.L2.Hash { return eth.L2BlockRef{}, fmt.Errorf("expected L2 genesis hash to match L2 block at genesis block number %d: %s <> %s", genesis.L2.Number, hash, genesis.L2.Hash) @@ -45,7 +46,7 @@ func L2BlockToBlockRef(block L2BlockRefSource, genesis *rollup.Genesis) (eth.L2B if tx.Type() != types.DepositTxType { return eth.L2BlockRef{}, fmt.Errorf("first payload tx has unexpected tx type: %d", tx.Type()) } - info, err := L1InfoDepositTxData(tx.Data()) + info, err := L1BlockInfoFromBytes(rollupCfg, block.Time(), tx.Data()) if err != nil { return eth.L2BlockRef{}, fmt.Errorf("failed to parse L1 info deposit tx from L2 block: %w", err) } diff --git a/op-node/rollup/derive/params.go b/op-node/rollup/derive/params.go index bba78cc2dfee..35ac8667e83c 100644 --- a/op-node/rollup/derive/params.go +++ b/op-node/rollup/derive/params.go @@ -4,6 +4,8 @@ import ( "encoding/hex" "errors" "fmt" + + plasma "github.com/ethereum-optimism/optimism/op-plasma" ) // count the tagging info as 200 in terms of buffer size. @@ -19,6 +21,9 @@ func frameSize(frame Frame) uint64 { const DerivationVersion0 = 0 +// DerivationVersion1 is reserved for batcher transactions containing plasma commitments. +const DerivationVersion1 = plasma.TxDataVersion1 + // MaxSpanBatchSize is the maximum amount of bytes that will be needed // to decode every span batch field. This value cannot be larger than // MaxRLPBytesPerChannel because single batch cannot be larger than channel size. diff --git a/op-node/rollup/derive/payload_util.go b/op-node/rollup/derive/payload_util.go index 11a183992be2..06a3a5a7f754 100644 --- a/op-node/rollup/derive/payload_util.go +++ b/op-node/rollup/derive/payload_util.go @@ -1,6 +1,7 @@ package derive import ( + "encoding/binary" "fmt" "github.com/ethereum/go-ethereum/core/types" @@ -11,7 +12,8 @@ import ( // PayloadToBlockRef extracts the essential L2BlockRef information from an execution payload, // falling back to genesis information if necessary. -func PayloadToBlockRef(payload *eth.ExecutionPayload, genesis *rollup.Genesis) (eth.L2BlockRef, error) { +func PayloadToBlockRef(rollupCfg *rollup.Config, payload *eth.ExecutionPayload) (eth.L2BlockRef, error) { + genesis := &rollupCfg.Genesis var l1Origin eth.BlockID var sequenceNumber uint64 if uint64(payload.BlockNumber) == genesis.L2.Number { @@ -31,7 +33,7 @@ func PayloadToBlockRef(payload *eth.ExecutionPayload, genesis *rollup.Genesis) ( if tx.Type() != types.DepositTxType { return eth.L2BlockRef{}, fmt.Errorf("first payload tx has unexpected tx type: %d", tx.Type()) } - info, err := L1InfoDepositTxData(tx.Data()) + info, err := L1BlockInfoFromBytes(rollupCfg, uint64(payload.Timestamp), tx.Data()) if err != nil { return eth.L2BlockRef{}, fmt.Errorf("failed to parse L1 info deposit tx from L2 block: %w", err) } @@ -49,12 +51,14 @@ func PayloadToBlockRef(payload *eth.ExecutionPayload, genesis *rollup.Genesis) ( }, nil } -func PayloadToSystemConfig(payload *eth.ExecutionPayload, cfg *rollup.Config) (eth.SystemConfig, error) { - if uint64(payload.BlockNumber) == cfg.Genesis.L2.Number { - if payload.BlockHash != cfg.Genesis.L2.Hash { - return eth.SystemConfig{}, fmt.Errorf("expected L2 genesis hash to match L2 block at genesis block number %d: %s <> %s", cfg.Genesis.L2.Number, payload.BlockHash, cfg.Genesis.L2.Hash) +func PayloadToSystemConfig(rollupCfg *rollup.Config, payload *eth.ExecutionPayload) (eth.SystemConfig, error) { + if uint64(payload.BlockNumber) == rollupCfg.Genesis.L2.Number { + if payload.BlockHash != rollupCfg.Genesis.L2.Hash { + return eth.SystemConfig{}, fmt.Errorf( + "expected L2 genesis hash to match L2 block at genesis block number %d: %s <> %s", + rollupCfg.Genesis.L2.Number, payload.BlockHash, rollupCfg.Genesis.L2.Hash) } - return cfg.Genesis.SystemConfig, nil + return rollupCfg.Genesis.SystemConfig, nil } else { if len(payload.Transactions) == 0 { return eth.SystemConfig{}, fmt.Errorf("l2 block is missing L1 info deposit tx, block hash: %s", payload.BlockHash) @@ -66,10 +70,18 @@ func PayloadToSystemConfig(payload *eth.ExecutionPayload, cfg *rollup.Config) (e if tx.Type() != types.DepositTxType { return eth.SystemConfig{}, fmt.Errorf("first payload tx has unexpected tx type: %d", tx.Type()) } - info, err := L1InfoDepositTxData(tx.Data()) + info, err := L1BlockInfoFromBytes(rollupCfg, uint64(payload.Timestamp), tx.Data()) if err != nil { return eth.SystemConfig{}, fmt.Errorf("failed to parse L1 info deposit tx from L2 block: %w", err) } + if isEcotoneButNotFirstBlock(rollupCfg, uint64(payload.Timestamp)) { + // Translate Ecotone values back into encoded scalar if needed. + // We do not know if it was derived from a v0 or v1 scalar, + // but v1 is fine, a 0 blob base fee has the same effect. + info.L1FeeScalar[0] = 1 + binary.BigEndian.PutUint32(info.L1FeeScalar[24:28], info.BlobBaseFeeScalar) + binary.BigEndian.PutUint32(info.L1FeeScalar[28:32], info.BaseFeeScalar) + } return eth.SystemConfig{ BatcherAddr: info.BatcherAddr, Overhead: info.L1FeeOverhead, diff --git a/op-node/rollup/derive/payloads_queue.go b/op-node/rollup/derive/payloads_queue.go index 78b1ffbb57e4..2ac554fb6d43 100644 --- a/op-node/rollup/derive/payloads_queue.go +++ b/op-node/rollup/derive/payloads_queue.go @@ -6,13 +6,14 @@ import ( "fmt" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-service/eth" ) type payloadAndSize struct { - payload *eth.ExecutionPayload - size uint64 + envelope *eth.ExecutionPayloadEnvelope + size uint64 } // payloadsByNumber buffers payloads ordered by block number. @@ -26,7 +27,7 @@ var _ heap.Interface = (*payloadsByNumber)(nil) func (pq payloadsByNumber) Len() int { return len(pq) } func (pq payloadsByNumber) Less(i, j int) bool { - return pq[i].payload.BlockNumber < pq[j].payload.BlockNumber + return pq[i].envelope.ExecutionPayload.BlockNumber < pq[j].envelope.ExecutionPayload.BlockNumber } // Swap is a heap.Interface method. Do not use this method directly. @@ -50,19 +51,19 @@ func (pq *payloadsByNumber) Pop() any { } const ( - // ~580 bytes per payload, with some margin for overhead like map data - payloadMemFixedCost uint64 = 800 + // ~1000 bytes per payload, with some margin for overhead like map data + payloadMemFixedCost uint64 = 1000 // 24 bytes per tx overhead (size of slice header in memory) payloadTxMemOverhead uint64 = 24 ) -func payloadMemSize(p *eth.ExecutionPayload) uint64 { +func payloadMemSize(p *eth.ExecutionPayloadEnvelope) uint64 { out := payloadMemFixedCost if p == nil { return out } // 24 byte overhead per tx - for _, tx := range p.Transactions { + for _, tx := range p.ExecutionPayload.Transactions { out += uint64(len(tx)) + payloadTxMemOverhead } return out @@ -80,16 +81,18 @@ type PayloadsQueue struct { currentSize uint64 MaxSize uint64 blockHashes map[common.Hash]struct{} - SizeFn func(p *eth.ExecutionPayload) uint64 + SizeFn func(p *eth.ExecutionPayloadEnvelope) uint64 + log log.Logger } -func NewPayloadsQueue(maxSize uint64, sizeFn func(p *eth.ExecutionPayload) uint64) *PayloadsQueue { +func NewPayloadsQueue(log log.Logger, maxSize uint64, sizeFn func(p *eth.ExecutionPayloadEnvelope) uint64) *PayloadsQueue { return &PayloadsQueue{ pq: nil, currentSize: 0, MaxSize: maxSize, blockHashes: make(map[common.Hash]struct{}), SizeFn: sizeFn, + log: log, } } @@ -108,48 +111,49 @@ func (upq *PayloadsQueue) MemSize() uint64 { // // We prefer higher block numbers over lower block numbers, since lower block numbers are more likely to be conflicts and/or read from L1 sooner. // The higher payload block numbers can be preserved, and once L1 contents meets these, they can all be processed in order. -func (upq *PayloadsQueue) Push(p *eth.ExecutionPayload) error { - if p == nil { +func (upq *PayloadsQueue) Push(e *eth.ExecutionPayloadEnvelope) error { + if e == nil || e.ExecutionPayload == nil { return errors.New("cannot add nil payload") } - if _, ok := upq.blockHashes[p.BlockHash]; ok { - return fmt.Errorf("cannot add duplicate payload %s", p.ID()) + if _, ok := upq.blockHashes[e.ExecutionPayload.BlockHash]; ok { + return fmt.Errorf("cannot add duplicate payload %s", e.ExecutionPayload.ID()) } - size := upq.SizeFn(p) + size := upq.SizeFn(e) if size > upq.MaxSize { - return fmt.Errorf("cannot add payload %s, payload mem size %d is larger than max queue size %d", p.ID(), size, upq.MaxSize) + return fmt.Errorf("cannot add payload %s, payload mem size %d is larger than max queue size %d", e.ExecutionPayload.ID(), size, upq.MaxSize) } heap.Push(&upq.pq, payloadAndSize{ - payload: p, - size: size, + envelope: e, + size: size, }) upq.currentSize += size for upq.currentSize > upq.MaxSize { - upq.Pop() + env := upq.Pop() + upq.log.Info("Dropping payload from payload queue because the payload queue is too large", "id", env.ExecutionPayload.ID()) } - upq.blockHashes[p.BlockHash] = struct{}{} + upq.blockHashes[e.ExecutionPayload.BlockHash] = struct{}{} return nil } // Peek retrieves the payload with the lowest block number from the queue in O(1), or nil if the queue is empty. -func (upq *PayloadsQueue) Peek() *eth.ExecutionPayload { +func (upq *PayloadsQueue) Peek() *eth.ExecutionPayloadEnvelope { if len(upq.pq) == 0 { return nil } // peek into the priority queue, the first element is the highest priority (lowest block number). // This does not apply to other elements, those are structured like a heap. - return upq.pq[0].payload + return upq.pq[0].envelope } // Pop removes the payload with the lowest block number from the queue in O(log(N)), // and may return nil if the queue is empty. -func (upq *PayloadsQueue) Pop() *eth.ExecutionPayload { +func (upq *PayloadsQueue) Pop() *eth.ExecutionPayloadEnvelope { if len(upq.pq) == 0 { return nil } ps := heap.Pop(&upq.pq).(payloadAndSize) // nosemgrep upq.currentSize -= ps.size // remove the key from the block hashes map - delete(upq.blockHashes, ps.payload.BlockHash) - return ps.payload + delete(upq.blockHashes, ps.envelope.ExecutionPayload.BlockHash) + return ps.envelope } diff --git a/op-node/rollup/derive/payloads_queue_test.go b/op-node/rollup/derive/payloads_queue_test.go index 515a803706fe..c5accbdeab11 100644 --- a/op-node/rollup/derive/payloads_queue_test.go +++ b/op-node/rollup/derive/payloads_queue_test.go @@ -5,17 +5,21 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" ) func TestPayloadsByNumber(t *testing.T) { p := payloadsByNumber{} mk := func(i uint64) payloadAndSize { return payloadAndSize{ - payload: ð.ExecutionPayload{ - BlockNumber: eth.Uint64Quantity(i), + envelope: ð.ExecutionPayloadEnvelope{ + ExecutionPayload: ð.ExecutionPayload{ + BlockNumber: eth.Uint64Quantity(i), + }, }, } } @@ -62,30 +66,35 @@ func TestPayloadsByNumber(t *testing.T) { func TestPayloadMemSize(t *testing.T) { require.Equal(t, payloadMemFixedCost, payloadMemSize(nil), "nil is same fixed cost") - require.Equal(t, payloadMemFixedCost, payloadMemSize(ð.ExecutionPayload{}), "empty payload fixed cost") - require.Equal(t, payloadMemFixedCost+payloadTxMemOverhead, payloadMemSize(ð.ExecutionPayload{Transactions: []eth.Data{nil}}), "nil tx counts") - require.Equal(t, payloadMemFixedCost+payloadTxMemOverhead, payloadMemSize(ð.ExecutionPayload{Transactions: []eth.Data{make([]byte, 0)}}), "empty tx counts") + require.Equal(t, payloadMemFixedCost, payloadMemSize(ð.ExecutionPayloadEnvelope{ExecutionPayload: ð.ExecutionPayload{}}), "empty payload fixed cost") + require.Equal(t, payloadMemFixedCost+payloadTxMemOverhead, payloadMemSize(ð.ExecutionPayloadEnvelope{ExecutionPayload: ð.ExecutionPayload{Transactions: []eth.Data{nil}}}), "nil tx counts") + require.Equal(t, payloadMemFixedCost+payloadTxMemOverhead, payloadMemSize(ð.ExecutionPayloadEnvelope{ExecutionPayload: ð.ExecutionPayload{Transactions: []eth.Data{make([]byte, 0)}}}), "empty tx counts") require.Equal(t, payloadMemFixedCost+4*payloadTxMemOverhead+42+1337+0+1, - payloadMemSize(ð.ExecutionPayload{Transactions: []eth.Data{ + payloadMemSize(ð.ExecutionPayloadEnvelope{ExecutionPayload: ð.ExecutionPayload{Transactions: []eth.Data{ make([]byte, 42), make([]byte, 1337), make([]byte, 0), make([]byte, 1), - }}), "mixed txs") + }}}), "mixed txs") +} + +func envelope(payload *eth.ExecutionPayload) *eth.ExecutionPayloadEnvelope { + return ð.ExecutionPayloadEnvelope{ExecutionPayload: payload} } func TestPayloadsQueue(t *testing.T) { - pq := NewPayloadsQueue(payloadMemFixedCost*3, payloadMemSize) + pq := NewPayloadsQueue(testlog.Logger(t, log.LvlInfo), payloadMemFixedCost*3, payloadMemSize) require.Equal(t, 0, pq.Len()) - require.Equal(t, (*eth.ExecutionPayload)(nil), pq.Peek()) - require.Equal(t, (*eth.ExecutionPayload)(nil), pq.Pop()) - - a := ð.ExecutionPayload{BlockNumber: 3, BlockHash: common.Hash{3}} - b := ð.ExecutionPayload{BlockNumber: 4, BlockHash: common.Hash{4}} - c := ð.ExecutionPayload{BlockNumber: 5, BlockHash: common.Hash{5}} - d := ð.ExecutionPayload{BlockNumber: 6, BlockHash: common.Hash{6}} - bAlt := ð.ExecutionPayload{BlockNumber: 4, BlockHash: common.Hash{0xff}} - bDup := ð.ExecutionPayload{BlockNumber: 4, BlockHash: common.Hash{4}} + require.Nil(t, pq.Peek()) + require.Nil(t, pq.Pop()) + + a := envelope(ð.ExecutionPayload{BlockNumber: 3, BlockHash: common.Hash{3}}) + b := envelope(ð.ExecutionPayload{BlockNumber: 4, BlockHash: common.Hash{4}}) + c := envelope(ð.ExecutionPayload{BlockNumber: 5, BlockHash: common.Hash{5}}) + d := envelope(ð.ExecutionPayload{BlockNumber: 6, BlockHash: common.Hash{6}}) + bAlt := envelope(ð.ExecutionPayload{BlockNumber: 4, BlockHash: common.Hash{0xff}}) + bDup := envelope(ð.ExecutionPayload{BlockNumber: 4, BlockHash: common.Hash{4}}) + require.NoError(t, pq.Push(b)) require.Equal(t, pq.Len(), 1) require.Equal(t, pq.Peek(), b) @@ -114,7 +123,7 @@ func TestPayloadsQueue(t *testing.T) { require.Equal(t, pq.Pop(), c) require.Equal(t, pq.Len(), 0, "expecting no items to remain") - e := ð.ExecutionPayload{BlockNumber: 5, Transactions: []eth.Data{make([]byte, payloadMemFixedCost*3+1)}} + e := envelope(ð.ExecutionPayload{BlockNumber: 5, Transactions: []eth.Data{make([]byte, payloadMemFixedCost*3+1)}}) require.Error(t, pq.Push(e), "cannot add payloads that are too large") require.NoError(t, pq.Push(b)) diff --git a/op-node/rollup/derive/pipeline.go b/op-node/rollup/derive/pipeline.go index 8ca69a9c138a..ed2bff13d03e 100644 --- a/op-node/rollup/derive/pipeline.go +++ b/op-node/rollup/derive/pipeline.go @@ -22,6 +22,7 @@ type Metrics interface { RecordHeadChannelOpened() RecordChannelTimedOut() RecordFrame() + RecordDerivedBatches(batchType string) RecordSequencerStepTime(step string, duration time.Duration) } @@ -33,42 +34,28 @@ type L1Fetcher interface { L1TransactionFetcher } -// ResettableEngineControl wraps EngineControl with reset-functionality, -// which handles reorgs like the derivation pipeline: -// by determining the last valid block references to continue from. -type ResettableEngineControl interface { - EngineControl - Reset() -} - type ResettableStage interface { // Reset resets a pull stage. `base` refers to the L1 Block Reference to reset to, with corresponding configuration. Reset(ctx context.Context, base eth.L1BlockRef, baseCfg eth.SystemConfig) error } type EngineQueueStage interface { - EngineControl - + LowestQueuedUnsafeBlock() eth.L2BlockRef FinalizedL1() eth.L1BlockRef - Finalized() eth.L2BlockRef - UnsafeL2Head() eth.L2BlockRef - SafeL2Head() eth.L2BlockRef - EngineSyncTarget() eth.L2BlockRef Origin() eth.L1BlockRef SystemConfig() eth.SystemConfig - SetUnsafeHead(head eth.L2BlockRef) Finalize(l1Origin eth.L1BlockRef) - AddUnsafePayload(payload *eth.ExecutionPayload) - UnsafeL2SyncTarget() eth.L2BlockRef + AddUnsafePayload(payload *eth.ExecutionPayloadEnvelope) Step(context.Context) error } // DerivationPipeline is updated with new L1 data, and the Step() function can be iterated on to keep the L2 Engine in sync. type DerivationPipeline struct { log log.Logger - cfg *rollup.Config + rollupCfg *rollup.Config l1Fetcher L1Fetcher + plasma PlasmaInputFetcher // Index of the stage that is currently being reset. // >= len(stages) if no additional resetting is required @@ -83,31 +70,38 @@ type DerivationPipeline struct { } // NewDerivationPipeline creates a derivation pipeline, which should be reset before use. -func NewDerivationPipeline(log log.Logger, cfg *rollup.Config, l1Fetcher L1Fetcher, engine Engine, metrics Metrics, syncCfg *sync.Config) *DerivationPipeline { + +func NewDerivationPipeline(log log.Logger, rollupCfg *rollup.Config, l1Fetcher L1Fetcher, l1Blobs L1BlobsFetcher, plasma PlasmaInputFetcher, l2Source L2Source, engine LocalEngineControl, metrics Metrics, syncCfg *sync.Config, safeHeadListener SafeHeadListener) *DerivationPipeline { // Pull stages - l1Traversal := NewL1Traversal(log, cfg, l1Fetcher) - dataSrc := NewDataSourceFactory(log, cfg, l1Fetcher) // auxiliary stage for L1Retrieval + l1Traversal := NewL1Traversal(log, rollupCfg, l1Fetcher) + dataSrc := NewDataSourceFactory(log, rollupCfg, l1Fetcher, l1Blobs, plasma) // auxiliary stage for L1Retrieval l1Src := NewL1Retrieval(log, dataSrc, l1Traversal) frameQueue := NewFrameQueue(log, l1Src) - bank := NewChannelBank(log, cfg, frameQueue, l1Fetcher, metrics) - chInReader := NewChannelInReader(cfg, log, bank, metrics) - batchQueue := NewBatchQueue(log, cfg, chInReader, engine) - attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, engine) - attributesQueue := NewAttributesQueue(log, cfg, attrBuilder, batchQueue) + bank := NewChannelBank(log, rollupCfg, frameQueue, l1Fetcher, metrics) + chInReader := NewChannelInReader(rollupCfg, log, bank, metrics) + batchQueue := NewBatchQueue(log, rollupCfg, chInReader, l2Source) + attrBuilder := NewFetchingAttributesBuilder(rollupCfg, l1Fetcher, l2Source) + attributesQueue := NewAttributesQueue(log, rollupCfg, attrBuilder, batchQueue) // Step stages - eng := NewEngineQueue(log, cfg, engine, metrics, attributesQueue, l1Fetcher, syncCfg) + eng := NewEngineQueue(log, rollupCfg, l2Source, engine, metrics, attributesQueue, l1Fetcher, syncCfg, safeHeadListener) + + // Plasma takes control of the engine finalization signal only when usePlasma is enabled. + plasma.OnFinalizedHeadSignal(func(ref eth.L1BlockRef) { + eng.Finalize(ref) + }) // Reset from engine queue then up from L1 Traversal. The stages do not talk to each other during // the reset, but after the engine queue, this is the order in which the stages could talk to each other. // Note: The engine queue stage is the only reset that can fail. - stages := []ResettableStage{eng, l1Traversal, l1Src, frameQueue, bank, chInReader, batchQueue, attributesQueue} + stages := []ResettableStage{eng, l1Traversal, l1Src, plasma, frameQueue, bank, chInReader, batchQueue, attributesQueue} return &DerivationPipeline{ log: log, - cfg: cfg, + rollupCfg: rollupCfg, l1Fetcher: l1Fetcher, + plasma: plasma, resetting: 0, stages: stages, eng: eng, @@ -133,7 +127,13 @@ func (dp *DerivationPipeline) Origin() eth.L1BlockRef { } func (dp *DerivationPipeline) Finalize(l1Origin eth.L1BlockRef) { - dp.eng.Finalize(l1Origin) + // In plasma mode, the finalization signal is proxied through the plasma manager. + // Finality signal will come from the DA contract or L1 finality whichever is last. + if dp.rollupCfg.UsePlasma { + dp.plasma.Finalize(l1Origin) + } else { + dp.eng.Finalize(l1Origin) + } } // FinalizedL1 is the L1 finalization of the inner-most stage of the derivation pipeline, @@ -142,51 +142,19 @@ func (dp *DerivationPipeline) FinalizedL1() eth.L1BlockRef { return dp.eng.FinalizedL1() } -func (dp *DerivationPipeline) Finalized() eth.L2BlockRef { - return dp.eng.Finalized() -} - -func (dp *DerivationPipeline) SafeL2Head() eth.L2BlockRef { - return dp.eng.SafeL2Head() -} - -// UnsafeL2Head returns the head of the L2 chain that we are deriving for, this may be past what we derived from L1 -func (dp *DerivationPipeline) UnsafeL2Head() eth.L2BlockRef { - return dp.eng.UnsafeL2Head() -} - -func (dp *DerivationPipeline) EngineSyncTarget() eth.L2BlockRef { - return dp.eng.EngineSyncTarget() -} - -func (dp *DerivationPipeline) StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *eth.PayloadAttributes, updateSafe bool) (errType BlockInsertionErrType, err error) { - return dp.eng.StartPayload(ctx, parent, attrs, updateSafe) -} - -func (dp *DerivationPipeline) ConfirmPayload(ctx context.Context) (out *eth.ExecutionPayload, errTyp BlockInsertionErrType, err error) { - return dp.eng.ConfirmPayload(ctx) -} - -func (dp *DerivationPipeline) CancelPayload(ctx context.Context, force bool) error { - return dp.eng.CancelPayload(ctx, force) -} - -func (dp *DerivationPipeline) BuildingPayload() (onto eth.L2BlockRef, id eth.PayloadID, safe bool) { - return dp.eng.BuildingPayload() -} - // AddUnsafePayload schedules an execution payload to be processed, ahead of deriving it from L1 -func (dp *DerivationPipeline) AddUnsafePayload(payload *eth.ExecutionPayload) { +func (dp *DerivationPipeline) AddUnsafePayload(payload *eth.ExecutionPayloadEnvelope) { dp.eng.AddUnsafePayload(payload) } -// UnsafeL2SyncTarget retrieves the first queued-up L2 unsafe payload, or a zeroed reference if there is none. -func (dp *DerivationPipeline) UnsafeL2SyncTarget() eth.L2BlockRef { - return dp.eng.UnsafeL2SyncTarget() +// LowestQueuedUnsafeBlock returns the lowest queued unsafe block. If the gap is filled from the unsafe head +// to this block, the EngineQueue will be able to apply the queued payloads. +func (dp *DerivationPipeline) LowestQueuedUnsafeBlock() eth.L2BlockRef { + return dp.eng.LowestQueuedUnsafeBlock() } // Step tries to progress the buffer. -// An EOF is returned if there pipeline is blocked by waiting for new L1 data. +// An EOF is returned if the pipeline is blocked by waiting for new L1 data. // If ctx errors no error is returned, but the step may exit early in a state that can still be continued. // Any other error is critical and the derivation pipeline should be reset. // An error is expected when the underlying source closes. @@ -211,7 +179,7 @@ func (dp *DerivationPipeline) Step(ctx context.Context) error { if err := dp.eng.Step(ctx); err == io.EOF { // If every stage has returned io.EOF, try to advance the L1 Origin return dp.traversal.AdvanceL1Block(ctx) - } else if errors.Is(err, EngineP2PSyncing) { + } else if errors.Is(err, EngineELSyncing) { return err } else if err != nil { return fmt.Errorf("engine stage failed: %w", err) diff --git a/op-node/rollup/derive/plasma_data_source.go b/op-node/rollup/derive/plasma_data_source.go new file mode 100644 index 000000000000..e6b9ad7dbfe1 --- /dev/null +++ b/op-node/rollup/derive/plasma_data_source.go @@ -0,0 +1,102 @@ +package derive + +import ( + "context" + "errors" + "fmt" + + plasma "github.com/ethereum-optimism/optimism/op-plasma" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/log" +) + +// PlasmaDataSource is a data source that fetches inputs from a plasma DA provider given +// their onchain commitments. Same as CalldataSource it will keep attempting to fetch. +type PlasmaDataSource struct { + log log.Logger + src DataIter + fetcher PlasmaInputFetcher + l1 L1Fetcher + id eth.BlockID + // keep track of a pending commitment so we can keep trying to fetch the input. + comm plasma.Keccak256Commitment +} + +func NewPlasmaDataSource(log log.Logger, src DataIter, l1 L1Fetcher, fetcher PlasmaInputFetcher, id eth.BlockID) *PlasmaDataSource { + return &PlasmaDataSource{ + log: log, + src: src, + fetcher: fetcher, + l1: l1, + id: id, + } +} + +func (s *PlasmaDataSource) Next(ctx context.Context) (eth.Data, error) { + // Process origin syncs the challenge contract events and updates the local challenge states + // before we can proceed to fetch the input data. This function can be called multiple times + // for the same origin and noop if the origin was already processed. It is also called if + // there is not commitment in the current origin. + if err := s.fetcher.AdvanceL1Origin(ctx, s.l1, s.id); err != nil { + if errors.Is(err, plasma.ErrReorgRequired) { + return nil, NewResetError(fmt.Errorf("new expired challenge")) + } + return nil, NewTemporaryError(fmt.Errorf("failed to advance plasma L1 origin: %w", err)) + } + + if s.comm == nil { + // the l1 source returns the input commitment for the batch. + data, err := s.src.Next(ctx) + if err != nil { + return nil, err + } + + if len(data) == 0 { + return nil, NotEnoughData + } + // If the tx data type is not plasma, we forward it downstream to let the next + // steps validate and potentially parse it as L1 DA inputs. + if data[0] != plasma.TxDataVersion1 { + return data, nil + } + + // validate batcher inbox data is a commitment. + comm, err := plasma.DecodeKeccak256(data[1:]) + if err != nil { + s.log.Warn("invalid commitment", "commitment", data, "err", err) + return s.Next(ctx) + } + s.comm = comm + } + // use the commitment to fetch the input from the plasma DA provider. + data, err := s.fetcher.GetInput(ctx, s.l1, s.comm, s.id) + // GetInput may call for a reorg if the pipeline is stalled and the plasma DA manager + // continued syncing origins detached from the pipeline origin. + if errors.Is(err, plasma.ErrReorgRequired) { + // challenge for a new previously derived commitment expired. + return nil, NewResetError(err) + } else if errors.Is(err, plasma.ErrExpiredChallenge) { + // this commitment was challenged and the challenge expired. + s.log.Warn("challenge expired, skipping batch", "comm", s.comm) + s.comm = nil + // skip the input + return s.Next(ctx) + } else if errors.Is(err, plasma.ErrMissingPastWindow) { + return nil, NewCriticalError(fmt.Errorf("data for comm %x not available: %w", s.comm, err)) + } else if errors.Is(err, plasma.ErrPendingChallenge) { + // continue stepping without slowing down. + return nil, NotEnoughData + } else if err != nil { + // return temporary error so we can keep retrying. + return nil, NewTemporaryError(fmt.Errorf("failed to fetch input data with comm %x from da service: %w", s.comm, err)) + } + // inputs are limited to a max size to ensure they can be challenged in the DA contract. + if len(data) > plasma.MaxInputSize { + s.log.Warn("input data exceeds max size", "size", len(data), "max", plasma.MaxInputSize) + s.comm = nil + return s.Next(ctx) + } + // reset the commitment so we can fetch the next one from the source at the next iteration. + s.comm = nil + return data, nil +} diff --git a/op-node/rollup/derive/plasma_data_source_test.go b/op-node/rollup/derive/plasma_data_source_test.go new file mode 100644 index 000000000000..0769eb504a11 --- /dev/null +++ b/op-node/rollup/derive/plasma_data_source_test.go @@ -0,0 +1,523 @@ +package derive + +import ( + "context" + "io" + "math/big" + "math/rand" + "testing" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + plasma "github.com/ethereum-optimism/optimism/op-plasma" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +type MockFinalitySignal struct { + mock.Mock +} + +func (m *MockFinalitySignal) OnFinalized(blockRef eth.L1BlockRef) { + m.MethodCalled("OnFinalized", blockRef) +} + +func (m *MockFinalitySignal) ExpectFinalized(blockRef eth.L1BlockRef) { + m.On("OnFinalized", blockRef).Once() +} + +// TestPlasmaDataSource verifies that commitments are correctly read from l1 and then +// forwarded to the Plasma DA to return the correct inputs in the iterator. +// First it generates some L1 refs containing a random number of commitments, challenges +// the first 4 commitments then generates enough blocks to expire the challenge. +// Then it simulates rederiving while verifying it does skip the expired input until the next +// challenge expires. +func TestPlasmaDataSource(t *testing.T) { + logger := testlog.Logger(t, log.LevelDebug) + ctx := context.Background() + + rng := rand.New(rand.NewSource(1234)) + + l1F := &testutils.MockL1Source{} + + storage := plasma.NewMockDAClient(logger) + + pcfg := plasma.Config{ + ChallengeWindow: 90, ResolveWindow: 90, + } + metrics := &plasma.NoopMetrics{} + + daState := plasma.NewState(logger, metrics) + + da := plasma.NewPlasmaDAWithState(logger, pcfg, storage, metrics, daState) + + finalitySignal := &MockFinalitySignal{} + da.OnFinalizedHeadSignal(finalitySignal.OnFinalized) + + // Create rollup genesis and config + l1Time := uint64(2) + refA := testutils.RandomBlockRef(rng) + refA.Number = 1 + l1Refs := []eth.L1BlockRef{refA} + refA0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: 0, + ParentHash: common.Hash{}, + Time: refA.Time, + L1Origin: refA.ID(), + SequenceNumber: 0, + } + batcherPriv := testutils.RandomKey() + batcherAddr := crypto.PubkeyToAddress(batcherPriv.PublicKey) + batcherInbox := common.Address{42} + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L1: refA.ID(), + L2: refA0.ID(), + L2Time: refA0.Time, + }, + BlockTime: 1, + SeqWindowSize: 20, + BatchInboxAddress: batcherInbox, + UsePlasma: true, + } + // keep track of random input data to validate against + var inputs [][]byte + var comms []plasma.Keccak256Commitment + + signer := cfg.L1Signer() + + factory := NewDataSourceFactory(logger, cfg, l1F, nil, da) + + nc := 0 + firstChallengeExpirationBlock := uint64(95) + + for i := uint64(0); i <= pcfg.ChallengeWindow+pcfg.ResolveWindow; i++ { + parent := l1Refs[len(l1Refs)-1] + // create a new mock l1 ref + ref := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: parent.Number + 1, + ParentHash: parent.Hash, + Time: parent.Time + l1Time, + } + l1Refs = append(l1Refs, ref) + logger.Info("new l1 block", "ref", ref) + // called for each l1 block to sync challenges + l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil) + + // pick a random number of commitments to include in the l1 block + c := rng.Intn(4) + var txs []*types.Transaction + + for j := 0; j < c; j++ { + // mock input commitments in l1 transactions + input := testutils.RandomData(rng, 2000) + comm, _ := storage.SetInput(ctx, input) + inputs = append(inputs, input) + comms = append(comms, comm) + + tx, err := types.SignNewTx(batcherPriv, signer, &types.DynamicFeeTx{ + ChainID: signer.ChainID(), + Nonce: 0, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: big.NewInt(30 * params.GWei), + Gas: 100_000, + To: &batcherInbox, + Value: big.NewInt(int64(0)), + Data: comm.TxData(), + }) + require.NoError(t, err) + + txs = append(txs, tx) + + } + logger.Info("included commitments", "count", c) + l1F.ExpectInfoAndTxsByHash(ref.Hash, testutils.RandomBlockInfo(rng), txs, nil) + // called once per derivation + l1F.ExpectInfoAndTxsByHash(ref.Hash, testutils.RandomBlockInfo(rng), txs, nil) + + if ref.Number == 2 { + l1F.ExpectL1BlockRefByNumber(ref.Number, ref, nil) + finalitySignal.ExpectFinalized(ref) + } + + // challenge the first 4 commitments as soon as we have collected them all + if len(comms) >= 4 && nc < 7 { + // skip a block between each challenge transaction + if nc%2 == 0 { + daState.SetActiveChallenge(comms[nc/2].Encode(), ref.Number, pcfg.ResolveWindow) + logger.Info("setting active challenge", "comm", comms[nc/2]) + } + nc++ + } + + // create a new data source for each block + src, err := factory.OpenData(ctx, ref, batcherAddr) + require.NoError(t, err) + + // first challenge expires + if i == firstChallengeExpirationBlock { + _, err := src.Next(ctx) + require.ErrorIs(t, err, ErrReset) + break + } + + for j := 0; j < c; j++ { + data, err := src.Next(ctx) + // check that each commitment is resolved + require.NoError(t, err) + require.Equal(t, hexutil.Bytes(inputs[len(inputs)-(c-j)]), data) + } + // returns EOF once done + _, err = src.Next(ctx) + require.ErrorIs(t, err, io.EOF) + } + + logger.Info("pipeline reset ..................................") + + // start at 1 since first input should be skipped + nc = 1 + secondChallengeExpirationBlock := 98 + + for i := 1; i <= len(l1Refs)+2; i++ { + + var ref eth.L1BlockRef + // first we run through all the existing l1 blocks + if i < len(l1Refs) { + ref = l1Refs[i] + logger.Info("re deriving block", "ref", ref, "i", i) + + if i == len(l1Refs)-1 { + l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil) + } + // once past the l1 head, continue generating new l1 refs + } else { + parent := l1Refs[len(l1Refs)-1] + // create a new mock l1 ref + ref = eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: parent.Number + 1, + ParentHash: parent.Hash, + Time: parent.Time + l1Time, + } + l1Refs = append(l1Refs, ref) + logger.Info("new l1 block", "ref", ref) + // called for each l1 block to sync challenges + l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil) + + // pick a random number of commitments to include in the l1 block + c := rng.Intn(4) + var txs []*types.Transaction + + for j := 0; j < c; j++ { + // mock input commitments in l1 transactions + input := testutils.RandomData(rng, 2000) + comm, _ := storage.SetInput(ctx, input) + inputs = append(inputs, input) + comms = append(comms, comm) + + tx, err := types.SignNewTx(batcherPriv, signer, &types.DynamicFeeTx{ + ChainID: signer.ChainID(), + Nonce: 0, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: big.NewInt(30 * params.GWei), + Gas: 100_000, + To: &batcherInbox, + Value: big.NewInt(int64(0)), + Data: comm.TxData(), + }) + require.NoError(t, err) + + txs = append(txs, tx) + + } + logger.Info("included commitments", "count", c) + l1F.ExpectInfoAndTxsByHash(ref.Hash, testutils.RandomBlockInfo(rng), txs, nil) + } + + // create a new data source for each block + src, err := factory.OpenData(ctx, ref, batcherAddr) + require.NoError(t, err) + + // next challenge expires + if i == secondChallengeExpirationBlock { + _, err := src.Next(ctx) + require.ErrorIs(t, err, ErrReset) + break + } + + for data, err := src.Next(ctx); err != io.EOF; data, err = src.Next(ctx) { + logger.Info("yielding data") + // check that each commitment is resolved + require.NoError(t, err) + require.Equal(t, hexutil.Bytes(inputs[nc]), data) + + nc++ + } + + } + + // trigger l1 finalization signal + da.Finalize(l1Refs[len(l1Refs)-32]) + + finalitySignal.AssertExpectations(t) + l1F.AssertExpectations(t) +} + +// This tests makes sure the pipeline returns a temporary error if data is not found. +func TestPlasmaDataSourceStall(t *testing.T) { + logger := testlog.Logger(t, log.LevelDebug) + ctx := context.Background() + + rng := rand.New(rand.NewSource(1234)) + + l1F := &testutils.MockL1Source{} + + storage := plasma.NewMockDAClient(logger) + + pcfg := plasma.Config{ + ChallengeWindow: 90, ResolveWindow: 90, + } + + metrics := &plasma.NoopMetrics{} + + daState := plasma.NewState(logger, metrics) + + da := plasma.NewPlasmaDAWithState(logger, pcfg, storage, metrics, daState) + + finalitySignal := &MockFinalitySignal{} + da.OnFinalizedHeadSignal(finalitySignal.OnFinalized) + + // Create rollup genesis and config + l1Time := uint64(2) + refA := testutils.RandomBlockRef(rng) + refA.Number = 1 + l1Refs := []eth.L1BlockRef{refA} + refA0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: 0, + ParentHash: common.Hash{}, + Time: refA.Time, + L1Origin: refA.ID(), + SequenceNumber: 0, + } + batcherPriv := testutils.RandomKey() + batcherAddr := crypto.PubkeyToAddress(batcherPriv.PublicKey) + batcherInbox := common.Address{42} + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L1: refA.ID(), + L2: refA0.ID(), + L2Time: refA0.Time, + }, + BlockTime: 1, + SeqWindowSize: 20, + BatchInboxAddress: batcherInbox, + UsePlasma: true, + } + + signer := cfg.L1Signer() + + factory := NewDataSourceFactory(logger, cfg, l1F, nil, da) + + parent := l1Refs[0] + // create a new mock l1 ref + ref := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: parent.Number + 1, + ParentHash: parent.Hash, + Time: parent.Time + l1Time, + } + l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil) + // mock input commitments in l1 transactions + input := testutils.RandomData(rng, 2000) + comm, _ := storage.SetInput(ctx, input) + + tx, err := types.SignNewTx(batcherPriv, signer, &types.DynamicFeeTx{ + ChainID: signer.ChainID(), + Nonce: 0, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: big.NewInt(30 * params.GWei), + Gas: 100_000, + To: &batcherInbox, + Value: big.NewInt(int64(0)), + Data: comm.TxData(), + }) + require.NoError(t, err) + + txs := []*types.Transaction{tx} + + l1F.ExpectInfoAndTxsByHash(ref.Hash, testutils.RandomBlockInfo(rng), txs, nil) + + // delete the input from the DA provider so it returns not found + require.NoError(t, storage.DeleteData(comm.Encode())) + + // next block is fetched to look ahead challenges but is not yet available + l1F.ExpectL1BlockRefByNumber(ref.Number+1, eth.L1BlockRef{}, ethereum.NotFound) + + src, err := factory.OpenData(ctx, ref, batcherAddr) + require.NoError(t, err) + + // data is not found so we return a temporary error + _, err = src.Next(ctx) + require.ErrorIs(t, err, ErrTemporary) + + // next block is available with no challenge events + nextRef := eth.L1BlockRef{ + Number: ref.Number + 1, + Hash: testutils.RandomHash(rng), + } + l1F.ExpectL1BlockRefByNumber(nextRef.Number, nextRef, nil) + l1F.ExpectFetchReceipts(nextRef.Hash, nil, types.Receipts{}, nil) + + // not enough data + _, err = src.Next(ctx) + require.ErrorIs(t, err, NotEnoughData) + + // now challenge is resolved + daState.SetResolvedChallenge(comm.Encode(), input, ref.Number+2) + + // derivation can resume + data, err := src.Next(ctx) + require.NoError(t, err) + require.Equal(t, hexutil.Bytes(input), data) + + l1F.AssertExpectations(t) +} + +// TestPlasmaDataSourceInvalidData tests that the pipeline skips invalid data and continues +// this includes invalid commitments and oversized inputs. +func TestPlasmaDataSourceInvalidData(t *testing.T) { + logger := testlog.Logger(t, log.LevelDebug) + ctx := context.Background() + + rng := rand.New(rand.NewSource(1234)) + + l1F := &testutils.MockL1Source{} + + storage := plasma.NewMockDAClient(logger) + + pcfg := plasma.Config{ + ChallengeWindow: 90, ResolveWindow: 90, + } + + da := plasma.NewPlasmaDAWithStorage(logger, pcfg, storage, &plasma.NoopMetrics{}) + + // Create rollup genesis and config + l1Time := uint64(2) + refA := testutils.RandomBlockRef(rng) + refA.Number = 1 + l1Refs := []eth.L1BlockRef{refA} + refA0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: 0, + ParentHash: common.Hash{}, + Time: refA.Time, + L1Origin: refA.ID(), + SequenceNumber: 0, + } + batcherPriv := testutils.RandomKey() + batcherAddr := crypto.PubkeyToAddress(batcherPriv.PublicKey) + batcherInbox := common.Address{42} + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L1: refA.ID(), + L2: refA0.ID(), + L2Time: refA0.Time, + }, + BlockTime: 1, + SeqWindowSize: 20, + BatchInboxAddress: batcherInbox, + UsePlasma: true, + } + + signer := cfg.L1Signer() + + factory := NewDataSourceFactory(logger, cfg, l1F, nil, da) + + parent := l1Refs[0] + // create a new mock l1 ref + ref := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: parent.Number + 1, + ParentHash: parent.Hash, + Time: parent.Time + l1Time, + } + l1F.ExpectFetchReceipts(ref.Hash, nil, types.Receipts{}, nil) + // mock input commitments in l1 transactions with an oversized input + input := testutils.RandomData(rng, plasma.MaxInputSize+1) + comm, _ := storage.SetInput(ctx, input) + + tx1, err := types.SignNewTx(batcherPriv, signer, &types.DynamicFeeTx{ + ChainID: signer.ChainID(), + Nonce: 0, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: big.NewInt(30 * params.GWei), + Gas: 100_000, + To: &batcherInbox, + Value: big.NewInt(int64(0)), + Data: comm.TxData(), + }) + require.NoError(t, err) + + // valid data + input2 := testutils.RandomData(rng, 2000) + comm2, _ := storage.SetInput(ctx, input2) + tx2, err := types.SignNewTx(batcherPriv, signer, &types.DynamicFeeTx{ + ChainID: signer.ChainID(), + Nonce: 0, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: big.NewInt(30 * params.GWei), + Gas: 100_000, + To: &batcherInbox, + Value: big.NewInt(int64(0)), + Data: comm2.TxData(), + }) + require.NoError(t, err) + + // regular input instead of commitment + input3 := testutils.RandomData(rng, 32) + tx3, err := types.SignNewTx(batcherPriv, signer, &types.DynamicFeeTx{ + ChainID: signer.ChainID(), + Nonce: 0, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: big.NewInt(30 * params.GWei), + Gas: 100_000, + To: &batcherInbox, + Value: big.NewInt(int64(0)), + Data: input3, + }) + require.NoError(t, err) + + txs := []*types.Transaction{tx1, tx2, tx3} + + l1F.ExpectInfoAndTxsByHash(ref.Hash, testutils.RandomBlockInfo(rng), txs, nil) + + src, err := factory.OpenData(ctx, ref, batcherAddr) + require.NoError(t, err) + + // oversized input is skipped and returns input2 directly + data, err := src.Next(ctx) + require.NoError(t, err) + require.Equal(t, hexutil.Bytes(input2), data) + + // regular input is passed through + data, err = src.Next(ctx) + require.NoError(t, err) + require.Equal(t, hexutil.Bytes(input3), data) + + _, err = src.Next(ctx) + require.ErrorIs(t, err, io.EOF) + + l1F.AssertExpectations(t) +} diff --git a/op-node/rollup/derive/singular_batch.go b/op-node/rollup/derive/singular_batch.go index 6354dc46ee53..fb7baeecb9b0 100644 --- a/op-node/rollup/derive/singular_batch.go +++ b/op-node/rollup/derive/singular_batch.go @@ -2,6 +2,7 @@ package derive import ( "bytes" + "errors" "io" "github.com/ethereum-optimism/optimism/op-node/rollup" @@ -44,6 +45,7 @@ func (b *SingularBatch) GetEpochNum() rollup.Epoch { // LogContext creates a new log context that contains information of the batch func (b *SingularBatch) LogContext(log log.Logger) log.Logger { return log.New( + "batch_type", "SingularBatch", "batch_timestamp", b.Timestamp, "parent_hash", b.ParentHash, "batch_epoch", b.Epoch(), @@ -65,3 +67,12 @@ func (b *SingularBatch) encode(w io.Writer) error { func (b *SingularBatch) decode(r *bytes.Reader) error { return rlp.Decode(r, b) } + +// GetSingularBatch retrieves SingularBatch from batchData +func GetSingularBatch(batchData *BatchData) (*SingularBatch, error) { + singularBatch, ok := batchData.inner.(*SingularBatch) + if !ok { + return nil, NewCriticalError(errors.New("failed type assertion to SingularBatch")) + } + return singularBatch, nil +} diff --git a/op-node/rollup/derive/span_batch.go b/op-node/rollup/derive/span_batch.go index e71dd05a5b18..af8c77d84802 100644 --- a/op-node/rollup/derive/span_batch.go +++ b/op-node/rollup/derive/span_batch.go @@ -3,6 +3,7 @@ package derive import ( "bytes" "encoding/binary" + "encoding/json" "errors" "fmt" "io" @@ -25,7 +26,7 @@ import ( // spanBatch := SpanBatchType ++ prefix ++ payload // prefix := rel_timestamp ++ l1_origin_num ++ parent_check ++ l1_origin_check // payload := block_count ++ origin_bits ++ block_tx_counts ++ txs -// txs := contract_creation_bits ++ y_parity_bits ++ tx_sigs ++ tx_tos ++ tx_datas ++ tx_nonces ++ tx_gases +// txs := contract_creation_bits ++ y_parity_bits ++ tx_sigs ++ tx_tos ++ tx_datas ++ tx_nonces ++ tx_gases ++ protected_bits var ErrTooBigSpanBatchSize = errors.New("span batch size limit reached") @@ -40,7 +41,7 @@ type spanBatchPrefix struct { type spanBatchPayload struct { blockCount uint64 // Number of L2 block in the span - originBits *big.Int // Bitlist of blockCount bits. Each bit indicates if the L1 origin is changed at the L2 block. + originBits *big.Int // Standard span-batch bitlist of blockCount bits. Each bit indicates if the L1 origin is changed at the L2 block. blockTxCounts []uint64 // List of transaction counts for each L2 block txs *spanBatchTxs // Transactions encoded in SpanBatch specs } @@ -57,34 +58,12 @@ func (b *RawSpanBatch) GetBatchType() int { } // decodeOriginBits parses data into bp.originBits -// originBits is bitlist right-padded to a multiple of 8 bits func (bp *spanBatchPayload) decodeOriginBits(r *bytes.Reader) error { - originBitBufferLen := bp.blockCount / 8 - if bp.blockCount%8 != 0 { - originBitBufferLen++ - } - // avoid out of memory before allocation - if originBitBufferLen > MaxSpanBatchSize { - return ErrTooBigSpanBatchSize - } - originBitBuffer := make([]byte, originBitBufferLen) - _, err := io.ReadFull(r, originBitBuffer) + bits, err := decodeSpanBatchBits(r, bp.blockCount) if err != nil { - return fmt.Errorf("failed to read origin bits: %w", err) - } - originBits := new(big.Int) - for i := 0; i < int(bp.blockCount); i += 8 { - end := i + 8 - if end < int(bp.blockCount) { - end = int(bp.blockCount) - } - bits := originBitBuffer[i/8] - for j := i; j < end; j++ { - bit := uint((bits >> (j - i)) & 1) - originBits.SetBit(originBits, j, bit) - } + return fmt.Errorf("failed to decode origin bits: %w", err) } - bp.originBits = originBits + bp.originBits = bits return nil } @@ -230,10 +209,10 @@ func (b *RawSpanBatch) decode(r *bytes.Reader) error { return ErrTooBigSpanBatchSize } if err := b.decodePrefix(r); err != nil { - return err + return fmt.Errorf("failed to decode span batch prefix: %w", err) } if err := b.decodePayload(r); err != nil { - return err + return fmt.Errorf("failed to decode span batch payload: %w", err) } return nil } @@ -292,26 +271,9 @@ func (bp *spanBatchPrefix) encodePrefix(w io.Writer) error { } // encodeOriginBits encodes bp.originBits -// originBits is bitlist right-padded to a multiple of 8 bits func (bp *spanBatchPayload) encodeOriginBits(w io.Writer) error { - originBitBufferLen := bp.blockCount / 8 - if bp.blockCount%8 != 0 { - originBitBufferLen++ - } - originBitBuffer := make([]byte, originBitBufferLen) - for i := 0; i < int(bp.blockCount); i += 8 { - end := i + 8 - if end < int(bp.blockCount) { - end = int(bp.blockCount) - } - var bits uint = 0 - for j := i; j < end; j++ { - bits |= bp.originBits.Bit(j) << (j - i) - } - originBitBuffer[i/8] = byte(bits) - } - if _, err := w.Write(originBitBuffer); err != nil { - return fmt.Errorf("cannot write origin bits: %w", err) + if err := encodeSpanBatchBits(w, bp.blockCount, bp.originBits); err != nil { + return fmt.Errorf("failed to encode origin bits: %w", err) } return nil } @@ -377,7 +339,7 @@ func (b *RawSpanBatch) encode(w io.Writer) error { return nil } -// derive converts RawSpanBatch into SpanBatch, which has a list of spanBatchElement. +// derive converts RawSpanBatch into SpanBatch, which has a list of SpanBatchElement. // We need chain config constants to derive values for making payload attributes. func (b *RawSpanBatch) derive(blockTime, genesisTimestamp uint64, chainID *big.Int) (*SpanBatch, error) { if b.blockCount == 0 { @@ -392,42 +354,54 @@ func (b *RawSpanBatch) derive(blockTime, genesisTimestamp uint64, chainID *big.I } } - b.txs.recoverV(chainID) + if err := b.txs.recoverV(chainID); err != nil { + return nil, err + } fullTxs, err := b.txs.fullTxs(chainID) if err != nil { return nil, err } spanBatch := SpanBatch{ - parentCheck: b.parentCheck, - l1OriginCheck: b.l1OriginCheck, + ParentCheck: b.parentCheck, + L1OriginCheck: b.l1OriginCheck, } txIdx := 0 for i := 0; i < int(b.blockCount); i++ { - batch := spanBatchElement{} + batch := SpanBatchElement{} batch.Timestamp = genesisTimestamp + b.relTimestamp + blockTime*uint64(i) batch.EpochNum = rollup.Epoch(blockOriginNums[i]) for j := 0; j < int(b.blockTxCounts[i]); j++ { batch.Transactions = append(batch.Transactions, fullTxs[txIdx]) txIdx++ } - spanBatch.batches = append(spanBatch.batches, &batch) + spanBatch.Batches = append(spanBatch.Batches, &batch) } return &spanBatch, nil } -// spanBatchElement is a derived form of input to build a L2 block. +// ToSpanBatch converts RawSpanBatch to SpanBatch, +// which implements a wrapper of derive method of RawSpanBatch +func (b *RawSpanBatch) ToSpanBatch(blockTime, genesisTimestamp uint64, chainID *big.Int) (*SpanBatch, error) { + spanBatch, err := b.derive(blockTime, genesisTimestamp, chainID) + if err != nil { + return nil, err + } + return spanBatch, nil +} + +// SpanBatchElement is a derived form of input to build a L2 block. // similar to SingularBatch, but does not have ParentHash and EpochHash // because Span batch spec does not contain parent hash and epoch hash of every block in the span. -type spanBatchElement struct { +type SpanBatchElement struct { EpochNum rollup.Epoch // aka l1 num Timestamp uint64 Transactions []hexutil.Bytes } -// singularBatchToElement converts a SingularBatch to a spanBatchElement -func singularBatchToElement(singularBatch *SingularBatch) *spanBatchElement { - return &spanBatchElement{ +// singularBatchToElement converts a SingularBatch to a SpanBatchElement +func singularBatchToElement(singularBatch *SingularBatch) *SpanBatchElement { + return &SpanBatchElement{ EpochNum: singularBatch.EpochNum, Timestamp: singularBatch.Timestamp, Transactions: singularBatch.Transactions, @@ -435,11 +409,27 @@ func singularBatchToElement(singularBatch *SingularBatch) *spanBatchElement { } // SpanBatch is an implementation of Batch interface, -// containing the input to build a span of L2 blocks in derived form (spanBatchElement) +// containing the input to build a span of L2 blocks in derived form (SpanBatchElement) type SpanBatch struct { - parentCheck [20]byte // First 20 bytes of the first block's parent hash - l1OriginCheck [20]byte // First 20 bytes of the last block's L1 origin hash - batches []*spanBatchElement // List of block input in derived form + ParentCheck [20]byte // First 20 bytes of the first block's parent hash + L1OriginCheck [20]byte // First 20 bytes of the last block's L1 origin hash + Batches []*SpanBatchElement // List of block input in derived form +} + +// spanBatchMarshaling is a helper type used for JSON marshaling. +type spanBatchMarshaling struct { + ParentCheck []hexutil.Bytes `json:"parent_check"` + L1OriginCheck []hexutil.Bytes `json:"l1_origin_check"` + Batches []*SpanBatchElement `json:"span_batch_elements"` +} + +func (b *SpanBatch) MarshalJSON() ([]byte, error) { + spanBatch := spanBatchMarshaling{ + ParentCheck: []hexutil.Bytes{b.ParentCheck[:]}, + L1OriginCheck: []hexutil.Bytes{b.L1OriginCheck[:]}, + Batches: b.Batches, + } + return json.Marshal(spanBatch) } // GetBatchType returns its batch type (batch_version) @@ -449,100 +439,101 @@ func (b *SpanBatch) GetBatchType() int { // GetTimestamp returns timestamp of the first block in the span func (b *SpanBatch) GetTimestamp() uint64 { - return b.batches[0].Timestamp + return b.Batches[0].Timestamp } // LogContext creates a new log context that contains information of the batch func (b *SpanBatch) LogContext(log log.Logger) log.Logger { - if len(b.batches) == 0 { + if len(b.Batches) == 0 { return log.New("block_count", 0) } return log.New( - "batch_timestamp", b.batches[0].Timestamp, - "parent_check", hexutil.Encode(b.parentCheck[:]), - "origin_check", hexutil.Encode(b.l1OriginCheck[:]), + "batch_type", "SpanBatch", + "batch_timestamp", b.Batches[0].Timestamp, + "parent_check", hexutil.Encode(b.ParentCheck[:]), + "origin_check", hexutil.Encode(b.L1OriginCheck[:]), "start_epoch_number", b.GetStartEpochNum(), - "end_epoch_number", b.GetBlockEpochNum(len(b.batches)-1), - "block_count", len(b.batches), + "end_epoch_number", b.GetBlockEpochNum(len(b.Batches)-1), + "block_count", len(b.Batches), ) } // GetStartEpochNum returns epoch number(L1 origin block number) of the first block in the span func (b *SpanBatch) GetStartEpochNum() rollup.Epoch { - return b.batches[0].EpochNum + return b.Batches[0].EpochNum } // CheckOriginHash checks if the l1OriginCheck matches the first 20 bytes of given hash, probably L1 block hash from the current canonical L1 chain. func (b *SpanBatch) CheckOriginHash(hash common.Hash) bool { - return bytes.Equal(b.l1OriginCheck[:], hash.Bytes()[:20]) + return bytes.Equal(b.L1OriginCheck[:], hash.Bytes()[:20]) } // CheckParentHash checks if the parentCheck matches the first 20 bytes of given hash, probably the current L2 safe head. func (b *SpanBatch) CheckParentHash(hash common.Hash) bool { - return bytes.Equal(b.parentCheck[:], hash.Bytes()[:20]) + return bytes.Equal(b.ParentCheck[:], hash.Bytes()[:20]) } // GetBlockEpochNum returns the epoch number(L1 origin block number) of the block at the given index in the span. func (b *SpanBatch) GetBlockEpochNum(i int) uint64 { - return uint64(b.batches[i].EpochNum) + return uint64(b.Batches[i].EpochNum) } // GetBlockTimestamp returns the timestamp of the block at the given index in the span. func (b *SpanBatch) GetBlockTimestamp(i int) uint64 { - return b.batches[i].Timestamp + return b.Batches[i].Timestamp } // GetBlockTransactions returns the encoded transactions of the block at the given index in the span. func (b *SpanBatch) GetBlockTransactions(i int) []hexutil.Bytes { - return b.batches[i].Transactions + return b.Batches[i].Transactions } // GetBlockCount returns the number of blocks in the span func (b *SpanBatch) GetBlockCount() int { - return len(b.batches) + return len(b.Batches) } // AppendSingularBatch appends a SingularBatch into the span batch // updates l1OriginCheck or parentCheck if needed. func (b *SpanBatch) AppendSingularBatch(singularBatch *SingularBatch) { - if len(b.batches) == 0 { - copy(b.parentCheck[:], singularBatch.ParentHash.Bytes()[:20]) + if len(b.Batches) == 0 { + copy(b.ParentCheck[:], singularBatch.ParentHash.Bytes()[:20]) } - b.batches = append(b.batches, singularBatchToElement(singularBatch)) - copy(b.l1OriginCheck[:], singularBatch.EpochHash.Bytes()[:20]) + b.Batches = append(b.Batches, singularBatchToElement(singularBatch)) + copy(b.L1OriginCheck[:], singularBatch.EpochHash.Bytes()[:20]) } // ToRawSpanBatch merges SingularBatch List and initialize single RawSpanBatch func (b *SpanBatch) ToRawSpanBatch(originChangedBit uint, genesisTimestamp uint64, chainID *big.Int) (*RawSpanBatch, error) { - if len(b.batches) == 0 { + if len(b.Batches) == 0 { return nil, errors.New("cannot merge empty singularBatch list") } raw := RawSpanBatch{} // Sort by timestamp of L2 block - sort.Slice(b.batches, func(i, j int) bool { - return b.batches[i].Timestamp < b.batches[j].Timestamp + sort.Slice(b.Batches, func(i, j int) bool { + return b.Batches[i].Timestamp < b.Batches[j].Timestamp }) // spanBatchPrefix - span_start := b.batches[0] - span_end := b.batches[len(b.batches)-1] + span_start := b.Batches[0] + span_end := b.Batches[len(b.Batches)-1] raw.relTimestamp = span_start.Timestamp - genesisTimestamp raw.l1OriginNum = uint64(span_end.EpochNum) - raw.parentCheck = b.parentCheck - raw.l1OriginCheck = b.l1OriginCheck + raw.parentCheck = b.ParentCheck + raw.l1OriginCheck = b.L1OriginCheck // spanBatchPayload - raw.blockCount = uint64(len(b.batches)) + raw.blockCount = uint64(len(b.Batches)) raw.originBits = new(big.Int) raw.originBits.SetBit(raw.originBits, 0, originChangedBit) - for i := 1; i < len(b.batches); i++ { + for i := 1; i < len(b.Batches); i++ { bit := uint(0) - if b.batches[i-1].EpochNum < b.batches[i].EpochNum { + if b.Batches[i-1].EpochNum < b.Batches[i].EpochNum { bit = 1 } raw.originBits.SetBit(raw.originBits, i, bit) } var blockTxCounts []uint64 var txs [][]byte - for _, batch := range b.batches { + for _, batch := range b.Batches { blockTxCount := uint64(len(batch.Transactions)) blockTxCounts = append(blockTxCounts, blockTxCount) for _, rawTx := range batch.Transactions { @@ -558,13 +549,13 @@ func (b *SpanBatch) ToRawSpanBatch(originChangedBit uint, genesisTimestamp uint6 return &raw, nil } -// GetSingularBatches converts spanBatchElements after L2 safe head to SingularBatches. -// Since spanBatchElement does not contain EpochHash, set EpochHash from the given L1 blocks. +// GetSingularBatches converts SpanBatchElements after L2 safe head to SingularBatches. +// Since SpanBatchElement does not contain EpochHash, set EpochHash from the given L1 blocks. // The result SingularBatches do not contain ParentHash yet. It must be set by BatchQueue. func (b *SpanBatch) GetSingularBatches(l1Origins []eth.L1BlockRef, l2SafeHead eth.L2BlockRef) ([]*SingularBatch, error) { var singularBatches []*SingularBatch originIdx := 0 - for _, batch := range b.batches { + for _, batch := range b.Batches { if batch.Timestamp <= l2SafeHead.Time { continue } @@ -590,20 +581,30 @@ func (b *SpanBatch) GetSingularBatches(l1Origins []eth.L1BlockRef, l2SafeHead et return singularBatches, nil } -// NewSpanBatch converts given singularBatches into spanBatchElements, and creates a new SpanBatch. +// NewSpanBatch converts given singularBatches into SpanBatchElements, and creates a new SpanBatch. func NewSpanBatch(singularBatches []*SingularBatch) *SpanBatch { spanBatch := &SpanBatch{} if len(singularBatches) == 0 { return spanBatch } - copy(spanBatch.parentCheck[:], singularBatches[0].ParentHash.Bytes()[:20]) - copy(spanBatch.l1OriginCheck[:], singularBatches[len(singularBatches)-1].EpochHash.Bytes()[:20]) + copy(spanBatch.ParentCheck[:], singularBatches[0].ParentHash.Bytes()[:20]) + copy(spanBatch.L1OriginCheck[:], singularBatches[len(singularBatches)-1].EpochHash.Bytes()[:20]) for _, singularBatch := range singularBatches { - spanBatch.batches = append(spanBatch.batches, singularBatchToElement(singularBatch)) + spanBatch.Batches = append(spanBatch.Batches, singularBatchToElement(singularBatch)) } return spanBatch } +// DeriveSpanBatch derives SpanBatch from BatchData. +func DeriveSpanBatch(batchData *BatchData, blockTime, genesisTimestamp uint64, chainID *big.Int) (*SpanBatch, error) { + rawSpanBatch, ok := batchData.inner.(*RawSpanBatch) + if !ok { + return nil, NewCriticalError(errors.New("failed type assertion to SpanBatch")) + } + // If the batch type is Span batch, derive block inputs from RawSpanBatch. + return rawSpanBatch.ToSpanBatch(blockTime, genesisTimestamp, chainID) +} + // SpanBatchBuilder is a utility type to build a SpanBatch by adding a SingularBatch one by one. // makes easier to stack SingularBatches and convert to RawSpanBatch for encoding. type SpanBatchBuilder struct { @@ -640,7 +641,7 @@ func (b *SpanBatchBuilder) GetRawSpanBatch() (*RawSpanBatch, error) { } func (b *SpanBatchBuilder) GetBlockCount() int { - return len(b.spanBatch.batches) + return len(b.spanBatch.Batches) } func (b *SpanBatchBuilder) Reset() { diff --git a/op-node/rollup/derive/span_batch_test.go b/op-node/rollup/derive/span_batch_test.go index eaa03a8a53d7..dd3574b4aa39 100644 --- a/op-node/rollup/derive/span_batch_test.go +++ b/op-node/rollup/derive/span_batch_test.go @@ -219,7 +219,8 @@ func TestSpanBatchPayload(t *testing.T) { err = sb.decodePayload(r) require.NoError(t, err) - sb.txs.recoverV(chainID) + err = sb.txs.recoverV(chainID) + require.NoError(t, err) require.Equal(t, rawSpanBatch.spanBatchPayload, sb.spanBatchPayload) } @@ -283,7 +284,8 @@ func TestSpanBatchTxs(t *testing.T) { err = sb.decodeTxs(r) require.NoError(t, err) - sb.txs.recoverV(chainID) + err = sb.txs.recoverV(chainID) + require.NoError(t, err) require.Equal(t, rawSpanBatch.txs, sb.txs) } @@ -302,7 +304,8 @@ func TestSpanBatchRoundTrip(t *testing.T) { err = sb.decode(bytes.NewReader(result.Bytes())) require.NoError(t, err) - sb.txs.recoverV(chainID) + err = sb.txs.recoverV(chainID) + require.NoError(t, err) require.Equal(t, rawSpanBatch, &sb) } @@ -328,18 +331,18 @@ func TestSpanBatchDerive(t *testing.T) { require.NoError(t, err) blockCount := len(singularBatches) - require.Equal(t, safeL2Head.Hash.Bytes()[:20], spanBatchDerived.parentCheck[:]) - require.Equal(t, singularBatches[blockCount-1].Epoch().Hash.Bytes()[:20], spanBatchDerived.l1OriginCheck[:]) + require.Equal(t, safeL2Head.Hash.Bytes()[:20], spanBatchDerived.ParentCheck[:]) + require.Equal(t, singularBatches[blockCount-1].Epoch().Hash.Bytes()[:20], spanBatchDerived.L1OriginCheck[:]) require.Equal(t, len(singularBatches), int(rawSpanBatch.blockCount)) for i := 1; i < len(singularBatches); i++ { - require.Equal(t, spanBatchDerived.batches[i].Timestamp, spanBatchDerived.batches[i-1].Timestamp+l2BlockTime) + require.Equal(t, spanBatchDerived.Batches[i].Timestamp, spanBatchDerived.Batches[i-1].Timestamp+l2BlockTime) } for i := 0; i < len(singularBatches); i++ { - require.Equal(t, singularBatches[i].EpochNum, spanBatchDerived.batches[i].EpochNum) - require.Equal(t, singularBatches[i].Timestamp, spanBatchDerived.batches[i].Timestamp) - require.Equal(t, singularBatches[i].Transactions, spanBatchDerived.batches[i].Transactions) + require.Equal(t, singularBatches[i].EpochNum, spanBatchDerived.Batches[i].EpochNum) + require.Equal(t, singularBatches[i].Timestamp, spanBatchDerived.Batches[i].Timestamp) + require.Equal(t, singularBatches[i].Transactions, spanBatchDerived.Batches[i].Transactions) } } } @@ -444,9 +447,10 @@ func TestSpanBatchToSingularBatch(t *testing.T) { func TestSpanBatchReadTxData(t *testing.T) { cases := []spanBatchTxTest{ - {"legacy tx", 32, testutils.RandomLegacyTx}, - {"access list tx", 32, testutils.RandomAccessListTx}, - {"dynamic fee tx", 32, testutils.RandomDynamicFeeTx}, + {"unprotected legacy tx", 32, testutils.RandomLegacyTx, false}, + {"legacy tx", 32, testutils.RandomLegacyTx, true}, + {"access list tx", 32, testutils.RandomAccessListTx, true}, + {"dynamic fee tx", 32, testutils.RandomDynamicFeeTx, true}, } for i, testCase := range cases { @@ -454,6 +458,9 @@ func TestSpanBatchReadTxData(t *testing.T) { rng := rand.New(rand.NewSource(int64(0x109550 + i))) chainID := new(big.Int).SetUint64(rng.Uint64()) signer := types.NewLondonSigner(chainID) + if !testCase.protected { + signer = types.HomesteadSigner{} + } var rawTxs [][]byte var txs []*types.Transaction @@ -508,8 +515,8 @@ func TestSpanBatchBuilder(t *testing.T) { for i := 0; i < len(singularBatches); i++ { spanBatchBuilder.AppendSingularBatch(singularBatches[i], seqNum) require.Equal(t, i+1, spanBatchBuilder.GetBlockCount()) - require.Equal(t, singularBatches[0].ParentHash.Bytes()[:20], spanBatchBuilder.spanBatch.parentCheck[:]) - require.Equal(t, singularBatches[i].EpochHash.Bytes()[:20], spanBatchBuilder.spanBatch.l1OriginCheck[:]) + require.Equal(t, singularBatches[0].ParentHash.Bytes()[:20], spanBatchBuilder.spanBatch.ParentCheck[:]) + require.Equal(t, singularBatches[i].EpochHash.Bytes()[:20], spanBatchBuilder.spanBatch.L1OriginCheck[:]) } rawSpanBatch, err := spanBatchBuilder.GetRawSpanBatch() diff --git a/op-node/rollup/derive/span_batch_tx.go b/op-node/rollup/derive/span_batch_tx.go index 12628097a3f5..cd0a471ab266 100644 --- a/op-node/rollup/derive/span_batch_tx.go +++ b/op-node/rollup/derive/span_batch_tx.go @@ -2,7 +2,6 @@ package derive import ( "bytes" - "errors" "fmt" "math/big" @@ -77,7 +76,7 @@ func (tx *spanBatchTx) setDecoded(inner spanBatchTxData, size uint64) { // decodeTyped decodes a typed transaction from the canonical format. func (tx *spanBatchTx) decodeTyped(b []byte) (spanBatchTxData, error) { if len(b) <= 1 { - return nil, errors.New("typed transaction too short") + return nil, fmt.Errorf("failed to decode span batch: %w", ErrTypedTxTooShort) } switch b[0] { case types.AccessListTxType: diff --git a/op-node/rollup/derive/span_batch_tx_test.go b/op-node/rollup/derive/span_batch_tx_test.go index dd50cb6bbbfa..c846f65812b9 100644 --- a/op-node/rollup/derive/span_batch_tx_test.go +++ b/op-node/rollup/derive/span_batch_tx_test.go @@ -12,16 +12,18 @@ import ( ) type spanBatchTxTest struct { - name string - trials int - mkTx func(rng *rand.Rand, signer types.Signer) *types.Transaction + name string + trials int + mkTx func(rng *rand.Rand, signer types.Signer) *types.Transaction + protected bool } func TestSpanBatchTxConvert(t *testing.T) { cases := []spanBatchTxTest{ - {"legacy tx", 32, testutils.RandomLegacyTx}, - {"access list tx", 32, testutils.RandomAccessListTx}, - {"dynamic fee tx", 32, testutils.RandomDynamicFeeTx}, + {"unprotected legacy tx", 32, testutils.RandomLegacyTx, false}, + {"legacy tx", 32, testutils.RandomLegacyTx, true}, + {"access list tx", 32, testutils.RandomAccessListTx, true}, + {"dynamic fee tx", 32, testutils.RandomDynamicFeeTx, true}, } for i, testCase := range cases { @@ -29,6 +31,9 @@ func TestSpanBatchTxConvert(t *testing.T) { rng := rand.New(rand.NewSource(int64(0x1331 + i))) chainID := big.NewInt(rng.Int63n(1000)) signer := types.NewLondonSigner(chainID) + if !testCase.protected { + signer = types.HomesteadSigner{} + } for txIdx := 0; txIdx < testCase.trials; txIdx++ { tx := testCase.mkTx(rng, signer) @@ -54,9 +59,10 @@ func TestSpanBatchTxConvert(t *testing.T) { func TestSpanBatchTxRoundTrip(t *testing.T) { cases := []spanBatchTxTest{ - {"legacy tx", 32, testutils.RandomLegacyTx}, - {"access list tx", 32, testutils.RandomAccessListTx}, - {"dynamic fee tx", 32, testutils.RandomDynamicFeeTx}, + {"unprotected legacy tx", 32, testutils.RandomLegacyTx, false}, + {"legacy tx", 32, testutils.RandomLegacyTx, true}, + {"access list tx", 32, testutils.RandomAccessListTx, true}, + {"dynamic fee tx", 32, testutils.RandomDynamicFeeTx, true}, } for i, testCase := range cases { @@ -64,6 +70,9 @@ func TestSpanBatchTxRoundTrip(t *testing.T) { rng := rand.New(rand.NewSource(int64(0x1332 + i))) chainID := big.NewInt(rng.Int63n(1000)) signer := types.NewLondonSigner(chainID) + if !testCase.protected { + signer = types.HomesteadSigner{} + } for txIdx := 0; txIdx < testCase.trials; txIdx++ { tx := testCase.mkTx(rng, signer) @@ -87,6 +96,7 @@ func TestSpanBatchTxRoundTrip(t *testing.T) { type spanBatchDummyTxData struct{} func (txData *spanBatchDummyTxData) txType() byte { return types.DepositTxType } + func TestSpanBatchTxInvalidTxType(t *testing.T) { // span batch never contain deposit tx depositTx := types.NewTx(&types.DepositTx{}) @@ -102,7 +112,7 @@ func TestSpanBatchTxInvalidTxType(t *testing.T) { func TestSpanBatchTxDecodeInvalid(t *testing.T) { var sbtx spanBatchTx _, err := sbtx.decodeTyped([]byte{}) - require.EqualError(t, err, "typed transaction too short") + require.ErrorIs(t, err, ErrTypedTxTooShort) tx := types.NewTx(&types.LegacyTx{}) txEncoded, err := tx.MarshalBinary() diff --git a/op-node/rollup/derive/span_batch_txs.go b/op-node/rollup/derive/span_batch_txs.go index 4f2fe19b58ed..ca9e8b1d84c1 100644 --- a/op-node/rollup/derive/span_batch_txs.go +++ b/op-node/rollup/derive/span_batch_txs.go @@ -18,16 +18,19 @@ type spanBatchTxs struct { // this field must be manually set totalBlockTxCount uint64 - // 7 fields - contractCreationBits *big.Int - yParityBits *big.Int + // 8 fields + contractCreationBits *big.Int // standard span-batch bitlist + yParityBits *big.Int // standard span-batch bitlist txSigs []spanBatchSignature txNonces []uint64 txGases []uint64 txTos []common.Address txDatas []hexutil.Bytes + protectedBits *big.Int // standard span-batch bitlist - txTypes []int + // intermediate variables which can be recovered + txTypes []int + totalLegacyTxCount uint64 } type spanBatchSignature struct { @@ -36,64 +39,41 @@ type spanBatchSignature struct { s *uint256.Int } -// contractCreationBits is bitlist right-padded to a multiple of 8 bits func (btx *spanBatchTxs) encodeContractCreationBits(w io.Writer) error { - contractCreationBitBufferLen := btx.totalBlockTxCount / 8 - if btx.totalBlockTxCount%8 != 0 { - contractCreationBitBufferLen++ - } - contractCreationBitBuffer := make([]byte, contractCreationBitBufferLen) - for i := 0; i < int(btx.totalBlockTxCount); i += 8 { - end := i + 8 - if end < int(btx.totalBlockTxCount) { - end = int(btx.totalBlockTxCount) - } - var bits uint = 0 - for j := i; j < end; j++ { - bits |= btx.contractCreationBits.Bit(j) << (j - i) - } - contractCreationBitBuffer[i/8] = byte(bits) - } - if _, err := w.Write(contractCreationBitBuffer); err != nil { - return fmt.Errorf("cannot write contract creation bits: %w", err) + if err := encodeSpanBatchBits(w, btx.totalBlockTxCount, btx.contractCreationBits); err != nil { + return fmt.Errorf("failed to encode contract creation bits: %w", err) } return nil } -// contractCreationBits is bitlist right-padded to a multiple of 8 bits func (btx *spanBatchTxs) decodeContractCreationBits(r *bytes.Reader) error { - contractCreationBitBufferLen := btx.totalBlockTxCount / 8 - if btx.totalBlockTxCount%8 != 0 { - contractCreationBitBufferLen++ + bits, err := decodeSpanBatchBits(r, btx.totalBlockTxCount) + if err != nil { + return fmt.Errorf("failed to decode contract creation bits: %w", err) } - // avoid out of memory before allocation - if contractCreationBitBufferLen > MaxSpanBatchSize { - return ErrTooBigSpanBatchSize + btx.contractCreationBits = bits + return nil +} + +func (btx *spanBatchTxs) encodeProtectedBits(w io.Writer) error { + if err := encodeSpanBatchBits(w, btx.totalLegacyTxCount, btx.protectedBits); err != nil { + return fmt.Errorf("failed to encode protected bits: %w", err) } - contractCreationBitBuffer := make([]byte, contractCreationBitBufferLen) - _, err := io.ReadFull(r, contractCreationBitBuffer) + return nil +} + +func (btx *spanBatchTxs) decodeProtectedBits(r *bytes.Reader) error { + bits, err := decodeSpanBatchBits(r, btx.totalLegacyTxCount) if err != nil { - return fmt.Errorf("failed to read contract creation bits: %w", err) - } - contractCreationBits := new(big.Int) - for i := 0; i < int(btx.totalBlockTxCount); i += 8 { - end := i + 8 - if end < int(btx.totalBlockTxCount) { - end = int(btx.totalBlockTxCount) - } - bits := contractCreationBitBuffer[i/8] - for j := i; j < end; j++ { - bit := uint((bits >> (j - i)) & 1) - contractCreationBits.SetBit(contractCreationBits, j, bit) - } + return fmt.Errorf("failed to decode protected bits: %w", err) } - btx.contractCreationBits = contractCreationBits + btx.protectedBits = bits return nil } -func (btx *spanBatchTxs) contractCreationCount() uint64 { +func (btx *spanBatchTxs) contractCreationCount() (uint64, error) { if btx.contractCreationBits == nil { - panic("contract creation bits not set") + return 0, errors.New("dev error: contract creation bits not set") } var result uint64 = 0 for i := 0; i < int(btx.totalBlockTxCount); i++ { @@ -102,30 +82,22 @@ func (btx *spanBatchTxs) contractCreationCount() uint64 { result++ } } - return result + return result, nil } -// yParityBits is bitlist right-padded to a multiple of 8 bits func (btx *spanBatchTxs) encodeYParityBits(w io.Writer) error { - yParityBitBufferLen := btx.totalBlockTxCount / 8 - if btx.totalBlockTxCount%8 != 0 { - yParityBitBufferLen++ - } - yParityBitBuffer := make([]byte, yParityBitBufferLen) - for i := 0; i < int(btx.totalBlockTxCount); i += 8 { - end := i + 8 - if end < int(btx.totalBlockTxCount) { - end = int(btx.totalBlockTxCount) - } - var bits uint = 0 - for j := i; j < end; j++ { - bits |= btx.yParityBits.Bit(j) << (j - i) - } - yParityBitBuffer[i/8] = byte(bits) + if err := encodeSpanBatchBits(w, btx.totalBlockTxCount, btx.yParityBits); err != nil { + return fmt.Errorf("failed to encode y-parity bits: %w", err) } - if _, err := w.Write(yParityBitBuffer); err != nil { - return fmt.Errorf("cannot write y parity bits: %w", err) + return nil +} + +func (btx *spanBatchTxs) decodeYParityBits(r *bytes.Reader) error { + bits, err := decodeSpanBatchBits(r, btx.totalBlockTxCount) + if err != nil { + return fmt.Errorf("failed to decode y-parity bits: %w", err) } + btx.yParityBits = bits return nil } @@ -183,37 +155,6 @@ func (btx *spanBatchTxs) encodeTxDatas(w io.Writer) error { return nil } -// yParityBits is bitlist right-padded to a multiple of 8 bits -func (btx *spanBatchTxs) decodeYParityBits(r *bytes.Reader) error { - yParityBitBufferLen := btx.totalBlockTxCount / 8 - if btx.totalBlockTxCount%8 != 0 { - yParityBitBufferLen++ - } - // avoid out of memory before allocation - if yParityBitBufferLen > MaxSpanBatchSize { - return ErrTooBigSpanBatchSize - } - yParityBitBuffer := make([]byte, yParityBitBufferLen) - _, err := io.ReadFull(r, yParityBitBuffer) - if err != nil { - return fmt.Errorf("failed to read y parity bits: %w", err) - } - yParityBits := new(big.Int) - for i := 0; i < int(btx.totalBlockTxCount); i += 8 { - end := i + 8 - if end < int(btx.totalBlockTxCount) { - end = int(btx.totalBlockTxCount) - } - bits := yParityBitBuffer[i/8] - for j := i; j < end; j++ { - bit := uint((bits >> (j - i)) & 1) - yParityBits.SetBit(yParityBits, j, bit) - } - } - btx.yParityBits = yParityBits - return nil -} - func (btx *spanBatchTxs) decodeTxSigsRS(r *bytes.Reader) error { var txSigs []spanBatchSignature var sigBuffer [32]byte @@ -264,7 +205,10 @@ func (btx *spanBatchTxs) decodeTxGases(r *bytes.Reader) error { func (btx *spanBatchTxs) decodeTxTos(r *bytes.Reader) error { var txTos []common.Address txToBuffer := make([]byte, common.AddressLength) - contractCreationCount := btx.contractCreationCount() + contractCreationCount, err := btx.contractCreationCount() + if err != nil { + return err + } for i := 0; i < int(btx.totalBlockTxCount-contractCreationCount); i++ { _, err := io.ReadFull(r, txToBuffer) if err != nil { @@ -287,32 +231,46 @@ func (btx *spanBatchTxs) decodeTxDatas(r *bytes.Reader) error { } txDatas = append(txDatas, txData) txTypes = append(txTypes, txType) + if txType == types.LegacyTxType { + btx.totalLegacyTxCount++ + } } btx.txDatas = txDatas btx.txTypes = txTypes return nil } -func (btx *spanBatchTxs) recoverV(chainID *big.Int) { +func (btx *spanBatchTxs) recoverV(chainID *big.Int) error { if len(btx.txTypes) != len(btx.txSigs) { - panic("tx type length and tx sigs length mismatch") + return errors.New("tx type length and tx sigs length mismatch") } + if btx.protectedBits == nil { + return errors.New("dev error: protected bits not set") + } + protectedBitsIdx := 0 for idx, txType := range btx.txTypes { bit := uint64(btx.yParityBits.Bit(idx)) var v uint64 switch txType { case types.LegacyTxType: - // EIP155 - v = chainID.Uint64()*2 + 35 + bit + protectedBit := btx.protectedBits.Bit(protectedBitsIdx) + protectedBitsIdx++ + if protectedBit == 0 { + v = 27 + bit + } else { + // EIP-155 + v = chainID.Uint64()*2 + 35 + bit + } case types.AccessListTxType: v = bit case types.DynamicFeeTxType: v = bit default: - panic(fmt.Sprintf("invalid tx type: %d", txType)) + return fmt.Errorf("invalid tx type: %d", txType) } btx.txSigs[idx].v = v } + return nil } func (btx *spanBatchTxs) encode(w io.Writer) error { @@ -337,6 +295,9 @@ func (btx *spanBatchTxs) encode(w io.Writer) error { if err := btx.encodeTxGases(w); err != nil { return err } + if err := btx.encodeProtectedBits(w); err != nil { + return err + } return nil } @@ -362,6 +323,9 @@ func (btx *spanBatchTxs) decode(r *bytes.Reader) error { if err := btx.decodeTxGases(r); err != nil { return err } + if err := btx.decodeProtectedBits(r); err != nil { + return err + } return nil } @@ -400,21 +364,35 @@ func (btx *spanBatchTxs) fullTxs(chainID *big.Int) ([][]byte, error) { return txs, nil } -func convertVToYParity(v uint64, txType int) uint { +func convertVToYParity(v uint64, txType int) (uint, error) { var yParityBit uint switch txType { case types.LegacyTxType: - // EIP155: v = 2 * chainID + 35 + yParity - // v - 35 = yParity (mod 2) - yParityBit = uint((v - 35) & 1) + if isProtectedV(v, txType) { + // EIP-155: v = 2 * chainID + 35 + yParity + // v - 35 = yParity (mod 2) + yParityBit = uint((v - 35) & 1) + } else { + // unprotected legacy txs must have v = 27 or 28 + yParityBit = uint(v - 27) + } case types.AccessListTxType: yParityBit = uint(v) case types.DynamicFeeTxType: yParityBit = uint(v) default: - panic(fmt.Sprintf("invalid tx type: %d", txType)) + return 0, fmt.Errorf("invalid tx type: %d", txType) } - return yParityBit + return yParityBit, nil +} + +func isProtectedV(v uint64, txType int) bool { + if txType == types.LegacyTxType { + // if EIP-155 applied, v = 2 * chainID + 35 + yParity + return v != 27 && v != 28 + } + // every non legacy tx are protected + return true } func newSpanBatchTxs(txs [][]byte, chainID *big.Int) (*spanBatchTxs, error) { @@ -427,11 +405,21 @@ func newSpanBatchTxs(txs [][]byte, chainID *big.Int) (*spanBatchTxs, error) { var txTypes []int contractCreationBits := new(big.Int) yParityBits := new(big.Int) + protectedBits := new(big.Int) + totalLegacyTxCount := uint64(0) for idx := 0; idx < int(totalBlockTxCount); idx++ { var tx types.Transaction if err := tx.UnmarshalBinary(txs[idx]); err != nil { return nil, errors.New("failed to decode tx") } + if tx.Type() == types.LegacyTxType { + protectedBit := uint(0) + if tx.Protected() { + protectedBit = uint(1) + } + protectedBits.SetBit(protectedBits, int(totalLegacyTxCount), protectedBit) + totalLegacyTxCount++ + } if tx.Protected() && tx.ChainId().Cmp(chainID) != 0 { return nil, fmt.Errorf("protected tx has chain ID %d, but expected chain ID %d", tx.ChainId(), chainID) } @@ -449,7 +437,10 @@ func newSpanBatchTxs(txs [][]byte, chainID *big.Int) (*spanBatchTxs, error) { contractCreationBit = uint(0) } contractCreationBits.SetBit(contractCreationBits, idx, contractCreationBit) - yParityBit := convertVToYParity(txSig.v, int(tx.Type())) + yParityBit, err := convertVToYParity(txSig.v, int(tx.Type())) + if err != nil { + return nil, err + } yParityBits.SetBit(yParityBits, idx, yParityBit) txNonces = append(txNonces, tx.Nonce()) txGases = append(txGases, tx.Gas()) @@ -474,5 +465,7 @@ func newSpanBatchTxs(txs [][]byte, chainID *big.Int) (*spanBatchTxs, error) { txTos: txTos, txDatas: txDatas, txTypes: txTypes, + protectedBits: protectedBits, + totalLegacyTxCount: totalLegacyTxCount, }, nil } diff --git a/op-node/rollup/derive/span_batch_txs_test.go b/op-node/rollup/derive/span_batch_txs_test.go index 1fda8b5ffbf3..ea8f898e45ff 100644 --- a/op-node/rollup/derive/span_batch_txs_test.go +++ b/op-node/rollup/derive/span_batch_txs_test.go @@ -14,6 +14,12 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testutils" ) +type txTypeTest struct { + name string + mkTx func(rng *rand.Rand, signer types.Signer) *types.Transaction + signer types.Signer +} + func TestSpanBatchTxsContractCreationBits(t *testing.T) { rng := rand.New(rand.NewSource(0x1234567)) chainID := big.NewInt(rng.Int63n(1000)) @@ -54,7 +60,8 @@ func TestSpanBatchTxsContractCreationCount(t *testing.T) { rawSpanBatch := RandomRawSpanBatch(rng, chainID) contractCreationBits := rawSpanBatch.txs.contractCreationBits - contractCreationCount := rawSpanBatch.txs.contractCreationCount() + contractCreationCount, err := rawSpanBatch.txs.contractCreationCount() + require.NoError(t, err) totalBlockTxCount := rawSpanBatch.txs.totalBlockTxCount var sbt spanBatchTxs @@ -62,7 +69,7 @@ func TestSpanBatchTxsContractCreationCount(t *testing.T) { sbt.totalBlockTxCount = totalBlockTxCount var buf bytes.Buffer - err := sbt.encodeContractCreationBits(&buf) + err = sbt.encodeContractCreationBits(&buf) require.NoError(t, err) result := buf.Bytes() @@ -72,7 +79,10 @@ func TestSpanBatchTxsContractCreationCount(t *testing.T) { err = sbt.decodeContractCreationBits(r) require.NoError(t, err) - require.Equal(t, contractCreationCount, sbt.contractCreationCount()) + contractCreationCount2, err := sbt.contractCreationCount() + require.NoError(t, err) + + require.Equal(t, contractCreationCount, contractCreationCount2) } func TestSpanBatchTxsYParityBits(t *testing.T) { @@ -108,6 +118,44 @@ func TestSpanBatchTxsYParityBits(t *testing.T) { require.Equal(t, yParityBits, sbt.yParityBits) } +func TestSpanBatchTxsProtectedBits(t *testing.T) { + rng := rand.New(rand.NewSource(0x7331)) + chainID := big.NewInt(rng.Int63n(1000)) + + rawSpanBatch := RandomRawSpanBatch(rng, chainID) + protectedBits := rawSpanBatch.txs.protectedBits + txTypes := rawSpanBatch.txs.txTypes + totalBlockTxCount := rawSpanBatch.txs.totalBlockTxCount + totalLegacyTxCount := rawSpanBatch.txs.totalLegacyTxCount + + var sbt spanBatchTxs + sbt.protectedBits = protectedBits + sbt.totalBlockTxCount = totalBlockTxCount + sbt.txTypes = txTypes + sbt.totalLegacyTxCount = totalLegacyTxCount + + var buf bytes.Buffer + err := sbt.encodeProtectedBits(&buf) + require.NoError(t, err) + + // protectedBit field is fixed length: single bit + protectedBitBufferLen := totalLegacyTxCount / 8 + require.NoError(t, err) + if totalLegacyTxCount%8 != 0 { + protectedBitBufferLen++ + } + require.Equal(t, buf.Len(), int(protectedBitBufferLen)) + + result := buf.Bytes() + sbt.protectedBits = nil + + r := bytes.NewReader(result) + err = sbt.decodeProtectedBits(r) + require.NoError(t, err) + + require.Equal(t, protectedBits, sbt.protectedBits) +} + func TestSpanBatchTxsTxSigs(t *testing.T) { rng := rand.New(rand.NewSource(0x73311337)) chainID := big.NewInt(rng.Int63n(1000)) @@ -259,40 +307,64 @@ func TestSpanBatchTxsRecoverV(t *testing.T) { rng := rand.New(rand.NewSource(0x123)) chainID := big.NewInt(rng.Int63n(1000)) - signer := types.NewLondonSigner(chainID) - totalblockTxCount := rng.Intn(100) - - var spanBatchTxs spanBatchTxs - var txTypes []int - var txSigs []spanBatchSignature - var originalVs []uint64 - yParityBits := new(big.Int) - for idx := 0; idx < totalblockTxCount; idx++ { - tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - txTypes = append(txTypes, int(tx.Type())) - var txSig spanBatchSignature - v, r, s := tx.RawSignatureValues() - // Do not fill in txSig.V - txSig.r, _ = uint256.FromBig(r) - txSig.s, _ = uint256.FromBig(s) - txSigs = append(txSigs, txSig) - originalVs = append(originalVs, v.Uint64()) - yParityBit := convertVToYParity(v.Uint64(), int(tx.Type())) - yParityBits.SetBit(yParityBits, idx, yParityBit) + londonSigner := types.NewLondonSigner(chainID) + totalblockTxCount := 20 + rng.Intn(100) + + cases := []txTypeTest{ + {"unprotected legacy tx", testutils.RandomLegacyTx, types.HomesteadSigner{}}, + {"legacy tx", testutils.RandomLegacyTx, londonSigner}, + {"access list tx", testutils.RandomAccessListTx, londonSigner}, + {"dynamic fee tx", testutils.RandomDynamicFeeTx, londonSigner}, } - spanBatchTxs.yParityBits = yParityBits - spanBatchTxs.txSigs = txSigs - spanBatchTxs.txTypes = txTypes - // recover txSig.v - spanBatchTxs.recoverV(chainID) + for _, testCase := range cases { + t.Run(testCase.name, func(t *testing.T) { + var spanBatchTxs spanBatchTxs + var txTypes []int + var txSigs []spanBatchSignature + var originalVs []uint64 + yParityBits := new(big.Int) + protectedBits := new(big.Int) + totalLegacyTxCount := 0 + for idx := 0; idx < totalblockTxCount; idx++ { + tx := testCase.mkTx(rng, testCase.signer) + txType := tx.Type() + txTypes = append(txTypes, int(txType)) + var txSig spanBatchSignature + v, r, s := tx.RawSignatureValues() + if txType == types.LegacyTxType { + protectedBit := uint(0) + if tx.Protected() { + protectedBit = uint(1) + } + protectedBits.SetBit(protectedBits, int(totalLegacyTxCount), protectedBit) + totalLegacyTxCount++ + } + // Do not fill in txSig.V + txSig.r, _ = uint256.FromBig(r) + txSig.s, _ = uint256.FromBig(s) + txSigs = append(txSigs, txSig) + originalVs = append(originalVs, v.Uint64()) + yParityBit, err := convertVToYParity(v.Uint64(), int(tx.Type())) + require.NoError(t, err) + yParityBits.SetBit(yParityBits, idx, yParityBit) + } + + spanBatchTxs.yParityBits = yParityBits + spanBatchTxs.txSigs = txSigs + spanBatchTxs.txTypes = txTypes + spanBatchTxs.protectedBits = protectedBits + // recover txSig.v + err := spanBatchTxs.recoverV(chainID) + require.NoError(t, err) - var recoveredVs []uint64 - for _, txSig := range spanBatchTxs.txSigs { - recoveredVs = append(recoveredVs, txSig.v) + var recoveredVs []uint64 + for _, txSig := range spanBatchTxs.txSigs { + recoveredVs = append(recoveredVs, txSig.v) + } + require.Equal(t, originalVs, recoveredVs, "recovered v mismatch") + }) } - - require.Equal(t, originalVs, recoveredVs, "recovered v mismatch") } func TestSpanBatchTxsRoundTrip(t *testing.T) { @@ -315,7 +387,9 @@ func TestSpanBatchTxsRoundTrip(t *testing.T) { sbt2.totalBlockTxCount = totalBlockTxCount err = sbt2.decode(r) require.NoError(t, err) - sbt2.recoverV(chainID) + + err = sbt2.recoverV(chainID) + require.NoError(t, err) require.Equal(t, sbt, &sbt2) } @@ -324,33 +398,39 @@ func TestSpanBatchTxsRoundTrip(t *testing.T) { func TestSpanBatchTxsRoundTripFullTxs(t *testing.T) { rng := rand.New(rand.NewSource(0x13377331)) chainID := big.NewInt(rng.Int63n(1000)) - signer := types.NewLondonSigner(chainID) - - for i := 0; i < 4; i++ { - totalblockTxCounts := uint64(1 + rng.Int()&0xFF) - var txs [][]byte - for i := 0; i < int(totalblockTxCounts); i++ { - tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - rawTx, err := tx.MarshalBinary() - require.NoError(t, err) - txs = append(txs, rawTx) - } - sbt, err := newSpanBatchTxs(txs, chainID) - require.NoError(t, err) + londonSigner := types.NewLondonSigner(chainID) - txs2, err := sbt.fullTxs(chainID) - require.NoError(t, err) + cases := []txTypeTest{ + {"unprotected legacy tx", testutils.RandomLegacyTx, types.HomesteadSigner{}}, + {"legacy tx", testutils.RandomLegacyTx, londonSigner}, + {"access list tx", testutils.RandomAccessListTx, londonSigner}, + {"dynamic fee tx", testutils.RandomDynamicFeeTx, londonSigner}, + } - require.Equal(t, txs, txs2) + for _, testCase := range cases { + t.Run(testCase.name, func(t *testing.T) { + for i := 0; i < 4; i++ { + totalblockTxCounts := uint64(1 + rng.Int()&0xFF) + var txs [][]byte + for i := 0; i < int(totalblockTxCounts); i++ { + tx := testCase.mkTx(rng, testCase.signer) + rawTx, err := tx.MarshalBinary() + require.NoError(t, err) + txs = append(txs, rawTx) + } + sbt, err := newSpanBatchTxs(txs, chainID) + require.NoError(t, err) + + txs2, err := sbt.fullTxs(chainID) + require.NoError(t, err) + + require.Equal(t, txs, txs2) + } + }) } } func TestSpanBatchTxsRecoverVInvalidTxType(t *testing.T) { - defer func() { - if r := recover(); r == nil { - t.Errorf("The code did not panic") - } - }() rng := rand.New(rand.NewSource(0x321)) chainID := big.NewInt(rng.Int63n(1000)) @@ -359,32 +439,44 @@ func TestSpanBatchTxsRecoverVInvalidTxType(t *testing.T) { sbt.txTypes = []int{types.DepositTxType} sbt.txSigs = []spanBatchSignature{{v: 0, r: nil, s: nil}} sbt.yParityBits = new(big.Int) + sbt.protectedBits = new(big.Int) - // expect panic - sbt.recoverV(chainID) + err := sbt.recoverV(chainID) + require.ErrorContains(t, err, "invalid tx type") } func TestSpanBatchTxsFullTxNotEnoughTxTos(t *testing.T) { rng := rand.New(rand.NewSource(0x13572468)) chainID := big.NewInt(rng.Int63n(1000)) - signer := types.NewLondonSigner(chainID) + londonSigner := types.NewLondonSigner(chainID) - totalblockTxCounts := uint64(1 + rng.Int()&0xFF) - var txs [][]byte - for i := 0; i < int(totalblockTxCounts); i++ { - tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - rawTx, err := tx.MarshalBinary() - require.NoError(t, err) - txs = append(txs, rawTx) + cases := []txTypeTest{ + {"unprotected legacy tx", testutils.RandomLegacyTx, types.HomesteadSigner{}}, + {"legacy tx", testutils.RandomLegacyTx, londonSigner}, + {"access list tx", testutils.RandomAccessListTx, londonSigner}, + {"dynamic fee tx", testutils.RandomDynamicFeeTx, londonSigner}, } - sbt, err := newSpanBatchTxs(txs, chainID) - require.NoError(t, err) - // drop single to field - sbt.txTos = sbt.txTos[:len(sbt.txTos)-2] + for _, testCase := range cases { + t.Run(testCase.name, func(t *testing.T) { + totalblockTxCounts := uint64(1 + rng.Int()&0xFF) + var txs [][]byte + for i := 0; i < int(totalblockTxCounts); i++ { + tx := testCase.mkTx(rng, testCase.signer) + rawTx, err := tx.MarshalBinary() + require.NoError(t, err) + txs = append(txs, rawTx) + } + sbt, err := newSpanBatchTxs(txs, chainID) + require.NoError(t, err) + + // drop single to field + sbt.txTos = sbt.txTos[:len(sbt.txTos)-2] - _, err = sbt.fullTxs(chainID) - require.EqualError(t, err, "tx to not enough") + _, err = sbt.fullTxs(chainID) + require.EqualError(t, err, "tx to not enough") + }) + } } func TestSpanBatchTxsMaxContractCreationBitsLength(t *testing.T) { @@ -404,3 +496,13 @@ func TestSpanBatchTxsMaxYParityBitsLength(t *testing.T) { err := sb.decodeOriginBits(r) require.ErrorIs(t, err, ErrTooBigSpanBatchSize) } + +func TestSpanBatchTxsMaxProtectedBitsLength(t *testing.T) { + var sb RawSpanBatch + sb.txs = &spanBatchTxs{} + sb.txs.totalLegacyTxCount = 0xFFFFFFFFFFFFFFFF + + r := bytes.NewReader([]byte{}) + err := sb.txs.decodeProtectedBits(r) + require.ErrorIs(t, err, ErrTooBigSpanBatchSize) +} diff --git a/op-node/rollup/derive/span_batch_util.go b/op-node/rollup/derive/span_batch_util.go new file mode 100644 index 000000000000..7b96cd784f78 --- /dev/null +++ b/op-node/rollup/derive/span_batch_util.go @@ -0,0 +1,60 @@ +package derive + +import ( + "bytes" + "fmt" + "io" + "math/big" +) + +// decodeSpanBatchBits decodes a standard span-batch bitlist. +// The bitlist is encoded as big-endian integer, left-padded with zeroes to a multiple of 8 bits. +// The encoded bitlist cannot be longer than MaxSpanBatchSize. +func decodeSpanBatchBits(r *bytes.Reader, bitLength uint64) (*big.Int, error) { + // Round up, ensure enough bytes when number of bits is not a multiple of 8. + // Alternative of (L+7)/8 is not overflow-safe. + bufLen := bitLength / 8 + if bitLength%8 != 0 { + bufLen++ + } + // avoid out of memory before allocation + if bufLen > MaxSpanBatchSize { + return nil, ErrTooBigSpanBatchSize + } + buf := make([]byte, bufLen) + _, err := io.ReadFull(r, buf) + if err != nil { + return nil, fmt.Errorf("failed to read bits: %w", err) + } + out := new(big.Int) + out.SetBytes(buf) + // We read the correct number of bytes, but there may still be trailing bits + if l := uint64(out.BitLen()); l > bitLength { + return nil, fmt.Errorf("bitfield has %d bits, but expected no more than %d", l, bitLength) + } + return out, nil +} + +// encodeSpanBatchBits encodes a standard span-batch bitlist. +// The bitlist is encoded as big-endian integer, left-padded with zeroes to a multiple of 8 bits. +// The encoded bitlist cannot be longer than MaxSpanBatchSize. +func encodeSpanBatchBits(w io.Writer, bitLength uint64, bits *big.Int) error { + if l := uint64(bits.BitLen()); l > bitLength { + return fmt.Errorf("bitfield is larger than bitLength: %d > %d", l, bitLength) + } + // Round up, ensure enough bytes when number of bits is not a multiple of 8. + // Alternative of (L+7)/8 is not overflow-safe. + bufLen := bitLength / 8 + if bitLength%8 != 0 { // rounding up this way is safe against overflows + bufLen++ + } + if bufLen > MaxSpanBatchSize { + return ErrTooBigSpanBatchSize + } + buf := make([]byte, bufLen) + bits.FillBytes(buf) // zero-extended, big-endian + if _, err := w.Write(buf); err != nil { + return fmt.Errorf("cannot write bits: %w", err) + } + return nil +} diff --git a/op-node/rollup/derive/span_channel_out.go b/op-node/rollup/derive/span_channel_out.go index a272dfaf5225..362272a44e21 100644 --- a/op-node/rollup/derive/span_channel_out.go +++ b/op-node/rollup/derive/span_channel_out.go @@ -3,12 +3,13 @@ package derive import ( "bytes" "crypto/rand" - "errors" "fmt" "io" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" + + "github.com/ethereum-optimism/optimism/op-node/rollup" ) type SpanChannelOut struct { @@ -64,12 +65,12 @@ func (co *SpanChannelOut) Reset() error { // and an error if there is a problem adding the block. The only sentinel error // that it returns is ErrTooManyRLPBytes. If this error is returned, the channel // should be closed and a new one should be made. -func (co *SpanChannelOut) AddBlock(block *types.Block) (uint64, error) { +func (co *SpanChannelOut) AddBlock(rollupCfg *rollup.Config, block *types.Block) (uint64, error) { if co.closed { - return 0, errors.New("already closed") + return 0, ErrChannelOutAlreadyClosed } - batch, l1Info, err := BlockToSingularBatch(block) + batch, l1Info, err := BlockToSingularBatch(rollupCfg, block) if err != nil { return 0, err } @@ -91,7 +92,7 @@ func (co *SpanChannelOut) AddBlock(block *types.Block) (uint64, error) { // It makes we can only get frames once the channel is full or closed, in the case of SpanBatch. func (co *SpanChannelOut) AddSingularBatch(batch *SingularBatch, seqNum uint64) (uint64, error) { if co.closed { - return 0, errors.New("already closed") + return 0, ErrChannelOutAlreadyClosed } if co.FullErr() != nil { // channel is already full @@ -186,7 +187,7 @@ func (co *SpanChannelOut) FullErr() error { func (co *SpanChannelOut) Close() error { if co.closed { - return errors.New("already closed") + return ErrChannelOutAlreadyClosed } co.closed = true if err := co.Flush(); err != nil { diff --git a/op-node/rollup/derive/system_config.go b/op-node/rollup/derive/system_config.go index 51bbe9fcd6ba..6b0dbe50411d 100644 --- a/op-node/rollup/derive/system_config.go +++ b/op-node/rollup/derive/system_config.go @@ -30,7 +30,7 @@ var ( ) // UpdateSystemConfigWithL1Receipts filters all L1 receipts to find config updates and applies the config updates to the given sysCfg -func UpdateSystemConfigWithL1Receipts(sysCfg *eth.SystemConfig, receipts []*types.Receipt, cfg *rollup.Config) error { +func UpdateSystemConfigWithL1Receipts(sysCfg *eth.SystemConfig, receipts []*types.Receipt, cfg *rollup.Config, l1Time uint64) error { var result error for i, rec := range receipts { if rec.Status != types.ReceiptStatusSuccessful { @@ -38,7 +38,7 @@ func UpdateSystemConfigWithL1Receipts(sysCfg *eth.SystemConfig, receipts []*type } for j, log := range rec.Logs { if log.Address == cfg.L1SystemConfigAddress && len(log.Topics) > 0 && log.Topics[0] == ConfigUpdateEventABIHash { - if err := ProcessSystemConfigUpdateLogEvent(sysCfg, log); err != nil { + if err := ProcessSystemConfigUpdateLogEvent(sysCfg, log, cfg, l1Time); err != nil { result = multierror.Append(result, fmt.Errorf("malformatted L1 system sysCfg log in receipt %d, log %d: %w", i, j, err)) } } @@ -56,7 +56,7 @@ func UpdateSystemConfigWithL1Receipts(sysCfg *eth.SystemConfig, receipts []*type // UpdateType indexed updateType, // bytes data // ); -func ProcessSystemConfigUpdateLogEvent(destSysCfg *eth.SystemConfig, ev *types.Log) error { +func ProcessSystemConfigUpdateLogEvent(destSysCfg *eth.SystemConfig, ev *types.Log, rollupCfg *rollup.Config, l1Time uint64) error { if len(ev.Topics) != 3 { return fmt.Errorf("expected 3 event topics (event identity, indexed version, indexed updateType), got %d", len(ev.Topics)) } @@ -111,8 +111,18 @@ func ProcessSystemConfigUpdateLogEvent(destSysCfg *eth.SystemConfig, ev *types.L if !solabi.EmptyReader(reader) { return NewCriticalError(errors.New("too many bytes")) } - destSysCfg.Overhead = overhead - destSysCfg.Scalar = scalar + if rollupCfg.IsEcotone(l1Time) { + if err := eth.CheckEcotoneL1SystemConfigScalar(scalar); err != nil { + return nil // ignore invalid scalars, retain the old system-config scalar + } + // retain the scalar data in encoded form + destSysCfg.Scalar = scalar + // zero out the overhead, it will not affect the state-transition after Ecotone + destSysCfg.Overhead = eth.Bytes32{} + } else { + destSysCfg.Overhead = overhead + destSysCfg.Scalar = scalar + } return nil case SystemConfigUpdateGasLimit: if pointer, err := solabi.ReadUint64(reader); err != nil || pointer != 32 { diff --git a/op-node/rollup/derive/system_config_test.go b/op-node/rollup/derive/system_config_test.go index 210455150bf9..cab9e83be6be 100644 --- a/op-node/rollup/derive/system_config_test.go +++ b/op-node/rollup/derive/system_config_test.go @@ -4,11 +4,14 @@ import ( "math/big" "testing" - "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/require" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" ) var ( @@ -42,6 +45,9 @@ func TestProcessSystemConfigUpdateLogEvent(t *testing.T) { config eth.SystemConfig hook func(*testing.T, *types.Log) *types.Log err bool + // forks (optional) + ecotoneTime *uint64 + l1Time uint64 }{ { // The log data is ignored by consensus and no modifications to the @@ -138,6 +144,34 @@ func TestProcessSystemConfigUpdateLogEvent(t *testing.T) { }, err: false, }, + { + // The ecotone scalars should be updated + name: "SystemConfigUpdateGasConfigEcotone", + log: &types.Log{ + Topics: []common.Hash{ + ConfigUpdateEventABIHash, + ConfigUpdateEventVersion0, + SystemConfigUpdateGasConfig, + }, + }, + hook: func(t *testing.T, log *types.Log) *types.Log { + scalarData := common.Hash{0: 1, 24 + 3: 0xb3, 28 + 3: 0xbb} + scalar := scalarData.Big() + overhead := big.NewInt(0xff) + numberData, err := twoUint256.Pack(overhead, scalar) + require.NoError(t, err) + data, err := bytesArgs.Pack(numberData) + require.NoError(t, err) + log.Data = data + return log + }, + config: eth.SystemConfig{ + Scalar: eth.Bytes32{0: 1, 24 + 3: 0xb3, 28 + 3: 0xbb}, + }, + err: false, + ecotoneTime: new(uint64), // activate ecotone + l1Time: 200, + }, { name: "SystemConfigOneTopic", log: &types.Log{ @@ -157,8 +191,9 @@ func TestProcessSystemConfigUpdateLogEvent(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { config := eth.SystemConfig{} + rollupCfg := rollup.Config{EcotoneTime: test.ecotoneTime} - err := ProcessSystemConfigUpdateLogEvent(&config, test.hook(t, test.log)) + err := ProcessSystemConfigUpdateLogEvent(&config, test.hook(t, test.log), &rollupCfg, test.l1Time) if test.err { require.Error(t, err) } else { diff --git a/op-node/rollup/derive/test/random.go b/op-node/rollup/derive/test/random.go index 5724fd023f31..c0f512b49588 100644 --- a/op-node/rollup/derive/test/random.go +++ b/op-node/rollup/derive/test/random.go @@ -4,6 +4,7 @@ import ( "math/big" "math/rand" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testutils" @@ -11,12 +12,17 @@ import ( "github.com/ethereum/go-ethereum/trie" ) -// RandomL2Block returns a random block whose first transaction is a random +// RandomL2Block returns a random block whose first transaction is a random pre-Ecotone upgrade // L1 Info Deposit transaction. func RandomL2Block(rng *rand.Rand, txCount int) (*types.Block, []*types.Receipt) { l1Block := types.NewBlock(testutils.RandomHeader(rng), nil, nil, nil, trie.NewStackTrie(nil)) - l1InfoTx, err := derive.L1InfoDeposit(0, eth.BlockToInfo(l1Block), eth.SystemConfig{}, testutils.RandomBool(rng)) + rollupCfg := rollup.Config{} + if testutils.RandomBool(rng) { + t := uint64(0) + rollupCfg.RegolithTime = &t + } + l1InfoTx, err := derive.L1InfoDeposit(&rollupCfg, eth.SystemConfig{}, 0, eth.BlockToInfo(l1Block), 0) if err != nil { panic("L1InfoDeposit: " + err.Error()) } diff --git a/op-node/rollup/driver/driver.go b/op-node/rollup/driver/driver.go index c41fea100a12..c81a44bba6f8 100644 --- a/op-node/rollup/driver/driver.go +++ b/op-node/rollup/driver/driver.go @@ -8,6 +8,8 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/async" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -18,7 +20,7 @@ type Metrics interface { RecordPublishingError() RecordDerivationError() - RecordReceivedUnsafePayload(payload *eth.ExecutionPayload) + RecordReceivedUnsafePayload(payload *eth.ExecutionPayloadEnvelope) RecordL1Ref(name string, ref eth.L1BlockRef) RecordL2Ref(name string, ref eth.L2BlockRef) @@ -27,6 +29,8 @@ type Metrics interface { RecordChannelTimedOut() RecordFrame() + RecordDerivedBatches(batchType string) + RecordUnsafePayloadsBuffer(length uint64, memSize uint64, next eth.BlockID) SetDerivationIdle(idle bool) @@ -53,16 +57,12 @@ type L2Chain interface { type DerivationPipeline interface { Reset() Step(ctx context.Context) error - AddUnsafePayload(payload *eth.ExecutionPayload) - UnsafeL2SyncTarget() eth.L2BlockRef + AddUnsafePayload(payload *eth.ExecutionPayloadEnvelope) Finalize(ref eth.L1BlockRef) FinalizedL1() eth.L1BlockRef - Finalized() eth.L2BlockRef - SafeL2Head() eth.L2BlockRef - UnsafeL2Head() eth.L2BlockRef Origin() eth.L1BlockRef EngineReady() bool - EngineSyncTarget() eth.L2BlockRef + LowestQueuedUnsafeBlock() eth.L2BlockRef } type L1StateIface interface { @@ -77,16 +77,16 @@ type L1StateIface interface { type SequencerIface interface { StartBuildingBlock(ctx context.Context) error - CompleteBuildingBlock(ctx context.Context) (*eth.ExecutionPayload, error) + CompleteBuildingBlock(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (*eth.ExecutionPayloadEnvelope, error) PlanNextSequencerAction() time.Duration - RunNextSequencerAction(ctx context.Context) (*eth.ExecutionPayload, error) + RunNextSequencerAction(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (*eth.ExecutionPayloadEnvelope, error) BuildingOnto() eth.L2BlockRef CancelBuildingBlock(ctx context.Context) } type Network interface { // PublishL2Payload is called by the driver whenever there is a new payload to publish, synchronously with the driver main loop. - PublishL2Payload(ctx context.Context, payload *eth.ExecutionPayload) error + PublishL2Payload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error } type AltSync interface { @@ -114,41 +114,63 @@ type SequencerStateListener interface { } // NewDriver composes an events handler that tracks L1 state, triggers L2 derivation, and optionally sequences new L2 blocks. -func NewDriver(driverCfg *Config, cfg *rollup.Config, l2 L2Chain, l1 L1Chain, altSync AltSync, network Network, log log.Logger, snapshotLog log.Logger, metrics Metrics, sequencerStateListener SequencerStateListener, syncCfg *sync.Config) *Driver { +func NewDriver( + driverCfg *Config, + cfg *rollup.Config, + l2 L2Chain, + l1 L1Chain, + l1Blobs derive.L1BlobsFetcher, + altSync AltSync, + network Network, + log log.Logger, + snapshotLog log.Logger, + metrics Metrics, + sequencerStateListener SequencerStateListener, + safeHeadListener derive.SafeHeadListener, + syncCfg *sync.Config, + sequencerConductor conductor.SequencerConductor, + plasma derive.PlasmaInputFetcher, +) *Driver { l1 = NewMeteredL1Fetcher(l1, metrics) l1State := NewL1State(log, metrics) sequencerConfDepth := NewConfDepth(driverCfg.SequencerConfDepth, l1State.L1Head, l1) findL1Origin := NewL1OriginSelector(log, cfg, sequencerConfDepth) verifConfDepth := NewConfDepth(driverCfg.VerifierConfDepth, l1State.L1Head, l1) - derivationPipeline := derive.NewDerivationPipeline(log, cfg, verifConfDepth, l2, metrics, syncCfg) + engine := derive.NewEngineController(l2, log, metrics, cfg, syncCfg.SyncMode) + derivationPipeline := derive.NewDerivationPipeline(log, cfg, verifConfDepth, l1Blobs, plasma, l2, engine, metrics, syncCfg, safeHeadListener) attrBuilder := derive.NewFetchingAttributesBuilder(cfg, l1, l2) - engine := derivationPipeline - meteredEngine := NewMeteredEngine(cfg, engine, metrics, log) + meteredEngine := NewMeteredEngine(cfg, engine, metrics, log) // Only use the metered engine in the sequencer b/c it records sequencing metrics. sequencer := NewSequencer(log, cfg, meteredEngine, attrBuilder, findL1Origin, metrics) - + driverCtx, driverCancel := context.WithCancel(context.Background()) + asyncGossiper := async.NewAsyncGossiper(driverCtx, network, log, metrics) return &Driver{ - l1State: l1State, - derivation: derivationPipeline, - stateReq: make(chan chan struct{}), - forceReset: make(chan chan struct{}, 10), - startSequencer: make(chan hashAndErrorChannel, 10), - stopSequencer: make(chan chan hashAndError, 10), - sequencerActive: make(chan chan bool, 10), - sequencerNotifs: sequencerStateListener, - config: cfg, - driverConfig: driverCfg, - done: make(chan struct{}), - log: log, - snapshotLog: snapshotLog, - l1: l1, - l2: l2, - sequencer: sequencer, - network: network, - metrics: metrics, - l1HeadSig: make(chan eth.L1BlockRef, 10), - l1SafeSig: make(chan eth.L1BlockRef, 10), - l1FinalizedSig: make(chan eth.L1BlockRef, 10), - unsafeL2Payloads: make(chan *eth.ExecutionPayload, 10), - altSync: altSync, + l1State: l1State, + derivation: derivationPipeline, + engineController: engine, + stateReq: make(chan chan struct{}), + forceReset: make(chan chan struct{}, 10), + startSequencer: make(chan hashAndErrorChannel, 10), + stopSequencer: make(chan chan hashAndError, 10), + sequencerActive: make(chan chan bool, 10), + sequencerNotifs: sequencerStateListener, + config: cfg, + syncCfg: syncCfg, + driverConfig: driverCfg, + driverCtx: driverCtx, + driverCancel: driverCancel, + log: log, + snapshotLog: snapshotLog, + l1: l1, + l2: l2, + sequencer: sequencer, + network: network, + metrics: metrics, + l1HeadSig: make(chan eth.L1BlockRef, 10), + l1SafeSig: make(chan eth.L1BlockRef, 10), + l1FinalizedSig: make(chan eth.L1BlockRef, 10), + unsafeL2Payloads: make(chan *eth.ExecutionPayloadEnvelope, 10), + altSync: altSync, + asyncGossiper: asyncGossiper, + sequencerConductor: sequencerConductor, } } diff --git a/op-node/rollup/driver/metered_engine.go b/op-node/rollup/driver/metered_engine.go index ce92fe13151c..29f2c7e4c8a2 100644 --- a/op-node/rollup/driver/metered_engine.go +++ b/op-node/rollup/driver/metered_engine.go @@ -7,6 +7,8 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/async" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" ) @@ -21,7 +23,7 @@ type EngineMetrics interface { // MeteredEngine wraps an EngineControl and adds metrics such as block building time diff and sealing time type MeteredEngine struct { - inner derive.ResettableEngineControl + inner derive.EngineControl cfg *rollup.Config metrics EngineMetrics @@ -30,10 +32,7 @@ type MeteredEngine struct { buildingStartTime time.Time } -// MeteredEngine implements derive.ResettableEngineControl -var _ derive.ResettableEngineControl = (*MeteredEngine)(nil) - -func NewMeteredEngine(cfg *rollup.Config, inner derive.ResettableEngineControl, metrics EngineMetrics, log log.Logger) *MeteredEngine { +func NewMeteredEngine(cfg *rollup.Config, inner derive.EngineControl, metrics EngineMetrics, log log.Logger) *MeteredEngine { return &MeteredEngine{ inner: inner, cfg: cfg, @@ -54,7 +53,7 @@ func (m *MeteredEngine) SafeL2Head() eth.L2BlockRef { return m.inner.SafeL2Head() } -func (m *MeteredEngine) StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *eth.PayloadAttributes, updateSafe bool) (errType derive.BlockInsertionErrType, err error) { +func (m *MeteredEngine) StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *derive.AttributesWithParent, updateSafe bool) (errType derive.BlockInsertionErrType, err error) { m.buildingStartTime = time.Now() errType, err = m.inner.StartPayload(ctx, parent, attrs, updateSafe) if err != nil { @@ -63,10 +62,10 @@ func (m *MeteredEngine) StartPayload(ctx context.Context, parent eth.L2BlockRef, return errType, err } -func (m *MeteredEngine) ConfirmPayload(ctx context.Context) (out *eth.ExecutionPayload, errTyp derive.BlockInsertionErrType, err error) { +func (m *MeteredEngine) ConfirmPayload(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (out *eth.ExecutionPayloadEnvelope, errTyp derive.BlockInsertionErrType, err error) { sealingStart := time.Now() // Actually execute the block and add it to the head of the chain. - payload, errType, err := m.inner.ConfirmPayload(ctx) + payload, errType, err := m.inner.ConfirmPayload(ctx, agossip, sequencerConductor) if err != nil { m.metrics.RecordSequencingError() return payload, errType, err @@ -76,12 +75,14 @@ func (m *MeteredEngine) ConfirmPayload(ctx context.Context) (out *eth.ExecutionP buildTime := now.Sub(m.buildingStartTime) m.metrics.RecordSequencerSealingTime(sealTime) m.metrics.RecordSequencerBuildingDiffTime(buildTime - time.Duration(m.cfg.BlockTime)*time.Second) - m.metrics.CountSequencedTxs(len(payload.Transactions)) + + txnCount := len(payload.ExecutionPayload.Transactions) + m.metrics.CountSequencedTxs(txnCount) ref := m.inner.UnsafeL2Head() m.log.Debug("Processed new L2 block", "l2_unsafe", ref, "l1_origin", ref.L1Origin, - "txs", len(payload.Transactions), "time", ref.Time, "seal_time", sealTime, "build_time", buildTime) + "txs", txnCount, "time", ref.Time, "seal_time", sealTime, "build_time", buildTime) return payload, errType, err } @@ -93,7 +94,3 @@ func (m *MeteredEngine) CancelPayload(ctx context.Context, force bool) error { func (m *MeteredEngine) BuildingPayload() (onto eth.L2BlockRef, id eth.PayloadID, safe bool) { return m.inner.BuildingPayload() } - -func (m *MeteredEngine) Reset() { - m.inner.Reset() -} diff --git a/op-node/rollup/driver/origin_selector_test.go b/op-node/rollup/driver/origin_selector_test.go index dec4892db215..3380e144fdf5 100644 --- a/op-node/rollup/driver/origin_selector_test.go +++ b/op-node/rollup/driver/origin_selector_test.go @@ -21,7 +21,7 @@ import ( // is no conf depth to stop the origin selection so block `b` should // be the next L1 origin func TestOriginSelectorAdvances(t *testing.T) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) cfg := &rollup.Config{ MaxSequencerDrift: 500, BlockTime: 2, @@ -63,7 +63,7 @@ func TestOriginSelectorAdvances(t *testing.T) { // but it should select block `a` because the L2 block time must be ahead // of the the timestamp of it's L1 origin. func TestOriginSelectorRespectsOriginTiming(t *testing.T) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) cfg := &rollup.Config{ MaxSequencerDrift: 500, BlockTime: 2, @@ -104,7 +104,7 @@ func TestOriginSelectorRespectsOriginTiming(t *testing.T) { // as the origin, however block `b` is the L1 Head & the sequencer // needs to wait until that block is confirmed enough before advancing. func TestOriginSelectorRespectsConfDepth(t *testing.T) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) cfg := &rollup.Config{ MaxSequencerDrift: 500, BlockTime: 2, @@ -147,7 +147,7 @@ func TestOriginSelectorRespectsConfDepth(t *testing.T) { // This is because 29 (next L2 time) > 20 (origin) + 8 (seq drift) => invalid block. // We maintain confirmation distance, even though we would shift to the next origin if we could. func TestOriginSelectorStrictConfDepth(t *testing.T) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) cfg := &rollup.Config{ MaxSequencerDrift: 8, BlockTime: 2, @@ -185,7 +185,7 @@ func TestOriginSelectorStrictConfDepth(t *testing.T) { // drift, the origin should remain on block `a` because the next origin's // time is greater than the next L2 time. func TestOriginSelectorSeqDriftRespectsNextOriginTime(t *testing.T) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) cfg := &rollup.Config{ MaxSequencerDrift: 8, BlockTime: 2, @@ -228,7 +228,7 @@ func TestOriginSelectorSeqDriftRespectsNextOriginTime(t *testing.T) { // Due to a conf depth of 2, block `b` is not immediately visible, // and the origin selection should fail until it is visible, by waiting for block `c`. func TestOriginSelectorHandlesLateL1Blocks(t *testing.T) { - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) cfg := &rollup.Config{ MaxSequencerDrift: 8, BlockTime: 2, diff --git a/op-node/rollup/driver/sequencer.go b/op-node/rollup/driver/sequencer.go index e77de008c21e..c983033adb98 100644 --- a/op-node/rollup/driver/sequencer.go +++ b/op-node/rollup/driver/sequencer.go @@ -11,6 +11,8 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/async" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" ) @@ -18,9 +20,6 @@ import ( // When block produce is interrupted by high L1 latency, sequencer will build a full block periodically to avoid chain stuck const buildFullBlockInterval = 20 -// When block produce is lagging exceed lagTimeWindow, sequencer will set attrs.NoTxPool to true to quickly catch up -const lagTimeWindow = 2 * time.Minute - type Downloader interface { InfoByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, error) FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) @@ -39,10 +38,10 @@ type SequencerMetrics interface { // Sequencer implements the sequencing interface of the driver: it starts and completes block building jobs. type Sequencer struct { - log log.Logger - config *rollup.Config + log log.Logger + rollupCfg *rollup.Config - engine derive.ResettableEngineControl + engine derive.EngineControl attrBuilder derive.AttributesBuilder l1OriginSelector L1OriginSelectorIface @@ -58,10 +57,10 @@ type Sequencer struct { accEmptyBlocks int } -func NewSequencer(log log.Logger, cfg *rollup.Config, engine derive.ResettableEngineControl, attributesBuilder derive.AttributesBuilder, l1OriginSelector L1OriginSelectorIface, metrics SequencerMetrics) *Sequencer { +func NewSequencer(log log.Logger, rollupCfg *rollup.Config, engine derive.EngineControl, attributesBuilder derive.AttributesBuilder, l1OriginSelector L1OriginSelectorIface, metrics SequencerMetrics) *Sequencer { return &Sequencer{ log: log, - config: cfg, + rollupCfg: rollupCfg, engine: engine, timeNow: time.Now, attrBuilder: attributesBuilder, @@ -104,18 +103,12 @@ func (d *Sequencer) StartBuildingBlock(ctx context.Context) error { // 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. - if uint64(attrs.Timestamp) > l1Origin.Time+d.config.MaxSequencerDrift { + attrs.NoTxPool = uint64(attrs.Timestamp) > l1Origin.Time+d.rollupCfg.MaxSequencerDrift + + // For the Ecotone activation block we shouldn't include any sequencer transactions. + if d.rollupCfg.IsEcotoneActivationBlock(uint64(attrs.Timestamp)) { attrs.NoTxPool = true - } else { - // This is short term solution to increase sequencer catching up speed. - // Long term solution should optimize op-geth payload building work flow. - attrsTime := time.Unix(int64(attrs.Timestamp), 0) - isCatchingUp := time.Since(attrsTime) > lagTimeWindow - if isCatchingUp && (d.accEmptyBlocks < buildFullBlockInterval) { - attrs.NoTxPool = true - } else { - attrs.NoTxPool = false - } + d.log.Info("Sequencing Ecotone upgrade block") } d.log.Debug("prepared attributes for new block", @@ -123,8 +116,9 @@ func (d *Sequencer) StartBuildingBlock(ctx context.Context) error { "origin", l1Origin, "origin_time", l1Origin.Time, "noTxPool", attrs.NoTxPool) // Start a payload building process. + withParent := derive.NewAttributesWithParent(attrs, l2Head, false) start = time.Now() - errTyp, err := d.engine.StartPayload(ctx, l2Head, attrs, false) + errTyp, err := d.engine.StartPayload(ctx, l2Head, withParent, false) if err != nil { return fmt.Errorf("failed to start building on top of L2 chain %s, error (%d): %w", l2Head, errTyp, err) } @@ -135,12 +129,12 @@ func (d *Sequencer) StartBuildingBlock(ctx context.Context) error { // CompleteBuildingBlock takes the current block that is being built, and asks the engine to complete the building, seal the block, and persist it as canonical. // Warning: the safe and finalized L2 blocks as viewed during the initiation of the block building are reused for completion of the block building. // The Execution engine should not change the safe and finalized blocks between start and completion of block building. -func (d *Sequencer) CompleteBuildingBlock(ctx context.Context) (*eth.ExecutionPayload, error) { - payload, errTyp, err := d.engine.ConfirmPayload(ctx) +func (d *Sequencer) CompleteBuildingBlock(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (*eth.ExecutionPayloadEnvelope, error) { + envelope, errTyp, err := d.engine.ConfirmPayload(ctx, agossip, sequencerConductor) if err != nil { return nil, fmt.Errorf("failed to complete building block: error (%d): %w", errTyp, err) } - return payload, nil + return envelope, nil } // CancelBuildingBlock cancels the current open block building job. @@ -157,7 +151,7 @@ func (d *Sequencer) PlanNextSequencerAction() time.Duration { if onto, _, safe := d.engine.BuildingPayload(); safe { d.log.Warn("delaying sequencing to not interrupt safe-head changes", "onto", onto, "onto_time", onto.Time) // approximates the worst-case time it takes to build a block, to reattempt sequencing after. - return time.Second * time.Duration(d.config.BlockTime) + return time.Second * time.Duration(d.rollupCfg.BlockTime) } head := d.engine.UnsafeL2Head() @@ -171,8 +165,8 @@ func (d *Sequencer) PlanNextSequencerAction() time.Duration { return delay } - blockTime := time.Duration(d.config.BlockTime) * time.Second - payloadTime := time.Unix(int64(head.Time+d.config.BlockTime), 0) + blockTime := time.Duration(d.rollupCfg.BlockTime) * time.Second + payloadTime := time.Unix(int64(head.Time+d.rollupCfg.BlockTime), 0) remainingTime := payloadTime.Sub(now) // If we started building a block already, and if that work is still consistent, @@ -225,24 +219,25 @@ func (d *Sequencer) BuildingOnto() eth.L2BlockRef { // If the derivation pipeline does force a conflicting block, then an ongoing sequencer task might still finish, // but the derivation can continue to reset until the chain is correct. // If the engine is currently building safe blocks, then that building is not interrupted, and sequencing is delayed. -func (d *Sequencer) RunNextSequencerAction(ctx context.Context) (*eth.ExecutionPayload, error) { - if onto, buildingID, safe := d.engine.BuildingPayload(); buildingID != (eth.PayloadID{}) { +func (d *Sequencer) RunNextSequencerAction(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (*eth.ExecutionPayloadEnvelope, error) { + // if the engine returns a non-empty payload, OR if the async gossiper already has a payload, we can CompleteBuildingBlock + if onto, buildingID, safe := d.engine.BuildingPayload(); buildingID != (eth.PayloadID{}) || agossip.Get() != nil { if safe { d.log.Warn("avoiding sequencing to not interrupt safe-head changes", "onto", onto, "onto_time", onto.Time) // approximates the worst-case time it takes to build a block, to reattempt sequencing after. - d.nextAction = d.timeNow().Add(time.Second * time.Duration(d.config.BlockTime)) + d.nextAction = d.timeNow().Add(time.Second * time.Duration(d.rollupCfg.BlockTime)) return nil, nil } - payload, err := d.CompleteBuildingBlock(ctx) + envelope, err := d.CompleteBuildingBlock(ctx, agossip, sequencerConductor) if err != nil { if errors.Is(err, derive.ErrCritical) { return nil, err // bubble up critical errors. } else if errors.Is(err, derive.ErrReset) { d.log.Error("sequencer failed to seal new block, requiring derivation reset", "err", err) d.metrics.RecordSequencerReset() - d.nextAction = d.timeNow().Add(time.Second * time.Duration(d.config.BlockTime)) // hold off from sequencing for a full block + d.nextAction = d.timeNow().Add(time.Second * time.Duration(d.rollupCfg.BlockTime)) // hold off from sequencing for a full block d.CancelBuildingBlock(ctx) - d.engine.Reset() + return nil, err } else if errors.Is(err, derive.ErrTemporary) { d.log.Error("sequencer failed temporarily to seal new block", "err", err) d.nextAction = d.timeNow().Add(time.Second) @@ -255,12 +250,13 @@ func (d *Sequencer) RunNextSequencerAction(ctx context.Context) (*eth.ExecutionP } return nil, nil } else { - d.attrBuilder.CachePayloadByHash(payload) + payload := envelope.ExecutionPayload if len(payload.Transactions) == 1 { d.accEmptyBlocks += 1 } + d.attrBuilder.CachePayloadByHash(envelope) d.log.Info("sequencer successfully built a new block", "block", payload.ID(), "time", uint64(payload.Timestamp), "txs", len(payload.Transactions)) - return payload, nil + return envelope, nil } } else { start := time.Now() @@ -271,8 +267,8 @@ func (d *Sequencer) RunNextSequencerAction(ctx context.Context) (*eth.ExecutionP } else if errors.Is(err, derive.ErrReset) { d.log.Error("sequencer failed to seal new block, requiring derivation reset", "err", err) d.metrics.RecordSequencerReset() - d.nextAction = d.timeNow().Add(time.Second * time.Duration(d.config.BlockTime)) // hold off from sequencing for a full block - d.engine.Reset() + d.nextAction = d.timeNow().Add(time.Second * time.Duration(d.rollupCfg.BlockTime)) // hold off from sequencing for a full block + return nil, err } else if errors.Is(err, derive.ErrTemporary) { d.log.Error("sequencer temporarily failed to start building new block", "err", err) d.nextAction = d.timeNow().Add(time.Second) diff --git a/op-node/rollup/driver/sequencer_test.go b/op-node/rollup/driver/sequencer_test.go index 76e3d0021b45..bde035d43f28 100644 --- a/op-node/rollup/driver/sequencer_test.go +++ b/op-node/rollup/driver/sequencer_test.go @@ -18,6 +18,8 @@ import ( "github.com/ethereum-optimism/optimism/op-node/metrics" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/async" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" @@ -60,7 +62,7 @@ func (m *FakeEngineControl) avgTxsPerBlock() float64 { return float64(m.totalTxs) / float64(m.totalBuiltBlocks) } -func (m *FakeEngineControl) StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *eth.PayloadAttributes, updateSafe bool) (errType derive.BlockInsertionErrType, err error) { +func (m *FakeEngineControl) StartPayload(ctx context.Context, parent eth.L2BlockRef, attrs *derive.AttributesWithParent, updateSafe bool) (errType derive.BlockInsertionErrType, err error) { if m.err != nil { return m.errTyp, m.err } @@ -68,12 +70,12 @@ func (m *FakeEngineControl) StartPayload(ctx context.Context, parent eth.L2Block _, _ = crand.Read(m.buildingID[:]) m.buildingOnto = parent m.buildingSafe = updateSafe - m.buildingAttrs = attrs + m.buildingAttrs = attrs.Attributes() m.buildingStart = m.timeNow() return derive.BlockInsertOK, nil } -func (m *FakeEngineControl) ConfirmPayload(ctx context.Context) (out *eth.ExecutionPayload, errTyp derive.BlockInsertionErrType, err error) { +func (m *FakeEngineControl) ConfirmPayload(ctx context.Context, agossip async.AsyncGossiper, sequencerConductor conductor.SequencerConductor) (out *eth.ExecutionPayloadEnvelope, errTyp derive.BlockInsertionErrType, err error) { if m.err != nil { return nil, m.errTyp, m.err } @@ -81,7 +83,7 @@ func (m *FakeEngineControl) ConfirmPayload(ctx context.Context) (out *eth.Execut m.totalBuildingTime += buildTime m.totalBuiltBlocks += 1 payload := m.makePayload(m.buildingOnto, m.buildingAttrs) - ref, err := derive.PayloadToBlockRef(payload, &m.cfg.Genesis) + ref, err := derive.PayloadToBlockRef(m.cfg, payload) if err != nil { panic(err) } @@ -92,7 +94,7 @@ func (m *FakeEngineControl) ConfirmPayload(ctx context.Context) (out *eth.Execut m.resetBuildingState() m.totalTxs += len(payload.Transactions) - return payload, derive.BlockInsertOK, nil + return ð.ExecutionPayloadEnvelope{ExecutionPayload: payload}, derive.BlockInsertOK, nil } func (m *FakeEngineControl) CancelPayload(ctx context.Context, force bool) error { @@ -125,11 +127,7 @@ func (m *FakeEngineControl) resetBuildingState() { m.buildingAttrs = nil } -func (m *FakeEngineControl) Reset() { - m.err = nil -} - -var _ derive.ResettableEngineControl = (*FakeEngineControl)(nil) +var _ derive.EngineControl = (*FakeEngineControl)(nil) type testAttrBuilderFn func(ctx context.Context, l2Parent eth.L2BlockRef, epoch eth.BlockID) (attrs *eth.PayloadAttributes, err error) @@ -177,7 +175,7 @@ func TestSequencerChaosMonkey(t *testing.T) { l1Time := uint64(100000) // mute errors. We expect a lot of the mocked errors to cause error-logs. We check chain health at the end of the test. - log := testlog.Logger(t, log.LvlCrit) + log := testlog.Logger(t, log.LevelCrit) cfg := &rollup.Config{ Genesis: rollup.Genesis{ @@ -256,7 +254,7 @@ func TestSequencerChaosMonkey(t *testing.T) { InfoBaseFee: big.NewInt(1234), InfoReceiptRoot: common.Hash{}, } - infoDep, err := derive.L1InfoDepositBytes(seqNr, l1Info, cfg.Genesis.SystemConfig, false) + infoDep, err := derive.L1InfoDepositBytes(cfg, cfg.Genesis.SystemConfig, seqNr, l1Info, 0) require.NoError(t, err) testGasLimit := eth.Uint64Quantity(10_000_000) @@ -352,15 +350,19 @@ func TestSequencerChaosMonkey(t *testing.T) { default: // no error } - payload, err := seq.RunNextSequencerAction(context.Background()) - require.NoError(t, err) + payload, err := seq.RunNextSequencerAction(context.Background(), async.NoOpGossiper{}, &conductor.NoOpConductor{}) + // RunNextSequencerAction passes ErrReset & ErrCritical through. + // Only suppress ErrReset, not ErrCritical + if !errors.Is(err, derive.ErrReset) { + require.NoError(t, err) + } if payload != nil { - require.Equal(t, engControl.UnsafeL2Head().ID(), payload.ID(), "head must stay in sync with emitted payloads") + require.Equal(t, engControl.UnsafeL2Head().ID(), payload.ExecutionPayload.ID(), "head must stay in sync with emitted payloads") var tx types.Transaction - require.NoError(t, tx.UnmarshalBinary(payload.Transactions[0])) - info, err := derive.L1InfoDepositTxData(tx.Data()) + require.NoError(t, tx.UnmarshalBinary(payload.ExecutionPayload.Transactions[0])) + info, err := derive.L1BlockInfoFromBytes(cfg, uint64(payload.ExecutionPayload.Timestamp), tx.Data()) require.NoError(t, err) - require.GreaterOrEqual(t, uint64(payload.Timestamp), info.Time, "ensure L2 time >= L1 time") + require.GreaterOrEqual(t, uint64(payload.ExecutionPayload.Timestamp), info.Time, "ensure L2 time >= L1 time") } } diff --git a/op-node/rollup/driver/state.go b/op-node/rollup/driver/state.go index 922c78c6f427..8292c5d2c16c 100644 --- a/op-node/rollup/driver/state.go +++ b/op-node/rollup/driver/state.go @@ -14,11 +14,19 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/async" + "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/retry" ) +var ( + ErrSequencerAlreadyStarted = errors.New("sequencer already running") + ErrSequencerAlreadyStopped = errors.New("sequencer not running") +) + // Deprecated: use eth.SyncStatus instead. type SyncStatus = eth.SyncStatus @@ -32,6 +40,10 @@ type Driver struct { // The derivation pipeline determines the new l2Safe. derivation DerivationPipeline + // The engine controller is used by the sequencer & derivation components. + // We will also use it for EL sync in a future PR. + engineController *derive.EngineController + // Requests to block the event loop for synchronous execution to avoid reading an inconsistent state stateReq chan chan struct{} @@ -58,9 +70,14 @@ type Driver struct { // Rollup config: rollup chain configuration config *rollup.Config + sequencerConductor conductor.SequencerConductor + // Driver config: verifier and sequencer settings driverConfig *Config + // Sync Mod Config + syncCfg *sync.Config + // L1 Signals: // // Not all L1 blocks, or all changes, have to be signalled: @@ -74,9 +91,13 @@ type Driver struct { // Interface to signal the L2 block range to sync. altSync AltSync + // async gossiper for payloads to be gossiped without + // blocking the event loop or waiting for insertion + asyncGossiper async.AsyncGossiper + // L2 Signals: - unsafeL2Payloads chan *eth.ExecutionPayload + unsafeL2Payloads chan *eth.ExecutionPayloadEnvelope l1 L1Chain l2 L2Chain @@ -86,9 +107,11 @@ type Driver struct { metrics Metrics log log.Logger snapshotLog log.Logger - done chan struct{} wg gosync.WaitGroup + + driverCtx context.Context + driverCancel context.CancelFunc } // Start starts up the state loop. @@ -111,6 +134,8 @@ func (s *Driver) Start() error { } } + s.asyncGossiper.Start() + s.wg.Add(1) go s.eventLoop() @@ -118,8 +143,10 @@ func (s *Driver) Start() error { } func (s *Driver) Close() error { - s.done <- struct{}{} + s.driverCancel() s.wg.Wait() + s.asyncGossiper.Stop() + s.sequencerConductor.Close() return nil } @@ -154,22 +181,34 @@ func (s *Driver) OnL1Finalized(ctx context.Context, finalized eth.L1BlockRef) er } } -func (s *Driver) OnUnsafeL2Payload(ctx context.Context, payload *eth.ExecutionPayload) error { +func (s *Driver) OnUnsafeL2Payload(ctx context.Context, envelope *eth.ExecutionPayloadEnvelope) error { select { case <-ctx.Done(): return ctx.Err() - case s.unsafeL2Payloads <- payload: + case s.unsafeL2Payloads <- envelope: return nil } } +func (s *Driver) logSyncProgress(reason string) { + s.log.Info("Sync progress", + "reason", reason, + "l2_finalized", s.engineController.Finalized(), + "l2_safe", s.engineController.SafeL2Head(), + "l2_pending_safe", s.engineController.PendingSafeL2Head(), + "l2_unsafe", s.engineController.UnsafeL2Head(), + "l2_time", s.engineController.UnsafeL2Head().Time, + "l1_derived", s.derivation.Origin(), + ) +} + // the eventLoop responds to L1 changes and internal timers to produce L2 blocks. func (s *Driver) eventLoop() { defer s.wg.Done() s.log.Info("State loop started") + defer s.log.Info("State loop returned") - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + defer s.driverCancel() // stepReqCh is used to request that the driver attempts to step forward by one L1 block. stepReqCh := make(chan struct{}, 1) @@ -223,19 +262,15 @@ func (s *Driver) eventLoop() { } sequencerStep := func() error { - payload, err := s.sequencer.RunNextSequencerAction(ctx) - if err != nil { + // the payload publishing is handled by the async gossiper, which will begin gossiping as soon as available + // so, we don't need to receive the payload here + _, err := s.sequencer.RunNextSequencerAction(s.driverCtx, s.asyncGossiper, s.sequencerConductor) + if errors.Is(err, derive.ErrReset) { + s.derivation.Reset() + } else if err != nil { s.log.Error("Sequencer critical error", "err", err) return err } - if s.network != nil && payload != nil { - // Publishing of unsafe data via p2p is optional. - // Errors are not severe enough to change/halt sequencing but should be logged and metered. - if err := s.network.PublishL2Payload(ctx, payload); err != nil { - s.log.Warn("failed to publish newly created block", "id", payload.ID(), "err", err) - s.metrics.RecordPublishingError() - } - } planSequencerAction() // schedule the next sequencer action to keep the sequencing looping return nil } @@ -245,26 +280,30 @@ func (s *Driver) eventLoop() { syncCheckInterval := time.Duration(s.config.BlockTime) * time.Second * 2 altSyncTicker := time.NewTicker(syncCheckInterval) defer altSyncTicker.Stop() - lastUnsafeL2 := s.derivation.UnsafeL2Head() + lastUnsafeL2 := s.engineController.UnsafeL2Head() for { + if s.driverCtx.Err() != nil { // don't try to schedule/handle more work when we are closing. + return + } + // If we are sequencing, and the L1 state is ready, update the trigger for the next sequencer action. // This may adjust at any time based on fork-choice changes or previous errors. // And avoid sequencing if the derivation pipeline indicates the engine is not ready. if s.driverConfig.SequencerEnabled && !s.driverConfig.SequencerStopped && s.l1State.L1Head() != (eth.L1BlockRef{}) && s.derivation.EngineReady() { - if s.driverConfig.SequencerMaxSafeLag > 0 && s.derivation.SafeL2Head().Number+s.driverConfig.SequencerMaxSafeLag <= s.derivation.UnsafeL2Head().Number { + if s.driverConfig.SequencerMaxSafeLag > 0 && s.engineController.SafeL2Head().Number+s.driverConfig.SequencerMaxSafeLag <= s.engineController.UnsafeL2Head().Number { // If the safe head has fallen behind by a significant number of blocks, delay creating new blocks // until the safe lag is below SequencerMaxSafeLag. if sequencerCh != nil { s.log.Warn( "Delay creating new block since safe lag exceeds limit", - "safe_l2", s.derivation.SafeL2Head(), - "unsafe_l2", s.derivation.UnsafeL2Head(), + "safe_l2", s.engineController.SafeL2Head(), + "unsafe_l2", s.engineController.UnsafeL2Head(), ) sequencerCh = nil } - } else if s.sequencer.BuildingOnto().ID() != s.derivation.UnsafeL2Head().ID() { + } else if s.sequencer.BuildingOnto().ID() != s.engineController.UnsafeL2Head().ID() { // If we are sequencing, and the L1 state is ready, update the trigger for the next sequencer action. // This may adjust at any time based on fork-choice changes or previous errors. // @@ -294,7 +333,7 @@ func (s *Driver) eventLoop() { // If the engine is not ready, or if the L2 head is actively changing, then reset the alt-sync: // there is no need to request L2 blocks when we are syncing already. - if head := s.derivation.UnsafeL2Head(); head != lastUnsafeL2 || !s.derivation.EngineReady() { + if head := s.engineController.UnsafeL2Head(); head != lastUnsafeL2 || !s.derivation.EngineReady() { lastUnsafeL2 = head altSyncTicker.Reset(syncCheckInterval) } @@ -313,7 +352,7 @@ func (s *Driver) eventLoop() { continue case respCh := <-s.stopSequencer: if s.driverConfig.SequencerStopped { - respCh <- hashAndError{err: errors.New("sequencer not running")} + respCh <- hashAndError{err: ErrSequencerAlreadyStopped} } else { if err := s.sequencerNotifs.SequencerStopped(); err != nil { respCh <- hashAndError{err: fmt.Errorf("sequencer start notification: %w", err)} @@ -321,7 +360,10 @@ func (s *Driver) eventLoop() { } s.log.Warn("Sequencer has been stopped") s.driverConfig.SequencerStopped = true - respCh <- hashAndError{hash: s.derivation.UnsafeL2Head().Hash} + // Cancel any inflight block building. If we don't cancel this, we can resume sequencing an old block + // even if we've received new unsafe heads in the interim, causing us to introduce a re-org. + s.sequencer.CancelBuildingBlock(s.driverCtx) + respCh <- hashAndError{hash: s.engineController.UnsafeL2Head().Hash} } continue case respCh := <-s.sequencerActive: @@ -341,18 +383,35 @@ func (s *Driver) eventLoop() { } case <-altSyncTicker.C: // Check if there is a gap in the current unsafe payload queue. - ctx, cancel := context.WithTimeout(ctx, time.Second*2) + ctx, cancel := context.WithTimeout(s.driverCtx, time.Second*2) err := s.checkForGapInUnsafeQueue(ctx) cancel() if err != nil { s.log.Warn("failed to check for unsafe L2 blocks to sync", "err", err) } - case payload := <-s.unsafeL2Payloads: + case envelope := <-s.unsafeL2Payloads: s.snapshot("New unsafe payload") - s.log.Info("Optimistically queueing unsafe L2 execution payload", "id", payload.ID()) - s.derivation.AddUnsafePayload(payload) - s.metrics.RecordReceivedUnsafePayload(payload) - reqStep() + // If we are doing CL sync or done with engine syncing, fallback to the unsafe payload queue & CL P2P sync. + if s.syncCfg.SyncMode == sync.CLSync || !s.engineController.IsEngineSyncing() { + s.log.Info("Optimistically queueing unsafe L2 execution payload", "id", envelope.ExecutionPayload.ID()) + s.derivation.AddUnsafePayload(envelope) + s.metrics.RecordReceivedUnsafePayload(envelope) + reqStep() + } else if s.syncCfg.SyncMode == sync.ELSync { + ref, err := derive.PayloadToBlockRef(s.config, envelope.ExecutionPayload) + if err != nil { + s.log.Info("Failed to turn execution payload into a block ref", "id", envelope.ExecutionPayload.ID(), "err", err) + continue + } + if ref.Number <= s.engineController.UnsafeL2Head().Number { + continue + } + s.log.Info("Optimistically inserting unsafe L2 execution payload to drive EL sync", "id", envelope.ExecutionPayload.ID()) + if err := s.engineController.InsertUnsafePayload(s.driverCtx, envelope, ref); err != nil { + s.log.Warn("Failed to insert unsafe payload for EL sync", "id", envelope.ExecutionPayload.ID(), "err", err) + } + s.logSyncProgress("unsafe payload from sequencer while in EL sync") + } case newL1Head := <-s.l1HeadSig: s.l1State.HandleNewL1HeadBlock(newL1Head) reqStep() // a new L1 head may mean we have the data to not get an EOF again. @@ -367,17 +426,21 @@ func (s *Driver) eventLoop() { delayedStepReq = nil step() case <-stepReqCh: + // Don't start the derivation pipeline until we are done with EL sync + if s.engineController.IsEngineSyncing() { + continue + } s.metrics.SetDerivationIdle(false) s.log.Debug("Derivation process step", "onto_origin", s.derivation.Origin(), "attempts", stepAttempts) - err := s.derivation.Step(context.Background()) + err := s.derivation.Step(s.driverCtx) stepAttempts += 1 // count as attempt by default. We reset to 0 if we are making healthy progress. if err == io.EOF { s.log.Debug("Derivation process went idle", "progress", s.derivation.Origin(), "err", err) stepAttempts = 0 s.metrics.SetDerivationIdle(true) continue - } else if err != nil && errors.Is(err, derive.EngineP2PSyncing) { - s.log.Debug("Derivation process went idle because the engine is syncing", "progress", s.derivation.Origin(), "sync_target", s.derivation.EngineSyncTarget(), "err", err) + } else if err != nil && errors.Is(err, derive.EngineELSyncing) { + s.log.Debug("Derivation process went idle because the engine is syncing", "progress", s.derivation.Origin(), "unsafe_head", s.engineController.UnsafeL2Head(), "err", err) stepAttempts = 0 s.metrics.SetDerivationIdle(true) continue @@ -414,9 +477,9 @@ func (s *Driver) eventLoop() { s.metrics.RecordPipelineReset() close(respCh) case resp := <-s.startSequencer: - unsafeHead := s.derivation.UnsafeL2Head().Hash + unsafeHead := s.engineController.UnsafeL2Head().Hash if !s.driverConfig.SequencerStopped { - resp.err <- errors.New("sequencer already running") + resp.err <- ErrSequencerAlreadyStarted } else if !bytes.Equal(unsafeHead[:], resp.hash[:]) { resp.err <- fmt.Errorf("block hash does not match: head %s, received %s", unsafeHead.String(), resp.hash.String()) } else { @@ -431,7 +494,7 @@ func (s *Driver) eventLoop() { } case respCh := <-s.stopSequencer: if s.driverConfig.SequencerStopped { - respCh <- hashAndError{err: errors.New("sequencer not running")} + respCh <- hashAndError{err: ErrSequencerAlreadyStopped} } else { if err := s.sequencerNotifs.SequencerStopped(); err != nil { respCh <- hashAndError{err: fmt.Errorf("sequencer start notification: %w", err)} @@ -441,12 +504,12 @@ func (s *Driver) eventLoop() { s.driverConfig.SequencerStopped = true // Cancel any inflight block building. If we don't cancel this, we can resume sequencing an old block // even if we've received new unsafe heads in the interim, causing us to introduce a re-org. - s.sequencer.CancelBuildingBlock(ctx) - respCh <- hashAndError{hash: s.derivation.UnsafeL2Head().Hash} + s.sequencer.CancelBuildingBlock(s.driverCtx) + respCh <- hashAndError{hash: s.engineController.UnsafeL2Head().Hash} } case respCh := <-s.sequencerActive: respCh <- !s.driverConfig.SequencerStopped - case <-s.done: + case <-s.driverCtx.Done(): return } } @@ -474,6 +537,11 @@ func (s *Driver) StartSequencer(ctx context.Context, blockHash common.Hash) erro if !s.driverConfig.SequencerEnabled { return errors.New("sequencer is not enabled") } + if isLeader, err := s.sequencerConductor.Leader(ctx); err != nil { + return fmt.Errorf("sequencer leader check failed: %w", err) + } else if !isLeader { + return errors.New("sequencer is not the leader, aborting.") + } h := hashAndErrorChannel{ hash: blockHash, err: make(chan error, 1), @@ -536,11 +604,10 @@ func (s *Driver) syncStatus() *eth.SyncStatus { HeadL1: s.l1State.L1Head(), SafeL1: s.l1State.L1Safe(), FinalizedL1: s.l1State.L1Finalized(), - UnsafeL2: s.derivation.UnsafeL2Head(), - SafeL2: s.derivation.SafeL2Head(), - FinalizedL2: s.derivation.Finalized(), - UnsafeL2SyncTarget: s.derivation.UnsafeL2SyncTarget(), - EngineSyncTarget: s.derivation.EngineSyncTarget(), + UnsafeL2: s.engineController.UnsafeL2Head(), + SafeL2: s.engineController.SafeL2Head(), + FinalizedL2: s.engineController.Finalized(), + PendingSafeL2: s.engineController.PendingSafeL2Head(), } } @@ -589,9 +656,9 @@ func (s *Driver) snapshot(event string) { "event", event, "l1Head", deferJSONString{s.l1State.L1Head()}, "l1Current", deferJSONString{s.derivation.Origin()}, - "l2Head", deferJSONString{s.derivation.UnsafeL2Head()}, - "l2Safe", deferJSONString{s.derivation.SafeL2Head()}, - "l2FinalizedHead", deferJSONString{s.derivation.Finalized()}) + "l2Head", deferJSONString{s.engineController.UnsafeL2Head()}, + "l2Safe", deferJSONString{s.engineController.SafeL2Head()}, + "l2FinalizedHead", deferJSONString{s.engineController.Finalized()}) } type hashAndError struct { @@ -608,8 +675,8 @@ type hashAndErrorChannel struct { // WARNING: This is only an outgoing signal, the blocks are not guaranteed to be retrieved. // Results are received through OnUnsafeL2Payload. func (s *Driver) checkForGapInUnsafeQueue(ctx context.Context) error { - start := s.derivation.UnsafeL2Head() - end := s.derivation.UnsafeL2SyncTarget() + start := s.engineController.UnsafeL2Head() + end := s.derivation.LowestQueuedUnsafeBlock() // Check if we have missing blocks between the start and end. Request them if we do. if end == (eth.L2BlockRef{}) { s.log.Debug("requesting sync with open-end range", "start", start) diff --git a/op-node/rollup/superchain.go b/op-node/rollup/superchain.go index 88d802f5cf13..9c8ff2b8cb4a 100644 --- a/op-node/rollup/superchain.go +++ b/op-node/rollup/superchain.go @@ -12,20 +12,22 @@ import ( "github.com/ethereum-optimism/superchain-registry/superchain" ) -var OPStackSupport = params.ProtocolVersionV0{Build: [8]byte{}, Major: 4, Minor: 0, Patch: 0, PreRelease: 1}.Encode() +var OPStackSupport = params.ProtocolVersionV0{Build: [8]byte{}, Major: 6, Minor: 0, Patch: 0, PreRelease: 0}.Encode() const ( - opMainnet = 10 - opGoerli = 420 - opSepolia = 11155420 + opMainnet = 10 + opGoerli = 420 + opSepolia = 11155420 + + labsGoerliDevnet = 997 + labsGoerliChaosnet = 888 + labsSepoliaDevnet0 = 11155421 + baseGoerli = 84531 baseMainnet = 8453 - pgnMainnet = 424 - pgnSepolia = 58008 - zoraGoerli = 999 - zoraMainnet = 7777777 - labsDevnet = 997 - chaosnet = 888 + + pgnMainnet = 424 + pgnSepolia = 58008 ) // LoadOPStackRollupConfig loads the rollup configuration of the requested chain ID from the superchain-registry. @@ -53,10 +55,8 @@ func LoadOPStackRollupConfig(chainID uint64) (*Config, error) { return nil, fmt.Errorf("unable to retrieve genesis SystemConfig of chain %d", chainID) } - var depositContractAddress common.Address - if addrs, ok := superchain.Addresses[chainID]; ok { - depositContractAddress = common.Address(addrs.OptimismPortalProxy) - } else { + addrs, ok := superchain.Addresses[chainID] + if !ok { return nil, fmt.Errorf("unable to retrieve deposit contract address") } @@ -68,9 +68,9 @@ func LoadOPStackRollupConfig(chainID uint64) (*Config, error) { regolithTime = 1683219600 case opGoerli: regolithTime = 1679079600 - case labsDevnet: + case labsGoerliDevnet: regolithTime = 1677984480 - case chaosnet: + case labsGoerliChaosnet: regolithTime = 1692156862 } @@ -98,17 +98,24 @@ func LoadOPStackRollupConfig(chainID uint64) (*Config, error) { L1ChainID: new(big.Int).SetUint64(superChain.Config.L1.ChainID), L2ChainID: new(big.Int).SetUint64(chConfig.ChainID), RegolithTime: ®olithTime, - CanyonTime: superChain.Config.CanyonTime, + CanyonTime: chConfig.CanyonTime, + DeltaTime: chConfig.DeltaTime, + EcotoneTime: chConfig.EcotoneTime, + FjordTime: chConfig.FjordTime, BatchInboxAddress: common.Address(chConfig.BatchInboxAddr), - DepositContractAddress: depositContractAddress, - L1SystemConfigAddress: common.Address(chConfig.SystemConfigAddr), + DepositContractAddress: common.Address(addrs.OptimismPortalProxy), + L1SystemConfigAddress: common.Address(addrs.SystemConfigProxy), } if superChain.Config.ProtocolVersionsAddr != nil { // Set optional protocol versions address cfg.ProtocolVersionsAddress = common.Address(*superChain.Config.ProtocolVersionsAddr) } - if chainID == labsDevnet || chainID == chaosnet { + if chainID == labsGoerliDevnet || chainID == labsGoerliChaosnet { cfg.ChannelTimeout = 120 cfg.MaxSequencerDrift = 1200 } + if chainID == pgnSepolia { + cfg.MaxSequencerDrift = 1000 + cfg.SeqWindowSize = 7200 + } return cfg, nil } diff --git a/op-node/rollup/sync/config.go b/op-node/rollup/sync/config.go index a30ae036789f..3b0b6b21880e 100644 --- a/op-node/rollup/sync/config.go +++ b/op-node/rollup/sync/config.go @@ -1,8 +1,73 @@ package sync +import ( + "fmt" + "strings" +) + +type Mode int + +// There are two kinds of sync mode that the op-node does: +// 1. In consensus-layer (CL) sync, the op-node fully drives the execution client and imports unsafe blocks & +// fetches unsafe blocks that it has missed. +// 2. In execution-layer (EL) sync, the op-node tells the execution client to sync towards the tip of the chain. +// It will consolidate the chain as usual. This allows execution clients to snap sync if they are capable of it. +const ( + CLSync Mode = iota + ELSync Mode = iota +) + +const ( + CLSyncString string = "consensus-layer" + ELSyncString string = "execution-layer" +) + +var Modes = []Mode{CLSync, ELSync} +var ModeStrings = []string{CLSyncString, ELSyncString} + +func StringToMode(s string) (Mode, error) { + switch strings.ToLower(s) { + case CLSyncString: + return CLSync, nil + case ELSyncString: + return ELSync, nil + default: + return 0, fmt.Errorf("unknown sync mode: %s", s) + } +} + +func (m Mode) String() string { + switch m { + case CLSync: + return CLSyncString + case ELSync: + return ELSyncString + default: + return "unknown" + } +} + +func (m *Mode) Set(value string) error { + v, err := StringToMode(value) + if err != nil { + return err + } + *m = v + return nil +} + +func (m *Mode) Clone() any { + cpy := *m + return &cpy +} + type Config struct { - // EngineSync is true when the EngineQueue can trigger execution engine P2P sync. - EngineSync bool `json:"engine_sync"` - // SkipSyncStartCheck skip the sanity check of consistency of L1 origins of the unsafe L2 blocks when determining the sync-starting point. This defers the L1-origin verification, and is recommended to use in when utilizing l2.engine-sync + // SyncMode is defined above. + SyncMode Mode `json:"syncmode"` + // SkipSyncStartCheck skip the sanity check of consistency of L1 origins of the unsafe L2 blocks when determining the sync-starting point. + // This defers the L1-origin verification, and is recommended to use in when utilizing --syncmode=execution-layer on op-node and --syncmode=snap on op-geth + // Warning: This will be removed when we implement proper checkpoints. + // Note: We probably need to detect the condition that snap sync has not complete when we do a restart prior to running sync-start if we are doing + // snap sync with a genesis finalization data. SkipSyncStartCheck bool `json:"skip_sync_start_check"` } diff --git a/op-node/rollup/sync/start.go b/op-node/rollup/sync/start.go index aed0befd04b0..34d650cec749 100644 --- a/op-node/rollup/sync/start.go +++ b/op-node/rollup/sync/start.go @@ -176,7 +176,7 @@ func FindL2Heads(ctx context.Context, cfg *rollup.Config, l1 L1Chain, l2 L2Chain if result.Unsafe == (eth.L2BlockRef{}) { result.Unsafe = n // Check we are not reorging L2 incredibly deep - if n.L1Origin.Number+(MaxReorgSeqWindows*cfg.SeqWindowSize) < prevUnsafe.L1Origin.Number { + if n.L1Origin.Number+(MaxReorgSeqWindows*cfg.SyncLookback()) < prevUnsafe.L1Origin.Number { // If the reorg depth is too large, something is fishy. // This can legitimately happen if L1 goes down for a while. But in that case, // restarting the L2 node with a bigger configured MaxReorgDepth is an acceptable @@ -195,13 +195,13 @@ func FindL2Heads(ctx context.Context, cfg *rollup.Config, l1 L1Chain, l2 L2Chain highestL2WithCanonicalL1Origin = n } } else { - // L1 origin not ahead of L1 head nor canonical, discard previous candidate and keep looking. + // L1 origin neither ahead of L1 head nor canonical, discard previous candidate and keep looking. result.Unsafe = eth.L2BlockRef{} highestL2WithCanonicalL1Origin = eth.L2BlockRef{} } // If the L2 block is at least as old as the previous safe head, and we have seen at least a full sequence window worth of L1 blocks to confirm - if n.Number <= result.Safe.Number && n.L1Origin.Number+cfg.SeqWindowSize < highestL2WithCanonicalL1Origin.L1Origin.Number && n.SequenceNumber == 0 { + if n.Number <= result.Safe.Number && n.L1Origin.Number+cfg.SyncLookback() < highestL2WithCanonicalL1Origin.L1Origin.Number && n.SequenceNumber == 0 { ready = true } diff --git a/op-node/rollup/sync/start_test.go b/op-node/rollup/sync/start_test.go index 1881b7b61e45..0c202543c5de 100644 --- a/op-node/rollup/sync/start_test.go +++ b/op-node/rollup/sync/start_test.go @@ -23,7 +23,7 @@ var _ L2Chain = (*testutils.FakeChainSource)(nil) // - Both heads are at the tip of their respective chains func (c *syncStartTestCase) generateFakeL2(t *testing.T) (*testutils.FakeChainSource, rollup.Genesis) { t.Helper() - log := testlog.Logger(t, log.LvlError) + log := testlog.Logger(t, log.LevelError) chain := testutils.NewFakeChainSource([]string{c.L1, c.NewL1}, []string{c.L2}, int(c.GenesisL1Num), log) chain.SetL2Head(len(c.L2) - 1) genesis := testutils.FakeGenesis(c.GenesisL1, c.GenesisL2, int(c.GenesisL1Num)) @@ -74,8 +74,7 @@ func (c *syncStartTestCase) Run(t *testing.T) { Genesis: genesis, SeqWindowSize: c.SeqWindowSize, } - lgr := log.New() - lgr.SetHandler(log.DiscardHandler()) + lgr := log.NewLogger(log.DiscardHandler()) result, err := FindL2Heads(context.Background(), cfg, chain, chain, lgr, &Config{}) if c.ExpectedErr != nil { require.ErrorIs(t, err, c.ExpectedErr, "expected error") @@ -108,6 +107,23 @@ func TestFindSyncStart(t *testing.T) { SafeL2Head: 'A', ExpectedErr: nil, }, + { + Name: "already synced with safe head after genesis", + GenesisL1Num: 0, + L1: "abcdefghijkj", + L2: "ABCDEFGHIJKJ", + NewL1: "abcdefghijkj", + PreFinalizedL2: 'B', + PreSafeL2: 'D', + GenesisL1: 'a', + GenesisL2: 'A', + UnsafeL2Head: 'J', + SeqWindowSize: 2, + // Important this steps back at least one safe block so the safedb is sent the latest safe head + // again - we may be resetting because the safedb failed to write the previous entry + SafeL2Head: 'C', + ExpectedErr: nil, + }, { Name: "small reorg long chain", GenesisL1Num: 0, diff --git a/op-node/rollup/types.go b/op-node/rollup/types.go index 31c30fa9af26..6aed715ae515 100644 --- a/op-node/rollup/types.go +++ b/op-node/rollup/types.go @@ -7,10 +7,12 @@ import ( "math/big" "time" - "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + + plasma "github.com/ethereum-optimism/optimism/op-plasma" + "github.com/ethereum-optimism/optimism/op-service/eth" ) var ( @@ -81,11 +83,25 @@ type Config struct { // Active if RegolithTime != nil && L2 block timestamp >= *RegolithTime, inactive otherwise. RegolithTime *uint64 `json:"regolith_time,omitempty"` - // CanyonTime sets the activation time of the next network upgrade. + // CanyonTime sets the activation time of the Canyon network upgrade. // Active if CanyonTime != nil && L2 block timestamp >= *CanyonTime, inactive otherwise. CanyonTime *uint64 `json:"canyon_time,omitempty"` - SpanBatchTime *uint64 `json:"span_batch_time,omitempty"` + // DeltaTime sets the activation time of the Delta network upgrade. + // Active if DeltaTime != nil && L2 block timestamp >= *DeltaTime, inactive otherwise. + DeltaTime *uint64 `json:"delta_time,omitempty"` + + // EcotoneTime sets the activation time of the Ecotone network upgrade. + // Active if EcotoneTime != nil && L2 block timestamp >= *EcotoneTime, inactive otherwise. + EcotoneTime *uint64 `json:"ecotone_time,omitempty"` + + // FjordTime sets the activation time of the Fjord network upgrade. + // Active if FjordTime != nil && L2 block timestamp >= *FjordTime, inactive otherwise. + FjordTime *uint64 `json:"fjord_time,omitempty"` + + // InteropTime sets the activation time for an experimental feature-set, activated like a hardfork. + // Active if InteropTime != nil && L2 block timestamp >= *InteropTime, inactive otherwise. + InteropTime *uint64 `json:"interop_time,omitempty"` // OPBNB hard fork L2 block number // Fermat switch block (nil = no fork, 0 = already on Fermat) @@ -106,6 +122,20 @@ type Config struct { // L1 address that declares the protocol versions, optional (Beta feature) ProtocolVersionsAddress common.Address `json:"protocol_versions_address,omitempty"` + + // L1 DataAvailabilityChallenge contract proxy address + DAChallengeAddress common.Address `json:"da_challenge_address,omitempty"` + + // DA challenge window value set on the DAC contract. Used in plasma mode + // to compute when a commitment can no longer be challenged. + DAChallengeWindow uint64 `json:"da_challenge_window"` + + // DA resolve window value set on the DAC contract. Used in plasma mode + // to compute when a challenge expires and trigger a reorg if needed. + DAResolveWindow uint64 `json:"da_resolve_window"` + + // UsePlasma is activated when the chain is in plasma mode. + UsePlasma bool `json:"use_plasma"` } // ValidateL1Config checks L1 config variables for errors. @@ -124,13 +154,16 @@ func (cfg *Config) ValidateL1Config(ctx context.Context, client L1Client) error } // ValidateL2Config checks L2 config variables for errors. -func (cfg *Config) ValidateL2Config(ctx context.Context, client L2Client) error { +func (cfg *Config) ValidateL2Config(ctx context.Context, client L2Client, skipL2GenesisBlockHash bool) error { // Validate the L2 Client Chain ID if err := cfg.CheckL2ChainID(ctx, client); err != nil { return err } - // Validate the Rollup L2 Genesis Blockhash + // Validate the Rollup L2 Genesis Blockhash if requested. We skip this when doing EL sync + if skipL2GenesisBlockHash { + return nil + } if err := cfg.CheckL2GenesisBlockHash(ctx, client); err != nil { return err } @@ -270,11 +303,42 @@ func (cfg *Config) Check() error { if cfg.L2ChainID.Sign() < 1 { return ErrL2ChainIDNotPositive } + + if err := checkFork(cfg.RegolithTime, cfg.CanyonTime, "regolith", "canyon"); err != nil { + return err + } + if err := checkFork(cfg.CanyonTime, cfg.DeltaTime, "canyon", "delta"); err != nil { + return err + } + if err := checkFork(cfg.DeltaTime, cfg.EcotoneTime, "delta", "ecotone"); err != nil { + return err + } + if err := checkFork(cfg.EcotoneTime, cfg.FjordTime, "ecotone", "fjord"); err != nil { + return err + } + + return nil +} + +// checkFork checks that fork A is before or at the same time as fork B +func checkFork(a, b *uint64, aName, bName string) error { + if a == nil && b == nil { + return nil + } + if a == nil && b != nil { + return fmt.Errorf("fork %s set (to %d), but prior fork %s missing", bName, *b, aName) + } + if a != nil && b == nil { + return nil + } + if *a > *b { + return fmt.Errorf("fork %s set to %d, but prior fork %s has higher offset %d", bName, *b, aName, *a) + } return nil } func (c *Config) L1Signer() types.Signer { - return types.NewLondonSigner(c.L1ChainID) + return types.NewCancunSigner(c.L1ChainID) } // IsRegolith returns true if the Regolith hardfork is active at or past the given timestamp. @@ -287,8 +351,101 @@ func (c *Config) IsCanyon(timestamp uint64) bool { return c.CanyonTime != nil && timestamp >= *c.CanyonTime } -func (c *Config) IsSpanBatch(timestamp uint64) bool { - return c.SpanBatchTime != nil && timestamp >= *c.SpanBatchTime +// IsDelta returns true if the Delta hardfork is active at or past the given timestamp. +func (c *Config) IsDelta(timestamp uint64) bool { + return c.DeltaTime != nil && timestamp >= *c.DeltaTime +} + +// IsEcotone returns true if the Ecotone hardfork is active at or past the given timestamp. +func (c *Config) IsEcotone(timestamp uint64) bool { + return c.EcotoneTime != nil && timestamp >= *c.EcotoneTime +} + +// IsEcotoneActivationBlock returns whether the specified block is the first block subject to the +// Ecotone upgrade. Ecotone activation at genesis does not count. +func (c *Config) IsEcotoneActivationBlock(l2BlockTime uint64) bool { + return c.IsEcotone(l2BlockTime) && + l2BlockTime >= c.BlockTime && + !c.IsEcotone(l2BlockTime-c.BlockTime) +} + +// IsFjord returns true if the Fjord hardfork is active at or past the given timestamp. +func (c *Config) IsFjord(timestamp uint64) bool { + return c.FjordTime != nil && timestamp >= *c.FjordTime +} + +// IsInterop returns true if the Interop hardfork is active at or past the given timestamp. +func (c *Config) IsInterop(timestamp uint64) bool { + return c.InteropTime != nil && timestamp >= *c.InteropTime +} + +// ForkchoiceUpdatedVersion returns the EngineAPIMethod suitable for the chain hard fork version. +func (c *Config) ForkchoiceUpdatedVersion(attr *eth.PayloadAttributes) eth.EngineAPIMethod { + if attr == nil { + // Don't begin payload build process. + return eth.FCUV3 + } + ts := uint64(attr.Timestamp) + if c.IsEcotone(ts) { + // Cancun + return eth.FCUV3 + } else if c.IsCanyon(ts) { + // Shanghai + return eth.FCUV2 + } else { + // According to Ethereum engine API spec, we can use fcuV2 here, + // but upstream Geth v1.13.11 does not accept V2 before Shanghai. + return eth.FCUV1 + } +} + +// NewPayloadVersion returns the EngineAPIMethod suitable for the chain hard fork version. +func (c *Config) NewPayloadVersion(timestamp uint64) eth.EngineAPIMethod { + if c.IsEcotone(timestamp) { + // Cancun + return eth.NewPayloadV3 + } else { + return eth.NewPayloadV2 + } +} + +// GetPayloadVersion returns the EngineAPIMethod suitable for the chain hard fork version. +func (c *Config) GetPayloadVersion(timestamp uint64) eth.EngineAPIMethod { + if c.IsEcotone(timestamp) { + // Cancun + return eth.GetPayloadV3 + } else { + return eth.GetPayloadV2 + } +} + +// PlasmaConfig validates and returns the plasma config from the rollup config. +func (c *Config) PlasmaConfig() (plasma.Config, error) { + if c.DAChallengeAddress == (common.Address{}) { + return plasma.Config{}, fmt.Errorf("missing DAChallengeAddress") + } + if c.DAChallengeWindow == uint64(0) { + return plasma.Config{}, fmt.Errorf("missing DAChallengeWindow") + } + if c.DAResolveWindow == uint64(0) { + return plasma.Config{}, fmt.Errorf("missing DAResolveWindow") + } + return plasma.Config{ + DAChallengeContractAddress: c.DAChallengeAddress, + ChallengeWindow: c.DAChallengeWindow, + ResolveWindow: c.DAResolveWindow, + }, nil +} + +// SyncLookback computes the number of blocks to walk back in order to find the correct L1 origin. +// In plasma mode longest possible window is challenge + resolve windows. +func (c *Config) SyncLookback() uint64 { + if c.UsePlasma { + if win := (c.DAChallengeWindow + c.DAResolveWindow); win > c.SeqWindowSize { + return win + } + } + return c.SeqWindowSize } // IsFermat returns true if the Fermat hardfork is active at or past the given block. @@ -351,7 +508,11 @@ func (c *Config) Description(l2Chains map[string]string) string { banner += "Post-Bedrock Network Upgrades (timestamp based):\n" banner += fmt.Sprintf(" - Regolith: %s\n", fmtForkTimeOrUnset(c.RegolithTime)) banner += fmt.Sprintf(" - Canyon: %s\n", fmtForkTimeOrUnset(c.CanyonTime)) - banner += fmt.Sprintf(" - SpanBatch: %s\n", fmtForkTimeOrUnset(c.SpanBatchTime)) + banner += fmt.Sprintf(" - Delta: %s\n", fmtForkTimeOrUnset(c.DeltaTime)) + banner += fmt.Sprintf(" - Ecotone: %s\n", fmtForkTimeOrUnset(c.EcotoneTime)) + banner += fmt.Sprintf(" - Fjord: %s\n", fmtForkTimeOrUnset(c.FjordTime)) + banner += fmt.Sprintf(" - Interop: %s\n", fmtForkTimeOrUnset(c.InteropTime)) + banner += "OPBNB hard forks (block based):\n" banner += fmt.Sprintf(" - Fermat: #%-8v\n", c.Fermat) banner += "OPBNB hard forks (timestamp based):\n" @@ -384,8 +545,12 @@ func (c *Config) LogDescription(log log.Logger, l2Chains map[string]string) { "l2_block_number", c.Genesis.L2.Number, "l1_block_hash", c.Genesis.L1.Hash.String(), "l1_block_number", c.Genesis.L1.Number, "regolith_time", fmtForkTimeOrUnset(c.RegolithTime), "canyon_time", fmtForkTimeOrUnset(c.CanyonTime), - "span_batch_time", fmtForkTimeOrUnset(c.SpanBatchTime), - "fermat", c.Fermat, "snow_time", fmtForkTimeOrUnset(c.SnowTime), + "delta_time", fmtForkTimeOrUnset(c.DeltaTime), + "ecotone_time", fmtForkTimeOrUnset(c.EcotoneTime), + "fjord_time", fmtForkTimeOrUnset(c.FjordTime), + "interop_time", fmtForkTimeOrUnset(c.InteropTime), + "fermat", c.Fermat, + "snow_time", fmtForkTimeOrUnset(c.SnowTime), ) } diff --git a/op-node/rollup/types_test.go b/op-node/rollup/types_test.go index a2b037b1f7a2..8b06d3356fa7 100644 --- a/op-node/rollup/types_test.go +++ b/op-node/rollup/types_test.go @@ -219,7 +219,7 @@ func TestValidateL2Config(t *testing.T) { config.Genesis.L2.Number = 100 config.Genesis.L2.Hash = [32]byte{0x01} mockClient := mockL2Client{chainID: big.NewInt(100), Hash: common.Hash{0x01}} - err := config.ValidateL2Config(context.TODO(), &mockClient) + err := config.ValidateL2Config(context.TODO(), &mockClient, false) assert.NoError(t, err) } @@ -229,10 +229,10 @@ func TestValidateL2ConfigInvalidChainIdFails(t *testing.T) { config.Genesis.L2.Number = 100 config.Genesis.L2.Hash = [32]byte{0x01} mockClient := mockL2Client{chainID: big.NewInt(100), Hash: common.Hash{0x01}} - err := config.ValidateL2Config(context.TODO(), &mockClient) + err := config.ValidateL2Config(context.TODO(), &mockClient, false) assert.Error(t, err) config.L2ChainID = big.NewInt(99) - err = config.ValidateL2Config(context.TODO(), &mockClient) + err = config.ValidateL2Config(context.TODO(), &mockClient, false) assert.Error(t, err) } @@ -242,13 +242,26 @@ func TestValidateL2ConfigInvalidGenesisHashFails(t *testing.T) { config.Genesis.L2.Number = 100 config.Genesis.L2.Hash = [32]byte{0x00} mockClient := mockL2Client{chainID: big.NewInt(100), Hash: common.Hash{0x01}} - err := config.ValidateL2Config(context.TODO(), &mockClient) + err := config.ValidateL2Config(context.TODO(), &mockClient, false) assert.Error(t, err) config.Genesis.L2.Hash = [32]byte{0x02} - err = config.ValidateL2Config(context.TODO(), &mockClient) + err = config.ValidateL2Config(context.TODO(), &mockClient, false) assert.Error(t, err) } +func TestValidateL2ConfigInvalidGenesisHashSkippedWhenRequested(t *testing.T) { + config := randConfig() + config.L2ChainID = big.NewInt(100) + config.Genesis.L2.Number = 100 + config.Genesis.L2.Hash = [32]byte{0x00} + mockClient := mockL2Client{chainID: big.NewInt(100), Hash: common.Hash{0x01}} + err := config.ValidateL2Config(context.TODO(), &mockClient, true) + assert.NoError(t, err) + config.Genesis.L2.Hash = [32]byte{0x02} + err = config.ValidateL2Config(context.TODO(), &mockClient, true) + assert.NoError(t, err) +} + func TestCheckL2ChainID(t *testing.T) { config := randConfig() config.L2ChainID = big.NewInt(100) @@ -395,6 +408,54 @@ func TestConfig_Check(t *testing.T) { assert.Same(t, err, test.expectedErr) }) } + + forkTests := []struct { + name string + modifier func(cfg *Config) + expectedErr error + }{ + { + name: "PriorForkMissing", + modifier: func(cfg *Config) { + ecotoneTime := uint64(1) + cfg.EcotoneTime = &ecotoneTime + }, + expectedErr: fmt.Errorf("fork ecotone set (to 1), but prior fork delta missing"), + }, + { + name: "PriorForkHasHigherOffset", + modifier: func(cfg *Config) { + regolithTime := uint64(2) + canyonTime := uint64(1) + cfg.RegolithTime = ®olithTime + cfg.CanyonTime = &canyonTime + }, + expectedErr: fmt.Errorf("fork canyon set to 1, but prior fork regolith has higher offset 2"), + }, + { + name: "PriorForkOK", + modifier: func(cfg *Config) { + regolithTime := uint64(1) + canyonTime := uint64(2) + deltaTime := uint64(3) + ecotoneTime := uint64(4) + cfg.RegolithTime = ®olithTime + cfg.CanyonTime = &canyonTime + cfg.DeltaTime = &deltaTime + cfg.EcotoneTime = &ecotoneTime + }, + expectedErr: nil, + }, + } + + for _, test := range forkTests { + t.Run(test.name, func(t *testing.T) { + cfg := randConfig() + test.modifier(cfg) + err := cfg.Check() + assert.Equal(t, err, test.expectedErr) + }) + } } func TestTimestampForBlock(t *testing.T) { @@ -447,3 +508,118 @@ func TestTimestampForBlock(t *testing.T) { } } + +func TestForkchoiceUpdatedVersion(t *testing.T) { + config := randConfig() + tests := []struct { + name string + canyonTime uint64 + ecotoneTime uint64 + attrs *eth.PayloadAttributes + expectedMethod eth.EngineAPIMethod + }{ + { + name: "NoAttrs", + canyonTime: 10, + ecotoneTime: 20, + attrs: nil, + expectedMethod: eth.FCUV3, + }, + { + name: "BeforeCanyon", + canyonTime: 10, + ecotoneTime: 20, + attrs: ð.PayloadAttributes{Timestamp: 5}, + expectedMethod: eth.FCUV1, + }, + { + name: "Canyon", + canyonTime: 10, + ecotoneTime: 20, + attrs: ð.PayloadAttributes{Timestamp: 15}, + expectedMethod: eth.FCUV2, + }, + { + name: "Ecotone", + canyonTime: 10, + ecotoneTime: 20, + attrs: ð.PayloadAttributes{Timestamp: 25}, + expectedMethod: eth.FCUV3, + }, + } + + for _, test := range tests { + test := test + t.Run(fmt.Sprintf("TestForkchoiceUpdatedVersion_%s", test.name), func(t *testing.T) { + config.CanyonTime = &test.canyonTime + config.EcotoneTime = &test.ecotoneTime + assert.Equal(t, config.ForkchoiceUpdatedVersion(test.attrs), test.expectedMethod) + }) + } +} + +func TestNewPayloadVersion(t *testing.T) { + config := randConfig() + canyonTime := uint64(0) + config.CanyonTime = &canyonTime + tests := []struct { + name string + ecotoneTime uint64 + payloadTime uint64 + expectedMethod eth.EngineAPIMethod + }{ + { + name: "BeforeEcotone", + ecotoneTime: 10, + payloadTime: 5, + expectedMethod: eth.NewPayloadV2, + }, + { + name: "Ecotone", + ecotoneTime: 10, + payloadTime: 15, + expectedMethod: eth.NewPayloadV3, + }, + } + + for _, test := range tests { + test := test + t.Run(fmt.Sprintf("TestNewPayloadVersion_%s", test.name), func(t *testing.T) { + config.EcotoneTime = &test.ecotoneTime + assert.Equal(t, config.NewPayloadVersion(test.payloadTime), test.expectedMethod) + }) + } +} + +func TestGetPayloadVersion(t *testing.T) { + config := randConfig() + canyonTime := uint64(0) + config.CanyonTime = &canyonTime + tests := []struct { + name string + ecotoneTime uint64 + payloadTime uint64 + expectedMethod eth.EngineAPIMethod + }{ + { + name: "BeforeEcotone", + ecotoneTime: 10, + payloadTime: 5, + expectedMethod: eth.GetPayloadV2, + }, + { + name: "Ecotone", + ecotoneTime: 10, + payloadTime: 15, + expectedMethod: eth.GetPayloadV3, + }, + } + + for _, test := range tests { + test := test + t.Run(fmt.Sprintf("TestGetPayloadVersion_%s", test.name), func(t *testing.T) { + config.EcotoneTime = &test.ecotoneTime + assert.Equal(t, config.GetPayloadVersion(test.payloadTime), test.expectedMethod) + }) + } +} diff --git a/op-node/service.go b/op-node/service.go index 5a8f419cf1bf..dc38981e6f7b 100644 --- a/op-node/service.go +++ b/op-node/service.go @@ -3,19 +3,20 @@ package opnode import ( "crypto/rand" "encoding/json" + "errors" "fmt" "io" "os" "strings" "github.com/ethereum-optimism/optimism/op-node/chaincfg" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + plasma "github.com/ethereum-optimism/optimism/op-plasma" + "github.com/ethereum-optimism/optimism/op-service/oppprof" "github.com/ethereum-optimism/optimism/op-service/sources" - "github.com/urfave/cli/v2" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/op-node/flags" "github.com/ethereum-optimism/optimism/op-node/node" @@ -23,6 +24,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/driver" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + opflags "github.com/ethereum-optimism/optimism/op-service/flags" ) // NewConfig creates a Config from the provided flags or environment variables. @@ -31,7 +33,7 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { return nil, err } - rollupConfig, err := NewRollupConfig(log, ctx) + rollupConfig, err := NewRollupConfigFromCLI(log, ctx) if err != nil { return nil, err } @@ -62,9 +64,10 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { return nil, fmt.Errorf("failed to load l2 endpoints info: %w", err) } - l2SyncEndpoint := NewL2SyncEndpointConfig(ctx) - - syncConfig := NewSyncConfig(ctx) + syncConfig, err := NewSyncConfig(ctx, log) + if err != nil { + return nil, fmt.Errorf("failed to create the sync config: %w", err) + } haltOption := ctx.String(flags.RollupHalt.Name) if haltOption == "none" { @@ -74,9 +77,9 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { cfg := &node.Config{ L1: l1Endpoint, L2: l2Endpoint, - L2Sync: l2SyncEndpoint, Rollup: *rollupConfig, Driver: *driverConfig, + Beacon: NewBeaconEndpointConfig(ctx), RPC: node.RPCConfig{ ListenAddr: ctx.String(flags.RPCListenAddr.Name), ListenPort: ctx.Int(flags.RPCListenPort.Name), @@ -87,11 +90,7 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { ListenAddr: ctx.String(flags.MetricsAddrFlag.Name), ListenPort: ctx.Int(flags.MetricsPortFlag.Name), }, - Pprof: oppprof.CLIConfig{ - Enabled: ctx.Bool(flags.PprofEnabledFlag.Name), - ListenAddr: ctx.String(flags.PprofAddrFlag.Name), - ListenPort: ctx.Int(flags.PprofPortFlag.Name), - }, + Pprof: oppprof.ReadCLIConfig(ctx), P2P: p2pConfig, P2PSigner: p2pSignerSetup, L1EpochPollInterval: ctx.Duration(flags.L1EpochPollIntervalFlag.Name), @@ -102,21 +101,43 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { URL: ctx.String(flags.HeartbeatURLFlag.Name), }, ConfigPersistence: configPersistence, + SafeDBPath: ctx.String(flags.SafeDBPath.Name), Sync: *syncConfig, RollupHalt: haltOption, RethDBPath: ctx.String(flags.L1RethDBPath.Name), + + ConductorEnabled: ctx.Bool(flags.ConductorEnabledFlag.Name), + ConductorRpc: ctx.String(flags.ConductorRpcFlag.Name), + ConductorRpcTimeout: ctx.Duration(flags.ConductorRpcTimeoutFlag.Name), + + Plasma: plasma.ReadCLIConfig(ctx), } if err := cfg.LoadPersisted(log); err != nil { return nil, fmt.Errorf("failed to load driver config: %w", err) } + // conductor controls the sequencer state + if cfg.ConductorEnabled { + cfg.Driver.SequencerStopped = true + } + if err := cfg.Check(); err != nil { return nil, err } return cfg, nil } +func NewBeaconEndpointConfig(ctx *cli.Context) node.L1BeaconEndpointSetup { + return &node.L1BeaconEndpointConfig{ + BeaconAddr: ctx.String(flags.BeaconAddr.Name), + BeaconHeader: ctx.String(flags.BeaconHeader.Name), + BeaconArchiverAddr: ctx.String(flags.BeaconArchiverAddr.Name), + BeaconCheckIgnore: ctx.Bool(flags.BeaconCheckIgnore.Name), + BeaconFetchAllSidecars: ctx.Bool(flags.BeaconFetchAllSidecars.Name), + } +} + func NewL1EndpointConfig(ctx *cli.Context) *node.L1EndpointConfig { return &node.L1EndpointConfig{ L1NodeAddr: ctx.String(flags.L1NodeAddr.Name), @@ -125,6 +146,7 @@ func NewL1EndpointConfig(ctx *cli.Context) *node.L1EndpointConfig { RateLimit: ctx.Float64(flags.L1RPCRateLimit.Name), BatchSize: ctx.Int(flags.L1RPCMaxBatchSize.Name), HttpPollInterval: ctx.Duration(flags.L1HTTPPollInterval.Name), + MaxConcurrency: ctx.Int(flags.L1RPCMaxConcurrency.Name), } } @@ -147,7 +169,7 @@ func NewL2EndpointConfig(ctx *cli.Context, log log.Logger) (*node.L2EndpointConf if _, err := io.ReadFull(rand.Reader, secret[:]); err != nil { return nil, fmt.Errorf("failed to generate jwt secret: %w", err) } - if err := os.WriteFile(fileName, []byte(hexutil.Encode(secret[:])), 0600); err != nil { + if err := os.WriteFile(fileName, []byte(hexutil.Encode(secret[:])), 0o600); err != nil { return nil, err } } @@ -158,15 +180,6 @@ func NewL2EndpointConfig(ctx *cli.Context, log log.Logger) (*node.L2EndpointConf }, nil } -// NewL2SyncEndpointConfig returns a pointer to a L2SyncEndpointConfig if the -// flag is set, otherwise nil. -func NewL2SyncEndpointConfig(ctx *cli.Context) *node.L2SyncEndpointConfig { - return &node.L2SyncEndpointConfig{ - L2NodeAddr: ctx.String(flags.BackupL2UnsafeSyncRPC.Name), - TrustRPC: ctx.Bool(flags.BackupL2UnsafeSyncRPCTrustRPC.Name), - } -} - func NewConfigPersistence(ctx *cli.Context) node.ConfigPersistence { stateFile := ctx.String(flags.RPCAdminPersistence.Name) if stateFile == "" { @@ -186,12 +199,21 @@ func NewDriverConfig(ctx *cli.Context) *driver.Config { } } -func NewRollupConfig(log log.Logger, ctx *cli.Context) (*rollup.Config, error) { - network := ctx.String(flags.Network.Name) - rollupConfigPath := ctx.String(flags.RollupConfig.Name) +func NewRollupConfigFromCLI(log log.Logger, ctx *cli.Context) (*rollup.Config, error) { + network := ctx.String(opflags.NetworkFlagName) + rollupConfigPath := ctx.String(opflags.RollupConfigFlagName) if ctx.Bool(flags.BetaExtraNetworks.Name) { log.Warn("The beta.extra-networks flag is deprecated and can be omitted safely.") } + rollupConfig, err := NewRollupConfig(log, network, rollupConfigPath) + if err != nil { + return nil, err + } + applyOverrides(ctx, rollupConfig) + return rollupConfig, nil +} + +func NewRollupConfig(log log.Logger, network string, rollupConfigPath string) (*rollup.Config, error) { if network != "" { if rollupConfigPath != "" { log.Error(`Cannot configure network and rollup-config at the same time. @@ -203,10 +225,6 @@ Conflicting configuration is deprecated, and will stop the op-node from starting if err != nil { return nil, err } - if ctx.IsSet(flags.CanyonOverrideFlag.Name) { - canyon := ctx.Uint64(flags.CanyonOverrideFlag.Name) - config.CanyonTime = &canyon - } return &config, nil } @@ -220,11 +238,6 @@ Conflicting configuration is deprecated, and will stop the op-node from starting if err := json.NewDecoder(file).Decode(&rollupConfig); err != nil { return nil, fmt.Errorf("failed to decode rollup config: %w", err) } - if ctx.IsSet(flags.CanyonOverrideFlag.Name) { - canyon := ctx.Uint64(flags.CanyonOverrideFlag.Name) - rollupConfig.CanyonTime = &canyon - } - if rollupConfig.L2ChainID == nil { return nil, fmt.Errorf("l2 chain ID must not be nil") } @@ -233,33 +246,56 @@ Conflicting configuration is deprecated, and will stop the op-node from starting return &rollupConfig, nil } - if ctx.IsSet(flags.CanyonOverrideFlag.Name) { - canyon := ctx.Uint64(flags.CanyonOverrideFlag.Name) - presetRollupConfig.CanyonTime = &canyon - } log.Warn("using preset rollup config of", rollupConfig.L2ChainID, "overwrite rollup file") return &presetRollupConfig, nil } +func applyOverrides(ctx *cli.Context, rollupConfig *rollup.Config) { + if ctx.IsSet(opflags.CanyonOverrideFlagName) { + canyon := ctx.Uint64(opflags.CanyonOverrideFlagName) + rollupConfig.CanyonTime = &canyon + } + if ctx.IsSet(opflags.DeltaOverrideFlagName) { + delta := ctx.Uint64(opflags.DeltaOverrideFlagName) + rollupConfig.DeltaTime = &delta + } + if ctx.IsSet(opflags.EcotoneOverrideFlagName) { + ecotone := ctx.Uint64(opflags.EcotoneOverrideFlagName) + rollupConfig.EcotoneTime = &ecotone + } +} + func NewSnapshotLogger(ctx *cli.Context) (log.Logger, error) { snapshotFile := ctx.String(flags.SnapshotLog.Name) - handler := log.DiscardHandler() - if snapshotFile != "" { - var err error - handler, err = log.FileHandler(snapshotFile, log.JSONFormat()) - if err != nil { - return nil, err - } - handler = log.SyncHandler(handler) + if snapshotFile == "" { + return log.NewLogger(log.DiscardHandler()), nil } - logger := log.New() - logger.SetHandler(handler) - return logger, nil + + sf, err := os.OpenFile(snapshotFile, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + return nil, err + } + handler := log.JSONHandler(sf) + return log.NewLogger(handler), nil } -func NewSyncConfig(ctx *cli.Context) *sync.Config { - return &sync.Config{ - EngineSync: ctx.Bool(flags.L2EngineSyncEnabled.Name), +func NewSyncConfig(ctx *cli.Context, log log.Logger) (*sync.Config, error) { + if ctx.IsSet(flags.L2EngineSyncEnabled.Name) && ctx.IsSet(flags.SyncModeFlag.Name) { + return nil, errors.New("cannot set both --l2.engine-sync and --syncmode at the same time.") + } else if ctx.IsSet(flags.L2EngineSyncEnabled.Name) { + log.Error("l2.engine-sync is deprecated and will be removed in a future release. Use --syncmode=execution-layer instead.") + } + mode, err := sync.StringToMode(ctx.String(flags.SyncModeFlag.Name)) + if err != nil { + return nil, err + } + cfg := &sync.Config{ + SyncMode: mode, SkipSyncStartCheck: ctx.Bool(flags.SkipSyncStartCheck.Name), } + if ctx.Bool(flags.L2EngineSyncEnabled.Name) { + cfg.SyncMode = sync.ELSync + } + + return cfg, nil } diff --git a/op-node/withdrawals/utils.go b/op-node/withdrawals/utils.go index 52e59ca42142..057b56a29945 100644 --- a/op-node/withdrawals/utils.go +++ b/op-node/withdrawals/utils.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/ethclient/gethclient" "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-bindings/bindingspreview" "github.com/ethereum-optimism/optimism/op-bindings/predeploys" ) @@ -28,6 +29,10 @@ type ReceiptClient interface { TransactionReceipt(context.Context, common.Hash) (*types.Receipt, error) } +type BlockClient interface { + BlockByNumber(context.Context, *big.Int) (*types.Block, error) +} + // ProvenWithdrawalParameters is the set of parameters to pass to the ProveWithdrawalTransaction // and FinalizeWithdrawalTransaction functions type ProvenWithdrawalParameters struct { @@ -42,10 +47,32 @@ type ProvenWithdrawalParameters struct { WithdrawalProof [][]byte // List of trie nodes to prove L2 storage } -// ProveWithdrawalParameters queries L1 & L2 to generate all withdrawal parameters and proof necessary to prove a withdrawal on L1. +// ProveWithdrawalParameters calls ProveWithdrawalParametersForBlock with the most recent L2 output after the given header. +func ProveWithdrawalParameters(ctx context.Context, proofCl ProofClient, l2ReceiptCl ReceiptClient, l2BlockCl BlockClient, txHash common.Hash, header *types.Header, l2OutputOracleContract *bindings.L2OutputOracleCaller) (ProvenWithdrawalParameters, error) { + l2OutputIndex, err := l2OutputOracleContract.GetL2OutputIndexAfter(&bind.CallOpts{}, header.Number) + if err != nil { + return ProvenWithdrawalParameters{}, fmt.Errorf("failed to get l2OutputIndex: %w", err) + } + l2BlockNumber := header.Number + return ProveWithdrawalParametersForBlock(ctx, proofCl, l2ReceiptCl, l2BlockCl, txHash, l2BlockNumber, l2OutputIndex) +} + +// ProveWithdrawalParametersFPAC calls ProveWithdrawalParametersForBlock with the most recent L2 output after the latest game. +func ProveWithdrawalParametersFPAC(ctx context.Context, proofCl ProofClient, l2ReceiptCl ReceiptClient, l2BlockCl BlockClient, txHash common.Hash, disputeGameFactoryContract *bindings.DisputeGameFactoryCaller, optimismPortal2Contract *bindingspreview.OptimismPortal2Caller) (ProvenWithdrawalParameters, error) { + latestGame, err := FindLatestGame(ctx, disputeGameFactoryContract, optimismPortal2Contract) + if err != nil { + return ProvenWithdrawalParameters{}, fmt.Errorf("failed to find latest game: %w", err) + } + + l2BlockNumber := new(big.Int).SetBytes(latestGame.ExtraData[0:32]) + l2OutputIndex := latestGame.Index + return ProveWithdrawalParametersForBlock(ctx, proofCl, l2ReceiptCl, l2BlockCl, txHash, l2BlockNumber, l2OutputIndex) +} + +// ProveWithdrawalParametersForBlock queries L1 & L2 to generate all withdrawal parameters and proof necessary to prove a withdrawal on L1. // The header provided is very important. It should be a block (timestamp) for which there is a submitted output in the L2 Output Oracle // contract. If not, the withdrawal will fail as it the storage proof cannot be verified if there is no submitted state root. -func ProveWithdrawalParameters(ctx context.Context, proofCl ProofClient, l2ReceiptCl ReceiptClient, txHash common.Hash, header *types.Header, l2OutputOracleContract *bindings.L2OutputOracleCaller) (ProvenWithdrawalParameters, error) { +func ProveWithdrawalParametersForBlock(ctx context.Context, proofCl ProofClient, l2ReceiptCl ReceiptClient, l2BlockCl BlockClient, txHash common.Hash, l2BlockNumber, l2OutputIndex *big.Int) (ProvenWithdrawalParameters, error) { // Transaction receipt receipt, err := l2ReceiptCl.TransactionReceipt(ctx, txHash) if err != nil { @@ -65,18 +92,14 @@ func ProveWithdrawalParameters(ctx context.Context, proofCl ProofClient, l2Recei return ProvenWithdrawalParameters{}, err } slot := StorageSlotOfWithdrawalHash(withdrawalHash) - p, err := proofCl.GetProof(ctx, predeploys.L2ToL1MessagePasserAddr, []string{slot.String()}, header.Number) - if err != nil { - return ProvenWithdrawalParameters{}, err - } - // Fetch the L2OutputIndex from the L2 Output Oracle caller (on L1) - l2OutputIndex, err := l2OutputOracleContract.GetL2OutputIndexAfter(&bind.CallOpts{}, header.Number) + // Fetch the block from the L2 node + l2Block, err := l2BlockCl.BlockByNumber(ctx, l2BlockNumber) if err != nil { - return ProvenWithdrawalParameters{}, fmt.Errorf("failed to get l2OutputIndex: %w", err) + return ProvenWithdrawalParameters{}, fmt.Errorf("failed to get l2Block: %w", err) } - // TODO: Could skip this step, but it's nice to double check it - err = VerifyProof(header.Root, p) + + p, err := proofCl.GetProof(ctx, predeploys.L2ToL1MessagePasserAddr, []string{slot.String()}, l2Block.Number()) if err != nil { return ProvenWithdrawalParameters{}, err } @@ -84,6 +107,11 @@ func ProveWithdrawalParameters(ctx context.Context, proofCl ProofClient, l2Recei return ProvenWithdrawalParameters{}, errors.New("invalid amount of storage proofs") } + err = VerifyProof(l2Block.Root(), p) + if err != nil { + return ProvenWithdrawalParameters{}, err + } + // Encode it as expected by the contract trieNodes := make([][]byte, len(p.StorageProof[0].Proof)) for i, s := range p.StorageProof[0].Proof { @@ -100,14 +128,42 @@ func ProveWithdrawalParameters(ctx context.Context, proofCl ProofClient, l2Recei Data: ev.Data, OutputRootProof: bindings.TypesOutputRootProof{ Version: [32]byte{}, // Empty for version 1 - StateRoot: header.Root, + StateRoot: l2Block.Root(), MessagePasserStorageRoot: p.StorageHash, - LatestBlockhash: header.Hash(), + LatestBlockhash: l2Block.Hash(), }, WithdrawalProof: trieNodes, }, nil } +// FindLatestGame finds the latest game in the DisputeGameFactory contract. +func FindLatestGame(ctx context.Context, disputeGameFactoryContract *bindings.DisputeGameFactoryCaller, optimismPortal2Contract *bindingspreview.OptimismPortal2Caller) (*bindings.IDisputeGameFactoryGameSearchResult, error) { + respectedGameType, err := optimismPortal2Contract.RespectedGameType(&bind.CallOpts{}) + if err != nil { + return nil, fmt.Errorf("failed to get respected game type: %w", err) + } + + gameCount, err := disputeGameFactoryContract.GameCount(&bind.CallOpts{}) + if err != nil { + return nil, fmt.Errorf("failed to get game count: %w", err) + } + if gameCount.Cmp(common.Big0) == 0 { + return nil, errors.New("no games") + } + + searchStart := new(big.Int).Sub(gameCount, common.Big1) + latestGames, err := disputeGameFactoryContract.FindLatestGames(&bind.CallOpts{}, respectedGameType, searchStart, common.Big1) + if err != nil { + return nil, fmt.Errorf("failed to get latest games: %w", err) + } + if len(latestGames) == 0 { + return nil, errors.New("no latest games") + } + + latestGame := latestGames[0] + return &latestGame, nil +} + // Standard ABI types copied from golang ABI tests var ( Uint256Type, _ = abi.NewType("uint256", "", nil) diff --git a/op-plasma/cli.go b/op-plasma/cli.go new file mode 100644 index 000000000000..92164bd5041d --- /dev/null +++ b/op-plasma/cli.go @@ -0,0 +1,73 @@ +package plasma + +import ( + "fmt" + "net/url" + + "github.com/urfave/cli/v2" +) + +const ( + EnabledFlagName = "plasma.enabled" + DaServerAddressFlagName = "plasma.da-server" + VerifyOnReadFlagName = "plasma.verify-on-read" +) + +func plasmaEnv(envprefix, v string) []string { + return []string{envprefix + "_PLASMA_" + v} +} + +func CLIFlags(envPrefix string, category string) []cli.Flag { + return []cli.Flag{ + &cli.BoolFlag{ + Name: EnabledFlagName, + Usage: "Enable plasma mode", + Value: false, + EnvVars: plasmaEnv(envPrefix, "ENABLED"), + Category: category, + }, + &cli.StringFlag{ + Name: DaServerAddressFlagName, + Usage: "HTTP address of a DA Server", + EnvVars: plasmaEnv(envPrefix, "DA_SERVER"), + Category: category, + }, + &cli.BoolFlag{ + Name: VerifyOnReadFlagName, + Usage: "Verify input data matches the commitments from the DA storage service", + Value: true, + EnvVars: plasmaEnv(envPrefix, "VERIFY_ON_READ"), + Category: category, + }, + } +} + +type CLIConfig struct { + Enabled bool + DAServerURL string + VerifyOnRead bool +} + +func (c CLIConfig) Check() error { + if c.Enabled { + if c.DAServerURL == "" { + return fmt.Errorf("DA server URL is required when plasma da is enabled") + } + if _, err := url.Parse(c.DAServerURL); err != nil { + return fmt.Errorf("DA server URL is invalid: %w", err) + } + } + return nil +} + +func (c CLIConfig) NewDAClient() *DAClient { + return &DAClient{url: c.DAServerURL, verify: c.VerifyOnRead} +} + +func ReadCLIConfig(c *cli.Context) CLIConfig { + return CLIConfig{ + Enabled: c.Bool(EnabledFlagName), + DAServerURL: c.String(DaServerAddressFlagName), + VerifyOnRead: c.Bool(VerifyOnReadFlagName), + } +} diff --git a/op-plasma/commitment.go b/op-plasma/commitment.go new file mode 100644 index 000000000000..6f45bd4f8429 --- /dev/null +++ b/op-plasma/commitment.go @@ -0,0 +1,61 @@ +package plasma + +import ( + "bytes" + "errors" + + "github.com/ethereum/go-ethereum/crypto" +) + +// ErrInvalidCommitment is returned when the commitment cannot be parsed into a known commitment type. +var ErrInvalidCommitment = errors.New("invalid commitment") + +// ErrCommitmentMismatch is returned when the commitment does not match the given input. +var ErrCommitmentMismatch = errors.New("commitment mismatch") + +// CommitmentType is the commitment type prefix. +type CommitmentType byte + +// KeccakCommitmentType is the default commitment type for the DA storage. +const Keccak256CommitmentType CommitmentType = 0 + +// Keccak256Commitment is the default commitment type for op-plasma. +type Keccak256Commitment []byte + +// Encode adds a commitment type prefix self describing the commitment. +func (c Keccak256Commitment) Encode() []byte { + return append([]byte{byte(Keccak256CommitmentType)}, c...) +} + +// TxData adds an extra version byte to signal it's a commitment. +func (c Keccak256Commitment) TxData() []byte { + return append([]byte{TxDataVersion1}, c.Encode()...) +} + +// Verify checks if the commitment matches the given input. +func (c Keccak256Commitment) Verify(input []byte) error { + if !bytes.Equal(c, crypto.Keccak256(input)) { + return ErrCommitmentMismatch + } + return nil +} + +// Keccak256 creates a new commitment from the given input. +func Keccak256(input []byte) Keccak256Commitment { + return Keccak256Commitment(crypto.Keccak256(input)) +} + +// DecodeKeccak256 validates and casts the commitment into a Keccak256Commitment. +func DecodeKeccak256(commitment []byte) (Keccak256Commitment, error) { + if len(commitment) == 0 { + return nil, ErrInvalidCommitment + } + if commitment[0] != byte(Keccak256CommitmentType) { + return nil, ErrInvalidCommitment + } + c := commitment[1:] + if len(c) != 32 { + return nil, ErrInvalidCommitment + } + return c, nil +} diff --git a/op-plasma/daclient.go b/op-plasma/daclient.go new file mode 100644 index 000000000000..e1c03509f69a --- /dev/null +++ b/op-plasma/daclient.go @@ -0,0 +1,83 @@ +package plasma + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "net/http" +) + +// ErrNotFound is returned when the server could not find the input. +var ErrNotFound = errors.New("not found") + +// ErrInvalidInput is returned when the input is not valid for posting to the DA storage. +var ErrInvalidInput = errors.New("invalid input") + +// DAClient is an HTTP client to communicate with a DA storage service. +// It creates commitments and retrieves input data + verifies if needed. +// Currently only supports Keccak256 commitments but may be extended eventually. +type DAClient struct { + url string + // VerifyOnRead sets the client to verify the commitment on read. + // SHOULD enable if the storage service is not trusted. + verify bool +} + +func NewDAClient(url string, verify bool) *DAClient { + return &DAClient{url, verify} +} + +// GetInput returns the input data for the given encoded commitment bytes. +func (c *DAClient) GetInput(ctx context.Context, comm Keccak256Commitment) ([]byte, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/get/0x%x", c.url, comm.Encode()), nil) + if err != nil { + return nil, fmt.Errorf("failed to create HTTP request: %w", err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode == http.StatusNotFound { + return nil, ErrNotFound + } + defer resp.Body.Close() + input, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if c.verify { + if err := comm.Verify(input); err != nil { + return nil, err + } + + } + return input, nil +} + +// SetInput sets the input data and returns the keccak256 hash commitment. +func (c *DAClient) SetInput(ctx context.Context, img []byte) (Keccak256Commitment, error) { + if len(img) == 0 { + return nil, ErrInvalidInput + } + comm := Keccak256(img) + // encode with commitment type prefix + key := comm.Encode() + body := bytes.NewReader(img) + url := fmt.Sprintf("%s/put/0x%x", c.url, key) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, body) + if err != nil { + return nil, fmt.Errorf("failed to create HTTP request: %w", err) + } + req.Header.Set("Content-Type", "application/octet-stream") + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to store preimage: %v", resp.StatusCode) + } + return comm, nil +} diff --git a/op-plasma/daclient_test.go b/op-plasma/daclient_test.go new file mode 100644 index 000000000000..f605cda761ad --- /dev/null +++ b/op-plasma/daclient_test.go @@ -0,0 +1,115 @@ +package plasma + +import ( + "context" + "io" + "math/rand" + "net/http" + "net/http/httptest" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestDAClient(t *testing.T) { + store := memorydb.New() + logger := testlog.Logger(t, log.LevelDebug) + + ctx := context.Background() + + mux := http.NewServeMux() + mux.Handle("/get/", http.StripPrefix("/get/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + logger.Debug("GET", "url", r.URL) + + comm, err := hexutil.Decode(r.URL.String()) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + + input, err := store.Get(comm) + if err != nil { + w.WriteHeader(http.StatusNotFound) + return + } + if _, err := w.Write(input); err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + }))) + mux.Handle("/put/", http.StripPrefix("/put/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + logger.Debug("PUT", "url", r.URL) + + input, err := io.ReadAll(r.Body) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + comm, err := hexutil.Decode(r.URL.String()) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + if err := store.Put(comm, input); err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + if _, err := w.Write(comm); err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + }))) + + tsrv := httptest.NewServer(mux) + + cfg := CLIConfig{ + Enabled: true, + DAServerURL: tsrv.URL, + VerifyOnRead: true, + } + require.NoError(t, cfg.Check()) + + client := cfg.NewDAClient() + + rng := rand.New(rand.NewSource(1234)) + + input := RandomData(rng, 2000) + + comm, err := client.SetInput(ctx, input) + require.NoError(t, err) + + require.Equal(t, comm, Keccak256(input)) + + stored, err := client.GetInput(ctx, comm) + require.NoError(t, err) + + require.Equal(t, input, stored) + + // set a bad commitment in the store + require.NoError(t, store.Put(comm.Encode(), []byte("bad data"))) + + _, err = client.GetInput(ctx, comm) + require.ErrorIs(t, err, ErrCommitmentMismatch) + + // test not found error + comm = Keccak256(RandomData(rng, 32)) + _, err = client.GetInput(ctx, comm) + require.ErrorIs(t, err, ErrNotFound) + + // test storing bad data + _, err = client.SetInput(ctx, []byte{}) + require.ErrorIs(t, err, ErrInvalidInput) + + // server not responsive + tsrv.Close() + _, err = client.SetInput(ctx, input) + require.Error(t, err) + + _, err = client.GetInput(ctx, Keccak256(input)) + require.Error(t, err) +} diff --git a/op-plasma/damgr.go b/op-plasma/damgr.go new file mode 100644 index 000000000000..3ecc2af7a7a6 --- /dev/null +++ b/op-plasma/damgr.go @@ -0,0 +1,425 @@ +package plasma + +import ( + "context" + "errors" + "fmt" + "io" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +// ErrPendingChallenge is returned when data is not available but can still be challenged/resolved +// so derivation should halt temporarily. +var ErrPendingChallenge = errors.New("not found, pending challenge") + +// ErrExpiredChallenge is returned when a challenge was not resolved and derivation should skip this input. +var ErrExpiredChallenge = errors.New("challenge expired") + +// ErrMissingPastWindow is returned when the input data is MIA and cannot be challenged. +// This is a protocol fatal error. +var ErrMissingPastWindow = errors.New("data missing past window") + +// ErrInvalidChallenge is returned when a challenge event does is decoded but does not +// relate to the actual chain commitments. +var ErrInvalidChallenge = errors.New("invalid challenge") + +// L1Fetcher is the required interface for syncing the DA challenge contract state. +type L1Fetcher interface { + InfoAndTxsByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, types.Transactions, error) + FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) + L1BlockRefByNumber(context.Context, uint64) (eth.L1BlockRef, error) +} + +// DAStorage interface for calling the DA storage server. +type DAStorage interface { + GetInput(ctx context.Context, key Keccak256Commitment) ([]byte, error) + SetInput(ctx context.Context, img []byte) (Keccak256Commitment, error) +} + +// HeadSignalFn is the callback function to accept head-signals without a context. +type HeadSignalFn func(eth.L1BlockRef) + +// Config is the relevant subset of rollup config for plasma DA. +type Config struct { + // Required for filtering contract events + DAChallengeContractAddress common.Address + // The number of l1 blocks after the input is committed during which one can challenge. + ChallengeWindow uint64 + // The number of l1 blocks after a commitment is challenged during which one can resolve. + ResolveWindow uint64 +} + +type DA struct { + log log.Logger + cfg Config + metrics Metricer + + storage DAStorage + + // the DA state keeps track of all the commitments and their challenge status. + state *State + + // the latest l1 block we synced challenge contract events from + origin eth.BlockID + // the latest recorded finalized head as per the challenge contract + finalizedHead eth.L1BlockRef + // the latest recorded finalized head as per the l1 finalization signal + l1FinalizedHead eth.L1BlockRef + // flag the reset function we are resetting because of an expired challenge + resetting bool + + finalizedHeadSignalFunc HeadSignalFn +} + +// NewPlasmaDA creates a new PlasmaDA instance with the given log and CLIConfig. +func NewPlasmaDA(log log.Logger, cli CLIConfig, cfg Config, metrics Metricer) *DA { + return NewPlasmaDAWithStorage(log, cfg, cli.NewDAClient(), metrics) +} + +// NewPlasmaDAWithStorage creates a new PlasmaDA instance with the given log and DAStorage interface. +func NewPlasmaDAWithStorage(log log.Logger, cfg Config, storage DAStorage, metrics Metricer) *DA { + return &DA{ + log: log, + cfg: cfg, + storage: storage, + metrics: metrics, + state: NewState(log, metrics), + } +} + +// NewPlasmaWithState creates a plasma storage from initial state used for testing in isolation. +// We pass the L1Fetcher to each method so it is kept in sync with the conf depth of the pipeline. +func NewPlasmaDAWithState(log log.Logger, cfg Config, storage DAStorage, metrics Metricer, state *State) *DA { + return &DA{ + log: log, + cfg: cfg, + storage: storage, + metrics: metrics, + state: state, + } +} + +// OnFinalizedHeadSignal sets the callback function to be called when the finalized head is updated. +// This will signal to the engine queue that will set the proper L2 block as finalized. +func (d *DA) OnFinalizedHeadSignal(f HeadSignalFn) { + d.finalizedHeadSignalFunc = f +} + +// Finalize takes the L1 finality signal, compares the plasma finalized block and forwards the finality +// signal to the engine queue based on whichever is most behind. +func (d *DA) Finalize(l1Finalized eth.L1BlockRef) { + ref := d.finalizedHead + d.log.Info("received l1 finalized signal, forwarding to engine queue", "l1", l1Finalized, "plasma", ref) + // if the l1 finalized head is behind it is the finalized head + if l1Finalized.Number < d.finalizedHead.Number { + ref = l1Finalized + } + // prune finalized state + d.state.Prune(ref.Number) + + if d.finalizedHeadSignalFunc == nil { + d.log.Warn("finalized head signal function not set") + return + } + + // signal the engine queue + d.finalizedHeadSignalFunc(ref) +} + +// LookAhead increments the challenges origin and process the new block if it exists. +// It is used when the derivation pipeline stalls due to missing data and we need to continue +// syncing challenge events until the challenge is resolved or expires. +func (d *DA) LookAhead(ctx context.Context, l1 L1Fetcher) error { + blkRef, err := l1.L1BlockRefByNumber(ctx, d.origin.Number+1) + // temporary error, will do a backoff + if err != nil { + return err + } + return d.AdvanceL1Origin(ctx, l1, blkRef.ID()) +} + +// Reset the challenge event derivation origin in case of L1 reorg +func (d *DA) Reset(ctx context.Context, base eth.L1BlockRef, baseCfg eth.SystemConfig) error { + // resetting due to expired challenge, do not clear state. + // If the DA source returns ErrReset, the pipeline is forced to reset by the rollup driver. + // In that case the Reset function will be called immediately, BEFORE the pipeline can + // call any further stage to step. Thus the state will NOT be cleared if the reset originates + // from this stage of the pipeline. + if d.resetting { + d.resetting = false + } else { + // resetting due to L1 reorg, clear state + d.origin = base.ID() + d.state.Reset() + } + return io.EOF +} + +// GetInput returns the input data for the given commitment bytes. blockNumber is required to lookup +// the challenge status in the DataAvailabilityChallenge L1 contract. +func (d *DA) GetInput(ctx context.Context, l1 L1Fetcher, comm Keccak256Commitment, blockId eth.BlockID) (eth.Data, error) { + // If the challenge head is ahead in the case of a pipeline reset or stall, we might have synced a + // challenge event for this commitment. Otherwise we mark the commitment as part of the canonical + // chain so potential future challenge events can be selected. + ch := d.state.GetOrTrackChallenge(comm.Encode(), blockId.Number, d.cfg.ChallengeWindow) + + // Fetch the input from the DA storage. + data, err := d.storage.GetInput(ctx, comm) + + // data is not found in storage but may be available if the challenge was resolved. + notFound := errors.Is(ErrNotFound, err) + + if err != nil && !notFound { + d.log.Error("failed to get preimage", "err", err) + // the storage client request failed for some other reason + // in which case derivation pipeline should be retried + return nil, err + } + + switch ch.challengeStatus { + case ChallengeActive: + if d.isExpired(ch.expiresAt) { + // this challenge has expired, this input must be skipped + return nil, ErrExpiredChallenge + } else if notFound { + // data is missing and a challenge is active, we must wait for the challenge to resolve + // hence we continue syncing new origins to sync the new challenge events. + if err := d.LookAhead(ctx, l1); err != nil { + return nil, err + } + return nil, ErrPendingChallenge + } + case ChallengeExpired: + // challenge was marked as expired, skip + return nil, ErrExpiredChallenge + case ChallengeResolved: + // challenge was resolved, data is available in storage, return directly + if !notFound { + return data, nil + } + // data not found in storage, return from challenge resolved input + resolvedInput, err := d.state.GetResolvedInput(comm.Encode()) + if err != nil { + return nil, err + } + return resolvedInput, nil + default: + if notFound { + if d.isExpired(ch.expiresAt) { + // we're past the challenge window and the data is not available + return nil, ErrMissingPastWindow + } else { + // continue syncing challenges hoping it eventually is challenged and resolved + if err := d.LookAhead(ctx, l1); err != nil { + return nil, err + } + return nil, ErrPendingChallenge + } + } + } + + return data, nil +} + +// isExpired returns whether the given expiration block number is lower or equal to the current head +func (d *DA) isExpired(bn uint64) bool { + return d.origin.Number >= bn +} + +// AdvanceL1Origin syncs any challenge events included in the l1 block, expires any active challenges +// after the new resolveWindow, computes and signals the new finalized head and sets the l1 block +// as the new head for tracking challenges. If forwards an error if any new challenge have expired to +// trigger a derivation reset. +func (d *DA) AdvanceL1Origin(ctx context.Context, l1 L1Fetcher, block eth.BlockID) error { + // do not repeat for the same origin + if block.Number <= d.origin.Number { + return nil + } + // sync challenges for the given block ID + if err := d.LoadChallengeEvents(ctx, l1, block); err != nil { + return err + } + // advance challenge window, computing the finalized head + bn, err := d.state.ExpireChallenges(block.Number) + if err != nil { + // warn the reset function not to clear the state + d.resetting = true + return err + } + + // finalized head signal is called only when the finalized head number increases + // and the l1 finalized head ahead of the DA finalized head. + if bn > d.finalizedHead.Number { + ref, err := l1.L1BlockRefByNumber(ctx, bn) + if err != nil { + return err + } + d.metrics.RecordChallengesHead("finalized", bn) + + // keep track of finalized had so it can be picked up by the + // l1 finalization signal + d.finalizedHead = ref + } + d.origin = block + d.metrics.RecordChallengesHead("latest", d.origin.Number) + + d.log.Info("processed plasma l1 origin", "origin", block, "next-finalized", bn, "finalized", d.finalizedHead.Number, "l1-finalize", d.l1FinalizedHead.Number) + return nil +} + +// LoadChallengeEvents fetches the l1 block receipts and updates the challenge status +func (d *DA) LoadChallengeEvents(ctx context.Context, l1 L1Fetcher, block eth.BlockID) error { + // filter any challenge event logs in the block + logs, err := d.fetchChallengeLogs(ctx, l1, block) + if err != nil { + return err + } + + for _, log := range logs { + i := log.TxIndex + status, comm, err := d.decodeChallengeStatus(log) + if err != nil { + d.log.Error("failed to decode challenge event", "block", block.Number, "tx", i, "log", log.Index, "err", err) + continue + } + switch status { + case ChallengeResolved: + // cached with input resolution call so not expensive + _, txs, err := l1.InfoAndTxsByHash(ctx, block.Hash) + if err != nil { + d.log.Error("failed to fetch l1 block", "block", block.Number, "err", err) + continue + } + // avoid panic in black swan case of faulty rpc + if uint(len(txs)) <= i { + d.log.Error("tx/receipt mismatch in InfoAndTxsByHash") + continue + } + // select the transaction corresponding to the receipt + tx := txs[i] + // txs and receipts must be in the same order + if tx.Hash() != log.TxHash { + d.log.Error("tx hash mismatch", "block", block.Number, "txIdx", i, "log", log.Index, "txHash", tx.Hash(), "receiptTxHash", log.TxHash) + continue + } + // Decode the input from resolver tx calldata + input, err := DecodeResolvedInput(tx.Data()) + if err != nil { + d.log.Error("failed to decode resolved input", "block", block.Number, "txIdx", i, "err", err) + continue + } + if err := comm.Verify(input); err != nil { + d.log.Error("failed to verify commitment", "block", block.Number, "txIdx", i, "err", err) + continue + } + d.log.Debug("challenge resolved", "block", block, "txIdx", i) + d.state.SetResolvedChallenge(comm.Encode(), input, log.BlockNumber) + case ChallengeActive: + d.log.Info("detected new active challenge", "block", block) + d.state.SetActiveChallenge(comm.Encode(), log.BlockNumber, d.cfg.ResolveWindow) + default: + d.log.Warn("skipping unknown challenge status", "block", block.Number, "tx", i, "log", log.Index, "status", status) + } + } + return nil +} + +// fetchChallengeLogs returns logs for challenge events if any for the given block +func (d *DA) fetchChallengeLogs(ctx context.Context, l1 L1Fetcher, block eth.BlockID) ([]*types.Log, error) { //cached with deposits events call so not expensive + var logs []*types.Log + _, receipts, err := l1.FetchReceipts(ctx, block.Hash) + if err != nil { + return nil, err + } + d.log.Info("loading challenges", "epoch", block.Number, "numReceipts", len(receipts)) + for _, rec := range receipts { + // skip error logs + if rec.Status != types.ReceiptStatusSuccessful { + continue + } + for _, log := range rec.Logs { + if log.Address == d.cfg.DAChallengeContractAddress && len(log.Topics) > 0 && log.Topics[0] == ChallengeStatusEventABIHash { + logs = append(logs, log) + } + } + } + + return logs, nil +} + +// decodeChallengeStatus decodes and validates a challenge event from a transaction log, returning the associated commitment bytes. +func (d *DA) decodeChallengeStatus(log *types.Log) (ChallengeStatus, Keccak256Commitment, error) { + event, err := DecodeChallengeStatusEvent(log) + if err != nil { + return 0, nil, err + } + comm, err := DecodeKeccak256(event.ChallengedCommitment) + if err != nil { + return 0, nil, err + } + d.log.Debug("decoded challenge status event", "log", log, "event", event, "comm", fmt.Sprintf("%x", comm.Encode())) + + bn := event.ChallengedBlockNumber.Uint64() + // IsTracking just validates whether the commitment was challenged for the correct block number + // if it has been loaded from the batcher inbox before. Spam commitments will be tracked but + // ignored and evicted unless derivation encounters the commitment. + if !d.state.IsTracking(comm.Encode(), bn) { + return 0, nil, fmt.Errorf("%w: %x at block %d", ErrInvalidChallenge, comm.Encode(), bn) + } + return ChallengeStatus(event.Status), comm, nil +} + +var ( + ChallengeStatusEventName = "ChallengeStatusChanged" + ChallengeStatusEventABI = "ChallengeStatusChanged(uint256,bytes,uint8)" + ChallengeStatusEventABIHash = crypto.Keccak256Hash([]byte(ChallengeStatusEventABI)) +) + +// DecodeChallengeStatusEvent decodes the challenge status event from the log data and the indexed challenged +// hash and block number from the topics. +func DecodeChallengeStatusEvent(log *types.Log) (*bindings.DataAvailabilityChallengeChallengeStatusChanged, error) { + // abi lazy loaded, cached after decoded once + dacAbi, err := bindings.DataAvailabilityChallengeMetaData.GetAbi() + if err != nil { + return nil, err + } + var event bindings.DataAvailabilityChallengeChallengeStatusChanged + err = dacAbi.UnpackIntoInterface(&event, ChallengeStatusEventName, log.Data) + if err != nil { + return nil, err + } + var indexed abi.Arguments + for _, arg := range dacAbi.Events[ChallengeStatusEventName].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + if err := abi.ParseTopics(&event, indexed, log.Topics[1:]); err != nil { + return nil, err + } + return &event, nil +} + +// DecodeResolvedInput decodes the preimage bytes from the tx input data. +func DecodeResolvedInput(data []byte) ([]byte, error) { + dacAbi, _ := bindings.DataAvailabilityChallengeMetaData.GetAbi() + + args := make(map[string]interface{}) + err := dacAbi.Methods["resolve"].Inputs.UnpackIntoMap(args, data[4:]) + if err != nil { + return nil, err + } + rd, ok := args["resolveData"].([]byte) + if !ok || len(rd) == 0 { + return nil, fmt.Errorf("invalid resolve data") + } + return rd, nil +} diff --git a/op-plasma/damgr_test.go b/op-plasma/damgr_test.go new file mode 100644 index 000000000000..5a37badc19ca --- /dev/null +++ b/op-plasma/damgr_test.go @@ -0,0 +1,366 @@ +package plasma + +import ( + "context" + "math/big" + "math/rand" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func RandomData(rng *rand.Rand, size int) []byte { + out := make([]byte, size) + rng.Read(out) + return out +} + +// TestDAChallengeState is a simple test with small values to verify the finalized head logic +func TestDAChallengeState(t *testing.T) { + logger := testlog.Logger(t, log.LvlDebug) + + rng := rand.New(rand.NewSource(1234)) + state := NewState(logger, &NoopMetrics{}) + + i := uint64(1) + + challengeWindow := uint64(6) + resolveWindow := uint64(6) + + // track commitments in the first 10 blocks + for ; i < 10; i++ { + // this is akin to stepping the derivation pipeline through a range a blocks each with a commitment + state.SetInputCommitment(RandomData(rng, 32), i, challengeWindow) + } + + // blocks are finalized after the challenge window expires + bn, err := state.ExpireChallenges(10) + require.NoError(t, err) + // finalized head = 10 - 6 = 4 + require.Equal(t, uint64(4), bn) + + // track the next commitment and mark it as challenged + c := RandomData(rng, 32) + // add input commitment at block i = 10 + state.SetInputCommitment(c, 10, challengeWindow) + // i+4 is the block at which it was challenged + state.SetActiveChallenge(c, 14, resolveWindow) + + for j := i + 1; j < 18; j++ { + // continue walking the pipeline through some more blocks with commitments + state.SetInputCommitment(RandomData(rng, 32), j, challengeWindow) + } + + // finalized l1 origin should not extend past the resolve window + bn, err = state.ExpireChallenges(18) + require.NoError(t, err) + // finalized is active_challenge_block - 1 = 10 - 1 and cannot move until the challenge expires + require.Equal(t, uint64(9), bn) + + // walk past the resolve window + for j := uint64(18); j < 22; j++ { + state.SetInputCommitment(RandomData(rng, 32), j, challengeWindow) + } + + // no more active challenges, the finalized head can catch up to the challenge window + bn, err = state.ExpireChallenges(22) + require.ErrorIs(t, err, ErrReorgRequired) + // finalized head is now 22 - 6 = 16 + require.Equal(t, uint64(16), bn) + + // cleanup state we don't need anymore + state.Prune(22) + // now if we expire the challenges again, it won't request a reorg again + bn, err = state.ExpireChallenges(22) + require.NoError(t, err) + // finalized head hasn't moved + require.Equal(t, uint64(16), bn) + + // add one more commitment and challenge it + c = RandomData(rng, 32) + state.SetInputCommitment(c, 22, challengeWindow) + // challenge 3 blocks after + state.SetActiveChallenge(c, 25, resolveWindow) + + // exceed the challenge window with more commitments + for j := uint64(23); j < 30; j++ { + state.SetInputCommitment(RandomData(rng, 32), j, challengeWindow) + } + + // finalized head should not extend past the resolve window + bn, err = state.ExpireChallenges(30) + require.NoError(t, err) + // finalized head is stuck waiting for resolve window + require.Equal(t, uint64(21), bn) + + input := RandomData(rng, 100) + // resolve the challenge + state.SetResolvedChallenge(c, input, 30) + + // finalized head catches up + bn, err = state.ExpireChallenges(31) + require.NoError(t, err) + // finalized head is now 31 - 6 = 25 + require.Equal(t, uint64(25), bn) + + // the resolved input is also stored + storedInput, err := state.GetResolvedInput(c) + require.NoError(t, err) + require.Equal(t, input, storedInput) +} + +// TestExpireChallenges expires challenges and prunes the state for longer windows +// with commitments every 6 blocks. +func TestExpireChallenges(t *testing.T) { + logger := testlog.Logger(t, log.LvlDebug) + + rng := rand.New(rand.NewSource(1234)) + state := NewState(logger, &NoopMetrics{}) + + comms := make(map[uint64][]byte) + + i := uint64(3713854) + + var finalized uint64 + + challengeWindow := uint64(90) + resolveWindow := uint64(90) + + // increment new commitments every 6 blocks + for ; i < 3713948; i += 6 { + comm := RandomData(rng, 32) + comms[i] = comm + logger.Info("set commitment", "block", i) + cm := state.GetOrTrackChallenge(comm, i, challengeWindow) + require.NotNil(t, cm) + + bn, err := state.ExpireChallenges(i) + logger.Info("expire challenges", "finalized head", bn, "err", err) + + // only update finalized head if it has moved + if bn > finalized { + finalized = bn + // prune unused state + state.Prune(bn) + } + } + + // activate a couple of subsequent challenges + state.SetActiveChallenge(comms[3713926], 3713948, resolveWindow) + + state.SetActiveChallenge(comms[3713932], 3713950, resolveWindow) + + // continue incrementing commitments + for ; i < 3714038; i += 6 { + comm := RandomData(rng, 32) + comms[i] = comm + logger.Info("set commitment", "block", i) + cm := state.GetOrTrackChallenge(comm, i, challengeWindow) + require.NotNil(t, cm) + + bn, err := state.ExpireChallenges(i) + logger.Info("expire challenges", "expired", bn, "err", err) + + if bn > finalized { + finalized = bn + state.Prune(bn) + } + + } + + // finalized head does not move as it expires previously seen blocks + bn, err := state.ExpireChallenges(3714034) + require.NoError(t, err) + require.Equal(t, uint64(3713920), bn) + + bn, err = state.ExpireChallenges(3714035) + require.NoError(t, err) + require.Equal(t, uint64(3713920), bn) + + bn, err = state.ExpireChallenges(3714036) + require.NoError(t, err) + require.Equal(t, uint64(3713920), bn) + + bn, err = state.ExpireChallenges(3714037) + require.NoError(t, err) + require.Equal(t, uint64(3713920), bn) + + // lastly we get to the resolve window and trigger a reorg + _, err = state.ExpireChallenges(3714038) + require.ErrorIs(t, err, ErrReorgRequired) + + // this is simulating a pipeline reset where it walks back challenge + resolve window + for i := uint64(3713854); i < 3714044; i += 6 { + cm := state.GetOrTrackChallenge(comms[i], i, challengeWindow) + require.NotNil(t, cm) + + // check that the challenge status was updated to expired + if i == 3713926 { + require.Equal(t, ChallengeExpired, cm.challengeStatus) + } + } + + bn, err = state.ExpireChallenges(3714038) + require.NoError(t, err) + + // finalized at last + require.Equal(t, uint64(3713926), bn) +} + +func TestDAChallengeDetached(t *testing.T) { + logger := testlog.Logger(t, log.LvlDebug) + + rng := rand.New(rand.NewSource(1234)) + state := NewState(logger, &NoopMetrics{}) + + challengeWindow := uint64(6) + resolveWindow := uint64(6) + + c1 := RandomData(rng, 32) + c2 := RandomData(rng, 32) + + // c1 at bn1 is missing, pipeline stalls + state.GetOrTrackChallenge(c1, 1, challengeWindow) + + // c2 at bn2 is challenged at bn3 + require.True(t, state.IsTracking(c2, 2)) + state.SetActiveChallenge(c2, 3, resolveWindow) + + // c1 is finally challenged at bn5 + state.SetActiveChallenge(c1, 5, resolveWindow) + + // c2 expires but should not trigger a reset because we don't know if it's valid yet + bn, err := state.ExpireChallenges(10) + require.NoError(t, err) + require.Equal(t, uint64(0), bn) + + // c1 expires finally + bn, err = state.ExpireChallenges(11) + require.ErrorIs(t, err, ErrReorgRequired) + require.Equal(t, uint64(1), bn) + + // pruning finalized block is safe + state.Prune(bn) + + // pipeline discovers c2 + comm := state.GetOrTrackChallenge(c2, 2, challengeWindow) + // it is already marked as expired so it will be skipped without needing a reorg + require.Equal(t, ChallengeExpired, comm.challengeStatus) + + // later when we get to finalizing block 10 + margin, the pending challenge is safely pruned + state.Prune(210) + require.Equal(t, 0, len(state.expiredComms)) +} + +// cannot import from testutils at this time because of import cycle +type mockL1Fetcher struct { + mock.Mock +} + +func (m *mockL1Fetcher) InfoAndTxsByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, types.Transactions, error) { + out := m.Mock.Called(hash) + return out.Get(0).(eth.BlockInfo), out.Get(1).(types.Transactions), out.Error(2) +} + +func (m *mockL1Fetcher) ExpectInfoAndTxsByHash(hash common.Hash, info eth.BlockInfo, transactions types.Transactions, err error) { + m.Mock.On("InfoAndTxsByHash", hash).Once().Return(info, transactions, err) +} + +func (m *mockL1Fetcher) FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) { + out := m.Mock.Called(blockHash) + return *out.Get(0).(*eth.BlockInfo), out.Get(1).(types.Receipts), out.Error(2) +} + +func (m *mockL1Fetcher) ExpectFetchReceipts(hash common.Hash, info eth.BlockInfo, receipts types.Receipts, err error) { + m.Mock.On("FetchReceipts", hash).Once().Return(&info, receipts, err) +} + +func (m *mockL1Fetcher) L1BlockRefByNumber(ctx context.Context, num uint64) (eth.L1BlockRef, error) { + out := m.Mock.Called(num) + return out.Get(0).(eth.L1BlockRef), out.Error(1) +} + +func (m *mockL1Fetcher) ExpectL1BlockRefByNumber(num uint64, ref eth.L1BlockRef, err error) { + m.Mock.On("L1BlockRefByNumber", num).Once().Return(ref, err) +} + +func TestFilterInvalidBlockNumber(t *testing.T) { + logger := testlog.Logger(t, log.LevelDebug) + ctx := context.Background() + + l1F := &mockL1Fetcher{} + + storage := NewMockDAClient(logger) + + daddr := common.HexToAddress("0x978e3286eb805934215a88694d80b09aded68d90") + pcfg := Config{ + ChallengeWindow: 90, ResolveWindow: 90, DAChallengeContractAddress: daddr, + } + + bn := uint64(19) + bhash := common.HexToHash("0xd438144ffab918b1349e7cd06889c26800c26d8edc34d64f750e3e097166a09c") + + state := NewState(logger, &NoopMetrics{}) + + da := NewPlasmaDAWithState(logger, pcfg, storage, &NoopMetrics{}, state) + + receipts := types.Receipts{&types.Receipt{ + Type: 2, + Status: 1, + Logs: []*types.Log{ + { + BlockNumber: bn, + Address: daddr, + Topics: []common.Hash{ + common.HexToHash("0xa448afda7ea1e3a7a10fcab0c29fe9a9dd85791503bf0171f281521551c7ec05"), + }, + }, + { + BlockNumber: bn, + Address: daddr, + Topics: []common.Hash{ + common.HexToHash("0xc5d8c630ba2fdacb1db24c4599df78c7fb8cf97b5aecde34939597f6697bb1ad"), + common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000000e"), + }, + Data: common.FromHex("0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002100eed82c1026bdd0f23461dd6ca515ef677624e63e6fc0ff91e3672af8eddf579d00000000000000000000000000000000000000000000000000000000000000"), + }, + }, + BlockNumber: big.NewInt(int64(bn)), + }} + id := eth.BlockID{ + Number: bn, + Hash: bhash, + } + l1F.ExpectFetchReceipts(bhash, nil, receipts, nil) + + // we get 1 log successfully filtered as valid status updated contract event + logs, err := da.fetchChallengeLogs(ctx, l1F, id) + require.NoError(t, err) + require.Equal(t, len(logs), 1) + + // commitment is tracked but not canonical + status, comm, err := da.decodeChallengeStatus(logs[0]) + require.NoError(t, err) + + c, has := state.commsByKey[string(comm.Encode())] + require.True(t, has) + require.False(t, c.canonical) + + require.Equal(t, ChallengeActive, status) + // once tracked, set as active based on decoded status + state.SetActiveChallenge(comm.Encode(), bn, pcfg.ResolveWindow) + + // once we request it during derivation it becomes canonical + tracked := state.GetOrTrackChallenge(comm.Encode(), 14, pcfg.ChallengeWindow) + require.True(t, tracked.canonical) + + require.Equal(t, ChallengeActive, tracked.challengeStatus) + require.Equal(t, uint64(14), tracked.blockNumber) + require.Equal(t, bn+pcfg.ResolveWindow, tracked.expiresAt) +} diff --git a/op-plasma/damock.go b/op-plasma/damock.go new file mode 100644 index 000000000000..f21e80df25e0 --- /dev/null +++ b/op-plasma/damock.go @@ -0,0 +1,99 @@ +package plasma + +import ( + "context" + "errors" + "io" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ethereum/go-ethereum/log" +) + +// MockDAClient mocks a DA storage provider to avoid running an HTTP DA server +// in unit tests. +type MockDAClient struct { + store ethdb.KeyValueStore + log log.Logger +} + +func NewMockDAClient(log log.Logger) *MockDAClient { + return &MockDAClient{ + store: memorydb.New(), + log: log, + } +} + +func (c *MockDAClient) GetInput(ctx context.Context, key Keccak256Commitment) ([]byte, error) { + bytes, err := c.store.Get(key.Encode()) + if err != nil { + return nil, ErrNotFound + } + return bytes, nil +} + +func (c *MockDAClient) SetInput(ctx context.Context, data []byte) (Keccak256Commitment, error) { + key := Keccak256(data) + return key, c.store.Put(key.Encode(), data) +} + +func (c *MockDAClient) DeleteData(key []byte) error { + return c.store.Delete(key) +} + +type DAErrFaker struct { + Client *MockDAClient + + getInputErr error + setInputErr error +} + +func (f *DAErrFaker) GetInput(ctx context.Context, key Keccak256Commitment) ([]byte, error) { + if err := f.getInputErr; err != nil { + f.getInputErr = nil + return nil, err + } + return f.Client.GetInput(ctx, key) +} + +func (f *DAErrFaker) SetInput(ctx context.Context, data []byte) (Keccak256Commitment, error) { + if err := f.setInputErr; err != nil { + f.setInputErr = nil + return nil, err + } + return f.Client.SetInput(ctx, data) +} + +func (f *DAErrFaker) ActGetPreImageFail() { + f.getInputErr = errors.New("get input failed") +} + +func (f *DAErrFaker) ActSetPreImageFail() { + f.setInputErr = errors.New("set input failed") +} + +var Disabled = &PlasmaDisabled{} + +var ErrNotEnabled = errors.New("plasma not enabled") + +// PlasmaDisabled is a noop plasma DA implementation for stubbing. +type PlasmaDisabled struct{} + +func (d *PlasmaDisabled) GetInput(ctx context.Context, l1 L1Fetcher, commitment Keccak256Commitment, blockId eth.BlockID) (eth.Data, error) { + return nil, ErrNotEnabled +} + +func (d *PlasmaDisabled) Reset(ctx context.Context, base eth.L1BlockRef, baseCfg eth.SystemConfig) error { + return io.EOF +} + +func (d *PlasmaDisabled) Finalize(ref eth.L1BlockRef) { +} + +func (d *PlasmaDisabled) OnFinalizedHeadSignal(f HeadSignalFn) { +} + +func (d *PlasmaDisabled) AdvanceL1Origin(ctx context.Context, l1 L1Fetcher, blockId eth.BlockID) error { + return ErrNotEnabled +} diff --git a/op-plasma/dastate.go b/op-plasma/dastate.go new file mode 100644 index 000000000000..c6fee4800af9 --- /dev/null +++ b/op-plasma/dastate.go @@ -0,0 +1,228 @@ +package plasma + +import ( + "container/heap" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/log" +) + +// ErrReorgRequired is returned when a commitment was derived but for which the challenge expired. +// This requires a reorg to rederive without the input even if the input was previously available. +var ErrReorgRequired = errors.New("reorg required") + +type ChallengeStatus uint8 + +const ( + ChallengeUninitialized ChallengeStatus = iota + ChallengeActive + ChallengeResolved + ChallengeExpired +) + +// Commitment keeps track of the onchain state of an input commitment. +type Commitment struct { + key []byte // the encoded commitment + input []byte // the input itself if it was resolved onchain + expiresAt uint64 // represents the block number after which the commitment can no longer be challenged or if challenged no longer be resolved. + blockNumber uint64 // block where the commitment is included as calldata to the batcher inbox + challengeStatus ChallengeStatus // latest known challenge status + canonical bool // whether the commitment was derived as part of the canonical chain if canonical it will be in comms queue if not in the pendingComms queue. +} + +// CommQueue is a priority queue of commitments ordered by block number. +type CommQueue []*Commitment + +var _ heap.Interface = (*CommQueue)(nil) + +func (c CommQueue) Len() int { return len(c) } + +// we want the first item in the queue to have the lowest block number +func (c CommQueue) Less(i, j int) bool { + return c[i].blockNumber < c[j].blockNumber +} + +func (c CommQueue) Swap(i, j int) { + c[i], c[j] = c[j], c[i] +} + +func (c *CommQueue) Push(x any) { + *c = append(*c, x.(*Commitment)) +} + +func (c *CommQueue) Pop() any { + old := *c + n := len(old) + item := old[n-1] + old[n-1] = nil // avoid memory leak + *c = old[0 : n-1] + return item +} + +// State tracks the commitment and their challenges in order of l1 inclusion. +type State struct { + activeComms CommQueue + expiredComms CommQueue + commsByKey map[string]*Commitment + log log.Logger + metrics Metricer + finalized uint64 +} + +func NewState(log log.Logger, m Metricer) *State { + return &State{ + activeComms: make(CommQueue, 0), + expiredComms: make(CommQueue, 0), + commsByKey: make(map[string]*Commitment), + log: log, + metrics: m, + } +} + +// IsTracking returns whether we currently have a commitment for the given key. +// if the block number is mismatched we return false to ignore the challenge. +func (s *State) IsTracking(key []byte, bn uint64) bool { + if c, ok := s.commsByKey[string(key)]; ok { + return c.blockNumber == bn + } + // track the commitment knowing we may be in detached head and not have seen + // the commitment in the inbox yet. + s.TrackDetachedCommitment(key, bn) + return true +} + +// TrackDetachedCommitment is used for indexing challenges for commitments that have not yet +// been derived due to the derivation pipeline being stalled pending a commitment to be challenged. +// Memory usage is bound to L1 block space during the DA windows, so it is hard and expensive to spam. +// Note that the challenge status and expiration is updated separately after it is tracked. +func (s *State) TrackDetachedCommitment(key []byte, bn uint64) { + c := &Commitment{ + key: key, + expiresAt: bn, + blockNumber: bn, + canonical: false, + } + s.log.Debug("tracking detached commitment", "blockNumber", c.blockNumber, "commitment", fmt.Sprintf("%x", key)) + heap.Push(&s.activeComms, c) + s.commsByKey[string(key)] = c +} + +// SetActiveChallenge switches the state of a given commitment to active challenge. Noop if +// the commitment is not tracked as we don't want to track challenges for invalid commitments. +func (s *State) SetActiveChallenge(key []byte, challengedAt uint64, resolveWindow uint64) { + if c, ok := s.commsByKey[string(key)]; ok { + c.expiresAt = challengedAt + resolveWindow + c.challengeStatus = ChallengeActive + s.metrics.RecordActiveChallenge(c.blockNumber, challengedAt, key) + } +} + +// SetResolvedChallenge switches the state of a given commitment to resolved. Noop if +// the commitment is not tracked as we don't want to track challenges for invalid commitments. +// The input posted onchain is stored in the state for later retrieval. +func (s *State) SetResolvedChallenge(key []byte, input []byte, resolvedAt uint64) { + if c, ok := s.commsByKey[string(key)]; ok { + c.challengeStatus = ChallengeResolved + c.expiresAt = resolvedAt + c.input = input + s.metrics.RecordResolvedChallenge(key) + } +} + +// SetInputCommitment initializes a new commitment and adds it to the state. +// This is called when we see a commitment during derivation so we can refer to it later in +// challenges. +func (s *State) SetInputCommitment(key []byte, committedAt uint64, challengeWindow uint64) *Commitment { + c := &Commitment{ + key: key, + expiresAt: committedAt + challengeWindow, + blockNumber: committedAt, + canonical: true, + } + s.log.Debug("append commitment", "expiresAt", c.expiresAt, "blockNumber", c.blockNumber) + heap.Push(&s.activeComms, c) + s.commsByKey[string(key)] = c + + return c +} + +// GetOrTrackChallenge returns the commitment for the given key if it is already tracked, or +// initializes a new commitment and adds it to the state. +func (s *State) GetOrTrackChallenge(key []byte, bn uint64, challengeWindow uint64) *Commitment { + if c, ok := s.commsByKey[string(key)]; ok { + // commitments previously introduced by challenge events are marked as canonical + c.canonical = true + return c + } + return s.SetInputCommitment(key, bn, challengeWindow) +} + +// GetResolvedInput returns the input bytes if the commitment was resolved onchain. +func (s *State) GetResolvedInput(key []byte) ([]byte, error) { + if c, ok := s.commsByKey[string(key)]; ok { + return c.input, nil + } + return nil, errors.New("commitment not found") +} + +// ExpireChallenges walks back from the oldest commitment to find the latest l1 origin +// for which input data can no longer be challenged. It also marks any active challenges +// as expired based on the new latest l1 origin. If any active challenges are expired +// it returns an error to signal that a derivation pipeline reset is required. +func (s *State) ExpireChallenges(bn uint64) (uint64, error) { + var err error + for s.activeComms.Len() > 0 && s.activeComms[0].expiresAt <= bn && s.activeComms[0].blockNumber > s.finalized { + // move from the active to the expired queue + c := heap.Pop(&s.activeComms).(*Commitment) + heap.Push(&s.expiredComms, c) + + if c.canonical { + // advance finalized head only if the commitment was derived as part of the canonical chain + s.finalized = c.blockNumber + } + + // active mark as expired so it is skipped in the derivation pipeline + if c.challengeStatus == ChallengeActive { + c.challengeStatus = ChallengeExpired + + // only reorg if canonical. If the pipeline is behind, it will just + // get skipped once it catches up. If it is spam, it will be pruned + // with no effect. + if c.canonical { + err = ErrReorgRequired + s.metrics.RecordExpiredChallenge(c.key) + } + } + } + + return s.finalized, err +} + +// safely prune in case reset is deeper than the finalized l1 +const commPruneMargin = 200 + +// Prune removes commitments once they can no longer be challenged or resolved. +// the finalized head block number is passed so we can safely remove any commitments +// with finalized block numbers. +func (s *State) Prune(bn uint64) { + if bn > commPruneMargin { + bn -= commPruneMargin + } else { + bn = 0 + } + for s.expiredComms.Len() > 0 && s.expiredComms[0].blockNumber < bn { + c := heap.Pop(&s.expiredComms).(*Commitment) + s.log.Debug("prune commitment", "expiresAt", c.expiresAt, "blockNumber", c.blockNumber) + delete(s.commsByKey, string(c.key)) + } +} + +// In case of L1 reorg, state should be cleared so we can sync all the challenge events +// from scratch. +func (s *State) Reset() { + s.activeComms = s.activeComms[:0] + s.expiredComms = s.expiredComms[:0] + s.finalized = 0 + clear(s.commsByKey) +} diff --git a/op-plasma/metrics.go b/op-plasma/metrics.go new file mode 100644 index 000000000000..9843e91f3863 --- /dev/null +++ b/op-plasma/metrics.go @@ -0,0 +1,73 @@ +package plasma + +import ( + "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +type Metricer interface { + RecordActiveChallenge(commBlock uint64, startBlock uint64, hash []byte) + RecordResolvedChallenge(hash []byte) + RecordExpiredChallenge(hash []byte) + RecordChallengesHead(name string, num uint64) + RecordStorageError() +} + +type Metrics struct { + ChallengesStatus *prometheus.GaugeVec + ChallengesHead *prometheus.GaugeVec + + StorageErrors *metrics.Event +} + +var _ Metricer = (*Metrics)(nil) + +func MakeMetrics(ns string, factory metrics.Factory) *Metrics { + return &Metrics{ + ChallengesStatus: factory.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: ns, + Name: "challenges_status", + Help: "Gauge representing the status of challenges synced", + }, []string{"status"}), + ChallengesHead: factory.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: ns, + Name: "challenges_head", + Help: "Gauge representing the l1 heads of challenges synced", + }, []string{"type"}), + StorageErrors: metrics.NewEvent(factory, ns, "", "storage_errors", "errors when fetching or uploading to storage service"), + } +} + +func (m *Metrics) RecordChallenge(status string) { + m.ChallengesStatus.WithLabelValues(status).Inc() +} + +// RecordActiveChallenge records when a commitment is challenged including the block where the commitment +// is included, the block where the commitment was challenged and the commitment hash. +func (m *Metrics) RecordActiveChallenge(commBlock uint64, startBlock uint64, hash []byte) { + m.RecordChallenge("active") +} + +func (m *Metrics) RecordResolvedChallenge(hash []byte) { + m.RecordChallenge("resolved") +} + +func (m *Metrics) RecordExpiredChallenge(hash []byte) { + m.RecordChallenge("expired") +} + +func (m *Metrics) RecordStorageError() { + m.StorageErrors.Record() +} + +func (m *Metrics) RecordChallengesHead(name string, num uint64) { + m.ChallengesHead.WithLabelValues(name).Set(float64(num)) +} + +type NoopMetrics struct{} + +func (m *NoopMetrics) RecordActiveChallenge(commBlock uint64, startBlock uint64, hash []byte) {} +func (m *NoopMetrics) RecordResolvedChallenge(hash []byte) {} +func (m *NoopMetrics) RecordExpiredChallenge(hash []byte) {} +func (m *NoopMetrics) RecordChallengesHead(name string, num uint64) {} +func (m *NoopMetrics) RecordStorageError() {} diff --git a/op-plasma/params.go b/op-plasma/params.go new file mode 100644 index 000000000000..e176c207919a --- /dev/null +++ b/op-plasma/params.go @@ -0,0 +1,11 @@ +package plasma + +// Max input size ensures the canonical chain cannot include input batches too large to +// challenge in the Data Availability Challenge contract. Value in number of bytes. +// This value can only be changed in a hard fork. +const MaxInputSize = 130672 + +// TxDataVersion1 is the version number for batcher transactions containing +// plasma commitments. It should not collide with DerivationVersion which is still +// used downstream when parsing the frames. +const TxDataVersion1 = 1 diff --git a/op-preimage/README.md b/op-preimage/README.md index 57e59fdab3b2..2543303a7d2f 100644 --- a/op-preimage/README.md +++ b/op-preimage/README.md @@ -1,6 +1,6 @@ # op-preimage -`op-preimage` offers simple Go bindings to interact as client or sever over the Pre-image Oracle ABI. +`op-preimage` offers simple Go bindings to interact as client or server over the Pre-image Oracle ABI. Read more about the Preimage Oracle in the [specs](../specs/fault-proof.md). diff --git a/op-preimage/iface.go b/op-preimage/iface.go index 8ccb7b84a599..c1835c0797d0 100644 --- a/op-preimage/iface.go +++ b/op-preimage/iface.go @@ -34,6 +34,14 @@ const ( LocalKeyType KeyType = 1 // Keccak256KeyType is for keccak256 pre-images, for any global shared pre-images. Keccak256KeyType KeyType = 2 + // GlobalGenericKeyType is a reserved key type for generic global data. + GlobalGenericKeyType KeyType = 3 + // Sha256KeyType is for sha256 pre-images, for any global shared pre-images. + Sha256KeyType KeyType = 4 + // BlobKeyType is for blob point pre-images. + BlobKeyType KeyType = 5 + // PrecompileKeyType is for precompile result pre-images. + PrecompileKeyType KeyType = 6 ) // LocalIndexKey is a key local to the program, indexing a special program input. @@ -62,6 +70,57 @@ func (k Keccak256Key) TerminalString() string { return "0x" + hex.EncodeToString(k[:]) } +// Sha256Key wraps a sha256 hash to use it as a typed pre-image key.hash +type Sha256Key [32]byte + +func (k Sha256Key) PreimageKey() (out [32]byte) { + out = k + out[0] = byte(Sha256KeyType) + return +} + +func (k Sha256Key) String() string { + return "0x" + hex.EncodeToString(k[:]) +} + +func (k Sha256Key) TerminalString() string { + return "0x" + hex.EncodeToString(k[:]) +} + +// BlobKey is the hash of a blob commitment and `z` value to use as a preimage key for `y`. +type BlobKey [32]byte + +func (k BlobKey) PreimageKey() (out [32]byte) { + out = k + out[0] = byte(BlobKeyType) + return +} + +func (k BlobKey) String() string { + return "0x" + hex.EncodeToString(k[:]) +} + +func (k BlobKey) TerminalString() string { + return "0x" + hex.EncodeToString(k[:]) +} + +// PrecompileKey is the hash of precompile address and its input data +type PrecompileKey [32]byte + +func (k PrecompileKey) PreimageKey() (out [32]byte) { + out = k + out[0] = byte(PrecompileKeyType) + return +} + +func (k PrecompileKey) String() string { + return "0x" + hex.EncodeToString(k[:]) +} + +func (k PrecompileKey) TerminalString() string { + return "0x" + hex.EncodeToString(k[:]) +} + // Hint is an interface to enable any program type to function as a hint, // when passed to the Hinter interface, returning a string representation // of what data the host should prepare pre-images for. diff --git a/op-preimage/iface_test.go b/op-preimage/iface_test.go new file mode 100644 index 000000000000..b7eb05c98a93 --- /dev/null +++ b/op-preimage/iface_test.go @@ -0,0 +1,80 @@ +package preimage + +import ( + "encoding/binary" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestPreimageKeyTypes(t *testing.T) { + t.Run("LocalIndexKey", func(t *testing.T) { + actual := LocalIndexKey(0xFFFFFFFF) + + // PreimageKey encoding + expected := [32]byte{} + expected[0] = byte(LocalKeyType) + binary.BigEndian.PutUint64(expected[24:], 0xFFFFFFFF) + require.Equal(t, expected, actual.PreimageKey()) + }) + + t.Run("Keccak256Key", func(t *testing.T) { + fauxHash := [32]byte{} + fauxHash[31] = 0xFF + actual := Keccak256Key(fauxHash) + + // PreimageKey encoding + expected := [32]byte{} + expected[0] = byte(Keccak256KeyType) + expected[31] = 0xFF + require.Equal(t, expected, actual.PreimageKey()) + + // String encoding + require.Equal(t, "0x00000000000000000000000000000000000000000000000000000000000000ff", actual.String()) + }) + + t.Run("Sha256Key", func(t *testing.T) { + fauxHash := [32]byte{} + fauxHash[31] = 0xFF + actual := Sha256Key(fauxHash) + + // PreimageKey encoding + expected := [32]byte{} + expected[0] = byte(Sha256KeyType) + expected[31] = 0xFF + require.Equal(t, expected, actual.PreimageKey()) + + // String encoding + require.Equal(t, "0x00000000000000000000000000000000000000000000000000000000000000ff", actual.String()) + }) + + t.Run("BlobKey", func(t *testing.T) { + fauxHash := [32]byte{} + fauxHash[31] = 0xFF + actual := BlobKey(fauxHash) + + // PreimageKey encoding + expected := [32]byte{} + expected[0] = byte(BlobKeyType) + expected[31] = 0xFF + require.Equal(t, expected, actual.PreimageKey()) + + // String encoding + require.Equal(t, "0x00000000000000000000000000000000000000000000000000000000000000ff", actual.String()) + }) + + t.Run("KZGPointEvaluationKey", func(t *testing.T) { + fauxHash := [32]byte{} + fauxHash[31] = 0xFF + actual := PrecompileKey(fauxHash) + + // PreimageKey encoding + expected := [32]byte{} + expected[0] = byte(PrecompileKeyType) + expected[31] = 0xFF + require.Equal(t, expected, actual.PreimageKey()) + + // String encoding + require.Equal(t, "0x00000000000000000000000000000000000000000000000000000000000000ff", actual.String()) + }) +} diff --git a/op-preimage/verifier.go b/op-preimage/verifier.go new file mode 100644 index 000000000000..6623d02abe13 --- /dev/null +++ b/op-preimage/verifier.go @@ -0,0 +1,48 @@ +package preimage + +import ( + "crypto/sha256" + "errors" + "fmt" + "slices" +) + +var ( + ErrIncorrectData = errors.New("incorrect data") + ErrUnsupportedKeyType = errors.New("unsupported key type") +) + +// WithVerification wraps the supplied source to verify that the returned data is a valid pre-image for the key. +func WithVerification(source PreimageGetter) PreimageGetter { + return func(key [32]byte) ([]byte, error) { + data, err := source(key) + if err != nil { + return nil, err + } + + switch KeyType(key[0]) { + case LocalKeyType: + return data, nil + case Keccak256KeyType: + hash := Keccak256(data) + if !slices.Equal(hash[1:], key[1:]) { + return nil, fmt.Errorf("%w for key %v, hash: %v data: %x", ErrIncorrectData, key, hash, data) + } + return data, nil + case Sha256KeyType: + hash := sha256.Sum256(data) + if !slices.Equal(hash[1:], key[1:]) { + return nil, fmt.Errorf("%w for key %v, hash: %v data: %x", ErrIncorrectData, key, hash, data) + } + return data, nil + case BlobKeyType: + // Can't verify an individual field element without having a kzg proof + return data, nil + case PrecompileKeyType: + // Can't verify precompile result without knowing the input preimage + return data, nil + default: + return nil, fmt.Errorf("%w: %v", ErrUnsupportedKeyType, key[0]) + } + } +} diff --git a/op-preimage/verifier_test.go b/op-preimage/verifier_test.go new file mode 100644 index 000000000000..fb2c722c875c --- /dev/null +++ b/op-preimage/verifier_test.go @@ -0,0 +1,105 @@ +package preimage + +import ( + "crypto/sha256" + "errors" + "fmt" + "reflect" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestWithVerification(t *testing.T) { + validData := []byte{1, 2, 3, 4, 5, 6} + keccak256Key := Keccak256Key(Keccak256(validData)) + sha256Key := Sha256Key(sha256.Sum256(validData)) + anError := errors.New("boom") + + validKeys := []Key{keccak256Key, sha256Key} + + type testData struct { + name string + key Key + data []byte + err error + expectedErr error + expectedData []byte + } + tests := []testData{ + { + name: "LocalKey NoVerification", + key: LocalIndexKey(1), + data: []byte{4, 3, 5, 7, 3}, + expectedData: []byte{4, 3, 5, 7, 3}, + }, + { + name: "BlobKey NoVerification", + key: BlobKey([32]byte{1, 2, 3, 4}), + data: []byte{4, 3, 5, 7, 3}, + expectedData: []byte{4, 3, 5, 7, 3}, + }, + { + name: "KZGPointEvaluationKey NoVerification", + key: PrecompileKey([32]byte{1, 2, 3, 4}), + data: []byte{4, 3, 5, 7, 3}, + expectedData: []byte{4, 3, 5, 7, 3}, + }, + { + name: "UnknownKey", + key: invalidKey([32]byte{0xaa}), + data: []byte{}, + expectedErr: ErrUnsupportedKeyType, + }, + } + + for _, key := range validKeys { + name := reflect.TypeOf(key).Name() + tests = append(tests, + testData{ + name: fmt.Sprintf("%v-Valid", name), + key: key, + data: validData, + expectedData: validData, + }, + testData{ + name: fmt.Sprintf("%v-Error", name), + key: key, + data: validData, + err: anError, + expectedErr: anError, + }, + testData{ + name: fmt.Sprintf("%v-InvalidData", name), + key: key, + data: []byte{6, 7, 8}, + expectedErr: ErrIncorrectData, + }, + testData{ + name: fmt.Sprintf("%v-EmptyData", name), + key: key, + data: []byte{}, + expectedErr: ErrIncorrectData, + }) + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + source := WithVerification(func(key [32]byte) ([]byte, error) { + return test.data, test.err + }) + actual, err := source(test.key.PreimageKey()) + require.ErrorIs(t, err, test.expectedErr) + require.Equal(t, test.expectedData, actual) + }) + } +} + +type invalidKey [32]byte + +func (k invalidKey) PreimageKey() (out [32]byte) { + out = k // copy the source hash + out[0] = byte(254) // apply invalid prefix + return +} diff --git a/op-program/Dockerfile.repro b/op-program/Dockerfile.repro new file mode 100644 index 000000000000..7d9dfc807240 --- /dev/null +++ b/op-program/Dockerfile.repro @@ -0,0 +1,51 @@ +FROM golang:1.21.3-alpine3.18 as builder + +RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash + +COPY ./go.mod /app/go.mod +COPY ./go.sum /app/go.sum + +WORKDIR /app + +RUN echo "go mod cache: $(go env GOMODCACHE)" +RUN echo "go build cache: $(go env GOCACHE)" + +RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build go mod download + +COPY . /app + +# We avoid copying the full .git dir into the build for just some metadata. +# Instead, specify: +# --build-arg GIT_COMMIT=$(git rev-parse HEAD) +# --build-arg GIT_DATE=$(git show -s --format='%ct') +ARG GIT_COMMIT +ARG GIT_DATE + +ARG CANNON_VERSION=v0.0.0 +ARG OP_PROGRAM_VERSION=v0.0.0 + +ARG TARGETOS TARGETARCH + +# Build the cannon, op-program, and op-program-client.elf binaries. +RUN --mount=type=cache,target=/root/.cache/go-build cd cannon && make cannon \ + GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$CANNON_VERSION" +RUN --mount=type=cache,target=/root/.cache/go-build cd op-program && make op-program-host \ + GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_PROGRAM_VERSION" +RUN --mount=type=cache,target=/root/.cache/go-build cd op-program && make op-program-client-mips \ + GOOS=linux GOARCH=mips GOMIPS=softfloat GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_PROGRAM_VERSION" + +# Run the op-program-client.elf binary directly through cannon's load-elf subcommand. +RUN /app/cannon/bin/cannon load-elf --path /app/op-program/bin/op-program-client.elf --out /app/op-program/bin/prestate.json --meta "" + +# Generate the prestate proof containing the absolute pre-state hash. +RUN /app/cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input /app/op-program/bin/prestate.json --meta "" --proof-fmt '/app/op-program/bin/%d.json' --output "" +RUN mv /app/op-program/bin/0.json /app/op-program/bin/prestate-proof.json + +# Exports files to the specified output location. +# Writing files to host requires buildkit to be enabled. +# e.g. `BUILDKIT=1 docker build ...` +FROM scratch AS export-stage +COPY --from=builder /app/op-program/bin/op-program . +COPY --from=builder /app/op-program/bin/op-program-client.elf . +COPY --from=builder /app/op-program/bin/prestate.json . +COPY --from=builder /app/op-program/bin/prestate-proof.json . diff --git a/op-program/Makefile b/op-program/Makefile index 54db39d8e485..83912f6aab21 100644 --- a/op-program/Makefile +++ b/op-program/Makefile @@ -25,30 +25,62 @@ op-program-client-mips: # verify output with: readelf -h bin/op-program-client.elf # result is mips32, big endian, R3000 +reproducible-prestate: + @docker build --output ./bin/ --progress plain -f Dockerfile.repro ../ + @echo "Absolute prestate hash:" + @cat ./bin/prestate-proof.json | jq -r .pre +.PHONY: reproducible-prestate + clean: rm -rf bin "$(COMPAT_DIR)" test: go test -v ./... -verify-goerli: op-program-host op-program-client - env GO111MODULE=on go run ./verify/cmd/goerli.go --l1 $$L1URL --l2 $$L2URL +verify-sepolia: op-program-host op-program-client + env GO111MODULE=on go run ./verify/sepolia/cmd/sepolia.go --l1 $$SEPOLIA_L1URL --l1.beacon $$SEPOLIA_BEACON_URL --l2 $$SEPOLIA_L2URL --datadir /tmp/test-sepolia + +capture-mainnet-genesis: op-program-host op-program-client + rm -rf "$(COMPAT_DIR)/mainnet-genesis" "$(COMPAT_DIR)/mainnet-genesis.tar.bz" + env GO111MODULE=on go run ./verify/mainnet/cmd/mainnet.go --l1 $$MAINNET_L1URL --l1.beacon $$MAINNET_BEACON_URL --l2 $$MAINNET_L2URL --datadir "$(COMPAT_DIR)/mainnet-genesis" --l1.head "0x4903424f6cc2cfba7c2bf8c8f48ca46721c963fa64b411cfee3697b781e3e5f1" --l2.start "105235063" --l2.end "105235064" + tar jcf "$(COMPAT_DIR)/mainnet-genesis.tar.bz" -C "$(COMPAT_DIR)" mainnet-genesis + +capture-sepolia-delta: op-program-host op-program-client + rm -rf "$(COMPAT_DIR)/sepolia-delta" "$(COMPAT_DIR)/sepolia-delta.tar.bz" + env GO111MODULE=on go run ./verify/sepolia/cmd/sepolia.go --l1 $$SEPOLIA_L1URL --l1.beacon $$SEPOLIA_BEACON_URL --l2 $$SEPOLIA_L2URL --datadir "$(COMPAT_DIR)/sepolia-delta" --l1.head "0x935428728bcfcfeb2e5ba9175fd2890e52831dae221aa4d5dcffed8320edc001" --l2.start "8728200" --l2.end "8728320" + tar jcf "$(COMPAT_DIR)/sepolia-delta.tar.bz" -C "$(COMPAT_DIR)" sepolia-delta + +capture-sepolia-ecotone: op-program-host op-program-client + rm -rf "$(COMPAT_DIR)/sepolia-ecotone" "$(COMPAT_DIR)/sepolia-ecotone.tar.bz" + env GO111MODULE=on go run ./verify/sepolia/cmd/sepolia.go --l1 $$SEPOLIA_L1URL --l1.beacon $$SEPOLIA_BEACON_URL --l2 $$SEPOLIA_L2URL --datadir "$(COMPAT_DIR)/sepolia-ecotone" --l1.head "0x5d491a8c1e728a4e70720c09fefdaa083681a9421cd365af85220cf8bd4448a3" --l2.start "9205715" --l2.end "9205815" + tar jcf "$(COMPAT_DIR)/sepolia-ecotone.tar.bz" -C "$(COMPAT_DIR)" sepolia-ecotone -capture-goerli-verify: op-program-host op-program-client - rm -rf "$(COMPAT_DIR)/goerli" "$(COMPAT_DIR)/goerli.tar.bz" - env GO111MODULE=on go run ./verify/cmd/goerli.go --l1 $$L1URL --l2 $$L2URL --datadir "$(COMPAT_DIR)/goerli" - tar jcf "$(COMPAT_DIR)/goerli.tar.bz" -C "$(COMPAT_DIR)" goerli +capture-chain-test-data: capture-mainnet-genesis capture-sepolia-delta capture-sepolia-ecotone -capture-chain-test-data: capture-goerli-verify +verify-sepolia-delta: op-program-host op-program-client + ./scripts/run-compat.sh "sepolia-delta" -run-goerli-verify: op-program-host op-program-client - mkdir -p "$(COMPAT_DIR)" - curl -L -o "$(COMPAT_DIR)/goerli.tar.bz" https://github.com/ethereum-optimism/chain-test-data/releases/download/2023-10-11/goerli.tar.bz - tar jxf "$(COMPAT_DIR)/goerli.tar.bz" -C "$(COMPAT_DIR)" - ./bin/op-program `cat "$(COMPAT_DIR)/goerli/args.txt"` +verify-mainnet-genesis: op-program-host op-program-client + ./scripts/run-compat.sh "mainnet-genesis" + +verify-sepolia-ecotone: op-program-host op-program-client + ./scripts/run-compat.sh "sepolia-ecotone" + +verify-compat: verify-sepolia-delta verify-sepolia-ecotone verify-mainnet-genesis .PHONY: \ op-program \ + op-program-host \ + op-program-client \ + op-program-client-mips \ clean \ test \ - lint + capture-goerli-verify \ + verify-sepolia \ + capture-mainnet-genesis \ + capture-sepolia-delta \ + capture-sepolia-ecotone \ + capture-chain-test-data \ + run-goerli-verify \ + run-sepolia-verify \ + run-compat diff --git a/op-program/README.md b/op-program/README.md index 6a2283bac8b6..78c121457974 100644 --- a/op-program/README.md +++ b/op-program/README.md @@ -4,7 +4,7 @@ Implements a fault proof program that runs through the rollup state-transition t This verifiable output can then resolve a disputed output on L1. The program is designed such that it can be run in a deterministic way such that two invocations with the same input -data wil result in not only the same output, but the same program execution trace. This allows it to be run in an +data will result in not only the same output, but the same program execution trace. This allows it to be run in an on-chain VM as part of the dispute resolution process. ## Compiling @@ -25,15 +25,6 @@ To run op-program unit tests, from within the `op-program` directory run: make test ``` -## Lint - -To run the linter, from within the `op-program` directory run: -```shell -make lint -``` - -This requires having `golangci-lint` installed. - ## Running From within the `op-program` directory, options can be reviewed with: @@ -41,3 +32,23 @@ From within the `op-program` directory, options can be reviewed with: ```shell ./bin/op-program --help ``` + +## Generating the Absolute Prestate + +The absolute pre-state of the op-program can be generated by executing the makefile +`reproducible-prestate` target. Effectively, this builds a docker image specified +by [Dockerfile.repro](./Dockerfile.repro) pinned with the following dependencies: +- golang version `1.21.3` +- alpine `3.18` + +After running `make reproducible-prestate`, the following files can be found in +[./bin/](./bin/): +- [`op-program`](./bin/op-program) +- [`op-program-client.elf`](./bin/op-program-client.elf) +- [`prestate.json`](./bin/prestate.json) +- [`prestate-proof.json`](./bin/prestate-proof.json) + +The `prestate-proof.json` file is what contains the absolute pre-state hash under +the `.pre` key that is also used by the [contracts][ctb] deploy script. + +[ctb]: ../packages/contracts-bedrock/ diff --git a/op-program/client/cmd/main.go b/op-program/client/cmd/main.go index 822c48556b6e..d075083e5aa1 100644 --- a/op-program/client/cmd/main.go +++ b/op-program/client/cmd/main.go @@ -13,10 +13,10 @@ func main() { // Default to a machine parsable but relatively human friendly log format. // Don't do anything fancy to detect if color output is supported. logger := oplog.NewLogger(os.Stdout, oplog.CLIConfig{ - Level: log.LvlInfo, + Level: log.LevelInfo, Format: oplog.FormatLogFmt, Color: false, }) - oplog.SetGlobalLogHandler(logger.GetHandler()) + oplog.SetGlobalLogHandler(logger.Handler()) client.Main(logger) } diff --git a/op-program/client/driver/driver.go b/op-program/client/driver/driver.go index 95a3df751f32..95cba25037bb 100644 --- a/op-program/client/driver/driver.go +++ b/op-program/client/driver/driver.go @@ -7,40 +7,46 @@ import ( "io" "github.com/ethereum-optimism/optimism/op-node/metrics" + "github.com/ethereum-optimism/optimism/op-node/node/safedb" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + plasma "github.com/ethereum-optimism/optimism/op-plasma" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/log" ) -var ( - ErrClaimNotValid = errors.New("invalid claim") -) +var ErrClaimNotValid = errors.New("invalid claim") type Derivation interface { Step(ctx context.Context) error +} + +type EngineState interface { SafeL2Head() eth.L2BlockRef } type L2Source interface { derive.Engine - L2OutputRoot() (eth.Bytes32, error) + L2OutputRoot(uint64) (eth.Bytes32, error) } type Driver struct { logger log.Logger pipeline Derivation - l2OutputRoot func() (eth.Bytes32, error) + engine EngineState + l2OutputRoot func(uint64) (eth.Bytes32, error) targetBlockNum uint64 } -func NewDriver(logger log.Logger, cfg *rollup.Config, l1Source derive.L1Fetcher, l2Source L2Source, targetBlockNum uint64) *Driver { - pipeline := derive.NewDerivationPipeline(logger, cfg, l1Source, l2Source, metrics.NoopMetrics, &sync.Config{}) +func NewDriver(logger log.Logger, cfg *rollup.Config, l1Source derive.L1Fetcher, l1BlobsSource derive.L1BlobsFetcher, l2Source L2Source, targetBlockNum uint64) *Driver { + engine := derive.NewEngineController(l2Source, logger, metrics.NoopMetrics, cfg, sync.CLSync) + pipeline := derive.NewDerivationPipeline(logger, cfg, l1Source, l1BlobsSource, plasma.Disabled, l2Source, engine, metrics.NoopMetrics, &sync.Config{}, safedb.Disabled) pipeline.Reset() return &Driver{ logger: logger, pipeline: pipeline, + engine: engine, l2OutputRoot: l2Source.L2OutputRoot, targetBlockNum: targetBlockNum, } @@ -52,10 +58,10 @@ func NewDriver(logger log.Logger, cfg *rollup.Config, l1Source derive.L1Fetcher, // Returns a non-EOF error if the derivation failed func (d *Driver) Step(ctx context.Context) error { if err := d.pipeline.Step(ctx); errors.Is(err, io.EOF) { - d.logger.Info("Derivation complete: reached L1 head", "head", d.pipeline.SafeL2Head()) + d.logger.Info("Derivation complete: reached L1 head", "head", d.engine.SafeL2Head()) return io.EOF } else if errors.Is(err, derive.NotEnoughData) { - head := d.pipeline.SafeL2Head() + head := d.engine.SafeL2Head() if head.Number >= d.targetBlockNum { d.logger.Info("Derivation complete: reached L2 block", "head", head) return io.EOF @@ -74,15 +80,16 @@ func (d *Driver) Step(ctx context.Context) error { } func (d *Driver) SafeHead() eth.L2BlockRef { - return d.pipeline.SafeL2Head() + return d.engine.SafeL2Head() } -func (d *Driver) ValidateClaim(claimedOutputRoot eth.Bytes32) error { - outputRoot, err := d.l2OutputRoot() +func (d *Driver) ValidateClaim(l2ClaimBlockNum uint64, claimedOutputRoot eth.Bytes32) error { + l2Head := d.SafeHead() + outputRoot, err := d.l2OutputRoot(min(l2ClaimBlockNum, l2Head.Number)) if err != nil { return fmt.Errorf("calculate L2 output root: %w", err) } - d.logger.Info("Validating claim", "head", d.SafeHead(), "output", outputRoot, "claim", claimedOutputRoot) + d.logger.Info("Validating claim", "head", l2Head, "output", outputRoot, "claim", claimedOutputRoot) if claimedOutputRoot != outputRoot { return fmt.Errorf("%w: claim: %v actual: %v", ErrClaimNotValid, claimedOutputRoot, outputRoot) } diff --git a/op-program/client/driver/driver_test.go b/op-program/client/driver/driver_test.go index cc24c696cf84..03cda64101ff 100644 --- a/op-program/client/driver/driver_test.go +++ b/op-program/client/driver/driver_test.go @@ -73,29 +73,55 @@ func TestValidateClaim(t *testing.T) { t.Run("Valid", func(t *testing.T) { driver := createDriver(t, io.EOF) expected := eth.Bytes32{0x11} - driver.l2OutputRoot = func() (eth.Bytes32, error) { + driver.l2OutputRoot = func(_ uint64) (eth.Bytes32, error) { return expected, nil } - err := driver.ValidateClaim(expected) + err := driver.ValidateClaim(uint64(0), expected) require.NoError(t, err) }) + t.Run("Valid-PriorToSafeHead", func(t *testing.T) { + driver := createDriverWithNextBlock(t, io.EOF, 10) + expected := eth.Bytes32{0x11} + requestedOutputRoot := uint64(0) + driver.l2OutputRoot = func(blockNum uint64) (eth.Bytes32, error) { + requestedOutputRoot = blockNum + return expected, nil + } + err := driver.ValidateClaim(uint64(20), expected) + require.NoError(t, err) + require.Equal(t, uint64(10), requestedOutputRoot) + }) + t.Run("Invalid", func(t *testing.T) { driver := createDriver(t, io.EOF) - driver.l2OutputRoot = func() (eth.Bytes32, error) { + driver.l2OutputRoot = func(_ uint64) (eth.Bytes32, error) { return eth.Bytes32{0x22}, nil } - err := driver.ValidateClaim(eth.Bytes32{0x11}) + err := driver.ValidateClaim(uint64(0), eth.Bytes32{0x11}) + require.ErrorIs(t, err, ErrClaimNotValid) + }) + + t.Run("Invalid-PriorToSafeHead", func(t *testing.T) { + driver := createDriverWithNextBlock(t, io.EOF, 10) + expected := eth.Bytes32{0x11} + requestedOutputRoot := uint64(0) + driver.l2OutputRoot = func(blockNum uint64) (eth.Bytes32, error) { + requestedOutputRoot = blockNum + return expected, nil + } + err := driver.ValidateClaim(uint64(20), eth.Bytes32{0x55}) require.ErrorIs(t, err, ErrClaimNotValid) + require.Equal(t, uint64(10), requestedOutputRoot) }) t.Run("Error", func(t *testing.T) { driver := createDriver(t, io.EOF) expectedErr := errors.New("boom") - driver.l2OutputRoot = func() (eth.Bytes32, error) { + driver.l2OutputRoot = func(_ uint64) (eth.Bytes32, error) { return eth.Bytes32{}, expectedErr } - err := driver.ValidateClaim(eth.Bytes32{0x11}) + err := driver.ValidateClaim(uint64(0), eth.Bytes32{0x11}) require.ErrorIs(t, err, expectedErr) }) } @@ -107,8 +133,9 @@ func createDriver(t *testing.T, derivationResult error) *Driver { func createDriverWithNextBlock(t *testing.T, derivationResult error, nextBlockNum uint64) *Driver { derivation := &stubDerivation{nextErr: derivationResult, nextBlockNum: nextBlockNum} return &Driver{ - logger: testlog.Logger(t, log.LvlDebug), + logger: testlog.Logger(t, log.LevelDebug), pipeline: derivation, + engine: derivation, targetBlockNum: 1_000_000, } } diff --git a/op-program/client/l1/blob_fetcher.go b/op-program/client/l1/blob_fetcher.go new file mode 100644 index 000000000000..b41082e4d4d8 --- /dev/null +++ b/op-program/client/l1/blob_fetcher.go @@ -0,0 +1,36 @@ +package l1 + +import ( + "context" + "errors" + + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/log" +) + +var InvalidHashesLengthError = errors.New("invalid hashes length") + +type BlobFetcher struct { + logger log.Logger + oracle Oracle +} + +var _ = (*derive.L1BlobsFetcher)(nil) + +func NewBlobFetcher(logger log.Logger, oracle Oracle) *BlobFetcher { + return &BlobFetcher{ + logger: logger, + oracle: oracle, + } +} + +// GetBlobs fetches blobs that were confirmed in the given L1 block with the given indexed blob hashes. +func (b *BlobFetcher) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { + blobs := make([]*eth.Blob, len(hashes)) + for i := 0; i < len(hashes); i++ { + b.logger.Info("Fetching blob", "l1_ref", ref.Hash, "blob_versioned_hash", hashes[i].Hash, "index", hashes[i].Index) + blobs[i] = b.oracle.GetBlob(ref, hashes[i]) + } + return blobs, nil +} diff --git a/op-program/client/l1/cache.go b/op-program/client/l1/cache.go index ad45bbd40bd2..a73813ba0264 100644 --- a/op-program/client/l1/cache.go +++ b/op-program/client/l1/cache.go @@ -2,11 +2,13 @@ package l1 import ( "context" + "encoding/binary" "github.com/hashicorp/golang-lru/v2/simplelru" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum-optimism/optimism/op-service/eth" ) @@ -20,17 +22,28 @@ type CachingOracle struct { blocks *simplelru.LRU[common.Hash, eth.BlockInfo] txs *simplelru.LRU[common.Hash, types.Transactions] rcpts *simplelru.LRU[common.Hash, types.Receipts] + blobs *simplelru.LRU[common.Hash, *eth.Blob] + pcmps *simplelru.LRU[common.Hash, precompileResult] +} + +type precompileResult struct { + result []byte + ok bool } func NewCachingOracle(oracle Oracle) *CachingOracle { blockLRU, _ := simplelru.NewLRU[common.Hash, eth.BlockInfo](cacheSize, nil) txsLRU, _ := simplelru.NewLRU[common.Hash, types.Transactions](cacheSize, nil) rcptsLRU, _ := simplelru.NewLRU[common.Hash, types.Receipts](cacheSize, nil) + blobsLRU, _ := simplelru.NewLRU[common.Hash, *eth.Blob](cacheSize, nil) + pcmps, _ := simplelru.NewLRU[common.Hash, precompileResult](cacheSize, nil) return &CachingOracle{ oracle: oracle, blocks: blockLRU, txs: txsLRU, rcpts: rcptsLRU, + blobs: blobsLRU, + pcmps: pcmps, } } @@ -66,6 +79,33 @@ func (o *CachingOracle) ReceiptsByBlockHash(blockHash common.Hash) (eth.BlockInf return block, rcpts } +func (o *CachingOracle) GetBlob(ref eth.L1BlockRef, blobHash eth.IndexedBlobHash) *eth.Blob { + // Create a 32 byte hash key by hashing `blobHash.Hash ++ ref.Time ++ blobHash.Index` + hashBuf := make([]byte, 48) + copy(hashBuf[0:32], blobHash.Hash[:]) + binary.BigEndian.PutUint64(hashBuf[32:], ref.Time) + binary.BigEndian.PutUint64(hashBuf[40:], blobHash.Index) + cacheKey := crypto.Keccak256Hash(hashBuf) + + blob, ok := o.blobs.Get(cacheKey) + if ok { + return blob + } + blob = o.oracle.GetBlob(ref, blobHash) + o.blobs.Add(cacheKey, blob) + return blob +} + +func (o *CachingOracle) Precompile(address common.Address, input []byte) ([]byte, bool) { + cacheKey := crypto.Keccak256Hash(append(address.Bytes(), input...)) + if val, ok := o.pcmps.Get(cacheKey); ok { + return val.result, val.ok + } + res, ok := o.oracle.Precompile(address, input) + o.pcmps.Add(cacheKey, precompileResult{res, ok}) + return res, ok +} + func (o *CachingOracle) GoOrUpdatePreFetchReceipts(ctx context.Context, block uint64) error { // do nothing return nil diff --git a/op-program/client/l1/cache_test.go b/op-program/client/l1/cache_test.go index c3b702bd9f78..1c6da3ddeeab 100644 --- a/op-program/client/l1/cache_test.go +++ b/op-program/client/l1/cache_test.go @@ -7,6 +7,8 @@ import ( "github.com/ethereum-optimism/optimism/op-program/client/l1/test" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" ) @@ -71,3 +73,44 @@ func TestCachingOracle_ReceiptsByBlockHash(t *testing.T) { require.Equal(t, eth.BlockToInfo(block), actualBlock) require.EqualValues(t, rcpts, actualRcpts) } + +func TestCachingOracle_GetBlobs(t *testing.T) { + stub := test.NewStubOracle(t) + oracle := NewCachingOracle(stub) + + l1BlockRef := eth.L1BlockRef{Time: 0} + indexedBlobHash := eth.IndexedBlobHash{Hash: [32]byte{0xFA, 0xCA, 0xDE}, Index: 0} + blob := eth.Blob{0xFF} + + // Initial call retrieves from the stub + stub.Blobs[l1BlockRef] = make(map[eth.IndexedBlobHash]*eth.Blob) + stub.Blobs[l1BlockRef][indexedBlobHash] = &blob + actualBlob := oracle.GetBlob(l1BlockRef, indexedBlobHash) + require.Equal(t, &blob, actualBlob) + + // Later calls should retrieve from cache + delete(stub.Blobs[l1BlockRef], indexedBlobHash) + actualBlob = oracle.GetBlob(l1BlockRef, indexedBlobHash) + require.Equal(t, &blob, actualBlob) +} + +func TestCachingOracle_Precompile(t *testing.T) { + stub := test.NewStubOracle(t) + oracle := NewCachingOracle(stub) + + input := []byte{0x01, 0x02, 0x03, 0x04} + output := []byte{0x0a, 0x0b, 0x0c, 0x0d} + addr := common.Address{0x1} + + // Initial call retrieves from the stub + stub.PcmpResults[crypto.Keccak256Hash(append(addr.Bytes(), input...))] = output + actualResult, actualStatus := oracle.Precompile(addr, input) + require.True(t, actualStatus) + require.EqualValues(t, output, actualResult) + + // Later calls should retrieve from cache + delete(stub.PcmpResults, crypto.Keccak256Hash(append(addr.Bytes(), input...))) + actualResult, actualStatus = oracle.Precompile(addr, input) + require.True(t, actualStatus) + require.EqualValues(t, output, actualResult) +} diff --git a/op-program/client/l1/client_test.go b/op-program/client/l1/client_test.go index 8333b4a70590..4e03f92baa94 100644 --- a/op-program/client/l1/client_test.go +++ b/op-program/client/l1/client_test.go @@ -164,7 +164,7 @@ func TestL1BlockRefByNumber(t *testing.T) { func newClient(t *testing.T) (*OracleL1Client, *test.StubOracle) { stub := test.NewStubOracle(t) stub.Blocks[head.Hash()] = head - client := NewOracleL1Client(testlog.Logger(t, log.LvlDebug), stub, head.Hash()) + client := NewOracleL1Client(testlog.Logger(t, log.LevelDebug), stub, head.Hash()) return client, stub } diff --git a/op-program/client/l1/hints.go b/op-program/client/l1/hints.go index 1383f6a295f4..0a1ceabaa956 100644 --- a/op-program/client/l1/hints.go +++ b/op-program/client/l1/hints.go @@ -2,6 +2,7 @@ package l1 import ( "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" preimage "github.com/ethereum-optimism/optimism/op-preimage" ) @@ -10,6 +11,8 @@ const ( HintL1BlockHeader = "l1-block-header" HintL1Transactions = "l1-transactions" HintL1Receipts = "l1-receipts" + HintL1Blob = "l1-blob" + HintL1Precompile = "l1-precompile" ) type BlockHeaderHint common.Hash @@ -35,3 +38,19 @@ var _ preimage.Hint = ReceiptsHint{} func (l ReceiptsHint) Hint() string { return HintL1Receipts + " " + (common.Hash)(l).String() } + +type BlobHint []byte + +var _ preimage.Hint = BlobHint{} + +func (l BlobHint) Hint() string { + return HintL1Blob + " " + hexutil.Encode(l) +} + +type PrecompileHint []byte + +var _ preimage.Hint = PrecompileHint{} + +func (l PrecompileHint) Hint() string { + return HintL1Precompile + " " + hexutil.Encode(l) +} diff --git a/op-program/client/l1/oracle.go b/op-program/client/l1/oracle.go index 6e24dc406192..122c71647655 100644 --- a/op-program/client/l1/oracle.go +++ b/op-program/client/l1/oracle.go @@ -2,10 +2,13 @@ package l1 import ( "context" + "encoding/binary" "fmt" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" preimage "github.com/ethereum-optimism/optimism/op-preimage" @@ -22,6 +25,13 @@ type Oracle interface { // ReceiptsByBlockHash retrieves the receipts from the block with the given hash. ReceiptsByBlockHash(blockHash common.Hash) (eth.BlockInfo, types.Receipts) + + // GetBlob retrieves the blob with the given hash. + GetBlob(ref eth.L1BlockRef, blobHash eth.IndexedBlobHash) *eth.Blob + + // Precompile retrieves the result and success indicator of a precompile call for the given input. + Precompile(precompileAddress common.Address, input []byte) ([]byte, bool) + GoOrUpdatePreFetchReceipts(ctx context.Context, block uint64) error } @@ -89,6 +99,40 @@ func (p *PreimageOracle) ReceiptsByBlockHash(blockHash common.Hash) (eth.BlockIn return info, receipts } +func (p *PreimageOracle) GetBlob(ref eth.L1BlockRef, blobHash eth.IndexedBlobHash) *eth.Blob { + // Send a hint for the blob commitment & blob field elements. + blobReqMeta := make([]byte, 16) + binary.BigEndian.PutUint64(blobReqMeta[0:8], blobHash.Index) + binary.BigEndian.PutUint64(blobReqMeta[8:16], ref.Time) + p.hint.Hint(BlobHint(append(blobHash.Hash[:], blobReqMeta...))) + + commitment := p.oracle.Get(preimage.Sha256Key(blobHash.Hash)) + + // Reconstruct the full blob from the 4096 field elements. + blob := eth.Blob{} + fieldElemKey := make([]byte, 80) + copy(fieldElemKey[:48], commitment) + for i := 0; i < params.BlobTxFieldElementsPerBlob; i++ { + binary.BigEndian.PutUint64(fieldElemKey[72:], uint64(i)) + fieldElement := p.oracle.Get(preimage.BlobKey(crypto.Keccak256(fieldElemKey))) + + copy(blob[i<<5:(i+1)<<5], fieldElement[:]) + } + + return &blob +} + +func (p *PreimageOracle) Precompile(address common.Address, input []byte) ([]byte, bool) { + hintBytes := append(address.Bytes(), input...) + p.hint.Hint(PrecompileHint(hintBytes)) + key := preimage.PrecompileKey(crypto.Keccak256Hash(hintBytes)) + result := p.oracle.Get(key) + if len(result) == 0 { // must contain at least the status code + panic(fmt.Errorf("unexpected precompile oracle behavior, got result: %x", result)) + } + return result[1:], result[0] == 1 +} + func (p *PreimageOracle) GoOrUpdatePreFetchReceipts(ctx context.Context, block uint64) error { // do nothing return nil diff --git a/op-program/client/l1/test/stub_oracle.go b/op-program/client/l1/test/stub_oracle.go index 7d495a90a6e5..e16de22ff561 100644 --- a/op-program/client/l1/test/stub_oracle.go +++ b/op-program/client/l1/test/stub_oracle.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" ) type StubOracle struct { @@ -20,16 +21,25 @@ type StubOracle struct { // Rcpts maps Block hash to receipts Rcpts map[common.Hash]types.Receipts + + // Blobs maps indexed blob hash to l1 block ref to blob + Blobs map[eth.L1BlockRef]map[eth.IndexedBlobHash]*eth.Blob + + // PcmpResults maps hashed input to the results of precompile calls + PcmpResults map[common.Hash][]byte } func NewStubOracle(t *testing.T) *StubOracle { return &StubOracle{ - t: t, - Blocks: make(map[common.Hash]eth.BlockInfo), - Txs: make(map[common.Hash]types.Transactions), - Rcpts: make(map[common.Hash]types.Receipts), + t: t, + Blocks: make(map[common.Hash]eth.BlockInfo), + Txs: make(map[common.Hash]types.Transactions), + Rcpts: make(map[common.Hash]types.Receipts), + Blobs: make(map[eth.L1BlockRef]map[eth.IndexedBlobHash]*eth.Blob), + PcmpResults: make(map[common.Hash][]byte), } } + func (o StubOracle) HeaderByBlockHash(blockHash common.Hash) eth.BlockInfo { info, ok := o.Blocks[blockHash] if !ok { @@ -54,6 +64,26 @@ func (o StubOracle) ReceiptsByBlockHash(blockHash common.Hash) (eth.BlockInfo, t return o.HeaderByBlockHash(blockHash), rcpts } +func (o StubOracle) GetBlob(ref eth.L1BlockRef, blobHash eth.IndexedBlobHash) *eth.Blob { + blobMap, ok := o.Blobs[ref] + if !ok { + o.t.Fatalf("unknown blob ref %s", ref) + } + blob, ok := blobMap[blobHash] + if !ok { + o.t.Fatalf("unknown blob hash %s %d", blobHash.Hash, blobHash.Index) + } + return blob +} + +func (o StubOracle) Precompile(addr common.Address, input []byte) ([]byte, bool) { + result, ok := o.PcmpResults[crypto.Keccak256Hash(append(addr.Bytes(), input...))] + if !ok { + o.t.Fatalf("unknown kzg point evaluation %x", input) + } + return result, true +} + func (o StubOracle) GoOrUpdatePreFetchReceipts(ctx context.Context, block uint64) error { // do nothing return nil diff --git a/op-program/client/l2/engine.go b/op-program/client/l2/engine.go index 3d105c181f26..3b7c6e8450e7 100644 --- a/op-program/client/l2/engine.go +++ b/op-program/client/l2/engine.go @@ -15,9 +15,7 @@ import ( "github.com/ethereum/go-ethereum/log" ) -var ( - ErrNotFound = errors.New("not found") -) +var ErrNotFound = errors.New("not found") type OracleEngine struct { api *engineapi.L2EngineAPI @@ -26,7 +24,7 @@ type OracleEngine struct { } func NewOracleEngine(rollupCfg *rollup.Config, logger log.Logger, backend engineapi.EngineBackend) *OracleEngine { - engineAPI := engineapi.NewL2EngineAPI(logger, backend) + engineAPI := engineapi.NewL2EngineAPI(logger, backend, nil) return &OracleEngine{ api: engineAPI, backend: backend, @@ -34,44 +32,72 @@ func NewOracleEngine(rollupCfg *rollup.Config, logger log.Logger, backend engine } } -func (o *OracleEngine) L2OutputRoot() (eth.Bytes32, error) { - outBlock := o.backend.CurrentHeader() +func (o *OracleEngine) L2OutputRoot(l2ClaimBlockNum uint64) (eth.Bytes32, error) { + outBlock := o.backend.GetHeaderByNumber(l2ClaimBlockNum) + if outBlock == nil { + return eth.Bytes32{}, fmt.Errorf("failed to get L2 block at %d", l2ClaimBlockNum) + } stateDB, err := o.backend.StateAt(outBlock.Root) if err != nil { return eth.Bytes32{}, fmt.Errorf("failed to open L2 state db at block %s: %w", outBlock.Hash(), err) } - withdrawalsTrie, err := stateDB.Database().OpenStorageTrie(outBlock.Root, predeploys.L2ToL1MessagePasserAddr, stateDB.GetStorageRoot(predeploys.L2ToL1MessagePasserAddr)) + withdrawalsTrie, err := stateDB.OpenStorageTrie(predeploys.L2ToL1MessagePasserAddr) if err != nil { return eth.Bytes32{}, fmt.Errorf("withdrawals trie unavailable at block %v: %w", outBlock.Hash(), err) } return rollup.ComputeL2OutputRootV0(eth.HeaderBlockInfo(outBlock), withdrawalsTrie.Hash()) } -func (o *OracleEngine) GetPayload(ctx context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayload, error) { - res, err := o.api.GetPayloadV2(ctx, payloadId) +func (o *OracleEngine) GetPayload(ctx context.Context, payloadInfo eth.PayloadInfo) (*eth.ExecutionPayloadEnvelope, error) { + var res *eth.ExecutionPayloadEnvelope + var err error + switch method := o.rollupCfg.GetPayloadVersion(payloadInfo.Timestamp); method { + case eth.GetPayloadV3: + res, err = o.api.GetPayloadV3(ctx, payloadInfo.ID) + case eth.GetPayloadV2: + res, err = o.api.GetPayloadV2(ctx, payloadInfo.ID) + default: + return nil, fmt.Errorf("unsupported GetPayload version: %s", method) + } if err != nil { return nil, err } - return res.ExecutionPayload, nil + return res, nil } func (o *OracleEngine) ForkchoiceUpdate(ctx context.Context, state *eth.ForkchoiceState, attr *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error) { - return o.api.ForkchoiceUpdatedV2(ctx, state, attr) + switch method := o.rollupCfg.ForkchoiceUpdatedVersion(attr); method { + case eth.FCUV3: + return o.api.ForkchoiceUpdatedV3(ctx, state, attr) + case eth.FCUV2: + return o.api.ForkchoiceUpdatedV2(ctx, state, attr) + case eth.FCUV1: + return o.api.ForkchoiceUpdatedV1(ctx, state, attr) + default: + return nil, fmt.Errorf("unsupported ForkchoiceUpdated version: %s", method) + } } -func (o *OracleEngine) NewPayload(ctx context.Context, payload *eth.ExecutionPayload) (*eth.PayloadStatusV1, error) { - return o.api.NewPayloadV2(ctx, payload) +func (o *OracleEngine) NewPayload(ctx context.Context, payload *eth.ExecutionPayload, parentBeaconBlockRoot *common.Hash) (*eth.PayloadStatusV1, error) { + switch method := o.rollupCfg.NewPayloadVersion(uint64(payload.Timestamp)); method { + case eth.NewPayloadV3: + return o.api.NewPayloadV3(ctx, payload, []common.Hash{}, parentBeaconBlockRoot) + case eth.NewPayloadV2: + return o.api.NewPayloadV2(ctx, payload) + default: + return nil, fmt.Errorf("unsupported NewPayload version: %s", method) + } } -func (o *OracleEngine) PayloadByHash(ctx context.Context, hash common.Hash) (*eth.ExecutionPayload, error) { +func (o *OracleEngine) PayloadByHash(ctx context.Context, hash common.Hash) (*eth.ExecutionPayloadEnvelope, error) { block := o.backend.GetBlockByHash(hash) if block == nil { return nil, ErrNotFound } - return eth.BlockAsPayload(block, o.rollupCfg.CanyonTime) + return eth.BlockAsPayloadEnv(block, o.rollupCfg.CanyonTime) } -func (o *OracleEngine) PayloadByNumber(ctx context.Context, n uint64) (*eth.ExecutionPayload, error) { +func (o *OracleEngine) PayloadByNumber(ctx context.Context, n uint64) (*eth.ExecutionPayloadEnvelope, error) { hash := o.backend.GetCanonicalHash(n) if hash == (common.Hash{}) { return nil, ErrNotFound @@ -98,7 +124,7 @@ func (o *OracleEngine) L2BlockRefByLabel(ctx context.Context, label eth.BlockLab if block == nil { return eth.L2BlockRef{}, ErrNotFound } - return derive.L2BlockToBlockRef(block, &o.rollupCfg.Genesis) + return derive.L2BlockToBlockRef(o.rollupCfg, block) } func (o *OracleEngine) L2BlockRefByHash(ctx context.Context, l2Hash common.Hash) (eth.L2BlockRef, error) { @@ -106,7 +132,7 @@ func (o *OracleEngine) L2BlockRefByHash(ctx context.Context, l2Hash common.Hash) if block == nil { return eth.L2BlockRef{}, ErrNotFound } - return derive.L2BlockToBlockRef(block, &o.rollupCfg.Genesis) + return derive.L2BlockToBlockRef(o.rollupCfg, block) } func (o *OracleEngine) L2BlockRefByNumber(ctx context.Context, n uint64) (eth.L2BlockRef, error) { @@ -122,9 +148,9 @@ func (o *OracleEngine) SystemConfigByL2Hash(ctx context.Context, hash common.Has if err != nil { return eth.SystemConfig{}, err } - return derive.PayloadToSystemConfig(payload, o.rollupCfg) + return derive.PayloadToSystemConfig(o.rollupCfg, payload.ExecutionPayload) } -func (o *OracleEngine) CachePayloadByHash(payload *eth.ExecutionPayload) bool { +func (o *OracleEngine) CachePayloadByHash(payload *eth.ExecutionPayloadEnvelope) bool { return true } diff --git a/op-program/client/l2/engine_backend.go b/op-program/client/l2/engine_backend.go index ca7a495753cf..3880056e3376 100644 --- a/op-program/client/l2/engine_backend.go +++ b/op-program/client/l2/engine_backend.go @@ -40,7 +40,7 @@ type OracleBackedL2Chain struct { var _ engineapi.EngineBackend = (*OracleBackedL2Chain)(nil) -func NewOracleBackedL2Chain(logger log.Logger, oracle Oracle, chainCfg *params.ChainConfig, l2OutputRoot common.Hash) (*OracleBackedL2Chain, error) { +func NewOracleBackedL2Chain(logger log.Logger, oracle Oracle, precompileOracle engineapi.PrecompileOracle, chainCfg *params.ChainConfig, l2OutputRoot common.Hash) (*OracleBackedL2Chain, error) { output := oracle.OutputByRoot(l2OutputRoot) outputV0, ok := output.(*eth.OutputV0) if !ok { @@ -66,6 +66,9 @@ func NewOracleBackedL2Chain(logger log.Logger, oracle Oracle, chainCfg *params.C oracleHead: head.Header(), blocks: make(map[common.Hash]*types.Block), db: NewOracleBackedDB(oracle), + vmCfg: vm.Config{ + OptimismPrecompileOverrides: engineapi.CreatePrecompileOverrides(precompileOracle), + }, }, nil } diff --git a/op-program/client/l2/engine_backend_test.go b/op-program/client/l2/engine_backend_test.go index 861e68068625..0801d8738038 100644 --- a/op-program/client/l2/engine_backend_test.go +++ b/op-program/client/l2/engine_backend_test.go @@ -28,6 +28,18 @@ var fundedKey, _ = crypto.GenerateKey() var fundedAddress = crypto.PubkeyToAddress(fundedKey.PublicKey) var targetAddress = common.HexToAddress("0x001122334455") +var ( + kzgInputData = common.FromHex("01e798154708fe7789429634053cbf9f99b619f9f084048927333fce637f549b564c0a11a0f704f4fc3e8acfe0f8245f0ad1347b378fbf96e206da11a5d3630624d25032e67a7e6a4910df5834b8fe70e6bcfeeac0352434196bdf4b2485d5a18f59a8d2a1a625a17f3fea0fe5eb8c896db3764f3185481bc22f91b4aaffcca25f26936857bc3a7c2539ea8ec3a952b7873033e038326e87ed3e1276fd140253fa08e9fc25fb2d9a98527fc22a2c9612fbeafdad446cbc7bcdbdcd780af2c16a") + ecRecoverInputData = common.FromHex("18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549") + bn256PairingInputData = common.FromHex("1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa") +) + +var ( + ecRecoverReturnValue = []byte{0x1, 0x2} + bn256PairingReturnValue = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} + blobPrecompileReturnValue = common.FromHex("000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001") +) + func TestInitialState(t *testing.T) { blocks, chain := setupOracleBackedChain(t, 5) head := blocks[5] @@ -186,6 +198,56 @@ func TestGetHeaderByNumber(t *testing.T) { }) } +func TestPrecompileOracle(t *testing.T) { + tests := []struct { + name string + input []byte + target common.Address + result []byte + }{ + { + name: "EcRecover", + input: ecRecoverInputData, + target: common.BytesToAddress([]byte{0x1}), + result: ecRecoverReturnValue, + }, + { + name: "Bn256Pairing", + input: bn256PairingInputData, + target: common.BytesToAddress([]byte{0x8}), + result: bn256PairingReturnValue, + }, + { + name: "KZGPointEvaluation", + input: kzgInputData, + target: common.BytesToAddress([]byte{0xa}), + result: blobPrecompileReturnValue, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + blockCount := 3 + headBlockNumber := 3 + logger := testlog.Logger(t, log.LevelDebug) + chainCfg, blocks, oracle := setupOracle(t, blockCount, headBlockNumber, true) + head := blocks[headBlockNumber].Hash() + stubOutput := eth.OutputV0{BlockHash: head} + precompileOracle := new(l2test.StubPrecompileOracle) + precompileOracle.Results = map[common.Hash]l2test.PrecompileResult{ + crypto.Keccak256Hash(append(test.target.Bytes(), test.input...)): {Result: test.result, Ok: true}, + } + chain, err := NewOracleBackedL2Chain(logger, oracle, precompileOracle, chainCfg, common.Hash(eth.OutputRoot(&stubOutput))) + require.NoError(t, err) + + newBlock := createBlock(t, chain, WithInput(test.input), WithTargetAddress(test.target)) + require.NoError(t, chain.InsertBlockWithoutSetHead(newBlock)) + require.Equal(t, 1, precompileOracle.Calls) + }) + } +} + func assertBlockDataAvailable(t *testing.T, chain *OracleBackedL2Chain, block *types.Block, blockNumber uint64) { require.Equal(t, block, chain.GetBlockByHash(block.Hash()), "get block %v by hash", blockNumber) require.Equal(t, block.Header(), chain.GetHeaderByHash(block.Hash()), "get header %v by hash", blockNumber) @@ -199,16 +261,17 @@ func setupOracleBackedChain(t *testing.T, blockCount int) ([]*types.Block, *Orac } func setupOracleBackedChainWithLowerHead(t *testing.T, blockCount int, headBlockNumber int) ([]*types.Block, *OracleBackedL2Chain) { - logger := testlog.Logger(t, log.LvlDebug) - chainCfg, blocks, oracle := setupOracle(t, blockCount, headBlockNumber) + logger := testlog.Logger(t, log.LevelDebug) + chainCfg, blocks, oracle := setupOracle(t, blockCount, headBlockNumber, false) head := blocks[headBlockNumber].Hash() stubOutput := eth.OutputV0{BlockHash: head} - chain, err := NewOracleBackedL2Chain(logger, oracle, chainCfg, common.Hash(eth.OutputRoot(&stubOutput))) + precompileOracle := new(l2test.StubPrecompileOracle) + chain, err := NewOracleBackedL2Chain(logger, oracle, precompileOracle, chainCfg, common.Hash(eth.OutputRoot(&stubOutput))) require.NoError(t, err) return blocks, chain } -func setupOracle(t *testing.T, blockCount int, headBlockNumber int) (*params.ChainConfig, []*types.Block, *l2test.StubBlockOracle) { +func setupOracle(t *testing.T, blockCount int, headBlockNumber int, enableEcotone bool) (*params.ChainConfig, []*types.Block, *l2test.StubBlockOracle) { deployConfig := &genesis.DeployConfig{ L1ChainID: 900, L2ChainID: 901, @@ -219,6 +282,13 @@ func setupOracle(t *testing.T, blockCount int, headBlockNumber int) (*params.Cha // This is slightly weird for a chain starting post-merge but it happens so need to make sure it works L2GenesisBlockDifficulty: (*hexutil.Big)(big.NewInt(100)), } + if enableEcotone { + ts := hexutil.Uint64(0) + deployConfig.L2GenesisRegolithTimeOffset = &ts + deployConfig.L2GenesisCanyonTimeOffset = &ts + deployConfig.L2GenesisDeltaTimeOffset = &ts + deployConfig.L2GenesisEcotoneTimeOffset = &ts + } l1Genesis, err := genesis.NewL1Genesis(deployConfig) require.NoError(t, err) l2Genesis, err := genesis.NewL2Genesis(deployConfig, l1Genesis.ToBlock()) @@ -246,7 +316,33 @@ func setupOracle(t *testing.T, blockCount int, headBlockNumber int) (*params.Cha return chainCfg, blocks, oracle } -func createBlock(t *testing.T, chain *OracleBackedL2Chain) *types.Block { +type blockCreateConfig struct { + input []byte + target *common.Address +} + +type blockCreateOption func(*blockCreateConfig) + +func WithInput(input []byte) blockCreateOption { + return func(opts *blockCreateConfig) { + opts.input = input + } +} + +func WithTargetAddress(target common.Address) blockCreateOption { + return func(opts *blockCreateConfig) { + opts.target = &target + } +} + +func createBlock(t *testing.T, chain *OracleBackedL2Chain, opts ...blockCreateOption) *types.Block { + cfg := blockCreateConfig{} + for _, o := range opts { + o(&cfg) + } + if cfg.target == nil { + cfg.target = &targetAddress + } parent := chain.GetBlockByHash(chain.CurrentHeader().Hash()) parentDB, err := chain.StateAt(parent.Root()) require.NoError(t, err) @@ -257,10 +353,11 @@ func createBlock(t *testing.T, chain *OracleBackedL2Chain) *types.Block { rawTx := &types.DynamicFeeTx{ ChainID: config.ChainID, Nonce: nonce, - To: &targetAddress, + To: cfg.target, GasTipCap: big.NewInt(0), GasFeeCap: parent.BaseFee(), - Gas: 21_000, + Gas: 2_000_000, + Data: cfg.input, Value: big.NewInt(1), } tx := types.MustSignNewTx(fundedKey, types.NewLondonSigner(config.ChainID), rawTx) diff --git a/op-program/client/l2/engine_test.go b/op-program/client/l2/engine_test.go index cfee68e6dac7..a3008115fbff 100644 --- a/op-program/client/l2/engine_test.go +++ b/op-program/client/l2/engine_test.go @@ -31,7 +31,7 @@ func TestPayloadByHash(t *testing.T) { require.NoError(t, err) expected, err := eth.BlockAsPayload(block, engine.rollupCfg.CanyonTime) require.NoError(t, err) - require.Equal(t, expected, payload) + require.Equal(t, ð.ExecutionPayloadEnvelope{ExecutionPayload: expected}, payload) }) t.Run("UnknownBlock", func(t *testing.T) { @@ -53,7 +53,7 @@ func TestPayloadByNumber(t *testing.T) { require.NoError(t, err) expected, err := eth.BlockAsPayload(block, engine.rollupCfg.CanyonTime) require.NoError(t, err) - require.Equal(t, expected, payload) + require.Equal(t, ð.ExecutionPayloadEnvelope{ExecutionPayload: expected}, payload) }) t.Run("NoCanonicalHash", func(t *testing.T) { @@ -87,7 +87,7 @@ func TestL2BlockRefByLabel(t *testing.T) { } for _, test := range tests { t.Run(string(test.name), func(t *testing.T) { - expected, err := derive.L2BlockToBlockRef(test.block, &engine.rollupCfg.Genesis) + expected, err := derive.L2BlockToBlockRef(engine.rollupCfg, test.block) require.NoError(t, err) blockRef, err := engine.L2BlockRefByLabel(ctx, test.name) require.NoError(t, err) @@ -105,7 +105,7 @@ func TestL2BlockRefByHash(t *testing.T) { engine, stub := createOracleEngine(t) t.Run("KnownBlock", func(t *testing.T) { - expected, err := derive.L2BlockToBlockRef(stub.safe, &engine.rollupCfg.Genesis) + expected, err := derive.L2BlockToBlockRef(engine.rollupCfg, stub.safe) require.NoError(t, err) ref, err := engine.L2BlockRefByHash(ctx, stub.safe.Hash()) require.NoError(t, err) @@ -126,7 +126,7 @@ func TestSystemConfigByL2Hash(t *testing.T) { t.Run("KnownBlock", func(t *testing.T) { payload, err := eth.BlockAsPayload(stub.safe, engine.rollupCfg.CanyonTime) require.NoError(t, err) - expected, err := derive.PayloadToSystemConfig(payload, engine.rollupCfg) + expected, err := derive.PayloadToSystemConfig(engine.rollupCfg, payload) require.NoError(t, err) cfg, err := engine.SystemConfigByL2Hash(ctx, stub.safe.Hash()) require.NoError(t, err) @@ -167,10 +167,10 @@ func createOracleEngine(t *testing.T) (*OracleEngine, *stubEngineBackend) { } func createL2Block(t *testing.T, number int) *types.Block { - tx, err := derive.L1InfoDeposit(uint64(1), eth.HeaderBlockInfo(&types.Header{ + tx, err := derive.L1InfoDeposit(chaincfg.Goerli, eth.SystemConfig{}, uint64(1), eth.HeaderBlockInfo(&types.Header{ Number: big.NewInt(32), BaseFee: big.NewInt(7), - }), eth.SystemConfig{}, true) + }), 0) require.NoError(t, err) header := &types.Header{ Number: big.NewInt(int64(number)), diff --git a/op-program/client/l2/engineapi/block_processor.go b/op-program/client/l2/engineapi/block_processor.go index c6966e0d94c2..d81212db206c 100644 --- a/op-program/client/l2/engineapi/block_processor.go +++ b/op-program/client/l2/engineapi/block_processor.go @@ -39,17 +39,26 @@ type BlockProcessor struct { dataProvider BlockDataProvider } -func NewBlockProcessorFromPayloadAttributes(provider BlockDataProvider, parent common.Hash, params *eth.PayloadAttributes) (*BlockProcessor, error) { +func NewBlockProcessorFromPayloadAttributes(provider BlockDataProvider, parent common.Hash, attrs *eth.PayloadAttributes) (*BlockProcessor, error) { header := &types.Header{ - ParentHash: parent, - Coinbase: params.SuggestedFeeRecipient, - Difficulty: common.Big0, - GasLimit: uint64(*params.GasLimit), - Time: uint64(params.Timestamp), - Extra: nil, - MixDigest: common.Hash(params.PrevRandao), - Nonce: types.EncodeNonce(0), + ParentHash: parent, + Coinbase: attrs.SuggestedFeeRecipient, + Difficulty: common.Big0, + GasLimit: uint64(*attrs.GasLimit), + Time: uint64(attrs.Timestamp), + Extra: nil, + MixDigest: common.Hash(attrs.PrevRandao), + Nonce: types.EncodeNonce(0), + ParentBeaconRoot: attrs.ParentBeaconBlockRoot, } + + // Ecotone + if attrs.ParentBeaconBlockRoot != nil { + zero := uint64(0) + header.BlobGasUsed = &zero + header.ExcessBlobGas = &zero + } + return NewBlockProcessorFromHeader(provider, header) } @@ -71,6 +80,18 @@ func NewBlockProcessorFromHeader(provider BlockDataProvider, h *types.Header) (* header.BaseFee = eip1559.CalcBaseFee(provider.Config(), parentHeader, header.Time) header.GasUsed = 0 gasPool := new(core.GasPool).AddGas(header.GasLimit) + if h.ParentBeaconRoot != nil { + // Unfortunately this is not part of any Geth environment setup, + // we just have to apply it, like how the Geth block-builder worker does. + context := core.NewEVMBlockContext(header, provider, nil, provider.Config(), statedb) + // NOTE: Unlikely to be needed for the beacon block root, but we setup any precompile overrides anyways for forwards-compatibility + var precompileOverrides vm.PrecompileOverrides + if vmConfig := provider.GetVMConfig(); vmConfig != nil && vmConfig.OptimismPrecompileOverrides != nil { + precompileOverrides = vmConfig.OptimismPrecompileOverrides + } + vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, provider.Config(), vm.Config{OptimismPrecompileOverrides: precompileOverrides}) + core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, statedb) + } return &BlockProcessor{ header: header, state: statedb, @@ -95,7 +116,7 @@ func (b *BlockProcessor) AddTx(tx *types.Transaction) error { receipt, err := core.ApplyTransaction(b.dataProvider.Config(), b.dataProvider, &b.header.Coinbase, b.gasPool, b.state, b.header, tx, &b.header.GasUsed, *b.dataProvider.GetVMConfig()) if err != nil { - return fmt.Errorf("failed to apply deposit transaction to L2 block (tx %d): %w", txIndex, err) + return fmt.Errorf("failed to apply transaction to L2 block (tx %d): %w", txIndex, err) } b.receipts = append(b.receipts, receipt) b.transactions = append(b.transactions, tx) diff --git a/op-program/client/l2/engineapi/l2_engine_api.go b/op-program/client/l2/engineapi/l2_engine_api.go index 1863e948464f..dbcd1b7c13e0 100644 --- a/op-program/client/l2/engineapi/l2_engine_api.go +++ b/op-program/client/l2/engineapi/l2_engine_api.go @@ -16,8 +16,10 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" ) type EngineBackend interface { @@ -50,6 +52,10 @@ type L2EngineAPI struct { log log.Logger backend EngineBackend + // Functionality for snap sync + remotes map[common.Hash]*types.Block + downloader *downloader.Downloader + // L2 block building data blockProcessor *BlockProcessor pendingIndices map[common.Address]uint64 // per account, how many txs from the pool were already included in the block, since the pool is lagging behind block mining. @@ -59,10 +65,12 @@ type L2EngineAPI struct { payloadID engine.PayloadID // ID of payload that is currently being built } -func NewL2EngineAPI(log log.Logger, backend EngineBackend) *L2EngineAPI { +func NewL2EngineAPI(log log.Logger, backend EngineBackend, downloader *downloader.Downloader) *L2EngineAPI { return &L2EngineAPI{ - log: log, - backend: backend, + log: log, + backend: backend, + remotes: make(map[common.Hash]*types.Block), + downloader: downloader, } } @@ -72,20 +80,20 @@ var ( ) // computePayloadId computes a pseudo-random payloadid, based on the parameters. -func computePayloadId(headBlockHash common.Hash, params *eth.PayloadAttributes) engine.PayloadID { +func computePayloadId(headBlockHash common.Hash, attrs *eth.PayloadAttributes) engine.PayloadID { // Hash hasher := sha256.New() hasher.Write(headBlockHash[:]) - _ = binary.Write(hasher, binary.BigEndian, params.Timestamp) - hasher.Write(params.PrevRandao[:]) - hasher.Write(params.SuggestedFeeRecipient[:]) - _ = binary.Write(hasher, binary.BigEndian, params.NoTxPool) - _ = binary.Write(hasher, binary.BigEndian, uint64(len(params.Transactions))) - for _, tx := range params.Transactions { + _ = binary.Write(hasher, binary.BigEndian, attrs.Timestamp) + hasher.Write(attrs.PrevRandao[:]) + hasher.Write(attrs.SuggestedFeeRecipient[:]) + _ = binary.Write(hasher, binary.BigEndian, attrs.NoTxPool) + _ = binary.Write(hasher, binary.BigEndian, uint64(len(attrs.Transactions))) + for _, tx := range attrs.Transactions { _ = binary.Write(hasher, binary.BigEndian, uint64(len(tx))) // length-prefix to avoid collisions hasher.Write(tx) } - _ = binary.Write(hasher, binary.BigEndian, *params.GasLimit) + _ = binary.Write(hasher, binary.BigEndian, *attrs.GasLimit) var out engine.PayloadID copy(out[:], hasher.Sum(nil)[:8]) return out @@ -106,9 +114,7 @@ func (ea *L2EngineAPI) PendingIndices(from common.Address) uint64 { return ea.pendingIndices[from] } -var ( - ErrNotBuildingBlock = errors.New("not currently building a block, cannot include tx from queue") -) +var ErrNotBuildingBlock = errors.New("not currently building a block, cannot include tx from queue") func (ea *L2EngineAPI) IncludeTx(tx *types.Transaction, from common.Address) error { if ea.blockProcessor == nil { @@ -134,22 +140,22 @@ func (ea *L2EngineAPI) IncludeTx(tx *types.Transaction, from common.Address) err return nil } -func (ea *L2EngineAPI) startBlock(parent common.Hash, params *eth.PayloadAttributes) error { +func (ea *L2EngineAPI) startBlock(parent common.Hash, attrs *eth.PayloadAttributes) error { if ea.blockProcessor != nil { ea.log.Warn("started building new block without ending previous block", "previous", ea.blockProcessor.header, "prev_payload_id", ea.payloadID) } - processor, err := NewBlockProcessorFromPayloadAttributes(ea.backend, parent, params) + processor, err := NewBlockProcessorFromPayloadAttributes(ea.backend, parent, attrs) if err != nil { return err } ea.blockProcessor = processor ea.pendingIndices = make(map[common.Address]uint64) - ea.l2ForceEmpty = params.NoTxPool - ea.payloadID = computePayloadId(parent, params) + ea.l2ForceEmpty = attrs.NoTxPool + ea.payloadID = computePayloadId(parent, attrs) // pre-process the deposits - for i, otx := range params.Transactions { + for i, otx := range attrs.Transactions { var tx types.Transaction if err := tx.UnmarshalBinary(otx); err != nil { return fmt.Errorf("transaction %d is not valid: %w", i, err) @@ -178,12 +184,19 @@ func (ea *L2EngineAPI) endBlock() (*types.Block, error) { } func (ea *L2EngineAPI) GetPayloadV1(ctx context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayload, error) { - return ea.getPayload(ctx, payloadId) + res, err := ea.getPayload(ctx, payloadId) + if err != nil { + return nil, err + } + return res.ExecutionPayload, nil } func (ea *L2EngineAPI) GetPayloadV2(ctx context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayloadEnvelope, error) { - payload, err := ea.getPayload(ctx, payloadId) - return ð.ExecutionPayloadEnvelope{ExecutionPayload: payload}, err + return ea.getPayload(ctx, payloadId) +} + +func (ea *L2EngineAPI) GetPayloadV3(ctx context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayloadEnvelope, error) { + return ea.getPayload(ctx, payloadId) } func (ea *L2EngineAPI) config() *params.ChainConfig { @@ -213,6 +226,17 @@ func (ea *L2EngineAPI) ForkchoiceUpdatedV2(ctx context.Context, state *eth.Forkc return ea.forkchoiceUpdated(ctx, state, attr) } +// Ported from: https://github.com/ethereum-optimism/op-geth/blob/c50337a60a1309a0f1dca3bf33ed1bb38c46cdd7/eth/catalyst/api.go#L197C1-L205C1 +func (ea *L2EngineAPI) ForkchoiceUpdatedV3(ctx context.Context, state *eth.ForkchoiceState, attr *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error) { + if attr != nil { + if err := ea.verifyPayloadAttributes(attr); err != nil { + return STATUS_INVALID, engine.InvalidParams.With(err) + } + } + return ea.forkchoiceUpdated(ctx, state, attr) +} + +// Ported from: https://github.com/ethereum-optimism/op-geth/blob/c50337a60a1309a0f1dca3bf33ed1bb38c46cdd7/eth/catalyst/api.go#L206-L218 func (ea *L2EngineAPI) verifyPayloadAttributes(attr *eth.PayloadAttributes) error { c := ea.config() @@ -220,6 +244,11 @@ func (ea *L2EngineAPI) verifyPayloadAttributes(attr *eth.PayloadAttributes) erro if err := checkAttribute(c.IsShanghai, attr.Withdrawals != nil, c.LondonBlock, uint64(attr.Timestamp)); err != nil { return fmt.Errorf("invalid withdrawals: %w", err) } + // Verify beacon root attribute for Cancun. + if err := checkAttribute(c.IsCancun, attr.ParentBeaconBlockRoot != nil, c.LondonBlock, uint64(attr.Timestamp)); err != nil { + return fmt.Errorf("invalid parent beacon block root: %w", err) + } + return nil } @@ -238,7 +267,7 @@ func (ea *L2EngineAPI) NewPayloadV1(ctx context.Context, payload *eth.ExecutionP return ð.PayloadStatusV1{Status: eth.ExecutionInvalid}, engine.InvalidParams.With(errors.New("withdrawals not supported in V1")) } - return ea.newPayload(ctx, payload) + return ea.newPayload(ctx, payload, nil, nil) } func (ea *L2EngineAPI) NewPayloadV2(ctx context.Context, payload *eth.ExecutionPayload) (*eth.PayloadStatusV1, error) { @@ -250,10 +279,32 @@ func (ea *L2EngineAPI) NewPayloadV2(ctx context.Context, payload *eth.ExecutionP return ð.PayloadStatusV1{Status: eth.ExecutionInvalid}, engine.InvalidParams.With(errors.New("non-nil withdrawals pre-shanghai")) } - return ea.newPayload(ctx, payload) + return ea.newPayload(ctx, payload, nil, nil) } -func (ea *L2EngineAPI) getPayload(ctx context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayload, error) { +// Ported from: https://github.com/ethereum-optimism/op-geth/blob/c50337a60a1309a0f1dca3bf33ed1bb38c46cdd7/eth/catalyst/api.go#L486C1-L507 +func (ea *L2EngineAPI) NewPayloadV3(ctx context.Context, params *eth.ExecutionPayload, versionedHashes []common.Hash, beaconRoot *common.Hash) (*eth.PayloadStatusV1, error) { + if params.ExcessBlobGas == nil { + return ð.PayloadStatusV1{Status: eth.ExecutionInvalid}, engine.InvalidParams.With(errors.New("nil excessBlobGas post-cancun")) + } + if params.BlobGasUsed == nil { + return ð.PayloadStatusV1{Status: eth.ExecutionInvalid}, engine.InvalidParams.With(errors.New("nil params.BlobGasUsed post-cancun")) + } + if versionedHashes == nil { + return ð.PayloadStatusV1{Status: eth.ExecutionInvalid}, engine.InvalidParams.With(errors.New("nil versionedHashes post-cancun")) + } + if beaconRoot == nil { + return ð.PayloadStatusV1{Status: eth.ExecutionInvalid}, engine.InvalidParams.With(errors.New("nil parentBeaconBlockRoot post-cancun")) + } + + if !ea.config().IsCancun(new(big.Int).SetUint64(uint64(params.BlockNumber)), uint64(params.Timestamp)) { + return ð.PayloadStatusV1{Status: eth.ExecutionInvalid}, engine.UnsupportedFork.With(errors.New("newPayloadV3 called pre-cancun")) + } + + return ea.newPayload(ctx, params, versionedHashes, beaconRoot) +} + +func (ea *L2EngineAPI) getPayload(_ context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayloadEnvelope, error) { ea.log.Trace("L2Engine API request received", "method", "GetPayload", "id", payloadId) if ea.payloadID != payloadId { ea.log.Warn("unexpected payload ID requested for block building", "expected", ea.payloadID, "got", payloadId) @@ -264,10 +315,11 @@ func (ea *L2EngineAPI) getPayload(ctx context.Context, payloadId eth.PayloadID) ea.log.Error("failed to finish block building", "err", err) return nil, engine.UnknownPayload } - return eth.BlockAsPayload(bl, ea.config().CanyonTime) + + return eth.BlockAsPayloadEnv(bl, ea.config().CanyonTime) } -func (ea *L2EngineAPI) forkchoiceUpdated(ctx context.Context, state *eth.ForkchoiceState, attr *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error) { +func (ea *L2EngineAPI) forkchoiceUpdated(_ context.Context, state *eth.ForkchoiceState, attr *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error) { ea.log.Trace("L2Engine API request received", "method", "ForkchoiceUpdated", "head", state.HeadBlockHash, "finalized", state.FinalizedBlockHash, "safe", state.SafeBlockHash) if state.HeadBlockHash == (common.Hash{}) { ea.log.Warn("Forkchoice requested update to zero hash") @@ -278,7 +330,24 @@ func (ea *L2EngineAPI) forkchoiceUpdated(ctx context.Context, state *eth.Forkcho // reason. block := ea.backend.GetBlockByHash(state.HeadBlockHash) if block == nil { - // TODO: syncing not supported yet + if ea.downloader == nil { + ea.log.Warn("Must register downloader to be able to snap sync") + return STATUS_SYNCING, nil + } + // If the head hash is unknown (was not given to us in a newPayload request), + // we cannot resolve the header, so not much to do. This could be extended in + // the future to resolve from the `eth` network, but it's an unexpected case + // that should be fixed, not papered over. + header := ea.remotes[state.HeadBlockHash] + if header == nil { + ea.log.Warn("Forkchoice requested unknown head", "hash", state.HeadBlockHash) + return STATUS_SYNCING, nil + } + + ea.log.Info("Forkchoice requested sync to new head", "number", header.Number(), "hash", header.Hash()) + if err := ea.downloader.BeaconSync(downloader.SnapSync, header.Header(), nil); err != nil { + return STATUS_SYNCING, err + } return STATUS_SYNCING, nil } // Block is known locally, just sanity check that the beacon client does not @@ -369,7 +438,7 @@ func toGethWithdrawals(payload *eth.ExecutionPayload) []*types.Withdrawal { return result } -func (ea *L2EngineAPI) newPayload(ctx context.Context, payload *eth.ExecutionPayload) (*eth.PayloadStatusV1, error) { +func (ea *L2EngineAPI) newPayload(_ context.Context, payload *eth.ExecutionPayload, hashes []common.Hash, root *common.Hash) (*eth.PayloadStatusV1, error) { ea.log.Trace("L2Engine API request received", "method", "ExecutePayload", "number", payload.BlockNumber, "hash", payload.BlockHash) txs := make([][]byte, len(payload.Transactions)) for i, tx := range payload.Transactions { @@ -387,11 +456,13 @@ func (ea *L2EngineAPI) newPayload(ctx context.Context, payload *eth.ExecutionPay GasUsed: uint64(payload.GasUsed), Timestamp: uint64(payload.Timestamp), ExtraData: payload.ExtraData, - BaseFeePerGas: payload.BaseFeePerGas.ToBig(), + BaseFeePerGas: (*uint256.Int)(&payload.BaseFeePerGas).ToBig(), BlockHash: payload.BlockHash, Transactions: txs, Withdrawals: toGethWithdrawals(payload), - }, nil, nil) + ExcessBlobGas: (*uint64)(payload.ExcessBlobGas), + BlobGasUsed: (*uint64)(payload.BlobGasUsed), + }, hashes, root) if err != nil { log.Debug("Invalid NewPayload params", "params", payload, "error", err) return ð.PayloadStatusV1{Status: eth.ExecutionInvalidBlockHash}, nil @@ -408,6 +479,7 @@ func (ea *L2EngineAPI) newPayload(ctx context.Context, payload *eth.ExecutionPay parent := ea.backend.GetBlock(block.ParentHash(), block.NumberU64()-1) if parent == nil { + ea.remotes[block.Hash()] = block // TODO: hack, saying we accepted if we don't know the parent block. Might want to return critical error if we can't actually sync. return ð.PayloadStatusV1{Status: eth.ExecutionAccepted, LatestValidHash: nil}, nil } diff --git a/op-program/client/l2/engineapi/precompiles.go b/op-program/client/l2/engineapi/precompiles.go new file mode 100644 index 000000000000..5ef77663d5bb --- /dev/null +++ b/op-program/client/l2/engineapi/precompiles.go @@ -0,0 +1,222 @@ +// This file contains code of the upstream go-ethereum kzgPointEvaluation implementation. +// Modifications have been made, primarily to substitute kzgPointEvaluation, ecrecover, and runBn256Pairing +// functions to interact with the preimage oracle. +// +// Original copyright disclaimer, applicable only to this file: +// ------------------------------------------------------------------- +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package engineapi + +import ( + "bytes" + "errors" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ethereum/go-ethereum/params" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +var ( + ecrecoverPrecompileAddress = common.BytesToAddress([]byte{0x1}) + bn256PairingPrecompileAddress = common.BytesToAddress([]byte{0x8}) + kzgPointEvaluationPrecompileAddress = common.BytesToAddress([]byte{0xa}) +) + +// PrecompileOracle defines the high-level API used to retrieve the result of a precompile call +// The caller is expected to validate the input to the precompile call +type PrecompileOracle interface { + Precompile(address common.Address, input []byte) ([]byte, bool) +} + +func CreatePrecompileOverrides(precompileOracle PrecompileOracle) vm.PrecompileOverrides { + return func(rules params.Rules, orig vm.PrecompiledContract, address common.Address) (vm.PrecompiledContract, bool) { + // NOTE: Ignoring chain rules for now. We assume that precompile behavior won't change for the foreseeable future + switch address { + case ecrecoverPrecompileAddress: + return &ecrecoverOracle{Orig: orig, Oracle: precompileOracle}, true + case bn256PairingPrecompileAddress: + return &bn256PairingOracle{Orig: orig, Oracle: precompileOracle}, true + case kzgPointEvaluationPrecompileAddress: + return &kzgPointEvaluationOracle{Orig: orig, Oracle: precompileOracle}, true + default: + return nil, false + } + } +} + +type ecrecoverOracle struct { + Orig vm.PrecompiledContract + Oracle PrecompileOracle +} + +func (c *ecrecoverOracle) RequiredGas(input []byte) uint64 { + return c.Orig.RequiredGas(input) +} + +func (c *ecrecoverOracle) Run(input []byte) ([]byte, error) { + // Modification note: the L1 precompile behavior may change, but not in incompatible ways. + // We want to enforce the subset that represents the EVM behavior activated in L2. + // Below is a copy of the Cancun behavior. L1 might expand on that at a later point. + + const ecRecoverInputLength = 128 + + input = common.RightPadBytes(input, ecRecoverInputLength) + // "input" is (hash, v, r, s), each 32 bytes + // but for ecrecover we want (r, s, v) + + r := new(big.Int).SetBytes(input[64:96]) + s := new(big.Int).SetBytes(input[96:128]) + v := input[63] - 27 + + // tighter sig s values input homestead only apply to tx sigs + if !allZero(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) { + return nil, nil + } + // We must make sure not to modify the 'input', so placing the 'v' along with + // the signature needs to be done on a new allocation + sig := make([]byte, 65) + copy(sig, input[64:128]) + sig[64] = v + // v needs to be at the end for libsecp256k1 + + // Modification note: below replaces the crypto.Ecrecover call + result, ok := c.Oracle.Precompile(ecrecoverPrecompileAddress, input) + if !ok { + return nil, errors.New("invalid ecrecover input") + } + return result, nil +} + +func allZero(b []byte) bool { + for _, byte := range b { + if byte != 0 { + return false + } + } + return true +} + +type bn256PairingOracle struct { + Orig vm.PrecompiledContract + Oracle PrecompileOracle +} + +func (b *bn256PairingOracle) RequiredGas(input []byte) uint64 { + return b.Orig.RequiredGas(input) +} + +var ( + // true32Byte is returned if the bn256 pairing check succeeds. + true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} + + // false32Byte is returned if the bn256 pairing check fails. + false32Byte = make([]byte, 32) + + // errBadPairingInput is returned if the bn256 pairing input is invalid. + errBadPairingInput = errors.New("bad elliptic curve pairing size") +) + +func (b *bn256PairingOracle) Run(input []byte) ([]byte, error) { + // Handle some corner cases cheaply + if len(input)%192 > 0 { + return nil, errBadPairingInput + } + // Modification note: below replaces point verification and pairing checks + // Assumes both L2 and the L1 oracle have an identical range of valid points + result, ok := b.Oracle.Precompile(bn256PairingPrecompileAddress, input) + if !ok { + return nil, errors.New("invalid bn256Pairing check") + } + if !bytes.Equal(result, true32Byte) && !bytes.Equal(result, false32Byte) { + panic("unexpected result from bn256Pairing check") + } + return result, nil +} + +// kzgPointEvaluationOracle implements the EIP-4844 point evaluation precompile, +// using the preimage-oracle to perform the evaluation. +type kzgPointEvaluationOracle struct { + Orig vm.PrecompiledContract + Oracle PrecompileOracle +} + +// RequiredGas estimates the gas required for running the point evaluation precompile. +func (b *kzgPointEvaluationOracle) RequiredGas(input []byte) uint64 { + return b.Orig.RequiredGas(input) +} + +const ( + blobVerifyInputLength = 192 // Max input length for the point evaluation precompile. + blobPrecompileReturnValue = "000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001" +) + +var ( + errBlobVerifyInvalidInputLength = errors.New("invalid input length") + errBlobVerifyMismatchedVersion = errors.New("mismatched versioned hash") + errBlobVerifyKZGProof = errors.New("error verifying kzg proof") +) + +// Run executes the point evaluation precompile. +func (b *kzgPointEvaluationOracle) Run(input []byte) ([]byte, error) { + // Modification note: the L1 precompile behavior may change, but not in incompatible ways. + // We want to enforce the subset that represents the EVM behavior activated in L2. + // Below is a copy of the Cancun behavior. L1 might expand on that at a later point. + + if len(input) != blobVerifyInputLength { + return nil, errBlobVerifyInvalidInputLength + } + // versioned hash: first 32 bytes + var versionedHash common.Hash + copy(versionedHash[:], input[:]) + + var ( + point kzg4844.Point + claim kzg4844.Claim + ) + // Evaluation point: next 32 bytes + copy(point[:], input[32:]) + // Expected output: next 32 bytes + copy(claim[:], input[64:]) + + // input kzg point: next 48 bytes + var commitment kzg4844.Commitment + copy(commitment[:], input[96:]) + if eth.KZGToVersionedHash(commitment) != versionedHash { + return nil, errBlobVerifyMismatchedVersion + } + + // Proof: next 48 bytes + var proof kzg4844.Proof + copy(proof[:], input[144:]) + + // Modification note: below replaces the kzg4844.VerifyProof call + result, ok := b.Oracle.Precompile(kzgPointEvaluationPrecompileAddress, input) + if !ok { + return nil, fmt.Errorf("%w: invalid KZG point evaluation", errBlobVerifyKZGProof) + } + if !bytes.Equal(result, common.FromHex(blobPrecompileReturnValue)) { + panic("unexpected result from KZG point evaluation check") + } + return result, nil +} diff --git a/op-program/client/l2/engineapi/test/l2_engine_api_tests.go b/op-program/client/l2/engineapi/test/l2_engine_api_tests.go index 2bdc784886e4..1d8a9ff61ff7 100644 --- a/op-program/client/l2/engineapi/test/l2_engine_api_tests.go +++ b/op-program/client/l2/engineapi/test/l2_engine_api_tests.go @@ -4,6 +4,7 @@ import ( "context" "testing" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -26,11 +27,15 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. api.assert.Equal(block.BlockHash, api.headHash(), "should create and import new block") }) + zero := uint64(0) + rollupCfg := &rollup.Config{ + RegolithTime: &zero, // activate Regolith upgrade + } t.Run("IncludeRequiredTransactions", func(t *testing.T) { api := newTestHelper(t, createBackend) genesis := api.backend.CurrentHeader() - txData, err := derive.L1InfoDeposit(1, eth.HeaderBlockInfo(genesis), eth.SystemConfig{}, true) + txData, err := derive.L1InfoDeposit(rollupCfg, eth.SystemConfig{}, 1, eth.HeaderBlockInfo(genesis), 0) api.assert.NoError(err) tx := types.NewTx(txData) block := api.addBlock(tx) @@ -48,7 +53,7 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. api := newTestHelper(t, createBackend) genesis := api.backend.CurrentHeader() - txData, err := derive.L1InfoDeposit(1, eth.HeaderBlockInfo(genesis), eth.SystemConfig{}, true) + txData, err := derive.L1InfoDeposit(rollupCfg, eth.SystemConfig{}, 1, eth.HeaderBlockInfo(genesis), 0) api.assert.NoError(err) txData.Gas = uint64(gasLimit + 1) tx := types.NewTx(txData) @@ -100,7 +105,8 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. payloadID := api.startBlockBuilding(genesis, eth.Uint64Quantity(genesis.Time+3)) api.assert.Equal(block.BlockHash, api.headHash(), "should not reset chain head when building starts") - payload := api.getPayload(payloadID) + envelope := api.getPayload(payloadID) + payload := envelope.ExecutionPayload api.assert.Equal(genesis.Hash(), payload.ParentHash, "should have old block as parent") api.newPayload(payload) @@ -131,11 +137,12 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. // Build a valid block payloadID := api.startBlockBuilding(genesis, eth.Uint64Quantity(genesis.Time+2)) - newBlock := api.getPayload(payloadID) + envelope := api.getPayload(payloadID) + newBlock := envelope.ExecutionPayload // But then make it invalid by changing the state root newBlock.StateRoot = eth.Bytes32(genesis.TxHash) - updateBlockHash(newBlock) + updateBlockHash(envelope) r, err := api.engine.NewPayloadV2(api.ctx, newBlock) api.assert.NoError(err) @@ -148,11 +155,12 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. // Start with a valid time payloadID := api.startBlockBuilding(genesis, eth.Uint64Quantity(genesis.Time+1)) - newBlock := api.getPayload(payloadID) + envelope := api.getPayload(payloadID) + newBlock := envelope.ExecutionPayload // Then make it invalid to check NewPayload rejects it newBlock.Timestamp = eth.Uint64Quantity(genesis.Time) - updateBlockHash(newBlock) + updateBlockHash(envelope) r, err := api.engine.NewPayloadV2(api.ctx, newBlock) api.assert.NoError(err) @@ -165,11 +173,12 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. // Start with a valid time payloadID := api.startBlockBuilding(genesis, eth.Uint64Quantity(genesis.Time+1)) - newBlock := api.getPayload(payloadID) + envelope := api.getPayload(payloadID) + newBlock := envelope.ExecutionPayload // Then make it invalid to check NewPayload rejects it newBlock.Timestamp = eth.Uint64Quantity(genesis.Time - 1) - updateBlockHash(newBlock) + updateBlockHash(envelope) r, err := api.engine.NewPayloadV2(api.ctx, newBlock) api.assert.NoError(err) @@ -293,10 +302,10 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. } // Updates the block hash to the expected value based on the other fields in the payload -func updateBlockHash(newBlock *eth.ExecutionPayload) { +func updateBlockHash(envelope *eth.ExecutionPayloadEnvelope) { // And fix up the block hash - newHash, _ := newBlock.CheckBlockHash() - newBlock.BlockHash = newHash + newHash, _ := envelope.CheckBlockHash() + envelope.ExecutionPayload.BlockHash = newHash } type testHelper struct { @@ -308,10 +317,10 @@ type testHelper struct { } func newTestHelper(t *testing.T, createBackend func(t *testing.T) engineapi.EngineBackend) *testHelper { - logger := testlog.Logger(t, log.LvlDebug) + logger := testlog.Logger(t, log.LevelDebug) ctx := context.Background() backend := createBackend(t) - api := engineapi.NewL2EngineAPI(logger, backend) + api := engineapi.NewL2EngineAPI(logger, backend, nil) test := &testHelper{ t: t, ctx: ctx, @@ -347,7 +356,9 @@ func (h *testHelper) addBlockWithParent(head *types.Header, timestamp eth.Uint64 prevHead := h.backend.CurrentHeader() id := h.startBlockBuilding(head, timestamp, txs...) - block := h.getPayload(id) + envelope := h.getPayload(id) + block := envelope.ExecutionPayload + h.assert.Equal(timestamp, block.Timestamp, "should create block with correct timestamp") h.assert.Equal(head.Hash(), block.ParentHash, "should have correct parent") h.assert.Len(block.Transactions, len(txs)) @@ -410,13 +421,13 @@ func (h *testHelper) startBlockBuilding(head *types.Header, newBlockTimestamp et return id } -func (h *testHelper) getPayload(id *eth.PayloadID) *eth.ExecutionPayload { +func (h *testHelper) getPayload(id *eth.PayloadID) *eth.ExecutionPayloadEnvelope { h.Log("getPayload", "id", id) envelope, err := h.engine.GetPayloadV2(h.ctx, *id) h.assert.NoError(err) h.assert.NotNil(envelope) h.assert.NotNil(envelope.ExecutionPayload) - return envelope.ExecutionPayload + return envelope } func (h *testHelper) newPayload(block *eth.ExecutionPayload) { diff --git a/op-program/client/l2/test/stub_oracle.go b/op-program/client/l2/test/stub_oracle.go index c681bc8d76f7..95610b6119ad 100644 --- a/op-program/client/l2/test/stub_oracle.go +++ b/op-program/client/l2/test/stub_oracle.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" ) @@ -122,3 +123,23 @@ func (o *StubStateOracle) CodeByHash(hash common.Hash) []byte { } return data } + +type StubPrecompileOracle struct { + t *testing.T + Results map[common.Hash]PrecompileResult + Calls int +} + +type PrecompileResult struct { + Result []byte + Ok bool +} + +func (o *StubPrecompileOracle) Precompile(address common.Address, input []byte) ([]byte, bool) { + result, ok := o.Results[crypto.Keccak256Hash(append(address.Bytes(), input...))] + if !ok { + o.t.Fatalf("no value for point evaluation %v", input) + } + o.Calls++ + return result.Result, result.Ok +} diff --git a/op-program/client/mpt/trie.go b/op-program/client/mpt/trie.go index 7f957cd630c2..daa530f42baf 100644 --- a/op-program/client/mpt/trie.go +++ b/op-program/client/mpt/trie.go @@ -116,9 +116,10 @@ func (n noResetHasher) Reset() {} func WriteTrie(values []hexutil.Bytes) (common.Hash, []hexutil.Bytes) { var out []hexutil.Bytes st := noResetHasher{trie.NewStackTrie( - func(path []byte, hash common.Hash, blob []byte) { - out = append(out, common.CopyBytes(blob)) // the stack hasher may mutate the blob bytes, so copy them. - })} + trie.NewStackTrieOptions().WithWriter( + func(path []byte, hash common.Hash, blob []byte) { + out = append(out, common.CopyBytes(blob)) // the stack hasher may mutate the blob bytes, so copy them. + }))} root := types.DeriveSha(rawList(values), st) return root, out } diff --git a/op-program/client/program.go b/op-program/client/program.go index 7d037a7b6ebe..a471941f2005 100644 --- a/op-program/client/program.go +++ b/op-program/client/program.go @@ -40,7 +40,6 @@ func Main(logger log.Logger) { // RunProgram executes the Program, while attached to an IO based pre-image oracle, to be served by a host. func RunProgram(logger log.Logger, preimageOracle io.ReadWriter, preimageHinter io.ReadWriter) error { - pClient := preimage.NewOracleClient(preimageOracle) hClient := preimage.NewHintWriter(preimageHinter) l1PreimageOracle := l1.NewCachingOracle(l1.NewPreimageOracle(pClient, hClient)) @@ -64,14 +63,15 @@ func RunProgram(logger log.Logger, preimageOracle io.ReadWriter, preimageHinter // runDerivation executes the L2 state transition, given a minimal interface to retrieve data. func runDerivation(logger log.Logger, cfg *rollup.Config, l2Cfg *params.ChainConfig, l1Head common.Hash, l2OutputRoot common.Hash, l2Claim common.Hash, l2ClaimBlockNum uint64, l1Oracle l1.Oracle, l2Oracle l2.Oracle) error { l1Source := l1.NewOracleL1Client(logger, l1Oracle, l1Head) - engineBackend, err := l2.NewOracleBackedL2Chain(logger, l2Oracle, l2Cfg, l2OutputRoot) + l1BlobsSource := l1.NewBlobFetcher(logger, l1Oracle) + engineBackend, err := l2.NewOracleBackedL2Chain(logger, l2Oracle, l1Oracle /* kzg oracle */, l2Cfg, l2OutputRoot) if err != nil { return fmt.Errorf("failed to create oracle-backed L2 chain: %w", err) } l2Source := l2.NewOracleEngine(cfg, logger, engineBackend) logger.Info("Starting derivation") - d := cldr.NewDriver(logger, cfg, l1Source, l2Source, l2ClaimBlockNum) + d := cldr.NewDriver(logger, cfg, l1Source, l1BlobsSource, l2Source, l2ClaimBlockNum) for { if err = d.Step(context.Background()); errors.Is(err, io.EOF) { break @@ -79,7 +79,7 @@ func runDerivation(logger log.Logger, cfg *rollup.Config, l2Cfg *params.ChainCon return err } } - return d.ValidateClaim(eth.Bytes32(l2Claim)) + return d.ValidateClaim(l2ClaimBlockNum, eth.Bytes32(l2Claim)) } func CreateHinterChannel() oppio.FileChannel { diff --git a/op-program/host/cmd/main.go b/op-program/host/cmd/main.go index 19d0f188730b..75dc1383983e 100644 --- a/op-program/host/cmd/main.go +++ b/op-program/host/cmd/main.go @@ -64,6 +64,6 @@ func run(args []string, action ConfigAction) error { func setupLogging(ctx *cli.Context) (log.Logger, error) { logCfg := oplog.ReadCLIConfig(ctx) logger := oplog.NewLogger(oplog.AppOut(ctx), logCfg) - oplog.SetGlobalLogHandler(logger.GetHandler()) + oplog.SetGlobalLogHandler(logger.Handler()) return logger, nil } diff --git a/op-program/host/cmd/main_test.go b/op-program/host/cmd/main_test.go index 081136af117b..928158c7cd01 100644 --- a/op-program/host/cmd/main_test.go +++ b/op-program/host/cmd/main_test.go @@ -9,7 +9,9 @@ import ( "github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-program/chainconfig" "github.com/ethereum-optimism/optimism/op-program/host/config" + oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/log" @@ -48,7 +50,12 @@ func TestLogFormat(t *testing.T) { verifyArgsInvalid(t, `unrecognized log-format: "foo"`, addRequiredArgs("--log.format=foo")) }) - for _, lvl := range []string{"json", "json-pretty", "terminal", "text", "logfmt"} { + for _, lvl := range []string{ + oplog.FormatJSON.String(), + oplog.FormatTerminal.String(), + oplog.FormatText.String(), + oplog.FormatLogFmt.String(), + } { lvl := lvl t.Run("AcceptValid_"+lvl, func(t *testing.T) { logger, _, err := runWithArgs(addRequiredArgs("--log.format", lvl)) @@ -239,6 +246,16 @@ func TestL2Claim(t *testing.T) { t.Run("Invalid", func(t *testing.T) { verifyArgsInvalid(t, config.ErrInvalidL2Claim.Error(), replaceRequiredArg("--l2.claim", "something")) }) + + t.Run("Allows all zero without prefix", func(t *testing.T) { + cfg := configForArgs(t, replaceRequiredArg("--l2.claim", "0000000000000000000000000000000000000000000000000000000000000000")) + require.EqualValues(t, common.Hash{}, cfg.L2Claim) + }) + + t.Run("Allows all zero with prefix", func(t *testing.T) { + cfg := configForArgs(t, replaceRequiredArg("--l2.claim", "0x0000000000000000000000000000000000000000000000000000000000000000")) + require.EqualValues(t, common.Hash{}, cfg.L2Claim) + }) } func TestL2BlockNumber(t *testing.T) { diff --git a/op-program/host/config/config.go b/op-program/host/config/config.go index 84d7c2e32908..25f1a75724c9 100644 --- a/op-program/host/config/config.go +++ b/op-program/host/config/config.go @@ -35,17 +35,17 @@ var ( type Config struct { Rollup *rollup.Config // DataDir is the directory to read/write pre-image data from/to. - //If not set, an in-memory key-value store is used and fetching data must be enabled + // If not set, an in-memory key-value store is used and fetching data must be enabled DataDir string - // L1Head is the block has of the L1 chain head block - L1Head common.Hash - L1URL string - L1TrustRPC bool - L1RPCKind sources.RPCProviderKind + // L1Head is the block hash of the L1 chain head block + L1Head common.Hash + L1URL string + L1BeaconURL string + L1TrustRPC bool + L1RPCKind sources.RPCProviderKind // L2Head is the l2 block hash contained in the L2 Output referenced by the L2OutputRoot - // TODO(inphi): This can be made optional with hardcoded rollup configs and output oracle addresses by searching the oracle for the l2 output root L2Head common.Hash // L2OutputRoot is the agreed L2 output root to start derivation from L2OutputRoot common.Hash @@ -85,9 +85,6 @@ func (c *Config) Check() error { if c.L2OutputRoot == (common.Hash{}) { return ErrInvalidL2OutputRoot } - if c.L2Claim == (common.Hash{}) { - return ErrInvalidL2Claim - } if c.L2ClaimBlockNumber == 0 { return ErrInvalidL2ClaimBlock } @@ -107,6 +104,7 @@ func (c *Config) Check() error { } func (c *Config) FetchingEnabled() bool { + // TODO: Include Beacon URL once cancun is active on all chains we fault prove. return c.L1URL != "" && c.L2URL != "" } @@ -139,7 +137,7 @@ func NewConfigFromCLI(log log.Logger, ctx *cli.Context) (*Config, error) { if err := flags.CheckRequired(ctx); err != nil { return nil, err } - rollupCfg, err := opnode.NewRollupConfig(log, ctx) + rollupCfg, err := opnode.NewRollupConfigFromCLI(log, ctx) if err != nil { return nil, err } @@ -151,9 +149,13 @@ func NewConfigFromCLI(log log.Logger, ctx *cli.Context) (*Config, error) { if l2OutputRoot == (common.Hash{}) { return nil, ErrInvalidL2OutputRoot } - l2Claim := common.HexToHash(ctx.String(flags.L2Claim.Name)) - if l2Claim == (common.Hash{}) { - return nil, ErrInvalidL2Claim + strClaim := ctx.String(flags.L2Claim.Name) + l2Claim := common.HexToHash(strClaim) + // Require a valid hash, with the zero hash explicitly allowed. + if l2Claim == (common.Hash{}) && + strClaim != "0x0000000000000000000000000000000000000000000000000000000000000000" && + strClaim != "0000000000000000000000000000000000000000000000000000000000000000" { + return nil, fmt.Errorf("%w: %v", ErrInvalidL2Claim, strClaim) } l2ClaimBlockNum := ctx.Uint64(flags.L2BlockNumber.Name) l1Head := common.HexToHash(ctx.String(flags.L1Head.Name)) @@ -192,6 +194,7 @@ func NewConfigFromCLI(log log.Logger, ctx *cli.Context) (*Config, error) { L2ClaimBlockNumber: l2ClaimBlockNum, L1Head: l1Head, L1URL: ctx.String(flags.L1NodeAddr.Name), + L1BeaconURL: ctx.String(flags.L1BeaconAddr.Name), L1TrustRPC: ctx.Bool(flags.L1TrustRPC.Name), L1RPCKind: sources.RPCProviderKind(ctx.String(flags.L1RPCProviderKind.Name)), ExecCmd: ctx.String(flags.Exec.Name), diff --git a/op-program/host/config/config_test.go b/op-program/host/config/config_test.go index 13f7cdcb657f..2b85da110778 100644 --- a/op-program/host/config/config_test.go +++ b/op-program/host/config/config_test.go @@ -65,11 +65,11 @@ func TestL2OutputRootRequired(t *testing.T) { require.ErrorIs(t, err, ErrInvalidL2OutputRoot) } -func TestL2ClaimRequired(t *testing.T) { +// The L2 claim may be provided by a dishonest actor so we must treat 0x00...00 as a real value. +func TestL2ClaimMayBeDefaultValue(t *testing.T) { config := validConfig() config.L2Claim = common.Hash{} - err := config.Check() - require.ErrorIs(t, err, ErrInvalidL2Claim) + require.NoError(t, config.Check()) } func TestL2ClaimBlockNumberRequired(t *testing.T) { diff --git a/op-program/host/flags/flags.go b/op-program/host/flags/flags.go index a4340be84cff..3356bbfda8a9 100644 --- a/op-program/host/flags/flags.go +++ b/op-program/host/flags/flags.go @@ -75,6 +75,11 @@ var ( Usage: "Address of L1 JSON-RPC endpoint to use (eth namespace required)", EnvVars: prefixEnvVars("L1_RPC"), } + L1BeaconAddr = &cli.StringFlag{ + Name: "l1.beacon", + Usage: "Address of L1 Beacon API endpoint to use", + EnvVars: prefixEnvVars("L1_BEACON_API"), + } L1TrustRPC = &cli.BoolFlag{ Name: "l1.trustrpc", Usage: "Trust the L1 RPC, sync faster at risk of malicious/buggy RPC providing bad or inconsistent L1 data", @@ -112,6 +117,7 @@ var requiredFlags = []cli.Flag{ L2Claim, L2BlockNumber, } + var programFlags = []cli.Flag{ RollupConfig, Network, @@ -119,6 +125,7 @@ var programFlags = []cli.Flag{ L2NodeAddr, L2GenesisPath, L1NodeAddr, + L1BeaconAddr, L1TrustRPC, L1RPCProviderKind, Exec, diff --git a/op-program/host/flags/flags_test.go b/op-program/host/flags/flags_test.go index 0fc39cf945ab..da307a6abce5 100644 --- a/op-program/host/flags/flags_test.go +++ b/op-program/host/flags/flags_test.go @@ -12,12 +12,13 @@ import ( func TestUniqueFlags(t *testing.T) { seenCLI := make(map[string]struct{}) for _, flag := range Flags { - name := flag.Names()[0] - if _, ok := seenCLI[name]; ok { - t.Errorf("duplicate flag %s", name) - continue + for _, name := range flag.Names() { + if _, ok := seenCLI[name]; ok { + t.Errorf("duplicate flag %s", name) + continue + } + seenCLI[name] = struct{}{} } - seenCLI[name] = struct{}{} } } diff --git a/op-program/host/host.go b/op-program/host/host.go index ede7961f46b6..2933d0be59b0 100644 --- a/op-program/host/host.go +++ b/op-program/host/host.go @@ -12,7 +12,6 @@ import ( "github.com/ethereum-optimism/optimism/op-node/chaincfg" preimage "github.com/ethereum-optimism/optimism/op-preimage" cl "github.com/ethereum-optimism/optimism/op-program/client" - "github.com/ethereum-optimism/optimism/op-program/client/driver" "github.com/ethereum-optimism/optimism/op-program/host/config" "github.com/ethereum-optimism/optimism/op-program/host/flags" "github.com/ethereum-optimism/optimism/op-program/host/kvstore" @@ -44,13 +43,10 @@ func Main(logger log.Logger, cfg *config.Config) error { return PreimageServer(ctx, logger, cfg, preimageChan, hinterChan) } - if err := FaultProofProgram(ctx, logger, cfg); errors.Is(err, driver.ErrClaimNotValid) { - log.Crit("Claim is invalid", "err", err) - } else if err != nil { + if err := FaultProofProgram(ctx, logger, cfg); err != nil { return err - } else { - log.Info("Claim successfully verified") } + log.Info("Claim successfully verified") return nil } @@ -174,7 +170,7 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, localPreimageSource := kvstore.NewLocalPreimageSource(cfg) splitter := kvstore.NewPreimageSourceSplitter(localPreimageSource.Get, getPreimage) - preimageGetter := splitter.Get + preimageGetter := preimage.WithVerification(splitter.Get) serverDone = launchOracleServer(logger, preimageChannel, preimageGetter) hinterDone = routeHints(logger, hintChannel, hinter) @@ -205,12 +201,14 @@ func makePrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg * if err != nil { return nil, fmt.Errorf("failed to create L1 client: %w", err) } + l1Beacon := sources.NewBeaconHTTPClient(client.NewBasicHTTPClient(cfg.L1BeaconURL, logger)) + l1BlobFetcher := sources.NewL1BeaconClient(l1Beacon, sources.L1BeaconClientConfig{FetchAllSidecars: false}) l2Cl, err := NewL2Client(l2RPC, logger, nil, &L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) if err != nil { return nil, fmt.Errorf("failed to create L2 client: %w", err) } l2DebugCl := &L2Source{L2Client: l2Cl, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} - return prefetcher.NewPrefetcher(logger, l1Cl, l2DebugCl, kv), nil + return prefetcher.NewPrefetcher(logger, l1Cl, l1BlobFetcher, l2DebugCl, kv), nil } func routeHints(logger log.Logger, hHostRW io.ReadWriter, hinter preimage.HintHandler) chan error { diff --git a/op-program/host/host_test.go b/op-program/host/host_test.go index b3fd3d83396e..c46ebe781190 100644 --- a/op-program/host/host_test.go +++ b/op-program/host/host_test.go @@ -35,7 +35,7 @@ func TestServerMode(t *testing.T) { hintServer, hintClient, err := io.CreateBidirectionalChannel() require.NoError(t, err) defer hintClient.Close() - logger := testlog.Logger(t, log.LvlTrace) + logger := testlog.Logger(t, log.LevelTrace) result := make(chan error) go func() { result <- PreimageServer(context.Background(), logger, cfg, preimageServer, hintServer) diff --git a/op-program/host/kvstore/mem.go b/op-program/host/kvstore/mem.go index 6071db4e1512..9af540e235fa 100644 --- a/op-program/host/kvstore/mem.go +++ b/op-program/host/kvstore/mem.go @@ -1,6 +1,7 @@ package kvstore import ( + "slices" "sync" "github.com/ethereum/go-ethereum/common" @@ -23,7 +24,7 @@ func NewMemKV() *MemKV { func (m *MemKV) Put(k common.Hash, v []byte) error { m.Lock() defer m.Unlock() - m.m[k] = v + m.m[k] = slices.Clone(v) return nil } @@ -34,5 +35,5 @@ func (m *MemKV) Get(k common.Hash) ([]byte, error) { if !ok { return nil, ErrNotFound } - return v, nil + return slices.Clone(v), nil } diff --git a/op-program/host/l2_client.go b/op-program/host/l2_client.go index 162cfe6d3154..e71cbd28d684 100644 --- a/op-program/host/l2_client.go +++ b/op-program/host/l2_client.go @@ -40,10 +40,12 @@ func (s *L2Client) OutputByRoot(ctx context.Context, l2OutputRoot common.Hash) ( if err != nil { return nil, err } - if eth.OutputRoot(output) != eth.Bytes32(l2OutputRoot) { + actualOutputRoot := eth.OutputRoot(output) + if actualOutputRoot != eth.Bytes32(l2OutputRoot) { // For fault proofs, we only reference outputs at the l2 head at boot time // The caller shouldn't be requesting outputs at any other block - return nil, fmt.Errorf("unknown output root") + // If they are, there is no chance of recovery and we should panic to avoid retrying forever + panic(fmt.Errorf("output root %v from specified L2 block %v does not match requested output root %v", actualOutputRoot, s.l2Head, l2OutputRoot)) } return output, nil } diff --git a/op-program/host/prefetcher/prefetcher.go b/op-program/host/prefetcher/prefetcher.go index 540133112a75..293b78eee034 100644 --- a/op-program/host/prefetcher/prefetcher.go +++ b/op-program/host/prefetcher/prefetcher.go @@ -2,8 +2,10 @@ package prefetcher import ( "context" + "encoding/binary" "errors" "fmt" + "slices" "strings" preimage "github.com/ethereum-optimism/optimism/op-preimage" @@ -15,10 +17,23 @@ import ( "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/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" ) +var ( + precompileSuccess = [1]byte{1} + precompileFailure = [1]byte{0} +) + +var acceleratedPrecompiles = []common.Address{ + common.BytesToAddress([]byte{0x1}), // ecrecover + common.BytesToAddress([]byte{0x8}), // bn256Pairing + common.BytesToAddress([]byte{0x0a}), // KZG Point Evaluation +} + type L1Source interface { InfoByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, error) InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) @@ -26,6 +41,11 @@ type L1Source interface { PreFetchReceipts(ctx context.Context, blockHash common.Hash) (bool, error) } +type L1BlobSource interface { + GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) + GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) +} + type L2Source interface { InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) @@ -34,19 +54,21 @@ type L2Source interface { } type Prefetcher struct { - logger log.Logger - l1Fetcher L1Source - l2Fetcher L2Source - lastHint string - kvStore kvstore.KV + logger log.Logger + l1Fetcher L1Source + l1BlobFetcher L1BlobSource + l2Fetcher L2Source + lastHint string + kvStore kvstore.KV } -func NewPrefetcher(logger log.Logger, l1Fetcher L1Source, l2Fetcher L2Source, kvStore kvstore.KV) *Prefetcher { +func NewPrefetcher(logger log.Logger, l1Fetcher L1Source, l1BlobFetcher L1BlobSource, l2Fetcher L2Source, kvStore kvstore.KV) *Prefetcher { return &Prefetcher{ - logger: logger, - l1Fetcher: NewRetryingL1Source(logger, l1Fetcher), - l2Fetcher: NewRetryingL2Source(logger, l2Fetcher), - kvStore: kvStore, + logger: logger, + l1Fetcher: NewRetryingL1Source(logger, l1Fetcher), + l1BlobFetcher: NewRetryingL1BlobSource(logger, l1BlobFetcher), + l2Fetcher: NewRetryingL2Source(logger, l2Fetcher), + kvStore: kvStore, } } @@ -76,13 +98,17 @@ func (p *Prefetcher) GetPreimage(ctx context.Context, key common.Hash) ([]byte, } func (p *Prefetcher) prefetch(ctx context.Context, hint string) error { - hintType, hash, err := parseHint(hint) + hintType, hintBytes, err := parseHint(hint) if err != nil { return err } - p.logger.Debug("Prefetching", "type", hintType, "hash", hash) + p.logger.Debug("Prefetching", "type", hintType, "bytes", hexutil.Bytes(hintBytes)) switch hintType { case l1.HintL1BlockHeader: + if len(hintBytes) != 32 { + return fmt.Errorf("invalid L1 block hint: %x", hint) + } + hash := common.Hash(hintBytes) header, err := p.l1Fetcher.InfoByHash(ctx, hash) if err != nil { return fmt.Errorf("failed to fetch L1 block %s header: %w", hash, err) @@ -93,18 +119,98 @@ func (p *Prefetcher) prefetch(ctx context.Context, hint string) error { } return p.kvStore.Put(preimage.Keccak256Key(hash).PreimageKey(), data) case l1.HintL1Transactions: + if len(hintBytes) != 32 { + return fmt.Errorf("invalid L1 transactions hint: %x", hint) + } + hash := common.Hash(hintBytes) _, txs, err := p.l1Fetcher.InfoAndTxsByHash(ctx, hash) if err != nil { return fmt.Errorf("failed to fetch L1 block %s txs: %w", hash, err) } return p.storeTransactions(txs) case l1.HintL1Receipts: + if len(hintBytes) != 32 { + return fmt.Errorf("invalid L1 receipts hint: %x", hint) + } + hash := common.Hash(hintBytes) _, receipts, err := p.l1Fetcher.FetchReceipts(ctx, hash) if err != nil { return fmt.Errorf("failed to fetch L1 block %s receipts: %w", hash, err) } return p.storeReceipts(receipts) + case l1.HintL1Blob: + if len(hintBytes) != 48 { + return fmt.Errorf("invalid blob hint: %x", hint) + } + + blobVersionHash := common.Hash(hintBytes[:32]) + blobHashIndex := binary.BigEndian.Uint64(hintBytes[32:40]) + refTimestamp := binary.BigEndian.Uint64(hintBytes[40:48]) + + // Fetch the blob sidecar for the indexed blob hash passed in the hint. + indexedBlobHash := eth.IndexedBlobHash{ + Hash: blobVersionHash, + Index: blobHashIndex, + } + // We pass an `eth.L1BlockRef`, but `GetBlobSidecars` only uses the timestamp, which we received in the hint. + sidecars, err := p.l1BlobFetcher.GetBlobSidecars(ctx, eth.L1BlockRef{Time: refTimestamp}, []eth.IndexedBlobHash{indexedBlobHash}) + if err != nil || len(sidecars) != 1 { + return fmt.Errorf("failed to fetch blob sidecars for %s %d: %w", blobVersionHash, blobHashIndex, err) + } + sidecar := sidecars[0] + + // Put the preimage for the versioned hash into the kv store + if err = p.kvStore.Put(preimage.Sha256Key(blobVersionHash).PreimageKey(), sidecar.KZGCommitment[:]); err != nil { + return err + } + + // Put all of the blob's field elements into the kv store. There should be 4096. The preimage oracle key for + // each field element is the keccak256 hash of `abi.encodePacked(sidecar.KZGCommitment, uint256(i))` + blobKey := make([]byte, 80) + copy(blobKey[:48], sidecar.KZGCommitment[:]) + for i := 0; i < params.BlobTxFieldElementsPerBlob; i++ { + binary.BigEndian.PutUint64(blobKey[72:], uint64(i)) + blobKeyHash := crypto.Keccak256Hash(blobKey) + if err := p.kvStore.Put(preimage.Keccak256Key(blobKeyHash).PreimageKey(), blobKey); err != nil { + return err + } + if err = p.kvStore.Put(preimage.BlobKey(blobKeyHash).PreimageKey(), sidecar.Blob[i<<5:(i+1)<<5]); err != nil { + return err + } + } + return nil + case l1.HintL1Precompile: + if len(hintBytes) < 20 { + return fmt.Errorf("invalid precompile hint: %x", hint) + } + precompileAddress := common.BytesToAddress(hintBytes[:20]) + // For extra safety, avoid accelerating unexpected precompiles + if !slices.Contains(acceleratedPrecompiles, precompileAddress) { + return fmt.Errorf("unsupported precompile address: %s", precompileAddress) + } + // NOTE: We use the precompiled contracts from Cancun because it's the only set that contains the addresses of all accelerated precompiles + // We assume the precompile Run function behavior does not change across EVM upgrades. + // As such, we must not rely on upgrade-specific behavior such as precompile.RequiredGas. + precompile := getPrecompiledContract(precompileAddress) + + // KZG Point Evaluation precompile also verifies its input + result, err := precompile.Run(hintBytes[20:]) + if err == nil { + result = append(precompileSuccess[:], result...) + } else { + result = append(precompileFailure[:], result...) + } + inputHash := crypto.Keccak256Hash(hintBytes) + // Put the input preimage so it can be loaded later + if err := p.kvStore.Put(preimage.Keccak256Key(inputHash).PreimageKey(), hintBytes); err != nil { + return err + } + return p.kvStore.Put(preimage.PrecompileKey(inputHash).PreimageKey(), result) case l2.HintL2BlockHeader, l2.HintL2Transactions: + if len(hintBytes) != 32 { + return fmt.Errorf("invalid L2 header/tx hint: %x", hint) + } + hash := common.Hash(hintBytes) header, txs, err := p.l2Fetcher.InfoAndTxsByHash(ctx, hash) if err != nil { return fmt.Errorf("failed to fetch L2 block %s: %w", hash, err) @@ -119,18 +225,30 @@ func (p *Prefetcher) prefetch(ctx context.Context, hint string) error { } return p.storeTransactions(txs) case l2.HintL2StateNode: + if len(hintBytes) != 32 { + return fmt.Errorf("invalid L2 state node hint: %x", hint) + } + hash := common.Hash(hintBytes) node, err := p.l2Fetcher.NodeByHash(ctx, hash) if err != nil { return fmt.Errorf("failed to fetch L2 state node %s: %w", hash, err) } return p.kvStore.Put(preimage.Keccak256Key(hash).PreimageKey(), node) case l2.HintL2Code: + if len(hintBytes) != 32 { + return fmt.Errorf("invalid L2 code hint: %x", hint) + } + hash := common.Hash(hintBytes) code, err := p.l2Fetcher.CodeByHash(ctx, hash) if err != nil { return fmt.Errorf("failed to fetch L2 contract code %s: %w", hash, err) } return p.kvStore.Put(preimage.Keccak256Key(hash).PreimageKey(), code) case l2.HintL2Output: + if len(hintBytes) != 32 { + return fmt.Errorf("invalid L2 output hint: %x", hint) + } + hash := common.Hash(hintBytes) output, err := p.l2Fetcher.OutputByRoot(ctx, hash) if err != nil { return fmt.Errorf("failed to fetch L2 output root %s: %w", hash, err) @@ -168,14 +286,19 @@ func (p *Prefetcher) storeTrieNodes(values []hexutil.Bytes) error { } // parseHint parses a hint string in wire protocol. Returns the hint type, requested hash and error (if any). -func parseHint(hint string) (string, common.Hash, error) { - hintType, hashStr, found := strings.Cut(hint, " ") +func parseHint(hint string) (string, []byte, error) { + hintType, bytesStr, found := strings.Cut(hint, " ") if !found { - return "", common.Hash{}, fmt.Errorf("unsupported hint: %s", hint) + return "", nil, fmt.Errorf("unsupported hint: %s", hint) } - hash := common.HexToHash(hashStr) - if hash == (common.Hash{}) { - return "", common.Hash{}, fmt.Errorf("invalid hash: %s", hashStr) + + hintBytes, err := hexutil.Decode(bytesStr) + if err != nil { + return "", make([]byte, 0), fmt.Errorf("invalid bytes: %s", bytesStr) } - return hintType, hash, nil + return hintType, hintBytes, nil +} + +func getPrecompiledContract(address common.Address) vm.PrecompiledContract { + return vm.PrecompiledContractsCancun[address] } diff --git a/op-program/host/prefetcher/prefetcher_test.go b/op-program/host/prefetcher/prefetcher_test.go index 802638437da2..6ffb9bd5af8a 100644 --- a/op-program/host/prefetcher/prefetcher_test.go +++ b/op-program/host/prefetcher/prefetcher_test.go @@ -2,13 +2,18 @@ package prefetcher import ( "context" + "crypto/sha256" + "encoding/binary" "math/rand" "testing" + "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" + gokzg4844 "github.com/crate-crypto/go-kzg-4844" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/require" @@ -24,14 +29,14 @@ import ( func TestNoHint(t *testing.T) { t.Run("NotFound", func(t *testing.T) { - prefetcher, _, _, _ := createPrefetcher(t) + prefetcher, _, _, _, _ := createPrefetcher(t) res, err := prefetcher.GetPreimage(context.Background(), common.Hash{0xab}) require.ErrorIs(t, err, kvstore.ErrNotFound) require.Nil(t, res) }) t.Run("Exists", func(t *testing.T) { - prefetcher, _, _, kv := createPrefetcher(t) + prefetcher, _, _, _, kv := createPrefetcher(t) data := []byte{1, 2, 3} hash := crypto.Keccak256Hash(data) require.NoError(t, kv.Put(hash, data)) @@ -51,7 +56,7 @@ func TestFetchL1BlockHeader(t *testing.T) { require.NoError(t, err) t.Run("AlreadyKnown", func(t *testing.T) { - prefetcher, _, _, kv := createPrefetcher(t) + prefetcher, _, _, _, kv := createPrefetcher(t) storeBlock(t, kv, block, rcpts) oracle := l1.NewPreimageOracle(asOracleFn(t, prefetcher), asHinter(t, prefetcher)) @@ -60,7 +65,7 @@ func TestFetchL1BlockHeader(t *testing.T) { }) t.Run("Unknown", func(t *testing.T) { - prefetcher, l1Cl, _, _ := createPrefetcher(t) + prefetcher, l1Cl, _, _, _ := createPrefetcher(t) l1Cl.ExpectInfoByHash(hash, eth.HeaderBlockInfo(block.Header()), nil) defer l1Cl.AssertExpectations(t) @@ -77,7 +82,7 @@ func TestFetchL1Transactions(t *testing.T) { hash := block.Hash() t.Run("AlreadyKnown", func(t *testing.T) { - prefetcher, _, _, kv := createPrefetcher(t) + prefetcher, _, _, _, kv := createPrefetcher(t) storeBlock(t, kv, block, rcpts) @@ -89,7 +94,7 @@ func TestFetchL1Transactions(t *testing.T) { }) t.Run("Unknown", func(t *testing.T) { - prefetcher, l1Cl, _, _ := createPrefetcher(t) + prefetcher, l1Cl, _, _, _ := createPrefetcher(t) l1Cl.ExpectInfoByHash(hash, eth.BlockToInfo(block), nil) l1Cl.ExpectInfoAndTxsByHash(hash, eth.BlockToInfo(block), block.Transactions(), nil) defer l1Cl.AssertExpectations(t) @@ -107,7 +112,7 @@ func TestFetchL1Receipts(t *testing.T) { hash := block.Hash() t.Run("AlreadyKnown", func(t *testing.T) { - prefetcher, _, _, kv := createPrefetcher(t) + prefetcher, _, _, _, kv := createPrefetcher(t) storeBlock(t, kv, block, receipts) // Check the data is available (note the oracle does not know about the block, only the kvstore does) @@ -118,7 +123,7 @@ func TestFetchL1Receipts(t *testing.T) { }) t.Run("Unknown", func(t *testing.T) { - prefetcher, l1Cl, _, _ := createPrefetcher(t) + prefetcher, l1Cl, _, _, _ := createPrefetcher(t) l1Cl.ExpectInfoByHash(hash, eth.BlockToInfo(block), nil) l1Cl.ExpectInfoAndTxsByHash(hash, eth.BlockToInfo(block), block.Transactions(), nil) l1Cl.ExpectFetchReceipts(hash, eth.BlockToInfo(block), receipts, nil) @@ -133,7 +138,7 @@ func TestFetchL1Receipts(t *testing.T) { // Blocks may have identical RLP receipts for different transactions. // Check that the node already existing is handled t.Run("CommonTrieNodes", func(t *testing.T) { - prefetcher, l1Cl, _, kv := createPrefetcher(t) + prefetcher, l1Cl, _, _, kv := createPrefetcher(t) l1Cl.ExpectInfoByHash(hash, eth.BlockToInfo(block), nil) l1Cl.ExpectInfoAndTxsByHash(hash, eth.BlockToInfo(block), block.Transactions(), nil) l1Cl.ExpectFetchReceipts(hash, eth.BlockToInfo(block), receipts, nil) @@ -153,13 +158,172 @@ func TestFetchL1Receipts(t *testing.T) { }) } +// Globally initialize a kzgCtx for blob tests. +var kzgCtx, _ = gokzg4844.NewContext4096Secure() + +// Returns a serialized random field element in big-endian +func GetRandFieldElement(seed int64) [32]byte { + var r fr.Element + _, _ = r.SetRandom() + return gokzg4844.SerializeScalar(r) +} + +func GetRandBlob(seed int64) gokzg4844.Blob { + var blob gokzg4844.Blob + bytesPerBlob := gokzg4844.ScalarsPerBlob * gokzg4844.SerializedScalarSize + for i := 0; i < bytesPerBlob; i += gokzg4844.SerializedScalarSize { + fieldElementBytes := GetRandFieldElement(seed + int64(i)) + copy(blob[i:i+gokzg4844.SerializedScalarSize], fieldElementBytes[:]) + } + return blob +} + +func TestFetchL1Blob(t *testing.T) { + blob := GetRandBlob(0xf00f00) + commitment, err := kzgCtx.BlobToKZGCommitment(blob, 0) + require.NoError(t, err) + versionedHash := sha256.Sum256(commitment[:]) + versionedHash[0] = params.BlobTxHashVersion + blobHash := eth.IndexedBlobHash{Hash: versionedHash, Index: 0xFACADE} + l1Ref := eth.L1BlockRef{Time: 0} + + t.Run("AlreadyKnown", func(t *testing.T) { + prefetcher, _, blobFetcher, _, kv := createPrefetcher(t) + storeBlob(t, kv, (eth.Bytes48)(commitment), (*eth.Blob)(&blob)) + + oracle := l1.NewPreimageOracle(asOracleFn(t, prefetcher), asHinter(t, prefetcher)) + defer blobFetcher.AssertExpectations(t) + + blobs := oracle.GetBlob(l1Ref, blobHash) + require.EqualValues(t, blobs[:], blob[:]) + }) + + t.Run("Unknown", func(t *testing.T) { + prefetcher, _, blobFetcher, _, _ := createPrefetcher(t) + + oracle := l1.NewPreimageOracle(asOracleFn(t, prefetcher), asHinter(t, prefetcher)) + blobFetcher.ExpectOnGetBlobSidecars( + context.Background(), + l1Ref, + []eth.IndexedBlobHash{blobHash}, + (eth.Bytes48)(commitment), + []*eth.Blob{(*eth.Blob)(&blob)}, + nil, + ) + defer blobFetcher.AssertExpectations(t) + + blobs := oracle.GetBlob(l1Ref, blobHash) + require.EqualValues(t, blobs[:], blob[:]) + + // Check that the preimages of field element keys are also stored + // This makes it possible for the challenger to extract the commitment and required field from the + // oracle key rather than needing the hint data. + + fieldElemKey := make([]byte, 80) + copy(fieldElemKey[:48], commitment[:]) + for i := 0; i < params.BlobTxFieldElementsPerBlob; i++ { + binary.BigEndian.PutUint64(fieldElemKey[72:], uint64(i)) + key := preimage.Keccak256Key(crypto.Keccak256(fieldElemKey)).PreimageKey() + actual, err := prefetcher.kvStore.Get(key) + require.NoError(t, err) + require.Equal(t, fieldElemKey, actual) + } + }) +} + +func TestFetchPrecompileResult(t *testing.T) { + ecRecoverInput := common.FromHex("18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549") + kzgPointEvalInput := common.FromHex("01e798154708fe7789429634053cbf9f99b619f9f084048927333fce637f549b564c0a11a0f704f4fc3e8acfe0f8245f0ad1347b378fbf96e206da11a5d3630624d25032e67a7e6a4910df5834b8fe70e6bcfeeac0352434196bdf4b2485d5a18f59a8d2a1a625a17f3fea0fe5eb8c896db3764f3185481bc22f91b4aaffcca25f26936857bc3a7c2539ea8ec3a952b7873033e038326e87ed3e1276fd140253fa08e9fc25fb2d9a98527fc22a2c9612fbeafdad446cbc7bcdbdcd780af2c16a") + + failure := []byte{0} + success := []byte{1} + + tests := []struct { + name string + addr common.Address + input []byte + result []byte + }{ + { + name: "EcRecover-Valid", + addr: common.BytesToAddress([]byte{0x1}), + input: ecRecoverInput, + result: append(success, common.FromHex("000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b")...), + }, + { + name: "Bn256Pairing-Valid", + addr: common.BytesToAddress([]byte{0x8}), + input: []byte{}, // empty is valid + result: append(success, common.FromHex("0000000000000000000000000000000000000000000000000000000000000001")...), + }, + { + name: "Bn256Pairing-Invalid", + addr: common.BytesToAddress([]byte{0x8}), + input: []byte{0x1}, + result: failure, + }, + { + name: "KzgPointEvaluation-Valid", + addr: common.BytesToAddress([]byte{0xa}), + input: kzgPointEvalInput, + result: append(success, common.FromHex("000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001")...), + }, + { + name: "KzgPointEvaluation-Invalid", + addr: common.BytesToAddress([]byte{0xa}), + input: []byte{0x0}, + result: failure, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + prefetcher, _, _, _, _ := createPrefetcher(t) + oracle := l1.NewPreimageOracle(asOracleFn(t, prefetcher), asHinter(t, prefetcher)) + + result, ok := oracle.Precompile(test.addr, test.input) + require.Equal(t, test.result[0] == 1, ok) + require.EqualValues(t, test.result[1:], result) + + key := crypto.Keccak256Hash(append(test.addr.Bytes(), test.input...)) + val, err := prefetcher.kvStore.Get(preimage.Keccak256Key(key).PreimageKey()) + require.NoError(t, err) + require.NotEmpty(t, val) + + val, err = prefetcher.kvStore.Get(preimage.PrecompileKey(key).PreimageKey()) + require.NoError(t, err) + require.EqualValues(t, test.result, val) + }) + } + + t.Run("Already Known", func(t *testing.T) { + input := []byte("test input") + addr := common.BytesToAddress([]byte{0x1}) + result := []byte{0x1} + prefetcher, _, _, _, kv := createPrefetcher(t) + err := kv.Put(preimage.PrecompileKey(crypto.Keccak256Hash(append(addr.Bytes(), input...))).PreimageKey(), append([]byte{1}, result...)) + require.NoError(t, err) + + oracle := l1.NewPreimageOracle(asOracleFn(t, prefetcher), asHinter(t, prefetcher)) + actualResult, status := oracle.Precompile(addr, input) + require.EqualValues(t, actualResult, result) + require.True(t, status) + }) +} + +func TestRestrictedPrecompileContracts(t *testing.T) { + for _, addr := range acceleratedPrecompiles { + require.NotNil(t, getPrecompiledContract(addr)) + } +} + func TestFetchL2Block(t *testing.T) { rng := rand.New(rand.NewSource(123)) block, rcpts := testutils.RandomBlock(rng, 10) hash := block.Hash() t.Run("AlreadyKnown", func(t *testing.T) { - prefetcher, _, _, kv := createPrefetcher(t) + prefetcher, _, _, _, kv := createPrefetcher(t) storeBlock(t, kv, block, rcpts) oracle := l2.NewPreimageOracle(asOracleFn(t, prefetcher), asHinter(t, prefetcher)) @@ -169,7 +333,7 @@ func TestFetchL2Block(t *testing.T) { }) t.Run("Unknown", func(t *testing.T) { - prefetcher, _, l2Cl, _ := createPrefetcher(t) + prefetcher, _, _, l2Cl, _ := createPrefetcher(t) l2Cl.ExpectInfoAndTxsByHash(hash, eth.BlockToInfo(block), block.Transactions(), nil) defer l2Cl.MockL2Client.AssertExpectations(t) @@ -186,7 +350,7 @@ func TestFetchL2Transactions(t *testing.T) { hash := block.Hash() t.Run("AlreadyKnown", func(t *testing.T) { - prefetcher, _, _, kv := createPrefetcher(t) + prefetcher, _, _, _, kv := createPrefetcher(t) storeBlock(t, kv, block, rcpts) oracle := l2.NewPreimageOracle(asOracleFn(t, prefetcher), asHinter(t, prefetcher)) @@ -195,7 +359,7 @@ func TestFetchL2Transactions(t *testing.T) { }) t.Run("Unknown", func(t *testing.T) { - prefetcher, _, l2Cl, _ := createPrefetcher(t) + prefetcher, _, _, l2Cl, _ := createPrefetcher(t) l2Cl.ExpectInfoAndTxsByHash(hash, eth.BlockToInfo(block), block.Transactions(), nil) defer l2Cl.MockL2Client.AssertExpectations(t) @@ -212,7 +376,7 @@ func TestFetchL2Node(t *testing.T) { key := preimage.Keccak256Key(hash).PreimageKey() t.Run("AlreadyKnown", func(t *testing.T) { - prefetcher, _, _, kv := createPrefetcher(t) + prefetcher, _, _, _, kv := createPrefetcher(t) require.NoError(t, kv.Put(key, node)) oracle := l2.NewPreimageOracle(asOracleFn(t, prefetcher), asHinter(t, prefetcher)) @@ -221,7 +385,7 @@ func TestFetchL2Node(t *testing.T) { }) t.Run("Unknown", func(t *testing.T) { - prefetcher, _, l2Cl, _ := createPrefetcher(t) + prefetcher, _, _, l2Cl, _ := createPrefetcher(t) l2Cl.ExpectNodeByHash(hash, node, nil) defer l2Cl.MockDebugClient.AssertExpectations(t) @@ -238,7 +402,7 @@ func TestFetchL2Code(t *testing.T) { key := preimage.Keccak256Key(hash).PreimageKey() t.Run("AlreadyKnown", func(t *testing.T) { - prefetcher, _, _, kv := createPrefetcher(t) + prefetcher, _, _, _, kv := createPrefetcher(t) require.NoError(t, kv.Put(key, code)) oracle := l2.NewPreimageOracle(asOracleFn(t, prefetcher), asHinter(t, prefetcher)) @@ -247,7 +411,7 @@ func TestFetchL2Code(t *testing.T) { }) t.Run("Unknown", func(t *testing.T) { - prefetcher, _, l2Cl, _ := createPrefetcher(t) + prefetcher, _, _, l2Cl, _ := createPrefetcher(t) l2Cl.ExpectCodeByHash(hash, code, nil) defer l2Cl.MockDebugClient.AssertExpectations(t) @@ -258,7 +422,7 @@ func TestFetchL2Code(t *testing.T) { } func TestBadHints(t *testing.T) { - prefetcher, _, _, kv := createPrefetcher(t) + prefetcher, _, _, _, kv := createPrefetcher(t) hash := common.Hash{0xad} t.Run("NoSpace", func(t *testing.T) { @@ -277,7 +441,7 @@ func TestBadHints(t *testing.T) { // But it will fail to prefetch when the pre-image isn't available pre, err := prefetcher.GetPreimage(context.Background(), hash) - require.ErrorContains(t, err, "invalid hash") + require.ErrorContains(t, err, "invalid bytes") require.Nil(t, pre) }) @@ -311,10 +475,10 @@ func TestRetryWhenNotAvailableAfterPrefetching(t *testing.T) { node := testutils.RandomData(rng, 30) hash := crypto.Keccak256Hash(node) - _, l1Source, l2Cl, kv := createPrefetcher(t) + _, l1Source, l1BlobSource, l2Cl, kv := createPrefetcher(t) putsToIgnore := 2 kv = &unreliableKvStore{KV: kv, putsToIgnore: putsToIgnore} - prefetcher := NewPrefetcher(testlog.Logger(t, log.LvlInfo), l1Source, l2Cl, kv) + prefetcher := NewPrefetcher(testlog.Logger(t, log.LevelInfo), l1Source, l1BlobSource, l2Cl, kv) // Expect one call for each ignored put, plus one more request for when the put succeeds for i := 0; i < putsToIgnore+1; i++ { @@ -355,18 +519,19 @@ func (m *l2Client) ExpectOutputByRoot(root common.Hash, output eth.Output, err e m.Mock.On("OutputByRoot", root).Once().Return(output, &err) } -func createPrefetcher(t *testing.T) (*Prefetcher, *testutils.MockL1Source, *l2Client, kvstore.KV) { - logger := testlog.Logger(t, log.LvlDebug) +func createPrefetcher(t *testing.T) (*Prefetcher, *testutils.MockL1Source, *testutils.MockBlobsFetcher, *l2Client, kvstore.KV) { + logger := testlog.Logger(t, log.LevelDebug) kv := kvstore.NewMemKV() l1Source := new(testutils.MockL1Source) + l1BlobSource := new(testutils.MockBlobsFetcher) l2Source := &l2Client{ MockL2Client: new(testutils.MockL2Client), MockDebugClient: new(testutils.MockDebugClient), } - prefetcher := NewPrefetcher(logger, l1Source, l2Source, kv) - return prefetcher, l1Source, l2Source, kv + prefetcher := NewPrefetcher(logger, l1Source, l1BlobSource, l2Source, kv) + return prefetcher, l1Source, l1BlobSource, l2Source, kv } func storeBlock(t *testing.T, kv kvstore.KV, block *types.Block, receipts types.Receipts) { @@ -392,6 +557,23 @@ func storeBlock(t *testing.T, kv kvstore.KV, block *types.Block, receipts types. require.NoError(t, kv.Put(preimage.Keccak256Key(block.Hash()).PreimageKey(), headerRlp)) } +func storeBlob(t *testing.T, kv kvstore.KV, commitment eth.Bytes48, blob *eth.Blob) { + // Pre-store versioned hash preimage (commitment) + err := kv.Put(preimage.Sha256Key(sha256.Sum256(commitment[:])).PreimageKey(), commitment[:]) + require.NoError(t, err, "Failed to store versioned hash preimage in kvstore") + + // Pre-store blob field elements + blobKeyBuf := make([]byte, 80) + copy(blobKeyBuf[:48], commitment[:]) + for i := 0; i < params.BlobTxFieldElementsPerBlob; i++ { + binary.BigEndian.PutUint64(blobKeyBuf[72:], uint64(i)) + feKey := crypto.Keccak256Hash(blobKeyBuf) + + err = kv.Put(preimage.BlobKey(feKey).PreimageKey(), blob[i<<5:(i+1)<<5]) + require.NoError(t, err, "Failed to store field element preimage in kvstore") + } +} + func asOracleFn(t *testing.T, prefetcher *Prefetcher) preimage.OracleFn { return func(key preimage.Key) []byte { pre, err := prefetcher.GetPreimage(context.Background(), key.PreimageKey()) diff --git a/op-program/host/prefetcher/retry.go b/op-program/host/prefetcher/retry.go index 325557657c3e..592ba5ca9361 100644 --- a/op-program/host/prefetcher/retry.go +++ b/op-program/host/prefetcher/retry.go @@ -59,6 +59,42 @@ func (s *RetryingL1Source) FetchReceipts(ctx context.Context, blockHash common.H var _ L1Source = (*RetryingL1Source)(nil) +type RetryingL1BlobSource struct { + logger log.Logger + source L1BlobSource + strategy retry.Strategy +} + +func NewRetryingL1BlobSource(logger log.Logger, source L1BlobSource) *RetryingL1BlobSource { + return &RetryingL1BlobSource{ + logger: logger, + source: source, + strategy: retry.Exponential(), + } +} + +func (s *RetryingL1BlobSource) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) { + return retry.Do(ctx, maxAttempts, s.strategy, func() ([]*eth.BlobSidecar, error) { + sidecars, err := s.source.GetBlobSidecars(ctx, ref, hashes) + if err != nil { + s.logger.Warn("Failed to retrieve blob sidecars", "ref", ref, "err", err) + } + return sidecars, err + }) +} + +func (s *RetryingL1BlobSource) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { + return retry.Do(ctx, maxAttempts, s.strategy, func() ([]*eth.Blob, error) { + blobs, err := s.source.GetBlobs(ctx, ref, hashes) + if err != nil { + s.logger.Warn("Failed to retrieve blobs", "ref", ref, "err", err) + } + return blobs, err + }) +} + +var _ L1BlobSource = (*RetryingL1BlobSource)(nil) + type RetryingL2Source struct { logger log.Logger source L2Source diff --git a/op-program/host/prefetcher/retry_test.go b/op-program/host/prefetcher/retry_test.go index c6d46d027a48..205b3ce84d0e 100644 --- a/op-program/host/prefetcher/retry_test.go +++ b/op-program/host/prefetcher/retry_test.go @@ -2,6 +2,7 @@ package prefetcher import ( "context" + "crypto/sha256" "errors" "testing" @@ -11,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/retry" @@ -103,7 +105,7 @@ func TestRetryingL1Source(t *testing.T) { } func createL1Source(t *testing.T) (*RetryingL1Source, *testutils.MockL1Source) { - logger := testlog.Logger(t, log.LvlDebug) + logger := testlog.Logger(t, log.LevelDebug) mock := &testutils.MockL1Source{} source := NewRetryingL1Source(logger, mock) // Avoid sleeping in tests by using a fixed retry strategy with no delay @@ -111,6 +113,117 @@ func createL1Source(t *testing.T) (*RetryingL1Source, *testutils.MockL1Source) { return source, mock } +func TestRetryingL1BlobSource(t *testing.T) { + ctx := context.Background() + blob := GetRandBlob(0xFACADE) + commitment, err := kzgCtx.BlobToKZGCommitment(blob, 0) + require.NoError(t, err) + versionedHash := sha256.Sum256(commitment[:]) + versionedHash[0] = params.BlobTxHashVersion + blobHash := eth.IndexedBlobHash{Hash: versionedHash, Index: 0xFACADE} + l1BlockRef := eth.L1BlockRef{Time: 0} + + t.Run("GetBlobs Success", func(t *testing.T) { + source, mock := createL1BlobSource(t) + defer mock.AssertExpectations(t) + mock.ExpectOnGetBlobs( + ctx, + l1BlockRef, + []eth.IndexedBlobHash{blobHash}, + []*eth.Blob{(*eth.Blob)(&blob)}, + nil, + ) + + result, err := source.GetBlobs(ctx, l1BlockRef, []eth.IndexedBlobHash{blobHash}) + require.NoError(t, err) + require.Equal(t, len(result), 1) + require.Equal(t, blob[:], result[0][:]) + }) + + t.Run("GetBlobs Error", func(t *testing.T) { + source, mock := createL1BlobSource(t) + defer mock.AssertExpectations(t) + expectedErr := errors.New("boom") + mock.ExpectOnGetBlobs( + ctx, + l1BlockRef, + []eth.IndexedBlobHash{blobHash}, + nil, + expectedErr, + ) + mock.ExpectOnGetBlobs( + ctx, + l1BlockRef, + []eth.IndexedBlobHash{blobHash}, + []*eth.Blob{(*eth.Blob)(&blob)}, + nil, + ) + + result, err := source.GetBlobs(ctx, l1BlockRef, []eth.IndexedBlobHash{blobHash}) + require.NoError(t, err) + require.Equal(t, len(result), 1) + require.Equal(t, blob[:], result[0][:]) + }) + + t.Run("GetBlobSidecars Success", func(t *testing.T) { + source, mock := createL1BlobSource(t) + defer mock.AssertExpectations(t) + mock.ExpectOnGetBlobSidecars( + ctx, + l1BlockRef, + []eth.IndexedBlobHash{blobHash}, + (eth.Bytes48)(commitment), + []*eth.Blob{(*eth.Blob)(&blob)}, + nil, + ) + + result, err := source.GetBlobSidecars(ctx, l1BlockRef, []eth.IndexedBlobHash{blobHash}) + require.NoError(t, err) + require.Equal(t, len(result), 1) + require.Equal(t, blob[:], result[0].Blob[:]) + require.Equal(t, blobHash.Index, uint64(result[0].Index)) + require.Equal(t, (eth.Bytes48)(commitment), result[0].KZGCommitment) + }) + + t.Run("GetBlobSidecars Error", func(t *testing.T) { + source, mock := createL1BlobSource(t) + defer mock.AssertExpectations(t) + expectedErr := errors.New("boom") + mock.ExpectOnGetBlobSidecars( + ctx, + l1BlockRef, + []eth.IndexedBlobHash{blobHash}, + (eth.Bytes48)(commitment), + []*eth.Blob{(*eth.Blob)(&blob)}, + expectedErr, + ) + mock.ExpectOnGetBlobSidecars( + ctx, + l1BlockRef, + []eth.IndexedBlobHash{blobHash}, + (eth.Bytes48)(commitment), + []*eth.Blob{(*eth.Blob)(&blob)}, + nil, + ) + + result, err := source.GetBlobSidecars(ctx, l1BlockRef, []eth.IndexedBlobHash{blobHash}) + require.NoError(t, err) + require.Equal(t, len(result), 1) + require.Equal(t, blob[:], result[0].Blob[:]) + require.Equal(t, blobHash.Index, uint64(result[0].Index)) + require.Equal(t, (eth.Bytes48)(commitment), result[0].KZGCommitment) + }) +} + +func createL1BlobSource(t *testing.T) (*RetryingL1BlobSource, *testutils.MockBlobsFetcher) { + logger := testlog.Logger(t, log.LvlDebug) + mock := &testutils.MockBlobsFetcher{} + source := NewRetryingL1BlobSource(logger, mock) + // Avoid sleeping in tests by using a fixed retry strategy with no delay + source.strategy = retry.Fixed(0) + return source, mock +} + func TestRetryingL2Source(t *testing.T) { ctx := context.Background() hash := common.Hash{0xab} @@ -216,7 +329,7 @@ func TestRetryingL2Source(t *testing.T) { } func createL2Source(t *testing.T) (*RetryingL2Source, *MockL2Source) { - logger := testlog.Logger(t, log.LvlDebug) + logger := testlog.Logger(t, log.LevelDebug) mock := &MockL2Source{} source := NewRetryingL2Source(logger, mock) // Avoid sleeping in tests by using a fixed retry strategy with no delay diff --git a/op-program/scripts/run-compat.sh b/op-program/scripts/run-compat.sh new file mode 100755 index 000000000000..c01fb7d1af00 --- /dev/null +++ b/op-program/scripts/run-compat.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -euo pipefail + +SCRIPTS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +COMPAT_DIR="${SCRIPTS_DIR}/../temp/compat" + +TESTNAME="${1?Must specify compat file to run}" +BASEURL="${2:-https://github.com/ethereum-optimism/chain-test-data/releases/download/2024-03-14.3}" + +URL="${BASEURL}/${TESTNAME}.tar.bz" + +mkdir -p "${COMPAT_DIR}" +curl --etag-save "${COMPAT_DIR}/${TESTNAME}-etag.txt" --etag-compare "${COMPAT_DIR}/${TESTNAME}-etag.txt" -L --fail -o "${COMPAT_DIR}/${TESTNAME}.tar.bz" "${URL}" +tar jxf "${COMPAT_DIR}/${TESTNAME}.tar.bz" -C "${COMPAT_DIR}" +# shellcheck disable=SC2046 +"${SCRIPTS_DIR}/../bin/op-program" $(cat "${COMPAT_DIR}/${TESTNAME}/args.txt") diff --git a/op-program/verify/cmd/goerli.go b/op-program/verify/cmd/goerli.go deleted file mode 100644 index 88e1fbf0b0a4..000000000000 --- a/op-program/verify/cmd/goerli.go +++ /dev/null @@ -1,156 +0,0 @@ -package main - -import ( - "context" - "flag" - "fmt" - "math/big" - "os" - "os/exec" - "path/filepath" - "strings" - "time" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/rpc" -) - -func main() { - var l1RpcUrl string - var l1RpcKind string - var l2RpcUrl string - var dataDir string - flag.StringVar(&l1RpcUrl, "l1", "", "L1 RPC URL to use") - flag.StringVar(&l1RpcKind, "l1-rpckind", "alchemy", "L1 RPC kind") - flag.StringVar(&l2RpcUrl, "l2", "", "L2 RPC URL to use") - flag.StringVar(&dataDir, "datadir", "", - "Directory to use for storing pre-images. If not set a temporary directory will be used.") - flag.Parse() - - if l1RpcUrl == "" || l2RpcUrl == "" { - _, _ = fmt.Fprintln(os.Stderr, "Must specify --l1 and --l2 RPC URLs") - os.Exit(2) - } - - goerliOutputAddress := common.HexToAddress("0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0") - err := Run(l1RpcUrl, l1RpcKind, l2RpcUrl, goerliOutputAddress, dataDir) - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "Failed: %v\n", err.Error()) - os.Exit(1) - } -} - -func Run(l1RpcUrl string, l1RpcKind string, l2RpcUrl string, l2OracleAddr common.Address, dataDir string) error { - ctx := context.Background() - l1RpcClient, err := rpc.Dial(l1RpcUrl) - if err != nil { - return fmt.Errorf("dial L1 client: %w", err) - } - l1Client := ethclient.NewClient(l1RpcClient) - - l2RpcClient, err := rpc.Dial(l2RpcUrl) - if err != nil { - return fmt.Errorf("dial L2 client: %w", err) - } - l2Client := ethclient.NewClient(l2RpcClient) - - outputOracle, err := bindings.NewL2OutputOracle(l2OracleAddr, l1Client) - if err != nil { - return fmt.Errorf("create output oracle bindings: %w", err) - } - - // Find L1 finalized block. Can't be re-orged. - l1BlockNum := big.NewInt(int64(rpc.FinalizedBlockNumber)) - l1HeadBlock, err := l1Client.BlockByNumber(ctx, l1BlockNum) - if err != nil { - return fmt.Errorf("find L1 head: %w", err) - } - fmt.Printf("Found l1 head block number: %v hash: %v\n", l1HeadBlock.NumberU64(), l1HeadBlock.Hash()) - - l1CallOpts := &bind.CallOpts{Context: ctx, BlockNumber: l1BlockNum} - - // Find the latest output root published in this finalized block - latestOutputIndex, err := outputOracle.LatestOutputIndex(l1CallOpts) - if err != nil { - return fmt.Errorf("fetch latest output index: %w", err) - } - output, err := outputOracle.GetL2Output(l1CallOpts, latestOutputIndex) - if err != nil { - return fmt.Errorf("fetch l2 output %v: %w", latestOutputIndex, err) - } - - // Use the previous output as the agreed starting point - agreedOutput, err := outputOracle.GetL2Output(l1CallOpts, new(big.Int).Sub(latestOutputIndex, common.Big1)) - if err != nil { - return fmt.Errorf("fetch l2 output before %v: %w", latestOutputIndex, err) - } - l2BlockAtOutput, err := l2Client.BlockByNumber(ctx, agreedOutput.L2BlockNumber) - if err != nil { - return fmt.Errorf("retrieve agreed block: %w", err) - } - - l2Head := l2BlockAtOutput.Hash() - l2BlockNumber := output.L2BlockNumber - l2Claim := common.Hash(output.OutputRoot) - l1Head := l1HeadBlock.Hash() - - if dataDir == "" { - dataDir, err = os.MkdirTemp("", "oracledata") - if err != nil { - return fmt.Errorf("create temp dir: %w", err) - } - defer func() { - err := os.RemoveAll(dataDir) - if err != nil { - fmt.Println("Failed to remove temp dir:" + err.Error()) - } - }() - } else { - if err := os.MkdirAll(dataDir, 0755); err != nil { - fmt.Printf("Could not create data directory %v: %v", dataDir, err) - os.Exit(1) - } - } - fmt.Printf("Using dir: %s\n", dataDir) - args := []string{ - "--log.level", "DEBUG", - "--network", "goerli", - "--exec", "./bin/op-program-client", - "--datadir", dataDir, - "--l1.head", l1Head.Hex(), - "--l2.head", l2Head.Hex(), - "--l2.outputroot", common.Bytes2Hex(agreedOutput.OutputRoot[:]), - "--l2.claim", l2Claim.Hex(), - "--l2.blocknumber", l2BlockNumber.String(), - } - argsStr := strings.Join(args, " ") - if err := os.WriteFile(filepath.Join(dataDir, "args.txt"), []byte(argsStr), 0644); err != nil { - fmt.Printf("Could not write args: %v", err) - os.Exit(1) - } - fmt.Printf("Configuration: %s\n", argsStr) - fmt.Println("Running in online mode") - err = runFaultProofProgram(ctx, append(args, "--l1", l1RpcUrl, "--l2", l2RpcUrl, "--l1.rpckind", l1RpcKind)) - if err != nil { - return fmt.Errorf("online mode failed: %w", err) - } - - fmt.Println("Running in offline mode") - err = runFaultProofProgram(ctx, args) - if err != nil { - return fmt.Errorf("offline mode failed: %w", err) - } - return nil -} - -func runFaultProofProgram(ctx context.Context, args []string) error { - ctx, cancel := context.WithTimeout(ctx, 60*time.Minute) - defer cancel() - cmd := exec.CommandContext(ctx, "./bin/op-program", args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - return cmd.Run() -} diff --git a/op-program/verify/mainnet/cmd/mainnet.go b/op-program/verify/mainnet/cmd/mainnet.go new file mode 100644 index 000000000000..bcd4d5df030d --- /dev/null +++ b/op-program/verify/mainnet/cmd/mainnet.go @@ -0,0 +1,67 @@ +package main + +import ( + "context" + "flag" + "fmt" + "os" + + "github.com/ethereum-optimism/optimism/op-program/chainconfig" + "github.com/ethereum-optimism/optimism/op-program/verify" + "github.com/ethereum/go-ethereum/common" +) + +func main() { + var l1RpcUrl string + var l1RpcKind string + var l1BeaconUrl string + var l2RpcUrl string + var dataDir string + var l1HashStr string + var l2Start uint64 + var l2End uint64 + flag.StringVar(&l1RpcUrl, "l1", "", "L1 RPC URL to use") + flag.StringVar(&l1BeaconUrl, "l1.beacon", "", "L1 Beacon URL to use") + flag.StringVar(&l1RpcKind, "l1-rpckind", "", "L1 RPC kind") + flag.StringVar(&l2RpcUrl, "l2", "", "L2 RPC URL to use") + flag.StringVar(&dataDir, "datadir", "", + "Directory to use for storing pre-images. If not set a temporary directory will be used.") + flag.StringVar(&l1HashStr, "l1.head", "", "Hash of L1 block to use") + flag.Uint64Var(&l2Start, "l2.start", 0, "Block number of agreed L2 block") + flag.Uint64Var(&l2End, "l2.end", 0, "Block number of claimed L2 block") + flag.Parse() + + if l1RpcUrl == "" { + _, _ = fmt.Fprintln(os.Stderr, "Must specify --l1 RPC URL") + os.Exit(2) + } + if l1BeaconUrl == "" { + _, _ = fmt.Fprintln(os.Stderr, "Must specify --l1.beacon URL") + os.Exit(2) + } + if l2RpcUrl == "" { + _, _ = fmt.Fprintln(os.Stderr, "Must specify --l2 RPC URL") + os.Exit(2) + } + + runner, err := verify.NewRunner(l1RpcUrl, l1RpcKind, l1BeaconUrl, l2RpcUrl, dataDir, "op-mainnet", chainconfig.OPMainnetChainConfig) + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Failed to create runner: %v\n", err.Error()) + os.Exit(1) + } + + if l1HashStr == "" && l2Start == 0 && l2End == 0 { + err = runner.RunToFinalized(context.Background()) + } else { + l1Hash := common.HexToHash(l1HashStr) + if l1Hash == (common.Hash{}) { + _, _ = fmt.Fprintf(os.Stderr, "Invalid --l1.head: %v\n", l1HashStr) + os.Exit(2) + } + err = runner.RunBetweenBlocks(context.Background(), l1Hash, l2Start, l2End) + } + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Failed: %v\n", err.Error()) + os.Exit(1) + } +} diff --git a/op-program/verify/sepolia/cmd/sepolia.go b/op-program/verify/sepolia/cmd/sepolia.go new file mode 100644 index 000000000000..50c38d4a70ec --- /dev/null +++ b/op-program/verify/sepolia/cmd/sepolia.go @@ -0,0 +1,67 @@ +package main + +import ( + "context" + "flag" + "fmt" + "os" + + "github.com/ethereum-optimism/optimism/op-program/chainconfig" + "github.com/ethereum-optimism/optimism/op-program/verify" + "github.com/ethereum/go-ethereum/common" +) + +func main() { + var l1RpcUrl string + var l1RpcKind string + var l1BeaconUrl string + var l2RpcUrl string + var dataDir string + var l1HashStr string + var l2Start uint64 + var l2End uint64 + flag.StringVar(&l1RpcUrl, "l1", "", "L1 RPC URL to use") + flag.StringVar(&l1BeaconUrl, "l1.beacon", "", "L1 Beacon URL to use") + flag.StringVar(&l1RpcKind, "l1-rpckind", "", "L1 RPC kind") + flag.StringVar(&l2RpcUrl, "l2", "", "L2 RPC URL to use") + flag.StringVar(&dataDir, "datadir", "", + "Directory to use for storing pre-images. If not set a temporary directory will be used.") + flag.StringVar(&l1HashStr, "l1.head", "", "Hash of L1 block to use") + flag.Uint64Var(&l2Start, "l2.start", 0, "Block number of agreed L2 block") + flag.Uint64Var(&l2End, "l2.end", 0, "Block number of claimed L2 block") + flag.Parse() + + if l1RpcUrl == "" { + _, _ = fmt.Fprintln(os.Stderr, "Must specify --l1 RPC URL") + os.Exit(2) + } + if l1BeaconUrl == "" { + _, _ = fmt.Fprintln(os.Stderr, "Must specify --l1.beacon URL") + os.Exit(2) + } + if l2RpcUrl == "" { + _, _ = fmt.Fprintln(os.Stderr, "Must specify --l2 RPC URL") + os.Exit(2) + } + + runner, err := verify.NewRunner(l1RpcUrl, l1RpcKind, l1BeaconUrl, l2RpcUrl, dataDir, "sepolia", chainconfig.OPSepoliaChainConfig) + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Failed to create runner: %v\n", err.Error()) + os.Exit(1) + } + + if l1HashStr == "" && l2Start == 0 && l2End == 0 { + err = runner.RunToFinalized(context.Background()) + } else { + l1Hash := common.HexToHash(l1HashStr) + if l1Hash == (common.Hash{}) { + _, _ = fmt.Fprintf(os.Stderr, "Invalid --l1.head: %v\n", l1HashStr) + os.Exit(2) + } + err = runner.RunBetweenBlocks(context.Background(), l1Hash, l2Start, l2End) + } + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Failed: %v\n", err.Error()) + os.Exit(1) + } +} diff --git a/op-program/verify/verify.go b/op-program/verify/verify.go new file mode 100644 index 000000000000..43150cfbc2b4 --- /dev/null +++ b/op-program/verify/verify.go @@ -0,0 +1,244 @@ +package verify + +import ( + "context" + "fmt" + "math/big" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-program/host" + "github.com/ethereum-optimism/optimism/op-program/host/config" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/eth" + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/retry" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" +) + +type Runner struct { + l1RpcUrl string + l1RpcKind string + l1BeaconUrl string + l2RpcUrl string + dataDir string + network string + chainCfg *params.ChainConfig + l2Client *sources.L2Client + logCfg oplog.CLIConfig + setupLog log.Logger + rollupCfg *rollup.Config +} + +func NewRunner(l1RpcUrl string, l1RpcKind string, l1BeaconUrl string, l2RpcUrl string, dataDir string, network string, chainCfg *params.ChainConfig) (*Runner, error) { + ctx := context.Background() + logCfg := oplog.DefaultCLIConfig() + logCfg.Level = log.LevelDebug + + setupLog := oplog.NewLogger(os.Stderr, logCfg) + + l2RawRpc, err := dial.DialRPCClientWithTimeout(ctx, dial.DefaultDialTimeout, setupLog, l2RpcUrl) + if err != nil { + return nil, fmt.Errorf("dial L2 client: %w", err) + } + + rollupCfg, err := rollup.LoadOPStackRollupConfig(chainCfg.ChainID.Uint64()) + if err != nil { + return nil, fmt.Errorf("failed to load rollup config: %w", err) + } + + l2ClientCfg := sources.L2ClientDefaultConfig(rollupCfg, false) + l2RPC := client.NewBaseRPCClient(l2RawRpc) + l2Client, err := sources.NewL2Client(l2RPC, setupLog, nil, l2ClientCfg) + if err != nil { + return nil, fmt.Errorf("failed to create L2 client: %w", err) + } + + return &Runner{ + l1RpcUrl: l1RpcUrl, + l1RpcKind: l1RpcKind, + l1BeaconUrl: l1BeaconUrl, + l2RpcUrl: l2RpcUrl, + dataDir: dataDir, + network: network, + chainCfg: chainCfg, + logCfg: logCfg, + setupLog: setupLog, + l2Client: l2Client, + rollupCfg: rollupCfg, + }, nil +} + +func (r *Runner) RunBetweenBlocks(ctx context.Context, l1Head common.Hash, startBlockNum uint64, endBlockNumber uint64) error { + if startBlockNum >= endBlockNumber { + return fmt.Errorf("start block number %v must be less than end block number %v", startBlockNum, endBlockNumber) + } + + l2Client, err := r.createL2Client(ctx) + if err != nil { + return err + } + defer l2Client.Close() + + agreedBlockInfo, agreedOutputRoot, err := outputAtBlockNum(ctx, l2Client, startBlockNum) + if err != nil { + return fmt.Errorf("failed to find starting block info: %w", err) + } + claimedBlockInfo, claimedOutputRoot, err := outputAtBlockNum(ctx, l2Client, endBlockNumber) + if err != nil { + return fmt.Errorf("failed to find ending block info: %w", err) + } + + return r.run(l1Head, agreedBlockInfo, agreedOutputRoot, claimedOutputRoot, claimedBlockInfo) +} + +func (r *Runner) createL2Client(ctx context.Context) (*sources.L2Client, error) { + l2RawRpc, err := dial.DialRPCClientWithTimeout(ctx, dial.DefaultDialTimeout, r.setupLog, r.l2RpcUrl) + if err != nil { + return nil, fmt.Errorf("dial L2 client: %w", err) + } + l2ClientCfg := sources.L2ClientDefaultConfig(r.rollupCfg, false) + l2RPC := client.NewBaseRPCClient(l2RawRpc) + l2Client, err := sources.NewL2Client(l2RPC, r.setupLog, nil, l2ClientCfg) + if err != nil { + return nil, fmt.Errorf("failed to create L2 client: %w", err) + } + return l2Client, nil +} + +func (r *Runner) RunToFinalized(ctx context.Context) error { + l1Client, err := dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, r.setupLog, r.l1RpcUrl) + if err != nil { + return fmt.Errorf("failed to dial L1 client: %w", err) + } + + l2Client, err := r.createL2Client(ctx) + if err != nil { + return err + } + defer l2Client.Close() + + l2Finalized, err := retryOp(ctx, func() (eth.BlockInfo, error) { + return l2Client.InfoByLabel(ctx, eth.Finalized) + }) + if err != nil { + return fmt.Errorf("failed to retrieve finalized L2 block: %w", err) + } + + // Retrieve finalized L1 block after finalized L2 block to ensure it is + l1Head, err := retryOp(ctx, func() (*types.Header, error) { + return l1Client.HeaderByNumber(ctx, big.NewInt(rpc.FinalizedBlockNumber.Int64())) + }) + if err != nil { + return fmt.Errorf("failed to retrieve finalized L1 block: %w", err) + } + + // Process the 100 blocks leading up to finalized + startBlockNum := uint64(0) + if l2Finalized.NumberU64() > 100 { + startBlockNum = l2Finalized.NumberU64() - 100 + } + agreedBlockInfo, agreedOutputRoot, err := outputAtBlockNum(ctx, l2Client, startBlockNum) + if err != nil { + return fmt.Errorf("failed to find starting block info: %w", err) + } + claimedBlockInfo, claimedOutputRoot, err := outputAtBlockNum(ctx, l2Client, l2Finalized.NumberU64()) + if err != nil { + return fmt.Errorf("failed to find ending block info: %w", err) + } + + return r.run(l1Head.Hash(), agreedBlockInfo, agreedOutputRoot, claimedOutputRoot, claimedBlockInfo) +} + +func (r *Runner) run(l1Head common.Hash, agreedBlockInfo eth.BlockInfo, agreedOutputRoot common.Hash, claimedOutputRoot common.Hash, claimedBlockInfo eth.BlockInfo) error { + var err error + if r.dataDir == "" { + r.dataDir, err = os.MkdirTemp("", "oracledata") + if err != nil { + return fmt.Errorf("create temp dir: %w", err) + } + defer func() { + err := os.RemoveAll(r.dataDir) + if err != nil { + fmt.Println("Failed to remove temp dir:" + err.Error()) + } + }() + } else { + if err := os.MkdirAll(r.dataDir, 0755); err != nil { + fmt.Printf("Could not create data directory %v: %v", r.dataDir, err) + os.Exit(1) + } + } + fmt.Printf("Using dir: %s\n", r.dataDir) + args := []string{ + "--log.level", "DEBUG", + "--network", r.network, + "--exec", "./bin/op-program-client", + "--datadir", r.dataDir, + "--l1.head", l1Head.Hex(), + "--l2.head", agreedBlockInfo.Hash().Hex(), + "--l2.outputroot", agreedOutputRoot.Hex(), + "--l2.claim", claimedOutputRoot.Hex(), + "--l2.blocknumber", strconv.FormatUint(claimedBlockInfo.NumberU64(), 10), + } + argsStr := strings.Join(args, " ") + // args.txt is used by the verify job for offline verification in CI + if err := os.WriteFile(filepath.Join(r.dataDir, "args.txt"), []byte(argsStr), 0644); err != nil { + fmt.Printf("Could not write args: %v", err) + os.Exit(1) + } + fmt.Printf("Configuration: %s\n", argsStr) + + offlineCfg := config.NewConfig( + r.rollupCfg, r.chainCfg, l1Head, agreedBlockInfo.Hash(), agreedOutputRoot, claimedOutputRoot, claimedBlockInfo.NumberU64()) + offlineCfg.DataDir = r.dataDir + onlineCfg := *offlineCfg + onlineCfg.L1URL = r.l1RpcUrl + onlineCfg.L1BeaconURL = r.l1BeaconUrl + onlineCfg.L2URL = r.l2RpcUrl + if r.l1RpcKind != "" { + onlineCfg.L1RPCKind = sources.RPCProviderKind(r.l1RpcKind) + } + + fmt.Println("Running in online mode") + err = host.Main(oplog.NewLogger(os.Stderr, r.logCfg), &onlineCfg) + if err != nil { + return fmt.Errorf("online mode failed: %w", err) + } + + fmt.Println("Running in offline mode") + err = host.Main(oplog.NewLogger(os.Stderr, r.logCfg), offlineCfg) + if err != nil { + return fmt.Errorf("offline mode failed: %w", err) + } + return nil +} + +func outputAtBlockNum(ctx context.Context, l2Client *sources.L2Client, blockNum uint64) (eth.BlockInfo, common.Hash, error) { + startBlockInfo, err := l2Client.InfoByNumber(ctx, blockNum) + if err != nil { + return nil, common.Hash{}, fmt.Errorf("failed to retrieve info for block %v: %w", startBlockInfo, err) + } + + output, err := retryOp(ctx, func() (*eth.OutputV0, error) { + return l2Client.OutputV0AtBlock(ctx, startBlockInfo.Hash()) + }) + if err != nil { + return nil, common.Hash{}, fmt.Errorf("failed to retrieve agreed output root for block %v: %w", startBlockInfo.Hash(), err) + } + return startBlockInfo, common.Hash(eth.OutputRoot(output)), nil +} + +func retryOp[T any](ctx context.Context, op func() (T, error)) (T, error) { + return retry.Do(ctx, 10, retry.Fixed(time.Second*2), op) +} diff --git a/op-proposer/Dockerfile b/op-proposer/Dockerfile index 151e46ec4a2a..4cdf13819d74 100644 --- a/op-proposer/Dockerfile +++ b/op-proposer/Dockerfile @@ -10,6 +10,7 @@ COPY ./op-proposer /app/op-proposer COPY ./op-bindings /app/op-bindings COPY ./op-node /app/op-node COPY ./op-service /app/op-service +COPY ./op-plasma /app/op-plasma COPY ./op-aws-sdk /app/op-aws-sdk COPY ./go.mod /app/go.mod COPY ./go.sum /app/go.sum diff --git a/op-proposer/Makefile b/op-proposer/Makefile index 1b2db9f30515..00bb036b78b8 100644 --- a/op-proposer/Makefile +++ b/op-proposer/Makefile @@ -19,5 +19,4 @@ test: .PHONY: \ clean \ op-proposer \ - test \ - lint + test diff --git a/op-proposer/cmd/main.go b/op-proposer/cmd/main.go index b180ff158297..4ef2083597cd 100644 --- a/op-proposer/cmd/main.go +++ b/op-proposer/cmd/main.go @@ -1,13 +1,11 @@ package main import ( - "context" "os" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/urfave/cli/v2" - opaws "github.com/ethereum-optimism/optimism/op-aws-sdk" "github.com/ethereum-optimism/optimism/op-proposer/flags" "github.com/ethereum-optimism/optimism/op-proposer/metrics" "github.com/ethereum-optimism/optimism/op-proposer/proposer" @@ -32,7 +30,7 @@ func main() { app.Name = "op-proposer" app.Usage = "L2Output Submitter" app.Description = "Service for generating and submitting L2 Output checkpoints to the L2OutputOracle contract" - app.Action = curryMain(Version) + app.Action = cliapp.LifecycleCmd(proposer.Main(Version)) app.Commands = []*cli.Command{ { Name: "doc", @@ -45,14 +43,3 @@ func main() { log.Crit("Application failed", "message", err) } } - -// curryMain transforms the proposer.Main function into an app.Action -// This is done to capture the Version of the proposer. -func curryMain(version string) func(ctx *cli.Context) error { - return func(ctx *cli.Context) error { - if err := opaws.KeyManager(context.Background(), ctx, opaws.OP_PROPOSER_SIGN_KEY); err != nil { - return err - } - return proposer.Main(version, ctx) - } -} diff --git a/op-proposer/flags/flags.go b/op-proposer/flags/flags.go index 7b7aae206bee..d6e04193d3b1 100644 --- a/op-proposer/flags/flags.go +++ b/op-proposer/flags/flags.go @@ -9,7 +9,7 @@ import ( opservice "github.com/ethereum-optimism/optimism/op-service" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) @@ -29,16 +29,16 @@ var ( } RollupRpcFlag = &cli.StringFlag{ Name: "rollup-rpc", - Usage: "HTTP provider URL for the rollup node", + Usage: "HTTP provider URL for the rollup node. A comma-separated list enables the active rollup provider.", EnvVars: prefixEnvVars("ROLLUP_RPC"), } + + // Optional flags L2OOAddressFlag = &cli.StringFlag{ Name: "l2oo-address", Usage: "Address of the L2OutputOracle contract", EnvVars: prefixEnvVars("L2OO_ADDRESS"), } - - // Optional flags PollIntervalFlag = &cli.DurationFlag{ Name: "poll-interval", Usage: "How frequently to poll L2 for new blocks", @@ -50,6 +50,28 @@ var ( Usage: "Allow the proposer to submit proposals for L2 blocks derived from non-finalized L1 blocks.", EnvVars: prefixEnvVars("ALLOW_NON_FINALIZED"), } + DisputeGameFactoryAddressFlag = &cli.StringFlag{ + Name: "game-factory-address", + Usage: "Address of the DisputeGameFactory contract", + EnvVars: prefixEnvVars("GAME_FACTORY_ADDRESS"), + } + ProposalIntervalFlag = &cli.DurationFlag{ + Name: "proposal-interval", + Usage: "Interval between submitting L2 output proposals when the dispute game factory address is set", + EnvVars: prefixEnvVars("PROPOSAL_INTERVAL"), + } + DisputeGameTypeFlag = &cli.UintFlag{ + Name: "game-type", + Usage: "Dispute game type to create via the configured DisputeGameFactory", + Value: 0, + EnvVars: prefixEnvVars("GAME_TYPE"), + } + ActiveSequencerCheckDurationFlag = &cli.DurationFlag{ + Name: "active-sequencer-check-duration", + Usage: "The duration between checks to determine the active sequencer endpoint.", + Value: 2 * time.Minute, + EnvVars: prefixEnvVars("ACTIVE_SEQUENCER_CHECK_DURATION"), + } // Legacy Flags L2OutputHDPathFlag = txmgr.L2OutputHDPathFlag ) @@ -57,13 +79,17 @@ var ( var requiredFlags = []cli.Flag{ L1EthRpcFlag, RollupRpcFlag, - L2OOAddressFlag, } var optionalFlags = []cli.Flag{ + L2OOAddressFlag, PollIntervalFlag, AllowNonFinalizedFlag, L2OutputHDPathFlag, + DisputeGameFactoryAddressFlag, + ProposalIntervalFlag, + DisputeGameTypeFlag, + ActiveSequencerCheckDurationFlag, } func init() { diff --git a/op-proposer/flags/flags_test.go b/op-proposer/flags/flags_test.go new file mode 100644 index 000000000000..c02c8e13d5aa --- /dev/null +++ b/op-proposer/flags/flags_test.go @@ -0,0 +1,100 @@ +package flags + +import ( + "slices" + "strings" + "testing" + + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + + "github.com/stretchr/testify/require" + "github.com/urfave/cli/v2" +) + +// TestOptionalFlagsDontSetRequired asserts that all flags deemed optional set +// the Required field to false. +func TestOptionalFlagsDontSetRequired(t *testing.T) { + for _, flag := range optionalFlags { + reqFlag, ok := flag.(cli.RequiredFlag) + require.True(t, ok) + require.False(t, reqFlag.IsRequired()) + } +} + +// TestUniqueFlags asserts that all flag names are unique, to avoid accidental conflicts between the many flags. +func TestUniqueFlags(t *testing.T) { + seenCLI := make(map[string]struct{}) + for _, flag := range Flags { + for _, name := range flag.Names() { + if _, ok := seenCLI[name]; ok { + t.Errorf("duplicate flag %s", name) + continue + } + seenCLI[name] = struct{}{} + } + } +} + +// TestBetaFlags test that all flags starting with "beta." have "BETA_" in the env var, and vice versa. +func TestBetaFlags(t *testing.T) { + for _, flag := range Flags { + envFlag, ok := flag.(interface { + GetEnvVars() []string + }) + if !ok || len(envFlag.GetEnvVars()) == 0 { // skip flags without env-var support + continue + } + name := flag.Names()[0] + envName := envFlag.GetEnvVars()[0] + if strings.HasPrefix(name, "beta.") { + require.Contains(t, envName, "BETA_", "%q flag must contain BETA in env var to match \"beta.\" flag name", name) + } + if strings.Contains(envName, "BETA_") { + require.True(t, strings.HasPrefix(name, "beta."), "%q flag must start with \"beta.\" in flag name to match \"BETA_\" env var", name) + } + } +} + +func TestHasEnvVar(t *testing.T) { + for _, flag := range Flags { + flag := flag + flagName := flag.Names()[0] + + t.Run(flagName, func(t *testing.T) { + envFlagGetter, ok := flag.(interface { + GetEnvVars() []string + }) + envFlags := envFlagGetter.GetEnvVars() + require.True(t, ok, "must be able to cast the flag to an EnvVar interface") + require.Equal(t, 1, len(envFlags), "flags should have exactly one env var") + }) + } +} + +func TestEnvVarFormat(t *testing.T) { + for _, flag := range Flags { + flag := flag + flagName := flag.Names()[0] + + skippedFlags := []string{ + txmgr.FeeLimitMultiplierFlagName, + txmgr.TxSendTimeoutFlagName, + txmgr.TxNotInMempoolTimeoutFlagName, + } + + t.Run(flagName, func(t *testing.T) { + if slices.Contains(skippedFlags, flagName) { + t.Skipf("Skipping flag %v which is known to not have a standard flag name <-> env var conversion", flagName) + } + envFlagGetter, ok := flag.(interface { + GetEnvVars() []string + }) + envFlags := envFlagGetter.GetEnvVars() + require.True(t, ok, "must be able to cast the flag to an EnvVar interface") + require.Equal(t, 1, len(envFlags), "flags should have exactly one env var") + expectedEnvVar := opservice.FlagNameToEnvVarName(flagName, "OP_PROPOSER") + require.Equal(t, expectedEnvVar, envFlags[0]) + }) + } +} diff --git a/op-proposer/metrics/metrics.go b/op-proposer/metrics/metrics.go index d26a85257ba8..1b91192f39ba 100644 --- a/op-proposer/metrics/metrics.go +++ b/op-proposer/metrics/metrics.go @@ -1,12 +1,11 @@ package metrics import ( - "context" + "io" "github.com/prometheus/client_golang/prometheus" "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum-optimism/optimism/op-service/httputil" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" "github.com/ethereum/go-ethereum" @@ -17,6 +16,9 @@ import ( const Namespace = "op_proposer" const RPCClientSubsystem = "rpc_client" +// implements the Registry getter, for metrics HTTP server to hook into +var _ opmetrics.RegistryMetricer = (*Metrics)(nil) + type Metricer interface { RecordInfo(version string) RecordUp() @@ -27,6 +29,8 @@ type Metricer interface { // Record Tx metrics txmetrics.TxMetricer + StartBalanceMetrics(l log.Logger, client ethereum.ChainStateReader, account common.Address) io.Closer + RecordL2BlocksProposed(l2ref eth.L2BlockRef) } @@ -76,18 +80,12 @@ func NewMetrics(procName string) *Metrics { } } -func (m *Metrics) Start(host string, port int) (*httputil.HTTPServer, error) { - return opmetrics.StartServer(m.registry, host, port) +func (m *Metrics) Registry() *prometheus.Registry { + return m.registry } -func (m *Metrics) StartBalanceMetrics(ctx context.Context, - l log.Logger, client ethereum.ChainStateReader, account common.Address) { - // TODO(7684): util was refactored to close, but ctx is still being used by caller for shutdown - balanceMetric := opmetrics.LaunchBalanceMetrics(l, m.registry, m.ns, client, account) - go func() { - <-ctx.Done() - _ = balanceMetric.Close() - }() +func (m *Metrics) StartBalanceMetrics(l log.Logger, client ethereum.ChainStateReader, account common.Address) io.Closer { + return opmetrics.LaunchBalanceMetrics(l, m.registry, m.ns, client, account) } // RecordInfo sets a pseudo-metric that contains versioning and diff --git a/op-proposer/metrics/noop.go b/op-proposer/metrics/noop.go index 58a8fe53a68f..06b7daad65b9 100644 --- a/op-proposer/metrics/noop.go +++ b/op-proposer/metrics/noop.go @@ -1,6 +1,12 @@ package metrics import ( + "io" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/eth" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" @@ -18,5 +24,9 @@ func (*noopMetrics) RecordUp() {} func (*noopMetrics) RecordL2BlocksProposed(l2ref eth.L2BlockRef) {} +func (*noopMetrics) StartBalanceMetrics(log.Logger, ethereum.ChainStateReader, common.Address) io.Closer { + return nil +} + func (m *noopMetrics) RecordL1UrlSwitchEvt(url string) { } diff --git a/op-proposer/proposer/abi_test.go b/op-proposer/proposer/abi_test.go index f9924c087c18..44395e4040d1 100644 --- a/op-proposer/proposer/abi_test.go +++ b/op-proposer/proposer/abi_test.go @@ -1,6 +1,7 @@ package proposer import ( + "crypto/ecdsa" "math/big" "math/rand" "testing" @@ -10,30 +11,51 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" ) +func simulatedBackend() (privateKey *ecdsa.PrivateKey, address common.Address, opts *bind.TransactOpts, backend *backends.SimulatedBackend, err error) { + privateKey, err = crypto.GenerateKey() + if err != nil { + return nil, common.Address{}, nil, nil, err + } + from := crypto.PubkeyToAddress(privateKey.PublicKey) + opts, err = bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1337)) + if err != nil { + return nil, common.Address{}, nil, nil, err + } + backend = backends.NewSimulatedBackend(core.GenesisAlloc{from: {Balance: big.NewInt(params.Ether)}}, 50_000_000) + + return privateKey, from, opts, backend, nil +} + // setupL2OutputOracle deploys the L2 Output Oracle contract to a simulated backend func setupL2OutputOracle() (common.Address, *bind.TransactOpts, *backends.SimulatedBackend, *bindings.L2OutputOracle, error) { - privateKey, err := crypto.GenerateKey() - from := crypto.PubkeyToAddress(privateKey.PublicKey) + _, from, opts, backend, err := simulatedBackend() + if err != nil { + return common.Address{}, nil, nil, nil, err + } + _, _, contract, err := bindings.DeployL2OutputOracle(opts, backend) if err != nil { return common.Address{}, nil, nil, nil, err } - opts, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1337)) + return from, opts, backend, contract, nil +} + +// setupDisputeGameFactory deploys the DisputeGameFactory contract to a simulated backend +func setupDisputeGameFactory() (common.Address, *bind.TransactOpts, *backends.SimulatedBackend, *bindings.DisputeGameFactory, error) { + _, from, opts, backend, err := simulatedBackend() if err != nil { return common.Address{}, nil, nil, nil, err } - backend := backends.NewSimulatedBackend(core.GenesisAlloc{from: {Balance: big.NewInt(params.Ether)}}, 50_000_000) - _, _, contract, err := bindings.DeployL2OutputOracle( + + _, _, contract, err := bindings.DeployDisputeGameFactory( opts, backend, - big.NewInt(10), - big.NewInt(2), - big.NewInt(100), ) if err != nil { return common.Address{}, nil, nil, nil, err @@ -45,22 +67,23 @@ func setupL2OutputOracle() (common.Address, *bind.TransactOpts, *backends.Simula // We don't use the contract to transact because it does not fit our transaction management scheme, but // we want to make sure that we don't incorrectly create the transaction data. func TestManualABIPacking(t *testing.T) { - _, opts, _, contract, err := setupL2OutputOracle() + // L2OO + _, opts, _, l2oo, err := setupL2OutputOracle() require.NoError(t, err) rng := rand.New(rand.NewSource(1234)) - abi, err := bindings.L2OutputOracleMetaData.GetAbi() + l2ooAbi, err := bindings.L2OutputOracleMetaData.GetAbi() require.NoError(t, err) output := testutils.RandomOutputResponse(rng) - txData, err := proposeL2OutputTxData(abi, output, true) + txData, err := proposeL2OutputTxData(l2ooAbi, output, true) require.NoError(t, err) // set a gas limit to disable gas estimation. The invariantes that the L2OO tries to uphold // are not maintained in this test. opts.GasLimit = 100_000 - tx, err := contract.ProposeL2Output( + tx, err := l2oo.ProposeL2Output( opts, output.OutputRoot, new(big.Int).SetUint64(output.BlockRef.Number), @@ -69,4 +92,28 @@ func TestManualABIPacking(t *testing.T) { require.NoError(t, err) require.Equal(t, txData, tx.Data()) + + // DGF + _, opts, _, dgf, err := setupDisputeGameFactory() + require.NoError(t, err) + rng = rand.New(rand.NewSource(1234)) + + dgfAbi, err := bindings.DisputeGameFactoryMetaData.GetAbi() + require.NoError(t, err) + + output = testutils.RandomOutputResponse(rng) + + txData, err = proposeL2OutputDGFTxData(dgfAbi, uint32(0), output) + require.NoError(t, err) + + opts.GasLimit = 100_000 + dgfTx, err := dgf.Create( + opts, + uint32(0), + output.OutputRoot, + math.U256Bytes(new(big.Int).SetUint64(output.BlockRef.Number)), + ) + require.NoError(t, err) + + require.Equal(t, txData, dgfTx.Data()) } diff --git a/op-proposer/proposer/config.go b/op-proposer/proposer/config.go index e950eba46bd8..dcd0693549bb 100644 --- a/op-proposer/proposer/config.go +++ b/op-proposer/proposer/config.go @@ -1,35 +1,19 @@ package proposer import ( + "errors" "time" - "github.com/ethereum-optimism/optimism/op-service/client" - - "github.com/ethereum/go-ethereum/common" "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/op-proposer/flags" - "github.com/ethereum-optimism/optimism/op-service/sources" - oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/oppprof" oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) -// Config contains the well typed fields that are used to initialize the output submitter. -// It is intended for programmatic use. -type Config struct { - L2OutputOracleAddr common.Address - PollInterval time.Duration - NetworkTimeout time.Duration - TxManager txmgr.TxManager - L1Client client.Client - RollupClient *sources.RollupClient - AllowNonFinalized bool -} - // CLIConfig is a well typed config that is parsed from the CLI params. // This also contains config options for auxiliary services. // It is transformed into a `Config` before the L2 output submitter is started. @@ -39,7 +23,7 @@ type CLIConfig struct { // L1EthRpc is the HTTP provider URL for L1. L1EthRpc string - // RollupRpc is the HTTP provider URL for the rollup node. + // RollupRpc is the HTTP provider URL for the rollup node. A comma-separated list enables the active rollup provider. RollupRpc string // L2OOAddress is the L2OutputOracle contract address. @@ -62,9 +46,21 @@ type CLIConfig struct { MetricsConfig opmetrics.CLIConfig PprofConfig oppprof.CLIConfig + + // DGFAddress is the DisputeGameFactory contract address. + DGFAddress string + + // ProposalInterval is the delay between submitting L2 output proposals when the DGFAddress is set. + ProposalInterval time.Duration + + // DisputeGameType is the type of dispute game to create when submitting an output proposal. + DisputeGameType uint32 + + // ActiveSequencerCheckDuration is the duration between checks to determine the active sequencer endpoint. + ActiveSequencerCheckDuration time.Duration } -func (c CLIConfig) Check() error { +func (c *CLIConfig) Check() error { if err := c.RPCConfig.Check(); err != nil { return err } @@ -77,12 +73,23 @@ func (c CLIConfig) Check() error { if err := c.TxMgrConfig.Check(); err != nil { return err } + + if c.DGFAddress != "" && c.L2OOAddress != "" { + return errors.New("both the `DisputeGameFactory` and `L2OutputOracle` addresses were provided") + } + if c.DGFAddress != "" && c.ProposalInterval == 0 { + return errors.New("the `DisputeGameFactory` address was provided but the `ProposalInterval` was not set") + } + if c.ProposalInterval != 0 && c.DGFAddress == "" { + return errors.New("the `ProposalInterval` was provided but the `DisputeGameFactory` address was not set") + } + return nil } // NewConfig parses the Config from the provided flags or environment variables. -func NewConfig(ctx *cli.Context) CLIConfig { - return CLIConfig{ +func NewConfig(ctx *cli.Context) *CLIConfig { + return &CLIConfig{ // Required Flags L1EthRpc: ctx.String(flags.L1EthRpcFlag.Name), RollupRpc: ctx.String(flags.RollupRpcFlag.Name), @@ -90,10 +97,14 @@ func NewConfig(ctx *cli.Context) CLIConfig { PollInterval: ctx.Duration(flags.PollIntervalFlag.Name), TxMgrConfig: txmgr.ReadCLIConfig(ctx), // Optional Flags - AllowNonFinalized: ctx.Bool(flags.AllowNonFinalizedFlag.Name), - RPCConfig: oprpc.ReadCLIConfig(ctx), - LogConfig: oplog.ReadCLIConfig(ctx), - MetricsConfig: opmetrics.ReadCLIConfig(ctx), - PprofConfig: oppprof.ReadCLIConfig(ctx), + AllowNonFinalized: ctx.Bool(flags.AllowNonFinalizedFlag.Name), + RPCConfig: oprpc.ReadCLIConfig(ctx), + LogConfig: oplog.ReadCLIConfig(ctx), + MetricsConfig: opmetrics.ReadCLIConfig(ctx), + PprofConfig: oppprof.ReadCLIConfig(ctx), + DGFAddress: ctx.String(flags.DisputeGameFactoryAddressFlag.Name), + ProposalInterval: ctx.Duration(flags.ProposalIntervalFlag.Name), + DisputeGameType: uint32(ctx.Uint(flags.DisputeGameTypeFlag.Name)), + ActiveSequencerCheckDuration: ctx.Duration(flags.ActiveSequencerCheckDurationFlag.Name), } } diff --git a/op-proposer/proposer/driver.go b/op-proposer/proposer/driver.go new file mode 100644 index 000000000000..2364723243bd --- /dev/null +++ b/op-proposer/proposer/driver.go @@ -0,0 +1,488 @@ +package proposer + +import ( + "context" + "errors" + "fmt" + "math/big" + _ "net/http/pprof" + "sync" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-proposer/metrics" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/txmgr" +) + +var ( + supportedL2OutputVersion = eth.Bytes32{} + ErrProposerNotRunning = errors.New("proposer is not running") +) + +type L1Client interface { + HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) + // CodeAt returns the code of the given account. This is needed to differentiate + // between contract internal errors and the local chain being out of sync. + CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) + + // CallContract executes an Ethereum contract call with the specified data as the + // input. + CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) +} + +type RollupClient interface { + SyncStatus(ctx context.Context) (*eth.SyncStatus, error) + OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) +} + +type DriverSetup struct { + Log log.Logger + Metr metrics.Metricer + Cfg ProposerConfig + Txmgr txmgr.TxManager + L1Client L1Client + + // RollupProvider's RollupClient() is used to retrieve output roots from + RollupProvider dial.RollupProvider +} + +// L2OutputSubmitter is responsible for proposing outputs +type L2OutputSubmitter struct { + DriverSetup + + wg sync.WaitGroup + done chan struct{} + + ctx context.Context + cancel context.CancelFunc + + mutex sync.Mutex + running bool + + l2ooContract *bindings.L2OutputOracleCaller + l2ooABI *abi.ABI + + dgfContract *bindings.DisputeGameFactoryCaller + dgfABI *abi.ABI +} + +// NewL2OutputSubmitter creates a new L2 Output Submitter +func NewL2OutputSubmitter(setup DriverSetup) (_ *L2OutputSubmitter, err error) { + ctx, cancel := context.WithCancel(context.Background()) + // The above context is long-lived, and passed to the `L2OutputSubmitter` instance. This context is closed by + // `StopL2OutputSubmitting`, but if this function returns an error or panics, we want to ensure that the context + // doesn't leak. + defer func() { + if err != nil || recover() != nil { + cancel() + } + }() + + if setup.Cfg.L2OutputOracleAddr != nil { + return newL2OOSubmitter(ctx, cancel, setup) + } else if setup.Cfg.DisputeGameFactoryAddr != nil { + return newDGFSubmitter(ctx, cancel, setup) + } else { + return nil, errors.New("neither the `L2OutputOracle` nor `DisputeGameFactory` addresses were provided") + } +} + +func newL2OOSubmitter(ctx context.Context, cancel context.CancelFunc, setup DriverSetup) (*L2OutputSubmitter, error) { + l2ooContract, err := bindings.NewL2OutputOracleCaller(*setup.Cfg.L2OutputOracleAddr, setup.L1Client) + if err != nil { + cancel() + return nil, fmt.Errorf("failed to create L2OO at address %s: %w", setup.Cfg.L2OutputOracleAddr, err) + } + + cCtx, cCancel := context.WithTimeout(ctx, setup.Cfg.NetworkTimeout) + defer cCancel() + version, err := l2ooContract.Version(&bind.CallOpts{Context: cCtx}) + if err != nil { + cancel() + return nil, err + } + log.Info("Connected to L2OutputOracle", "address", setup.Cfg.L2OutputOracleAddr, "version", version) + + parsed, err := bindings.L2OutputOracleMetaData.GetAbi() + if err != nil { + cancel() + return nil, err + } + + return &L2OutputSubmitter{ + DriverSetup: setup, + done: make(chan struct{}), + ctx: ctx, + cancel: cancel, + + l2ooContract: l2ooContract, + l2ooABI: parsed, + }, nil +} + +func newDGFSubmitter(ctx context.Context, cancel context.CancelFunc, setup DriverSetup) (*L2OutputSubmitter, error) { + dgfCaller, err := bindings.NewDisputeGameFactoryCaller(*setup.Cfg.DisputeGameFactoryAddr, setup.L1Client) + if err != nil { + cancel() + return nil, fmt.Errorf("failed to create DGF at address %s: %w", setup.Cfg.DisputeGameFactoryAddr, err) + } + + cCtx, cCancel := context.WithTimeout(ctx, setup.Cfg.NetworkTimeout) + defer cCancel() + version, err := dgfCaller.Version(&bind.CallOpts{Context: cCtx}) + if err != nil { + cancel() + return nil, err + } + log.Info("Connected to DisputeGameFactory", "address", setup.Cfg.DisputeGameFactoryAddr, "version", version) + + parsed, err := bindings.DisputeGameFactoryMetaData.GetAbi() + if err != nil { + cancel() + return nil, err + } + + return &L2OutputSubmitter{ + DriverSetup: setup, + done: make(chan struct{}), + ctx: ctx, + cancel: cancel, + + dgfContract: dgfCaller, + dgfABI: parsed, + }, nil +} + +func (l *L2OutputSubmitter) StartL2OutputSubmitting() error { + l.Log.Info("Starting Proposer") + + l.mutex.Lock() + defer l.mutex.Unlock() + + if l.running { + return errors.New("proposer is already running") + } + l.running = true + + l.wg.Add(1) + go l.loop() + + l.Log.Info("Proposer started") + return nil +} + +func (l *L2OutputSubmitter) StopL2OutputSubmittingIfRunning() error { + err := l.StopL2OutputSubmitting() + if errors.Is(err, ErrProposerNotRunning) { + return nil + } + return err +} + +func (l *L2OutputSubmitter) StopL2OutputSubmitting() error { + l.Log.Info("Stopping Proposer") + + l.mutex.Lock() + defer l.mutex.Unlock() + + if !l.running { + return ErrProposerNotRunning + } + l.running = false + + l.cancel() + close(l.done) + l.wg.Wait() + + l.Log.Info("Proposer stopped") + return nil +} + +// FetchNextOutputInfo gets the block number of the next proposal. +// It returns: the next block number, if the proposal should be made, error +func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.OutputResponse, bool, error) { + if l.l2ooContract == nil { + return nil, false, fmt.Errorf("L2OutputOracle contract not set, cannot fetch next output info") + } + + cCtx, cancel := context.WithTimeout(ctx, l.Cfg.NetworkTimeout) + defer cancel() + callOpts := &bind.CallOpts{ + From: l.Txmgr.From(), + Context: cCtx, + } + nextCheckpointBlock, err := l.l2ooContract.NextBlockNumber(callOpts) + if err != nil { + l.Log.Error("proposer unable to get next block number", "err", err) + return nil, false, err + } + // Fetch the current L2 heads + currentBlockNumber, err := l.FetchCurrentBlockNumber(ctx) + if err != nil { + return nil, false, err + } + + // Ensure that we do not submit a block in the future + if currentBlockNumber.Cmp(nextCheckpointBlock) < 0 { + l.Log.Debug("proposer submission interval has not elapsed", "currentBlockNumber", currentBlockNumber, "nextBlockNumber", nextCheckpointBlock) + return nil, false, nil + } + + return l.FetchOutput(ctx, nextCheckpointBlock) +} + +// FetchCurrentBlockNumber gets the current block number from the [L2OutputSubmitter]'s [RollupClient]. If the `AllowNonFinalized` configuration +// option is set, it will return the safe head block number, and if not, it will return the finalized head block number. +func (l *L2OutputSubmitter) FetchCurrentBlockNumber(ctx context.Context) (*big.Int, error) { + cCtx, cancel := context.WithTimeout(ctx, l.Cfg.NetworkTimeout) + defer cancel() + rollupClient, err := l.RollupProvider.RollupClient(cCtx) + if err != nil { + l.Log.Error("proposer unable to get rollup client", "err", err) + return nil, err + } + status, err := rollupClient.SyncStatus(cCtx) + if err != nil { + l.Log.Error("proposer unable to get sync status", "err", err) + return nil, err + } + + // Use either the finalized or safe head depending on the config. Finalized head is default & safer. + var currentBlockNumber *big.Int + if l.Cfg.AllowNonFinalized { + currentBlockNumber = new(big.Int).SetUint64(status.SafeL2.Number) + } else { + currentBlockNumber = new(big.Int).SetUint64(status.FinalizedL2.Number) + } + return currentBlockNumber, nil +} + +func (l *L2OutputSubmitter) FetchOutput(ctx context.Context, block *big.Int) (*eth.OutputResponse, bool, error) { + ctx, cancel := context.WithTimeout(ctx, l.Cfg.NetworkTimeout) + defer cancel() + + rollupClient, err := l.RollupProvider.RollupClient(ctx) + if err != nil { + l.Log.Error("proposer unable to get rollup client", "err", err) + return nil, false, err + } + output, err := rollupClient.OutputAtBlock(ctx, block.Uint64()) + if err != nil { + l.Log.Error("failed to fetch output at block", "block", block, "err", err) + return nil, false, err + } + if output.Version != supportedL2OutputVersion { + l.Log.Error("unsupported l2 output version", "output_version", output.Version, "supported_version", supportedL2OutputVersion) + return nil, false, errors.New("unsupported l2 output version") + } + if output.BlockRef.Number != block.Uint64() { // sanity check, e.g. in case of bad RPC caching + l.Log.Error("invalid blockNumber", "next_block", block, "output_block", output.BlockRef.Number) + return nil, false, errors.New("invalid blockNumber") + } + + // Always propose if it's part of the Finalized L2 chain. Or if allowed, if it's part of the safe L2 chain. + if output.BlockRef.Number > output.Status.FinalizedL2.Number && (!l.Cfg.AllowNonFinalized || output.BlockRef.Number > output.Status.SafeL2.Number) { + l.Log.Debug("not proposing yet, L2 block is not ready for proposal", + "l2_proposal", output.BlockRef, + "l2_safe", output.Status.SafeL2, + "l2_finalized", output.Status.FinalizedL2, + "allow_non_finalized", l.Cfg.AllowNonFinalized) + return nil, false, nil + } + return output, true, nil +} + +// ProposeL2OutputTxData creates the transaction data for the ProposeL2Output function +func (l *L2OutputSubmitter) ProposeL2OutputTxData(output *eth.OutputResponse) ([]byte, error) { + if l.Cfg.AllowNonFinalized { + return proposeL2OutputTxData(l.l2ooABI, output, true) + } + return proposeL2OutputTxData(l.l2ooABI, output, false) +} + +// proposeL2OutputTxData creates the transaction data for the ProposeL2Output function +func proposeL2OutputTxData(abi *abi.ABI, output *eth.OutputResponse, withCurrentL1Hash bool) ([]byte, error) { + currentL1Hash := common.Hash{} + if withCurrentL1Hash { + currentL1Hash = output.Status.CurrentL1.Hash + } + + return abi.Pack( + "proposeL2Output", + output.OutputRoot, + new(big.Int).SetUint64(output.BlockRef.Number), + currentL1Hash, + new(big.Int).SetUint64(output.Status.CurrentL1.Number), + ) +} + +func (l *L2OutputSubmitter) ProposeL2OutputDGFTxData(output *eth.OutputResponse) ([]byte, *big.Int, error) { + bond, err := l.dgfContract.InitBonds(&bind.CallOpts{}, l.Cfg.DisputeGameType) + if err != nil { + return nil, nil, err + } + data, err := proposeL2OutputDGFTxData(l.dgfABI, l.Cfg.DisputeGameType, output) + if err != nil { + return nil, nil, err + } + return data, bond, err +} + +// proposeL2OutputDGFTxData creates the transaction data for the DisputeGameFactory's `create` function +func proposeL2OutputDGFTxData(abi *abi.ABI, gameType uint32, output *eth.OutputResponse) ([]byte, error) { + return abi.Pack("create", gameType, output.OutputRoot, math.U256Bytes(new(big.Int).SetUint64(output.BlockRef.Number))) +} + +// We wait until l1head advances beyond blocknum. This is used to make sure proposal tx won't +// immediately fail when checking the l1 blockhash. Note that EstimateGas uses "latest" state to +// execute the transaction by default, meaning inside the call, the head block is considered +// "pending" instead of committed. In the case l1blocknum == l1head then, blockhash(l1blocknum) +// will produce a value of 0 within EstimateGas, and the call will fail when the contract checks +// that l1blockhash matches blockhash(l1blocknum). +func (l *L2OutputSubmitter) waitForL1Head(ctx context.Context, blockNum uint64) error { + ticker := time.NewTicker(l.Cfg.PollInterval) + defer ticker.Stop() + l1head, err := l.Txmgr.BlockNumber(ctx) + if err != nil { + return err + } + for l1head <= blockNum { + l.Log.Debug("waiting for l1 head > l1blocknum1+1", "l1head", l1head, "l1blocknum", blockNum) + select { + case <-ticker.C: + l1head, err = l.Txmgr.BlockNumber(ctx) + if err != nil { + return err + } + case <-l.done: + return fmt.Errorf("L2OutputSubmitter is done()") + } + } + return nil +} + +// sendTransaction creates & sends transactions through the underlying transaction manager. +func (l *L2OutputSubmitter) sendTransaction(ctx context.Context, output *eth.OutputResponse) error { + err := l.waitForL1Head(ctx, output.Status.HeadL1.Number+1) + if err != nil { + return err + } + + var receipt *types.Receipt + if l.Cfg.DisputeGameFactoryAddr != nil { + data, bond, err := l.ProposeL2OutputDGFTxData(output) + if err != nil { + return err + } + receipt, err = l.Txmgr.Send(ctx, txmgr.TxCandidate{ + TxData: data, + To: l.Cfg.DisputeGameFactoryAddr, + GasLimit: 0, + Value: bond, + }) + if err != nil { + return err + } + } else { + data, err := l.ProposeL2OutputTxData(output) + if err != nil { + return err + } + receipt, err = l.Txmgr.Send(ctx, txmgr.TxCandidate{ + TxData: data, + To: l.Cfg.L2OutputOracleAddr, + GasLimit: 0, + }) + if err != nil { + return err + } + } + + if receipt.Status == types.ReceiptStatusFailed { + l.Log.Error("proposer tx successfully published but reverted", "tx_hash", receipt.TxHash) + } else { + l.Log.Info("proposer tx successfully published", + "tx_hash", receipt.TxHash, + "l1blocknum", output.Status.CurrentL1.Number, + "l1blockhash", output.Status.CurrentL1.Hash) + } + return nil +} + +// loop is responsible for creating & submitting the next outputs +func (l *L2OutputSubmitter) loop() { + defer l.wg.Done() + ctx := l.ctx + + if l.dgfContract == nil { + l.loopL2OO(ctx) + } else { + l.loopDGF(ctx) + } +} + +func (l *L2OutputSubmitter) loopL2OO(ctx context.Context) { + ticker := time.NewTicker(l.Cfg.PollInterval) + defer ticker.Stop() + for { + select { + case <-ticker.C: + output, shouldPropose, err := l.FetchNextOutputInfo(ctx) + if err != nil || !shouldPropose { + break + } + + l.proposeOutput(ctx, output) + case <-l.done: + return + } + } +} + +func (l *L2OutputSubmitter) loopDGF(ctx context.Context) { + ticker := time.NewTicker(l.Cfg.ProposalInterval) + defer ticker.Stop() + for { + select { + case <-ticker.C: + blockNumber, err := l.FetchCurrentBlockNumber(ctx) + if err != nil { + break + } + + output, shouldPropose, err := l.FetchOutput(ctx, blockNumber) + if err != nil || !shouldPropose { + break + } + + l.proposeOutput(ctx, output) + case <-l.done: + return + } + } +} + +func (l *L2OutputSubmitter) proposeOutput(ctx context.Context, output *eth.OutputResponse) { + cCtx, cancel := context.WithTimeout(ctx, 10*time.Minute) + defer cancel() + + if err := l.sendTransaction(cCtx, output); err != nil { + l.Log.Error("Failed to send proposal transaction", + "err", err, + "l1blocknum", output.Status.CurrentL1.Number, + "l1blockhash", output.Status.CurrentL1.Hash, + "l1head", output.Status.HeadL1.Number) + return + } + l.Metr.RecordL2BlocksProposed(output.BlockRef) +} diff --git a/op-proposer/proposer/l2_output_submitter.go b/op-proposer/proposer/l2_output_submitter.go index 0f46dbbeddb9..695955e17c0f 100644 --- a/op-proposer/proposer/l2_output_submitter.go +++ b/op-proposer/proposer/l2_output_submitter.go @@ -2,439 +2,38 @@ package proposer import ( "context" - "errors" "fmt" - "math/big" - _ "net/http/pprof" - "sync" - "time" "github.com/urfave/cli/v2" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" + opaws "github.com/ethereum-optimism/optimism/op-aws-sdk" "github.com/ethereum-optimism/optimism/op-proposer/flags" - "github.com/ethereum-optimism/optimism/op-proposer/metrics" opservice "github.com/ethereum-optimism/optimism/op-service" - "github.com/ethereum-optimism/optimism/op-service/client" - "github.com/ethereum-optimism/optimism/op-service/dial" - "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/cliapp" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum-optimism/optimism/op-service/opio" - oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" - oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" - "github.com/ethereum-optimism/optimism/op-service/sources" - "github.com/ethereum-optimism/optimism/op-service/txmgr" ) -var supportedL2OutputVersion = eth.Bytes32{} - -// Main is the entrypoint into the L2 Output Submitter. This method executes the -// service and blocks until the service exits. -func Main(version string, cliCtx *cli.Context) error { - if err := flags.CheckRequired(cliCtx); err != nil { - return err - } - cfg := NewConfig(cliCtx) - if err := cfg.Check(); err != nil { - return fmt.Errorf("invalid CLI flags: %w", err) - } - - l := oplog.NewLogger(oplog.AppOut(cliCtx), cfg.LogConfig) - oplog.SetGlobalLogHandler(l.GetHandler()) - opservice.ValidateEnvVars(flags.EnvVarPrefix, flags.Flags, l) - m := metrics.NewMetrics("default") - l.Info("Initializing L2 Output Submitter") - - proposerConfig, err := NewL2OutputSubmitterConfigFromCLIConfig(cfg, l, m) - if err != nil { - l.Error("Unable to create the L2 Output Submitter", "error", err) - return err - } - - l2OutputSubmitter, err := NewL2OutputSubmitter(*proposerConfig, l, m) - if err != nil { - l.Error("Unable to create the L2 Output Submitter", "error", err) - return err - } - - l.Info("Starting L2 Output Submitter") - if err := l2OutputSubmitter.Start(); err != nil { - l.Error("Unable to start L2 Output Submitter", "error", err) - return err - } - defer l2OutputSubmitter.Stop() - - l.Info("L2 Output Submitter started") - pprofConfig := cfg.PprofConfig - if pprofConfig.Enabled { - l.Debug("starting pprof", "addr", pprofConfig.ListenAddr, "port", pprofConfig.ListenPort) - pprofSrv, err := oppprof.StartServer(pprofConfig.ListenAddr, pprofConfig.ListenPort) - if err != nil { - l.Error("failed to start pprof server", "err", err) - return err +// Main is the entrypoint into the L2OutputSubmitter. +// This method returns a cliapp.LifecycleAction, to create an op-service CLI-lifecycle-managed L2Output-submitter +func Main(version string) cliapp.LifecycleAction { + return func(cliCtx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, error) { + if err := opaws.KeyManager(context.Background(), cliCtx, opaws.OP_PROPOSER_SIGN_KEY); err != nil { + return nil, err } - l.Info("started pprof server", "addr", pprofSrv.Addr()) - defer func() { - if err := pprofSrv.Stop(context.Background()); err != nil { - l.Error("failed to stop pprof server", "err", err) - } - }() - } - metricsCfg := cfg.MetricsConfig - if metricsCfg.Enabled { - l.Debug("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort) - metricsSrv, err := m.Start(metricsCfg.ListenAddr, metricsCfg.ListenPort) - if err != nil { - return fmt.Errorf("failed to start metrics server: %w", err) + if err := flags.CheckRequired(cliCtx); err != nil { + return nil, err } - l.Info("started metrics server", "addr", metricsSrv.Addr()) - defer func() { - if err := metricsSrv.Stop(context.Background()); err != nil { - l.Error("failed to stop metrics server", "err", err) - } - }() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - m.StartBalanceMetrics(ctx, l, proposerConfig.L1Client, proposerConfig.TxManager.From()) - } - - rpcCfg := cfg.RPCConfig - server := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version, oprpc.WithLogger(l)) - if rpcCfg.EnableAdmin { - server.AddAPI(oprpc.ToGethAdminAPI(oprpc.NewCommonAdminAPI(&m.RPCMetrics, l))) - l.Info("Admin RPC enabled") - } - if err := server.Start(); err != nil { - return fmt.Errorf("error starting RPC server: %w", err) - } - - m.RecordInfo(version) - m.RecordUp() - - opio.BlockOnInterrupts() - - return nil -} - -// L2OutputSubmitter is responsible for proposing outputs -type L2OutputSubmitter struct { - txMgr txmgr.TxManager - wg sync.WaitGroup - done chan struct{} - log log.Logger - metr metrics.Metricer - - ctx context.Context - cancel context.CancelFunc - - // RollupClient is used to retrieve output roots from - rollupClient *sources.RollupClient - - l2ooContract *bindings.L2OutputOracleCaller - l2ooContractAddr common.Address - l2ooABI *abi.ABI - - // AllowNonFinalized enables the proposal of safe, but non-finalized L2 blocks. - // The L1 block-hash embedded in the proposal TX is checked and should ensure the proposal - // is never valid on an alternative L1 chain that would produce different L2 data. - // This option is not necessary when higher proposal latency is acceptable and L1 is healthy. - allowNonFinalized bool - // How frequently to poll L2 for new finalized outputs - pollInterval time.Duration - networkTimeout time.Duration -} - -// NewL2OutputSubmitterFromCLIConfig creates a new L2 Output Submitter given the CLI Config -func NewL2OutputSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger, m metrics.Metricer) (*L2OutputSubmitter, error) { - proposerConfig, err := NewL2OutputSubmitterConfigFromCLIConfig(cfg, l, m) - if err != nil { - return nil, err - } - return NewL2OutputSubmitter(*proposerConfig, l, m) -} - -// NewL2OutputSubmitterConfigFromCLIConfig creates the proposer config from the CLI config. -func NewL2OutputSubmitterConfigFromCLIConfig(cfg CLIConfig, l log.Logger, m metrics.Metricer) (*Config, error) { - l2ooAddress, err := opservice.ParseAddress(cfg.L2OOAddress) - if err != nil { - return nil, err - } - - txManager, err := txmgr.NewSimpleTxManager("proposer", l, m, cfg.TxMgrConfig) - if err != nil { - return nil, err - } - - // Connect to L1 and L2 providers. Perform these last since they are the most expensive. - l1Client, err := dial.DialEthClientWithTimeoutAndFallback(context.Background(), cfg.L1EthRpc, dial.DefaultDialTimeout, l, dial.ProposerFallbackThreshold, m) - if err != nil { - return nil, err - } - l1Client = client.NewInstrumentedClient(l1Client, m) - - rollupClient, err := dial.DialRollupClientWithTimeout(context.Background(), dial.DefaultDialTimeout, l, cfg.RollupRpc) - if err != nil { - return nil, err - } - - return &Config{ - L2OutputOracleAddr: l2ooAddress, - PollInterval: cfg.PollInterval, - NetworkTimeout: cfg.TxMgrConfig.NetworkTimeout, - L1Client: l1Client, - RollupClient: rollupClient, - AllowNonFinalized: cfg.AllowNonFinalized, - TxManager: txManager, - }, nil - -} - -// NewL2OutputSubmitter creates a new L2 Output Submitter -func NewL2OutputSubmitter(cfg Config, l log.Logger, m metrics.Metricer) (*L2OutputSubmitter, error) { - ctx, cancel := context.WithCancel(context.Background()) - - l2ooContract, err := bindings.NewL2OutputOracleCaller(cfg.L2OutputOracleAddr, cfg.L1Client) - if err != nil { - cancel() - return nil, fmt.Errorf("failed to create L2OO at address %s: %w", cfg.L2OutputOracleAddr, err) - } - - cCtx, cCancel := context.WithTimeout(ctx, cfg.NetworkTimeout) - defer cCancel() - version, err := l2ooContract.Version(&bind.CallOpts{Context: cCtx}) - if err != nil { - cancel() - return nil, err - } - log.Info("Connected to L2OutputOracle", "address", cfg.L2OutputOracleAddr, "version", version) - - parsed, err := bindings.L2OutputOracleMetaData.GetAbi() - if err != nil { - cancel() - return nil, err - } - - return &L2OutputSubmitter{ - txMgr: cfg.TxManager, - done: make(chan struct{}), - log: l, - ctx: ctx, - cancel: cancel, - metr: m, - - rollupClient: cfg.RollupClient, - - l2ooContract: l2ooContract, - l2ooContractAddr: cfg.L2OutputOracleAddr, - l2ooABI: parsed, - - allowNonFinalized: cfg.AllowNonFinalized, - pollInterval: cfg.PollInterval, - networkTimeout: cfg.NetworkTimeout, - }, nil -} - -func (l *L2OutputSubmitter) Start() error { - l.wg.Add(1) - go l.loop() - return nil -} - -func (l *L2OutputSubmitter) Stop() { - l.cancel() - close(l.done) - l.wg.Wait() -} - -// FetchNextOutputInfo gets the block number of the next proposal. -// It returns: the next block number, if the proposal should be made, error -func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.OutputResponse, bool, error) { - cCtx, cancel := context.WithTimeout(ctx, l.networkTimeout) - defer cancel() - callOpts := &bind.CallOpts{ - From: l.txMgr.From(), - Context: cCtx, - } - nextCheckpointBlock, err := l.l2ooContract.NextBlockNumber(callOpts) - if err != nil { - l.log.Error("proposer unable to get next block number", "err", err) - return nil, false, err - } - // Fetch the current L2 heads - cCtx, cancel = context.WithTimeout(ctx, l.networkTimeout) - defer cancel() - status, err := l.rollupClient.SyncStatus(cCtx) - if err != nil { - l.log.Error("proposer unable to get sync status", "err", err) - return nil, false, err - } - - // Use either the finalized or safe head depending on the config. Finalized head is default & safer. - var currentBlockNumber *big.Int - if l.allowNonFinalized { - currentBlockNumber = new(big.Int).SetUint64(status.SafeL2.Number) - } else { - currentBlockNumber = new(big.Int).SetUint64(status.FinalizedL2.Number) - } - // Ensure that we do not submit a block in the future - if currentBlockNumber.Cmp(nextCheckpointBlock) < 0 { - l.log.Debug("proposer submission interval has not elapsed", "currentBlockNumber", currentBlockNumber, "nextBlockNumber", nextCheckpointBlock) - return nil, false, nil - } - - return l.fetchOutput(ctx, nextCheckpointBlock) -} - -func (l *L2OutputSubmitter) fetchOutput(ctx context.Context, block *big.Int) (*eth.OutputResponse, bool, error) { - ctx, cancel := context.WithTimeout(ctx, l.networkTimeout) - defer cancel() - output, err := l.rollupClient.OutputAtBlock(ctx, block.Uint64()) - if err != nil { - l.log.Error("failed to fetch output at block %d: %w", block, err) - return nil, false, err - } - if output.Version != supportedL2OutputVersion { - l.log.Error("unsupported l2 output version: %s", output.Version) - return nil, false, errors.New("unsupported l2 output version") - } - if output.BlockRef.Number != block.Uint64() { // sanity check, e.g. in case of bad RPC caching - l.log.Error("invalid blockNumber: next blockNumber is %v, blockNumber of block is %v", block, output.BlockRef.Number) - return nil, false, errors.New("invalid blockNumber") - } - - // Always propose if it's part of the Finalized L2 chain. Or if allowed, if it's part of the safe L2 chain. - if !(output.BlockRef.Number <= output.Status.FinalizedL2.Number || (l.allowNonFinalized && output.BlockRef.Number <= output.Status.SafeL2.Number)) { - l.log.Debug("not proposing yet, L2 block is not ready for proposal", - "l2_proposal", output.BlockRef, - "l2_safe", output.Status.SafeL2, - "l2_finalized", output.Status.FinalizedL2, - "allow_non_finalized", l.allowNonFinalized) - return nil, false, nil - } - return output, true, nil -} - -// ProposeL2OutputTxData creates the transaction data for the ProposeL2Output function -func (l *L2OutputSubmitter) ProposeL2OutputTxData(output *eth.OutputResponse) ([]byte, error) { - if l.allowNonFinalized { - return proposeL2OutputTxData(l.l2ooABI, output, true) - } - return proposeL2OutputTxData(l.l2ooABI, output, false) -} - -// proposeL2OutputTxData creates the transaction data for the ProposeL2Output function -func proposeL2OutputTxData(abi *abi.ABI, output *eth.OutputResponse, withCurrentL1Hash bool) ([]byte, error) { - currentL1Hash := common.Hash{} - if withCurrentL1Hash { - currentL1Hash = output.Status.CurrentL1.Hash - } - - return abi.Pack( - "proposeL2Output", - output.OutputRoot, - new(big.Int).SetUint64(output.BlockRef.Number), - currentL1Hash, - new(big.Int).SetUint64(output.Status.CurrentL1.Number)) -} - -// We wait until l1head advances beyond blocknum. This is used to make sure proposal tx won't -// immediately fail when checking the l1 blockhash. Note that EstimateGas uses "latest" state to -// execute the transaction by default, meaning inside the call, the head block is considered -// "pending" instead of committed. In the case l1blocknum == l1head then, blockhash(l1blocknum) -// will produce a value of 0 within EstimateGas, and the call will fail when the contract checks -// that l1blockhash matches blockhash(l1blocknum). -func (l *L2OutputSubmitter) waitForL1Head(ctx context.Context, blockNum uint64) error { - ticker := time.NewTicker(l.pollInterval) - defer ticker.Stop() - l1head, err := l.txMgr.BlockNumber(ctx) - if err != nil { - return err - } - for l1head <= blockNum { - l.log.Debug("waiting for l1 head > l1blocknum1+1", "l1head", l1head, "l1blocknum", blockNum) - select { - case <-ticker.C: - l1head, err = l.txMgr.BlockNumber(ctx) - if err != nil { - return err - } - break - case <-l.done: - return fmt.Errorf("L2OutputSubmitter is done()") + cfg := NewConfig(cliCtx) + if err := cfg.Check(); err != nil { + return nil, fmt.Errorf("invalid CLI flags: %w", err) } - } - return nil -} -// sendTransaction creates & sends transactions through the underlying transaction manager. -func (l *L2OutputSubmitter) sendTransaction(ctx context.Context, output *eth.OutputResponse) error { - err := l.waitForL1Head(ctx, output.Status.HeadL1.Number+1) - if err != nil { - return err - } - data, err := l.ProposeL2OutputTxData(output) - if err != nil { - return err - } - receipt, err := l.txMgr.Send(ctx, txmgr.TxCandidate{ - TxData: data, - To: &l.l2ooContractAddr, - GasLimit: 0, - }) - if err != nil { - return err - } - if receipt.Status == types.ReceiptStatusFailed { - l.log.Error("proposer tx successfully published but reverted", "tx_hash", receipt.TxHash) - } else { - l.log.Info("proposer tx successfully published", - "tx_hash", receipt.TxHash, - "l1blocknum", output.Status.CurrentL1.Number, - "l1blockhash", output.Status.CurrentL1.Hash) - } - return nil -} - -// loop is responsible for creating & submitting the next outputs -func (l *L2OutputSubmitter) loop() { - defer l.wg.Done() - - ctx := l.ctx + l := oplog.NewLogger(oplog.AppOut(cliCtx), cfg.LogConfig) + oplog.SetGlobalLogHandler(l.Handler()) + opservice.ValidateEnvVars(flags.EnvVarPrefix, flags.Flags, l) - ticker := time.NewTicker(l.pollInterval) - defer ticker.Stop() - for { - select { - case <-ticker.C: - output, shouldPropose, err := l.FetchNextOutputInfo(ctx) - if err != nil { - break - } - if !shouldPropose { - break - } - cCtx, cancel := context.WithTimeout(ctx, 10*time.Minute) - if err := l.sendTransaction(cCtx, output); err != nil { - l.log.Error("Failed to send proposal transaction", - "err", err, - "l1blocknum", output.Status.CurrentL1.Number, - "l1blockhash", output.Status.CurrentL1.Hash, - "l1head", output.Status.HeadL1.Number) - cancel() - break - } - l.metr.RecordL2BlocksProposed(output.BlockRef) - cancel() - - case <-l.done: - return - } + l.Info("Initializing L2Output Submitter") + return ProposerServiceFromCLIConfig(cliCtx.Context, version, cfg, l) } } diff --git a/op-proposer/proposer/rpc/api.go b/op-proposer/proposer/rpc/api.go new file mode 100644 index 000000000000..56b5fd28431e --- /dev/null +++ b/op-proposer/proposer/rpc/api.go @@ -0,0 +1,43 @@ +package rpc + +import ( + "context" + + "github.com/ethereum/go-ethereum/log" + gethrpc "github.com/ethereum/go-ethereum/rpc" + + "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/rpc" +) + +type ProposerDriver interface { + StartL2OutputSubmitting() error + StopL2OutputSubmitting() error +} + +type adminAPI struct { + *rpc.CommonAdminAPI + b ProposerDriver +} + +func NewAdminAPI(dr ProposerDriver, m metrics.RPCMetricer, log log.Logger) *adminAPI { + return &adminAPI{ + CommonAdminAPI: rpc.NewCommonAdminAPI(m, log), + b: dr, + } +} + +func GetAdminAPI(api *adminAPI) gethrpc.API { + return gethrpc.API{ + Namespace: "admin", + Service: api, + } +} + +func (a *adminAPI) StartProposer(_ context.Context) error { + return a.b.StartL2OutputSubmitting() +} + +func (a *adminAPI) StopProposer(ctx context.Context) error { + return a.b.StopL2OutputSubmitting() +} diff --git a/op-proposer/proposer/service.go b/op-proposer/proposer/service.go new file mode 100644 index 000000000000..1045353e464b --- /dev/null +++ b/op-proposer/proposer/service.go @@ -0,0 +1,342 @@ +package proposer + +import ( + "context" + "errors" + "fmt" + "io" + "strings" + "sync/atomic" + "time" + + "github.com/ethereum-optimism/optimism/op-proposer/metrics" + "github.com/ethereum-optimism/optimism/op-proposer/proposer/rpc" + opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/cliapp" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/httputil" + opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/oppprof" + oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +var ErrAlreadyStopped = errors.New("already stopped") + +type ProposerConfig struct { + // How frequently to poll L2 for new finalized outputs + PollInterval time.Duration + NetworkTimeout time.Duration + + // How frequently to post L2 outputs when the DisputeGameFactory is configured + ProposalInterval time.Duration + + L2OutputOracleAddr *common.Address + DisputeGameFactoryAddr *common.Address + DisputeGameType uint32 + + // AllowNonFinalized enables the proposal of safe, but non-finalized L2 blocks. + // The L1 block-hash embedded in the proposal TX is checked and should ensure the proposal + // is never valid on an alternative L1 chain that would produce different L2 data. + // This option is not necessary when higher proposal latency is acceptable and L1 is healthy. + AllowNonFinalized bool +} + +type ProposerService struct { + Log log.Logger + Metrics metrics.Metricer + + ProposerConfig + + TxManager txmgr.TxManager + L1Client client.Client + RollupProvider dial.RollupProvider + + driver *L2OutputSubmitter + + Version string + + pprofService *oppprof.Service + metricsSrv *httputil.HTTPServer + rpcServer *oprpc.Server + + balanceMetricer io.Closer + + stopped atomic.Bool +} + +// ProposerServiceFromCLIConfig creates a new ProposerService from a CLIConfig. +// The service components are fully started, except for the driver, +// which will not be submitting state (if it was configured to) until the Start part of the lifecycle. +func ProposerServiceFromCLIConfig(ctx context.Context, version string, cfg *CLIConfig, log log.Logger) (*ProposerService, error) { + var ps ProposerService + if err := ps.initFromCLIConfig(ctx, version, cfg, log); err != nil { + return nil, errors.Join(err, ps.Stop(ctx)) // try to clean up our failed initialization attempt + } + return &ps, nil +} + +func (ps *ProposerService) initFromCLIConfig(ctx context.Context, version string, cfg *CLIConfig, log log.Logger) error { + ps.Version = version + ps.Log = log + + ps.initMetrics(cfg) + + ps.PollInterval = cfg.PollInterval + ps.NetworkTimeout = cfg.TxMgrConfig.NetworkTimeout + ps.AllowNonFinalized = cfg.AllowNonFinalized + + ps.initL2ooAddress(cfg) + ps.initDGF(cfg) + + if err := ps.initRPCClients(ctx, cfg); err != nil { + return err + } + if err := ps.initTxManager(cfg); err != nil { + return fmt.Errorf("failed to init Tx manager: %w", err) + } + ps.initBalanceMonitor(cfg) + if err := ps.initMetricsServer(cfg); err != nil { + return fmt.Errorf("failed to start metrics server: %w", err) + } + if err := ps.initPProf(cfg); err != nil { + return fmt.Errorf("failed to init profiling: %w", err) + } + if err := ps.initDriver(); err != nil { + return fmt.Errorf("failed to init Driver: %w", err) + } + if err := ps.initRPCServer(cfg); err != nil { + return fmt.Errorf("failed to start RPC server: %w", err) + } + + ps.Metrics.RecordInfo(ps.Version) + ps.Metrics.RecordUp() + return nil +} + +func (ps *ProposerService) initRPCClients(ctx context.Context, cfg *CLIConfig) error { + l1Client, err := dial.DialEthClientWithTimeoutAndFallback(ctx, cfg.L1EthRpc, dial.DefaultDialTimeout, ps.Log, dial.ProposerFallbackThreshold, ps.Metrics) + if err != nil { + return fmt.Errorf("failed to dial L1 RPC: %w", err) + } + ps.L1Client = client.NewInstrumentedClient(l1Client, ps.Metrics) + + var rollupProvider dial.RollupProvider + if strings.Contains(cfg.RollupRpc, ",") { + rollupUrls := strings.Split(cfg.RollupRpc, ",") + rollupProvider, err = dial.NewActiveL2RollupProvider(ctx, rollupUrls, cfg.ActiveSequencerCheckDuration, dial.DefaultDialTimeout, ps.Log) + } else { + rollupProvider, err = dial.NewStaticL2RollupProvider(ctx, ps.Log, cfg.RollupRpc) + } + if err != nil { + return fmt.Errorf("failed to build L2 endpoint provider: %w", err) + } + ps.RollupProvider = rollupProvider + return nil +} + +func (ps *ProposerService) initMetrics(cfg *CLIConfig) { + if cfg.MetricsConfig.Enabled { + procName := "default" + ps.Metrics = metrics.NewMetrics(procName) + } else { + ps.Metrics = metrics.NoopMetrics + } +} + +// initBalanceMonitor depends on Metrics, L1Client and TxManager to start background-monitoring of the Proposer balance. +func (ps *ProposerService) initBalanceMonitor(cfg *CLIConfig) { + if cfg.MetricsConfig.Enabled { + ps.balanceMetricer = ps.Metrics.StartBalanceMetrics(ps.Log, ps.L1Client, ps.TxManager.From()) + } +} + +func (ps *ProposerService) initTxManager(cfg *CLIConfig) error { + txManager, err := txmgr.NewSimpleTxManager("proposer", ps.Log, ps.Metrics, cfg.TxMgrConfig) + if err != nil { + return err + } + ps.TxManager = txManager + return nil +} + +func (ps *ProposerService) initPProf(cfg *CLIConfig) error { + ps.pprofService = oppprof.New( + cfg.PprofConfig.ListenEnabled, + cfg.PprofConfig.ListenAddr, + cfg.PprofConfig.ListenPort, + cfg.PprofConfig.ProfileType, + cfg.PprofConfig.ProfileDir, + cfg.PprofConfig.ProfileFilename, + ) + + if err := ps.pprofService.Start(); err != nil { + return fmt.Errorf("failed to start pprof service: %w", err) + } + + return nil +} + +func (ps *ProposerService) initMetricsServer(cfg *CLIConfig) error { + if !cfg.MetricsConfig.Enabled { + ps.Log.Info("metrics disabled") + return nil + } + m, ok := ps.Metrics.(opmetrics.RegistryMetricer) + if !ok { + return fmt.Errorf("metrics were enabled, but metricer %T does not expose registry for metrics-server", ps.Metrics) + } + ps.Log.Debug("starting metrics server", "addr", cfg.MetricsConfig.ListenAddr, "port", cfg.MetricsConfig.ListenPort) + metricsSrv, err := opmetrics.StartServer(m.Registry(), cfg.MetricsConfig.ListenAddr, cfg.MetricsConfig.ListenPort) + if err != nil { + return fmt.Errorf("failed to start metrics server: %w", err) + } + ps.Log.Info("started metrics server", "addr", metricsSrv.Addr()) + ps.metricsSrv = metricsSrv + return nil +} + +func (ps *ProposerService) initL2ooAddress(cfg *CLIConfig) { + l2ooAddress, err := opservice.ParseAddress(cfg.L2OOAddress) + if err != nil { + // Return no error & set no L2OO related configuration fields. + return + } + ps.L2OutputOracleAddr = &l2ooAddress +} + +func (ps *ProposerService) initDGF(cfg *CLIConfig) { + dgfAddress, err := opservice.ParseAddress(cfg.DGFAddress) + if err != nil { + // Return no error & set no DGF related configuration fields. + return + } + ps.DisputeGameFactoryAddr = &dgfAddress + ps.ProposalInterval = cfg.ProposalInterval + ps.DisputeGameType = cfg.DisputeGameType +} + +func (ps *ProposerService) initDriver() error { + driver, err := NewL2OutputSubmitter(DriverSetup{ + Log: ps.Log, + Metr: ps.Metrics, + Cfg: ps.ProposerConfig, + Txmgr: ps.TxManager, + L1Client: ps.L1Client, + RollupProvider: ps.RollupProvider, + }) + if err != nil { + return err + } + ps.driver = driver + return nil +} + +func (ps *ProposerService) initRPCServer(cfg *CLIConfig) error { + server := oprpc.NewServer( + cfg.RPCConfig.ListenAddr, + cfg.RPCConfig.ListenPort, + ps.Version, + oprpc.WithLogger(ps.Log), + ) + if cfg.RPCConfig.EnableAdmin { + adminAPI := rpc.NewAdminAPI(ps.driver, ps.Metrics, ps.Log) + server.AddAPI(rpc.GetAdminAPI(adminAPI)) + ps.Log.Info("Admin RPC enabled") + } + ps.Log.Info("Starting JSON-RPC server") + if err := server.Start(); err != nil { + return fmt.Errorf("unable to start RPC server: %w", err) + } + ps.rpcServer = server + return nil +} + +// Start runs once upon start of the proposer lifecycle, +// and starts L2Output-submission work if the proposer is configured to start submit data on startup. +func (ps *ProposerService) Start(_ context.Context) error { + ps.driver.Log.Info("Starting Proposer") + + return ps.driver.StartL2OutputSubmitting() +} + +func (ps *ProposerService) Stopped() bool { + return ps.stopped.Load() +} + +// Kill is a convenience method to forcefully, non-gracefully, stop the ProposerService. +func (ps *ProposerService) Kill() error { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + return ps.Stop(ctx) +} + +// Stop fully stops the L2Output-submitter and all its resources gracefully. After stopping, it cannot be restarted. +// See driver.StopL2OutputSubmitting to temporarily stop the L2Output submitter. +func (ps *ProposerService) Stop(ctx context.Context) error { + if ps.stopped.Load() { + return ErrAlreadyStopped + } + ps.Log.Info("Stopping Proposer") + + var result error + if ps.driver != nil { + if err := ps.driver.StopL2OutputSubmittingIfRunning(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to stop L2Output submitting: %w", err)) + } + } + + if ps.rpcServer != nil { + // TODO(7685): the op-service RPC server is not built on top of op-service httputil Server, and has poor shutdown + if err := ps.rpcServer.Stop(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to stop RPC server: %w", err)) + } + } + if ps.pprofService != nil { + if err := ps.pprofService.Stop(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to stop PProf server: %w", err)) + } + } + if ps.balanceMetricer != nil { + if err := ps.balanceMetricer.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err)) + } + } + + if ps.TxManager != nil { + ps.TxManager.Close() + } + + if ps.metricsSrv != nil { + if err := ps.metricsSrv.Stop(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err)) + } + } + + if ps.L1Client != nil { + ps.L1Client.Close() + } + + if ps.RollupProvider != nil { + ps.RollupProvider.Close() + } + + if result == nil { + ps.stopped.Store(true) + ps.Log.Info("L2Output Submitter stopped") + } + + return result +} + +var _ cliapp.Lifecycle = (*ProposerService)(nil) + +// Driver returns the handler on the L2Output-submitter driver element, +// to start/stop/restart the L2Output-submission work, for use in testing. +func (ps *ProposerService) Driver() rpc.ProposerDriver { + return ps.driver +} diff --git a/op-service/Makefile b/op-service/Makefile index a83804af8bbc..d458b3c15aa5 100644 --- a/op-service/Makefile +++ b/op-service/Makefile @@ -4,14 +4,16 @@ test: generate-mocks: go generate ./... -.PHONY: \ - test \ - lint \ - generate-mocks \ - fuzz - fuzz: go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzExecutionPayloadUnmarshal ./eth go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzExecutionPayloadMarshalUnmarshalV1 ./eth go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzExecutionPayloadMarshalUnmarshalV2 ./eth + go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzExecutionPayloadMarshalUnmarshalV3 ./eth go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzOBP01 ./eth + go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzEncodeDecodeBlob ./eth + go test -run NOTAREALTEST -v -fuzztime 10s -fuzz FuzzDetectNonBijectivity ./eth + +.PHONY: \ + test \ + generate-mocks \ + fuzz diff --git a/op-service/cliapp/lifecycle.go b/op-service/cliapp/lifecycle.go index 3afce92898dc..2154c025645d 100644 --- a/op-service/cliapp/lifecycle.go +++ b/op-service/cliapp/lifecycle.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "os" "github.com/urfave/cli/v2" @@ -30,21 +29,22 @@ type Lifecycle interface { // a shutdown when the Stop context is not expired. type LifecycleAction func(ctx *cli.Context, close context.CancelCauseFunc) (Lifecycle, error) +var interruptErr = errors.New("interrupt signal") + // LifecycleCmd turns a LifecycleAction into an CLI action, // by instrumenting it with CLI context and signal based termination. +// The signals are caught with the opio.BlockFn attached to the context, if any. +// If no block function is provided, it adds default interrupt handling. // The app may continue to run post-processing until fully shutting down. // The user can force an early shut-down during post-processing by sending a second interruption signal. func LifecycleCmd(fn LifecycleAction) cli.ActionFunc { - return lifecycleCmd(fn, opio.BlockOnInterruptsContext) -} - -type waitSignalFn func(ctx context.Context, signals ...os.Signal) - -var interruptErr = errors.New("interrupt signal") - -func lifecycleCmd(fn LifecycleAction, blockOnInterrupt waitSignalFn) cli.ActionFunc { return func(ctx *cli.Context) error { hostCtx := ctx.Context + blockOnInterrupt := opio.BlockerFromContext(hostCtx) + if blockOnInterrupt == nil { // add default interrupt blocker to context if none is set. + hostCtx = opio.WithInterruptBlocker(hostCtx) + blockOnInterrupt = opio.BlockerFromContext(hostCtx) + } appCtx, appCancel := context.WithCancelCause(hostCtx) ctx.Context = appCtx diff --git a/op-service/cliapp/lifecycle_test.go b/op-service/cliapp/lifecycle_test.go index 8cb65ee00d40..4c421a35493e 100644 --- a/op-service/cliapp/lifecycle_test.go +++ b/op-service/cliapp/lifecycle_test.go @@ -3,12 +3,13 @@ package cliapp import ( "context" "errors" - "os" "testing" "time" "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/op-service/opio" ) type fakeLifecycle struct { @@ -47,12 +48,14 @@ var _ Lifecycle = (*fakeLifecycle)(nil) func TestLifecycleCmd(t *testing.T) { - appSetup := func(t *testing.T, shareApp **fakeLifecycle) (signalCh chan struct{}, initCh, startCh, stopCh, resultCh chan error) { + appSetup := func(t *testing.T) (signalCh chan struct{}, initCh, startCh, stopCh, resultCh chan error, appCh chan *fakeLifecycle) { signalCh = make(chan struct{}) initCh = make(chan error) startCh = make(chan error) stopCh = make(chan error) resultCh = make(chan error) + // optional channel to retrieve the fakeLifecycle from, available some time after init, before start. + appCh = make(chan *fakeLifecycle, 1) // mock an application that may fail at different stages of its lifecycle mockAppFn := func(ctx *cli.Context, close context.CancelCauseFunc) (Lifecycle, error) { @@ -71,25 +74,23 @@ func TestLifecycleCmd(t *testing.T) { stopped: false, selfClose: close, } - if shareApp != nil { - *shareApp = app - } + appCh <- app return app, nil } - // puppeteer a system signal waiter with a test signal channel - fakeSignalWaiter := func(ctx context.Context, signals ...os.Signal) { - select { - case <-ctx.Done(): - case <-signalCh: - } - } - // turn our mock app and system signal into a lifecycle-managed command - actionFn := lifecycleCmd(mockAppFn, fakeSignalWaiter) + actionFn := LifecycleCmd(mockAppFn) // try to shut the test down after being locked more than a minute ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + + // puppeteer system signal interrupts by hooking up the test signal channel as "blocker" for the app to use. + ctx = opio.WithBlocker(ctx, func(ctx context.Context) { + select { + case <-ctx.Done(): + case <-signalCh: + } + }) t.Cleanup(cancel) // create a fake CLI context to run our command with @@ -114,29 +115,30 @@ func TestLifecycleCmd(t *testing.T) { close(startCh) close(stopCh) close(resultCh) + close(appCh) }) return } t.Run("interrupt int", func(t *testing.T) { - signalCh, _, _, _, resultCh := appSetup(t, nil) + signalCh, _, _, _, resultCh, _ := appSetup(t) signalCh <- struct{}{} res := <-resultCh require.ErrorIs(t, res, interruptErr) require.ErrorContains(t, res, "failed to setup") }) t.Run("failed init", func(t *testing.T) { - _, initCh, _, _, resultCh := appSetup(t, nil) - v := errors.New("TEST INIT ERRROR") + _, initCh, _, _, resultCh, _ := appSetup(t) + v := errors.New("TEST INIT ERROR") initCh <- v res := <-resultCh require.ErrorIs(t, res, v) require.ErrorContains(t, res, "failed to setup") }) t.Run("interrupt start", func(t *testing.T) { - var app *fakeLifecycle - signalCh, initCh, _, _, resultCh := appSetup(t, &app) + signalCh, initCh, _, _, resultCh, appCh := appSetup(t) initCh <- nil + app := <-appCh require.False(t, app.Stopped()) signalCh <- struct{}{} res := <-resultCh @@ -145,9 +147,9 @@ func TestLifecycleCmd(t *testing.T) { require.True(t, app.Stopped()) }) t.Run("failed start", func(t *testing.T) { - var app *fakeLifecycle - _, initCh, startCh, _, resultCh := appSetup(t, &app) + _, initCh, startCh, _, resultCh, appCh := appSetup(t) initCh <- nil + app := <-appCh require.False(t, app.Stopped()) v := errors.New("TEST START ERROR") startCh <- v @@ -157,9 +159,9 @@ func TestLifecycleCmd(t *testing.T) { require.True(t, app.Stopped()) }) t.Run("graceful shutdown", func(t *testing.T) { - var app *fakeLifecycle - signalCh, initCh, startCh, stopCh, resultCh := appSetup(t, &app) + signalCh, initCh, startCh, stopCh, resultCh, appCh := appSetup(t) initCh <- nil + app := <-appCh require.False(t, app.Stopped()) startCh <- nil signalCh <- struct{}{} // interrupt, but at an expected time @@ -168,9 +170,9 @@ func TestLifecycleCmd(t *testing.T) { require.True(t, app.Stopped()) }) t.Run("interrupted shutdown", func(t *testing.T) { - var app *fakeLifecycle - signalCh, initCh, startCh, _, resultCh := appSetup(t, &app) + signalCh, initCh, startCh, _, resultCh, appCh := appSetup(t) initCh <- nil + app := <-appCh require.False(t, app.Stopped()) startCh <- nil signalCh <- struct{}{} // start graceful shutdown @@ -181,9 +183,9 @@ func TestLifecycleCmd(t *testing.T) { require.True(t, app.Stopped()) // still fully closes, interrupts only accelerate shutdown where possible. }) t.Run("failed shutdown", func(t *testing.T) { - var app *fakeLifecycle - signalCh, initCh, startCh, stopCh, resultCh := appSetup(t, &app) + signalCh, initCh, startCh, stopCh, resultCh, appCh := appSetup(t) initCh <- nil + app := <-appCh require.False(t, app.Stopped()) startCh <- nil signalCh <- struct{}{} // start graceful shutdown @@ -195,9 +197,9 @@ func TestLifecycleCmd(t *testing.T) { require.True(t, app.Stopped()) }) t.Run("app self-close", func(t *testing.T) { - var app *fakeLifecycle - _, initCh, startCh, stopCh, resultCh := appSetup(t, &app) + _, initCh, startCh, stopCh, resultCh, appCh := appSetup(t) initCh <- nil + app := <-appCh require.False(t, app.Stopped()) startCh <- nil v := errors.New("TEST SELF CLOSE ERROR") diff --git a/op-service/client/http.go b/op-service/client/http.go new file mode 100644 index 000000000000..7b5cc680eac8 --- /dev/null +++ b/op-service/client/http.go @@ -0,0 +1,93 @@ +package client + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "time" + + "github.com/ethereum/go-ethereum/log" +) + +const ( + DefaultTimeoutSeconds = 30 +) + +var _ HTTP = (*BasicHTTPClient)(nil) + +type HTTP interface { + Get(ctx context.Context, path string, query url.Values, headers http.Header) (*http.Response, error) +} + +type BasicHTTPClient struct { + endpoint string + header http.Header // optional header to use in every request + + log log.Logger + client *http.Client +} + +func NewBasicHTTPClient(endpoint string, log log.Logger, opts ...BasicHTTPClientOption) *BasicHTTPClient { + c := &BasicHTTPClient{ + endpoint: endpoint, + log: log, + client: &http.Client{Timeout: DefaultTimeoutSeconds * time.Second}, + } + + for _, opt := range opts { + opt.Apply(c) + } + + return c +} + +type BasicHTTPClientOption interface { + Apply(c *BasicHTTPClient) +} + +type BasicHTTPClientOptionFn func(*BasicHTTPClient) + +func (fn BasicHTTPClientOptionFn) Apply(c *BasicHTTPClient) { + fn(c) +} + +func WithHeader(h http.Header) BasicHTTPClientOption { + return BasicHTTPClientOptionFn(func(c *BasicHTTPClient) { + c.header = h + }) +} + +var ErrNoEndpoint = errors.New("no endpoint is configured") + +func (cl *BasicHTTPClient) Get(ctx context.Context, p string, query url.Values, headers http.Header) (*http.Response, error) { + if cl.endpoint == "" { + return nil, ErrNoEndpoint + } + target, err := url.Parse(cl.endpoint) + if err != nil { + return nil, fmt.Errorf("failed to parse endpoint URL: %w", err) + } + // If we include the raw query in the path-join, it gets url-encoded, + // and fails to parse as query, and ends up in the url.URL.Path part on the server side. + // We want to avoid that, and insert the query manually. Real footgun in the url package. + target = target.JoinPath(p) + target.RawQuery = query.Encode() + req, err := http.NewRequestWithContext(ctx, http.MethodGet, target.String(), nil) + if err != nil { + return nil, fmt.Errorf("%w: failed to construct request", err) + } + addHTTPHeaders(req.Header, cl.header, headers) + return cl.client.Do(req) +} + +func addHTTPHeaders(header http.Header, hs ...http.Header) { + for _, h := range hs { + for key, values := range h { + for _, value := range values { + header.Add(key, value) + } + } + } +} diff --git a/op-service/client/http_test.go b/op-service/client/http_test.go new file mode 100644 index 000000000000..60fd9fd9873f --- /dev/null +++ b/op-service/client/http_test.go @@ -0,0 +1,100 @@ +package client + +import ( + "context" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "golang.org/x/exp/slog" + + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/stretchr/testify/require" +) + +func TestBasicHTTPClient(t *testing.T) { + called := make(chan *http.Request, 1) + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + called <- r + })) + defer ts.Close() + + // generate deep clones + mkhdr := func() http.Header { + return http.Header{ + "Foo": []string{"bar", "baz"}, + "Superchain": []string{"op"}, + } + } + opt := WithHeader(mkhdr()) + c := NewBasicHTTPClient(ts.URL, testlog.Logger(t, slog.LevelInfo), opt) + + const ep = "/api/version" + query := url.Values{ + "key": []string{"123"}, + } + getheader := http.Header{ + "Fruits": []string{"apple"}, + "Superchain": []string{"base"}, + } + resp, err := c.Get(context.Background(), ep, query, getheader) + require.NoError(t, err) + defer resp.Body.Close() + + require.Equal(t, http.StatusOK, resp.StatusCode) + req := <-called + require.Equal(t, ep, req.URL.Path) + require.Equal(t, query, req.URL.Query()) + require.ElementsMatch(t, req.Header.Values("Foo"), mkhdr()["Foo"]) + require.ElementsMatch(t, req.Header.Values("Fruits"), getheader["Fruits"]) + require.ElementsMatch(t, req.Header.Values("Superchain"), []string{"op", "base"}) +} + +func TestAddHTTPHeaders(t *testing.T) { + for _, test := range []struct { + desc string + expheader http.Header + headers []http.Header + }{ + { + desc: "all-empty", + expheader: http.Header{}, + headers: nil, + }, + { + desc: "1-header-and-nils", + expheader: http.Header{"Foo": []string{"bar"}}, + headers: []http.Header{ + nil, + {"Foo": []string{"bar"}}, + nil, + }, + }, + { + desc: "2-headers", + expheader: http.Header{ + "Foo": []string{"bar", "baz"}, + "Super": []string{"chain"}, + "Fruit": []string{"apple"}, + }, + headers: []http.Header{ + { + "Foo": []string{"bar"}, + "Super": []string{"chain"}, + }, + { + "Foo": []string{"baz"}, + "Fruit": []string{"apple"}, + }, + }, + }, + } { + t.Run(test.desc, func(t *testing.T) { + h := make(http.Header) + addHTTPHeaders(h, test.headers...) + require.Equal(t, test.expheader, h) + }) + } +} diff --git a/op-service/client/polling_test.go b/op-service/client/polling_test.go index a0210d911a48..721cd326ca49 100644 --- a/op-service/client/polling_test.go +++ b/op-service/client/polling_test.go @@ -73,8 +73,7 @@ func (m *MockRPC) popResult() { } func TestPollingClientSubscribeUnsubscribe(t *testing.T) { - lgr := log.New() - lgr.SetHandler(log.DiscardHandler()) + lgr := log.NewLogger(log.DiscardHandler()) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -134,8 +133,7 @@ func TestPollingClientSubscribeUnsubscribe(t *testing.T) { } func TestPollingClientErrorRecovery(t *testing.T) { - lgr := log.New() - lgr.SetHandler(log.DiscardHandler()) + lgr := log.NewLogger(log.DiscardHandler()) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -165,8 +163,7 @@ func TestPollingClientErrorRecovery(t *testing.T) { } func TestPollingClientClose(t *testing.T) { - lgr := log.New() - lgr.SetHandler(log.DiscardHandler()) + lgr := log.NewLogger(log.DiscardHandler()) ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/op-service/clock/advancing.go b/op-service/clock/advancing.go index c57bf23a7901..a441c0b8982c 100644 --- a/op-service/clock/advancing.go +++ b/op-service/clock/advancing.go @@ -55,6 +55,7 @@ func (c *AdvancingClock) Stop() { // Already stopped return } + c.ticker.Stop() c.quit <- nil } diff --git a/op-service/clock/clock.go b/op-service/clock/clock.go index 834d2984c911..d38eaa256908 100644 --- a/op-service/clock/clock.go +++ b/op-service/clock/clock.go @@ -13,6 +13,9 @@ type Clock interface { // Now provides the current local time. Equivalent to time.Now Now() time.Time + // Since returns the time elapsed since t. It is shorthand for time.Now().Sub(t). + Since(time.Time) time.Duration + // After waits for the duration to elapse and then sends the current time on the returned channel. // It is equivalent to time.After After(d time.Duration) <-chan time.Time @@ -81,6 +84,10 @@ func (s systemClock) Now() time.Time { return time.Now() } +func (s systemClock) Since(t time.Time) time.Duration { + return time.Since(t) +} + func (s systemClock) After(d time.Duration) <-chan time.Time { return time.After(d) } diff --git a/op-service/clock/deterministic.go b/op-service/clock/deterministic.go index 8d28fb917340..ce11773232ce 100644 --- a/op-service/clock/deterministic.go +++ b/op-service/clock/deterministic.go @@ -138,6 +138,12 @@ func (s *DeterministicClock) Now() time.Time { return s.now } +func (s *DeterministicClock) Since(t time.Time) time.Duration { + s.lock.Lock() + defer s.lock.Unlock() + return s.now.Sub(t) +} + func (s *DeterministicClock) After(d time.Duration) <-chan time.Time { s.lock.Lock() defer s.lock.Unlock() diff --git a/op-service/clock/simple.go b/op-service/clock/simple.go new file mode 100644 index 000000000000..1f685d180372 --- /dev/null +++ b/op-service/clock/simple.go @@ -0,0 +1,22 @@ +package clock + +import ( + "sync/atomic" + "time" +) + +type SimpleClock struct { + unix atomic.Uint64 +} + +func NewSimpleClock() *SimpleClock { + return &SimpleClock{} +} + +func (c *SimpleClock) SetTime(u uint64) { + c.unix.Store(u) +} + +func (c *SimpleClock) Now() time.Time { + return time.Unix(int64(c.unix.Load()), 0) +} diff --git a/op-service/clock/simple_test.go b/op-service/clock/simple_test.go new file mode 100644 index 000000000000..3760f1033ceb --- /dev/null +++ b/op-service/clock/simple_test.go @@ -0,0 +1,52 @@ +package clock + +import ( + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestSimpleClock_Now(t *testing.T) { + c := NewSimpleClock() + require.Equal(t, time.Unix(0, 0), c.Now()) + expectedTime := uint64(time.Now().Unix()) + c.unix = atomic.Uint64{} + c.unix.Store(expectedTime) + require.Equal(t, time.Unix(int64(expectedTime), 0), c.Now()) +} + +func TestSimpleClock_SetTime(t *testing.T) { + tests := []struct { + name string + expectedTime int64 + }{ + { + name: "SetZeroTime", + expectedTime: 0, + }, + { + name: "SetZeroUnixTime", + expectedTime: time.Unix(0, 0).Unix(), + }, + + { + name: "SetCurrentTime", + expectedTime: time.Now().Unix(), + }, + { + name: "SetFutureTime", + expectedTime: time.Now().Add(time.Hour).Unix(), + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + c := NewSimpleClock() + c.SetTime(uint64(test.expectedTime)) + require.Equal(t, time.Unix(test.expectedTime, 0), c.Now()) + }) + } +} diff --git a/op-service/clock/util.go b/op-service/clock/util.go new file mode 100644 index 000000000000..dc564c652fff --- /dev/null +++ b/op-service/clock/util.go @@ -0,0 +1,25 @@ +package clock + +import ( + "time" +) + +type RWClock interface { + Now() time.Time +} + +// MinCheckedTimestamp returns the minimum checked unix timestamp. +// If the duration is 0, the returned minimum timestamp is 0. +// Otherwise, the minimum timestamp is the current unix time minus the duration. +// The subtraction operation is checked and returns 0 on underflow. +func MinCheckedTimestamp(clock RWClock, duration time.Duration) uint64 { + if duration.Seconds() == 0 { + return 0 + } + // To compute t-d for a duration d, use t.Add(-d). + // See https://pkg.go.dev/time#Time.Sub + if clock.Now().Unix() > int64(duration.Seconds()) { + return uint64(clock.Now().Add(-duration).Unix()) + } + return 0 +} diff --git a/op-service/clock/util_test.go b/op-service/clock/util_test.go new file mode 100644 index 000000000000..b2c5e3f50259 --- /dev/null +++ b/op-service/clock/util_test.go @@ -0,0 +1,64 @@ +package clock + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestMinCheckedTimestamp(t *testing.T) { + tests := []struct { + name string + now time.Time + duration time.Duration + want uint64 + }{ + { + name: "ZeroDurationZeroClock", + now: time.Unix(0, 0), + duration: 0, + want: 0, + }, + { + name: "ZeroDurationPositiveClock", + now: time.Unix(1, 0), + duration: 0, + want: 0, + }, + { + name: "UnderflowZeroClock", + now: time.Unix(0, 0), + duration: time.Second, + want: 0, + }, + { + name: "UnderflowPositiveClock", + now: time.Unix(1, 0), + duration: time.Second * 2, + want: 0, + }, + { + name: "CorrectArithmetic", + now: time.Unix(100, 0), + duration: time.Second * 10, + want: 90, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + clock := &mockClock{now: test.now} + require.Equal(t, test.want, MinCheckedTimestamp(clock, test.duration)) + }) + } +} + +type mockClock struct { + now time.Time +} + +func (m *mockClock) Now() time.Time { + return m.now +} diff --git a/op-service/dial/active_l2_provider.go b/op-service/dial/active_l2_provider.go new file mode 100644 index 000000000000..5eb3fadbc050 --- /dev/null +++ b/op-service/dial/active_l2_provider.go @@ -0,0 +1,114 @@ +package dial + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/ethereum/go-ethereum/log" +) + +const DefaultActiveSequencerFollowerCheckDuration = 2 * DefaultDialTimeout + +type ethDialer func(ctx context.Context, timeout time.Duration, log log.Logger, url string) (EthClientInterface, error) + +// ActiveL2EndpointProvider is an interface for providing a RollupClient and l2 eth client +// It manages the lifecycle of the RollupClient and eth client for callers +// It does this by failing over down the list of rollupUrls if the current one is inactive or broken +type ActiveL2EndpointProvider struct { + ActiveL2RollupProvider + currentEthClient EthClientInterface + ethClientIndex int + ethDialer ethDialer + ethUrls []string +} + +// NewActiveL2EndpointProvider creates a new ActiveL2EndpointProvider +// the checkDuration is the duration between checks to see if the current rollup client is active +// provide a checkDuration of 0 to check every time +func NewActiveL2EndpointProvider(ctx context.Context, + ethUrls, rollupUrls []string, + checkDuration time.Duration, + networkTimeout time.Duration, + logger log.Logger, +) (*ActiveL2EndpointProvider, error) { + ethDialer := func(ctx context.Context, timeout time.Duration, + log log.Logger, url string, + ) (EthClientInterface, error) { + return DialEthClientWithTimeout(ctx, timeout, log, url) + } + rollupDialer := func(ctx context.Context, timeout time.Duration, + log log.Logger, url string, + ) (RollupClientInterface, error) { + return DialRollupClientWithTimeout(ctx, timeout, log, url) + } + return newActiveL2EndpointProvider(ctx, ethUrls, rollupUrls, checkDuration, networkTimeout, logger, ethDialer, rollupDialer) +} + +func newActiveL2EndpointProvider( + ctx context.Context, + ethUrls, rollupUrls []string, + checkDuration time.Duration, + networkTimeout time.Duration, + logger log.Logger, + ethDialer ethDialer, + rollupDialer rollupDialer, +) (*ActiveL2EndpointProvider, error) { + if len(rollupUrls) == 0 { + return nil, errors.New("empty rollup urls list, expected at least one URL") + } + if len(ethUrls) != len(rollupUrls) { + return nil, fmt.Errorf("number of eth urls (%d) and rollup urls (%d) mismatch", len(ethUrls), len(rollupUrls)) + } + + rollupProvider, err := newActiveL2RollupProvider(ctx, rollupUrls, checkDuration, networkTimeout, logger, rollupDialer) + if err != nil { + return nil, err + } + p := &ActiveL2EndpointProvider{ + ActiveL2RollupProvider: *rollupProvider, + ethDialer: ethDialer, + ethUrls: ethUrls, + } + cctx, cancel := context.WithTimeout(ctx, networkTimeout) + defer cancel() + if _, err = p.EthClient(cctx); err != nil { + return nil, fmt.Errorf("setting provider eth client: %w", err) + } + return p, nil +} + +func (p *ActiveL2EndpointProvider) EthClient(ctx context.Context) (EthClientInterface, error) { + p.clientLock.Lock() + defer p.clientLock.Unlock() + err := p.ensureActiveEndpoint(ctx) + if err != nil { + return nil, err + } + if p.ethClientIndex != p.rollupIndex || p.currentEthClient == nil { + // we changed sequencers, dial a new EthClient + cctx, cancel := context.WithTimeout(ctx, p.networkTimeout) + defer cancel() + idx := p.rollupIndex + ep := p.ethUrls[idx] + log.Info("sequencer changed (or ethClient was nil due to startup), dialing new eth client", "new_index", idx, "new_url", ep) + ethClient, err := p.ethDialer(cctx, p.networkTimeout, p.log, ep) + if err != nil { + return nil, fmt.Errorf("dialing eth client: %w", err) + } + if p.currentEthClient != nil { + p.currentEthClient.Close() + } + p.ethClientIndex = idx + p.currentEthClient = ethClient + } + return p.currentEthClient, nil +} + +func (p *ActiveL2EndpointProvider) Close() { + if p.currentEthClient != nil { + p.currentEthClient.Close() + } + p.ActiveL2RollupProvider.Close() +} diff --git a/op-service/dial/active_l2_provider_test.go b/op-service/dial/active_l2_provider_test.go new file mode 100644 index 000000000000..e9b532cc10bd --- /dev/null +++ b/op-service/dial/active_l2_provider_test.go @@ -0,0 +1,794 @@ +package dial + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +// endpointProviderTest is a test harness for setting up endpoint provider tests. +type endpointProviderTest struct { + t *testing.T + rollupClients []*testutils.MockRollupClient + ethClients []*testutils.MockEthClient + rollupDialOutcomes map[int]bool // true for success, false for failure + ethDialOutcomes map[int]bool // true for success, false for failure +} + +// setupEndpointProviderTest sets up the basic structure of the endpoint provider tests. +func setupEndpointProviderTest(t *testing.T, numSequencers int) *endpointProviderTest { + ept := &endpointProviderTest{ + t: t, + rollupClients: make([]*testutils.MockRollupClient, numSequencers), + ethClients: make([]*testutils.MockEthClient, numSequencers), + rollupDialOutcomes: make(map[int]bool), + ethDialOutcomes: make(map[int]bool), + } + + for i := 0; i < numSequencers; i++ { + ept.rollupClients[i] = new(testutils.MockRollupClient) + ept.ethClients[i] = new(testutils.MockEthClient) + ept.rollupDialOutcomes[i] = true // by default, all dials succeed + ept.ethDialOutcomes[i] = true // by default, all dials succeed + } + + return ept +} + +// newActiveL2EndpointProvider constructs a new ActiveL2RollupProvider using the test harness setup. +func (et *endpointProviderTest) newActiveL2RollupProvider(checkDuration time.Duration) (*ActiveL2RollupProvider, error) { + mockRollupDialer := func(ctx context.Context, timeout time.Duration, log log.Logger, url string) (RollupClientInterface, error) { + for i, client := range et.rollupClients { + if url == fmt.Sprintf("rollup%d", i) { + if !et.rollupDialOutcomes[i] { + return nil, fmt.Errorf("simulated dial failure for rollup %d", i) + } + return client, nil + } + } + return nil, fmt.Errorf("unknown test url: %s", url) + } + + // make the "URLs" + rollupUrls := make([]string, len(et.rollupClients)) + for i := range et.rollupClients { + rollupUrl := fmt.Sprintf("rollup%d", i) + rollupUrls[i] = rollupUrl + } + + return newActiveL2RollupProvider( + context.Background(), + rollupUrls, + checkDuration, + 1*time.Minute, + testlog.Logger(et.t, log.LevelDebug), + mockRollupDialer, + ) +} + +// newActiveL2EndpointProvider constructs a new ActiveL2EndpointProvider using the test harness setup. +func (et *endpointProviderTest) newActiveL2EndpointProvider(checkDuration time.Duration) (*ActiveL2EndpointProvider, error) { + mockRollupDialer := func(ctx context.Context, timeout time.Duration, log log.Logger, url string) (RollupClientInterface, error) { + for i, client := range et.rollupClients { + if url == fmt.Sprintf("rollup%d", i) { + if !et.rollupDialOutcomes[i] { + return nil, fmt.Errorf("simulated dial failure for rollup %d", i) + } + return client, nil + } + } + return nil, fmt.Errorf("unknown test url: %s", url) + } + + mockEthDialer := func(ctx context.Context, timeout time.Duration, log log.Logger, url string) (EthClientInterface, error) { + for i, client := range et.ethClients { + if url == fmt.Sprintf("eth%d", i) { + if !et.ethDialOutcomes[i] { + return nil, fmt.Errorf("simulated dial failure for eth %d", i) + } + return client, nil + } + } + return nil, fmt.Errorf("unknown test url: %s", url) + } + + // make the "URLs" + rollupUrls := make([]string, len(et.rollupClients)) + for i := range et.rollupClients { + rollupUrl := fmt.Sprintf("rollup%d", i) + rollupUrls[i] = rollupUrl + } + ethUrls := make([]string, len(et.ethClients)) + for i := range et.ethClients { + ethUrl := fmt.Sprintf("eth%d", i) + ethUrls[i] = ethUrl + } + + return newActiveL2EndpointProvider( + context.Background(), + ethUrls, + rollupUrls, + checkDuration, + 1*time.Minute, + testlog.Logger(et.t, log.LevelDebug), + mockEthDialer, + mockRollupDialer, + ) +} + +func (et *endpointProviderTest) assertAllExpectations(t *testing.T) { + for _, sequencer := range et.rollupClients { + sequencer.AssertExpectations(t) + } + for _, ethClient := range et.ethClients { + ethClient.AssertExpectations(t) + } +} + +func (et *endpointProviderTest) setRollupDialOutcome(index int, success bool) { + et.rollupDialOutcomes[index] = success +} + +// TestRollupProvider_FailoverOnInactiveSequencer verifies that the ActiveL2RollupProvider +// will switch to the next provider if the current one becomes inactive. +func TestRollupProvider_FailoverOnInactiveSequencer(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer, secondarySequencer := ept.rollupClients[0], ept.rollupClients[1] + + primarySequencer.ExpectSequencerActive(true, nil) // respond true once on creation + primarySequencer.ExpectSequencerActive(true, nil) // respond true again when the test calls `RollupClient()` the first time + + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + + firstSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, primarySequencer, firstSequencerUsed) + + primarySequencer.ExpectSequencerActive(false, nil) // become inactive after that + primarySequencer.MaybeClose() + secondarySequencer.ExpectSequencerActive(true, nil) + secondSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, secondarySequencer, secondSequencerUsed) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_FailoverOnInactiveSequencer verifies that the ActiveL2EndpointProvider +// will switch to the next provider if the current one becomes inactive. +func TestEndpointProvider_FailoverOnInactiveSequencer(t *testing.T) { + // as TestActiveSequencerFailoverBehavior_RollupProviders, + // but ensure the added `EthClient()` method also triggers the failover. + ept := setupEndpointProviderTest(t, 2) + primarySequencer, secondarySequencer := ept.rollupClients[0], ept.rollupClients[1] + primarySequencer.ExpectSequencerActive(true, nil) // primary sequencer gets hit once on creation: embedded call of `RollupClient()` + primarySequencer.ExpectSequencerActive(true, nil) // primary sequencer gets hit twice on creation: implicit call of `EthClient()` + primarySequencer.ExpectSequencerActive(true, nil) // respond true again when the test calls `EthClient()` the first time + + activeProvider, err := ept.newActiveL2EndpointProvider(0) + require.NoError(t, err) + + firstSequencerUsed, err := activeProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, ept.ethClients[0], firstSequencerUsed) + + primarySequencer.ExpectSequencerActive(false, nil) // become inactive after that + secondarySequencer.ExpectSequencerActive(true, nil) + primarySequencer.MaybeClose() + ept.ethClients[0].MaybeClose() // we close the ethclient when we switch over to the next sequencer + secondSequencerUsed, err := activeProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, ept.ethClients[1], secondSequencerUsed) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_FailoverOnErroredSequencer verifies that the ActiveL2RollupProvider +// will switch to the next provider if the current one returns an error. +func TestRollupProvider_FailoverOnErroredSequencer(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer, secondarySequencer := ept.rollupClients[0], ept.rollupClients[1] + + primarySequencer.ExpectSequencerActive(true, nil) // respond true once on creation + primarySequencer.ExpectSequencerActive(true, nil) // respond true again when the test calls `RollupClient()` the first time + + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + + firstSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, primarySequencer, firstSequencerUsed) + + primarySequencer.ExpectSequencerActive(true, fmt.Errorf("a test error")) // error-out after that + primarySequencer.MaybeClose() + secondarySequencer.ExpectSequencerActive(true, nil) + secondSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, secondarySequencer, secondSequencerUsed) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_FailoverOnErroredSequencer verifies that the ActiveL2EndpointProvider +// will switch to the next provider if the current one returns an error. +func TestEndpointProvider_FailoverOnErroredSequencer(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer, secondarySequencer := ept.rollupClients[0], ept.rollupClients[1] + primaryEthClient, secondaryEthClient := ept.ethClients[0], ept.ethClients[1] + + primarySequencer.ExpectSequencerActive(true, nil) // primary sequencer gets hit once on creation: embedded call of `RollupClient()` + primarySequencer.ExpectSequencerActive(true, nil) // primary sequencer gets hit twice on creation: implicit call of `EthClient()` + + activeProvider, err := ept.newActiveL2EndpointProvider(0) + require.NoError(t, err) + + primarySequencer.ExpectSequencerActive(true, nil) // respond true again when the test calls `EthClient()` the first time + firstSequencerUsed, err := activeProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, primaryEthClient, firstSequencerUsed) + + primarySequencer.ExpectSequencerActive(true, fmt.Errorf("a test error")) // error out after that + primarySequencer.MaybeClose() + primaryEthClient.MaybeClose() + secondarySequencer.ExpectSequencerActive(true, nil) + + secondSequencerUsed, err := activeProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, secondaryEthClient, secondSequencerUsed) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_NoExtraCheckOnActiveSequencer verifies that the ActiveL2RollupProvider +// does not change if the current sequencer is active. +func TestRollupProvider_NoExtraCheckOnActiveSequencer(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer := ept.rollupClients[0] + + primarySequencer.ExpectSequencerActive(true, nil) // default test provider, which always checks, checks Active on creation + + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + require.Same(t, primarySequencer, rollupProvider.currentRollupClient) + + primarySequencer.ExpectSequencerActive(true, nil) // default test provider, which always checks, checks again on RollupClient() + + firstSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, primarySequencer, firstSequencerUsed) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_NoExtraCheckOnActiveSequencer verifies that the ActiveL2EndpointProvider +// does not change if the current sequencer is active. +func TestEndpointProvider_NoExtraCheckOnActiveSequencer(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer := ept.rollupClients[0] + + primarySequencer.ExpectSequencerActive(true, nil) // default test provider, which always checks, checks Active twice on creation (once for internal RollupClient() call) + primarySequencer.ExpectSequencerActive(true, nil) // default test provider, which always checks, checks Active twice on creation (once for internal EthClient() call) + + endpointProvider, err := ept.newActiveL2EndpointProvider(0) + require.NoError(t, err) + require.Same(t, ept.ethClients[0], endpointProvider.currentEthClient) + + primarySequencer.ExpectSequencerActive(true, nil) // default test provider, which always checks, checks again on EthClient() + + firstEthClientUsed, err := endpointProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, ept.ethClients[0], firstEthClientUsed) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_FailoverAndReturn verifies the ActiveL2RollupProvider's ability to +// failover and then return to the primary sequencer once it becomes active again. +func TestRollupProvider_FailoverAndReturn(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer, secondarySequencer := ept.rollupClients[0], ept.rollupClients[1] + + // Primary initially active + primarySequencer.ExpectSequencerActive(true, nil) + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + + // Primary becomes inactive, secondary active + primarySequencer.ExpectSequencerActive(false, nil) + primarySequencer.MaybeClose() + secondarySequencer.ExpectSequencerActive(true, nil) + + // Fails over to secondary + secondSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, secondarySequencer, secondSequencerUsed) + + // Primary becomes active again, secondary becomes inactive + primarySequencer.ExpectSequencerActive(true, nil) + secondarySequencer.ExpectSequencerActive(false, nil) + secondarySequencer.MaybeClose() + + // Should return to primary + thirdSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, primarySequencer, thirdSequencerUsed) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_FailoverAndReturn verifies the ActiveL2EndpointProvider's ability to +// failover and then return to the primary sequencer once it becomes active again. +func TestEndpointProvider_FailoverAndReturn(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer, secondarySequencer := ept.rollupClients[0], ept.rollupClients[1] + + // Primary initially active + primarySequencer.ExpectSequencerActive(true, nil) + primarySequencer.ExpectSequencerActive(true, nil) // see comment in other tests about why we expect this twice + endpointProvider, err := ept.newActiveL2EndpointProvider(0) + require.NoError(t, err) + + // Primary becomes inactive, secondary active + primarySequencer.ExpectSequencerActive(false, nil) + primarySequencer.MaybeClose() + ept.ethClients[0].MaybeClose() + secondarySequencer.ExpectSequencerActive(true, nil) + + // Fails over to secondary + secondEthClient, err := endpointProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, ept.ethClients[1], secondEthClient) + + // Primary becomes active again, secondary becomes inactive + primarySequencer.ExpectSequencerActive(true, nil) + secondarySequencer.ExpectSequencerActive(false, nil) + secondarySequencer.MaybeClose() + ept.ethClients[1].MaybeClose() + + // // Should return to primary + thirdSequencerUsed, err := endpointProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, ept.ethClients[0], thirdSequencerUsed) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_InitialActiveSequencerSelection verifies that the ActiveL2RollupProvider +// selects the active sequencer correctly at the time of creation. +func TestRollupProvider_InitialActiveSequencerSelection(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer := ept.rollupClients[0] + + // Primary active at creation + primarySequencer.ExpectSequencerActive(true, nil) + + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + + // Check immediately after creation without additional Active check + require.Same(t, primarySequencer, rollupProvider.currentRollupClient) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_InitialActiveSequencerSelection verifies that the ActiveL2EndpointProvider +// selects the active sequencer correctly at the time of creation. +func TestEndpointProvider_InitialActiveSequencerSelection(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer := ept.rollupClients[0] + + // Primary active at creation + primarySequencer.ExpectSequencerActive(true, nil) + primarySequencer.ExpectSequencerActive(true, nil) // see comment in other tests about why we expect this twice + + rollupProvider, err := ept.newActiveL2EndpointProvider(0) + require.NoError(t, err) + + // Check immediately after creation without additional Active check + require.Same(t, primarySequencer, rollupProvider.currentRollupClient) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_SelectSecondSequencerIfFirstInactiveAtCreation verifies that if the first sequencer +// is inactive at the time of ActiveL2RollupProvider creation, the second active sequencer is chosen. +func TestRollupProvider_SelectSecondSequencerIfFirstInactiveAtCreation(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + + // First sequencer is inactive, second sequencer is active + ept.rollupClients[0].ExpectSequencerActive(false, nil) + ept.rollupClients[0].MaybeClose() + ept.rollupClients[1].ExpectSequencerActive(true, nil) + + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + + require.Same(t, ept.rollupClients[1], rollupProvider.currentRollupClient) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_SelectLastSequencerIfManyOfflineAtCreation verifies that if all but the last sequencer +// are offline at the time of ActiveL2RollupProvider creation, the last active sequencer is chosen. +func TestRollupProvider_SelectLastSequencerIfManyOfflineAtCreation(t *testing.T) { + ept := setupEndpointProviderTest(t, 5) + + // First four sequencers are dead, last sequencer is active + for i := 0; i < 4; i++ { + ept.setRollupDialOutcome(i, false) + } + ept.rollupClients[4].ExpectSequencerActive(true, nil) + + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + + require.Same(t, ept.rollupClients[4], rollupProvider.currentRollupClient) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_SelectSecondSequencerIfFirstOfflineAtCreation verifies that if the first sequencer +// is inactive at the time of ActiveL2EndpointProvider creation, the second active sequencer is chosen. +func TestEndpointProvider_SelectSecondSequencerIfFirstOfflineAtCreation(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + + // First sequencer is inactive, second sequencer is active + ept.rollupClients[0].ExpectSequencerActive(false, nil) + ept.rollupClients[0].MaybeClose() + ept.rollupClients[1].ExpectSequencerActive(true, nil) + ept.rollupClients[1].ExpectSequencerActive(true, nil) // see comment in other tests about why we expect this twice + + endpointProvider, err := ept.newActiveL2EndpointProvider(0) + require.NoError(t, err) + + require.Same(t, ept.ethClients[1], endpointProvider.currentEthClient) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_SelectLastSequencerIfManyInactiveAtCreation verifies that if all but the last sequencer +// are inactive at the time of ActiveL2EndpointProvider creation, the last active sequencer is chosen. +func TestEndpointProvider_SelectLastSequencerIfManyInactiveAtCreation(t *testing.T) { + ept := setupEndpointProviderTest(t, 5) + + // First four sequencers are dead, last sequencer is active + for i := 0; i < 4; i++ { + ept.setRollupDialOutcome(i, false) + } + ept.rollupClients[4].ExpectSequencerActive(true, nil) + ept.rollupClients[4].ExpectSequencerActive(true, nil) // Double check due to embedded call of `EthClient()` + + endpointProvider, err := ept.newActiveL2EndpointProvider(0) + require.NoError(t, err) + + require.Same(t, ept.ethClients[4], endpointProvider.currentEthClient) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_ConstructorErrorOnFirstSequencerOffline verifies that the ActiveL2RollupProvider +// constructor handles the case where the first sequencer (index 0) is offline at startup. +func TestRollupProvider_ConstructorErrorOnFirstSequencerOffline(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + + // First sequencer is dead, second sequencer is active + ept.rollupClients[0].ExpectSequencerActive(false, fmt.Errorf("I am offline")) + ept.rollupClients[0].MaybeClose() + ept.rollupClients[1].ExpectSequencerActive(true, nil) + + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + + require.Same(t, ept.rollupClients[1], rollupProvider.currentRollupClient) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_ConstructorErrorOnFirstSequencerOffline verifies that the ActiveL2EndpointProvider +// constructor handles the case where the first sequencer (index 0) is offline at startup. +func TestEndpointProvider_ConstructorErrorOnFirstSequencerOffline(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + + // First sequencer is dead, second sequencer is active + ept.rollupClients[0].ExpectSequencerActive(false, fmt.Errorf("I am offline")) + ept.rollupClients[0].MaybeClose() + ept.rollupClients[1].ExpectSequencerActive(true, nil) + ept.rollupClients[1].ExpectSequencerActive(true, nil) // see comment in other tests about why we expect this twice + + endpointProvider, err := ept.newActiveL2EndpointProvider(0) + require.NoError(t, err) + + require.Same(t, ept.ethClients[1], endpointProvider.currentEthClient) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_FailOnAllInactiveSequencers verifies that the ActiveL2RollupProvider +// fails to be created when all sequencers are inactive. +func TestRollupProvider_FailOnAllInactiveSequencers(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + + // All sequencers are inactive + for _, sequencer := range ept.rollupClients { + sequencer.ExpectSequencerActive(false, nil) + sequencer.MaybeClose() + } + + _, err := ept.newActiveL2RollupProvider(0) + require.Error(t, err) // Expect an error as all sequencers are inactive + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_FailOnAllInactiveSequencers verifies that the ActiveL2EndpointProvider +// fails to be created when all sequencers are inactive. +func TestEndpointProvider_FailOnAllInactiveSequencers(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + + // All sequencers are inactive + for _, sequencer := range ept.rollupClients { + sequencer.ExpectSequencerActive(false, nil) + sequencer.MaybeClose() + } + + _, err := ept.newActiveL2EndpointProvider(0) + require.Error(t, err) // Expect an error as all sequencers are inactive + ept.assertAllExpectations(t) +} + +// TestRollupProvider_FailOnAllErroredSequencers verifies that the ActiveL2RollupProvider +// fails to create when all sequencers return an error. +func TestRollupProvider_FailOnAllErroredSequencers(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + + // All sequencers are inactive + for _, sequencer := range ept.rollupClients { + sequencer.ExpectSequencerActive(true, fmt.Errorf("a test error")) + sequencer.MaybeClose() + } + + _, err := ept.newActiveL2RollupProvider(0) + require.Error(t, err) // Expect an error as all sequencers are inactive + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_FailOnAllErroredSequencers verifies that the ActiveL2EndpointProvider +// fails to create when all sequencers return an error. +func TestEndpointProvider_FailOnAllErroredSequencers(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + + // All sequencers are inactive + for _, sequencer := range ept.rollupClients { + sequencer.ExpectSequencerActive(true, fmt.Errorf("a test error")) + sequencer.MaybeClose() + } + + _, err := ept.newActiveL2EndpointProvider(0) + require.Error(t, err) // Expect an error as all sequencers are inactive + ept.assertAllExpectations(t) +} + +// TestRollupProvider_LongCheckDuration verifies the behavior of ActiveL2RollupProvider with a long check duration. +func TestRollupProvider_LongCheckDuration(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer := ept.rollupClients[0] + + longCheckDuration := 1 * time.Hour + primarySequencer.ExpectSequencerActive(true, nil) // Active check on creation + + rollupProvider, err := ept.newActiveL2RollupProvider(longCheckDuration) + require.NoError(t, err) + + // Should return the same client without extra checks + firstSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, primarySequencer, firstSequencerUsed) + + secondSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, primarySequencer, secondSequencerUsed) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_LongCheckDuration verifies the behavior of ActiveL2EndpointProvider with a long check duration. +func TestEndpointProvider_LongCheckDuration(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer := ept.rollupClients[0] + + longCheckDuration := 1 * time.Hour + primarySequencer.ExpectSequencerActive(true, nil) // Active check on creation + + endpointProvider, err := ept.newActiveL2EndpointProvider(longCheckDuration) + require.NoError(t, err) + + // Should return the same client without extra checks + firstEthClient, err := endpointProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, ept.ethClients[0], firstEthClient) + + secondEthClient, err := endpointProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, ept.ethClients[0], secondEthClient) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_ErrorWhenAllSequencersInactive verifies that RollupClient() returns an error +// if all sequencers become inactive after the provider is successfully created. +func TestRollupProvider_ErrorWhenAllSequencersInactive(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + ept.rollupClients[0].ExpectSequencerActive(true, nil) // Main sequencer initially active + + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + + // All sequencers become inactive + for _, sequencer := range ept.rollupClients { + sequencer.ExpectSequencerActive(false, nil) + sequencer.MaybeClose() + } + + _, err = rollupProvider.RollupClient(context.Background()) + require.Error(t, err) // Expect an error as all sequencers are inactive + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_ErrorWhenAllSequencersInactive verifies that EthClient() returns an error +// if all sequencers become inactive after the provider is successfully created. +func TestEndpointProvider_ErrorWhenAllSequencersInactive(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + ept.rollupClients[0].ExpectSequencerActive(true, nil) // Main sequencer initially active + ept.rollupClients[0].ExpectSequencerActive(true, nil) // Main sequencer initially active (double check due to embedded call of `EthClient()`) + + endpointProvider, err := ept.newActiveL2EndpointProvider(0) + require.NoError(t, err) + + // All sequencers become inactive + for _, sequencer := range ept.rollupClients { + sequencer.ExpectSequencerActive(false, nil) + sequencer.MaybeClose() + } + + _, err = endpointProvider.EthClient(context.Background()) + require.Error(t, err) // Expect an error as all sequencers are inactive + ept.assertAllExpectations(t) +} + +// TestRollupProvider_ReturnsSameSequencerOnInactiveWithLongCheckDuration verifies that the ActiveL2RollupProvider +// still returns the same sequencer across calls even if it becomes inactive, due to a long check duration. +func TestRollupProvider_ReturnsSameSequencerOnInactiveWithLongCheckDuration(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer := ept.rollupClients[0] + + longCheckDuration := 1 * time.Hour + primarySequencer.ExpectSequencerActive(true, nil) // Active on creation + + rollupProvider, err := ept.newActiveL2RollupProvider(longCheckDuration) + require.NoError(t, err) + + // Primary sequencer becomes inactive, but the provider won't check immediately due to longCheckDuration + primarySequencer.ExpectSequencerActive(false, nil) + firstSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, primarySequencer, firstSequencerUsed) + + active, err := primarySequencer.SequencerActive(context.Background()) + require.NoError(t, err) + require.False(t, active) + + secondSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, primarySequencer, secondSequencerUsed) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_ReturnsSameSequencerOnInactiveWithLongCheckDuration verifies that the ActiveL2EndpointProvider +// still returns the same sequencer across calls even if it becomes inactive, due to a long check duration. +func TestEndpointProvider_ReturnsSameSequencerOnInactiveWithLongCheckDuration(t *testing.T) { + ept := setupEndpointProviderTest(t, 2) + primarySequencer := ept.rollupClients[0] + + longCheckDuration := 1 * time.Hour + primarySequencer.ExpectSequencerActive(true, nil) // Active on creation + + endpointProvider, err := ept.newActiveL2EndpointProvider(longCheckDuration) + require.NoError(t, err) + + // Primary sequencer becomes inactive, but the provider won't check immediately due to longCheckDuration + primarySequencer.ExpectSequencerActive(false, nil) + firstEthClientUsed, err := endpointProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, ept.ethClients[0], firstEthClientUsed) + + active, err := primarySequencer.SequencerActive(context.Background()) + require.NoError(t, err) + require.False(t, active) + + secondEthClientUsed, err := endpointProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, ept.ethClients[0], secondEthClientUsed) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_HandlesManyIndexClientMismatch verifies that the ActiveL2RollupProvider avoids +// the case where the index of the current sequencer does not match the index of the current rollup client. +func TestRollupProvider_HandlesManyIndexClientMismatch(t *testing.T) { + ept := setupEndpointProviderTest(t, 3) + seq0, seq1, seq2 := ept.rollupClients[0], ept.rollupClients[1], ept.rollupClients[2] + + // "start happy": primarySequencer is active on creation + seq0.ExpectSequencerActive(true, nil) // active on creation + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + + // primarySequencer goes down + seq0.ExpectSequencerActive(false, fmt.Errorf("I'm offline now")) + seq0.MaybeClose() + ept.setRollupDialOutcome(0, false) // primarySequencer fails to dial + // secondarySequencer is inactive, but online + seq1.ExpectSequencerActive(false, nil) + seq1.MaybeClose() + // tertiarySequencer can't even be dialed + ept.setRollupDialOutcome(2, false) + // In a prior buggy implementation, this scenario lead to an internal inconsistent state + // where the current client didn't match the index. On a subsequent try, this led to the + // active sequencer at 0 to be skipped entirely, while the sequencer at index 1 + // was checked twice. + rollupClient, err := rollupProvider.RollupClient(context.Background()) + require.Error(t, err) + require.Nil(t, rollupClient) + // internal state would now be inconsistent in a buggy impl. + + // now seq0 is dialable and active + ept.setRollupDialOutcome(0, true) + seq0.ExpectSequencerActive(true, nil) + seq0.MaybeClose() + // now seq1 and seq2 are dialable, but inactive + ept.setRollupDialOutcome(1, true) + seq1.ExpectSequencerActive(false, nil) + seq1.MaybeClose() + ept.setRollupDialOutcome(2, true) + seq2.ExpectSequencerActive(false, nil) + seq2.MaybeClose() + // this would trigger the prior bug: request the rollup client. + rollupClient, err = rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, seq0, rollupClient) + ept.assertAllExpectations(t) +} + +// TestRollupProvider_HandlesSingleSequencer verifies that the ActiveL2RollupProvider +// can handle being passed a single sequencer endpoint without issue. +func TestRollupProvider_HandlesSingleSequencer(t *testing.T) { + ept := setupEndpointProviderTest(t, 1) + onlySequencer := ept.rollupClients[0] + onlySequencer.ExpectSequencerActive(true, nil) // respond true once on creation + + rollupProvider, err := ept.newActiveL2RollupProvider(0) + require.NoError(t, err) + + onlySequencer.ExpectSequencerActive(true, nil) // respond true again when the test calls `RollupClient()` the first time + firstSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.NoError(t, err) + require.Same(t, onlySequencer, firstSequencerUsed) + + onlySequencer.ExpectSequencerActive(false, nil) // become inactive after that + onlySequencer.MaybeClose() + secondSequencerUsed, err := rollupProvider.RollupClient(context.Background()) + require.Error(t, err) + require.Nil(t, secondSequencerUsed) + ept.assertAllExpectations(t) +} + +// TestEndpointProvider_HandlesSingleSequencer verifies that the ActiveL2EndpointProvider +// can handle being passed a single sequencer endpoint without issue. +func TestEndpointProvider_HandlesSingleSequencer(t *testing.T) { + ept := setupEndpointProviderTest(t, 1) + onlySequencer := ept.rollupClients[0] + onlySequencer.ExpectSequencerActive(true, nil) // respond true once on creation + onlySequencer.ExpectSequencerActive(true, nil) // respond true again when the constructor calls `RollupClient()` + + endpointProvider, err := ept.newActiveL2EndpointProvider(0) + require.NoError(t, err) + + onlySequencer.ExpectSequencerActive(true, nil) // respond true a once more on fall-through check in `EthClient()` + firstEthClientUsed, err := endpointProvider.EthClient(context.Background()) + require.NoError(t, err) + require.Same(t, ept.ethClients[0], firstEthClientUsed) + + onlySequencer.ExpectSequencerActive(false, nil) // become inactive after that + onlySequencer.MaybeClose() + secondEthClientUsed, err := endpointProvider.EthClient(context.Background()) + require.Error(t, err) + require.Nil(t, secondEthClientUsed) + ept.assertAllExpectations(t) +} diff --git a/op-service/dial/active_rollup_provider.go b/op-service/dial/active_rollup_provider.go new file mode 100644 index 000000000000..76f30b3da99a --- /dev/null +++ b/op-service/dial/active_rollup_provider.go @@ -0,0 +1,169 @@ +package dial + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/log" +) + +type rollupDialer func(ctx context.Context, timeout time.Duration, log log.Logger, url string) (RollupClientInterface, error) + +// ActiveL2EndpointProvider is an interface for providing a RollupClient +// It manages the lifecycle of the RollupClient for callers +// It does this by failing over down the list of rollupUrls if the current one is inactive or broken +type ActiveL2RollupProvider struct { + checkDuration time.Duration + networkTimeout time.Duration + log log.Logger + + activeTimeout time.Time + + rollupUrls []string + rollupDialer rollupDialer + currentRollupClient RollupClientInterface + rollupIndex int + clientLock *sync.Mutex +} + +// NewActiveL2RollupProvider creates a new ActiveL2RollupProvider +// the checkDuration is the duration between checks to see if the current rollup client is active +// provide a checkDuration of 0 to check every time +func NewActiveL2RollupProvider( + ctx context.Context, + rollupUrls []string, + checkDuration time.Duration, + networkTimeout time.Duration, + logger log.Logger, +) (*ActiveL2RollupProvider, error) { + rollupDialer := func(ctx context.Context, timeout time.Duration, + log log.Logger, url string, + ) (RollupClientInterface, error) { + return DialRollupClientWithTimeout(ctx, timeout, log, url) + } + return newActiveL2RollupProvider(ctx, rollupUrls, checkDuration, networkTimeout, logger, rollupDialer) +} + +func newActiveL2RollupProvider( + ctx context.Context, + rollupUrls []string, + checkDuration time.Duration, + networkTimeout time.Duration, + logger log.Logger, + dialer rollupDialer, +) (*ActiveL2RollupProvider, error) { + if len(rollupUrls) == 0 { + return nil, errors.New("empty rollup urls list") + } + p := &ActiveL2RollupProvider{ + checkDuration: checkDuration, + networkTimeout: networkTimeout, + log: logger, + rollupUrls: rollupUrls, + rollupDialer: dialer, + clientLock: &sync.Mutex{}, + } + cctx, cancel := context.WithTimeout(ctx, networkTimeout) + defer cancel() + + if _, err := p.RollupClient(cctx); err != nil { + return nil, fmt.Errorf("setting provider rollup client: %w", err) + } + return p, nil +} + +func (p *ActiveL2RollupProvider) RollupClient(ctx context.Context) (RollupClientInterface, error) { + p.clientLock.Lock() + defer p.clientLock.Unlock() + err := p.ensureActiveEndpoint(ctx) + if err != nil { + return nil, err + } + return p.currentRollupClient, nil +} + +func (p *ActiveL2RollupProvider) ensureActiveEndpoint(ctx context.Context) error { + if !p.shouldCheck() { + return nil + } + if err := p.findActiveEndpoints(ctx); err != nil { + return err + } + p.activeTimeout = time.Now().Add(p.checkDuration) + return nil +} + +func (p *ActiveL2RollupProvider) shouldCheck() bool { + return time.Now().After(p.activeTimeout) +} + +func (p *ActiveL2RollupProvider) findActiveEndpoints(ctx context.Context) error { + startIdx := p.rollupIndex + var errs error + for offset := range p.rollupUrls { + idx := (startIdx + offset) % p.numEndpoints() + if offset != 0 || p.currentRollupClient == nil { + if err := p.dialSequencer(ctx, idx); err != nil { + errs = errors.Join(errs, err) + p.log.Warn("Error dialing next sequencer.", "err", err, "index", p.rollupIndex) + continue + } + } + + ep := p.rollupUrls[idx] + if active, err := p.checkCurrentSequencer(ctx); err != nil { + errs = errors.Join(errs, err) + p.log.Warn("Error querying active sequencer, trying next.", "err", err, "index", idx, "url", ep) + } else if active { + if offset == 0 { + p.log.Debug("Current sequencer active.", "index", idx, "url", ep) + } else { + p.log.Info("Found new active sequencer.", "index", idx, "url", ep) + } + return nil + } else { + p.log.Info("Sequencer inactive, trying next.", "index", idx, "url", ep) + } + } + return fmt.Errorf("failed to find an active sequencer, tried following urls: %v; errs: %w", p.rollupUrls, errs) +} + +func (p *ActiveL2RollupProvider) checkCurrentSequencer(ctx context.Context) (bool, error) { + cctx, cancel := context.WithTimeout(ctx, p.networkTimeout) + defer cancel() + return p.currentRollupClient.SequencerActive(cctx) +} + +func (p *ActiveL2RollupProvider) numEndpoints() int { + return len(p.rollupUrls) +} + +// dialSequencer dials the sequencer for the url at the given index. +// If successful, the currentRollupClient and rollupIndex are updated and the +// old rollup client is closed. +func (p *ActiveL2RollupProvider) dialSequencer(ctx context.Context, idx int) error { + cctx, cancel := context.WithTimeout(ctx, p.networkTimeout) + defer cancel() + + ep := p.rollupUrls[idx] + p.log.Info("Dialing next sequencer.", "index", idx, "url", ep) + rollupClient, err := p.rollupDialer(cctx, p.networkTimeout, p.log, ep) + if err != nil { + return fmt.Errorf("dialing rollup client: %w", err) + } + if p.currentRollupClient != nil { + p.currentRollupClient.Close() + } + p.rollupIndex = idx + p.currentRollupClient = rollupClient + return nil +} + +func (p *ActiveL2RollupProvider) Close() { + if p.currentRollupClient != nil { + p.currentRollupClient.Close() + } +} diff --git a/op-service/dial/dial.go b/op-service/dial/dial.go index 65cd0e55bdc2..d2f346472af6 100644 --- a/op-service/dial/dial.go +++ b/op-service/dial/dial.go @@ -51,6 +51,15 @@ func DialRollupClientWithTimeout(ctx context.Context, timeout time.Duration, log return sources.NewRollupClient(client.NewBaseRPCClient(rpcCl)), nil } +// DialRPCClientWithTimeout attempts to dial the RPC provider using the provided URL. +// If the dial doesn't complete within timeout seconds, this method will return an error. +func DialRPCClientWithTimeout(ctx context.Context, timeout time.Duration, log log.Logger, url string) (*rpc.Client, error) { + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + return dialRPCClientWithBackoff(ctx, log, url) +} + // Dials a JSON-RPC endpoint repeatedly, with a backoff, until a client connection is established. Auth is optional. func dialRPCClientWithBackoff(ctx context.Context, log log.Logger, addr string) (*rpc.Client, error) { bOff := retry.Fixed(defaultRetryTime) diff --git a/op-service/dial/ethclient_interface.go b/op-service/dial/ethclient_interface.go new file mode 100644 index 000000000000..58a2070974ee --- /dev/null +++ b/op-service/dial/ethclient_interface.go @@ -0,0 +1,16 @@ +package dial + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/core/types" +) + +// EthClientInterface is an interface for providing an ethclient.Client +// It does not describe all of the functions an ethclient.Client has, only the ones used by callers of the L2 Providers +type EthClientInterface interface { + BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) + + Close() +} diff --git a/op-service/dial/rollupclient_interface.go b/op-service/dial/rollupclient_interface.go new file mode 100644 index 000000000000..46e1afdc7264 --- /dev/null +++ b/op-service/dial/rollupclient_interface.go @@ -0,0 +1,20 @@ +package dial + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" +) + +// RollupClientInterface is an interface for providing a RollupClient +// It does not describe all of the functions a RollupClient has, only the ones used by the L2 Providers and their callers +type RollupClientInterface interface { + OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) + SyncStatus(ctx context.Context) (*eth.SyncStatus, error) + RollupConfig(ctx context.Context) (*rollup.Config, error) + StartSequencer(ctx context.Context, unsafeHead common.Hash) error + SequencerActive(ctx context.Context) (bool, error) + Close() +} diff --git a/op-service/dial/static_l2_provider.go b/op-service/dial/static_l2_provider.go new file mode 100644 index 000000000000..c6fbb64845df --- /dev/null +++ b/op-service/dial/static_l2_provider.go @@ -0,0 +1,51 @@ +package dial + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum/go-ethereum/log" +) + +// L2EndpointProvider is an interface for providing a RollupClient and l2 eth client +// It manages the lifecycle of the RollupClient and eth client for callers +// It does this by extending the RollupProvider interface to add the ability to get an EthClient +type L2EndpointProvider interface { + RollupProvider + // EthClient(ctx) returns the underlying ethclient pointing to the L2 execution node + EthClient(ctx context.Context) (EthClientInterface, error) +} + +// StaticL2EndpointProvider is a L2EndpointProvider that always returns the same static RollupClient and eth client +// It is meant for scenarios where a single, unchanging (L2 rollup node, L2 execution node) pair is used +type StaticL2EndpointProvider struct { + StaticL2RollupProvider + ethClient client.Client +} + +func NewStaticL2EndpointProvider(ctx context.Context, log log.Logger, ethClientUrl string, rollupClientUrl string, metrics metrics.RPCMetricer) (*StaticL2EndpointProvider, error) { + ethClient, err := DialEthClientWithTimeout(ctx, DefaultDialTimeout, log, ethClientUrl) + if err != nil { + return nil, err + } + rollupProvider, err := NewStaticL2RollupProvider(ctx, log, rollupClientUrl) + if err != nil { + return nil, err + } + return &StaticL2EndpointProvider{ + StaticL2RollupProvider: *rollupProvider, + ethClient: client.NewInstrumentedClient(ethClient, metrics), + }, nil +} + +func (p *StaticL2EndpointProvider) EthClient(context.Context) (EthClientInterface, error) { + return p.ethClient, nil +} + +func (p *StaticL2EndpointProvider) Close() { + if p.ethClient != nil { + p.ethClient.Close() + } + p.StaticL2RollupProvider.Close() +} diff --git a/op-service/dial/static_rollup_provider.go b/op-service/dial/static_rollup_provider.go new file mode 100644 index 000000000000..a40bb667290a --- /dev/null +++ b/op-service/dial/static_rollup_provider.go @@ -0,0 +1,50 @@ +package dial + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum/go-ethereum/log" +) + +// RollupProvider is an interface for providing a RollupClient +// It manages the lifecycle of the RollupClient for callers +type RollupProvider interface { + // RollupClient(ctx) returns the underlying sources.RollupClient pointing to the L2 rollup consensus node + RollupClient(ctx context.Context) (RollupClientInterface, error) + // Close() closes the underlying client or clients + Close() +} + +// StaticL2RollupProvider is a RollupProvider that always returns the same static RollupClient +// It is meant for scenarios where a single, unchanging L2 rollup node is used +type StaticL2RollupProvider struct { + rollupClient *sources.RollupClient +} + +func NewStaticL2RollupProvider(ctx context.Context, log log.Logger, rollupClientUrl string) (*StaticL2RollupProvider, error) { + rollupClient, err := DialRollupClientWithTimeout(ctx, DefaultDialTimeout, log, rollupClientUrl) + if err != nil { + return nil, err + } + return &StaticL2RollupProvider{ + rollupClient: rollupClient, + }, nil +} + +// The NewStaticL2EndpointProviderFromExistingRollup constructor is used in e2e testing +func NewStaticL2RollupProviderFromExistingRollup(rollupCl *sources.RollupClient) (*StaticL2RollupProvider, error) { + return &StaticL2RollupProvider{ + rollupClient: rollupCl, + }, nil +} + +func (p *StaticL2RollupProvider) RollupClient(context.Context) (RollupClientInterface, error) { + return p.rollupClient, nil +} + +func (p *StaticL2RollupProvider) Close() { + if p.rollupClient != nil { + p.rollupClient.Close() + } +} diff --git a/op-service/dummydial/dummydial.go b/op-service/dummydial/dummydial.go new file mode 100644 index 000000000000..7a1fb211ca46 --- /dev/null +++ b/op-service/dummydial/dummydial.go @@ -0,0 +1,85 @@ +// dummydial is copied from op-service/dial/dial.go but removed DialRollupClientWithTimeout, to workaround cycle imports issue +package dummydial + +import ( + "context" + "fmt" + "time" + + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/retry" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" +) + +// DefaultDialTimeout is a default timeout for dialing a client. +const DefaultDialTimeout = 1 * time.Minute +const defaultRetryCount = 30 +const defaultRetryTime = 2 * time.Second + +const BatcherFallbackThreshold int64 = 10 +const ProposerFallbackThreshold int64 = 3 +const TxmgrFallbackThreshold int64 = 3 + +// DialEthClientWithTimeout attempts to dial the L1 provider using the provided +// URL. If the dial doesn't complete within defaultDialTimeout seconds, this +// method will return an error. +func DialEthClientWithTimeout(ctx context.Context, timeout time.Duration, log log.Logger, url string) (client.Client, error) { + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + c, err := dialRPCClientWithBackoff(ctx, log, url) + if err != nil { + return nil, err + } + + return ethclient.NewClient(c), nil +} + +// DialRPCClientWithTimeout attempts to dial the RPC provider using the provided URL. +// If the dial doesn't complete within timeout seconds, this method will return an error. +func DialRPCClientWithTimeout(ctx context.Context, timeout time.Duration, log log.Logger, url string) (*rpc.Client, error) { + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + return dialRPCClientWithBackoff(ctx, log, url) +} + +// Dials a JSON-RPC endpoint repeatedly, with a backoff, until a client connection is established. Auth is optional. +func dialRPCClientWithBackoff(ctx context.Context, log log.Logger, addr string) (*rpc.Client, error) { + bOff := retry.Fixed(defaultRetryTime) + return retry.Do(ctx, defaultRetryCount, bOff, func() (*rpc.Client, error) { + if !client.IsURLAvailable(addr) { + log.Warn("failed to dial address, but may connect later", "addr", addr) + return nil, fmt.Errorf("address unavailable (%s)", addr) + } + client, err := rpc.DialOptions(ctx, addr) + if err != nil { + return nil, fmt.Errorf("failed to dial address (%s): %w", addr, err) + } + return client, nil + }) +} + +// DialEthClientWithTimeoutAndFallback will try to dial within the timeout period and create an EthClient. +// If the URL is a multi URL, then a fallbackClient will be created to add the fallback capability to the client +func DialEthClientWithTimeoutAndFallback(ctx context.Context, url string, timeout time.Duration, l log.Logger, fallbackThreshold int64, m client.FallbackClientMetricer) (client.Client, error) { + isMultiUrl, urlList := client.MultiUrlParse(url) + if isMultiUrl { + firstEthClient, err := DialEthClientWithTimeout(ctx, timeout, l, urlList[0]) + if err != nil { + return nil, err + } + fallbackClient := client.NewFallbackClient(firstEthClient, urlList, l, fallbackThreshold, m, func(url string) (client.Client, error) { + ethClientNew, err := DialEthClientWithTimeout(ctx, timeout, l, url) + if err != nil { + return nil, err + } + return ethClientNew, nil + }) + return fallbackClient, nil + } + + return DialEthClientWithTimeout(ctx, timeout, l, url) +} diff --git a/op-service/eth/blob.go b/op-service/eth/blob.go new file mode 100644 index 000000000000..2c60828571db --- /dev/null +++ b/op-service/eth/blob.go @@ -0,0 +1,287 @@ +package eth + +import ( + "crypto/sha256" + "errors" + "fmt" + "reflect" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ethereum/go-ethereum/params" +) + +const ( + BlobSize = 4096 * 32 + MaxBlobDataSize = (4*31+3)*1024 - 4 + EncodingVersion = 0 + VersionOffset = 1 // offset of the version byte in the blob encoding + Rounds = 1024 // number of encode/decode rounds +) + +var ( + ErrBlobInvalidFieldElement = errors.New("invalid field element") + ErrBlobInvalidEncodingVersion = errors.New("invalid encoding version") + ErrBlobInvalidLength = errors.New("invalid length for blob") + ErrBlobInputTooLarge = errors.New("too much data to encode in one blob") + ErrBlobExtraneousData = errors.New("non-zero data encountered where blob should be empty") + ErrBlobExtraneousDataFieldElement = errors.New("non-zero data encountered where field element should be empty") +) + +type Blob [BlobSize]byte + +func (b *Blob) KZGBlob() *kzg4844.Blob { + return (*kzg4844.Blob)(b) +} + +func (b *Blob) UnmarshalJSON(text []byte) error { + return hexutil.UnmarshalFixedJSON(reflect.TypeOf(b), text, b[:]) +} + +func (b *Blob) UnmarshalText(text []byte) error { + return hexutil.UnmarshalFixedText("Bytes32", text, b[:]) +} + +func (b *Blob) MarshalText() ([]byte, error) { + return hexutil.Bytes(b[:]).MarshalText() +} + +func (b *Blob) String() string { + return hexutil.Encode(b[:]) +} + +// TerminalString implements log.TerminalStringer, formatting a string for console +// output during logging. +func (b *Blob) TerminalString() string { + return fmt.Sprintf("%x..%x", b[:3], b[BlobSize-3:]) +} + +func (b *Blob) ComputeKZGCommitment() (kzg4844.Commitment, error) { + return kzg4844.BlobToCommitment(*b.KZGBlob()) +} + +// KZGToVersionedHash computes the "blob hash" (a.k.a. versioned-hash) of a blob-commitment, as used in a blob-tx. +// We implement it here because it is unfortunately not (currently) exposed by geth. +func KZGToVersionedHash(commitment kzg4844.Commitment) (out common.Hash) { + // EIP-4844 spec: + // def kzg_to_versioned_hash(commitment: KZGCommitment) -> VersionedHash: + // return VERSIONED_HASH_VERSION_KZG + sha256(commitment)[1:] + h := sha256.New() + h.Write(commitment[:]) + _ = h.Sum(out[:0]) + out[0] = params.BlobTxHashVersion + return out +} + +// VerifyBlobProof verifies that the given blob and proof corresponds to the given commitment, +// returning error if the verification fails. +func VerifyBlobProof(blob *Blob, commitment kzg4844.Commitment, proof kzg4844.Proof) error { + return kzg4844.VerifyBlobProof(*blob.KZGBlob(), commitment, proof) +} + +// FromData encodes the given input data into this blob. The encoding scheme is as follows: +// +// In each round we perform 7 reads of input of lengths (31,1,31,1,31,1,31) bytes respectively for +// a total of 127 bytes. This data is encoded into the next 4 field elements of the output by +// placing each of the 4x31 byte chunks into bytes [1:32] of its respective field element. The +// three single byte chunks (24 bits) are split into 4x6-bit chunks, each of which is written into +// the top most byte of its respective field element, leaving the top 2 bits of each field element +// empty to avoid modulus overflow. This process is repeated for up to 1024 rounds until all data +// is encoded. +// +// For only the very first output field, bytes [1:5] are used to encode the version and the length +// of the data. +func (b *Blob) FromData(data Data) error { + if len(data) > MaxBlobDataSize { + return fmt.Errorf("%w: len=%v", ErrBlobInputTooLarge, data) + } + b.Clear() + + readOffset := 0 + + // read 1 byte of input, 0 if there is no input left + read1 := func() byte { + if readOffset >= len(data) { + return 0 + } + out := data[readOffset] + readOffset += 1 + return out + } + + writeOffset := 0 + var buf31 [31]byte + var zero31 [31]byte + + // Read up to 31 bytes of input (left-aligned), into buf31. + read31 := func() { + if readOffset >= len(data) { + copy(buf31[:], zero31[:]) + return + } + n := copy(buf31[:], data[readOffset:]) // copy as much data as we can + copy(buf31[n:], zero31[:]) // pad with zeroes (since there might not be enough data) + readOffset += n + } + // Write a byte, updates the write-offset. + // Asserts that the write-offset matches encoding-algorithm expectations. + // Asserts that the value is 6 bits. + write1 := func(v byte) { + if writeOffset%32 != 0 { + panic(fmt.Errorf("blob encoding: invalid byte write offset: %d", writeOffset)) + } + if v&0b1100_0000 != 0 { + panic(fmt.Errorf("blob encoding: invalid 6 bit value: 0b%b", v)) + } + b[writeOffset] = v + writeOffset += 1 + } + // Write buf31 to the blob, updates the write-offset. + // Asserts that the write-offset matches encoding-algorithm expectations. + write31 := func() { + if writeOffset%32 != 1 { + panic(fmt.Errorf("blob encoding: invalid bytes31 write offset: %d", writeOffset)) + } + copy(b[writeOffset:], buf31[:]) + writeOffset += 31 + } + + for round := 0; round < Rounds && readOffset < len(data); round++ { + // The first field element encodes the version and the length of the data in [1:5]. + // This is a manual substitute for read31(), preparing the buf31. + if round == 0 { + buf31[0] = EncodingVersion + // Encode the length as big-endian uint24. + // The length check at the start above ensures we can always fit the length value into only 3 bytes. + ilen := uint32(len(data)) + buf31[1] = byte(ilen >> 16) + buf31[2] = byte(ilen >> 8) + buf31[3] = byte(ilen) + + readOffset += copy(buf31[4:], data[:]) + } else { + read31() + } + + x := read1() + A := x & 0b0011_1111 + write1(A) + write31() + + read31() + y := read1() + B := (y & 0b0000_1111) | ((x & 0b1100_0000) >> 2) + write1(B) + write31() + + read31() + z := read1() + C := z & 0b0011_1111 + write1(C) + write31() + + read31() + D := ((z & 0b1100_0000) >> 2) | ((y & 0b1111_0000) >> 4) + write1(D) + write31() + } + + if readOffset < len(data) { + panic(fmt.Errorf("expected to fit data but failed, read offset: %d, data: %d", readOffset, len(data))) + } + return nil +} + +// ToData decodes the blob into raw byte data. See FromData above for details on the encoding +// format. If error is returned it will be one of InvalidFieldElementError, +// InvalidEncodingVersionError and InvalidLengthError. +func (b *Blob) ToData() (Data, error) { + // check the version + if b[VersionOffset] != EncodingVersion { + return nil, fmt.Errorf( + "%w: expected version %d, got %d", ErrBlobInvalidEncodingVersion, EncodingVersion, b[VersionOffset]) + } + + // decode the 3-byte big-endian length value into a 4-byte integer + outputLen := uint32(b[2])<<16 | uint32(b[3])<<8 | uint32(b[4]) + if outputLen > MaxBlobDataSize { + return nil, fmt.Errorf("%w: got %d", ErrBlobInvalidLength, outputLen) + } + + // round 0 is special cased to copy only the remaining 27 bytes of the first field element into + // the output due to version/length encoding already occupying its first 5 bytes. + output := make(Data, MaxBlobDataSize) + copy(output[0:27], b[5:]) + + // now process remaining 3 field elements to complete round 0 + opos := 28 // current position into output buffer + ipos := 32 // current position into the input blob + var err error + encodedByte := make([]byte, 4) // buffer for the 4 6-bit chunks + encodedByte[0] = b[0] + for i := 1; i < 4; i++ { + encodedByte[i], opos, ipos, err = b.decodeFieldElement(opos, ipos, output) + if err != nil { + return nil, err + } + } + opos = reassembleBytes(opos, encodedByte, output) + + // in each remaining round we decode 4 field elements (128 bytes) of the input into 127 bytes + // of output + for i := 1; i < Rounds && opos < int(outputLen); i++ { + for j := 0; j < 4; j++ { + // save the first byte of each field element for later re-assembly + encodedByte[j], opos, ipos, err = b.decodeFieldElement(opos, ipos, output) + if err != nil { + return nil, err + } + } + opos = reassembleBytes(opos, encodedByte, output) + } + for i := int(outputLen); i < len(output); i++ { + if output[i] != 0 { + return nil, fmt.Errorf("fe=%d: %w", opos/32, ErrBlobExtraneousDataFieldElement) + } + } + output = output[:outputLen] + for ; ipos < BlobSize; ipos++ { + if b[ipos] != 0 { + return nil, fmt.Errorf("pos=%d: %w", ipos, ErrBlobExtraneousData) + } + } + return output, nil +} + +// decodeFieldElement decodes the next input field element by writing its lower 31 bytes into its +// appropriate place in the output and checking the high order byte is valid. Returns an +// InvalidFieldElementError if a field element is seen with either of its two high order bits set. +func (b *Blob) decodeFieldElement(opos, ipos int, output []byte) (byte, int, int, error) { + // two highest order bits of the first byte of each field element should always be 0 + if b[ipos]&0b1100_0000 != 0 { + return 0, 0, 0, fmt.Errorf("%w: field element: %d", ErrBlobInvalidFieldElement, ipos) + } + copy(output[opos:], b[ipos+1:ipos+32]) + return b[ipos], opos + 32, ipos + 32, nil +} + +// reassembleBytes takes the 4x6-bit chunks from encodedByte, reassembles them into 3 bytes of +// output, and places them in their appropriate output positions. +func reassembleBytes(opos int, encodedByte []byte, output []byte) int { + opos-- // account for fact that we don't output a 128th byte + x := (encodedByte[0] & 0b0011_1111) | ((encodedByte[1] & 0b0011_0000) << 2) + y := (encodedByte[1] & 0b0000_1111) | ((encodedByte[3] & 0b0000_1111) << 4) + z := (encodedByte[2] & 0b0011_1111) | ((encodedByte[3] & 0b0011_0000) << 2) + // put the re-assembled bytes in their appropriate output locations + output[opos-32] = z + output[opos-(32*2)] = y + output[opos-(32*3)] = x + return opos +} + +func (b *Blob) Clear() { + for i := 0; i < BlobSize; i++ { + b[i] = 0 + } +} diff --git a/op-service/eth/blob_test.go b/op-service/eth/blob_test.go new file mode 100644 index 000000000000..83e21ed88b4e --- /dev/null +++ b/op-service/eth/blob_test.go @@ -0,0 +1,293 @@ +package eth + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBlobEncodeDecode(t *testing.T) { + cases := []string{ + "this is a test of blob encoding/decoding", + "short", + "\x00", + "\x00\x01\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "", + } + + var b Blob + for _, c := range cases { + data := Data(c) + err := b.FromData(data) + require.NoError(t, err) + decoded, err := b.ToData() + require.NoError(t, err) + require.Equal(t, c, string(decoded)) + } +} + +func TestSmallBlobEncoding(t *testing.T) { + // the first field element is filled and no data remains + data := Data(make([]byte, 128)) + data[127] = 0xFF + + var b Blob + err := b.FromData(data) + require.NoError(t, err) + + decoded, err := b.ToData() + require.NoError(t, err) + require.Equal(t, data, decoded) + + // only 10 bytes of data + data = Data(make([]byte, 10)) + data[9] = 0xFF + err = b.FromData(data) + require.NoError(t, err) + decoded, err = b.ToData() + require.NoError(t, err) + require.Equal(t, data, decoded) + + // no 3 bytes of extra data left to encode after the first 4 field elements + data = Data(make([]byte, 27+31*3)) + data[27+31*3-1] = 0xFF + err = b.FromData(data) + require.NoError(t, err) + decoded, err = b.ToData() + require.NoError(t, err) + require.Equal(t, data, decoded) +} + +func TestBigBlobEncoding(t *testing.T) { + r := rand.New(rand.NewSource(99)) + bigData := Data(make([]byte, MaxBlobDataSize)) + for i := range bigData { + bigData[i] = byte(r.Intn(256)) + } + var b Blob + // test the maximum size of data that can be encoded + err := b.FromData(bigData) + require.NoError(t, err) + decoded, err := b.ToData() + require.NoError(t, err) + require.Equal(t, bigData, decoded) + + // perform encode/decode test on progressively smaller inputs to exercise boundary conditions + // pertaining to length of the input data + for i := 1; i < 256; i++ { + tempBigData := bigData[i:] + err := b.FromData(tempBigData) + require.NoError(t, err) + decoded, err := b.ToData() + require.NoError(t, err) + require.Equal(t, len(tempBigData), len(decoded)) + require.Equal(t, tempBigData, decoded) + } +} + +func TestInvalidBlobDecoding(t *testing.T) { + data := Data("this is a test of invalid blob decoding") + var b Blob + if err := b.FromData(data); err != nil { + t.Fatalf("failed to encode bytes: %v", err) + } + + b[32] = 0b10000000 // field elements should never have their highest order bit set + _, err := b.ToData() + require.ErrorIs(t, err, ErrBlobInvalidFieldElement) + b[32] = 0x0 + + b[32] = 0b01000000 // field elements should never have their second highest order bit set + _, err = b.ToData() + require.ErrorIs(t, err, ErrBlobInvalidFieldElement) + b[32] = 0x0 + + b[VersionOffset] = 0x01 // invalid encoding version + _, err = b.ToData() + require.ErrorIs(t, err, ErrBlobInvalidEncodingVersion) + b[VersionOffset] = EncodingVersion + + b[2] = 0xFF // encode an invalid (much too long) length prefix + _, err = b.ToData() + require.ErrorIs(t, err, ErrBlobInvalidLength) +} + +func TestTooLongDataEncoding(t *testing.T) { + // should never be able to encode data that has size the same as that of the blob due to < 256 + // bit precision of each field element + data := Data(make([]byte, BlobSize)) + var b Blob + err := b.FromData(data) + require.ErrorIs(t, err, ErrBlobInputTooLarge) +} + +func FuzzEncodeDecodeBlob(f *testing.F) { + var b Blob + f.Fuzz(func(t *testing.T, d []byte) { + b.Clear() + data := Data(d) + err := b.FromData(data) + require.NoError(t, err) + decoded, err := b.ToData() + require.NoError(t, err) + require.Equal(t, data, decoded) + }) +} + +func FuzzDetectNonBijectivity(f *testing.F) { + var b Blob + r := rand.New(rand.NewSource(99)) + f.Fuzz(func(t *testing.T, d []byte) { + b.Clear() + data := Data(d) + err := b.FromData(data) + require.NoError(t, err) + // randomly flip a bit and make sure the data either fails to decode or decodes differently + byteToFlip := r.Intn(BlobSize) + bitToFlip := r.Intn(8) + mask := byte(1 << bitToFlip) + b[byteToFlip] = b[byteToFlip] ^ mask + decoded, err := b.ToData() + if err != nil { + require.NotEqual(t, data, decoded) + } + }) +} + +func TestDecodeTestVectors(t *testing.T) { + cases := []struct { + input, output string + err error + }{ + { + // an empty blob has version 0 and length 0, so is valid and will decode as empty output + input: "", + output: "", + }, + { + // encode len==1, so should get one zero byte output + input: "\x00\x00\x00\x00\x01", + output: "\x00", + }, + { + // encode len==130044 (0x01FBFC), max blob capacity, so should get 130044 zero bytes + // for output + input: "\x00\x00\x01\xFB\xFC", + output: string(make([]byte, 130044)), + }, + { + // encode len==130045 (0x01FBFD) which is greater than blob capacity, blob invalid + input: "\x00\x00\x01\xFB\xFD", + err: ErrBlobInvalidLength, + }, + { + // encode len=10 + input: "\x00\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff", + output: "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff", + }, + { + // decode what should be 27 0xFF bytes + input: "\x00\x00\x00\x00\x1b\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", + output: "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", + }, + { + // decode what should be 32 0xFF bytes + input: "\x3f\x00\x00\x00\x20\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\xff\xff\xff\xff", + output: "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", + }, + } + + var b Blob + for _, c := range cases { + b.Clear() + copy(b[:], []byte(c.input)) + decoded, err := b.ToData() + if c.err != nil { + require.ErrorIs(t, err, c.err) + } else { + require.NoError(t, err) + require.Equal(t, len(c.output), len(decoded)) + require.Equal(t, c.output, string(decoded)) + } + } +} + +func TestEncodeTestVectors(t *testing.T) { + cases := []struct { + input, output string + err error + }{ + { + // empty (all zeros) blob should decode as empty string + input: "", + output: "", + }, + { + // max input data + input: string(make([]byte, MaxBlobDataSize)), + output: "\x00\x00\x01\xfb\xfc", + }, + { + // input data too big + input: string(make([]byte, MaxBlobDataSize+1)), + output: "", + err: ErrBlobInputTooLarge, + }, + { + // 27 bytes each with high order bits set (should cleanly fit in the first FE along with the version+length) + input: "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", + output: "\x00\x00\x00\x00\x1b\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", + }, + { + // 28 bytes each with high order bits set, requires high bits spilling into byte 0 and last byte + input: "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", + output: "\x3f\x00\x00\x00\x1c\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30", + }, + } + + var b, testBlob Blob + for _, c := range cases { + err := b.FromData(Data(c.input)) + if c.err != nil { + require.ErrorIs(t, err, c.err) + } else { + require.NoError(t, err) + testBlob.Clear() + copy(testBlob[:], []byte(c.output)) + require.Equal(t, testBlob, b) + } + } +} + +func TestExtraneousData(t *testing.T) { + var b Blob + // make sure 0 length blob with non-zero bits in upper byte are detected & rejected + input := "\x30\x00\x00\x00\x00" + copy(b[:], []byte(input)) + _, err := b.ToData() + require.ErrorIs(t, err, ErrBlobExtraneousDataFieldElement) + input = "\x01\x00\x00\x00\x00" + copy(b[:], []byte(input)) + _, err = b.ToData() + require.ErrorIs(t, err, ErrBlobExtraneousDataFieldElement) + b.Clear() + i := len(input) + + // make sure non-zero bytes in blob following the encoded length are detected & rejected + for ; i < 128; i++ { + b[i-1] = 0 + b[i] = 0x01 + decoded, err := b.ToData() + require.ErrorIs(t, err, ErrBlobExtraneousDataFieldElement, len(decoded)) + } + for ; i < BlobSize; i += 7 { // increment by 7 bytes each iteration so the test isn't too slow + b[i-1] = 0 + b[i] = 1 + decoded, err := b.ToData() + require.ErrorIs(t, err, ErrBlobExtraneousData, len(decoded)) + } +} diff --git a/op-service/eth/blobs_api.go b/op-service/eth/blobs_api.go new file mode 100644 index 000000000000..14b739352211 --- /dev/null +++ b/op-service/eth/blobs_api.go @@ -0,0 +1,89 @@ +package eth + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +type BlobSidecar struct { + Blob Blob `json:"blob"` + Index Uint64String `json:"index"` + KZGCommitment Bytes48 `json:"kzg_commitment"` + KZGProof Bytes48 `json:"kzg_proof"` +} + +type APIBlobSidecar struct { + Index Uint64String `json:"index"` + Blob Blob `json:"blob"` + KZGCommitment Bytes48 `json:"kzg_commitment"` + KZGProof Bytes48 `json:"kzg_proof"` + SignedBlockHeader SignedBeaconBlockHeader `json:"signed_block_header"` + // The inclusion-proof of the blob-sidecar into the beacon-block is ignored, + // since we verify blobs by their versioned hashes against the execution-layer block instead. +} + +func (sc *APIBlobSidecar) BlobSidecar() *BlobSidecar { + return &BlobSidecar{ + Blob: sc.Blob, + Index: sc.Index, + KZGCommitment: sc.KZGCommitment, + KZGProof: sc.KZGProof, + } +} + +type SignedBeaconBlockHeader struct { + Message BeaconBlockHeader `json:"message"` + // signature is ignored, since we verify blobs against EL versioned-hashes +} + +type BeaconBlockHeader struct { + Slot Uint64String `json:"slot"` + ProposerIndex Uint64String `json:"proposer_index"` + ParentRoot Bytes32 `json:"parent_root"` + StateRoot Bytes32 `json:"state_root"` + BodyRoot Bytes32 `json:"body_root"` +} + +type APIGetBlobSidecarsResponse struct { + Data []*APIBlobSidecar `json:"data"` +} + +type ReducedGenesisData struct { + GenesisTime Uint64String `json:"genesis_time"` +} + +type APIGenesisResponse struct { + Data ReducedGenesisData `json:"data"` +} + +type ReducedConfigData struct { + SecondsPerSlot Uint64String `json:"SECONDS_PER_SLOT"` +} + +type APIConfigResponse struct { + Data ReducedConfigData `json:"data"` +} + +type APIVersionResponse struct { + Data VersionInformation `json:"data"` +} + +type VersionInformation struct { + Version string `json:"version"` +} + +type BSCBlobTxSidecar struct { + Blobs []Blob `json:"blobs"` + Commitments []Bytes48 `json:"commitments"` + Proofs []Bytes48 `json:"proofs"` +} + +type BSCBlobSidecar struct { + BSCBlobTxSidecar `json:"blobSidecar"` + BlockNumber *hexutil.Big `json:"blockNumber"` + BlockHash common.Hash `json:"blockHash"` + TxIndex *hexutil.Uint64 `json:"txIndex"` + TxHash common.Hash `json:"txHash"` +} + +type BSCBlobSidecars []*BSCBlobSidecar diff --git a/op-service/eth/blobs_api_test.go b/op-service/eth/blobs_api_test.go new file mode 100644 index 000000000000..ca8a15766ad8 --- /dev/null +++ b/op-service/eth/blobs_api_test.go @@ -0,0 +1,97 @@ +package eth_test + +import ( + "encoding/json" + "os" + "path/filepath" + "reflect" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/stretchr/testify/require" +) + +type dataJson struct { + Data map[string]any `json:"data"` +} + +// TestAPIGenesisResponse tests that json unmarshaling a json response from a +// eth/v1/beacon/genesis beacon node call into a APIGenesisResponse object +// fills all existing fields with the expected values, thereby confirming that +// APIGenesisResponse is compatible with the current beacon node API. +// This also confirms that the [sources.L1BeaconClient] correctly parses +// responses from a real beacon node. +func TestAPIGenesisResponse(t *testing.T) { + require := require.New(t) + var resp eth.APIGenesisResponse + require.Equal(1, reflect.TypeOf(resp.Data).NumField(), "APIGenesisResponse changed, adjust test") + + path := filepath.Join("testdata", "eth_v1_beacon_genesis_goerli.json") + jsonStr, err := os.ReadFile(path) + require.NoError(err) + + require.NoError(json.Unmarshal(jsonStr, &resp)) + require.NotZero(resp.Data.GenesisTime) + + jsonMap := &dataJson{Data: make(map[string]any)} + require.NoError(json.Unmarshal(jsonStr, jsonMap)) + genesisTime, err := resp.Data.GenesisTime.MarshalText() + require.NoError(err) + require.Equal(jsonMap.Data["genesis_time"].(string), string(genesisTime)) +} + +// TestAPIConfigResponse tests that json unmarshaling a json response from a +// eth/v1/config/spec beacon node call into a APIConfigResponse object +// fills all existing fields with the expected values, thereby confirming that +// APIGenesisResponse is compatible with the current beacon node API. +// This also confirms that the [sources.L1BeaconClient] correctly parses +// responses from a real beacon node. +func TestAPIConfigResponse(t *testing.T) { + require := require.New(t) + var resp eth.APIConfigResponse + require.Equal(1, reflect.TypeOf(resp.Data).NumField(), "APIConfigResponse changed, adjust test") + + path := filepath.Join("testdata", "eth_v1_config_spec_goerli.json") + jsonStr, err := os.ReadFile(path) + require.NoError(err) + + require.NoError(json.Unmarshal(jsonStr, &resp)) + require.NotZero(resp.Data.SecondsPerSlot) + + jsonMap := &dataJson{Data: make(map[string]any)} + require.NoError(json.Unmarshal(jsonStr, jsonMap)) + secPerSlot, err := resp.Data.SecondsPerSlot.MarshalText() + require.NoError(err) + require.Equal(jsonMap.Data["SECONDS_PER_SLOT"].(string), string(secPerSlot)) +} + +// TestAPIGetBlobSidecarsResponse tests that json unmarshaling a json response from a +// eth/v1/beacon/blob_sidecars/ beacon node call into a APIGetBlobSidecarsResponse object +// fills all existing fields with the expected values, thereby confirming that +// APIGenesisResponse is compatible with the current beacon node API. +// This also confirms that the [sources.L1BeaconClient] correctly parses +// responses from a real beacon node. +func TestAPIGetBlobSidecarsResponse(t *testing.T) { + require := require.New(t) + + path := filepath.Join("testdata", "eth_v1_beacon_blob_sidecars_7422094_goerli.json") + jsonStr, err := os.ReadFile(path) + require.NoError(err) + + var resp eth.APIGetBlobSidecarsResponse + require.NoError(json.Unmarshal(jsonStr, &resp)) + require.NotEmpty(resp.Data) + require.Equal(5, reflect.TypeOf(*resp.Data[0]).NumField(), "APIBlobSidecar changed, adjust test") + require.Equal(1, reflect.TypeOf(resp.Data[0].SignedBlockHeader).NumField(), "SignedBeaconBlockHeader changed, adjust test") + require.Equal(5, reflect.TypeOf(resp.Data[0].SignedBlockHeader.Message).NumField(), "BeaconBlockHeader changed, adjust test") + + require.NotZero(resp.Data[0].Blob) + require.NotZero(resp.Data[1].Index) + require.NotZero(resp.Data[0].KZGCommitment) + require.NotZero(resp.Data[0].KZGProof) + require.NotZero(resp.Data[0].SignedBlockHeader.Message.Slot) + require.NotZero(resp.Data[0].SignedBlockHeader.Message.ParentRoot) + require.NotZero(resp.Data[0].SignedBlockHeader.Message.BodyRoot) + require.NotZero(resp.Data[0].SignedBlockHeader.Message.ProposerIndex) + require.NotZero(resp.Data[0].SignedBlockHeader.Message.StateRoot) +} diff --git a/op-service/eth/block_info.go b/op-service/eth/block_info.go index 0b8d69189be8..268c6d934b6e 100644 --- a/op-service/eth/block_info.go +++ b/op-service/eth/block_info.go @@ -4,6 +4,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" ) @@ -18,8 +19,13 @@ type BlockInfo interface { // MixDigest field, reused for randomness after The Merge (Bellatrix hardfork) MixDigest() common.Hash BaseFee() *big.Int + // BlobBaseFee returns the result of computing the blob fee from excessDataGas, or nil if the + // block isn't a Dencun (4844 capable) block + BlobBaseFee() *big.Int ReceiptHash() common.Hash GasUsed() uint64 + GasLimit() uint64 + ParentBeaconRoot() *common.Hash // Dencun extension // HeaderRLP returns the RLP of the block header as per consensus rules // Returns an error if the header RLP could not be written @@ -50,10 +56,22 @@ func ToBlockID(b NumberAndHash) BlockID { // blockInfo is a conversion type of types.Block turning it into a BlockInfo type blockInfo struct{ *types.Block } +func (b blockInfo) BlobBaseFee() *big.Int { + ebg := b.ExcessBlobGas() + if ebg == nil { + return nil + } + return eip4844.CalcBlobFee(*ebg) +} + func (b blockInfo) HeaderRLP() ([]byte, error) { return rlp.EncodeToBytes(b.Header()) } +func (b blockInfo) ParentBeaconRoot() *common.Hash { + return b.Block.BeaconRoot() +} + func BlockToInfo(b *types.Block) BlockInfo { return blockInfo{b} } @@ -92,6 +110,13 @@ func (h headerBlockInfo) BaseFee() *big.Int { return h.Header.BaseFee } +func (h headerBlockInfo) BlobBaseFee() *big.Int { + if h.ExcessBlobGas == nil { + return nil + } + return eip4844.CalcBlobFee(*h.ExcessBlobGas) +} + func (h headerBlockInfo) ReceiptHash() common.Hash { return h.Header.ReceiptHash } @@ -100,6 +125,14 @@ func (h headerBlockInfo) GasUsed() uint64 { return h.Header.GasUsed } +func (h headerBlockInfo) GasLimit() uint64 { + return h.Header.GasLimit +} + +func (h headerBlockInfo) ParentBeaconRoot() *common.Hash { + return h.Header.ParentBeaconRoot +} + func (h headerBlockInfo) HeaderRLP() ([]byte, error) { return rlp.EncodeToBytes(h.Header) } diff --git a/op-service/eth/ether.go b/op-service/eth/ether.go new file mode 100644 index 000000000000..ad0d9152e647 --- /dev/null +++ b/op-service/eth/ether.go @@ -0,0 +1,29 @@ +package eth + +import ( + "errors" + "fmt" + "math" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/params" +) + +func GweiToWei(gwei float64) (*big.Int, error) { + if math.IsNaN(gwei) || math.IsInf(gwei, 0) { + return nil, fmt.Errorf("invalid gwei value: %v", gwei) + } + + // convert float GWei value into integer Wei value + wei, _ := new(big.Float).Mul( + big.NewFloat(gwei), + big.NewFloat(params.GWei)). + Int(nil) + + if wei.Cmp(abi.MaxUint256) == 1 { + return nil, errors.New("gwei value larger than max uint256") + } + + return wei, nil +} diff --git a/op-service/eth/ether_test.go b/op-service/eth/ether_test.go new file mode 100644 index 000000000000..f313619a4521 --- /dev/null +++ b/op-service/eth/ether_test.go @@ -0,0 +1,71 @@ +package eth + +import ( + "math" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/stretchr/testify/require" +) + +func TestGweiToWei(t *testing.T) { + maxUint256p1, _ := new(big.Int).Add(abi.MaxUint256, big.NewInt(1)).Float64() + for _, tt := range []struct { + desc string + gwei float64 + wei *big.Int + err bool + }{ + { + desc: "zero", + gwei: 0, + wei: new(big.Int), + }, + { + desc: "one-wei", + gwei: 0.000000001, + wei: big.NewInt(1), + }, + { + desc: "one-gwei", + gwei: 1.0, + wei: big.NewInt(1e9), + }, + { + desc: "one-ether", + gwei: 1e9, + wei: big.NewInt(1e18), + }, + { + desc: "err-pos-inf", + gwei: math.Inf(1), + err: true, + }, + { + desc: "err-neg-inf", + gwei: math.Inf(-1), + err: true, + }, + { + desc: "err-nan", + gwei: math.NaN(), + err: true, + }, + { + desc: "err-too-large", + gwei: maxUint256p1, + err: true, + }, + } { + t.Run(tt.desc, func(t *testing.T) { + wei, err := GweiToWei(tt.gwei) + if tt.err { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.wei, wei) + } + }) + } +} diff --git a/op-service/eth/heads.go b/op-service/eth/heads.go index af92990f0f1d..db837cbbed17 100644 --- a/op-service/eth/heads.go +++ b/op-service/eth/heads.go @@ -17,7 +17,8 @@ type NewHeadSource interface { SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) } -// WatchHeadChanges wraps a new-head subscription from NewHeadSource to feed the given Tracker +// WatchHeadChanges wraps a new-head subscription from NewHeadSource to feed the given Tracker. +// The ctx is only used to create the subscription, and does not affect the returned subscription. func WatchHeadChanges(ctx context.Context, src NewHeadSource, fn HeadSignalFn) (ethereum.Subscription, error) { headChanges := make(chan *types.Header, 10) sub, err := src.SubscribeNewHead(ctx, headChanges) @@ -25,22 +26,33 @@ func WatchHeadChanges(ctx context.Context, src NewHeadSource, fn HeadSignalFn) ( return nil, err } return event.NewSubscription(func(quit <-chan struct{}) error { + eventsCtx, eventsCancel := context.WithCancel(context.Background()) defer sub.Unsubscribe() + defer eventsCancel() + + // We can handle a quit signal while fn is running, by closing the ctx. + go func() { + select { + case <-quit: + eventsCancel() + case <-eventsCtx.Done(): // don't wait for quit signal if we closed for other reasons. + return + } + }() + for { select { case header := <-headChanges: - fn(ctx, L1BlockRef{ + fn(eventsCtx, L1BlockRef{ Hash: header.Hash(), Number: header.Number.Uint64(), ParentHash: header.ParentHash, Time: header.Time, }) - case err := <-sub.Err(): - return err - case <-ctx.Done(): - return ctx.Err() - case <-quit: + case <-eventsCtx.Done(): return nil + case err := <-sub.Err(): // if the underlying subscription fails, stop + return err } } }), nil @@ -53,7 +65,7 @@ type L1BlockRefsSource interface { // PollBlockChanges opens a polling loop to fetch the L1 block reference with the given label, // on provided interval and with request timeout. Results are returned with provided callback fn, // which may block to pause/back-pressure polling. -func PollBlockChanges(ctx context.Context, log log.Logger, src L1BlockRefsSource, fn HeadSignalFn, +func PollBlockChanges(log log.Logger, src L1BlockRefsSource, fn HeadSignalFn, label BlockLabel, interval time.Duration, timeout time.Duration) ethereum.Subscription { return event.NewSubscription(func(quit <-chan struct{}) error { if interval <= 0 { @@ -61,22 +73,32 @@ func PollBlockChanges(ctx context.Context, log log.Logger, src L1BlockRefsSource <-quit return nil } + eventsCtx, eventsCancel := context.WithCancel(context.Background()) + defer eventsCancel() + // We can handle a quit signal while fn is running, by closing the ctx. + go func() { + select { + case <-quit: + eventsCancel() + case <-eventsCtx.Done(): // don't wait for quit signal if we closed for other reasons. + return + } + }() + ticker := time.NewTicker(interval) defer ticker.Stop() for { select { case <-ticker.C: - reqCtx, reqCancel := context.WithTimeout(ctx, timeout) + reqCtx, reqCancel := context.WithTimeout(eventsCtx, timeout) ref, err := src.L1BlockRefByLabel(reqCtx, label) reqCancel() if err != nil { log.Warn("failed to poll L1 block", "label", label, "err", err) } else { - fn(ctx, ref) + fn(eventsCtx, ref) } - case <-ctx.Done(): - return ctx.Err() - case <-quit: + case <-eventsCtx.Done(): return nil } } diff --git a/op-service/eth/id.go b/op-service/eth/id.go index 6a159edf1280..7beeabfe329c 100644 --- a/op-service/eth/id.go +++ b/op-service/eth/id.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" ) type BlockID struct { @@ -21,6 +22,14 @@ func (id BlockID) TerminalString() string { return fmt.Sprintf("%s:%d", id.Hash.TerminalString(), id.Number) } +func ReceiptBlockID(r *types.Receipt) BlockID { + return BlockID{Number: r.BlockNumber.Uint64(), Hash: r.BlockHash} +} + +func HeaderBlockID(h *types.Header) BlockID { + return BlockID{Number: h.Number.Uint64(), Hash: h.Hash()} +} + type L2BlockRef struct { Hash common.Hash `json:"hash"` Number uint64 `json:"number"` @@ -94,3 +103,11 @@ func (id L2BlockRef) ParentID() BlockID { Number: n, } } + +// IndexedBlobHash represents a blob hash that commits to a single blob confirmed in a block. The +// index helps us avoid unnecessary blob to blob hash conversions to find the right content in a +// sidecar. +type IndexedBlobHash struct { + Index uint64 // absolute index in the block, a.k.a. position in sidecar blobs array + Hash common.Hash // hash of the blob, used for consistency checks +} diff --git a/op-service/eth/output.go b/op-service/eth/output.go index 8cadaeb26c1e..516829d93df9 100644 --- a/op-service/eth/output.go +++ b/op-service/eth/output.go @@ -16,6 +16,11 @@ type OutputResponse struct { Status *SyncStatus `json:"syncStatus"` } +type SafeHeadResponse struct { + L1Block BlockID `json:"l1Block"` + SafeHead BlockID `json:"safeHead"` +} + var ( ErrInvalidOutput = errors.New("invalid output") ErrInvalidOutputVersion = errors.New("invalid output version") diff --git a/op-service/eth/ssz.go b/op-service/eth/ssz.go index 80d5041f3be7..1eb31235f625 100644 --- a/op-service/eth/ssz.go +++ b/op-service/eth/ssz.go @@ -8,6 +8,7 @@ import ( "math" "sync" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) @@ -15,45 +16,69 @@ type BlockVersion int const ( // iota is reset to 0 BlockV1 BlockVersion = iota - BlockV2 = iota + BlockV2 + BlockV3 ) -// ExecutionPayload is the only SSZ type we have to marshal/unmarshal, +// ExecutionPayload and ExecutionPayloadEnvelope are the only SSZ types we have to marshal/unmarshal, // so instead of importing a SSZ lib we implement the bare minimum. // This is more efficient than RLP, and matches the L1 consensus-layer encoding of ExecutionPayload. -// All fields (4s are offsets to dynamic data) -const blockV1FixedPart = 32 + 20 + 32 + 32 + 256 + 32 + 8 + 8 + 8 + 8 + 4 + 32 + 32 + 4 +var ( + // The payloads are small enough to read and write at once. + // But this happens often enough that we want to avoid re-allocating buffers for this. + payloadBufPool = sync.Pool{New: func() any { + x := make([]byte, 0, 100_000) + return &x + }} -// V1 + Withdrawals offset -const blockV2FixedPart = blockV1FixedPart + 4 + // ErrExtraDataTooLarge occurs when the ExecutionPayload's ExtraData field + // is too large to be properly represented in SSZ. + ErrExtraDataTooLarge = errors.New("extra data too large") -const withdrawalSize = 8 + 8 + 20 + 8 + ErrBadTransactionOffset = errors.New("transactions offset is smaller than extra data offset, aborting") + ErrBadWithdrawalsOffset = errors.New("withdrawals offset is smaller than transaction offset, aborting") -// MAX_TRANSACTIONS_PER_PAYLOAD in consensus spec -// https://github.com/ethereum/consensus-specs/blob/ef434e87165e9a4c82a99f54ffd4974ae113f732/specs/bellatrix/beacon-chain.md#execution -const maxTransactionsPerPayload = 1 << 20 + ErrMissingData = errors.New("execution payload envelope is missing data") +) + +const ( + // All fields (4s are offsets to dynamic data) + blockV1FixedPart = 32 + 20 + 32 + 32 + 256 + 32 + 8 + 8 + 8 + 8 + 4 + 32 + 32 + 4 + + // V1 + Withdrawals offset + blockV2FixedPart = blockV1FixedPart + 4 -// MAX_WITHDRAWALS_PER_PAYLOAD in consensus spec -// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#execution -const maxWithdrawalsPerPayload = 1 << 4 + // V2 + BlobGasUed + ExcessBlobGas + blockV3FixedPart = blockV2FixedPart + 8 + 8 -// ErrExtraDataTooLarge occurs when the ExecutionPayload's ExtraData field -// is too large to be properly represented in SSZ. -var ErrExtraDataTooLarge = errors.New("extra data too large") + withdrawalSize = 8 + 8 + 20 + 8 -// The payloads are small enough to read and write at once. -// But this happens often enough that we want to avoid re-allocating buffers for this. -var payloadBufPool = sync.Pool{New: func() any { - x := make([]byte, 0, 100_000) - return &x -}} + // MAX_TRANSACTIONS_PER_PAYLOAD in consensus spec + // https://github.com/ethereum/consensus-specs/blob/ef434e87165e9a4c82a99f54ffd4974ae113f732/specs/bellatrix/beacon-chain.md#execution + maxTransactionsPerPayload = 1 << 20 -var ErrBadTransactionOffset = errors.New("transactions offset is smaller than extra data offset, aborting") -var ErrBadWithdrawalsOffset = errors.New("withdrawals offset is smaller than transaction offset, aborting") + // MAX_WITHDRAWALS_PER_PAYLOAD in consensus spec + // https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#execution + maxWithdrawalsPerPayload = 1 << 4 +) + +func (v BlockVersion) HasBlobProperties() bool { + return v == BlockV3 +} + +func (v BlockVersion) HasWithdrawals() bool { + return v == BlockV2 || v == BlockV3 +} + +func (v BlockVersion) HasParentBeaconBlockRoot() bool { + return v == BlockV3 +} func executionPayloadFixedPart(version BlockVersion) uint32 { - if version == BlockV2 { + if version == BlockV3 { + return blockV3FixedPart + } else if version == BlockV2 { return blockV2FixedPart } else { return blockV1FixedPart @@ -61,7 +86,9 @@ func executionPayloadFixedPart(version BlockVersion) uint32 { } func (payload *ExecutionPayload) inferVersion() BlockVersion { - if payload.Withdrawals != nil { + if payload.ExcessBlobGas != nil && payload.BlobGasUsed != nil { + return BlockV3 + } else if payload.Withdrawals != nil { return BlockV2 } else { return BlockV1 @@ -168,10 +195,20 @@ func (payload *ExecutionPayload) MarshalSSZ(w io.Writer) (n int, err error) { if payload.Withdrawals != nil { binary.LittleEndian.PutUint32(buf[offset:offset+4], fixedSize+extraDataSize+transactionSize) offset += 4 + } - if offset != fixedSize { - panic("withdrawals - fixed part size is inconsistent") + if payload.inferVersion() == BlockV3 { + if payload.BlobGasUsed == nil || payload.ExcessBlobGas == nil { + return 0, errors.New("cannot encode ecotone payload without dencun header attributes") } + binary.LittleEndian.PutUint64(buf[offset:offset+8], uint64(*payload.BlobGasUsed)) + offset += 8 + binary.LittleEndian.PutUint64(buf[offset:offset+8], uint64(*payload.ExcessBlobGas)) + offset += 8 + } + + if payload.Withdrawals != nil && offset != fixedSize { + panic("withdrawals - fixed part size is inconsistent") } // dynamic value 1: ExtraData @@ -180,7 +217,7 @@ func (payload *ExecutionPayload) MarshalSSZ(w io.Writer) (n int, err error) { // dynamic value 2: Transactions marshalTransactions(buf[offset:offset+transactionSize], payload.Transactions) offset += transactionSize - // dyanmic value 3: Withdrawals + // dynamic value 3: Withdrawals if payload.Withdrawals != nil { marshalWithdrawals(buf[offset:], *payload.Withdrawals) } @@ -220,7 +257,7 @@ func (payload *ExecutionPayload) UnmarshalSSZ(version BlockVersion, scope uint32 fixedSize := executionPayloadFixedPart(version) if scope < fixedSize { - return fmt.Errorf("scope too small to decode execution payload: %d", scope) + return fmt.Errorf("scope too small to decode execution payload: %d, version is: %v", scope, version) } buf := *payloadBufPool.Get().(*[]byte) @@ -275,15 +312,24 @@ func (payload *ExecutionPayload) UnmarshalSSZ(version BlockVersion, scope uint32 } withdrawalsOffset := scope - if version == BlockV2 { + if version.HasWithdrawals() { withdrawalsOffset = binary.LittleEndian.Uint32(buf[offset : offset+4]) - // No offset increment, due to this being the last field + offset += 4 if withdrawalsOffset < transactionsOffset { return ErrBadWithdrawalsOffset } } + if version == BlockV3 { + blobGasUsed := binary.LittleEndian.Uint64(buf[offset : offset+8]) + payload.BlobGasUsed = (*Uint64Quantity)(&blobGasUsed) + offset += 8 + excessBlobGas := binary.LittleEndian.Uint64(buf[offset : offset+8]) + payload.ExcessBlobGas = (*Uint64Quantity)(&excessBlobGas) + } + _ = offset // for future extensions: we keep the offset accurate for extensions + if transactionsOffset > extraDataOffset+32 || transactionsOffset > scope { return fmt.Errorf("extra-data is too large: %d", transactionsOffset-extraDataOffset) } @@ -298,7 +344,7 @@ func (payload *ExecutionPayload) UnmarshalSSZ(version BlockVersion, scope uint32 } payload.Transactions = txs - if version == BlockV2 { + if version.HasWithdrawals() { if withdrawalsOffset > scope { return fmt.Errorf("withdrawals offset is too large: %d", withdrawalsOffset) } @@ -388,3 +434,48 @@ func unmarshalTransactions(in []byte) (txs []Data, err error) { } return txs, nil } + +// UnmarshalSSZ decodes the ExecutionPayloadEnvelope as SSZ type +func (envelope *ExecutionPayloadEnvelope) UnmarshalSSZ(scope uint32, r io.Reader) error { + if scope < common.HashLength { + return fmt.Errorf("scope too small to decode execution payload envelope: %d", scope) + } + + data := make([]byte, common.HashLength) + n, err := r.Read(data) + if err != nil || n != common.HashLength { + return err + } + + envelope.ParentBeaconBlockRoot = &common.Hash{} + copy(envelope.ParentBeaconBlockRoot[:], data) + + var payload ExecutionPayload + err = payload.UnmarshalSSZ(BlockV3, scope-32, r) + if err != nil { + return err + } + + envelope.ExecutionPayload = &payload + return nil +} + +// MarshalSSZ encodes the ExecutionPayload as SSZ type +func (envelope *ExecutionPayloadEnvelope) MarshalSSZ(w io.Writer) (n int, err error) { + if envelope.ExecutionPayload == nil || envelope.ParentBeaconBlockRoot == nil { + return 0, ErrMissingData + } + + // write parent beacon block root + hashSize, err := w.Write(envelope.ParentBeaconBlockRoot[:]) + if err != nil || hashSize != common.HashLength { + return 0, errors.New("unable to write parent beacon block hash") + } + + payloadSize, err := envelope.ExecutionPayload.MarshalSSZ(w) + if err != nil { + return 0, err + } + + return hashSize + payloadSize, nil +} diff --git a/op-service/eth/ssz_test.go b/op-service/eth/ssz_test.go index 79a4c0288839..fdaded1c19e6 100644 --- a/op-service/eth/ssz_test.go +++ b/op-service/eth/ssz_test.go @@ -3,12 +3,14 @@ package eth import ( "bytes" "encoding/binary" + "errors" "fmt" "math" "testing" "github.com/google/go-cmp/cmp" "github.com/holiman/uint256" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" @@ -65,7 +67,7 @@ func FuzzExecutionPayloadMarshalUnmarshalV1(f *testing.F) { extraData = extraData[:32] } payload.ExtraData = extraData - payload.BaseFeePerGas.SetBytes(data[:32]) + (*uint256.Int)(&payload.BaseFeePerGas).SetBytes(data[:32]) payload.BlockHash = *(*common.Hash)(data[:32]) payload.Transactions = make([]Data, txs) for i := 0; i < int(txs); i++ { @@ -122,7 +124,7 @@ func FuzzExecutionPayloadMarshalUnmarshalV2(f *testing.F) { extraData = extraData[:32] } payload.ExtraData = extraData - payload.BaseFeePerGas.SetBytes(data[:32]) + (*uint256.Int)(&payload.BaseFeePerGas).SetBytes(data[:32]) payload.BlockHash = *(*common.Hash)(data[:32]) payload.Transactions = make([]Data, txs) for i := 0; i < int(txs); i++ { @@ -166,6 +168,78 @@ func FuzzExecutionPayloadMarshalUnmarshalV2(f *testing.F) { }) } +func FuzzExecutionPayloadMarshalUnmarshalV3(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte, a, b, c, d uint64, extraData []byte, txs uint16, txsData []byte, wCount uint16, blobGasUsed, excessBlobGas uint64) { + if len(data) < 32+20+32+32+256+32+32+32 { + return + } + var payload ExecutionPayload + payload.ParentHash = *(*common.Hash)(data[:32]) + data = data[32:] + payload.FeeRecipient = *(*common.Address)(data[:20]) + data = data[20:] + payload.StateRoot = *(*Bytes32)(data[:32]) + data = data[32:] + payload.ReceiptsRoot = *(*Bytes32)(data[:32]) + data = data[32:] + payload.LogsBloom = *(*Bytes256)(data[:256]) + data = data[256:] + payload.PrevRandao = *(*Bytes32)(data[:32]) + data = data[32:] + payload.BlockNumber = Uint64Quantity(a) + payload.GasLimit = Uint64Quantity(a) + payload.GasUsed = Uint64Quantity(a) + payload.Timestamp = Uint64Quantity(a) + payload.BlobGasUsed = (*Uint64Quantity)(&blobGasUsed) + payload.ExcessBlobGas = (*Uint64Quantity)(&excessBlobGas) + if len(extraData) > 32 { + extraData = extraData[:32] + } + payload.ExtraData = extraData + (*uint256.Int)(&payload.BaseFeePerGas).SetBytes(data[:32]) + payload.BlockHash = *(*common.Hash)(data[:32]) + payload.Transactions = make([]Data, txs) + for i := 0; i < int(txs); i++ { + if len(txsData) < 2 { + payload.Transactions[i] = make(Data, 0) + continue + } + txSize := binary.LittleEndian.Uint16(txsData[:2]) + txsData = txsData[2:] + if int(txSize) > len(txsData) { + txSize = uint16(len(txsData)) + } + payload.Transactions[i] = txsData[:txSize] + txsData = txsData[txSize:] + } + + wCount = wCount % maxWithdrawalsPerPayload + withdrawals := make(types.Withdrawals, wCount) + for i := 0; i < int(wCount); i++ { + withdrawals[i] = &types.Withdrawal{ + Index: a, + Validator: b, + Address: common.BytesToAddress(data[:20]), + Amount: c, + } + } + payload.Withdrawals = &withdrawals + + var buf bytes.Buffer + if _, err := payload.MarshalSSZ(&buf); err != nil { + t.Fatalf("failed to marshal ExecutionPayload: %v", err) + } + var roundTripped ExecutionPayload + err := roundTripped.UnmarshalSSZ(BlockV3, uint32(len(buf.Bytes())), bytes.NewReader(buf.Bytes())) + if err != nil { + t.Fatalf("failed to decode previously marshalled payload: %v", err) + } + if diff := cmp.Diff(payload, roundTripped); diff != "" { + t.Fatalf("The data did not round trip correctly:\n%s", diff) + } + }) +} + func FuzzOBP01(f *testing.F) { payload := &ExecutionPayload{ ExtraData: make([]byte, 32), @@ -190,7 +264,7 @@ func FuzzOBP01(f *testing.F) { }) } -// TestOPB01 verifies that the SSZ unmarshaling code +// TestOPB01 verifies that the SSZ unmarshalling code // properly checks for the transactionOffset being larger // than the extraDataOffset. func TestOPB01(t *testing.T) { @@ -245,7 +319,6 @@ func TestOPB04(t *testing.T) { require.Error(t, err) require.Equal(t, ErrExtraDataTooLarge, err) } - } func createPayloadWithWithdrawals(w *types.Withdrawals) *ExecutionPayload { @@ -260,11 +333,11 @@ func createPayloadWithWithdrawals(w *types.Withdrawals) *ExecutionPayload { GasLimit: Uint64Quantity(333), GasUsed: Uint64Quantity(444), Timestamp: Uint64Quantity(555), - ExtraData: common.Hex2Bytes("0x666"), - BaseFeePerGas: *uint256.NewInt(777), + ExtraData: common.FromHex("6666"), + BaseFeePerGas: Uint256Quantity(*uint256.NewInt(777)), BlockHash: common.HexToHash("0x888"), Withdrawals: w, - Transactions: []Data{common.Hex2Bytes("0x999")}, + Transactions: []Data{common.FromHex("9999")}, } } @@ -337,3 +410,74 @@ func TestMarshalUnmarshalWithdrawals(t *testing.T) { }) } } + +func TestMarshalUnmarshalExecutionPayloadEnvelopes(t *testing.T) { + hash := common.HexToHash("0x123") + + zero := uint64(0) + validInput := &ExecutionPayloadEnvelope{ + ParentBeaconBlockRoot: &hash, + ExecutionPayload: createPayloadWithWithdrawals(&types.Withdrawals{}), + } + validInput.ExecutionPayload.ExcessBlobGas = (*Uint64Quantity)(&zero) + validInput.ExecutionPayload.BlobGasUsed = (*Uint64Quantity)(&zero) + + missingHash := &ExecutionPayloadEnvelope{ + ParentBeaconBlockRoot: nil, + ExecutionPayload: createPayloadWithWithdrawals(&types.Withdrawals{}), + } + + missingExecutionPaylaod := &ExecutionPayloadEnvelope{ + ParentBeaconBlockRoot: &hash, + ExecutionPayload: nil, + } + + tests := []struct { + name string + input *ExecutionPayloadEnvelope + err error + }{ + {"ValidInputSucceeds", validInput, nil}, + {"MissingHashFailsToSerialize", missingHash, ErrMissingData}, + {"MissingExecutionDataFailsToSerialize", missingExecutionPaylaod, ErrMissingData}, + } + + for _, test := range tests { + test := test + + t.Run(fmt.Sprintf("TestExecutionPayloadEnvelopeMarshalUnmarshal_%s", test.name), func(t *testing.T) { + hash := common.HexToHash("0x123") + + var buf bytes.Buffer + _, err := test.input.MarshalSSZ(&buf) + + if test.err != nil { + require.ErrorIs(t, err, test.err) + return + } else { + require.NoError(t, err) + } + + data := buf.Bytes() + + output := &ExecutionPayloadEnvelope{} + err = output.UnmarshalSSZ(uint32(len(data)), bytes.NewReader(data)) + + require.NoError(t, err) + + require.NotNil(t, output.ParentBeaconBlockRoot) + assert.Equal(t, hash, *output.ParentBeaconBlockRoot) + + require.NotNil(t, output.ExecutionPayload) + if diff := cmp.Diff(*test.input.ExecutionPayload, *output.ExecutionPayload); diff != "" { + t.Fatalf("The data did not round trip correctly:\n%s", diff) + } + }) + } +} + +func TestFailsToDeserializeTooLittleData(t *testing.T) { + var payload ExecutionPayloadEnvelope + err := payload.UnmarshalSSZ(1, bytes.NewReader([]byte{0x00})) + assert.Equal(t, err, errors.New("scope too small to decode execution payload envelope: 1")) +} diff --git a/op-service/eth/sync_status.go b/op-service/eth/sync_status.go index 74ac24c12cc0..d6ff393a61d7 100644 --- a/op-service/eth/sync_status.go +++ b/op-service/eth/sync_status.go @@ -32,10 +32,6 @@ type SyncStatus struct { // FinalizedL2 points to the L2 block that was derived fully from // finalized L1 information, thus irreversible. FinalizedL2 L2BlockRef `json:"finalized_l2"` - // UnsafeL2SyncTarget points to the first unprocessed unsafe L2 block. - // It may be zeroed if there is no targeted block. - UnsafeL2SyncTarget L2BlockRef `json:"queued_unsafe_l2"` - // EngineSyncTarget points to the L2 block that the execution engine is syncing to. - // If it is ahead from UnsafeL2, the engine is in progress of P2P sync. - EngineSyncTarget L2BlockRef `json:"engine_sync_target"` + // PendingSafeL2 points to the L2 block processed from the batch, but not consolidated to the safe block yet. + PendingSafeL2 L2BlockRef `json:"pending_safe_l2"` } diff --git a/op-service/eth/testdata/eth_v1_beacon_blob_sidecars_7422094_goerli.json b/op-service/eth/testdata/eth_v1_beacon_blob_sidecars_7422094_goerli.json new file mode 100644 index 000000000000..d12f32be7a18 --- /dev/null +++ b/op-service/eth/testdata/eth_v1_beacon_blob_sidecars_7422094_goerli.json @@ -0,0 +1 @@ +{"data":[{"index":"0","blob":"0x001611aa000000000457ff00ff0001feed85761635b18d5c3dad729a4fac046000592ff3bb0758092d90e872b30e7d1cc619e9033bef4172e6fb6ec759a7800b0014148fb1dac497206eb65e923b1ee2fb94a425444dc0bc2f18a5eb9f34a74a0051071f45627d868b3dc2f202a13edc8916ed25e0c66cd7ba29cdbbb43877aa00238a350f0b969d3ee524fcfbb67f8bdf2159f622123a72876b671fe0a78a5b00f0f09dca0347bdc26f09f170403d8bbe8d34b37c94797cbb13b2cc4aed312300e3d266a946a7b810299009959a085d8be34f1f54bbde7c7326445b69467189008ecfd12e18af6d3cb8b0874fadf6ae507003c06f364095dab3011c0f2b5028000faecdb137b2a86b6fa430a08582952af259e4162526310d0ceadf9b747a8c0048c6c81ac522a46e657486705f92ce8bc3b878108c39a928127dc0f2d1254500c970f76bb294c47bed95669ef0edb051e0351b68ecc33bf05b67cacc01377900fcd8079a9f8d4b2c729a13ce4faf699d77752400c77f4402ef51fb54d1385e00b52af5fa562a262be7f1a0df53364b58275520568f207ea3f60a8b3a8fcf61009b3009a3ec482f3ff3892e58b2cfc1279dd0eee672f5db4f2a191c50a032da0030f29753509eeb3fc279fcd13beaba4be00a83fa8bfa9e4bd94db12a5bb87c00c400423cb4f87acc889c1020e71ea27fcb8fb7fd7e80baf221b74fba4ba6b9005a24fa37f13cce94a50ed10e3cc3a17b4a58d1ceafda16c02145d54ed63997009ffa6f6c61e9c3afb8c0ed67e1c8978182de71f4a758226ee02801431ab3fe00a529451c71e478d231af801d2a9e67c47f044755aa909afc7230745e099f4400f68a67228b4adbf822c9e362807a35dcd1a6ca18b6a5e989c8c582ecebf51000be88d36050b2a932c4f1439f0f4a29e0a870f41877cb37c60c1f17c35fe9c3005e72b6ed43cb40c4a7a933acc4d7800f71740cc299b7bad96142bc159c3041003de042891d96a2f2933ced8f703400383149111dbc603db157350f89c22153002efcd191062562a14decab56be2dc270bf78d6941fb324aeda90ee4b963dfb00c1fb9697b0b3ea17a0fbd670691c5fe57a73c2b9348328236f15784bd695c5007172118c9d33b18c4c3690ff6bae86fee4f5d5dfe32ffdd46a85bc8b6188d80016fe24b3a83227664f84b4b259776547186ad7efa242d7b361bc992e283385006b23e2affa3c86b2e7501fdfe1132b9ca162fe647592a5f137aff8f02e97ee00f0214b90a60ed2aea4f7f7778baf511d97c410f188a66810e06999582b650800866f5ca37d0904582388b1c12f1a9f10f6b98ad1f832899a24ad9ecb2cac670043761ff5a8e9500cd5fb0f955016df340fb86b18a2a68762b5f60ce6ddd09700401d384392ab642228555b6d02c01583c036aa524d34e9d05104538aea503e00c11732111f8f6e8e23275a4115eb8849334f5edbfae86bd3b219f356bfb386007c13c54360b9300a8d258e049e7dfd882061342e2997a5386c8c889597bc360074eda705b2bba3d6e14eb29de2404b42b212ff08c382de886e923319f28cfc008b3b6dd4a41f989e5c4257dd27355974e4a44ac7f3144bedf907f50961167d00e0cd9c47c1a1fcd41157207c78a32a38312a4481e5ec1630eff46ffa04bdf20094fd79c73e708c75f1de72a6b2daf77a5fd048e743f7c29551613986c0efc200de28604069817b3369f5290b0d7f0804298cfcc50ab48bbfca7f053e139abb000beef3d6a0393b28c0a2d442722b06a1cb813d72071f285cc9b13762842372004825a05acdcd28f37b6a6f3e79fa1c30fe6301ced84e74b5dc06c42a04774600a506d846bcefb8b854812321af0d1465465754cc2629c114fadc57156a5a1000c81d9b744ea6c87317ad605813e570ba6ab6e32a4d479afbfd22965b654cd900eb36bc1933fc6894401e7c9f89b506a1dbf587bca61c0431417f7a533bcfdd009a4a1c30a3338ba17dd974f9a114862ccdeb088f361ab5ce498c0996998ae600eece027cd433ac1e2e39dc52860919adf4251c086eb03f7ef1c98a69ad75a10088ab417107e5945d9bbe4fce71a46f77e9e575d0a2793965d9e455efb9bc410086b4c64f46d423ef54dbc600be9d7f8d363cadc1f47ca0d39235d125da31d90035a030f9a0969ad4965fdb9772d09bb1ef871264eb091abf25914551aa802500ff0fe0b5453c26bb4f81efa4dcf09a50314d212f61e64cfded1818172c9a4c00d8d3cc288cc56e1721770a4e17dc9afd4bdc61b27e365e63180db9ca724dde00e4616f8568e3771f36ec915f6314d5a2571533bf3b94ee3d3dc2c17b928f2800f8e0f45327588258a001670f5b894415462ab4c6772ae2ddeb0fea6363e0df00e518c504af24493490a12fd705786ca42ea4d1ce7b64957742feabab5f203f0015a5ea7745c20052bdfcea61bd225f4ad3f9b221ae5317ea2bdeeeaed06a870084f6f26090efb21209ec1c4bc704cd7c2e458bc1e7b964dfdfd1a80f96dce700ee1f56384e0d4077b89a5d3fb9159351f0f818fa18171c306a8d7ba61337d60023cf50ea2a9a77763c35712f5dce168e0df3b09941fd214af0ca5bfeb5e6b90009accab253202529bb36f0645fe38f0da7d8b28b54cca201827ae253b711df009a587fb2ce2ada63c1eec587b8412eacca109c096dcd58884a83aecdbe482500217e18b6d4a76f10390b6de4217efa0e77102e7bdc874dc124495803a848c200b80024c1a3cff5c5616a01f9960f7ed8a51fd4cbf022ea34dd064eccab1111003461f6a411a746c8de99e89bd04e3a13d1b76bb0876e1f2a4bd61cdf7543c000e834265caf279892b5c75a2e89667d6d901f90d1e6f06374ff1f1d0e537f85003a0f5754f4dda5ca5bac1762d6d1b2ef3d0399c15a105551bb32dc364b08d4008bb24764f12a73ccdf2042f2336974e76d66b09dd71f00039e9c35b7946aee000c8e2742fe8a191b8b7b4045bd0ae8cd95f3dd780aa8818ecb872b8a6ff135009e1021ed2c76efcd999b59fb51d2ada90f7935facea58b80d39d6dc7f55945001ddd1ebbdcd9fc560c5925744c879bc4968d2952f3cd3aa7fc9def1c90669d002c553378ee62f97a8dd5265393e499feb05aa45479edd018c963b9e36f91bf00db49bdc0c7c9613c53053f5a137a071bec01a99d939567e13b2cf8413dbe3a00f719c3dff8a21c46f955dcddf9c02b5502e6a75b1dccc346817a3744d95c590078db8713799752e253d02d743d22c73b0a84ed278858170e4b08f15db9d0f70024d356c3674e5ee69e04000c6460e7db7d4c82f5f3454f50e3cce0c1574d4200915860d8f2d3851c7aae3c3d0e3be33b6a2c4f7ad66aa0e86db5e47ee32dea0000ca0e2acc5bc579214b55a07172687cb490d251f8d0fb0a41219cf1a7735d004b48a0e0401aefc44bb0bd5c4a46c41b2fe77bb18a633917fccb125579c74900a7029ab196edccc9b8e92d6d0f3a000f3be7fffd2afe75960afe9aa3cb3d930024cf7a75289a37242511805028b4da0243374587cff7c6cacf9fd539c8dde50031c41aadc8adae4896dfdd8f51f53fd2e3e457d353f6e0612718e39daed109003c8ae90c61c378e5edd22a4c9a28c8d4a51a30144a8791e393d925c9487bc2007f8ccd5752081944942f873167b47a7ad659b7e7f8d14e21f7feb5024a02f0000345e51710e68ab03ad0cfeb1e88a5d3738771f5f890035be3269c02ff35ca00ba718ce3c0569413794f7973b0eba06577aa886f7011ffd8e36083f9b60a3700f8325167615ce8a5e9e5e060ce160605cf4dc5d4c07fe9468d3613d91a104000358c9e84912e751ba5756cfb8980b491eb9599b0e34100ca3d43914440fe6f0070fb307613949d4710c96c47a9e27e7b4229991ac2856f0fb41772c395e27800e8dc376c80d81bb09a159d1548608351982eaece197af6bea1715f4bd7bd4c0022e5246bb87492ce733e780710c3da91568224bc28d3ea6f3503a0bacfb5f100af41f7dc1ed1405032fc4156357b3fdaa207854e6edd4e26684c01fa76b5ed003fa381b21c4dedb7c2b43432188e42f3c7143b930b07019fed4ca331dcc54400b7571a31305b4bf803ef5a42939d0a0c75a02f0b6a92b72758dc39f07e310700731d203e01e488a54a7679fb76ce5e85d535ab03e077e397423e5c851d880900c5fdf5f9178589dec52f911224e6bf5a6b44fc2753662f31e0ebf83da835d300c5fb9b0e4ee137ce7e800735cd8785ee765bec60fbfe633815ce9bd7a59987008f8abe6238e55539a80b9dc900c2e0e554dfa744bcceaea7b717c249c5efec00a72c984aa2c47adad4723b27d85f6da2160fc9df4ce199a9300a31f969b20b00b352f5ec2755825668f0db3f5c0a62c056bca9352f330228dcd6fcb57b93ad0084fe778afba9f9299d42da1f73107c5e64ed8280af9132395a6766493a5a2100d38d34f5eb06ac0334faa7e09eb6215494c161655ba81892200b38475faa6300d7c88f1271651ddad0af26f867ef1fcbfccbc9f1e338a4362b759092d06a1e00050e088480c5705f165e311c6a87c3b65de5470ad96b4ce61e171b11dc07d600059be6aac6797aa6fc86ad1810716d49d544ef965073f749d722cd4f22d1ff0037444e4f57dde5ba3388c5a19b9786b97352658bd20e5e269501938723ecd800f43c65bacae6a172d9711abc4ae242c97931d221cd46b704f20c3d506201c80081df8fee57f8e2ec87c087cba4be9d9f23254918f663475d0b00727fab3b7900befe61f19b7833e6911ef2b37fe2852e4cf284a704c352079fdaf052fc2457000f33aec6d6b3c5f6c4b54639c447b9fdbec0b2b75cf2053c01c694ea027b72009bad47bc0b19f5b60000cc268bcbe02585ba8607a2feb27c4f3fe886cdac5f00a7b68170a4a161374d6216f0009119bfa43640722fb70f23f76d905d2f5b1700108151473245b24b7af48db591892ba1327dcfddce5798da4fb19eb6e734e6006fb1c85250a099623e1c6f68f13320ba66e08eb55a78207a27bad1cee4ea4300567487aee701bcad4c9f050389f8cddf8f4fc5998b98baff00c74a8a63375a00bf84c0487aabe3fb8f26503f43d96e0a5cc787d4c207e5ef8506808ef74e4c0055cc9c1cff1d77abc3fa0ea2283d1ec32ec6382afa25913e6bebea4628c3d500d80faf9a2cb9b5a19657c7b2cf037ebd00558dcfb48ab537cd4109ffd356f2006b308150f051344f7b77a3b4b1686f123b7ff6346896ef41996572bebbfc860008e413e0659e84ae1431bcdeadc1007c56da7d81f8d5178ae17d98d1948b4f000cfc8e127079ee7f99cab3cf22d9189c930ed7dcd7eb09ddb10a70046c31bb00a0266c74a1db2640dbb6a2d277eb26465da57e669670214b071590c438149000096ab4bff26d8b093b73252bd90d616fa257cd07e4c446cdd7a18d373e7a3a00237201be2f41a2e3941927cecbcfa01a332152d897800e7c713f235041ef3d00e8fe1275bfe64a922defeba2139ee772cbaac7920c694523e70be01d186de800c33e438d09949ea1f3aeacfb8c2808e95f5af46dba555bba51f529a99c3ad300732566e287d052f45b0073a4812ff4860fc0177ac74099df407b598bc16e88009551095459d52b1bf86c5fa9346add2a9fa0da59e94fd43190bca499de33a800db9ddf6c4e32c9e5162945f4abef0158a9690890469566e9295fd8209f301500ce01ec62fa90f945adf0f0e7b269fef57b61b81888805b2c9909bffde6a2e400ea51bd94e761f84ec649837ccb2877d6e0e3506095b8b9bcc7a56319c9ed2d00a0b39147f7063149f654e897568c7738d924ddf663e80af6661d81f6da09ec004365bf7732e2cfcb3fdf05de10dc2b98023c1b9f8d01cc98bd6bd9f4ebc10b007c09cd8da76ae66408364c76f3ada5f6fad5009ee4ab394d6e7f6a5c8293570022494613bd27829ca96d8a4ec6bc00ad5209726f2015f30fa13329003b60ee002117a1fcb7f9b4b5d0232a93672ccabfe1137c92ac111d896809fa60b3afe000a209d004eb863aaa89fea457c9179de2abc9d78802ba3e038d2d3e26de3e8d003ad22eefc780f751d06e9bbce0beef268bbcdf01df24181f50f844b533c28800817bbef1bd67f159be50746e1c86594fb112ef32d81b6d11e612c335329e4d00c24c59e689f9257d0254c33ce1de4a27d551e2d1653f3b7b4bf742306362790028d8003a7904dad1821c1a6c0403f2a900c4103d09a37505b52bbb62bc39d100e00fb973b722ae5db0a893f5120f9bc352bac1081ed802dbd814ca5f456b8c00e64305630ff8e48644e4a263cfa30b64e75c06e5fc05425cb4a678bcae898c00428b29f35372d7f92187f32bde9a795f4cc292a068acbd054b32de98f5e096004c25838e32148524d5fb59ac5852827c898b4ff2d7e3e823fa9ec34d394f19005cd50dec8fffefb6b057d6a128871ae4894a45ed4ab53e7fcd825921a4040a00e57acfac6129e7a8f1d4ce39a8e813270479d0f02ded29c159f3ffaddf1b8900f480c0e396e723f7d8a311ee7173ccda069cfd38ba6475ea616b9acd492e8a00fda1990da1c49840c63a4d9647f1c4114ca001f9ac645808f2296f50cde1b100ffd8830d64b9ee56bb95901ec628a93014433addd43778e34b63986c953667006e53011e09a838aa54cb9d4d181ad6ffe4bc0b54ad015a00fa09de861173f8000fd0f6dbce027b5c8ebf46d7c48e7aad857ca119f10259c720dffff1bfb4780054d214b3e36b4e1b72325d9c145203852535e7c56694d0a93a469399414e5d001da45a221431e0f9c3db70f91ae1a9e278949f0955e25e3054ae7a439ec679003db321e04742bf70fef6a5e7fcc5253aa18babbf30e8388fa2dc0051236eec00d4267104543af93829d531586c0ad42a15b384333911d01be65f963589fa85000728f781cd4fa5b842f9a1202d899b87271a6f79a1310ca637d08a32efc1270099e990a5d8146cbcfd4e545511f0e1700d6bf1b5b9ecbed30eddca39fa9dcd005bcee6faa87335493b88ac1010714509b576bf4fe50294e05543684839b7070054c9e50ed25d88e6a082e1f5fd2e326807f33ddd4642f6ad1d3e102f1ce297009d17cce0bd8869e965c2f9764ecd2fd021aa67c455babc04c6e5ff0628509c0001b3179317d031fa23771b0f93a7c061b539fce166551ed641e91f9571260b005d764b0bf102fbc1ea6f343f17dc5c1a5d0563c8d268020806a7807f9ba0ac00bd189223c207d0d8423a147595398f5f60a747c95a1b2430d4989f8426018400b8d0bb6212214db6bc10c7a49d7cb6401eb3e76cb38c1e98b67132a196693d006932447a3a618ad236cb675a7c5bdd7caf55e892a68d0b681153c3923cc35900b8242a94819b2ae0b894e1eb9f863be49d479c3a3e7676328928f2c73f0dbf00658f3b00604a2a93ad76451df0dd7f0f31ccae696c5786377ccb54ceeaae700035b706fe82ece95d51c644377c03353b093cff0c737f349963f6625e81058c00ceb3152b92ecdd99069592c31405fd7378fc6e1736b99fa324f241e55a05c900963ad3a84796393d1f50ffd60ca07c2afd706bd5c9f25f31b36608954c5aa7003ad49a2488babe2753f7baa8f010a30421a355d5b8d29418e1ccb37c3c05f600b2fcdc633466dd807a97c90b2019e1a8d37321a4b02de05ecdbcb057e7705e00576639f0e931a02977b2c2038173a30a0a03922711c3def008c1d0d63b723a00540d1d28f83b04b440f408622089e0c998c8b867cc16e7b3f92682958c5fbd00831bac1614e8349168d59c90a5f970306327193656c1770dcd26eb20ed9a3500a63ba0895755f5802a23f51afcd0ebe80f9aafd24fa267b710b114de497920006f45b311f84105f877ad377deb18db71e8d3cd52a9a0365efe758df1c32036008879a48eba5780c89f2c058715e1dd153f1aceb63f9fd728622543ec1147ba00ae0aca46112a6ca46dfec5521c166619ea97e31f2fca72642e0f4a4868f13b00d30810ede75fdb529b501a90bfcfa756179194c08c08d1e0904d383e2fff69007a0635509c4ce17c6bf458f0edf52a899053b4bf9a52d0319c606d90a3c9520059e3d6a0e6fa947c548a38a77bef3adc5ea81b60d0728e9eaf887c2fe3c40700a241f24acb24301d28b4c36f959dffadacabc0f86ba608cb7f4edabd926c0a00123670aca462c7f03994a039c0e14f473c933cc372a8f7f6a12bef296f693400c19151d404f2e8ae46467fe154564aac8fead5694ed3111edb0f3a46f63406005990a8411682f53b1c8adbf4384b8885f06400186b7bca471a86c4389066ca00e560f0e3c9e9a0ddf04b192fefb68a35d4b6033f68047015dad4bb43efab51007e74f30c4089f613cb9058623c6f682ad83ace064bcb450a661d04f6b9c1c5002ad1d37463265e0570b7200dfd2a62688a37cc4502dbe1998d23071e3435dd00fad341c54c69f208ac7c8f0ef178fb1a0bbdc86a1e2b1da2f56933b6fa4d2c0049eabe0a1d0b7fc5e69fffd3109132cd3cd4100d9b508caa4216bd64a012f30056968baace2aeec02d66334417ad33813123cbc3072f7c0499193a84da6a49001e03c8fbc99e97f875b60f63362fb9486def2f70bd85c4084a773628beae65003830f46a7f74bf7aa242a4eb8f16fc21bb048dcf5dda4fd026eb66a40cfeb60041000369aa88f556bcf742f9f9588475bf6f4f4f362758c08c0f1a66c2a1c500526e13a444f565ef5fb34ff8d05695b0696055ec32626f38d8a84c51b24a52006ba32ea1bae7513a8a3a180311679499ffbba568f89ca8ca97dfef8144e90700817e3c6b648b9b4f48fef6a578cdfd54cef60500e11b801e53f48421534da700e27f2f5a9b2ee3b2ad0ba3f8e24d3bea59d40a084eb3f49e52cdc120a7abd4000c9fdb41705e8ee08e723f0b33623574fb4f5eec9ce2919a282dbd1d0db2970064c192aa1af7952c82280b1caf5557858559ac03d865c4e38d0b1ad10f24f200b3b229794d20cf57040b8eb3dcff8bc1581446c6d42ceb5f5ea38edae3fd0400f0fb6e014b8c7ff5bfbbed87a98084c1ef6bf6f8f2b85644398ad031c60908001b5135495c53b5fded2d098abbae43c3e472e57fb8064b5082e1560b757e8400bdba07e8655ebf020c970e25d862a91b05fe64f60327bd797360c1f04496a40008aa6f89ad5b85565007dcbdc4d678598eb1ec2047495d16e373c1c2bbf7ae00e8c74fd40447e3a14227e95efe5b8d6e518fc24183292596ce00400290d07400acae6086dc13b5fa9b351bcc029efaf7798036595b32b54a1923c961cb80ce00a089b473fadce897758a13e86f3faaa4042ed9e23162d2cc596f49ae7c4362009f310678441fe9e5e6dd7c8c8a61db57cd96893f3986dcf11fff9cecb7404f008b31273323125916dd13ef1d93e4a1e31f350d96779b5f66193a1f0ba7cdf1006997993963d10d475c1b2b470a9dbb479d97a16a9dd5f6aa5e662c4872580100ac3e34b32e6c2572cc3ef1102e987f17406d42b411ae4280048bc66ea13438000fc5efa222e53ba8c2b836ad0666a15a2189ad5637d49643ea4ea24abdf0a60058c646f4e51f1d503ffa38e7e97f37ea9872b2f0cab9e2bae24a8088752928006b7df72b8531ad633d80f4c9136aacef30b823335fa3246fafa7d332054e9700782d6a3e4fb6296362783613bbc8569fcb4b798a01153fe308b9be6c44434b001fc4ae1a555c397ec080584c0f4c56cabbcc07e7eb3148dc0c898c5f5ab968002ed32da96626aad951df3babf0cb3b6ee30635061ed016e9e2c2696376169e00b7df980b65dac4eed59fe7ef0e18a5df69271c9a6b1c50c93308194424ed80005002f0c25e17ba91019f1f5a6769ae68910049c620ba00d03e202222eb04ad008e2d7d22c81a42394125bc32cb92d3955f258618228dba0360fbd26a3c8bd50091d2010bd2adc0a24840df5e25d6c996bea18cfa6e0784ff405ff7c67c3376002bf1b23c66bed62478989478edcb0c613c0f17d9a7853387bbea7a7e867fcf00e2ceed49816fa95ce5c75303a9da8877f4dc5d0039f7621c24929c8a074cb7005fc358b4113144f2fd7dbbf84cc9e0dc3b5c90862e2c7a8d0bd671927173f50039ce087dad6170652fe32945a9bc442ab5fea92574e9b8f059e42bf90162dc00b7dad489959660238cd2c3d048a5f56352483d95992e1bf0137e6d83b24ac7005b675fe788e1343ed2dcb2bdf9931c67f4d0ffc44cd5f455e99d9651f41210008ca023880c8a3690c1a206a794ce308fdca6d6f1b259fa7b679eaa1d1dd74e00bcc7876e2850c843c8dffdad4f6f0f2b94dbd49c20dc3cf25bcde38adf97760001068b88e61dc15d2ebb75da00659a877681edbc4aefee1a9644aad0f933bc00d8d1194dca3a1b74c1a2d1775c5dc143be0b7333acd207bef0f499250a62540053f2f76e517544886fc5532781782853380cf1f3d58f22bbae6a2ae95455e0002dba22446ac5c5ec209c7a21fcf1b3b6dfc029a30eaaf2c58a2500fb96da9a00f088550c4994b25c44001bbd8409df908f19f5b3e11180793ae52e3460560700c9776d9733a321bbf55358d01894528092bddbd7027318bbde8c00bfb04c87001bf2181a44fbf19a18cdaf3935221868594392a5ef06a62293a094dd5ea4e1000de7fc5416a4da67ecdcdfc63edf6ea3fe6e0fffe251cad712eaaa6ed7711f00e1fd330aa3f28e645c13c622fdbfdd2f9014bb7b7397143527697f2cfd62b100b701f7c2d61355c76bd7794e7615e1c2d8ea27d28d439b576ab64b8ca52d4c00322bee5e038eb779dd15877b36d28d65a1780b639403cdc49ca54a8bc8f153007f8402d11f922f82b8c61df54b87aeb71550ded549134560667d9a29f96a4300edb46a6904bd769fd905e749213f1a9b7dfd2e928fc6516aef341f41768a88007870c942b0e726569c3a11469a3d6361b4e9568cddbbf112881ca939d4a25700378d72ea52d2fcf5b6201471c3f2208fb00238e682992088fd80f9a6daab4600beda643cc599464b395d9d6df8d3885aa212a5512a97408b47f491e167ec9a002d66059fb58ee3410ca2174b82cde3bd6c3f06aa5a54940ee88e1cdf20bd5600ff92e91365803ea9d21e1858bf0c1cdcf3607604d8d9e3b826b686c3a8c8b2005edecdf1f0b7a6fc8521ed45f8231e9cc22a488a96282a0558ef5ac7419185007e4e29b1f485b134e5bfaa26048c6d80802d04c05419219be805e5a84b338200e2d2c7ff35abae4c02719d47b7d3cb4f2d7f8053166027e4d1eb3f8734b934007cfc605aa84eaa9570e4afb022b3521de9382128c617a14d6e4c65639abe0d00d28a61c75b9ea5b896825d35f3c6389d792644733b1653ea456c28da8be5af009e9a5d2c9fc4602f18cc7a2bf2665547ba8cc45b67d0464500fcbd8e7296240013609925c34a517dc3426be9ab6711e58ab72fe9cb31ea202edc802659275d00d82aee932d193be6595c4ac260882c00f23ea820c34e1d8f368cfff6f44dea00e6619d3f0b0dda2921fc65f67131df0dd3f82f22ffca09d54d624c680094810098b7051df0c80644ad682b69cf8935af430028c089e5d2539d3adc94bad76f001823a547348626f8e0b5cc55ec200d3707f0be843706eef30e458a0d94781f007135cd83bab9015e1179925a59dd5783de002349e5a0ce0dee9bd2f12c0b710044d2257ebc2a1b568314e3d254918bd43acb4a3aff1a3bc88a0d7a9a08568900f2a0378e204ece0a7c5b901d9048e890e4e6f43ef90f5b9c2c70d6b9e17cb80001ee26cf48f96155f4bb7d7d05f63d6b875d17cd0143ed507822b37d398f1900b7eb7c72aee7744e20bcc784a06dfd0ff814dfa70a3c364ea3746469549e17000abc2ffd0e3c58ca4d462e253e91c13473ec2c42727253c5ac7647fe50253b0029e69d60c8e7a5f4015f31b3af5537bfe475cc299608d8b334f1eca922e94a0082bc84a499b0d04df3ed31f958aa6b0477ef12d8a4d11f29f5ca231d1bd98900a3ff14d665e5a4a175f5324a5eb3e4e16677bda4514864392a6e536d3e2e8000dac21443d5ccf3bae40b93768713452696a64375f1e373ff88f8941262e5e0004f60d8fcb393c5e599be96e8b6a63eac3e388ef7a8ef76017097d9fd3f58dc0084bbaa693d7291b15e2caeb6ef6a34fcb2a0d8aa5bb3234a0b5628b1b9ec1600df74b2f76cf6f0e305eb453ccc7f98833a13d642669419b56fcef3024cb49600320e013a2ff1b09b473858d2f7c7c0aa7afdedda5d05413171ebbde6eb5c810000cb5d26b3e2544d64c0a95ba42fb2e19a22681379670b9aac458a56183a7300820d5406ee0154218a628fa6efc01359241b302cd8917341e7aee357b7612200fd362978630217a7fa55fd49f7bbec459e9c1a4607cb5d9f71ea1f82f88f8a00fcdce54c2119222a30b3d1c80082cdb4bc924b5c24aab9d5b5be2859d77ee7000f8d4e4998c2eeab5ac275ec0719f55d50448be6c5f36ab7c0f558b41755200017b08e866910b546a3797fe0dcc8764d6d681bebc437a5518b541c0aa185ef0058e7a69e95ff97e3217011dc5fb6e8af45481b126fea54769e413e444ee8e90070e3126dd725edf18fd06fdd193f55b6655cf7d8be19fe5135f86ca14203c000df1a49a58b0d6a76dbf51d781117cabc77ddba9af9d3a153e70dbf7c52ad72003cb241f59f7506d0e4fd90df3319f10b744af62fff263100ff0d15f3436a0b0016fa89299826eb118f5a792d3f4e1c125ed12b72e96ecd4f49b352cca0a2f0000e386f71ec3369d350f1b005c9a3233066981e631f0fac7c2abbda98d176b6001f0c3aca5eafb1bdd59fb7523f7916d00146661c861ef19665e5b5291f84cf006668851c8b4c04e5466e9b203b1fc1ca38de4d52979243cf47f62833cfa56c0086cdc3cc597c758b1479765690c3a5ebc3373ff4407e72dcb859b9a572babb00631afe2d01a734e7225a4904546de51918c09f42baa1d7c464a6611d8877be00cdf59e4fb91045c5de193d6df996d82ca6248192e8493ff2d3457b3bb3ea1f004946e3005ca3eceb9123a3d29a004d1f4ebf77a5faf8a05ee6e74c92ec752b0020f11b576c5d6725a707a4e0cf30901df63df48d01dbbeb93204b8a08936cd0081f47a64c8782287ca48a46f2abb32548ed3b7a4d2743724bcc528abf6a15000b1ed688fb165e56827e6f89aa97f359a114922ab8867749d51a6d8438d9d7d0063782cc373c9f8671fb7b097a5df2a27956e08501ea4d3526924a2bf3336fe000aeadcdd38c088c52030c6e0924fc948b85a48328371c7032c6d32f4dd33310029cdf9f223557203016b399632841c0038ad699dd06871b78cb3f39deef87000e758a4dfb896c406732593fa8d11ff296e183b78e2999533b8707a442280760032fe4001b02d9dc4b045100324ed2bff8b24ab227d70fe4e57c59960fc306c0058e68d7f820c78dcfd55f4e6be073bc6b397f4a77f8cc3514d3819699e227800809aef2d998bd62458e7b01e61451ec70e71f64904ed9c94082f132694d3e20038fd5306a47e57340d3bd39c22ebb180d944ef46f895018de10721a22af88d00005c7b8ce7204bbc51dede9af5aaaccd7d04fb55778333ce81142f4f22bbac0031133ad3a00a741a9d3a14c3e17d3310c14b718af6aa08c6628fbe28e844f0002bd1f28a5e672e7fd25220e2ef8a81145c1d17d2419807bf6e1478fe5e347d00eb47061bc2b3c6163e6c02deb21ae8deeb1cf3568fc4b8247077109f5b9c490099bbec94cace8b796d3d5238ed44912e60593d804c05cdbd0939d9b80d52560059356eee908dc0fb364f4b38c00f9ee3bd8904916674fdb9cac1a4bc70786f00e58a38b301c2bf2d1387d27acbf6908a07a0cd19361f1d723e5f4190db41e400dec8f38f0c05374898b4f91e0761c337c4968a1aabef2822c011dc9bfc38b90079072855b1bd2afb0e308367957fe366baf7e9354bb11ff9b717fcbea0972300ca35b8645596b43f9a9012c4a544138d2e5ceb38a49b4c019d6b959ac43e5c006510d54b2ea5ecdb7a8599ae3dd55b18c2d1c5826385b1991c629cbbc50cab0053ab3b658438ebed42803b7f853f8427726b46ff488d1807aaacb3b186781900d1ff42323353384a86d05dee6cb727956c5ab34e607ba8cddc028f6d7710440014b6b626e86ca7b65e230c97edc3ff9afa328578b95b6cdfc3a4c33132ae6200b7624a2b03b14d11f7846eaf0c02978ab8bd8e8c9924d9ce1af47ebe040b8b00f9bfd94c43c8f24501d992498cf39a8ed94226e4d8c53742a481f1a40c125f0005a7d30c6d5cf71fc5dcc190dc1a7ce969c4a01f85f7019e13018fd43b29eb007e40e25203bfb11077d1207cdf8db39140c9ec988280d72649e306b6b6e00400b66af22812ac9e6037f26bba9252b718ba0f21855bd06fb6d956d1c6c208eb00a1fe8350bb20f93e806a643fc70cfb7ef1cfa487ebbdd925e13d0d8ee90be100b9f11d7e7a9903acb8039d733dde576cafa339dadf61f9052bc81944cb4dd3005fd45df5d03362c810b0295de5565c0be7a4c472afda6547556fe755aaf92800cb692d7af3f493fbe4775a7be82865121c83157465c4fffd758d52416fb8180053f15d40e20f3c404cb113da0ebe86fd293ed3456e5814bfdfc7107620f07f001887f0e95870b392a67597bf829db8a3533487079ab816b1d7fce7a2b6bf6c00a5412fc93839b240ab333dbca32f2a3ed890f062e49c5aad40c19a8629fadf00b19371dba0d493123ac4ebf7eb850f30905572f262c9e4c0596adaeb39da9c00e661a4eda8716f0d25715414e0cd6d3dab4e54d1ad4427452dc377d4c8553700c860c3d166edb77e3f6c7a6f17dff5c084de32ac303242c7e2f38af10ac0d400fdb2fe511fd83063d7030414f28ef38289fab6b8d4a9cf2f68155a9165098f0066c3eb7751d959b35d462e2e8f32e6641420645094c5e3d717cd7894e6b439001eaf3cdc7ef2907650adb7b53957293da4563dc7c3bad452c37b6d82689c03007a14fc3c80fea87ad017f10c00168f7aa74eb03b292257e66697e71fa421dd008dfac8094c0a24a0bdcbbe4ba79ec55659efae6a3bb252444d9e08a099862d00fc4166f08b4f813a3275a5c25f071eda076f235dbd4abccef8be965276b7c000cebf636028424eb409a925ae192a89c37b5c6aa7910d0438e5f1d2208bebd9009ba12f97d99be873806f924d90bad27753ccfa729f273258d6e487cd56952b004d9bd187113fd0a1a5b989a4387c53e885cbe9fcdc56bf28b73a2bf76b8d3800454a88706c9339156d5520af1452b72f560b94e8d013ff9b28500952f7aa6400ad37852127b7e916fd426a0a126052d485eb1b557242c5d51d168231689bc800d943a404f25e17a5c16d62ebd4da9e749dec100dd7ad93159607bf97846b6800fd587881475678df649fabbe41e07d580a1ad6d617dd98d169c5160ba9103800afc9da75b00916bb59be68091a806f8c4df4cc5ad31b1751078372b383d700001c70e09b93dc7863c8147bb6efb2e2b5c1de3750f583035b174cc2b9c1e0c30003182a166f1b9a72433993d4527727acc7ade34a1d28cec837c8aa1b8008860052c8e0dc42697b04d7b7c128b95428c240c9da50939a4db62e9849b38955ca001cbca20438ff7280625e8d30c18b7a88441089a5016782019be7fac687f331008400e65481b531f709afc6e7417d194c356a8da9b22eb1d8f7049bdc0e7206000250ac00c1d52e23d844f92ade54accf6070271bc8ab5d2d667cae397975780034ae923d3f5db4077cc2c1d9aad535e0cae1dc7d3b9cc74c24de452eb5d6ce00b0cca6eab2c6acf7c561306d8e7cf6a6634149ba56b8e724ea7d9dfd5a064d00efc23fa8fe75e32b87bf3c364ded4ef7b4e5d9810a0afdf5b2806a9c7c570b00f9d13d7eae2d9a0c48b091277e3edd5cd9df79758f23dda4858f373ed5891e0049551c2c5466ed5f15c2e3308f8e60732f4151a2564f8d506fa43097e719b4000d04663833ede8a8da8ff3a7e26113c08bb272ef4787d209006994d99f7e5f00585971e73a1a60827bf5e555f9b4f1aac9a350aeca6d314e8f8ed1932195240070d3fe73908a537a3da2dfe82516e6a51ec2d1a7cc0d251634dca687f945650020a8c064633d20745731fa9f592f0a8d7cd9653ae4b1a1a62592ddc06c3b600062acbf30376cd51d94b228e3401fce31c9b820348fb51ee8ec551b59319a6b0090f3878ab72c39629d62ec7b7ac9859e6bfdc822121f12956515892d9556090053d43d89630780b21f84f767eb54c401f59d2edc2281dd1e1f504ef458f15c00aee1e098aaab02288367eda9f7fe04920d3a47021cdb5935b3c58150e9c0ab00d86de7a4eb31a6d61ec9d0e0228e07dff9004db5cca0114581e43e4f5f0e5e00124069422570e2ccc599882b50fba5aca335e6dded6a37c89dcbaf3cc6bc4900b994103285f9e4743f1f6d811570e663fcbad49b8906532485f3e7101156b7009a63948787bee4b16fe6369bcd4fa6eb96ed58df6fd1005b8b349b88d9df1400db1e10d035c570751dac6fa997841178dc518390d53de5368fc3a0dd29100a008b1d41d70935e03f024f6d75fb59aad92bbe515a3bd12ee1dfdc27ab70082b00a08c8ac84d54f19922326d7858cb2fa6aca6294ea696d0a71c45028a4453e2007401cdfdb8359f99222d29802a94ada048b57a8dd252909a54bb4c6e589cd3009a298604359ce42c3ffc7d279ca25cd2daec3512d8da153bee9d1979addeac000009a3ec6d3aa0ff3b12f73b63b5744ecab9e4c76427ca3d5730951055e72f000c6437d95345c5afd1a0ab3087554acb59479e3f102027c31c49cb5b2dca9000677a2671ca4996c47f0a925c22536897511c52f761e92cfb755c9eae59e5e500f032e83267c92c1bfef02fbfb09dab7bdaba3b84cea6f36bcaf3b37fb40f1d0006c99d758bb68e2b77ea905d16c7cd6d8e61369579f0036ee38b9814df931e00c9dd14faa40938255cc438fd7b94cd4e4445f2dcbe271e350ecb5de662cf8c000667fff2434668800c2240d998f33fb916ae48423ab942c5cecf41b16474140091b9ce1255dead52930c32da8302eca311552e8791a045071b291c7bb894bc005338170c0aa0e1e18a3c1d8c129c07065be01e138b882ce9033b0ba9e4ee62005f9d61d3f35cb5b58573749122349bd925fb3c735fc2ccc2abc4c96ef92a810096609ee63284247a79f9425a9d66d2ead8b17452f5d73308bfd8240f87c47200c112a5980feb9624504b48aaab7a0c1a39977b9659310f128525a29f9adad80021bdf148f7ff01f268c8a125a765d16c53c5ae0a1e40f94604daf0794882ec00435d4a08a1bc3824a7b528f467d9889f7f74df12eb38a7e3b8f1d09b5ab17600fcd2bf8d247428d09e77b63502e4bc91f58f0d04b211b57e1efec4f123ba6e009417321ebed2b77b265b258f7786357c2727880e87772721492d8f3becdc8c009e3ffe9913da46d5d5885b37c6d5aaaac1de3ba5c644e66e5337d27c050da5008028f2080c46bc84c9fbb2b3fca8a0789c65955af4a6d7dcc2fbf53454221000a4b357232beb3c6b5650686a0adb7425ca913cecafd8d4220fcec09fceb30300bb203f3475c16654856cbb7c19eba2c293f1e24ce5929ebb7751d2d664ae5f00f1b25f75a5ebab759d5b2656e7bfaaca2ad0bb5c773b8ee8142318bef455170097dc8c1d938333f26e5a9d6c8f311118b039496ef6460a6a47fe0cc9959a6f00354be1bb1053bac919397feb9eee8700a477be01d4c72bca7cc3efaffb4e860065fc7e8a5b2f7cf6393df7feda6575b49375189cc33b54fc77f385e345515a00b6f5604f25644f748c70b44eceac9fc022e005b18e933cf2f11d834d8d792a007e9b801f17a1c0ceb4f0d7e3114693c6ccec2e4921f5de12a36f05c3b2146c0088d8896cff8a723d5c536831183700248e98eedf9547a672c1b72cfdedbbbb00892afc30028750fe97804185a3e957c04b2ddfe006dca8cd26d12b4af80e8900c7d2a41fe33700258ec5469acc0caa7b4543b38be0df8325d82983356e1b900079f67179330e441dc21d48bfbce28a8932f40241f6fe4e2de7cb42fa8adc200034752452a4a16ad7c5500960d3edf7004f3c3695220875e158688ee065927700f047aca7672d126b69264ab3b2c8a7c936c462daccc4d255982cce0de90391005ebdcf9203a274f964ef1bf4e14f1583b368b3484345fe2a867caa55c2cefd00987351d3dccc17f3b04adb125399cbcdb00e559c69ce0c629bc8364ec7bd3500c22a352edbb231fd7b8dea7bc28436cc1cad635f340fdc7a801f5b778c594c00502a059c72d7f20dd1a23c73c97b2de23c25158a95ef293e9fd1256f833629004bfa27bfa8db481cc0a89eeb18cb039f412ee0da2e5c6fbb51281aae15745700d2fc45d974f2a449baf9360d30dca4c24b32359114c33bab2ffc5b1657009800bcf993f3a29955af4d225d86676de2c8e3ff08849a70cae91a78fa23e4d2d000155d0a1472dc37b5f8355aa938804db34c23883a233fcc3f1fa1732ccb673f008ed4bf0b3f5c40a25c035907712815d58f2715ed355d3cdf6e9855e9597f2b00e6fe9046fdf63c7ea367675001b5d17688ee0e8c068652941615f6ccc9cc8f006e48ce0b29a07afe2280e471cb6ec710b5cbfaffbb35a3ec085957b6b4453900ba65d4396bd4ee7f9cc5dfaddcd6551f205dc92c765a4b19e919d8a572a3700090d32911bfa0e0b5690f050af0a72ad3b7cac522058da83e9805f85e09e50b0029cc50d5d2de21087652849ee506d163b65f9c5b27877ba00a2f220cd8b9d000f9780564c3f7628ee73a5693c2cdb4dfe95b1e9389c04d418b06fd962b9e99002982cc6ee068f71fffc1ed0bc17f900ba52463d6f07a072b972b28e5bbbce40062b4e2fb9a811ba48216fba03ecceb7d6a54f448b9756cede639a5b0fb960c0065ba304b516972c644a02808e68551fffbc91d67d6ffa8fc19c7a1604be60e00375e5ad271149c48728e7130ee5144e51ed2a1d6bb4f589c5cb744358290940076c7c209ebb4faceed7c53ce728d278938dee86401a6bdfa3ea4a9a643d88b000bad27e05be6e5a69e5a64c2491e725658242f535a1a21880a61359e36e2f70031a98d0605d792ccfb5a63b5eba51018499fefe99bfe118c47082eed27117300a35581f626506dd003032c12cc4e98b806d001e8aaa2f12c391bdeee295d0d00f6b394ffeea03bcbf5139982457da1b2fbec098b60cf46b7b797b6ad5f0087004bf361c191e82b2e8a9994c9989a80bf4d10c9b742e7d6acc74fc49e2295e90027b1b4d630dab74461e85d67109b3138c73f6cb15fa80d8897a229bfcad9ff0092447f6fd3e7e11026a498b4c86f3d1b06f8e5f66189ec1081d38439e85662001e126ba8d797f9ea675f21c76274779a9b2c917d1b0e9df0774259eefa99a9007da9a575439c85e39882286b7d55d0f127d3dca3216298bff1a2cb8c4768bc0029a5ec1f97dde9c75c3989f58024734d0fd17fa96c3cfe3d56abb4f135723c003d47c7acd8fb6ceee9a450732d3650195f552e9838381beab660c9b6fbf75000e9ff56daab314dfde941e31fe7c8d7b1a4de22e2263b45f6ca28de69fda51900460794e93ffb3bd9eed25c81e35e9eccf57ba1ab6809998f8c8ac6da4670d800eb4959c6489656e202f67a5ea8f7963e5533126e07f8f0e0efa63cd9b49f85003d1eba20d79baecf66da5ac263235d9862597b0ea4748b3dba192273446b8700a1136f8acbc169c51224c19ad90aba1180e19f5df0e263a95916e5de5606dd00ca6df44d86b1d0f13e708b36b29f7d3b9c97f0d6f4f6b5c35bc3fe87c54ebe008f6d194943de156f597ce2644930e90aa0e845073c47c9b10718e009c54cfd0029c6bc9322ce613772ebb8bf8497b19e280f8eb898f9f420a7ff939cba22bc00ad4fc8162d23a33aa3c43fb4dbee94fd55d3b85ffb05af7f3cadb3252a2137006bafd7cf130265c95d95cabee4f0475a09db1e88d1b1d72f24b4aefbb039e200603cb2ed88e6b83f031eddb6ef587eeabdb7b20e215f92db75eee1c32420eb00f598462a31cbeb0b2c5038a31331d36c88669489bff6c14d10dc96aea1eb7200de554f1d92af70b395d9419d12a6e90f46126f566c873813fe60d60eff0066004dd784bd3d9f7a6eb1a71bdbddb9aac06cbf40678a0c17afa967ac852bc6690091dc5ab4f70888eb7d9d0c99f33335aae48cfc5f0c6c74d429e585d0c3fbff006e0163cc64e0b975833ac46cce7ccd391cae447b9684748fa1ff6cb5455e5600b85afb45875523d75bb78617ab250c0d051bc08bfb9cadbbfb06ae24524ccb0002a367ba9c017a22d107849e2b816c84a615a4e219b0e72b4fe4d9d4fcab0c00ae43eedc657c190d0865d79dd63d4186159f87c2337de46c0d00027ce0a2c70098421a701cf4c07665d705e111c18ba8da51ef9920f9d17a648ba33ddc385300ca9c1e67a3001393201c9286d15953195ba227acdde5f42936edb9c6e3ea18004c742c7f12eb3894f515d4f29681e1faf7fa02ab470f6bcee01779b8fc0e00000e9130c49e5ae196691f85900eefeec58a1411fbafbb39543a24cbf219333000935a2e1ffc6501f1abf8f620e2538c649c90362ff3f5eb6a50a6d700fba84a0084ddfc3c4eb4e1fc3ed5f1dae03a639d861aeb2ce7020ee4af8b02310957f00098fc8aac1d523a2c1ff3e8bfbf0370515f6de80a4eb7bee413d755b6aea52c00a49969bc960f11788bab0d24827c160ea325efc14545d8076491b04a2d96c700cefd8a3e545724603458f5de229be34a52752e3f1343cca54e12a08f3b95ce003f46bafbe1b28ae387753023aa40fa0fde5bafb1a6f6b212f34ce8993e43480038bcc33fea8cf01df5a78a7bae2b2a36b03c8c052fbe78bf6030edbef0200a002d92652a60050f1e8d5a5e146423fca044df89c40c857f122c0461a3efb2b9001254b3476dc5f4ad1ee49c438328385b52dc62092a90ff37771b11b94152a800b2a22d6e11081cb184145257f4cdd90f43882fef16d3517f901b8d049fc6c40065c68c57dcbbebba7de4f7a6fee59915419a0793671be1892ee3629b63748f00336f039096a73676a62c5f090c058dd6b5b3b1b59c7c552f3d231b00a88fbe00059d1e654cb9d30ca2f1d435a3201f411e6b2589307617b65623ce9cb7478e002a035cac8d1f6d4b7affa9a4c4debae6ab5d2cb0122ed10dd266446622e7db0009655fc7ec8dd82df5c3f576a2fa83c07b6893e13517819524f33304903b4d00d6524328f0c3c22703f780822acb504a6e1ca25ee820f36ef0c082dda91f58008bf6e19c15ef252e52022eb6bb2782c5840f9de3a8f8d5a7fc24b322da4b280077c62a73028a88c84b3e231af2557cdbbf115ffa04c19c99748034958626e70073e2717f714fdaf3c76bb767ec1cfdf02532cfe65d40e457d146833af8e2f400a9c5f88efcfe59cf4c29950c6ee5787855de440cf66f3e818e635f13f6ad8400d138951051a777e2d38f5c74f8c467f0263ba35e0059d79a00543ec2cf47ca00a8668da1ad60a23cf61e04b37b47b05c76788fc04c43ffd2e3b32951530bcb006e1cba5ca22cf22211ca215d99e68075f3f9af4fecf2e94c9e8347472a34f300b5c28038408221dcda316ac773fe3466a53fe6ef841c78b27133312feefa9900c221217c50d08355369cae3adeaf6a7753f407570970f608ee119a9554aab400fd34187330a6a555379eef672f5cfa8f1b1d8080dcb4263a12c1b8c653370800d0afab6a2cbb84ebebecb8f8f7fc222a0287032704c0309b59f1219297ae0200d1b37e279562bcc3ccdb15fda877dfbfcd7edecc81972454b6d60359d1669e00fbe68e6c27ab6a47d6a8fe9361b273589b25b8a4425ed7b2f45af1e891333100bbf86080fbe0ed0d8afdc8b48d573674b7fe8199dc026f01877c01c534493a00ee2d8d4b5f7256a1610a8b6041f59041714329106ffb1107f93972b9ed35b50083361f7354268385960ac44e00e701aaa8ec8f4231d3b24697f06bc1ed0724006a475db34c0b1c4f525d1653b913fa701b775ba18ae3316f0941513496bc5600bec70b44452635f7e81132ad14db04e5a11ee7f0db02c7b2eedb374ec77c5600cb0d1cd1c62da8f87bb0db4f50ea28b7bafcd57508d80082e48a97c286558e003fb10381b17013a791a1dfd3849f820d22697aa49eb107f308bb634d5e53e800facac395e5ed6847ae6b9602c581850e5a52d6912b7e18db0e4d8dfa604fbd003ce957f2be857babb7efe359b02f26b23c0f6f15f1d59f90f48c10f67dd838001d896342daf318b01f21ba9535fa7e05d5fad54638f357a3adc57d67bec31a00a263afd85a28966da97a70442c414e4e58bd4ca0981e62155e3797e240950f00f8993153b844d7369069bab5ed6c7eb0a1dc451f76fb23b3074d4d8ffffc9600accaf0299ef8a8cda03474537a09296e4ef82b08299cd806c3427adf48c057005e17669dd8386db56128358c94ef4421144d91b45209a66ddfd98445621b8700fb7b35ebbaa1c6a24b6987fa72626b71b807affbf2af59b126127aad10cd56009b14c3dd89f3c280cb3f619de7231f036917cf27a1a787bccb70500256597500b43cc5a7e454d9072d393b680d57c7280098a63d28d4cfaf4f863e2556c99e000b8be403fbecf5fc16dbdc2ec23974eec2c177c667eb7bf984d5d431c7245b004d1537dff990bf62a0f70991c7fcf7646f9105e5a4977bec4a9093663bf25d00a09e8373dd938b86a60f1526e93cfa9ab39bac35205ac0b9f20bfa6d4b787c0070f3b727916ef8b6e575dcbade6755d82492a4b88e2117e91e6a934ef7c4bd00eea50df0c98787811002392ed685b8c95d924b979eab895de40394e73b457e00f5ed266cfcfd2ad819954aa605ffab53f4b016ed08bc8c63612d0d5e2deb44000c41d4d1b15cd37921033d9611fa401edd81d3b2e90106865c6d77a0a56b6f00f6dec34e11d6f98a00cb6d49f9ffb17a58a84c434793f184fc7e123ee23b480085ef21241d8bfa09795533f60e83a60c83ceca2c42083b46fb8f3c5827ffb800bb77fd82f03094ba106e3fbc74c12390e6707becc42e7673336fb00dcc1b8d004dde552ed716d4590655ce569deb50d639b3905392014154a4d90eeb44fe11007b8104082e91cf7b7dc2f9578fe267686cc820aabbe79abe6c071a47924f22008e11d9a77c22fc462dd9fa8f26738dcb405b0a586d0af1418ad3c3b86d22d8009b53c49a8373f68676058b64dadf09e12f30c337455f99eb269ad6f571a50e00b8b0012445ee96ee19e7c2eed35c9328db9bfd80f42a46fbf075d0cd187d970081c8e024f3058216c4127b9d66463bff7db8a5585a4fe4dcd9877e2a3e559700f24b73c82e628b5551ec2d1887f3fa3136c9cbb201892baebe65d4de55c95000047fa42ec3cee60554c6ba12150fe70e357c5023ffc83191c390e72d1ae650001d8cd2368ae909e76f8962271e0c4b17e72faca5f1b4e62826f3ae751c62d5007c5b95f9237fc1247f0234f29ce963ef0c3335f730a1ad6c0616006e4348c700c287e8f5969a70048ccd312174d6e680e567696ce69a6c9ea54dd0e5809df100a9a387cb1988a2092caeb9b0cc4d8ab9a0c0197b6814b23a2815ddb4bfa9b9003d1302654a762217fab91a7fbc318e8165a73e8987108b62e2bade4a0ac31700c24f9d55a001b73af0fde61da305e274d5d000c612adc902f2a1b896b5c3930097e7b105a4345c9c4afef8d1a1f582edea03fbcac886fc6ebf373e08a3242500d5ca1652fb5671ff16eec22335b977ae9b24ea318563ffd6100f08f3bc8186004620b36f8c1019965da0944b71219906ab50ba4e8faddc8be9266c460606ba00f732891aeafb89d48c1925bbed55c1b1966849dbaf829083173a11674c2d6000e5331bd39137373cddebfb8619435d1c3dc1f4e7487d3e6e4af33ced36cd94006fde34fa74022bda3837138c50fada91f0bef278d2d1b64a60f41b99a0b8c3000f8fb0c368b5a93c6c9e6081408471e61bcf2716f65e985c420ce39eeb03b500eb6fbe66839e18c9361f1a85c74e998272bba3853733e7c82b4808eff47cff00b9d410d1d1bafb22694a69fb85abfa0deff7731278f5545794dea55ec45d61002d66d2370cbdf5bd6878383727ce867f0cd2f9a13d0aa0d16168a2a960307a00f2bd149ab0348aa2d0fb7b29aa3db29374c6357ec9d6fd55b41d4ab4d376d30052fb59c7683ece6f9faf12ca4229739ea5bdb6e64bb2f39826201a280d7fcc006d2d4a1b0fc693b773c53f515bfba4941ff3be897422ca77106dfd6231527000aaa94fbd5e28a335dfcb9fa7c145c59b37b87e7e54460220292aac5d529101008ad405c9937bf8a2b15524c86458819c173b5234cc164a1d25c95f0e200f3a0041ec9b9fce196e002a0b1ceb28e726b891ba3dd19ecd81ef6ac1445ad822f700f714888694f3ea100fd7a8765de338ddfaba4170193a53dce0b3e5ed01c8b6006473a3bb5b41f43123c9edc8a549f7e57a9a4f295cae3c38ec16b97416b581004b6869783069cee7b69c0b06219d9a15049729089de7d37a1b5a60c296b2cc005732247260bb64dd5f0e8c72a4d3370761763566a424b7ac4af40c5118f33e00b5e0a9c64204bd8ffd7834f550ee0d5375a2189b7fd50e24c7c36120800752009e1f27118acd68389ece8c9d42251f0d93435925da2e63d9eae93f5ab42c4b005cb920c23d31137355391223bdb25b0c7c463b131f327e0e223acb40ff4fe600fc666c4aab700d9d2ce6f355c2bbc36d163b63bf648ce32e69b6a79649a4c400594d1bad0ee4e9c7f018bc497b816a1a654d87a06f3a7d8cd7da96ea7e6aa500fcb21b00b0a3ed486139a1f3641ab073412de4165801ad603e3d06273379ec007bb2ac6b0668f8c14419c7412a5e8102f4c40ca109a66288d2eec0c2a40cd8002320e0c96a3b5e05053140dcaad9092821ebc93aa4d590faf1c34461c9e46200a59b1d526c1f5f407bda77b829a959cbb3d9f41ce4e70211e76603436a901d00346174a7eafc05764699f1f41612bdd23e4775877b34e7a80fd2969489768400d12e9cb765fb33ae41ade6f4fd2ec64c4a55324d64e498a742fa1edb3792d6006919b003924b4071d83492078ee40b268a2a0123cdd985a0721faed60296a600e6cd6ee6387c98b4807d304b5076a9d3abec148c842fcb29c3cd45168dcd4400b7be565fd56a72b426d0f50f65bf2e01c45dbf3581a2fa83d6eea036a3f92800a1f0fb03a1b847ed6aad4f86e0ca2de50c5ab3fb63bf043e7d7f21e03f7012008b2bed3dffa930cdc178da8eb9145e4ccd324d64722b104a8f9864d2338392009c4d30eeecca42bb370756ec48deb81b564f05d302850fc700e2d3767f6a8700a5b448745f1670a05e72e1e0f6a149fa577144c603dbd87853f7a06ab855d40007aaf1663a0f9c2a756ff661b17955b51d679d62a2545bef96f548aed513470000e763da2fb04064e15b2aa91ab749ec4f936c79f8e663f05856fca7827fd300e3ad0c3d4629e04a694b02125bed7df1489d1e94084a53e1d6a2e85f188b7300c1ff18e600b582e0cbf29f6c34ced3d82004ba9db3d200f08d4cd00b92a71b00b0f923f99166c3ffae1e66e7c401e0d048e5eb9d62db8639e756270667bd52008481bbbfe7d606ce2c65dea4ef1200aadf7f6835e28249921c83f7cd90d146008a04a10770ab25d9e2d31e5c39b0ba58a3b161be187b1e3244e0b9f0a8c1ad00ffb9c825f46151ae6d353ffa85ef6600fdce5792fe00340c6d5079e68a88ba008941536c06d5817144d559db6a8012a4e83c3a8e7ec4e3e0acb7ec627399b700f85b56b14b1fdccd34155d661d1f684f47113f94d80dc23dbc6f7fd345b9e900f3afd805668dd7e42742f9acb272342b8b55753ffcef3e5e694a3bb9c7f14500a94bbe7a948427277c3a24a8f27838d972f76daf2757c761bd8eb668ac4f3000604fbcae126cb24cf51376b4559762e13ae8ffe26bc3b190d93c9615bf4b9900881689b1c2c50659fe9b09e23234430905e19561371020163d86eb3fff536e008c82fcaaf2cc0ff4e0d8423f83a3abef2ec481aa670347a9eb1792465d2e2100954d489ad3529143519a1c2a6dff728a17b25d19f762dca766c17263e015500014f1b6096de382d34f1427088b5d056070b42ebe2877cd0256e7d8218d7bbb00240d1a6518bb829fef8e34d2361e3a55cb9a3a3cf2de13d56fb433d782b90e00c18f68426e114071160e15d00cb38e0fe8f156a6d9d260a959a5367a1af09c00c5182fe40d944857ac0f692b4b717828b1c381a558f96ac0ab4ae8b018f7ea003a105fe2484dfc5a43b7feb234b4e526960f636c3bc4383f986df78eca4fed003a144359d8f54922c44057031730d4f43eb39c5df53a0f0f8d45b2ebfe585f006880e798a23816eb39427dfc6ccf4c029aeb6e218d01a010418be61a0f1110007578ae535cd9991da47746c6408de584e3758143dcbb6c062394d985e2f2f400cb51fa8cb5e14e5291bdf120108ee025ded8fed36fed680176df09e61eb30300c38d3a15d9a3543ae140c7c859fa1184ea81564e881b45257922bf4ace70a800abb0d584266781d5a17aaa71390507c5a9ed65e5ec7a92e387b6705686e5c60039d7a091b2456ddae84c04641ece2595a811a7b3b0cd1a2206fb21a00ee8ca0062beab7e941aa5b7aa4e45f6d73b599600d7a0308e6ee79fa83400b3cf93a500fb21c1eea84d9aa45b85f7d4e4c8c3d201d4b10d7dd53c50bac06c490b888c00ce11dcd99926f92d6d10c277b6be10854003b03b74cabad922ca91731ffa4200187974e33cde91bbd8cdb26c506389572048d9f36252be5d3e80875e6e41690001adfaf89d2ca0408ba32aa67a6910dcf253ccfcd1d3ce92e93a34c32648e500b3b4257b26118d2fbdac6eab46fa7b7097b6ffc034dbfe911186d17fd1a5b000c9a1d24f29725af2ac2ec39ebb787cd6ca1c1ad75d45c9ca930faf6a9fd28f001ffae3fb2df30dd1358aa1e422b02e776594e0b67ebe951d6902be8f9a6e0100af2aed7807cc8206da5e516703690f8ad52716b6289e188925b374b766cec800b47a7596c3bb1ae36ba2c346cd9c055111e67c56980ec56a8f37e025f6da2900a2e452b7fe2c3c15c780fa8269eb0b9e30c214c61c85a49d6233d94e2881e4008cab3695ba53e71bc31d1931459379ec81e7535f3300a17fcd340d3589ba7d00a6d7cb1022624f73bbee1a267e1ca29992e9c0b1e41fd53713aa2a188c865900607df6b53ac72e03c492af69e9b56f2f506cf39b364b58213ef6e805491002004de32fcdb7806cef358116e843f93adeab623799d0cf22e20ef454ace32256002f21d7a3c73c3fa64221811d1ad9f31e988a7070836a52f0fa51ba1c28e1ab00291a8deee19c2cc2c20b72ac4cae57d760a8ae137edb1f4349a70a8be24abd001abc18a93c5e751cd8f27170595d3a44c7c37637f74ca4522f3a1ca4e8cd7e00f086e75ac037c154a84cba668008e92d3a97aa449ba4c1a5f6be647feed341009b838d16d5c9286535c4923b8bb2e75d34955bed818422eead7fc6161e074900162cb38da629cdaa0cde9e609e3e3db95c4503e380c072a8ae3e45760a10a9004e3d2837352a7ea676aa80e0582a5214fba4b48a4967dfa93f7290773018c20087991d226bfdd85407119caa826aab816846cc15bf50d5819800a1fec6f45e00c600f3e2f660e241cf4c31d88a2857d2ce701d60c7bfec936416055a79370200bb1f3c6c0ee9c731c42c51d47b4460e1e0b2d37b37355b8ce23111e0399ba40020c40da7117d88fc057e59ca95a21d6bf6f84ba9bd403e230a611372ce068900e6dc5bd793701fd3c35954655d4d9142c24065df42625338da34a3d5d08748007a5f4b294982cb1436fa5e24f5185e8a4fafa11883477e585918702d4c9911004b6d72d0b87228e6dbfb2e1f5d5671a870c39bfca5e4afc21200bd761217b100bd928e409d25f11ef369bc8f9bb008d0a2efd5ed2e70484e3422873bfe94d8004d113d8425e37ed065fcbaad1459691a5e0e852bd0344f28e2ec3f90fdab6c0031ce47a3016a937ee84bd6d068aec5efa833c5d86c45a738f8ca55b76ae87d00544ff96e176c2c40eb202092480e9aa50658efd5f2339c6d59cd0e04bbed1e00ef9994115d2bc1b9aa3759c3296371d5214e7385a79ac2ffa53e5a5d6d6a510036c1ca3e8a51acb8920ca302a9e16c23a1af8b9eef02162394a82e3086766b009d4bfd9cf1db8afe32d72ded0675e27cfdfb3e2fbe20c1a8ca31a6ed2f04e500a29e71c4b865d027cbf2667ea5df0748aa5f59abb885966c054ce9145a918d008d10d3ecb44541407dd4e9e4e3f5b08de89bff120bc1b776b321c47c7e80d60017112a9fd37b157a267e4a7cb943411b39f141961afe2f90a65a2caea7960a00307f6c3d6ce48703e1e927938f034c4101874b7d1c1bb0379fafa0a3816560006e062ee5c6dfbbf9271e4bb3ee198f085200dd275545e1ae4ae0bb79ce44ec00c74afb602460c38fbb57dc92b72c3a306ac1dac09f68f0cc3e628ca4e5101300962e933ba9479e875e3ce0c055834fde7750b10f6d1db2dd2420667c69b52a00f9fef7819f97da4d65c5aaa86e16c8c5ba0381f49e7a35a4dd2ef6ee80f00700f3debf55392f57b2c0f044ca949a85c6e4ccf7e108cac8b82a6ef75ac35a7300a4e803b2a1eac2d068dd0483a4655866ea9109b77e4c3f98b19dd790e27c350053f29e7b8dadc1fec2a35920f0e0bf3bfb5990d6d963e343451f40eeb005fc00c6178cdb69e2cd1e69edd97a261d15088547675fef41e5cc0b2ec40f3aa573004fd8940cc595f59d5540e8568895c1b7e1285792d928f590cc954103fac9c6009d0e2208f7f6ac2871db9032b67e741922d16a619833be46d26ef58f5e2c2f000b3f8a67d4e329895737170281454bd5b558a06d19e28a3bdff6def802f34a00f78a90c97765c0331b071135117314c675df155167e730b3ddfb11ece9419b0049d2e1ad9c5f51a3506abbefda2158fded87daea04c70e45f6127c3d47bab800c4abf265e0b2371449c90c7ad37510409f2ac8d57df9e095e96613170db19c006b3e126f16cba7abff207f3fdd6c2ae7a4aa2e81fcbc1c0f90a6bb82185b0600be3f2a319e2c8e6831f38917ddc4c8afc791472bf15887fad02b1848555f9f00e7128d6860b18614b1598320b47b73d18fa10098a834df93a58d6d8ff1fb230088364cd59a81d1970a89772407618f46878ebaa1c14eb42cfc4c46f929f250000df390f946c064ad39358e7af4ecaef1942e2c501667ec56b5c65accffccff00aa68bc201bcc9ccd4d3d4f15ae674fe263989e0e229bb4ca66b37443b4975b00dca99165b630e9783eaffd1285e0cf47c6d5ec2074cda67e047122ffaefab000e55ea00b7014dab1ccb6d193e80682d8551f5a1bcb7582a32dd45dab133649003e49470259cc023a300c840e02bc0146e84ba4a40af3de73f81dfb05702dfa0005e254a4e85a394b8d756b66e4c12d602f9a5b3e0009f52e0bcd530e8102a90036c0969b8abd4bf4a7b562a536ed6bc92ba95c0d23a6ab0f6c1e8cd1afaf15006955d7738235054fc7326ab3174d2eb4d56031ab3e902f874243a4a67872ec00beadf49b56e6c647555c46263c6c2afe121ee1ed8e0e1517f473836bbb677d00b66b3a2101365c5c31f925374bf905fee6097fc36dd41602ce57611ee78e070066c44e8987518910556c9c91b41a313a7c9a4aa9e226091d27151bf6c124ce009963c33363845dd9e57f360d644474dc243407a26f68d1e9af42f4be0870670076275d946b6c3782f822a591c78b57f454926f256c6e1bd9ac17f27058ed6400ce8815c27403a4e06355e9321c8feb92b43d782a306b18c3c05960abf16f84001324d8ade1d18df4515211a23880b204153c8c46212f9bce89533adf4c5ca3008afad6e32eb4403af0b40b72c323e8df1b693155afd9b594661d0cc7a239cd00108f0428a562ac978e3b9b4e67f215b5d46e3c255ccd0a7056f012e4ad901c005277ecec0ef85332cb9d21e4a04a2ae6c4939cbe491ff2d4e1fe8d2b698d0100f9624557e91c66e93a759a52f1cbcacb04d4034564acd17d0c47de7863fcb700683d9d475cf1007f4052df957978139074e67af805613ba1ce572c44ae35d50058cb33dd0ac77e7630aa23b1865e577b0def87daa0af6f6961524ac75e4402000d7e04ebfcd12bea135555e0a0138a6ce48c28708d85e4b8c26ae4c290de0a006c5d223ca8b2532e207f50760c6027f80a6e03b9358752e5ecf219cff8cf69001c5e6e619ffc6c81a26a8f63bf2ecc4666b78df42dc2db9cde37f90f5a0b5800083f36444268b599043335c9c4331b22e253d2b5f849e14bcb78413893bb8200323b240b1988eca01f72ee2b6761d924e6be1e4c42091b66686401dfea564e00d18a80a1371357222b21bbcfbefda3179d5c605daad370c4f2983cc100262c00d9de3061691b246191ef4a23b516b345d9f8c5907282edff7a49f65f4132190030a2174bf472808681d4f60ed23c02f189c27d3801b5ecc92983836200dd1900366b75aec460cd5dc2d1c646c15f79efe202cd6b5ce8af64ede803fc966365007a1279372c9db18b8592216de626ad479e143295afa072b1fb1c4309bd943f00c25f46aa748a72d331c1881d844dd742f7f818212934b0b6257c565df89c8c00dc09196038c8b2d48fc391622812b719dc977fb2912517d7d29e5dd087d57900c149d1acd47cac61bcd1edfb3bfb4e82a50b0f1df90787c4d679a2d97e6f5800e5299d66b63cf7563b5d9fd6280d4ff972f1fafcd910777953146cfb61c3980085a4ba8a76bff71c97ef746148ba97c7508b4d6f97f97ee6ed855954ee5b3300a2f2219b891172646119e60b6ab340af1db0a475cfa0312cb430e4fe35ed190056e13cfb30fabcbd01c88793f144cc7abcf39ff18a36380a1ce55b3310082000c50ffa29a9bbd45b983f204b636c409e22f71637527fd2a786877c572c355e003b4cf19d25cdf22516f8aed749afcd2204807c8a290dc7a8f7a1573ae05e5600fc832314856306852c1c33332e1578bd030e575141bf5139f337b22101f43200dc183a3cededb1b43001475098dd3287fe5d80f659981a7538ef781806650c0030b00c61e34ac918015d7c4ec80d8e4237022b59188f890291d1ec246aea2e00c789098d9410f413ccdea493db3a942b8897c452a7d5633dc49dfb94d5929b00d0b0ed897d5da51825bf4bdba921c99313fc5202c93b65447c06c506da167300618e0e7870844598d5df87d74f922d15ecf4070e21461472ac19ea3b0073ad007f92f6a8107f19d11d635f41ddbd75f3e1a4c67e5f6185f6b0ba3c58d130be0085b1a3b82f970a79bd0d38ac0177fbb0a64871b6c7bf04728a1c411959d5bd007c3aa1ae5a45a13ec437cfebaf14ff3480572f20231882c59bdb67e891c90300c32ac6811e0d8f981a5a61314c1e8cc574391cd00b5814f19947914c3cea0f001cc07bb80de7946f3d1e2f0032668e90d4fac8d97bc043a2864b0d4b2bf75d00335ce3088fd68b0759725439f668cef204866a37c5231c0bbca59c2166fa3100dc17daa78c2861841957f29bd9d15cfb741e5bd80be3dc60687dbe917b676700be9185b83d96509514031e0916107ca39df62a7c2b72a82b8a80da10bf02be004f5dffc46fb0c91246869d292a2795ec05a5b51590f1cbb471e7e855bd48c6008c115a8b8d728aae50fa40f94e2d7b75c7280936d2151b0b8d469ddfff431100c0a76b28bf48445ae5ca91209a0451ba89c5766f5c762cce10e6d6a0fa9ef7009a49f9d872ab7c0c386ebbd0b3b9dc8a528b319a8217c1814f431c9c37673700c235006ac2b99823801c98b91b327ea2f3215e71d0d3af16290732b17127b800ff19968a80e26f031c21ffc8e408948f8cb3bbce3f64b8d49560cde7c53d5400b18726f1c2530653a832a612386432a0aa307aaee407f3fc81c92aaa4b2c7300ab68302527c94bb3dde47959d68a46817fd8bf43b550cfc106f98b96cd4a2f008bc3ae9086ee24b3aba5158264b35112bfb5c2ac66d91ffbe194d4febb8cb100cab34d97f789e8b7d1c0ae79ecf4efd2f6582314ed6f08e13c906132669f7e00314a610d93ab0ab33d3f4ee05fe740d3e9d7d4f420e605c65401cf8b38de21006db539a07a11c33db0367df6fe592b625ed2e24b804bde4529ec648de1b42200fca7d8a597824ab8119b7faaacfaea4633759f4bd922061792bbd98483c4e000d1586d53ddb54ef309abec3e14c80d3d85c26d9afbd70224449af1c0368fe10069dc39927848b9c9fa9e3eee8bafed1798912dfc586d1c0bd2f8e551dae90a0026a514f378d6955df5a0208348314b8ed60a3f22992ce16d6bc5c65d5f3925007346a1969a508748992d845ded38ec4ab2abd4370f7abd4a242c9d59a45c5c006fb07ad75cb2329ee59e583a4ea58047b4869bba04d704ef5f12f41669b92100ca86ad50444ef9f29b2154360b54ef9e4015486b880d4f0f8155462852ced800b033384e43bf28875a89b6265bd6b99fd94d757f071294189067c30fc7dfe1004df77a099b446e14274ea6dbd788dbca3903992c33479509e362d2a2d52fbf00d9cb80952bdbc02a7cac338642bd87b3a663fc3957d7faa8e0b12e1a834f6d002f5ae0a8f4904c49c33057dbb045801d010871b75b794fbc3b2ff224d5e34700e4a6d2239c14c8c1c99787d79e46fcf5aea0dfcdcaf41772b1fb860165d3aa0099788cf35c2997e52ed1beedd88d1658dd0fc21b483bc0e4517509aba9d9800045cc93ca67dd4d3c3fdf5c675b2968360ffd35eb45a1bd02e340150daab3cb007a76bad21b1e90706dfb8c357f510fbcd5c76347cf5f0f18a111ff011b751500ab058a4c99888cfd65a5548169d730340999c76bb6f7beb5ef1c9e9d112f5b0019b2616e33a3839f76b2b84a9103abb986455aaa404af6dde75415c03d05200021699e04191c802f9a27957727b77238317d76c872beab90d7caa2200740fc003af97e5e41c0f1a47cb730923acd248912ce30f27466fee63eb0ef4bb18b65009e5076319ffa8b0128db43c1f4e2e0e0e8c8ee7833838ed96c43d9972bd7ab0072db1ad3d11e598fa317e444aadd553ae37c354d916ba7104261c6e7cd74c10018d7bbacfb5e2c0e69ce5a802df6a844edcf74c3534f56d674998f1aacc494002fb8a0e8dd39f76165e62b3d61a4afd792d191047b79355b3a6bea9644014f00e25937741cb0723972cba023eff4275cfd7f402ff2d319fc222ae66ab2ddc70051b6af29d1bfbce951a24996f99bc073d664f2498f1aa94b2c31d5094ce91e00c8f3065326c13f8f42051ec8390900f18f8281996a63ac675eb05a5cf4b8ab007e8224e39551d73a07442b79a302e499428e566308ba72290a95a40091b273003bb1adca653804a1415cc4a826ec41bc22ff507f92803eec69c365188ad2d900195b905da5905aa22c3c7a533277c5ce150ff10aafb043cb7370ef803153b5003c64c283e347b0c5dded6c1e334073b197db522c1c230f97b7d6eb06533a3c006a86912b225497fe8672442d9efc1288f6ea5842ddec87db7e1c4e8869c61300670e3009805b30be01c03b1d4ec56fe3d55bf2a8b640950e3dcc4e83097f2d009364a08f45457420712194dd2bda185eed92d9779b9d97a8b22bbcf61ecd50003139b958edf11ef1b709708b3c906610ef92af34b73840f83e750cab0efca40005a6470fb62e4ca5e4579366ab84cff0cbd04b2c4013818479ac1a97bd5808008a71cd185072209fdabbcb0aa57629d9599d734d87e51b7bd0cc1b9e0d7d1500e99edbdc075280ffa827c669a8222d910c15eed9c5c8bfc59476451fde510c0065ea851e2c7b3e2b25ea360aaed800cac7c9cf59745ecd0394a7bb5d0815df004c8d260da77856fa1836833fd816c768cf43164057a6e3a0d62ff532e0ec69002fae087746521e50c7fb1f99dd750e5eeb007d6abb77579743da56bd14dcd200e276fab21ded42fb8adf17865f74bb3615d6dae80345a43544d359a8d5d1dd003abd173812ab04c63185cd5e32e4df3773450b3952043931f6ccd1fa00d1ba00fac435e9137a39f5488f589bd7c050e47afd1789b8c87f3a2bc65a7ebedf3e009d2250e133e57849798cbf6b539dd95f0068b0ca4cdeac1ecbc2fe9808098f0080df24e17d9ed99679135e1036f2b8e81de3c24391255d682645b49f299c1100075123d571c6dd56db470eee6ffc2a292a2675cde4c595a3058fe219553fcc002a90208d7b8b457fbde5370271cb93cb635dc6f956decb46fdd034b484b6a3005d58ae11241237362fa0637ceca6fa14227575e75a87bcbd5ba56fe5f55eaf003c531a86fae7d0547c01deaa844f51d841ccebb09d1b8b1e7af56039978e0e006d51ac6f0cd766e6cae785d9f8e22b7796c8f31857896369dc32fb65a0d14500306ab9a72e7a1a98d3f27d0f925c9b5d45654f32aa05a8c661ef473c2227e9004abeaa367104e5b09d31b008d57f899a5e1c053aa906d59d20024829ee582b00aea0f766ead1a44fcbe82e09bb47e7b1a3efae05a2f1274c158a88e61009ce0011deac0e716db4040649cf3896ec7811c4118c9ef2c34d65965db91f9215160052d3da7d944f6eb4b11b8809ab58201d9ea9df9bfbf3b40b5f490b8889db7f00f3b77f3ff709018468dfbcbae9670b1a11ac57cf6b3eb23b0756f9a6f79f0d007b818379481f1b4ffafea9aa3f1b817b1f05277cf4a7c2c81dfefd44f2f30c00bca52485de4bc4c95c6ae5c994e24f467c591e2af06933e1f7ca8745d27754006104298ffd34879441c8da8cbeec5d49823d8bffa2b1c41f7890acb87fd833002a3c9b5754a1728ac817738a6c766c7c9d1a7595530218f018ef2ad0ce89380021e2dae9df05d8140eeae473c9f11820e36cf129bd94a1b583a33d63218cee005bbc07461c0336f1cdd1aca2a92f85cf4594ba6756db2b64ea0ee596b1f50400a2e48a9788383aa1ceb5b70ba46b878a984aa99ea027e59462035678a6204500625b03a50f6243862831cb64763ea26f7cd4369e372a563eef08777a650878000b017b94201c62b28d29d7745219e9a9df6842f70d376b964dd315f34a7db8000340f8ca2d4e14475947d9e838857254119904f8c614c0a6259f470246ed00008a0acbcceec83787d10ba00229ad9558223bd3209f6a99339ea5ced01342f100424670f80e0757c2be60df9390ae6b5f874411ffe2754ae4217915423462a200997abf4db2699612faa91cded1dbe45571ac58876d565bf8e7b6a650b406cf00abd585d7f6439eacb6d42f8ee43d53658f9a3ec1eba3c3fc572c7c17c0273200de47cf3b8926d1cb447dcadf96710eada37a6121f175448037e77530e87431005322702b70554e02830ddbe0122fb6814dbbe2a18b37975c52b57a1d17c53c0070975178bc48ecd7fe43d18c5b213baf231c2491ced9d88747309a7ce57cdd0015cbbd5fed047895ab7760fa8a7270838be4ec84e4073532a2dcea8129290b00c54542e21ebc4f75bba07f35d51ed0c740c0f3129c4dd20c4dd46bb7e52ecb0025fd474f5aae01b4a90a61db5e6d110da624831f2bf4424f1804425e0723960002a244154b1cb7ae62944f629cfbee5f0db45cf036f6c9f4ee429960a42df300b5ddf1116cea27acf0446caede9f2eb99a3b1fef81afe6f0ad1acc4b42dea700816d26e2a7f6a80d15fe476a419c092ba09561f0d437c1f218f36b992108a000de692ea5de9361bd2bb86924b087c1078db0507c433f56d44caa89c34145cf00ad1f0d5768aa8d70d34e1804d985eb3f296a3f603310aabeb283fdb0dbd523001d810c06185388f7e6d36ea3517b45945eec3d6afd4c16a64aec0675be50650084d6dbd92f8199a48fdb1536a6d45957c8b05fae1a722831d7eb024c15031b00d548ecf6a5bdeb4dc5b4245c87ce5d3d7ef4fc5aecbd39ae889d3c8d8e68710006855ec930249034a2c449a9d965dbcdb806ce7756966629f8007ad3c32e82000ad75e657742fb70279707d85cad73b72b6af200035f289a2de67f5a0b25c900e4d8fa864bc243507fb03d85684662dc04bf56d9430bf4b2bbb70d90118076001b6511b7027e4e1acf9d9dc63559a52eb1ffbe1bc0110f7271218ddd34e414008b622d2b40708583516bc2a6a8a1b1f42c1582388fe014b1b4c649ee8070ae00ff165dd545457a990990162008cffecd638724eed86ca40567cb3ba41356d000bb83d24919511a5269c49a801bbee55614bb54c482fe99a461a3dac30f9da300c47c74f4a7ebfbdd96dcc5c1284bffc30fe0eebf1b4333b9926cc6e5bec6e900b3f6b2862f1ccaded3614132713dd9cd2aad62f637bdf1b7b7c6584bb6101400bf60f0344cb384860528167a34723f27612aa92c5dff6f871ff08f08e0eb0a00bdcbdc6e23da61dd3197904ae8fcf94dd9e905532e6c4f126bd204fcaa085800e5ac82272f517765063be49d9c8a488f68bc618e4a787da48daca72bfe0d1e00e8221208f86571a3dfce87154562c5ea669a7d13a58f904441da536238f001001a80cc617dbf4085ff18b5a69ddb8cd2372f988be7f8f20c98961b2685df6600c6bdd4789ddb9c834a8c71b4968bd1f644d8ff0f4811cd055ba6acd8eebc7f00b49eb49606785d063d38d47084fa204e78e58976d1b68bfd9f8e590cccaba500572cec5f612f069e4588f13c52107371ad4fb9f1f99be3fffa0943d7290414008813294d05c50dc87a17fe42e5a913d4d9aa6586dd1d84207d07419cee3e500063e670e1e767deea00bc4529a2f1f6ea022dffcc22e25a3f329c7f65f88bc00011bb249edf72b434e784a0f49264da199230030509bc75d37d8cc1d25daf0900be0c3d3b4e7ba7ba30fe5d66b9919b69aaa7c8bb5420c24d6b4279f2b214990008f67ed0db7aed325dd9f793cebd5157c196d86f23a2238ae1877678fd7421008d525fbfd46120a0206f027a235978c0f3069950988751b10c458f20f74b9a007c5fd1ae05aad517754733322f00a5ba68db23d90f91145e4433a212bbb9b60091cb5b46a4ad95611cd3b41b63928059b77cf94733548b7d38fa0a748ad0730013a97596af2f4331be27d6b98b33d2e378dcf52411beddd41b56cfca166515003ac8e7eddc9d0a23ed302118e9cc86bdeeeeb854aecc04d9d7c2446cba7a7100d3e9a20eba189490ca73f0f8d5d7711f99ac2e162699dc554bb84a4fdeb33000f4ed442f052e234ba1341fa72ec049572e34e03d202fbe038350916ae0c7b800ea07d05c39b8d9293cbd324748b986c44f13d03ed2e3a096fa8d08e21da6120050f0e8eb397dc7a05a55dd62fed23e7e9a1a25b010f9e63b49392e35a794c600a653a26213b07b325ff71521246df9fec39735acfeaf654a283a5b6e22a6a2001ba61de388503adc47d331580e08a31a3d9894aa982c195560356cd94723f1001fe2fd5ce3d6140d7677c5975df582738f468deaf1ef0177d8124757f6ea6f00c71cfef52f283b3c0d38fa7a9498ecd48306096d8f012da5d77f3516abda1400661323f18ef42645a25db3b6f0da87679fa6d7c1ff73ccfa45744c2738d39c0053ef00fec99f9b6d81286adf166bffb03d6e6c9ed0783dcae35c9994916384002a6e37474d0e8033aa62b97df4cda7ef426740f7b6ed9af95fd645cefe85e3005fe0d37a75be10025bd053bf4c9525606457719a1f987a4750506d4b8c39ff00266f81172b3a6da0a63f86bc1f40ed797b340ae0317e5517249c4cc33d126a000ac66e60222865da752b7cc5a99a07d8a89d27bca8545eeaa62e27fb25ffc70037b4f33b63be1e3987079e1ce75d273fb4e906ed437be8e2064adb41556a4300c3c214dcc47cbae02993d6af6c465ef3168fb9fea63a275c46eea131c997d000a0d38306734e5f688cf51bd0935df0efd2d302cc58c54ce9d91f7100dcc25b009aad9f02436a45054f38f5f257ca6a16a21f2a70139b15f064145918227095006104ebe603e92facda06af13462b4e414ecd578737933e61640b8f97d0c433006c6e179a028ccb30dfd636e2962e85055707a5c84ffdea3864263570346be3003ac0e6393a3ad3b934f08a374822822c0f68840a1455fa704dbc3dc3951a6000010e97951ed4d3bc87da1a41d80b269bb15ea90ec8b94626a41017aea50c4100d4b5b16b0c86cbff729edf0d35bd4696f6119946a56cb182ca1a09e5828b10005e24e447e1bf39ff7b701f6791656be7e6a60c411d8dfc93485fdf9eda9ec400c4734f3c628c2fb198af32a7bf1edf7b873c9ca6a3818763a328f2fe62a72a00e7b82fd0ff276e194d0e6da01ef93d234d78b23b38124e91815a77c3df01bf0019054c9659d2dc8acab20eca8221acef91453a9ddca7642537012b11e8d056009a08e6dd6dfe6f5a57ca5adc8fd984ab9f2975c55ba2cc2784973866b8653e005125f95a20a7c6c1f4d04f23f3b094ed0261857bb7a08ff882b6ee93525d82002b218e50588e259ffb8956e943cdc834fdf01c378136c463e02658a5226ebf00e0869ca2b4dfbbed5865d8530a556b5ce3957c29870c62f2e08e5ba9e616d3004f96497ccd922f54630f4b11fe11579b5a8d9653ecbddf2057d2cc5fde27ed0035c8f4bffbbf3cdfd77ffe13c150a9d37733f44113c005fa5b904032e82830000c903e54f700d16bdcb88e264372ad643159e1227ac659cc3d9b44b719bfcc00c73e6e3bb6a1f4519e4ddd0f7c7e0a61617291f095a120362b0a476d2e6fd7005ce751192f61fb03a060f12744443f87dccd837f27016899f45403456f091700e568598f5e3bd2451555b68fe7df3a4c3c9b8e2a9b4668c184b4ff58e9d12c00d39a008df58663313297737fc4e4246c7b7f450e3b1221d9d2301d8c91b343001d728da85ed8cfa663528aae5f23035a5097798eb31b8e0ad5c3101b90fffb0031b94bf6ce5e77dc4e15f07fba4e133eec20afe917940d16943f6b22a32370004ac0a03a61245e4d36d3f26b05ba97aade2ede9db48fbb46e991205014da0f00a4103028586e7b446834cc50329d883edbf7405a987264a8bec06611e93f32007e031696987ad39502451b33a1b4611b975d78352900610086f2571bb1a610008b08078369ace3eb9615b9cbcd4161e62b6ccb2221e04f0a92c570eace096d00f8bddde96367c99f5cdaf9881cce5b13bb1c2f9d34616063a51db61440a81d0009cf160691ec92160601f82bd740adb326f36ce55f6fad73c908386c63b95c0091c91133ed1aadbc636efe7a4d37d64e83899d086f6f86269e6b9e8006750c0071ca5b7ed364e7c4d7a0620b0bc1c0e689df7dd9ad117998479b724ed9872c00e947634ca307a4b90504840d4af83949a555dd29f086d05df526db7838c4f100ca40ae7fc4fada78c3a705583ea68f8b7d9a16adb64562da1d9f58dae3c5d000bb2451ef3450db03dda247db2745e9250a699937a990e766795c907bbc522a00542e7034b2cd392fb69982817818eb59ae0e332e6b8db9122acc81aba37e8b00ae2cad282abea1a4802c6f44afb04f33a5f9064ea49cbd169ceded49f42b5f003e48dfb79bc7d8395e132144f1cf40fea356f17fb81c585ee0b7bdfd595e1e00ae2c7fa96b305bb747b30dcb3610dbeda10061a009c5ce1b1cdfe215ab093e00cb862850b6701fe3181474c710286b674eb2ed0f6929feedc749b4f240bbe9008f3416baafbd048cd9852c28a0246bebc287868665cdbd282172ea69c857bd006b30090c06eea4ba52fbc6d4d8810d6490404603524cdd2b8c1240e0fddd90004e95103f8f21a6ca91d730947f7e8a31c8fe82b9248cb8b6fe355a6530b15e001eb1daccd67100ab61b8b83a1cb03bcc497636479d69dd18e10e7ae79cc1b5000ef338899c7f082dc5c74aefca163d2a0922afb0cc841fb5266d0b1ab8762b003ee82d2dd968e9bb62f85c74ef9310712ba77d0ff92a2cb67807cee6ad7ecd00323573fb806ad7504e8be7d5f9e02d536d21c1592ab5338f5d1f724951d38b004fdd0afb852adec10cce710905d0dadfe3d8f50ce6c2d03f0902a3766da4f300005b201c84ac110c621bab5b24bcbd97236a470f7517b2b3bd1cf58ddb0e6c003415b0fda6fe2e6c9f1e2a2d7b19a8141542bf62efbaa4d8376208536a8d7c00fc1bc2b348cfc10d5d1daaaa8a58c361e88574d8f4930d59a0b1e70124a5a200e8ca2725d12901ae0c356c0cbd51115fea77c5ab0a233853734e472d22dbb4004e656c4c55199b5b24080d70b50e6f4796b02fe203c04b3355a3a3a4730dc100476fa31becb79232c7225d12207d5c00232d4842fba9d88c63e2cff864922400c552ecdee78c04c89867f08aaa8ade98fbb51f7eb577874e7c81cc381a3e3800d81db489f52c10a437046f560a7fb9a75afb57424252dd5ec9d1731bfcdbfe00926417e150ed7cca3cc0dedf096c87877c50ddfb59b031c03a748276c7a5db0073322b0feb144ebfc4cb16d11e14e53fdb5127587efc8f08ebc0e3d3b243eb0097336e0deb39a19de307818d1ac5a876ef1f6a20d0a53e24529cb9dadddca5002ba5a00568a0b20d82272330178830666e6819f5f29e9342edfbf2c5a0ac0a0053bb4315b2822ab15cbd211ba2825262dfea30c385daf0bce9796a14b50fe800008911588e31313e87da7fd3ca6aa58910e1cb46dc4ebc4fc6f8c27f922eaf005243a552f2b81259df219c214b7cd76697b4580929df6a429001c1016e159a00803ca70399ef6970356aa6a63080c27912a7a8fa9cf1c821129a4869ceb0d4005fa79c90460fb483e49a740246900bc5a97c8f34eab2bd02c32224258e4c110004b0226f468e41895b98f672e0c53d085f66a717a45e77183e05b721c9f81c00e5976b6a8e5d1215cf03c9b4b99e8bb6021b3a7e3fa8b4221008a740a8a1d5003ba5787f47f54728c9236e041baa5ff1085286d161240a15d9615a1d1fe08a008459d63ad66d6b321e122d941731ed6f6d10fa21be5df0938eab47e4607fe7005a883d3001d6a2973e12cc4e3d8d14116efd160fb9a19fa5a74f863e636d6c000cf8353d331b0151e94e5986a3278ae90cb9f4f7a3b1d8a6847ea09be56bf7004777097fc261bc55c6fb882bb46dd229ff2618b032ac534a79ddb78716514b00a529586254de91d35948a48139f9ae5cb7abac9a38f793e981b4a805a0d199007374211d9ac160f4177250736c015536be7522e50b5878bc49c3138ecb449600bfeae8893d247719fafab0043e44fbd7996320f2c859652a6fed499395e6a3001adb0ed7775425c3803c4541d721cb27470ba819ba3d62b6cb791e5c93ba0300586cf06372beb58c1f596974bef84c49d4d1d8f31684270e83d1a2a32fe0f60085cefcaaac1a6c9c2958d49fea02c822aa1dade49484e309326546f5920735001e20bbed567f7f26f1ea5b2f7b905fe8dc968a226d109ce0f99d9e10aab91d00887932f9a9d2760a880e9afb306974c5b5e634955c8b592aba0809bea5720c00300c244e59faccd89bc9abcce66bfb2f1ae25b53562b50c4953b9de93118fd005e22d605314be31cd70c5b00cca6268f4b7fa687f203a48cbe1855c54dbbbe004b781757470fc4bb718e5fcd78fe77435b1b6a966d679e42f4d81a2b5b904f00bf32904dbf2bf086ce5173e674967b05637101a2a81a97bf751a003aeb1706002c3da93e3820fcd12469b02bc1a6c627d2d276802a4d3b822ff19aee3fc876008ed9b91d847edfcacfc7f330c3d2dfa2ed7b1b7e5860ab2dae6d5ee6f8fde5000b7cd7864bf1ffe70dad5d206e12bb68c8d43c629410c4ae5a21efc57ce11400f6c506497210e32050c50a43485053ca9c334d41544ad1ab8d2cf43ce108a800317a1e5939135476f2b9b32c9b5e558db2a61df6b6600104353a94e55ae61e0075b9d40f6e105c44647c7c823052bb9058ab4447851d06c480efd169bc8b82004802380f79a0d44ad73c05fe6deeb4dc07a54fe67bd31cc9c99984cc85ffd300ec65aa04533ec7590c5897e71afd3f07e0b7c0a772dea1176b390a3d984f620038d8593d1b93bfb9db01b3e7fe4a0736aee898cd22f5961c58da9c54807d8b00ef90c033e69a3a7c226f2d9aff0b29da76e993231a2ecfa4dd269e014be3ed0027da039b191255500e194aa39fd00fbe9d5c16d9f451f87b127e0216090c5f001cd29b64589a28ed41fc16db9108fcc573a41078d837c0de756cc1946a487f002a5b4e48df50ff2491c31c83ed407f5ff4d7b8a1ac5a83fa83fe1bde1d8e650064ced9329b7d005bdf5bc37607ebfa4e5217557d180a5c7662da89639c903400d4ab97c62b5620bdcc30ca234cc9bc997357d24a9b7565f150ffa391c755b000e798dc831079170a29ee06b97ba183d47d73e3b665d512a78d837c920d19a700aacc45a43d2d20173c657f969b29bbfe56f7291a80aeaefb2e1cf601ea586700a1adf1e2fe52c7368808187449f78a704f033e36fb903f41df33c181d2b30800ea44142a1ce503e46e1010a753ce12fa7424cacea982b58d6fe322da17b0a000f52210846d5187601b20657f88f25a427c4eeb06e1211ccfaa426102a26761007a0aaa948cca9e3f1bcfda6dc282e7363a5033d8b326e57fef41f0daf05eb7008aa8ebe994c146f1d1820fdd73b231fa7dec2fdca0aa9acd48cec48f0a3909000c62f6c3a93ef6f86bd0526f0f55a73eb6a677c2cee32aefe7b99779400deb008bb5ceba113ac95d6dc08ec34ed8eff806a2e9f2a990f99fac717de696b322003f3f264de0f35bd7f682dc0b9528cc785db3ff3155fe70eae6a1b49145d6a9002d9395eb436fa5d734420f6642b8317d94e7f3fa4cc51049a137418561997a006448963fc28ff73811e34a2bb84630700b757fde10d9d6b4f7ee03cc700e9c0089b74622479b20bab42cba75dc2cd765326c35dc291c90936389790d66dc83001040ab6fe46ee2eef9a24bc9fa329331a7f27026515ceab3d456dbf70e94e80058f8b82251b52083894c556b394f57af8f2bd0858f31b21ecd75600bae18630016e2745f5f69be3626e3b6bbe947d7d645641e3846c4bc5b408f303b625aec00202415770247be6262a50803de6f36794cbf56914283fffc0d9c057ba5d8f000cb7132bfcc33910a27283c65dc54bd4fd0af9f66b49b3987e0a0032254f5490012a12dea75a1119d5c3771ac458079ff6dd26c5850260979fbab031891906800890fc8ffa9faa35efa58ac36a0d16a570a0aca74cfafa67aa78b5dfc6deff800d629a93b69394dc9cfe338117b728d0705c2f81a30474abb3b7eff7d2e6577000266adcd5637edf63d3a61282c8461c2b2db7167adddaefa3d16ac9674292200d8432eb050e0f04f38e5923bfcdb80217313f94acfb4d7a3c099e00e0fb6d400a5cc5d78d2cd75a61bfdf9f5a36d03bab277b740265ea136cd1b7c55cba6aa00ae6c7e1a3bca11aa44b6f188910a7b580f8226f6b1f8f206b2bca8075d149500ab428580551dc5bb90258bb2ba57d716dcda5e067c5b1c71b10003a861ecc300ebaea1f5d18154b458d9113d80e916b4f9d251d0d97410ab2b59e226a5879a00b2824db3844899e8410ef0fac88939ca3de5b8b5131bf672dcfa3c241f550900a302aba8de31fc0153143a1f7bb9c8595927985a3dcb0434a71f08e92dff4a007b128cdf3e5abd0b72f9f9b5c543f1ea0aa1bbfb0d95321b910a22a7233bf100fb4e0384ca300aa51dd786376217ac2c1195b7bcffe131513881fd098a6ab1006008686542cd700288aff42fa81793a2312e8cfc7e422c9a17566cf8fb7b4900fc4c744e338283ba653f8d56ca8ce49d187e6adf048cc0395ce2f09b84b553007ea0e9a989c1a37d92eec4cc71ab69637b3be304d9e1247b616cb0ec615c8c00fe96c82da0e8b01a415523c9ddad412f9cb64c86ddce854b077fb4e19ad8a00053f63a027f56db0c9a1502a54750ee423052e714b7d8ee4b612dfd6cae0cf0002b2f0b66401e35cf3cfc94cf208b11ba35e6df265a10f0273050c1f89e360000767f242494534a73d837d89d90879ea2718fc18e25424862a0de5b87ccd78400751511d9bb1c162a67acf742c2ecfc56cc351ae90fdbef990f5261fb14fcb50017f90cb116e42153f10c4eb231256738f375ecc687020b34254f4ea272ab72009ea6acc814bec6c2451937c6157802ee02ec4a86323a4245ff00945a02ff220094b2aaee20a15723bc6a8c2b30653b90122ad2bbb1a61a500697715579963500f07d2ce49eccefb5212ba9ff0a757f64b69eba8e255e97069f0238d63b52db000b989c3d37f73cdd1a118679dc60e67965028fd060a5265c9dd157d5df8ad300f9edb40d87cdd048456a83e8b0e125373ea9a6196f5a8b45d2eb2498af8c65002d593dafcdfeff756f63a3eb4efc6407af5f38d0a515256c51ea09419bcbb900488c3e505e231dfd948cc882977d613d7b9108f206fba9ce72562685d051700071e24195d6613a30d20cf0546aea77ab2377dbaa0683625ac1d620db2e3db000822a7ab8ebb70ebd85e6529fc7edf5baadd532b8da35fc182ce6fb892dd88f00ecff9e44a23efe8347ef726ce95fee70df8f6f7024352369796ad125a8861d007c53850b68a3411945ffd7b677dfc773d7598446c5e05125c0f26eb536099400da45d6628bfa63e56b65cd58102da3e64e936fb72126325c17aa54c7fa462e0001cd2778381dd46178bb4ba7f0f7e17b167259ccacf0abba7b82222f75a64300203721e5f2d180d2da17ed2a6c25477c46fabce2d10f6970370c2781691238007529a93c5bbc52cd9c0c080cd9b301772b7f383c3b0a5d7f05cc6a31706559003064a37a743219ee0a0cefe7fbb13a77a0d760aadb9a255d2996f6f4084dd00022210a872f361da23e0412950244b05bae2e41bc2ee534d1056d91f52577e10042a7a82c9a9c9d2b365acecbe4e83ae601cb14f1eeb89958fd2dc629a5a01f005c04b2f2ae85ae22be77837f5a65ee7fb92d4a5cfb053872cec84e5fdec4bb00e311d500c09d00e05c3f0dee2757bf1c664e5281106ba701bc64c6852fe01300b05c58821c5426387298d767d584e61c4d991ee4ec5aeffd8693cde9a71c5e00960a49910f70f33ac8645da90d0b016eb278e116be60fe60d9a0f77ae82879007c78810ee9f60720abf63de6fa860e5b8370db81046ecebe616d7d09e9ab27000230543d3b405d68fd90248e2825b812d21869bbc990d03b8382aa660c196300c440e32621db7c81de8b10838b4a4c3018d0d2f75585cf8e259d92bbe0eff0002c8cbbf0a2dcddccf9626c900cafa5dbc8ccd91d0d873b05513f12cbc611050019f8e0b98deffb4314c9d06c7fb16fc8ccab633a6a10375c2ab5bc80c93e18008132c68dd14115d183eae5b3228448d4253a14639dfdb6ed95c0215beef07600cae432f8f57c78d727a496ef2e938ae1d2c3eb1b8d11ea2eeb189b970b3ac1001b469fa42b610767a36365e206816c0f32c38c1bd196be594925eb98e7ce5b00036cc6b121ee96b15dad1e1f0f2338b84016f05ba2d89a1aa4f1afffb6db3600883d9cbab638218d5ad8cd8a4996acb2055c02820cff52a9d25b9c26129f970058d140bc5d193fdbf3a5650cbf2404a4d8cf36e48c9c12f787c593a214d18d00e6db517b45445293d9d030da60123be73ca3bebd0652ed54fde45d9e20da0500f135795bae2df6fa44c5dc68d95b62760d04106bf265d735264dc8669ee407003e58fff5a83276e824d552d5cd413a05b4efe3df16931d20897ff6595f8cb500e86e2bb103b023d8253ec732be52816b1a8dc37a158431144f44587de6214600b42e1d73229dd31658f7c96f3d11f1d8faaec22b18d3582136faeb31b6cb210014125e173baf72a418741c00823f018845d5cb365a31059515df85ba0eec41005ad0b8a795a8807328c25ae931f4c51ca6bd24b6c94cf9bc268d63f38af6c5004d832a4faac48f80d3c6fea5ad4436bb5775b5d22cb05616bf99dc1151547e000c16a8bf86d6c8c8889a55de20aad4076452e356e8756becb521de07b7aedd0070d254fea2776853d11e6b2371a26eb7d039370f22960e820290b4eae492580098e3d9c71c29d708bfc222393b422dd018c9696033e6e2ffb28aea7908b330003ee2ae38b1e7af1bbb5fc8b08c475457d4201f6a9efe152c180133e151132700c57df9f283308d3d735cf68fc78fa260cfb95b9ae5554cb6ceb430426e68770084f6fc6520c901e9549698be1a4df688258953e2450fbae5cbf2203aea5c3f00c64d08237d122a37faa1cef4bb2dc7232d6261d36faf61d25c23f885edd310002a79f9957508e1c72712e89ac2ece5cb201cd1d30071178af6fc716bd1bb9a001386180d49ce10133d7469b415b49f9b9e096eed02eefdf415f80f83eea625005b05aa826613954dce934e3580c1997da5a25eb97943fd2370e013666bdd3900cc3dd9ffc84843fb893ac7d2530fc11c495115d0347cd45a029aebdd387f3e00dc094585766dc7ebb5570c0db521ac8d61ecf395d21f2714960238f4d6636800cb493a6d83365f476bf288cddc6220b0c4175b5ba316289046e0608738043b00e6c8cc055f6b61ecad9f701cd5530a75b3e160126ba7ca00f91029c3a2e7b4003a04fe007b6fab0786e694fdc95dbb7074ea0d0acddc3b22ec193d42ab2fc8005492f3ab8e15f3440ad7f4a79aa3ced827686116523317f99bfd0debe2b2260014665e32e23ad8df792d94335b1fac78624f3a254c9c1e78d153a0bff77dfd00ba9c5615145b817751f6031bca9e0149b6d74d0ec7bb0c378201c62b00a06e00cc4892fea456518b3c53c082ea62cc5c673eccb92ceb6754867807471fc75b001e4c3e77de9f5ce277433f6f09c7583c9168751fe612001914e254134f7f1500dc582110775f15ff240d058387f0566b9c14ef82b264e59cbc62bcdb8f0ad9003ec22c529e643f89a9e3f06822d9d695796a21f5a9ad3cb1dc26f58f2986c900e576ce04ad2b1287a0e344a923803efca0c5928d7dc7ee5ede461882eeca2e0088a3602a2e783a8188e52c6e8332797d32bfe63124033ed5ac4cf14dea958800409bbd7f4082a2607430d9941675ad071367df2273ecea9c4766ca3485a941000183b99e51d9f2c3c4377cf442517484b5e8c89a116a3bf945b8bab19b13390073bd954b37a75df118746628249bae850a5ede05fe2abbef8540ed405e207500d197b7bbbd19d1315defb917e356637d10430a1ed15f886c6e70c91ac1885300b7aa6ea790c18567f0cca664bd1610983cfc579b07ed74856bd7cd6cca44b800e0bb96904ca232b18c65c3418a31f054aa86b3e5af194a16f8874fe4fcc08900b29e151dc1825c36ac0aeafe7f54be8dc6bafb7164763083c34a37434dc9f9008a1b62ad97a42070f5fb7576b5445f49614a1b1c5e4d6dcb41234a1044980c0006a83e1163c97ba345358db0364198a304a873b3a2ef7864f72adadc93ee4c007a2e694206e450702aae6f032a3b0acab7244bce5a3d47b5a5aaa480316e0500a771338e635f7e1d5df5ab1f4eba24f98abeb8365c4478676fa90431cd4b9700ab1de3eaab4e1a720333abc116a88ca64d365cbe4e17f78a5f436fd89e4958009bd942fd295e721da8b6380a32d227dc9dd9087d9f014bd69e7dd3c08cfc54000d29dc0fba8fb8aad16cef03a8bc34d23d47893e6c2c59e08d611a6226be600083935717b1bcf7d8a713410cb3c93d61f9435e3b7d0cabbde81df12fb3d41500db878555416564c58a86a5356a4d8d6947824276ab24d666776d452b98e72800158816f8b5c2b7cf54e2add23bec9b60b3220dad16012f24c767358e78f144007974bb1f89e917c99cea1300aa12277a84b9c30ff7cd3d1730059e8cf01c64006484cfd9111af8155e661d59e6649699f8fc0e52606ba963e1a9c634648f4f00ee56102bc01d7a1e5eda33704644fc96ba72126ddc51aa6cddb9148857758900f9cf0d460b94a83f88ba78a9a3d99ca89f4e9c6dda5934384ee78ed71112130084b8934ae10543b1283ac3bb48e0585480d69878fd5ea962f71919f7854351001db594cc93c36e6be1839b16aeaba1fdccc59a0124f3ad41110ad9f04d428700afc581d11b7089dcd94f4c278f4053fb3fc35276c5cdb7d2a59f6172c139790033262218fc4674589561b08a69c03db5c7a5f8c38232fc528245ba3a99cd8200d3f777aa030f41d7b630b89a42b4d53f40164197240ebd1fe42bec5d76f4ad001178d6a69be3df121c6309dda07d1a5fe4dcd236f8075dec9ca2fc553c76cd00a4e64cd47efbe1f34d64bb16bdc1b036c9faca8ef2175390f2f1538eaa406c0013c8134930a9e126af06530c1c48986b5e07e17716b20600b1187a5c923c2d0025633f210cfca5e13a62fc8280896048179102f5e8f8ec401e1d2f8e7510010094dcb7a6c0710ff63338cb8a53f11d6f258b5f1dae44c78cd0bfec043c0f9a003106ebe5a5b9b523bd0d5238f80e8972880b0b6382519ba9ff69ef955042a400623fc47a062f9d84e8022ede40d773922a285514dd586b40dee1d0bdc3888d00eae6424ef24a42428904c4562ff77c0d63a71f93934af5e4a13a4446f04b2000e3bd4811eabac9fb7dbc50c9cbd9063fc6b47a921771f6524de5f5710cf45c00da700681ebd8784c53ee7dde4e7b118fc47cba38b45403e7d90e6459ecb85500aa600b13465d076d2fd077720b658106ec3ea816e952f3d38c7249f151b94400def83baa38ab8f8bbe3f0b979d2e8c82c3f8737fe9ba7a6730bf8cd29c15c100ee3faa206fbb4d11ff0306eb93a9e435e764978ad02142eaded7559b6898f600c8afa65e40032ac50a9f74d1c2d74e0c2cb385bd069ddc5b10232135a7f5e50021c2dd9f50a2945517661a2117624bd3dedfa5b9bc3270b46024d0b4c2fc2f00767f45d4bcbd8f5f58b6678eaea21cfb2050f623fce613d316a18934e969d000355cc11622e874e2cc0f92cdc652da8fb2b52ecc0c01768f3ba819ae016d3a00bdefb04c19f65b17c4351c3983731c5cb35bbab22a1789446d86be2c27f558009d97de1f5a827fca98da8dd56231809abce874b5f253f84c859b999f92cbc100dd1168c86ecd53c85f7d7ffc7094ec0694cbbdff299ea4146229c7234687b000b15424eac7b9f4e24c2304a6c01840e6a7de52bf23648698bbc34a1c880c7e004421b2acfc3ab57226fe2dbeff36e5414e75cb78e32769c4929a02b56bbcf2008e31500e23e43078a9d625455ff6e09e5b6f407c736416792fa0adeb369a8e003d51c9979daadc967af63f7eb672e627debb3a0a3150eedc6e968d8bdba03e0026cb513d9d01506f8a647567e5bf7607af1227139ff1266b40f2e7c1c54ead00e25e6299428ddaa6e369cba6f952681da626f24e781510404760079494a1ef00a6442505e43d86ff501de08351011388900a56cbf396553cf65e0ac00df1aa00f784200cd93608e2f97b565ee66bc49136c6e4f54219cb86b68bcabc85eefd003343d643d52e267b129dc0556bf0c6315308c7765b940c6820773c7c15d03d00db793f8150a230bd5a5ee1b109ae92017e3042082cf21ea3b4de08dd4f6698007874abd1ecf4d45ce44172f480ca9943dd31153c18e6decdcdc3e81f5bd037006ad647b26a3d49ecef6bf88baed1853cbdce24c9b7aa330a78feaf111cb1db001fce65e318ab54cd2959b3f4840fbd7d349da13bbebf1d7f8b5fe16202521c00c327474d5c14ffa479f22bb0b4802ddd27e8b6a980034aba3b3e727a9b191a00ab5148b1b9c3bcfc065d58f86de320cedb45b5052c9aff04f6f09189d126d4009e63fe6d5307d1bd8836f400ab1026397d69b2db4c9f5c6164a4f738d2050f0061de15d3954bf54a90d37472d77becc139f4687897c08048155994bd9a1cb700123fc0359b66aeb0a03a169946a852d2ee8769770c7d3810debf8f8b62038d0097a7beeb5507d27fda9bf3712b024737951ef8b97742e4ebd17ed03fc50d770085226b4a9e01f97962d490828ecaf4051c0138b8a10cc154fcf9d5b549468d000bae94d06bcf79d7caee7e6091d6ede848d312511a2d682dade153a6a956cd0040eab73d8e27eb31d7b9f7ec0fadbe79749d55e6923de79d8db28b4b921baf0077e3c04844ed5f389d2006116e650b61cac1f0d4fda9d60d3e5f786eeb716700376a3317eea308014f43900d0170b2a671cef05288c633c1def9c36507478000e59990b718f24c028f184e635bdac6a3deded4f3d890e74525ae269b60a1fa00e5c35276555afa97c0ffe04704f33831e3d6b0047f215799469b76114452c500739d4687c1d73949eb48c116c7a446c27673978e4146dd5176a809ad7a26f100c194a09929e20a1f3fd6d9ba7e870d48ee2c5261d3e721824fb8157ab958b000f1ddeaf8507234337cdf6e767ffe2d2015afb6cc7054464c12cadd1b7a49660052ba5a3a56165dfc858a546478026f153e661d16ae7e06f2dc0b62f69d560d00df3bacaf70fc2a6bac5d2f5e9089f379674b7837da8fe5bcbbbdd3ac9084ed00e9ded83bb7b70db8c4aa59e8e4f0797457a2305a3fce45ac8fd17aa2769b6900427f6b8061789c5d61aabc6d7a526465a56e2f605c54683142815681aa16e300b68ca371130c94476adae82700fc996e361418226e2f55db4cd26bf187e82f001957bd2d13d17500114ead00bc59b1cc6e3fe90223e335ff1f688d874a4adc007f866e8e7ce635abdfda86178730ace206994fd72e37cc0ecbb0873700cc8c00beff86b9a18762146da432fb1a43491cb6fbed75c26f506909f1d394b081200001121be57c8603da30d72b306b3d3428e56e80d5ebce49e262b2a9fcb16ae900123dd0929765d4e339ba1074deac15a9adae1a61d9d2cab4fa81af5df7440100bc45c73ad9a4cc42f403bfc6f18a6a25c88e701588325c979137ef7736108900b9c1d8a3631c77d8a6982531d81dad3f6fdd3423d1aa1ff990f997990ae62200a9527aca313d98ff45ae372dea881f2d9c4c955cc4f846f3783bd28c6cf513009a545856f365c2fd83b5f2be8d175c460de452b65686647e9cf825ad21fc5f0095b535364d2d6918ecd166f137f53ddf8728f92852dbda11eb417d8d8f5b4800cc1ed05f47515591e4966eae34889106a73a611d46e6769114fd4939f0bb4500f95e475aac78a8ba58eadd232eb0d92d35321c892bd08595640536f50a58660007c8d56997cde62f93fe0e729ae8cbbc836b0e1fac9942748c5b2125323245000308ec70156692160a05ed3d34739d75418a4ccbc6c881dec71e2c779970a400ed21d7af3b0433fdd31296c3e37e25d25a100b59d4855577ab7a618af0938900deee633969e2c922dd70a7a25dcea0957d27937935c8c4ca55fab4d2f2c3b200c3041a3fcef4bae021576f51181c59447b6e9f52054fe9727822a396788ca600e798c0b169229230a2902d9ae03270773c12ed7a52ee497f47d06f4894d6c900fffcf0741d2323833374abb01363f0eccacd5e9be0cb43c2dcfebbe696a0af0027d285d835e6801ad5685332cbe5a3a3f4ce6d98a906e3b4831a906444cf0b0056af3b1ceef68b857531572d62545b83bb86815ecee88f33653b34d612450a00326d8213a662024749037fbece9e6132807873a0daf047b8daf7a83fc520650059342cc8ae12e89bbc7873323d40cd2e5d5ebb4bb2ccfd11b115f5346b5cc300fad002cab061929ca735bea527674e08642fd9a86e7b33e7ebc01c46cee4e4009cda5e4e3beefe787e8b3d68559a902d543ab81bf80b22793eed1d2ee25a9800725f17e454399aa7bfcce673b27caf9c724f0c6c20ee7035359e2b537ead0a0026903a9bf2dd52478bb19827eb527817c592ae05d4928bbec576fb4001064500fe6e64c11ef1d82fc0cc760b650acb1125ddc109cd948ceb47f78ce868c989007836e942139548078b9e9866b9a9f5c1ab5a9a576e42608c181625f2028ac5008906cf91cdb8892f7bc41ada605d2bfa18ef4f72e2b704bbde46c8e5b929a1001ea9ff09d9639e935c0597e09e1cbede87abcde875df1edf2dc2fa78dda8ed00cc1e4f29ae0b5f3dcaf1ef59cba19b7f58541079d8b06e4720608182bae3c000386994d639b93d596a1533ab35e9cc50676992f1df4d5c1b0c325bf0119f0e00640922d21bd7d846f8da0e83838c2b25a498164d5b07c52452b92938d2ad5c00f5ebc771e7e96d815fe9b56db64e90d280788aa8553b32beb6c024341770ae00ce08a2be8690c48e9af9385d77b43dd113cc78471086b019984b406c3a359900a4edd3966875bf1a6f30e2b78a99de7de4bb151b8ff18dfce6329b9783c5ba005af4156fd2def9f43f3a48745a2752f5ae5b24622d15d76b92360ea19d80ad00fba75d1b76537be7649122e4892225427a2e4bd5e4b27b0ecf78af1af773b5007475dc0f34b56e0dfa76c99d843440ca8ea72f56995aa3ab93262f7115b439006dc34621a74105c9d08fe2e379ac6c3e712623bbdd5a4c9ef9a3ddf7aa8c7400ba4c62f035996be816423068537af0df360fcac03696cb119ce6b947aefcc300cc413863d519fa84fcb03297cda5a739563fada217cad776e93dc27ca3de9700128ceced60c0d0745ef400a4c7497a371e9c537b4b45059ab1b226937e32de004409c3c6dfdfa2baf2e5b0aacf4a29368c0545355666527b960e0cd0abdab0000e3282286fae5f741da7fe0b8587a361cdd3a90f76a53edbce21dad179da14000e2a3d7637d50883a83f6d16ca3ed73615fec6c612ac21a123807128681d9f0094d51e1395a3d34d06dbf3819be0c131afe7f3dd8da30fc84e383c296f336500d84783b7f408baefa59c8941adcb20316540498db504a422c6c296f5993b6e0042c6363b473cd6735b9ad486b68fd01251d41a65f696edb9c8cd70a22c67ac00bf61bef29b7878ff82d5bf8ddcb52ccd3e29394054eb05a7eecb2ce26d4c4d00373f3d1fc90b0c16293341e6367eb348b8e0d7de87292900003b22635db3dd00dee578d1483ca9cdd33d4c62045f865cd489733372e313f8d6469c74bdbe2b00b77ce03868a45e8524c3878f419289b74f7385a78163288222b1dff3f5eb6700ac0a3cb9fb9bfd31f710e327ce59ae258bf447a00ff3322008b1f6e5d97b4b00d243b2be4ce5327c3d58b74ad75b95858d94d6f8b0bf5ea1c27b686a8a44fa006692bcd261dd1fe1287b940f4280e61e39537b9aec53c389b682bc76d85b73000565a0f1fb8402bdd0fd9adc01ce93e05842627d1d1d36e9aed9fab9c54592004bfa36e01b39469f4b3a3ba22396bcb11c766d5875f3ae5bc83b31a272c19800a9a26901a6241867ab5a19e7b164678b6aaa29feb7b629aff8a33da973cfeb0004cebebe264d40cdd6bbf45c99865a2c402c6846087151fc6c3c6dfb0be4aa00837e3c2873d9f05cc069e617182ee646f6f9dafaed1ea64d7ffeae0a869d2400d98f775e1983fc68030b0c6c08e913bc70fb0329447b3400fb00c0215d18830006f49a21272103ca34d315de013f24e1689048a4bfc2d47cc6c16be584f0b8009641ab83582dcc038bf064e8cfc3e569b9aa1914cef1b2ed394c66eee5634c00c79361e3b961a5df5865a59b6624b96456e80a4279fc7f766b8da951e926d40043b4d10aab4959a5f097f0dd878c25b1d3af77438cb510cae09443ca4fd1ff00c4e35594b6fb55edcd0fef765c9f4d562d8ce2e7dea9eb7727b3b93aff127c00e80aae68854e3c68572b2a63e5d2869942c7225cf9402c6b3e52c9e480115700e922875b1cadb6d2fe61c7076c46c08bb371394b0abf135d1327fecdf45364009d777c00ff307fb42bd9dc39d051accdd95be492146be07a4d983ab07f88bc003e1b70e5b3cd6871d4bb06a4211907cdba0939b76ac7080d63d8b89a91de7900cd711afc0bb5591c0b7ad46cacf37931f942d3e6795a0607202f1d7e2b568e0021fd02953e593d62a3857f7c00c327a508bece3175d473013a8a942571a977003d69065a83fe4363211362f0ce54372f80a14538412ce94e5fc571f39c458e00ae2f1748fefa575d4a5e7169965860088547a0475268b36c484ecd042f88e4002f36b8aaef3c9a2aecf35c136159541f0e5eb7e468ecfb880335b0f63bfa59001fcd3ad062d6568d16b1b83b0185ab710e5098e11046e8feeff7c24226f0e9000c9c65cb6f7ee672a3d324d68eb25f1a5a79b93950f563d50be6482c97f9d2005257b264409cf9c098083afdda5f4a0a8dba0bfc7208d9b69781010f86eb740006d8a5c4c34fe88d1022e3178a5b1dab6b89a02f995ddeb1ba8598b5662cc60062f68c865db8959442dfde9e3fc2d5ba3648bc8cedd20bb84f29bbfd779a800031e1c33d90c9f99971f31a7ea506b713b9fb316bf7f16319c0e38e4fa9f5200020bf9c00d0b2acf568ecee0fa3c69a341acc01e26fa597ff68bed7a23052a000cd2257c760038ed6a4ce459472e5ad155090738c00af2d4eeb6d70378ce7630019387adc226f0709de0719c07c3750c90fba5941e534380d415a2797baa8cd00875638d782ab5da51c4f196c74a2220f44e266759bf933de62f13f5e44570f00ea243b8edadafde7eb641c0b310d3e66c1d53cc8d4b13f63f3e5f8c064d502002616d64268e2b10f1ac576a7b25f89d5c7c95db6790333857b4a9b18f0f03e006dfe4bf44fb64f358b0b58ecc65aa1bdc4ac67153f2775707b81ab6e602f5f009fa78c538ba6c7c1ec7628dc773338dfca67137f5b2fcd05670b5eefb986fe00448dcdd24a316ec591dfca2e4d5a2a6e5248e226d54dca5b025f7d01a9633200209fcd55eadeea1a77f94d606def30a28e9d94ffaba184e6263e1e834b92b000eb7357f0229d08bfc9124b5f9d5fc9e30b98b0995463da1e3ec5a215cbf3a100537dc01d54c3ee4944c2441da49e42af577e2469e809e50887e014a114a11c002887237091a30b981c5e05a0d068cf4259ca43b185a22298dd2c202714721a001054c8f80c9f7b657cf09dc57f35c4216f09ef01093306a700f8d15e97760700c08585dfc2b28ad172ebd45472f619b5e12e117d06f405f84efe7607e61a640065aa5c4847c7d25e6800423495241c2880b31d811d91302a4ec10ad1079a3600c78304762791bc013994272ff23723a473e1b4af16327e8fc95a0ae2bc564500fc400915afe0f48ef93f028566703c1087dabab78f1097c974377b26ce1f3e0004b7f6ed9973fef772501f10223944e726d79dffc45ef8414757174ffdcb2000d40df31ff4c1362a178bfcebe3b244e0c4640a67624dd5348258b0cb606e440044835fd550a845c1d2d2b3847ad376598bb1be217deae99c7465f6a59a454c000724a73188ecb6a619f18aacae41910c1cb0667d404d0ddb39713b90115ec70023db35ba4b8d984109fd50b5db9f9ca8190a7aab5340ed286d93b7a5c7059b00199e7c89a2753c4a29514427bfae42d6568960d7ee0094bb485d732d755cba009a246e2239fd58121dc0318fed24de7d736cd19c844dd65d3351242fb9b2c400d557ecf14b1bb6893aa2a13a7e8e6a93ac594610cdb919ea3602d39971e8c20084602f1855f7f4fa45248be8f26e65778ac177a3dbbc231675677ca73834a3002b35c9807c18b2bbe20dfea7059f32b48d3876cc11e12872867d254485ef7d00f4e041fdc11747cd9aa6ee9a1e6f6ea5d54a3c155af5bdedb3e4194a4631ad006bb5458914d270b7cdef772b3bea5776dcf7e60c51147bf6f17a48bce2b89a00bb3ee29be34b0137ad9e11a7c705d9a157ec47df3440dfe1221745339dbb5a00d305fd77bae68a61cdfe919dec3593404b2e2eb46100b64e8e4437fe894cbe00a0f3aa9ab5f3965f6dec6fae3f85167c8b7ce221e589d452f779915efe4864001062cbf3f82f40b113b3866252bdea16f4a31ecb7a39062528e5923d3dd5f9006ff3589cca2d6deae3ec689d452ea4f53278413a0a6c06b0993ea5af25888000ed974fcec983bb27ac8b3517b31f495ef529345afc92f5f0d5df05224a1a3700b52a37e24f9036b605a74817387d8c9f00177d4d486813461a4b67bdba6a120052ef687a6b93b2950483b39a1610fdf492adaec848c5b65c7e7c047648d677006062b8e2f8673b291ee94bf5352540c95577b97b87298174676875e528c5aa00aa60a68c4689223a94775660e88a890e57d7fb5ebde202ac7ad9216ce8d03e007ad0a81f94da8ed8a5bdaebaa6acd05cebf50521cb8b0a681e6bc540f144d00064edb679c4ae94573d535fcf9fb81aa9dd32ba55ee57d4750358a80cbfcb3a008b93d32b06a580c81c771a4b4b5a98782ca7164befa1ef042498c6d3dcb04a004bc7c2f134dbdf02495f3eb387213c0d10a6659c380e2665dfc671b500a07c00f472338e2e0eb70b42005cb6e34c7b55f8d5871bc8092c9ae97fa904a86f9a00c412174431880f07d17edd37e5fbe589866c1f248f8d2b76950a7f611bc44b009079c10e98675173bc9440b3d8450a90ae2d3a2d06f544a05eb3b13f96437400cb2e6748354caf652ed5a89335019e2d63586fc60eb04816ef20205eb8c81500134acde604e70cec11aff148741fe720802c690ccb17db6fcac35039ac9c890023c3c3c7372aa97095d488f35779506b3612341c96946a6775dc23da4cf0a9006705dafbd66092433f004df44f5e25b5960d29a82361a16cd0698ba21550f6002301aeb126008f44b7c2aaed0d3e75b19db720b2b08f1675f0a56b9771a097005e1dc9067af64805f5ee505aabd8c67c4d5cd90d56da02c9b88982409ae2750010e5d7b2d32bf5567c538fdcc82a44f9830186c304f21a711231c7be5810a8002810c11d57a9eaf36a20f7dffae5096cfedf906461c940baf3e09a5701d4d500c3efd68ca20d503e5572c2be22ac7e7b094ef89e0796a0b02ee0b8c096f17700f28e1af51a72802669aea6b7d36c670e70ea1abe388fe02b157489fa4d5b9d009fe033fbd0addcb4e1ace91c28faf91361a77cb26de2e4e7e1216d24db2bd400297fb688308a7c3d0cbcafc2d461de1260945a3c8ba0467b0db659303521c50069956f03580662be7c64153a3208523455c6fae3ccb5c173359c63a8cb720e001b5f7ef8d09063fa51ba0480ee5546220d4ced54425c590f201cd6b4d1499a00750482872aeb2f73c3807c641405e0d03c91c263b0abda5c10cf38d158598e00a6ef2fa9968313ceb76cf781e51a27da5e49b7cedee286f3e35be3a8bd2db600b7c5d08dc3ee7b3f3c8a6cb233ed4d936ee589344fdf185a9928492a8dd91900278637fd451a6c2b745585888dba3785d280dbaaf29be9599e740f53b88290009cefe9b7dbfd190ecc270642f3e87b0df3d6bda15209c8aef9cb1b6848333d00a119e685d6ff2bca360c321be45def64f09695bc6286c47136cd1f01ac91f300e358050d6de915cb9c8241ccd90e6ca76aa918e465abde128596410b48230b004bdd217dd4bbf5cd06cf2115c44be434d2554c5b951568c9a57e054f0de00800de14c03d16e025429db15b8cd8e9d274a783c360d7ca7aef4d26024d8f07e9000d92b664d6153c1677e8a5c89184e484342d05144b7c470da59e32379b714a00f6d2f8605e983c0188839edaf21fc4e67ca4f480796409f7de6e4ce2094b010006e688e5b3f490e652098ba354d464871b6e3f772da39fd2e614e08e23cd11004138fbe6646350badb6740f1ee6a34087459a092257cd7bdbf0d79c88d9077006b75a22cc9ac333414830fa97c57918a6f3f05dc516e29d916ce66d1b73a71002776428a41c26da9f23bcd4e81ba92d8d03d5f86f0a40ee8cbd80eb59a3aa7008996be25c539914a3cf6d960170d7c815230e7ed2efc90d34fe8a6effcbff90058a6c74c9710a23332a8bdb83739fa3925f2488430d8bd80bce68ce33c80b90046e0c69ce5a48fce5d966e28edf3439c7d0c9a5bc4d478f59f487fe43c6f970017f956e2eba87f79744d831ee58c99cbf42b98b91b07133a93304f6b96415900849ea4a7f0a45a60da8ff92e87e71965639eff3c2b525e01103d0ec00a9bd700cd92a9fa01b2350fba24417a0e519e88e181e7d93cb0a3ed5f65803a6dee4200d023bec9f42cc6b520e9690abd24fb4f86cf1a60995e79f43c117b82f220ac009f0725920a4813c547eda827c94291506b6e361c8b1f3f7d4f10dcb95d977a004485aac3658eaf68f97e126b8ed14612c383b77ea02e4ffcbf187d6a0fd2e800328a6d92898fcf613c62ebc161abff1fdd9c8e38aff5536a2281cfecf3dcc9003a6b0233f7536f087e299e4986d164e82343c5c7f289eb05ea997b926c19f90004be8fab01490578b8e7a4eabdd6e31c5f2a0c833b66b59952d90f06e83947002e49dd77ab35be2ac19a17c941fc4c3b530ca86f337a4c0f48434c00950046003f9b01789abda95729bc0492dce11045b59d67550da04029fb383b2bc10d3d0096fd8a6ee559cbcc9c0bdb037c12d79ed0b1997c7d8356a2641a68e8b6c7b80094526f623eaeb192f876bcdf45ddda631819dd2652667ed3bb1af9686040d3006918281914202ad40c6feb917ff7bb03a5c375e4c4c40e17232cdc62f9f16000e07c4007679dbd5472f07cf3107fa67d8a842fb167d09750ee8e8b8d98573c0058c7d7b71fd88454b351237a7f19c9cd65503ca60bcf9dfe46a5e19b248d72005d6f17e4ec7ce49253a45abd4ba96a06a658b51bfb25abf4e6e0c2d437246b0091e863dc8f097b41ad9bb0c61e0746dd9ff9afa8946908db2c6c7c21da11a600cf675815f0ebea3a759b7eb17c31cee71076d5ccc5b8159bfe868629b0cb4900f8c6c31f72c81078752d56c21daf52b10446b86618b3804cb26a831b031066005f10919323bc4f0417c81304980911c92572a64e6d6a4696de93be2234aedf0044ac40f6ce07b9168a2b5ec5cf564a4ce5966872bcb4c60fc04d2ab3c2dc0f0096fdd0917ac9b0d66424929d5775493b6424429cad08324676b0938ca9bba400f6f704a599f951fb5df831072f0dddec4fb176ac0d99e72dbfce477043736f00b25f799376733b1297bd93c1322652bb49c62b12dd6d47ac6659c158058925004ad99f172acfad2f0b769aac3fa9a2296d77ccda59b475d1ea171209b2db71004dfadd38710e4def397fc5f9a183ecdc77779ce410917224ce637f17680ca400153167b4fd700085f5951349e02932b56c058d3c734196ef29a9edd516b27100ee7dddecabbaaa407a3c833bcc6873c9fbcc4fc32d40437c95e5f3c472695300559cfef1e5286d38ce87612261c1441dfed2e940dadd3dbefd19b9868c0c0d0007bf10acc39ba041c2dca3a02951eb52f27549d4c5007b469d6c12163eecdc0069d4d3b694bb6f7428c5cd17ee6791bd908da4300dc1b65804bcc99148e7f00029bd1fff370dbee1a4af6c2ed3fb3042682d2e7fdc3645a8e31b37f27304db00098b6432649f63fc2ea53c1c97ddd840d48a73b5e725e7ef83d553434aac6600a4b644fd73bff706a3c31993f0ab9db93bf5f13791e7bea465a42e4b0f29010027f23580547958eff51182fe0291458fcffaeb304571e874fcbbc4bff1dc9900a263179d17cfe778f5385d665668653626cf3a50d63c7f75f1027ae33d9d3b0007a1c48b2a7a4725d51fffe4023766a0347935e4e4f56529bdd18b0ad78aba00b207064642f7ac76e8a129e7953bb9c686b4a5efa38974dc0b883bb372b8580026c58be34953747440b86ff24b2225a91aed76520060a3fa73f808b866ae9c00d027856919f356843f63a063c39448e334a91fe7864cd6a515b9fa72a7c2ee00bfd0ac27052ee249b049b6f3e6fd6cd7b4508e7954f156bc66b3e5262558b100359f5eac72c46cebb5eb15838af751d7dcad83fc7a212c5b7585de0fe1054e002bf9f0519ee75c1344ee30d5d463c23885dd466a0710bac88f09ca6c480eae00fe328c0e082a8ee19c3a08861d2f3ab592c526845620d577e6a371f04a0e9f00380026c144b21062e075af4fe2fad96d27a2949fca06cf7d5fcc3c37eb6c8f00fecc8d27e82551f30499a23235259dddaf2f11ebacd772fb0c7d85b684c08c00edfe134d3511abbbc5b5a5e62a7866c55fcf5e021629cfb9a75203c2efbb6c000dee3b1c24a76bc95aa3563f0da8e3df2118fc06a8b62bd7e8e827e75271b100e50b90587f925839107038cd70859da52a733a80331ee5778cb735b63423eb00219fd9dc27f7b00a5f86c545518cf1bd3bf68864f7f82ad24d5c54417b2353001b748ba28ee6ed876ea4d48c1423568becfc56a6a6f0236ec826d2fe53b91e00f2c266ea60511872d0109271749329af804cba9fca2f1f51a04d0251b0bad50004ee20e16d02f488b60a6bc081c159f88193eb84d6e5ce31d3bce580ed978e006093a739b756e40df38d2e9f6050ba2a0a7f16c242135bc48fdb215eeb8396007b204747a578903da63ab527cdedaee52d9fed2cf1c16b59914577956ed7f400c0d8db2a41c1ab9101cf93e0e8ec16692cc26e1d9555a694e3edc6c3d5e06500437186f3b5ea684c1f23b0bfdcd74371bdc26c2259bb8eb5ed6da4b7deec480027e64a526c61d3c70fd569a04cce99510127af7352d37d0a3fe35c33ee34bf00a259e5fba44331684f9d480fbbd0a6b50e7f7e89b3cc3424b0d0fac97f8f350070aa71c4c76e6902dbbb01b7cb53695de815050bf3c817582bf88d1d69b8b00038f40d9a52f7432d3e3337a5ea5eba77fe4f3e79d902b4aa49fd47eb31eb7700ad0860a7ce5bcd1897a654c239da3326fe69c162975929ad467c1c3fa8de0a005209b6a32238499258091a917ff271fe04310edb506b638cef2c1dbb07ba3f0049360575d305c803773091d251100e44958df08b1d0146ffc1ab558b1dde170083093bb05afe398dd823fa8afebd4af705fbc49b95743ad27f459741f27a4800ba8005da164795d381b773f7e60a83a909fa949775ed4ad3ec5868bdcfb915004bb7d3dd7618653792b2c999a07c51cb3e5a580c53ff7f44a853f695e7ff6d0076e980d5f50b635aa4622d4a87fb9fb3fc0d892e3267faddf819425767191300a9be3e53faf362b76425d6c7081ce3e66fd76b82fefdc5baa5e2e8c2530873005e9e05808ca449910f0995a8a131b8d5076e3882a0620a218d265950e7129f005fbff09f0b3d9cfa9c00e7024f78b4584ddfd9ec3ffceac5f3a8972b0c4e19009fbfc273f00acc9a16bee32957bffdecfb73711a5245a23543b3ef10c48523004d2b6a3a9c983f2ef08ab3c4431212b942fe990a68f4fc465a6524c096c60700a5af4ab12322f939b96c72f89875156b7e4ad3945b3f6024fec01b6fd6a45f00f432076ef946dac5e933ae166997f47570495f3eeb9fabdafff338263837fe00f0fd7ff87bc25413f95fdfe355f1965e364c7b792b9127a65fe424741513e2008abe34cabb472a36067b9042a5d3912ea535efcdac9a1aef55cf334ada20d0009b64c42708e2883ec7ad0d036d1347a202b49b3d039bc28ac742280652df56008e30b7232af07e3c2a2db307b5f0e15a81706935b0b6edacae256fbb60988c0080d2412e9b82363ba0835e454d98fc82d9c71d25f9839639544a7567527506006a5c568bfe1076776af6d2fae0b83a075714e962e9bae2c4b5ba833237f3d400feec9e3ea881a9c8d93e9787c9bbac678eda8d187831ed40f4367b496622a900f7e92af6f2854de31773bdeec295461b825a0d57eefd2a609c8dc5ebb087400070a0ce2d17c0a2e3bb6325525d232fe562e46314c1a786518b9362e2831f51009fa85f56d685f904669da3fbd9fa40e5c55bb1ff363720193b01f95ea404d20087ba2813e0338f34c2535b9832566f32b9788c22921c92f8461c50697d13ee00633b9acc439e639f57b1b1256f91877b1da0c5af285a539eb003bf5cac4a4e00b2031dd642f3c03bbef7c5eeb1e581759c0d27c8ef029a9934cb50eb073d3500a78775b543c005e431c116e8e52e15702033f484c5a6fbfc1ad25a1973814200a800383c19336163ced12160c7401ad4c7bbff1a86cec7924a7cea90cb051a00608eae50f9ee90eeca9b114b0ca3f49b9b45ed4146f86c1e9c1adcec6742e800f2ed2c92464ee86f3450dd0d6602a59ebd087af6f76dfec7182ab4996c1ee400159ffa856939f67e1a7243056f74bfbf91a182df99b2ec0c575fd099e89fa600e38d4028fdbba34261f61326265705c4aa33abcb563e6b52cf191162e94c0d00555e08a224fd71e689ee547b038924a6b2a2c2c9554dc3a10a6473bdce711b002a675aa5f9f3576ec27fd86b51d6a8c739ce8a43d83111c4b9bad268391b5c00129f29c7ad08ec8bff2e94ee48d9f9d8f1afb7c179f8eccf3b5959595b59d500b5688707b0a75466afed2a4101054badd1d3ca263e39a406c4555f8f60d5d00068150b9c0467df52fc19257a4400328e5c6e26f0142d3dd0ac2c469f835ae4008a23006d26516509854079772b315dad5259d0bd50879b3c709e31148bee1500bce6753bfd29e8917e9e3b8f670e5c9df132d0bfe8226357a5ea26eb28fce3007ac56e9bb8d0c728ccb1e4cec3d3267eafb9d5dc9264bff197deef342316da0027c3e3d27790b52487b154ef3344d9df090e179fa2c6c000fd3dcde9c13b4200ce226fe14ca87a58979bb858f465c288bc75815393b08b6ace152c31d94f8f00bf57e6957f8ff45701e7b80de78428dc3e93fe6e280c0308662f6622b9bc4700927c61e9a68096686f096ddce54c21a9702e3d7351e019f099c1f1bf4fa17b00b1fc5236b40e817a906f4fee5be4de83dda81087a758258b2f3ff6eeed9e98009af72018d9ce565dbe8603904ebfa1bf0dc5ffde66b3f440fcc565774a507f00e4d78ad61b0be01f97045264f2dc0700e65a0255e764103a1ee6a9bc35428d00d7033dd2d43de0703829e17309a31253cdacf1bd45cb7dc2f5495db301048200a344d8d5f0a3f28227c00350f180d3b9931fabfb99514e3f90056e6490f8b20092534d62935f84b55608b4d8d16ed9c1f711116cedf956019d8b98e0bdd3ea00b0bf0f01a62119466a750eb43eef12684c8d13b71ddea9634aae77503b48490054046ed5735ca408bb98f29d91210f3497c894dce6e7b58deb206d0558856d008ce38033445ae07371824c9797abd8a09f440faaf3443d61e5f780c24659a500239dab0890a94d31ec5a64665efbf91fc38afc196f2fa3d26c6010464c1cf800b75ad6ac7672c850c176bc7b7e735190f7a9fe4d4f2f5b89e78d4dc95dcc5b003a069b0e2e480b4a7c3639cc1c1444249ed749a214f912dd38697d3dc039c50071406c97d18212ee6e1b1328d411011f2151231d37f2e097c1e880ca1269c600e62573dce79f09dd84d7496cb5bcecee821bfdba94cf15d77d8125f6f35ebc00dfefcc4e0db3a0fe9f80210742823eabd829e4740fe578a494c24d74af3c090082480a2856397e3a06eeea99d32cb8c446c4927327a641140d42d9bb84030c00b77f7a87a0cdd226ae4d5a687924068e0233176131a0a8ec74e604717f61e2001a0fa09b5cae973e157b444acbd4d2d235be547b31fb828ef8d17c3d0a3939003368bc4c4e1b0a3218031c184b1784d5fc9af4f44a2b807934a1a6d6a6fac70061bdd2010287ff8b526d3f3dca16aba9a1eef42b1a2b22045cd4bd15c5a4550006ec84466c770568c28be080b0b418e801c137e7c7b5eb83c99e590597b54400e346fc3a4644b5c388f5a277380daacee958625ee0e0658ba4ab88b589208100f6bb8ef9f54a7f21dabbf2324fe5f973c290cc76bbc195f7c0bcd38758014900d8e9d29fe607536a35c9f9f996b76bf423757ab6e235f65744e8e448ee550300346b7fb7d56c521a2eb7cbd53ab8aeda0ed242c69dd6a8018f57509a8f0eac0006b7172186cb3337d7355cf7bbab77841ca8c19b14ed0047c2ebf0ac67658600e4de3bef519cc256a5e08de9cb384c79511964fc21cfc346d45da42fb616b600d3c669f502061406c9517617b97f2dc4ff786b45042b0a05f829fd89bf2cd300100d77b15d512029c5aa425494df338d3e47a42bae7cad4f570afb01b7957b00225977e69e340eba6f2d52d9beb91e599dd07393f9b356400e8f2a0b96148e00ed9a0e2ba629eb2bb8826046990b0178867bc464e694231a7ac780af6baf2f003f0e2c0b21da65c4b4a0ff1f41e28bcc045e8d18706981a500909a0c7bef4e00eb178ef237b91ce44abf71fe1ee60c645e835f0f553dd391acda6ee194306200c2295322f4df9efbe0e527b664446ea87fad8eb4a930807aaf9567eda091f200f2e60dab25afccb6da998c178472c0148ec60fb87c0af64990c929ce22b2d000af95d1a2b03f87e26e8e92f3321c4222f61020b317e0d2ded15357f0c5985a009ac4e28d4eb62481208dda35bb947a523cd1ed9a1678989852b0aee914582f001235e86989440cc14053c17f5a24cccbe634868c2b0ef25891293b709389610035339cd743a4c775a7149d21aa0dd8f3e086833c73bf57df3b5bf4555e0f5c004dc602c562aa1032da1a6013331adf7e4ab9dfbfb78afc1dc48a66ab7c611300eed6d05eb75a768650e0e3731f62bd285a3478f6e7e0c5484643447098901c00d509f1ece51d6d2015409b6b6039128f3df7e3d7a3b0258f27d706f78c5e4c00cdaa53ff0796e2f42962b9ec5f7f89f72e450ce7558b6105ae2dc9eebc6ade00301ee664c21789250f8799f0294a4e9b4a78476e71f7f8bea6cba2c98ed8cc0061380787d6400b9da8fc28af840b8ddc92c31cc6a6311e2869f8cb19635242006653adead06aa19861d868c68a1686c874f83f996406ead0ad6d84bbe3f8890068f88ed70d6c2716e0458657516fbd8b90fd1239be226527cd3f5da1c970650024204507721a74a347d7fe34040a76a88c2ca42207390e33bb154864cfc33500f8f524b113cd0a0b760aa474fc65b5400addfd040d280a3d776969451a626400d48b89ce89df3d70836255ec0713bb7d7cea21bd41f4e11737c4cd575fb0630064336301724cc5b07490d660eca33f9e59c5182fa781481823d5644aa92ec7000115e9ca6a5207a6755229f66eb9b15d2a2d62afba4f6c13940528398e8a3d008e35a68ec030666be18f77e01dc42d52e85b8d0c3ca968df782e4415bf5af000209ed99fbcf0959770fccd85b6a3ab352ca24bfbef4e3f6b80c66396caf1f1001151ac8de54838f381843a24f5a1314b08740150eb35edcc34aea61d25bce30044355d5013950bab3c0619072c7a003f993c4c5233f6fee8ad02e56fb0bf8c001a69abdc9a08ebc4b19366c7828acc50bc7fcec0ad385ced7442304d97028100c4e052763922c2034fe124c8824fec93ab69ae2d900841b6e53799540a2b3c003a167e3ac34d55639a49e55d18d465f969f45ea38d18909d8e480c3ac9456200e1d85be62c15638803429d8f7cc7b5f914532fc2c1cae37296a9e85b0a74d200c08bd21ae43c8c5e60344af6eeac890214b4b37d23ce97121b01917c352fd600c53ea6cd1a71d9f11870d6dcdfff86f8ef9fa2f1f470454a12d67d51b42ed400cf3b77a54655e4d70407e91393d2ace54171eaf9fdf198a2f4db767205f94b0040a2211a2c9b374bc2733146a98c446eb86893b70e58d77b8a1f37ef71637300426a592075f1c267f2b38dc71db40c9cb8ccc5a67f1b9596a104dfdf5e9af900d4b3267f4474a58f4622c9e4fcc67a9fb99ec850895294b6e9c610cfb831800079c6ab332cf8414a57ee966c3537a33fed33b5018d51577c763e3ea37a90b700aa27d0c15e65c341da11707cf3e5f949cd6e4bf914102babca1088c3bf391d00e94ba121673232ea3fcf4be1258ff8bf0ba627026b451a77dedd73741e789d002bbe38031ad48b6be3389e13c813c0eba38556decabc85a4238beb09148ce8002933874a67bd659ea1e180499d4fe057906fc7ba8f7f06af758f6f85b5d4ce00266382004d7c54f25d752d2688787fd425b5a921539a1e689129f2688d15d400ec01ef3649bd8101b6c3484d3c0b44a493280218f587987bf18107bb722c08008ea975038fe3d8650b2dc351a4767edcc320fdb5bd38f56faf36e254f53a3f00c50ed1a2b8d996b9e295c09434f9d04585db47135d59a512a7af761476f63a0028e4cd8e44730824d08c3d5e9046c4b638e3c47e639836ca0927bc626a65bb0034d5295ea1b784247c5aecdef4b0e3cf488441e4e0927ab407ab77a571cc2900d99d006ead652aeeac9100db492070e1edce5cbc4eefe6daa6d478a153cda3001af2431d418b87e3192829443496be4e1c0e2db909c495ab74f10ba681f3e8004bdba725710036a4df011971a3caaa953cc1db33c2593902f3fa5c3844362e00d9125e355a6ad2993ee6ed9ba03887544a4980ae1d3bf1eec2fc60669b5d8400bc959a32bb0e9027571a1b158b3c887f5e84719ca646108a5eec95f6ac711e00e824636add47e4878e9d521f969955608d0ed3c8b86d38dc083ca75eac4278000768e8eed8711efd0cb3c4db56eaa3359ab7df19b363b77bfcfb48bd79b175009390f49c5f109a0b4bce5f8af16eedd1de39e3aa1d95ac76b5740d6f7b1f7200c3c2dfa7d73e9f8ad3117e2e9d7f56fc8da1f7d76d2864d61cf13e41b21d8100348035cc7d32c9a4b48bdfa46c021a19c21a8eac8e468fb2f3b7447b8024b50071978a5c1d867319b815fa0a01a798a3c3b8cec3512d8b93f76b7a01f486840093c5e643cafb0fa23cde42dbe1441990d1451ebd8471b892925a7fafc80df400a91df0a274a35e4b97c7474ef579158caab81c31d55f4a2cc9289c783318d900d4563b6c8bd25932d8d7455a476203e9b9b450962276c275c734406679c17d0012b75170ef8c4b89737be766287606055868c902216ba45a791cd6786acbed0058eb453188fbafee54f9b88416139b6dfdb3695c0c8e01f2757f4fc4a6605800a876a1aa7ccb93542bf298401a32b5ffc6b3710f5dda1193320cb17584fd5a008fc4cf02d358b1038862d0ba231c1bcbc27c1c27c19974d95e555ebd1151910038341ac44f628f7421d963bde65404fe1cddda62e40d567a5df4bef14994880062e294391bc93ab0ce9e349313fab0b3ca5f04e30eee20daf65a2ad3420c8d0031555e9883ff9cc5df6b798a0fb302fd6fd809bc056e99dbc438390bc52072008922ced15951766f41e474a3f2f0a8e745c419d1f2878cf1958cfbe8c2a45e00f4971bbed35d4291f6424139036ff1c98014af7f653c3e0b21b4de289925610054b61186a741108b2d30ea8316d46c7e040453ffac621dc901a2b1d5ed211300263b30ffe80895fac12881d68f08a0728450e0a5f808f55209b430a4a5c7c300114383cc7e8eb5d8bd4c92e35222d27ffb11a6342e34ffc6937939e09c151b00f3d383226b1a747004d97adafade7e4ac7351805a96ef2ce0bb232e7042ee9001546a8446efb65faac94554ee72ede9cdba8254bd0418d537666701636cec3003cc4eef9e5a38c83862fd566ca50a7e9d024d5b97fc22d69280e255fe794130071b426de9c08d3a11f9db6ec846b0529aa4d6b79905675e121cec870c3c94100e61f4ad2cbb289b21b7d99d7349eab8f84e1e905c163a953c83c6405369a4000b36040ef8fc5a4f5cebb9878bb736699d7c23c8772cae6ce33081cf45e326d00472fb855c0a044c71bd66ffc7087c472a5be3ccb01866c63286e823aa409080056431fab8a504d8ec6ce6ba0fb8d2219497ef8fc56c16fa588ead5b83d025a00c67902db675d0faf06afe6ae350fd2fc9be0b608458878328f21d01675b11a00e30afd59100894cd057fb855f74e7acbcbf5603965e5aeb12d7b38cfb94434008c3382c2707f9a41941e519068b3cd451454d20d769bfa6fd498ce3101ea8900806e1180da3b0e4fe53cd96b6a10840561e4f45f81e2c4be4bb2b0211276c000de52f46499662c69117ec2b46062a6819bdb5d5f7266cab1212ef11a26fc0600309ea159b2dd9b8ad086c3ad16160f419168e9d1e8fcb8979de6cc3100dcee0008ad267082b8b9fdbd06f69593c4dc91e702003c61620e65a262804f525a72009f1bd710240bac3010fc377e3cb02ef183bfffd9c5f26a1fdbaacf9277f88900f24d6629c4583cbc2607a0858f3934df0ea69c495bd6b4f2648e1494463547003e9a58bdb9380d7d128c6193b6f537c3890de2e1de5d80ef3f01ee85a8d7950041bbf921650764a161fd58c247847fa881fd801ba2beaf84cfb86dc4b9f4290048712f3b7040a75f8e70227c10eca5314242bbbb546a5f9456b83f8be05f38003f9f443a338f62a518eeac4aba6f7b57851688415c289e41f7becfd01b3c9a00f42512265a68fe5a70b41b02d0f5ea63cd5854e08eedd0701bfca22a6f0ca90013749adc532067b443c06e3e01dac5d0cd8c747b28055dee3ab1f2d3655d9400c2281f92eeeaebba309ac2ecec51ce68f1fbda6dcedd57e7a51f1deb43488e0057e51b8eacbdfe379b823b9915e44e9b1c8076942f3202d566dc3ef31f534300aa9362b439e140bbd1bf5d2d5808b88a237b28453e2724b88cf905a10b85010065fd57cbf5a31eb26eba45bc42bb2100f4654b646ffbc540447b56b31771d200f11c9df68a3250b476b785f2cb5a0820b5165c0e70a3c7e831bb2c1f7ed19d007fb5922c4df59a9befbeaed8951bdcb1ce18136506efd8867e7b3d4168db220010d04f3431ba52350be35882ed56ea5b5f3c17b7aec2c1fef88868256967d600c82e24bdb3587825e4c233b14b793972d1bbebcb0b16ee69795aa23b2e5c5a00c7735746bb9b99c62ff384a35701af7019de8a471d259fa8a365c49fe34f4f00c7b2a1663a16b56bf727d9596ff9c63f82268d05b7cd09286631f371f895f600bbca0a1c657da83c1ed1d8be04adb332be2682b206afb44c4d32182254d9630072db4ce99515d9ee102f1f68150b57b738b15cccfd184ad98f2d16a37897af00b29362f4ac46d9782dc78973b8a6432b055cc71c6a59264bd52ca2652b027d0031b511cf9c76f80c6c73088fd03abb4e2ce197b64a5bd4415c94ceb8ec651d00a1e37b93fcda2c8338beaa546acf03ec8351b5fdd60ec8b2890797d704c06f007333c52f9bb5848fd3a168b7f1a0f2338fecfbd3f8eb78e5ff6dfed56db251006e72945070db2719ecbb3eea0985d3ee050715d51953f282be4345f9d5049100ddd7fb6be31de0b1c2518e6877320fef7edda6b4107c37672c36094d808fbf00c999824f843e5455b177d00fe2dbe145c1e23259a7937e2b0a2bb3e63ed1ba00c8739f9c4329e94eb8e0991468d3a5c9c76a63bdfcf491d66ad863b138e33900ed9ac67b1ae988ca7b8bd412949d3af75ab902f774a6938ff7b7db9a7f3fc80079e065a8fa57627e925c0aa85079f4fc25de5367f7eaa94cb05a4e797667fb0062d4ccf8530ac85699868a8f839fa41078d7e6fe69ba9b9291a71f4db582d400007824582b56652b5ac414f9fc98d58f861c455d544288b273f1bab5521b1000cfe609a2a46bd385edb58a1ee038e3b5cb412729fb087817fb8b3b25f0989c009db4b9e352adc1ebfab5d83fb3c383a806ad67adc3958d921df175b0e659ff00841e40eeeaa48299ce4f65068aa986c8553fb60ea7bb6e72c88e8f5cba9b650076b993299b5397ef75c9f76d299f82f367cfc3f65e36bbaa24a79b05292bd200b9ceb09b9baac51ed103672d6a77df47931d2a3db79a2b39a482c41e7899af00151791370a36392803a7bcf2d8e68776e72df8bd5c366e6be51a35163dfbde0089f02d064e2ce35bcf33de3b372c3b422093d2610681ce14647a926398485600d9698c40501a4cdf35b174854c3f35875326686a8caccd1a23ae122f85dfec00060300181aa4f2b78fbf63514b6d04f7f2240e5827889d8c1613cbe9726f8d00e090a1ccedd383f720647414bff0fea24c3e0221110e3cb7791b00c1ee75b900d05545be39be1dd926e2d4f2c5ba5f3f54f3ab18a66a1fe779c544670a2cff0032f911441d9f203e331150e250dc767436d8674d110bdb0d22a9010ab61e2d00a2b19ce4d65b07ea7942be7da1b17e0cd856f60f3eb02cce049a0d7680844f004731a67f6907b5414295133c1bad72c3267908d5571933d06c5b65959a4310006031e8ebb3d155397f2d3c45b93041f8dd8f377b83d9d0502d76a83545008700ec0b369097fc831a46e8d9243c4d29135d421533296e56980d55f571237ccd004073c43cd76ab02817726e3f007e45189cf9875d9e5569a5dd3618d4237ed7006834ecc55bbc35f6c24fb99473544deccca2528112abedc3db812ea20c085000754c780fd702843af9e51c5ac134204ebaf031f8147610ec4167f8d9623b3f00a6824b754095e00b34ff1128ea16d8f17581c90beabf177d53cd2eb516747e00015728f5c4593a868b054b0321b1bc224b12da72c02be7d6172f1f8e2664c8007fa82de8e81061930cab8fafcd68009ac460e2a0a69a3b7908979e960039a2009a9089e875e4a91820fb1ae82cd9ea9448c1d806277c2c1ebddd664e9ac06c00e82bc4015e68ff5818e8a8ec8ff7fa69843488810b470fa38ab4dccac72126004d820fb2b3920d1cc372db87fb37180dbfa09348a0741049f41757ae4b55680037dfb32addaaa5e5b29bbb556fe93a5600ec050997d4a71c45654f3bf1bd2300444282f2a672e3e3f88079e53cb097dc921c7b46a611141007227850d3bc220078ac9d472ef8a7bf06b5c9699670f549f46bd06ce2976b7ae790a7c224a8d300f84d2e3ae51a8133bd88918672c4f334002b8a8505b54a580dc13d19ceb91000898761f0281eaca1b903fa3f1323436f25ba6d6da14bbb1fb2339323493f8a00672682b2bc8a38811dc10e5bb4158916066f6ddfcec9765dc1384f64ffe3130090337ffe4721af1efe13d9de23183315b3544d07d6bd731bba86cf705008ee0057f9bec28e112cae8089c6aaf2fe05becbfd94171757c82c44e7c556a26d980064d6c9c301292a593300a27ea106c35c7ee0184516eadb310b2365e704fce900745349f7f26a351b46c2ab70416b38d59276a1968be7e5b7d442578198c017003a30a9892cb23b75a449d9ed930fc7275e0a4d057ce4757e8311732d251735009d3fa7b40207adb23e2a6a375ec6cc3ac92d24bb77a611aa20272e008c6f7600a6d2ccf5a2a0dc8abb1b75ec2199a7fc561a194f5c4ac60832544ba7f4f83900765ef6df166fb74640888698e7e6f775991bee8da901826686276bb47cf82000e507abbc5823b36e6d96daca390b1c6b02c964259cd40ccfe614b8f00d4ac3006636f8c7d51d311b66ef6469107f33f879956fce79f016fc4f6afa7c33255a00abbcf969e43e99f30f8c01092608a43606752a4c3e3f5bb61a71182dacb93800f9e7af08ebf9ecf754550eb1aed9973d581729a0b8ad594a92003e097696d2004100c7b6e34a44fabec44855b76fcffd873222fc3bc7998e6888f88203e89900180d7dc5dab82cc5bf9e76b9cf27d6e0f9719860cb6524f04d3964359fd9ae00c73da4111b002c7b12c504d04e17dc2f688f5180a00242915781503580872e00925d885a4ee43bcdcd7074ef05599924290bdd141b960300ce706bed584892006e62a779a65f959a21ffaba8b15e802a9c9a8487ed001cbdadbadaeab4280100e11d018bf48402c4e3a4e1171957678438b33d796feeb56cb3d0b66939397900b02058a7ed6db2526799a95e665e373b7c4e78e0cc30f66cb39e4d05396161007903a00270463eeb6b1f585d352dc9eb38b71f4991b3c6afa69bbe5d6e589400adeae99a2c1bb760a12ee565f335a7c537c3cc4f7b79fb389975895046d487002828b27a09483185bf715af55ab2005dcf9a08697fd9bdb03962f8171f63d900cc0335744cc1d655007c2eaa336744fcffb6315aa6e1d21db0268a86b24ef200ef24e092ddf7222806c400ebb1b893b903b0e7ea5edf71b68bc321ebfbb84f003dcea48eeac0675302f185a9a96782c356bb63c955a32425a9b7198d131dd500fecf1483f57720d7e7ae631008c037680401a3582ba82d8cbef919049d23d100144b7886531c24d3f68ac1f403926c8ff4dcc199e9d4be4494fd0b4271248300d784308c63c278c0038de00cf6bfc4bc9f0ca31b9e6fc3298111d3538c0f3b00ba5aafea99180de5a1236e6bd6b8505c1efbb5b439afe0158837cab5891abf0028c11a9c562ffe28fd49236afa820cbe17b8d47bc6839893078a153a492ceb00d5f93c8b995946534f1300246fd96026f1218d23adcfbf4887e4461c63d10500e4dff1364aac47e04a93ea6ecc71a23b1862139c424df4247c7c52a7d067670085038d8dbfba08a8e06e2232df31b22ac7d6d4d4999c52baa0a14880869b1e006e3ec2b3839caaf48e38bcc82aafeca604748917bb1a8ad61b7a37e61ab9d1001e15645c63c25bf10007e3c8bf02fc4d27830e4b18b099c5469422b28e04b5002c73398c97ce1fc15ca80302026a20aed4eb95ec421d251ad1a659954cf081004f12a29227a1081fcfb4a98a58c09589ccddb24125ce7e880bc89512b044840015af0ccf63ca0bd302a572cefb6aac4d5b30a2da261f3523d792b38bc116b8000d814a20baf2ee7e4fa44d8a548f9ec9af4beae392e3b07db70d827086c602009aba3bdc8447414b30556cc78b738adb5f880f24fc899663210344dc1a58f600dfcdf14054689e2c4980a78ed05665f1134f608065f22099734b1e142f5cdc000f888e1f02e0cbbb6a782243ea41673dac89e41829a7b57115422bd6ec5dd9002914413fafc501c8ab3fd83c4f7855693843437cc6d0817ccb83b08e7a7e700006be38dc94fa27a2cf9eb3bd45d4a39b3e988354cd94c607883efe2f5fa64d00d28c5c58fd742ab6b5b91a1000cac984f16a0b433ec294b1e23418f6f1c14c00b544abddc22342989bf139ae026993701ee7de9e1eac762616a1374d4f40fe00509bc74a780a80807de73ebaa5057e0124415d78526ebf35e9d3854b0c9021000e795f1e51f7344f15735ea73042e651bbf7837fc0056af2cd9f28289c7d4f00dd27e9636f7a9ba92860484254cca2b386443c002d17598bb0624898879dbb00740ac676a866a4b1b80836ea119d7c6d8dcb25a91297ddcff1b52535ab73f700eb9d737a6e85c67875a1e7adf7533d6291161ccf0f21d498e27509b4d1b67f0039101eec243172a2d2d98ba0d87762bbb91ee1fb7a9ac6f767216e969f385100131210399f9e45f12c88f6f44c3f6d3430dc950dc948d32c9f0dcbf866904f00b46b155d6f0dfb57b902c5f0c911d83aec3c41010eef03b499a4d541d07bc6007132b3257807e243628567b2d4f370923bafcda876b45f820dcb872e3e0b4a0032935d5dea13101b68b27fc2906777251bcc07840c6df6d31cb659556f022f004ea636c0a4b14f0f1f4a152fd42440c99de99c0f0748c78a4dfa2c7829380f0084156695e2072c4c9fdadd21e45e24a1e70a35da99dfb64c7154a8512c99e900965ab92106d30d965fbbe8e3dfa8a068650d5951c6f240d15763e554934bc70057a0499e19cff20af139a8701f186c6d4d4751ac5f55995f7539d8dc40fb9b0009971c3c34d5ee95f65a2c08149555169fefebbf4fd853d95d809da7a827a3008b18197b97258180449d6855b77a5f8c4e7f2355a06a4082d330ad186eaf5900ca2f15f3aa10deaee710252c45e94ba65c0d0ee57a6c2eda8b5180406ce94d003f08ae2ae3efd740d61ae06a14d0213dd473eed9027f765e3f9130056d3a3200f0adfa1898fd0f677d8963b04bca7c8f229b52f8444d6b2e6d513d69a31782000e7dbbee11032e44a6a8bab5f27377b70efc1efaa211efcaa26476fa05bd8400b5f763c01ab74bff7dba5a2c3a13a3e8751a26c9cefb70f1525a60893c309600a2842564c742e5f03e1780916e41858be7b35e93eb2a2e60eb381346e1362d006a768e112b03d9192581c2dba7ad7ae434a08860cc3e8fa104287bcaf7b0c700a7e9ccf6c60b96701bff3630225336551cbd2e9b09e028dba6a3ea83b3381a005dfb0fe5e61c4888d804688fac9a09956706e68a1b8fbfd19d6bde233ab7c700f4789f42bb586cbd5675146573f151b00e9870b51c097df5df254ae0aac7ea000ae9916806a0b301bb6c3f04da554e8585895b515eac964976a62e9be523ed00596d654b99bec9ff5df9e8106209673bd2dca82149f820e1057f638ef6ce8a008195f7539c6d4e08cad761e23a52c62fb8490d3c6869bb11adb8dbe1ae2dc1007c9d24c2f3ac6557fd22b57cd868603fbd723b95a85e6547e3df956b54ae48001c89caafb2358be58922a882eea7e53ed83cb661b7a3bde455ff296d125744006bfb1a63abdb42ba4c0fa4012def2d370eaef5c391d8563e6288e8a75cce5f00104a9cca0e02b28a07039f867742cc22f736eff8c5ba4fe7a0e67a8b15eb200029b426b43df500450257e0bdde19d0a735642e46f12361be5800725bacfe1a00d96048bf87be7f1817c32f76d854d06f2ba0a2b9984a243614275ed4f348a2005dea55e104ab3b27aea121c8d4d276051de3d1269643418b49a1af982176930069257ddfb79d8e7d787e74ad33a60127af80b481751a35d676b049b5b566d0002d2e66aae73424683d99b01856956953c4a0d764e36465dd59d1afca7191fe00b565955998f154ffc8918541b5eb2f3927954e62981a528b744741182382f80034625bd97d24fc5eb890709b1e37da924ebd0e22236ce51a65266c1379292400e76f4546a12c3124ab91edd82a7284e057e796320540741a2fd7aa512b7b7200773972653b364c856854ebbdaa147a792e78b721d0f4d547d4530bc11d7cf2006f27822cebdf99d0be1e650b3302947fcbe3313cb3b2448e8f712690c18738000474a5fcd69252b2e2048fe4945b72e6c584175731637dd26c95ea36bdf09000f7652a8c52edef6892e7ee061d5db5772882a0d690e25ce218fa4e216f736b00bc6e7128e1d3df7dcfc44eb8eec21aaed554e307c20eed240facb3309ababe00de835b7cf77b31b1c49265488d23d8249188af4271cbda3795f14d7d4070fc00e71fd8a0c9b0d32839d967d0443287c5ec4401f6a815924f1d0005a4db453500d8049998b79545f7d53797ae3cf0bb0acbda9a66291d00acfb4daa3b02d993007f906d14d9904fb8ef050fd06796ed51bab76934a5e8e48a2ead6f0477cfd600eac83f29724a7e90f1416ef1d19467423f3ed40e47a47420350db02550c96c00ced7854941f288a2f36a11d5443e3cc683ca84b350c42417609ab51e3186250056580b5c6ddc17e3e91c1ef2f210a665d3bed8d6e493303811c776e919fdca000c85d649f97dc6a6a353c0b385e1c630a326c747ed38c1de88b2991bfc5819006953c0b4597d4f69cc2d11aa1afa8eb05b66d77d8baec7b70de2fca90039c900b380c4daec4da6ec1ed9280c6b7afffaef20e2e5b7fb07147114a8dbfe53b3000bc5c32cc762df9231194e2cb9d3a6db11ea031373097ce9a9e2236f2e1d87005c5d8694ce36b968b1dd8f48eadf78810b101747162cebce9c7f92e9d42d770095fcb87ea08fa8e50d5097264de5f05f5a8b81a93ac5e08e1d9bd98d8dbb3700c126a35436487df2b411ace2a2a082beefa4a71ec71df12085a1fb4971117f00d2d47a4f7212fb7a2b19f35beb67c13aad50be7f86e250e02a6545fc0065d100e1bba963a81c12a552a8a3b7954b85bedcea7ba61422f52deeb0a363022f7900adebb7bd6fc01f2223910de74c2a8eaa95c2186aad1998aa7898da502954a300a07e5c1d0cd089aa07644b57eb3ddc239240aed37d4be8442a86b660ab3cba00f97240a79beace30007e00aae410cbcf01a5ae01cffdeded2c69313314179a001fc6edb003313030a4d677b246fca0961cdb3d8cd35515e97224686f70ba2300a934737e39293c702ea49f53b5949d506209d23d08ad9e5ed9845d0849c2f3006c5a66e27fe9c6db15a4405c567cff3901b50a0e06cca6dd85b07a0ae152b70077422e854c6b7274398a814f191fc9b40c9f031cb4e984132f60c9af59667f0084227265199070d509251e734df5a9a51ef1edd4015cecd05eb8e70174723800c33408aef2f0d2fd7f4f6f8df8ec9fd3a143ac58c2c0bee64ba61fb73e7bfb00367531fdbc41ee57ad99cb6ec97e6bb73f620c3360477e4987170532f59c0e003a5e24933914dd1a33142e35fbf48c06430ce3ab14f6599c933840bffda5ab000b925a71c3f1da381034fe09ee00726d74b78f8cb88e4e2a2038b98e05718f0078438b598794a9c78b503798096f15aa50bfc0184805f99d855ccfb9dcfddb006ef99a8a2cfa0ffce006522ff1dd55b4cd4ebdeff262869040509134820fcc009d11641ef5e981c394ceb504761ce1a845c3a96f2a0c969a149c392dd6ce87002e5fb9d80dc0f652ad2f4e48b81f42742643208c6acbd5481feabd15841eab003b9f97ece1c4760cb5a93b040caa99948f35db05dd3df60ab84685c7967282004f608b9ea1f87746068f0d116af15f944f367f2fb7daa081cd6a1a7bc74d8d00f10bb853a4e6469bf08df24af7dd2f4c0b13be39e305abf6869a9f74bcd1ac00c0a202dc8d61a335963582f309d76a4ba1a14dc5f687ada35d91263dc31877008626b1a64901b4bf7667eae76801fa12243a8fc9b357d10b1efe805099cdf3001bf4068f022d4ef635f814545374e0fb41d014bb0a93add598ebe3f15c46d8008c22cd184f0c1cd998043f56dafc8ed6c7651d963ff00653c3b3784b390d8500193922529cd3827291c748419fb84be67ac9c5ce0ac71a5926e95a2d6c0ab600b03be69ab46ee460ea6aab7f39aeb0c2c24fac9439678cff48ce90ade2c0f5009ed725bd7285073ac25b08a896455b3395b9accb4e74c57208e567b298895d003513e9471f806fda0fbf2ac8334f336b1a0c24f31f26bde1a820102b166ba400f1d02e0842d64cb57411efb8170cdbe6e5e98bd0ed52fb77f527e269174ffd00c4f2bf580c636cfaabb9549489f295a7c55b2623f35d8753ac18f88074282f00636d8a3d734e997f14ec867ec7ea7c301e44708f454b95438acd1c586fe8ec00cf1ab9624605edcdbc6e122b1a501b8d1220f01dd12c6d0f6c5c8b8f7e49af00a0f7efd4541a96171e941cb8f80501344c3a9d968313987e16166f285890d000cd0463753cb3abaca74390a0cb8b729f8f413e3b22ea157065ddf262136ec1007f8a920d05fc1c73250049c7f42ec1bde37415371635d0b278ac96fcd7f17f009680078e0f6b7c24030fbb33f7d87ba13fed9b055dd4615cc4b4de919485b4000e8fb049d3be422897b152958e1d0fe6c9c596ec8fe05c4722fccad68065690020cb71d0c7814b1514b6c506e03142741ee6a07a898b629d607b2560d9d05b0004d1ad5dd5b49a30ac8efa39a8758aec731581ef232b1d81215b609287057100288dadd43957b651573920a2d8e723dcb447872cfc55e520e7fc6c75ad2522006530535369792508ef12c18e3770b6a716694eef3ac5159cc9c336fcf2cc6100998b297f3b0daf917a898abac8b73cfc6078a5b661b113a577c75b543481c80018b45ccf0d4a8ab5c8e2f6a32f2f3b7d20645c04b370297df163f082511d5400461d2fee6cf035893dee544e35019a74783f256b53b8efab547d5be54d708d00b057f1cfb05869ef9f15172c21ab07268c5db16ac0822faf6c754644e46cbd002d54fa93eb63c0ddbe69c5053b8cad4e6af02c16adbb3e4cb2f1212da4f85200e2731a5deaa3a26dfbd43ccd98024669320295e93bbedbc9a671e29ac82a25003fecadbdcf25901f03447597e46a91861119e868d432119f81088e081e3389003b3d8c759e5927a25b6e09edfd7074bc24657d16f00122498c3a0cc83c7421000f1a31b801b69f12b7175c7d541c5824d4a64542155300fea8a5e850c0bfaf003d93946ac90787ca2fb55e0274edb26545f15627eb879701054af917f173fc003230ccdcfc9c5d22189c4519e16b0a7b3098a2d3d841382771a73622bcb86200e781962aa4c1dc621b2d2621d2c2e880f7476fa207281a44f0c458c2a9b358007876b46f1780f12b12f32fca315e50293fd3df6efa682c5f9f784dc7e8d73b00caa54fe186a00c5171b115e16b81bfeac5cfd37169b3af80a11d554092b39d00811e375e36806b2729592df84a527e3ce6700fdc18bec21add429c71cdbb63007e4b31ae1de293ba95f29d0447c00d964af6f5eb055cff76242dfa8fa9c7d60086f0fc21679d573446b9b46e5d59d5290d7b4c19508b21b795420813a480c4005cc5839fb235f6451627117876dfccee56a517fff6d75d48ecdf2105b3103200e5cc25107c15679eab78d59079575f90e79f2ac1a83b3178e371fce1358088006696606564e4d45da3241e563865f2a2357d6ad0563b15da27780bce9c862400e663fe5492491facb1ce62dba240b04282ca282cf2478434a64c2b37f8b414001653517c46c186891d37ec7ed75974d8bb896314a1c63cd2006593ff1e08e500e48183bece77a4efaa6db6a973eb06021ed84e937f9b3fb94465543ef12f86009ea670225b8d2a2942dc7d3edee3b46ecc0989abc183d03cb967cb98d9979400bb7e3dfa33394779cccd9efc340d3bd661e7d3e5917624cdc36ef98b67fbf100c3d3b6fccee90c253db48d70a9b6906a30a3d12daa33ac0ac05e5128939d9b00fb94717e9b05a289efaf7745ca9c48bdaaa269f7921c6aa08fa95fdab61f2700c611d607f00e26e1babb7a19aca437a480bc1353db85d8a8a1b3b26279e17100469e82ef7c1548c74d3557723529962ff589e4b416d5ab3181adb190bc4cd000b743c828e18169f9c5748cbcd9483f429e347ddcb99de34b0315a967b2387100b87ae36628f7d8dab0de83a457e0116506f0ede88eb57d9295d5aecb90536600c8e941ed035645e104c573d8f21bbbc03a9f8e92c02ba5df19f6525611a2e000f8831d6bc7213e885356419876770b20a090f440d14448d8ee0b902bd4927d00aad5caa35e0e440eff21c49793177f883cbd30bd05c15bcc12096c160dc1b500d4e9f7b8c201bc792ee1fd7b9f1205e982cff4106ebb93d1d1c2513df431c100101f4ff826d556a7ab20d9d165e7a6b536b9bd7357db0ea11c97c8d4df426500d8df84fc5e894dcb3ffb6e8c5793736509ad639ba2c7ba7e258594e86e92a200e62f5474cbb2fb0cc56d6e8aca52792e12244040af34237edc239e5883e7bf00267204ac363f2fa9fc5564f034742a0093aaafd10a12a7fd68bf3fe1ece2b300ebb1771b608525aaa2ec4be93bccd6b6d5a7c3c79835559cc1624cc4c8fc0f000e8d498a30e5cfe9e7cf66ec871ecdb29230e9f36150ba184dd41d835bbca00053f2858e9613fad541a921a5506283cb6b45b409b40703aa8e1853f054f8a2002c496f8b6b50efefdf762b22c581aefaf0687139a196a30a01bfc45958ee94001881ce19b032ef2f3571b1826ac9a58599e4afd8e5c71eeed32efb371b7866007beab5d88029e319f65eb8fd527b7e36dfadf44e3b4f9a294b5409d9332ca900869ad538e05ebbc621246872dc39e490256294c4588898c124243e4ad19e2b00c32e68aa94123ebca1e6e517956112bdf17593cd733c39013ff8a4fb9abe80001ec021d52440163dfddcd70a9091a90f11a1669b38be28270d24a55f54079000a811cc7d6b5eddb1e7a13fe95c0519bd08ba7c60c319c3ef04efece94ab4f300ed7caa15c638461c2240d4286a01e149809cf77cef907e1c64639c73657bbb005ba5ba89eecfc77f5fc3cf2875d120775bcd01152ea813c75cdda30dde27ee0026440f96849701aafd6f658d2618f6e464ebfc9455fc6b495b5c0a5711f38400e4ce0f96f52ee9736c9438b66116bb0c161aeaa15af7db9b43fe567b7007c300341a1443c6831b111d97decc671d683a618743bf7abf54dce33cfa17c1aef70018c5618b9515c1803f58a58f5c6278623b44661bb5b201742083ecbb92a8ca003ba4534c69e2838cb859568101b5fd490c9855b1f840105863715df61cf83e00b49676b62dbf26537458a100ab755103125cab7c09a5bac3342ddadce4e7730054f6f81c0b6c6ad7ce7e016dcf822b8f060109d123004f57d41db1d4ca91340042e1bfb4720ed245722db04f04b0e728b5f8618d7f3226bbb04b09a44177db001e8a9f21c6b0aa9aceef7330e20777bc32fc127fc03b4bafa69b0465d30a7700265cd8abb5a799a4d9bad3ec956f39435c01d930240f4ae6b3b317c6a51e88008a205ad517ee0aff5de362446dd43ccd7a3fde36cd93bf3ed093b4b0119f1f0095a4e05a50a70a4deec449fbcb940d76ecc6ad91ea211a3ae1183f1a8cd8fb00e76c77a234d2e4387a38486e57d9e05516b6adf23e17d0da21bd472984f03600d5c2ec4ce4ed914df8f970c41983a1c5472926e80067b83ad011bb137f322f008d1b733d6ad1c5dc5ea32c270e25f3fe50ad607673af9006b113a0568fe97000e3c813c16544c7ea102735e8a768f95ae6daf5398752cc572ea892725a775d007810df22811f810a96aec5e9f528e8eed908201d6555391d8f4cf2adf3c17500579191155bb99720a292481eedac6b432d0f33d833a26263248efd0a8cf51f002534c93f8b39e605bed81fab36e2c6ad89bbb126a09cbc176a33a50b721e8200c0321e2e54e3e52f625913ca5a77b77912f6f0178f764723a75269ece087d9002e26e009b2acafba84f850f896adaf37d710942b42a23a05ba56cff00c6218003c82a4fdd1a925d1a8b1c58a994c122794d9881b8d7553ea439ad76e5f6c8800afadbbf2936a5e2045d1ee7a1ec5b475e1e6b7d68f72f8f567d0060e76990b002e117718f97571a369412d19daeeb8bb030558cea584322b02ce2f0517deda003eb05505204ef7eadb2beb9fd505db149d37fe243aa86f0a0789ef8cebcafa00860ebe0f65ad756a3643aab0a6a72b1d54d71cf9dfdc7db59b05dd2b207f3d00d3c85d33735ce7dcbfab27acc7cd449fa3de4ef59ffa05bde158f75029d47f00461aa36c9ee9644ca1d00e58e7cf5f8c3209e757583a0ac55e7a7b4a96ea6f00fc114d72b42684275c56129a64c13b19c4208dc2152464960c31e243a150440063053b9c5bc1255e15fbb9e5c0fa5b78d2cd8950d93cf4ba61c85b65add17400a8475f1ccc4b8521e5f4e511f4199408646701ac343d9acbec0b50c7ccc11400f6d92abb0c67697c70897bdefcec6aec6805621ad1a5a1ed44396c8cf83e6a004f62ffb1d08daeb10c9d8be9e80fb2b95e9e2d761e06644ba8920275c5563700793d676788b3eed9c3831aa864e734e6c6abc26d50a2ae70c13334df663a6400dc216b72d729cbb0b53c4ce179f3a4e629822878d477bda9b71d649130f00e00d7f26618774aae32104da4c49d2db37d53bd6491cd2f2f98d07ac92d5913a8006607d85471ae7965e15f01f090bef118a7d665fcb428314eb5397b372800b400bc87948009e02c3666a9ed307daa76d45486adb0e2d90caa1d0855c7e6a62e00a78d045a028c12ad6f7b729893be3091c29b8c3363f61392915461b51ad5e7009e696948db154d215f11b98a9b5495bceea0ef9c7f2781fb10d8b95915419900803a66b1c01bd9dde2495f14b6b4312df9ffeeb99050c7014cad39c43728c90031a633b2105467f849fe217c4f2600a25fe3381b4e73ca711a7f27c54ea1de00379a482d8b90ef15adf107ef712f26c83e6b71cbf4aa1f94461d1d6d1c88d20041554de0254c9651912a9284f6e93d7840d2063d69259b10c43aaa2133fd5700efaf313fc9c2fc8c7af27021181581513aaaa4daf135c941ef5e040e558659009e8156eac49e62d9ab78615b3fc9afc5cbdfd3d78822b4df3525c8cef3bcaa00826f17fe44e0abe618369894d00af7945138c5700322f68d494a48c665f5ff0046fac2c86571bc1b9516d40c39e9124627b6c28f53834911d940cf34328405009bbb97edef5a8827512802b400b2fcccb9eb22a1c063117baafad1a932300100e7d4e7b8ffbd6e0914cc4e1ad9e8d60b9a9b256cd98e18a61188dfe77c607f00a328f17886aa1d49ccbec4ed10d1356f9292edd639fa28241fe8fdde3fc0cb0096bf40eed1d4697c530ed8180518f8e6e8b6959fa1904f8097bd9c9d444f9300851e5c958a2606fa0e010c07f3f94d177534efbfe03262129d8f1f225156e10092d43217bad2eb325d5707c642fbaf8202f2a34a146e5a3bac846a49875ff200c707381f5eb592370508e5410033f6620948027caeab07d35396039330b96500d7a8bdbf936686dcf8919c2724b3a6003e3d11ce1cb17b8a4ffe8c07c8ede30080775ac7cfd6e54f24359a16973079953f1b8111b6560ee69ba2c5f79b41680021261bcf2409eb528efb2d2a686091c60398e9921367646e9ce99db177fca40057bc3cd7a68c256fb56d514fcabc5d0098337099f77a6c6d7433e1c4db677300b505cd4cdcec07116ca962dcdbdba331104b1f1338ebb30b10657b732aa4d100e59fb5aaa577d6491f7420b4dcb91c56ea2480f73dbaf190672e76a9044ead00b77dee03cb8c7f8452e43d890aa39d6d5e697166fa994c354a270638e5954e00abbbc7490edfc172df96f938d3caef5b441bad79bebaf0b05d5f9ec3a8aed40049d914a11304b942b4220317acfcd0150477f38ab596855c15f1f84b8197cc009ef5526356055a2634539eeb41d83329f231fa76f0c1d3ca70fa19829d334200d1111ce3c11e3f7791f9d6100d218c43d1b409de37c5c3ab97a0bc05cce3d100ee09db8c4a00f937a88ee63b7cdbaf7513a4074093e5a8a60f933c2318fc3000db7dac3df04aad26edc28073056079e6a91fb6d3e78858ddc143eeaa034fab00c9c3636acb5a3f76859ddf5cea3fdf990b25483456c478bad13cfee5d7d5fd00aa8675bed21ad84281c3640683d2bbcdd7e5c76abe2092a6641b159e69cb4300ac963b06a11133b115a0d143745546fc1d4b4fcf3a06ab7be0b50a7d93171900227b086905dabad6863aade5f8892ef7fb84c2863d82f4ba7c9ce94cb4e8920080166f5c4107d4405fc33dc6584cedc67e5a8e29fb6f45748fccbe9d28bfa700c61b217d779e5f6ee3c617ac552a89a014eeb2fabb93d87d216a87d1af2d57008d6cb919de4b07fc4707d4e11d6681fb91cb84fe686c2389131cc6806c8b7e00cec85c4f4f2a36b8800e1c2a81979d9b1c744697e942ef84e4550598fa312400e56b77bd4e04f8b5563c0f9f42f635cdf15ff6a7de69686190130235ba77680065846362924f87e1f91c0eacff646c32b4886a3e0b2666dad46b8a201f5400009bd528be8c15bf2bb3e865893a34ff9326a90ebdc8dd9e0bd883cfb00415ca002ebc5ef33362ee79e745ee2111af8bb39f2845c73be7c2cf40da97a8ca95da00dd10596811c8afc8f1251ddcd16860b6ab21e288ddc54245354f4206fb31b300eebd1e2c28a757b7faa08eaa79ef1ede206f841d4d273d70451c4027e0ae8d00ad8ce393d360d0136fc89aa579b0aec8d6cf53996284f2507ac4a0955a4db800353e9e71e19cd529186008df653113aad1e7c9bade2e98cba32c71bd2fb46600a4d6f7ec3a02d532d35f3e2d8322c87bc5b63e490aaf2c3b4596eb108db5e100714f2f150fb88996b8afdef7a38ee14e521e02c8a1dbb37ddc6f75f3bf4bf800b2eb345b033e5caf538a6ba550ba0dd9d4bb46fbcaee3c32a6be8d725b2aed009572eb84bbd9ac752637d42312e9355b398c31d25c18ea755f03062c7e703a0080b45c302da55e21ffc8457770eba6ad2cca27eb30b1e86289b037729630dd00a6e3bd88c0179f4935539df93d841e17bf54db446d34a168d7cd87d0f5a82400bdd869f593c3b91d1bfc249b6d0215fb19d2ff371c7287b042db6ea10c8e8a001ec4cf24e760069dd1df7e11390d369f3805509a40ef962674049a7279629000f3f881bbf0abdea207c366e2a3bd893b47572cb4748a767eb2fed1b2f4327800e4b9e823e7dc4588e2d967e5028e479d1a245429921fa4c7cebc677bb633be00439503697354b571af913166a6e32ed777c9849e46be39fcc0b74d0857974e00162307309569181339bedf8f826a2d626c21f0baf3cdbed2f93ce160069fcd005d43e34a008ce1a5628739520b26a075585615e4460847ac85ca12474524dd00bf56fe7eba039d6d3be50fb6f4a1afe16572f54b3804520ae65f73c018197b00c2a36de83675fd25d6000b12a08533dc172cd560f7d5236969ee6ce482fca80087374703ccef966da3fd776c91a8258a2f5402ac1775e683f564b1b4af7a740002135891e933eb9ba42edf00eb35a66b1d770c6cdd9a0f1136495c68c3a2a8003dc1daadd4f36f4346a084396f5b0db2b6cee3eb60396bf8178bb46b13432300b02d629072d398c5425aae5acaf3168611f6b419c41ca18c56b9f5cba1bdcf00c70475bd665381ba526d158913157f71f2a2916513be35c98eab54e77cadb300cf77de60edf33b487119b5c9e826b21a3e9662d211b96dc96f4f82c81e23eb0035172f05527a237711310e7af229251692e402101f6b7546f585a4abf3c007002315cd3df3191c03680b1742a4a8857f661a54770ba2106a380c9131f50e33007e85a29dc79da4e121b4d6bf6f08536a6510ad653a65cace86dce94987820100e22cb142b475d1d958d1b0bdc6e05aac9ddf1b26f94ea26ae257b2f4bd1a790036a45f6bba31233edfb4a2be0dfca9d5a06b356d9949817604462c8eede1a200423545229321efd271dbcf14066ee121eae11ce70dbf7f4af7619493b4ad07002a0499fb059f63fbcb716b53f9a6b6b3e144a8894c42392be70c40a2fa84cd005a8600d4060d43bc61de5f14bbe482f184936270bf21671d45bc674c7b957d00316ffc5127638eeb608166e34ad8d097eed516cdffb26324c557077720c38c00da0d02b0ca0642519ff7189a9005c51f3526d046f1c47f9f841e75afac2cb0007c248beeb49e3c89bf279594de82cc7729f66af6e448468a4070e9dd64f9850083c15680811b3c22b5916cc8fb9c08bcc22f14bb6df964dd6697584704de91009d0b4c08f0bac162cf56cc3b7fc4b2b59929a9d22f4fac939cf3efbf629aff005d3724d049f4caf18bce39bf2deb73477f02703a9a699be3466b0b99d126cd00b1060a0c562b3ef83ba76635303e0b54b5beee48f0c0fa0f320aabf549e62800e0b7ff4dc6059a9834c30ff9a5c2db971fd867d299975d1b9086601441525f00b8980fe4354d92593cfdb067adb031d98d67c35074ed70d31002c1934b58a800c181e274be10d69917c80df4fec16795dcc2a0ed305e360298097cb0426758008797002a39409d19e83576eda9b9b9cd374bd7bc6d3f49cc4b4f40bc23710400a583681602c6d7aa4f3806e1812604f0da3f596fe6d7771e81d5d98810eab100fb315e0e41670975c5fed684a34557c36d9eab14a09d76261960813e29ca92001f194a5277d5b2ac3f273e6639c0517d33ff95484b47c9aa2658f47e94dc120022635526cd8a97df73c6baac69df20cd2d6a323167b6e6cf6df60cd86773c90033f619406573e85feb4d0e570a719f7377ff4948195cc7b18dc3a7d44a64f900b088c3e8d112a5bc94608d6042b2367687479119eb8e683312f619c7eaa5260083f6792ca9ba9011fdd6c51d093d54d106170b00f622fd5c592fbe690440930023f8caa4749d868e0576678eebebf3c3ec3879afad8d90cabce1e9ecc9134d006f041d149085eb49178a745c6c3bc78bd8f4b850a24cba0d99fee010f4cc2300a970a47f6f0b50c25b1d6e6c74174011509dfa3a98c135663d7ef2bceab4d80068f313b71f3c4374322f0fcc899d98a0ab868dad4e6a7f145e78b0f3f46c2300a1616590f769baa7591966d6af64e26f4ad06a31dccafc5cdb243eb599d7f800c8c67196ae0da8fd282db4b15da3a00c5db841ed5026a8bbc57e0857fdc452001ea39ecbc70389a5fb94fdc2bd052a1bf430d932082882d66a529d749749bd0044503ea30983cb353da61d62550f1f6e4359ae257f95d05dcdac8240e20b4500568c653de695792db165281e0f0707616554577ac0c390fbe0ed42653db0be00a1d77bcaaba0908ebab2e5af4e50d68ace7277da8e8d6bca6bd93eadb129a200d3d8cdc554169710292cbc494410817b1c2c6beba17fce47b88645c1c7df6c00b3344942d2437c325d822b6b991d4daa0605d1f11126aa51fcb763b422c17100840c51bbbdac1125f1151748bd04f377fe55eb1ac46b4373fcee007170b3b1006c9530b53c1826a7fd1c5cafe57dec97c5ec15f2b479adb9aa4ef05aae3eb1001f89dce351d58dc3047ba8363bb022cb67d99ea56aa5f82df233cd686cd7cb000e3b94915633861154fe9a73545af5623e4150b4dd3cccf5389c2b127de601006b1d69a451153d3419d02c8dcfd142428b1adb72813283def2dd99b33ce4980091c2970076c5a263323f0ad2da19ebf5519ef8f7e2c291b9e5bf523692589f0098b3fc9bc7e8c541f435e2c93ec005b561378436fdd1136ab6d56967dbe8c40033a1b7623a7118dadd7bb304a7efca6c5b7c142144902dfc1b293fa31dff3100a02b4a37210480e9e09f9281e863fe5f6ca7f3c0b5e4a03f1ebd8ded7131c600e47de7a01e43bd8e2d0d1f2c56469da2f3f37c120a0fe3d6bf5e61ff54646e0062c7042fc4fd1a5899f820b724b97cbf5b2b6609daff3a158356661718c97c002c6901931edd5b4032bef53cc1505838fe5de70cbb1f84fcee859549e9a99c00d3955f3ea19c88029389dee05e9972296439092fdfc87d2cae2ced5eb0158800cdc284bddb4ca98bc09613a28717069bb523ea3200e09e08c9a5133e86419d006ae5c9367af7846bb192f6038eb76bba889e2ded2bcd431bccd97a7fd48ef400fd57922e41cad19b95cbdbc6fb8b73a8881d4cb547c20b2571e6a19358cc30000ffb70ff3bf77a249f2a61a7c82c8bf0c1e76e719c93b36f8e40d6e7e5a7ef00575000953d811f28d11bcdac5801adadf331f2c8ef9229d52433d20b599e99007299a2d62484548623fe96624df2ef9aa8fd4a85454fe3d371f06d6ed70dfc00ff7600217f19cb7ad846084777cf5558d1da3cf43f17d59dd1946cd18d16c0008dce9dbb8c013382d9ddf55514d30c7d08b04e20883033c65b0ef9270b391100b6365c7fc377948ea8c9cc9db02914ec37d44ea0e39a0c86506f0d0d11697200a58e3fd6187919e4cdd4f75f9a46f3abd7fd9c217c4cee6f3907eb51c7f497009c43927b98e539dc4a4eab907b6a13709defd0bd725cd10f35ea53e3559880003b7606301205018b838338fd727520f08a5b7a548ab9c67037c289324bb11200aa1dcb210a8ae8979a0592c5563682092dab52c09b549c49ceecd63302988000cb541751ef3ade3fc147e3bfa0be3c32705832fcceb3023d3b6a60ef5cb07200a9e3276c83b6fa6b3aaccb4cffe821b87b9a70738da3594f0834f7c916ab9b00ac25a38472cc4461b3aa410d5e6ca3d860cb262b2d52dfaeeaa5ae99eab2f000a3d42157794339088aec785081ec45ecbe9134c3eb2ec5b80a155a990c08c0003e2c7b677f36689d7e7fec3f6b81ee61c3795f1fbce56a8483e465de0e81790034bc8cf0c8dcd8386e3d2189459e24248ba0b06ebc1a572f9b3b9755044d4500e543f0087fd57d721b6bcb76f3e8fd9c8e8df6c8679f245037ce370d2e81870073b998012eb8c669bcc995c56055d72ae844283b5ca9a7b0446554314e60e400168f452a0c999dfadef88d16b9b61e066f5d7840830cb6410283b578fd60ac000997405798183acba4dab877b16d7a716486ead429da1c21367539a76d675600a7e85c49dc3b1677f76d399fa5a1d4dac9d3e97e4fa233948b9c0759cb5b8500f4ad77135db2f07a5ce3252a36daf323446b1e67aca0925dd4bf8957de17d100287904fbf87e8e0d4249c0db9e18aae18237b761f5b615985dc7bc07f10361006e0cf9a09ef7243dab986063b0a9df97f90b5fa07104b90ed3209d028bce8500092a6ade6d373ea772e70fe5538f995e15334bc9a321977b9f6a546ab3179e002285338a66bf9064f4cc80781e22bedb7f3ec66230a8eb178f920b04486cef0068fc21714d09952a6c4f12c452306d122e6b3fb5fe4f62f1bf91e2ebfeb9eb00ffc76cdf54fdac657a204b2f7be626ff55a10979d29badeb2800c33f06c0d7004c13e189ffb8ea8483f316948ec1d80e05436ef1de1eb24d960f0a09a2bb2c00595f7ee3aedd053b5ce9ae6c66ba9e3a182315ccf274fad3df9a57f95776f400038be865c7871b5bd7cd369c73d6bcca6dbc468c5e94905715aa57d84eb211000c5f091d2bd80b11d1b56f542f32985c2cae01f67a7bf25e4c06d30c31647d00f5cfcfe09b2c7eaa6305dd28e3f9ae1bd8d7ce96a85adec0550aa8e4926e3f00baf70094c6b22676d39b8f29460e9be6b6d73b7810092525ed35c05c333c97003132674b88952332444cc931fdec721bffe2c64b695a506aee4cb0780e9e9100515a04e367123d14aba071d8a03a1c87c68d4445b6ff4d319b064264d3d90300ae560fbfc39faa017af6b5cd89ebe9664f1ed32704fa9b0fb182ceee5e0cc1007f8b4ee066bc768f4b6ad0d357f49df8936a1f352bb1d5c992f721f6ee7a5100f9e096b19f87d2ff6ba8a8957e449a414eeac189c91274b3da02957f6a5d890007ba07dbf08953fc04d9e99de45797958a8d91a583f6e42d549d3582579df000f9d0df54ad76f2f52adf23b4498899dd0a91154058f01a9cce679640c68cee00779b73c519032f5966bb0d4609295cc6a2cf5debd2213271913fafcfd16c8c00421711b9ba5330997d607e7e84416970b0d5bf3720a94f61a98a4d629fdbc400d72cdc1c593a0b1bbb28693095ab9b04f3701bc9b5941df829f3986d2d071100ee97ada6ca8054ce6121e798f74fa98416c7e2b1df96551dac73320c1f5cee0091b16defd3633e0ffb85bc79a9188b99c600771b3023e4f10cd23e433909f100d1761fcea2af50f151718d06be5ad083fd19c7e64c0a5678edc3db5a65702a0004b032ff70bc08ca29053316f10e4293ed8366631c0bf1b46006ffeede9eb900d65760d1bbac164f9efab1f797a478c88f8fa4bb9801c88973c2ecb18cfb5a003695bbfe5dc0873365ac5120396ed2309323d0759f18da1e2f8266e2c102c000a9d46f1c84c762a0f58daf2dbfe5f5c1045d7c044a2b17812fc82b56196cd1004e623acf57c015438568e64ebf627751173fbf3fd3aaf69e240296144e52cb006b48f630107bc7253b2753961113a9509fda7fb3ca0dc82083096cf4a289e900e6507fc46cfd1e945465a3811cb668f651f956aa788e407230b617a858cd1800c2b46d25c23987e38afc3acdbee6cc2f097e6016f13a1995dbaaee7de5c3330048d3f9b19a93e6cc8d109d855dcb3c8ad3d1b26ea9075f5ce1f563477ce80c00682503611d306883e4806b0473658f3f94472f729273f03d0ab0e0a31ed35900a2768bd0c596811fe7d71c14c5cf29825e70e7a8928bb94a256da076beb86700c5f09dee18114a89cc141d7a6222dee8b65a9be927f8a0b8f99f5d729f08b600d4f7cbc21c9c05c56afac37f8542029acc57ef6199adbcb535ae8d0c1ad4050018ce31cc333480d3c16de8313ac35f8222e5ceda88868edb4913dc172017110093646b6ad147f8796be859eb7148d1b738db1bd2c453d950022bbd77a498d00052abd9541fc1c82807ff976af7eb9f4443c1cba317b2ea56552f5de5167a3a00acfccba72e52bc97b6a858a2c7ca1ed07f031736979ef0dcccde170d47d3bf006a2f5df96fb0bdb23526d4af41b8c4af9d567d90aefdb11a294d846a044f5d001e687032e0a8bfbf7df8dd79793064dab4fc863ae63b7e316a2fd73d46231700909ba48ffb6f23f89e5ebdafa47ed00af4aeedbb831194bf62a8765618f589004aed1180c52aa8c6a33300276afcf8f32e6dcadd1f6d34b6ccaeac35ed11c700d4bf54424c0406510b998dbcdc91ab6a5b793adb0d979e16d771a0aa2969e60020ffe3d857577b0c1552d3c9934e6876f8b6f49169abd0de4d8d1cf3b2fdc500a9175621289ba7ac722dc6b1a520a7c4ca768bc3e9558edb67294e95251ec80067d8a5714b359f2a5d841ee6a09b8a9344fcf1226ccc4afea0e2bc3981d0c0006a4016aa1c30f5b51baf70a68900467b0a3161a99c0a526fc8d03b81220d29005a937c509961444678fb386b37ed1d237c4fcdb78cb69dd2b5062a37145c110031823b0a67f11f0b459d1a4daa5240f8f423bcb80fa09532c9da6318d127f200a434db4bea5c5819c1ebbe90baf053f0b2edece86600616ef2beec9df5e69c007e7286ce15e8304e76a3badf592bc0eb5beba860945db53173566ef4e96b55001335a1a94e88390b004213cd938db371d7531b57aff4f2d0e03c03c0d1c017005d1235b1dc527493726f3e5f668cc1f30345e31bdef6468fa31115b14df84b00c692a4f12e13926ab909862cec728dc4ec8e405c9ab8ba0e1ed4609c50c63c0077aff200dc84290f7d76a8c1053aff0397c9c9e4386b7bdbaf0ba7cb03f575002636566e98bd7e26e7196cf00fb6964640722ff8b1fbcfe759e199ff68f08000c80aa9583be237ac0f664cd28a89df99e26af645a0215a7f2593526d27f08d008095e3e4b98558a6b478598db4b5178d53715ebd8936badaa1e90864d4aaf900c063b148879cf4f07230e3b07a378cb128922427cb12fcfc72ea7a8ffcd2d100bd8805500e9459b641c7b4ef9f4d8d3c915d5d4b8a4968608a55e2dba41b3e00ddf44782329b7f2e7757ceb441e9cbcfa6db71821f3717598c86cc8a900ef70050546ca9b4579d46230a665c2119a95c9dc26aeec100d8a368a93b99fd46e7007937d744ea96efc3d466d0ea57b7f593b1a551f21020ded70ae0159085da6d0085ca65705b6d29dd960fe24d34ae1a97a3b55512cffcb9ebf984c5b61128e5006a3ba0e578ad08b59410ce41a9a29ebbc6b7d3572202fb01718ba56169622600a7fed8f69b0b46d80ba12c08cdc9a454a0ad253366ee653a4a4ab81525f5a9006c25105609eed51b7ea3436f11bf09e80665ed2bfb91ba71aeb3c1fd0e82eb00672dfb18aa9a406c7e7d2c94276a48f52225fbebf5f5e30938e5dcd7f5b09100377bd4f017687c7881adfe4886fc6eaff33ba21c3715a89f8a755f1a40eca80043645e62628f0c1898b1b7fdc029f0d05af0a6e30e5b14758a3968a344fb72001b5c7a443f847be60a609139da0752d790c9eaf70d05cf2197573fac0c0710004ede448fdc47c6c1d9b1f3c59c9f4cae71de2f20b5ed6dc83ce2253c7439e600fb7b92da2b6d6ee66e9912502f490c86858203eaef443939a36dee057dd477001c75499b1adcd5ef68b689978a18429ad9d1e30be428a348fdb696ef33052d003d20bb749103e36da2c5044f204ba6d3c81d8b0346392a7c9ac6f7894bda50001a61d78caf85c6f3708197385a7c735357667d99c5bffaf72c77c0b2f7d4cc003cbdc9a0af5406249602a69313839ae4d63ca5910f4e1911750c6db609274e00afaaec4de4fbe5bdfdee8a40f8df4f7e9234f4f59323094c8a16631f2a198200ba94984a6da9cc7087854940b1206e2ee423f55bbb74dbf4ef89b2de13c84d007f70b1ddf2209d7da1a62425cdd441f452513b38212959afa5f62fcea3151500869c72dc6311b528edc557af75a1300298d606a091f7b2d4bc89e272ac177400dd870381162860ac1037d8f2e9a6d4cdb18b730b3616dfd6bdbab4b1e91c0f0052bb527d1b289f827fa7b65f1f6347a87075a679b2379e7b5677f5c31323f1004637452f1993292e662313476f327c93cf7357ab3ee13608bea922e89edf7c0010445044f25c0ee0d26b0f16d734487d4f6c803d3ecffb1646bb53da9057f20031bd1db7b2d579870870fdad8f623662803f0ba0d4bc0707de3d4dec6cb91b008a0ab6737b8a1ed792bae46be979123407542d63c547d7e123fcc08f4455f700a5cdd9a2479f015b3e0175911a885bd51ba91093374f59105a613627a76b90005156ae02ad669cb8fcb0e0d05403a1137c5b3c856a8b02e92cb961bc4555810026fba7d653b53237a67876cf6cfa62c8d6e5853350b9aa583dfbb67e80a5f2000fbea54e5e66b5abff6844cae2a2488a9a9c841db482076adecbf1ac45a27d00220108b7b34ffba14642feaeb5767e6952c3da37ac2f94d0da4928ddf45aac007b585171e4feac682d811eaa70adc2c1cacd5e7b051b83a5dade6dd01567000032fb76394cd5c28c7b9cc9048de578978a38a66cf95fdc3c7269e28559b918008822dc3c847aa27968331d3f1ecf8ba6e7a198d3809166471743e8c6ee332500614919cf95fbad7e1113bfadbdcd9536f62c93f3f3797b98afbee90ecd1808001cf2daa676564298b4620dea91ea0ccd60c1dc39765ad50b0dd0de591a724000a10e0bfdee7567735781672c18deebb886e974d53ca9fd498c006244db932e0081fc989bde66dd38aa25d56db813a70f205406dde53c84c92c9b3df0fcb01d0094fbe25164ea452022a4c5eb2287a20089695b441f24664425df0da1bf20a100152e6d36100a416ee4335de9bebe5e1fedd7f751623df6e4f11cf576e571fc00d01578af9258f14021aa6e1bab98c528e0b21ef51ed6fb9e99773658e4b27000337e3de15d5d05af0533bfafed25c49465a604a96281da911b371e4480f59e00d108610fa36c79b27e2326805d0fb78bcae1487c09b603ce1e4998ac5fb0dc0076afb0ea64ece9d9d055f9435f44d01f60b2131b0fe745a19041d8b5b96b4700947a32facd28bc44e40f05122542da4f6a94ec71fb4ab0860d766293c4d539000cbe217627975eddb199248171404f16baf93a8070ed4d624bd5400294ca1c00605a472424e152ff2eb47eb8fb14bea61f6efec68a3975bfb8dc2886a900f800d846be7a3d6ad9a04245fda58daab8ee0658be53c3eb74d88d8adb241d652d00f0e41f32c59b0eeb52c69c32192e72d4bd8ccb48732ea65a5c517f5da00d0300b11e550372e3405ad7842938f8810ef76dd91109d40b94ebdcc6e9ad67f58a001ddb46e2c98cf3b3115e9236d7e59b0af111a6095aba3cd0eeee0d9a3febd8007eb36e2fd3e202607c09e14ca37de3d9a4d83da6c53063ddc5c55775fd42c400973d1e36a8c5b7f2f62af894f3841096fb4767401d0cb6e79c45cd015f39dd00ba3632c3d6ad1e560063cf78da527c6e6f086fba947adba9dd4e7a240bfa050094e4618341cf5cb022c0408d18821b3c2f42a1cec9fe20bb59fb1ca073daf400186b6f512bcde17c987e34d026740be26b6e59f4519bee7faa2332f03d361900b4a4f3a49a1b036000a154a8d9921cb7f5313e30f5de79ba50ae69de10a3d00055da023e1ccb9097336485d459dc80b0925eff5c9744c2a5f6739c521fe66500aa21c22220ca4235f50c1dc8d4e56d320e5f447660c6b88a3a7a173cdd057900f519359aed3a09fe1358d3e81191ecd00cf4a3f4e052a738792711bcb851ee001b41104451b6f0c43bfe8a0c73669743c99f42843cf401e82c19e075591520002a6c59c5fc02012d349cce4a55999dfd2695d7aa1552d8a471373f1ef9898d0020d410f0a6fea44f39cbd7221746672a731334a2b4ba0f1fa613a0e6bf2334002edf2a2910ba6f0288e22807b7ec941668efe9c2d4c3ec47a0d0164f33b36800782b745af64f6cf5adf228bc1c5f2b17a3bffab2c5cccc2f3082c85c69582800ff2702cc1d0da7c8c6e9b5e800f3048fbee2d8337e9cc4cfcc69f55ef7ce1f006d4ff9ae40eb9d2a34081a6e888e6b3252604bfbc2fe9092418aea4a9446a6009abb3fdb82b503270344565ea7039c245e6fece973548156151afa90afa2d000a49eb25624679580f1cdd472c45ff5eafcfeb50345c8c8ad00b24721895933006d220205cd126f33c16d797349bebe9f359c0e1a293eafc03b243aaab18dfb00a2b4e56352f44aa4647c17b87f7af42d010ccad0cf1dc5c711f2f1bc2e84b2009f62f07b60e9a05d207cc8babaf5ea01c4b1d1a0845417860dbc7b4ef49123006b1c8684a490e28bcafece48031940c3117fd5e8a956a5c3f27cded5d5e157003cd71ba035351496360e2307290194bb5e70719a71dfc23b6c8c1a780b1bcd004c7e60c9acf649ea592d49d303ceacad89d171d4fbc7ab5b52c3a9f6b8550c00e53f01d85d0213d16bbc7513f20ff32d73059ab53c908848ae9354ab51f6dc0018985ae185fb4ba5add99fa356a22d56fc63e9868a0678f32578b1b2adef2f00a0c6c86acaba0f806778f507aac0c6c0da1568b2242c5bab329dcc4cfaac7e0091eae7b2e001668664f27b8fb9b019cbee7ea3a193cdad6fa55bad93032dd600486985d88dad41dc9f3db553650d00c32496c5c64c79ffb52a7c01949935250066b5c4d2573fb6d93743a7a6b365e7844ae1a2403187f03060a89a6117cd57008da3e52746032c1db1323557ca21fd3b3564f0d6d84bbb8950343f0fc0e9a600aef42ce3090777b38b89aef90b6842540685e12099dbb40549e22c4989f5a20087ff4f60087808e77c5d2e1442a5865be25c417603fc53c90c9a66477a8d1e004486d193e0680cac1fc9dd6a0bd4f06e1a494e825689df18773c14397995030050f7ed03f80ac4ef114dbb234af48f63c427c4ac932733298800d4e1b8cdae00c8d62d183e8f3dc013daecb74b036230a86320dfc7ea5ba69de421162d74bb00d64a27d9b1d02d0b4de4ca98dd4fb2b19212dbbd79d8414fcfcf6d1b8ad9e10063045ce09ebd73d5ea353052f8862c2c1fee8db0a32e373b2eb7e47140029300a19284959aca0db3f24c981d61a080c443251a61a1775cd7d4ddc22679de6e00e72039d0f2b1e456410ebc03a6ba9af2c35402fb2490e778d66ef17d1e3f9f00e9f4e68b1c16e5e50a9eb2aa0e460dd90de293eb7875db1ee8c969da8acef700bbfd8935092b5c5da28d7bc460555693693ade4f75c1b7f1a2b8da82d25468002ec11c5703038b7b9add6ed875063aef524314c4bf5f33fbafc1f7dcceb38d001f841521f47d03b1092733403b09722321fa48023045f10441f2a5e617292400c8a0f2f0f4c550bea064f673f4d8c7e4fd7f0ccf346953a6c3b9ecf0b9ff1800ed30c9859189d03f2fdab2734c9e9e0a5f5bc8627d57e18ec4e50722306cdb0058b73a6b57348d0df819e649d9cd94470ef833b5f835bd100a860803f1bec800b09a1fcdf306384eb74fdd447790e99cb43a2d0b3a95bac9943ab4ef815a7a000311c04eaf0f6b9934f798f7770fe8c033485a81c9239f78ffe90a5a53b5ab00955b30b3ba8f9a4a60dbd3ea4e11fc7fa347be78e971164aeadac1993b6c3800300376b172633b68b41c63ceff23045e6441a61cc668f1e1eea611b76cd4490064ddb752f0574876a3e6486e96f7f88b5e939d7dee1d6a417c0e7a9c1f448c002116d1c90749109db8bd6a765b0a42422de61550cf2e8d83bb0a2e5bddcc5600dddc958b4effdbef1864905fa051886145ea0befc3034dece0645a7f39a82400c08b187cd77b5dfd77395d68b9c13def1ff74b45a3a1ec32af0898841950ad00834830ca33de3324040439b9f2ae3cffc8a30979512ee4efb9b32eca12247e00cafb34296e4bb451132258c53e8e8271d6b7f6d62c85508ee172e1c86c1b070075dd9cc0ca137f60ddeb12fee55c963f6e6527af456e8ead2ba56a4d9c121b00ef5a48dde12ad78489d3725edcad852f930e22ad98d0832e67032b7b96934100fdcc49ae7eb74a83bfdaa15afba0c789de8b1fee7d0ea5461c6f14e5e520d1006bc99989f78b841f03afb7ad6304178450fe5df69a57a9f073c822349e3d1e005ef0d72145d54fa0de801ebd0a47a48205b7b39e733f81ea7abb5d917e74cb006abfee0d381d02e5d1ec05e1fd309e9b013d31241465c4e26092a28df93b3d004f742df737e8e7f192b84248245ea11f29dc049575a99853928212302eb7140069f7043f3826ba15fbdc3bff0014e403839551ecbc3e7ed46e9b5b78ac7c7600c969126541111790429d62ea795ef3a915a234ef898e02defb40820db39d3f00853d717fd4e1543325f46ac089ae8b7323eceb8daae4da4e914b50de40d45200d59e01a068b222809ea35d3faea00c550cc5cd4974706c5eee48d37ca9266d00638847c662818a891cfe3a821caec6fc06c1846c1e3bbf471ecb771b5b2f0600fe563f38bfc70d48078f0e3b6b6c3ce7d8d0e6da1df4235715a58674049afb00969dc662cbd89910ea7d47115718cb56cb14cce905a221b5706999ad2ba0e80030bf0641945abd8f977cbc9f099d7f7ae74a26c28cdf4a7caddf4ccf527be200891e6eb5f89d524d7baefa233e1dced4bb3e0a2a489a37395a48f69e9bd464002e2046815600f784a843c942d28fd9998d20091847147efd192c2c948471f2004033c7c4bbb7de6ec95a86e9806d035edf6deef966063fab36dd04017a672300b4aaf93e4f879406b795f4c501e8c331aa8ef79cab8eb602d50eccfe7e279a000139873d8dc470336dce496ca6268cd8927912bd7a0c17486e2c6331e63dd700917f1879d85bb2dff1cf116354c7038586f68615af5ad811dfec7542a72c5d00ca55ebbf4884cd74c470d2959d76bc4562d3d2eab6fbd9c07ca3dfbd8775700005183e4f996e0121227531ce13bf79292c76d12ea2086c73549348c4b77dad006636ab32f024c3cf36b1bf8e0dc9aafe3610e2e3610fd4c1392c4abf4d8d6a0036ed4c497f54550aa5d1a1993de28412561ca27cf657086c11dc2a697e8f0f00f361f9ad835ff65dbf39ee8959cf2d8a1686e988480af8b8c8cc70999c237600f521b9f45394635e81e52a35c7880df855f99788b131a26c4c500676fe7d4b00d62f80ce3ad56a23d617608cb2fb5435e23de28ea167e92e445e4924fabed30096226e77a08c97117fa173d57b44467b3fd3619efe07f58e2e4be9085e404a000fdd31ee7c32d3e17b85ee8f78997d32bd553404bec92a8df3125c288cdbe7007dfe1de32cf5132b355111a1e04c0e141395a1fd9d7f559fac34bcfcade67900fd0a5998772e6162d9b0c771cb43bafa4d01efb36fc47e1c70e2ccab98da100034bbd507b2b995906c6f0f93c543a97af4524fe367dc2f01c9f5a3ebad9cd8009ad0c3f0b68ce43fba69c5a5532d9fcaf0ea2ed5ec38553aba2cbc89b9d1ff00d4afb8fced67ab65da165a7ed863e78b2fea669613d02e63e480736f490cb900ba42a0edd03eb3c58ac8bab902b55977f7b4938c61da2797e727cb741f36cb003e916ca51b8681b54b0cc838124c3da4ff6260a57255b9085a40a2adca6de2009cddec6f5740d7fb468fc60b810499fb68bf3edf907e8c339841879814d1540004e38a9439ee08ec8ace1c0994c9b399981c143fe97019c60a702dc4583ab2001d9f6b8a2643d5ec065a0d2199f925b0321d530c22356947b3c8329c592db90026827163e8f5547f0ed607f164dcacb8d73355b9b5ea2fef3752d7c9396daf0029e169b4e485970207f9dd3174f5a5e0e8ea91454488eae07dacb024cdfe1900da9b67abbe0f6272a555d0ee6e2625247016ef2a1bbe863c860d94679fa06800444775be372ea035d29fb7b6a033fcd0bf3c25ec6a6a2dc04f44ca5918f519002eebac8f4071f379f473f59341e6557d37e9366bb0db328552a10c1e6e7ff60006db264006aa4fa7a63f4f5243de5680ee6c9eea8cbc86fc4bb8354c616a34006842689ec1a7dbf04cb7558b1df526e694f52018aff7d0ad49df01fe446860000d8008638d7312f4098a65e74bdd158b7c2af8c37552885e3606336b29be1400f4b3efec199c2a2eaa1d404da307a4c19f5c71596e5a8645d6d61f38aecc2a005a60a79279dde4de7ad482f59b266d227e74761abab0719a8567181d1a94d000d3f2643dc664846117269fce29cecd9d5bd9deab259d072f16ef3709895eb20029b89922e3e4cbbbe16a9df6a49a4f8c16541de2b22886589c4c95fc2b68f10054daef8a14f9cf91fab7bdca45ed2addb67ebf783cf74bd9d1b1fef521586000925fd914950a002f12e7aa248387c9cc2d1a3cedd87459ab2f9bc498095bb400580aa7660a5febce120d092fa9a9eaf81dc8b065d2c74e5ccf70cd5793820b00c6fd701ff155f228602d5c3c3becf5f943081e3c3e7625c921c71ace99a3c500c26c92f7c9b245a518d0ea15c637168c6aaa7296f5b740b0bf09b1552806db00fc850a2ddc5d1e828a99c1d6196d760945257423b36f3af18209ed721492e4008b0c5b7f06f6caa6d71c96ea8ba5960b20c99ed7858dd2201e5e200c6d000c00f8014fe26284ee126dd2db4c1eced399873994eca9c211454fd5a5b063eefd002aeb1031390dc0f48fd6ff170c6199005a237d63a280b8971f31dcfceb765100a969a6c627dc89fb61091299726418fecebce3426617e47c943fcfa145870b008f18bfbb9686620185f455ca69410e7bcd6dfd3ab978f2759084f5292c11d7004599f0da2c87ec2ddb654dace19f565910056f090d30e3709802cec8c7756400620cdc489a2de9486255f941000773bd3a3cf985efb03c6a20c76349ab946a009a9d0b46fa5a150bcab05f4ab64ecec4b994feb3826e8d67833d3403998ee700df1d9218acede1e4085d44a79d22e4be84a8b1231a0f78ff0fc6c4c48e6719000dd9d9a476c87ee48396c643ba3d8e211e2671cde3c0352d4d222a8e32ee2900468f3e6a8d880fcb02194e1b7d7c9e63e8b08c68338e662af0def6fce3efdf00deddd58d5a269664503f51694b65770d04f62c5396f17da12213ca0a9cae4b00d5b29b18bd71f541a2c7582a1ea8ed4773438bbb3674557cd411dbe67bd72400c100b700afcae11280827c4ed3f0bc3227a98e20950d9542ba0f923497a3ec00e8b1e5032c53fd7e7da19670acd8f8e726226c1921ce7577d011bd3733648b0016c1bf3a3e1c823d152b1d292dc988d63c5a7f46ad42f72b20af9cd6287cdc003fe156772e85eeb29176145f490ba83f2f5bcb6b3968d70c6f8efabb0b313f00fc021661ee6882d6acd4d42eb110e7c7281643162395cf389d9d83034495da009eb75c8c2ad87b40098f9428cfe1d5ff85d3025583328000c47303ea1aa19900149010a05c7e68975a3b2a2f178bb8fb8b9aac7609e0964a505210f019230c006ab31207affa7b7be601635faad004c1f7e9d751652065a17f7710ffaeb610004af61e540a37933bbacdb86d9bfc5316e8da5ef0f35491e1fbed0c3268517b0026f2cf34a07fd1b722ccdc884889503421a54c40413d2f47088b99f1042efe00924e8d0f1857b0498ad0fcfe78046e254c8bf883d84452591f799ee9ef633300515330c6d38eeca0d38c7de90590b6534db71c82db01daac2d929256422578006012c3d48b571e1ff01ce6d95f43fdecdcd3cade1c532cb6f0f7a8f0a9e89d005ada1c3d203b460722dbaca24eb84481ea5727fcf3f9d4c3cd4769b745957a00340393fda1c846a2ac9b2e5a3bc5153b8213d45f0e5d262b7e4e6ac595a287005343012e1df457e164f0afd52054922823732059701eadb732822016f919410025853f8a6395be22982f68c5944cc0064497b73b10dd8451bb05b3a69ff50f006f2032929cc4d997b153965d1e7d956e0da3fd748980f05133d173d35b38e300527bf08b265937f78e16d4a36ad9dae9386f5b424ee50bf7d54f23f397ed4c004bf97ac095416311299df4695658c25259704a9a8cd1847e86c4bd6d18cf3400ed2d60df640971f477b196e0e62bc3908dd2e68e6f9ee9ca63d09bb64cecb0000fccb3962bb1f29e1cda8f5e7f59f2232d00f649673cdf31f0aad2488d4943005c4d3e5bbdf421471a786e9664a0ddb8025448395ac2b60000571a934f8be60076b675383d8296ca07359713f494fd6b12030d1ac0eb406a0ab10ead860a3900fb040db061fdf57db6d76b821e83959d348e1f940ecdf8801b9ac6e6dbca4c0026abb8e59c788e808d5685bec74afe103014eb5033f8b4c66c9865ffecafdd000c91020acf0f21c134d0bf3343b0234dfa2679778a13fa45ae09dc1cb68a0e00d96df15b59a83a80c62e3c1604cba53f8c812a2622f7e21f8c5cf41e3cbc7e00910cfa0cc3d7dd08d598675645365d5d85fff25aaf06db05738e5b2a099977007574a63f35e1c10edf1834ff7a0dae51ccb1a03f63463c809bdbbf3e27569c00f398476352044472df2e29a28bd4c76adedcb5e6d18b51ee07372089dda96000045763164a79f8ff9d6fe17c326963d3388d87c8d42948229b13ba9476bd820013265b42905e7ad551f2313c3f51297c3ae2c26fb7cec96d5ec57302f79049003c93524a2a481b2318fd8233d72171f7a8ed98e2f94f1962eaad6f4423389c000993052d2fe57efeb6df3954474b6a988061f6ee0815777d30e2f70f18b73500471154f113d082a74248155ec22bd4392f65f4253bba5f074eee5e320a961000504add92071a4eac82a27ad8c2e5b5807139fba5744b134124e59aea856e72005f092e46dec0207bb72c3c248681b962616539d195e79b7dd7ae2d8101d7cd00899d0d842c4813935def103a5b7343610ad8f2d40fff88ee9e84c810157e2000e69680ec8cbc2a17344b1bdabb9cd3b4112746edbb83e42fbb0214061ed85b00a9b2fbd5ca042e66f8248792884eff29eec01277e871a58d680bee78d7e68c00504d74a616aec8e1a01314652b5ba0da4c90b42f11c96e2658ef437733f9c20052bbff66a4c5ce7555cee3a1e33b3f77d341c92ddf3a8085cd93e0ad30aa7100758e79b69a9a069fbb1625012db53d51f4d14088a329256bcccb245305d6a900e1a4ecf1eda1b57e6998997e8de366d5f6011df50dc5ea22b4507e0bb902f3003d9d3eddfce7df4154868d6525a5aa7ce3d326cec739ec85097ab5ce022f18009811626ccb28f43f7f293f8686d379298b17474b68920b74e495a2d30e999100256d3e2462998e5952454485a7486b758a066b732344e46607de6032bc8534005d10ccd18563b697b8f79a7e8bb97de41b957c3287c9d7575c33d41fbf64080059be237d7fb231a7c9085f567db0369d2c1673401bed39e75099c0c19bdf8900cabb3239ed59113301e53089b60682caba0718d9f98230abda1c8d0200ef3d0088be2536f0606abd4592a00fe5a72f9a20933bed6c8ff5162d89291678e46a00a9ca7c8e016475d8433c87948e7138fc96f20363d75d62832d8a18bacb50ea00a00ece0e1fc8dede11e898fc76a283c501a6c4df89796a281cfb5c8fe89a66007658badfd4376c43d54561d1cbe96648638be736da76e0d40d0c7d1507e01600fb38aab4015a43d1cbc9fb8cf26834f729b8101b917e7a560e7f1baa984e0c00b595d3f9bf3323a6d7183f07220bd3d9acf1c8243c6b0b775e608439c5fcfd003c763a6f744cb7140ea5ed74dfbf36d7d006b3d8d91290116dff859168b2f1005a65596784aec0a99f849b08aa803317022f42a9a5ab7699c31668d604812c000c7b7ff97865f9cd4a0fef003c5300559914745f1ae9d2e259077bddca49f0003ec0e959603b93fa035b7fe6d8114bf125537cc58fbfd7be65ad32a802460e00ea1ebe11d2e206501f0e8bb5eba62f321d7f95ebc609a72ec0c79934e74c700078ca71062e2da6940399264a2cee17deb25b3ddb6c048e7ca8d0f27f3c19c7000f2843eb612fbf268909a87c522f2599b86d259e5f9c2ee3484aa73818f03200332bd10e58d97749f42da724d7f037839ab9a212a2da8361003f91475568dc00c1af24f7973c6ec3767afdf8edcc40ffd5f17ae7b11135e1e4ba46b62a74a10069e069326caee3df9e79dae74422351f16ecc35d3f065c56de637f8d078f5d0036477d9111a1737d5aacc1ec5d09355477fe1be897fa5df62a956f568d2974004ffd65e7eb7cbf0d6b48ef457da813a9f9a4a2c3ba2c5c83c8c2cecc5b1b01001175424dd5997045baa38b9ffdd85677ef60b20d3e661f317a66d043d4fda7003f9209e04dbed7307fc8ec9c40abc4309a49c7dcdcca0e45b1f2fb8b03ffe00040d61f7e5b432f1cb1a1a88c07934bff50861950af7d3a3d83221870132dc2003d10bf93559855e5d866686acc947eb62e8493bbd7b5e3548d4e4f2fa1c3af0056186af6a6cd159edcad5d902483a94f296559c4f5b76fee88a8d6c8c2e17a00fa5d10998f90639f42ccfe23921fb73a32d022e20710e85354045ba0c5db02001945be327ef4ed6a88521480e57375f2abe45dcd22f22b3cbdc7ce594dc23600a590a23bbf59b15e3d523d9262fabe0afbfa06657ed8a20cd49c6f860b04f0001e14751dee677fb748c13766ea9909973288d2917d1088cc7061f2353c22b70073ac7eb6bdfb9cd562a49810227b831ffbe8320743c1e669c473f65a9f79e5001f52a05557ee8692ceffb0067fa1cff73e86d75c95d2f38c5c5c952aba43fa001bca4a2c95e1c91bf468f7ba7f2dd759293562f355d885bea1002ef8d9b95400b09656b55966c389ddab283ca4825f72f1615016dcb10419cc134bd7581b7000fafa520aebd38ef1fe8465abf4a1f5fd3d5488c64567f0a6d69edb359e109f00ef17dfb5829ab8a45a14f2c74759ff070cccf8304c1652495e6e9e5b1c57d9008c1d59b93a282ce44fad6f127d6f60de9591410c060f921db105a99cec9968003aae5c21499d775bef38f9c2de823284b3d7e8b137cd2c326ad45a638cd2c300c003c01d7f40c72aa8e42e863233c42574fafe640b1183db1db55cc1cf940d00c9b0864eae60249b62c83f939b505ec2ce0c9accdc78671a03c38ac169101000589ad0acb31dfe197e71791a46e62b8b4d54e43bae2787879a0ac3c583e257008b0a36c0eb228956b25631ed2ec7e6e3420a633816993e4064c586f484e2bb00b58668055339448370a78ab286fcecde95db0639ef605ffae7f35b495d9d6100e406f60bca53116e8582956123a2d134435e468d671d06b6b5891c7e5081f3006c8a4625060014556a3ea06ebae219f4af02b652a359b7b2edfa9ca9a55f3a0080d0deef9a8645e846b7ce58018dcbe91fbbe7c1387ae535f5ff561bef7fa90086c12e75ca47a70b101616086ec2d131ea51be2eb581626929fea5b85eccdd0040a627f3b62db3ea036028534f20de986f109d2c3df716d7587293604b7cd300d7e621df6d5ea9a76f52646466e378c4573762c04770bdc2fab60ba6b0df22007cae5aa330b65a28efcee08732dcc130aa9240441fabca3b66e537af82190f007eb8f25cc971d9e4c465090fc29f9ccb009b34552cb4e84c7fb8e1b063f93a0061639cd3583bae5e50548e8511925d76a78600a1b6b974ec03ef345d98d2b3002e79ddeaa2f5393856d3f77185697021f5524962644fd0541ee0be2d37349700caaa8d9d03cb4c3cbf66ab4a4d784452f3259916188eeec274f694f2f6909200760eaaad0c900dc450c2b576f8e3300675b32ca09d23ca34e1f60b097ebb0800c851b526c979585af30654b6f0bd58d6da58048e2aab457bc432431de60a170092bb0131d5061739e80be28ec9ac72f4863c158eb1133ff185fc3d2df9419300ef1506a3c07eb2e85639cefdd824a8529656a2f3fdfece3bcb97331874149b00a1862edd74c80c5a655916fc9587c2ee5d2e071a15e5ae3dfde490bfe35e0a00ccdc3dd4aba7b3ef824e38c1448c0debc23bbfa43d77953dffe031806b27c20057b44f677e7a7a20b4c3fdea76dbfcfad4a95fde613d1df360eb01c320187a00a97ded2785139d811f466f79628aebdb4e589808751b992beac3db8e2723a00013d4588e67888f998b592aec03df0da0ad7e8da3960e3c19b28b3272bd71fa005dc202824a35cdf2b742ed8ad375cfbc0f92172a1c87663949459669849c0f00e6db60f4223cd3d166a07a06f634b03e7b57554ee16bcbeeb5043c79fa0a4d0004d889498daa4d99ad5ae45df430ea45d717f745d6ae1a2b968e0d857f27de00f45b2d0e535d95e2ef5e0edb5e50c54a107d3c8435421030db509b241a58b100cf839c81a88a96b06dc420817d7830b0753e6ddc95f0c5abd19984679bf37c0061467630ea11db9e31dace6512657159b0fbffce80af2a906f27ab67f42f2a00a20cbecc756560f774d519f23fbc307b735b039ce5ed59a5f5ca2eebfe2b3100cdcaa112f8fa711e0cfc71d493a025050823b35aae0f1dc6f8a5dffbcd3fc700665e656857b2f20e7ff746b7d144a089f03778aa1f76e95f3bea792f58ddad004b041bc085563ab49cbadbef2f903c047e636353abc96330d5b3bf2265e44100ebc1dc9b648be1099b8721949087531da234d181158cb1f4b92c5d71b20c6800032753a0303499d29577b0dff47d74658782f4b71e416cc7b03e98c61a21c10055d439c5b4840d63895192002d125440253441d5b2dca47dbbefaf726516d9009bc0afc0d8fc3e126ec6423f92ec113b917242ff4196f1d5482420f1d9c917003199f25319e504f8b2868a3e18ef0b4dfc8886329837bbcbbac797743362c400afa208d0af7781c2d8d412280aa3288ebad5af40e50c73d52e7e5a5ba5deb6003911ee56afaec85574c7856961de962b9916e248f4229cc11a02357c6afba800dda277c84aa6bced8740181bf28f2e1d2b0e41e351200a413461b0db46df5800812824e4437aff8e3840fba99b5e9d2c5c2f163d03dd69c6c1c2db51a256ac00a5bcb62fe00889fc424cfaad2dcf33d0cac60939081ea950a639fd8cc74f29001097f81c2a03e77e403feac6b15143f3b15b00dbd7fd02b9e859f90a7de93c0035012b6e5fbd2390b4651e7abb0a6ea9a2e40f70745f15b1777a4894d497db0019b0062ac1bda0f6e057410c69a0fda04a14c9d8d566b6e21976e5f24a7ba900d733b898f802afd8840789b68d37a0fdcbdaecc55333c820fc6ff4cd2fe29f00c59a55b24570b0a79d1bc541444971d8e221408df9afc6184838723ffd461100bdc75772cc0d20a7d8dafda69f943c3ffc6dca92cb122e7f0900ca8008d1dd005108ab4d81826253dfa49206362a0687b7e326c7a1f4c1e611c4f03ca5a02c00436e2cc17103c97da0b199fc36f05620c876f0ac680aa95cfb7e64c3f0d39300f3e06e39692b531ac159b222beca6d7e958bc058504d3458ace5c6248a73c60048feb7ce3697cb6d4d3552859e905b0aaf39f555ea2f4b7b77751e4f23a4f600658a0bc3a0b693233feb476db1a251b2966ea05c871202dc6d0f82ddee692200ce16839dbde7aea12d2edacad3bb1a1ba0f50e189ea306114d3b09357543de00d8c670261728b2d5a8972b2cac28ea94f215baa8c00fc5c9943b60fef4a56c001c15069f338f3f88fcf9e7fbe231d115fffb267bb987fbd766aa5ab4bcb34b00e480b36c1bf524364afcc588d666be0b221394b1122cea369108d3ddba4e7e003fa466aaca587c3e2c1d70f4781bb62bdd1237a25c7f781c69709145cc22ea008eea9bd72dd99f2368cb38316f71d47b96deec3870b116f28673df721320e00067e16bb862040d8bee07e134c51241725f729888967500e1234f7d2f54ceef00c657fa83a01aa3c63717065144487ad8b2c95676fc5342fc0a4ef7bfec303b00a30a67d29cd87a3a112b4b3d215883223240740b5edf0b63f8964cdfbc33b100ad8fed9ee5545dd00b88f2cbca865ced93944b8ea34368ddcf816f88643508007b07971212c936e597680d25e8969e3fa94863fc1c81ac39b9f62d4f33f66800d220ee21c179a51fa343e8e7cd84162872b02894a51add9984b0aadb28f94d00e5b19d10e60df53e2777d7f13794c7d8b5be5538e3de165f850674755cd4c5003584067c8b10c919cf76aec4e150db51dd1327bdca9d7567c88b9b0f9ba96f0098f8fa5f159340cdeffec0add813aadbc5300f05d03d12b38feeb71dd3757300fb4331ea97cb24cd82c12d8e6e4ca9d9ca9ea1fb083afc16ac07b042ae738c00d163544ecf3f41fc3baad7e3adfca1241742a1d8821dc1ad5e59bd3ac919cd00fecc654020485abb1decd7bccca81e626978e724b51067543fdc59919dd50000a397eaaed6d0ae9f5ba3d63d04820def8844077832737cc62fcaa514beaf4f005e2645e3316b7ea3ff01248b5b1f0e76fc4692afa80fc7a633e48eeaacc8f700f35a686e4570189194645357d71449ec2070b3bd87633b3d50c30002ea10b10091f07576b8b7967362b383f9224272dc4a127bc651e2e42f157afd5cb1d2100042324d42c80018bff9ace97b6e236f52025d143dc506c9520a84079eb5502900c1d6dfaea43308fa6f3aef2e14a8efc34edfc73eef658f193fd00232765b5200ca08a38e083207fe95d831f749c5eee9189925e7656d2ca50e92eaaaeefaf100548d9b3bac7dc039ea2cf30569f5b314ce468c0453a2617af3992902747e2d0027e86583621f6cb0f0f5525f57222a57bd3246c14f9c515ce6eccfba53be64003e61344f6c0d24805ccf1ba7bb721bf12d24d11f69f1bd7cf078add9379aa200b307b16ea2d448658370c9492a5997060d7da5d05326baa3d82fc52bbd2f5d008aac2a01424859861e125b28f92892a836d6e9d25fe7927b64306afa79dbde007ab856e3004c31b8411020ab1136436673a1f65c78641e487d28a364cb491100326280e141916ea5a627296c231f375a1daa1fee835de2aa21c72f5a8fe74900bb81111f32b5f4ffe8efb6270583bfd8323c5b289b060d4f3d38fc8be7ea43005b32738b0b35fcf4e73feac92e12ab437cf14389bcce5bddeb8163f87c7af4001d936d907197a14a4b592fe9e2b4163d288905530004eb4223f06dea1c9dc000e463538b4dc738c275c32d120377189eed57f41a53dbf62d651c671c758ea1002ebc9f86ff7e18ac7cc82bc4e3171be6389aacbbc8e429f4a5ad574bdfb9f80011b0b01d4e597decbb0a7360a418d553f36b717c196055dc27bb99b9010ac20059c5011f47fa935112d2d5ec9e3aff0cc08337534ecd329feb4c64eacd9116008c04f3099eb73cb71e49b0be540b0ba9576aec27791cbe49d1619b441d93ce00dbebcda84831f21efae21094e7b5ebe99eb57bc56d2aae1b870d586ef8018600d387e62ebbbe7a95373a7eeea54f2907540164754b8ee31aa02601940c13b3005a6ca7939a565a0ab46ec0f5e1a9dec1a8f4cc668b3e0d0ac6e1b93a3bc15700588f58ecf39e625c26b8eb2e3c54601e01a9e73d8d4d68959ea05e4cf0966400bae1790b9cce4219ed0516ed77b0f2c9de73d73e480b5381b90c0964d480cd0062895ab3ae229929a6fd6f1d99584190da7875d55e12823bad722270db5c2d0061c73390b816c983ce8882fb970f0c32bb52bc98a67ec26a87ec3f7e28947b00f70ed19fc275adcd1c865c9dae6335e2f33bdfb1f61e631c3a65cfe209bd59003b3060b0a7fc8fcfd0946efdc9fcf6506979ab9e111a71a05526113c90a277007f263ce55cb80ceca9e43f1ceca84fbce3dc19dd1aefeb4dcee48bc6545476008e3f883710b05bb16f03881f11b26394f2b1beedb06d3c4ec12e663edac6c000f2f9a0b981a791f8a2eea6b61f81ad6d6c7b765446e74a6ec9b28518d2824700021218b5436f9704434904d40e4a1cac008a4ef2130fead99a989405180f8a00657ba2c97225377a14bbb0a2c9a609b3a41caf66f52b498598d641e476b11c00f624015175a95baf1c751ca0ccdbf8eed4b29edd04ff501d3acf886aeca3f300607b66ed43a3d346e9c279965ff9ca1e39da094225fb7b14493fb348f491a500d46fb5a61e837f94bfe49b982d478b70c6b0cfe3f9b9fcca3459f1bef79e5400686229dfcc990582a3ce7f47c168b4ad04eb8461177d8dd352948248275200004b8bb46d19cae94f2cd9b9ed72036f91ca298606e1f2eb3b9bd7f4fd9ee62a001e03a6be51cd41b2cf6cac1985f8418a8296ba12eaec744a568de0b0bd00fc00090aa531391ea92c0f223d78c3c380ccf7cf788d896f1bd7855bdc2f69a54d00748a0975b52aabd69ede7e57b34fe81f2c7b611952c3e2469ba3d9bb57f6c300fffd5c6fb68b044848b7897c4a53754fd030e6d3c977a2a6ca02201110f0f000eb929ed4a3a78d686a253bbac0a1853544ba7275727e262e92cd390b66153b0049d7dae71eb9b1105e891472f77a900eccfc36d56f9829f9b718ec16d19a5300b58468023d143e95d21fd3398139e93ef2c90ec237dbe09698cf14f136193e003d35a788be1f54c02118798889661613d62fa5c5185540d8c8996cc21432860063d103a2130522bd5960b7ed1bd66dad6f10435edee697020f8a8fcf0c3344003bb8290b2bf5b53c632bd0aed5aebd110484429bffa70a3060654671fac14d0031bb63f900c42dd4ec0494714c90624e1085ec500be896071106aa813cee8a0090f54b3931939f03c077c80d026ee05e8389e917f0524d53c16d724b9eb1fd005116694575cff7be6fc30f5af92aba77a2a369e084757058c763bc3ae3b79e006e8db67f2336b234e3750b29b9e2678e2a5f7e9a0d7d3a632c4c89bfcdd7ad00820a54ae65a9253dab5af68f65b22fa3e18dde5af298c3fc5dd4ca83faf7ff001a8f00d81436a7856dd7041c8c813c7aecb076816b6d1aef638c19a014ba570082f489422c80da0c19a9e9bd1d439e30970a7e3f1873287cc3ea0f658fbe4c0035b221e8fe0389a3d6a1af03ae0caef8a22b65a68842ac04316b65c2f93856008aae9abc9689e4d22e6ae7e5e1ff99d1aeb86a4a92b277d6d1c45f4fb103ad0056bbaadda9b0eedcc07b75b9586aa909e2d0e2e9cfe90ff1aaead6a824c50d00bea032732d97b8b1d2e3deaa6a61e65a6ef9e4ab8541c0fe216c6eb88a0e99000a0058cfdd36d8d6c67f642681426e6154766c32f18b591f98a4bc938dab9e009b201f13d87cfa3aeb28eed9f8ac1e9ca6e605b33b5eb439d4a83bec43297500ba2a97c27377ccf902616804c153020f46de09e0cdff2227c713ee48f6950d00f91512ffd94f55f0702790581a229c4e4959533dc033ab12bccd386e76724e001bf6322605c4930e99c42e029706571b93c27b9204f0e50ddb1ff1b372aa500009878169b799ac5e3cbfd4d32e9ab988a480f50682c9c041bfbed013a66bdf00aac7b43d4bc451185cb87e17ae56d3f96e4348dc1c5bb5beacc2908fea4d4b0018bb0dbdf2b17663dfba2c3b5a5490d314aad2668a16d52a90a9bda23ef910000a21a156f5f408e717edb9784bdbb0f7d119df9d08d135287b65eb22f0335400dc55db04a4c79d49b32a2d53c1351e13eb8d09ec654358b3082d140531846900fc49a348e75f1a6093f59e03ebae1e1bfcefc93ca68795e9ed5a848e18f1250066bd28de58757ce788b87f674525c5a9bdcadf5d9be63f1bfba799558ee979006883b8a292141f791ee08955a612cdfd59a199141bb826eaef0a850d8c3b4b0002a114b02255d102bbddb6d09883cb5e288efde48ae7c8a7f62b008d0c369c000bb28c3029c612e77b38d2ed100dca507d06396537c71b48a4a32d580bbfdd00d5f534ac470600c08af38e441b2723e85538fd6f365db8c44a96849e757ef700e67ce27cee1d10a1285d5e0fecf36b086bef12d6a6c54a8a3599ca4228280800e8943288ebf43e55503710ea4f3552e1e8bcfd57a1c519b7954f53fbdcb2e700d416e5805fc77858bd365656c18f858f64764810fbff7224e6c834a61ccbe900afe9a349a38709d47de18f915c2460a04553da43d42fe756b2506e76e247ae009f2204d5ca70f5f2882bec1fe7bfc35cc6db8f6b56d389feb335831075760f001bbd05afdd7d29499dd74c7437d2a12524c4f05106cf7154ace7ccaf48b5b70089ae72061798f01049389419dfe9fa4a7746a1510fc418d30cafb3669cfbc70042485a22b6e62b400a6b5d98bb20ffd8792a2765cab992a820e7f4a6e0f83100a8dfe866024db6f70e7429be01c73c1b1b13e61252d1a037003eabc19db1e400c372985b8af6d9ee866fd634f830d41709d461fea47876f4cf9a31951c61b200287198b9adf671df9b0cbf81e8b5af3ea25355f5000c10068faacee7480a5700fb4ca32af40d89bd5119dc91eba8d28cf1664596becf2220054ecfcb050ee900719d478b5dcd372fed4f2b0488e855c6361a4c2fc231ea136c6c985c0a8d180051048f7a6866720c444d4385b510e6897ed2a5692cb2df1938c2d1344a6d6b004664df80f51389f90c98d68071b238beee6afe6be706a550b5a32245f5ca52008d080f22d708f44ccc38f30207b4a25e9805c75a89b673baebddc87bb6b75e009ba010dcedf3d542ea18da331bcc347b6c50aee91818719c845406f4863834003eb4f566f900ac331dc53a97d7a15c8c694c228bb0004bdaa6cad046b683e50029beb43896f4ebc6fe909cfd48821b5571072adff764362c545ad4ae5778890036e3bdb75c3c6ed15218d4f90076e1e9a1bc7daa8c7317f613984fd41ccc2b00b8ba3586a0f5481c7aafb24b8b05a6ec03a44cc5180c5e4f87c1830de70de30040fbfb95e428a861ecde3668f0c77509dbd595a8fa25341007836e983f750e006782430edffdd8820b3d3a04756305e71c38599c545fe1297c06ca88443703007413f289f9115a42889fd99c4912f132934a5597a54c2ef652e312a6bdb95600b4cbeecb566196ebb0d84aeb256447c2e7c8d3f079b2b977eb4a90d6763106007c4a02c8238734013dca4160f97b19097473b8f381f781f002a808a30af6270050c3c0fb7191d618813c9deeceb91eedb5b1c68079b4547f80558d5c125e3d000dd6b61379899c983096f104ee895b53135e56e4de59c7d76c1ed3cf6c53c1003e7df1d38b23d834b3cc27688660687b7b4a0652fb63326277cf9de71e9e34007a4f5805b4badc5feb8ece0605b1a2827718ef78878c2d03e9dd211fc2d97b00dceac1c2b19f0367ee91cab5da6556fa87d157ddc7d34f3c11370dd80888e8003cb7f2d61fdc7818ff2a28fb50d9069458d671ae32a47c170544c625fdbc8e005ef780bd64f92b5905935d78e58dafa771da28d127fa47053137ddc04929b800a115dd726918e4ec60640012d77eb887395442b4bf6036e7c209b91f28600800872d573d8488f55851e42dfd9ca68b39f0f758b38ce38f79ff4458dcd0bfca00c614fe899f41529810e2502144ca6199896af476a9ec9451897ca53daac25400f06417a36d9f99b17f136ba22abae1fd33a2f049d23b225a4b82bb6935250a005bbd02afec0751e87eea583758a300fc4a3f4086961d8e988b8b029a79324800350bec7c107d43947b73505fcdd6025259c79d56fe390171e243f14472208100973018fe6e1bd80eb1cd516ebdad5c878337f481d7c9d03f3a8e9c2335094b00b1ed53b497486a6e59521a64b091ca7f3d8caefcc3143a6e723a44ec7a444c0071cc9f214597b51001b22dc5158db4099ebfe4a1636bdc90102bdd1fc338c100673a8bc2ffe36c01d6ad5915767822d5f6acc09abd9060a21529c1105232bb003ea3c7acf330a2b31d235f5b7d2a5b5776ea7bdea712cfd40c388760d1568000a50b16a715023e3ef37a1f69a0f9cadc142e128cba9ec2540fe33ab19d337e0041b32844bc541f94627aa2fc53f3701a133d9f49c740b5c6afe9ee33f2fe62006d267aae86b3120169fa24dd34a7617c4861300585a64aa34b32082949d8b4002a3d25fa30ee8ef12f21ad40e684daf04659c5fd83e1229158e2f50366ad2d007c8df307a659608dd16315719551738c7aa3cfd8141c8cc7975b4c038c436200f1d94dd258528456f8abcd98df4f9bdb86d180c2263f6ff065b6e181e3f23a001111d301973e536ea53980798e7278f23635ef24b51948704a83c0fc436a2900b303ce86482ba5e06da298af8bf41951afd2fbc7c8f160805a17650c01025f00b497d5fc17c95116074866054a016100ccff7625a5347f0e0b419e639911cd0082df3b64e0773aa75e78cf78e419758a39e5218c680da68cc3c4df1d26f68400bfc3e3da457e58a6cb69f82f33a425aa3bec6d12a346bb71fbad5ffaf130df00040dd541844119da12db2ee682f3afb52f077f309ffa718a774ac966eb42f2006309d95a17e1d1b90901b953eb4bba23acd5fa976d422acec0f57b47d6febc0057bb4e1cc81c942eac5475ad7b9176722a5051bd8cd2fcae07278d5360c521008a4b415ef41e5c98a3bf24123a38d1a8134908e32f6fc285465aefb400c6dd00c5526159b5253c28b73bafb5bad685f830158d70332c4a7d370b319b17b4a30037124edd6225c957701645e20b961b96fc5d9a2e7ea9fa3fac261282ea61a80019975689cc13fd231f6f1d483dd2c8ba7ed2c31e5679ef7c495646e4c58f9900d44210be7bbc72cbd70b76b6ae110b216bc9cb3276b6e8ae5c7f877d67a0ad004aae16be5c7c66e1df8c245f3a2f3e3167d537729fb26b742522dfa1c4f3d200d38ff93bd869758e6fbcb09aa1d79c4de1f12379971de2459c25a9b42269320068b7fc528d1453ddb230445235977987b3943fe82e531ad15e4cabf4620dac00cbf02cb819a75cd39d4d6284d223b2393596a86df35f6eb5beb1fd20fe665d00466b88d24182876a5ed7033389559d66c4c38e3bd1faf0bc7231c6f41f6078001608688a1900dd285b514dcba920a6bcbec13e25ed28c0ff89cea1cc63f8e10019222f3c3c323a95efe4c2ab08a6428134611984d453366dfc27c313389635008f32a4000b31efe8b7e9d48552602f00015586e421b9b613ad228ad73bfbad00d8d0da8e04e57acf55178ecf404606b0373c0222b6d9e4969058a092d28f98003986f0f394a28ec83dec769a5e67b5e857ede440c039c9a505b166ff34a13200f2f8d2852d0c7c33577e4342aace2812ec9700088a5281ff772fb22e296f5000216fdf4df1b9a95f8912261c4448cc69e5a4363fb0a070b85bd8b7b7bc0ad0008533a24e308e741c325f6e43cce03b417b3a909cadf2938927e49939fef08b0093c94fe28da4282c6630eb7040f6a456ae58d9059cd85fb3563b189bb1c17d0033599bc7544d90964272c1126f3d16309a620e254a08a1af7ef77395d1310200970228575e6c3e27e21b3d128762655cb797e149e92332acb756ac82cf62a800226853cac4b30ca54fcc97d8fdff998a4e558622c488eb2d30287dc13b576c00829100a88abebd3a726366af227611498b7692111d53f12d0f55f5ab862b2600b3ae252612aee1e8424f84f367f14714e5f8eda3333ed19444652559e429ad0084c8f803fbc86455a00aca766c67e5827239dc458bf62801ab782333214030009b40bb0c4198d441656104a5372e650e7e74a25e89a8836788a36fdfbd24eb00e29832d6a1265da1d28d731a7df5bd14c03e7b57d7e258802dae492b45ad9b0019aec5043a656e692bf9f79838b9c4406a1c81118afa393769eee93c84beaa00f47292bb088386f671c437e1713a35c3bedf321b003d4f7963b8b8c8b7d690006088d7157ca82f778bc1b7478bc82665eed5977744cf980349e8d0f77eb3cb00c4cf918069a5c7389881262fcf69a297364ceb4faae6682e74830259ede945007c1ad3d339c8e8df4b478b9ad6d57623def8effb177fae71ab68bd8823772600bba44b54bc41906eb57c492d01b6f9181b3de948ad5ee1546f081ef5e94efd006a0b351e547d3ba1a3f2944a5c65b3c877959337998e99d749a51e05767da0009e381f93232e21c48a317d1762fe06c98003844f6b8e9f21835029f6d547380014d354481181228d852ecc82ea9158ace8295875722227c20349933ad85f1200f911ab2335b80d71cbc375ab08341c5eb26dea91b3aa857a679fb6379273120097552df0b71606468d2c8ed05248d09aa3076987a1d58031719496c86063c7009a9e4ca1ec2a227a84c13f1b996eecb91a9b6066e379d6bb36c716b2a0a34000d1db8e29f2e81084dde5b79bdef95002738d8e4afd6e1bdce0fd1d61890b4a0097da5a70626071be392f391c316ac15aa3e6e888f9eccaa43ae56e126a2068002f90389040f39a3070ed6c4bf95bd3abb3ded5690400b5e6bb2dd98f6b6fee00e5a18b13db96a56786959fa2cda11df7988382202889307bad48519200d32300066addd9d1a6343635149b42cf4c7d04d368e271a18e34cf5c7df33392a36c009146f51733f7368963e9392ec3290817c6a133ecccdb1afcf39f39b724789500ebb8fa2a8bb936fb3e2a74ddf72b3f1ae8da6927be59050ff5d53010a85df5003f67746265a6786f83b432ffe15205ad31dbefba909ea8bf418bc19aa4f1be0087f14b5622d09b38ad634e25781ee363644bd7de15e05d73f32f956f8d40760080a56c3489eaf7c7f036f2847f8a45baac524a9ac2f93431169e1a215cba0600304cf4ed54ff51b46446a5d753adab2f2cb49f5feb114986214867a2fb30e2004dcb31d03660d6322a76f747deb399e19a718321ee034ceb2c0d6b2a4c3d990036b4e237925040c05fbc5479aceed4a86dc76bc6e98b5ed5611196ef2eabc800a1b7585af5b6a46edefcfcdde73d40a870bbccb0408ed33c7bc551289d2da2008cba6f6cceb2379f36b9c6d686ce0d2c4b9dfc184945b98ef36d96f4ad6dad003a631dc3dca98e7927705e43f19c67289e3a84f9ab502c813509d2cbd380d1008533ae94f31875183cd3cadcf44d66077157d5c93fdd593c5b1c628398727900c4857a36df7bde7e255843f72c97422e7501be436d4c61ca7ef2cc4c9366f7000994fa5944ab972508e0017138c7e7175e3ba54aad6460c25576f3ec29d1c4000f76ae725fe47df763f2769b1738388a0131985500fac952c1a148290f198300f65b2fca24a11c703f7c0ad90cbc5c197d27e8356689b0222417dc6233929400e964c71fba4db19d11af53129531139028fa743e73245a6bb1c498c877f30400f2a684e165d5b5fb87a4f980d8a0b70af2db7d101f98f6fadbcdd23edcadab00969d785e43c18000b70824d07e3ffddbb0c9c3afb7871756380791a9e8bb3f0016037055af47422700a66d0a6c9c992e7647b4f0fe7f219d1d9792b0c6bc8600545a85fed1275b2ee16cfd03bab81b10faaed85a5519ee4cbe97ab3bcf58f2004753d3052d863f06738718a9199168a41a3434d25469a612dba4c6b00ed70e0068bffba3389b6fafdec659a3fbb8c21f06b4d1f758e9223117f1924584794f00a77735ba8498f36fda91c81a3c900ac7004ae4f538b18a060cb089c9368fb60003f556c269647ebb22a81bd5918b105b180cde5098992aef73a2f62a34e28f007269ca00ef8a6d3e16486941f4caf3ceb00270780d76bff16e039a53a8498c009afc7f92331e183ad1bdfadbaa6e2c43fdde3147499133d8a0950365caee1f00d5905740c4039ff8a56ad8279dafbb5141d77cae2c14c1ff39584f1ca9b44200934412120f4e2311bd3de0b3e96db97c25ab6bd85fd91aa15283ee3514d9a300765727701ce2274951bcd5fffcc52d11602242c5a23cdf821fb156f935cb0c005795ba9c0d2ec042b455d052925a55f35fa87dcfe20c17821df2b53c72d3fd00a4dcb76b6fe6e62cee2ac468a84d8d3b2f49bc943a1bbdce327ed58686f4720091688e767926505cdd1dde92594ba7e9fc477078124bce0ccf1a8871cad0b20056405adc9d0a705c5b552618284844c0e5a5f085f796ede89444835e92a8e700a037b748438d0b24dff41fa9551b3e9e0b10f95388a1f73f78d2940b76a7e70018ce77e8ca56d206aa1f6ad81013768814383bd33c568b7b79d3ce651e34e100592ad7cd6aae97ad01d4ea1b7428d38fcb6719a4facaba6f2b9db2242d0909004822aeb46c452adcc14461bc04e09f804699832fbe7cdb1c8ee2f447e720f900aaa7fda98ef5433a2f63c287f6d498e7ebd7fe12a168739bdcc520bd69947d007297def190dbc6175c42ee6fa905ca246e6a81d08afdd525b07bb978ce8ecf00f9b6b61bf585a069700c9ea21a823b072ac80c4bcf15ada98b5e841f7a03b300de2c19d786bbbaa698b054ea62e6fcdb440204694e7a7ed351eb2518b0691c008feac94ad5487aef31bee60e9748efdab6efa8245e009f24a46d52d49ee7350020551c20479a87227d74290f7060f71f158d143a05be5d3515d8524289a6d100d11ee2101efa53bc3ed9b64d92e2d80936a8607ddafc60ff8dfddc9ba1f88e0006223e918c69017bea71a86de27ca84b7f6df11ec2e2258dfe812bca69ccdb0009ae2e854475c3b3dc63a84ae138df4fcff2d924efa4c3b9ac2931d26ffb2900000d2bc6d3dccd12af9d7ebc86e33eb1e1ca4f0396fc893c295b47cad0bee80020b501115378ebde205e6229c2026953056e5b96e0d34d6026db1e6608db9700b5fe6b053737e47e14905d123e2ff36ee42c4b540e7919e86498c077fd84a4003bc2a95e8e9cbc3ed2efc6b4ce986ba2ac0f52de78fba3b390375b9091ac5b00d14d97789f6e489377945276d317cdbc88c5009fc08c6477919526b87198c9004821c7469ea9045ca9d53e6463e080102c03c4d8130e82857428235719f5d100c2bdaac71b6d2fb067b281a12302da894634986cf3e69909b0f45f767727e1001688b4d714cf85f686959483005ae52a128358e17f526eb4fb7f8211a3e80400d35b0b7f28eea63c05fbffec61507749fa9b04af4bd61ce2a42c9110124db7004b28435394d8e8a42d0df8f8f4a64614f836d098bc0131f6a076b02676f37100805e237ff9d036f02b9ad8e226723892a9d66f4d442f6f76ed7e3894d3354c00bb231865795e6a117b1ebafbd180ea1ee85cda31e338a975e8a49479374cc1001eca64c4edd81d95904696a8d7b3b6b5d452f26e6b86780479be853f877dd5005cf7a4269a9a908b1fd137b6ad725b7cb75c44de1b428d2aad8aa8420a826f0099e995d07bee7732b560d51dff6655fce1fb6474a2774c56831e71ecefced500c9f68ad28423539878950664c01bdbd3de838db81cd0b014e47d4453cd659600ce541239994269c21dad08521075b1d124b59d0204f4db5acff9bb64619d88009685a1a6047121d702f440cf44c3811f230dde6a8990a4487e9fc805e64831007eb2e286b7c06e1a931dc2fc37d80b09bbb2529aa322f80271f8ad8eabbf320081bf59d24704f7b98434e904b5b1136338ea634b44c1fe14ff92220f8440cc00ba3809822cbe8ad7fdd36ebd307cd289a91f5445d887af884b43d0cc0561d000d4554fedab70b13339a7b3f60b1695476c9b9e2eb005e85b8a4f925a13b87500e7a6e557ac09d17247d720d0742c115355ff73a1ca35306254ee7ab5e845070027d792c2741fc39f92167a6a317e5c69b4e68bab1fea9bf5e9dc78cb43e6ce00c6c74af874c3314dfd4bd7bef31db3f875abab55fbaaf080592c506008952300c63d8aab4d855eec327895fcc5145a9057b3cb5e4a2a2c55d8e8f519708cb9009abf56118bdaac9d15ba5d2ac5a5a0f4122bdde437ad1f1385466b26894c6400971402fedb25b0e19afb9d5cb65e39f8376ed685dabbf059007d330f74c3b40037a1683e4a5b2adba1eea104a9f1a581ea0de8de2eab29bc5430ab0de924dc00cb64bb03c48adf9ec17c2db26b1e6890975965ab188c6dd92e32e3c785464d007548dc173ebce2df592c071991dd653755db8f5dac27a313af5d0fbe14274e008c08c48b9e5f0666a000ffb0272910df3f9d8b31df088e4e84256a81a85c88004abf0a062684573426e1bfd0fe35579eb322390d6e6d444ad4bbbdbf1cc7670072abf2492fbfd366361dbd1ad96ea1b0a35bbb70a8fd20a3dc73a652f7c7280027f9f76f00b8005beb65c9b0b19ebcdfb245995ef3868092d0560d1c97999200d1aa15cca311dcff5d5357e25a3316a466d72212f3b4f9e072b23e8fc0fa6d00ec8eb0a22479a632d9a02ab2dc6fd92c64ba4025154b866b7d649573cf9f3900250124482948b66f037a8b0741770077603db9dfb84e8fedf464929f088d6c00785a3021a19690580323b341fd3df14f8205c715304967da2f2fcdce19674a0069822d00e2bd1e53b749e3ea1100022fcaf8c98f02ad11eb8ed2f71e4d44cc002aa8d7848c35e7212df35fd73cfdc4c16c8cc4aec26134afd326f441de2791003a869662c3c5ea43466260cd864d9ce74f9dbfb46f9c3ba4605c9214345769000cee71845ecb2d6c16f94bbbb14d6872aec68857254fcebb79522b7933b494003f38fd3d39f19954136cf3f7b73b77a0ce2ec8ddbba71e8446b6acb413239e0055c6dd3a39a5ccfa55c91d53d1329ce171787ce7701ffef533ea8db0fc41aa008c8a0c98f7cdf33cda6507c55514c3d249ce15310c83e0325cfa1ad69257f5008f5057212b3473b7ea39f8d7747ab5771e14396ae71969ac4f142dd661fab300c1110b35375122b6cd2209b789331e8e05b43543abf8bb4c2f4175400a6df5005dd2ecb603e72cee2ff14977a2bcd233814938b4c42b23275b5802723d6c6000c7023b9f9632d5894712cf506b48df33e53164602ab97991b1d6c71beec6a300caacc406c7c7f550ad8e6406be8548f9bde2c6ddb695d71aeddb2c192a78b9002b517006a2171db5e67bb50e9fc9eb93d43c110fd9e6a3437d128b40deef53007130b4f300cead3a3dcb742bb6a475fc794181b35888787bf1a5a1547669c900b4d379be353929fb2cc3232761ad5ad87a25b1805e5ee20eddc4eaf1eca2fe00e36633a049c93736a8be03558a86e3319196d1b37587f0c90ea692c6d9a9f700d12f4f697f91a87fc8d960fe80dcd3907fdc86d570fa9b170d0910649894ae00c974911bb3a4b4b47af8fd034a1e7b97bbddd4dd53246c00180916ee1337fe00555a905386f2d7fd41bfa699a46f6553e90d12f4e435cb703041c1997159d000043e84c8674ac50787614ec35243fcdc8a6ac44900e55b181a1e04a7eeb4dc0072d9eb09ed6597ec798dc390c6e1905251d416754ffeaabc8c8d1670899500000d10b63b0ed1ecbd7b6ef0293d74fb0bf9135eedcbe0c8a4e28fd2a20acd6600f8da05c5fc8263c5d99bce93ed34bc68b4095a2669a38d17b14afe39ba35fc00f1559839f2049b1c7c7b92a87ce802e4847e6faa730442c7f7cd5e7b96903a00e72154e519cb1c592bbd7fc3fb047fdbea2cbfe828aa5edbb3223e56666ecb00b8291faffde409f8b03ebe26b29374268143c6db3d938d3ed1feedea8c3a7e001df51db109714c5bdd4e64880b4e88f9a7458ad7d4371c4b9060994435587800672dbad05efa4a399dfa811243d1243a65e5aeddd70f5b0c86dad6c708cda9003bee1637aead2982fa9d50f6bea56bde10cfb10cd175f27185b20e6478da9e00af68e1399a01bbc1a80554fb5b4822d77364478cf0c372bdaaf770a602d66400754ab54d08ae0193f045bf6760999efebcdd1255ade0e287ee3330a7cfd61900e43c50ab84228bb4d79b46b716f9c779d1bced5876c9b5028fd40992dabd2b00b07d13a6395fa04bd08368cda1242ca4b15f785e2e955384d81062fd47cd5d00952d54416b9331dde59d6c8162aa3c72c9da9f884cc5b97b1c53264fb40af7008c6097ad721a5efee84e25642d33edf0238cda6707d694db3fd784936ec610006fab266627fcf680f96f317625a7bfa06f0a4fa70dfa652dbfa77ba559a6db000cb7c483ca4f45f69d5321ccf26cd30f6944c20bc40f5b8312842c6525f14100126b8720b124ac5227ca1be0836f19d8dffc33e7b71c8278566006baacb9b600e2c1cb2dce476ac4b2d15565ad19bb1dc144b23215839ac994727baa7012d000b58ef152e7deac0430a7f86cf2fd4929af0c0a47e3a48d00b6d3ec02da4a5400cc22fefa5677338092156cb9cbb343782700d5f5ae93d5f9c0e421c4f6614700c3fdfb948c83cd8f2c36b44cf6b59eb0b164e3368ce6196e6ca34aec18edc70080ed54e401bc4a8d339f217a45d5e7543573c5c42da4fb6981c856abcb27a6006b136ad89a9c9eccdf5a553898c0bfc8c2101ee7ae5c16314f56db44d248ed00b91c55eb547cb06e5275e9e967a80e59c4dff7e029e83ef1a69c26134450cf00a5390fb213198368886cd061a8a390b92c9e46548ea1d8040589c7f2cd7935004e68a9ff076f5957a174e342e46fa64a49959917e928ff7a6e717ca48f27ca0071445dc4aa26c4f3ef019c3f2bc13f5b60a02e5747ecda7040e0ec46d862700072b7d266ef6678ae5d4ff671465465c967cafad60098e2519ba88c60e5fa5c00d58264aca3df81b1b7386337ff77d611e3348485523c1e5e07a67718307128005dd027da64f53376a34b0c01cb222493109f907ce7e4a6ee45239b469dd1900021e3595c40e8adddd6c95e549d821dfefb86bf5394fa742b2b4eaa8dcf749d0052b2584e188a2696493a0ad5284113342be208e34165dd9bb8d82a0084136b00e9f55cea72d08869aa6560ff8e3c99b9a0402f3ae564fc323e3c9cf8fd80e4001d0de67fcdb76fc50fe24233d6213284e7481aab56957138d558b639b1a79600715e4270c24f5894fd97bd3baf0c541e8f3730d98e34fb13c2874e6e10a46d008983069524eda86b5ba0a5cf6f0c24987cc82b98a3c0c3d8a4e9aa0fb03afb0060b0f80575282f06d793c09647b85a4e01b67e842c5999a162312efccb7bd8005e6b86d20b2db11e742857e15771cf8c42e5a8a43967e43879c5bb4321ef4e0000fb7883b99cf74d5d1ab469865ae2e703d324b6ef87d13207d3eff0f61a4e008e8807898973b388db684a8890d4380bf9bd8c943427330d2e9b39ef457ebf00d19429c856b909a68d0fc28fd4477e5f61b91398f3a86f59c34a5a1969d242008790b1699e8db066c4ca421def93125bfe0c5e61ab80123260a7fa06fdb3b800e6f4e48a02eb50e51663b5de8bd3e144277b3fe47608f5e062d4a98ccb5cda00958e02042798d400f4d8f42da797d79785fdab30faa5c659d27e9e650430da0020af8875f7defed78ba23dadaed02d662c815d284ef6362804796a410aa6ce0031d86cdff34521d000a9e31b3a87803bc5a4f0350121d0f9e32958d74262bf0094c7144588ce50b9535d2eb9ca3f6028ed1ee9702bbd74abecab652dcbe38600f85ed92cd2c0a910043d20c4c8f9b2892b9697d5a813ac9f0e20a2f42195b60055d5c9e865fae630f7a6feebddaec6bc0a255bc3b9ffa510ff5196c9cebe91006b03ca55707cb9cb19941e781ed3aab70a17251a6612db921ced7016621be4002685502ea53fbf6a382f752404c7bf2704628e9abbea3568b17a2ad611ab320052f5779b225827756bd73ec2e2ffdffe76c1a3a16d0dd632693188574ec40100995efc98c61a777e6809aca680e03e59ce6c6773753039c6415041a297cd1c005d8ea801b09c45430abce9c83d4c78e4cc85177ed02e7ca7d12d006f64211a00ed5e3b515cf2f83eb48dd8fc2c2669c8d4c98adfe5313d80003c9be9fe193500a478cf6c0fd050735b6fa3093a1e4b848a42d44c2289fcc592bbccf6754383001e60f5fb70f9325fbb5e1417021aa121c046569175e858ac82233ea28423dc001c98825625dc99ea5dea13c561986bf24da26ab7ea997cb06910a60babaf23002c58d2dee6652756d53a7d9cdc44ce0bc2515df386ad573999c13eb2bc8f9c00a39915968939041fffa979aee9e47218e0a935743fd54ef30d5153e89685e300f23fde7b28609dd7f9a8288b296a4ac16cf020e9c115d33ef64a0f796fcaf8007998987adaffb3ea1f3311494c9c0dbddfee57f6b66cce104080cb1e4b9e7f00c1f7ccab4c020bbc7285cd685bdd3bbe53d3ddb6130880f249ed83cc1b9db400e10bc1ae6e3733bcfe735153bb21c7d1edcb338b102dc3bddc8e67bff76ad5000534006b998413163cbb7f96dedef0c99ae9f9b84124df520f3ba88ec4621e0096f7c25b229f9735177c9f60901318902ff1a18a5e08ef88bc60cc7dc22d9c000aee79b04dde3e1049b7a878837385621bad012ebfb0655127c742d3066ac500d16fcc19491515d6f860c352309e1cdd776e8831fde85837a45a353c77d6c200c98b533992624e22ac42da48b488712e131a1935d5f00eb53da51ffabcf01400049ad4a0a29ce850d4cb52c004f1e3b2914cef8aea757b5393871efab2230500c2325782854ba567817c16b14700078d66e858e841bd49f276efc4ebe6e98e003ad64e200a4d84d663605e406a64f9206b103567242ea0c9dc08fecfd540c600bb0483c4edc219fa375e19bd944a25fca4496b6ea1acf5de51f350080c6ec000018414b4e28f3af955c47bbc79376c665508c33dfb91d6c5909151ed62506300d24eae6e5e90a4c714c4d741281be20bc0c837537dda2cb36efeca47dd95ff0069bd272ca54501f8e4fef43354d9be64c8224072f2916b386e9059be1106a9002a37800266a273bd6c6ddbf9e5c0cbbc36810bf1d100ae77f7105409cc2f530031aa468dbcb96a2a9ecbd17319c8fd7f9f1d0a219971b3f40d29503028562c0012012c3017cb9ca775bcfa4898d48544f92ea342c647a2b1af8d6a94ec008700959e7c7e23456a2955c03d7e9c00ec895d596eb834db4c17d3a9f877dcc21300b5fb81d27525c5201f37fab5f1a105982f9745a1e1718e86ce5c3fc06e1dab003af7c88d5fed28f5f9404455d69026d83032e9a7bfd15d5f3be9f1ca8f00c30004d58405dc41f6237b62d38759a1e1f78696ea1765b2f12f18de9e4719062200ca591f3bc5df1ed1eb6e7c5e519221af4739d018050949c4a664d99695252200fc4a137616da8a1876ca2170fb1abfa7edd8c9730dfff9a23dc18525b38b2e00a8b6bbebd1debe698eca8b91132ba89a51d77a8832c087cdef5c667803ce1e0071713c640958c8eb8fdf3ce3ebaafa9155cb8b4fe2b61566f86edf227bd5b5005fe78f5e18481b08b163b2f53b3d6ea984194896515f98a7dc55442cd0392800edede8375feddadb42b2e06212f48f9feef980de03033e3eb1cf2a8d700e1100be3ad47bc63082f59574a5d157b490fd602b2781f2621461c87ea6cb5c39a9004fe49393a9afc3f1e7091acefaf6e330588b3c959de200a6c3feff33fe8a8400e7862a2c57cb76a612ee1413013017f807b2932178ea47b8ca42024d8405bc00ee778790b30045c0acce3a6d5166c38737e047db23b585816216415ae7404a0032b5c4f51c353c5ec44b52d86e8598c0bd61205196e6f428dbd756d98cb511001e4bea7accf1438cec0a33f4eb2e1dd539f4345a6e026830f0e6633a6a7887002b8213b333d9e8ac04a1257e0657dce17c0bb182f061e685ba41e992767dc600f7ed0efb13aec258cf6b83b13ef2e2bca1a0848d525a9c19f6c93d6a94bdbd0047f3d7cb6035375ed4e457941394d429b3183d90b2fc5fe18cc551d4ac99900050aa06511338ddec01c28f3d770ab5383254b073fcb0475434b9d3935bbe28006d8e91296bbde611209a39d9b5e89e054baae4909b8e8b6fe40621daa418a800e401664cc78b26ce4824513c0521864d473d44d717a5f398fdbc343cda9584000b272f3f4c5b3bde4539e61d81db31c6b95b3f8c2dfbb0c85abe250ea838d0001b36ee55ae69bd0354cfa255508c7736955c090e5b2692de1a534166f40151009269b76daf462404e993faf143dfdfe8b63553ec9048a0af2f34465660bd8000c9f1fe1b7a6219c4e812b67aa21a73cd011ac2e24486299704ae76e9b9ef4a0090e7c3614ba1392f6810840b486615bd5a1de402d6cbcc84df22517fd4f77000b5e3ae92d640f7ca34ab337957470899311155bf9a99f6e70c12a1d25a74e400237e97b6d1ee84a41c05ca4e3f202048f094964b7205e55d05d3b3470fadc5006e9f88f53dc73352cdc3888413fd54ae99232716627788b00bac61c979d00c006cbba5ce3d7c447190ed3c1503fd0305b405fcc9dcc5f356df87b3827cfb8100c055d1147755b021cafb5f56326112016e4213f82bc3078da22ba40d32b342002d579292a4c2adf800239a9ce0825007b90c7e3f8a439833ffa32f17e32ab50030bb0e94f9d98d5d97b003f2c65fb56ae958f19b5c3497eeb51a7df3f5d80a00f5bed168e6165a10e486b2f6a501d6d31ae9187adae49e1e42b13e9712bd320074d5d5531ddf36313a9844567de770378960abef224a36c0c403607696a1bf00eb82a57a15cad48de2694c32480c2068bd6978c97bcdd6ed35e3527cd735130076fb2191bfa377cb08f81d8e45de9a6a06cbe4fbcbcfefc10bf25e69ad0de600a27cbc107cb982f62c0363e457712562f35ba29b5de279f3b060aed7daeb4a00c3e8694ec45d0bdb8ffeb91996fd583b56ed83553c76298b137ab08822c44e0042354aa0b7a27f9506fb6a8e27e838af65714ede1e8e7111feb03090ee511a0095d42b28573c04645620dacabed21cab52a51e8665ea4d1e1aa919c73e3747006ffd23f98e7aef3c47f4cfdf58cbc2244546c6dc118999c0d8723027351296008d56a05bf320138890dbacab0cab5c34a8914bedf68c4aedf6fef68cc87e900070c61a0784db95dc5bea0b3d7201f28d8a027d5083568f4bc75c19c217805600fe505bfea4db9a08e2876c23f47d51a9e6754ccf07cfcbfc6baadde4b1f0c2009c6e391fe5c3c6600cdda243f45d09d61fb45662d02ac1d77da60b47e3c5260066a1e0328d5b9ff7547327eecb963fdce797405dcad235f0fcac6a00315d3e00d23c2a0e55649801253788e23b5b364f9849d972fdd869ebdd0ade8a535e62001a1924cce7768f903a9ace0e2e544900a5fabd6ce6dec3437db0016c04140600d20e4ed2a398c0ba9b666dd65277111f4c2a185ff21d86685de5cc5f19730c007861c0189c27617e7665f08f2e26f89d9d880ccc72b21bbdb5a2a1eaabb7ac00a7cfef3d012c1603ebab46d2043429d492926e3789126bdcb3824810d5e80200acbb824905e9690a7f80f2e864283572d998b6477d9a35e067b53ef1f5771000d959756ac0a5b51575e1750a529360e6be759a3a52de63c3a5c55d167f19850021ce0c8bd5264abc5af43b79340643b36acb318bfef96ec11f9a00432856c0009f872346f9fd694265db48166aa13ff155dd4dde88bfcb17efbc027626a18c00d89809f10e930f422c0a74103b809c830408838ba14f0689b34c0e40519bae003402b857931567c020a2c00f16a7e28a472cdce65d3bfffcf79c55eb25e47300a835625992d0764ddbf5f98f1aa9fc24dcc0fd5b156dd68abe124cabe61da600934c18acf56a53788d7eeb1ea48970ff7116bca3c8c6a445d095b3eb78f29200c6672120af75c972c311d4c9ce2e769daafeb4490d3fe740170670a8b7b6e1005c20d123a5c97f25004c6c6695557d9852bf39302cd0ac79fe7065512a483b0085d5a153b1510f26b7a48f0478690a716d52b9c69ca7449764218e4d860598001be30cb9875a6a6ac9c14e735cd2c2eb4eafdc42f2f5242378164990d2f6cc00a80ad4f2de4ab98dabb2971e15459ffec6ed96115c58caad0bae5ca545df040080bcd39be7aa9cccadf1b9240fcf158ac16e747dc54fa978f712d3fd5a544600bb5444aeeac6751fc3f336c35375f2aec1295f51e0f454e4180156657f192200e271b81f124941a32d841e7528b623208c9527de0facb948cc8dc303e49779003d004a4cf6b46e53dbe4ed820fd9f60bcff083d3a8db47c03c0f1e59512827001f479cb9b7ab6ec4883673ddd77e14d87bcfc60dfcae543d83cdccd94cc2500035a3af4f490f40e2db589474320fea5449668636ce8f35c35e61723c3254af00e3f1895a13fe5f646fe70944c2e38b59c65d41a08f0cf758ad180d71c8389d00704192646829dcd306701feb9f2ad92e16d6ae4949a2edef66256d4b438117002dac16bcddaea13e665617f09f0510a1999c07bfd98471878f080dbf809c220088a145987d4188caefba1be708f8fd370ee9b92af29ce55a283032f845845900e963519f1c07126066d3eb7ec2722a101559f9fbee04abe771a316b89f2d1f003c2bc21cd3d23c37d510bca6e7315decc6cfa2f70f273585efe48e59047b5100c5575f1a68d497a0af89c71aa1c85e138e0aaec2263752521bd87f2f6c20240068dd07cec4fd1531c7488a6f298fa232c15dc6b960adb51b99df1489d33c9f00f685405e491c2ac43a1f43b6e79e76ae7cb8b6a6a298daa2ee2609dce7b1e2003f2ae8fa8e093aa3081360979340cd33fbaf7baa9464c66b2e78f8d19f8a4e0071fd211c46f3bc323505015bd3be6a713a711a78d788bbf7e51f2cfd0295440093c3913f42c23843d28a6a45eb73bee9304e3a47989cea832b8e25ac398d4f001ca182b815b8c9b401a6105de45f1e2f73656dea3a0f4ca4744ac7c82b85fa0092303299a36eb991b647e041e9b106b261e53cd560f0187235825bc876a6f9008ca3c52cdbf8c2cb523e50a6d474bedfe4ac9bc83e4e6a60c7a94ed19ef06700dfc076d38154894741d534af45c1256f71b7ac37fabaf96f704b02f9ec4855006f2772a3ecf7d55544f14649f40988b0ebdcb14e51bc4765f654c34f5815ab000e69871c96752265545da9b3864232c666ed00de802feda95aec08d48fa4f100e8baadd7b62a4d9b9b9e73b4476bed9d5f30f7bc44d1fc5f9259841e71de2e0085419a23482a5c9cfa6b9be7420ac1869c2d87124dfe9bbe3913b3d85e820a0055c2b61d028fc9440fd2ff677b2c86ca48c594141d949e83c4b8b15db2c28400e273fefe4d7eba03b8356f2437f52fac9713660556000a880d1647bee1e9d1004c25d53d7d991c7ce9077ce8b8d6b434949f74d376da856c76709fc6c41a830097321d105db10d678da976c4304f0a71c3107a2e4f8527066a6f2d0f947e9f00637c89dc4423da491bafe2bd13449a531a6de6fec408dbf8f2a532a528c48800e8b01b2dbaa294d25e4c60ff06ccdbe2770e97de1b23da351927db519ec45e0005b3f53087229cef35fd2d36e13786d02180afabbdb853e83b1c6c91003de200f635125b595cebaa03aac4297d84cf89228857196d662b79624f16c68c39ef00fc8fc9f68f98f3b3cdb136c48707c57b1aaa4f81362a1ad3d345b900c67d120012157a42e4d65a001226489ade09b8e983506edf5aaf12094104218296365400d8bb1f0568b6abb28b8b867d2455d6ae9fbc70b81af6d8c27118eb8816351c00b927a58c0d151ddb7af989d7a576e4ac2b2cc30ac4eb922c3ece5ea6619b160011e3fc08a1dd875428619d78fffeafed6c4d51488e55a2c67c4004ee0f1b3e00a5fcff15418ce16465e4cf11135683502a5102173769f0027fcbeffd4e7e80007e5d0bc695357688e7361f983941dce234c8a81b207c04bf70d1337fb71067001f21b6c49d9926bb915d07082527dcdee845da18a8f2ca22238702891a9298001438c8028e13f67553a6a2579ecea39119d2bfcd87234ca8b121c423748d4800a8b66ec59932bac3e3abd3bc78e26fcc5ea576adfbd3ac01f9b9d32c4eec83005d833eff9e7e480363595576c9b1db07fcb5048dc4ee9e26bd6a30351cb4f90098f17ad80bf9b29988e93adcdac31065a68b3231886a3bc706f8d453fcbb0e005be166d1ba74cdff2bc4c4502c51696773ca4451f5cafc59e4cb263c2f46e5000e8d769f0dc10d3b609368a5c0027ac693b509334954a528f5c5f93ff2802300d0f3394c2f13f107476b29c38b429cd75de7823af2eaa49d00647a131f33ec00458bf5afa998b879e69f431c9dd33f45d2ecdd199bd9a3fa35bb6a2dcd775f00e7bb65bb2046caeea20b547e26162112733bd909471be97e07eb9a32a84ec000405dcba6836f977fb3b26327b040baa07c9e1d776a00074021b8cdc4fd40b60087f0a97c13be7c6ec16930000f290d25feb11d1ea02c816be5b82577e52bbf0012c905aedf8b239e8f3a26e82200fd95cbb41667dce1dc709fee5e866acf5500750956fc1f39d8da9e05436f3bdc264c61efbd4c081e15a2206f74caf87def007f3321ab27df4eef5d19ddc8af13f91a22a12bb5f9c02a71d52e5fe75ba20d007fbb5456ee68211f158813445beedbd9af9f40b5e059cbf373a6c6501ecb7500ee0f1c5dc80d3b8dfbca33f40f5f12c03544669a513576a1f61dc7200a79b900810099bec747eb3c87161b886920def96a349ee69cb817fff91a1928f150ce0074bd1c4dc861752ce74beb0bba8a1ff4420c5ecb1a625867d3aaa37bfdd49100d5ab9cc38892d64deebc89160189892aa1b39c717f4224eaf4d6a9771ab06e00c2eee3db509d85fe127f0f1dfc4a7ed390aecd0fd2c8da2c193db353edc8e00004796756f10319dd3c38d2d20466f84d259c721f6a2a708126abf576d9d544008f464458f9e8114b355e7b01d1e80deb3ecb78333a32c34746a4c13512cdde00e5eb55839e68d497bb8a68ac1b505bcf771b2bd2c0fe777a617e58872d72ef001719ccd58c6502aec0714ceaf74e22a99ac7ffe7fc957db70617cacc2b6e2b00ee9d597aa9bc89d80206c1a2718a15454634b464656b71613ee5d9f9ab6db7009bde6c342e52e9cdabc3941c52f691a36cf0dad5618cb0ca6eb0f8be71e492007215f1721ea94e710419f75cd1a8a3292084678a0f36c03fc5a1863250282500de05daf77ca57ef6fe456ac419bef1da74cf461045b5639722c3b3424c637300b99a2bb27f0e0e79755bf6710523a8575e62ca3bde8f8d67af0474bf69452900f2c14426b857a51c9603172d1eab1d30b653d19b2d1e2a12916ddcc3f0b86800c63a3c23b367b382cc8196005acb742f799e0ccde74e1c6875d69c1db1d756003111bb6b7d6f367f67d4be8a9f654384cfdfc49e6604ffd2dcc24d01c7f0e000aa4111179bcf1d9faa9e6cc6739813db74661812cc5322038dcc5ad0d80d6500d82ca00aeb6ebb3c9394904e31561174ce86d508dd350186cdbc8d7b4c8aad009f429dc75c90b869ba4d104fa135cd4b5a297af005b514d28c7e1ef210621100bcbd60835da607c5c514419f9e926f194b9c7e59de4e7a25fdc295fbd5950b0036b348d056ebbc03ad50382a7135e4cc3d01dbd7350dac63dc5d1587ba8d930036ceed7d9b6b0cf5a0e6d77a5d80706dc04b9647f237f56c4c756f9a485204002f93317a5dc86f14edf4bb4b56aff7a9ab418a82d0a9057b844055658428c4007d704c78861531aad2edffec4890a902cbc153463b4948c43f64d787f5d0af00f27c64e82193d2c0eeb4b8c60e97c289f59fb9339220569145a6764bb414ba00a7fdbbbadc681b7f419d90ca293d6359983cf83b7b5b47ae7864739b655426003d108ce738832a852896619bc99f73c8a94a83c5f43df7f8d26942e7cd0c4200ff650620eba6cf49f94352563ea84886f080bb8792107cb0578bbd5402289a00c2d6c7474cbc665a7fee2cb8822f778df7a7b3b657287340872f4aa341609c00f892b8160d28e0bd8ed7d9984126a33470372e5c4fbf2bda949fe4cb83aaa6006293c54f2e952c5f76db9bfecd119a36a63e417460be631f1eaf3abdd1e0d40062ad5bd44cfece1e662e37742c0a17f818e651906fb42dce2b1f8a48ae0640006586dd18b1d89a4af811ce9b521d7f6d5252b233bfe58413b4c555da179cc60049e8cea21fa5981a4a11664a655cbc18a77d9bfc79a24dedcff74fbca98ae10017ef6de651f095a105dd3edd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","kzg_commitment":"0xaaccc280c65023434e95ee016e4d91723f04a0773a6b24175e1e6fb823f607cf24f92ab674983e614b86b63c83b9a2a8","kzg_proof":"0xb4637b19b219776efcbb0b4de19144cf082d442483d36fd0ddd98eb69e9b342cc96a850c7e06bef5631c2ab3ab3ec713","signed_block_header":{"message":{"slot":"7422094","proposer_index":"129686","parent_root":"0x811c9952feff5a7c8325635f1729e31ebca866ed88a53aa5f26cd11d4b9788a0","state_root":"0x0bd0bd3f512e5f64d36170790010238168bf0dfcdc22fc438fcf12e7675b33ae","body_root":"0x71d8c523acce371dfce3ce7bc2897e62fcd72eafa2870be5ce6c08b94d444fe3"},"signature":"0x8ed9b52cc7323bd7d16e7685c4e5608fdc3144fd053bab8d2cc6cd19048b0214d2aeaa541dc4221e4587d9ef9830ae960b5d417951fb79d86fea3bfe31a9fa06a83af01ed7e579896afc3ba14e3be41b7934ddd1886a79cb23cd1a9031cc7668"},"kzg_commitment_inclusion_proof":["0xcc4ac137bf6baae019250f8ad48158a9fbd144be628a0f0343a24d43eb12d8c0","0x377f03971f37c0bf16cb7405a8a729b947e77ab49bf0915731492370ab12b0f4","0x8c0b1d87cf64f28c21bd39edc742ca5f7bbc3dd5aac8a97009fe53ccc6b47011","0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c","0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c","0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30","0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1","0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c","0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193","0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1","0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b","0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220","0x0500000000000000000000000000000000000000000000000000000000000000","0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535","0x56bd14bfdc37d27695b4efdf7f9851efa0e51272eb0fb3a5934f0d9f52ab0d5e","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0xcf8646fca4890f4bec369e0f281f4c3199f294b2f3b3812a4a2f76639c93742b"]},{"index":"1","blob":"0x001611aa000000000457ff01ff0001feed3a29f145d6750d7be9c0ae6ff2aaf000e619efa8ff42b6acc80b5fa6f3bfb1cd9451462239a49d7eecbb1320f8eee6000baaf49f9798277cb372e5f5562c35b3359bbc766628590abe7c082795a3f100e473a8448162a4518c877ffca9fb57107613132d52b596e6d207d833438f140094713eb423846d999ba04aa02b3fb023d970bcab5e40e6ed893b7113617ac9009647a0f1bad0a377f21286a7edc0dd6ab339f2f899db2885c8cd92eda7c278008d3daaf409402c65357369a9ebe228dd39c5b2813d6c0b16a90339127f9f880003aebb8433a76a957c2a14e7578b569c6a1a57ede4aab5edb4a8426848852600de406a6379186e511b3105d88123b4e42deffe480806a170a3e15fb6e1457f00cbba6b6ad1d6744fc65667e5c1a10319772208928d75ab54ee0adc0e253eb200923d23de17f5ed69b41df993d61901dcf986c96b4c0b28c1d62d1936103425006b56e03db7cf3e717c1336691103b037e4606bed6079ed64ab327560dfb3c3002282b90a862720a947fb6edbfde000edc4be53c35ed4d22ac0c32788fff30a007e4fe7751f5b1d651cf584ae46ab3ceb03343bc102ca4ac56ced914d874d5400c6fff3580b5e6afc0d7d410a5a79fc5a034ca1336ba53b0e72974aafefae7100423a67eb0cfb7ae18f9cb031c1c8ca8bed3365f8d46936b871cbd64dee3bf5005dc45ea3afa3b7827d711bfe15a56072c1a1e6a629b6350d5cfde8765f6f2400f2706640b94d9513fc2fe070087d0165d7da898955a37bb198e141d16da75900d8e63d19ea8a6166eef09349c7dac6678b9f84963074f5ae110f5bc9d208a500b12f463bc95e792758da8a5dca1889b8fcd10429e6a377bb5e8d8fc6b7769e008796dfcb21112b68fe38cfc4a7cfae28969bdb34cc248859330176b588a41d00e2e7d262cff1be93749daa3ae0dad0fe0a1de90f09da0c475a1ca0a6f7911d003ee740c22d904cccee6226b70a668eac1a65da00e42eac68a11267635568af0010525b090da8c5048041efa4373088eba3ea273785478d95b7ea4efcd8b32b00381897c59a71bf8367c27e53bcd30ade966df8fa060ad617f1311668975a4000ccd3daa31a3d00432d288647907f8574e68f580b1d4f8df637f0f8a283c78d00a8890526a6d17ed61d6a578b97e879c4cf8399078f207c5919555af7c32b6300f5558a8f18ba38f965cf7387e2f13d8da4aa1c48669f361ffa7b51e176a735004bf58c64e3de9e8a1c2a30dd38454b4137b9b16a6bc12ad118f87ceb41b4110081dc2fd6ab46356fb85c6af7999d3fe99735a6588ff0e8181cab94baa72ae70071e931f5368f0421e57b6d68a402602e0d1652f9156b947ecfb00fc764423f007f068e6ba5d62acc26128e3427f4e565da1c25eff6df224d798fde4f0d829d00a1bc973fe32a8a7548e11297205c9bfe6c88e97acaedd327b6cc47db0e606c0075e71820497b74d5d031d49e47b7a97ddb089cbd7b7d204814dc4be572c9c3001832abcccd4c66f0dfc5817a623bee513b69d8a90673a7c36887169110d4f300e26574bb5a84de2928624f284d0b8c67758fc97162e797aa6aff14c24dbea100661bc56285a02d1e4c0bf412266f3599390b2b5b1f26334accb3c7ed52c5eb002d046bc109185cfed7ee11fbc78224c095e31a551075641bac2756daec3471006e4bc178527356d0bd87f3d148cf09863fdbcad41ad7b3ea327b56e0baadcc00936e20b309b535a2dfab629784f0044a68b626aa24e89082bab6f570c564aa00dc7838591e5bfafdeaf0aa81983190b4425a9510e29818b355cf28849e4836008df61124e82cef4d59051251e7231c93ef23f4eee7e57e0ba3af05a24bb9f400cb23dd711231a3a49a6f3aa6c7d11129bcf85cea40e68d2c7a3f830715dcb50020daf720eb79b4628633f21c9b9b2d731ad248b01caa9eb2f9728530df2c0800d5f1ba58da1f9618c8261ba31d90bb49c9646e29e127a899e7aa2a63c969c90003bf24eb3f0562c5720957ca77cf5ced489bf03e4c9ccaa02cf44c080b80a4006eb0885bb1e338ef2ccc8cbfccc1541ee3c81c9ae0cd7c106226659baa94e000245aefeaf1a41f698cc909681708e155d97db720b690e43597d14c8b5c55f10041170237fc1932017451e80b77c73939cefea56854772c428d4dd65eae714a00d51535c533b85e3ab38d7caec298996105b52ae98b9292d5436045e0b64e90008f15fb6982d987c16878047be930fc54d54a48604db07ebb405a6a5fa8b027006e813c719f9aaaf7c005a7ee643e0649f80c277c42f42e40d43219cd71d1e5007eb8e59f9ebc1f823df9fa6d68b5dbbd9a3326498a8c361251c7840a4a97a4001520464d4c72a380625b99ac5fa92e71e10d09b34da819ca8edc67a0ed566b006f0d5f5016d0740a53602e37cd21919e2394465522509f6582ffdb50e7c17f00925a52b84cefeb4be14b7a3667bcc875433607dd3960aee29b99711bfee05f006711ea5f4b0e45cd1ed48455f187a47997f91b83dacb7ef95a6c136a73dced00e7bd999c546e27a9ee41c365c428ee8da002005d45a64b5ba613866652ec2c004ccb7241e723d1610e2062091e58516d3759722be2d2f89c83598db6c4bd410040a56cf017cf04373b3fd40c31e64e20bf2537614c3c8fa8a06a3e8b449f3d00decb73dc718c4594d39f80bf4b7e9af7787454d056cf0e4ee03e004d2bb8ea000f441478da292542761f758074c82c901457243b1e284dd432feca6374372a00ddb02cf2595fa40d7e24d7f2eac2823b2e623d47d1308c8c978b62717e04ff006c901371fe2dcde25c33582ab118ac1cddf6747608cb75c97bea9ca7cfd2bf004b8e853a51d3070be28ab06fa6b690bd0036dff60118acb6bf4ae57024b5fa0087657c06509bc7b7d24437e6279cc40d20099d34c9952b9a041232e898970800fdd74af0808fa6f889bfd0cec2abcd8cba79b6ff55f1d17343b1065e13d15400985ea8f001d57ccc01d7b6fc27206e0dc7e2f157e327e7133c1632d13c8f86002a7db57e4cca0e1c451486be1550c417d6517d2adcf4a28146bfb65305b05700a31f0653cef88af4512bdb9013294f5c5338f7382c1626ef8727f9186a5b920038893194e73a0401d4c255bccfd7b677e473c918b89557b57562a8bc3108d4009d15e7f55928fab708aba876d2aaba9524a4be3a0c1fabf259e375e25ff675005878243995c161fd0498fb464e78968f14df3086bf4926d1dcc5800f4b553100423930d0197a7f79e081965f2c4ff81dbbb6734124013c00bece44ff196c4b0030e7a509f432e5e92dc255c39dcfeaad1f1b244f978b066999fba47364c1c500b7cb7252255efd06525e312bfd32cfd7326a1f81c7fcb4ab98399b297302160094f91b2f600c13dbf312969299b62b8779a2f3e24756c5c2a4a36c77ffc06100cda210feabac96da650f2a933c297c119a0bfedc2e00b4e56343c765ed50c200c3fe55515d9cff54905f0c1b93dd906788a58f3dd437028393d35a1b0ab02000082ec94b41407a6d7bf4e7fca67728e09b0042a1698e8143faceff5bbe682500a76596c31e2313488ce3fbe150d3b202e602d459b5432969a3cabe6dd6bc1000182adb5cc8a7733fe5f278251015a1576cf60dc3542c1aa4bb79d8c30c650800860ad1f9deea82b1e9b8f6a0eac6604bd053ec7f95444b2876344c475a77ac009f48bda7d00207b5016a77aadd6284c43ce9d43576e0f3fa67618376f1eb7a0037259b7adc8eb0d7e160487874d044802fe3e19beeab57059833f6f554bfef00f930400d10a06a6fd640bb2884922f6a931ee73440a90ee5046ca09b19c08800334d3473206ad6a417406d874a1ee26011e34d30965d18b21470c5c1958107008cdacc386485a992d657449c7e6ffc78835db1a8d1168303e97715ba80789f00eb3767cf212b93296408be0ed4514ed502170764c526324d68dba9f687ec23000d6d83419a7c6fb53444bddcc8bb79060e260bde8dcb28287a019c12406652005580e87cf485698c16e6e240d365c406f86595b0b2157c6a603bb1dd0b68fe00e2cdeef7577a2bca734a0d4d40918e2001feeb85809cf72b425ee728e5fac6003b74aa4d377555469f7f411d6b795820f8fbcc4a2caa2da8d66484af78dbd10039aa684463e48a94bd0af894fd89f7d149fa3390e414c4152a297979c6870200cb794ef0ece1912e383f1a122679e09928cd118f6ec149a39790723286661b00d4ededc3e31159fd287ec2f9f0b33c6f2debdd45f282b053470785ce337e6700b4bf2df1c4808a19d1209106e6ec3ef0fa85a35471a1f0f69162670c81eebf0037d8bb08d3f029e959b8415ae822f14646e968ec0e85dd6d79a6853257ee9d005bb4c815a674fa27aec00a8a9e9e258803507ec38c61d973e58f3f23b414ec00ff32c8b07995b9b1774b6ebee3890454ace35f358a651096d8fdb0cae53a9c0080ac499967171188c999cc4b14cfa65d18fbc3b1908b94dd3eace2b4f519ac0093d4eb8710f1da5f54f550cc0389ddd84d116f047bd3fa01de2fa7efdb648c00f9a9e66878d6cbed2e5c3d63de674e3c70e4af7ef3ed8c02ead49700d0b0ee00bea2d4fd278ff791fdfed6520f4ed0a768d11cb8a6e0d6a097b3da070bf00e007ba5f5c4ad09c7a061ceb02e967b0eb1a235fcd29c80dbd1490709f4b26c5100b681525db23fa6bc4e97f96dc8524635329b9820e0a66aa60dc65408d6a96300ee361372c8198008d6b93e93d6a07cafa7eec631dc61725c3f9b854f39d0a300ef71d628a01d3164ee6df004d5898298ab534a1351a1434d669560168f66e800b358f86baf023efaae86f39ef260645605ba8c4e96a33ce551af9edd695ac800d9058298ac294dbf3dfe181b557edb32d313cb66cd1585d47700b0ac0bc79a00b5d142141ae3735bbb8bb7b6d3ed2ff0bee08702a4f58f84c068456a5e56b400edb54c84e791bed9e5d9687b4f72b933d734c0dd53f54319137b85021cb1250095d94918eb19fed157c534d4e52dac39e9e7f010d0dd1c3e333258d299ae5e005d9014aee35083470522518babb968157c473b291bbe87878e8030ae389a5b007ff8e186f56cb2a5430c6b21d03d827f013bd922143e118e9aa2f45a0afff200cd1c4c7361a4ce4032dd070cc158c36198fdcaa895446496de3724b58a2101006799c4dd15bbafac982045030452e7f7b49e37deb27e47a715490f02d9b9650043a5fcba18e84fd4921ff33f970b01a193a29c9069e0a72617f1dd3f743a75007827328ce69891c6128ed916d08cc0e57020433773430fffb342a50a4d86e00060ca32b7beb6afaba8037eb255c99dd14f142a625a76f120f05c577a2e07db004e6a40dea27be193c11b16629e6f6ec009589c94cc7b4f056a4edf2b036bd400193b291273920eae0be4ef21f48983e611b853197efdb9a0b7284f93b52141004c15bc865bb9fa5c43f39f9785fffb360d10dea5f696e839520f18d91f756e004d464e3363e98e03b066625e7dfb6be42fd0db0e3026b264f63c3990fe06ea00700711c3ce3a55158eb72079fbd2733fbc6e323d7c1083659d4397374a37020028e91fa17a911cb5b9b907147c46539f1e22d0e42100208e165b95da8a70c500598447edf135b3883d478952ff298d45c2c28a3e3ec38d96c2acd1c99351d900d0caee359b1ad86774d71f7d383ea6312979cee0a649e6055a5931e19a71f9003e54ee3355a947d549cbaa9c2bbdd0c899b7d1f596a22f72a3be036898d844006f917108b592dfb9dae5b42c2dd0869f2586878c5618ad3d1466d4a8b8a8f2005164a119b4e4b3d69ad2d5dcf82387a5247f40443d5151c5560b94614ffe5300185d4c40ae25c3b9b39d5d7a4bbbac0dc4d7aac6374c0fc8381c093b6302cd0010b5116108dc67c8a9cb8d80654b7476e94fd07b14188bb66430463c24c57b002cdcfd77fe43178edc6e113f7c7bbc444148327c0b17d1baac2f2731e4c9cd0077078590f274df613ab512c6e8353c0e3f4ef54383c65d5018a9e1b0509300006df18d28a2c9ef8b2d57927cc571ac4831b1c6b2a2fbc2c20f0f754a8c3e1100c1f5b121c9bb884d97ce7f45790f58231946377a554990cf80ce5a1cb541f500cb59cf875c5d26d27f34edb8f8653c0832af87d037b9812efbd1617c605d270028b7bb2ecde75cc124ef8f1ae072af3360fe4c4a036b65f0886759f61a56ae0039cd0caa572052f02eb6b640aa2f6df8edbc9d16fda5f3755de7ac1a160cdd00584d20868ce16985ba2ea9a9781ed73eab0a9dbf59ab84ddef8e262d03e40800298aa95fbd72b625563460d037d39bef685ba20b4e9436309526f34f96ceb20069262a9b786a338131c19db7a4fd8c554f307d29c5b43f30de9e282c9d52500089c4a4c04e99c2468bcf58af00d3ee8ee50c6bf680ab7ae1e6a56f2ad2a0cd005c5b0a7247258aa186db626ca6823172e8cb800fe1d97ee887b294f1238f9b00b9fc375d741213a15079af09ed7fddb468f78e159956287a21c1d3abc1094500251b194a977055cbc22a68749e5093577ad791bb77a2deaab3180210b3e3380059f99f743ddf256b36fe1c20454391b60b5ae76ea806ab6de1363882e44ecd00cbf5296f94d50d4d2023eeb79298f4dd59eeab7301b7777503c102e5a812dc001fcbd99494a6f80c292ba15a7a6ba69e8aa8de61878fda02505cd6a3abcf9c0032e4c4634dbe766c159fc74061f175b5c079247f2fa07280891a6223546969009c13bcf00e6632851a99cc450ed21d74fb294ab0c2b73d345396319ba0f192009b30be2d25eef0233db35742cd037b275e23a920ce7e9cd39d5a476c93ce1b00743b7336d2861b24068a5f63626c2855f73eb0af674c3084abbd246e3a1ba100fd1d183649f91b831b69da15baa1112759fc79c98193d05d4d90fab2f4997d0097d54e9b1423dd6942e98e180f6d2b9d71e675d34540a2e7713131b365c32b00d0487cdf9e03ec641c12c662b130cb1187fd6868f0347bda70aa618bef8a6b003f54bad0751abee2daae83edfd7bc62884a43240ff980186c48d28a568c45c00446ba37190e9bf5f060e0eff71f69f4b1af32bea1519de915de603594504e3009797817c0f44273c3d737f5949547426c0c558fa14335a84ff3be856855f3200a2bc0ee342730a0144fb5638da4778ab960d46f7af5d68742e7373ccff252e0005aca4f0ff0e858f61f4cc67a76ac254e1673e81bc7de9a7a9ae4c8b1c5c41006123153f9457b54fda6d0816d74039e3496d0bc0f52d94038d91835d22f00b0012b5e872be6b50ca26241bd7596477fd6556e09443671a0526754e5795578500b3deca51e33b7cb1dc696805e3784cc8d58ab769ce9e43347fe49defc8ee80007c47b52a7be5d174917853b82612d7d53d009e639f5c91fa6f3aed2419063300c72b1b084e862029e003ef86e716e45d07894157f3aa933aa3774ad61f941c0035e85033c3d0847c0a9abbea28062c5f45d5432af195315c566948a4980f55007a5888d44ee6df96a97a97990b3a8567198e7f1715567168ded04cde06f78300be74059022867f8e25bbe597bdeb36b4afcbeeee3b522c18d7bce892573ef70029c02eb412076a6a61a183790e71ac31bd8f8898cb400abeb552ee6b998a7300941f3c9ced2c513cfa3783871c7944e39b8938a8ad03851c11f09b5763b98100aeed0cb2aaac65691dca87b5330604af85dd375ecc580b4c779a9368ebc5c700ee8c4bec83533656e2c5e6735c76dcbe763ce828495a6b57889f374a61cc8f00a5999748dd55513322bb6ec214b44628ad187531e7f4062348dace618685230034b4c867e53294e866de50794fa1b76728a7b4b76722643246cbde5717886a001800ba228ed77a5ab75cc1bc26c8c4e472e462f866aeaea0f49a34ac9c74960058283a19e538fdcfd3431371b37b13632afb13373661733a2211081484dbad005314c06933181a7134112ffd63c822a899d864dc193489a18115b345700ec6000a773fd49ed8fc0823462017ed2bfe9143a2c0a56847075d192eeb1a7fdccc003ed6cccf5cddbe334afff3e27123ab048902786902c4838fd2da050cfcaefe000fee1baf3fcfc411e3099ef959548430640a984bfdda3e950b43e7dbbaa4ae00158b4603ef690041e9666528841a5b2b1435e3ea0e3528690b8612baef2a96003f7dbbbfc800724187cc8debd82b79fdce5106a2a36fa78384f5b2403216ea0034c0bbd79814254a3807e2b4681ebff62c4a15c649c8197b713a6be03ff60800bd6260a7bb562fdd837c8ab7821a7d6c050fbee5e23188e86be64f1274801000adda35a9b64271485ccbb71997b766c1db52f58d17d402da0237af1bec7fe6007f188ad0594ae227492dfb72bfc2db5b010831298094903692d6126595876e0047e6f135f26e86e4970629f4f5d2362d51115e83552913af4a642fa84ba0ff00955e82c1318c879a73f7627094e46543872a9e3797a5632c86eabaa516addf0084b7ad78fb03309ee8f49d423d569ed85540e0bf371f2d46b3b938ac3fc8ec00a996bd0023c4c36730cc0b9858cccf50d25a3b8412fc345750aa75f9d2bc3a001f2a8ec30366777be40615b666a1d44f27699a7426661b3ede2adcbb390659004231f90510ab9d122899aa4e5b721d05dae0090180582b93a72b8aaa9c13e50010585b958331693cb8f0040a0e46084b60425a44c8cd09970864b40f0539900093a94b6d63ee963d56d0a441db997362c3f24d049cbec78ab385c28a67a8f800e528d2320c8d182454d1a1777e5766a9a66537f2cc74e91a480ebcaad8f317006b0efaf2da051a50376f438bdd74adba8ae74e7429815b73834c915e54bc0d00bb276101d4cef85571237a43bcebe23910b695ad4ab6ffddb15be4a491a74800a25225dbdb572909e1c46bb53bc4118f508067b513d71a3fdeb5c5ab651804002fa9d54b78273c510e9100985a4c5fc7ae28e2bf87b23cc7e6da685f1b2c5e0026b9fe3be81f49e1f2103fb1633c6cc511005cf8c9fc54de141b403f3f5a57001de5db33bc4093b59832b33334da4d84570b4cdc2067fb4bf86f53d92fbfe100dac483d5cf6bd7c54b7767aa004e5eebf791ff90fa7dcb2b2fec9914ee9cb1001b79884d612252f6e8a2974655711b2d426c8a39e99cfef793f70fa13e1951007e04003004b98235a9b3753b8dc61b22c3f5305012bd02f553715127d1be1400106cb91884fc7cdd84e94daa716940f2f5c81fdaf15976e14f644e98f84e300096f07ac52dd0fd537a8bf64a15fced6d8d54f202ed5585c8a61aa6d9c2c333009499a1080dd4073d6469168da757ba84c397d2d26e0ab9e8cb252b4f08b42400e441612137d13da408810351f09f5df676acbe90268fc79bffc07472ecd766002b49b01c967bc28f005ff564ae1393cba4ead3f31e3b9ac20db79ee5b5df0000de4042767cca7aa076146fb959341415a381c88efda74cdd5d9335aa645c20002c97c4f5f7b67cfa593b814d59677a4761157158a8af5972828f1ab593e82b00383e084ba029ea6b8744d60117936bb9b5129ce7da165c2ea6151dd9f76d520038ce7c93a98a2bb9fbe0284a2827191344ee81d28a3af7403e4ac329a8423000f9a7f69e5819bf664e8421f5f41cb488a940cf5c6cf5cc549426943c101c370067a2e151b769198fb3e875e26fe703a8602b893695e60ba106e7f75cc9d10c002acce943ddbcefcca20867f13264726217999611b5d9c5f1014ef326fab27200278c7c0f877e26d839d38662cce270af57738aa07696bfeefaede94842cca700214f3a0fb55a9f5b4ec9a9a5cf6d761b3b6253f2ea308d098295840af77eb90071ae7617409436b95eed3753df6037cb549a53c72e8ea545d2ff83982c925000e613c41e92e454af0ee7694d2e220c83795d5c48cedd8d4ae220ed059235bb008611689bc37f8a749ef181c6e658f0a562893d27432eea7976b7011be477c10009d16bd11e2db493577e9cef349bd5e17e12a98b8abc4800630ee3dc58e92b002fe67837b97bfde6664383a23d5bac0289e7ce9653c2f8751fc8739f1693ab00edd87a68917acf146945f5344ce4f6e7f64a670b985eafcf2019f751ad6d2800d3e461bf9bd3c6a6e669deb9cd883692e32608d939df23adb4a3a65e1ae36b00198583d675e72fd437cafe71f96e404bfdac6966d2f4a0fee3511cfea20b5b00cc2c25b2dcd1484921540874471ba68a15d41bd7c7814ae3b84ee2dd4142c200c3aae41e78b92b2d556ce1adcf20875d1600518a489603c4096d4027a7d4ec001792c51d7b35d58e687b9e4b3be624e5d4fbe9795f32152498c859201ef35d00545beef13eb1c1ea24ac93432db5879ac12bc204b2eff0fb101aea47de4da0005473d093cac7bb8282b1249b5e70973bb6d649d47f7cf200e4fd698438690800481013e52702457a98e4289019356d4df4b277c52cc8fa5777281bb4f8e70b00150c9565c4b563f91c0f0ed9476e06c324673660ad62799d35e1ff7ac879ee00b21121503936521f70273c011b35ea7c443d898aec59c333bb4494a58eb6ea00c02bf4899944e74aaf472092bfa165c05a45ab08fe7836a4fd323ed1c7d327004ee675dee7f0e7996ab98c5e7c66802dfed06ed7f66581709cb3b0b015c81f002f4f45b0524a25d566064d96224bd1cac8d63e882465e3b53056c40e925aed005b3422b9867d5da9b7efa352321f48643c47a209fadbd50aacd2b502a9018f0088cbe04bf303d453ff8c62e7cebe659760769a7f59defa5ec396f0b56287e900ff3aa4a8ca88e1550fb8b023e21248874c07c793bf60a5a72023f81685418b003d538a97a9293f63ae13a3dbc5be5ce1dbb51e0ec7f7558fa8506d8cb8361000f4c63627506aaed17f503ef10aa5d88bc07c8c1b016defeaaaacfc11a0f9220089fe56199d683056f8fb9530fb8d7ab6b702080d5ce0d179b03df7765e6e84000baf38cf411ff6ef52a900a41256d2fb99f8864001631546c2bd1e3e12b6f90091cdf37165408f5c97054198d2eaf50de601c4b6c349d270426805a6a561ea00a531d133d7425ea514055cb55d1b33c28fc2caaf7a07412167a194e31ee8da00a37335183425b074e504a5e197b49ede00618577410519cf63e3c59147b283001387afae3e08061bb8cc1e8e31a6e33c058a339425b57744544b1bde388ca900372ac23b8ccb2b0a779741f5231f6bd8e34c89769a5c5a9b6bd70e26bcc646009cf7adb7a7b2a714e1f435ed2e984450ab65971278d9f85c97fb5a7e7a0d2e00e5724090eb66e7ed5372da14ba069d17bf96d4b12a1cc8d4bc0366268a8d9200ee4f7fe41fdd1ec6425ecf4f4f1e9761acb07aa8d498bc4918bc62db95e558001c4397e9ede627e03dd2c6d4d99a9d20dc970b9d09f665b4abc15deced744a0024e19bb4fe1237ab446d705230006c67c4acf278e0d6afb3355364a704644a005272e139a10b0d0276b117a09f4a0a6ba09b02c2d46e5d05539698acdd6ee100cee449281847ad7e8b398327cc5cf0c87b916e8cf771ce47e6b71f1bbe71b30067aa67a2ce9c95955d5935ef1712acaef16ae4e43f3d91da74687263e14c4b007fbbbd51765abec0e58fad0895d0d1780d2adf18b33dbb06390b314fd843d700cdfba8b00a5ab52f218d1e9f050242cce380954dd1fe7af8fe50c4d9be0d7f006b9bcc4ba3a1f43147f77d6edfe8fd78a17cce68c8505fc5ad8eedc59f3d7100424f72423ee8bd8d88650b275ec5e48e84bf4e1b8e4894ba016344d6fd41e900a91f4738aa07751f76cd299f6da730091fb0d3da136ae3593998788f0821b100cad49382365603a4528b837a79617bd74e0d564b61331d611662c61403611600c80215f344e849ec002eb95e0aadcffe8bedd22c7bb1856a0b3b16d26b6a56004fc1da9174b2b7ccfde475a8a87a50fcbabb10a8aaabc72b9ac71407b5807b00be0d770ffc81e15e846d0e7def96114b8b7db21108e266b558367d51451d29008ed18066ac682ec3d0f7658d920d4d1cd01a4aa935703eb1805988ee4d0a5000d2dcd64e6b0f4eeabab209f346ce028eb0d0cbae0c18e881db39367635ce9600ed29fa40e1ea3e5378ae7394cacb10c08a33b9c5fbda4e59628865f574458f007493bfd2fca96b1cfa31395954acae43b97a2fd3b9ae7c10d480a3b597138f00f18c2378a703d49fb837e0f43558bed1f2c3fa8e3417eb38e6c5473767181200a71d29fd192af92d47db10e8fffc1afb67d9ce287a9d315b90e2a888f40af200e0a7af9224feac872d586b3530408e2b347cc08bf118ed5001fd4e3c27cf75008edfbee2bfbfdbc573b80b5d750c25b7ba3eb0bf2fda2a19e5ad28500d180e0049329647b1bfd601380dc66001736fab505ea7a8188758b5b4335004860632001ccf3f5281854dbfa82201be03408def0c86b83161823eed0be802f6200c8a005c70b34119dfd1d8c845a18227b48ca964cd704f1765055ee2d7a178f8020a006afada31a2f4dfa2032bdafbffec36222dd03a544de9854bac2a4fc00fdcfc002261b87cc23d39548d3c5295dd4462cafda4fc8d547e9254d03c27cd2be7be0032265434aa788ca6786ee95fad15bc726c91f30068d83033e0fdf451f26764000f0182f666cf8eb4c10d616739d657f1ca1bcf40883259a16b069c175d4fc10082978c34b6568e6de633bd4ad2035b60cf851a19425e19de9b477123f7bd590087a09c4e6cb367daca72c8409625c05ace1b22917fa5a33533db6b2de4da7e005b4e113547a23343d34caba5f2485d73f8d3c64176890caf61044834b401dc003a586901ff32a445b058b0a649b29061eef59b2b1d434da03c450ebd9537360020e132c3de4d7abd7bc247830c0ee757afc0bc6f6271dee3333f1b49fe04b200c5ac5475d894386fa240ef2fc43c945f75fee7a810ee05ddebea74b696ed010088870dc1ea7f87cdef71dd410e6bda4be1b5b602e8442be61716cc87d0840400c93aa947075a61d34da0d3200b91a24d660e8aa14dff7991b4b7c32a106281002b75757008b3666a0a9898e8e861b07d469282f5831c0be88b60fcfc31f366000a7a015d620f57782b4f5c48214996d11ac2aa17443a70886a45dfaeac0e820066d4b8a4d3fa116204de052397b145fbc2e70544c6fc9be912e221ba4ee74900574cea69834b0429f4d9939f53a27ff800117976a3b61652dd4e5c8d4000c3002e1981bf93d07d47ee62246ff2be1c4454b6bd5c0a3fb2b47014ca889c044e004bbd6f98be60a63676e39b2ede18c71b7dcc53f85cc75773a668f3b5a328c00044fec09b351caf8a1c931bc5cc755563d6d9eae2648209b88a74a5a9a8b7ed0043984d478454b21c395f303a4021e9de3373c76c0a2a3c5cca14719f77d02200f8d27cfb5b750d8ab8b1017b975c2c25a9d84a379b7be74655d5e63fe38fc6007369dee45a7601d0b5a1a95da82add3429543f0b5c9973c1bcb0ee07745cb1003f0d335585de75162feb4feb6edbd5227fbbdc9a54813614b73c1b34f3a42d00e088a189778ab88a097753c608397ff93935f3c299a573c0fe830c5da16ab700a268d0d014ada576d9e9ecead54fc0e3d0a03252f676aed4c83f62bdc38126007a277931be230573f59e14f344301d90c2071061a73ec45501d6f427add22c004b8524cfe46d56aa9791259b967b14b69b446c77a667132c116e5ee965c2c600fa513ec7ed25f4ab63d4810bfa62061e58619793fa74c6cad77f6a0eaddadf0058b29e82a6fd579236c7951e06cde3117a0c0960b9eab5bd3829f43bdb020100f2c7b3ad5a3ed4e40eed6e6e5e309835da645451ecfb1fa848993582ea503a00d3ff303ca3c4fdf0ca6e38b62626f7fdc0cb9211230575d584c91a660b9d1900c343033c9ca323b53b25b0c5655b040c013055b731b6d557cf3b6cf146b0f70000b7ddf911d2c958984191c6bbcfcf6de3cf95327d55357d566131a7701f8200d00b71270855289097ba7fe6892dd8147f59589511f7baded0953fb918fd62002fe08304a8723ae689e23c3ba18a2bc591d91c80103ba5ded0b893e1c9dc5500856fcf4eb820f8c5bd25a5f4363d7291211e780cb2e6a3a2fa30be720894bc00554543d86fd1b763ec761a831bb6d0062170daab14d01147445ae1c75b44120017591eebfd477538e0f3cf336848c8059cbef037ef7dec0485bbbae33afe57002ab1a5c1c90fec101659a12f24c40531d696017c70115b018a593c0042d01900f94316b21d685c39149c6d8ba0be8f0504653de97ae3b5de73d50b0057defe00da9d029f7676cfc5b5a791063fab4a35acf67ec6637eb21b71c73adbef5c4e00acaece14817b95f40c92fc5f6f9c2f644193d690fb3f7236b094c0c559c78400d2dd36b66d5261055abcb95a374a81aaa8d577005162d6defc7048e255ebb400200b5b73518a1d677aef7d4fa0955f2975bd791b57124d1162e187e36e8069003026f21f2bbce5eb02aa5736d90ab2e9bbcef5d846c6135ab003f83d921f9400f75eb074459b5b4238eba912584e1862a2166259876d2adbea129df4f88923009b4ab7b340420f1fd2dc7ad0cbb413d99df8318b36affcc4c6f3a6c02e67f4005c100df8c5087a46d6e820c752502db252aa83d1b61fe186f6689ffbbb55fc00db7f38209328a04e6527af6eaba374a236d3c4257340e6641108dc865b3e45002c72e83a3af1a4f1d032d342d0c1ea9ac071fa3b918a9de9721a8cdeb8f540006a79096c02e601943ff6c36963cd0f1f7c792f7dfcbf37f6c8f179caf04ef0006122f1086d8b18f4ce4393ac07bc64d1748d270a2a554ebf7b8d2bf25845900094a0e2c7f56c000f2cdd5a58893d798294fb233f168bbe4208868435eab49e00cdd9a359a54ea22fed4ed01716bf5f0b422ae84dd544a7c5d9c89abd432a270021e6f70bf069730a19afaf3a0214ec25dfeddee6ec8c644f80e3f7b16ebbb2006d21f334cc0635d57936f8cd42254660112534c477fd4116e1c2d749615635000cf2ca5be24685ad029338a565369a4e88d44966a0dbeaa736490616a66edc00a09894d6c7bab07ab79c1cc9c28e8d55ae8f15e0835a4305160e6398d80c26005cbe687c0f3107a9cc51db2890213af784a497d7d8e600516265172b3e112a0046de3bb8d9da430a95a780aaa28de3472be6830d8eb761f73ef87d48610ffb000e80d550f3f7c7bd8422e331097cf97af879230bb5d571fce9b9d9e115cd910036ddf4a9f0a5066c387937b2555737a906c85dc94ba592b97d31a524e5f82500483184bb4d96abddef6d55d891f2ea93c02121100d7e3bffe66a0e085329f8008b6c9d0cc33e5ef8fe03850a77b1d6f45c99b7b4f4990f511d9c34645622d500fdc8f1e5b1bff375fdfb420a829ae17f520e6e4b0e642e6f7535cbd91d7f6e00a90cebcb0811789e1d0b08725794b36e627acd14fa30bba3cdf14ec0b0c7ca006fdf9bf91daf8595b50fe96bbc2a43a03f89b5a0a35c0be607b1e8ee6dff5f00b2fc01e6ca73e2670ccea67fba90e3dc6d5452ace450d78478f532528801480016b1b212323eaf17e41ff309bdf9ba9559e5cc66b25da7c9945967ab00b52800d0945d63d56ca07e349eb1acb7113b9febb517e1eac8862543aa32c9bb4ed600199d87c501568e96e077635c77d9383298e3fc679a746441cc16266b48f01b00939cd07d1404c8f7409aca857ad13f16424915dfc4ebfbc2a11c23ecd2411500fadfe782ffe796870e2d39de403a383ab161cb349badf28c5612dfc6e2c9e7006b83c494948c32c1f7f855b395e6d69cdca178fe8529549c2b0f1675d6f86e00f70a7391156731e9acc5d76ac7ead90593a8c935b08b80dff8148ef26ad1360072d6699d914745be29d6f79ccdc1fa49509df6619e64f3ccb417c9230f0320007e1fe99f102efb4d7903eab4b4fcd4f9bd193d258e8737ad28995d044a770900aa2278b70f389e739551edb4bd062144a9b884305f0e354a4d67ec121d43a30063da5c474da56e42f07e3e1104b804780fc67ced025053b34066cc015e77cd00bc61aac5c50b449baaa5d4acdd730d2be3e8b97512a23ad5d638e2f75dffb600c1af584c0819d90e2dd01eba8244a471f49c14691b3488690c0372f61e1318007a6d63e119e21db9be50f19b12584927c0b261319d20a1d2206a2ba253ec3500e10e0028aa2e872c924c0e74be9c804ede85df5aa9dcfb183c41daff880afd00461af2fef6a17611c10c622f3bde790b95058b1dc93ba5e14c3c14ba7034df000a865bbab3722e2caa50e8b4035f40664fbb53238e401d258ee32a159c1ccf00592489892bbf74518907c2c6010539d75799af28a56a1451ebdffe8c02322800d3ec25e55069ed6c05773110cf0088c2cf6e4c56b90a095c0e51ed9adfed6900d3cb7ebb3be50a5e8938cbe9377ebc778182c95c9243e303fc82f0e78653f400fc47e9d427a8faa196c31b894b0ba95623d5df262b0ae633ce302b63e5cf6e008c3bd3ac7b47abbcb188811fa049ac513d1ba9821bcedf82e1cf40e56eaa5a00def714b7b15deafd28d407ac9e261e74615e79f947866a2dac8748316ba6bf005a954a776cc1adc21805e58ceead94fe41e1b00c052df55012df6922f2a98400c240362f30a5e111df43b280854762fb8b10c82fcbb7789d30dd2df5eb3590001e3b2c43b8a85b63ceaea4412328a5058946b7366a65659d05b7ea0b2b714c006ecb50dff08167d79a75a7f5dca8607985552b339e760508bb5883bf2b598600fc07fcac1e3aa34b5ce9053149feaa528d3cb00e37044f3b7cd1b5be5e94f500fc5a3878c527809ffe88f4f4d96b11d05ee2aaefba47f342bf76e0e1d9d7f900b4b64174ab23e86a08fe6ca7d69548c0b2fdfe4d468152bb2f7ecb712138e5009b982f2b233640e7fcb5b735cd6a444c9090917ba7443234bcbea182c13692009acc49a501f63ca7b451cafcb930ba305c629a64847164412a3e6c5059e6ea00048db4255497daf9bf9657a24bf9b9f02d481a828b747c658852f5e1e80d7900ddce3f59a390b1c94527bd5cb75fd8dd2c5c38b8d76ad3ae074d9884ff719e00c6c88ba37e9c553ba6778f01381968ed826d20c85f703ebf0d30c3d446641c00188bca9c4eb49c3866af0c6b195ede4d31384da460363c4e37c14e27288c2f00aba834eedcbbe9b3b9bfd25f9c3e67468cd3315a79838bd0341ea78d6cb591000619aff42fc752b115e83a842b3b70dd0cfeef5262f25cb958024c0694369e004e001fd975f7ec54b6e7bcb448f99bd395765159a35872026a3ac3ebf7129800b9ff131bb9158e08007f67a6606b9f24ee108e51107ffd54cc2ea7bd270f4e0058f26eacc261a889f9f15ba79f21f2bc816368c77f0787c6238b08512e5808008a0a9b6ada976a223f39f0d3841e2f18d681ce1c5fca09834582482779990100de915e6b0262fb1bbbc177f5487383354eba42882e55c99b623fcba9f57ea1001e58ea4722ca985270320be40612e3b4c7a8c3ce4a7dbe933ac45c54a5c5ab00ecb91d59a4498b9e8491284056212f0ddf32997a973d2058f6e1d93dcc3a4200003567c48df861d6cde462d5d16fd293f3eacbe7b50a1e8e8ad811db846070006f8f20e04941f118c6e5ad4bfbb426a8834c76c46203846151aae64f24aaca00a9d6bb8204a214d4f664f06c9488578fdaea2706156138507a6d71773a93cf00eae08860649b6f0acb317ea6450ec234fb853faf784cd7883b1889b3edc4b9008f3a61f72c2c0fa7e62dba74d4c03c33c785e2f779cf3c7806f49fcf8be4ec00248f550a0a56c206f06773ac30f7bdcfc210ff81a37b2d48fee0a067f46c8f001a57ecafb11dbcfad51c7467c2de0bbb1908e93524d5c17edb6bea263332d500a5697cd4324211c8d2772ceceb25ab525fcfb21e67fbc4f41d0f5fab78383a0094d3e563505f7ea95641d19106d778e832125e45c40303618cf108071b10af0018da681f6483f14c9ce5057c52830e3971f82110eed5580192aa255a44c216000876554d1e9a350477483b9b45b5a2295b42b1b2f41021a59baf9062485dc100adef2dbc28e9d7d7278f2d2e022463bcb4924b5d6c72dc95a85296b7a864fd00ed5d0dd363ee77ad6d5600da16aa6f7fa1cef5251832751668e6e3775c599a00763b1b39f40e130b117525698fead65fb7cca6e469a0409552ca8dfb58b33e008cf24c2044f27624eab321c89790870381780b75909c2658565474b4ff738300ee8f98e85e9b8e8830396b5fc2ce6dfce345ee38a15d4113a8328bd6948fb9006a3fadbd42ac6d98319f997fd0e049ed10ff2e9c04aa6d66b026ef57d8e2c60097faa23b2f322d379f4db67e0920d8c74df341441619c35d69cff15bfb11ee0084cb13b432bfef347ac50537361b606d2bc433c04b30d7b7a41c1df4b5ef1d00e87ca49aab2419e1a07c5b58d1964d8f2505e5d518d2842ecca6b3b8eadcb600c70897680a71d042cb36957c7b52bdcc52b232b34dc7cafc4ea413c8d6f8850017e85cd38c325b4ec0619a4287fbf7ad17ca60c082fcb787262b93c85d5618007fdca3595897e0c6f8eadb64d734451bfc4e929fb1d6ee668d1f3903974ee600d0fb23589cf4b47e54f880c5b4d87389d91c2f27231803a181b61151990b5b001e2912c4b15ed2bd9a4cb7b5651ec69d6fb6d8e59542d59fd47fa4b7fbe03b00e28a27e0fd4f1d5efbd388ad642638d116c0d69446eb68a7d9a1412bc63d2f00e9a08c8411f908e4d4769a25ec0d2434ece9370831872407488011c46148d40078b3453ab9730a7688d593a9a09f8189829290c797d300ac8a79f648f56d0f00e5d1b80a83fd398f69ebe4860afde2843555e87fbccfe001c0338be13adfb500b77e690c7b7665b27d868a5a10b503bac7e2da61efac3e00d1ebebda5444f10081cfe631825b0ce62dc67e5e2b8979aebd1fa40e160edb6b828097585d81840008f6020fc43b250e88eb7d0e309a371235fbf0caf6e3234626742c6e8fed03003a5817f28d6ecaa77faddfbcd75f10387a75280b4cc9b2c0099b453e3f5ce50033433dcfc76c4d79af57d4d53c30c09abc209eb1830ebf9f73f3634ff084cd0052e05363a527a7b0f7fe669cf145af43575a8e2f58fcc29967af5aca491df2000a3a391ac4a2ed627e670da3988d9a77a6e5247b4f36a17208e2865c5c0df100c197fecd72b57a5e037f97a8a3fec8596a1beec5f4bbace97d2b0940ca4660006b9366914347a9028510b47fbfb221786a08f059a405b913507e09f0b8bcdb00b5f63f7d4363a81009094517e18466cfb9132638f8587987e60587bfa2f7160095062038709b07b610606b44ca008fea8ffec03c75b47f0f57cbaeb67a5b360074ecb4278e9573fc07f0baae5e80f622c66476df6a6c218194f7ff8880faed008b874b284b8ee5e04bf2dda6ea8565deeac369b1a5ae604b199ff472459867000ba317a60b26a0d3f99bf5c921b836132f4a6d9a5af53880643736186d772000947f7d8be30e26bca8ea5d9056c4b6c758993871e0b9dcf2291e1e310a0355006c1586b8023fb8ed1d090adb4e64cf3e31b3ed45098bb32ccd4c2e3898749400d9faa742a8b17ea5ecafd95202a71214260a96646d97eb4e607064e488d0e9006685a7131d57378acebbc679d819be9176c36a6179b4cc879c4e6b6a23ebb70083c5634ca3994c9eaed6ab60e21cc011bcb36ed357935301c3636dc5ef64ec00d7717b5552fb739c88040946bed0d62e60a8db441ea24dcfd37764baa4f60a009ae062732c9e4b2627a3b465843da0e74711b340bdff155ef54dfa700a2673001723cab25fc977df35bf024e208aded5879ae80e45d0f804cacece98d53a4600b883aac5b57f2ea510a9e8b2ad46ac583389011cdb7e521cde29d9ac034f6e006a7b00695014f9da087dfbda103641c9511c30894086c6e8948081640ac49900c3a9f98c37b0bde26610fe4aa443cd4659cb3c28069985443138e0611d41c600a54544fe9ec5f06b6c69be975879b1d2fefcc9043d47f88624329ff201da95000bc2ed18fb8e84dce01dc4bbfaebf2de5d31802ac63b1b1905acf7ca1ec02000cfadc3bb34115b8b75260a2e90cb63299a5d89d7ebcdf902469e507696c8aa00429d7cd9d587de4a88db293c018fb7b39754e66f1d89058c6287c8fd34bc1a008bf88aa31a66d57d94f0fa629cf033e7036ba22171431c231a563efe96e24700cc10ba2a6238bf33282c39eda57f8992ea854466a83501d531c2c03344984e00bc4fe6b4e54306302d56cf8f808c1a3df64be4ee1ffa10dac02fde8e1ffade00242a515d721fab16a98edaba1f89e403d98c9b1a872c2d0be2e4822c56083e003d413fd6d025c394621202aab1e3c466939bc404e14a68c6097d1e3196ff2b00cd364c5c369c6f904805565134dc0cf5c52f49e252316c518d5aef96727c4700baf6c2cbcc179b5110ebbe25f453393f83e5f996690d8bda59abfdbea7aedb0051c0c2876562bedb86b278dcd038f8b8ed7a67def942a60b5b6cee8b28437e003cdf5e3334d9351ca3ff1d12f5b9932296bd6fed7cdbc205df4c3774bd8b15004427b61e81272d85285208cc9035ecb0ce5ed2b7eae9f3dd73cf89adb3b30f006ae5a50ba6c9b3fb9a19ece9d960a3eec7ca669c8668cffb26ecec1512b9560074c2395668bbda6c39b9b96bb817ee5cc4ef4bb5c4040f6404d901382d56c700d235eb7f4043bd7af250acd2c6ec555a65b561a16611ccf87dd2f642a093a300200ce77c50ed97483ada68432f801122f21d57d493125a4a62964741cf780200e543c5a2f7cafc347e8d14ec5ac209fa639a7f28cbdb5bddfe7b28a5dbae3000a808c097d565f74885b5ac8b5a94ae1afa20c4ec9312588dfadfa5ff37b67d00d0244ae60238511b494d276482f06b45412a403a8f4398171bf6679ad1eaac002e0ace6039236989b28a15a536e1d184521b28d99c57f29e0992e971fcbe46004b31a0c36a9a555f7bdb156caa506dcbc3666f8450fabee3864ba357803d25007da796d854b62240d74a071baf62ee9000cc3f13196aac2c1d02b6b52f9192007d38694ff2270ddaef2817f70debea3c7b695067a0a0a25dee3592982fddbb007eeede78880e2e0acbf1183cb309e8253106bee41f26970c183b97a9ef33580089df5bf1afa04e89cefc66d3b15fbaa37f4cdf156e25523eb5eb29553ba44c007116f5e3e105909d206879e653df00c20a7e77a6b3a46c96f16c5e89f9def90013323f770056545c98b63f687d8f2c3feb75d3719238d1f3d951648b51c538005c21d34811fba3be3d3e8647d5f8aaee3796cdb7d9e2c93446d6bc75f428290033d6d50c37665d3c70d8ffa5f3b671c3dd9b8639a85701be002f0f15fa49ef00456358e759e8b021de5fbfd58e87f0a12ab40f41f440044a70645bc97210930078f7e2ac678c8d78d9a57d24d103ab1da0fdb1553a3bedf4f2ad224bce4b6800fc39ed24914094828fef9efadd5c90d63c058269b6e7324536746c1d09e45c0095128a15b912394f32e9f34321fa42b1413bb6fb6a161acec8e490effb3174005b1b18de3eda7997768a907b8c9d3c2186c76138fdea62edcbab77706cce940051e10f861f5b951a403fb671d7d3233e966326cf8005d91efe2ee4ce6f280a004e0c55a713319930a72c5a5d8b081c8c19e01197b2a9742cf8f2482a9f543d00c37e0529d8bbf7b87b9cd21d6cca1e244dc22cb244b58066f3177708b42e5b0019ab0df8dee466bc02d75489c0e54345500cfe7f4b564a2464855af7f4723000a475dbb009223fcc6fee359bc43535a431b00c4531951c88ed63c75bb2f71f008e4adb71a7842510128b81b8590868f96909034470982e90a0e686ab9a4e050048e1d1bb76b174cd641cc975a389966dedd8417dd90692b8d2abb1ca285a5c009e04f5f9aebd14e0dc90963102d06e2a172f23f0f311ad08f8063a28059c5300d20399fa5ed095f0af48d5ecf285778f7b28eac1bea00a1980b655ce455e8400b2a2a4d12f088f21f6dfef4f3901c57fadcb5a8369f83316ae1772a7ffae6e0055af09f53731e063dce537d253ab7d81379bdf13348f865f6e3dab6e27c3b80033a1c8d91b93d70a8e436cccb19be36c9506d45fedefbfd275d198e66e46b4004f795d23b39359dacc883801f2a92dc9f078a10ea864aaee9e9b8b9a1bf745003f5720001e9f7eeb98293992ada36b96f0aafb199a78a04adacf3139e7134e004f78733fed338f00188af0340999dc0ad8db85f2cb92e7c3d3cd79ad15031d00ad45f37919b548afaa35bf718a6b388c8ff7734f032597a7b5c6a5c5dbd01400d39d9c8f1083308a8098e966532e3a76837d8cd0efc29c7060240115b24013002a99b61e1daba187d5416878bb99189ebd3d7ff8509100ecafa98d8c1c6b210092a6d1267c3bef562ae8aa94526903272ac091fc294930d57ff488ecee2604003a4831bb7999d4a3cc66029c31771b57b0bb0cc0c4871605aa748d78a809af007adfd86029f469aca4d00ff225eb70982e6ecf16bcc9277d4193fc6808946100923bfd64a2e02093e08c70416146d7c3a03384c0f9c3a92d3e4fd87e0a3c6b00b94af91f8d5fcbc2c1dff385a540dc5aedad7e67022bf3b354c03d55475b3b00e1c6e0c4eebeb6a43240ff8c1cc238e5d3557cd95d717098312a620e6337c80041ffb03d87151df1747b0a4c5eb6ce9142c711dcfc6cdb4f674d27920f00ff002a4d58442cba6edb2f064cdd2280563ebc76e372e27a16a592d36a4910d1b10014a7466a37adbfee039aea771a1c89ff00502ef4adc3c73aeda2b42f739d5100fd98b79447b6452be333a2a4679f0ef1eeddc871f4d907d7ef155016b2fd3d00bd43a865c2deffa70d823af21f0b4acf0fd05598fe198ccdd3ebe5772171f20026b5740ba263abb0d8cc4f5ee4784e5c770b79f940a2968885251314f1b092001ebefd53e0f72467eb1c646f0d4faf88b0cca94b16005c1f13d7a00c9b203c00a60407d8d75df883f130f54b8e5cf23f6eacc46f114aada74b565019e27a3900513ed3f70f62a0240bcb381daf7809f1bf093bd839576b0d25cc64c38f295800737ac9add0ed9ed131e2835798feede8d98072c9fc1569c170fdf4b276bae200ca17bc82588c5d23fae372047809fd9bb9dbeab44e3b99252a31e22fc192c1005e7b86358d357b266f94b7424a086d363bcd6919eb444ce4b162f2f314bb1a007e1cfc4f4156b1f1a4a94855c07f8a20ccef8136af4691fe7d2586c4dba95c00832ebc1e13ac191f0c22864ea7f66a53d45046340c1c6d98be52e740bbdb0000cfbe216feaf3ddb518f283375a30536a802bae99ea8e4708e0f681439e546d00c628d11dcfcc337a2aebf1890e1164d93c19fb2fda809a1978583a54dcc2d500d6f89f6bf92246eeabf1fc403c9f0e2410276a8857450ba29cda25f9fc5480006d2e8e9b0749e760b6bd6b35666fbb5f05691a34ac462c6101a183778e73a5006dbe92db03ec828c3a3068add82a4ec96050ab4a1ee7cbd6bd54306bfa0df8005dbd49b3fd57bf0321e7e71c36572fd7424bf3ba7cca49c997a2a2c0906798004f1985358aa67c6e130e92013dd463890df915b6103bdc18d417dc706ceb56002e88fdbb5533b1bcaeaacbcaba074ff2ff60f228fd33e5a6e0325e8cd21f8500a4872ffa8ec0b63d8d352823dafa6d9d9ff606c4b1145a37de295be52fd1850004473a72ba1665ac0b69ee5f0b5adaf3f8a1b96464085a58d07fe6e00459ce00c4020ccb779f4b02b1789cb398ebc4bc3cbf12c7d11ebda18edfe2d13612990003ed65cdcbf8e1a07e63829380e7829a155eac57acf074f17b274f956d153d00776862f74150302712b5abd6b3079e522e2888368b2173ed7cddf69626777d001fafe4201414a992b463aa4cb1e13a179a7490f4d4025eb10b3cd5c4e7a5a8009fb8813001b28b44358c8641e9e782df6792049b3123f4bf16ef44e7510e0c007b5b635fdd91d2206db4bc503a10b35d8bdfae180f3bf0e7f097239315a4df00a980bdb622433c659e96d3929ff9e5b6cce0fae2cf6e39cf8afa81b139bc1000c1cf03297273b560b6a4a78ef97c9b21af936e85529848743300712d337be200cf7a7143684a87ea108125b08516aef4a99be3a72288d0f7e8453a16ddcb210089726b3f1f6cbae49e58b9757bf95030f45be54656c8e7bfc8050c61ab067400d48d45493a98dea9e481d9ea1d7c3ad3a49ea8649a27aefab337a08eb427a100526448de9d2965b8554212af60c661bb7a1d80b496c82dae57c8b9e06727b500076f486d44a159fe18502c42f25eac29332680f74319343269c8648c35048b0033a95bd3de3d2033ec3055e5ea72817b5c0d448981ae942b9506fb74b009b700b88f39263d019b74ba795fd67452823357efafc16449a87d422aae55e65ba900dd8117e80254816e7d57f1b9e9d09a3350f4f1fe1c0ccea21efc7ceff9cc390099fa6a5afee8a3e04dfda3ad0e20907c4f3619cff08885c8167447f01edae900094d35e2567849762b73ac21298208a109202f150f8af041df0e6d88718e9900e100a4a0bf733e7dbf3ed3123de688bc28aa4c06a497e32a9e2b2bcf28756100a46186177f32ea45d66d0521a10791df0cd7ef28176e5d494e0ab81b2424f8006f7c88223ff4e398abc67464ae50636fef6cdb9a3b85caad17f6de4564a75b001a1a1b73336ce430c1124a103e8d7b91425d66daacdd3437679ace2e6758b8007cdcffd23b62239bdd8d535dc6626b3d1fb48cdde3d0bf83a9e3a0ab717a760097c88af884b1b71c33a83c3b532c490edb65308886baa3d7447c17a61b6e1e00a397728805b3eeb706694ba37638258ac459682ff42af16a28a9c9a0a62e55005a5df647010715df1effd2a6348543add91da4c38e429310f64cb503366fac00dc41560204acfb2555fd6aa3216b26f8a0aef94c60b431bbcc3fe1c8da3102005b2a2662fc21ed26f5eb388d7ea5e77f166912d98480e788c2e0ef5548855e00d64875d5c202b2b79675b6ba91238b7410da817a0be1fa6fb03c6efb825e81007b4ea84bd6ae3730abca9008427eded75e9541404931c92eeaa3b2a9a231d7008c01a1a93a2ebeae89b0aec53a928fed8344ea5cc96b81c496f76fff5345df001beb4e8e22addc51da0219dbf6355b0b284bf385fa29ea690ccc263f8824250079b6ab17d180ae1048f2031d0ac7678de4b2a908764fdaa76cc6d65ce600f500cfcf5067a2e1fe63992e65cfe68a66c9ffe26c79ffec8d62ada44ccabc70a700c0e136b30c54d840926035c6b8246579b06d7e19ad04e9a986a31847b797fb001cfab48e85ba7f886f7344af2d2d13e275d2fddcd0be80c27405f27f327e050066ef12f07f683d3c411ebbb0d2dafa11a7b15321c022390495e0754641e1ba00ae363016812defa31cb345968e557e450d1897033638ebf2fedd004a19f5030029418b19d548133ab1c29450c9683f4cc1cb3c1f83ed432bf182e0debbf198002cd6a485654eda1ca70e8053badb1dcce51757cd17e47027167347443c0271008aff36c4dfcd573962928b3f4019bb1e1863c9eec9896e425be0624246ddc0003d58e0626f2035ad0f4b5e74838e04dddd78cb79a543799db293e73478d006007d34339511124c4ed954401516e2a9497c50e76b780b872ab7808a51bf7df80045561a575d5674a8156f65e2fbc7dae0b86c9255055a7019d58532205a8678006fd20b6ffbb4723d05c29c7b9b690b2395fc84fdbc8908761ae7b708dcaa3500155241e0b6abb463099c458e8275e4cf7b2effcfd4e449b98c7e07404428fb00ece7c14b09a4905e6cfb39151d5292af0f57b5256b7b5a711adbb8fe0f58cc002183510197465b40c6428be9b4b50a6324c3a42c9a8c2fea349f6085b4599700491cd0f0bd3ca51d924af04f5742542b875d21e47ad9dcb79e232a5448f9bb007cab7fe3ebe3862a906705e837eb2accbd23e10c1403adb0316de8f3a9d9360046651b89301f1b27d9b691111739e206c615b07a94042644cb59c486d254a4000342c987977e421d11685ed96c835c43e40060ed8bb2428478d95f6601b246008f76985ecf91a71fc0383588d2f240c8d7847e3582f77f8b9f2a3e95a1587500431b01c17dc6b38ec8f787319b5505c7767bdfa6d4aa87ca2778d40cc363e3000053ce10ddd08782847159c8cee4850c5f30cf5e81387d0bb87bbffa04a1250097efce8e8a43bcfc73f45ee140cf7dd93cd541d664c71e7b6f1ba62335888700b9c66f0f0b4ce65ae46d91a95f378626dfda807343b24215cd9055de7dec1600252ac6f21cd9314da49ffb8b71b647f2a06a3282955588feacc900ffd07f9b008906fed46e5135e91b95b69b677c0e8dbdeee6114b8602d78834e01b8d4f0c00250e1573c51cc638e295e054caba0a7c40663a4f6a6d382e6d99e31b0ae2ef003a97ef88982475638829bc92e13ce593cefc65f140ff923ee5479438ef510e003eb210d656b7fc8a4796da3804842cdddbfb93876261d19ec2ac587529492c00ac06fc6e3f9181832d7b9dac1107a1aca382ae3e24794c945c0167dec8545100ab48e5812f9482450b56e9112d3eed3fdecf245d55d77713ec38a86fde27d200224a52f2bc21901d20ab6f584e5bf207ba8472a3fa63859b2bacf9fa83b37800073d25a7f1399caf7328fd47d3220e25e86e6d0db9e1b2566e5bc970c2a07a004cd334ac31bc8dccc2321f4cc5c13254e2680b39bc5719a4a0f6050ee8e909002c0c49965d76f277e80dbd4bb19d8fe97965091fb3a45dc10090e6226921f60029da7634437c301d98d8ef74932ebff3822550b08565c17eec569dfea4d6d600999b755c365c8c75001ca25d1804603522ef6ba14065f0faf5ff136618927800d2b4669092de1dcdb36faaf5b47c40d0d9bdeeca7822201ee8c50266a9d2ac005814f3e62caeaa071de03b1feb7d981d9a923331c418ab0ec4817ff851b14500a7103a43d9537ed7d394ecd4e6558da594743bd41b142b0242d0bc2ac6e5210020e0df1e01d9328ca3e57de8491876bbd0ff5786a9084da9c01a0afd80dff200f52add770e49e7a3c43e45a1d8c715db678b41d7dd1ada8ec75d188a77291f008bc0c1e1724162d7004228a37ec487d92c8a0fcaded974c345c402cc21218e0074df3c3905d6c59ec4cdad67a2a3ee62284758656f34cd8a4be4b67fac02f40000c23ba544f7deace98b39cc5e1cdea99111f5274f1a69fb41a3debf356966008eaa6b50d38ff0e952ce8c09dad13b4bdb8dd1be28ce3341379e49d0e7abcc00e8601537e1ead423bed11a916bf693d15694b235e205bbea0286f59dc76cf0003835318710270eca5d3c2825db825c15db617e435ab2fc9e7567881e27872300712cc7ab494445869933db0effbfb2213eb1e6162cccd9099e6d77f826829000d797efc13c93bd5f73a178dcdb3e79fd0525dfd5309eec916c224830b76be6006adf898f5d5cdbd36e033bf79feb06b6701175c57f44bbdcfda17833f317880011262931d232ab5d78644254c251fc4ba94ff95aea0c691be9af5b398951dc00b202b400e41e149762fb0c8f1888be76fc0275f2928a1a685a3babcd3ee1a100d9b6231316010b1789a5add2887e087f4f5b91e90f2c3bfeb4aadb5bf9299900363b69d5c697a2878794bbe27ffe897a39489c6d47d8c415a6985a4a0cb72400314f3a228330dd5512d38d9e2e690982b3c02926d7bae19b76cd2b5fa175e4002eabb357cc5cad6d53583ae9305425280eaaf9a65eb0a35cc0a7418ec70f5200fd7420a5658dc6e8ec5074f328dd0fafd3b452d56f61cb42185e244763f9d000a44efd83f518e0e6a5e9fa388454df6eff7d43dcd50657ccd0745355571cba00d8a5217ecbf6ede46e5a042b32f95d5861eab7155033692c033c5bfd2f0b04004377923fcbe17a135899f6b5be3587b575c2de59cbf90330b0735ee3c3d4c9005a61ec22021ab1ddbdc7bc7a79eab0ee7dabc19c3a25b1fbab435e7a7dd76900a739dc68df828ce873610ee09709d35239aa04c34166c4f7e7e03a0985cb0c0053ba282e1c1a8d3037d8e1d5fae2367f46adda8579ea8337fcd022f46585520045ac52dd6fb7be5c6c11f4fb622421f5a92c57c38167ae2bbfa60fe67ac505006e5e8c0e58de61044f0ae693c83c88e78ca86fcc352c42997b3a276880b7af00697670393f44908b355eb296360feb2dbdb3bd3209737c3d685b4ebbd2f49400e25497acc1b0900f4a5a543fb13e6fe55b42adb4668304ed48767d4d37178b0075e4ecc13acae98ddbc144b0c98ea59829b82f12072f618fbe7a32201bf17f00218d6cc1d105aceef7b7efc6db506b7d3b0f62b6accc28750b8b652a2843240075b8fa2e153bdd49fabd682003384d187d96d83256d0d0743e98eda35568fd00f5d717d4c54ee8459ac2fb205c1f9ab4038136a177f72d1658e3937c2ffc3d0045f4393397c9d41f8c1aa5ea1f62dc77ef0517f74abd7ef6b869a096d5b2660030eae2171ad4c6e016a22e79052e9c05367e1ce660c962ce95a935b5f0ab6400d728cd8a08a7f5dae100c292df2d31956e7d7523c101dcc2d34a8195c1668f00b4694b2a192f52263d40b999bb103af8738da37bf8d22c214d5557a5ed607500f7aa37399f370e16616e0df6d2d3bd7e0bdd0537a2e95bddbb8f898e0b73850099544f5a6395dbdfd98aa25e63e130084eb8ef73b0cb3aff7eb93c1dfcfcb1001e63cee2863016678244ef5b0ea1ce50314e75a683a998431706eb14cab6390059ca0246143c764a914f8fe99bc7bbddb437d5c47f830d791a42079869482a006ff51ee11ea96f3604e96842b4c122651618c0307ceedaf593bf48e37c074000072adbc5386574dc8ad2fdd4b461c0d60f2cfe797b86db01c2bd369522a4af00beb6d59313535d94d8bf8afb0bb599ad796e47be005db8eed949ba3e5191bc007a3ba0ae02e8d46af6f390eb69206be6662f24bf074ac57714a38960ca913e001b3f8731c3f942ecca7b71ed652f30861296a44eccf8e5b0086fc1563ade810055465c60a33cadd9922219b60246e5c3e4d6e0400069041e6280511431df34009b583020050e2479054b48233108f2f37f1b34bdcd86e501eb2cb5fdfb27ab0019e9f214886fde1c4a71dbb44edf034018fbeeb7b1b86f77d040f17f6cbd8a00d21a8e394dcc64ba2e9f89ffa7d360257c5ff037e3dcfd9f423079864c057b00d17d85ff72fec619a2cb6380f3f95ffba9226739f74ab851b14733ab15552900d046111b7d4781e77d648f256fd2e76fd77b0b9f0ec53afc767d107e8e687500e2e606233f3b96034722c8d82d04f64e0d0643f4a2550087552b172d595c4000af33cad11141b54317e804f7e576e8c565ca5786562b6f573fb4cccce6dd2d001ca5455df3f397c5176f651e4cb9a4d632970c894cd33f88c592b506907e3e009ec52177d72d5325a2e5541f10345dd740222a47e47931ba59246261d16e6600a55062b28ec81763e3fa283d49711daa917469d466c798de81aa382328214500c7299f092cbfbc1d23a0ac87a6e60ca47d5bfed9b4887c7dde56f1cd75caef0035c61cc9a2b1155427f4a574d7d5f380f39b5d6947791c3de69ece9f72a124001fc3dc7c6c3930a99433e85972e994e666b2aaea5c786738418bef951137c6003c47cd4181254a23761936565b173b05576f8d4fe37f5c15b4fc249ecf1f0f00c1f4c6350499ac6ae61b1e63a76bd97f82535b8178d318b5408b2c693954c900ee40f39fb499856fa111747818b115b988d4b348e438c47bd7d2c4117005a100321b7f35c57bd0d3c2d438170643c4afab261a599da7e2a0eb144342a3cd61000c74f1a089f250ed290948a9cd1e918239956859422fdbb7c074f7f9a95bae0063f11f5204f01dd42d59b80f21078d00f9ab7894f37ecdcf722531274fd35c00c2fd4610bb8bb70ae0a618e3f4fcf6eee7c7643866f67fcb59e6cef4a9018800f83956ea39732e1a76025917715b6eb40a91ed9197991770d554fb8bb4029800a037c37de3cdb92038615caa7019e2a8dac9de78f1c65cf146035c708fd7e000d4501bffb0c5e8cdee62cc69c9d5ff0dc88c2cbac1deb77cc0467d1837628500af5b5c46cc81168017ed3bfdaa037c6be128fc7bb3b693a0fbdb8779685c18005a3badfc3d7c25d80ac0ac5779d49ca43d022cfbe25e16b72d7ce68bb678fb00ecfa9577ede332405b0ca602fa0e2a0070f1721f7b933dc4b4746569acb7f1002bc5e21559ca468ded251f5a8bea447515d27c5c1c0202c8b30a28fa3cba73006921682f6d12a7bfb5b5be4975f75db0935d4e3a3f62f7214d4109e2cf204a003aa92afae1c1e75eaf6b9301c8bae5b94a41f15eff8e9def0060db9a689a7500a56a0b37bf338b44e07238817496af5eb1549fad340bd1008a786735a1e9660076d7a761097a8b724de12f8130b0fa0e1fd2f13cb85f40d82a3b66b5fd52f700878b5d6c4fe286be69565f187523e21313177d748ccbc7fdb34db5afdd65e6005cb2ad4e98d2fee9f1ffe390451e723eeb1177ff4046f0c8fa90c15b03d6d80044ba78438f43106d1c425004c0de78cb558043fe90eb164e44e58099aba761005eba6551f379e7c01f8679090379543a3527dc4328e4a8491cf4a4ef6bc890009091b189c85f32b0eae60480ef96539506d98755ffdd7af76b48187626bc460027f08561f97ab9f6b28d3253feb28820f51f59465383bab4b1591ca2d2816f007f65357e821e11b9aaed6001d041b702f3737adf9f7a1e898606dc1e364bf40034daae35e85c110e85f253c434483e7bae92127117ed13c1f81f6de7837167001961bb1b836b27581310676dacdf60bcb37e3b8219130baad7373e6f047d2c007909a14771dc6b3c041040b4704527ab53543b292262ffc9bf62c2c478433100fd7df49635420907cb18b60b58118cf32e0651deb44308f6480e1f9f299036006d776361e1e65ffbf8b60a4e3b3a37d93103d1ce722c4847692c38ef257f1900a026012b96a679b44de7068cf64f76aa4b489680ad52fbcd304c93e622a26c002b6ba17f07f96cd0321d645c62bc6ce24380736917eebdb1e9b57f343cae0600c2236014fef6fccb9cbfbdc37a4044496889a10e93b44ecbf09e8b1995ec1d00108b03f884f71b5e4741e1d25f1f8470bb1cb01dc49e6441248ebbc6d61f420085b61bf7d1f0ed1194b80c0a08548283753a7d4e50f936fde905d1a6774f4d00a58b85fdbd9a56e476f82e045f1f1fcc666f4356f92bd166dc195426c80fe000ff0e424e497f1437092955bf090e451dadca9f1211a46c228f2a2b8711bbb000d2c57995db595476217f46ae6474a66b5ab9db47a38ec7dd2039b397f88f6a008cca5c9861f0634bd0488f322eb7c9ea1c3e9eb94276e4292c1063a9794360001964af06ad8948a6b1dcb6bbd41f98ae1f47a2a17dedc46b16953e3ec9574000e386bb56a5f5bcb11df9502934065e47e09a6c6a83dc3b1c11d4a964f9ea0200b1c3f534ae1565938105e6872fc58a2c9e07ce6df03935885482e056b4930b0002982075cae141ee10f65f3d6713394eb407c382c9b092f5ad87c75fc39b1b00d9de034089b433377f56fcd6b5e9f5007dd19ffcf5019deac236c5a1ded6c800f655120a186566ac2f5db139ab2db20298ecc5a5cfbfb40b93d5aa39785bfe00bab3729bf98e85614c7b2f77f8a66cce47f9b7303af2df03c2f299b0141488005bf080258b3e3a9538aac0c275a1afa69ffc5f9ac2f252612b97dc34ae874c003548868e613cc73d2957ac3bea03ede96b9ba5abd5aad37ce53e716952eb1200784c7fdf7c9deb719f5612ceb6cbfd929e46e8cc33cbadc5cdf1083cae8b6a0062581a1d43906b34adf16db62a6fb3a7a59ab2ccbba10b3d237bf575ef27c500203f6fb4112bae9b0ea7cd83229f67c25f5fe093e93ae75beda848f681fc1100cfdfe2bf56c960fa05efdeddba7dd1a5a2e31b32f11f2dd880b6d5b9cb8c5d00d2d762da35f63e7e97f9dfa4dd9d74e40c14cedf0b250292d9c0c0fc30d0f90009615402a7444e1086d5a81ef3b7e0caf0e9a4e9c651fc64301a68c18ecf04005e19f221c473717c9f884d5564d36e53ff7e6509b37764efd3da247023b9a70095f7c1e2d45926c6feb8a75783723d61fffdc93cb51300e09e77d627be443f00cbc9532a3a1d033a4a487468b8d4c02a29bf7893df9d44be30b651bd30bcd10028483d5e978d79dc2d8dc1a26fba7e3b53a6c89b69e21e1c109dbd901ccf0b00b0797848a6f6226aa78462bb4a30ee56fc4f22e762fe3b3e97d3ff4a6692950082b4e71bfbe325b27bb2280359e52d51f290175836019d2bda31e11e121156001e6f742d5f256c64a733726a75cc3895b2dd0a22a83f9693e673bb6c2d07b700d18f4a0bdbd88b4bbe8e69a5e1df942eb0b294a42293163a526c9b4fcc2db2002899aa92e93a68ffc887ca5c4bed31982ea250be411a2a139c6358b4844f6c004b5a31b796166278a0b5bd2fa53c8de6e09c0650a9cb81041a4f677e097b1000f629127d89cf819fbef6694e00dd77c11e7cdb3267a5d7d819ae67fc9101cc00ccdcec42a2eb74a4090574e81fd4770932e2f96a5fe8d12e843ce6c6fd401700c54980d2fb96a8dfc4ef89e96659c935e0f07b6eef5d9d08b84c2ea8f09ca7004edc660d34eab277761aef6ddac122d343623bd1b369afcb87f836b5ae4d8d003621fdced2e762f0553b899464da0ea3c910beb117e432eff833a37c0f9aec007cd655fe3ca1091fb84de660ccb0809d0ca32584916bda9e124b96f8eaffbc007b4ebfcdd953df20cc2804e214eb34589b63b392465af4252b6e56ecbed5c70076794e404aa90e99194d10b1e8d6048c4194dd75785d9523667eaa250e9c6400dd1ff07784828d86b05b78ad54ea243d8dad776275f479792f2e0715aa90c0006f69a1bc3c624009c6040d58590f72ea98eb3a22010c67311cd7a23cdcf35100688b29c78a37d69fb18b63dc5e0f1f5108ce933018e5691bec07283265d995000a67dc0c141df3eed21b68b327b7b77dc680cf0fd56b1661dc2430419d7c6b007ead540f6c49103b5d2b6d11a5b78fba935c6dd1c0e94ab96af78e0ec6bd3b002e9fab2fa58c0641a3b053c8d9064fede629600b8188024d30516016dc7181008baf37360b838b50be58ccf48d3a410299040c51b73c1b5a1a59144e2aed24003bf9c1c0df902a02adcdf1c679ffe24ded678fe410eea11ede654ee148e7a7005ee13e617bcde125766e8ee7ac329c744d465e4608e6b2cf8ac5f8aa23d68e000bd65c11387b588052f8bb8969a08cafc7559d378243ce6e880eb63ab4576f00b6ec13496da6d7d9f353cd5ddb844c8c1bc7a063c361ae2518ca6b47f0aaca00b030ac3bead05c9ab836386b7ac11c02a992fc6dd879aba59b7cee049c0c1700c071734eecb8b0f4d83193adcabd4c6e41831b66086edba9e1bb5dbbdea64700a2238d0f02f2ea402ebc72de19fabbc2f9ad8597b9ee2ee4ad52b1a7477aac000e883e7af72b4956d9d9bf468c433c35be18e87e59e79b0ea3cb81667aabe60079b0efc8b2261c458715f2c3ba0c62c13078b69324aa4f47bc228ddd520902001599caafa566ef5ef9bb7662aea2bc08688827cf5c5f7d90da1f13c4c372a9008c61c5423414e793ec2b175a14525e10197adf27e0e7b0f399afb3afd4801d00b0d3c5bfdbfaa8f4c0ced64110f923a0903007dbbb48a5797a56eaf18625c6009e000143be3ca3883f79f831f298289c55df891ee8b81001c5cde7b09661be00d9022a54c30f1b414c2a2b7790530b732c2ae671a598182a0b9cd4c5023a6e00c215696f85171691fd334c485365cb1ed74d02e56f7ee964f5559b55998c4b00d157890375c86ca76c24d04ca19eb1d26d201547738f8c5cb05bf229a3526d0072fcdcc227eeb271086c2d22bf225238a05e964f584f392814cf8f9f3257f900ee6676212338d74c3b7524c4827c9adfe2acbf5806dacf0a9953d98d69e00a007cadaaf55d535fd6a4b5254ef2a3b9ccb20eb9a64ec5631777a4f77882f495004b5d81d1f846efd57ebd447aac56a2714e24a7cd25b012cb82c57777ad2a9d004ebc8bdee1e5a30bfd9b68ae04813a11b260f556e1d9c857935e4d1f01349d00a89f769d4c5f135b2d924cdb40233c3788ebcc4a085fe572a04fb43b36652800fca5072f082821e52d8d60c2674c22f73f1c839fbeedadf9b76744825eb51d0070562729f17996d293c6a4498d6bf88819d462817fb1641a6692bbedbe458000186eebd1b1b5313216a1ec27b1d3168097cefdbaa4209d624c764af4f7fa8f0094324972625e23945dedeedcf9e79775cc31fbd2756e7d67fe42cc3248fcfb00f6580e63b5b61639463a5c3b433bf716b2b3b238d587df7ed4369fa617cdd800141e51219fba5521fce373411989d766164676a4d0c813768a3fdf65d46ae00057eb4eff5e24003e11af7125e65cfd1506659b15ebd50a78df374a2ca79cbe0001f24afba31ec1f99da0bc1ab5ee6d243f0e4ed5b2b6da4c52323a2a2efbc900c9c7d40d639ce4a05114433ffeb0c2a110bbe3a94424002ce52fd2114f55cd0093ccca03a219d76555a043fda9eaffd833ece893482f4ca31f301c1f3301b500d9540a2fd10c2c567f13308e3819508091fe3bcd19715933c6ccd034c507d000d359b10d5baa40f636714c6695050ca43fd4e15dd431461e45a8f527c6f2c100cfab7c252f85faed3ca715e32b5c6744ef3e5983c6da75f17326a9fd2f300a00cb248c2660d8390bdf1df44d1066367b9f4da873dbc7f307c182bb7e638d0600e3cbf0431fa66974a4cd477ba9ac2b9a7d9a2525f8fc444bbc50d553fefe21001d38c221d371fbfa2250eaa19bb3651604f2186c3ded846b31e592920436a200823db53dbabbed72316f8319e977ac31a652ce0389533017639121010737060095167ec20384b60253c818a3d70e16603de09ad73ec26e8f19406fa078be2900efd5978fb63106f68405df409aec4c100ec46f6a03de849dc7d949101269cb0064e642fc7a2b0b883608cba2b951d32fb3c265b8a9dbc2bc36281155945e7400d0c3d2d35ecab366c40766e3897f3e82e0ec28a0e23cc6674c4f468f4b06e600783b216354b8c2f9a40b855c35e8da1f31981d71cbc1d40628e29709ee917600f1db3cddfaedb5d726c3a533e96b5d4db65ecd786d534560842192cedc442e008309e2b22e78fa26731ac83ba833c27593f72a93580f61e7ba07e4ac11ddd300b6a220522c8ad7e4606064fec6a79352b4823b3c43c47519ac9b8507470ce4007749c686a26b456fc24c5e5bf6e7848486d6551c6207a934c1c2f3c37c8c02004d0a9b8139086bf8797cdb2930baab1f2bbdf2fba01da622dfd2d064bb843d00b4202de928562a39650eb1e1607ea45360c0eb495510ef1273515aec4e2899003abd29aed1f73a2f3a12c9508c78bd37d50bebb3de28212226b0a5ae6ec41700b3db98a3c0345729a97c4cf735520521067158c787d08dfda7e7129498b38a00628ad1941058df90646534a81396a72fd884420e818c07c368be61c802facd00e9fb42f7c72b566f8eed9f7e7244ba016d8042aac1989dcdb1904d1ae3cf10006d56e0364887da94c592057a6501ec6c688973c74f28c60c4b11b3025cdc7d00a0fb93463cd3b6680a9a42fafd9ee658d52758f6d0bb7050301d784364e5f50075a4049323e4af1a2152caf56de2ec0c5183ac5136152740d13fdea1984de3000e10d4bc55d4fd79ddef7e3696fbfa8600b50eae77ef6cae78844838d6d34800c771437eff167f1f49991e1c22e8712d582b3638a3f74ac2eb0a6f73f03c660023f8091acfd757061cb4728c50208623f7fface26b321351ad9562819cb91700f2cde43423f15819838b7e26c817e395c619da6b0dd181d9b0fc37ba8b573e0003d7e3056e70437ab8f05b2dd5520d0994829caf4d5a40eb8651310354670d004760ee509260173ab540d5c6e4f7ec5ab2ccc0be28b1d3af23561c7c6b6dea001ebe6c3f9497a1587420e663beab1e6843c15a4740a71d7b69c0dc911776f100ddf7f8c46626e7f9bf80d295277dc4e42434b720eecb68859d47f0612a1fc1008a825ac99603843cc9b7a577d6a4b134a166bb1c4fdaf3dd364e633b5fea1e00207825f33f5ee0bc13718c71c3e16352605bd896aca4f01608ad4662093beb001cf42de734784be74673697298b7e3690d27c69be14834893aa093619fe48400d49264d77fbeb90ba337339bf7ab15e89d116ed999dc66fe13ffdfc30be10a00cfd6706fcfe9035eb680f189f337a94d240ca657ccbc14cfa6eb326922f9cb00b0a3248084c0810c21fc05fd9aa2c2f4736d742df8e0170ce2193d6faaca7100efdbde7b794489ee4952d0da98c909fb6b98e1c54e662a048d192b0ce9ad81000b5714cabb3848a28b3c8e31f006639f466260ffcca8c01b73421de87b7b3f00af08a98f585c2a2f87685e75bbd2dd7cea66a4e0e0d672d1c72574e7bf416300f8105d75c462c492ae9c2bf7b29f11ecb29edf4b2cd218ca57637686d22eb7009f592d273f595586bc565f291c79e7ad96a1193c3ac59238c424c9fd075ff0009af5c22a6ba263431f3758d5a8e999370294aa8e63dc8488ddc1edd71fb68800886a81d3ca4cdd00c0d11aaa838a951074952710fd6bdaede4ed3cdcda4f350012165b3c97e5d09b6edeb6f157a767996c1a20f9c009c90d9064948dbfb74b000237467b6ef17e7e596062b21f2e2a263271e2f785f3c60e95e2d0e14552ac001fa86cac59e26e0ca22574dfb0455ab2aee52323a31fd862f472a5d25e548e00f88840b307dff608dd82480d6b3db4bf7c76e86a4bb6144a3ba7fae2d0d81700dbf3501652c406dd1d08fe1e6532ebdc4284c27c6eeeca5eab96f0354431a400cb92051e700550e832cb47686d45643dae33a5052398b8731885b3d982c19600136d118a9a2b6b99570bb57d6d0d22a7f6b2b2a9136acf5e2ba8984b65b14500776ec3e6dbb44a22131905dabf3aaf1cdaf82dd2138ae664618aea70a2590c0041a8a640e14fab348acc3dcd41a4aec12bd7cc6640b8a606c65f1f1aaf45d900dfbc8a9543370049df9ffacbcfcf1442dc14f95b6075830d8addff1fa7b0f200467007b3bb596b2eb366664455afc113bf0950c16869e4c15bdd709322eaa1008f79880235b9509bc3657dfab190e9c0d8a268fdf9ad819ba64f9437f4c688001f3a2057c5c4cef5027f12ba5a960e76ec904db13648b9d4987a612408e18f00315175cc37f20ee73f649c58c690c072d9b05a1b7a1384102269d6567ced1d005690af47818d47b33eebe4ed9ef46edadbec6e2c6da86a706535393474f1a00080c39dc38f92aeadf0d92afdf97146a3395d178f1325dd464fe0a64dedfb8500f67d9e6c885b308b1b0f4718742be90c59fe692e0c7520d2fc1ccafd50815100c3b0a23394ad5b745ed2f8a29de9857845630616e27e84edce3ddc348d20530056f81f6b69ad25ec0a0d6c38acdd54104802a1a51c2f813404e19a0a77870a00a2c5889a4156d847c95712196fbb80e481cb4ff96a545e983cc83c2c72858500b6f62e41bae8113b1172c956bcb2d2a3b12efa32acadbc81a46ba3a52da46500cf692a6f60bf29045138027238859f5f7da0368ae5bc8f16a6c2c3b28354ed00db9213957c2e922de8c24acd41211edffb0c68ef924096fb66e3689679018d0034e0c316d3c5979f457da6d8263c8be8cfac5ddf65dd70c38949033e94f508009075f2353ae75473901f0eb0d8c895adaf4f2d777971085cc5775c8db35a8c00c8d5e37f4020037a5a44ea6048cbb6dc1770f7595aff590faa76773f5dddaf00be3c974e0f3a9d5df4ffabd517e1986936c5f39ae9127fd3ad20400448c80700f39c5c91ae1a9661c74b9f7d8923458f357409f261dea514518a52061f3e40004d78751041fd48ee166f29b15206f0752a838379dd37b8330cc1995d3d7df100744ab2398cbdeb7632293404d3cc35f597fe4c38ff4f4e3e2ba37311ecf6dd00abb44d7ff185fd445110aeed67371b07e97fdda933b73ee088a393cdbc68e900c4ac934e91eb6eeeb30e3b8c0ff6da14577537cd187ff6d42743aba2a660d700675c58729ecb9039b5fe9993e71a7bfb27c0d362b69ce62731c14c218d4b4e005033978a22258ac890ac46ddf6a3119927d96e44f0cbf492d87136de1426d900205dc8701b6c6b5e522e86bd4fd8dc7e8132a26c33b5e1fca9ac29be7b1486008bb73bbea214c84bfb9a0bbb46bca1c9c9dbe3e41eb000c604eeecbdf2fdfe0022afc5d10042074e40373bab610c067fae41580ec00fa23d0d0a936e2c918e0000b1dd5141bf75ba65326dccdbc1dfa3a72bc86f535a89122685d2b930bb7700c07efb5493e94c4e5a3f8f26b488d632bc3b22422dfe36eba9975a8490f57800a9d937ffe73561ebbba3c3ec2ef8cc436eb6a90858c756db3eca17dc21c5f40055dd5054ef92d8d9d635751c1c41865f58848e9d380628a15eda18f50b0571006334c72e8bddd8a0423b4496939092e6c660824bee27cdd3c801792f72f14d00bbbff53c4ef7dd4e2575d6468a5003649f845be35740921edf6a6562cf0ad10052db3f8717eb497737be28ccc7a3e22800080b6195a08c7c03b159a9629f09005d2efd5616907e45b175286f70bb67db65c8d2ef903d085f5a04d19e6aa3600090fbeeec7adc8b76c52339464c25d199c601836abd5f4650d1ab75ec827ebd0010846e407c35ce1e3810f048ba9d691b4595ac0c3ea66a173bcbb0c6c8d57f009e70220103eaf723ef61ed7caf3d06f57f4407dd2644312b1798fe42dbad2000c74e10eb65c19fc9c09da6a3cd518c882f4cddac988ea9ccc98d002752923400af9d539052c21a93d5d51811ace99dbc1288c39c572d9285df8730acb1486e00b22d0c7d920d9f89c3e464e52a54bc621079bf38f9071f469a7f0739496c080084eeefb07a5c79a3a5d3dabf893aa6d5f12453b4b7f0e1312cdcd1320127d20040109ffe7b2ef302ff493c35a2fb03b5b3ccfb286a8fae7760df4600d6a96100c27d6413cc583fd5a06e2309dceb1ad5962b44a207938c8f245b2aacb20be00058c91a8e0d539b39533464154c4c1bdfce67a0cbbb2374f1df950566746e0d00244dd17186804565d6768dd5ab3f04cdd4e91eae8b16bc9efef9b4536e114c007f205b3adf4f83ed2fe03a40200470863478fbad8ef38c5d110c4ad816bbed00bb2a04111f1c637085777e420f49bca511d195aefe280f095ea5cfbe5231d20047858a7c4beb04254832c0305fea73e6506af854ba5ef678dce854bbc6296a00182746a5163b1e84e9271be6302f8067c23c6769bafb4dd7ee56b0e81a270e009f48762a4c0e8de2104112d70948589575f6b9f12cce9dbbe43c511bd00a04009bab84aa13a04efac60b5eb97c0f15d5b6389ff51ca159e50368b4056ff7dc00ff27e0a1e10129f396b03e36dfedd1f8c83c98356d01eac36ef0793ae161fa00904dcd858404d04f78d8154e48188cf72af545e5a6954d690abf1354af8c87008240ea1ecfc1b8234d6d21c5a9ec4ed66a8d72e1e80dd07d943b1a9c7edf90005448b9aa26903379bb99f05361573bb3383965a720727c75dc6d240e865e6b0075cb6588243fb4fe5340b004e1680b4325a9127a1e569aa949e5407bb917990005f0020991fc5953113a85800df692bac889738bec77886d623b3faef7861b0095b096b922c25b3f1d99ade1e884c456bb964bb00fb22745bc1223ce80d8690022c32a762824b6843f019cdec0e3ea51edd6d09ec3e20007b24f761b2f20e700c3267578b38041a444f8f50a43a24f55d8c878721a0598852559d3519163690040f56e1b1b014d815ec3a256d36089342421b323ef0163d26291018aaf222b00b73bbbe70ca62f5248757f810d1de0d5f446c00ddbd481eaa2577ea0cef11e00a508ef81068cdb74a9a1bd1281a38f5a7d91616cea6c7c99b67aee9743aeb200ead76d6b17c467a7f9a07abda71c710b7ab25f658d7bb5cc2fd03de969bc3000c2d618b3751777db6a152824c98b78b00f6613d8901292ac962940e3fc97ff00da05b7fe4c5fc13b70eee7851fb74621c363f1c5f206f925de4467f4f32bd2001ba42ae8a7138154184114a4a472e9173de1fd0c583cde9989a392b38f448400a1fabf162c74b5533c166260373ef041e51861574c954091f31c294fc68b260044b3bbfb6f34597ea0b088a4b6217933dfbd63b97e0cac7d290f4b42ef371c0083ae2821d7bbef6274b5b990dd074e6d28b761a7c1c3c9bbeca1d9ca2e4a6b009ef379cc8683a04f721dc50be0ca28651279ce377402b5674a86a45a5d49ec00204094641f94725b8138f0d1b56f76fae2e15bd11990f7dc57c4b516a5c403004f0bae1c584c9a560b5b07e32a58fce76e14cc682c2f9bddd976d02b15da05005cecbbf27d1c38182021443b6e23988755efa092cad3f184ad7138511de7c70086b285cf0d64c38096f8e73269f8a0025b56568934ac7c27d1d67177ce06e600d890cc43910f23934fd1aff2e79ab6f1130ee7060cd590ccd47c99a8a8a2700025d534f4344408a99963f400fcefafc10a60392e0596ccab4418631786746b007f910d5e7182c80f6e9751eb1f7a64a7a8df8849e000d34c8cfd81338446f400c8d6406c18f040c5f3aa244bef8262e09ab827c76b430b14cdc333e309175800f0f13ba0276fa5aceb2ed9aeaffe192be06e1072d8780d7fb0ff98a092c9360069004f90d3a9ab2db289a917056876ef5d2c449f69e23a95015d95a55d7d80001e359b19375d4972e1bf991fb46de1941ca1604a64bd9893d8432c06acdce700a2246e48da4e1bff527b64270e21ca8cee1059d82a82f1a793561b31695a87005e99c96c610ea77e8015402b2d5f4c2e86224fd3600bf313ab4eb8216e91a10048c35e2a7a5964d2fd9dd080e4d4a35600fd716ffcf50391c7783fdab5624f002f6bd358fcbf09b1eaae2e9c6de74304285a25bb3e6016de8005493151451b00ef8a2a53243e3584d2a0b7159e4452628a2a055550058664063f0daf5ceae80061c454cc316b27e3d8b58ae9843702a1c7d9bde8a43c74a6a14d19b9420bf700cd6595baba5083f3913bc3559f99139b5426cbbeb3fb49fa25b1dea42865a800964c84d479b92706ee86c054a255b480962ffbd1c6779eadb1cdb16e251111002288f28683a075832f035db5ca0e4c44cdaff7cf9ff1a155a3a0adb4a7914d007fe76c3c0b830b2b815a8d2ae82ff9a38b617e365c90750b8c1138ff0292bb00de915fd352cb6b38f43faeae4ec09786d47d05db2d090b5b1d2577d9751ddc00d6d5cc508ecccc62bbe982f8105740670ad212beac74224d3d21c677c7f5be00ea98894fc5591600711c21241917f04f4f3f980d68c665e729dab3eafa58f400f6cb3d49ff4d8c5aa332b54af61ed02fb483866c7472230f0ba91bfc7a88b400059137dd724669834a2f0a6601feb268e3a804bc4274f3415c9e73f640a99b008a06aa305bfe4114826dc290536a7afe56b1ea4821f7efe3f8037c8e07d1b300467e2b44d0360a9031258014770e75c0e3ad2d908218bd54553d26555263ee00886aa5d0c54a1d997b44979c1023540ebca292c855d0c68d8498cf761c9914002a4167e2480d48cab91ea189bb19b07a8dbbabb4cd6aed452f959bde97147200850e4aef718b6c208dfa2187f47f80915498245e54a7437424f3a7b98ade49002b8f5339f94c844f33fb8da3962608951f6711d4addc4aa63c9b2e3b26fbf2008e35ca69ee615e97332160230047d8846928519a0a2bb71ab328b45af09a920019d0bb0df4476edd5887db940cfabf7c30b846850124bdc1f85910ff51821500438b810ae8fc6cbe3c4c1610e1436c5e71390f2ea668e0d14506d1ab1f9877001c48c5bf0b61c4fa1c747893859397898a4a4f3a82bcb35ecf2d2130a046550018db67e000a844fdee3f654da6f28e7e97a845896f72149e84385fe41a45200011eee1ea8d9f3d08d77354c5a5a8f93adbc6fb1e5c537dfe2f972752ffa75400d7495cb612e93b82c8863e4929309e609c5d994644c138908558db62cf588a001597b4848184f1d59cc82ca8431b86ec7d5f8b93e2adaf9e048a84e496d79f00818871fc290f76182e464da4630a99740fa47bda3bca41d1cad5360a30983e005b3ff9754ac26fc830b6f0203935052062e7e63e9e10c573c9c470037044a300524303d6ca20aece410004906617103559a16e61a206435b0ebb75e0c36e7d00a710c7ed52f22603e54ff40d9cfba353db7fd7ea70d7da4a80ad7be0e687c700c5f8526f2410e0fbe08f9d997bdd504a3b3cfa18cb7274b6db782256fb644800b55d14df9cd7da288d559b249bd8c95e0fad0b5ab391742b239774916bdf6d0051ca10a053ce902f94f23ebba42687309431f62ba4a91fbc64203bb73a8610000602ca27766c30685b5fbec87351b0672537e2c0efa2a4ecdadf9be9bb5ff60097f5e839ebe5bdfc41fde436b58dc6c94d88772bd45ad623d26e7602bdafd2008366e253fa4204322c4d48158f03f2ce6e3e08f7e0eb16a8341d2d0daa99f400ea5eb3a92faed2adb330344eb89a1044cf1acb9373458414c8acb2d3cf9d910006e90a6d63392df366db7117a70443809550a8918de17f6f29179a82597eff0025da16b350859faea6e5dcab810554750f86975839f4e92870339987a6eca300c460d78e0ea799a94671f8b48039b08cd7ca53f601a618658d8b13bccb811a0091bc57ba87399a37ded97517254f7f445164b4b63749a5b1188293b351667700610bbbd86a3419ada2e795ad9eb72a6bcaee7df234bbc2b4e04adfcb94b0f300554a332c47cdd65fb3605639a76076f50442e7ee65cb959f1eb144344268730092ecc2550e729b28d9a80b9f962e5198b0a222c516a45c508c4b5e683f76ad0081dbb080b1810330838d3d7f1dd18dc9864031405a2e4ac1fc064819359b33004491f5c2ce9638b21367c89cf7e4ac3d2693f972d1fe89cb47d64a6a52aac70020fc22da76b62a00fa775d564524a51c1a2200ea822d9098905b5c871dba5c004efd535d0ba80052c0c222e0ff78856ea172b2c7807e83d0338e86f297e10400167e5b08f43c09075e332c007b6d016d677bb12191d6a24e97eb3578d435da00f4a47f63fdf6853b686b6e75d1f71d48fe1a66028f1cc3ecf9f0d371e636640043074e6c9e79d6c9f05cb137f19a2aac5febf4d831143115ef5fb36eba876000d9143a08a8cfc1926a8dd9c3ea4cd8bccdb032dbeb700d92ebc3e0287a6e9c004305111544372eea123b4349f090f91fa48593288720f577556ff87c191336009981893c3bfbda65174c2bf4eb6bdb91a1dd4ac90f26d24ac40f244d647c1400fc1e645b16e6bfa28ad678ae57c5f9060648680442b2d044c5d5e73ecac2ab00b30ee2e42c54a5de0d375d849b104b43f188d8dc3e193c7e9c823d8c144c1600538e1d0117ef4459f78640bea28066a4f3f1c8b3e6e8285cd155a8f49402f500521f754f0506a7728effa8b0e071e79e7faf6b38723a52fd19c022f6f8141b00d53b7fdfedd069f0096450a945914c68c273207789720d82a6a31889c2a06b00d4f19078b45f21f44a193123c801e9fdf04583a72b1d2351ce7e4cd51e4502000be1e69e0dd7805cad594d6d41ff367dd561beca87aea914b210ede49e71570080468fac51aaa4a4fafa6cad2b7101a878ac236ee493b1e6a83d0a682b077000f0c92a85584c32d745b2cce7fda3d494fd97faf9f0834f6af0777146bca8850071228b843a37c3c791ddcc534092a91691a735e9117f96ac892bc713a2e5270015a2cdb50a31cdeac3ac8d124fecf21db94a495fd563394b0f98b1f09730aa003af7061869b16ab952c6b2e50400c2eb0b0440c80069bc6258c111486f68ba00e4b0c42c2676808bd3762fd1cfbcc32b55cb7faf6d383b7223ceafbcdafb4d00781ab8c381ce32d6fd8876dc3cd5715ae08b764a05162f9e2bf2c99241c4ac00508f0a5c689c92091cda2468a62e0b4c21aed3a26ff6ea3f168533bd14f2ce0080bbd41c3620b77b0e73b05d8305a5f9f9468eeaa6e47ca6a0e57b7ff3916200df7df2b2b55a741f0685f9effd2becb40bf980739d0bcaa26878a5f84978b400fc1872d1e92cf292ac12aadd8a571e94e5a391f6955da1a0107db0f7a29392008776eee3ca7ca0d54bc2d37c756c8748a32a46a734f2c071f33ac9f7198bea00b62d007a582274f567de15815aaf151c05905d757d74b8fa47bdf4b4bcdead007037d2c74aa8d2a3aceba2d8dac0707e32112dc0cb57026febf19bf526d4a700d2695ce6538596b4680e0670f968627fab3f72963df5ee5a3603d430f30ff800010ed56d7e2f18101fe074a07b7db7e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","kzg_commitment":"0x97945ba52be93ce4389cab44ba4ca9a41122ea441c55860fe330167cb8149693b40ead0b6016e4952d08c0b9393a184f","kzg_proof":"0x89affb0483ad9b1c6e9a54c3e0859346946347adf5777914b9151d0cc6ae88a523ea0d9230a95d0aca75e6bf203fa167","signed_block_header":{"message":{"slot":"7422094","proposer_index":"129686","parent_root":"0x811c9952feff5a7c8325635f1729e31ebca866ed88a53aa5f26cd11d4b9788a0","state_root":"0x0bd0bd3f512e5f64d36170790010238168bf0dfcdc22fc438fcf12e7675b33ae","body_root":"0x71d8c523acce371dfce3ce7bc2897e62fcd72eafa2870be5ce6c08b94d444fe3"},"signature":"0x8ed9b52cc7323bd7d16e7685c4e5608fdc3144fd053bab8d2cc6cd19048b0214d2aeaa541dc4221e4587d9ef9830ae960b5d417951fb79d86fea3bfe31a9fa06a83af01ed7e579896afc3ba14e3be41b7934ddd1886a79cb23cd1a9031cc7668"},"kzg_commitment_inclusion_proof":["0xddee5edf41febd06f21c9bc4c091337121938392d9d6e5b3d446fc39a8c3df12","0x377f03971f37c0bf16cb7405a8a729b947e77ab49bf0915731492370ab12b0f4","0x8c0b1d87cf64f28c21bd39edc742ca5f7bbc3dd5aac8a97009fe53ccc6b47011","0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c","0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c","0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30","0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1","0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c","0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193","0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1","0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b","0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220","0x0500000000000000000000000000000000000000000000000000000000000000","0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535","0x56bd14bfdc37d27695b4efdf7f9851efa0e51272eb0fb3a5934f0d9f52ab0d5e","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0xcf8646fca4890f4bec369e0f281f4c3199f294b2f3b3812a4a2f76639c93742b"]},{"index":"2","blob":"0x001611aa000000000465ff00ff0000feed3a0feaad4eebe18c6a83dd6876449b00a3b5dc20ce518e0f25ab7916da524199f40a1ca75fea313ffd62c07eb2d8510086a69e31c2fb5718689c6982948151e7b635a327cc77157a02feecfc736d93003c4a9acb3d16a3a015a6e77b82cf6d897b5bd2c0096bb1fe510f74a13b2fd000616897b7ea0fd4516f79fc072a97b2a3c9e77aff97f27c744d03e39d1bdc7c00f3cb8838dc97b21e3092c7731de7046a4b984ee50e5b9330ca6ec3c163020000c6e9f3097ac39831a038fd34dd071561f707781fb31eb3a50d9842f0527b2600e19490cdbcbca22554d2c925a263760fc7883b00f05b91037748f5f756ce8c00ff4bf17ba2fcd7461376762233d499351c328013b082649ffbb04e3eea85e900f65a7ac489482d99bd9c0a9e5342c5e78e9fb79bfd7df30ede822b6aded1710061c2b95326222161b7af761b1aaa2c3228fef6305b00f705dc2fa55afa4071003b41ceea65696603c7aefbffc8c883bfe6ef139d99c24fa0604890839d9aba0030dc4b2844482b480d69adec924962ae65438611fc17e8b18490adaeadb9bc00abe0cf7e6b05474a5d56c03bac00f6c34534b602986746e1e82d275ad3425d00d8aa92bf528af342920259d53973485034c8b27d93474cb570a435e364af88001ae482058b17bb5b3063c00039aa94c14b6d13eb138ea750cf9a5c0a0a515500506f379dcecc9462f0c7cff04f0c7750b5b2bebbe55b9039b28a50793287bf00e114b6946054e7105f24a422471ef236425df622cb06420480d99d4b05271100066850378eb29786adf5bd1100943fb103747413a25f7e020a89edc11091d5006614e83e89200a2f78b4fd4ad0521167efbb48964f1d36b5545714a9cc706300e6df72f45f8acb1766951b2f020ad8cb25c42b47888f49d4a774892d0f28ba00e110bc3500c4b713017945ea090eb476ca34c9f59fbab699311af12d0cdb2600e830ec4d2e394d2d63906c7900cc8b5b96907ac50206378c3b59f3d31a9e0600784bec64e132492903c5c17396b474500933fba3d343e86bad0e300051d4c800457b29e722bb11e42d5fae9c402f8849bd6b1c53309c07b95a75c3024504ab00e91ebdb7ae86032577bc3158b27b19380429e987a98e3726538923db68538f002b1a46d359ba6a8eb6af8400f2cd1aad2380bc3cdb55ef568d3a5ea2a9eaaf00eb7d411d16bd8911a9492a31ebb73e0ed34e191657278745bb568642ba02ff00db2442747710f5f899a0bf74659ff61c18c5a507a4dd1cfec4752d58ba3fe3004b3fcb589f292c5458006ad376011734a857c58df11fe766eccfc77de30f520026d702f854367d957f0cbbc0bd5f7c8b63ba94f45ae117a860d297f7a386b40090fa253278a65cebe4be05fff117c1aae07792cef5f443397ba75ce188734f00a8224bcec104f96db7048900293013870a0067eddbae84c79a3ce1a8e1bf0b0063a7aa2eb6e637493a290443bd292fe719b60c6f8e4a578b6489cbe7b6b32300d8a3cd985c7e1adcdeb3e7056fbef5b540ae765c89b117e1151af499a37a81002e0f34b5b80c1b6a87e24c2d676f307650921bb8b8219c75fde2a21dfa395100dc471663a05edd8833faaf9eca8f3fde628c542630f2cbe4432a5e48d6aad200ff63072a9887bad7799ad107de12f92f6201574250b4450963d6d02cde42ad00cf8bd3fddb41c9da709fefb171fd253f9224590692220be0f05207910697df00c820d50d3ec8c63c26b3c479dc55a85fde0456459db3f641b59d10b280d4fb00aa0cb1c542144052e785989486444c2e2843e98c708cbb843c834fef75b2f700308ca401a9539b6ea5f4354cb3c31d376d49bfba8ff9b441115df806fa81a600b452e2cf1357b5790dc8eee926c8ea6d5b3c0df84918741bc91cc263c3584c00f2094433c857359cc1235578e10b51a49fcdca680390daab5d0a1071a985ab00d70e003497eef9bd94f87a49a22d3c31d120684bbb785e3734804fc051d5dd00accd630a69f95ee53b66e7599b1c639c49795eb897466e16cdf7c9bb2501e20015e6ffd0eed3e7b8d3dd4f5443f6bbba5903dad0f4d0d3a7aeb53c3d5d3b3d00fae0c8a488274e6a22305ccb0e4e4a30289bc8df52efd9f79f8217b5ebeada00db9c217f40f0a867794ff83a063a2ad89b9bd3f46b7e7e38f0f927ea4871a0007fa6947fbdc3b99cd2e3e7a1809d86694561c30ea17504bec8373384b7113d00bfb777a8628dadce5bb6d28c9120d9e8ee5a47dedbc755cdff184d0141fc910014ec02c59095bd08b11f614590629dce65e415d71873fbe958dc829e2afda300b1621671e6ea4e3401f5daf72d8d8a603ca7362da15ddebdec2d4f9f83dc8b0042b4cc60378036d7783c1dfc823f083a926196b6b2e0951bc02fa547a26aac00a9f5d3697262bc689a0be25d2e2ec9f9620439bdff326afbae4e0d02eb407100e4f70319c54dae535f8cc3f8fecef0705f1e289e0dd4cd8364f07b6a2d8111005f607ab77677e4fff1028e260a74b3bdd9ff6f0261136fd42945b6ed9aea0a00f5e5da1fd9af8e9067950e44ac0985cbf183c03c05522c2238a7723679f22900c2ae01b8b36ffcefa641f01be5d7cf198f2b09ed4f7ed25e76b841c7230b9100f93d12cb457f96fd89637440767d7fdf2253a7add1dcf6f97ee7e264e71a26000a9dbe0a345d1ca3b6d2276f33281ead734764e53512613dae0fa88852ed8600ead110cc35c9358e6f7e640cb5ea2a2e134a772ebfe3a773b5a7de8d85a2af000caa0fa80bb80c7ad6c644ab2b37c40192be581e0f43c2ae192b18eb2cd616005caab2d676b240147dfbc3a2efbf56e304135388dda6dde5cde05da11703440024ac8e17c7c3e17221bf4f9f34270b4b55f6bbd99577a8016117156fb99b4b00d99edeec905ee66618c28d5fdc637e1498ae71dda32bb6f27e573c00f9130c00cff8858bfb46ce4f381f82f329b8c0967b6c4d699ff14c6dbf98f545af7cd800ce4262ee23a9a27267a546966d9ebc6da2f23cf3e59c204dd820f40946568100f3000b40f7fc2ac1942dad3b514c6996c96311fbd915bff1885a0f7a825ebb007711ad7b83b013af2a1e99f0cc6be4f4fb32e6998f4a38d1fb6f86c1b28c33002c9bfe8441b172593cbb1d9e400805cdc86e46576a103f4bbe3bd34ebf3f0000eecb8edb83f06024c4de297f22c661bc376d47aa2ff9de6e2bcd20c8b75b9500144d30f38b5e6b414adf71186e24056a0de733a2fa3a8a1fe5a6be911711d1003a4f6309586cda3af383b4f5237eb2f8a717edb7fff1c343f086705c980600000d4a55804973fb10331f69746b011c5c69c675950674487cf4d6997a87b6db00078eca57793b152ba2ece1d062a039b494f525275d9c3351191787ecc0c448007bb55defe75717ca192117e9a001e9eb589dce055b69bb2a6912c0f805c4200053e0ba5fcfdf0522913724708ccbb44187aac27144234fe34b340a05089b8d003760951d01dae684af1274daea530a8235b25ce586e928c3045351615580870041c08a820428cd1f86aa867d3ca42047a3be3ae2bded3333769bdab12c6cc7006969a4cbc80e2ce61c752135ae2ef063278174b38a17ae325318fcfc785bd60016a5a7124f32c6e9b1cccaf33ae33cb996225d6b542a04db371cc902e3d154008e6c60ef9e25c5481cd3dfb6d298b5ba399862984e939aac0934e881a0a567002ca455931f25e7449711ea987791dfa89dee2e7a254a13e807214c27b11f9000526432958fc08cd86dd120beca705a4678669a777f0e71daa2c50900ec49a30062c4dd4c6145bbe20a1380f0eb70eb5ec8e8673525f1405cc7f44644cfa17100985e1db9fc7b4a15424a2d94b5ca558a394aaccead7d5536b11dec7f36af4000f571c2f1f9864cc4766674efe3e36b53376cdec363f7f2eadd54267f969dda0099eece19011170165bac42e6bb7fe1824d72e81a0dabbfe4701b49dad7d48f00bd262558b39735713166415c18fdf52e29341409425d426c0994e8009b709b006724099c5792a23c74cbe5d1586b30f71d9bca1a37e482c0585ce2ea1718a600a377fa10790fbbb3e07aa0f5d961115049cb39bba19d5f4ae1ce5f94c791fb00121225fe59e5767ca1162c2724e77e63dd67ae95b5c78422955d3016cf2b1f00165b1cf0e12b9ed0e0fb26efae4735762d9524acfd232b73562c17a577355a009f83eb3fa060e87911889c6bc73eb1eec5dc29415218d876d451cefe16b65a0073b6fa84f9838cc6740fc4010ba404625aabaa0e706b436a9a9435a8574b1600a479ba6fcdfc9c42876da3901e10599cf022f5810df599be626cbfc7a874c10063810bafc79d8a00ea6afa9ae58983c7001fb27e5db367b3c849a74456f68100b0fc6aa06b9b36f4ae6f5f041dc43fb8d152608e037e57be1256a33cd00d460047b0bbb890bbb706622d1762201a7f55f7c0c716b60d02dbd448637c3c0ae200bba947654821a021a65daf99e7f0f6434dc1a8f606d60d7f5bd3f9efb1171f008a6743607b4abdbebd5013a4659af055885cf5efd854d94e8c898fc812660b00e0c427fa796ce7708de86356bd26b771e2059148d034d7cf104f5a44516a0700f7ea213da2a4618f60e9aa76b388bab16abb02318fa2c93e1431e86d578c1e00cf38c4446b0b990f30e346a7bf54ed4b278eec989232927ccf774a7c9e1433002ab1a21d939d692166ed13690e668b33e31c97e16ef57fc9a9d4b060c706fb0093a039120171114859dd6688ba0ca9c910b7f06e3b23968de0161324924d510052c59c4830beacfaee79a79b1f797ae4c82839572da0ca6b6699e39b608634000c55ebe53cb2f5709a6b2977fb40d9b7cd48aa87a15b4d36df75f10839729b00f7d3cf96e8e50525ca84707690232500667dc588d816f6a961ddca71532c8d00f3351520a0a2d17e11e883d95453c98caecbc549c93ed4d525e5e76a0650ce00206e4a6d8760be64fb81982e7f066d09ba5c47dcf9196e998c68b9ba48a26300bedebc83e2e27a0f7bde7aeb93124f345bef1de2a8ccd05cd3207198d4aa4900afc34d3b769ee05967b7afe1fca2fe18edd1c4d798e44203e41547a27906ac007313192a0d82a82ca2f233751f0bb85e05a786e4170e38a80da7cdbaba72730058fa3701b7eda9c24a5bb36b284101ff73ebcc81610f3534d078b11ce9c028008e98b28e9a9c5e81043bafe3fbf7df69b56d14e4bd1dde380e43c1206bb46000c2f065cdfa5c26a442503daf55aa4dbe2f34bf23dbe956c84770a50e5b39f600f70e3b96edeb07939d3ebb88cdde97d592b63c5ceff31534285bbb6e2f822e00c470fdf8e443b0961b756ee0fba743c89b9a647c17f152c6c98e847a16159d007b89e8b1c5097d633d119cea01a040c89b2184be467cf11f9ba9e464b000b6007fa4beded1c1376ccbcd247e50225a0107be3e2d4c9053733946bd9b6c63f5008991d0edd39e1473c2f7896f8efb95e0766ea32e1366db8e8c2309b804fed3000b4884c9f3c620e55d30bf063354eae8ad5d69c40769f9baf6e6f86950714300a4fd7d9fc476f5eaf07f9813de1183df3ad59b50f9710335f9b92d8be21f20003fe2c4947d458d30d110d6e1f9ed530b3e75888f1619b30754d4c407d83bee00280bc3bb75be3b994f2dd151571d3d654ac81ad632d74110749303b9ca557e009c2da161f73e1081ad8e3999fc8cb95fbc12423e12b7e98fc16a75755d57eb005499503a715e9cdb0ef656d8abe1c838f00d4c08bb580a55dde1a8d86fab6d005aac979b3160d75cbcbb00e1e4b5d16997264101a2da186f786f175e9e2349007b5f07b46831f70d4d191ae85dcee3e538565356cd91baac077c0bc2b50b320078cac8af4f65ab90066d1736133a20f65f98eabae60500f9fb65a3ff4106a000de18a435a8168ff0ba0d5eb15254990ffb3a0f4bfc236cbe791222822f8976002963bd83d031e6cc926675bac668c4bd6edeab270accb5668e1fb1f670b11800c4790bedb8f5e91ecd61b63d7c25f3d5daf8fc5d041b19a93539898940dc84008cd418e719248de42d4b99938cc22a7eda2cd9a2daa0c3f6fe64618606d70f00c0e7ccde362f35e9aa8f630b98cbacc7b29466f5329e4880efe5a05646bfdb009f461c447ccfb1a75118acee638aca77e2ae0eff7fb69373a2f2cf8b6d1406000b6e0753534c00d9e662cf8bee90886bdf936e3af0d804db72c5021f541a8500a8531cba729c5a5410eced76c1e297b759347e50fd6be480a3dee69485087a005691f283170585c3d30ed6d5c5d4b757ba21082c03ffbb92bf89efeda64ee1003f6b53dcede2a50c22b16cd027a7cf3dccdc9713c3e6e827f008ee666fe21c00e054dd49862283ae55dc77fb975256c8d6c0e50c2632fee2823f767410b6cf00fe50887c134735927757f1c3c1bb734a3c5a34e572687247b2cabb77004f7700f88a3d7c849cb8faf8f3eb61917ef9f19770da287fe6dd565734770c2480cd002f8a2130c8d8c3dd188750613d1befd03837ef26e2689e58248dfc922ca40f00a06af960264505f3e7940c35a5ce3ff4d88780c79377ffc8b710e8dcb38cdf00e133835235219aa867cd84f4dee62d217e1fc4574a146bea5d2975acdc447700e546a97ed54f62a74a4600429d93969685eb0ac55d6657de3f7ceb634b78a2002f84ce086a594580b1676d9070ff1a324d7c89e6eb6da92b5a7f4e2e95e0fe004e160bef8a8163eb41197545e931a6d9c1cf181dff87a6fc69bde31e40d8c800b968c930ed9fb0ef53fd774afce66136867f0ae85a3acd071a694652503d7e00ee63e597832c0f2d5a30af7ce465c018cacd557661762a6ace321ef646f0e9008998628dd0b0e1c377fb3ef948216489ac42b8e1c8f7bd989217d457a704310026b7a9ea429fabcaa5b77b37e96963b17c08d83ea7647f256ce6d015587b5c00c1ff3fbdf6d8f8ecdd6ad39da427df8b51fa8b6abd3a4f4dc4f1bf8437b1eb006c56b2543c2ae75776f3196462def6cced91fa3ca0b295ea89abe46bad155700b20de898a65633f7ba5fe3e18cb578f12d4b4540a7e593226a4215ced30c61002eabe5edf92d892a2622b96a2c342e0664364f246c4cb3898e1c82ce9c739000d8e547fe0695b4e4c91d0f8ab3e1abfa6f07be89a4e0ea2b100ff246579d420083fd88c40856c2391750bd45493578790a959573c27f9910e0b89d920b7822008f0e1a5457958f65b3f02d9704206e6e8b8f4a491f4c7d6c3086ce8280188000cebe576c151912b5371e90e5d8f9ddecaad7f068a2529011fbefe92a2736a10058bf65bc0650064ad33287e30b22fa9e878787b43d846a66752233eea9a357005e427188433d28e002a6ea1609c555bc0ee36a086bce17ce57a0690e6fe37a00eeed57cc8a0ec3280fca1daadf0ce5a16286e4ab45c375ea7ded65bd22157f0014e1871923c5c59c7252a6e01fcb5d1533a168b48767eba639aea7119c6642000faf26210b227c9c0f8eacb38fc5ecb0a3696b1c807a2cc8edc1d9393508c10039514d66b90a1d155478d6cd2ee6f128fa7e39134021dc42031a162cc5c02b007433cac767c9ee1bfdc1095484ebc7d32b33d57030c922cef18ef37cb0744200c804263861a3db391b24e8c0c166fa86b882e54719ef337af7515b6e5b94a000c4465199d62a03cba30c3c0c4ea93d53310b16998eae25c4679d41a4df6b64006c2e58618a3aa1e9f05f681d1f3728315c24d7670444a9fb0bc5c80650657400b03d249c441d09f91f07eca0810ebf5035fc214536597d3eb31127cc8c9a12003faec71d957c222838a300482e1511c389ed42e3cce3eb3fbbe348030d7105007284f047dd0d5b91ac272100de069575d192245bd5eb046ff4b4d6f03ecd86003fc8f10bac0c7ff8bd216bb3213afb9324641ab2ff1a648a74171f7e6b86390047e4db3927ca867443fb6dcf2bf4e20019bdffc17c347c22bce42295a5a55800205b3d07309c1d5c8436eb0d516cbce3cccf57bb181ff7325f64735570a2ea00cc871cb09777b4658f18dd77114a5a74366507d38efe426cad3557e73052240047ba50e4f568fddf195f076760a66281efbec7facfe9eeb03aa967c178fad70018295a890095429e799c1062f13b78c5587939aaa33536d7156683e6fea5ba00086d0f379f373eccd8bfcf83f1eeda66fa1376eb15b1edb2e9f7a651f4df3f000268c88984eaea2f3b0467792c36cd0114f8990541193f0256fd6f33f5637b00845bf687627a09665f711b45ef67c0aa65c6eafc0da3fce5c7c100093805b900a28d1a202ad661f7a6026f9c3789bd6fe96e6ac3ddc231d2a9af3f67fbb35a00b23dccbe867fb4e2132c12fe4faf99e83f5a88b4e90ce11ab949bcdb47d283003e70e6a51f4a06bc51bbced2550c9dab5534681412a88f9a7cb588e8621087003c18a7d24658faaf63721ba898bf5e6719f1d742058c35e51e97746256f13b00bb55cc1a4403014739ba3c3a5b713d71126078aa55fc822059cd1d47566b75003d50cadb2103dcba7759fb56af66fa8f09af18b5490f03f2d4bdb416203de400c083dda343714cecaa6303c3a7e99e08d733de5e491934aa4966fa92ad585f00fbdb10055cfb0e7de5e01e16475866cdc98729f65e1f3522cd21a06e5e8523003adbbd0dbd1e04a1b810bc5144a4a67bdb66a5dd27914842b95757940e0378001588cebdb04b2a86ea995b7ae54d9c33341b7e1945205b69ac6539e071a7a500d4bf954b0000974b90ad76cf508b603baf24977967186f71b73b330136af6100bab635c47a3528f20ed79217a40bbed4496e0981b02527047dea0226c1917e00dc7f38e19222dfd147563c69c4ab9dd5e29f953382b741906b2cf190a7a9d000b479acbb70919b7ed395b7af4969b04a2da5c73c41fee7cb14c23cb1392ac3004a66c2580e82028ecacf9574d387c86aa7fd394725ca736a23c065e1ff9fa4007ef4020cb80ebed3cfb9028b0a1a93a0753dcb0571874868195eb695fed6a1005cce7d179738a4e2e3f9c4cafaf0513e31ecadca9adb03948d9239428866ab00fd027dfcef307d4a4de53529c0b1a7494deeed5238a9b7bc087b6d0d1b8a0a009987f3ee724595cd1c6e6317726448e5ec6ff01043d6fa515f0bee1b96fba90081e3c9b83e5de856c7f907abb98865aafc63283bb7291153a993d824ccd6e800f35a3a34e622a3b7f76b8ba31bbc03a736d4007906c3056fa7f9a3af9cdb9100a4fe50290000323762d55d7ee988ef9b3625a1b5124684b1a4895522236d42005a5fc5e372f9dbba10f9b41847579b1665d4a9a850cf777a08b1b787727d250071632e5b7b25a8639ebd9b262cc93a1f8758cb78bf7a671733ab5b57ceecd700711c11d51182cbfa4997196066772ce7f26cd77c189e90838d6af4aa34baeb00fa8ab3be9a8f0418b042339c95feb7f27e4ddff0a7fcf4b9b519e902c5d6320018a8ad14c5870452b15dddce3ea0d938effa9b74e0de9318efe5ad728659c900a44bc81ee6bce16f070a7ae5113ac9a2fa61652d08134539e504098688ee7800eafc76dbc2473b74ff6029456808863afafc5f88b4d20b348fe1c141c4b32f00562f166f2d3d100595e96a6df5b433367f82d71fea5fea4b1a1668792bdf1d0059bb86fccfb53014ef1c3b705c5b44aa3e6a8644c2aefeffb6455f7072d10d0017b55fadba0863ddb6308622cf18b73c612d1812ad7497fdf80846ed8bc63f003bd6fc1178d0c3c2e5bfb35e9fe7d3a6cc233f59bf3ce1ab5ef17d5158257a00de476e290c8f7cf5faea129c05e37a2f54fda031bd81ff3434e76614c0f34d00d817773c05ecc89ccbd138678123440344cf9bbc9f3c632654ee586426587900c726c96cb2523c7db020b61c9a7e76d94931e4bb16dc064df8e692adf97c4e004e1af276ff080c478fcce82d762465d7b135635cad2db5aa698a4a8e1bc893008a9fe1ac8a64256cbb7ba8a368fcdd36a050b8ee28257194eb27a68b5f080e0007b706c9b3f3b5b44932179615565bb6f15087ce2917678a514c7372046b17006bad2bfaba37c7c8df6d5a21ec16e66a665a1b91971c35ae82ad5d91767fde0017ce249c2169a46f2174d5e29462b9eb0b1aae0ed08e6b46a85e0d95a37d6800da9ad310ca295f3a81c3205385bf3f0f85976d5486ff97e730f942de20195000e6efc9daa75e657d821dc3cd431e8012d6b57deedaebe8ee27de7f986abaf3006421b6fc294d4857957eee86c44a68849006108e28b7185a8d93302fbf2f4d0065e482e81f03c33c156d459e0f409b929d0d02b204bc45fcff859b87a4817100b7088025492a3396431912240e9b7249bfcd0a0ae2c1862eae53a1405fc270009ace05e3901a7ac447fe1b396dc4dfbc0a69960d8c2f8feb36595fedb27bba00861f5ad87485587c11d438e1976c641eaf0832d6e07d29ee86b7ce6565b21b00103cbc7892bef98ede5afa5e41f33b8c47bcda16ea5dc60c48c56290ec65ed002ea6dd3af3ffb3efb060a3106bc512ce2f26eb960c9ba2371aefd29fcb3f1d009a3b074ba704fe569636c685c97ee44f23360a5cc1fa60d0b9da18fb11d08900a364b26ccd7068afcbc5b75ff87243872e649fabdceb2e8662f89c0abbe600001431e661ef72c6068038ea93422d7a46a6e3fa95da6657cc0618c65ee6a04a0029cc05a02bbdde304ef5aae5bd4178c29434882eb1b9a19f23b4383d3577710056e94fd0d95b4c7f7337135cb3e4f752b0106a57ff53cae01f918b59df62e7006572c5953ac7b1555c35af500668b84f84601bc7ccfbef805c43865c721bdd00ebe1d743abe00c91422a3274a5d36a291dc137b6d12582993db8f9b66783ff002528a8bee324744a33f3f4ba59e2d35f26d72fb95fa44d009eef2b23d2ec2c0068ea9f9e88a5429c35e07c2bc72679b044fd34420669cea4a422c537c70182008ac8f74b77e756019426dfee07ab81cbca689be16e14c3eb91c61c14f24310006a3bbf6cd9bbe0eca9666cabc983e368bba73d6848fe505573badc555be16f005eccfbc48b89428a4bb55d6f991965a5aa0d63940448fe04807377721fa562006b808c5c6c4461a62bc3ab207aac5f8c5e3e4f8bcab1cd7a46d633fb436ae200616f16247b15c1a598ab0b386d91d89443de06445386543bde7886b0cc658d00fb601d0fd9549c42c7a55e4ee0b05c61041c1bffb4c95991c35fca88ecaeda008954c240400c2e4e8d9e28b62c41fc7ed34384b9edd6ee54d2eb105bdcc27e00f6016f2857b8cf9588b98056ebee80d03feece1ae3b0123ba758eca696da7d0064e8d41be718e516dbc1a21e5fa3e80f4805a8e83fa18708d508ed2d5326a700342757b6b2c45f29a429b06e5407a31237329859731de7c95e7c54dc5d2a100043f1e77fe08690633c726d46dc281a1d5c81d03437980587438f6a086dd3a400645f3ecacaaaf8bc4f25a4852549aa1fef5d792d9cca476778a7bdd739c69b000f2eb56ff46cc19a6794d491cf48e892f34bd59feb5c894271588e51792fa9004a6967861f149cba411e30e6d6725dcfee39e39c0ae631d671047804528924006051b4cd9c7b72be74042c2a863fd8a8e2a3ba0df3a8e1e1c14c3ade91318100017ef0571d960ff8800e885cb8644b288b5c17c4cd9f6f31988bf903cf5ad9000d1839b3be677448fdb664eb8a7bee781345f59c8369875d341634163ba94100a45f0653b5efba312162a650140cd2848a20bbc19e756c5789f713d3ebbae4005220e84eb3d5dc05ce672ff41a43142e44e8ea18a6b0c00257d07e488bce09003ad0fb1dd82925a464e8149291c875ee2554966bd58029aa5b990b712ebca900898068a744439ed2a9e5b20943e3e76f720b575a53d65ea9f5f1ad239d7e4d003490191ec8519ecf7d097f55c2d2db6347f1f162833fdea03e658ef103e8eb00feb59a3ffd43e2d418ee25f71b70eaeea5698e099d088e9c2f909a8e2807f0005f3feabdb4b8fca63100dea599748f3f90ec697c93b0d205f0a5dab6f7d7970040bcd623719c8315d8b0b116bad6fd965f86e8ff5c84a7862d9f285b1974a90037e07a54332da8240c93854a8b1eb2892b72237b561eb357d336125742a27e00f49ca99acc39129dba93c5f37af07883c6cf155469c263577e67c5489cee9900fbd34475cb449c2ea8c9e8e1cbc9949951a6808292974a1a151bf101fd0542009ffaa1ff2946a009f7f6fb185419de899325115d5c11bde6fcc0303d275759004f68f6efbfad4a4473987c858781154016d52efd4cecb918395bc49375c0380002aff4fb995925785be9fa23ae2fbc3d3397e5aa4cebe0264d1c6ba8ee2e6800750c4227ab60f562e602c06426f6adc5b500ae091aa5e97b855f38e783dc0b00e910579370ca118ee564278253e17af5794d9a9e2e378af1d45dc64310155500ae83a6d2a863d640fc3f7acdcd34dd8b1439849c513564ff936e38f19574c60070cad1791848da37e3143b1e5b467f255c3b20f98a83448bca52ef119737e10098c711d4dda61f016284f01090641f8e17bca21d68753063acbccb975c77f6005449381eb04b9db923278720c2021318bfdbe3903fd0d7ad13e190dbd9f8d2009ce4c24afd4bceab4fc6a9213627fb50bb73b927ccea384dfb2a07685cb5bc003ce147e485065d525e2d3fbf1dc9ac7e64882611eb062526c67afe6229f3da00db9b57c8c56db8ddd9475ae03bb8820323741942a07137c56749034239863500d908cf89f18e3d9dfa76239b9306a37a99b6ca74ab7ac9e8edd8452ecf7173007210733f66a1b95278b28730f8715a24d65e0b0b2396c7633b979bb558b651002d02f6f11ee58ae90155b148080d019e52e49df4712b010143c9d1da26d0f100253ac3f253c7ef15ed605ccd3f0224781d5652fe44697a0471070a7cc6f6c000d33a567a26592e1a209e40b8566519dd51a1177ab2a6d17dda7d6010802ebe00ba42915f5d3a1bd268736490748157471f0c79e2d5a209ace5f5f80c36864d007388018c858422079956ac23716075165686850588cf378bd8ff6e6d8dd4020027b1744d542e8d62f77ff470506c99d48dbecebb5994a2c529b952d9b49166001ac60d1d8d7771fed905de34ed73b52db904499853ef6e10832dbbde254b6c005f6b857acefdaca35c973c65efce99a5efe326ee99087006c893e7ec91a732000a2c308f505286cb4a54c6084c9a82cbdffa5a22296b5959f1aa6432e42fb8008d1e78a71ca7820ea2ee55ba9d8a3fb473a25079e872ade1d0fe07d01644d700f34b1a463a64ed2b0b9c69e4b85ed53426702c4a22f675ac79daa8ec5a6fa8003689fc2d0a22e59acc7e7fcb6f4f3996e8f729278d826f52ba21d046a93c38006b3f6ae12876a0adca086f9b7a90d8e9e09e6956ec7c2cf0433525ccd0117200de3e4bc03d28cd0b7cc39611d6da6bf4fd0ff8a1aef54b4b7b732905d2995500a06b679a5401275d999f0836047399d04be85876fb1839bc00673e9761b5a000b595534c152ddfeafd8644f7ed34e5dcba1bac027b02b82e4925da5b6e8527001f18d4c567cadbb91eb5d8b896ce1ddbd024a5718314d6d562bb89ad3347c40086217b80ab7a6f88c6874fccf3ac460de2ec78478cb179274a4ea0df09722200d9c49ea6c5c28398cde49d72daa6e76cf504ff845e356891cc4e1e170f54e100d2293ebfa8a905d2d2a050442ae8c90c2cb100a0b22e563ac88957cf84938b00eb96b2574449884258bef80b563e4f650a1a84577cf5fbe41545c9370e7b6200c732bffbfe17a0ea9479b6f106fc97efe43111f2d5868645395d45d213b72a00e70c0b84bde728e8a2c311e4f235a4ab3518734d57acfd79e208132b37203c002852111f058dcd134cc83ec91d40bcc54edd6d379ba78a47eb65f2885de70c00798c695b8555c685fb658996caa70868e1ccb6ea2533cf2d3c59f1e08487ca003ed3dd041215aee0bc867d2bd85693f24d0aa434809720e5868520602316950018075c8660e3c4fe11c4e86eb92cfb9b7df0017b069d2edef46d97462f6ba8009bf07398c57623b198e2718e1a8ad8fac5fdfd172f27c209a1d0a856ae88c30048a044d7384aa04a364ae5788129979dce280ca1366072faef05ccfdba762300f176f12ed800aae03096b7fd498999d51ee3490dcd2bcfc4179cd4cb135b1000cbdd0d89e2a0deed656be7b4fe3d48c269a3206c6f1b94561de66e16c84f00001386c54171c2a0f6902291a2caf208b2c6a34b999688e414eb2148275cc5ea00e81ac23581e11dda6a2ac9a9168f637678fb8035735811950ce9e49b150c23009a9de1d09a6c3e9c4458a544ac2531d1b2a1ab66ebe259f29e21c3b0b8d21c00136ac3c3da19dbc66e9b7e7421f48188da7cef511b4760ab910ded0a75e49100bac9d9c2012e0a82b367fe0e23d1b17359dc0199a01782ee4688f4dcc330f300fb14ca7b4bd32be448102e3532fe3a8595b95596c7929f78e1bdfe42b79cdd00d8b817899dcbf375906937922f3b538f1be932a64467142f9db61aad47c9a500eea35689c4ffd70a38b638ad6037c3d1a22cc514ff38cdd3b3b2e7f3e7415b00a2106b780e710ba8c96a1fb78c7326b6c321e9a54c9679f9a0b98c56cd320d00981d41183a66bbe0cff886759213a8eb5becc926d868d64896143f4aff1ac5009ec0177ea4b774bc1be479ba42dea1c144a299d117c792879e721ff74addea0090f1e6e909efd5c7866feb294e15f8f1e328739a36ba37015bc61e503014b900bc6fa0a688707364095f586a34958ef7c1b95c74d1537ba83c7636cec22a0d00ff98097787905d060fbf66490a59bf626e5ffb5f94bd05fd6fcab4f53091ef00ddd5388f75845f9d1476646b8871f74015d03981cf4c417d8fab16aeaadc4400c26b808b439f7db830bd279f67d1de5ebd130520b7c38adb7462e74c36678600404c1f8f857a2ff46ec9a589ab76bfba9231a9683481dfcac596b94b7b5a1600b8cdf488a8e42fc0288cd0049ba02cf2f8260c77ba9eb40b7f36fc284150e600612cfec2fd643a2843f4ea43204f870affe32d76127b598397ef39100e42b200a1ac160f6f84ea65a8e80248d776875d0414dfdf772973cc4a393134383d4300b3a5fdd2d9aeff47b1e91bf4c99a988a8c4600ea4474c0d4671b7afe7a5e03004dbee6abe7c0b1dc625d2a9673f312511ba50c8984baecc41538c6cc153f4100290aea84bf0a910ae52c058d30cf76446c92172953d97477cd62926d5c5da700a8505a0d6d2f4bc58199dcc6ce33c6ca4cb2ba1179946fee9864b5fa73fdae004b130f37a3a3800b9df086532658a14c256a6f9fd81b9d3315ee614cf378b60032e0639317e684485db127c75f264a08fabf23b8e350150263b58476bb5620002791f890c85a80587618513b8e708ea447a25324b991da2285db76f15cd3d300337d3735fabe00745d9cb3926f67b9197c9d84d5617123403aba033091398900e96c0f5c7e7a62800dc3a48d736ee22d0f241c5d8adf4bca295e374c1c18c2009005e1d20c43549d3c64045122a667e66498d23903e2950aa71e0ae9da499200566a4dfe1e9fe86fbd08ca0ec1e309c3381c75508c0193aa39dd2903076cbc008f6d87c15b7225f6a9b66a4ee901e627410123e64c7775a8cf236a55730f54002d42ebe3fded6a0b49f81905420e7813cb4e483ff5c97a8d3bd38d52bba3f20016aede5c67b4b9e6d6da5a3c8d6e8e70201358cf08f3873d8907c27c56faef00fbab0473d72d7e147be7032ab2a30df7c2e91ade2d99c0f9130ee718f2247b002f514bc54468e7b6a022ed1c55b9af7dbc689fa18a92cd71ea6136d00673a000d7abbc5c19ea674209b93acb6e4ed98d6857d4028b7b4b70088332a335aa9000747066978d97b98dabd7c70c1ec2df442cfd9d3312973312d0ec1259279f65008cd7c6d0b651799df01d1fc890b6ae864112cd2805768b2f160bd9625e3ceb008f05a960ae1fc44c507417aa2bc4dc0c3b44629e1964feba9ad82248cb235d00b9fa3bda2b19fb26062f4f85682ac56ca7558953c20dfbfc0341612602a0e400baf6c68982e21f83ab0ed65a5b831cf8a093f3ae66dc9c2c0d11a53c431ca2008eea0eaf8884f3ad969135248be5ac89ce5677f47db3bcc3955124afffcd2200f11744ef365a6481ad46f533645dee4e0472d506945f50229b5214321eb16e007f27b91f623ca1513cffc12f08ab3e51bd045e146c69e4a8f80f03afcb1e2d00158b8abdbd17010ab49e4f5dee74d1bbb540f464d9454f216eda5a56f4c55e001febe7b3115bdb266c56ecca8d3bdf8bde4b21347104ab19c6334f73251d2c0078e32a4bd97c7216b18ffe9694bce03495d0e7c40ecc9c4896437d9eda7c9d003de4a8184cc06dd66fbbe42ccf9a0f394cda5f00b37731bf785727f2553b2f00d4fac7ef96b20832e7551902b7faeaa12a4aa6465092f492f4b976dd2c6c2900e2a82d4175bfdeb94b6c23002b831203ec6efad1b895ba3a2c3bc2fc9c8c0800852068c3642cb6fffa15bb6b3b28324008f2a1070c2ecbbe8070f1ccd0250c008d7660c72c446f027dff239af01d19fb6ccc3c3ccf2bdedecdf37b45bc298000ac3e6ca8dd1de54dcf08bbfa66e0bc91f50c961dd70337587bd6bee96ba6be00fb20ce5b2b4521e294578fc7af60eb49313b888ee8d9d375b2daf7503f28d80046c6baa7048b9d7a26a6041affd701d30badab27f11863844cd8af7ae5844c00d5eb8287d33f4e2c929dfa4982bf276a68c6e03f2572be40176a2dc05528ba009bbcbd3d2041973b45ee60caa29a807118762f6abc48789666d6621668d55c003bc2b2ff773b60d958f9f201c9a8f12a79c88aa85cb92c06f11bbcfe4dcb780051317dab96fc714d1afdddbf6e8c9f947f1bd60e153dea492cca115473525800fd3a9b51c037afd625dc9596aaf030d7c2cb37cf6a861d37219a8d8bcc90a700dc7818e7e6f06468dc7815fca37d0b89ca2be4404b7c807e7e0b29b0c282e10077132cc382ba6ab7f371022a66c75b51d2fc0c538e4ec665a60a0704ceadac00fb61632d890257c946ed9997f52925603c57551f16044752a4d53e8619433300ec5d6e67fdad15ba97cf4be4051f7a70a31f2ed284cf7f550c61f9a02a6262009cda522c9d7e239689936b83d79c7f135d81153543365c2a27c6f421a393c300d1c97805961e765c10949e5225f3ff73348d6d10615b21b802486324d2bb7200e95f315dca5b39d9df37c28ecbc8dad8d9a1bd11b119539f110d97a6ca290700fbc54e0fdc75bbd81687b2d358cdb3c564f577a95fd6a5558ad2ec9d8e6bc100a1bebbaf56a0ad814edb4986728e6a532b213f4f67524f41e10bcf1f2fbea600a20dba00a378e6cc7128647d31136eac785836419931ae173b457d1b829cc0009e7185b0799a925b25626325158104084e7626636a73842f7a483517196e820078a5f4ab6a205063af5ec3f3f9c115a60a21177f08d1316eb765e478860bdf00dfd71534983582e0abb551a0eb053cddb3b62f6587b2fe01a536933933b21d00ea969275d81dc232358e2ee8280a45a67facf317bae7c5e5329813c1c92e740015431b37b6f7302166a6746c65c6435abeb7a605ca514b9b11674bad66449300f0afeff26ab2046072731728298dc62d88b6357dbd45ed62ed60404152a8ba00bfe8a78935d18bc90ead9585db35195db259a9fc9dac7e0e551bcef3ece10b0069242135126ef1fede364f4127ac95d59fbbcc658d63ae9f9ea82614e537b10091ec395fa0c7f430e390d0f33c99f439efe073eaf04017e93ced61de05471b006b3e940469e75ddf522af53b426d3f15bbc24405d931f361fac9f578eeea1c004968d84214a85c1ef93143e73a6e620b075fa43bd1b5afec062c6845eaf40a00eec2eaa2106e25d8532ac7b9fb835b2d7281566fb75b10f8859b3191180a1400d72c4d6fc0ce143c9bb46d3c2420dbdd043c3c0e39469ebfd79c5ba86388ca0014573ad3afb3aadd398c2d5893e6085080351ddddcdfe4d6b5123066beeb19003f8739c22db2982e71e4914d64f9678ca75589d6328c739f0b80811d4119b800bc692ca17a27898142d7b1c59ce97a7c92d79a213fb43c815552df4707316c00af85ac4a217859cc4798e2e65e4a0da1171c2c9c51641f70f87527319feec100af185443412a0723666edca776a7579c2097f611474864e2bd5e9de0a442440016c5071131ca4e6f39032fdc583d865cbb03c5fa264202acc30e50e2f9af4300b9812564ab023af5dc426b42c5aed7b5ecd4c97462c4123984b9639a6e71ca0038d8b10bb34e3ef5afa37afd7143baed3ec6213766430b06835e9cc526fbad00affccd7ec05392a040811f78605dd853a849c41cf71b449b93f2173302c20b00d57123554c78fa178aa4ea34bf01466679b560df0486e26575052d1816f4cb0097fc477cf6d49c9cdfa07f1a4e7030c97904ff08d00be85980c997c1fbd7a000b83109f169c3d0e7d6f48c6a883275e6967a42604d85eb057b800fdbe80a2900ab0d4882daaab483cfd8b9124575c9516c6f42922831c9262fab84203a509b003b62a032aa7e6da66a34f1d4e4ad5fbc03b0bf14a56cb113c7fd74b5e6c7e3009bc7883616d074b20050f6db58cbed7d92f1d7800c583024b3b6a66fd2147900721f95647d9b9c4d1e7bf3aa67ba51a41ae8a5c105382464b1fa5e9e0bc67500c5ddd653daa6cf8f8d5e9afe35e6a14cd6b6ac9fd5820e9c145211598e8ec200535800374673a36a99d67410e3a33b6e4da4f56fc9acdf5f0db7943cb50fc800368d43662ddded9c944e1387af58ebfa41c7bf965510098712b59e594e7f7a008933d8199a6f74c1da1bcd4f4087cc23b6fa92acd62fc01cbaa58face3ce0400ccf670c534cd6f31e54094559b47ced1f0360fbaab00d5b0950ee187ce0e4f001b30dd40cc028eac346569b6dd42295e708f67e5cd2020954609ef7d67f444004fa030a733014e128b3cc90dbce29463310d4b399029c940829a33f9e8cdf300c9a1145fb1b380bd513630af386f0fd7bea4c09851a44d22c40fe66dec6d0a009ee9e08476cbab68ad3fa4af3b296ec21d327a399065a4138152b822221ac200603aee6d519a858f38ff6808372632390afeb4a214e4f772a93dce1eec38b50018c3a7c3531eb6da828709431f79bab803cd85727a48711f9c292fc1289df000f4340c982873338af015395ecc45de81be14e94c236c10bd6348cc2860290000958c2a3f08f1d97590539fe829de5599ff9a129a6a6665895d59ff5b1095960013f9b02b1044295f738ec5d7d0455ce2483333d0bd337c803e3ae6fa89101400190b9df0ae9f22d7f4ccf5d259ffa7f7e88b640ad5d96d24085bb7534ef7da00d6e98c11079586e56de1b030d21f37143482273d9e3ef2a9c6f90ee4ee1e82001f1736ce99602246ce906203f5952e1233a7f7d4fb19507ffd8cab8224a68e00da16857ab3f719cf66178cf886cc8cdd03ea4532d1c2bc5a82d1e10ad7c36d00dff767259c585a09b98837253ef08629483bb00177e44020f783d0ec4eded500fd4433fb9500f12d993847950ccf4191523dcca243babbd0a8727284b400450080828e2cedcecc2b43557fe4f04b640538a7d4e67acb5e88899c914bf3a3d200c14270dac262af27dfa83f7b34a2f39e76218f1aeefd4e1ec8364a99d4875800eaad8a574bba4a62713822cf490d3100b86f526d961d47219da79a048ce2bc00c672b7e80fc06f5c1ec6772b14081ee3c2409ae42f2a3db92cd2048d8be98100c0ec3e6c711462eac89a879a9b4fd366ab51b0bbe514f5b7c3663914e93c2000f2dc87732f824e8188792c42afe4a19cafbae616b1578d09af71ca6d8cd10300646bc02b3fc5773fd6ab46930ffca16d242c21ba8b9635664103c96bc26ef400b5d7e704d43fdfabbb121ac0157766b8a93fe97ce78b5ded7ea5713cfa050d005e45ec517bdb303477bba1b4f14e1220edadd48c0a9da3e33d783a0e136e1a00867c32e842d98792ef7a8c15f7e29e1093f1fcf6f65bc3d0f74f44d9f55b61002a3f64d7133b3cafc68746a7fe70838dacbbc22740d4f9d108e9da843aa4e600f317ef4eba920a0b0982b2664363d14de47d775cbb68981cdb972f0d75cf4500cd27ee3c823b36bdf4365818b9932de7947f6eaf6e4989e08482d1f342b4530010f7665a575daf03f3668ddc5fefc7e8cf61dc9fabe48ceea13758ea6fe09400b40e3c117c05cf097960952343afedcddfe22bd6f9bb9d8ecb1b48af7652d600a59ee96b98d352233f65d85bc85ef580a972ebef97eb0aff527f01cc82eab100a3503be89a95659e9617a03692d1d2a9e70517643e1e4427ead9f7cdd5531300128b4037b9fc89a3bdb691a85bbbb946a75e192ae531ff35c7ac7240a0c6dd00087e1cc38f4685130aa57f3f66b26dd47a5aba7bfbeb8e9defdc86276f18dc00db16c885ec4f6ae5d70166620591b814292b3a78a4b6ee81b064a665bcc39c001eb0c24c6998d160b52d4d2cc7c53ad01c39f449f2497a3e8b920a012c84cf005c76a92014994c4b34d622dbc755a49278512e06cec85188864a24f25e5cb000185053bbd85c19d13c2712b5dca843d946f9f6aa1c9ce88370b52c9f0a123d0028e2079b3282c35ee69738e9a98b444cb32216105377b2373d50a7e1b879cb003096faf438f67536b7f30f0cd94b346d995fb1671c1e5bcb5bde64f4f024b500c58a56151fce8b894d8c5fc14427fb93aa0558457215d7637907385eb9f99500a4b2a758c338de14d84c74943092cf4ca9fa9ef4b2c48e63d2918ba5c807b3007b4b486fa407b5826d8b8e86c3d7cdfc08b9502ffb258003cd3f90cd5ec307005e58903c5b58fda96b9c0b933afa4569e4d8bbc57cfeddce053d2c4a41f8260039bd5ee4618ebe2392e0818f72ac1295acaf06035994ea894ba89ccff7801300b575f6904eee6d9c94c05d4e333c1da68f79a54a920e5b9aacfcc432d7fbb00030795198c5a223f6d241eeea62f50edf357e06ae9ecc3c4086397498539db7005e0b1bf2d826d03d725789d28e04e4311207499812aab08502a13600bcf59c003234501b4621772b49295e0bcc354c3aa9aefc273291c6217941af2b862a2c000ab432d32d74b6adb4b2ebe614740c67716c48a0792a1c4afc36b1d328613600f572dd865fb3c541ae1ce56ab431edbf13a76b95c94ad91e7dc9a504577c4e00d93577a408db4fccd8135b7fd7718d194bd509d85c97dcb3a2c1f2b75ffa0700e32098cd36313176ad23465e906783700b371834df71064b9578530a3799ed006cad8102cd67821344aa3c8abdb64959aea8d42c703e516b050cb99d041d2500353438f628cb6ab89c218a2e7ff4281484f3e7f5977fe348b137c21dc7534e00f3f4fb0561b29c3f2fa74a565ad89ff146243dbae5b78eabd8ee36eab719b200a7a1b0824e18f143d3e3c79ad3715665bb26d35ca609206e6b02fe38dff7d400aaf104dc4c94ab1fc6b2766275266060a9ba610cf66d1dd20fa01898860deb00f03baefda7be5c24279c5c7b6f5b0fdba54a71111fb069c4aa5cf1d82bc27d009fff62fbb7a1acbeb2d4a05a4d27b758e7a0a8d3d40d8287b16e24a50536a800ede8456beb2d5df1fc14c38f4bf26f5adc45204b91413cb8f46ec54942b6bc007ee7f35af8e62544079472b7f67e1cb3f6d14196a437609d6f136d77db2edb00762e56f115a8ffc80cb812304ef94c8b802a124ddc79b129f2f3ece6128a810062df187870bf48b6f607b7d9ceb6cfc417bb35855542d95345bb9d35ff929000d3ac09150ddf2dc608ab3b500a9d69017a160d9b9176616508f68cce35859900beb9264fb55c6d22ab6d5763581559c8cde7df7479ccf59d434a37f2a788870056a5d869c617847d406042ec987a779bae20cb8a399dfbf760233ed158707e0049be66d400f071a9eed398fd9654089d7408d927a18b8539ac852ebbe5ab97007ed45e2f7692e234d30b6f1186ac7ccab8a5a766b68958a01e4f4866d2e09300d23bf6df0c1300af697b1cec00fd5547596a2ccede73d00eaf1d76e7977d5e0057286286078c70324c99b4527d00d03391bacc114373c2124bcf84882d33e300fe41b438021babf74486d0675fb3b8dd3d04d810b8b86109a1f9ff830d1f5b00f4aded11f59d9322bdec7c0f845921b5644e44b82f30519b434b97bf6749c00021f637daa304d0cd1ee8b8b477c1b0484d434584ca3b30e488226a84a4f78000a0315fe4c25a344c47f11d7f5da28057994d44014008abcbe5dd3bc1de9f260042ce5305db0d73caf2c8ff7b5fa98491a7d21bb592d2a7d1bcafa4595337c700dbcf25fbd1363e2b236c6c962268f09f8243103fbf0064b9491123813662ae00a579c099b449b266f2a02409452555b73df7398b82b32d01cb48daba7dade000846bc9f812e9db26ef1e30606d1ca71c43552d06795821b819f04c6fdd008a0060dc2a0e18e301ae0d0ff66c3147789af92ed3f0433f3410e187469abb706300b0b32f6e9891e658a65f623c3114a54f9323d8fe740bed2d8a73a11ced061300e46a8351b6193a9f8221fccc9c44660dee79d790a1c833dd37d4fc05f40e3800c2a161963bfd95cc965263da8eda3dddc0320c93e1a460e9e229dad1a7189b004a11239a39d308cad0164fe429ab1c05c76b082911d99807e23b9eec540daf00a164a448994988ec9e7190f6e142460bb57b0e87a619394c9760ed70edb93a00ea88f0e0653f0087805bd1b34cfef623db6ff11680305068e598c3d25c651a00af4710e2e709f0910e22a5daeaf00e844f20430fa2a22bf4f06ae470f4750200c5d07d95d56e5a882a36524007f5a7640762bbf0730f064fe23feb11a9d8e8005237aa90c66bbac433bf653c13a49e144d9f497d83584fbcb4573d13516b38001bb2cf68922895a1da1f2244ddabdff9da8ad612983167b5a534e560f6063200a5decf708efa543d3587eb396f804c0c421aa180d2010b59573c8da7a3c98d0038c805eeba93935b61099449c3d54725c980d484d710a1f0086d1c0635f3ea00203897d7f3f8e008e66139e528c239880c26e2980f042647a36da9e507224200573c6cc5e34b6f9514449da56cd17dc79ba5d2fa5d8cbe86efbf81a31dca5e00798578bf9aa31e537dd0403511024f759700e6bd6c8adeadeb0c932164a6ff0061b239bf5fec58d8f8f95e92bece05e517d973a278beea2c6b7c603762e89b00477099301d82af5d6183271d02dcd964f3fe0ed8baccc6fd8bb2cc75e6ee97003d90a690f506963dbade0f44abb6a98ddcd04c09be368108ab92904e3203a90094758e42ae22bd8e67721e6a6c43a0ecd7baa7e2d29c9bfe71adba4882ab3f00eefe16ef6407ee5ee9b380c47bf01a0b18bc792ff9e9f066654650a005be7300efe23e47e181b0da05cec2770fb13253b6c98e770899374525162b2cc1cc0f00ea4131033604ca71f361fb93c5c8d3527ef1a9ccca8de7887e0e1d38a26afc00d32c186d1e7b94eee8c7998a4e1402f35eb81c27b5aef18014df22af3080f300ac498dc83bf68009b65159c20e5babbea774f075ab4c769e8eeffdfa10547a002dd517f6a174db7566104337721e6368f2d58e11ebb186d53f0b841e307d32006581372c318e134f6c7b57bab179c5202f82692de3a8e1e984a970b01a2e78002b728a7f68fca5ef939b0a38760e710ea6d1263281b542ba18f5222212f86d009ef1b8ab59be4ab4e83591443662f6b3dd22568e79feccf9ca2016ee890eb900fc86f905ce51d2d28b019aa3703c9fbccafaa22cb9457a1f0c6f52eadf6fc8001834fd752b6e29ba9d409a85288d8435e769cdf54f74c6b3f6cf6758ada32f00f12a6e7be5ade39a72f0b4f22155ce8caa0ceb4dac4a6c9c12129ad6e8044f00e8ffcae6b6cdb06cf29d637ff225d75d950b78e5852cc1f794c1081b7c748c00d229127e5d47100e978c0ff1b6592b29b02bbcd2015067192a1ef6378c646d000492df1ab25bb65745f07b5f264a97164137fa888634d606339df8b9c2218b00e26770ff8676eda06679a77435ff0f0e34d36512d6b87327ae7c2a595e097a0090176c2014a488613529b4a382efa92a50996b9f5eb0d4b9ac16f4ba59a83900ab4dba4a04925a7e66688b546b7e76c7f5d26a933e1a5e43c6083866a4dbc1001ed21d274fd21fd9df417178fd03b20e8c7dd105c2a6dda3e00d393ee1701700ac8a2be3a0800997a610ff438b19b7bc2202d805c8427b62fc69dee2b9d43b00d03c5ae5a1f1eaad820129732a9049b78d56fcee09178915df4930a809ba6c00a4dee94cf68ce76a02e3e79e9791a95b3169e9106e31ec4a7bd74395d5b6990060b672c53dcf1428d81ce931b98436be0907b9a5adedafe6dc4de8115f8dbf00dfa2ee129548be7b1dcced04da1329294bad2aa59e821970e9f1d9c5d5567c0059f9b898c28ce7fe9ad147310fb5cae29fc3fa533b4714b8e71d043e428da300a919dbaa9be368f62794deb16574ca6cd3cd668b28be373e5f48dd1ee1be23000d357e69bd73123e6c97382d333f361f03d8f65ae450644e739dc44ea751bd003d92cc62ec8db9e03c8005c384c60403ae6e450bfa24138be62a4554db7bf500dab0d06441daac737b1c72b7a385f1143c4394cb102f201b420279c47e180d00ca1f3ca164ea914ed4243cc6ceb8bd890f0810c41d927e1666dbd5ff8fdef60005b64c1390057ea898156cb78c3a2a3cd8a711e001346e57ce793dc950e93900311d9d4c387df814955e3a7abde8a47fa8f8aea1f907b9f06e905e03c52283005b79b09f6e184998b8815fc83e01edc2bf42097e080d8a069d0480787bdee000dc2a2706d4255483935b36e0823548ce18fc36282a86c239889c7685efc405008fe16c1d0ba964cc694ffcdd11be2929774d7003f9f5e971fdffb0cf30f68d0067c278e57b53f27a978d2339968523944166d666f363640a92edcb26f92a2a00f46c8cfe8412dc82c3fb3f07015598af2d263dab843195efc26508f6052c8500133e3709ac6e1218376effba5c67f935abc320c7e0838f2b92e5ecd690652c00330199ddad76ad875511f361df604f55c5f12bcac765a86be4c5efd413f2e4001715e20056a72e0c33149fe2d68ffcf9097936e073417a6aec0a258705312b00dc953d274d1a6b966f69907dafc477801226bbd7c234fad748888bf88ef12a00b4b48e310266e8dab4a56b3ad1079d0c0b97d1d7072c6f8828a3a1767ada0900b2e944d333b30a1017d9568526fd64289a312b8ee05340284798210fb1633800c55d25b449665f92602fab829090fae9143aa37af1fd868afc24b9d2e1e9b3005461bc133b38ec70e6d73f5a42e67dfa7748a3a59e57631352ad56ce1688a600dd3e00b02469d058ff19350d68db1d65d407adaddf0cdd0b5c5dd677c2335e00043b2403bd561a79035b6c33281733b5de95deb4a14fc1986fcae91f90664600a10ae4c6628ccf2a23c55f3d6cacc64d0637073faac5dc03d533949df47a2800e1f9f8907417e75ba2db9c3dd20413ba6a85e40008659869b5adcfe353be5400a7cdc747a01a14202ff9d5007f9e0624f2a226894726f6190603f92568d4be000c32e4c975a3eaa2b6624f2bae88991e27f4a2cb82b7f8178c9ca69b28b3a0005e9f2ee9ada6fbbf514fc63befc66cc84e0f3588a3f5f6dece7dbbad74d1f20048b9ad22f07b4a65deaf6d6a2ad74c1a0cca1f333e41cf89e6fe48cf8ef3f60018d1c6f84b8a0a33343ed75b7bdf0d31fbee69367e8ff339c10e99df93db0700fa8e9aca8b908262041fc16ec66100d94a4e88e9a3ee55465d7f7e81e2bfae00adc6f890ff85e34beab67aa734363ab7af4a16d8cf09c5437fda18614e0009001b4c9ba67725b89a9048f4bc2878521f9f9673752dbcb35d2ec8d8b281d75e00966f03b8b89c1f47ab249b9065731bdba41e558587b94f130d2b7b17446eea006ff0e52050f2f85ecf228494a1d21d0da60d15a537e55976688afcf503e0f1001569647be0517bc91185e52880336ab9c157fedaf72bd2642c3609179832e600ecb0d6695cc74e74e53a73ac5d37ee417e8026688b1a2329e20f511dbd03e2003a2dd01dfad9e0f58e305bc3b66138213213c1de8be6c39b363ad94887b63c00e79eb3ae4ca6ca5b13c669778bf72d4b8d77f1b8c803475c4ee0e8d62ae3fd0065fc37398f543dce117a143dddbd3607a2a7e50ca09ac1f38fa093ac1ff8cd00238ef44dfa9356d830a98c0532dde32aea69e475b690e1074836741a6a44bd00af743b7baa54fb09b380e58cd14cb4387a6ae47123dd6dca71678386b05e9e001b5d140dc4793b06a14e841ed6f6c5bec36f4beaec830bf4deb458bb9a317a006d5e281773b941af96e28a7ecc200d1f84fdf4aa188c85b7e00db08c7a8152001c4c72216eb0ecda5c76f9587c25e2d8168fd8be1d04c0588ecd1987d7f33d008594bf26e64a51776c1ce6986b6ada1b351a929a8dde27e4225933074a8a7100f353b40a5359208c352b9b800938e3b5b0cccca2cb327d6165bbbfe2de3471004319f3381238cb52aa781ad2077679650c5e3503e02ad763d68a3e478cc409000dd00cb6f222dd509d6cdb8018f5aee45786f0e2368fd94876ff128c91928000ab4295b65afc15f0ac640b9effa6c9eae91a6f54dd16f19d0030366df5c77e008bca35d00ebf2bce7c9f1daf269319a036491a69b1e8f6210ab0d5e7a8a33f0041c1412d23f8b4198cfd6b06f2981c6cb4dcb9cf60b5196da1ab5296e0c1f100172466c07aa71db35606261a9ae2e5f80d8c7ebecb604259a061dbfa014458003f1ec605586bbd2129ffd38ee02221a36dc018cca4d43c35c2e602a53e733a0071ca38c2acbc69464992051e459ffca7ef30695c9d2fb189db55b00156ef9100bb0c8fe731614d6db9c81fbfe72db236659adb2f1e31cec0a388a90a72d69d007ed98a07b196b262f1e059e37cd6614a111533202df0035b5270385b41c1cd00df773a397f6f700558b5823aa396b47ecc15ff1068ddff16f640c577d4bdf0001d8fb1d1852e6cfa0aea9deb39cd04811bda18227f0cc60c435649db2987eb0004ef93f3bafb68fb745b0dee48bb3e7149c0c762ccf698e8241b91c874ce2300aabd7c6ef86abd6ef5a8f16a5ab80c0d7587fd51a20a9c44e3ec886f02ef72000a96589157c907545cfbeed375e8a8369b45b95fadc0513d83fd6872b318c300f8b6eda17ea714a9b387dc634fb3bd00f38d39df38a9261a40afcb61b1c987005fc925c771e16aabecb273691185187918aa333000af77d7ce31190901df9a00432add0558f2222abeccbaaa51d2e79723a71d2827305e34841933a0b6622200756590790107c77b2fa8461afdc6e5f6e05a71316a812d4c4ca2a79e4ad8f000c6792bc89c8cd61945ebdec6bcf93eb46b2c23913c034594d3e1b374e703e8009f20a4345b7525cfaa259e73240dcb1dd1c0d0b04294c3f5822b65a253514f0008740e5c71087305be5528e28be505a1e6188f5ce04ee46fdf28160745b1da00750f8d85ce457d9f31248eb257f425fe95a82a7deddd90b1537c0be8387515006aaa0b8ca0ff5e72c5f4a73c537c063c901933a0d4355ed62674191c9a111a0003c34a42ba20c021e02f64b09316a59f3368a51b50c5bc6f67366c424d64b600075ac068597a93e9c5ef74f5283b3d763b53458cf0f4205c6d80918d03dbd500901707599c8df90d91b76f727b76b229c2c4263cb20aaa6acd2326ab9dc44f0033f6835270aed69b47bf050a75c43dc8ce4ae01ecbfdf8a241dee9557065a5001ec80a794e6fdc5228e86ea6966662f49be4c50fd82fc06f48f6bffeb5407800b538937085420a8bc2812bcbf88e09e3ca2ca338bbadf02cab6b71cb5c21ec00b771229e6fba96cd1c27f6d07eb5acf80e1d66b7e7ac292553a6f91065e74900d9d432c0d848711eb5d7e4af5f18e7aff1eab4fca34f4f3efc0643c602e175000a03e489db36c9f96b5d7bc5394b2c819296cf5cb5e04e9110fad552ec73af00b28c8a98cb6f18241e475d7fa0d61a626dfe53906c50973813740b0d2b73c500729be5c2ef5961a045e4e9b29b057ce3e6e3cff665e0aa09cf8079a7205ddb00406e712354c3be00b3173cceec926b108fa6d1bb2a2d046feba7b65a9095f6007203cebf9e8b302a7e97af419d028481167f96e7b5f75f6f20d18f8adf58e5008e6ba631a250add6f5e048b91057ceda0427e1adf1922e1e18df4361ff2323008797aa5978363ec4c29276e20d1decd2433e8a2a21b75eb4b10cc318c57cea0055f04145717895ea68ef3ac1d775613b80a3b12276f2a6dfe398d0b22b349f00cf1f09a5206777c646b7bb71db3afad0ca59fbb7650e07cf5df9a08e39fd7d00bdf8b0d9f78d2bec948df3231cc3b1e01a6c531a2e2f4d3085e25a569c9197000bc6de364114d6f7ae1a83d1b4d99a5cfd7e8c74a734322c1b0cdf6706dfaf003e2ec4f750cf3a8183874f404f21413940086503f5506f8f23efb8c498e19b003332903dbdd4d73d413dab1aebdcf18496859e38e83eaae47e26b79d8db93600ce93bab8f3610cc9bde084ccf5f6e60deb3de9304e863d28bf3ad30c8cd079007dd7f57767596bb7de935cabb7672aa14c3f8b1b8fc9c4477ffd8e4fdc7a1300ef8530db21e44ca331f2bbce7de871b7493d264852e5ea9637c1054861061600c06130be4f1e85f3a12ab634ab4ef1f2818b2003e81d56e5964a9204898fa3000135e06172c55dba67e92eae330ffc059c9d4a8f41de0f50aa81105aedb8ae00f937e46628b5fad77af3a8540c72bb95005afd6dcaedeb36c936e1c65eab7e00c3f88d64fc780512e55fbb41251af39241c9effb26549b2fe71c6ccb1313090010bf79cabc0c4f03beb979f949754ba3cd99d6316c0a2bbce3263b571908320046bad3cfca0542aa127722a93e6b1400ab7d1b8eed8a4891a17e735a3828c70053d952d0091f98f003f7a3e2ad0d75064e12e0b054406254725e9e1db3d014000288684768fa63dd02575e67dec7e930e00c625a2706d87811746e4a32577100adcc2ed800342ee5531085f859ddfcdcdf24b7b902f23dabd87a506fe943d400d8314705f36f4241b3c66ed55fedca235430708bece6189d56a4779533bae000d5f0d28c836ccd738b2c51dff3483acc0002c66ecaa28e7c7856f321c43a2f002f149a9b78c96342a8c9b0e6145105ce072caa41355175ed744cd9003fe420006d45c3e1d1e47bb81d8ac0eba622a058778c4c4a68f8cb183bb0e763b0223f0049834dec02c21ba97c56fc93af64f42b1873d3731fdc416ba086238296c36f00466020a6dd26e893de97586f6346297dbd270c81adfc99a229c561b1f7096e006005a50245ffc7d54cf6f75c3165b0d8667560306f61e5cd7796531fd6048e001d6eb19000c79eb21de829dd299d0225d0175473459f31b2df32bdbb4d454100e3e7f58969133745122476183b3653d192de1be1cb0bd5b689077cb42876a500f45911878b88abd31d1623ffaffc33105ad365ab15bcc3d94bc885c66baa9f00307bde88de529915a0a285a43c76d10c2ace2d1757b4423d0a8e1b2dd36bdb0090771a74b218b4bb2f8fe6d2533ee63a033e2050ff8d6dbb8eb194ac874c38008f690f22a220df531e3117c75218d37e9cd15edef312d244f74041ee7864d6004716d2aaf7cf06b86cf4a26379e2c55442c36b3df58366bf9ece0c52bd033b00115d2e4c202c8ecaf4488503400aad198ffdd711f342e7e7e64eec937257b7001d21da1961dfecbe531b026feef76e93192f53137dedf436a5643a63987cc200ef3994922c740176cd87a01e830827c1aaac3f36c3986af39459daed41985c00f2acef627f214a53192bb4a41131ff203d460ac7831cfefdac3f71e243d23c00d3cc49cd36222ca614fc88948b4269158bac7aa15ff1bc17e08fa211cb01400091f0183d28572dcf06800ab2832d6437e4fabdf847b99775b4da2cf7783a71008dc144f2c2b52a44d32258d7c0ed69b2510c448fb7af187e7fca77d47b008400d8831cd07c08bf48418ae4016505ee0d7abec7917ac2e61f2c0b1fa6008fd500332bb12b899fd53f0d792b65b14da3d1e2d4bda892ff9ed1b5963439517c2b005c9abee5362107e6c65b26474d3c4d0ab7f73df7fb2075257f4eae71d13de000aaa61db916aa486169df59b145d1d084b1159c89870c9553b43437a6b4b29800775900c3df16acd2b8b0270f9fb95187dea8a911d05ddf83ddd2f64b8fadad00d51c833e3db6eda95e26bc52fc108b42786f1b9357ae2bcd256a86056856ba003f7efaa2c28f3b87b581993ab64d3eef732a542980288c1fe3ee77f4e379ce003a41a3f7f78afc8ef22a9f18d514aefc628d2c8f9c244aaa6dad79524730bf007d42fc1c160e5bbf876ec2c9d96a4ed02dcbf79a04c72e853a2405a907f07700f5267d2b97ccf09e1f80d1a02799672ee493c9f0e703e262f661552239324a0061b548de115c24794a27b21507670266dc173352a5c9aad48875ca7dc2b96d0096ae91256c0e5a802d09ef4e9ff4661606edd614a204a27beee4c66b5112d60018d73acc9e2f0cb959787ae5f352401286d01d408e762ab46b4204e41ddbdc005751a059b5c7264f793cc0cb08938cc2ce80592afa90047d35dd89018c2eb000a3fe57cf7e9931bbff87c22c07c82575290f23ed72d7c59261b45693da5f17006b0a5c406988025757d2966731bb98b49fc3012f6d5941496d15202773329100e0425ed91805b80349a60c64c8dff8e13b89265eeb39b1241ebd66cada918d004203cea8d79b93596740a4ca2b586d3eb347fe771e554336a8da16a5f8bb9e000469c634d376f455b0172350371051c509364f9abce7d5c8079ab26316012b0014be38748fa244c4b223634941be03e64144b958eefaba5e76fcc0bf988b9b00af29ff7fa29f93845112690a6e6f7724ff64253b938c1bad489d2987657e0b00212ffadc3a9a65e31923b8df14a22f65f39d782002375397e63d516352deee00c645bc8cfef161b522c3531f4d975c881b182f825b7d0bf7e5f49a62e6ec9200523d9f80f07d9bad5a72aaac57cbb5f81f0f10b81a64cc36ea676ed940a4b40082d661239b0885e9ed09924f5c22a4e5a63a1acc2b81c08dbef0ecd435edd800045b3d7b9c3336a672716dbf2d2b3dc0b9fff933c9b1b682549d556a9cfe8100de60e322f35866cff6708c7826a9131efe1d0fd7c07ad70f9dca5e31a5567e009ac050d0ebac2d6d46cc8f8a7f2f63be02fd7d000efb0180a4533b1460d8d80014c98a46d84a33af535bfae09654ab7c84ffcba76478ab1a6d5cc221f80961008bf3052926301ae842faff93c80c6f6ecca9265224e1111272dafc04e683e400031ffa5a6fb9f048bce7b1ba9c2b75ada00fc123f7cad0fba01f74dda1651d00977255f59b6490bc65f6100956c7e89ccfba4846cc124cc69b74609039f53400792f75f6407fb94e5b1fad2ae661e434ee3ad87f7b5ada9e0f86059249705200dc0731a7d12fc0b1d9ac0247e384958c9a68fcb274c70584964b2ad36249bc00272b77e370d858ecd1c35ab16e78a34e0d9ae5b86be1f1059f296552561c17002a1daaa6861af1ecb17ff05ae6176bb3966a6db9c0f747a7e87a8a3d94d1a300bb0c128a3dd80588a2da0efaed956772cbb1836fc77d7950cd45a11706403c0039ca6a70fd553c71e4e31ee823ad88727688da6da2a3a5c029ec8287e16c6400f98aa291835fb0f193347354ec899629fd6b09d3fa77a2e67d3675066bf65c0039836026228bea1ad2a14a51d7b98d67b9edbc8c76276ad64101012ac312a600626a2611dd6763f279f49ed7762c95eeb5aff34e5ac20e9e4c818c6dc2a3d60023180f1b0b7a681354942ad03e4646397d225e76f4096df1576c3d0a2de8720056314d170478104f578269950d054deb21b596f653173c8a3f25087967f150007fcae475e68e6701a68a2b2608e30e757e2b8f5360e72cbf21203eef31a61900d2bf99a912262b8ee3b71a175a062d042ce89faf932192003138424894d28f005b32e3a491d9f43626fd5ed859446c4dabc168e50a975a89736f9428b376d70048d1ddbe6f28f313c7127f69b575e0f9a77d3a92fef0b745804ee69bed36fe00563633823d768446b011eddbec22b8e16535600a737c8ad87c2a24e70e158c00ec1a2c89e8cd00bf68d4cd250c1cb0f9a70a5615ce7da1140403f7ad8dbfdb00789b0bf6e563a6fd45668891465851afcc9b57c929aa484ce6fcc562b665d4007f1770014a5018fa9354b44d04c5154643b43050ea07d531f873aafb66e2bb00f409c0b9e7dbaa14c1a3ced745b09db97fbee0894b7649aaed6bc855ff2445008e5ee8b7b0edc2896e84e57f00ce538a39edc463850f8907f3e866df8ca08e00013f2db0708ed7f0fd0e86d81a9623c33866505ecd10f4fac5356e26a1be64004070bcd4f9bc4602a75c116876029fe5bbb35ea55097359d17348085f9fab700f2dd9b72459accc4b45cc6b9d7ef1d26eb3b50ddcf8701ae21ef91e7a5b6aa001d417a8937898d5b1da3ed378f4f0188ed5e13d6516e957ee254408bf33f270081a0f2b0abd799946edabc30832b9939c49e091836c37dbd142a146bc5da87001aa88b11b92ba87f9185d4b09d84cc2b10d2142a1d6102cede65a6fafe6b9300b59b2f3a03d1df4f88fd01f510661b5f4603093b410bc2c3a4990b59ec6ae7002e84136048e21d7d3fdf9c8ccea7d7f5297345009a4eea90416173d0dece3600c5edfdfdcf93f1192491dcad0ef6fa14cf4872318a5b450e51789f2667cb5500a70ad04919c10a343b6ebb2e93cb425db7fcdefcff04171bf9edff12f0fed5005b83ff5e0c8680f49731671e8b7adc7345ab4aebc1fe853b465cdae4b1d2b5002f78344191f1cd0b8449b737d12b57846a19b47c61af0a3a8119b568ca17f000ea7905be4d21e24e1a18e4a48d472dda5bef70ee4cca613f5367e9a21c9ee6009919038951ef79fd47455457fe83c09d061384ba6c110a1b7f89bc332fa7aa00b67955a2c89dcc9a2a84c9cce882b930c0f4ebee803c2aeb298c7f15352a170091462813b4d02f63a61562738eccf73d9744dad94edc3f4b24060e6c798af60044cba870bda57df7267f33eea61b79be07ac5731468feea2009316d9ba815d002ef2abe61fdc133ef1adabfc338f277dca9f8d4387e6fe3d4eb742cf96279e0089fb8dcf2684b9b63978255e376d47fd1d0da631d7a73754f83a8d21516caf00b7102f052622ce430a90c1e85727a8358b9c22ae82929622ecd3edff19e3d50096eb5769b77d610fa3c1b0a90ab8df6a31787d07ed284702b374c5ad11483800a3d070c88f2176cfe46db46d5b0004f778b72bdf0eb48dab694b4c13246a7f0061747b72e109b18deebfe4912f6775c929cc7ddf94f4ee01554c94985f171800fa17a3e1e897baf6563b5bd4377b3b098ae3ba9774c85290a6dd7ff296ec4b00204e5a4c2f0f069a07195c364f78d6d510a9d72b773d5f4cfa22e78b62d6c6006b3038c320395494d7167faaf92779f0d53fe6d43a9e44b5767eed9f5724e80041974241200914b35b7536c5a6ec13383157b6770f2b35e251e4d836fd1c8100a37f2878f2a7c4be7ac791479a22ed2791db0e20e89c39db54f0ff8d6a59a100b221ee15396dd46216807c6092eab8af3086ed2b64e38093dc3fc495fdf1df00ea547488d009b66e9e55f29dbb44a7b5de0c393cdca8647bce199748753925009df153a1765e929cb6611084cf2a5302bd5380b1824788a0dfd7ad8da9e51500e2d3ea0773bf2bf85913111a5428576954f7fdad06e3dd89c0992e6bd142670090a622576f70f745f49e815ab5cdb519c415b25fa9c9e538f8c56f08144f4c00c59fc97445df9b89b677e067509701dd6018b692251e7e665d42df34938b0300d44c86ea3638f9d74a7dd134d861d15a0edfa6659c1253fd272137030c4ed70002811a3a14e228683fae86ed3d120163c95a31aba36c58febd50e9eb665af900ce3df9a18c62ac15f17fdcbdad25fb5d14476b7af09f2bb877d5a36cb3822100c8b014e5622e0a13906f888e317a1f0f0db55e2df0b7192ca64d04148e853a00ef460f1a40ac89987cdcb102c261268a4789cafa4797f6e3b3d935c8646d26004e4b451607b1227753818749a90a8a61ac950cfc2ccb2c6e8cc7d9aa725f2c00fca4cc6da63fc48ae1f77d3e39700889d5959cef4b966ea06606814b47a0b9008508f05a54fa0005790a78d91cf71560ad41397bb794d488f98394554774770055f58952301f7d7772313a5381aba8be5ce2c53b99cc853bba913b1be6541400ea9e11d17e5f9e0311ca78dcc2fa020774a3da275e0a8b9e0d381c64395a1b007c03b636636148aaace8c65a972ccdb5166c2c9fec73e19b925e1f523ccbf0003969f37f22405fed4c072c89acdc70da4592d3c07315d0223ca3fe506dfc9c00264988082893ccdbf2ad324dd87f8373ae7e6ab0c09a5ca7e51efc8cfb7419009b246e5071dcca4a63141e52a448f4e1ee7eb00c75fded6f3becb6ba48bba4006a0f9b3416f700c144b2165bc86249d7b423cf47bd875cc46d4bd6ec49f6b2001fda35e1a08475ee5e77f49a77498b506998af0ae0720aba68542885917a9f0086a1a5ad93a1efc629bfc7d272193e415cde4cd919d90b3261571ee665821e003f5db1bc571a8a779f76a0d47dee445b5277367a68b5d1396f4be02509924900796d5bb1f861db43c5a1432867d6f1608904dfdbd137959b0371053071380d008aa13d78924ffbc0f2639b9bca33eaa020b669351fc3b47bf527c9b385e38e00180bd016362662bc07f4f32b0144161710c3255257c6cbee03fdc5f8b7894600456a26a7cfbb1c08df66f3646630f96dbd6b22d9ed4cd2b046d00d2a0a46960096d6051a2bd7ea26cfa5378739ad441aceb22fbe3f67950185ff0daaa208740058e5972060bc46a5ab8ad7560f0c33b79d0d797e846ac009fd1db3fd6edf5f00e388e5fe4d0e9c4ca0a73fb52dc27fd29eff6909274ee454ae22738df08f58008ec7b509e49b1c4948eebce7c32f662fd3bcc9b934bd0c806e20ada5a39cf900118351ecb30a32bb9677dfc2deb7f0a8f6bf9ea0827babdd406246fec10017006dc07a61c355589c4e6f37f90acd50b6629b21d14899856867a00b670401e300ddb5c6761735124355e5a4d98ef1df0223394218ff9791b422393240afcbcb006fb5d72ce5c968aebfcfbc87d99762e8544e5eb326e2df7bbeadc515ccc25b00d138efe4f7583cdb8c5fdc26e4fe79ba9821ae1e990b8fb0b4275f59bcc6bc00c1f930f0e93fdf3ef531dac92b4abc66e4b24c6b7a98c12586bcb1954f922d00183223b3d1cf095cdcedfa4d972d8c962b20b31f85fddaa4db732b1d145324001b888d5d300c63fe3a5ec39be8cadc46ed6ab1064459e775f3c275a5cd66f000ce62d1cf8dc80ca14eafd36306891aacb81fe87bbed9980f10b137067bca1700d92fcf324083614d4de20e68569f1b262fcee97d7a9f1324a52bde365e7083000775a835c6d43d1c86aebe8a399612ae559c4ef03c0078baff0a165c56edce008e9a6a83187072d5e3ce6d534eb1f14d123554ec3ed9a1f5f6bde89db695c50051a5b58226779558aa80f816bb4e38cddbb3ab715cc8049ff2d3c47885877a00a8766fb048820f196334e8733696b964ff9cf513b04ba3ca97defcbb601ff700e0f958dadc855536fac42ad303af0b6837df54e4ce7420fba2c7ae48128a7a005d54a45c6fd755c20f4617e839ca75e95d6a3aadb66d5dd9b8dad59c10e4fb00787e82527d29aa95b6d70d59b5aa36864a3e2c0d0f9c3267f594560eeb2f3900ac2c704c932994525095079b45a6ad36635452457ef1bf52b388dce950cf3800360fa80eb9dcfe5bd1514cf909517d3273277436ae8e3b493e3791b6eb9a7c0079c5d83362c98296b3ec9ac729b47f97998d023e6ff35661a1a4a1365e5e4900a2728ca782e71a7d7201d036d5cba6834107f4f548ff0810124a1dd30d6ac700f553fd1e2145f9453650ba759b0d21290d3da480fab3168f78a16ff3215005001f65819ddd6699754291203f7087d55b2ed51800be14194473622c79a1a46c00bc0a09e51ea0c841936953b3e2149720332c4f8418636885c7ecab4de904e000bd3bd2a71f94b46cdce9963d7217993b6c96ffb6acfa481e1671a709789ac0006e4ee77bb6a72c05aacae744317326767a5ac4dcd82b4848814d91a465150200c020db26263f4848f5c906e1ec8ccd7d970e95d21cda8532fcd815c09208c60089df87a85489916cde74694e0a57a2c125848d888f1dc130951a06c9396a2800bcee2d53d8fcb1c260d423c7a5def5bc43afddcef77a96d6ccd296c4e236a500c50281c6df8f425bfca938cda15b2fea9cd7f62f40828eff38ad89653d9dd000af7143a8817775399e6100c4aae489ecd30c51faf67ca3a8f986fcef63990700049e1b5c7ebfd2b781ee0fae9abca1490fd15d7f5698f10336020ba0c1eb12006b821704eda077af2e4fa0c7c1d4773c7d78a4e1dd4948a79328a21ec025ff00a6735754413b92c808d40c2eef7c7cfd4379d03d2577d355cb18fcb64f5f160077ecf22c97d9bb5ea60ecffbf1e51ea9cde7d16f4aacd5b6ed7086fb421804005bbce947febb06ea6b3762a2388f13ca0827b18c55b9c54f8d5d996c0320100059f15816117ea5a08d1bd94f6902eca00b501d58c9e80d4528a11e8c2bbf3b00151e97bbbb14522ac4fb377c1993555ba7367bdb195786517ed2a6987f0b2f0076e6b79325a3fb111cf21f874971a5063d7ce079e081b00febcd2cc3a19e6e00ce9f620fde46330c2011fa98a48ab0d7e2c55f9a3af99c89b4b3f154e397b8007a4d6724e3695e98c35722b1455b36074c94c10f322cf57beed2af83f24b7600b3be91f1fde397e7b00e9b21ad97a909a233d89782946c2fd4a46d34e1be3100692d5835e7701b1dcecdc766f61c98ba8fde351d88c8683c6695961b4bfc6a00d7ed1154c3ae7099fea02a277673083c3a93755f7073265f5d44c29cb7ebd9008f2c7918cc4245eac71ac261cf8c922d0bf9e527e3fb33d3226f0dd6622f5900e98ccaefffdb32bbea7406cdc2b648521f314af0039a04292661ff3850b06200554c06d050dbf39e82f5f0d74ab391f990966262424fc03860b645258e4ca300368a6950623d5c4a4982cc37a575cca7b659ddc1ddb5da87a6b2611117393100f9e880fc31081be33173935fc9b36ad70f51b0ff9e9df0a11597058863dc0c00561edec232a12bcf6486f773e22e4459f18df70d984963472b42bc37e870cb002c8e0e140002aed0bd32fbb663a7928c8e1fb1f334a957122c71bf27ed3fb9008eeb6ff4155c668cb0615ae988b7cfdc26641237d319d940519832913d19640078f9e1591d245f8e53fe3ee4f3816fb5b3b476c08cb8f4f3746789ef286b5a0091a927a35e512dd363659e385cb681ffa8240a8c8eee117e7eba88d8126026004ce3e2d8e82dcb905e129d26235c64797176e4c5f9e1a77153c0bcfc3d644b006823e0483366295bd04fd48fd86ad46e67ae3386ecdf3f24b1a28d22089f600030c9628e347be987762aff1a517a7c202518b40b35f4fada366d5f81adbcae005a85e7476f1b802cf5802941865ee51ca96f8e5f2ed852bfd34761153adaa3005256963c704be9aa53d5467a0cbb77e784d8d1252dd76cef550bbd4ecece97002dbbaa6d13c8a99ae8be91230a7911e90c283523775a98d58c67af0206c16400eef3f75b39fcda2bc4d4cd9884dfed57529c3f1a2da04212a3c0401dee93fb00966e896eb44e4a0421d4601d5c05e8e8b2086f2395377b2ac88b1824e8be7600ee8002981f718be6889e5e7c7a8a920fad9dacb5de460c8dc16ff5004a147b0034ca5696b13fd7a334cc98749d1d7fd6791260c3bfe8569b2c20fa45645696008390bfc388b84284d663918e8cb39d98a8116d85c0b7db26163835567e7d2600fd07e406400d2e311f51c53f03e53c41880f43d2c0836bcc0592e620c4e922002a77667b2e26064f56a30f5207ee5a45387856a2b9e3d2259de43f8134696200d810e2cee3d67a8ad1e675a6beb4b9d38bf9499cddd62540862d81ccd23d5300f6c22fb4a3be8054b0bf7de3efffef6845eb3dc58a6094053cc380269c4ed500a62bd67789fc3a7c16be32d99597dc3cd40b9a36c5a6f4e54ad9299391a6210092d1dac84d115d7f2246ee87db72eb35d2283e4652f30aa825ab60c8352806004a88adcc0543836bce02d3698ee0d8e972c1f7ea8b26782487e6ba5f630c59004668f80ccb4c80a1d27e4a377b2d171e670c6bc7f07911f8604c16216bc82e006cbf14d79752a0f8c04ff18c840b2dc750f7ec2ce18ebb2d411ea87ba8cb4900c3dbd4d5e8d9c8b5197454c81fc0b040c4df41d7401a3074ce05ecea1bbd1500e82b50d7fc61c71fd8bd07856a272686b40cfec186b6f01d892127e3b99f690086105cd215f91bc5f0b4b8478348f1ea6859fa4c3bf711cbc10a224b729a14006d71c16f3466238eaa1d1d38da22414e7dabbe5c48063c9d6babf09a225c1500f39133f11dddb030b2e8e921a12049e357629f1bf632db342ef80b59ddd65d0051255f54bc391748f26b332d5c12b66a647978935b809fb6ec732d14652933002943947ceaa650dc283b0ece9c727d61177dfd5e982b3208c6d9e8c64dc65400e4f263acbfa82cc3d06cfda2b1a64b0bebd8252e3e734a311ff9c8cc055f84002489b5dd0c38f1a4203801ed5c8a189a8e26fec825bee5b20047ffc92684de00c0baf83d859674dc44721f868eb781da677af1d380be1b3cb64b49b0e1409d0044e91c5ba38728f682456f6cd03949861b3ef384355d0f0e70bc07bdefc6b8004ceaf62c8099343c7d57c00ea9bb4f75dc77a691d961df5b2dc7061b8c96dc000353e3e3508d50546fb2c50dd044a0b7c75b9488496a9f06f99ff86789b24300588e22a68261e607bc962c1e378da8690dd483b9e7be8eeb46ffb877d24f0b00e30b7c37166c8ea7f2578438ee4c1841200ca10b228fdbe8305307f0707e8b00297e3f5fe39c6b0b8d1aa2d6c6117c77c11085ac5abebd1af92ccd3fa1fa1a00bbcc8c59801536f54318cb4bab55f709278b754ddea2e994dea07d7637aaca00489d021ff4402260ac76b93314622c43ddb4705d57b5e470d763ee8cc36805004c50b8cd5403769e833ae3d990573c98585b3a9079dc561c1ee257969cf62500f582e1229abcd85c2465eafc800435b9cbae809788829ddbc8170d590bb0ea00f1894af5cca1d1194f160a0f57f893cbf5a33180ee82d732773ffc871d30d9000e121945c2806772c5a5dfde82090c6e11ea7f6d7b519fa89977b76d9b10ea00b369feba8d75c1efaf554dc5108b038506e63d3d54bf6a881f933d2dc49f8600c5c8c45cd2821de5b235b8f1ae9524dbe52db1312060f077ccc76a753ece2000292921804b00dbcc0a5c3051d318b59550bad9605b63ba850a4af9ca73665e00cb34f887688fe792f2a00d6ab7aa1781a201b3fcdda51a89f7c5d64db375c1008f6021e42fba419794b89b122da41881afcac2be17e15129ec3277570c75a800ab867e40ad03a019ad98220933b28dc7cde7339865d6fd97af8119afab8c3a006e8309e8b6dfddc0b8641b36339eb573087ce872a580a0c624356292bfc489002b44de43ed3e097be5d6967a759e716ad6eab4b18844fa6115f0367eb5470e0093752264d3eeeb3a9f3ad8b52e1e1e792fe852d3522ee814581f35bd5468d400bf23aa9f84fbdecb887436469fd20d60e89000761f4f9d0ae8a2736b58dbf700a3c94d73df45b12f5e992b3396526f995d3c3cde0a9f108969e9241cbc428200a9a4c8a8f38981ac821b7629d18da2a5a1a95cca2f1c853b62113b8bc3c87200758ea2c295878c59af442aa4004e9020b8d4f528db3d73c09333c4f6873c040092cbda53956090a9bdf619f4b557495fdb2ad7b4bf31d41772575dd487dfa6006232982c2c1ec3adfe282c4bca8bf584d8b10c1db28f821ad6415b2bab811500ec25ae509e7711ce6c8624b4aae0c7f092bb14c87a4d968898eb867463b82100b2106df767e3e474dcfd6d1b3b4e5d00f3c39f09828435b5e68ff0cb671df500626c1416c4f06da77ffa8bd27024cad3ef31c76742653577f99619bb630614001573292addf9299f041ff684b614ea4978d146913e7da1c3240b642d0e4417001206efd141fbe100d58cc709beea27b890a39cd864c196935b7f8c387c6d8a002b8632852a93dedcc9f8bb070706b06fd73d8a96ff90d224ad33c0c92f46bf006889f72b23a287d5765589baf65390e251bc2bb161d0a337eca750f6f44ed8001de686435dc9a942b9ca96db6b1a07098d1362a01e97d20a805ae42971df8f00ec2b70e31a4213e426592d9727b502670925bd2b0408d2152d4bfa0231bd9900404c4aca90bcc762df4a4d92480ee253e70d729d9642eab6002aef9e4563bd006f257cfe0e2a56b479cf0f9b5daf150a840c0b4df980aadb9302c7e45264b100e26982ab1c5a7f81287e2e95a1422a299b776ceaac28c21b5fe2ced11646780001e1c2e32e930248ab4da0acba5554d3db7eac9e9a47b988109128a92c269c00256622feeb1894dc2cbce46b3cfc9e44960cf76c3174e5d082d61e25ff9b1e00f402a15d9eb8d052ace384db9de1ad0da9cc6f9ef5709d93c2f19beb713ba3000e17af4669524bbe9d619a4035d74410cd0501a3a5d92d617c5e2f47019ae9000a90bccfdfbfccc18508ee6e9a3109a21f28c3f2f5e33a8bc9d05acfc1be5100be23ae9e6881e986dec413cd7c783c96c569bbf80a048c2f025b558a05b0d6005b0037eafdfdca6749a5b3636d5766ad38744fca5ea356e422ed91608629c900c62661978120d9dae3fbd70217b0800ea75cd8d98e046c1c93bb7634aaaea800c4eb9cc2b286d4341a418906ebf60aca974cb5c504b1248dae6b4078b70f670063aae0eb2255ca9a03ac7699d681bf5318f4db23a738858027cf7bea2fbd3d0072e51438bf73af4fb2924a6ee98dd83330c997b831035a57b0c9dae50f0740008734fbe6c81786b708c503d4c3489a0c90ff7157a55f20070e0f9c9c187046005a37b0a9ea526e9abc772d9c2b8ba0ce2c2337ad633398d54c464f926776d700ed9db0ebb4fd4ccfbb23b78b9666ebc9a71eb8eeb888557c06fa640c6ea51b0090a551fb5886704d964970e83dc7816a03afa6c83f41a81412a89679f52f89001204e0cf346ae8742002a9ba304015c00df06e0ce8f1427a7d1084247e384600a6b8da4cef90e74cece403b810eb763eb7bdfc0c01f15a28807b33788fd83c00eda697445595e3e40d37438689442fd62c1d83997b637485d0379e30114a140000c4b8109bb43b6c2c4e8c3f521b817f36713c8322bd65b3497c4b2886f852006b5290abd3196d363716cdee1fb187d01a29139da9e83a2e8a8676275be6dd00a9a4d1838683a056ce4edda8b8f115b4ea16fa76c1b9f44024f86434b47b730049c08dd8f7458693cd050d4d5a01a3f8b0f3eff0b6885a39c15bb98f350fa700d19406795aefb9ecf7f51aee8c7c5a0bf47f2c6462f61aa6c0fc0aff67694d00cd7e468a941d9da0623a5ef2b45a64c073ccb41ecc20a69e11c7d89ac84c78000023d4b38a4fb20d4c87a7e536078299a931744a59c6a967800f458665f145002676da181f3a812cd9c21d3975e1292d8efcda7677ee3e00f868742d64452e00e4b70c8ab072467f530f6f0072c374c35efaf0c8e63b9fc7c1acfad8fcf91b005ab3e84ad663d0115ac1115b8845700902bcf62fe4c5c3102579ad69096d1d000e993b0ca51f4e2564cf9c3e533a50ac98fb20f50c6773d6620d213daaff5700b05a4f0e48034462c1c039246613922f22a49f86b926abb0ac3b4ff69fb0120004a8b5c951309fe5f87df9776d4ab32282e7c65260df6efa47d0f21ed4021d0085600faf0601a4cea227b37496f7ecd089682faecdc237d52ee06f4bda7be80020ff4fb9f6d7edf0ff402a6a49d7779450f3e4278eb852950c1b1b85c7b5b100ba04d1ad4610a35f606513d15ecf8698249b267961b9eaa98927320b6072b800a386c579fabe70a2d05ff40ffa4c455cf6d2a04d6144c0e73709f8d63ea8cc00e7cff925065f132698fb68fb6877fdb5b9c51ea0acf67fbeacf02085c4ca1c00ab22d83402f6017bfdfbcae195888b3079ca4ad6ff4b56220f937e19ec50ea002a0db0f533bf5bec78b3932268f02391caa390cac54fb6248b2f6846098447003dac1bf22d3c59fc5bd4d3c22d9a7be0e3f22c43bc4d2ae712c1ee67a19acc0071ef637e3b6364e2c9ec833968ba061c5222638e6fadab4c66c5626b098ca0006880c2745f7844061bf513fe72cc82683492926559a05dc0f482ca1eefa0c200b081951ea55affbe4139828fa5ca65cc79f0fd1bbbf1414f766e4b43821c9e00d8dc9ce23adc920cab4bb495750430cf690b87225e3bd415ce2ce11685fc5c006ca68cb917e58b8cf24800bdc7c297b99b39cfb285871a94ebed9d92af0a55008c9ff8e63ce9b8adae45a16b1839d65d4976655479cbb638a39aa07e6c640d003d9047d65da8efad632b1b560690de91eef4b4f23d5654e408bc704d246140003f58036062b6c597680969fb1ea9da26a91de76f4a16419b7e1fd72af612770068a214a138f8a3c00248463597c94f427a959ee8d72a4117a03149e8ba926f00734bba6ec2b6546df307064f75b0c31899b09a038eca81ed37bd8d3d0b879b0009a739f476e43b7a48afd272497ea0eb9284a3ba027b65ef03b25f11becb4300a24900d97e49b9ea588ea94d03ae20713930308742b0b47410deae1f20e52b0066c012ac494b7cd00dadfc18a60cd9d46979554b084a90d266a4fdb7f6783c00bcc9d76436e16e6fdaf849ffcc5e06ca32b0a197bf8a43b688bc17fa214c1f0023b3d51d2967ed502b11fc77c4c83063502d8f35a69c3aa470b8b526859770005434f005b8cd5a417e169b00eebedf1d469b99d9fae73eec0e95ea81690ced00f16eec38edc18fc840033777dcb9a00b710ed50ea935a3a96ad6062381fc5700d424c1363fe50b7c266d116f51ac83279b2cdf5fe2be61eb50af9abf7def210079312d9579672ed80cce703bb8b6401f84e94df221fb5d66f48dc3fb37a2a300530e20cf0a895a87b935108a6015466a5882675b90e6dec25cd3e028564035007edf2c3f4e231609dbd4d3ce105f3f3dbe910f7e6db1893bf35f9830e5bbdd00f0892150bc174bedfcb9ec261e558d56b45bceef17cfa8ba1d5eebe98ba54900b67fa18939c0b6d0ebdbc6e86c4c9caa2a24514efcd5674c04ffcabcc1b550000b96e86e2ae8cd433a19097c93aef43c4a985b71c00b947fc89d1e445c6ec100d477a2f527db9edd871812c9e55ad5aa8ec4c2b13280380c6275758e22484b00f6ca0c2718caa0b39b1f6ef30b274468282d9bcd4952afbcd6c3bcb538e16b0070ba67190f4dc91150ae8176532590c66d272a42e015f3a0ca405188dd74d600ff8389aa117cb29af512b4bdb5d946706d351924e4f9232793231f3a46fcda0080d7fd4b13add2935fabe70dccd40d4ec1ac4476fa3d3bc5b10c3ebca2b40e005a8ae0b2639c98eb1a81700504849b659380af83a94d3799416dc0c02b5a440092d5ac8345d71a670397a6d384499416ab893985a3353dccfc60d398f2567e00d48ede70af58db6f817af1bcc0d1b8066696f77fe8ed7d22922f42c7d64f1600e9e080c742f765bcd121c24359b4b901260e8ee49a56e1e606a248efbe735e00728f51b57e7647dcff6f376545e71631573b65d59d2b5c6b5f4b8552b40c300058a33c333feb911252938e193ec02499fac17b6e54bdaff214bf11c5e55088000f318513a1b00af902fb6ebdae84a7c1e0012bba65c55a37de85faec6e2c4c004b3f8c22a6d309cdb76566622050f7082526ca950b515f267941645d58e79c0030df98fc7fb6052a95aa21ec099703b688e6410b8efa121bec473773764c60002a2e5091bf8e8ed73009f714bc28d41570838f31d0a0627cabc8a0e35a655c00be32d00a9f179e856c33b76e8ede8e6535006124f790ecf1e5b106a07f96c2007483d59c5570c8602c40a4e550b0f9a68ca14da976be1f24a9a04597619b3d00ef1a6a866d4b678fbfd85b519c28918e23b80e48db9405268e129fdc1a82b7000945e6247ee0a39968f98eeb38ec57449603a4cc1b7856d150396f6b178f1b001292a61b838a129b3f816b772f866baf3f55c504205f4daf4fe7f7a35f532c0045c4527037a52af7611928197e108acb829811b71bdf43559df544455339c500106ba86c3a2acb5b6126b892657f61c63b86e0b4cfc4cb7a580403a1bd7beb00d59d9d575bd205eb58fd3f36a02a19314228f96a17501d03e7706b0a3e5fd200cbd4c8c599562c0516cdbe8ed4504eaa949493ddd11c81efb81323801875ca00b9ac0e2252f145f11a23fb48c7d147c3b60d5af0bf2157e6442f0fceb5e18e00c222cc3752ffade86865a90dda0a3c4c0424e799961c9febd72769eae962fa0064d7f9643f582c6a4317cf7812ee59167e6633a1e996d558d55cd9e3cf0fa700f88111bcad25676a60be6bb889229aa4ce1860718f452950b4fc7a9a3e4a3d0084ff8af9c41320c3516b583bc693c15954447571f2cb1e2d281a5302cf3f9800ca5779275612f045368f5a1080c4cb6e64e2ff3287f3505fe2bcb8a09e50920068f158f96ba550f63f6abf925c14749b26bf020d94556aea02533ab4459b3600552bf9bfdd3291a1895a68c33691650924bcb1b677ecdc26bb3b6a27f19281003e885213a909a1a49a755a106d778ceb4348de0272db52b3eea60002bbf563000f8f6577720776c4a84f56a894b184cd9d6c49f1d5826d72167b28cf8da47500034b0b9b57e14836e598ebba92921826b1c5de9db0613cec50562c898b2e6000fb306cea95ab945ed70851354b7112a7e40d12db116a39d4c26d5fd8db4c29009e19f8ec1228be6df5c87702fe2625b51c83a5b6cd02ec40a81b9ba0fd173d00bf1fb15744f6f5d12e202d525f0a53f724527451304c540b564ff6b25c737a00f83c18c5c9899c8ce474c5774ea1669890b62fe91e309f55dba91ced5e3c01009082d9167930ad1ce2123653457c3c8ce6d7b978989d27dbbda3f9d86e931f0004bc42cc6b9d4fd2d92692dd2549ad2f8b1efecb936e1c763f6cf02cb0f01300e5a4684bbeb9e30c0570b413092f5f9d0627d4fcdc2eeb3f4bc84c864680f500c0e23590e8a2bdb1792f9bcb3e6b567b7e57509371ba6fdd606f365a55da590012a88a3f378afa0b6eb3b5598ff37f831aa6fa6bffec280a75911f095dc69a00d74a88ca1a4fafbc2bc29ebf8e6283668b2ff17e538af7162f7fd1b6209d2b00158dcfe91535b37d10ddb74cea2dab579e0072f9750b4ba752236c3fa15b7b006b4aeeecc96530659c0abd893a1a3962a7d48a159065564793884299041e2300f91fad475ba7ef4b6960f21d3fe8cc73e2b6f48316c16a231735a8d64e516500422457529326c0d006fd9b35a2f270723ae8d7e76c99e8b7eabf7dec08619000b5e3ae6333d41a2468f4616809556a27d457617c4137b55717b2ac1de0ecfb00b011db0fefd7a3f0048291446b1f682a534df9d1be1e7099ba45b1b6a7bfa1008a4a139840eb2337fbf4c5f01b1474649ee54427930d2d1f73ccbac8845846003e96a41b3a41d8050e5997925f906bb213631589880397ff37760d309be2b000e30cd8b203cd96911627a846d914cea23aba13cc38904cb98709453adb890900ab3db1cdff41282d3f3886ec7501eb3809e70345eb8d3bea4f0cbe1206dde5008b1bcb478482a2cb9c562f6f62505abc92d2418625d306085fbdf2172d3484009e862c07783170ffed8353ab507452010030b85cd5aeda8dc0007f91a7087e00317a0da6e273ffcfed8101806e3c36b2a7f566515911240201cc52d1a3d69300c5559a994ffc0dcab435c4ea31ab94dfc0e26e7591599336ac2d630f1dbd8000c7a18e1b364123ccf424bfb79376b3352f9fd6acc118071bc9edbc330fd9430043b35750f7008839d90e195a148a3df6b02939b8d29931832961a6b59226be00951d74313dde8efd5d1c88075824261d66b3d3e0012195e1408b6662432055006d973e494d04eac564ad301a144ca9a39de2fa1546cfdf4bf992baea8d0681007a27236015f441f0d9748a6af832d47eaf561a535fe859ec27bf5ab31d29370066935c90f82f1957ca5fe73052fe7df3a3d011c9da699b20f0e408f8037d690066f5610b017a94ee3397dbac4373d1c660ac99b3b2cdb9a9a26ef188f9d8990029b43639ec08b0c329b7880fab41d2d99ebb4ed7c574cce6dd7c11b9f56ff800ee7c5cea629846a9c21ccfc6c484c6c8f4d344eaaddc97c9e95f58060992b9000a71a32d6b3c9707d28cbf7dedc4c895e95754b7306d562c21c86fc6903d0000594167bdd488a24821cdb3de9bcd0610f16f84be7951a508eb9a058c221ae2008884d99a09bee31ec35e7a3a6c3dd191d4f716ec4f96974da77e3ad39ffbed00b63b193307eec4a924c4efdad06bac4e955c30ced5872e0699f9e0ad3b770e002b1a528cb776ce0fe1aedb688beb711247c6932e821e39bc9e6b0651d9af7c0023ec1afb32f05215fa2eeb4bee44b16eba7565f4c735063da978e1fe0a848c00b0f0e8abb8094bab5058a687a64559ac2357ee8dd9b640f037db42bf60e40a003f04173325650f2a43039495a38aaef9fc5bb0520830750bd74b16d9a77dfe003e3dbd8a77069c95969491c84d0ca427a340c8ee36d3760396ef6452def9e600e2aaba5515984e3d269df24c4f7d43c959e70df35ab0dd313c40b8600e4858009dce61e34384a6b45e3c8533dcdc72ca3fb07e10520deba85cbc854e3d6641008ad4d54dba4eb24f04e308e1c7baf2aec09b5ee8a19db07bdc89b5bc91596a006fbbad2bee89e1c9295e23deed33ccd0037c0c1a2d0fc30afeba7c39065c9800dcd82748f2e607a15376afe25a4bd3c3ea2d989e52ddb27229aefd792f002000b6518e2652266460806e8aedb3c959fb605fb0936c30f2b9c526bf2a24ffcc004389198cf235b9001e9143e73e2a8e0ab1094db0bf1202314340d8bdcbe2a10058e6c6a27d99b6a84f5d08570f4af196ba73209136e7adfcc9227619050f0000782ebd34964f811936fc2ff2d5bf13b16003d88228051b7c4ca0ee3e24d95d00afec5760e7c7dbd983dfe733fd8fd112a266147b4924b36ebaaa8b5b4f3b1100a81ec4390c18059e1e3e8c0ea3e5751cecdb0202dab86daa704e3c90b96d8e00f11449dccbc65aff544930f83154829da4664e04fa5903efbe1c54932c25d5005e6fed2ce9dbb75ba8101b1a3b66fea05769f05a492edc1292cd48fe6d3dd100c164f661d3f7a59a0b8c915b13cb9a44f76060e6e6def400efa2dd8dfb8ee8005f8a82fc3ca75f813b7a1812152d68c1b96aa52662a0e61de49b7daffabb6900794b280a7d11309fca698f2b031d39e2efc3594cab0db0a0a07b8d840e5399008e20aa130143574bf40ecfd6bfede89685eaab73227fa7d3ed6c2c2de651e100eaa60176dc5451331575d875ba3c3f50688a08e779556b35f0dd6be7011aa8007d680be7d958302a7e75763ae289f2a215fcffa4e3618c19e80e784f7c30a400a05cb5bbb6d81077a3ae4a93a77520df5a3b3376960c9e318e5b9dc56aa91b00111bcdc22efdd66b5a399765a7ad523c2cfd1677c605043bd453de3737fe9a003b3fd65602221e636983b45c169beec2978f36de04e70aa6b59e9265f0ce4c00831ea0c44baf0c0c348482c1b727a4a3eaa3d26c4b5b2941562fabaa2a992500be10d6020cc63447d609bb6dac49fcb23ded3bd7b2f8bd45e1e68bbf23fc5a00dad974dd8edea3e2cc1c53faf5bb812bf1f4816f0c4b237989fcf0dde485e1008cb47f03da782a8ef0280c51ce57b0d56c0e2bde2084d94831c7449589f16c003ddfa0c5d9ed3b63353e1e30ae56ae64dd2fd50cdcfd2f825454d3589fe554007b6b2b2005a7af621921c81c86db148162b03f2df42df650c93ba1cfb4dd7a008c5e0dd997caa3325a2e29dc001d252d7fdfd19c711003931d879b58541993005066cd0943a9fd91d06d86e36500fecfa4f0e0851c9646e62342ec47b2fea1005cbc7ff7de5981757fcfbbb8295b1fa6eae8c7f53e047013e365173a3fedf70034b90ab30de717717e3907f6577da7d1496fba4de541d86b531d33aa56a08f00f90f1aa35569f0a2a4a462f88c0f7bed6e16875fc2bf64c6f74295950edcc9004fd9705110103ef95c5e1ef07bfa725f592712749bf24853b3e51b002baa6e00e7c158a8b77583c0c17bf1c6ae8834c29637a00da177c9e937525fdd3ef659004d70c10d4091eb32b9798fad681ecdbca92c87b9efaee893f2f6ebc6718d6d0009cb262a07b89872adee97651378b9e2e6e953287ffc0a0a015821ccb2bb530090939a791e5f8ffa0e5bae02dee523fa0989a7673b9daf0cf341371e839ccd0084c5f5e8cc36b37818f558bcf0329588261afb5c1547c743990e2bd431913b008438217dbb46ba12afed1afd193bb5bee2fd03ed7f30a61ca492c970a36ec300237bafdbdeb2495a7cfbb35b61bd5d0e1520e98637cfe93d35cec48ff8ce61001e5925bb4b4cd5e5e0e069351cc8a67e042c1d844cc8d8b8bf98971ef4dbef00e1bec2982179e71cc4139c21d97f1aeea4184610ab0526203eedae40fd9ab2003eb81ee2ff18e4044709a3e4537e5bc58f5ffdaddd7ffb4a70dcddee7714910008f2fa80a35e30b7fa59d1db7358fc56593c6f5956e33bc3205e38c3e2fae6009cddb794881e04cb7bb989d61daceec663289af9c1f1e79167221825fa520e0034f385ae1cedc5cf8ad4b162ad4348d4acade7289ce488cc02818da158b46200ec133b88272baf9f6f3cbcafc3ae4f432ca7f3da48c3133bbe6ba3ba86dc0900abde5050cfc1bd672297d148bec6450b6c58a66bf86467d4fb59a9f2784230008796b6a4763430230bc28e19ae19cc7beb6b1299100c6b86274362a76bd58700a493ba9e45883fcd21fe6da4a4d098220190746aef85bb843f5cdc57007bd600a5519130f7ba11ee973faf0797aeff32d93b396d39cd316f7c0748241925ed005d7b52792c0e0526c4b502bc97cba13ca5d02fa3bde7d05e1d6e22afb5c7da00741ddddca4c173133446ecc55f9206dfc8327c52311f5163084ec5a3b0f6d5000c4a2abd9e6c302fd07d4e1432311a7edd0f3c17ff51c6512ec68455a609e7001150cb1580828ba4165c4947071ec7d726c559ec591fa5c885a660680c59270085cfc499dd1ef1f80fa461f6c422826a5fab6ec4a32233e7381da8d03269b900985ce26712466792dcda487076268d6052d2ea7637ecb6ab78adc573443c4c002b29a3e6a81a660ac211812796660a0fae70d412bc70159333297f65fafdaa0075632619786ec3be795ea2d6e142a966952d9a6210e98a12f0899c70d9ab9b004fd0c45eaa408f9b2422308d3b26f450716cf0c98cc79f1f6b631a8ef39f7200a34220f722083aa23ed0c8ab6af09febe568e7c91611bc29d7a35094c4fd7200f96cf4de31e8b8557a374f7241ff80b5257fb85383531b5e713e33cac004510094d7c5b13bc027506c9c946d976938fa2d479e686503cfcbec9974702c0c18000e37bf1c92b1709fee2de2aa3ad78b8eddd5cb73bbc4258617b46fecaa0a9b00a537f56a88d2e8428ced06c91e3478a7804ba7beed7aac23a5e42f9899b46400408c8a47e9d6ba04928cdf834a8302dc6040e70413be6b1792a4573bdde7d9007a629bb0cfa4eacce0b209055b4749f3dadb931e33e1d6443b3552a361edae007d30d76f27eb734c9786008d102cf6be4a083c56fcdb4ea23d1e1da0c0972000efc1f954f08bf135851ed277102bf225be5efbc412c237da4410707c1a2ba40055a10e8e572e5373a198eba113e0ad88cdc7be9bd866e7992e66414042007f00cf5aa0c9a56bfbf110b41893a17a415214537be8254f72eb255c77f253e01d00bd5abf5734697ee45d0aba53d944186b43c31bc5bdfd02b1f65807703a34b90071f98deb4a2ff4024859d8d68d5c24f95d0408d0d0b0902e75bb019ed936dd00477d8bf59de3b6ba96a112199d858f9570db3d4c8860a81b94477102b994b800f04adb812582abd4a7d1de08234ab109b03e9f777dd8dd20b681c605c807580029ad657efd3cf95a32f8bd715a2f69662831f053392c3502829c3dc2066ce600a2420c5b284efb5aed5d5da3e664699d74ffaf03aca739520ac860e53ed8f0000e65fb518248494520fe4570e8acfb1826f698e59b4dea09bdaed8612d1eb7004d5abcd4f9eb32c3e48fa7f6adb785407e21721146f143207c9f499b914b130014491bb4bcabf211d0b4e76488b20697e8f0ef7441f092bd14018fa74eda1100ea422bd8a869450d14cca56edc0dc6abbe70b98ae6f9a50f1b3f9fa389f7f50076ee52c55df9247a94417dd9b13bf2ed40bbae0177d05f325d81221a9c7174002663bbae6348d8e4e88d1ca789380054714ba000cab4cb604651c6ac41a9af009ed5805d238fa6a099afec6198c8775eb1be9df3064a445c510d82eaa41b80002d9d4fb0d8820243649636a9cb058dc3418d0f7660e15ac3b0e23f876f7fe300d3a412fe84dac527bc52221d627fa69c396c2b918557b1e9716cc70dd802b9009d25c521121b8ccbb159bdcef2354e95d5316d03dc072649d16713e90cf65300dfc7409bbf907c76ec2111b528a66fd8db00e623a45fe58f99005a69212b0200f613e19b8b0e9073a4f4cd719ebea4e4b3cb9a843fc84ed7e55c10224d2596005b6c47bf6e71ecef4c7c66afff4fef93dbf50ba13fdf65cc79c3561d4f7c7700328eb7d22b71abbe9df9781076bee8c7de9d7c280265d1dfed8b2ccb6afcfa00379ca2c5e94ebf5bcdb6ef3160defbe476fb5d227ee545f9d2b784cd74f5f400fd826334d05cf133ea3f2d14b497b45f0fd3fd2cdc5e04f575266a31d3ed1400eb9d6a3c371cd9af8992b4ad0b43eed9ac6d949b9135b34a4fa460318d39880092cbd69de0c7699b0e350ed6f19292f5f922b6909b531ba3275671ad7e4b7b00bfa957d329ddf849854b96a5a268d3de995a783b846c3896af542672a25d2e006fc2a75e7f29f618937bfbe35d1ad538cb0f713acf32220c18f4b78e288f11005c4d36b6c2dfd23f0e6ca1c5fa6544ee74e26de9508f43d81c02bd8685ded6008fdd23e0ef70604bcf3453393177548352fac99b166ed7dc9b16c58218339800bd88a2194cbe557d600bb43004308ece91c8690596534d2335d16f0d5e7a8e005e1e5016f6be9d4c1ab1101edc9dfe45276781cff3048252369c1b6e15c65300c1af2131c8c8a1f915b12ab5622b23e30e03750e389bb7454e221feb71df4f00c47ea868449eb2e2118d0e16b5a92eef1660b3442d1481ab9be6cd23b04f6f006c997e7064ea67f3da2acd4478eda877ccd451300de09b8fedd0c3d948e6450089781d25b885d74526bcf414c8b35b9dfca2b1c84505b0000dd4d41e47fdb600d5619194ee3e28f501e527351638bc3769e114ad0210b7e9dc8986e428d6dd00522be73028d072805f40fbcaaa912b9f972026cac738900b6bf211e609fb6c0005062a8a3ba8cf2c0b9e3d4f19ee9aff695b46eedce3a951c8fe974cbe0d5b003e0c52f0b8a267f3cb81d6ca2af45b65e66e550becf9968efd24b0b98f8e97000edea74160f2848abbd7ec862a9a4c6cda9b34d582d4f3a69131c16d24b2ae00c017ce732123b960cc612c1dbaa066939216b974bf0c4a5c9ba0ee0b239cfb000ba75f869746af6fd794cf2d05e29af6fb631c68a07189e9088b669ad89ff100e51272cea8e85c86c7317ede718d9b096e8d196bc3165103da0d4e0641e6320042211a6e5ac532f3b62201880947c084bf212bf2850aed3f1756fe8770379e00ea9188ba6cd1388c1a8445d6a0b3da14507184384c9e3aa14360b174cdae2a00306bf441b272f9ddbf3d8a7924bfcaa97f23f4c9599c80e19317f2c463d02d003279071c8343e0df0774c66ca0ced06ed1eaaa03fd79db0e5f8dab8aa8d67b0035d59325d5a87573fd749c67e3704e29d08fd59cd9170000f7e4da5dced6e300e7076ab33ff663f2e698473e44f784255c968220393e5bb4e27916b9f0591200c485d2783b214f35df66487603fbc8ca91cab34be9ff4bf094ea3beccf57e9002d471dbf7e3102c8fa4edb601e0c599b4247ee36a993668500eb9c7cf8e2d500e8e2238bbea984ea6ad663f37149a2b5b7161effa019377acf53b072a8613d00bbf9e627589aa428ff73c8d44ec2fab6188ef3c193d9b43c27af69953cac5b0056a07e159fb12636ae6d1837f7cca6d8aab722d898c7c808984afc3751ca8600ecf4e4f93c8dda87d5c032a93759a25f1ac66aff2281b21f9bef81b5f7a7c10063c5061fb3763e4a98ac047323cd2d0c2d2d8c0557ff1eaccb839b17d5540d00c36f209f6d29872a2bce5fca0925d3ab8ca7a3d02e8472f21e73abc3e12420001eca6d1712542d180991b4a31f71f7419232cb237bf46c67ca3efdecc2d38000cab5ac0b4a760239574d020cbab54161f69076c5c913bd0e5ca06e60783674004bd39804c591a4dd55e29244c2e98b1ca69675edeac522b1ccd7f496542d09009ab0abcff75410c97bfab711825617e1893acdacf950a797efa4da49714f5a00e66f06c44767d21b2ebef89c8eb560240f4de465709c45889082789439255200ec44953a1e47c98457d20ea249a0858e00989d64ec9d66b41eadaa5ce3860b00ef1cef7f5ae9dcf15e44a08f727f7a350170b534332c61dceb336f89c246f000862b1afcd2aa7304fa25aad549bfcb40dee63bd0bf9ae132231a6e3a3f261700cd3a40c4b1c53888a6b359aa6a4f94d5016f105f53817846ca9802f3fc529200756920e67f8dc6987d121821347c1e0150c5a513248bfa1be65db7ecf61048009973df8bc3e76d374e1b325bad95fb60f4d34a11bef3f97df407e5683503fe00189bd8c055d340d27167256245a96da2fbd2e8c7e48a5df33a809cd3595cb6008dcd74411101e7c8fd85acf0eb331e196224ab2b37943c498bc81bc294fb9500a771cf2202094889b6516d5a059f85eefbe1cc4a949355a95ce94aebca09cc00791d4c5c6d03660aa7e59b92beaa217d04f9bb96786d6ce425627e3b47d47f00d16a55b41535387db0039a1af24f714adccd7675180a1787b2ce4f30d24029002f134425b11fcac8769943c6f220935e8f9b4b053cd28ace29649258fe416b00a6cd55695d685126ebff70b0a0c1c0ecfd29ba961f8d7f0d2abf60a501eb4600fbaea9acadbe6acd5a6a9b3e93b0699ea04f2be4d97226f6db17b5641401c900e26d235da16d366f7fa946d846b06ac6f51746d137ce5a50029a5bea2c7dc800f01e50c8743996b99053a438c7eb02cb1713716871e231a15a986ecc84c1fc0004ff57b071ed4ffb60a6d1398df857b96aee10705eb0e338008f9b2b42eba1001a95d1d42127dbf4882fe2cf0e7e452e273438aca1b51cc7a7922a8caaed400021b598fdbc7872bbd1dca73fd01b0857c6765739d101695c8ded5ad85efeef0099acdf72acc6e7188ec88d7830102081de600b0ba8769362d22a59332ae87600205fd7bdb7aae2af07f9e9949ce8dfb40ec1eacb39828749f7276b758df4ff00a943dd6a7e2c88cfbd7786326fe9c7763367666de1e0da339e4b1ca0733e900028ecbcd3835fdbec5354d2c52e561868572ba86140d0becdf971e2340eee99001eb7436cc55b49617725302a8337f3d8b133fca1cb6fc0f7bbaadf85643d0300ff65b09616422bda8bc4a73ef3c0c3feafe31a477296bb74598bc04a1f9b6d0015e86dd524247a4cf118073763b94fcf9d0f813868ade2135761b950f44167001a18b3e275636883d4207d46787ca38e6013c83f0f7ef4f4c59361cf9bbf7200aa7bbef4fdf26b83d71a9dc33e2f0ee4c6d61ea748e2abf72c678f68cddf560056d3d27cd26d051b459826f037b99e496d9bf57637108f9a82b1f76591f29f00ffbe9bed10ee0fceb71b001825213b7ce96a85655da13152380395215536f600a385e47a8646bbe6b6045d5da80c685aa73e6295563b432b682221871c8086008f0bf415ed87dcea2dc129731198f65b0e1e0bc07f92a417130bfe2351137500f0c89ffc5ffa1d6a6c6a8841710212f832c444bd96e3190c2457c4d61d35840086c1c9d535c41ca67628bfaf4d6fa54f7cdf5135ef3d76d66634907d39156400052f4c264e30442f55e6a353c0e7cc1af1c0f206df49d26961653391fb384c000e39c0b24a811c121e226fb0c3507afa2f6c6103562124ade4edede397f9830084608ccfe95532dfec90c6daa90e68c84e0fd5ab87185812e0ccf35bf10e7e005f95298f0ec76b8f8e19fd9660485f98fc405322abf2015680c169e4ddbac10043bba5325346c22c99d20494646a8485a55e82e5f020d3bfb49144e58e610e00a464f8c5c2e10c4c89dc9ef810b8392f607f8797b8586bd5a5cc552afb635c00654daaa85f2e6fe87d8c8da241fd1dffbd13f51d231acc5947fce03b97021000e083f5468aa66b3dc36adb926ea5e8ca6ab4417c09e77b9cf889b235d7d94b00151b61fbc85d7eefdd26a62a4a9de5a5162e7add430249f28c0d2d819830ea0020f471d045be2e2932c1089a6ee5541667e04757cf1a662ca20f669b7ce00c007ad1ce6fc29c09d9a84223b12d4f29d45cf13c892f4c1c53de960f0e7943b10069fe5000e71108b4e94b49ff686c3c2fda6ff99530e71982d6c5f8d879a3da00116149e273674e37abdcd0289a95a2bba6a5dd68f53dbbdd8eaddecee43d29008120f1ffff3fe2f6336a60a1be707367bc82a679bc768be91e4f2f66f323ec003170a9bcb75fe5a9ee5a5374c3dcb8e13b5df0eb4a32b37203fdf9b492bbde0037568fc9f96dcc83c487539710fc4aaacb14f14a00b5485bad193a9985c08b00a9f995b65ca25c30816c51c51312b773a329c7939d0441fd7dac67141b5d1d00d6c96602fedf80f05dccf9b879b5e632c52d326c232e59a79d2bbd9d4b76cc00f4f805cc6e33ca2728ee9e46587de5fea89b6fbc73b50e855ffb8ee06539850005b2a15c51a7c7d1fb2f5a7b4687b9ac3fdcfded90a8744398f90390d720930065e956a4ec676ce4ee241e20354836a6ef5a8c4d8d50bc451b4949fd14556300eaef49096b7b412c354c6a042795f3639df5e4a8cdb37bc83971c76b2ba14500e4714bff7fac0f4072dee68f2390b563395a0df3b56ab56c9cb6d258edc79d0002d914a6b1cb742bf140538057b399e3a46387084e91bc2e07f2dc7f4b1825007e7d6b615d10329bcf5facb65db579a439d206a8cc861ef3ebbdc741442ca100c2b9269c3073f7f19d95e0a9c0941bbf13fca3aa1bc9e2e3d5483d4e3dcf130027a5e289fcda24e07106678e75e40bdf0a606dc8426137b3dc77eb27559f4b0000f8a406e3e33b10df549efcc2714fd60641cae6b6a5a63624e9614a3e1d180043a21e1c166feb347db9a8f2c52e4cf36a934c0688d22e986bfde92040dd4900e32b5b39402f9697ee4d6040fa19026e2f56739dc6248b83db85f7ffe795de0058da966ef675c1b1402e828f7d54d17029fd5ca7aaa3823165babed60b2cff00632585c347ec28e3e5a79887cf4d4e488f38b65a22bbe4bb56f95fb2e20827002fc402b7138e0b3219602ee37c4eeb76a0d9b275bd62917e98c69687298ff10023d31a839c63aa9f41759e76d4f33e84354a6edef0fdb6afbfe924fce1f08a00d41467069843edf7adf2f9c3f09b548e8a6ba5b13cbc492d119771d20cb714004371ecd81c25b405451ba40292e77a1798a9ce3b86d74021daa1f08302c56300a35aa9f61ad820c6901f2ee3c1ef7e8a19fb0bba403b537f1417522f382f0f008032f3d56413d8f6d7f59301c0184b3b7b78a467e288c447434e58f82de1d500dbc480d3988502f1b20b1fb844bf5b0d81d2fc8ae565669a605dae71543f80002deded77b4a278ec560499d834aaab8e1d3eec8bf4e9a04df4a792d03ec36e00ceb6ff9199795c63b5cb1255bb95fb6101ea098da1838ca341fda2cbe87c9600f07b98a383c22ec0c38beb637c7f9314deb49b61d23372d375fc7993e8b8a200db9e580a931214e2ee1124eec853402e33ccd0e8f70d000b458dc3982ea5ac0066284caeea6d10a2021e248b3df2395e3b7f6a349a869abe534213376660d400f08965ac7355189ef89ec59e92d86ba21ca60b480c36829a55bb3bea59979200a6b6ff70d8719fbe8f66fbd40708d7d8d00efed3a69ba25e7701400e8eb42e0020b78ecc73fb81cda055e679df339c1082b7084a93f8ee625ca2e7935b04120046ee77d76aef1fee00aa568791ae476842ab5fbcefe347f36c839042166cfa00aa1ce1ec930f5ff6ce3c9f1f0a3f31001c27ff63e570c9ed829f0d62d012eb007dd0afc97a91642a9de4256f5dea633fb3325fc8b081d77acc5e270523035600435312aac714da630cd610c279e36584bf5dcba6876adde5313ccf6dc02708007d58767e8286b94524d581fa605eb3c845c90f7a79333f0e3c7fb478cae0f200d7223dfb4173184ef4cf3ac08ef68fe2b1545a7383754a441be08f636c04aa00f4cb8d5dadcdf1702c96718b2a8e1d3dc9cc008372b9bf0961af646d1b618d0067f65396679277bd234ce8057fdb1136fef25e97a0bf82fd74bfbe6101856600b05ec08787644eef9fbe3c80cd9fe32b476efcc0fa43538b6dbe00a32e43740043f50a23a28a918fcaf50755d7b184be290b7c782c9385a72fed5b58b4eb53006dff5b8d6db320b7ea8bd7ff4d87ec5dd23ecbc55cdadac90597209b843c72009a715bc7da9fdb5147ce44cd9c6ebea1cf17e9f9f8a7323b723708428d4a3e001078901f99de71e653e7ce68c9024cbfaa83318da0ab12c037724a050d569e008560109cc992f80fc6221c07560c5f985aa931ab859ccfefea820f40f9d6ac00ee914bdb849b909656ea304fa0795a5f6e56893fb6a1f310e4926126a26df500d5a772b815a22defd5bb537f7d952f9616f41f76afaf122bdf72936dcc92e100329043f0d702258e95e2c0fd9bacb4de228b20ae75ed477996844950cf6a5400235471c155860b4b58c71a0ff42436b00f7c9b48d5af5590f168c3e517da6000abb9a7cde9a478677c8a125a41699806dd10182b6fe027726d9fa05925a8c700ea6ebf49f0e7dc4cd529d2c5835fa2a596d7c9b689411c2b615339fc80929a00de7fbb51fe663ffd0e58e193edc57ca83a6d3ff50ce0cdb6f296676f05968800ef240a2014e709374ef9b37a21cc2e2fd90611ed848d46c92c14b8bd6f68b2001c5bc9811bad332bdf0619c7df31cbfd4d834ed5d8f72911adb845f3239c13002f68d84e95f906c1e361edca3f2e806d9ad61427d8155db164e41d8e4e1e8a001fd616670dbbd4eda54dd7e770d331e996cf23c5ace9615e3e0389b237fdcd0058ab84d9ed9d61174f27b786f52759853a3af4d30b4c2201be1cffbf27f928007c23f022a375888cc250413d873e8d31580b28bc1d13c4e5946e4d5f959b770016af84c12567f82ff7d8b15f14997ab6e34899f772d07660054593cd0c7d36007754a6384f612e7846d78ced02ea2cb79e5cccf6a20ec343f359ea8f198b6500ac252a29af6fdb8db2840881d7344736d25545a876c8513d2c8e8d2764b942001ef5af0630a4ceed0d81461d461a8895913b3b9a3ad62e6b91338bcbdd9a4a00c5f3df018ff0e13f04f1b702cdd23c8fc0b006c27d1b28e990e10e230bd1b000f4bc2a0683edf1c365ef01eaf70bbbb5b1951ca5f558d10d10b4eb1169dad400c626ceb2b8f4ec30eb4c549aacc7b62076a8b17c55024a9b15049c6ff218f4007182cd38e6933032a743f3c5fcdcd2ca7f52789206b7979a1603795ced5d7600fbf88b7f4bdfdac458824f344e679fb8ecbba9638971834cc6bfb896ee3c3800fa6418686a67c5735fdfa778e9e03af7c0bdbbecb81b90a31e39cdedb5eeb40014529ab23ac28d108e5a39e0daa6ac13ce5b7905231706d131c5bcb90423610024b5e3593faf18c9c3e97465b6071af5efb9a03760568dfb11557518b6726a00f61bb7e0dd28b60e1119c00d597277b745ee575393bb838de5a201ef1b7696006c21916add28639c673e648a886f44adf018eb53a16842e1e405b61d889cc400970eb4622f50e5ba573b82aeea90931e9995f2ac78526cf4b16448f393c84000de868b76f68758332502e83d73760df9a073ac3b09731bb273f2647a5f66b000a13f9b872caa8ae0836bc076c1f24b76c2d1dd0e096fc8db8575136cc1398a0001518dc9057a4c24751fba850b0242b44de6eafddd94f2c2066676f7709450004a3a3d23db49dbf1f5219dff8533ad9e8526456a64310fe3aaf218e3d5cda3006d44f8de132dd4ee46a6d1398aa234163b37d7bcc6c97e8bb673f89163b79500ff77cf4c286fe5d32d28ca723722157584737992a70cf70f4d85171df66385001338e192d31440f21580685a89503cd3319f5385aabde4871663559918fb1600d83d5818d18bc195db025d5cc36daeb3cac985828308dad3385208a1b2abf900d6e135d71f8dd7adc80531883ee0946bff8ff7a3627ec67e55bc071099755d00a99d8b30ccc7e33dcc4388e187501da8cfb7e4b2c2977e9cabe9470db159a600467f0a8bab10fb5080812ffe83452c675f565d4f1f9e55b81e36382c2abb7b00ccebf52c109efdc7e04dbde13cc2bec66cace918edb9c6c85f6e0e6dfb71f6005ca50035e610506ebaca8e22f2b401d599a571ec1e9c4cce3e981cc854ac73002b1948cfdbdc4217e7210c87be23beb753b285bf6140f79223ef87ef440fc500c6bbc724ea0c789f089eaeb49beb71e121807312bda0dbbaebcf58ebda3ccb0060411b81514dff8cd6becf26141342d540d680aa20ff77a05beb950615b33700f6eb0f07de822405c271acfe3dfc5699b21bf794476cbcf5544f590fb274d40019742d37a8617a9f86cdc8096f2229b3ba967ccab5d43ced410c70b368022800fb56e66f1bb2069e06ac48dce311a20535ab2807f4c918c98435a7dfd1b90c00d8a75a09c442835d4be0f72aa14d355df876bb6dd7edf4eb57239fdc8e5543006b9585a6b91553195811d93569f65165e19853bb88066c919dae5eb232ea9800d4b9a5cedfcc47b1f6995fcba297d7103e16f89d621c206a44d4818d786db50091a87d16656b910db6c8c172648a80b42af721995dc30577aa8d1fc0ea879000ce65333d6500007643a77e227a1c3621c7231220810eca467aee3371356aa50000e9e9e19861218dc637751c4a216c690b98437eff0cc3984653542968e7ab0079aec6915b25f36811b9f5fa5d3d2287c5a755f60d88bca9f542d9414f0f26003b38b0997528811611b85205e70001fe0cebe66016db063b068136067bbb8400ab2599e79912c562adfb84209c5259d9c20056c900d066e53ee73ffa5fd38f00fefe3eee5e38c818e84e755efa3a53f87f3d752569e82f453a9596faa143f0007309d8e8c281d1f287997118682af3fde2bc844ed6571f4eab8d041542e06e004c7682188a12db96d57178c18ad5f38703b3b041a175e28171872ee7994eec000a41e989f5fcea49c093dbca7d03a8a41b25ee6fe4b16d4c17003ecf58f11c00ce54854cbf17ed33de36cbd81eede4025508b87125bc20d0dbc6477bee156500b8471aeafb10dd9d6810ded50fa2710f6349c6edafc22d5bc61a9759121bce0067bb19c0d266249e6a629c3bd7a661fc75ecd97caae975ac7370ee54f45fa300883504da8497f7eccd133bb457cf6b3cadf3a316cb859cb79f53fafc8f34f3002554e05151bf69225b2cc2b81d912141cf9cd44ee27701efa26610d38e899400d2d6a68e7b4a53a5dd06c1d80e7cb376874e0b4fb126fc027dba127e154ea40041eb4d0acc39644bec7faa6331ea38916df50f0646a8ca0142f1c36117b2f70097d9db3afd7102f537b614dff3933bc5a8c15bbe5008f4c290af0d2baf430d00b626aec372ca5ee76eba9ae1cc5426f1069cf1c75de63b2b591cbf48b985b600577ae662b726573917f17cee37853cc21a597830bef5bdf3e1e66a784ca25a001bdd0b02f5c9927cfebbfcf60c782b6940f311eef7bfceff64c746415fd22b009442f3516e742fa353030c1b6372cc4effdbf3a804202c595667d95f78895600131ba2905373402b5c8595c4cfc1bb2af6948c0d3be75a43694eb8985a20c20047cf3cb22908b8b342f0d119ad4a76d8c5476f8ddc81cb0b3abaea113ff2df00033fa6893b7a6c63a718bf61011c9ef1b1447af379e1e6be79dc0bc06f4a5800e31198638090416ac21120a5a73c776c13781c227f878444123e38827569e5009dbc13db322870d7ae6a439babff5f37a957bf80216d7f6c8541d79c3e66270017076e362aa457163f9a2cbfd84f3d304e2baf1db8b29136d1e6f9f24a973800792adcf03900abe5ca07fcb64a243978bb3b85bd691634255caf816b660ccc0088a820f09d7286143b6acc060c2f5520105ef2e85f6773ba852a8605494db2008d51bb5e26ebdff02dc6047523450d771802171fb702509810d896f106fdca00524b82d9d9280f771da60cf0bdbc11f27b64d1242b201f11de1b92b3601f4a0063c1d74f4c7b4e93e9ce575162814cec391321f5d4d0c721383dae62566025003ed470a21d9b53661e53ab1fe4730cb6fb9969fa74cc0fb82162feef08766300008dde2bd008e73b1291df43872b48b1d950ff981f72531ee9dce6c62f88cf0029c9a235c31bc471e45dad27ddc23a6173812bacbaaba41795c60a4486281e00892492ac6b31bc1f5b3ce803b4460b7b4ee31863cb3dee1d4053b68f3c0f6700f1bf5534b5e75d1527a33bc54d7bb45f33a3296750b85982c4cfd31b44b47400e3f9cc5f5a0e1732b28874f55791d6182669287edf611507796db8c822788f003d1ccde5693053ed9705fb9ed2884e7d5b8bcc3bc74b45a55183b02158d9c800f295f8748ec728c560ab34c98bb767508a1e8d06f04322f00358f029e3b22200c71bb77dc36697cb54b3096e58fb9f43aba445381b0ba5025d7af734755915003350a77d9a8342886f3e94cf3769c45cce8aead8573d1b3e24bd0bee0e095100c9ee7b181225dec5a981248830536c1d11c9d1e1184506df1678768825078400f06ccd4131afd2fbe5c9ca345d3f5423fd6561d333296106571434057fb68700d967cc2d9efcfef6496f4d75905c6a261bdfd0591e2a692c5ef6613412c35c0027a37d08a6f4c7d3173e5bca0bd6abca63bc1fae8545a09f3e9330eac2c73700acb9a625e0b58d152e07f9d58153a7231c220e4cf4aa7f0d9fac84fffdc2a2003a5646acb6c3d5df74de42083697dcc23062d87ea0b43a07e270213fb109570079a2b85ceb9b7281c10a04ff2a10b7202f881e51dc470159e5619eda0c89d00076ec7df6b44cd705cea380f717dbc07f9e56c7375d989685dde1c9b6ea5d6b0042caaf15f4a9a49d1ff04e9bef22411fc60a947553d66d5375183d584d7cd1009ee01c9d69c40459405c44cf9cf1c7abe8aa8c0329630ead3c41bffbda75d90094620b60f0c6165fb130b0170bd2bd8f1ca38ef7da71fbe0f8e9c0c5277ae700a867371122077372b3e0d46e0615e39ffbc07fdfe15dd361fbfec9087eeeb10095eda0d69f1969bb07c6f349475009e5c8152e7930a8166fff49f4467a51050081bf5bdf89cd29f48ad30196626dde397cf2fa4a47e9b46156fdcee946d72300ab91745ab795668936a539e963b3b7bfe488f91a0562ecd820ef552a4d5b9800d1dad0cd3c81ef08355c02dea92f1e2434893359de40d05accbf4e65d6a46d00c0f2fba7fa91dcedd88058e0005e4fb975c1c5dedd2ff56153f5b87fd4650c00d0aa45df1161e5ce93df6fc43e7af7328174e1defc1b87712b6c785c29d49d007c0cf2fc1e90240c2225e59deb6aee28a89b5dc867c306312b9083954244540027ed2e53e36c67ec3ab721b14186d5ca97621c580d77a2ea01af2e5f0508510080e45833b16d4c7807b2d7adbe92e8da0e96319b0061e06ead75d3b30bac740037ac1a4ef7cd4ca75b263e7888c454c14aa8f8d6d5edd8a160948b673f0323000809d171b44c0bec4435aa53aff2e8595ae27bca238010970ad4d65cca2fa9000ce3b2262be488844ad71e658610f94eb5681532f449eb536ad287749778aa003fa2baa0f5bfe3ed5534d9457eae2a28aa5330d56fdecfae522dacd85c19b3009aa6d3a3b44a6a89207e476b7f2c8b3ed4a7fd963bba493eff5600fe0e5cd700b91885a76eef8e23676dc1df3b55b391f5165b55189fae368ad8810806413500856d59374f5c8ea7d85b41c78f0ba091791e899b1fd5a8ba7546a52e6104ef0060dc8f11320ac59cdb04c6aa07e017aec21523d2dd78e33259566444f4239000d9017d9a1d065e0ed3615cbf6c9d964998f9d253d85b4f3dea7dcdc9bd33860008ef54fbb5e98165721ffdd66f10cbd12d242b3edab6bcb818f07067e55470008a619b5fa701de1b92a97deb5decbe5c430931516ce46290385db3fb9cda8600dab21260fd7b805aee7b8153b53a0b2dc94c550c06b80c72d5b08dae65805700191ebac523b4372d7d07dc412db4e8b606bf327c48697c19e24f054f06341800bf877ffe6b4007a5c01595066cfca5a014a9ae757f6a291c76ae3a3950cc6300b2a3a7e8d3bd1d40b300e2de788e11138ab079d17fe42875c361cbf425c56a00f465442b32e2058305e04bb3f2534e46a2be228a1f5fbab76cf6dd5712059400af59ff87ab17b4de724278a76c09b0ce9830d15b7f2393aca298350a9f40ed00323175a54cd05e61c70127bc49bc0f531a08ce27afe2d841c1a85c17c8e80200a589f9ff7993dad211605d3ede91895a8f60b28f7f591c314616cb4819bafe00de391fcf45f454b2d25c4a0fa3e15010109dce8e2a762c7b5465fa71d22664008d58b134fe43aa253922b6173a5a66b82a1a0e4eb1b76dda33d7d9db35ef3c001ef1832025a23c1d9dbc6438d05d0035956bb6a3a39f1516a3f3099ab8649e00a3455853226594958fa52765df067291d7592a5d447a69bdbf9e66ed9fb8a100f5db8c1a4e46d198a13dfb7a90d43c9a2e2be0242110fd83b714960cbcb8c80096f4486cf88bf94b8171b50065b31edf81daad388f25cf9fd7cddeedf7e3fb00b9d0d3eb235f0e384a1833c92b545e89edfc787c70826f9ccee187711bf78000b1a05079a7adc7b0d8b4102a2d76c9754fe034f675d23f22bf395a7558cbed00ab66492811654907191fc87e41e7652b0bc96b53a5547f23d062789b504ceb0025511443c784547ce0377fc89a49bb44d3c6d7736751e2f19a1581a83c71f700980948fb16efc7deb731198d9b79ef3b67d13badf9dcbe0de9c9bd3d6ccbb300ac18fa89de918f92cb4078e4238fa49cdcfd750315a6551b9dc9c6f238595a008ecfec09080ced7f7662c777198d51539ca776b8855a4fb584522518c62c4e002788a2dbaa6ee57d498abb175f303d1f13ca4bbce9fabaefadf92a3e3a972b000564534c6f4dadbdb37bfe6668405c1e0873bc01700f3dbcd1919d29051a22003da73c2d7381f23066596a0f908b5592e1c24c229f9212918afb73230b9b2a0098a1fd1d38885997d73108a4bbeaf4899d5af1d432852f9e2dca4c341c04ac0038917b7ac5c04ccc04a4949d282248af914f4c02308ac6dd1282caa1b941b400e0292ee1646d803c29535ab10b6cc9315d7852a301c0e0f47da0dac49e6318009ce5d2f567008900e6db94091c7ff514299cefe7dc80060d42e94c74643ad8003c8a6c68e82f072f6b7e3926ea21badc3ce9178c1a71deedea95f5ba942aaf005ec0edb3a7cc912318b8680e9c072fa09acd35e025dff5a9388b6214ead72f00e7a457ed3bff19d58be9060ee45cbcbe1dc274f952b8e5ddde3a85bd83444f008e22d74707559af49298501b16b1f87a0cf19e306af6d6a32a91d23b4ca78800814f346279ff04f80499ecef63f5d53834bf74878fe625fb7d3445042789ec0069b7ce4c9112daebe8b3f9bea2036d43bb4a9dee05625b1a96f00bc9354d0e002e15a86ec2ecdb3eb6d2fb5ab5689efb54aad51f2b8f06093b10eb0132eac300e6b8d3da1ee74d2afb6ac589b6b7fb60afeb12524cc058621f7bdb51ad6c48009a4ebb43845a57785d90c9b254f6a3cf23b38e3681430a46063664c28054b300cd58ae3df92640be3dc76740b4ba9286a0ba9aaaeac8977079eb1a23a38fd4003f3e350dc77df701f111ecdb27aeeddbcc5a6d821e0096b87dd7828ca4179e0008f2db57c8217e7b8f920bd4f12aabf8daa0de77de7d5ceeadd6c98b107ee9001b1a95aa0438cdaaf33727544e906a9a2fd8763d9de1872e2652a0340e85160097bec05f7dfa0a80588567ea1d42b27c98d1464355a8f7bcd7d7134812009200fd40736274f3f2ea1dd2a43e4fb50869c027af6c41947d683c5f51c18ee2e200dfefe7eba6a6a6d400b1d527f6e8452db90735e34036921cf65f93a945c3ac00ab38b05381284278f3c0e5573c6acdbb05c555d490dbbc851f371c9e98f5ff00cb4e7fd0b8bc680a9ea38150da4b3ce8b0d5813ded5ac503816e0edbe8c3ed002305753694fca036238fadc1e709c35d9326a32b9d78b57b025704e9a373a60040a5a2bce6fd06c13a1a4b7ffb567163d57793fe6587e8e12a171221498d0c00a9a36ee62be1e86ffba7219dce0b7345af9a5488b4cd20bbc8e0a517a7a1ce0055991c895b9ea9a8076c86f9a40316659b1d6fbeaa36b9eae2313151e2013400029c46cb1b3c8341281287ca5c70f2e6848e86b7583fe2b59ee589226fa50a00d754797e1906800cf725e867f6ae860cfa2db068a02403d2d94abd0747c0e10066e7b41fb4b4b6ad4971e598258471b5554d72cf2042bb9c67f090db6a9b0200aa4e68e37d117d3131971fb36b8af28c7ea3cdc103ee6237e0792080bd9edf00801b5f106a72671a2ae97cf3584d2112a6df1867e2d88d78e9b25a7548d5ad00026b02d76ec7b37dd3a7b920ba8be5a8d8d1b0ee3f0712f715807ced3d18af00dfc8bc32cf28c4e9f0f48bdf8f8586ac8bc37c98cd270a37670fe953b37e3400f6370ace8dde00219dd0e469e9be69b61a3aa6e7b3bbb6953190f53ead2b3e003cef978ca624ca18cc83f43a59aacef0f270527137721ea6f93f4a0a761995006e8b65ce29f14666edbd46b7d5387777a1433a0bdeab402703658022a5dd3800dd47347ee18cf8ed1886a66f230bb30d3af135d14f19e7ae5e442daffc5f1e00cdd096fdd4bbff113a2eb9bb489571c28aaa0ecc23fc43dcb7885124f96fe800f0d536a9b90557d2683a13a206e925e59e14a9eb0f84e0c02116944c65cbfc007d2093f4c4bb152d30d9977cdb91eb3c86232d7a03cca87e853d5c5862017600ad3f7b31af9a53ea814fd269f3f111ee9e83a3ae53b9e501d92452a946fba90070b62f3a8cc4a22d19f5ab6dc7f862208353b0668ef6c8251cf0666a2db39b000d930aba1e44bc6453322975242c75dd2183ba569a871724e9ea20453c920000146766fb2761048f76b9bf8dfade25a81a19c418b6b398701eec8f6fa13a61005eaf3bd7e07ee1383dadeda84364cfb0268a1cebc87d38eec32533cf01fa5200272dd49fa440d17d9817155e356ef60ea2d3e34f0cba857d9788e2773d21860046eb31cbb107787e79c62b799bf5d9cafe134e4ccf9a348a00fa2fafd2baf300e3162dfa82f6fa7966709b7a28eedd05b4e29e7f119a3e02045be8ee55d8030056f722d4cd49a484c72f6d638241d4fee6ecebf75e4954ca2f40300533dbfe00e5948824214beaa3efb87594e8532df1a2d6fec76b76aa18f29e0cde74cf68008c3d549e3d974cd4002d06dc2059b75fd28e30f3b7cd2459006fe2c92de5c700b5af7b3efe1e6d3b2fcfdf8c633b813ce03a76ff5db7b6c23e76679ad9ce1f005c5b2876619b7160963ede89d948590bc1e29bdb553289658431424beea04200f210776f341ec6ed4b44d299462dd4b0f3f438319d26ec034622759b36658d0073ecc362e73218647d3f0bb032e2084c9cdd914267ca52c1d46957c93c0e450068b5ff310a38199b897c1b49cb90f0ff653fc47bf0f6612f9bab392112df850038e995b177177f9cdfd2b2cc478b9ed0776a38af8dc4b6777d34a6b827514c00a649024d5c20be5a2e787177d94ddf9959a9999a922095444325f237c233b100b78aa0fedeb575effe25f7087dbf45a5344471a505465fb238481c0823da8e00974c86ec4c7189b5298e980c97cbec7003c67f8aac0891a536f864bc2bb93d008487712ac7fb54d156db65961d663284216ea6f9e8b41dc94be621dc3a50a800f5fc164d7d5cbe39ec89b0eb62aad849ca2c30b2f6aeeabfe257a88fa73cd2004ae1a6d96bcec6017ea2da31b5c5305e165676bbe783f3e7f466c8bec35ece00a982913dde426f2c7badf67f44ae5b555f0472ec84d4df928dac6e5b9f79d80026064a452d6825883465cdd1609049c6d8064477f96afe123480ca104a568e0013f18e3261b127d21a8efeb78b01608f1395f7c6dedd9be122886b027d04eb00d0e9b97e3f4a12ebe163bc6fa2119f61fa82bbbd604bd634700a802c54ed5700a456300adcca1be5bcd55dfc8d632faec3ac2c01db792b7972678a9707661c009826f3d1c97ccd163d05357097ce51b36da4ac863e6ad17b6ee00b5626f118006032f62963a577aac33d33c3bda5aca8796deb639025fe313104b54a2c1c5700186855e00cfdb830600b56942a462d5f77e9a9af538483d6617038233672c700913d3740c305432735b05fb91ebe41a5b8e02411666a57a7c9fdf88516f3d6005230b7aabe2c6f405a7fb8ab2dd77616493fd9f9cc5d9b8096dfd14851c317009a460fd9477cef617cd79ef37135e59e658356bb8c20daf04d8c6a3757f072003e859788b5b13c70811d0a86969f5b4ac694833e48558284804c954136571500505ab9a33c09165f5bb62da832fcdac78978a4510de2e61bf61825fd6a161f00b3080a3bec4427c0a67e29919c0fb012a1c409cbe33470b31213d4302c6244001e8e3f3e197cb8926cf6995bfca2a60b159fbb3a3bb0fbca1aa80dd7f864cd009c463fbb748d58aaaeadc79568c39503053f4e8247220035ba33829946167200e28de94e2facf1b85f32bf47c3c9e50fc65782adcf502ce3a0e3a16956bf7c006527616cc93e7d256b0dea362f62188e64874070f610f181992e43f20c92f6001ab02201b83164cf9a63524ab9efea09af3af49dbf6ea40d348bf3e485e5a500bad46c7cd47e3ebb82e083f3c12d3ca3406f36bd378bb9c80b0a928b184827001f11e7c33665db5d9c872abb42c15ddb6ae0d8478486806630d5bd06ef4c380020d419724853d68916a79b08b10a623df2c1f697af4496e2169e0a61752c650034b086da0c46f2bd3197d5f0d517cac8df91de4effe160d6388735f6f04e0300dda006ac6df20981d28ebc42b24e3d05963cef2d40136d5a48d230c7776aef00f9a9090482145bee7f3a55c5f655d8f71b9780f98e53ea5894336e8ebdb09a00d639df809e4716d59c9c2d7549c0e3d6b82c81fec9baaf16a0d668dbbc19c0006d9d6aa60b5f1940f2d87b2fbc0d9dd42b2be8957eeea39b8e575ac9091a360000ff53aec2f19437bdd9d9049d47cf47f23b951a783d0abea10b9e8b0b5eef001d6bf6e4b72df1e968023e83954105b98cbd2628016ee409ab3d2f4ac01a5c00501bd1e1f1bae7733b8af56c52a56262185b36c443ab6242ede01fabb3b6a400512da6fd493db642408ae7be8bb8da0f0d28797388b96a396bbfcb49d1c3810079c51bd3961ee5e6e2bf0860a56de77d13c3974e5cb90ecf0bdad5cd7b12af0092759d27cfa662713e29dbef8397b882fe53078f2102c74e56a3691d5cc6f500f096b2b2d8815c4fa67a0fcd034ba18c9d82ea5c2bbfb238a00926bf56ca6f0088c7fd00da38a559116b945fcce4959442193631eaaf2e564ac675225a90f800b2cf36ec7543f7416c132f25e8dbc1d707016a93a7840239ef9102260328c70064d9ddbcef44fd6f0f8162f1b133e97294aa4c71e748eae6b403db9472ecee0015cfe8891ec430b3a1bad34ffb7482ca05302524aefd65c79c4a721c7316a800484e301822b1019f6b7ba909afd2aff5dcbc83615e6967ce42634d4865265d00b6f9df0db252cbbec27b002ab3be8b3bdd878369a3267b72f88105829a32460040403463abede4bd3eb16efa67b1d8e1ec5dc7a68928abb0e9d8ec779983ec0070c8f4f642ee4513944884abd93df5e9a8f4c293a83f166c162408ac9b637d003550c7c9b0d6f5a252e7082d768b4cf1681cc4abd9cb84decc9b8b1be521ee002b5e95429362135c5e8eb526c67ab45a3ee19f72c959a9818d6ca2d65d82180064d4cebbea173792d650a2ba50a64addb35aa06e131488c08f4e8a801dddf200c2996c20d60894982eaff68c33f000c6e3cd384f5e2a0dd3f484c8875e9ee6007c01ec4931811f4e6cb79812067626e886990c67182f8dce798dd2ae3aa61300f5f8e21d8499db87d18ff8dcc0a73459802f6d131302316f6cd17927abd38300eab5645a6a97af2e6f4cdf7f34ee5c719a504470b963aab4df6a76c799a4900063afb17dd5621e471e4ef65cf08a32473f100b3cfe9532f1ce19fdce7eac7600b4b0bc5a23b3a8734e7e83873d7fe19b80d52eb33695c67bb796389a1cc3810064c3a48d83a25d2e45098e385bd6831d7cf95b70b8e14c9f9373cdf0e832f70033320658a3c291bdc89d4d8fe5d1ff1db3aa33673197583bbf1efbeebb466c004537513b70adc36d7943e9038f95172d582af55e8f9e529d0ec4d685b9c80100c27d2468c0a26f836bf3c369f2b0d3623c42e56fbe9d3164f78eb249a8630300a66d0b1823f7ac343bec9b7d8ba934aae9e007134b7fd278d58e4adcd4d0d40092955b9313fa2b44873ba1c939321cdb7be1fcd20aae2b0ef08357ed65160c00329a682810dd0e49bcd7fc6e3d378cb81951c3bbce8c0f2e3e0cb8c852addb00225a2225608ae47d31d7d40e0173c0069e2f8a304507de1cdcea0a4f2019a1003f283a6309500f532e6bda35725385649c874ee548fa512801cfb54460cbe0006438ce6d4ee195805b9856a0c3a5dfc66c0eb2169dec80c3756a8fb7c2f5e2007cf61fdbf4a77bf1a613093cd620d6185bf17b8c01363bef220c92cb772dea00da08dcb0052a171a0ba06768a3be4a2790a1a77c18a61bc3e5214d4215d1b0002d7f6dc068446fff934d87513c4f06aa6f416966013e76c4d8a15f5f59c88800482f0190e28f5e4609e71d97b9c0598985c1289e04c1537acd1f93317ebf8400f947e76cb5977c08d65c4173c21ec551de38288d0f6062f413bf63654463aa00d7069b436b38efb00cfa0026c8959cf49f350a87f137e5388e3787e2d5b289008a68058b7c259ca5cba498fb97533c849dbccf48d4af5a0d09e9a28bab3a6500904579683015904adb3c1be7e41f9b472d6e156c7fd86f7303a99c5d7672e400129c6672064e722860cb3fda6755b3543668cf6670142593f73a7414ccdd47009c9b2f4d1ef5cbf561b7b7b045738678f8662c03ded0ef146c0a91cfb9cc62009882b6cf63ea88dc4bad4a6a0a6df4437a9ba06b4b6a3f333a26e5579b5e3000f9117242c7b9fa9c6f4ddff6b88f0c5ff7b4c679702953c189dbaa31e1a3730072a7834f8ce6913ea335bab354ed5ed35935c4bb5e22889093aef22a52fab600c459f44126b03ee6b06b69325d5842146351590537fbb3a8f776f00dee31dc00b487e76c33a6ccaa1272f7be17dc80b9f6b6737fcee2630a268fd2e1b09f6700eefa477ea0814530f3d75aa01260077790f537de7ceaaf21b181e55d315aae00eda82f57d0cbab1ef7d3a31d4a07e0faa638a6b5bd30d40bdcc2916b32851200333331a3351524972c79cc8d7e390aa4f909fb6f1dcfdd34ae07165c3ac8a20075c2c0426714eedde42cb20b2ae8b8c4b51e740b219c095c7ccaf00ae96474006b053988a5175a024075c92f27b5480551d3abeea1b6f4ebaa2ad0df05fa8000d91fd5f97a3f683c5fc80e1cd6d0b6ad7d61379fabc1a637bc00481dd808cc00315836e2bd558f8f275aaa7fd3c9f352458ec223548e399186e74f4409617c001b0892b839d9414c14d81541692f32d41374729eed5a83465294d33f16c7e400221f21542d630928f84c5e1f4cd5368794a1b7948e8cf530e5c2b248a620d3003d6c231b3b0cee9305848282733043b5fcef5a2c858f502e9993cc4a50bdf30001d430b4ad853e2093d2d281c8c85f9d78709de6edbee2aa7c9558afa3a24100331196679f3ace72a12644d7460df8d84e1977e7c8f5e17f660e9a4750ac7f008d964576bbc56b2accdd6e5e887d74b4ed037559ee0a83a56bff07ef6886b900b0263852598ca8d6131c3bc815b9efdf64edbaa97018e9b0e01f06e57d66ba001227d412763a939e5c59e5e2e5f698c0385705d8f7af37866b0f462dd2656800ec626fd7650fb83212f9bc5ec17754ed6dcec87cfec9028bfec586c558adb3005da773dcf3a1a8859fba2f9171b78d7c8043826c508ca992604962a135a4af005281485249f7d1829fc3d67eabf8e74876efe75070033362bd427444f3322400dee1fe00cd52feed81fb7c1c5d638078dd5b05b516bb7d858c92866675e5ba008bf5d8d19d99580c25e596145fb4a274cd3cf85ef9bce9a299dd1bec8c9fa000c1b1330aceff9b6097ff9c985c5245aa11d4c67987cb02a4cca9ed7aedecb900828a324d504a631f9eb44da5148539077c1783c3ca12038ebfc8bcc7354fc8001abfefc7571f38ae1059fa29fd9ca4fcdabbded6c4b9467984d47a3435f5be008825655c0fdda9ecc92170cb25d3e1b394669c08ed1524bc1d64efe17cc1cb0093d9455626b16581726a926f4354c4ccb7592adc35c6fd9d7bc7e82468c3b100885ca38edbdb0a5fbe57a2571e93bb3b46952c7f096a96484a57e94f1e68880031a31c93ef01ad2ab03bab813b55b4330b3dc47f0e26312df7e5817900834f00cb9af5e296fbc108400fa8bdd72bb99cb8df5144dec845f35e1d5e4b4bdfa3000725c4611372ccefbc70bf012f92b59907695ba8e6a646b1a214ae2224c5ef00c40c260489638fdb1b566fd78da3fc72ecc01a7a6e3db947d91eafc1e29d3800db472d8e1c6253cbf64f41426b7911fc1326b4a1ff95a0ecc01e52d0eba4df002d5a8ae7d394526714a5f9d529a2fbd696d2be1728d7386d5a7f42d8931cd700da04cae40cbe2b9284b76c023ab4f950632b0e526081a78fc0734ac9604c7b00b2d3a00b42e803905f60bfab533334eba1aaef52656573e1345e2384ac2fcc002e058f75a3e3faf2638d07e853019fc497970f0d528bbd474978ba75e1177a005e68e9f97883de87913dbee7d0b871f4fbc7df7082343def852f2eda9abb960078a72277ff51884e9d966b37256ae5ff91c8c796ef63c7b8b8af83864426ce00d7791575b3870b7ab6e03e357292b4c237d57435039acd16848be03c204be80076da07f5a317a4a0661b170bc9d9a31e24ef2157bfbdf0f2112bd91614b2b00091fe6cd0ef690db3da77ada28cd4dd086c21ad36fcd6cc0677522576d42d0d000897c5bb80e40ad076569dff6d7f046408555691d11b8d256f378acd6340f600740cf2b155ff63a15f614aeee67e0d08d5a2ac3b6fb53e4f180e5c951bd93500a8f0acb6533f7d4daa33600e068cfdd6b6f70b2b2adc9562f01f0bcd349ea000f36740b9dbd403e35dccc2f831de2d7ab4c174372afa92101e8a7601202c470064a78bcc45619f1ed57199f00b7425c1c71554e16b180615e14998ba246d1e00629c08fdada384816ec698333386f4765c51e1be4b171ee4860887f31da5b3006fcf1c87542c0fbb27d8dd94baf9a8942ebdb9e303ebce025a401289d316530080a8a19054aba1f5ffeb723097586a77f4c1da6f9158628e7aede1d88ecc780050e28a117ee5edd652ab82cd0ca018a9448fc06f836869d86fcd6a5c33100900eb3d6ab4d21853a7734ae022eaf2eb7421144812093cdb0f05c543b903bd9c0030315713010430701cabd2f635b1edce6074d97c6d968791cfac06134bd9860024a4bf416e6a273bcd528d17714f08cd1cc5022d2796a2107ab2ae52178812008f6462bbebc5f764de0d06b9bbc7ea389f5bdc2c27af8ef87225063be802a4009fb3cc5c572007fc770427e085514ceed453b3c829f4bb71ae5cc519f2348200d2186536ac44a8007d4e099ca9653cae6645604c8334a9fc111514d61715fe00abe589ddf25193188352613bab7b21e1619c776a16b5590ed735f1f614555c00a45449dd4c5d88f7b1de9ac3aeecedf407e736e7199e37286965c77113ee7c005dbc89561fec7ca56636c3a548613ecbb4a951bc0a506fe15fd49bb2d0f1f00073ff14577bc8d2b71854b87c5b5e7177fd447f36889390222456dce6a50ecf002fe9851da0adcfe9bcb6e2443ed2c996b2ce0f088a0abc520913b34ea13fbe00275169a8c0969d4c3a2da37e91ffff08ac194b07efee998ff0a1c5515bc6de00da524e2b5708215c6ca46d941f7977c16cc8527f49f53e0ea5d3bff2730d2600b8fd90185f32704f8e366ae92150d19901eb78db980776c18d2371b9e416ba0031bd4360236f0c6feeb9c7868c7130aff8ec652dfddb9610b3fa30d6d82b2100b079b453217d82d492143112be41ec32a419430c09a395673cb4315af99ec7009dd303edf30a9e7edd78800ddd1139746a0bdabd8a13e51e7cf51d0c7a08f700b9ce6a090589b0163ed48c3731a8b0b888b78d78e07f2f288f9e0eb607ce7500226e0093417cdaeb61d649e9efef5d72ae81eb55a798a627a15ec8505bd40100bcca344cd3094e1979202fd4fad61f87a0cf9db8efb25e6055071d8eadbbc900886476b2fa5e45a2ed848bd9cdc3a7d19109a0066327de6c2bc73a563ad68d0088ba90e8a45cc68ba581ce6fd31cb6bb7ee6d02f6338ec6da583573334ebe3005c47305ca5347bc5022286f44174c6d5389b5fd8c33188589c496c55bf1f290078f0c06796e7fc6992fb074b8449db9622869b5bfb6b08c60b710dcd99156400c3e5751f7d330f87f77c6f019a498560d888927dc922c064de905ca845b8620098c3ce25a403efa3349e16b45bdfc27ded67072f2f67b87c0707898133ad110066750d31e39f20015293cab9c855c8727793ff7315f7e1db7457f07a34207c0060e3033a929eb693243a0faa8b1536f0889f1ab4135c85bb5049aef916c5c0005c4bf117667db7936696c4f0b491481a999de8e69aa447f73b3ebbcf4fdb1500720b263648c8e71ec77e642f832d83a24df3bf3478e7c49987f021bf2cd8cf0063c49873b23f62c80191579792aa518497bbffa5a1699433fddd28cf7e0a9d008b5570313b70928a06918a6090adae2255fbf9a71ae313d2a1be25a21d2bf4008323b52e93975a50d9dfa92f9e025b292b60ed413b568e33d0fc548bbc7d64001f936b89b26d27f606476afa183545965131bc29b312c77beae8f8bca500b0003d5426d9cadfdf04468dbd1a8867b7c61e51bb0919bd4412583a2e052f7cb400d24b6be2d0816335f7cfe11c19e1bedb079923d35570ff95270a07cdaecd7100d884580b48371d1458dca70e391cc7012d64d909aab6f0561478bc4c3bb12a00cf1a1ff81fa72234910b5ec9b3684d4c4f3a91e3b02b44b5430836f9e8f80800384a91456f68b9af026f8f164cd7337bf6129f8d392333e05414452b3a10d300406da47b05af2d9c8f20d2fc961c8d06856cdb828e005a7529b900a3de8b0100697c0ccfb69fd3f45bfc5e27496d4a1b0cd78d43201f1f8f1c73d2b5b99802008e261958a6b7596bbc4ec896b40c32cfa2fb1e8287935c7123dc58c11dab1a002b33b794bddbb589c2a200b137fd9c5870987a66d33fadb9e3f1e05c0f23a60030ca8a03fbc92cdf94ba30bce12a9671564f965ab4f520d968f3ba87fcb1f900e44771082d919fc2c958d784d56f0bf17866234f9b20a8fe6765a4f0f62e170047252d5059edc7d8099e05a8b5d6c9d42ba0256fe4fe48c73a84ae98016712002edb2060758f2606cb7bbf02b2d4a7ce2686b3c47226664eaabf573e1f871800df50f46cd9fe919ba68f1023c6c24fca5a0a1496403c8ef61ad1d588a762e900c43bfeefeb0eca03902df731a1b6bd23130c0cd50712a5498f6f806b86ee220056d607b5d43d4fcc830c563519295fbd25f373d24b847e59330317ce3514cf00c8d536728eb6c0446b590c57a20ece6e4cd9c6e93694da9a895b747fc492e400ed03c6f039869aefb504bd80a9dde7ad2ccde76926f582d23ce3f90bf03f510069f70d110f72ae4ed6bd4a564ee74c06b24f5688623e91af320bb11cb0339900fa44fa5383f05f6156e45ca2d14e02a8392a9cfaa7216a40cf28e12fbdd5bb00b127c6852359f2068ec266139a0009b4e3cb3b15a056bce93e2c9d4a17a87c001d62d6498c998e3b019048bb1732c3ba390fffa42772ca9f148a267708b55f0011b9d4e691c80c310654e4da0135ec6db6d152fb8bbf8ff22d53221ba2574e00577b3a7d1aecfa5a3d4e6cf0e29659b755420ce491ec0683f7c3e9402a64b100aa266673243d145c253dea3ef1bf2780a3357d2bb8598bc9a4b1ca088ea414008f540350d34e5c8d7c4fcb3100f526f42c6ccb3c10af6db1ea5c300272ff130093abed4855e611944adabe1eef80a25b2252f5b16ec104f78de36ccb4624f900e5a4692cfe0668f7d5921e063ff5de945c1eb95e58b93f40fe16c1e50fc264003aa22f4e93d6a11116878cfc8b658577481e0dbad9a3c93c131f6ef53c92640071b1fe421c59354d6b74c70d3f0f64e9e0b7fa79b0d91b4b9c65dc6473f962008adb44e5daecddffdcdcf749ee7a270bc1ccca658fdcfab00e755f3f95502b00720cc072cb56f3b7f0b00e42e02c253550c2f29ad1fde5d50fc293c436348200412a5ad2c05bb3865b939568b7eb07ab660ebc3642b7f4daff7f10930921ee0096514ae8beaf30437dd55bd6abf45a8d38917218e4b40bf8c8cb1bc036d0af00de2cc1e506cfb53e4f341066614493fdf1493395799c261e317bf2694ccd540098642c911a5974ef1b63584c072e6dc7538d573efb44a58c066c324c8e5a5d002eac64fd6f480543e4405fb19881e958c6c06bf7bdd02f27c1e7490cb2c91200780d04d9af8412f53b6e1868c48d26781ab4b4eb70eac9ab9d3b7db40ab437008a85d1a294dc4fcccf5deddb96efabdfb09380180379535eb6c9fa1722a2e4009a7911c94b8e4bfa9e9f40ddd8e236eecbb3417efa1d7a8076f625caf77b37003034b2f64e8fbbd72a17e04dc25ee19c94eb616456bc2e10d53bae170907a80007c8e97df6b77c91a62a819314f69359e63e3c7e4e06699aa43a65094966d700b2faec2098dbd9a5d52a692f187226fbd1834b09b0b91150f8aec84c5755eb00237eb62680058b97aa89d84da7f9dd8ba50f907648ab87a8bb683831726fc7004cb7cc405065c992fad800694fb362f394b89e35600beb2476abeade1f492e00b18d7dcaca6e43db9c0cc9ef49db5ae6565562513d1390161a34423595de6400059931eaab9e926918460a741bd7cd1484ddcc906ee729b53c8f261f75e36600f3dc586130df87b1e10effca72a2beeb2c2302aa5ad98a1ea0fde9c5524834001538050db7b66398cb0ff5cd532c17a322db357b59c0e50c8e5f437028565700448734a735dd5e8e5b723039fa0ff51136a6271cac8f2d9c8cb05219756720003541940ecff9f49b99161d31fda06fcfc2b539810ae7020f02d7da13d33e5e00e6d4944c6d84b38fe70eda860fa1f1fbb3bd5712f30a42b95f3365ea692ee700e82e91abd91ff48d01ca45bc013c1620938ea9e6a03c0fdeab1961b630dff500f25279e841687baf5f16a275b22f44b5b7ef0263789e9751a58fae1b0dd4bc0049cedce328bf01972f421a9c389157270ed19491baaea7f08f00a68fc922c100a8d70652b81c95b1029e450e25513024b179899e95813c6ba17c0c4ca864fe00ca9202263be4d6a68f8a00d8932624ac23519cbb9f74c48b786b7d9175337d001f1c75d11b2ebd869031a0696ed4e87b0e4b27387b8882de10f88b57b9b22200a7c4e43f357bb518a9469e6644ac4042a0fc7a5e9f86ee61adb71e666890a400483bb0547ca44adbf1283f757d2787b5e2e690ea82fcee3a7e61659e4ad9a600c514cab72b2e72a30d82ea65c5221b27f3c076adc8bcc901c8389aa9d3a05e000b446f93a79d2fd12aadebf574c9351384f4784108f2769f911e8b6e76aab2001f4228b4d17bceb339626a58f3c75b7dcad89828f135eef4db4fd85caacc4a006590ff45526fad8e3de0e48976484c68c85f684be904d4b2a1202887d7891e0010b1f302cd1948ea98fa629af9a435801ea775b2a93f6998542a35538f89b500ad1cbe39c0fcc4dcdc3c5ed58742afbafd7f923d3813bf777f90d0a0cea333004339db3d6ba744ad00f5b789de85019cc67841963914f5513a2b5fe2f37dd0008721bb474e4f1ea67ec1173c0711d687f43f77422dfcbb998fd7557c2c664f0094445ecf9f8430490ed94ba4fe6e5549cdab73bb115a1e2279cd3eafabf2f50088477e6299670ecfc22371a96c20cd56cdc6e43aae514559e9cd4238ac75c2009b3fcfda6aff42ea345df9fda3fa054cfa07a55482cd22cca8602099d2735800351329761cc50fe0b4152fae31ea92c671e1ec861f642e8ecfffdd2ed166ed008a95b34841d36c8f638a11e5c67c2e60d2e9e99b867cb93d3ef00787761f4900a02abe76fc599a38a30a410e8e4b94282b5974ee26a39065ac5cda7b923155009130aedb4bc30cf0c450ab661fcf5e1fb10773600415d1f4511003071678cf008806ffde8608e68a8b0b517519d92bb3e4f8a4da972113df25e2746ab833580044b723e30cc0346023ccc01ec6004c9b7b3bd1925f24c2a6dd9ffa4a90ec48000a73451dafd9c19ee982e02b9f2940e2989266cbbfa5326eac23c851271ef200ca7064e787aff8afba39e71e6e4c88b572e479911c8c4b937c0b17843328db0073ec5c6a655157f5ae60b6ae17e3986edbb5bee53a7e91a0b7399dae23dd5200353a818a153acce8e008e779e72588c2f90d39e0f0badcfb7d86c4eb4f5b2300a167b52240b191f1da21f34c6b015a45119dda1eb3738796311ddc121a061100fa65e57bd282ed29599b3a6d22720612b86356591bfc5a4789d65835a96d3d0037fb72e61df4772aa13900a59e80577dd1f1deb22f0b197376f8140586481700911c5737c42233324110d29d03cf07943c0110aaf26b275b84b3e0854a609700614632084c0959954640f04b67b838756876504c3276bd16d77c831632fdd3009bb867e406e24365ba77ba3aaec2813e3f27e9379ed86343a36f11f0281455002db45c52c08cc38fc070fafd9e43bd5d373504bf120575348cc4dca0f05c1c008415632449db6fdad67759ce7a035952f0904dcdca6d58cc1fbda3eaf7e71a00dc834bcf6136f67ae5df0b4592950ef76393add0382f809c0d6d20901157860097fbba497bcd0459746b3f8f476aa8e6b51ab5c20866a52990df7d8a4d245900b47d600319b07fd061a6e0be4178891551bf29652a9d9d3f6f69fbdc89e26d0023e26637fedd3f3b73bc7c81e0665a2b446d278a1ce389109672609b06e08b001037669a9582e309680cbf3b8f3ded971e248decc96700cb9589687a6447510042d384888a21092d073ca1b1bd08c0b67dffa502f9bfe6953f24e2f8b727a20090b06a709cdc0793d7333cf2e256af519ac9ed9109e6ef5d9e8d27657707cb00928ddcbfdea3e67b003fcc8e1d533daaa4964130461f73622fc83e0026da2800133344c888f15db7a7918c51ade51bc662454053d4d12af2bb2e373af75486003ce433c89da9f3ab199b8e132e1e4b19a9455507872e26f7f84f96a3182f820001900b3b0950c8c62b323524b9c374ed58e23dc5f55c78238088f55c4bf3e50087b9b3679d8394e040f9f6925835eb87ed8fb820ee2fbb358570df5e5bfb9c00c9418b60bd3f368d3630365a3893658f2fd26faa4c53cf441eb24e26146b6e00ee331f36c3857760bc2110304ca274b76a66ad76998c9b299e72b3c44fd88c000f5ce7eaf53cd10ff589a6ae9ba320f3ab0614fe344b67694f48f92b16eb7c005ce0e9394f63e2cfea6a19754b4e7cf0a8cd64bdaab991029f0e6be3a0112200848bc5bd62205a19ed441b98d252b66464fa98e3eea68f96e31df6521124a3003135bced2435e192ee1ce377e0bc8af6b697e6f9ae66c77912993ce2ff4bbe00c460e22fe469e4fd13e94219b31f47d8559f4f5c1214626949ae4fbce755360072386503b29d3215a8526a8a61b7ef44a3e7941860ef04ea3156ba75288238007f7cc774a06607e1140379d7589627102651e0b7aad144f714dec3b01da98500a69a2f2144269a9b892c039a5d3193c12bf7332f7cc2f3d4c661792649cadf00eb1a24f0c84dc1bcc69c0c5f910f9be11939ad8185a2f8f3b2e4d0b562f685004a899e3cca7173cf7bf2213725ec3eb91e4249288b79763ac1c86fb9f1b0f300ea08df4407cb9a44f49f4416885d7c435c88d8d3190ec37ffe3e8c408bf08a0092361c422b6358d10481c2c951838d3abab1a63787831fb88b47079f01956300040a104f7ef91cac565ef5485a01249efc39236e917a5c13116ac8c074a388001c06311c93e47d37d97ab7487b18c9e8d55120c117f2a9b4b78475f05927b6003d16e58348537fb0aff9919e5a6298d812ff87fe8dac6bda72370ffd94cdbb0067e355a5c658551661ba9a059e6a83575ebf3a14b6677f6a659316c8be65eb007e0587c4c630a749ab9dd3d57ec6e91cf2d720bf474abd6a109cef438ec9bd00f58ffc3749247664fa75adda576a3731729445c9953fc42d8b175e59e8770400645592f023ea353d076108ff7244c07539b76c5422bed85ff1fa0e28051a4800d1136adde666333ee4cac0132a77e01001398719f59463fc406f4dc639042500a39c566503d128e0f7a4fd6ce246b6d401ed8159d2f35efcb4096aebfbbe7f00d6aeffc425e7bc5dcd402795ff625f1ee46705d5244acd554ea18d22a4896000f8c4302a7cba97708a0e314f9262373dad79c42b8a91e3d8e00a3a5468ac53006e7a67518e11d4251ad8633855d0a32b87b9a576f6955a224af8950b5bbb4800c747452135b8d81c1c2ec8970b71a365610a77214106ba97031d2ae35d42a0008425b82894b83baf9fd13727a91526cc46797fc16685e1ec36029d8277cbba004e93d280667d745928c426ce64cdbf96a9f38d85f86f8fa4e92b8d8de1498b002bac1038491390f7b75ac7376f4c8c7fa691217e4ba46b08e594309baeb057006f91af13040172db0bdd7ece18756b7167cf08087bb62592645491125ab0dd00a9d430fa1959540052670cc460de4d56b2e926771d127ef884fcf392e4209100f9ecd0b13363f1820c04e8c3d9e6f02dba4db5cb2552aee236f084a9e4191f007876cc021656b1eda704d8f9d0c5c97b188aa266d8eaf4bc5e7be22bbed6a1000656f774300363f22b7858ff346bd5c81b15f58a56306bde9efd102344ba7b00585b1c95b7b3726d17aa74304a5f792cc892f44f4e3f66015c218840775a37007b085cc4a8bf20a8cf6dc155a7826a58ec106715cf3a1a2e2bb43bb33908af000b79fe900ab9e339ae02b9648a65daa9dad161db862fc720055d3028cb1260008b2f96fd9689a195fac130ce2df24cbc99e3bf854a0bf1a4453b588082eda500b3dc793c2195c613c46376db125773d3992f747f0872cd7ddead1fff695eec00a85bbcedef94e8cce41aec1f4813c02532b37e3c7eb2532bb38f5954356ced0052c640827386e6c4aee5a79dd5dcb89b4dfcf623251bc38acde61e78c3fae2000495cca4016bc92ede8a18a7481a77c646869d1808b96d65cbc489520adc7100998d4b0dbf521f270c4870801feba575683689a3d876bcd0a023655544c424009876d0b13daf87cc1653c2ba72c7f29c61ed47855facb4ecf4b4e56fd0114000455a25cd98420c4b8d7fedab0958a7cf8b1d8d86ef251781db337da5cd3efb0086514b7f4eb2adbb42a1a147bdf17d2aa69c203c98113374a02f8de33b3c47006ca1bc92b3779c4da4d2dd639c42d4c9726cb0ba07ccee2e4405b4fca03dcd0007811f07a03a21240533dc17f4e1541f1762f824333c526e5c4b65082f3b1900bd6f38da160ff0583d553a563308a2a324d92733826b7a1982c397e919165e007a560ca44137ce0b9c72331d4dd7b1afba7b7ee430823bc43284b478abfd1300c4e447438e98d316b7b067eab1b47a6dce55f04dcb0b67120574bb9e7917e700123f6a4ec76e8a956c31082a7cee0072b9bd6935de41421a6bd32f97f004ca006fa208e17469e816d4e310a22c5197f08a886eb3596919efb5adf7c28a916900c183001576b7747a256e06e0a8f0f00fa7c311e346816d934015487d9f814100e22da360614d5361dc21828f70d20807962a76e658110eab7f928173b36f770095c949875defe28421351145efe9b7433c37e1bdc68ce1753963b18378f7e90070dce9b2db51e9750c16061067648043f8aec9f63231a7517073f7d2bbc859007a62308286ac1a3ae850baff64b7f6798b2ba9137c250f957688d7647bf083007be7f8b3abc240c53153b8c8cae81569b16c5c58e9432a992e4b13d6b0d6630026660289eb341c990c60dd9dc297b3960fcc9494bcfe41caff47a622c85ebf005eaf188cbc92a859c2161ea99d48dc0701e01a27423abd272ac396c5201ba400293f1bbff53d43d59b9144f8a4b98b0e4ec1abdad06e1e1309b1bd7cb0f818009d30e032b5b2861997bfce9798fe895ff38423c83e4996558d1d30612cc3ff00d689b1dbb82f310b3d3ae9dd95aff74b156dc4cb07b823effe2e467d3158510038e3ea68042c4c9e10fe70a49d63ae25a5ddb8af737968948a73835604c01300a84f6d70b25b096ed22eea34226db1c8e995fa42539da369c15651ab5e78310044a232cfe58e8204c86610a55925c12af166aee0f9f1130cb313ea2b0c7f49005ec40432d6b089580a0da72ddea6909b2b64905bd973579271540675e1f05b00ee92bca2a6cbe87f0ecfdb4f4f18df7514de8f348bee843893628209f4c7f600959f663aa27a65f6e2a28edb2e5c51ede321beb70cf78470a7fb0113c377750080673ad573d658d8587505680669d7e6c4a9c92e00e8004daac63c4747ec8f004b1353d10a6e97a9ed48a47d419a0e2ae020ef8b61920d9849e6424bf35af400edac8f32d9a015ba37121231affb7651ac0daae18554d8612c059c4895a4a100848262f6d4d7e0c79e2c8189e4d16d0db6dad38695a4446e9c41a9a6a15323003667f8cc3ba657b997db7fc8995861dbfd40779ad0015e598f12efa880ffe700cdc1e051afd47fcdb64671ddbd6b46cdf8f1e6e10d676832f1b5f174ff675a007d6b213d55f23db80eacdf96e7efce4daba2992f59a6d939c0c4f6c03f0b3d002a7bfe508fe56051517c5405d8ca76e6dfdaad3513f22a79255ff9920ac60200f5aba9483df4c5481d94af5a53a7db00f1254fe6ad5ca2ab0d99dd38dff8ec000e8142392e9a5c92ba228bbef782213b957e197c5ab6293e1994cbf66729c4008922353cf5a15bdf903b916d20a4bc65ee9bd9a8cda4d2d6ca66e758d6bff900c4b06ce05aa629e505d5d7e49e02d73b3b444792a4450e1027687d12f26265000afac4e71e8bb4dbae7d85e40cc0e1adfef9fbefe5aa544f074633a1254a6000ac310a79f974bc05ef2ba62a4db82ebbd90aa2599b48f0665bcb6a16c2080f008aff0e47af683baa1507ab9442f9f46773ed8b97cfb18384de7f242205c931002cb715cc45a3e631c7cc0b0f2a625d24e0e8549e2fc43df5e050a0b80e4d7400f62641da5eb99bbfeef0d179d0dc543dbfaeaac809ed18f1a4db227626f57b00ae5823aad108073f7194dad3dd0a38735ecf40584e49b7aa66937b6022e1c300c2b6907e3583514ad68407d838c2d063396a112aca8d1f582a7ac666c8ba9f003fd46429e237e322dafe25c8770890c94b2d7febe1ece588f2b6bf5fe0c17d009bca394665551d7a171a787eba73a81bac22455b5425d524b249954ae464f700055bff126458591a6224c35c568f33b20cb1df40176bbd5d247c944220b34f00acad7043822e0c427697cf985dc7b9b398fb0894c44b34ecea128f7277c2aa007dc78f9f8a5dc929a7b7a2f0396b3299dfe438652b9b484d58f274b7402c970011bf0e74fa00f3951abb95fa71f027f044bc5111b36e18da58ea51afdbb5ef00dd7b3e21fad6f670c62848973472fece85ba89f101ee6cc05dd70ad127b28100a46ee331f8b491b711f43470a4fa3a92157f646ef0c5bb64ac5588c6242192005503d83a75171c555736fbd03bf74ca02e26f1b7d0f2c1e282de6a59965249006c84bc1df3caf7bf775cb215ae9467d07be588631b6034d8c1ab4978924b1900662402672fc2b994e8081308e88147ded3052db4b379d25318407956603503001bd778f8c20c8b2e184d6a149c63b25ebe3519ce9a6c0d0ecf93ca7a72dce700e1fdfca2406cf73d73e86bea6b5b8b46c88de6d3dc2049c519fab42a076d950006395bbf7fe4a3f3d9469891a3db2fbdc113c9485947b57b068492a2fa6a6c00e562ca3e51f5386e0df12c4e81cb791e8420bfc89fad54dff104f533f22d7900517a1dfa0e54a2b1c135322c8a71ff6e3877d66948d0b80463270a93ed4e2800730af5ccc09b4f878ff2e845b8cf3a8803cea2ab385802faa655057ae0dd2d00c0073b6f8c6038111d7f23973106cd56baa0973cf78e68301f4ff636c933c6008fcd319b14d0dcdc25cea32f3b522ff921c5282e083b821c29029239b9296600bfba9c6fe38922b468af3dd881774e15d0a647df8e8d71d65409caf29a419200744cb2197498e4159d7af8d0957c94326606d407899b64d97165da9cb6b2ea00ed2474df8ae15c0db1b4750a2ea0da1ff9ba5e0495645e7e0b89d80ba4cfad00e886f4797e6521ce23802ec57ce7ac3c33b79b47bc078599b8fd6ff28e28ec0082dafdedff092de58fd346054a96aa313d68816d24b043668bf9379698521e00023736538431ca4e33d9b0f60291f60e132eaf2e0b0426dbb71c052e41749a00fa9979f5f7d34192ef4111b1fc14e6ead7a3a89cf6c37fe792e4c3da2f280700ce238926c631bd2f158f342484337677dbc32c217382a813741663824e38c3006f576d6d257985e56244fd9c5b0efbe2116b1e29ecdde35e91222446aef30b005c3bf2371cf98fcfff66ed26a1ab2c7b0d27614657579e297795b8346078a7001b130d98ad01e8b8a7c9c561a196b8f4605a752aad7561881f8a2fae98559900af134c442747b0aa5b3ac005cd633e949588926f57d321095b6bb6c2e206be0067c3b37e54db47f213102f8d27accb312f21d3e220223a1ffcf9ffeb546b4f006358db771f6346ec816ed2ba256cd9fec32482272e4d6e26f4b9d5c487983800bd2176793c413a1be703d9b6e6faf1476bd9599de7bd79b94c8ca9ef4b40fb00b95c64f58107a5dd6973f79628f93a3cc5c5f299eb08ed236d139adc23fade00c61e7740efd03cf098a7b4667608173bea9a0ddd657a9c9bd5a5970c151608008af9c402d8e7361255486c55d3dc27360d32c0a137cb98c5754ecb336d4f9400554dcd6475ccd1b53fe16977c909dfaf8a762c2b873626f2108556928b94180023621f29456243c5292dd2588ed38267ad4441cc3b0b640b369db1bc2547130051515513b16fb586f044f74418c06ae1c7365852ee242759ce828ad451b9e60064c502631dd61ea2f09715f12bb301ebd9768eef1b6ae4712d87aa10bd26f300e9c212a07ef04d2a7c11b72f035d393e4130a575ca93d2206c52350559fcc700789286b422be5deaa3dd30f5c1613189a725307c585b84aefabcc61dd808dd0018fc0549da6db56b84657e0bcdca9bfa0bb3ba80ad6e9f7b8858bc769596c200eb48f4a9d2a3b16f53aa106ff922d5d184f9a025c322f5edd06291a23dc5b60046292fcb6c08580499c24cf412c37b2faa9b420101a1cb5ae9462356d551a300a4ebd51819665f0a502a29eb76f316b46b45eb6aa0fafa1b96c4bf53e8a31b004da08fc7b8102309f78d8c1b272ac965f81b2e8a01adfe0fea41391a86a3e10011ac53fe56d3e6d7ebbf43aba0a5b4b64e79f6f2d619f8f976621a314c16920093d760351c43ed7c01d0dfe6666bc1b4574caf15b3582db295e4d5f0d66c7e00dc8cd63cf4910e6c70200e055693528a0f324c643f7e90e0dd068e407a4051008f86188033a3592156ad69109fee667e7d4483842e19cb6d983105c48c2d3a00f9fc53bd81c892105a1256c4c2f268acc580806ccb4a7bbe9a8cae407bdd670047cf9b321369bf7cb1935766df938c1f0b4cc1140a84f0b8f476ddb492067000c3b2681edb6f4fc5e144cfc5b96ad0dbf11ef1a841438220b382849b63c43a000922a3bcd27935bf699ae1633604753a0e9a0e9d2ca45e8db1b3c9c9afbc0a0036e3cff10579809b6875150739c0c7d3e6e1c7f9eb08fe4923a406c328d54d00fbb21ce9465ea0b4667df975438771a02f3193ec9636e616b199dd624d0612007b9c4159fda40bed30220f9e4f5115fe1e6c2146d9b13c8ac2404df0cb59b000f0cde7bac6486635e9a820156b74e3bad3ce3badd62972834db4abc7abd41e00528a33d9faaefce0988316996a11656f90c68e519abdfede6451aec590da1700733e05b5c6f87dbcce32f450a15d4b24bbd87add1d4c9f30bcccbfb0022d56003ec61c222f54bc54b47bc7e8f2491d3616578e5b6bc425e35cb5c714330d1e00b7f8d6accba392f4183a0a63d2dfcff413b88caf0674132c4a97a18bf7bf4500ee701561573edc8f1a23590055bdfab2d620b5389fafd6b00b5dd59f2df010000b234ad5fda38ee44f714a063d823273eb9f9d4bdc6130b2d97ec702cb555d00bf6c01da694656597c54125fe96b53207790b73901024a5c472b6e131acac3005b563f7d71661735a69ec0778336e215594ef2739a66c4a97176e2087ff86c00d08d10c8d209a4675551e023d7746ce9272528702fca0c2045740c0e7bf74b00b1db20dcb7754bf4fd5b241904d0d5f37d85ba97cc5c959397ebcc7fd4c36f008c2e47227c47536b280f365577228f2fc40198c8b33324642d3a35f0efc06800b9000c9c0e4bac11c65953b800a1ba24e37eae8d0becb687316c31d64d16a90031c783634d9fe5fcfe5073c5f7f31a37715776d5f9e0003c7f7dff078a2abe007ae02ef34f867b00cf475e1dcfefd1973dd6c208598e59a1dfe1c5ebd7e05d0027d636fdb69d5c65ecf92834390caeb72ac86f6dc4a337684fe15e28464cdd004de354e611e3d2f1c75a70b09371007ae5dcd868d8848303c1bb1dbb187e36001fc1f15ed22073e673a577420af245e7bf55c9efec9cc406b0eae04ecbf8cd00859205136e8836ec6aba210818be40996f9801bae8a2045d8fb62a64d05e2e0003e8d4ec6b88c07277c7cb0a86f3454ce5215e1300ba5f75b948e7be38efbf00d25cbcacf221db0ea87855f436df80362894511087cb5324e804b59200dc0d003372f171d9e832d681b3513f7c32a3d8a467cd15fdd1c20e9c790bea1718ce005ad9fa2645b7d1d317b955b6cf382448abab7a175bf9a1a936534f1242a4b0006eea2f86e549cd98f0d1f572e0e775b9f79e09f5ede7f708fcd249171dc44a005d99ca461ee2ecda0a732577b0de014849c8577fd3d9d80367cfad04636858001f7cc5b6b232533ccbf4f939092e67df333dbe9f95d17dfbb0a1a3ea37b44f007feed688051c9e0fe3b57e131207a8483b077f0952a779fed4818cbf1ce26b0090a0ea33aa74efb56468fa5a7b2f359520eebbc98da529b6ced9c22673ae0100f58d985b3893e1b29361d41f755ac10479b3ef1f42b1683fa5379eb445a653003463a5376120a1f5e8d65b81795fd04a33663ac717d747ed74eb792a04cc4c004e97f1573bb3eaa7d953d4bafa9bfe55d0b258bf875fbd6e3222b21a58da86001ab7daf1b75c6b7449a17e96c64e4fc336f4f8478a112280f60cd72497fb2800eb5b750662fe18a4fe3a314de4c5fafc505adeb2725db50c3cd4ef3b18889200fec9a6f52b1adbe16b60034f79ab2061c7925d711409196ff239eb30075624006ee81b17b47a343c32f06e2999a3f1dca37d6bf169e2cd182436a2f76d886800027c377eb312b20d31ae569e51da27149c291f41c9268960c0d0fdd14d1802009856157cc3d8fb3b0b3d23d48f6356d2bb8fca9b86253dcce378943bb006d200526e24f6d545694dbb78dd5b74a75a8546a6a2a55168ba11f5583e25f8d2d900c7e61eeb27ea720005d444b833278cc7569c5a1318a5b39df060eb3a430a1b00c14d270ba0d14be95dda43999257d7b41526afeb56ff0c9aa9c335ccf6d912003a5ddce81f610cabf381c7482b4f78ce605f6884e1715672342d5b7446daaa00c286faf49eea89728208497c31357a4be3e01f6a2b81f84d9e52ae6044e100005926b9771fbdbcd1d5fc3bba06ceee0fc63a8d067790773c3f7d715dfe9f02005b24a2b760566a41d50a92df2b22169026b8eb5d2e899799ba3b327cfcbe9e005df8554afc104da30152435ae0731e42dcf8aa73b296361134fcdc5e454a0c0001259b465bf1dbfce43574d3325374bddebf4c8127b63eb904c9437f4f600000ad44068271df18d0a7198aa2d77fd28e614f2c56890392cab945885a9e05b000ba19b008ad2d1fa3bf3f2638f408be5404f2452bea430d15b3ab1828aa99fa0023e12d5a70e2fd0f0a27186e4884b05d70da7b462d38bc32985f39867d0507003f39d522f6a5fbadd01a5a2753488648bc04a8073fb0a8e345ec0f38b17c3400a021e809469a73a5df79c39bd38e69fffd54cd5252ff0ed641a702bb726bda000fc64c091ff7205e29a3f458e30fb87d33b7477821671d3a5cccb9b2120953008abf94d313ac4df3cbc90fe81ba045697454de23c80518de75215f615a71ce00b39df157ede297efb8ddfa5de5f8e616615513b7b0d87e74514db1a92eb2f800b7720aa42eaf2b60d793d40ebcb74dca2b26a97174921ad9e2e9c0c2c833ba00f87bebf18fadf1488de04348f588650559d7a4272a1485285ffd17e100b2ed005e5baa90eccf9617c5fe72e3d9543d970dc46c665b6509112b1441429e62ee001e9ddb69adaa6bd21a73581a752cb3d6318d6eb9b20fad66cce537c8ce6feb0015fc8951daac085488b0fb3debcb27a9f7d834420a2d48c2ffac60cc6745bb00b2d3f60bfb0bf182da1addf790bc8b5ed54715f134c039fd5fa21362aacd1600b76c1b7dab22a63300b01d5641523cb1aa5a4900afa6dd8f6c953df3a670e2004bc024625c4c94e4d268bfe211e12c16acde5d5a9d1518e7934de0ae72bf3b0018753ba2b41715ed923832c87a5ca29c9512fd4db55fa8c790cfb923408e1f00ad0f2e3888bef4a30bf4adbdc41b3842ed5169d848a165d9f8ad3269665ce40003095965593850211d1ff802c8036009374faf7dbbaf080c16659910d8002c0058834dfa1e3510f3b39c51ee8869ff1da20cc9fd9e28370baeabfdf373134f0028760e11d9505a562ab4ce350f719c2b8d2cac122fa3be1fa3c34a8df83eb300d31a7628cee9eacb4b2672e98be63a752751923a641324d19a07411d5b9ffc00b928cbb9966ca05abd5438c5730a3f86e54ee6b62723ff2fa8765124e52cac00226cf5d8e3ce47cc78944eb4ea3644b83a05112694c4eadbbc436e85c0d675000f9c2c3ddfe482554fbb5d35e8debf54105d5e5f69c90b0391ad5bbfc9e5ca0053b2e3bc3a5904132cc97a135611453598e70b54e30bb1ee8ea5a1036c6e14004634c2174b0e7438863d6a6d860bd8316f9f07d4b0f83694e5084a7920060900b16adaa85fdf50e4e5420e1f539082539440241e3ddd5cc8dfab6f407c3edd008a7638a8817bae324eab680a32ec0b074a6840c4f54dd51a8737efb5031ffb00fa4bf6f4704009ad1de205edd9c2751785002be30d5b616c9ae1a2d0448616006eb77b49dda8ae1f23163ff32be05bd72f07ac7225d9e9384de2b1d730b0c00048b31dc864d7dcb9514b6f05eacdd004b3a592c27fd4b4e3783d8e7d97a01f00c3d62d2f2f0998a20e6cf5c483e4d06eba0bee24f362bd2d64c46d5d5b885c003d8568a58392f1c06b81dade6e86d7c67cd6482d0c9e0be163d0f0285eabba00b6d7b0a57316b07c58bb45a338eea4210d4519c424ce32ea32726ed0406b570026c057d817cf04c7d691347a55c1f9af870507940acd79d11dabc38f12281c0001ec5b0e1d7e3d5fc4bbf1aa01d758cdab1c38ccf4a0e20d633bad7673807900a593c42dcd822aa15f2fc26663461ee1b44045674336fcba3a5c7e950fe96100794c0ea7a15ef150234dc23422a167d335cd82f66af4db871953c3c795795a009b1b1d3d0d87cb28ea91e36859147a80e7dac25ece86dc0701bd718832bbba0009b6310f00fd52a56906076108196234cdce2ce2a423696c613b6bf4b238b900ee53d366b947b229a6841585a384a2a2bb335e5b3242dd7f9d8df72474009c00d3c52fab54c7468c77558fdcc1aefdb17cb41afd4fe066bf740ebfaac2e3b400dd26638c0b83f6cba1cc545398c9d2009468d598ed098b1f89c983110846300005e3cfee0ad5630ac7b168284afa89b20c9c66a20ae85868cf87839d38b8360022d35d647d3b2a9fc4823d32e006cf871b192abe803b3b87b4283076dcd974009f8c1af8bd92daf2a241a995357ceda3fdb6f5ac95942bcabee4365f98b8bf00b4c488ae6af509fe80d0c5ae733225f79a8c514b083a5696f4f4bbb1a84be600b0167edb6dc2da95da0a366bd1db5da8f9ecf7e0e56f0ec37775995f3f9ff200b9eb3d7614d9443057d3f2e8867a8022ddbe2435975383a7dec65dad96153600022094bf7ece7f1d9f74c8c17580f3c4e2e3235c867a42ccf19acae01b1798004eb134f65b8f656390a821ab8bc35b47ead974864ca07ae9fc93593d8cc30d00653372ef076f5f0bd10b354721dddfe72150661a3d1252a7cf60e78289d9340098d2cf05989c98a727b618ed960068c2e2a956a6c55b8b98acad060f7b2ad100144e5a0d93bb0af727804177278f811167428d46655f341d05f4a55a2eb9da00397e59c89ccd5a9e93f1a0695169085482ec54ecf3a49a2c9926f9f2794b59006148c8d5e4daafa42e4cc56ebce255495488afa59f23c5a61cdc5adff678820082149b8176651b191222c58252f9f9175c16adf502289f91b5101830abe575004d3a2e01f7be594d7439715ce3eb0c3f02cbcf285288eb40ec60e34eb5f77e00e5d3b84c4f23c1acd030a82908863685def28b5a8f40b0243e21d6ac5b229c008ebcb27ca4fa85eec2717dcaceb776f05b5e98f19a823ba269396f53ea5a6500b4bb00a237920c13cb2dafd3ff92d880ab70d8b2fc23e2f3162c072d0ee36d002201be6c06558b72b9aff7759b14bebc99d16b4b5682cca30488cbfb936a330088d5c6809d17f422b454c9a0ed4ba3a4ea0c9f2b93dc1186a514dfde8171ea001e0266d29a7e014516ab8344baaaa1383f757f740046626127a4e6e768b01e00e8c3b26231b166f6ff8783fdff400baa69c0e1c8c4882bdeb5dcdee8778d73004e70a67aa648bd6088d574428d7162498e327fcbfb5f65861f90a0195e4e890020c5051884bfb4e5b584d3d11bbf6821a2ccd50aa0acfc684f20f4e24d1879009b27532dc7cd585f561f408c932e19ce47e5d2453ccea9242346c283ccfebb00ce13ef33bd29a41891019f3aaedb97b0a919180e811de8941dc70ca454cc34007b0fc209fb9b0800c68b5b2b99909056a732d6da7e2327eb8d4c322f31d0e800ce2b6cc6b077ad4a483fbe5ac93e519e56b8a664ece533bc994f906433b2db00e8589b28c0c7f1512dfce4fff52bc4621e8660aa163b4923e127025e5dd8a600494ff8a82d5e1cf75806a9bb386ad64b911e10b0e2cb117650176840774c3b00e7db43b393c6e2827c10cfd226b6856bb83bf308d5b2015d7b4f0a3e25b99000aa66863abb96108bf560f956affa1169046005fcf3f5ef9ac232cc4d74d68b0010908afbe007e5c95f71d013b405b23ee195c3f089fdb39799992dcd114cb8006cb951bb6b0e358781e727c7ca5d740b574d4b3014692af60e7ab8304d2979001c7214bfcf499f719773beb02719a3a4e9d49df98ef574d0bd55c563445ada00efd7b2ebc08285e47b5171a8cef4962bbdb37b703339911e28a19055708751000463f56cf453200db9a99104162fec851fe08bca4f0af82a7bf1913714023200d81f21b879233e84fa16d00296a55d9c0cdccf7f4f0eea0faf3523cd391f9600da9ec72690a3c04c330e02406c8b4a061e47b45088cba8b86176ce9bea7a2f00b029afc680c7cf5d08ec197c87500d7c2ea185da0ca5ed0e213da279449a3f00cbe6fb1c6f46079c0df6eb79d6a3ca3d95c4c962fad81b0b335fb757f596a500cff3a6a09f501656a820660ffa2545d9464782310e756dda74fd7a37d5809b0075ec4a6bc2fa5aac9c7dd6a8ced822677d9effd61be30ec78f1c8ec4ff8bdf00c7e38c2489bd79662c20f4eef9d466521cc0e748b6c2ccf6b2f030489b788400b3f853a45a84290e7b1a0d85c170192b89a9ac8c2aa2ca63c49f2e2955089d00cb6122c706f87096d7e9dc9a00fc1f2e74bc04d7e5beabc56d0e3cb3c3c49d00d1841eaa82c7e22224fbef7bcd12dd0b14d85930f1394f3ab5b8c8f8034b91002789719585c73b407b04197d63338ec9bde13d2071b06622d9f255cf0b4e450098096d83a445a350ade4a2935a9be4ebb9049343eb69703c226fa2060aab6c002bee494e73a11ca294251ea733f4911729442566d07b0a0d44860e932b9a87000534c644a779ca005b195a4cba707469a0674198def444ee7ee187a6cca15600985983218998b66c2bd5d28af30fb557a4b0c6112f9e5944004f0d66463d90004ba161a3c1e86aeb80ac649bce00f3c98e1e9463cb9becf3b7213f2a493f4800d5e6de0d915641dd2265b47e0d4e3abcc5b47ea395015b7791003cbdb3204500d45fd725ddd0829110b48a5f36e5f632934d07a6abf30b824796183437aa9e002d1bce621a69334b88aee7e700a852109c4502b7bdad293e1c6a11b5481a7900486f50c8e16d5096cc53e8acfb5bd9d630e97ddb3fd56a28acc378c57dbdab001dba1506ee95c0fa1dd44c17de641e6b9c25a8a8fb68e5df61a61d30f6ea2b00e090688a3b56db610e21760c709f67fa927f84cf4f5ad9d5c2c60a0b3f4344005d0a8b4a3ba66a6383f248a559eda3b7721b2a4a133fff8f52115b79b4b75a001cf193513f714c06064e00b3a149a259f4aa1bfc09156e6201f3a92de40ead00ab680577a907cb03b0f6511d47be9b72dc10a5a4f210b6ac6abc9740de9bbe00d1cb0c08510d4a6edf8e41527dcf3d2e34a5d3f90c9e15dfd581519684f5fa00fb236fb2c239f6368d926f8ed46ba01692d7adfc5b393f99a1bac25ddd7a1d00a05e9fc9446742b4be100c6abf1e955588fb5c7fa438e6a27ca8edef0ff6db003aeb82c0485f9c5996d11370dc3d4ba4e04df5c5779087e927ed1393a46ed1003b4032f6e1e37bcd59155b6d7e17da1f3c44e6f930640d62a9bc0f5b7ded0700629e76a079f0252cc9034d0b0ffee6247fe3b7c0e76f67d0a960b963a8152b0035f491829a15dfc3dda5df26eed07d50dd7016650a8c25d2cfcf75eff22d6900450b5938c762b13219d40fb9757a3a28df509d045367849ae43d23e0ca2f8b00b52fd55b2e269520a46ba12787516d72af6a518590d99e0dd353c47572e3ed00823290687f679d833f259fe3389aab73b028cfb106715f47172a0ab83e513400b97e0d92f6eeec86857de24208cae9f32ce647eed2eee8139bb4aedf8e19c00096f27d2f0cff052fc48dc3bf692781b3df2b3389421ee0884a8fbb8b81e29e005e4da7ddefe34b11fb690c8e3cb0ae5b047e0731fd4010b0313be5be0b98d9002d5600a72265471ea43585bd7585fa98bd4b4e6f12e8324e6d508e9487024c00a6dea821300224ac4ef58eff3befa453c5f797f69492c0745f0a6e9b4201b500e4383e2de38c6250d2e13702065d77f98b2350f29e2584ad6b0f5afb19c32f006e7ea1165d77a0c8dab867a7bfd3cea643c3d5cd6e59edc96ce5a336589d5a000971d3c4dc3e07d3bfe3d2fc6f99729d09ad798998a7f8e25aba0fda4742e700c6032c74b491214b02985cdbeea199cddbf2bfe11b835d96d4ab6b457f71c100c1d3e712298854b208d2f8432b4e347eeff05c7d8b9e0d6260c9c5068e237e001e753c1a12c7c30be9c5012747df2a218c3a8ed2ffaf7e1c7809687e6685f3002f149bfad029ed2dee5649f60e096d73f875269185a9b68199d5835371c75400790b9f9ef3824937a933dda895a6503006481d1d38742f10f375b4c717b1c6007880aac498dad41386bdcf8aa568056029d44b7b89ee471d517bd80b27f7c4000c8f198b687b718f2cf180ed345b3c1b8f6b6ec68f204f4fc25a5cb9ef4b040090efe557c1dd55a45a208af2b1294244469f03c127eeeb46c3898c282888a7009820a474e48cf6f583568d9ea45cbf7b67d61029b538efa3e39571832c036b00776343767c3ea90793c96e5902afaa12167e870bb95c7abe01c99483e7ed6a00f911ab498af222c76185c639eabc4ce2c0da3c0db9426b3c728cec24c1d03a00d4f21212708a371f50a21126d1970883500b81ac1a707712df0906f177de2500830538f939644e6fd83cc53a52f794cafcb8a27f7aad29b7018aa450b5645e0019fd6393281bcbb9f56f85e88816f8afd682abdf45021283552c037201664500ce30ebe7d62fdaf3ac7288d12af6871a131ab812914e357867342e3b927c6100405af660881aabd31fe97b3ad136be7968bdc0065c4062f5ad54953d1e068200a8d48202870d1ff9e488af8c055ad96e9711bb41680c2bd9d8f009189471610065e0cd416fac19c4c9fe289fc29b95333442ce5c20a0fe61af16ee2465bf380058a3c3e0c7ea40046e91f0a6ef01bb12172e045aceef9670968efe635827a400fa0ba9098ec60da2f2f95ed0df7bb55e32ba03bee1f802cdf4e7e43698ba7700c4ecd9439ea48a7d08d86ff97ff75c347d2667ef648c5abaaab71d1e83e615005ca52fc744c0053c8521dbd52d831be7e22ff8440fa8a5ddc4c7710bc9649b00cad0558941a605c7e735aa1bf89908321a94e9aa7fa9f5f605946334c0da4700d95516b7c3ea2a47b06820cc6ed274587d7e14056af9f4ebdf1629c61bdb420042c7ed03cc2255aa7681594e14ba998d0a67614054458e17d7ebf3293e1f41005eb8420092cdb683db8b998edba732d375875f9fc3b0b4baf46dea4965419900c0ee2375395890c4b6d80cff98a0038be11d931fc466b117cfcbc59e94b671003c957d6f0ec45703738a84dd182281949fe8e2c122555aca8146cc2dc4c2e500897d534a32c370e009ee40de41302e84d7a7dbe20b2f0e777d611b001ed6980076341fc5bf4cd96501eb0bb4f0708cfcbb5da1d3e9854bd222257845b12efd009eee0ec0ca4727aff5f2bc105d81388d74e7dd39f71cfdf88d8632a7523248000bddd051d0544438db23949e7aa3b057bf1e7beb1efc7b1ca2b8d011693911008a527d236090065a241c98934f80e884660b46b9a482f44f65c5ad4204fbe4005a681b6665ee54973dbe08c040d0b28d259b2eb6b2b9c5fe07a9c8948f19a100aa120ed8457adea9f42256e48db8910a942ceb7bb574427a61ce43da0c641600f6603d76f614bce6325f49359ecd6491b23701569561f81e03dafb0299831800ff6728e2f01aa58cd4537a93f8d2f011f435d0118b831b6d4980cf6a3592d900c3a6f88203881112042896338590ebb15274168c0edbf06bffc328fe817bb200019999b1e86180748e771410b7476fb784f26a58f8153815fadd9cf8613926009cde1ad289cffdf954e0e611f72f5194c78f36ad567daa1814dfdf0bb313b400f93dbc18bb939f1c709b911c49d183f9a55b7917872ceed82fa8622937a865005f90d3a3a8e962be0e9f5efc7c1cfc890bc33b425dd165aa0a8a46f9d1b66600b7789f926bdb7d5f27dcaf8f989a018356e3a0728119a876b2e3ab18888360007a4992c234f13bd6d6aceaba226e96ed88e4ad058cd416d4949eb956970eef00e7b7c2982d055f0c9f90318a923507ba667b943b94414b8ba7507466d1f1bc00577eee75ec3bbadd39457a1af21b78cad7eb91b3e749b41372166567b305f0000073db96706c140999ce5e5b5050522e0bc1bbd7422405067a0a03d9bebcdd0024ec621f08fcdd042c2f5871141d95ffde394ad29c4a96b76d81882c1dd58800de00763c7cc76b453cf3b158de97dec1e5c47e1486eeeaa0d0c01aed55f408003a9a7ca34935f05119081f379da6235734a24470892a387a900faed5e4644700d328e9b3309347a44f7cddc5a17ce5113e7f5cebb7db5972ca31e0600baef80076025a4dfccab9ae19c1813e04fa8e704ae50caa2e820ac567925a23fbe39200ddce07873db37e10cec8358f0774110e9d88343c41459779f35acbc15ddf4c006d4b955635dbd11c5e7cc1e613ff6df7781f4c5e959270edc1a85aca131d3d00fe299b0b524d59f11ddc3a429ad125896ddd7a8ed418a7ebb29677843b378400e5440afc44da8a48375d6c8f5a531cae3b76ed46e41f31c30a3098ac319c8100aef71360283f47b66df323e121fd0f47c8ee04fcb01a4e1470344aff60f30b00b484d7a7c8018e4ed5c614437937f7be396307745b4bbe5c55bc0e30e4987a00257082d54e8d4825f1371d1ce4a409a759b2f6a67f01d74f021954f8118637008d985f70d4181d0571354fba8a57dbf0f31b0d06a9a345c1b80a9da5c83be0005b6136a644c0c5f7200846e111c0020514639b9de9a5d398ab9e86a31258ec004b86eeb580332b67cbbed4e29ed772f139bc2fee1d56dfa7880c7abfc0f610001fcae9bbc34dc36aa93e2f4844984d6bdab59ebfdbf0fcefcdc8d48b249a5100e2d56fb94d3d95d62b62a2eb1318fc989cfbbadd19e2b6df855de507385d200009f3d55e14dc15c92abc26d2573ad7a537478b83821842fa84d168a78601a800e79fc46c4528fc8bdf1e6eb618ab6366ee1478626a3026d762976df1e9253f0020e9ab7c5ae83d0f22f078e27569bc314bf3adddfcc7c6147af11ed69851b4008a9344e18f47fd4d065e1423fb026e4aee419e243870b2466b3ea305ad657a002241492c418a735e8b7350a6c53e26da81be2227749b2f2e3dcd7e44699d5a000e579343612a8d6afde9a1a9fc1c91867ed6964623b46f493209df1f3bc070008f8a7485b2dfe40bf476a82937e535d0a1330e3a2fa091c7c90d1047ff0cc700d546e9756d94e6c8b6c1db2e0d46090ad88634aa6d4b829370cfab30f7830e00dc0c7c61945f3870228174b1d9e49655c5f6a2ccb79ad214a1d4ea708d1a6300edc82a9a2e2cd97737ad8955c31231b3bf15db73d06359974c56276dfc620c00785982b6a48399307edba4da3be928372a8f7b123882d8a1da05e89b1bfc60001c99ae3ae086f0f60575270857e6a1c5bbe9003f10bfdd7cbc67cb0fc929f7009c10088e0662a503fc70bdd3da26d124d456fb2860a495d6ae094b9285e30f006524b4f58a86660e805bb792cacbc989c9b859e084605bb16511d705f23a5200859ddfdda8f1659d44d055ae9ccffea1ab5e3ad0b3df46d8776314ca34fcbe00803b7ae6e0212d33121ec0a3f5f2033532bac918af3cf65cb44ea63a00c863003b3b0b6c2afb9c118391264af763b1e0b1bf3d8f98fe53f5d4c77ec3ecbd130071017d58307859438fc3849e11b5973ec7e25d9c8993b96c567c641762cd3400b4e112f375b87a02c85b43453418b9b408b92e376dcea8ca9fe7445d0ada8c00c8111312ced6fdf11b9ad062739e8e65c46be46acc8419d2d766362b0eebc500dae6e70fd2bf94990a6a706a1d4aa4a76bfa8f611f7ddecb044659f2b8c3f3000f19d204202a9375abc1bbff1aae9905e862b079f09728de4b33e82dc4ac0200287c5a67ea6c5a30fd5b6373838b36bc0556d33e3149031223f8197c1cf7c400df7c98320ddd45d74d8708a5dbfa27b908c87a30bd501e8b297a49ed638e2000b4cedcc50a06b41d9d8138bd13d4d8e894153985e33f63be880afcf917ac38002ff9ee887ea810fa6afa1b44a4255884f0368bf854e96c3e2f22d044c14d8500babf9b06a604157e497ce4b2bdd9c611bb59254d68343f95418440273a8b8a002279ca96adcf6bb7cf0a3bc9f7eedf898d80dd158736d72dcdb1f35d3038cc001e7e3ba7a874321979f70c8601dbf09c2c77a1fc32f357b2328c6114b55a7e000a3bab540af2a6cf8de4092d8cd04815bcad2e236184c3d1c01b029e41dc59000f6d19fac9da2a8b8252dd522c63acc6dadb4c98eee46fdd59a3e30b3807640050c66dd20a5cafb2d5ec52a2930a8d95013b9f2935b69c940824bcdd43ca4300fff7ab26304c0f130e2636250543994d959c95d78847bf83eed054bd1bf49600e23673bab2e85453508812b0fe29d1a3424e84dcf1be9bd0f901dd2645dc9c0004fc8696033617871715bc52626f5daa1df5e20a4b7cfdbfbcb741bfd1b5350030fc3654c688de11ff736dd83b850f701c46ba9a2fc0005026ca08bca7142700f4a108a2a7441a2a00101730aa4818347420a4276ff030cc25f45162c58454006e18be9666a461b098256d87bd28554f1d15ec836f7edd9c47b610300061220096a5eaa397722152d077191d1f108be34c5570691b5f92c4cec8f3f1e70ac600fb53a72cf916fb9e5209c5034a736117a355b215e7a3ae919d1e0a4b9d98ca0085e94069c3e00750ff7e608bc9faf539aa5ad016de83bb583ad4a747b9e60a002d9e392365b78b331be1d396b909d0257703aa65506e16f91b4f44cec7c8770025905e42446be64539e0ff45901e8377012ebdbea4970fad4b0ca3034cc43c007b25964bcecfc8ff17ee3cff75bb2e69436206bf933326db3f3b9e6bc5213b00352ca9391d50f9be5e1ca0e9a8e80161c88dcdd253f4c275d4de8b6274d73e00d03a3337881ec42e4994a3c757c15753f6f375aefa587d9751abc0693f3c8900972201eefa2f0da8b12497953ed8f6494640738787261c4eded5b382c1354100888048204142d7bf7e75dd851b0b932b64984fb755374f2ecddbe67571b5df00ca350a22a4d8cb544143f96f4b4b6dc9e06c80c894fbaf556fc60815bd84170097cc3de2e228069889ac9a7e7d4f902332624cd9b5fef80a9aa98ab2edf3b200cfd3069b57d23c5cfc4c2bc0555c52d11c0c7a9a602e04d8f02b6f3cc7a2ae0082cbfa8c3e4fa4c113078b69e56120ec12b417e3051e67823b2a740062319c00b997618e1e2e9e1159eb1a9bc16fd97226d61536de95c5ce031aefd9dfb5560044ae1e2e6f7d7962db5cdb503dac3e4372dbd5ca30b271901b4dda3b0413e900a7b549f3901bcd4d59018c6692ec610cb99753e616d5e610c54b53dff51d910014d64a32b393fa8f8350bb35ed7f4a32b6028f182f05a6b492ed598cbbca37007928107e6acea8b622c809b9cc258506a211a72c3cbb8f664a5dcaa2eea68a000c81687ce94a04a8843cad3d28eaee20090aa548771e5b057497552201b9cf00c8a59f04eb1c1b9b8ff054a468e71b6da5b4a27700072444e47503d78c92440040d9ea7f24bc6d34b1d5b7f89d1a35b6e5994c5bee56a2128d6c475645fe8800c3943672c9ec44bc22f175347f56de32b4f65ec014b161d0978631412cdba500d084ea5423eeaa2181e06caccfac9d8c5ea986a4882c542cde95f57f1792c100ec7e5b42e1b30f0dab298180cdf3b3cf78b9bd6214d029a374f18b59e6b6e300f1efe102ed27d75d004de3fa3c1c0521c8af51b1d0f321a6f415f1df6d3a8600f1b16ebebf431919b9ecc94e8b1578b4c7f48efefdc7ce897fa78fa111f9fc006687f957c1513e163b53cd1514e8b69234cf8262c32ad47d24700856f6305500f2b29098d001855d60c7cfc2b8e9e3a177520c3b538b4da85d49a0cc7f50a4004f41d624477d6d0a17f809fd390695f400d073c06f65d6d5053442f93d63160095fe96e4c0bc77ea5813199738e6cee01dbe8b09c0cfd24f7c98a5ba40fb920010e542359eed28b2a74742ef21cf01ac4943b3157cfb3b5a6b750959870b7b00ca8ac4176c906c563e30494fd942a6cf4cf3fea702bf02354f686570e59bba004e028117e1a5029adf73aea417c9fc06574b979c623d040776879ec683a8910020effb79cba67e667b3d80f7110e27c0d0c2f4d1dc5addfbf564bc74bf114f008a719572c0fc6c1428463a87110dcba5b55fc42e2527e88eb76760d53bef3200dbd5712038ae597f5cfd782e4896535a5700f581571c293005fa0b4d88ee1e004fc2ec9ddfe51f4d7fc300dcd08d669a0c4acfaebe2045c361a41515a8065c00d6e534e9e9c3512910188c4d6a57f004e04ee78cb671ac27e6b2521db57edb003dcbd9315d4e0aa2d0177b3c9720a66669a4d93006f4d3c37c7bd93e9ed5cb006b84443223d8c9df227a4fd324409e394944461178e57f793f76e4db50564e00cd527fcc854705e9363cd1d602080203cdc9acac6efb03e0a5c3504901a43100d7fb3dc42cff9f2d0eecc8b36c0c038d2960e8ced9172ce4c8be85db955226006acb052136cfb021efb18515ed65f85603d6c80c9d7b5f438db4acc980a1b4003869df3fea3f885539dbe9994d7d1bd86fe55ac0037e163d88978524b43077003623050dbad989703b647e89483ce518ccfbedfb98a3ff218ad8f1fc1cafc80040f7889b662304aab670cce34b4193620a66c87905650f776f459705b1f1e900e9eca6c50bbacc96f097f13485d7c8e321908f7c0b32938e81ac01b893523f00869062523b6b6181a4e1a40a89a6f4bc64d4afe552e8c322d5914e9696b2cf0007a30d93a5b4326acce8b653948137a9c0caf05d84ec370f1a0ed8e7d887290031c74cd9d5e83ce22f60a5ed4ab51f4716c2a4b09f1aac206cbf388e016875001a21274ad197fb781c0a557ed01fd9f16465697927935dc85540cbcd0d7ead003e475663ab2cb7b48293adc472c2945de229d2ccec0e5f581ca098ed2eec200076787fbf5b74365594e98141164100a9db4fb57885baa21875aa055e77dcb300c82398232a3fb255df9fc1b2f8ecc729f69e47ae7176780f0d582c5a8da8b800800ec4ca04faa3f2d4b389451733fc6ab216d9455c55c1380d272ba187e8a50002e320c22a7af479c29d4c9b3314ac589ab5ed0bd73f4ab2c189870512ee7f00b684ab264b0a3c6a85c69a95a6166d765b38633f2dc7d997e0d46ed931398300af5e79d61cdeff95db23bd66165a56febd9895cedb4c755e18cf42df64bfa600722602a67a0d3c79e378feb3b908d590d0c1ae8b9041af088d8e9ec9816a110077f4202131f20acca3f86c38d770aa2befcae58504ceb11718e6577906460400c6155b0d43ff4c9dfe748545f1f503859e6ad4e30a928fae81cc298ac78941002d55c21fa80f00a038df1f587e22d1bb649b37304d5293e34ed0227ca7da8e00192dc354558945962316aa30ebfba9b75e5433d54727a0d166848e48ad826900ccc5378dd141de70250b85b376aa59226f6a9824e526215e7f0f5f071f5ae9006120696825b3c476dd8f8454b7733537a82efdc8fa929f6aa120b5df9f81b600600f2cb8d600b589328052492cec61a885b5c5b66f96a3390d3cdab3f0c39a002218d2edc33717ffd0847c534a756c8e9f9b2dcc1fab0a45780cdbe1fd6c2e005e167ffa9d1f64d78c60548ebdedfd69f4df4517174eaa21d425826d8dd29100911aa90a6d348049a0648b9017ad8607dff5e3b54f91f16faeb4dab686381400cbf813cc12033ae618c5cabb46cb27d8ba56eb4541c171d873ffe0f118ff5f002b893efd9bdd928c2314c7282e829b5bff9b0a3c64d93df092c8978016fc59003bddc437152623ae862662f45bbd36b84767d74cdeddc9d211f092854a4f0b0045ea7c63817b30f1bdc522be7ef1459b687588f267f2f56685a64369767252003ad7f3b122d281b86fd2fb40bde2e2e934bad05fd5dcc2728ed162e2cc697b000311f244dfbc8dd1abdedf43cb6d4c56f4f38fc47e2e29e1a9fb0e23cf0dc300582c3de8ca6d428ba6e36487ba1b5c79da85d9f3ef571aa6b5d2368fc62f5900b210fac6bdf212cd6eec9515bf38fd590cf62671456556ad58466e1b1bc61200f75edd6e0b32750b8ba630b0e92b7343e4c781efec2fc8e4692adce287fd8c00ed962f32965fb7da06cc0b1477e0f9a6818210adf70a6a6efa9d087d22c50d00134234139947e0efd1659bdbda5f60f0f4801348a1ab020fd2f7f70674e87d0068744a94dc959a6751cde49bed419741cf1cf951bfab1d2e615a9084ab80b2002e0b273a722832680a42cc54497f0b1d1e5bc60dfe4a321091b522f1abe1330052a3c6c38cd1bf8926bdd04436c6adeb5d2b3b5b627ba660b7835af9b9706b003dacbbdfc11800f5358b206a05b797d3a8077cea1dae0a4244d470a8c94a5f0035ee3ed4c0aad6005e9b38c4617ab9fdc73adbe4ffb5f377e44c6e88bfded0001aa356328d6fc65bcb7fcc0c10987a6945bd9d4a75474757827f81be9d542400d8e109ae85c82c259440e5f14eb8e1816dfd366f4603bfabc1f322c2d3f43a002cb21fed50ee27c7c5081a3855f2148206c91caf5828ed814f195e4b429cc0005341e8787e4fa4ed3194105c7baecbbd3f5a537ed1732fb8d4cf131c7adb5d00d3024b61ea78df6af74f677f1267138bc3421d02e603c5b9fbeeb13d555dab009966d0a06f9d524da99d8ef65b527f08bf2fb639ee6e2c51127382f7d2595d00be2150ef00d8f07f2c373df3d15dba3b4e2b6cc6ee1ca241dc5eb23c27b80000e7ddc2a4ab4ebeccb1bb486ea24fb348808eb15b3075f73bc3bad03ee5ed89006fcfc4c3e22387e3f7e75d46eab4698cbc4d17c3a2c2913f0231dcb890542400f03336647e95bf2eac368054df2836b708299d7d21da0f52bda38d92c4b0b600ca585d094ff37a892de944ac5056d382b92569041ca196b07fc8512a9d66b300ea20fda5720433e17ec12e7427ebf8aabf7a08395e16abcbcaa2b630a9875d00498c1225c7f0eadf3cce5e20bd2cb4673c3d127b94b5a19205d930aac00298008a2d0d9e7466d34b91887d476ec67d9848c3b02f22fc39b67d88ebb235a1c6006d5a492c4c44365720452c4b8aee9af97cb3eb38baebf7a46fcc720ac3276e00f166f636212f19bce6118b1b1e0b53dda384d31f3af9a8d19f2fb00e5d8f1900de97de3227d9658d9576d189b8318b41d9f8526b210fabbeb3511b98318af000f8175d77098b12461c985a8370a3edc0c32d7d67b0f39634168dff411d19dd0046836f6f5b4056188a2cbebd23338bb8f3cf56fb1a0438c325a1cc574f48590046ffdfdb54cd4fe0b11be89d48df36933d4a7bd4f2ac3b282c96bae42ac8500090a401bad202a96371159913eca3147c84a66a9d0c498f7ca9eeae9bff618700dedf5e19d689acff760b69624dad1dcfe0ec2775f18e21d5a13c709bd17f500040b2adeca7f8d04ff1ba492e1cba4c97d35298547a857f69b254eb43df670e00e020620e170f8fee15469d86884f39a29efb109b1712e38e9b39c81beda38f009addbe5925b10b6388bbf7918672488926824542321037ae42e53366c2356500d3dab74a484dfbb7737bf021d6d93978b35a729306edeaf0153018922cd74600cbd832b52408b424134418a5c3397bcef1da9c7f2d53950d814e4f0423076100b15b8b1ca363b43fd005cce319e4b143b060658a80cb23c5e6db4e485623f500f053fe6245118acdd0b5f041042ecb96d004baf0cf836410389360081884d5009aff689d636ab6ebb1687d199d7c6c458df24ceb13baa2e4d4c3769dcd02ac0059fb7ef1971c7b0d8f1751c57b81e445d71c8cadfeb5d62aa931e770e9f40c00cf8a6323a25099b33aca1d5e9294e4da941ca8a2b1fd50c21b012e4e01c7ea002620ac538a2ab4d4bdc367ddd856ffe0286bcb8bd83fe58c74fab2a635cfab00a8c546846dd2e0c839056227d50fc0394aa02ed6a0a289bde57fa08ab4e64a001938dae89fbb5ee4948621583b1c81615170077bd680938ea405762694116600e5687dce869f8850633cc441c371ade344c3e10a26531ba381f91eeb63386600471931951d66eb5f60dd3ac93f786d2942089f39c4d55e5a732079dfabd894001bb72eb305e3ffcb47596fc33273039708b821ed83e8b0e7c50dba40333c6c00e01555b019be1b7cc2eb7727088671eb6eedb07ba4ce7a5e5850ce2e6a26ed00228294bf0d7e6bd15b417a968498c7fd7ecc162b924e14b17564d0dde6519d00ed2e7c65994ec353846798e5b409baf3a73a5e22daffdccaa559a1b1e4355c007110082f195b5bbb3f8248c413af6e7dede0cd25ae4bb75920ba2be196b62e0033e82f299a3dff4e4470ab88b7df83aa6ed08a45a7e15a1b1c95f5f218af17008f215230900fa3706128f3aa586637cfe82e5a5f7c639538de4c580a960d0200a255f21cf61add8ed717c1bbd7e43bd8753b877b77da1c8da7a0f1f51077460022bfb2d9557bee2edbd9f893d5ef18c94ace03f39cbe434d014351b659a73c000f739363a2a6470571ff54d38c81cc41a3896ca1a6a1832ed8cf2f411991e70048ba8f6ee3b765b6fa4f62a4d2ee2595b8eefe28e11066b68ff994752e04b00046bcafe44a858b7ce3868c63392f977b32bc3b8cc3ca638adbf1b77a31523000ca06d103e3a3ecb38d61fc5a48e156614d0b6cd7b65ce6ef880edde3a22b75006208f394168496fdc7d040dec10edb6bce7feacc4fa17d57ec2cf404c7deaa00fe1d87742b24a13f5f39e83fb465d889b2b230a8125047b7349d301951511700ed29ea72aba954f481ff90c4ec900cfde9bffd062e26e03520089c9499d28c00478b46f53fe6349bf1f786ecb31f25e706646279d356ee149eadd6a2d8a6c30094bc850c3a096e7a90e9c22fbf91d3de57ab33719551e9f9d5ea30b49cc5240007e28453efeecb309a487c05de935eed431d1de1863ed0a6b97545562a5dc800ebb62ca5f3481971b1a76204b7ac61aded006e93ab46f84bee7c6462f5dbda00e62afc467439225b7c8d9f3d2bc352516238392505b501121c02f10cec114500b09ea9365335a5fa06d34a71c9af28c5f695d5d4cc4be88dd725ae5f4e4d810021ef1381e1c52b9fbb36aff2aa290163f88767404587cd1c35d655bf0bed070043f2d2d735c2aa9b91d44bbc542f0eb4a88c45422b3165350ced1dfb2e8f5c00cf244861992a6ed490ab50b0bdcf298adf66a57986bcf6edcf61004fa6db1900af66f7a8d2021e6668744f72ff1ff830fd0f1c60276063ef5ba337c4d8309000124bbdf627a7e6e00b0e445a35a65c6020ccc6de4f1f5dbc4ed6b7059656160071331d51cd051ce23df5574a5f0462ab6dee9ce42c1db07d1d57081477d556005fe09707ed4d00031d22355bef357af7e22e62bc99b12dfa082624343889d000438b3ed916c7e3e21adfd631a8b508e20820ba23c57d763c21228e31b9fdcc0066fb0831508577251c8781c41eeb7bd0f21d9453733aaa9bf5525a93f3ac0f00df40ef6eea6d2607785c8f3c7692e04352e04bfd5930dd439200a1cc949730000e1b8bfa1f23a784b3eec702e7d9e753107fcb053dc75d1b1129ceda3efcd600bd89446a6c43580c9b11bb1cffaa08455a11523c8ff8e836359b7720564ced006e9f671a0bc61690159c9923dedb102d7ff1f88af8dd98522f55a5a05173df00b55416f51d9ed4bd9ea27b2db485a826865c3342327e98f6a0b95d2a18790a00d5941c933d41a0441b70350ae6662a97e304c00abea3725bb727abd8dd6bd0000c4e84f8250402eba51f015350b1e158f8321dfd0b1cfff98b251ba3391f9b00deb1448e03f45633922858acb310b1f3c42bdb58d9759abb3592f95b8368bc00e7c0f2ad19eb55384dfd482d52232914f044c61e8eb9f46ae0a4155c7741180040e9b4feb69122fc0ccdd941f8bc7cfcddc4c3744971c4d427c7039e7456bd002313de4704e75c81fd2f0fcffd20157e9414a49c788afed82fe14820cbb43c00d6b585ef9ce18695746a0a6ca568c838e698cb348fd326bfed6193bd49ec6f001d1143ca0fe0cfbcd6d27d6eec94bd4ccdf357b35276315f4596e4038fe96400b47e272b491078e22df6fc08dc2135548e662e9a5508481de03120e51b366900d182a5e9129277a38a5d10211d24a636f53c744467451d2752dd900e30dc3300cdec237334146cfcaefa5e0eab93bd2d7be90196ba8f39197f6023d8cdb0ea002b1daae1fc63311d866dfce840eeda3c86bd4648d449a0e99fe8fe3215d298008a5dcfbf842b5b0f264075d8c6fc0a3a87125b1eb182d6cef9d666b1c1190a0048e29b9b634067c1e85199ff45f7a0ff6904d373694cbc7bb9c016ce9fb1d80007dfdff34d3d634a7b2a3e907d5f9836583fb980e58f258cb7df2449c13f6d00187282b1ac81d25b4937dc1a1f7125e870f50cc3afb2b1b64b589460dd74b90080deef345dd20281be77c3ff1fa76bc6c03bf18beaa6764442ee426b5cc95a000823749d01645ff9c4aff2b566d4c2f0c742b57aa1616cab1bbda450bacda2006be89a8f4db13cd44c90d34c3dcc38817d1c43c58bc75c18b01e9dcf44e8d700f5889429ea95873b80a7315dc4ab0ecc7057b3ff4a7636eee35f9fe59e93bf004bd9f794ac7731aebe0c8c63690d6f519018684f13220e212427ad7db99f83005d5eac5b567847af21400659be608488d86ba1c6111c6b9e8659765abd7f770030ef8ccfaf22b9f0f6945a7dfa80408d65c103501dc33516a48a6ff556f3e900706e2ab5b28de2d841f3a517bee0711078fcde029c4f844dc8404b1058a6920016c73a0a3e7103ab2542cecee3a1e308806dd0b4f7cddada63efd6b223f98e00dd0890249c4716f9044354b82dc1e384e82af8589e0844d244ff2d41ab20c300fc40daa87cabaf9935c9ec5fcd652eecff6aa9831f529f175dfd5615a6d05600991dd9da263bc9c18145ed3f0a3d73cadae09341f38701cea6e928645ed6bb0038c93045d981f3e2b197f4a9aa4fbe7630f4ee2d06c578ca54e540873c92d500ab2bc71ec351fe3be553ef592414e5a56350f0beb682ba5bb14e89559f67c900541bfdab1ba9368ba333f70f997c864ed39c3f269372ffed7dba6428bce952004289db1443005e454b5af761946c7c589e3ebe032c84f5d601280f867d5309007071cc9115545ef740d5e9f82e0d93e8f16d690d8d8b7755ab8c97c502c71300fb566322e1c510d84d4a6ff137b57725b995472cb94986d585cc83eddb98a000698c894699f346e4e15bc7de3bafcd608ca0f09e6386f2f3af5838bcc5a373005f9c3ff7fc3c80df5f47eac4ed5180c14827a9e3a8e3caa7909334b2047b030070dc6ff095d79067dfa79d739b72b945f46e83fe36ce2f3d9737ed91d3dbcd0041de0604f4fa6e120e77f0189c0b6c284064721b4513a844b565db0f51470700c647ed1851999f05fa05dce0511d1f487dbd702bbb9511088cc09607c81cdb00c6b84f48094e938a83a5d1ee31e675374d69c65fbd49d4540e1a4704335c6b005851209b20db7a70ab185ee8ebfc50a546f3aae98da68c326e1a3e4affafe800c7401b2662e3f06146035963b99732bc990ccf017927628c19c07c7974c2570093ce4f9da53a8706e2915de24657fbf57f915eda0b96c0c0f3d5b56ebfec880099cddd72cfc37c9955521906cf05161d6aa2582f652d885eaa5564d81a5b910042cc886245be774746a10f4173df03fd31f63d4b0a45f65f97b2089036c3c300deafa9a177f28d718c1a9c12360a557810c9bdb468de14c9c971866d8aa33f0095a96a0d8fa586f0975d91b6ad12a311e15fb83e8d765215a780379884fe87001f612da41e63e18268bf79f22947d1b99358c5f70e24117c2b4741c65710eb009af3255da4b71e2d54c2434c3e785fa84c751224d4bad01598b56b830d27fa00c5f55fe6f8b78de9991e0875e5edbb30569b76fe96c4042ed8c550e59df1ad00164c1092137908fd4acf9d2f30996e5f5214072f5b0c2164e5d0666191bd6b0047975f1dc273c8a153a1df2a68d3c256482ce2723d83cd5c1c3d46f8895264007c9578f1b3c9b60b3540157616e4b95a91d1f225af704f419713dcab0209cb00b7187051242fb2e57b5e8aa19956b6b650f09d0b04790811c6eaea27e75e7700708e1ec4ca0c1b6e5b76d36e72ee619883e6d3c63158c48bb7f30ed2469de500af7aa79c4d686adee652858f736c6b387047b8f0d1d5b3d8aa1c13efa74a7d0038eed3e88da6803085dd964213db36105b29b88dc7c34185a1e7e9178a412700ba29a831b3fc4f71a855ef2b55fa3e3f044fa67771f812718fc8555fbfa9dd0037c17fc759be2dc2f409e0de429724abc017a4352a2a065e83d7e183d8c19000ddd2d0747f5038cc8f53b8c94ffe5c1fd31b849bfce16ff4418d0d16ca1646004eb74c18d3a7d7038ef99e2a6eac4bea1b7dac4cc5ad9f82288922de2b188000c1876e0d51b78cf5f3e24632279b021af4d3aa096d634db887375fd883b05500ade324fe1aa3d688229ca25f39759933afa80bf07a106c828c0671ab70d7b000cb2908926c5780c58f25ecf7503156dd7720759467788513606d9eb7140c5b0017623660f5bdfa3bbe3cc046ccc480023db2476df7b136996ad9b427d2ca6f00ac579d06cac2b6b01aa1030e2675ed161b30891222f1375bb93f4c3c94a15400755347596171ac2eda03e64b9fc06f844d6c86127825e306b4deae151101e800a62c96114080cca365230ed58d18bd85feb12a3ae29900fd73f113de4f9a0e004e0e1a17385b0373e359572c66ddc5e2069fd9611cbd1f0b66d9e4ab39fe2300a85a7b887ba3cb1cb43ad79df9a2c81c96e07702922137e5616447eea5fea8002cfc267c9d855e6ece569a155e5fb73f6e40c8fa82e0bddb3492cf615a09ac006353c6ca0b206c602a90b4d7ed2021881d23b891852a72b35630f0d9f48b630076b8d523f444fddda02ded9bc0111b95b4dde4cdd9e2b40ed4cbdfe475826f00728750a00bf3ea797f5efb2cd8ffc7c23eb3accb4142d39bdf2163388f971b0093f81050e10a5ba380aad9232fe4c2ca3a49d62ba736f455a786042149a565004b3c1a860f1ea6d9231cb7ac0d83907ba28a9ddf20ed9385c684226943c40300949d22c154269e4eeebb25fa349e6f9d3e62039285579794158ee28e69c06d0005b37afcfbe9f60f54a6a3b795a5eff50517ec9b609338fdadb5e8ddfc448a00ab64340a9fb6a59c35e8d90f6b4b174566594cf57e748495aab018ec2452f9000dc6538aa11d0dd10cd2d7a78ad9232e2cf75ba2767da376c203f290dd33ab0065d5ac7b3fed4cba30001b18c67c9725201127d95f32f94931624215719273003346458f0c9b16ed0a07a9054392253b3d4b8bf4bccaf2b878d75fab0c688e009e3b2c9afbcfc8519519e9f56ea1a2e397121a1f1c054a3ab7cebc34bfdffd001fbfbf566b2ef439831f13e8c5f4810734ac580cf6a6cd4d039fb404f03e8f004f9ed94126a59c17975897d47ef17f7f86511e49582b05f3e4a3316dade1a7003857c5ea670a9b2b463dbd1617f80e13b88bcded58ca5f3e767783dff8650f00ea047888d5a31cf8c7062e4146ed50dca0836f73653a94c3209c22080c926300270ee84ebfab25786cbe61222ba9a2e91f400c091549ad421d22e7c4cbc1220065d3b41e17bab3c90553b429c8894a40a5c043ecba93d29bba1773950b4868006d58cbd2a69f7e359579d226e9a7a14b7ad9b56d78318b139c1dac6c900ae70062faad86b3fcfd319349f4a5c0a409020d102eb011d9f4cffe16b5e269c19300bc8979e53e71da8fefa574e97fd538d869ef755a6f8b9280733b69c84de13500b94cee8299c373658bd850386e7a09d021b136100a09384c8e4d0d1070536b000ccaa654300f3df1463fcdb1f23edf7a7f4f0c483211481f73d0824813cb7c00d865dea0d731faa86eb0c6a256fcde47a6e547659d8be8512cd828c2431ecd0001a573c51e309950611bbbc0d68e0b58135894ee66b4f4a13aeca22076d99300b341d374c2ed69248b07343942cf18006ca159270a7f83b4e42634662d5e0e00670681c4482bddfe0241e8d558f1f8b2847aa331756a64b55eb0a80d72efd200f87b83baa229e5d1031a419d804a5f2e3e038461dadef7161e706fb80d1517008404a9013b49bdd15ed772b86faee302b1ea8dd887374198aec81aed5b573f00540f861d5a368d9a2554d00478f185ec375abe16093dce40e47e7328776e12004d5b8f9df17ca861aa3efc9667220b71e84cb0c5f4be4af7a5ba994d2151a7000800072f759afb4b80844a3a40506724fcab6a3b5d87f445412e4712f685130038837679e44517f0b35adf533837d582ed312da3085ba4ae4888b4bb9f82d90063c8f76a959317079a6cff755a64d5ec2f3f1f94671204b2e0349b4e78ff5e00b6986f00c75c075232c40d7a60541dbc6e67be2572e46cdca92d56106aaecd008d8a656dfb40393743572be710bd0908f8be91aeca583d544ea6aab764532b00ecbeba129b6f227c37149ae460318fb82e3d621625efeb467ed9a9153b4cfc00d1d2ea431c8d080bfa30256113722c674aefe7c0ca57ac4d7ccbc9a5a6830400066484c927c017d1c15cc84d93c056fe7032fca4029cfa2723c46bf2f38f31003d2dab2238f0a2a29ad40b9efc1adbbe833c1be0db1df9108a8e557bcc6b1b00456ea194419284cc48d0cb74868c12f0b956444d1af2574071671f882583f100c698363144cdc1814317f7c0f401aea72e4a89a71ccc650b8d785b5b980a23006666f1c941b5de275c38a7bb7b30f30957e8dd85135785002bf711695d2f4400903dafa19f141f674db48e71b2bea5a5437feb6c1c03c02f342308dfc84af80084c9c0dce3e63d621cf8434005057ef8e52f801edab59e2e46719e5e9f53dd003d7a68840e943638d7b34346561cf101ba107ed4f5e21ee362108f6330413b004c5d21f429ad8185d26913ff67e9dea4c41b2f587230aa9d13968e7fb195d3008f209c84b5b22bf0cc1f23fd1a5e7ef8c6cb8bb1b22107cb5a90bf797a35a8004aead67d79cbed90c2a820c5d0fd41412cd5c15be9214f19201cc3e7ba190d00fd21c6ab08d55f3bb3ac7d8fd481c01a16c05dd567665b7422b3874cd72ac500ecbe1becf6ebcfa831851af77502ab21c1d93a02a2e8e56b36b5767cf2e65d00e3966dcb2ed27ab26067ca1f91821bf6ae2dbc586a43b807111a81fe9e2f16009511b7579b976a0c59ef7bcc7e9ffcaea2e6b2eeef8df28f050418a112ccda0068d0147cbddd0595ddc77948c58376232d8a35f7e0f87986f8478b2fe1a888009f20981162fb84d97bda0ef092197ffd2274d3e8decd3c106bc39efe6ab2490054adc8b326cd8ba717cea1db310a006905cbc3ecdb597071d4e0e804d8f1d50039268d1c080add93accf376e86485df30625b754824a82ea1449985c3c690b001af2369e8a05f5ea9f4e059125a9ddda1b38b1d64c97c14b07d6e009cb283000144530611fb0a339d2f1540ddf1656f120551a44601094f78903092250f6e9005317701dd287f2e253823d897bee6f78f20bb709a39d6783b86db6eeb4d05f00eba5b594fe9b761e71aa999a423d8be84cf1d9bd76b4105dfa820ec1c154e70034587ceecb58a714b6e3e7a137c043044faf6d4be30cb93f12c8fe70f84a84004c6a47a90db16ceb27363ab194f304582f3562a9453414adca7f4b7defc07c00166c051bdab205c06be4713d0ba55ff90d167f3c73e9a37cecbd1c75151a7100b5491ed85627d60b779499b3caa8d029fb30f1c0023cb7e495bccbd9dc9e6f00de145b79764c23aa10a04e20494400719a8a5b5736ef47682eae8f150be12000a7b957d6ed922e781fc6166ce3b0d88bb3aa60036e1088eefb18401ea34a8600da56c1889287f8f4a9f6397ddd691d706253b1c1c86d82c594b06e09fe8d5c00064b47f8c57b1fc77f3a3cefc2914d79c1f073bc9b93a9c844b678cff378d800b70e64a111cb68db0b82d1df503d1aa02878fa9467f594d4d1808930d9e1de005f28cf6e92c11e3bcbc2a3b3230608aab9828f6a18e62de32f1e27b2a3bcaa009fe3edd4738d73dea61245dfb24ebc7b16570fbdd8f73c2771ff62f945fd540088cb9c091dde36d651ec1e66f4da2d4322f1b799bc192031df904918e3f797001dc3bc0f2ccbea3a4613bcaa84bd768340bb17fc4ef971f017eb4608238bc5006c2b21d97b189cd5c504b0056ba4645a8f805d1bc5db2ec0f4113a290f6602003e2b1605612b470da6d95732035360341ce4e5b2941d8e2fb388d562a49d4900699d5711d505270224f16d68d4bb37ca0f61077e7781d6d19e8ef9c77f70b60043743db5b6d6ac0ce52042486667f7e28042c51e5538c6b338e8b1cb5d08410007e5aba920ed2d19477be114c6a0e93c8d24597699ba541198900096e1e1f500d0bfe49636c6b290e1c1c46ed5463671553d2697d318a7cb80982ccd14246a00a8fca245a7e27bf0314bfdd2325481d31780b5a115cdb0e30c4c9ee30f0894007ae7361c50e6350f503dc6684c435d0c7e416b44d87fe0c9c67368727c961f001fcf739716bc7cb28ff1ce914eb6f782c636ae301ae918057b2e102653c7ea00f0743329531d6c208038e244fb645eb0ab614ada665284c4657ae66d738f1100878d9bf4e815e6f3449b5ff476e22f0a5c3fc7937ed7256486a36626fbd481003167b812da621548a41fb747b5ba09226a87087d0a2ebfaf0010c4ac8bcfbf003023c9b47b61a05b1b99e4bb13fdad28b68cf7df13801128245e79fd10868500b65ff9ba5e4dde2f2e141002d14c9b28008617f7990160e938ec77646fb00d007e16a993a4cd78a1ca4d79900a18973b39d01b9bd81ba317f093edc21dfe480046b3b2048cc1325ee4172f878dbc425f2d57956b14b603a7616c9c63d3fb52006fa56a3a13d0325e0ef76228e144e7ac7111d40e5936080dc4bce540110e1b004996fd196fd52ba2d1f68d6960b0ec75c4454ae5cd6deb61c967ea457d515800da41805d4c7de3d99acce686d0f9895b61101017e977fb7741312b0cb55850002e0def6c2588dbf5c85c6f17535851de05e74ecab3c4585ecb302e821c9d46005c8e424ccb315e71299866608671567b32bf3626c9dc6b8ed52dbb0da5854b0058a1f421450c498059d3a208e28d511318f915566f7af47c3e3115e7b4d73d00d5fcf39cd6966e3719ac68b141b7d71bf16fc0ae649983530e35bdb4393bd70030a3992ed131f739dec451722325fa530124c6431b80cab73cb91310eb5a5f00bbfa79e0891f81e96383c9f2a885a18c33c2ad5422175c07a230bcab91516200d96ad219bafa66ba362029e7531d40ec0c99d3551c16cb22fe2ad6dd2b517900b11420a1282395641670dadb1ab3a1eef71bb7aa87ab3647e23deef963caa100e433ddfc26a392b0550f92381ea24b9a7b662f964f1de7054d6acc2d88a39100daccf32e25334384ed4fec2f012cc7729b19f55bfa1af8113f9d55da5668c400c2701ba71f34d232a7fae552119dbd675f8c90083e219d1e66e6afc5fa468f004320d0fc3ee9bcde61e41255fbfc08aedba7bffadbc955e6191dbc910e669400b5ec6bbc436483891e7d0f1e204769a4564abfe91ca056629733f86208a335005b35d41cbe51ab3d69aa50541221a0303038ead686268e4e2f62564918e8ac00765d2458355d9254c4508d7eb59e7b1b2057cc34a166aa967deabda09cdb220060bd74f18c7a7cc40d593ff653924853a3b1b1c9974f49b3b4fd27ef4734ed0028559c450cb94f18c8b50ecd91c4626809130869cef2cce84759a36c20ae9b00735a723ee850b758e7da547d2aef1e7ca1cde151bd5073339ca7ba45f20a140044995c3800f2ec93692f35ef25cfdaa3e480e35a27d6c9eedb9657f3d36094006525e51b1ca530ed1e1f5deb1a42b1c1f17c99048b2550695db2a06bbd54fe00b4d65d07f7e00f56c72bf79c380e4f3275e7ecd14c3e207984e31bcaaeb87900e926fa2b626b1c9ce7c65e5ce67fd082ab5e53d60b6fa2c53f37d3d6e50bf8001fe36ab2348f4828506dada2a63ba3d1e223dc9f52be7dbb80b0f07d53c72e00e9c6df85d3cebcc08b0b9d1b7d46929fc7f0954f2a4e3854b96d1fa8d5d96500da758935159df7eed645cc729e9fc94b03421f48bfae251434d8681b6613800074ae70b3f14305a8d676ca422176d61f2d5ce9b17c33f4687c8fc683861da400834191e63e367da00572da4a940e095da2f84314d78baafff09e67308210fb008cb68f9e0d18024d0c2bf999256c1042053a08a49028282b975a3b1020563a00b4e4e0c92c8ee5ffa593e6e25d659a0926e4995d0c99c3e85121478bdcce4b00d05e0f9b4f616fedc1f5024c1ae1c914e697f6c0b38fb53517b5633c91da5700179bb56d1d7801d90a838ccdd08ae46f2d3976181c9a3079e443c0aa5193ec0024f2a0ca4626a7f71e5819bf0a5f1e03c5020e414bd91d790f141bcc3cc709007443d452781b40eb192625d6526144847746a7bb1edc59d7262bb8d481c802004ab44336760c5685f346b8b82e06860de83966afcb70f23e584b678470981c00fc0e12395c0b7bdc5372ecb28f225bd1804c95fb173aff66bd290a8f4cf90900bc3909329034a0789966e8a74d96ac0a53f71e8eb57e2ecf29dc647e272ae4004306ee4630fcf52041c79a33ac21b3d670de61f240746a892e1d709ea0551400718b331b746910ba0859138d09c211974639793dbb1de17df13df786271d2b004588f709b02453fb80ae4e8696821ab7fd294cd56b68fb3ed1512103aa0b0c003be9ad86a50031b4fa95dbfbf93449257563fb655e79da47b22002dcce76820070b0f161ad85e2eedaaeddd9653f3094146c7ef0c70fcfebbdad318106a318002fb257aa9f675090086e91524780e19c36bf68f2e751224b4e0a835154eead00620c603d443173bc9725163639f3b49b8c369bf36ca3ca2dc4ed6e2ce6144200beba9e477540960ad005ecb4adec9e0c3040532d874934ce9c582934d241ff009052c9fc4ef89d373b73982e9db8b398ef2eff144f755bb8c85484702cca49007c8bcf758e09811690922e3440e9ca7d41fe0ac9c32e624a568ffd7d70375200042fe3184ef2f1c31d52df729d2baa42ad4e4b7c23cf888d1e4ca5ef716fea00a647916b336c7d873ec62c821c2b26a5cef05a444660c162e1213eff1801c8009ae99107e6b199b13ef67542aa81251d38ef2aa7a343e37cef0d2dabf38afe00e5cb3d84d5d01ac6f9f10aef76360a9fca079268579834fcf2b6075e43aaed00e8ea0ec5a6e7ffe31e4ba4ee070b164d4bea5b1f940661aa7574b1ff4f24560082ea48c241cd6c84ac9ab8bb7c22e08da426b392389b391eaa4630fdd2f022008faeffa7764928438f9a1ef636c8c27d66c1a6f15dbfc947ebbc1ed92d51100064e34f53aa61c0c402e0d2c86ab109f492e83397e26488cb1117df4f5134c900e038fdcbe954def5c8b998cdf08e2b375547dff4bde2b60884a5381944ac930064bb37639d76c3000742dfd1c2bb38b258e066fd57c1d0f9094dc1f9e658ab0066a5910e15451d0ea437d1d6cdbd11cc4d774f49046576ccf591a8b9fc97120019bdd22eabf48d866a786d18dcdc190087a6a90fe3c7c1153195f80893077b00449d57fa60d9f95226db8cd73625848da61a27a3eefd294a768478f66253d400db05e1345185e67c94b8d1b3afe1b9233c35e6eb2d72f6e9f4febb25a3a22500e7342ea4d9bfe68fc8bc56f6fa8357aef85ce55739fe14fd543f74b82b1a7400d937d0508f5516538ad47708f3d29ee74a59b7450fc3843fed037e898851890021a4e313a4f16d623e58c2adf2d5f3e407fc854169a48c6a9dda4ffe70df4100a8cc6103890a4b9d0d729fc09fdc96eaf3e34bf7440564e021e116aff9eeeb00eaf7f02e1f4b3d6e8eaa34ea52db98847fe9a50e725ef0ec7c944653d106c200360f04dda2e1b29b24df33332e2b7e54502141a8a8327b13be04690b7a1f1d001edde01be7dbef455ec04e7ca3137675a2938925e1bf876c21bfb1de29a21500070ceca9a305d9975c572818d4a44f0e56fe98003b7b584688242c54df690b00ab99eff89196f0423bb8f48b0d956b2cd2152c61db1d74e0b47b2ca3170ad20080a1048fc188d02b45ad689ce06c5b00a36ed4f1d71e3f7bce57ecc5f680d700cbec513e7846fec036dc2c911d4a84af5801dad44d06624d6274650de6ee1700bbaf52cbb6178791ad13cb326ec0f55e3b30d6506c1b999dce3092a9c5922100128e3f52907ff7afdfbffaf869ab6f869d664c1052f1e4433d377f1f9a5d7b0048c1e4e0236cb35c4e2363b35d4156d42bc439bd5230073973a6012686378700263b43350f0ae46b0f38bdbeecedec3a35f6d3d9773545401f0f5aba7434a200d4d0c4586a519932335eead45ffcee8265a8d41fa7fcf66303f4f673f78f33001d38fdfac603288f1fd4811e1d2c0c3631d84f7ebcea7b0e3a302b8130e47c00cae1ac590e23cfd618c4255e8ec3b65c9b66269ee9695f2360276cd3a5930c009b22270038308a39831a93ac37aaccd1986e8751cd788161b0630141d81e3e00238105ab27c9eb5e6fc353f3723638a11c17d2b212b4d6aab5f131499001bd00f721f3abc56229dc806ca54c371351a9c08df825c81add8c26da9ec4fb2133003c14d4c7c31fb8c2c8c8ab9fedf62bef4fe68318b6038abbe9ba4ac21dbf8000217544b358a96c3c632de5af7ff548ffdb06cd312fd611d2cb9de29cb83fe6006ae1b8465854191ab0f3cb9f224c09688c94a090eeb5a5ec34197ca7d3c491001e7f23cbbd828b9c0e12d2fa2d81835855394266546185735cd714c7f10b0100d8ca9880ec893e9bde8537a4d141c14ece7d92f975bfd93481e1a748ba040b00b8d66fd0d80b252c346ab1009b2de35cf3625c5fad1534081642056769dae000ec26d7adee913ab694cb2242960a363f3328c066ffb5a00649ab2fcc43735700eae746c16499a50b5dcb21c9cc9709a1bdbad0b0a1e1205aca18eda76a73920027472e41c486f39002cdaf4a6a3ac682384f08bc1db0697f6c2b33966901dc003c72e1dcc7eb5194d3be2de95c6e1f2dab5e685476659ffd9b0c4b9adb02e8008cc2346d70abb73ce14663e7e3965bf705be64f48bce63709ecfb0d04e7a4a00a90ae36abcbea955efbb3a14ba50db5d1c367f02ea5072bd6973e27b84be4000f9c3df9ed597769dee7ebc23b17ad5cdb7a01404486cf8acbc8a948f81249200211914ce82aba176b52c6d9310113fc54dfe7b5a23fc2757a8cbc5ef4fc374009c176fa5038984c67cc625f661fdcb8f53388af4acf0aa33f2702e124b8300009444f733fd3c4e1a1059854b6161b9687215f28e35fa42a7606dae03a7f88700334af455f6ce3f1d04f10554904b689ec848cf88f38d6c30f8246afe8c52a40085e6edabd3e64e50ffd4123624c0ecfc0a7f3e57597311b779ec3b04217b4000ae917afd2ac81090e30fe5e8247e971ef7b9dc58439e02fcd9f56194e8e42a00e05fb081325600a705cc3e037f8530050d12c329dc113c7816b30316bea716008af44ac9d0151c106bddb669a2a3b5eb9a8d41cf3a40dbdd58f2442cbbf2860001822b250cbc50f341cdd890643704c1e3dfd4e8bc7a5f9b86c116847d4c7a00b27bb2b1f35bc947964ed990669e59a32b799adb127eb60991001d4f16030a0055f0b8b7f38fdcc52ed4ef5754c427a3c2eadba841948993552bfea30298db00526b235023f5fff092c76924f028ae7a23354f5ab171eb3119ca53dd8463190042aa62b92225e5fe43e579db1be3103eeccd6aeca2c126cae7e4733788034c00b4622eb47a13ac59537a584e9e725346947aec8e0b06b047a60c86b8eec174002cbe16ee56b5a4c9e58abe724a9cf0510dfd20989db3b3d3b78ccd7aebf4940048de2a6b446f091e7d0dab92af3ac49e14e98c85774f46b34bf3c5497e76b2001d29e4d2cf2202bc53f755e086ec0286511b475d513f3602dbd8aefa2933710004e4c6972db14c39c31cf3b13a0f88e9a201435afd024eefb0abe0695fcc8b003b2a40bca59efb27e9851843d43de7f7f21fcf53b98968c66812e6c19b5ca100ae28a2411a07ae9006d88ee2742030a991904b94e48bc9d1538986eeaa8a2a007a83d364fdf5badb000d8f38567c19dfa25f61a20115716a2bde2b79461a6800d27b22fd7fab70ff15b525e5c2d9e74cf62eacdbf252e86eaee096f8d1476a00cf50f5fa03b8a2b4d3c195824a2c8a3dffed2b2316a074c195ad153feb86d200e0310c9896c48e41a9c2de4ba53aefd60e495ff7ac758f977ddae291e7f965000c3dd4740ff84c17564a43e82bfad4ab0ec386627eb730c969718c8d3c003d003613a0bd576130d25bcb10ff4ab789fa3146717b3ca759a6b1f0d884144a83007f5214e19186d12dba2b3777b6683e7c8279183d08c6c0e438b5ba064b294a0050ce022c35f9c47d9825d3556c74b99e5e20eb31667ee0326fc9ef66c739d0009fbe78d1862e01c9ff1e2349b7ee91539717c6cf0c40feb9f665aba53175b900038fff89917c25ce7b297802d377e13d70eb65c1359526de8abcb2f6b344e200c54abd68b17f0b6afd914949200e785b88243d74ad6496d3889d45c53e461600c858dbe4127d1546764624c0c59c4c6684561516aa01fcbf01de4d2220cf4f0004dbbedfe42982069c0dc97c0408c7d0a70a480cfbbe12318064ff6eca175300a0de9743aec086d3fdb0a0ed6df712ccb80d912b23570d5c4eff17a76ea81b008481f84cc9fab340ea294d820a3e92c030bf66f45657ff9e5d3f15e0db8cce006927d57f73bb2d6b0857410316abb7a880afdd59e82dd1755306b5d06cc60f00cfdbb4f749d146048d31c18ca22ac65ff06859035023cab1c9f60b6d14bce0004d21ecacb59787da7bdfdcb12f14fd415905485c0f9e445aff1d511bbd48c2001c47a1387c2dfd7d86bcc164815737440686689c0e7a612c54932eb481cf12001ccde44e55620ebdebaa670d0481e991be6fe3d19469335e437f2c7ad04e3500cf43651f2f504d890f5a5c33b253cf1176f3a9905c5174a3952700b179522300f4108e9ee92ce38aa8ac4df8974a00e11372c3094e1a272c33ba5a1360984500f688ef82fc17c594b974e4d97dfa7da175c63850c2cdedb9a9d6236c659ec800dcff6394f868a98f2610f192313f1855b35b885c2eb44eaa55d686785c9016001c916c65b8da26c087ab3250fd1ca47c5e67bcda0a4573075d5744396505e900e05fa175f1e04a184ed64c342cd6a0e8e5f290f550f6b815ec5c640c90c8260022f7d00081733c518182a011e7a87a9cfdcf689ae25b67994cc0b5f302453c00db00060c6f2b510945eb71db439560d6035417937796af55a468ccdb746a3e001b622181a27e679643d98662774595b853a400b7c3cde114399efc5689cd0a00b6f39d93dadf39991b39bca096d7b6b9e3b4a0630ad4b1eda49a0ae8dacaad007b894d434655e57e00672c021bfc91afe68a1872ef59406f2336bf27ca41c700f5ed229356c53b974e0648ac0259dc5429fcd2cc1605fa67967f514b56df2300e1d007f9647f7e9b0e4ecc317860ccda641e48923deba644bd9d79c69ce6bf00698768753aa2ec5ba96706dfc7226ea3a9e014bbaebaedfb05c06e6b9639f2008f33e282f87e0c027d7039b2925555039b1f3b70d2f1fa04235608b5e5e8a700c1548b3b1b8c2c1e924175539e9b2939964fe18b28b7766b958bc11b42bbd80080894ce4784486222fa27cad82ed5a1b9116a5f68af59a7f1c3b91c4b016150055db90b06773ab9c2664aef84bfd41879c207f1b1da2961462e8985e97f78d00192e7da570b507699dafa43d27d7dbad01748cfb149842b4d4ed8d281d28b100058e3424109a22f1a786a9f009dfbf49073ce0cc4de90f3d367b32009abb86007f6eaaeb9dc532713b8e0dfbc6d1925bd86b6027f221a6ebbd1f686243b584001a92491bede1ec10bb78abf03321f4079edc1bcdbedadeb31273a66838dba200fd148ea29f9a628504193fa73b4d1750fa14e973196280053960c46618eea400d802674d2a6a7d4d3f7cc20110f7355f7365c46c09ba8650b607ff4bd100cb0012fbb67ad169f9602c585686b51f292885c039a96e53369f6e6d5479d0aa51005112bd7c512b357dda6c70b3b790a02067a98cc8939a7756029646b9653daa0007f72f44e719f00344b207490b3902bdc97b0b562a971ae6fc08840c298a0a00b0ef29d656c666d5936958ad8ed90927d7631930843e2c51808f64c3db1354000e9f9ccbdaad61116984c8416e7ec56e6ea7668c8b681e8ff2952ab551e62e00df02bacc08c5937eafae69ff848829a8e9676eed18f0182d2ed006fe345686005ac64b8f5eb6acdd7d61566c63c6ee141b352de522eb06ed6a66ac56430283009b6934db4e10a4656bebd6938b65c8709c7c1138edd8812e168ea1d4b3e7c7008db7f8d7191c1fd8758ebde988df4f0c585d1d8dada8bd1238b24378f62b350008fa16be652677866544366300ac1cd24e7059c969b32afb5c277a445e2332007f76dcf42294cfcaeed2fed92eea321d06186a38cd40f079ac2bccdc832385004ac4e9216ca257a6c898cd06350dcde84f0f4ff70005a2023f16ba7b1a105f00eeed708f47edeff7afaebb8f71766edcbec583eaaa2dfebecaafdb9521eb2500b4d7f9205d7ffe6ba4be69abe440fc49a42970d98aa169e73372af97d712e20068716c6ac97846cf5ecdf2dc36f86a4f9feef617b847b048441976843e8eb10010aba68f9f4639b54be75dc6515665084d4ab0ef6f7a96e442e9c7fb42bc280096f54983481dc15fe0b82339d30abb122d0813534d72b0f2d183c2af05cd30009f50be5d6fec437b650490c764c3a96cb6af487d4540567b88c789284bcc6700991ac5e25f4e21496533f0f8cc8d92cb380aabe49185a0c53ef0b2e808328400da8e6cd7a05354a3e68db0a1fe5f65f2f6b8b73d6eab05cc662336a386b25b00eeaeef7ac9b9f26b6e2b4a4a77b4838120c605eda42eb0ae0c804ad4fa081b00f62b3196add5b01f9636ffae9d75a178b2ceb1661e9459f43f0911af15128b00cf8feda6be87453c42a865acfc4ff7e8885202b8ee866acdc8345e89e0ef330080b7ecaf9366fb0b9773e3c23daf653c9689d318313624bca13e68b2389fba0001fa71829b01a2579a94ee0fe8413d8638a31118c45534e18f739f7ffb2e7e0034dd860bba0db6182101a5b36f1ae1ba610ebbd32659f5ad61b6ee65aacc1f00cccc7d05f147bfb3efffe4f3816aa5c558e39e3f9f2aa439b06a138d91882c00d1fb53e1175acc36141614bcc6b4a9d92cae22306458175abcf9ff386a04b700950c7b381138e110ab51749644df92179701d4b4553341625bde8557a6a501008f65f78d6b486e5aba16a14de6e281c2353cbde3e556956c84ecc69bb74206007e909bb5da7ed076717afe00582191ef517702fe654734020490d21cd0937100a368c281cff4dfd1c2a24069f1c7cb656df5000fe3e642ec6509ff35e3ace100d2907efb0f18eed7eddc93bba4650a068810ddc2466d222b544d330f2b4e3300a057ce42a6bd947a92aa9f77558613b2c6ad2146e78e9c3a3ad1959fffe659008ced9b2f03c7ce7d2abb7000ea852c6e34abdf07ae9118e7b09e4a1136c07f00169188d6bde95262a73190eecda5b8cfe89699de971900efbeee5611e5f73e00d3dd62047796dffbce9ff806ba0f1b22b1b2556f3588eddeb54d435a3743dd00c81c39da4538cd2a4c6e59ca298b19f52c25acaea12c1c000a7a2cce718dd0007eb9938a4b1c3aeb6521f6af25644e1b4557ef01b71a61dfcd872df3b2f4f200875721bf43116cd400a7cb6d40092994c4327f19e9dca29a10b538978ded8a005fb6280cb2afb4521df0e47ed709d707db4da78f4f6ba163048b6a53c7986a00afcd484ca4b5e9676afde9f4c29bc6ceadae709e7a70ea297e09df9b16bd3b0076a68122904f00030ab950386c1b969cfe88016a1a66e86a15a2b91986f70600f31e516a81f73c2a344ab5cdd968310af6f38d172a124eab4e6427065fb9e500ffe332860e8972934fb8f809dfbc7f652879c284319898c99bde8a18a6a3f8002ef621ec4a91529f46ed1b0c035987b1349458077e819a730812ece2081a6e006c2ee977587fc81a2c1940e8ea9e93ecf363d18e187a581b39817b078a30b100c9c2b0ecab5cd7c0ad46f3a5a4b9b3d511ac6b21f1b1f7b0b9ffb8f0d3d9850064bdc43eec513f5f285939ccb37ccbe4e4eacf71e836486538115a043f0f7e007ad675ed2f5af3ed42498225f68899d042a742014e7880633c8023411f5a7800257a823646fcafcd395901574be085a44eff237df62ca772f0a3ee253c1e9700da092b7294a3a0dc7c6913873caefba629b7b9cab2c176d02645c8176dd7d200e9d3c1a3714dddfe72a9ef9f7f1fda71179c6be89b147b7f99133c8197945900b0c9ecdf9e860e0e4df001ad41ae3b5189d883a30ae6ceadb00ba14c1ca77400fc227077c6b76266a8efc481755c5821c8dec974dea3d4a593a9abf1bd5b1c00aa1003ba7a9c8eafb7f0425ddce1edf621d4f482769027795a455c2427e6fb0044feada1f53cde32d12ab59d469adf5253ff3468e32b615ee93386e31d406c001afba4974eb09ddfc4a8fd2cedf2f9d7103b2cdda2edfb58242298b9c41e8200123fb1c1aa98bbe08572c0eb73f26fff9036a82f479e79dfe2005222922de5006e0c6513468e8de27c463766256e9cd27b43a120115f1dbb42336a1f21edc2009968ea2de6839107b33cafc21a2551d3f49b251c78222eb2bf8c20fe386d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","kzg_commitment":"0xb04a21885899cfb62d0768bd27e98f93d040a538fc9973cd5f3739b3b71146a1c5a58f301908387c80eaa8f6119f841c","kzg_proof":"0xb4cffa2542194d78b15d686992a073c241456d194dcad0b5ed95d792ce1400dd8fe3d3a9d6941a7b7775450c4379bdde","signed_block_header":{"message":{"slot":"7422094","proposer_index":"129686","parent_root":"0x811c9952feff5a7c8325635f1729e31ebca866ed88a53aa5f26cd11d4b9788a0","state_root":"0x0bd0bd3f512e5f64d36170790010238168bf0dfcdc22fc438fcf12e7675b33ae","body_root":"0x71d8c523acce371dfce3ce7bc2897e62fcd72eafa2870be5ce6c08b94d444fe3"},"signature":"0x8ed9b52cc7323bd7d16e7685c4e5608fdc3144fd053bab8d2cc6cd19048b0214d2aeaa541dc4221e4587d9ef9830ae960b5d417951fb79d86fea3bfe31a9fa06a83af01ed7e579896afc3ba14e3be41b7934ddd1886a79cb23cd1a9031cc7668"},"kzg_commitment_inclusion_proof":["0x858389eee5f1408b8080eb8fa22e3bc4d9e3a4e40ee5bf5dbfe4146831f7328b","0x1b8127c003fb028cf043207a1ab815571f4ec5852339a6a21d95a6c5d841b68c","0x8c0b1d87cf64f28c21bd39edc742ca5f7bbc3dd5aac8a97009fe53ccc6b47011","0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c","0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c","0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30","0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1","0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c","0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193","0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1","0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b","0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220","0x0500000000000000000000000000000000000000000000000000000000000000","0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535","0x56bd14bfdc37d27695b4efdf7f9851efa0e51272eb0fb3a5934f0d9f52ab0d5e","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0xcf8646fca4890f4bec369e0f281f4c3199f294b2f3b3812a4a2f76639c93742b"]},{"index":"3","blob":"0x001611aa000000000465ff01ff0000feed0c87fca6aec3e94ea2dd3dcd7233c800074d6794e1ae0dda37a99dc84282a7b5377666839fe8446a304a3a62b7045000ea5a03352c1458e09a8d4d7dd48e34ab951b3d4ae9712174c4ff7cc3eaf6f000d1e3b24e83db71993b8e5b8a9bb239e09ebf451f3a62c0f3b802d4092ae4d3003296c12f19a9386386958cd05a3d90e33f6cc21aba1906bd57a98b9ac0e1060085e1fcde52166286f7847e733ec042206cb77c5a51ca603a42003f4eadd8b50065d295c85213b4dff36685d413854ea632efba746f2f892e2f0dda003c03e300132a6a5904628b734d485791077337e153ec4d611ddaeb76bb18f8853255880042a2e4e176eb566b435afbe0b833f2951c8d78e1b279d86787bdae5afc625f00411a7d6fd3b93db9b5c54c6bd1b8a1b230b049f9262d3c12c4df982fed35da00f056cddde2ab2133deb65cc8e82a4d3f395eb22c5e062b268cd78e740342e700c26580c999db15d8db4b543a51de1f2887565a34853be677629151ae91e0c80059bc6952cf25c064f40c5886c63abdb3167bbc9ad2cf8836915d83379222e3001efec688bff4771bb7bcc7f95bc4710fb66eb3a10ad3003cc1a73ade30ac4000977ecfb621699e4d3e846a0263c1ccf3ea7a1b23efd22a96d30739616788c800b8622f36fd9f8ebceac64515032c96f4c2ecb6fbad6fe49fd5aa1470f02bf200102d7cd743e91d12dc6b03f129ab8d91efe32e4af824032bbb227e338d1d6d00db3b728ffc3e7bd773bb2062087f36eeee1492ba234f70bd74cdeaaab4e83b00561417a6765bf5b2dde0f24632e3b90b34fe88e5c4c326959e5839cb463eac0070b74f3fcd3a37609b248adaddda734414c9e8e9d2b4004829621357049e6d009ddee33df816b8e8b1cb95c106e2e6e34a9e5e85d32b730a4765682aed2e4f00f893b378eb2f0c1890a3aa9297ad6da21f390c57501fba57950945a6d9428100fcced09a29b1d6042d442f44bbbc308945d52723ecf0471ebd5e92a18aef8d00b046d3fe71dc9d792191b5f808a3eea5202afad69dcd048f1e7f228f3b1aa2006f0d74d48cb49005da5a9894860ab72d5dd1cf7bcafb05980c42a45c0f7d37007ff876956016fb7dcf573ca84c7287fd5bc2d7b95f52b97eb1f9f9ab2ed6a10008c0dd20c0945c588b0e9dbd3cd31e5b3ac235ad8880e446ba508259181622005b77675140486d132ff0b8e2a92eed643f4a5f52cbf0c76261e2435f0298b50075b4e26edd071fa026f743d4017d4e42c6c1f6ffc6cd0c0d97b575da6a16bc00a2e1ff3cd81f03b8182b534501991baf8be32dae91ad6c5d4b43b46bb327b80000720db9727ce729234fdce97158832e94cb07f17710e823cc742b01b58ca700fe24461f9c0c07de3af44d4c9da40da640c4be5ab50bf59cd9f99ccd347c230095eaf1258ae582cab7dc26dda1444621a32de3b4c873300148b494216932ad00d8cef0caa88526d32a539ad6f558e16d18f7afd6de662d249be7baef76e3b300bfb3aa76716747caeceeb2826b88e7c3c2e0c7f66d3b2984d61957d97cd3b200a5605f30ea211adcda3ec4f1ab28cf24bf5e298cfdf922478e95235cacf2150007ee101ba258bd486f8ec60306a6b3c2e1033b9fc41b597e8f083eca24815800402c60d69ec82f2c6179590f7539e63de96a0a7411765d2c156294e1e3fe46003168d0ac9b6208f9a6c4293cd08e3ca8a43720b079478bc9ebccc5974cff3600f365c38a175d9bbd6ede460e1a0b98b82d5ba2b94d173094c162650bdab590001a139e1462aa66d85d5d1cafbee257cc3d69771921ed21a299934b1b4cc485008e5869fc5dc2f7788473e592d5203994eb866377ae9e9bf4a5e5d1f1369803004a8f907a96dcc7019da5203efd1705d22d80a74df96288fbd28ca706c5b49000981c2fe6b8eace29de255297176d3ad2aa3647d0f8d933f09d9180f727755a00d4982b689c70cba7fe1aa773fd3cce42c9f40c9a4ce227d494a5b8bfc464b300217a13357cc48f6e8be233acc4381d886653b9365631474ee5a56871bbbdd000d69f57b912b0478361fdd49ad32fca9a0709af55bb22989ede4b2f0560fc5a00f1de11e85b1d322aabed036e12f83aff1a809a1e3c2285f684dcc7cfb45e4300f8137c9b267bb265a939f5062e89f2052a0b7abc4f0a646f374232c0489bf900c0351371bf0ec7d5b2b0e4759f7eb57e884eb10e890cedfaaadff480dbf27e00b1bee710ac9cda6d2aaa30628b97c17840e0d706cfa09f73e6d71bfb0d4dff0018662bc40667789667898b986ec0669da123a7062c0152a5e816df874515620047467c8f11a8ab458ce3efbdc1b8ba3ee632787cafbbcc906ca9b9461c911b000d698b1fbb11be79c5211a25ca6e6749c43a08def8f8e17b583c86254fd7e800b7e069ff83184a43dc9a82203e5eb9f0127793f56b37d5289bb458f6dec2920015ae4ec1b80c66aa1eeef2e85bd945dd900aae598cecefbe8eb4978fa5e22e002321fb534691498da9bfd49f42bc8c3b6b8b4aaf931168423a81eb719bb4bf00a463a08e3282801855aa29c2acf18342f31b74e5ac7222d445d1cb9ed0f71000184ebe76fef008090d8a3180469fc303804106dd56ee83b55e377d008e543d0046437062524c9f944b92f90f5ffce2c4203d1daa1587da39d34c30f411f1cd002ed388b2bda1d445196640774f89ea1135f7935b7b31a928411ebc7a2359540088cc6b8dc13f13c46a65dcf1429ec6a15574eb53b00e374260dd132e1439be00c0a7846b9f3dbe4d1d8ac81a01a089e03e0c221776e25d652d4455cf92543300615ef002ad4c064cbf7182c3e9fbf61c54a83546132bba75d5155140976c1900ef2cd33cddff41198952cba07b6cbdb144b8c165c5dee6e01b6bec7824beac008d8db2dcb487d55b9371bb44b04be6708c5a5cd7c3e275cfac2c6cb7b2db4a00c591557d671808b1a37d0b537ddad15810b4cf3206819758de67561acf6c4d00b26e395b38ab436c7096ac661b28e72b56e6fef16f0622a6d9a4da30834a4a005747bb4efa11465aad609ece9e13978673d58cdf0a7fda005a7e5212a84bb000c087bfd4c45c58c2fe986764c7898a491323470e45da2e646134dcb6493942008675d051251c10088c534d3d0a4f5450e4459bbee8db2ea62554cfbdb6004c0046af839efb90618771473647a53fd30409028c59c36b57cf1b38251447f1d800a09fd8f36328c99c9c74c29de18e93a5d632664e5c488b1f0f88a134bbba8900243e43c749bb983507460d6222659911a23b0f6763c9e1a88a8772cf42882800b5b9410754b5b0250c8e20fd947ed25f75b61b19cac707cda50237f65763c2002c3fd2cdb502fed61c84c2eb6fb7442558e253066b4b87ce066ff8047e80860048807a9896fa02ccabd8e733304c4d5606a6d111ccd9dfbf5e912035e6915c00ec21e6a147e0592e84f93e20e0988b699e09d196869fdc1fbd4f843b09522000db1a59cd2200494a0835454002bb717e60ad65635ef55b2015a808ecead88a00c65f5716414079d000132ed12e4e9881ccbc7106d5046e4cd2d169cf7bccea00690483def9ef9fccc56cc769b0b38357c5e083a1a58b4a98f414983656ec58003b5b95f653d059c1136562194c075b72357b3a61b10b624cffee74aeb214ee001dd9012416b8bd4fb6a1ec77655d04b66a298fc3bf2fc774a92dd02a5ac246007c48449c61da4f5320c2e5d8ac7da0fae17d9065d36c53990b4c2339338f0a007f41c8fd51f26896fe2d46543ec63f2f43c6404ca08d7e02aa4ee3e562810b00db41ac6d831306bf7adbf4e1edb79ab1ca0575920442a019f60c1ad64f6d0d0071e515987fe51bcc9b543ec3abb02fa48c2ee04f7de5a64db939d7ba5d190c0090b01ecfc258f07dc619f872859868e8b315a5f6138a2795098f741be7d802005eb07eb2e224fff66b4d1aec50c96d1de58c77146b0b5ac07925d0d78f508b00404947033dc57eca018d2f826e4861fa8b2bbdf6667d4b7d43a7b8da78000c00dd1c1434fc318aa5ec4c2a90698b036290a813af4da7287c99cce6c9c4010a00dd9757f4a499476398bb6fae76e8184414112e14973a106b6bde1a9f47229000c8dc563e8e065c1487e179e221b399ca1e327873e18047cd17c1650755ebee00e14eed79a27caabeb299e2be95d0aa7861b4856618afef6fc39d03d175020900e0f20d5de464d9dedae8be03e8f58e1e46a7499959ccd9ca0d0bab3a1c94ec00d85259183b58b22142e7a0fc602ff7e65d27548b4dc26c99a353218602642800f1d55a67f083b88765d529796b7fbaf8849883349e6b6d75cc87e825451e30002622404fc5cea153fbd81c939cedd93903a15f45cbcb6cbf3636ab86e704630063f850572644f709456201f655a3d60dd46e3e10caef639c8441162e4739440059ddf833082a66338a2725caa03bc6c0c53418a886bb7e67669c66575627940067c2736145ba8d788492ab97760c55d803eec65358d087bc8237d0fce5c31c00627bf65daf50d93b36f3ece4305ca964f8120c324755559012a2beda28b60500f50892792efb19b6bc88d46d8dcba11fa7c7b1d9d58bb722ff095f1ae9df6c00be6d383738e50fde43f161faddef7f00ad2d66a2a6aa38cb162f4f4c793ecf000118ac7a22a572c4b5a9dbfa3f2fe245770ae15a5175d9cd0c74f7b318f53f00942d3e2133c1118e6d7d6dc65ce6e7e73f904af0f9b9bfe5ca1089c6ec024a00e8cc9a41648302b14dcb8d30cb35a511451d15c89ddd4f635e676a8ac2469100ded85b6fb274141c876423d21fdadc9f529ea8955183b2a84df53f4dafb95700c829953c53c821cdee8fc87180a14bc6fbb92efe99d9168b4c21039be45f03004aa2d5074df155b8ab779709b37872009514c749021abe8bf17d85e9c345fa0015006aeb383b8f5198001144130de34bdea0279c54a501f56740639efd60e400305a1c7da9d928b121f9dd6eb2feeadd8ccc0d9e6bbfb28b9d406739b1af530021692acb7f37b5978a827effa0bb20b86e2be96f1cb506c698ad37d038667200b64e9c1dfcd024c540eae79e835422e1ca06a7de1cf29527ea17c49edfb91d000d23fcaa64bb26847119baee1b7defe178b931d8742dd8aae9f8b09de6522f005637aabe539bcdb0a92b472eca0987e659699b18915287598627f006aab95700c060c3d01920a6a044771f67261e9c864101de33e842c172419333f37160ee004613b8e1b9cbdb806ea002bf99d4fb414241aa7486e6cf95042204bfa0d89300216093d286deb2ae50c9f688de0890472c477b04dc913de32e2bd7e67b3c4600875217185e6393c324fd79c4f989b9139036c067550f444f5c1483dd7e68d0001b1810d598664d673aec64e4c7caebf8cae0426b47607610bd74e45efd9cb800f0b7a1e3900e79d73fd7cd10b3e2a343bdb61277c873973fc9a2bd55cc058d00a0e09fe3891e4372218888079740bd55ed492b42bedf91c0d5c9a0c64468ca00ed81fa161dcdce8f3a7061a14655e983421cf689f4e5a4230e339133e75d360006153eb61abe725b1d2beedb3502acd97d9cdc36a62aa123aca9267a57493a004e0f4488aa8e6451bcd8e270b6c3a4e0cb643679ea7ddfdd228ef42b38dc8300d9d23b2a441d05f77b4dff98a9fe38020b1c8cf3424c941ba0da4acaa50add00f0a3ddc9b470f5ad3ce770a500bd68c2e0078b47e6c646789728af7c088b0300b7f8bb1495f8324016a27ee0aef0e926332c146e4174324c36b5ecf7ac948d001571092eacab8c1919a863d2c7b97272a6f9bc56417fd21d1de85c61fa10ae00b7c67ef956b65993c0601369b459dd187c45488854284cbfb4dec5985c94a2000da20a076c94d889f7cc9c5f664b422c4322a35701c7681236bc01e85c737c00e72d23266af76b849c2ac67934a3d91452c49f7c4be6b797d0ad03d910f1ef0008e7b1be020c75bc4dcc25159dbc8059a2326b38b6c9a3e66914b17bf6e397009daf30f5d640db356232d53087d78353df8b9eb6861ce5437ebc038d3620c20091cdb8f3538624f015a9b2e49db836008a467f60b46796fa910e22d716c506001b4367d819d646278f85a5d9327200dc61d1ce44e8ef4354781f91ee31bb360077334a3485cd7438ca40cfd8e2f93b009724b54ae10bfba7e402c51cb90aa300e239fc43afd93c27603612a2d7209fa08cf9396864b7634928b19166ea4658000b034e6c23b08d82ff5c03f32b9f0048d284d1297e936f76cafe84eb2d8111009214356ca4bc11f990037a522c09c7b7111a7030a5db3555ce7aa201e97810000965a94c96aa1dc64c5b0e3a5116245d8c523a76e95807174efaf0fd088f560073773d73bac21fcd8a24528956b112bfe71b2a6528f44fee7438ce64852ef0004e561aed97e69557113a252c26b6a8aa0d282f7006a3cac9ca233d835b458e0087c1e3d6eb98e4dba5725d3eea5156991344af8128e9b897bf2a6d12ac65fe00baadc7642fba859f3a1cea430d77b925e17934b11bec7e8107742fc3d806d70079fd4792d1f3c4d63942a14bca32ded9fb9dac4253161653b830464312d57400b2213268812e01523df79394fee4665288297f795747e115818a56c3b0a422003fe024bb9902cfa30560fa2c2b032bb7e93b7948349022c920ed035dedba7200104bef0c666cf58b30bfdcb0b031364e10dbbcd81d1c6639f11148032a3d7f002977ee81ec479c882687fe1c208be6c76765a85c8069c5955d180de0311a74000cad9029289cc00e2224d7a63d39d75e44ef67c16a7f4228130f505fd43d6d00148dbbf19fcfe9b93d419ed636ce94d8d246150841b2b1fcba804193dd4c2a0018af9903cce172a06180056994d3cd652bd2e16b869dd05f8816a65bfa2ecc0006b59f0252345a4816e0b8ba646d567d54f95f57113254fa18eea4d7ce152a00c27b9b49c641614a5d855065b3c77a8655e180c364969820c6e28019277606006ecee56a1335a8b2d207a7d7b76ce3086f0e27cd7bb212d9079bc276e0af2200e1c3978d42ef27066664f4c376daeaacab8108002b1df75b615bd6134b67cc00f053180c2e06280096dc96e6bb2aa73b43b80f94d9d5699b9f6648b62d4829004e2fc62bcdaac7e6471744a9ff92d2d940d3e1f7877f9fe779f91a7321a764006ec6b83d847b48b9cac366c8812016f173f02ab815cb1fb4607c6dd0438c70008a761586802ad5d64da4835188268b0647576e4da3a8b303b001a10eb26595004ea585742df1186101d282aaa9dbf8c2b1db186cb1c5a9240906254c95ec4900b4ae1ab67b0d5d13a96b7ecec230b33fde4cea03f5558696d0dcd12efba39c00d9962d2d4862ba271c577da6e3a4e3a6a05cc3778aeed62bdf80f5b31f3a920043e989cb6eba57b706b36edcba2e0a867cf9e928d619373295f5f8f00ccd6a00256987c984e2d90f44c2f76990dc394212b1b516a661a46a308f6f33ada490004bb9a5d7116b149688a3feb6925a2786884ff087b8a5725218dd7a69007b910008db766f2cb9b673d86274c10eec6d88a4505d5e7ed11d683bc3ad96b0626a00a5988a3e32d83d4e9c50b89f78ffb4642ddf389a7cc92f716073dc42bc71a300cd961cfd1d62480b7be41d6c903b8309786e0af3f171b3de6c66b6ef164a7f00477dd1d234a2ccf0bb45084289ec8c390a5fce885e212af04ba97dd7f4770300b1f127bfdc9bbc3cb2834b4828c3ac34babb2a2c97f771b8951b1386426e5900c99d0b88ec17ba209862265e60cbc5dff4a4d6d3e85a7a963559c80263e87c003d68c115ec6e77ab7405bdbf5fbac7f69a4214dfd8ac3af63cd43a80bf966f00baf6bace4a82c9cd047fb881fef7f762f3baea11d65569058f60f4a8728a07001c22ad59eec42b273b1297e7b133365a37c7084d0b419ae523e941a318dd36001a3494ed1a633a131a58db466493e493ab0e3b3cf4d7139d68880625a614c30051009702db41f3a1f1af6c60c08374ec83541a6956380dffc9547ccd9e79650005faace2226e4cfe83dd5611274b43da9c853112342a3be6d6fb246c6fe0a900352cbc6615811883ea8feac412ad074fb17545510f3a4582287ad84ee4bb2d00e1eeddd8a8cf5fc264d9dc876c65770f71564d86c44173b14d6116a99edd4900ec0825bee3bd24560983ef8cdd100db0ec612c3b6cdb48da6d3ec2005836e200732c608e49bb67c62ccb71ef913c611aabac1a5f2732980eaf76c61053dc240021724e46a9882c321f2cab9292e5e3be880b8390da37e05f711fefd59f2092001a5d64474c2f83ad26bd2e8fc67cab28277c3056ed38645b6ede592c2d383c00c36b6061744abe70f6fcef05b75791a58b1fd1751335ea5cf49def53f5f6030099c28448f4871e637989816fb8336ee5f76be47fd402a0648a91efbe94185b003bd9fce7635753b119838f5d49a72580201791a95b16913243540e9393ed0100acf5b1d7f314a29db4ab8acaad75efe8b06383b4663f9d9672d54298752f3f003f0b0cb7dccada20bd98f1282a6b7369f721f45c6d00ef3f9018ef68c61578009c318f3e7abf1bb4eceefab4d1d2be10cce911f0518ddf8e068b8a5e964e710060074f90a43db3fd80d4420722d8e19b8141f40e2a77ff0b56bf7d7ca63ba6007a3dfc9296f6a9c4cad26db30bf93bde901e7e6f2cd25b78f571444ae2a78b003836980ee2e5b9728d9f7fc1d9cd6fb55d1075feb9e5f05e1a61fde460c77400ca1025665c40281e15aaff3d63c1b3719c9a24b1da62a18dba00d588cf018b00c274b2c3ec0a4bcd3ee544222800832009c849913fec7cc4b52c9a1071ddad000d4f81d20ef4809c60233cd3225856eddb438547d54c1afa42309e08e10fd100a6bb32768e3bec0090bd01d92242404af08461f1db576f59327c4db39185f1002e77d351548153b935104a9c3418a9f6e09949de1e2da62b698f1d442f677000e4cee8526b2f6626c3e979efcff32e09ef18dca82b52a27d238978b948717700a77b973635f66ce28ef93bccc8c000d1b0c2717efc107b07f4cc9cfd4aab28000d9de9c0d72a2539d9c7ed4ab9b45f5d52fe64e4411ab72c995649b8021b6f00fdf19d9612a0ccffb66e7228c9984b226f4067b2d53a1ca9108ffa715bedcd00993f755be5a6a068554691a4ec97fc9fbe813d59b77da460394c07102dc274001f99751b8e380c9c6e073fc03cbf68fa414b867abece313de240c05c73f7a0001dc8c4adf485061f04bebf23325c2d20cfbd06991cfc8b25f6b69784e9f051003debd941233098f6c75f4e14f80001ec9322fba605ce95b9e47683750086ee009975873e7475aab425a3e8618476d57bb5188f4133be76335df0b5be27c8470023863e44a7c7e9c4772504e29e1e30b02bb9115596abba6b23412779b788b400b35383b5ac7041df1d553177042a26b4dd6d313b4b3f807a3cb4c91e4c20440060dc4d843fadd60576fde745e2ea0ff001a718b00cdf2fa5efd10c2bc59149006414873493c1930f574d8dd612db4064007f0a07d378a5a7718266385c1408006c3e49e8e2fb78a9aea53d922e4178bfc0cf215f6b5fbe6753625f8c20d90300c791dd51316d39084b2a6bf2ddbd4cafb70f74333e755b4fdc529c069fada0009e5bfe2593bb8764d38335ee9e53934c29bff26e02ec2e3e533a09e7a22d2000700708ef41dedb175a4e70f89c0762d8321fa75e9e3aece444d20e88eabd540084930da47501030c210dbc65f837231010beabcfcc0fc877e17b1899bdf9190057bee0ec89febad95bc29a62c03e8c0b0944c6ed86562ef2cbbceb1bbed8ed00978431b92ed870b7083d5ce45e101bb355c218b09261c6cf60d35559e799f700f7dd2c2f50b31923c7e145758852295606d8e8472904ade49778ba2970419700e88d5f023413b0a2dfa23707772ea3fb2511fc0ae03877513dc5d93fba52ce00b5c6c8539339d48f911e91d7717a14d0fc842ba7462bb2b567ffa7af1dc5bd00732173f248187845e3642aafaffe6f8aff41ac348b50f1e8676c7b917815ce000ea66c3e42474ba448df21f842309bee7e8e1f418c818e662ab842156f1efd00e2fb7ed355da864614bf7a823b8c2b0e171af27eb8a744de12745f0878c0e700b2d9c904733a1ec5497a55554d59a9ef831c533cc5005d0b34f25e3fb8e45d0066445050a59879626603af5d85af31c30fba840e055ab248771a7522c908860033d22b32b944b40207e69a0e106e0ebd9a8dc1fe01fe5fefb0e90c09d20d8b0012ae25433c0835db9aa9f9477e444ce7fd40f1868376143a0f11c8d2fc59e8003ee936cd955f38ea0f7ffcbc93abcc013132ea4d4aa070d9927840aff5836a00c1f98fbc3b3be3844bdc2d7a7705a1be66dc98a332e16aaeda37dbd7d0d893000626ff2b7eed06a115e33241aa6c3b4059db5df856eff56c1d741d27ae5bfa00f26167eea5fdeb306402874cc295ddb94ba9ab9f44811d231a1e6e6f13eee8004917c4caf76aeede4c52209acfe54dab997f96cb355dcdcca2e7712cd0f21f009c80ecd62642a1589e7903a68553cbb444cbfccbab4bd4520dd4b030c1afb100e635bc7b7579ab2e9174dff34636a2f4c6023fb2e0dcd0a11f46e7ed6253db00caf6f22dab69c5321571dd5482b1045eda6b5f2e8428d73b99e12751f168d600d385680b4617341070a8f2a546f8de34bdb2609730c88c8eee51186beab7ff0012711035d999ea5bc92fb41a5e42ded1518bd2ad3ea64b2b236023f08be2b4006869c8085b5b9f572b530278b65098a9454b162201ca20e9a3c8f5a6e4aa430047c4177e3cbeda0082f910ec43c39f24575466cb26cf1b0613452515c8a3f6000843d4248fb5751062f1a76e5c80a56392570cfb5c6acce3c64f8059e942ce000e5b530956d1ac285ef458130a67a6217b20d116e9a9e3295abd1d438db0520052c4750a35f60ee748781181aa3212fb7b2e8be2c2a4f4981d6924eae05fe2006ddbd3ec86d1159feb6541a143698935f271955afdb6a8cb3903f7071636aa002f24e667d0e28b2d5d03a45fde953d7f6a2b22d62d913b678b37ba886ac1fe006c85c49c89ac099570cdf14a50f0fc2d72619e9747d1233e4afe501dad829200c390a38be095f21be9520dd2715bc81cb67cdfad31ec62a208fd9533f1cb5500831f5b0995dd451d883fb325de4a47eff73c5eb86c9bb88c5cefb83a9aad0e00ee3e31d989f31f6a4e35b8091e5970027ea0ef717e0c5827ee9213f8c47a4a0089d6695126707fec1708a255bcfaf2221207cc13effbb5f736491e6e4e732c00fb16beaad09f296921f972eb027dcf9bd955ba137eb1d8c1636f9c1015b96d00f58df328854384681b00a11315880443f9faec9ebd627da8069509c568cdc600f4c8a0dccb6622139e79309bf19338cdf7158c8be40faeec5bce18c405246800f6d3fc170dfffdc1370fb3ccdb69612afbcf58cb8c12576f6761d8aebf02ca00303ee1a397ebfb78e3311f11b5231f5e2e4aa355abc3ba2eb5800e0c5d2d1d00c89fdd93b978e994c51d68fb6482dcf5f5d713e1356c7e3c363af87447701d008f9ec3908afee8d0e5b1d64577ee9d1206aef00567ddc81379c46f0bd33e7500ff70861d2b897e29b5d75c4a4bac305d84ad6f1fd35f9763e14411275ea285007eae5b005b492b03243166a2175b3f13b7604d19c1d40acab629fd7ef7f09700c327cd47b748f2f4605f0dcd042eb2aebd2473ffd2725c4c48154f275e939600d816e285c112ae3042ff8261604c3b3e36cbe396ac50cbd31bca37c09d9ddf00a60499d795952b77afeb92d8dac5aceb6ed5e07f1be2defe645b4ba5cd5fee007b0ca0ab3052fa41856b96dc541f6c49dcb834a4f03d64277f54eebee4f02d00c59f981d2adee535dbebd1faed8e83d41581f4726c6f8b1fb2660566d7482400736c5ac9984413956aab44363cb630a1feee5d558b4178f1fd29eba92b14ab00119682f92fc00a65e04ab3dae90df6bfc66f3834b6a289beedcaad7f5074d5003fa50e7a472ad5c9fa60bbb83734e34dbe5f176c28ffe0e2b5528742da24fa00419f12f5c1ff9009fde6f751a33913f470996e76b4377221d4d005f8f28c320034f4f89e99af00d0dec82e075133911a36665f490ea9860e637b20d940672300bb8d61706c7cdc4638c44605f5bbbf7759b98d7b1175777eaeef27787ea8ef003e797cc7c568d4f1a63152e059acf4a40c87c68a8fdb1002318a7197f1cb49004b3225ef318cd46597967cb232aec0a7f6d46cb87464817f54890211486fed0088ec82695647caaa5ac08c043e9a0076986ffc4e1e9b42f5bdf45511f73e5b00d69ce69cc6dcc0f0e0e27acc481a18192f76501f2b90d2d923df3cf06f7bba00928ce0def43693f32fc0f03042dfd5deac4982b7c9b7f51082902f5ef699d200741b8a1a06e61b39b6b1e5ac7fbd9e7d9efa384bf5b96706b186337724c95b00c77f9321ac24b79428bee63bbb019ad0ceba2c3a597cec00f7ce987617a44100b7c4abb0bd1a90d2aec24e1151bccd974ba22d81ff9b56061fd0bb59a9ffce00796d753f91e1666d225bbce310f6963ec568ee8a07c180e03eaa6d03653aed0088081a8e8eb301fca8d80bb8d14e65201c9a08d52cd7eb1b7be99156faac4d003d52f6ba60b8a1eb72b44e7fa2ad3c4c8f6f0afcc57f2a8ebf8a78c369915d000a656d72e6fede65bf76d69f3b82cf91317221e33e10fb098822a53710ed4100baf2cd66cb4edaca7f4d73109b391bcadc28ad291407cc8431ce5e8c611ea000e0553eededfab75d93a497ba1cb472ae0a2aa3b423320be4a3855a7fb675f8003b7816c090c8f16bde220c1a946672687fff879fdd60a54c715b91a2bad37f003fc98cb0a42649e5de4ed3506b9b2953e6241a7380f77dcd710c7eece66878009de0d1a0360d2ee7c104995870e7bff154f578fda0d3652d5e4e49838eaabf00da0c72a3cc8966164aa3db118abc1570314b935f04c83d8460d54e9f967c7900ad98914b74191ebc88aaa56a9cf583cdb6c865db1adcf489ce2e86ce5acaf000aca4f73bd1c460ba5c0a179a1844bed768d6530182067ade112d07336acc5700c89ec2019f071c13b1786736801c6cfc700659a0006c1c7d1245107bce83d700760cb9715ac1285cebd909c8b2bc796466c7800b5745d62a205458ecc9e57100d27875c9a435f3fbf02f5ef8c4375c77244defffaa1b9ce178d3a73d64028100a3525e73b56291f9b06e1894f54c793c8bb4f92baf61f21cbb9b1b862a7f62004c064b9f839fd9bc09ed6b50959720fe7617144634a44071a15f14b68f6b1c00c44621d2f409d2145413a2ec056ae8b7bda82b97049935774373e556ba12bf00ad362a9f40e2d47b1364b8aa257e2ad80acd013330a7e45b6a92b8e3822749002534b6e568f7871f40dbd6792a56c25fe1745fed2937b9c2d8035e025014df00940f5eb8633b182443872852ab9ca8d60b552b69054f692e20586dc03f44720030477df0c9fdd5ebdd08a68b32c1b09425eed8ed2f2e88bf1a86d72c29648100dd9663ad98f9cb828a27fcc8be9aedc68fa1c58a5f699419ed63c676df52640025c0d9cac1dfe1f9f2e64307af46e43e9015a2897adf6093a753dbecd6e2c80013b42d1061239b52ed014d91435621176ac671ed85eb44668783b67b434ac40084bfbbb5de9020de1707cadaaed0ee64be428c6ecb52f87a18c0e1aac0c77e0023e81a65ffcf180fbdfa775d1d1fef2f5aa45f235d158e697d58bb6a3090b700764f0117b81dd5ccee504c9a7c99da03e4a38ecee232a0587f46ca647deadd0084d1ca15d211ae09ef5e9bbca1b6ac125292ba92638ea8980cb3011b722663006db702d17cb5a0a76be9f059f71b5abfcf62166e43edb1bfc9684dc38308620072a76e73c69aa8669abb204e4e4a716926d6599a97535176f23db0b22c3cb9003e245f8806aa2cf9453ed1e6bbd1dda3c0137ce0372b3fdea614e476270b6900bf782cdc5adb5f84ede9bbf931dbd60daf41c135d68ac855a74dd786b7c8e000b4cc2cff1e05ecfc7b637938cced2708dff71b756a180e1ffcebeabfa50dad00495efdc73b878b2692254f7bed7c8d02d457eb64567b57592ab3706bf9d6a500c04017360ce97d9344c138049f49c0cb5ac8ca5874607df4ed0f3e64dd55c100df8ad583604f55c1ac607cc7aec7a0d04cca2721913c6398f7279eec0b152f00b62ff0fc2b34c4bc7265fe01662e6ffcfe31c2bb27304befa3f1a85c215bc3005b0eab11034e8297b52ce02fe0d3673d3a5a1457893aae1c637d72d710591e00397b2243c6b5d74041cae99d107be95173e35951fb9f99fcd779f8e4e06f4a0040273bc179dda28ee2da6aaf47b1e4fed57f589a9de262dc34e516a84610fe0028b46ea313706eb1d3ecbaf4c6ecb26a3a5c853ed0096893d9df212d9b4a9f00a46d7dcd3cba1b22f1f089b91c94e21fd3526ba447432bbf47694a22df932200589b7c3bc4a175e8ec1384688f49aaeddb50a9c5721f1d05095fcef8a4884d0054dcc5eb5cac1667a9e584767c06f22d02e82657b13977ca8786ebcfdac19d00bcaeed6858600d81ee5c68c898b6c55584e4f812290b6b756fc78c8940745f00c668732e771770cccdcbf7e0bf29e1a66cc88e1a406d1093d447c846272d9600e41ea0b082c673e9e5fa34d534d8d924a6420442a6d7d56277cdd6bfc8b4600095319027e40f95b14ce80aa7dc5702d3a4fcbd29ee7e686afccd0ebc3225f6008d3738e8f37c2a043d35cd612feaab1e2143e45a34e726e3524c95a737f95d007cf99706bc7248b2b99f84b2e2acc7a1203d829355284723d7cae645b9a5d700a98bb7de4dc17accb840fdd183cf3b52bb8a8feeea2c835b7f76d07b2df52300964f73e32c2ce4fcf28ed6d35526c990c71f33f8fd9870b7e38fe1dae5d47300a26f00813d42e37ca848f69134d914edbcc155efe2cb1d5bb3d47cddb6515600669a8bfb244d97fd1b292439cfec959a3bfa6a76995e6dd627449857bc10d0005f01ab7886118833aa6b75aae0dc9aa41acd5b85fa84a4189e333148915ba600e2e8ff9dd7d6d244b214e201d9fa4895b5f36d534f9ce2695271d2c42751780043bdfb2c9b8ed1657c0482ac038e2c48d245a909d99deaa1f1a11a3eec835400e1ee0a1d45424ad140507966e394b13b376837ca19bd625b36ec6ddc2f1d150037e406776cbe03571a93eb11c0078255e67f30921d376e971679f9c2e55ead008530f5e09baf327e94783eb5bbf84af57e1be8162dda8728006611595c962000482a5e719e5a2027f0a6c306959cd80994dfd66fd5e524c110a00772871097000d2befb65d64ad8f83d1c3ef9ed2914f7da05bfa51c075896072bf14858ab4006ea4c5365faa83593962dc7f5dc4bbd507e7d026fe60c76f320d5a4c30f5ec00d636a5a1bc4775051b01559709bffb36acedcbc790ee24c8838bd705ae590f006d4f445616f4df3f6cc7700a0087643f0ca698980c0b73f07e7dee816e7ffa008f556575bb2af1fc79a54ca1da6a646d924970b213ef1d88c604942e887bd600bff68aa8a663599d3e3ceb228c52b044964b90a5878908fce43830f0b3ef2800ef4c5bff233cdcf0ac9b87883bcfc31da526fa6fcf9971e1884684247db7cd006d07f198fe0b9ef9d711611a609ab5192d2e4620ce50f6f0f7ab8c32ba4d9500ecb5a229a40540f218505b48619cb37d593728ba17f55e06305d806e99bbc200448aeaae940da80a39450aeb81b958dc91b02c63b137f635b79fa65d184313004f9cb670844746e5bed3665bc4063208b06590496610efc152437b4718c94700cefd123b14b26407809c232ff1d28f437fb4f9283370e9742fcb19fbd05adf003a83bd54bbc7e189fee0ff35085feed25bdf07c6fb602ee1f50ed130aad667006c9c023e7ccd77f436c7ea2f43fa0a57346e9c137d3e359e699c10df2d65be00d902d945619a86e12a0f3612a627fbe4a12b04ea4f0aecb6527b83a0c3e2d600dab9af5956a7c26b6c065d0d4e791de6269574be032854352915cf96b8b2810018acd71ae103691714a9c3de07fe5f3c0487ce8333c554b0a7c5cb3569075f00a89cdc9c3a4e8e0f897c4a0945f5988a9bb5fb074b4406cf0040b6275c693c00aba4cbe4b3f875dbab6dc7bd77db0f75b3775185e00cfceaf7c52c59e03ffa00304af372510ac605726b8cb9b9c9947d6b3f655e0bf12a548b567ed004386f005425604daad5b49445f922d846fc9476e51bc6da3a983e860f786ea7a04f8b000b154bef764549c11b0aad536a45d33fb6232ef4e25c694d83f9988f0063df00e91d446d5676c0803b8fd820d9bcdf85ae0267f375cda0c915b9d7d0c8834300b4bb798e29b687725c7f3db8175f888ccb33c123c57c21df0ab76ce48a0e420047a797916becb8e7a1c169198faf2f1067cdca1f090d0c1042c3d70b07c6fb00d455aa878bd1cfdb23b42174c377851f27b26ea4b0da88ca75bdfd41a3959f0080b7d03a30ab7d41e18e6e58dcd63be45ce14341ee03652fff1f6539c24557000435a3ce126558d04a0f845aa720778dd6b095d2c38be09eb307457e803adc003297c8f008ad3faf60b35ab767b76e830da26fd295ea2ad3df45b6176c78e900e22bac4701670ed073b6cecb1cc4c98da6e5d1c8ad057905b837088727f28f00f05a8bb2d772c285b5026c50d4c26d81d6d2cdc7789d57a88b270f36130e670046c4cb4861da3414592477159d42e5ffeab52bc81e3369203396d404027c1600bc8b1d18902c0032db2857e3bf3e557594280bdd400341fa32baa33d75cbff006314ebe4f9f0e1a991e5b8910b2111219f94bc125d861ac38dd664b7e0784200e5b24a5e54ab1accea78d6477183439f531bcaa456d1bcd08f9ebd23ef50fe007e4ead01ea6ef84e00e4a94e0ec5edbfcb8bb6607f81661a9f6fe9b58bf443003e9d3299a6a81b3c7261e2012356d41cbc3e13c735887c5dc0c9eaaf13ebaa00518a2f1950196ffc67b27c4d05b1538c4879ec5fa52ddb932c8f3aed7875c100f4fa821125f713bb0cd98aee0c6c97d28f251d81952a466d219897e18b907100bd069d24559ec45702304e974e42433063be9c38d229b6c3644d45d5019dbc00cbf82253c8a56816eea000517178ccfabbc4ac000eacef6dc7d6813831417800896dd357441acea7285634ac1b60a201d06dc015d537b04df5586d22870ad40017cf80004a2d9582eab868286edd3828df75e9ff62ae935725399dd809e8a6002474fe60d2f294ab5c36e812c99c8fe0a07cee54602b2d3017483ef3347c210042a4d659af4468aaad404bd7dbdbbe5d753b2f10e2155dc18420ad4f98ff9200a3d5b2a3280028bcee5c560eeb09e3f64e4ca3cd8327c497a2295799a4de2d00a80231608d5b0d36b69ca6ef93079cefe62e5660644cc8c59b4c6f49850f9500f1320d043dd6c9a3356bd6b842d5c3a328eb332d33a4bd98dbd931f5e4e4b8000853632de926b5a302094be0f03e9e8357a079c3d015a9d2eaef16f5976d9b00a3e6edd4f5a01c993a0ca48c09d77c1a08e4193b7138c4f13e6f4f872c1de40096c36b203e28c7c75e21036e878cce483ad3e7feb19dafcd16b3f67846bf2f006152747915edc6297afcc0f3fa28a82442fa1d01dd2133f79a285cc5a62116009d1e757bbf22f14fc25c857ae2482e50b57c18c089880c2f74262e90389e0c00056f9b0790bcc723c93127712260ce8098d9f6932ac5ce0494fe066eecfe7000c91a55a03caa4960878b17223d024d7eb3a1cb56c76014214fe12554927cc1004175c95b6750daf8a69fae10e4ad4daf3effd9a30e8f6b30ecb0f0eabd0fdd00e09baf3ab8ba2016a60e2b1fdc1b219669becda04f1f2f49472174d60c9ac900d62311bfc7d3b7344933cf30c9ffb5ff66134a227c0482a725eb2d869295a400b7ae7cb23ad36c0300f2e9696caecbde7b69972d531ffad4f7550e99b3641c009e4b331d988db8ebddf2c6edcd4f392d44d8f63343b63638e948b89892ce9900b315f5ac99dfe51a507003d935f94da74a769499d4d6dcad560846e6fdefe600073929fff0753115d2520d36f86bb6b6fd5b208b379550d45db5535d0355f800dabba3e7cdff4f24c4ef34a7b9a86719c8d00b8ad8871544be4c55a3fe8cc900b6fe880194c80436fa00367118735b8e012074eb8c61327118aeb05cfa818300ecb6499ee5f50fab01c0062d00ddf39b3315a428b765712174e0f67b1818310035e5dc3652339ed2d9b6d7dc5a7ffde245d3dd389c4bce1f76ae30c93204f8006e23e3c307f3fc4a468283bd91a8cea9d75dcc739ab0eefa50baffc656682f0009b24687462f4c227dc7632cf8896f95318fa9b3a8f123e770323d85e1dcb000d01846386241115684e24dc0042667bd62555f1040b67859b3eba8769151ac00df46f1905a06d51316594d68fead0025bb3d9dbf3a1e25f325ad001faffd0000278383e6bec29be420247528ef94e869e745b77a4481a3698d46c2dfb5a62500ccaf693a39b6a7d17b22e7415c9a43f5fb66c08fe094139b9dde51557c08e200fe26451fc85415e591abc9b30fe48d265b31dcc954f1c8eb300e3d97a8a07f0032c9b4a7064370572d35ede8c98ac634a3679487f6fdbcbe2c5ac5d9be3bc8003e2d30f0b16063e6955566f59dc0411dd04050aa95af41cf9a00b6c7a5b9df005258ff55ee301f0cdbb8aeedbe2546a604bd73fad81a6e9fd6704db6311bad0041324571ed51ea5e70d7494460ce8f8209c5b8b790428fe5cb7a85b52020c600785040dde6ab8087d96805d2a9165874baab344c92f5aff02bb965658da7b70053cabee760663d06f7edf0ff178d1f4470187572115ab2176781fe6ab7f6ca005f9ae708553b7f03391e6ceda5cab9ff82c4fb0274a8814e1765f08e72cbe400c993016a8f1baebe95dcb5ee210cb089dfd68d21136dcc82946ec33a0e410000fb274ca50a3c6b1bcba044a2be3d564e3570e93c9ae97c92379de6b685585b0024445edd5f46ed38277b2f3fdc17a54259c56a6ff9aa19ba90e29d28d2941500a2706da903ae3e19b189cd0649985410a578f8e9402ff25fc96a4a53082dbf0020a4451e161e7072c2099e5f04989ca3901cf47457fe319d3a580a1eca25d3000a701cdda29212a29405200ad5c1c479dcc932c7dff730ba0e1111d8ea7e70001172ff94e255248d4dba7f0aa7d2094a06cd9821be84df96cf1a67ded0935e00ac048c9c477c3f5f9c006cebb659bb829b7d3a2b486a325071adfc7095df1a00c0c1f6245595e7aac0639acc12e0a6d233b10905d09a1040825f70241169bb009f3eb5c88ebb83a9c0d82d33283013ceff5b296d265e8d2aed1edbdeb7d52d00380f0cc6fe75a626e1e8006ab9aacffd468008a39ba8ce2e6bf091afcf9c840019285355f413b57d4f9145d1bfb60a7ba1245f0397948a17476d7a1ac8fbe400a10da876945513b5764549dfe8063445b258cd790255364bb1da25db7d650a00f79e2c150aa4c3f7f915417acb35fdf51926a0f5343a951163c5b931693e9f00ae9c2f8337e46beec7b309b87b728e4c21c4b05a9a869bf1fe28e3f933f03700acd53e7f9bb2c017a035e349c7f84ae37be4bbf6b4ab956dcfc1684efe34f0005c80180def3ff1935874f1258651d934fdb84d808a0ccd5650a24a292187c000530b862f176ab07b2193dd7e8408d53f0e098594f9bc4bbe29468bbce40768003c94fb642c5b47dd06e8d395aea5bda983bf9588e4ec0108734b2f70d1b32500c941251e403be022a442342d7230c57ea589a9c172dbc116555e3e83a7ac3800cfe0baa2294d660fec337b16689366ac41fd4c8f2f4e9515417dbf1e79a7a000bd5e15b987fd583b3e4c53265cf9d27826a9d33231d72ed80977b6a90bb4b7005d83fc8177d919eda87d7211ef780038ad2023f97e4cf01e981304c8e4721c0013b9f761d612cd929037e61da6557477eb6d73e4f8025b21d1f4632fa96f1a00243cdd277a7b0714f329ce3b527c1d67ca67c76b73a605915bb1d519bc0f15002e7d6ed652918aee5535fda34ebc246368d96853ac7bdd57b8b2b8194923a100df0d6722e7b9a96e6fc9c63f9ec7fd2cd0d868863997444c60030c5ea8cc310003e9e3f31c2276f3e909ea82e9ebf9363ae0fa40f1a018aaf26e95a029d54f00dd814abd096d3c3a21ffa9d55a38557399d9ae42a667edf541f58242711cc400c425d68972d86607b3f941b7700bf2fe87caa00546aeb5cdd2456afe4aa058009bbb356d19e4db0715b888464e2eb75e9e6dbe721e3f371695e0cda5dbd0c20087379276e2f3d1be9316a56c8c14072f88d38e60090df3d898594d5533600e0063a9aa7a54beabd6e9a8c6f7c3a2de66bf9650eea88f9736493e0b247741730053c749e2944526b7560b84aaee785b06fbea5475782fed8067b67e266973ac00ffd5bb0658319f50b82a9fb314c747ebe8069109d0be775408c25e0b5e8ee900310c503aaf6508483cf7d4bc425e35f649a393a8e7b987c94270bd2c4794360001a9fe5ffbc4a4f04161c905d2c75178ebc8d4f31ea966feede1579710f9590095e7cb6954afde09218e3925184348ba4c1ab1feb364b7a1bde947c8f0f2e200d6b2a20cad6f745a90ac8f842fdc4424c50e21ef1b39b8baec61259a1a324700fc7a689460a438f948b2323efeecf67db92c89a67f94c88f8fb92b98f8351a0077d118f7f06f5f2adc0ce4b87b36e76c112f0136548a70badbda011ca6505a001341a02be168b8a6d0a0410e1af74da204be7465464223e82a69cbf8b8037f00489741c1f1443b4e9796fe53c9b5e2ba7e7e869f130ce4bfd9ae69e63f08bb009492e9ca32ecd90c67a1327225fc12f0169c08249f8562ba0dbc511db3e94f0071a4e59cb7d541fbc6501e46e6d414bb9bfff23a39a431e42a618e95aae671007669b11eb0025ffc3463d6b6676d6d17889e4c747d3248d0e46c832e6c172f00a3bd1dffd523062917d373379d2221cecb5caa5f3d855ee489563661e7abe800d8ae448303f1e54c299d9f27fa4936f6e7117c7cdc694b1d17f52c52680dc500fe79a8e6cc4e33c2b42b1293c1f61fa9f53709271bc6b594ba0d5e674498fe00fc5f3ffd9253c81e9e0319c0b87bfcc1d6f5a2caed5d12cc8808d75a322ea100371d8959d4d8e562bc9eab2a14b2e682a8d677a19eda114a80766786509d160018cec53cca359ebb17c05980ff3c1e4d3b436a184093ed4c3e2bdba22421960038c12b7d96e4a6a396639ec2e702e807a8415b9fc83241a4076fb7ce7dc2b200e2f107d62b997e7c2edc824b48833605409abbbc9c829a1a2eb8412d21333200e9e25b05b91a2b2f62f7b7231fd0f617e084a1feac90136099b88db3ff9ad700812da971b0d274b7d7cae32c4474086209e0d55aa1f6bafeabccac18b3f2260016b46e338c141c357406fc9d04068e3c99e41e6d1eb28f323a66aeaf81704500c51f2cd66291ac8150456c99654475b6c532263f80b1d76af3b3b708863bc80029ab62403c196c02d7824f4067e734ad25834bd8be195018fe1c69f0af50a50021db359fc14305b1261c2bbbdca75655a5819cfcaefcbd85195d82b145e4a300dd2c0aa548568a26c743603aab4885fc537ef29fd2a63f2fbe99d7a331ee8500e779ca06716c7f03482418aef6ed8dfc774bf724f8f331f0777b74e4a317bf0090f0242fe1021e90c0513995e17574b81601adef8adda9ca4ad2f11f86aa5600e182e55e22e5f4e9f283748a4f29d315b57cbd59323654a89b1c25064d096500f35367a3acedab12a80c9960116d0e30eef1913fdda51794d43cf3b8bc247f000c7729a049fd9b8a9504c10437ead54666736c61c917715c9420797bb8dddf00dffbd2b14f07579595275be09757bc1d676e48937adf78e42f57f50bf602e7009182ddccb457c0f0cac8e38d76756d22f5a82807f771aed24eebc8d9df266d003397df4cabd252bc59cb223780bbc0bc854bd1c39309d6139a191dd6143edf009105959503f421298c44177a8888573a0e643a76b372e88b740115b7f4895c00a048bea35a6e4a18129cff2eda486b26b4090e1a8995cb9376249bcc3b0f84000cee1e7f45706c9ef5f8046e118d98fa47749464bc8d85c48594b4840ccd63009e1ca617df9d406b40e130b2f2b0a0993aee838d72782d42bbd36909a1ff1c0075b5d3bc5bbb0d08da7713be657528089cdbb3aa387043d5c94b9492bb92130054df6c0aaac3125e63c21aca92d94090407295558d69fb1b1eb7038526dfa6004deb89308ed04cc3816d17f013f02a4e16ea46d2304bf7409fef60c627bc2000c2cedf2c143eee5bfb0792ddde3cc2c79e7678a826de047790e2efde53c833002a95fc4639883c9ac5371b749f4b5bcf232d7069ea6e9bbe956bd849b99d430097b9198c70f60a64c9dffc69666f15477c44550e9ea7ae98acf746340d81f60065d96cb51d62bbfcbf661940518f4c6c3ea36349183f1b33cf363110b5ebeb00eeca70edf4774dd55179451cef78f2aee6edcb1094f9aae5e07e33cfcdd62c00e98a1cc0b3dedbbcc3eb7f8bde0fc998adf1fc4941cdd99e3f5224b224cf170091822da608daab303a03a469a70bbede0838951bb54c27b0ec8ef1e51a559800ac96993fee4dce19c4c2863113cf0f6ba1dae17b83a12a2be92541dd130a72007e8ce7e81aa71fb8c54351aeeb888e1b42723c776ea6be3f3a73749f9fb70100852b988a0df18e4700a3bd209b943a4bbbcebd3ef616b662951d0ef88d0953001c9d62f0d5b54fb7ebd310c6e27e4abd1d7f20146a6ab50ea7f7a1b5a94d71004af9c8e2ca55a7028cba123d41636224e45c41e0b75dd721a63eecbb9d351100798881f15f7da1c17a4b7c49e071fa8e34c7d9195da43778bd42814ce1dcef00f9412675639142f2ff06bec5f66c5428a5ea9cb8b880f44606d4eb3444008e005eec8a1911ab0a702bb70e04f853866309ec315be8faca50c5ebc367b869c500413db6e99fa56caa0c094d01160ce45de3cea3acf12c610f8d74969df4715d006bc04ff794564a8b7ee72e8b2ac121ea0613d1c92aacfc6e4558a63633b68e00536e457d2af731702366fc14f2a847187ea51379d59759afd2200f4b03e4b7002c9995c9596141a39725a81eb95f1b4af65a7d57893c9d22c0f2cd5a3945e30090789bf5d0bc104e1a89aa501f358a00e39b56258d1fa184d23a8fe94ac0c9001f07fa6d657ed52abd3cd7a006665688c4e2d2424458c30f8b7e3efbd06f9f00bb9f9e4927b87e278debfa47b52844f0c47260d7d54836db11ce5baedc71a900cd0eb512903b2ad52a46444fc16220a86907d15affd54d4f92d2a7fcf7f90d00e7d34574bc9ccb340905f12a9436ed79596ee797fe3d863a511abd9fb3f9900043834cf49709093726797723208363a4faa7d49fe58e9b64fdbbf6a52397c70012d3c68b08598875be7191af09878c1c779c2845b72c57918f737514d01aa6009dba251608e77a4f61f1f29594c49dfbe12cfbb1c9386874ec99b30bda09fc007b1202b61ddfa917721cc779e4ac6051d809b5ec143feeaedb71ccbbd8e70600a4225f8bca50246896a5256a803d190ac3ad45b7854bd3249e647ae51f1776007956b4eb2d5c1d0a53e53bda399e62a95de5977b088e7a2bfca17e8058bb76004d6fffe424ed32563af0b152f95274d9b2127cf0fba2118f9a77799630b7ad00496b4e6340742b465fdcdccde0412c4ee58b4ffd15c9c4cd8d87aec241ebe6001b3c68354f17af91786d1a3fc14c2a0e4380fc0ad15e8f119a7a47189c1a99008bfb5a2600fd4bd5358b48334c24d35c5b69618597106977c54908aecb9ffc00c6a85a7095e9079d1e745c4a32c20021290328f4a4f179a92b4978681a8590004346c564fa976d72a8088409232fb8539e567af5a8c22c245712f3e257adc000c2a20d957e56a511ea7e621f3cdc77ed111b50aef6fa9ef9df9c0b5e71d51e00c8653f26afb2e0ead80d58250dd358ba0f4ef2334d8e183c96dcdb5039394d003c148c5fc0b6975e964a6c7e05369c771d57831e9d059d3a4b9f151c59bbcb008fde092c9e7183008e57e00615460ddd5595ade705dae6e4e51cbde76ec66500863a085a03fdb99ce8e42b897025d344a40b6507ac08cdd4938dfe94befcfb006b23ccc9aecdd37fdd4b55e7f1b6b3607a21fe922fafd7c739a64a124410ca009431879393d0d698908f60f3770b33f7072d6759b9be1193dd972c4c29cf9c00ee383d3f6831211f2833f4ce2083194c7ec94d8bbe9729bc2413bbc4ce1b31002c79040bffb721320fd586b6d762ab5ace7ad03a2b8254593bbaa3f096a95c004cffcd1a3c4b0b2a8ca2bc889a47504fb2703d48ec95dec1109cf0e4ff1c5e008d66737b944f8dd23cfc8adb78dcf10e3e29e2f71781445d6eda464ee5d2b1004ed91858462f5f88e1126319ef5c35fb1417267b8f7f2e71300a0809ba9d41007e390cb827ee532ccc8c6b8ba9063175b5cdac4426cb1c38f679c3df1be07000f00613d069526ab3b169d1e8717db8a24793640cd4680a8154da94966ebcc500ce0fda937be4a868fd8dfa2cbf889fe96332d6fbbbd5859e9b5c1adba17a5f0086177dedbcb28fa40705e102034d73dca706aab37b4ae804a9824543a5b44900f1343fddc0d10d8d74a4fcb5d4050e1f93eac69590db03f11505797fcf50b000c11454c20841604a42b3b9a0330f5ae77a986ab82ec8687526b49a81f97f9a001ce555c7321c47074f75d14939cc40af0f3f94d46a3d7c76f218c42a705fe00068fad4816106fa60025fd0904913a7ab366df69d523a91b1295d45bdbbc27b004f648d0f9dbf348ab12786bdf129593cc0e83f2c13f72688639e21fe4b125a0034de986cbc99954a794516a57fa1ad55563c3302fa4be6b55cdf709eafadbd00fdef19be5795e7ac4b9598c3ec6444716ec2db1b5cbaa357016ff5c3b2212e000bc91e4e8d0b371d512cb28cfb98c7696911532b532f73a4b5d48d5f82ecbe0054324e665adee92c19a9aab885b2c5d6d2454aefbb05c8fb35490f08de792c004beda472ce5c8ec871ea2caa55e311b0345595e0cf22eeea77b5e3f929600e00a196bae41761e1d06335f886b3722bdd213933121c3ac6e5f5b32cba695af90068a4a972ffabdc728471098d675fd9bb496da472a3fd09aed52be5d6065e0f00789d6cba68258294139455368281302e50545c6ccfcea164ca092383da9a950085835ede0b33b1b7e8591f00c556465733d641f9134e566dc0bc82e8eafdfd00f0ef1e91f1447235d44421f5c1b90a638c66f04dc6ff30304f7c3bd711f45500e682b841095b6d97ed4a3f0ed268d482550bdaf163fccc44ac1065d8ad59e7006e099cae30f4ee3542428559369b5ccea89ed68a334cc7df82e9890a38055d009a7c02f32acce2846a1ed3c6a3c7349428e375acee2641e71c40a9d7e65e4c005b90bafc133737e209e21edea40450a2ccb8103a696367b914f65ecf70fa5d0074a46110c2b1562212b59ebab12920f49872e6f0c08102e74c82c4bedd4dcc009695ef569b9c6b96b860fc90be9255af570cfa2bc8a391b4ec4487f6be5a8400d30f6b4800c6074f42716d3558dbf57f255f9abb47d66bfe1e33ae15c132a30029012ecd9323f3e200f4ec4809540f0f76963f9ca5f24116322b3cfc6dab320059ae79d6899376e4fc12b1ec5cca2dd6bac01aa07a570a612ec1a77fa7fc00001fb23983c45033eda6e5ad558862dc1378c640ac69f27e02c55510103042aa00fffef2bbfaf720f8c12f59fef406457a6ae53655d57d9196ecb64e478bd19600cf01b754c9851c0319ec5d9d4efbac6d778352cbbab18aac3c539f1f0356340034f412490c816a1ad53bd0605df74af525af5cc21076490450e05435e77a770094a68c0878257a5f7e3df2dfc42531295e88e196cdb3d388c12f69dbcdfffe00fc2b63d1aac6c4bc3fbdb015ec455fee15ca08f63f17acedfdfd06f6e8505100860a268e91ec22dfa3e701d34258114482bb077f2822d2427a2f07dea795b50039a4e332d99ee7ba093e7b47319e40c636d4a392f0ad6e6704c740926525d40021b242f9ca766acf47dbc5719cfc1ffb1d6d1f66e31b2b74bc434927fcb1cf004929cf7bec8dec4ab620aeda1360dc9ea089b2238c75ff86917cab9d64118b00b98cd39bd206cf141f8d80b1bb94da1b4d16faa7650d930a6993e4dc04f9a000f30685a1fbfe4e3d23ba0dacf7e678af4552392a915f604336ad29e3032d730002b634f777bbe8b5de1a34776cbd9ad1b2e01f2aa2a7b669a6db50e04e79b300c69a769ed8c8bb80e0c81a729c24a95985bb310da27814671657d869ff61020075277f0c039ade3034fc660763666cb1386088e7d8397df25249b36c0842d8003ba4f59f94e6270f6eac0b52da10b5ad1323c5c991b1502e3d68488724d8b90076156ea02b0370c7f11d161240c5b74bacb561d03cdc36d59fdd8fd400aeb10085a3c3760ff0a8f53902fe251055f1b30cd41a33f1e266cf1ba7fc35ac1fbe00fb5294cb7b4d0a04631d64d0ffc8c40037b3f004b6a482d470fa4a5e0fdd7200667856717d73942ccaf5d9a2203d15244d0fcc33fe91de349dc955abfa47010054ed93e03266e27cd9d8e65ae3a75afc099a4b9f96d83f88dc00541906ce70008cf1e4fca1c967087b562f5456f15ff3b076c26b031ba7d115c73a626074b400216604413885cdf13b2f9cf50b73d6f7cba9873888ce064733cb7b4b3469c700cfc86ca465ce03296b1742b597b7cd1ed9a6f9b7c74f3eed6021023856497000d797be3d45a5d700745d26a9662b4323ea70181ea2d38aa51d3503ad17034800f33513d341dadb2816dc3f35d1bad86bb8e8a69764a7b6f7f0ddcd65d8b7a100148948de6247212c84713435e6bba66dfbbd3284c5f0dccb7c2bc0fde6b0cc00d1a30be24e36f3bb0161acb339955e2526331872cc2810f53dc552593f9614008c92f3d086c756c75fa1ea7623cfb8a20b18336e9d546c201c8fe7ebf0279100dd0e352e7d10952a582c3b6de0ec6d74ef43ea7b73a4887c02dcefa3e675520035a655de6bae5f27e7bdb45f4fa67b6b4aac11462a8f951aa0e4f0bc0c1a8300c1a7d7112f1de287d1727e085cb68f513609fb3f53526cc9721bb92244099a00c9caca5b495d7a25ea3faf468ecf39166306ba18d26f23e094fa1c02aa1a6b009a6fdf0e17f5943d6523546f1eb118f6031581bbd1e65aed774947f71bd24c00c0f94743bf72917b5df6a7e2483520cbd0716c15339d023204f5677094f58e0094c82008a3cd059305a92bfb768478dcdb01a846009c68e88568ebea9feacd0056e4d4bf39db45ec5af2747f05af631f262b7552e06fd9e39db5ef085378fa005191504adc37c0cc4ac548d6b79cfd7c32f2d7e38984b478bfb1165c4b38fe0094ed9479a2bbde1dabcde3bd82800e244eb588f366fd5137b65ba83d7577ba00cdc888171f61f04b48408145b4f3be78cb399978b2abfcca8997f126e9bea000d47b4b50316ff000d98f4de5feef86b3f0224f098dc2a49c97180b294823700001824b05fb2401764c9129a74bb5b80445dac14eb312569a6a6770467b48b400d6e7d6a9d69ee7d59ccbc998ca6a3734e66fb91fd3326ecbee5b9a0c16934400b244811ea4e04d4c3c84d5d44421091c9cb731915716a456f2714acb3f03c10025d5042b6669c0ec3a2227c6793fbde00abd61b717945af4be03bdfa44e52500679e12f2ce3cd483a5d32ee1833010d8dad6de8853a3a178d3f5a4dcb38ccc00eadc13bdd91a8a3b8f67793019289deb017b0f54e88f44cf3b85cad2080133000f94ce1170f107b3cf6880638488cdfc00cb11a492f1230fe0fab0e0e413dc00e70a3223b7267c4b348b875a3983337bebcbb2620e4cf95e4a755cce97fb0000a8c3671d48e8ef7fa36ad5dd070e382526c2d706cb0044a471b42d83d3cb74008b06fdee85b513bc276392fbe963b9343b2d492e2fae20e72721ee740eef670030f1f456f2c79c76a7ff69ca717f249b30bab62f35994557fb9559f94bfdc90032bf40e5bc960904f03140bbbaae2cd3964ff4a1476b42a53d03e3fb98b5c200974556a05a3cf58203d75686866b5f965eb4d1cbccac28c04a517e2df56e94004baa550cd9aa3dccc97782f7d75897c367744dcf04f67bdfa8cbd44e03ecfb00da4f4893d071e0e542cf3d2698b8f29f9b9c1f22c2fca4168c92d8a0f6d7680075e2a9af2fa3e89b11fd0a92ff66837e9f0816230989a5afff460506db42bb00c3fc4ce4b9421dcfccffc04de4eae8892491467a27de28e63c8e92c00b5743002d7455b4269e526b7887b0f331b45e2cdd157139e3ba76f89dbfb39f6097790042065b3a5ccfae9f5d657f472cf7bf44c3415698149fbcda3506de777643d300114779eb1aa24a9adc0defa06b4749f72f32366bd9ca648b35551620233ecb0074a09cf15e8c718e4b598c4fce5f5ff569cf9d44069d69af97c2a37c9ed29e009a86ff9a22b9448ea96093e19d84f634920c8424d8273e1e60bacda6b856ac00f06c1ee3659bc0fe2c56f3a83fd7eab8f3a5d2657bbe040d50c139b85bd758002293ba76be0088b304fc6e5594ef619b63f8ac6d430fec0e0667cce64723dd008b7baf35a56d22c4c5a98c58d17fc1ac7651740d0202eacc754966c7508c3f0054b927a8f72411af20aec24ec8ddf66ef3e78b6ed72a232273a40a98240d9e001296c0b4db42f9ca551fc5b3b184a12864bf895fa031077d535f6e595edda100ecd4b5d2e167ed4eb8259888a42b8fb7a5986a9e029ae6e8d399a4a1819e0b001586c1476cf64e635c63ea280a9af01d3c0375e66162e2bb9cb7f3f7d319aa005a768b1a9f278aba889414208a84599710bc562bb9336540ae76c528cc26ed00b492ca6d43bdcac7ba71a992cffee77e6fe5d9d1c1eeba282eac62b8833880001b273c2953ea396f1336db27f7edd591daccb83d3da40301c61e6ce5fa968e00764e835d18133130fd7ececd78ace9aef09537d5b0d1726e2b8bf21f8d804e00f4e8f6f618fd6f62105e1761cea6eb05213b182a37864dbad1963f22e8de82009bbc527e8a65ac80680845c2e4d8e538b7f3cf2f8004bdef4d933bfc2b5c5200f8877a6f548e4921ee213e3d6fde5346c09c249ca856b2679f31d00274b79d005cc1df1109c23045f114a7d4c3b7e1a77c4a3b675d4c3c3fc5e43eec7b096d005f30bc385f9f493d73427f30cafc479bbf117583773d911ebdb874a80a123c00aa4c27fff9d15ad44dd391915380f1f8948706c8666500ca5765d9f552f930003bab861de205211090cbbef3621a5472d80fa663ca2bb36aa0c748b80116cd002931a21531bea535ca6e405bfa93df185c913943f419fbfaf5990d2c88aa8d0019fa35a11427045d0055da2d2de3a2c1eb245281f95e9acd9a2a90fa3e6c7f00f3f0030bb4bdfee7bd4cc6e38849cc4583330f28553b1d24b9031644d8bedc00866618673ac3f959c36a521bda3ad3ceb0eea4f40080e17ed59eef83b26dcb00c02d2a567006f82babb387a60a9dd99193dc59155e228998cf10813642c65200c74b050444b79fb258b1a202f366b08a807b1a397da08209ed9e2aefc39aaa0077a28a9801de92bb596023c1d50fa417bd0cb1680f225e58dcc8a03d7a773d0094da68f0b0a9edd1c3b2959e97c74979ce9d42e5a3f9a5bfaef6ad2e3aa76700c1fa550632f52b5f2865b1002d2307592ffe4d743bcd1369354d2499967c980097610eaa33744926f859285de808c048377a1c2d0e472a2c4cf797729f7d91001563628cab5b1e19c6b8de910d449d76b137920dbdd9c20c75ed8b6062dd9100066f3867702addfc122ae52efe4c988cb202ba9579b4445d271cc60fde9c820091ff8365a6f9f5ba85a4cc4a914e5e0edb0584e37fa4e850fd6e22e6d42f54001c6bb00565e6f939a6b6cf9f82543a223238b6b0a9c0fc8106111e4a6984c8002793cad8d8d4cffa503e7e26d5f04603997b2d8cc238c27d130946e601b3ce00babe2a9ab9bbe351dcb6dbffa99b920ec2a288cf9243d8cac82452d9e6c6fe009b61a028eb654ef7fd6a1c451fdcd1a8d22ad94fa9b66075bc1dd4e82bbc4c005dd82d238efbd02490fe1535a73c2ee375d92510535d6503ce13ffbd077c37009dedda0be1056ceccad82ade04abc5eb0a3c4a39c1e4dce1086fe55cfc846100dd164b5976c2fe298af587c0f4c0062259bb6b58f8ba2a9390535dda46c2b400ce1aebd378cbb9a83c3225fe380596d8b14adf10e42f0d68c533742ec2e5eb002063bc7dc50a5c1c6eaabe1be4e0379521b1cd48d44fb70ab15019c074be3b002126eed273aeffeb5caee0a466de08cf30ccf4c5ef90dae4e859dc91aadffd009b444ba04edc29ba619b35cc750125582f8872ea54e3e6cd8bebf108adbeed00a5319429ca4628ac68703ba6258be6be8db037f12e5a6d9756c3761ad69eb9002686d274dfcee5095081845823ff1fe6dbd2a19b90d37c9cc99f073ba83eed0015fddc6e1c03e9231b3dcd3797761172f8b5d05c8a23200ba2e1e9d70cdbf000e237b810101f3093df202c886ad88b49d8ac6fe9c04bcd1b40583db0ad2ce30083882da7295428ff8748cdd6e86a056f3da1b8fff9c7d294acf26005669dde00eddf3c36e36ac413598d8bb86c556dfc05b0f8a9bd265fc4dd370c5855411200fc557e49fd91874a69432269281fdc4538817ae99afd412b75ed12e43c19e5004db140fabb4577ea1eef215c9c3412c49f34de9481ade4ac056266190f6f1700cdd3c896b5aa09e0c9f365c5da0bb1bbec10859f9f8cd9237cb15b9e3b4b5700a145f250e627535899a98136ec1702ef0ee6493e9b1890a052a1cd6b3cd41900a0ae62adbf446e3d3d46faa2bc2d5b23b3e460acd56507212b7d86a516a948004a7d69515a352958fc8356b54c486dad3da184aa27f2a58f2d53e26796b927006f5c316b4d9cc0ab53831382676e06fc65878d6f6b11a4f970af197f12ef0a003b1d7c4a7ee283b136c263ec0ef4ba8ffc77c74ecfa2e9df2d980379b4491200b769aeee179ef4e8886093758612d88d98d55a2a1c780eadca1995ffe84c3e0007239053e9015cb6ccd0e94ff8c0a30b7233166746aaf23341b5f4b2f3f6af00521a613ca730411fc5300cc0a4d56b371b718d5828fdbefaad4bfa5ae9aa82004e86d662c80adafe97e1ed5ed575efb031435c0711184bf72bafd285b77fb40074d2d8d7af19ffa7fa9cd311fde9de066e940d5b19f8c2582c051102422c8c002fc150916ea9e40fdda44cb4c43e12534a22ab29f6ae7610219057c24e93800067adbbb28bea103a41f003f11832cf2a3908a0f3b05180755d6cda3116ba1e0071c8ced3814efc7cfa3a2ad8405f655a7018ffb62e94d384ac75c86e58d57000cbb8088c5c70d9ee41c23d0f1d484ccaf1bd8daebf30747f1a21339fae00b9002b1d79682c40bc08e475f847761e587ff303a8c5b345cc7b05d10db88145e100730cc36ac6d993ff8cc07e27aaff096ad2f06146d2ab53fd9701115c696be000479b0214df2cc05981b3f871674b76c34e235f7227ddfdf779d3e638c0e53900c965f45d323afd018a09d18b3554855c91eb02303d5cbc67ff6ef14443712400162a2cfa7d975bc211cc7ea73ec65d71085268fdf72cb3deaa75fe360fc31800f416fc5a90fb2aa496ebe841a3ebb41ad2cda4f58a3f6dc6f788f08b4f2f5500795d6a65755814de16e06acc689a8315733d17fecdf3addf76bf9b3a35007a008588fdced7f82094844dbaa42301d826284c54106d2ab2074b9a685f2c4275006e108355a40e32990f1c748ab64b74abf5bd17e32d981cdace64371b78752c0022db09759d5e25df0a038bc524c4ac5e4cbc058a852ff56f48aeb1f0e20cf800f62ad0dacdada096092845d57c21fd232cfd2cbf18ffac37a8f6a95e9685bc00e95ea18989de4b7ef6ab875a357286ab17db6b0c93b7d24bcafac7e7ff0fb8009fb05b1399cba10e3980fb7a3ea3ddcbf590c52a791b3452113ba04fb42ac1005ef5de51364961fd4dbece8f0e5c06f151948542b0d70b33c8e96f296e7075000d8dd83384e98bf5eaaa8417a0dccb8e9e8c77fc8f4ec3f67d2e13c1e32d7500dbfe5650bc7cb67a727b73fa9cd965278ff2c9cef3a42ad7255cc52665d84c00f503eedb46a21accfeb8f4bd96cacd7c08e09aacb48b7b32d1cbc5a821031f0010b230042e0f615f4eff261d0ec81c0fcb3358764b35a099136f4f0aab52bd006a913e5439ef7ab4877d25f423c0043aa700c9b27a3f6b92842c10a3ee159e00393d5d8f98046ef0bef4435ce5a90b936b54370c72fbbea3c75e96dbc7bd550018d48eb8d8892dfe1e7d797dd5738902f5e553bff9f9045f07d3b856bf31aa00cd2800f469caecc3c33d69a02ef5483ac7969ddbc816a55e223754e27e79e200842a209e4d016142d26a14b50fa86348e8eec03c6783f6b1d73729716af32400c34dfb0620edaf3b9af9ef34fe98f87d6977f81fe6e0215ba3ac86aa484c65005c533411f2d184852d188956480bc6e75830c54290207a09f485ed15f40110008a6f952a48a3cdd824b56ad9ef7ec5a96d922624b5903a5e5df5cf091b984100b09b4cd9484dd1404d158fe160b7e6645242b514ded531f5a9ba0b11f6963d006512fac45a82126108c47014e606c906c3ffe63d72abdff48b90260c9c7046008f76ccd849f51f7d24603d41fb7f759c4d98d7a89aac54cfbb2eeae408a10900d438ac885816eb6a17e012f186db6ed565e9a182d046b3de57fa6f6f7f3c4a007b9a39a338d10e69ca67c3803a42daad296a19b1d0273b70444d5eeee51e5800af0d44d262ae3af025e0904f3186ac842e2408d3f8a16c73d802ca072ae87f00a984aeffc58bc84381898661553b086578c3cf273c41d02f685f99c420145800708c2fafd8b379302e6675051d687bed19b3cf06b699c33fd5d228a6d65d7d00402a5c37fee1bfccc791948efea0d5e75b6937ce0509300986654aa499172d00b6fc170330b304f6b58db2b2495f32b9c186ea77a9aa4ae63532db1d47f08d009fac617e86daa8ea1044c16aed826938183f5e7e2d0fba7a6ae238989c5eda00b820f03785bef3d2d32d533fbca0608b1337f3d8cc4f6ed7ce51e5d28ce5ab008074eb4e8c6e3d3fd9c12e58b5e61dd50e93f2e731b6febfbf83589f058751002f0376002d6ca6dd73af30f2645141bcba18d4f475d3c733a225cc44b20de500f7d9afa305ff8485c818915989835257df8df2ff99cf816cce8e604ef9251a006641a0920d552bd8a39f6a16f4b80892cf08cc9b15bbc96bf61febe1c42d71001118dcbf7336b1a77ca45181d2f1433acfd1cc0c30a27e043ce191f080308100c3ea26706ccb5f5fadbf066d4d81d561a2785dcd208ed33cce2bb02ffdbbf3005b2ee0e2fe0aa33025b847f9ab64c7fac3c3acfc46385532e93b799faf21cb00be5438d7c9f88376197745d2f5a3aeeb7e717b44a4686ec00e7ccbdb15634c0047b500504510a4fc6652a60b30a6e6254de3890d9101b99f6ffe884f3757c000e3baf1332c05536682d84b317e06d86f54c7894cd4b3aaf36bb1b697537b9900ea39ad264ffa05d6d6b3e957c416a4a68b014ba272cdf6a49c7e1df34b2a7300928c85dcdbc8a6289e1fa6c08ed2fcc0e6abfcfd20cdaeecf11920e4127b6d00207c979509c4bf2b0174046aa8097f0a28b51857f28d5d9b2454fb7957ab1f00ab16b17cf2561b97e1be16684eab67c6c95994e1d190f5295c1f431b8d7879002aaa3bd3b1dda50cc3987eb6d396733d8c188231257547028286032377a96d004b635acd9ba2a4eeea3d261034d3318ec874c97fbd2a9bdd29a3ab54cf67590059abdeebeef4cb495d77eb32b917b5e9030cf2e2cbac3dcb3a691c32ed57d500cbc851e58208b5e54aceec174456111511e8544f653ccb1242c68fd14e3473006f6424cfd29bbed5449b2d67d7837ef50f86162a76c598b52e8986f40b791d00b0ceb02d00df9a2325eafe5502d00085e66c96af2e5fb26e22c4cde499171000aee3198069c78cb22f4f9e72f868c13056fbeed2f31e7ba8f1e161b82f588c0086d420a24f7507da6842cde5a2123f07e0d27ff565c0fe29b9be3ee703bd1f00dc912367db03534909763148f3fc810dfc6d833a80d1f8ff3baf817a5e07b8004dd58f01746ec39c1f938474145fc62582dcca719aec04f8edc33a97c0d1f300f7ba46e8733b782feae5e75c0625d9ec571b04a6b92d5b68946f0474e6c9ec001fe394d5083f01b49febbe66d1233897dd98cf130fd88ea0f2425700f4514f00f330831720f46fc2059856d80fc253d471b4f237073ca8590ab710d9e4432c006aecd708f88b8af09cfdb739876fab8bff2fa1186d3b6acfabb6b8efe57ada005827f3975c6d4c5e0f2990d65df00df12ce3820eefa8e0474f6ca14632453e00f446d9a0d22b24f4be4b8b5007c90ee7df67a1045a133f0a89e0b6d4f0749800e548e0a42b121fa352c59f3f3119ceff642f1236fa6f7db13bc84f076980ab00a65ba27fc32f24f0ef337c05dd6187b0a96b8eb0ad8ea5830708270e157a4900b162b8fd8a931c2f5ef783f594a2272f0ae58eb9909d8f6f1db3da616df89600c5d42d548083b9fd6c85b67bd59672ed6aa96ec2e7e3a10af4cb6a9fdee17c00ab1ca3f6213aecab41a81bf96561a2620877832f4b1eaadb8ad85f60a5739600fab96531658a3544d989ec25ec59117a1f5b080931b429e48a9264ceabd87a00c3ea740164c8f09bb14809713f4715d674267e8a3a791cf2ef9d0ec4e724ba00f689a56f2412f79af65f8d6d33e642f07d868bfe5375a978c0a3db70c758f5009dfc87c1c7c6bc3356d8ec3fe1d0c1cdc40e8b5bdcfed335986087cd10a2d4004529b17a0a8ba07d9d99c702c34520adbba82c2610e6cee214b8884bead1980086cf6728f9bfe3cdb551015b3b35d284442c034addb8357e6130ee5b5a3c5c007a5164bfed43a00ebda0dd13ca388a69e6b2998cd59b1f79293e2ed5d3748700899b2049e43098f1bae39ca853327d5f813f29f97aaff0f6cb5f9f20ef9dfd009c7afca4f7efc534cecf9226e7c0e5a2f2908b3aefad81f0bc7bc45abd35a200afbb53854e8902f6ca133453715b8762c174649275ffb1fbf374058d0e8e5700520ff805abd3ada4b6a66ce4b8b05cb0467eec9dd29740ce495a46b4491f980046a678944a245524e966ed176cc7a8cf70419e1dfb21fb5ba9abc96f01213d005e3cfc94f87a8f9a2044995286549e94178be0b06e47e27417c631b453446f00067f0e3e52fe83b003055988447a816dcfaa6283b0da6fce5245e6cb46455c0047b4a4be3e39086b16e5281dc7e435a0f304cf8d28a1ea63d52b1f4b383ebd00dc6f284b28f9ca3c221fb4fbff9ab2705a250490b7b10daf1c18aae15a9ca00027a6f56e344aa8636402191dae9f32d6608d1f290a14d4729d95786faced1d00f25b1888a76f2e49fdfb786966e59b93ad54b1cb7fc8c36c82591476e5191200a5828819eb834b93715a28a391c8625ceef8fb528e367c9757faee90420b50006fd795244ca2f301d6dfc6730edcdc29caf5019c4c2570f0ccdb7c03a4208400e665126b1141a4a0201159706b7e61e53dfc2fe469b402fd8370222fa179ee0071e79c79ff5443917f5f7dc999458aa3428f9206c0ff9161f137f6ae355d7900c786a81d145ab6674ca2c86340ff022783cdaf70e9be7237294adb47fa83dd00a868fc5fb403e8f72a1f19d1d98f3e0555199c39251c7cfc8f113615c1539200b0cc29a51f52aa33fe662133e64176b9b12a2e2f40057b5e657532d224699c00802b2df4694bc86f6f56817d5f01c2be5bc624813694fb63e0aef2f3350239006ef2ec9df6912bd850f30aacc701fe4538a2211455bc5724507ed0f9f1b3990037a8742cc309e4641dd5e1ec6d9a846ce5ce9a61efe3aa8ed1ad4e65a318e6003118dc68f303112b66b3724daa42f333faa9d201af0a4f1f5e716b48a4004f00d609d74a2b9f35903c981ac41d764735978d687bc21ab339ea098019250adb00402a18ae8d90843e9654c28146e073a378cb5f216851d7f52bfcdcd72c5d180072e7283d9e28391d6e3a6fd08406fbe276739466af59a80ed4749b71de4f3c00a9c96b0a75c7ed145cb78954a618b2c195270c5c23173d05d4260ca0b2454900d2aa7e8ba2ebd164b139f4561e2f21923047bb29f40cadfa1167d66a7ed1760053d7c8c13c2a3922b7800311e7a9f1a71d3c76212988cf41989cda4bc16f4500879041d405e76b4edb7242cfd9affafcf591505d58f7a10c071254097106c200499a97b08a57f6e0e7faa0ff1d77afde4d4f0cb68f0f438181f9862b1c08a90049abf56f09d9540acfb087d00c037dda58be0b9783c85c4fe26e4bde6ae57300497b66efa82f977c854355ad8038e15c0036ebd2788956da7b56f7548c1fdb00a0eea90e21d55a9d22160d7ed473498fef0ff3265bad8916679ad4e0b28ece007d7d1c4d89281e4b0623bfc149040d24aa872299d2c3163f33ee62f448031100497e16d12ec1557c7322a91ac48b125c5972f0d8afd7d8d44a905b4e1310e400fa1857b6668e08b48d8e9ca1a9d7f5c68d2874f224c5f635f65f291ae0480800d42c406af4684594c594e0aab68b8a4a67e824b8ff26093028278bc805fead009dc553faffddd4b9cd47a9ee5543c67eb7cc6d2085e1598bef2bd7fed43f6600e876d375eca06cdee04c3340da5557aca7a4aa3b9a0d99a94f9279d75a2c700007c41c5f80d7358a7b7fc071a609e905171c323bcda9ef60c0b8ab316c9ace007041c0648790e7ecb543753ccb1f2fb6cc22af81e59f4483e977de990e5adc00876edf391374adc7f31b8c8fa613361fc71d86e62067a3e1240acc15bbba5500518b9477653b8f49623c79adc9bdbeb7c4854bf9daf65b922634ca768570ad0079aad96403440febad3ed1cc9339e810aaf9c30a8e24ae2a59bd818d27ab2c00ed2b047c837fe707bf6ff4125d91b9a2ecc096da8a0985c6344b82c4e2d4d4003b0f0ff12031a6474d7e7673c9191fd132710e167d95e89ba5ca40cb6a5268007e6c19804e90e1537b7493b14bb9d1a0061ab88d6320b258eef56b04c78977006808864b2367de7de5ce7fc1fb8078d1f2d00f4822f2f0a232e10fd2808bd70089c0281f6b036578dd756dc11815fe30dc01feb896af8cd0e658b652aaaab000b7beafb5958b924a7f8c3d3d205c7e53deb44f41003f4bdfc45481c536737b00c44f7307bbe468d2f7bdc617483c7ccfd32aeb2d834ff76cc8001011a6a7c300d1248c1e06cd6d2b9f5082a2a5751bf582921dc9b29ab6b8ce95b7110198790044577e9aae83d538b05aa5e711a896d8c9349b9b3e0ffb9b818cfbbd1fac1e007ce6b185b79b384068a8a0de58ec224e1b5cbbd72a9382beb35aa81f3e3a0a001d29f36ecff180c1a6447dfb7ef0761f98b30fb3bd1fb21ed472b0b7ae9a270048514cb1d13853df1c80a4b536b553eda08fbd767e350d0c54f010e07ad42000b6ae610d0e60ac846a5956c2ffe2ccbf18a72a4b3f62a44a3aa113dbe9699f00a6c6d808fd37a4b070ef4059f4d845e9e7a187099df5744f04f400892c2d08006cf76697b6e005cc69db9715fcc10b72b40b1cfbf5ea0029a7588ce5cbc55d00a361d3d921fe041010375a135db1e4892ea7e7d63fa99ae13c9a95548118c400f1f02bda74e5cd325006e3e5a028fc0808fd9495dfa3083d3b48980c2ba5dc0041c1cf3dd707c6e7159a3653022872c08125c58c362eae94d1e30c4257fa5d008f972c91425d6d684da11f15de4465aa310e1ab5884d1875f043fb2c55955300110a8e343b787f381530cbf90867092a60069aa7e3c13fa59b7a448b26902a00bc09ac816799b0ac370bcd09ca3de309c4f509fec8f7ef96f07d1ec336d768001ac567fa9a11158867b242ea6ff08c45ee63786053d348d1cc3a618dae2356005fec9febf9d98da760e05f6646c2a7445ab93665776b8191f5f430bd9b72b60025f0b5574cf32701ec6d3feda06c998113a61fb89b5ddf46b70c460b36d22000a4462b88a9448c89cddfcc1cf24c058190383b42ab5516a4e59f28fdd67be0007f410b4606fb69d8c61fa443e8f9ef249ff0d7ee2f56c21c7e90f4f8e8bc92005a5f12c420d2fb6895cd11230de0870ac4ee6696399896017142ae928cdfb300b3a09a6a3bff606e7194d5c8a5080e6e5d2466f2ab6c6b22722da75c866546008daee5f499e67a3b167ba9d733476139bb9a81c9be2926154830827f842d9500111955effd8d2517249cce8075e808730e30ef23199c2d40af18556c1bb91700e856a3128936c477071d72506e2784ec12d22102262c1902f599300a334af5005a17d3d29bb391ce049e8fd226fb7609650e333073d2c933524bcd0f207466009791a03ec4a6f34c6cccee569afe311a49aaa310369c37b069edbf7fe8073a004a2ef2f563af46c161ea577c3f0869884e87cff31dcb2bc31a3c586e24f7cf0089dbea6bd773ebd0d4f65c2d4a7d00e8302a5c4f91f2823402c4aef3d09cb00090a4040ce4a3b1b7ff256b6e239afa2c75f3da776abcee2382aa1150e103f000f5d05a816cd78916fd95d13094fcd00e8125c685cbc47c132b069c403afd5a00c8515b35536e4af3db349d80a08092bf58b2567b0e583a422204097cdf1f5500b5d03c48b7e132393b4ff4e87546321358106c0908cd5a8602fdcc2721a0280030e97b4beb5e1d197daef3f244d58087a5b2a5a7966963d0fb2782e68fb0dd00a4979ea59736fddef4916f3af11845e974c9996a5f0d6086cb527392906a2500f538fc7caa569e5a7b9ed5189be44ff60df37fa920921e94972f6720347e8f00c6255e830e2e333395f1d13864277e0678aaacc150f138c87b50ab5d916a2500b74c9f78cff08c103922db41fc41ea35253b8dab8d1a927e70aae5803157f400d01439c041d015b99bb8e865723d68e10dd44f3beb499a05d4782e8f3d5dae003ef4d9235c99c88b8d8da39ce4e4475df3ee68198c03abdd890724a4151a8d00481688266f0ad7979efa32e084d572d5dfda6777a26875380524b3322a4b8c00157e63e2f91fe89d3be2ab6240f520e89b6554a2b1ec3ad1b3f912ac8db74c008f86d11ff810420a00163308b90e8d39a6407f037d12f83b0c004e0bee039500133b3bd0ea9e13f583de7d0fd03f69f4615a0ec4fa2b7b1165873f121519a900b40624959392f137129d80f4f62e82c4d215c8f28f6eeb15bd31cc89da162a00da61dc2f6647df966a17277e1420a1418dc74b68c545ecd5ec486ea939b3cf00e6c26b3fdec9b4e9408f6111982745cc1e56b53dafbfce1aa5d49c9424282b00cc00d9ae96c10119eeec5fa7c98314582e8c9eeacc996f32d256438b18731500a4ca99766842fd7e570aa9f7d18bbc17cce18b867c008bd96f18a8efa82aef00a229715242a06794c1eb0ed0c5011c3658aba7181a2682b3bfa024679fdc84007dcac2cf21b959d556ca18fcbcee0cc50478b066060ced7a0cfbc9e8b844ad002a1f872aae6537c24bdf1addbb36e4dd5b8b108c44542431288574634f8c7600938fa8071589e238d6e9951f85d8ec37fc2f26a79f589fe5bce5c2fd08cbe800490afbc6487560be51afb61f616e67a3e1efdecbd894a6137139a5691bdb4e002ff84e2435d704c342153d4b7fcb16500723659960c04506bf4f2f58e4f3ee002030bb5046feb9f5f9b6938851e76cf9f8f671533502ea2516c90dce5b2f3100bc54f5657340364189e544b9dfa41dc69c61eb0a0bd3b328e7cb0dea260a5800592af72515a074970d436721182a57dd393a5a78c188cf199d3f4d254861cf00ca891f0bde07b148387b0d18811a97c5e0396836adcdeaf868c24b23d7eb8c00e7f2e4ff070a68e9546c6e6026776bef9d86da242cbdb4c13afd27cc2763d30072b15e75b9911b1b679e428943b6532199d7dbcfb470737c03d20ba6557b340079771f385236127fdd5fcbb81ab19d08b231af20a357d27d55cceb70a7f7b7000102f40ab52f716b413ce48fd808e9c097261c049cd0aff0bf3d08306c2eb10006dfe902a26170fedfec318932ea561577dc74f0f8698fa15033381f03d08a00cddef09623ae7a6bcfdb1d6d909f0dae495346d8bacda849f53c4f6b999d6200c01529561dd8a7f04d218afb88746ad1b89d1fb1882817f1e56562eb683a2b003f1dad19e7ed43381eefdbb8ed16d95ca9953cb3c0690ac5a41722d5d4aaa0000a13a7a5c618fac1a009d80a434d6a6a438cf0ecaaafd48e47a1ea715231e100bbb522225b2953111f3c68528d49d51f328a89af74f73c7a9f4660f530370900ab5dd92acd772aa5cf4a9fed56d62b524fd358f7d4e77aabfbce7488e81d1f0093fe4e8e1d3dec489d444f9a00f62c0c79f0906b487943325a0daf2d36535600dda1f0820228416fb16f4f04fe3345facb0468915be585ced939dc535b881600c2e000c3b13327fe0413808efc244c77575f689addf72101fe4ef3e29d85b300fb5e0ea4cc44bc75332a78b5f45fee01729d1adaf6279bef5456a5dafafab3008dc0e06416f7e99e034f9934296a690d2ab2033f08645e89437e7bf0ac0ae400292391f8f9d80f600965f52ba51fadc4166ebb72690c5ad61dd6f284667ac200617aed04ad9e4ab4dc4fe0ae22fd2f26335de04ae3789d31b23580bd29d222003ef9180c2703057924bd88dbb854c6bc370a1879eac41b69d8785c186086ef00e941b77e090645bd687cd8d4781ba91e0fe8c1ce5335cd29a9bced569fd99d00b7b60b708fbe7fbd00aba3c4e51241632ae32d07a8f8e77d5d61014dc43793005784ce39edcb4e5985b11e8bef0b25fc0748fd5d5c10c88131188ce629bae200364d399614faea13d8d9935befa6489cd4504ab43b759cbebcb0ac5cda8e53007a458e8e0753ec36cc5ca4f4f4bf75852795a6864a891a7422679f85fba8180019b610a893cedf4a31ff7e54f335f0431616d3a9fccadaa8890e7d76a48359003fc98780a6deabf22b6a536757dee1ba9557af40e8cb945670de2c29dd2c34001e8287b9ed0d123888a78c42022fb4f8d865f803d36fcc4261f10613147c0100158ac785b4b34d7645f046078efc8b942963271670a2bb5981a0bbb0bd9fdf006128d8b99bea149c33bb31a4e163a179fd815e82a5abf4ad15e328d0145857003d48b78cca103c8d9fd51f432c6f97320443c96a4026d75e7e3b16f56eaee400af432b2ddceac7b9eed61abab8e5d385a877858ec094a995dc4da6d777a06d00e724d1521eb3c5f6bffddbb9d5e2c8482fe219de76696f5702b6b3e655a12300214c4139597d6cea722ef7290a3f51a3f06fde065c72996218fea60b19c296002be5e75b8add7fc5f6a9145c069bfbec341fda4a54c544d5f16cd1b5faab9d001a1784a0d02e309deedbe1f80c36df585054ee36231dc620896f8abe5c61ab00a230d73611e375ded7c6378cbd39d075c7f12412a86c9e548385653942427f00837cb7f76c7ca5172899d135008821c1dc3b6001de36d8ec374d844e7ee3c00029ca04f37e9f682b0294cf0af5b87665bcd3ee07784883da9e012a5d83240a005391d942e7339327f0b522a4bc56bc45074cd31625c82866541383ad546af3008458a963d88d99fee4779a23e62b12df1ce86adb76946e54b4263e494c30cc0076fcbef4d072d40c79d289486ac4cec3c7e605cc59c93c34981ca02685961a009a90e03bce71f0a722a3ce8f4cb77829fb78581ca7fcbb63cd906f8bfd2ebb00f1f9e8653be89d017c2fb779939c814d1ba1853d101b8624f167be8f92ef7b00f76d90bed934cbbd875324ed1211faeb34354ff5d9bfe613186fe8aec73e6b00a3eee246094e695db6716d9f054f1e569a0e87106107ff974a5814b169ec4e00e61ba66a9c8385516b4b8bdb3f8eef085796274537ca7ec44f08f6e7914086008a9e8b4aed18eff72b2efea0b71214c0e710f6c26239a860b056f4b95be6df00e9b2ad4361990232df498c85680c0982a97273079da7581f533f4a55bc2544006a88d156b1691717cdddecde7bf21ad6e158a6c33db5487d871f04c889b9c2000c7e736585ca960b173ab40dd4c89d8b64e9837ee1981b2e72e5e69168adf8005c3f82cc94cd02c7946c1007e40198272583ed4eb29bfbfb0aa3c74197093e007b82821644e2532cfe8ee4c0bdb9bd99b096336d281baa975d116a870df46800499d4bd8ee1264e545e0ca992b81e4143b8985bd3f26a97aee321b3abe118100ecf456d426a577b2de5de63ddb86795622fecd2be32e6865ae3503f712f39e00450422412b0ec71fd79a28310e7d29a78ec4e9adab32215abfb008c02c840800e7177d0082f5a265c2c12eaeaa04f667bf6de6b8eb03f7698b607b7cdf61400056be80163b4c698aeea1e4f5b41ad0af6a41bd52c523e4efcd816a6e54ecef0063fd516fd830bf2638c6e4ef153d61d9993675290422934111be09a25a450c0049b95c501c2d1e0560fe0ba88ec199e3a0230f18d94cef9f4d8399696c24e100e8a6d3cf77e72e5c0469f84c40ee3f3d016c6d68f4a6b39af889b037de843200a3d0df7dec01b0554ff5f03fb07aeda1ad535b974ad9853a5951995b5ca2af0025f85e01d04c65b0f06e6ebff447f1720aae61c2dbbb897392830da3f352a3001a1de63e545af46877f2abefbcf1c2f07cf25849222ef90431a8627270e28400e9e71f7f4c1c3286c9e49690c0028376600a92a3efd2c82e33d81437726af2006c9e505d083d4bcb6e2f64777aa25f1b807c53584ff76226806c5f283bba05007d1a9f340c1c68745362912423ee45709b3003329c7aa7ced83d4d0a74f7cd008b97d05635a4e070cae72dd6bb588e89ffe9dea79b89f1fa7c5136360fd1cd00f8e49f9c0401ad85cbbb22fd51758758c5b0ae0f0ca5b8bcf15e190acb529c00e4aa6936a0f27149cdc6e75677bb9bb817f0acea0a285267f9a992f84101030052392851d13f99b06271be31bb1136b719a902c68f970f14abadda7a2d3df0003ce4c81c9b82b1023790531fca42ceb8ef69469ea01c3c299de8840f66841a004090ce7d30b663a935b24f60745639e50b6e7299ed6e9b640304cb8aa3811a00a97b6f672761c914b37605588fa9992e81510de8c9ba6bb21497dca6d9334f004dbc6fe04c75e099d807a03919d00e7a6d0b0fec9cdbfcdf770c89e39b041b00ff77a0badad74375989814ff2f44297e7bc34252fffbe495c9eed8143acf4f00e4aa9994d77180d6ded115e60cf9c612473afdeb86b443526f356c9321bf4c00122e13bc0bee52358a445cc9fbe1f2b4e3f94efc4cd763177d772c7d938ed4005a9b68f04cfc820b307a40a85c2bcb73a983c8c9988bac3872be4b0a0ac92100f8e1c05e1cf78f7746bea3964e45d822e0126313accca8aa3b790f9d00062c00790b619637a71e56203dacf212202b873fe090dd3b5880a66959adc8d8e0a10089fd817f894258505aceb9476955c4128a6c77f5660578fd99fc25cbd4b9e70006e25366081cbd5f63d2d18a3b0c393aa2197b1b1d39f05895b558465bd297003dc7fe0d3ce5f500d99508e90a0f10adb6bb5b4a7e50f3975a620909e4d4a50042bc8d995f92d083797418d410f75701cd22bbd3b3f3691e576a8231f9955c000a07c930290cecf60ed052315d450cb924fa0fec3c709f7fba393477622c2f009717927e302b98eb7c9d88e62c548c6ce5eefdf4b66411a313b88078f7f4f8003a66c39aefbffa44251faecdfbe4b6b1007e2fe7df0b0edfa938ef614cb22e002d7e78f9472a064d30924afec698c250c21ef79c596df08087cab91312a70d0047456901ed30b9da21d8c382a1d8bb068874d69bcdc613fd6d2f60f88989b000d9cb594beb4697c23f988ce729de6b92d28172965bf622f0d9f82335197a63001429ffe46eabfe31e884504602d67a75fc60faefed5272cc31291daca99edb009997c839055bff227e49d5241f406c13ea0d7435b2cd51cae532e7a2ee58ba00b3faaddb7a73adb9ca087f5e74c80f47e30ccd0bfa2a0b10d694c125b98a7a00077f80f478835c91cd1fe23b7a792d3645d36068b7cebb07f646314c18995300597bbd5c2addb7dce4c9fafa33be0ac3d8c75cea9ece9466b08c6fc56b163c004ba9006fc644e2339a483de0bd99abed221165fe5fc0e1b4fe03eb81a7832200f71265944c0a1f49605530feec743346addee6b11e4e8c3d0d641487628358007841e4a8842c441c55ba2b5814dd73299812495f718325ae21ddcae67d36d200d5f980ed2c7054a3e7fdeba3038015959cb722d45fce762d2ef94b3709b866004c8559f1180a78b5599fbd8701dc7bd284a91f298fa1d39c197e951b1e049b0019791202a743e9557642c7314edc6bec15cfc04419f42e717e3a0a6152eb6000f2b38c7032df8249be3d5a0f92370d2a3821c5490b1073bed0b12f22652a3c000fb1eb5707ad21b9e3a8ed4d6b19bf62f4a63d3ac7bdc29960abe8d297053e00650272996187120c33ae78aaeea0ace36cfaf8ae946e5cd98c8f0eb8a5ef550015264a9cc4b6cd884438200dcbdc4709ee27ddd0b13c559ec60b19ec230358000e86f9dc2f4b7845e3af3c7c56e73f60e0ccbbabe13e035460a40d1d584bb20027fa5f8d11e7acd25108e752f500100e4f5d9eff8b3c92b23fd43b1d93ea4e00eb9e1330ed53fe7984d0d4afa4e74089c5e463b70d07ea2c598bc323a16ed3008a547fc2d4b5a68ad3c17c75fd907872470d0669ca474ed0d8c28719d0161200f1858f01cc07b9b68dfe6d5a0aa9f33cee2995416135f991f7edf068ccb8440019693747621d0d3a73ad3243d71f559918fa8ec6b5d4514d4f423bcc26ea1900330badeb0d405301c6ec7518c04598f356f4c07bce6f5a4735968feb2690cd0015a812d7697eee48305f9ac03d4e722115fd8233e5b678e2bb6097dc25a88e001f20460842e1ed19986a2cc7184516bbc7cb78fd40d2815f4e5f8e32ded422007060b9715d6eaddb89d9977a01a65cc33fd31bd2977d5b1dd886605b4a992400c7324ef45a584487763b15cec7d59fdab21c0d4abcd43da6fcda5c4b02354f000eda4c99c8919d2d6dbbfef161922ba166b6c88363a62fad5012058e7450b0008979b0d0db50be46a06195dac756435871b2898461aacd54558e7e2744ac4f007a5cd8aa12d29521cb20d3d4ac74591e423503e6d329fadd7a403164ce86de008f02be8184b2cf192c706d5ac54149566e10ebb7de6ca795471d4eab605abc0021031cd1e25594409031bbd66b0addf417e12d37ac7f9c95e84694208d10710090b1a9b971670a1889b967454059f60c23d63d9f0ff3f228270b6c990623c30096b4ceb5050ad1df28e5d4a53e1e21350c8693cd32e6b787305f0a0a8f8a79001e5cb049698e4493be990fb01051c1e0faf25ec9e6f7e9176c2aef53aca26700e44adf079e356aba81e8215b149b5ce950055f9818fbe3ee7c6c574f90a28b00055784e5699659613f1113c038c6fdc9acf0056491079e78d0a0e059934bd60073fb0c1637586bfca982ddc1dace25fb133afbd18052b1643703490b41f0aa0085b4d015c965e6cee712988ff124c7cef577e86b7558eaeec8898d1add43ad0042660989deceb99d36319b1ac3ea3f06ebeabda71b34793e4e8ba396e53d08001ccb0fe44a1d7b4b59f1cee542a2f35415a86eb79705d1c43345f7865d39dc00a432cb00f66a73dd6d9234e18c8f62179886c7f56901f1660a7a0187d24770002f7763238e63bd756cea8b75e6fcb01ecaf420bf2ca9553968342d63687a8600d6c55cca4dbc27602cc2d2a11eff79dfea7d9dc2bb48615bc0c683267a740c0081c9a7dcdd94475b71023dab842a596df7459edc90472d5823c7b4a6184a1f00a8c93b4f7f2f68ed24836eb99e92a4863c01b5b1e2313a6ffb09c8963ee4030018cbef03e6ae5c30290cfc256c163aa936cfc703511a7a4b7264860e2e87d100a5abf2156e3173c37e6d143ef50065e3641f7b632adedd104b6f330b709a8d009ca2bd0460b43d7270e1567bc427e95b6b2fd59dbd8468ec5b30b89f275b090024f62cb3ab885ebcbd92044cef6208bc03eee14b486e407bc1bb406682544700be9478785c695637d55527fea3a282569695b7e50bb35cbba54d14a93bc69c00129ce9dde0531ac6b2eb71042b7442333d13b17e54ba889daf9aed3246faa400d1013c6bb59a64a3cbee83a3623cf5ac6a99d7fa485c18e1164c580e5b5ad7001959ad2917f481cd8a956ffcca417b9eebb96eccdb80b2a10584416ffb460500a451892ef7cbf0ba2ad92a3cd6e304fbec4f4ebb618390b4a1b822937c3d4b00af48b20e35f30973154a44a3d2daf3bb49ba6f21020ce8bbc60c420dab3d6e00e541dcfe7229df5e349123e52663d18c9f78c6e289cec2804bd453a1f7b5ef003d1ec4a47c41d28c00e18ecb9194b15641c46481cdcd15e8f7affa7648ddea00a0dae4dec101529abee7ce884c9db3521581be47cb8c112de69aaf773aee0600884afeeae7a09923244a3c51705a88057c1a05017ddfb5278ac1dab2f4f2ed003b2f6215fbdf33845a746fcfdcea9ebd33f4ac923ed0d38d20779707fa6f29003d1bacb5ea8f3d00661da45b976750d932c5103829838749410ec75d82d71c009d1d5e4d23ce49f180dfcffce63c68089c55265dbabe6ab75490a481383f7b0030378d1d433107f5a8a60c9a2b6c0d24051ee75657ece734aac52b9d6c00ae009400e618007b1a31959b0bdc786e1c98b5224cb5fc09aa846ce7369b973d5e0000336ae492a8b0b82cf4bee1577d17c37c380685b8c54e6021e2053324f39600b78999a6203caba615e046dcb4d23ead594e700b328e6c0b24bb2e08f6ef6e00efea95f7eb307f15348e182c387626600e5888ffe0e1295080d2ef34f12071003b305bf565a06b9d56ac44b27a6ca665bd49df9f0ecbae8d95d9847d7f734100d8d265f0043f6ce81ac16b7b7c9ca7e2a2d0cc690901b1c9e80b62e9c6b70800e6260537b2b900df46b4a8e8f68c4deef5a71d4db073d6fb91dc8eafafa5db0099585e8f5ebda09ce03e0203aecfb00beaba381b749f6b415ae72710079707005560ac2a3a5a14b743082efee1310e9a77879048d5386f6e79960bb58f89b9009586dcd0f5d1994ffa066228a22940dea29e32c2ed62f7f06f7b56d43f91b9000849cdc216a6ccfa1b6147d696785199fefae1ad8f8d2baef57ef2a7a4d2f3008d8f7498d2cd4c65eb3de1a557b19cb0ff5956aef7e7c3da04951e12cbc925002aa014fa8d08d1c6e3c90d3d9c70a830982c4fbc15c8dabcf0d1930322ab1c0089f6925b5615f397f5a95fd5bc70fe9b044492a5653e7dbeddf0b0ea80cf7200ec08bf4188ec3e3d52ad0f567908ac6ab22d1135354d0f8cf2d7751d04ea0b0065b88dfe41d439e389e781c1bfa9d13e8711709f679bd30c995d1eed416e43004efaa91541506fd2dbb7661989cb1c4978be1f5b04f3beb740ecefac26a7950013eb58b6d6477909a10b49ae9cf3a9452037c839504208aeef98def096dafe001249f32126a845da2ac69e588192074444983d9e24a8c7bc6913e56dc3011f00989dfd470361ebb5253a8535cb782748bac1344754a94371e818ed1e21c33b0016e79b6041260480df38c89e9dd727455e59188eccacc41324639be46aa7c700258f3776192a8f0b6d215a4e59f9fc4ad91477c358fa4f46cfaf582298037100769b230ddce43b001b0df3b7d3b8b8db7655b7b06190a353034ef8d3aa1f740043fe61cb323e32f536e7ca5f7abc660ea76f1dafbac2b2592fff5fafecbe4c001860561a53668c6e2f75ef44853dd18f92b579ff503392876ee55e380a457f0076903e1181cd8c95ec7a0afb98dc707fb5491f4273d0b77211c48550cc4ba60091ae2050edca0946920b4f0a3c49db1ce49ff45956f2091a1a7d0721f5590400770d2ecc103cb4db9b12bed346292f9140df4bbd28090ca8eb95a3fcee508f005955e383f3fbe54106a7ced4f090e88ec577d2691180be9140de5d639e7e4c00f7b35e7f5964873a495279cb3f0f69d0c62ed6d21d204e7eb34dba17bcd87f00a2d3f0bf29b51c76aa4463ef383445bfebd5b7c9a8b83e43b4a6196d5e509300a45221fe6f25c4509c2f024fe5ec6cd5479abfbcc0430afcec9720cf5c30d000d85cf120d363dc9a1f5fa5e521f47d98ed6282b420985165da71103b71052400e86ddf3b4f0e078d8a6965a68088cb9da32421c9a6d6150ae06acd9229d8710014687c09a503b0b3d5c84ca18fc892330d19001128f6349436fe55f3a5e0c700fbe8fa08d86742a4543698486794c83f3df37855debd9ead42e967846067b600d36f2b80420d020b9ae1082d526e1f3baca73f0f133e701fd5b93e190bfab0005c1af11b9f4b4f3bccc3bfec29198190a10466e1accb593c19ec2fe652285c00129e93cecf70e0e377b0d34dff7ebda198439b4dd2c36589bcc2321da63b8900626af481208d0211289910bdac68e599bf29b055a56bde0ea38ca08657e0fc00c2fa178e9a2260aca8488f9442f13222324da47c1227c163bbe542f28245c200f35c6c834f37fd94ff53327ba240be91ced08a8b58349761597767e2ef6469009679bcdb870c30f242908cde2762bb7b0d1b43d453cc0ff9bb3eb3f607d64a00ef11b083d07d3a682228f7599e095e7a2c00057341ab5ed500bc3a1cabe8f100b5e1da9f5b1744fc8634d3d2fc1b95fa09d36b582dfb572a7b0deb160a1fc60045d4c7f9f1d03fe55a905f2be37d59dda7f38c9fdc241fdb9f33d79a9a99a100f2c3e6bf15aca0a383d69060f8b8b0c9c7cd3f5bc6a194b9cbcc69ed57b30700a0ff63a78b4ae7df48b13a70e77f4875fc3c00794c1f7b4e198eba8d6afa3400c83620cdc70eaff690440daaa0246ee734b91843757b95ab4b0f88f812cf3d007a7a1c0e55bed3e60adb6ac9bfb9be5feba3d55acff7a2ca091ff0bebdc895005b3b9b5cfb053c790ad840792163f475722eb3e5b2dbd303ff16c13a0263ec006dd3816f5c49efd67972d4a750cde1dfd5b0df4494e6b9f35f7b785176840c00c69ce76fdc2b42303f72c6831bc5526de677e4b5cfd39cdfce3135ac7d61230080e5ba888346f50036d85cb836a37737a4bc80704729c0a52294c6a800fd5500b604051f948748ec8b3a2de2de3d19960c644c0befec481fad696285e4c347000428dfefa62ba06e2bfb5b6f6e4ca1553e7ca890cbe5bf8b41e717eaeab54300d9b419d51e4f155bdaf607a8068d2d1e28b8c8d30d764e09d8c4c892f9d45e002a8e5ef37244629fdc83b1840b1b588c28746af50e4fa6ca09c7196e59210900b15298b8cc3ebb69da3f60ab5fac3094b007607fe42abe6f3726ae5129edfc00a11d5a1fad97c7e2996ded68cf8bcf9baea8c8f574da2660fdf37e85fc884600fc949d38870e3cc14bedb45cdf35bd96c38d997948c8de9bec9f5c6e8975bc00ba80c20243d85b24a038896a4d0779707787c6d93832e3d6a3bec0d46ec2ba00aa51c8c7e6eefdf800415726ada1ee1a037dd0b123a29b006ba17c9f262f6100e910dcdf708c0680a1def7ab045aea3854a8272b297d9f5f1133909f59731800d0fbeaf4b2c3f5f0e48b3fba1bf16166819f777ec3646298310adf9303fcc1009985e7782613f587239c825b069e0afcb259320ae760c964764a3cd37801cc00ef105f6b74f41556034aaf15320834c744e97164d19271b3df164930420cad0083e4181a1ee48d48bf4320f3e5919d94b51c98e93d8cdb4581ac8df37e84860037254f894099000b5ca13ad7f646f7e606f0ba1fded8d8ddc8edded0be251200a1c9a88f27b866263a3521b2f4fb7021784b8d3ef7834dc8c2c3e44bae1b1b008c410160d12c15b8c080b4949a37dc19d929852e23f1b3b0e3dcf5345d9f5900b88ea010903f9de1ea3d1710aa9c815548de68103d9ff9865ed9ff31c3620100a22ee319fc4ae557c283166411a3576d8a3b19252c0047affde6733f8c8fdb00eedd49fae037e26b4af596c1eb2ad2622530c4e6a7512852eea0f2027a1f4c0059c1f9ed3c103298ac5ee693c3f20959f7f0057206a5295009c3f9437692a000d0c4b0fa46716a635199c781af6c511a6adad4a42befdc3635930be16ef44100e51a31a8ba5a50dd7fa680ef9868f037c0460e7e5c291a617e76dacbedad530032e0cae7f2544708b88531f4c0ffa19f362e6b43623b1edc6a46a4963bfb37007366b3a0050073d630842faff3ff3d4fe91c34933b3408ff556f5ca298526d00a33b3bfdd1a4c1838a7c52872bc41aa262c8881084361a67cd2ab7a7d7b15600bf542a8ef414d83ed3ac2ed92ba14cf81fb4bd4e3764b178ea656c4f2352c400f1eab8430ef6e7f475b8639b6c7dbcae77929f14c07ab48b7498d66a6833ed0066303394321070da0cdeb245cab502c9fa292d260d6b23b9f2dec53687463700f507c32fe49008a2d4f9c6b5d136baf8a0f4682780ab01a1f21294c5c9c65700695ce8902a104740958e6b70ff906dabbfae9e2518a557308630e7a5398a1200c4866978eedf70d045dd2b7fe0b1663709036234af531e22ae1754d97873f1002f7529c9a22bdf66a60ed2b4fe3e8a6c8c82ac2d1763507785f96ad5f28802006b5476847cca07c903251aee130fb7f355a1ce37769ec5a3af13260f2c02f700bf776935bf06906d9cbc26ec83bff5cd29e19ada274f571b8106f0bf13835900f378e72ebc591f09fab8035823c2f928388ef4da62c1c0412c5a3b5aedca3600a471c6f6bfc5ecbaee41fbdd3299028914543d0c5b177ada2823d7842d69f800abd4117e0b295a42cbfa72fb8df37f01c03fb01ecc328470698d84061e7dd900389cbd79d002d3919acf2a7da92876906d68af8618669370edef80c328e4c800ca8b029e2b3dc74f22f1739614b190aab091cb7075ce0e1fedcb022bea5a9700f0e22787cd2e2467e58f70db5fce1159fbfb123b6ea8bd414e751182de5ebf0040567ed3fba174406ffaf3e1f5cf4fadc1cf51494bc7b777bb2da1069cbb6200fd882b477c6e71816232752c605bf5b25a2e88c3fc8c85034256ca86cbfc610058bd929f17465a470d9c5a923d91f36ab3116633187a579c05f39b122f9b21006cf2f86d1a909f76068c21bfbe615f6c032ed4bab02a1a4f3f0f692158490d00bbe50fbe12493b73521498d2355d4f6a8982e9c22a3ac1ca3d8261be33964600cab0c7f23ce84fdec31d58cb7fb0c5dd40a3bbf3fc078b0ec5d3a4f749438500e6d6c1c7234f05fb015c8876644c25cb85ad9d9f953019919e758d010a9c8000b1b8ff2cc936ad76c7cf147af8a12af70204ec130dbf79a9ae8742a706b9fb002965d79560a22e578f768783ef709b0f12a2b0248ce1f0346f1c274ac56b1a00bae1af8ca19d9095fe18296aaeb40f561e9f470356bad5fa228c42165aafa200a9e2d37dc70785df1ebfb380f77d85c49ca480f874637450002123dbbdfe87007edb80831eb283edb30095107e696b2f4526bcd2713241733ef395988a964c00bb7fb16f16018ec93d67bab6945b1e00dda5d3821bb4b0213915c4df8c703800eaeeb5e4feb025ab857068c771019237c846044a1f09dcd7021e445aa87210001ec50ff140893362b579af5c37b3b1de4bd5d9cc5ed89752303b9baa7b820d00df129b4ec109d5520af7d9ea88aa656c0a296fb0a9e763cb8d281b7602557600ab14d75a96df39491d13a37c5bf2e1c5d4e60c63fe9b931bff6915c11f7c7d002743c4c6bd8c32ea8a8172c6afb87237676bca1a24de98935fbcd05b535ebb0084d2de659999ee4ec98303876f314cba4322fd50df44fdd0ada6f0c87941d1004e32f861d05458a1e8e2b4345cfd3dc087d49a85fd4405381e140b11fc3973003565c33c4e538bb779764a2f4a1484709898cc9e87b5654faff1ddd0fabdcd00dae91544bc84896339e4c9d7ea9256268848b76fe2981331023690e98a773a0083800f8408d9c5bcf375ddce1c04473b8ef0b032af9ee1fc7114e67a3621080056d1892c60cd56af4ae81b1d64303c3ac96c6fdce866178eeaf11e1687d99d0040d732ae8794ad59c82b1efbeb6a59584201b8f0dbed3ea9467496edcaeec10079c37a241a60bd1d6645331810e45f70d0ea6de2a0d6701a292686cc62704400607539dca013c04a61524ada348a950f4de9678b37d76df9081b90a789614600612237da7a5a6d44421c1214525646ccbbc2f8bd5c19d370c43f3bfc722903006bf65343553473466f7fd30a13407dfde1464a8f902ccf1869b0a8656fc17500df1b77e6c648c84895d40eb46f9ccbbc947c71d8ec34d00d7141326bee736d0018a27dba8b179a278dff436eecb5b5b1b9a66de623b6a80bc7fc2a1a9e4502005e0540741e1054ea463737734d50f81ec9dd67ec7570e306f5c7b12ddcfa97008aa2d912a2111886df09f70bfb0e1fee5361fcb0c67ae3896b2057542ee66f00fe2c2393e9aa81a0431856f4921d14eb0c1a1115d8ccb385f792c878931be300f4299934af506d0aecdbd1e02d585155de700a6474abf0e97558cb48c57fa70080e055b4c0d3eb1374b4276f92f875a2836dbdda7253158e8e3321caf4321d00707dcfb9979a94facf5e0b5f232a15c300c46dc5b3f717e1c76227461ec5450095f1caa653b1aa9a1af146acec461df71e6095596bc51b448cfe21300953c5007def5ed42603c54452e0d0d0de1115e4b967b9c5d8f8136f575e8b457f12fb00dd35797eeb58923a0f7d0fb900073e6d4724b194d7cf075ac5d5b5a99a2b7c001731fbe9583c5de4593c1549d2468411b1d80b4419b6bb0af84bc1370f7e96004c0949a84c9ecc8711bc9ab74434ed345ec6325b55df28d3098f7786c2830a008b1a0a26198ca31338c0b0e69e4db0f4c2801764753d6e70ffbb470c1f4e6900e72ebe46b7e3f695bed712378281904a1061eef2ae2d7347d357be4fe2babd0087613eeef4d9482116e937481e839cdec3b048a6275efb328a1fde1975e32f002ca80fcc702f5aad28890da10102a48cc33e245709f6f761faa63027f65633000f818eaa77cdee83df9aa2f39d80b94ff17979bac31690e8e2beca87453760007b02cf93caf4aa5cb60934f977b4cfe39f83e978654623136b9a980828cb8000b071fd3319e64e05d6dfc24a9d1916f47034c23de46b4d596fb589d94c88b200cc8b544a06a165bb37712fa9f9f8ea8ab0bcb3092dcc8408e03d014e0da075009f9d83051b141f7a9c0102ba933ca9213704a1d1d0ad4f35b65505c6c74555008eeb4500c835f3f40aead0c867f5d6ce06f1759242bda4e3568e2840809060007bed3714ccbe2e611fa401c1fab69997baf669cd87dae79ea6c2e9f4c95b5c00a031832551fe8fc8219dfa32992ecb1f4635d07c79495f6b90259acc4ed50e0003c92a14214bfbbcfb10b457101ce24ca979716bbd384c0205c4b3316ad931000c2c9ab31498bd16f5d84b65ccb999c231371dd4808c679586f0956399fa46006d4a923118654749cf70e5ccb5597d5bbde77301db245575cb3555fc5c7c5600b94fb2d0df97bc938377293ea3eb2289bb2b2797b10d89918a596fcb5dd23e00da089b568210645f59b1e7e22051d30c91fd1afd23e15740e3e2c5cda5fcf300f139d0158e4885e500da453179d224d834a889193c3d043e876ba4a93b660600c6c5da271b64dbb55efbc355d14f873503696a5471216db2f5264b6168905000f1fd5f3fb3f879b17358bae64167880049ccca3aaf748e5656790f80ae931100780cccbe25e1232cdc015b1c0f60aa32520eb05871b1b48c8274ab72214fa3005e3b6f4c25a246bf190ef4b3c331da10dd56b5241aae2f9e3fd5cc8ec46b5b000e9473e7a3a6f3bf91e3e61f111c73929409299f193451c84e8a07c32e6d4c00537fc7c5844112a2aa67189eea2339f199edbbaf9b09f3c2e1febbf3559b0c00bcb2e4ea3c63b51085d8d9521b282cd281c7beeaee1406bbb87f3bd0ea048400a249d92253571197c3804c67bba7b0f7284de0c4211ab2380ab0cd891cfe6500c18471ef083b094a61de75d6c4cb59ec8a76c376f9f5cba246b7d484f5df51005e9312bf6824c552a517486c63520000d008cfd19800a392d3543b168d3ce500b2feaaa5fb9fdf2ec17bdac606d157a8fa37e7549cf7596c110fa48480f1dc006927050db434dc76ff11e7659b351ac56aa5d9c02afc246d0a1a80c97b165000d5436c9a5b625a7c139c650388f8e69c3be5dba5643b609bac15565c534c7b00922fa5e5f75bdf258a60a456698f5ce7e08eb35f2cfdfc5dd395559da975cc004d42b391b28557e68d8c3eccafe2aa3e5bc19ca6180ceba9ca49c6f25dff6400d1ceb80e7249420175b043638c5005747e5c7294a8d72afd37107c6bff22c8009122158ad3926096f21c70e91e2a0a722a1b03cb2107747bf676b61aca6bdb001d40c0fcf8321fab721fed989d5fca55190cc571a92e0bb73701e850ce9fe9002c626e8a9350b7bbc81ae74fb87a97090bf02c8aa506b8b400336d1f5b8e9900837f6c6d70edf0ed36037386a57b049f024821b060d26c3a677bb832cbcaf000445277a10b325a346f2773f4f861f9cc2c1af91a28f53e98e87b9ca56fde2800ee75365146a16bd79863c5e7fd0dfafc7141e4691524236dfe28b58238a73900a2c6e6473db6ff8a4eccf92eaa8a796290f9d7c1fb91f2c1e349f2560e4c430086957e3d0ea3e23dcb32f7b963fd30cdd39a003b1435f2016fea31945964c20070e1611da7b3eaf76b1ba96a482e9e0ce4dd0b46b0d59fbabca2db7825afe5008afc1cb06df88b1ed6abaf3c8b05872968b70dffcf55e355623afac47f1da7005eb1f147c0691f7d13f08613d94089af6eb8208ec4e756a3c19d95935e9608009e62351f3d2f23661086a05eceb8c8bcb1eb89596687256ae92e40c0ba59fc00e5730be4ab951b79359f2c59d38739c0868d9a737281a6f4be2e20abdfa35500b530204ece9cf403b259dec1e48dd4ac7a94adc6ef39351c1d026f2da861aa00b5dcc0a9a7393a06d6efc02e988a5f7f888add78c6b56a08b05f2169ad9bfa00b4cbad083e5961d6f9a5aeaacc12b686708a06533d1cc8cfc0047c30da15b8004fd53082c2069584f986090b2e4af33470bc83333c54587422d9208b44890a006029649af93355980f40fe58370ddc37ab129bbd53c7185d9eeac7a37f63e80006104cc743127b0d9a5fc27a63c1b26d9d089e7283e3e370e0e1da599f3ff00001187d46093ffa9f308d8419da169485217ed513af166c7d145e872b5cbf9c00f8d36b4a395841d9137d90ced67d1dd3f42e4d12008f87a134a26f174816f300056ce657dd9dd3cd2a17e87930fd2cf8e2c6b8b3cee16312a25b505f0c560600fe7ec2d0bb030038f56a41f12dcdf8499acf9ded2e4aabcb173b9ff8b3c35b003145c349592ea2d0925773d81ee35c3b65a3c576dadece670b8ed6f591dc1d000b26e7eb6c597a4a5c3182a8dfcb0e1bf2296181bb0dd8864a5757e72719b10049d44902f7ad298ac0604183539565babb085764ef682bdd5a323aadbda0bc00b02539f2b3533b350c3f875d4058c9dc198957285cbf0d82d4222ddd9b1d5b0050545e4ff21152eb52229490af203d46ea19f81dcd0893d09c45a119aea9dc00d5c7fd22c55b18927d5c7f2f408054ab01202c69fe7d3ab220fb2823c0702b00319b423c870f0e3e23a120d81b85c6a08aa95c446f003c01f6b0ee4f7c09af0076e841fb6e0e38ff8864a5abbc1209e6cfcaedb5a849430af0df88a281aecc003bfe65d34f864323bfab7ad3a2b15853c5bf51a26eb6e1195cc319219fc9eb009ed15122ebd937f97069190a08abd0322fad1f31d46c326f26e5d12c7b96f000be6210e05a2852ab71b1b3aeaef5e58f80c91fb675cb8eb04409d3687d9b9900caaeb5d15d7b88db9e42feaae0761f6bbec8795a219172e8666419b0ba0ac0009fdeff1d8d8d9c7b57c1607411394308964d5a020bdd8f3a7828bc0e3c2505004da6fe6617a33b69d5218de56b89430ee080d78eae5a39cb1c1e2d31a970b300051e39f767ccda50f6c9f7a543c9b1581ea7996752b9699fdbcd13b51877c6000a701cc3bc97fd71ef7d30f365c77671d296bc00e2ff06218e36d1dba4e8cf00c8c27bed5030163a740b3dd976420a89d0c735741d95e2d270bb4073880009003ff881d88cc09d494158de04b88fd706b92b404a9d6650a354d366ae67c88200679378cf8f41cba93e043b1f23bc553d94d44aed82764e3b638455b2e28844006e28c98fcb6496f17a47a52dc780e87f21da375fad5dbba1d8169383bb5b57002209d95118931425a6805cf60cd02454558a4b6c758ef576b5b1ecda581c1c00de9f584964e91be2a77d2a964d0372a019d3ab696b5896db2335561cf2bddf00e640ff4ef089f2bc583b2293ca1230d492a115436d8c46532cf834a372a70a008cb0cc22c0e643f2937bb1f6f021d9abbe29d1b57646ef3713aa63d5b79e9900b8c55642e03bb7d7e9e652d8c55956134b4ab446b2561a5fe075978396d1c8002897f87aec1877212c4edec9eebd3f3abb3b2a177163d8a375bd4beb0be9f3003b322a0769c25727ce820e2dc0a8ebd83ad7b5f81aae8718effb2a012d3eaa00c0cf75ad7dc8c349f9037be97d4620957a6076a3a569e42c08508db8f42a3600f32d9449a55fc4b32d0661d820e99e5100100182c6409f66cb9e2a29a87aff00b995287887168db92f95815a2ea45da3dd985cd7c9b058b6f7acf2d2f4ddf8007bdbc6d09352aea95d791c652771b93b4747ae67c852f9a310b8bcc9ff566300bd6cdb77a827053efa0b5e7ed6ac1d20a62a41debab9fd5ad1962e60f6caf1005c2a401d15df1098bee240a7949b07bbe6de8d273f62918bcb6fa2b90fb47400f4fa4a2e674212f42011d37c0bef4c78bfb8febfe1a6f95361b28e62e323c700947c0dce9b6a7086b1ec8489dc2011498a7ae3c31b0654d8461590d3b3fb4f00d04ca86e4dc173ae9543596c74bd67efa63836d3af586bfb2557fb5915c9c400e35fb9a44f3735b73aa0e8100495eafa92b5ed79ce9dc049c93e3896679637000c653df77365f1b361a9976854396a038831b588283b7721f9af0b244a772500bdaa5febf0bc05b38835100f9d99681b66a9914db39e763e1e4c8260047bdd00c00828264ace94802e35f91587929e57de9f0a0efd05aa9c9089e617eb809d00e00abc4e24dde90327add7c3af4f7e617bcad817fc18a47f95cc2b4ea1c9b3006bbe8b92a43f7c3d52482b7d84c8317675feee2e2091939c6ed600ef06e091009b0eaac72e7b60c44d19fba4cd3c801d5904cbd948235938075c704f25e0fe00fa2d324e7ed35e8eb9ca87b0866f82348beff68d6e46e88d2da5cebdf4e14900257b066e92a8507f76311c028e7bd7a4394c162c404e919e2f1f3b32ec5a910041904144253e42aab78a3d7e140f0e127a65ad4d7b40274e92eda228088809009e52bf95d81d85ea7d06b99e6eeb3fce704c7ab8df13d333a910c8b6516fbf003d9510f83b61f90b3b416220dee2fc5b0db23eba9e44f01c9e8b1f34f20f3000d0695649d32e25616fbd30aaa728258fcf195093f1c06abb342e2e2024abdf00cafa8a6898676081909d9c41da319325f6a718bdac5b0cbe9303c77428d161009c3ad0f09563fd81d3cd64e22b9fe21419ef777656448b739f70a578ce7be400951d7b94a368849dfa578df9e46ed3894db164b2fdcb9ee33d7f74ae2580e50048fd6922a1543aab7149854d36088b6040fa6fe0d6afe9185d776e50c4148600d436424bd207981eec2e6d779b3178f50004703e56c8dc1f36fa1cb4d2d067009f4db2305c604aaa415b4c49fb16c3f659aa6472b77318bd8183417bd4abba00fc869e37a596ae326349ea7618c508e164bd23fee88e550c20dbc1d4ff9de7005f0f963402ed21bf16e63d67c99403004e32a6e55285a40a5be96fa156352900f8c3b8de98d2cf31ba08e5c44d73d67fff93e295be397135bf10384429df1b00c7053990352bf5696314333b7f239612260ca9d271813d338dc612833e0ad4002eeea2c3f85bc232c2fded87fd5d36fdad826ebc7d212fde2229e25aac3f6900330fe0157bdf5921fd9ec6ae8aa6bdd253548835a403c08d04d62bb44943730040af8c43431aea14b5b12e5c74aacc71f0b6de2f79e45331769a14982e8a680054463a41a8d9d282e0e408299f545e539c8e3779eaae30d26f3d32f80aa53100c87186d49d05adbfb9207d73fb61bade40d9e3ffb69107c0e40f4edb99ae9e009a6fd340f1d3d8715e423d88eb21e44f9c1a4a78471036023d5f9e5115411700b3cfffeb9a82b51f94eafd5a438ed7f0cbb0a385b5a1449c90014154a0a34700b532651dec0fdc045479aca736815d98ad8677af2d82701e86b40dc83deffa0002075f841b57d8c3614c7257eea854d57d7b06988c4812c7b98a56f59ad93700f751b64edfab9b92d094ba165949bf7e2decab81601ca547e314972baccb050010a301948da0a97c550f755e2d87fed463e0378f3adb56147e8d315ba5ad7600a794af101e94d85a728c311319147d6d70c5fd7d1abd0ea3c50af7f20c632a00497f7f821631bf9412aa9b72187c5e065e30d537c7c3bf21e669acabb5edd4000b75376395b5342fc19cd11eec86460509fa6d341224ea3f16f1f28c2cd994009b254b92d9a20a1205ff329d428cccadaed2898ac63525fbf165fa9c4a003b006edf02ea386d4272cc87256f2e3a6060e3b703a06ac78e9fd48cc8b7b92dfe00a6052ad638ec0cd8eb34a06c465d0c23c9c88c822e506c9562a60d3bf3330100e62f94c8fe31869839dff80e1e4414851f1367442e515182dbd253ac241c5b0047d9f365bfe4a9086eda87c148692a2239a2fcac7097363286272d522ea33d0045b9d2d346a0853224648361f0142393d551a921626c8961aeaaa8d178ab9b008dee1f5473dd2f60a1f9f3f29f8282470f9a4474f258a464a10e5f4e60c7a400a21bd02a23a4c6fa7fd9c88260de5369a3744e94caedcc8bf421ae4c490cc600be5db7b68dfa197b4c213d3dd8d32a81a3e30348fcf74d18cab7abb97a523200604719e56d662ebb6506fe60aac4aa2df339588f113cf995e8ee291cfeb8a300dd081f4f6de6ebb8f8ae47d02f6cda3b566b3c68ae2735659a6e6d10c6e8a300bdbbfd127b5ec2c750661e144b00ff7a58740078a02eba00afdd80e0d97bbd001cf8c2b26322a4f8dc59d33f9e11f914f15643229fd5ffb2011c884e591075002043b3780f40b05ed720002b11202659d8055af917c2fc83d1543535d996d0003542e8e1d2b5f99d076bf7b00472dbec5f2a86cdc0db5474bf2ddc0687c87e00b2594f824e6424659e67ffc6141f8999088ce888589584b04f0023d8ada67d00864c3fdaedc0dfbef23c75cdf1823300271daa27299028bf0c33ac2d539c1200d89dd8ff3fcd6b7e35d71e311f8143b64a748b355ff7781e637b6b4f09a1d7006f7a877db97bf9a5eefea22dd60613c21929ca098709f26266878b8d74674100a99baab0438c641f74795f929dbfe2b544ca3b1461b99f013db849186e52540031137c3df7ead35bb1ad4ebc3c95d6059960f34c2b38ba1b24da2a932baffa00bd2f3b82e344e0b18a51e60252a834ddace7b36623d053fd9ba49814943082009d32ed5ad5564c8948127fdb875cee391d82cdc03600cbdb991db332b989f40002b5afbc4f2baca580657f91de5c86d5e2d804e90c643b46bbd5a39b7347eb00f801b22e568004462afe414e883640c7180beaf65a6920d4d62f5905d62ff3007a15e92f376f57e63b34d040dce912e24d0a06121edb76d5b3e7b10256d9eb00097592afde7dabe8b5fc26c6d8a2be117d056efdcb418a9adca3cc82e38c1c00e9a55ed026233eddfd153dd15510b7819e6fa2a6aa5b0b4ae999699b8c788800f450b56f2986e7b541c21835b50cf37d333ed36bb17b2b6c48ed7598b4662700c954c7c4159f295eb80d9fb68fdecca189ce1f34c799d8a308e348cbcccac5000ed9c68993804e77efcbcca336811d97c22f02a317b11d62cdc7fceb4b7e4500339e16a155a3ec380354c98b1763f33d23b8edbf7bccd0122dbd2a5b9825a1001ba8142199d585ce278eedd4a5aff19f1f5e544025bc7cfb02942be42d6dbc003657850baf650d4b0bb4e6f2536259d1c368108fdf03721cdaf5fecaad6c15004b3e6b3094638ac3f315f280a9fcfa010628942b77964ed5a1f9e35c94349b0016e20d616e2df929fcf1c589a34441625f9e92112ddef4b04c065ae233484f00d607b9e290cf23438b82e5ed7286cbbe231174e08e14f53bd542167b6602710065e3037164ed29b77c0338364105ee8b930e7fdcb24b4bef4571476b5baa22002693b189ed434a927a1de3780fe8813b3b0c2750cff4a84473e5db8c09c088007129b9ed0916c6122ccc2e84ca49e608a4f2ddf6f910dd9dcbe4ccf7d175dc0002b36eb610dabddc1d33a484993b0a01188b7430688d6c206682050e48daf600fccfdf323deced047382d6e834eac268bcdaf7c3311328fee74e0f1ef120ce00f57d32e1963c4894218105dfd3145d85dffdf6c06cebac4544dfa95321eec400969a3de65e3b893d5887e07e1a6a1ff7e9f55220f3888d383a1ee2a9030a2b00b7fc895c16ddff1eaf681f68c1cf75b79b31639aa41e3439b96a103132c44c00493bff00671eb1ed3f12f93c1044655b48461a93c8d1ab90edeb15d8a5139b00d1e38a99abe29cd66655aedc09ffcb353a134a49dad93a5dca44608cb56895000358bd71a5fed57e0fc928c14e102a09bf0aae1d3762bd119684c7a2648633007e4534476d536efc47152e2ae00ca6145b2ed9cd86e20d5a255405d40a2cbf005a980d798edc82cc974c8ab42264c1ecade654cce2742cd9293c6367eedcdc006346b7bada5ef6140fcc16a6b1b1b6f03d8b9d6cbe1636a9a231945a8e861600f3c9790b809fc5aa88e25d6b679ec145d70421855c5be3d5a219cc8642f933007d2312e8d20a0bfce1568036f3c9c515c874a917ad2894a3708898776313d2005338f6982926d829a47349cb0915358d3a21350a8d3ff9dc7c0b077ed043ab003204c4157b3e637e5382d8057432b28387c539340302787dcd7b9e6654d4d400ed2995042b6eaf350e3e05ba09248e12629024b7db1e4bd2d323030e4009ef00019b063bb860f9cffb0aed58741a8bc69da48d8d1ccb3cb8ae1acf9b7acd270098bd8cbb56fe2f89255c5265f93aa8f6516a63a067ea88c5b7a595fecb050100cecc2ebfb3212438c3d5b052c8ea33c78be9b8da25f8b1c9488d34f10c95da00dfd5edd9a6d0e7c55350ebfe27dcd4501e6c480d1518a4d0c4152a7d833c00003d765bea3b56822696ac2d2674f8d544dfe193ecf1c12f3b07e63a7dd4d62d00d9260a9578cc0b1a46fef1eb640da6ba0d46e80f7c701a64131621956b75510017c144ce4da02657ee0b4523d7697b662a698c0233ea5c59b62b788433523b002679e50de5f25c0b88c29964a839b21ee817ed8bd5d91d12e167cb5fd61e57001997a0a55af16be4581f165f68ca5017706886506109580903daa21bdcf76d001e220086d75d94d3c04ea174568b44d3377b830f0956aae59639fdbc634f9800302a59e8ca2e7e5cf38b1a2b949aa33c59e576b66431a32052e67575b7dd5400b30492389172493a503b53eae4761d0abc3df9eb770bbba0e6e2251adbf19c0056a282c1c1c37b77d0fd78df911c6bf9e0bb212ae35da379442da5b2894bcc00afafbcc7f12c5d49e21fa928d5737db4cbe51c850eb08b7ba1a05781d9a4ae00ba6a4d80ae3ecbc78484807e2a4c130c69687136423e07e8c18cd8f5f9d3bb008b2dd0ac0420b1aaa827a7e39020a15ef44d8468ba0eb39612436c3133206a0063c8ff9cd20dce9f9fe33a86885a57cca0ab4bd314bcc0c63201f2f4ded6d500cbd666b9bda279cb9baae1c39152a912b037203eebb4c664f8e9ae01fe3e0100a1db03456e03e30b29aa8c147e4bab0dec656d7d1891e9e0e784f9124068f5003d0a6a69f6277b59a4a316d8af69d4636b1b1f4d0ea4698012968ad9d67057009046215acf82ae2efeff8e2c992724cb14d652232ee2fc1357c141e5fba0a0009ad20fc5502794dfb7b20e0edd48f89adee0843906f822a2e4ce450035f27c00a3b4b0fcca5771857e06a6a361b00292f17d94321fd8350fddfec7b4f7e17a00cbc08e6f68ca659e51c9e04012ee6ffe2640048f03c27bb5b34176096f2321006a0e31db991dc4b3567f6f0eb9fd9715b67faa6565d72cea1b40306c672446004324ccff2a33139095eb5af92ea2ad4d6dfb3db67c4d8e36ae92baa7cc288300ed0f49ca44bda89207da89444963f618543138333cc95d8631fe1d446194fc00ee80e286bcef8750ffda7868ff972e2c291e2647e991bcf63d48cf50a5413f003f940e3a8af17bc2fe39b1ee31ba04cebc19fc503cb46f300f3c451832c3a60069774bc7b34e96999db51014fd4a6385eb9675b77cd7043d8f52fc9127f36f00c618017a4a3172a3abc5da7a805854e1215ec804e429a619ecf71699a82788000d3468f9cf8637f618bc4c12fe39ca6525aec3c3c7b5329766918bc15a778500f8fcf40cd96fc64571abbbf50b885d178fbb11eb0f9f0dbc672b055708f57a002fb78d2fabf548cdb78d518a2ac9e35eec1486b370c4810e42ebfa92bbbb3a002681e5585f5376914567e8a24256f1c74e3dc443f08bf89c4021591e5c4a1b00031b1eb1e3407a33f57faf7837870f065782853567bf7d22300d815057ec2000190aa2d07d54111d3770b47644de7ddbf1996a25229956933fa15f4703a01900eb40d715cb4eae5ca0457370109d7d459b602a9e4810982b526893e61fac58007bda215d698c8fb60daba7eeb469d1c1a298504cc8134091b57fd034dfa40300dc0b446e62dbf6341bdd5c00021063261bfc3a707c5ba75c7d0ed61183fda3001d92130ba47f1d21d6b8d65b13b9d64db6bb1ac1343c5abd1e6859a46c816800a5a0bb3ffb793f84a30bc4c63507341ab9bf97c40749d98f403e1c8978bb3500c9fa72e3dcb7e9a48a33a6645b23458c61b7abefcafa56512b88bbf23fe048008bae5ed00575afeec5bff8029a1db44183a7e06387d8a3cdd78354c2b8bdd600fced9bc654923930cab4eba78b0dfea1e5b6f24b5bc72efad1e05d93b9c0550087febe097e7abba8ddaec283347a2b03ed238680f06790195055ab31bcf9f100c2a5ebec6046464f0f7faf56ee7b0846737e64d65b06ff5e30c22172b225760046373c46de2ca155a789445a118992d215f095cdea808d5cff5f82d9a53b28006dd664c024e95dd1b80e3357df2478d6b0e833fcd4d29f73473d65009a9aee00d184a00861300cbc1d93f1a5de58f71676a94ce0eb98b9e19298a9f9ff2d06001ab24c16ddbaab58d300f720cd53474d651699c6606065d0e5275ac8c2f9ef00ebf5b41d61bb496debe2354003a9b80809df4a49c3319fa1adf9ad921b735500a0da0f2a6486454fd8e44608c878abc157fea96f776c1d677e4f6ffb92035e00033b1ee0b82a487b35ef317e8bac2489efcade090b4e0e0ba0f0a3319234f3001787690a6905450bb20c8bbd1203ca50795f19aac5d10eca7192264dcc105d000d9334285dcb928362c6ac213a8a5b0388597e418fd4f04342a5d62d33b2e3005b324df822f864ba2e078e4b7b797e40ba7db93d7837947115b7c5f665d08a007f00ff81a1d162a7ca4984ff0ae1e3b826777d636d7094e6358107bc40dc8400e6cd49342c6a9a863f312ac7bebc5870ef68cd1dff33c489941c0d80742bf900ea12b048d0341be8345166e34934a29d0a38e33a56d6d78cf68c45bb03979700485f9d3a551ea2e44c65e29f6bcf78c5e76e9cbee58bdc9693fbf0543c9ad00074945af2b56a8bda47a1f26e3abb324eff09aa96c3f3db52c5b3b1722ac1c900bf35fe724bf13af0190529beddc3a2d2efa847e65d77572011f9fa0674f54e000ee775a6e4a5f8c1a9f200d33e989df27dbce3c8c00c2cc8d460492e9f3b82008ea813528e1d05162f3e28fc09d3abec253ed310e20fd31b410f5382a3eb9e005b037c2ce69e0d445ee7d6ca438ef7158315f4f10229ad9496525788228262007ec2a9a9f45a86bec49f93d325afc882da5de1ac8c570179c1651a44971039006a74aa36df22fcfa2dad0b22fecb379f9c47dcf4037aa224caecd039bd93af0018bac5c2792ebafc5efe22247edcdabcec571aea5eddd93634ef936e82b3ae00faa4a837af804a47216cece6a723d6df4a67d728f7e7dcc9514a649756ae3b00a363ba2aacc1765cee7d92256f81a3c9f7b1f39f6d690264d11b4f78225c250095dd5590933ba476fc3e4395fe97eb05ce47c73752d421f615eb651c2e383200d287450fd7d2458f37916238918e63b581a4c395c17bfa2286c35b3236acb000f6cbd3b235c69b2b03621e030d4e286b964dbb3cd11357e1a681c08757ed78005c979298c5e55d8d101881a80ba9868aca04ec17692b0e6feea26ea97037b7001b7367e57eb42cd11bdcfc2cd6274a3ab83889ab387a4d33982e5e02b5dbc3009e1db3ac63937fbfc095175192981a1f91e91d5f10c2f5d61a3ba6aa7e1d0200f91dbcb9f1b3440c8c9a628974aa8df68729366189bfb8952454584f0ec1b000a0828389610833b792e4f46c2b7b0adc7c29b448f41db7943352858cd59cba0047e8897c7617a00c21debf69f758c59e191a0eaf36c12828e7e80a7fc3da23003f4c67592bdb5d34639e82d991eb90bae8a64fad62c9a7da790f2ff2e0e3670055a5c2c3d45ee7f6d83e020b9d4561bd107817151941ab216165821648dca4000dca81cfd04a9df5af9174a93e736f89b693e5baf8e1839da0ce8adb6a0b1f007b5975a6b2c37c1a1f98b292b23a2a9f0980b5d740c4a37c6b8572ee9f392e0013bee0cf3de050f8ecf15b8da08e2197aab0d261c9c6460229b4f4af0285ac00b1780ead46e384b751f74d6d474eb04b1bdf5a9fb49fe5e1ce73c2c6cd9caa008c09838193f0f5ca575aeb9efe1a3c4c431f748416f88e4a1f3fdfebc4be9000f73f0f87182408f4e11775bbfbff84da1921f45b832f017017b49d448069bb0036c1783032f5495c869a38944ef497bb71eb2f9be1ee916c39999510c3b0ae0063dd4ac8f662c5fc8b37c6b599679fbe963644886701c153d5d9c6e73ce11a000e2af2aec94d8c8c89c3ee4fdc29c201a7b87c4c16beb08392a28c6dc49a5a00cb7285b1a53ae4e46756f55e4a716fa24aa9ef0f99d753cd60237bb2bdada800612814675bd4934730e6296e7c820f6bbdcaf7dde18582c4a989162445043100fda0cddf46a3f07ed87f9bafd1d51d8d961f6d4ad2bf13b2c0548ea98ecfdf00c577e102e4e98f6eb03c4cb3902e8d5b8446eab8734cdb0d5ecd91998f127e003474ea1ed159844514a7e3fbf29412d15445f8cad9426e1f88c26d3775724700e01752b3e65d8b23e6acaf5fc0b03cfa2a1953205418251403b271234df9f0001c12226fb942333f60d082e736790b0d903bdc212f9d1b91ad3f3be168f7aa00df75c6c205e5a98d3ee902b4aa8ec19f49ffa8d1b0a799e75b779d0b62991f00e2b31a78df220909ffe466681bd5df1bc821406b6cb64972a8fcfd7668146b006234f8d481820c75dab49eaedd9ab354e0b4dcb4a6885196967ae32f645343006bcf6e60ec8d47bc0f9b790c2b6023dc803091924b383665f786354f380d3c00d9e0034282eb344988148bfb901822c9bf1199fa62eaa150ebcbe380ab96c3003c5459d8bfee1cbd72c66cad5ca999d528541d28e76480f8a857a68a9fb378000ccd07dacb83e4724834658ee815ca15dd7eb9d76ed728757808f4f3de7df600cedcb8773cb0dbe7d108aed1e311143823e4f79b53db8a946ff62bf76ed1590095618c08f603335fff16c378ddb442764a66a2ddbc86de6b4348e6961ea0ae00334fad26ccdc4b8301d72f4ce38115569c9accbda7c8243376bc4c87c283f100046846744eedd3ea44ef67ad682afb5530d633dce3f6dcdda6528d920fe3c200d597c97d18745074813a49076cf50e5dec359f815bbe8a892e10f72e519c0100a7bfadaeed5deb8ec20884f9c084a26f656760684380df996c767031647c09007ff502ae41608d620a72766b631051a848f683a5dd828bbe9e43e0b609fc1a00496f370f18540f09531e6e227be9806ee6028d4c637244740d0a942948e95400e93361c4201cf05743bf7e7af1cfb38418b8abf0a6cc8bea7187407f10aaee004a1fa9b139d75c10953bac9ce1c7b786cc044a7e0d44f3b59eeb17f3a0952d000debbac74c9bde266a822d49171461f623dfb6f250a808eb187ae29faedf8d008055f6cb6dcc717328788fe03694cf1894b1431bc09a72b194e092b08d101f003c3b68ce8da9bfb09d1722ad0f5a166c81f6ab060d85308d38a5332d2ab0a00098d7d471aca1e516a99d702b62f085e5c2b4e3295749e4492988ee215669e300dd112c1ca879b0b6aba1dcb62a381cde912c74dea6fc8fa75ffcae548b422c0009289b3eea3817714ffa60fa2bc37afa97865766014f3580e7cd0ba108532d0081a2759687532aaca0e64897c94ed6ba6744a7ef0e1fd7d0529b9d4a4ef330009098b65e1332479d349ac04524a5571c308bdecf021a97fd8e05a83c939f18007fad09501c69808d2df007b2ad5bfacd8efdabbf1381e8d5f9c6c97270ef4a00dcaf0f227ec35fec3cbae7b208f3e441a5a8a586fad7d794750d74653c98be005c01221288e17b56c1888812a9d677681a507c5630a416559f7fd64846537d0017189bd4e773ed9dc54252bd0f0afc61ba364ed7b6552de2b8694324e76d2300308af5ec9fc0b76fb8379273594cbbbb3c96f881f4985779193471f1d7b649002d4e3e703cf1f2836a425ed9fb9daf69af23936b7a56f74e659b9ec8fadaad003f4ef861c1b7c2bbd0fa58bc874a070798ae917bd3cff557818df3421f81b200d4e554a01ad415ad0d04b3bf5c5cbf6d65e97a34377a4e6e89f87033e120df000031dab9213049c57299decc0711c87f848ccb93235d289b8834231431f1c300c94fd91d3b7e568cd5d0663d00ed515ab88902799827c0ee888c262be44ed100ce75e621d54c0ce97a8aadcd758e1c7e53d8824cbd7da453da388700308a9900404afbbf739a04d2772ab55b5554e4308cfd8ef1ad92fb57853ba27fb91a5a00c7b447ab7ed49b86c9435c0eabcc1d84801c933ea8005bbfa5ddf53b5fa473001c036ed09b032215464434a193417b3d4d8e49c8ca5483e74cb02f338bd283000edaf92fcdaa4006b5c1e28e59082c81245d4710797b854729de3a6d81fe9f00241c93c514c917e676084ce2d6fb65d4e8eac5eb9d2b31f6d6c9182e7cd5a900754776996990a3217f15bf1e5cf314809af9e50cd68dc30fba05b782b5972600d126ebc3e4e0dc3c48f822bfc4c192c5513f41ce48a631f2a39c2f1caed6d1008b0448c47725603f3342a895ced9f83f9557f57ffd67aa6a9bced8e27a0bae0079dfaa09fe9c567506db83a196a1a157ed9fd5480b46e7726cc03117c92ce500ad807b4c3e9c9c158fd6e3cd008d45ddab39c5dd3b795e2fd5830fbba83a450001b2026cfa464600bd8f0603c4fe78596e6fe2a3bade80babde5f080b1cf58001c053b8ec7227be5387d5898d31a35f0feda2ce94eb5e6c45977a4fa474f44004b0e29ba09bffa181a6af5b51fd92f8e8e42656ab6014e31733f120bc8d0a200c0344d9ffdc219785414f1bca2c0adc6625f2d87b73f87f1d530c9121ed5c100e374421b4a9515f2e0528d019668e4bdb5862b5f0f0c1e58756a44262a5c6600594af9411c254226517d0eeaed4cddcbe1d8a56636fce4f4b7e00863262f7a005e83480140c50efb656084575d8f1585f0afc7f8ae9e476d4385cdb18f4a5000ce7fcc8491a3e3de62bf56add625c6f2ec3a56e12e4c54b3397d9e98c4be57004f548eda509ddd4e37563140ff6a07f7018dd5ba532f742587204181fe0b360027063df5de4ce3d9983316a3e64e7d9b2b0defec38a5aef7e3dc6015f4113d00bb8657dc0baa46918cbe47579fefe9cfc5633bea8ab3a6836eaad8710890f700ac9c20aba093aa7157602dcd97c2ad62d77cef8273020ea79261983d2566ca00cbedd4ba0ea2add3927fc9d3bffece60a010a80622c8997d62c5aad8c9f77e00fab877dfb666f0c9e1308da57b748d05dad15bd87769de1bbe8aac2445768300077973706da25bf792998f311064f1b17d606e218888077430233a05e3de1400fa118e750951234439955a9af740a14cefedb29a93ff503f1a7c32b2be4cd60087064ae1c4c5a7f2dd73f5300de0e3de8a5ec3b3da0d6dbb8416ca74c99fc100648a39e049de55df886b3402f400398d59a96897efaeea8148e71a36bce43c0025b063a4a3a9e240b4a2453c7a015fbadcf3149a840acb7041e9d9da45d83e0035ca3d122807eb5e1dd6ccd248b3650b1b254a87a2706a6044db1966ddaaad00d52f52e5d44c2d79777daedea6fed814b3161f9f62c1ef390dc75ed1543ff500793e86edde9660addee3c80c767f19d8179ceccdaea9ea4bec47a6fe48e9f50030554395eebd08d3054bc443df5efc7af8da9a30ffe6437748cdf118208a0b00f284f42f386602f1bdf280fffbe44ea7293c233419cd30220b45f9791256940092470c953a428313b7449d39a1f50b33ce208b6363466d2f4c6516c48548320017d3e6b809c5a1e7fa4cdd294d483fd2eff8199c374506c58781dab3bd1a1d009e50aa0cc6a5f9e78e98b239e461c1c82ba5f9a44525141128e1444097ce450062558bdb3a66395210f3ea495e9048d051181c47ea932feeb05ac412a651aa0015571985d6764f38819601bae1427fb1e9cb76600611416efafe4a7ba8a4390014f3cab64493b808b1403e32987dedd885fe5247f8c01fceabd9a2e02c480e00b96ff58eaad85444051e7b00918f336c89d2ac8814bb11fedaea9a4994c19500711fb82d364d07b02d601b2aa4fc3c7286ffb82914e6937709e8bbf96f67e300975d09e5eb83c3991ff72ebc1ced3bc6c6f38dd13619fa6123eb9164ce9a0c0050a97edeb0c182e68ced4d061c55c2be12d88f2887c23c587fd38ae37ae72200409d0843ac9b6f7ea6beace05e5527d7a8a65775a8f5636d47ae251116c03d005f899ab24dba60d2eaf8251ee9bb08431a8c455bdd85dde0bdf976b8c08d3d00d09df66b1c1cfa3463ce0a77ed07993928db13db3234e7582ba30f08f294d900e3b117cdb9ed4c2bc05da039d2f8514d63d39664eb59502e4336ae2416296700759acff7834e58d3a203a923a40f68e0b26e862f00eb5fcaea7298480906cc005d6de1b43e6cfe72bd0b352bd8112d517da811c557d7cde743113148969ebc00b9dfbb84e83a187d626f533da2190ed5f4e198ee4a276a0a887684b5238ec200990f9950b7879c7e058000fba9b0071eb7112becc280cabd720850573e1967005a5d85c04e73c53f537ab3e9086de08dbc8a66bf222f1a92c4ab91e72d7c2100d1c2f33b1ed0edc06e1465fd824bb2d61ade9cb1717dbe498180fb2f029027009a3833e57f9851c13defbf250bdcb71f8055b43d509ed158f8b7910f2dd171005bd3b5077852d18fe1f62d60fb8602f194f8548028a44652df752f5306f46300b881de4ff7caaa0b80bf538e6c721e83c7a9821a17a17821011fb74c3226c800b48ef15c93ad9443e9d8cdb5e6161970e4df43d4ff563ea1aa54e83045d4be00fbf6ff2dab91df5c353b4a1fc548425f016594f5fd006549be309e57d274e800ace403156dd8d697310c59bdffd429d8f3e0f0be519cafcc1a4d5a3ef892f400444f848db20a11bec6522ecb3adfd8023e3b2138578ae7a112ee6b6a89916c000ab3de742c3bf833d2f409aaf5b64fa7b0b70225e71ca82f4f711e2fead35800fb4650ea425f6220936061fb859cb7dfed505b5e5b63cf701bc913927429240015c73b57de1cbd66860f8b13098606181a3056cbd16f95be532c4b206c18f1002cbd35a0e6ad4cded7949e985fce31f9ff9c7ca44f56768bf64a7e9af99f5000dca149af5c88dfefde61f022e5ce09c3293171ad197bcc75ca7ebd34bddeb200480a62917fd0535f91ebff37aca37aa65cf679b77d98bdf5a78556ab5dfbbf00c609d8f749efc16857aa478010ca374a3abd621c93ab729f5c978c2a9a24b10025e30d9f632c9f4c98ac80728429c868904e57bea634e17b3d18b12af47be7003ba8053e36f06c10e2ffa43942a68d81d6261a28079536f56fed9c988227f000b98abc13db6a0aa20baabf57c20913c6b53c259f349cc8b598e42ee826aec600111187e22cbb9efd477035ef214e4c2c809e834c109cd9ddac87ab17b199f300c6ee38a3c52935e5427ee0f59afcdd118791f76ee9af927da4c3336b8eafc80062085499904dfa46101e25e170a5e3b93f1d4850a66266c5972495ebabe1160056643d9c6cf4685d60389f47f135339bb9a42c149d78d85c87115a59bb5d0b00c12989489016bf2babaefc41ae9dd693ac971c2a8e264ce2adadca22c43f68001a167f980016c9395a7dbbc7d557f594d945a87c63097d7001b0fa27cca4bb006a1e5d0befa703750956e9c385e3cbdb00cc74793d001fa97b8d7602213528006f101bc63ba9d6115d511a929c494d1a31a595a1452c8334e6a4023f44d64c0010fe1462ec4ab32faeec944e1821d8e79f360988c085a19bbcd04946da6c0d0077c5f0312b6a72afc5f26d842b732bea2b62abb025f7b822cd207eb8ad6cfc0089e6408a93e62908f3b62ff9f23b9ff5c5bc041a0103abf9813f5ad8037e15008a5981ca50f265c0e40f84e86e2bf3077905a560c8efc1fbe168960c56eac900160ac9b1c30bb22c739df67fe8cb1569c5870aad553b2a72aeeab294019868004f2eed284399cbaf6f4f18367539c4552807b10c1e731dc9e2510dc72df66f009654604645650b786153724bd8433d4d9f806cdf397b16750451db060a210e00b11ef620ee3b9deb9ddd495566069c78505cc5aecfc6ff34eb82166166af4e004166bcd72d3da1ce3474860882b23bab4058dc02edf8d44e099de74b997d15000fa86a900e138c587dd3ce50ea31b829fcb99c7a4168461437981e9c213787007ac4bab66ed0b6c0408f7e45cb20f9717f3e21e0a9621d98632cda72792f8100ad42f56f6037a6a6e62071f6d8bfe7a6c301ab05acf6324151c3b13454a7f1000fd9039c4b46a45adfbdbd86bd91428950053b3d02645c2d1187d345df255100a46291502410306a891ef92361a1e65996b830271e72b53b6ae0ecd5a4211f005750d632b1844c4dd0e645cd959ff62ffebbc7d022e94d17998d33bc3025b200ba69984acd332d75e69db9d98ac851adafb374a48f07a44dcc7fa7d568e1d7000599b24ee7ea156f9e34b1ab97a637449fca1381abc8a8cae4d58e7e3f381800076d3ea5cfc0cedda73c2f6ca94fc76ca1d2692ae6fbb97ff9787d0037bf5300c0eac06c4a57cc36612158527801c0861e11fad425ec2190aefdc2924f6abb00999b32ba4970105f0bf5bf3a2199e4292714b2ee7fd809cd36e962d062326800d1ecf108211b2bd2393e2dc94006370795c99ca008987abd6c7d5d2e56652400966e043c61f8615a3d3b0444099d4c8774b1adfaf9fc5a26773ecab328306900a939bfa9b48597de7e3c3b567e291a62d3074af2b8d1c1e51289be127af3f500c3a0ed66f1d12c63cd8b3fdac107cd42a565529fd4e88ad3fe765e99f9991100188b4184965cc8be18cedffb13a783f7baa51b2b246958925c193e08fc6a2b00c7cfab453b00b705f5555dff6bd2b9e03b8ab13d7cd1b4304f9efe4eb9a45a0049f18ef9ca9d28b7e5428c377f45df00dd32cd9c3df20fbca04210f620e1500039791bd8546f0b13d015893c100376837af2bd8a115bec470f5a774fedff1b002624078027c2c3e70d22b4b03e0258f4ac7ad3fcaf439c5b1986a7aa27b1170064bb7e3e050e45f869bcffab39c4f37296fc32fe37e0a9927d1efb444d89d400151dbbfccddf168024edef841c2c034abbf0a487d504159ba4524b4a7fc4fa00da5e2502ceed1a63d072e0d050eb70b5d9faa27019b795b4cd3630cd14ae8000a02ae07f7bd96f2f5770af5096a052d6a533a87cafddf648b1c7d1380e868600c62f7d3dfd8065f457b13d956b58dc43b5341e05a888f1abbf71e3a7e5066e0084b2dfd0ce39dc6b951c6a32026684bb22745f6342ed979af2b45a94959178006a1727414047e35fe0f65d6117b8e46e2426e1d2ac3f246b8f58b4f9237153003af13677e82cac1edf2eca2fe876501434b0c1100458bf680ea347571d7823003dafd80e61671860d3166e4c3614b7e6c580b008031744a74f9237cf2de21600000d9a08b9f93a4d312d9a4d075db66eb353479116b992778ba7d9183186f70059a877fdb4c45a638b21e87b7194772d73b345a54a35f5767f0662b5ad7fe7005a1bd58151514a0c143d7a9a17437b64c194c60c9b338a47c408b995934a7300e80fde1fa6ff6cd8e5ae59a8a44f3f0a6455afef3a3bae069786a0546a561d000bcd749ca3114179a5315de073c6a07c74e3e8d73e1ab4bbfc63c1ad384edf00988e7aad731dc0bac9d864b42f3738f3e89ef5db29923e7ab8d4b245a473630063efd86f166cf3636ee5fbd82400841dbd781146e9807efc886f82e969f3e400545369ac84740ccfa21c76a02b0d394c747394ca35333f5286d97826ef06b2000d4be0427ecc643e40b8d9bc31ce1ab0b272ac20818e2597823f3cbd8039370079ced956a4d8591e166643b2ba718ae1255bb37f6e3a7c146b4a8d72ebebb500ba5aaeab39d7f5432d2b3fcccaf7864ef3efc08e61d391b16cb8cae87bf37600301b02ff0bcc56b8eb66ac60a4f314a7157178804d8ab0b5f7deefe79d543700a677d455b73967770db2f05b39a7b8822e3630867e28c8a1bcde7b589baf12002639dfb6e0a99ddc3b70a29813241b7447f54347f67450541ec2881ac3dba100f36fcad9fa0a77c71a072987969bd23574a6c9f8b78514e9760109832085590003f4d1e5164d4b0e14bfe7345a0df2a9c0bafd560b1fc40840eedecaccc072004e1c4693cc298c6cd6245f6b7951948802f7da77c9688154bc28ebc146c14b00af007c007068f9abcf9bc84ecd93fb4c58e35142c22af5bbdbe45179c6949c001b83a9b08054f5c63883813b9488983f7c33d961652b8cdb38747b4b9a4233005d489f08b792fe49e8ffd86558d6f3d295b846758ad281affc160a71f99c5b0084d616a28217aed0683a6a1155eb0f824cdd82d863ebc002e710589048baaf0047993217e8a73b59192ef1d45db361ddfd54e3ce0f92207a4708078796895f00cca94190249e0eea9c8d331e2d224cadd7d87d9e19cd698e029efd9443463800daf24c73049a9dec2f9ab0d0f95059124485de2b0f73b23d90ce08f1f5b78800b5ea36b6b7fa2f5020b504ad774b222ceeee61405fd6a520ab8312b9c619e00029be3ba900a36b728685249fbc0bf8a25b2be8ae0450ec773f1824fd23de7b0093fcf180ce04e346db0498e21621caa0d79dc5bc7b9eff24e5b63a04b6d8c400e015d0f3170dac973b255feb7324d28348788b8044d61abb1d039c22c20bd3009b278e24ec45dacdfcdaa5c135914f4c78e7811ece2774db3d39a16308765700ee50d9056c831d5c11e29101c32d42dec4ca7c0d752635d856f8412d3dc6ca00b8c4a9f3b46131c4a2969539bf0dd2de4e259b356bdb6250388369bc3880c40053a0fe67570da5e7e12fe2562695d284977b9d3a318f753882473f1d9719ec0001c66e42a1e0500a9edd72b44bd277113251999dc88d2565a4e8f86472c3af006bb39b024a2da5ed7e423b726a8c59da76a9b603b275e43e264caaa2edf15200318604eb338ad6d8ddf03f06f4ce4f305df038aa8c07d4e0acf1ed3410121600e7b1bb4e6dadabc7e88fe5d054e9085afc0bc7107f3ae918668615f62a8162006c7c8cd2daab014658b1f6b5cad85fed4931333d871cd731580317d21dfc8500e77c2adfcc10e64dd46b968d831247447a7da4d0f60ba0a86d34d9a9a3faae00bc37aa22b433a8b7a5ac8e7c846894ee7d1e29a9c7d6459e12663f10c2724000779ef0f52002bd242306b965d9e00005302b438a41c74d9ea8a42bc3134b32000fce486933945fd4b3191d1c373ae59e7e168b21bb65448a5000125ef70f870025dbaa61fc9dc109d439bd4fd25cd394df4a0796bf76b80cb053010b6d8d2c00871b3f90c05b06008eff772e45bc1435ef14742fb90f5e31acf2d1b27195a500c62c2e19d07acb67b14bfa5d408a0e8690312126c038ed29da7e85f843e07b00397db890bac5e06abf9cd5693fabea73e0e8567d9e295d968786df2e3612bf000cb35b2a5e59bbdd61079dede4799c2c421360a52a6d6292160defcf7591b60099f4be9667524e941f75295e097aed5a7956dc41327568ab8fea12bb8d206700affbbee054e97d2ba52227773c72c11551d727c33cdf7d31d1e9d3b0515ded00676b5133d69f8657cca5e509e4ae0893aea2743ff7c69a387d6b93a341832a0068d2c7215c650e00cbfbf24f63f088708df70b0811b17c1626fee6027a1fe400a081e384e1d6f5cfe29044baa540760e7c36984f330dfe7c9a16e259be025100b0c2e13b8fd38cfcdf0af49edc4d66a641786bd9ec7aa3aac4e029ec59d3740050a65c97af06d3b16fbc3754556d2f40bc85ca792826f09c179349b91a97d9009c29e8d152167dee11bbe062b9bec963ca01eecab3918741c0b69637e406a800cf94fa72c37fb9bc621e2ed96c0aa89574247a96519852dafd385af5815cdf00ee5ada15706ef46cb757520b0a5a02c905d0ad62d488ada6d2dce9fe8f0b7f00d32acc93f216d38bcec91391da170e357102609e96f78b3d5b5a8619d36c78002fa7f82fbd1904677df9b579e9488cc703f826c1a3ca86b4954f9bc4c3ade7002618624599052522aa0f6a731783589d5952f7f45970ee1d69c4f477a4d78100c5e3b9e3ae878c30b5f041d07558e820a55f846ece668fea37682efc3dc4aa003557d22edf2673a4d9df495adfe8277c5f2c839eb928c89bc8cceba3cc7fea00c02b613b56948f588cad5f767928d31b852bce731c9f73b027843e895264e3002a1ba55b55d3cdcacae91b5e8b6922188b9ae9886c51337647e3825161112700c85340df0797d2278d369edf9badac8e411e9926e8c809476c85e95e87b21a00baf1b18642385137f7c9daedf74b9464aaf08b70335d4cdd38b5229dd9316500eaf1254bde4570775a621bfeeff5b8bb1849d26d62d1222d129122a7f42c6b000827a7349fe20f0d0018f493b4345d179440ae74ffcdc27592127c95a59bd00007ebad0acf0d0a80a5896ef5bb0afe91c71b6cc0df342558d16425f3134b8100667f6179a6449063cdd96ce894a715a29df7c717b04a88f454d5eb809a8a9900fd31130afa45b0f65642ef213bb32ab38d8479f42498424c15ae3d4636e9d7007b582d532b19748bc37d25c00c26e66a747529a3bddf8ca1c8a60b063e90cb001c4e2f339b84304758b32035bad30576021fec3f79b4b321a120a778cec6cf007aea270e3bdc4305a18a138b5d3e08cb22ba26ec8bb9ed0796319e191989d800ee6b09ebdddf97c40661c4a667d5bc51e4079ef08d72858209e02fa1a6ffd600e0e39d1c3b175830acc07f2bcb60e313f72e93c5905baa6ffa1d73dda11c9700f127981aa4feab3dfaa041effbefb44dbe14d558068675c862df9ceec03bee00458473abfd91454f62c7cb876c3816cb66ae8f1f3c0bd95e7882c5c4c6a39b005e2fba61e3368de79e21d32a0041737d99133e3bae567deac95e36727447ee008ec44be08a0be5e0872535a8275202796cf04a870a7daefbdadca4834a975d00889f128c2aca64a25f9fd71f78c5174057bd28aee95f72de656dda22e22b0b0029ef39bd9531fe4c4dcb9cd34c30260d8a3b18a6130ea6f1b4a7745e4102150098028251b48de98500a869cfe98d348193dbe773b6c0c5fe88dc99a02549e400ff67c9d12efda604002459038b6d6128343d5077577a91a401363b3871e67f00e1ff7a1b3d46e804a845118ea134dc9efbd4c9f7a603bbb350d40483342986002851a1c7732c8f52ee35186887f3339ea0afcc48a6d3f7ae957468c23fb1ec0004c7db89692b6f70fcfd9b278af2e2c74ab71058adfa9b6ffa31d35c56761a00d15a649189b4c10c68466f972284d8d50382f2bf78a13241a3dd696b5988bf00dacabd438bd15fd3efd65528502c77e9ad87a98a48fd838c73e56efd1d977c00e5afa3e65a076274197b1fbe637f3ce99dfbacdc68b7b31d4cc3fee4720d5a0019dafca495c8b82a20021b14604f76c835e1fa0f6177fb05df9b1cd8c5b9c6008a8a4108215f4e25c387ccc4b71b7a4d239821d31981503047e2ff2c74dee200a355fa408ddd54bc8c0ef629d6bd90830fb66d5496ea6dc24e1b47fa33b8010079a00566e95ee087a36a9919b6e38ea3e271b3c0f6bcd809c443d7325e7dfc002e74870b2d4adb3af461ac9825c441d64f6bfb1d2c6f175d62d80d6674078c00a0af33145c91976930aff90696f45b01e7b38f5d654a465e40c346a54d312400f913c3ef65b83f5e503ff5069d5d1e9217dda8c165a8136344f71ac29635fc0073b1b7dc56c19a765f82330609cba472fe061d230fc5bad3499be2689d15d50047eba1eb86ece75673e78026861efed4175f6fd427a86a01387b8f4ed46960008d4f0f44165ccd208e4b708ef95ca97e0ae31c1f78e22dc2c96e38bc221cdd00f52d6f57d6979527561d1e4b5f618cfe05cf098ec4a6ceabce48036982e5db00dab5b934ee0db886eced631d0f67e1760fc3ea3d15e1faaeef0a405fa6cc55001b9e9392c3a909607c20834e593855b98eaaa4c9c9c66ed5d10d8d8fc2705a00cc673d36f4f17d33a3a1e59bb601ff158195de48210e74365f94eb1ee186390053ba1b7b9785f0ea63937d69de71f9930009673cf5ca27779375cf0e2fc63c007fab9bb09f4d0c093879ebef51d6a8bbde47d3d1cbd5d536ca30f6525e3cb600296b6e73e36f6d0b35008712b106b48a2ac3f609df81a945e06ef57c53cfd50065e24a6ac3a90b1fbc7311c53483f18497ced9fd35f2dda2dbc49340c2aa4300dec2d978b0624dd98a54b06bee7b259f7be0df157694bdd97be5e1204dee40000b7be4b8ec8629df7b23b7e3f17c7637dc5ea2d1c4ceffb5c1665d717f7a9c00b9c66ec0ee3c52f66ae3d82e037e8a88745f74b31b0a0dfb2eedf70cf41fdf00d7fdceeb5fee8d606db7a22983c79ef896d3b005129e2ada651303d21fafbe00038726fd14cf16f27171c74848e2051799237aa8170e05e647adc2f24f9fef003079400321364f770e296190701a3d5ce3da096b94070d54c2870f993fe15400b839344ed3d8f340a7232b065e888d107338978f0cd8b28756b0b4961c370400d3fdc711b11cefaf1e7de7195c835565e5484b4bfac0d00365ebc53328e634005d60c1c306db7a2e0a4b1c16a1c1fc1617771ea7848f1cee8a17a00d76314500d4269f72329bb1dd37250815c64473248e62fd245c30c280a318c4d4ce1d3300317d546b12e9a605ace21039be6ccea7eea20ad36566e265705c1ab26212240027c7b2507bb717b92c2867c960dae0a9328e94a4af70833b89725c8d02f19600e418518a368f6cd81c8b61fb28b2fa128731292aae76df947db1af2f85ef8e0056ecf5b00323d8aba9d3156733efbf9efe989f29c2b9a13bb9df993805114700eb5e6f5b3522946c4663b6e95974f784097c38d38c4924d16e0642966784020056b62d46f1591599cda146b85de1f40f799bc8e7276cd1dbc84766d49ad3db0036bb5e4de1f9686f8b1f7b1efa23d4bf934ffe4c3b606b30cd7b7e1f60944b005a6dbd37f667bddc2299d4fc6201cbd365acae7bd4a13674cff0beeb1f1605004db2550d2973ac4caf53559489dc27fcb650f52c13d1642798552180876792007c29a3326ca068fabdeb90534c1c6972fae9f8674b783aa379c461e0b7736100409f379244c33bee4e9c5e18b12e5a1abae8384e1d5de2cc1979b5b68c429500bf2b8f1c9e372773fdc92dfbcd3d7e811c20f05e2d68f93fedbad37d8fd18e00ef2dcda8c2073c33756bb8b41f67a248cae983a216be625dcc996c178e3a3500942029f078265f4f0315e562fb3b1af840bf3fc98098b95304475b1408ed280052d0a34918b14e736bcce0e587f8065427781c78ad0d580c4544977268ce23008af4245a527092aff1b798307e0f4b8d876d6166c0c8d92b551aab3c67191400aa601a18057c923f49d600cd66f53c19d52f830cf4dc15226567d8fd44a19b001f027c0484bc037fdfea192b5d086067e728e795be59baf035aca34dd2505700f70f827028a3c90daeaf010a797f076d1966f05f038f131060ab002502b91f006dedba9ac79f19f1a1869c141839e54036129d1216d1be8ba17926fb5a9414000ce7fc77aba6d5748e74c3b8e77211020787bdde09cdb557edf8a06091c276005d33f205bbb4e621b2846a74799a5f5bc527b8940cbffb6c59b88edc7f5bc20045f44a1e7f2ce39091c6c9603590c9b6a751b68de22e7da4681cd484839f7c00ea8dc3211b71d5433a02f9ee02594cad7a13c8cd2d3863605d0fb8aff0862200b88f930a4ef4bf3442346e404c7fb31ef554e1607c2008586e74435dce265600d68756bda416b6089119ea31c501aae1e878000daa739f9a09c998c3c3524e001bba9614d452e1d7df9f8c4e69d608905a1764e5241f76b72ff27187f0760000d989d705f06f1fd650c06010ab754fb0971d2a13ddc00977ddf8827ccfe67600a3403ae556550046451d4a0ec75ee28df66ec407b613f22c550f60715e8cd2006a52159bc347803bdedb6a3c030453c07107f61c3d1149cfb64044c0e21180002f16cb25544e728ee871b4d2a43a8e2df3df88252d656c61fd997ec02b051c00c110ecbc3b057df4f2662b9115fc5a0699c2395768e1d740dab53ef731d86c001a296c17062142a5fce53c98063d1a6ebae8b7f116a4de7854ef3b471a364d00a571bdac6715326ad3333fd5135113c46f34951532d869e03cf8ad7ab8ec17000e9628779bbf22b3ff2a8ed19bb22f704955a1f27045f2aed42d18ef393bde00f9aa87b488ddd79960458d72a57593f0985c02a045c8fc42ef2e8dfeaefdb5009d26a779790e8cee970e39f6a27def18d887d042a8afb6efe0787504e551b50042fd860f8717c8d2199421447f8f3d66597af53682c528d543137cb6e1e139003615ab939980ffbc1bbf275f91e3f2a86bb30700893a90f4d78a4ffc6dc94000cfd4bdddbb86f38f94d5962845eab04ddcd0f32d39c6e1eeb4a2570432dfb1004dcc8730a0b0252e2191513a409da751ae07a4587b1898915ca78adea16f8900234c9e6a4495d7222d2c36cfbcd3313d4ec241ccd9f457ef8d826b332bdc1c007f24a9b49ee20c45282cd7c9e48ce3bb15201f030b665722d4884f9143a6bd00ed9c55c910f0662c1a9efcba527ba554e69673e886b9183ca8b0bebc573fe500df01a48c9106f83378f44e5e38474511656d32bb714067cecfdcec97d03b3600f4a1fd48180113ab3a43fcd17466e8837a00a5969778c12287e20a24c51c8400e27682c9124e4e1e2f7e737157a3e9a9fdc1d1db8f62bd960c225abd264c3000ca8ea5fd5f2c9c60483db5ecdb6d5a9ff231a8449cb146ca43fe9f4941ffa700eff76176e6506a83b31594387a21e6d3b15941fc8339457a507b39d2de95bc0063bb41ac653a2dd8e3042f21cdcfa7f8fd3a875fca122e7bd33419adb10de100c5ffee12cee7444706a4a6e85f889b5fa9b10b42068a53084ae08254d11a2d00bac9c0561df1655561bbd1f7d78ecef86076e942c0d66be41283b37c097a2600115bd0f6dee22e7af99833585f591f7bb73e18f239452ed8ebede718ea0a8500a7b291b11b41c1048e23bf8a63ddb063e2fab2d35c6f52fe5f0e74603b34e600abccfecd76df9218034f601130c1fa9dd13fc8f1734a9c6e53b45f28c542ab006da11b21c1a4b65c4c1aa75cbdbc97736ce1a5966b1aa6e1358d35ab2c5097003eb1196a3a94c79a1148a1526b336174da6815ef9b3921fa97eca2788f73b7005d6f3c1d4301eb5098017b0f5cbcfcb47cdcd28ca0e0559d9b97b5689d1463009cdde4557ddae5221227c98c42f02cc74fd484f7a5086e53318f9ac0a996ac0037d711be2b1ea88b0ba1b37b65a76af9fea321c7d8bd23b36b146b748152ba00aea583b2805f779475f0ef6f8c6e477fbfaa23e3e58f9762aa7dbc60d46136002e66ed6324ee99799b73f07062e5aa069b60d24aa95bc70534e565decb037200c6537833ea8b3c6037aa624da4f21cabde61483a464387012126674c2abb2100652851c62d9e4a253eac3ed9b8076df920fcd83801321863864c0caff87f5500f4d71bdd9fad8b86757a41496d9a8c84d1b3c449e0fc1d0bf005da3635bd8500fdda1118801752d26640e04bde1113c69af3b6486f027fff63c0621f6bda9f00d330ab5f34f92625607c0a8e9a6e38cb1b794cc03993ba5b7c5a3655584293000be143faa11b9eee0e0dccd8bdac0b7af17be3c165ef264d67768804d9593200ec435d857aa0147ede9a939a982bd1b52d2a208dd6b071acd3fc5e2118b2c5002302d653d243f20fc3a2bae2dc30647f3d3f8b34c069ea003207d99ec3086b00f77367da01cbf9ba0c6b20b632b85169da290598177fa5d922ae97f16bc54d006b3746594e9677f733741802b22eae23910185ebb4a98a8c14429fccc4487d00b0997375053cc92c254199027d130706608988202155efe774d73c6da3f5c20073d93c14bfe2f2dc9fa429ea03ce094df8c6e9d4a59829483f3c534e98231100870668657f3fcf5803f0b5fd0e77e3466bcce9ef96b9788a3430cb68a4497e00a22bdd1a48b8874cf92b746a4d78154d628f14c431a7a0ca1fca3300835c5800df69a5d1954470947d1d9d688570f8072e38e1f931dbf5a47dc8aba5cd8ddf00a65014adfdd278103cdffdc5f720e092dae93135367c0ebfbb61c0c71e7dbe00358941ccf5d48c8db93f8c794e4fceff5f6a7934e94eb33d424f535d7307cb006947a94c68b62fae72ca60fee24cdd22536c35b82785b0532e3d0f966bd23b007924b4c23894114667e86172f79c0bdef95a34f8164bdcae328e42e013ad120075237839db8f6be82288eec19ad259782a8ae5f0830e775e207e986d2f13f300076ca8ca6662e21862bc21164bfc0103946edb92157293af3a5ecbdef3aebd008704cf384cf92620342a9b6495fbd1320ecdbd9450496a44cded2f7ccf0bb000fc19424f1d7a252ff0793790a39af53a28b52ebd9f270e3c308b8f7ab51eb900f6e9d68c03ce93412652bd2a7388083b3b087072d11b1e481cbbfb066eff770069717b786430c86252e9dc9dee1d44b9801e4d954325f19ea99a45741062b700779ee9b3a2e579d3f1e898e0a1e6d22c1136417a92aa75e686c2e3ab0ef1dd0005964d550681ac686d6e3ecb0a1edde6c809defe42a8b0be546c76f20bf08200a511c3313a9f097b955a37296213a45688e2f6c1ac36ac2e9f9704550af6d800e1bb6ae75bdbcaba78c9c9cbe8791e3eafed240e1aad1f8059f18a923cf5860015b8871f496f0b05cb96d3f252c16ebe44317c681d8c656dbd2c41c13fd762005e7d88a3ccd57f0a89f694af39aae4c658edff4ddf2c6f5da77e479e4c511300b10450e896319975351a0fcce15e8b48add000ab719b8a34665cdcf0152d61003daadc2c4a54f542b32a15c7f3525956e8673784ce1c0f651a3f70f7d7df8b0032b2113dbae9c04a5f23c1037e3fef18ce7f1b44bc56830261ffc7f8eb77a80041a0df4c1b24df8134af24b6c2f90f0c57ab819c75f98608e71d884729b86f000656a52b405d54573290ce2ee4fe677b61894b953193164e06ec1ad0b3c8d7000818b9d9daaee8688559a28efb178a346357f25db12c0b54fe144ec72a5b3400d84d1a7a8196605a624e52fcb9489d8112c11bd9862815bbb006c6830b8dba0068a4a86c287f67ed414a79baeea7bdc537b14e8eb76f75a03b428d3d241a8e004fcffab573b0b6a1b4b9e689d7b16e4eb74ac50f90a4a8eead23057657ec8300441f852e479e48bd12104e98a178011b85e550fa7a50afb6c2328e72cf9fb90075e2f63a54f95b2f74149250ab15c59d07b0a18ae8dd949717b8616e370b41001c6b7127e9f2cdfd0fb52530b3aa18007ab2a5e6a4717f525339f12c3667e600eef01f84a7d840052942bdcc59501a6c133d143f46289d8fb9ac867985f8b300c93c9dd77fd66ee76c5117f1e7f16222b9797c41ad0134cfd61bcfaf2849ce003434fe9267aeb9790b5a20173a2a522046eeee7cd2e7c4fab4776cbf8c2251008b66706fb2047c5401350c20f074e7061566f8edd73cac7e53973b93db76a90088092f006e71b5b286fc8c75c3a6b14978a359f4a4f7cc9092f2521fbba887008127e1c4d0621e4aa0c30cdb0ffce35257f8b1058bf9f5917ac8591969d5f80048bd091d39759370ef9541a24d23a5b63d4b68455f9df67a7a02217e4fb581003ccf9042df92fe46979d65f0c812b26bafb816449b4052f2b96c6fc8991253001ba85f55e9be24cd840169845482210d11b874f68beda7b5483e349df8d8ae00f73525307266c79463ea9f18818a52be8d8b2cd0b8267f5d2ec0f2c522edbc0018403d2632edda722ff99279e7b7442ee568249a4daf746b58494e598c288e00c6ff6bbda660976a36abb4bbec72c54f07a8419ef4794f04626cbc69a66c0e00f510fbe2408210f0f53c793cd92aee05f2c0607cf43f604d2ccc6d21bc83e000447665ee6404103a161b638f49f77eeebf35a462c6b67ce02957eb4e2c4cbc00c2442faee5718a88a935d9ca249fe51ba56bacae7729112d250aaedcb1650700c53f0a79f0358117fa97834d52dd8d59e7f25633d77d833a6ff362337562f600c1676b86176496e30990e4eb2ef949d4fdc1023bd6417b883b67fb3a09beb500f92085fa9323599339fde4ab0f1227e6c16861cf829b1945f447099a89aefb00f0368a989c199e4d725b5cc9b8dd9a37880ac7b07d2361dbb595af7e2a86da00cb9e3b12479cb967b01b17cc067a4e71b58c017d10eecc9c3e9d8fefe3447700d2d93555e13dab47b028709b7dd2a7bd89c296911ac90c3b57f3742dcebfa6005ae193913e67c116f463a12690d2648e2f21ea20d02e435ea64871264429180051c67b68e1f9bcb2d5af34712186f8a9a5e104769384288e2000d6012789ce00bdf00efac5a1a56cb9f56fbb82c2b35249663e33b970a84b56fb0b38503ae500878d29e1c309484f250700beeb9cc6d74924663600ada6c704e0e0476c9f4100907c44e7ce465989b34b7aec6ac56e6ec741e0272e3482166bd113ad829cb800edcacdee98726f969fe933252aa1187c6d959c28ed87bcdb903773bacb2a47003e97c0467556aa9ecc7606f73c15ca976e7fbca860797ffcb381e5a91f59ac004983c214ca5ca5b307c5687e125224a3b7ab9c8166ca1595496810284ae1e7003ecd3aa598ea1cdace2fea38a8cd7e4b133719da2ddefd44e906bf76c58709008582d7608294d29a3986540de6856d5fbea8d998d14bd37518adaf9ba99cb400f78e749bc3dc85177b198fcc3f44598a5befdc98fc150124684f50099baf3700fd6e17212bc5625ff2215fab4ab20ee2cff94cb1c68e33941b921ca5bb7832008d573502d669176e8766fe45c1a2127e8b4f00ed196176eb774abd94aa64c60092933cc0f74356a0b6230ecd10a4d2e932fa83493cd9283432060a00fd1fc7009f1cfd993482075b0fdc2487838a06dfcec119ab603467d60e2e1334c27faf0049766b5035757cf8eedb0938bed45ecb4fd7f56fbcd91f5e011480d954559e001cf2ac4ee1d011137fe01a02e2ae49fd252e2c30cfc8a3212db815aa990642006e5000b72eea31cff24d4e8b110f1aa51efdc335b659ec56c891c8a9a5dbb3000278386e5c9f48d99dc1114154a56d52d3365b4c842f4a7fe452b30f3a085300764220e19970293f2052d7622117d6e8e20a8e9f2780eeebba21e684e2a47100c6724b3f16e3affc1cd2f857da26710f956927d6d0b03960b3c952ca8e821400db1f9c7873d73642d0c4675d1a2a6fff990b457b170978374eae4e18a17c6600f899bb1aef95602a9743b5ac9c3d3a5d6150aa02342311c8e41575fdd5d058006a5b64a3fe39e049c89a853fccc9214aeda8be07921e12c3b7ae52af1536540084913372328767470b3de2b042b87d2aad5629a64fcff52a1db900a9f1557a006bb6989ae2ce1ae0e8ac3d93a5f179911cd12b9a12f12285d47ef43045222e002355d1b59fabe36b288611c09921451c13ea795c608dd8dc2f387a7e20e6f800e421d85a70b941a25e0d2ba583e8c56dc6657662bf63c62e665c7c973180a000701a03f7354f66963dc05eabd5e514688f918d84b0b1c173158788e21a7281006382e6fabd92ebd5d24599188ad94a40a7285d9e667962ec91077a33ef7ceb00fba8b4aa05220dbf3ee327fe2a917feccd499e96bb90742d8a51b5576d60fd00dcbf91fa6b12d0a5b195b9bb888e2226246a7c732cf366506dcaf445e215eb0083c1018f63e802e2c197c71891929e0b9db2e46730efec018b9b97fd4d5394003ca792da7dbd8839b29406e0152a5f7065fd7cfac332684cdb898d65b79b4b003abca4293dee2b79c8f83504da5f7afd202fb271ed00edb531bb1549ede8f600e36530e37924b514a59405133bd1256ce92b5428037fc5b71486b04202d38a004d8fe5e5a80606c8fad5d2442dd64e1312c2311cdd52ff6edf889eb61afc510086388457a03ac8bee39f8dfe8f3a9225629c662fdf5d0beb35347437908ba600352ec37a7941b7fcb7ebd6b0bf98acf27db870ed8071fa763eb38c0bec1864003d5af9d8888618c5e653471a6ec93e3fcf75e64cfb76b37378446171110b1900d4ed29a32ccc48c139428e9298c9b855395908bb80f155761d2895099990e7006d1aec34d88730bcca3dbdaa68d723a52f7a82261c17a741c6063abd360338002d8e9eec4345d5a77e960588f564147fd82aa4493ee0197981a88bb2cc4b700048464a9301ceda17df675d71f0a71b5a11415e5672a9de4be6d6a0f78ae703000b0046e3114258f0a468c45f8426fd18ae410f0d772675dca2e10f5b0ff16b0013e9362d8185acb2e403b224d38933a558389c8d71bf609b64e7c8904f8ea9009b89f1f437d744fc27a706789ee29196c0b3aa750c0becb22e8ccc354b8882009ba016a45d4c22b8a8f8498b54e079612ee7716588700de30d72385d6fc15d00a7f418dff5afa55e89054aa239a3662be6bce6b7d38f03ed1b68858debe99500beb940ca610d4c137f539d221e5671a22cb928cb81098ea8ff4a796a8b436a0088ba2c039c4e4347bddca9a794888019209eed1a189c38587e175d8fcad79a0010f52947dbd737906ba32105232ab2abb6c90ef1b5c11619eb0c939bfc6e48009b100b4768b4af6e6d336f168933871c780d70dcd0ccd6f7ff88017f6754f80087d0dc857ed8fb0bdae6cdd5d237d350cc9410e0a43699761d9ae2560c41c40001a33d489f0f66d852a861ca5b0497d59f2652545216c29d1e32944379c146007c60e9cb334a9afdc02d82567af3c112935ab42a260c01da12e820c020cf61002235b190089343dfce13dfbae1f99307833125d8cce351fc4548f85c1fa53b0059f032cbd8d418660e2a59041811809818ae3548f65934af50cc68a201765e007b27f45109b6ff213120c658df02ff052a33b7ae33148d61c2e8faceb40daf00e5a7463f4f853ecf035e865f86fb2c2d9c373b72cd5b12e31615e6458927d6004ab3b76fcff430a0424fb0012a5f6a42e27be383cf6251c1644efdbc2a93170025c77c7e310ca7f057cbb83cb00dd92d9a56000cd6ea801eaf1bec76efb153007243a7247ba8e1a8a0404fc5192165dd3e5b0cbbab1d36294b2a6c08baf5b100925010a43f1f3395b66a6b60052864ed9d24d92874c3dda591bd7e570435110017a6501d5789e8d2eb866df498f708a2840d2739278862ae5d34a394995dc300904b081598c6b2b392ebb7f0e50c024e499a0551ef171bae3aedfafa84b58500e997450ce0b5167478b72ee63f7676c569ffa91a106ba5ad73fb9d9875674d003b1208094c22be15b1943bb1627a2afe185dbf5555565631a1f078d5413d4800e1242a1f50642103245594a596b5b062366db9d1c82ef3cf1edb0013c5213600967e7545228c46dbeaca0e47932cde0953f463ee256ae6c2b630f38a1ca6f400919595838d48d514bf3876545691b1b5e4edfc172195283f30f78b32882c7d00c24e238b97ec004a6da403a257df6ee07571556f569837bf60a14ede1a3a8000e7bb2653214c67985bc3f364f79c7c938b087df7363ecc41069b3284b434310039eb53acc01eb6b7790f9f234d45efe98d2393c55e1a95e6db994fbf420b52003c5d0921b1dcecd1425283cf92fad68d8b07c24080f4f77a4cd766a060fd90003baa7dd287a872ade6e222f0306b7247472754f26358e1e45a98aef38668f90069200f33b44e84ce406f6cf1a3a9efb68e377dc61e31c2b4e4e026e4b9f1170003051327ed54bbbfde76b3f7d87f2071daa806672467c2cc02a0bab18c51330021902a8f35b2cd2a5ed078d0ae822dcd29ab98d833017197c914dd32b46c64006cbac8b7cff87cfbae3a6e5748098fe5381e77892053852f6ba2412d30ce7c00764dc332b5a6670b10f881382a9e22d1d300afde1bc61db9ad8e273c58917800468cbb8caac428c4b07acf8803aa62913e2eda568efc6edb7db2cf9e6722e000c79a15be20c094a568ae164fa89e8b8fa5a4322f63e85bde944646ffe1769100c92203a6e2e1390cb1c7155700846313b1092c22a3cd87441617c70567b56200d44e71bdbfc1424831317fb680a66aae47421448129267adf73439f62b093800f9eaf91d9c8b2d1828b530c6542d5d78bddefa64d726c6dfe7086369f88d5f0035a12e1a2182d657bc132e205be96e597ba3d41ed58bc9c6fc6bdd68d0af7700655db549267b3566af3e5517964db905de681f13da95e24616dcc95bed2eeb008d7628bbd2e6675cc8f4680c0883121dfd62b02d44cb861edf052f7ac69b9b007575afb0c7d44ab363bc6b057c1b72b4ad0cbd301c93637de3bc16f6aecf43008c4aac19f47f0d7bdbc9fd29d087ecebd9ef7cc3d747749302cf85b7f280c50000487df52737285c93e20566f0818d5f32912f3d2fe8506b020131944ba94c0027c9f8ca480630f95ecd50d8933126a44d7276e562f37eba144747ea8a2d9000835fa151f7d9c492ae100c11f54128b48cd9241e180d3f3723e71aea30d15a0081962dbade6db8b7af9bb1d6f5fdf242c770a84e0b6d779ce85ccb8574675b00abcbe99c500b46ce40810c417f2af16b7ccc440a7d91f70d2913cbc7f8037b0035e76b902b6f3446f7eaa20c0e9aa0e1e28cf3fcada2cc2a05b09ab59c73950003191c6f84c6909953be4715d3c4275d508710a21fc7443a11024a8162439c00145698c0c89d363c4a704464fe495da7bd4f92c59d2ede2b3796d079e2ef2700d2163e61b1778f6a687f574df8c1183d803b1098ead277655b831a24d595ad008af9888c013ab90a8fb0b387bd7407bfa0608e2f11e446591ed09034b4d367003bae9681dbc3696009fa25303684de74b53422eaf603b32e98a59e118bdfe800d3bec4a1516e45b6674bec561873bec582b03d28c6881f51e6ee501cc9dcd700d899bde5ac37a840bcf5953844c85e178cbdc27d3a2eb0746edd800e98b8ef00a335fa9b979794d0a77fe1fdc88fdba5e917fe34e7ec22fd98baaca4c5410f00f1b086fc8003a67f6887bee9d3413f43981e25e74b710ada33bbbd2f87795b0065cbbfac3b710b71d553f4b339bb40156d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","kzg_commitment":"0x8169bb0cb6f3f2b6ec48ab6beb7c76cd951b8380837771e5c6cdd6ad532972a8113a41f0574dc50a05a3998ccfb658d1","kzg_proof":"0xa955f11c7135d9dadab6294e153ebc33ad1d4b0c7ea92454afcc9a72eb6df5e8c0eed7a77c2702be91ad46dc177a98da","signed_block_header":{"message":{"slot":"7422094","proposer_index":"129686","parent_root":"0x811c9952feff5a7c8325635f1729e31ebca866ed88a53aa5f26cd11d4b9788a0","state_root":"0x0bd0bd3f512e5f64d36170790010238168bf0dfcdc22fc438fcf12e7675b33ae","body_root":"0x71d8c523acce371dfce3ce7bc2897e62fcd72eafa2870be5ce6c08b94d444fe3"},"signature":"0x8ed9b52cc7323bd7d16e7685c4e5608fdc3144fd053bab8d2cc6cd19048b0214d2aeaa541dc4221e4587d9ef9830ae960b5d417951fb79d86fea3bfe31a9fa06a83af01ed7e579896afc3ba14e3be41b7934ddd1886a79cb23cd1a9031cc7668"},"kzg_commitment_inclusion_proof":["0x2005c9672552d87ce6292c5727c8adb70032c64c9472b54e0e893ee04d409130","0x1b8127c003fb028cf043207a1ab815571f4ec5852339a6a21d95a6c5d841b68c","0x8c0b1d87cf64f28c21bd39edc742ca5f7bbc3dd5aac8a97009fe53ccc6b47011","0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c","0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c","0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30","0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1","0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c","0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193","0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1","0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b","0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220","0x0500000000000000000000000000000000000000000000000000000000000000","0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535","0x56bd14bfdc37d27695b4efdf7f9851efa0e51272eb0fb3a5934f0d9f52ab0d5e","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0xcf8646fca4890f4bec369e0f281f4c3199f294b2f3b3812a4a2f76639c93742b"]},{"index":"4","blob":"0x001611aa000000000463ff00ff0000feedf462ff12b2d4a91a814a0263b1200a00034647c92c17601a05df0c06477d6bc10619201782ce0ffa158847793884da0087023eae999892f7b8fb183af9857e62c5d62801eb0ebdcde37f9a53da27a600e8b01bd2a3caa7c18c7fb7ab24069b48c0b680540bc6f3e76117910ce3e6930064792db34bc1b694037cdda0d94369938d138a2b49608c705a4cf6acbd0ff60017bf5c4b46503dc7ec9f5ae9553f6ca0883a16777ac2b30289264acc649e9800d622ba8294ba82b943a46f56cf26938730a1e042fcf0499e6e4e1c8ee89daa00c481fba215d8b27e464f331d07f42075d66839810660d94007c0af8eddeb1e008e764ba26abe8b7a081bb2580907f43acaf7ed14f22df9a624916052bea06e00dc5986d0d85bbce09967acaad96531c7cbb1fd391c4fe68f2a495788c7efd70049bfac687f142bceab302202ba5e64f8c5d227f6a982d7d35c7383f722db61003ad084f0dec3144ec65c55282c4ae5223d89433dff0639089cf0ea63945d9100221f8c40de367f53955f6af6682668d1a883273fe0e261ed414c873fb94c6500247df213ede73e2f041102cb8971872523be8de589bb5ff86df4d7427d4a33006bd827893629a497d1c9fe3321ba7d784a7c9d7b26fba0a47cb0172f89119a00a668b3993bfff11decc040ddc0a8bf63bbbe5121c197eb81fa85f7ee864e1d00fccbac3ba84cb1c8f7baee2e967b90e7eb531b9ae709881fcbe91df5f9ce8900b8a1d1ae7879ebd3c7ca3508ad3ff1dec18511333065f7b1c6669d90f627f7004d04e04b59b3311ed85ace538e57acb32335e48475554e3bae18782978ecb300fab5b1cd68b7c8c0e80585ff5c04c1cb92aeead957efaf9465cffddc7f17ef0087fb7aed22df89dfa63222b1bd4d1869d28c460f9b8c545967f1f9916a36e600c321f3c2e8e95f36c3eb023310d2da3108f6c7c34b388c923ea77f6664fb35006cba18480a9b32da86a7869d3e442f1935101227573dac174b44ecf3b0506e004bf148e1c797436ba3f2cfcad51df8f37b33cbb4e3a6f2e559b4a00483e6f500915fb6375c5366f46ba25e8ed8ca0f393bb0d9a747b6b57c5c3b8fbc86775000de9ec86d1ec937dd3575ae69c02137dddd8f1ab80b3b4b3b97827d7249b08400ae5b09a95d3f733ba2a5d4a4b4f0e911ff015b85fabb5b9b2f3eebb8701ebe0044acc64c2d97757f6f81a37ca11076d882091830b4117559ff9796d6b2eda100ef0064fa69d0e8082b9966310d67d700e58600735fe2247f5643674a0dd69a0065499a30281ef2328352e9f4f0835afb2d0c80c556d18e963a00f6bda5298d0045948cf2d96a904c71b6467c8604a44e9720177116487621ec9c56f636b58400844f7c2584e31742eaeb8387a0974b4c3c8a3c4db4bba7487bd8b3b07635290038c8c5414eb7ff56a9d9895d2a0edda76e2b8a6fbc8035986d945268ca9fb60024129bb1e5e0019b8920bdf3e3a20dcc4712aa3b8870bbb3e221b377e926b200c9929b7e637f335c823aab59d42c9877a8167175d5179519a852f90c778c930024c732ac529e89ecddc4102168cc6be85df9edb17c9f47bb7137fae93427810006454c758bd021e862428e20badde8e03f4189422a201d44bd5f5fb752972e00a41160de424ebed157a783e25d1f7d0d5229713614496847a6466390aba2b20092c661548b9a6541fb71bf35322223e135f1b501cec988b9f783562065580f00a942c6a899eaa965fd68e345d4ad2f457f04fcadf4596d3a6e316ee3976fec005ebfd6f7dda19ce16e1c976ebfa1463e2be58aa8ccfdeb46af13e0155bd94f0040c184c7d39917d45d958e94dc5a7cd79e389440f971a97192900e3b15b4a3003837afd63345f13e369a8c06a18e67497434cdcdf85b53a90cc7cc09dbaa3c00fdfb22c647043eff09963079bb1da80bdc47a9b587312db52b1ad74c03654700804e1b378aa5c1bcfd53d5685d79ed5e929ad8a3c25a5a89812dd1c88be1f9003654ecd3a3f8bbb178ce5f3008ef29c7f4ef68260fa7b98421cab4f7f21c1a00e21066e0791eec3e93129896694714726f73a2d42dd74efd0b05c63417b0d600bab057b6ba8c70f81d2f1486659c7801e43e2f8edb4c04bfed6fa8383b8f0900264a40287cd8bc73470db1e68a35633cf46330ad982dfaca7576ac3089bcf400ce3782b6bdbc5b4a93430fdb512612a06da17ebda9d7fe66fd27627364c80c00778590255bcfbceabb683d02d6b93cd68f80b0dfded9c4dca12c5c4a3942dc007ee1b6f03077686202430294986623bc3af918e3d0c701654f1faf96593cba0045f2a090fcbd9c41a731bf717c36e00668c3ff28218e390cc4b28d3d75075c00e95d5d138fd52f5b12d5a39faf8366222247b85b9f06e38d5f15ed45f6978c009f175353675e6fa42a3f7cbdb5e6fa6083fc6d42dfb7c58994be06c9093b22008eb656eec0fd5412a7569366d596b3528607ff5f352f2fe676cfdd09333f3b00bdae58cc00b53635dffc6a08a4eb62fc8b902713fb2fdbd17f2b6988b323f100f7250a5310431e3e223b092cc188b2f118b93c5cab3a48afd12d02ae687548003b2b5b269366132f30bd1955d279312bb6de2e339d2331da9f0cec9abe43d50025075591ce41541db3a442dbfd3bb66e37d78554cb200c91b5e265d15c32120066f4f74790fa8795f374952787ab7d91f565b8e5f1911376c3ff4f6bed4d5d00d680b9072ce8f7ea1fa9f8b6037b1992c9261e6ed5ebc53746e68fe24b676200435e67b0583dacd02e9f6031ac2d11f7b6e99139a401a9e9d086cbc7ba93280005e8b543fe285111b3752cd3ed0380b7e98baa45d87e1224f3129add1a878a00c033a3c415c1659586106d2780fcc2bbbbfc7c3dfa994aab49dee9f9061992004958abfcafb89bcff5455eb9e438cf68012290987840693da2453de43fc25900ebc0c574256bb66d4a7537018a52771ed31faf57b9837ec72910672ca02a79002b5b816e32896aa5401bc0b108437b1810602ac55fe38556d54046301bf9b800fdcdf36072802c5be4067d54c85ebc6aa90b2cd7d4ac41e37f3663075bacd10094bfa513de607e4269e891af3422b30280408b6f0625bfa4a429092f7d5b5300baa30413f2b60f3698bef85c30ca1071341d39dc03ea9bca12217f0c524f5800ea60ddd85263b2b71d05f7a44461fe428faeeb5876c94c7143f22b7de4c35500d704860cb57b1258088b549620433aa9f3637240ed4cc154d28166693e5a4e00b2e052cfe060a1f4dcea15a14f9ddd522c3f3ef4942e844c6af27f967c2d220057701f034334ea1d147d37ce4e0df7c28f72d780984ac616c3c0ce30b825e5000f77a1a088baaffc2e80899e433ba9ae61efccc0c533e7bd417bc5242d0d3f00ed16e46949d187d206605ab45eec7c7146f07961e9e8ee52b57be009ece24500f6d582946766adee3437bdd7dd8a2090d71522e944e4bcf76ba90cb4ef262c007eba124fac93baf0a02e00cc918bf8f79de9938e14603c88f1488971295c410069cd1125c07fce68d2d1d3e7b851279891508325a660ada157685a29551f6a00594d99bc5dd9299f87e9de3304922c191f8f9c441deb3d734923f27f47214b0054b96932e0d127f39df3e8cd924512d3e2d24045b7bf87bd168e7b4baa194f00a6377377a394b4e756616bff01153e0eb372aaf55cd12f813b1fa8622ad47200fb7a15ef0e540d4102c36353c19d3a5020902215cfb84cd92fea43e531fa4a0077ebee2a6d7f0c00850ea2c6529825e32699d2838d0c865538da306911900b000b897afb39c3324111749c0926a64077f4d220307ff88983cab834c906356a0089db337f2a1973a3327a909a17cc172ebd48873ae06759e6d095c1254f8c9300e409679f3f788a5da105b995d0bbbd86bf5362a23aabd22b3b859869e0926c0003a290ef7020eb3b688024b2634f31c0a3f0553b480c531d9c34b19bc19f2f00636611e8e98ce2125a1da04959cd3180e493ae1fdcb83d19af7d3dde6b3fd80040195b89bda26fbe54a5afdd8ea45457afe83301e3c8db0e9a3e59a99577140012c4fbdee81828af316da6a99af5841d1e3f773828402b7ee4930c9395904000cbbd380a6d156105d60a93fea577c4579eef001b1eab62f96063c301fe533000e21aa681f6fb375269cb5f839fc8d7ecce65311dcb6dd6de9f620e71da1a48006806c7a67149be8bb3883b402b10e5102859bf5a7cf09748f26ad9010fc77700223a7c70d22820c5cc9504df43fc8cd0654774ac7b4ab0d492e599d77607f5002b0d1d99de83248030e6f7088ff858f1d5999d976138f168d9fe3200dc2c380026b4847aa0a52d6655c231b4bc2eaa3379186562f3298e93d0795a7cd8d9a00005e95520781c33c01f4c6d6d24c2ce66b057ddcfaf2e6d910b22c9d1489351009bb0c612faaf3a7fb0dce4a8bbb6a43b53288a5b486b87a8fe1bec457889de0091e1c83519dd05d7426cb38ac9116a6ffaa3e687e44a5e42aa4bc547e005c70099aab31120397727c991657ef131ad8a1927fa4167c936e1264523bed93e05009a484fa2c94c12332eecaec3dba789c1dd364a534927a8624334adc354c00b00b104347a23b5e942998e4b325a31021b5630e837d655b01505f6e34f03a60800531b948602db54e02ebe11f9b891223fb5c6ed050abd4fc3cbc52a4f7e8acc001b5486e7689eb3b642db5709d2ea03d15a1b09967384fa4b4a3c96ae56d6d600d12290e24c8a09b118b44b12a23dccfacca70dfea9775fe4b0a2bcda700dab00e10747c98dcfa2d69b5ebb50e81f9ca6a704c8bf5e8d59d9168c3067532d4100a47d9ba374c4e7eb752f3f75dd1a7b0e5b22a29236cfa2e7cd4c1dafe8041d00b59db75407b038d8eebde73ce99b2750429fa02a1deaa370ccc63a2c49c03b00b7008114fd35d7a7db4061f38924f4927f3ad10595aebf29c581462a9d86ec0079fd4e173b824c279725b0da7aba74e6ddf52d4079e47fd5af17234527f4c700731042ce0daa26f72f2e727b6aa24160379eca87fd5075e60ba5f1a56adfc200584dbea9ce65f56463334d9a20e5843b7fb4972f4c446b9ade796c3615552200e2ac4ef8a44794e1e12aef60375124e78ba9f2a7b47bf06452bb6cf2952862001c5d08da90d609296cf9addea45c50edb23a6048d398e3b6aecd4bbfd46e3c00738ca1da23fd5809e7a60668e49c5233b040fe26fbfe83ae659f736622df300061c111fb1025e8f2e6e46ff223652383f0b42ff5796685a133f29c8503c917006394740c4622a8b253583e2e27518e4af4094d23dd3317b26cdb47a2587c74000038c40986ae39a3775a46ed33098b1491dcf7739a24a75cf2c000287dce900066b15dcb80cd246f6692b437b0d436cf2e71b8c4549967fb11748c4cf137fb00c6da14f1107e6504f12b87f3e3da758923e76ae6fcd290319b22b425a26266000fd273580b83b04e1e85c80b436d8e3b40015aba7ad2ecf7c50287de4808dd008416ac0318aefc53b0dbb81869a4050b3f80667f94c9ae7ceeafb5e5befdfd00ded3720db6252be0fedf4d9c3ea8834713c161d245735b64e0a611c864570e0023ae807ba836b163688a566e54ff5d6923a2e6796b3069c451067b0715d4e7005e04b926c28a763f9e943b1d833474d3fc5d68b32e092bb7c720dc1816dc4a00ef0b2af820ad0aa4622398ae768003e1c7374d32b7081d1f3e9be1f2824dfa00e2c943f3ac805840dfe32de068d9df82d2c1a6b970b8808c6943119a17abc700f672304ac984ecca987ef09ae551fe2a39708123306cc927d6896d68fffab600868c59d5fda841457bdd5895f6ad2da006844a6d5e1da52e95dca9b318887700507949aec709a666cfe31416b2fcfc1d7b9d094ffd725e8836f17233a293f20012b1844f0e9ee14d85df5cab6aaf791a426407433f77ab80eda47f87721c2000258b92f05efc0379b42f0a50ea36a7b879864aa2d3179d988900e7c97f3e2200df6612e76e5cee8502a433d7c382a081071b216cd45685df07af58b7edd6b400be7034f289794ad35068438bbc9520f6dc82c6922062a2f43d3b3f3dad881d0036fc18708d6bb852e3feeea7f123acda87593862441ba9bfb3baf87048862c005698c789190f4c8864c5a1ca753e75e1255460cad6ca653724c5797a4bccc0002b39b998b3aa7767237293db75f4ce88484e12260aed2ced2ab6c658d8594500c7e1c5976a78f59f5a4f573a6626928676b027713c1404ed91b9b8f90539d100a9a49e7ac17787097effb9f01f9f0ff7a5f7f24fa803bf8629964196eced01005103f18e365f69512d1a8d140b19403b206e2e7e8f8c03052bdfa4736bf76a004036486e6239f1e2c0087102dd8caea5208a24a221cc8e29c4a8a88e8858af0071240ba763db63fb9e60a2fcd05fb21a46fa4b7de2b801dc0ed39299333588000f467f3aef19051dcfc00bcee9df5e04493b8aa190b3247ab5f8e5db3a0970006b914d7d509dbfeddfe963688ea760a08e413a23614d4196679ab8155397dd00cffc49a8f6c8f7fdb7dcb6f87da4d94ec5ffd3ccc1a20ad93cb03cfe5dcdae007997e2027a47392f41693a5dbe0356bf22ba7a7b4efdff28ea66f7c13cbe8a004f718a5b4668efbc3f16c86185f58e1c99b02e5f854a89975920795529c7350093158a0ca99f290f2ffea6b4542fedc468f00e8f2ee3cd8e7c43dace0a9b4c000784c938eace0f534bd0904f993cf677e94517171ff4730148712c8d72caca00cde7e5171e6fbe34bf8f20d02992b915538b696c64defdde9e7041a5553a280089c1b6c19e44bc5864a991c3afc891c8697291067343aeccd6af3d11f839d00002e23bb0f444891ea302f9e4cc9ceb4592969f7bb86e65025993a271e6379000765d41e20e2c9fe771f2483e45906a67144fb7efda567e49622bad4c486605004ed494006ec0c8a58a7dff56f79e7631e98fb2676d9ddeea1f63888f54e7a60049a1f98afacee219f775509082994637e6c9010d88055ef8833b73298ce9aa007dcfef598150c7fc6ad2965187e2e7faaeff54ebf17d607b798e314349450c00e61284ebc0920fa27cc11a591dcc9726531db5c7592d446d0626000213c50b001b2d7a4afa71cb9f7e5d073686a3ffdc7d1132eba6a7ba6763fe85761059d100a60e2a7475ba2ccb1eb198df08cc988fca0fa61ca19bc7af42cee210798eb2007645b7e21bc03eca8fe9b8ed6588c95fd14c643bd2db4b5e622a2500f0842100c76f7b5ac8718de81a17bf02794c5e61e8348920ff83f0c9b6fce078f300d60092fb26a0a80d8e3a3aeda29c32b91b201fa3cb97db9aa6751e3aad30a6f91b00db216e3385df76b9bbee0b418d0c41fdbb24aa768ddbfc08b866f4ad5c082e0036060d8419c2f31f7f0e776a8b9584acb7f0c4ae88f74b75ce14e3efe6e7a5001e9156e9afe5182df09d853c12bddadaeb212822d549fbbe11e68a8ba43e660029de495890841b7e0fc8fbb915b7fe7c7be683ffaa58b81d5e39314c99b7f0008eb04edf42f6d6fd63d4a23d75bdb0d91f3793b1e79a812336b7fcea773e100030b220203ce10ae69f69d1f2d10e9c651c8aae736124cc5509446b1584959300e29c55bb48937b3a4aea49ef940442494c72a8bde008f284ab346f45670ef700a66633c3a760b14d76b799681cda29768af4f33b15acd666d809cafe96fb0b005646e70b122d3f41d77b872d9f8abd77dbfe025ba59072796ecbe0649fb5410027ffa427ef9ee9f62685466202289e3febcc6da7be968136093346d212596d001ed87ef96fb49e236304a1b90005c6908f5960baa6598c8423f14c6028559b001f714990540ce9867452ac21b8ddc0cb3b7f9108e2b2e0b0c3a21587a03a4800a5f6748e96ddc54c6a81690dc947fe987be8219012a6abe4a78a6858f14c1100e3abcdf55d9e0edd49e0bc8676c88c9aff4c6c33ab2e528e8b43b434293549009c96e2c766f37351b0dc39e03eb79f922cdf81d7aee86fa8d4a6b230886b100085d122eed2ae0d844e755d94c40c91aca065d4c1acef6ea9d8ea254c24b7d900409f15a03bb9b3e779db02a7971289b8eed8ee58034931b02a9b57475dbb0c0050b925bddbba4cac6c94b7b16e611eefb6d547f7a39e85968069f65b0e983b008407feb47cc9e1c8be5ecebd6218809d739d4d8bcdcc5c9826ae900e242626000b1c04bebf4415dd4fc49eb6c5eb7c38e77614e0e5df875744df86e5fac34900f3e27b851acc190b1724231656f6d3c7ce5657ab44d49a4304820847c8b56200917aaa38628b0bb1115c60320f8cb710da8749d223540952de56ba884a5038008970dce387e397cf6d4c56ea62663f1719dd40b2a00ee11f8decd044111a6900b7f9c69b12d34c93306e4c9deb56d672a9b81a56d9a2681d8c53d027458c7000917390b073176cf6eb162474e3411810bc4cc026a00720c3d37e28fe99ecc000c52a019afb96cea203a0d76b638c16bbfe75095ae04241ae52fa4bbd5202fd004a5ef53a859e1ddae020a609784c27d7bf922f809bb322d4222b1ce340137400dae8790888441ca3a7ceb06a907271df88f7f9b23c2029e160f4d795650a7c009de9d5dbe608ffa77c0e210e536c79185b1d417db1111adf8d79668755440000f0d08d0a938b97b69f73f37868f8a9f0d7791bf8bcac0f8fa52bd470c1b14b00d11c750f023dc1923f23044b19820379418e1748d697516560d39969de4072004c401dbdd273b9ec9d6fd8cd58d337e1ac6303cbd8b2faf7c079951eaa80c900ad0aec4785cca02c6a6f566d959366c4a1b937a0ebd295ad8d243ce656ae5300be2de76c9a1132ae500518576f82b0b17f714fd54c6885b776d8f1017c3059005e755b9de694cad8693856c91fbd62cfafdce008f0c205b70f7cc8676e3e4000f86ab81ed64a448769aa6a42da696616ee887d5a826f06704d2f934786459b00880953851ab99416c338e9c24b3ca25c57ae7e73943a90d6420abf04958a5d00b859a5fb59a76499c9a59ecf1c42c107158d7f7658c9b7ee5e6d273c655a8f00d7398c7ea0c768587cc80ff12058c370e110b143cdfeab9150295ab5511e660056fbaa1fae0f0b22259aa778767cc607b51b51059ce7994d42485a569e809a00ef258e02574025764cdb24d961f249d579583b21d7e86ce97057b6c51f53360004e6cd62696ee78a6e26ba10ba6089b005bd82267a6677d8d00623b86581400024d7e878189d90449262429f73b5e8d9397e1b56f088ba93bf32e926a7d78700ca1c3b4433f4d3041fc3014bf6ac320841955389b71d6c438149021a55001f0050555d7fca2626216ba02f623668f2b856b383203e9cfb7ae004826121b3050057fe913abc22f447f3312d2ed11273facdd0392e4ec7e6c17f8c93467806d400289b5ba04931b57d9f2007b791f7944317e4ef26690dc16c1382e8ce3380a9005cd0ce7a50cd44eb9f74d52c816ad89b8e2f746e9222835c522c2dc3aa711500f2b0a7cfba35de5247496b12c384502e66cf36a87b6c0564ed39f76456459000db7868498e661be20be7aee024ab6855a4961275d34d05d4469404c19e897a006226767abb3f6a8c51fcf136394a39bdde281cdeddc20d3923eddca95b1e4300da6d7ab153ff992f55138f3b1a9077cbdcf2b62fa6bea7a786a8b7600b37ec00988d799c798b8e32f1e962ab102aaf4f49a1eefd1f63d4f884cb01c5a49c3700399ed3cf02e70425f5dbddd1f86e83480d098feaa12a140bbc32f3396502040025fc7bf6f1ca0c2a60340fbc8270049d9135b01dab5eaaf309f97cf896ff2200afeac937bfb1fbc2a413b2dcfd2cbcd722cc2af43c18809b2903b82a6c48a40008248e28afd5b958348fb8f5b3041f425364e13ec3c9b544ffb4c6923982f3008224cbc6bcad6867055c2a7a9a3b7ccddfbe9b8bd5355c78f966033d7e963700311ceb66712322a33111009ef4d2125975f4e2017733c18772632040b96fe20096be27822ce17be41c28232519779e2e6e47da8b43c4cdb6e2581940c5c62f0044cc3f8926d6ec757193d4b436691234226f2cb733712db2e658181bcb22d800707e86b5e152843de19a548fbc257ebdfad84497441236deca2ae4cee376a400dae191d3c7060b42173ec34b8bd2768680edef34fc38272eb3162a6b850c25001a68a0ec9897351bd5a51f6cc3066f3c818d3fd8a28ecc1125c4efebae9c6f0013ff86d74d4945438fee117a46fe2d5a91f550f20ba0cabed14c133367a72600ee8f909be13232ed6abe40eadf38a54fd05786872821bed92f02335b81c09e00b679a2bdf6ec2ed9f9bdfa69c5f9f7bde0813b0b11e9b5050482be77290b48000e1ad3049e275a0f71dea59b49f128e51d487b12b653e61162f31fa41eaf07007e9ef298311cfb531f33a87bb0135a22851f812b620e85fa6de765fa13dfca000b04690797206075f91959b08c73d4282775d55cd62e8ad5fefe3c5f839fa5007e62a24814c99f186129e2abbc6b91009fdde1f259b57d4085aae1f377917d002b93124cb13c5e6cf9a4ca1557e8f3d92b61687ae68a7e42cf5db07435adf100aa0009ff0fd9f5b06527a8a96b4e89e948dc727d04523c0adcb04a8841818700345087ea0ad0d3c16ec04dab1a5c218045ce6ec365503c1ddedd593c99619d0022c31726812af4a82c05551b7b0be8bfa955352b815f93d802e2dd5368039800e35b6187329f82f1b0f3638adb6a0737dc8e549531f2c15d7eea982faedea500e79fe7c52c27a13e46cd24236794661b1b60a53b4f1ce3fdb68b5f9980019f005983ee41437efd0c2a07822478069681d59441a0a663bb48c8acb08178aa4e00f127198d04bbd4c133fde2f99575d5fe6f0ad444dbca51cd2e1234c3b169eb00b0f548ad10c4d82cf89ff9e65d38b145dee0a0d89cef1227de4f0e62e77b35006a8417e80494c91dbc6b0653869e2e345a4bfc3d4a5f5782bf4e9d354b4b9d00e208744c78925e60daa1011515e722344b6e2940f782d62f056b548ccc36c300c14a84c2422008366d9adb252c88b604c285564475d08357ce067f0314857e006a612ece84d4063c959467129b59e17b87eb92c74b45d78141a4f4779d058300136c9f5817b374263a17bbc9a181b08729b1f14bac40290d816d914d6f1f9600c60dee64f6a734a889423e428053798f7c0f5856ee39db8b2ec3d261afe6ad0044fbf9b570bef4f922d636df5439cfad01c134588a086cddc845b929d7781000526b8d54b983b68dea1e74979d3eac4b42c24630610ba550c494da393710c6004498e763c4dbe3c4050ba242ded46648e405c18c8b5d5e99ca36352a3d55130075e7a73c194e07dbadfd79b6fe2a3f7f7d9e0b4d674f2e88bc926dfd06d82200a1061e39e34897c06e62dcd6eb40d7a04096383bf7b5e589d8da8d1e56adda00e58697a5a3e6c887a9ddb0bb96cc760bf4f352b4270b7d008b3fc9d1b131ed00394b350e5887dec5244826e40a16a7850e134f0bbc55fd8cecabe96e4f14cf008c644fe2d6aabb63f08aa347a4bfa3bfdcb7e806936d40dbd67206df77bb3b0044d008589bc32630cc2451392d25e2b0ed8f477ba92d08a1c3bf5bb4f118d30042ef4c5b85cb45e8989683b16b178154c533e49c1313470befb789e792ba9e0051c9cc4dc73ebbf89b53db81d0767cb3ad8e28b741ca98e487b8ca00330d3500beb8ae1b23dc871cce06f53dd154f74c0e74c7ee53e88a3fa668c2633c3c4800130a3b759cd31331c6a5e6d395f4f32a7a1722811c21e1aab1dfafb6d6eb3b0078fb9325133177ba58cbd87de547df21a8ec383ce1286edcdd389cd05fce4500c1ac56d57b9f848bdb17d5a9302fb22b0db1c2cecd2850cd2b76b95eace87b00997d2c4c696e42e8b528765a0d416931406652dcbc47be953b7fdcb8d8c6a400c5236d2d4f189772c8b444750ec09f6b027641ef1a12d7cc10840e9a46103000d0c122ed4553100ddfb7b3a0a528b3bed4459aec251a8da26c96096c2b67cd00a2c199d2b5c094748d66a78b9f2c70e7b13d18e4eaa9a222bb888cc849795a00ef6e27310d18e4b81eb9b06aa6329487f08c43ccdd31103b653c590667da03001e837e69f82364e449feb66890ce84abd35f37070ead8a5a589d3dd4e62726008890677076e012718fac836f2fb4eba0a097968d41489a46c555e189fd055d00dd9063df58de9a90222a04cdf3e6769e64bcbfa5ba5f38eb6588afcb479abb007ffaf642617c60bf8b1f63152c68a615daa716df00dfbec990cbcc944a1d00001da931e1eaeff5ec88a047c8cd1739eb238c42fdb73c2922a1b2e80547da2300013278dfc03e681ca4b036e3ed97ec3425e440949baf964749e294521e13bf00495c09ebb0b92e43a50d16e849a052cdbec409ec346eaec9280fa25e37130100c8d4a7723292612e16b422460a1b5c0ff7749ae7f46664b8eba22b360ea20800621c7ccf54bd0c0db584bb6e61c4c4c4365bc69a9ff0b263e585d01f27a00a008035052e30080ba0a5b52df638ae8e27efac5118e6e9f53d04791ec5626a8400f1d1cf5c5315b3ae50efaa07318af2bedff42bd6908c4d56617a41c757301d00bac07538795eb1e2ecb38eb8fd6abc3433c9fc48011994e98bd7f64b032e16008334b75e0a066c6e4e37843c82208ed812b2b4612cb4a044ae7b324cb083f4005cd7e6cc9f379e23ccaf7255312947c4f43a5890bb969871de54d2d8a3502d0020747e886ad316c6dfadbf4ac10a03e22f324ac04c771af7a174d2e33ed501005b2b8c98506ef21586b7875e4a11292d4b129c9ccd1abf275e1598ce9b91cc002e46f52f6d08fb3a261caa35f656dc04f0d2a1c855a7a5441bb41cb83837eb00ac8650dcb726a70cd6c11628ddb619255830e6d9e3f4749ef015cf1cd7846f00c3db9ebfc365cf2c58602dda91687287eea7f58ded08c716c2b04217e908b4004ba25f26e2ad9f5769e9845b53404b3db8e59310e9bda51b2442c645b5de3200ebcb403480caba64fa5d958ca5f26291723c378c6b657d90f9dcf6b818818100ece035b3c06e7d95fa1027e16a28944e2572cae98844d14813214f6a4cd699005b962642d88a922690b4295abc48052e215fe2589fcd1709217addee01aa19006d75d75b206cf933d25cd939e98c175d00ce53f11ed86416235e374a7399610020f8111cf2ae65b150591c6725b700dfffdd08938b8ab56270c248b7c31768002889ce2241c53fbab7e831e28603da36a623d2e0ed5dcab56ea5a7058f8ed400b74302ed9fc146dc0a0372a7f92f59c7931c0b24b3cd3d01b1578cdb61e16200869647d4c137cb3ee2ea3f2f2ac0c4000cae375192d51281f211ce4a30985200e8d098cd0f7801dce4edbd2458d62db5b802786d837c3b0ddf02ed872640c1004a23fccd8e3201fd1e0fbbdd18dc7755924f6f97821105bc0e15a75da7b25d00d71b6a26573f4fd8a0c50fdef4bd979c880ac3efa6e50e61f594ea098f563200e4be2b6911c2bb42dbbfdc531cf0328631c1aa3b246b53fb01f9c913261d8f0035010917f6a5233ed8fd1ca57949b2a091bef8aed34353fbd04ef1e307110500a15ecace38ead94c8057520f5191c90fb38ad636d537752b4d84779fc140dc00d6aff9cd4a49a1848b06ad9df7f5fb07e4d9d3a584cf7514b497eb8ae8247900714fcec014c50d00e67f2509047c892a16d93375fa3c9a59ea83a40d53c13d004fd2ab328ac54bd08a6fd8ef976d35ef234e8e4e96cdff419eb67b0205935c0041a1e9f0b9aa579ed8e3042b4917d7e2834e64cb3981adfbec0020af60ed3000e88e27c4d4f65b9e2fb2bf9455d2aa4fd3039bda6b9bcd518adbb99ecd643a00e16b5723316efa17a1e75b9358b7ee907e914685515cb58ebcead7fb23024e004e5cbb14315d1fc3bcb3b1974923a1f86ebae9b2b8674bebd44e7e4c8427fc00bb7dd82098b82e2072d35b8e4e52989454fd9fc69dc34e1ffee4071b1f9dd300caa07e99975610724c1e695ba317ffd8dad9c249d731002b41a8639993d5a000f1171f80d3709596702ee7f5c5395338768a59ee13ea63ab0c5d74d7c7276200c28e438564664e5fc6b39b306c0048a6d8faf4f1d1c338dd81b75c03ef17a00072666767a803b086e2913ac528e082293c5dbdb2abd1645186f5fb2f43144f00e393e577dc8e21ddec8edbdd4b16aeaefe0a5c456632db23750e8604bfe9aa00eab2fae532beb02a6e0570a2ddc76ce6ce31f630ad70a48b89e32984bacf710014e0882225b9c2ab6a3519d8952573de01b35c884c88cc1964a509334e9dbb00b5058a75f3d08608cf5a7e9f9fb6b0aeb7fa8d71c2e48f90fb28d5045fc81b0096513a60e831fdb7dc7bd3d18d65581e8e5d4f5599f1ac05c80f3aaa53484000f511c729de8fd5b719fa935498dfadfdf433c5e565ac28d3775c3d747474a200c196c2f9deead94edb1e9eac5ca08d2274024a07856a301554fe6311d402250090a0cb1d5a050c9dc9fbe3a0607b49a3c8870197921f7be4949bfb65bab49d0040997a659a024bb151085498adb8181b07785a172bfb29a31831d09930ab7d00c34a93b34e0594df143b9eb33003f8e8cbd80c18980b8aaad14ca8a038548b000a28373fec8705707165365503fd2c26120ebcf22ca18be305f51cffba249600b3c6d4d7cb50768d80b688886d016ac22315c48786241adb47b630869c3c66004785af1b2fc65ebc4da3624a0edbf0ecb506500b68c82dc738dbc906a9eca7009363af91500d6a1a3ff21d58ac3d3b943088aeebe9df948d55aa7602944196009a0f32745962c635a65d4ff5364ec22ad835e7a2bd2c6a4f7653770514818f0046edd59b17d4a14a17fa245faec6718f88d4520f32f7eabed22a5ab13666c200b151aa9ad083d33982dbe3972a5bb9279bb9994f680d584cf01266033f905c006fbc51450e6cbad77dd53f4ee05a099fddacd7743a775081fac6c131ac60af007bcf6ad3657e601a76660d00fb4c7d1b61fa313ebe47ef3a74a48030f9f29300c4cc21255acfcdd1683adc59e56e3db7754bc42a0e628c12d416c177c228ac0078a6eb92e3e3a2fc61c822131c9b3199c92bd53e4dd25ef524008f293fac63005f2e5a05642bae86c8ac0a2b9cb232e6c32a7e7a233c8682843a7d05547df900dd2bc1fdac8e177d1cfbf15c4dc56b00be2230cb1c3238e777974efadd45ac00a838d96703104c146d12413120b428a42ad8850e29791881981eec0d2b4642004e7c257ff9f4859646d1123e28d97b5f77564df540a6a6d83e0e011c67de530028e4fd31d023d9dbfa476a04fa220808ce5be05e5793234be73cbe92e71cbd0097975e70f4cbf4f7662354385be89b26b5aedb8a7c597020edf055c8995a3a006a3a40add11f5eae4e44f25a349c93985a27ca361195c6ba5c4c7fc6db3acc0012634d1efca17c3fc26b610881e5d384533a18b2446ddd61101533a3a82208008223469b654abe40883d582224375d9d1d3b57a170d5ec11709a39c702df6300b1d23e9450573e550286ca01e0344213bb3ce89527fc7083b0f3407d0f59ce004d2afcf41786e273046fae819cc2ecee204cec8b6d792651fe8720b8f1d1d6007025091a6a4ceea0f73d2bdc5686418bdc752cfb73784cdce8dcd43f5a90fd00cbe0488adf4404cc18d8ff75b4c0140a809c0ccd8e782dc7bb1a0c9964cb8d0079a8b485e7bc2c05518238a4bca186545b21884a2b2f2ac5e79ea3bb8cb56100004bfd3f9232bc8b013dac3d9e575b64a0b0d531fd69edad4c55cb1e34e2db0024da1e2e477b85b932924a4680a1e9c043bade3b2c348d7a6fbe411e4c7d2800da9ba6d6f4122cfee272f84db788e70333bca239ac36b5d7ec82ee91553054007ac4afc4635c6120eb4d6d292b5b1cbd4bb173ab060b7a45801abd9404e8aa00ac8178e66d7441877247241ad1b012dc030de31162a53ac6ea6f01a011c55d00f921028c9a130c79b0161770844a6592c1a91fab28b45d54098d30f67afdb7001ad48c2d5e24cad2f2ea6f08c9bc4b3a39b4f0d318f636285b126fcd6d6b9a0057ab6562876bb2f7834810204cf7c0ffb4f03c375ecbd893e7f3f5fbd3d692000137693b9a8e8ec39d97aab80acd697fce3e5798209b016a7717eddd7ddda2002dfb0c0e3919df414a057f18a8d04db82e9a98f23e848787bdec1205a719ba005a5b61060dba119bb773fbe17d9d4db912cdde61b05af195a22b2e7ce0004600b40b1fc5c574aadd5c98d4f7936b1b7f971822d5c3023def91c003a6ab0bc600ad94f98d90ac71db8594d5045dd2289057ff2ae9b05751289235d5a3862ac500c4a704a90481132673abdc6bdeefe5d10ada2dcab11f55d1cc6e346479b16c009bd4bc07d00273609b88e75aed9ad8af9004f11f05577b81675154f3d5408c0014ae69ee1fecc5636801f7976240dca346e6ce3cd468977e6898eba206660900d3b23676a7db2727adef087500571e06efe29fcfac176b6d8f043ea73663ce0050c7ab55e3873008e88e78669bcb2042c5cae12a13a89db3c3b9af42ad3b4f00d9e376d9a9b7e43f32e8ecd3a2a06f4da126c9ec09cbcb58952abaf607acb5009a2a9090a3fd753d7a25bcac67d278c6af7a1eaa0a6cdb22ad33eb755a57e50014bd0e1d05fec93d42f68edb69c8eb28ccb06277e9f512c065c15516cac6c700a531303e8ba3d26c5794eb06938f8b9bf114eaf1b8516f1a88e909f50c014300cb416fe2d91c16a048055d69e7c93291dc14f4a00ff5c346a1be1a4f8219c1005c76d6d780b056aae0da1bd9ca47ef096dc0ac5111159b200600f79c1e369a00075b4c452ef88f6b71ff1b8419939ca1210434cf825b2a051a6ee8b6e3175e006ceeb2160c68e36703ede04b3f40ddc64291fda9f73e915bcdd961f0448ee0003200280fd9288fb58ce4ea6ff5cf93fa27194d80e13c56d7cf7dad361f8c8a00b1064b466a8d03614388603160efdb25b18f9cc6df281074ba6477f8f001ca00ae7abe2a804431b22377e4c515bc545699da2b69f10b02259327309a8192f500bc782a4264808ad9804ceb376043e9b2dce4993f39cd0b192d9dae5eba642800aabb3273f863cec85261c488b61a958c4ce26387f3607fc616d261245017c3006f758b86a324567f26a1a5cd39fc9d860aaa7cfcc6e43c1900240b8238022600eb4b287748bebeba192df1ae0e813bd4b4988c3eeab0d07aeadb3b959dadbb000e39168146330e2b51f2c241811ea222d4ed2c4b2b3860c081dcdd035a753100fa02610c2d04172d88bb23f2e40d63e227d6cba80ffb37b42f0218fa8829f5003cca499d512dcfa26a2cc4ff568a7a674c8157056aa10cc57dca1a0b18ebb600143228fb6e380df6f596a7cfd0e69b8294769e2fef227f4db7a267aad7fbc300a27211a48083547bc4b555eaabba627ae2f220866203a5c198cb1babbb7b58000d9d399a4160b21545f9948db272bb41c04e00ba69e272f7acb62cbc94a314009a5c395473016ef36a0e24f9648e7a51b1c1238ca1ee4c5d40d253389af3aa0095349eba157aa8d59ab5cd666c2dd02d17ec01276fc8043b3ab293e3c85b5100a47bd9eb27003ba1aee044caa38713e47e3965d1a947469147f0c27cc69ba800810ee4885f822eaf6cd46558ef94bf3d3de600612c563c5fe78b9629cf8bf800050ca4ee48b90bd80edbc4c38477cdc9f8a629a2a5c4e8387df937038102db00021ee6dbc130d61b92b9ee6f8a7c8eb392e429ac9020e0a858c4b49e3c6dc300d7f5544e1aaff09a1a029f01bb65031a3cf4abbbee314479f5ddc6f7ab498f00918b833a2e00b44d890bcdc7156572927a48ee6cb4e5706e6340b4d1421f6f0092e0fb6a008dfdf62fbef93b8782bf04168916d2579bf448cdffff2cd11d7c00e051718a567d672088a9abb9f197253fada5c3914953d79620ca43c963f44400c97a3ac56eefdc2605eb3cc9af30e91163304b14c15f1a6bdeca16b85611ab00bb94f8ca175c68a4977b61c36dc4db7cd7762d3324c77ae08029783419560e009bc6e23d6d8e38fb1ae10b384a46f9a750fefee1596e9588157106906ceecf00167fcacfeee6e3b9d7c8c6daff4308e6aa0ea0c88639904bb6af52e7484a2f00c69e638cf5cf2e72321a852071346b905cda3a12c978a7b13c483887d9047800d4984df8d427f08fa1a7963fe9da9c4d0ec3964de4b362a5e7ed1f5b8d0df400b00f5903cb14caa8169d1f37b5fd385cdb6d419ece2759380f7b922a1d544300b1ea3424993881d50dd37fbc65e05e1177c462303e386ede828d88cc226b1400be484bd6916143edf06995ae2e18158a4b3ea2bad0e645cb0daf0527db699f00a18fb13a40de4723fae4a6c8a256013d494183d09e1ed78359c8076b35aabc00d3799975ce7f338f7df3dde1613afe7f89373fb0f4d77694ceccd03712cc45006e5805adb4c832004271f993198a27bd776287ff7c6f5fa2b2d3ad26769173006c9087561dd9ad7e46dd8a2422911340e16746ba84b27004b63066fb013aca00d260108d065a3f57185a692d9838d7caac2c014426734e4ba39855d8308fac005cc2d2d2def6ce942279a43ff8cdcce624b0f335b234ffcfe828b5fe5500d70023395f9d21eed8ab60c8ee28615ae88b26b9d96dc303ae46c6987596af06ed00373e99c7630195e63953445cd4cd49707a23aafa1734c9079e7461538131a500f841272a0b79fa2e41a9187de21262195102eef65f37ec0ceda9427aeafc8e00131443ac3cad5186b4261825d69209d0bd8aa145176fd00d812f57400ee28e0065471f08f817bce60b88cef3ec9b485e5f385fc9765d518bde44445932083a00f01b5a47f187f20213d7effb94b23c8386fec8ac5d1f2c115c193575acc98c00d04200841645b4f64f8d1bd85f21b2553dc642517181fd270914e3124b43c50009a1d618c976c601ff86c952a85ded903766d7d169ef32d9575090b3ee910f00d82e356f33423de310fac545f293d5c41b985f77031d1b50cae7fb5cfacf2300751decff3ed5766203a07f04a4ad8247e978b91eaa22b2737069db0a803f2900d78dedf771c2489d5cbcd8c5c70e70dcc983dd5150a38169c0f6256461939b00d5dbea9e42c328ff75554a5c9fe66e5a32056d0843207192e66cfb1d6eaa3200f14fc1963e7ae96973bedfcefb4a8d5acfaf25e8e84cb19fb3afeb72238dd000a41845df74c39e4268bacb8ab7a878ffa896854a908dbc3cb9bb0c4f706c7300fb2abbbdf740786e34b74aa9231779951e5edeb31faa8e292dc0f3b3e0468500b2bcd46938e3d9ee16bc470a1e2cbef46a827f70a0000f3f3e316e20da6c47000d31c485ad09409491b4e0195d9cdf76542a020b191700aca6bee119835997003c5b944a61f6e19bf3a3423e76d44cd0ccc62d39308fe0fc88a747fcdb03670071c29407780649efbbf7a585bc6092eef9c3c5e9485b427e412a916007487f00c0720083da591a311479a981cedd688532cc550cf47134d902bfdd17ecd55a003c33221ced070998137ab906704b4ab5f224b429297de6d390ec3cf15210d900bf7c4814e791d16f4d76246453fbe90e71e4b08a8c3b2ea6696d973971d0fc00dd7f1f9a628366f600075f762294cce29119b4b2a2b558dc2d0db0511ef88a00cb1a715d77e3a0d2b894d44d73ce668dc59e472eaa015df999bc7c43af6063007f3457d0f2bb2c20c5382beda5ee46e5f08aa41965c97b5a08aaa5f12fb5dd002ee17632c66f513d2a7a87b40357f53f885014d0c013b1d36a7ce809b7c2db000e125702e573338628b2d541b0cdd90de611cae00371145a9ac778b82ee0e9008ee294ba70cb3cbda540d116461eda58e5a2c86173f8ca024520f8b04e3852002a3abc266cb34c3f0f92a1432f10e649c351dc8ce4a8983ca23f7c8da40b4600f93d848d0ca6e8378f152deaeac0330acf7d3ceebc825dba843c0849dc553000175fdd2d3fe0df2a68b1989432ec078745124e43f2e7ce82896c9041e9db86007bfecfc59f39cb90dc38de8a2cbf745252e1529b08be8bf5e89434e75402c500a90c6df0869c4718743d3cb8e1718a7dfab881b91e30fa4c3018352331979100544752ee51752713323031283eda465e7ae8ee1cc111833126e86b1256e23d00a08bbf6e910e8a2f041cbc71b6a00061cca8c045894a119195f8adea6abd3800de337aeb0e427ca9b690d77bfd2f56643c1fdfb5a642823fb5120ce74b4c8400213e87507b233451c1d719eaaf3548888437bfa7a2bbcaef6a76d3326ebb6600fbae6a40fbfcc943d87d474174a5093a624d6db373dfe3d153f6e7e714caf200e8e2850ff6f945a8d23cd7d41cb82a0d0ad6e0909ba7448014fecc4f6fdd2f00df01f48efd09e01e48604fd737deec71f5ca5d0289bcf10ed67be5cbcee0b8000258dc7f6474c41968b1b1e0dcb666a73c576306cac40e5ec64638dc6d984f00fb0819c797615f20c97b28d858aa44839fa0ff8c2ef6ea394973911faa8b55002e0d1fe7b1b92ded42ca51d465e7417c1daca06718f57b10c5e46b75b57f4b0032911642b0c65580cfebd14a73c2a03a1df7c60e9c28bb00465ab27a5b7ee6001ae1c3ff709ef11ad2773e30c5f5e41665e180f015515b90dd499da27a1adf00136dcd1c1db73c9723ad0b5f228d485118496e8eb615d4338dcca8d5917c6c0007d16215f90a9b70808a456f52ea3ef3cea921d3e1f87ece76ef15a5ca0bd900e291aa17996429108551da461d93ad346f6b0c293ea2abda3871d91ef4bf6b004696c1b6f44a92f69805dd561fde2589f3dae1024c3788f65ab7f7848bd3de00d53bc8cca7ad7d24a6c88803b5c82f7be78db8da021afec58512cd690e02c900740ab11febffc08c1fecf4f2b92c70047cfd4c8707e17678eccba3e7efb7ad00243085223f346609cef37331c06feb9fb1cf449baa0a659d0b979c19693d0a00de7eae74c71d78d5cd1b0c7e0b63ea7fb87a5c6ce35904c82c3c1add53a79c000935a6fbe3e7cc9d1fdd34efbec9f4a78d7963e08f6664136450b36f22198b00a343f7ca572c78fbb88a29b1167d506aad70d4a0e52e1050aac1ec93a5601d000e1ee19aad765f9d0ba4bc04e5f296e791ea36ebbff54d141c4b1cca718140008d592dda4647d747739f1d3b4ae9e22a489e2cebebdf336239b96e07414b1700766e678cda8881b1bf82052f9f40fce0d5a30fbb487d543ffd909bc7525cab00bfcee9c20d1d51d98770b20c77df78074f7d2a3d7b1a439b5a01aa46ec6d9200662ac77d7afbba02062d2db11638776dd35b81ce0016876efffadea325f38e00823977490131a22f14d7eb62027c5411ad05a7110eb09f762c62134ff8f76c00179387baa2d2e91af1adbac38cfd098b5d58ca5c5de02caa0d5c7ac3edf3e500602421adf1d090071af0cc59e953d6998bfd005330f3c4c0c8986bea53d12f00cc7ff8e55a3fb792c27dd865d865b7de86d578f1b729e95e09312c6061fa8b008c5d48d23fac02f7e856abbeccc2827104bec2f631ff792f1de1427fe90daf004fed42e4ac240558a155ee187efe88ceb18a74bb65334ade3070676c6cbedb00ba60264702343fc691fdd0f9a4b51770884be565e168b152f3cfac601283b100d38184ed8b893776721e07139d1b1202ba425854627b68294571c71f405cf1003e31eff32f23553424b02e13d6040893929a5c09843f6e2535c119973f830100c398e9ad1bd01c2c46819f32d3300902229a95704dc44c30858defb70c177700d316396a69057c20101c1bf9fd8eb629230bcd75b0a069ba9ca921fbb8771500f08542e9d45058391ad7d2b1e5611b4094e13faeaa51fcc5f14c263ffc8c7b00674affc8fb0fd8d439579c8c908ad0c0b3d79c793612752dd7f1acf489c6a1008191b8c3d0848f80dfac2eeeb4c02aa3b80dd83da7b617bd030b4f25b528620036dd1117eda260f37c5327236a1fa73588d04296aca039df66bb1cd1c7554300d01780207c818fb7dd59749dd5dabc79654197813d0c31865978c3727afe450064ff10230294a620d16358b81ad5871f26e87a4efaae8f31ce2fcd31297db9005d691bdcf13a8dd0704a2021f9f4f7d2d062631c8b5bc83e29ff3be75b29bd00a05b4b5a3ebae6c9b6680fe7f49130d40db8d16872c0cc1799a711a64c323e00d7512ee929db23909a57d6a7512583a222f688d8971ce447943a024168b53000c2621957cd875bdfc0da980a77a025c6b493bf8171be307ff621bd782845a0008fb8c6d0e63c3af6d5f3a40bfeda2cf9b16002cf480258d34e9e72e2530ff8002933c4e31c3c93bde11faa1cd478c907941e69e2ad9191b1e49cb498935b1b0032080d930b2539459117a5402e9532358f5ec0eeb6cb65bb0848818d43e7aa0028dffa075d8e7d62daed3b517d90787bcffeea3c2d7631be60ea91a0856a8f00d533ecf1896e0a8fd0f75520132f6515fb97d68dbe1bcd83157dc85955f5b3005bbcdf3f784aeb22799fa64fe2449304348117da122b7fbab608cac6c062d100f61567798218f3057b6c838adf162585fad4e8c6398857c47ecc70ba99d6ca00acb0632a0d8fb1964a5418b940064dc02a84055b896b4e6b3a072913a6324900dee3d8965ba811d5b3d7c87f49b028f1df14797c115255c099b85e1792fb5c0060db20a6e59a184443361f6f594d37d573e0a35ba25a48264d94363287124c00112402006e95008d51da09c002ef036613515b8cc2648e1234c15da0f132fa0005b6300f780647b56efd729e0c2fc445519f4c438f97abee229eae1070b60d00ca56cc2003fbb7843b041706b935deebdf25e2336e773a1e967f94e3b83fe300602512de10e113445cf2f3cc3ded46082200af01d2b1a7aa3db684b363529600d1d207719445633e9e7ad16be1c6b3bd06058edcc6280a50941c3230683a6c009840229e0f215036d9fdb7a028ee03f0ea37d5f7b31ec36f8a6bbd83d6f27600360d47e659622935e94c6e54795d5d4bfaedf49b25f4c4796091410b1a53a700b3db4ca268e83cf28920d00c099814663d3cccc98ada527fc0682c4ffe4bc5009d7dd8103e638f1e441d9e33cd365735b7b3e53a219974602decf9856b311a0078e82c1a8e9c69896fc6e2560c82f6d5815024c3543da35c610cca9a57a82c003e033848867e9867ed54b565df8d95c9f99ce0598cd1a6fa811075533e723600e7058768faa65a8c145805c2d4bf4a7f85d75233452a5dcbfd0807270d3b0100aaac1cf0fd697508a759ec9785c60c7d81d2d3840cae1c9da3c2b3687da89f007527e575d6db61179df123189c3a45638d07b471d0f777ea597f41ad116af400baa72c9557503abc7b215be2f142b4f5ce346e93c240ca63a0442e9560904c00c6aede584dc77bcee83bad72dece2d5626c1be0e4372fb0ad8b007780c3df200f98dd69336c841e1839a44afe9956fab9f133e1bde70c170bd5fe3b8325c4e001c41e1610c830bd0fb66aae759ec5d097fe47019a8d24bfa06f1c6e33def6c0051405df9d4693fc104c8ffc32e84382aa051fa7c6100e3317c0489b66f0016006fdf5ddea43109322c4fcbb9a6a7974e397cca14bdf4ed60496a47a4a7c856001b7eb4f2562ef832a8c97a5ff2fe3dcb03fbf8e5d2fef7f07d0ab6b9cbd85b00da410ec43508f0834f3dd149c995597f5762c3b75603847004c3bdd26750750025aa4d91377a06cadf455bc19c781b4f9117c017a6fea29dc4c3cf45609d4e00daa289616314281e2e8fdc26bf75a6b58aeb1e062afb684e2757991aa45660006969d1736afb3a35835b57c91b52f6f0763aadc9d630d17a2b0b9f8d73a37e00becbcaaebf73c03d9cf1cfeacf1d98e746cb37b834991a4f135dc3a7ab1d3200c9a3cf6bea91e244301047c1160744caae18b709661faf9517e9910fd4f41200f977b311f01812d8354a7f1012cb453fd380b7b9f2a7ac82cf8c2bfe7efdec00d5c215b21911cb887d3578f66b94a5c0a383ec3561e36e35f9ef066e3f459f009ec8968aa4585f4791f47f0fea9eea5705055912b11321240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","kzg_commitment":"0x811064befbab0b21851ada32c098fcbcc4d9f5f175afc9902899bc6510494e4afd473fceab15eda2391e898bb6327df5","kzg_proof":"0x86006bc8b7b22d607cf8e6a8bde4821d3df1e4935b94b524380bf4506fa0215e9e4eb691afdb998b8d8339047ed167d7","signed_block_header":{"message":{"slot":"7422094","proposer_index":"129686","parent_root":"0x811c9952feff5a7c8325635f1729e31ebca866ed88a53aa5f26cd11d4b9788a0","state_root":"0x0bd0bd3f512e5f64d36170790010238168bf0dfcdc22fc438fcf12e7675b33ae","body_root":"0x71d8c523acce371dfce3ce7bc2897e62fcd72eafa2870be5ce6c08b94d444fe3"},"signature":"0x8ed9b52cc7323bd7d16e7685c4e5608fdc3144fd053bab8d2cc6cd19048b0214d2aeaa541dc4221e4587d9ef9830ae960b5d417951fb79d86fea3bfe31a9fa06a83af01ed7e579896afc3ba14e3be41b7934ddd1886a79cb23cd1a9031cc7668"},"kzg_commitment_inclusion_proof":["0x0000000000000000000000000000000000000000000000000000000000000000","0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","0x5d607877b46177ee9c0d47f1bf08ed4811d2c8afa0c6959e4eac7e2a429661f1","0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c","0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c","0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30","0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1","0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c","0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193","0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1","0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b","0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220","0x0500000000000000000000000000000000000000000000000000000000000000","0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535","0x56bd14bfdc37d27695b4efdf7f9851efa0e51272eb0fb3a5934f0d9f52ab0d5e","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0xcf8646fca4890f4bec369e0f281f4c3199f294b2f3b3812a4a2f76639c93742b"]}]} diff --git a/op-service/eth/testdata/eth_v1_beacon_genesis_goerli.json b/op-service/eth/testdata/eth_v1_beacon_genesis_goerli.json new file mode 100644 index 000000000000..a8ba0047cddd --- /dev/null +++ b/op-service/eth/testdata/eth_v1_beacon_genesis_goerli.json @@ -0,0 +1 @@ +{"data":{"genesis_time":"1606824023","genesis_validators_root":"0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95","genesis_fork_version":"0x00000000"}} \ No newline at end of file diff --git a/op-service/eth/testdata/eth_v1_config_spec_goerli.json b/op-service/eth/testdata/eth_v1_config_spec_goerli.json new file mode 100644 index 000000000000..3b974f16e1db --- /dev/null +++ b/op-service/eth/testdata/eth_v1_config_spec_goerli.json @@ -0,0 +1 @@ +{"data":{"CONFIG_NAME":"mainnet","PRESET_BASE":"mainnet","TERMINAL_TOTAL_DIFFICULTY":"58750000000000000000000","TERMINAL_BLOCK_HASH":"0x0000000000000000000000000000000000000000000000000000000000000000","TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH":"18446744073709551615","SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY":"128","MIN_GENESIS_ACTIVE_VALIDATOR_COUNT":"16384","MIN_GENESIS_TIME":"1606824000","GENESIS_FORK_VERSION":"0x00000000","GENESIS_DELAY":"604800","ALTAIR_FORK_VERSION":"0x01000000","ALTAIR_FORK_EPOCH":"74240","BELLATRIX_FORK_VERSION":"0x02000000","BELLATRIX_FORK_EPOCH":"144896","CAPELLA_FORK_VERSION":"0x03000000","CAPELLA_FORK_EPOCH":"194048","SECONDS_PER_SLOT":"12","SECONDS_PER_ETH1_BLOCK":"14","MIN_VALIDATOR_WITHDRAWABILITY_DELAY":"256","SHARD_COMMITTEE_PERIOD":"256","ETH1_FOLLOW_DISTANCE":"2048","SUBNETS_PER_NODE":"2","INACTIVITY_SCORE_BIAS":"4","INACTIVITY_SCORE_RECOVERY_RATE":"16","EJECTION_BALANCE":"16000000000","MIN_PER_EPOCH_CHURN_LIMIT":"4","CHURN_LIMIT_QUOTIENT":"65536","PROPOSER_SCORE_BOOST":"40","DEPOSIT_CHAIN_ID":"1","DEPOSIT_NETWORK_ID":"1","DEPOSIT_CONTRACT_ADDRESS":"0x00000000219ab540356cbb839cbe05303d7705fa","MAX_COMMITTEES_PER_SLOT":"64","TARGET_COMMITTEE_SIZE":"128","MAX_VALIDATORS_PER_COMMITTEE":"2048","SHUFFLE_ROUND_COUNT":"90","HYSTERESIS_QUOTIENT":"4","HYSTERESIS_DOWNWARD_MULTIPLIER":"1","HYSTERESIS_UPWARD_MULTIPLIER":"5","SAFE_SLOTS_TO_UPDATE_JUSTIFIED":"8","MIN_DEPOSIT_AMOUNT":"1000000000","MAX_EFFECTIVE_BALANCE":"32000000000","EFFECTIVE_BALANCE_INCREMENT":"1000000000","MIN_ATTESTATION_INCLUSION_DELAY":"1","SLOTS_PER_EPOCH":"32","MIN_SEED_LOOKAHEAD":"1","MAX_SEED_LOOKAHEAD":"4","EPOCHS_PER_ETH1_VOTING_PERIOD":"64","SLOTS_PER_HISTORICAL_ROOT":"8192","MIN_EPOCHS_TO_INACTIVITY_PENALTY":"4","EPOCHS_PER_HISTORICAL_VECTOR":"65536","EPOCHS_PER_SLASHINGS_VECTOR":"8192","HISTORICAL_ROOTS_LIMIT":"16777216","VALIDATOR_REGISTRY_LIMIT":"1099511627776","BASE_REWARD_FACTOR":"64","WHISTLEBLOWER_REWARD_QUOTIENT":"512","PROPOSER_REWARD_QUOTIENT":"8","INACTIVITY_PENALTY_QUOTIENT":"67108864","MIN_SLASHING_PENALTY_QUOTIENT":"128","PROPORTIONAL_SLASHING_MULTIPLIER":"1","MAX_PROPOSER_SLASHINGS":"16","MAX_ATTESTER_SLASHINGS":"2","MAX_ATTESTATIONS":"128","MAX_DEPOSITS":"16","MAX_VOLUNTARY_EXITS":"16","INACTIVITY_PENALTY_QUOTIENT_ALTAIR":"50331648","MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR":"64","PROPORTIONAL_SLASHING_MULTIPLIER_ALTAIR":"2","SYNC_COMMITTEE_SIZE":"512","EPOCHS_PER_SYNC_COMMITTEE_PERIOD":"256","MIN_SYNC_COMMITTEE_PARTICIPANTS":"1","INACTIVITY_PENALTY_QUOTIENT_BELLATRIX":"16777216","MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX":"32","PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX":"3","MAX_BYTES_PER_TRANSACTION":"1073741824","MAX_TRANSACTIONS_PER_PAYLOAD":"1048576","BYTES_PER_LOGS_BLOOM":"256","MAX_EXTRA_DATA_BYTES":"32","MAX_BLS_TO_EXECUTION_CHANGES":"16","MAX_WITHDRAWALS_PER_PAYLOAD":"16","MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP":"16384","DOMAIN_DEPOSIT":"0x03000000","DOMAIN_SELECTION_PROOF":"0x05000000","SYNC_COMMITTEE_SUBNET_COUNT":"4","DOMAIN_AGGREGATE_AND_PROOF":"0x06000000","TARGET_AGGREGATORS_PER_COMMITTEE":"16","BLS_WITHDRAWAL_PREFIX":"0x00","DOMAIN_SYNC_COMMITTEE":"0x07000000","DOMAIN_BEACON_PROPOSER":"0x00000000","DOMAIN_BEACON_ATTESTER":"0x01000000","DOMAIN_VOLUNTARY_EXIT":"0x04000000","DOMAIN_RANDAO":"0x02000000","DOMAIN_APPLICATION_MASK":"0x00000001","DOMAIN_CONTRIBUTION_AND_PROOF":"0x09000000","TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE":"16","DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF":"0x08000000"}} \ No newline at end of file diff --git a/op-service/eth/types.go b/op-service/eth/types.go index f3bdf8be9df4..58d16c3cdd22 100644 --- a/op-service/eth/types.go +++ b/op-service/eth/types.go @@ -2,9 +2,13 @@ package eth import ( "bytes" + "encoding/binary" + "errors" "fmt" + "math" "math/big" "reflect" + "strconv" "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" @@ -22,6 +26,8 @@ const ( InvalidPayloadAttributes ErrorCode = -38003 // Payload attributes are invalid / inconsistent. ) +var ErrBedrockScalarPaddingNotEmpty = errors.New("version 0 scalar value has non-empty padding") + // InputError distinguishes an user-input error from regular rpc errors, // to help the (Engine) API user divert from accidental input mistakes. type InputError struct { @@ -68,6 +74,30 @@ func (b Bytes32) TerminalString() string { return fmt.Sprintf("%x..%x", b[:3], b[29:]) } +type Bytes96 [96]byte + +func (b *Bytes96) UnmarshalJSON(text []byte) error { + return hexutil.UnmarshalFixedJSON(reflect.TypeOf(b), text, b[:]) +} + +func (b *Bytes96) UnmarshalText(text []byte) error { + return hexutil.UnmarshalFixedText("Bytes96", text, b[:]) +} + +func (b Bytes96) MarshalText() ([]byte, error) { + return hexutil.Bytes(b[:]).MarshalText() +} + +func (b Bytes96) String() string { + return hexutil.Encode(b[:]) +} + +// TerminalString implements log.TerminalStringer, formatting a string for console +// output during logging. +func (b Bytes96) TerminalString() string { + return fmt.Sprintf("%x..%x", b[:3], b[93:]) +} + type Bytes256 [256]byte func (b *Bytes256) UnmarshalJSON(text []byte) error { @@ -118,14 +148,21 @@ func (b BytesMax32) String() string { return hexutil.Encode(b) } -type Uint256Quantity = uint256.Int +type Uint256Quantity = hexutil.U256 type Data = hexutil.Bytes -type PayloadID = engine.PayloadID +type ( + PayloadID = engine.PayloadID + PayloadInfo struct { + ID PayloadID + Timestamp uint64 + } +) type ExecutionPayloadEnvelope struct { - ExecutionPayload *ExecutionPayload `json:"executionPayload"` + ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot,omitempty"` + ExecutionPayload *ExecutionPayload `json:"executionPayload"` } type ExecutionPayload struct { @@ -142,11 +179,15 @@ type ExecutionPayload struct { ExtraData BytesMax32 `json:"extraData"` BaseFeePerGas Uint256Quantity `json:"baseFeePerGas"` BlockHash common.Hash `json:"blockHash"` - // nil if not present, pre-shanghai - Withdrawals *types.Withdrawals `json:"withdrawals,omitempty"` // Array of transaction objects, each object is a byte list (DATA) representing // TransactionType || TransactionPayload or LegacyTransaction as defined in EIP-2718 Transactions []Data `json:"transactions"` + // Nil if not present (Bedrock) + Withdrawals *types.Withdrawals `json:"withdrawals,omitempty"` + // Nil if not present (Bedrock, Canyon, Delta) + BlobGasUsed *Uint64Quantity `json:"blobGasUsed,omitempty"` + // Nil if not present (Bedrock, Canyon, Delta) + ExcessBlobGas *Uint64Quantity `json:"excessBlobGas,omitempty"` } func (payload *ExecutionPayload) ID() BlockID { @@ -173,27 +214,30 @@ func (payload *ExecutionPayload) CanyonBlock() bool { } // CheckBlockHash recomputes the block hash and returns if the embedded block hash matches. -func (payload *ExecutionPayload) CheckBlockHash() (actual common.Hash, ok bool) { +func (envelope *ExecutionPayloadEnvelope) CheckBlockHash() (actual common.Hash, ok bool) { + payload := envelope.ExecutionPayload + hasher := trie.NewStackTrie(nil) txHash := types.DeriveSha(rawTransactions(payload.Transactions), hasher) header := types.Header{ - ParentHash: payload.ParentHash, - UncleHash: types.EmptyUncleHash, - Coinbase: payload.FeeRecipient, - Root: common.Hash(payload.StateRoot), - TxHash: txHash, - ReceiptHash: common.Hash(payload.ReceiptsRoot), - Bloom: types.Bloom(payload.LogsBloom), - Difficulty: common.Big0, // zeroed, proof-of-work legacy - Number: big.NewInt(int64(payload.BlockNumber)), - GasLimit: uint64(payload.GasLimit), - GasUsed: uint64(payload.GasUsed), - Time: uint64(payload.Timestamp), - Extra: payload.ExtraData, - MixDigest: common.Hash(payload.PrevRandao), - Nonce: types.BlockNonce{}, // zeroed, proof-of-work legacy - BaseFee: payload.BaseFeePerGas.ToBig(), + ParentHash: payload.ParentHash, + UncleHash: types.EmptyUncleHash, + Coinbase: payload.FeeRecipient, + Root: common.Hash(payload.StateRoot), + TxHash: txHash, + ReceiptHash: common.Hash(payload.ReceiptsRoot), + Bloom: types.Bloom(payload.LogsBloom), + Difficulty: common.Big0, // zeroed, proof-of-work legacy + Number: big.NewInt(int64(payload.BlockNumber)), + GasLimit: uint64(payload.GasLimit), + GasUsed: uint64(payload.GasUsed), + Time: uint64(payload.Timestamp), + Extra: payload.ExtraData, + MixDigest: common.Hash(payload.PrevRandao), + Nonce: types.BlockNonce{}, // zeroed, proof-of-work legacy + BaseFee: (*uint256.Int)(&payload.BaseFeePerGas).ToBig(), + ParentBeaconRoot: envelope.ParentBeaconBlockRoot, } if payload.CanyonBlock() { @@ -231,9 +275,11 @@ func BlockAsPayload(bl *types.Block, canyonForkTime *uint64) (*ExecutionPayload, GasUsed: Uint64Quantity(bl.GasUsed()), Timestamp: Uint64Quantity(bl.Time()), ExtraData: bl.Extra(), - BaseFeePerGas: *baseFee, + BaseFeePerGas: Uint256Quantity(*baseFee), BlockHash: bl.Hash(), Transactions: opaqueTxs, + ExcessBlobGas: (*Uint64Quantity)(bl.ExcessBlobGas()), + BlobGasUsed: (*Uint64Quantity)(bl.BlobGasUsed()), } if canyonForkTime != nil && uint64(payload.Timestamp) >= *canyonForkTime { @@ -243,6 +289,17 @@ func BlockAsPayload(bl *types.Block, canyonForkTime *uint64) (*ExecutionPayload, return payload, nil } +func BlockAsPayloadEnv(bl *types.Block, canyonForkTime *uint64) (*ExecutionPayloadEnvelope, error) { + payload, err := BlockAsPayload(bl, canyonForkTime) + if err != nil { + return nil, err + } + return &ExecutionPayloadEnvelope{ + ExecutionPayload: payload, + ParentBeaconBlockRoot: bl.BeaconRoot(), + }, nil +} + type PayloadAttributes struct { // value for the timestamp field of the new payload Timestamp Uint64Quantity `json:"timestamp"` @@ -252,6 +309,11 @@ type PayloadAttributes struct { SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient"` // Withdrawals to include into the block -- should be nil or empty depending on Shanghai enablement Withdrawals *types.Withdrawals `json:"withdrawals,omitempty"` + // parentBeaconBlockRoot optional extension in Dencun + ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot,omitempty"` + + // Optimism additions + // Transactions to force into the block (always at the start of the transactions list). Transactions []Data `json:"transactions,omitempty"` // NoTxPool to disable adding any transactions from the transaction-pool. @@ -309,11 +371,120 @@ type ForkchoiceUpdatedResult struct { type SystemConfig struct { // BatcherAddr identifies the batch-sender address used in batch-inbox data-transaction filtering. BatcherAddr common.Address `json:"batcherAddr"` - // Overhead identifies the L1 fee overhead, and is passed through opaquely to op-geth. + // Overhead identifies the L1 fee overhead. + // Pre-Ecotone this is passed as-is to the engine. + // Post-Ecotone this is always zero, and not passed into the engine. Overhead Bytes32 `json:"overhead"` - // Scalar identifies the L1 fee scalar, and is passed through opaquely to op-geth. + // Scalar identifies the L1 fee scalar + // Pre-Ecotone this is passed as-is to the engine. + // Post-Ecotone this encodes multiple pieces of scalar data. Scalar Bytes32 `json:"scalar"` // GasLimit identifies the L2 block gas limit GasLimit uint64 `json:"gasLimit"` // More fields can be added for future SystemConfig versions. } + +// The Ecotone upgrade introduces a versioned L1 scalar format +// that is backward-compatible with pre-Ecotone L1 scalar values. +const ( + // L1ScalarBedrock is implied pre-Ecotone, encoding just a regular-gas scalar. + L1ScalarBedrock = byte(0) + // L1ScalarEcotone is new in Ecotone, allowing configuration of both a regular and a blobs scalar. + L1ScalarEcotone = byte(1) +) + +func (sysCfg *SystemConfig) EcotoneScalars() (blobBaseFeeScalar, baseFeeScalar uint32, err error) { + if err := CheckEcotoneL1SystemConfigScalar(sysCfg.Scalar); err != nil { + if errors.Is(err, ErrBedrockScalarPaddingNotEmpty) { + // L2 spec mandates we set baseFeeScalar to MaxUint32 if there are non-zero bytes in + // the padding area. + return 0, math.MaxUint32, nil + } + return 0, 0, err + } + switch sysCfg.Scalar[0] { + case L1ScalarBedrock: + blobBaseFeeScalar = 0 + baseFeeScalar = binary.BigEndian.Uint32(sysCfg.Scalar[28:32]) + case L1ScalarEcotone: + blobBaseFeeScalar = binary.BigEndian.Uint32(sysCfg.Scalar[24:28]) + baseFeeScalar = binary.BigEndian.Uint32(sysCfg.Scalar[28:32]) + default: + err = fmt.Errorf("unexpected system config scalar: %s", sysCfg.Scalar) + } + return +} + +func CheckEcotoneL1SystemConfigScalar(scalar [32]byte) error { + versionByte := scalar[0] + switch versionByte { + case L1ScalarBedrock: + if ([27]byte)(scalar[1:28]) != ([27]byte{}) { // check padding + return ErrBedrockScalarPaddingNotEmpty + } + return nil + case L1ScalarEcotone: + if ([23]byte)(scalar[1:24]) != ([23]byte{}) { // check padding + return fmt.Errorf("invalid version 1 scalar padding: %x", scalar[1:24]) + } + return nil + default: + // ignore the event if it's an unknown scalar format + return fmt.Errorf("unrecognized scalar version: %d", versionByte) + } +} + +type Bytes48 [48]byte + +func (b *Bytes48) UnmarshalJSON(text []byte) error { + return hexutil.UnmarshalFixedJSON(reflect.TypeOf(b), text, b[:]) +} + +func (b *Bytes48) UnmarshalText(text []byte) error { + return hexutil.UnmarshalFixedText("Bytes32", text, b[:]) +} + +func (b Bytes48) MarshalText() ([]byte, error) { + return hexutil.Bytes(b[:]).MarshalText() +} + +func (b Bytes48) String() string { + return hexutil.Encode(b[:]) +} + +// TerminalString implements log.TerminalStringer, formatting a string for console +// output during logging. +func (b Bytes48) TerminalString() string { + return fmt.Sprintf("%x..%x", b[:3], b[45:]) +} + +// Uint64String is a decimal string representation of an uint64, for usage in the Beacon API JSON encoding +type Uint64String uint64 + +func (v Uint64String) MarshalText() (out []byte, err error) { + out = strconv.AppendUint(out, uint64(v), 10) + return +} + +func (v *Uint64String) UnmarshalText(b []byte) error { + n, err := strconv.ParseUint(string(b), 0, 64) + if err != nil { + return err + } + *v = Uint64String(n) + return nil +} + +type EngineAPIMethod string + +const ( + FCUV1 EngineAPIMethod = "engine_forkchoiceUpdatedV1" + FCUV2 EngineAPIMethod = "engine_forkchoiceUpdatedV2" + FCUV3 EngineAPIMethod = "engine_forkchoiceUpdatedV3" + + NewPayloadV2 EngineAPIMethod = "engine_newPayloadV2" + NewPayloadV3 EngineAPIMethod = "engine_newPayloadV3" + + GetPayloadV2 EngineAPIMethod = "engine_getPayloadV2" + GetPayloadV3 EngineAPIMethod = "engine_getPayloadV3" +) diff --git a/op-service/eth/types_test.go b/op-service/eth/types_test.go index 895cd34acac3..16f98d7b9393 100644 --- a/op-service/eth/types_test.go +++ b/op-service/eth/types_test.go @@ -2,6 +2,7 @@ package eth import ( "errors" + "math" "testing" "github.com/stretchr/testify/require" @@ -18,3 +19,39 @@ func TestInputError(t *testing.T) { } require.ErrorIs(t, err, InputError{}, "need to detect input error with errors.Is") } + +type scalarTest struct { + name string + val Bytes32 + fail bool + blobBaseFeeScalar uint32 + baseFeeScalar uint32 +} + +func TestEcotoneScalars(t *testing.T) { + testCases := []scalarTest{ + {"dirty padding v0 scalar", Bytes32{0: 0, 27: 1, 31: 2}, false, 0, math.MaxUint32}, + {"dirty padding v0 scalar v2", Bytes32{0: 0, 1: 1, 31: 2}, false, 0, math.MaxUint32}, + {"valid v0 scalar", Bytes32{0: 0, 27: 0, 31: 2}, false, 0, 2}, + {"invalid v1 scalar", Bytes32{0: 1, 7: 1, 31: 2}, true, 0, 0}, + {"valid v1 scalar with 0 blob scalar", Bytes32{0: 1, 27: 0, 31: 2}, false, 0, 2}, + {"valid v1 scalar with non-0 blob scalar", Bytes32{0: 1, 27: 123, 31: 2}, false, 123, 2}, + {"valid v1 scalar with non-0 blob scalar and 0 scalar", Bytes32{0: 1, 27: 123, 31: 0}, false, 123, 0}, + {"zero v0 scalar", Bytes32{0: 0}, false, 0, 0}, + {"zero v1 scalar", Bytes32{0: 1}, false, 0, 0}, + {"unknown version", Bytes32{0: 2}, true, 0, 0}, + } + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + sysConfig := SystemConfig{Scalar: tc.val} + blobScalar, regScalar, err := sysConfig.EcotoneScalars() + if tc.fail { + require.NotNil(t, err) + } else { + require.Equal(t, tc.blobBaseFeeScalar, blobScalar) + require.Equal(t, tc.baseFeeScalar, regScalar) + } + }) + } +} diff --git a/op-service/flags/custom.go b/op-service/flags/custom.go new file mode 100644 index 000000000000..38e0d283d705 --- /dev/null +++ b/op-service/flags/custom.go @@ -0,0 +1,51 @@ +package flags + +import ( + "os" + "path/filepath" +) + +// PathFlag accepts path to some file or directory and splits it +// into dirPath and filename (both can be empty) +type PathFlag struct { + originalPath string + dirPath string + filename string +} + +func (f *PathFlag) Set(path string) error { + f.originalPath = path + + fileInfo, err := os.Stat(path) + if err != nil && !os.IsNotExist(err) { + return err + } + + if fileInfo != nil && fileInfo.IsDir() { + f.dirPath = path + return nil + } + + f.dirPath, f.filename = filepath.Split(path) + return nil +} + +func (f *PathFlag) String() string { + return f.originalPath +} + +func (f *PathFlag) Clone() any { + return &PathFlag{ + originalPath: f.originalPath, + dirPath: f.dirPath, + filename: f.filename, + } +} + +func (f *PathFlag) Dir() string { + return f.dirPath +} + +func (f *PathFlag) Filename() string { + return f.filename +} diff --git a/op-service/flags/flags.go b/op-service/flags/flags.go new file mode 100644 index 000000000000..31ca3eb5bc6b --- /dev/null +++ b/op-service/flags/flags.go @@ -0,0 +1,90 @@ +package flags + +import ( + "fmt" + "strings" + + "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/op-node/chaincfg" + opservice "github.com/ethereum-optimism/optimism/op-service" +) + +const ( + RollupConfigFlagName = "rollup.config" + NetworkFlagName = "network" + CanyonOverrideFlagName = "override.canyon" + DeltaOverrideFlagName = "override.delta" + EcotoneOverrideFlagName = "override.ecotone" +) + +func CLIFlags(envPrefix string, category string) []cli.Flag { + return []cli.Flag{ + &cli.Uint64Flag{ + Name: CanyonOverrideFlagName, + Usage: "Manually specify the Canyon fork timestamp, overriding the bundled setting", + EnvVars: opservice.PrefixEnvVar(envPrefix, "OVERRIDE_CANYON"), + Hidden: false, + Category: category, + }, + &cli.Uint64Flag{ + Name: DeltaOverrideFlagName, + Usage: "Manually specify the Delta fork timestamp, overriding the bundled setting", + EnvVars: opservice.PrefixEnvVar(envPrefix, "OVERRIDE_DELTA"), + Hidden: false, + Category: category, + }, + &cli.Uint64Flag{ + Name: EcotoneOverrideFlagName, + Usage: "Manually specify the Ecotone fork timestamp, overriding the bundled setting", + EnvVars: opservice.PrefixEnvVar(envPrefix, "OVERRIDE_ECOTONE"), + Hidden: false, + Category: category, + }, + CLINetworkFlag(envPrefix, category), + CLIRollupConfigFlag(envPrefix, category), + } +} + +func CLINetworkFlag(envPrefix string, category string) cli.Flag { + return &cli.StringFlag{ + Name: NetworkFlagName, + Usage: fmt.Sprintf("Predefined network selection. Available networks: %s", strings.Join(chaincfg.AvailableNetworks(), ", ")), + EnvVars: opservice.PrefixEnvVar(envPrefix, "NETWORK"), + Category: category, + } +} + +func CLIRollupConfigFlag(envPrefix string, category string) cli.Flag { + return &cli.StringFlag{ + Name: RollupConfigFlagName, + Usage: "Rollup chain parameters", + EnvVars: opservice.PrefixEnvVar(envPrefix, "ROLLUP_CONFIG"), + Category: category, + } +} + +// This checks flags that are exclusive & required. Specifically for each +// set of flags, exactly one flag must be set. +var requiredXorFlags = [][]string{ + // TODO(client-pod#391): Re-enable this check at a later point + // { + // RollupConfigFlagName, + // NetworkFlagName, + // }, +} + +func CheckRequiredXor(ctx *cli.Context) error { + for _, flagSet := range requiredXorFlags { + var setCount int + for _, flagName := range flagSet { + if ctx.IsSet(flagName) { + setCount++ + } + } + if setCount != 1 { + return fmt.Errorf("exactly one of the following flags must be set: %s", strings.Join(flagSet, ", ")) + } + } + return nil +} diff --git a/op-service/ioutil/atomic.go b/op-service/ioutil/atomic.go new file mode 100644 index 000000000000..2bf3ae88d0c2 --- /dev/null +++ b/op-service/ioutil/atomic.go @@ -0,0 +1,46 @@ +package ioutil + +import ( + "io" + "os" + "path/filepath" +) + +type atomicWriter struct { + dest string + temp string + out io.WriteCloser +} + +// NewAtomicWriterCompressed creates a io.WriteCloser that performs an atomic write. +// The contents are initially written to a temporary file and only renamed into place when the writer is closed. +// NOTE: It's vital to check if an error is returned from Close() as it may indicate the file could not be renamed +// If path ends in .gz the contents written will be gzipped. +func NewAtomicWriterCompressed(path string, perm os.FileMode) (io.WriteCloser, error) { + f, err := os.CreateTemp(filepath.Dir(path), filepath.Base(path)) + if err != nil { + return nil, err + } + if err := f.Chmod(perm); err != nil { + _ = f.Close() + return nil, err + } + return &atomicWriter{ + dest: path, + temp: f.Name(), + out: CompressByFileType(path, f), + }, nil +} + +func (a *atomicWriter) Write(p []byte) (n int, err error) { + return a.out.Write(p) +} + +func (a *atomicWriter) Close() error { + // Attempt to clean up the temp file even if it can't be renamed into place. + defer os.Remove(a.temp) + if err := a.out.Close(); err != nil { + return err + } + return os.Rename(a.temp, a.dest) +} diff --git a/op-service/ioutil/atomic_test.go b/op-service/ioutil/atomic_test.go new file mode 100644 index 000000000000..291cbeb37730 --- /dev/null +++ b/op-service/ioutil/atomic_test.go @@ -0,0 +1,86 @@ +package ioutil + +import ( + "io" + "io/fs" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestAtomicWriter_RenameOnClose(t *testing.T) { + dir := t.TempDir() + target := filepath.Join(dir, "target.txt") + f, err := NewAtomicWriterCompressed(target, 0755) + require.NoError(t, err) + defer f.Close() + _, err = os.Stat(target) + require.ErrorIs(t, err, os.ErrNotExist, "should not create target file when created") + + content := ([]byte)("Hello world") + n, err := f.Write(content) + require.NoError(t, err) + require.Equal(t, len(content), n) + _, err = os.Stat(target) + require.ErrorIs(t, err, os.ErrNotExist, "should not create target file when writing") + + require.NoError(t, f.Close()) + stat, err := os.Stat(target) + require.NoError(t, err, "should create target file when closed") + require.EqualValues(t, fs.FileMode(0755), stat.Mode()) + + files, err := os.ReadDir(dir) + require.NoError(t, err) + require.Len(t, files, 1, "should not leave temporary files behind") +} + +func TestAtomicWriter_MultipleClose(t *testing.T) { + dir := t.TempDir() + target := filepath.Join(dir, "target.txt") + f, err := NewAtomicWriterCompressed(target, 0755) + require.NoError(t, err) + + require.NoError(t, f.Close()) + require.ErrorIs(t, f.Close(), os.ErrClosed) +} + +func TestAtomicWriter_ApplyGzip(t *testing.T) { + tests := []struct { + name string + filename string + compressed bool + }{ + {"Uncompressed", "test.notgz", false}, + {"Gzipped", "test.gz", true}, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0} + dir := t.TempDir() + path := filepath.Join(dir, test.filename) + out, err := NewAtomicWriterCompressed(path, 0o644) + require.NoError(t, err) + defer out.Close() + _, err = out.Write(data) + require.NoError(t, err) + require.NoError(t, out.Close()) + + writtenData, err := os.ReadFile(path) + require.NoError(t, err) + if test.compressed { + require.NotEqual(t, data, writtenData, "should have compressed data on disk") + } else { + require.Equal(t, data, writtenData, "should not have compressed data on disk") + } + + in, err := OpenDecompressed(path) + require.NoError(t, err) + readData, err := io.ReadAll(in) + require.NoError(t, err) + require.Equal(t, data, readData) + }) + } +} diff --git a/op-service/ioutil/gzip.go b/op-service/ioutil/gzip.go index 2c87125b6ddc..5af9b99d7841 100644 --- a/op-service/ioutil/gzip.go +++ b/op-service/ioutil/gzip.go @@ -33,10 +33,7 @@ func OpenCompressed(file string, flag int, perm os.FileMode) (io.WriteCloser, er if err != nil { return nil, err } - if IsGzip(file) { - out = gzip.NewWriter(out) - } - return out, nil + return CompressByFileType(file, out), nil } // WriteCompressedJson writes the object to the specified file as a compressed json object @@ -58,3 +55,10 @@ func WriteCompressedJson(file string, obj any) error { func IsGzip(path string) bool { return strings.HasSuffix(path, ".gz") } + +func CompressByFileType(file string, out io.WriteCloser) io.WriteCloser { + if IsGzip(file) { + return gzip.NewWriter(out) + } + return out +} diff --git a/op-service/jsonutil/json.go b/op-service/jsonutil/json.go new file mode 100644 index 000000000000..a7918d6d4a62 --- /dev/null +++ b/op-service/jsonutil/json.go @@ -0,0 +1,63 @@ +package jsonutil + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "os" + + "github.com/ethereum-optimism/optimism/op-service/ioutil" +) + +func LoadJSON[X any](inputPath string) (*X, error) { + if inputPath == "" { + return nil, errors.New("no path specified") + } + var f io.ReadCloser + f, err := ioutil.OpenDecompressed(inputPath) + if err != nil { + return nil, fmt.Errorf("failed to open file %q: %w", inputPath, err) + } + defer f.Close() + var state X + if err := json.NewDecoder(f).Decode(&state); err != nil { + return nil, fmt.Errorf("failed to decode file %q: %w", inputPath, err) + } + return &state, nil +} + +func WriteJSON[X any](outputPath string, value X, perm os.FileMode) error { + if outputPath == "" { + return nil + } + var out io.Writer + finish := func() error { return nil } + if outputPath != "-" { + f, err := ioutil.NewAtomicWriterCompressed(outputPath, perm) + if err != nil { + return fmt.Errorf("failed to open output file: %w", err) + } + // Ensure we close the stream even if failures occur. + defer f.Close() + out = f + // Closing the file causes it to be renamed to the final destination + // so make sure we handle any errors it returns + finish = f.Close + } else { + out = os.Stdout + } + enc := json.NewEncoder(out) + enc.SetIndent("", " ") + if err := enc.Encode(value); err != nil { + return fmt.Errorf("failed to encode to JSON: %w", err) + } + _, err := out.Write([]byte{'\n'}) + if err != nil { + return fmt.Errorf("failed to append new-line: %w", err) + } + if err := finish(); err != nil { + return fmt.Errorf("failed to finish write: %w", err) + } + return nil +} diff --git a/cannon/cmd/json_test.go b/op-service/jsonutil/json_test.go similarity index 86% rename from cannon/cmd/json_test.go rename to op-service/jsonutil/json_test.go index 63d4636b7d9a..16eb91992f87 100644 --- a/cannon/cmd/json_test.go +++ b/op-service/jsonutil/json_test.go @@ -1,4 +1,4 @@ -package cmd +package jsonutil import ( "encoding/json" @@ -13,7 +13,7 @@ func TestRoundTripJSON(t *testing.T) { dir := t.TempDir() file := filepath.Join(dir, "test.json") data := &jsonTestData{A: "yay", B: 3} - err := writeJSON(file, data) + err := WriteJSON(file, data, 0o755) require.NoError(t, err) // Confirm the file is uncompressed @@ -23,7 +23,7 @@ func TestRoundTripJSON(t *testing.T) { require.NoError(t, err) var result *jsonTestData - result, err = loadJSON[jsonTestData](file) + result, err = LoadJSON[jsonTestData](file) require.NoError(t, err) require.EqualValues(t, data, result) } @@ -32,7 +32,7 @@ func TestRoundTripJSONWithGzip(t *testing.T) { dir := t.TempDir() file := filepath.Join(dir, "test.json.gz") data := &jsonTestData{A: "yay", B: 3} - err := writeJSON(file, data) + err := WriteJSON(file, data, 0o755) require.NoError(t, err) // Confirm the file isn't raw JSON @@ -42,7 +42,7 @@ func TestRoundTripJSONWithGzip(t *testing.T) { require.Error(t, err, "should not be able to decode without decompressing") var result *jsonTestData - result, err = loadJSON[jsonTestData](file) + result, err = LoadJSON[jsonTestData](file) require.NoError(t, err) require.EqualValues(t, data, result) } diff --git a/op-service/log/cli.go b/op-service/log/cli.go index 983f7228dbfc..afac61483391 100644 --- a/op-service/log/cli.go +++ b/op-service/log/cli.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/urfave/cli/v2" + "golang.org/x/exp/slog" "golang.org/x/term" "github.com/ethereum/go-ethereum/log" @@ -21,95 +22,128 @@ const ( ColorFlagName = "log.color" ) -// CLIFlags creates flag definitions for the logging utils. +func CLIFlags(envPrefix string) []cli.Flag { + return CLIFlagsWithCategory(envPrefix, "") +} + +// CLIFlagsWithCategory creates flag definitions for the logging utils. // Warning: flags are not safe to reuse due to an upstream urfave default-value mutation bug in GenericFlag. // Use cliapp.ProtectFlags(flags) to create a copy before passing it into an App if the app runs more than once. -func CLIFlags(envPrefix string) []cli.Flag { +func CLIFlagsWithCategory(envPrefix string, category string) []cli.Flag { return []cli.Flag{ &cli.GenericFlag{ - Name: LevelFlagName, - Usage: "The lowest log level that will be output", - Value: NewLvlFlagValue(log.LvlInfo), - EnvVars: opservice.PrefixEnvVar(envPrefix, "LOG_LEVEL"), + Name: LevelFlagName, + Usage: "The lowest log level that will be output", + Value: NewLevelFlagValue(log.LevelInfo), + EnvVars: opservice.PrefixEnvVar(envPrefix, "LOG_LEVEL"), + Category: category, }, &cli.GenericFlag{ - Name: FormatFlagName, - Usage: "Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty',", - Value: NewFormatFlagValue(FormatText), - EnvVars: opservice.PrefixEnvVar(envPrefix, "LOG_FORMAT"), + Name: FormatFlagName, + Usage: "Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty',", + Value: NewFormatFlagValue(FormatText), + EnvVars: opservice.PrefixEnvVar(envPrefix, "LOG_FORMAT"), + Category: category, }, &cli.BoolFlag{ - Name: ColorFlagName, - Usage: "Color the log output if in terminal mode", - EnvVars: opservice.PrefixEnvVar(envPrefix, "LOG_COLOR"), + Name: ColorFlagName, + Usage: "Color the log output if in terminal mode", + EnvVars: opservice.PrefixEnvVar(envPrefix, "LOG_COLOR"), + Category: category, }, } } -// LvlFlagValue is a value type for cli.GenericFlag to parse and validate log-level values. +// LevelFlagValue is a value type for cli.GenericFlag to parse and validate log-level values. // Log level: trace, debug, info, warn, error, crit. Capitals are accepted too. -type LvlFlagValue log.Lvl +type LevelFlagValue slog.Level -func NewLvlFlagValue(lvl log.Lvl) *LvlFlagValue { - return (*LvlFlagValue)(&lvl) +func NewLevelFlagValue(lvl slog.Level) *LevelFlagValue { + return (*LevelFlagValue)(&lvl) } -func (fv *LvlFlagValue) Set(value string) error { +func (fv *LevelFlagValue) Set(value string) error { value = strings.ToLower(value) // ignore case - lvl, err := log.LvlFromString(value) + lvl, err := LevelFromString(value) if err != nil { return err } - *fv = LvlFlagValue(lvl) + *fv = LevelFlagValue(lvl) return nil } -func (fv LvlFlagValue) String() string { - return log.Lvl(fv).String() +func (fv LevelFlagValue) String() string { + return slog.Level(fv).String() } -func (fv LvlFlagValue) LogLvl() log.Lvl { - return log.Lvl(fv) +func (fv LevelFlagValue) Level() slog.Level { + return slog.Level(fv).Level() } -func (fv *LvlFlagValue) Clone() any { +func (fv *LevelFlagValue) Clone() any { cpy := *fv return &cpy } -var _ cliapp.CloneableGeneric = (*LvlFlagValue)(nil) +// LevelFromString returns the appropriate Level from a string name. +// Useful for parsing command line args and configuration files. +// It also converts strings to lowercase. +// If the string is unknown, LevelDebug is returned as a default, together with +// a non-nil error. +func LevelFromString(lvlString string) (slog.Level, error) { + lvlString = strings.ToLower(lvlString) // ignore case + switch lvlString { + case "trace", "trce": + return log.LevelTrace, nil + case "debug", "dbug": + return log.LevelDebug, nil + case "info": + return log.LevelInfo, nil + case "warn": + return log.LevelWarn, nil + case "error", "eror": + return log.LevelError, nil + case "crit": + return log.LevelCrit, nil + default: + return log.LevelDebug, fmt.Errorf("unknown level: %v", lvlString) + } +} + +var _ cliapp.CloneableGeneric = (*LevelFlagValue)(nil) // FormatType defines a type of log format. -// Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty' +// Supported formats: 'text', 'terminal', 'logfmt', 'json' type FormatType string const ( - FormatText FormatType = "text" - FormatTerminal FormatType = "terminal" - FormatLogFmt FormatType = "logfmt" - FormatJSON FormatType = "json" - FormatJSONPretty FormatType = "json-pretty" + FormatText FormatType = "text" + FormatTerminal FormatType = "terminal" + FormatLogFmt FormatType = "logfmt" + FormatJSON FormatType = "json" ) -// Formatter turns a format type and color into a structured Format object -func (ft FormatType) Formatter(color bool) log.Format { +// FormatHandler returns the correct slog handler factory for the provided format. +func FormatHandler(ft FormatType, color bool) func(io.Writer) slog.Handler { + termColorHandler := func(w io.Writer) slog.Handler { + return log.NewTerminalHandler(w, color) + } + logfmtHandler := func(w io.Writer) slog.Handler { return log.LogfmtHandlerWithLevel(w, log.LevelTrace) } switch ft { case FormatJSON: - return log.JSONFormat() - case FormatJSONPretty: - return log.JSONFormatEx(true, true) + return log.JSONHandler case FormatText: if term.IsTerminal(int(os.Stdout.Fd())) { - return log.TerminalFormat(color) + return termColorHandler } else { - return log.LogfmtFormat() + return logfmtHandler } case FormatTerminal: - return log.TerminalFormat(color) + return termColorHandler case FormatLogFmt: - return log.LogfmtFormat() + return logfmtHandler default: - panic(fmt.Errorf("failed to create `log.Format` for format-type=%q and color=%v", ft, color)) + panic(fmt.Errorf("failed to create slog.Handler factory for format-type=%q and color=%v", ft, color)) } } @@ -126,7 +160,7 @@ func NewFormatFlagValue(fmtType FormatType) *FormatFlagValue { func (fv *FormatFlagValue) Set(value string) error { switch FormatType(value) { - case FormatText, FormatTerminal, FormatLogFmt, FormatJSON, FormatJSONPretty: + case FormatText, FormatTerminal, FormatLogFmt, FormatJSON: *fv = FormatFlagValue(value) return nil default: @@ -150,7 +184,7 @@ func (fv *FormatFlagValue) Clone() any { var _ cliapp.CloneableGeneric = (*FormatFlagValue)(nil) type CLIConfig struct { - Level log.Lvl + Level slog.Level Color bool Format FormatType } @@ -165,20 +199,16 @@ func AppOut(ctx *cli.Context) io.Writer { } // NewLogHandler creates a new configured handler, compatible as LvlSetter for log-level changes during runtime. -func NewLogHandler(wr io.Writer, cfg CLIConfig) log.Handler { - handler := log.StreamHandler(wr, cfg.Format.Formatter(cfg.Color)) - handler = log.SyncHandler(handler) - handler = NewDynamicLogHandler(cfg.Level, handler) - return handler +func NewLogHandler(wr io.Writer, cfg CLIConfig) slog.Handler { + handler := FormatHandler(cfg.Format, cfg.Color)(wr) + return NewDynamicLogHandler(cfg.Level, handler) } // NewLogger creates a new configured logger. // The log handler of the logger is a LvlSetter, i.e. the log level can be changed as needed. func NewLogger(wr io.Writer, cfg CLIConfig) log.Logger { - handler := NewLogHandler(wr, cfg) - logger := log.New() - logger.SetHandler(handler) - return logger + h := NewLogHandler(wr, cfg) + return log.NewLogger(h) } // SetGlobalLogHandler sets the log handles as the handler of the global default logger. @@ -186,15 +216,15 @@ func NewLogger(wr io.Writer, cfg CLIConfig) log.Logger { // as it does makes it difficult to distinguish different services in the same process, e.g. during tests. // Geth and other components may use the global logger however, // and it is thus recommended to set the global log handler to catch these logs. -func SetGlobalLogHandler(h log.Handler) { - log.Root().SetHandler(h) +func SetGlobalLogHandler(h slog.Handler) { + log.SetDefault(log.NewLogger(h)) } // DefaultCLIConfig creates a default log configuration. // Color defaults to true if terminal is detected. func DefaultCLIConfig() CLIConfig { return CLIConfig{ - Level: log.LvlInfo, + Level: log.LevelInfo, Format: FormatText, Color: term.IsTerminal(int(os.Stdout.Fd())), } @@ -202,7 +232,7 @@ func DefaultCLIConfig() CLIConfig { func ReadCLIConfig(ctx *cli.Context) CLIConfig { cfg := DefaultCLIConfig() - cfg.Level = ctx.Generic(LevelFlagName).(*LvlFlagValue).LogLvl() + cfg.Level = ctx.Generic(LevelFlagName).(*LevelFlagValue).Level() cfg.Format = ctx.Generic(FormatFlagName).(*FormatFlagValue).FormatType() if ctx.IsSet(ColorFlagName) { cfg.Color = ctx.Bool(ColorFlagName) diff --git a/op-service/log/defaults.go b/op-service/log/defaults.go index a57408be81db..d7997e8040a3 100644 --- a/op-service/log/defaults.go +++ b/op-service/log/defaults.go @@ -7,10 +7,5 @@ import ( ) func SetupDefaults() { - log.Root().SetHandler( - log.LvlFilterHandler( - log.LvlInfo, - log.StreamHandler(os.Stdout, log.LogfmtFormat()), - ), - ) + SetGlobalLogHandler(log.LogfmtHandlerWithLevel(os.Stdout, log.LevelInfo)) } diff --git a/op-service/log/dynamic.go b/op-service/log/dynamic.go index 901279aba094..72f23f505bbc 100644 --- a/op-service/log/dynamic.go +++ b/op-service/log/dynamic.go @@ -1,31 +1,53 @@ package log -import "github.com/ethereum/go-ethereum/log" +import ( + "context" + + "golang.org/x/exp/slog" +) type LvlSetter interface { - SetLogLevel(lvl log.Lvl) + SetLogLevel(lvl slog.Level) } // DynamicLogHandler allow runtime-configuration of the log handler. type DynamicLogHandler struct { - log.Handler // embedded, to expose any extra methods the underlying handler might provide - maxLvl log.Lvl + h slog.Handler + minLvl *slog.Level // shared with derived dynamic handlers } -func NewDynamicLogHandler(lvl log.Lvl, h log.Handler) *DynamicLogHandler { +func NewDynamicLogHandler(lvl slog.Level, h slog.Handler) *DynamicLogHandler { return &DynamicLogHandler{ - Handler: h, - maxLvl: lvl, + h: h, + minLvl: &lvl, } } -func (d *DynamicLogHandler) SetLogLevel(lvl log.Lvl) { - d.maxLvl = lvl +func (d *DynamicLogHandler) SetLogLevel(lvl slog.Level) { + *d.minLvl = lvl } -func (d *DynamicLogHandler) Log(r *log.Record) error { - if r.Lvl > d.maxLvl { // lower log level values are more critical +func (d *DynamicLogHandler) Handle(ctx context.Context, r slog.Record) error { + if r.Level < *d.minLvl { // higher log level values are more critical return nil } - return d.Handler.Log(r) // process the log + return d.h.Handle(ctx, r) // process the log +} + +func (d *DynamicLogHandler) Enabled(ctx context.Context, lvl slog.Level) bool { + return (lvl >= *d.minLvl) && d.h.Enabled(ctx, lvl) +} + +func (d *DynamicLogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + return &DynamicLogHandler{ + h: d.h.WithAttrs(attrs), + minLvl: d.minLvl, + } +} + +func (d *DynamicLogHandler) WithGroup(name string) slog.Handler { + return &DynamicLogHandler{ + h: d.h.WithGroup(name), + minLvl: d.minLvl, + } } diff --git a/op-service/log/dynamic_test.go b/op-service/log/dynamic_test.go index 45fd3def95df..3a992710b4d8 100644 --- a/op-service/log/dynamic_test.go +++ b/op-service/log/dynamic_test.go @@ -1,44 +1,84 @@ package log import ( + "context" "testing" "github.com/stretchr/testify/require" + "golang.org/x/exp/slog" "github.com/ethereum/go-ethereum/log" ) func TestDynamicLogHandler_SetLogLevel(t *testing.T) { - var records []*log.Record - h := log.FuncHandler(func(r *log.Record) error { - records = append(records, r) - return nil - }) - d := NewDynamicLogHandler(log.LvlInfo, h) - logger := log.New() - logger.SetHandler(d) + h := new(testRecorder) + d := NewDynamicLogHandler(log.LevelInfo, h) + logger := log.NewLogger(d) logger.Info("hello world") // y logger.Error("error!") // y logger.Debug("debugging") // n // increase log level - logger.GetHandler().(LvlSetter).SetLogLevel(log.LvlDebug) + d.SetLogLevel(log.LevelDebug) logger.Info("hello again") // y logger.Debug("can see debug now") // y logger.Trace("but no trace") // n // and decrease log level - logger.GetHandler().(LvlSetter).SetLogLevel(log.LvlWarn) + d.SetLogLevel(log.LevelWarn) logger.Warn("visible warning") // y logger.Info("info should be hidden now") // n logger.Error("another error") // y - require.Len(t, records, 2+2+2) - require.Equal(t, records[0].Msg, "hello world") - require.Equal(t, records[1].Msg, "error!") - require.Equal(t, records[2].Msg, "hello again") - require.Equal(t, records[3].Msg, "can see debug now") - require.Equal(t, records[4].Msg, "visible warning") - require.Equal(t, records[5].Msg, "another error") + require.Len(t, h.records, 2+2+2) + require.Equal(t, h.records[0].Message, "hello world") + require.Equal(t, h.records[1].Message, "error!") + require.Equal(t, h.records[2].Message, "hello again") + require.Equal(t, h.records[3].Message, "can see debug now") + require.Equal(t, h.records[4].Message, "visible warning") + require.Equal(t, h.records[5].Message, "another error") } + +func TestDynamicLogHandler_WithAttrs(t *testing.T) { + h := new(testRecorder) + d := NewDynamicLogHandler(log.LevelInfo, h) + logger := log.NewLogger(d) + logwith := logger.With("a", 1) // derived logger + + // increase log level + d.SetLogLevel(log.LevelDebug) + + logwith.Info("info0") // y + logwith.Debug("debug0") // y + logwith.Trace("trace0") // n + + // and decrease log level + d.SetLogLevel(log.LevelWarn) + + logwith.Info("info1") // n + logwith.Warn("warn1") // y + logwith.Error("error1") // y + + require.Len(t, h.records, 2+2) + require.Equal(t, h.records[0].Message, "info0") + require.Equal(t, h.records[1].Message, "debug0") + require.Equal(t, h.records[2].Message, "warn1") + require.Equal(t, h.records[3].Message, "error1") +} + +type testRecorder struct { + records []slog.Record +} + +func (r testRecorder) Enabled(context.Context, slog.Level) bool { + return true +} + +func (r *testRecorder) Handle(_ context.Context, rec slog.Record) error { + r.records = append(r.records, rec) + return nil +} + +func (r *testRecorder) WithAttrs([]slog.Attr) slog.Handler { return r } +func (r *testRecorder) WithGroup(string) slog.Handler { return r } diff --git a/op-service/log/writer.go b/op-service/log/writer.go index 77c787249142..0a1731383068 100644 --- a/op-service/log/writer.go +++ b/op-service/log/writer.go @@ -3,29 +3,31 @@ package log import ( "sync" + "golang.org/x/exp/slog" + "github.com/ethereum/go-ethereum/log" ) type Writer struct { - log func(str string, ctx ...interface{}) + log func(str string, ctx ...any) lock sync.Mutex pending []byte } -func NewWriter(l log.Logger, lvl log.Lvl) *Writer { - var logMethod func(str string, ctx ...interface{}) +func NewWriter(l log.Logger, lvl slog.Level) *Writer { + var logMethod func(str string, ctx ...any) switch lvl { - case log.LvlTrace: + case log.LevelTrace: logMethod = l.Trace - case log.LvlDebug: + case log.LevelDebug: logMethod = l.Debug - case log.LvlInfo: + case log.LevelInfo: logMethod = l.Info - case log.LvlWarn: + case log.LevelWarn: logMethod = l.Warn - case log.LvlError: + case log.LevelError: logMethod = l.Error - case log.LvlCrit: + case log.LevelCrit: logMethod = l.Crit default: // Cast lvl to int to avoid trying to convert it to a string which will fail for unknown types diff --git a/op-service/log/writer_test.go b/op-service/log/writer_test.go index 4a4c000bd5b3..2e9cf14b3a75 100644 --- a/op-service/log/writer_test.go +++ b/op-service/log/writer_test.go @@ -1,81 +1,98 @@ -package log +package log_test import ( "io" "testing" - "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" + "golang.org/x/exp/slog" + + "github.com/ethereum/go-ethereum/log" + + . "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/testlog" ) var _ io.Writer = (*Writer)(nil) func TestLogWriter(t *testing.T) { - setup := func(t *testing.T, lvl log.Lvl) (*Writer, *testlog.CapturingHandler) { - logger := testlog.Logger(t, lvl) - logs := testlog.Capture(logger) + setup := func(t *testing.T, lvl slog.Level) (*Writer, *testlog.CapturingHandler) { + logger, logs := testlog.CaptureLogger(t, lvl) writer := NewWriter(logger, lvl) return writer, logs } t.Run("LogSingleLine", func(t *testing.T) { - writer, logs := setup(t, log.LvlInfo) + writer, logs := setup(t, log.LevelInfo) line := []byte("Test line\n") count, err := writer.Write(line) require.NoError(t, err) require.Equal(t, len(line), count) - require.NotNil(t, logs.FindLog(log.LvlInfo, "Test line")) + levelFilter := testlog.NewLevelFilter(log.LevelInfo) + msgFilter := testlog.NewMessageFilter("Test line") + require.NotNil(t, logs.FindLog(levelFilter, msgFilter)) }) t.Run("LogMultipleLines", func(t *testing.T) { - writer, logs := setup(t, log.LvlInfo) + writer, logs := setup(t, log.LevelInfo) line := []byte("Line 1\nLine 2\n") count, err := writer.Write(line) require.NoError(t, err) require.Equal(t, len(line), count) - require.NotNil(t, logs.FindLog(log.LvlInfo, "Line 1")) - require.NotNil(t, logs.FindLog(log.LvlInfo, "Line 2")) + levelFilter := testlog.NewLevelFilter(log.LevelInfo) + lineOneFilter := testlog.NewMessageFilter("Line 1") + lineTwoFilter := testlog.NewMessageFilter("Line 2") + require.NotNil(t, logs.FindLog(levelFilter, lineOneFilter)) + require.NotNil(t, logs.FindLog(levelFilter, lineTwoFilter)) }) t.Run("LogLineAcrossMultipleCalls", func(t *testing.T) { - writer, logs := setup(t, log.LvlInfo) + writer, logs := setup(t, log.LevelInfo) line := []byte("First line\nSplit ") count, err := writer.Write(line) require.NoError(t, err) require.Equal(t, len(line), count) - require.NotNil(t, logs.FindLog(log.LvlInfo, "First line")) + levelFilter := testlog.NewLevelFilter(log.LevelInfo) + msgFilter := testlog.NewMessageFilter("First line") + require.NotNil(t, logs.FindLog(levelFilter, msgFilter)) line = []byte("Line\nLast Line\n") count, err = writer.Write(line) require.NoError(t, err) require.Equal(t, len(line), count) - require.NotNil(t, logs.FindLog(log.LvlInfo, "Split Line")) - require.NotNil(t, logs.FindLog(log.LvlInfo, "Last Line")) + levelFilter = testlog.NewLevelFilter(log.LevelInfo) + splitLineFilter := testlog.NewMessageFilter("Split Line") + lastLineFilter := testlog.NewMessageFilter("Last Line") + require.NotNil(t, logs.FindLog(levelFilter, splitLineFilter)) + require.NotNil(t, logs.FindLog(levelFilter, lastLineFilter)) }) - // Can't test LvlCrit or it will call os.Exit - for _, lvl := range []log.Lvl{log.LvlTrace, log.LvlDebug, log.LvlInfo, log.LvlWarn, log.LvlError} { + // Can't test LevelCrit or it will call os.Exit + for _, lvl := range []slog.Level{log.LevelTrace, log.LevelDebug, log.LevelInfo, log.LevelWarn, log.LevelError} { lvl := lvl - t.Run("LogLvl_"+lvl.String(), func(t *testing.T) { + t.Run("LogLevel_"+lvl.String(), func(t *testing.T) { writer, logs := setup(t, lvl) line := []byte("Log line\n") count, err := writer.Write(line) require.NoError(t, err) require.Equal(t, len(line), count) - require.NotNil(t, logs.FindLog(lvl, "Log line")) + levelFilter := testlog.NewLevelFilter(lvl) + msgFilter := testlog.NewMessageFilter("Log line") + require.NotNil(t, logs.FindLog(levelFilter, msgFilter)) }) } t.Run("UseErrorForUnknownLevels", func(t *testing.T) { - logger := testlog.Logger(t, log.LvlInfo) - logs := testlog.Capture(logger) + logger, logs := testlog.CaptureLogger(t, log.LevelInfo) writer := NewWriter(logger, 60027) line := []byte("Log line\n") count, err := writer.Write(line) require.NoError(t, err) require.Equal(t, len(line), count) - require.NotNil(t, logs.FindLog(log.LvlError, "Unknown log level. Using Error")) - require.NotNil(t, logs.FindLog(log.LvlError, "Log line")) + levelFilter := testlog.NewLevelFilter(log.LevelError) + unknownFilter := testlog.NewMessageFilter("Unknown log level. Using Error") + logLineFilter := testlog.NewMessageFilter("Log line") + require.NotNil(t, logs.FindLog(levelFilter, unknownFilter)) + require.NotNil(t, logs.FindLog(levelFilter, logLineFilter)) }) } diff --git a/op-service/metrics/ref_metrics.go b/op-service/metrics/ref_metrics.go index 9405abfbd7ca..19d8badb9ab7 100644 --- a/op-service/metrics/ref_metrics.go +++ b/op-service/metrics/ref_metrics.go @@ -34,7 +34,7 @@ type RefMetrics struct { var _ RefMetricer = (*RefMetrics)(nil) // MakeRefMetrics returns a new RefMetrics, initializing its prometheus fields -// using factory. It is supposed to be used inside the construtors of metrics +// using factory. It is supposed to be used inside the constructors of metrics // structs for any op service after the full namespace and factory have been // setup. // diff --git a/op-service/opio/interrupts.go b/op-service/opio/interrupts.go index 1b886c6d9001..cd1b8485791d 100644 --- a/op-service/opio/interrupts.go +++ b/op-service/opio/interrupts.go @@ -41,3 +41,74 @@ func BlockOnInterruptsContext(ctx context.Context, signals ...os.Signal) { signal.Stop(interruptChannel) } } + +type interruptContextKeyType struct{} + +var blockerContextKey = interruptContextKeyType{} + +type interruptCatcher struct { + incoming chan os.Signal +} + +// Block blocks until either an interrupt signal is received, or the context is cancelled. +// No error is returned on interrupt. +func (c *interruptCatcher) Block(ctx context.Context) { + select { + case <-c.incoming: + case <-ctx.Done(): + } +} + +// WithInterruptBlocker attaches an interrupt handler to the context, +// which continues to receive signals after every block. +// This helps functions block on individual consecutive interrupts. +func WithInterruptBlocker(ctx context.Context) context.Context { + if ctx.Value(blockerContextKey) != nil { // already has an interrupt handler + return ctx + } + catcher := &interruptCatcher{ + incoming: make(chan os.Signal, 10), + } + signal.Notify(catcher.incoming, DefaultInterruptSignals...) + + return context.WithValue(ctx, blockerContextKey, BlockFn(catcher.Block)) +} + +// WithBlocker overrides the interrupt blocker value, +// e.g. to insert a block-function for testing CLI shutdown without actual process signals. +func WithBlocker(ctx context.Context, fn BlockFn) context.Context { + return context.WithValue(ctx, blockerContextKey, fn) +} + +// BlockFn simply blocks until the implementation of the blocker interrupts it, or till the given context is cancelled. +type BlockFn func(ctx context.Context) + +// BlockerFromContext returns a BlockFn that blocks on interrupts when called. +func BlockerFromContext(ctx context.Context) BlockFn { + v := ctx.Value(blockerContextKey) + if v == nil { + return nil + } + return v.(BlockFn) +} + +// CancelOnInterrupt cancels the given context on interrupt. +// If a BlockFn is attached to the context, this is used as interrupt-blocking. +// If not, then the context blocks on a manually handled interrupt signal. +func CancelOnInterrupt(ctx context.Context) context.Context { + inner, cancel := context.WithCancel(ctx) + + blockOnInterrupt := BlockerFromContext(ctx) + if blockOnInterrupt == nil { + blockOnInterrupt = func(ctx context.Context) { + BlockOnInterruptsContext(ctx) // default signals + } + } + + go func() { + blockOnInterrupt(ctx) + cancel() + }() + + return inner +} diff --git a/op-service/oppprof/cli.go b/op-service/oppprof/cli.go new file mode 100644 index 000000000000..710cbeaaf764 --- /dev/null +++ b/op-service/oppprof/cli.go @@ -0,0 +1,141 @@ +package oppprof + +import ( + "errors" + "fmt" + "math" + "strings" + + opservice "github.com/ethereum-optimism/optimism/op-service" + openum "github.com/ethereum-optimism/optimism/op-service/enum" + "github.com/ethereum-optimism/optimism/op-service/flags" + "github.com/urfave/cli/v2" +) + +const ( + EnabledFlagName = "pprof.enabled" + ListenAddrFlagName = "pprof.addr" + PortFlagName = "pprof.port" + ProfileTypeFlagName = "pprof.type" + ProfilePathFlagName = "pprof.path" + defaultListenAddr = "0.0.0.0" + defaultListenPort = 6060 +) + +var allowedProfileTypes = []profileType{"cpu", "heap", "goroutine", "threadcreate", "block", "mutex", "allocs"} + +type profileType string + +func (t profileType) String() string { + return string(t) +} + +func (t *profileType) Set(value string) error { + if !validProfileType(profileType(value)) { + return fmt.Errorf("unknown profile type: %q", value) + } + *t = profileType(value) + return nil +} + +func (t *profileType) Clone() any { + cpy := *t + return &cpy +} + +func validProfileType(value profileType) bool { + for _, k := range allowedProfileTypes { + if k == value { + return true + } + } + return false +} + +func DefaultCLIConfig() CLIConfig { + return CLIConfig{ + ListenEnabled: false, + ListenAddr: defaultListenAddr, + ListenPort: defaultListenPort, + } +} + +func CLIFlags(envPrefix string) []cli.Flag { + return CLIFlagsWithCategory(envPrefix, "") +} + +func CLIFlagsWithCategory(envPrefix string, category string) []cli.Flag { + return []cli.Flag{ + &cli.BoolFlag{ + Name: EnabledFlagName, + Usage: "Enable the pprof server", + EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_ENABLED"), + Category: category, + }, + &cli.StringFlag{ + Name: ListenAddrFlagName, + Usage: "pprof listening address", + Value: defaultListenAddr, // TODO(CLI-4159): Switch to 127.0.0.1 + EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_ADDR"), + Category: category, + }, + &cli.IntFlag{ + Name: PortFlagName, + Usage: "pprof listening port", + Value: defaultListenPort, + EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_PORT"), + Category: category, + }, + &cli.GenericFlag{ + Name: ProfilePathFlagName, + Usage: "pprof file path. If it is a directory, the path is {dir}/{profileType}.prof", + Value: new(flags.PathFlag), + EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_PATH"), + Category: category, + }, + &cli.GenericFlag{ + Name: ProfileTypeFlagName, + Usage: "pprof profile type. One of " + openum.EnumString(allowedProfileTypes), + Value: func() *profileType { + defaultProfType := profileType("") + return &defaultProfType + }(), + EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_TYPE"), + Category: category, + }, + } +} + +type CLIConfig struct { + ListenEnabled bool + ListenAddr string + ListenPort int + + ProfileType profileType + ProfileDir string + ProfileFilename string +} + +func (m CLIConfig) Check() error { + if !m.ListenEnabled { + return nil + } + + if m.ListenPort < 0 || m.ListenPort > math.MaxUint16 { + return errors.New("invalid pprof port") + } + + return nil +} + +func ReadCLIConfig(ctx *cli.Context) CLIConfig { + profilePathFlag := ctx.Generic(ProfilePathFlagName).(*flags.PathFlag) + return CLIConfig{ + ListenEnabled: ctx.Bool(EnabledFlagName), + ListenAddr: ctx.String(ListenAddrFlagName), + ListenPort: ctx.Int(PortFlagName), + ProfileType: profileType(strings.ToLower(ctx.String(ProfileTypeFlagName))), + ProfileDir: profilePathFlag.Dir(), + ProfileFilename: profilePathFlag.Filename(), + } +} diff --git a/op-service/oppprof/service.go b/op-service/oppprof/service.go new file mode 100644 index 000000000000..8259bbfb1e12 --- /dev/null +++ b/op-service/oppprof/service.go @@ -0,0 +1,138 @@ +package oppprof + +import ( + "context" + "io" + "net" + "net/http" + httpPprof "net/http/pprof" + "os" + "path/filepath" + "runtime" + "runtime/pprof" + "strconv" + + "github.com/ethereum-optimism/optimism/op-service/httputil" + "github.com/ethereum/go-ethereum/log" +) + +type Service struct { + listenEnabled bool + listenAddr string + listenPort int + + profileType string + profileDir string + profileFilename string + + cpuFile io.Closer + httpServer *httputil.HTTPServer +} + +func New(listenEnabled bool, listenAddr string, listenPort int, profType profileType, profileDir, profileFilename string) *Service { + return &Service{ + listenEnabled: listenEnabled, + listenAddr: listenAddr, + listenPort: listenPort, + profileType: string(profType), + profileDir: profileDir, + profileFilename: profileFilename, + } +} + +func (s *Service) Start() error { + switch s.profileType { + case "cpu": + if err := s.startCPUProfile(); err != nil { + return err + } + case "block": + runtime.SetBlockProfileRate(1) + case "mutex": + runtime.SetMutexProfileFraction(1) + } + if s.listenEnabled { + if err := s.startServer(); err != nil { + return err + } + } + if s.profileType != "" { + log.Info("start profiling to file", "profile_type", s.profileType, "profile_filepath", s.buildTargetFilePath()) + } + return nil +} + +func (s *Service) Stop(ctx context.Context) error { + switch s.profileType { + case "cpu": + pprof.StopCPUProfile() + if s.cpuFile != nil { + if err := s.cpuFile.Close(); err != nil { + return err + } + } + case "heap": + runtime.GC() + fallthrough + default: + profile := pprof.Lookup(s.profileType) + if profile == nil { + break + } + filepath := s.buildTargetFilePath() + log.Info("saving profile info", "profile_type", s.profileType, "profile_filepath", s.buildTargetFilePath()) + f, err := os.Create(filepath) + if err != nil { + return err + } + defer f.Close() + _ = profile.WriteTo(f, 0) + } + if s.httpServer != nil { + if err := s.httpServer.Stop(ctx); err != nil { + return err + } + } + return nil +} + +func (s *Service) startServer() error { + log.Debug("starting pprof server", "addr", net.JoinHostPort(s.listenAddr, strconv.Itoa(s.listenPort))) + mux := http.NewServeMux() + + // have to do below to support multiple servers, since the + // pprof import only uses DefaultServeMux + mux.Handle("/debug/pprof/", http.HandlerFunc(httpPprof.Index)) + mux.Handle("/debug/pprof/profile", http.HandlerFunc(httpPprof.Profile)) + mux.Handle("/debug/pprof/symbol", http.HandlerFunc(httpPprof.Symbol)) + mux.Handle("/debug/pprof/trace", http.HandlerFunc(httpPprof.Trace)) + + addr := net.JoinHostPort(s.listenAddr, strconv.Itoa(s.listenPort)) + + var err error + s.httpServer, err = httputil.StartHTTPServer(addr, mux) + if err != nil { + return err + } + + log.Info("started pprof server", "addr", s.httpServer.Addr()) + return nil +} + +func (s *Service) startCPUProfile() error { + f, err := os.Create(s.buildTargetFilePath()) + if err != nil { + return err + } + err = pprof.StartCPUProfile(f) + s.cpuFile = f + return err +} + +func (s *Service) buildTargetFilePath() string { + filename := s.profileType + ".prof" + if s.profileFilename != "" { + filename = s.profileFilename + } + return filepath.Join(s.profileDir, filename) +} diff --git a/op-service/pprof/cli.go b/op-service/pprof/cli.go deleted file mode 100644 index 3a732cd184ee..000000000000 --- a/op-service/pprof/cli.go +++ /dev/null @@ -1,73 +0,0 @@ -package pprof - -import ( - "errors" - "math" - - opservice "github.com/ethereum-optimism/optimism/op-service" - "github.com/urfave/cli/v2" -) - -const ( - EnabledFlagName = "pprof.enabled" - ListenAddrFlagName = "pprof.addr" - PortFlagName = "pprof.port" - defaultListenAddr = "0.0.0.0" - defaultListenPort = 6060 -) - -func DefaultCLIConfig() CLIConfig { - return CLIConfig{ - Enabled: false, - ListenAddr: defaultListenAddr, - ListenPort: defaultListenPort, - } -} - -func CLIFlags(envPrefix string) []cli.Flag { - return []cli.Flag{ - &cli.BoolFlag{ - Name: EnabledFlagName, - Usage: "Enable the pprof server", - EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_ENABLED"), - }, - &cli.StringFlag{ - Name: ListenAddrFlagName, - Usage: "pprof listening address", - Value: defaultListenAddr, // TODO(CLI-4159): Switch to 127.0.0.1 - EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_ADDR"), - }, - &cli.IntFlag{ - Name: PortFlagName, - Usage: "pprof listening port", - Value: defaultListenPort, - EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_PORT"), - }, - } -} - -type CLIConfig struct { - Enabled bool - ListenAddr string - ListenPort int -} - -func (m CLIConfig) Check() error { - if !m.Enabled { - return nil - } - - if m.ListenPort < 0 || m.ListenPort > math.MaxUint16 { - return errors.New("invalid pprof port") - } - - return nil -} - -func ReadCLIConfig(ctx *cli.Context) CLIConfig { - return CLIConfig{ - Enabled: ctx.Bool(EnabledFlagName), - ListenAddr: ctx.String(ListenAddrFlagName), - ListenPort: ctx.Int(PortFlagName), - } -} diff --git a/op-service/pprof/server.go b/op-service/pprof/server.go deleted file mode 100644 index 906c8571f726..000000000000 --- a/op-service/pprof/server.go +++ /dev/null @@ -1,25 +0,0 @@ -package pprof - -import ( - "net" - "net/http" - "net/http/pprof" - "strconv" - - "github.com/ethereum-optimism/optimism/op-service/httputil" -) - -func StartServer(hostname string, port int) (*httputil.HTTPServer, error) { - mux := http.NewServeMux() - - // have to do below to support multiple servers, since the - // pprof import only uses DefaultServeMux - mux.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index)) - mux.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline)) - mux.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile)) - mux.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol)) - mux.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace)) - - addr := net.JoinHostPort(hostname, strconv.Itoa(port)) - return httputil.StartHTTPServer(addr, mux) -} diff --git a/op-service/rethdb-reader/.gitignore b/op-service/rethdb-reader/.gitignore index 96359724ffbc..360eaff0efc3 100644 --- a/op-service/rethdb-reader/.gitignore +++ b/op-service/rethdb-reader/.gitignore @@ -3,3 +3,6 @@ target/ # Bindings rdb.h + +# Testdata DB +testdata/db diff --git a/op-service/rethdb-reader/Cargo.lock b/op-service/rethdb-reader/Cargo.lock index 14622c0a8c03..9ad3a5ed6639 100644 --- a/op-service/rethdb-reader/Cargo.lock +++ b/op-service/rethdb-reader/Cargo.lock @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher 0.4.4", @@ -66,26 +66,16 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b" dependencies = [ "cfg-if", - "getrandom 0.2.10", "once_cell", "version_check", "zerocopy", ] -[[package]] -name = "aho-corasick" -version = "0.7.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" -dependencies = [ - "memchr", -] - [[package]] name = "aho-corasick" version = "1.1.2" @@ -96,73 +86,62 @@ dependencies = [ ] [[package]] -name = "alloc-no-stdlib" -version = "2.0.4" +name = "allocator-api2" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] -name = "alloc-stdlib" -version = "0.2.2" +name = "alloy-chains" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +checksum = "fe92bd1fb0c96e938f9f2284618028e5f4dc3d719cac32631ed51e1b86a06895" dependencies = [ - "alloc-no-stdlib", + "alloy-rlp", + "arbitrary", + "num_enum", + "proptest", + "serde", + "strum", ] [[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - -[[package]] -name = "alloy-dyn-abi" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e0daba57ddaba12dc9b21f608b843251f3de017f94a431dca4e7f4f72e5ba9" +name = "alloy-eips" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e" dependencies = [ - "alloy-json-abi", "alloy-primitives", - "alloy-sol-type-parser", - "alloy-sol-types", - "const-hex", - "derive_more", - "itoa", - "serde", - "serde_json", + "alloy-rlp", + "thiserror", ] [[package]] -name = "alloy-json-abi" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63c9319ad8b2b623c6a3ac15899f8ffb71479224762dbaedc385c16efbb6cfe3" +name = "alloy-genesis" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e" dependencies = [ "alloy-primitives", - "alloy-sol-type-parser", + "alloy-rpc-types", "serde", - "serde_json", ] [[package]] name = "alloy-primitives" -version = "0.4.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0628ec0ba5b98b3370bb6be17b12f23bfce8ee4ad83823325a20546d9b03b78" +checksum = "ef197eb250c64962003cb08b90b17f0882c192f4a6f2f544809d424fd7cb0e7d" dependencies = [ "alloy-rlp", - "arbitrary", "bytes", "cfg-if", "const-hex", - "derive_arbitrary", "derive_more", - "getrandom 0.2.10", + "getrandom 0.2.12", "hex-literal", "itoa", + "k256", + "keccak-asm", "proptest", - "proptest-derive", "rand 0.8.5", "ruint", "serde", @@ -171,63 +150,108 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc0fac0fc16baf1f63f78b47c3d24718f3619b0714076f6a02957d808d52cbef" +checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" dependencies = [ "alloy-rlp-derive", "arrayvec", "bytes", - "smol_str", ] [[package]] name = "alloy-rlp-derive" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0391754c09fab4eae3404d19d0d297aa1c670c1775ab51d8a5312afeca23157" +checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", +] + +[[package]] +name = "alloy-rpc-engine-types" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "alloy-rpc-types", + "jsonrpsee-types", + "serde", + "thiserror", +] + +[[package]] +name = "alloy-rpc-trace-types" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e" +dependencies = [ + "alloy-primitives", + "alloy-rpc-types", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-rpc-types" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "itertools 0.12.1", + "jsonrpsee-types", + "serde", + "serde_json", + "thiserror", ] [[package]] name = "alloy-sol-macro" -version = "0.4.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a98ad1696a2e17f010ae8e43e9f2a1e930ed176a8e3ff77acfeff6dfb07b42c" +checksum = "82e92100dee7fd1e44abbe0ef6607f18758cf0ad4e483f4c65ff5c8d85428a6d" dependencies = [ "const-hex", "dunce", "heck", + "indexmap 2.2.3", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", "syn-solidity", "tiny-keccak", ] [[package]] -name = "alloy-sol-type-parser" -version = "0.4.2" +name = "alloy-sol-types" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81c61ccc29e7c58bf16a2f780898852348183f58b127bde03ced6d07ad544787" +checksum = "3e7c6a8c492b1d6a4f92a8fc6a13cf39473978dd7d459d7221969ce5a73d97cd" dependencies = [ - "winnow", + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", ] [[package]] -name = "alloy-sol-types" -version = "0.4.2" +name = "alloy-trie" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d7107bed88e8f09f0ddcc3335622d87bfb6821f3e0c7473329fb1cfad5e015" +checksum = "6b9e1498416f7e7f09af8061970e14936846b6271e153aa5ba539a22a7eb414d" dependencies = [ "alloy-primitives", - "alloy-sol-macro", - "const-hex", + "alloy-rlp", + "derive_more", + "hashbrown 0.14.3", + "nybbles", "serde", + "smallvec", + "tracing", ] [[package]] @@ -247,9 +271,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -261,66 +285,63 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "aquamarine" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df752953c49ce90719c7bf1fc587bc8227aed04732ea0c0f85e5397d7fdbd1a1" +checksum = "21cc1548309245035eb18aa7f0967da6bc65587005170c56e6ef2788a4cf3f4e" dependencies = [ "include_dir", "itertools 0.10.5", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.52", ] [[package]] name = "arbitrary" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859" -dependencies = [ - "derive_arbitrary", -] +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" [[package]] name = "ark-ff" @@ -452,70 +473,26 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" -[[package]] -name = "async-compression" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f658e2baef915ba0f26f1f7c42bfb8e12f532a01f449a090ded75ae7a07e9ba2" -dependencies = [ - "brotli", - "flate2", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", - "zstd 0.13.0", - "zstd-safe 7.0.0", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener", -] - [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", -] - -[[package]] -name = "atomic-polyfill" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" -dependencies = [ - "critical-section", -] - -[[package]] -name = "atomic-polyfill" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" -dependencies = [ - "critical-section", + "syn 2.0.52", ] [[package]] name = "attohttpc" -version = "0.16.3" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb8867f378f33f78a811a8eb9bf108ad99430d7aad43315dd9319c827ef6247" +checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" dependencies = [ "http", "log", "url", - "wildmatch", ] [[package]] @@ -530,14 +507,13 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.52", ] [[package]] @@ -546,18 +522,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backon" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c1a6197b2120bb2185a267f6515038558b019e92b832bb0320e96d66268dcf9" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "pin-project", - "tokio", -] - [[package]] name = "backtrace" version = "0.3.69" @@ -581,15 +545,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -617,72 +575,29 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.64.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 1.0.109", -] - -[[package]] -name = "bindgen" -version = "0.66.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" -dependencies = [ - "bitflags 2.4.1", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.38", - "which", -] - -[[package]] -name = "bindgen" -version = "0.68.1" +version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cexpr", "clang-sys", + "itertools 0.12.1", "lazy_static", "lazycell", - "peeking_take_while", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] name = "binout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "288c7b1c00556959bb7dc822d8adad4a30edd0d3a1fcc6839515792b8f300e5f" +checksum = "b60b1af88a588fca5fe424ae7d735bc52814f80ff57614f57043cc4e2024f2ea" [[package]] name = "bit-set" @@ -707,19 +622,18 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" dependencies = [ - "arbitrary", "serde", ] [[package]] name = "bitm" -version = "0.2.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7becd9fb525c1c507eb025ec37129a0d9320aee17c841085a48101f4f18c0d27" +checksum = "31b9ea263f0faf826a1c9de0e8bf8f32f5986c05f5e3abcf6bcde74616009586" dependencies = [ "dyn_size_of", ] @@ -737,15 +651,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -777,234 +682,59 @@ dependencies = [ ] [[package]] -name = "boa_ast" -version = "0.17.3" +name = "bumpalo" +version = "3.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73498e9b2f0aa7db74977afa4d594657611e90587abf0dd564c0b55b4a130163" -dependencies = [ - "bitflags 2.4.1", - "boa_interner", - "boa_macros", - "indexmap 2.0.2", - "num-bigint", - "rustc-hash", -] +checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" [[package]] -name = "boa_engine" -version = "0.17.3" +name = "byte-slice-cast" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16377479d5d6d33896e7acdd1cc698d04a8f72004025bbbddf47558cd29146a6" -dependencies = [ - "bitflags 2.4.1", - "boa_ast", - "boa_gc", - "boa_icu_provider", - "boa_interner", - "boa_macros", - "boa_parser", - "boa_profiler", - "chrono", - "dashmap", - "fast-float", - "icu_normalizer", - "indexmap 2.0.2", - "itertools 0.11.0", - "num-bigint", - "num-integer", - "num-traits", - "num_enum 0.6.1", - "once_cell", - "pollster", - "rand 0.8.5", - "regress", - "rustc-hash", - "ryu-js", - "serde", - "serde_json", - "sptr", - "static_assertions", - "tap", - "thin-vec", - "thiserror", -] +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] -name = "boa_gc" -version = "0.17.3" +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c97b44beaef9d4452342d117d94607fdfa8d474280f1ba0fd97853834e3a49b2" -dependencies = [ - "boa_macros", - "boa_profiler", - "thin-vec", -] +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] -name = "boa_icu_provider" -version = "0.17.3" +name = "bytes" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30e52e34e451dd0bfc2c654a9a43ed34b0073dbd4ae3394b40313edda8627aa" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ - "icu_collections", - "icu_normalizer", - "icu_properties", - "icu_provider", - "icu_provider_adapters", - "icu_provider_blob", - "once_cell", + "serde", ] [[package]] -name = "boa_interner" -version = "0.17.3" +name = "c-kzg" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e5afa991908cfbe79bd3109b824e473a1dc5f74f31fab91bb44c9e245daa77" +checksum = "94a4bc5367b6284358d2a6a6a1dc2d92ec4b86034561c3b9d3341909752fd848" dependencies = [ - "boa_gc", - "boa_macros", - "hashbrown 0.14.2", - "indexmap 2.0.2", - "once_cell", - "phf", - "rustc-hash", - "static_assertions", + "blst", + "cc", + "glob", + "hex", + "libc", + "serde", ] [[package]] -name = "boa_macros" -version = "0.17.3" +name = "cc" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005fa0c5bd20805466dda55eb34cd709bb31a2592bb26927b47714eeed6914d8" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", - "synstructure", + "jobserver", + "libc", ] [[package]] -name = "boa_parser" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e09afb035377a9044443b598187a7d34cd13164617182a4d7c348522ee3f052" -dependencies = [ - "bitflags 2.4.1", - "boa_ast", - "boa_icu_provider", - "boa_interner", - "boa_macros", - "boa_profiler", - "fast-float", - "icu_locid", - "icu_properties", - "icu_provider", - "icu_provider_macros", - "num-bigint", - "num-traits", - "once_cell", - "regress", - "rustc-hash", - "tinystr", -] - -[[package]] -name = "boa_profiler" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190f92dfe48224adc92881c620f08ccf37ff62b91a094bb357fe53bd5e84647" - -[[package]] -name = "boyer-moore-magiclen" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "116d76fee857b03ecdd95d5f9555e46aa0cd34e5bb348a520e9445d151182a7e" -dependencies = [ - "debug-helper", -] - -[[package]] -name = "brotli" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" -dependencies = [ - "serde", -] - -[[package]] -name = "c-kzg" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac926d808fb72fe09ebf471a091d6d72918876ccf0b4989766093d2d0d24a0ef" -dependencies = [ - "bindgen 0.66.1", - "blst", - "cc", - "glob", - "hex", - "libc", - "serde", -] - -[[package]] -name = "cassowary" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "jobserver", - "libc", -] - -[[package]] -name = "cexpr" -version = "0.6.0" +name = "cexpr" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ @@ -1019,9 +749,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1029,7 +759,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.4", ] [[package]] @@ -1053,9 +783,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ "glob", "libc", @@ -1064,9 +794,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.7" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" dependencies = [ "clap_builder", "clap_derive", @@ -1074,51 +804,45 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.10.0", + "strsim 0.11.0", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - -[[package]] -name = "cobs" -version = "0.2.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "codecs-derive" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ "convert_case 0.6.0", "parity-scale-codec", "proc-macro2", "quote", "serde", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -1127,53 +851,24 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" -[[package]] -name = "comfy-table" -version = "7.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" -dependencies = [ - "crossterm 0.27.0", - "strum", - "strum_macros", - "unicode-width", -] - -[[package]] -name = "confy" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37668cb35145dcfaa1931a5f37fde375eeae8068b4c0d2f289da28a270b2d2c" -dependencies = [ - "directories", - "serde", - "thiserror", - "toml 0.5.11", -] - [[package]] name = "const-hex" -version = "1.9.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c37be52ef5e3b394db27a2341010685ad5103c72ac15ce2e9420a7e8f93f342c" +checksum = "efbd12d49ab0eaf8193ba9175e45f56bbc2e4b27d57b8cfe62aa47942a46b9a9" dependencies = [ "cfg-if", "cpufeatures", "hex", + "proptest", "serde", ] [[package]] name = "const-oid" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" - -[[package]] -name = "const-str" -version = "0.5.6" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aca749d3d3f5b87a0d6100509879f9cf486ab510803a4a4e1001da1ff61c2bd6" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "convert_case" @@ -1190,27 +885,17 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -1226,108 +911,43 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "critical-section" -version = "1.1.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossterm" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" -dependencies = [ - "bitflags 1.3.2", - "crossterm_winapi", - "libc", - "mio", - "parking_lot 0.12.1", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" -dependencies = [ - "bitflags 2.4.1", - "crossterm_winapi", - "libc", - "mio", - "parking_lot 0.12.1", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm_winapi" -version = "0.9.1" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" -dependencies = [ - "winapi", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crunchy" @@ -1337,9 +957,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -1400,9 +1020,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ "cfg-if", "cpufeatures", @@ -1417,13 +1037,13 @@ dependencies = [ [[package]] name = "curve25519-dalek-derive" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -1438,12 +1058,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.20.8", + "darling_macro 0.20.8", ] [[package]] @@ -1462,16 +1082,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -1487,13 +1107,13 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ - "darling_core 0.20.3", + "darling_core 0.20.8", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -1503,7 +1123,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.2", + "hashbrown 0.14.3", "lock_api", "once_cell", "parking_lot_core 0.9.9", @@ -1511,15 +1131,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" - -[[package]] -name = "debug-helper" -version = "0.3.13" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "delay_map" @@ -1543,9 +1157,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", "serde", @@ -1562,17 +1176,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_arbitrary" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] - [[package]] name = "derive_builder" version = "0.9.0" @@ -1611,12 +1214,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - [[package]] name = "digest" version = "0.9.0" @@ -1632,74 +1229,12 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "const-oid", "crypto-common", "subtle", ] -[[package]] -name = "directories" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" -dependencies = [ - "dirs-sys 0.3.7", -] - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys 0.4.1", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "discv5" version = "0.3.1" @@ -1716,7 +1251,7 @@ dependencies = [ "hex", "hkdf", "lazy_static", - "lru 0.12.0", + "lru", "more-asserts", "parking_lot 0.11.2", "rand 0.8.5", @@ -1730,17 +1265,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "displaydoc" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] - [[package]] name = "dns-lookup" version = "1.0.8" @@ -1759,23 +1283,17 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" -[[package]] -name = "dyn-clone" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" - [[package]] name = "dyn_size_of" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8adcce29eef18ae1369bbd268fd56bf98144e80281315e9d4a82e34df001c7" +checksum = "33d4f78a40b1ec35bf8cafdaaf607ba2f773c366b0b3bda48937cacd7a8d5134" [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", "digest 0.10.7", @@ -1797,15 +1315,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", "rand_core 0.6.4", "serde", "sha2", + "subtle", "zeroize", ] @@ -1823,15 +1342,15 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "elliptic-curve" -version = "0.13.6" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -1846,12 +1365,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "embedded-io" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" - [[package]] name = "endian-type" version = "0.1.2" @@ -1864,7 +1377,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" dependencies = [ - "base64 0.21.5", + "base64", "bytes", "ed25519-dalek", "hex", @@ -1890,18 +1403,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "enum-as-inner" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.38", -] - [[package]] name = "enum-ordinalize" version = "3.1.15" @@ -1912,18 +1413,18 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] name = "enumn" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ad8cef1d801a4686bfd8919f0b30eac4c8e48968c437a6405ded4fb5272d2b" +checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -1934,66 +1435,24 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] - -[[package]] -name = "errno" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - [[package]] name = "eyre" -version = "0.6.8" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", ] -[[package]] -name = "fast-float" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - [[package]] name = "fastrand" version = "2.0.1" @@ -2011,15 +1470,6 @@ dependencies = [ "bytes", ] -[[package]] -name = "fdlimit" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4c9e43643f5a3be4ca5b67d26b98031ff9db6806c3440ae32e02e3ceac3f1b" -dependencies = [ - "libc", -] - [[package]] name = "ff" version = "0.13.0" @@ -2032,9 +1482,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.1" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" +checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" [[package]] name = "fixed-hash" @@ -2048,16 +1498,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "flate2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -2066,9 +1506,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -2081,9 +1521,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -2096,9 +1536,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -2106,15 +1546,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -2123,48 +1563,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" - -[[package]] -name = "futures-timer" -version = "3.0.2" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" -dependencies = [ - "gloo-timers", - "send_wrapper", -] +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -2202,9 +1632,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -2223,9 +1653,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" @@ -2233,52 +1663,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "gloo-net" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ac9e8288ae2c632fa9f8657ac70bfe38a1530f345282d7ba66a1f70b72b7dc4" -dependencies = [ - "futures-channel", - "futures-core", - "futures-sink", - "gloo-utils", - "http", - "js-sys", - "pin-project", - "serde", - "serde_json", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-utils" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" -dependencies = [ - "js-sys", - "serde", - "serde_json", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "group" version = "0.13.0" @@ -2292,9 +1676,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -2302,22 +1686,13 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.2.3", "slab", "tokio", "tokio-util", "tracing", ] -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -2326,18 +1701,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "allocator-api2", @@ -2350,31 +1716,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.2", -] - -[[package]] -name = "hdrhistogram" -version = "7.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" -dependencies = [ - "byteorder", - "num-traits", -] - -[[package]] -name = "heapless" -version = "0.7.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" -dependencies = [ - "atomic-polyfill 0.1.11", - "hash32", - "rustc_version 0.4.0", - "serde", - "spin 0.9.8", - "stable_deref_trait", + "hashbrown 0.14.3", ] [[package]] @@ -2385,9 +1727,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" [[package]] name = "hex" @@ -2406,9 +1748,9 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac", ] @@ -2422,31 +1764,11 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi", -] - [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -2455,21 +1777,15 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", "pin-project-lite", ] -[[package]] -name = "http-range-header" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" - [[package]] name = "httparse" version = "1.8.0" @@ -2482,33 +1798,11 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "human_bytes" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91f255a4535024abf7640cb288260811fc14794f62b063652ed349f9a6c2348e" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "humantime-serde" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" -dependencies = [ - "humantime", - "serde", -] - [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -2521,29 +1815,13 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2 0.5.6", "tokio", "tower-service", "tracing", "want", ] -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http", - "hyper", - "log", - "rustls", - "rustls-native-certs", - "tokio", - "tokio-rustls", -] - [[package]] name = "hyper-system-resolver" version = "0.5.0" @@ -2560,9 +1838,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2582,197 +1860,83 @@ dependencies = [ ] [[package]] -name = "icu_collections" -version = "1.2.0" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8302d8dfd6044d3ddb3f807a5ef3d7bbca9a574959c6d6e4dc39aa7012d0d5" -dependencies = [ - "displaydoc", - "serde", - "yoke", - "zerofrom", - "zerovec", -] +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "icu_locid" -version = "1.2.0" +name = "idna" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3003f85dccfc0e238ff567693248c59153a46f4e6125ba4020b973cef4d1d335" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ - "displaydoc", - "litemap", - "serde", - "tinystr", - "writeable", - "zerovec", + "matches", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "icu_normalizer" -version = "1.2.0" +name = "idna" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "652869735c9fb9f5a64ba180ee16f2c848390469c116deef517ecc53f4343598" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "displaydoc", - "icu_collections", - "icu_properties", - "icu_provider", - "serde", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "icu_properties" -version = "1.2.0" +name = "igd-next" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce0e1aa26851f16c9e04412a5911c86b7f8768dac8f8d4c5f1c568a7e5d7a434" +checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" dependencies = [ - "displaydoc", - "icu_collections", - "icu_provider", - "serde", - "tinystr", - "zerovec", + "async-trait", + "attohttpc", + "bytes", + "futures", + "http", + "hyper", + "log", + "rand 0.8.5", + "tokio", + "url", + "xmltree", ] [[package]] -name = "icu_provider" -version = "1.2.0" +name = "impl-codec" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dc312a7b6148f7dfe098047ae2494d12d4034f48ade58d4f353000db376e305" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "postcard", - "serde", - "stable_deref_trait", - "writeable", - "yoke", - "zerofrom", - "zerovec", + "parity-scale-codec", ] [[package]] -name = "icu_provider_adapters" -version = "1.2.0" +name = "impl-trait-for-tuples" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ae1e2bd0c41728b77e7c46e9afdec5e2127d1eedacc684724667d50c126bd3" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "icu_locid", - "icu_provider", - "serde", - "tinystr", - "yoke", - "zerovec", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "icu_provider_blob" -version = "1.2.0" +name = "include_dir" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd364c9a01f791a4bc04a74cf2a1d01d9f6926a40fd5ae1c28004e1e70d8338b" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" dependencies = [ - "icu_provider", - "postcard", - "serde", - "writeable", - "yoke", - "zerovec", + "include_dir_macros", ] [[package]] -name = "icu_provider_macros" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b728b9421e93eff1d9f8681101b78fa745e0748c95c655c83f337044a7e10" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "igd" -version = "0.12.0" -source = "git+https://github.com/stevefan1999-personal/rust-igd?rev=c2d1f83eb1612a462962453cb0703bc93258b173#c2d1f83eb1612a462962453cb0703bc93258b173" -dependencies = [ - "attohttpc", - "bytes", - "futures", - "http", - "hyper", - "log", - "rand 0.8.5", - "tokio", - "url", - "xmltree", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "include_dir" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" -dependencies = [ - "include_dir_macros", -] - -[[package]] -name = "include_dir_macros" -version = "0.7.3" +name = "include_dir_macros" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" dependencies = [ @@ -2799,12 +1963,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown 0.14.3", "serde", ] @@ -2827,45 +1991,12 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "ipconfig" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" -dependencies = [ - "socket2 0.5.5", - "widestring", - "windows-sys 0.48.0", - "winreg", -] - [[package]] name = "ipnet" version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" -[[package]] -name = "iri-string" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21859b667d66a4c1dacd9df0863b3efb65785474255face87f5bca39dd8407c0" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "itertools" version = "0.10.5" @@ -2877,191 +2008,37 @@ dependencies = [ [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" - -[[package]] -name = "jemalloc-ctl" -version = "0.5.4" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cffc705424a344c054e135d12ee591402f4539245e8bbd64e6c9eaa9458b63c" -dependencies = [ - "jemalloc-sys", - "libc", - "paste", -] - -[[package]] -name = "jemalloc-sys" -version = "0.5.4+5.3.0-patched" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "jemallocator" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0de374a9f8e63150e6f5e8a60cc14c668226d7a347d8aee1a45766e3c4dd3bc" -dependencies = [ - "jemalloc-sys", - "libc", -] +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonrpsee" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" -dependencies = [ - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-http-client", - "jsonrpsee-proc-macros", - "jsonrpsee-server", - "jsonrpsee-types", - "jsonrpsee-wasm-client", - "jsonrpsee-ws-client", - "tokio", - "tracing", -] - -[[package]] -name = "jsonrpsee-client-transport" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935" -dependencies = [ - "futures-channel", - "futures-util", - "gloo-net", - "http", - "jsonrpsee-core", - "pin-project", - "rustls-native-certs", - "soketto", - "thiserror", - "tokio", - "tokio-rustls", - "tokio-util", - "tracing", - "url", - "webpki-roots", -] - -[[package]] -name = "jsonrpsee-core" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" -dependencies = [ - "anyhow", - "async-lock", - "async-trait", - "beef", - "futures-timer", - "futures-util", - "hyper", - "jsonrpsee-types", - "parking_lot 0.12.1", - "rand 0.8.5", - "rustc-hash", - "serde", - "serde_json", - "soketto", - "thiserror", - "tokio", - "tracing", - "wasm-bindgen-futures", -] - -[[package]] -name = "jsonrpsee-http-client" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f80c17f62c7653ce767e3d7288b793dfec920f97067ceb189ebdd3570f2bc20" -dependencies = [ - "async-trait", - "hyper", - "hyper-rustls", - "jsonrpsee-core", - "jsonrpsee-types", - "serde", - "serde_json", - "thiserror", - "tokio", - "tower", - "tracing", - "url", -] - -[[package]] -name = "jsonrpsee-proc-macros" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29110019693a4fa2dbda04876499d098fa16d70eba06b1e6e2b3f1b251419515" -dependencies = [ - "heck", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "jsonrpsee-server" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c39a00449c9ef3f50b84fc00fc4acba20ef8f559f07902244abf4c15c5ab9c" -dependencies = [ - "futures-util", - "http", - "hyper", - "jsonrpsee-core", - "jsonrpsee-types", - "route-recognizer", - "serde", - "serde_json", - "soketto", - "thiserror", - "tokio", - "tokio-stream", - "tokio-util", - "tower", - "tracing", -] - [[package]] name = "jsonrpsee-types" version = "0.20.3" @@ -3076,49 +2053,11 @@ dependencies = [ "tracing", ] -[[package]] -name = "jsonrpsee-wasm-client" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c7cbb3447cf14fd4d2f407c3cc96e6c9634d5440aa1fbed868a31f3c02b27f0" -dependencies = [ - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-types", -] - -[[package]] -name = "jsonrpsee-ws-client" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca9cb3933ccae417eb6b08c3448eb1cb46e39834e5b503e395e5e5bd08546c0" -dependencies = [ - "http", - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-types", - "url", -] - -[[package]] -name = "jsonwebtoken" -version = "8.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" -dependencies = [ - "base64 0.21.5", - "pem", - "ring 0.16.20", - "serde", - "serde_json", - "simple_asn1", -] - [[package]] name = "k256" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa", @@ -3130,20 +2069,30 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-asm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin 0.5.2", + "spin", ] [[package]] @@ -3154,37 +2103,45 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] -name = "libloading" -version = "0.7.4" +name = "libffi" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2" dependencies = [ - "cfg-if", - "winapi", + "libc", + "libffi-sys", ] [[package]] -name = "libm" -version = "0.2.8" +name = "libffi-sys" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c" +dependencies = [ + "cc", +] [[package]] -name = "libproc" -version = "0.13.0" +name = "libloading" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b18cbf29f8ff3542ba22bdce9ac610fcb75d74bb4e2b306b2a2762242025b4f" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ - "bindgen 0.64.0", - "errno 0.2.8", - "libc", + "cfg-if", + "windows-sys 0.48.0", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "linked-hash-map" version = "0.5.6" @@ -3202,21 +2159,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" - -[[package]] -name = "linux-raw-sys" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" - -[[package]] -name = "litemap" -version = "0.7.1" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2647d5b7134127971a6de0d533c49de2159167e7f259c427195f87168a1" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -3236,51 +2181,18 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lru" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" -dependencies = [ - "hashbrown 0.14.2", -] - -[[package]] -name = "lru" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60" -dependencies = [ - "hashbrown 0.14.2", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" dependencies = [ - "linked-hash-map", + "hashbrown 0.14.3", ] [[package]] name = "lz4_flex" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea9b256699eda7b0387ffbc776dd625e28bde3918446381781245b7a50349d8" - -[[package]] -name = "mach2" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" -dependencies = [ - "libc", -] - -[[package]] -name = "match_cfg" -version = "0.1.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" [[package]] name = "matchers" @@ -3299,9 +2211,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memmap2" @@ -3312,15 +2224,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "metrics" version = "0.21.1" @@ -3332,83 +2235,15 @@ dependencies = [ "portable-atomic", ] -[[package]] -name = "metrics-exporter-prometheus" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a4964177ddfdab1e3a2b37aec7cf320e14169abb0ed73999f558136409178d5" -dependencies = [ - "base64 0.21.5", - "hyper", - "indexmap 1.9.3", - "ipnet", - "metrics", - "metrics-util", - "quanta", - "thiserror", - "tokio", - "tracing", -] - [[package]] name = "metrics-macros" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" +checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", -] - -[[package]] -name = "metrics-process" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c93f6ad342d3f7bc14724147e2dbc6eb6fdbe5a832ace16ea23b73618e8cc17" -dependencies = [ - "libproc", - "mach2", - "metrics", - "once_cell", - "procfs", - "rlimit", - "windows", -] - -[[package]] -name = "metrics-util" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "111cb375987443c3de8d503580b536f77dc8416d32db62d9456db5d93bd7ac47" -dependencies = [ - "aho-corasick 0.7.20", - "crossbeam-epoch", - "crossbeam-utils", - "hashbrown 0.13.2", - "indexmap 1.9.3", - "metrics", - "num_cpus", - "ordered-float", - "quanta", - "radix_trie", - "sketches-ddsketch", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", + "syn 2.0.52", ] [[package]] @@ -3419,21 +2254,20 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.9" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -3517,33 +2351,37 @@ dependencies = [ "autocfg", "num-integer", "num-traits", - "serde", ] [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" dependencies = [ "autocfg", "num-integer", @@ -3564,9 +2402,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -3584,73 +2422,52 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive 0.6.1", -] - -[[package]] -name = "num_enum" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" -dependencies = [ - "num_enum_derive 0.7.0", -] - -[[package]] -name = "num_enum_derive" -version = "0.6.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.38", + "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] -name = "num_threads" -version = "0.1.6" +name = "nybbles" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +checksum = "95f06be0417d97f81fe4e5c86d7d01b392655a9cac9c19a848aa033e18937b23" dependencies = [ - "libc", + "alloy-rlp", + "const-hex", + "proptest", + "serde", + "smallvec", ] [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" -dependencies = [ - "atomic-polyfill 1.0.3", - "critical-section", -] +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -3658,27 +2475,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "ordered-float" -version = "3.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" -dependencies = [ - "num-traits", -] - [[package]] name = "overload" version = "0.1.1" @@ -3697,9 +2493,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" dependencies = [ "arrayvec", "bitvec", @@ -3712,28 +2508,14 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "parity-tokio-ipc" -version = "0.9.0" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ - "futures", - "libc", - "log", - "rand 0.7.3", - "tokio", - "winapi", + "proc-macro-crate 2.0.0", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -3790,32 +2572,17 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "pem" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" -dependencies = [ - "base64 0.13.1", -] - [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.5" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" dependencies = [ "memchr", "thiserror", @@ -3824,9 +2591,9 @@ dependencies = [ [[package]] name = "ph" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c6e62e083483e2812a9d2a6eff6b97871302ef4166b5182c6da30624b7e991" +checksum = "86b7b74d575d7c11fb653fae69688be5206cafc1ead33c01ce61ac7f36eae45b" dependencies = [ "binout", "bitm", @@ -3835,66 +2602,24 @@ dependencies = [ "wyhash", ] -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_macros", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" -dependencies = [ - "phf_shared", - "rand 0.8.5", -] - -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn 2.0.38", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" -dependencies = [ - "siphasher", -] - [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -3921,21 +2646,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "platforms" -version = "3.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" - -[[package]] -name = "pollster" -version = "0.3.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "polyval" @@ -3951,21 +2670,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b559898e0b4931ed2d3b959ab0c2da4d99cc644c4b0b1a35b4d344027f474023" - -[[package]] -name = "postcard" -version = "1.0.8" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" -dependencies = [ - "cobs", - "embedded-io", - "heapless", - "serde", -] +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" [[package]] name = "powerfmt" @@ -3979,26 +2686,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "pretty_assertions" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" -dependencies = [ - "diff", - "yansi", -] - -[[package]] -name = "prettyplease" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" -dependencies = [ - "proc-macro2", - "syn 2.0.38", -] - [[package]] name = "primitive-types" version = "0.12.2" @@ -4012,12 +2699,20 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", ] [[package]] @@ -4046,57 +2741,33 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] -[[package]] -name = "procfs" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943ca7f9f29bab5844ecd8fdb3992c5969b6622bb9609b9502fef9b4310e3f1f" -dependencies = [ - "bitflags 1.3.2", - "byteorder", - "hex", - "lazy_static", - "rustix 0.36.16", -] - [[package]] name = "proptest" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.1", + "bitflags 2.4.2", "lazy_static", "num-traits", "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", "rusty-fork", "tempfile", "unarray", ] -[[package]] -name = "proptest-derive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf16337405ca084e9c78985114633b6827711d22b9e6ef6c6c0d665eb3f0b6e" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "public-ip" version = "0.2.2" @@ -4115,23 +2786,7 @@ dependencies = [ "tracing", "tracing-futures", "trust-dns-client", - "trust-dns-proto 0.20.4", -] - -[[package]] -name = "quanta" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" -dependencies = [ - "crossbeam-utils", - "libc", - "mach2", - "once_cell", - "raw-cpuid", - "wasi 0.11.0+wasi-snapshot-preview1", - "web-sys", - "winapi", + "trust-dns-proto", ] [[package]] @@ -4142,9 +2797,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -4224,7 +2879,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", ] [[package]] @@ -4245,20 +2900,11 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "raw-cpuid" -version = "10.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "rayon" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" dependencies = [ "either", "rayon-core", @@ -4266,9 +2912,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -4283,15 +2929,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -4301,26 +2938,15 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom 0.2.10", - "redox_syscall 0.2.16", - "thiserror", -] - [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ - "aho-corasick 1.1.2", + "aho-corasick", "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.5", "regex-syntax 0.8.2", ] @@ -4335,207 +2961,35 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ - "aho-corasick 1.1.2", + "aho-corasick", "memchr", "regex-syntax 0.8.2", ] [[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "regress" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a9ecfa0cb04d0b04dddb99b8ccf4f66bc8dfd23df694b398570bd8ae3a50fb" -dependencies = [ - "hashbrown 0.13.2", - "memchr", -] - -[[package]] -name = "resolv-conf" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" -dependencies = [ - "hostname", - "quick-error", -] - -[[package]] -name = "reth" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "alloy-rlp", - "aquamarine", - "backon", - "boyer-moore-magiclen", - "clap", - "comfy-table", - "confy", - "const-str", - "crossterm 0.27.0", - "dirs-next", - "eyre", - "fdlimit", - "futures", - "human_bytes", - "humantime", - "hyper", - "itertools 0.11.0", - "jemalloc-ctl", - "jemallocator", - "metrics", - "metrics-exporter-prometheus", - "metrics-process", - "metrics-util", - "pin-project", - "pretty_assertions", - "proptest", - "rand 0.8.5", - "reth-auto-seal-consensus", - "reth-basic-payload-builder", - "reth-beacon-consensus", - "reth-blockchain-tree", - "reth-config", - "reth-consensus-common", - "reth-db", - "reth-discv4", - "reth-downloaders", - "reth-interfaces", - "reth-metrics", - "reth-net-nat", - "reth-network", - "reth-network-api", - "reth-nippy-jar", - "reth-payload-builder", - "reth-primitives", - "reth-provider", - "reth-prune", - "reth-revm", - "reth-revm-inspectors", - "reth-rpc", - "reth-rpc-api", - "reth-rpc-builder", - "reth-rpc-engine-api", - "reth-rpc-types", - "reth-rpc-types-compat", - "reth-snapshot", - "reth-stages", - "reth-tasks", - "reth-tracing", - "reth-transaction-pool", - "reth-trie", - "secp256k1 0.27.0", - "serde", - "serde_json", - "shellexpand", - "tempfile", - "thiserror", - "tokio", - "toml 0.8.5", - "tracing", - "tui", - "vergen", -] - -[[package]] -name = "reth-auto-seal-consensus" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "futures-util", - "reth-beacon-consensus", - "reth-interfaces", - "reth-primitives", - "reth-provider", - "reth-revm", - "reth-stages", - "reth-transaction-pool", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "reth-basic-payload-builder" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "alloy-rlp", - "futures-core", - "futures-util", - "metrics", - "reth-interfaces", - "reth-metrics", - "reth-payload-builder", - "reth-primitives", - "reth-provider", - "reth-revm", - "reth-tasks", - "reth-transaction-pool", - "revm", - "tokio", - "tracing", -] - -[[package]] -name = "reth-beacon-consensus" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "futures", - "metrics", - "reth-consensus-common", - "reth-db", - "reth-interfaces", - "reth-metrics", - "reth-payload-builder", - "reth-primitives", - "reth-provider", - "reth-prune", - "reth-rpc-types", - "reth-rpc-types-compat", - "reth-snapshot", - "reth-stages", - "reth-tasks", - "reth-tokio-util", - "schnellru", - "thiserror", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] name = "reth-blockchain-tree" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ "aquamarine", "linked_hash_set", - "lru 0.11.1", + "lru", "metrics", "parking_lot 0.12.1", "reth-db", @@ -4544,46 +2998,28 @@ dependencies = [ "reth-primitives", "reth-provider", "reth-stages", + "reth-trie", "tokio", "tracing", ] [[package]] name = "reth-codecs" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "arbitrary", + "alloy-primitives", "bytes", "codecs-derive", - "proptest", - "proptest-derive", - "revm-primitives", -] - -[[package]] -name = "reth-config" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "confy", - "reth-discv4", - "reth-downloaders", - "reth-net-nat", - "reth-network", - "reth-primitives", - "reth-stages", - "secp256k1 0.27.0", - "serde", - "serde_json", - "tempfile", ] [[package]] name = "reth-consensus-common" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ + "alloy-chains", + "cfg-if", "reth-interfaces", "reth-primitives", "reth-provider", @@ -4591,27 +3027,19 @@ dependencies = [ [[package]] name = "reth-db" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "arbitrary", "bytes", "derive_more", "eyre", - "futures", - "heapless", - "itertools 0.11.0", "metrics", "modular-bitfield", + "once_cell", "page_size", "parity-scale-codec", "parking_lot 0.12.1", "paste", - "postcard", - "proptest", - "proptest-derive", - "rand 0.8.5", - "rayon", "reth-codecs", "reth-interfaces", "reth-libmdbx", @@ -4619,17 +3047,16 @@ dependencies = [ "reth-nippy-jar", "reth-primitives", "reth-tracing", + "rustc-hash", "serde", - "tempfile", + "strum", "thiserror", - "tokio-stream", - "vergen", ] [[package]] name = "reth-discv4" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ "alloy-rlp", "discv5", @@ -4648,61 +3075,12 @@ dependencies = [ "tracing", ] -[[package]] -name = "reth-dns-discovery" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "alloy-rlp", - "async-trait", - "data-encoding", - "enr", - "linked_hash_set", - "parking_lot 0.12.1", - "reth-net-common", - "reth-primitives", - "schnellru", - "secp256k1 0.27.0", - "serde", - "serde_with", - "thiserror", - "tokio", - "tokio-stream", - "tracing", - "trust-dns-resolver", -] - -[[package]] -name = "reth-downloaders" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "alloy-rlp", - "futures", - "futures-util", - "itertools 0.11.0", - "metrics", - "pin-project", - "rayon", - "reth-db", - "reth-interfaces", - "reth-metrics", - "reth-primitives", - "reth-tasks", - "tempfile", - "thiserror", - "tokio", - "tokio-stream", - "tokio-util", - "tracing", -] - [[package]] name = "reth-ecies" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "aes 0.8.3", + "aes 0.8.4", "alloy-rlp", "block-padding", "byteorder", @@ -4730,12 +3108,13 @@ dependencies = [ [[package]] name = "reth-eth-wire" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ + "alloy-chains", "alloy-rlp", - "async-trait", "bytes", + "derive_more", "futures", "metrics", "pin-project", @@ -4753,82 +3132,68 @@ dependencies = [ "tracing", ] +[[package]] +name = "reth-ethereum-forks" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" +dependencies = [ + "alloy-chains", + "alloy-primitives", + "alloy-rlp", + "crc", + "serde", + "thiserror", +] + [[package]] name = "reth-interfaces" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "async-trait", "auto_impl", - "clap", "futures", - "modular-bitfield", - "parity-scale-codec", - "parking_lot 0.12.1", - "rand 0.8.5", - "reth-codecs", "reth-eth-wire", "reth-network-api", "reth-nippy-jar", "reth-primitives", "reth-rpc-types", - "revm-primitives", - "secp256k1 0.27.0", - "thiserror", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "reth-ipc" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "async-trait", - "bytes", - "futures", - "jsonrpsee", - "parity-tokio-ipc", - "pin-project", - "serde_json", "thiserror", "tokio", - "tokio-stream", - "tokio-util", - "tower", "tracing", ] [[package]] name = "reth-libmdbx" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "byteorder", + "dashmap", "derive_more", - "indexmap 2.0.2", + "indexmap 2.2.3", "libc", + "libffi", "parking_lot 0.12.1", "reth-mdbx-sys", "thiserror", + "tracing", ] [[package]] name = "reth-mdbx-sys" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "bindgen 0.68.1", + "bindgen", "cc", "libc", ] [[package]] name = "reth-metrics" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ "futures", "metrics", @@ -4839,20 +3204,20 @@ dependencies = [ [[package]] name = "reth-metrics-derive" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ "once_cell", "proc-macro2", "quote", "regex", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] name = "reth-net-common" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ "pin-project", "reth-primitives", @@ -4861,10 +3226,10 @@ dependencies = [ [[package]] name = "reth-net-nat" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "igd", + "igd-next", "pin-project-lite", "public-ip", "serde_with", @@ -4873,54 +3238,12 @@ dependencies = [ "tracing", ] -[[package]] -name = "reth-network" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "alloy-rlp", - "aquamarine", - "async-trait", - "auto_impl", - "enr", - "fnv", - "futures", - "humantime-serde", - "linked-hash-map", - "linked_hash_set", - "metrics", - "parking_lot 0.12.1", - "pin-project", - "rand 0.8.5", - "reth-discv4", - "reth-dns-discovery", - "reth-ecies", - "reth-eth-wire", - "reth-interfaces", - "reth-metrics", - "reth-net-common", - "reth-network-api", - "reth-primitives", - "reth-provider", - "reth-rpc-types", - "reth-tasks", - "reth-tokio-util", - "reth-transaction-pool", - "secp256k1 0.27.0", - "serde", - "serde_json", - "thiserror", - "tokio", - "tokio-stream", - "tokio-util", - "tracing", -] - [[package]] name = "reth-network-api" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ + "alloy-chains", "async-trait", "reth-discv4", "reth-eth-wire", @@ -4932,329 +3255,147 @@ dependencies = [ ] [[package]] -name = "reth-nippy-jar" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "anyhow", - "bincode", - "bytes", - "cuckoofilter", - "hex", - "lz4_flex", - "memmap2", - "ph", - "serde", - "sucds 0.8.1", - "tempfile", - "thiserror", - "tracing", - "tracing-appender", - "zstd 0.12.4", -] - -[[package]] -name = "reth-payload-builder" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "alloy-rlp", - "futures-util", - "metrics", - "reth-interfaces", - "reth-metrics", - "reth-primitives", - "reth-rpc-types", - "reth-rpc-types-compat", - "reth-transaction-pool", - "revm-primitives", - "sha2", - "thiserror", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "reth-primitives" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "alloy-sol-types", - "arbitrary", - "byteorder", - "bytes", - "c-kzg", - "clap", - "crc", - "derive_more", - "itertools 0.11.0", - "modular-bitfield", - "num_enum 0.7.0", - "once_cell", - "proptest", - "proptest-derive", - "rayon", - "reth-codecs", - "revm", - "revm-primitives", - "secp256k1 0.27.0", - "serde", - "serde_json", - "serde_with", - "sha2", - "strum", - "sucds 0.6.0", - "tempfile", - "thiserror", - "tracing", - "url", - "zstd 0.12.4", -] - -[[package]] -name = "reth-provider" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "alloy-rlp", - "auto_impl", - "itertools 0.11.0", - "parking_lot 0.12.1", - "pin-project", - "rayon", - "reth-db", - "reth-interfaces", - "reth-nippy-jar", - "reth-primitives", - "reth-trie", - "revm", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "reth-prune" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "itertools 0.11.0", - "metrics", - "rayon", - "reth-db", - "reth-interfaces", - "reth-metrics", - "reth-primitives", - "reth-provider", - "reth-snapshot", - "reth-tokio-util", - "thiserror", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "reth-revm" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +name = "reth-nippy-jar" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "reth-consensus-common", - "reth-interfaces", - "reth-primitives", - "reth-provider", - "reth-revm-inspectors", - "revm", + "anyhow", + "bincode", + "cuckoofilter", + "derive_more", + "lz4_flex", + "memmap2", + "ph", + "serde", + "sucds 0.8.1", + "thiserror", "tracing", + "zstd", ] [[package]] -name = "reth-revm-inspectors" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +name = "reth-node-api" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "alloy-sol-types", - "boa_engine", - "boa_gc", "reth-primitives", "reth-rpc-types", "revm", + "revm-primitives", "serde", - "serde_json", "thiserror", - "tokio", ] [[package]] -name = "reth-rpc" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +name = "reth-primitives" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "alloy-dyn-abi", + "alloy-chains", + "alloy-eips", + "alloy-genesis", "alloy-primitives", "alloy-rlp", - "alloy-sol-types", - "async-trait", + "alloy-trie", + "byteorder", "bytes", + "c-kzg", + "cfg-if", "derive_more", - "futures", - "http", - "http-body", - "hyper", - "jsonrpsee", - "jsonwebtoken", - "lazy_static", - "metrics", - "pin-project", - "rand 0.8.5", + "itertools 0.12.1", + "modular-bitfield", + "num_enum", + "nybbles", + "once_cell", "rayon", - "reth-consensus-common", - "reth-interfaces", - "reth-metrics", - "reth-network-api", - "reth-primitives", - "reth-provider", - "reth-revm", - "reth-rpc-api", - "reth-rpc-engine-api", + "reth-codecs", + "reth-ethereum-forks", "reth-rpc-types", - "reth-rpc-types-compat", - "reth-tasks", - "reth-transaction-pool", "revm", "revm-primitives", - "schnellru", "secp256k1 0.27.0", "serde", "serde_json", + "sha2", + "strum", + "sucds 0.6.0", + "tempfile", "thiserror", - "tokio", - "tokio-stream", - "tokio-util", - "tower", "tracing", - "tracing-futures", -] - -[[package]] -name = "reth-rpc-api" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "jsonrpsee", - "reth-primitives", - "reth-rpc-types", - "serde_json", + "zstd", ] [[package]] -name = "reth-rpc-builder" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +name = "reth-provider" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "hyper", - "jsonrpsee", + "auto_impl", + "dashmap", + "itertools 0.12.1", "metrics", + "parking_lot 0.12.1", + "pin-project", + "rayon", + "reth-db", "reth-interfaces", - "reth-ipc", "reth-metrics", - "reth-network-api", + "reth-nippy-jar", + "reth-node-api", "reth-primitives", - "reth-provider", - "reth-rpc", - "reth-rpc-api", - "reth-rpc-engine-api", - "reth-rpc-types", - "reth-rpc-types-compat", - "reth-tasks", - "reth-transaction-pool", - "serde", + "reth-trie", + "revm", "strum", - "thiserror", - "tower", - "tower-http", + "tokio", + "tokio-stream", "tracing", ] [[package]] -name = "reth-rpc-engine-api" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +name = "reth-revm" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ - "async-trait", - "jsonrpsee-core", - "jsonrpsee-types", - "metrics", - "reth-beacon-consensus", + "reth-consensus-common", "reth-interfaces", - "reth-metrics", - "reth-payload-builder", + "reth-node-api", "reth-primitives", "reth-provider", - "reth-rpc-api", - "reth-rpc-types", - "reth-rpc-types-compat", - "reth-tasks", - "serde", - "thiserror", - "tokio", + "revm", + "revm-inspectors", "tracing", ] [[package]] name = "reth-rpc-types" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ "alloy-primitives", "alloy-rlp", - "itertools 0.11.0", + "alloy-rpc-engine-types", + "alloy-rpc-trace-types", + "alloy-rpc-types", + "bytes", + "itertools 0.12.1", "jsonrpsee-types", - "reth-primitives", + "secp256k1 0.27.0", "serde", "serde_json", "serde_with", "thiserror", -] - -[[package]] -name = "reth-rpc-types-compat" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "alloy-rlp", - "reth-primitives", - "reth-rpc-types", -] - -[[package]] -name = "reth-snapshot" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "clap", - "reth-db", - "reth-interfaces", - "reth-nippy-jar", - "reth-primitives", - "reth-provider", - "thiserror", - "tokio", - "tracing", + "url", ] [[package]] name = "reth-stages" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ "aquamarine", - "async-trait", + "auto_impl", "futures-util", - "itertools 0.11.0", + "itertools 0.12.1", "metrics", "num-traits", "pin-project", @@ -5275,25 +3416,10 @@ dependencies = [ "tracing", ] -[[package]] -name = "reth-tasks" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "dyn-clone", - "futures-util", - "metrics", - "reth-metrics", - "thiserror", - "tokio", - "tracing", - "tracing-futures", -] - [[package]] name = "reth-tokio-util" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ "tokio", "tokio-stream", @@ -5301,58 +3427,33 @@ dependencies = [ [[package]] name = "reth-tracing" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ + "clap", + "eyre", "rolling-file", "tracing", "tracing-appender", "tracing-journald", + "tracing-logfmt", "tracing-subscriber", ] -[[package]] -name = "reth-transaction-pool" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" -dependencies = [ - "alloy-rlp", - "aquamarine", - "async-trait", - "auto_impl", - "bitflags 2.4.1", - "fnv", - "futures-util", - "metrics", - "parking_lot 0.12.1", - "paste", - "rand 0.8.5", - "reth-interfaces", - "reth-metrics", - "reth-primitives", - "reth-provider", - "reth-tasks", - "revm", - "serde", - "thiserror", - "tokio", - "tokio-stream", - "tracing", -] - [[package]] name = "reth-trie" -version = "0.1.0-alpha.10" -source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +version = "0.1.0-alpha.21" +source = "git+https://github.com/paradigmxyz/reth.git?rev=e0c220e#e0c220efef09dd5732e69d1da5c79bc52e0b5424" dependencies = [ + "alloy-chains", "alloy-rlp", "auto_impl", "derive_more", "reth-db", "reth-interfaces", "reth-primitives", + "revm", "thiserror", - "tokio", "tracing", ] @@ -5360,34 +3461,61 @@ dependencies = [ name = "rethdb-reader" version = "0.1.0" dependencies = [ + "alloy-rlp", "anyhow", - "reth", + "reth-blockchain-tree", + "reth-db", + "reth-primitives", + "reth-provider", + "reth-revm", + "reth-rpc-types", "serde", "serde_json", ] [[package]] name = "revm" -version = "3.5.0" -source = "git+https://github.com/bluealloy/revm?rev=0d78d1eb304a2ce41ddac8f03206f5a316af247b#0d78d1eb304a2ce41ddac8f03206f5a316af247b" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d35316fc02d99e42831356c71e882f5d385c77b78f64a44ae82f2f9a4b8b72f" dependencies = [ "auto_impl", + "cfg-if", "revm-interpreter", "revm-precompile", + "serde", + "serde_json", +] + +[[package]] +name = "revm-inspectors" +version = "0.1.0" +source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=75a187b#75a187ba967a29b30af2e5e848073c755068da06" +dependencies = [ + "alloy-primitives", + "alloy-rpc-trace-types", + "alloy-rpc-types", + "alloy-sol-types", + "anstyle", + "colorchoice", + "revm", ] [[package]] name = "revm-interpreter" -version = "1.3.0" -source = "git+https://github.com/bluealloy/revm?rev=0d78d1eb304a2ce41ddac8f03206f5a316af247b#0d78d1eb304a2ce41ddac8f03206f5a316af247b" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fa10c2dc1e8f4934bdc763a2c09371bcec29e50c22e55e3eb325ee0cba09064" dependencies = [ "revm-primitives", + "serde", ] [[package]] name = "revm-precompile" -version = "2.2.0" -source = "git+https://github.com/bluealloy/revm?rev=0d78d1eb304a2ce41ddac8f03206f5a316af247b#0d78d1eb304a2ce41ddac8f03206f5a316af247b" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db828d49d329560a70809d9d1fa0c74695edb49f50c5332db3eb24483076deac" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -5395,25 +3523,26 @@ dependencies = [ "once_cell", "revm-primitives", "ripemd", - "secp256k1 0.28.0", + "secp256k1 0.28.2", "sha2", "substrate-bn", ] [[package]] name = "revm-primitives" -version = "1.3.0" -source = "git+https://github.com/bluealloy/revm?rev=0d78d1eb304a2ce41ddac8f03206f5a316af247b#0d78d1eb304a2ce41ddac8f03206f5a316af247b" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fecd125aad58e135e2ca5771ed6e4e7b1f05fa3a64e0dfb9cc643b7a800a8435" dependencies = [ "alloy-primitives", - "alloy-rlp", "auto_impl", - "bitflags 2.4.1", + "bitflags 2.4.2", "bitvec", "c-kzg", + "cfg-if", "derive_more", "enumn", - "hashbrown 0.14.2", + "hashbrown 0.14.3", "hex", "once_cell", "serde", @@ -5429,35 +3558,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - -[[package]] -name = "ring" -version = "0.17.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" -dependencies = [ - "cc", - "getrandom 0.2.10", - "libc", - "spin 0.9.8", - "untrusted 0.9.0", - "windows-sys 0.48.0", -] - [[package]] name = "ripemd" version = "0.1.3" @@ -5467,15 +3567,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "rlimit" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3560f70f30a0f16d11d01ed078a07740fe6b489667abc7c7b029155d9f21c3d8" -dependencies = [ - "libc", -] - [[package]] name = "rlp" version = "0.5.2" @@ -5495,25 +3586,19 @@ dependencies = [ "chrono", ] -[[package]] -name = "route-recognizer" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" - [[package]] name = "ruint" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95294d6e3a6192f3aabf91c38f56505a625aa495533442744185a36d75a790c4" +checksum = "49b1d9521f889713d1221270fdd63370feca7e5c71a18745343402fa86e4f04f" dependencies = [ "alloy-rlp", - "arbitrary", "ark-ff 0.3.0", "ark-ff 0.4.2", "bytes", "fastrlp", "num-bigint", + "num-traits", "parity-scale-codec", "primitive-types", "proptest", @@ -5527,9 +3612,9 @@ dependencies = [ [[package]] name = "ruint-macro" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" +checksum = "f86854cf50259291520509879a5c294c3c9a4c334e9ff65071c51e42ef1e2343" [[package]] name = "rustc-demangle" @@ -5553,88 +3638,31 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" name = "rustc_version" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver 1.0.20", -] - -[[package]] -name = "rustix" -version = "0.36.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6da3636faa25820d8648e0e31c5d519bbb01f72fdf57131f0f5f7da5fed36eab" -dependencies = [ - "bitflags 1.3.2", - "errno 0.3.5", - "io-lifetimes", - "libc", - "linux-raw-sys 0.1.4", - "windows-sys 0.45.0", -] - -[[package]] -name = "rustix" -version = "0.38.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" -dependencies = [ - "bitflags 2.4.1", - "errno 0.3.5", - "libc", - "linux-raw-sys 0.4.10", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustls" -version = "0.21.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" -dependencies = [ - "log", - "ring 0.17.5", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-native-certs" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" dependencies = [ - "openssl-probe", - "rustls-pemfile", - "schannel", - "security-framework", + "semver 0.11.0", ] [[package]] -name = "rustls-pemfile" -version = "1.0.3" +name = "rustc_version" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "base64 0.21.5", + "semver 1.0.22", ] [[package]] -name = "rustls-webpki" -version = "0.101.7" +name = "rustix" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "ring 0.17.5", - "untrusted 0.9.0", + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", ] [[package]] @@ -5657,35 +3685,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" - -[[package]] -name = "ryu-js" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6518fc26bced4d53678a22d6e423e9d8716377def84545fe328236e3af070e7f" - -[[package]] -name = "schannel" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "schnellru" -version = "0.2.1" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" -dependencies = [ - "ahash", - "cfg-if", - "hashbrown 0.13.2", -] +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "scopeguard" @@ -5693,16 +3695,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring 0.17.5", - "untrusted 0.9.0", -] - [[package]] name = "sec1" version = "0.7.3" @@ -5730,11 +3722,11 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.28.0" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acea373acb8c21ecb5a23741452acd2593ed44ee3d343e72baaa143bc89d0d5" +checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" dependencies = [ - "secp256k1-sys 0.9.0", + "secp256k1-sys 0.9.2", ] [[package]] @@ -5748,36 +3740,13 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.9.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09e67c467c38fd24bd5499dc9a18183b31575c12ee549197e3e20d57aa4fe3b7" +checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" dependencies = [ "cc", ] -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "semver" version = "0.11.0" @@ -5789,9 +3758,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "semver-parser" @@ -5802,73 +3771,60 @@ dependencies = [ "pest", ] -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - [[package]] name = "serde" -version = "1.0.190" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ + "indexmap 2.2.3", "itoa", "ryu", "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" -dependencies = [ - "serde", -] - [[package]] name = "serde_with" -version = "3.4.0" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +checksum = "15d167997bd841ec232f5b2b8e0e26606df2e7caa4c31b95ea9ca52b200bd270" dependencies = [ - "base64 0.21.5", + "base64", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.0.2", + "indexmap 2.2.3", "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -5876,27 +3832,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.4.0" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +checksum = "865f9743393e638991566a8b7a479043c2c8da94a33e0a31f18214c9cae0a64d" dependencies = [ - "darling 0.20.3", + "darling 0.20.8", "proc-macro2", "quote", - "syn 2.0.38", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "syn 2.0.52", ] [[package]] @@ -5921,49 +3864,29 @@ dependencies = [ ] [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "sha3-asm" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" dependencies = [ - "lazy_static", + "cc", + "cfg-if", ] [[package]] -name = "shellexpand" -version = "3.1.0" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ - "dirs", + "lazy_static", ] [[package]] name = "shlex" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" - -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.3" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" -dependencies = [ - "libc", - "mio", - "signal-hook", -] +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" @@ -5976,38 +3899,14 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", ] -[[package]] -name = "simple_asn1" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror", - "time", -] - -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "sketches-ddsketch" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a406c1882ed7f29cd5e248c9848a80e7cb6ae0fea82346d2746f2f941c07e1" - [[package]] name = "slab" version = "0.4.9" @@ -6019,24 +3918,18 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" - -[[package]] -name = "smol_str" -version = "0.2.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" dependencies = [ "serde", ] [[package]] name = "snap" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "socket2" @@ -6050,28 +3943,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "soketto" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" -dependencies = [ - "base64 0.13.1", - "bytes", - "futures", - "http", - "httparse", - "log", - "rand 0.8.5", - "sha-1", + "windows-sys 0.52.0", ] [[package]] @@ -6080,37 +3957,16 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", ] -[[package]] -name = "sptr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "static_assertions" version = "1.1.0" @@ -6129,26 +3985,32 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + [[package]] name = "strum" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -6202,9 +4064,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -6213,26 +4075,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.4.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b837ef12ab88835251726eb12237655e61ec8dc8a280085d1961cdc3dfd047" +checksum = "e656cbcef8a77543b5accbd76f60f9e0bc4be364b0aba4263a6f313f8a355511" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.38", -] - -[[package]] -name = "synstructure" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "285ba80e733fac80aa4270fbcdf83772a79b80aa35c97075320abfee4a915b06" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", - "unicode-xid", + "syn 2.0.52", ] [[package]] @@ -6243,48 +4093,41 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.1", - "redox_syscall 0.3.5", - "rustix 0.38.20", - "windows-sys 0.48.0", + "fastrand", + "rustix", + "windows-sys 0.52.0", ] -[[package]] -name = "thin-vec" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aac81b6fd6beb5884b0cf3321b8117e6e5d47ecb6fc89f414cfdcca8b2fe2dd8" - [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -6301,14 +4144,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", - "libc", - "num_threads", + "num-conv", "powerfmt", "serde", "time-core", @@ -6323,10 +4165,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] @@ -6339,17 +4182,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "tinystr" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8faa444297615a4e020acb64146b0603c9c395c03a97c17fd9028816d3b4d63e" -dependencies = [ - "displaydoc", - "serde", - "zerovec", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -6367,9 +4199,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -6379,30 +4211,20 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2 0.5.6", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", + "syn 2.0.52", ] [[package]] @@ -6425,7 +4247,6 @@ checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", - "futures-io", "futures-sink", "pin-project-lite", "slab", @@ -6433,117 +4254,34 @@ dependencies = [ "tracing", ] -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3efaf127c78d5339cc547cce4e4d973bd5e4f56e949a06d091c082ebeef2f800" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.20.5", -] - [[package]] name = "toml_datetime" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" -dependencies = [ - "serde", -] [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.2.3", "toml_datetime", "winnow", ] [[package]] name = "toml_edit" -version = "0.20.5" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "782bf6c2ddf761c1e7855405e8975472acf76f7f36d0d4328bd3b7a2fae12a85" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.0.2", - "serde", - "serde_spanned", + "indexmap 2.2.3", "toml_datetime", "winnow", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "hdrhistogram", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand 0.8.5", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" -dependencies = [ - "async-compression", - "base64 0.21.5", - "bitflags 2.4.1", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "httpdate", - "iri-string", - "mime", - "mime_guess", - "percent-encoding", - "pin-project-lite", - "tokio", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "uuid", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - [[package]] name = "tower-service" version = "0.3.2" @@ -6564,11 +4302,12 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", + "thiserror", "time", "tracing-subscriber", ] @@ -6581,7 +4320,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -6619,31 +4358,56 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ "log", "once_cell", "tracing-core", ] +[[package]] +name = "tracing-logfmt" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84bab42e40ace4e4ff19c92023ee1dbc1510db60976828fbbdc6994852c7d065" +dependencies = [ + "time", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", "nu-ansi-term", "once_cell", "regex", + "serde", + "serde_json", "sharded-slab", "smallvec", "thread_local", "tracing", "tracing-core", "tracing-log", + "tracing-serde", ] [[package]] @@ -6663,7 +4427,7 @@ dependencies = [ "thiserror", "time", "tokio", - "trust-dns-proto 0.20.4", + "trust-dns-proto", ] [[package]] @@ -6675,7 +4439,7 @@ dependencies = [ "async-trait", "cfg-if", "data-encoding", - "enum-as-inner 0.3.4", + "enum-as-inner", "futures-channel", "futures-io", "futures-util", @@ -6691,70 +4455,11 @@ dependencies = [ "url", ] -[[package]] -name = "trust-dns-proto" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner 0.6.0", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.4.0", - "ipnet", - "once_cell", - "rand 0.8.5", - "smallvec", - "thiserror", - "tinyvec", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" -dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lru-cache", - "once_cell", - "parking_lot 0.12.1", - "rand 0.8.5", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "tracing", - "trust-dns-proto 0.23.2", -] - [[package]] name = "try-lock" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" - -[[package]] -name = "tui" -version = "0.19.0" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1" -dependencies = [ - "bitflags 1.3.2", - "cassowary", - "crossterm 0.25.0", - "unicode-segmentation", - "unicode-width", -] +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" @@ -6786,20 +4491,11 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" -[[package]] -name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -6809,30 +4505,18 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - -[[package]] -name = "unicode-xid" -version = "0.2.4" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "universal-hash" @@ -6844,73 +4528,29 @@ dependencies = [ "subtle", ] -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna 0.4.0", + "idna 0.5.0", "percent-encoding", ] -[[package]] -name = "utf16_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52df8b7fb78e7910d776fccf2e42ceaf3604d55e8e7eb2dbd183cb1441d8a692" - -[[package]] -name = "utf8_iter" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a8922555b9500e3d865caed19330172cd67cbf82203f1a3311d8c305cc9f33" - [[package]] name = "utf8parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "uuid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" -dependencies = [ - "getrandom 0.2.10", -] - [[package]] name = "valuable" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "vergen" -version = "8.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e7dc29b3c54a2ea67ef4f953d5ec0c4085035c0ae2d325be1c0d2144bd9f16" -dependencies = [ - "anyhow", - "rustversion", - "time", -] - [[package]] name = "version_check" version = "0.9.4" @@ -6949,9 +4589,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -6959,36 +4599,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6996,62 +4624,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" - -[[package]] -name = "web-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.20", -] - -[[package]] -name = "widestring" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" - -[[package]] -name = "wildmatch" -version = "1.1.0" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "winapi" @@ -7075,32 +4663,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" -dependencies = [ - "windows-core", - "windows-targets 0.48.5", -] - [[package]] name = "windows-core" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.42.2", + "windows-targets 0.52.4", ] [[package]] @@ -7113,18 +4682,12 @@ dependencies = [ ] [[package]] -name = "windows-targets" -version = "0.42.2" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.52.4", ] [[package]] @@ -7143,10 +4706,19 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" +name = "windows-targets" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] [[package]] name = "windows_aarch64_gnullvm" @@ -7155,10 +4727,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +name = "windows_aarch64_gnullvm" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -7167,10 +4739,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "windows_i686_gnu" -version = "0.42.2" +name = "windows_aarch64_msvc" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -7179,10 +4751,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnu" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -7191,10 +4763,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +name = "windows_i686_msvc" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -7203,10 +4775,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +name = "windows_x86_64_gnu" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -7215,10 +4787,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +name = "windows_x86_64_gnullvm" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -7227,36 +4799,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] -name = "winnow" -version = "0.5.17" +name = "windows_x86_64_msvc" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" -dependencies = [ - "memchr", -] +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] -name = "winreg" -version = "0.50.0" +name = "winnow" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ - "cfg-if", - "windows-sys 0.48.0", + "memchr", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - -[[package]] -name = "writeable" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0af0c3d13faebf8dda0b5256fa7096a2d5ccb662f7b9f54a40fe201077ab1c2" - [[package]] name = "wyhash" version = "0.5.0" @@ -7290,82 +4846,31 @@ dependencies = [ "xml-rs", ] -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - -[[package]] -name = "yoke" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e38c508604d6bbbd292dadb3c02559aa7fff6b654a078a36217cad871636e4" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5e19fb6ed40002bab5403ffa37e53e0e56f914a4450c8765f533018db1db35f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", - "synstructure", -] - [[package]] name = "zerocopy" -version = "0.7.15" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81ba595b9f2772fbee2312de30eeb80ec773b4cb2f1e8098db024afadda6c06f" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772666c41fb6dceaf520b564b962d738a8e1a83b41bd48945f50837aed78bb1d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] - -[[package]] -name = "zerofrom" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655b0814c5c0b19ade497851070c640773304939a6c0fd5f5fb43da0696d05b7" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.3" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", - "synstructure", + "syn 2.0.52", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] @@ -7378,30 +4883,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", -] - -[[package]] -name = "zerovec" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "591691014119b87047ead4dcf3e6adfbf73cb7c38ab6980d4f18a32138f35d46" -dependencies = [ - "serde", - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a4a1638a1934450809c2266a70362bfc96cd90550c073f5b8a55014d1010157" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -7410,16 +4892,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" dependencies = [ - "zstd-safe 6.0.6", -] - -[[package]] -name = "zstd" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" -dependencies = [ - "zstd-safe 7.0.0", + "zstd-safe", ] [[package]] @@ -7432,15 +4905,6 @@ dependencies = [ "zstd-sys", ] -[[package]] -name = "zstd-safe" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" -dependencies = [ - "zstd-sys", -] - [[package]] name = "zstd-sys" version = "2.0.9+zstd.1.5.5" diff --git a/op-service/rethdb-reader/Cargo.toml b/op-service/rethdb-reader/Cargo.toml index c73662970ad1..16bbc7325b7f 100644 --- a/op-service/rethdb-reader/Cargo.toml +++ b/op-service/rethdb-reader/Cargo.toml @@ -9,7 +9,18 @@ name = "rethdbreader" crate-type = ["cdylib"] [dependencies] -reth = { git = "https://github.com/paradigmxyz/reth.git" } -serde = "1.0.190" -serde_json = "1.0.107" -anyhow = "1.0.75" +# reth +reth-primitives = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } +reth-provider = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } +reth-db = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } +reth-rpc-types = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } +reth-blockchain-tree = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } + +# misc +serde = "1.0.197" +serde_json = "1.0.114" +anyhow = "1.0.80" + +[dev-dependencies] +reth-revm = { git = "https://github.com/paradigmxyz/reth.git", rev = "e0c220e" } +alloy-rlp = "0.3.4" diff --git a/op-service/rethdb-reader/Makefile b/op-service/rethdb-reader/Makefile new file mode 100644 index 000000000000..6e9037bdfe5b --- /dev/null +++ b/op-service/rethdb-reader/Makefile @@ -0,0 +1,8 @@ +.PHONY: testdata +testdata: + mkdir -p testdata + @echo "Fetching block RLP and receipts for block #18,663,292 from ethereum mainnet" + cast rpc debug_getRawBlock 0x11CC77C | jq -r | xxd -r -p > testdata/block.rlp + cast rpc debug_getRawReceipts 0x11CC77C | jq -r > testdata/receipts.json + @echo "Done. Generating testdata DB & testing integrity..." + cargo test diff --git a/op-service/rethdb-reader/README.md b/op-service/rethdb-reader/README.md index 2ef313ef413e..30469a58b294 100644 --- a/op-service/rethdb-reader/README.md +++ b/op-service/rethdb-reader/README.md @@ -27,6 +27,14 @@ cargo doc --open cargo +nightly fmt -- && cargo +nightly clippy --all --all-features -- -D warnings ``` +**Generating `testdata`** + +The testdata block and `reth` database can be generated by running the `testdata` make directive: + +```sh +ETH_RPC_URL="" make testdata +``` + **Generating the C header** To generate the C header, first install `cbindgen` via `cargo install cbindgen --force`. Then, run the generation script: diff --git a/op-service/rethdb-reader/rustfmt.toml b/op-service/rethdb-reader/rustfmt.toml new file mode 100644 index 000000000000..68c3c93033d4 --- /dev/null +++ b/op-service/rethdb-reader/rustfmt.toml @@ -0,0 +1,11 @@ +reorder_imports = true +imports_granularity = "Crate" +use_small_heuristics = "Max" +comment_width = 100 +wrap_comments = true +binop_separator = "Back" +trailing_comma = "Vertical" +trailing_semicolon = false +use_field_init_shorthand = true +format_code_in_doc_comments = true +doc_comment_code_block_width = 100 diff --git a/op-service/rethdb-reader/src/lib.rs b/op-service/rethdb-reader/src/lib.rs index 20aabb1f1391..46f545ed7397 100644 --- a/op-service/rethdb-reader/src/lib.rs +++ b/op-service/rethdb-reader/src/lib.rs @@ -8,8 +8,8 @@ mod receipts; /// Read the receipts for a blockhash from the RETH database directly. /// /// # Safety -/// - All possible nil pointer dereferences are checked, and the function will return a -/// failing [ReceiptsResult] if any are found. +/// - All possible nil pointer dereferences are checked, and the function will return a failing +/// [ReceiptsResult] if any are found. #[no_mangle] pub unsafe extern "C" fn rdb_read_receipts( block_hash: *const u8, diff --git a/op-service/rethdb-reader/src/receipts.rs b/op-service/rethdb-reader/src/receipts.rs index 3f17daff74bd..3e10900ef6e5 100644 --- a/op-service/rethdb-reader/src/receipts.rs +++ b/op-service/rethdb-reader/src/receipts.rs @@ -2,16 +2,14 @@ //! [reth] database. use anyhow::{anyhow, Result}; -use reth::{ - blockchain_tree::noop::NoopBlockchainTree, - primitives::{ - BlockHashOrNumber, Receipt, TransactionKind, TransactionMeta, TransactionSigned, MAINNET, - U128, U256, U64, - }, - providers::{providers::BlockchainProvider, BlockReader, ProviderFactory, ReceiptProvider}, - rpc::types::{Log, TransactionReceipt}, - utils::db::open_db_read_only, +use reth_blockchain_tree::noop::NoopBlockchainTree; +use reth_db::{mdbx::DatabaseArguments, open_db_read_only}; +use reth_primitives::{ + BlockHashOrNumber, Receipt, TransactionKind, TransactionMeta, TransactionSigned, MAINNET, U128, + U256, U64, }; +use reth_provider::{providers::BlockchainProvider, BlockReader, ProviderFactory, ReceiptProvider}; +use reth_rpc_types::{Log, TransactionReceipt}; use std::{ffi::c_char, path::Path}; /// A [ReceiptsResult] is a wrapper around a JSON string containing serialized [TransactionReceipt]s @@ -30,28 +28,20 @@ pub struct ReceiptsResult { impl ReceiptsResult { /// Constructs a successful [ReceiptsResult] from a JSON string. pub fn success(data: *mut char, data_len: usize) -> Self { - Self { - data, - data_len, - error: false, - } + Self { data, data_len, error: false } } /// Constructs a failing [ReceiptsResult] with a null pointer to the data. pub fn fail() -> Self { - Self { - data: std::ptr::null_mut(), - data_len: 0, - error: true, - } + Self { data: std::ptr::null_mut(), data_len: 0, error: true } } } /// Read the receipts for a blockhash from the RETH database directly. /// /// # Safety -/// - All possible nil pointer dereferences are checked, and the function will return a -/// failing [ReceiptsResult] if any are found. +/// - All possible nil pointer dereferences are checked, and the function will return a failing +/// [ReceiptsResult] if any are found. #[inline(always)] pub(crate) unsafe fn read_receipts_inner( block_hash: *const u8, @@ -76,16 +66,16 @@ pub(crate) unsafe fn read_receipts_inner( } .to_str()?; - let db = open_db_read_only(Path::new(db_path_str), None).map_err(|e| anyhow!(e))?; + let db = open_db_read_only(Path::new(db_path_str), DatabaseArguments::default()) + .map_err(|e| anyhow!(e))?; let factory = ProviderFactory::new(db, MAINNET.clone()); // Create a read-only BlockChainProvider let provider = BlockchainProvider::new(factory, NoopBlockchainTree::default())?; // Fetch the block and the receipts within it - let block = provider - .block_by_hash(block_hash.into())? - .ok_or(anyhow!("Failed to fetch block"))?; + let block = + provider.block_by_hash(block_hash.into())?.ok_or(anyhow!("Failed to fetch block"))?; let receipts = provider .receipts_by_block(BlockHashOrNumber::Hash(block_hash.into()))? .ok_or(anyhow!("Failed to fetch block receipts"))?; @@ -165,15 +155,14 @@ fn build_transaction_receipt_with_block_receipts( // TODO pre-byzantium receipts have a post-transaction state root state_root: None, logs_bloom: receipt.bloom_slow(), - status_code: if receipt.success { - Some(U64::from(1)) - } else { - Some(U64::from(0)) - }, + status_code: if receipt.success { Some(U64::from(1)) } else { Some(U64::from(0)) }, // EIP-4844 fields blob_gas_price: None, blob_gas_used: None, + + // Other: + other: Default::default(), }; match tx.transaction.kind() { @@ -209,3 +198,147 @@ fn build_transaction_receipt_with_block_receipts( Some(res_receipt) } + +#[cfg(test)] +mod test { + use super::*; + use alloy_rlp::Decodable; + use reth_db::{database::Database, mdbx::DatabaseArguments}; + use reth_primitives::{ + address, b256, bloom, hex, Address, Block, Bytes, ReceiptWithBloom, Receipts, + SealedBlockWithSenders, U8, + }; + use reth_provider::{BlockWriter, BundleStateWithReceipts, DatabaseProvider}; + use reth_revm::revm::db::BundleState; + use std::{ffi::CString, fs::File, path::Path}; + + #[inline] + fn dummy_block_with_receipts() -> Result<(Block, Vec)> { + // To generate testdata (block 18,663,292 on Ethereum Mainnet): + // 1. BLOCK RLP: `cast rpc debug_getRawBlock 0x11CC77C | jq -r | xxd -r -p > + // testdata/block.rlp` + // 2. RECEIPTS RLP: `cast rpc debug_getRawReceipts 0x11CC77C | jq -r > + // testdata/receipts.json` + let block_rlp = include_bytes!("../testdata/block.rlp"); + let block = Block::decode(&mut block_rlp.as_ref())?; + + let receipt_rlp: Vec> = serde_json::from_str(include_str!( + "../testdata/receipts.json" + )) + .map(|v: Vec| { + v.into_iter().map(|s| hex::decode(s)).collect::>, _>>() + })??; + let receipts = receipt_rlp + .iter() + .map(|r| ReceiptWithBloom::decode(&mut r.as_slice()).map(|r| r.receipt)) + .collect::, _>>()?; + + Ok((block, receipts)) + } + + #[inline] + fn open_receipts_testdata_db() -> Result<()> { + if File::open("testdata/db").is_ok() { + return Ok(()); + } + + // Open a RW handle to the MDBX database + let db = reth_db::init_db(Path::new("testdata/db"), DatabaseArguments::default()) + .map_err(|e| anyhow!(e))?; + let pr = DatabaseProvider::new_rw(db.tx_mut()?, MAINNET.clone()); + + // Grab the dummy block and receipts + let (mut block, receipts) = dummy_block_with_receipts()?; + + // Patch: The block's current state root expects the rest of the chain history to be in the + // DB; manually override it. Otherwise, the DatabaseProvider will fail to commit the + // block. + block.header.state_root = reth_primitives::constants::EMPTY_ROOT_HASH; + + // Fetch the block number and tx senders for bundle state creation. + let block_number = block.header.number; + let senders = block + .body + .iter() + .map(|tx| tx.recover_signer()) + .collect::>>() + .ok_or(anyhow!("Failed to recover signers"))?; + + // Commit the bundle state to the database + pr.append_blocks_with_state( + vec![SealedBlockWithSenders { block: block.seal_slow(), senders }], + BundleStateWithReceipts::new( + BundleState::default(), + Receipts::from_block_receipt(receipts), + block_number, + ), + Default::default(), + Default::default(), + None, + )?; + pr.commit()?; + + Ok(()) + } + + #[test] + fn fetch_receipts() { + open_receipts_testdata_db().unwrap(); + + unsafe { + let mut block_hash = + b256!("6a229123d607c2232a8b0bdd36f90745945d05181018e64e60ff2b93ab6b52e5"); + let receipts_res = super::read_receipts_inner( + block_hash.as_mut_ptr(), + 32, + CString::new("testdata/db").unwrap().into_raw() as *const c_char, + ) + .unwrap(); + + let receipts_data = + std::slice::from_raw_parts(receipts_res.data as *const u8, receipts_res.data_len); + let receipt = { + let mut receipts: Vec = + serde_json::from_slice(receipts_data).unwrap(); + receipts.remove(0) + }; + + // Check the first receipt in the block for validity + assert_eq!(receipt.transaction_type, U8::from(2)); + assert_eq!(receipt.status_code, Some(U64::from(1))); + assert_eq!(receipt.cumulative_gas_used, U256::from(115_316)); + assert_eq!(receipt.logs_bloom, bloom!("00200000000000000000000080001000000000000000000000000000000000000000000000000000000000000000100002000100080000000000000000000000000000000000000000000008000000200000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000400000000000001000000000000000100000000080000004000000000000000000000000000000000000002000000000000000000000000000000000000000006000000000000000000000000000000000000001000000000000000000000200000000000000100000000020000000000000000000000000000000010")); + assert_eq!( + receipt.logs[0].address, + address!("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2") + ); + assert_eq!( + receipt.logs[0].topics[0], + b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") + ); + assert_eq!( + receipt.logs[0].topics[1], + b256!("00000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40") + ); + assert_eq!( + receipt.logs[0].data, + Bytes::from_static( + hex!("00000000000000000000000000000000000000000000000008a30cd230000000") + .as_slice() + ) + ); + assert_eq!(receipt.from, address!("41d3ab85aafed2ef9e644cb7d3bbca2fc4d8cac8")); + assert_eq!(receipt.to, Some(address!("00000000003b3cc22af3ae1eac0440bcee416b40"))); + assert_eq!( + receipt.transaction_hash, + Some(b256!("88b2d153a4e893ba91ac235325c44b1aa0c802fcb42657701e1a73e1c675f7ca")) + ); + + assert_eq!(receipt.block_number, Some(U256::from(18_663_292))); + assert_eq!(receipt.block_hash, Some(block_hash)); + assert_eq!(receipt.transaction_index, U64::from(0)); + + crate::rdb_free_string(receipts_res.data as *mut c_char); + } + } +} diff --git a/op-service/rethdb-reader/testdata/block.rlp b/op-service/rethdb-reader/testdata/block.rlp new file mode 100644 index 000000000000..978ba6be01b4 Binary files /dev/null and b/op-service/rethdb-reader/testdata/block.rlp differ diff --git a/op-service/rethdb-reader/testdata/receipts.json b/op-service/rethdb-reader/testdata/receipts.json new file mode 100644 index 000000000000..aef76b0c2eb8 --- /dev/null +++ b/op-service/rethdb-reader/testdata/receipts.json @@ -0,0 +1,12 @@ +[ + "0xb903c202f903be018301c274b9010000200000000000000000000080001000000000000000000000000000000000000000000000000000000000000000100002000100080000000000000000000000000000000000000000000008000000200000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000400000000000001000000000000000100000000080000004000000000000000000000000000000000000002000000000000000000000000000000000000000006000000000000000000000000000000000000001000000000000000000000200000000000000100000000020000000000000000000000000000000010f902b3f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa000000000000000000000000000000000000000000000000008a30cd230000000f89b94d10bc8517059e51b625e1e57a60b348d552f685df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a000000000000000000000000000000000000000000000000000007921e915b684f879945c1694c8168668c11777909c79142dc9d992788fe1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b840000000000000000000000000000000000000000000000001129c9861392306df000000000000000000000000000000000000000000000000000e9d834abd9cdff8fc945c1694c8168668c11777909c79142dc9d992788ff863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40b88000000000000000000000000000000000000000000000000008a30cd2300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007921e915b684", + "0xb9043e02f9043a0183042135b9010000200000000000000000000080001000100000000000000000000000000000000000000000000000000000000000100002000000080000000000000000010000000000000000010000000008000000200000000400100000000000008000000000000000000000000000000000000000000000000000000000000010000000000000000400000000000001000000000000000101000000080000004000000000000000000000000000000000000002000000000000000000000000000000000000000002000000000000000000000000000000000000001000000000000000000000200000000000008000000000020000000000000000400000000000000010f9032ff87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a0e1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109ca00000000000000000000000002ec705d306b51e486b1bc0d6ebee708e0661add1a00000000000000000000000000000000000000000000000000bd0c7ca01c48000f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000002ec705d306b51e486b1bc0d6ebee708e0661add1a00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa00000000000000000000000000000000000000000000000000bd0c7ca01c48000f89b94d10bc8517059e51b625e1e57a60b348d552f685df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa00000000000000000000000001f3c8f19ab956457994de1d50eb0ae7d057f77f8a0000000000000000000000000000000000000000000000000000099e622c10336f879945c1694c8168668c11777909c79142dc9d992788fe1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b8400000000000000000000000000000000000000000000000011e6d602b3ae786df000000000000000000000000000000000000000000000000000e039d27fc99a9f8fc945c1694c8168668c11777909c79142dc9d992788ff863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a00000000000000000000000002ec705d306b51e486b1bc0d6ebee708e0661add1a00000000000000000000000001f3c8f19ab956457994de1d50eb0ae7d057f77f8b8800000000000000000000000000000000000000000000000000bd0c7ca01c4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099e622c10336", + "0xb903c202f903be018305b26fb9010000200000000000000000000080001000000000000000000000000000000000000000000000000000000000000000100002000100080000000000000000000000000000000000000000000008000000200000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000400000000000001000000000000000100000000080000004000000000000000000000000000000000000002000000000000000000000000000000000000000006000000000000000000000000000000000000001000000000000000000000200000000000000100000000020000000000000000000000000000000010f902b3f89b94d10bc8517059e51b625e1e57a60b348d552f685df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa000000000000000000000000000000000000000000000000000007921e99216a0f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000005c1694c8168668c11777909c79142dc9d992788fa000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a00000000000000000000000000000000000000000000000000953f38350000000f879945c1694c8168668c11777909c79142dc9d992788fe1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b84000000000000000000000000000000000000000000000000115196ca7eae786df000000000000000000000000000000000000000000000000000e7cbf118eb049f8fc945c1694c8168668c11777909c79142dc9d992788ff863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40a000000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40b880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007921e99216a00000000000000000000000000000000000000000000000000953f383500000000000000000000000000000000000000000000000000000000000000000000000", + "0xb90bdf02f90bdb01830b2215b9010000200000002000000000000080000000000000000000000001010000000004000000000000000000420000000000010002000000080020002000000000200800000000000000080800000008000000200090000000000000080000408040000000000000000000000008084000000000000000000000000010010050000800000800800000000000000000000000000000000000000000080000004000100000020100000000000000100080000004000000000000020000000000000000000000400002000000000000000000000000000000000000001000000000002000400012200000800000020404000000000000020000008000000000000000000010f90ad0f89b941111111254eeb25477b68fb85ed929f73a960582f842a0b9ed0243fdf00f0545c63a0af8850c090d86bb46682baec4bf3c496814fe4f02a000000000000000000000000058c1c6a484ef2d6b0f8d93b2dbeb72f3c3e9ceb5b8402511106c0eade4c289445ac7275a89e6e088cc2cb5e313a42712b2987c2fb8d30000000000000000000000000000000000000000000000000000000000000001f89b94dac17f958d2ee523a2206206994597c13d831ec7f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000058c1c6a484ef2d6b0f8d93b2dbeb72f3c3e9ceb5a0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa000000000000000000000000000000000000000000000000000000002f0174a58f89b94fe67a4450907459c3e1fff623aa927dd4e28c67af863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000a050f7adc241afa59ad5f343eaf4faf5f30a4cdba0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa000000000000000000000000000000000000000000000143c3719a34f04e020edf89b94dac17f958d2ee523a2206206994597c13d831ec7f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa000000000000000000000000006da0fd433c1a5d7a4faa01111c044910a184553a000000000000000000000000000000000000000000000000000000000da1b3bf5f89b94dac17f958d2ee523a2206206994597c13d831ec7f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa00000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852a00000000000000000000000000000000000000000000000000000000215fc0e63f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000006da0fd433c1a5d7a4faa01111c044910a184553a0000000000000000000000000a050f7adc241afa59ad5f343eaf4faf5f30a4cdba00000000000000000000000000000000000000000000000001913572822ee731ff8799406da0fd433c1a5d7a4faa01111c044910a184553e1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b8400000000000000000000000000000000000000000000000b3986c20be3ddb96f70000000000000000000000000000000000000000000000000000061647f821daf8fc9406da0fd433c1a5d7a4faa01111c044910a184553f863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa0000000000000000000000000a050f7adc241afa59ad5f343eaf4faf5f30a4cdbb880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000da1b3bf50000000000000000000000000000000000000000000000001913572822ee731f0000000000000000000000000000000000000000000000000000000000000000f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852a0000000000000000000000000a050f7adc241afa59ad5f343eaf4faf5f30a4cdba00000000000000000000000000000000000000000000000003d5ec06d1b711bcff879940d4a11d5eeaac28ec3f61d100daf4d40471f1852e1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b8400000000000000000000000000000000000000000000004724d25b9c0c67a0c7800000000000000000000000000000000000000000000000000002694ca870b04f8fc940d4a11d5eeaac28ec3f61d100daf4d40471f1852f863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa0000000000000000000000000a050f7adc241afa59ad5f343eaf4faf5f30a4cdbb88000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000215fc0e630000000000000000000000000000000000000000000000003d5ec06d1b711bcf0000000000000000000000000000000000000000000000000000000000000000f9011c94a050f7adc241afa59ad5f343eaf4faf5f30a4cdbf863a0c42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67a0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781ab8a0000000000000000000000000000000000000000000000000567217953e5f8eeeffffffffffffffffffffffffffffffffffffffffffffebc3c8e65cb0fb1fdf13000000000000000000000000000000000000007b89284efd1b25e6f5f0dcbf2e000000000000000000000000000000000000000000000aa86d459fd0c59c2a59000000000000000000000000000000000000000000000000000000000001784ff89b94fe67a4450907459c3e1fff623aa927dd4e28c67af863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000d1742b3c4fbb096990c8950fa635aec75b30781aa0000000000000000000000000a88800cd213da5ae406ce248380802bd53b47647a0000000000000000000000000000000000000000000001375a0d26e739f71f370f89b94fe67a4450907459c3e1fff623aa927dd4e28c67af863a08c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a0000000000000000000000000a88800cd213da5ae406ce248380802bd53b47647a00000000000000000000000001111111254eeb25477b68fb85ed929f73a960582a0000000000000000000000000000000000000000000001375a0d26e739f71f370f89b94fe67a4450907459c3e1fff623aa927dd4e28c67af863a08c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a0000000000000000000000000a88800cd213da5ae406ce248380802bd53b47647a00000000000000000000000001111111254eeb25477b68fb85ed929f73a960582a00000000000000000000000000000000000000000000000000000000000000000f89b94fe67a4450907459c3e1fff623aa927dd4e28c67af863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000a88800cd213da5ae406ce248380802bd53b47647a000000000000000000000000058c1c6a484ef2d6b0f8d93b2dbeb72f3c3e9ceb5a0000000000000000000000000000000000000000000001375a0d26e739f71f370", + "0xb905cf02f905cb01830e0902b9010000200000008020000000000280004000000000000000000000000000000000000000200000000000000000200080000002000000080000000000000800000000000000000000000100000008040000200004000000000000000000008000004000000000000000000000000000000400240000000000000004000010000000000000000000000000000001010000000200000001000000080000004000000400002000000000004002020000000000000000000000000000002000000000000000000002000000000000000000000040000000000000001000000000000000000000200000000000000000000000000000000001000400400000000080010000f904c0f87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a0e1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109ca0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216a000000000000000000000000000000000000000000000000001617eb90b26c000f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216a0000000000000000000000000e090e0518ea17607a01e9286522655808c3f8919a000000000000000000000000000000000000000000000000001617eb90b26c000f89b94f83e0399fd7ef1c9c1a3dbc0a4d586edc3c8d125f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000e090e0518ea17607a01e9286522655808c3f8919a0000000000000000000000000faa04b4d06297dca749c2ac7783211638de3e491a000000000000000000000000000000000000000000000019d0da576764721e7e7f87994e090e0518ea17607a01e9286522655808c3f8919e1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b8400000000000000000000000000000000000000000000000001e6d6c84d2f7cd2b00000000000000000000000000000000000000000000220ae8d75c1df124f53df8fc94e090e0518ea17607a01e9286522655808c3f8919f863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a0000000000000000000000000c6265979793435b496e28e61af1500c22c3ba277a0000000000000000000000000faa04b4d06297dca749c2ac7783211638de3e491b88000000000000000000000000000000000000000000000000001617eb90b26c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019d0da576764721e7e7f87994db5889e35e379ef0498aae126fc2cce1fbd23216e1a06cb8c9cbcedb37b7d125170f5d929dbbdb3203c8fd4d60356b496fa31f77fd00b8400000000000000000000000000000000000000000000000000001c4793ec69800000000000000000000000000000000000000000000000000000000000000008ef87994db5889e35e379ef0498aae126fc2cce1fbd23216e1a00c2a2f565c7774c59e49ef6b3c255329f4d254147e06e724d3a8569bb7bd21adb8400000000000000000000000000000000000000000000000000001c4793ec69800000000000000000000000000faa04b4d06297dca749c2ac7783211638de3e491f89994db5889e35e379ef0498aae126fc2cce1fbd23216e1a09f849d23f4955d98202378ea318f2b0c7533695d3c9fb2a3931f0f919fa8c420b86000000000000000000000000000000000000000000000000001617eb90b26c00000000000000000000000000000000000000000000000019d0da576764721e7e700000000000000000000000000000000000000000000019d0da576764721e7e7", + "0xf905cb0183105d5cb90100000000000180a0000004000000004000000000000001000000000000002200000000000000000000080200200000000002000000080020000000000800000000000000000000000900000008040000000000000000400000000000000000004000000000000000000000000000000400240000000000040000000010000804000000000000000000000080010000000000000000000000008000000000000480000000000000004002000000000000000000000000000000000000000000008000000002080000000000000000000000000000000000000000000002000000000000200000000000000000000000000000000000000000000000000000010000f904c0f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000009e31efffe1e016f514f774f43d91a85ebbc11564a0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216a00000000000000000000000000000000000000000000000000e803e90becaf29bf89b949dd5f5dae94633760b3125a7490ecb4571d09a42f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000087033ad96757ecd730aa1652b1a7dabcc5ffb182a00000000000000000000000009e31efffe1e016f514f774f43d91a85ebbc11564a0000000000000000000000000000000000000000000acb37f48fe24c23d1833c6f9011c949e31efffe1e016f514f774f43d91a85ebbc11564f863a0c42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67a0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216a0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216b8a0000000000000000000000000000000000000000000acb37f48fe24c23d1833c6fffffffffffffffffffffffffffffffffffffffffffffffff17fc16f41350d65000000000000000000000000000000000000000000049c65546ad3eed1521a58000000000000000000000000000000000000000000009404a8bb774136003dadfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd14eff87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a07fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65a0000000000000000000000000db5889e35e379ef0498aae126fc2cce1fbd23216a00000000000000000000000000000000000000000000000000e803e90becaf29bf87994db5889e35e379ef0498aae126fc2cce1fbd23216e1a06cb8c9cbcedb37b7d125170f5d929dbbdb3203c8fd4d60356b496fa31f77fd00b84000000000000000000000000000000000000000000000000000128fac3e64dad00000000000000000000000000000000000000000000000000000000000000012f87994db5889e35e379ef0498aae126fc2cce1fbd23216e1a00c2a2f565c7774c59e49ef6b3c255329f4d254147e06e724d3a8569bb7bd21adb84000000000000000000000000000000000000000000000000000128fac3e64dad000000000000000000000000087033ad96757ecd730aa1652b1a7dabcc5ffb182f89994db5889e35e379ef0498aae126fc2cce1fbd23216e1a09f849d23f4955d98202378ea318f2b0c7533695d3c9fb2a3931f0f919fa8c420b860000000000000000000000000000000000000000000acb37f48fe24c23d1833c60000000000000000000000000000000000000000000000000e803e90becaf29b0000000000000000000000000000000000000000000000000e803e90becaf29bf85894db5889e35e379ef0498aae126fc2cce1fbd23216e1a0522881958b3c4a6fc0840ad3b7fb947b881edc28c004245a62541647422ade97a00000000000000000000000000000000000000000000000000e803e90becaf29b", + "0xb903e402f903e00183128fdcb9010000000000010000000000000000000000000000000000010000000000040000000000000000000000000008000000000002000000080020000000000000000000000000000000000808000008000000000000000000410000000000000000000000000000000000000000040000000000000000000000040000000010000800000000000000000000200000000000000000000000010000000000000000000000000000000000200000000000010000000000000000000000002000000008000000000002000000000000080000000000000000000000000000000002000000000000200000000000000010000000000000000000000000000000000000000000f902d5f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f5640a00000000000000000000000008e30dead12d19228cf9cdc984f237f0ad00df195a000000000000000000000000000000000000000000000000000b5762b8f483dbff89b94a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000f706190050f8c7d62021d5ba52871640ea9fd3fea000000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f5640a0000000000000000000000000000000000000000000000000000000000629852ff9011c9488e6a0c2ddd26feeb64f039a2c41296fcb3f5640f863a0c42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67a00000000000000000000000008e30dead12d19228cf9cdc984f237f0ad00df195a00000000000000000000000008e30dead12d19228cf9cdc984f237f0ad00df195b8a0000000000000000000000000000000000000000000000000000000000629852fffffffffffffffffffffffffffffffffffffffffffffffffff4a89d470b7c24100000000000000000000000000000000000056d8c2fe7c57e75b18c386394ff90000000000000000000000000000000000000000000000016397a5e7cf05707c0000000000000000000000000000000000000000000000000000000000030e04f87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a07fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65a00000000000000000000000008e30dead12d19228cf9cdc984f237f0ad00df195a000000000000000000000000000000000000000000000000000b5762b8f483dbf", + "0xb901ab02f901a701831345f7b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000200000000000000000000000004000000000008000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000080000000000000008000000000000000000000000000000000000000000000000100000000000000000000010000000000000000000000001000000000000000000000000000000000000f89df89b9496add417293a49e80f024734e96cfd8b355bcc14f863a08c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a0000000000000000000000000af56ec1d3a54e9d05fbe2bc158219a810890dc77a0000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0xb9053d02f90539018315a059b9010000210000000000100000100080000000000000000000000080000000000000000000000000000000000000000000000002010000080000000000000000080000000020080000800000000008000000208000000000400000000000000020000000000000000000000000000000000000000000000000040000000010000000000040004000000000000000000000000000000000000000080000004000000000000000000000000000000000000000000400000000080000000000000008000000000002000000000000000000000000000400400000101000000002000202000000200000000000000000000001000000001000000000000000000000000400f9042ef8fd94000000000022d473030f116ddee9f6b43ac78ba3f884a0c6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708eca0000000000000000000000000af56ec1d3a54e9d05fbe2bc158219a810890dc77a000000000000000000000000096add417293a49e80f024734e96cfd8b355bcc14a00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fadb860000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000658c27210000000000000000000000000000000000000000000000000000000000000000f89b9496add417293a49e80f024734e96cfd8b355bcc14f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000af56ec1d3a54e9d05fbe2bc158219a810890dc77a00000000000000000000000000bee64a7c035fa2f69b9a6cad5d761de038ecb02a000000000000000000000000000000000000000000000000c83b84b800fe98c96f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000000bee64a7c035fa2f69b9a6cad5d761de038ecb02a00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fada000000000000000000000000000000000000000000000000001e7841cb75e9302f879940bee64a7c035fa2f69b9a6cad5d761de038ecb02e1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b840000000000000000000000000000000000000000000004581511bfd43276c16b400000000000000000000000000000000000000000000000a99e131364ae486cff8fc940bee64a7c035fa2f69b9a6cad5d761de038ecb02f863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fada00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fadb88000000000000000000000000000000000000000000000000c83b84b800fe98c960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e7841cb75e9302f87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a07fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65a00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fada000000000000000000000000000000000000000000000000001e7841cb75e9302", + "0xb9010d02f90109018315f261b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0" +] diff --git a/op-service/rpc/api.go b/op-service/rpc/api.go index 6ed8229d92dd..1bea71ad5799 100644 --- a/op-service/rpc/api.go +++ b/op-service/rpc/api.go @@ -33,13 +33,12 @@ func (n *CommonAdminAPI) SetLogLevel(ctx context.Context, lvlStr string) error { recordDur := n.M.RecordRPCServerRequest("admin_setLogLevel") defer recordDur() - h := n.log.GetHandler() - - lvl, err := log.LvlFromString(lvlStr) + lvl, err := oplog.LevelFromString(lvlStr) if err != nil { return err } + h := n.log.Handler() // We set the log level, and do not wrap the handler with an additional filter handler, // as the underlying handler would otherwise also still filter with the previous log level. lvlSetter, ok := h.(oplog.LvlSetter) diff --git a/op-service/rpc/cli.go b/op-service/rpc/cli.go index a36684fa73cb..866dfd0336d7 100644 --- a/op-service/rpc/cli.go +++ b/op-service/rpc/cli.go @@ -42,6 +42,14 @@ type CLIConfig struct { EnableAdmin bool } +func DefaultCLIConfig() CLIConfig { + return CLIConfig{ + ListenAddr: "0.0.0.0", + ListenPort: 8545, + EnableAdmin: false, + } +} + func (c CLIConfig) Check() error { if c.ListenPort < 0 || c.ListenPort > math.MaxUint16 { return errors.New("invalid RPC port") diff --git a/op-service/rpc/server.go b/op-service/rpc/server.go index d22dc26593cd..a715c0de699b 100644 --- a/op-service/rpc/server.go +++ b/op-service/rpc/server.go @@ -10,13 +10,13 @@ import ( "strconv" "time" - oplog "github.com/ethereum-optimism/optimism/op-service/log" - opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" - optls "github.com/ethereum-optimism/optimism/op-service/tls" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/rpc" + + oplog "github.com/ethereum-optimism/optimism/op-service/log" + opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + optls "github.com/ethereum-optimism/optimism/op-service/tls" ) var wildcardHosts = []string{"*"} @@ -33,6 +33,7 @@ type Server struct { healthzPath string httpRecorder opmetrics.HTTPRecorder httpServer *http.Server + listener net.Listener log log.Logger tls *ServerTLSConfig middlewares []Middleware @@ -149,7 +150,7 @@ func NewServer(host string, port int, appVersion string, opts ...ServerOption) * } func (b *Server) Endpoint() string { - return b.endpoint + return b.listener.Addr().String() } func (b *Server) AddAPI(api rpc.API) { @@ -180,14 +181,22 @@ func (b *Server) Start() error { handler = oplog.NewLoggingMiddleware(b.log, handler) b.httpServer.Handler = handler + listener, err := net.Listen("tcp", b.endpoint) + if err != nil { + return fmt.Errorf("failed to listen: %w", err) + } + b.listener = listener + // override endpoint with the actual listener address, in case the port was 0 during test. + b.httpServer.Addr = listener.Addr().String() + b.endpoint = listener.Addr().String() errCh := make(chan error, 1) go func() { if b.tls != nil { - if err := b.httpServer.ListenAndServeTLS("", ""); err != nil { + if err := b.httpServer.ServeTLS(b.listener, "", ""); err != nil { errCh <- err } } else { - if err := b.httpServer.ListenAndServe(); err != nil { + if err := b.httpServer.Serve(b.listener); err != nil { errCh <- err } } @@ -195,6 +204,8 @@ func (b *Server) Start() error { // verify that the server comes up tick := time.NewTimer(10 * time.Millisecond) + defer tick.Stop() + select { case err := <-errCh: return fmt.Errorf("http server failed: %w", err) diff --git a/op-service/rpc/server_test.go b/op-service/rpc/server_test.go index a495c244e240..c44cc8298934 100644 --- a/op-service/rpc/server_test.go +++ b/op-service/rpc/server_test.go @@ -3,8 +3,9 @@ package rpc import ( "fmt" "io" - "math/rand" + "net" "net/http" + "strconv" "testing" "github.com/ethereum/go-ethereum/rpc" @@ -21,7 +22,7 @@ func TestBaseServer(t *testing.T) { appVersion := "test" server := NewServer( "127.0.0.1", - 10000+rand.Intn(22768), + 0, appVersion, WithAPIs([]rpc.API{ { @@ -58,4 +59,13 @@ func TestBaseServer(t *testing.T) { require.NoError(t, rpcClient.Call(&res, "test_frobnicate", 2)) require.Equal(t, 4, res) }) + + t.Run("supports 0 port", func(t *testing.T) { + endpoint := server.Endpoint() + _, portStr, err := net.SplitHostPort(endpoint) + require.NoError(t, err) + port, err := strconv.Atoi(portStr) + require.NoError(t, err) + require.Greater(t, port, 0) + }) } diff --git a/op-service/signer/client.go b/op-service/signer/client.go index e5baa33568f8..9822a1a7409f 100644 --- a/op-service/signer/client.go +++ b/op-service/signer/client.go @@ -93,17 +93,23 @@ func (s *SignerClient) pingVersion() (string, error) { } func (s *SignerClient) SignTransaction(ctx context.Context, chainId *big.Int, from common.Address, tx *types.Transaction) (*types.Transaction, error) { - args := NewTransactionArgsFromTransaction(chainId, from, tx) + sidecar := tx.BlobTxSidecar() + args := NewTransactionArgsFromTransaction(chainId, &from, tx.WithoutBlobTxSidecar()) var result hexutil.Bytes if err := s.client.CallContext(ctx, &result, "eth_signTransaction", args); err != nil { return nil, fmt.Errorf("eth_signTransaction failed: %w", err) } - signed := &types.Transaction{} + var signed types.Transaction if err := signed.UnmarshalBinary(result); err != nil { return nil, err } + if sidecar != nil { + if err := signed.SetBlobTxSidecar(sidecar); err != nil { + return nil, fmt.Errorf("failed to attach sidecar to signed blob tx: %w", err) + } + } - return signed, nil + return &signed, nil } diff --git a/op-service/signer/transaction_args.go b/op-service/signer/transaction_args.go index ea9fcd486231..bd7fec62adf9 100644 --- a/op-service/signer/transaction_args.go +++ b/op-service/signer/transaction_args.go @@ -1,8 +1,13 @@ package signer import ( + "bytes" + "errors" + "fmt" "math/big" + "github.com/holiman/uint256" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -10,6 +15,8 @@ import ( // TransactionArgs represents the arguments to construct a new transaction // or a message call. +// Geth has an internal version of this, but this is not exported, and only supported in v1.13.11 and forward. +// This signing API format is based on the legacy personal-account signing RPC of ethereum. type TransactionArgs struct { From *common.Address `json:"from"` To *common.Address `json:"to"` @@ -28,16 +35,20 @@ type TransactionArgs struct { AccessList *types.AccessList `json:"accessList,omitempty"` ChainID *hexutil.Big `json:"chainId,omitempty"` + + // Custom extension for EIP-4844 support + BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` + BlobFeeCap *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` } -// NewTransactionArgsFromTransaction creates a TransactionArgs struct from an EIP-1559 transaction -func NewTransactionArgsFromTransaction(chainId *big.Int, from common.Address, tx *types.Transaction) *TransactionArgs { +// NewTransactionArgsFromTransaction creates a TransactionArgs struct from an EIP-1559 or EIP-4844 transaction +func NewTransactionArgsFromTransaction(chainId *big.Int, from *common.Address, tx *types.Transaction) *TransactionArgs { data := hexutil.Bytes(tx.Data()) nonce := hexutil.Uint64(tx.Nonce()) gas := hexutil.Uint64(tx.Gas()) accesses := tx.AccessList() args := &TransactionArgs{ - From: &from, + From: from, Input: &data, Nonce: &nonce, Value: (*hexutil.Big)(tx.Value()), @@ -47,6 +58,8 @@ func NewTransactionArgsFromTransaction(chainId *big.Int, from common.Address, tx MaxFeePerGas: (*hexutil.Big)(tx.GasFeeCap()), MaxPriorityFeePerGas: (*hexutil.Big)(tx.GasTipCap()), AccessList: &accesses, + BlobVersionedHashes: tx.BlobHashes(), + BlobFeeCap: (*hexutil.Big)(tx.BlobGasFeeCap()), } return args } @@ -62,23 +75,106 @@ func (args *TransactionArgs) data() []byte { return nil } -// ToTransaction converts the arguments to a transaction. -func (args *TransactionArgs) ToTransaction() *types.Transaction { +func (args *TransactionArgs) Check() error { + if args.Gas == nil { + return errors.New("gas not specified") + } + if args.GasPrice != nil { + return errors.New("only accepts maxFeePerGas/maxPriorityFeePerGas params") + } + if args.MaxFeePerGas == nil || args.MaxPriorityFeePerGas == nil { + return errors.New("missing maxFeePerGas or maxPriorityFeePerGas") + } + // Both EIP-1559 fee parameters are now set; sanity check them. + if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 { + return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas) + } + if args.Nonce == nil { + return errors.New("nonce not specified") + } + if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { + return errors.New(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`) + } + if args.To == nil && len(args.data()) == 0 { + return errors.New("contract creation without any data provided") + } + if args.ChainID == nil { + return errors.New("chain id not specified") + } + if args.Value == nil { + args.Value = new(hexutil.Big) + } + if args.AccessList == nil { + args.AccessList = &types.AccessList{} + } + if args.BlobVersionedHashes != nil { + if len(args.BlobVersionedHashes) == 0 { + return errors.New("non-null blob versioned hashes should not be empty") + } + if args.BlobFeeCap == nil { + return errors.New("when including blobs a blob-fee-cap is required") + } + } else { + if args.BlobFeeCap != nil { + return errors.New("unexpected blob-fee-cap, transaction does not include blobs") + } + } + return nil +} + +// ToTransactionData converts the arguments to transaction content-data. Warning: this excludes blob data. +func (args *TransactionArgs) ToTransactionData() (types.TxData, error) { var data types.TxData al := types.AccessList{} if args.AccessList != nil { al = *args.AccessList } - data = &types.DynamicFeeTx{ - To: args.To, - ChainID: (*big.Int)(args.ChainID), - Nonce: uint64(*args.Nonce), - Gas: uint64(*args.Gas), - GasFeeCap: (*big.Int)(args.MaxFeePerGas), - GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas), - Value: (*big.Int)(args.Value), - Data: args.data(), - AccessList: al, - } - return types.NewTx(data) + if len(args.BlobVersionedHashes) > 0 { + chainID, overflow := uint256.FromBig((*big.Int)(args.ChainID)) + if overflow { + return nil, fmt.Errorf("chainID %s too large for blob tx", args.ChainID) + } + maxFeePerGas, overflow := uint256.FromBig((*big.Int)(args.MaxFeePerGas)) + if overflow { + return nil, fmt.Errorf("maxFeePerGas %s too large for blob tx", args.MaxFeePerGas) + } + maxPriorityFeePerGas, overflow := uint256.FromBig((*big.Int)(args.MaxPriorityFeePerGas)) + if overflow { + return nil, fmt.Errorf("maxPriorityFeePerGas %s too large for blob tx", args.MaxPriorityFeePerGas) + } + value, overflow := uint256.FromBig((*big.Int)(args.Value)) + if overflow { + return nil, fmt.Errorf("value %s too large for blob tx", args.Value) + } + blobFeeCap, overflow := uint256.FromBig((*big.Int)(args.BlobFeeCap)) + if overflow { + return nil, fmt.Errorf("blobFeeCap %s too large for blob tx", args.BlobFeeCap) + } + data = &types.BlobTx{ + ChainID: chainID, + Nonce: uint64(*args.Nonce), + GasTipCap: maxPriorityFeePerGas, + GasFeeCap: maxFeePerGas, + Gas: uint64(*args.Gas), + To: *args.To, + Value: value, + Data: args.data(), + AccessList: al, + BlobFeeCap: blobFeeCap, + BlobHashes: args.BlobVersionedHashes, + } + } else { + data = &types.DynamicFeeTx{ + ChainID: (*big.Int)(args.ChainID), + Nonce: uint64(*args.Nonce), + GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas), + GasFeeCap: (*big.Int)(args.MaxFeePerGas), + Gas: uint64(*args.Gas), + To: args.To, + Value: (*big.Int)(args.Value), + Data: args.data(), + AccessList: al, + } + } + return data, nil } diff --git a/op-service/sources/batching/arrays.go b/op-service/sources/batching/arrays.go new file mode 100644 index 000000000000..b946014215c1 --- /dev/null +++ b/op-service/sources/batching/arrays.go @@ -0,0 +1,30 @@ +package batching + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" +) + +// ReadArray uses batch calls to load all entries from an array. +// countCall is used to retrieve the current array length, then getCall is used to create calls for each element +// which are sent in a batch call. +// The returned *CallResult slice, contains a result for each entry in the array, in the same order as in the contract. +func ReadArray(ctx context.Context, caller *MultiCaller, block rpcblock.Block, countCall *ContractCall, getCall func(i *big.Int) *ContractCall) ([]*CallResult, error) { + result, err := caller.SingleCall(ctx, block, countCall) + if err != nil { + return nil, fmt.Errorf("failed to load array length: %w", err) + } + count := result.GetBigInt(0).Uint64() + calls := make([]Call, count) + for i := uint64(0); i < count; i++ { + calls[i] = getCall(new(big.Int).SetUint64(i)) + } + results, err := caller.Call(ctx, block, calls...) + if err != nil { + return nil, fmt.Errorf("failed to fetch array data: %w", err) + } + return results, nil +} diff --git a/op-service/sources/batching/balance_call.go b/op-service/sources/batching/balance_call.go new file mode 100644 index 000000000000..a91bca04a30b --- /dev/null +++ b/op-service/sources/batching/balance_call.go @@ -0,0 +1,40 @@ +package batching + +import ( + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" +) + +type BalanceCall struct { + addr common.Address +} + +var _ Call = (*BalanceCall)(nil) + +func NewBalanceCall(addr common.Address) *BalanceCall { + return &BalanceCall{addr} +} + +func (b *BalanceCall) ToBatchElemCreator() (BatchElementCreator, error) { + return func(block rpcblock.Block) (any, rpc.BatchElem) { + out := new(hexutil.Big) + return out, rpc.BatchElem{ + Method: "eth_getBalance", + Args: []interface{}{b.addr, block.ArgValue()}, + Result: &out, + } + }, nil +} + +func (b *BalanceCall) HandleResult(result interface{}) (*CallResult, error) { + val, ok := result.(*hexutil.Big) + if !ok { + return nil, fmt.Errorf("response %v was not a *big.Int", result) + } + return &CallResult{out: []interface{}{(*big.Int)(val)}}, nil +} diff --git a/op-service/sources/batching/balance_call_test.go b/op-service/sources/batching/balance_call_test.go new file mode 100644 index 000000000000..5541360ae966 --- /dev/null +++ b/op-service/sources/batching/balance_call_test.go @@ -0,0 +1,25 @@ +package batching + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestGetBalance(t *testing.T) { + addr := common.Address{0xab, 0xcd} + expectedBalance := big.NewInt(248924) + + stub := test.NewRpcStub(t) + stub.AddExpectedCall(test.NewGetBalanceCall(addr, rpcblock.Latest, expectedBalance)) + + caller := NewMultiCaller(stub, DefaultBatchSize) + result, err := caller.SingleCall(context.Background(), rpcblock.Latest, NewBalanceCall(addr)) + require.NoError(t, err) + require.Equal(t, expectedBalance, result.GetBigInt(0)) +} diff --git a/op-service/sources/batching.go b/op-service/sources/batching/batching.go similarity index 99% rename from op-service/sources/batching.go rename to op-service/sources/batching/batching.go index 958185ac32bb..0cf88f702704 100644 --- a/op-service/sources/batching.go +++ b/op-service/sources/batching/batching.go @@ -1,4 +1,4 @@ -package sources +package batching import ( "context" diff --git a/op-service/sources/batching_test.go b/op-service/sources/batching/batching_test.go similarity index 99% rename from op-service/sources/batching_test.go rename to op-service/sources/batching/batching_test.go index 4d79e3e1f4e6..c2880dd0c92b 100644 --- a/op-service/sources/batching_test.go +++ b/op-service/sources/batching/batching_test.go @@ -1,4 +1,4 @@ -package sources +package batching import ( "context" diff --git a/op-service/sources/batching/bound.go b/op-service/sources/batching/bound.go new file mode 100644 index 000000000000..a6b7e3385f8d --- /dev/null +++ b/op-service/sources/batching/bound.go @@ -0,0 +1,50 @@ +package batching + +import ( + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +var ( + ErrUnknownMethod = errors.New("unknown method") + ErrInvalidCall = errors.New("invalid call") +) + +type BoundContract struct { + abi *abi.ABI + addr common.Address +} + +func NewBoundContract(abi *abi.ABI, addr common.Address) *BoundContract { + return &BoundContract{ + abi: abi, + addr: addr, + } +} + +func (b *BoundContract) Addr() common.Address { + return b.addr +} + +func (b *BoundContract) Call(method string, args ...interface{}) *ContractCall { + return NewContractCall(b.abi, b.addr, method, args...) +} + +func (b *BoundContract) DecodeCall(data []byte) (string, *CallResult, error) { + if len(data) < 4 { + return "", nil, ErrUnknownMethod + } + method, err := b.abi.MethodById(data[:4]) + if err != nil { + // ABI doesn't return a nicely typed error so treat any failure to find the method as unknown + return "", nil, fmt.Errorf("%w: %v", ErrUnknownMethod, err.Error()) + } + args, err := method.Inputs.Unpack(data[4:]) + if err != nil { + return "", nil, fmt.Errorf("%w: %v", ErrInvalidCall, err.Error()) + } + return method.Name, &CallResult{args}, nil +} diff --git a/op-service/sources/batching/bound_test.go b/op-service/sources/batching/bound_test.go new file mode 100644 index 000000000000..b5672897a575 --- /dev/null +++ b/op-service/sources/batching/bound_test.go @@ -0,0 +1,53 @@ +package batching + +import ( + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestDecodeCall(t *testing.T) { + method := "approve" + spender := common.Address{0xbb, 0xee} + amount := big.NewInt(4242) + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + validData, err := testAbi.Pack(method, spender, amount) + require.NoError(t, err) + + contract := NewBoundContract(testAbi, common.Address{0xaa}) + t.Run("TooShort", func(t *testing.T) { + _, _, err := contract.DecodeCall([]byte{1, 2, 3}) + require.ErrorIs(t, err, ErrUnknownMethod) + }) + + t.Run("UnknownMethodId", func(t *testing.T) { + _, _, err := contract.DecodeCall([]byte{1, 2, 3, 4}) + require.ErrorIs(t, err, ErrUnknownMethod) + }) + + t.Run("MissingArgs", func(t *testing.T) { + // Truncate to just the 4 byte method selector + _, _, err = contract.DecodeCall(validData[:4]) + require.ErrorIs(t, err, ErrInvalidCall) + + // Truncate to partial args + _, _, err = contract.DecodeCall(validData[:6]) + require.ErrorIs(t, err, ErrInvalidCall) + + // Truncate to first arg but missing second + _, _, err = contract.DecodeCall(validData[:24]) + require.ErrorIs(t, err, ErrInvalidCall) + }) + + t.Run("ValidCall", func(t *testing.T) { + name, args, err := contract.DecodeCall(validData) + require.NoError(t, err) + require.Equal(t, name, method) + require.Equal(t, spender, args.GetAddress(0)) + require.Zero(t, amount.Cmp(args.GetBigInt(1))) + }) +} diff --git a/op-service/sources/batching/call.go b/op-service/sources/batching/call.go new file mode 100644 index 000000000000..d84932fac6ee --- /dev/null +++ b/op-service/sources/batching/call.go @@ -0,0 +1,65 @@ +package batching + +import ( + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" +) + +type BatchElementCreator func(block rpcblock.Block) (any, rpc.BatchElem) + +type Call interface { + ToBatchElemCreator() (BatchElementCreator, error) + HandleResult(interface{}) (*CallResult, error) +} + +type CallResult struct { + out []interface{} +} + +func (c *CallResult) GetUint8(i int) uint8 { + return *abi.ConvertType(c.out[i], new(uint8)).(*uint8) +} + +func (c *CallResult) GetUint32(i int) uint32 { + return *abi.ConvertType(c.out[i], new(uint32)).(*uint32) +} + +func (c *CallResult) GetUint64(i int) uint64 { + return *abi.ConvertType(c.out[i], new(uint64)).(*uint64) +} + +func (c *CallResult) GetBool(i int) bool { + return *abi.ConvertType(c.out[i], new(bool)).(*bool) +} + +func (c *CallResult) GetHash(i int) common.Hash { + return *abi.ConvertType(c.out[i], new([32]byte)).(*[32]byte) +} + +func (c *CallResult) GetAddress(i int) common.Address { + return *abi.ConvertType(c.out[i], new([20]byte)).(*[20]byte) +} + +func (c *CallResult) GetBigInt(i int) *big.Int { + return *abi.ConvertType(c.out[i], new(*big.Int)).(**big.Int) +} + +func (c *CallResult) GetStruct(i int, target interface{}) { + abi.ConvertType(c.out[i], target) +} + +func (c *CallResult) GetBytes(i int) []byte { + return *abi.ConvertType(c.out[i], new([]byte)).(*[]byte) +} + +func (c *CallResult) GetBytes32(i int) [32]byte { + return *abi.ConvertType(c.out[i], new([32]byte)).(*[32]byte) +} + +func (c *CallResult) GetBytes32Slice(i int) [][32]byte { + return *abi.ConvertType(c.out[i], new([][32]byte)).(*[][32]byte) +} diff --git a/op-service/sources/batching/call_test.go b/op-service/sources/batching/call_test.go new file mode 100644 index 000000000000..10b785127763 --- /dev/null +++ b/op-service/sources/batching/call_test.go @@ -0,0 +1,115 @@ +package batching + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestCallResult_GetValues(t *testing.T) { + tests := []struct { + name string + getter func(result *CallResult, i int) interface{} + expected interface{} + }{ + { + name: "GetUint8", + getter: func(result *CallResult, i int) interface{} { + return result.GetUint8(i) + }, + expected: uint8(12), + }, + { + name: "GetUint32", + getter: func(result *CallResult, i int) interface{} { + return result.GetUint32(i) + }, + expected: uint32(12346), + }, + { + name: "GetUint64", + getter: func(result *CallResult, i int) interface{} { + return result.GetUint64(i) + }, + expected: uint64(12346), + }, + { + name: "GetBool", + getter: func(result *CallResult, i int) interface{} { + return result.GetBool(i) + }, + expected: true, + }, + { + name: "GetAddress", + getter: func(result *CallResult, i int) interface{} { + return result.GetAddress(i) + }, + expected: ([20]byte)(common.Address{0xaa, 0xbb, 0xcc}), + }, + { + name: "GetHash", + getter: func(result *CallResult, i int) interface{} { + return result.GetHash(i) + }, + expected: ([32]byte)(common.Hash{0xaa, 0xbb, 0xcc}), + }, + { + name: "GetBytes", + getter: func(result *CallResult, i int) interface{} { + return result.GetBytes(i) + }, + expected: []byte{0xaa, 0xbb, 0xcc}, + }, + { + name: "GetBytes32", + getter: func(result *CallResult, i int) interface{} { + return result.GetBytes32(i) + }, + expected: [32]byte{0xaa, 0xbb, 0xcc}, + }, + { + name: "GetBytes32Slice", + getter: func(result *CallResult, i int) interface{} { + return result.GetBytes32Slice(i) + }, + expected: [][32]byte{{0xaa, 0xbb, 0xcc}, {0xdd, 0xee, 0xff}, {0x11, 0x22, 0x33}}, + }, + { + name: "GetBigInt", + getter: func(result *CallResult, i int) interface{} { + return result.GetBigInt(i) + }, + expected: big.NewInt(2398423), + }, + { + name: "GetStruct", + getter: func(result *CallResult, i int) interface{} { + out := struct { + a *big.Int + b common.Hash + }{} + result.GetStruct(i, &out) + return out + }, + expected: struct { + a *big.Int + b common.Hash + }{ + a: big.NewInt(6), + b: common.Hash{0xee}, + }, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + callResult := &CallResult{[]interface{}{nil, 0, "abc", test.expected, "xyz", 3, nil}} + actual := test.getter(callResult, 3) + require.EqualValues(t, test.expected, actual) + }) + } +} diff --git a/op-service/sources/batching/contract_call.go b/op-service/sources/batching/contract_call.go new file mode 100644 index 000000000000..87b265e84717 --- /dev/null +++ b/op-service/sources/batching/contract_call.go @@ -0,0 +1,95 @@ +package batching + +import ( + "fmt" + + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" +) + +type ContractCall struct { + Abi *abi.ABI + Addr common.Address + Method string + Args []interface{} + From common.Address +} + +func NewContractCall(abi *abi.ABI, addr common.Address, method string, args ...interface{}) *ContractCall { + return &ContractCall{ + Abi: abi, + Addr: addr, + Method: method, + Args: args, + } +} + +func (c *ContractCall) Pack() ([]byte, error) { + return c.Abi.Pack(c.Method, c.Args...) +} + +func (c *ContractCall) CallMethod() string { + return "eth_call" +} + +func (c *ContractCall) ToBatchElemCreator() (BatchElementCreator, error) { + args, err := c.ToCallArgs() + if err != nil { + return nil, err + } + f := func(block rpcblock.Block) (any, rpc.BatchElem) { + out := new(hexutil.Bytes) + return out, rpc.BatchElem{ + Method: "eth_call", + Args: []interface{}{args, block.ArgValue()}, + Result: &out, + } + } + return f, nil +} + +func (c *ContractCall) ToCallArgs() (interface{}, error) { + data, err := c.Pack() + if err != nil { + return nil, fmt.Errorf("failed to pack arguments: %w", err) + } + + arg := map[string]interface{}{ + "from": c.From, + "to": &c.Addr, + "input": hexutil.Bytes(data), + } + return arg, nil +} + +func (c *ContractCall) CreateResult() interface{} { + return new(hexutil.Bytes) +} + +func (c *ContractCall) HandleResult(result interface{}) (*CallResult, error) { + out, err := c.Unpack(*result.(*hexutil.Bytes)) + return out, err +} + +func (c *ContractCall) Unpack(hex hexutil.Bytes) (*CallResult, error) { + out, err := c.Abi.Unpack(c.Method, hex) + if err != nil { + return nil, fmt.Errorf("failed to unpack data: %w", err) + } + return &CallResult{out: out}, nil +} + +func (c *ContractCall) ToTxCandidate() (txmgr.TxCandidate, error) { + data, err := c.Pack() + if err != nil { + return txmgr.TxCandidate{}, fmt.Errorf("failed to pack arguments: %w", err) + } + return txmgr.TxCandidate{ + TxData: data, + To: &c.Addr, + }, nil +} diff --git a/op-service/sources/batching/contract_call_test.go b/op-service/sources/batching/contract_call_test.go new file mode 100644 index 000000000000..854161c5cbda --- /dev/null +++ b/op-service/sources/batching/contract_call_test.go @@ -0,0 +1,102 @@ +package batching + +import ( + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/require" +) + +func TestContractCall_ToCallArgs(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + call := NewContractCall(testAbi, addr, "approve", common.Address{0xcc}, big.NewInt(1234444)) + call.From = common.Address{0xab} + args, err := call.ToCallArgs() + require.NoError(t, err) + argMap, ok := args.(map[string]interface{}) + require.True(t, ok) + require.Equal(t, argMap["from"], call.From) + require.Equal(t, argMap["to"], &addr) + expectedData, err := call.Pack() + require.NoError(t, err) + require.Equal(t, argMap["input"], hexutil.Bytes(expectedData)) + + require.NotContains(t, argMap, "value") + require.NotContains(t, argMap, "gas") + require.NotContains(t, argMap, "gasPrice") +} + +func TestContractCall_ToTxCandidate(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + call := NewContractCall(testAbi, addr, "approve", common.Address{0xcc}, big.NewInt(1234444)) + candidate, err := call.ToTxCandidate() + require.NoError(t, err) + require.Equal(t, candidate.To, &addr) + expectedData, err := call.Pack() + require.NoError(t, err) + require.Equal(t, candidate.TxData, expectedData) + + require.Nil(t, candidate.Value) + require.Zero(t, candidate.GasLimit) +} + +func TestContractCall_Pack(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + sender := common.Address{0xcc} + amount := big.NewInt(1234444) + call := NewContractCall(testAbi, addr, "approve", sender, amount) + actual, err := call.Pack() + require.NoError(t, err) + + expected, err := testAbi.Pack("approve", sender, amount) + require.NoError(t, err) + require.Equal(t, actual, expected) +} + +func TestContractCall_PackInvalid(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + // Second arg should be a *big.Int so packing should fail + call := NewContractCall(testAbi, addr, "approve", common.Address{0xcc}, uint32(123)) + _, err = call.Pack() + require.Error(t, err) +} + +func TestContractCall_Unpack(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + call := NewContractCall(testAbi, addr, "balanceOf", common.Address{0xcc}) + outputs := testAbi.Methods["balanceOf"].Outputs + expected := big.NewInt(1234) + packed, err := outputs.Pack(expected) + require.NoError(t, err) + + unpacked, err := call.Unpack(packed) + require.NoError(t, err) + require.Equal(t, unpacked.GetBigInt(0), expected) +} + +func TestContractCall_UnpackInvalid(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + call := NewContractCall(testAbi, addr, "balanceOf", common.Address{0xcc}) + + // Input data is the wrong format and won't unpack successfully + inputPacked, err := call.Pack() + require.NoError(t, err) + + _, err = call.Unpack(inputPacked) + require.Error(t, err) +} diff --git a/op-service/sources/batching/multicall.go b/op-service/sources/batching/multicall.go new file mode 100644 index 000000000000..2a02ce774f73 --- /dev/null +++ b/op-service/sources/batching/multicall.go @@ -0,0 +1,82 @@ +package batching + +import ( + "context" + "fmt" + "io" + + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/rpc" +) + +var DefaultBatchSize = 100 + +type EthRpc interface { + CallContext(ctx context.Context, out interface{}, method string, args ...interface{}) error + BatchCallContext(ctx context.Context, b []rpc.BatchElem) error +} + +type MultiCaller struct { + rpc EthRpc + batchSize int +} + +func NewMultiCaller(rpc EthRpc, batchSize int) *MultiCaller { + return &MultiCaller{ + rpc: rpc, + batchSize: batchSize, + } +} + +func (m *MultiCaller) BatchSize() int { + return m.batchSize +} + +func (m *MultiCaller) SingleCall(ctx context.Context, block rpcblock.Block, call Call) (*CallResult, error) { + results, err := m.Call(ctx, block, call) + if err != nil { + return nil, err + } + return results[0], nil +} + +func (m *MultiCaller) Call(ctx context.Context, block rpcblock.Block, calls ...Call) ([]*CallResult, error) { + keys := make([]BatchElementCreator, len(calls)) + for i := 0; i < len(calls); i++ { + creator, err := calls[i].ToBatchElemCreator() + if err != nil { + return nil, err + } + keys[i] = creator + } + fetcher := NewIterativeBatchCall[BatchElementCreator, any]( + keys, + func(key BatchElementCreator) (any, rpc.BatchElem) { + return key(block) + }, + m.rpc.BatchCallContext, + m.rpc.CallContext, + m.batchSize) + for { + if err := fetcher.Fetch(ctx); err == io.EOF { + break + } else if err != nil { + return nil, fmt.Errorf("failed to fetch batch: %w", err) + } + } + results, err := fetcher.Result() + if err != nil { + return nil, fmt.Errorf("failed to get batch call results: %w", err) + } + + callResults := make([]*CallResult, len(results)) + for i, result := range results { + call := calls[i] + out, err := call.HandleResult(result) + if err != nil { + return nil, fmt.Errorf("failed to unpack result: %w", err) + } + callResults[i] = out + } + return callResults, nil +} diff --git a/op-service/sources/batching/rpcblock/blocks.go b/op-service/sources/batching/rpcblock/blocks.go new file mode 100644 index 000000000000..caf8bf94c78f --- /dev/null +++ b/op-service/sources/batching/rpcblock/blocks.go @@ -0,0 +1,33 @@ +package rpcblock + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" +) + +// Block represents the block ref value in RPC calls. +// It can be either a label (e.g. latest), a block number or block hash. +type Block struct { + value any +} + +func (b Block) ArgValue() any { + return b.value +} + +var ( + Pending = Block{"pending"} + Latest = Block{"latest"} + Safe = Block{"safe"} + Finalized = Block{"finalized"} +) + +// ByNumber references a canonical block by number. +func ByNumber(blockNum uint64) Block { + return Block{rpc.BlockNumber(blockNum)} +} + +// ByHash references a block by hash. Canonical or non-canonical blocks may be referenced. +func ByHash(hash common.Hash) Block { + return Block{rpc.BlockNumberOrHashWithHash(hash, false)} +} diff --git a/op-service/sources/batching/test/abi_stub.go b/op-service/sources/batching/test/abi_stub.go new file mode 100644 index 000000000000..f4a70b907a96 --- /dev/null +++ b/op-service/sources/batching/test/abi_stub.go @@ -0,0 +1,138 @@ +package test + +import ( + "encoding/json" + "errors" + "fmt" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/txmgr" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/exp/slices" +) + +type expectedCall struct { + abiMethod abi.Method + to common.Address + block rpcblock.Block + args []interface{} + packedArgs []byte + outputs []interface{} +} + +func (c *expectedCall) Matches(rpcMethod string, args ...interface{}) error { + if rpcMethod != "eth_call" { + return fmt.Errorf("expected rpcMethod eth_call but was %v", rpcMethod) + } + if len(args) != 2 { + return fmt.Errorf("expected arg count 2 but was %v", len(args)) + } + callOpts, ok := args[0].(map[string]any) + if !ok { + return fmt.Errorf("arg 0 is not a map[string]any") + } + actualBlockRef := args[1] + to, ok := callOpts["to"].(*common.Address) + if !ok { + return errors.New("to is not an address") + } + if to == nil { + return errors.New("to is nil") + } + if *to != c.to { + return fmt.Errorf("expected to %v but was %v", c.to, *to) + } + data, ok := callOpts["input"].(hexutil.Bytes) + if !ok { + return errors.New("input is not hexutil.Bytes") + } + if len(data) < 4 { + return fmt.Errorf("expected input to have at least 4 bytes but was %v", len(data)) + } + if !slices.Equal(c.abiMethod.ID, data[:4]) { + return fmt.Errorf("expected abi method ID %x but was %x", c.abiMethod.ID, data[:4]) + } + if !slices.Equal(c.packedArgs, data[4:]) { + return fmt.Errorf("expected args %x but was %x", c.packedArgs, data[4:]) + } + if !assert.ObjectsAreEqualValues(c.block.ArgValue(), actualBlockRef) { + return fmt.Errorf("expected block ref %v but was %v", c.block.ArgValue(), actualBlockRef) + } + return nil +} + +func (c *expectedCall) Execute(t *testing.T, out interface{}) { + output, err := c.abiMethod.Outputs.Pack(c.outputs...) + require.NoErrorf(t, err, "Invalid outputs for method %v: %v", c.abiMethod.Name, c.outputs) + + // I admit I do not understand Go reflection. + // So leverage json.Unmarshal to set the out value correctly. + j, err := json.Marshal(hexutil.Bytes(output)) + require.NoError(t, err) + require.NoError(t, json.Unmarshal(j, out)) +} + +func (c *expectedCall) String() string { + return fmt.Sprintf("{to: %v, block: %v, args: %v, outputs: %v}", c.to, c.block, c.args, c.outputs) +} + +type AbiBasedRpc struct { + RpcStub + abis map[common.Address]*abi.ABI +} + +func NewAbiBasedRpc(t *testing.T, to common.Address, contractAbi *abi.ABI) *AbiBasedRpc { + abis := make(map[common.Address]*abi.ABI) + abis[to] = contractAbi + return &AbiBasedRpc{ + RpcStub: RpcStub{ + t: t, + }, + abis: abis, + } +} + +func (l *AbiBasedRpc) AddContract(to common.Address, contractAbi *abi.ABI) { + l.abis[to] = contractAbi +} + +func (l *AbiBasedRpc) abi(to common.Address) *abi.ABI { + abi, ok := l.abis[to] + require.Truef(l.t, ok, "Missing ABI for %v", to) + return abi +} + +func (l *AbiBasedRpc) SetResponse(to common.Address, method string, block rpcblock.Block, expected []interface{}, output []interface{}) { + if expected == nil { + expected = []interface{}{} + } + if output == nil { + output = []interface{}{} + } + abiMethod, ok := l.abi(to).Methods[method] + require.Truef(l.t, ok, "No method: %v", method) + packedArgs, err := abiMethod.Inputs.Pack(expected...) + require.NoErrorf(l.t, err, "Invalid expected arguments for method %v: %v", method, expected) + l.AddExpectedCall(&expectedCall{ + abiMethod: abiMethod, + to: to, + block: block, + args: expected, + packedArgs: packedArgs, + outputs: output, + }) +} + +func (l *AbiBasedRpc) VerifyTxCandidate(candidate txmgr.TxCandidate) { + require.NotNil(l.t, candidate.To) + l.findExpectedCall("eth_call", map[string]any{ + "to": candidate.To, + "input": hexutil.Bytes(candidate.TxData), + "value": candidate.Value, + }, rpcblock.Latest.ArgValue()) +} diff --git a/op-service/sources/batching/test/generic_stub.go b/op-service/sources/batching/test/generic_stub.go new file mode 100644 index 000000000000..9e78656ad48f --- /dev/null +++ b/op-service/sources/batching/test/generic_stub.go @@ -0,0 +1,104 @@ +package test + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type ExpectedRpcCall interface { + fmt.Stringer + Matches(rpcMethod string, args ...interface{}) error + Execute(t *testing.T, out interface{}) +} + +type RpcStub struct { + t *testing.T + expectedCalls []ExpectedRpcCall +} + +func NewRpcStub(t *testing.T) *RpcStub { + return &RpcStub{t: t} +} + +func (r *RpcStub) ClearResponses() { + r.expectedCalls = nil +} + +func (r *RpcStub) AddExpectedCall(call ExpectedRpcCall) { + r.expectedCalls = append(r.expectedCalls, call) +} + +func (r *RpcStub) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { + var errs []error + for _, elem := range b { + elem.Error = r.CallContext(ctx, elem.Result, elem.Method, elem.Args...) + errs = append(errs, elem.Error) + } + return errors.Join(errs...) +} + +func (r *RpcStub) CallContext(_ context.Context, out interface{}, method string, args ...interface{}) error { + call := r.findExpectedCall(method, args...) + call.Execute(r.t, out) + return nil +} + +func (r *RpcStub) findExpectedCall(rpcMethod string, args ...interface{}) ExpectedRpcCall { + var matchResults string + for _, call := range r.expectedCalls { + if err := call.Matches(rpcMethod, args...); err == nil { + return call + } else { + matchResults += fmt.Sprintf("%v: %v", call, err) + } + } + require.Failf(r.t, "No matching expected calls.", matchResults) + return nil +} + +type GenericExpectedCall struct { + method string + args []interface{} + result interface{} +} + +func NewGetBalanceCall(addr common.Address, block rpcblock.Block, balance *big.Int) ExpectedRpcCall { + return &GenericExpectedCall{ + method: "eth_getBalance", + args: []interface{}{addr, block.ArgValue()}, + result: (*hexutil.Big)(balance), + } +} + +func (c *GenericExpectedCall) Matches(rpcMethod string, args ...interface{}) error { + if rpcMethod != c.method { + return fmt.Errorf("expected method %v but was %v", c.method, rpcMethod) + } + if !assert.ObjectsAreEqualValues(c.args, args) { + return fmt.Errorf("expected args %v but was %v", c.args, args) + } + return nil +} + +func (c *GenericExpectedCall) Execute(t *testing.T, out interface{}) { + // I admit I do not understand Go reflection. + // So leverage json.Unmarshal to set the out value correctly. + j, err := json.Marshal(c.result) + require.NoError(t, err) + require.NoError(t, json.Unmarshal(j, out)) +} + +func (c *GenericExpectedCall) String() string { + return fmt.Sprintf("%v(%v)->%v", c.method, c.args, c.result) +} diff --git a/op-service/sources/batching/types.go b/op-service/sources/batching/types.go new file mode 100644 index 000000000000..4bd0cc2048d6 --- /dev/null +++ b/op-service/sources/batching/types.go @@ -0,0 +1,11 @@ +package batching + +import ( + "context" + + "github.com/ethereum/go-ethereum/rpc" +) + +type BatchCallContextFn func(ctx context.Context, b []rpc.BatchElem) error + +type CallContextFn func(ctx context.Context, result any, method string, args ...any) error diff --git a/op-service/sources/caching/pre_fetch_cache.go b/op-service/sources/caching/pre_fetch_cache.go index ad928fe1fea7..c7df91246710 100644 --- a/op-service/sources/caching/pre_fetch_cache.go +++ b/op-service/sources/caching/pre_fetch_cache.go @@ -57,6 +57,10 @@ func (v *PreFetchCache[V]) AddIfNotFull(key uint64, value V) (success bool, isFu return true, false } +func (v *PreFetchCache[V]) IsFull() bool { + return v.queue.Size() >= v.maxSize +} + func (v *PreFetchCache[V]) Get(key uint64, recordMetrics bool) (V, bool) { defer v.lock.Unlock() v.lock.Lock() diff --git a/op-service/sources/debug_client.go b/op-service/sources/debug_client.go index db5a782281f1..e9bb2ca579a7 100644 --- a/op-service/sources/debug_client.go +++ b/op-service/sources/debug_client.go @@ -4,16 +4,17 @@ import ( "context" "fmt" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/rawdb" ) type DebugClient struct { - callContext CallContextFn + callContext batching.CallContextFn } -func NewDebugClient(callContext CallContextFn) *DebugClient { +func NewDebugClient(callContext batching.CallContextFn) *DebugClient { return &DebugClient{callContext} } diff --git a/op-service/sources/engine_client.go b/op-service/sources/engine_client.go index 4f54d324ce89..183356f03c53 100644 --- a/op-service/sources/engine_client.go +++ b/op-service/sources/engine_client.go @@ -5,15 +5,16 @@ import ( "fmt" "time" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/eth/catalyst" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources/caching" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rpc" ) type EngineClientConfig struct { @@ -30,6 +31,7 @@ func EngineClientDefaultConfig(config *rollup.Config) *EngineClientConfig { // EngineClient extends L2Client with engine API bindings. type EngineClient struct { *L2Client + *EngineAPIClient } func NewEngineClient(client client.RPC, log log.Logger, metrics caching.Metrics, config *EngineClientConfig) (*EngineClient, error) { @@ -38,11 +40,39 @@ func NewEngineClient(client client.RPC, log log.Logger, metrics caching.Metrics, return nil, err } + engineAPIClient := NewEngineAPIClient(client, log, config.RollupCfg) + return &EngineClient{ - L2Client: l2Client, + L2Client: l2Client, + EngineAPIClient: engineAPIClient, }, nil } +// EngineAPIClient is an RPC client for the Engine API functions. +type EngineAPIClient struct { + RPC client.RPC + log log.Logger + evp EngineVersionProvider +} + +type EngineVersionProvider interface { + ForkchoiceUpdatedVersion(attr *eth.PayloadAttributes) eth.EngineAPIMethod + NewPayloadVersion(timestamp uint64) eth.EngineAPIMethod + GetPayloadVersion(timestamp uint64) eth.EngineAPIMethod +} + +func NewEngineAPIClient(rpc client.RPC, l log.Logger, evp EngineVersionProvider) *EngineAPIClient { + return &EngineAPIClient{ + RPC: rpc, + log: l, + evp: evp, + } +} + +// EngineVersionProvider returns the underlying engine version provider used for +// resolving the correct Engine API versions. +func (s *EngineAPIClient) EngineVersionProvider() EngineVersionProvider { return s.evp } + // ForkchoiceUpdate updates the forkchoice on the execution client. If attributes is not nil, the engine client will also begin building a block // based on attributes after the new head block and return the payload ID. // @@ -50,21 +80,23 @@ func NewEngineClient(client client.RPC, log log.Logger, metrics caching.Metrics, // 1. Processing error: ForkchoiceUpdatedResult.PayloadStatusV1.ValidationError or other non-success PayloadStatusV1, // 2. `error` as eth.InputError: the forkchoice state or attributes are not valid. // 3. Other types of `error`: temporary RPC errors, like timeouts. -func (s *EngineClient) ForkchoiceUpdate(ctx context.Context, fc *eth.ForkchoiceState, attributes *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error) { - e := s.log.New("state", fc, "attr", attributes) - e.Trace("Sharing forkchoice-updated signal") +func (s *EngineAPIClient) ForkchoiceUpdate(ctx context.Context, fc *eth.ForkchoiceState, attributes *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error) { + llog := s.log.New("state", fc) // local logger + tlog := llog.New("attr", attributes) // trace logger + tlog.Trace("Sharing forkchoice-updated signal") fcCtx, cancel := context.WithTimeout(ctx, time.Second*5) defer cancel() var result eth.ForkchoiceUpdatedResult - err := s.client.CallContext(fcCtx, &result, "engine_forkchoiceUpdatedV2", fc, attributes) + method := s.evp.ForkchoiceUpdatedVersion(attributes) + err := s.RPC.CallContext(fcCtx, &result, string(method), fc, attributes) if err == nil { - e.Trace("Shared forkchoice-updated signal") + tlog.Trace("Shared forkchoice-updated signal") if attributes != nil { // block building is optional, we only get a payload ID if we are building a block - e.Trace("Received payload id", "payloadId", result.PayloadID) + tlog.Trace("Received payload id", "payloadId", result.PayloadID) } return &result, nil } else { - e.Warn("Failed to share forkchoice-updated signal", "err", err) + llog.Warn("Failed to share forkchoice-updated signal", "err", err) if rpcErr, ok := err.(rpc.Error); ok { code := eth.ErrorCode(rpcErr.ErrorCode()) switch code { @@ -84,14 +116,24 @@ func (s *EngineClient) ForkchoiceUpdate(ctx context.Context, fc *eth.ForkchoiceS // NewPayload executes a full block on the execution engine. // This returns a PayloadStatusV1 which encodes any validation/processing error, // and this type of error is kept separate from the returned `error` used for RPC errors, like timeouts. -func (s *EngineClient) NewPayload(ctx context.Context, payload *eth.ExecutionPayload) (*eth.PayloadStatusV1, error) { +func (s *EngineAPIClient) NewPayload(ctx context.Context, payload *eth.ExecutionPayload, parentBeaconBlockRoot *common.Hash) (*eth.PayloadStatusV1, error) { e := s.log.New("block_hash", payload.BlockHash) e.Trace("sending payload for execution") execCtx, cancel := context.WithTimeout(ctx, time.Second*5) defer cancel() var result eth.PayloadStatusV1 - err := s.client.CallContext(execCtx, &result, "engine_newPayloadV2", payload) + + var err error + switch method := s.evp.NewPayloadVersion(uint64(payload.Timestamp)); method { + case eth.NewPayloadV3: + err = s.RPC.CallContext(execCtx, &result, string(method), payload, []common.Hash{}, parentBeaconBlockRoot) + case eth.NewPayloadV2: + err = s.RPC.CallContext(execCtx, &result, string(method), payload) + default: + return nil, fmt.Errorf("unsupported NewPayload version: %s", method) + } + e.Trace("Received payload execution result", "status", result.Status, "latestValidHash", result.LatestValidHash, "message", result.ValidationError) if err != nil { e.Error("Payload execution failed", "err", err) @@ -104,13 +146,14 @@ func (s *EngineClient) NewPayload(ctx context.Context, payload *eth.ExecutionPay // There may be two types of error: // 1. `error` as eth.InputError: the payload ID may be unknown // 2. Other types of `error`: temporary RPC errors, like timeouts. -func (s *EngineClient) GetPayload(ctx context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayload, error) { - e := s.log.New("payload_id", payloadId) +func (s *EngineAPIClient) GetPayload(ctx context.Context, payloadInfo eth.PayloadInfo) (*eth.ExecutionPayloadEnvelope, error) { + e := s.log.New("payload_id", payloadInfo.ID) e.Trace("getting payload") var result eth.ExecutionPayloadEnvelope - err := s.client.CallContext(ctx, &result, "engine_getPayloadV2", payloadId) + method := s.evp.GetPayloadVersion(payloadInfo.Timestamp) + err := s.RPC.CallContext(ctx, &result, string(method), payloadInfo.ID) if err != nil { - e.Warn("Failed to get payload", "payload_id", payloadId, "err", err) + e.Warn("Failed to get payload", "payload_id", payloadInfo.ID, "err", err) if rpcErr, ok := err.(rpc.Error); ok { code := eth.ErrorCode(rpcErr.ErrorCode()) switch code { @@ -126,12 +169,12 @@ func (s *EngineClient) GetPayload(ctx context.Context, payloadId eth.PayloadID) return nil, err } e.Trace("Received payload") - return result.ExecutionPayload, nil + return &result, nil } -func (s *EngineClient) SignalSuperchainV1(ctx context.Context, recommended, required params.ProtocolVersion) (params.ProtocolVersion, error) { +func (s *EngineAPIClient) SignalSuperchainV1(ctx context.Context, recommended, required params.ProtocolVersion) (params.ProtocolVersion, error) { var result params.ProtocolVersion - err := s.client.CallContext(ctx, &result, "engine_signalSuperchainV1", &catalyst.SuperchainSignal{ + err := s.RPC.CallContext(ctx, &result, "engine_signalSuperchainV1", &catalyst.SuperchainSignal{ Recommended: recommended, Required: required, }) diff --git a/op-service/sources/eth_client.go b/op-service/sources/eth_client.go index e1d749ad0324..e2db86dcddef 100644 --- a/op-service/sources/eth_client.go +++ b/op-service/sources/eth_client.go @@ -63,7 +63,9 @@ type EthClientConfig struct { // If this is 0 then the client does not fall back to less optimal but available methods. MethodResetDuration time.Duration - // [OPTIONAL] The reth DB path to fetch receipts from + // [OPTIONAL] The reth DB path to fetch receipts from. + // If it is specified, the rethdb receipts fetcher will be used + // and the RPC configuration parameters don't need to be set. RethDBPath string } @@ -80,6 +82,15 @@ func (c *EthClientConfig) Check() error { if c.PayloadsCacheSize < 0 { return fmt.Errorf("invalid payloads cache size: %d", c.PayloadsCacheSize) } + if c.RethDBPath != "" { + if buildRethdb { + // If the rethdb path is set, we use the rethdb receipts fetcher and skip creating + // an RCP receipts fetcher, so below rpc config parameters don't need to be checked. + return nil + } else { + return fmt.Errorf("rethdb path specified, but built without rethdb support") + } + } if c.MaxConcurrentRequests < 1 { return fmt.Errorf("expected at least 1 concurrent request, but max is %d", c.MaxConcurrentRequests) } @@ -96,21 +107,14 @@ func (c *EthClientConfig) Check() error { type EthClient struct { client client.RPC - maxBatchSize int + recProvider ReceiptsProvider trustRPC bool mustBePostMerge bool - provKind RPCProviderKind - log log.Logger - // cache receipts in bundles per block hash - // We cache the receipts fetching job to not lose progress when we have to retry the `Fetch` call - // common.Hash -> *receiptsFetchingJobPair - receiptsCache *caching.PreFetchCache[*receiptsFetchingJobPair] - // cache transactions in bundles per block hash // common.Hash -> types.Transactions transactionsCache *caching.LRUCache[common.Hash, types.Transactions] @@ -121,76 +125,32 @@ type EthClient struct { // cache payloads by hash // common.Hash -> *eth.ExecutionPayload - payloadsCache *caching.LRUCache[common.Hash, *eth.ExecutionPayload] - - // availableReceiptMethods tracks which receipt methods can be used for fetching receipts - // This may be modified concurrently, but we don't lock since it's a single - // uint64 that's not critical (fine to miss or mix up a modification) - availableReceiptMethods ReceiptsFetchingMethod - - // lastMethodsReset tracks when availableReceiptMethods was last reset. - // When receipt-fetching fails it falls back to available methods, - // but periodically it will try to reset to the preferred optimal methods. - lastMethodsReset time.Time - - // methodResetDuration defines how long we take till we reset lastMethodsReset - methodResetDuration time.Duration - - // [OPTIONAL] The reth DB path to fetch receipts from - rethDbPath string + payloadsCache *caching.LRUCache[common.Hash, *eth.ExecutionPayloadEnvelope] // isReadOrderly Indicates whether the client often reads data in order of block height. // If so, the process of reading the cache will be different to ensure a high cache hit rate. isReadOrderly bool } -func (s *EthClient) PickReceiptsMethod(txCount uint64) ReceiptsFetchingMethod { - if now := time.Now(); now.Sub(s.lastMethodsReset) > s.methodResetDuration { - m := AvailableReceiptsFetchingMethods(s.provKind) - if s.availableReceiptMethods != m { - s.log.Warn("resetting back RPC preferences, please review RPC provider kind setting", "kind", s.provKind.String()) - } - s.availableReceiptMethods = m - s.lastMethodsReset = now - } - return PickBestReceiptsFetchingMethod(s.provKind, s.availableReceiptMethods, txCount) -} - -func (s *EthClient) OnReceiptsMethodErr(m ReceiptsFetchingMethod, err error) { - if unusableMethod(err) { - // clear the bit of the method that errored - s.availableReceiptMethods &^= m - s.log.Warn("failed to use selected RPC method for receipt fetching, temporarily falling back to alternatives", - "provider_kind", s.provKind, "failed_method", m, "fallback", s.availableReceiptMethods, "err", err) - } else { - s.log.Debug("failed to use selected RPC method for receipt fetching, but method does appear to be available, so we continue to use it", - "provider_kind", s.provKind, "failed_method", m, "fallback", s.availableReceiptMethods&^m, "err", err) - } -} - // NewEthClient returns an [EthClient], wrapping an RPC with bindings to fetch ethereum data with added error logging, // metric tracking, and caching. The [EthClient] uses a [LimitRPC] wrapper to limit the number of concurrent RPC requests. func NewEthClient(client client.RPC, log log.Logger, metrics caching.Metrics, config *EthClientConfig, isReadOrderly bool) (*EthClient, error) { if err := config.Check(); err != nil { return nil, fmt.Errorf("bad config, cannot create L1 source: %w", err) } + client = LimitRPC(client, config.MaxConcurrentRequests) + recProvider := newRecProviderFromConfig(client, log, metrics, config) return &EthClient{ - client: client, - maxBatchSize: config.MaxRequestsPerBatch, - trustRPC: config.TrustRPC, - mustBePostMerge: config.MustBePostMerge, - provKind: config.RPCProviderKind, - log: log, - receiptsCache: caching.NewPreFetchCache[*receiptsFetchingJobPair](metrics, "receipts", config.ReceiptsCacheSize), - transactionsCache: caching.NewLRUCache[common.Hash, types.Transactions](metrics, "txs", config.TransactionsCacheSize), - headersCache: caching.NewLRUCache[common.Hash, eth.BlockInfo](metrics, "headers", config.HeadersCacheSize), - payloadsCache: caching.NewLRUCache[common.Hash, *eth.ExecutionPayload](metrics, "payloads", config.PayloadsCacheSize), - availableReceiptMethods: AvailableReceiptsFetchingMethods(config.RPCProviderKind), - lastMethodsReset: time.Now(), - methodResetDuration: config.MethodResetDuration, - rethDbPath: config.RethDBPath, - isReadOrderly: isReadOrderly, + client: client, + recProvider: recProvider, + trustRPC: config.TrustRPC, + mustBePostMerge: config.MustBePostMerge, + log: log, + transactionsCache: caching.NewLRUCache[common.Hash, types.Transactions](metrics, "txs", config.TransactionsCacheSize), + headersCache: caching.NewLRUCache[common.Hash, eth.BlockInfo](metrics, "headers", config.HeadersCacheSize), + payloadsCache: caching.NewLRUCache[common.Hash, *eth.ExecutionPayloadEnvelope](metrics, "payloads", config.PayloadsCacheSize), + isReadOrderly: isReadOrderly, }, nil } @@ -232,7 +192,7 @@ func (n numberID) CheckID(id eth.BlockID) error { } func (s *EthClient) headerCall(ctx context.Context, method string, id rpcBlockID) (eth.BlockInfo, error) { - var header *rpcHeader + var header *RPCHeader err := s.client.CallContext(ctx, &header, method, id.Arg(), false) // headers are just blocks without txs if err != nil { return nil, err @@ -252,7 +212,7 @@ func (s *EthClient) headerCall(ctx context.Context, method string, id rpcBlockID } func (s *EthClient) blockCall(ctx context.Context, method string, id rpcBlockID) (eth.BlockInfo, types.Transactions, error) { - var block *rpcBlock + var block *RPCBlock err := s.client.CallContext(ctx, &block, method, id.Arg(), true) if err != nil { return nil, nil, err @@ -272,8 +232,8 @@ func (s *EthClient) blockCall(ctx context.Context, method string, id rpcBlockID) return info, txs, nil } -func (s *EthClient) payloadCall(ctx context.Context, method string, id rpcBlockID) (*eth.ExecutionPayload, error) { - var block *rpcBlock +func (s *EthClient) payloadCall(ctx context.Context, method string, id rpcBlockID) (*eth.ExecutionPayloadEnvelope, error) { + var block *RPCBlock err := s.client.CallContext(ctx, &block, method, id.Arg(), true) if err != nil { return nil, err @@ -281,15 +241,15 @@ func (s *EthClient) payloadCall(ctx context.Context, method string, id rpcBlockI if block == nil { return nil, ethereum.NotFound } - payload, err := block.ExecutionPayload(s.trustRPC) + envelope, err := block.ExecutionPayloadEnvelope(s.trustRPC) if err != nil { return nil, err } - if err := id.CheckID(payload.ID()); err != nil { + if err := id.CheckID(envelope.ExecutionPayload.ID()); err != nil { return nil, fmt.Errorf("fetched payload does not match requested ID: %w", err) } - s.payloadsCache.Add(payload.BlockHash, payload) - return payload, nil + s.payloadsCache.Add(envelope.ExecutionPayload.BlockHash, envelope) + return envelope, nil } // ChainID fetches the chain id of the internal RPC. @@ -350,22 +310,22 @@ func (s *EthClient) InfoAndTxsByLabel(ctx context.Context, label eth.BlockLabel) return s.blockCall(ctx, "eth_getBlockByNumber", label) } -func (s *EthClient) PayloadByHash(ctx context.Context, hash common.Hash) (*eth.ExecutionPayload, error) { +func (s *EthClient) PayloadByHash(ctx context.Context, hash common.Hash) (*eth.ExecutionPayloadEnvelope, error) { if payload, ok := s.payloadsCache.Get(hash); ok { return payload, nil } return s.payloadCall(ctx, "eth_getBlockByHash", hashID(hash)) } -func (s *EthClient) CachePayloadByHash(payload *eth.ExecutionPayload) bool { - return s.payloadsCache.Add(payload.BlockHash, payload) +func (s *EthClient) CachePayloadByHash(payload *eth.ExecutionPayloadEnvelope) bool { + return s.payloadsCache.Add(payload.ExecutionPayload.BlockHash, payload) } -func (s *EthClient) PayloadByNumber(ctx context.Context, number uint64) (*eth.ExecutionPayload, error) { +func (s *EthClient) PayloadByNumber(ctx context.Context, number uint64) (*eth.ExecutionPayloadEnvelope, error) { return s.payloadCall(ctx, "eth_getBlockByNumber", numberID(number)) } -func (s *EthClient) PayloadByLabel(ctx context.Context, label eth.BlockLabel) (*eth.ExecutionPayload, error) { +func (s *EthClient) PayloadByLabel(ctx context.Context, label eth.BlockLabel) (*eth.ExecutionPayloadEnvelope, error) { return s.payloadCall(ctx, "eth_getBlockByNumber", label) } @@ -391,32 +351,14 @@ func (s *EthClient) PreFetchReceipts(ctx context.Context, blockHash common.Hash) func (s *EthClient) fetchReceiptsInner(ctx context.Context, blockHash common.Hash, isForPreFetch bool) (eth.BlockInfo, types.Receipts, error, bool) { info, txs, err := s.infoAndTxsByHash(ctx, blockHash, !isForPreFetch) if err != nil { - return nil, nil, err, false - } - // Try to reuse the receipts fetcher because is caches the results of intermediate calls. This means - // that if just one of many calls fail, we only retry the failed call rather than all of the calls. - // The underlying fetcher uses the receipts hash to verify receipt integrity. - var job *receiptsFetchingJob - var isFull bool - v, ok := s.receiptsCache.Get(info.NumberU64(), !isForPreFetch) - if ok && v.blockHash == blockHash { - job = v.job - } else { - txHashes := eth.TransactionsToHashes(txs) - job = NewReceiptsFetchingJob(s, s.client, s.maxBatchSize, eth.ToBlockID(info), info.ReceiptHash(), txHashes, s.rethDbPath) - _, isFull = s.receiptsCache.AddIfNotFull(info.NumberU64(), &receiptsFetchingJobPair{ - blockHash: blockHash, - job: job, - }) - if isForPreFetch && isFull { - return nil, nil, nil, true - } + return nil, nil, fmt.Errorf("querying block: %w", err), false } - receipts, err := job.Fetch(ctx) + + txHashes, _ := eth.TransactionsToHashes(txs), eth.ToBlockID(info) + receipts, err, isFull := s.recProvider.FetchReceipts(ctx, info, txHashes, isForPreFetch) if err != nil { return nil, nil, err, isFull } - return info, receipts, nil, isFull } @@ -480,7 +422,7 @@ func (s *EthClient) Close() { } func (s *EthClient) bscFinalizedHeader(ctx context.Context, probabilisticFinalized int64) (eth.BlockInfo, error) { - var header *rpcHeader + var header *RPCHeader err := s.client.CallContext(ctx, &header, "eth_getFinalizedHeader", probabilisticFinalized) // headers are just blocks without txs if err != nil { return nil, err diff --git a/op-service/sources/eth_client_test.go b/op-service/sources/eth_client_test.go index 13749fbc70fb..a437f32085b0 100644 --- a/op-service/sources/eth_client_test.go +++ b/op-service/sources/eth_client_test.go @@ -4,6 +4,7 @@ import ( "context" crand "crypto/rand" "math/big" + "math/rand" "testing" "github.com/stretchr/testify/mock" @@ -18,6 +19,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources/caching" ) type mockRPC struct { @@ -60,7 +62,7 @@ func randHash() (out common.Hash) { return out } -func randHeader() (*types.Header, *rpcHeader) { +func randHeader() (*types.Header, *RPCHeader) { hdr := &types.Header{ ParentHash: randHash(), UncleHash: randHash(), @@ -79,7 +81,7 @@ func randHeader() (*types.Header, *rpcHeader) { Nonce: types.BlockNonce{}, BaseFee: big.NewInt(100), } - rhdr := &rpcHeader{ + rhdr := &RPCHeader{ ParentHash: hdr.ParentHash, UncleHash: hdr.UncleHash, Coinbase: hdr.Coinbase, @@ -106,9 +108,9 @@ func TestEthClient_InfoByHash(t *testing.T) { _, rhdr := randHeader() expectedInfo, _ := rhdr.Info(true, false) ctx := context.Background() - m.On("CallContext", ctx, new(*rpcHeader), + m.On("CallContext", ctx, new(*RPCHeader), "eth_getBlockByHash", []any{rhdr.Hash, false}).Run(func(args mock.Arguments) { - *args[1].(**rpcHeader) = rhdr + *args[1].(**RPCHeader) = rhdr }).Return([]error{nil}) s, err := NewEthClient(m, nil, nil, testEthClientConfig, false) require.NoError(t, err) @@ -129,9 +131,9 @@ func TestEthClient_InfoByNumber(t *testing.T) { expectedInfo, _ := rhdr.Info(true, false) n := rhdr.Number ctx := context.Background() - m.On("CallContext", ctx, new(*rpcHeader), + m.On("CallContext", ctx, new(*RPCHeader), "eth_getBlockByNumber", []any{n.String(), false}).Run(func(args mock.Arguments) { - *args[1].(**rpcHeader) = rhdr + *args[1].(**RPCHeader) = rhdr }).Return([]error{nil}) s, err := NewL1Client(m, nil, nil, L1ClientDefaultConfig(&rollup.Config{SeqWindowSize: 10}, true, RPCKindStandard)) require.NoError(t, err) @@ -148,9 +150,9 @@ func TestEthClient_WrongInfoByNumber(t *testing.T) { rhdr2.Number += 1 n := rhdr.Number ctx := context.Background() - m.On("CallContext", ctx, new(*rpcHeader), + m.On("CallContext", ctx, new(*RPCHeader), "eth_getBlockByNumber", []any{n.String(), false}).Run(func(args mock.Arguments) { - *args[1].(**rpcHeader) = &rhdr2 + *args[1].(**RPCHeader) = &rhdr2 }).Return([]error{nil}) s, err := NewL1Client(m, nil, nil, L1ClientDefaultConfig(&rollup.Config{SeqWindowSize: 10}, true, RPCKindStandard)) require.NoError(t, err) @@ -167,9 +169,9 @@ func TestEthClient_WrongInfoByHash(t *testing.T) { rhdr2.Hash = rhdr2.computeBlockHash() k := rhdr.Hash ctx := context.Background() - m.On("CallContext", ctx, new(*rpcHeader), + m.On("CallContext", ctx, new(*RPCHeader), "eth_getBlockByHash", []any{k, false}).Run(func(args mock.Arguments) { - *args[1].(**rpcHeader) = &rhdr2 + *args[1].(**RPCHeader) = &rhdr2 }).Return([]error{nil}) s, err := NewL1Client(m, nil, nil, L1ClientDefaultConfig(&rollup.Config{SeqWindowSize: 10}, true, RPCKindStandard)) require.NoError(t, err) @@ -177,3 +179,50 @@ func TestEthClient_WrongInfoByHash(t *testing.T) { require.Error(t, err, "cannot accept the wrong block") m.Mock.AssertExpectations(t) } + +func newEthClientWithCaches(metrics caching.Metrics, cacheSize int) *EthClient { + return &EthClient{ + transactionsCache: caching.NewLRUCache[common.Hash, types.Transactions](metrics, "txs", cacheSize), + headersCache: caching.NewLRUCache[common.Hash, eth.BlockInfo](metrics, "headers", cacheSize), + payloadsCache: caching.NewLRUCache[common.Hash, *eth.ExecutionPayloadEnvelope](metrics, "payloads", cacheSize), + } +} + +// TestReceiptValidation tests that the receipt validation is performed by the underlying RPCReceiptsFetcher +func TestReceiptValidation(t *testing.T) { + require := require.New(t) + mrpc := new(mockRPC) + rp := NewRPCReceiptsFetcher(mrpc, nil, RPCReceiptsConfig{}) + const numTxs = 1 + block, _ := randomRpcBlockAndReceipts(rand.New(rand.NewSource(420)), numTxs) + //txHashes := receiptTxHashes(receipts) + ctx := context.Background() + + mrpc.On("CallContext", + ctx, + mock.Anything, + "eth_getTransactionReceipt", + mock.Anything). + Run(func(args mock.Arguments) { + }). + Return([]error{nil}) + + // when the block is requested, the block is returned + mrpc.On("CallContext", + ctx, + mock.Anything, + "eth_getBlockByHash", + mock.Anything). + Run(func(args mock.Arguments) { + *(args[1].(**RPCBlock)) = block + }). + Return([]error{nil}) + + ethcl := newEthClientWithCaches(nil, numTxs) + ethcl.client = mrpc + ethcl.recProvider = rp + ethcl.trustRPC = true + + _, _, err := ethcl.FetchReceipts(ctx, block.Hash) + require.ErrorContains(err, "unexpected nil block number") +} diff --git a/op-service/sources/fallback_client.go b/op-service/sources/fallback_client.go index 826cfb1ae480..60ff59f34ad8 100644 --- a/op-service/sources/fallback_client.go +++ b/op-service/sources/fallback_client.go @@ -272,8 +272,8 @@ func (l *FallbackClient) ChainID(ctx context.Context, rpc client.RPC) (*big.Int, return (*big.Int)(&id), nil } -func (l *FallbackClient) l1BlockRefByNumber(ctx context.Context, number uint64, newRpc client.RPC) (*rpcHeader, error) { - var header *rpcHeader +func (l *FallbackClient) l1BlockRefByNumber(ctx context.Context, number uint64, newRpc client.RPC) (*RPCHeader, error) { + var header *RPCHeader err := newRpc.CallContext(ctx, &header, "eth_getBlockByNumber", numberID(number).Arg(), false) // headers are just blocks without txs if err != nil { return nil, err diff --git a/op-service/sources/l1_beacon_client.go b/op-service/sources/l1_beacon_client.go new file mode 100644 index 000000000000..7a6aea703a13 --- /dev/null +++ b/op-service/sources/l1_beacon_client.go @@ -0,0 +1,304 @@ +package sources + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "path" + "strconv" + "sync" + + "github.com/ethereum/go-ethereum/crypto/kzg4844" + + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +const ( + versionMethod = "eth/v1/node/version" + specMethod = "eth/v1/config/spec" + genesisMethod = "eth/v1/beacon/genesis" + sidecarsMethodPrefix = "eth/v1/beacon/blob_sidecars/" +) + +type L1BeaconClientConfig struct { + FetchAllSidecars bool +} + +// L1BeaconClient is a high level golang client for the Beacon API. +type L1BeaconClient struct { + cl BeaconClient + pool *ClientPool[BlobSideCarsFetcher] + cfg L1BeaconClientConfig + + initLock sync.Mutex + timeToSlotFn TimeToSlotFn +} + +// BeaconClient is a thin wrapper over the Beacon APIs. +// +//go:generate mockery --name BeaconClient --with-expecter=true +type BeaconClient interface { + NodeVersion(ctx context.Context) (string, error) + ConfigSpec(ctx context.Context) (eth.APIConfigResponse, error) + BeaconGenesis(ctx context.Context) (eth.APIGenesisResponse, error) + BeaconBlobSideCars(ctx context.Context, fetchAllSidecars bool, slot uint64, hashes []eth.IndexedBlobHash) (eth.APIGetBlobSidecarsResponse, error) +} + +// BlobSideCarsFetcher is a thin wrapper over the Beacon APIs. +// +//go:generate mockery --name BlobSideCarsFetcher --with-expecter=true +type BlobSideCarsFetcher interface { + BeaconBlobSideCars(ctx context.Context, fetchAllSidecars bool, slot uint64, hashes []eth.IndexedBlobHash) (eth.APIGetBlobSidecarsResponse, error) +} + +// BeaconHTTPClient implements BeaconClient. It provides golang types over the basic Beacon API. +type BeaconHTTPClient struct { + cl client.HTTP +} + +func NewBeaconHTTPClient(cl client.HTTP) *BeaconHTTPClient { + return &BeaconHTTPClient{cl} +} + +func (cl *BeaconHTTPClient) apiReq(ctx context.Context, dest any, reqPath string, reqQuery url.Values) error { + headers := http.Header{} + headers.Add("Accept", "application/json") + resp, err := cl.cl.Get(ctx, reqPath, reqQuery, headers) + if err != nil { + return fmt.Errorf("http Get failed: %w", err) + } + if resp.StatusCode != http.StatusOK { + errMsg, _ := io.ReadAll(resp.Body) + _ = resp.Body.Close() + return fmt.Errorf("failed request with status %d: %s", resp.StatusCode, string(errMsg)) + } + if err := json.NewDecoder(resp.Body).Decode(dest); err != nil { + _ = resp.Body.Close() + return err + } + if err := resp.Body.Close(); err != nil { + return fmt.Errorf("failed to close response body: %w", err) + } + return nil +} + +func (cl *BeaconHTTPClient) NodeVersion(ctx context.Context) (string, error) { + var resp eth.APIVersionResponse + if err := cl.apiReq(ctx, &resp, versionMethod, nil); err != nil { + return "", err + } + return resp.Data.Version, nil +} + +func (cl *BeaconHTTPClient) ConfigSpec(ctx context.Context) (eth.APIConfigResponse, error) { + var configResp eth.APIConfigResponse + if err := cl.apiReq(ctx, &configResp, specMethod, nil); err != nil { + return eth.APIConfigResponse{}, err + } + return configResp, nil +} + +func (cl *BeaconHTTPClient) BeaconGenesis(ctx context.Context) (eth.APIGenesisResponse, error) { + var genesisResp eth.APIGenesisResponse + if err := cl.apiReq(ctx, &genesisResp, genesisMethod, nil); err != nil { + return eth.APIGenesisResponse{}, err + } + return genesisResp, nil +} + +func (cl *BeaconHTTPClient) BeaconBlobSideCars(ctx context.Context, fetchAllSidecars bool, slot uint64, hashes []eth.IndexedBlobHash) (eth.APIGetBlobSidecarsResponse, error) { + reqPath := path.Join(sidecarsMethodPrefix, strconv.FormatUint(slot, 10)) + var reqQuery url.Values + if !fetchAllSidecars { + reqQuery = url.Values{} + for i := range hashes { + reqQuery.Add("indices", strconv.FormatUint(hashes[i].Index, 10)) + } + } + var resp eth.APIGetBlobSidecarsResponse + if err := cl.apiReq(ctx, &resp, reqPath, reqQuery); err != nil { + return eth.APIGetBlobSidecarsResponse{}, err + } + return resp, nil +} + +type ClientPool[T any] struct { + clients []T + index int +} + +func NewClientPool[T any](clients ...T) *ClientPool[T] { + return &ClientPool[T]{ + clients: clients, + index: 0, + } +} + +func (p *ClientPool[T]) Len() int { + return len(p.clients) +} + +func (p *ClientPool[T]) Get() T { + return p.clients[p.index] +} + +func (p *ClientPool[T]) MoveToNext() { + p.index += 1 + if p.index == len(p.clients) { + p.index = 0 + } +} + +// NewL1BeaconClient returns a client for making requests to an L1 consensus layer node. +// Fallbacks are optional clients that will be used for fetching blobs. L1BeaconClient will rotate between +// the `cl` and the fallbacks whenever a client runs into an error while fetching blobs. +func NewL1BeaconClient(cl BeaconClient, cfg L1BeaconClientConfig, fallbacks ...BlobSideCarsFetcher) *L1BeaconClient { + cs := append([]BlobSideCarsFetcher{cl}, fallbacks...) + return &L1BeaconClient{ + cl: cl, + pool: NewClientPool[BlobSideCarsFetcher](cs...), + cfg: cfg} +} + +type TimeToSlotFn func(timestamp uint64) (uint64, error) + +// GetTimeToSlotFn returns a function that converts a timestamp to a slot number. +func (cl *L1BeaconClient) GetTimeToSlotFn(ctx context.Context) (TimeToSlotFn, error) { + cl.initLock.Lock() + defer cl.initLock.Unlock() + if cl.timeToSlotFn != nil { + return cl.timeToSlotFn, nil + } + + genesis, err := cl.cl.BeaconGenesis(ctx) + if err != nil { + return nil, err + } + + config, err := cl.cl.ConfigSpec(ctx) + if err != nil { + return nil, err + } + + genesisTime := uint64(genesis.Data.GenesisTime) + secondsPerSlot := uint64(config.Data.SecondsPerSlot) + if secondsPerSlot == 0 { + return nil, fmt.Errorf("got bad value for seconds per slot: %v", config.Data.SecondsPerSlot) + } + cl.timeToSlotFn = func(timestamp uint64) (uint64, error) { + if timestamp < genesisTime { + return 0, fmt.Errorf("provided timestamp (%v) precedes genesis time (%v)", timestamp, genesisTime) + } + return (timestamp - genesisTime) / secondsPerSlot, nil + } + return cl.timeToSlotFn, nil +} + +func (cl *L1BeaconClient) fetchSidecars(ctx context.Context, slot uint64, hashes []eth.IndexedBlobHash) (eth.APIGetBlobSidecarsResponse, error) { + var errs []error + for i := 0; i < cl.pool.Len(); i++ { + f := cl.pool.Get() + resp, err := f.BeaconBlobSideCars(ctx, cl.cfg.FetchAllSidecars, slot, hashes) + if err != nil { + cl.pool.MoveToNext() + errs = append(errs, err) + } else { + return resp, nil + } + } + return eth.APIGetBlobSidecarsResponse{}, errors.Join(errs...) +} + +// GetBlobSidecars fetches blob sidecars that were confirmed in the specified +// L1 block with the given indexed hashes. +// Order of the returned sidecars is guaranteed to be that of the hashes. +// Blob data is not checked for validity. +func (cl *L1BeaconClient) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) { + if len(hashes) == 0 { + return []*eth.BlobSidecar{}, nil + } + slotFn, err := cl.GetTimeToSlotFn(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get time to slot function: %w", err) + } + slot, err := slotFn(ref.Time) + if err != nil { + return nil, fmt.Errorf("error in converting ref.Time to slot: %w", err) + } + + resp, err := cl.fetchSidecars(ctx, slot, hashes) + if err != nil { + return nil, fmt.Errorf("failed to fetch blob sidecars for slot %v block %v: %w", slot, ref, err) + } + + apiscs := make([]*eth.APIBlobSidecar, 0, len(hashes)) + // filter and order by hashes + for _, h := range hashes { + for _, apisc := range resp.Data { + if h.Index == uint64(apisc.Index) { + apiscs = append(apiscs, apisc) + break + } + } + } + + if len(hashes) != len(apiscs) { + return nil, fmt.Errorf("expected %v sidecars but got %v", len(hashes), len(apiscs)) + } + + bscs := make([]*eth.BlobSidecar, 0, len(hashes)) + for _, apisc := range apiscs { + bscs = append(bscs, apisc.BlobSidecar()) + } + + return bscs, nil +} + +// GetBlobs fetches blobs that were confirmed in the specified L1 block with the given indexed +// hashes. The order of the returned blobs will match the order of `hashes`. Confirms each +// blob's validity by checking its proof against the commitment, and confirming the commitment +// hashes to the expected value. Returns error if any blob is found invalid. +func (cl *L1BeaconClient) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { + blobSidecars, err := cl.GetBlobSidecars(ctx, ref, hashes) + if err != nil { + return nil, fmt.Errorf("failed to get blob sidecars for L1BlockRef %s: %w", ref, err) + } + return blobsFromSidecars(blobSidecars, hashes) +} + +func blobsFromSidecars(blobSidecars []*eth.BlobSidecar, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { + if len(blobSidecars) != len(hashes) { + return nil, fmt.Errorf("number of hashes and blobSidecars mismatch, %d != %d", len(hashes), len(blobSidecars)) + } + + out := make([]*eth.Blob, len(hashes)) + for i, ih := range hashes { + sidecar := blobSidecars[i] + if sidx := uint64(sidecar.Index); sidx != ih.Index { + return nil, fmt.Errorf("expected sidecars to be ordered by hashes, but got %d != %d", sidx, ih.Index) + } + + // make sure the blob's kzg commitment hashes to the expected value + hash := eth.KZGToVersionedHash(kzg4844.Commitment(sidecar.KZGCommitment)) + if hash != ih.Hash { + return nil, fmt.Errorf("expected hash %s for blob at index %d but got %s", ih.Hash, ih.Index, hash) + } + + // confirm blob data is valid by verifying its proof against the commitment + if err := eth.VerifyBlobProof(&sidecar.Blob, kzg4844.Commitment(sidecar.KZGCommitment), kzg4844.Proof(sidecar.KZGProof)); err != nil { + return nil, fmt.Errorf("blob at index %d failed verification: %w", i, err) + } + out[i] = &sidecar.Blob + } + return out, nil +} + +// GetVersion fetches the version of the Beacon-node. +func (cl *L1BeaconClient) GetVersion(ctx context.Context) (string, error) { + return cl.cl.NodeVersion(ctx) +} diff --git a/op-service/sources/l1_beacon_client_test.go b/op-service/sources/l1_beacon_client_test.go new file mode 100644 index 000000000000..defee7d8cbf3 --- /dev/null +++ b/op-service/sources/l1_beacon_client_test.go @@ -0,0 +1,190 @@ +package sources + +import ( + "context" + "errors" + "testing" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources/mocks" + "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/stretchr/testify/require" +) + +func makeTestBlobSidecar(index uint64) (eth.IndexedBlobHash, *eth.BlobSidecar) { + blob := kzg4844.Blob{} + // make first byte of test blob match its index so we can easily verify if is returned in the + // expected order + blob[0] = byte(index) + commit, _ := kzg4844.BlobToCommitment(blob) + proof, _ := kzg4844.ComputeBlobProof(blob, commit) + hash := eth.KZGToVersionedHash(commit) + + idh := eth.IndexedBlobHash{ + Index: index, + Hash: hash, + } + sidecar := eth.BlobSidecar{ + Index: eth.Uint64String(index), + Blob: eth.Blob(blob), + KZGCommitment: eth.Bytes48(commit), + KZGProof: eth.Bytes48(proof), + } + return idh, &sidecar +} + +func TestBlobsFromSidecars(t *testing.T) { + indices := []uint64{5, 7, 2} + + // blobs should be returned in order of their indices in the hashes array regardless + // of the sidecar ordering + index0, sidecar0 := makeTestBlobSidecar(indices[0]) + index1, sidecar1 := makeTestBlobSidecar(indices[1]) + index2, sidecar2 := makeTestBlobSidecar(indices[2]) + + hashes := []eth.IndexedBlobHash{index0, index1, index2} + + // put the sidecars in scrambled order to confirm error + sidecars := []*eth.BlobSidecar{sidecar2, sidecar0, sidecar1} + _, err := blobsFromSidecars(sidecars, hashes) + require.Error(t, err) + + // too few sidecars should error + sidecars = []*eth.BlobSidecar{sidecar0, sidecar1} + _, err = blobsFromSidecars(sidecars, hashes) + require.Error(t, err) + + // correct order should work + sidecars = []*eth.BlobSidecar{sidecar0, sidecar1, sidecar2} + blobs, err := blobsFromSidecars(sidecars, hashes) + require.NoError(t, err) + // confirm order by checking first blob byte against expected index + for i := range blobs { + require.Equal(t, byte(indices[i]), blobs[i][0]) + } + + // mangle a proof to make sure it's detected + badProof := *sidecar0 + badProof.KZGProof[11]++ + sidecars[1] = &badProof + _, err = blobsFromSidecars(sidecars, hashes) + require.Error(t, err) + + // mangle a commitment to make sure it's detected + badCommitment := *sidecar0 + badCommitment.KZGCommitment[13]++ + sidecars[1] = &badCommitment + _, err = blobsFromSidecars(sidecars, hashes) + require.Error(t, err) + + // mangle a hash to make sure it's detected + sidecars[1] = sidecar0 + hashes[2].Hash[17]++ + _, err = blobsFromSidecars(sidecars, hashes) + require.Error(t, err) +} + +func TestBlobsFromSidecars_EmptySidecarList(t *testing.T) { + hashes := []eth.IndexedBlobHash{} + sidecars := []*eth.BlobSidecar{} + blobs, err := blobsFromSidecars(sidecars, hashes) + require.NoError(t, err) + require.Empty(t, blobs, "blobs should be empty when no sidecars are provided") +} + +func toAPISideCars(sidecars []*eth.BlobSidecar) []*eth.APIBlobSidecar { + var out []*eth.APIBlobSidecar + for _, s := range sidecars { + out = append(out, ð.APIBlobSidecar{ + Index: s.Index, + Blob: s.Blob, + KZGCommitment: s.KZGCommitment, + KZGProof: s.KZGProof, + SignedBlockHeader: eth.SignedBeaconBlockHeader{}, + }) + } + return out +} + +func TestBeaconClientNoErrorPrimary(t *testing.T) { + indices := []uint64{5, 7, 2} + index0, sidecar0 := makeTestBlobSidecar(indices[0]) + index1, sidecar1 := makeTestBlobSidecar(indices[1]) + index2, sidecar2 := makeTestBlobSidecar(indices[2]) + + hashes := []eth.IndexedBlobHash{index0, index1, index2} + sidecars := []*eth.BlobSidecar{sidecar0, sidecar1, sidecar2} + apiSidecars := toAPISideCars(sidecars) + + ctx := context.Background() + p := mocks.NewBeaconClient(t) + f := mocks.NewBlobSideCarsFetcher(t) + c := NewL1BeaconClient(p, L1BeaconClientConfig{}, f) + p.EXPECT().BeaconGenesis(ctx).Return(eth.APIGenesisResponse{Data: eth.ReducedGenesisData{GenesisTime: 10}}, nil) + p.EXPECT().ConfigSpec(ctx).Return(eth.APIConfigResponse{Data: eth.ReducedConfigData{SecondsPerSlot: 2}}, nil) + // Timestamp 12 = Slot 1 + p.EXPECT().BeaconBlobSideCars(ctx, false, uint64(1), hashes).Return(eth.APIGetBlobSidecarsResponse{Data: apiSidecars}, nil) + + resp, err := c.GetBlobSidecars(ctx, eth.L1BlockRef{Time: 12}, hashes) + require.Equal(t, sidecars, resp) + require.NoError(t, err) +} + +func TestBeaconClientFallback(t *testing.T) { + indices := []uint64{5, 7, 2} + index0, sidecar0 := makeTestBlobSidecar(indices[0]) + index1, sidecar1 := makeTestBlobSidecar(indices[1]) + index2, sidecar2 := makeTestBlobSidecar(indices[2]) + + hashes := []eth.IndexedBlobHash{index0, index1, index2} + sidecars := []*eth.BlobSidecar{sidecar0, sidecar1, sidecar2} + apiSidecars := toAPISideCars(sidecars) + + ctx := context.Background() + p := mocks.NewBeaconClient(t) + f := mocks.NewBlobSideCarsFetcher(t) + c := NewL1BeaconClient(p, L1BeaconClientConfig{}, f) + p.EXPECT().BeaconGenesis(ctx).Return(eth.APIGenesisResponse{Data: eth.ReducedGenesisData{GenesisTime: 10}}, nil) + p.EXPECT().ConfigSpec(ctx).Return(eth.APIConfigResponse{Data: eth.ReducedConfigData{SecondsPerSlot: 2}}, nil) + // Timestamp 12 = Slot 1 + p.EXPECT().BeaconBlobSideCars(ctx, false, uint64(1), hashes).Return(eth.APIGetBlobSidecarsResponse{}, errors.New("404 not found")) + f.EXPECT().BeaconBlobSideCars(ctx, false, uint64(1), hashes).Return(eth.APIGetBlobSidecarsResponse{Data: apiSidecars}, nil) + + resp, err := c.GetBlobSidecars(ctx, eth.L1BlockRef{Time: 12}, hashes) + require.Equal(t, sidecars, resp) + require.NoError(t, err) + + // Second set of calls. This time rotate back to the primary + indices = []uint64{3, 9, 11} + index0, sidecar0 = makeTestBlobSidecar(indices[0]) + index1, sidecar1 = makeTestBlobSidecar(indices[1]) + index2, sidecar2 = makeTestBlobSidecar(indices[2]) + + hashes = []eth.IndexedBlobHash{index0, index1, index2} + sidecars = []*eth.BlobSidecar{sidecar0, sidecar1, sidecar2} + apiSidecars = toAPISideCars(sidecars) + + // Timestamp 14 = Slot 2 + f.EXPECT().BeaconBlobSideCars(ctx, false, uint64(2), hashes).Return(eth.APIGetBlobSidecarsResponse{}, errors.New("404 not found")) + p.EXPECT().BeaconBlobSideCars(ctx, false, uint64(2), hashes).Return(eth.APIGetBlobSidecarsResponse{Data: apiSidecars}, nil) + + resp, err = c.GetBlobSidecars(ctx, eth.L1BlockRef{Time: 14}, hashes) + require.Equal(t, sidecars, resp) + require.NoError(t, err) + +} + +func TestClientPoolSingle(t *testing.T) { + p := NewClientPool[int](1) + for i := 0; i < 10; i++ { + require.Equal(t, 1, p.Get()) + p.MoveToNext() + } +} +func TestClientPoolSeveral(t *testing.T) { + p := NewClientPool[int](0, 1, 2, 3) + for i := 0; i < 25; i++ { + require.Equal(t, i%4, p.Get()) + p.MoveToNext() + } +} diff --git a/op-service/sources/l1_client.go b/op-service/sources/l1_client.go index 75e963e2ff2b..fc69d061c4fb 100644 --- a/op-service/sources/l1_client.go +++ b/op-service/sources/l1_client.go @@ -3,12 +3,14 @@ package sources import ( "context" "fmt" + "math/big" "strings" "sync" "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-node/rollup" @@ -150,7 +152,7 @@ func (s *L1Client) GoOrUpdatePreFetchReceipts(ctx context.Context, l1Start uint6 return case currentL1Block = <-s.preFetchReceiptsStartBlockChan: s.log.Debug("pre-fetching receipts currentL1Block changed", "block", currentL1Block) - s.receiptsCache.RemoveAll() + s.recProvider.GetReceiptsCache().RemoveAll() parentHash = common.Hash{} default: blockRef, err := s.L1BlockRefByLabel(ctx, eth.Unsafe) @@ -193,7 +195,7 @@ func (s *L1Client) GoOrUpdatePreFetchReceipts(ctx context.Context, l1Start uint6 time.Sleep(1 * time.Second) continue } - pair, ok := s.receiptsCache.Get(blockNumber, false) + pair, ok := s.recProvider.GetReceiptsCache().Get(blockNumber, false) if ok && pair.blockHash == blockInfo.Hash { blockInfoChan <- blockInfo return @@ -252,7 +254,74 @@ func (s *L1Client) GoOrUpdatePreFetchReceipts(ctx context.Context, l1Start uint6 func (s *L1Client) ClearReceiptsCacheBefore(blockNumber uint64) { s.log.Debug("clear receipts cache before", "blockNumber", blockNumber) - s.receiptsCache.RemoveLessThan(blockNumber) + s.recProvider.GetReceiptsCache().RemoveLessThan(blockNumber) +} + +func (s *L1Client) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { + if len(hashes) == 0 { + return []*eth.Blob{}, nil + } + + blobSidecars, err := s.getBlobSidecars(ctx, ref) + if err != nil { + return nil, fmt.Errorf("failed to get blob sidecars for L1BlockRef %s: %w", ref, err) + } + + validatedBlobs, err := validateBlobSidecars(blobSidecars, ref) + if err != nil { + return nil, fmt.Errorf("failed to validate blob sidecars for L1BlockRef %s: %w", ref, err) + } + + blobs := make([]*eth.Blob, len(hashes)) + for i, indexedBlobHash := range hashes { + blob, ok := validatedBlobs[indexedBlobHash.Hash] + if !ok { + return nil, fmt.Errorf("blob sidecars fetched from rpc mismatched with expected hash %s for L1BlockRef %s", indexedBlobHash.Hash, ref) + } + blobs[i] = blob + } + return blobs, nil +} + +func (s *L1Client) getBlobSidecars(ctx context.Context, ref eth.L1BlockRef) (eth.BSCBlobSidecars, error) { + var blobSidecars eth.BSCBlobSidecars + err := s.client.CallContext(ctx, &blobSidecars, "eth_getBlobSidecars", numberID(ref.Number).Arg()) + if err != nil { + return nil, err + } + if blobSidecars == nil { + return nil, ethereum.NotFound + } + return blobSidecars, nil +} + +func validateBlobSidecars(blobSidecars eth.BSCBlobSidecars, ref eth.L1BlockRef) (map[common.Hash]*eth.Blob, error) { + if len(blobSidecars) == 0 { + return nil, fmt.Errorf("invalidate api response, blob sidecars of block %s are empty", ref.Hash) + } + blobsMap := make(map[common.Hash]*eth.Blob) + for _, blobSidecar := range blobSidecars { + if blobSidecar.BlockNumber.ToInt().Cmp(big.NewInt(0).SetUint64(ref.Number)) != 0 { + return nil, fmt.Errorf("invalidate api response of tx %s, expect block number %d, got %d", blobSidecar.TxHash, ref.Number, blobSidecar.BlockNumber.ToInt().Uint64()) + } + if blobSidecar.BlockHash.Cmp(ref.Hash) != 0 { + return nil, fmt.Errorf("invalidate api response of tx %s, expect block hash %s, got %s", blobSidecar.TxHash, ref.Hash, blobSidecar.BlockHash) + } + if len(blobSidecar.Blobs) == 0 || len(blobSidecar.Blobs) != len(blobSidecar.Commitments) || len(blobSidecar.Blobs) != len(blobSidecar.Proofs) { + return nil, fmt.Errorf("invalidate api response of tx %s,idx:%d, len of blobs(%d)/commitments(%d)/proofs(%d) is not equal or is 0", blobSidecar.TxHash, blobSidecar.TxIndex, len(blobSidecar.Blobs), len(blobSidecar.Commitments), len(blobSidecar.Proofs)) + } + + for i := 0; i < len(blobSidecar.Blobs); i++ { + // confirm blob data is valid by verifying its proof against the commitment + if err := eth.VerifyBlobProof(&blobSidecar.Blobs[i], kzg4844.Commitment(blobSidecar.Commitments[i]), kzg4844.Proof(blobSidecar.Proofs[i])); err != nil { + return nil, fmt.Errorf("blob of tx %s at index %d failed verification: %w", blobSidecar.TxHash, i, err) + } + // the blob's kzg commitment hashes + hash := eth.KZGToVersionedHash(kzg4844.Commitment(blobSidecar.Commitments[i])) + blobsMap[hash] = &blobSidecar.Blobs[i] + } + } + return blobsMap, nil } func (s *L1Client) Close() { diff --git a/op-service/sources/l2_client.go b/op-service/sources/l2_client.go index 202fe06357f9..fc42068b6d45 100644 --- a/op-service/sources/l2_client.go +++ b/op-service/sources/l2_client.go @@ -92,9 +92,13 @@ func NewL2Client(client client.RPC, log log.Logger, metrics caching.Metrics, con }, nil } +func (s *L2Client) RollupConfig() *rollup.Config { + return s.rollupCfg +} + // L2BlockRefByLabel returns the [eth.L2BlockRef] for the given block label. func (s *L2Client) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) { - payload, err := s.PayloadByLabel(ctx, label) + envelope, err := s.PayloadByLabel(ctx, label) if err != nil { // Both geth and erigon like to serve non-standard errors for the safe and finalized heads, correct that. // This happens when the chain just started and nothing is marked as safe/finalized yet. @@ -104,7 +108,7 @@ func (s *L2Client) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) // w%: wrap to preserve ethereum.NotFound case return eth.L2BlockRef{}, fmt.Errorf("failed to determine L2BlockRef of %s, could not get payload: %w", label, err) } - ref, err := derive.PayloadToBlockRef(payload, &s.rollupCfg.Genesis) + ref, err := derive.PayloadToBlockRef(s.rollupCfg, envelope.ExecutionPayload) if err != nil { return eth.L2BlockRef{}, err } @@ -114,12 +118,12 @@ func (s *L2Client) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) // L2BlockRefByNumber returns the [eth.L2BlockRef] for the given block number. func (s *L2Client) L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2BlockRef, error) { - payload, err := s.PayloadByNumber(ctx, num) + envelope, err := s.PayloadByNumber(ctx, num) if err != nil { // w%: wrap to preserve ethereum.NotFound case return eth.L2BlockRef{}, fmt.Errorf("failed to determine L2BlockRef of height %v, could not get payload: %w", num, err) } - ref, err := derive.PayloadToBlockRef(payload, &s.rollupCfg.Genesis) + ref, err := derive.PayloadToBlockRef(s.rollupCfg, envelope.ExecutionPayload) if err != nil { return eth.L2BlockRef{}, err } @@ -134,12 +138,12 @@ func (s *L2Client) L2BlockRefByHash(ctx context.Context, hash common.Hash) (eth. return ref, nil } - payload, err := s.PayloadByHash(ctx, hash) + envelope, err := s.PayloadByHash(ctx, hash) if err != nil { // w%: wrap to preserve ethereum.NotFound case return eth.L2BlockRef{}, fmt.Errorf("failed to determine block-hash of hash %v, could not get payload: %w", hash, err) } - ref, err := derive.PayloadToBlockRef(payload, &s.rollupCfg.Genesis) + ref, err := derive.PayloadToBlockRef(s.rollupCfg, envelope.ExecutionPayload) if err != nil { return eth.L2BlockRef{}, err } @@ -154,12 +158,12 @@ func (s *L2Client) SystemConfigByL2Hash(ctx context.Context, hash common.Hash) ( return ref, nil } - payload, err := s.PayloadByHash(ctx, hash) + envelope, err := s.PayloadByHash(ctx, hash) if err != nil { // w%: wrap to preserve ethereum.NotFound case return eth.SystemConfig{}, fmt.Errorf("failed to determine block-hash of hash %v, could not get payload: %w", hash, err) } - cfg, err := derive.PayloadToSystemConfig(payload, s.rollupCfg) + cfg, err := derive.PayloadToSystemConfig(s.rollupCfg, envelope.ExecutionPayload) if err != nil { return eth.SystemConfig{}, err } diff --git a/op-service/sources/mocks/BeaconClient.go b/op-service/sources/mocks/BeaconClient.go new file mode 100644 index 000000000000..b862b39db64c --- /dev/null +++ b/op-service/sources/mocks/BeaconClient.go @@ -0,0 +1,249 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + eth "github.com/ethereum-optimism/optimism/op-service/eth" + mock "github.com/stretchr/testify/mock" +) + +// BeaconClient is an autogenerated mock type for the BeaconClient type +type BeaconClient struct { + mock.Mock +} + +type BeaconClient_Expecter struct { + mock *mock.Mock +} + +func (_m *BeaconClient) EXPECT() *BeaconClient_Expecter { + return &BeaconClient_Expecter{mock: &_m.Mock} +} + +// BeaconBlobSideCars provides a mock function with given fields: ctx, fetchAllSidecars, slot, hashes +func (_m *BeaconClient) BeaconBlobSideCars(ctx context.Context, fetchAllSidecars bool, slot uint64, hashes []eth.IndexedBlobHash) (eth.APIGetBlobSidecarsResponse, error) { + ret := _m.Called(ctx, fetchAllSidecars, slot, hashes) + + var r0 eth.APIGetBlobSidecarsResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, bool, uint64, []eth.IndexedBlobHash) (eth.APIGetBlobSidecarsResponse, error)); ok { + return rf(ctx, fetchAllSidecars, slot, hashes) + } + if rf, ok := ret.Get(0).(func(context.Context, bool, uint64, []eth.IndexedBlobHash) eth.APIGetBlobSidecarsResponse); ok { + r0 = rf(ctx, fetchAllSidecars, slot, hashes) + } else { + r0 = ret.Get(0).(eth.APIGetBlobSidecarsResponse) + } + + if rf, ok := ret.Get(1).(func(context.Context, bool, uint64, []eth.IndexedBlobHash) error); ok { + r1 = rf(ctx, fetchAllSidecars, slot, hashes) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BeaconClient_BeaconBlobSideCars_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BeaconBlobSideCars' +type BeaconClient_BeaconBlobSideCars_Call struct { + *mock.Call +} + +// BeaconBlobSideCars is a helper method to define mock.On call +// - ctx context.Context +// - fetchAllSidecars bool +// - slot uint64 +// - hashes []eth.IndexedBlobHash +func (_e *BeaconClient_Expecter) BeaconBlobSideCars(ctx interface{}, fetchAllSidecars interface{}, slot interface{}, hashes interface{}) *BeaconClient_BeaconBlobSideCars_Call { + return &BeaconClient_BeaconBlobSideCars_Call{Call: _e.mock.On("BeaconBlobSideCars", ctx, fetchAllSidecars, slot, hashes)} +} + +func (_c *BeaconClient_BeaconBlobSideCars_Call) Run(run func(ctx context.Context, fetchAllSidecars bool, slot uint64, hashes []eth.IndexedBlobHash)) *BeaconClient_BeaconBlobSideCars_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(bool), args[2].(uint64), args[3].([]eth.IndexedBlobHash)) + }) + return _c +} + +func (_c *BeaconClient_BeaconBlobSideCars_Call) Return(_a0 eth.APIGetBlobSidecarsResponse, _a1 error) *BeaconClient_BeaconBlobSideCars_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *BeaconClient_BeaconBlobSideCars_Call) RunAndReturn(run func(context.Context, bool, uint64, []eth.IndexedBlobHash) (eth.APIGetBlobSidecarsResponse, error)) *BeaconClient_BeaconBlobSideCars_Call { + _c.Call.Return(run) + return _c +} + +// BeaconGenesis provides a mock function with given fields: ctx +func (_m *BeaconClient) BeaconGenesis(ctx context.Context) (eth.APIGenesisResponse, error) { + ret := _m.Called(ctx) + + var r0 eth.APIGenesisResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (eth.APIGenesisResponse, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) eth.APIGenesisResponse); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(eth.APIGenesisResponse) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BeaconClient_BeaconGenesis_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BeaconGenesis' +type BeaconClient_BeaconGenesis_Call struct { + *mock.Call +} + +// BeaconGenesis is a helper method to define mock.On call +// - ctx context.Context +func (_e *BeaconClient_Expecter) BeaconGenesis(ctx interface{}) *BeaconClient_BeaconGenesis_Call { + return &BeaconClient_BeaconGenesis_Call{Call: _e.mock.On("BeaconGenesis", ctx)} +} + +func (_c *BeaconClient_BeaconGenesis_Call) Run(run func(ctx context.Context)) *BeaconClient_BeaconGenesis_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *BeaconClient_BeaconGenesis_Call) Return(_a0 eth.APIGenesisResponse, _a1 error) *BeaconClient_BeaconGenesis_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *BeaconClient_BeaconGenesis_Call) RunAndReturn(run func(context.Context) (eth.APIGenesisResponse, error)) *BeaconClient_BeaconGenesis_Call { + _c.Call.Return(run) + return _c +} + +// ConfigSpec provides a mock function with given fields: ctx +func (_m *BeaconClient) ConfigSpec(ctx context.Context) (eth.APIConfigResponse, error) { + ret := _m.Called(ctx) + + var r0 eth.APIConfigResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (eth.APIConfigResponse, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) eth.APIConfigResponse); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(eth.APIConfigResponse) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BeaconClient_ConfigSpec_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ConfigSpec' +type BeaconClient_ConfigSpec_Call struct { + *mock.Call +} + +// ConfigSpec is a helper method to define mock.On call +// - ctx context.Context +func (_e *BeaconClient_Expecter) ConfigSpec(ctx interface{}) *BeaconClient_ConfigSpec_Call { + return &BeaconClient_ConfigSpec_Call{Call: _e.mock.On("ConfigSpec", ctx)} +} + +func (_c *BeaconClient_ConfigSpec_Call) Run(run func(ctx context.Context)) *BeaconClient_ConfigSpec_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *BeaconClient_ConfigSpec_Call) Return(_a0 eth.APIConfigResponse, _a1 error) *BeaconClient_ConfigSpec_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *BeaconClient_ConfigSpec_Call) RunAndReturn(run func(context.Context) (eth.APIConfigResponse, error)) *BeaconClient_ConfigSpec_Call { + _c.Call.Return(run) + return _c +} + +// NodeVersion provides a mock function with given fields: ctx +func (_m *BeaconClient) NodeVersion(ctx context.Context) (string, error) { + ret := _m.Called(ctx) + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (string, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) string); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BeaconClient_NodeVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NodeVersion' +type BeaconClient_NodeVersion_Call struct { + *mock.Call +} + +// NodeVersion is a helper method to define mock.On call +// - ctx context.Context +func (_e *BeaconClient_Expecter) NodeVersion(ctx interface{}) *BeaconClient_NodeVersion_Call { + return &BeaconClient_NodeVersion_Call{Call: _e.mock.On("NodeVersion", ctx)} +} + +func (_c *BeaconClient_NodeVersion_Call) Run(run func(ctx context.Context)) *BeaconClient_NodeVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *BeaconClient_NodeVersion_Call) Return(_a0 string, _a1 error) *BeaconClient_NodeVersion_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *BeaconClient_NodeVersion_Call) RunAndReturn(run func(context.Context) (string, error)) *BeaconClient_NodeVersion_Call { + _c.Call.Return(run) + return _c +} + +type mockConstructorTestingTNewBeaconClient interface { + mock.TestingT + Cleanup(func()) +} + +// NewBeaconClient creates a new instance of BeaconClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewBeaconClient(t mockConstructorTestingTNewBeaconClient) *BeaconClient { + mock := &BeaconClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/op-service/sources/mocks/BlobSideCarsFetcher.go b/op-service/sources/mocks/BlobSideCarsFetcher.go new file mode 100644 index 000000000000..5dc530d9317a --- /dev/null +++ b/op-service/sources/mocks/BlobSideCarsFetcher.go @@ -0,0 +1,93 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + eth "github.com/ethereum-optimism/optimism/op-service/eth" + mock "github.com/stretchr/testify/mock" +) + +// BlobSideCarsFetcher is an autogenerated mock type for the BlobSideCarsFetcher type +type BlobSideCarsFetcher struct { + mock.Mock +} + +type BlobSideCarsFetcher_Expecter struct { + mock *mock.Mock +} + +func (_m *BlobSideCarsFetcher) EXPECT() *BlobSideCarsFetcher_Expecter { + return &BlobSideCarsFetcher_Expecter{mock: &_m.Mock} +} + +// BeaconBlobSideCars provides a mock function with given fields: ctx, fetchAllSidecars, slot, hashes +func (_m *BlobSideCarsFetcher) BeaconBlobSideCars(ctx context.Context, fetchAllSidecars bool, slot uint64, hashes []eth.IndexedBlobHash) (eth.APIGetBlobSidecarsResponse, error) { + ret := _m.Called(ctx, fetchAllSidecars, slot, hashes) + + var r0 eth.APIGetBlobSidecarsResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, bool, uint64, []eth.IndexedBlobHash) (eth.APIGetBlobSidecarsResponse, error)); ok { + return rf(ctx, fetchAllSidecars, slot, hashes) + } + if rf, ok := ret.Get(0).(func(context.Context, bool, uint64, []eth.IndexedBlobHash) eth.APIGetBlobSidecarsResponse); ok { + r0 = rf(ctx, fetchAllSidecars, slot, hashes) + } else { + r0 = ret.Get(0).(eth.APIGetBlobSidecarsResponse) + } + + if rf, ok := ret.Get(1).(func(context.Context, bool, uint64, []eth.IndexedBlobHash) error); ok { + r1 = rf(ctx, fetchAllSidecars, slot, hashes) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BlobSideCarsFetcher_BeaconBlobSideCars_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BeaconBlobSideCars' +type BlobSideCarsFetcher_BeaconBlobSideCars_Call struct { + *mock.Call +} + +// BeaconBlobSideCars is a helper method to define mock.On call +// - ctx context.Context +// - fetchAllSidecars bool +// - slot uint64 +// - hashes []eth.IndexedBlobHash +func (_e *BlobSideCarsFetcher_Expecter) BeaconBlobSideCars(ctx interface{}, fetchAllSidecars interface{}, slot interface{}, hashes interface{}) *BlobSideCarsFetcher_BeaconBlobSideCars_Call { + return &BlobSideCarsFetcher_BeaconBlobSideCars_Call{Call: _e.mock.On("BeaconBlobSideCars", ctx, fetchAllSidecars, slot, hashes)} +} + +func (_c *BlobSideCarsFetcher_BeaconBlobSideCars_Call) Run(run func(ctx context.Context, fetchAllSidecars bool, slot uint64, hashes []eth.IndexedBlobHash)) *BlobSideCarsFetcher_BeaconBlobSideCars_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(bool), args[2].(uint64), args[3].([]eth.IndexedBlobHash)) + }) + return _c +} + +func (_c *BlobSideCarsFetcher_BeaconBlobSideCars_Call) Return(_a0 eth.APIGetBlobSidecarsResponse, _a1 error) *BlobSideCarsFetcher_BeaconBlobSideCars_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *BlobSideCarsFetcher_BeaconBlobSideCars_Call) RunAndReturn(run func(context.Context, bool, uint64, []eth.IndexedBlobHash) (eth.APIGetBlobSidecarsResponse, error)) *BlobSideCarsFetcher_BeaconBlobSideCars_Call { + _c.Call.Return(run) + return _c +} + +type mockConstructorTestingTNewBlobSideCarsFetcher interface { + mock.TestingT + Cleanup(func()) +} + +// NewBlobSideCarsFetcher creates a new instance of BlobSideCarsFetcher. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewBlobSideCarsFetcher(t mockConstructorTestingTNewBlobSideCarsFetcher) *BlobSideCarsFetcher { + mock := &BlobSideCarsFetcher{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/op-service/sources/receipts.go b/op-service/sources/receipts.go index a7eed80df595..a64f070f13c9 100644 --- a/op-service/sources/receipts.go +++ b/op-service/sources/receipts.go @@ -3,18 +3,34 @@ package sources import ( "context" "fmt" - "io" - "sync" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources/caching" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/trie" - - "github.com/ethereum-optimism/optimism/op-service/eth" ) +type ReceiptsHashPair struct { + blockHash common.Hash + receipts types.Receipts +} + +type ReceiptsProvider interface { + // FetchReceipts returns a block info and all of the receipts associated with transactions in the block. + // It verifies the receipt hash in the block header against the receipt hash of the fetched receipts + // to ensure that the execution engine did not fail to return any receipts. + FetchReceipts(ctx context.Context, blockInfo eth.BlockInfo, txHashes []common.Hash, isForPreFetch bool) (types.Receipts, error, bool) + GetReceiptsCache() *caching.PreFetchCache[*ReceiptsHashPair] +} + +type InnerReceiptsProvider interface { + // FetchReceipts returns a block info and all of the receipts associated with transactions in the block. + // It verifies the receipt hash in the block header against the receipt hash of the fetched receipts + // to ensure that the execution engine did not fail to return any receipts. + FetchReceipts(ctx context.Context, blockInfo eth.BlockInfo, txHashes []common.Hash) (types.Receipts, error) +} + // validateReceipts validates that the receipt contents are valid. // Warning: contractAddress is not verified, since it is a more expensive operation for data we do not use. // See go-ethereum/crypto.CreateAddress to verify contract deployment address data based on sender and tx nonce. @@ -87,476 +103,3 @@ func validateReceipts(block eth.BlockID, receiptHash common.Hash, txHashes []com } return nil } - -func makeReceiptRequest(txHash common.Hash) (*types.Receipt, rpc.BatchElem) { - out := new(types.Receipt) - return out, rpc.BatchElem{ - Method: "eth_getTransactionReceipt", - Args: []any{txHash}, - Result: &out, // receipt may become nil, double pointer is intentional - } -} - -// Cost break-down sources: -// Alchemy: https://docs.alchemy.com/reference/compute-units -// QuickNode: https://www.quicknode.com/docs/ethereum/api_credits -// Infura: no pricing table available. -// -// Receipts are encoded the same everywhere: -// -// blockHash, blockNumber, transactionIndex, transactionHash, from, to, cumulativeGasUsed, gasUsed, -// contractAddress, logs, logsBloom, status, effectiveGasPrice, type. -// -// Note that Alchemy/Geth still have a "root" field for legacy reasons, -// but ethereum does not compute state-roots per tx anymore, so quicknode and others do not serve this data. - -// RPCProviderKind identifies an RPC provider, used to hint at the optimal receipt fetching approach. -type RPCProviderKind string - -const ( - RPCKindAlchemy RPCProviderKind = "alchemy" - RPCKindQuickNode RPCProviderKind = "quicknode" - RPCKindInfura RPCProviderKind = "infura" - RPCKindParity RPCProviderKind = "parity" - RPCKindNethermind RPCProviderKind = "nethermind" - RPCKindDebugGeth RPCProviderKind = "debug_geth" - RPCKindErigon RPCProviderKind = "erigon" - RPCKindBasic RPCProviderKind = "basic" // try only the standard most basic receipt fetching - RPCKindAny RPCProviderKind = "any" // try any method available - RPCKindStandard RPCProviderKind = "standard" // try standard methods, including newer optimized standard RPC methods - RPCKindRethDB RPCProviderKind = "reth_db" // read data directly from reth's database - RPCKindBscFullNode RPCProviderKind = "bsc_fullnode" -) - -var RPCProviderKinds = []RPCProviderKind{ - RPCKindAlchemy, - RPCKindQuickNode, - RPCKindInfura, - RPCKindParity, - RPCKindNethermind, - RPCKindDebugGeth, - RPCKindErigon, - RPCKindBasic, - RPCKindAny, - RPCKindStandard, - RPCKindBscFullNode, -} - -// Copy of RPCProviderKinds with RethDB added to all RethDB to be used but to hide it from the flags -var validRPCProviderKinds = func() []RPCProviderKind { - return append(RPCProviderKinds, RPCKindRethDB) -}() - -func (kind RPCProviderKind) String() string { - return string(kind) -} - -func (kind *RPCProviderKind) Set(value string) error { - if !ValidRPCProviderKind(RPCProviderKind(value)) { - return fmt.Errorf("unknown rpc kind: %q", value) - } - *kind = RPCProviderKind(value) - return nil -} - -func (kind *RPCProviderKind) Clone() any { - cpy := *kind - return &cpy -} - -func ValidRPCProviderKind(value RPCProviderKind) bool { - for _, k := range validRPCProviderKinds { - if k == value { - return true - } - } - return false -} - -// ReceiptsFetchingMethod is a bitfield with 1 bit for each receipts fetching type. -// Depending on errors, tx counts and preferences the code may select different sets of fetching methods. -type ReceiptsFetchingMethod uint64 - -func (r ReceiptsFetchingMethod) String() string { - out := "" - x := r - addMaybe := func(m ReceiptsFetchingMethod, v string) { - if x&m != 0 { - out += v - x ^= x & m - } - if x != 0 { // add separator if there are entries left - out += ", " - } - } - addMaybe(EthGetTransactionReceiptBatch, "eth_getTransactionReceipt (batched)") - addMaybe(AlchemyGetTransactionReceipts, "alchemy_getTransactionReceipts") - addMaybe(DebugGetRawReceipts, "debug_getRawReceipts") - addMaybe(ParityGetBlockReceipts, "parity_getBlockReceipts") - addMaybe(EthGetBlockReceipts, "eth_getBlockReceipts") - addMaybe(ErigonGetBlockReceiptsByBlockHash, "erigon_getBlockReceiptsByBlockHash") - addMaybe(EthGetTransactionReceiptsByBlockNumber, "eth_getTransactionReceiptsByBlockNumber") - addMaybe(^ReceiptsFetchingMethod(0), "unknown") // if anything is left, describe it as unknown - return out -} - -const ( - // EthGetTransactionReceiptBatch is standard per-tx receipt fetching with JSON-RPC batches. - // Available in: standard, everywhere. - // - Alchemy: 15 CU / tx - // - Quicknode: 2 credits / tx - // Method: eth_getTransactionReceipt - // See: https://ethereum.github.io/execution-apis/api-documentation/ - EthGetTransactionReceiptBatch ReceiptsFetchingMethod = 1 << iota - // AlchemyGetTransactionReceipts is a special receipt fetching method provided by Alchemy. - // Available in: - // - Alchemy: 250 CU total - // Method: alchemy_getTransactionReceipts - // Params: - // - object with "blockNumber" or "blockHash" field - // Returns: "array of receipts" - docs lie, array is wrapped in a struct with single "receipts" field - // See: https://docs.alchemy.com/reference/alchemy-gettransactionreceipts#alchemy_gettransactionreceipts - AlchemyGetTransactionReceipts - // DebugGetRawReceipts is a debug method from Geth, faster by avoiding serialization and metadata overhead. - // Ideal for fast syncing from a local geth node. - // Available in: - // - Geth: free - // - QuickNode: 22 credits maybe? Unknown price, undocumented ("debug_getblockreceipts" exists in table though?) - // Method: debug_getRawReceipts - // Params: - // - string presenting a block number or hash - // Returns: list of strings, hex encoded RLP of receipts data. "consensus-encoding of all receipts in a single block" - // See: https://geth.ethereum.org/docs/rpc/ns-debug#debug_getrawreceipts - DebugGetRawReceipts - // ParityGetBlockReceipts is an old parity method, which has been adopted by Nethermind and some RPC providers. - // Available in: - // - Alchemy: 500 CU total - // - QuickNode: 59 credits - docs are wrong, not actually available anymore. - // - Any open-ethereum/parity legacy: free - // - Nethermind: free - // Method: parity_getBlockReceipts - // Params: - // Parity: "quantity or tag" - // Alchemy: string with block hash, number in hex, or block tag. - // Nethermind: very flexible: tag, number, hex or object with "requireCanonical"/"blockHash" fields. - // Returns: array of receipts - // See: - // - Parity: https://openethereum.github.io/JSONRPC-parity-module#parity_getblockreceipts - // - QuickNode: undocumented. - // - Alchemy: https://docs.alchemy.com/reference/eth-getblockreceipts - // - Nethermind: https://docs.nethermind.io/nethermind/ethereum-client/json-rpc/parity#parity_getblockreceipts - ParityGetBlockReceipts - // EthGetBlockReceipts is a previously non-standard receipt fetching method in the eth namespace, - // supported by some RPC platforms. - // This since has been standardized in https://github.com/ethereum/execution-apis/pull/438 and adopted in Geth: - // https://github.com/ethereum/go-ethereum/pull/27702 - // Available in: - // - Alchemy: 500 CU total (and deprecated) - // - QuickNode: 59 credits total (does not seem to work with block hash arg, inaccurate docs) - // - Standard, incl. Geth, Besu and Reth, and Nethermind has a PR in review. - // Method: eth_getBlockReceipts - // Params: - // - QuickNode: string, "quantity or tag", docs say incl. block hash, but API does not actually accept it. - // - Alchemy: string, block hash / num (hex) / block tag - // Returns: array of receipts - // See: - // - QuickNode: https://www.quicknode.com/docs/ethereum/eth_getBlockReceipts - // - Alchemy: https://docs.alchemy.com/reference/eth-getblockreceipts - // Erigon has this available, but does not support block-hash argument to the method: - // https://github.com/ledgerwatch/erigon/blob/287a3d1d6c90fc6a7a088b5ae320f93600d5a167/cmd/rpcdaemon/commands/eth_receipts.go#L571 - EthGetBlockReceipts - // ErigonGetBlockReceiptsByBlockHash is an Erigon-specific receipt fetching method, - // the same as EthGetBlockReceipts but supporting a block-hash argument. - // Available in: - // - Erigon - // Method: erigon_getBlockReceiptsByBlockHash - // Params: - // - Erigon: string, hex-encoded block hash - // Returns: - // - Erigon: array of json-ified receipts - // See: - // https://github.com/ledgerwatch/erigon/blob/287a3d1d6c90fc6a7a088b5ae320f93600d5a167/cmd/rpcdaemon/commands/erigon_receipts.go#LL391C24-L391C51 - ErigonGetBlockReceiptsByBlockHash - // RethGetBlockReceiptsMDBX is a Reth-specific receipt fetching method. It reads the data directly from reth's database, using their - // generic DB abstractions, rather than requesting it from the RPC provider. - // Available in: - // - Reth - // Method: n/a - does not use RPC. - // Params: - // - Reth: string, hex-encoded block hash - // Returns: - // - Reth: string, json-ified receipts - // See: - // - reth's DB crate documentation: https://github.com/paradigmxyz/reth/blob/main/docs/crates/db.md - RethGetBlockReceipts - // EthGetTransactionReceiptsByBlockNumber is a method provided by the fullnode of the bsc network to obtain receipts. - // Method: eth_getTransactionReceiptsByBlockNumber - // Params: - // - blockNumberTag - // Returns: array of receipts - // See: - // https://github.com/bnb-chain/bsc/blob/f8439514e33ad6430f50558ce1d85a83ec6ef658/internal/ethapi/api.go#L1960 - EthGetTransactionReceiptsByBlockNumber - - // Other: - // - 250 credits, not supported, strictly worse than other options. In quicknode price-table. - // qn_getBlockWithReceipts - in price table, ? undocumented, but in quicknode "Single Flight RPC" description - // qn_getReceipts - in price table, ? undocumented, but in quicknode "Single Flight RPC" description - // debug_getBlockReceipts - ? undocumented, shows up in quicknode price table, not available. -) - -// AvailableReceiptsFetchingMethods selects receipt fetching methods based on the RPC provider kind. -func AvailableReceiptsFetchingMethods(kind RPCProviderKind) ReceiptsFetchingMethod { - switch kind { - case RPCKindAlchemy: - return AlchemyGetTransactionReceipts | EthGetBlockReceipts | EthGetTransactionReceiptBatch - case RPCKindQuickNode: - return DebugGetRawReceipts | EthGetBlockReceipts | EthGetTransactionReceiptBatch - case RPCKindInfura: - // Infura is big, but sadly does not support more optimized receipts fetching methods (yet?) - return EthGetTransactionReceiptBatch - case RPCKindParity: - return ParityGetBlockReceipts | EthGetTransactionReceiptBatch - case RPCKindNethermind: - return ParityGetBlockReceipts | EthGetTransactionReceiptBatch - case RPCKindDebugGeth: - return DebugGetRawReceipts | EthGetTransactionReceiptBatch - case RPCKindErigon: - return ErigonGetBlockReceiptsByBlockHash | EthGetTransactionReceiptBatch - case RPCKindBasic: - return EthGetTransactionReceiptBatch - case RPCKindBscFullNode: - return EthGetTransactionReceiptsByBlockNumber | EthGetTransactionReceiptBatch - case RPCKindAny: - // if it's any kind of RPC provider, then try all methods (except for RethGetBlockReceipts) - return AlchemyGetTransactionReceipts | EthGetBlockReceipts | - DebugGetRawReceipts | ErigonGetBlockReceiptsByBlockHash | - ParityGetBlockReceipts | EthGetTransactionReceiptBatch - case RPCKindStandard: - return EthGetBlockReceipts | EthGetTransactionReceiptBatch - case RPCKindRethDB: - return RethGetBlockReceipts - default: - return EthGetTransactionReceiptBatch - } -} - -// PickBestReceiptsFetchingMethod selects an RPC method that is still available, -// and optimal for fetching the given number of tx receipts from the specified provider kind. -func PickBestReceiptsFetchingMethod(kind RPCProviderKind, available ReceiptsFetchingMethod, txCount uint64) ReceiptsFetchingMethod { - // If we have optimized methods available, it makes sense to use them, but only if the cost is - // lower than fetching transactions one by one with the standard receipts RPC method. - if kind == RPCKindRethDB { - return RethGetBlockReceipts - } else if kind == RPCKindAlchemy { - if available&AlchemyGetTransactionReceipts != 0 && txCount > 250/15 { - return AlchemyGetTransactionReceipts - } - if available&EthGetBlockReceipts != 0 && txCount > 500/15 { - return EthGetBlockReceipts - } - return EthGetTransactionReceiptBatch - } else if kind == RPCKindQuickNode { - if available&DebugGetRawReceipts != 0 { - return DebugGetRawReceipts - } - if available&EthGetBlockReceipts != 0 && txCount > 59/2 { - return EthGetBlockReceipts - } - return EthGetTransactionReceiptBatch - } - // in order of preference (based on cost): check available methods - if available&AlchemyGetTransactionReceipts != 0 { - return AlchemyGetTransactionReceipts - } - if available&DebugGetRawReceipts != 0 { - return DebugGetRawReceipts - } - if available&ErigonGetBlockReceiptsByBlockHash != 0 { - return ErigonGetBlockReceiptsByBlockHash - } - if available&EthGetBlockReceipts != 0 { - return EthGetBlockReceipts - } - if available&ParityGetBlockReceipts != 0 { - return ParityGetBlockReceipts - } - if available&EthGetTransactionReceiptsByBlockNumber != 0 { - return EthGetTransactionReceiptsByBlockNumber - } - // otherwise fall back on per-tx fetching - return EthGetTransactionReceiptBatch -} - -type rpcClient interface { - CallContext(ctx context.Context, result any, method string, args ...any) error - BatchCallContext(ctx context.Context, b []rpc.BatchElem) error -} - -type receiptsFetchingJobPair struct { - blockHash common.Hash - job *receiptsFetchingJob -} - -// receiptsFetchingJob runs the receipt fetching for a specific block, -// and can re-run and adapt based on the fetching method preferences and errors communicated with the requester. -type receiptsFetchingJob struct { - m sync.Mutex - - requester ReceiptsRequester - - client rpcClient - maxBatchSize int - - block eth.BlockID - receiptHash common.Hash - txHashes []common.Hash - - fetcher *IterativeBatchCall[common.Hash, *types.Receipt] - - // [OPTIONAL] RethDB path to fetch receipts from - rethDbPath string - - result types.Receipts -} - -func NewReceiptsFetchingJob(requester ReceiptsRequester, client rpcClient, maxBatchSize int, block eth.BlockID, - receiptHash common.Hash, txHashes []common.Hash, rethDb string) *receiptsFetchingJob { - return &receiptsFetchingJob{ - requester: requester, - client: client, - maxBatchSize: maxBatchSize, - block: block, - receiptHash: receiptHash, - txHashes: txHashes, - rethDbPath: rethDb, - } -} - -// ReceiptsRequester helps determine which receipts fetching method can be used, -// and is given feedback upon receipt fetching errors to adapt the choice of method. -type ReceiptsRequester interface { - PickReceiptsMethod(txCount uint64) ReceiptsFetchingMethod - OnReceiptsMethodErr(m ReceiptsFetchingMethod, err error) -} - -// runFetcher retrieves the result by continuing previous batched receipt fetching work, -// and starting this work if necessary. -func (job *receiptsFetchingJob) runFetcher(ctx context.Context) error { - if job.fetcher == nil { - // start new work - job.fetcher = NewIterativeBatchCall[common.Hash, *types.Receipt]( - job.txHashes, - makeReceiptRequest, - job.client.BatchCallContext, - job.client.CallContext, - job.maxBatchSize, - ) - } - // Fetch all receipts - for { - if err := job.fetcher.Fetch(ctx); err == io.EOF { - break - } else if err != nil { - return err - } - } - result, err := job.fetcher.Result() - if err != nil { // errors if results are not available yet, should never happen. - return err - } - if err := validateReceipts(job.block, job.receiptHash, job.txHashes, result); err != nil { - job.fetcher.Reset() // if results are fetched but invalid, try restart all the fetching to try and get valid data. - return err - } - // Remember the result, and don't keep the fetcher and tx hashes around for longer than needed - job.result = result - job.fetcher = nil - job.txHashes = nil - return nil -} - -// receiptsWrapper is a decoding type util. Alchemy in particular wraps the receipts array result. -type receiptsWrapper struct { - Receipts []*types.Receipt `json:"receipts"` -} - -// runAltMethod retrieves the result by fetching all receipts at once, -// using the given non-standard receipt fetching method. -func (job *receiptsFetchingJob) runAltMethod(ctx context.Context, m ReceiptsFetchingMethod) error { - var result []*types.Receipt - var err error - switch m { - case AlchemyGetTransactionReceipts: - var tmp receiptsWrapper - err = job.client.CallContext(ctx, &tmp, "alchemy_getTransactionReceipts", blockHashParameter{BlockHash: job.block.Hash}) - result = tmp.Receipts - case DebugGetRawReceipts: - var rawReceipts []hexutil.Bytes - err = job.client.CallContext(ctx, &rawReceipts, "debug_getRawReceipts", job.block.Hash) - if err == nil { - if len(rawReceipts) == len(job.txHashes) { - result, err = eth.DecodeRawReceipts(job.block, rawReceipts, job.txHashes) - } else { - err = fmt.Errorf("got %d raw receipts, but expected %d", len(rawReceipts), len(job.txHashes)) - } - } - case ParityGetBlockReceipts: - err = job.client.CallContext(ctx, &result, "parity_getBlockReceipts", job.block.Hash) - case EthGetBlockReceipts: - err = job.client.CallContext(ctx, &result, "eth_getBlockReceipts", job.block.Hash) - case ErigonGetBlockReceiptsByBlockHash: - err = job.client.CallContext(ctx, &result, "erigon_getBlockReceiptsByBlockHash", job.block.Hash) - case EthGetTransactionReceiptsByBlockNumber: - err = job.client.CallContext(ctx, &result, "eth_getTransactionReceiptsByBlockNumber", hexutil.EncodeUint64(job.block.Number)) - case RethGetBlockReceipts: - if job.rethDbPath == "" { - return fmt.Errorf("reth_db path not set") - } - res, err := FetchRethReceipts(job.rethDbPath, &job.block.Hash) - if err != nil { - return err - } - result = res - default: - err = fmt.Errorf("unknown receipt fetching method: %d", uint64(m)) - } - if err != nil { - job.requester.OnReceiptsMethodErr(m, err) - return err - } else { - if err := validateReceipts(job.block, job.receiptHash, job.txHashes, result); err != nil { - return err - } - job.result = result - return nil - } -} - -// Fetch makes the job fetch the receipts, and returns the results, if any. -// An error may be returned if the fetching is not successfully completed, -// and fetching may be continued/re-attempted by calling Fetch again. -// The job caches the result, so repeated Fetches add no additional cost. -// Fetch is safe to be called concurrently, and will lock to avoid duplicate work or internal inconsistency. -func (job *receiptsFetchingJob) Fetch(ctx context.Context) (types.Receipts, error) { - job.m.Lock() - defer job.m.Unlock() - - if job.result != nil { - return job.result, nil - } - - m := job.requester.PickReceiptsMethod(uint64(len(job.txHashes))) - - if m == EthGetTransactionReceiptBatch { - if err := job.runFetcher(ctx); err != nil { - return nil, err - } - } else { - if err := job.runAltMethod(ctx, m); err != nil { - return nil, err - } - } - - return job.result, nil -} diff --git a/op-service/sources/receipts_basic.go b/op-service/sources/receipts_basic.go new file mode 100644 index 000000000000..ec63c0565bf2 --- /dev/null +++ b/op-service/sources/receipts_basic.go @@ -0,0 +1,87 @@ +package sources + +import ( + "context" + "io" + "sync" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" +) + +type receiptsBatchCall = batching.IterativeBatchCall[common.Hash, *types.Receipt] + +type BasicRPCReceiptsFetcher struct { + client rpcClient + maxBatchSize int + + // calls caches uncompleted batch calls + calls map[common.Hash]*receiptsBatchCall + callsMu sync.Mutex +} + +func NewBasicRPCReceiptsFetcher(client rpcClient, maxBatchSize int) *BasicRPCReceiptsFetcher { + return &BasicRPCReceiptsFetcher{ + client: client, + maxBatchSize: maxBatchSize, + calls: make(map[common.Hash]*receiptsBatchCall), + } +} + +// FetchReceipts fetches receipts for the given block and transaction hashes +// it does not validate receipts, and expects the caller to do so +func (f *BasicRPCReceiptsFetcher) FetchReceipts(ctx context.Context, blockInfo eth.BlockInfo, txHashes []common.Hash) (types.Receipts, error) { + block := eth.ToBlockID(blockInfo) + call := f.getOrCreateBatchCall(block.Hash, txHashes) + + // Fetch all receipts + for { + if err := call.Fetch(ctx); err == io.EOF { + break + } else if err != nil { + return nil, err + } + } + res, err := call.Result() + if err != nil { + return nil, err + } + // call successful, remove from cache + f.deleteBatchCall(block.Hash) + return res, nil +} + +func (f *BasicRPCReceiptsFetcher) getOrCreateBatchCall(blockHash common.Hash, txHashes []common.Hash) *receiptsBatchCall { + f.callsMu.Lock() + defer f.callsMu.Unlock() + if call, ok := f.calls[blockHash]; ok { + return call + } + call := batching.NewIterativeBatchCall[common.Hash, *types.Receipt]( + txHashes, + makeReceiptRequest, + f.client.BatchCallContext, + f.client.CallContext, + f.maxBatchSize, + ) + f.calls[blockHash] = call + return call +} + +func (f *BasicRPCReceiptsFetcher) deleteBatchCall(blockHash common.Hash) { + f.callsMu.Lock() + defer f.callsMu.Unlock() + delete(f.calls, blockHash) +} + +func makeReceiptRequest(txHash common.Hash) (*types.Receipt, rpc.BatchElem) { + out := new(types.Receipt) + return out, rpc.BatchElem{ + Method: "eth_getTransactionReceipt", + Args: []any{txHash}, + Result: &out, // receipt may become nil, double pointer is intentional + } +} diff --git a/op-service/sources/receipts_basic_test.go b/op-service/sources/receipts_basic_test.go new file mode 100644 index 000000000000..3a0bbdf2219d --- /dev/null +++ b/op-service/sources/receipts_basic_test.go @@ -0,0 +1,178 @@ +package sources + +import ( + "context" + "errors" + "fmt" + "math/rand" + "sync/atomic" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +// simpleMockRPC is needed for some tests where the return value dynamically +// depends on the input, so that the test can set the function. +type simpleMockRPC struct { + callFn func(ctx context.Context, result any, method string, args ...any) error + batchCallFn func(ctx context.Context, b []rpc.BatchElem) error +} + +func (m *simpleMockRPC) CallContext(ctx context.Context, result any, method string, args ...any) error { + return m.callFn(ctx, result, method, args...) +} + +func (m *simpleMockRPC) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { + return m.batchCallFn(ctx, b) +} + +func TestBasicRPCReceiptsFetcher_Reuse(t *testing.T) { + require := require.New(t) + batchSize, txCount := 2, uint64(4) + block, receipts := randomRpcBlockAndReceipts(rand.New(rand.NewSource(123)), txCount) + txHashes := make([]common.Hash, 0, len(receipts)) + recMap := make(map[common.Hash]*types.Receipt, len(receipts)) + for _, rec := range receipts { + txHashes = append(txHashes, rec.TxHash) + recMap[rec.TxHash] = rec + } + mrpc := new(simpleMockRPC) + rp := NewBasicRPCReceiptsFetcher(mrpc, batchSize) + + // prepare mock + ctx, done := context.WithTimeout(context.Background(), 10*time.Second) + defer done() + // 1st fetching + response := map[common.Hash]bool{ + txHashes[0]: true, + txHashes[1]: true, + txHashes[2]: false, + txHashes[3]: false, + } + var numCalls atomic.Int32 + mrpc.batchCallFn = func(_ context.Context, b []rpc.BatchElem) (err error) { + numCalls.Add(1) + for i, el := range b { + if el.Method == "eth_getTransactionReceipt" { + txHash := el.Args[0].(common.Hash) + if response[txHash] { + // The IterativeBatchCall expects that the values are written + // to the fields of the allocated *types.Receipt. + **(el.Result.(**types.Receipt)) = *recMap[txHash] + } else { + err = errors.Join(err, fmt.Errorf("receipt[%d] error, hash %x", i, txHash)) + } + } else { + err = errors.Join(err, fmt.Errorf("unknown method %s", el.Method)) + } + } + return err + } + + bInfo, _, _ := block.Info(true, true) + + // 1st fetching should result in errors + recs, err := rp.FetchReceipts(ctx, bInfo, txHashes) + require.Error(err) + require.Nil(recs) + require.EqualValues(2, numCalls.Load()) + + // prepare 2nd fetching - all should succeed now + response[txHashes[2]] = true + response[txHashes[3]] = true + recs, err = rp.FetchReceipts(ctx, bInfo, txHashes) + require.NoError(err) + require.NotNil(recs) + for i, rec := range recs { + requireEqualReceipt(t, receipts[i], rec) + } + require.EqualValues(3, numCalls.Load()) +} + +func TestBasicRPCReceiptsFetcher_Concurrency(t *testing.T) { + require := require.New(t) + const numFetchers = 32 + batchSize, txCount := 4, uint64(18) // 4.5 * 4 + block, receipts := randomRpcBlockAndReceipts(rand.New(rand.NewSource(123)), txCount) + recMap := make(map[common.Hash]*types.Receipt, len(receipts)) + for _, rec := range receipts { + recMap[rec.TxHash] = rec + } + mrpc := new(mockRPC) + rp := NewBasicRPCReceiptsFetcher(mrpc, batchSize) + + // prepare mock + var numCalls atomic.Int32 + mrpc.On("BatchCallContext", mock.Anything, mock.AnythingOfType("[]rpc.BatchElem")). + Run(func(args mock.Arguments) { + numCalls.Add(1) + els := args.Get(1).([]rpc.BatchElem) + for _, el := range els { + if el.Method == "eth_getTransactionReceipt" { + txHash := el.Args[0].(common.Hash) + // The IterativeBatchCall expects that the values are written + // to the fields of the allocated *types.Receipt. + **(el.Result.(**types.Receipt)) = *recMap[txHash] + } + } + }). + Return([]error{nil}) + + runConcurrentFetchingTest(t, rp, numFetchers, receipts, block) + + mrpc.AssertExpectations(t) + finalNumCalls := int(numCalls.Load()) + require.NotZero(finalNumCalls, "BatchCallContext should have been called.") + require.Less(finalNumCalls, numFetchers, "Some IterativeBatchCalls should have been shared.") +} + +func runConcurrentFetchingTest(t *testing.T, rp ReceiptsProvider, numFetchers int, receipts types.Receipts, block *RPCBlock) { + require := require.New(t) + txHashes := receiptTxHashes(receipts) + + // start n fetchers + type fetchResult struct { + rs types.Receipts + err error + } + fetchResults := make(chan fetchResult, numFetchers) + barrier := make(chan struct{}) + bInfo, _, _ := block.Info(true, true) + ctx, done := context.WithTimeout(context.Background(), 10*time.Second) + defer done() + for i := 0; i < numFetchers; i++ { + go func() { + <-barrier + recs, err := rp.FetchReceipts(ctx, bInfo, txHashes) + fetchResults <- fetchResult{rs: recs, err: err} + }() + } + close(barrier) // Go! + + // assert results + for i := 0; i < numFetchers; i++ { + select { + case f := <-fetchResults: + require.NoError(f.err) + require.Len(f.rs, len(receipts)) + for j, r := range receipts { + requireEqualReceipt(t, r, f.rs[j]) + } + case <-ctx.Done(): + t.Fatal("Test timeout") + } + } +} + +func receiptTxHashes(receipts types.Receipts) []common.Hash { + txHashes := make([]common.Hash, 0, len(receipts)) + for _, rec := range receipts { + txHashes = append(txHashes, rec.TxHash) + } + return txHashes +} diff --git a/op-service/sources/receipts_caching.go b/op-service/sources/receipts_caching.go new file mode 100644 index 000000000000..a7127ef22bb0 --- /dev/null +++ b/op-service/sources/receipts_caching.go @@ -0,0 +1,92 @@ +package sources + +import ( + "context" + "sync" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources/caching" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +// A CachingReceiptsProvider caches successful receipt fetches from the inner +// ReceiptsProvider. It also avoids duplicate in-flight requests per block hash. +type CachingReceiptsProvider struct { + inner InnerReceiptsProvider + cache *caching.PreFetchCache[*ReceiptsHashPair] + // lock fetching process for each block hash to avoid duplicate requests + fetching map[common.Hash]*sync.Mutex + fetchingMu sync.Mutex // only protects map +} + +func NewCachingReceiptsProvider(inner InnerReceiptsProvider, m caching.Metrics, cacheSize int) *CachingReceiptsProvider { + return &CachingReceiptsProvider{ + inner: inner, + cache: caching.NewPreFetchCache[*ReceiptsHashPair](m, "receipts", cacheSize), + fetching: make(map[common.Hash]*sync.Mutex), + } +} + +func NewCachingRPCReceiptsProvider(client rpcClient, log log.Logger, config RPCReceiptsConfig, m caching.Metrics, cacheSize int) *CachingReceiptsProvider { + return NewCachingReceiptsProvider(NewRPCReceiptsFetcher(client, log, config), m, cacheSize) +} + +func (p *CachingReceiptsProvider) getOrCreateFetchingLock(blockHash common.Hash) *sync.Mutex { + p.fetchingMu.Lock() + defer p.fetchingMu.Unlock() + if mu, ok := p.fetching[blockHash]; ok { + return mu + } + mu := new(sync.Mutex) + p.fetching[blockHash] = mu + return mu +} + +func (p *CachingReceiptsProvider) deleteFetchingLock(blockHash common.Hash) { + p.fetchingMu.Lock() + defer p.fetchingMu.Unlock() + delete(p.fetching, blockHash) +} + +// FetchReceipts fetches receipts for the given block and transaction hashes +// it expects that the inner FetchReceipts implementation handles validation +func (p *CachingReceiptsProvider) FetchReceipts(ctx context.Context, blockInfo eth.BlockInfo, txHashes []common.Hash, isForPreFetch bool) (types.Receipts, error, bool) { + block := eth.ToBlockID(blockInfo) + var isFull bool + + if v, ok := p.cache.Get(block.Number, !isForPreFetch); ok && v.blockHash == block.Hash { + return v.receipts, nil, isFull + } + + mu := p.getOrCreateFetchingLock(block.Hash) + mu.Lock() + defer mu.Unlock() + // Other routine might have fetched in the meantime + if v, ok := p.cache.Get(block.Number, !isForPreFetch); ok && v.blockHash == block.Hash { + // we might have created a new lock above while the old + // fetching job completed. + p.deleteFetchingLock(block.Hash) + return v.receipts, nil, isFull + } + + isFull = p.cache.IsFull() + if isForPreFetch && isFull { + return nil, nil, true + } + + r, err := p.inner.FetchReceipts(ctx, blockInfo, txHashes) + if err != nil { + return nil, err, isFull + } + + p.cache.AddIfNotFull(block.Number, &ReceiptsHashPair{blockHash: block.Hash, receipts: r}) + // result now in cache, can delete fetching lock + p.deleteFetchingLock(block.Hash) + return r, nil, isFull +} + +func (p *CachingReceiptsProvider) GetReceiptsCache() *caching.PreFetchCache[*ReceiptsHashPair] { + return p.cache +} diff --git a/op-service/sources/receipts_caching_test.go b/op-service/sources/receipts_caching_test.go new file mode 100644 index 000000000000..e7891b9e34fd --- /dev/null +++ b/op-service/sources/receipts_caching_test.go @@ -0,0 +1,64 @@ +package sources + +import ( + "context" + "math/rand" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +type mockReceiptsProvider struct { + mock.Mock +} + +func (m *mockReceiptsProvider) FetchReceipts(ctx context.Context, blockInfo eth.BlockInfo, txHashes []common.Hash) (types.Receipts, error) { + block := eth.ToBlockID(blockInfo) + args := m.Called(ctx, block, txHashes) + return args.Get(0).(types.Receipts), args.Error(1) +} + +func TestCachingReceiptsProvider_Caching(t *testing.T) { + block, receipts := randomRpcBlockAndReceipts(rand.New(rand.NewSource(69)), 4) + txHashes := receiptTxHashes(receipts) + blockid := block.BlockID() + mrp := new(mockReceiptsProvider) + rp := NewCachingReceiptsProvider(mrp, nil, 1) + ctx, done := context.WithTimeout(context.Background(), 10*time.Second) + defer done() + + mrp.On("FetchReceipts", ctx, blockid, txHashes). + Return(types.Receipts(receipts), error(nil)). + Once() // receipts should be cached after first fetch + + bInfo, _, _ := block.Info(true, true) + for i := 0; i < 4; i++ { + gotRecs, err := rp.FetchReceipts(ctx, bInfo, txHashes) + require.NoError(t, err) + for i, gotRec := range gotRecs { + requireEqualReceipt(t, receipts[i], gotRec) + } + } + mrp.AssertExpectations(t) +} + +func TestCachingReceiptsProvider_Concurrency(t *testing.T) { + block, receipts := randomRpcBlockAndReceipts(rand.New(rand.NewSource(69)), 4) + txHashes := receiptTxHashes(receipts) + blockid := block.BlockID() + mrp := new(mockReceiptsProvider) + rp := NewCachingReceiptsProvider(mrp, nil, 1) + + mrp.On("FetchReceipts", mock.Anything, blockid, txHashes). + Return(types.Receipts(receipts), error(nil)). + Once() // receipts should be cached after first fetch + + runConcurrentFetchingTest(t, rp, 32, receipts, block) + + mrp.AssertExpectations(t) +} diff --git a/op-service/sources/receipts_rpc.go b/op-service/sources/receipts_rpc.go new file mode 100644 index 000000000000..ecf2c8582210 --- /dev/null +++ b/op-service/sources/receipts_rpc.go @@ -0,0 +1,396 @@ +package sources + +import ( + "context" + "fmt" + "time" + + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/sources/caching" + "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" + "github.com/ethereum/go-ethereum/rpc" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +func newRPCRecProviderFromConfig(client client.RPC, log log.Logger, metrics caching.Metrics, config *EthClientConfig) *CachingReceiptsProvider { + recCfg := RPCReceiptsConfig{ + MaxBatchSize: config.MaxRequestsPerBatch, + ProviderKind: config.RPCProviderKind, + MethodResetDuration: config.MethodResetDuration, + } + return NewCachingRPCReceiptsProvider(client, log, recCfg, metrics, config.ReceiptsCacheSize) +} + +type rpcClient interface { + CallContext(ctx context.Context, result any, method string, args ...any) error + BatchCallContext(ctx context.Context, b []rpc.BatchElem) error +} + +type RPCReceiptsFetcher struct { + client rpcClient + basic *BasicRPCReceiptsFetcher + + log log.Logger + + provKind RPCProviderKind + + // availableReceiptMethods tracks which receipt methods can be used for fetching receipts + // This may be modified concurrently, but we don't lock since it's a single + // uint64 that's not critical (fine to miss or mix up a modification) + availableReceiptMethods ReceiptsFetchingMethod + + // lastMethodsReset tracks when availableReceiptMethods was last reset. + // When receipt-fetching fails it falls back to available methods, + // but periodically it will try to reset to the preferred optimal methods. + lastMethodsReset time.Time + + // methodResetDuration defines how long we take till we reset lastMethodsReset + methodResetDuration time.Duration +} + +type RPCReceiptsConfig struct { + MaxBatchSize int + ProviderKind RPCProviderKind + MethodResetDuration time.Duration +} + +func NewRPCReceiptsFetcher(client rpcClient, log log.Logger, config RPCReceiptsConfig) *RPCReceiptsFetcher { + return &RPCReceiptsFetcher{ + client: client, + basic: NewBasicRPCReceiptsFetcher(client, config.MaxBatchSize), + log: log, + provKind: config.ProviderKind, + availableReceiptMethods: AvailableReceiptsFetchingMethods(config.ProviderKind), + lastMethodsReset: time.Now(), + methodResetDuration: config.MethodResetDuration, + } +} + +func (f *RPCReceiptsFetcher) FetchReceipts(ctx context.Context, blockInfo eth.BlockInfo, txHashes []common.Hash) (result types.Receipts, err error) { + m := f.PickReceiptsMethod(len(txHashes)) + block := eth.ToBlockID(blockInfo) + switch m { + case EthGetTransactionReceiptBatch: + result, err = f.basic.FetchReceipts(ctx, blockInfo, txHashes) + case AlchemyGetTransactionReceipts: + var tmp receiptsWrapper + err = f.client.CallContext(ctx, &tmp, "alchemy_getTransactionReceipts", blockHashParameter{BlockHash: block.Hash}) + result = tmp.Receipts + case DebugGetRawReceipts: + var rawReceipts []hexutil.Bytes + err = f.client.CallContext(ctx, &rawReceipts, "debug_getRawReceipts", block.Hash) + if err == nil { + if len(rawReceipts) == len(txHashes) { + result, err = eth.DecodeRawReceipts(block, rawReceipts, txHashes) + } else { + err = fmt.Errorf("got %d raw receipts, but expected %d", len(rawReceipts), len(txHashes)) + } + } + case ParityGetBlockReceipts: + err = f.client.CallContext(ctx, &result, "parity_getBlockReceipts", block.Hash) + case EthGetBlockReceipts: + err = f.client.CallContext(ctx, &result, "eth_getBlockReceipts", block.Hash) + case ErigonGetBlockReceiptsByBlockHash: + err = f.client.CallContext(ctx, &result, "erigon_getBlockReceiptsByBlockHash", block.Hash) + default: + err = fmt.Errorf("unknown receipt fetching method: %d", uint64(m)) + } + + if err != nil { + f.OnReceiptsMethodErr(m, err) + return nil, err + } + + if err = validateReceipts(block, blockInfo.ReceiptHash(), txHashes, result); err != nil { + return nil, err + } + + return +} + +// receiptsWrapper is a decoding type util. Alchemy in particular wraps the receipts array result. +type receiptsWrapper struct { + Receipts []*types.Receipt `json:"receipts"` +} + +func (f *RPCReceiptsFetcher) PickReceiptsMethod(txCount int) ReceiptsFetchingMethod { + txc := uint64(txCount) + if now := time.Now(); now.Sub(f.lastMethodsReset) > f.methodResetDuration { + m := AvailableReceiptsFetchingMethods(f.provKind) + if f.availableReceiptMethods != m { + f.log.Warn("resetting back RPC preferences, please review RPC provider kind setting", "kind", f.provKind.String()) + } + f.availableReceiptMethods = m + f.lastMethodsReset = now + } + return PickBestReceiptsFetchingMethod(f.provKind, f.availableReceiptMethods, txc) +} + +func (f *RPCReceiptsFetcher) OnReceiptsMethodErr(m ReceiptsFetchingMethod, err error) { + if unusableMethod(err) { + // clear the bit of the method that errored + f.availableReceiptMethods &^= m + f.log.Warn("failed to use selected RPC method for receipt fetching, temporarily falling back to alternatives", + "provider_kind", f.provKind, "failed_method", m, "fallback", f.availableReceiptMethods, "err", err) + } else { + f.log.Debug("failed to use selected RPC method for receipt fetching, but method does appear to be available, so we continue to use it", + "provider_kind", f.provKind, "failed_method", m, "fallback", f.availableReceiptMethods&^m, "err", err) + } +} + +// Cost break-down sources: +// Alchemy: https://docs.alchemy.com/reference/compute-units +// QuickNode: https://www.quicknode.com/docs/ethereum/api_credits +// Infura: no pricing table available. +// +// Receipts are encoded the same everywhere: +// +// blockHash, blockNumber, transactionIndex, transactionHash, from, to, cumulativeGasUsed, gasUsed, +// contractAddress, logs, logsBloom, status, effectiveGasPrice, type. +// +// Note that Alchemy/Geth still have a "root" field for legacy reasons, +// but ethereum does not compute state-roots per tx anymore, so quicknode and others do not serve this data. + +// RPCProviderKind identifies an RPC provider, used to hint at the optimal receipt fetching approach. +type RPCProviderKind string + +const ( + RPCKindAlchemy RPCProviderKind = "alchemy" + RPCKindQuickNode RPCProviderKind = "quicknode" + RPCKindInfura RPCProviderKind = "infura" + RPCKindParity RPCProviderKind = "parity" + RPCKindNethermind RPCProviderKind = "nethermind" + RPCKindDebugGeth RPCProviderKind = "debug_geth" + RPCKindErigon RPCProviderKind = "erigon" + RPCKindBasic RPCProviderKind = "basic" // try only the standard most basic receipt fetching + RPCKindAny RPCProviderKind = "any" // try any method available + RPCKindStandard RPCProviderKind = "standard" // try standard methods, including newer optimized standard RPC methods +) + +var RPCProviderKinds = []RPCProviderKind{ + RPCKindAlchemy, + RPCKindQuickNode, + RPCKindInfura, + RPCKindParity, + RPCKindNethermind, + RPCKindDebugGeth, + RPCKindErigon, + RPCKindBasic, + RPCKindAny, + RPCKindStandard, +} + +func (kind RPCProviderKind) String() string { + return string(kind) +} + +func (kind *RPCProviderKind) Set(value string) error { + if !ValidRPCProviderKind(RPCProviderKind(value)) { + return fmt.Errorf("unknown rpc kind: %q", value) + } + *kind = RPCProviderKind(value) + return nil +} + +func (kind *RPCProviderKind) Clone() any { + cpy := *kind + return &cpy +} + +func ValidRPCProviderKind(value RPCProviderKind) bool { + for _, k := range RPCProviderKinds { + if k == value { + return true + } + } + return false +} + +// ReceiptsFetchingMethod is a bitfield with 1 bit for each receipts fetching type. +// Depending on errors, tx counts and preferences the code may select different sets of fetching methods. +type ReceiptsFetchingMethod uint64 + +func (r ReceiptsFetchingMethod) String() string { + out := "" + x := r + addMaybe := func(m ReceiptsFetchingMethod, v string) { + if x&m != 0 { + out += v + x ^= x & m + } + if x != 0 { // add separator if there are entries left + out += ", " + } + } + addMaybe(EthGetTransactionReceiptBatch, "eth_getTransactionReceipt (batched)") + addMaybe(AlchemyGetTransactionReceipts, "alchemy_getTransactionReceipts") + addMaybe(DebugGetRawReceipts, "debug_getRawReceipts") + addMaybe(ParityGetBlockReceipts, "parity_getBlockReceipts") + addMaybe(EthGetBlockReceipts, "eth_getBlockReceipts") + addMaybe(ErigonGetBlockReceiptsByBlockHash, "erigon_getBlockReceiptsByBlockHash") + addMaybe(^ReceiptsFetchingMethod(0), "unknown") // if anything is left, describe it as unknown + return out +} + +const ( + // EthGetTransactionReceiptBatch is standard per-tx receipt fetching with JSON-RPC batches. + // Available in: standard, everywhere. + // - Alchemy: 15 CU / tx + // - Quicknode: 2 credits / tx + // Method: eth_getTransactionReceipt + // See: https://ethereum.github.io/execution-apis/api-documentation/ + EthGetTransactionReceiptBatch ReceiptsFetchingMethod = 1 << iota + // AlchemyGetTransactionReceipts is a special receipt fetching method provided by Alchemy. + // Available in: + // - Alchemy: 250 CU total + // Method: alchemy_getTransactionReceipts + // Params: + // - object with "blockNumber" or "blockHash" field + // Returns: "array of receipts" - docs lie, array is wrapped in a struct with single "receipts" field + // See: https://docs.alchemy.com/reference/alchemy-gettransactionreceipts#alchemy_gettransactionreceipts + AlchemyGetTransactionReceipts + // DebugGetRawReceipts is a debug method from Geth, faster by avoiding serialization and metadata overhead. + // Ideal for fast syncing from a local geth node. + // Available in: + // - Geth: free + // - QuickNode: 22 credits maybe? Unknown price, undocumented ("debug_getblockreceipts" exists in table though?) + // Method: debug_getRawReceipts + // Params: + // - string presenting a block number or hash + // Returns: list of strings, hex encoded RLP of receipts data. "consensus-encoding of all receipts in a single block" + // See: https://geth.ethereum.org/docs/rpc/ns-debug#debug_getrawreceipts + DebugGetRawReceipts + // ParityGetBlockReceipts is an old parity method, which has been adopted by Nethermind and some RPC providers. + // Available in: + // - Alchemy: 500 CU total + // - QuickNode: 59 credits - docs are wrong, not actually available anymore. + // - Any open-ethereum/parity legacy: free + // - Nethermind: free + // Method: parity_getBlockReceipts + // Params: + // Parity: "quantity or tag" + // Alchemy: string with block hash, number in hex, or block tag. + // Nethermind: very flexible: tag, number, hex or object with "requireCanonical"/"blockHash" fields. + // Returns: array of receipts + // See: + // - Parity: https://openethereum.github.io/JSONRPC-parity-module#parity_getblockreceipts + // - QuickNode: undocumented. + // - Alchemy: https://docs.alchemy.com/reference/eth-getblockreceipts + // - Nethermind: https://docs.nethermind.io/nethermind/ethereum-client/json-rpc/parity#parity_getblockreceipts + ParityGetBlockReceipts + // EthGetBlockReceipts is a previously non-standard receipt fetching method in the eth namespace, + // supported by some RPC platforms. + // This since has been standardized in https://github.com/ethereum/execution-apis/pull/438 and adopted in Geth: + // https://github.com/ethereum/go-ethereum/pull/27702 + // Available in: + // - Alchemy: 500 CU total (and deprecated) + // - QuickNode: 59 credits total (does not seem to work with block hash arg, inaccurate docs) + // - Standard, incl. Geth, Besu and Reth, and Nethermind has a PR in review. + // Method: eth_getBlockReceipts + // Params: + // - QuickNode: string, "quantity or tag", docs say incl. block hash, but API does not actually accept it. + // - Alchemy: string, block hash / num (hex) / block tag + // Returns: array of receipts + // See: + // - QuickNode: https://www.quicknode.com/docs/ethereum/eth_getBlockReceipts + // - Alchemy: https://docs.alchemy.com/reference/eth-getblockreceipts + // Erigon has this available, but does not support block-hash argument to the method: + // https://github.com/ledgerwatch/erigon/blob/287a3d1d6c90fc6a7a088b5ae320f93600d5a167/cmd/rpcdaemon/commands/eth_receipts.go#L571 + EthGetBlockReceipts + // ErigonGetBlockReceiptsByBlockHash is an Erigon-specific receipt fetching method, + // the same as EthGetBlockReceipts but supporting a block-hash argument. + // Available in: + // - Erigon + // Method: erigon_getBlockReceiptsByBlockHash + // Params: + // - Erigon: string, hex-encoded block hash + // Returns: + // - Erigon: array of json-ified receipts + // See: + // https://github.com/ledgerwatch/erigon/blob/287a3d1d6c90fc6a7a088b5ae320f93600d5a167/cmd/rpcdaemon/commands/erigon_receipts.go#LL391C24-L391C51 + ErigonGetBlockReceiptsByBlockHash + + // Other: + // - 250 credits, not supported, strictly worse than other options. In quicknode price-table. + // qn_getBlockWithReceipts - in price table, ? undocumented, but in quicknode "Single Flight RPC" description + // qn_getReceipts - in price table, ? undocumented, but in quicknode "Single Flight RPC" description + // debug_getBlockReceipts - ? undocumented, shows up in quicknode price table, not available. +) + +// AvailableReceiptsFetchingMethods selects receipt fetching methods based on the RPC provider kind. +func AvailableReceiptsFetchingMethods(kind RPCProviderKind) ReceiptsFetchingMethod { + switch kind { + case RPCKindAlchemy: + return AlchemyGetTransactionReceipts | EthGetBlockReceipts | EthGetTransactionReceiptBatch + case RPCKindQuickNode: + return DebugGetRawReceipts | EthGetBlockReceipts | EthGetTransactionReceiptBatch + case RPCKindInfura: + // Infura is big, but sadly does not support more optimized receipts fetching methods (yet?) + return EthGetTransactionReceiptBatch + case RPCKindParity: + return ParityGetBlockReceipts | EthGetTransactionReceiptBatch + case RPCKindNethermind: + return ParityGetBlockReceipts | EthGetTransactionReceiptBatch + case RPCKindDebugGeth: + return DebugGetRawReceipts | EthGetTransactionReceiptBatch + case RPCKindErigon: + return ErigonGetBlockReceiptsByBlockHash | EthGetTransactionReceiptBatch + case RPCKindBasic: + return EthGetTransactionReceiptBatch + case RPCKindAny: + // if it's any kind of RPC provider, then try all methods + return AlchemyGetTransactionReceipts | EthGetBlockReceipts | + DebugGetRawReceipts | ErigonGetBlockReceiptsByBlockHash | + ParityGetBlockReceipts | EthGetTransactionReceiptBatch + case RPCKindStandard: + return EthGetBlockReceipts | EthGetTransactionReceiptBatch + default: + return EthGetTransactionReceiptBatch + } +} + +// PickBestReceiptsFetchingMethod selects an RPC method that is still available, +// and optimal for fetching the given number of tx receipts from the specified provider kind. +func PickBestReceiptsFetchingMethod(kind RPCProviderKind, available ReceiptsFetchingMethod, txCount uint64) ReceiptsFetchingMethod { + // If we have optimized methods available, it makes sense to use them, but only if the cost is + // lower than fetching transactions one by one with the standard receipts RPC method. + if kind == RPCKindAlchemy { + if available&AlchemyGetTransactionReceipts != 0 && txCount > 250/15 { + return AlchemyGetTransactionReceipts + } + if available&EthGetBlockReceipts != 0 && txCount > 500/15 { + return EthGetBlockReceipts + } + return EthGetTransactionReceiptBatch + } else if kind == RPCKindQuickNode { + if available&DebugGetRawReceipts != 0 { + return DebugGetRawReceipts + } + if available&EthGetBlockReceipts != 0 && txCount > 59/2 { + return EthGetBlockReceipts + } + return EthGetTransactionReceiptBatch + } + // in order of preference (based on cost): check available methods + if available&AlchemyGetTransactionReceipts != 0 { + return AlchemyGetTransactionReceipts + } + if available&DebugGetRawReceipts != 0 { + return DebugGetRawReceipts + } + if available&ErigonGetBlockReceiptsByBlockHash != 0 { + return ErigonGetBlockReceiptsByBlockHash + } + if available&EthGetBlockReceipts != 0 { + return EthGetBlockReceipts + } + if available&ParityGetBlockReceipts != 0 { + return ParityGetBlockReceipts + } + // otherwise fall back on per-tx fetching + return EthGetTransactionReceiptBatch +} diff --git a/op-service/sources/receipts_test.go b/op-service/sources/receipts_test.go index fe79c136c096..235e51bb9042 100644 --- a/op-service/sources/receipts_test.go +++ b/op-service/sources/receipts_test.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "math/big" "math/rand" "testing" "time" @@ -17,6 +18,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/trie" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -25,9 +27,9 @@ type ethBackend struct { *mock.Mock } -func (b *ethBackend) GetBlockByHash(id common.Hash, fullTxs bool) (*rpcBlock, error) { +func (b *ethBackend) GetBlockByHash(id common.Hash, fullTxs bool) (*RPCBlock, error) { out := b.Mock.MethodCalled("eth_getBlockByHash", id, fullTxs) - return out[0].(*rpcBlock), nil + return out[0].(*RPCBlock), nil } func (b *ethBackend) GetTransactionReceipt(txHash common.Hash) (*types.Receipt, error) { @@ -96,7 +98,7 @@ type ReceiptsTestCase struct { name string providerKind RPCProviderKind staticMethod bool - setup func(t *testing.T) (*rpcBlock, []ReceiptsRequest) + setup func(t *testing.T) (*RPCBlock, []ReceiptsRequest) } func (tc *ReceiptsTestCase) Run(t *testing.T) { @@ -161,7 +163,7 @@ func (tc *ReceiptsTestCase) Run(t *testing.T) { if tc.staticMethod { // if static, instantly reset, for fast clock-independent testing testCfg.MethodResetDuration = 0 } - logger := testlog.Logger(t, log.LvlError) + logger := testlog.Logger(t, log.LevelError) ethCl, err := NewEthClient(client.NewBaseRPCClient(cl), logger, nil, testCfg, true) require.NoError(t, err) defer ethCl.Close() @@ -169,15 +171,13 @@ func (tc *ReceiptsTestCase) Run(t *testing.T) { for i, req := range requests { info, result, err := ethCl.FetchReceipts(context.Background(), block.Hash) if err == nil { - require.Nil(t, req.err, "error") + require.NoError(t, req.err, "error") require.Equal(t, block.Hash, info.Hash(), fmt.Sprintf("req %d blockhash", i)) - expectedJson, err := json.MarshalIndent(req.result, "", " ") - require.NoError(t, err) - gotJson, err := json.MarshalIndent(result, "", " ") - require.NoError(t, err) - require.Equal(t, string(expectedJson), string(gotJson), fmt.Sprintf("req %d result", i)) + for j, rec := range req.result { + requireEqualReceipt(t, rec, result[j], "req %d result %d", i, j) + } } else { - require.NotNil(t, req.err, "error") + require.Error(t, req.err, "error") require.Equal(t, req.err.Error(), err.Error(), fmt.Sprintf("req %d err", i)) } } @@ -185,10 +185,10 @@ func (tc *ReceiptsTestCase) Run(t *testing.T) { m.AssertExpectations(t) } -func randomRpcBlockAndReceipts(rng *rand.Rand, txCount uint64) (*rpcBlock, []*types.Receipt) { +func randomRpcBlockAndReceipts(rng *rand.Rand, txCount uint64) (*RPCBlock, []*types.Receipt) { block, receipts := testutils.RandomBlock(rng, txCount) - return &rpcBlock{ - rpcHeader: rpcHeader{ + return &RPCBlock{ + RPCHeader: RPCHeader{ ParentHash: block.ParentHash(), UncleHash: block.UncleHash(), Coinbase: block.Coinbase(), @@ -214,8 +214,8 @@ func randomRpcBlockAndReceipts(rng *rand.Rand, txCount uint64) (*rpcBlock, []*ty func TestEthClient_FetchReceipts(t *testing.T) { // Helper to quickly define the test case requests scenario: // each method fails to fetch the receipts, except the last - fallbackCase := func(txCount uint64, methods ...ReceiptsFetchingMethod) func(t *testing.T) (*rpcBlock, []ReceiptsRequest) { - return func(t *testing.T) (*rpcBlock, []ReceiptsRequest) { + fallbackCase := func(txCount uint64, methods ...ReceiptsFetchingMethod) func(t *testing.T) (*RPCBlock, []ReceiptsRequest) { + return func(t *testing.T) (*RPCBlock, []ReceiptsRequest) { block, receipts := randomRpcBlockAndReceipts(rand.New(rand.NewSource(123)), txCount) // zero out the data we don't want to verify for _, r := range receipts { @@ -338,3 +338,242 @@ func TestEthClient_FetchReceipts(t *testing.T) { t.Run(tc.name, tc.Run) } } + +func TestVerifyReceipts(t *testing.T) { + validData := func() (eth.BlockID, common.Hash, []common.Hash, []*types.Receipt) { + block := eth.BlockID{ + Hash: common.HexToHash("0x40fb7cc5fbc1ec594230a60648a442412116d50ae43d517ea458d8ea4e60bd1b"), + Number: 9998910, + } + txHashes := []common.Hash{ + common.HexToHash("0x61e4872004a80843fcbede236527bf24707f4e8f44a2704ed9c4fb91c87b0f29"), + common.HexToHash("0x0ae25ad9ff01fd74fa1b0c11f12fbb623a3f0553a0eed465a6dbf0962898c3b6"), + common.HexToHash("0x2de33b18143039dcdf88cb62c3f3dd8f3f5d9f29807edfd3b0507246c55f9cb8"), + common.HexToHash("0xb6a381d3c31df47da82ac807c3000ae4adf55e981715f56d13a27b220de20198"), + } + receipts := []*types.Receipt{ + { + Type: 2, + Status: 0, + CumulativeGasUsed: 0x3035b, + Bloom: types.BytesToBloom(common.FromHex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")), + Logs: nil, + TxHash: txHashes[0], + GasUsed: 0x3035b, + EffectiveGasPrice: big.NewInt(0x12a05f20a), + BlockHash: block.Hash, + BlockNumber: new(big.Int).SetUint64(block.Number), + TransactionIndex: 0, + }, + { + Type: 2, + Status: 1, + CumulativeGasUsed: 0xa9ae4, + Bloom: types.BytesToBloom(common.FromHex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")), + Logs: nil, + TxHash: txHashes[1], + GasUsed: 0x79789, + EffectiveGasPrice: big.NewInt(0xb2d05e0a), + BlockHash: block.Hash, + BlockNumber: new(big.Int).SetUint64(block.Number), + TransactionIndex: 1, + }, + { + Type: 0, + Status: 1, + CumulativeGasUsed: 0x101f09, + Bloom: types.BytesToBloom(common.FromHex("00000000000000000000000000000200000400000000000000000000000000800000000000040000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002002000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000800000000000000000000000000000000000000000000000000000400000000000000020000000000000000000000000002000000000000000000000000000000000000000000")), + Logs: []*types.Log{ + { + Address: common.HexToAddress("0x759c5e44a9e4be8b7e9bd25a790ceb662c924c45"), + Topics: []common.Hash{ + common.HexToHash("0x33830f93f4b524630176cdcbc04070b30ada13c6ad27081289131b77f178ff89"), + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000426a80"), + common.HexToHash("0x000000000000000000000000a6275ee214f80a532c3abee0a4cbbc2d1dc22a72"), + }, + Data: common.FromHex("00000000000000000000000000000000000000000000000000000000000005dc"), + BlockNumber: block.Number, + TxHash: txHashes[2], + TxIndex: 2, + BlockHash: block.Hash, + Index: 0, + Removed: false, + }, + }, + TxHash: txHashes[2], + GasUsed: 0x58425, + EffectiveGasPrice: big.NewInt(0xb2d05e00), + BlockHash: block.Hash, + BlockNumber: new(big.Int).SetUint64(block.Number), + TransactionIndex: 2, + }, + { + Type: 0, + Status: 1, + CumulativeGasUsed: 0x1227ab, + Bloom: types.BytesToBloom(common.FromHex("00000000000000000000000000000200000400000000000000000000000000800000000000040000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002002000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000800000000000000000000000000000000000000000000000000000400000000000000020000000000000000000000000002000000000000000000000000000000000000000000")), + Logs: []*types.Log{ + { + Address: common.HexToAddress("0x759c5e44a9e4be8b7e9bd25a790ceb662c924c45"), + Topics: []common.Hash{ + common.HexToHash("0x33830f93f4b524630176cdcbc04070b30ada13c6ad27081289131b77f178ff89"), + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000426a80"), + common.HexToHash("0x000000000000000000000000a6275ee214f80a532c3abee0a4cbbc2d1dc22a72"), + }, + Data: common.FromHex("00000000000000000000000000000000000000000000000000000000000005dc"), + BlockNumber: block.Number, + TxHash: txHashes[3], + TxIndex: 3, + BlockHash: block.Hash, + Index: 1, + Removed: false, + }, + }, + TxHash: txHashes[3], + GasUsed: 0x208a2, + EffectiveGasPrice: big.NewInt(0x59682f0a), + BlockHash: block.Hash, + BlockNumber: new(big.Int).SetUint64(block.Number), + TransactionIndex: 3, + }, + } + receiptsHash := types.DeriveSha(types.Receipts(receipts), trie.NewStackTrie(nil)) + return block, receiptsHash, txHashes, receipts + } + + t.Run("Valid", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.NoError(t, err) + }) + + t.Run("NotEnoughReceipts", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + err := validateReceipts(block, receiptHash, txHashes, receipts[1:]) + require.ErrorContains(t, err, fmt.Sprintf("got %d receipts but expected %d", len(receipts)-1, len(receipts))) + }) + + t.Run("TooManyReceipts", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + err := validateReceipts(block, receiptHash, txHashes, append(receipts, receipts[0])) + require.ErrorContains(t, err, fmt.Sprintf("got %d receipts but expected %d", len(receipts)+1, len(receipts))) + }) + + t.Run("NoTxButNotEmptyTrieRoot", func(t *testing.T) { + block, receiptHash, _, _ := validData() + err := validateReceipts(block, receiptHash, nil, nil) + require.ErrorContains(t, err, "no transactions, but got non-empty receipt trie root") + }) + + t.Run("NoTxWithEmptyTrieRoot", func(t *testing.T) { + block, _, _, _ := validData() + err := validateReceipts(block, types.EmptyRootHash, nil, nil) + require.NoError(t, err) + }) + + t.Run("IncorrectReceiptRoot", func(t *testing.T) { + block, _, txHashes, receipts := validData() + err := validateReceipts(block, common.Hash{0x35}, txHashes, receipts) + require.ErrorContains(t, err, "failed to fetch list of receipts: expected receipt root") + }) + + t.Run("NilReceipt", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[0] = nil + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "returns nil on retrieval") + }) + + t.Run("IncorrectTxIndex", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[0].TransactionIndex = 2 + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has unexpected tx index") + }) + + t.Run("Missing block number", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[0].BlockNumber = nil + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has unexpected nil block number") + }) + + t.Run("IncorrectBlockNumber", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[0].BlockNumber = big.NewInt(1234) + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has unexpected block number") + }) + + t.Run("IncorrectBlockHash", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[0].BlockHash = common.Hash{0x48} + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has unexpected block hash") + }) + + t.Run("IncorrectCumulativeUsed", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[1].CumulativeGasUsed = receipts[0].CumulativeGasUsed + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has invalid gas used metadata") + }) + + t.Run("IncorrectLogIndex", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[2].Logs[0].Index = 4 + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has unexpected log index") + }) + + t.Run("LogIndexNotBlockBased", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[3].Logs[0].Index = 0 + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has unexpected log index") + }) + + t.Run("IncorrectLogTxIndex", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[2].Logs[0].TxIndex = 1 + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has unexpected tx index") + }) + + t.Run("IncorrectLogBlockHash", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[2].Logs[0].BlockHash = common.Hash{0x64} + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has unexpected block hash") + }) + + t.Run("IncorrectLogBlockNumber", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[2].Logs[0].BlockNumber = 4727923 + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has unexpected block number") + }) + + t.Run("IncorrectLogTxHash", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[2].Logs[0].TxHash = common.Hash{0x87} + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "has unexpected tx hash") + }) + + t.Run("Removed", func(t *testing.T) { + block, receiptHash, txHashes, receipts := validData() + receipts[2].Logs[0].Removed = true + err := validateReceipts(block, receiptHash, txHashes, receipts) + require.ErrorContains(t, err, "must never be removed due to reorg") + }) +} + +func requireEqualReceipt(t *testing.T, exp, act *types.Receipt, msgAndArgs ...any) { + t.Helper() + expJson, err := json.MarshalIndent(exp, "", " ") + require.NoError(t, err, msgAndArgs...) + actJson, err := json.MarshalIndent(act, "", " ") + require.NoError(t, err, msgAndArgs...) + require.Equal(t, string(expJson), string(actJson), msgAndArgs...) +} diff --git a/op-service/sources/reth_db.go b/op-service/sources/reth_db.go index 2579b95f3f87..aba2d8f25bff 100644 --- a/op-service/sources/reth_db.go +++ b/op-service/sources/reth_db.go @@ -3,13 +3,17 @@ package sources import ( + "context" "encoding/json" "fmt" - "unsafe" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources/caching" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" ) /* @@ -63,3 +67,38 @@ func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, e return receipts, nil } + +type RethDBReceiptsFetcher struct { + dbPath string + // TODO(8225): Now that we have reading from a Reth DB encapsulated here, + // We could store a reference to the RethDB here instead of just a db path, + // which would be more optimal. + // We could move the opening of the RethDB and creation of the db reference + // into NewRethDBReceiptsFetcher. +} + +var _ ReceiptsProvider = (*RethDBReceiptsFetcher)(nil) + +func NewRethDBReceiptsFetcher(dbPath string) *RethDBReceiptsFetcher { + return &RethDBReceiptsFetcher{ + dbPath: dbPath, + } +} + +func (f *RethDBReceiptsFetcher) FetchReceipts(ctx context.Context, block eth.BlockInfo, txHashes []common.Hash) (types.Receipts, error) { + hash := block.Hash() + return FetchRethReceipts(f.dbPath, &hash) +} + +func NewCachingRethDBReceiptsFetcher(dbPath string, m caching.Metrics, cacheSize int) *CachingReceiptsProvider { + return NewCachingReceiptsProvider(NewRethDBReceiptsFetcher(dbPath), m, cacheSize) +} + +const buildRethdb = true + +func newRecProviderFromConfig(client client.RPC, log log.Logger, metrics caching.Metrics, config *EthClientConfig) *CachingReceiptsProvider { + if dbPath := config.RethDBPath; dbPath != "" { + return NewCachingRethDBReceiptsFetcher(dbPath, metrics, config.ReceiptsCacheSize) + } + return newRPCRecProviderFromConfig(client, log, metrics, config) +} diff --git a/op-service/sources/reth_db_stub.go b/op-service/sources/reth_db_stub.go index be685a1d5a9c..2ddc9c545168 100644 --- a/op-service/sources/reth_db_stub.go +++ b/op-service/sources/reth_db_stub.go @@ -3,11 +3,13 @@ package sources import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/sources/caching" + "github.com/ethereum/go-ethereum/log" ) -// FetchRethReceipts stub; Not available without `rethdb` build tag. -func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, error) { - panic("unimplemented! Did you forget to enable the `rethdb` build tag?") +const buildRethdb = false + +func newRecProviderFromConfig(client client.RPC, log log.Logger, metrics caching.Metrics, config *EthClientConfig) *CachingReceiptsProvider { + return newRPCRecProviderFromConfig(client, log, metrics, config) } diff --git a/op-service/sources/reth_db_test.go b/op-service/sources/reth_db_test.go new file mode 100644 index 000000000000..c98cf07a6153 --- /dev/null +++ b/op-service/sources/reth_db_test.go @@ -0,0 +1,43 @@ +//go:build rethdb + +package sources + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" +) + +func TestRethDBReceiptsLoad(t *testing.T) { + t.Parallel() + + // ETH Mainnet block #18,663,292 + // + // https://etherscan.io/tx/0x88b2d153a4e893ba91ac235325c44b1aa0c802fcb42657701e1a73e1c675f7ca + // + // NOTE: The block hash differs from the live block due to a state root mismatch. In order to generate + // a testdata database with only this block in it, the state root of the block was modified. + // Old State Root: 0xaf81a692d228d56d35c80d65aeba59636b4671403054f6c57446c0e3e4d951c8 + // New State Root (Empty MPT): 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 + blockHash := common.HexToHash("0x6a229123d607c2232a8b0bdd36f90745945d05181018e64e60ff2b93ab6b52e5") + res, err := FetchRethReceipts("../rethdb-reader/testdata/db", &blockHash) + require.NoError(t, err) + + receipt := (*types.Receipt)(res[0]) + require.Equal(t, receipt.Type, uint8(2)) + require.Equal(t, receipt.Status, uint64(1)) + require.Equal(t, receipt.CumulativeGasUsed, uint64(115_316)) + require.Equal(t, receipt.Bloom, types.BytesToBloom(common.FromHex("00200000000000000000000080001000000000000000000000000000000000000000000000000000000000000000100002000100080000000000000000000000000000000000000000000008000000200000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000400000000000001000000000000000100000000080000004000000000000000000000000000000000000002000000000000000000000000000000000000000006000000000000000000000000000000000000001000000000000000000000200000000000000100000000020000000000000000000000000000000010"))) + require.Equal(t, receipt.Logs[0].Address, common.HexToAddress("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")) + require.Equal(t, receipt.Logs[0].Topics[0], common.HexToHash("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")) + require.Equal(t, receipt.Logs[0].Topics[1], common.HexToHash("00000000000000000000000000000000003b3cc22af3ae1eac0440bcee416b40")) + require.Equal(t, receipt.Logs[0].Data, common.FromHex("00000000000000000000000000000000000000000000000008a30cd230000000")) + require.Equal(t, receipt.TxHash, common.HexToHash("0x88b2d153a4e893ba91ac235325c44b1aa0c802fcb42657701e1a73e1c675f7ca")) + + require.Equal(t, receipt.BlockHash, blockHash) + require.Equal(t, receipt.BlockNumber, big.NewInt(18_663_292)) + require.Equal(t, receipt.TransactionIndex, uint(0)) +} diff --git a/op-service/sources/rollupclient.go b/op-service/sources/rollupclient.go index 863305d6a101..96cd166732a9 100644 --- a/op-service/sources/rollupclient.go +++ b/op-service/sources/rollupclient.go @@ -3,9 +3,10 @@ package sources import ( "context" + "golang.org/x/exp/slog" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/client" @@ -26,6 +27,12 @@ func (r *RollupClient) OutputAtBlock(ctx context.Context, blockNum uint64) (*eth return output, err } +func (r *RollupClient) SafeHeadAtL1Block(ctx context.Context, blockNum uint64) (*eth.SafeHeadResponse, error) { + var output *eth.SafeHeadResponse + err := r.rpc.CallContext(ctx, &output, "optimism_safeHeadAtL1Block", hexutil.Uint64(blockNum)) + return output, err +} + func (r *RollupClient) SyncStatus(ctx context.Context) (*eth.SyncStatus, error) { var output *eth.SyncStatus err := r.rpc.CallContext(ctx, &output, "optimism_syncStatus") @@ -60,7 +67,11 @@ func (r *RollupClient) SequencerActive(ctx context.Context) (bool, error) { return result, err } -func (r *RollupClient) SetLogLevel(ctx context.Context, lvl log.Lvl) error { +func (r *RollupClient) PostUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { + return r.rpc.CallContext(ctx, nil, "admin_postUnsafePayload", payload) +} + +func (r *RollupClient) SetLogLevel(ctx context.Context, lvl slog.Level) error { return r.rpc.CallContext(ctx, nil, "admin_setLogLevel", lvl.String()) } diff --git a/op-service/sources/sync_client.go b/op-service/sources/sync_client.go deleted file mode 100644 index 1b84d56a1f2d..000000000000 --- a/op-service/sources/sync_client.go +++ /dev/null @@ -1,191 +0,0 @@ -package sources - -import ( - "context" - "errors" - "fmt" - "io" - "sync" - "time" - - "github.com/ethereum-optimism/optimism/op-node/rollup" - "github.com/ethereum-optimism/optimism/op-service/client" - "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum-optimism/optimism/op-service/retry" - "github.com/ethereum-optimism/optimism/op-service/sources/caching" - - "github.com/ethereum/go-ethereum/log" - "github.com/libp2p/go-libp2p/core/peer" -) - -var ErrNoUnsafeL2PayloadChannel = errors.New("unsafeL2Payloads channel must not be nil") - -// RpcSyncPeer is a mock PeerID for the RPC sync client. -var RpcSyncPeer peer.ID = "ALT_RPC_SYNC" - -// receivePayload queues the received payload for processing. -// This may return an error if there's no capacity for the payload. -type receivePayload = func(ctx context.Context, from peer.ID, payload *eth.ExecutionPayload) error - -type RPCSync interface { - io.Closer - // Start starts an additional worker syncing job - Start() error - // RequestL2Range signals that the given range should be fetched, implementing the alt-sync interface. - RequestL2Range(ctx context.Context, start uint64, end eth.L2BlockRef) error -} - -// SyncClient implements the driver AltSync interface, including support for fetching an open-ended chain of L2 blocks. -type SyncClient struct { - *L2Client - - requests chan uint64 - - resCtx context.Context - resCancel context.CancelFunc - - receivePayload receivePayload - wg sync.WaitGroup -} - -type SyncClientConfig struct { - L2ClientConfig -} - -func SyncClientDefaultConfig(config *rollup.Config, trustRPC bool) *SyncClientConfig { - return &SyncClientConfig{ - *L2ClientDefaultConfig(config, trustRPC), - } -} - -func NewSyncClient(receiver receivePayload, client client.RPC, log log.Logger, metrics caching.Metrics, config *SyncClientConfig) (*SyncClient, error) { - l2Client, err := NewL2Client(client, log, metrics, &config.L2ClientConfig) - if err != nil { - return nil, err - } - // This resource context is shared between all workers that may be started - resCtx, resCancel := context.WithCancel(context.Background()) - return &SyncClient{ - L2Client: l2Client, - resCtx: resCtx, - resCancel: resCancel, - requests: make(chan uint64, 128), - receivePayload: receiver, - }, nil -} - -// Start starts the syncing background work. This may not be called after Close(). -func (s *SyncClient) Start() error { - // TODO(CLI-3635): we can start multiple event loop runners as workers, to parallelize the work - s.wg.Add(1) - go s.eventLoop() - return nil -} - -// Close sends a signal to close all concurrent syncing work. -func (s *SyncClient) Close() error { - s.resCancel() - s.wg.Wait() - return nil -} - -func (s *SyncClient) RequestL2Range(ctx context.Context, start, end eth.L2BlockRef) error { - // Drain previous requests now that we have new information - for len(s.requests) > 0 { - select { // in case requests is being read at the same time, don't block on draining it. - case <-s.requests: - default: - break - } - } - - endNum := end.Number - if end == (eth.L2BlockRef{}) { - n, err := s.rollupCfg.TargetBlockNumber(uint64(time.Now().Unix())) - if err != nil { - return err - } - if n <= start.Number { - return nil - } - endNum = n - } - - // TODO(CLI-3635): optimize the by-range fetching with the Engine API payloads-by-range method. - - s.log.Info("Scheduling to fetch trailing missing payloads from backup RPC", "start", start, "end", endNum, "size", endNum-start.Number-1) - - for i := start.Number + 1; i < endNum; i++ { - select { - case s.requests <- i: - case <-ctx.Done(): - return ctx.Err() - } - } - return nil -} - -// eventLoop is the main event loop for the sync client. -func (s *SyncClient) eventLoop() { - defer s.wg.Done() - s.log.Info("Starting sync client event loop") - - backoffStrategy := &retry.ExponentialStrategy{ - Min: 1000 * time.Millisecond, - Max: 20_000 * time.Millisecond, - MaxJitter: 250 * time.Millisecond, - } - - for { - select { - case <-s.resCtx.Done(): - s.log.Debug("Shutting down RPC sync worker") - return - case reqNum := <-s.requests: - _, err := retry.Do(s.resCtx, 5, backoffStrategy, func() (interface{}, error) { - // Limit the maximum time for fetching payloads - ctx, cancel := context.WithTimeout(s.resCtx, time.Second*10) - defer cancel() - // We are only fetching one block at a time here. - return nil, s.fetchUnsafeBlockFromRpc(ctx, reqNum) - }) - if err != nil { - if err == s.resCtx.Err() { - return - } - s.log.Error("failed syncing L2 block via RPC", "err", err, "num", reqNum) - // Reschedule at end of queue - select { - case s.requests <- reqNum: - default: - // drop syncing job if we are too busy with sync jobs already. - } - } - } - } -} - -// fetchUnsafeBlockFromRpc attempts to fetch an unsafe execution payload from the backup unsafe sync RPC. -// WARNING: This function fails silently (aside from warning logs). -// -// Post Shanghai hardfork, the engine API's `PayloadBodiesByRange` method will be much more efficient, but for now, -// the `eth_getBlockByNumber` method is more widely available. -func (s *SyncClient) fetchUnsafeBlockFromRpc(ctx context.Context, blockNumber uint64) error { - s.log.Info("Requesting unsafe payload from backup RPC", "block number", blockNumber) - - payload, err := s.PayloadByNumber(ctx, blockNumber) - if err != nil { - return fmt.Errorf("failed to fetch payload by number (%d): %w", blockNumber, err) - } - // Note: the underlying RPC client used for syncing verifies the execution payload blockhash, if set to untrusted. - - s.log.Info("Received unsafe payload from backup RPC", "payload", payload.ID()) - - // Send the retrieved payload to the `unsafeL2Payloads` channel. - if err = s.receivePayload(ctx, RpcSyncPeer, payload); err != nil { - return fmt.Errorf("failed to send payload %s into the driver's unsafeL2Payloads channel: %w", payload.ID(), err) - } else { - s.log.Debug("Sent received payload into the driver's unsafeL2Payloads channel", "payload", payload.ID()) - return nil - } -} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-receipts_data.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-receipts-hash_data.json similarity index 100% rename from op-service/sources/testdata/data/blocks/post-shanghai-bad-receipts_data.json rename to op-service/sources/testdata/data/blocks/post-shanghai-bad-receipts-hash_data.json diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-receipts-hash_metadata.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-receipts-hash_metadata.json new file mode 100644 index 000000000000..62535fdc0388 --- /dev/null +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-receipts-hash_metadata.json @@ -0,0 +1 @@ +{"name":"post-shanghai-bad-receipts-hash","fail":true, "reason":"failed to verify block hash"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-receipts_metadata.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-receipts_metadata.json deleted file mode 100644 index 4da07c88cd37..000000000000 --- a/op-service/sources/testdata/data/blocks/post-shanghai-bad-receipts_metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"post-shanghai-bad-receipts","fail":true} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-hash_data.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-hash_data.json new file mode 100644 index 000000000000..f82f515d96dd --- /dev/null +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-hash_data.json @@ -0,0 +1 @@ +{"baseFeePerGas":"0x3fb7c357","difficulty":"0x0","extraData":"0x","gasLimit":"0x1c9c380","gasUsed":"0x18f759","hash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","logsBloom":"0x020010404000001a0000021000000080001100410000100001000010040200980220400000008806200200000100000000000000000000008000000400042000000050000040000112080808800002044000040004042008800480002000000000000002020020000042002400000820000080040000000010200010020010100101212050000008000000008000001010200c80000112010000438040020400000000202400000000002002a0210402000622010000000001700144000040000000002204000000c000410105024010000808000000002004002000000261000000822200200800881000000012500400400000000000000040010000800000","miner":"0x000095e79eac4d76aab57cb2c1f091d553b36ca0","mixHash":"0x5b53dc49cbab268ef9950b1d81b5e36a1b2f1b97aee1b7ff6e4db0e06c29a8b0","nonce":"0x0000000000000000","number":"0x84161e","parentHash":"0x72d92c1498e05952988d4e79a695928a6bcbd37239f8a1734051263b4d3504b8","receiptsRoot":"0xaff90ae18dcc35924a4bddb68d403b8b7812c10c3ea2a114f34105c87d75bcdb","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2a51","stateRoot":"0xc56738518b2c7854a640ae25996d2211c9ef0dd2e4dd9e59e9d9cacef39622da","timestamp":"0x64110a5c","totalDifficulty":"0xa4a470","transactions":[{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x1b7aa44088a0ea95bdc65fef6e5071e946bf7d8f","gas":"0x5208","gasPrice":"0x4159f01735","hash":"0x1e8f148a9aea7d8d16ea6e9446723b8f262e8bcd89c7c961d52046ebd43b4598","input":"0x","nonce":"0x279ad","to":"0xa21765a03dd41e2783696d314f235f4d520f6cac","transactionIndex":"0x0","value":"0x3782dace9d90000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xf9eca8b74ccaec5f4a83e981baeb8602f38d0271179c592b4a18f3866316a367","s":"0x350a9d26718d1fa9dc4f268f9c0e18fb96dbc037816ca8fc20f33f1a76f9f501"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4d9a852e6aecd3a6e87fece2ca109780e45e6f2d","gas":"0x160ab","gasPrice":"0xd4babc57","maxFeePerGas":"0x11407d03e","maxPriorityFeePerGas":"0x9502f900","hash":"0xab5c870f4c367012bd763172afbfbe68fbf35336a66ae41aff3f2c9dbf4ea3f8","input":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200c479c99d58d7fbee5ee3aef5001431073a3d465bdfa46cf747a7c0b9289607864736f6c634300080d0033","nonce":"0xafd","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x48f6acf4ac4371eb96ffca8cdef5b7704ea8c68a631d1c02927036d4ce92567e","s":"0x1f12261ddde63fd3da2ed9ea1bcbb4b0f25af898248c805a9d4b0a6e42caf9c8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xce297b30e56bf2f6142c4048fbae1cb8a756fefd","gas":"0x557300","gasPrice":"0xd4babc57","maxFeePerGas":"0xfabdd183","maxPriorityFeePerGas":"0x9502f900","hash":"0xa81fd92b2d0f0bbd3cc355f869cca3243c98c5e2641db9ecf3eeabb3b13bff6a","input":"0x7bbaf1ea0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000","nonce":"0xad92","to":"0x4c0ce02c1219ce5d2afffba97e484272a4637b49","transactionIndex":"0x2","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xd11b842a5f7b0e020470e764b443fafc4044327bca8dbb37131425359abace2","s":"0x1009867573946fb0a4a35339a6eaaece4d0a168b2346539076e6319e9a466b1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x47a916d0b694c95bc0c09953c1a6e22c8867be32","gas":"0x5208","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xa92c7b720c08c83f1a0ed7e4c163200e30a3a8c03fcc5a51e685ea20cd0cb577","input":"0x","nonce":"0x2","to":"0xf955dfe99bbfd06a8be208274cd654ecfb66a45e","transactionIndex":"0x3","value":"0x11c37937e08000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeecd431225215c3ddc2e13cf16fa29f9a2ab1afbaa02988f3ceac27416edf0f5","s":"0x6494062330a9d509f7c778cb45cbcc9932e5f9b4ec94a1ec315f579f8d973b7b","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x672d214fe4db218defae698085a3ccefc773dfa9","gas":"0xf4f6","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0x6921b429ad2ec1e97d3457049ad2e893b5a0349beba47ca1c74a9540af75347a","input":"0xa1ddc546000000000000000000000000000000000000000000000000000000000000118f","nonce":"0x8e","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x4","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4732ad21401b509bebb947a8566127fba1e245eb5a262ddc522d6867ab80567e","s":"0x2153013617fefdb06db0a7316d8883056441d33c2abf5ed6291fa0e3cc5c3a2f","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x0b12f7f996579fe7d9302d2574910121c214ee15","gas":"0x56a8","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xf776b2da0b835dde05d0d8b76fd19385d61e7055036cf637f804b36dc94f2384","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f40000000000000000000000000b12f7f996579fe7d9302d2574910121c214ee150000000000000000000000000000000000000000000000000000000000000000","nonce":"0xe","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x5","value":"0x2386f26fc10000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc4505d4c46ef9a0103178e5ef4fbc857114ae5c4686b68b74d07c3ee3a86e575","s":"0x74db34fd675bea7d2ee74f14fd8709cb88c7d22c2267d12f2c671b5ebc180bd5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd36aac0c9676e984d72823fb662ce94d3ab5e551","gas":"0xff212","gasPrice":"0x991ff257","maxFeePerGas":"0xd86d063e","maxPriorityFeePerGas":"0x59682f00","hash":"0x9a08d899cd14ebb930ed59fa774afdb88a22615b3a931e930931ea54d26dc0bc","input":"0x49160658babdf216946a22b96c966ceeba750f14807726306ebeed500a2621a7481df010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000084d6f6f6e6265616d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078434133633746363939643335333137316438434643364236334431433764333841333233373238300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b616f73c8d00641109f0000054f967b8a135e44e233da070ea88c5e4a53bacac0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c6a3a17399d88e5dfd2de4fa41dcccade6a2d2170000000000000000000000008676147503f761e44b85df01811edd52be01b56c000000000000000000000000000000000000000000000000d02ab486cedc00000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x7121","to":"0x2d276bd64fe8643a1d76b2e9530c753423e972c1","transactionIndex":"0x6","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xce452361d331baf2ac86947a1b3b454b3e842923e1f39139b33a572845dd5d7c","s":"0x388126881782af5a146ce8409f1e3a2c9a4cadcfe9a2c1d27258af6e4eb5cec1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x326ff","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0x0fe0d97e25d5eb11a33a3e8278584c3780941fc2675bdf8fc547cee3d1fd3b17","input":"0xa4110dbe190e65a7fe0ad5acd305c6446a02cb39de30f382000fe67927434063bf4c4b2ca86b3ee6d039dc7a0268f9e1c39266c3f12a752a7eb72f0895dedf62291fd292","nonce":"0x12e","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x46819bb540fa459a5a0cbf041a0286507d597fc8958a6af8b9ce193f00005238","s":"0x31495c58bf4b74925f870c59635912681bee947b1cb4b08cc19f22421b1a10ab","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x3270b","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0xef47a60f57f177a683c723c658137efab66d311e1c5abbc4d74f653535144d03","input":"0xa4110dbe18eba3e815ec7fcb03a8eea0487209c3253024d1dc4f36f775a43fdd3e409b74c0a5c88e54f39b88db6f185a41431b204120d3e66c9b08b86f5e8382623327e5","nonce":"0x12f","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x8","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4d7e11fe3914763a2735493a62b71ae0028e75a750a8b06407996cf478e273c8","s":"0x60c18fdf948721f96fdc2efbf694910122e82191c7a40a5caab247c06ab7f3cf","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x7712a1f96b3f37c3dd88a22d4f7a7977b937fe62","gas":"0x1ff06","gasPrice":"0x991ff257","maxFeePerGas":"0xcf662006","maxPriorityFeePerGas":"0x59682f00","hash":"0xe23a5b35faae5335adc5aca38c5d633b00438b798c2053104b8df48406c9b141","input":"0x3ff9751b0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000002e516d566e75374a51566f445271536748427a72615970374879373848774a744c4669366e5546436f775447647a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d5439716b3343525962464457704446596541763854384831676e6f6e67774b6868354a36384e4c6b4c6972360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041c9f31b989aaa745aecc563139f89c8ab3ab492e725d1e0305b7d602fcbf9293c463f0d2e4f5fb0c9efb54eb2cde9af10ebc9c3676f2334007291ffa8efb40adb1c00000000000000000000000000000000000000000000000000000000000000","nonce":"0x16","to":"0xc3b87ea584cb9cb5a4523e2bed16a34bf7746317","transactionIndex":"0x9","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcc693a9544394653e1f393f02635e2c1f78b5e6c26c4d00a867bcf4adc2bc09e","s":"0x23f4b71b773c19f77cf251b2aeea03f2696bddd847d1f6d75acd2fbea6a543e4","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0x1b2e020","gasPrice":"0x8f0d3617","maxFeePerGas":"0x1cb3abd5a","maxPriorityFeePerGas":"0x4f5572c0","hash":"0xd8cea4ba619b317bc05d58534af73beec6c2548b31b24d4dc61c9bbd29cfa17a","input":"0x","nonce":"0x4d","to":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8dae28608985d6ab47cbe122ee88972e38664cede30978f41944f347bad86e5c","s":"0x17c2898b39b7e3b874dc78e7df3fcff68f4d715385c632aad4bdf6e62505651c","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6999c36394dd5d3d3295af63a4736ad6bd279448","gas":"0x14d94","gasPrice":"0x7b528d57","maxFeePerGas":"0x7df743e0","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x79a4b9d90b02c768baaad305f266281213cc75062cbe99a13222cc0c4b509498","input":"0x6a7612020000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000a4ec6cb13f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003826d8d7371becafc0afedc3fe85b699b87f4357d55ec39ce83c510ed7d70ff514dce8236351f4627ccec6a7d9a67bc6fc2ec17ca76411113c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000006999c36394dd5d3d3295af63a4736ad6bd27944800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000","nonce":"0x13","to":"0xdce8236351f4627ccec6a7d9a67bc6fc2ec17ca7","transactionIndex":"0xb","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x669487011643510f7512ec15b07d74efb853ba4ad9fe9c7e9850ccf24e3d4c53","s":"0x2191f9ee81087e1df833e69d6129ec330ed4c99be2031060834e22c589fcf79b","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xf6e4d9c4","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x6790a3bbddbeb21fcb736a59b3775755051c3a6344d8390cf8ca27f2e8a814f0","input":"0x6871ee40","nonce":"0x4","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xc","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa7a58ab858e5dd87b9a74d550e5716ac40ddefd1c21d5baa51e542f4f941d73e","s":"0x1fd0cb1563df0368bd332717d7c8210187cd1ac2ff44f61f5242fc02eaa0c2fe","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x87ec7ace5442db252b5751ffddd38dcb04b088d36b6b0e526ff25607a4293c81","input":"0xcb40cbfd","nonce":"0x5","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xd","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x8e4bd40195bdfaa868af97dbf22e0b74295d95564a8381bc9bcfe1af3cde2cdb","s":"0x62057dc87c8b2b197d12c648233aab4134b7c2a2f65db89a49728564f3d0864d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x40cb487ecffda94f97ce7fc0f7163f2f024235df2c8291169edc80dac063e6d0","input":"0xcb40cbfd","nonce":"0x6","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xe","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x993c4386ffc2bd63a48dd31cf5f65aa355cba3c063b08778b328d748937098e5","s":"0x203b1faf595628dd78e760bcc1740065625abb6cf00b1b17224e10fa6b424e43","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xafc7682751d3654f34958e3fb660971bf5918367","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xefb40664","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xb76bb3d88c9b30d927c45ccfcf8d5b0054411ac8501ad588822a7d04690cccf6","input":"0x40c10f19000000000000000000000000afc7682751d3654f34958e3fb660971bf59183670000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x20","to":"0x84ced17d95f3ec7230baf4a369f1e624ae60090d","transactionIndex":"0xf","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x78e9d29c606f6a61a1428ed7326df05210d802c3061f3b469847cc461eb48025","s":"0x517afe5a21175f186233ae7a6c090cd33e028a77e5854e98eb2fa4c9284430e7","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0x16ba45bce","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x798ebe823209869347c08bd81e04fbf60e9bdfe44b1cc923215182d0cf3d4edb","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000032","nonce":"0x4e","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x10","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xbe2aa95f4c32188c9ecbae97286ab983f7cc5a7017d46c404f8eb80b55e2dc13","s":"0x55d8968f509f51633f49260178941fd5a3db999e1995206348d7a3f05152b3d5","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0xc6132c0c","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xbe68a7e02725f799a65ebb069ccc83a014ac7c40e4119bf7c220a2f6ddfee295","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000064","nonce":"0x4f","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x11","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1750ed45d0d2d048a61dcc3ff3e7ad0cbd395b77698c4f2eeb6baaea4c966d96","s":"0xe646e3a87b6dc50439468bcfd24cbf12a6f95b2762f1527c97a7d1b7f03530e","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd0c0338baac9ce09c1d1caab88b4360507061e37","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1918167aa","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xc90c3a72efe81331727fcce4b5bd4906066da314ca9a0b44023a6b09ea7e8114","input":"0x4e71d92d","nonce":"0xe7","to":"0x0137d796936e199b917b93118eb4e002508a48bd","transactionIndex":"0x12","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x22222ce8fe753082c8e5dc7478fa7b87db9c8d0fb070ebc88ab015db13fd6bb","s":"0x6dceadecf6f6a3ddc433a547dba6d5fcdfb7d006ce09eeae1c06c1828ef9fff9","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1a4019792","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x619a6cbd43cde074d314c19623bd66d9fb1e13c158d7138775236f798dc1245e","input":"0x1da1db5e00000000000000000000000000000000000000000000000000001b5ec4ff740d","nonce":"0x10","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x733c496e8c84f78d113bc8b5ad6d04a133bb10bbcecf0db93d97eeedfa3d984a","s":"0x6627c16aa7dea27db44c0f0641c30ffd544b9b9b1c299dc60611e1e01c714ee8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x11df0","gasPrice":"0x7b528d57","maxFeePerGas":"0x1d3fbccb8","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xca5a56cd77b9e5b0e79020cc6346edf205bc11e901984d805125f28c2e6686e6","input":"0xd7c01032000000000000000000000000356f24c0f3187a6dcb949e4a60aa0a74a8a0327e0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd","nonce":"0x11","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x4aa872c1a7da70126917604193717575b91407f82449bca956d4089b90cd902","s":"0x4b5f788c68024f8958f66e8c768a8e0f65ef297c4ffd420a715258b0a55cb0a0","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1e706c8d2","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x999c9ddeed67c6ef6fbf02a6e977a6c1b68e18d24814e51643c7157b87a43e0a","input":"0xa8b78ed0","nonce":"0x3","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf1ca074104ee0b6a67223afd797654b8f21060453f7662dd7be79de938c396da","s":"0x4c9a4e56f0ad21e2dd8d1116c7a3e41ea2c6126853772f7897bd959e81e2e28a","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x2dc6c0","gasPrice":"0xd4babc57","maxFeePerGas":"0x21c13e710","maxPriorityFeePerGas":"0x9502f900","hash":"0x47c8f5d0b3778e4c34eba7fcc356fa04a5afd954ccf484728e72c002764dd3c4","input":"0xf688bcfb0000000000000000000000000000000000000000000000000000000005f5e100","nonce":"0x4","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x970982425d18b9949141bbabb5c5230fa168626ce210a97f3856d64700fc0eeb","s":"0x6fa6d0aea6ae48783d80c1e51cda47e11c28b90a5497579b93d7f242d786f67e","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4b596cebd02c35aa99878eb9ecb24d6f5ca5f865","gas":"0x5208","gasPrice":"0x68c88f79","maxFeePerGas":"0x68c88f79","maxPriorityFeePerGas":"0x68c88f79","hash":"0x396797ae0ebcdb72ff1f96fd08b6128f78acc7417353f142f1a5facd425a33e6","input":"0x","nonce":"0x1","to":"0x375980b8e1a417620ba9b18e5a9e0b17dccbac9d","transactionIndex":"0x17","value":"0x1c9a406c58878","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcb2a7b106097b2f2a61d3a048054a5175c386b1dcdd5b6fcd7849dcac7c32a66","s":"0x10aef76e98276c47470f04a599b81c260ace9d2f6adc95755c6d22d859e805a2","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0x1b2e020","gasPrice":"0x61010bda","maxFeePerGas":"0x61010bda","maxPriorityFeePerGas":"0x61010bda","hash":"0x454aa43d6546a6f62246826c16b7a49c6c704238c18802ef0d659922f23a573c","input":"0xe99a3f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee40000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e06defd69964a6ce467b87c64627a7a2be4be139b504757c625eb6114ec166557d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001f63c28250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf17500000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d5458000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000413e24433da3efc4c3cc305339a7b77a1b31abb4e4d4967e97e42aed1dd0bf98936f43035f40bc80f6f6e3a9cfb43524a1171ee7f21e9ac2fa586d33a31f10619d1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace5786000000000000000000000000000000000000000000000000000000000000012000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf1750000000000000000000000000000000000000000000000000000000000000ba200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175ffffffff09616c6c64617461","nonce":"0x82","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xc7ac308b1ae238cb2aa4b030ca79baffb7b498e1b10df0c3354b3cc19cfabac9","s":"0x2358b1093b9aab5fae0cf751766b0bb2e3d8cd2b18ca627e1e12520990a8ed6d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6ece61d29b90642941c41240da924690da145696","gas":"0x4399c","gasPrice":"0x506794e0","hash":"0x317ecb5bd19caa42a69f836d41556ebb0e0e00e1c6cd2dee230e6e6192612527","input":"0x46f83b5000000000000000000000000000000000000000000000000000000000000000654666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b000000000000000000000000000000000000000000000000000000000000000f4666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b","nonce":"0x2cc4","to":"0xa6bf2be6c60175601bf88217c75dd4b14abb5fbb","transactionIndex":"0x19","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x37aeab0db6d550e6cba2c04c9cb10a2af0fec0b11f6e04b85e1ea0b8b9defeae","s":"0x4f32f4ef74872e1385c25e69bf21ee049545a4d423e939eaff29677450efe9eb"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xc4a5c059840a146b81c77bf79f1398f2b3d28ca7","gas":"0x432ec","gasPrice":"0x45db0a51","hash":"0xc879285db5ef0a6bce98021584d16f134c1dc0aed8cc988802c4f72ba6877ff6","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1a7","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1a","value":"0x470efc4514e000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x237e3a541c5ab490843cdc20d0fcb7416bff8da471f6a11ae1b32d2bab119141","s":"0x3c8417d7a60bd5b0bcae4975dbb4aaee54a4b4d588226481be400843bfe2b64e"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0xffff","gasPrice":"0x44e9acbc","maxFeePerGas":"0x44e9acbc","maxPriorityFeePerGas":"0x44e9acbc","hash":"0xecaa2d6f597608307e5084854854ba6dc1e69395e2abea14f2c6a2fa1d6faf9a","input":"0xe2864fe300000000000000000000000000000000000000000000000000000000000000200000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace57860000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002004a8312e37fcecd450e6684009a2b54bc64f66afbe5217c7b2f63b03cd9980a9e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064893e8223d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a7640000aaaebeba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d54580000000000000000000000000000000000000000000000000000000000000000","nonce":"0x83","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x1b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa18772e4b9e1493ebfd5ae6219cc9ca060b71e83788fb614ab02b03fb36eaf1b","s":"0x482c7e50fde29bb4130fd6e723176e0e9913430ebb9260667d7fb55f5408d9c5","yParity":"0x1"}],"transactionsRoot":"0x038aa965036f8a4fc4825a83ae35ec6135b936ad429b47bd14961d744e2fc2ac","uncles":[],"withdrawals":[{"index":"0x1170","validatorIndex":"0x38c2c","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x66edfd65"},{"index":"0x1171","validatorIndex":"0x38c2d","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6cd228e4"},{"index":"0x1172","validatorIndex":"0x38c2e","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x77f3431b"},{"index":"0x1173","validatorIndex":"0x38c2f","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6b61f268"},{"index":"0x1174","validatorIndex":"0x38c30","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6e10bb21"},{"index":"0x1175","validatorIndex":"0x38c31","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6eb115a5"},{"index":"0x1176","validatorIndex":"0x38c32","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7caead1d"},{"index":"0x1177","validatorIndex":"0x38c33","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x772c0ddf"},{"index":"0x1178","validatorIndex":"0x38c34","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x75930a95"},{"index":"0x1179","validatorIndex":"0x38c35","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76a4db09"},{"index":"0x117a","validatorIndex":"0x38c36","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7e692b27"},{"index":"0x117b","validatorIndex":"0x38c37","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x72038ae6"},{"index":"0x117c","validatorIndex":"0x38c38","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6ccce352"},{"index":"0x117d","validatorIndex":"0x38c39","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x79ef6898"},{"index":"0x117e","validatorIndex":"0x38c3a","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6d58977d"},{"index":"0x117f","validatorIndex":"0x38c3b","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76f7d208"}],"withdrawalsRoot":"0xbe712c930a0665264b025ced87cc7839eef95a3cbc26dadc93e9e185a350ad28"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-hash_metadata.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-hash_metadata.json new file mode 100644 index 000000000000..33f6dc140e87 --- /dev/null +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-hash_metadata.json @@ -0,0 +1 @@ +{"name":"post-shanghai-bad-transactions-hash","fail":true, "reason":"failed to verify block hash"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-nil_data.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-nil_data.json new file mode 100644 index 000000000000..9c030f27cec1 --- /dev/null +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-nil_data.json @@ -0,0 +1 @@ +{"baseFeePerGas":"0x3fb7c357","difficulty":"0x0","extraData":"0x","gasLimit":"0x1c9c380","gasUsed":"0x18f759","hash":"0x0afe3cbfbf24c0b097b50864b8aaf9f819cf56d4b2b6a67b1edff20bc2a66ad2","logsBloom":"0x020010404000001a0000021000000080001100410000100001000010040200980220400000008806200200000100000000000000000000008000000400042000000050000040000112080808800002044000040004042008800480002000000000000002020020000042002400000820000080040000000010200010020010100101212050000008000000008000001010200c80000112010000438040020400000000202400000000002002a0210402000622010000000001700144000040000000002204000000c000410105024010000808000000002004002000000261000000822200200800881000000012500400400000000000000040010000800000","miner":"0x000095e79eac4d76aab57cb2c1f091d553b36ca0","mixHash":"0x5b53dc49cbab268ef9950b1d81b5e36a1b2f1b97aee1b7ff6e4db0e06c29a8b0","nonce":"0x0000000000000000","number":"0x84161e","parentHash":"0x72d92c1498e05952988d4e79a695928a6bcbd37239f8a1734051263b4d3504b8","receiptsRoot":"0xaff90ae18dcc35924a4bddb68d403b8b7812c10c3ea2a114f34105c87d75bcdb","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2a51","stateRoot":"0xc56738518b2c7854a640ae25996d2211c9ef0dd2e4dd9e59e9d9cacef39622da","timestamp":"0x64110a5c","totalDifficulty":"0xa4a470","transactions":[null,{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4d9a852e6aecd3a6e87fece2ca109780e45e6f2d","gas":"0x160ab","gasPrice":"0xd4babc57","maxFeePerGas":"0x11407d03e","maxPriorityFeePerGas":"0x9502f900","hash":"0xab5c870f4c367012bd763172afbfbe68fbf35336a66ae41aff3f2c9dbf4ea3f8","input":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200c479c99d58d7fbee5ee3aef5001431073a3d465bdfa46cf747a7c0b9289607864736f6c634300080d0033","nonce":"0xafd","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x48f6acf4ac4371eb96ffca8cdef5b7704ea8c68a631d1c02927036d4ce92567e","s":"0x1f12261ddde63fd3da2ed9ea1bcbb4b0f25af898248c805a9d4b0a6e42caf9c8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xce297b30e56bf2f6142c4048fbae1cb8a756fefd","gas":"0x557300","gasPrice":"0xd4babc57","maxFeePerGas":"0xfabdd183","maxPriorityFeePerGas":"0x9502f900","hash":"0xa81fd92b2d0f0bbd3cc355f869cca3243c98c5e2641db9ecf3eeabb3b13bff6a","input":"0x7bbaf1ea0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000","nonce":"0xad92","to":"0x4c0ce02c1219ce5d2afffba97e484272a4637b49","transactionIndex":"0x2","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xd11b842a5f7b0e020470e764b443fafc4044327bca8dbb37131425359abace2","s":"0x1009867573946fb0a4a35339a6eaaece4d0a168b2346539076e6319e9a466b1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x47a916d0b694c95bc0c09953c1a6e22c8867be32","gas":"0x5208","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xa92c7b720c08c83f1a0ed7e4c163200e30a3a8c03fcc5a51e685ea20cd0cb577","input":"0x","nonce":"0x2","to":"0xf955dfe99bbfd06a8be208274cd654ecfb66a45e","transactionIndex":"0x3","value":"0x11c37937e08000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeecd431225215c3ddc2e13cf16fa29f9a2ab1afbaa02988f3ceac27416edf0f5","s":"0x6494062330a9d509f7c778cb45cbcc9932e5f9b4ec94a1ec315f579f8d973b7b","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x672d214fe4db218defae698085a3ccefc773dfa9","gas":"0xf4f6","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0x6921b429ad2ec1e97d3457049ad2e893b5a0349beba47ca1c74a9540af75347a","input":"0xa1ddc546000000000000000000000000000000000000000000000000000000000000118f","nonce":"0x8e","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x4","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4732ad21401b509bebb947a8566127fba1e245eb5a262ddc522d6867ab80567e","s":"0x2153013617fefdb06db0a7316d8883056441d33c2abf5ed6291fa0e3cc5c3a2f","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x0b12f7f996579fe7d9302d2574910121c214ee15","gas":"0x56a8","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xf776b2da0b835dde05d0d8b76fd19385d61e7055036cf637f804b36dc94f2384","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f40000000000000000000000000b12f7f996579fe7d9302d2574910121c214ee150000000000000000000000000000000000000000000000000000000000000000","nonce":"0xe","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x5","value":"0x2386f26fc10000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc4505d4c46ef9a0103178e5ef4fbc857114ae5c4686b68b74d07c3ee3a86e575","s":"0x74db34fd675bea7d2ee74f14fd8709cb88c7d22c2267d12f2c671b5ebc180bd5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd36aac0c9676e984d72823fb662ce94d3ab5e551","gas":"0xff212","gasPrice":"0x991ff257","maxFeePerGas":"0xd86d063e","maxPriorityFeePerGas":"0x59682f00","hash":"0x9a08d899cd14ebb930ed59fa774afdb88a22615b3a931e930931ea54d26dc0bc","input":"0x49160658babdf216946a22b96c966ceeba750f14807726306ebeed500a2621a7481df010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000084d6f6f6e6265616d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078434133633746363939643335333137316438434643364236334431433764333841333233373238300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b616f73c8d00641109f0000054f967b8a135e44e233da070ea88c5e4a53bacac0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c6a3a17399d88e5dfd2de4fa41dcccade6a2d2170000000000000000000000008676147503f761e44b85df01811edd52be01b56c000000000000000000000000000000000000000000000000d02ab486cedc00000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x7121","to":"0x2d276bd64fe8643a1d76b2e9530c753423e972c1","transactionIndex":"0x6","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xce452361d331baf2ac86947a1b3b454b3e842923e1f39139b33a572845dd5d7c","s":"0x388126881782af5a146ce8409f1e3a2c9a4cadcfe9a2c1d27258af6e4eb5cec1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x326ff","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0x0fe0d97e25d5eb11a33a3e8278584c3780941fc2675bdf8fc547cee3d1fd3b17","input":"0xa4110dbe190e65a7fe0ad5acd305c6446a02cb39de30f382000fe67927434063bf4c4b2ca86b3ee6d039dc7a0268f9e1c39266c3f12a752a7eb72f0895dedf62291fd292","nonce":"0x12e","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x46819bb540fa459a5a0cbf041a0286507d597fc8958a6af8b9ce193f00005238","s":"0x31495c58bf4b74925f870c59635912681bee947b1cb4b08cc19f22421b1a10ab","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x3270b","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0xef47a60f57f177a683c723c658137efab66d311e1c5abbc4d74f653535144d03","input":"0xa4110dbe18eba3e815ec7fcb03a8eea0487209c3253024d1dc4f36f775a43fdd3e409b74c0a5c88e54f39b88db6f185a41431b204120d3e66c9b08b86f5e8382623327e5","nonce":"0x12f","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x8","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4d7e11fe3914763a2735493a62b71ae0028e75a750a8b06407996cf478e273c8","s":"0x60c18fdf948721f96fdc2efbf694910122e82191c7a40a5caab247c06ab7f3cf","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x7712a1f96b3f37c3dd88a22d4f7a7977b937fe62","gas":"0x1ff06","gasPrice":"0x991ff257","maxFeePerGas":"0xcf662006","maxPriorityFeePerGas":"0x59682f00","hash":"0xe23a5b35faae5335adc5aca38c5d633b00438b798c2053104b8df48406c9b141","input":"0x3ff9751b0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000002e516d566e75374a51566f445271536748427a72615970374879373848774a744c4669366e5546436f775447647a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d5439716b3343525962464457704446596541763854384831676e6f6e67774b6868354a36384e4c6b4c6972360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041c9f31b989aaa745aecc563139f89c8ab3ab492e725d1e0305b7d602fcbf9293c463f0d2e4f5fb0c9efb54eb2cde9af10ebc9c3676f2334007291ffa8efb40adb1c00000000000000000000000000000000000000000000000000000000000000","nonce":"0x16","to":"0xc3b87ea584cb9cb5a4523e2bed16a34bf7746317","transactionIndex":"0x9","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcc693a9544394653e1f393f02635e2c1f78b5e6c26c4d00a867bcf4adc2bc09e","s":"0x23f4b71b773c19f77cf251b2aeea03f2696bddd847d1f6d75acd2fbea6a543e4","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0x1b2e020","gasPrice":"0x8f0d3617","maxFeePerGas":"0x1cb3abd5a","maxPriorityFeePerGas":"0x4f5572c0","hash":"0xd8cea4ba619b317bc05d58534af73beec6c2548b31b24d4dc61c9bbd29cfa17a","input":"0x","nonce":"0x4d","to":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8dae28608985d6ab47cbe122ee88972e38664cede30978f41944f347bad86e5c","s":"0x17c2898b39b7e3b874dc78e7df3fcff68f4d715385c632aad4bdf6e62505651c","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6999c36394dd5d3d3295af63a4736ad6bd279448","gas":"0x14d94","gasPrice":"0x7b528d57","maxFeePerGas":"0x7df743e0","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x79a4b9d90b02c768baaad305f266281213cc75062cbe99a13222cc0c4b509498","input":"0x6a7612020000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000a4ec6cb13f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003826d8d7371becafc0afedc3fe85b699b87f4357d55ec39ce83c510ed7d70ff514dce8236351f4627ccec6a7d9a67bc6fc2ec17ca76411113c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000006999c36394dd5d3d3295af63a4736ad6bd27944800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000","nonce":"0x13","to":"0xdce8236351f4627ccec6a7d9a67bc6fc2ec17ca7","transactionIndex":"0xb","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x669487011643510f7512ec15b07d74efb853ba4ad9fe9c7e9850ccf24e3d4c53","s":"0x2191f9ee81087e1df833e69d6129ec330ed4c99be2031060834e22c589fcf79b","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xf6e4d9c4","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x6790a3bbddbeb21fcb736a59b3775755051c3a6344d8390cf8ca27f2e8a814f0","input":"0x6871ee40","nonce":"0x4","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xc","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa7a58ab858e5dd87b9a74d550e5716ac40ddefd1c21d5baa51e542f4f941d73e","s":"0x1fd0cb1563df0368bd332717d7c8210187cd1ac2ff44f61f5242fc02eaa0c2fe","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x87ec7ace5442db252b5751ffddd38dcb04b088d36b6b0e526ff25607a4293c81","input":"0xcb40cbfd","nonce":"0x5","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xd","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x8e4bd40195bdfaa868af97dbf22e0b74295d95564a8381bc9bcfe1af3cde2cdb","s":"0x62057dc87c8b2b197d12c648233aab4134b7c2a2f65db89a49728564f3d0864d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x40cb487ecffda94f97ce7fc0f7163f2f024235df2c8291169edc80dac063e6d0","input":"0xcb40cbfd","nonce":"0x6","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xe","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x993c4386ffc2bd63a48dd31cf5f65aa355cba3c063b08778b328d748937098e5","s":"0x203b1faf595628dd78e760bcc1740065625abb6cf00b1b17224e10fa6b424e43","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xafc7682751d3654f34958e3fb660971bf5918367","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xefb40664","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xb76bb3d88c9b30d927c45ccfcf8d5b0054411ac8501ad588822a7d04690cccf6","input":"0x40c10f19000000000000000000000000afc7682751d3654f34958e3fb660971bf59183670000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x20","to":"0x84ced17d95f3ec7230baf4a369f1e624ae60090d","transactionIndex":"0xf","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x78e9d29c606f6a61a1428ed7326df05210d802c3061f3b469847cc461eb48025","s":"0x517afe5a21175f186233ae7a6c090cd33e028a77e5854e98eb2fa4c9284430e7","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0x16ba45bce","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x798ebe823209869347c08bd81e04fbf60e9bdfe44b1cc923215182d0cf3d4edb","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000032","nonce":"0x4e","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x10","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xbe2aa95f4c32188c9ecbae97286ab983f7cc5a7017d46c404f8eb80b55e2dc13","s":"0x55d8968f509f51633f49260178941fd5a3db999e1995206348d7a3f05152b3d5","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0xc6132c0c","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xbe68a7e02725f799a65ebb069ccc83a014ac7c40e4119bf7c220a2f6ddfee295","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000064","nonce":"0x4f","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x11","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1750ed45d0d2d048a61dcc3ff3e7ad0cbd395b77698c4f2eeb6baaea4c966d96","s":"0xe646e3a87b6dc50439468bcfd24cbf12a6f95b2762f1527c97a7d1b7f03530e","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd0c0338baac9ce09c1d1caab88b4360507061e37","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1918167aa","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xc90c3a72efe81331727fcce4b5bd4906066da314ca9a0b44023a6b09ea7e8114","input":"0x4e71d92d","nonce":"0xe7","to":"0x0137d796936e199b917b93118eb4e002508a48bd","transactionIndex":"0x12","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x22222ce8fe753082c8e5dc7478fa7b87db9c8d0fb070ebc88ab015db13fd6bb","s":"0x6dceadecf6f6a3ddc433a547dba6d5fcdfb7d006ce09eeae1c06c1828ef9fff9","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1a4019792","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x619a6cbd43cde074d314c19623bd66d9fb1e13c158d7138775236f798dc1245e","input":"0x1da1db5e00000000000000000000000000000000000000000000000000001b5ec4ff740d","nonce":"0x10","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x733c496e8c84f78d113bc8b5ad6d04a133bb10bbcecf0db93d97eeedfa3d984a","s":"0x6627c16aa7dea27db44c0f0641c30ffd544b9b9b1c299dc60611e1e01c714ee8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x11df0","gasPrice":"0x7b528d57","maxFeePerGas":"0x1d3fbccb8","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xca5a56cd77b9e5b0e79020cc6346edf205bc11e901984d805125f28c2e6686e6","input":"0xd7c01032000000000000000000000000356f24c0f3187a6dcb949e4a60aa0a74a8a0327e0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd","nonce":"0x11","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x4aa872c1a7da70126917604193717575b91407f82449bca956d4089b90cd902","s":"0x4b5f788c68024f8958f66e8c768a8e0f65ef297c4ffd420a715258b0a55cb0a0","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1e706c8d2","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x999c9ddeed67c6ef6fbf02a6e977a6c1b68e18d24814e51643c7157b87a43e0a","input":"0xa8b78ed0","nonce":"0x3","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf1ca074104ee0b6a67223afd797654b8f21060453f7662dd7be79de938c396da","s":"0x4c9a4e56f0ad21e2dd8d1116c7a3e41ea2c6126853772f7897bd959e81e2e28a","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x2dc6c0","gasPrice":"0xd4babc57","maxFeePerGas":"0x21c13e710","maxPriorityFeePerGas":"0x9502f900","hash":"0x47c8f5d0b3778e4c34eba7fcc356fa04a5afd954ccf484728e72c002764dd3c4","input":"0xf688bcfb0000000000000000000000000000000000000000000000000000000005f5e100","nonce":"0x4","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x970982425d18b9949141bbabb5c5230fa168626ce210a97f3856d64700fc0eeb","s":"0x6fa6d0aea6ae48783d80c1e51cda47e11c28b90a5497579b93d7f242d786f67e","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4b596cebd02c35aa99878eb9ecb24d6f5ca5f865","gas":"0x5208","gasPrice":"0x68c88f79","maxFeePerGas":"0x68c88f79","maxPriorityFeePerGas":"0x68c88f79","hash":"0x396797ae0ebcdb72ff1f96fd08b6128f78acc7417353f142f1a5facd425a33e6","input":"0x","nonce":"0x1","to":"0x375980b8e1a417620ba9b18e5a9e0b17dccbac9d","transactionIndex":"0x17","value":"0x1c9a406c58878","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcb2a7b106097b2f2a61d3a048054a5175c386b1dcdd5b6fcd7849dcac7c32a66","s":"0x10aef76e98276c47470f04a599b81c260ace9d2f6adc95755c6d22d859e805a2","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0x1b2e020","gasPrice":"0x61010bda","maxFeePerGas":"0x61010bda","maxPriorityFeePerGas":"0x61010bda","hash":"0x454aa43d6546a6f62246826c16b7a49c6c704238c18802ef0d659922f23a573c","input":"0xe99a3f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee40000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e06defd69964a6ce467b87c64627a7a2be4be139b504757c625eb6114ec166557d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001f63c28250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf17500000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d5458000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000413e24433da3efc4c3cc305339a7b77a1b31abb4e4d4967e97e42aed1dd0bf98936f43035f40bc80f6f6e3a9cfb43524a1171ee7f21e9ac2fa586d33a31f10619d1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace5786000000000000000000000000000000000000000000000000000000000000012000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf1750000000000000000000000000000000000000000000000000000000000000ba200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175ffffffff09616c6c64617461","nonce":"0x82","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xc7ac308b1ae238cb2aa4b030ca79baffb7b498e1b10df0c3354b3cc19cfabac9","s":"0x2358b1093b9aab5fae0cf751766b0bb2e3d8cd2b18ca627e1e12520990a8ed6d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6ece61d29b90642941c41240da924690da145696","gas":"0x4399c","gasPrice":"0x506794e0","hash":"0x317ecb5bd19caa42a69f836d41556ebb0e0e00e1c6cd2dee230e6e6192612527","input":"0x46f83b5000000000000000000000000000000000000000000000000000000000000000654666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b000000000000000000000000000000000000000000000000000000000000000f4666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b","nonce":"0x2cc4","to":"0xa6bf2be6c60175601bf88217c75dd4b14abb5fbb","transactionIndex":"0x19","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x37aeab0db6d550e6cba2c04c9cb10a2af0fec0b11f6e04b85e1ea0b8b9defeae","s":"0x4f32f4ef74872e1385c25e69bf21ee049545a4d423e939eaff29677450efe9eb"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xc4a5c059840a146b81c77bf79f1398f2b3d28ca7","gas":"0x432ec","gasPrice":"0x45db0a51","hash":"0xc879285db5ef0a6bce98021584d16f134c1dc0aed8cc988802c4f72ba6877ff6","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1a7","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1a","value":"0x470efc4514e000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x237e3a541c5ab490843cdc20d0fcb7416bff8da471f6a11ae1b32d2bab119141","s":"0x3c8417d7a60bd5b0bcae4975dbb4aaee54a4b4d588226481be400843bfe2b64e"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0xffff","gasPrice":"0x44e9acbc","maxFeePerGas":"0x44e9acbc","maxPriorityFeePerGas":"0x44e9acbc","hash":"0xecaa2d6f597608307e5084854854ba6dc1e69395e2abea14f2c6a2fa1d6faf9a","input":"0xe2864fe300000000000000000000000000000000000000000000000000000000000000200000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace57860000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002004a8312e37fcecd450e6684009a2b54bc64f66afbe5217c7b2f63b03cd9980a9e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064893e8223d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a7640000aaaebeba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d54580000000000000000000000000000000000000000000000000000000000000000","nonce":"0x83","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x1b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa18772e4b9e1493ebfd5ae6219cc9ca060b71e83788fb614ab02b03fb36eaf1b","s":"0x482c7e50fde29bb4130fd6e723176e0e9913430ebb9260667d7fb55f5408d9c5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xdb33365a8730de2f7574ff1189fb9d337bf4c36d","gas":"0x61a80","gasPrice":"0x433653c8","maxFeePerGas":"0x828367af","maxPriorityFeePerGas":"0x37e9071","hash":"0x4dd69b69a568ff30ae439e2ded72fbd7f2e7aaa345836703663f155c749c5eed","input":"0x7f34c0ddc6e984f46ab7c13b7a53643096e79c39103dc74550204d5bd1b5206ef5a2f49689071bb6a332212df26aa57cd4d1e3c0894187a9fc5e5d686cbedba5b187470f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000e8c44c30e8e52c38ac7bd232e7b7f0c7463a535100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002e516d5044645856613738437a6b7856325a364e52777a67685a785872736e75397261616a695a7555423569465a62000000000000000000000000000000000000","nonce":"0x2b57","to":"0xb8ad54644e2371cbb7940b9fa0936f399ba7495f","transactionIndex":"0x1c","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa1fb0e5662b54ceb3dc1623ebfb200668433cb27252d553669bcd136387394f3","s":"0x27c2f8e19f69a52a0960f05d8b21f11c313dd3e86a7139b5783a18353c407415","yParity":"0x0"}],"transactionsRoot":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","uncles":[],"withdrawals":[{"index":"0x1170","validatorIndex":"0x38c2c","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x66edfd65"},{"index":"0x1171","validatorIndex":"0x38c2d","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6cd228e4"},{"index":"0x1172","validatorIndex":"0x38c2e","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x77f3431b"},{"index":"0x1173","validatorIndex":"0x38c2f","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6b61f268"},{"index":"0x1174","validatorIndex":"0x38c30","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6e10bb21"},{"index":"0x1175","validatorIndex":"0x38c31","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6eb115a5"},{"index":"0x1176","validatorIndex":"0x38c32","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7caead1d"},{"index":"0x1177","validatorIndex":"0x38c33","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x772c0ddf"},{"index":"0x1178","validatorIndex":"0x38c34","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x75930a95"},{"index":"0x1179","validatorIndex":"0x38c35","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76a4db09"},{"index":"0x117a","validatorIndex":"0x38c36","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7e692b27"},{"index":"0x117b","validatorIndex":"0x38c37","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x72038ae6"},{"index":"0x117c","validatorIndex":"0x38c38","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6ccce352"},{"index":"0x117d","validatorIndex":"0x38c39","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x79ef6898"},{"index":"0x117e","validatorIndex":"0x38c3a","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6d58977d"},{"index":"0x117f","validatorIndex":"0x38c3b","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76f7d208"}],"withdrawalsRoot":"0xbe712c930a0665264b025ced87cc7839eef95a3cbc26dadc93e9e185a350ad28"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-nil_metadata.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-nil_metadata.json new file mode 100644 index 000000000000..9fc85fff5071 --- /dev/null +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions-nil_metadata.json @@ -0,0 +1 @@ +{"name":"post-shanghai-bad-transactions-nil","fail":true, "reason": "block tx 0 is nil"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions_data.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions_data.json index 8986999d9ebe..1c7594777a15 100644 --- a/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions_data.json +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions_data.json @@ -1 +1 @@ -{"baseFeePerGas":"0x3fb7c357","difficulty":"0x0","extraData":"0x","gasLimit":"0x1c9c380","gasUsed":"0x18f759","hash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","logsBloom":"0x020010404000001a0000021000000080001100410000100001000010040200980220400000008806200200000100000000000000000000008000000400042000000050000040000112080808800002044000040004042008800480002000000000000002020020000042002400000820000080040000000010200010020010100101212050000008000000008000001010200c80000112010000438040020400000000202400000000002002a0210402000622010000000001700144000040000000002204000000c000410105024010000808000000002004002000000261000000822200200800881000000012500400400000000000000040010000800000","miner":"0x000095e79eac4d76aab57cb2c1f091d553b36ca0","mixHash":"0x5b53dc49cbab268ef9950b1d81b5e36a1b2f1b97aee1b7ff6e4db0e06c29a8b0","nonce":"0x0000000000000000","number":"0x84161e","parentHash":"0x72d92c1498e05952988d4e79a695928a6bcbd37239f8a1734051263b4d3504b8","receiptsRoot":"0xaff90ae18dcc35924a4bddb68d403b8b7812c10c3ea2a114f34105c87d75bcdb","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2a51","stateRoot":"0xc56738518b2c7854a640ae25996d2211c9ef0dd2e4dd9e59e9d9cacef39622da","timestamp":"0x64110a5c","totalDifficulty":"0xa4a470","transactions":[{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x1b7aa44088a0ea95bdc65fef6e5071e946bf7d8f","gas":"0x5208","gasPrice":"0x4159f01735","hash":"0x1e8f148a9aea7d8d16ea6e9446723b8f262e8bcd89c7c961d52046ebd43b4598","input":"0x","nonce":"0x279ad","to":"0xa21765a03dd41e2783696d314f235f4d520f6cac","transactionIndex":"0x0","value":"0x3782dace9d90000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xf9eca8b74ccaec5f4a83e981baeb8602f38d0271179c592b4a18f3866316a367","s":"0x350a9d26718d1fa9dc4f268f9c0e18fb96dbc037816ca8fc20f33f1a76f9f501"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4d9a852e6aecd3a6e87fece2ca109780e45e6f2d","gas":"0x160ab","gasPrice":"0xd4babc57","maxFeePerGas":"0x11407d03e","maxPriorityFeePerGas":"0x9502f900","hash":"0xab5c870f4c367012bd763172afbfbe68fbf35336a66ae41aff3f2c9dbf4ea3f8","input":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200c479c99d58d7fbee5ee3aef5001431073a3d465bdfa46cf747a7c0b9289607864736f6c634300080d0033","nonce":"0xafd","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x48f6acf4ac4371eb96ffca8cdef5b7704ea8c68a631d1c02927036d4ce92567e","s":"0x1f12261ddde63fd3da2ed9ea1bcbb4b0f25af898248c805a9d4b0a6e42caf9c8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xce297b30e56bf2f6142c4048fbae1cb8a756fefd","gas":"0x557300","gasPrice":"0xd4babc57","maxFeePerGas":"0xfabdd183","maxPriorityFeePerGas":"0x9502f900","hash":"0xa81fd92b2d0f0bbd3cc355f869cca3243c98c5e2641db9ecf3eeabb3b13bff6a","input":"0x7bbaf1ea0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000","nonce":"0xad92","to":"0x4c0ce02c1219ce5d2afffba97e484272a4637b49","transactionIndex":"0x2","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xd11b842a5f7b0e020470e764b443fafc4044327bca8dbb37131425359abace2","s":"0x1009867573946fb0a4a35339a6eaaece4d0a168b2346539076e6319e9a466b1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x47a916d0b694c95bc0c09953c1a6e22c8867be32","gas":"0x5208","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xa92c7b720c08c83f1a0ed7e4c163200e30a3a8c03fcc5a51e685ea20cd0cb577","input":"0x","nonce":"0x2","to":"0xf955dfe99bbfd06a8be208274cd654ecfb66a45e","transactionIndex":"0x3","value":"0x11c37937e08000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeecd431225215c3ddc2e13cf16fa29f9a2ab1afbaa02988f3ceac27416edf0f5","s":"0x6494062330a9d509f7c778cb45cbcc9932e5f9b4ec94a1ec315f579f8d973b7b","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x672d214fe4db218defae698085a3ccefc773dfa9","gas":"0xf4f6","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0x6921b429ad2ec1e97d3457049ad2e893b5a0349beba47ca1c74a9540af75347a","input":"0xa1ddc546000000000000000000000000000000000000000000000000000000000000118f","nonce":"0x8e","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x4","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4732ad21401b509bebb947a8566127fba1e245eb5a262ddc522d6867ab80567e","s":"0x2153013617fefdb06db0a7316d8883056441d33c2abf5ed6291fa0e3cc5c3a2f","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x0b12f7f996579fe7d9302d2574910121c214ee15","gas":"0x56a8","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xf776b2da0b835dde05d0d8b76fd19385d61e7055036cf637f804b36dc94f2384","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f40000000000000000000000000b12f7f996579fe7d9302d2574910121c214ee150000000000000000000000000000000000000000000000000000000000000000","nonce":"0xe","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x5","value":"0x2386f26fc10000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc4505d4c46ef9a0103178e5ef4fbc857114ae5c4686b68b74d07c3ee3a86e575","s":"0x74db34fd675bea7d2ee74f14fd8709cb88c7d22c2267d12f2c671b5ebc180bd5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd36aac0c9676e984d72823fb662ce94d3ab5e551","gas":"0xff212","gasPrice":"0x991ff257","maxFeePerGas":"0xd86d063e","maxPriorityFeePerGas":"0x59682f00","hash":"0x9a08d899cd14ebb930ed59fa774afdb88a22615b3a931e930931ea54d26dc0bc","input":"0x49160658babdf216946a22b96c966ceeba750f14807726306ebeed500a2621a7481df010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000084d6f6f6e6265616d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078434133633746363939643335333137316438434643364236334431433764333841333233373238300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b616f73c8d00641109f0000054f967b8a135e44e233da070ea88c5e4a53bacac0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c6a3a17399d88e5dfd2de4fa41dcccade6a2d2170000000000000000000000008676147503f761e44b85df01811edd52be01b56c000000000000000000000000000000000000000000000000d02ab486cedc00000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x7121","to":"0x2d276bd64fe8643a1d76b2e9530c753423e972c1","transactionIndex":"0x6","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xce452361d331baf2ac86947a1b3b454b3e842923e1f39139b33a572845dd5d7c","s":"0x388126881782af5a146ce8409f1e3a2c9a4cadcfe9a2c1d27258af6e4eb5cec1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x326ff","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0x0fe0d97e25d5eb11a33a3e8278584c3780941fc2675bdf8fc547cee3d1fd3b17","input":"0xa4110dbe190e65a7fe0ad5acd305c6446a02cb39de30f382000fe67927434063bf4c4b2ca86b3ee6d039dc7a0268f9e1c39266c3f12a752a7eb72f0895dedf62291fd292","nonce":"0x12e","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x46819bb540fa459a5a0cbf041a0286507d597fc8958a6af8b9ce193f00005238","s":"0x31495c58bf4b74925f870c59635912681bee947b1cb4b08cc19f22421b1a10ab","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x3270b","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0xef47a60f57f177a683c723c658137efab66d311e1c5abbc4d74f653535144d03","input":"0xa4110dbe18eba3e815ec7fcb03a8eea0487209c3253024d1dc4f36f775a43fdd3e409b74c0a5c88e54f39b88db6f185a41431b204120d3e66c9b08b86f5e8382623327e5","nonce":"0x12f","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x8","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4d7e11fe3914763a2735493a62b71ae0028e75a750a8b06407996cf478e273c8","s":"0x60c18fdf948721f96fdc2efbf694910122e82191c7a40a5caab247c06ab7f3cf","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x7712a1f96b3f37c3dd88a22d4f7a7977b937fe62","gas":"0x1ff06","gasPrice":"0x991ff257","maxFeePerGas":"0xcf662006","maxPriorityFeePerGas":"0x59682f00","hash":"0xe23a5b35faae5335adc5aca38c5d633b00438b798c2053104b8df48406c9b141","input":"0x3ff9751b0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000002e516d566e75374a51566f445271536748427a72615970374879373848774a744c4669366e5546436f775447647a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d5439716b3343525962464457704446596541763854384831676e6f6e67774b6868354a36384e4c6b4c6972360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041c9f31b989aaa745aecc563139f89c8ab3ab492e725d1e0305b7d602fcbf9293c463f0d2e4f5fb0c9efb54eb2cde9af10ebc9c3676f2334007291ffa8efb40adb1c00000000000000000000000000000000000000000000000000000000000000","nonce":"0x16","to":"0xc3b87ea584cb9cb5a4523e2bed16a34bf7746317","transactionIndex":"0x9","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcc693a9544394653e1f393f02635e2c1f78b5e6c26c4d00a867bcf4adc2bc09e","s":"0x23f4b71b773c19f77cf251b2aeea03f2696bddd847d1f6d75acd2fbea6a543e4","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0x1b2e020","gasPrice":"0x8f0d3617","maxFeePerGas":"0x1cb3abd5a","maxPriorityFeePerGas":"0x4f5572c0","hash":"0xd8cea4ba619b317bc05d58534af73beec6c2548b31b24d4dc61c9bbd29cfa17a","input":"0x","nonce":"0x4d","to":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8dae28608985d6ab47cbe122ee88972e38664cede30978f41944f347bad86e5c","s":"0x17c2898b39b7e3b874dc78e7df3fcff68f4d715385c632aad4bdf6e62505651c","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6999c36394dd5d3d3295af63a4736ad6bd279448","gas":"0x14d94","gasPrice":"0x7b528d57","maxFeePerGas":"0x7df743e0","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x79a4b9d90b02c768baaad305f266281213cc75062cbe99a13222cc0c4b509498","input":"0x6a7612020000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000a4ec6cb13f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003826d8d7371becafc0afedc3fe85b699b87f4357d55ec39ce83c510ed7d70ff514dce8236351f4627ccec6a7d9a67bc6fc2ec17ca76411113c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000006999c36394dd5d3d3295af63a4736ad6bd27944800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000","nonce":"0x13","to":"0xdce8236351f4627ccec6a7d9a67bc6fc2ec17ca7","transactionIndex":"0xb","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x669487011643510f7512ec15b07d74efb853ba4ad9fe9c7e9850ccf24e3d4c53","s":"0x2191f9ee81087e1df833e69d6129ec330ed4c99be2031060834e22c589fcf79b","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xf6e4d9c4","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x6790a3bbddbeb21fcb736a59b3775755051c3a6344d8390cf8ca27f2e8a814f0","input":"0x6871ee40","nonce":"0x4","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xc","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa7a58ab858e5dd87b9a74d550e5716ac40ddefd1c21d5baa51e542f4f941d73e","s":"0x1fd0cb1563df0368bd332717d7c8210187cd1ac2ff44f61f5242fc02eaa0c2fe","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x87ec7ace5442db252b5751ffddd38dcb04b088d36b6b0e526ff25607a4293c81","input":"0xcb40cbfd","nonce":"0x5","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xd","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x8e4bd40195bdfaa868af97dbf22e0b74295d95564a8381bc9bcfe1af3cde2cdb","s":"0x62057dc87c8b2b197d12c648233aab4134b7c2a2f65db89a49728564f3d0864d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x40cb487ecffda94f97ce7fc0f7163f2f024235df2c8291169edc80dac063e6d0","input":"0xcb40cbfd","nonce":"0x6","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xe","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x993c4386ffc2bd63a48dd31cf5f65aa355cba3c063b08778b328d748937098e5","s":"0x203b1faf595628dd78e760bcc1740065625abb6cf00b1b17224e10fa6b424e43","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xafc7682751d3654f34958e3fb660971bf5918367","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xefb40664","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xb76bb3d88c9b30d927c45ccfcf8d5b0054411ac8501ad588822a7d04690cccf6","input":"0x40c10f19000000000000000000000000afc7682751d3654f34958e3fb660971bf59183670000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x20","to":"0x84ced17d95f3ec7230baf4a369f1e624ae60090d","transactionIndex":"0xf","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x78e9d29c606f6a61a1428ed7326df05210d802c3061f3b469847cc461eb48025","s":"0x517afe5a21175f186233ae7a6c090cd33e028a77e5854e98eb2fa4c9284430e7","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0x16ba45bce","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x798ebe823209869347c08bd81e04fbf60e9bdfe44b1cc923215182d0cf3d4edb","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000032","nonce":"0x4e","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x10","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xbe2aa95f4c32188c9ecbae97286ab983f7cc5a7017d46c404f8eb80b55e2dc13","s":"0x55d8968f509f51633f49260178941fd5a3db999e1995206348d7a3f05152b3d5","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0xc6132c0c","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xbe68a7e02725f799a65ebb069ccc83a014ac7c40e4119bf7c220a2f6ddfee295","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000064","nonce":"0x4f","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x11","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1750ed45d0d2d048a61dcc3ff3e7ad0cbd395b77698c4f2eeb6baaea4c966d96","s":"0xe646e3a87b6dc50439468bcfd24cbf12a6f95b2762f1527c97a7d1b7f03530e","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd0c0338baac9ce09c1d1caab88b4360507061e37","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1918167aa","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xc90c3a72efe81331727fcce4b5bd4906066da314ca9a0b44023a6b09ea7e8114","input":"0x4e71d92d","nonce":"0xe7","to":"0x0137d796936e199b917b93118eb4e002508a48bd","transactionIndex":"0x12","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x22222ce8fe753082c8e5dc7478fa7b87db9c8d0fb070ebc88ab015db13fd6bb","s":"0x6dceadecf6f6a3ddc433a547dba6d5fcdfb7d006ce09eeae1c06c1828ef9fff9","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1a4019792","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x619a6cbd43cde074d314c19623bd66d9fb1e13c158d7138775236f798dc1245e","input":"0x1da1db5e00000000000000000000000000000000000000000000000000001b5ec4ff740d","nonce":"0x10","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x733c496e8c84f78d113bc8b5ad6d04a133bb10bbcecf0db93d97eeedfa3d984a","s":"0x6627c16aa7dea27db44c0f0641c30ffd544b9b9b1c299dc60611e1e01c714ee8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x11df0","gasPrice":"0x7b528d57","maxFeePerGas":"0x1d3fbccb8","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xca5a56cd77b9e5b0e79020cc6346edf205bc11e901984d805125f28c2e6686e6","input":"0xd7c01032000000000000000000000000356f24c0f3187a6dcb949e4a60aa0a74a8a0327e0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd","nonce":"0x11","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x4aa872c1a7da70126917604193717575b91407f82449bca956d4089b90cd902","s":"0x4b5f788c68024f8958f66e8c768a8e0f65ef297c4ffd420a715258b0a55cb0a0","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1e706c8d2","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x999c9ddeed67c6ef6fbf02a6e977a6c1b68e18d24814e51643c7157b87a43e0a","input":"0xa8b78ed0","nonce":"0x3","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf1ca074104ee0b6a67223afd797654b8f21060453f7662dd7be79de938c396da","s":"0x4c9a4e56f0ad21e2dd8d1116c7a3e41ea2c6126853772f7897bd959e81e2e28a","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x2dc6c0","gasPrice":"0xd4babc57","maxFeePerGas":"0x21c13e710","maxPriorityFeePerGas":"0x9502f900","hash":"0x47c8f5d0b3778e4c34eba7fcc356fa04a5afd954ccf484728e72c002764dd3c4","input":"0xf688bcfb0000000000000000000000000000000000000000000000000000000005f5e100","nonce":"0x4","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x970982425d18b9949141bbabb5c5230fa168626ce210a97f3856d64700fc0eeb","s":"0x6fa6d0aea6ae48783d80c1e51cda47e11c28b90a5497579b93d7f242d786f67e","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4b596cebd02c35aa99878eb9ecb24d6f5ca5f865","gas":"0x5208","gasPrice":"0x68c88f79","maxFeePerGas":"0x68c88f79","maxPriorityFeePerGas":"0x68c88f79","hash":"0x396797ae0ebcdb72ff1f96fd08b6128f78acc7417353f142f1a5facd425a33e6","input":"0x","nonce":"0x1","to":"0x375980b8e1a417620ba9b18e5a9e0b17dccbac9d","transactionIndex":"0x17","value":"0x1c9a406c58878","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcb2a7b106097b2f2a61d3a048054a5175c386b1dcdd5b6fcd7849dcac7c32a66","s":"0x10aef76e98276c47470f04a599b81c260ace9d2f6adc95755c6d22d859e805a2","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0x1b2e020","gasPrice":"0x61010bda","maxFeePerGas":"0x61010bda","maxPriorityFeePerGas":"0x61010bda","hash":"0x454aa43d6546a6f62246826c16b7a49c6c704238c18802ef0d659922f23a573c","input":"0xe99a3f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee40000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e06defd69964a6ce467b87c64627a7a2be4be139b504757c625eb6114ec166557d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001f63c28250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf17500000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d5458000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000413e24433da3efc4c3cc305339a7b77a1b31abb4e4d4967e97e42aed1dd0bf98936f43035f40bc80f6f6e3a9cfb43524a1171ee7f21e9ac2fa586d33a31f10619d1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace5786000000000000000000000000000000000000000000000000000000000000012000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf1750000000000000000000000000000000000000000000000000000000000000ba200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175ffffffff09616c6c64617461","nonce":"0x82","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xc7ac308b1ae238cb2aa4b030ca79baffb7b498e1b10df0c3354b3cc19cfabac9","s":"0x2358b1093b9aab5fae0cf751766b0bb2e3d8cd2b18ca627e1e12520990a8ed6d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6ece61d29b90642941c41240da924690da145696","gas":"0x4399c","gasPrice":"0x506794e0","hash":"0x317ecb5bd19caa42a69f836d41556ebb0e0e00e1c6cd2dee230e6e6192612527","input":"0x46f83b5000000000000000000000000000000000000000000000000000000000000000654666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b000000000000000000000000000000000000000000000000000000000000000f4666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b","nonce":"0x2cc4","to":"0xa6bf2be6c60175601bf88217c75dd4b14abb5fbb","transactionIndex":"0x19","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x37aeab0db6d550e6cba2c04c9cb10a2af0fec0b11f6e04b85e1ea0b8b9defeae","s":"0x4f32f4ef74872e1385c25e69bf21ee049545a4d423e939eaff29677450efe9eb"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xc4a5c059840a146b81c77bf79f1398f2b3d28ca7","gas":"0x432ec","gasPrice":"0x45db0a51","hash":"0xc879285db5ef0a6bce98021584d16f134c1dc0aed8cc988802c4f72ba6877ff6","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1a7","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1a","value":"0x470efc4514e000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x237e3a541c5ab490843cdc20d0fcb7416bff8da471f6a11ae1b32d2bab119141","s":"0x3c8417d7a60bd5b0bcae4975dbb4aaee54a4b4d588226481be400843bfe2b64e"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0xffff","gasPrice":"0x44e9acbc","maxFeePerGas":"0x44e9acbc","maxPriorityFeePerGas":"0x44e9acbc","hash":"0xecaa2d6f597608307e5084854854ba6dc1e69395e2abea14f2c6a2fa1d6faf9a","input":"0xe2864fe300000000000000000000000000000000000000000000000000000000000000200000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace57860000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002004a8312e37fcecd450e6684009a2b54bc64f66afbe5217c7b2f63b03cd9980a9e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064893e8223d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a7640000aaaebeba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d54580000000000000000000000000000000000000000000000000000000000000000","nonce":"0x83","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x1b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa18772e4b9e1493ebfd5ae6219cc9ca060b71e83788fb614ab02b03fb36eaf1b","s":"0x482c7e50fde29bb4130fd6e723176e0e9913430ebb9260667d7fb55f5408d9c5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xdb33365a8730de2f7574ff1189fb9d337bf4c36d","gas":"0x61a80","gasPrice":"0x433653c8","maxFeePerGas":"0x828367af","maxPriorityFeePerGas":"0x37e9071","hash":"0x4dd69b69a568ff30ae439e2ded72fbd7f2e7aaa345836703663f155c749c5eed","input":"0x7f34c0ddc6e984f46ab7c13b7a53643096e79c39103dc74550204d5bd1b5206ef5a2f49689071bb6a332212df26aa57cd4d1e3c0894187a9fc5e5d686cbedba5b187470f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000e8c44c30e8e52c38ac7bd232e7b7f0c7463a535100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002e516d5044645856613738437a6b7856325a364e52777a67685a785872736e75397261616a695a7555423569465a62000000000000000000000000000000000000","nonce":"0x2b57","to":"0xb8ad54644e2371cbb7940b9fa0936f399ba7495f","transactionIndex":"0x1c","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa1fb0e5662b54ceb3dc1623ebfb200668433cb27252d553669bcd136387394f3","s":"0x27c2f8e19f69a52a0960f05d8b21f11c313dd3e86a7139b5783a18353c407415","yParity":"0x0"}],"transactionsRoot":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","uncles":[],"withdrawals":[{"index":"0x1170","validatorIndex":"0x38c2c","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x66edfd65"},{"index":"0x1171","validatorIndex":"0x38c2d","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6cd228e4"},{"index":"0x1172","validatorIndex":"0x38c2e","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x77f3431b"},{"index":"0x1173","validatorIndex":"0x38c2f","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6b61f268"},{"index":"0x1174","validatorIndex":"0x38c30","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6e10bb21"},{"index":"0x1175","validatorIndex":"0x38c31","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6eb115a5"},{"index":"0x1176","validatorIndex":"0x38c32","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7caead1d"},{"index":"0x1177","validatorIndex":"0x38c33","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x772c0ddf"},{"index":"0x1178","validatorIndex":"0x38c34","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x75930a95"},{"index":"0x1179","validatorIndex":"0x38c35","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76a4db09"},{"index":"0x117a","validatorIndex":"0x38c36","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7e692b27"},{"index":"0x117b","validatorIndex":"0x38c37","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x72038ae6"},{"index":"0x117c","validatorIndex":"0x38c38","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6ccce352"},{"index":"0x117d","validatorIndex":"0x38c39","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x79ef6898"},{"index":"0x117e","validatorIndex":"0x38c3a","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6d58977d"},{"index":"0x117f","validatorIndex":"0x38c3b","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76f7d208"}],"withdrawalsRoot":"0xbe712c930a0665264b025ced87cc7839eef95a3cbc26dadc93e9e185a350ad28"} +{"baseFeePerGas":"0x3fb7c357","difficulty":"0x0","extraData":"0x","gasLimit":"0x1c9c380","gasUsed":"0x18f759","hash":"0x0afe3cbfbf24c0b097b50864b8aaf9f819cf56d4b2b6a67b1edff20bc2a66ad2","logsBloom":"0x020010404000001a0000021000000080001100410000100001000010040200980220400000008806200200000100000000000000000000008000000400042000000050000040000112080808800002044000040004042008800480002000000000000002020020000042002400000820000080040000000010200010020010100101212050000008000000008000001010200c80000112010000438040020400000000202400000000002002a0210402000622010000000001700144000040000000002204000000c000410105024010000808000000002004002000000261000000822200200800881000000012500400400000000000000040010000800000","miner":"0x000095e79eac4d76aab57cb2c1f091d553b36ca0","mixHash":"0x5b53dc49cbab268ef9950b1d81b5e36a1b2f1b97aee1b7ff6e4db0e06c29a8b0","nonce":"0x0000000000000000","number":"0x84161e","parentHash":"0x72d92c1498e05952988d4e79a695928a6bcbd37239f8a1734051263b4d3504b8","receiptsRoot":"0xaff90ae18dcc35924a4bddb68d403b8b7812c10c3ea2a114f34105c87d75bcdb","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2a51","stateRoot":"0xc56738518b2c7854a640ae25996d2211c9ef0dd2e4dd9e59e9d9cacef39622da","timestamp":"0x64110a5c","totalDifficulty":"0xa4a470","transactions":[{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x1b7aa44088a0ea95bdc65fef6e5071e946bf7d8f","gas":"0x5208","gasPrice":"0x4159f01735","hash":"0x1e8f148a9aea7d8d16ea6e9446723b8f262e8bcd89c7c961d52046ebd43b4598","input":"0x","nonce":"0x279ad","to":"0xa21765a03dd41e2783696d314f235f4d520f6cac","transactionIndex":"0x0","value":"0x3782dace9d90000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xf9eca8b74ccaec5f4a83e981baeb8602f38d0271179c592b4a18f3866316a367","s":"0x350a9d26718d1fa9dc4f268f9c0e18fb96dbc037816ca8fc20f33f1a76f9f501"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4d9a852e6aecd3a6e87fece2ca109780e45e6f2d","gas":"0x160ab","gasPrice":"0xd4babc57","maxFeePerGas":"0x11407d03e","maxPriorityFeePerGas":"0x9502f900","hash":"0xab5c870f4c367012bd763172afbfbe68fbf35336a66ae41aff3f2c9dbf4ea3f8","input":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200c479c99d58d7fbee5ee3aef5001431073a3d465bdfa46cf747a7c0b9289607864736f6c634300080d0033","nonce":"0xafd","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x48f6acf4ac4371eb96ffca8cdef5b7704ea8c68a631d1c02927036d4ce92567e","s":"0x1f12261ddde63fd3da2ed9ea1bcbb4b0f25af898248c805a9d4b0a6e42caf9c8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xce297b30e56bf2f6142c4048fbae1cb8a756fefd","gas":"0x557300","gasPrice":"0xd4babc57","maxFeePerGas":"0xfabdd183","maxPriorityFeePerGas":"0x9502f900","hash":"0xa81fd92b2d0f0bbd3cc355f869cca3243c98c5e2641db9ecf3eeabb3b13bff6a","input":"0x7bbaf1ea0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000","nonce":"0xad92","to":"0x4c0ce02c1219ce5d2afffba97e484272a4637b49","transactionIndex":"0x2","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xd11b842a5f7b0e020470e764b443fafc4044327bca8dbb37131425359abace2","s":"0x1009867573946fb0a4a35339a6eaaece4d0a168b2346539076e6319e9a466b1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x47a916d0b694c95bc0c09953c1a6e22c8867be32","gas":"0x5208","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xa92c7b720c08c83f1a0ed7e4c163200e30a3a8c03fcc5a51e685ea20cd0cb577","input":"0x","nonce":"0x2","to":"0xf955dfe99bbfd06a8be208274cd654ecfb66a45e","transactionIndex":"0x3","value":"0x11c37937e08000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeecd431225215c3ddc2e13cf16fa29f9a2ab1afbaa02988f3ceac27416edf0f5","s":"0x6494062330a9d509f7c778cb45cbcc9932e5f9b4ec94a1ec315f579f8d973b7b","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x672d214fe4db218defae698085a3ccefc773dfa9","gas":"0xf4f6","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0x6921b429ad2ec1e97d3457049ad2e893b5a0349beba47ca1c74a9540af75347a","input":"0xa1ddc546000000000000000000000000000000000000000000000000000000000000118f","nonce":"0x8e","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x4","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4732ad21401b509bebb947a8566127fba1e245eb5a262ddc522d6867ab80567e","s":"0x2153013617fefdb06db0a7316d8883056441d33c2abf5ed6291fa0e3cc5c3a2f","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x0b12f7f996579fe7d9302d2574910121c214ee15","gas":"0x56a8","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xf776b2da0b835dde05d0d8b76fd19385d61e7055036cf637f804b36dc94f2384","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f40000000000000000000000000b12f7f996579fe7d9302d2574910121c214ee150000000000000000000000000000000000000000000000000000000000000000","nonce":"0xe","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x5","value":"0x2386f26fc10000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc4505d4c46ef9a0103178e5ef4fbc857114ae5c4686b68b74d07c3ee3a86e575","s":"0x74db34fd675bea7d2ee74f14fd8709cb88c7d22c2267d12f2c671b5ebc180bd5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd36aac0c9676e984d72823fb662ce94d3ab5e551","gas":"0xff212","gasPrice":"0x991ff257","maxFeePerGas":"0xd86d063e","maxPriorityFeePerGas":"0x59682f00","hash":"0x9a08d899cd14ebb930ed59fa774afdb88a22615b3a931e930931ea54d26dc0bc","input":"0x49160658babdf216946a22b96c966ceeba750f14807726306ebeed500a2621a7481df010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000084d6f6f6e6265616d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078434133633746363939643335333137316438434643364236334431433764333841333233373238300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b616f73c8d00641109f0000054f967b8a135e44e233da070ea88c5e4a53bacac0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c6a3a17399d88e5dfd2de4fa41dcccade6a2d2170000000000000000000000008676147503f761e44b85df01811edd52be01b56c000000000000000000000000000000000000000000000000d02ab486cedc00000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x7121","to":"0x2d276bd64fe8643a1d76b2e9530c753423e972c1","transactionIndex":"0x6","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xce452361d331baf2ac86947a1b3b454b3e842923e1f39139b33a572845dd5d7c","s":"0x388126881782af5a146ce8409f1e3a2c9a4cadcfe9a2c1d27258af6e4eb5cec1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x326ff","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0x0fe0d97e25d5eb11a33a3e8278584c3780941fc2675bdf8fc547cee3d1fd3b17","input":"0xa4110dbe190e65a7fe0ad5acd305c6446a02cb39de30f382000fe67927434063bf4c4b2ca86b3ee6d039dc7a0268f9e1c39266c3f12a752a7eb72f0895dedf62291fd292","nonce":"0x12e","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x46819bb540fa459a5a0cbf041a0286507d597fc8958a6af8b9ce193f00005238","s":"0x31495c58bf4b74925f870c59635912681bee947b1cb4b08cc19f22421b1a10ab","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x3270b","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0xef47a60f57f177a683c723c658137efab66d311e1c5abbc4d74f653535144d03","input":"0xa4110dbe18eba3e815ec7fcb03a8eea0487209c3253024d1dc4f36f775a43fdd3e409b74c0a5c88e54f39b88db6f185a41431b204120d3e66c9b08b86f5e8382623327e5","nonce":"0x12f","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x8","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4d7e11fe3914763a2735493a62b71ae0028e75a750a8b06407996cf478e273c8","s":"0x60c18fdf948721f96fdc2efbf694910122e82191c7a40a5caab247c06ab7f3cf","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x7712a1f96b3f37c3dd88a22d4f7a7977b937fe62","gas":"0x1ff06","gasPrice":"0x991ff257","maxFeePerGas":"0xcf662006","maxPriorityFeePerGas":"0x59682f00","hash":"0xe23a5b35faae5335adc5aca38c5d633b00438b798c2053104b8df48406c9b141","input":"0x3ff9751b0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000002e516d566e75374a51566f445271536748427a72615970374879373848774a744c4669366e5546436f775447647a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d5439716b3343525962464457704446596541763854384831676e6f6e67774b6868354a36384e4c6b4c6972360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041c9f31b989aaa745aecc563139f89c8ab3ab492e725d1e0305b7d602fcbf9293c463f0d2e4f5fb0c9efb54eb2cde9af10ebc9c3676f2334007291ffa8efb40adb1c00000000000000000000000000000000000000000000000000000000000000","nonce":"0x16","to":"0xc3b87ea584cb9cb5a4523e2bed16a34bf7746317","transactionIndex":"0x9","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcc693a9544394653e1f393f02635e2c1f78b5e6c26c4d00a867bcf4adc2bc09e","s":"0x23f4b71b773c19f77cf251b2aeea03f2696bddd847d1f6d75acd2fbea6a543e4","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0x1b2e020","gasPrice":"0x8f0d3617","maxFeePerGas":"0x1cb3abd5a","maxPriorityFeePerGas":"0x4f5572c0","hash":"0xd8cea4ba619b317bc05d58534af73beec6c2548b31b24d4dc61c9bbd29cfa17a","input":"0x","nonce":"0x4d","to":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8dae28608985d6ab47cbe122ee88972e38664cede30978f41944f347bad86e5c","s":"0x17c2898b39b7e3b874dc78e7df3fcff68f4d715385c632aad4bdf6e62505651c","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6999c36394dd5d3d3295af63a4736ad6bd279448","gas":"0x14d94","gasPrice":"0x7b528d57","maxFeePerGas":"0x7df743e0","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x79a4b9d90b02c768baaad305f266281213cc75062cbe99a13222cc0c4b509498","input":"0x6a7612020000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000a4ec6cb13f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003826d8d7371becafc0afedc3fe85b699b87f4357d55ec39ce83c510ed7d70ff514dce8236351f4627ccec6a7d9a67bc6fc2ec17ca76411113c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000006999c36394dd5d3d3295af63a4736ad6bd27944800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000","nonce":"0x13","to":"0xdce8236351f4627ccec6a7d9a67bc6fc2ec17ca7","transactionIndex":"0xb","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x669487011643510f7512ec15b07d74efb853ba4ad9fe9c7e9850ccf24e3d4c53","s":"0x2191f9ee81087e1df833e69d6129ec330ed4c99be2031060834e22c589fcf79b","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xf6e4d9c4","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x6790a3bbddbeb21fcb736a59b3775755051c3a6344d8390cf8ca27f2e8a814f0","input":"0x6871ee40","nonce":"0x4","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xc","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa7a58ab858e5dd87b9a74d550e5716ac40ddefd1c21d5baa51e542f4f941d73e","s":"0x1fd0cb1563df0368bd332717d7c8210187cd1ac2ff44f61f5242fc02eaa0c2fe","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x87ec7ace5442db252b5751ffddd38dcb04b088d36b6b0e526ff25607a4293c81","input":"0xcb40cbfd","nonce":"0x5","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xd","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x8e4bd40195bdfaa868af97dbf22e0b74295d95564a8381bc9bcfe1af3cde2cdb","s":"0x62057dc87c8b2b197d12c648233aab4134b7c2a2f65db89a49728564f3d0864d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x40cb487ecffda94f97ce7fc0f7163f2f024235df2c8291169edc80dac063e6d0","input":"0xcb40cbfd","nonce":"0x6","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xe","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x993c4386ffc2bd63a48dd31cf5f65aa355cba3c063b08778b328d748937098e5","s":"0x203b1faf595628dd78e760bcc1740065625abb6cf00b1b17224e10fa6b424e43","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xafc7682751d3654f34958e3fb660971bf5918367","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xefb40664","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xb76bb3d88c9b30d927c45ccfcf8d5b0054411ac8501ad588822a7d04690cccf6","input":"0x40c10f19000000000000000000000000afc7682751d3654f34958e3fb660971bf59183670000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x20","to":"0x84ced17d95f3ec7230baf4a369f1e624ae60090d","transactionIndex":"0xf","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x78e9d29c606f6a61a1428ed7326df05210d802c3061f3b469847cc461eb48025","s":"0x517afe5a21175f186233ae7a6c090cd33e028a77e5854e98eb2fa4c9284430e7","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0x16ba45bce","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x798ebe823209869347c08bd81e04fbf60e9bdfe44b1cc923215182d0cf3d4edb","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000032","nonce":"0x4e","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x10","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xbe2aa95f4c32188c9ecbae97286ab983f7cc5a7017d46c404f8eb80b55e2dc13","s":"0x55d8968f509f51633f49260178941fd5a3db999e1995206348d7a3f05152b3d5","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0xc6132c0c","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xbe68a7e02725f799a65ebb069ccc83a014ac7c40e4119bf7c220a2f6ddfee295","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000064","nonce":"0x4f","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x11","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1750ed45d0d2d048a61dcc3ff3e7ad0cbd395b77698c4f2eeb6baaea4c966d96","s":"0xe646e3a87b6dc50439468bcfd24cbf12a6f95b2762f1527c97a7d1b7f03530e","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd0c0338baac9ce09c1d1caab88b4360507061e37","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1918167aa","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xc90c3a72efe81331727fcce4b5bd4906066da314ca9a0b44023a6b09ea7e8114","input":"0x4e71d92d","nonce":"0xe7","to":"0x0137d796936e199b917b93118eb4e002508a48bd","transactionIndex":"0x12","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x22222ce8fe753082c8e5dc7478fa7b87db9c8d0fb070ebc88ab015db13fd6bb","s":"0x6dceadecf6f6a3ddc433a547dba6d5fcdfb7d006ce09eeae1c06c1828ef9fff9","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1a4019792","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x619a6cbd43cde074d314c19623bd66d9fb1e13c158d7138775236f798dc1245e","input":"0x1da1db5e00000000000000000000000000000000000000000000000000001b5ec4ff740d","nonce":"0x10","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x733c496e8c84f78d113bc8b5ad6d04a133bb10bbcecf0db93d97eeedfa3d984a","s":"0x6627c16aa7dea27db44c0f0641c30ffd544b9b9b1c299dc60611e1e01c714ee8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x11df0","gasPrice":"0x7b528d57","maxFeePerGas":"0x1d3fbccb8","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xca5a56cd77b9e5b0e79020cc6346edf205bc11e901984d805125f28c2e6686e6","input":"0xd7c01032000000000000000000000000356f24c0f3187a6dcb949e4a60aa0a74a8a0327e0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd","nonce":"0x11","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x4aa872c1a7da70126917604193717575b91407f82449bca956d4089b90cd902","s":"0x4b5f788c68024f8958f66e8c768a8e0f65ef297c4ffd420a715258b0a55cb0a0","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1e706c8d2","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x999c9ddeed67c6ef6fbf02a6e977a6c1b68e18d24814e51643c7157b87a43e0a","input":"0xa8b78ed0","nonce":"0x3","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf1ca074104ee0b6a67223afd797654b8f21060453f7662dd7be79de938c396da","s":"0x4c9a4e56f0ad21e2dd8d1116c7a3e41ea2c6126853772f7897bd959e81e2e28a","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x2dc6c0","gasPrice":"0xd4babc57","maxFeePerGas":"0x21c13e710","maxPriorityFeePerGas":"0x9502f900","hash":"0x47c8f5d0b3778e4c34eba7fcc356fa04a5afd954ccf484728e72c002764dd3c4","input":"0xf688bcfb0000000000000000000000000000000000000000000000000000000005f5e100","nonce":"0x4","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x970982425d18b9949141bbabb5c5230fa168626ce210a97f3856d64700fc0eeb","s":"0x6fa6d0aea6ae48783d80c1e51cda47e11c28b90a5497579b93d7f242d786f67e","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4b596cebd02c35aa99878eb9ecb24d6f5ca5f865","gas":"0x5208","gasPrice":"0x68c88f79","maxFeePerGas":"0x68c88f79","maxPriorityFeePerGas":"0x68c88f79","hash":"0x396797ae0ebcdb72ff1f96fd08b6128f78acc7417353f142f1a5facd425a33e6","input":"0x","nonce":"0x1","to":"0x375980b8e1a417620ba9b18e5a9e0b17dccbac9d","transactionIndex":"0x17","value":"0x1c9a406c58878","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcb2a7b106097b2f2a61d3a048054a5175c386b1dcdd5b6fcd7849dcac7c32a66","s":"0x10aef76e98276c47470f04a599b81c260ace9d2f6adc95755c6d22d859e805a2","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0x1b2e020","gasPrice":"0x61010bda","maxFeePerGas":"0x61010bda","maxPriorityFeePerGas":"0x61010bda","hash":"0x454aa43d6546a6f62246826c16b7a49c6c704238c18802ef0d659922f23a573c","input":"0xe99a3f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee40000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e06defd69964a6ce467b87c64627a7a2be4be139b504757c625eb6114ec166557d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001f63c28250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf17500000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d5458000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000413e24433da3efc4c3cc305339a7b77a1b31abb4e4d4967e97e42aed1dd0bf98936f43035f40bc80f6f6e3a9cfb43524a1171ee7f21e9ac2fa586d33a31f10619d1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace5786000000000000000000000000000000000000000000000000000000000000012000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf1750000000000000000000000000000000000000000000000000000000000000ba200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175ffffffff09616c6c64617461","nonce":"0x82","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xc7ac308b1ae238cb2aa4b030ca79baffb7b498e1b10df0c3354b3cc19cfabac9","s":"0x2358b1093b9aab5fae0cf751766b0bb2e3d8cd2b18ca627e1e12520990a8ed6d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6ece61d29b90642941c41240da924690da145696","gas":"0x4399c","gasPrice":"0x506794e0","hash":"0x317ecb5bd19caa42a69f836d41556ebb0e0e00e1c6cd2dee230e6e6192612527","input":"0x46f83b5000000000000000000000000000000000000000000000000000000000000000654666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b000000000000000000000000000000000000000000000000000000000000000f4666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b","nonce":"0x2cc4","to":"0xa6bf2be6c60175601bf88217c75dd4b14abb5fbb","transactionIndex":"0x19","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x37aeab0db6d550e6cba2c04c9cb10a2af0fec0b11f6e04b85e1ea0b8b9defeae","s":"0x4f32f4ef74872e1385c25e69bf21ee049545a4d423e939eaff29677450efe9eb"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xc4a5c059840a146b81c77bf79f1398f2b3d28ca7","gas":"0x432ec","gasPrice":"0x45db0a51","hash":"0xc879285db5ef0a6bce98021584d16f134c1dc0aed8cc988802c4f72ba6877ff6","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1a7","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1a","value":"0x470efc4514e000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x237e3a541c5ab490843cdc20d0fcb7416bff8da471f6a11ae1b32d2bab119141","s":"0x3c8417d7a60bd5b0bcae4975dbb4aaee54a4b4d588226481be400843bfe2b64e"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0xffff","gasPrice":"0x44e9acbc","maxFeePerGas":"0x44e9acbc","maxPriorityFeePerGas":"0x44e9acbc","hash":"0xecaa2d6f597608307e5084854854ba6dc1e69395e2abea14f2c6a2fa1d6faf9a","input":"0xe2864fe300000000000000000000000000000000000000000000000000000000000000200000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace57860000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002004a8312e37fcecd450e6684009a2b54bc64f66afbe5217c7b2f63b03cd9980a9e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064893e8223d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a7640000aaaebeba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d54580000000000000000000000000000000000000000000000000000000000000000","nonce":"0x83","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x1b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa18772e4b9e1493ebfd5ae6219cc9ca060b71e83788fb614ab02b03fb36eaf1b","s":"0x482c7e50fde29bb4130fd6e723176e0e9913430ebb9260667d7fb55f5408d9c5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xdb33365a8730de2f7574ff1189fb9d337bf4c36d","gas":"0x61a80","gasPrice":"0x433653c8","maxFeePerGas":"0x828367af","maxPriorityFeePerGas":"0x37e9071","hash":"0x4dd69b69a568ff30ae439e2ded72fbd7f2e7aaa345836703663f155c749c5eed","input":"0x7f34c0ddc6e984f46ab7c13b7a53643096e79c39103dc74550204d5bd1b5206ef5a2f49689071bb6a332212df26aa57cd4d1e3c0894187a9fc5e5d686cbedba5b187470f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000e8c44c30e8e52c38ac7bd232e7b7f0c7463a535100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002e516d5044645856613738437a6b7856325a364e52777a67685a785872736e75397261616a695a7555423569465a62000000000000000000000000000000000000","nonce":"0x2b57","to":"0xb8ad54644e2371cbb7940b9fa0936f399ba7495f","transactionIndex":"0x1c","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa1fb0e5662b54ceb3dc1623ebfb200668433cb27252d553669bcd136387394f3","s":"0x27c2f8e19f69a52a0960f05d8b21f11c313dd3e86a7139b5783a18353c407415","yParity":"0x0"}],"transactionsRoot":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","uncles":[],"withdrawals":[{"index":"0x1170","validatorIndex":"0x38c2c","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x66edfd65"},{"index":"0x1171","validatorIndex":"0x38c2d","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6cd228e4"},{"index":"0x1172","validatorIndex":"0x38c2e","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x77f3431b"},{"index":"0x1173","validatorIndex":"0x38c2f","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6b61f268"},{"index":"0x1174","validatorIndex":"0x38c30","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6e10bb21"},{"index":"0x1175","validatorIndex":"0x38c31","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6eb115a5"},{"index":"0x1176","validatorIndex":"0x38c32","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7caead1d"},{"index":"0x1177","validatorIndex":"0x38c33","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x772c0ddf"},{"index":"0x1178","validatorIndex":"0x38c34","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x75930a95"},{"index":"0x1179","validatorIndex":"0x38c35","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76a4db09"},{"index":"0x117a","validatorIndex":"0x38c36","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7e692b27"},{"index":"0x117b","validatorIndex":"0x38c37","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x72038ae6"},{"index":"0x117c","validatorIndex":"0x38c38","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6ccce352"},{"index":"0x117d","validatorIndex":"0x38c39","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x79ef6898"},{"index":"0x117e","validatorIndex":"0x38c3a","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6d58977d"},{"index":"0x117f","validatorIndex":"0x38c3b","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76f7d208"}],"withdrawalsRoot":"0xbe712c930a0665264b025ced87cc7839eef95a3cbc26dadc93e9e185a350ad28"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions_metadata.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions_metadata.json index 03c892fc1ea3..0a9f8871b554 100644 --- a/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions_metadata.json +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-transactions_metadata.json @@ -1 +1 @@ -{"name":"post-shanghai-bad-transactions","fail":true} +{"name":"post-shanghai-bad-transactions","fail":true, "reason": "failed to verify transactions list"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-hash_data.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-hash_data.json new file mode 100644 index 000000000000..07d959023dbc --- /dev/null +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-hash_data.json @@ -0,0 +1 @@ +{"baseFeePerGas":"0x3fb7c357","difficulty":"0x0","extraData":"0x","gasLimit":"0x1c9c380","gasUsed":"0x18f759","hash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","logsBloom":"0x020010404000001a0000021000000080001100410000100001000010040200980220400000008806200200000100000000000000000000008000000400042000000050000040000112080808800002044000040004042008800480002000000000000002020020000042002400000820000080040000000010200010020010100101212050000008000000008000001010200c80000112010000438040020400000000202400000000002002a0210402000622010000000001700144000040000000002204000000c000410105024010000808000000002004002000000261000000822200200800881000000012500400400000000000000040010000800000","miner":"0x000095e79eac4d76aab57cb2c1f091d553b36ca0","mixHash":"0x5b53dc49cbab268ef9950b1d81b5e36a1b2f1b97aee1b7ff6e4db0e06c29a8b0","nonce":"0x0000000000000000","number":"0x84161e","parentHash":"0x72d92c1498e05952988d4e79a695928a6bcbd37239f8a1734051263b4d3504b8","receiptsRoot":"0xaff90ae18dcc35924a4bddb68d403b8b7812c10c3ea2a114f34105c87d75bcdb","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2a51","stateRoot":"0xc56738518b2c7854a640ae25996d2211c9ef0dd2e4dd9e59e9d9cacef39622da","timestamp":"0x64110a5c","totalDifficulty":"0xa4a470","transactions":[{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x1b7aa44088a0ea95bdc65fef6e5071e946bf7d8f","gas":"0x5208","gasPrice":"0x4159f01735","hash":"0x1e8f148a9aea7d8d16ea6e9446723b8f262e8bcd89c7c961d52046ebd43b4598","input":"0x","nonce":"0x279ad","to":"0xa21765a03dd41e2783696d314f235f4d520f6cac","transactionIndex":"0x0","value":"0x3782dace9d90000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xf9eca8b74ccaec5f4a83e981baeb8602f38d0271179c592b4a18f3866316a367","s":"0x350a9d26718d1fa9dc4f268f9c0e18fb96dbc037816ca8fc20f33f1a76f9f501"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4d9a852e6aecd3a6e87fece2ca109780e45e6f2d","gas":"0x160ab","gasPrice":"0xd4babc57","maxFeePerGas":"0x11407d03e","maxPriorityFeePerGas":"0x9502f900","hash":"0xab5c870f4c367012bd763172afbfbe68fbf35336a66ae41aff3f2c9dbf4ea3f8","input":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200c479c99d58d7fbee5ee3aef5001431073a3d465bdfa46cf747a7c0b9289607864736f6c634300080d0033","nonce":"0xafd","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x48f6acf4ac4371eb96ffca8cdef5b7704ea8c68a631d1c02927036d4ce92567e","s":"0x1f12261ddde63fd3da2ed9ea1bcbb4b0f25af898248c805a9d4b0a6e42caf9c8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xce297b30e56bf2f6142c4048fbae1cb8a756fefd","gas":"0x557300","gasPrice":"0xd4babc57","maxFeePerGas":"0xfabdd183","maxPriorityFeePerGas":"0x9502f900","hash":"0xa81fd92b2d0f0bbd3cc355f869cca3243c98c5e2641db9ecf3eeabb3b13bff6a","input":"0x7bbaf1ea0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000","nonce":"0xad92","to":"0x4c0ce02c1219ce5d2afffba97e484272a4637b49","transactionIndex":"0x2","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xd11b842a5f7b0e020470e764b443fafc4044327bca8dbb37131425359abace2","s":"0x1009867573946fb0a4a35339a6eaaece4d0a168b2346539076e6319e9a466b1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x47a916d0b694c95bc0c09953c1a6e22c8867be32","gas":"0x5208","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xa92c7b720c08c83f1a0ed7e4c163200e30a3a8c03fcc5a51e685ea20cd0cb577","input":"0x","nonce":"0x2","to":"0xf955dfe99bbfd06a8be208274cd654ecfb66a45e","transactionIndex":"0x3","value":"0x11c37937e08000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeecd431225215c3ddc2e13cf16fa29f9a2ab1afbaa02988f3ceac27416edf0f5","s":"0x6494062330a9d509f7c778cb45cbcc9932e5f9b4ec94a1ec315f579f8d973b7b","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x672d214fe4db218defae698085a3ccefc773dfa9","gas":"0xf4f6","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0x6921b429ad2ec1e97d3457049ad2e893b5a0349beba47ca1c74a9540af75347a","input":"0xa1ddc546000000000000000000000000000000000000000000000000000000000000118f","nonce":"0x8e","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x4","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4732ad21401b509bebb947a8566127fba1e245eb5a262ddc522d6867ab80567e","s":"0x2153013617fefdb06db0a7316d8883056441d33c2abf5ed6291fa0e3cc5c3a2f","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x0b12f7f996579fe7d9302d2574910121c214ee15","gas":"0x56a8","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xf776b2da0b835dde05d0d8b76fd19385d61e7055036cf637f804b36dc94f2384","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f40000000000000000000000000b12f7f996579fe7d9302d2574910121c214ee150000000000000000000000000000000000000000000000000000000000000000","nonce":"0xe","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x5","value":"0x2386f26fc10000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc4505d4c46ef9a0103178e5ef4fbc857114ae5c4686b68b74d07c3ee3a86e575","s":"0x74db34fd675bea7d2ee74f14fd8709cb88c7d22c2267d12f2c671b5ebc180bd5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd36aac0c9676e984d72823fb662ce94d3ab5e551","gas":"0xff212","gasPrice":"0x991ff257","maxFeePerGas":"0xd86d063e","maxPriorityFeePerGas":"0x59682f00","hash":"0x9a08d899cd14ebb930ed59fa774afdb88a22615b3a931e930931ea54d26dc0bc","input":"0x49160658babdf216946a22b96c966ceeba750f14807726306ebeed500a2621a7481df010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000084d6f6f6e6265616d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078434133633746363939643335333137316438434643364236334431433764333841333233373238300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b616f73c8d00641109f0000054f967b8a135e44e233da070ea88c5e4a53bacac0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c6a3a17399d88e5dfd2de4fa41dcccade6a2d2170000000000000000000000008676147503f761e44b85df01811edd52be01b56c000000000000000000000000000000000000000000000000d02ab486cedc00000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x7121","to":"0x2d276bd64fe8643a1d76b2e9530c753423e972c1","transactionIndex":"0x6","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xce452361d331baf2ac86947a1b3b454b3e842923e1f39139b33a572845dd5d7c","s":"0x388126881782af5a146ce8409f1e3a2c9a4cadcfe9a2c1d27258af6e4eb5cec1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x326ff","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0x0fe0d97e25d5eb11a33a3e8278584c3780941fc2675bdf8fc547cee3d1fd3b17","input":"0xa4110dbe190e65a7fe0ad5acd305c6446a02cb39de30f382000fe67927434063bf4c4b2ca86b3ee6d039dc7a0268f9e1c39266c3f12a752a7eb72f0895dedf62291fd292","nonce":"0x12e","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x46819bb540fa459a5a0cbf041a0286507d597fc8958a6af8b9ce193f00005238","s":"0x31495c58bf4b74925f870c59635912681bee947b1cb4b08cc19f22421b1a10ab","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x3270b","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0xef47a60f57f177a683c723c658137efab66d311e1c5abbc4d74f653535144d03","input":"0xa4110dbe18eba3e815ec7fcb03a8eea0487209c3253024d1dc4f36f775a43fdd3e409b74c0a5c88e54f39b88db6f185a41431b204120d3e66c9b08b86f5e8382623327e5","nonce":"0x12f","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x8","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4d7e11fe3914763a2735493a62b71ae0028e75a750a8b06407996cf478e273c8","s":"0x60c18fdf948721f96fdc2efbf694910122e82191c7a40a5caab247c06ab7f3cf","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x7712a1f96b3f37c3dd88a22d4f7a7977b937fe62","gas":"0x1ff06","gasPrice":"0x991ff257","maxFeePerGas":"0xcf662006","maxPriorityFeePerGas":"0x59682f00","hash":"0xe23a5b35faae5335adc5aca38c5d633b00438b798c2053104b8df48406c9b141","input":"0x3ff9751b0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000002e516d566e75374a51566f445271536748427a72615970374879373848774a744c4669366e5546436f775447647a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d5439716b3343525962464457704446596541763854384831676e6f6e67774b6868354a36384e4c6b4c6972360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041c9f31b989aaa745aecc563139f89c8ab3ab492e725d1e0305b7d602fcbf9293c463f0d2e4f5fb0c9efb54eb2cde9af10ebc9c3676f2334007291ffa8efb40adb1c00000000000000000000000000000000000000000000000000000000000000","nonce":"0x16","to":"0xc3b87ea584cb9cb5a4523e2bed16a34bf7746317","transactionIndex":"0x9","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcc693a9544394653e1f393f02635e2c1f78b5e6c26c4d00a867bcf4adc2bc09e","s":"0x23f4b71b773c19f77cf251b2aeea03f2696bddd847d1f6d75acd2fbea6a543e4","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0x1b2e020","gasPrice":"0x8f0d3617","maxFeePerGas":"0x1cb3abd5a","maxPriorityFeePerGas":"0x4f5572c0","hash":"0xd8cea4ba619b317bc05d58534af73beec6c2548b31b24d4dc61c9bbd29cfa17a","input":"0x","nonce":"0x4d","to":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8dae28608985d6ab47cbe122ee88972e38664cede30978f41944f347bad86e5c","s":"0x17c2898b39b7e3b874dc78e7df3fcff68f4d715385c632aad4bdf6e62505651c","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6999c36394dd5d3d3295af63a4736ad6bd279448","gas":"0x14d94","gasPrice":"0x7b528d57","maxFeePerGas":"0x7df743e0","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x79a4b9d90b02c768baaad305f266281213cc75062cbe99a13222cc0c4b509498","input":"0x6a7612020000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000a4ec6cb13f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003826d8d7371becafc0afedc3fe85b699b87f4357d55ec39ce83c510ed7d70ff514dce8236351f4627ccec6a7d9a67bc6fc2ec17ca76411113c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000006999c36394dd5d3d3295af63a4736ad6bd27944800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000","nonce":"0x13","to":"0xdce8236351f4627ccec6a7d9a67bc6fc2ec17ca7","transactionIndex":"0xb","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x669487011643510f7512ec15b07d74efb853ba4ad9fe9c7e9850ccf24e3d4c53","s":"0x2191f9ee81087e1df833e69d6129ec330ed4c99be2031060834e22c589fcf79b","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xf6e4d9c4","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x6790a3bbddbeb21fcb736a59b3775755051c3a6344d8390cf8ca27f2e8a814f0","input":"0x6871ee40","nonce":"0x4","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xc","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa7a58ab858e5dd87b9a74d550e5716ac40ddefd1c21d5baa51e542f4f941d73e","s":"0x1fd0cb1563df0368bd332717d7c8210187cd1ac2ff44f61f5242fc02eaa0c2fe","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x87ec7ace5442db252b5751ffddd38dcb04b088d36b6b0e526ff25607a4293c81","input":"0xcb40cbfd","nonce":"0x5","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xd","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x8e4bd40195bdfaa868af97dbf22e0b74295d95564a8381bc9bcfe1af3cde2cdb","s":"0x62057dc87c8b2b197d12c648233aab4134b7c2a2f65db89a49728564f3d0864d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x40cb487ecffda94f97ce7fc0f7163f2f024235df2c8291169edc80dac063e6d0","input":"0xcb40cbfd","nonce":"0x6","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xe","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x993c4386ffc2bd63a48dd31cf5f65aa355cba3c063b08778b328d748937098e5","s":"0x203b1faf595628dd78e760bcc1740065625abb6cf00b1b17224e10fa6b424e43","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xafc7682751d3654f34958e3fb660971bf5918367","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xefb40664","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xb76bb3d88c9b30d927c45ccfcf8d5b0054411ac8501ad588822a7d04690cccf6","input":"0x40c10f19000000000000000000000000afc7682751d3654f34958e3fb660971bf59183670000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x20","to":"0x84ced17d95f3ec7230baf4a369f1e624ae60090d","transactionIndex":"0xf","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x78e9d29c606f6a61a1428ed7326df05210d802c3061f3b469847cc461eb48025","s":"0x517afe5a21175f186233ae7a6c090cd33e028a77e5854e98eb2fa4c9284430e7","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0x16ba45bce","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x798ebe823209869347c08bd81e04fbf60e9bdfe44b1cc923215182d0cf3d4edb","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000032","nonce":"0x4e","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x10","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xbe2aa95f4c32188c9ecbae97286ab983f7cc5a7017d46c404f8eb80b55e2dc13","s":"0x55d8968f509f51633f49260178941fd5a3db999e1995206348d7a3f05152b3d5","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0xc6132c0c","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xbe68a7e02725f799a65ebb069ccc83a014ac7c40e4119bf7c220a2f6ddfee295","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000064","nonce":"0x4f","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x11","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1750ed45d0d2d048a61dcc3ff3e7ad0cbd395b77698c4f2eeb6baaea4c966d96","s":"0xe646e3a87b6dc50439468bcfd24cbf12a6f95b2762f1527c97a7d1b7f03530e","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd0c0338baac9ce09c1d1caab88b4360507061e37","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1918167aa","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xc90c3a72efe81331727fcce4b5bd4906066da314ca9a0b44023a6b09ea7e8114","input":"0x4e71d92d","nonce":"0xe7","to":"0x0137d796936e199b917b93118eb4e002508a48bd","transactionIndex":"0x12","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x22222ce8fe753082c8e5dc7478fa7b87db9c8d0fb070ebc88ab015db13fd6bb","s":"0x6dceadecf6f6a3ddc433a547dba6d5fcdfb7d006ce09eeae1c06c1828ef9fff9","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1a4019792","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x619a6cbd43cde074d314c19623bd66d9fb1e13c158d7138775236f798dc1245e","input":"0x1da1db5e00000000000000000000000000000000000000000000000000001b5ec4ff740d","nonce":"0x10","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x733c496e8c84f78d113bc8b5ad6d04a133bb10bbcecf0db93d97eeedfa3d984a","s":"0x6627c16aa7dea27db44c0f0641c30ffd544b9b9b1c299dc60611e1e01c714ee8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x11df0","gasPrice":"0x7b528d57","maxFeePerGas":"0x1d3fbccb8","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xca5a56cd77b9e5b0e79020cc6346edf205bc11e901984d805125f28c2e6686e6","input":"0xd7c01032000000000000000000000000356f24c0f3187a6dcb949e4a60aa0a74a8a0327e0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd","nonce":"0x11","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x4aa872c1a7da70126917604193717575b91407f82449bca956d4089b90cd902","s":"0x4b5f788c68024f8958f66e8c768a8e0f65ef297c4ffd420a715258b0a55cb0a0","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1e706c8d2","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x999c9ddeed67c6ef6fbf02a6e977a6c1b68e18d24814e51643c7157b87a43e0a","input":"0xa8b78ed0","nonce":"0x3","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf1ca074104ee0b6a67223afd797654b8f21060453f7662dd7be79de938c396da","s":"0x4c9a4e56f0ad21e2dd8d1116c7a3e41ea2c6126853772f7897bd959e81e2e28a","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x2dc6c0","gasPrice":"0xd4babc57","maxFeePerGas":"0x21c13e710","maxPriorityFeePerGas":"0x9502f900","hash":"0x47c8f5d0b3778e4c34eba7fcc356fa04a5afd954ccf484728e72c002764dd3c4","input":"0xf688bcfb0000000000000000000000000000000000000000000000000000000005f5e100","nonce":"0x4","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x970982425d18b9949141bbabb5c5230fa168626ce210a97f3856d64700fc0eeb","s":"0x6fa6d0aea6ae48783d80c1e51cda47e11c28b90a5497579b93d7f242d786f67e","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4b596cebd02c35aa99878eb9ecb24d6f5ca5f865","gas":"0x5208","gasPrice":"0x68c88f79","maxFeePerGas":"0x68c88f79","maxPriorityFeePerGas":"0x68c88f79","hash":"0x396797ae0ebcdb72ff1f96fd08b6128f78acc7417353f142f1a5facd425a33e6","input":"0x","nonce":"0x1","to":"0x375980b8e1a417620ba9b18e5a9e0b17dccbac9d","transactionIndex":"0x17","value":"0x1c9a406c58878","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcb2a7b106097b2f2a61d3a048054a5175c386b1dcdd5b6fcd7849dcac7c32a66","s":"0x10aef76e98276c47470f04a599b81c260ace9d2f6adc95755c6d22d859e805a2","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0x1b2e020","gasPrice":"0x61010bda","maxFeePerGas":"0x61010bda","maxPriorityFeePerGas":"0x61010bda","hash":"0x454aa43d6546a6f62246826c16b7a49c6c704238c18802ef0d659922f23a573c","input":"0xe99a3f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee40000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e06defd69964a6ce467b87c64627a7a2be4be139b504757c625eb6114ec166557d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001f63c28250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf17500000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d5458000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000413e24433da3efc4c3cc305339a7b77a1b31abb4e4d4967e97e42aed1dd0bf98936f43035f40bc80f6f6e3a9cfb43524a1171ee7f21e9ac2fa586d33a31f10619d1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace5786000000000000000000000000000000000000000000000000000000000000012000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf1750000000000000000000000000000000000000000000000000000000000000ba200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175ffffffff09616c6c64617461","nonce":"0x82","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xc7ac308b1ae238cb2aa4b030ca79baffb7b498e1b10df0c3354b3cc19cfabac9","s":"0x2358b1093b9aab5fae0cf751766b0bb2e3d8cd2b18ca627e1e12520990a8ed6d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6ece61d29b90642941c41240da924690da145696","gas":"0x4399c","gasPrice":"0x506794e0","hash":"0x317ecb5bd19caa42a69f836d41556ebb0e0e00e1c6cd2dee230e6e6192612527","input":"0x46f83b5000000000000000000000000000000000000000000000000000000000000000654666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b000000000000000000000000000000000000000000000000000000000000000f4666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b","nonce":"0x2cc4","to":"0xa6bf2be6c60175601bf88217c75dd4b14abb5fbb","transactionIndex":"0x19","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x37aeab0db6d550e6cba2c04c9cb10a2af0fec0b11f6e04b85e1ea0b8b9defeae","s":"0x4f32f4ef74872e1385c25e69bf21ee049545a4d423e939eaff29677450efe9eb"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xc4a5c059840a146b81c77bf79f1398f2b3d28ca7","gas":"0x432ec","gasPrice":"0x45db0a51","hash":"0xc879285db5ef0a6bce98021584d16f134c1dc0aed8cc988802c4f72ba6877ff6","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1a7","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1a","value":"0x470efc4514e000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x237e3a541c5ab490843cdc20d0fcb7416bff8da471f6a11ae1b32d2bab119141","s":"0x3c8417d7a60bd5b0bcae4975dbb4aaee54a4b4d588226481be400843bfe2b64e"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0xffff","gasPrice":"0x44e9acbc","maxFeePerGas":"0x44e9acbc","maxPriorityFeePerGas":"0x44e9acbc","hash":"0xecaa2d6f597608307e5084854854ba6dc1e69395e2abea14f2c6a2fa1d6faf9a","input":"0xe2864fe300000000000000000000000000000000000000000000000000000000000000200000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace57860000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002004a8312e37fcecd450e6684009a2b54bc64f66afbe5217c7b2f63b03cd9980a9e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064893e8223d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a7640000aaaebeba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d54580000000000000000000000000000000000000000000000000000000000000000","nonce":"0x83","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x1b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa18772e4b9e1493ebfd5ae6219cc9ca060b71e83788fb614ab02b03fb36eaf1b","s":"0x482c7e50fde29bb4130fd6e723176e0e9913430ebb9260667d7fb55f5408d9c5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xdb33365a8730de2f7574ff1189fb9d337bf4c36d","gas":"0x61a80","gasPrice":"0x433653c8","maxFeePerGas":"0x828367af","maxPriorityFeePerGas":"0x37e9071","hash":"0x4dd69b69a568ff30ae439e2ded72fbd7f2e7aaa345836703663f155c749c5eed","input":"0x7f34c0ddc6e984f46ab7c13b7a53643096e79c39103dc74550204d5bd1b5206ef5a2f49689071bb6a332212df26aa57cd4d1e3c0894187a9fc5e5d686cbedba5b187470f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000e8c44c30e8e52c38ac7bd232e7b7f0c7463a535100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002e516d5044645856613738437a6b7856325a364e52777a67685a785872736e75397261616a695a7555423569465a62000000000000000000000000000000000000","nonce":"0x2b57","to":"0xb8ad54644e2371cbb7940b9fa0936f399ba7495f","transactionIndex":"0x1c","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa1fb0e5662b54ceb3dc1623ebfb200668433cb27252d553669bcd136387394f3","s":"0x27c2f8e19f69a52a0960f05d8b21f11c313dd3e86a7139b5783a18353c407415","yParity":"0x0"}],"transactionsRoot":"0x4a87d0cf5990b1c5bac631583e5965c2ba943858bebb2e07f74d0b697f73821a","uncles":[],"withdrawals":[{"index":"0x1171","validatorIndex":"0x38c2d","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6cd228e4"},{"index":"0x1172","validatorIndex":"0x38c2e","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x77f3431b"},{"index":"0x1173","validatorIndex":"0x38c2f","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6b61f268"},{"index":"0x1174","validatorIndex":"0x38c30","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6e10bb21"},{"index":"0x1175","validatorIndex":"0x38c31","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6eb115a5"},{"index":"0x1176","validatorIndex":"0x38c32","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7caead1d"},{"index":"0x1177","validatorIndex":"0x38c33","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x772c0ddf"},{"index":"0x1178","validatorIndex":"0x38c34","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x75930a95"},{"index":"0x1179","validatorIndex":"0x38c35","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76a4db09"},{"index":"0x117a","validatorIndex":"0x38c36","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7e692b27"},{"index":"0x117b","validatorIndex":"0x38c37","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x72038ae6"},{"index":"0x117c","validatorIndex":"0x38c38","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6ccce352"},{"index":"0x117d","validatorIndex":"0x38c39","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x79ef6898"},{"index":"0x117e","validatorIndex":"0x38c3a","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6d58977d"},{"index":"0x117f","validatorIndex":"0x38c3b","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76f7d208"}],"withdrawalsRoot":"0x6fd5c0b3074ad20176493616ef2e1ca79172f09ff7695e63a5ca2fd7b66cbe55"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-hash_metadata.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-hash_metadata.json new file mode 100644 index 000000000000..afffda99a930 --- /dev/null +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-hash_metadata.json @@ -0,0 +1 @@ +{"name":"post-shanghai-bad-withdrawals-hash","fail":true, "reason":"failed to verify block hash"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-nil_data.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-nil_data.json new file mode 100644 index 000000000000..6891f9916845 --- /dev/null +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-nil_data.json @@ -0,0 +1 @@ +{"baseFeePerGas":"0x3fb7c357","difficulty":"0x0","extraData":"0x","gasLimit":"0x1c9c380","gasUsed":"0x18f759","hash":"0x808eada47015f4a265801a708c720cc5d7c7e051fdd7cd1e042777866b379a73","logsBloom":"0x020010404000001a0000021000000080001100410000100001000010040200980220400000008806200200000100000000000000000000008000000400042000000050000040000112080808800002044000040004042008800480002000000000000002020020000042002400000820000080040000000010200010020010100101212050000008000000008000001010200c80000112010000438040020400000000202400000000002002a0210402000622010000000001700144000040000000002204000000c000410105024010000808000000002004002000000261000000822200200800881000000012500400400000000000000040010000800000","miner":"0x000095e79eac4d76aab57cb2c1f091d553b36ca0","mixHash":"0x5b53dc49cbab268ef9950b1d81b5e36a1b2f1b97aee1b7ff6e4db0e06c29a8b0","nonce":"0x0000000000000000","number":"0x84161e","parentHash":"0x72d92c1498e05952988d4e79a695928a6bcbd37239f8a1734051263b4d3504b8","receiptsRoot":"0xaff90ae18dcc35924a4bddb68d403b8b7812c10c3ea2a114f34105c87d75bcdb","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2a51","stateRoot":"0xc56738518b2c7854a640ae25996d2211c9ef0dd2e4dd9e59e9d9cacef39622da","timestamp":"0x64110a5c","totalDifficulty":"0xa4a470","transactions":[{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x1b7aa44088a0ea95bdc65fef6e5071e946bf7d8f","gas":"0x5208","gasPrice":"0x4159f01735","hash":"0x1e8f148a9aea7d8d16ea6e9446723b8f262e8bcd89c7c961d52046ebd43b4598","input":"0x","nonce":"0x279ad","to":"0xa21765a03dd41e2783696d314f235f4d520f6cac","transactionIndex":"0x0","value":"0x3782dace9d90000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xf9eca8b74ccaec5f4a83e981baeb8602f38d0271179c592b4a18f3866316a367","s":"0x350a9d26718d1fa9dc4f268f9c0e18fb96dbc037816ca8fc20f33f1a76f9f501"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4d9a852e6aecd3a6e87fece2ca109780e45e6f2d","gas":"0x160ab","gasPrice":"0xd4babc57","maxFeePerGas":"0x11407d03e","maxPriorityFeePerGas":"0x9502f900","hash":"0xab5c870f4c367012bd763172afbfbe68fbf35336a66ae41aff3f2c9dbf4ea3f8","input":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200c479c99d58d7fbee5ee3aef5001431073a3d465bdfa46cf747a7c0b9289607864736f6c634300080d0033","nonce":"0xafd","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x48f6acf4ac4371eb96ffca8cdef5b7704ea8c68a631d1c02927036d4ce92567e","s":"0x1f12261ddde63fd3da2ed9ea1bcbb4b0f25af898248c805a9d4b0a6e42caf9c8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xce297b30e56bf2f6142c4048fbae1cb8a756fefd","gas":"0x557300","gasPrice":"0xd4babc57","maxFeePerGas":"0xfabdd183","maxPriorityFeePerGas":"0x9502f900","hash":"0xa81fd92b2d0f0bbd3cc355f869cca3243c98c5e2641db9ecf3eeabb3b13bff6a","input":"0x7bbaf1ea0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000","nonce":"0xad92","to":"0x4c0ce02c1219ce5d2afffba97e484272a4637b49","transactionIndex":"0x2","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xd11b842a5f7b0e020470e764b443fafc4044327bca8dbb37131425359abace2","s":"0x1009867573946fb0a4a35339a6eaaece4d0a168b2346539076e6319e9a466b1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x47a916d0b694c95bc0c09953c1a6e22c8867be32","gas":"0x5208","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xa92c7b720c08c83f1a0ed7e4c163200e30a3a8c03fcc5a51e685ea20cd0cb577","input":"0x","nonce":"0x2","to":"0xf955dfe99bbfd06a8be208274cd654ecfb66a45e","transactionIndex":"0x3","value":"0x11c37937e08000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeecd431225215c3ddc2e13cf16fa29f9a2ab1afbaa02988f3ceac27416edf0f5","s":"0x6494062330a9d509f7c778cb45cbcc9932e5f9b4ec94a1ec315f579f8d973b7b","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x672d214fe4db218defae698085a3ccefc773dfa9","gas":"0xf4f6","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0x6921b429ad2ec1e97d3457049ad2e893b5a0349beba47ca1c74a9540af75347a","input":"0xa1ddc546000000000000000000000000000000000000000000000000000000000000118f","nonce":"0x8e","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x4","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4732ad21401b509bebb947a8566127fba1e245eb5a262ddc522d6867ab80567e","s":"0x2153013617fefdb06db0a7316d8883056441d33c2abf5ed6291fa0e3cc5c3a2f","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x0b12f7f996579fe7d9302d2574910121c214ee15","gas":"0x56a8","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xf776b2da0b835dde05d0d8b76fd19385d61e7055036cf637f804b36dc94f2384","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f40000000000000000000000000b12f7f996579fe7d9302d2574910121c214ee150000000000000000000000000000000000000000000000000000000000000000","nonce":"0xe","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x5","value":"0x2386f26fc10000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc4505d4c46ef9a0103178e5ef4fbc857114ae5c4686b68b74d07c3ee3a86e575","s":"0x74db34fd675bea7d2ee74f14fd8709cb88c7d22c2267d12f2c671b5ebc180bd5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd36aac0c9676e984d72823fb662ce94d3ab5e551","gas":"0xff212","gasPrice":"0x991ff257","maxFeePerGas":"0xd86d063e","maxPriorityFeePerGas":"0x59682f00","hash":"0x9a08d899cd14ebb930ed59fa774afdb88a22615b3a931e930931ea54d26dc0bc","input":"0x49160658babdf216946a22b96c966ceeba750f14807726306ebeed500a2621a7481df010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000084d6f6f6e6265616d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078434133633746363939643335333137316438434643364236334431433764333841333233373238300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b616f73c8d00641109f0000054f967b8a135e44e233da070ea88c5e4a53bacac0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c6a3a17399d88e5dfd2de4fa41dcccade6a2d2170000000000000000000000008676147503f761e44b85df01811edd52be01b56c000000000000000000000000000000000000000000000000d02ab486cedc00000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x7121","to":"0x2d276bd64fe8643a1d76b2e9530c753423e972c1","transactionIndex":"0x6","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xce452361d331baf2ac86947a1b3b454b3e842923e1f39139b33a572845dd5d7c","s":"0x388126881782af5a146ce8409f1e3a2c9a4cadcfe9a2c1d27258af6e4eb5cec1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x326ff","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0x0fe0d97e25d5eb11a33a3e8278584c3780941fc2675bdf8fc547cee3d1fd3b17","input":"0xa4110dbe190e65a7fe0ad5acd305c6446a02cb39de30f382000fe67927434063bf4c4b2ca86b3ee6d039dc7a0268f9e1c39266c3f12a752a7eb72f0895dedf62291fd292","nonce":"0x12e","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x46819bb540fa459a5a0cbf041a0286507d597fc8958a6af8b9ce193f00005238","s":"0x31495c58bf4b74925f870c59635912681bee947b1cb4b08cc19f22421b1a10ab","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x3270b","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0xef47a60f57f177a683c723c658137efab66d311e1c5abbc4d74f653535144d03","input":"0xa4110dbe18eba3e815ec7fcb03a8eea0487209c3253024d1dc4f36f775a43fdd3e409b74c0a5c88e54f39b88db6f185a41431b204120d3e66c9b08b86f5e8382623327e5","nonce":"0x12f","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x8","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4d7e11fe3914763a2735493a62b71ae0028e75a750a8b06407996cf478e273c8","s":"0x60c18fdf948721f96fdc2efbf694910122e82191c7a40a5caab247c06ab7f3cf","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x7712a1f96b3f37c3dd88a22d4f7a7977b937fe62","gas":"0x1ff06","gasPrice":"0x991ff257","maxFeePerGas":"0xcf662006","maxPriorityFeePerGas":"0x59682f00","hash":"0xe23a5b35faae5335adc5aca38c5d633b00438b798c2053104b8df48406c9b141","input":"0x3ff9751b0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000002e516d566e75374a51566f445271536748427a72615970374879373848774a744c4669366e5546436f775447647a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d5439716b3343525962464457704446596541763854384831676e6f6e67774b6868354a36384e4c6b4c6972360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041c9f31b989aaa745aecc563139f89c8ab3ab492e725d1e0305b7d602fcbf9293c463f0d2e4f5fb0c9efb54eb2cde9af10ebc9c3676f2334007291ffa8efb40adb1c00000000000000000000000000000000000000000000000000000000000000","nonce":"0x16","to":"0xc3b87ea584cb9cb5a4523e2bed16a34bf7746317","transactionIndex":"0x9","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcc693a9544394653e1f393f02635e2c1f78b5e6c26c4d00a867bcf4adc2bc09e","s":"0x23f4b71b773c19f77cf251b2aeea03f2696bddd847d1f6d75acd2fbea6a543e4","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0x1b2e020","gasPrice":"0x8f0d3617","maxFeePerGas":"0x1cb3abd5a","maxPriorityFeePerGas":"0x4f5572c0","hash":"0xd8cea4ba619b317bc05d58534af73beec6c2548b31b24d4dc61c9bbd29cfa17a","input":"0x","nonce":"0x4d","to":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8dae28608985d6ab47cbe122ee88972e38664cede30978f41944f347bad86e5c","s":"0x17c2898b39b7e3b874dc78e7df3fcff68f4d715385c632aad4bdf6e62505651c","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6999c36394dd5d3d3295af63a4736ad6bd279448","gas":"0x14d94","gasPrice":"0x7b528d57","maxFeePerGas":"0x7df743e0","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x79a4b9d90b02c768baaad305f266281213cc75062cbe99a13222cc0c4b509498","input":"0x6a7612020000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000a4ec6cb13f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003826d8d7371becafc0afedc3fe85b699b87f4357d55ec39ce83c510ed7d70ff514dce8236351f4627ccec6a7d9a67bc6fc2ec17ca76411113c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000006999c36394dd5d3d3295af63a4736ad6bd27944800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000","nonce":"0x13","to":"0xdce8236351f4627ccec6a7d9a67bc6fc2ec17ca7","transactionIndex":"0xb","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x669487011643510f7512ec15b07d74efb853ba4ad9fe9c7e9850ccf24e3d4c53","s":"0x2191f9ee81087e1df833e69d6129ec330ed4c99be2031060834e22c589fcf79b","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xf6e4d9c4","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x6790a3bbddbeb21fcb736a59b3775755051c3a6344d8390cf8ca27f2e8a814f0","input":"0x6871ee40","nonce":"0x4","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xc","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa7a58ab858e5dd87b9a74d550e5716ac40ddefd1c21d5baa51e542f4f941d73e","s":"0x1fd0cb1563df0368bd332717d7c8210187cd1ac2ff44f61f5242fc02eaa0c2fe","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x87ec7ace5442db252b5751ffddd38dcb04b088d36b6b0e526ff25607a4293c81","input":"0xcb40cbfd","nonce":"0x5","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xd","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x8e4bd40195bdfaa868af97dbf22e0b74295d95564a8381bc9bcfe1af3cde2cdb","s":"0x62057dc87c8b2b197d12c648233aab4134b7c2a2f65db89a49728564f3d0864d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x40cb487ecffda94f97ce7fc0f7163f2f024235df2c8291169edc80dac063e6d0","input":"0xcb40cbfd","nonce":"0x6","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xe","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x993c4386ffc2bd63a48dd31cf5f65aa355cba3c063b08778b328d748937098e5","s":"0x203b1faf595628dd78e760bcc1740065625abb6cf00b1b17224e10fa6b424e43","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xafc7682751d3654f34958e3fb660971bf5918367","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xefb40664","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xb76bb3d88c9b30d927c45ccfcf8d5b0054411ac8501ad588822a7d04690cccf6","input":"0x40c10f19000000000000000000000000afc7682751d3654f34958e3fb660971bf59183670000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x20","to":"0x84ced17d95f3ec7230baf4a369f1e624ae60090d","transactionIndex":"0xf","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x78e9d29c606f6a61a1428ed7326df05210d802c3061f3b469847cc461eb48025","s":"0x517afe5a21175f186233ae7a6c090cd33e028a77e5854e98eb2fa4c9284430e7","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0x16ba45bce","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x798ebe823209869347c08bd81e04fbf60e9bdfe44b1cc923215182d0cf3d4edb","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000032","nonce":"0x4e","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x10","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xbe2aa95f4c32188c9ecbae97286ab983f7cc5a7017d46c404f8eb80b55e2dc13","s":"0x55d8968f509f51633f49260178941fd5a3db999e1995206348d7a3f05152b3d5","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0xc6132c0c","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xbe68a7e02725f799a65ebb069ccc83a014ac7c40e4119bf7c220a2f6ddfee295","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000064","nonce":"0x4f","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x11","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1750ed45d0d2d048a61dcc3ff3e7ad0cbd395b77698c4f2eeb6baaea4c966d96","s":"0xe646e3a87b6dc50439468bcfd24cbf12a6f95b2762f1527c97a7d1b7f03530e","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd0c0338baac9ce09c1d1caab88b4360507061e37","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1918167aa","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xc90c3a72efe81331727fcce4b5bd4906066da314ca9a0b44023a6b09ea7e8114","input":"0x4e71d92d","nonce":"0xe7","to":"0x0137d796936e199b917b93118eb4e002508a48bd","transactionIndex":"0x12","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x22222ce8fe753082c8e5dc7478fa7b87db9c8d0fb070ebc88ab015db13fd6bb","s":"0x6dceadecf6f6a3ddc433a547dba6d5fcdfb7d006ce09eeae1c06c1828ef9fff9","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1a4019792","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x619a6cbd43cde074d314c19623bd66d9fb1e13c158d7138775236f798dc1245e","input":"0x1da1db5e00000000000000000000000000000000000000000000000000001b5ec4ff740d","nonce":"0x10","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x733c496e8c84f78d113bc8b5ad6d04a133bb10bbcecf0db93d97eeedfa3d984a","s":"0x6627c16aa7dea27db44c0f0641c30ffd544b9b9b1c299dc60611e1e01c714ee8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x11df0","gasPrice":"0x7b528d57","maxFeePerGas":"0x1d3fbccb8","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xca5a56cd77b9e5b0e79020cc6346edf205bc11e901984d805125f28c2e6686e6","input":"0xd7c01032000000000000000000000000356f24c0f3187a6dcb949e4a60aa0a74a8a0327e0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd","nonce":"0x11","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x4aa872c1a7da70126917604193717575b91407f82449bca956d4089b90cd902","s":"0x4b5f788c68024f8958f66e8c768a8e0f65ef297c4ffd420a715258b0a55cb0a0","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1e706c8d2","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x999c9ddeed67c6ef6fbf02a6e977a6c1b68e18d24814e51643c7157b87a43e0a","input":"0xa8b78ed0","nonce":"0x3","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf1ca074104ee0b6a67223afd797654b8f21060453f7662dd7be79de938c396da","s":"0x4c9a4e56f0ad21e2dd8d1116c7a3e41ea2c6126853772f7897bd959e81e2e28a","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x2dc6c0","gasPrice":"0xd4babc57","maxFeePerGas":"0x21c13e710","maxPriorityFeePerGas":"0x9502f900","hash":"0x47c8f5d0b3778e4c34eba7fcc356fa04a5afd954ccf484728e72c002764dd3c4","input":"0xf688bcfb0000000000000000000000000000000000000000000000000000000005f5e100","nonce":"0x4","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x970982425d18b9949141bbabb5c5230fa168626ce210a97f3856d64700fc0eeb","s":"0x6fa6d0aea6ae48783d80c1e51cda47e11c28b90a5497579b93d7f242d786f67e","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4b596cebd02c35aa99878eb9ecb24d6f5ca5f865","gas":"0x5208","gasPrice":"0x68c88f79","maxFeePerGas":"0x68c88f79","maxPriorityFeePerGas":"0x68c88f79","hash":"0x396797ae0ebcdb72ff1f96fd08b6128f78acc7417353f142f1a5facd425a33e6","input":"0x","nonce":"0x1","to":"0x375980b8e1a417620ba9b18e5a9e0b17dccbac9d","transactionIndex":"0x17","value":"0x1c9a406c58878","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcb2a7b106097b2f2a61d3a048054a5175c386b1dcdd5b6fcd7849dcac7c32a66","s":"0x10aef76e98276c47470f04a599b81c260ace9d2f6adc95755c6d22d859e805a2","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0x1b2e020","gasPrice":"0x61010bda","maxFeePerGas":"0x61010bda","maxPriorityFeePerGas":"0x61010bda","hash":"0x454aa43d6546a6f62246826c16b7a49c6c704238c18802ef0d659922f23a573c","input":"0xe99a3f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee40000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e06defd69964a6ce467b87c64627a7a2be4be139b504757c625eb6114ec166557d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001f63c28250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf17500000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d5458000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000413e24433da3efc4c3cc305339a7b77a1b31abb4e4d4967e97e42aed1dd0bf98936f43035f40bc80f6f6e3a9cfb43524a1171ee7f21e9ac2fa586d33a31f10619d1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace5786000000000000000000000000000000000000000000000000000000000000012000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf1750000000000000000000000000000000000000000000000000000000000000ba200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175ffffffff09616c6c64617461","nonce":"0x82","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xc7ac308b1ae238cb2aa4b030ca79baffb7b498e1b10df0c3354b3cc19cfabac9","s":"0x2358b1093b9aab5fae0cf751766b0bb2e3d8cd2b18ca627e1e12520990a8ed6d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6ece61d29b90642941c41240da924690da145696","gas":"0x4399c","gasPrice":"0x506794e0","hash":"0x317ecb5bd19caa42a69f836d41556ebb0e0e00e1c6cd2dee230e6e6192612527","input":"0x46f83b5000000000000000000000000000000000000000000000000000000000000000654666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b000000000000000000000000000000000000000000000000000000000000000f4666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b","nonce":"0x2cc4","to":"0xa6bf2be6c60175601bf88217c75dd4b14abb5fbb","transactionIndex":"0x19","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x37aeab0db6d550e6cba2c04c9cb10a2af0fec0b11f6e04b85e1ea0b8b9defeae","s":"0x4f32f4ef74872e1385c25e69bf21ee049545a4d423e939eaff29677450efe9eb"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xc4a5c059840a146b81c77bf79f1398f2b3d28ca7","gas":"0x432ec","gasPrice":"0x45db0a51","hash":"0xc879285db5ef0a6bce98021584d16f134c1dc0aed8cc988802c4f72ba6877ff6","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1a7","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1a","value":"0x470efc4514e000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x237e3a541c5ab490843cdc20d0fcb7416bff8da471f6a11ae1b32d2bab119141","s":"0x3c8417d7a60bd5b0bcae4975dbb4aaee54a4b4d588226481be400843bfe2b64e"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0xffff","gasPrice":"0x44e9acbc","maxFeePerGas":"0x44e9acbc","maxPriorityFeePerGas":"0x44e9acbc","hash":"0xecaa2d6f597608307e5084854854ba6dc1e69395e2abea14f2c6a2fa1d6faf9a","input":"0xe2864fe300000000000000000000000000000000000000000000000000000000000000200000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace57860000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002004a8312e37fcecd450e6684009a2b54bc64f66afbe5217c7b2f63b03cd9980a9e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064893e8223d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a7640000aaaebeba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d54580000000000000000000000000000000000000000000000000000000000000000","nonce":"0x83","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x1b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa18772e4b9e1493ebfd5ae6219cc9ca060b71e83788fb614ab02b03fb36eaf1b","s":"0x482c7e50fde29bb4130fd6e723176e0e9913430ebb9260667d7fb55f5408d9c5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xdb33365a8730de2f7574ff1189fb9d337bf4c36d","gas":"0x61a80","gasPrice":"0x433653c8","maxFeePerGas":"0x828367af","maxPriorityFeePerGas":"0x37e9071","hash":"0x4dd69b69a568ff30ae439e2ded72fbd7f2e7aaa345836703663f155c749c5eed","input":"0x7f34c0ddc6e984f46ab7c13b7a53643096e79c39103dc74550204d5bd1b5206ef5a2f49689071bb6a332212df26aa57cd4d1e3c0894187a9fc5e5d686cbedba5b187470f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000e8c44c30e8e52c38ac7bd232e7b7f0c7463a535100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002e516d5044645856613738437a6b7856325a364e52777a67685a785872736e75397261616a695a7555423569465a62000000000000000000000000000000000000","nonce":"0x2b57","to":"0xb8ad54644e2371cbb7940b9fa0936f399ba7495f","transactionIndex":"0x1c","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa1fb0e5662b54ceb3dc1623ebfb200668433cb27252d553669bcd136387394f3","s":"0x27c2f8e19f69a52a0960f05d8b21f11c313dd3e86a7139b5783a18353c407415","yParity":"0x0"}],"transactionsRoot":"0x4a87d0cf5990b1c5bac631583e5965c2ba943858bebb2e07f74d0b697f73821a","uncles":[],"withdrawals":[null,{"index":"0x1171","validatorIndex":"0x38c2d","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6cd228e4"},{"index":"0x1172","validatorIndex":"0x38c2e","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x77f3431b"},{"index":"0x1173","validatorIndex":"0x38c2f","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6b61f268"},{"index":"0x1174","validatorIndex":"0x38c30","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6e10bb21"},{"index":"0x1175","validatorIndex":"0x38c31","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6eb115a5"},{"index":"0x1176","validatorIndex":"0x38c32","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7caead1d"},{"index":"0x1177","validatorIndex":"0x38c33","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x772c0ddf"},{"index":"0x1178","validatorIndex":"0x38c34","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x75930a95"},{"index":"0x1179","validatorIndex":"0x38c35","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76a4db09"},{"index":"0x117a","validatorIndex":"0x38c36","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7e692b27"},{"index":"0x117b","validatorIndex":"0x38c37","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x72038ae6"},{"index":"0x117c","validatorIndex":"0x38c38","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6ccce352"},{"index":"0x117d","validatorIndex":"0x38c39","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x79ef6898"},{"index":"0x117e","validatorIndex":"0x38c3a","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6d58977d"},{"index":"0x117f","validatorIndex":"0x38c3b","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76f7d208"}],"withdrawalsRoot":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-nil_metadata.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-nil_metadata.json new file mode 100644 index 000000000000..284a5aa42de4 --- /dev/null +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals-nil_metadata.json @@ -0,0 +1 @@ +{"name":"post-shanghai-bad-withdrawals-nil","fail":true, "reason": "block withdrawal 0 is null"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals_data.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals_data.json index f66ef388b910..6c5747e36701 100644 --- a/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals_data.json +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals_data.json @@ -1 +1 @@ -{"baseFeePerGas":"0x3fb7c357","difficulty":"0x0","extraData":"0x","gasLimit":"0x1c9c380","gasUsed":"0x18f759","hash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","logsBloom":"0x020010404000001a0000021000000080001100410000100001000010040200980220400000008806200200000100000000000000000000008000000400042000000050000040000112080808800002044000040004042008800480002000000000000002020020000042002400000820000080040000000010200010020010100101212050000008000000008000001010200c80000112010000438040020400000000202400000000002002a0210402000622010000000001700144000040000000002204000000c000410105024010000808000000002004002000000261000000822200200800881000000012500400400000000000000040010000800000","miner":"0x000095e79eac4d76aab57cb2c1f091d553b36ca0","mixHash":"0x5b53dc49cbab268ef9950b1d81b5e36a1b2f1b97aee1b7ff6e4db0e06c29a8b0","nonce":"0x0000000000000000","number":"0x84161e","parentHash":"0x72d92c1498e05952988d4e79a695928a6bcbd37239f8a1734051263b4d3504b8","receiptsRoot":"0xaff90ae18dcc35924a4bddb68d403b8b7812c10c3ea2a114f34105c87d75bcdb","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2a51","stateRoot":"0xc56738518b2c7854a640ae25996d2211c9ef0dd2e4dd9e59e9d9cacef39622da","timestamp":"0x64110a5c","totalDifficulty":"0xa4a470","transactions":[{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x1b7aa44088a0ea95bdc65fef6e5071e946bf7d8f","gas":"0x5208","gasPrice":"0x4159f01735","hash":"0x1e8f148a9aea7d8d16ea6e9446723b8f262e8bcd89c7c961d52046ebd43b4598","input":"0x","nonce":"0x279ad","to":"0xa21765a03dd41e2783696d314f235f4d520f6cac","transactionIndex":"0x0","value":"0x3782dace9d90000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xf9eca8b74ccaec5f4a83e981baeb8602f38d0271179c592b4a18f3866316a367","s":"0x350a9d26718d1fa9dc4f268f9c0e18fb96dbc037816ca8fc20f33f1a76f9f501"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4d9a852e6aecd3a6e87fece2ca109780e45e6f2d","gas":"0x160ab","gasPrice":"0xd4babc57","maxFeePerGas":"0x11407d03e","maxPriorityFeePerGas":"0x9502f900","hash":"0xab5c870f4c367012bd763172afbfbe68fbf35336a66ae41aff3f2c9dbf4ea3f8","input":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200c479c99d58d7fbee5ee3aef5001431073a3d465bdfa46cf747a7c0b9289607864736f6c634300080d0033","nonce":"0xafd","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x48f6acf4ac4371eb96ffca8cdef5b7704ea8c68a631d1c02927036d4ce92567e","s":"0x1f12261ddde63fd3da2ed9ea1bcbb4b0f25af898248c805a9d4b0a6e42caf9c8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xce297b30e56bf2f6142c4048fbae1cb8a756fefd","gas":"0x557300","gasPrice":"0xd4babc57","maxFeePerGas":"0xfabdd183","maxPriorityFeePerGas":"0x9502f900","hash":"0xa81fd92b2d0f0bbd3cc355f869cca3243c98c5e2641db9ecf3eeabb3b13bff6a","input":"0x7bbaf1ea0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000","nonce":"0xad92","to":"0x4c0ce02c1219ce5d2afffba97e484272a4637b49","transactionIndex":"0x2","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xd11b842a5f7b0e020470e764b443fafc4044327bca8dbb37131425359abace2","s":"0x1009867573946fb0a4a35339a6eaaece4d0a168b2346539076e6319e9a466b1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x47a916d0b694c95bc0c09953c1a6e22c8867be32","gas":"0x5208","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xa92c7b720c08c83f1a0ed7e4c163200e30a3a8c03fcc5a51e685ea20cd0cb577","input":"0x","nonce":"0x2","to":"0xf955dfe99bbfd06a8be208274cd654ecfb66a45e","transactionIndex":"0x3","value":"0x11c37937e08000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeecd431225215c3ddc2e13cf16fa29f9a2ab1afbaa02988f3ceac27416edf0f5","s":"0x6494062330a9d509f7c778cb45cbcc9932e5f9b4ec94a1ec315f579f8d973b7b","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x672d214fe4db218defae698085a3ccefc773dfa9","gas":"0xf4f6","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0x6921b429ad2ec1e97d3457049ad2e893b5a0349beba47ca1c74a9540af75347a","input":"0xa1ddc546000000000000000000000000000000000000000000000000000000000000118f","nonce":"0x8e","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x4","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4732ad21401b509bebb947a8566127fba1e245eb5a262ddc522d6867ab80567e","s":"0x2153013617fefdb06db0a7316d8883056441d33c2abf5ed6291fa0e3cc5c3a2f","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x0b12f7f996579fe7d9302d2574910121c214ee15","gas":"0x56a8","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xf776b2da0b835dde05d0d8b76fd19385d61e7055036cf637f804b36dc94f2384","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f40000000000000000000000000b12f7f996579fe7d9302d2574910121c214ee150000000000000000000000000000000000000000000000000000000000000000","nonce":"0xe","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x5","value":"0x2386f26fc10000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc4505d4c46ef9a0103178e5ef4fbc857114ae5c4686b68b74d07c3ee3a86e575","s":"0x74db34fd675bea7d2ee74f14fd8709cb88c7d22c2267d12f2c671b5ebc180bd5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd36aac0c9676e984d72823fb662ce94d3ab5e551","gas":"0xff212","gasPrice":"0x991ff257","maxFeePerGas":"0xd86d063e","maxPriorityFeePerGas":"0x59682f00","hash":"0x9a08d899cd14ebb930ed59fa774afdb88a22615b3a931e930931ea54d26dc0bc","input":"0x49160658babdf216946a22b96c966ceeba750f14807726306ebeed500a2621a7481df010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000084d6f6f6e6265616d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078434133633746363939643335333137316438434643364236334431433764333841333233373238300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b616f73c8d00641109f0000054f967b8a135e44e233da070ea88c5e4a53bacac0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c6a3a17399d88e5dfd2de4fa41dcccade6a2d2170000000000000000000000008676147503f761e44b85df01811edd52be01b56c000000000000000000000000000000000000000000000000d02ab486cedc00000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x7121","to":"0x2d276bd64fe8643a1d76b2e9530c753423e972c1","transactionIndex":"0x6","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xce452361d331baf2ac86947a1b3b454b3e842923e1f39139b33a572845dd5d7c","s":"0x388126881782af5a146ce8409f1e3a2c9a4cadcfe9a2c1d27258af6e4eb5cec1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x326ff","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0x0fe0d97e25d5eb11a33a3e8278584c3780941fc2675bdf8fc547cee3d1fd3b17","input":"0xa4110dbe190e65a7fe0ad5acd305c6446a02cb39de30f382000fe67927434063bf4c4b2ca86b3ee6d039dc7a0268f9e1c39266c3f12a752a7eb72f0895dedf62291fd292","nonce":"0x12e","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x46819bb540fa459a5a0cbf041a0286507d597fc8958a6af8b9ce193f00005238","s":"0x31495c58bf4b74925f870c59635912681bee947b1cb4b08cc19f22421b1a10ab","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x3270b","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0xef47a60f57f177a683c723c658137efab66d311e1c5abbc4d74f653535144d03","input":"0xa4110dbe18eba3e815ec7fcb03a8eea0487209c3253024d1dc4f36f775a43fdd3e409b74c0a5c88e54f39b88db6f185a41431b204120d3e66c9b08b86f5e8382623327e5","nonce":"0x12f","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x8","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4d7e11fe3914763a2735493a62b71ae0028e75a750a8b06407996cf478e273c8","s":"0x60c18fdf948721f96fdc2efbf694910122e82191c7a40a5caab247c06ab7f3cf","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x7712a1f96b3f37c3dd88a22d4f7a7977b937fe62","gas":"0x1ff06","gasPrice":"0x991ff257","maxFeePerGas":"0xcf662006","maxPriorityFeePerGas":"0x59682f00","hash":"0xe23a5b35faae5335adc5aca38c5d633b00438b798c2053104b8df48406c9b141","input":"0x3ff9751b0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000002e516d566e75374a51566f445271536748427a72615970374879373848774a744c4669366e5546436f775447647a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d5439716b3343525962464457704446596541763854384831676e6f6e67774b6868354a36384e4c6b4c6972360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041c9f31b989aaa745aecc563139f89c8ab3ab492e725d1e0305b7d602fcbf9293c463f0d2e4f5fb0c9efb54eb2cde9af10ebc9c3676f2334007291ffa8efb40adb1c00000000000000000000000000000000000000000000000000000000000000","nonce":"0x16","to":"0xc3b87ea584cb9cb5a4523e2bed16a34bf7746317","transactionIndex":"0x9","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcc693a9544394653e1f393f02635e2c1f78b5e6c26c4d00a867bcf4adc2bc09e","s":"0x23f4b71b773c19f77cf251b2aeea03f2696bddd847d1f6d75acd2fbea6a543e4","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0x1b2e020","gasPrice":"0x8f0d3617","maxFeePerGas":"0x1cb3abd5a","maxPriorityFeePerGas":"0x4f5572c0","hash":"0xd8cea4ba619b317bc05d58534af73beec6c2548b31b24d4dc61c9bbd29cfa17a","input":"0x","nonce":"0x4d","to":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8dae28608985d6ab47cbe122ee88972e38664cede30978f41944f347bad86e5c","s":"0x17c2898b39b7e3b874dc78e7df3fcff68f4d715385c632aad4bdf6e62505651c","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6999c36394dd5d3d3295af63a4736ad6bd279448","gas":"0x14d94","gasPrice":"0x7b528d57","maxFeePerGas":"0x7df743e0","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x79a4b9d90b02c768baaad305f266281213cc75062cbe99a13222cc0c4b509498","input":"0x6a7612020000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000a4ec6cb13f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003826d8d7371becafc0afedc3fe85b699b87f4357d55ec39ce83c510ed7d70ff514dce8236351f4627ccec6a7d9a67bc6fc2ec17ca76411113c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000006999c36394dd5d3d3295af63a4736ad6bd27944800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000","nonce":"0x13","to":"0xdce8236351f4627ccec6a7d9a67bc6fc2ec17ca7","transactionIndex":"0xb","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x669487011643510f7512ec15b07d74efb853ba4ad9fe9c7e9850ccf24e3d4c53","s":"0x2191f9ee81087e1df833e69d6129ec330ed4c99be2031060834e22c589fcf79b","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xf6e4d9c4","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x6790a3bbddbeb21fcb736a59b3775755051c3a6344d8390cf8ca27f2e8a814f0","input":"0x6871ee40","nonce":"0x4","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xc","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa7a58ab858e5dd87b9a74d550e5716ac40ddefd1c21d5baa51e542f4f941d73e","s":"0x1fd0cb1563df0368bd332717d7c8210187cd1ac2ff44f61f5242fc02eaa0c2fe","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x87ec7ace5442db252b5751ffddd38dcb04b088d36b6b0e526ff25607a4293c81","input":"0xcb40cbfd","nonce":"0x5","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xd","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x8e4bd40195bdfaa868af97dbf22e0b74295d95564a8381bc9bcfe1af3cde2cdb","s":"0x62057dc87c8b2b197d12c648233aab4134b7c2a2f65db89a49728564f3d0864d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x40cb487ecffda94f97ce7fc0f7163f2f024235df2c8291169edc80dac063e6d0","input":"0xcb40cbfd","nonce":"0x6","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xe","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x993c4386ffc2bd63a48dd31cf5f65aa355cba3c063b08778b328d748937098e5","s":"0x203b1faf595628dd78e760bcc1740065625abb6cf00b1b17224e10fa6b424e43","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xafc7682751d3654f34958e3fb660971bf5918367","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xefb40664","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xb76bb3d88c9b30d927c45ccfcf8d5b0054411ac8501ad588822a7d04690cccf6","input":"0x40c10f19000000000000000000000000afc7682751d3654f34958e3fb660971bf59183670000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x20","to":"0x84ced17d95f3ec7230baf4a369f1e624ae60090d","transactionIndex":"0xf","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x78e9d29c606f6a61a1428ed7326df05210d802c3061f3b469847cc461eb48025","s":"0x517afe5a21175f186233ae7a6c090cd33e028a77e5854e98eb2fa4c9284430e7","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0x16ba45bce","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x798ebe823209869347c08bd81e04fbf60e9bdfe44b1cc923215182d0cf3d4edb","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000032","nonce":"0x4e","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x10","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xbe2aa95f4c32188c9ecbae97286ab983f7cc5a7017d46c404f8eb80b55e2dc13","s":"0x55d8968f509f51633f49260178941fd5a3db999e1995206348d7a3f05152b3d5","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0xc6132c0c","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xbe68a7e02725f799a65ebb069ccc83a014ac7c40e4119bf7c220a2f6ddfee295","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000064","nonce":"0x4f","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x11","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1750ed45d0d2d048a61dcc3ff3e7ad0cbd395b77698c4f2eeb6baaea4c966d96","s":"0xe646e3a87b6dc50439468bcfd24cbf12a6f95b2762f1527c97a7d1b7f03530e","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd0c0338baac9ce09c1d1caab88b4360507061e37","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1918167aa","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xc90c3a72efe81331727fcce4b5bd4906066da314ca9a0b44023a6b09ea7e8114","input":"0x4e71d92d","nonce":"0xe7","to":"0x0137d796936e199b917b93118eb4e002508a48bd","transactionIndex":"0x12","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x22222ce8fe753082c8e5dc7478fa7b87db9c8d0fb070ebc88ab015db13fd6bb","s":"0x6dceadecf6f6a3ddc433a547dba6d5fcdfb7d006ce09eeae1c06c1828ef9fff9","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1a4019792","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x619a6cbd43cde074d314c19623bd66d9fb1e13c158d7138775236f798dc1245e","input":"0x1da1db5e00000000000000000000000000000000000000000000000000001b5ec4ff740d","nonce":"0x10","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x733c496e8c84f78d113bc8b5ad6d04a133bb10bbcecf0db93d97eeedfa3d984a","s":"0x6627c16aa7dea27db44c0f0641c30ffd544b9b9b1c299dc60611e1e01c714ee8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x11df0","gasPrice":"0x7b528d57","maxFeePerGas":"0x1d3fbccb8","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xca5a56cd77b9e5b0e79020cc6346edf205bc11e901984d805125f28c2e6686e6","input":"0xd7c01032000000000000000000000000356f24c0f3187a6dcb949e4a60aa0a74a8a0327e0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd","nonce":"0x11","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x4aa872c1a7da70126917604193717575b91407f82449bca956d4089b90cd902","s":"0x4b5f788c68024f8958f66e8c768a8e0f65ef297c4ffd420a715258b0a55cb0a0","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1e706c8d2","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x999c9ddeed67c6ef6fbf02a6e977a6c1b68e18d24814e51643c7157b87a43e0a","input":"0xa8b78ed0","nonce":"0x3","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf1ca074104ee0b6a67223afd797654b8f21060453f7662dd7be79de938c396da","s":"0x4c9a4e56f0ad21e2dd8d1116c7a3e41ea2c6126853772f7897bd959e81e2e28a","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x2dc6c0","gasPrice":"0xd4babc57","maxFeePerGas":"0x21c13e710","maxPriorityFeePerGas":"0x9502f900","hash":"0x47c8f5d0b3778e4c34eba7fcc356fa04a5afd954ccf484728e72c002764dd3c4","input":"0xf688bcfb0000000000000000000000000000000000000000000000000000000005f5e100","nonce":"0x4","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x970982425d18b9949141bbabb5c5230fa168626ce210a97f3856d64700fc0eeb","s":"0x6fa6d0aea6ae48783d80c1e51cda47e11c28b90a5497579b93d7f242d786f67e","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4b596cebd02c35aa99878eb9ecb24d6f5ca5f865","gas":"0x5208","gasPrice":"0x68c88f79","maxFeePerGas":"0x68c88f79","maxPriorityFeePerGas":"0x68c88f79","hash":"0x396797ae0ebcdb72ff1f96fd08b6128f78acc7417353f142f1a5facd425a33e6","input":"0x","nonce":"0x1","to":"0x375980b8e1a417620ba9b18e5a9e0b17dccbac9d","transactionIndex":"0x17","value":"0x1c9a406c58878","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcb2a7b106097b2f2a61d3a048054a5175c386b1dcdd5b6fcd7849dcac7c32a66","s":"0x10aef76e98276c47470f04a599b81c260ace9d2f6adc95755c6d22d859e805a2","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0x1b2e020","gasPrice":"0x61010bda","maxFeePerGas":"0x61010bda","maxPriorityFeePerGas":"0x61010bda","hash":"0x454aa43d6546a6f62246826c16b7a49c6c704238c18802ef0d659922f23a573c","input":"0xe99a3f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee40000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e06defd69964a6ce467b87c64627a7a2be4be139b504757c625eb6114ec166557d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001f63c28250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf17500000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d5458000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000413e24433da3efc4c3cc305339a7b77a1b31abb4e4d4967e97e42aed1dd0bf98936f43035f40bc80f6f6e3a9cfb43524a1171ee7f21e9ac2fa586d33a31f10619d1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace5786000000000000000000000000000000000000000000000000000000000000012000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf1750000000000000000000000000000000000000000000000000000000000000ba200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175ffffffff09616c6c64617461","nonce":"0x82","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xc7ac308b1ae238cb2aa4b030ca79baffb7b498e1b10df0c3354b3cc19cfabac9","s":"0x2358b1093b9aab5fae0cf751766b0bb2e3d8cd2b18ca627e1e12520990a8ed6d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6ece61d29b90642941c41240da924690da145696","gas":"0x4399c","gasPrice":"0x506794e0","hash":"0x317ecb5bd19caa42a69f836d41556ebb0e0e00e1c6cd2dee230e6e6192612527","input":"0x46f83b5000000000000000000000000000000000000000000000000000000000000000654666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b000000000000000000000000000000000000000000000000000000000000000f4666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b","nonce":"0x2cc4","to":"0xa6bf2be6c60175601bf88217c75dd4b14abb5fbb","transactionIndex":"0x19","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x37aeab0db6d550e6cba2c04c9cb10a2af0fec0b11f6e04b85e1ea0b8b9defeae","s":"0x4f32f4ef74872e1385c25e69bf21ee049545a4d423e939eaff29677450efe9eb"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xc4a5c059840a146b81c77bf79f1398f2b3d28ca7","gas":"0x432ec","gasPrice":"0x45db0a51","hash":"0xc879285db5ef0a6bce98021584d16f134c1dc0aed8cc988802c4f72ba6877ff6","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1a7","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1a","value":"0x470efc4514e000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x237e3a541c5ab490843cdc20d0fcb7416bff8da471f6a11ae1b32d2bab119141","s":"0x3c8417d7a60bd5b0bcae4975dbb4aaee54a4b4d588226481be400843bfe2b64e"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0xffff","gasPrice":"0x44e9acbc","maxFeePerGas":"0x44e9acbc","maxPriorityFeePerGas":"0x44e9acbc","hash":"0xecaa2d6f597608307e5084854854ba6dc1e69395e2abea14f2c6a2fa1d6faf9a","input":"0xe2864fe300000000000000000000000000000000000000000000000000000000000000200000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace57860000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002004a8312e37fcecd450e6684009a2b54bc64f66afbe5217c7b2f63b03cd9980a9e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064893e8223d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a7640000aaaebeba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d54580000000000000000000000000000000000000000000000000000000000000000","nonce":"0x83","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x1b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa18772e4b9e1493ebfd5ae6219cc9ca060b71e83788fb614ab02b03fb36eaf1b","s":"0x482c7e50fde29bb4130fd6e723176e0e9913430ebb9260667d7fb55f5408d9c5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xdb33365a8730de2f7574ff1189fb9d337bf4c36d","gas":"0x61a80","gasPrice":"0x433653c8","maxFeePerGas":"0x828367af","maxPriorityFeePerGas":"0x37e9071","hash":"0x4dd69b69a568ff30ae439e2ded72fbd7f2e7aaa345836703663f155c749c5eed","input":"0x7f34c0ddc6e984f46ab7c13b7a53643096e79c39103dc74550204d5bd1b5206ef5a2f49689071bb6a332212df26aa57cd4d1e3c0894187a9fc5e5d686cbedba5b187470f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000e8c44c30e8e52c38ac7bd232e7b7f0c7463a535100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002e516d5044645856613738437a6b7856325a364e52777a67685a785872736e75397261616a695a7555423569465a62000000000000000000000000000000000000","nonce":"0x2b57","to":"0xb8ad54644e2371cbb7940b9fa0936f399ba7495f","transactionIndex":"0x1c","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa1fb0e5662b54ceb3dc1623ebfb200668433cb27252d553669bcd136387394f3","s":"0x27c2f8e19f69a52a0960f05d8b21f11c313dd3e86a7139b5783a18353c407415","yParity":"0x0"}],"transactionsRoot":"0x4a87d0cf5990b1c5bac631583e5965c2ba943858bebb2e07f74d0b697f73821a","uncles":[],"withdrawals":[{"index":"0x1170","validatorIndex":"0x38c2c","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x66edfd65"},{"index":"0x1171","validatorIndex":"0x38c2d","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6cd228e4"},{"index":"0x1172","validatorIndex":"0x38c2e","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x77f3431b"},{"index":"0x1173","validatorIndex":"0x38c2f","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6b61f268"},{"index":"0x1174","validatorIndex":"0x38c30","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6e10bb21"},{"index":"0x1175","validatorIndex":"0x38c31","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6eb115a5"},{"index":"0x1176","validatorIndex":"0x38c32","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7caead1d"},{"index":"0x1177","validatorIndex":"0x38c33","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x772c0ddf"},{"index":"0x1178","validatorIndex":"0x38c34","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x75930a95"},{"index":"0x1179","validatorIndex":"0x38c35","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76a4db09"},{"index":"0x117a","validatorIndex":"0x38c36","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7e692b27"},{"index":"0x117b","validatorIndex":"0x38c37","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x72038ae6"},{"index":"0x117c","validatorIndex":"0x38c38","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6ccce352"},{"index":"0x117d","validatorIndex":"0x38c39","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x79ef6898"},{"index":"0x117e","validatorIndex":"0x38c3a","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6d58977d"},{"index":"0x117f","validatorIndex":"0x38c3b","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76f7d208"}],"withdrawalsRoot":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"} +{"baseFeePerGas":"0x3fb7c357","difficulty":"0x0","extraData":"0x","gasLimit":"0x1c9c380","gasUsed":"0x18f759","hash":"0x808eada47015f4a265801a708c720cc5d7c7e051fdd7cd1e042777866b379a73","logsBloom":"0x020010404000001a0000021000000080001100410000100001000010040200980220400000008806200200000100000000000000000000008000000400042000000050000040000112080808800002044000040004042008800480002000000000000002020020000042002400000820000080040000000010200010020010100101212050000008000000008000001010200c80000112010000438040020400000000202400000000002002a0210402000622010000000001700144000040000000002204000000c000410105024010000808000000002004002000000261000000822200200800881000000012500400400000000000000040010000800000","miner":"0x000095e79eac4d76aab57cb2c1f091d553b36ca0","mixHash":"0x5b53dc49cbab268ef9950b1d81b5e36a1b2f1b97aee1b7ff6e4db0e06c29a8b0","nonce":"0x0000000000000000","number":"0x84161e","parentHash":"0x72d92c1498e05952988d4e79a695928a6bcbd37239f8a1734051263b4d3504b8","receiptsRoot":"0xaff90ae18dcc35924a4bddb68d403b8b7812c10c3ea2a114f34105c87d75bcdb","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2a51","stateRoot":"0xc56738518b2c7854a640ae25996d2211c9ef0dd2e4dd9e59e9d9cacef39622da","timestamp":"0x64110a5c","totalDifficulty":"0xa4a470","transactions":[{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x1b7aa44088a0ea95bdc65fef6e5071e946bf7d8f","gas":"0x5208","gasPrice":"0x4159f01735","hash":"0x1e8f148a9aea7d8d16ea6e9446723b8f262e8bcd89c7c961d52046ebd43b4598","input":"0x","nonce":"0x279ad","to":"0xa21765a03dd41e2783696d314f235f4d520f6cac","transactionIndex":"0x0","value":"0x3782dace9d90000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xf9eca8b74ccaec5f4a83e981baeb8602f38d0271179c592b4a18f3866316a367","s":"0x350a9d26718d1fa9dc4f268f9c0e18fb96dbc037816ca8fc20f33f1a76f9f501"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4d9a852e6aecd3a6e87fece2ca109780e45e6f2d","gas":"0x160ab","gasPrice":"0xd4babc57","maxFeePerGas":"0x11407d03e","maxPriorityFeePerGas":"0x9502f900","hash":"0xab5c870f4c367012bd763172afbfbe68fbf35336a66ae41aff3f2c9dbf4ea3f8","input":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200c479c99d58d7fbee5ee3aef5001431073a3d465bdfa46cf747a7c0b9289607864736f6c634300080d0033","nonce":"0xafd","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x48f6acf4ac4371eb96ffca8cdef5b7704ea8c68a631d1c02927036d4ce92567e","s":"0x1f12261ddde63fd3da2ed9ea1bcbb4b0f25af898248c805a9d4b0a6e42caf9c8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xce297b30e56bf2f6142c4048fbae1cb8a756fefd","gas":"0x557300","gasPrice":"0xd4babc57","maxFeePerGas":"0xfabdd183","maxPriorityFeePerGas":"0x9502f900","hash":"0xa81fd92b2d0f0bbd3cc355f869cca3243c98c5e2641db9ecf3eeabb3b13bff6a","input":"0x7bbaf1ea0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000","nonce":"0xad92","to":"0x4c0ce02c1219ce5d2afffba97e484272a4637b49","transactionIndex":"0x2","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xd11b842a5f7b0e020470e764b443fafc4044327bca8dbb37131425359abace2","s":"0x1009867573946fb0a4a35339a6eaaece4d0a168b2346539076e6319e9a466b1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x47a916d0b694c95bc0c09953c1a6e22c8867be32","gas":"0x5208","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xa92c7b720c08c83f1a0ed7e4c163200e30a3a8c03fcc5a51e685ea20cd0cb577","input":"0x","nonce":"0x2","to":"0xf955dfe99bbfd06a8be208274cd654ecfb66a45e","transactionIndex":"0x3","value":"0x11c37937e08000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeecd431225215c3ddc2e13cf16fa29f9a2ab1afbaa02988f3ceac27416edf0f5","s":"0x6494062330a9d509f7c778cb45cbcc9932e5f9b4ec94a1ec315f579f8d973b7b","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x672d214fe4db218defae698085a3ccefc773dfa9","gas":"0xf4f6","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0x6921b429ad2ec1e97d3457049ad2e893b5a0349beba47ca1c74a9540af75347a","input":"0xa1ddc546000000000000000000000000000000000000000000000000000000000000118f","nonce":"0x8e","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x4","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4732ad21401b509bebb947a8566127fba1e245eb5a262ddc522d6867ab80567e","s":"0x2153013617fefdb06db0a7316d8883056441d33c2abf5ed6291fa0e3cc5c3a2f","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x0b12f7f996579fe7d9302d2574910121c214ee15","gas":"0x56a8","gasPrice":"0x991ff257","maxFeePerGas":"0xb2fea055","maxPriorityFeePerGas":"0x59682f00","hash":"0xf776b2da0b835dde05d0d8b76fd19385d61e7055036cf637f804b36dc94f2384","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f40000000000000000000000000b12f7f996579fe7d9302d2574910121c214ee150000000000000000000000000000000000000000000000000000000000000000","nonce":"0xe","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x5","value":"0x2386f26fc10000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc4505d4c46ef9a0103178e5ef4fbc857114ae5c4686b68b74d07c3ee3a86e575","s":"0x74db34fd675bea7d2ee74f14fd8709cb88c7d22c2267d12f2c671b5ebc180bd5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd36aac0c9676e984d72823fb662ce94d3ab5e551","gas":"0xff212","gasPrice":"0x991ff257","maxFeePerGas":"0xd86d063e","maxPriorityFeePerGas":"0x59682f00","hash":"0x9a08d899cd14ebb930ed59fa774afdb88a22615b3a931e930931ea54d26dc0bc","input":"0x49160658babdf216946a22b96c966ceeba750f14807726306ebeed500a2621a7481df010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000084d6f6f6e6265616d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078434133633746363939643335333137316438434643364236334431433764333841333233373238300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b616f73c8d00641109f0000054f967b8a135e44e233da070ea88c5e4a53bacac0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c6a3a17399d88e5dfd2de4fa41dcccade6a2d2170000000000000000000000008676147503f761e44b85df01811edd52be01b56c000000000000000000000000000000000000000000000000d02ab486cedc00000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x7121","to":"0x2d276bd64fe8643a1d76b2e9530c753423e972c1","transactionIndex":"0x6","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xce452361d331baf2ac86947a1b3b454b3e842923e1f39139b33a572845dd5d7c","s":"0x388126881782af5a146ce8409f1e3a2c9a4cadcfe9a2c1d27258af6e4eb5cec1","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x326ff","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0x0fe0d97e25d5eb11a33a3e8278584c3780941fc2675bdf8fc547cee3d1fd3b17","input":"0xa4110dbe190e65a7fe0ad5acd305c6446a02cb39de30f382000fe67927434063bf4c4b2ca86b3ee6d039dc7a0268f9e1c39266c3f12a752a7eb72f0895dedf62291fd292","nonce":"0x12e","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x46819bb540fa459a5a0cbf041a0286507d597fc8958a6af8b9ce193f00005238","s":"0x31495c58bf4b74925f870c59635912681bee947b1cb4b08cc19f22421b1a10ab","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xb83a48ee322989a0a4f838cb207abc28ec021b73","gas":"0x3270b","gasPrice":"0x991ff257","maxFeePerGas":"0x5c3362b9c","maxPriorityFeePerGas":"0x59682f00","hash":"0xef47a60f57f177a683c723c658137efab66d311e1c5abbc4d74f653535144d03","input":"0xa4110dbe18eba3e815ec7fcb03a8eea0487209c3253024d1dc4f36f775a43fdd3e409b74c0a5c88e54f39b88db6f185a41431b204120d3e66c9b08b86f5e8382623327e5","nonce":"0x12f","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x8","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4d7e11fe3914763a2735493a62b71ae0028e75a750a8b06407996cf478e273c8","s":"0x60c18fdf948721f96fdc2efbf694910122e82191c7a40a5caab247c06ab7f3cf","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x7712a1f96b3f37c3dd88a22d4f7a7977b937fe62","gas":"0x1ff06","gasPrice":"0x991ff257","maxFeePerGas":"0xcf662006","maxPriorityFeePerGas":"0x59682f00","hash":"0xe23a5b35faae5335adc5aca38c5d633b00438b798c2053104b8df48406c9b141","input":"0x3ff9751b0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000002e516d566e75374a51566f445271536748427a72615970374879373848774a744c4669366e5546436f775447647a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d5439716b3343525962464457704446596541763854384831676e6f6e67774b6868354a36384e4c6b4c6972360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041c9f31b989aaa745aecc563139f89c8ab3ab492e725d1e0305b7d602fcbf9293c463f0d2e4f5fb0c9efb54eb2cde9af10ebc9c3676f2334007291ffa8efb40adb1c00000000000000000000000000000000000000000000000000000000000000","nonce":"0x16","to":"0xc3b87ea584cb9cb5a4523e2bed16a34bf7746317","transactionIndex":"0x9","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcc693a9544394653e1f393f02635e2c1f78b5e6c26c4d00a867bcf4adc2bc09e","s":"0x23f4b71b773c19f77cf251b2aeea03f2696bddd847d1f6d75acd2fbea6a543e4","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0x1b2e020","gasPrice":"0x8f0d3617","maxFeePerGas":"0x1cb3abd5a","maxPriorityFeePerGas":"0x4f5572c0","hash":"0xd8cea4ba619b317bc05d58534af73beec6c2548b31b24d4dc61c9bbd29cfa17a","input":"0x","nonce":"0x4d","to":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8dae28608985d6ab47cbe122ee88972e38664cede30978f41944f347bad86e5c","s":"0x17c2898b39b7e3b874dc78e7df3fcff68f4d715385c632aad4bdf6e62505651c","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6999c36394dd5d3d3295af63a4736ad6bd279448","gas":"0x14d94","gasPrice":"0x7b528d57","maxFeePerGas":"0x7df743e0","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x79a4b9d90b02c768baaad305f266281213cc75062cbe99a13222cc0c4b509498","input":"0x6a7612020000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000a4ec6cb13f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003826d8d7371becafc0afedc3fe85b699b87f4357d55ec39ce83c510ed7d70ff514dce8236351f4627ccec6a7d9a67bc6fc2ec17ca76411113c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000006999c36394dd5d3d3295af63a4736ad6bd27944800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000","nonce":"0x13","to":"0xdce8236351f4627ccec6a7d9a67bc6fc2ec17ca7","transactionIndex":"0xb","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x669487011643510f7512ec15b07d74efb853ba4ad9fe9c7e9850ccf24e3d4c53","s":"0x2191f9ee81087e1df833e69d6129ec330ed4c99be2031060834e22c589fcf79b","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xf6e4d9c4","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x6790a3bbddbeb21fcb736a59b3775755051c3a6344d8390cf8ca27f2e8a814f0","input":"0x6871ee40","nonce":"0x4","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xc","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa7a58ab858e5dd87b9a74d550e5716ac40ddefd1c21d5baa51e542f4f941d73e","s":"0x1fd0cb1563df0368bd332717d7c8210187cd1ac2ff44f61f5242fc02eaa0c2fe","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x87ec7ace5442db252b5751ffddd38dcb04b088d36b6b0e526ff25607a4293c81","input":"0xcb40cbfd","nonce":"0x5","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xd","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x8e4bd40195bdfaa868af97dbf22e0b74295d95564a8381bc9bcfe1af3cde2cdb","s":"0x62057dc87c8b2b197d12c648233aab4134b7c2a2f65db89a49728564f3d0864d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x08ebc052e6353b4d8392113f0f2c5decd691ddcd","gas":"0x12c36","gasPrice":"0x7b528d57","maxFeePerGas":"0xe596c292","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x40cb487ecffda94f97ce7fc0f7163f2f024235df2c8291169edc80dac063e6d0","input":"0xcb40cbfd","nonce":"0x6","to":"0xb21b333c40354393f18de57f2d0a0fc21f270482","transactionIndex":"0xe","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x993c4386ffc2bd63a48dd31cf5f65aa355cba3c063b08778b328d748937098e5","s":"0x203b1faf595628dd78e760bcc1740065625abb6cf00b1b17224e10fa6b424e43","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xafc7682751d3654f34958e3fb660971bf5918367","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0xefb40664","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xb76bb3d88c9b30d927c45ccfcf8d5b0054411ac8501ad588822a7d04690cccf6","input":"0x40c10f19000000000000000000000000afc7682751d3654f34958e3fb660971bf59183670000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x20","to":"0x84ced17d95f3ec7230baf4a369f1e624ae60090d","transactionIndex":"0xf","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x78e9d29c606f6a61a1428ed7326df05210d802c3061f3b469847cc461eb48025","s":"0x517afe5a21175f186233ae7a6c090cd33e028a77e5854e98eb2fa4c9284430e7","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0x16ba45bce","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x798ebe823209869347c08bd81e04fbf60e9bdfe44b1cc923215182d0cf3d4edb","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000032","nonce":"0x4e","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x10","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xbe2aa95f4c32188c9ecbae97286ab983f7cc5a7017d46c404f8eb80b55e2dc13","s":"0x55d8968f509f51633f49260178941fd5a3db999e1995206348d7a3f05152b3d5","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x12bbafcfa06423d87bed591a64c1a1f34791e90a","gas":"0xcafe","gasPrice":"0x7b528d57","maxFeePerGas":"0xc6132c0c","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xbe68a7e02725f799a65ebb069ccc83a014ac7c40e4119bf7c220a2f6ddfee295","input":"0x40c10f1900000000000000000000000012bbafcfa06423d87bed591a64c1a1f34791e90a0000000000000000000000000000000000000000000000000000000000000064","nonce":"0x4f","to":"0xd25d682189afa7ed0c2811195b3f3d07616927bc","transactionIndex":"0x11","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1750ed45d0d2d048a61dcc3ff3e7ad0cbd395b77698c4f2eeb6baaea4c966d96","s":"0xe646e3a87b6dc50439468bcfd24cbf12a6f95b2762f1527c97a7d1b7f03530e","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xd0c0338baac9ce09c1d1caab88b4360507061e37","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1918167aa","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xc90c3a72efe81331727fcce4b5bd4906066da314ca9a0b44023a6b09ea7e8114","input":"0x4e71d92d","nonce":"0xe7","to":"0x0137d796936e199b917b93118eb4e002508a48bd","transactionIndex":"0x12","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x22222ce8fe753082c8e5dc7478fa7b87db9c8d0fb070ebc88ab015db13fd6bb","s":"0x6dceadecf6f6a3ddc433a547dba6d5fcdfb7d006ce09eeae1c06c1828ef9fff9","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1a4019792","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x619a6cbd43cde074d314c19623bd66d9fb1e13c158d7138775236f798dc1245e","input":"0x1da1db5e00000000000000000000000000000000000000000000000000001b5ec4ff740d","nonce":"0x10","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x733c496e8c84f78d113bc8b5ad6d04a133bb10bbcecf0db93d97eeedfa3d984a","s":"0x6627c16aa7dea27db44c0f0641c30ffd544b9b9b1c299dc60611e1e01c714ee8","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x8bd834cc1dd17d1a2f7eb6140c3dd5ab51d0f338","gas":"0x11df0","gasPrice":"0x7b528d57","maxFeePerGas":"0x1d3fbccb8","maxPriorityFeePerGas":"0x3b9aca00","hash":"0xca5a56cd77b9e5b0e79020cc6346edf205bc11e901984d805125f28c2e6686e6","input":"0xd7c01032000000000000000000000000356f24c0f3187a6dcb949e4a60aa0a74a8a0327e0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd0000000000000000000000000f8bacfae87aee49a2eec86df0c6b958ec3fd4fd","nonce":"0x11","to":"0xbad0009f7a8e796e3f975dc1d6ab3e3c237b857c","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x4aa872c1a7da70126917604193717575b91407f82449bca956d4089b90cd902","s":"0x4b5f788c68024f8958f66e8c768a8e0f65ef297c4ffd420a715258b0a55cb0a0","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x1b2e020","gasPrice":"0x7b528d57","maxFeePerGas":"0x1e706c8d2","maxPriorityFeePerGas":"0x3b9aca00","hash":"0x999c9ddeed67c6ef6fbf02a6e977a6c1b68e18d24814e51643c7157b87a43e0a","input":"0xa8b78ed0","nonce":"0x3","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf1ca074104ee0b6a67223afd797654b8f21060453f7662dd7be79de938c396da","s":"0x4c9a4e56f0ad21e2dd8d1116c7a3e41ea2c6126853772f7897bd959e81e2e28a","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x9bedd66b05712a1add7d1fec899b8641b3ecc863","gas":"0x2dc6c0","gasPrice":"0xd4babc57","maxFeePerGas":"0x21c13e710","maxPriorityFeePerGas":"0x9502f900","hash":"0x47c8f5d0b3778e4c34eba7fcc356fa04a5afd954ccf484728e72c002764dd3c4","input":"0xf688bcfb0000000000000000000000000000000000000000000000000000000005f5e100","nonce":"0x4","to":"0xf6c2afb18b85175e5ffb28f20f007c047ce28592","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x970982425d18b9949141bbabb5c5230fa168626ce210a97f3856d64700fc0eeb","s":"0x6fa6d0aea6ae48783d80c1e51cda47e11c28b90a5497579b93d7f242d786f67e","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x4b596cebd02c35aa99878eb9ecb24d6f5ca5f865","gas":"0x5208","gasPrice":"0x68c88f79","maxFeePerGas":"0x68c88f79","maxPriorityFeePerGas":"0x68c88f79","hash":"0x396797ae0ebcdb72ff1f96fd08b6128f78acc7417353f142f1a5facd425a33e6","input":"0x","nonce":"0x1","to":"0x375980b8e1a417620ba9b18e5a9e0b17dccbac9d","transactionIndex":"0x17","value":"0x1c9a406c58878","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xcb2a7b106097b2f2a61d3a048054a5175c386b1dcdd5b6fcd7849dcac7c32a66","s":"0x10aef76e98276c47470f04a599b81c260ace9d2f6adc95755c6d22d859e805a2","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0x1b2e020","gasPrice":"0x61010bda","maxFeePerGas":"0x61010bda","maxPriorityFeePerGas":"0x61010bda","hash":"0x454aa43d6546a6f62246826c16b7a49c6c704238c18802ef0d659922f23a573c","input":"0xe99a3f8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee40000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e06defd69964a6ce467b87c64627a7a2be4be139b504757c625eb6114ec166557d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001f63c28250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf17500000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d5458000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000413e24433da3efc4c3cc305339a7b77a1b31abb4e4d4967e97e42aed1dd0bf98936f43035f40bc80f6f6e3a9cfb43524a1171ee7f21e9ac2fa586d33a31f10619d1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace5786000000000000000000000000000000000000000000000000000000000000012000000000000000000000000058ce7eb44ae575fb3b3974861c1138dad3c5aee400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000641a269023d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf1750000000000000000000000000000000000000000000000000000000000000ba200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002b05699353b600008ae85d840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175ffffffff09616c6c64617461","nonce":"0x82","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xc7ac308b1ae238cb2aa4b030ca79baffb7b498e1b10df0c3354b3cc19cfabac9","s":"0x2358b1093b9aab5fae0cf751766b0bb2e3d8cd2b18ca627e1e12520990a8ed6d","yParity":"0x0"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6ece61d29b90642941c41240da924690da145696","gas":"0x4399c","gasPrice":"0x506794e0","hash":"0x317ecb5bd19caa42a69f836d41556ebb0e0e00e1c6cd2dee230e6e6192612527","input":"0x46f83b5000000000000000000000000000000000000000000000000000000000000000654666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b000000000000000000000000000000000000000000000000000000000000000f4666803decc59e7d0a5d3efa3c3653c05645ef4342738445e20a3b43e0b4aa8b","nonce":"0x2cc4","to":"0xa6bf2be6c60175601bf88217c75dd4b14abb5fbb","transactionIndex":"0x19","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x37aeab0db6d550e6cba2c04c9cb10a2af0fec0b11f6e04b85e1ea0b8b9defeae","s":"0x4f32f4ef74872e1385c25e69bf21ee049545a4d423e939eaff29677450efe9eb"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xc4a5c059840a146b81c77bf79f1398f2b3d28ca7","gas":"0x432ec","gasPrice":"0x45db0a51","hash":"0xc879285db5ef0a6bce98021584d16f134c1dc0aed8cc988802c4f72ba6877ff6","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1a7","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1a","value":"0x470efc4514e000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x237e3a541c5ab490843cdc20d0fcb7416bff8da471f6a11ae1b32d2bab119141","s":"0x3c8417d7a60bd5b0bcae4975dbb4aaee54a4b4d588226481be400843bfe2b64e"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0x6f4aa3bc9732372daa288beb9b2516374ace5786","gas":"0xffff","gasPrice":"0x44e9acbc","maxFeePerGas":"0x44e9acbc","maxPriorityFeePerGas":"0x44e9acbc","hash":"0xecaa2d6f597608307e5084854854ba6dc1e69395e2abea14f2c6a2fa1d6faf9a","input":"0xe2864fe300000000000000000000000000000000000000000000000000000000000000200000000000000000000000006f4aa3bc9732372daa288beb9b2516374ace57860000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002004a8312e37fcecd450e6684009a2b54bc64f66afbe5217c7b2f63b03cd9980a9e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064893e8223d235ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000173ad21460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000def65f8e2f62bde60cd86ad3b4ad7fa6741cf175000000000000000000000000000000000000000000000000000000000000085000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a7640000aaaebeba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006e512435020ac228a15543236b1f46656f98136300000000000000000000000000000000000000000000000000000000000000fa000000000000000000000000d6ffd79b52a587a0a9941a61f4e6cb0d386d54580000000000000000000000000000000000000000000000000000000000000000","nonce":"0x83","to":"0x02afbd43cad367fcb71305a2dfb9a3928218f0c1","transactionIndex":"0x1b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa18772e4b9e1493ebfd5ae6219cc9ca060b71e83788fb614ab02b03fb36eaf1b","s":"0x482c7e50fde29bb4130fd6e723176e0e9913430ebb9260667d7fb55f5408d9c5","yParity":"0x1"},{"blockHash":"0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452","blockNumber":"0x84161e","from":"0xdb33365a8730de2f7574ff1189fb9d337bf4c36d","gas":"0x61a80","gasPrice":"0x433653c8","maxFeePerGas":"0x828367af","maxPriorityFeePerGas":"0x37e9071","hash":"0x4dd69b69a568ff30ae439e2ded72fbd7f2e7aaa345836703663f155c749c5eed","input":"0x7f34c0ddc6e984f46ab7c13b7a53643096e79c39103dc74550204d5bd1b5206ef5a2f49689071bb6a332212df26aa57cd4d1e3c0894187a9fc5e5d686cbedba5b187470f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000e8c44c30e8e52c38ac7bd232e7b7f0c7463a535100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002e516d5044645856613738437a6b7856325a364e52777a67685a785872736e75397261616a695a7555423569465a62000000000000000000000000000000000000","nonce":"0x2b57","to":"0xb8ad54644e2371cbb7940b9fa0936f399ba7495f","transactionIndex":"0x1c","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa1fb0e5662b54ceb3dc1623ebfb200668433cb27252d553669bcd136387394f3","s":"0x27c2f8e19f69a52a0960f05d8b21f11c313dd3e86a7139b5783a18353c407415","yParity":"0x0"}],"transactionsRoot":"0x4a87d0cf5990b1c5bac631583e5965c2ba943858bebb2e07f74d0b697f73821a","uncles":[],"withdrawals":[{"index":"0x1170","validatorIndex":"0x38c2c","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x66edfd65"},{"index":"0x1171","validatorIndex":"0x38c2d","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6cd228e4"},{"index":"0x1172","validatorIndex":"0x38c2e","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x77f3431b"},{"index":"0x1173","validatorIndex":"0x38c2f","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6b61f268"},{"index":"0x1174","validatorIndex":"0x38c30","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6e10bb21"},{"index":"0x1175","validatorIndex":"0x38c31","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6eb115a5"},{"index":"0x1176","validatorIndex":"0x38c32","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7caead1d"},{"index":"0x1177","validatorIndex":"0x38c33","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x772c0ddf"},{"index":"0x1178","validatorIndex":"0x38c34","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x75930a95"},{"index":"0x1179","validatorIndex":"0x38c35","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76a4db09"},{"index":"0x117a","validatorIndex":"0x38c36","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x7e692b27"},{"index":"0x117b","validatorIndex":"0x38c37","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x72038ae6"},{"index":"0x117c","validatorIndex":"0x38c38","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6ccce352"},{"index":"0x117d","validatorIndex":"0x38c39","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x79ef6898"},{"index":"0x117e","validatorIndex":"0x38c3a","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x6d58977d"},{"index":"0x117f","validatorIndex":"0x38c3b","address":"0x8f0844fd51e31ff6bf5babe21dccf7328e19fd9f","amount":"0x76f7d208"}],"withdrawalsRoot":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"} diff --git a/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals_metadata.json b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals_metadata.json index 16d4bd5bcc0e..8dc2a01f6fae 100644 --- a/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals_metadata.json +++ b/op-service/sources/testdata/data/blocks/post-shanghai-bad-withdrawals_metadata.json @@ -1 +1 @@ -{"name":"post-shanghai-bad-withdrawals","fail":true} +{"name":"post-shanghai-bad-withdrawals","fail":true,"reason": "failed to verify withdrawals list"} diff --git a/op-service/sources/testdata/data/blocks/pre-shanghai-bad-receipts_data.json b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-receipts-hash_data.json similarity index 100% rename from op-service/sources/testdata/data/blocks/pre-shanghai-bad-receipts_data.json rename to op-service/sources/testdata/data/blocks/pre-shanghai-bad-receipts-hash_data.json diff --git a/op-service/sources/testdata/data/blocks/pre-shanghai-bad-receipts-hash_metadata.json b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-receipts-hash_metadata.json new file mode 100644 index 000000000000..3e6f348b85f6 --- /dev/null +++ b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-receipts-hash_metadata.json @@ -0,0 +1 @@ +{"name":"pre-shanghai-bad-receipts-hash","fail":true, "reason":"failed to verify block hash"} diff --git a/op-service/sources/testdata/data/blocks/pre-shanghai-bad-receipts_metadata.json b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-receipts_metadata.json deleted file mode 100644 index 7deed556e8b2..000000000000 --- a/op-service/sources/testdata/data/blocks/pre-shanghai-bad-receipts_metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"pre-shanghai-bad-receipts","fail":true} diff --git a/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions-hash_data.json b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions-hash_data.json new file mode 100644 index 000000000000..e1821ce46dc8 --- /dev/null +++ b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions-hash_data.json @@ -0,0 +1 @@ +{"baseFeePerGas":"0x7ccf990f8","difficulty":"0x0","extraData":"0xd883010b02846765746888676f312e32302e31856c696e7578","gasLimit":"0x1c9c380","gasUsed":"0xa79638","hash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","logsBloom":"0xb034000008010014411408c080a0018440087220211154100005a1388807241142a2504080034a00111212a47f05008520200000280202a12800538cc06488486a0141989c7800c0c848011f02249661800e08449145b040a252d18082c009000641004052c80102000804ac10901c24032000980010438a01e50a90a0d8008c138c21204040000b20425000833041028000148124c2012d0aa8d1d0548301808228002015184090000224021040d68220100210220480420308455c382a40020130dc42502986080600000115034c0401c81828490410308005610048026b822e10b4228071ba00bdd20140621b2000c02012300808084181ac308200000011","miner":"0x0000000000000000000000000000000000000000","mixHash":"0x31f0c0305fc07a93b1a33da339c79aadbe8d9811c78d2b514cd18d64e1328f25","nonce":"0x0000000000000000","number":"0x840249","parentHash":"0x2303b55af4add799b19275a491b150c1a03075395f87a7856a4e3327595ed7df","receiptsRoot":"0x99da71b17ae1929db912c3315ebe349d37f2bb600454616fdde0ee90d6dbc59e","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0xea6d","stateRoot":"0xd12bf4cf3941cf48be329a939b13d3403d326841c69cdcc9a9c13ab2f227e904","timestamp":"0x640fdeb0","totalDifficulty":"0xa4a470","transactions":[{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x030b1cddf635e9e71ad70b8668e235e8ec3c67c4","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0x2ca7289ab3738d17e0f5093bd96c97c06c9a2ea4c22fc84a6a7fbfda93ce55ee","input":"0x","nonce":"0x456d","to":"0x89416096a0a1acad3436a357478c5c548e4d382b","transactionIndex":"0x1","value":"0x16345785d8a0000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x5aa6ad410ea42dbff3781de67b4815a376cd459206595fa6655c966a7709e5cb","s":"0x82f620f8dbc356dc38ef346d1e152656a1d318becbcc41884f61e85972355c0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9c67435ce8a33ad23f377ddf08260ffc56417f21","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0xb0085de1476530de3efc6928c4683e7c40f8fac18875f74cbcc47df159de17d9","input":"0x","nonce":"0x446c","to":"0x471f3a988a77472e971112e7ff2ce65996b6c8cd","transactionIndex":"0x2","value":"0x2c68af0bb140000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x75425f21a6e66e6feaee79455c897656c4a94b6189c4c033facab1b67812fc3f","s":"0x7014f4b9f760165c7757f9d6dccea349b3d00b0a9c2f845af8010140842f826"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x168f6dec26cbbb3749654e0e3cc4fc29314fdf6c","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0xe01c8631c86ded63af95b8dbc0c8aac5d31254c14d6ecb4cc51d98259d838e52","input":"0x","nonce":"0x403c","to":"0xf2119a49a3ae35453c1c2704da248d08977084f1","transactionIndex":"0x3","value":"0x16345785d8a0000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x56bba57ee69c09dbbd5167d0fee07d5803130fea7c278f4d8b7bc54b34be8ff9","s":"0x7eea69c0de47b6b808ea1bdd9ecf5d25f4f2743e867b1f838db59c456026d7e6"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xc9af69904b4ba7f0fb69ab1a8719bd8950265e73","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0x69414a126a6f07ab5e31ad2f9069fb986b7c490e096898473873e41ece6af783","input":"0x","nonce":"0x44c20","to":"0x6adc3f5394e00cd067d1fad5a33756791e303c25","transactionIndex":"0x4","value":"0x16345785d8a0000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xdc9a52b87755cd07143bf032d57258d0d6c36500b38a574a9a5addc1293343da","s":"0x581e6fd051d0c72d64303c1f90edecfef46580f84f24dba930cde910923f7c21"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x92964e63cd52450e6e09a266e0c226e524754563","gas":"0x2625a0","gasPrice":"0xf5686c7be","hash":"0xa2fef1133ee726533c7f190f246fede123e3706a03933c1febc92618f90d2804","input":"0xa9059cbb00000000000000000000000011f7db5a824eaa5737c935ad09a925dd707f092b0000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x2636","to":"0xbc071c64ed8f536011c78e847755680740d6b73c","transactionIndex":"0x5","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x422c5026584cd8fb8a1fe66e6edc7a020bc513cc3114083fb35f9846cd9a9792","s":"0x7fcd4e48ac5b53d881531a5651e587188157ed88d85c51533f7c6eda94c67ff7"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdec1bc71bf91431d60ef2742f412dcd1c5a204b8","gas":"0x7a120","gasPrice":"0xb80e515ce","hash":"0x6585ec5c4c2bbf1f683f90f58e18f3b38d875e94457fe4cbb7bc5bf6581f83af","input":"0x67a5cd060000000000000000000000006343e96c99e2725e845ba04f90e03d853cc9bb2d","nonce":"0x6a5a4","to":"0xf5de760f2e916647fd766b4ad9e85ff943ce3a2b","transactionIndex":"0x6","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0xcb7b32949ac0dedd3151d06d85ec4e99483c8ea706f12a009d97b055975241eb","s":"0x69f0009bce12e24408f9a3d5ad5a8578e2b23efb09002f7b86b3425cf8748889"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdb954dd5d224004b26cfbb089312e0542e5d1c31","gas":"0xd5ef","gasPrice":"0x9fc748df1","maxFeePerGas":"0x116482c049","maxPriorityFeePerGas":"0x22f7afcf9","hash":"0x1db276b864fbf01dcf8cededf8d597553ecb0eb9438edfaf2f5bd0cc93297c66","input":"0xa3e35f36000000000000000000000000f18f2320e4779f21d6882d83f9133e582dfaa9b6","nonce":"0x570","to":"0x11672c0bbff498c72bc2200f42461c0414855042","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf23a1fb0d17cdbc2831a2cb0b779795e12533e34425a3abbc4b7e7bde262b92d","s":"0xd4a2c8189378696065b7fc5d13e9cf6595d96047a31a4fcb812c2e677d22a26","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xe84d601e5d945031129a83e5602be0cc7f182cf3","gas":"0x249f0","gasPrice":"0x9502f9000","hash":"0xcbe7ed31654af4e191ca53445b82de040ae2cd92459a3f951bdcce423d780f08","input":"0xa9059cbb000000000000000000000000355f96e3261cc8237d2d36fd81cc9b9cdcbfc5ea0000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x4f1f0","to":"0x499d11e0b6eac7c0593d8fb292dcbbf815fb29ae","transactionIndex":"0x8","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xadf7dce5f34d482bb19ff0c85f43be7008cb838043f9abb5fc08421245ac4228","s":"0x5d2c0f0b9d2e68bb8da6084e4971d57bd76bf0cd9d893c9c985962812d2df026"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xea0193f88a0d9c36e83e6fb6d382212b6373faba","gas":"0x43238","gasPrice":"0x933ea77d8","hash":"0x808ba5211f03cc78a732ff0f9383c6355e63c83ae8c6035ced2ba6f7c331dc63","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x9","value":"0x470e9f23394000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x9536f87e8c3433ea23ef7211c0c32689551906dfdf31bcc73b89fcf18fe86a92","s":"0x3e94bfe3b4ba32a6ce71ee6e0ff9f26dfc2b0d61b5c0fe049469e3c4b88ac227"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1f9ab300b380313e6a2208e44c01a0602538385d","gas":"0x32b38","gasPrice":"0x87fc9eef8","maxFeePerGas":"0x2e90edd000","maxPriorityFeePerGas":"0xb2d05e00","hash":"0xdd66f1f26672849ef54c420210f479c9f0c46924d8e9f7b210981ffe8d3fac82","input":"0x32db5470000000000000000000000000000000000000000000000000000000000084021000000000000000000000000000000000000000000000085b0af981975a40fc5a00000000000000000000000000000000000000000000053ae1f470262f3b01c4000000000000000000000000000000000000000000000813bca9f8389ffd193f","nonce":"0x5699","to":"0x28cea7b0f3916c1dba667d3d58ec4836ad843c49","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xbe8eddd463a3518a4c94b5922c0f2fb26a32c8afcd819f7deaf4f0416757ad13","s":"0x3e234182acd5261dfba3cf4f125d1a8377fc707b3b1900b565d1a6b8987b398c","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1d990a2cf61b46f37582dd31a7b242e989e1a1ee","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x254abb2f8cdcffe9ef62ab924312a1e4142578db87e4f7c199fd35991e92f014","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xb","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xbfe9b99fd2e9bbd2d65bb4cc17da88130d8f6b569a26afa642ed1cc8efd2e2ef","s":"0x7003dd3962eec2369bc5abe5e3d5b73a9086a3219643b1741f3a9832369448fa"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1124bbb196fd7b61947f6f03b7d7cebde8340b6f","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0xa7b7c654e7073b8043b680b7ffc95d3f2099abaa0b0578d6f954a2a7c99404e1","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xc","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xe8dae9efa8fa73a3aebdaa75ba12acf56712b1f99fc128ab802a7610d014547b","s":"0x2ef347ea90a0db21b035637342bfc916c9962d3ec610a4e99cfaf555a2606fe2"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdedf52a88fe47f6a11d629badd0096d201aef86a","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x7ccdfa698c8acf47ab9316ed078eb40819ff575bcf612c6f59f29e7726df3f96","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xd","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0xfc4e092094abc7fed9cf11eea8ad6ec3a760d13b9c603b5570c2143e48090f2f","s":"0x31a0a6016ab51ed6375891bf532d9031bf91c1d0e01df63cf7e46076aeee83a3"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xe1db1fd154b344ce7dfcb53a65279559b298f0df","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0xa0b035ef315824a6f6a6565fa8de27042ade3af9cf0583a36dea83d6e01bf2a8","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xe","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x79c316492bfa36fa4de2dca02ffac77f6c1772714e153aad8c947ce848d4106f","s":"0x4fe3e083943ca8f974cb0752a2ffb70e4d6c8b615e16ece7e19b2c464be66929"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xd4c3777e1821f6fb532957104e1317a9d3f881ec","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x1ebad7f3e8cb3543d4963686a94d99f61839f666831eab9c9c1b4711de11d3d9","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xf","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x5c1f544ca92b28a014129a9d04f8e895dc8a6987ddc1717c26b0619bb9bac420","s":"0x47574643bd92a0f129f9c5ce3caebe7943cfd828d67fb0e5bdc1eb2ca202822a"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x127418955b15f5ff2fa232431a798b53fd006c82","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x501750278e91d8b5be1ccf60e793d4bbcd9b3bb3ccc518d3634a71caeac65f48","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x10","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0xcfc9894bf716ba707521f0969082afb688b7d47cc21f1423b239c40867128f47","s":"0x5d9b9c66d8437d0a37768fb9c3241ef64b7e795d0d908196e1f707215ac1f56"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xc2ac1bdcb3dd77864b99eb2cafef2ed36c1487c3","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0xd80ff8af29ae163d5811ba511e60b3a87a279f677bb3872a0f1aa6d0a226e880","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x11","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x8bd7220d176d18cfbc824063448cf864c494fcf0958dec82126f26d3fc6c0b6e","s":"0x2f4de3d2fc3be6d2812ee10aee16a995af5affcfec27f9953ae609886d2b563e"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x11a5ad000f8494233df5bd2f2573fe20bad744ab","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x096acab3b3fe47b149d375782d1eb00b9fef7904076d60c54b3c197b04e6bf82","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x12","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x43726c3165958e94d80cb6992121f55df2904a1de4356e0a6ff3d8bfd03c0928","s":"0x6244361e31daccbb5c7e9f3f7d01004080d2efa314d614fdc2aad4c1b7d71613"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x90f8b290ec2929cce086826e971cad3857c6dbb5","gas":"0x50f46","gasPrice":"0x861fc89f8","maxFeePerGas":"0xe22924cba","maxPriorityFeePerGas":"0x9502f900","hash":"0xbe9d1738af74a22400591a9a808fb01a25ab41e2e56f202dd7251eb113e8ceeb","input":"0x6ab150710000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0xe4","to":"0x2e84c9894f628fd209f48b06d10b46c8cada4c10","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x412c7bfb0236a4317da40645ee4e60f19185e7d0cd2cc9bc88f7629de505b939","s":"0x4f6bd485d10fa134926ec3e3a83e212f3c5d903ba52da87f07794a2ba0a5c1eb","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x7915ec065b644568155c4772a286addad3864c1b","gas":"0xb71b00","gasPrice":"0x861fc89f8","maxFeePerGas":"0x1176592e000","maxPriorityFeePerGas":"0x9502f900","hash":"0x0834c720e55cccd97aaf4f8fb0cb66afb9881fb6a762c0f70473ec53f98a712e","input":"0xedce8b4d6a1fb55588eadfd3a0c3350435a31d31e7c236125eafcc2a892d50711d9a4939a4282888c956c070cd83400fd47ab83bd5287244053b8228711b07386dccacbd000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000092000888ad4975d4079d80bc6da5ded57746f889644719ec160efc2e4a96ad645df10b1683afcd7ce41ba6c06528761f821cbc6e806ef4b71c189603ec218b12a1f1478883498e67b97ae4babef6996acc582db1377d8755374602e00b8148025ac2d2f52e78d7484919cef14bf96e5b7a3f7f8cf09989551888f2c697052ce2bdb02a9296b20016c78683a9ca137037e57c8ff25198146f9d4cdb5a25ab9c95a03038f22f83c8604ca7c035ef756d2963c3657eea4ffb18ef967752d8cff15a16124a1d92a1cda613624c98e3078742803da1417b78bb264b7bb2197515cb4facc2ea395c6241664dbd953d0034900a86eb94897bf89aae775a1d73e6fd034785400000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000001d802f901d482e7041b846de27f7b846de27f8383026c28946aa397cab00a2a40025dbf839a83f16d5ec7c1eb841dcd6500b901a45ae401dc00000000000000000000000000000000000000000000000000000000640fdf5900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf0000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c000000000000000000000000964ff70695da981027c81020b1c58d833d49a64000000000000000000000000000000000000000000000000000000000000027100000000000000000000000009a1a41127726f74560a57990fb928120eed6f55e000000000000000000000000000000000000000000000000000000001dcd6500000000000000000000000000000002d4766adcf72ef2d996edfadc866be12c28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000001d802f901d482e7041c846a969541846a96954983026c28946aa397cab00a2a40025dbf839a83f16d5ec7c1eb841dcd6500b901a45ae401dc00000000000000000000000000000000000000000000000000000000640fdf5a00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf0000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c000000000000000000000000964ff70695da981027c81020b1c58d833d49a64000000000000000000000000000000000000000000000000000000000000027100000000000000000000000009a1a41127726f74560a57990fb928120eed6f55e000000000000000000000000000000000000000000000000000000001dcd6500000000000000000000000000000002d4766adcf72ef2d996edfadc866be12c28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000001db02f901d782e70480846a969541846a9695498302e100946aa397cab00a2a40025dbf839a83f16d5ec7c1eb870aa87bee538000b901a45ae401dc00000000000000000000000000000000000000000000000000000000640fdf8d00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf0000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c000000000000000000000000964ff70695da981027c81020b1c58d833d49a6400000000000000000000000000000000000000000000000000000000000000bb800000000000000000000000048f2c17f8885e135c8689626d5841d0b94013556000000000000000000000000000000000000000000000000000aa87bee5380000000000000000000000000017a8db2711fe83b10bbfabb6a8b86c3e26ca154ef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000003760f4e19e59be10b323fe1b42e42de2754c5da54ff316cef74ef09dbc0144bbf73e609a8d21a38f393bae9a3de6bebbf362608d907d941c8166f44d8ee2c6686b5dbbd6681f5467219d9bb530db013b7c067db659c03efe935caeb7bab36699d00000000000000000000000000000000000000000000000000000000000000032d2d7436bd45b5e81824945ff3dda846e270c81e72929841f4b14f56e02eef39477f9c162a2759c8d7c7e1feefdd064f6aefb4360d483f70671f36fc11ccc6db6c53f74e3019c12d859545ad75b51998b2238887dc0be3c78522c8356150526a0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x48f08","to":"0xe87d317eb8dcc9afe24d9f63d6c760e52bc18a40","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x54159a63b8ce19097cb8afeaffc84cfb5257f9709dcb0f0a258befa0b924b13","s":"0x17f5ef5aeceb6f082a8a0f8fa28e55d453c52e5f86d48dfb4d4f039aad7fa493","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x52db522edf50fc32b8fc0f77d51140031da11da3","gas":"0x201568","gasPrice":"0x861fc89f8","maxFeePerGas":"0xe22924cba","maxPriorityFeePerGas":"0x9502f900","hash":"0x51a0c33c9b37245b416575bdd2751c0d8a5d8bead49585ac427bfc873d4016af","input":"0x96d3f83c0000000000000000000000008cd194f4ced354a14960f76f49305feb8510f73f00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000641024ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b3fd330d479974ad52e18b8767d9f18cf9ff024fa749b1066a803b237570cb73e2868e821124c8128505d883124711ae7fdca0339f4f5cd5dadd8eb6956eb4af500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003","nonce":"0x2d9","to":"0x29c1442d7e3b6ed179ceb55fe996e1f4384880da","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xac84f403fa0347be3246ad695f8f6a780332357d49dfa67388fae3e051e5566c","s":"0xac2e148c1045af0ebdb334f20743af7d5499558af5eea43393159ce26a3fb1b","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3aea5f857b75a946d5f5b329bdcf4db46aec5d2c","gas":"0x50f46","gasPrice":"0x861fc89f8","maxFeePerGas":"0xe22924cba","maxPriorityFeePerGas":"0x9502f900","hash":"0x531c25d51ccda59aa9ea82e85c99be9dd4e285af9b8973cbab9ac4a38e26e55a","input":"0x6ab150710000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x1d","to":"0x6c23a4586cc791d2be6767532e12264992aef74a","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x81abc4fdf3b57fdf3a951fb293853fdd86aadce8f319576ac78c60caac186c43","s":"0x452742335bd1f63fd623d5e6cf91f6339361f863dba1a57fc3c1da8292e82c77","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x7915ec065b644568155c4772a286addad3864c1b","gas":"0xb71b00","gasPrice":"0x861fc89f8","maxFeePerGas":"0x1176592e000","maxPriorityFeePerGas":"0x9502f900","hash":"0x93ac6c08d21cb1b61ff59e5e2d6fa3f9ad54008b0a66c669199050bef219f6e3","input":"0xedce8b4da4282888c956c070cd83400fd47ab83bd5287244053b8228711b07386dccacbdb54cb66757631f9f22e2faf7da0eecc43474ab1a1af21aec22dcf949e2579241000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000009e011cb7bbabfab668b42b5582cec8d60f326ae14ad55f8d675060dd111dee6c88d0937435261929ba3a881bea107593a10e13c917a0ef5ae4e8bde40de2d1da4ba25ab3a239ba53eb4e260d23b98a7db944f644f40ab75992a89fad40e8d692ad62f8671604db415b54238c5522f6c4e6b25785bffa696d173659309b95a2fae8700d4b9c14382973ea34a3cd8b8428594908dcad2d5d7a01056b8e49a8c25087f12f9e9fec1f4b5fdc57509dba6839100e28016b2e3fec4928bbe11d3789b6cab280c17bebfa5a0e06aea22764e1a18d2d11316bdf81028e65755582586ebdf571cbd0ef59800ba3405539187dfc03eac1dba0cf590e2131a56ef7f260aa38f940000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000da02f8d782e704820101846a969541846a96954982dc1994a59477f7742ba7d51bb1e487a8540ab339d6801d87470de4df820000b8a4220b5b82000000000000000000000000f6213f16f3db9b50c684b2da37ff080895ae4a02000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000064376b6900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000003202f082e70411846de27f7b846de27f8382520894b6605a717a2447edac46b1cdafe35e3e91130c8d87038d7ea4c6800080c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f202f8ef82e7040d846de27f7b846de27f838303335f947191061d5d4c60f598214cc6913502184baddf1880b8c44d49e87d00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000160f9854c9f595e000000000000000000000000000000000000000000000000000000006417d4b8000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000b2f4f1df2e372ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027502f9027182e7048197846a969541846a96954983029eb1946aa397cab00a2a40025dbf839a83f16d5ec7c1eb80b902445ae401dc00000000000000000000000000000000000000000000000000000000640fdf0b000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000e404e45aaf000000000000000000000000964ff70695da981027c81020b1c58d833d49a6400000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c00000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000c097ce7bc90715b34b9f10000000000000000000000000000000000000000000000000000000000000000000000614000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c0000000000000000000000000000000000000000000000000000000000000614000000000000000000000000694b3f194e94c80b2d7a0e986e1440f204f0503f00000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000b902f8b682e70427846a969541846a969549830dbba094964ff70695da981027c81020b1c58d833d49a640872aa1efb94e0000b884437471fd0000000000000000000000004e44260732136caeffc7d076e17b2a3554b9ce2a000000000000000000000000000000000000000000000000002aa1efb94e00000000000000000000000000000000000000000000000000000000000064376b6600000000000000000000000000000000000000000000000000000000000dbba0c0000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000005b0efccaa7c845eddd4fb98211c7a58a37abdf06b264fade6cbff8a73ed22fccc602337b33a81e2cc4127be9d913fb3aec24194e14a61515a26429a00cfb86196aa3c2e6983f1a05dec045f0e63db7bd8619cd2a770ed1f7f470eb7c297e8e19d61277fb276ed8a63fd666b4a5ab02347065a3c16539f4ccccbed8fa39f2a7dc6606fc04c49f3d69463ba1c86c6ddcef8b9f06b9741dc2ebae9f5f1c0523b320b00000000000000000000000000000000000000000000000000000000000000050668b9ca5e5b17e2e79f9f5a7d9ea27e4e7f0302e878584fef3c2304c70c1ef53da311342341f89df488646b97a83994a3d07cc622ffde98598548c5326b7ccc0cf77d5d6fca6cf3f5b5b41a266fa2aaf697fd976dddc710fca834c96d2dfd725eec5980733db3c4e8f779f9fde3a598b2860d819419c961012825f0e160ee7b220989005b6ac5c48734db18158c2d85c8499bea1972c9f875c2d2aeafccb33700000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000f6213f16f3db9b50c684b2da37ff080895ae4a02000000000000000000000000f6213f16f3db9b50c684b2da37ff080895ae4a02000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000064376b6900000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000964ff70695da981027c81020b1c58d833d49a64000000000000000000000000073fee82ba7f6b98d27bcdc2befc1d3f6597fb02d000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064376b6600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000044a1c058fa0000000000000000000000004e44260732136caeffc7d076e17b2a3554b9ce2a00000000000000000000000000000000000000000000000000000000000dbba000000000000000000000000000000000000000000000000000000000","nonce":"0x48f09","to":"0xe87d317eb8dcc9afe24d9f63d6c760e52bc18a40","transactionIndex":"0x17","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xb5f185933d49064643686594f44a2584b1d57ba6a91f2a45d1a122892488f209","s":"0x7bb4af7ea30290b36fa7c266ee2387eff9e3ee0cd79b48aed27f5bfaaf34114c","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x4281ecf07378ee595c564a59048801330f3084ee","gas":"0xea60","gasPrice":"0x861fc89f8","maxFeePerGas":"0xfd18eeafe","maxPriorityFeePerGas":"0x9502f900","hash":"0x3792db6dd6285f409e4281951e9f78dad16c4a78072ff1c909dfadea5658d857","input":"0xa9059cbb0000000000000000000000000cc351a97c2fafde4cfa8a00c4fd79881cf13b53000000000000000000000000000000000000000000000001158e460913d00000","nonce":"0x77ffb2","to":"0x326c977e6efc84e512bb9c30f76e30c160ed06fb","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xef4173dd45060791cfb6dfc3cdc8a9b417ff6a4b3ba57759ea91fd875b01a522","s":"0x4de926b5099c7d60cc24add3c2eecd8e9550c1fe7f878430eccb887a2ff932ff","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x53e2c2479833ca17f946aeb16dcc49f5e2194701","gas":"0x431eb","gasPrice":"0x8442f24f8","maxFeePerGas":"0xd6aac8818","maxPriorityFeePerGas":"0x77359400","hash":"0xd2d51764c01e8c0a43fbe362704388df5bacf7e5e620c3864e242530ffb3e828","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x2","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x19","value":"0x470e9f23394000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x155352758fb04a6c0816c3dd9ca16bd6c66c37e2e19f2aa5d969225e3cb7f118","s":"0x6a4a1237db75dac4322fe12aee8b94edf7083ea661d6e93334c667d2d5c2c101","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x535619cf2bd2e84e567bda1a6164f195cb2bba21","gas":"0x55730","gasPrice":"0x83152e5b0","hash":"0x516b0227d9e64eb6e0de6862764d40f5376b5f12fec878436fea3479b4c36bb8","input":"0xa9059cbb00000000000000000000000030509945d2b329cc253a8bb2e2c54bdbb08b1070000000000000000000000000000000000000000000000010ce1d3d8cb3180000","nonce":"0x2176","to":"0x1173069b0e472a64ce2b6203fec8fb25a05b75c2","transactionIndex":"0x1a","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x289ee9948b80fc623b8c5d85c7df6fd25786fcc118163042b77a00560f53c3fb","s":"0x5b0a79e30d05370b27664b2a10cf964e110387bd62098561b6ea6a9dcc4634a"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x339d413ccefd986b1b3647a9cfa9cbbe70a30749","gas":"0x180ac","gasPrice":"0x83152e5af","hash":"0x81b0abc78b82840adb666775b182a9e292f663b64bcd35004c04436ed3c8281c","input":"0x711746e200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000002540be40100000000000000000000000000000000000000000000000000000006d3c514bd0000000000000000000000000000000000000000000000000000000000000010","nonce":"0x2689","to":"0x7cbd185f21bef4d87310d0171ad5f740bc240e26","transactionIndex":"0x1b","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x1f70a3d0933aab069a55fb2b16a259d21ea5fb3255e2032c5ff194a600ed2ab1","s":"0x3ac2142fc9f2009d68b08855eb5bc85e889e15d043c33bfc516f28ea38715485"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x339d413ccefd986b1b3647a9cfa9cbbe70a30749","gas":"0x180ac","gasPrice":"0x933ea77d8","hash":"0xd0287570d431d2baea96ecc81cb890e7f4f06ab5df02f9b4067768abca19acb5","input":"0x711746e200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000003a09994473bc00000000000000000000000000000000000000000000000000000005672af7e00000000000000000000000000000000000000000000000000000000000000010","nonce":"0x268a","to":"0x7cbd185f21bef4d87310d0171ad5f740bc240e26","transactionIndex":"0x1c","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x73a68e10ef9726d47ff314cd16d1846a0876d2b63a65014909140de7e45aa8b3","s":"0x580de27e4626139fbad4129a249c7ac2b22e1062659293e5fc3a244fd74907c"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xb5b9345e21f34b6cfa538f49e2b14ad4c3db3f7e","gas":"0x431e0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x76ddab2674369f34946c5fa2f05e2aa8566d86235b83e808e9b27bc106e04ac7","input":"0x9f8420b3000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x38","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1d","value":"0x1634632a1414000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4314a4757076c92ca696f14cbe037bcc0178f8b10749418d4535195e90b2cdc9","s":"0x15ee917bc3e27928196ad987b61e3fd35ac92a4200b139d355b30502bff7fceb","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xac2fde165d9f13a223f58b9ac1dde51b63feff2b","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x34a5c74011a2c8a00103bc91bfbfd94aa99cd569be69066e4bf64d188fe8714e","input":"0x","nonce":"0x38","to":"0x7155eba8ef327ac3b36fe59b5e00ab85f735f4f4","transactionIndex":"0x1e","value":"0x1c9f78d2893e40000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x52178c5dce512607a6242f501f78bc894917a482e99a3368caea6bca94c6dd69","s":"0x728be90654231b65f790eba478ccab574e2468fc4e031b712efa88af31fc6592","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1ddedd674bfacb6587e0c68cee8f2f7d8a71e9d7","gas":"0x1d4c0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x7b9730ead1b9f59b206d0ddea87be9383ba3fc7b496c7863b0cb847889b86617","input":"0x607019b9000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000041971588d95d4d664ac84a45e59fc81871b7051d679376d86cef6b9e1453c762dc33a84a125774319ee47f2a8b8d588da6c8ff7ad84fd9eed22fa124b1a5c5ed4d1b00000000000000000000000000000000000000000000000000000000000000","nonce":"0x1","to":"0xe1e6aef7642b6609e6c54884d1bda4a3cb152461","transactionIndex":"0x1f","value":"0x4380663abb8000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc0d3e609b2e9f844d300a7784aa9e7cb956415d025cb573a73848f49e4be69e5","s":"0x6ce01527c00c1a93341a541824aed7a1c895f5a0d998f4415cf6d88171c5ad3e","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xf6df8ead0bdabfba61d9b2457d5a5ccec67fb7f3","gas":"0xc836","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x77166ee0409ba86bd26e7c03ad1a927abaf5af8a8a37149e725cd37512091dd6","input":"0x67a5cd06000000000000000000000000fa8449189744799ad2ace7e0ebac8bb7575eff47","nonce":"0xbd","to":"0xccb0f4cf5d3f97f4a55bb5f5ca321c3ed033f244","transactionIndex":"0x20","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x5649e1ff58fa9b6ee27a7316904df02db1ba1c471a2f3409f370a31c6b3d5ec4","s":"0x386b766277e267f8796ba6e92af71a752335bbe45cb3385b9cdcab9ef6c53e41","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xf37cbbc2dad42e8826898d45933afd3a04937e71","gas":"0x112c1","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x3c2b6c2ae505c5c36d5f316c1fcb5f54f7346ed35ae35c93462991ded7968a68","input":"0x095ea7b300000000000000000000000071bcefe9e9fbad3f12f2e6c14ea0cae7f0c91e7900000000000000000000000000000000000000000000000000000004912e6bef","nonce":"0x9","to":"0xb5d86e1f237d52f1f19793d3265e9340394f75b8","transactionIndex":"0x21","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x3ee4d5bfc575fa4b241b4d23e6f099eba5f1e6a20b8cea663c63db6400d01506","s":"0x21481ea7a3e7ad758f2e149829f70f43d67b3cc0d44112cd3744e290a06dd985","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x52b6255b7810d97de8f751737547d1792dff4fe0","gas":"0xece2","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xf99a792837e13827b5e0a8915fb59c760babc95d242feca99a5594e64ff6b6e2","input":"0x095ea7b3000000000000000000000000c92470d7ffa21473611ab6c6e2fcfb8637c8f330ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","nonce":"0x51","to":"0x07865c6e87b9f70255377e024ace6630c1eaa37f","transactionIndex":"0x22","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x5237f7449c0df409c1a4d6cb09005a9224860aa74737debd961e2a24668d1022","s":"0x17e5e842e3f5ffb5a16eca0ec2a92e5b52d43bf9856f97e2083b2e951499b970","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3c70503d83c5a681aab503d724f47fe810ae8205","gas":"0x17eb2","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x522313f5d923f048ae5bd0b5595c1f4fc883bc0b3cf3cb0939d3fcf8b08c829c","input":"0x94d008ef0000000000000000000000003c70503d83c5a681aab503d724f47fe810ae82050000000000000000000000000000000000000000000000000000000316195298000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000","nonce":"0x5","to":"0xb5d86e1f237d52f1f19793d3265e9340394f75b8","transactionIndex":"0x23","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x6741309799fccf0f1359bd710291ec1bb66eed23522d6ed60c5924264d4d283e","s":"0x69c43182ee8a650b0042cdb2352781b23eb1de72f1c3a8903a1a33360e7d9732","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x4da9a48963c158a88bf6d4845a6a1890d20e55ad","gas":"0x431eb","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x471ceb0e85af594aa56deca54cb8198567b2afd8406722ea530077aaa6b641b3","input":"0x9f8420b3000000000000000000000000000000000000000000000000001dd7c1681d00000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x24","value":"0x1dd87babd44000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xf977ce19da80b7e155ee2d8b7656e5c89004851407bd5370785befe2c89d82f6","s":"0x1d76177407e73d8b73b0909158825ee375a25fa7c18b04884f4be77bb60795a8","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xe40a2cd9efde08fb7664bcdbbdd877c52c4bd228","gas":"0xf4f6","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x3e9dca502e9039ae0c6d642f62e9562ff00010c6bfbb8234a6135712ba70dfda","input":"0xa1ddc5460000000000000000000000000000000000000000000000000000000000000738","nonce":"0xa","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x25","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x34df85658956c9eb71549db3a73abca70dd01b8e91284afcd372c1212a36605d","s":"0x5036e2984bb2edbb5fd647bba873f1f5c5ee4845e539c9b0bc70d3d12a4bd93f","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x17299065e99b12b0c8cad06638624cff8d507334","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xc95cac67267f4accb9b5950316ac64772f7d082bed6b712c09cf2da0bdc237b7","input":"0x","nonce":"0x7","to":"0x02647cbb1714fa9a5747ec5be6333e06d806e85a","transactionIndex":"0x26","value":"0x71afd498d0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x82ee5cafbd010cdf7a4604df728d1b8713a5bd26a708f5c92f6b6a55864c9576","s":"0x2b9a70d812123b2ddce1108c4101ddce182f6c83fc8aa0a139ba597aa178b270","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9aef7b879787baf0c2dfe888e67a7edb7a233209","gas":"0x431eb","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xfca28fdbd13fc16daf7aec7d4a2ad2c6b5f0b2a7b0fb1d9167c09b5e115ff26e","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x2","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x27","value":"0x2387acb3784000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x7e5f1a27ea5e652ec8705f80365f1703d2fd50c1de7c22ee0181d556dd2fcc38","s":"0xb22fb8b31dbfff8ad0457ba4b659fb0d7031cd86f08fc3cb78d81c97248034e","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x06006a25e0fe65f0eeaad1f4813940b68db782a7","gas":"0x17ea3","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xc73124ca798b2f7a5df2ea4d568efab2f41b135130ea5cc41d4bcb4b5c57d5bd","input":"0x94d008ef00000000000000000000000006006a25e0fe65f0eeaad1f4813940b68db782a700000000000000000000000000000000000000000000000000000002726bc7f1000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000","nonce":"0x6","to":"0xb5d86e1f237d52f1f19793d3265e9340394f75b8","transactionIndex":"0x28","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xabe4fc843d3a1628a464884c13c21bd21ae9a0a5738d9ae2761ec7cb24b059d0","s":"0x68408d8096e542b2c06cbbecb9494a3778c3ab644e69dde1fac078079c4bcad4","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x2501bf5c8ddf04a60fdd47a95d53d99b315604e2","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x29abb76b5e7a5ce137bf9c22474d386eb58d249f43178d2b2e15c16dfdc5ca80","input":"0x","nonce":"0xa","to":"0x901a4e04f1513443c6efc6ce4e913d1b960ecd20","transactionIndex":"0x29","value":"0x1a3385ff37f0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1a1789d5b19950f45383cb1909cff9128dc2b332e2ea7ba42cfca5806376e3cb","s":"0x617a5a4339503a9c9d08705d98e7a202ed7ede1d1192fd7d98b648c8c102716c","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x507832c92ade971b9a2880427353c6ce6d0ffe53","gas":"0x61a80","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x03e5ab25a58bd44fb9dd0c698b323eab8b8363479dfcbcbb16d0a0bd983880ae","input":"0x85ff842c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000080383847bd75f91c168269aa74004877592f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000557300000000000000000000000000000000000000000000000000000000000000014507832c92ade971b9a2880427353c6ce6d0ffe53000000000000000000000000","nonce":"0x1e7","to":"0x805fe47d1fe7d86496753bb4b36206953c1ae660","transactionIndex":"0x2a","value":"0x214e8348c4f0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf707322f65ba56c95ced5654efafcf9bfd60a2dd80e74bded3190673cda55d8e","s":"0x46412ec3d2137fcef30f53cc4644769f4da126128979920ed4e209acb1c8ebc9","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xd44c850ce9103d6b2398d4ed9bbce321f3b769c7","gas":"0x1e0cf","gasPrice":"0x82661bff8","maxFeePerGas":"0xde6f782ba","maxPriorityFeePerGas":"0x59682f00","hash":"0x3c8ee80ddea7fa2d2b75e44563c10c10756f598e8ad252a49c5d3e8a5c8e6cbf","input":"0xeb672419000000000000000000000000d44c850ce9103d6b2398d4ed9bbce321f3b769c7000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000d44c850ce9103d6b2398d4ed9bbce321f3b769c700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","nonce":"0x9","to":"0x1908e2bf4a88f91e4ef0dc72f02b8ea36bea2319","transactionIndex":"0x2b","value":"0x2e2f6e5e148000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x327a6fbcaa2ac3cfb0ce64b47f6e61de4d18297f1305f23c6bfd42d88e8d068","s":"0x6b3a9b5252ced14b2e2f2833ad7cc62c46fbd0785d57f2747473af3fff7d46b8","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x78aa9046272fec8d51a402681d7c37481db01c6f","gas":"0x431e0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xaffa73b68bc7ab0c3f5e28377f5ca0a5df33c0a485f64dc094b7f6ae23353203","input":"0x9f8420b3000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x36","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x2c","value":"0x1634632a1414000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x925370b51dda3e1d1bc6b86580fda3b40875157ea594a9a14174436c726ad46c","s":"0x516c88bf3cb2f46ca81572140b41e5db2d74c4a736ee7d572b508415c438f779","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x56784e51c2ce28dbe9aa68342638d1e95ea4324b","gas":"0xb72e","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xc66c9c66fbc8fe97fcc16506cde7a58689af1004a18c6171cfe763bcd94f50b2","input":"0x095ea7b3000000000000000000000000805fe47d1fe7d86496753bb4b36206953c1ae66000000000000000000000000000000000000000000000000029a2241af62c0000","nonce":"0x9","to":"0xcc7bb2d219a0fc08033e130629c2b854b7ba9195","transactionIndex":"0x2d","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x407c855bed0fb088e886c3721ee9abee4761221d110512ac29b8fb143c4b34d4","s":"0x1e47aa957d9ebdb564dfa41b72022d525383ffd825a307fbfa9ca13a59994dcc","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x805e39acf2f170251c48a35df16411cfb2f761e3","gas":"0x56a8","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x80fec96707519172b53790610d5800cd09a4243aca9bacfa956c56337d06f820","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f4000000000000000000000000805e39acf2f170251c48a35df16411cfb2f761e30000000000000000000000000000000000000000000000000000000000000000","nonce":"0xc","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x2e","value":"0xb1a2bc2ec50000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8fcf376106af19aac48ecb840ea51df90a5e3ba557eeaad41cd3c8a90785d416","s":"0x4a9e9021ddb5f839bf7f54b54ad52c57b21b6ed285773eea022e3ccae69d1b99","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x4199614bf74f6b3ef47a812d976dd1f57a8f082c","gas":"0x431eb","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x61b33bfcf11214906dcdce7d7ed83ad82f38184c03ded07f7782059d02eeedea","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x6","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x2f","value":"0x2387acb3784000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x3d295f5fa2dbec04793f07adec57e29c03376c628a0256ee297fb3070a1e3364","s":"0x6f115dd4505bd320bd7460a47bab0c20e6bcb4b3f17c6d0e00e3ff1d936ed2af","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xf6df8ead0bdabfba61d9b2457d5a5ccec67fb7f3","gas":"0xc7c7","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x5d4138d4e28a8327e506cb012346b1b38b65f615a2b991d35cf5d4de244b3e6d","input":"0x67a5cd060000000000000000000000001f1f156e0317167c11aa412e3d1435ea29dc3cce","nonce":"0xbe","to":"0xccb0f4cf5d3f97f4a55bb5f5ca321c3ed033f244","transactionIndex":"0x30","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x47bfb48eb89a8b110749d34d171db36a8ad21c8d7cc78c7489e72f21cd86ba14","s":"0xa525976583b19b3d2c2dd6b34324cf55b1a61595cb53e3c58acaf203f8709e6","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9eda8333e09828571db26576a566668f79f98946","gas":"0x50df20","gasPrice":"0x82661bff8","maxFeePerGas":"0xc8d5e2427","maxPriorityFeePerGas":"0x59682f00","hash":"0x875a142b6dfcf10ffb71a7afe0ce4672c047fc7e162ba0383390516d6334d45d","input":"0xb1dc65a400011a04d404e571ead64b2f08cfae623a0d96b9beb326c20e322001cbbd34470000000000000000000000000000000000000000000000000000000000bd780a7d2e00ee03a29f787096cae99da52d07803c76c13473654239118e2cf0491bcb00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000480000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000077359400000000000000000000000000000000000000000000000000000e50bb6420faa6000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000217f0aee859cd78a5cdf79c68c8de4342658d52ccc6420181b5fcb7c657c5fdfa5ca2c8f2dd7e6e5799d44d6818e6dd8fee19b2530bed2045e0c665041f053fe70000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000840235df8360bffc902a68675311f5eaa79ea2c25e2cc394bff0a43d5d608e98c97de200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000493e00000000000000000000000000000000000000000000000000000000000840235df8360bffc902a68675311f5eaa79ea2c25e2cc394bff0a43d5d608e98c97de200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000007080000000000000000000000000000000000000000000000000000000000061a800000000000000000000000000000000000000000000000000000000000000003312d88cdb7cfd5fc5458d9a424da374cd818847f87fc4fb6eae2c3b97e541a6b81e108e55daf857b71514fb7213db7ba15bd6adc12253afc3c5e949144c13696faabe22d1b7ace91532134a5cc65bed9afdd897d6f84ad1b0b6da463bda8fde5000000000000000000000000000000000000000000000000000000000000000352c2a75f88112864819de485c392c349f718fc257934181c4d8ac8eb3a9b1fdd3b7bfb96496290f2b41fcd20fc8d29bd8e29be38550775dc97d21b17c2d679ad05f519787eb2c92a9a897c9f02f15316865cfeb4bcc2c0ba5ac2dc4aaab5c0c9","nonce":"0x3705a","to":"0x233a95ccebf3c9f934482c637c08b4015cdd6ddd","transactionIndex":"0x31","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x7e9247209bede2c21548c6e4f26e41d2636a2490e09ad062f9235e978094073d","s":"0x288d820793b48e55777e794f1694b1605d74dc8726fff438b481125f219eaec","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x6df2b54f23ed4e95235c6e21ada2cfff5a2615a6","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x79b6df832bfbd04085d0b005a6e3ad8f00fc8717eed59280aa8107268b71e7e0","input":"0x","nonce":"0x17f","to":"0x6143d939b2d117f4b998d8d88a56eb0e0a1e9c31","transactionIndex":"0x32","value":"0x186cc6acd4b0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xcb641be908976bc0a035b0b31a96039da9e63e829e0a24a092ecfbce7724b9c7","s":"0x4034e7dc4001cf9f62a2e5dc4390229655b85e9aac5a5b263278e9d2cb43abb2","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3f5ceedd435b6143eba2254811a39fc3423f18dd","gas":"0x186a0","gasPrice":"0x82661bff8","maxFeePerGas":"0xaa246a58c","maxPriorityFeePerGas":"0x59682f00","hash":"0xcb2fb25d268f65dc9312e89bd3c328c9847a3c9da282026793c54a745f825ab5","input":"0xe9e05c420000000000000000000000003f5ceedd435b6143eba2254811a39fc3423f18dd000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","to":"0xe93c8cd0d409341205a592f8c4ac1a5fe5585cfa","transactionIndex":"0x33","value":"0x1c6bf526340000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa48a4ece6fbe881e342a4eda767c82097c3bd47dc70c09ef6a4e7f90c0f8e843","s":"0x66c92f16907488d115f5088ed8ff4d71c966232458479245bf6dae45358c0429","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdb4f0eeb7c89b00118cc74de8c9ed55d65c2b933","gas":"0xb72e","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xe483d4a36ad19fd5eacb7f6d9ad3ce080ad70ac673273e710f6e3d5acbc6559c","input":"0x095ea7b3000000000000000000000000805fe47d1fe7d86496753bb4b36206953c1ae66000000000000000000000000000000000000000000000000029a2241af62c0000","nonce":"0x120","to":"0xcc7bb2d219a0fc08033e130629c2b854b7ba9195","transactionIndex":"0x34","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x6d73169394cb6a9bceb2dcb16aacd261705096f50f30ffe146a09659e25dae48","s":"0x496a1cccf01ad2ae7094b8da2ce50c0a990baba6300625c48ca12c5f20005a64","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9ac253db14a434cbe7653a99c5039648fa4f7353","gas":"0xb4f8","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x0564242c37d5013b671ef4864394cc0f3924c589f8aad64118223a9af2f164f6","input":"0x095ea7b300000000000000000000000028ac7dbbf9ed6ece39a902e76780fba60f1b2e3b000000000000000000000000000000000000000c9f2c9cd04674edea40000000","nonce":"0x4a","to":"0x0dece1605795461158538302b5f0936afe78c4db","transactionIndex":"0x35","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x15684c9697dcc8d89abe562c4315bfb959938fe7644c00615d9e147a4e496ff6","s":"0x7c58abea24e1fa8caeb73a70219b0d63007785c39694fe5ed2a5a342c99292a6","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x22496eece162f52d185c07524d452b9506e9fe12","gas":"0x186a0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x48db358e80b278c3a46c2a166339797060a40f33984a5d974992cd9722139d5d","input":"0xe9e05c4200000000000000000000000022496eece162f52d185c07524d452b9506e9fe12000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","to":"0xe93c8cd0d409341205a592f8c4ac1a5fe5585cfa","transactionIndex":"0x36","value":"0x1c6bf526340000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa50e6ea1eff21fd33d69f8c74b90c28303b92ebc4a77c71b65c4c8bf3e92ac8c","s":"0x29af3bce2365578b76dc528917b44e96e4fe2e7a8f948eff3e379721f35664d8","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9ce3f4210dc06889ad5267ef0ce3ded4bd96dc50","gas":"0x249f0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x69d7758db91fae31fa35ecbed4d40897c5087f45dc796cd796b8ceead21f972e","input":"0x47e7ef2400000000000000000000000089f01bc9865324583380d8d7ed08b8046bffd7fd0000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x1c","to":"0x6cf3df5d00e842aab1eb504bcf01ebf81646f7b7","transactionIndex":"0x37","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeefc19e8dca874308c84712c3e48c032a25971a0f7dff16dc47633ba7a4f5b96","s":"0xc0994cf21d29cb0c5f1e666538b58d6dff3b9ba2aa7545337da732c4b5938cc","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xbd1c4e36842c06e53b378eca310cd2dc79a78cbe","gas":"0x35965","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x2951478916ecd27a8e808d08f85be4bf2c0b0e0546f21f4e309145dd96eb8df1","input":"0xab7d7969102507275d685f3f55d10ee45f7b9fa39c29a8a604a7a971c05eee739e63938500000000000000000000000000000000000000000000000000000000641cfd18","nonce":"0x252","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x38","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x87fcffa38e0c84cf80fb37ac1e538faeca21462b0a9ec25af0ca0517af22789a","s":"0x72cffece99e79edb7425a9d660590fbc395cdd0db8fd4848074c85f814b3cf63","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x5dbcb3e489fbef1656dbbd7bc4848ed0e520a089","gas":"0x7a120","gasPrice":"0x82661bff8","maxFeePerGas":"0xc8d5e2427","maxPriorityFeePerGas":"0x59682f00","hash":"0xaca9028cb5d55bbf71b7bff9884a9a3b0b38a575ffc8f8807ce345cf8bd298ef","input":"0xc9807539000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a7a9d91e687decaa6b045797c2e002d70001b48f03020003010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000002361273ef6f000000000000000000000000000000000000000000000000000002368a4faa14000000000000000000000000000000000000000000000000000002368a4faa1400000000000000000000000000000000000000000000000000000237b9042149000000000000000000000000000000000000000000000000000000000000000288e1b54f6e54124deb78bdb67cbfd0bf63612da12868fc281afc34bb26200a1771f9e00fce297da11cf49427becf350d0bd20a2277439fbb2e8db0fbb5e3d34700000000000000000000000000000000000000000000000000000000000000027d16a90ad0e1f8d924255e6380764fa7c7d46427c8e8ea19f5ba6a9d595297a340f141f74e705d0fe851d7564eba89fcde574deb5975d9126867cd927a0d92cc","nonce":"0x11d38","to":"0xbe57bac491de9a260abb6ba2c9ad4c5d2eaea09a","transactionIndex":"0x39","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1eba7bf95bf63d02b74d20554af050eedd78ecfbe1a42ec70badb36ccfae4bfd","s":"0x4d7f8d0ac2be28e59374453f24ae6506a81707cc57f0d1c6877b49b3949a9a79","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3079be9d8622173f02618ba2b793f00795d4f320","gas":"0xf848e","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xd9a8cbe9a","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0xc7f625a19ee41a1750eac9428b4394a9a2476b8ea2d31b4c2f9f5b4fcb86cae3","input":"0x2169f79f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000fdce50000000000000000000000000000000000000000000000000000000000003f2000000000000000000000000000000000000000000000000000000000000001f579a43ce4f3e38c6a948f1ef3bf7954c2059b087b18fdb22c7b69d61727a5d2aa16090b4d1f3281bce660a31d3e2789eeb360192a54e3ac3513c5c8f67b7346fda957c92c1a2981bc68a47d0282e78df2fb63822f06f410e1ffbee7eb83c425122be9be94d817e2e42099632fb9eb5ce7c414cf6ce48e4ed2e64e46e1558ca809742159e841e3de803a8cdc628f7877bfa6d75af4b4ebb185e6d0670ce83332478137fec243a38c0a80d067c955cbe13103294dadfc8c356d0e7996cb62fb2c683e6dd5ad58be934f57375920142990074f8a161ad2390a1e6bea9fc3a58dc3f7e002e9952a68bff229437d3fb4cc1cd8097032b22c884868253d8f2f69c75ada0fbe1dd57145610ae5f451b47645718aca7432d8cd3193d0b96417df6638fd47062a1cb1f63636236fb72195e5a46d1b37f493b8380315e5bb1a6fe67cc6546d62f2c73aad5699e6ffa0d49ce653bcefa173fe0de7b4328aad75f74d15f4f570a1839514550d576e21b8d16c8355b770442f0740e6e5e77ab450ee1fadff8daeeb25a91585192fcd3cdd64dcb6a35e41ff47e854337ebd0923ce280cdacff2ced48eac96bc9f910391a44cfec243a8660ff80c10ff844ea22411953e0387f87d2c2ae81055fc8e87d59e04cd7a923d6aa5204b3eaaf5b842b5fd656e9fda16c59e90c64ef51124fb32f8e63442b1f79d3ba3c0cd5fb90895103719629857d5999b44aad2d69380f48dd824795a89dce14bb82600701ad8fa9bbb36fe93a97d75da26ffcb1a8828918e0293680ecb12e1b772fd98637a7a83cffbca1a994fc889ed0c0b20d447ff727b9f5dcb9a83e1aae9a3518dfe1d7ddab1da48310eaa7ab293d85dd9ca811bfdfee990459fa044c9a9fa6460e5ff7612e42021f16854d790710684663bb6a10ba475fa602b02519f03eb544fe486d9cdde47ab7d4027bfb8f29d778b3a7cc35a9f78dbb05943062efe3b388f1a8c496682a0215265b99fed0363a1061556a40e0539a6656b6cf8967c8fb3092a7fc9b56af124c8f1bd0abbb9af753884b22b333410d47d80c083c9fee52dda8907be0c87c5496f1fe9ac4bf4dd4f06d6ac0ac0cde22138b67bf782e8e9b5c991d58a2a828b4c68620e6d3d26abf8d41005a00866cb4095518b2711636f2fac3b5e26403ef96f5b1765519787ed74c6802b445de029d7bc696aeef5a2e605376aeda4f495c29af66e357c6e1232d7a2c3f22c0bae0c62372d6b2690e503804e2ad314c38a4ffc080d36213458f606075d32dc0a365087616e94a972bf76d7e5eb4a53292fd0d7570cb6fbb4540b3c5ee6deee0f257fe8703d5d8d0180d09754bd9a05894e77318b8c8fb6b4a56999bfc6c405c09d9ce7fe424812db5bf778d7d8634b2f44ad6d00f18615e4c3695d9c5965ba51991508405187275840a3f27cb3101a9742c49edf42dea79ae5418ada42dfe2042f931af15a205e64196b04ef53492a450423c2b63dc849ef72a166fac5f36b25c72d9cb4a2507d5ad15094a979b4ac4ff8eb4c90f448a81fc6dbfcf6a228675ab3308bca37bda8eda22b61ec7e596f2448ee6b7cb6eef589f43f28fc5444d1da3f82ddbe574b774719a3a7869e897e642735517832959ea9cb9164eb2f7665bca1d2e44e1093acc7088271f2be20459c383f5762303b553af1ccfb3371e4eef1f102ce70d62620c5164972facbfbe03b5018265ed62c4c3cc49522166913517e2f2718edb591047a72e818f07c645a18aed87c0384d180dc0bb7fe63bd335b1c09e58571b92e2267ffa5712a33e4a92231d9da7b005730f6d6559ee685edad9a9031c4708c8642c297287af3a3e637d9b5ac6b23218977cf4d30231a79063987f98313a2bc0ca4a73a97e441a45b58cdd8731fc269255b415a9d2ef2bb8a311587f39f6dc82f537cf86a68af19a68c409910f4dbebdfa66445361877a3bf551480d115d8768e8650e9979472a64802da3625cdbddee8f02678a3cc6400824d91b3c7d4c9274b74fb11a9538f1990fc314d35564a0cb0b384590e15cb93db1de1a837b9319828b3fd6b76f1d2bca4ac765f9ec4366905f2dca69a4c8c194cf0a5d821c58bd291e8dd4ddd829a873d093042c1b8e1bb2bb1a95e150c0a0d5c3369c4a791dfcfbc3e631da3d1e704214c3cf8318901f9c58465be78a870a040f34c567c27eb077db2d1ff825a127a038eb14c2890ff9a8a1dc8d6360a91fd788fec97599a318ab03f69bd50a5ece92d96c49413b517579ececf71371b6b1d902b1dbbf40c728c64fadf368582cc4b3c51712c8d6441c0c61802943624e93f9de9eedde87056c21ecf66b3a6977af0261ef48b4c6191ca7ea70d6acc5af910ebf247e2a4429c506c6a41f865175a9bfc81dbb69e59ec2c47370fcee9169b8749c852e7a1275c1278aa3f88bc16d311e58aa9a579ed7bed62f12b4c4dfe9c493cf33f979f667eda043c2aaaf863a747b208f3aa2ccc34f07b12d89bfd75b696a82c493e7eedcdc41eb01321ecfdcb691d14996c3ed7487b5f831436bb7c25876c4149cb6222dbee9e1a05771a8abfd0fd530266476e1bf69d9a15e99c901243585f56a77ef0e6c684a4d49417133ebb91f896176ec3a8f0b966eaffce96f129d18960fdbf5917f8aa0926d52c57192f99e55959369e57ce85ae84ad944e40652f6a81ab8da1dbe81a827366b8b8d2ffb9c7b93087f7a356a16d0022ee8ae891060e29ff11f9f17b01f39b8024baefc8b928a6816309a5c3fc92ed6007499353b5f1bc5700d5fe67f3e34ef3654712b9c67c231f30dff485213b94c20afaa91540560df80ba9ff1cc0f6ea75bf1dac0566551050873c112478f3fce6af162397161e1b41e1ca295f327a4f0ccf4d15fbe58e20a23698bdc25c751d020df371cd1fc59fa51dbf7ad619d208d7084c5752984b5fd0e3a7978f2c11e6b26531fe03c0cb85519483d668bf1dc4dce24509b00aa6e146adb49f31c2c937a2d3a08f1cc0b73cd66f2cb926f0453cf78618e39cbfccd6e6a3b4909d6874872eefed0e395ac2582d8c1d0483007fa6ed7b735323fe8fa1c4be83c725c6b743f63cbd0d6017f1145634b0b905552a2a237561b37c415146d0555a276b4b45d515ed7dab942f9bf40a26d5366032f23fc5fad8b98a1625a841c8cc97dfe0e2074a363a951946df16d1261ef6b2da7f5789dada153448b076637f9d2e04f4390e9dd32fd5e9ab3f5939807bb451bd19d962403da9dd118f1cfa91731973bc721e5ae4a687bb2270e3e76966dd2156e95796d4bfa6b4c10caaee46e1d8f8495f901cfc241c6f9a690349eb0752adb220996ebb95ed26ef376dbb9eea201906a6a3eb346c64eba3c9e4d1b3088baa0ed868cdaf063a4c2434b9d1bbbd69f44ef659262fad9535988ce729aadafcfc6c3ff741dbf8b784b3465fb05f6d5daec91e915f89117e01c9b0c99d7b7cb78e44f5c28de0d3b782de981be058ffa1294072c4e5a66d2d81641d1c07a9a04012f9f1ad15028709fba761a659becf01963de0cc42b0e16bc5432cffa00722a84628373198dbbe75f209115c4e30e60297c2d737996dd9aac330f4a3e82609dd33460438026ae287c172af8aeed0d6c71b1f9470d60588ebd365f20d596999d97c7a6f265890c719dfe43ae1ee5bba122d9d4cfc96b399f610a90606add4f0d25b903c7ddf6eb7bfdc3b9f926243108f591678b0e92a48d52b1dbcdf30ef8af74cfe34d48d0e02d0f99af2adb090c489d4214f3562d3f6a6e9b83b54bb6cfe6c1961ecd2eb2b7eda63601c835c5dc696b32bc495bda9b6567984f83e79a9d4ee88b140dc78cdb64a2ba8761a827cdc8d2b27e690c22402178ade602f2e9092a1b07d56d142bd24d665d7b10bc7646eb6d6823d5622f1fb08f2e48b8deda6cde324d6508fc428e3bf1a9ed608c196786db4e8d6b7271a07e4f73d9ef76244e3e10aa13fd9b82ce2ce72af2df7faaecaf95d885e64bcae16f9b59ab8e0f21a2f459d00a290b0dc57e10bf21ce06a029224ae15cb86bb1cf060ddccb1f6ae82d767eb077fa4ab0f37d02a4bede5d3f8ee3972a6a3a438a3cd92ffd6c1fb11cf2c68c2c6d1efff62b9f769e302f6c5eec96b0c05a942321ef8b9cf0ff2bb80073a8fe138bac5bd8e93f3b27e7ec7a78512059fa37b0b6939f3b1311cb6ea154909e9d316567e013df315e8f02a80e17feb8f3248cc3f11d1253ef3156d7f12d1f6d7a382d6b6ac6abd38fdb5d954e13ce005ce16bd5625a5df01883409f4ab938a59a75b7a816af6a2447b2c65ea55c0ec4e4f23fde145a26ef0b13b740b352809c10b54bfdf30592a8b0d507cb8210391d66d6f68d06f3a4663756697d472adb6ba78976b423ad9ccb3a3bead9de51e324fb77609729c78664f4d37c7c748ad9fad95af355be4f00a76cd5cc2c0b6170fdf3efaa2571bc8fc2d0d24682fec5e034460de55cd0426b8ad448551032e1f6ade6d96682bc38a92c296e5bdbf42fcf106d14c5e8a4acbfc0cc1f0bd6877c4469be8b204ffd5d7c0ee85e7b3265011ad5e4896f9f8a69997e321a797549cd3c1cbb0301ff30c3a136068ba37b2176e556b574a542db90250eca38f3b0e418e352b5728206d6d531ea253d781d771ad974b476a045ff14718d9a1820fb469e981c7b71ae8fe423b0a04278bcfc967ca602254de37751127fe3716456df3fae50ed508e529c2181d63479b6464bfcde6629e8179f8d5fa5b61003edfc2f129affa58608d6145de98ca8f1c0b3b9b5ae996a7fbc6326a9ac2880206fbeb1c99d0448cd1ac5f275b84e4be03258f9fd0d3f44a692513957fa083a462086787315e38aec8c09b96cca034cc6294359fe00285c607d41fb4e3bf25760ed1ef0802bcc40b2fce2cfe1c64f7c34b21d0bb1f5210360079ca8638ab42943b0ab8277f1cfb1e529073d2068a36a4d8ae8179c32bf66ca335d698f76db1cfe5236e6427e01804464c1ed4facf18ae09148c5a0cc9ebcf6fb6c7d03ec6782b7595816245ac2d1fdb3184ea49800d5d0f1dd880ff99d6016549d63ba2a44ab96f0db0d0cbd5fd4f67af1f1da0b1023883d4b2e7cb23cf85c617c180a771267fe63c70f19eee28fdc50c57d73b2718f8001383135b859f4c2fa3b9a12d095beba8857df13e921d9dcda5b87e1fce6038fc2f92282c717305157b6fca5ca2c23cb7307a093512f985628e75326e0bca2c4dc5ed44bed8e0cbce1238f4023089a81bf62b04a31539de9c8a0c867b791c18a34abcc721c0e90a1604e8d2855e78673367ce463307f6036850b81e0aadc9f81d8c9ad6e3b81d7850d4a46bd6772e651e03581a7a55568c9d63c1b1e8ca947174d68afcae6401b75dc7397be3c0dd76ad1827424f9ea9de8ac99803641535dae3eb57ee1eb1e2c193bf66addd488da55055bcf93172b1966364db4412e44bde64c50f7692a38d1536683af14fa057569cc7ef11f614a58995ade1b12f979005a53bee0769847deceab4f58f3d062767f7ac0511a04fea349e7688ab26425cfc369127325ab7fd24d73c4a8b23f099892b3bf52f35f0d775ba753098611ce35c56873a7455737a42672747bcfa99da8c8d0f06d8754d2babe3eb303cb06ce69e4046541ce63b6c28ded5a6fbf729200060132e9b01d8646b512356c92d8a642de0f62d169b195cc2e7ea2efebe550b1cddb5df7668a0d1f94a2f5cdf7897e46cb03b958ad906393c7d252b58493ce6c7d813c8fdfd5ef577a9e778c64d48c21b130c4f6a57985b8122f3cb69de015081cd3e247de65643f9d863fac6935cffb2ca23083d4fca9b8707679d9d4c3cb34d05d092334b1740ccf4b2aeae724902ad4fb4bceaa642b3ffdd5b564d7bfb725fae91f5c7ab9583abc2d80afd2272b14ec6fafbc51e35bebecce63bd95fa3f39e4e689034c47628345c4d8e30a73c36d87d289b6ec715a2769efacf39c9f19eefdb311b9800377c5c61aadeac78dba6946da4e7914415eced875b66f10b96ec98f64e58320bff09e8ac4f5969608171dbd4ab5883548a289b52d55aa82da62ba3d9fa59734d8f810bc1a40a0e3b2e116873116fdd8bad95471f16a14054fe247637febb6081d00e7ded3019ec03f76ebef5401a27f380fbe8a55bb4a0014f61276d9aa5626a34e7fe5a129a75ff130ccfd78cfbde65416882ce9ae9da57a3a04c67d22d3a12e811b2578fce5f6a64a09a86782bc15e5872e546dcca46bd9ccce5b787d17c70d6b075bf4c789ca184dedad3485a0526a61d280dcecd984fcb7ec663f8f491e91253675877987433e11b9cfcb5940a1357b55fcc5f977fc898f72e8199ed5d8d2554d54a55d6b4b3726e7fd7093996e271e218533f3b31257aa989f5efbdb12dce02d18a5188ec32c3c1c91845a17011ffede3f060f19d59b6565a352e90c5ca30eb252c6fb0cc845833e553f0bbe1822b5d6b26eb817608799b5b77c2cce27beb151060261f34ea73db94bb2fee11864aff76da5b10b17aba6634ae655dd396fd7e7155013fe3c6f840ab1ba9b25489c67f6bd5967a62134b238c325986c87aa005396c54af6357ca88baf5a03e353c8b0175386157d9221833585921d581f1fd3f5d9932b24d41895a5c35be91b35643e7091a7585ede900853aebc260b1fbe8b72d527390ddf46472f7c8d5844355ffc0b731dd5e584e13d65f2347131ba8a5161a6749458c1899b60cf9f9f8810889fc23b5d0fe2c843fb5675cfac6dc8ec8125d1c582186eac82d5e0b3f6df2a83eb2fc23c4c3f873267deb5ea86dcf1e3c5bb39df23f06560609b9fbd89511281fc7d69fb19764c41168a539b44f0603a52577c266fd601c0cc849b067746b4da78d280385ef80a3a553dabe4b137c50152f4e1de456d43e015e26f7d76e612b7be29b9f8e15c6a73653f5f7dc28aa245e64f076130bad58bbbd3b024c97e267a96365f019846d965c037116c74ef18415ed5500f12a1816997895f3bbe7b0fa1eb12a565255a64d5eceb2272027e45ecb0a1a8b5dc99128c002058c569076371703e1f10368c6cfb830ae8bc688eb143da7a1780dbe29cc4c83743b25d570f5d8609df46c807edbbc96358cde9ed0d9b8936271b3ade28001a6bfa6ff7ffeb4e6a6687e803b5e8f67b82e6dff215ee4f2caee571b8febeeff368a89539d145842526fef110174ba3a2d9f1b4a348dd25dd964efcf88847d3eef1c18fde81ce84b80cca8588bc1fbf9c9f34059808d3eef3fc2cef7636f7a76c533933b79a9dd2ae2791d1ab5e1e715837a766d9df1947d5986c21808eac758461596870b744a6a2862f7f5bff0c7a3460875b3b326e45fcec1cdad1cb4b99085748d69a62320f7e6c53c061a55ae20368a4e6cfc126cf2c0b410af545f169fcc741cfcec4947f577a1bfad47b5080ecb41760b5056a9bd10a10ca43677de0e06bf36b0d2bf7ca605b9217240871ed1ce43bbd07a7e77d1901dde15e173ca344ee8078ff115e954a2fa660bd4af61ac32256fa7d62af17a4f95adbdcd09b933fa47828d91a6b710a5c67195797bc789647db90107fb527b8ccbc1200bac302dc47a366d170314f5fd7b60535130d76832ab7a06ebcd83d064c1a1c5a7386b0945d39f8ddfc3503415ea22514a0ebd0ad74e3ece5508d83355cba944b12b669d6355a6143921533190eaeda0337a1b89ff9db0cae62a239025bef078137362db71a9eaa6d0a26fcda7e80a9b8fa4a1799819f0489b899cba4048c999fda79e0bb046d7e765d9abb445279efd13d47fde8b731a944af92da8d8965bc4e90d9da8ba0a9c385357e16788cfb663573d9d34810c754e86e3293a868461b241d7872911e676e73136557db1261573962221589850fa5ce049d2356e6630a142427a2cb2efecfed09445edd112323f0071f63f6a42035a9248efe155aae056db25b8004204d530d27027c34eb6937a5a05bd2096eeb1fa266a0325cbc7ac03270b751013b53429aa2d8da2de8c12e7d4996b5f1dd365e270285d2f3a65bdeea9346d960ecf015215a88f465a66417d12d95be2c0bb3d8e15163e0dc66028a30f1f5506558ef534ab28cf6dc2b7d12f49b0e319995efbde71978ef7121df58bbd16be908298b0abb6197bec22c598413283e7893f0fa7398369b83d30b29560ad09a0a24e029d0c22a7cc6fe53d84a7b2104681df35cf4c3ffd90b14cacb2ebbb673ddbbba291feae96498b30d024398676107d3efdce47353a544c9d885cd5cae19588a4b9e29c700c539bbcc119926e3d1adcbf4e8fa3dfb0d5c2686a3fb4ae7b4b278fd94db5efcad7f280488702d9f7675aafd248960806df3e8f95325298968a8e7bf54cd2797decb5bbea7bd3cbe34081c0b65ca9a4d0d08d86ff39f97751471e09f25b486dddfb2975edd51ec77d949862dd4a658ec974b8a5a381ca5b7314b677c4491e07b43a5a9964d95e1a29fc1d87cbf1a64296f4cbd8128ab13dcb60dfa8593a575140f5a9fa6a3708052b3bbed4b129aea88e66b72e583f1fc285ed6f835df0d4751c5d5f004ee0c65203ba9fbd8ff70fc255e497748f24c476d18c94089bcab8ae3f933563c6682e5452da8f760943c7efa631b2980e6589ad4ee83c88fe0b2ed9900571c3df6bac839df1a6d9d281a5ff627d41ada13b867735aa7377386182b1b113f237c14b6d806079d2f7c234a7cb585e12a5b16f7064fccff99386d58f91d9c235eef730660a02ad37dcfb0352b1da76d739ba7bd4982cbb8be48494acab84451bb39bc59521c9873ec9f53cedb527332c47afd919c94d777e603b405e8563248c9ca72f3b2fb52f08a876778d18e7d179f6437b64f79ca01f6be06d7b115b8d3c3320c2dc0ac59c860aca8c92407ca2239998613f44945bbe2c6a0ef0890ceb27467d1ab805ec960e6e58e49678a0841823632f62c58f540f19e82bf719e12bdc63db5363fc0749877539865a05786106b58dcf50bbdd015893b043b21bc1f24ef9eee5f2487d986db13c143d3366260ade522ab824fe82218daafe5e42c50ef740cb9ac570a13cb55fc30c9017228f2c60680f75ca89affdd376ce70ca5223078a47da0aab9bd18333c14aa021e6c088609d7a2460744006f149b648116152e7c814a5730bedeb6ebb59fe395e6b15d379909f197c4703dff34f8915b26a36e30088cb227fc1df108560fce419f462181e468b5d94251fe1373e0dd004fad02d690f8f28bd972e85ec49485cfcdba717db66e6a343044a2453ceb6403fa0795485f8014225d283da4c3aa6fcbbbdd6b04c30c96fce04579578882a44fe7b781285daa11ee71239c1b69791b8fe45868fe6e85341b7ba4292d6da1ae079875b33d7aa2becb02327a17bf2d09f6a42e9681df41890f17de5cf4752880660a35dab912d10480f20f92589d52ef4780ec28920d11de0de06bf63d61829a3d0894f9a32f911ac79041ef51fbcdf3f5b03f6a0b16f0b9e47444b82efa7c012e3bb9324c8649053433306d0640ae953737336cebe9b854186f9dbfda861fd7eedd76fc24634acb9cb925302d0bfd3751b7b6bab36ebe2ea80cb7c5359a505689ed5642118ce93cd783c80a2cf050f57d5acb62853367ac606fc1b8a01abb7b29e49fdb190e2b586e249639889bcf5ad23161f278086f244d0db0f9ff520e6858b68f5bfa0f5ca700096277ddfbcd14a4cf4358c0f042b1eb34bca6353a1383f5d310176262ba45512ea4f172f321efe971c391fa9e9876a250ab653fd6d5a8b046028018ae043da256b78eb26d86e6e89873476ae24dad26ec1d39da44ffdcd93d8c5c1fe0796bd46dbe9b01be0aeae841662c10ea28cbfbef76f0197cee86dd4c7dae3ba46d5c2884ae977c456681d5d9859d854a3e0708bc35fd8415c22ef4cb889bf0e66da72ebc635b71f5df04db801c76564d2fbd946ac17e27fbf995994ad26c3d577ac86b3b19f855d87bf3f0f7c3fd574b89901732dfacf2e13960975176f7418893b31747d96bd981e9b1463590bd35b51b7a2eacf1a7733f76a7d4b02fa2afc5925f5483f82cb529682f785c21cb951d5678a7d09f99c0e2bd98948b79456e4e0b5d9de80943f1df0c639ab8acd6c99a6297cc5a53a829561a6615c6c44b24a30a75174aac207a35fc429e1a415b0813857ed85ab49db6e523cdf9b122c2442a4fc2b4fc21685c9c4a5de8f36c0b405e34ddee91832cc6567d458ab76b4650020d270a65a562e75e06a3d8f1313b4d1d4d29d597bae9eee653bf8e31b82f9cad2d0848ed5daff73d99472c7e71d2f1be60bca4ee9d315196c096cd8260192597c8ce3cefa9cb6f129dcfbcbd65b5b0e19df5a1e81bdd423a2e26d11ca4f7aee99104530c1c8e3b1150669f16acf415559a38cb27eb6d637c78b1c90ddb5eef14ab9b2ff14ddababd7a349b7f6f5b6caa3a28c45835c9beaf8f836848f579598ae80ff9af739cdd800c5a3d7675c780ad66b2c449824d8ccf55a7669fb720604eeab427a0308122c3039ef9be6df46e34b719aca7a001b884e3f7b1d1579176aa4d365a25b6f3d420190e3cd9babefd8382b6bb12b4c38b981b08b5a139cd46e9382c01f361abdac7fb16b87e2c61f3241191028c770c3e3be939c8825c63bc4e523b389d1ee28189b5a2c11ccbe0aa7d3c2b47443028c89f3d4bc1bcac39eb61d91e75e0d372b9f27c8dc622a86bc0cc0a9c9dafa5e2bc67834a75805f3bf1571fbc5528e4c69f3e64ed27c1f2d93f43215ea0d4213bf2809391b8b9201f36ee2a275dc7c44d0d83de3b82490b65d2b399a7348133c4df7ef40e6dcc114d040f65de00a70cc0c9fe615c6fa90a2fad6dbcb39370af043345ebd9d8af094c831f341fa5f7658c2c1ea062948fef5015696eddd181d87dea49ac8bbcc2c7a1ea01ba1d04239153ca401bdc27aa87093a78b2020109d7cbdd39f279a7d67b14a5822fae28854323a2620033a5fcf9817a0d45eca7e2d120a113fd5ccd9fc0011e89398767f7f6b7d01d5a670b4fcb9c5648991817a62edf43d6964de204541a8b5573d7cc10bacaa1bb835f87d12985ad5fc6ac4834ce76c76e5dc34cc322c4220d9d65ca77051e7c1d4edcfb4595db16c641fa445401c72a24e36567631ea02e4875b7f9ac2ddb4712b79d1468c7ed2384ad5d90ea0825f817e42413de33eb30861ac92e19b1aada118beaddb179399008137f28a8f3df1509ab12d6f6ce7872521f5cfe4738722fdb410b3824f139ccf8ea63817d154b1e497a70e6f55b75e4decb73d10ddb0c57d7e0f74b3f4fb41ee57c2da1e4399c2577f28b7e911db08e877c366f231114cc9553c7f3cda2b75895fb60ce9eef4e0c25d253f689dff5e4f9cdc744c301b6f13e9fa9e30bdba8abc203c05879ff01bf8c3a3aa742ea5fffabbd6d165e50bc412bf5e18c60bbdd4fdb276f3bbfef246cfe36612ad61fcbd4498c18321a1ee12e6dee902c737999f9c6b3919f52125cc77e237a788640f262ab76d5c9db9ceb2d988c261dca63455658293b10842ee0b30cc1f928215e0308cf258ee39ba666b16319d0e21df8b9ed91be2e2feb9e117682cdc9edbc20b0b3b9ddaa93ec7a2d8f752ebaae57b7d74037c5cd64cb04746a38c0ea3ba3241319360e585c257fb593c123a653e6e0420fc540bcc0f072de6ae1a31b57dd5acf0b8607e04d21b727c93623e5227202a7c6432b308f74266dd1e1447a2d637a5259fdcd1d8729f341a7dc383b4c8a6ae0e78c34a55793043d2dddbbca1d161c300a8a7cb760298541c90a1c5a890b5257369b8fea0b4d14dc0848e644953cfd5196494e4c1b422f8e188314f2fa903fe93393193e9b76bb71c0caddba43d8586d72657a2d717e4b2c3a0e8bc33a6f8d89b871244eb04e4ecee26f9b71ae7d5c44f828083b0c1920d37cb5d7db86be3b18ef16653863762939cd1ab5c5e0cd1c495ebd0a3037725470d526bf12d21c2fbf4946ec224619c79906e8c87f0699be8a3621ae718aa232e26e43bf7cace7918ce34577a5e27261a4a6bdbbb8ac21a8a40b0c9682a0e0a37b7fc43306820b0db5fb5bbeed529102187fc3e5019185588d1ca6222a5e2b60faa2a93857bd7224e1e1c3c86128fd16993aaacaa34d8679e194ac0da6bf617144a2b1e844e7f6f8884df05ce1624ef1fe5d0895265bef2de61d637a74f78f6e3402923c9363656b7b91131dfc8f8f7360d14e01a25869f0f15a9355c07bba82e4969f5643519611d99ee9566138e4610712d55f22ad36c7acdc9e32b4e1e9b1ee9bd14ca122db05938840b8f47a5fd25a26072e2055494eb4ba916473e973c1efcef8dd7f0f04711b7e968d59d144fc04b9c6d8f951ab973441a6086ab6ab896f4d282793fb14c74322c7ff1c4c1c6d0544b7457635a6fe2632644344b1fabe12633b2f7d8fcb6e0929a05aeb2749fbc99671283c47c0eabe152fb6215bbc6e03d61b1ae955838a8b7b3bfa883a04f5156982ba433dcb21311fe9027a5b2e133cce16ac15786d2d44b5e4979cf2a8667d2976ea386eef4c85bcebc39b9d2dd216e8b4f7c68b7e0a5d7ff570770a20cc605e66470d995ef96f1e0acf6136716cd8a26b3b725db3ff48364f19cb2c640600d00d0d728d8fdac7b8a205ba8109318eb5519ee03848e79a1c33898555b298aa62d6da66188506638918b46926a99ebfccb649cd6bea1eb87fa6c1999a70937f51c4a2d485c6aa2bb5f98b1c8ae558e82287b9f34ad70954f8dbf3a9736604c43bc3062f8707fe88483b0865bd6df65f7e085593d5046554ee465a10ddb0c0b651e2b1031d56f5130e100e4544809a093026b88277e4e1f1e3aa40997871ced6e6eca44f183ee09ca679e4fb0796af62cec931c553ea788e75fd37ced477f9a58e54410c513fa79a4b5552b049fffd7d261d90a16f253a0782ec75219d1f7492ac2a242fc04c0216e6c804f8fd8f761a70eb747e1545313706136b085fc72dff1714ced89ba14a65a34168dc0e997ea8718ff304a962cbe8c7df8b759d76eb0f18155e49822d21d91dc8913c323a824da271f8c57d44a27be3f04991e2a47e5c8da2f0d71610be89dd4459b9a9f5cd4bb5ebf730a72617613667984d9a0e0ccf81c803e46425899b2fffe9158f9e3d7c36c2c42938d9433f764ed1f6d9c7d69e9ebf854db44c398c00b2612cdf19927de8bf45df70a5d4307e3a628a88a09a79d4e03742f89363d891b241383887b4447d0cf3e0eebe4a9143cd6873abfe2993b1f4d1b3b3a18aae4db4465385500ebef246adf17f1d9196f78749dba2b12deecc5c957e022f5b9dfcc3536bfd306a1a70e50f7bab1db22e98c8705328fedf3686938eccea04e7db4abfbdd939d56c0c357612ee3536356c0f5bbf1d428fb31c7b06a75c5b4fd5b020e6d9894b50eaf1df723131712344888adb5a0b4c07d23f6e853c88b51fcd56beefa721557256bd9978caca155db7f9c325f9564479c39b589431ee7d5da402e79ee6e04061c62c1f369176f6b35174b65a978ae3a4e8a25032d987dbaa5ca048734cc1da5f875f72db399df6e6a300db183e96ade56ecae019c4559c8f7c94899178c98e5071aece48a3e9f5a795159b2dfd0a1aa784b263ae5d352a890b7c2c6887d76f0364e2028d4f9046408e76efd6b5092590d39ec343facb16ccfc0000bfe7bebca2575b1f02c8a0aaaf5fb0bb13ac3246e245ace99f2186160a12792fabc0b390cb4c32f87c46f741c8fc940c4aa7843d650f90d422504bf97dd4825e533f646c6b77c4f004b7036b5480b587a913f05bb8ee470f0ab148727835b1659d8c046fd24276c95d30158424914e75d9b01fe52b34d5f76b2a1c98bc5236945fb46724e02851d46aca237fbf047f3055d6331dccab91c0bc20be2260086552fa7c958840843a3c38acfb24f9dcb506ee3cfc67f3125954d9090c1fcd629d1c3fc557b7d6ab33b9369ebc8b5b43f9e23673f688ffe50e6c3dfb12ac58aac60590991c9ce68502873fbdea04455459f6ee721570a87f87ae03a9f97f6e457ce1447358d8e3453632618701d62885ec4f8dd201e26405499dd7f317a8d2456940348827a08950d548b5c0b24cf494eb76dd0a51e3f5c6fda9f8f6545e3a6d1009775d78720f9b20ddded15c162f226873162a5076bc0cfc151e655e29d100b7a0d32c9c783375d1c6af0f39b51d927442386cc2c26337cbe5f4a34bfbb65b544b50b4947f72d839e6255a95fc859d6f1e34bb63dbfae1469be613472f22cbc703468d8552b9c691c829bdaf0d2e7e4093e940398f9ab8837baad8d9e4c710e4584685df01ea15ed9ed95ba9f6420e5766363e86ab8dfd1626eb1c7d2dba91d360821da99977be4642488972ec61fce7d754dd45a4d7fd9fc3498a6b7e0b7235c7843dfe8980bbd3a52c8868c1832f62d9e25a40986d061d7ca9d8fe29c7f234e3448fa315d749a09cf29556060307b970e5e080e90dcdbec4ecab1a7868cc5bad1037c07e17f961f3cb5641405f3d3c1439596a243f83b4f8576019712320ccc40581bf02a0788e3ad9cf4c44113d47f587e96061c61c06be84f6e35711d105f0c46b31f036356f6abd329c4e1e74f7d97ae6e4e0879be998a85257b6de6277d9c18980208e83d9bf266c9909a26f3e19941e728fe4ab0866d103644fd86b203029271361ea97fa93079ff227861aceb55e68d7454d1dc25aa8a7c780590a04756c840d13dfbde1d52d7df47d4146ed8d530907fcb13f6071e5c18acfd0a694938bca6cb081b7dbef2a646aaf55d4da9f3d42996a90655cb48144a4dd2789d75692530dc02a2635c26d428f2c6b66779bd9facebcd73274ebf333b8de26609bedad5739e73ed68798cf9882ebcb12902bed483bd905b92b3df495e708a0914a96840761da66379d85105f29e14e47a3e5273cc23ef5053077ecc513363379d2e6cb3aed80098589032cab7c20eeaaeb7bdae7e3a1c7a704cda4568138ce1ed94e944eb4ea72120ec91117338d0c86116db36f3807a70bcd98de03cc46ae9dd0c5fd3b26d78fed5a8b53c0c8f9566f921175fd193ec521c9914be68f2864715a572cd6b25948fb8dfbd75f4315967d5a6a707f1ceb81b98972e615d3e81b08ad5ef1838af673af9b6d63dccc226eda6d0b6fc1fd104f62b80662ff157999d7508f625fa2408b6f9ab4deb410ebef73750dca3e63d5045300d9b52845afc42f064bd78ce574ba9b4fce22aa3158bd058772ac2eadbf9fc77bfdf85dc745b529e8baf248a0bc1963f8fad78471116b9ac11679a326e92d87e03e316c90d15d2f9e3921e0bb6ab4b7ce91f12e7cdcd9dd141b8ef160e5db1faa47525a77a038558abd98757ac5f6313afb4f4c84b2c768e456f6de4a78b5b25f90926352fbfe83037f81b31251249fe52860f3cfa7ae1b20c73acb015821840dde2ff2de0470450b11aed7c1f84d4020147f8b9aeed4a37909bbb63508e533f939f23c2f5952ba6734745c51b837b72a398a4eb8dd6b4ee7648ecb55799cee7b6385ecb0b2e36b9518439ba550b257230885b83f72312e53afce7e7670b26342e4eb0a6286c0693c54abceaed1811418a9a289b4b09b65e84b3149cada8114e830c0403884ffb74c515bac074e4a981c61447ac99368dbe9cab8830911ba9cbb64633f444716f401aa17f599174581538918e88cd255765142a49412841deb528f44a64acb372498bd66f979d9189fa0f0e70e305015dcd3c9aea085cb0f1d79a63e92eb39b2dd2fb1b9ee9aec0213f3a4a848f3450e4a6d902f5435e234588ce4a7d2c9dbf60de27227ff02ee4ca19314d72674fb06c00ac7e5d15cd05fb35e973f0974a4718ea9b0d35bb4064a6280b654a15a7188c5d5a5998ba1f031a3baecdf7b608169c0ede84d91c9a5f73b0176e5ab2958169ccc6022e0c43481bb8e6217ddb1bd9ba8e8446aebed6afd163dbb6873d81afcb74b034085afec0d626b02fb10839bdf2279acec3d8f3f7c47fcc3ddc8cf1f08de8c8e120d9c06648acbd1ba6824ff74419776b73b05d797a0bc43d77eb75029112380ff4e87e543863ae29065e40c1b2b1b2d62a409a299ee5868036835627dacf4f9f7c84fd2f6707d823eebca0e8ceb2bd258038b137aaf43e0e937be762be5d3a6545e439a45090d397c8d4a068286836780536ad99cb138cbdc6fe5e9db3bd405ae6eb86084be3a49c8af88682dd52a5fa8f7fdad76cc0b452b3c37b27dc3cf66c57a4ae59a3687950ad3f1fdab3002fb2281365348cfcd9306583eb79a9555e8750dc95260a1b277c566babda92cf2b3ef177854fcc3dbac88da1536eb3c6d6fa3e336ed3a7a6da006901c845619fa00596af8e54bc1980aec4aa97bc98266c248bc038013020fdd128db0b9425e8f7e3165f5b9190fbf2dae5e317485d9d103695cd209d5d247ac7e1122bee4538b5b74790277ecfd2051e43a34b7c5440d1198a1875a0501eb3f519ac2f17553c5e99a9c83412200a519251d4d4ed1c84baecf7d8cfbfe4a7e50d789cc034a21043fc13fc3150314bd7a7801bf9c31aa00b7cbd9d0fa4ef0636504f0dab63316d9b9a1f4703b3be23170549fa3a29ec02f418d687589f77939fe068e41abce460fe118b04fd418f28edba4fe70d8fd24b38078a5c47ea236d73610ea116666a49acec52fbd810bb99af1dc5bfc4eaa634dbf2178151acc453f93567f015f2a25002eebc1f778da195b7e9cf683db1a85da98a99d98614f2c25b2237d4393f5799d06cd36254d3f22a53df5133cb1f43836991d3f7529cd260df88bc47e4172ab045b66e081940dff797b28c632898140425c3f81a60236b82522c0da7f0e0ec7a8ccdc73cee175d3b4543293135c31c0e0c926c7506920cea1d0a1eed64ede7572b8c77ade1d95bce10dfa69fab7fb5ba64055800593465dd4c26717e37a66089f550202a0530157e5274f3d3fdae187444f5ed641c608643eee1b361d78c9ed8070a85150c80368a84b14c9dba5b20a9059f1a05a60de938ab914a093b2e741e891c02f638c73c730e60ef8cb5d9e5031fdaf6918750f192ea7a76e035eb05d7556ad64a77109c5e13bb3ac7627d99165567dfbcfb7fdc7bd847ee7dedd7864353f8fdb7a9939867d9a5ff4d9ec9727fd432d8abb43628519cdb6fa49ce49064a421a89bc924cf6286fdec8bea6b5a7b8eb606f584d44c7194d5424f98576dc4b5ce7dccf65509727ed52f8d7210095252403023473af96eb5892cd3881f2e1f4dedd4c9b0755b70776aedead14e2606bbc1ea3c300984ebf27ca69f36beb03c0fe3c13d9df79791d828d52260103be72b832ba235bf1165250b608e2cbda0c9c8d3c96534802534080b2a4ddd5be4f269f37c4cde9d43dbb42fef8d507cce8b8e2eed799c72a2fb836f4160b5e5729192f088ab8557d51b58940065ceb4b48fec1873cc4b178166d15d441f45625f45af62c1d13863feaa8afc320bb36af0d151165c122a47d4306d075b344974835363818009d86c81e90345cf4b7d81786c40318a371fbedcfc325cf0e853fdfe6e91e99c07dc9430c04e6069b9e2efeed0eccfb161ca85d96298ae6dd67c395b78668d5818f567f2039111a7a0c52a21d84ef72dedbabe83f811184a95976b1a90dba5aca60d0313c546ea97d7b2e40b34ae88ccf4f45e28f05f16732d7a0d62dfd86e40a51de7f2b9b66ed780476cebeca547c8eb71ac20a245b1bf7445e64bce260b8871ead95f708974c3a93dcc4ee979975daa399055108854c1c3fe5a07046d13169c084b2e4e81821ff73d5d20e7556f40fa152226a6da48d5f86cfcf1a5520451c3c1e534db654b1a58adea167ffeea90023cc2b0b01710323177059e1c610154cb234d5ea165dcaebdc2fd9d9b66413b8a6848ea11a673f207ad76bd3ab5399dc0ed58a3ac0ac9d3c53781c36415d54b452a4a78e1eaa7046d062e3105541fec8819439da85ce53aa683aaed543704aa8210b26c1e6c8f1d1814595e3bce2d98a36089bd722110bcefd651937892ffd36dbc34f1284eb32c49a1c134ad460c19e01b3f3f2d40f664d90020ae8c546bba9ccf5500171ad07a55f9fd299d7518f00c0017f6c25d4aa01615fc7eec160ac2cc1ecd38bb0324e54cb466c3df4d56508f5239e1b392a50a8c20946a6db9220088d77c494406296921e3ac9997c34f15fc5c39f2529eb2bf6b41b0415e90cc9d7e8a83256cc59b4607be49eb76a7dc07c1ce3d0512888705c9ea145079085273f2236d5bb151dbe7d1bda2ed607fe51847ba09ea6431dcae727ec1ef0a201b8df9e148885e1308425d5c7fde473e90b4382de8bf5e215c3be357f8a2356348bab00a2b629dee017ecbd76d7ebd45fe4df2884e34ecbb86ea371fca29496fd05327c3b985a069a24a32380ac9e4b131ff48d58b1c528b941dc6290cbb41ab4aad2a55e5e03a63813c2113c0740029529eca008d906dcda1094571f5d2cd31ed79e9bca8e815e206b3ff3a7b4b82b0d30775e0b77260a42b1ccd0a58a91f0378df95cfc7f8dcabcabd2d7ae3b603e9061c1e126d00fde94b4b625e953b6b781da167c71a6a7ce0792e7de070863deaff94d74a7ab9dd2e3d39519a6c5c864036f7bcd4663fecd163d78a72a74d2838b6949eb7ba85dacb2eecbff1af2792047b036f77d488e5256ea16252257bdbdc1ca3d18d01c5de00ae8ce7d1c4cf103b2bd7a31dd52fa92d945da38eb9070d6f11aa9cb8bfaebe133cdd7a72f94f0fa067da0481dcc86e6eabe115cdfd8fe2e2c63c3cb3c0f75a4655eacfd337ddc82f770442d18ef9cf3993a9d1830217f50917153de7576917c533247a6725a0cb7447ebb0cf7516e19781a8ea8d1854349db9d3bc4e4931a1fa4fc075186dfc37ac10db1d3feb6298c1fabc8d897e1c806e38981c3fe7f252371b0e92efc61b2e787279f4a8138e7c6527ffc4092de912378ae692e9941d0b6d14354dd25900912f9a907dd970db649dd965c959e60f4d174ab0aeb7bc016735e8b847e231bdd240042aca16731926f537fe388b6496967b750a94cf514c9296805607b5f44451bc622486ff62e7af5c0d243503ff31d1c753d9fa3adecc8f555445298aa10a877250455c43d412719aade5a202076fdf080589a28cbeace5a63de77d188c1fb486d888528c5142f92e54f005239285cc4f8695c05ed32fddf0b0072bbf7642a1daff7246055cf35e077acb567b78c73094e583b9bac3ccea986305eb4322bcb923b93187bb3061fc00ee0b3d10702d7890c4eaf4e5f3da2143282dea0b12c3f043818914ae3ea98cb1322d73878b5d9920e87e6e00ae831a3b76484e0f69d35eb15b053c545464811f9c381337a80a603ca91ddebab47b72d6c80db4cf0646c579a136326be69bae46cb6ecbe23ae355cf7181981d8f7b8e16b3303aade349f44c005602c34878690d91fb7b4bbbaa75a91528fab18c3c8c1380c0c26a98dae3a2e441527e8c7e7df331a506eeaa2d299757e8b0cbba97a91f64e36e5a24cc83b00fa14b8a41e6fcbafab7eaa905c04c30755c551b2f0f1a24fb422bbd76090e212efa160103344200e83545a119cd7d2f53e8e5e6d89b1c75f12a44ddce7b9e9bb4710e30c853ac8d024be6f5b3d162941e2767c61a7f7ac5265d08a680b87f07bdb4d4e2037b99a6eeabef33b7ca6e7e6f4428f6814e294b7c08783525e1f632fc2a43dc057264bed23898edcc35493222a92dbe28da74c07c49fd725670ded86494fbce9476d3a594f4d96ccc3302a9e861933dcf46d03b7648bbe7bca88d9791b5a62694b34a9ee0d6c9d5600f0758e7e0a2721cadd048bf59d84bcd7ab33a5ffa8c1a237dbdf3481f03e6368b0c1a86ddf01b962520372bbb8e330a70cc684e84e1a438fc571ad9bfd297288135934aa4f1310849bc9c1658006eb1639d4b8ad2f858fdec1d5a4aa89259e591e2cc2948ff126caffa24bf41bf71b408da6b5107e1d65fcf37697d307ef3a3ce742e5d117e7bd4d095dfe8598213e0925bc9c8da414b09fd21451ad8f3531a756f15269614ea1ed728d3d37820c6e90578aa43f8f4cddeb9ce97b345840899a016591690a810c5773572f34b68d1f2f1538dd7c541508c990621d54dc2653bb4a7e9a1c637515538840f836d38333de92ff70997478fa7e4eb0b447ef04a96b2376d3e7319b49f8eb0b9c656bbaeb8a000104f3407e33c23030ee9d5d92a2aa7ff76f419ea3b1c9a8953b30a92759a8d0fd37b50e66c8f664792da1448f8d12d60e169382da435c038f10be62dd1c0430f18eb30af8c14512d3311a28d4252fd4b4dcc04b5da190a22c6eda7ad837e470b9d8ca3254f89a3e613ddc74c1865b5386efc7a8811e95163fc4c2a61b738bab3ce75e9450dfc38a52a59b89746cbb216cafa6faa0236db5b86747e7d9d3b6515bb19aee0a85bd4c2bfd76c1916e04db2e0d0382efd97d2ce79eb9370087b19faf4f269e7fdf64f6c30eabdef01c5a4f347dea6e28c48a55643ca36881ac5b283a9f85a56b203c3076e592779f91d3a00344a29eefcda31e2c66e38c6386367a5b43dfcb3978c891feda33c7907d7e4a501376e1786b9cc2ae1e0a60b9c0c979a0c1c96b9c126f647c3bb21abca0d4498c08a4544fc46ad1a33b17b105db91390689ecdbe0b9e6b5cc1d65a52a51d7d3a714c850c14c9329410c9efdbbd55cbc43e8568b01957d664de2a82c04caaf9e55ae5a34c533bc4da5c2a715409a900c7dbda950463131367613ddb0ae44c73625fc8f293e4002d5b704645c08098ead5a0fde1980d8addf0af0efa1288d569fa62d6b3f6227d1b4d628d1142f5eab4f7f1302bc97809b1b022e5976b32da3537a192938b8716307aac1972cc5b97019f4b7a9e5e650d0569ef4e7d12f8b123b1ff1d95d3d713a18dce009364a07d01b3b62a1f3ffe29130bee4f3b275dd27fd6860423629b181194a10ac44077eb2323e931cfdf64504a94a1e7683110ee8a21e67396d09b85237a51d824966527f9e3681ba9fa6db51e571d7d6a1d04d0f9bbd9d1036316a67ce225705018d1f0a9b9817b0d01dc092beb4e1290a7f12b22cc32697a75e17b9a93ff817a721ed0c696643353b80478a8d41e92b0dde35d7f2918f310e829305711683fc8c2119f0759e4bdca673ec93f4f0837aaab4c925925504fab72f35bc494a4d8bca2b2ee392af02422b2f80f174519fc83a06f99290cc7f1812a32511dc9fce9499947c92cc12c241923e62e98824b85ff3ea4979bd4362f87b7a89204598f51629ba1bc6d42354cb13c093d00c7da85b2523fee61b85573aa7d4a3145d518689ffcae21ff6470a8210cc6302bcce2459244e6f9173e1d9447726942749fb6bb13bd0d3479ac5f1e6d70e104990f2c9311046798f906aa215c002ae0b918af3db1bc591a937d5f485489a132fe9098bb77387906ae54d92d368ded939a069d0866279e0f7cd815062dc25c664c168ae4a11b9f1fedcaff8e3c37b6f7b075e737354074381a135291383a35047b1dcc7cf3b815c1b7ac187a4dcbf64fa5ef83c4fa2c0b4f5b7e024af32ab5d72e4e86a92acf858ff0aaf0fb8fc64fa12d0733c6fc530ad739df51038fceaa88e6e47fd80a357f501dc4ba5de4b6c0c573534a84e5aac913bdfd30e548c8009f06e7281d4b91b968852033af7b9e79b644b1532b9324b9788ab6ed930236c5bb2de248231f3046f490131ac34586b43a3c8e0a73cc756a816c79f3f10f12c23501947b29617fdc2a45c7f361d27966f73b1b3a1f50cb0052dcee33ce739cf2da8fbf9b7e5734c5a7fb8eea9f5a598ec6c207735409ca3401894f634fc787fbae311d4bdc8c99e8986f306883d7185a18e71b5166cb9b84cdaa3cb03231ac3053beb31ff3d87838e53ef698f9921a0ebe69c9b1526ba5940bdf21fd745f6f2653adc2d3c36340a6dd7c9ada045dfee2349e26a62b437e0c8f4fae2c7eb9eb577c20886d8a8fdbd02d245c1a1478f52e339e8ddd71fbc6d2cd1668a44e2c82b311720996b8da7111658a04f4b756d84418ef3e99713cb73d87bb4a14f69d5ef4a8b8cd6d0008164fa0a802c0679b26e155d801b40a2c77453dbdaa5a582d7c9d967e8a5706358c68c6da6c3e6746f0648401f896f1674797b0e14b354c27ea94fb12ad6d8494ecb0eca0eb5795b1920c618b429b4e95979174fd21685ead022e7ca4f87958c8a101b8b3a5e0a9d64393395b12dfdbe7e7503b62db0fa8813c4eaf1ffe5f190de55e83fc3a01b10a647d77cc49b07a258cc4e65d489451f849f6aeea5bde2aedd8e184cb9c778a3676dcf87d2bcbc19647bff28953c5d06fa73b860a16785238f9765c0fa958757b4791272cd8d1fae302b8dc47282b782d5c4c5ae75a9c02a3e911a79547df96d2c2306a2e347e83a8d8a126e6a3a21cc46e476a706af9c42a97b3f8fbcc0de5cdfb59bd6cecba11bbb93ec1bac6422b61277eccecb8b28b3d97f0051b89997c8c22a9f517d9fee5e16606614fda11940cf388c04daa1b302d3b0590a9bd0692d6139b77546d71454054197adf346bb94b4f2e85e502e3cd919bb43e8b424339e2af0e7070b035271783b1d7d48ecb6e63f3597d08a9d0677a44c29948d9cf9570e7fab1ab0d8262bb963d62e895c9bc8ea999f6f8770ed5ebf75a39dc0fe2eff88d75ae19690e0f0d52090f18bbfbe39697042cfb5293692f1e66d76aad38bd919b634ee20000000000000000000000000000000000000000000000000000000000000041187a86f715ea1475c76d354d556242c15f6b8f7c441cd862cc7c89d89a58bca02ac74c422eb01833db93e4b067e507da65080f93cf1815f4cf1dc0d53a2802230100000000000000000000000000000000000000000000000000000000000000","nonce":"0x190ed","to":"0x91a5d806ba73d0aa4bfa9b318126dde60582e92a","transactionIndex":"0x3a","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x1f02737dec59ce5f29b7e11309a33cea7b370eddefa1a8007ed3fadfd1c6b23b","s":"0x106ff6938ec0a46da92e74768b54926633945ab503e2f2dcb69469b544907586","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x2d679b567db6187c0c8323fa982cfb88b74dbcc7","gas":"0x5c90c","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xf49895cde","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0x45499074aa521ac4151138f0aad969bcc2dfc1648d22ff8c42e51c74cb77414d","input":"0x003851f8368551cdf133121c7cf32ee5690000000057b378dadc7d07581359f7f74c422f52a4d750946601a4898820282002a14608e24ce8d2412c889246951210c5eea0206041c4025828362c2828a8a860418a28208a224185ef99505d5d85ddfdbfefbb9ffb3cd964ee997b4ff99d73cf2ddc5b063a034cd01e114eddde75618857bf21dae562932ea35bbe70493443b0d3bda8e6161bdf9a2e6e1a1d63845cef77f151ab3e17f6819ec2bc7388893dbbbf49e9f0c76d8f4e3a6d5cb9c46eff41ba97c0b3794c105b1a891908a7812b16b0d1d7780802e8c7621a188764369f6bba1bb0c95c54c4e3ecad237716b875175c0e27d3cb133dee5692910d9eb1ceb4679f65e7247f51ad58b4609f4c41fb91c48acf7b7d2a8532654b741723ce4f70eb38a521e9948c62bb5d73328e2aa5e7174426f5da2a4b1c6ef04eb66b2d4d1a48f0a20cd3d8b6bff8794b3975124f8d8149ff9c0b714da5e23b8ff418940c5dadad787c4298fc8486c94c44d45593bb8dcf6cbea18578904b0c99dd61f2b7653a1562b2cfdc3dc96fb15db01fd11710145c7d6b0957b60eb6fe886a047920fc64a496565e715ce7ac34a51a8fb632f62680c9de88bce189d008e29a23679115012cd789ae2fdf6cf5f4dac0cc4aa2e092b846d3d3b36974cc62244625394645ce73c1eaeec885e6dedb131a1d420a57f945698a9e7c57befcea025554af9a4cf6a432908061828ea86605e8ae7ef301f4c388060625fc5cded2d60f4bcdd4270b2cd05a133fe45e31ff72c0fb8465065d16678ff60a4f2ebf901d2403345bd6c4459c6c6b97bc038b3cbf9f0ffcbd7fe06fca91bff93e504946e2051d05e23e28dcf2d35dd2d1c2b16da8fffcf65ec0b789efb1afec71cf481e5b4476b7df95109b64e2c1950beb3cf3ec9a671ecbebbca59aade6ca79f06328bb06669266f9fe9a6673c50f5aced1aabd49947341ec338b82d9ae31d9fff59a0511ed938e016432f9c5a001a7d5d34b54a7d9a2419456e3bd0eaa860ff52e69806188aec7e559a70415ccb6653c885fa17efcfccdb680026e43c9ad0bd5b379d4da2127d429e74dcb29f3e45b3ead08e1e85c2be6505fac13244c6e528ea261329310d9b80b16bb7b562d9477dd95f6415de5bddec30bbcfab9cb9bbf88e71eb47c16df81087fa93c4b39b5e0e1cbad17cb1bbae73eca0e2c75f73e12e89371e79a4d42babb71e9da013fdf5ff1c20a45ac00a02bf1ee09b0efb1254f4862526e5abc8cafc311bb27abd9af1464ed617acf4c1647dc8765d530e4b40fed95768dcfb24a0782f32fa6cb29e165a5745f2b44a8875a96812b99a095edaf5afb1144335625ebac2a489d9133676bffed7d161671de594b27973fdebe55eef99d65ca83e607ce6ed86d32efc36bcb4bffeb2062a99371c93d2eea8a0f47519e0b40ef21ee8d9de5e8d8da61657072561ab1cf9a4b1d51da9926a2d934cb9be7a548af7a5835758b5164f249ef0f0b53051779089dab29284dc10c24a1ee298ff1faf3aee4072cfd4ca19520b23941a4852bf56dfdf0eb075ff435f87aa51ebedab52cc3ebcb4db9e133e57c2aeb10a836d1f5484807f73a9d411e059283bb45fc028cc8f919abb8ad2b008ff7a95ca576c0c04aa4f243f10d2fcbc425ce014f5fa6793335650b99beb722faab1bae677d9939a02d3de5e0ae5d5906ba024cd019c11f0d51c89e73b8cb3609f7faf3d127f969f3beddda1a756fef93ba1a4d33e4c3992957a9c304394b7760063250a5519ae83b304c00fdf0a21e2acdec12482b724df3ac5ea472c065a9e2b7c8de28454d72ced29d817ebf3126b6928c2cd7cabbf0cee395489744896faea55699fc7ec581ad49b782e1bb83bcf535468b91703bcda0c48fef1e919dbbf30aa45b162c92f0e01496643bab3d9020b8e471695769f04020557e8d0fd5812bf346deaabcc118c92dfa146a1b5fa6aaf5db5e6fd704d073d9c6d549004066b97db487f857716ddbe6cc6332f7ddba3ce2df47f0f25911e833adf8f345677a96c7223a3efc77a3f7a5d24e543525591d1fe4afde76a4a3fa883efb81fb9e324c5727a5d2e7c04013a249366aa8f8242373f9c0aa55a7366d364b0bb89ca1da127046eea1de1d39b917fa53d6acde40da381a71d342e3fdbb19254d7df86704eb979ebcb905762ad78a852bc948b97aba45e99ea4fd7e0340ba70097b4884abc81c20e99276eadce78b6b5f075620424b9a83af6457cf29d9fa52b6df6bb7054711e789cbfdfd1bccf3081ed96225866598328089398b84ac237a46aeb513780c62f5ba256d9de6392fb333debe7b2ebf00571be5b6dfb5298b68c0c4f8a281db7b5a819b91297d29e586e6e78dd685f9810e830dad91e79459de4f2cc484ed9cb3a49eebe9b51975dbedfa1699e3c2fb9cd6a7e9ecde33677fd57e07847bdfb9bef75f07bb9f55f73c695a97ac188df3280a5e92f0a4f1c4adaf8f53bbab4682a9dff482e9cfb43db9dcfcda1a466cbfae58cb09a97d8336c88b124bf1cfff8a603a78299b6e6a9ffec57be9c75d73fa3a86049c56f127d5f3a6645bec138e6f9ee98510eef2dfcaba7f894ce575889ed3c89b3c1caaa37f0901d49f7ef9d46c955095899a76feb44cab15d918d6f9e924e77ef594b9af6e7a2bcbd2190758bcdc73a2cb5f7e25e9afd87f893b653e7d81b294fd6e0bfca1f5565a21f725312a2108c950f275a4c0a698ebabc567bc1d0e7b1d74b027f1dd7187cb584fccf0206d997519a61060628e2255ba437bdffb3cba91b64c87899fb19b5790ebbe92b0d55d2b0eeceed76d6e91aa53c6ae2113e33e299d531c4fe70c696050e654c13387f0f5a9006691089779741473c7c7dacc4503fe93cbf7565bbbc4f715dade96b451a21f1e36920bdd10f42f48946f8ac56ab3afafd84800b2a9fb6d643cb17cde43a619d7ceaa915e6f5d209ce489a8b47bab1eeb9a93792c6dc3b7676dbacfbf3e3cf43e2d68c79522b62530e423f3ac341333908eea556442afd4a7035384916fe5ea257e3af6655cd75ed06f3498afbed542b0ad0491373609b66dc14b70fb96868a8962a2d7ee4d16ceebdbf334a8758b9721bc879a8ff8bf9f2fbcc6f63a9718a35d8b5df1d6a38bf1c6123b43566a079d88b94f3870ea1b9ad8d94d2db14bf12db3ba58dee361949713c756937de91dffcef9fabe2f9714589d51e3a72c7c896ce9b1fde893f5ea895975986ed8766eb7c7598bf7371fdab658e7bad069a9b52f9e9761ae014c4c15c25b1f98e3e0dc1d831cbaddb6f4d3a993f2257d61f345b3cec990f79d3edeb2f5ea94016bc4c4448c8f9815e81b7433017a719d074003d7307e3d627653f5cae3753642527b0a49b76bae643e4f0cb4fe00bc7b71202d6b1ed7329f6ec4ae64ae463ba7cae1375d3ae4b36741ed88e3dbfc48efbabebde8c1eedd487fb8a9f42b66808936bb6692353b37642efd113c62f14a711f42aa00a0947ef974dbf1c9455e3c1ef175af9cbd8bb729f5a7069685775d8ba8fc3552e37e8765680a58eed27db682227eb6f9f12e9378bed42d4292a77ca86c2eb79f2d289b557e5be66535a2f7bef852cfa2dea5d97c52fee7124916123d91d6d6911564a5c2be40110b99de71e9d9a6203de69a6f7b57e54fa4af76b82daad4021a3fdf1ed0cb5f2118646dbd38f2ff5c7a107967eff06986db9e2bb8996f3dd20b7905cb8f091bfa1f9ab52307226009181925c4cf729b64c39add884cc606b5cd0ffd92167e5871ca3b85b0eda19eecd1f3876fb98ea4b0ba1df9cb8b5e5a87dc74399170e34ec1a2b29df609aa1f86f24fac697de3bdd5eec694516c5c59c6160a30d90211319e50ed9384a8c8e316331b2a64f65a2f2f72b3793163870b4fbec75e81af7d4353aed284c926575a821938c34a619bc75358126deef5ca9fe7b0a5e69b6a7c19935505c73df8f2c06ceb3c09fabd79df5e67c5f209579df95d20ad0491ca79df3ae257b8ac3e95aa302f84de6fc847c8cb147bbef136f355a240aebf1d19e1db26bab8ad4c6cc6d6e27c92d0cc8420e0f9e9cd2bab9e9ef2196e07f04997abc6c1054e015c72da67366699fc045c21974f9d6433740a3abc30b8fea46456ddc7c3adf8ff00b85cfd8e8b6ea2ead437ba951d6d5c6c73322d29be2a35e63081d752933b7938c212b1289d2775222261d18633dad1e73e5f323ff2e0ecf36784f52179e6bdc31c5c19616886a139ad0c632e47d0d32d1ba2ac6c0807fae7bd766ec53b94fab2d2ff22a93483fbb6445e72d409a398840f476eb72f1a0ae8143b70fd04676db9411782f83dee540fbe6aa82664c779605bf155030785e13d8f0bbf86951c62ecaa7e25881f491ef1ffec48fc67ecfe2b9247df77673fee6cb0f66f64fb982379d6deb13a79a3f893488596938b1bd7369f9b99832c4c3c23b04cd34cec0dc5236c4105ede9dcad1943c5813cd18525daa70fcbacda879ad6675aa6bdd5174f0b9e9b6c53e67f7771408aabf9fefe79e92c5e8a6638ae8f1e38b621647d0d51aad753ad3b5a5dffd869f18bcb9a8f73c76b452f45c2f8ef6bbc39c9a479bd1c66bb74f6e3f555db06f55a1566364ace5a637cabb4b6b5f422305086e8542d0ebfcdfff1d1e7ac9d2deab374165267cd49df53bcfaecc76a6139337e9fd029079ca503816826e13fb54ca2dd757e147bf8cb7d793ab299cb920dfd306ab4654bb7661cd83814994236d8b50cd984ccb5d210aa54dc73415c96b92d6079d19ad0da60496d2b64f3d687b8cb154565602ec004b311f96d330f172d255bc6f0c550afe9acd9927abfc7bf67c37ca527edf3f61625f6dd9d32ffe64cd0b10cc433411bc558b67cf11bc09f8f4d7f44bcdf6395fde7ea9f70c80cd66aed764d8dd0ce88679b5caed8fc9c2ee8e32d2ef5a8ed9efd1e418feb40aacf7f19f16c9a1b35357f8bf8049ea7fb91c7ba47d670ec211f547ddfac75bc552f487263f859af5dea16f91baf2104b6dac8af88eefba672312ee7fb9f96886ca51ead0fda9213f8aafb5bc4a7840f65a01cc004a510ee5ad1dcfb0fb650b747acbfff26a26f568544c0d24186f8ee4b169615fdec32de53b6d3f2813ba5b7076edaff3224797d524bba359d90f417140cb222acc5ea65d83c0e7bab279f4bd8b9f44e0e7c907865bb83d3ededf3f539ee85c3420f10ebfb0725fd91f3cd2f3cb28d9ea9911fe136e6acee0bb05a7f18bcd4b5caa9784b19f63dc0c47623730f54eb3f52b2610e9cac31bf560d29def6b778e3a6512fec915eff7cb1c18981292bc892893d581a311046dd9c132b6eb9fe354075e0caece17f573454c035ec85e973988dedccbb7041ce2801733da9f782c8d85491ddce93a943b1b647b41d02902ccebdc3c82b7901adb91cbad9d18b7915866a1d9098e1c43de52e70477048d02ab565547ad68c33c7138d30fb165f1e5e76a837bd74a4af58fbcf4e34203d0a1b56be539f2ddeb3706d3f25e663ed919a97ff8abe62a76be6bc6fa6e61aaf2c8ec01768c7eadc9bee7ceae30c31dcba975d6b558ea932e22a71a5c728d2dce05067b1d4a27dcfe0438fefcca5cb4a95efe83e63a7dc247570449dbed353e7efbad6ad8c981a2b47de139ff5bab370c969e154b9e4f07f813a9310a9c021f52b22829622dba52fc47814892fca57ded9158663b293356decac92b391c56d7ab26702767e30b9726aa51bb16b79ead28fb4e00b815b66ed75006e443a9e41bb5ead6975bd3f8326cbb4de758e7907ef62dfdbaddcb7b1fd85b3785ab27cc0128d4a8f0306ce3c92cfe0f708ffdb335bf69c55348e88597f711e5d35efb6e05bfb9d266f107bf8497e8ef403b791e1c3f23d6f83f7c7f2c7bdc63776dd4f3ab24178e30daebb616cec37cecfc9756e2809a6d131c648f88c6eaae019a9c3579c6287d7681f8b5a24bedd607ed629eae12f9e2bdf55ca28a01ebfa2b20cf30460621e22b49241d178f5884481f3cb5e062f2b5a1f90e4a66da24bcd9328d9501e5f7369ef94ab5cc9c42494d60edc51fa6d5ff843a8fd5d5ff89743ad44ca92594df4fd090a213696a51aa7c3845fb4d89b7c8ce12a9e57ea61d3651b8868e7d8af070f78ec48dfba75613df791126e81aefbbeed1911f5ee74eca37da5f0c478e8d9d4c6433984cb8ffef678888c982b7fdbd36c736ccbc9c74f65d3b6659d3f23ea63f6614974a4d62507951089c22d885256b29d96a7f196cdde15515ef5b95bed572ef4bd1b712467c7bd67f96b1674378d8f87a07fe35443630157d419d038c7fbb0486d5ff6dc908db1319271d24b7d8ec8b0cd7fa16d812828368871866b96fbd5fbc63f5db2e85991c937e1e7fe1dd93972d9013b5e56e69661f40026461bc9fde8a9a46f19da2be783f9f07695579e22609fe4b6252ef1ddbc0bbbbf687d9e316570db32c1563487f09b5e0ef117862d5301762222e99860629271f05b8d38d06658ead0e686113b9aa67ba89cb26bdd3e8fa4d64244cb955fef548f69f9c5059c0de748799e245be3b9cac822e2927319db667124ee46639bc3b462dbd6ba6f375e94842e4e5dfde5d409975afdb02d03b52c27f33f98f745c0d9ca2d2d3405f2babb8231fb446e87f1f97b776e3e7a862db3fc7a05512b633f75ab70bd7244aefa306fe9c5975202ef0d360dc8b725b06b961c6257d02b4d1c8867d3a1817257a7c80adf3e15ac7108cfcca555bde972db3b1bcf38bb19b35839f0fad1166f936c23877501f220ff81b93c06ad91f798214b63bbfc9e9cb6af0f41548c3772da35590ca55d22b6decc5d1d7b3149fb5e71e09a40fcd997da77eed62a8d84d9aee853c68fcbdd79b210ce34a9ac25093a57572d557d47cfeeac5beaf9eaa9e0bc29c3065f59c6190a303903918dd88b9b4c7624db2ee1b48de9cd4d0ca875095650d5c8b5d903717d33bc5b1635e52a1d989c72e3d397e29367db456ffe6afa124496a6f331d5243f40dd192b1a2e230badcf97acb3130f5e2af588fda4bac803875788d425867687a67dfbbb7da5fefd9443c7b565b79d3dd9e669e76d59a797b3ed7a1e3a580b98da60adba5c7c71d0acfd5bde9ab5ccb69fefbf6915976653797ef913ed65260a5c6286eb11e962d9358e3bfa3c8fef1526293c72e4bbba4522a7e07a5f6da6012775d5b1d487283eb5ff89e5b024e4b918e98ca203a0eac6bb26a5be64bb478ba936f1b410c298db9260f6969ef4023125bdbc7db8b725cf7e4b69e0c0bb1733f3a4ce5f6b2eb374713fbfd4f488c5d1be324c038689a943154e1568a3dca5823234ce6c5c26ed2da769d0b1a78bdb4fa9a71d59a2af1241315f462ec378dd24472efc8d17937fe3e4bf89a2987f3201db5ebf41726d27cf6c26b167556dfbbd0c00589c8fc1827fab8ddf45f95f76efec6f8d3ffcb2bc9754f9ebf26c935f967f74e5fe0d7f18c35eb6fe9b112b9767b418c56d9ef750f7725ad45de079a5d42b2569d5857cbdba2f426619e57273da74b5cf5af951e76b3dfc6843519c8e6ed6dc7b8290fdb0b1f7efeae73a579a7cb26abf03c7e7e8bdce598e578a5a6f1dd57f77ec99edba37793aef1fee973cb8ae75cee284055e15d62e19178d3707522ae7e3ee9ae5d00e9d4d82d21e79578288e3068737f317a7c865c4ce6f38eedfa4502deb116b7735b897b77f8d41b7cdb7fd07973e715eb9995a40986da462fa51b9e682506f2559526a6bffbe8b6f6ebcbe97568679806162eeb1602d386302d65aadbb374419f9dd1e08dcad0467c5f3e96934cdf94fc11a04ff3158473a8a7e3db77f79c292f017ed42a28ab2ff7d58f7ae65fcba3cb1ee97e5ef3feafe1ad6a4dfcd1061fa5d171d2f21debb4a99b5ec48d57adee17b492faac44efb1bed06b538a30302078e9e17bbb15b25d3ba8a4e9255b1ebb3905ab17ccebefd6591d9feea87e3660fe17e57bf9f60cf0992dab3aacb619b0902162a967eaa4709aa8b0c65aef4bbb2a56fe2695b51f950ea8b5544e6fc4d5d81b96fdccbd55df29cbae1ac667efbf62b51c39c6b2ac9c839cf8f85c7869fe8162a5f6a3925e16cea1e6cba00bffb4863d8c73c355ead66692428b3a88f939c136818237f256159881265b37aadff156ec96f73aaa3b7f8783f2bed00065a914715bb57d12b5f65a5ddda5ea31c67d9b9e6d2aab2c0a425ba857c471fd552097a343a660972b6d4cefe7e3671d5d34d5da54312451d414f00d3944635dad335e7f56b00b30ab4c3751ac81adfd8c33e950db63ff44c85b901983717a35575561570ef166c747d3abfb8a112440aeed6cc8f575a3d285f3a6c1c163bf745b4d79172d13da49263bb2415b00f520d118b3767240e1dd82f7666b352989c7a6fc8e7dde6c5ee6bcfd79e9ea9bf4ba342865886f90c30317d88903d4fc501a706f9b7070c15ef543ed850963cab079ef72e75090761717efdca575316d58589c9fdf9424ac0cf070ef2cc885b83e49f0c1c82e91a1a00b3ac246599bcc4db1ebdbbd70d956efd071652cc5e2d14f79a0f78614f7fb472185af9cabfd138b7705b9f9bf6725e29faa5804f8838a6e5f5ca00385808eb2ab34363ab50b2f2f9f39233eddd4e463d18d6352ada86a61dfeffc4424a22b2986f9791436fd96cc3ed2bdaa399b32dfad71bdd1e36cedf2f6996f6c2b6ebab2bb2ea4bf11b2295f77d0bdd9e91295cdd23ea548e8b8839e7dfec6bb74976a68232ca8be3b478f1bf6ce7868db922b5bad6f87ab1e162b27256ed71560a54aa622cdc91785046ee2dbbb4c8f220a9334b8aa9d6bbf73fe724f69fc8a0bec2236e0d39769befbf3128e88811c39d55dfccdefed9a8fdcdaac78c8df18882b467cff80e2ce569edc0fad9247625883cf6577f16f08d9efc2ce1f8c3976b73e789773f6c32b6d1baeded08ee286e68f046148b66e61ea93da5735c56a5c956b076d067db079b76bce5add735a078b5db7ce3328c04c0c488205ee15f6f3b81b559f9bc83df308fb6b974bce453e894adb0df2061d8b3c3cf62ef9491bf8a095e1fcfaab174aede7b64f4e32c0d84737f9d559b16bb8b3acccf662b81b5a01d5f8da95ea91483152a4c93feb61db3f5d2aa8791009f43820bce2c1076edf0d56a31311c6c40b4bd9bd65764de5cf8e886805e3c6d64d22ef09f9d03fd5df9ffeca41dc983f7d403e190d873607781e2d756177c31b750dea08658fba0dd215e28a501096dfbe83e5b51e068a650ebbca797ea4508fd1a570e3cc5bfa6d46fce6e35580e9581150013bc8004a93d12b222cd5dfffaa8ecc66fa9694daf5e333b4ceb24d584bd67573d34f50c9e3234dc9860d0785084ff75b32920b2539af3f26d5363e70b94bbc71615c564d61d5df3527885b8dae59373333db7ecad439655a79c12b0c39c0f552cbafd6ef742e2e682ea274bcd9a5a7a7de6de1f7a1ec5561a341040e5e75ec0da406ab741f458c3a11bf714f23f730c19ca32d78af3c52b6d79a2600b698e2c0ac8dc7548b658bc4bc3f975bf2ebfdb916e214be74fcdd8c60737bbd2e5bf68de1e444c28562b70515cc9bbce2cbf911b7ac2aa18a20b1dbbe556bb8e6788921c34285766b410601ae9221fe28ffb48169cac5e277cef909925dbec8f8e3b6fa884553a865f085fd7f9992b75ca1674672eea28d37f8f61ea77b3a6f29e4f9aca9bfde138995ca6cf80c89089830e59940400420408207f23e221137b32640242260e64084b718070600caca5ff4b6d531cfee25b1408cba09000202d9d4102b86a5c887832c4c67a923dfe048f2701c05512009492009007c2494338191722090085277d675b400280c724006c1c7b08f19000a003ad85d7cc85e8c9fee92540028001d6834cd63b2f27dee7d7752142c002069e81fe1fe2860086130306011e065bc4f04ffe8931f014940a25a138517e4a83911463d07efe36469ce18cfff95b627ff23866db0bce7d8e62ae2233cdefc8d7e57ca04b5ac564291e7e72f2d5198990002fc20bc8c41eb5413a9671188f6749213c2acecf2ba4fefc319604601c0990897d0cd7954dc8afcd07b1812400b3824102f84c5c88a3ad7f2392008c2f04d06824006b3ba662328481002ad589046036a326e023b91033f0780ac3194f860032fde7ccfc8986507431589f108063550b8ed6f527cafb331dc4347f703821dd7263afffe522bfaffa29477768e4bdf7bc9a2da6fac9cde693d2e97734c8c49e0460e7b1582e1c97f13009c0ae181531604c4454eb2400eb43633d0e8570d224802f4a7cb40c3ffa4102b0092c0a367f1605bff608c59fb148fb5333615b0924007b974a02d88227908c7d4602d8ee4dfc66f3fa2b1060332190003675daf775b319fea16e4fd6a7fd1fc948dff144fc4e7ab6bb103b04d0febabd4900db65b4c14f130db22f1eb701ab893e888304b0759000f69b3f23421542fe5b3c3831f0e90c96939100763b12c05e3f5637034f2601ec3e7408004900fbfbb1c782a22480fd2a810a0120854186408a1348a63a93d3f1780864601910e000e12000ad9b918efe8777a64220489d1ae9886a2100c2388d7a3c0960ef82b8480087f908c6f4c54799639592a96427061e4b0238b80910c0c093008e252e440a04d2d0e72480439605f7db2e448a134590047068114800872609e0e770211227387062e089a36aa0400038a1148afde8d7185bcbcd61bfeec71d205388cd015286806f5323571c274725a6b231f01048152393008e06021443154bc713211c559082caf70665bc93047024bb1089e3dca1b17b54867196211c244f03d9c67f53a9d20c7c46faa862b9681812c0e91433fc9b7f5412c0298a828d138aa38d7cdf81274bd2c5b6e3c9716274f10c3c1ebf3d63d45c14c6248ec6e1c479820470e69100ce6c3a09e0dcc8aa8ccafadc881af00f6f9000ce9b6843c9acaf2f49006723cac31917229dee440238155d885467fc68830c16d10009e0ec44bf71b153e8681be5a3be49a450509872cd2590002e0508402bea71214220054451c1c53b12e22079aa104a168d922da790008e5e566df6685dec2e440a08e1625915c1040a038f166d22015ca1b123c534904a02b878d0bac6704ba5ca4ce89a0470654380241de2c290002e8a0b51924c134bc74f2ebf88864fae5417623a9e0a613054f1b1b74900d7232a09e0707021fa8e9984c262b60f65f60309e058ed4244c986d19e88e302fa0a371f951a4b02b8b44660c0c043f2342108a48890006e730204d0454900f77c02351eb46749c3bd281695a0d08518e78c2701dcc7509548d2c54800b753dc883620804865e9927b2b819e08da539d21900aa6e3215c2c98898770230ae526b810e3682cb2032c3212c0bd07924f14a38e484773c6132110c22460c004d486a8ba581a9b929b084d72130a04ca8c43874c4dc7d31868d5b1a86a784c09e4383696967824092480478204709f7621a2e562e8433502998a49c713c9140cca35cfc25812c0dde242cc444560a2ffcf1c43349504f0b813209674bcf35d881412c013381a6258bf47d4ca134b8030ac2f0cb4c1eb28c6d2f1a334d0309dc54b2e5a9433ca0b0dc2f0a4e3e92ce0f154a025e5a325a36fe1211c4d100617d004c5205bba20c44b171413172501bc00814ae561e06923020ea2af32475f1d799304f00ad0e974082401dcefd09c8481a7d047f4c1ab462001bcaaa3e414547ee2b8f742c354b1496ecb8ba78eb8683acad16a1a09e0d5436b2301bcc9bf0d1ba81bf2ac40dd7b02e5bcd9932b2ca48dfcc8c053a91812c05b4e192ba452d9e82234517112c0db88b2fb684c31635551a90e108e0a8ed51db3ccc14c5bd31017e41fbc0eb72e04b7cecf1b17e51d1e8283bdbcc2bd23220008a0820ea34cf0a942f2a828cf47d8e0d3a592005e14e0ac0ac74327fa8342c142000d7420017ca8ddf92427452b12c01732491abee849d2800c3c996557be2c0209e0db39cafe9843f3e58f4a4a75c04f6a8d04f05d439ba39300befd2ec409b5f1354e6ea86d5243589447b4217e006d68f8bb86a6e452dae32e05ab5b934900ff32085808017d4363832818101c1b43b1e909c2a00d010274a1173264cf5084aa250403570864cf5dd2ca754230103dfa5504c62204b2670ee1f22311185b47207b16b0efbb2002b30104b2e7e3c7c9ad22309b2681ecd94cea361681d92002d9f3c3b757db4460360601066d5c8823958bc0583602d9330c2f714404c6ea10c89e9b6a7c192230d69840f64cc9bd4d1481b16e04b2e78ec6bda62230762381ec992514e6260263778e55b310bfdd5e08064509235f45600c1f81ec695225202902638c0864cfa53b03fd4460cc2a02d9d3b6e5ce561118b38e40f6741fee7c2602637208644f58dbf998088c6918ab91e3db33ac080c3a10c89edc1e79a74560309440f69410e36f168141546aa5d270f46b3981eca965d4e62b02833d04224b8330e806b31d6725dc30e89bce80a59ac6b3ef3e220c26416c643d2c0564c0606c3a0396dee74284d98d47e9b3d0279fbfa3cf87d9e1d1d2b3e90c5846e1bbd2c689daead15223b4b68051fab61f6beb87d9f78c9462b028fdb1c9a598d9e3b56114c6793b3c4abfe087da302e13f4f6e3f44f5c880011c6844f9405a12d5d47cb7a47ca5227ca12c7dee3601b6d67ef0f5262ca27e8cbd219b0ec4e947edd28fded1ff9ea99a0ef4c67c072722e44986b548b982f3fd48f951ba7c74a8ed3378ed063357ea43782b9712c49b0ab26de741c93845b67a48c04733b8dd61182d6eaf65d1d64987beb6869ca0f28c11e807904476a393fd1c2d9313df2288dbe59fd236f6f26e8dbc638e219e3e3f30fba62931aa767131da7bf3d42cfa6f223fd8a09fa65e3f43da3f4841ff8618b9aa08f44b510e94284794347e9e37fa43f3a419f3b660bdecfa82e2008c2929d60b60b0c58ae151d98cb83108e9cce8641873626f60c0a6b0e27239d41618d76a8286dc728ad28ccae432043f282303b3701060132cd890d4373488770603accaee342a482e9e3e303063a7c70604020c8807020992604b38b13a80c2c242f4605d347b299b11109cc6e05f32f43bb0c98dd85121b0bf3db8c6605e339f8f8e0860cb3af1f27a6c55263610131d42b52636363618143a3ef4d74d4c213ef158ebf578b36c25e199bc8d222cc7e2b9d01cb9bbb10ffd830ccde020b4ba0ffefa25261e19d233930cc01c2ec5f589551e1995dac71276b4c0973d8d3d1f16dc25f1f5bc2a26568ef958ea7c01c7e0498c33396e54430c75a172299884a35a61298232696e59074215198a36aea933630472903967f3369ca06adec4e5c1c0b820c3cccf1383e8e256c8c59ba65ef85ebd45b9c07963f6cb9dc5bf5aa14f7fe507a917f63827a45f2fb94c7f13f17c953e915dfb605898971494990897dbce7c82ccc0be991e63917efdc91b93d239d01e308683281b241c3522020deedbd285914e674272c8600b2f162b4af45610299d82f86e42521792a284605d1de168f429b938c56d1e9421481392ba7213e6709035648f85e7cce5bb058214b78ce96044d7a22ccd93c0609145e10401521c35cb204fc9f4da6fcc9d493085114e63222c05cfa09b404984b7bac521435309703fab13c217ef4a77d0295ce82301102514befc8c48f0dde34a73585230273ed274000cc750fad3697d5f9fd360d85b9ead219b0423e3ac81f1f2dfc23f32430b7ea8817716b43002c76da85887e5f4e85b94d584e441b71616e3c75d49df0539e86455d1b82d8c84e3077cad4231a77d97844e3e1188968dc4f7f88683c1cbf8b68dc9d3f8d68308fc488bc3c38587cd3a4f0c0b3800e714cf2701e2b02cc63ce320fcc633de6e063ba8779d68c062cf4d5206a1c2b58a1a319415198a7781a88e72960c08ab693100ff35450e3e2e8d8d1783739ac90619e87637192e7156572501d23d19cd65ca508cceb310d5e799d19b0e2f9c9bcf2fad168b078ede401120442c0df9a34fe7ba81eed1c788759669e6648c0c27cc1d3d0079f3703565a39591f7c1b282c274259e08ba5d16830bff6f4679061be5a02cc77990a8b3f42ebb9054ba8a3fddfdce9cf17c3fc9204989f8f365213bfc8684d73d00fc5b1a71a230d4d9e0dfee3bce1825f2e58fca91cfc17a7a14dfed30c58e9d977b17f9ac2ced0984673331419b072e8a4e6c8287263ff0e72ff06ec7fb144f227da8d4926be6c7bdbb58578cf2e6ce916397a5f3356a4f273b19a1c11c773a3fa4ad92c1a9a810a707f9f811e1e352f2ca048a78f06addf763f141158601f8182c63681d469a8582096012b374df60f81bd743a7d34b611c73ad069824a50681a2c087231e059c17f075482e4e934b78101cf06264b2cb80d8d0212c6a3fd4cecdf0a6e2c13084d477e212e063c3b631243acd92072dcdf442a049063ffa185c13f513cfd2fae0bd251d40b0dff01f5b0b0309d4e87256c5d4651070be3583de9cf5b81858d5963db3feb358533a76102e16d0c78f6d02413fc85303e937d3a0d7e65c02a6b278370a610048ca2706cb9179ea9349af0fe4b167be1990d7f34eaccd72362d98ee5a5d3d4aa08711a5a157160c02a5f276b55c4970a01937c9bfef77d5ba47b3a1cb53260d5d41f7c3bf6effaf60840b0a3b69c667c9e9a838a227fb4a5e8191a048c7be898468560d1e1696844b49f01ab0e4eb69118272ce138320e17b39a464d62260c58cde7fb81a8181c1b0b01202ce1c548678c0c9c59393f048064d48058586c2b0102c819f80c3c1e16cb4353733a0482548a13451016db4980c576c06a71dfafd4b2888919f80cc6d84ae0ff2fbb5c60f158880b96941df99ec6b203031f43d67cbd88ad71f33b47cb19b3676bfb3cbce51367988f5f7b2b6496ebbda4ecdbbe14141fe295dfe3239b9c8e1fc94047f37b0995bfb959019650a48d4cdf482e18c9d7258c200e58427f64c8873e449f59a1bd375f94cb77b9312cb106e282f9f527d6ed59ebf35858228ab5a6064b8ab39ed2d1a70c3c914c15148525eea2c37e89dd341a2cc99acea0c31247e269b064034a0b3a0989c212a504723a1e96b8c15adb8525ae8d4768221e968865cd7508914561897e029e064bf4c641602c2cf176746a60bc2611a2282c294480402a2cc9355a880e23596c51d06f63cb32209ae57f17b947e4935c3c6a2d322cb9928e625eb2df8528280a4b16fc9fef94a0d22560c98a7406acd6ea42a4d2c560c99a51354c8c31c9340870a08ed481aabb9b024b2d4547ee1314233b296029be118b482d9ed847014bc98d6a85e59852f309b0d4bc1f1c73d2168a1fb74ffcb078070144d6d85f2a8e40a682f6143ae830b29a0c4b05a0a5743ae83096efb2e6cb68e0c422252c554885a556ba1061a9524a2c2c4570216ec7c3523728b1102e0e84a5fcd0927b14582ac38548ff6eeaf5bb053e58aa9f4287a50e7fa7a96f631f3f758a492ba5b0f4022a2ccd35be38084b9b516069551722450496b61d5d3d632941978187a5210a2c6d38b1be47197f6b130596f619798bfec35b3b29b074e8c45b64c884168b151685a54f1360e962586ac885c862a52a961a07c2d2f62ce0423858fafec883f811238f454b8aa8e878bbef29b074d31f572361193ed662242cfd7aac5558467a84c33f52ea8d50ca084fe60f80207a1ccaa18c330196711ae750c6338e1a3fc2e176168732ebc61fa02c9bc032b1230fc659c667fc61751a96c9a5c032693f725239cac9be094e201c95ce62a38900cb3c9d60e30d9d1a3bd1c8d8f4b3cc109565bab18664675060993e96516425ff6814590d0a2ccb3e49e86fdf7fd020793a280ccbba106059675856cb8548a4ea32f093f771c0b2110458361c96d543d9c2d1c0743c0d02a9181a8896a51160d9545876910b71a29f238f28971c97804a255b4c80654f8d4b255b99404d0461591917e20e967265efb11ea0cacd642957b665e441fc88faa13850f73b7ee4b004580e034b635d8844584e60a43a13d43419787cc60e7cc60ec6f6eff42aa74380e5168c7320b77444aff693f40acb398d38c41fcc251732622e39eb9f005b2e9900cb6d9ba877cf1f802d776cfcc104b0ffce6e2b58eeebf79bad607901022c3f03963b3bbed36adadb5460793b2acb67d2f1b0bc1b8df575d21601583e9c00cb87c1f2a213cbf6accd0ccb03e1083f1bffe075863838282432781dce7ba3a7b7b757042e88b5992106dec82259190207ff9c11dcd8960758be01d2a0b16223cac4732a2cbf114d0ffe74bb038cc35260f9ea499b1dfe10b2a9149a3e3a7e6005665613383d5a2c8ce361455f9c192d960ee3a45d88306e256d34f432262d5e212ce3e302d1c61259c687719b50ec278cfe88834c68603c2b9ec0b8ed104403e3583f5006c92c068f50e871304e1d65316b271e3fbea2301e4c71d72930ee34cb6f71f726fbad3ddaf42b0a8cbbf46388c00d1360dcd038e414f85950c6354c82f20fd6f10f5e0f07fa7be1c2bdd7458607e3d68f5a2730f2977f363ac93a0ae190f2b87514b6506105b15f5b47219b022b784fb20eac707a1c630ae513181bdd1d022b3c24c00a0f7ec49821cecbdb33dc1b8ef0f6c2c18181211be0604f6f1cc93b3064c38814ac4d34539342d1009a352e85a219155668fab5148abe145851635c8a1ff4ba213c24d817b72e24c03b78d4b126daca81a427da3a498515837fb97d0756aca7c08a59136dd96d08864981de86b860ef0db8900dc1dee138ff8849bb8646a41fdd3b3415e995f4a0d9e31c29995261c527bf965ec99b022ba9fd417a431c1c1a1a1eb2de1be7131e12f4dd2ea6118e7ecdcff71cdd98842aa57a2aac14f81b8e3e5360a50b7fcad10fbbaa4638fa353fdf71a4ec06298e73a4ec4d8595867ecd9172220556b6f98123ffe088481f1f7f4f7fefe07513b0fd1e21cad721d989b6ee516165c6af11a2fc89022b97fdd0d6ba703838c2c73bfc07838c22e437069924fdac5593fc6396271556fefa6be967c553e059d67fced11f0d32c2d16f00f21d476f20a5098e3e51e159a9bfe668b624059ed5fce71cfda19f228d45c251f3fc9ea3d9d193bc68763c159e8dfb0d47c728f0ec909ff8b5271c1838e2d4c121eb587a6279f92484cc7e0de126daeaa3c2b38b7f8d1015710a3cfbe90fd24f61cb21ace204c98fb7a5b2860aabc8fda62d1a0556b1f8a12d12dac1fc101ac2bd23467d1198b22faab4430a131cbda7c22a49bfd6b4aa28055679fc738efe6877d4e2231c797a4f9923d58d93a2832a8d0aabcafc86a33c0aac1af0078e1c83e1d008bf10b45bf642adaf3939319b68ab15129b68eb1d15562dfcb53dd4665260d5477fda567048b0f746ff88756840f2f7fabe2d35fca448a446a4c26a52bf692b8602ab994db435bd4d9c5322179e9c9faabd1bcf1dd406c77307589d8700ab73c36a68ea4b45536456e23074c8cb3fd4276295a2300e42f2d627d33db73d2e215cb5582376872c7f78913f55a7ecc1de0bdb63dae58dbc2242023dcd002e6160412588987173ae8e5b27cf4f7aff45cd789beb623d3257a7d987e01bc744a564495bf45e22b622f60c4299f92c7e0176a0831accecffa49c527fab463d9dbd2e79fd368b79a54903090ba6f507d4f92ffd8e10198bcd14acf8bb6b396a37973eeab665fd31772387554c5dc6d1a3cd9ab752acde3d37601a2d8f84c0a57bf5380469a7af9f7b89c86fc9b58b0c192ccd59a7286c622ab7e6a09ebfcfc0f21b9b3e5992c29f71debfffdd611b7a13876d0ce800cb5f8a85c3ecda17e7473a29cbf408a595fcc70edbf8e7fe1e58eac4ce7beca97babdd2d73308addc04600589c8f0531d8ffd2611ba00cb2cbfe17f73d61b4b51de4257e51ae175e5774fc57e509aa949cdf1d8651a12f5e5f107db9d63d717763b87540f7056e97eaaaa13967a8d8769d756bdf3d9a79c6edee968c37a0cb9d3da27b9f6f5d5935bb5c2e7287cef5eaab83fb08363586bfab3f7cf0525012670ea652ccac4c26c6e5f055bb3b4c25ef973b1c3f53da9e2b0e58b27d7c224917afbe5690beb725cbefe09b6371a79c5e2846dcd8c6df41db79ffb169258898da3baa42ebdf0db917bb9a2cd5d077a0dfbba64e0cc3c844b7d8749d9fbf401859b196193df322d703cd96c48f85ae9d4b86b6bd791a95b369e9c0fb28a28b69ef9cf18301664deb608016bf37d71e0c959c557940e6cbb1a57cec4ade78b41244f25579b61edf6a6a6d76d63ca67d97294dbb708de30701fed8f564eb87678ad6442378d2936376699f3a9c382fec4c63ef70680783b006da4dd7f56e78e75ccc9c1758869d0f30b11ac871f35bd1999e87be191938dfd876f0b0ddd015419fd398c7b6a53efa56f77a4ee54ef96f873d9898e632cc130c13f370e4fca7ebe38703dcfdaf9f96f30ffe41ffcf4ecbc162c1bfd5c8df3b2da7c7eacbaf4fcbd1bff1ebd3706c9ffdb2fcd37a95df3958aae660c1e0aefb222e9d22e1bc5ca5ef177a540cd51faeec332c5ed1a85ea4f676ddba35fa37d9573ad7dc32ed345ac00ff770d739c8e4ea7fb4b8bdcf791934f0bb536731361eaffb234b29abd5df955fac2ab7b19c2556cfec5bbde106ffb621e058506ca45b489b4468bbef57be4367ed45d7dc3e15f56691f5a5f26d5767ae38793c31d3c2b4928c34dfe792edf7bf8bdd30e0ec5c34681054a83127ce17283930c7d007ab0e3db6463c664458e262a5afc7a45775d83bab757a2bef29e5fe68a69751abd84d0aff5c58862d0198d8d3c8e6dc35a56a2e72e27d43ecef9bb21796f6e2b4df735679c5ec55727cf075c0559d46c7982043f47bdb0566a489bd0aeb28a433fcae75303addac5c5f5fa06e5ede8cf3800ea11e0331b1ded33a8d1fa3504c6afed92132afd72203576cf6166c8adb6e9555bc252167be5bee7fe0f449a4f7d529f2d5f52fc436ef375ab75144e4e31ed1f6595107d3a2f2b744b57aec588688cdea71e0b0376ad0d0400849cb63edcaeba859e40b8f3e712be8b31f5f593d84e61d6ba79577545569633092dafa1b485b07773c3b9375b1b6559d9577845ea687b5c52a8add5ffef9eaf28550650455dd97f3a2a293b9ddd6d32f228ea722162dad9f940645b784ec5b70b92aa6bee240f74a64a1dda2f925bc1ffbb615fae4a2bc38fd3307da2cdc838481d78d8fcfbcbe92a9738570d113b83958cdd79122eab161d7994b455d089758583c367ad68b8e60da9b3de96e4a292b6bed77776e5ab0203aea2e9735b56de4a493a07ff6a4939f9d76ffaf38e9e4f5420d2d4d0d3fe7757250c93262c9cc5ebb0e19cf83afcf6a9c2fb6555bc15b82cc8a765d1cc57d4c0c4aea945dcea66c3953f5aa6258fd76a7ba0f518dc9ca6fa44bdb8181570865c52b2b719a4707e7cc674dd6d0d04be81c59dbfd5ecff1add6dafe8d36f724a7ecb7a4819de3b70d89fe95db86847a8af42ec6eddcd8eba9a2fffec54cd307a4b3d44a32d27da963f95a5b5dbfd21d5bd45e7da9d9472d7e5ec2bdc6cf4eb5b7bf490d799b84444bf2ae6e911e6a6a150a65cb977bef5505e1d2e6ca5f176e1754d1bcfbaa5db20c0c0298a03f32074e19ea482ef7d66953ace9d20a95d54830da146fabd5b3b6e1907069c9bc5d5396d48b094aa37ea1332dbf98c7b620a0b741aa7afdfd0a7f7cbbfb7d0fcc8037cb907b4e5e153a6a6cccd979e919d648759e5d9ba79a68c3870637e9baab6edcf96b3d9195cbe1abc78fe6c404d1d6cd33ad2c49a6ea362ff1c25dde7cb630fa9c5ec5ae67e339941cc6671a3994a7b4e422f752874c152e1fb354dd7a4422ffa34b2588cc30d4de56539ab1ccd43f4c90a344a9caa65fb238cfef4a71824c5d453bcf85b588f7cb8556a722dc9a3738489ceff802710eac0fb9be769ffe605a20efcaf5378343c7cedf7fa6e45780177eb2e3b367e58ea36def7431f9e7f6de9f41b821db53798693ff55f994f5ed3372fe7ef0f4cecefd0b47184ded50e8778a09af45ab62be7eb469616fdd71fe1b368590cad96452edfce66c5d9155d02b448291cd6598947f50b2e8f40bd2dba3f2dec75f0ead259e6aef693b659bc85e2d5986f10398182fa4467df656d292f543b948c846ae27ecadbd315629214e86e6af2d16087d583b77c99415e4c7c4888d7799a47fe181cd5e87cb35f15bd6ee7549da2c58a7d3fd7a79a397ff12eca73cb677973fec7a3b7f0db24cc3a2648656a80e589692641f722c090857e9ae52b5caacc5462eeb4dfa701375c78069b96368efe226e1c30098574ec2ee513bdbeb3cb72e9065def5073fa4be316e13c3c9ab0b7743cf5b6eecdc2d6c17b0d7f0915982baf909291bc4daeccab7f3f7522d021ecbb7765db43856a27b8fa47162a3e1a0c2a607e75a375d437971fe278e7d4f42b6fb9a78bec6da1b13b92e1eca6a2b709dcbe3a12f351454b72ed0d96c438af23564eb7d8900dd3df5ab0b6fb53d176e219c5eea6061aebcd0202e99c3cb4af1a4b16b19580d30c12bc88288e604bdeb98ddbe0c53c34b47d722c7ceaeb76d5eddb31c6f9cfea1dfb0e9f094a1b69609468e1f74a638f5dbcf4044e75afdfc17caedf39d06dbefcc34715ff1e933fd5c5535ad375641e3c23db1b52b9079e5865c8992c72ed5e50ce95ec67646a5ddae7d548995bcf45c0eebadfc98c4f393a4d0e84f118e3be9faf6ddcf102e52ced3f5764df2fa067eb5a75ea70d050ec4b477fd070ed12ae7a9bfbc5baa90c3345a79cb97e75a6c0fb27dd964aa579df6d8bb82e2f1a6e332a2a0f526a93455c131c93e40f644fe0937578ef50f4c254b1845a09ce02645ede2324c1dc0c4d4200ae6f194bd6da4ab7b376e5978a2f9ce85c08e6df8a84fabbdf44ccf2f9bcd85659fb225039998ad932e5ec44ce568ca1fd3ab85fb7456e70b06cf5a73f2746a90bfc99502d703772797fb24f069e57f4e00927b56fa155c9e9b207d6ca7fcff7a7a554946ba3ccf168928dce79fed5473a262d623e387af7dc959331e241d7fa57241d4d12d1309ad192c22c9ac320895f556313b223fac82975948d4bb676c6da3aa39cbe64b77e94eccc076d6881f8c9d04d729274306af0ac3bbaf34d6b45bfbbf56583f2f7b11ee8d6b258854b4be6e93c2a8a5ad585825b7babe46a46e5f6a99ca7d99e836c32f9a335e7a1d46562721da1b2e447f34dbd8e5989ccc56646af1f90ec5a64cbc546aa5c7eb3e9d323438e9fe33f9fc7611e2666ffd4b5bd602f319cb3b0f54b938575f1d006f495eeef572b0c699462292eeda2dce6baf9223d66df4b1d551106bc052eb5fea751dbeec7974b6a8d4375c19c80d304176c4eee8c74b995eaf8cd87949d9333d9e35f2eb29343d152268390d2f7971cb392568ca900e1e282d3d871938cd3aa5edc5c4296dd41281ccaa334ea52503fd77025cad78760824efcb55996f4d2e35e7f6c83bfdf7ee5b901faa04912b56add25970f83771c7900a3e678dad2762ec782282535b12cf5ca075de6ddb8f2c7c69fa7c26b8cbcd8862eb47ad3db78729b142988bb24266c7ed93359a9a3be78c5c8dc5f886e4add54c8f28ba5fde7c83cc10ebf03a1b156b5a74fc134fb631b7ed9a8d53d644e8c8d5582153396d3d09a940c0b0dcab5c3565267616774379fc12be84bbc794a40fc52ff4632e75333744a264670708cef5dc1b710d7ce32e8898a87eda8a0935ae6f280998c9c7b3cf6e43198727c0e45883449f6a0ba3056cdbc5bdec80b5ca5efdc282aa24fbfd166b0e3ce8ed64323992be4c99ff702687d0c8d5584ad3bf1a4bbd63bd5de5e75abb1ec9b977973614fb952fb6f4ff5de2fb5f8e4953b91a2b09094e91cc2e7838ff3c69d12b45be450bef6725c5455fdff1a5e2ababa8515f4e6323027a3f2c189c3b3baea14b48dafa74bb732678413c94db499023e2d3303975b7c3a4782ff1d72edafddd70f9d509bb66effe0e1b6d46da716ebdec6d94fb73fbffe7e33d88dc5493dc4f69e278efee965e5ab85b7ed329bbaf72314733535f6dfd6492fb4d6a0962dfa4372be41ac7c90277c255c53d350d408ac05320a7a37cf9ed5514c69e24e7c9eb3302d594bb5450eebfbe3e03fcdfaecfb003580cf8df99dec5e8453ff53cffabf27e05c6c35f94ebcbd4a925fcaa7ce3f69d06bf9b7e6513b85560bdd93a49353fb7494a6b1746e831c702c6a1d876e5b79ebcf147b419d7ec367bdc3e367859be6fb82af7f88e142eb9ec7589273adf9e2899afc53b58dcf1bbfa030d1c33d7c6f5a53b1fef3b3d3f4a78759d74dd9138de77b7cbf69bd9b8ef8879be38f49b6ce2f2b673164a12fc396a9f5235e44b186f6f37a8d56749e429bffb86af242309183933cb8a8b579d95e7151f78d86efe5e9ae78d85c8c5855497bbe5f03ead14c45cafa7e3a094a3fac1baccd5c7fa25edec1b3514cfcd5deee4c8b1fac2d20bcc54345f709956bef0b3cb9858f9c2be8470bb752598cb745a97ca9bed6fc181f4e5fbeeb93fbdd61c124d5d3927a41b5987e195589496714d78bd2397dda645ba552be9a488c88d38f5e379490afead1bcb30960013638ed4a79a75dc8aaa5829b541b9981ebf6c16ce3de4f66ccd859a42ca6e09a6ab3a64a6dccbac6382fde3a30acf298c2afed7c6cdc203d073e52fc9c5d1856d2ee485c7300a96aaafcb94d9b59243ea3b691e852b10310db7974d7bb34befaddd3fd79c229e6b2caccf99da7a2685bd2d64cecc1689443449089c5a9270a66ecfb7c5f854bad8fe1747973ed7fe665ceff9f298a3fab0ed5200c833492222726aaf13173ce1cee60c3e7275c9f6e72909bb0a4ef03759f4dc4c9ef3e6957786260a25bd694169454f0bffaefd5b949ff1efdb9c9d78b007a4b8e6b278c9feb0dd25e735247a63f91ea5f543c6516f37bff5bba5e4aa77f6cbeed715aa05414884220e5ed34bd3166b65cf6b1c50bfba982bb167dfeb3aa3eb360749f74e0af18edcd3736cf62646c62ee5d4cf2b7d9f9d3dd69037df85bfe2f53d05db7a24660dfcd09e7bca405a5f598639013031054834cd27d840ed65fbdce1ed29efe35d1d0d56b7a99b15dcb50c5d56e4561b95866640a688dc96eb7d31a6550a671cbf3dded3e16f5d737ffd16d17bfb9f25ee2bb2ebecd61d42abdcc8c41047ee54cc9db8539154b7fa1c3692ca79d0dba495d3337d0e8d0cdbfde14ec5e06a7e0f4697d190b05ca3f991ba47ad75067dbc2bb3de9e2bee7a2cde607d4216d9087f783317df7621578087cbcaf7a3586cf2d5c44f43c71d92e62a3b50931edd1cbfac80f2723c83f6a21e2afd79069db37467a0df6f80ca5f494616dfdede5c6953f16260752e9c45dfb55d2f89246bafba738ea543f91d2b73ec5b8467f683c7cdedbdd9db3747cd122d19d4513821c9ceddbb555066f3f58c82f9dbe78e4cfe87feb393ff06c5a11c65cd7389d5d66a7b8efbbc78710b8a14f8174cfe27222efc7e74bd1c98f3884467b638e3ce7be9aa1bb3bb8fad70b5a9ef2a983b33e50e22d51dea5bd5faad78de90fdc10e47a719853cf88557f248ee811ee73755bdecd319c3abfc5094a9652370b1b3dcf26c9c86f2de70430f8941051d67cea297596215379029e3350ac56bedc01de5e95fdff7bb7cfd2fced426223c5a417509f4dd15e77862ce6f0bb7a19d3da3607cd46367c8b2afd64bcc86eb3088de270a5620ffcc1981270f36e987e55fc8bbaa3ba810b7dc2a391ff6f2341fe41bef1c38a6d039fce93ae47fe5ca7932b2abd8f4e3f2968bd8bdc2724eab07f92f55fb9bd8149dacb64c322a3bc07ee6f900e26ad07265de1b33eea017b73825ece4dd42031b938e852df93420baa433509bc2bae38df0cfdc0ace5d5630fc499bf0799ec0f5708dfefdfb1f2cf55e57ed946c3fe3b2b269eee134552462561897338effa6dd1dac6b67e497b28fcccd356e4edf743bc55e208df3a51ccb40358009ce426abeacf7f6da35436c2567a30562fb44f8c4968ff3961cfaec9fad7ef6cdaaf076dc94f11a3dd058fa1033508f5a5770c2ba34506470aab81568ad891f72af987f39e07dc232832e8bb3477bfff60a43258844c62f4d6abc7041c820aa7ca8eb90fa4afb55a5060d73bcdfa67d01f1d22e895710f0a29dc40185561ba6733bc375f70c77cf3031d0d19cdedd7970e155c62ac7e1328e4b0093a30c79f2cc033b57c2ed6693ca296fa5a153cd3b8779a343797085bea4797d6050d8d929eb6a2b9323a0740366601daa2cb649aee0c09509983d9c117fad99eb46a096920e277bb673a08564bc28fe7353deacf9e44a32725ddba6fb2ae35dc2e2bcdb7ef657ec8f3a398b8a6fe67f6a305ce0ba93c195aa83ac53e4d7319e19b4ff63b8b017f6a60878bc2d7adecd4d34e6a9259564770c1e9cdeb46f74806ffdcf7cb029d5bbb653c2966d9f907d52407ae867cce13cb5ffc0b4ef5a3ac1cb77bd096753e04b524b4ccc815877aafbd61acf79f35e95cc8d18e0a120562619f47ba927b5aec327331478b81047932fcb2ccc17d9cab8ba8349ea7d8746ba3dfde9757bbf9be0f8d7deee71108b7de8ca57bb7585af469878f02da924cbb59cef3d4eee8cae3f24d430d3b5105996bf5de9442155f6e88b9365874f78e428a5ea55dd52b418548dbd1e71ace034f2dd364afdff91abf8feb93bcb7e76151f0788fd6fde59f69babf6def7d5fcb2fc833ef9d7bbb4dc7ebb8d727d3a533d66cbad63f39958639f2417d0698f032757575fcf5cfe85daa0af87d5708874bf6af5fb85079b7702b33c81dc5df197575665c7a8777677e3ee76b697fdaefe2dd9a9fee147bc1fdb575d7ec031d83ab4dcec6ca67db4fb01f3fd29ef2e8671399a9d5b32e38b2e8f884bcaeb9033253afeebe6846d4ffb76ffc5b194d3fbd3a50edfaa242338eb1505f72fc845db87e6ceadd83428bff2c88b6a695fafba9d05ed73f63c73388e2cad5f926960659fcb5917a0dfdafe285fd3ffc2a60fc9ee9a51f5a47cfd4739acf5f1b0ff89f5f144c4fb66d5dc01e5edade5f107dc43afcef9585ddd1961f36ace66a354f7878577536621a6974e35d816ac12d3098e1172ea911c7cb2d0acbea06cc6bae7372ecd3ea854d930b62e40caefaad6ac99d958f5b44d2023bed3e77c9fdf4deca768e323891fbe896337c64fb9ff224f5e176899b42e70f9c49fad0b6caaf165fcbd750180ad928cc80cf9c6e49c28b1e08ebc40e2eeb06d9ba9e4cca315356397a68e0cd675ab6907429891a8bab7f2c693e39ed677452b39795c783dddb08015724f29bba38efd464019d80430c146a48922e81e6cb6c87c83e860ca37bf4a27d3d6fe84fc790ff82b4fcc3159c6afdb39655d509960d27897eaf52fdc2b90adb9fdd0fcab0642f34fbfb8850815f7f21f0d292c3911f7a2e2ddbbc4c3e6f50a888bf63259cd0daf766f363f6a6d2dbe897670556fbacb894afdc646e2a0fc81072bd0b476d5b4d2da19ab92755615a4cec899b3b5fff63e0b8b38efaca52ca8575eccd6f45ba9480adb36c41f6bf964edaefe07ca225b0a45407089369d90ba03c1cb9eb23750ad5ff385d1631e98356740acf123d476fbc5b1c3590ada816ef53565986a8089b982043d894ba3088b75787ceedb967931f623b69caf77c155f8ead2e2fa6f8331b93e343a6629d2c8f398a1608d8d9f4dcf95a05012771cdd9fae4eaca7debeecb9f1fd92ea6721a879e94c4c64e9da01bfa0a94deab464608ded756266dee0caaef6edd735d0e1bdadae6063717be1e6ce050673027510d7fba73bb35d796c1a1fb1edb86bb0cb6837653342eb2f6fdf2390d6ac7ff97c0b1a780ca61778fec2f2cbd436e6a463d85f3ee7f0ac9634b8eee738ef86eac6971a430ca399da2d8e0e3912d9bb1d1005a3c53378b7b5f4377f7d12ca7f29e78a28a088b49e594c8d7b7420b7e52e44fc8b9bd17fba918a8cdc483ebc45c3ed3e59cba0d372e92a8147a106d5ff8fbb2f0f8772fdff9f194b832c85ecbb644b96905d681864295bb652b66c59b33396c328644bb678b2644d945d458821eb945df63142488591e57739ae3aaeeb774e679cbabed7399f3fe6afe79ae79ee7fdbaeff7fd7abddfaf7b1edb92ea14987071ea8c13ae760180e9cf04d615f5e48c0a3067222b9f4ca90b43032ccea3a43229571218527b78ab0ad7f3834958c44220f1fa091f2bb4b48e940f16848f4bf1f8620fdb67b3741620aa54e842cc98ffbf68b83f4edafd8018b26d41a01fbeca16b49b1d7f0f9ea4a1631fc813a937f452dd50577479dbfd963af4b542ed2903e1e09b6c6cf6db192f7866318e11ee628c2cd242cd55a415259f02081a0cee86df389283f93c5a5f0d7e00c281ef0357aa9a7a79247fb3f4411fbfc62da7abc87e72e87ee1b08b4c71f475610ea9462fbc6772180eacbdc77e5d7f6dd127cd3296529da988786d8cddbe6e96355d3d5a8ee83f51f4813d4d3b19e4dfc12c3daeb04eaec59eb8f462c2502e3d54e6c5a171a608394934a0bb22466f94d63d3c21debdc46370ddd1b53c37a0a1d4c88ac67ae3c5333462ea9b8896b97ddd223c4a9d4885c572b455285347e24a610d04b97089c99b533a10e03a873746c87d229afc9f89e81cba0c354191ae561356034037a1c489f0158ee8a745340200483ce9df7d9e8d70a0975883d1896fb55dafd259179b9e164c8c8c2f51862e03015e386fc679e32a7e7a018ff366ba48e262c226cdb6279467259342656d8873aa0950201c411330d299e5c01c1948155071a66004c910529d9849d95a363f9f365a77cc93f1550bdeb1ba8523b8f9070b99dac7423c607fc542b20d1bfa7f928510d58381cd6d53472f92b02cc97b56fdac19132a67fb8802e8275e87c355830b9b97d20d00e7e177b1728d2c27aac86cdee4918c8a0c9cf88dc67c715bfeb9879931f3e680c477c717fb411c5f66fef90bc2be304b87a3f04469d326d457b832f3631ff7c4582b8af6345de9c3802d9629c9fbf69015268922da35314f48e32dee9a5a68054ea9e5c28ed74ee79bbde5ef74b0e5ff6735a8835cffd72eff73e9758e85627e60a38e47e6120068788061eb6bb68de493538bde6225ae163e8047a05aea293e73519d2c860c2d6627484a8cf02bb25cb12ed5f418dd50d466cf2e2fb884dffbf75db4b95ae0561d9b74e57e18817cf2aefefeb238df9796c9d95a22797728ef14008209cc3223e7b33448df67642642ad385643903e51cdfab7c6a2cb863facca2ced922ca95fd1ec89006ab7ce9a57f4083569b3483c1ab8e63c56a71d04e39924b359ba669de2aae82c049c99469b64caf1e6b0adf2ea4d9aea1a4a170482c71539513d172291aba76dc9bf19922ff149130a278dbfbdcae75458de51c4a6203c9bf3ec8edf45736b939449d68b77f05eca917b8664b77f89e0f2dd843f2be5bfe06c37c7e7ce78b96d16c2888ab62d9b599468adaf465cba7611a0b32d6a7d4333c14b61de3f4bae014f78c0fde471ad8e3553db75f1f6ae681fdf6a702508077e0a7c66ab3c6278ab9e694518ed77e62502ab8a3dff86d324c4aef890476a8013cb32de018ac681adbee70ce87ea7096deb8f7346ec5dbeb77c0fb411911e9b44921462d96172c7da939a26af8a97192bc7982b9002fc5c370280c63e54fdb272c686ba0c99f0b62f5557367965c6fc8add35bb39d5efc3921c64d813204862166c896880e1716ca776bcff25f233a41b30bdcec80c8735c3931e35c071770b2abea98240b9a6a5b3b9d3d44ccfe966faf22548b424c2cb4f18762106bf0f4bba7f1bfcbb618bcc54f886de7d585c199b34fde2fdc4c68432457c0b56db58f1406447a3776a01e099106d21338488beb83c04cdc9b09c8531323fd112de6e17218321aba5da73f6fa981730f10d9a5c823e6313ae62759d5802d94e63b567b95eec225b57278582b57b434221cac0430da8a12fb0aaa8d889b1c716f82087d64eb2357f00053e788a0a826b938077718ba9af26a205e1888e00d051651e8139d4e455adcd12d9707ab3a31fc37cb050aa4eec6d18a7fc64e704deb78cc31136ee39b9380eeee4820f59d322636a7dd80eb378cc45b7a8587d2c8bfb97e7727c9c5c1180958e7bf66cb31c2832e6d92cbfeaea369350f6adcad2ce8bd0abf4592b95c061c0e76e3dc1722d98da4d869da7c7ef5629249566f45509ddeb410d21a7873529b0ef12deea3f28e1e7c3328349b0a7d30cb8238094cab4b35fdb481f893ce41145850919e25eeec40146812ad8d5ca693deda352a6aa794b5845a273b70b02edea4a2451fc3b67b00adf7bd4c4fb17b9701c9e5b8d3285fa8ad767f10ba9348773e41f50a73a8c0586d6230048340a639faec54a7a41354b76e3ed8c95c38c1b8d48a94b058dc290d8a5f348e0ba2c751b91b9c5c504e355c932f123d471500f849d183cd167ca4909d3ae706f8faf181f8caffc5971e17fe2805ad70295920b5a9d425263838bf70b46a9222cf7a61b51086dc6b593f6b3cd9c01c0b9eca50f4e2f9008b113cf6a74387448aa3f4ddea17f55e43a1c48434bdf777b6e9743481f8843008b1c9e9a4bfc3c748b5276ab41819fbb1eb64ffcfe5b8815cd1d578f267de0b5e7bdefeb694a003240bdb8f7e2ec08474d90eb95c4866ec08d596bc9d3a8fa7a029d92896c9d7205ec29347fdd9dd9939f81ede3ac2f895b350403c2412600cda3cfdba0415c57a268f97f0b94c3c42852703a600a8e0b1a093ced92e38f4bc73b2f26e020f17fc881e9fd72a0feafe480944ebcee4fca01e27a04c0c860ddfe7051bc7eb0a83d91c8d1adfb9dbff1e711afb420916c1a448168c857801663ebfd6640cdc2103ea137b53c3569c3d8290f49f778c7ee956ae23e9a77631718f70301036f1614747850728b2ccea69d31f7da90f2e649ffdf136172a4653f307ef37c7698048c667d1ab130a2d038e55cac055e5b966c0dafdc02f469b55cf2c4ce0979255defb21f7fcff3fe4d09ad01a8aae6e3c7cb3e8dbe92647b6beec6afd508d7aea6b5f9b5e80c8b8ebfb6a63a9fe19060533bfd9f58736ede03e59943dae5d4f5d2023b3bc4645f3ed569aa070c905a0f16d6c2f3357b01d618cae20eb22a3d78cfcc391345c93bc5341cd657f559adf99220d8b4e3d43e7b87425fe7cfa62fa0c12ca9156b8d0d98dbba63693e6942433225f4b7e23af4d2d9d3f09ee589fb0e851edbb7537d68feb9544df8825c8d58c2ea5d17eda9b7646f1972b912b4cd593d3daea4aa7fdd24171850060ec9717871e4d731a13fccd527f61535e6de66121077b25639db5434df9998eff74d13e47d72e531876f6bd159b2f913930ce6c1d5cd4b37d846a2ac6db891924a157d783f69d29e2630399826f8bbe4ff8f354109f9715213553d6355818a76497b47c63838ea5e780bf7a6acc0c8734c54f23d002a6496d48b75f832a1b166c472c2c331f30282ea665e66607afb910ee913fd65d5e065100ebc00385e3ff17c6653d5cf74b22d92fb26e1dbbbc76e64a8c06adadd027da92ba3ce7ae31da0141c38bdaa6bbd83f3e006a1bfa381ffb862acafb37151882a3a81d95db79a7fddf8dafb23d0f317ae425978529fd75241474e0214c14484665d32d0fec3332dd45c0587f3a1b26fc3535a9e5a3b5f6c77e10dc3ed42ee7c30c8ff0167c50f72494ff10537e788dcc75f4d89233b121ed0849324f42550e4197af1850a4a43f50038abce58ab3fdb97c36ed30123e501299fe6ebf2da57641bbd9b1dcb03099937aa4640eb830076c52e4344d96b9ef96ca6fb43274ce1cc74e33944eb0aa26068f0ac8b0f78136fc0d3d62377370a995f711432027846dafea4b6d8993d0379a682c943a9dee6f4c6a7fc49ced512f9ee8af75ccd148029733fcb51d39b14e82ee9b595c9de3ef74bf22a8e3708300c15fde8cd858d8fd584c6201ca10110620cb2dca07add2e1f089bf05473c54595d984131f2a80c8b71abffaf8b05b10efe74bc71142abc12238b050f0a189507b385a3a048c284ad097a4a0acbd6c12553ce855c37cc8189e5e7aa80a51d5e442079bfc1b18d97f6e1a9cf0ffe1657be0dd8fee6d91e55afe37e353fd0e04efac02fac9a94f4cad36da0659fcb6342bcbeed3324c371202b87a775843f50601db165de5649f4be414dc2f83bb798ffb7c8589bce20c73c435062f7e94af3b1ff42d6693ff86983dfa51675f8f6cfa87dff7b26608c02b66a237a8a21763730fbff1e4a07edfbdb3c16b9dea0a3fe7ce503094af258745da0090e5de0f61f54a56ada14cc96aaf06ecd59d079f9e66582c6e49ba37a8da1f4ef12d6653ff869845fc44cc88f9d93aedf088d92de0b4d2cc1d27ff88cc42bb64abecb0e8471e8f6a47f3087afafb7b1727ad32cd8d01f2d3495b1990cd378b4c02a26cbe16616acf95b86256a52763c96322ac75dce7aaecd66d39f02b77a22c6d0d3e838dbcb70dd36a1ea7c913a4385c6e34cb4737151de14bbcdb3bce02088ff0760d8b2d7bc35081bf853b16d7570ed2081ec58683bfa87d40bdd09775ac06278270e0388081bbbf3f5ee87295478fb88524da5eacd4e77e0955ef619a90d202c8d5c2bc28bc930b8003abfc210f30fbe4c1a3eebf92078a2f29197e4e1e10c8d58381a3626e23fdf14f1b261402da750767331a1ca2065f691dc73c5f3575ce545d4b02fc4ba7e706f5dc8695dcdedd0e7abff205414f5e1d298c72af3c26d2d1969fa2b29bf54d7f4dd6b7dbda2229b430599e9b12324445e545da2077348bdb569c4607e60760845acf00a7c6f1ecac116edeb5e2c910dfd4fb7e1b8ae9141a3b40d9329ad3cace2dbea01a920ec24152006e228e37d26766c7b91b5649635d7bc8a4d0f3062b264ca03b75cf08bb86efa3f106261307d1acfa0a595fc7f3ef89c2da7a6450cb7f527b29c7b632ddf7a0f71098e4f017687ee03607e585fc1f38125d241db744eeba6ee4396707dae590296a84d2d05b8e7ff22b1c4b22ce0eb39e05a4128e1bfa7e323d9673a572baa660bdfdf69965cbd8da159c981cff9df93922fa3dc1e5f26b05d711544c4b22cdc9e5b98756aa8c6a6b0dbea16941ff09c18584d2c4c66c57d20adc2aa917bcf4785bef50de2663c5cd2b0647e62bec3e138b02a61770236d5dce412e8564e853a3913df3dd102343bb1ad2b759d85287906d996a88300807110444eb4a9315a2e73e37f1075bf0713812703ebd328188437629b950da747e09c59f6767e3c0a37b18711e0c23cfd703fd3e335d12ddf7270e45d06b680a299e92fe1f28444500c69e4ed69878761ca577100512bed36e3630e59ddcab5eb53c245d2ef59cf82a20b3186f7a51aa8035f9f5b2b5a6522f6b475627ef73a9741706e15e969b719a6cdf7d215c07f285fcd9a4af070329c746938d422f67de7022d37f8498459f4f149ef50f71f92097c6547526895b1670999a96e9e36fe315d1379379894db6569ead7eb460763b52fa6d992fc2ef02e65b1bdf656c504bf6b4088f1ccb3c0a162b2bb465cc390cdd316fb821ee21b34c0fa1c27bca3cdcd7c667d85f51c5bf8dff0f26073e5ef870c7e0ba37b9a74ec9bd93e047493b472a050130456e64d4c360e34b77e55d8d000d4a61ddbe8b3af09a00356dea2f26d1e68a3c5fa508c68aeee4a189178edaebffbf000000ffff1ed9a0d101","nonce":"0x128cd","to":"0x8453100000000000000000000000000000000000","transactionIndex":"0x3b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x41535904d7b20be8d733e03d95ec725d0c6ee4307d899cd00e0ca0de91533b13","s":"0x3f98c81207d078199bf74a600a77cfa389574646d63ff55ccfd194491faf7226","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xd3343d473f624c02045a01f4e7ab604bc56c4f42","gas":"0x156c0","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xf49895cde","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0x00b5b05c6d1a2eb8abe2c383da600516515e383fc8a29953bb6e6d167e9705b2","input":"0x9aaab64814636b3e36ce9c4227a5fb53273a04c3fdc94c8a00a4d6d5b6521571b94ec7ac00000000000000000000000000000000000000000000000000000000000028a416eb20a9e75d33ef7eeb4a0bad7413cea6c0b3a7f6ea249a93a428c0c36b52240000000000000000000000000000000000000000000000000000000000840244","nonce":"0x6c7","to":"0x1a8b038f5dff48f541e8cc658b9e186b9828a726","transactionIndex":"0x3c","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xfcd40d6ec6fa94f40f866c18457c22ebf5d8e3aaf2616c4c1cee5245ce8f042c","s":"0x45e5962efdda48e38f706cf8fb7c2f722d80da6e0a1d2589b6627627b44feb82","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9aba7eeb134fa94dfe735205dda6ac6447d76f9b","gas":"0x3e64f","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xf49895cde","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0x6fc411f24c7b4b8d821b45de32b9edc5ac998d1ac748a98abe8e983c6f39fc19","input":"0x2e260ac30000000000000000000000000000000000000000000000000000000000000200a5c46e2dd70854a0fe8167b705eb7df71cc927469c345248c81b21a5ab2f5f19000000000000000000000000000000000000000000000000000000000000051d000000000000000000000000000000000000000000000000000000000000051e000000000000000000000000000000000000000000000000000000000084024700000000000000000000000000000000000000000000000000000001b3fd9f800000000000000000000000007ebc0d2451003f2d3bc5f6eafbb7e6bad81e250d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000640fdea40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e43c000000000000000000000000000000000000000000000000000000000002e7d600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6cb686532a3ece4a20f823e59cc386e1ba384d8504e902c932fa1497c4afdfb0b000000000008008402470000051e00000000000000082ffe82e7b18f0778493c989ecae1740325207ea29328999d5ae646723a4bb75a1305c8ca593670972f535ff8afda050351549ed800e9b98c805788acfe20e6ac076ae024efa64ac3ceb8f0a3cc9ce93d122f6faf8376c854da95567fb7576f762299ca2135608c7ac5a824257b50043526903fc8e01ad88006448a69a4afda4c01ad8a6ed1260582538f2311e902c1e7d5853a75b74482117f2cf920897c1b9428eaeb7e74a95d3d32db03931d157a48aaca9748bfebfecffc2d140caddc66b300000000000000000000","nonce":"0x108af","to":"0x7ebc0d2451003f2d3bc5f6eafbb7e6bad81e250d","transactionIndex":"0x3d","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1b284cf86146fa2094c7c709cf9fcb8a177f4fde1d1c5ca112e41f82a5e973d2","s":"0x5618261c40d23e5beb7ac0bac77b16ead56e547f103f649462387c5acdf18ba5","yParity":"0x0"}],"transactionsRoot":"0x709b85056e1bc5d3ba99dff25f42906bf99d8cd57201621ded11072fad4db62e","uncles":[]} diff --git a/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions-hash_metadata.json b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions-hash_metadata.json new file mode 100644 index 000000000000..c4008f7f082c --- /dev/null +++ b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions-hash_metadata.json @@ -0,0 +1 @@ +{"name":"pre-shanghai-bad-transactions-hash","fail":true, "reason":"failed to verify block hash"} diff --git a/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions_data.json b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions_data.json index e1371c9118c1..eeb34e170910 100644 --- a/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions_data.json +++ b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions_data.json @@ -1 +1 @@ -{"baseFeePerGas":"0x7ccf990f8","difficulty":"0x0","extraData":"0xd883010b02846765746888676f312e32302e31856c696e7578","gasLimit":"0x1c9c380","gasUsed":"0xa79638","hash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","logsBloom":"0xb034000008010014411408c080a0018440087220211154100005a1388807241142a2504080034a00111212a47f05008520200000280202a12800538cc06488486a0141989c7800c0c848011f02249661800e08449145b040a252d18082c009000641004052c80102000804ac10901c24032000980010438a01e50a90a0d8008c138c21204040000b20425000833041028000148124c2012d0aa8d1d0548301808228002015184090000224021040d68220100210220480420308455c382a40020130dc42502986080600000115034c0401c81828490410308005610048026b822e10b4228071ba00bdd20140621b2000c02012300808084181ac308200000011","miner":"0x0000000000000000000000000000000000000000","mixHash":"0x31f0c0305fc07a93b1a33da339c79aadbe8d9811c78d2b514cd18d64e1328f25","nonce":"0x0000000000000000","number":"0x840249","parentHash":"0x2303b55af4add799b19275a491b150c1a03075395f87a7856a4e3327595ed7df","receiptsRoot":"0x99da71b17ae1929db912c3315ebe349d37f2bb600454616fdde0ee90d6dbc59e","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0xea6d","stateRoot":"0xd12bf4cf3941cf48be329a939b13d3403d326841c69cdcc9a9c13ab2f227e904","timestamp":"0x640fdeb0","totalDifficulty":"0xa4a470","transactions":[{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1b7aa44088a0ea95bdc65fef6e5071e946bf7d8f","gas":"0x5208","gasPrice":"0x174876e800","hash":"0x39c666d9b5cec429accad7b0f94f789ca2ebeb5294b8b129c1b76f552daf57d3","input":"0x","nonce":"0x26bd1","to":"0x68643ada5885f14e7c15c13bee06168eff0f7c36","transactionIndex":"0x0","value":"0xb1a2bc2ec50000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x26e648625520c256d87d8e15769e8c4290d2a7e27147594815da42070870825b","s":"0x7db34c91603e51494b59b020597e7118433d50ed548bc7efad8880cbe7820ca"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x030b1cddf635e9e71ad70b8668e235e8ec3c67c4","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0x2ca7289ab3738d17e0f5093bd96c97c06c9a2ea4c22fc84a6a7fbfda93ce55ee","input":"0x","nonce":"0x456d","to":"0x89416096a0a1acad3436a357478c5c548e4d382b","transactionIndex":"0x1","value":"0x16345785d8a0000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x5aa6ad410ea42dbff3781de67b4815a376cd459206595fa6655c966a7709e5cb","s":"0x82f620f8dbc356dc38ef346d1e152656a1d318becbcc41884f61e85972355c0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9c67435ce8a33ad23f377ddf08260ffc56417f21","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0xb0085de1476530de3efc6928c4683e7c40f8fac18875f74cbcc47df159de17d9","input":"0x","nonce":"0x446c","to":"0x471f3a988a77472e971112e7ff2ce65996b6c8cd","transactionIndex":"0x2","value":"0x2c68af0bb140000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x75425f21a6e66e6feaee79455c897656c4a94b6189c4c033facab1b67812fc3f","s":"0x7014f4b9f760165c7757f9d6dccea349b3d00b0a9c2f845af8010140842f826"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x168f6dec26cbbb3749654e0e3cc4fc29314fdf6c","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0xe01c8631c86ded63af95b8dbc0c8aac5d31254c14d6ecb4cc51d98259d838e52","input":"0x","nonce":"0x403c","to":"0xf2119a49a3ae35453c1c2704da248d08977084f1","transactionIndex":"0x3","value":"0x16345785d8a0000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x56bba57ee69c09dbbd5167d0fee07d5803130fea7c278f4d8b7bc54b34be8ff9","s":"0x7eea69c0de47b6b808ea1bdd9ecf5d25f4f2743e867b1f838db59c456026d7e6"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xc9af69904b4ba7f0fb69ab1a8719bd8950265e73","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0x69414a126a6f07ab5e31ad2f9069fb986b7c490e096898473873e41ece6af783","input":"0x","nonce":"0x44c20","to":"0x6adc3f5394e00cd067d1fad5a33756791e303c25","transactionIndex":"0x4","value":"0x16345785d8a0000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xdc9a52b87755cd07143bf032d57258d0d6c36500b38a574a9a5addc1293343da","s":"0x581e6fd051d0c72d64303c1f90edecfef46580f84f24dba930cde910923f7c21"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x92964e63cd52450e6e09a266e0c226e524754563","gas":"0x2625a0","gasPrice":"0xf5686c7be","hash":"0xa2fef1133ee726533c7f190f246fede123e3706a03933c1febc92618f90d2804","input":"0xa9059cbb00000000000000000000000011f7db5a824eaa5737c935ad09a925dd707f092b0000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x2636","to":"0xbc071c64ed8f536011c78e847755680740d6b73c","transactionIndex":"0x5","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x422c5026584cd8fb8a1fe66e6edc7a020bc513cc3114083fb35f9846cd9a9792","s":"0x7fcd4e48ac5b53d881531a5651e587188157ed88d85c51533f7c6eda94c67ff7"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdec1bc71bf91431d60ef2742f412dcd1c5a204b8","gas":"0x7a120","gasPrice":"0xb80e515ce","hash":"0x6585ec5c4c2bbf1f683f90f58e18f3b38d875e94457fe4cbb7bc5bf6581f83af","input":"0x67a5cd060000000000000000000000006343e96c99e2725e845ba04f90e03d853cc9bb2d","nonce":"0x6a5a4","to":"0xf5de760f2e916647fd766b4ad9e85ff943ce3a2b","transactionIndex":"0x6","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0xcb7b32949ac0dedd3151d06d85ec4e99483c8ea706f12a009d97b055975241eb","s":"0x69f0009bce12e24408f9a3d5ad5a8578e2b23efb09002f7b86b3425cf8748889"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdb954dd5d224004b26cfbb089312e0542e5d1c31","gas":"0xd5ef","gasPrice":"0x9fc748df1","maxFeePerGas":"0x116482c049","maxPriorityFeePerGas":"0x22f7afcf9","hash":"0x1db276b864fbf01dcf8cededf8d597553ecb0eb9438edfaf2f5bd0cc93297c66","input":"0xa3e35f36000000000000000000000000f18f2320e4779f21d6882d83f9133e582dfaa9b6","nonce":"0x570","to":"0x11672c0bbff498c72bc2200f42461c0414855042","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf23a1fb0d17cdbc2831a2cb0b779795e12533e34425a3abbc4b7e7bde262b92d","s":"0xd4a2c8189378696065b7fc5d13e9cf6595d96047a31a4fcb812c2e677d22a26","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xe84d601e5d945031129a83e5602be0cc7f182cf3","gas":"0x249f0","gasPrice":"0x9502f9000","hash":"0xcbe7ed31654af4e191ca53445b82de040ae2cd92459a3f951bdcce423d780f08","input":"0xa9059cbb000000000000000000000000355f96e3261cc8237d2d36fd81cc9b9cdcbfc5ea0000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x4f1f0","to":"0x499d11e0b6eac7c0593d8fb292dcbbf815fb29ae","transactionIndex":"0x8","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xadf7dce5f34d482bb19ff0c85f43be7008cb838043f9abb5fc08421245ac4228","s":"0x5d2c0f0b9d2e68bb8da6084e4971d57bd76bf0cd9d893c9c985962812d2df026"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xea0193f88a0d9c36e83e6fb6d382212b6373faba","gas":"0x43238","gasPrice":"0x933ea77d8","hash":"0x808ba5211f03cc78a732ff0f9383c6355e63c83ae8c6035ced2ba6f7c331dc63","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x9","value":"0x470e9f23394000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x9536f87e8c3433ea23ef7211c0c32689551906dfdf31bcc73b89fcf18fe86a92","s":"0x3e94bfe3b4ba32a6ce71ee6e0ff9f26dfc2b0d61b5c0fe049469e3c4b88ac227"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1f9ab300b380313e6a2208e44c01a0602538385d","gas":"0x32b38","gasPrice":"0x87fc9eef8","maxFeePerGas":"0x2e90edd000","maxPriorityFeePerGas":"0xb2d05e00","hash":"0xdd66f1f26672849ef54c420210f479c9f0c46924d8e9f7b210981ffe8d3fac82","input":"0x32db5470000000000000000000000000000000000000000000000000000000000084021000000000000000000000000000000000000000000000085b0af981975a40fc5a00000000000000000000000000000000000000000000053ae1f470262f3b01c4000000000000000000000000000000000000000000000813bca9f8389ffd193f","nonce":"0x5699","to":"0x28cea7b0f3916c1dba667d3d58ec4836ad843c49","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xbe8eddd463a3518a4c94b5922c0f2fb26a32c8afcd819f7deaf4f0416757ad13","s":"0x3e234182acd5261dfba3cf4f125d1a8377fc707b3b1900b565d1a6b8987b398c","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1d990a2cf61b46f37582dd31a7b242e989e1a1ee","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x254abb2f8cdcffe9ef62ab924312a1e4142578db87e4f7c199fd35991e92f014","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xb","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xbfe9b99fd2e9bbd2d65bb4cc17da88130d8f6b569a26afa642ed1cc8efd2e2ef","s":"0x7003dd3962eec2369bc5abe5e3d5b73a9086a3219643b1741f3a9832369448fa"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1124bbb196fd7b61947f6f03b7d7cebde8340b6f","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0xa7b7c654e7073b8043b680b7ffc95d3f2099abaa0b0578d6f954a2a7c99404e1","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xc","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xe8dae9efa8fa73a3aebdaa75ba12acf56712b1f99fc128ab802a7610d014547b","s":"0x2ef347ea90a0db21b035637342bfc916c9962d3ec610a4e99cfaf555a2606fe2"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdedf52a88fe47f6a11d629badd0096d201aef86a","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x7ccdfa698c8acf47ab9316ed078eb40819ff575bcf612c6f59f29e7726df3f96","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xd","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0xfc4e092094abc7fed9cf11eea8ad6ec3a760d13b9c603b5570c2143e48090f2f","s":"0x31a0a6016ab51ed6375891bf532d9031bf91c1d0e01df63cf7e46076aeee83a3"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xe1db1fd154b344ce7dfcb53a65279559b298f0df","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0xa0b035ef315824a6f6a6565fa8de27042ade3af9cf0583a36dea83d6e01bf2a8","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xe","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x79c316492bfa36fa4de2dca02ffac77f6c1772714e153aad8c947ce848d4106f","s":"0x4fe3e083943ca8f974cb0752a2ffb70e4d6c8b615e16ece7e19b2c464be66929"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xd4c3777e1821f6fb532957104e1317a9d3f881ec","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x1ebad7f3e8cb3543d4963686a94d99f61839f666831eab9c9c1b4711de11d3d9","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xf","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x5c1f544ca92b28a014129a9d04f8e895dc8a6987ddc1717c26b0619bb9bac420","s":"0x47574643bd92a0f129f9c5ce3caebe7943cfd828d67fb0e5bdc1eb2ca202822a"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x127418955b15f5ff2fa232431a798b53fd006c82","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x501750278e91d8b5be1ccf60e793d4bbcd9b3bb3ccc518d3634a71caeac65f48","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x10","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0xcfc9894bf716ba707521f0969082afb688b7d47cc21f1423b239c40867128f47","s":"0x5d9b9c66d8437d0a37768fb9c3241ef64b7e795d0d908196e1f707215ac1f56"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xc2ac1bdcb3dd77864b99eb2cafef2ed36c1487c3","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0xd80ff8af29ae163d5811ba511e60b3a87a279f677bb3872a0f1aa6d0a226e880","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x11","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x8bd7220d176d18cfbc824063448cf864c494fcf0958dec82126f26d3fc6c0b6e","s":"0x2f4de3d2fc3be6d2812ee10aee16a995af5affcfec27f9953ae609886d2b563e"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x11a5ad000f8494233df5bd2f2573fe20bad744ab","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x096acab3b3fe47b149d375782d1eb00b9fef7904076d60c54b3c197b04e6bf82","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x12","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x43726c3165958e94d80cb6992121f55df2904a1de4356e0a6ff3d8bfd03c0928","s":"0x6244361e31daccbb5c7e9f3f7d01004080d2efa314d614fdc2aad4c1b7d71613"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x90f8b290ec2929cce086826e971cad3857c6dbb5","gas":"0x50f46","gasPrice":"0x861fc89f8","maxFeePerGas":"0xe22924cba","maxPriorityFeePerGas":"0x9502f900","hash":"0xbe9d1738af74a22400591a9a808fb01a25ab41e2e56f202dd7251eb113e8ceeb","input":"0x6ab150710000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0xe4","to":"0x2e84c9894f628fd209f48b06d10b46c8cada4c10","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x412c7bfb0236a4317da40645ee4e60f19185e7d0cd2cc9bc88f7629de505b939","s":"0x4f6bd485d10fa134926ec3e3a83e212f3c5d903ba52da87f07794a2ba0a5c1eb","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x7915ec065b644568155c4772a286addad3864c1b","gas":"0xb71b00","gasPrice":"0x861fc89f8","maxFeePerGas":"0x1176592e000","maxPriorityFeePerGas":"0x9502f900","hash":"0x0834c720e55cccd97aaf4f8fb0cb66afb9881fb6a762c0f70473ec53f98a712e","input":"0xedce8b4d6a1fb55588eadfd3a0c3350435a31d31e7c236125eafcc2a892d50711d9a4939a4282888c956c070cd83400fd47ab83bd5287244053b8228711b07386dccacbd000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000092000888ad4975d4079d80bc6da5ded57746f889644719ec160efc2e4a96ad645df10b1683afcd7ce41ba6c06528761f821cbc6e806ef4b71c189603ec218b12a1f1478883498e67b97ae4babef6996acc582db1377d8755374602e00b8148025ac2d2f52e78d7484919cef14bf96e5b7a3f7f8cf09989551888f2c697052ce2bdb02a9296b20016c78683a9ca137037e57c8ff25198146f9d4cdb5a25ab9c95a03038f22f83c8604ca7c035ef756d2963c3657eea4ffb18ef967752d8cff15a16124a1d92a1cda613624c98e3078742803da1417b78bb264b7bb2197515cb4facc2ea395c6241664dbd953d0034900a86eb94897bf89aae775a1d73e6fd034785400000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000001d802f901d482e7041b846de27f7b846de27f8383026c28946aa397cab00a2a40025dbf839a83f16d5ec7c1eb841dcd6500b901a45ae401dc00000000000000000000000000000000000000000000000000000000640fdf5900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf0000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c000000000000000000000000964ff70695da981027c81020b1c58d833d49a64000000000000000000000000000000000000000000000000000000000000027100000000000000000000000009a1a41127726f74560a57990fb928120eed6f55e000000000000000000000000000000000000000000000000000000001dcd6500000000000000000000000000000002d4766adcf72ef2d996edfadc866be12c28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000001d802f901d482e7041c846a969541846a96954983026c28946aa397cab00a2a40025dbf839a83f16d5ec7c1eb841dcd6500b901a45ae401dc00000000000000000000000000000000000000000000000000000000640fdf5a00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf0000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c000000000000000000000000964ff70695da981027c81020b1c58d833d49a64000000000000000000000000000000000000000000000000000000000000027100000000000000000000000009a1a41127726f74560a57990fb928120eed6f55e000000000000000000000000000000000000000000000000000000001dcd6500000000000000000000000000000002d4766adcf72ef2d996edfadc866be12c28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000001db02f901d782e70480846a969541846a9695498302e100946aa397cab00a2a40025dbf839a83f16d5ec7c1eb870aa87bee538000b901a45ae401dc00000000000000000000000000000000000000000000000000000000640fdf8d00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf0000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c000000000000000000000000964ff70695da981027c81020b1c58d833d49a6400000000000000000000000000000000000000000000000000000000000000bb800000000000000000000000048f2c17f8885e135c8689626d5841d0b94013556000000000000000000000000000000000000000000000000000aa87bee5380000000000000000000000000017a8db2711fe83b10bbfabb6a8b86c3e26ca154ef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000003760f4e19e59be10b323fe1b42e42de2754c5da54ff316cef74ef09dbc0144bbf73e609a8d21a38f393bae9a3de6bebbf362608d907d941c8166f44d8ee2c6686b5dbbd6681f5467219d9bb530db013b7c067db659c03efe935caeb7bab36699d00000000000000000000000000000000000000000000000000000000000000032d2d7436bd45b5e81824945ff3dda846e270c81e72929841f4b14f56e02eef39477f9c162a2759c8d7c7e1feefdd064f6aefb4360d483f70671f36fc11ccc6db6c53f74e3019c12d859545ad75b51998b2238887dc0be3c78522c8356150526a0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x48f08","to":"0xe87d317eb8dcc9afe24d9f63d6c760e52bc18a40","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x54159a63b8ce19097cb8afeaffc84cfb5257f9709dcb0f0a258befa0b924b13","s":"0x17f5ef5aeceb6f082a8a0f8fa28e55d453c52e5f86d48dfb4d4f039aad7fa493","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x52db522edf50fc32b8fc0f77d51140031da11da3","gas":"0x201568","gasPrice":"0x861fc89f8","maxFeePerGas":"0xe22924cba","maxPriorityFeePerGas":"0x9502f900","hash":"0x51a0c33c9b37245b416575bdd2751c0d8a5d8bead49585ac427bfc873d4016af","input":"0x96d3f83c0000000000000000000000008cd194f4ced354a14960f76f49305feb8510f73f00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000641024ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b3fd330d479974ad52e18b8767d9f18cf9ff024fa749b1066a803b237570cb73e2868e821124c8128505d883124711ae7fdca0339f4f5cd5dadd8eb6956eb4af500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003","nonce":"0x2d9","to":"0x29c1442d7e3b6ed179ceb55fe996e1f4384880da","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xac84f403fa0347be3246ad695f8f6a780332357d49dfa67388fae3e051e5566c","s":"0xac2e148c1045af0ebdb334f20743af7d5499558af5eea43393159ce26a3fb1b","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3aea5f857b75a946d5f5b329bdcf4db46aec5d2c","gas":"0x50f46","gasPrice":"0x861fc89f8","maxFeePerGas":"0xe22924cba","maxPriorityFeePerGas":"0x9502f900","hash":"0x531c25d51ccda59aa9ea82e85c99be9dd4e285af9b8973cbab9ac4a38e26e55a","input":"0x6ab150710000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x1d","to":"0x6c23a4586cc791d2be6767532e12264992aef74a","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x81abc4fdf3b57fdf3a951fb293853fdd86aadce8f319576ac78c60caac186c43","s":"0x452742335bd1f63fd623d5e6cf91f6339361f863dba1a57fc3c1da8292e82c77","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x7915ec065b644568155c4772a286addad3864c1b","gas":"0xb71b00","gasPrice":"0x861fc89f8","maxFeePerGas":"0x1176592e000","maxPriorityFeePerGas":"0x9502f900","hash":"0x93ac6c08d21cb1b61ff59e5e2d6fa3f9ad54008b0a66c669199050bef219f6e3","input":"0xedce8b4da4282888c956c070cd83400fd47ab83bd5287244053b8228711b07386dccacbdb54cb66757631f9f22e2faf7da0eecc43474ab1a1af21aec22dcf949e2579241000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000009e011cb7bbabfab668b42b5582cec8d60f326ae14ad55f8d675060dd111dee6c88d0937435261929ba3a881bea107593a10e13c917a0ef5ae4e8bde40de2d1da4ba25ab3a239ba53eb4e260d23b98a7db944f644f40ab75992a89fad40e8d692ad62f8671604db415b54238c5522f6c4e6b25785bffa696d173659309b95a2fae8700d4b9c14382973ea34a3cd8b8428594908dcad2d5d7a01056b8e49a8c25087f12f9e9fec1f4b5fdc57509dba6839100e28016b2e3fec4928bbe11d3789b6cab280c17bebfa5a0e06aea22764e1a18d2d11316bdf81028e65755582586ebdf571cbd0ef59800ba3405539187dfc03eac1dba0cf590e2131a56ef7f260aa38f940000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000da02f8d782e704820101846a969541846a96954982dc1994a59477f7742ba7d51bb1e487a8540ab339d6801d87470de4df820000b8a4220b5b82000000000000000000000000f6213f16f3db9b50c684b2da37ff080895ae4a02000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000064376b6900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000003202f082e70411846de27f7b846de27f8382520894b6605a717a2447edac46b1cdafe35e3e91130c8d87038d7ea4c6800080c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f202f8ef82e7040d846de27f7b846de27f838303335f947191061d5d4c60f598214cc6913502184baddf1880b8c44d49e87d00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000160f9854c9f595e000000000000000000000000000000000000000000000000000000006417d4b8000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000b2f4f1df2e372ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027502f9027182e7048197846a969541846a96954983029eb1946aa397cab00a2a40025dbf839a83f16d5ec7c1eb80b902445ae401dc00000000000000000000000000000000000000000000000000000000640fdf0b000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000e404e45aaf000000000000000000000000964ff70695da981027c81020b1c58d833d49a6400000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c00000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000c097ce7bc90715b34b9f10000000000000000000000000000000000000000000000000000000000000000000000614000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c0000000000000000000000000000000000000000000000000000000000000614000000000000000000000000694b3f194e94c80b2d7a0e986e1440f204f0503f00000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000b902f8b682e70427846a969541846a969549830dbba094964ff70695da981027c81020b1c58d833d49a640872aa1efb94e0000b884437471fd0000000000000000000000004e44260732136caeffc7d076e17b2a3554b9ce2a000000000000000000000000000000000000000000000000002aa1efb94e00000000000000000000000000000000000000000000000000000000000064376b6600000000000000000000000000000000000000000000000000000000000dbba0c0000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000005b0efccaa7c845eddd4fb98211c7a58a37abdf06b264fade6cbff8a73ed22fccc602337b33a81e2cc4127be9d913fb3aec24194e14a61515a26429a00cfb86196aa3c2e6983f1a05dec045f0e63db7bd8619cd2a770ed1f7f470eb7c297e8e19d61277fb276ed8a63fd666b4a5ab02347065a3c16539f4ccccbed8fa39f2a7dc6606fc04c49f3d69463ba1c86c6ddcef8b9f06b9741dc2ebae9f5f1c0523b320b00000000000000000000000000000000000000000000000000000000000000050668b9ca5e5b17e2e79f9f5a7d9ea27e4e7f0302e878584fef3c2304c70c1ef53da311342341f89df488646b97a83994a3d07cc622ffde98598548c5326b7ccc0cf77d5d6fca6cf3f5b5b41a266fa2aaf697fd976dddc710fca834c96d2dfd725eec5980733db3c4e8f779f9fde3a598b2860d819419c961012825f0e160ee7b220989005b6ac5c48734db18158c2d85c8499bea1972c9f875c2d2aeafccb33700000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000f6213f16f3db9b50c684b2da37ff080895ae4a02000000000000000000000000f6213f16f3db9b50c684b2da37ff080895ae4a02000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000064376b6900000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000964ff70695da981027c81020b1c58d833d49a64000000000000000000000000073fee82ba7f6b98d27bcdc2befc1d3f6597fb02d000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064376b6600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000044a1c058fa0000000000000000000000004e44260732136caeffc7d076e17b2a3554b9ce2a00000000000000000000000000000000000000000000000000000000000dbba000000000000000000000000000000000000000000000000000000000","nonce":"0x48f09","to":"0xe87d317eb8dcc9afe24d9f63d6c760e52bc18a40","transactionIndex":"0x17","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xb5f185933d49064643686594f44a2584b1d57ba6a91f2a45d1a122892488f209","s":"0x7bb4af7ea30290b36fa7c266ee2387eff9e3ee0cd79b48aed27f5bfaaf34114c","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x4281ecf07378ee595c564a59048801330f3084ee","gas":"0xea60","gasPrice":"0x861fc89f8","maxFeePerGas":"0xfd18eeafe","maxPriorityFeePerGas":"0x9502f900","hash":"0x3792db6dd6285f409e4281951e9f78dad16c4a78072ff1c909dfadea5658d857","input":"0xa9059cbb0000000000000000000000000cc351a97c2fafde4cfa8a00c4fd79881cf13b53000000000000000000000000000000000000000000000001158e460913d00000","nonce":"0x77ffb2","to":"0x326c977e6efc84e512bb9c30f76e30c160ed06fb","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xef4173dd45060791cfb6dfc3cdc8a9b417ff6a4b3ba57759ea91fd875b01a522","s":"0x4de926b5099c7d60cc24add3c2eecd8e9550c1fe7f878430eccb887a2ff932ff","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x53e2c2479833ca17f946aeb16dcc49f5e2194701","gas":"0x431eb","gasPrice":"0x8442f24f8","maxFeePerGas":"0xd6aac8818","maxPriorityFeePerGas":"0x77359400","hash":"0xd2d51764c01e8c0a43fbe362704388df5bacf7e5e620c3864e242530ffb3e828","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x2","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x19","value":"0x470e9f23394000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x155352758fb04a6c0816c3dd9ca16bd6c66c37e2e19f2aa5d969225e3cb7f118","s":"0x6a4a1237db75dac4322fe12aee8b94edf7083ea661d6e93334c667d2d5c2c101","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x535619cf2bd2e84e567bda1a6164f195cb2bba21","gas":"0x55730","gasPrice":"0x83152e5b0","hash":"0x516b0227d9e64eb6e0de6862764d40f5376b5f12fec878436fea3479b4c36bb8","input":"0xa9059cbb00000000000000000000000030509945d2b329cc253a8bb2e2c54bdbb08b1070000000000000000000000000000000000000000000000010ce1d3d8cb3180000","nonce":"0x2176","to":"0x1173069b0e472a64ce2b6203fec8fb25a05b75c2","transactionIndex":"0x1a","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x289ee9948b80fc623b8c5d85c7df6fd25786fcc118163042b77a00560f53c3fb","s":"0x5b0a79e30d05370b27664b2a10cf964e110387bd62098561b6ea6a9dcc4634a"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x339d413ccefd986b1b3647a9cfa9cbbe70a30749","gas":"0x180ac","gasPrice":"0x83152e5af","hash":"0x81b0abc78b82840adb666775b182a9e292f663b64bcd35004c04436ed3c8281c","input":"0x711746e200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000002540be40100000000000000000000000000000000000000000000000000000006d3c514bd0000000000000000000000000000000000000000000000000000000000000010","nonce":"0x2689","to":"0x7cbd185f21bef4d87310d0171ad5f740bc240e26","transactionIndex":"0x1b","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x1f70a3d0933aab069a55fb2b16a259d21ea5fb3255e2032c5ff194a600ed2ab1","s":"0x3ac2142fc9f2009d68b08855eb5bc85e889e15d043c33bfc516f28ea38715485"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x339d413ccefd986b1b3647a9cfa9cbbe70a30749","gas":"0x180ac","gasPrice":"0x933ea77d8","hash":"0xd0287570d431d2baea96ecc81cb890e7f4f06ab5df02f9b4067768abca19acb5","input":"0x711746e200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000003a09994473bc00000000000000000000000000000000000000000000000000000005672af7e00000000000000000000000000000000000000000000000000000000000000010","nonce":"0x268a","to":"0x7cbd185f21bef4d87310d0171ad5f740bc240e26","transactionIndex":"0x1c","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x73a68e10ef9726d47ff314cd16d1846a0876d2b63a65014909140de7e45aa8b3","s":"0x580de27e4626139fbad4129a249c7ac2b22e1062659293e5fc3a244fd74907c"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xb5b9345e21f34b6cfa538f49e2b14ad4c3db3f7e","gas":"0x431e0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x76ddab2674369f34946c5fa2f05e2aa8566d86235b83e808e9b27bc106e04ac7","input":"0x9f8420b3000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x38","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1d","value":"0x1634632a1414000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4314a4757076c92ca696f14cbe037bcc0178f8b10749418d4535195e90b2cdc9","s":"0x15ee917bc3e27928196ad987b61e3fd35ac92a4200b139d355b30502bff7fceb","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xac2fde165d9f13a223f58b9ac1dde51b63feff2b","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x34a5c74011a2c8a00103bc91bfbfd94aa99cd569be69066e4bf64d188fe8714e","input":"0x","nonce":"0x38","to":"0x7155eba8ef327ac3b36fe59b5e00ab85f735f4f4","transactionIndex":"0x1e","value":"0x1c9f78d2893e40000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x52178c5dce512607a6242f501f78bc894917a482e99a3368caea6bca94c6dd69","s":"0x728be90654231b65f790eba478ccab574e2468fc4e031b712efa88af31fc6592","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1ddedd674bfacb6587e0c68cee8f2f7d8a71e9d7","gas":"0x1d4c0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x7b9730ead1b9f59b206d0ddea87be9383ba3fc7b496c7863b0cb847889b86617","input":"0x607019b9000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000041971588d95d4d664ac84a45e59fc81871b7051d679376d86cef6b9e1453c762dc33a84a125774319ee47f2a8b8d588da6c8ff7ad84fd9eed22fa124b1a5c5ed4d1b00000000000000000000000000000000000000000000000000000000000000","nonce":"0x1","to":"0xe1e6aef7642b6609e6c54884d1bda4a3cb152461","transactionIndex":"0x1f","value":"0x4380663abb8000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc0d3e609b2e9f844d300a7784aa9e7cb956415d025cb573a73848f49e4be69e5","s":"0x6ce01527c00c1a93341a541824aed7a1c895f5a0d998f4415cf6d88171c5ad3e","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xf6df8ead0bdabfba61d9b2457d5a5ccec67fb7f3","gas":"0xc836","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x77166ee0409ba86bd26e7c03ad1a927abaf5af8a8a37149e725cd37512091dd6","input":"0x67a5cd06000000000000000000000000fa8449189744799ad2ace7e0ebac8bb7575eff47","nonce":"0xbd","to":"0xccb0f4cf5d3f97f4a55bb5f5ca321c3ed033f244","transactionIndex":"0x20","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x5649e1ff58fa9b6ee27a7316904df02db1ba1c471a2f3409f370a31c6b3d5ec4","s":"0x386b766277e267f8796ba6e92af71a752335bbe45cb3385b9cdcab9ef6c53e41","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xf37cbbc2dad42e8826898d45933afd3a04937e71","gas":"0x112c1","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x3c2b6c2ae505c5c36d5f316c1fcb5f54f7346ed35ae35c93462991ded7968a68","input":"0x095ea7b300000000000000000000000071bcefe9e9fbad3f12f2e6c14ea0cae7f0c91e7900000000000000000000000000000000000000000000000000000004912e6bef","nonce":"0x9","to":"0xb5d86e1f237d52f1f19793d3265e9340394f75b8","transactionIndex":"0x21","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x3ee4d5bfc575fa4b241b4d23e6f099eba5f1e6a20b8cea663c63db6400d01506","s":"0x21481ea7a3e7ad758f2e149829f70f43d67b3cc0d44112cd3744e290a06dd985","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x52b6255b7810d97de8f751737547d1792dff4fe0","gas":"0xece2","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xf99a792837e13827b5e0a8915fb59c760babc95d242feca99a5594e64ff6b6e2","input":"0x095ea7b3000000000000000000000000c92470d7ffa21473611ab6c6e2fcfb8637c8f330ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","nonce":"0x51","to":"0x07865c6e87b9f70255377e024ace6630c1eaa37f","transactionIndex":"0x22","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x5237f7449c0df409c1a4d6cb09005a9224860aa74737debd961e2a24668d1022","s":"0x17e5e842e3f5ffb5a16eca0ec2a92e5b52d43bf9856f97e2083b2e951499b970","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3c70503d83c5a681aab503d724f47fe810ae8205","gas":"0x17eb2","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x522313f5d923f048ae5bd0b5595c1f4fc883bc0b3cf3cb0939d3fcf8b08c829c","input":"0x94d008ef0000000000000000000000003c70503d83c5a681aab503d724f47fe810ae82050000000000000000000000000000000000000000000000000000000316195298000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000","nonce":"0x5","to":"0xb5d86e1f237d52f1f19793d3265e9340394f75b8","transactionIndex":"0x23","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x6741309799fccf0f1359bd710291ec1bb66eed23522d6ed60c5924264d4d283e","s":"0x69c43182ee8a650b0042cdb2352781b23eb1de72f1c3a8903a1a33360e7d9732","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x4da9a48963c158a88bf6d4845a6a1890d20e55ad","gas":"0x431eb","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x471ceb0e85af594aa56deca54cb8198567b2afd8406722ea530077aaa6b641b3","input":"0x9f8420b3000000000000000000000000000000000000000000000000001dd7c1681d00000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x24","value":"0x1dd87babd44000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xf977ce19da80b7e155ee2d8b7656e5c89004851407bd5370785befe2c89d82f6","s":"0x1d76177407e73d8b73b0909158825ee375a25fa7c18b04884f4be77bb60795a8","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xe40a2cd9efde08fb7664bcdbbdd877c52c4bd228","gas":"0xf4f6","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x3e9dca502e9039ae0c6d642f62e9562ff00010c6bfbb8234a6135712ba70dfda","input":"0xa1ddc5460000000000000000000000000000000000000000000000000000000000000738","nonce":"0xa","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x25","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x34df85658956c9eb71549db3a73abca70dd01b8e91284afcd372c1212a36605d","s":"0x5036e2984bb2edbb5fd647bba873f1f5c5ee4845e539c9b0bc70d3d12a4bd93f","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x17299065e99b12b0c8cad06638624cff8d507334","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xc95cac67267f4accb9b5950316ac64772f7d082bed6b712c09cf2da0bdc237b7","input":"0x","nonce":"0x7","to":"0x02647cbb1714fa9a5747ec5be6333e06d806e85a","transactionIndex":"0x26","value":"0x71afd498d0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x82ee5cafbd010cdf7a4604df728d1b8713a5bd26a708f5c92f6b6a55864c9576","s":"0x2b9a70d812123b2ddce1108c4101ddce182f6c83fc8aa0a139ba597aa178b270","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9aef7b879787baf0c2dfe888e67a7edb7a233209","gas":"0x431eb","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xfca28fdbd13fc16daf7aec7d4a2ad2c6b5f0b2a7b0fb1d9167c09b5e115ff26e","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x2","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x27","value":"0x2387acb3784000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x7e5f1a27ea5e652ec8705f80365f1703d2fd50c1de7c22ee0181d556dd2fcc38","s":"0xb22fb8b31dbfff8ad0457ba4b659fb0d7031cd86f08fc3cb78d81c97248034e","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x06006a25e0fe65f0eeaad1f4813940b68db782a7","gas":"0x17ea3","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xc73124ca798b2f7a5df2ea4d568efab2f41b135130ea5cc41d4bcb4b5c57d5bd","input":"0x94d008ef00000000000000000000000006006a25e0fe65f0eeaad1f4813940b68db782a700000000000000000000000000000000000000000000000000000002726bc7f1000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000","nonce":"0x6","to":"0xb5d86e1f237d52f1f19793d3265e9340394f75b8","transactionIndex":"0x28","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xabe4fc843d3a1628a464884c13c21bd21ae9a0a5738d9ae2761ec7cb24b059d0","s":"0x68408d8096e542b2c06cbbecb9494a3778c3ab644e69dde1fac078079c4bcad4","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x2501bf5c8ddf04a60fdd47a95d53d99b315604e2","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x29abb76b5e7a5ce137bf9c22474d386eb58d249f43178d2b2e15c16dfdc5ca80","input":"0x","nonce":"0xa","to":"0x901a4e04f1513443c6efc6ce4e913d1b960ecd20","transactionIndex":"0x29","value":"0x1a3385ff37f0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1a1789d5b19950f45383cb1909cff9128dc2b332e2ea7ba42cfca5806376e3cb","s":"0x617a5a4339503a9c9d08705d98e7a202ed7ede1d1192fd7d98b648c8c102716c","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x507832c92ade971b9a2880427353c6ce6d0ffe53","gas":"0x61a80","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x03e5ab25a58bd44fb9dd0c698b323eab8b8363479dfcbcbb16d0a0bd983880ae","input":"0x85ff842c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000080383847bd75f91c168269aa74004877592f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000557300000000000000000000000000000000000000000000000000000000000000014507832c92ade971b9a2880427353c6ce6d0ffe53000000000000000000000000","nonce":"0x1e7","to":"0x805fe47d1fe7d86496753bb4b36206953c1ae660","transactionIndex":"0x2a","value":"0x214e8348c4f0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf707322f65ba56c95ced5654efafcf9bfd60a2dd80e74bded3190673cda55d8e","s":"0x46412ec3d2137fcef30f53cc4644769f4da126128979920ed4e209acb1c8ebc9","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xd44c850ce9103d6b2398d4ed9bbce321f3b769c7","gas":"0x1e0cf","gasPrice":"0x82661bff8","maxFeePerGas":"0xde6f782ba","maxPriorityFeePerGas":"0x59682f00","hash":"0x3c8ee80ddea7fa2d2b75e44563c10c10756f598e8ad252a49c5d3e8a5c8e6cbf","input":"0xeb672419000000000000000000000000d44c850ce9103d6b2398d4ed9bbce321f3b769c7000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000d44c850ce9103d6b2398d4ed9bbce321f3b769c700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","nonce":"0x9","to":"0x1908e2bf4a88f91e4ef0dc72f02b8ea36bea2319","transactionIndex":"0x2b","value":"0x2e2f6e5e148000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x327a6fbcaa2ac3cfb0ce64b47f6e61de4d18297f1305f23c6bfd42d88e8d068","s":"0x6b3a9b5252ced14b2e2f2833ad7cc62c46fbd0785d57f2747473af3fff7d46b8","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x78aa9046272fec8d51a402681d7c37481db01c6f","gas":"0x431e0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xaffa73b68bc7ab0c3f5e28377f5ca0a5df33c0a485f64dc094b7f6ae23353203","input":"0x9f8420b3000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x36","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x2c","value":"0x1634632a1414000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x925370b51dda3e1d1bc6b86580fda3b40875157ea594a9a14174436c726ad46c","s":"0x516c88bf3cb2f46ca81572140b41e5db2d74c4a736ee7d572b508415c438f779","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x56784e51c2ce28dbe9aa68342638d1e95ea4324b","gas":"0xb72e","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xc66c9c66fbc8fe97fcc16506cde7a58689af1004a18c6171cfe763bcd94f50b2","input":"0x095ea7b3000000000000000000000000805fe47d1fe7d86496753bb4b36206953c1ae66000000000000000000000000000000000000000000000000029a2241af62c0000","nonce":"0x9","to":"0xcc7bb2d219a0fc08033e130629c2b854b7ba9195","transactionIndex":"0x2d","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x407c855bed0fb088e886c3721ee9abee4761221d110512ac29b8fb143c4b34d4","s":"0x1e47aa957d9ebdb564dfa41b72022d525383ffd825a307fbfa9ca13a59994dcc","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x805e39acf2f170251c48a35df16411cfb2f761e3","gas":"0x56a8","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x80fec96707519172b53790610d5800cd09a4243aca9bacfa956c56337d06f820","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f4000000000000000000000000805e39acf2f170251c48a35df16411cfb2f761e30000000000000000000000000000000000000000000000000000000000000000","nonce":"0xc","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x2e","value":"0xb1a2bc2ec50000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8fcf376106af19aac48ecb840ea51df90a5e3ba557eeaad41cd3c8a90785d416","s":"0x4a9e9021ddb5f839bf7f54b54ad52c57b21b6ed285773eea022e3ccae69d1b99","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x4199614bf74f6b3ef47a812d976dd1f57a8f082c","gas":"0x431eb","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x61b33bfcf11214906dcdce7d7ed83ad82f38184c03ded07f7782059d02eeedea","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x6","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x2f","value":"0x2387acb3784000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x3d295f5fa2dbec04793f07adec57e29c03376c628a0256ee297fb3070a1e3364","s":"0x6f115dd4505bd320bd7460a47bab0c20e6bcb4b3f17c6d0e00e3ff1d936ed2af","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xf6df8ead0bdabfba61d9b2457d5a5ccec67fb7f3","gas":"0xc7c7","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x5d4138d4e28a8327e506cb012346b1b38b65f615a2b991d35cf5d4de244b3e6d","input":"0x67a5cd060000000000000000000000001f1f156e0317167c11aa412e3d1435ea29dc3cce","nonce":"0xbe","to":"0xccb0f4cf5d3f97f4a55bb5f5ca321c3ed033f244","transactionIndex":"0x30","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x47bfb48eb89a8b110749d34d171db36a8ad21c8d7cc78c7489e72f21cd86ba14","s":"0xa525976583b19b3d2c2dd6b34324cf55b1a61595cb53e3c58acaf203f8709e6","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9eda8333e09828571db26576a566668f79f98946","gas":"0x50df20","gasPrice":"0x82661bff8","maxFeePerGas":"0xc8d5e2427","maxPriorityFeePerGas":"0x59682f00","hash":"0x875a142b6dfcf10ffb71a7afe0ce4672c047fc7e162ba0383390516d6334d45d","input":"0xb1dc65a400011a04d404e571ead64b2f08cfae623a0d96b9beb326c20e322001cbbd34470000000000000000000000000000000000000000000000000000000000bd780a7d2e00ee03a29f787096cae99da52d07803c76c13473654239118e2cf0491bcb00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000480000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000077359400000000000000000000000000000000000000000000000000000e50bb6420faa6000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000217f0aee859cd78a5cdf79c68c8de4342658d52ccc6420181b5fcb7c657c5fdfa5ca2c8f2dd7e6e5799d44d6818e6dd8fee19b2530bed2045e0c665041f053fe70000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000840235df8360bffc902a68675311f5eaa79ea2c25e2cc394bff0a43d5d608e98c97de200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000493e00000000000000000000000000000000000000000000000000000000000840235df8360bffc902a68675311f5eaa79ea2c25e2cc394bff0a43d5d608e98c97de200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000007080000000000000000000000000000000000000000000000000000000000061a800000000000000000000000000000000000000000000000000000000000000003312d88cdb7cfd5fc5458d9a424da374cd818847f87fc4fb6eae2c3b97e541a6b81e108e55daf857b71514fb7213db7ba15bd6adc12253afc3c5e949144c13696faabe22d1b7ace91532134a5cc65bed9afdd897d6f84ad1b0b6da463bda8fde5000000000000000000000000000000000000000000000000000000000000000352c2a75f88112864819de485c392c349f718fc257934181c4d8ac8eb3a9b1fdd3b7bfb96496290f2b41fcd20fc8d29bd8e29be38550775dc97d21b17c2d679ad05f519787eb2c92a9a897c9f02f15316865cfeb4bcc2c0ba5ac2dc4aaab5c0c9","nonce":"0x3705a","to":"0x233a95ccebf3c9f934482c637c08b4015cdd6ddd","transactionIndex":"0x31","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x7e9247209bede2c21548c6e4f26e41d2636a2490e09ad062f9235e978094073d","s":"0x288d820793b48e55777e794f1694b1605d74dc8726fff438b481125f219eaec","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x6df2b54f23ed4e95235c6e21ada2cfff5a2615a6","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x79b6df832bfbd04085d0b005a6e3ad8f00fc8717eed59280aa8107268b71e7e0","input":"0x","nonce":"0x17f","to":"0x6143d939b2d117f4b998d8d88a56eb0e0a1e9c31","transactionIndex":"0x32","value":"0x186cc6acd4b0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xcb641be908976bc0a035b0b31a96039da9e63e829e0a24a092ecfbce7724b9c7","s":"0x4034e7dc4001cf9f62a2e5dc4390229655b85e9aac5a5b263278e9d2cb43abb2","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3f5ceedd435b6143eba2254811a39fc3423f18dd","gas":"0x186a0","gasPrice":"0x82661bff8","maxFeePerGas":"0xaa246a58c","maxPriorityFeePerGas":"0x59682f00","hash":"0xcb2fb25d268f65dc9312e89bd3c328c9847a3c9da282026793c54a745f825ab5","input":"0xe9e05c420000000000000000000000003f5ceedd435b6143eba2254811a39fc3423f18dd000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","to":"0xe93c8cd0d409341205a592f8c4ac1a5fe5585cfa","transactionIndex":"0x33","value":"0x1c6bf526340000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa48a4ece6fbe881e342a4eda767c82097c3bd47dc70c09ef6a4e7f90c0f8e843","s":"0x66c92f16907488d115f5088ed8ff4d71c966232458479245bf6dae45358c0429","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdb4f0eeb7c89b00118cc74de8c9ed55d65c2b933","gas":"0xb72e","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xe483d4a36ad19fd5eacb7f6d9ad3ce080ad70ac673273e710f6e3d5acbc6559c","input":"0x095ea7b3000000000000000000000000805fe47d1fe7d86496753bb4b36206953c1ae66000000000000000000000000000000000000000000000000029a2241af62c0000","nonce":"0x120","to":"0xcc7bb2d219a0fc08033e130629c2b854b7ba9195","transactionIndex":"0x34","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x6d73169394cb6a9bceb2dcb16aacd261705096f50f30ffe146a09659e25dae48","s":"0x496a1cccf01ad2ae7094b8da2ce50c0a990baba6300625c48ca12c5f20005a64","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9ac253db14a434cbe7653a99c5039648fa4f7353","gas":"0xb4f8","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x0564242c37d5013b671ef4864394cc0f3924c589f8aad64118223a9af2f164f6","input":"0x095ea7b300000000000000000000000028ac7dbbf9ed6ece39a902e76780fba60f1b2e3b000000000000000000000000000000000000000c9f2c9cd04674edea40000000","nonce":"0x4a","to":"0x0dece1605795461158538302b5f0936afe78c4db","transactionIndex":"0x35","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x15684c9697dcc8d89abe562c4315bfb959938fe7644c00615d9e147a4e496ff6","s":"0x7c58abea24e1fa8caeb73a70219b0d63007785c39694fe5ed2a5a342c99292a6","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x22496eece162f52d185c07524d452b9506e9fe12","gas":"0x186a0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x48db358e80b278c3a46c2a166339797060a40f33984a5d974992cd9722139d5d","input":"0xe9e05c4200000000000000000000000022496eece162f52d185c07524d452b9506e9fe12000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","to":"0xe93c8cd0d409341205a592f8c4ac1a5fe5585cfa","transactionIndex":"0x36","value":"0x1c6bf526340000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa50e6ea1eff21fd33d69f8c74b90c28303b92ebc4a77c71b65c4c8bf3e92ac8c","s":"0x29af3bce2365578b76dc528917b44e96e4fe2e7a8f948eff3e379721f35664d8","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9ce3f4210dc06889ad5267ef0ce3ded4bd96dc50","gas":"0x249f0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x69d7758db91fae31fa35ecbed4d40897c5087f45dc796cd796b8ceead21f972e","input":"0x47e7ef2400000000000000000000000089f01bc9865324583380d8d7ed08b8046bffd7fd0000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x1c","to":"0x6cf3df5d00e842aab1eb504bcf01ebf81646f7b7","transactionIndex":"0x37","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeefc19e8dca874308c84712c3e48c032a25971a0f7dff16dc47633ba7a4f5b96","s":"0xc0994cf21d29cb0c5f1e666538b58d6dff3b9ba2aa7545337da732c4b5938cc","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xbd1c4e36842c06e53b378eca310cd2dc79a78cbe","gas":"0x35965","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x2951478916ecd27a8e808d08f85be4bf2c0b0e0546f21f4e309145dd96eb8df1","input":"0xab7d7969102507275d685f3f55d10ee45f7b9fa39c29a8a604a7a971c05eee739e63938500000000000000000000000000000000000000000000000000000000641cfd18","nonce":"0x252","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x38","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x87fcffa38e0c84cf80fb37ac1e538faeca21462b0a9ec25af0ca0517af22789a","s":"0x72cffece99e79edb7425a9d660590fbc395cdd0db8fd4848074c85f814b3cf63","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x5dbcb3e489fbef1656dbbd7bc4848ed0e520a089","gas":"0x7a120","gasPrice":"0x82661bff8","maxFeePerGas":"0xc8d5e2427","maxPriorityFeePerGas":"0x59682f00","hash":"0xaca9028cb5d55bbf71b7bff9884a9a3b0b38a575ffc8f8807ce345cf8bd298ef","input":"0xc9807539000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a7a9d91e687decaa6b045797c2e002d70001b48f03020003010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000002361273ef6f000000000000000000000000000000000000000000000000000002368a4faa14000000000000000000000000000000000000000000000000000002368a4faa1400000000000000000000000000000000000000000000000000000237b9042149000000000000000000000000000000000000000000000000000000000000000288e1b54f6e54124deb78bdb67cbfd0bf63612da12868fc281afc34bb26200a1771f9e00fce297da11cf49427becf350d0bd20a2277439fbb2e8db0fbb5e3d34700000000000000000000000000000000000000000000000000000000000000027d16a90ad0e1f8d924255e6380764fa7c7d46427c8e8ea19f5ba6a9d595297a340f141f74e705d0fe851d7564eba89fcde574deb5975d9126867cd927a0d92cc","nonce":"0x11d38","to":"0xbe57bac491de9a260abb6ba2c9ad4c5d2eaea09a","transactionIndex":"0x39","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1eba7bf95bf63d02b74d20554af050eedd78ecfbe1a42ec70badb36ccfae4bfd","s":"0x4d7f8d0ac2be28e59374453f24ae6506a81707cc57f0d1c6877b49b3949a9a79","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3079be9d8622173f02618ba2b793f00795d4f320","gas":"0xf848e","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xd9a8cbe9a","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0xc7f625a19ee41a1750eac9428b4394a9a2476b8ea2d31b4c2f9f5b4fcb86cae3","input":"0x2169f79f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000fdce50000000000000000000000000000000000000000000000000000000000003f2000000000000000000000000000000000000000000000000000000000000001f579a43ce4f3e38c6a948f1ef3bf7954c2059b087b18fdb22c7b69d61727a5d2aa16090b4d1f3281bce660a31d3e2789eeb360192a54e3ac3513c5c8f67b7346fda957c92c1a2981bc68a47d0282e78df2fb63822f06f410e1ffbee7eb83c425122be9be94d817e2e42099632fb9eb5ce7c414cf6ce48e4ed2e64e46e1558ca809742159e841e3de803a8cdc628f7877bfa6d75af4b4ebb185e6d0670ce83332478137fec243a38c0a80d067c955cbe13103294dadfc8c356d0e7996cb62fb2c683e6dd5ad58be934f57375920142990074f8a161ad2390a1e6bea9fc3a58dc3f7e002e9952a68bff229437d3fb4cc1cd8097032b22c884868253d8f2f69c75ada0fbe1dd57145610ae5f451b47645718aca7432d8cd3193d0b96417df6638fd47062a1cb1f63636236fb72195e5a46d1b37f493b8380315e5bb1a6fe67cc6546d62f2c73aad5699e6ffa0d49ce653bcefa173fe0de7b4328aad75f74d15f4f570a1839514550d576e21b8d16c8355b770442f0740e6e5e77ab450ee1fadff8daeeb25a91585192fcd3cdd64dcb6a35e41ff47e854337ebd0923ce280cdacff2ced48eac96bc9f910391a44cfec243a8660ff80c10ff844ea22411953e0387f87d2c2ae81055fc8e87d59e04cd7a923d6aa5204b3eaaf5b842b5fd656e9fda16c59e90c64ef51124fb32f8e63442b1f79d3ba3c0cd5fb90895103719629857d5999b44aad2d69380f48dd824795a89dce14bb82600701ad8fa9bbb36fe93a97d75da26ffcb1a8828918e0293680ecb12e1b772fd98637a7a83cffbca1a994fc889ed0c0b20d447ff727b9f5dcb9a83e1aae9a3518dfe1d7ddab1da48310eaa7ab293d85dd9ca811bfdfee990459fa044c9a9fa6460e5ff7612e42021f16854d790710684663bb6a10ba475fa602b02519f03eb544fe486d9cdde47ab7d4027bfb8f29d778b3a7cc35a9f78dbb05943062efe3b388f1a8c496682a0215265b99fed0363a1061556a40e0539a6656b6cf8967c8fb3092a7fc9b56af124c8f1bd0abbb9af753884b22b333410d47d80c083c9fee52dda8907be0c87c5496f1fe9ac4bf4dd4f06d6ac0ac0cde22138b67bf782e8e9b5c991d58a2a828b4c68620e6d3d26abf8d41005a00866cb4095518b2711636f2fac3b5e26403ef96f5b1765519787ed74c6802b445de029d7bc696aeef5a2e605376aeda4f495c29af66e357c6e1232d7a2c3f22c0bae0c62372d6b2690e503804e2ad314c38a4ffc080d36213458f606075d32dc0a365087616e94a972bf76d7e5eb4a53292fd0d7570cb6fbb4540b3c5ee6deee0f257fe8703d5d8d0180d09754bd9a05894e77318b8c8fb6b4a56999bfc6c405c09d9ce7fe424812db5bf778d7d8634b2f44ad6d00f18615e4c3695d9c5965ba51991508405187275840a3f27cb3101a9742c49edf42dea79ae5418ada42dfe2042f931af15a205e64196b04ef53492a450423c2b63dc849ef72a166fac5f36b25c72d9cb4a2507d5ad15094a979b4ac4ff8eb4c90f448a81fc6dbfcf6a228675ab3308bca37bda8eda22b61ec7e596f2448ee6b7cb6eef589f43f28fc5444d1da3f82ddbe574b774719a3a7869e897e642735517832959ea9cb9164eb2f7665bca1d2e44e1093acc7088271f2be20459c383f5762303b553af1ccfb3371e4eef1f102ce70d62620c5164972facbfbe03b5018265ed62c4c3cc49522166913517e2f2718edb591047a72e818f07c645a18aed87c0384d180dc0bb7fe63bd335b1c09e58571b92e2267ffa5712a33e4a92231d9da7b005730f6d6559ee685edad9a9031c4708c8642c297287af3a3e637d9b5ac6b23218977cf4d30231a79063987f98313a2bc0ca4a73a97e441a45b58cdd8731fc269255b415a9d2ef2bb8a311587f39f6dc82f537cf86a68af19a68c409910f4dbebdfa66445361877a3bf551480d115d8768e8650e9979472a64802da3625cdbddee8f02678a3cc6400824d91b3c7d4c9274b74fb11a9538f1990fc314d35564a0cb0b384590e15cb93db1de1a837b9319828b3fd6b76f1d2bca4ac765f9ec4366905f2dca69a4c8c194cf0a5d821c58bd291e8dd4ddd829a873d093042c1b8e1bb2bb1a95e150c0a0d5c3369c4a791dfcfbc3e631da3d1e704214c3cf8318901f9c58465be78a870a040f34c567c27eb077db2d1ff825a127a038eb14c2890ff9a8a1dc8d6360a91fd788fec97599a318ab03f69bd50a5ece92d96c49413b517579ececf71371b6b1d902b1dbbf40c728c64fadf368582cc4b3c51712c8d6441c0c61802943624e93f9de9eedde87056c21ecf66b3a6977af0261ef48b4c6191ca7ea70d6acc5af910ebf247e2a4429c506c6a41f865175a9bfc81dbb69e59ec2c47370fcee9169b8749c852e7a1275c1278aa3f88bc16d311e58aa9a579ed7bed62f12b4c4dfe9c493cf33f979f667eda043c2aaaf863a747b208f3aa2ccc34f07b12d89bfd75b696a82c493e7eedcdc41eb01321ecfdcb691d14996c3ed7487b5f831436bb7c25876c4149cb6222dbee9e1a05771a8abfd0fd530266476e1bf69d9a15e99c901243585f56a77ef0e6c684a4d49417133ebb91f896176ec3a8f0b966eaffce96f129d18960fdbf5917f8aa0926d52c57192f99e55959369e57ce85ae84ad944e40652f6a81ab8da1dbe81a827366b8b8d2ffb9c7b93087f7a356a16d0022ee8ae891060e29ff11f9f17b01f39b8024baefc8b928a6816309a5c3fc92ed6007499353b5f1bc5700d5fe67f3e34ef3654712b9c67c231f30dff485213b94c20afaa91540560df80ba9ff1cc0f6ea75bf1dac0566551050873c112478f3fce6af162397161e1b41e1ca295f327a4f0ccf4d15fbe58e20a23698bdc25c751d020df371cd1fc59fa51dbf7ad619d208d7084c5752984b5fd0e3a7978f2c11e6b26531fe03c0cb85519483d668bf1dc4dce24509b00aa6e146adb49f31c2c937a2d3a08f1cc0b73cd66f2cb926f0453cf78618e39cbfccd6e6a3b4909d6874872eefed0e395ac2582d8c1d0483007fa6ed7b735323fe8fa1c4be83c725c6b743f63cbd0d6017f1145634b0b905552a2a237561b37c415146d0555a276b4b45d515ed7dab942f9bf40a26d5366032f23fc5fad8b98a1625a841c8cc97dfe0e2074a363a951946df16d1261ef6b2da7f5789dada153448b076637f9d2e04f4390e9dd32fd5e9ab3f5939807bb451bd19d962403da9dd118f1cfa91731973bc721e5ae4a687bb2270e3e76966dd2156e95796d4bfa6b4c10caaee46e1d8f8495f901cfc241c6f9a690349eb0752adb220996ebb95ed26ef376dbb9eea201906a6a3eb346c64eba3c9e4d1b3088baa0ed868cdaf063a4c2434b9d1bbbd69f44ef659262fad9535988ce729aadafcfc6c3ff741dbf8b784b3465fb05f6d5daec91e915f89117e01c9b0c99d7b7cb78e44f5c28de0d3b782de981be058ffa1294072c4e5a66d2d81641d1c07a9a04012f9f1ad15028709fba761a659becf01963de0cc42b0e16bc5432cffa00722a84628373198dbbe75f209115c4e30e60297c2d737996dd9aac330f4a3e82609dd33460438026ae287c172af8aeed0d6c71b1f9470d60588ebd365f20d596999d97c7a6f265890c719dfe43ae1ee5bba122d9d4cfc96b399f610a90606add4f0d25b903c7ddf6eb7bfdc3b9f926243108f591678b0e92a48d52b1dbcdf30ef8af74cfe34d48d0e02d0f99af2adb090c489d4214f3562d3f6a6e9b83b54bb6cfe6c1961ecd2eb2b7eda63601c835c5dc696b32bc495bda9b6567984f83e79a9d4ee88b140dc78cdb64a2ba8761a827cdc8d2b27e690c22402178ade602f2e9092a1b07d56d142bd24d665d7b10bc7646eb6d6823d5622f1fb08f2e48b8deda6cde324d6508fc428e3bf1a9ed608c196786db4e8d6b7271a07e4f73d9ef76244e3e10aa13fd9b82ce2ce72af2df7faaecaf95d885e64bcae16f9b59ab8e0f21a2f459d00a290b0dc57e10bf21ce06a029224ae15cb86bb1cf060ddccb1f6ae82d767eb077fa4ab0f37d02a4bede5d3f8ee3972a6a3a438a3cd92ffd6c1fb11cf2c68c2c6d1efff62b9f769e302f6c5eec96b0c05a942321ef8b9cf0ff2bb80073a8fe138bac5bd8e93f3b27e7ec7a78512059fa37b0b6939f3b1311cb6ea154909e9d316567e013df315e8f02a80e17feb8f3248cc3f11d1253ef3156d7f12d1f6d7a382d6b6ac6abd38fdb5d954e13ce005ce16bd5625a5df01883409f4ab938a59a75b7a816af6a2447b2c65ea55c0ec4e4f23fde145a26ef0b13b740b352809c10b54bfdf30592a8b0d507cb8210391d66d6f68d06f3a4663756697d472adb6ba78976b423ad9ccb3a3bead9de51e324fb77609729c78664f4d37c7c748ad9fad95af355be4f00a76cd5cc2c0b6170fdf3efaa2571bc8fc2d0d24682fec5e034460de55cd0426b8ad448551032e1f6ade6d96682bc38a92c296e5bdbf42fcf106d14c5e8a4acbfc0cc1f0bd6877c4469be8b204ffd5d7c0ee85e7b3265011ad5e4896f9f8a69997e321a797549cd3c1cbb0301ff30c3a136068ba37b2176e556b574a542db90250eca38f3b0e418e352b5728206d6d531ea253d781d771ad974b476a045ff14718d9a1820fb469e981c7b71ae8fe423b0a04278bcfc967ca602254de37751127fe3716456df3fae50ed508e529c2181d63479b6464bfcde6629e8179f8d5fa5b61003edfc2f129affa58608d6145de98ca8f1c0b3b9b5ae996a7fbc6326a9ac2880206fbeb1c99d0448cd1ac5f275b84e4be03258f9fd0d3f44a692513957fa083a462086787315e38aec8c09b96cca034cc6294359fe00285c607d41fb4e3bf25760ed1ef0802bcc40b2fce2cfe1c64f7c34b21d0bb1f5210360079ca8638ab42943b0ab8277f1cfb1e529073d2068a36a4d8ae8179c32bf66ca335d698f76db1cfe5236e6427e01804464c1ed4facf18ae09148c5a0cc9ebcf6fb6c7d03ec6782b7595816245ac2d1fdb3184ea49800d5d0f1dd880ff99d6016549d63ba2a44ab96f0db0d0cbd5fd4f67af1f1da0b1023883d4b2e7cb23cf85c617c180a771267fe63c70f19eee28fdc50c57d73b2718f8001383135b859f4c2fa3b9a12d095beba8857df13e921d9dcda5b87e1fce6038fc2f92282c717305157b6fca5ca2c23cb7307a093512f985628e75326e0bca2c4dc5ed44bed8e0cbce1238f4023089a81bf62b04a31539de9c8a0c867b791c18a34abcc721c0e90a1604e8d2855e78673367ce463307f6036850b81e0aadc9f81d8c9ad6e3b81d7850d4a46bd6772e651e03581a7a55568c9d63c1b1e8ca947174d68afcae6401b75dc7397be3c0dd76ad1827424f9ea9de8ac99803641535dae3eb57ee1eb1e2c193bf66addd488da55055bcf93172b1966364db4412e44bde64c50f7692a38d1536683af14fa057569cc7ef11f614a58995ade1b12f979005a53bee0769847deceab4f58f3d062767f7ac0511a04fea349e7688ab26425cfc369127325ab7fd24d73c4a8b23f099892b3bf52f35f0d775ba753098611ce35c56873a7455737a42672747bcfa99da8c8d0f06d8754d2babe3eb303cb06ce69e4046541ce63b6c28ded5a6fbf729200060132e9b01d8646b512356c92d8a642de0f62d169b195cc2e7ea2efebe550b1cddb5df7668a0d1f94a2f5cdf7897e46cb03b958ad906393c7d252b58493ce6c7d813c8fdfd5ef577a9e778c64d48c21b130c4f6a57985b8122f3cb69de015081cd3e247de65643f9d863fac6935cffb2ca23083d4fca9b8707679d9d4c3cb34d05d092334b1740ccf4b2aeae724902ad4fb4bceaa642b3ffdd5b564d7bfb725fae91f5c7ab9583abc2d80afd2272b14ec6fafbc51e35bebecce63bd95fa3f39e4e689034c47628345c4d8e30a73c36d87d289b6ec715a2769efacf39c9f19eefdb311b9800377c5c61aadeac78dba6946da4e7914415eced875b66f10b96ec98f64e58320bff09e8ac4f5969608171dbd4ab5883548a289b52d55aa82da62ba3d9fa59734d8f810bc1a40a0e3b2e116873116fdd8bad95471f16a14054fe247637febb6081d00e7ded3019ec03f76ebef5401a27f380fbe8a55bb4a0014f61276d9aa5626a34e7fe5a129a75ff130ccfd78cfbde65416882ce9ae9da57a3a04c67d22d3a12e811b2578fce5f6a64a09a86782bc15e5872e546dcca46bd9ccce5b787d17c70d6b075bf4c789ca184dedad3485a0526a61d280dcecd984fcb7ec663f8f491e91253675877987433e11b9cfcb5940a1357b55fcc5f977fc898f72e8199ed5d8d2554d54a55d6b4b3726e7fd7093996e271e218533f3b31257aa989f5efbdb12dce02d18a5188ec32c3c1c91845a17011ffede3f060f19d59b6565a352e90c5ca30eb252c6fb0cc845833e553f0bbe1822b5d6b26eb817608799b5b77c2cce27beb151060261f34ea73db94bb2fee11864aff76da5b10b17aba6634ae655dd396fd7e7155013fe3c6f840ab1ba9b25489c67f6bd5967a62134b238c325986c87aa005396c54af6357ca88baf5a03e353c8b0175386157d9221833585921d581f1fd3f5d9932b24d41895a5c35be91b35643e7091a7585ede900853aebc260b1fbe8b72d527390ddf46472f7c8d5844355ffc0b731dd5e584e13d65f2347131ba8a5161a6749458c1899b60cf9f9f8810889fc23b5d0fe2c843fb5675cfac6dc8ec8125d1c582186eac82d5e0b3f6df2a83eb2fc23c4c3f873267deb5ea86dcf1e3c5bb39df23f06560609b9fbd89511281fc7d69fb19764c41168a539b44f0603a52577c266fd601c0cc849b067746b4da78d280385ef80a3a553dabe4b137c50152f4e1de456d43e015e26f7d76e612b7be29b9f8e15c6a73653f5f7dc28aa245e64f076130bad58bbbd3b024c97e267a96365f019846d965c037116c74ef18415ed5500f12a1816997895f3bbe7b0fa1eb12a565255a64d5eceb2272027e45ecb0a1a8b5dc99128c002058c569076371703e1f10368c6cfb830ae8bc688eb143da7a1780dbe29cc4c83743b25d570f5d8609df46c807edbbc96358cde9ed0d9b8936271b3ade28001a6bfa6ff7ffeb4e6a6687e803b5e8f67b82e6dff215ee4f2caee571b8febeeff368a89539d145842526fef110174ba3a2d9f1b4a348dd25dd964efcf88847d3eef1c18fde81ce84b80cca8588bc1fbf9c9f34059808d3eef3fc2cef7636f7a76c533933b79a9dd2ae2791d1ab5e1e715837a766d9df1947d5986c21808eac758461596870b744a6a2862f7f5bff0c7a3460875b3b326e45fcec1cdad1cb4b99085748d69a62320f7e6c53c061a55ae20368a4e6cfc126cf2c0b410af545f169fcc741cfcec4947f577a1bfad47b5080ecb41760b5056a9bd10a10ca43677de0e06bf36b0d2bf7ca605b9217240871ed1ce43bbd07a7e77d1901dde15e173ca344ee8078ff115e954a2fa660bd4af61ac32256fa7d62af17a4f95adbdcd09b933fa47828d91a6b710a5c67195797bc789647db90107fb527b8ccbc1200bac302dc47a366d170314f5fd7b60535130d76832ab7a06ebcd83d064c1a1c5a7386b0945d39f8ddfc3503415ea22514a0ebd0ad74e3ece5508d83355cba944b12b669d6355a6143921533190eaeda0337a1b89ff9db0cae62a239025bef078137362db71a9eaa6d0a26fcda7e80a9b8fa4a1799819f0489b899cba4048c999fda79e0bb046d7e765d9abb445279efd13d47fde8b731a944af92da8d8965bc4e90d9da8ba0a9c385357e16788cfb663573d9d34810c754e86e3293a868461b241d7872911e676e73136557db1261573962221589850fa5ce049d2356e6630a142427a2cb2efecfed09445edd112323f0071f63f6a42035a9248efe155aae056db25b8004204d530d27027c34eb6937a5a05bd2096eeb1fa266a0325cbc7ac03270b751013b53429aa2d8da2de8c12e7d4996b5f1dd365e270285d2f3a65bdeea9346d960ecf015215a88f465a66417d12d95be2c0bb3d8e15163e0dc66028a30f1f5506558ef534ab28cf6dc2b7d12f49b0e319995efbde71978ef7121df58bbd16be908298b0abb6197bec22c598413283e7893f0fa7398369b83d30b29560ad09a0a24e029d0c22a7cc6fe53d84a7b2104681df35cf4c3ffd90b14cacb2ebbb673ddbbba291feae96498b30d024398676107d3efdce47353a544c9d885cd5cae19588a4b9e29c700c539bbcc119926e3d1adcbf4e8fa3dfb0d5c2686a3fb4ae7b4b278fd94db5efcad7f280488702d9f7675aafd248960806df3e8f95325298968a8e7bf54cd2797decb5bbea7bd3cbe34081c0b65ca9a4d0d08d86ff39f97751471e09f25b486dddfb2975edd51ec77d949862dd4a658ec974b8a5a381ca5b7314b677c4491e07b43a5a9964d95e1a29fc1d87cbf1a64296f4cbd8128ab13dcb60dfa8593a575140f5a9fa6a3708052b3bbed4b129aea88e66b72e583f1fc285ed6f835df0d4751c5d5f004ee0c65203ba9fbd8ff70fc255e497748f24c476d18c94089bcab8ae3f933563c6682e5452da8f760943c7efa631b2980e6589ad4ee83c88fe0b2ed9900571c3df6bac839df1a6d9d281a5ff627d41ada13b867735aa7377386182b1b113f237c14b6d806079d2f7c234a7cb585e12a5b16f7064fccff99386d58f91d9c235eef730660a02ad37dcfb0352b1da76d739ba7bd4982cbb8be48494acab84451bb39bc59521c9873ec9f53cedb527332c47afd919c94d777e603b405e8563248c9ca72f3b2fb52f08a876778d18e7d179f6437b64f79ca01f6be06d7b115b8d3c3320c2dc0ac59c860aca8c92407ca2239998613f44945bbe2c6a0ef0890ceb27467d1ab805ec960e6e58e49678a0841823632f62c58f540f19e82bf719e12bdc63db5363fc0749877539865a05786106b58dcf50bbdd015893b043b21bc1f24ef9eee5f2487d986db13c143d3366260ade522ab824fe82218daafe5e42c50ef740cb9ac570a13cb55fc30c9017228f2c60680f75ca89affdd376ce70ca5223078a47da0aab9bd18333c14aa021e6c088609d7a2460744006f149b648116152e7c814a5730bedeb6ebb59fe395e6b15d379909f197c4703dff34f8915b26a36e30088cb227fc1df108560fce419f462181e468b5d94251fe1373e0dd004fad02d690f8f28bd972e85ec49485cfcdba717db66e6a343044a2453ceb6403fa0795485f8014225d283da4c3aa6fcbbbdd6b04c30c96fce04579578882a44fe7b781285daa11ee71239c1b69791b8fe45868fe6e85341b7ba4292d6da1ae079875b33d7aa2becb02327a17bf2d09f6a42e9681df41890f17de5cf4752880660a35dab912d10480f20f92589d52ef4780ec28920d11de0de06bf63d61829a3d0894f9a32f911ac79041ef51fbcdf3f5b03f6a0b16f0b9e47444b82efa7c012e3bb9324c8649053433306d0640ae953737336cebe9b854186f9dbfda861fd7eedd76fc24634acb9cb925302d0bfd3751b7b6bab36ebe2ea80cb7c5359a505689ed5642118ce93cd783c80a2cf050f57d5acb62853367ac606fc1b8a01abb7b29e49fdb190e2b586e249639889bcf5ad23161f278086f244d0db0f9ff520e6858b68f5bfa0f5ca700096277ddfbcd14a4cf4358c0f042b1eb34bca6353a1383f5d310176262ba45512ea4f172f321efe971c391fa9e9876a250ab653fd6d5a8b046028018ae043da256b78eb26d86e6e89873476ae24dad26ec1d39da44ffdcd93d8c5c1fe0796bd46dbe9b01be0aeae841662c10ea28cbfbef76f0197cee86dd4c7dae3ba46d5c2884ae977c456681d5d9859d854a3e0708bc35fd8415c22ef4cb889bf0e66da72ebc635b71f5df04db801c76564d2fbd946ac17e27fbf995994ad26c3d577ac86b3b19f855d87bf3f0f7c3fd574b89901732dfacf2e13960975176f7418893b31747d96bd981e9b1463590bd35b51b7a2eacf1a7733f76a7d4b02fa2afc5925f5483f82cb529682f785c21cb951d5678a7d09f99c0e2bd98948b79456e4e0b5d9de80943f1df0c639ab8acd6c99a6297cc5a53a829561a6615c6c44b24a30a75174aac207a35fc429e1a415b0813857ed85ab49db6e523cdf9b122c2442a4fc2b4fc21685c9c4a5de8f36c0b405e34ddee91832cc6567d458ab76b4650020d270a65a562e75e06a3d8f1313b4d1d4d29d597bae9eee653bf8e31b82f9cad2d0848ed5daff73d99472c7e71d2f1be60bca4ee9d315196c096cd8260192597c8ce3cefa9cb6f129dcfbcbd65b5b0e19df5a1e81bdd423a2e26d11ca4f7aee99104530c1c8e3b1150669f16acf415559a38cb27eb6d637c78b1c90ddb5eef14ab9b2ff14ddababd7a349b7f6f5b6caa3a28c45835c9beaf8f836848f579598ae80ff9af739cdd800c5a3d7675c780ad66b2c449824d8ccf55a7669fb720604eeab427a0308122c3039ef9be6df46e34b719aca7a001b884e3f7b1d1579176aa4d365a25b6f3d420190e3cd9babefd8382b6bb12b4c38b981b08b5a139cd46e9382c01f361abdac7fb16b87e2c61f3241191028c770c3e3be939c8825c63bc4e523b389d1ee28189b5a2c11ccbe0aa7d3c2b47443028c89f3d4bc1bcac39eb61d91e75e0d372b9f27c8dc622a86bc0cc0a9c9dafa5e2bc67834a75805f3bf1571fbc5528e4c69f3e64ed27c1f2d93f43215ea0d4213bf2809391b8b9201f36ee2a275dc7c44d0d83de3b82490b65d2b399a7348133c4df7ef40e6dcc114d040f65de00a70cc0c9fe615c6fa90a2fad6dbcb39370af043345ebd9d8af094c831f341fa5f7658c2c1ea062948fef5015696eddd181d87dea49ac8bbcc2c7a1ea01ba1d04239153ca401bdc27aa87093a78b2020109d7cbdd39f279a7d67b14a5822fae28854323a2620033a5fcf9817a0d45eca7e2d120a113fd5ccd9fc0011e89398767f7f6b7d01d5a670b4fcb9c5648991817a62edf43d6964de204541a8b5573d7cc10bacaa1bb835f87d12985ad5fc6ac4834ce76c76e5dc34cc322c4220d9d65ca77051e7c1d4edcfb4595db16c641fa445401c72a24e36567631ea02e4875b7f9ac2ddb4712b79d1468c7ed2384ad5d90ea0825f817e42413de33eb30861ac92e19b1aada118beaddb179399008137f28a8f3df1509ab12d6f6ce7872521f5cfe4738722fdb410b3824f139ccf8ea63817d154b1e497a70e6f55b75e4decb73d10ddb0c57d7e0f74b3f4fb41ee57c2da1e4399c2577f28b7e911db08e877c366f231114cc9553c7f3cda2b75895fb60ce9eef4e0c25d253f689dff5e4f9cdc744c301b6f13e9fa9e30bdba8abc203c05879ff01bf8c3a3aa742ea5fffabbd6d165e50bc412bf5e18c60bbdd4fdb276f3bbfef246cfe36612ad61fcbd4498c18321a1ee12e6dee902c737999f9c6b3919f52125cc77e237a788640f262ab76d5c9db9ceb2d988c261dca63455658293b10842ee0b30cc1f928215e0308cf258ee39ba666b16319d0e21df8b9ed91be2e2feb9e117682cdc9edbc20b0b3b9ddaa93ec7a2d8f752ebaae57b7d74037c5cd64cb04746a38c0ea3ba3241319360e585c257fb593c123a653e6e0420fc540bcc0f072de6ae1a31b57dd5acf0b8607e04d21b727c93623e5227202a7c6432b308f74266dd1e1447a2d637a5259fdcd1d8729f341a7dc383b4c8a6ae0e78c34a55793043d2dddbbca1d161c300a8a7cb760298541c90a1c5a890b5257369b8fea0b4d14dc0848e644953cfd5196494e4c1b422f8e188314f2fa903fe93393193e9b76bb71c0caddba43d8586d72657a2d717e4b2c3a0e8bc33a6f8d89b871244eb04e4ecee26f9b71ae7d5c44f828083b0c1920d37cb5d7db86be3b18ef16653863762939cd1ab5c5e0cd1c495ebd0a3037725470d526bf12d21c2fbf4946ec224619c79906e8c87f0699be8a3621ae718aa232e26e43bf7cace7918ce34577a5e27261a4a6bdbbb8ac21a8a40b0c9682a0e0a37b7fc43306820b0db5fb5bbeed529102187fc3e5019185588d1ca6222a5e2b60faa2a93857bd7224e1e1c3c86128fd16993aaacaa34d8679e194ac0da6bf617144a2b1e844e7f6f8884df05ce1624ef1fe5d0895265bef2de61d637a74f78f6e3402923c9363656b7b91131dfc8f8f7360d14e01a25869f0f15a9355c07bba82e4969f5643519611d99ee9566138e4610712d55f22ad36c7acdc9e32b4e1e9b1ee9bd14ca122db05938840b8f47a5fd25a26072e2055494eb4ba916473e973c1efcef8dd7f0f04711b7e968d59d144fc04b9c6d8f951ab973441a6086ab6ab896f4d282793fb14c74322c7ff1c4c1c6d0544b7457635a6fe2632644344b1fabe12633b2f7d8fcb6e0929a05aeb2749fbc99671283c47c0eabe152fb6215bbc6e03d61b1ae955838a8b7b3bfa883a04f5156982ba433dcb21311fe9027a5b2e133cce16ac15786d2d44b5e4979cf2a8667d2976ea386eef4c85bcebc39b9d2dd216e8b4f7c68b7e0a5d7ff570770a20cc605e66470d995ef96f1e0acf6136716cd8a26b3b725db3ff48364f19cb2c640600d00d0d728d8fdac7b8a205ba8109318eb5519ee03848e79a1c33898555b298aa62d6da66188506638918b46926a99ebfccb649cd6bea1eb87fa6c1999a70937f51c4a2d485c6aa2bb5f98b1c8ae558e82287b9f34ad70954f8dbf3a9736604c43bc3062f8707fe88483b0865bd6df65f7e085593d5046554ee465a10ddb0c0b651e2b1031d56f5130e100e4544809a093026b88277e4e1f1e3aa40997871ced6e6eca44f183ee09ca679e4fb0796af62cec931c553ea788e75fd37ced477f9a58e54410c513fa79a4b5552b049fffd7d261d90a16f253a0782ec75219d1f7492ac2a242fc04c0216e6c804f8fd8f761a70eb747e1545313706136b085fc72dff1714ced89ba14a65a34168dc0e997ea8718ff304a962cbe8c7df8b759d76eb0f18155e49822d21d91dc8913c323a824da271f8c57d44a27be3f04991e2a47e5c8da2f0d71610be89dd4459b9a9f5cd4bb5ebf730a72617613667984d9a0e0ccf81c803e46425899b2fffe9158f9e3d7c36c2c42938d9433f764ed1f6d9c7d69e9ebf854db44c398c00b2612cdf19927de8bf45df70a5d4307e3a628a88a09a79d4e03742f89363d891b241383887b4447d0cf3e0eebe4a9143cd6873abfe2993b1f4d1b3b3a18aae4db4465385500ebef246adf17f1d9196f78749dba2b12deecc5c957e022f5b9dfcc3536bfd306a1a70e50f7bab1db22e98c8705328fedf3686938eccea04e7db4abfbdd939d56c0c357612ee3536356c0f5bbf1d428fb31c7b06a75c5b4fd5b020e6d9894b50eaf1df723131712344888adb5a0b4c07d23f6e853c88b51fcd56beefa721557256bd9978caca155db7f9c325f9564479c39b589431ee7d5da402e79ee6e04061c62c1f369176f6b35174b65a978ae3a4e8a25032d987dbaa5ca048734cc1da5f875f72db399df6e6a300db183e96ade56ecae019c4559c8f7c94899178c98e5071aece48a3e9f5a795159b2dfd0a1aa784b263ae5d352a890b7c2c6887d76f0364e2028d4f9046408e76efd6b5092590d39ec343facb16ccfc0000bfe7bebca2575b1f02c8a0aaaf5fb0bb13ac3246e245ace99f2186160a12792fabc0b390cb4c32f87c46f741c8fc940c4aa7843d650f90d422504bf97dd4825e533f646c6b77c4f004b7036b5480b587a913f05bb8ee470f0ab148727835b1659d8c046fd24276c95d30158424914e75d9b01fe52b34d5f76b2a1c98bc5236945fb46724e02851d46aca237fbf047f3055d6331dccab91c0bc20be2260086552fa7c958840843a3c38acfb24f9dcb506ee3cfc67f3125954d9090c1fcd629d1c3fc557b7d6ab33b9369ebc8b5b43f9e23673f688ffe50e6c3dfb12ac58aac60590991c9ce68502873fbdea04455459f6ee721570a87f87ae03a9f97f6e457ce1447358d8e3453632618701d62885ec4f8dd201e26405499dd7f317a8d2456940348827a08950d548b5c0b24cf494eb76dd0a51e3f5c6fda9f8f6545e3a6d1009775d78720f9b20ddded15c162f226873162a5076bc0cfc151e655e29d100b7a0d32c9c783375d1c6af0f39b51d927442386cc2c26337cbe5f4a34bfbb65b544b50b4947f72d839e6255a95fc859d6f1e34bb63dbfae1469be613472f22cbc703468d8552b9c691c829bdaf0d2e7e4093e940398f9ab8837baad8d9e4c710e4584685df01ea15ed9ed95ba9f6420e5766363e86ab8dfd1626eb1c7d2dba91d360821da99977be4642488972ec61fce7d754dd45a4d7fd9fc3498a6b7e0b7235c7843dfe8980bbd3a52c8868c1832f62d9e25a40986d061d7ca9d8fe29c7f234e3448fa315d749a09cf29556060307b970e5e080e90dcdbec4ecab1a7868cc5bad1037c07e17f961f3cb5641405f3d3c1439596a243f83b4f8576019712320ccc40581bf02a0788e3ad9cf4c44113d47f587e96061c61c06be84f6e35711d105f0c46b31f036356f6abd329c4e1e74f7d97ae6e4e0879be998a85257b6de6277d9c18980208e83d9bf266c9909a26f3e19941e728fe4ab0866d103644fd86b203029271361ea97fa93079ff227861aceb55e68d7454d1dc25aa8a7c780590a04756c840d13dfbde1d52d7df47d4146ed8d530907fcb13f6071e5c18acfd0a694938bca6cb081b7dbef2a646aaf55d4da9f3d42996a90655cb48144a4dd2789d75692530dc02a2635c26d428f2c6b66779bd9facebcd73274ebf333b8de26609bedad5739e73ed68798cf9882ebcb12902bed483bd905b92b3df495e708a0914a96840761da66379d85105f29e14e47a3e5273cc23ef5053077ecc513363379d2e6cb3aed80098589032cab7c20eeaaeb7bdae7e3a1c7a704cda4568138ce1ed94e944eb4ea72120ec91117338d0c86116db36f3807a70bcd98de03cc46ae9dd0c5fd3b26d78fed5a8b53c0c8f9566f921175fd193ec521c9914be68f2864715a572cd6b25948fb8dfbd75f4315967d5a6a707f1ceb81b98972e615d3e81b08ad5ef1838af673af9b6d63dccc226eda6d0b6fc1fd104f62b80662ff157999d7508f625fa2408b6f9ab4deb410ebef73750dca3e63d5045300d9b52845afc42f064bd78ce574ba9b4fce22aa3158bd058772ac2eadbf9fc77bfdf85dc745b529e8baf248a0bc1963f8fad78471116b9ac11679a326e92d87e03e316c90d15d2f9e3921e0bb6ab4b7ce91f12e7cdcd9dd141b8ef160e5db1faa47525a77a038558abd98757ac5f6313afb4f4c84b2c768e456f6de4a78b5b25f90926352fbfe83037f81b31251249fe52860f3cfa7ae1b20c73acb015821840dde2ff2de0470450b11aed7c1f84d4020147f8b9aeed4a37909bbb63508e533f939f23c2f5952ba6734745c51b837b72a398a4eb8dd6b4ee7648ecb55799cee7b6385ecb0b2e36b9518439ba550b257230885b83f72312e53afce7e7670b26342e4eb0a6286c0693c54abceaed1811418a9a289b4b09b65e84b3149cada8114e830c0403884ffb74c515bac074e4a981c61447ac99368dbe9cab8830911ba9cbb64633f444716f401aa17f599174581538918e88cd255765142a49412841deb528f44a64acb372498bd66f979d9189fa0f0e70e305015dcd3c9aea085cb0f1d79a63e92eb39b2dd2fb1b9ee9aec0213f3a4a848f3450e4a6d902f5435e234588ce4a7d2c9dbf60de27227ff02ee4ca19314d72674fb06c00ac7e5d15cd05fb35e973f0974a4718ea9b0d35bb4064a6280b654a15a7188c5d5a5998ba1f031a3baecdf7b608169c0ede84d91c9a5f73b0176e5ab2958169ccc6022e0c43481bb8e6217ddb1bd9ba8e8446aebed6afd163dbb6873d81afcb74b034085afec0d626b02fb10839bdf2279acec3d8f3f7c47fcc3ddc8cf1f08de8c8e120d9c06648acbd1ba6824ff74419776b73b05d797a0bc43d77eb75029112380ff4e87e543863ae29065e40c1b2b1b2d62a409a299ee5868036835627dacf4f9f7c84fd2f6707d823eebca0e8ceb2bd258038b137aaf43e0e937be762be5d3a6545e439a45090d397c8d4a068286836780536ad99cb138cbdc6fe5e9db3bd405ae6eb86084be3a49c8af88682dd52a5fa8f7fdad76cc0b452b3c37b27dc3cf66c57a4ae59a3687950ad3f1fdab3002fb2281365348cfcd9306583eb79a9555e8750dc95260a1b277c566babda92cf2b3ef177854fcc3dbac88da1536eb3c6d6fa3e336ed3a7a6da006901c845619fa00596af8e54bc1980aec4aa97bc98266c248bc038013020fdd128db0b9425e8f7e3165f5b9190fbf2dae5e317485d9d103695cd209d5d247ac7e1122bee4538b5b74790277ecfd2051e43a34b7c5440d1198a1875a0501eb3f519ac2f17553c5e99a9c83412200a519251d4d4ed1c84baecf7d8cfbfe4a7e50d789cc034a21043fc13fc3150314bd7a7801bf9c31aa00b7cbd9d0fa4ef0636504f0dab63316d9b9a1f4703b3be23170549fa3a29ec02f418d687589f77939fe068e41abce460fe118b04fd418f28edba4fe70d8fd24b38078a5c47ea236d73610ea116666a49acec52fbd810bb99af1dc5bfc4eaa634dbf2178151acc453f93567f015f2a25002eebc1f778da195b7e9cf683db1a85da98a99d98614f2c25b2237d4393f5799d06cd36254d3f22a53df5133cb1f43836991d3f7529cd260df88bc47e4172ab045b66e081940dff797b28c632898140425c3f81a60236b82522c0da7f0e0ec7a8ccdc73cee175d3b4543293135c31c0e0c926c7506920cea1d0a1eed64ede7572b8c77ade1d95bce10dfa69fab7fb5ba64055800593465dd4c26717e37a66089f550202a0530157e5274f3d3fdae187444f5ed641c608643eee1b361d78c9ed8070a85150c80368a84b14c9dba5b20a9059f1a05a60de938ab914a093b2e741e891c02f638c73c730e60ef8cb5d9e5031fdaf6918750f192ea7a76e035eb05d7556ad64a77109c5e13bb3ac7627d99165567dfbcfb7fdc7bd847ee7dedd7864353f8fdb7a9939867d9a5ff4d9ec9727fd432d8abb43628519cdb6fa49ce49064a421a89bc924cf6286fdec8bea6b5a7b8eb606f584d44c7194d5424f98576dc4b5ce7dccf65509727ed52f8d7210095252403023473af96eb5892cd3881f2e1f4dedd4c9b0755b70776aedead14e2606bbc1ea3c300984ebf27ca69f36beb03c0fe3c13d9df79791d828d52260103be72b832ba235bf1165250b608e2cbda0c9c8d3c96534802534080b2a4ddd5be4f269f37c4cde9d43dbb42fef8d507cce8b8e2eed799c72a2fb836f4160b5e5729192f088ab8557d51b58940065ceb4b48fec1873cc4b178166d15d441f45625f45af62c1d13863feaa8afc320bb36af0d151165c122a47d4306d075b344974835363818009d86c81e90345cf4b7d81786c40318a371fbedcfc325cf0e853fdfe6e91e99c07dc9430c04e6069b9e2efeed0eccfb161ca85d96298ae6dd67c395b78668d5818f567f2039111a7a0c52a21d84ef72dedbabe83f811184a95976b1a90dba5aca60d0313c546ea97d7b2e40b34ae88ccf4f45e28f05f16732d7a0d62dfd86e40a51de7f2b9b66ed780476cebeca547c8eb71ac20a245b1bf7445e64bce260b8871ead95f708974c3a93dcc4ee979975daa399055108854c1c3fe5a07046d13169c084b2e4e81821ff73d5d20e7556f40fa152226a6da48d5f86cfcf1a5520451c3c1e534db654b1a58adea167ffeea90023cc2b0b01710323177059e1c610154cb234d5ea165dcaebdc2fd9d9b66413b8a6848ea11a673f207ad76bd3ab5399dc0ed58a3ac0ac9d3c53781c36415d54b452a4a78e1eaa7046d062e3105541fec8819439da85ce53aa683aaed543704aa8210b26c1e6c8f1d1814595e3bce2d98a36089bd722110bcefd651937892ffd36dbc34f1284eb32c49a1c134ad460c19e01b3f3f2d40f664d90020ae8c546bba9ccf5500171ad07a55f9fd299d7518f00c0017f6c25d4aa01615fc7eec160ac2cc1ecd38bb0324e54cb466c3df4d56508f5239e1b392a50a8c20946a6db9220088d77c494406296921e3ac9997c34f15fc5c39f2529eb2bf6b41b0415e90cc9d7e8a83256cc59b4607be49eb76a7dc07c1ce3d0512888705c9ea145079085273f2236d5bb151dbe7d1bda2ed607fe51847ba09ea6431dcae727ec1ef0a201b8df9e148885e1308425d5c7fde473e90b4382de8bf5e215c3be357f8a2356348bab00a2b629dee017ecbd76d7ebd45fe4df2884e34ecbb86ea371fca29496fd05327c3b985a069a24a32380ac9e4b131ff48d58b1c528b941dc6290cbb41ab4aad2a55e5e03a63813c2113c0740029529eca008d906dcda1094571f5d2cd31ed79e9bca8e815e206b3ff3a7b4b82b0d30775e0b77260a42b1ccd0a58a91f0378df95cfc7f8dcabcabd2d7ae3b603e9061c1e126d00fde94b4b625e953b6b781da167c71a6a7ce0792e7de070863deaff94d74a7ab9dd2e3d39519a6c5c864036f7bcd4663fecd163d78a72a74d2838b6949eb7ba85dacb2eecbff1af2792047b036f77d488e5256ea16252257bdbdc1ca3d18d01c5de00ae8ce7d1c4cf103b2bd7a31dd52fa92d945da38eb9070d6f11aa9cb8bfaebe133cdd7a72f94f0fa067da0481dcc86e6eabe115cdfd8fe2e2c63c3cb3c0f75a4655eacfd337ddc82f770442d18ef9cf3993a9d1830217f50917153de7576917c533247a6725a0cb7447ebb0cf7516e19781a8ea8d1854349db9d3bc4e4931a1fa4fc075186dfc37ac10db1d3feb6298c1fabc8d897e1c806e38981c3fe7f252371b0e92efc61b2e787279f4a8138e7c6527ffc4092de912378ae692e9941d0b6d14354dd25900912f9a907dd970db649dd965c959e60f4d174ab0aeb7bc016735e8b847e231bdd240042aca16731926f537fe388b6496967b750a94cf514c9296805607b5f44451bc622486ff62e7af5c0d243503ff31d1c753d9fa3adecc8f555445298aa10a877250455c43d412719aade5a202076fdf080589a28cbeace5a63de77d188c1fb486d888528c5142f92e54f005239285cc4f8695c05ed32fddf0b0072bbf7642a1daff7246055cf35e077acb567b78c73094e583b9bac3ccea986305eb4322bcb923b93187bb3061fc00ee0b3d10702d7890c4eaf4e5f3da2143282dea0b12c3f043818914ae3ea98cb1322d73878b5d9920e87e6e00ae831a3b76484e0f69d35eb15b053c545464811f9c381337a80a603ca91ddebab47b72d6c80db4cf0646c579a136326be69bae46cb6ecbe23ae355cf7181981d8f7b8e16b3303aade349f44c005602c34878690d91fb7b4bbbaa75a91528fab18c3c8c1380c0c26a98dae3a2e441527e8c7e7df331a506eeaa2d299757e8b0cbba97a91f64e36e5a24cc83b00fa14b8a41e6fcbafab7eaa905c04c30755c551b2f0f1a24fb422bbd76090e212efa160103344200e83545a119cd7d2f53e8e5e6d89b1c75f12a44ddce7b9e9bb4710e30c853ac8d024be6f5b3d162941e2767c61a7f7ac5265d08a680b87f07bdb4d4e2037b99a6eeabef33b7ca6e7e6f4428f6814e294b7c08783525e1f632fc2a43dc057264bed23898edcc35493222a92dbe28da74c07c49fd725670ded86494fbce9476d3a594f4d96ccc3302a9e861933dcf46d03b7648bbe7bca88d9791b5a62694b34a9ee0d6c9d5600f0758e7e0a2721cadd048bf59d84bcd7ab33a5ffa8c1a237dbdf3481f03e6368b0c1a86ddf01b962520372bbb8e330a70cc684e84e1a438fc571ad9bfd297288135934aa4f1310849bc9c1658006eb1639d4b8ad2f858fdec1d5a4aa89259e591e2cc2948ff126caffa24bf41bf71b408da6b5107e1d65fcf37697d307ef3a3ce742e5d117e7bd4d095dfe8598213e0925bc9c8da414b09fd21451ad8f3531a756f15269614ea1ed728d3d37820c6e90578aa43f8f4cddeb9ce97b345840899a016591690a810c5773572f34b68d1f2f1538dd7c541508c990621d54dc2653bb4a7e9a1c637515538840f836d38333de92ff70997478fa7e4eb0b447ef04a96b2376d3e7319b49f8eb0b9c656bbaeb8a000104f3407e33c23030ee9d5d92a2aa7ff76f419ea3b1c9a8953b30a92759a8d0fd37b50e66c8f664792da1448f8d12d60e169382da435c038f10be62dd1c0430f18eb30af8c14512d3311a28d4252fd4b4dcc04b5da190a22c6eda7ad837e470b9d8ca3254f89a3e613ddc74c1865b5386efc7a8811e95163fc4c2a61b738bab3ce75e9450dfc38a52a59b89746cbb216cafa6faa0236db5b86747e7d9d3b6515bb19aee0a85bd4c2bfd76c1916e04db2e0d0382efd97d2ce79eb9370087b19faf4f269e7fdf64f6c30eabdef01c5a4f347dea6e28c48a55643ca36881ac5b283a9f85a56b203c3076e592779f91d3a00344a29eefcda31e2c66e38c6386367a5b43dfcb3978c891feda33c7907d7e4a501376e1786b9cc2ae1e0a60b9c0c979a0c1c96b9c126f647c3bb21abca0d4498c08a4544fc46ad1a33b17b105db91390689ecdbe0b9e6b5cc1d65a52a51d7d3a714c850c14c9329410c9efdbbd55cbc43e8568b01957d664de2a82c04caaf9e55ae5a34c533bc4da5c2a715409a900c7dbda950463131367613ddb0ae44c73625fc8f293e4002d5b704645c08098ead5a0fde1980d8addf0af0efa1288d569fa62d6b3f6227d1b4d628d1142f5eab4f7f1302bc97809b1b022e5976b32da3537a192938b8716307aac1972cc5b97019f4b7a9e5e650d0569ef4e7d12f8b123b1ff1d95d3d713a18dce009364a07d01b3b62a1f3ffe29130bee4f3b275dd27fd6860423629b181194a10ac44077eb2323e931cfdf64504a94a1e7683110ee8a21e67396d09b85237a51d824966527f9e3681ba9fa6db51e571d7d6a1d04d0f9bbd9d1036316a67ce225705018d1f0a9b9817b0d01dc092beb4e1290a7f12b22cc32697a75e17b9a93ff817a721ed0c696643353b80478a8d41e92b0dde35d7f2918f310e829305711683fc8c2119f0759e4bdca673ec93f4f0837aaab4c925925504fab72f35bc494a4d8bca2b2ee392af02422b2f80f174519fc83a06f99290cc7f1812a32511dc9fce9499947c92cc12c241923e62e98824b85ff3ea4979bd4362f87b7a89204598f51629ba1bc6d42354cb13c093d00c7da85b2523fee61b85573aa7d4a3145d518689ffcae21ff6470a8210cc6302bcce2459244e6f9173e1d9447726942749fb6bb13bd0d3479ac5f1e6d70e104990f2c9311046798f906aa215c002ae0b918af3db1bc591a937d5f485489a132fe9098bb77387906ae54d92d368ded939a069d0866279e0f7cd815062dc25c664c168ae4a11b9f1fedcaff8e3c37b6f7b075e737354074381a135291383a35047b1dcc7cf3b815c1b7ac187a4dcbf64fa5ef83c4fa2c0b4f5b7e024af32ab5d72e4e86a92acf858ff0aaf0fb8fc64fa12d0733c6fc530ad739df51038fceaa88e6e47fd80a357f501dc4ba5de4b6c0c573534a84e5aac913bdfd30e548c8009f06e7281d4b91b968852033af7b9e79b644b1532b9324b9788ab6ed930236c5bb2de248231f3046f490131ac34586b43a3c8e0a73cc756a816c79f3f10f12c23501947b29617fdc2a45c7f361d27966f73b1b3a1f50cb0052dcee33ce739cf2da8fbf9b7e5734c5a7fb8eea9f5a598ec6c207735409ca3401894f634fc787fbae311d4bdc8c99e8986f306883d7185a18e71b5166cb9b84cdaa3cb03231ac3053beb31ff3d87838e53ef698f9921a0ebe69c9b1526ba5940bdf21fd745f6f2653adc2d3c36340a6dd7c9ada045dfee2349e26a62b437e0c8f4fae2c7eb9eb577c20886d8a8fdbd02d245c1a1478f52e339e8ddd71fbc6d2cd1668a44e2c82b311720996b8da7111658a04f4b756d84418ef3e99713cb73d87bb4a14f69d5ef4a8b8cd6d0008164fa0a802c0679b26e155d801b40a2c77453dbdaa5a582d7c9d967e8a5706358c68c6da6c3e6746f0648401f896f1674797b0e14b354c27ea94fb12ad6d8494ecb0eca0eb5795b1920c618b429b4e95979174fd21685ead022e7ca4f87958c8a101b8b3a5e0a9d64393395b12dfdbe7e7503b62db0fa8813c4eaf1ffe5f190de55e83fc3a01b10a647d77cc49b07a258cc4e65d489451f849f6aeea5bde2aedd8e184cb9c778a3676dcf87d2bcbc19647bff28953c5d06fa73b860a16785238f9765c0fa958757b4791272cd8d1fae302b8dc47282b782d5c4c5ae75a9c02a3e911a79547df96d2c2306a2e347e83a8d8a126e6a3a21cc46e476a706af9c42a97b3f8fbcc0de5cdfb59bd6cecba11bbb93ec1bac6422b61277eccecb8b28b3d97f0051b89997c8c22a9f517d9fee5e16606614fda11940cf388c04daa1b302d3b0590a9bd0692d6139b77546d71454054197adf346bb94b4f2e85e502e3cd919bb43e8b424339e2af0e7070b035271783b1d7d48ecb6e63f3597d08a9d0677a44c29948d9cf9570e7fab1ab0d8262bb963d62e895c9bc8ea999f6f8770ed5ebf75a39dc0fe2eff88d75ae19690e0f0d52090f18bbfbe39697042cfb5293692f1e66d76aad38bd919b634ee20000000000000000000000000000000000000000000000000000000000000041187a86f715ea1475c76d354d556242c15f6b8f7c441cd862cc7c89d89a58bca02ac74c422eb01833db93e4b067e507da65080f93cf1815f4cf1dc0d53a2802230100000000000000000000000000000000000000000000000000000000000000","nonce":"0x190ed","to":"0x91a5d806ba73d0aa4bfa9b318126dde60582e92a","transactionIndex":"0x3a","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x1f02737dec59ce5f29b7e11309a33cea7b370eddefa1a8007ed3fadfd1c6b23b","s":"0x106ff6938ec0a46da92e74768b54926633945ab503e2f2dcb69469b544907586","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x2d679b567db6187c0c8323fa982cfb88b74dbcc7","gas":"0x5c90c","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xf49895cde","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0x45499074aa521ac4151138f0aad969bcc2dfc1648d22ff8c42e51c74cb77414d","input":"0x003851f8368551cdf133121c7cf32ee5690000000057b378dadc7d07581359f7f74c422f52a4d750946601a4898820282002a14608e24ce8d2412c889246951210c5eea0206041c4025828362c2828a8a860418a28208a224185ef99505d5d85ddfdbfefbb9ffb3cd964ee997b4ff99d73cf2ddc5b063a034cd01e114eddde75618857bf21dae562932ea35bbe70493443b0d3bda8e6161bdf9a2e6e1a1d63845cef77f151ab3e17f6819ec2bc7388893dbbbf49e9f0c76d8f4e3a6d5cb9c46eff41ba97c0b3794c105b1a891908a7812b16b0d1d7780802e8c7621a188764369f6bba1bb0c95c54c4e3ecad237716b875175c0e27d3cb133dee5692910d9eb1ceb4679f65e7247f51ad58b4609f4c41fb91c48acf7b7d2a8532654b741723ce4f70eb38a521e9948c62bb5d73328e2aa5e7174426f5da2a4b1c6ef04eb66b2d4d1a48f0a20cd3d8b6bff8794b3975124f8d8149ff9c0b714da5e23b8ff418940c5dadad787c4298fc8486c94c44d45593bb8dcf6cbea18578904b0c99dd61f2b7653a1562b2cfdc3dc96fb15db01fd11710145c7d6b0957b60eb6fe886a047920fc64a496565e715ce7ac34a51a8fb632f62680c9de88bce189d008e29a23679115012cd789ae2fdf6cf5f4dac0cc4aa2e092b846d3d3b36974cc62244625394645ce73c1eaeec885e6dedb131a1d420a57f945698a9e7c57befcea025554af9a4cf6a432908061828ea86605e8ae7ef301f4c388060625fc5cded2d60f4bcdd4270b2cd05a133fe45e31ff72c0fb8465065d16678ff60a4f2ebf901d2403345bd6c4459c6c6b97bc038b3cbf9f0ffcbd7fe06fca91bff93e504946e2051d05e23e28dcf2d35dd2d1c2b16da8fffcf65ec0b789efb1afec71cf481e5b4476b7df95109b64e2c1950beb3cf3ec9a671ecbebbca59aade6ca79f06328bb06669266f9fe9a6673c50f5aced1aabd49947341ec338b82d9ae31d9fff59a0511ed938e016432f9c5a001a7d5d34b54a7d9a2419456e3bd0eaa860ff52e69806188aec7e559a70415ccb6653c885fa17efcfccdb680026e43c9ad0bd5b379d4da2127d429e74dcb29f3e45b3ead08e1e85c2be6505fac13244c6e528ea261329310d9b80b16bb7b562d9477dd95f6415de5bddec30bbcfab9cb9bbf88e71eb47c16df81087fa93c4b39b5e0e1cbad17cb1bbae73eca0e2c75f73e12e89371e79a4d42babb71e9da013fdf5ff1c20a45ac00a02bf1ee09b0efb1254f4862526e5abc8cafc311bb27abd9af1464ed617acf4c1647dc8765d530e4b40fed95768dcfb24a0782f32fa6cb29e165a5745f2b44a8875a96812b99a095edaf5afb1144335625ebac2a489d9133676bffed7d161671de594b27973fdebe55eef99d65ca83e607ce6ed86d32efc36bcb4bffeb2062a99371c93d2eea8a0f47519e0b40ef21ee8d9de5e8d8da61657072561ab1cf9a4b1d51da9926a2d934cb9be7a548af7a5835758b5164f249ef0f0b53051779089dab29284dc10c24a1ee298ff1faf3aee4072cfd4ca19520b23941a4852bf56dfdf0eb075ff435f87aa51ebedab52cc3ebcb4db9e133e57c2aeb10a836d1f5484807f73a9d411e059283bb45fc028cc8f919abb8ad2b008ff7a95ca576c0c04aa4f243f10d2fcbc425ce014f5fa6793335650b99beb722faab1bae677d9939a02d3de5e0ae5d5906ba024cd019c11f0d51c89e73b8cb3609f7faf3d127f969f3beddda1a756fef93ba1a4d33e4c3992957a9c304394b7760063250a5519ae83b304c00fdf0a21e2acdec12482b724df3ac5ea472c065a9e2b7c8de28454d72ced29d817ebf3126b6928c2cd7cabbf0cee395489744896faea55699fc7ec581ad49b782e1bb83bcf535468b91703bcda0c48fef1e919dbbf30aa45b162c92f0e01496643bab3d9020b8e471695769f04020557e8d0fd5812bf346deaabcc118c92dfa146a1b5fa6aaf5db5e6fd704d073d9c6d549004066b97db487f857716ddbe6cc6332f7ddba3ce2df47f0f25911e833adf8f345677a96c7223a3efc77a3f7a5d24e543525591d1fe4afde76a4a3fa883efb81fb9e324c5727a5d2e7c04013a249366aa8f8242373f9c0aa55a7366d364b0bb89ca1da127046eea1de1d39b917fa53d6acde40da381a71d342e3fdbb19254d7df86704eb979ebcb905762ad78a852bc948b97aba45e99ea4fd7e0340ba70097b4884abc81c20e99276eadce78b6b5f075620424b9a83af6457cf29d9fa52b6df6bb7054711e789cbfdfd1bccf3081ed96225866598328089398b84ac237a46aeb513780c62f5ba256d9de6392fb333debe7b2ebf00571be5b6dfb5298b68c0c4f8a281db7b5a819b91297d29e586e6e78dd685f9810e830dad91e79459de4f2cc484ed9cb3a49eebe9b51975dbedfa1699e3c2fb9cd6a7e9ecde33677fd57e07847bdfb9bef75f07bb9f55f73c695a97ac188df3280a5e92f0a4f1c4adaf8f53bbab4682a9dff482e9cfb43db9dcfcda1a466cbfae58cb09a97d8336c88b124bf1cfff8a603a78299b6e6a9ffec57be9c75d73fa3a86049c56f127d5f3a6645bec138e6f9ee98510eef2dfcaba7f894ce575889ed3c89b3c1caaa37f0901d49f7ef9d46c955095899a76feb44cab15d918d6f9e924e77ef594b9af6e7a2bcbd2190758bcdc73a2cb5f7e25e9afd87f893b653e7d81b294fd6e0bfca1f5565a21f725312a2108c950f275a4c0a698ebabc567bc1d0e7b1d74b027f1dd7187cb584fccf0206d997519a61060628e2255ba437bdffb3cba91b64c87899fb19b5790ebbe92b0d55d2b0eeceed76d6e91aa53c6ae2113e33e299d531c4fe70c696050e654c13387f0f5a9006691089779741473c7c7dacc4503fe93cbf7565bbbc4f715dade96b451a21f1e36920bdd10f42f48946f8ac56ab3afafd84800b2a9fb6d643cb17cde43a619d7ceaa915e6f5d209ce489a8b47bab1eeb9a93792c6dc3b7676dbacfbf3e3cf43e2d68c79522b62530e423f3ac341333908eea556442afd4a7035384916fe5ea257e3af6655cd75ed06f3498afbed542b0ad0491373609b66dc14b70fb96868a8962a2d7ee4d16ceebdbf334a8758b9721bc879a8ff8bf9f2fbcc6f63a9718a35d8b5df1d6a38bf1c6123b43566a079d88b94f3870ea1b9ad8d94d2db14bf12db3ba58dee361949713c756937de91dffcef9fabe2f9714589d51e3a72c7c896ce9b1fde893f5ea895975986ed8766eb7c7598bf7371fdab658e7bad069a9b52f9e9761ae014c4c15c25b1f98e3e0dc1d831cbaddb6f4d3a993f2257d61f345b3cec990f79d3edeb2f5ea94016bc4c4448c8f9815e81b7433017a719d074003d7307e3d627653f5cae3753642527b0a49b76bae643e4f0cb4fe00bc7b71202d6b1ed7329f6ec4ae64ae463ba7cae1375d3ae4b36741ed88e3dbfc48efbabebde8c1eedd487fb8a9f42b66808936bb6692353b37642efd113c62f14a711f42aa00a0947ef974dbf1c9455e3c1ef175af9cbd8bb729f5a7069685775d8ba8fc3552e37e8765680a58eed27db682227eb6f9f12e9378bed42d4292a77ca86c2eb79f2d289b557e5be66535a2f7bef852cfa2dea5d97c52fee7124916123d91d6d6911564a5c2be40110b99de71e9d9a6203de69a6f7b57e54fa4af76b82daad4021a3fdf1ed0cb5f2118646dbd38f2ff5c7a107967eff06986db9e2bb8996f3dd20b7905cb8f091bfa1f9ab52307226009181925c4cf729b64c39add884cc606b5cd0ffd92167e5871ca3b85b0eda19eecd1f3876fb98ea4b0ba1df9cb8b5e5a87dc74399170e34ec1a2b29df609aa1f86f24fac697de3bdd5eec694516c5c59c6160a30d90211319e50ed9384a8c8e316331b2a64f65a2f2f72b3793163870b4fbec75e81af7d4353aed284c926575a821938c34a619bc75358126deef5ca9fe7b0a5e69b6a7c19935505c73df8f2c06ceb3c09fabd79df5e67c5f209579df95d20ad0491ca79df3ae257b8ac3e95aa302f84de6fc847c8cb147bbef136f355a240aebf1d19e1db26bab8ad4c6cc6d6e27c92d0cc8420e0f9e9cd2bab9e9ef2196e07f04997abc6c1054e015c72da67366699fc045c21974f9d6433740a3abc30b8fea46456ddc7c3adf8ff00b85cfd8e8b6ea2ead437ba951d6d5c6c73322d29be2a35e63081d752933b7938c212b1289d2775222261d18633dad1e73e5f323ff2e0ecf36784f52179e6bdc31c5c19616886a139ad0c632e47d0d32d1ba2ac6c0807fae7bd766ec53b94fab2d2ff22a93483fbb6445e72d409a398840f476eb72f1a0ae8143b70fd04676db9411782f83dee540fbe6aa82664c779605bf155030785e13d8f0bbf86951c62ecaa7e25881f491ef1ffec48fc67ecfe2b9247df77673fee6cb0f66f64fb982379d6deb13a79a3f893488596938b1bd7369f9b99832c4c3c23b04cd34cec0dc5236c4105ede9dcad1943c5813cd18525daa70fcbacda879ad6675aa6bdd5174f0b9e9b6c53e67f7771408aabf9fefe79e92c5e8a6638ae8f1e38b621647d0d51aad753ad3b5a5dffd869f18bcb9a8f73c76b452f45c2f8ef6bbc39c9a479bd1c66bb74f6e3f555db06f55a1566364ace5a637cabb4b6b5f422305086e8542d0ebfcdfff1d1e7ac9d2deab374165267cd49df53bcfaecc76a6139337e9fd029079ca503816826e13fb54ca2dd757e147bf8cb7d793ab299cb920dfd306ab4654bb7661cd83814994236d8b50cd984ccb5d210aa54dc73415c96b92d6079d19ad0da60496d2b64f3d687b8cb154565602ec004b311f96d330f172d255bc6f0c550afe9acd9927abfc7bf67c37ca527edf3f61625f6dd9d32ffe64cd0b10cc433411bc558b67cf11bc09f8f4d7f44bcdf6395fde7ea9f70c80cd66aed764d8dd0ce88679b5caed8fc9c2ee8e32d2ef5a8ed9efd1e418feb40aacf7f19f16c9a1b35357f8bf8049ea7fb91c7ba47d670ec211f547ddfac75bc552f487263f859af5dea16f91baf2104b6dac8af88eefba672312ee7fb9f96886ca51ead0fda9213f8aafb5bc4a7840f65a01cc004a510ee5ad1dcfb0fb650b747acbfff26a26f568544c0d24186f8ee4b169615fdec32de53b6d3f2813ba5b7076edaff3224797d524bba359d90f417140cb222acc5ea65d83c0e7bab279f4bd8b9f44e0e7c907865bb83d3ededf3f539ee85c3420f10ebfb0725fd91f3cd2f3cb28d9ea9911fe136e6acee0bb05a7f18bcd4b5caa9784b19f63dc0c47623730f54eb3f52b2610e9cac31bf560d29def6b778e3a6512fec915eff7cb1c18981292bc892893d581a311046dd9c132b6eb9fe354075e0caece17f573454c035ec85e973988dedccbb7041ce2801733da9f782c8d85491ddce93a943b1b647b41d02902ccebdc3c82b7901adb91cbad9d18b7915866a1d9098e1c43de52e70477048d02ab565547ad68c33c7138d30fb165f1e5e76a837bd74a4af58fbcf4e34203d0a1b56be539f2ddeb3706d3f25e663ed919a97ff8abe62a76be6bc6fa6e61aaf2c8ec01768c7eadc9bee7ceae30c31dcba975d6b558ea932e22a71a5c728d2dce05067b1d4a27dcfe0438fefcca5cb4a95efe83e63a7dc247570449dbed353e7efbad6ad8c981a2b47de139ff5bab370c969e154b9e4f07f813a9310a9c021f52b22829622dba52fc47814892fca57ded9158663b293356decac92b391c56d7ab26702767e30b9726aa51bb16b79ead28fb4e00b815b66ed75006e443a9e41bb5ead6975bd3f8326cbb4de758e7907ef62dfdbaddcb7b1fd85b3785ab27cc0128d4a8f0306ce3c92cfe0f708ffdb335bf69c55348e88597f711e5d35efb6e05bfb9d266f107bf8497e8ef403b791e1c3f23d6f83f7c7f2c7bdc63776dd4f3ab24178e30daebb616cec37cecfc9756e2809a6d131c648f88c6eaae019a9c3579c6287d7681f8b5a24bedd607ed629eae12f9e2bdf55ca28a01ebfa2b20cf30460621e22b49241d178f5884481f3cb5e062f2b5a1f90e4a66da24bcd9328d9501e5f7369ef94ab5cc9c42494d60edc51fa6d5ff843a8fd5d5ff89743ad44ca92594df4fd090a213696a51aa7c3845fb4d89b7c8ce12a9e57ea61d3651b8868e7d8af070f78ec48dfba75613df791126e81aefbbeed1911f5ee74eca37da5f0c478e8d9d4c6433984cb8ffef678888c982b7fdbd36c736ccbc9c74f65d3b6659d3f23ea63f6614974a4d62507951089c22d885256b29d96a7f196cdde15515ef5b95bed572ef4bd1b712467c7bd67f96b1674378d8f87a07fe35443630157d419d038c7fbb0486d5ff6dc908db1319271d24b7d8ec8b0cd7fa16d812828368871866b96fbd5fbc63f5db2e85991c937e1e7fe1dd93972d9013b5e56e69661f40026461bc9fde8a9a46f19da2be783f9f07695579e22609fe4b6252ef1ddbc0bbbbf687d9e316570db32c1563487f09b5e0ef117862d5301762222e99860629271f05b8d38d06658ead0e686113b9aa67ba89cb26bdd3e8fa4d64244cb955fef548f69f9c5059c0de748799e245be3b9cac822e2927319db667124ee46639bc3b462dbd6ba6f375e94842e4e5dfde5d409975afdb02d03b52c27f33f98f745c0d9ca2d2d3405f2babb8231fb446e87f1f97b776e3e7a862db3fc7a05512b633f75ab70bd7244aefa306fe9c5975202ef0d360dc8b725b06b961c6257d02b4d1c8867d3a1817257a7c80adf3e15ac7108cfcca555bde972db3b1bcf38bb19b35839f0fad1166f936c23877501f220ff81b93c06ad91f798214b63bbfc9e9cb6af0f41548c3772da35590ca55d22b6decc5d1d7b3149fb5e71e09a40fcd997da77eed62a8d84d9aee853c68fcbdd79b210ce34a9ac25093a57572d557d47cfeeac5beaf9eaa9e0bc29c3065f59c6190a303903918dd88b9b4c7624db2ee1b48de9cd4d0ca875095650d5c8b5d903717d33bc5b1635e52a1d989c72e3d397e29367db456ffe6afa124496a6f331d5243f40dd192b1a2e230badcf97acb3130f5e2af588fda4bac803875788d425867687a67dfbbb7da5fefd9443c7b565b79d3dd9e669e76d59a797b3ed7a1e3a580b98da60adba5c7c71d0acfd5bde9ab5ccb69fefbf6915976653797ef913ed65260a5c6286eb11e962d9358e3bfa3c8fef1526293c72e4bbba4522a7e07a5f6da6012775d5b1d487283eb5ff89e5b024e4b918e98ca203a0eac6bb26a5be64bb478ba936f1b410c298db9260f6969ef4023125bdbc7db8b725cf7e4b69e0c0bb1733f3a4ce5f6b2eb374713fbfd4f488c5d1be324c038689a943154e1568a3dca5823234ce6c5c26ed2da769d0b1a78bdb4fa9a71d59a2af1241315f462ec378dd24472efc8d17937fe3e4bf89a2987f3201db5ebf41726d27cf6c26b167556dfbbd0c00589c8fc1827fab8ddf45f95f76efec6f8d3ffcb2bc9754f9ebf26c935f967f74e5fe0d7f18c35eb6fe9b112b9767b418c56d9ef750f7725ad45de079a5d42b2569d5857cbdba2f426619e57273da74b5cf5af951e76b3dfc6843519c8e6ed6dc7b8290fdb0b1f7efeae73a579a7cb26abf03c7e7e8bdce598e578a5a6f1dd57f77ec99edba37793aef1fee973cb8ae75cee284055e15d62e19178d3707522ae7e3ee9ae5d00e9d4d82d21e79578288e3068737f317a7c865c4ce6f38eedfa4502deb116b7735b897b77f8d41b7cdb7fd07973e715eb9995a40986da462fa51b9e682506f2559526a6bffbe8b6f6ebcbe97568679806162eeb1602d386302d65aadbb374419f9dd1e08dcad0467c5f3e96934cdf94fc11a04ff3158473a8a7e3db77f79c292f017ed42a28ab2ff7d58f7ae65fcba3cb1ee97e5ef3feafe1ad6a4dfcd1061fa5d171d2f21debb4a99b5ec48d57adee17b492faac44efb1bed06b538a30302078e9e17bbb15b25d3ba8a4e9255b1ebb3905ab17ccebefd6591d9feea87e3660fe17e57bf9f60cf0992dab3aacb619b0902162a967eaa4709aa8b0c65aef4bbb2a56fe2695b51f950ea8b5544e6fc4d5d81b96fdccbd55df29cbae1ac667efbf62b51c39c6b2ac9c839cf8f85c7869fe8162a5f6a3925e16cea1e6cba00bffb4863d8c73c355ead66692428b3a88f939c136818237f256159881265b37aadff156ec96f73aaa3b7f8783f2bed00065a914715bb57d12b5f65a5ddda5ea31c67d9b9e6d2aab2c0a425ba857c471fd552097a343a660972b6d4cefe7e3671d5d34d5da54312451d414f00d3944635dad335e7f56b00b30ab4c3751ac81adfd8c33e950db63ff44c85b901983717a35575561570ef166c747d3abfb8a112440aeed6cc8f575a3d285f3a6c1c163bf745b4d79172d13da49263bb2415b00f520d118b3767240e1dd82f7666b352989c7a6fc8e7dde6c5ee6bcfd79e9ea9bf4ba342865886f90c30317d88903d4fc501a706f9b7070c15ef543ed850963cab079ef72e75090761717efdca575316d58589c9fdf9424ac0cf070ef2cc885b83e49f0c1c82e91a1a00b3ac246599bcc4db1ebdbbd70d956efd071652cc5e2d14f79a0f78614f7fb472185af9cabfd138b7705b9f9bf6725e29faa5804f8838a6e5f5ca00385808eb2ab34363ab50b2f2f9f39233eddd4e463d18d6352ada86a61dfeffc4424a22b2986f9791436fd96cc3ed2bdaa399b32dfad71bdd1e36cedf2f6996f6c2b6ebab2bb2ea4bf11b2295f77d0bdd9e91295cdd23ea548e8b8839e7dfec6bb74976a68232ca8be3b478f1bf6ce7868db922b5bad6f87ab1e162b27256ed71560a54aa622cdc91785046ee2dbbb4c8f220a9334b8aa9d6bbf73fe724f69fc8a0bec2236e0d39769befbf3128e88811c39d55dfccdefed9a8fdcdaac78c8df18882b467cff80e2ce569edc0fad9247625883cf6577f16f08d9efc2ce1f8c3976b73e789773f6c32b6d1baeded08ee286e68f046148b66e61ea93da5735c56a5c956b076d067db079b76bce5add735a078b5db7ce3328c04c0c488205ee15f6f3b81b559f9bc83df308fb6b974bce453e894adb0df2061d8b3c3cf62ef9491bf8a095e1fcfaab174aede7b64f4e32c0d84737f9d559b16bb8b3acccf662b81b5a01d5f8da95ea91483152a4c93feb61db3f5d2aa8791009f43820bce2c1076edf0d56a31311c6c40b4bd9bd65764de5cf8e886805e3c6d64d22ef09f9d03fd5df9ffeca41dc983f7d403e190d873607781e2d756177c31b750dea08658fba0dd215e28a501096dfbe83e5b51e068a650ebbca797ea4508fd1a570e3cc5bfa6d46fce6e35580e9581150013bc8004a93d12b222cd5dfffaa8ecc66fa9694daf5e333b4ceb24d584bd67573d34f50c9e3234dc9860d0785084ff75b32920b2539af3f26d5363e70b94bbc71615c564d61d5df3527885b8dae59373333db7ecad439655a79c12b0c39c0f552cbafd6ef742e2e682ea274bcd9a5a7a7de6de1f7a1ec5561a341040e5e75ec0da406ab741f458c3a11bf714f23f730c19ca32d78af3c52b6d79a2600b698e2c0ac8dc7548b658bc4bc3f975bf2ebfdb916e214be74fcdd8c60737bbd2e5bf68de1e444c28562b70515cc9bbce2cbf911b7ac2aa18a20b1dbbe556bb8e6788921c34285766b410601ae9221fe28ffb48169cac5e277cef909925dbec8f8e3b6fa884553a865f085fd7f9992b75ca1674672eea28d37f8f61ea77b3a6f29e4f9aca9bfde138995ca6cf80c89089830e59940400420408207f23e221137b32640242260e64084b718070600caca5ff4b6d531cfee25b1408cba09000202d9d4102b86a5c887832c4c67a923dfe048f2701c05512009492009007c2494338191722090085277d675b400280c724006c1c7b08f19000a003ad85d7cc85e8c9fee92540028001d6834cd63b2f27dee7d7752142c002069e81fe1fe2860086130306011e065bc4f04ffe8931f014940a25a138517e4a83911463d07efe36469ce18cfff95b627ff23866db0bce7d8e62ae2233cdefc8d7e57ca04b5ac564291e7e72f2d5198990002fc20bc8c41eb5413a9671188f6749213c2acecf2ba4fefc319604601c0990897d0cd7954dc8afcd07b1812400b3824102f84c5c88a3ad7f2392008c2f04d06824006b3ba662328481002ad589046036a326e023b91033f0780ac3194f860032fde7ccfc8986507431589f108063550b8ed6f527cafb331dc4347f703821dd7263afffe522bfaffa29477768e4bdf7bc9a2da6fac9cde693d2e97734c8c49e0460e7b1582e1c97f13009c0ae181531604c4454eb2400eb43633d0e8570d224802f4a7cb40c3ffa4102b0092c0a367f1605bff608c59fb148fb5333615b0924007b974a02d88227908c7d4602d8ee4dfc66f3fa2b1060332190003675daf775b319fea16e4fd6a7fd1fc948dff144fc4e7ab6bb103b04d0febabd4900db65b4c14f130db22f1eb701ab893e888304b0759000f69b3f23421542fe5b3c3831f0e90c96939100763b12c05e3f5637034f2601ec3e7408004900fbfbb1c782a22480fd2a810a0120854186408a1348a63a93d3f1780864601910e000e12000ad9b918efe8777a64220489d1ae9886a2100c2388d7a3c0960ef82b8480087f908c6f4c54799639592a96427061e4b0238b80910c0c093008e252e440a04d2d0e72480439605f7db2e448a134590047068114800872609e0e770211227387062e089a36aa0400038a1148afde8d7185bcbcd61bfeec71d205388cd015286806f5323571c274725a6b231f01048152393008e06021443154bc713211c559082caf70665bc93047024bb1089e3dca1b17b54867196211c244f03d9c67f53a9d20c7c46faa862b9681812c0e91433fc9b7f5412c0298a828d138aa38d7cdf81274bd2c5b6e3c9716274f10c3c1ebf3d63d45c14c6248ec6e1c479820470e69100ce6c3a09e0dcc8aa8ccafadc881af00f6f9000ce9b6843c9acaf2f49006723cac31917229dee440238155d885467fc68830c16d10009e0ec44bf71b153e8681be5a3be49a450509872cd2590002e0508402bea71214220054451c1c53b12e22079aa104a168d922da790008e5e566df6685dec2e440a08e1625915c1040a038f166d22015ca1b123c534904a02b878d0bac6704ba5ca4ce89a0470654380241de2c290002e8a0b51924c134bc74f2ebf88864fae5417623a9e0a613054f1b1b74900d7232a09e0707021fa8e9984c262b60f65f60309e058ed4244c986d19e88e302fa0a371f951a4b02b8b44660c0c043f2342108a48890006e730204d0454900f77c02351eb46749c3bd281695a0d08518e78c2701dcc7509548d2c54800b753dc883620804865e9927b2b819e08da539d21900aa6e3215c2c98898770230ae526b810e3682cb2032c3212c0bd07924f14a38e484773c6132110c22460c004d486a8ba581a9b929b084d72130a04ca8c43874c4dc7d31868d5b1a86a784c09e4383696967824092480478204709f7621a2e562e8433502998a49c713c9140cca35cfc25812c0dde242cc444560a2ffcf1c43349504f0b813209674bcf35d881412c013381a6258bf47d4ca134b8030ac2f0cb4c1eb28c6d2f1a334d0309dc54b2e5a9433ca0b0dc2f0a4e3e92ce0f154a025e5a325a36fe1211c4d100617d004c5205bba20c44b171413172501bc00814ae561e06923020ea2af32475f1d799304f00ad0e974082401dcefd09c8481a7d047f4c1ab462001bcaaa3e414547ee2b8f742c354b1496ecb8ba78eb8683acad16a1a09e0d5436b2301bcc9bf0d1ba81bf2ac40dd7b02e5bcd9932b2ca48dfcc8c053a91812c05b4e192ba452d9e82234517112c0db88b2fb684c31635551a90e108e0a8ed51db3ccc14c5bd31017e41fbc0eb72e04b7cecf1b17e51d1e8283bdbcc2bd23220008a0820ea34cf0a942f2a828cf47d8e0d3a592005e14e0ac0ac74327fa8342c142000d7420017ca8ddf92427452b12c01732491abee849d2800c3c996557be2c0209e0db39cafe9843f3e58f4a4a75c04f6a8d04f05d439ba39300befd2ec409b5f1354e6ea86d5243589447b4217e006d68f8bb86a6e452dae32e05ab5b934900ff32085808017d4363832818101c1b43b1e909c2a00d010274a1173264cf5084aa250403570864cf5dd2ca754230103dfa5504c62204b2670ee1f22311185b47207b16b0efbb2002b30104b2e7e3c7c9ad22309b2681ecd94cea361681d92002d9f3c3b757db4460360601066d5c8823958bc0583602d9330c2f714404c6ea10c89e9b6a7c192230d69840f64cc9bd4d1481b16e04b2e78ec6bda62230762381ec992514e6260263778e55b310bfdd5e08064509235f45600c1f81ec695225202902638c0864cfa53b03fd4460cc2a02d9d3b6e5ce561118b38e40f6741fee7c2602637208644f58dbf998088c6918ab91e3db33ac080c3a10c89edc1e79a74560309440f69410e36f168141546aa5d270f46b3981eca965d4e62b02833d04224b8330e806b31d6725dc30e89bce80a59ac6b3ef3e220c26416c643d2c0564c0606c3a0396dee74284d98d47e9b3d0279fbfa3cf87d9e1d1d2b3e90c5846e1bbd2c689daead15223b4b68051fab61f6beb87d9f78c9462b028fdb1c9a598d9e3b56114c6793b3c4abfe087da302e13f4f6e3f44f5c880011c6844f9405a12d5d47cb7a47ca5227ca12c7dee3601b6d67ef0f5262ca27e8cbd219b0ec4e947edd28fded1ff9ea99a0ef4c67c072722e44986b548b982f3fd48f951ba7c74a8ed3378ed063357ea43782b9712c49b0ab26de741c93845b67a48c04733b8dd61182d6eaf65d1d64987beb6869ca0f28c11e807904476a393fd1c2d9313df2288dbe59fd236f6f26e8dbc638e219e3e3f30fba62931aa767131da7bf3d42cfa6f223fd8a09fa65e3f43da3f4841ff8618b9aa08f44b510e94284794347e9e37fa43f3a419f3b660bdecfa82e2008c2929d60b60b0c58ae151d98cb83108e9cce8641873626f60c0a6b0e27239d41618d76a8286dc728ad28ccae432043f282303b3701060132cd890d4373488770603accaee342a482e9e3e303063a7c70604020c8807020992604b38b13a80c2c242f4605d347b299b11109cc6e05f32f43bb0c98dd85121b0bf3db8c6605e339f8f8e0860cb3af1f27a6c55263610131d42b52636363618143a3ef4d74d4c213ef158ebf578b36c25e199bc8d222cc7e2b9d01cb9bbb10ffd830ccde020b4ba0ffefa25261e19d233930cc01c2ec5f589551e1995dac71276b4c0973d8d3d1f16dc25f1f5bc2a26568ef958ea7c01c7e0498c33396e54430c75a172299884a35a61298232696e59074215198a36aea933630472903967f3369ca06adec4e5c1c0b820c3cccf1383e8e256c8c59ba65ef85ebd45b9c07963f6cb9dc5bf5aa14f7fe507a917f63827a45f2fb94c7f13f17c953e915dfb605898971494990897dbce7c82ccc0be991e63917efdc91b93d239d01e308683281b241c3522020deedbd285914e674272c8600b2f162b4af45610299d82f86e42521792a284605d1de168f429b938c56d1e9421481392ba7213e6709035648f85e7cce5bb058214b78ce96044d7a22ccd93c0609145e10401521c35cb204fc9f4da6fcc9d493085114e63222c05cfa09b404984b7bac521435309703fab13c217ef4a77d0295ce82301102514befc8c48f0dde34a73585230273ed274000cc750fad3697d5f9fd360d85b9ead219b0423e3ac81f1f2dfc23f32430b7ea8817716b43002c76da85887e5f4e85b94d584e441b71616e3c75d49df0539e86455d1b82d8c84e3077cad4231a77d97844e3e1188968dc4f7f88683c1cbf8b68dc9d3f8d68308fc488bc3c38587cd3a4f0c0b3800e714cf2701e2b02cc63ce320fcc633de6e063ba8779d68c062cf4d5206a1c2b58a1a319415198a7781a88e72960c08ab693100ff35450e3e2e8d8d1783739ac90619e87637192e7156572501d23d19cd65ca508cceb310d5e799d19b0e2f9c9bcf2fad168b078ede401120442c0df9a34fe7ba81eed1c788759669e6648c0c27cc1d3d0079f3703565a39591f7c1b282c274259e08ba5d16830bff6f4679061be5a02cc77990a8b3f42ebb9054ba8a3fddfdce9cf17c3fc9204989f8f365213bfc8684d73d00fc5b1a71a230d4d9e0dfee3bce1825f2e58fca91cfc17a7a14dfed30c58e9d977b17f9ac2ced0984673331419b072e8a4e6c8287263ff0e72ff06ec7fb144f227da8d4926be6c7bdbb58578cf2e6ce916397a5f3356a4f273b19a1c11c773a3fa4ad92c1a9a810a707f9f811e1e352f2ca048a78f06addf763f141158601f8182c63681d469a8582096012b374df60f81bd743a7d34b611c73ad069824a50681a2c087231e059c17f075482e4e934b78101cf06264b2cb80d8d0212c6a3fd4cecdf0a6e2c13084d477e212e063c3b631243acd92072dcdf442a049063ffa185c13f513cfd2fae0bd251d40b0dff01f5b0b0309d4e87256c5d4651070be3583de9cf5b81858d5963db3feb358533a76102e16d0c78f6d02413fc85303e937d3a0d7e65c02a6b278370a610048ca2706cb9179ea9349af0fe4b167be1990d7f34eaccd72362d98ee5a5d3d4aa08711a5a157160c02a5f276b55c4970a01937c9bfef77d5ba47b3a1cb53260d5d41f7c3bf6effaf60840b0a3b69c667c9e9a838a227fb4a5e8191a048c7be898468560d1e1696844b49f01ab0e4eb69118272ce138320e17b39a464d62260c58cde7fb81a8181c1b0b01202ce1c548678c0c9c59393f048064d48058586c2b0102c819f80c3c1e16cb4353733a0482548a13451016db4980c576c06a71dfafd4b2888919f80cc6d84ae0ff2fbb5c60f158880b96941df99ec6b203031f43d67cbd88ad71f33b47cb19b3676bfb3cbce51367988f5f7b2b6496ebbda4ecdbbe14141fe295dfe3239b9c8e1fc94047f37b0995bfb959019650a48d4cdf482e18c9d7258c200e58427f64c8873e449f59a1bd375f94cb77b9312cb106e282f9f527d6ed59ebf35858228ab5a6064b8ab39ed2d1a70c3c914c15148525eea2c37e89dd341a2cc99acea0c31247e269b064034a0b3a0989c212a504723a1e96b8c15adb8525ae8d4768221e968865cd7508914561897e029e064bf4c641602c2cf176746a60bc2611a2282c294480402a2cc9355a880e23596c51d06f63cb32209ae57f17b947e4935c3c6a2d322cb9928e625eb2df8528280a4b16fc9fef94a0d22560c98a7406acd6ea42a4d2c560c99a51354c8c31c9340870a08ed481aabb9b024b2d4547ee1314233b296029be118b482d9ed847014bc98d6a85e59852f309b0d4bc1f1c73d2168a1fb74ffcb078070144d6d85f2a8e40a682f6143ae830b29a0c4b05a0a5743ae83096efb2e6cb68e0c422252c554885a556ba1061a9524a2c2c4570216ec7c3523728b1102e0e84a5fcd0927b14582ac38548ff6eeaf5bb053e58aa9f4287a50e7fa7a96f631f3f758a492ba5b0f4022a2ccd35be38084b9b516069551722450496b61d5d3d632941978187a5210a2c6d38b1be47197f6b130596f619798bfec35b3b29b074e8c45b64c884168b151685a54f1360e962586ac885c862a52a961a07c2d2f62ce0423858fafec883f811238f454b8aa8e878bbef29b074d31f572361193ed662242cfd7aac5558467a84c33f52ea8d50ca084fe60f80207a1ccaa18c330196711ae750c6338e1a3fc2e176168732ebc61fa02c9bc032b1230fc659c667fc61751a96c9a5c032693f725239cac9be094e201c95ce62a38900cb3c9d60e30d9d1a3bd1c8d8f4b3cc109565bab18664675060993e96516425ff6814590d0a2ccb3e49e86fdf7fd020793a280ccbba106059675856cb8548a4ea32f093f771c0b2110458361c96d543d9c2d1c0743c0d02a9181a8896a51160d9545876910b71a29f238f28971c97804a255b4c80654f8d4b255b99404d0461591917e20e967265efb11ea0cacd642957b665e441fc88faa13850f73b7ee4b004580e034b635d8844584e60a43a13d43419787cc60e7cc60ec6f6eff42aa74380e5168c7320b77444aff693f40acb398d38c41fcc251732622e39eb9f005b2e9900cb6d9ba877cf1f802d776cfcc104b0ffce6e2b58eeebf79bad607901022c3f03963b3bbed36adadb5460793b2acb67d2f1b0bc1b8df575d21601583e9c00cb87c1f2a213cbf6accd0ccb03e1083f1bffe075863838282432781dce7ba3a7b7b757042e88b5992106dec82259190207ff9c11dcd8960758be01d2a0b16223cac4732a2cbf114d0ffe74bb038cc35260f9ea499b1dfe10b2a9149a3e3a7e6005665613383d5a2c8ce361455f9c192d960ee3a45d88306e256d34f432262d5e212ce3e302d1c61259c687719b50ec278cfe88834c68603c2b9ec0b8ed104403e3583f5006c92c068f50e871304e1d65316b271e3fbea2301e4c71d72930ee34cb6f71f726fbad3ddaf42b0a8cbbf46388c00d1360dcd038e414f85950c6354c82f20fd6f10f5e0f07fa7be1c2bdd7458607e3d68f5a2730f2977f363ac93a0ae190f2b87514b6506105b15f5b47219b022b784fb20eac707a1c630ae513181bdd1d022b3c24c00a0f7ec49821cecbdb33dc1b8ef0f6c2c18181211be0604f6f1cc93b3064c38814ac4d34539342d1009a352e85a219155668fab5148abe145851635c8a1ff4ba213c24d817b72e24c03b78d4b126daca81a427da3a498515837fb97d0756aca7c08a59136dd96d08864981de86b860ef0db8900dc1dee138ff8849bb8646a41fdd3b3415e995f4a0d9e31c29995261c527bf965ec99b022ba9fd417a431c1c1a1a1eb2de1be7131e12f4dd2ea6118e7ecdcff71cdd98842aa57a2aac14f81b8e3e5360a50b7fcad10fbbaa4638fa353fdf71a4ec06298e73a4ec4d8595867ecd9172220556b6f98123ffe088481f1f7f4f7fefe07513b0fd1e21cad721d989b6ee516165c6af11a2fc89022b97fdd0d6ba703838c2c73bfc07838c22e437069924fdac5593fc6396271556fefa6be967c553e059d67fced11f0d32c2d16f00f21d476f20a5098e3e51e159a9bfe668b624059ed5fce71cfda19f228d45c251f3fc9ea3d9d193bc68763c159e8dfb0d47c728f0ec909ff8b5271c1838e2d4c121eb587a6279f92484cc7e0de126daeaa3c2b38b7f8d1015710a3cfbe90fd24f61cb21ace204c98fb7a5b2860aabc8fda62d1a0556b1f8a12d12dac1fc101ac2bd23467d1198b22faab4430a131cbda7c22a49bfd6b4aa28055679fc738efe6877d4e2231c797a4f9923d58d93a2832a8d0aabcafc86a33c0aac1af0078e1c83e1d008bf10b45bf642adaf3939319b68ab15129b68eb1d15562dfcb53dd4665260d5477fda567048b0f746ff88756840f2f7fabe2d35fca448a446a4c26a52bf692b8602ab994db435bd4d9c5322179e9c9faabd1bcf1dd406c77307589d8700ab73c36a68ea4b45536456e23074c8cb3fd4276295a2300e42f2d627d33db73d2e215cb5582376872c7f78913f55a7ecc1de0bdb63dae58dbc2242023dcd002e6160412588987173ae8e5b27cf4f7aff45cd789beb623d3257a7d987e01bc744a564495bf45e22b622f60c4299f92c7e0176a0831accecffa49c527fab463d9dbd2e79fd368b79a54903090ba6f507d4f92ffd8e10198bcd14acf8bb6b396a37973eeab665fd31772387554c5dc6d1a3cd9ab752acde3d37601a2d8f84c0a57bf5380469a7af9f7b89c86fc9b58b0c192ccd59a7286c622ab7e6a09ebfcfc0f21b9b3e5992c29f71debfffdd611b7a13876d0ce800cb5f8a85c3ecda17e7473a29cbf408a595fcc70edbf8e7fe1e58eac4ce7beca97babdd2d73308addc04600589c8f0531d8ffd2611ba00cb2cbfe17f73d61b4b51de4257e51ae175e5774fc57e509aa949cdf1d8651a12f5e5f107db9d63d717763b87540f7056e97eaaaa13967a8d8769d756bdf3d9a79c6edee968c37a0cb9d3da27b9f6f5d5935bb5c2e7287cef5eaab83fb08363586bfab3f7cf0525012670ea652ccac4c26c6e5f055bb3b4c25ef973b1c3f53da9e2b0e58b27d7c224917afbe5690beb725cbefe09b6371a79c5e2846dcd8c6df41db79ffb169258898da3baa42ebdf0db917bb9a2cd5d077a0dfbba64e0cc3c844b7d8749d9fbf401859b196193df322d703cd96c48f85ae9d4b86b6bd791a95b369e9c0fb28a28b69ef9cf18301664deb608016bf37d71e0c959c557940e6cbb1a57cec4ade78b41244f25579b61edf6a6a6d76d63ca67d97294dbb708de30701fed8f564eb87678ad6442378d2936376699f3a9c382fec4c63ef70680783b006da4dd7f56e78e75ccc9c1758869d0f30b11ac871f35bd1999e87be191938dfd876f0b0ddd015419fd398c7b6a53efa56f77a4ee54ef96f873d9898e632cc130c13f370e4fca7ebe38703dcfdaf9f96f30ffe41ffcf4ecbc162c1bfd5c8df3b2da7c7eacbaf4fcbd1bff1ebd3706c9ffdb2fcd37a95df3958aae660c1e0aefb222e9d22e1bc5ca5ef177a540cd51faeec332c5ed1a85ea4f676ddba35fa37d9573ad7dc32ed345ac00ff770d739c8e4ea7fb4b8bdcf791934f0bb536731361eaffb234b29abd5df955fac2ab7b19c2556cfec5bbde106ffb621e058506ca45b489b4468bbef57be4367ed45d7dc3e15f56691f5a5f26d5767ae38793c31d3c2b4928c34dfe792edf7bf8bdd30e0ec5c34681054a83127ce17283930c7d007ab0e3db6463c664458e262a5afc7a45775d83bab757a2bef29e5fe68a69751abd84d0aff5c58862d0198d8d3c8e6dc35a56a2e72e27d43ecef9bb21796f6e2b4df735679c5ec55727cf075c0559d46c7982043f47bdb0566a489bd0aeb28a433fcae75303addac5c5f5fa06e5ede8cf3800ea11e0331b1ded33a8d1fa3504c6afed92132afd72203576cf6166c8adb6e9555bc252167be5bee7fe0f449a4f7d529f2d5f52fc436ef375ab75144e4e31ed1f6595107d3a2f2b744b57aec588688cdea71e0b0376ad0d0400849cb63edcaeba859e40b8f3e712be8b31f5f593d84e61d6ba79577545569633092dafa1b485b07773c3b9375b1b6559d9577845ea687b5c52a8add5ffef9eaf28550650455dd97f3a2a293b9ddd6d32f228ea722162dad9f940645b784ec5b70b92aa6bee240f74a64a1dda2f925bc1ffbb615fae4a2bc38fd3307da2cdc838481d78d8fcfbcbe92a9738570d113b83958cdd79122eab161d7994b455d089758583c367ad68b8e60da9b3de96e4a292b6bed77776e5ab0203aea2e9735b56de4a493a07ff6a4939f9d76ffaf38e9e4f5420d2d4d0d3fe7757250c93262c9cc5ebb0e19cf83afcf6a9c2fb6555bc15b82cc8a765d1cc57d4c0c4aea945dcea66c3953f5aa6258fd76a7ba0f518dc9ca6fa44bdb8181570865c52b2b719a4707e7cc674dd6d0d04be81c59dbfd5ecff1add6dafe8d36f724a7ecb7a4819de3b70d89fe95db86847a8af42ec6eddcd8eba9a2fffec54cd307a4b3d44a32d27da963f95a5b5dbfd21d5bd45e7da9d9472d7e5ec2bdc6cf4eb5b7bf490d799b84444bf2ae6e911e6a6a150a65cb977bef5505e1d2e6ca5f176e1754d1bcfbaa5db20c0c0298a03f32074e19ea482ef7d66953ace9d20a95d54830da146fabd5b3b6e1907069c9bc5d5396d48b094aa37ea1332dbf98c7b620a0b741aa7afdfd0a7f7cbbfb7d0fcc8037cb907b4e5e153a6a6cccd979e919d648759e5d9ba79a68c3870637e9baab6edcf96b3d9195cbe1abc78fe6c404d1d6cd33ad2c49a6ea362ff1c25dde7cb630fa9c5ec5ae67e339941cc6671a3994a7b4e422f752874c152e1fb354dd7a4422ffa34b2588cc30d4de56539ab1ccd43f4c90a344a9caa65fb238cfef4a71824c5d453bcf85b588f7cb8556a722dc9a3738489ceff802710eac0fb9be769ffe605a20efcaf5378343c7cedf7fa6e45780177eb2e3b367e58ea36def7431f9e7f6de9f41b821db53798693ff55f994f5ed3372fe7ef0f4cecefd0b47184ded50e8778a09af45ab62be7eb469616fdd71fe1b368590cad96452edfce66c5d9155d02b448291cd6598947f50b2e8f40bd2dba3f2dec75f0ead259e6aef693b659bc85e2d5986f10398182fa4467df656d292f543b948c846ae27ecadbd315629214e86e6af2d16087d583b77c99415e4c7c4888d7799a47fe181cd5e87cb35f15bd6ee7549da2c58a7d3fd7a79a397ff12eca73cb677973fec7a3b7f0db24cc3a2648656a80e589692641f722c090857e9ae52b5caacc5462eeb4dfa701375c78069b96368efe226e1c30098574ec2ee513bdbeb3cb72e9065def5073fa4be316e13c3c9ab0b7743cf5b6eecdc2d6c17b0d7f0915982baf909291bc4daeccab7f3f7522d021ecbb7765db43856a27b8fa47162a3e1a0c2a607e75a375d437971fe278e7d4f42b6fb9a78bec6da1b13b92e1eca6a2b709dcbe3a12f351454b72ed0d96c438af23564eb7d8900dd3df5ab0b6fb53d176e219c5eea6061aebcd0202e99c3cb4af1a4b16b19580d30c12bc88288e604bdeb98ddbe0c53c34b47d722c7ceaeb76d5eddb31c6f9cfea1dfb0e9f094a1b69609468e1f74a638f5dbcf4044e75afdfc17caedf39d06dbefcc34715ff1e933fd5c5535ad375641e3c23db1b52b9079e5865c8992c72ed5e50ce95ec67646a5ddae7d548995bcf45c0eebadfc98c4f393a4d0e84f118e3be9faf6ddcf102e52ced3f5764df2fa067eb5a75ea70d050ec4b477fd070ed12ae7a9bfbc5baa90c3345a79cb97e75a6c0fb27dd964aa579df6d8bb82e2f1a6e332a2a0f526a93455c131c93e40f644fe0937578ef50f4c254b1845a09ce02645ede2324c1dc0c4d4200ae6f194bd6da4ab7b376e5978a2f9ce85c08e6df8a84fabbdf44ccf2f9bcd85659fb225039998ad932e5ec44ce568ca1fd3ab85fb7456e70b06cf5a73f2746a90bfc99502d703772797fb24f069e57f4e00927b56fa155c9e9b207d6ca7fcff7a7a554946ba3ccf168928dce79fed5473a262d623e387af7dc959331e241d7fa57241d4d12d1309ad192c22c9ac320895f556313b223fac82975948d4bb676c6da3aa39cbe64b77e94eccc076d6881f8c9d04d729274306af0ac3bbaf34d6b45bfbbf56583f2f7b11ee8d6b258854b4be6e93c2a8a5ad585825b7babe46a46e5f6a99ca7d99e836c32f9a335e7a1d46562721da1b2e447f34dbd8e5989ccc56646af1f90ec5a64cbc546aa5c7eb3e9d323438e9fe33f9fc7611e2666ffd4b5bd602f319cb3b0f54b938575f1d006f495eeef572b0c699462292eeda2dce6baf9223d66df4b1d551106bc052eb5fea751dbeec7974b6a8d4375c19c80d304176c4eee8c74b995eaf8cd87949d9333d9e35f2eb29343d152268390d2f7971cb392568ca900e1e282d3d871938cd3aa5edc5c4296dd41281ccaa334ea52503fd77025cad78760824efcb55996f4d2e35e7f6c83bfdf7ee5b901faa04912b56add25970f83771c7900a3e678dad2762ec782282535b12cf5ca075de6ddb8f2c7c69fa7c26b8cbcd8862eb47ad3db78729b142988bb24266c7ed93359a9a3be78c5c8dc5f886e4add54c8f28ba5fde7c83cc10ebf03a1b156b5a74fc134fb631b7ed9a8d53d644e8c8d5582153396d3d09a940c0b0dcab5c3565267616774379fc12be84bbc794a40fc52ff4632e75333744a264670708cef5dc1b710d7ce32e8898a87eda8a0935ae6f280998c9c7b3cf6e43198727c0e45883449f6a0ba3056cdbc5bdec80b5ca5efdc282aa24fbfd166b0e3ce8ed64323992be4c99ff702687d0c8d5584ad3bf1a4bbd63bd5de5e75abb1ec9b977973614fb952fb6f4ff5de2fb5f8e4953b91a2b09094e91cc2e7838ff3c69d12b45be450bef6725c5455fdff1a5e2ababa8515f4e6323027a3f2c189c3b3baea14b48dafa74bb732678413c94db499023e2d3303975b7c3a4782ff1d72edafddd70f9d509bb66effe0e1b6d46da716ebdec6d94fb73fbffe7e33d88dc5493dc4f69e278efee965e5ab85b7ed329bbaf72314733535f6dfd6492fb4d6a0962dfa4372be41ac7c90277c255c53d350d408ac05320a7a37cf9ed5514c69e24e7c9eb3302d594bb5450eebfbe3e03fcdfaecfb003580cf8df99dec5e8453ff53cffabf27e05c6c35f94ebcbd4a925fcaa7ce3f69d06bf9b7e6513b85560bdd93a49353fb7494a6b1746e831c702c6a1d876e5b79ebcf147b419d7ec367bdc3e367859be6fb82af7f88e142eb9ec7589273adf9e2899afc53b58dcf1bbfa030d1c33d7c6f5a53b1fef3b3d3f4a78759d74dd9138de77b7cbf69bd9b8ef8879be38f49b6ce2f2b673164a12fc396a9f5235e44b186f6f37a8d56749e429bffb86af242309183933cb8a8b579d95e7151f78d86efe5e9ae78d85c8c5855497bbe5f03ead14c45cafa7e3a094a3fac1baccd5c7fa25edec1b3514cfcd5deee4c8b1fac2d20bcc54345f709956bef0b3cb9858f9c2be8470bb752598cb745a97ca9bed6fc181f4e5fbeeb93fbdd61c124d5d3927a41b5987e195589496714d78bd2397dda645ba552be9a488c88d38f5e379490afead1bcb30960013638ed4a79a75dc8aaa5829b541b9981ebf6c16ce3de4f66ccd859a42ca6e09a6ab3a64a6dccbac6382fde3a30acf298c2afed7c6cdc203d073e52fc9c5d1856d2ee485c7300a96aaafcb94d9b59243ea3b691e852b10310db7974d7bb34befaddd3fd79c229e6b2caccf99da7a2685bd2d64cecc1689443449089c5a9270a66ecfb7c5f854bad8fe1747973ed7fe665ceff9f298a3fab0ed5200c833492222726aaf13173ce1cee60c3e7275c9f6e72909bb0a4ef03759f4dc4c9ef3e6957786260a25bd694169454f0bffaefd5b949ff1efdb9c9d78b007a4b8e6b278c9feb0dd25e735247a63f91ea5f543c6516f37bff5bba5e4aa77f6cbeed715aa05414884220e5ed34bd3166b65cf6b1c50bfba982bb167dfeb3aa3eb360749f74e0af18edcd3736cf62646c62ee5d4cf2b7d9f9d3dd69037df85bfe2f53d05db7a24660dfcd09e7bca405a5f598639013031054834cd27d840ed65fbdce1ed29efe35d1d0d56b7a99b15dcb50c5d56e4561b95866640a688dc96eb7d31a6550a671cbf3dded3e16f5d737ffd16d17bfb9f25ee2bb2ebecd61d42abdcc8c41047ee54cc9db8539154b7fa1c3692ca79d0dba495d3337d0e8d0cdbfde14ec5e06a7e0f4697d190b05ca3f991ba47ad75067dbc2bb3de9e2bee7a2cde607d4216d9087f783317df7621578087cbcaf7a3586cf2d5c44f43c71d92e62a3b50931edd1cbfac80f2723c83f6a21e2afd79069db37467a0df6f80ca5f494616dfdede5c6953f16260752e9c45dfb55d2f89246bafba738ea543f91d2b73ec5b8467f683c7cdedbdd9db3747cd122d19d4513821c9ceddbb555066f3f58c82f9dbe78e4cfe87feb393ff06c5a11c65cd7389d5d66a7b8efbbc78710b8a14f8174cfe27222efc7e74bd1c98f3884467b638e3ce7be9aa1bb3bb8fad70b5a9ef2a983b33e50e22d51dea5bd5faad78de90fdc10e47a719853cf88557f248ee811ee73755bdecd319c3abfc5094a9652370b1b3dcf26c9c86f2de70430f8941051d67cea297596215379029e3350ac56bedc01de5e95fdff7bb7cfd2fced426223c5a417509f4dd15e77862ce6f0bb7a19d3da3607cd46367c8b2afd64bcc86eb3088de270a5620ffcc1981270f36e987e55fc8bbaa3ba810b7dc2a391ff6f2341fe41bef1c38a6d039fce93ae47fe5ca7932b2abd8f4e3f2968bd8bdc2724eab07f92f55fb9bd8149dacb64c322a3bc07ee6f900e26ad07265de1b33eea017b73825ece4dd42031b938e852df93420baa433509bc2bae38df0cfdc0ace5d5630fc499bf0799ec0f5708dfefdfb1f2cf55e57ed946c3fe3b2b269eee134552462561897338effa6dd1dac6b67e497b28fcccd356e4edf743bc55e208df3a51ccb40358009ce426abeacf7f6da35436c2567a30562fb44f8c4968ff3961cfaec9fad7ef6cdaaf076dc94f11a3dd058fa1033508f5a5770c2ba34506470aab81568ad891f72af987f39e07dc232832e8bb3477bfff60a43258844c62f4d6abc7041c820aa7ca8eb90fa4afb55a5060d73bcdfa67d01f1d22e895710f0a29dc40185561ba6733bc375f70c77cf3031d0d19cdedd7970e155c62ac7e1328e4b0093a30c79f2cc033b57c2ed6693ca296fa5a153cd3b8779a343797085bea4797d6050d8d929eb6a2b9323a0740366601daa2cb649aee0c09509983d9c117fad99eb46a096920e277bb673a08564bc28fe7353deacf9e44a32725ddba6fb2ae35dc2e2bcdb7ef657ec8f3a398b8a6fe67f6a305ce0ba93c195aa83ac53e4d7319e19b4ff63b8b017f6a60878bc2d7adecd4d34e6a9259564770c1e9cdeb46f74806ffdcf7cb029d5bbb653c2966d9f907d52407ae867cce13cb5ffc0b4ef5a3ac1cb77bd096753e04b524b4ccc815877aafbd61acf79f35e95cc8d18e0a120562619f47ba927b5aec327331478b81047932fcb2ccc17d9cab8ba8349ea7d8746ba3dfde9757bbf9be0f8d7deee71108b7de8ca57bb7585af469878f02da924cbb59cef3d4eee8cae3f24d430d3b5105996bf5de9442155f6e88b9365874f78e428a5ea55dd52b418548dbd1e71ace034f2dd364afdff91abf8feb93bcb7e76151f0788fd6fde59f69babf6def7d5fcb2fc833ef9d7bbb4dc7ebb8d727d3a533d66cbad63f39958639f2417d0698f032757575fcf5cfe85daa0af87d5708874bf6af5fb85079b7702b33c81dc5df197575665c7a8777677e3ee76b697fdaefe2dd9a9fee147bc1fdb575d7ec031d83ab4dcec6ca67db4fb01f3fd29ef2e8671399a9d5b32e38b2e8f884bcaeb9033253afeebe6846d4ffb76ffc5b194d3fbd3a50edfaa242338eb1505f72fc845db87e6ceadd83428bff2c88b6a695fafba9d05ed73f63c73388e2cad5f926960659fcb5917a0dfdafe285fd3ffc2a60fc9ee9a51f5a47cfd4739acf5f1b0ff89f5f144c4fb66d5dc01e5edade5f107dc43afcef9585ddd1961f36ace66a354f7878577536621a6974e35d816ac12d3098e1172ea911c7cb2d0acbea06cc6bae7372ecd3ea854d930b62e40caefaad6ac99d958f5b44d2023bed3e77c9fdf4deca768e323891fbe896337c64fb9ff224f5e176899b42e70f9c49fad0b6caaf165fcbd750180ad928cc80cf9c6e49c28b1e08ebc40e2eeb06d9ba9e4cca315356397a68e0cd675ab6907429891a8bab7f2c693e39ed677452b39795c783dddb08015724f29bba38efd464019d80430c146a48922e81e6cb6c87c83e860ca37bf4a27d3d6fe84fc790ff82b4fcc3159c6afdb39655d509960d27897eaf52fdc2b90adb9fdd0fcab0642f34fbfb8850815f7f21f0d292c3911f7a2e2ddbbc4c3e6f50a888bf63259cd0daf766f363f6a6d2dbe897670556fbacb894afdc646e2a0fc81072bd0b476d5b4d2da19ab92755615a4cec899b3b5fff63e0b8b38efaca52ca8575eccd6f45ba9480adb36c41f6bf964edaefe07ca225b0a45407089369d90ba03c1cb9eb23750ad5ff385d1631e98356740acf123d476fbc5b1c3590ada816ef53565986a8089b982043d894ba3088b75787ceedb967931f623b69caf77c155f8ead2e2fa6f8331b93e343a6629d2c8f398a1608d8d9f4dcf95a05012771cdd9fae4eaca7debeecb9f1fd92ea6721a879e94c4c64e9da01bfa0a94deab464608ded756266dee0caaef6edd735d0e1bdadae6063717be1e6ce050673027510d7fba73bb35d796c1a1fb1edb86bb0cb6837653342eb2f6fdf2390d6ac7ff97c0b1a780ca61778fec2f2cbd436e6a463d85f3ee7f0ac9634b8eee738ef86eac6971a430ca399da2d8e0e3912d9bb1d1005a3c53378b7b5f4377f7d12ca7f29e78a28a088b49e594c8d7b7420b7e52e44fc8b9bd17fba918a8cdc483ebc45c3ed3e59cba0d372e92a8147a106d5ff8fbb2f0f8772fdff9f194b832c85ecbb644b96905d681864295bb652b66c59b33396c328644bb678b2644d945d458821eb945df63142488591e57739ae3aaeeb774e679cbabed7399f3fe6afe79ae79ee7fdbaeff7fd7abddfaf7b1edb92ea14987071ea8c13ae760180e9cf04d615f5e48c0a3067222b9f4ca90b43032ccea3a43229571218527b78ab0ad7f3834958c44220f1fa091f2bb4b48e940f16848f4bf1f8620fdb67b3741620aa54e842cc98ffbf68b83f4edafd8018b26d41a01fbeca16b49b1d7f0f9ea4a1631fc813a937f452dd50577479dbfd963af4b542ed2903e1e09b6c6cf6db192f7866318e11ee628c2cd242cd55a415259f02081a0cee86df389283f93c5a5f0d7e00c281ef0357aa9a7a79247fb3f4411fbfc62da7abc87e72e87ee1b08b4c71f475610ea9462fbc6772180eacbdc77e5d7f6dd127cd3296529da988786d8cddbe6e96355d3d5a8ee83f51f4813d4d3b19e4dfc12c3daeb04eaec59eb8f462c2502e3d54e6c5a171a608394934a0bb22466f94d63d3c21debdc46370ddd1b53c37a0a1d4c88ac67ae3c5333462ea9b8896b97ddd223c4a9d4885c572b455285347e24a610d04b97089c99b533a10e03a873746c87d229afc9f89e81cba0c354191ae561356034037a1c489f0158ee8a745340200483ce9df7d9e8d70a0975883d1896fb55dafd259179b9e164c8c8c2f51862e03015e386fc679e32a7e7a018ff366ba48e262c226cdb6279467259342656d8873aa0950201c411330d299e5c01c1948155071a66004c910529d9849d95a363f9f365a77cc93f1550bdeb1ba8523b8f9070b99dac7423c607fc542b20d1bfa7f928510d58381cd6d53472f92b02cc97b56fdac19132a67fb8802e8275e87c355830b9b97d20d00e7e177b1728d2c27aac86cdee4918c8a0c9cf88dc67c715bfeb9879931f3e680c477c717fb411c5f66fef90bc2be304b87a3f04469d326d457b832f3631ff7c4582b8af6345de9c3802d9629c9fbf69015268922da35314f48e32dee9a5a68054ea9e5c28ed74ee79bbde5ef74b0e5ff6735a8835cffd72eff73e9758e85627e60a38e47e6120068788061eb6bb68de493538bde6225ae163e8047a05aea293e73519d2c860c2d6627484a8cf02bb25cb12ed5f418dd50d466cf2e2fb884dffbf75db4b95ae0561d9b74e57e18817cf2aefefeb238df9796c9d95a22797728ef14008209cc3223e7b33448df67642642ad385643903e51cdfab7c6a2cb863facca2ced922ca95fd1ec89006ab7ce9a57f4083569b3483c1ab8e63c56a71d04e39924b359ba669de2aae82c049c99469b64caf1e6b0adf2ea4d9aea1a4a170482c71539513d172291aba76dc9bf19922ff149130a278dbfbdcae75458de51c4a6203c9bf3ec8edf45736b939449d68b77f05eca917b8664b77f89e0f2dd843f2be5bfe06c37c7e7ce78b96d16c2888ab62d9b599468adaf465cba7611a0b32d6a7d4333c14b61de3f4bae014f78c0fde471ad8e3553db75f1f6ae681fdf6a702508077e0a7c66ab3c6278ab9e694518ed77e62502ab8a3dff86d324c4aef890476a8013cb32de018ac681adbee70ce87ea7096deb8f7346ec5dbeb77c0fb411911e9b44921462d96172c7da939a26af8a97192bc7982b9002fc5c370280c63e54fdb272c686ba0c99f0b62f5557367965c6fc8add35bb39d5efc3921c64d813204862166c896880e1716ca776bcff25f233a41b30bdcec80c8735c3931e35c071770b2abea98240b9a6a5b3b9d3d44ccfe966faf22548b424c2cb4f18762106bf0f4bba7f1bfcbb618bcc54f886de7d585c199b34fde2fdc4c68432457c0b56db58f1406447a3776a01e099106d21338488beb83c04cdc9b09c8531323fd112de6e17218321aba5da73f6fa981730f10d9a5c823e6313ae62759d5802d94e63b567b95eec225b57278582b57b434221cac0430da8a12fb0aaa8d889b1c716f82087d64eb2357f00053e788a0a826b938077718ba9af26a205e1888e00d051651e8139d4e455adcd12d9707ab3a31fc37cb050aa4eec6d18a7fc64e704deb78cc31136ee39b9380eeee4820f59d322636a7dd80eb378cc45b7a8587d2c8bfb97e7727c9c5c1180958e7bf66cb31c2832e6d92cbfeaea369350f6adcad2ce8bd0abf4592b95c061c0e76e3dc1722d98da4d869da7c7ef5629249566f45509ddeb410d21a7873529b0ef12deea3f28e1e7c3328349b0a7d30cb8238094cab4b35fdb481f893ce41145850919e25eeec40146812ad8d5ca693deda352a6aa794b5845a273b70b02edea4a2451fc3b67b00adf7bd4c4fb17b9701c9e5b8d3285fa8ad767f10ba9348773e41f50a73a8c0586d6230048340a639faec54a7a41354b76e3ed8c95c38c1b8d48a94b058dc290d8a5f348e0ba2c751b91b9c5c504e355c932f123d471500f849d183cd167ca4909d3ae706f8faf181f8caffc5971e17fe2805ad70295920b5a9d425263838bf70b46a9222cf7a61b51086dc6b593f6b3cd9c01c0b9eca50f4e2f9008b113cf6a74387448aa3f4ddea17f55e43a1c48434bdf777b6e9743481f8843008b1c9e9a4bfc3c748b5276ab41819fbb1eb64ffcfe5b8815cd1d578f267de0b5e7bdefeb694a003240bdb8f7e2ec08474d90eb95c4866ec08d596bc9d3a8fa7a029d92896c9d7205ec29347fdd9dd9939f81ede3ac2f895b350403c2412600cda3cfdba0415c57a268f97f0b94c3c42852703a600a8e0b1a093ced92e38f4bc73b2f26e020f17fc881e9fd72a0feafe480944ebcee4fca01e27a04c0c860ddfe7051bc7eb0a83d91c8d1adfb9dbff1e711afb420916c1a448168c857801663ebfd6640cdc2103ea137b53c3569c3d8290f49f778c7ee956ae23e9a77631718f70301036f1614747850728b2ccea69d31f7da90f2e649ffdf136172a4653f307ef37c7698048c667d1ab130a2d038e55cac055e5b966c0dafdc02f469b55cf2c4ce0979255defb21f7fcff3fe4d09ad01a8aae6e3c7cb3e8dbe92647b6beec6afd508d7aea6b5f9b5e80c8b8ebfb6a63a9fe19060533bfd9f58736ede03e59943dae5d4f5d2023b3bc4645f3ed569aa070c905a0f16d6c2f3357b01d618cae20eb22a3d78cfcc391345c93bc5341cd657f559adf99220d8b4e3d43e7b87425fe7cfa62fa0c12ca9156b8d0d98dbba63693e6942433225f4b7e23af4d2d9d3f09ee589fb0e851edbb7537d68feb9544df8825c8d58c2ea5d17eda9b7646f1972b912b4cd593d3daea4aa7fdd24171850060ec9717871e4d731a13fccd527f61535e6de66121077b25639db5434df9998eff74d13e47d72e531876f6bd159b2f913930ce6c1d5cd4b37d846a2ac6db891924a157d783f69d29e2630399826f8bbe4ff8f354109f9715213553d6355818a76497b47c63838ea5e780bf7a6acc0c8734c54f23d002a6496d48b75f832a1b166c472c2c331f30282ea665e66607afb910ee913fd65d5e065100ebc00385e3ff17c6653d5cf74b22d92fb26e1dbbbc76e64a8c06adadd027da92ba3ce7ae31da0141c38bdaa6bbd83f3e006a1bfa381ffb862acafb37151882a3a81d95db79a7fddf8dafb23d0f317ae425978529fd75241474e0214c14484665d32d0fec3332dd45c0587f3a1b26fc3535a9e5a3b5f6c77e10dc3ed42ee7c30c8ff0167c50f72494ff10537e788dcc75f4d89233b121ed0849324f42550e4197af1850a4a43f50038abce58ab3fdb97c36ed30123e501299fe6ebf2da57641bbd9b1dcb03099937aa4640eb830076c52e4344d96b9ef96ca6fb43274ce1cc74e33944eb0aa26068f0ac8b0f78136fc0d3d62377370a995f711432027846dafea4b6d8993d0379a682c943a9dee6f4c6a7fc49ced512f9ee8af75ccd148029733fcb51d39b14e82ee9b595c9de3ef74bf22a8e3708300c15fde8cd858d8fd584c6201ca10110620cb2dca07add2e1f089bf05473c54595d984131f2a80c8b71abffaf8b05b10efe74bc71142abc12238b050f0a189507b385a3a048c284ad097a4a0acbd6c12553ce855c37cc8189e5e7aa80a51d5e442079bfc1b18d97f6e1a9cf0ffe1657be0dd8fee6d91e55afe37e353fd0e04efac02fac9a94f4cad36da0659fcb6342bcbeed3324c371202b87a775843f50601db165de5649f4be414dc2f83bb798ffb7c8589bce20c73c435062f7e94af3b1ff42d6693ff86983dfa51675f8f6cfa87dff7b26608c02b66a237a8a21763730fbff1e4a07edfbdb3c16b9dea0a3fe7ce503094af258745da0090e5de0f61f54a56ada14cc96aaf06ecd59d079f9e66582c6e49ba37a8da1f4ef12d6653ff869845fc44cc88f9d93aedf088d92de0b4d2cc1d27ff88cc42bb64abecb0e8471e8f6a47f3087afafb7b1727ad32cd8d01f2d3495b1990cd378b4c02a26cbe16616acf95b86256a52763c96322ac75dce7aaecd66d39f02b77a22c6d0d3e838dbcb70dd36a1ea7c913a4385c6e34cb4737151de14bbcdb3bce02088ff0760d8b2d7bc35081bf853b16d7570ed2081ec58683bfa87d40bdd09775ac06278270e0388081bbbf3f5ee87295478fb88524da5eacd4e77e0955ef619a90d202c8d5c2bc28bc930b8003abfc210f30fbe4c1a3eebf92078a2f29197e4e1e10c8d58381a3626e23fdf14f1b261402da750767331a1ca2065f691dc73c5f3575ce545d4b02fc4ba7e706f5dc8695dcdedd0e7abff205414f5e1d298c72af3c26d2d1969fa2b29bf54d7f4dd6b7dbda2229b430599e9b12324445e545da2077348bdb569c4607e60760845acf00a7c6f1ecac116edeb5e2c910dfd4fb7e1b8ae9141a3b40d9329ad3cace2dbea01a920ec24152006e228e37d26766c7b91b5649635d7bc8a4d0f3062b264ca03b75cf08bb86efa3f106261307d1acfa0a595fc7f3ef89c2da7a6450cb7f527b29c7b632ddf7a0f71098e4f017687ee03607e585fc1f38125d241db744eeba6ee4396707dae590296a84d2d05b8e7ff22b1c4b22ce0eb39e05a4128e1bfa7e323d9673a572baa660bdfdf69965cbd8da159c981cff9df93922fa3dc1e5f26b05d711544c4b22cdc9e5b98756aa8c6a6b0dbea16941ff09c18584d2c4c66c57d20adc2aa917bcf4785bef50de2663c5cd2b0647e62bec3e138b02a61770236d5dce412e8564e853a3913df3dd102343bb1ad2b759d85287906d996a88300807110444eb4a9315a2e73e37f1075bf0713812703ebd328188437629b950da747e09c59f6767e3c0a37b18711e0c23cfd703fd3e335d12ddf7270e45d06b680a299e92fe1f28444500c69e4ed69878761ca577100512bed36e3630e59ddcab5eb53c245d2ef59cf82a20b3186f7a51aa8035f9f5b2b5a6522f6b475627ef73a9741706e15e969b719a6cdf7d215c07f285fcd9a4af070329c746938d422f67de7022d37f8498459f4f149ef50f71f92097c6547526895b1670999a96e9e36fe315d1379379894db6569ead7eb460763b52fa6d992fc2ef02e65b1bdf656c504bf6b4088f1ccb3c0a162b2bb465cc390cdd316fb821ee21b34c0fa1c27bca3cdcd7c667d85f51c5bf8dff0f26073e5ef870c7e0ba37b9a74ec9bd93e047493b472a050130456e64d4c360e34b77e55d8d000d4a61ddbe8b3af09a00356dea2f26d1e68a3c5fa508c68aeee4a189178edaebffbf000000ffff1ed9a0d101","nonce":"0x128cd","to":"0x8453100000000000000000000000000000000000","transactionIndex":"0x3b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x41535904d7b20be8d733e03d95ec725d0c6ee4307d899cd00e0ca0de91533b13","s":"0x3f98c81207d078199bf74a600a77cfa389574646d63ff55ccfd194491faf7226","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xd3343d473f624c02045a01f4e7ab604bc56c4f42","gas":"0x156c0","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xf49895cde","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0x00b5b05c6d1a2eb8abe2c383da600516515e383fc8a29953bb6e6d167e9705b2","input":"0x9aaab64814636b3e36ce9c4227a5fb53273a04c3fdc94c8a00a4d6d5b6521571b94ec7ac00000000000000000000000000000000000000000000000000000000000028a416eb20a9e75d33ef7eeb4a0bad7413cea6c0b3a7f6ea249a93a428c0c36b52240000000000000000000000000000000000000000000000000000000000840244","nonce":"0x6c7","to":"0x1a8b038f5dff48f541e8cc658b9e186b9828a726","transactionIndex":"0x3c","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xfcd40d6ec6fa94f40f866c18457c22ebf5d8e3aaf2616c4c1cee5245ce8f042c","s":"0x45e5962efdda48e38f706cf8fb7c2f722d80da6e0a1d2589b6627627b44feb82","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9aba7eeb134fa94dfe735205dda6ac6447d76f9b","gas":"0x3e64f","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xf49895cde","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0x6fc411f24c7b4b8d821b45de32b9edc5ac998d1ac748a98abe8e983c6f39fc19","input":"0x2e260ac30000000000000000000000000000000000000000000000000000000000000200a5c46e2dd70854a0fe8167b705eb7df71cc927469c345248c81b21a5ab2f5f19000000000000000000000000000000000000000000000000000000000000051d000000000000000000000000000000000000000000000000000000000000051e000000000000000000000000000000000000000000000000000000000084024700000000000000000000000000000000000000000000000000000001b3fd9f800000000000000000000000007ebc0d2451003f2d3bc5f6eafbb7e6bad81e250d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000640fdea40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e43c000000000000000000000000000000000000000000000000000000000002e7d600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6cb686532a3ece4a20f823e59cc386e1ba384d8504e902c932fa1497c4afdfb0b000000000008008402470000051e00000000000000082ffe82e7b18f0778493c989ecae1740325207ea29328999d5ae646723a4bb75a1305c8ca593670972f535ff8afda050351549ed800e9b98c805788acfe20e6ac076ae024efa64ac3ceb8f0a3cc9ce93d122f6faf8376c854da95567fb7576f762299ca2135608c7ac5a824257b50043526903fc8e01ad88006448a69a4afda4c01ad8a6ed1260582538f2311e902c1e7d5853a75b74482117f2cf920897c1b9428eaeb7e74a95d3d32db03931d157a48aaca9748bfebfecffc2d140caddc66b300000000000000000000","nonce":"0x108af","to":"0x7ebc0d2451003f2d3bc5f6eafbb7e6bad81e250d","transactionIndex":"0x3d","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1b284cf86146fa2094c7c709cf9fcb8a177f4fde1d1c5ca112e41f82a5e973d2","s":"0x5618261c40d23e5beb7ac0bac77b16ead56e547f103f649462387c5acdf18ba5","yParity":"0x0"}],"transactionsRoot":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","uncles":[]} +{"baseFeePerGas":"0x7ccf990f8","difficulty":"0x0","extraData":"0xd883010b02846765746888676f312e32302e31856c696e7578","gasLimit":"0x1c9c380","gasUsed":"0xa79638","hash":"0x11f97ccd0591e9746603e95797e835d6f972384bd8d48053624c99a611cf9b03","logsBloom":"0xb034000008010014411408c080a0018440087220211154100005a1388807241142a2504080034a00111212a47f05008520200000280202a12800538cc06488486a0141989c7800c0c848011f02249661800e08449145b040a252d18082c009000641004052c80102000804ac10901c24032000980010438a01e50a90a0d8008c138c21204040000b20425000833041028000148124c2012d0aa8d1d0548301808228002015184090000224021040d68220100210220480420308455c382a40020130dc42502986080600000115034c0401c81828490410308005610048026b822e10b4228071ba00bdd20140621b2000c02012300808084181ac308200000011","miner":"0x0000000000000000000000000000000000000000","mixHash":"0x31f0c0305fc07a93b1a33da339c79aadbe8d9811c78d2b514cd18d64e1328f25","nonce":"0x0000000000000000","number":"0x840249","parentHash":"0x2303b55af4add799b19275a491b150c1a03075395f87a7856a4e3327595ed7df","receiptsRoot":"0x99da71b17ae1929db912c3315ebe349d37f2bb600454616fdde0ee90d6dbc59e","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0xea6d","stateRoot":"0xd12bf4cf3941cf48be329a939b13d3403d326841c69cdcc9a9c13ab2f227e904","timestamp":"0x640fdeb0","totalDifficulty":"0xa4a470","transactions":[{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1b7aa44088a0ea95bdc65fef6e5071e946bf7d8f","gas":"0x5208","gasPrice":"0x174876e800","hash":"0x39c666d9b5cec429accad7b0f94f789ca2ebeb5294b8b129c1b76f552daf57d3","input":"0x","nonce":"0x26bd1","to":"0x68643ada5885f14e7c15c13bee06168eff0f7c36","transactionIndex":"0x0","value":"0xb1a2bc2ec50000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x26e648625520c256d87d8e15769e8c4290d2a7e27147594815da42070870825b","s":"0x7db34c91603e51494b59b020597e7118433d50ed548bc7efad8880cbe7820ca"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x030b1cddf635e9e71ad70b8668e235e8ec3c67c4","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0x2ca7289ab3738d17e0f5093bd96c97c06c9a2ea4c22fc84a6a7fbfda93ce55ee","input":"0x","nonce":"0x456d","to":"0x89416096a0a1acad3436a357478c5c548e4d382b","transactionIndex":"0x1","value":"0x16345785d8a0000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x5aa6ad410ea42dbff3781de67b4815a376cd459206595fa6655c966a7709e5cb","s":"0x82f620f8dbc356dc38ef346d1e152656a1d318becbcc41884f61e85972355c0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9c67435ce8a33ad23f377ddf08260ffc56417f21","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0xb0085de1476530de3efc6928c4683e7c40f8fac18875f74cbcc47df159de17d9","input":"0x","nonce":"0x446c","to":"0x471f3a988a77472e971112e7ff2ce65996b6c8cd","transactionIndex":"0x2","value":"0x2c68af0bb140000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x75425f21a6e66e6feaee79455c897656c4a94b6189c4c033facab1b67812fc3f","s":"0x7014f4b9f760165c7757f9d6dccea349b3d00b0a9c2f845af8010140842f826"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x168f6dec26cbbb3749654e0e3cc4fc29314fdf6c","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0xe01c8631c86ded63af95b8dbc0c8aac5d31254c14d6ecb4cc51d98259d838e52","input":"0x","nonce":"0x403c","to":"0xf2119a49a3ae35453c1c2704da248d08977084f1","transactionIndex":"0x3","value":"0x16345785d8a0000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x56bba57ee69c09dbbd5167d0fee07d5803130fea7c278f4d8b7bc54b34be8ff9","s":"0x7eea69c0de47b6b808ea1bdd9ecf5d25f4f2743e867b1f838db59c456026d7e6"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xc9af69904b4ba7f0fb69ab1a8719bd8950265e73","gas":"0xf618","gasPrice":"0x1701ca2b9d","hash":"0x69414a126a6f07ab5e31ad2f9069fb986b7c490e096898473873e41ece6af783","input":"0x","nonce":"0x44c20","to":"0x6adc3f5394e00cd067d1fad5a33756791e303c25","transactionIndex":"0x4","value":"0x16345785d8a0000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xdc9a52b87755cd07143bf032d57258d0d6c36500b38a574a9a5addc1293343da","s":"0x581e6fd051d0c72d64303c1f90edecfef46580f84f24dba930cde910923f7c21"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x92964e63cd52450e6e09a266e0c226e524754563","gas":"0x2625a0","gasPrice":"0xf5686c7be","hash":"0xa2fef1133ee726533c7f190f246fede123e3706a03933c1febc92618f90d2804","input":"0xa9059cbb00000000000000000000000011f7db5a824eaa5737c935ad09a925dd707f092b0000000000000000000000000000000000000000000000008ac7230489e80000","nonce":"0x2636","to":"0xbc071c64ed8f536011c78e847755680740d6b73c","transactionIndex":"0x5","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x422c5026584cd8fb8a1fe66e6edc7a020bc513cc3114083fb35f9846cd9a9792","s":"0x7fcd4e48ac5b53d881531a5651e587188157ed88d85c51533f7c6eda94c67ff7"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdec1bc71bf91431d60ef2742f412dcd1c5a204b8","gas":"0x7a120","gasPrice":"0xb80e515ce","hash":"0x6585ec5c4c2bbf1f683f90f58e18f3b38d875e94457fe4cbb7bc5bf6581f83af","input":"0x67a5cd060000000000000000000000006343e96c99e2725e845ba04f90e03d853cc9bb2d","nonce":"0x6a5a4","to":"0xf5de760f2e916647fd766b4ad9e85ff943ce3a2b","transactionIndex":"0x6","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0xcb7b32949ac0dedd3151d06d85ec4e99483c8ea706f12a009d97b055975241eb","s":"0x69f0009bce12e24408f9a3d5ad5a8578e2b23efb09002f7b86b3425cf8748889"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdb954dd5d224004b26cfbb089312e0542e5d1c31","gas":"0xd5ef","gasPrice":"0x9fc748df1","maxFeePerGas":"0x116482c049","maxPriorityFeePerGas":"0x22f7afcf9","hash":"0x1db276b864fbf01dcf8cededf8d597553ecb0eb9438edfaf2f5bd0cc93297c66","input":"0xa3e35f36000000000000000000000000f18f2320e4779f21d6882d83f9133e582dfaa9b6","nonce":"0x570","to":"0x11672c0bbff498c72bc2200f42461c0414855042","transactionIndex":"0x7","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf23a1fb0d17cdbc2831a2cb0b779795e12533e34425a3abbc4b7e7bde262b92d","s":"0xd4a2c8189378696065b7fc5d13e9cf6595d96047a31a4fcb812c2e677d22a26","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xe84d601e5d945031129a83e5602be0cc7f182cf3","gas":"0x249f0","gasPrice":"0x9502f9000","hash":"0xcbe7ed31654af4e191ca53445b82de040ae2cd92459a3f951bdcce423d780f08","input":"0xa9059cbb000000000000000000000000355f96e3261cc8237d2d36fd81cc9b9cdcbfc5ea0000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x4f1f0","to":"0x499d11e0b6eac7c0593d8fb292dcbbf815fb29ae","transactionIndex":"0x8","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xadf7dce5f34d482bb19ff0c85f43be7008cb838043f9abb5fc08421245ac4228","s":"0x5d2c0f0b9d2e68bb8da6084e4971d57bd76bf0cd9d893c9c985962812d2df026"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xea0193f88a0d9c36e83e6fb6d382212b6373faba","gas":"0x43238","gasPrice":"0x933ea77d8","hash":"0x808ba5211f03cc78a732ff0f9383c6355e63c83ae8c6035ced2ba6f7c331dc63","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x9","value":"0x470e9f23394000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x9536f87e8c3433ea23ef7211c0c32689551906dfdf31bcc73b89fcf18fe86a92","s":"0x3e94bfe3b4ba32a6ce71ee6e0ff9f26dfc2b0d61b5c0fe049469e3c4b88ac227"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1f9ab300b380313e6a2208e44c01a0602538385d","gas":"0x32b38","gasPrice":"0x87fc9eef8","maxFeePerGas":"0x2e90edd000","maxPriorityFeePerGas":"0xb2d05e00","hash":"0xdd66f1f26672849ef54c420210f479c9f0c46924d8e9f7b210981ffe8d3fac82","input":"0x32db5470000000000000000000000000000000000000000000000000000000000084021000000000000000000000000000000000000000000000085b0af981975a40fc5a00000000000000000000000000000000000000000000053ae1f470262f3b01c4000000000000000000000000000000000000000000000813bca9f8389ffd193f","nonce":"0x5699","to":"0x28cea7b0f3916c1dba667d3d58ec4836ad843c49","transactionIndex":"0xa","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xbe8eddd463a3518a4c94b5922c0f2fb26a32c8afcd819f7deaf4f0416757ad13","s":"0x3e234182acd5261dfba3cf4f125d1a8377fc707b3b1900b565d1a6b8987b398c","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1d990a2cf61b46f37582dd31a7b242e989e1a1ee","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x254abb2f8cdcffe9ef62ab924312a1e4142578db87e4f7c199fd35991e92f014","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xb","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xbfe9b99fd2e9bbd2d65bb4cc17da88130d8f6b569a26afa642ed1cc8efd2e2ef","s":"0x7003dd3962eec2369bc5abe5e3d5b73a9086a3219643b1741f3a9832369448fa"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1124bbb196fd7b61947f6f03b7d7cebde8340b6f","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0xa7b7c654e7073b8043b680b7ffc95d3f2099abaa0b0578d6f954a2a7c99404e1","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xc","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0xe8dae9efa8fa73a3aebdaa75ba12acf56712b1f99fc128ab802a7610d014547b","s":"0x2ef347ea90a0db21b035637342bfc916c9962d3ec610a4e99cfaf555a2606fe2"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdedf52a88fe47f6a11d629badd0096d201aef86a","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x7ccdfa698c8acf47ab9316ed078eb40819ff575bcf612c6f59f29e7726df3f96","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xd","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0xfc4e092094abc7fed9cf11eea8ad6ec3a760d13b9c603b5570c2143e48090f2f","s":"0x31a0a6016ab51ed6375891bf532d9031bf91c1d0e01df63cf7e46076aeee83a3"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xe1db1fd154b344ce7dfcb53a65279559b298f0df","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0xa0b035ef315824a6f6a6565fa8de27042ade3af9cf0583a36dea83d6e01bf2a8","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xe","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x79c316492bfa36fa4de2dca02ffac77f6c1772714e153aad8c947ce848d4106f","s":"0x4fe3e083943ca8f974cb0752a2ffb70e4d6c8b615e16ece7e19b2c464be66929"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xd4c3777e1821f6fb532957104e1317a9d3f881ec","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x1ebad7f3e8cb3543d4963686a94d99f61839f666831eab9c9c1b4711de11d3d9","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0xf","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x5c1f544ca92b28a014129a9d04f8e895dc8a6987ddc1717c26b0619bb9bac420","s":"0x47574643bd92a0f129f9c5ce3caebe7943cfd828d67fb0e5bdc1eb2ca202822a"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x127418955b15f5ff2fa232431a798b53fd006c82","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x501750278e91d8b5be1ccf60e793d4bbcd9b3bb3ccc518d3634a71caeac65f48","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x10","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0xcfc9894bf716ba707521f0969082afb688b7d47cc21f1423b239c40867128f47","s":"0x5d9b9c66d8437d0a37768fb9c3241ef64b7e795d0d908196e1f707215ac1f56"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xc2ac1bdcb3dd77864b99eb2cafef2ed36c1487c3","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0xd80ff8af29ae163d5811ba511e60b3a87a279f677bb3872a0f1aa6d0a226e880","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x11","value":"0x2387acb3784000","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x8bd7220d176d18cfbc824063448cf864c494fcf0958dec82126f26d3fc6c0b6e","s":"0x2f4de3d2fc3be6d2812ee10aee16a995af5affcfec27f9953ae609886d2b563e"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x11a5ad000f8494233df5bd2f2573fe20bad744ab","gas":"0x493e0","gasPrice":"0x86f96eddb","hash":"0x096acab3b3fe47b149d375782d1eb00b9fef7904076d60c54b3c197b04e6bf82","input":"0x9f8420b3000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x1","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x12","value":"0x45d964b8000","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x43726c3165958e94d80cb6992121f55df2904a1de4356e0a6ff3d8bfd03c0928","s":"0x6244361e31daccbb5c7e9f3f7d01004080d2efa314d614fdc2aad4c1b7d71613"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x90f8b290ec2929cce086826e971cad3857c6dbb5","gas":"0x50f46","gasPrice":"0x861fc89f8","maxFeePerGas":"0xe22924cba","maxPriorityFeePerGas":"0x9502f900","hash":"0xbe9d1738af74a22400591a9a808fb01a25ab41e2e56f202dd7251eb113e8ceeb","input":"0x6ab150710000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0xe4","to":"0x2e84c9894f628fd209f48b06d10b46c8cada4c10","transactionIndex":"0x13","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x412c7bfb0236a4317da40645ee4e60f19185e7d0cd2cc9bc88f7629de505b939","s":"0x4f6bd485d10fa134926ec3e3a83e212f3c5d903ba52da87f07794a2ba0a5c1eb","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x7915ec065b644568155c4772a286addad3864c1b","gas":"0xb71b00","gasPrice":"0x861fc89f8","maxFeePerGas":"0x1176592e000","maxPriorityFeePerGas":"0x9502f900","hash":"0x0834c720e55cccd97aaf4f8fb0cb66afb9881fb6a762c0f70473ec53f98a712e","input":"0xedce8b4d6a1fb55588eadfd3a0c3350435a31d31e7c236125eafcc2a892d50711d9a4939a4282888c956c070cd83400fd47ab83bd5287244053b8228711b07386dccacbd000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000008a0000000000000000000000000000000000000000000000000000000000000092000888ad4975d4079d80bc6da5ded57746f889644719ec160efc2e4a96ad645df10b1683afcd7ce41ba6c06528761f821cbc6e806ef4b71c189603ec218b12a1f1478883498e67b97ae4babef6996acc582db1377d8755374602e00b8148025ac2d2f52e78d7484919cef14bf96e5b7a3f7f8cf09989551888f2c697052ce2bdb02a9296b20016c78683a9ca137037e57c8ff25198146f9d4cdb5a25ab9c95a03038f22f83c8604ca7c035ef756d2963c3657eea4ffb18ef967752d8cff15a16124a1d92a1cda613624c98e3078742803da1417b78bb264b7bb2197515cb4facc2ea395c6241664dbd953d0034900a86eb94897bf89aae775a1d73e6fd034785400000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000001d802f901d482e7041b846de27f7b846de27f8383026c28946aa397cab00a2a40025dbf839a83f16d5ec7c1eb841dcd6500b901a45ae401dc00000000000000000000000000000000000000000000000000000000640fdf5900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf0000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c000000000000000000000000964ff70695da981027c81020b1c58d833d49a64000000000000000000000000000000000000000000000000000000000000027100000000000000000000000009a1a41127726f74560a57990fb928120eed6f55e000000000000000000000000000000000000000000000000000000001dcd6500000000000000000000000000000002d4766adcf72ef2d996edfadc866be12c28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000001d802f901d482e7041c846a969541846a96954983026c28946aa397cab00a2a40025dbf839a83f16d5ec7c1eb841dcd6500b901a45ae401dc00000000000000000000000000000000000000000000000000000000640fdf5a00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf0000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c000000000000000000000000964ff70695da981027c81020b1c58d833d49a64000000000000000000000000000000000000000000000000000000000000027100000000000000000000000009a1a41127726f74560a57990fb928120eed6f55e000000000000000000000000000000000000000000000000000000001dcd6500000000000000000000000000000002d4766adcf72ef2d996edfadc866be12c28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000001db02f901d782e70480846a969541846a9695498302e100946aa397cab00a2a40025dbf839a83f16d5ec7c1eb870aa87bee538000b901a45ae401dc00000000000000000000000000000000000000000000000000000000640fdf8d00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf0000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c000000000000000000000000964ff70695da981027c81020b1c58d833d49a6400000000000000000000000000000000000000000000000000000000000000bb800000000000000000000000048f2c17f8885e135c8689626d5841d0b94013556000000000000000000000000000000000000000000000000000aa87bee5380000000000000000000000000017a8db2711fe83b10bbfabb6a8b86c3e26ca154ef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000003760f4e19e59be10b323fe1b42e42de2754c5da54ff316cef74ef09dbc0144bbf73e609a8d21a38f393bae9a3de6bebbf362608d907d941c8166f44d8ee2c6686b5dbbd6681f5467219d9bb530db013b7c067db659c03efe935caeb7bab36699d00000000000000000000000000000000000000000000000000000000000000032d2d7436bd45b5e81824945ff3dda846e270c81e72929841f4b14f56e02eef39477f9c162a2759c8d7c7e1feefdd064f6aefb4360d483f70671f36fc11ccc6db6c53f74e3019c12d859545ad75b51998b2238887dc0be3c78522c8356150526a0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x48f08","to":"0xe87d317eb8dcc9afe24d9f63d6c760e52bc18a40","transactionIndex":"0x14","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x54159a63b8ce19097cb8afeaffc84cfb5257f9709dcb0f0a258befa0b924b13","s":"0x17f5ef5aeceb6f082a8a0f8fa28e55d453c52e5f86d48dfb4d4f039aad7fa493","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x52db522edf50fc32b8fc0f77d51140031da11da3","gas":"0x201568","gasPrice":"0x861fc89f8","maxFeePerGas":"0xe22924cba","maxPriorityFeePerGas":"0x9502f900","hash":"0x51a0c33c9b37245b416575bdd2751c0d8a5d8bead49585ac427bfc873d4016af","input":"0x96d3f83c0000000000000000000000008cd194f4ced354a14960f76f49305feb8510f73f00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000641024ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b3fd330d479974ad52e18b8767d9f18cf9ff024fa749b1066a803b237570cb73e2868e821124c8128505d883124711ae7fdca0339f4f5cd5dadd8eb6956eb4af500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003","nonce":"0x2d9","to":"0x29c1442d7e3b6ed179ceb55fe996e1f4384880da","transactionIndex":"0x15","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xac84f403fa0347be3246ad695f8f6a780332357d49dfa67388fae3e051e5566c","s":"0xac2e148c1045af0ebdb334f20743af7d5499558af5eea43393159ce26a3fb1b","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3aea5f857b75a946d5f5b329bdcf4db46aec5d2c","gas":"0x50f46","gasPrice":"0x861fc89f8","maxFeePerGas":"0xe22924cba","maxPriorityFeePerGas":"0x9502f900","hash":"0x531c25d51ccda59aa9ea82e85c99be9dd4e285af9b8973cbab9ac4a38e26e55a","input":"0x6ab150710000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x1d","to":"0x6c23a4586cc791d2be6767532e12264992aef74a","transactionIndex":"0x16","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x81abc4fdf3b57fdf3a951fb293853fdd86aadce8f319576ac78c60caac186c43","s":"0x452742335bd1f63fd623d5e6cf91f6339361f863dba1a57fc3c1da8292e82c77","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x7915ec065b644568155c4772a286addad3864c1b","gas":"0xb71b00","gasPrice":"0x861fc89f8","maxFeePerGas":"0x1176592e000","maxPriorityFeePerGas":"0x9502f900","hash":"0x93ac6c08d21cb1b61ff59e5e2d6fa3f9ad54008b0a66c669199050bef219f6e3","input":"0xedce8b4da4282888c956c070cd83400fd47ab83bd5287244053b8228711b07386dccacbdb54cb66757631f9f22e2faf7da0eecc43474ab1a1af21aec22dcf949e2579241000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000092000000000000000000000000000000000000000000000000000000000000009e011cb7bbabfab668b42b5582cec8d60f326ae14ad55f8d675060dd111dee6c88d0937435261929ba3a881bea107593a10e13c917a0ef5ae4e8bde40de2d1da4ba25ab3a239ba53eb4e260d23b98a7db944f644f40ab75992a89fad40e8d692ad62f8671604db415b54238c5522f6c4e6b25785bffa696d173659309b95a2fae8700d4b9c14382973ea34a3cd8b8428594908dcad2d5d7a01056b8e49a8c25087f12f9e9fec1f4b5fdc57509dba6839100e28016b2e3fec4928bbe11d3789b6cab280c17bebfa5a0e06aea22764e1a18d2d11316bdf81028e65755582586ebdf571cbd0ef59800ba3405539187dfc03eac1dba0cf590e2131a56ef7f260aa38f940000000000000000000000000000000000000000000000000000000000000aa0000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000da02f8d782e704820101846a969541846a96954982dc1994a59477f7742ba7d51bb1e487a8540ab339d6801d87470de4df820000b8a4220b5b82000000000000000000000000f6213f16f3db9b50c684b2da37ff080895ae4a02000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000064376b6900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000003202f082e70411846de27f7b846de27f8382520894b6605a717a2447edac46b1cdafe35e3e91130c8d87038d7ea4c6800080c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f202f8ef82e7040d846de27f7b846de27f838303335f947191061d5d4c60f598214cc6913502184baddf1880b8c44d49e87d00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000160f9854c9f595e000000000000000000000000000000000000000000000000000000006417d4b8000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000b2f4f1df2e372ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027502f9027182e7048197846a969541846a96954983029eb1946aa397cab00a2a40025dbf839a83f16d5ec7c1eb80b902445ae401dc00000000000000000000000000000000000000000000000000000000640fdf0b000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000e404e45aaf000000000000000000000000964ff70695da981027c81020b1c58d833d49a6400000000000000000000000002c1b868d6596a18e32e61b901e4060c872647b6c00000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000c097ce7bc90715b34b9f10000000000000000000000000000000000000000000000000000000000000000000000614000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c0000000000000000000000000000000000000000000000000000000000000614000000000000000000000000694b3f194e94c80b2d7a0e986e1440f204f0503f00000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000b902f8b682e70427846a969541846a969549830dbba094964ff70695da981027c81020b1c58d833d49a640872aa1efb94e0000b884437471fd0000000000000000000000004e44260732136caeffc7d076e17b2a3554b9ce2a000000000000000000000000000000000000000000000000002aa1efb94e00000000000000000000000000000000000000000000000000000000000064376b6600000000000000000000000000000000000000000000000000000000000dbba0c0000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b0000000000000000000000000000000000000000000000000000000000000005b0efccaa7c845eddd4fb98211c7a58a37abdf06b264fade6cbff8a73ed22fccc602337b33a81e2cc4127be9d913fb3aec24194e14a61515a26429a00cfb86196aa3c2e6983f1a05dec045f0e63db7bd8619cd2a770ed1f7f470eb7c297e8e19d61277fb276ed8a63fd666b4a5ab02347065a3c16539f4ccccbed8fa39f2a7dc6606fc04c49f3d69463ba1c86c6ddcef8b9f06b9741dc2ebae9f5f1c0523b320b00000000000000000000000000000000000000000000000000000000000000050668b9ca5e5b17e2e79f9f5a7d9ea27e4e7f0302e878584fef3c2304c70c1ef53da311342341f89df488646b97a83994a3d07cc622ffde98598548c5326b7ccc0cf77d5d6fca6cf3f5b5b41a266fa2aaf697fd976dddc710fca834c96d2dfd725eec5980733db3c4e8f779f9fde3a598b2860d819419c961012825f0e160ee7b220989005b6ac5c48734db18158c2d85c8499bea1972c9f875c2d2aeafccb33700000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000f6213f16f3db9b50c684b2da37ff080895ae4a02000000000000000000000000f6213f16f3db9b50c684b2da37ff080895ae4a02000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000064376b6900000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000964ff70695da981027c81020b1c58d833d49a64000000000000000000000000073fee82ba7f6b98d27bcdc2befc1d3f6597fb02d000000000000000000000000000000000000000000000000002aa1efb94e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064376b6600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000044a1c058fa0000000000000000000000004e44260732136caeffc7d076e17b2a3554b9ce2a00000000000000000000000000000000000000000000000000000000000dbba000000000000000000000000000000000000000000000000000000000","nonce":"0x48f09","to":"0xe87d317eb8dcc9afe24d9f63d6c760e52bc18a40","transactionIndex":"0x17","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xb5f185933d49064643686594f44a2584b1d57ba6a91f2a45d1a122892488f209","s":"0x7bb4af7ea30290b36fa7c266ee2387eff9e3ee0cd79b48aed27f5bfaaf34114c","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x4281ecf07378ee595c564a59048801330f3084ee","gas":"0xea60","gasPrice":"0x861fc89f8","maxFeePerGas":"0xfd18eeafe","maxPriorityFeePerGas":"0x9502f900","hash":"0x3792db6dd6285f409e4281951e9f78dad16c4a78072ff1c909dfadea5658d857","input":"0xa9059cbb0000000000000000000000000cc351a97c2fafde4cfa8a00c4fd79881cf13b53000000000000000000000000000000000000000000000001158e460913d00000","nonce":"0x77ffb2","to":"0x326c977e6efc84e512bb9c30f76e30c160ed06fb","transactionIndex":"0x18","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xef4173dd45060791cfb6dfc3cdc8a9b417ff6a4b3ba57759ea91fd875b01a522","s":"0x4de926b5099c7d60cc24add3c2eecd8e9550c1fe7f878430eccb887a2ff932ff","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x53e2c2479833ca17f946aeb16dcc49f5e2194701","gas":"0x431eb","gasPrice":"0x8442f24f8","maxFeePerGas":"0xd6aac8818","maxPriorityFeePerGas":"0x77359400","hash":"0xd2d51764c01e8c0a43fbe362704388df5bacf7e5e620c3864e242530ffb3e828","input":"0x9f8420b300000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x2","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x19","value":"0x470e9f23394000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x155352758fb04a6c0816c3dd9ca16bd6c66c37e2e19f2aa5d969225e3cb7f118","s":"0x6a4a1237db75dac4322fe12aee8b94edf7083ea661d6e93334c667d2d5c2c101","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x535619cf2bd2e84e567bda1a6164f195cb2bba21","gas":"0x55730","gasPrice":"0x83152e5b0","hash":"0x516b0227d9e64eb6e0de6862764d40f5376b5f12fec878436fea3479b4c36bb8","input":"0xa9059cbb00000000000000000000000030509945d2b329cc253a8bb2e2c54bdbb08b1070000000000000000000000000000000000000000000000010ce1d3d8cb3180000","nonce":"0x2176","to":"0x1173069b0e472a64ce2b6203fec8fb25a05b75c2","transactionIndex":"0x1a","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x289ee9948b80fc623b8c5d85c7df6fd25786fcc118163042b77a00560f53c3fb","s":"0x5b0a79e30d05370b27664b2a10cf964e110387bd62098561b6ea6a9dcc4634a"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x339d413ccefd986b1b3647a9cfa9cbbe70a30749","gas":"0x180ac","gasPrice":"0x83152e5af","hash":"0x81b0abc78b82840adb666775b182a9e292f663b64bcd35004c04436ed3c8281c","input":"0x711746e200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000002540be40100000000000000000000000000000000000000000000000000000006d3c514bd0000000000000000000000000000000000000000000000000000000000000010","nonce":"0x2689","to":"0x7cbd185f21bef4d87310d0171ad5f740bc240e26","transactionIndex":"0x1b","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2d","r":"0x1f70a3d0933aab069a55fb2b16a259d21ea5fb3255e2032c5ff194a600ed2ab1","s":"0x3ac2142fc9f2009d68b08855eb5bc85e889e15d043c33bfc516f28ea38715485"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x339d413ccefd986b1b3647a9cfa9cbbe70a30749","gas":"0x180ac","gasPrice":"0x933ea77d8","hash":"0xd0287570d431d2baea96ecc81cb890e7f4f06ab5df02f9b4067768abca19acb5","input":"0x711746e200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000003a09994473bc00000000000000000000000000000000000000000000000000000005672af7e00000000000000000000000000000000000000000000000000000000000000010","nonce":"0x268a","to":"0x7cbd185f21bef4d87310d0171ad5f740bc240e26","transactionIndex":"0x1c","value":"0x0","type":"0x0","chainId":"0x5","v":"0x2e","r":"0x73a68e10ef9726d47ff314cd16d1846a0876d2b63a65014909140de7e45aa8b3","s":"0x580de27e4626139fbad4129a249c7ac2b22e1062659293e5fc3a244fd74907c"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xb5b9345e21f34b6cfa538f49e2b14ad4c3db3f7e","gas":"0x431e0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x76ddab2674369f34946c5fa2f05e2aa8566d86235b83e808e9b27bc106e04ac7","input":"0x9f8420b3000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x38","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x1d","value":"0x1634632a1414000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x4314a4757076c92ca696f14cbe037bcc0178f8b10749418d4535195e90b2cdc9","s":"0x15ee917bc3e27928196ad987b61e3fd35ac92a4200b139d355b30502bff7fceb","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xac2fde165d9f13a223f58b9ac1dde51b63feff2b","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x34a5c74011a2c8a00103bc91bfbfd94aa99cd569be69066e4bf64d188fe8714e","input":"0x","nonce":"0x38","to":"0x7155eba8ef327ac3b36fe59b5e00ab85f735f4f4","transactionIndex":"0x1e","value":"0x1c9f78d2893e40000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x52178c5dce512607a6242f501f78bc894917a482e99a3368caea6bca94c6dd69","s":"0x728be90654231b65f790eba478ccab574e2468fc4e031b712efa88af31fc6592","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x1ddedd674bfacb6587e0c68cee8f2f7d8a71e9d7","gas":"0x1d4c0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x7b9730ead1b9f59b206d0ddea87be9383ba3fc7b496c7863b0cb847889b86617","input":"0x607019b9000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000041971588d95d4d664ac84a45e59fc81871b7051d679376d86cef6b9e1453c762dc33a84a125774319ee47f2a8b8d588da6c8ff7ad84fd9eed22fa124b1a5c5ed4d1b00000000000000000000000000000000000000000000000000000000000000","nonce":"0x1","to":"0xe1e6aef7642b6609e6c54884d1bda4a3cb152461","transactionIndex":"0x1f","value":"0x4380663abb8000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xc0d3e609b2e9f844d300a7784aa9e7cb956415d025cb573a73848f49e4be69e5","s":"0x6ce01527c00c1a93341a541824aed7a1c895f5a0d998f4415cf6d88171c5ad3e","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xf6df8ead0bdabfba61d9b2457d5a5ccec67fb7f3","gas":"0xc836","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x77166ee0409ba86bd26e7c03ad1a927abaf5af8a8a37149e725cd37512091dd6","input":"0x67a5cd06000000000000000000000000fa8449189744799ad2ace7e0ebac8bb7575eff47","nonce":"0xbd","to":"0xccb0f4cf5d3f97f4a55bb5f5ca321c3ed033f244","transactionIndex":"0x20","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x5649e1ff58fa9b6ee27a7316904df02db1ba1c471a2f3409f370a31c6b3d5ec4","s":"0x386b766277e267f8796ba6e92af71a752335bbe45cb3385b9cdcab9ef6c53e41","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xf37cbbc2dad42e8826898d45933afd3a04937e71","gas":"0x112c1","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x3c2b6c2ae505c5c36d5f316c1fcb5f54f7346ed35ae35c93462991ded7968a68","input":"0x095ea7b300000000000000000000000071bcefe9e9fbad3f12f2e6c14ea0cae7f0c91e7900000000000000000000000000000000000000000000000000000004912e6bef","nonce":"0x9","to":"0xb5d86e1f237d52f1f19793d3265e9340394f75b8","transactionIndex":"0x21","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x3ee4d5bfc575fa4b241b4d23e6f099eba5f1e6a20b8cea663c63db6400d01506","s":"0x21481ea7a3e7ad758f2e149829f70f43d67b3cc0d44112cd3744e290a06dd985","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x52b6255b7810d97de8f751737547d1792dff4fe0","gas":"0xece2","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xf99a792837e13827b5e0a8915fb59c760babc95d242feca99a5594e64ff6b6e2","input":"0x095ea7b3000000000000000000000000c92470d7ffa21473611ab6c6e2fcfb8637c8f330ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","nonce":"0x51","to":"0x07865c6e87b9f70255377e024ace6630c1eaa37f","transactionIndex":"0x22","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x5237f7449c0df409c1a4d6cb09005a9224860aa74737debd961e2a24668d1022","s":"0x17e5e842e3f5ffb5a16eca0ec2a92e5b52d43bf9856f97e2083b2e951499b970","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3c70503d83c5a681aab503d724f47fe810ae8205","gas":"0x17eb2","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x522313f5d923f048ae5bd0b5595c1f4fc883bc0b3cf3cb0939d3fcf8b08c829c","input":"0x94d008ef0000000000000000000000003c70503d83c5a681aab503d724f47fe810ae82050000000000000000000000000000000000000000000000000000000316195298000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000","nonce":"0x5","to":"0xb5d86e1f237d52f1f19793d3265e9340394f75b8","transactionIndex":"0x23","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x6741309799fccf0f1359bd710291ec1bb66eed23522d6ed60c5924264d4d283e","s":"0x69c43182ee8a650b0042cdb2352781b23eb1de72f1c3a8903a1a33360e7d9732","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x4da9a48963c158a88bf6d4845a6a1890d20e55ad","gas":"0x431eb","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x471ceb0e85af594aa56deca54cb8198567b2afd8406722ea530077aaa6b641b3","input":"0x9f8420b3000000000000000000000000000000000000000000000000001dd7c1681d00000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x0","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x24","value":"0x1dd87babd44000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xf977ce19da80b7e155ee2d8b7656e5c89004851407bd5370785befe2c89d82f6","s":"0x1d76177407e73d8b73b0909158825ee375a25fa7c18b04884f4be77bb60795a8","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xe40a2cd9efde08fb7664bcdbbdd877c52c4bd228","gas":"0xf4f6","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x3e9dca502e9039ae0c6d642f62e9562ff00010c6bfbb8234a6135712ba70dfda","input":"0xa1ddc5460000000000000000000000000000000000000000000000000000000000000738","nonce":"0xa","to":"0xdef65f8e2f62bde60cd86ad3b4ad7fa6741cf175","transactionIndex":"0x25","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x34df85658956c9eb71549db3a73abca70dd01b8e91284afcd372c1212a36605d","s":"0x5036e2984bb2edbb5fd647bba873f1f5c5ee4845e539c9b0bc70d3d12a4bd93f","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x17299065e99b12b0c8cad06638624cff8d507334","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xc95cac67267f4accb9b5950316ac64772f7d082bed6b712c09cf2da0bdc237b7","input":"0x","nonce":"0x7","to":"0x02647cbb1714fa9a5747ec5be6333e06d806e85a","transactionIndex":"0x26","value":"0x71afd498d0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x82ee5cafbd010cdf7a4604df728d1b8713a5bd26a708f5c92f6b6a55864c9576","s":"0x2b9a70d812123b2ddce1108c4101ddce182f6c83fc8aa0a139ba597aa178b270","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9aef7b879787baf0c2dfe888e67a7edb7a233209","gas":"0x431eb","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xfca28fdbd13fc16daf7aec7d4a2ad2c6b5f0b2a7b0fb1d9167c09b5e115ff26e","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x2","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x27","value":"0x2387acb3784000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x7e5f1a27ea5e652ec8705f80365f1703d2fd50c1de7c22ee0181d556dd2fcc38","s":"0xb22fb8b31dbfff8ad0457ba4b659fb0d7031cd86f08fc3cb78d81c97248034e","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x06006a25e0fe65f0eeaad1f4813940b68db782a7","gas":"0x17ea3","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xc73124ca798b2f7a5df2ea4d568efab2f41b135130ea5cc41d4bcb4b5c57d5bd","input":"0x94d008ef00000000000000000000000006006a25e0fe65f0eeaad1f4813940b68db782a700000000000000000000000000000000000000000000000000000002726bc7f1000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000","nonce":"0x6","to":"0xb5d86e1f237d52f1f19793d3265e9340394f75b8","transactionIndex":"0x28","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xabe4fc843d3a1628a464884c13c21bd21ae9a0a5738d9ae2761ec7cb24b059d0","s":"0x68408d8096e542b2c06cbbecb9494a3778c3ab644e69dde1fac078079c4bcad4","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x2501bf5c8ddf04a60fdd47a95d53d99b315604e2","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x29abb76b5e7a5ce137bf9c22474d386eb58d249f43178d2b2e15c16dfdc5ca80","input":"0x","nonce":"0xa","to":"0x901a4e04f1513443c6efc6ce4e913d1b960ecd20","transactionIndex":"0x29","value":"0x1a3385ff37f0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1a1789d5b19950f45383cb1909cff9128dc2b332e2ea7ba42cfca5806376e3cb","s":"0x617a5a4339503a9c9d08705d98e7a202ed7ede1d1192fd7d98b648c8c102716c","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x507832c92ade971b9a2880427353c6ce6d0ffe53","gas":"0x61a80","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x03e5ab25a58bd44fb9dd0c698b323eab8b8363479dfcbcbb16d0a0bd983880ae","input":"0x85ff842c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000080383847bd75f91c168269aa74004877592f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000557300000000000000000000000000000000000000000000000000000000000000014507832c92ade971b9a2880427353c6ce6d0ffe53000000000000000000000000","nonce":"0x1e7","to":"0x805fe47d1fe7d86496753bb4b36206953c1ae660","transactionIndex":"0x2a","value":"0x214e8348c4f0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xf707322f65ba56c95ced5654efafcf9bfd60a2dd80e74bded3190673cda55d8e","s":"0x46412ec3d2137fcef30f53cc4644769f4da126128979920ed4e209acb1c8ebc9","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xd44c850ce9103d6b2398d4ed9bbce321f3b769c7","gas":"0x1e0cf","gasPrice":"0x82661bff8","maxFeePerGas":"0xde6f782ba","maxPriorityFeePerGas":"0x59682f00","hash":"0x3c8ee80ddea7fa2d2b75e44563c10c10756f598e8ad252a49c5d3e8a5c8e6cbf","input":"0xeb672419000000000000000000000000d44c850ce9103d6b2398d4ed9bbce321f3b769c7000000000000000000000000000000000000000000000000002e2f6e5e14800000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000d44c850ce9103d6b2398d4ed9bbce321f3b769c700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","nonce":"0x9","to":"0x1908e2bf4a88f91e4ef0dc72f02b8ea36bea2319","transactionIndex":"0x2b","value":"0x2e2f6e5e148000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x327a6fbcaa2ac3cfb0ce64b47f6e61de4d18297f1305f23c6bfd42d88e8d068","s":"0x6b3a9b5252ced14b2e2f2833ad7cc62c46fbd0785d57f2747473af3fff7d46b8","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x78aa9046272fec8d51a402681d7c37481db01c6f","gas":"0x431e0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xaffa73b68bc7ab0c3f5e28377f5ca0a5df33c0a485f64dc094b7f6ae23353203","input":"0x9f8420b3000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x36","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x2c","value":"0x1634632a1414000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x925370b51dda3e1d1bc6b86580fda3b40875157ea594a9a14174436c726ad46c","s":"0x516c88bf3cb2f46ca81572140b41e5db2d74c4a736ee7d572b508415c438f779","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x56784e51c2ce28dbe9aa68342638d1e95ea4324b","gas":"0xb72e","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xc66c9c66fbc8fe97fcc16506cde7a58689af1004a18c6171cfe763bcd94f50b2","input":"0x095ea7b3000000000000000000000000805fe47d1fe7d86496753bb4b36206953c1ae66000000000000000000000000000000000000000000000000029a2241af62c0000","nonce":"0x9","to":"0xcc7bb2d219a0fc08033e130629c2b854b7ba9195","transactionIndex":"0x2d","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x407c855bed0fb088e886c3721ee9abee4761221d110512ac29b8fb143c4b34d4","s":"0x1e47aa957d9ebdb564dfa41b72022d525383ffd825a307fbfa9ca13a59994dcc","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x805e39acf2f170251c48a35df16411cfb2f761e3","gas":"0x56a8","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x80fec96707519172b53790610d5800cd09a4243aca9bacfa956c56337d06f820","input":"0x71ec5c05aa669c4922569c1d33f7a81aaa21813800000000000000000000000013a0c5930c028511dc02665e7285134b6d11a5f4000000000000000000000000805e39acf2f170251c48a35df16411cfb2f761e30000000000000000000000000000000000000000000000000000000000000000","nonce":"0xc","to":"0x7c125c1d515b8945841b3d5144a060115c58725f","transactionIndex":"0x2e","value":"0xb1a2bc2ec50000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x8fcf376106af19aac48ecb840ea51df90a5e3ba557eeaad41cd3c8a90785d416","s":"0x4a9e9021ddb5f839bf7f54b54ad52c57b21b6ed285773eea022e3ccae69d1b99","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x4199614bf74f6b3ef47a812d976dd1f57a8f082c","gas":"0x431eb","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x61b33bfcf11214906dcdce7d7ed83ad82f38184c03ded07f7782059d02eeedea","input":"0x9f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40","nonce":"0x6","to":"0xe5e30e7c24e4dfcb281a682562e53154c15d3332","transactionIndex":"0x2f","value":"0x2387acb3784000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x3d295f5fa2dbec04793f07adec57e29c03376c628a0256ee297fb3070a1e3364","s":"0x6f115dd4505bd320bd7460a47bab0c20e6bcb4b3f17c6d0e00e3ff1d936ed2af","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xf6df8ead0bdabfba61d9b2457d5a5ccec67fb7f3","gas":"0xc7c7","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x5d4138d4e28a8327e506cb012346b1b38b65f615a2b991d35cf5d4de244b3e6d","input":"0x67a5cd060000000000000000000000001f1f156e0317167c11aa412e3d1435ea29dc3cce","nonce":"0xbe","to":"0xccb0f4cf5d3f97f4a55bb5f5ca321c3ed033f244","transactionIndex":"0x30","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x47bfb48eb89a8b110749d34d171db36a8ad21c8d7cc78c7489e72f21cd86ba14","s":"0xa525976583b19b3d2c2dd6b34324cf55b1a61595cb53e3c58acaf203f8709e6","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9eda8333e09828571db26576a566668f79f98946","gas":"0x50df20","gasPrice":"0x82661bff8","maxFeePerGas":"0xc8d5e2427","maxPriorityFeePerGas":"0x59682f00","hash":"0x875a142b6dfcf10ffb71a7afe0ce4672c047fc7e162ba0383390516d6334d45d","input":"0xb1dc65a400011a04d404e571ead64b2f08cfae623a0d96b9beb326c20e322001cbbd34470000000000000000000000000000000000000000000000000000000000bd780a7d2e00ee03a29f787096cae99da52d07803c76c13473654239118e2cf0491bcb00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000480000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000077359400000000000000000000000000000000000000000000000000000e50bb6420faa6000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000217f0aee859cd78a5cdf79c68c8de4342658d52ccc6420181b5fcb7c657c5fdfa5ca2c8f2dd7e6e5799d44d6818e6dd8fee19b2530bed2045e0c665041f053fe70000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000840235df8360bffc902a68675311f5eaa79ea2c25e2cc394bff0a43d5d608e98c97de200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000493e00000000000000000000000000000000000000000000000000000000000840235df8360bffc902a68675311f5eaa79ea2c25e2cc394bff0a43d5d608e98c97de200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000007080000000000000000000000000000000000000000000000000000000000061a800000000000000000000000000000000000000000000000000000000000000003312d88cdb7cfd5fc5458d9a424da374cd818847f87fc4fb6eae2c3b97e541a6b81e108e55daf857b71514fb7213db7ba15bd6adc12253afc3c5e949144c13696faabe22d1b7ace91532134a5cc65bed9afdd897d6f84ad1b0b6da463bda8fde5000000000000000000000000000000000000000000000000000000000000000352c2a75f88112864819de485c392c349f718fc257934181c4d8ac8eb3a9b1fdd3b7bfb96496290f2b41fcd20fc8d29bd8e29be38550775dc97d21b17c2d679ad05f519787eb2c92a9a897c9f02f15316865cfeb4bcc2c0ba5ac2dc4aaab5c0c9","nonce":"0x3705a","to":"0x233a95ccebf3c9f934482c637c08b4015cdd6ddd","transactionIndex":"0x31","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x7e9247209bede2c21548c6e4f26e41d2636a2490e09ad062f9235e978094073d","s":"0x288d820793b48e55777e794f1694b1605d74dc8726fff438b481125f219eaec","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x6df2b54f23ed4e95235c6e21ada2cfff5a2615a6","gas":"0x5208","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x79b6df832bfbd04085d0b005a6e3ad8f00fc8717eed59280aa8107268b71e7e0","input":"0x","nonce":"0x17f","to":"0x6143d939b2d117f4b998d8d88a56eb0e0a1e9c31","transactionIndex":"0x32","value":"0x186cc6acd4b0000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xcb641be908976bc0a035b0b31a96039da9e63e829e0a24a092ecfbce7724b9c7","s":"0x4034e7dc4001cf9f62a2e5dc4390229655b85e9aac5a5b263278e9d2cb43abb2","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3f5ceedd435b6143eba2254811a39fc3423f18dd","gas":"0x186a0","gasPrice":"0x82661bff8","maxFeePerGas":"0xaa246a58c","maxPriorityFeePerGas":"0x59682f00","hash":"0xcb2fb25d268f65dc9312e89bd3c328c9847a3c9da282026793c54a745f825ab5","input":"0xe9e05c420000000000000000000000003f5ceedd435b6143eba2254811a39fc3423f18dd000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","to":"0xe93c8cd0d409341205a592f8c4ac1a5fe5585cfa","transactionIndex":"0x33","value":"0x1c6bf526340000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xa48a4ece6fbe881e342a4eda767c82097c3bd47dc70c09ef6a4e7f90c0f8e843","s":"0x66c92f16907488d115f5088ed8ff4d71c966232458479245bf6dae45358c0429","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xdb4f0eeb7c89b00118cc74de8c9ed55d65c2b933","gas":"0xb72e","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0xe483d4a36ad19fd5eacb7f6d9ad3ce080ad70ac673273e710f6e3d5acbc6559c","input":"0x095ea7b3000000000000000000000000805fe47d1fe7d86496753bb4b36206953c1ae66000000000000000000000000000000000000000000000000029a2241af62c0000","nonce":"0x120","to":"0xcc7bb2d219a0fc08033e130629c2b854b7ba9195","transactionIndex":"0x34","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x6d73169394cb6a9bceb2dcb16aacd261705096f50f30ffe146a09659e25dae48","s":"0x496a1cccf01ad2ae7094b8da2ce50c0a990baba6300625c48ca12c5f20005a64","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9ac253db14a434cbe7653a99c5039648fa4f7353","gas":"0xb4f8","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x0564242c37d5013b671ef4864394cc0f3924c589f8aad64118223a9af2f164f6","input":"0x095ea7b300000000000000000000000028ac7dbbf9ed6ece39a902e76780fba60f1b2e3b000000000000000000000000000000000000000c9f2c9cd04674edea40000000","nonce":"0x4a","to":"0x0dece1605795461158538302b5f0936afe78c4db","transactionIndex":"0x35","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x15684c9697dcc8d89abe562c4315bfb959938fe7644c00615d9e147a4e496ff6","s":"0x7c58abea24e1fa8caeb73a70219b0d63007785c39694fe5ed2a5a342c99292a6","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x22496eece162f52d185c07524d452b9506e9fe12","gas":"0x186a0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x48db358e80b278c3a46c2a166339797060a40f33984a5d974992cd9722139d5d","input":"0xe9e05c4200000000000000000000000022496eece162f52d185c07524d452b9506e9fe12000000000000000000000000000000000000000000000000001c6bf52634000000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","to":"0xe93c8cd0d409341205a592f8c4ac1a5fe5585cfa","transactionIndex":"0x36","value":"0x1c6bf526340000","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0xa50e6ea1eff21fd33d69f8c74b90c28303b92ebc4a77c71b65c4c8bf3e92ac8c","s":"0x29af3bce2365578b76dc528917b44e96e4fe2e7a8f948eff3e379721f35664d8","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9ce3f4210dc06889ad5267ef0ce3ded4bd96dc50","gas":"0x249f0","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x69d7758db91fae31fa35ecbed4d40897c5087f45dc796cd796b8ceead21f972e","input":"0x47e7ef2400000000000000000000000089f01bc9865324583380d8d7ed08b8046bffd7fd0000000000000000000000000000000000000000000000000de0b6b3a7640000","nonce":"0x1c","to":"0x6cf3df5d00e842aab1eb504bcf01ebf81646f7b7","transactionIndex":"0x37","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xeefc19e8dca874308c84712c3e48c032a25971a0f7dff16dc47633ba7a4f5b96","s":"0xc0994cf21d29cb0c5f1e666538b58d6dff3b9ba2aa7545337da732c4b5938cc","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xbd1c4e36842c06e53b378eca310cd2dc79a78cbe","gas":"0x35965","gasPrice":"0x82661bff8","maxFeePerGas":"0x97f5c211e","maxPriorityFeePerGas":"0x59682f00","hash":"0x2951478916ecd27a8e808d08f85be4bf2c0b0e0546f21f4e309145dd96eb8df1","input":"0xab7d7969102507275d685f3f55d10ee45f7b9fa39c29a8a604a7a971c05eee739e63938500000000000000000000000000000000000000000000000000000000641cfd18","nonce":"0x252","to":"0x96e6192eeaf7bb308f79fb5017a9085754b9e12a","transactionIndex":"0x38","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x87fcffa38e0c84cf80fb37ac1e538faeca21462b0a9ec25af0ca0517af22789a","s":"0x72cffece99e79edb7425a9d660590fbc395cdd0db8fd4848074c85f814b3cf63","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x5dbcb3e489fbef1656dbbd7bc4848ed0e520a089","gas":"0x7a120","gasPrice":"0x82661bff8","maxFeePerGas":"0xc8d5e2427","maxPriorityFeePerGas":"0x59682f00","hash":"0xaca9028cb5d55bbf71b7bff9884a9a3b0b38a575ffc8f8807ce345cf8bd298ef","input":"0xc9807539000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a7a9d91e687decaa6b045797c2e002d70001b48f03020003010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000002361273ef6f000000000000000000000000000000000000000000000000000002368a4faa14000000000000000000000000000000000000000000000000000002368a4faa1400000000000000000000000000000000000000000000000000000237b9042149000000000000000000000000000000000000000000000000000000000000000288e1b54f6e54124deb78bdb67cbfd0bf63612da12868fc281afc34bb26200a1771f9e00fce297da11cf49427becf350d0bd20a2277439fbb2e8db0fbb5e3d34700000000000000000000000000000000000000000000000000000000000000027d16a90ad0e1f8d924255e6380764fa7c7d46427c8e8ea19f5ba6a9d595297a340f141f74e705d0fe851d7564eba89fcde574deb5975d9126867cd927a0d92cc","nonce":"0x11d38","to":"0xbe57bac491de9a260abb6ba2c9ad4c5d2eaea09a","transactionIndex":"0x39","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1eba7bf95bf63d02b74d20554af050eedd78ecfbe1a42ec70badb36ccfae4bfd","s":"0x4d7f8d0ac2be28e59374453f24ae6506a81707cc57f0d1c6877b49b3949a9a79","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x3079be9d8622173f02618ba2b793f00795d4f320","gas":"0xf848e","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xd9a8cbe9a","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0xc7f625a19ee41a1750eac9428b4394a9a2476b8ea2d31b4c2f9f5b4fcb86cae3","input":"0x2169f79f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000fdce50000000000000000000000000000000000000000000000000000000000003f2000000000000000000000000000000000000000000000000000000000000001f579a43ce4f3e38c6a948f1ef3bf7954c2059b087b18fdb22c7b69d61727a5d2aa16090b4d1f3281bce660a31d3e2789eeb360192a54e3ac3513c5c8f67b7346fda957c92c1a2981bc68a47d0282e78df2fb63822f06f410e1ffbee7eb83c425122be9be94d817e2e42099632fb9eb5ce7c414cf6ce48e4ed2e64e46e1558ca809742159e841e3de803a8cdc628f7877bfa6d75af4b4ebb185e6d0670ce83332478137fec243a38c0a80d067c955cbe13103294dadfc8c356d0e7996cb62fb2c683e6dd5ad58be934f57375920142990074f8a161ad2390a1e6bea9fc3a58dc3f7e002e9952a68bff229437d3fb4cc1cd8097032b22c884868253d8f2f69c75ada0fbe1dd57145610ae5f451b47645718aca7432d8cd3193d0b96417df6638fd47062a1cb1f63636236fb72195e5a46d1b37f493b8380315e5bb1a6fe67cc6546d62f2c73aad5699e6ffa0d49ce653bcefa173fe0de7b4328aad75f74d15f4f570a1839514550d576e21b8d16c8355b770442f0740e6e5e77ab450ee1fadff8daeeb25a91585192fcd3cdd64dcb6a35e41ff47e854337ebd0923ce280cdacff2ced48eac96bc9f910391a44cfec243a8660ff80c10ff844ea22411953e0387f87d2c2ae81055fc8e87d59e04cd7a923d6aa5204b3eaaf5b842b5fd656e9fda16c59e90c64ef51124fb32f8e63442b1f79d3ba3c0cd5fb90895103719629857d5999b44aad2d69380f48dd824795a89dce14bb82600701ad8fa9bbb36fe93a97d75da26ffcb1a8828918e0293680ecb12e1b772fd98637a7a83cffbca1a994fc889ed0c0b20d447ff727b9f5dcb9a83e1aae9a3518dfe1d7ddab1da48310eaa7ab293d85dd9ca811bfdfee990459fa044c9a9fa6460e5ff7612e42021f16854d790710684663bb6a10ba475fa602b02519f03eb544fe486d9cdde47ab7d4027bfb8f29d778b3a7cc35a9f78dbb05943062efe3b388f1a8c496682a0215265b99fed0363a1061556a40e0539a6656b6cf8967c8fb3092a7fc9b56af124c8f1bd0abbb9af753884b22b333410d47d80c083c9fee52dda8907be0c87c5496f1fe9ac4bf4dd4f06d6ac0ac0cde22138b67bf782e8e9b5c991d58a2a828b4c68620e6d3d26abf8d41005a00866cb4095518b2711636f2fac3b5e26403ef96f5b1765519787ed74c6802b445de029d7bc696aeef5a2e605376aeda4f495c29af66e357c6e1232d7a2c3f22c0bae0c62372d6b2690e503804e2ad314c38a4ffc080d36213458f606075d32dc0a365087616e94a972bf76d7e5eb4a53292fd0d7570cb6fbb4540b3c5ee6deee0f257fe8703d5d8d0180d09754bd9a05894e77318b8c8fb6b4a56999bfc6c405c09d9ce7fe424812db5bf778d7d8634b2f44ad6d00f18615e4c3695d9c5965ba51991508405187275840a3f27cb3101a9742c49edf42dea79ae5418ada42dfe2042f931af15a205e64196b04ef53492a450423c2b63dc849ef72a166fac5f36b25c72d9cb4a2507d5ad15094a979b4ac4ff8eb4c90f448a81fc6dbfcf6a228675ab3308bca37bda8eda22b61ec7e596f2448ee6b7cb6eef589f43f28fc5444d1da3f82ddbe574b774719a3a7869e897e642735517832959ea9cb9164eb2f7665bca1d2e44e1093acc7088271f2be20459c383f5762303b553af1ccfb3371e4eef1f102ce70d62620c5164972facbfbe03b5018265ed62c4c3cc49522166913517e2f2718edb591047a72e818f07c645a18aed87c0384d180dc0bb7fe63bd335b1c09e58571b92e2267ffa5712a33e4a92231d9da7b005730f6d6559ee685edad9a9031c4708c8642c297287af3a3e637d9b5ac6b23218977cf4d30231a79063987f98313a2bc0ca4a73a97e441a45b58cdd8731fc269255b415a9d2ef2bb8a311587f39f6dc82f537cf86a68af19a68c409910f4dbebdfa66445361877a3bf551480d115d8768e8650e9979472a64802da3625cdbddee8f02678a3cc6400824d91b3c7d4c9274b74fb11a9538f1990fc314d35564a0cb0b384590e15cb93db1de1a837b9319828b3fd6b76f1d2bca4ac765f9ec4366905f2dca69a4c8c194cf0a5d821c58bd291e8dd4ddd829a873d093042c1b8e1bb2bb1a95e150c0a0d5c3369c4a791dfcfbc3e631da3d1e704214c3cf8318901f9c58465be78a870a040f34c567c27eb077db2d1ff825a127a038eb14c2890ff9a8a1dc8d6360a91fd788fec97599a318ab03f69bd50a5ece92d96c49413b517579ececf71371b6b1d902b1dbbf40c728c64fadf368582cc4b3c51712c8d6441c0c61802943624e93f9de9eedde87056c21ecf66b3a6977af0261ef48b4c6191ca7ea70d6acc5af910ebf247e2a4429c506c6a41f865175a9bfc81dbb69e59ec2c47370fcee9169b8749c852e7a1275c1278aa3f88bc16d311e58aa9a579ed7bed62f12b4c4dfe9c493cf33f979f667eda043c2aaaf863a747b208f3aa2ccc34f07b12d89bfd75b696a82c493e7eedcdc41eb01321ecfdcb691d14996c3ed7487b5f831436bb7c25876c4149cb6222dbee9e1a05771a8abfd0fd530266476e1bf69d9a15e99c901243585f56a77ef0e6c684a4d49417133ebb91f896176ec3a8f0b966eaffce96f129d18960fdbf5917f8aa0926d52c57192f99e55959369e57ce85ae84ad944e40652f6a81ab8da1dbe81a827366b8b8d2ffb9c7b93087f7a356a16d0022ee8ae891060e29ff11f9f17b01f39b8024baefc8b928a6816309a5c3fc92ed6007499353b5f1bc5700d5fe67f3e34ef3654712b9c67c231f30dff485213b94c20afaa91540560df80ba9ff1cc0f6ea75bf1dac0566551050873c112478f3fce6af162397161e1b41e1ca295f327a4f0ccf4d15fbe58e20a23698bdc25c751d020df371cd1fc59fa51dbf7ad619d208d7084c5752984b5fd0e3a7978f2c11e6b26531fe03c0cb85519483d668bf1dc4dce24509b00aa6e146adb49f31c2c937a2d3a08f1cc0b73cd66f2cb926f0453cf78618e39cbfccd6e6a3b4909d6874872eefed0e395ac2582d8c1d0483007fa6ed7b735323fe8fa1c4be83c725c6b743f63cbd0d6017f1145634b0b905552a2a237561b37c415146d0555a276b4b45d515ed7dab942f9bf40a26d5366032f23fc5fad8b98a1625a841c8cc97dfe0e2074a363a951946df16d1261ef6b2da7f5789dada153448b076637f9d2e04f4390e9dd32fd5e9ab3f5939807bb451bd19d962403da9dd118f1cfa91731973bc721e5ae4a687bb2270e3e76966dd2156e95796d4bfa6b4c10caaee46e1d8f8495f901cfc241c6f9a690349eb0752adb220996ebb95ed26ef376dbb9eea201906a6a3eb346c64eba3c9e4d1b3088baa0ed868cdaf063a4c2434b9d1bbbd69f44ef659262fad9535988ce729aadafcfc6c3ff741dbf8b784b3465fb05f6d5daec91e915f89117e01c9b0c99d7b7cb78e44f5c28de0d3b782de981be058ffa1294072c4e5a66d2d81641d1c07a9a04012f9f1ad15028709fba761a659becf01963de0cc42b0e16bc5432cffa00722a84628373198dbbe75f209115c4e30e60297c2d737996dd9aac330f4a3e82609dd33460438026ae287c172af8aeed0d6c71b1f9470d60588ebd365f20d596999d97c7a6f265890c719dfe43ae1ee5bba122d9d4cfc96b399f610a90606add4f0d25b903c7ddf6eb7bfdc3b9f926243108f591678b0e92a48d52b1dbcdf30ef8af74cfe34d48d0e02d0f99af2adb090c489d4214f3562d3f6a6e9b83b54bb6cfe6c1961ecd2eb2b7eda63601c835c5dc696b32bc495bda9b6567984f83e79a9d4ee88b140dc78cdb64a2ba8761a827cdc8d2b27e690c22402178ade602f2e9092a1b07d56d142bd24d665d7b10bc7646eb6d6823d5622f1fb08f2e48b8deda6cde324d6508fc428e3bf1a9ed608c196786db4e8d6b7271a07e4f73d9ef76244e3e10aa13fd9b82ce2ce72af2df7faaecaf95d885e64bcae16f9b59ab8e0f21a2f459d00a290b0dc57e10bf21ce06a029224ae15cb86bb1cf060ddccb1f6ae82d767eb077fa4ab0f37d02a4bede5d3f8ee3972a6a3a438a3cd92ffd6c1fb11cf2c68c2c6d1efff62b9f769e302f6c5eec96b0c05a942321ef8b9cf0ff2bb80073a8fe138bac5bd8e93f3b27e7ec7a78512059fa37b0b6939f3b1311cb6ea154909e9d316567e013df315e8f02a80e17feb8f3248cc3f11d1253ef3156d7f12d1f6d7a382d6b6ac6abd38fdb5d954e13ce005ce16bd5625a5df01883409f4ab938a59a75b7a816af6a2447b2c65ea55c0ec4e4f23fde145a26ef0b13b740b352809c10b54bfdf30592a8b0d507cb8210391d66d6f68d06f3a4663756697d472adb6ba78976b423ad9ccb3a3bead9de51e324fb77609729c78664f4d37c7c748ad9fad95af355be4f00a76cd5cc2c0b6170fdf3efaa2571bc8fc2d0d24682fec5e034460de55cd0426b8ad448551032e1f6ade6d96682bc38a92c296e5bdbf42fcf106d14c5e8a4acbfc0cc1f0bd6877c4469be8b204ffd5d7c0ee85e7b3265011ad5e4896f9f8a69997e321a797549cd3c1cbb0301ff30c3a136068ba37b2176e556b574a542db90250eca38f3b0e418e352b5728206d6d531ea253d781d771ad974b476a045ff14718d9a1820fb469e981c7b71ae8fe423b0a04278bcfc967ca602254de37751127fe3716456df3fae50ed508e529c2181d63479b6464bfcde6629e8179f8d5fa5b61003edfc2f129affa58608d6145de98ca8f1c0b3b9b5ae996a7fbc6326a9ac2880206fbeb1c99d0448cd1ac5f275b84e4be03258f9fd0d3f44a692513957fa083a462086787315e38aec8c09b96cca034cc6294359fe00285c607d41fb4e3bf25760ed1ef0802bcc40b2fce2cfe1c64f7c34b21d0bb1f5210360079ca8638ab42943b0ab8277f1cfb1e529073d2068a36a4d8ae8179c32bf66ca335d698f76db1cfe5236e6427e01804464c1ed4facf18ae09148c5a0cc9ebcf6fb6c7d03ec6782b7595816245ac2d1fdb3184ea49800d5d0f1dd880ff99d6016549d63ba2a44ab96f0db0d0cbd5fd4f67af1f1da0b1023883d4b2e7cb23cf85c617c180a771267fe63c70f19eee28fdc50c57d73b2718f8001383135b859f4c2fa3b9a12d095beba8857df13e921d9dcda5b87e1fce6038fc2f92282c717305157b6fca5ca2c23cb7307a093512f985628e75326e0bca2c4dc5ed44bed8e0cbce1238f4023089a81bf62b04a31539de9c8a0c867b791c18a34abcc721c0e90a1604e8d2855e78673367ce463307f6036850b81e0aadc9f81d8c9ad6e3b81d7850d4a46bd6772e651e03581a7a55568c9d63c1b1e8ca947174d68afcae6401b75dc7397be3c0dd76ad1827424f9ea9de8ac99803641535dae3eb57ee1eb1e2c193bf66addd488da55055bcf93172b1966364db4412e44bde64c50f7692a38d1536683af14fa057569cc7ef11f614a58995ade1b12f979005a53bee0769847deceab4f58f3d062767f7ac0511a04fea349e7688ab26425cfc369127325ab7fd24d73c4a8b23f099892b3bf52f35f0d775ba753098611ce35c56873a7455737a42672747bcfa99da8c8d0f06d8754d2babe3eb303cb06ce69e4046541ce63b6c28ded5a6fbf729200060132e9b01d8646b512356c92d8a642de0f62d169b195cc2e7ea2efebe550b1cddb5df7668a0d1f94a2f5cdf7897e46cb03b958ad906393c7d252b58493ce6c7d813c8fdfd5ef577a9e778c64d48c21b130c4f6a57985b8122f3cb69de015081cd3e247de65643f9d863fac6935cffb2ca23083d4fca9b8707679d9d4c3cb34d05d092334b1740ccf4b2aeae724902ad4fb4bceaa642b3ffdd5b564d7bfb725fae91f5c7ab9583abc2d80afd2272b14ec6fafbc51e35bebecce63bd95fa3f39e4e689034c47628345c4d8e30a73c36d87d289b6ec715a2769efacf39c9f19eefdb311b9800377c5c61aadeac78dba6946da4e7914415eced875b66f10b96ec98f64e58320bff09e8ac4f5969608171dbd4ab5883548a289b52d55aa82da62ba3d9fa59734d8f810bc1a40a0e3b2e116873116fdd8bad95471f16a14054fe247637febb6081d00e7ded3019ec03f76ebef5401a27f380fbe8a55bb4a0014f61276d9aa5626a34e7fe5a129a75ff130ccfd78cfbde65416882ce9ae9da57a3a04c67d22d3a12e811b2578fce5f6a64a09a86782bc15e5872e546dcca46bd9ccce5b787d17c70d6b075bf4c789ca184dedad3485a0526a61d280dcecd984fcb7ec663f8f491e91253675877987433e11b9cfcb5940a1357b55fcc5f977fc898f72e8199ed5d8d2554d54a55d6b4b3726e7fd7093996e271e218533f3b31257aa989f5efbdb12dce02d18a5188ec32c3c1c91845a17011ffede3f060f19d59b6565a352e90c5ca30eb252c6fb0cc845833e553f0bbe1822b5d6b26eb817608799b5b77c2cce27beb151060261f34ea73db94bb2fee11864aff76da5b10b17aba6634ae655dd396fd7e7155013fe3c6f840ab1ba9b25489c67f6bd5967a62134b238c325986c87aa005396c54af6357ca88baf5a03e353c8b0175386157d9221833585921d581f1fd3f5d9932b24d41895a5c35be91b35643e7091a7585ede900853aebc260b1fbe8b72d527390ddf46472f7c8d5844355ffc0b731dd5e584e13d65f2347131ba8a5161a6749458c1899b60cf9f9f8810889fc23b5d0fe2c843fb5675cfac6dc8ec8125d1c582186eac82d5e0b3f6df2a83eb2fc23c4c3f873267deb5ea86dcf1e3c5bb39df23f06560609b9fbd89511281fc7d69fb19764c41168a539b44f0603a52577c266fd601c0cc849b067746b4da78d280385ef80a3a553dabe4b137c50152f4e1de456d43e015e26f7d76e612b7be29b9f8e15c6a73653f5f7dc28aa245e64f076130bad58bbbd3b024c97e267a96365f019846d965c037116c74ef18415ed5500f12a1816997895f3bbe7b0fa1eb12a565255a64d5eceb2272027e45ecb0a1a8b5dc99128c002058c569076371703e1f10368c6cfb830ae8bc688eb143da7a1780dbe29cc4c83743b25d570f5d8609df46c807edbbc96358cde9ed0d9b8936271b3ade28001a6bfa6ff7ffeb4e6a6687e803b5e8f67b82e6dff215ee4f2caee571b8febeeff368a89539d145842526fef110174ba3a2d9f1b4a348dd25dd964efcf88847d3eef1c18fde81ce84b80cca8588bc1fbf9c9f34059808d3eef3fc2cef7636f7a76c533933b79a9dd2ae2791d1ab5e1e715837a766d9df1947d5986c21808eac758461596870b744a6a2862f7f5bff0c7a3460875b3b326e45fcec1cdad1cb4b99085748d69a62320f7e6c53c061a55ae20368a4e6cfc126cf2c0b410af545f169fcc741cfcec4947f577a1bfad47b5080ecb41760b5056a9bd10a10ca43677de0e06bf36b0d2bf7ca605b9217240871ed1ce43bbd07a7e77d1901dde15e173ca344ee8078ff115e954a2fa660bd4af61ac32256fa7d62af17a4f95adbdcd09b933fa47828d91a6b710a5c67195797bc789647db90107fb527b8ccbc1200bac302dc47a366d170314f5fd7b60535130d76832ab7a06ebcd83d064c1a1c5a7386b0945d39f8ddfc3503415ea22514a0ebd0ad74e3ece5508d83355cba944b12b669d6355a6143921533190eaeda0337a1b89ff9db0cae62a239025bef078137362db71a9eaa6d0a26fcda7e80a9b8fa4a1799819f0489b899cba4048c999fda79e0bb046d7e765d9abb445279efd13d47fde8b731a944af92da8d8965bc4e90d9da8ba0a9c385357e16788cfb663573d9d34810c754e86e3293a868461b241d7872911e676e73136557db1261573962221589850fa5ce049d2356e6630a142427a2cb2efecfed09445edd112323f0071f63f6a42035a9248efe155aae056db25b8004204d530d27027c34eb6937a5a05bd2096eeb1fa266a0325cbc7ac03270b751013b53429aa2d8da2de8c12e7d4996b5f1dd365e270285d2f3a65bdeea9346d960ecf015215a88f465a66417d12d95be2c0bb3d8e15163e0dc66028a30f1f5506558ef534ab28cf6dc2b7d12f49b0e319995efbde71978ef7121df58bbd16be908298b0abb6197bec22c598413283e7893f0fa7398369b83d30b29560ad09a0a24e029d0c22a7cc6fe53d84a7b2104681df35cf4c3ffd90b14cacb2ebbb673ddbbba291feae96498b30d024398676107d3efdce47353a544c9d885cd5cae19588a4b9e29c700c539bbcc119926e3d1adcbf4e8fa3dfb0d5c2686a3fb4ae7b4b278fd94db5efcad7f280488702d9f7675aafd248960806df3e8f95325298968a8e7bf54cd2797decb5bbea7bd3cbe34081c0b65ca9a4d0d08d86ff39f97751471e09f25b486dddfb2975edd51ec77d949862dd4a658ec974b8a5a381ca5b7314b677c4491e07b43a5a9964d95e1a29fc1d87cbf1a64296f4cbd8128ab13dcb60dfa8593a575140f5a9fa6a3708052b3bbed4b129aea88e66b72e583f1fc285ed6f835df0d4751c5d5f004ee0c65203ba9fbd8ff70fc255e497748f24c476d18c94089bcab8ae3f933563c6682e5452da8f760943c7efa631b2980e6589ad4ee83c88fe0b2ed9900571c3df6bac839df1a6d9d281a5ff627d41ada13b867735aa7377386182b1b113f237c14b6d806079d2f7c234a7cb585e12a5b16f7064fccff99386d58f91d9c235eef730660a02ad37dcfb0352b1da76d739ba7bd4982cbb8be48494acab84451bb39bc59521c9873ec9f53cedb527332c47afd919c94d777e603b405e8563248c9ca72f3b2fb52f08a876778d18e7d179f6437b64f79ca01f6be06d7b115b8d3c3320c2dc0ac59c860aca8c92407ca2239998613f44945bbe2c6a0ef0890ceb27467d1ab805ec960e6e58e49678a0841823632f62c58f540f19e82bf719e12bdc63db5363fc0749877539865a05786106b58dcf50bbdd015893b043b21bc1f24ef9eee5f2487d986db13c143d3366260ade522ab824fe82218daafe5e42c50ef740cb9ac570a13cb55fc30c9017228f2c60680f75ca89affdd376ce70ca5223078a47da0aab9bd18333c14aa021e6c088609d7a2460744006f149b648116152e7c814a5730bedeb6ebb59fe395e6b15d379909f197c4703dff34f8915b26a36e30088cb227fc1df108560fce419f462181e468b5d94251fe1373e0dd004fad02d690f8f28bd972e85ec49485cfcdba717db66e6a343044a2453ceb6403fa0795485f8014225d283da4c3aa6fcbbbdd6b04c30c96fce04579578882a44fe7b781285daa11ee71239c1b69791b8fe45868fe6e85341b7ba4292d6da1ae079875b33d7aa2becb02327a17bf2d09f6a42e9681df41890f17de5cf4752880660a35dab912d10480f20f92589d52ef4780ec28920d11de0de06bf63d61829a3d0894f9a32f911ac79041ef51fbcdf3f5b03f6a0b16f0b9e47444b82efa7c012e3bb9324c8649053433306d0640ae953737336cebe9b854186f9dbfda861fd7eedd76fc24634acb9cb925302d0bfd3751b7b6bab36ebe2ea80cb7c5359a505689ed5642118ce93cd783c80a2cf050f57d5acb62853367ac606fc1b8a01abb7b29e49fdb190e2b586e249639889bcf5ad23161f278086f244d0db0f9ff520e6858b68f5bfa0f5ca700096277ddfbcd14a4cf4358c0f042b1eb34bca6353a1383f5d310176262ba45512ea4f172f321efe971c391fa9e9876a250ab653fd6d5a8b046028018ae043da256b78eb26d86e6e89873476ae24dad26ec1d39da44ffdcd93d8c5c1fe0796bd46dbe9b01be0aeae841662c10ea28cbfbef76f0197cee86dd4c7dae3ba46d5c2884ae977c456681d5d9859d854a3e0708bc35fd8415c22ef4cb889bf0e66da72ebc635b71f5df04db801c76564d2fbd946ac17e27fbf995994ad26c3d577ac86b3b19f855d87bf3f0f7c3fd574b89901732dfacf2e13960975176f7418893b31747d96bd981e9b1463590bd35b51b7a2eacf1a7733f76a7d4b02fa2afc5925f5483f82cb529682f785c21cb951d5678a7d09f99c0e2bd98948b79456e4e0b5d9de80943f1df0c639ab8acd6c99a6297cc5a53a829561a6615c6c44b24a30a75174aac207a35fc429e1a415b0813857ed85ab49db6e523cdf9b122c2442a4fc2b4fc21685c9c4a5de8f36c0b405e34ddee91832cc6567d458ab76b4650020d270a65a562e75e06a3d8f1313b4d1d4d29d597bae9eee653bf8e31b82f9cad2d0848ed5daff73d99472c7e71d2f1be60bca4ee9d315196c096cd8260192597c8ce3cefa9cb6f129dcfbcbd65b5b0e19df5a1e81bdd423a2e26d11ca4f7aee99104530c1c8e3b1150669f16acf415559a38cb27eb6d637c78b1c90ddb5eef14ab9b2ff14ddababd7a349b7f6f5b6caa3a28c45835c9beaf8f836848f579598ae80ff9af739cdd800c5a3d7675c780ad66b2c449824d8ccf55a7669fb720604eeab427a0308122c3039ef9be6df46e34b719aca7a001b884e3f7b1d1579176aa4d365a25b6f3d420190e3cd9babefd8382b6bb12b4c38b981b08b5a139cd46e9382c01f361abdac7fb16b87e2c61f3241191028c770c3e3be939c8825c63bc4e523b389d1ee28189b5a2c11ccbe0aa7d3c2b47443028c89f3d4bc1bcac39eb61d91e75e0d372b9f27c8dc622a86bc0cc0a9c9dafa5e2bc67834a75805f3bf1571fbc5528e4c69f3e64ed27c1f2d93f43215ea0d4213bf2809391b8b9201f36ee2a275dc7c44d0d83de3b82490b65d2b399a7348133c4df7ef40e6dcc114d040f65de00a70cc0c9fe615c6fa90a2fad6dbcb39370af043345ebd9d8af094c831f341fa5f7658c2c1ea062948fef5015696eddd181d87dea49ac8bbcc2c7a1ea01ba1d04239153ca401bdc27aa87093a78b2020109d7cbdd39f279a7d67b14a5822fae28854323a2620033a5fcf9817a0d45eca7e2d120a113fd5ccd9fc0011e89398767f7f6b7d01d5a670b4fcb9c5648991817a62edf43d6964de204541a8b5573d7cc10bacaa1bb835f87d12985ad5fc6ac4834ce76c76e5dc34cc322c4220d9d65ca77051e7c1d4edcfb4595db16c641fa445401c72a24e36567631ea02e4875b7f9ac2ddb4712b79d1468c7ed2384ad5d90ea0825f817e42413de33eb30861ac92e19b1aada118beaddb179399008137f28a8f3df1509ab12d6f6ce7872521f5cfe4738722fdb410b3824f139ccf8ea63817d154b1e497a70e6f55b75e4decb73d10ddb0c57d7e0f74b3f4fb41ee57c2da1e4399c2577f28b7e911db08e877c366f231114cc9553c7f3cda2b75895fb60ce9eef4e0c25d253f689dff5e4f9cdc744c301b6f13e9fa9e30bdba8abc203c05879ff01bf8c3a3aa742ea5fffabbd6d165e50bc412bf5e18c60bbdd4fdb276f3bbfef246cfe36612ad61fcbd4498c18321a1ee12e6dee902c737999f9c6b3919f52125cc77e237a788640f262ab76d5c9db9ceb2d988c261dca63455658293b10842ee0b30cc1f928215e0308cf258ee39ba666b16319d0e21df8b9ed91be2e2feb9e117682cdc9edbc20b0b3b9ddaa93ec7a2d8f752ebaae57b7d74037c5cd64cb04746a38c0ea3ba3241319360e585c257fb593c123a653e6e0420fc540bcc0f072de6ae1a31b57dd5acf0b8607e04d21b727c93623e5227202a7c6432b308f74266dd1e1447a2d637a5259fdcd1d8729f341a7dc383b4c8a6ae0e78c34a55793043d2dddbbca1d161c300a8a7cb760298541c90a1c5a890b5257369b8fea0b4d14dc0848e644953cfd5196494e4c1b422f8e188314f2fa903fe93393193e9b76bb71c0caddba43d8586d72657a2d717e4b2c3a0e8bc33a6f8d89b871244eb04e4ecee26f9b71ae7d5c44f828083b0c1920d37cb5d7db86be3b18ef16653863762939cd1ab5c5e0cd1c495ebd0a3037725470d526bf12d21c2fbf4946ec224619c79906e8c87f0699be8a3621ae718aa232e26e43bf7cace7918ce34577a5e27261a4a6bdbbb8ac21a8a40b0c9682a0e0a37b7fc43306820b0db5fb5bbeed529102187fc3e5019185588d1ca6222a5e2b60faa2a93857bd7224e1e1c3c86128fd16993aaacaa34d8679e194ac0da6bf617144a2b1e844e7f6f8884df05ce1624ef1fe5d0895265bef2de61d637a74f78f6e3402923c9363656b7b91131dfc8f8f7360d14e01a25869f0f15a9355c07bba82e4969f5643519611d99ee9566138e4610712d55f22ad36c7acdc9e32b4e1e9b1ee9bd14ca122db05938840b8f47a5fd25a26072e2055494eb4ba916473e973c1efcef8dd7f0f04711b7e968d59d144fc04b9c6d8f951ab973441a6086ab6ab896f4d282793fb14c74322c7ff1c4c1c6d0544b7457635a6fe2632644344b1fabe12633b2f7d8fcb6e0929a05aeb2749fbc99671283c47c0eabe152fb6215bbc6e03d61b1ae955838a8b7b3bfa883a04f5156982ba433dcb21311fe9027a5b2e133cce16ac15786d2d44b5e4979cf2a8667d2976ea386eef4c85bcebc39b9d2dd216e8b4f7c68b7e0a5d7ff570770a20cc605e66470d995ef96f1e0acf6136716cd8a26b3b725db3ff48364f19cb2c640600d00d0d728d8fdac7b8a205ba8109318eb5519ee03848e79a1c33898555b298aa62d6da66188506638918b46926a99ebfccb649cd6bea1eb87fa6c1999a70937f51c4a2d485c6aa2bb5f98b1c8ae558e82287b9f34ad70954f8dbf3a9736604c43bc3062f8707fe88483b0865bd6df65f7e085593d5046554ee465a10ddb0c0b651e2b1031d56f5130e100e4544809a093026b88277e4e1f1e3aa40997871ced6e6eca44f183ee09ca679e4fb0796af62cec931c553ea788e75fd37ced477f9a58e54410c513fa79a4b5552b049fffd7d261d90a16f253a0782ec75219d1f7492ac2a242fc04c0216e6c804f8fd8f761a70eb747e1545313706136b085fc72dff1714ced89ba14a65a34168dc0e997ea8718ff304a962cbe8c7df8b759d76eb0f18155e49822d21d91dc8913c323a824da271f8c57d44a27be3f04991e2a47e5c8da2f0d71610be89dd4459b9a9f5cd4bb5ebf730a72617613667984d9a0e0ccf81c803e46425899b2fffe9158f9e3d7c36c2c42938d9433f764ed1f6d9c7d69e9ebf854db44c398c00b2612cdf19927de8bf45df70a5d4307e3a628a88a09a79d4e03742f89363d891b241383887b4447d0cf3e0eebe4a9143cd6873abfe2993b1f4d1b3b3a18aae4db4465385500ebef246adf17f1d9196f78749dba2b12deecc5c957e022f5b9dfcc3536bfd306a1a70e50f7bab1db22e98c8705328fedf3686938eccea04e7db4abfbdd939d56c0c357612ee3536356c0f5bbf1d428fb31c7b06a75c5b4fd5b020e6d9894b50eaf1df723131712344888adb5a0b4c07d23f6e853c88b51fcd56beefa721557256bd9978caca155db7f9c325f9564479c39b589431ee7d5da402e79ee6e04061c62c1f369176f6b35174b65a978ae3a4e8a25032d987dbaa5ca048734cc1da5f875f72db399df6e6a300db183e96ade56ecae019c4559c8f7c94899178c98e5071aece48a3e9f5a795159b2dfd0a1aa784b263ae5d352a890b7c2c6887d76f0364e2028d4f9046408e76efd6b5092590d39ec343facb16ccfc0000bfe7bebca2575b1f02c8a0aaaf5fb0bb13ac3246e245ace99f2186160a12792fabc0b390cb4c32f87c46f741c8fc940c4aa7843d650f90d422504bf97dd4825e533f646c6b77c4f004b7036b5480b587a913f05bb8ee470f0ab148727835b1659d8c046fd24276c95d30158424914e75d9b01fe52b34d5f76b2a1c98bc5236945fb46724e02851d46aca237fbf047f3055d6331dccab91c0bc20be2260086552fa7c958840843a3c38acfb24f9dcb506ee3cfc67f3125954d9090c1fcd629d1c3fc557b7d6ab33b9369ebc8b5b43f9e23673f688ffe50e6c3dfb12ac58aac60590991c9ce68502873fbdea04455459f6ee721570a87f87ae03a9f97f6e457ce1447358d8e3453632618701d62885ec4f8dd201e26405499dd7f317a8d2456940348827a08950d548b5c0b24cf494eb76dd0a51e3f5c6fda9f8f6545e3a6d1009775d78720f9b20ddded15c162f226873162a5076bc0cfc151e655e29d100b7a0d32c9c783375d1c6af0f39b51d927442386cc2c26337cbe5f4a34bfbb65b544b50b4947f72d839e6255a95fc859d6f1e34bb63dbfae1469be613472f22cbc703468d8552b9c691c829bdaf0d2e7e4093e940398f9ab8837baad8d9e4c710e4584685df01ea15ed9ed95ba9f6420e5766363e86ab8dfd1626eb1c7d2dba91d360821da99977be4642488972ec61fce7d754dd45a4d7fd9fc3498a6b7e0b7235c7843dfe8980bbd3a52c8868c1832f62d9e25a40986d061d7ca9d8fe29c7f234e3448fa315d749a09cf29556060307b970e5e080e90dcdbec4ecab1a7868cc5bad1037c07e17f961f3cb5641405f3d3c1439596a243f83b4f8576019712320ccc40581bf02a0788e3ad9cf4c44113d47f587e96061c61c06be84f6e35711d105f0c46b31f036356f6abd329c4e1e74f7d97ae6e4e0879be998a85257b6de6277d9c18980208e83d9bf266c9909a26f3e19941e728fe4ab0866d103644fd86b203029271361ea97fa93079ff227861aceb55e68d7454d1dc25aa8a7c780590a04756c840d13dfbde1d52d7df47d4146ed8d530907fcb13f6071e5c18acfd0a694938bca6cb081b7dbef2a646aaf55d4da9f3d42996a90655cb48144a4dd2789d75692530dc02a2635c26d428f2c6b66779bd9facebcd73274ebf333b8de26609bedad5739e73ed68798cf9882ebcb12902bed483bd905b92b3df495e708a0914a96840761da66379d85105f29e14e47a3e5273cc23ef5053077ecc513363379d2e6cb3aed80098589032cab7c20eeaaeb7bdae7e3a1c7a704cda4568138ce1ed94e944eb4ea72120ec91117338d0c86116db36f3807a70bcd98de03cc46ae9dd0c5fd3b26d78fed5a8b53c0c8f9566f921175fd193ec521c9914be68f2864715a572cd6b25948fb8dfbd75f4315967d5a6a707f1ceb81b98972e615d3e81b08ad5ef1838af673af9b6d63dccc226eda6d0b6fc1fd104f62b80662ff157999d7508f625fa2408b6f9ab4deb410ebef73750dca3e63d5045300d9b52845afc42f064bd78ce574ba9b4fce22aa3158bd058772ac2eadbf9fc77bfdf85dc745b529e8baf248a0bc1963f8fad78471116b9ac11679a326e92d87e03e316c90d15d2f9e3921e0bb6ab4b7ce91f12e7cdcd9dd141b8ef160e5db1faa47525a77a038558abd98757ac5f6313afb4f4c84b2c768e456f6de4a78b5b25f90926352fbfe83037f81b31251249fe52860f3cfa7ae1b20c73acb015821840dde2ff2de0470450b11aed7c1f84d4020147f8b9aeed4a37909bbb63508e533f939f23c2f5952ba6734745c51b837b72a398a4eb8dd6b4ee7648ecb55799cee7b6385ecb0b2e36b9518439ba550b257230885b83f72312e53afce7e7670b26342e4eb0a6286c0693c54abceaed1811418a9a289b4b09b65e84b3149cada8114e830c0403884ffb74c515bac074e4a981c61447ac99368dbe9cab8830911ba9cbb64633f444716f401aa17f599174581538918e88cd255765142a49412841deb528f44a64acb372498bd66f979d9189fa0f0e70e305015dcd3c9aea085cb0f1d79a63e92eb39b2dd2fb1b9ee9aec0213f3a4a848f3450e4a6d902f5435e234588ce4a7d2c9dbf60de27227ff02ee4ca19314d72674fb06c00ac7e5d15cd05fb35e973f0974a4718ea9b0d35bb4064a6280b654a15a7188c5d5a5998ba1f031a3baecdf7b608169c0ede84d91c9a5f73b0176e5ab2958169ccc6022e0c43481bb8e6217ddb1bd9ba8e8446aebed6afd163dbb6873d81afcb74b034085afec0d626b02fb10839bdf2279acec3d8f3f7c47fcc3ddc8cf1f08de8c8e120d9c06648acbd1ba6824ff74419776b73b05d797a0bc43d77eb75029112380ff4e87e543863ae29065e40c1b2b1b2d62a409a299ee5868036835627dacf4f9f7c84fd2f6707d823eebca0e8ceb2bd258038b137aaf43e0e937be762be5d3a6545e439a45090d397c8d4a068286836780536ad99cb138cbdc6fe5e9db3bd405ae6eb86084be3a49c8af88682dd52a5fa8f7fdad76cc0b452b3c37b27dc3cf66c57a4ae59a3687950ad3f1fdab3002fb2281365348cfcd9306583eb79a9555e8750dc95260a1b277c566babda92cf2b3ef177854fcc3dbac88da1536eb3c6d6fa3e336ed3a7a6da006901c845619fa00596af8e54bc1980aec4aa97bc98266c248bc038013020fdd128db0b9425e8f7e3165f5b9190fbf2dae5e317485d9d103695cd209d5d247ac7e1122bee4538b5b74790277ecfd2051e43a34b7c5440d1198a1875a0501eb3f519ac2f17553c5e99a9c83412200a519251d4d4ed1c84baecf7d8cfbfe4a7e50d789cc034a21043fc13fc3150314bd7a7801bf9c31aa00b7cbd9d0fa4ef0636504f0dab63316d9b9a1f4703b3be23170549fa3a29ec02f418d687589f77939fe068e41abce460fe118b04fd418f28edba4fe70d8fd24b38078a5c47ea236d73610ea116666a49acec52fbd810bb99af1dc5bfc4eaa634dbf2178151acc453f93567f015f2a25002eebc1f778da195b7e9cf683db1a85da98a99d98614f2c25b2237d4393f5799d06cd36254d3f22a53df5133cb1f43836991d3f7529cd260df88bc47e4172ab045b66e081940dff797b28c632898140425c3f81a60236b82522c0da7f0e0ec7a8ccdc73cee175d3b4543293135c31c0e0c926c7506920cea1d0a1eed64ede7572b8c77ade1d95bce10dfa69fab7fb5ba64055800593465dd4c26717e37a66089f550202a0530157e5274f3d3fdae187444f5ed641c608643eee1b361d78c9ed8070a85150c80368a84b14c9dba5b20a9059f1a05a60de938ab914a093b2e741e891c02f638c73c730e60ef8cb5d9e5031fdaf6918750f192ea7a76e035eb05d7556ad64a77109c5e13bb3ac7627d99165567dfbcfb7fdc7bd847ee7dedd7864353f8fdb7a9939867d9a5ff4d9ec9727fd432d8abb43628519cdb6fa49ce49064a421a89bc924cf6286fdec8bea6b5a7b8eb606f584d44c7194d5424f98576dc4b5ce7dccf65509727ed52f8d7210095252403023473af96eb5892cd3881f2e1f4dedd4c9b0755b70776aedead14e2606bbc1ea3c300984ebf27ca69f36beb03c0fe3c13d9df79791d828d52260103be72b832ba235bf1165250b608e2cbda0c9c8d3c96534802534080b2a4ddd5be4f269f37c4cde9d43dbb42fef8d507cce8b8e2eed799c72a2fb836f4160b5e5729192f088ab8557d51b58940065ceb4b48fec1873cc4b178166d15d441f45625f45af62c1d13863feaa8afc320bb36af0d151165c122a47d4306d075b344974835363818009d86c81e90345cf4b7d81786c40318a371fbedcfc325cf0e853fdfe6e91e99c07dc9430c04e6069b9e2efeed0eccfb161ca85d96298ae6dd67c395b78668d5818f567f2039111a7a0c52a21d84ef72dedbabe83f811184a95976b1a90dba5aca60d0313c546ea97d7b2e40b34ae88ccf4f45e28f05f16732d7a0d62dfd86e40a51de7f2b9b66ed780476cebeca547c8eb71ac20a245b1bf7445e64bce260b8871ead95f708974c3a93dcc4ee979975daa399055108854c1c3fe5a07046d13169c084b2e4e81821ff73d5d20e7556f40fa152226a6da48d5f86cfcf1a5520451c3c1e534db654b1a58adea167ffeea90023cc2b0b01710323177059e1c610154cb234d5ea165dcaebdc2fd9d9b66413b8a6848ea11a673f207ad76bd3ab5399dc0ed58a3ac0ac9d3c53781c36415d54b452a4a78e1eaa7046d062e3105541fec8819439da85ce53aa683aaed543704aa8210b26c1e6c8f1d1814595e3bce2d98a36089bd722110bcefd651937892ffd36dbc34f1284eb32c49a1c134ad460c19e01b3f3f2d40f664d90020ae8c546bba9ccf5500171ad07a55f9fd299d7518f00c0017f6c25d4aa01615fc7eec160ac2cc1ecd38bb0324e54cb466c3df4d56508f5239e1b392a50a8c20946a6db9220088d77c494406296921e3ac9997c34f15fc5c39f2529eb2bf6b41b0415e90cc9d7e8a83256cc59b4607be49eb76a7dc07c1ce3d0512888705c9ea145079085273f2236d5bb151dbe7d1bda2ed607fe51847ba09ea6431dcae727ec1ef0a201b8df9e148885e1308425d5c7fde473e90b4382de8bf5e215c3be357f8a2356348bab00a2b629dee017ecbd76d7ebd45fe4df2884e34ecbb86ea371fca29496fd05327c3b985a069a24a32380ac9e4b131ff48d58b1c528b941dc6290cbb41ab4aad2a55e5e03a63813c2113c0740029529eca008d906dcda1094571f5d2cd31ed79e9bca8e815e206b3ff3a7b4b82b0d30775e0b77260a42b1ccd0a58a91f0378df95cfc7f8dcabcabd2d7ae3b603e9061c1e126d00fde94b4b625e953b6b781da167c71a6a7ce0792e7de070863deaff94d74a7ab9dd2e3d39519a6c5c864036f7bcd4663fecd163d78a72a74d2838b6949eb7ba85dacb2eecbff1af2792047b036f77d488e5256ea16252257bdbdc1ca3d18d01c5de00ae8ce7d1c4cf103b2bd7a31dd52fa92d945da38eb9070d6f11aa9cb8bfaebe133cdd7a72f94f0fa067da0481dcc86e6eabe115cdfd8fe2e2c63c3cb3c0f75a4655eacfd337ddc82f770442d18ef9cf3993a9d1830217f50917153de7576917c533247a6725a0cb7447ebb0cf7516e19781a8ea8d1854349db9d3bc4e4931a1fa4fc075186dfc37ac10db1d3feb6298c1fabc8d897e1c806e38981c3fe7f252371b0e92efc61b2e787279f4a8138e7c6527ffc4092de912378ae692e9941d0b6d14354dd25900912f9a907dd970db649dd965c959e60f4d174ab0aeb7bc016735e8b847e231bdd240042aca16731926f537fe388b6496967b750a94cf514c9296805607b5f44451bc622486ff62e7af5c0d243503ff31d1c753d9fa3adecc8f555445298aa10a877250455c43d412719aade5a202076fdf080589a28cbeace5a63de77d188c1fb486d888528c5142f92e54f005239285cc4f8695c05ed32fddf0b0072bbf7642a1daff7246055cf35e077acb567b78c73094e583b9bac3ccea986305eb4322bcb923b93187bb3061fc00ee0b3d10702d7890c4eaf4e5f3da2143282dea0b12c3f043818914ae3ea98cb1322d73878b5d9920e87e6e00ae831a3b76484e0f69d35eb15b053c545464811f9c381337a80a603ca91ddebab47b72d6c80db4cf0646c579a136326be69bae46cb6ecbe23ae355cf7181981d8f7b8e16b3303aade349f44c005602c34878690d91fb7b4bbbaa75a91528fab18c3c8c1380c0c26a98dae3a2e441527e8c7e7df331a506eeaa2d299757e8b0cbba97a91f64e36e5a24cc83b00fa14b8a41e6fcbafab7eaa905c04c30755c551b2f0f1a24fb422bbd76090e212efa160103344200e83545a119cd7d2f53e8e5e6d89b1c75f12a44ddce7b9e9bb4710e30c853ac8d024be6f5b3d162941e2767c61a7f7ac5265d08a680b87f07bdb4d4e2037b99a6eeabef33b7ca6e7e6f4428f6814e294b7c08783525e1f632fc2a43dc057264bed23898edcc35493222a92dbe28da74c07c49fd725670ded86494fbce9476d3a594f4d96ccc3302a9e861933dcf46d03b7648bbe7bca88d9791b5a62694b34a9ee0d6c9d5600f0758e7e0a2721cadd048bf59d84bcd7ab33a5ffa8c1a237dbdf3481f03e6368b0c1a86ddf01b962520372bbb8e330a70cc684e84e1a438fc571ad9bfd297288135934aa4f1310849bc9c1658006eb1639d4b8ad2f858fdec1d5a4aa89259e591e2cc2948ff126caffa24bf41bf71b408da6b5107e1d65fcf37697d307ef3a3ce742e5d117e7bd4d095dfe8598213e0925bc9c8da414b09fd21451ad8f3531a756f15269614ea1ed728d3d37820c6e90578aa43f8f4cddeb9ce97b345840899a016591690a810c5773572f34b68d1f2f1538dd7c541508c990621d54dc2653bb4a7e9a1c637515538840f836d38333de92ff70997478fa7e4eb0b447ef04a96b2376d3e7319b49f8eb0b9c656bbaeb8a000104f3407e33c23030ee9d5d92a2aa7ff76f419ea3b1c9a8953b30a92759a8d0fd37b50e66c8f664792da1448f8d12d60e169382da435c038f10be62dd1c0430f18eb30af8c14512d3311a28d4252fd4b4dcc04b5da190a22c6eda7ad837e470b9d8ca3254f89a3e613ddc74c1865b5386efc7a8811e95163fc4c2a61b738bab3ce75e9450dfc38a52a59b89746cbb216cafa6faa0236db5b86747e7d9d3b6515bb19aee0a85bd4c2bfd76c1916e04db2e0d0382efd97d2ce79eb9370087b19faf4f269e7fdf64f6c30eabdef01c5a4f347dea6e28c48a55643ca36881ac5b283a9f85a56b203c3076e592779f91d3a00344a29eefcda31e2c66e38c6386367a5b43dfcb3978c891feda33c7907d7e4a501376e1786b9cc2ae1e0a60b9c0c979a0c1c96b9c126f647c3bb21abca0d4498c08a4544fc46ad1a33b17b105db91390689ecdbe0b9e6b5cc1d65a52a51d7d3a714c850c14c9329410c9efdbbd55cbc43e8568b01957d664de2a82c04caaf9e55ae5a34c533bc4da5c2a715409a900c7dbda950463131367613ddb0ae44c73625fc8f293e4002d5b704645c08098ead5a0fde1980d8addf0af0efa1288d569fa62d6b3f6227d1b4d628d1142f5eab4f7f1302bc97809b1b022e5976b32da3537a192938b8716307aac1972cc5b97019f4b7a9e5e650d0569ef4e7d12f8b123b1ff1d95d3d713a18dce009364a07d01b3b62a1f3ffe29130bee4f3b275dd27fd6860423629b181194a10ac44077eb2323e931cfdf64504a94a1e7683110ee8a21e67396d09b85237a51d824966527f9e3681ba9fa6db51e571d7d6a1d04d0f9bbd9d1036316a67ce225705018d1f0a9b9817b0d01dc092beb4e1290a7f12b22cc32697a75e17b9a93ff817a721ed0c696643353b80478a8d41e92b0dde35d7f2918f310e829305711683fc8c2119f0759e4bdca673ec93f4f0837aaab4c925925504fab72f35bc494a4d8bca2b2ee392af02422b2f80f174519fc83a06f99290cc7f1812a32511dc9fce9499947c92cc12c241923e62e98824b85ff3ea4979bd4362f87b7a89204598f51629ba1bc6d42354cb13c093d00c7da85b2523fee61b85573aa7d4a3145d518689ffcae21ff6470a8210cc6302bcce2459244e6f9173e1d9447726942749fb6bb13bd0d3479ac5f1e6d70e104990f2c9311046798f906aa215c002ae0b918af3db1bc591a937d5f485489a132fe9098bb77387906ae54d92d368ded939a069d0866279e0f7cd815062dc25c664c168ae4a11b9f1fedcaff8e3c37b6f7b075e737354074381a135291383a35047b1dcc7cf3b815c1b7ac187a4dcbf64fa5ef83c4fa2c0b4f5b7e024af32ab5d72e4e86a92acf858ff0aaf0fb8fc64fa12d0733c6fc530ad739df51038fceaa88e6e47fd80a357f501dc4ba5de4b6c0c573534a84e5aac913bdfd30e548c8009f06e7281d4b91b968852033af7b9e79b644b1532b9324b9788ab6ed930236c5bb2de248231f3046f490131ac34586b43a3c8e0a73cc756a816c79f3f10f12c23501947b29617fdc2a45c7f361d27966f73b1b3a1f50cb0052dcee33ce739cf2da8fbf9b7e5734c5a7fb8eea9f5a598ec6c207735409ca3401894f634fc787fbae311d4bdc8c99e8986f306883d7185a18e71b5166cb9b84cdaa3cb03231ac3053beb31ff3d87838e53ef698f9921a0ebe69c9b1526ba5940bdf21fd745f6f2653adc2d3c36340a6dd7c9ada045dfee2349e26a62b437e0c8f4fae2c7eb9eb577c20886d8a8fdbd02d245c1a1478f52e339e8ddd71fbc6d2cd1668a44e2c82b311720996b8da7111658a04f4b756d84418ef3e99713cb73d87bb4a14f69d5ef4a8b8cd6d0008164fa0a802c0679b26e155d801b40a2c77453dbdaa5a582d7c9d967e8a5706358c68c6da6c3e6746f0648401f896f1674797b0e14b354c27ea94fb12ad6d8494ecb0eca0eb5795b1920c618b429b4e95979174fd21685ead022e7ca4f87958c8a101b8b3a5e0a9d64393395b12dfdbe7e7503b62db0fa8813c4eaf1ffe5f190de55e83fc3a01b10a647d77cc49b07a258cc4e65d489451f849f6aeea5bde2aedd8e184cb9c778a3676dcf87d2bcbc19647bff28953c5d06fa73b860a16785238f9765c0fa958757b4791272cd8d1fae302b8dc47282b782d5c4c5ae75a9c02a3e911a79547df96d2c2306a2e347e83a8d8a126e6a3a21cc46e476a706af9c42a97b3f8fbcc0de5cdfb59bd6cecba11bbb93ec1bac6422b61277eccecb8b28b3d97f0051b89997c8c22a9f517d9fee5e16606614fda11940cf388c04daa1b302d3b0590a9bd0692d6139b77546d71454054197adf346bb94b4f2e85e502e3cd919bb43e8b424339e2af0e7070b035271783b1d7d48ecb6e63f3597d08a9d0677a44c29948d9cf9570e7fab1ab0d8262bb963d62e895c9bc8ea999f6f8770ed5ebf75a39dc0fe2eff88d75ae19690e0f0d52090f18bbfbe39697042cfb5293692f1e66d76aad38bd919b634ee20000000000000000000000000000000000000000000000000000000000000041187a86f715ea1475c76d354d556242c15f6b8f7c441cd862cc7c89d89a58bca02ac74c422eb01833db93e4b067e507da65080f93cf1815f4cf1dc0d53a2802230100000000000000000000000000000000000000000000000000000000000000","nonce":"0x190ed","to":"0x91a5d806ba73d0aa4bfa9b318126dde60582e92a","transactionIndex":"0x3a","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0x1f02737dec59ce5f29b7e11309a33cea7b370eddefa1a8007ed3fadfd1c6b23b","s":"0x106ff6938ec0a46da92e74768b54926633945ab503e2f2dcb69469b544907586","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x2d679b567db6187c0c8323fa982cfb88b74dbcc7","gas":"0x5c90c","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xf49895cde","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0x45499074aa521ac4151138f0aad969bcc2dfc1648d22ff8c42e51c74cb77414d","input":"0x003851f8368551cdf133121c7cf32ee5690000000057b378dadc7d07581359f7f74c422f52a4d750946601a4898820282002a14608e24ce8d2412c889246951210c5eea0206041c4025828362c2828a8a860418a28208a224185ef99505d5d85ddfdbfefbb9ffb3cd964ee997b4ff99d73cf2ddc5b063a034cd01e114eddde75618857bf21dae562932ea35bbe70493443b0d3bda8e6161bdf9a2e6e1a1d63845cef77f151ab3e17f6819ec2bc7388893dbbbf49e9f0c76d8f4e3a6d5cb9c46eff41ba97c0b3794c105b1a891908a7812b16b0d1d7780802e8c7621a188764369f6bba1bb0c95c54c4e3ecad237716b875175c0e27d3cb133dee5692910d9eb1ceb4679f65e7247f51ad58b4609f4c41fb91c48acf7b7d2a8532654b741723ce4f70eb38a521e9948c62bb5d73328e2aa5e7174426f5da2a4b1c6ef04eb66b2d4d1a48f0a20cd3d8b6bff8794b3975124f8d8149ff9c0b714da5e23b8ff418940c5dadad787c4298fc8486c94c44d45593bb8dcf6cbea18578904b0c99dd61f2b7653a1562b2cfdc3dc96fb15db01fd11710145c7d6b0957b60eb6fe886a047920fc64a496565e715ce7ac34a51a8fb632f62680c9de88bce189d008e29a23679115012cd789ae2fdf6cf5f4dac0cc4aa2e092b846d3d3b36974cc62244625394645ce73c1eaeec885e6dedb131a1d420a57f945698a9e7c57befcea025554af9a4cf6a432908061828ea86605e8ae7ef301f4c388060625fc5cded2d60f4bcdd4270b2cd05a133fe45e31ff72c0fb8465065d16678ff60a4f2ebf901d2403345bd6c4459c6c6b97bc038b3cbf9f0ffcbd7fe06fca91bff93e504946e2051d05e23e28dcf2d35dd2d1c2b16da8fffcf65ec0b789efb1afec71cf481e5b4476b7df95109b64e2c1950beb3cf3ec9a671ecbebbca59aade6ca79f06328bb06669266f9fe9a6673c50f5aced1aabd49947341ec338b82d9ae31d9fff59a0511ed938e016432f9c5a001a7d5d34b54a7d9a2419456e3bd0eaa860ff52e69806188aec7e559a70415ccb6653c885fa17efcfccdb680026e43c9ad0bd5b379d4da2127d429e74dcb29f3e45b3ead08e1e85c2be6505fac13244c6e528ea261329310d9b80b16bb7b562d9477dd95f6415de5bddec30bbcfab9cb9bbf88e71eb47c16df81087fa93c4b39b5e0e1cbad17cb1bbae73eca0e2c75f73e12e89371e79a4d42babb71e9da013fdf5ff1c20a45ac00a02bf1ee09b0efb1254f4862526e5abc8cafc311bb27abd9af1464ed617acf4c1647dc8765d530e4b40fed95768dcfb24a0782f32fa6cb29e165a5745f2b44a8875a96812b99a095edaf5afb1144335625ebac2a489d9133676bffed7d161671de594b27973fdebe55eef99d65ca83e607ce6ed86d32efc36bcb4bffeb2062a99371c93d2eea8a0f47519e0b40ef21ee8d9de5e8d8da61657072561ab1cf9a4b1d51da9926a2d934cb9be7a548af7a5835758b5164f249ef0f0b53051779089dab29284dc10c24a1ee298ff1faf3aee4072cfd4ca19520b23941a4852bf56dfdf0eb075ff435f87aa51ebedab52cc3ebcb4db9e133e57c2aeb10a836d1f5484807f73a9d411e059283bb45fc028cc8f919abb8ad2b008ff7a95ca576c0c04aa4f243f10d2fcbc425ce014f5fa6793335650b99beb722faab1bae677d9939a02d3de5e0ae5d5906ba024cd019c11f0d51c89e73b8cb3609f7faf3d127f969f3beddda1a756fef93ba1a4d33e4c3992957a9c304394b7760063250a5519ae83b304c00fdf0a21e2acdec12482b724df3ac5ea472c065a9e2b7c8de28454d72ced29d817ebf3126b6928c2cd7cabbf0cee395489744896faea55699fc7ec581ad49b782e1bb83bcf535468b91703bcda0c48fef1e919dbbf30aa45b162c92f0e01496643bab3d9020b8e471695769f04020557e8d0fd5812bf346deaabcc118c92dfa146a1b5fa6aaf5db5e6fd704d073d9c6d549004066b97db487f857716ddbe6cc6332f7ddba3ce2df47f0f25911e833adf8f345677a96c7223a3efc77a3f7a5d24e543525591d1fe4afde76a4a3fa883efb81fb9e324c5727a5d2e7c04013a249366aa8f8242373f9c0aa55a7366d364b0bb89ca1da127046eea1de1d39b917fa53d6acde40da381a71d342e3fdbb19254d7df86704eb979ebcb905762ad78a852bc948b97aba45e99ea4fd7e0340ba70097b4884abc81c20e99276eadce78b6b5f075620424b9a83af6457cf29d9fa52b6df6bb7054711e789cbfdfd1bccf3081ed96225866598328089398b84ac237a46aeb513780c62f5ba256d9de6392fb333debe7b2ebf00571be5b6dfb5298b68c0c4f8a281db7b5a819b91297d29e586e6e78dd685f9810e830dad91e79459de4f2cc484ed9cb3a49eebe9b51975dbedfa1699e3c2fb9cd6a7e9ecde33677fd57e07847bdfb9bef75f07bb9f55f73c695a97ac188df3280a5e92f0a4f1c4adaf8f53bbab4682a9dff482e9cfb43db9dcfcda1a466cbfae58cb09a97d8336c88b124bf1cfff8a603a78299b6e6a9ffec57be9c75d73fa3a86049c56f127d5f3a6645bec138e6f9ee98510eef2dfcaba7f894ce575889ed3c89b3c1caaa37f0901d49f7ef9d46c955095899a76feb44cab15d918d6f9e924e77ef594b9af6e7a2bcbd2190758bcdc73a2cb5f7e25e9afd87f893b653e7d81b294fd6e0bfca1f5565a21f725312a2108c950f275a4c0a698ebabc567bc1d0e7b1d74b027f1dd7187cb584fccf0206d997519a61060628e2255ba437bdffb3cba91b64c87899fb19b5790ebbe92b0d55d2b0eeceed76d6e91aa53c6ae2113e33e299d531c4fe70c696050e654c13387f0f5a9006691089779741473c7c7dacc4503fe93cbf7565bbbc4f715dade96b451a21f1e36920bdd10f42f48946f8ac56ab3afafd84800b2a9fb6d643cb17cde43a619d7ceaa915e6f5d209ce489a8b47bab1eeb9a93792c6dc3b7676dbacfbf3e3cf43e2d68c79522b62530e423f3ac341333908eea556442afd4a7035384916fe5ea257e3af6655cd75ed06f3498afbed542b0ad0491373609b66dc14b70fb96868a8962a2d7ee4d16ceebdbf334a8758b9721bc879a8ff8bf9f2fbcc6f63a9718a35d8b5df1d6a38bf1c6123b43566a079d88b94f3870ea1b9ad8d94d2db14bf12db3ba58dee361949713c756937de91dffcef9fabe2f9714589d51e3a72c7c896ce9b1fde893f5ea895975986ed8766eb7c7598bf7371fdab658e7bad069a9b52f9e9761ae014c4c15c25b1f98e3e0dc1d831cbaddb6f4d3a993f2257d61f345b3cec990f79d3edeb2f5ea94016bc4c4448c8f9815e81b7433017a719d074003d7307e3d627653f5cae3753642527b0a49b76bae643e4f0cb4fe00bc7b71202d6b1ed7329f6ec4ae64ae463ba7cae1375d3ae4b36741ed88e3dbfc48efbabebde8c1eedd487fb8a9f42b66808936bb6692353b37642efd113c62f14a711f42aa00a0947ef974dbf1c9455e3c1ef175af9cbd8bb729f5a7069685775d8ba8fc3552e37e8765680a58eed27db682227eb6f9f12e9378bed42d4292a77ca86c2eb79f2d289b557e5be66535a2f7bef852cfa2dea5d97c52fee7124916123d91d6d6911564a5c2be40110b99de71e9d9a6203de69a6f7b57e54fa4af76b82daad4021a3fdf1ed0cb5f2118646dbd38f2ff5c7a107967eff06986db9e2bb8996f3dd20b7905cb8f091bfa1f9ab52307226009181925c4cf729b64c39add884cc606b5cd0ffd92167e5871ca3b85b0eda19eecd1f3876fb98ea4b0ba1df9cb8b5e5a87dc74399170e34ec1a2b29df609aa1f86f24fac697de3bdd5eec694516c5c59c6160a30d90211319e50ed9384a8c8e316331b2a64f65a2f2f72b3793163870b4fbec75e81af7d4353aed284c926575a821938c34a619bc75358126deef5ca9fe7b0a5e69b6a7c19935505c73df8f2c06ceb3c09fabd79df5e67c5f209579df95d20ad0491ca79df3ae257b8ac3e95aa302f84de6fc847c8cb147bbef136f355a240aebf1d19e1db26bab8ad4c6cc6d6e27c92d0cc8420e0f9e9cd2bab9e9ef2196e07f04997abc6c1054e015c72da67366699fc045c21974f9d6433740a3abc30b8fea46456ddc7c3adf8ff00b85cfd8e8b6ea2ead437ba951d6d5c6c73322d29be2a35e63081d752933b7938c212b1289d2775222261d18633dad1e73e5f323ff2e0ecf36784f52179e6bdc31c5c19616886a139ad0c632e47d0d32d1ba2ac6c0807fae7bd766ec53b94fab2d2ff22a93483fbb6445e72d409a398840f476eb72f1a0ae8143b70fd04676db9411782f83dee540fbe6aa82664c779605bf155030785e13d8f0bbf86951c62ecaa7e25881f491ef1ffec48fc67ecfe2b9247df77673fee6cb0f66f64fb982379d6deb13a79a3f893488596938b1bd7369f9b99832c4c3c23b04cd34cec0dc5236c4105ede9dcad1943c5813cd18525daa70fcbacda879ad6675aa6bdd5174f0b9e9b6c53e67f7771408aabf9fefe79e92c5e8a6638ae8f1e38b621647d0d51aad753ad3b5a5dffd869f18bcb9a8f73c76b452f45c2f8ef6bbc39c9a479bd1c66bb74f6e3f555db06f55a1566364ace5a637cabb4b6b5f422305086e8542d0ebfcdfff1d1e7ac9d2deab374165267cd49df53bcfaecc76a6139337e9fd029079ca503816826e13fb54ca2dd757e147bf8cb7d793ab299cb920dfd306ab4654bb7661cd83814994236d8b50cd984ccb5d210aa54dc73415c96b92d6079d19ad0da60496d2b64f3d687b8cb154565602ec004b311f96d330f172d255bc6f0c550afe9acd9927abfc7bf67c37ca527edf3f61625f6dd9d32ffe64cd0b10cc433411bc558b67cf11bc09f8f4d7f44bcdf6395fde7ea9f70c80cd66aed764d8dd0ce88679b5caed8fc9c2ee8e32d2ef5a8ed9efd1e418feb40aacf7f19f16c9a1b35357f8bf8049ea7fb91c7ba47d670ec211f547ddfac75bc552f487263f859af5dea16f91baf2104b6dac8af88eefba672312ee7fb9f96886ca51ead0fda9213f8aafb5bc4a7840f65a01cc004a510ee5ad1dcfb0fb650b747acbfff26a26f568544c0d24186f8ee4b169615fdec32de53b6d3f2813ba5b7076edaff3224797d524bba359d90f417140cb222acc5ea65d83c0e7bab279f4bd8b9f44e0e7c907865bb83d3ededf3f539ee85c3420f10ebfb0725fd91f3cd2f3cb28d9ea9911fe136e6acee0bb05a7f18bcd4b5caa9784b19f63dc0c47623730f54eb3f52b2610e9cac31bf560d29def6b778e3a6512fec915eff7cb1c18981292bc892893d581a311046dd9c132b6eb9fe354075e0caece17f573454c035ec85e973988dedccbb7041ce2801733da9f782c8d85491ddce93a943b1b647b41d02902ccebdc3c82b7901adb91cbad9d18b7915866a1d9098e1c43de52e70477048d02ab565547ad68c33c7138d30fb165f1e5e76a837bd74a4af58fbcf4e34203d0a1b56be539f2ddeb3706d3f25e663ed919a97ff8abe62a76be6bc6fa6e61aaf2c8ec01768c7eadc9bee7ceae30c31dcba975d6b558ea932e22a71a5c728d2dce05067b1d4a27dcfe0438fefcca5cb4a95efe83e63a7dc247570449dbed353e7efbad6ad8c981a2b47de139ff5bab370c969e154b9e4f07f813a9310a9c021f52b22829622dba52fc47814892fca57ded9158663b293356decac92b391c56d7ab26702767e30b9726aa51bb16b79ead28fb4e00b815b66ed75006e443a9e41bb5ead6975bd3f8326cbb4de758e7907ef62dfdbaddcb7b1fd85b3785ab27cc0128d4a8f0306ce3c92cfe0f708ffdb335bf69c55348e88597f711e5d35efb6e05bfb9d266f107bf8497e8ef403b791e1c3f23d6f83f7c7f2c7bdc63776dd4f3ab24178e30daebb616cec37cecfc9756e2809a6d131c648f88c6eaae019a9c3579c6287d7681f8b5a24bedd607ed629eae12f9e2bdf55ca28a01ebfa2b20cf30460621e22b49241d178f5884481f3cb5e062f2b5a1f90e4a66da24bcd9328d9501e5f7369ef94ab5cc9c42494d60edc51fa6d5ff843a8fd5d5ff89743ad44ca92594df4fd090a213696a51aa7c3845fb4d89b7c8ce12a9e57ea61d3651b8868e7d8af070f78ec48dfba75613df791126e81aefbbeed1911f5ee74eca37da5f0c478e8d9d4c6433984cb8ffef678888c982b7fdbd36c736ccbc9c74f65d3b6659d3f23ea63f6614974a4d62507951089c22d885256b29d96a7f196cdde15515ef5b95bed572ef4bd1b712467c7bd67f96b1674378d8f87a07fe35443630157d419d038c7fbb0486d5ff6dc908db1319271d24b7d8ec8b0cd7fa16d812828368871866b96fbd5fbc63f5db2e85991c937e1e7fe1dd93972d9013b5e56e69661f40026461bc9fde8a9a46f19da2be783f9f07695579e22609fe4b6252ef1ddbc0bbbbf687d9e316570db32c1563487f09b5e0ef117862d5301762222e99860629271f05b8d38d06658ead0e686113b9aa67ba89cb26bdd3e8fa4d64244cb955fef548f69f9c5059c0de748799e245be3b9cac822e2927319db667124ee46639bc3b462dbd6ba6f375e94842e4e5dfde5d409975afdb02d03b52c27f33f98f745c0d9ca2d2d3405f2babb8231fb446e87f1f97b776e3e7a862db3fc7a05512b633f75ab70bd7244aefa306fe9c5975202ef0d360dc8b725b06b961c6257d02b4d1c8867d3a1817257a7c80adf3e15ac7108cfcca555bde972db3b1bcf38bb19b35839f0fad1166f936c23877501f220ff81b93c06ad91f798214b63bbfc9e9cb6af0f41548c3772da35590ca55d22b6decc5d1d7b3149fb5e71e09a40fcd997da77eed62a8d84d9aee853c68fcbdd79b210ce34a9ac25093a57572d557d47cfeeac5beaf9eaa9e0bc29c3065f59c6190a303903918dd88b9b4c7624db2ee1b48de9cd4d0ca875095650d5c8b5d903717d33bc5b1635e52a1d989c72e3d397e29367db456ffe6afa124496a6f331d5243f40dd192b1a2e230badcf97acb3130f5e2af588fda4bac803875788d425867687a67dfbbb7da5fefd9443c7b565b79d3dd9e669e76d59a797b3ed7a1e3a580b98da60adba5c7c71d0acfd5bde9ab5ccb69fefbf6915976653797ef913ed65260a5c6286eb11e962d9358e3bfa3c8fef1526293c72e4bbba4522a7e07a5f6da6012775d5b1d487283eb5ff89e5b024e4b918e98ca203a0eac6bb26a5be64bb478ba936f1b410c298db9260f6969ef4023125bdbc7db8b725cf7e4b69e0c0bb1733f3a4ce5f6b2eb374713fbfd4f488c5d1be324c038689a943154e1568a3dca5823234ce6c5c26ed2da769d0b1a78bdb4fa9a71d59a2af1241315f462ec378dd24472efc8d17937fe3e4bf89a2987f3201db5ebf41726d27cf6c26b167556dfbbd0c00589c8fc1827fab8ddf45f95f76efec6f8d3ffcb2bc9754f9ebf26c935f967f74e5fe0d7f18c35eb6fe9b112b9767b418c56d9ef750f7725ad45de079a5d42b2569d5857cbdba2f426619e57273da74b5cf5af951e76b3dfc6843519c8e6ed6dc7b8290fdb0b1f7efeae73a579a7cb26abf03c7e7e8bdce598e578a5a6f1dd57f77ec99edba37793aef1fee973cb8ae75cee284055e15d62e19178d3707522ae7e3ee9ae5d00e9d4d82d21e79578288e3068737f317a7c865c4ce6f38eedfa4502deb116b7735b897b77f8d41b7cdb7fd07973e715eb9995a40986da462fa51b9e682506f2559526a6bffbe8b6f6ebcbe97568679806162eeb1602d386302d65aadbb374419f9dd1e08dcad0467c5f3e96934cdf94fc11a04ff3158473a8a7e3db77f79c292f017ed42a28ab2ff7d58f7ae65fcba3cb1ee97e5ef3feafe1ad6a4dfcd1061fa5d171d2f21debb4a99b5ec48d57adee17b492faac44efb1bed06b538a30302078e9e17bbb15b25d3ba8a4e9255b1ebb3905ab17ccebefd6591d9feea87e3660fe17e57bf9f60cf0992dab3aacb619b0902162a967eaa4709aa8b0c65aef4bbb2a56fe2695b51f950ea8b5544e6fc4d5d81b96fdccbd55df29cbae1ac667efbf62b51c39c6b2ac9c839cf8f85c7869fe8162a5f6a3925e16cea1e6cba00bffb4863d8c73c355ead66692428b3a88f939c136818237f256159881265b37aadff156ec96f73aaa3b7f8783f2bed00065a914715bb57d12b5f65a5ddda5ea31c67d9b9e6d2aab2c0a425ba857c471fd552097a343a660972b6d4cefe7e3671d5d34d5da54312451d414f00d3944635dad335e7f56b00b30ab4c3751ac81adfd8c33e950db63ff44c85b901983717a35575561570ef166c747d3abfb8a112440aeed6cc8f575a3d285f3a6c1c163bf745b4d79172d13da49263bb2415b00f520d118b3767240e1dd82f7666b352989c7a6fc8e7dde6c5ee6bcfd79e9ea9bf4ba342865886f90c30317d88903d4fc501a706f9b7070c15ef543ed850963cab079ef72e75090761717efdca575316d58589c9fdf9424ac0cf070ef2cc885b83e49f0c1c82e91a1a00b3ac246599bcc4db1ebdbbd70d956efd071652cc5e2d14f79a0f78614f7fb472185af9cabfd138b7705b9f9bf6725e29faa5804f8838a6e5f5ca00385808eb2ab34363ab50b2f2f9f39233eddd4e463d18d6352ada86a61dfeffc4424a22b2986f9791436fd96cc3ed2bdaa399b32dfad71bdd1e36cedf2f6996f6c2b6ebab2bb2ea4bf11b2295f77d0bdd9e91295cdd23ea548e8b8839e7dfec6bb74976a68232ca8be3b478f1bf6ce7868db922b5bad6f87ab1e162b27256ed71560a54aa622cdc91785046ee2dbbb4c8f220a9334b8aa9d6bbf73fe724f69fc8a0bec2236e0d39769befbf3128e88811c39d55dfccdefed9a8fdcdaac78c8df18882b467cff80e2ce569edc0fad9247625883cf6577f16f08d9efc2ce1f8c3976b73e789773f6c32b6d1baeded08ee286e68f046148b66e61ea93da5735c56a5c956b076d067db079b76bce5add735a078b5db7ce3328c04c0c488205ee15f6f3b81b559f9bc83df308fb6b974bce453e894adb0df2061d8b3c3cf62ef9491bf8a095e1fcfaab174aede7b64f4e32c0d84737f9d559b16bb8b3acccf662b81b5a01d5f8da95ea91483152a4c93feb61db3f5d2aa8791009f43820bce2c1076edf0d56a31311c6c40b4bd9bd65764de5cf8e886805e3c6d64d22ef09f9d03fd5df9ffeca41dc983f7d403e190d873607781e2d756177c31b750dea08658fba0dd215e28a501096dfbe83e5b51e068a650ebbca797ea4508fd1a570e3cc5bfa6d46fce6e35580e9581150013bc8004a93d12b222cd5dfffaa8ecc66fa9694daf5e333b4ceb24d584bd67573d34f50c9e3234dc9860d0785084ff75b32920b2539af3f26d5363e70b94bbc71615c564d61d5df3527885b8dae59373333db7ecad439655a79c12b0c39c0f552cbafd6ef742e2e682ea274bcd9a5a7a7de6de1f7a1ec5561a341040e5e75ec0da406ab741f458c3a11bf714f23f730c19ca32d78af3c52b6d79a2600b698e2c0ac8dc7548b658bc4bc3f975bf2ebfdb916e214be74fcdd8c60737bbd2e5bf68de1e444c28562b70515cc9bbce2cbf911b7ac2aa18a20b1dbbe556bb8e6788921c34285766b410601ae9221fe28ffb48169cac5e277cef909925dbec8f8e3b6fa884553a865f085fd7f9992b75ca1674672eea28d37f8f61ea77b3a6f29e4f9aca9bfde138995ca6cf80c89089830e59940400420408207f23e221137b32640242260e64084b718070600caca5ff4b6d531cfee25b1408cba09000202d9d4102b86a5c887832c4c67a923dfe048f2701c05512009492009007c2494338191722090085277d675b400280c724006c1c7b08f19000a003ad85d7cc85e8c9fee92540028001d6834cd63b2f27dee7d7752142c002069e81fe1fe2860086130306011e065bc4f04ffe8931f014940a25a138517e4a83911463d07efe36469ce18cfff95b627ff23866db0bce7d8e62ae2233cdefc8d7e57ca04b5ac564291e7e72f2d5198990002fc20bc8c41eb5413a9671188f6749213c2acecf2ba4fefc319604601c0990897d0cd7954dc8afcd07b1812400b3824102f84c5c88a3ad7f2392008c2f04d06824006b3ba662328481002ad589046036a326e023b91033f0780ac3194f860032fde7ccfc8986507431589f108063550b8ed6f527cafb331dc4347f703821dd7263afffe522bfaffa29477768e4bdf7bc9a2da6fac9cde693d2e97734c8c49e0460e7b1582e1c97f13009c0ae181531604c4454eb2400eb43633d0e8570d224802f4a7cb40c3ffa4102b0092c0a367f1605bff608c59fb148fb5333615b0924007b974a02d88227908c7d4602d8ee4dfc66f3fa2b1060332190003675daf775b319fea16e4fd6a7fd1fc948dff144fc4e7ab6bb103b04d0febabd4900db65b4c14f130db22f1eb701ab893e888304b0759000f69b3f23421542fe5b3c3831f0e90c96939100763b12c05e3f5637034f2601ec3e7408004900fbfbb1c782a22480fd2a810a0120854186408a1348a63a93d3f1780864601910e000e12000ad9b918efe8777a64220489d1ae9886a2100c2388d7a3c0960ef82b8480087f908c6f4c54799639592a96427061e4b0238b80910c0c093008e252e440a04d2d0e72480439605f7db2e448a134590047068114800872609e0e770211227387062e089a36aa0400038a1148afde8d7185bcbcd61bfeec71d205388cd015286806f5323571c274725a6b231f01048152393008e06021443154bc713211c559082caf70665bc93047024bb1089e3dca1b17b54867196211c244f03d9c67f53a9d20c7c46faa862b9681812c0e91433fc9b7f5412c0298a828d138aa38d7cdf81274bd2c5b6e3c9716274f10c3c1ebf3d63d45c14c6248ec6e1c479820470e69100ce6c3a09e0dcc8aa8ccafadc881af00f6f9000ce9b6843c9acaf2f49006723cac31917229dee440238155d885467fc68830c16d10009e0ec44bf71b153e8681be5a3be49a450509872cd2590002e0508402bea71214220054451c1c53b12e22079aa104a168d922da790008e5e566df6685dec2e440a08e1625915c1040a038f166d22015ca1b123c534904a02b878d0bac6704ba5ca4ce89a0470654380241de2c290002e8a0b51924c134bc74f2ebf88864fae5417623a9e0a613054f1b1b74900d7232a09e0707021fa8e9984c262b60f65f60309e058ed4244c986d19e88e302fa0a371f951a4b02b8b44660c0c043f2342108a48890006e730204d0454900f77c02351eb46749c3bd281695a0d08518e78c2701dcc7509548d2c54800b753dc883620804865e9927b2b819e08da539d21900aa6e3215c2c98898770230ae526b810e3682cb2032c3212c0bd07924f14a38e484773c6132110c22460c004d486a8ba581a9b929b084d72130a04ca8c43874c4dc7d31868d5b1a86a784c09e4383696967824092480478204709f7621a2e562e8433502998a49c713c9140cca35cfc25812c0dde242cc444560a2ffcf1c43349504f0b813209674bcf35d881412c013381a6258bf47d4ca134b8030ac2f0cb4c1eb28c6d2f1a334d0309dc54b2e5a9433ca0b0dc2f0a4e3e92ce0f154a025e5a325a36fe1211c4d100617d004c5205bba20c44b171413172501bc00814ae561e06923020ea2af32475f1d799304f00ad0e974082401dcefd09c8481a7d047f4c1ab462001bcaaa3e414547ee2b8f742c354b1496ecb8ba78eb8683acad16a1a09e0d5436b2301bcc9bf0d1ba81bf2ac40dd7b02e5bcd9932b2ca48dfcc8c053a91812c05b4e192ba452d9e82234517112c0db88b2fb684c31635551a90e108e0a8ed51db3ccc14c5bd31017e41fbc0eb72e04b7cecf1b17e51d1e8283bdbcc2bd23220008a0820ea34cf0a942f2a828cf47d8e0d3a592005e14e0ac0ac74327fa8342c142000d7420017ca8ddf92427452b12c01732491abee849d2800c3c996557be2c0209e0db39cafe9843f3e58f4a4a75c04f6a8d04f05d439ba39300befd2ec409b5f1354e6ea86d5243589447b4217e006d68f8bb86a6e452dae32e05ab5b934900ff32085808017d4363832818101c1b43b1e909c2a00d010274a1173264cf5084aa250403570864cf5dd2ca754230103dfa5504c62204b2670ee1f22311185b47207b16b0efbb2002b30104b2e7e3c7c9ad22309b2681ecd94cea361681d92002d9f3c3b757db4460360601066d5c8823958bc0583602d9330c2f714404c6ea10c89e9b6a7c192230d69840f64cc9bd4d1481b16e04b2e78ec6bda62230762381ec992514e6260263778e55b310bfdd5e08064509235f45600c1f81ec695225202902638c0864cfa53b03fd4460cc2a02d9d3b6e5ce561118b38e40f6741fee7c2602637208644f58dbf998088c6918ab91e3db33ac080c3a10c89edc1e79a74560309440f69410e36f168141546aa5d270f46b3981eca965d4e62b02833d04224b8330e806b31d6725dc30e89bce80a59ac6b3ef3e220c26416c643d2c0564c0606c3a0396dee74284d98d47e9b3d0279fbfa3cf87d9e1d1d2b3e90c5846e1bbd2c689daead15223b4b68051fab61f6beb87d9f78c9462b028fdb1c9a598d9e3b56114c6793b3c4abfe087da302e13f4f6e3f44f5c880011c6844f9405a12d5d47cb7a47ca5227ca12c7dee3601b6d67ef0f5262ca27e8cbd219b0ec4e947edd28fded1ff9ea99a0ef4c67c072722e44986b548b982f3fd48f951ba7c74a8ed3378ed063357ea43782b9712c49b0ab26de741c93845b67a48c04733b8dd61182d6eaf65d1d64987beb6869ca0f28c11e807904476a393fd1c2d9313df2288dbe59fd236f6f26e8dbc638e219e3e3f30fba62931aa767131da7bf3d42cfa6f223fd8a09fa65e3f43da3f4841ff8618b9aa08f44b510e94284794347e9e37fa43f3a419f3b660bdecfa82e2008c2929d60b60b0c58ae151d98cb83108e9cce8641873626f60c0a6b0e27239d41618d76a8286dc728ad28ccae432043f282303b3701060132cd890d4373488770603accaee342a482e9e3e303063a7c70604020c8807020992604b38b13a80c2c242f4605d347b299b11109cc6e05f32f43bb0c98dd85121b0bf3db8c6605e339f8f8e0860cb3af1f27a6c55263610131d42b52636363618143a3ef4d74d4c213ef158ebf578b36c25e199bc8d222cc7e2b9d01cb9bbb10ffd830ccde020b4ba0ffefa25261e19d233930cc01c2ec5f589551e1995dac71276b4c0973d8d3d1f16dc25f1f5bc2a26568ef958ea7c01c7e0498c33396e54430c75a172299884a35a61298232696e59074215198a36aea933630472903967f3369ca06adec4e5c1c0b820c3cccf1383e8e256c8c59ba65ef85ebd45b9c07963f6cb9dc5bf5aa14f7fe507a917f63827a45f2fb94c7f13f17c953e915dfb605898971494990897dbce7c82ccc0be991e63917efdc91b93d239d01e308683281b241c3522020deedbd285914e674272c8600b2f162b4af45610299d82f86e42521792a284605d1de168f429b938c56d1e9421481392ba7213e6709035648f85e7cce5bb058214b78ce96044d7a22ccd93c0609145e10401521c35cb204fc9f4da6fcc9d493085114e63222c05cfa09b404984b7bac521435309703fab13c217ef4a77d0295ce82301102514befc8c48f0dde34a73585230273ed274000cc750fad3697d5f9fd360d85b9ead219b0423e3ac81f1f2dfc23f32430b7ea8817716b43002c76da85887e5f4e85b94d584e441b71616e3c75d49df0539e86455d1b82d8c84e3077cad4231a77d97844e3e1188968dc4f7f88683c1cbf8b68dc9d3f8d68308fc488bc3c38587cd3a4f0c0b3800e714cf2701e2b02cc63ce320fcc633de6e063ba8779d68c062cf4d5206a1c2b58a1a319415198a7781a88e72960c08ab693100ff35450e3e2e8d8d1783739ac90619e87637192e7156572501d23d19cd65ca508cceb310d5e799d19b0e2f9c9bcf2fad168b078ede401120442c0df9a34fe7ba81eed1c788759669e6648c0c27cc1d3d0079f3703565a39591f7c1b282c274259e08ba5d16830bff6f4679061be5a02cc77990a8b3f42ebb9054ba8a3fddfdce9cf17c3fc9204989f8f365213bfc8684d73d00fc5b1a71a230d4d9e0dfee3bce1825f2e58fca91cfc17a7a14dfed30c58e9d977b17f9ac2ced0984673331419b072e8a4e6c8287263ff0e72ff06ec7fb144f227da8d4926be6c7bdbb58578cf2e6ce916397a5f3356a4f273b19a1c11c773a3fa4ad92c1a9a810a707f9f811e1e352f2ca048a78f06addf763f141158601f8182c63681d469a8582096012b374df60f81bd743a7d34b611c73ad069824a50681a2c087231e059c17f075482e4e934b78101cf06264b2cb80d8d0212c6a3fd4cecdf0a6e2c13084d477e212e063c3b631243acd92072dcdf442a049063ffa185c13f513cfd2fae0bd251d40b0dff01f5b0b0309d4e87256c5d4651070be3583de9cf5b81858d5963db3feb358533a76102e16d0c78f6d02413fc85303e937d3a0d7e65c02a6b278370a610048ca2706cb9179ea9349af0fe4b167be1990d7f34eaccd72362d98ee5a5d3d4aa08711a5a157160c02a5f276b55c4970a01937c9bfef77d5ba47b3a1cb53260d5d41f7c3bf6effaf60840b0a3b69c667c9e9a838a227fb4a5e8191a048c7be898468560d1e1696844b49f01ab0e4eb69118272ce138320e17b39a464d62260c58cde7fb81a8181c1b0b01202ce1c548678c0c9c59393f048064d48058586c2b0102c819f80c3c1e16cb4353733a0482548a13451016db4980c576c06a71dfafd4b2888919f80cc6d84ae0ff2fbb5c60f158880b96941df99ec6b203031f43d67cbd88ad71f33b47cb19b3676bfb3cbce51367988f5f7b2b6496ebbda4ecdbbe14141fe295dfe3239b9c8e1fc94047f37b0995bfb959019650a48d4cdf482e18c9d7258c200e58427f64c8873e449f59a1bd375f94cb77b9312cb106e282f9f527d6ed59ebf35858228ab5a6064b8ab39ed2d1a70c3c914c15148525eea2c37e89dd341a2cc99acea0c31247e269b064034a0b3a0989c212a504723a1e96b8c15adb8525ae8d4768221e968865cd7508914561897e029e064bf4c641602c2cf176746a60bc2611a2282c294480402a2cc9355a880e23596c51d06f63cb32209ae57f17b947e4935c3c6a2d322cb9928e625eb2df8528280a4b16fc9fef94a0d22560c98a7406acd6ea42a4d2c560c99a51354c8c31c9340870a08ed481aabb9b024b2d4547ee1314233b296029be118b482d9ed847014bc98d6a85e59852f309b0d4bc1f1c73d2168a1fb74ffcb078070144d6d85f2a8e40a682f6143ae830b29a0c4b05a0a5743ae83096efb2e6cb68e0c422252c554885a556ba1061a9524a2c2c4570216ec7c3523728b1102e0e84a5fcd0927b14582ac38548ff6eeaf5bb053e58aa9f4287a50e7fa7a96f631f3f758a492ba5b0f4022a2ccd35be38084b9b516069551722450496b61d5d3d632941978187a5210a2c6d38b1be47197f6b130596f619798bfec35b3b29b074e8c45b64c884168b151685a54f1360e962586ac885c862a52a961a07c2d2f62ce0423858fafec883f811238f454b8aa8e878bbef29b074d31f572361193ed662242cfd7aac5558467a84c33f52ea8d50ca084fe60f80207a1ccaa18c330196711ae750c6338e1a3fc2e176168732ebc61fa02c9bc032b1230fc659c667fc61751a96c9a5c032693f725239cac9be094e201c95ce62a38900cb3c9d60e30d9d1a3bd1c8d8f4b3cc109565bab18664675060993e96516425ff6814590d0a2ccb3e49e86fdf7fd020793a280ccbba106059675856cb8548a4ea32f093f771c0b2110458361c96d543d9c2d1c0743c0d02a9181a8896a51160d9545876910b71a29f238f28971c97804a255b4c80654f8d4b255b99404d0461591917e20e967265efb11ea0cacd642957b665e441fc88faa13850f73b7ee4b004580e034b635d8844584e60a43a13d43419787cc60e7cc60ec6f6eff42aa74380e5168c7320b77444aff693f40acb398d38c41fcc251732622e39eb9f005b2e9900cb6d9ba877cf1f802d776cfcc104b0ffce6e2b58eeebf79bad607901022c3f03963b3bbed36adadb5460793b2acb67d2f1b0bc1b8df575d21601583e9c00cb87c1f2a213cbf6accd0ccb03e1083f1bffe075863838282432781dce7ba3a7b7b757042e88b5992106dec82259190207ff9c11dcd8960758be01d2a0b16223cac4732a2cbf114d0ffe74bb038cc35260f9ea499b1dfe10b2a9149a3e3a7e6005665613383d5a2c8ce361455f9c192d960ee3a45d88306e256d34f432262d5e212ce3e302d1c61259c687719b50ec278cfe88834c68603c2b9ec0b8ed104403e3583f5006c92c068f50e871304e1d65316b271e3fbea2301e4c71d72930ee34cb6f71f726fbad3ddaf42b0a8cbbf46388c00d1360dcd038e414f85950c6354c82f20fd6f10f5e0f07fa7be1c2bdd7458607e3d68f5a2730f2977f363ac93a0ae190f2b87514b6506105b15f5b47219b022b784fb20eac707a1c630ae513181bdd1d022b3c24c00a0f7ec49821cecbdb33dc1b8ef0f6c2c18181211be0604f6f1cc93b3064c38814ac4d34539342d1009a352e85a219155668fab5148abe145851635c8a1ff4ba213c24d817b72e24c03b78d4b126daca81a427da3a498515837fb97d0756aca7c08a59136dd96d08864981de86b860ef0db8900dc1dee138ff8849bb8646a41fdd3b3415e995f4a0d9e31c29995261c527bf965ec99b022ba9fd417a431c1c1a1a1eb2de1be7131e12f4dd2ea6118e7ecdcff71cdd98842aa57a2aac14f81b8e3e5360a50b7fcad10fbbaa4638fa353fdf71a4ec06298e73a4ec4d8595867ecd9172220556b6f98123ffe088481f1f7f4f7fefe07513b0fd1e21cad721d989b6ee516165c6af11a2fc89022b97fdd0d6ba703838c2c73bfc07838c22e437069924fdac5593fc6396271556fefa6be967c553e059d67fced11f0d32c2d16f00f21d476f20a5098e3e51e159a9bfe668b624059ed5fce71cfda19f228d45c251f3fc9ea3d9d193bc68763c159e8dfb0d47c728f0ec909ff8b5271c1838e2d4c121eb587a6279f92484cc7e0de126daeaa3c2b38b7f8d1015710a3cfbe90fd24f61cb21ace204c98fb7a5b2860aabc8fda62d1a0556b1f8a12d12dac1fc101ac2bd23467d1198b22faab4430a131cbda7c22a49bfd6b4aa28055679fc738efe6877d4e2231c797a4f9923d58d93a2832a8d0aabcafc86a33c0aac1af0078e1c83e1d008bf10b45bf642adaf3939319b68ab15129b68eb1d15562dfcb53dd4665260d5477fda567048b0f746ff88756840f2f7fabe2d35fca448a446a4c26a52bf692b8602ab994db435bd4d9c5322179e9c9faabd1bcf1dd406c77307589d8700ab73c36a68ea4b45536456e23074c8cb3fd4276295a2300e42f2d627d33db73d2e215cb5582376872c7f78913f55a7ecc1de0bdb63dae58dbc2242023dcd002e6160412588987173ae8e5b27cf4f7aff45cd789beb623d3257a7d987e01bc744a564495bf45e22b622f60c4299f92c7e0176a0831accecffa49c527fab463d9dbd2e79fd368b79a54903090ba6f507d4f92ffd8e10198bcd14acf8bb6b396a37973eeab665fd31772387554c5dc6d1a3cd9ab752acde3d37601a2d8f84c0a57bf5380469a7af9f7b89c86fc9b58b0c192ccd59a7286c622ab7e6a09ebfcfc0f21b9b3e5992c29f71debfffdd611b7a13876d0ce800cb5f8a85c3ecda17e7473a29cbf408a595fcc70edbf8e7fe1e58eac4ce7beca97babdd2d73308addc04600589c8f0531d8ffd2611ba00cb2cbfe17f73d61b4b51de4257e51ae175e5774fc57e509aa949cdf1d8651a12f5e5f107db9d63d717763b87540f7056e97eaaaa13967a8d8769d756bdf3d9a79c6edee968c37a0cb9d3da27b9f6f5d5935bb5c2e7287cef5eaab83fb08363586bfab3f7cf0525012670ea652ccac4c26c6e5f055bb3b4c25ef973b1c3f53da9e2b0e58b27d7c224917afbe5690beb725cbefe09b6371a79c5e2846dcd8c6df41db79ffb169258898da3baa42ebdf0db917bb9a2cd5d077a0dfbba64e0cc3c844b7d8749d9fbf401859b196193df322d703cd96c48f85ae9d4b86b6bd791a95b369e9c0fb28a28b69ef9cf18301664deb608016bf37d71e0c959c557940e6cbb1a57cec4ade78b41244f25579b61edf6a6a6d76d63ca67d97294dbb708de30701fed8f564eb87678ad6442378d2936376699f3a9c382fec4c63ef70680783b006da4dd7f56e78e75ccc9c1758869d0f30b11ac871f35bd1999e87be191938dfd876f0b0ddd015419fd398c7b6a53efa56f77a4ee54ef96f873d9898e632cc130c13f370e4fca7ebe38703dcfdaf9f96f30ffe41ffcf4ecbc162c1bfd5c8df3b2da7c7eacbaf4fcbd1bff1ebd3706c9ffdb2fcd37a95df3958aae660c1e0aefb222e9d22e1bc5ca5ef177a540cd51faeec332c5ed1a85ea4f676ddba35fa37d9573ad7dc32ed345ac00ff770d739c8e4ea7fb4b8bdcf791934f0bb536731361eaffb234b29abd5df955fac2ab7b19c2556cfec5bbde106ffb621e058506ca45b489b4468bbef57be4367ed45d7dc3e15f56691f5a5f26d5767ae38793c31d3c2b4928c34dfe792edf7bf8bdd30e0ec5c34681054a83127ce17283930c7d007ab0e3db6463c664458e262a5afc7a45775d83bab757a2bef29e5fe68a69751abd84d0aff5c58862d0198d8d3c8e6dc35a56a2e72e27d43ecef9bb21796f6e2b4df735679c5ec55727cf075c0559d46c7982043f47bdb0566a489bd0aeb28a433fcae75303addac5c5f5fa06e5ede8cf3800ea11e0331b1ded33a8d1fa3504c6afed92132afd72203576cf6166c8adb6e9555bc252167be5bee7fe0f449a4f7d529f2d5f52fc436ef375ab75144e4e31ed1f6595107d3a2f2b744b57aec588688cdea71e0b0376ad0d0400849cb63edcaeba859e40b8f3e712be8b31f5f593d84e61d6ba79577545569633092dafa1b485b07773c3b9375b1b6559d9577845ea687b5c52a8add5ffef9eaf28550650455dd97f3a2a293b9ddd6d32f228ea722162dad9f940645b784ec5b70b92aa6bee240f74a64a1dda2f925bc1ffbb615fae4a2bc38fd3307da2cdc838481d78d8fcfbcbe92a9738570d113b83958cdd79122eab161d7994b455d089758583c367ad68b8e60da9b3de96e4a292b6bed77776e5ab0203aea2e9735b56de4a493a07ff6a4939f9d76ffaf38e9e4f5420d2d4d0d3fe7757250c93262c9cc5ebb0e19cf83afcf6a9c2fb6555bc15b82cc8a765d1cc57d4c0c4aea945dcea66c3953f5aa6258fd76a7ba0f518dc9ca6fa44bdb8181570865c52b2b719a4707e7cc674dd6d0d04be81c59dbfd5ecff1add6dafe8d36f724a7ecb7a4819de3b70d89fe95db86847a8af42ec6eddcd8eba9a2fffec54cd307a4b3d44a32d27da963f95a5b5dbfd21d5bd45e7da9d9472d7e5ec2bdc6cf4eb5b7bf490d799b84444bf2ae6e911e6a6a150a65cb977bef5505e1d2e6ca5f176e1754d1bcfbaa5db20c0c0298a03f32074e19ea482ef7d66953ace9d20a95d54830da146fabd5b3b6e1907069c9bc5d5396d48b094aa37ea1332dbf98c7b620a0b741aa7afdfd0a7f7cbbfb7d0fcc8037cb907b4e5e153a6a6cccd979e919d648759e5d9ba79a68c3870637e9baab6edcf96b3d9195cbe1abc78fe6c404d1d6cd33ad2c49a6ea362ff1c25dde7cb630fa9c5ec5ae67e339941cc6671a3994a7b4e422f752874c152e1fb354dd7a4422ffa34b2588cc30d4de56539ab1ccd43f4c90a344a9caa65fb238cfef4a71824c5d453bcf85b588f7cb8556a722dc9a3738489ceff802710eac0fb9be769ffe605a20efcaf5378343c7cedf7fa6e45780177eb2e3b367e58ea36def7431f9e7f6de9f41b821db53798693ff55f994f5ed3372fe7ef0f4cecefd0b47184ded50e8778a09af45ab62be7eb469616fdd71fe1b368590cad96452edfce66c5d9155d02b448291cd6598947f50b2e8f40bd2dba3f2dec75f0ead259e6aef693b659bc85e2d5986f10398182fa4467df656d292f543b948c846ae27ecadbd315629214e86e6af2d16087d583b77c99415e4c7c4888d7799a47fe181cd5e87cb35f15bd6ee7549da2c58a7d3fd7a79a397ff12eca73cb677973fec7a3b7f0db24cc3a2648656a80e589692641f722c090857e9ae52b5caacc5462eeb4dfa701375c78069b96368efe226e1c30098574ec2ee513bdbeb3cb72e9065def5073fa4be316e13c3c9ab0b7743cf5b6eecdc2d6c17b0d7f0915982baf909291bc4daeccab7f3f7522d021ecbb7765db43856a27b8fa47162a3e1a0c2a607e75a375d437971fe278e7d4f42b6fb9a78bec6da1b13b92e1eca6a2b709dcbe3a12f351454b72ed0d96c438af23564eb7d8900dd3df5ab0b6fb53d176e219c5eea6061aebcd0202e99c3cb4af1a4b16b19580d30c12bc88288e604bdeb98ddbe0c53c34b47d722c7ceaeb76d5eddb31c6f9cfea1dfb0e9f094a1b69609468e1f74a638f5dbcf4044e75afdfc17caedf39d06dbefcc34715ff1e933fd5c5535ad375641e3c23db1b52b9079e5865c8992c72ed5e50ce95ec67646a5ddae7d548995bcf45c0eebadfc98c4f393a4d0e84f118e3be9faf6ddcf102e52ced3f5764df2fa067eb5a75ea70d050ec4b477fd070ed12ae7a9bfbc5baa90c3345a79cb97e75a6c0fb27dd964aa579df6d8bb82e2f1a6e332a2a0f526a93455c131c93e40f644fe0937578ef50f4c254b1845a09ce02645ede2324c1dc0c4d4200ae6f194bd6da4ab7b376e5978a2f9ce85c08e6df8a84fabbdf44ccf2f9bcd85659fb225039998ad932e5ec44ce568ca1fd3ab85fb7456e70b06cf5a73f2746a90bfc99502d703772797fb24f069e57f4e00927b56fa155c9e9b207d6ca7fcff7a7a554946ba3ccf168928dce79fed5473a262d623e387af7dc959331e241d7fa57241d4d12d1309ad192c22c9ac320895f556313b223fac82975948d4bb676c6da3aa39cbe64b77e94eccc076d6881f8c9d04d729274306af0ac3bbaf34d6b45bfbbf56583f2f7b11ee8d6b258854b4be6e93c2a8a5ad585825b7babe46a46e5f6a99ca7d99e836c32f9a335e7a1d46562721da1b2e447f34dbd8e5989ccc56646af1f90ec5a64cbc546aa5c7eb3e9d323438e9fe33f9fc7611e2666ffd4b5bd602f319cb3b0f54b938575f1d006f495eeef572b0c699462292eeda2dce6baf9223d66df4b1d551106bc052eb5fea751dbeec7974b6a8d4375c19c80d304176c4eee8c74b995eaf8cd87949d9333d9e35f2eb29343d152268390d2f7971cb392568ca900e1e282d3d871938cd3aa5edc5c4296dd41281ccaa334ea52503fd77025cad78760824efcb55996f4d2e35e7f6c83bfdf7ee5b901faa04912b56add25970f83771c7900a3e678dad2762ec782282535b12cf5ca075de6ddb8f2c7c69fa7c26b8cbcd8862eb47ad3db78729b142988bb24266c7ed93359a9a3be78c5c8dc5f886e4add54c8f28ba5fde7c83cc10ebf03a1b156b5a74fc134fb631b7ed9a8d53d644e8c8d5582153396d3d09a940c0b0dcab5c3565267616774379fc12be84bbc794a40fc52ff4632e75333744a264670708cef5dc1b710d7ce32e8898a87eda8a0935ae6f280998c9c7b3cf6e43198727c0e45883449f6a0ba3056cdbc5bdec80b5ca5efdc282aa24fbfd166b0e3ce8ed64323992be4c99ff702687d0c8d5584ad3bf1a4bbd63bd5de5e75abb1ec9b977973614fb952fb6f4ff5de2fb5f8e4953b91a2b09094e91cc2e7838ff3c69d12b45be450bef6725c5455fdff1a5e2ababa8515f4e6323027a3f2c189c3b3baea14b48dafa74bb732678413c94db499023e2d3303975b7c3a4782ff1d72edafddd70f9d509bb66effe0e1b6d46da716ebdec6d94fb73fbffe7e33d88dc5493dc4f69e278efee965e5ab85b7ed329bbaf72314733535f6dfd6492fb4d6a0962dfa4372be41ac7c90277c255c53d350d408ac05320a7a37cf9ed5514c69e24e7c9eb3302d594bb5450eebfbe3e03fcdfaecfb003580cf8df99dec5e8453ff53cffabf27e05c6c35f94ebcbd4a925fcaa7ce3f69d06bf9b7e6513b85560bdd93a49353fb7494a6b1746e831c702c6a1d876e5b79ebcf147b419d7ec367bdc3e367859be6fb82af7f88e142eb9ec7589273adf9e2899afc53b58dcf1bbfa030d1c33d7c6f5a53b1fef3b3d3f4a78759d74dd9138de77b7cbf69bd9b8ef8879be38f49b6ce2f2b673164a12fc396a9f5235e44b186f6f37a8d56749e429bffb86af242309183933cb8a8b579d95e7151f78d86efe5e9ae78d85c8c5855497bbe5f03ead14c45cafa7e3a094a3fac1baccd5c7fa25edec1b3514cfcd5deee4c8b1fac2d20bcc54345f709956bef0b3cb9858f9c2be8470bb752598cb745a97ca9bed6fc181f4e5fbeeb93fbdd61c124d5d3927a41b5987e195589496714d78bd2397dda645ba552be9a488c88d38f5e379490afead1bcb30960013638ed4a79a75dc8aaa5829b541b9981ebf6c16ce3de4f66ccd859a42ca6e09a6ab3a64a6dccbac6382fde3a30acf298c2afed7c6cdc203d073e52fc9c5d1856d2ee485c7300a96aaafcb94d9b59243ea3b691e852b10310db7974d7bb34befaddd3fd79c229e6b2caccf99da7a2685bd2d64cecc1689443449089c5a9270a66ecfb7c5f854bad8fe1747973ed7fe665ceff9f298a3fab0ed5200c833492222726aaf13173ce1cee60c3e7275c9f6e72909bb0a4ef03759f4dc4c9ef3e6957786260a25bd694169454f0bffaefd5b949ff1efdb9c9d78b007a4b8e6b278c9feb0dd25e735247a63f91ea5f543c6516f37bff5bba5e4aa77f6cbeed715aa05414884220e5ed34bd3166b65cf6b1c50bfba982bb167dfeb3aa3eb360749f74e0af18edcd3736cf62646c62ee5d4cf2b7d9f9d3dd69037df85bfe2f53d05db7a24660dfcd09e7bca405a5f598639013031054834cd27d840ed65fbdce1ed29efe35d1d0d56b7a99b15dcb50c5d56e4561b95866640a688dc96eb7d31a6550a671cbf3dded3e16f5d737ffd16d17bfb9f25ee2bb2ebecd61d42abdcc8c41047ee54cc9db8539154b7fa1c3692ca79d0dba495d3337d0e8d0cdbfde14ec5e06a7e0f4697d190b05ca3f991ba47ad75067dbc2bb3de9e2bee7a2cde607d4216d9087f783317df7621578087cbcaf7a3586cf2d5c44f43c71d92e62a3b50931edd1cbfac80f2723c83f6a21e2afd79069db37467a0df6f80ca5f494616dfdede5c6953f16260752e9c45dfb55d2f89246bafba738ea543f91d2b73ec5b8467f683c7cdedbdd9db3747cd122d19d4513821c9ceddbb555066f3f58c82f9dbe78e4cfe87feb393ff06c5a11c65cd7389d5d66a7b8efbbc78710b8a14f8174cfe27222efc7e74bd1c98f3884467b638e3ce7be9aa1bb3bb8fad70b5a9ef2a983b33e50e22d51dea5bd5faad78de90fdc10e47a719853cf88557f248ee811ee73755bdecd319c3abfc5094a9652370b1b3dcf26c9c86f2de70430f8941051d67cea297596215379029e3350ac56bedc01de5e95fdff7bb7cfd2fced426223c5a417509f4dd15e77862ce6f0bb7a19d3da3607cd46367c8b2afd64bcc86eb3088de270a5620ffcc1981270f36e987e55fc8bbaa3ba810b7dc2a391ff6f2341fe41bef1c38a6d039fce93ae47fe5ca7932b2abd8f4e3f2968bd8bdc2724eab07f92f55fb9bd8149dacb64c322a3bc07ee6f900e26ad07265de1b33eea017b73825ece4dd42031b938e852df93420baa433509bc2bae38df0cfdc0ace5d5630fc499bf0799ec0f5708dfefdfb1f2cf55e57ed946c3fe3b2b269eee134552462561897338effa6dd1dac6b67e497b28fcccd356e4edf743bc55e208df3a51ccb40358009ce426abeacf7f6da35436c2567a30562fb44f8c4968ff3961cfaec9fad7ef6cdaaf076dc94f11a3dd058fa1033508f5a5770c2ba34506470aab81568ad891f72af987f39e07dc232832e8bb3477bfff60a43258844c62f4d6abc7041c820aa7ca8eb90fa4afb55a5060d73bcdfa67d01f1d22e895710f0a29dc40185561ba6733bc375f70c77cf3031d0d19cdedd7970e155c62ac7e1328e4b0093a30c79f2cc033b57c2ed6693ca296fa5a153cd3b8779a343797085bea4797d6050d8d929eb6a2b9323a0740366601daa2cb649aee0c09509983d9c117fad99eb46a096920e277bb673a08564bc28fe7353deacf9e44a32725ddba6fb2ae35dc2e2bcdb7ef657ec8f3a398b8a6fe67f6a305ce0ba93c195aa83ac53e4d7319e19b4ff63b8b017f6a60878bc2d7adecd4d34e6a9259564770c1e9cdeb46f74806ffdcf7cb029d5bbb653c2966d9f907d52407ae867cce13cb5ffc0b4ef5a3ac1cb77bd096753e04b524b4ccc815877aafbd61acf79f35e95cc8d18e0a120562619f47ba927b5aec327331478b81047932fcb2ccc17d9cab8ba8349ea7d8746ba3dfde9757bbf9be0f8d7deee71108b7de8ca57bb7585af469878f02da924cbb59cef3d4eee8cae3f24d430d3b5105996bf5de9442155f6e88b9365874f78e428a5ea55dd52b418548dbd1e71ace034f2dd364afdff91abf8feb93bcb7e76151f0788fd6fde59f69babf6def7d5fcb2fc833ef9d7bbb4dc7ebb8d727d3a533d66cbad63f39958639f2417d0698f032757575fcf5cfe85daa0af87d5708874bf6af5fb85079b7702b33c81dc5df197575665c7a8777677e3ee76b697fdaefe2dd9a9fee147bc1fdb575d7ec031d83ab4dcec6ca67db4fb01f3fd29ef2e8671399a9d5b32e38b2e8f884bcaeb9033253afeebe6846d4ffb76ffc5b194d3fbd3a50edfaa242338eb1505f72fc845db87e6ceadd83428bff2c88b6a695fafba9d05ed73f63c73388e2cad5f926960659fcb5917a0dfdafe285fd3ffc2a60fc9ee9a51f5a47cfd4739acf5f1b0ff89f5f144c4fb66d5dc01e5edade5f107dc43afcef9585ddd1961f36ace66a354f7878577536621a6974e35d816ac12d3098e1172ea911c7cb2d0acbea06cc6bae7372ecd3ea854d930b62e40caefaad6ac99d958f5b44d2023bed3e77c9fdf4deca768e323891fbe896337c64fb9ff224f5e176899b42e70f9c49fad0b6caaf165fcbd750180ad928cc80cf9c6e49c28b1e08ebc40e2eeb06d9ba9e4cca315356397a68e0cd675ab6907429891a8bab7f2c693e39ed677452b39795c783dddb08015724f29bba38efd464019d80430c146a48922e81e6cb6c87c83e860ca37bf4a27d3d6fe84fc790ff82b4fcc3159c6afdb39655d509960d27897eaf52fdc2b90adb9fdd0fcab0642f34fbfb8850815f7f21f0d292c3911f7a2e2ddbbc4c3e6f50a888bf63259cd0daf766f363f6a6d2dbe897670556fbacb894afdc646e2a0fc81072bd0b476d5b4d2da19ab92755615a4cec899b3b5fff63e0b8b38efaca52ca8575eccd6f45ba9480adb36c41f6bf964edaefe07ca225b0a45407089369d90ba03c1cb9eb23750ad5ff385d1631e98356740acf123d476fbc5b1c3590ada816ef53565986a8089b982043d894ba3088b75787ceedb967931f623b69caf77c155f8ead2e2fa6f8331b93e343a6629d2c8f398a1608d8d9f4dcf95a05012771cdd9fae4eaca7debeecb9f1fd92ea6721a879e94c4c64e9da01bfa0a94deab464608ded756266dee0caaef6edd735d0e1bdadae6063717be1e6ce050673027510d7fba73bb35d796c1a1fb1edb86bb0cb6837653342eb2f6fdf2390d6ac7ff97c0b1a780ca61778fec2f2cbd436e6a463d85f3ee7f0ac9634b8eee738ef86eac6971a430ca399da2d8e0e3912d9bb1d1005a3c53378b7b5f4377f7d12ca7f29e78a28a088b49e594c8d7b7420b7e52e44fc8b9bd17fba918a8cdc483ebc45c3ed3e59cba0d372e92a8147a106d5ff8fbb2f0f8772fdff9f194b832c85ecbb644b96905d681864295bb652b66c59b33396c328644bb678b2644d945d458821eb945df63142488591e57739ae3aaeeb774e679cbabed7399f3fe6afe79ae79ee7fdbaeff7fd7abddfaf7b1edb92ea14987071ea8c13ae760180e9cf04d615f5e48c0a3067222b9f4ca90b43032ccea3a43229571218527b78ab0ad7f3834958c44220f1fa091f2bb4b48e940f16848f4bf1f8620fdb67b3741620aa54e842cc98ffbf68b83f4edafd8018b26d41a01fbeca16b49b1d7f0f9ea4a1631fc813a937f452dd50577479dbfd963af4b542ed2903e1e09b6c6cf6db192f7866318e11ee628c2cd242cd55a415259f02081a0cee86df389283f93c5a5f0d7e00c281ef0357aa9a7a79247fb3f4411fbfc62da7abc87e72e87ee1b08b4c71f475610ea9462fbc6772180eacbdc77e5d7f6dd127cd3296529da988786d8cddbe6e96355d3d5a8ee83f51f4813d4d3b19e4dfc12c3daeb04eaec59eb8f462c2502e3d54e6c5a171a608394934a0bb22466f94d63d3c21debdc46370ddd1b53c37a0a1d4c88ac67ae3c5333462ea9b8896b97ddd223c4a9d4885c572b455285347e24a610d04b97089c99b533a10e03a873746c87d229afc9f89e81cba0c354191ae561356034037a1c489f0158ee8a745340200483ce9df7d9e8d70a0975883d1896fb55dafd259179b9e164c8c8c2f51862e03015e386fc679e32a7e7a018ff366ba48e262c226cdb6279467259342656d8873aa0950201c411330d299e5c01c1948155071a66004c910529d9849d95a363f9f365a77cc93f1550bdeb1ba8523b8f9070b99dac7423c607fc542b20d1bfa7f928510d58381cd6d53472f92b02cc97b56fdac19132a67fb8802e8275e87c355830b9b97d20d00e7e177b1728d2c27aac86cdee4918c8a0c9cf88dc67c715bfeb9879931f3e680c477c717fb411c5f66fef90bc2be304b87a3f04469d326d457b832f3631ff7c4582b8af6345de9c3802d9629c9fbf69015268922da35314f48e32dee9a5a68054ea9e5c28ed74ee79bbde5ef74b0e5ff6735a8835cffd72eff73e9758e85627e60a38e47e6120068788061eb6bb68de493538bde6225ae163e8047a05aea293e73519d2c860c2d6627484a8cf02bb25cb12ed5f418dd50d466cf2e2fb884dffbf75db4b95ae0561d9b74e57e18817cf2aefefeb238df9796c9d95a22797728ef14008209cc3223e7b33448df67642642ad385643903e51cdfab7c6a2cb863facca2ced922ca95fd1ec89006ab7ce9a57f4083569b3483c1ab8e63c56a71d04e39924b359ba669de2aae82c049c99469b64caf1e6b0adf2ea4d9aea1a4a170482c71539513d172291aba76dc9bf19922ff149130a278dbfbdcae75458de51c4a6203c9bf3ec8edf45736b939449d68b77f05eca917b8664b77f89e0f2dd843f2be5bfe06c37c7e7ce78b96d16c2888ab62d9b599468adaf465cba7611a0b32d6a7d4333c14b61de3f4bae014f78c0fde471ad8e3553db75f1f6ae681fdf6a702508077e0a7c66ab3c6278ab9e694518ed77e62502ab8a3dff86d324c4aef890476a8013cb32de018ac681adbee70ce87ea7096deb8f7346ec5dbeb77c0fb411911e9b44921462d96172c7da939a26af8a97192bc7982b9002fc5c370280c63e54fdb272c686ba0c99f0b62f5557367965c6fc8add35bb39d5efc3921c64d813204862166c896880e1716ca776bcff25f233a41b30bdcec80c8735c3931e35c071770b2abea98240b9a6a5b3b9d3d44ccfe966faf22548b424c2cb4f18762106bf0f4bba7f1bfcbb618bcc54f886de7d585c199b34fde2fdc4c68432457c0b56db58f1406447a3776a01e099106d21338488beb83c04cdc9b09c8531323fd112de6e17218321aba5da73f6fa981730f10d9a5c823e6313ae62759d5802d94e63b567b95eec225b57278582b57b434221cac0430da8a12fb0aaa8d889b1c716f82087d64eb2357f00053e788a0a826b938077718ba9af26a205e1888e00d051651e8139d4e455adcd12d9707ab3a31fc37cb050aa4eec6d18a7fc64e704deb78cc31136ee39b9380eeee4820f59d322636a7dd80eb378cc45b7a8587d2c8bfb97e7727c9c5c1180958e7bf66cb31c2832e6d92cbfeaea369350f6adcad2ce8bd0abf4592b95c061c0e76e3dc1722d98da4d869da7c7ef5629249566f45509ddeb410d21a7873529b0ef12deea3f28e1e7c3328349b0a7d30cb8238094cab4b35fdb481f893ce41145850919e25eeec40146812ad8d5ca693deda352a6aa794b5845a273b70b02edea4a2451fc3b67b00adf7bd4c4fb17b9701c9e5b8d3285fa8ad767f10ba9348773e41f50a73a8c0586d6230048340a639faec54a7a41354b76e3ed8c95c38c1b8d48a94b058dc290d8a5f348e0ba2c751b91b9c5c504e355c932f123d471500f849d183cd167ca4909d3ae706f8faf181f8caffc5971e17fe2805ad70295920b5a9d425263838bf70b46a9222cf7a61b51086dc6b593f6b3cd9c01c0b9eca50f4e2f9008b113cf6a74387448aa3f4ddea17f55e43a1c48434bdf777b6e9743481f8843008b1c9e9a4bfc3c748b5276ab41819fbb1eb64ffcfe5b8815cd1d578f267de0b5e7bdefeb694a003240bdb8f7e2ec08474d90eb95c4866ec08d596bc9d3a8fa7a029d92896c9d7205ec29347fdd9dd9939f81ede3ac2f895b350403c2412600cda3cfdba0415c57a268f97f0b94c3c42852703a600a8e0b1a093ced92e38f4bc73b2f26e020f17fc881e9fd72a0feafe480944ebcee4fca01e27a04c0c860ddfe7051bc7eb0a83d91c8d1adfb9dbff1e711afb420916c1a448168c857801663ebfd6640cdc2103ea137b53c3569c3d8290f49f778c7ee956ae23e9a77631718f70301036f1614747850728b2ccea69d31f7da90f2e649ffdf136172a4653f307ef37c7698048c667d1ab130a2d038e55cac055e5b966c0dafdc02f469b55cf2c4ce0979255defb21f7fcff3fe4d09ad01a8aae6e3c7cb3e8dbe92647b6beec6afd508d7aea6b5f9b5e80c8b8ebfb6a63a9fe19060533bfd9f58736ede03e59943dae5d4f5d2023b3bc4645f3ed569aa070c905a0f16d6c2f3357b01d618cae20eb22a3d78cfcc391345c93bc5341cd657f559adf99220d8b4e3d43e7b87425fe7cfa62fa0c12ca9156b8d0d98dbba63693e6942433225f4b7e23af4d2d9d3f09ee589fb0e851edbb7537d68feb9544df8825c8d58c2ea5d17eda9b7646f1972b912b4cd593d3daea4aa7fdd24171850060ec9717871e4d731a13fccd527f61535e6de66121077b25639db5434df9998eff74d13e47d72e531876f6bd159b2f913930ce6c1d5cd4b37d846a2ac6db891924a157d783f69d29e2630399826f8bbe4ff8f354109f9715213553d6355818a76497b47c63838ea5e780bf7a6acc0c8734c54f23d002a6496d48b75f832a1b166c472c2c331f30282ea665e66607afb910ee913fd65d5e065100ebc00385e3ff17c6653d5cf74b22d92fb26e1dbbbc76e64a8c06adadd027da92ba3ce7ae31da0141c38bdaa6bbd83f3e006a1bfa381ffb862acafb37151882a3a81d95db79a7fddf8dafb23d0f317ae425978529fd75241474e0214c14484665d32d0fec3332dd45c0587f3a1b26fc3535a9e5a3b5f6c77e10dc3ed42ee7c30c8ff0167c50f72494ff10537e788dcc75f4d89233b121ed0849324f42550e4197af1850a4a43f50038abce58ab3fdb97c36ed30123e501299fe6ebf2da57641bbd9b1dcb03099937aa4640eb830076c52e4344d96b9ef96ca6fb43274ce1cc74e33944eb0aa26068f0ac8b0f78136fc0d3d62377370a995f711432027846dafea4b6d8993d0379a682c943a9dee6f4c6a7fc49ced512f9ee8af75ccd148029733fcb51d39b14e82ee9b595c9de3ef74bf22a8e3708300c15fde8cd858d8fd584c6201ca10110620cb2dca07add2e1f089bf05473c54595d984131f2a80c8b71abffaf8b05b10efe74bc71142abc12238b050f0a189507b385a3a048c284ad097a4a0acbd6c12553ce855c37cc8189e5e7aa80a51d5e442079bfc1b18d97f6e1a9cf0ffe1657be0dd8fee6d91e55afe37e353fd0e04efac02fac9a94f4cad36da0659fcb6342bcbeed3324c371202b87a775843f50601db165de5649f4be414dc2f83bb798ffb7c8589bce20c73c435062f7e94af3b1ff42d6693ff86983dfa51675f8f6cfa87dff7b26608c02b66a237a8a21763730fbff1e4a07edfbdb3c16b9dea0a3fe7ce503094af258745da0090e5de0f61f54a56ada14cc96aaf06ecd59d079f9e66582c6e49ba37a8da1f4ef12d6653ff869845fc44cc88f9d93aedf088d92de0b4d2cc1d27ff88cc42bb64abecb0e8471e8f6a47f3087afafb7b1727ad32cd8d01f2d3495b1990cd378b4c02a26cbe16616acf95b86256a52763c96322ac75dce7aaecd66d39f02b77a22c6d0d3e838dbcb70dd36a1ea7c913a4385c6e34cb4737151de14bbcdb3bce02088ff0760d8b2d7bc35081bf853b16d7570ed2081ec58683bfa87d40bdd09775ac06278270e0388081bbbf3f5ee87295478fb88524da5eacd4e77e0955ef619a90d202c8d5c2bc28bc930b8003abfc210f30fbe4c1a3eebf92078a2f29197e4e1e10c8d58381a3626e23fdf14f1b261402da750767331a1ca2065f691dc73c5f3575ce545d4b02fc4ba7e706f5dc8695dcdedd0e7abff205414f5e1d298c72af3c26d2d1969fa2b29bf54d7f4dd6b7dbda2229b430599e9b12324445e545da2077348bdb569c4607e60760845acf00a7c6f1ecac116edeb5e2c910dfd4fb7e1b8ae9141a3b40d9329ad3cace2dbea01a920ec24152006e228e37d26766c7b91b5649635d7bc8a4d0f3062b264ca03b75cf08bb86efa3f106261307d1acfa0a595fc7f3ef89c2da7a6450cb7f527b29c7b632ddf7a0f71098e4f017687ee03607e585fc1f38125d241db744eeba6ee4396707dae590296a84d2d05b8e7ff22b1c4b22ce0eb39e05a4128e1bfa7e323d9673a572baa660bdfdf69965cbd8da159c981cff9df93922fa3dc1e5f26b05d711544c4b22cdc9e5b98756aa8c6a6b0dbea16941ff09c18584d2c4c66c57d20adc2aa917bcf4785bef50de2663c5cd2b0647e62bec3e138b02a61770236d5dce412e8564e853a3913df3dd102343bb1ad2b759d85287906d996a88300807110444eb4a9315a2e73e37f1075bf0713812703ebd328188437629b950da747e09c59f6767e3c0a37b18711e0c23cfd703fd3e335d12ddf7270e45d06b680a299e92fe1f28444500c69e4ed69878761ca577100512bed36e3630e59ddcab5eb53c245d2ef59cf82a20b3186f7a51aa8035f9f5b2b5a6522f6b475627ef73a9741706e15e969b719a6cdf7d215c07f285fcd9a4af070329c746938d422f67de7022d37f8498459f4f149ef50f71f92097c6547526895b1670999a96e9e36fe315d1379379894db6569ead7eb460763b52fa6d992fc2ef02e65b1bdf656c504bf6b4088f1ccb3c0a162b2bb465cc390cdd316fb821ee21b34c0fa1c27bca3cdcd7c667d85f51c5bf8dff0f26073e5ef870c7e0ba37b9a74ec9bd93e047493b472a050130456e64d4c360e34b77e55d8d000d4a61ddbe8b3af09a00356dea2f26d1e68a3c5fa508c68aeee4a189178edaebffbf000000ffff1ed9a0d101","nonce":"0x128cd","to":"0x8453100000000000000000000000000000000000","transactionIndex":"0x3b","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x41535904d7b20be8d733e03d95ec725d0c6ee4307d899cd00e0ca0de91533b13","s":"0x3f98c81207d078199bf74a600a77cfa389574646d63ff55ccfd194491faf7226","yParity":"0x0"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0xd3343d473f624c02045a01f4e7ab604bc56c4f42","gas":"0x156c0","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xf49895cde","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0x00b5b05c6d1a2eb8abe2c383da600516515e383fc8a29953bb6e6d167e9705b2","input":"0x9aaab64814636b3e36ce9c4227a5fb53273a04c3fdc94c8a00a4d6d5b6521571b94ec7ac00000000000000000000000000000000000000000000000000000000000028a416eb20a9e75d33ef7eeb4a0bad7413cea6c0b3a7f6ea249a93a428c0c36b52240000000000000000000000000000000000000000000000000000000000840244","nonce":"0x6c7","to":"0x1a8b038f5dff48f541e8cc658b9e186b9828a726","transactionIndex":"0x3c","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x1","r":"0xfcd40d6ec6fa94f40f866c18457c22ebf5d8e3aaf2616c4c1cee5245ce8f042c","s":"0x45e5962efdda48e38f706cf8fb7c2f722d80da6e0a1d2589b6627627b44feb82","yParity":"0x1"},{"blockHash":"0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663","blockNumber":"0x840249","from":"0x9aba7eeb134fa94dfe735205dda6ac6447d76f9b","gas":"0x3e64f","gasPrice":"0x7d9f6fbd8","maxFeePerGas":"0xf49895cde","maxPriorityFeePerGas":"0xcfd6ae0","hash":"0x6fc411f24c7b4b8d821b45de32b9edc5ac998d1ac748a98abe8e983c6f39fc19","input":"0x2e260ac30000000000000000000000000000000000000000000000000000000000000200a5c46e2dd70854a0fe8167b705eb7df71cc927469c345248c81b21a5ab2f5f19000000000000000000000000000000000000000000000000000000000000051d000000000000000000000000000000000000000000000000000000000000051e000000000000000000000000000000000000000000000000000000000084024700000000000000000000000000000000000000000000000000000001b3fd9f800000000000000000000000007ebc0d2451003f2d3bc5f6eafbb7e6bad81e250d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000640fdea40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e43c000000000000000000000000000000000000000000000000000000000002e7d600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6cb686532a3ece4a20f823e59cc386e1ba384d8504e902c932fa1497c4afdfb0b000000000008008402470000051e00000000000000082ffe82e7b18f0778493c989ecae1740325207ea29328999d5ae646723a4bb75a1305c8ca593670972f535ff8afda050351549ed800e9b98c805788acfe20e6ac076ae024efa64ac3ceb8f0a3cc9ce93d122f6faf8376c854da95567fb7576f762299ca2135608c7ac5a824257b50043526903fc8e01ad88006448a69a4afda4c01ad8a6ed1260582538f2311e902c1e7d5853a75b74482117f2cf920897c1b9428eaeb7e74a95d3d32db03931d157a48aaca9748bfebfecffc2d140caddc66b300000000000000000000","nonce":"0x108af","to":"0x7ebc0d2451003f2d3bc5f6eafbb7e6bad81e250d","transactionIndex":"0x3d","value":"0x0","type":"0x2","accessList":[],"chainId":"0x5","v":"0x0","r":"0x1b284cf86146fa2094c7c709cf9fcb8a177f4fde1d1c5ca112e41f82a5e973d2","s":"0x5618261c40d23e5beb7ac0bac77b16ead56e547f103f649462387c5acdf18ba5","yParity":"0x0"}],"transactionsRoot":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","uncles":[]} diff --git a/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions_metadata.json b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions_metadata.json index 6ae97b067cf5..3673671aee60 100644 --- a/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions_metadata.json +++ b/op-service/sources/testdata/data/blocks/pre-shanghai-bad-transactions_metadata.json @@ -1 +1 @@ -{"name":"pre-shanghai-bad-transactions","fail":true} +{"name":"pre-shanghai-bad-transactions","fail":true,"reason": "failed to verify transactions list"} diff --git a/op-service/sources/testdata/gen.sh b/op-service/sources/testdata/gen.sh index 50612d71b81e..8eeaedf7cc3b 100644 --- a/op-service/sources/testdata/gen.sh +++ b/op-service/sources/testdata/gen.sh @@ -1,7 +1,7 @@ #!/bin/bash set -euo pipefail -SOURCE_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) +SOURCE_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) cd "$SOURCE_DIR" export ETH_RPC_URL=https://ethereum-goerli-rpc.allthatnode.com @@ -56,24 +56,14 @@ generate_test_vector() { echo "{\"name\": \"$name\"}" > "$metadata_file" - cast rpc eth_getBlockByHash $blockhash $fulltxs > $data_file + cast rpc eth_getBlockByHash "$blockhash" "$fulltxs" > "$data_file" # Mutate data using the provided function - $mutation_func "$data_file" $metadata_file + $mutation_func "$data_file" "$metadata_file" } -mkdir -p data/blocks mkdir -p data/headers -# Blocks -generate_test_vector "pre-shanghai-success" "0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663" true success_case -generate_test_vector "pre-shanghai-bad-transactions" "0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663" true bad_transactions_root -generate_test_vector "pre-shanghai-bad-receipts" "0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663" true bad_receipts_root -generate_test_vector "post-shanghai-success" "0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452" true success_case -generate_test_vector "post-shanghai-bad-withdrawals" "0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452" true bad_withdrawals_root -generate_test_vector "post-shanghai-bad-transactions" "0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452" true bad_transactions_root -generate_test_vector "post-shanghai-bad-receipts" "0xa16c6bcda4fdca88b5761965c4d724f7afc6a6900d9051a204e544870adb3452" true bad_receipts_root - # Headers generate_test_vector "pre-shanghai-success" "0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663" false success_case generate_test_vector "pre-shanghai-bad-transactions" "0x9ef7cd2241202b919a0e51240818a8666c73f7ce4b908931e3ae6d26d30f7663" false bad_transactions_root diff --git a/op-service/sources/types.go b/op-service/sources/types.go index 2655986bb2ca..afb994bd7cc3 100644 --- a/op-service/sources/types.go +++ b/op-service/sources/types.go @@ -1,7 +1,6 @@ package sources import ( - "context" "fmt" "math/big" "strings" @@ -11,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/trie" @@ -18,10 +18,6 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" ) -type BatchCallContextFn func(ctx context.Context, b []rpc.BatchElem) error - -type CallContextFn func(ctx context.Context, result any, method string, args ...any) error - // Note: these types are used, instead of the geth types, to enable: // - batched calls of many block requests (standard bindings do extra uncle-header fetches, cannot be batched nicely) // - ignore uncle data (does not even exist anymore post-Merge) @@ -75,6 +71,13 @@ func (h headerInfo) BaseFee() *big.Int { return h.Header.BaseFee } +func (h headerInfo) BlobBaseFee() *big.Int { + if h.Header.ExcessBlobGas == nil { + return nil + } + return eip4844.CalcBlobFee(*h.Header.ExcessBlobGas) +} + func (h headerInfo) ReceiptHash() common.Hash { return h.Header.ReceiptHash } @@ -83,11 +86,19 @@ func (h headerInfo) GasUsed() uint64 { return h.Header.GasUsed } +func (h headerInfo) GasLimit() uint64 { + return h.Header.GasLimit +} + +func (h headerInfo) ParentBeaconRoot() *common.Hash { + return h.Header.ParentBeaconRoot +} + func (h headerInfo) HeaderRLP() ([]byte, error) { return rlp.EncodeToBytes(h.Header) } -type rpcHeader struct { +type RPCHeader struct { ParentHash common.Hash `json:"parentHash"` UncleHash common.Hash `json:"sha3Uncles"` Coinbase common.Address `json:"miner"` @@ -108,7 +119,16 @@ type rpcHeader struct { BaseFee *hexutil.Big `json:"baseFeePerGas"` // WithdrawalsRoot was added by EIP-4895 and is ignored in legacy headers. - WithdrawalsRoot *common.Hash `json:"withdrawalsRoot"` + WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"` + + // BlobGasUsed was added by EIP-4844 and is ignored in legacy headers. + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed,omitempty"` + + // ExcessBlobGas was added by EIP-4844 and is ignored in legacy headers. + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas,omitempty"` + + // ParentBeaconRoot was added by EIP-4788 and is ignored in legacy headers. + ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot,omitempty"` // untrusted info included by RPC, may have to be checked Hash common.Hash `json:"hash"` @@ -116,7 +136,7 @@ type rpcHeader struct { // checkPostMerge checks that the block header meets all criteria to be a valid ExecutionPayloadHeader, // see EIP-3675 (block header changes) and EIP-4399 (mixHash usage for prev-randao) -func (hdr *rpcHeader) checkPostMerge() error { +func (hdr *RPCHeader) checkPostMerge() error { // TODO: the genesis block has a non-zero difficulty number value. // Either this block needs to change, or we special case it. This is not valid w.r.t. EIP-3675. if hdr.Number != 0 && (*big.Int)(&hdr.Difficulty).Cmp(common.Big0) != 0 { @@ -126,7 +146,7 @@ func (hdr *rpcHeader) checkPostMerge() error { return fmt.Errorf("post-merge block header requires zeroed block nonce field, but got: %s", hdr.Nonce) } if hdr.BaseFee == nil { - return fmt.Errorf("post-merge block header requires EIP-1559 basefee field, but got %s", hdr.BaseFee) + return fmt.Errorf("post-merge block header requires EIP-1559 base fee field, but got %s", hdr.BaseFee) } if len(hdr.Extra) > 32 { return fmt.Errorf("post-merge block header requires 32 or less bytes of extra data, but got %d", len(hdr.Extra)) @@ -137,12 +157,12 @@ func (hdr *rpcHeader) checkPostMerge() error { return nil } -func (hdr *rpcHeader) computeBlockHash() common.Hash { +func (hdr *RPCHeader) computeBlockHash() common.Hash { gethHeader := hdr.createGethHeader() return gethHeader.Hash() } -func (hdr *rpcHeader) createGethHeader() *types.Header { +func (hdr *RPCHeader) createGethHeader() *types.Header { return &types.Header{ ParentHash: hdr.ParentHash, UncleHash: hdr.UncleHash, @@ -161,10 +181,14 @@ func (hdr *rpcHeader) createGethHeader() *types.Header { Nonce: hdr.Nonce, BaseFee: (*big.Int)(hdr.BaseFee), WithdrawalsHash: hdr.WithdrawalsRoot, + // Cancun + BlobGasUsed: (*uint64)(hdr.BlobGasUsed), + ExcessBlobGas: (*uint64)(hdr.ExcessBlobGas), + ParentBeaconRoot: hdr.ParentBeaconRoot, } } -func (hdr *rpcHeader) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInfo, error) { +func (hdr *RPCHeader) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInfo, error) { if mustBePostMerge { if err := hdr.checkPostMerge(); err != nil { return nil, err @@ -178,19 +202,26 @@ func (hdr *rpcHeader) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInfo return &headerInfo{hdr.Hash, hdr.createGethHeader()}, nil } -type rpcBlock struct { - rpcHeader +func (hdr *RPCHeader) BlockID() eth.BlockID { + return eth.BlockID{ + Hash: hdr.Hash, + Number: uint64(hdr.Number), + } +} + +type RPCBlock struct { + RPCHeader Transactions []*types.Transaction `json:"transactions"` Withdrawals *types.Withdrawals `json:"withdrawals,omitempty"` } -func (block *rpcBlock) verify() error { +func (block *RPCBlock) verify() error { if computed := block.computeBlockHash(); computed != block.Hash { return fmt.Errorf("failed to verify block hash: computed %s but RPC said %s", computed, block.Hash) } for i, tx := range block.Transactions { if tx == nil { - return fmt.Errorf("block tx %d is null", i) + return fmt.Errorf("block tx %d is nil", i) } } if computed := types.DeriveSha(types.Transactions(block.Transactions), trie.NewStackTrie(nil)); block.TxHash != computed { @@ -216,7 +247,7 @@ func (block *rpcBlock) verify() error { return nil } -func (block *rpcBlock) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInfo, types.Transactions, error) { +func (block *RPCBlock) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInfo, types.Transactions, error) { if mustBePostMerge { if err := block.checkPostMerge(); err != nil { return nil, nil, err @@ -229,7 +260,7 @@ func (block *rpcBlock) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInf } // verify the header data - info, err := block.rpcHeader.Info(trustCache, mustBePostMerge) + info, err := block.RPCHeader.Info(trustCache, mustBePostMerge) if err != nil { return nil, nil, fmt.Errorf("failed to verify block from RPC: %w", err) } @@ -237,7 +268,7 @@ func (block *rpcBlock) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInf return info, block.Transactions, nil } -func (block *rpcBlock) ExecutionPayload(trustCache bool) (*eth.ExecutionPayload, error) { +func (block *RPCBlock) ExecutionPayloadEnvelope(trustCache bool) (*eth.ExecutionPayloadEnvelope, error) { if err := block.checkPostMerge(); err != nil { return nil, err } @@ -260,7 +291,7 @@ func (block *rpcBlock) ExecutionPayload(trustCache bool) (*eth.ExecutionPayload, opaqueTxs[i] = data } - return ð.ExecutionPayload{ + payload := ð.ExecutionPayload{ ParentHash: block.ParentHash, FeeRecipient: block.Coinbase, StateRoot: eth.Bytes32(block.Root), @@ -272,10 +303,17 @@ func (block *rpcBlock) ExecutionPayload(trustCache bool) (*eth.ExecutionPayload, GasUsed: block.GasUsed, Timestamp: block.Time, ExtraData: eth.BytesMax32(block.Extra), - BaseFeePerGas: baseFee, + BaseFeePerGas: eth.Uint256Quantity(baseFee), BlockHash: block.Hash, Transactions: opaqueTxs, Withdrawals: block.Withdrawals, + BlobGasUsed: block.BlobGasUsed, + ExcessBlobGas: block.ExcessBlobGas, + } + + return ð.ExecutionPayloadEnvelope{ + ParentBeaconBlockRoot: block.ParentBeaconRoot, + ExecutionPayload: payload, }, nil } @@ -299,5 +337,6 @@ func unusableMethod(err error) bool { return strings.Contains(errText, "unsupported method") || // alchemy -32600 message strings.Contains(errText, "unknown method") || strings.Contains(errText, "invalid param") || - strings.Contains(errText, "is not available") + strings.Contains(errText, "is not available") || + strings.Contains(errText, "rpc method is not whitelisted") // proxyd -32001 error code } diff --git a/op-service/sources/types_test.go b/op-service/sources/types_test.go index 50ca8423c796..6d6bad5565bf 100644 --- a/op-service/sources/types_test.go +++ b/op-service/sources/types_test.go @@ -3,9 +3,14 @@ package sources import ( "embed" "encoding/json" + "math/big" "strings" "testing" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/require" ) @@ -13,8 +18,9 @@ import ( var blocksTestdata embed.FS type testMetadata struct { - Name string `json:"name"` - Fail bool `json:"fail,omitempty"` + Name string `json:"name"` + Fail bool `json:"fail,omitempty"` + Reason string `json:"reason,omitempty"` } func readJsonTestdata(t *testing.T, name string, dest any) { @@ -36,7 +42,7 @@ func TestBlockHeaderJSON(t *testing.T) { var metadata testMetadata readJsonTestdata(t, "testdata/data/headers/"+entry.Name(), &metadata) t.Run(metadata.Name, func(t *testing.T) { - var header rpcHeader + var header RPCHeader readJsonTestdata(t, "testdata/data/headers/"+strings.Replace(entry.Name(), "_metadata.json", "_data.json", 1), &header) h := header.computeBlockHash() @@ -61,15 +67,82 @@ func TestBlockJSON(t *testing.T) { var metadata testMetadata readJsonTestdata(t, "testdata/data/blocks/"+entry.Name(), &metadata) t.Run(metadata.Name, func(t *testing.T) { - var block rpcBlock + var block RPCBlock readJsonTestdata(t, "testdata/data/blocks/"+strings.Replace(entry.Name(), "_metadata.json", "_data.json", 1), &block) err := block.verify() if metadata.Fail { require.NotNil(t, err, "expecting verification error") + require.ErrorContains(t, err, metadata.Reason, "validation failed for incorrect reason") } else { require.NoError(t, err, "verification should pass") } }) } } + +func TestBlockToExecutionPayloadIncludesEcotoneProperties(t *testing.T) { + zero := uint64(0) + + hdr := &types.Header{ + ParentHash: randHash(), + UncleHash: types.EmptyUncleHash, + Coinbase: common.Address{}, + Root: randHash(), + TxHash: types.EmptyTxsHash, + ReceiptHash: randHash(), + Bloom: types.Bloom{}, + Difficulty: big.NewInt(0), + Number: big.NewInt(1234), + GasLimit: 0, + GasUsed: 0, + Time: 123456, + Extra: make([]byte, 0), + MixDigest: randHash(), + Nonce: types.BlockNonce{}, + BaseFee: big.NewInt(100), + WithdrawalsHash: &types.EmptyWithdrawalsHash, + ExcessBlobGas: &zero, + BlobGasUsed: &zero, + ParentBeaconRoot: &common.Hash{}, + } + rhdr := RPCHeader{ + ParentBeaconRoot: hdr.ParentBeaconRoot, + ParentHash: hdr.ParentHash, + WithdrawalsRoot: hdr.WithdrawalsHash, + UncleHash: hdr.UncleHash, + Coinbase: hdr.Coinbase, + Root: hdr.Root, + TxHash: hdr.TxHash, + ReceiptHash: hdr.ReceiptHash, + Bloom: eth.Bytes256(hdr.Bloom), + Difficulty: *(*hexutil.Big)(hdr.Difficulty), + Number: hexutil.Uint64(hdr.Number.Uint64()), + GasLimit: hexutil.Uint64(hdr.GasLimit), + GasUsed: hexutil.Uint64(hdr.GasUsed), + Time: hexutil.Uint64(hdr.Time), + Extra: hdr.Extra, + MixDigest: hdr.MixDigest, + Nonce: hdr.Nonce, + BaseFee: (*hexutil.Big)(hdr.BaseFee), + Hash: hdr.Hash(), + BlobGasUsed: (*hexutil.Uint64)(hdr.BlobGasUsed), + ExcessBlobGas: (*hexutil.Uint64)(hdr.ExcessBlobGas), + } + + block := RPCBlock{ + RPCHeader: rhdr, + Transactions: types.Transactions{}, + Withdrawals: &types.Withdrawals{}, + } + + envelope, err := block.ExecutionPayloadEnvelope(false) + require.NoError(t, err) + + require.NotNil(t, envelope.ParentBeaconBlockRoot) + require.Equal(t, *envelope.ParentBeaconBlockRoot, *hdr.ParentBeaconRoot) + require.NotNil(t, envelope.ExecutionPayload.ExcessBlobGas) + require.Equal(t, *envelope.ExecutionPayload.ExcessBlobGas, *rhdr.ExcessBlobGas) + require.NotNil(t, envelope.ExecutionPayload.BlobGasUsed) + require.Equal(t, *envelope.ExecutionPayload.BlobGasUsed, *rhdr.BlobGasUsed) +} diff --git a/op-service/tasks/tasks.go b/op-service/tasks/tasks.go new file mode 100644 index 000000000000..67675995b2c4 --- /dev/null +++ b/op-service/tasks/tasks.go @@ -0,0 +1,32 @@ +package tasks + +import ( + "fmt" + "runtime/debug" + + "golang.org/x/sync/errgroup" +) + +// Group is a tasks group, which can at any point be awaited to complete. +// Tasks in the group are run in separate go routines. +// If a task panics, the panic is recovered with HandleCrit. +type Group struct { + errGroup errgroup.Group + HandleCrit func(err error) +} + +func (t *Group) Go(fn func() error) { + t.errGroup.Go(func() error { + defer func() { + if err := recover(); err != nil { + debug.PrintStack() + t.HandleCrit(fmt.Errorf("panic: %v", err)) + } + }() + return fn() + }) +} + +func (t *Group) Wait() error { + return t.errGroup.Wait() +} diff --git a/op-service/testlog/capturing.go b/op-service/testlog/capturing.go index 5b87e30f445b..6e1edb09b504 100644 --- a/op-service/testlog/capturing.go +++ b/op-service/testlog/capturing.go @@ -1,56 +1,155 @@ package testlog import ( + "context" + "strings" + + "golang.org/x/exp/slog" + "github.com/ethereum/go-ethereum/log" ) // CapturingHandler provides a log handler that captures all log records and optionally forwards them to a delegate. // Note that it is not thread safe. type CapturingHandler struct { - Delegate log.Handler - Logs []*log.Record + handler slog.Handler + Logs *[]*slog.Record // shared among derived CapturingHandlers } -func Capture(l log.Logger) *CapturingHandler { - handler := &CapturingHandler{ - Delegate: l.GetHandler(), - } - l.SetHandler(handler) - return handler +func CaptureLogger(t Testing, level slog.Level) (_ log.Logger, ch *CapturingHandler) { + return LoggerWithHandlerMod(t, level, func(h slog.Handler) slog.Handler { + ch = &CapturingHandler{handler: h, Logs: new([]*slog.Record)} + return ch + }), ch +} + +func (c *CapturingHandler) Enabled(context.Context, slog.Level) bool { + // We want to capture all logs, even if the underlying handler only logs + // above a certain level. + return true } -func (c *CapturingHandler) Log(r *log.Record) error { - c.Logs = append(c.Logs, r) - if c.Delegate != nil { - return c.Delegate.Log(r) +func (c *CapturingHandler) Handle(ctx context.Context, r slog.Record) error { + *c.Logs = append(*c.Logs, &r) + if c.handler != nil && c.handler.Enabled(ctx, r.Level) { + return c.handler.Handle(ctx, r) } return nil } +func (c *CapturingHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + // Note: additional attributes won't be visible for captured logs + return &CapturingHandler{ + handler: c.handler.WithAttrs(attrs), + Logs: c.Logs, + } +} + +func (c *CapturingHandler) WithGroup(name string) slog.Handler { + return &CapturingHandler{ + handler: c.handler.WithGroup(name), + Logs: c.Logs, + } +} + func (c *CapturingHandler) Clear() { - c.Logs = nil + *c.Logs = (*c.Logs)[:0] // reuse slice +} + +func NewLevelFilter(level slog.Level) LogFilter { + return func(r *slog.Record) bool { + return r.Level == level + } } -func (c *CapturingHandler) FindLog(lvl log.Lvl, msg string) *HelperRecord { - for _, record := range c.Logs { - if record.Lvl == lvl && record.Msg == msg { +func NewAttributesFilter(key, value string) LogFilter { + return func(r *slog.Record) bool { + found := false + r.Attrs(func(a slog.Attr) bool { + if a.Key == key && a.Value.String() == value { + found = true + return false + } + return true // try next + }) + return found + } +} + +func NewAttributesContainsFilter(key, value string) LogFilter { + return func(r *slog.Record) bool { + found := false + r.Attrs(func(a slog.Attr) bool { + if a.Key == key && strings.Contains(a.Value.String(), value) { + found = true + return false + } + return true // try next + }) + return found + } +} + +func NewMessageFilter(message string) LogFilter { + return func(r *slog.Record) bool { + return r.Message == message + } +} + +func NewMessageContainsFilter(message string) LogFilter { + return func(r *slog.Record) bool { + return strings.Contains(r.Message, message) + } +} + +type LogFilter func(*slog.Record) bool + +func (c *CapturingHandler) FindLog(filters ...LogFilter) *HelperRecord { + for _, record := range *c.Logs { + match := true + for _, filter := range filters { + if !filter(record) { + match = false + break + } + } + if match { return &HelperRecord{record} } } return nil } +func (c *CapturingHandler) FindLogs(filters ...LogFilter) []*HelperRecord { + var logs []*HelperRecord + for _, record := range *c.Logs { + match := true + for _, filter := range filters { + if !filter(record) { + match = false + break + } + } + if match { + logs = append(logs, &HelperRecord{record}) + } + } + return logs +} + type HelperRecord struct { - *log.Record + *slog.Record } -func (h *HelperRecord) GetContextValue(name string) any { - for i := 0; i < len(h.Ctx); i += 2 { - if h.Ctx[i] == name { - return h.Ctx[i+1] +func (h HelperRecord) AttrValue(name string) (v any) { + h.Attrs(func(a slog.Attr) bool { + if a.Key == name { + v = a.Value.Any() + return false } - } - return nil + return true // try next + }) + return } -var _ log.Handler = (*CapturingHandler)(nil) +var _ slog.Handler = (*CapturingHandler)(nil) diff --git a/op-service/testlog/capturing_test.go b/op-service/testlog/capturing_test.go new file mode 100644 index 000000000000..46f6fd175e08 --- /dev/null +++ b/op-service/testlog/capturing_test.go @@ -0,0 +1,60 @@ +package testlog_test + +import ( + "testing" + + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestCaptureLogger(t *testing.T) { + lgr, logs := testlog.CaptureLogger(t, log.LevelInfo) + msg := "foo bar" + lgr.Info(msg, "a", 1) + msgFilter := testlog.NewMessageFilter(msg) + rec := logs.FindLog(msgFilter) + require.Equal(t, msg, rec.Message) + require.EqualValues(t, 1, rec.AttrValue("a")) + + lgr.Debug("bug") + containsFilter := testlog.NewMessageContainsFilter("bug") + l := logs.FindLog(containsFilter) + require.NotNil(t, l, "should capture all logs, not only above level") + + msgClear := "clear" + lgr.Error(msgClear) + levelFilter := testlog.NewLevelFilter(log.LevelError) + msgFilter = testlog.NewMessageFilter(msgClear) + require.NotNil(t, logs.FindLog(levelFilter, msgFilter)) + logs.Clear() + containsFilter = testlog.NewMessageContainsFilter(msgClear) + l = logs.FindLog(containsFilter) + require.Nil(t, l) + + lgrb := lgr.New("b", 2) + msgOp := "optimistic" + lgrb.Info(msgOp, "c", 3) + containsFilter = testlog.NewMessageContainsFilter(msgOp) + recOp := logs.FindLog(containsFilter) + require.NotNil(t, recOp, "should still capture logs from derived logger") + require.EqualValues(t, 3, recOp.AttrValue("c")) + // Note: "b" attributes won't be visible on captured record +} + +func TestCaptureLoggerAttributesFilter(t *testing.T) { + lgr, logs := testlog.CaptureLogger(t, log.LevelInfo) + msg := "foo bar" + lgr.Info(msg, "a", "test") + lgr.Info(msg, "a", "test 2") + lgr.Info(msg, "a", "random") + msgFilter := testlog.NewMessageFilter(msg) + attrFilter := testlog.NewAttributesFilter("a", "random") + + rec := logs.FindLog(msgFilter, attrFilter) + require.Equal(t, msg, rec.Message) + require.EqualValues(t, "random", rec.AttrValue("a")) + + recs := logs.FindLogs(msgFilter, attrFilter) + require.Len(t, recs, 1) +} diff --git a/op-service/testlog/testlog.go b/op-service/testlog/testlog.go index d3e3c8b04447..0ff544225599 100644 --- a/op-service/testlog/testlog.go +++ b/op-service/testlog/testlog.go @@ -18,12 +18,17 @@ package testlog import ( + "bufio" + "bytes" + "context" "os" "runtime" "strconv" "strings" "sync" + "golang.org/x/exp/slog" + "github.com/ethereum/go-ethereum/log" ) @@ -42,52 +47,32 @@ type Testing interface { Helper() } -// Handler returns a log handler which logs to the unit test log of t. -func Handler(t Testing, level log.Lvl, format log.Format) log.Handler { - return log.LvlFilterHandler(level, &handler{t, format}) -} - -type handler struct { - t Testing - fmt log.Format -} - -func (h *handler) Log(r *log.Record) error { - h.t.Logf("%s", h.fmt.Format(r)) - return nil -} - // logger implements log.Logger such that all output goes to the unit test log via // t.Logf(). All methods in between logger.Trace, logger.Debug, etc. are marked as test // helpers, so the file and line number in unit test output correspond to the call site // which emitted the log message. type logger struct { - t Testing - l log.Logger - mu *sync.Mutex - h *bufHandler + t Testing + l log.Logger + mu *sync.Mutex + buf *bytes.Buffer } -type bufHandler struct { - buf []*log.Record - fmt log.Format +// Logger returns a logger which logs to the unit test log of t. +func Logger(t Testing, level slog.Level) log.Logger { + return LoggerWithHandlerMod(t, level, func(h slog.Handler) slog.Handler { return h }) } -func (h *bufHandler) Log(r *log.Record) error { - h.buf = append(h.buf, r) - return nil +func LoggerWithHandlerMod(t Testing, level slog.Level, handlerMod func(slog.Handler) slog.Handler) log.Logger { + l := &logger{t: t, mu: new(sync.Mutex), buf: new(bytes.Buffer)} + var handler slog.Handler = log.NewTerminalHandlerWithLevel(l.buf, level, useColorInTestLog) + handler = handlerMod(handler) + l.l = log.NewLogger(handler) + return l } -// Logger returns a logger which logs to the unit test log of t. -func Logger(t Testing, level log.Lvl) log.Logger { - l := &logger{ - t: t, - l: log.New(), - mu: new(sync.Mutex), - h: &bufHandler{fmt: log.TerminalFormat(useColorInTestLog)}, - } - l.l.SetHandler(log.LvlFilterHandler(level, l.h)) - return l +func (l *logger) Handler() slog.Handler { + return l.l.Handler() } func (l *logger) Trace(msg string, ctx ...any) { @@ -138,16 +123,28 @@ func (l *logger) Crit(msg string, ctx ...any) { l.flush() } +func (l *logger) Log(level slog.Level, msg string, ctx ...any) { + l.t.Helper() + l.mu.Lock() + defer l.mu.Unlock() + l.l.Log(level, msg, ctx...) + l.flush() +} + +func (l *logger) Write(level slog.Level, msg string, ctx ...any) { + l.Log(level, msg, ctx...) +} + func (l *logger) New(ctx ...any) log.Logger { - return &logger{l.t, l.l.New(ctx...), l.mu, l.h} + return &logger{l.t, l.l.New(ctx...), l.mu, l.buf} } -func (l *logger) GetHandler() log.Handler { - return l.l.GetHandler() +func (l *logger) With(ctx ...any) log.Logger { + return l.New(ctx...) } -func (l *logger) SetHandler(h log.Handler) { - l.l.SetHandler(h) +func (l *logger) Enabled(ctx context.Context, level slog.Level) bool { + return l.l.Enabled(ctx, level) } // flush writes all buffered messages and clears the buffer. @@ -160,10 +157,12 @@ func (l *logger) flush() { if decorationLen <= padLength { padding = padLength - decorationLen } - for _, r := range l.h.buf { - l.t.Logf("%*s%s", padding, "", l.h.fmt.Format(r)) + + scanner := bufio.NewScanner(l.buf) + for scanner.Scan() { + l.t.Logf("%*s%s", padding, "", scanner.Text()) } - l.h.buf = nil + l.buf.Reset() } // The Go testing lib uses the runtime package to get info about the calling site, and then decorates the line. diff --git a/op-service/testutils/l1info.go b/op-service/testutils/l1info.go index 0109f5e1650b..8f04b71fed93 100644 --- a/op-service/testutils/l1info.go +++ b/op-service/testutils/l1info.go @@ -10,6 +10,8 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) +var _ eth.BlockInfo = &MockBlockInfo{} + type MockBlockInfo struct { // Prefixed all fields with "Info" to avoid collisions with the interface method names. @@ -21,9 +23,13 @@ type MockBlockInfo struct { InfoTime uint64 InfoMixDigest [32]byte InfoBaseFee *big.Int + InfoBlobBaseFee *big.Int InfoReceiptRoot common.Hash InfoGasUsed uint64 + InfoGasLimit uint64 InfoHeaderRLP []byte + + InfoParentBeaconRoot *common.Hash } func (l *MockBlockInfo) Hash() common.Hash { @@ -58,6 +64,10 @@ func (l *MockBlockInfo) BaseFee() *big.Int { return l.InfoBaseFee } +func (l *MockBlockInfo) BlobBaseFee() *big.Int { + return l.InfoBlobBaseFee +} + func (l *MockBlockInfo) ReceiptHash() common.Hash { return l.InfoReceiptRoot } @@ -66,10 +76,18 @@ func (l *MockBlockInfo) GasUsed() uint64 { return l.InfoGasUsed } +func (l *MockBlockInfo) GasLimit() uint64 { + return l.InfoGasLimit +} + func (l *MockBlockInfo) ID() eth.BlockID { return eth.BlockID{Hash: l.InfoHash, Number: l.InfoNum} } +func (l *MockBlockInfo) ParentBeaconRoot() *common.Hash { + return l.InfoParentBeaconRoot +} + func (l *MockBlockInfo) HeaderRLP() ([]byte, error) { if l.InfoHeaderRLP == nil { return nil, errors.New("header rlp not available") @@ -93,6 +111,7 @@ func RandomBlockInfo(rng *rand.Rand) *MockBlockInfo { InfoTime: rng.Uint64(), InfoHash: RandomHash(rng), InfoBaseFee: big.NewInt(rng.Int63n(1000_000 * 1e9)), // a million GWEI + InfoBlobBaseFee: big.NewInt(rng.Int63n(2000_000 * 1e9)), // two million GWEI InfoReceiptRoot: types.EmptyRootHash, InfoRoot: RandomHash(rng), InfoGasUsed: rng.Uint64(), diff --git a/op-service/testutils/metrics.go b/op-service/testutils/metrics.go index 24ad329bb743..c5d166bf3a11 100644 --- a/op-service/testutils/metrics.go +++ b/op-service/testutils/metrics.go @@ -55,7 +55,10 @@ func (t *TestDerivationMetrics) RecordChannelTimedOut() { func (t *TestDerivationMetrics) RecordFrame() { } -func (t *TestDerivationMetrics) RecordSequencerStepTime(step string, duration time.Duration) { +func (n *TestDerivationMetrics) RecordDerivedBatches(batchType string) { +} + +func (n *TestDerivationMetrics) RecordSequencerStepTime(step string, duration time.Duration) { } type TestRPCMetrics struct{} diff --git a/op-service/testutils/mock_blobs_fetcher.go b/op-service/testutils/mock_blobs_fetcher.go new file mode 100644 index 000000000000..df09f5f46a23 --- /dev/null +++ b/op-service/testutils/mock_blobs_fetcher.go @@ -0,0 +1,34 @@ +package testutils + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/stretchr/testify/mock" +) + +type MockBlobsFetcher struct { + mock.Mock +} + +func (cl *MockBlobsFetcher) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { + out := cl.Mock.MethodCalled("GetBlobs", ref, hashes) + return out.Get(0).([]*eth.Blob), out.Error(1) +} + +func (cl *MockBlobsFetcher) ExpectOnGetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash, blobs []*eth.Blob, err error) { + cl.Mock.On("GetBlobs", ref, hashes).Once().Return(blobs, err) +} + +func (cl *MockBlobsFetcher) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) { + out := cl.Mock.MethodCalled("GetBlobSidecars", ref, hashes) + return out.Get(0).([]*eth.BlobSidecar), out.Error(1) +} + +func (cl *MockBlobsFetcher) ExpectOnGetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash, commitment eth.Bytes48, blobs []*eth.Blob, err error) { + cl.Mock.On("GetBlobSidecars", ref, hashes).Once().Return([]*eth.BlobSidecar{{ + Blob: *blobs[0], + Index: eth.Uint64String(hashes[0].Index), + KZGCommitment: commitment, + }}, err) +} diff --git a/op-service/testutils/mock_debug_client.go b/op-service/testutils/mock_debug_client.go index 57e13fb2e97f..b03591f15175 100644 --- a/op-service/testutils/mock_debug_client.go +++ b/op-service/testutils/mock_debug_client.go @@ -12,19 +12,19 @@ type MockDebugClient struct { } func (m *MockDebugClient) ExpectNodeByHash(hash common.Hash, res []byte, err error) { - m.Mock.On("NodeByHash", hash).Once().Return(res, &err) + m.Mock.On("NodeByHash", hash).Once().Return(res, err) } func (m *MockDebugClient) NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) { - out := m.Mock.MethodCalled("NodeByHash", hash) - return out[0].([]byte), *out[1].(*error) + out := m.Mock.Called(hash) + return out.Get(0).([]byte), out.Error(1) } func (m *MockDebugClient) ExpectCodeByHash(hash common.Hash, res []byte, err error) { - m.Mock.On("CodeByHash", hash).Once().Return(res, &err) + m.Mock.On("CodeByHash", hash).Once().Return(res, err) } func (m *MockDebugClient) CodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) { - out := m.Mock.MethodCalled("CodeByHash", hash) - return out[0].([]byte), *out[1].(*error) + out := m.Mock.Called(hash) + return out.Get(0).([]byte), out.Error(1) } diff --git a/op-service/testutils/mock_engine.go b/op-service/testutils/mock_engine.go index 6818978c4733..7875f6e28892 100644 --- a/op-service/testutils/mock_engine.go +++ b/op-service/testutils/mock_engine.go @@ -3,6 +3,8 @@ package testutils import ( "context" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum-optimism/optimism/op-service/eth" ) @@ -10,33 +12,33 @@ type MockEngine struct { MockL2Client } -func (m *MockEngine) GetPayload(ctx context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayload, error) { - out := m.Mock.MethodCalled("GetPayload", payloadId) - return out[0].(*eth.ExecutionPayload), *out[1].(*error) +func (m *MockEngine) GetPayload(ctx context.Context, payloadInfo eth.PayloadInfo) (*eth.ExecutionPayloadEnvelope, error) { + out := m.Mock.Called(payloadInfo.ID) + return out.Get(0).(*eth.ExecutionPayloadEnvelope), out.Error(1) } -func (m *MockEngine) ExpectGetPayload(payloadId eth.PayloadID, payload *eth.ExecutionPayload, err error) { - m.Mock.On("GetPayload", payloadId).Once().Return(payload, &err) +func (m *MockEngine) ExpectGetPayload(payloadId eth.PayloadID, payload *eth.ExecutionPayloadEnvelope, err error) { + m.Mock.On("GetPayload", payloadId).Once().Return(payload, err) } func (m *MockEngine) ForkchoiceUpdate(ctx context.Context, state *eth.ForkchoiceState, attr *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error) { - out := m.Mock.MethodCalled("ForkchoiceUpdate", state, attr) - return out[0].(*eth.ForkchoiceUpdatedResult), *out[1].(*error) + out := m.Mock.Called(state, attr) + return out.Get(0).(*eth.ForkchoiceUpdatedResult), out.Error(1) } func (m *MockEngine) ExpectForkchoiceUpdate(state *eth.ForkchoiceState, attr *eth.PayloadAttributes, result *eth.ForkchoiceUpdatedResult, err error) { - m.Mock.On("ForkchoiceUpdate", state, attr).Once().Return(result, &err) + m.Mock.On("ForkchoiceUpdate", state, attr).Once().Return(result, err) } -func (m *MockEngine) NewPayload(ctx context.Context, payload *eth.ExecutionPayload) (*eth.PayloadStatusV1, error) { - out := m.Mock.MethodCalled("NewPayload", payload) - return out[0].(*eth.PayloadStatusV1), *out[1].(*error) +func (m *MockEngine) NewPayload(ctx context.Context, payload *eth.ExecutionPayload, parentBeaconBlockRoot *common.Hash) (*eth.PayloadStatusV1, error) { + out := m.Mock.Called(payload, parentBeaconBlockRoot) + return out.Get(0).(*eth.PayloadStatusV1), out.Error(1) } -func (m *MockEngine) ExpectNewPayload(payload *eth.ExecutionPayload, result *eth.PayloadStatusV1, err error) { - m.Mock.On("NewPayload", payload).Once().Return(result, &err) +func (m *MockEngine) ExpectNewPayload(payload *eth.ExecutionPayload, parentBeaconBlockRoot *common.Hash, result *eth.PayloadStatusV1, err error) { + m.Mock.On("NewPayload", payload, parentBeaconBlockRoot).Once().Return(result, err) } -func (m *MockEngine) CachePayloadByHash(payload *eth.ExecutionPayload) bool { +func (m *MockEngine) CachePayloadByHash(payload *eth.ExecutionPayloadEnvelope) bool { return true } diff --git a/op-service/testutils/mock_eth_client.go b/op-service/testutils/mock_eth_client.go index 27270db75992..3de74aca9c71 100644 --- a/op-service/testutils/mock_eth_client.go +++ b/op-service/testutils/mock_eth_client.go @@ -2,6 +2,7 @@ package testutils import ( "context" + "math/big" "github.com/stretchr/testify/mock" @@ -16,89 +17,89 @@ type MockEthClient struct { } func (m *MockEthClient) InfoByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, error) { - out := m.Mock.MethodCalled("InfoByHash", hash) - return *out[0].(*eth.BlockInfo), *out[1].(*error) + out := m.Mock.Called(hash) + return *out.Get(0).(*eth.BlockInfo), out.Error(1) } func (m *MockEthClient) ExpectInfoByHash(hash common.Hash, info eth.BlockInfo, err error) { - m.Mock.On("InfoByHash", hash).Once().Return(&info, &err) + m.Mock.On("InfoByHash", hash).Once().Return(&info, err) } func (m *MockEthClient) InfoByNumber(ctx context.Context, number uint64) (eth.BlockInfo, error) { - out := m.Mock.MethodCalled("InfoByNumber", number) - return *out[0].(*eth.BlockInfo), *out[1].(*error) + out := m.Mock.Called(number) + return *out.Get(0).(*eth.BlockInfo), out.Error(1) } func (m *MockEthClient) ExpectInfoByNumber(number uint64, info eth.BlockInfo, err error) { - m.Mock.On("InfoByNumber", number).Once().Return(&info, &err) + m.Mock.On("InfoByNumber", number).Once().Return(&info, err) } func (m *MockEthClient) InfoByLabel(ctx context.Context, label eth.BlockLabel) (eth.BlockInfo, error) { - out := m.Mock.MethodCalled("InfoByLabel", label) - return *out[0].(*eth.BlockInfo), *out[1].(*error) + out := m.Mock.Called(label) + return *out.Get(0).(*eth.BlockInfo), out.Error(1) } func (m *MockEthClient) ExpectInfoByLabel(label eth.BlockLabel, info eth.BlockInfo, err error) { - m.Mock.On("InfoByLabel", label).Once().Return(&info, &err) + m.Mock.On("InfoByLabel", label).Once().Return(&info, err) } func (m *MockEthClient) InfoAndTxsByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, types.Transactions, error) { - out := m.Mock.MethodCalled("InfoAndTxsByHash", hash) - return out[0].(eth.BlockInfo), out[1].(types.Transactions), *out[2].(*error) + out := m.Mock.Called(hash) + return out.Get(0).(eth.BlockInfo), out.Get(1).(types.Transactions), out.Error(2) } func (m *MockEthClient) ExpectInfoAndTxsByHash(hash common.Hash, info eth.BlockInfo, transactions types.Transactions, err error) { - m.Mock.On("InfoAndTxsByHash", hash).Once().Return(info, transactions, &err) + m.Mock.On("InfoAndTxsByHash", hash).Once().Return(info, transactions, err) } func (m *MockEthClient) InfoAndTxsByNumber(ctx context.Context, number uint64) (eth.BlockInfo, types.Transactions, error) { - out := m.Mock.MethodCalled("InfoAndTxsByNumber", number) - return out[0].(eth.BlockInfo), out[1].(types.Transactions), *out[2].(*error) + out := m.Mock.Called(number) + return out.Get(0).(eth.BlockInfo), out.Get(1).(types.Transactions), out.Error(2) } func (m *MockEthClient) ExpectInfoAndTxsByNumber(number uint64, info eth.BlockInfo, transactions types.Transactions, err error) { - m.Mock.On("InfoAndTxsByNumber", number).Once().Return(info, transactions, &err) + m.Mock.On("InfoAndTxsByNumber", number).Once().Return(info, transactions, err) } func (m *MockEthClient) InfoAndTxsByLabel(ctx context.Context, label eth.BlockLabel) (eth.BlockInfo, types.Transactions, error) { - out := m.Mock.MethodCalled("InfoAndTxsByLabel", label) - return out[0].(eth.BlockInfo), out[1].(types.Transactions), *out[2].(*error) + out := m.Mock.Called(label) + return out.Get(0).(eth.BlockInfo), out.Get(1).(types.Transactions), out.Error(2) } func (m *MockEthClient) ExpectInfoAndTxsByLabel(label eth.BlockLabel, info eth.BlockInfo, transactions types.Transactions, err error) { - m.Mock.On("InfoAndTxsByLabel", label).Once().Return(info, transactions, &err) + m.Mock.On("InfoAndTxsByLabel", label).Once().Return(info, transactions, err) } -func (m *MockEthClient) PayloadByHash(ctx context.Context, hash common.Hash) (*eth.ExecutionPayload, error) { - out := m.Mock.MethodCalled("PayloadByHash", hash) - return out[0].(*eth.ExecutionPayload), *out[1].(*error) +func (m *MockEthClient) PayloadByHash(ctx context.Context, hash common.Hash) (*eth.ExecutionPayloadEnvelope, error) { + out := m.Mock.Called(hash) + return out.Get(0).(*eth.ExecutionPayloadEnvelope), out.Error(1) } -func (m *MockEthClient) ExpectPayloadByHash(hash common.Hash, payload *eth.ExecutionPayload, err error) { - m.Mock.On("PayloadByHash", hash).Once().Return(payload, &err) +func (m *MockEthClient) ExpectPayloadByHash(hash common.Hash, payload *eth.ExecutionPayloadEnvelope, err error) { + m.Mock.On("PayloadByHash", hash).Once().Return(payload, err) } -func (m *MockEthClient) PayloadByNumber(ctx context.Context, n uint64) (*eth.ExecutionPayload, error) { +func (m *MockEthClient) PayloadByNumber(ctx context.Context, n uint64) (*eth.ExecutionPayloadEnvelope, error) { out := m.Mock.MethodCalled("PayloadByNumber", n) - return out[0].(*eth.ExecutionPayload), *out[1].(*error) + return out[0].(*eth.ExecutionPayloadEnvelope), *out[1].(*error) } -func (m *MockEthClient) ExpectPayloadByNumber(n uint64, payload *eth.ExecutionPayload, err error) { +func (m *MockEthClient) ExpectPayloadByNumber(n uint64, payload *eth.ExecutionPayloadEnvelope, err error) { m.Mock.On("PayloadByNumber", n).Once().Return(payload, &err) } -func (m *MockEthClient) PayloadByLabel(ctx context.Context, label eth.BlockLabel) (*eth.ExecutionPayload, error) { - out := m.Mock.MethodCalled("PayloadByLabel", label) - return out[0].(*eth.ExecutionPayload), *out[1].(*error) +func (m *MockEthClient) PayloadByLabel(ctx context.Context, label eth.BlockLabel) (*eth.ExecutionPayloadEnvelope, error) { + out := m.Mock.Called(label) + return out.Get(0).(*eth.ExecutionPayloadEnvelope), out.Error(1) } -func (m *MockEthClient) ExpectPayloadByLabel(label eth.BlockLabel, payload *eth.ExecutionPayload, err error) { - m.Mock.On("PayloadByLabel", label).Once().Return(payload, &err) +func (m *MockEthClient) ExpectPayloadByLabel(label eth.BlockLabel, payload *eth.ExecutionPayloadEnvelope, err error) { + m.Mock.On("PayloadByLabel", label).Once().Return(payload, err) } func (m *MockEthClient) FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) { - out := m.Mock.MethodCalled("FetchReceipts", blockHash) - return *out[0].(*eth.BlockInfo), out[1].(types.Receipts), *out[2].(*error) + out := m.Mock.Called(blockHash) + return *out.Get(0).(*eth.BlockInfo), out.Get(1).(types.Receipts), out.Error(2) } func (m *MockEthClient) PreFetchReceipts(ctx context.Context, blockHash common.Hash) (bool, error) { @@ -107,29 +108,53 @@ func (m *MockEthClient) PreFetchReceipts(ctx context.Context, blockHash common.H } func (m *MockEthClient) ExpectFetchReceipts(hash common.Hash, info eth.BlockInfo, receipts types.Receipts, err error) { - m.Mock.On("FetchReceipts", hash).Once().Return(&info, receipts, &err) + m.Mock.On("FetchReceipts", hash).Once().Return(&info, receipts, err) } func (m *MockEthClient) GetProof(ctx context.Context, address common.Address, storage []common.Hash, blockTag string) (*eth.AccountResult, error) { - return m.Mock.MethodCalled("GetProof", address, storage, blockTag).Get(0).(*eth.AccountResult), nil + out := m.Mock.Called(address, storage, blockTag) + return out.Get(0).(*eth.AccountResult), out.Error(1) } func (m *MockEthClient) ExpectGetProof(address common.Address, storage []common.Hash, blockTag string, result *eth.AccountResult, err error) { - m.Mock.On("GetProof", address, storage, blockTag).Once().Return(result, &err) + m.Mock.On("GetProof", address, storage, blockTag).Once().Return(result, err) } func (m *MockEthClient) GetStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockTag string) (common.Hash, error) { - return m.Mock.MethodCalled("GetStorageAt", address, storageSlot, blockTag).Get(0).(common.Hash), nil + out := m.Mock.Called(address, storageSlot, blockTag) + return out.Get(0).(common.Hash), out.Error(1) } func (m *MockEthClient) ExpectGetStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockTag string, result common.Hash, err error) { - m.Mock.On("GetStorageAt", address, storageSlot, blockTag).Once().Return(result, &err) + m.Mock.On("GetStorageAt", address, storageSlot, blockTag).Once().Return(result, err) } func (m *MockEthClient) ReadStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockHash common.Hash) (common.Hash, error) { - return m.Mock.MethodCalled("ReadStorageAt", address, storageSlot, blockHash).Get(0).(common.Hash), nil + out := m.Mock.Called(address, storageSlot, blockHash) + return out.Get(0).(common.Hash), out.Error(1) } func (m *MockEthClient) ExpectReadStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockHash common.Hash, result common.Hash, err error) { - m.Mock.On("ReadStorageAt", address, storageSlot, blockHash).Once().Return(result, &err) + m.Mock.On("ReadStorageAt", address, storageSlot, blockHash).Once().Return(result, err) +} + +func (m *MockEthClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { + out := m.Mock.Called(number) + return out.Get(0).(*types.Block), out.Error(1) +} + +func (m *MockEthClient) ExpectBlockByNumber(number *big.Int, block *types.Block, err error) { + m.Mock.On("BlockByNumber", number).Once().Return(block, err) +} + +func (m *MockEthClient) ExpectClose() { + m.Mock.On("Close").Once() +} + +func (m *MockEthClient) MaybeClose() { + m.Mock.On("Close").Maybe() +} + +func (m *MockEthClient) Close() { + m.Mock.Called() } diff --git a/op-service/testutils/mock_l1.go b/op-service/testutils/mock_l1.go index 45b2b76815e8..78ce1b174a24 100644 --- a/op-service/testutils/mock_l1.go +++ b/op-service/testutils/mock_l1.go @@ -12,30 +12,30 @@ type MockL1Source struct { } func (m *MockL1Source) L1BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L1BlockRef, error) { - out := m.Mock.MethodCalled("L1BlockRefByLabel", label) - return out[0].(eth.L1BlockRef), *out[1].(*error) + out := m.Mock.Called(label) + return out.Get(0).(eth.L1BlockRef), out.Error(1) } func (m *MockL1Source) ExpectL1BlockRefByLabel(label eth.BlockLabel, ref eth.L1BlockRef, err error) { - m.Mock.On("L1BlockRefByLabel", label).Once().Return(ref, &err) + m.Mock.On("L1BlockRefByLabel", label).Once().Return(ref, err) } func (m *MockL1Source) L1BlockRefByNumber(ctx context.Context, num uint64) (eth.L1BlockRef, error) { - out := m.Mock.MethodCalled("L1BlockRefByNumber", num) - return out[0].(eth.L1BlockRef), *out[1].(*error) + out := m.Mock.Called(num) + return out.Get(0).(eth.L1BlockRef), out.Error(1) } func (m *MockL1Source) ExpectL1BlockRefByNumber(num uint64, ref eth.L1BlockRef, err error) { - m.Mock.On("L1BlockRefByNumber", num).Once().Return(ref, &err) + m.Mock.On("L1BlockRefByNumber", num).Once().Return(ref, err) } func (m *MockL1Source) L1BlockRefByHash(ctx context.Context, hash common.Hash) (eth.L1BlockRef, error) { - out := m.Mock.MethodCalled("L1BlockRefByHash", hash) - return out[0].(eth.L1BlockRef), *out[1].(*error) + out := m.Mock.Called(hash) + return out.Get(0).(eth.L1BlockRef), out.Error(1) } func (m *MockL1Source) ExpectL1BlockRefByHash(hash common.Hash, ref eth.L1BlockRef, err error) { - m.Mock.On("L1BlockRefByHash", hash).Once().Return(ref, &err) + m.Mock.On("L1BlockRefByHash", hash).Once().Return(ref, err) } func (m *MockL1Source) GoOrUpdatePreFetchReceipts(ctx context.Context, l1StartBlock uint64) error { diff --git a/op-service/testutils/mock_l2.go b/op-service/testutils/mock_l2.go index 574f1c97a1f1..d4931cb79ac0 100644 --- a/op-service/testutils/mock_l2.go +++ b/op-service/testutils/mock_l2.go @@ -30,32 +30,32 @@ func (m *MockL2Client) ExpectL2BlockRefByNumber(num uint64, ref eth.L2BlockRef, } func (c *MockL2Client) L2BlockRefByHash(ctx context.Context, hash common.Hash) (eth.L2BlockRef, error) { - out := c.Mock.MethodCalled("L2BlockRefByHash", hash) - return out[0].(eth.L2BlockRef), *out[1].(*error) + out := c.Mock.Called(hash) + return out.Get(0).(eth.L2BlockRef), out.Error(1) } func (m *MockL2Client) ExpectL2BlockRefByHash(hash common.Hash, ref eth.L2BlockRef, err error) { - m.Mock.On("L2BlockRefByHash", hash).Once().Return(ref, &err) + m.Mock.On("L2BlockRefByHash", hash).Once().Return(ref, err) } func (m *MockL2Client) SystemConfigByL2Hash(ctx context.Context, hash common.Hash) (eth.SystemConfig, error) { - out := m.Mock.MethodCalled("SystemConfigByL2Hash", hash) - return out[0].(eth.SystemConfig), *out[1].(*error) + out := m.Mock.Called(hash) + return out.Get(0).(eth.SystemConfig), out.Error(1) } func (m *MockL2Client) ExpectSystemConfigByL2Hash(hash common.Hash, cfg eth.SystemConfig, err error) { - m.Mock.On("SystemConfigByL2Hash", hash).Once().Return(cfg, &err) + m.Mock.On("SystemConfigByL2Hash", hash).Once().Return(cfg, err) } func (m *MockL2Client) OutputV0AtBlock(ctx context.Context, blockHash common.Hash) (*eth.OutputV0, error) { - out := m.Mock.MethodCalled("OutputV0AtBlock", blockHash) - return out[0].(*eth.OutputV0), *out[1].(*error) + out := m.Mock.Called(blockHash) + return out.Get(0).(*eth.OutputV0), out.Error(1) } func (m *MockL2Client) ExpectOutputV0AtBlock(blockHash common.Hash, output *eth.OutputV0, err error) { - m.Mock.On("OutputV0AtBlock", blockHash).Once().Return(output, &err) + m.Mock.On("OutputV0AtBlock", blockHash).Once().Return(output, err) } -func (m *MockL2Client) CachePayloadByHash(payload *eth.ExecutionPayload) bool { +func (m *MockL2Client) CachePayloadByHash(payload *eth.ExecutionPayloadEnvelope) bool { return true } diff --git a/op-service/testutils/mock_rollup_client.go b/op-service/testutils/mock_rollup_client.go new file mode 100644 index 000000000000..a7a42e878481 --- /dev/null +++ b/op-service/testutils/mock_rollup_client.go @@ -0,0 +1,71 @@ +package testutils + +import ( + "context" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/mock" +) + +type MockRollupClient struct { + mock.Mock +} + +func (m *MockRollupClient) OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) { + out := m.Mock.Called(blockNum) + return out.Get(0).(*eth.OutputResponse), out.Error(1) +} + +func (m *MockRollupClient) ExpectOutputAtBlock(blockNum uint64, response *eth.OutputResponse, err error) { + m.Mock.On("OutputAtBlock", blockNum).Once().Return(response, err) +} + +func (m *MockRollupClient) SyncStatus(ctx context.Context) (*eth.SyncStatus, error) { + out := m.Mock.Called() + return out.Get(0).(*eth.SyncStatus), out.Error(1) +} + +func (m *MockRollupClient) ExpectSyncStatus(status *eth.SyncStatus, err error) { + m.Mock.On("SyncStatus").Once().Return(status, err) +} + +func (m *MockRollupClient) RollupConfig(ctx context.Context) (*rollup.Config, error) { + out := m.Mock.Called() + return out.Get(0).(*rollup.Config), out.Error(1) +} + +func (m *MockRollupClient) ExpectRollupConfig(config *rollup.Config, err error) { + m.Mock.On("RollupConfig").Once().Return(config, err) +} + +func (m *MockRollupClient) StartSequencer(ctx context.Context, unsafeHead common.Hash) error { + out := m.Mock.Called(unsafeHead) + return out.Error(0) +} + +func (m *MockRollupClient) ExpectStartSequencer(unsafeHead common.Hash, err error) { + m.Mock.On("StartSequencer", unsafeHead).Once().Return(err) +} + +func (m *MockRollupClient) SequencerActive(ctx context.Context) (bool, error) { + out := m.Mock.Called() + return out.Bool(0), out.Error(1) +} + +func (m *MockRollupClient) ExpectSequencerActive(active bool, err error) { + m.Mock.On("SequencerActive").Once().Return(active, err) +} + +func (m *MockRollupClient) ExpectClose() { + m.Mock.On("Close").Once() +} + +func (m *MockRollupClient) MaybeClose() { + m.Mock.On("Close").Maybe() +} + +func (m *MockRollupClient) Close() { + m.Mock.Called() +} diff --git a/op-service/testutils/random.go b/op-service/testutils/random.go index d1363ecf3f5d..f13fb2fc658d 100644 --- a/op-service/testutils/random.go +++ b/op-service/testutils/random.go @@ -106,7 +106,7 @@ func NextRandomL2Ref(rng *rand.Rand, l2BlockTime uint64, parent eth.L2BlockRef, // Output is deterministic when the supplied rng generates the same random sequence. func InsecureRandomKey(rng *rand.Rand) *ecdsa.PrivateKey { idx := rng.Intn(len(randomEcdsaKeys)) - key, err := crypto.ToECDSA(common.Hex2Bytes(randomEcdsaKeys[idx])) + key, err := crypto.ToECDSA(common.FromHex(randomEcdsaKeys[idx])) if err != nil { // Should never happen because the list of keys is hard coded and known to be valid. panic(fmt.Errorf("invalid pre-generated ecdsa key at index %v: %w", idx, err)) @@ -157,6 +157,10 @@ func RandomTx(rng *rand.Rand, baseFee *big.Int, signer types.Signer) *types.Tran return tx } +func RandomLegacyTxNotProtected(rng *rand.Rand) *types.Transaction { + return RandomLegacyTx(rng, types.HomesteadSigner{}) +} + func RandomLegacyTx(rng *rand.Rand, signer types.Signer) *types.Transaction { key := InsecureRandomKey(rng) txData := &types.LegacyTx{ @@ -324,7 +328,7 @@ func RandomOutputResponse(rng *rand.Rand) *eth.OutputResponse { UnsafeL2: RandomL2BlockRef(rng), SafeL2: RandomL2BlockRef(rng), FinalizedL2: RandomL2BlockRef(rng), - EngineSyncTarget: RandomL2BlockRef(rng), + PendingSafeL2: RandomL2BlockRef(rng), }, } } diff --git a/op-service/txmgr/cli.go b/op-service/txmgr/cli.go index 9e71734cb28a..18c2ca0dfe61 100644 --- a/op-service/txmgr/cli.go +++ b/op-service/txmgr/cli.go @@ -7,13 +7,13 @@ import ( "math/big" "time" - "github.com/ethereum-optimism/optimism/op-service/client" - txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" - opservice "github.com/ethereum-optimism/optimism/op-service" + "github.com/ethereum-optimism/optimism/op-service/client" opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" - "github.com/ethereum-optimism/optimism/op-service/dial" + dial "github.com/ethereum-optimism/optimism/op-service/dummydial" + "github.com/ethereum-optimism/optimism/op-service/eth" opsigner "github.com/ethereum-optimism/optimism/op-service/signer" + txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/urfave/cli/v2" @@ -30,6 +30,9 @@ const ( NumConfirmationsFlagName = "num-confirmations" SafeAbortNonceTooLowCountFlagName = "safe-abort-nonce-too-low-count" FeeLimitMultiplierFlagName = "fee-limit-multiplier" + FeeLimitThresholdFlagName = "txmgr.fee-limit-threshold" + MinBaseFeeFlagName = "txmgr.min-basefee" + MinTipCapFlagName = "txmgr.min-tip-cap" ResubmissionTimeoutFlagName = "resubmission-timeout" NetworkTimeoutFlagName = "network-timeout" TxSendTimeoutFlagName = "txmgr.send-timeout" @@ -56,6 +59,9 @@ type DefaultFlagValues struct { NumConfirmations uint64 SafeAbortNonceTooLowCount uint64 FeeLimitMultiplier uint64 + FeeLimitThresholdGwei float64 + MinTipCapGwei float64 + MinBaseFeeGwei float64 ResubmissionTimeout time.Duration NetworkTimeout time.Duration TxSendTimeout time.Duration @@ -68,6 +74,9 @@ var ( NumConfirmations: uint64(10), SafeAbortNonceTooLowCount: uint64(3), FeeLimitMultiplier: uint64(5), + FeeLimitThresholdGwei: 100.0, + MinTipCapGwei: 1.0, + MinBaseFeeGwei: 1.0, ResubmissionTimeout: 48 * time.Second, NetworkTimeout: 10 * time.Second, TxSendTimeout: 0 * time.Second, @@ -78,6 +87,9 @@ var ( NumConfirmations: uint64(3), SafeAbortNonceTooLowCount: uint64(3), FeeLimitMultiplier: uint64(5), + FeeLimitThresholdGwei: 100.0, + MinTipCapGwei: 1.0, + MinBaseFeeGwei: 1.0, ResubmissionTimeout: 24 * time.Second, NetworkTimeout: 10 * time.Second, TxSendTimeout: 2 * time.Minute, @@ -128,6 +140,24 @@ func CLIFlagsWithDefaults(envPrefix string, defaults DefaultFlagValues) []cli.Fl Value: defaults.FeeLimitMultiplier, EnvVars: prefixEnvVars("TXMGR_FEE_LIMIT_MULTIPLIER"), }, + &cli.Float64Flag{ + Name: FeeLimitThresholdFlagName, + Usage: "The minimum threshold (in GWei) at which fee bumping starts to be capped. Allows arbitrary fee bumps below this threshold.", + Value: defaults.FeeLimitThresholdGwei, + EnvVars: prefixEnvVars("TXMGR_FEE_LIMIT_THRESHOLD"), + }, + &cli.Float64Flag{ + Name: MinTipCapFlagName, + Usage: "Enforces a minimum tip cap (in GWei) to use when determining tx fees. 1 GWei by default.", + Value: defaults.MinTipCapGwei, + EnvVars: prefixEnvVars("TXMGR_MIN_TIP_CAP"), + }, + &cli.Float64Flag{ + Name: MinBaseFeeFlagName, + Usage: "Enforces a minimum base fee (in GWei) to assume when determining tx fees. 1 GWei by default.", + Value: defaults.MinBaseFeeGwei, + EnvVars: prefixEnvVars("TXMGR_MIN_BASEFEE"), + }, &cli.DurationFlag{ Name: ResubmissionTimeoutFlagName, Usage: "Duration we will wait before resubmitting a transaction to L1", @@ -172,6 +202,9 @@ type CLIConfig struct { NumConfirmations uint64 SafeAbortNonceTooLowCount uint64 FeeLimitMultiplier uint64 + FeeLimitThresholdGwei float64 + MinBaseFeeGwei float64 + MinTipCapGwei float64 ResubmissionTimeout time.Duration ReceiptQueryInterval time.Duration NetworkTimeout time.Duration @@ -185,6 +218,9 @@ func NewCLIConfig(l1RPCURL string, defaults DefaultFlagValues) CLIConfig { NumConfirmations: defaults.NumConfirmations, SafeAbortNonceTooLowCount: defaults.SafeAbortNonceTooLowCount, FeeLimitMultiplier: defaults.FeeLimitMultiplier, + FeeLimitThresholdGwei: defaults.FeeLimitThresholdGwei, + MinTipCapGwei: defaults.MinTipCapGwei, + MinBaseFeeGwei: defaults.MinBaseFeeGwei, ResubmissionTimeout: defaults.ResubmissionTimeout, NetworkTimeout: defaults.NetworkTimeout, TxSendTimeout: defaults.TxSendTimeout, @@ -207,6 +243,10 @@ func (m CLIConfig) Check() error { if m.FeeLimitMultiplier == 0 { return errors.New("must provide FeeLimitMultiplier") } + if m.MinBaseFeeGwei < m.MinTipCapGwei { + return fmt.Errorf("minBaseFee smaller than minTipCap, have %f < %f", + m.MinBaseFeeGwei, m.MinTipCapGwei) + } if m.ResubmissionTimeout == 0 { return errors.New("must provide ResubmissionTimeout") } @@ -237,6 +277,9 @@ func ReadCLIConfig(ctx *cli.Context) CLIConfig { NumConfirmations: ctx.Uint64(NumConfirmationsFlagName), SafeAbortNonceTooLowCount: ctx.Uint64(SafeAbortNonceTooLowCountFlagName), FeeLimitMultiplier: ctx.Uint64(FeeLimitMultiplierFlagName), + FeeLimitThresholdGwei: ctx.Float64(FeeLimitThresholdFlagName), + MinBaseFeeGwei: ctx.Float64(MinBaseFeeFlagName), + MinTipCapGwei: ctx.Float64(MinTipCapFlagName), ResubmissionTimeout: ctx.Duration(ResubmissionTimeoutFlagName), ReceiptQueryInterval: ctx.Duration(ReceiptQueryIntervalFlagName), NetworkTimeout: ctx.Duration(NetworkTimeoutFlagName), @@ -278,10 +321,28 @@ func NewConfig(cfg CLIConfig, l log.Logger, m txmetrics.TxMetricer) (Config, err return Config{}, fmt.Errorf("could not init signer: %w", err) } + feeLimitThreshold, err := eth.GweiToWei(cfg.FeeLimitThresholdGwei) + if err != nil { + return Config{}, fmt.Errorf("invalid fee limit threshold: %w", err) + } + + minBaseFee, err := eth.GweiToWei(cfg.MinBaseFeeGwei) + if err != nil { + return Config{}, fmt.Errorf("invalid min base fee: %w", err) + } + + minTipCap, err := eth.GweiToWei(cfg.MinTipCapGwei) + if err != nil { + return Config{}, fmt.Errorf("invalid min tip cap: %w", err) + } + return Config{ Backend: l1, ResubmissionTimeout: cfg.ResubmissionTimeout, FeeLimitMultiplier: cfg.FeeLimitMultiplier, + FeeLimitThreshold: feeLimitThreshold, + MinBaseFee: minBaseFee, + MinTipCap: minTipCap, ChainID: chainID, TxSendTimeout: cfg.TxSendTimeout, TxNotInMempoolTimeout: cfg.TxNotInMempoolTimeout, @@ -306,6 +367,17 @@ type Config struct { // The multiplier applied to fee suggestions to put a hard limit on fee increases. FeeLimitMultiplier uint64 + // Minimum threshold (in Wei) at which the FeeLimitMultiplier takes effect. + // On low-fee networks, like test networks, this allows for arbitrary fee bumps + // below this threshold. + FeeLimitThreshold *big.Int + + // Minimum base fee (in Wei) to assume when determining tx fees. + MinBaseFee *big.Int + + // Minimum tip cap (in Wei) to enforce when determining tx fees. + MinTipCap *big.Int + // ChainID is the chain ID of the L1 chain. ChainID *big.Int @@ -353,6 +425,10 @@ func (m Config) Check() error { if m.FeeLimitMultiplier == 0 { return errors.New("must provide FeeLimitMultiplier") } + if m.MinBaseFee != nil && m.MinTipCap != nil && m.MinBaseFee.Cmp(m.MinTipCap) == -1 { + return fmt.Errorf("minBaseFee smaller than minTipCap, have %v < %v", + m.MinBaseFee, m.MinTipCap) + } if m.ResubmissionTimeout == 0 { return errors.New("must provide ResubmissionTimeout") } diff --git a/op-service/txmgr/metrics/noop.go b/op-service/txmgr/metrics/noop.go index 377b3c8046cd..80a2f6acb2e9 100644 --- a/op-service/txmgr/metrics/noop.go +++ b/op-service/txmgr/metrics/noop.go @@ -1,8 +1,11 @@ package metrics import ( - "github.com/ethereum-optimism/optimism/op-service/metrics" + "math/big" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/ethereum-optimism/optimism/op-service/metrics" ) type NoopTxMetrics struct { @@ -15,5 +18,7 @@ func (*NoopTxMetrics) RecordGasBumpCount(int) {} func (*NoopTxMetrics) RecordTxConfirmationLatency(int64) {} func (*NoopTxMetrics) TxConfirmed(*types.Receipt) {} func (*NoopTxMetrics) TxPublished(string) {} +func (*NoopTxMetrics) RecordBaseFee(*big.Int) {} +func (*NoopTxMetrics) RecordTipCap(*big.Int) {} func (*NoopTxMetrics) RPCError() {} func (m *NoopTxMetrics) RecordL1UrlSwitchEvt(url string) {} diff --git a/op-service/txmgr/metrics/tx_metrics.go b/op-service/txmgr/metrics/tx_metrics.go index 279366980241..e0cfb80a1fd7 100644 --- a/op-service/txmgr/metrics/tx_metrics.go +++ b/op-service/txmgr/metrics/tx_metrics.go @@ -1,6 +1,8 @@ package metrics import ( + "math/big" + "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/metrics" "github.com/ethereum/go-ethereum/core/types" @@ -15,6 +17,8 @@ type TxMetricer interface { RecordPendingTx(pending int64) TxConfirmed(*types.Receipt) TxPublished(string) + RecordBaseFee(*big.Int) + RecordTipCap(*big.Int) RPCError() client.FallbackClientMetricer metrics.RPCMetricer @@ -32,6 +36,8 @@ type TxMetrics struct { txPublishError *prometheus.CounterVec publishEvent *metrics.Event confirmEvent metrics.EventVec + baseFee prometheus.Gauge + tipCap prometheus.Gauge rpcError prometheus.Counter *client.FallbackClientMetrics } @@ -103,6 +109,18 @@ func MakeTxMetrics(ns string, factory metrics.Factory) TxMetrics { }, []string{"error"}), confirmEvent: metrics.NewEventVec(factory, ns, "txmgr", "confirm", "tx confirm", []string{"status"}), publishEvent: metrics.NewEvent(factory, ns, "txmgr", "publish", "tx publish"), + baseFee: factory.NewGauge(prometheus.GaugeOpts{ + Namespace: ns, + Name: "basefee_wei", + Help: "Latest L1 baseFee (in Wei)", + Subsystem: "txmgr", + }), + tipCap: factory.NewGauge(prometheus.GaugeOpts{ + Namespace: ns, + Name: "tipcap_wei", + Help: "Latest L1 suggested tip cap (in Wei)", + Subsystem: "txmgr", + }), rpcError: factory.NewCounter(prometheus.CounterOpts{ Namespace: ns, Name: "rpc_error_count", @@ -128,7 +146,6 @@ func (t *TxMetrics) TxConfirmed(receipt *types.Receipt) { t.TxL1GasFee.Set(fee) t.txFees.Add(fee) t.txFeeHistogram.Observe(fee) - } func (t *TxMetrics) RecordGasBumpCount(times int) { @@ -147,6 +164,16 @@ func (t *TxMetrics) TxPublished(errString string) { } } +func (t *TxMetrics) RecordBaseFee(baseFee *big.Int) { + bff, _ := baseFee.Float64() + t.baseFee.Set(bff) +} + +func (t *TxMetrics) RecordTipCap(tipcap *big.Int) { + tcf, _ := tipcap.Float64() + t.tipCap.Set(tcf) +} + func (t *TxMetrics) RPCError() { t.rpcError.Inc() } diff --git a/op-service/txmgr/mocks/TxManager.go b/op-service/txmgr/mocks/TxManager.go index 75058e3dabc5..a5c6f584537e 100644 --- a/op-service/txmgr/mocks/TxManager.go +++ b/op-service/txmgr/mocks/TxManager.go @@ -4,12 +4,9 @@ package mocks import ( context "context" - big "math/big" common "github.com/ethereum/go-ethereum/common" - ethereum "github.com/ethereum/go-ethereum" - mock "github.com/stretchr/testify/mock" txmgr "github.com/ethereum-optimism/optimism/op-service/txmgr" @@ -46,30 +43,9 @@ func (_m *TxManager) BlockNumber(ctx context.Context) (uint64, error) { return r0, r1 } -// Call provides a mock function with given fields: ctx, msg, blockNumber -func (_m *TxManager) Call(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { - ret := _m.Called(ctx, msg, blockNumber) - - var r0 []byte - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg, *big.Int) ([]byte, error)); ok { - return rf(ctx, msg, blockNumber) - } - if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg, *big.Int) []byte); ok { - r0 = rf(ctx, msg, blockNumber) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]byte) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, ethereum.CallMsg, *big.Int) error); ok { - r1 = rf(ctx, msg, blockNumber) - } else { - r1 = ret.Error(1) - } - - return r0, r1 +// Close provides a mock function with given fields: +func (_m *TxManager) Close() { + _m.Called() } // From provides a mock function with given fields: @@ -88,6 +64,20 @@ func (_m *TxManager) From() common.Address { return r0 } +// IsClosed provides a mock function with given fields: +func (_m *TxManager) IsClosed() bool { + ret := _m.Called() + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + // Send provides a mock function with given fields: ctx, candidate func (_m *TxManager) Send(ctx context.Context, candidate txmgr.TxCandidate) (*types.Receipt, error) { ret := _m.Called(ctx, candidate) diff --git a/op-service/txmgr/price_bump_test.go b/op-service/txmgr/price_bump_test.go index 5b32b12d0032..37d55be4fba0 100644 --- a/op-service/txmgr/price_bump_test.go +++ b/op-service/txmgr/price_bump_test.go @@ -14,18 +14,19 @@ import ( type priceBumpTest struct { prevGasTip int64 - prevBasefee int64 + prevBaseFee int64 newGasTip int64 - newBasefee int64 + newBaseFee int64 expectedTip int64 expectedFC int64 + isBlobTx bool } func (tc *priceBumpTest) run(t *testing.T) { - prevFC := calcGasFeeCap(big.NewInt(tc.prevBasefee), big.NewInt(tc.prevGasTip)) - lgr := testlog.Logger(t, log.LvlCrit) + prevFC := calcGasFeeCap(big.NewInt(tc.prevBaseFee), big.NewInt(tc.prevGasTip)) + lgr := testlog.Logger(t, log.LevelCrit) - tip, fc := updateFees(big.NewInt(tc.prevGasTip), prevFC, big.NewInt(tc.newGasTip), big.NewInt(tc.newBasefee), lgr) + tip, fc := updateFees(big.NewInt(tc.prevGasTip), prevFC, big.NewInt(tc.newGasTip), big.NewInt(tc.newBaseFee), tc.isBlobTx, lgr) require.Equal(t, tc.expectedTip, tip.Int64(), "tip must be as expected") require.Equal(t, tc.expectedFC, fc.Int64(), "fee cap must be as expected") @@ -35,55 +36,115 @@ func TestUpdateFees(t *testing.T) { require.Equal(t, int64(10), priceBump, "test must be updated if priceBump is adjusted") tests := []priceBumpTest{ { - prevGasTip: 100, prevBasefee: 1000, - newGasTip: 90, newBasefee: 900, + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 90, newBaseFee: 900, expectedTip: 110, expectedFC: 2310, }, { - prevGasTip: 100, prevBasefee: 1000, - newGasTip: 101, newBasefee: 1000, + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 90, newBaseFee: 900, + expectedTip: 200, expectedFC: 4200, + isBlobTx: true, + }, + { + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 101, newBaseFee: 1000, expectedTip: 110, expectedFC: 2310, }, { - prevGasTip: 100, prevBasefee: 1000, - newGasTip: 100, newBasefee: 1001, + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 101, newBaseFee: 1000, + expectedTip: 200, expectedFC: 4200, + isBlobTx: true, + }, + { + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 100, newBaseFee: 1001, expectedTip: 110, expectedFC: 2310, }, { - prevGasTip: 100, prevBasefee: 1000, - newGasTip: 101, newBasefee: 900, + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 100, newBaseFee: 1001, + expectedTip: 200, expectedFC: 4200, + isBlobTx: true, + }, + { + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 101, newBaseFee: 900, expectedTip: 110, expectedFC: 2310, }, { - prevGasTip: 100, prevBasefee: 1000, - newGasTip: 90, newBasefee: 1010, + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 101, newBaseFee: 900, + expectedTip: 200, expectedFC: 4200, + isBlobTx: true, + }, + { + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 90, newBaseFee: 1010, expectedTip: 110, expectedFC: 2310, }, { - prevGasTip: 100, prevBasefee: 1000, - newGasTip: 101, newBasefee: 2000, + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 90, newBaseFee: 1010, + expectedTip: 200, expectedFC: 4200, + isBlobTx: true, + }, + { + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 101, newBaseFee: 2000, expectedTip: 110, expectedFC: 4110, }, { - prevGasTip: 100, prevBasefee: 1000, - newGasTip: 120, newBasefee: 900, + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 101, newBaseFee: 3000, + expectedTip: 200, expectedFC: 6200, + isBlobTx: true, + }, + { + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 120, newBaseFee: 900, expectedTip: 120, expectedFC: 2310, }, { - prevGasTip: 100, prevBasefee: 1000, - newGasTip: 120, newBasefee: 1100, + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 220, newBaseFee: 900, + expectedTip: 220, expectedFC: 4200, + isBlobTx: true, + }, + { + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 120, newBaseFee: 1100, expectedTip: 120, expectedFC: 2320, }, { - prevGasTip: 100, prevBasefee: 1000, - newGasTip: 120, newBasefee: 1140, + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 220, newBaseFee: 2000, + expectedTip: 220, expectedFC: 4220, + isBlobTx: true, + }, + { + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 120, newBaseFee: 1140, expectedTip: 120, expectedFC: 2400, }, { - prevGasTip: 100, prevBasefee: 1000, - newGasTip: 120, newBasefee: 1200, + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 220, newBaseFee: 2040, + expectedTip: 220, expectedFC: 4300, + isBlobTx: true, + }, + { + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 120, newBaseFee: 1200, expectedTip: 120, expectedFC: 2520, }, + { + prevGasTip: 100, prevBaseFee: 1000, + newGasTip: 220, newBaseFee: 2100, + expectedTip: 220, expectedFC: 4420, + isBlobTx: true, + }, } for i, test := range tests { i := i diff --git a/op-service/txmgr/queue.go b/op-service/txmgr/queue.go index 619dd4f86b05..cf83b00d5f8a 100644 --- a/op-service/txmgr/queue.go +++ b/op-service/txmgr/queue.go @@ -10,7 +10,7 @@ import ( ) type TxReceipt[T any] struct { - // ID can be used to identify unique tx receipts within the recept channel + // ID can be used to identify unique tx receipts within the receipt channel ID T // Receipt result from the transaction send Receipt *types.Receipt @@ -28,9 +28,9 @@ type Queue[T any] struct { } // NewQueue creates a new transaction sending Queue, with the following parameters: +// - ctx: runtime context of the queue. If canceled, all ongoing send processes are canceled. +// - txMgr: transaction manager to use for transaction sending // - maxPending: max number of pending txs at once (0 == no limit) -// - pendingChanged: called whenever a tx send starts or finishes. The -// number of currently pending txs is passed as a parameter. func NewQueue[T any](ctx context.Context, txMgr TxManager, maxPending uint64) *Queue[T] { if maxPending > math.MaxInt { // ensure we don't overflow as errgroup only accepts int; in reality this will never be an issue diff --git a/op-service/txmgr/queue_test.go b/op-service/txmgr/queue_test.go index 0f08e8199095..e0b65d32fd09 100644 --- a/op-service/txmgr/queue_test.go +++ b/op-service/txmgr/queue_test.go @@ -38,15 +38,6 @@ type testTx struct { sendErr bool // error to return from send for this tx } -type testCase struct { - name string // name of the test - max uint64 // max concurrency of the queue - calls []queueCall // calls to the queue - txs []testTx // txs to generate from the factory (and potentially error in send) - nonces []uint64 // expected sent tx nonces after all calls are made - total time.Duration // approx. total time it should take to complete all queue calls -} - type mockBackendWithNonce struct { mockBackend } @@ -64,8 +55,15 @@ func (b *mockBackendWithNonce) NonceAt(ctx context.Context, account common.Addre return uint64(len(b.minedTxs)), nil } -func TestSend(t *testing.T) { - testCases := []testCase{ +func TestQueue_Send(t *testing.T) { + testCases := []struct { + name string // name of the test + max uint64 // max concurrency of the queue + calls []queueCall // calls to the queue + txs []testTx // txs to generate from the factory (and potentially error in send) + nonces []uint64 // expected sent tx nonces after all calls are made + total time.Duration // approx. total time it should take to complete all queue calls + }{ { name: "success", max: 5, @@ -160,7 +158,7 @@ func TestSend(t *testing.T) { {}, }, nonces: []uint64{0, 1}, - total: 3 * time.Second, + total: 1 * time.Second, }, } for _, test := range testCases { @@ -178,7 +176,7 @@ func TestSend(t *testing.T) { name: "TEST", cfg: conf, backend: backend, - l: testlog.Logger(t, log.LvlCrit), + l: testlog.Logger(t, log.LevelCrit), metr: &metrics.NoopTxMetrics{}, } @@ -195,7 +193,7 @@ func TestSend(t *testing.T) { return core.ErrNonceTooLow } txHash := tx.Hash() - backend.mine(&txHash, tx.GasFeeCap()) + backend.mine(&txHash, tx.GasFeeCap(), nil) return nil } backend.setTxSender(sendTx) @@ -206,24 +204,16 @@ func TestSend(t *testing.T) { // make all the queue calls given in the test case start := time.Now() + receiptChs := make([]chan TxReceipt[int], len(test.calls)) for i, c := range test.calls { msg := fmt.Sprintf("Call %d", i) - c := c - receiptCh := make(chan TxReceipt[int], 1) candidate := TxCandidate{ TxData: []byte{byte(i)}, To: &common.Address{}, } - queued := c.call(i, candidate, receiptCh, queue) + receiptChs[i] = make(chan TxReceipt[int], 1) + queued := c.call(i, candidate, receiptChs[i], queue) require.Equal(t, c.queued, queued, msg) - go func() { - r := <-receiptCh - if c.txErr { - require.Error(t, r.Err, msg) - } else { - require.NoError(t, r.Err, msg) - } - }() } // wait for the queue to drain (all txs complete or failed) queue.Wait() @@ -234,6 +224,20 @@ func TestSend(t *testing.T) { // check that the nonces match slices.Sort(nonces) require.Equal(t, test.nonces, nonces, "expected nonces do not match") + // check receipts + for i, c := range test.calls { + if !c.queued { + // non-queued txs won't have a tx result + continue + } + msg := fmt.Sprintf("Receipt %d", i) + r := <-receiptChs[i] + if c.txErr { + require.Error(t, r.Err, msg) + } else { + require.NoError(t, r.Err, msg) + } + } }) } } diff --git a/op-service/txmgr/send_state.go b/op-service/txmgr/send_state.go index e1878c64f9dd..7ccc52b2e151 100644 --- a/op-service/txmgr/send_state.go +++ b/op-service/txmgr/send_state.go @@ -1,7 +1,7 @@ package txmgr import ( - "strings" + "errors" "sync" "time" @@ -9,6 +9,17 @@ import ( "github.com/ethereum/go-ethereum/core" ) +var ( + // Returned by CriticalError when there is an incompatible tx type already in the mempool. + // geth defines this error as txpool.ErrAlreadyReserved in v1.13.14 so we can remove this + // declaration once op-geth is updated to this version. + ErrAlreadyReserved = errors.New("address already reserved") + + // Returned by CriticalError when the system is unable to get the tx into the mempool in the + // alloted time + ErrMempoolDeadlineExpired = errors.New("failed to get tx into the mempool") +) + // SendState tracks information about the publication state of a given txn. In // this context, a txn may correspond to multiple different txn hashes due to // varying gas prices, though we treat them all as the same logical txn. This @@ -27,6 +38,9 @@ type SendState struct { successFullPublishCount uint64 // nil error => tx made it to the mempool safeAbortNonceTooLowCount uint64 // nonce too low error + // Whether any attempt to send the tx resulted in ErrAlreadyReserved + alreadyReserved bool + // Miscellaneous tracking bumpCount int // number of times we have bumped the gas price } @@ -60,8 +74,10 @@ func (s *SendState) ProcessSendError(err error) { switch { case err == nil: s.successFullPublishCount++ - case strings.Contains(err.Error(), core.ErrNonceTooLow.Error()): + case errStringMatch(err, core.ErrNonceTooLow): s.nonceTooLowCount++ + case errStringMatch(err, ErrAlreadyReserved): + s.alreadyReserved = true } } @@ -93,27 +109,29 @@ func (s *SendState) TxNotMined(txHash common.Hash) { } } -// ShouldAbortImmediately returns true if the txmgr should give up on trying a -// given txn with the target nonce. -// This occurs when the set of errors recorded indicates that no further progress can be made -// on this transaction. -func (s *SendState) ShouldAbortImmediately() bool { +// CriticalError returns a non-nil error if the txmgr should give up on trying a given txn with the +// target nonce. This occurs when the set of errors recorded indicates that no further progress +// can be made on this transaction, or if there is an incompatible tx type currently in the +// mempool. +func (s *SendState) CriticalError() error { s.mu.RLock() defer s.mu.RUnlock() - // Never abort if our latest sample reports having at least one mined txn. - if len(s.minedTxs) > 0 { - return false - } - - // If we have exceeded the nonce too low count, abort - if s.nonceTooLowCount >= s.safeAbortNonceTooLowCount || - // If we have not published a transaction in the allotted time, abort - (s.successFullPublishCount == 0 && s.now().After(s.txInMempoolDeadline)) { - return true + switch { + case len(s.minedTxs) > 0: + // Never abort if our latest sample reports having at least one mined txn. + return nil + case s.nonceTooLowCount >= s.safeAbortNonceTooLowCount: + // we have exceeded the nonce too low count + return core.ErrNonceTooLow + case s.successFullPublishCount == 0 && s.now().After(s.txInMempoolDeadline): + // unable to get the tx into the mempool in the alloted time + return ErrMempoolDeadlineExpired + case s.alreadyReserved: + // incompatible tx type in mempool + return ErrAlreadyReserved } - - return false + return nil } // IsWaitingForConfirmation returns true if we have at least one confirmation on diff --git a/op-service/txmgr/send_state_test.go b/op-service/txmgr/send_state_test.go index fa768ed62b66..20bfe155ed97 100644 --- a/op-service/txmgr/send_state_test.go +++ b/op-service/txmgr/send_state_test.go @@ -1,4 +1,4 @@ -package txmgr_test +package txmgr import ( "errors" @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/require" - "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" ) @@ -18,15 +17,15 @@ var ( const testSafeAbortNonceTooLowCount = 3 -func newSendState() *txmgr.SendState { +func newSendState() *SendState { return newSendStateWithTimeout(time.Hour, time.Now) } -func newSendStateWithTimeout(t time.Duration, now func() time.Time) *txmgr.SendState { - return txmgr.NewSendStateWithNow(testSafeAbortNonceTooLowCount, t, now) +func newSendStateWithTimeout(t time.Duration, now func() time.Time) *SendState { + return NewSendStateWithNow(testSafeAbortNonceTooLowCount, t, now) } -func processNSendErrors(sendState *txmgr.SendState, err error, n int) { +func processNSendErrors(sendState *SendState, err error, n int) { for i := 0; i < n; i++ { sendState.ProcessSendError(err) } @@ -36,7 +35,7 @@ func processNSendErrors(sendState *txmgr.SendState, err error, n int) { // trigger an abort even after the safe abort interval has elapsed. func TestSendStateNoAbortAfterInit(t *testing.T) { sendState := newSendState() - require.False(t, sendState.ShouldAbortImmediately()) + require.Nil(t, sendState.CriticalError()) require.False(t, sendState.IsWaitingForConfirmation()) } @@ -46,7 +45,7 @@ func TestSendStateNoAbortAfterProcessNilError(t *testing.T) { sendState := newSendState() processNSendErrors(sendState, nil, testSafeAbortNonceTooLowCount) - require.False(t, sendState.ShouldAbortImmediately()) + require.Nil(t, sendState.CriticalError()) } // TestSendStateNoAbortAfterProcessOtherError asserts that non-nil errors other @@ -56,7 +55,7 @@ func TestSendStateNoAbortAfterProcessOtherError(t *testing.T) { otherError := errors.New("other error") processNSendErrors(sendState, otherError, testSafeAbortNonceTooLowCount) - require.False(t, sendState.ShouldAbortImmediately()) + require.Nil(t, sendState.CriticalError()) } // TestSendStateAbortSafelyAfterNonceTooLowButNoTxMined asserts that we will @@ -65,11 +64,11 @@ func TestSendStateAbortSafelyAfterNonceTooLowButNoTxMined(t *testing.T) { sendState := newSendState() sendState.ProcessSendError(core.ErrNonceTooLow) - require.False(t, sendState.ShouldAbortImmediately()) + require.Nil(t, sendState.CriticalError()) sendState.ProcessSendError(core.ErrNonceTooLow) - require.False(t, sendState.ShouldAbortImmediately()) + require.Nil(t, sendState.CriticalError()) sendState.ProcessSendError(core.ErrNonceTooLow) - require.True(t, sendState.ShouldAbortImmediately()) + require.ErrorIs(t, sendState.CriticalError(), core.ErrNonceTooLow) } // TestSendStateMiningTxCancelsAbort asserts that a tx getting mined after @@ -80,9 +79,9 @@ func TestSendStateMiningTxCancelsAbort(t *testing.T) { sendState.ProcessSendError(core.ErrNonceTooLow) sendState.ProcessSendError(core.ErrNonceTooLow) sendState.TxMined(testHash) - require.False(t, sendState.ShouldAbortImmediately()) + require.Nil(t, sendState.CriticalError()) sendState.ProcessSendError(core.ErrNonceTooLow) - require.False(t, sendState.ShouldAbortImmediately()) + require.Nil(t, sendState.CriticalError()) } // TestSendStateReorgingTxResetsAbort asserts that unmining a tx does not @@ -96,7 +95,7 @@ func TestSendStateReorgingTxResetsAbort(t *testing.T) { sendState.TxMined(testHash) sendState.TxNotMined(testHash) sendState.ProcessSendError(core.ErrNonceTooLow) - require.False(t, sendState.ShouldAbortImmediately()) + require.Nil(t, sendState.CriticalError()) } // TestSendStateNoAbortEvenIfNonceTooLowAfterTxMined asserts that we will not @@ -112,7 +111,7 @@ func TestSendStateNoAbortEvenIfNonceTooLowAfterTxMined(t *testing.T) { processNSendErrors( sendState, core.ErrNonceTooLow, testSafeAbortNonceTooLowCount, ) - require.False(t, sendState.ShouldAbortImmediately()) + require.Nil(t, sendState.CriticalError()) } // TestSendStateSafeAbortIfNonceTooLowPersistsAfterUnmine asserts that we will @@ -125,9 +124,9 @@ func TestSendStateSafeAbortIfNonceTooLowPersistsAfterUnmine(t *testing.T) { sendState.TxNotMined(testHash) sendState.ProcessSendError(core.ErrNonceTooLow) sendState.ProcessSendError(core.ErrNonceTooLow) - require.False(t, sendState.ShouldAbortImmediately()) + require.Nil(t, sendState.CriticalError()) sendState.ProcessSendError(core.ErrNonceTooLow) - require.True(t, sendState.ShouldAbortImmediately()) + require.ErrorIs(t, sendState.CriticalError(), core.ErrNonceTooLow) } // TestSendStateSafeAbortWhileCallingNotMinedOnUnminedTx asserts that we will @@ -140,7 +139,7 @@ func TestSendStateSafeAbortWhileCallingNotMinedOnUnminedTx(t *testing.T) { sendState, core.ErrNonceTooLow, testSafeAbortNonceTooLowCount, ) sendState.TxNotMined(testHash) - require.True(t, sendState.ShouldAbortImmediately()) + require.ErrorIs(t, sendState.CriticalError(), core.ErrNonceTooLow) } // TestSendStateIsWaitingForConfirmationAfterTxMined asserts that we are waiting @@ -179,7 +178,7 @@ func stepClock(step time.Duration) func() time.Time { // when no successful transactions have been recorded func TestSendStateTimeoutAbort(t *testing.T) { sendState := newSendStateWithTimeout(10*time.Millisecond, stepClock(20*time.Millisecond)) - require.True(t, sendState.ShouldAbortImmediately(), "Should abort after timing out") + require.ErrorIs(t, sendState.CriticalError(), ErrMempoolDeadlineExpired, "Should abort after timing out") } // TestSendStateNoTimeoutAbortIfPublishedTx ensure that this will not abort if there is @@ -187,5 +186,5 @@ func TestSendStateTimeoutAbort(t *testing.T) { func TestSendStateNoTimeoutAbortIfPublishedTx(t *testing.T) { sendState := newSendStateWithTimeout(10*time.Millisecond, stepClock(20*time.Millisecond)) sendState.ProcessSendError(nil) - require.False(t, sendState.ShouldAbortImmediately(), "Should not abort if published transcation successfully") + require.Nil(t, sendState.CriticalError(), "Should not abort if published transaction successfully") } diff --git a/op-service/txmgr/txmgr.go b/op-service/txmgr/txmgr.go index 1a616da64709..b60ba4e21fed 100644 --- a/op-service/txmgr/txmgr.go +++ b/op-service/txmgr/txmgr.go @@ -12,24 +12,41 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" - "github.com/ethereum-optimism/optimism/op-service/bsc" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" ) const ( - // Geth requires a minimum fee bump of 10% for tx resubmission + // geth requires a minimum fee bump of 10% for regular tx resubmission priceBump int64 = 10 + // geth requires a minimum fee bump of 100% for blob tx resubmission + blobPriceBump int64 = 100 ) -// new = old * (100 + priceBump) / 100 -var priceBumpPercent = big.NewInt(100 + priceBump) -var oneHundred = big.NewInt(100) +var ( + priceBumpPercent = big.NewInt(100 + priceBump) + blobPriceBumpPercent = big.NewInt(100 + blobPriceBump) + + // geth enforces a 1 gwei minimum for blob tx fee + minBlobTxFee = big.NewInt(params.GWei) + + oneHundred = big.NewInt(100) + ninetyNine = big.NewInt(99) + two = big.NewInt(2) + + ErrBlobFeeLimit = errors.New("blob fee limit reached") + ErrClosed = errors.New("transaction manager is closed") +) // TxManager is an interface that allows callers to reliably publish txs, // bumping the gas price if needed, and obtain the receipt of the resulting tx. @@ -42,18 +59,22 @@ type TxManager interface { // may be included on L1 even if the context is cancelled. // // NOTE: Send can be called concurrently, the nonce will be managed internally. + // + // Callers using both Blob and non-Blob transactions should check to see if the returned error + // is ErrAlreadyReserved, which indicates an incompatible transaction may be stuck in the + // mempool and is in need of replacement or cancellation. Send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error) - // Call is used to call a contract. - // Internally, it uses the [ethclient.Client.CallContract] method. - Call(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) - // From returns the sending address associated with the instance of the transaction manager. // It is static for a single instance of a TxManager. From() common.Address // BlockNumber returns the most recent block number from the underlying network. BlockNumber(ctx context.Context) (uint64, error) + + // Close the underlying connection + Close() + IsClosed() bool } // ETHBackend is the set of methods that the transaction manager uses to resubmit gas & determine @@ -73,7 +94,7 @@ type ETHBackend interface { // SendTransaction submits a signed transaction to L1. SendTransaction(ctx context.Context, tx *types.Transaction) error - // These functions are used to estimate what the basefee & priority fee should be set to. + // These functions are used to estimate what the base fee & priority fee should be set to. // TODO(CLI-3318): Maybe need a generic interface to support different RPC providers HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) SuggestGasTipCap(ctx context.Context) (*big.Int, error) @@ -85,6 +106,8 @@ type ETHBackend interface { // EstimateGas returns an estimate of the amount of gas needed to execute the given // transaction against the current pending block. EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) + // Close the underlying eth connection + Close() } // SimpleTxManager is a implementation of TxManager that performs linear fee @@ -102,6 +125,8 @@ type SimpleTxManager struct { nonceLock sync.RWMutex pending atomic.Int64 + + closed atomic.Bool } // NewSimpleTxManager initializes a new SimpleTxManager with the passed Config. @@ -136,11 +161,33 @@ func (m *SimpleTxManager) BlockNumber(ctx context.Context) (uint64, error) { return m.backend.BlockNumber(ctx) } +// Close closes the underlying connection, and sets the closed flag. +// once closed, the tx manager will refuse to send any new transactions, and may abandon pending ones. +func (m *SimpleTxManager) Close() { + m.backend.Close() + m.closed.Store(true) +} + +func (m *SimpleTxManager) txLogger(tx *types.Transaction, logGas bool) log.Logger { + fields := []any{"tx", tx.Hash(), "nonce", tx.Nonce()} + if logGas { + fields = append(fields, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap(), "gasLimit", tx.Gas()) + } + if len(tx.BlobHashes()) != 0 { + // log the number of blobs a tx has only if it's a blob tx + fields = append(fields, "blobs", len(tx.BlobHashes()), "blobFeeCap", tx.BlobGasFeeCap()) + } + return m.l.New(fields...) +} + // TxCandidate is a transaction candidate that can be submitted to ask the // [TxManager] to construct a transaction with gas price bounds. type TxCandidate struct { - // TxData is the transaction data to be used in the constructed tx. + // TxData is the transaction calldata to be used in the constructed tx. TxData []byte + // Blobs to send along in the tx (optional). If len(Blobs) > 0 then a blob tx + // will be sent instead of a DynamicFeeTx. + Blobs []*eth.Blob // To is the recipient of the constructed tx. Nil means contract creation. To *common.Address // GasLimit is the gas limit to be used in the constructed tx. @@ -159,6 +206,10 @@ type TxCandidate struct { // // NOTE: Send can be called concurrently, the nonce will be managed internally. func (m *SimpleTxManager) Send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error) { + // refuse new requests if the tx manager is closed + if m.closed.Load() { + return nil, ErrClosed + } m.metr.RecordPendingTx(m.pending.Add(1)) defer func() { m.metr.RecordPendingTx(m.pending.Add(-1)) @@ -170,12 +221,6 @@ func (m *SimpleTxManager) Send(ctx context.Context, candidate TxCandidate) (*typ return receipt, err } -// Call is used to call a contract. -// Internally, it uses the [ethclient.Client.CallContract] method. -func (m *SimpleTxManager) Call(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { - return m.backend.CallContract(ctx, msg, blockNumber) -} - // send performs the actual transaction creation and sending. func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error) { if m.cfg.TxSendTimeout != 0 { @@ -184,6 +229,9 @@ func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*typ defer cancel() } tx, err := retry.Do(ctx, 30, retry.Fixed(2*time.Second), func() (*types.Transaction, error) { + if m.closed.Load() { + return nil, ErrClosed + } tx, err := m.craftTx(ctx, candidate) if err != nil { m.l.Warn("Failed to create a transaction, will retry", "err", err) @@ -202,44 +250,97 @@ func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*typ // NOTE: If the [TxCandidate.GasLimit] is non-zero, it will be used as the transaction's gas. // NOTE: Otherwise, the [SimpleTxManager] will query the specified backend for an estimate. func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (*types.Transaction, error) { - gasTipCap, basefee, err := m.suggestGasPriceCaps(ctx) + m.l.Debug("crafting Transaction", "blobs", len(candidate.Blobs), "calldata_size", len(candidate.TxData)) + gasTipCap, baseFee, blobBaseFee, err := m.suggestGasPriceCaps(ctx) if err != nil { m.metr.RPCError() return nil, fmt.Errorf("failed to get gas price info: %w", err) } - gasFeeCap := calcGasFeeCap(basefee, gasTipCap) + gasFeeCap := calcGasFeeCap(baseFee, gasTipCap) - rawTx := &types.DynamicFeeTx{ - ChainID: m.chainID, - To: candidate.To, - GasTipCap: gasTipCap, - GasFeeCap: gasFeeCap, - Data: candidate.TxData, - Value: candidate.Value, - } - - m.l.Info("Creating tx", "to", rawTx.To, "from", m.cfg.From) + gasLimit := candidate.GasLimit // If the gas limit is set, we can use that as the gas - if candidate.GasLimit != 0 { - rawTx.Gas = candidate.GasLimit - } else { + if gasLimit == 0 { // Calculate the intrinsic gas for the transaction - gas, err := m.backend.EstimateGas(ctx, bsc.ToLegacyCallMsg(ethereum.CallMsg{ + gas, err := m.backend.EstimateGas(ctx, ethereum.CallMsg{ From: m.cfg.From, To: candidate.To, - GasFeeCap: gasFeeCap, GasTipCap: gasTipCap, - Data: rawTx.Data, - Value: rawTx.Value, - })) + GasFeeCap: gasFeeCap, + Data: candidate.TxData, + Value: candidate.Value, + }) if err != nil { return nil, fmt.Errorf("failed to estimate gas: %w", err) } - rawTx.Gas = gas + gasLimit = gas + } + + var sidecar *types.BlobTxSidecar + var blobHashes []common.Hash + if len(candidate.Blobs) > 0 { + if candidate.To == nil { + return nil, errors.New("blob txs cannot deploy contracts") + } + if sidecar, blobHashes, err = MakeSidecar(candidate.Blobs); err != nil { + return nil, fmt.Errorf("failed to make sidecar: %w", err) + } + } + + var txMessage types.TxData + if sidecar != nil { + if blobBaseFee == nil { + return nil, fmt.Errorf("expected non-nil blobBaseFee") + } + blobFeeCap := calcBlobFeeCap(blobBaseFee) + message := &types.BlobTx{ + To: *candidate.To, + Data: candidate.TxData, + Gas: gasLimit, + BlobHashes: blobHashes, + Sidecar: sidecar, + } + if err := finishBlobTx(message, m.chainID, gasTipCap, gasFeeCap, blobFeeCap, candidate.Value); err != nil { + return nil, fmt.Errorf("failed to create blob transaction: %w", err) + } + txMessage = message + } else { + txMessage = &types.DynamicFeeTx{ + ChainID: m.chainID, + To: candidate.To, + GasTipCap: gasTipCap, + GasFeeCap: gasFeeCap, + Value: candidate.Value, + Data: candidate.TxData, + Gas: gasLimit, + } } + return m.signWithNextNonce(ctx, txMessage) // signer sets the nonce field of the tx + +} - return m.signWithNextNonce(ctx, rawTx) +// MakeSidecar builds & returns the BlobTxSidecar and corresponding blob hashes from the raw blob +// data. +func MakeSidecar(blobs []*eth.Blob) (*types.BlobTxSidecar, []common.Hash, error) { + sidecar := &types.BlobTxSidecar{} + blobHashes := []common.Hash{} + for i, blob := range blobs { + rawBlob := *blob.KZGBlob() + sidecar.Blobs = append(sidecar.Blobs, rawBlob) + commitment, err := kzg4844.BlobToCommitment(rawBlob) + if err != nil { + return nil, nil, fmt.Errorf("cannot compute KZG commitment of blob %d in tx candidate: %w", i, err) + } + sidecar.Commitments = append(sidecar.Commitments, commitment) + proof, err := kzg4844.ComputeBlobProof(rawBlob, commitment) + if err != nil { + return nil, nil, fmt.Errorf("cannot compute KZG proof for fast commitment verification of blob %d in tx candidate: %w", i, err) + } + sidecar.Proofs = append(sidecar.Proofs, proof) + blobHashes = append(blobHashes, eth.KZGToVersionedHash(commitment)) + } + return sidecar, blobHashes, nil } // signWithNextNonce returns a signed transaction with the next available nonce. @@ -247,7 +348,7 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (* // then subsequent calls simply increment this number. If the transaction manager // is reset, it will query the eth_getTransactionCount nonce again. If signing // fails, the nonce is not incremented. -func (m *SimpleTxManager) signWithNextNonce(ctx context.Context, rawTx *types.DynamicFeeTx) (*types.Transaction, error) { +func (m *SimpleTxManager) signWithNextNonce(ctx context.Context, txMessage types.TxData) (*types.Transaction, error) { m.nonceLock.Lock() defer m.nonceLock.Unlock() @@ -265,12 +366,17 @@ func (m *SimpleTxManager) signWithNextNonce(ctx context.Context, rawTx *types.Dy *m.nonce++ } - rawTx.Nonce = *m.nonce + switch x := txMessage.(type) { + case *types.DynamicFeeTx: + x.Nonce = *m.nonce + case *types.BlobTx: + x.Nonce = *m.nonce + default: + return nil, fmt.Errorf("unrecognized tx type: %T", x) + } ctx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout) defer cancel() - - legacyTx := bsc.ToLegacyTx(rawTx) - tx, err := m.cfg.Signer(ctx, m.cfg.From, types.NewTx(legacyTx)) + tx, err := m.cfg.Signer(ctx, m.cfg.From, types.NewTx(txMessage)) if err != nil { // decrement the nonce, so we can retry signing with the same nonce next time // signWithNextNonce is called @@ -320,16 +426,20 @@ func (m *SimpleTxManager) sendTx(ctx context.Context, tx *types.Transaction) (*t defer ticker.Stop() for { + if err := sendState.CriticalError(); err != nil { + m.txLogger(tx, false).Warn("Aborting transaction submission", "err", err) + return nil, fmt.Errorf("aborted tx send due to critical error: %w", err) + } select { case <-ticker.C: // Don't resubmit a transaction if it has been mined, but we are waiting for the conf depth. if sendState.IsWaitingForConfirmation() { continue } - // If we see lots of unrecoverable errors (and no pending transactions) abort sending the transaction. - if sendState.ShouldAbortImmediately() { - m.l.Warn("Aborting transaction submission") - return nil, errors.New("aborted transaction sending") + // if the tx manager closed while we were waiting for the tx, give up + if m.closed.Load() { + m.txLogger(tx, false).Warn("TxManager closed, aborting transaction submission") + return nil, ErrClosed } tx = publishAndWait(tx, true) @@ -348,14 +458,16 @@ func (m *SimpleTxManager) sendTx(ctx context.Context, tx *types.Transaction) (*t // it will bump the fees and retry. // Returns the latest fee bumped tx, and a boolean indicating whether the tx was sent or not func (m *SimpleTxManager) publishTx(ctx context.Context, tx *types.Transaction, sendState *SendState, bumpFeesImmediately bool) (*types.Transaction, bool) { - updateLogFields := func(tx *types.Transaction) log.Logger { - return m.l.New("hash", tx.Hash(), "nonce", tx.Nonce(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) - } - l := updateLogFields(tx) + l := m.txLogger(tx, true) l.Info("Publishing transaction") for { + // if the tx manager closed, give up without bumping fees or retrying + if m.closed.Load() { + l.Warn("TxManager closed, aborting transaction submission") + return tx, false + } if bumpFeesImmediately { newTx, err := m.increaseGasPrice(ctx, tx) if err != nil { @@ -365,7 +477,7 @@ func (m *SimpleTxManager) publishTx(ctx context.Context, tx *types.Transaction, } tx = newTx sendState.bumpCount++ - l = updateLogFields(tx) + l = m.txLogger(tx, true) } bumpFeesImmediately = true // bump fees next loop @@ -382,14 +494,19 @@ func (m *SimpleTxManager) publishTx(ctx context.Context, tx *types.Transaction, if err == nil { m.metr.TxPublished("") - log.Info("Transaction successfully published") + l.Info("Transaction successfully published") return tx, true } switch { + case errStringMatch(err, ErrAlreadyReserved): + // this can happen if, say, a blob transaction is stuck in the mempool and we try to + // send a non-blob transaction (and vice-versa). + l.Warn("txpool contains pending tx of incompatible type", "err", err) + m.metr.TxPublished("pending_tx_of_incompatible_type") case errStringMatch(err, core.ErrNonceTooLow): l.Warn("nonce too low", "err", err) - m.metr.TxPublished("nonce_to_low") + m.metr.TxPublished("nonce_too_low") case errStringMatch(err, context.Canceled): m.metr.RPCError() l.Warn("transaction send cancelled", "err", err) @@ -424,7 +541,7 @@ func (m *SimpleTxManager) waitForTx(ctx context.Context, tx *types.Transaction, receipt, err := m.waitMined(ctx, tx, sendState) if err != nil { // this will happen if the tx was successfully replaced by a tx with bumped fees - log.Info("Transaction receipt not found", "err", err) + m.txLogger(tx, true).Info("Transaction receipt not found", "err", err) return } select { @@ -458,15 +575,15 @@ func (m *SimpleTxManager) queryReceipt(ctx context.Context, txHash common.Hash, receipt, err := m.backend.TransactionReceipt(ctx, txHash) if errors.Is(err, ethereum.NotFound) { sendState.TxNotMined(txHash) - m.l.Trace("Transaction not yet mined", "hash", txHash) + m.l.Trace("Transaction not yet mined", "tx", txHash) return nil } else if err != nil { m.metr.RPCError() - m.l.Info("Receipt retrieval failed", "hash", txHash, "err", err) + m.l.Info("Receipt retrieval failed", "tx", txHash, "err", err) return nil } else if receipt == nil { m.metr.RPCError() - m.l.Warn("Receipt and error are both nil", "hash", txHash) + m.l.Warn("Receipt and error are both nil", "tx", txHash) return nil } @@ -474,14 +591,17 @@ func (m *SimpleTxManager) queryReceipt(ctx context.Context, txHash common.Hash, sendState.TxMined(txHash) txHeight := receipt.BlockNumber.Uint64() - tipHeight, err := m.backend.BlockNumber(ctx) + tip, err := m.backend.HeaderByNumber(ctx, nil) if err != nil { - m.l.Error("Unable to fetch block number", "err", err) + m.metr.RPCError() + m.l.Error("Unable to fetch tip", "err", err) return nil } - m.l.Debug("Transaction mined, checking confirmations", "hash", txHash, "txHeight", txHeight, - "tipHeight", tipHeight, "numConfirmations", m.cfg.NumConfirmations) + m.metr.RecordBaseFee(tip.BaseFee) + m.l.Debug("Transaction mined, checking confirmations", "tx", txHash, + "block", eth.ReceiptBlockID(receipt), "tip", eth.HeaderBlockID(tip), + "numConfirmations", m.cfg.NumConfirmations) // The transaction is considered confirmed when // txHeight+numConfirmations-1 <= tipHeight. Note that the -1 is @@ -490,139 +610,234 @@ func (m *SimpleTxManager) queryReceipt(ctx context.Context, txHash common.Hash, // transaction should be confirmed when txHeight is equal to // tipHeight. The equation is rewritten in this form to avoid // underflows. + tipHeight := tip.Number.Uint64() if txHeight+m.cfg.NumConfirmations <= tipHeight+1 { - m.l.Info("Transaction confirmed", "hash", txHash) + m.l.Info("Transaction confirmed", "tx", txHash, + "block", eth.ReceiptBlockID(receipt), + "effectiveGasPrice", receipt.EffectiveGasPrice) return receipt } // Safe to subtract since we know the LHS above is greater. confsRemaining := (txHeight + m.cfg.NumConfirmations) - (tipHeight + 1) - m.l.Debug("Transaction not yet confirmed", "hash", txHash, "confsRemaining", confsRemaining) + m.l.Debug("Transaction not yet confirmed", "tx", txHash, "confsRemaining", confsRemaining) return nil } -// increaseGasPrice takes the previous transaction, clones it, and returns it with fee values that -// are at least `priceBump` percent higher than the previous ones to satisfy Geth's replacement -// rules, and no lower than the values returned by the fee suggestion algorithm to ensure it -// doesn't linger in the mempool. Finally to avoid runaway price increases, fees are capped at a -// `feeLimitMultiplier` multiple of the suggested values. +// increaseGasPrice returns a new transaction that is equivalent to the input transaction but with +// higher fees that should satisfy geth's tx replacement rules. It also computes an updated gas +// limit estimate. To avoid runaway price increases, fees are capped at a `feeLimitMultiplier` +// multiple of the suggested values. func (m *SimpleTxManager) increaseGasPrice(ctx context.Context, tx *types.Transaction) (*types.Transaction, error) { - m.l.Info("bumping gas price for tx", "hash", tx.Hash(), "tip", tx.GasTipCap(), "fee", tx.GasFeeCap(), "gaslimit", tx.Gas()) - tip, basefee, err := m.suggestGasPriceCaps(ctx) + m.txLogger(tx, true).Info("bumping gas price for transaction") + tip, baseFee, blobBaseFee, err := m.suggestGasPriceCaps(ctx) if err != nil { - m.l.Warn("failed to get suggested gas tip and basefee", "err", err) + m.txLogger(tx, false).Warn("failed to get suggested gas tip and base fee", "err", err) return nil, err } - bumpedTip, bumpedFee := updateFees(tx.GasTipCap(), tx.GasFeeCap(), tip, basefee, m.l) + bumpedTip, bumpedFee := updateFees(tx.GasTipCap(), tx.GasFeeCap(), tip, baseFee, tx.Type() == types.BlobTxType, m.l) - // Make sure increase is at most [FeeLimitMultiplier] the suggested values - maxTip := new(big.Int).Mul(tip, big.NewInt(int64(m.cfg.FeeLimitMultiplier))) - if bumpedTip.Cmp(maxTip) > 0 { - return nil, fmt.Errorf("bumped tip 0x%s is over %dx multiple of the suggested value", bumpedTip.Text(16), m.cfg.FeeLimitMultiplier) - } - maxFee := calcGasFeeCap(new(big.Int).Mul(basefee, big.NewInt(int64(m.cfg.FeeLimitMultiplier))), maxTip) - if bumpedFee.Cmp(maxFee) > 0 { - return nil, fmt.Errorf("bumped fee 0x%s is over %dx multiple of the suggested value", bumpedFee.Text(16), m.cfg.FeeLimitMultiplier) - } - rawTx := &types.DynamicFeeTx{ - ChainID: tx.ChainId(), - Nonce: tx.Nonce(), - GasTipCap: bumpedTip, - GasFeeCap: bumpedFee, - To: tx.To(), - Value: tx.Value(), - Data: tx.Data(), - AccessList: tx.AccessList(), + if err := m.checkLimits(tip, baseFee, bumpedTip, bumpedFee); err != nil { + return nil, err } // Re-estimate gaslimit in case things have changed or a previous gaslimit estimate was wrong gas, err := m.backend.EstimateGas(ctx, ethereum.CallMsg{ From: m.cfg.From, - To: rawTx.To, - GasFeeCap: bumpedTip, - GasTipCap: bumpedFee, - Data: rawTx.Data, + To: tx.To(), + GasTipCap: bumpedTip, + GasFeeCap: bumpedFee, + Data: tx.Data(), + Value: tx.Value(), }) if err != nil { // If this is a transaction resubmission, we sometimes see this outcome because the // original tx can get included in a block just before the above call. In this case the // error is due to the tx reverting with message "block number must be equal to next // expected block number" - m.l.Warn("failed to re-estimate gas", "err", err, "gaslimit", tx.Gas()) + m.l.Warn("failed to re-estimate gas", "err", err, "tx", tx.Hash(), "gaslimit", tx.Gas(), + "gasFeeCap", bumpedFee, "gasTipCap", bumpedTip) return nil, err } if tx.Gas() != gas { - m.l.Info("re-estimated gas differs", "oldgas", tx.Gas(), "newgas", gas) + // non-determinism in gas limit estimation happens regularly due to underlying state + // changes across calls, and is even more common now that geth uses an in-exact estimation + // approach as of v1.13.6. + m.l.Debug("re-estimated gas differs", "tx", tx.Hash(), "oldgas", tx.Gas(), "newgas", gas, + "gasFeeCap", bumpedFee, "gasTipCap", bumpedTip) + } + + var newTx *types.Transaction + if tx.Type() == types.BlobTxType { + // Blob transactions have an additional blob gas price we must specify, so we must make sure it is + // getting bumped appropriately. + bumpedBlobFee := calcThresholdValue(tx.BlobGasFeeCap(), true) + if bumpedBlobFee.Cmp(blobBaseFee) < 0 { + bumpedBlobFee = blobBaseFee + } + if err := m.checkBlobFeeLimits(blobBaseFee, bumpedBlobFee); err != nil { + return nil, err + } + message := &types.BlobTx{ + Nonce: tx.Nonce(), + To: *tx.To(), + Data: tx.Data(), + Gas: gas, + BlobHashes: tx.BlobHashes(), + Sidecar: tx.BlobTxSidecar(), + } + if err := finishBlobTx(message, tx.ChainId(), bumpedTip, bumpedFee, bumpedBlobFee, tx.Value()); err != nil { + return nil, err + } + newTx = types.NewTx(message) + } else { + newTx = types.NewTx(&types.DynamicFeeTx{ + ChainID: tx.ChainId(), + Nonce: tx.Nonce(), + To: tx.To(), + GasTipCap: bumpedTip, + GasFeeCap: bumpedFee, + Value: tx.Value(), + Data: tx.Data(), + Gas: gas, + }) } - rawTx.Gas = gas ctx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout) defer cancel() - - legacyTx := bsc.ToLegacyTx(rawTx) - newTx, err := m.cfg.Signer(ctx, m.cfg.From, types.NewTx(legacyTx)) + signedTx, err := m.cfg.Signer(ctx, m.cfg.From, newTx) if err != nil { - m.l.Warn("failed to sign new transaction", "err", err) + m.l.Warn("failed to sign new transaction", "err", err, "tx", tx.Hash()) return tx, nil } - return newTx, nil + return signedTx, nil } -// suggestGasPriceCaps suggests what the new tip & new basefee should be based on the current L1 conditions -func (m *SimpleTxManager) suggestGasPriceCaps(ctx context.Context) (*big.Int, *big.Int, error) { +// suggestGasPriceCaps suggests what the new tip, base fee, and blob base fee should be based on +// the current L1 conditions. blobfee will be nil if 4844 is not yet active. +func (m *SimpleTxManager) suggestGasPriceCaps(ctx context.Context) (*big.Int, *big.Int, *big.Int, error) { cCtx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout) defer cancel() tip, err := m.backend.SuggestGasTipCap(cCtx) if err != nil { m.metr.RPCError() - return nil, nil, fmt.Errorf("failed to fetch the suggested gas tip cap: %w", err) + return nil, nil, nil, fmt.Errorf("failed to fetch the suggested gas tip cap: %w", err) } else if tip == nil { - return nil, nil, errors.New("the suggested tip was nil") + return nil, nil, nil, errors.New("the suggested tip was nil") } cCtx, cancel = context.WithTimeout(ctx, m.cfg.NetworkTimeout) defer cancel() head, err := m.backend.HeaderByNumber(cCtx, nil) if err != nil { m.metr.RPCError() - return nil, nil, fmt.Errorf("failed to fetch the suggested basefee: %w", err) + return nil, nil, nil, fmt.Errorf("failed to fetch the suggested base fee: %w", err) } else if head.BaseFee == nil { //return nil, nil, errors.New("txmgr does not support pre-london blocks that do not have a basefee") + } + + // basefee of BSC block is 0 + baseFee := big.NewInt(0) + m.metr.RecordBaseFee(baseFee) + m.metr.RecordTipCap(tip) + + // Enforce minimum base fee and tip cap + if minTipCap := m.cfg.MinTipCap; minTipCap != nil && tip.Cmp(minTipCap) == -1 { + m.l.Debug("Enforcing min tip cap", "minTipCap", m.cfg.MinTipCap, "origTipCap", tip) + tip = new(big.Int).Set(m.cfg.MinTipCap) + } + if minBaseFee := m.cfg.MinBaseFee; minBaseFee != nil && baseFee.Cmp(minBaseFee) == -1 { + m.l.Debug("Enforcing min base fee", "minBaseFee", m.cfg.MinBaseFee, "origBaseFee", baseFee) + baseFee = new(big.Int).Set(m.cfg.MinBaseFee) + } - // Compatible to BSC - return tip, big.NewInt(0), nil + var blobFee *big.Int + if head.ExcessBlobGas != nil { + blobFee = eip4844.CalcBlobFee(*head.ExcessBlobGas) } - return tip, head.BaseFee, nil + return tip, baseFee, blobFee, nil } -// calcThresholdValue returns x * priceBumpPercent / 100 -func calcThresholdValue(x *big.Int) *big.Int { - threshold := new(big.Int).Mul(priceBumpPercent, x) - threshold = threshold.Div(threshold, oneHundred) - return threshold +// checkLimits checks that the tip and baseFee have not increased by more than the configured multipliers +// if FeeLimitThreshold is specified in config, any increase which stays under the threshold are allowed +func (m *SimpleTxManager) checkLimits(tip, baseFee, bumpedTip, bumpedFee *big.Int) (errs error) { + threshold := m.cfg.FeeLimitThreshold + limit := big.NewInt(int64(m.cfg.FeeLimitMultiplier)) + maxTip := new(big.Int).Mul(tip, limit) + maxFee := calcGasFeeCap(new(big.Int).Mul(baseFee, limit), maxTip) + + // generic check function to check tip and fee, and build up an error + check := func(v, max *big.Int, name string) { + // if threshold is specified and the value is under the threshold, no need to check the max + if threshold != nil && threshold.Cmp(v) > 0 { + return + } + // if the value is over the max, add an error message + if v.Cmp(max) > 0 { + errs = errors.Join(errs, fmt.Errorf("bumped %s cap %v is over %dx multiple of the suggested value", name, v, limit)) + } + } + check(bumpedTip, maxTip, "tip") + check(bumpedFee, maxFee, "fee") + + return errs } -// updateFees takes an old transaction's tip & fee cap plus a new tip & basefee, and returns +func (m *SimpleTxManager) checkBlobFeeLimits(blobBaseFee, bumpedBlobFee *big.Int) error { + // If below threshold, don't apply multiplier limit. Note we use same threshold parameter here + // used for non-blob fee limiting. + if thr := m.cfg.FeeLimitThreshold; thr != nil && thr.Cmp(bumpedBlobFee) == 1 { + return nil + } + maxBlobFee := new(big.Int).Mul(calcBlobFeeCap(blobBaseFee), big.NewInt(int64(m.cfg.FeeLimitMultiplier))) + if bumpedBlobFee.Cmp(maxBlobFee) > 0 { + return fmt.Errorf( + "bumped blob fee %v is over %dx multiple of the suggested value: %w", + bumpedBlobFee, m.cfg.FeeLimitMultiplier, ErrBlobFeeLimit) + } + return nil +} + +// IsClosed returns true if the tx manager is closed. +func (m *SimpleTxManager) IsClosed() bool { + return m.closed.Load() +} + +// calcThresholdValue returns ceil(x * priceBumpPercent / 100) for non-blob txs, or +// ceil(x * blobPriceBumpPercent / 100) for blob txs. +// It guarantees that x is increased by at least 1 +func calcThresholdValue(x *big.Int, isBlobTx bool) *big.Int { + threshold := new(big.Int) + if isBlobTx { + threshold.Set(blobPriceBumpPercent) + } else { + threshold.Set(priceBumpPercent) + } + return threshold.Mul(threshold, x).Add(threshold, ninetyNine).Div(threshold, oneHundred) +} + +// updateFees takes an old transaction's tip & fee cap plus a new tip & base fee, and returns // a suggested tip and fee cap such that: // -// (a) each satisfies geth's required tx-replacement fee bumps (we use a 10% increase), and +// (a) each satisfies geth's required tx-replacement fee bumps, and // (b) gasTipCap is no less than new tip, and // (c) gasFeeCap is no less than calcGasFee(newBaseFee, newTip) -func updateFees(oldTip, oldFeeCap, newTip, newBaseFee *big.Int, lgr log.Logger) (*big.Int, *big.Int) { +func updateFees(oldTip, oldFeeCap, newTip, newBaseFee *big.Int, isBlobTx bool, lgr log.Logger) (*big.Int, *big.Int) { newFeeCap := calcGasFeeCap(newBaseFee, newTip) - lgr = lgr.New("old_tip", oldTip, "old_feecap", oldFeeCap, "new_tip", newTip, "new_feecap", newFeeCap) - thresholdTip := calcThresholdValue(oldTip) - thresholdFeeCap := calcThresholdValue(oldFeeCap) + lgr = lgr.New("old_gasTipCap", oldTip, "old_gasFeeCap", oldFeeCap, + "new_gasTipCap", newTip, "new_gasFeeCap", newFeeCap, "new_baseFee", newBaseFee) + thresholdTip := calcThresholdValue(oldTip, isBlobTx) + thresholdFeeCap := calcThresholdValue(oldFeeCap, isBlobTx) if newTip.Cmp(thresholdTip) >= 0 && newFeeCap.Cmp(thresholdFeeCap) >= 0 { lgr.Debug("Using new tip and feecap") return newTip, newFeeCap } else if newTip.Cmp(thresholdTip) >= 0 && newFeeCap.Cmp(thresholdFeeCap) < 0 { - // Tip has gone up, but basefee is flat or down. + // Tip has gone up, but base fee is flat or down. // TODO(CLI-3714): Do we need to recalculate the FC here? lgr.Debug("Using new tip and threshold feecap") return newTip, thresholdFeeCap } else if newTip.Cmp(thresholdTip) < 0 && newFeeCap.Cmp(thresholdFeeCap) >= 0 { - // Basefee has gone up, but the tip hasn't. Recalculate the feecap because if the tip went up a lot - // not enough of the feecap may be dedicated to paying the basefee. + // Base fee has gone up, but the tip hasn't. Recalculate the feecap because if the tip went up a lot + // not enough of the feecap may be dedicated to paying the base fee. lgr.Debug("Using threshold tip and recalculated feecap") return thresholdTip, calcGasFeeCap(newBaseFee, thresholdTip) @@ -640,10 +855,20 @@ func updateFees(oldTip, oldFeeCap, newTip, newBaseFee *big.Int, lgr log.Logger) func calcGasFeeCap(baseFee, gasTipCap *big.Int) *big.Int { return new(big.Int).Add( gasTipCap, - new(big.Int).Mul(baseFee, big.NewInt(2)), + new(big.Int).Mul(baseFee, two), ) } +// calcBlobFeeCap computes a suggested blob fee cap that is twice the current header's blob base fee +// value, with a minimum value of minBlobTxFee. +func calcBlobFeeCap(blobBaseFee *big.Int) *big.Int { + cap := new(big.Int).Mul(blobBaseFee, two) + if cap.Cmp(minBlobTxFee) < 0 { + cap.Set(minBlobTxFee) + } + return cap +} + // errStringMatch returns true if err.Error() is a substring in target.Error() or if both are nil. // It can accept nil errors without issue. func errStringMatch(err, target error) bool { @@ -654,3 +879,24 @@ func errStringMatch(err, target error) bool { } return strings.Contains(err.Error(), target.Error()) } + +// finishBlobTx finishes creating a blob tx message by safely converting bigints to uint256 +func finishBlobTx(message *types.BlobTx, chainID, tip, fee, blobFee, value *big.Int) error { + var o bool + if message.ChainID, o = uint256.FromBig(chainID); o { + return fmt.Errorf("ChainID overflow") + } + if message.GasTipCap, o = uint256.FromBig(tip); o { + return fmt.Errorf("GasTipCap overflow") + } + if message.GasFeeCap, o = uint256.FromBig(fee); o { + return fmt.Errorf("GasFeeCap overflow") + } + if message.BlobFeeCap, o = uint256.FromBig(blobFee); o { + return fmt.Errorf("BlobFeeCap overflow") + } + if message.Value, o = uint256.FromBig(value); o { + return fmt.Errorf("Value overflow") + } + return nil +} diff --git a/op-service/txmgr/txmgr_test.go b/op-service/txmgr/txmgr_test.go index d15eae373148..e404ea9de761 100644 --- a/op-service/txmgr/txmgr_test.go +++ b/op-service/txmgr/txmgr_test.go @@ -2,6 +2,7 @@ package txmgr import ( "context" + "crypto/rand" "errors" "fmt" "math/big" @@ -9,16 +10,30 @@ import ( "testing" "time" + "github.com/holiman/uint256" "github.com/stretchr/testify/require" - "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" +) + +const ( + startingNonce = 1 // we pick something other than 0 so we can confirm nonces are getting set properly +) + +var ( + blobData1 = eth.Data("this is a blob!") + blobData2 = eth.Data("amazing, the txmgr can handle more than one blob in a tx!!") ) type sendTransactionFunc func(ctx context.Context, tx *types.Transaction) error @@ -46,7 +61,7 @@ func newTestHarnessWithConfig(t *testing.T, cfg Config) *testHarness { name: "TEST", cfg: cfg, backend: cfg.Backend, - l: testlog.Logger(t, log.LvlCrit), + l: testlog.Logger(t, log.LevelCrit), metr: &metrics.NoopTxMetrics{}, } @@ -74,6 +89,21 @@ func (h testHarness) createTxCandidate() TxCandidate { } } +// createBlobTxCandidate creates a mock [TxCandidate] that results in a blob tx +func (h testHarness) createBlobTxCandidate() TxCandidate { + inbox := common.HexToAddress("0x42000000000000000000000000000000000000ff") + + var b1, b2 eth.Blob + _ = b1.FromData(blobData1) + _ = b2.FromData(blobData2) + return TxCandidate{ + To: &inbox, + TxData: []byte{0x00, 0x01, 0x02, 0x03}, + GasLimit: uint64(1337), + Blobs: []*eth.Blob{&b1, &b2}, + } +} + func configWithNumConfs(numConfirmations uint64) Config { return Config{ ResubmissionTimeout: time.Second, @@ -94,6 +124,7 @@ type gasPricer struct { mineAtEpoch int64 baseGasTipFee *big.Int baseBaseFee *big.Int + excessBlobGas uint64 err error mu sync.Mutex } @@ -103,44 +134,64 @@ func newGasPricer(mineAtEpoch int64) *gasPricer { mineAtEpoch: mineAtEpoch, baseGasTipFee: big.NewInt(5), baseBaseFee: big.NewInt(7), + // Simulate 100 excess blobs, which results in a blobBaseFee of 50 wei. This default means + // blob txs will be subject to the geth minimum blobgas fee of 1 gwei. + excessBlobGas: 100 * (params.BlobTxBlobGasPerBlob), } } func (g *gasPricer) expGasFeeCap() *big.Int { - _, gasFeeCap := g.feesForEpoch(g.mineAtEpoch) + _, gasFeeCap, _ := g.feesForEpoch(g.mineAtEpoch) return gasFeeCap } +func (g *gasPricer) expBlobFeeCap() *big.Int { + _, _, excessBlobGas := g.feesForEpoch(g.mineAtEpoch) + return eip4844.CalcBlobFee(excessBlobGas) +} + func (g *gasPricer) shouldMine(gasFeeCap *big.Int) bool { - return g.expGasFeeCap().Cmp(gasFeeCap) == 0 + return g.expGasFeeCap().Cmp(gasFeeCap) <= 0 } -func (g *gasPricer) feesForEpoch(epoch int64) (*big.Int, *big.Int) { - epochBaseFee := new(big.Int).Mul(g.baseBaseFee, big.NewInt(epoch)) - epochGasTipCap := new(big.Int).Mul(g.baseGasTipFee, big.NewInt(epoch)) - epochGasFeeCap := calcGasFeeCap(epochBaseFee, epochGasTipCap) +func (g *gasPricer) shouldMineBlobTx(gasFeeCap, blobFeeCap *big.Int) bool { + return g.shouldMine(gasFeeCap) && g.expBlobFeeCap().Cmp(blobFeeCap) <= 0 +} - return epochGasTipCap, epochGasFeeCap +func (g *gasPricer) feesForEpoch(epoch int64) (*big.Int, *big.Int, uint64) { + e := big.NewInt(epoch) + epochBaseFee := new(big.Int).Mul(g.baseBaseFee, e) + epochGasTipCap := new(big.Int).Mul(g.baseGasTipFee, e) + epochGasFeeCap := calcGasFeeCap(epochBaseFee, epochGasTipCap) + epochExcessBlobGas := g.excessBlobGas * uint64(epoch) + return epochGasTipCap, epochGasFeeCap, epochExcessBlobGas } -func (g *gasPricer) basefee() *big.Int { +func (g *gasPricer) baseFee() *big.Int { g.mu.Lock() defer g.mu.Unlock() return new(big.Int).Mul(g.baseBaseFee, big.NewInt(g.epoch)) } -func (g *gasPricer) sample() (*big.Int, *big.Int) { +func (g *gasPricer) excessblobgas() uint64 { + g.mu.Lock() + defer g.mu.Unlock() + return g.excessBlobGas * uint64(g.epoch) +} + +func (g *gasPricer) sample() (*big.Int, *big.Int, uint64) { g.mu.Lock() defer g.mu.Unlock() g.epoch++ - epochGasTipCap, epochGasFeeCap := g.feesForEpoch(g.epoch) + epochGasTipCap, epochGasFeeCap, epochExcessBlobGas := g.feesForEpoch(g.epoch) - return epochGasTipCap, epochGasFeeCap + return epochGasTipCap, epochGasFeeCap, epochExcessBlobGas } type minedTxInfo struct { gasFeeCap *big.Int + blobFeeCap *big.Int blockNumber uint64 } @@ -175,7 +226,7 @@ func (b *mockBackend) setTxSender(s sendTransactionFunc) { // mine records a (txHash, gasFeeCap) as confirmed. Subsequent calls to // TransactionReceipt with a matching txHash will result in a non-nil receipt. // If a nil txHash is supplied this has the effect of mining an empty block. -func (b *mockBackend) mine(txHash *common.Hash, gasFeeCap *big.Int) { +func (b *mockBackend) mine(txHash *common.Hash, gasFeeCap, blobFeeCap *big.Int) { b.mu.Lock() defer b.mu.Unlock() @@ -183,6 +234,7 @@ func (b *mockBackend) mine(txHash *common.Hash, gasFeeCap *big.Int) { if txHash != nil { b.minedTxs[*txHash] = minedTxInfo{ gasFeeCap: gasFeeCap, + blobFeeCap: blobFeeCap, blockNumber: b.blockHeight, } } @@ -202,8 +254,18 @@ func (b *mockBackend) CallContract(ctx context.Context, call ethereum.CallMsg, b } func (b *mockBackend) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { + b.mu.RLock() + defer b.mu.RUnlock() + + num := big.NewInt(int64(b.blockHeight)) + if number != nil { + num.Set(number) + } + bg := b.g.excessblobgas() return &types.Header{ - BaseFee: b.g.basefee(), + Number: num, + BaseFee: b.g.baseFee(), + ExcessBlobGas: &bg, }, nil } @@ -211,11 +273,14 @@ func (b *mockBackend) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (ui if b.g.err != nil { return 0, b.g.err } - return b.g.basefee().Uint64(), nil + if msg.GasFeeCap.Cmp(msg.GasTipCap) < 0 { + return 0, core.ErrTipAboveFeeCap + } + return b.g.baseFee().Uint64(), nil } func (b *mockBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { - tip, _ := b.g.sample() + tip, _, _ := b.g.sample() return tip, nil } @@ -227,23 +292,22 @@ func (b *mockBackend) SendTransaction(ctx context.Context, tx *types.Transaction } func (b *mockBackend) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) { - return 0, nil + return startingNonce, nil } func (b *mockBackend) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { - return 0, nil + return startingNonce, nil } func (*mockBackend) ChainID(ctx context.Context) (*big.Int, error) { return big.NewInt(1), nil } -// TransactionReceipt queries the mockBackend for a mined txHash. If none is -// found, nil is returned for both return values. Otherwise, it retruns a -// receipt containing the txHash and the gasFeeCap used in the GasUsed to make -// the value accessible from our test framework. +// TransactionReceipt queries the mockBackend for a mined txHash. If none is found, nil is returned +// for both return values. Otherwise, it returns a receipt containing the txHash, the gasFeeCap +// used in GasUsed, and the blobFeeCap in CumuluativeGasUsed to make the values accessible from our +// test framework. func (b *mockBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { - b.mu.RLock() defer b.mu.RUnlock() @@ -254,13 +318,21 @@ func (b *mockBackend) TransactionReceipt(ctx context.Context, txHash common.Hash // Return the gas fee cap for the transaction in the GasUsed field so that // we can assert the proper tx confirmed in our tests. + var blobFeeCap uint64 + if txInfo.blobFeeCap != nil { + blobFeeCap = txInfo.blobFeeCap.Uint64() + } return &types.Receipt{ - TxHash: txHash, - GasUsed: txInfo.gasFeeCap.Uint64(), - BlockNumber: big.NewInt(int64(txInfo.blockNumber)), + TxHash: txHash, + GasUsed: txInfo.gasFeeCap.Uint64(), + CumulativeGasUsed: blobFeeCap, + BlockNumber: big.NewInt(int64(txInfo.blockNumber)), }, nil } +func (b *mockBackend) Close() { +} + // TestTxMgrConfirmAtMinGasPrice asserts that Send returns the min gas price tx // if the tx is mined instantly. func TestTxMgrConfirmAtMinGasPrice(t *testing.T) { @@ -270,7 +342,7 @@ func TestTxMgrConfirmAtMinGasPrice(t *testing.T) { gasPricer := newGasPricer(1) - gasTipCap, gasFeeCap := gasPricer.sample() + gasTipCap, gasFeeCap, _ := gasPricer.sample() tx := types.NewTx(&types.DynamicFeeTx{ GasTipCap: gasTipCap, GasFeeCap: gasFeeCap, @@ -279,7 +351,7 @@ func TestTxMgrConfirmAtMinGasPrice(t *testing.T) { sendTx := func(ctx context.Context, tx *types.Transaction) error { if gasPricer.shouldMine(tx.GasFeeCap()) { txHash := tx.Hash() - h.backend.mine(&txHash, tx.GasFeeCap()) + h.backend.mine(&txHash, tx.GasFeeCap(), nil) } return nil } @@ -301,7 +373,7 @@ func TestTxMgrNeverConfirmCancel(t *testing.T) { h := newTestHarness(t) - gasTipCap, gasFeeCap := h.gasPricer.sample() + gasTipCap, gasFeeCap, _ := h.gasPricer.sample() tx := types.NewTx(&types.DynamicFeeTx{ GasTipCap: gasTipCap, GasFeeCap: gasFeeCap, @@ -320,6 +392,23 @@ func TestTxMgrNeverConfirmCancel(t *testing.T) { require.Nil(t, receipt) } +// TestAlreadyReserved tests that AlreadyReserved error results in immediate abort of transaction +// sending. +func TestAlreadyReserved(t *testing.T) { + conf := configWithNumConfs(1) + h := newTestHarnessWithConfig(t, conf) + + sendTx := func(ctx context.Context, tx *types.Transaction) error { + return ErrAlreadyReserved + } + h.backend.setTxSender(sendTx) + + _, err := h.mgr.Send(context.Background(), TxCandidate{ + To: &common.Address{}, + }) + require.ErrorIs(t, err, ErrAlreadyReserved) +} + // TestTxMgrConfirmsAtMaxGasPrice asserts that Send properly returns the max gas // price receipt if none of the lower gas price txs were mined. func TestTxMgrConfirmsAtHigherGasPrice(t *testing.T) { @@ -327,7 +416,7 @@ func TestTxMgrConfirmsAtHigherGasPrice(t *testing.T) { h := newTestHarness(t) - gasTipCap, gasFeeCap := h.gasPricer.sample() + gasTipCap, gasFeeCap, _ := h.gasPricer.sample() tx := types.NewTx(&types.DynamicFeeTx{ GasTipCap: gasTipCap, GasFeeCap: gasFeeCap, @@ -335,7 +424,7 @@ func TestTxMgrConfirmsAtHigherGasPrice(t *testing.T) { sendTx := func(ctx context.Context, tx *types.Transaction) error { if h.gasPricer.shouldMine(tx.GasFeeCap()) { txHash := tx.Hash() - h.backend.mine(&txHash, tx.GasFeeCap()) + h.backend.mine(&txHash, tx.GasFeeCap(), nil) } return nil } @@ -350,6 +439,43 @@ func TestTxMgrConfirmsAtHigherGasPrice(t *testing.T) { require.Equal(t, h.gasPricer.expGasFeeCap().Uint64(), receipt.GasUsed) } +// TestTxMgrConfirmsBlobTxAtMaxGasPrice asserts that Send properly returns the max gas price +// receipt if none of the lower gas price txs were mined when attempting to send a blob tx. +func TestTxMgrConfirmsBlobTxAtHigherGasPrice(t *testing.T) { + t.Parallel() + + h := newTestHarness(t) + + gasTipCap, gasFeeCap, excessBlobGas := h.gasPricer.sample() + blobFeeCap := eip4844.CalcBlobFee(excessBlobGas) + t.Log("Blob fee cap:", blobFeeCap, "gasFeeCap:", gasFeeCap) + + tx := types.NewTx(&types.BlobTx{ + GasTipCap: uint256.MustFromBig(gasTipCap), + GasFeeCap: uint256.MustFromBig(gasFeeCap), + BlobFeeCap: uint256.MustFromBig(blobFeeCap), + }) + sendTx := func(ctx context.Context, tx *types.Transaction) error { + if h.gasPricer.shouldMineBlobTx(tx.GasFeeCap(), tx.BlobGasFeeCap()) { + txHash := tx.Hash() + h.backend.mine(&txHash, tx.GasFeeCap(), tx.BlobGasFeeCap()) + } + return nil + } + h.backend.setTxSender(sendTx) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + receipt, err := h.mgr.sendTx(ctx, tx) + require.Nil(t, err) + require.NotNil(t, receipt) + // the fee cap for the blob tx at epoch == 3 should end up higher than the min required gas + // (expFeeCap()) since blob tx fee caps are bumped 100% with each epoch. + require.Less(t, h.gasPricer.expGasFeeCap().Uint64(), receipt.GasUsed) + require.Equal(t, h.gasPricer.expBlobFeeCap().Uint64(), receipt.CumulativeGasUsed) +} + // errRpcFailure is a sentinel error used in testing to fail publications. var errRpcFailure = errors.New("rpc failure") @@ -361,7 +487,7 @@ func TestTxMgrBlocksOnFailingRpcCalls(t *testing.T) { h := newTestHarness(t) - gasTipCap, gasFeeCap := h.gasPricer.sample() + gasTipCap, gasFeeCap, _ := h.gasPricer.sample() tx := types.NewTx(&types.DynamicFeeTx{ GasTipCap: gasTipCap, GasFeeCap: gasFeeCap, @@ -387,20 +513,67 @@ func TestTxMgr_CraftTx(t *testing.T) { candidate := h.createTxCandidate() // Craft the transaction. - gasTipCap, gasFeeCap := h.gasPricer.feesForEpoch(h.gasPricer.epoch + 1) + gasTipCap, gasFeeCap, _ := h.gasPricer.feesForEpoch(h.gasPricer.epoch + 1) + tx, err := h.mgr.craftTx(context.Background(), candidate) + require.Nil(t, err) + require.NotNil(t, tx) + require.Equal(t, byte(types.DynamicFeeTxType), tx.Type()) + + // Validate the gas tip cap and fee cap. + require.Equal(t, gasTipCap, tx.GasTipCap()) + require.Equal(t, gasFeeCap, tx.GasFeeCap()) + + // Validate the nonce was set correctly using the backend. + require.Equal(t, uint64(startingNonce), tx.Nonce()) + + // Check that the gas was set using the gas limit. + require.Equal(t, candidate.GasLimit, tx.Gas()) +} + +// TestTxMgr_CraftBlobTx ensures that the tx manager will create blob transactions as expected. +func TestTxMgr_CraftBlobTx(t *testing.T) { + t.Parallel() + h := newTestHarness(t) + candidate := h.createBlobTxCandidate() + + // Craft the transaction. + gasTipCap, gasFeeCap, _ := h.gasPricer.feesForEpoch(h.gasPricer.epoch + 1) tx, err := h.mgr.craftTx(context.Background(), candidate) require.Nil(t, err) require.NotNil(t, tx) + require.Equal(t, byte(types.BlobTxType), tx.Type()) // Validate the gas tip cap and fee cap. require.Equal(t, gasTipCap, tx.GasTipCap()) require.Equal(t, gasFeeCap, tx.GasFeeCap()) + require.Equal(t, minBlobTxFee, tx.BlobGasFeeCap()) // Validate the nonce was set correctly using the backend. - require.Zero(t, tx.Nonce()) + require.Equal(t, uint64(startingNonce), tx.Nonce()) // Check that the gas was set using the gas limit. require.Equal(t, candidate.GasLimit, tx.Gas()) + + // Check the blob fields + require.Equal(t, 2, len(tx.BlobHashes())) + sidecar := tx.BlobTxSidecar() + require.Equal(t, 2, len(sidecar.Blobs)) + require.Equal(t, 2, len(sidecar.Commitments)) + require.Equal(t, 2, len(sidecar.Proofs)) + + // verify the blobs + for i := range sidecar.Blobs { + require.NoError(t, kzg4844.VerifyBlobProof(sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i])) + } + b1 := eth.Blob(sidecar.Blobs[0]) + d1, err := b1.ToData() + require.NoError(t, err) + require.Equal(t, blobData1, d1) + + b2 := eth.Blob(sidecar.Blobs[1]) + d2, err := b2.ToData() + require.NoError(t, err) + require.Equal(t, blobData2, d2) } // TestTxMgr_EstimateGas ensures that the tx manager will estimate @@ -492,7 +665,7 @@ func TestTxMgrOnlyOnePublicationSucceeds(t *testing.T) { h := newTestHarness(t) - gasTipCap, gasFeeCap := h.gasPricer.sample() + gasTipCap, gasFeeCap, _ := h.gasPricer.sample() tx := types.NewTx(&types.DynamicFeeTx{ GasTipCap: gasTipCap, GasFeeCap: gasFeeCap, @@ -505,7 +678,7 @@ func TestTxMgrOnlyOnePublicationSucceeds(t *testing.T) { } txHash := tx.Hash() - h.backend.mine(&txHash, tx.GasFeeCap()) + h.backend.mine(&txHash, tx.GasFeeCap(), nil) return nil } h.backend.setTxSender(sendTx) @@ -520,14 +693,14 @@ func TestTxMgrOnlyOnePublicationSucceeds(t *testing.T) { } // TestTxMgrConfirmsMinGasPriceAfterBumping delays the mining of the initial tx -// with the minimum gas price, and asserts that it's receipt is returned even +// with the minimum gas price, and asserts that its receipt is returned even // though if the gas price has been bumped in other goroutines. func TestTxMgrConfirmsMinGasPriceAfterBumping(t *testing.T) { t.Parallel() h := newTestHarness(t) - gasTipCap, gasFeeCap := h.gasPricer.sample() + gasTipCap, gasFeeCap, _ := h.gasPricer.sample() tx := types.NewTx(&types.DynamicFeeTx{ GasTipCap: gasTipCap, GasFeeCap: gasFeeCap, @@ -538,7 +711,7 @@ func TestTxMgrConfirmsMinGasPriceAfterBumping(t *testing.T) { if h.gasPricer.shouldMine(tx.GasFeeCap()) { time.AfterFunc(5*time.Second, func() { txHash := tx.Hash() - h.backend.mine(&txHash, tx.GasFeeCap()) + h.backend.mine(&txHash, tx.GasFeeCap(), nil) }) } return nil @@ -559,7 +732,7 @@ func TestTxMgrDoesntAbortNonceTooLowAfterMiningTx(t *testing.T) { h := newTestHarnessWithConfig(t, configWithNumConfs(2)) - gasTipCap, gasFeeCap := h.gasPricer.sample() + gasTipCap, gasFeeCap, _ := h.gasPricer.sample() tx := types.NewTx(&types.DynamicFeeTx{ GasTipCap: gasTipCap, GasFeeCap: gasFeeCap, @@ -576,9 +749,9 @@ func TestTxMgrDoesntAbortNonceTooLowAfterMiningTx(t *testing.T) { // Accept and mine the actual txn we expect to confirm. case h.gasPricer.shouldMine(tx.GasFeeCap()): txHash := tx.Hash() - h.backend.mine(&txHash, tx.GasFeeCap()) + h.backend.mine(&txHash, tx.GasFeeCap(), nil) time.AfterFunc(5*time.Second, func() { - h.backend.mine(nil, nil) + h.backend.mine(nil, nil, nil) }) return nil @@ -608,7 +781,7 @@ func TestWaitMinedReturnsReceiptOnFirstSuccess(t *testing.T) { // Create a tx and mine it immediately using the default backend. tx := types.NewTx(&types.LegacyTx{}) txHash := tx.Hash() - h.backend.mine(&txHash, new(big.Int)) + h.backend.mine(&txHash, new(big.Int), nil) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -650,7 +823,7 @@ func TestWaitMinedMultipleConfs(t *testing.T) { // Create an unimined tx. tx := types.NewTx(&types.LegacyTx{}) txHash := tx.Hash() - h.backend.mine(&txHash, new(big.Int)) + h.backend.mine(&txHash, new(big.Int), nil) receipt, err := h.mgr.waitMined(ctx, tx, NewSendState(10, time.Hour)) require.Equal(t, err, context.DeadlineExceeded) @@ -660,7 +833,7 @@ func TestWaitMinedMultipleConfs(t *testing.T) { defer cancel() // Mine an empty block, tx should now be confirmed. - h.backend.mine(nil, nil) + h.backend.mine(nil, nil, nil) receipt, err = h.mgr.waitMined(ctx, tx, NewSendState(10, time.Hour)) require.Nil(t, err) require.NotNil(t, receipt) @@ -672,7 +845,7 @@ func TestWaitMinedMultipleConfs(t *testing.T) { func TestManagerErrsOnZeroCLIConfs(t *testing.T) { t.Parallel() - _, err := NewSimpleTxManager("TEST", testlog.Logger(t, log.LvlCrit), &metrics.NoopTxMetrics{}, CLIConfig{}) + _, err := NewSimpleTxManager("TEST", testlog.Logger(t, log.LevelCrit), &metrics.NoopTxMetrics{}, CLIConfig{}) require.Error(t, err) } @@ -681,7 +854,7 @@ func TestManagerErrsOnZeroCLIConfs(t *testing.T) { func TestManagerErrsOnZeroConfs(t *testing.T) { t.Parallel() - _, err := NewSimpleTxManagerFromConfig("TEST", testlog.Logger(t, log.LvlCrit), &metrics.NoopTxMetrics{}, Config{}) + _, err := NewSimpleTxManagerFromConfig("TEST", testlog.Logger(t, log.LevelCrit), &metrics.NoopTxMetrics{}, Config{}) require.Error(t, err) } @@ -690,8 +863,10 @@ func TestManagerErrsOnZeroConfs(t *testing.T) { // inner loop of WaitMined properly handles this case. type failingBackend struct { returnSuccessBlockNumber bool + returnSuccessHeader bool returnSuccessReceipt bool baseFee, gasTip *big.Int + excessBlobGas *uint64 } // BlockNumber for the failingBackend returns errRpcFailure on the first @@ -708,8 +883,8 @@ func (b *failingBackend) BlockNumber(ctx context.Context) (uint64, error) { // TransactionReceipt for the failingBackend returns errRpcFailure on the first // invocation, and a receipt containing the passed TxHash on the second. func (b *failingBackend) TransactionReceipt( - ctx context.Context, txHash common.Hash) (*types.Receipt, error) { - + ctx context.Context, txHash common.Hash, +) (*types.Receipt, error) { if !b.returnSuccessReceipt { b.returnSuccessReceipt = true return nil, errRpcFailure @@ -721,9 +896,16 @@ func (b *failingBackend) TransactionReceipt( }, nil } -func (b *failingBackend) HeaderByNumber(_ context.Context, _ *big.Int) (*types.Header, error) { +func (b *failingBackend) HeaderByNumber(ctx context.Context, _ *big.Int) (*types.Header, error) { + if !b.returnSuccessHeader { + b.returnSuccessHeader = true + return nil, errRpcFailure + } + return &types.Header{ - BaseFee: b.baseFee, + Number: big.NewInt(1), + BaseFee: b.baseFee, + ExcessBlobGas: b.excessBlobGas, }, nil } @@ -755,6 +937,9 @@ func (b *failingBackend) ChainID(ctx context.Context) (*big.Int, error) { return nil, errors.New("unimplemented") } +func (b *failingBackend) Close() { +} + // TestWaitMinedReturnsReceiptAfterFailure asserts that WaitMined is able to // recover from failed calls to the backend. It uses the failedBackend to // simulate an rpc call failure, followed by the successful return of a receipt. @@ -772,7 +957,7 @@ func TestWaitMinedReturnsReceiptAfterFailure(t *testing.T) { }, name: "TEST", backend: &borkedBackend, - l: testlog.Logger(t, log.LvlCrit), + l: testlog.Logger(t, log.LevelCrit), metr: &metrics.NoopTxMetrics{}, } @@ -789,10 +974,11 @@ func TestWaitMinedReturnsReceiptAfterFailure(t *testing.T) { require.Equal(t, receipt.TxHash, txHash) } -func doGasPriceIncrease(t *testing.T, txTipCap, txFeeCap, newTip, newBaseFee int64) (*types.Transaction, *types.Transaction) { +func doGasPriceIncrease(t *testing.T, txTipCap, txFeeCap, newTip, newBaseFee int64) (*types.Transaction, *types.Transaction, error) { borkedBackend := failingBackend{ - gasTip: big.NewInt(newTip), - baseFee: big.NewInt(newBaseFee), + gasTip: big.NewInt(newTip), + baseFee: big.NewInt(newBaseFee), + returnSuccessHeader: true, } mgr := &SimpleTxManager{ @@ -809,7 +995,7 @@ func doGasPriceIncrease(t *testing.T, txTipCap, txFeeCap, newTip, newBaseFee int }, name: "TEST", backend: &borkedBackend, - l: testlog.Logger(t, log.LvlCrit), + l: testlog.Logger(t, log.LevelCrit), metr: &metrics.NoopTxMetrics{}, } @@ -818,8 +1004,7 @@ func doGasPriceIncrease(t *testing.T, txTipCap, txFeeCap, newTip, newBaseFee int GasFeeCap: big.NewInt(txFeeCap), }) newTx, err := mgr.increaseGasPrice(context.Background(), tx) - require.NoError(t, err) - return tx, newTx + return tx, newTx, err } func TestIncreaseGasPrice(t *testing.T) { @@ -829,53 +1014,92 @@ func TestIncreaseGasPrice(t *testing.T) { name string run func(t *testing.T) }{ + { + name: "bump at least 1", + run: func(t *testing.T) { + tx, newTx, err := doGasPriceIncrease(t, 1, 3, 1, 1) + require.True(t, newTx.GasFeeCap().Cmp(tx.GasFeeCap()) > 0, "new tx fee cap must be larger") + require.True(t, newTx.GasTipCap().Cmp(tx.GasTipCap()) > 0, "new tx tip must be larger") + require.NoError(t, err) + }, + }, { name: "enforces min bump", run: func(t *testing.T) { - tx, newTx := doGasPriceIncrease(t, 100, 1000, 101, 460) + tx, newTx, err := doGasPriceIncrease(t, 100, 1000, 101, 460) require.True(t, newTx.GasFeeCap().Cmp(tx.GasFeeCap()) > 0, "new tx fee cap must be larger") require.True(t, newTx.GasTipCap().Cmp(tx.GasTipCap()) > 0, "new tx tip must be larger") + require.NoError(t, err) }, }, { - name: "enforces min bump on only tip incrase", + name: "enforces min bump on only tip increase", run: func(t *testing.T) { - tx, newTx := doGasPriceIncrease(t, 100, 1000, 101, 440) + tx, newTx, err := doGasPriceIncrease(t, 100, 1000, 101, 440) require.True(t, newTx.GasFeeCap().Cmp(tx.GasFeeCap()) > 0, "new tx fee cap must be larger") require.True(t, newTx.GasTipCap().Cmp(tx.GasTipCap()) > 0, "new tx tip must be larger") + require.NoError(t, err) }, }, { - name: "enforces min bump on only basefee incrase", + name: "enforces min bump on only base fee increase", run: func(t *testing.T) { - tx, newTx := doGasPriceIncrease(t, 100, 1000, 99, 460) + tx, newTx, err := doGasPriceIncrease(t, 100, 1000, 99, 460) require.True(t, newTx.GasFeeCap().Cmp(tx.GasFeeCap()) > 0, "new tx fee cap must be larger") require.True(t, newTx.GasTipCap().Cmp(tx.GasTipCap()) > 0, "new tx tip must be larger") + require.NoError(t, err) }, }, { name: "uses L1 values when larger", run: func(t *testing.T) { - _, newTx := doGasPriceIncrease(t, 10, 100, 50, 200) + _, newTx, err := doGasPriceIncrease(t, 10, 100, 50, 200) require.True(t, newTx.GasFeeCap().Cmp(big.NewInt(450)) == 0, "new tx fee cap must be equal L1") require.True(t, newTx.GasTipCap().Cmp(big.NewInt(50)) == 0, "new tx tip must be equal L1") + require.NoError(t, err) }, }, { name: "uses L1 tip when larger and threshold FC", run: func(t *testing.T) { - _, newTx := doGasPriceIncrease(t, 100, 2200, 120, 1050) + _, newTx, err := doGasPriceIncrease(t, 100, 2200, 120, 1050) require.True(t, newTx.GasTipCap().Cmp(big.NewInt(120)) == 0, "new tx tip must be equal L1") require.True(t, newTx.GasFeeCap().Cmp(big.NewInt(2420)) == 0, "new tx fee cap must be equal to the threshold value") + require.NoError(t, err) + }, + }, + { + name: "bumped fee above multiplier limit", + run: func(t *testing.T) { + _, _, err := doGasPriceIncrease(t, 1, 9999, 1, 1) + require.ErrorContains(t, err, "fee cap") + require.NotContains(t, err.Error(), "tip cap") + }, + }, + { + name: "bumped tip above multiplier limit", + run: func(t *testing.T) { + _, _, err := doGasPriceIncrease(t, 9999, 0, 0, 9999) + require.ErrorContains(t, err, "tip cap") + require.NotContains(t, err.Error(), "fee cap") + }, + }, + { + name: "bumped fee and tip above multiplier limit", + run: func(t *testing.T) { + _, _, err := doGasPriceIncrease(t, 9999, 9999, 1, 1) + require.ErrorContains(t, err, "tip cap") + require.ErrorContains(t, err, "fee cap") }, }, { name: "uses L1 FC when larger and threshold tip", run: func(t *testing.T) { - _, newTx := doGasPriceIncrease(t, 100, 2200, 100, 2000) + _, newTx, err := doGasPriceIncrease(t, 100, 2200, 100, 2000) require.True(t, newTx.GasTipCap().Cmp(big.NewInt(110)) == 0, "new tx tip must be equal the threshold value") t.Log("Vals:", newTx.GasFeeCap()) require.True(t, newTx.GasFeeCap().Cmp(big.NewInt(4110)) == 0, "new tx fee cap must be equal L1") + require.NoError(t, err) }, }, } @@ -885,16 +1109,46 @@ func TestIncreaseGasPrice(t *testing.T) { } } -// TestIncreaseGasPriceNotExponential asserts that if the L1 basefee & tip remain the -// same, repeated calls to IncreaseGasPrice do not continually increase the gas price. -func TestIncreaseGasPriceNotExponential(t *testing.T) { +// TestIncreaseGasPriceLimits asserts that if the L1 base fee & tip remain the +// same, repeated calls to IncreaseGasPrice eventually hit a limit. +func TestIncreaseGasPriceLimits(t *testing.T) { + t.Run("no-threshold", func(t *testing.T) { + testIncreaseGasPriceLimit(t, gasPriceLimitTest{ + expTipCap: 46, + expFeeCap: 354, // just below 5*100 + expBlobFeeCap: 4 * params.GWei, + }) + }) + t.Run("with-threshold", func(t *testing.T) { + testIncreaseGasPriceLimit(t, gasPriceLimitTest{ + thr: big.NewInt(params.GWei * 10), + expTipCap: 1_293_535_754, + expFeeCap: 9_192_620_686, // just below 10 gwei + expBlobFeeCap: 8 * params.GWei, + }) + }) +} + +type gasPriceLimitTest struct { + thr *big.Int + expTipCap, expFeeCap int64 + expBlobFeeCap int64 +} + +// testIncreaseGasPriceLimit runs a gas bumping test that increases the gas price until it hits an error. +// It starts with a tx that has a tip cap of 10 wei and fee cap of 100 wei. +func testIncreaseGasPriceLimit(t *testing.T, lt gasPriceLimitTest) { t.Parallel() borkedTip := int64(10) borkedFee := int64(45) + // simulate 100 excess blobs which yields a 50 wei blob base fee + borkedExcessBlobGas := uint64(100 * params.BlobTxBlobGasPerBlob) borkedBackend := failingBackend{ - gasTip: big.NewInt(borkedTip), - baseFee: big.NewInt(borkedFee), + gasTip: big.NewInt(borkedTip), + baseFee: big.NewInt(borkedFee), + excessBlobGas: &borkedExcessBlobGas, + returnSuccessHeader: true, } mgr := &SimpleTxManager{ @@ -904,6 +1158,7 @@ func TestIncreaseGasPriceNotExponential(t *testing.T) { NumConfirmations: 1, SafeAbortNonceTooLowCount: 3, FeeLimitMultiplier: 5, + FeeLimitThreshold: lt.thr, Signer: func(ctx context.Context, from common.Address, tx *types.Transaction) (*types.Transaction, error) { return tx, nil }, @@ -911,29 +1166,51 @@ func TestIncreaseGasPriceNotExponential(t *testing.T) { }, name: "TEST", backend: &borkedBackend, - l: testlog.Logger(t, log.LvlCrit), + l: testlog.Logger(t, log.LevelCrit), metr: &metrics.NoopTxMetrics{}, } - tx := types.NewTx(&types.DynamicFeeTx{ + lastGoodTx := types.NewTx(&types.DynamicFeeTx{ GasTipCap: big.NewInt(10), GasFeeCap: big.NewInt(100), }) - // Run IncreaseGasPrice a bunch of times in a row to simulate a very fast resubmit loop. + // Run increaseGasPrice a bunch of times in a row to simulate a very fast resubmit loop to make + // sure it errors out without a runaway fee increase. ctx := context.Background() + var err error for { - newTx, err := mgr.increaseGasPrice(ctx, tx) + var tmpTx *types.Transaction + tmpTx, err = mgr.increaseGasPrice(ctx, lastGoodTx) if err != nil { break } - tx = newTx + lastGoodTx = tmpTx } - lastTip, lastFee := tx.GasTipCap(), tx.GasFeeCap() - require.Equal(t, lastTip.Int64(), int64(36)) - require.Equal(t, lastFee.Int64(), int64(493)) - // Confirm that fees stop rising - _, err := mgr.increaseGasPrice(ctx, tx) require.Error(t, err) + + // Confirm that fees only rose until expected threshold + require.Equal(t, lt.expTipCap, lastGoodTx.GasTipCap().Int64()) + require.Equal(t, lt.expFeeCap, lastGoodTx.GasFeeCap().Int64()) + + // Confirm blob txs also don't see runaway fee increase and that blob fee market is also capped + // as expected + blobTx := &types.BlobTx{} + blobTx.GasTipCap = uint256.NewInt(1) + blobTx.GasFeeCap = uint256.NewInt(10) + // set a large initial blobFeeCap to make sure blob fee cap is hit before regular fee cap + blobTx.BlobFeeCap = uint256.NewInt(params.GWei * 2) + lastGoodTx = types.NewTx(blobTx) + for { + var tmpTx *types.Transaction + tmpTx, err = mgr.increaseGasPrice(ctx, lastGoodTx) + if err != nil { + break + } + lastGoodTx = tmpTx + } + require.ErrorIs(t, err, ErrBlobFeeLimit) + // Confirm that fees only rose until expected threshold + require.Equal(t, lt.expBlobFeeCap, lastGoodTx.BlobGasFeeCap().Int64()) } func TestErrStringMatch(t *testing.T) { @@ -973,7 +1250,7 @@ func TestNonceReset(t *testing.T) { return core.ErrNonceTooLow } txHash := tx.Hash() - h.backend.mine(&txHash, tx.GasFeeCap()) + h.backend.mine(&txHash, tx.GasFeeCap(), nil) return nil } h.backend.setTxSender(sendTx) @@ -991,6 +1268,207 @@ func TestNonceReset(t *testing.T) { } } - // internal nonce tracking should be reset every 3rd tx - require.Equal(t, []uint64{0, 0, 1, 2, 0, 1, 2, 0}, nonces) + // internal nonce tracking should be reset to startingNonce value every 3rd tx + require.Equal(t, []uint64{1, 1, 2, 3, 1, 2, 3, 1}, nonces) +} + +func TestMinFees(t *testing.T) { + for _, tt := range []struct { + desc string + minBaseFee *big.Int + minTipCap *big.Int + expectMinBaseFee bool + expectMinTipCap bool + }{ + { + desc: "no-mins", + }, + { + desc: "high-min-basefee", + minBaseFee: big.NewInt(10_000_000), + expectMinBaseFee: true, + }, + { + desc: "high-min-tipcap", + minTipCap: big.NewInt(1_000_000), + expectMinTipCap: true, + }, + { + desc: "high-mins", + minBaseFee: big.NewInt(10_000_000), + minTipCap: big.NewInt(1_000_000), + expectMinBaseFee: true, + expectMinTipCap: true, + }, + { + desc: "low-min-basefee", + minBaseFee: big.NewInt(1), + }, + { + desc: "low-min-tipcap", + minTipCap: big.NewInt(1), + }, + { + desc: "low-mins", + minBaseFee: big.NewInt(1), + minTipCap: big.NewInt(1), + }, + } { + t.Run(tt.desc, func(t *testing.T) { + require := require.New(t) + conf := configWithNumConfs(1) + conf.MinBaseFee = tt.minBaseFee + conf.MinTipCap = tt.minTipCap + h := newTestHarnessWithConfig(t, conf) + + tip, baseFee, _, err := h.mgr.suggestGasPriceCaps(context.TODO()) + require.NoError(err) + + if tt.expectMinBaseFee { + require.Equal(tt.minBaseFee, baseFee, "expect suggested base fee to equal MinBaseFee") + } else { + require.Equal(h.gasPricer.baseBaseFee, baseFee, "expect suggested base fee to equal mock base fee") + } + + if tt.expectMinTipCap { + require.Equal(tt.minTipCap, tip, "expect suggested tip to equal MinTipCap") + } else { + require.Equal(h.gasPricer.baseGasTipFee, tip, "expect suggested tip to equal mock tip") + } + }) + } +} + +// TestClose ensures that the tx manager will refuse new work and cancel any in progress +func TestClose(t *testing.T) { + conf := configWithNumConfs(1) + conf.SafeAbortNonceTooLowCount = 100 + h := newTestHarnessWithConfig(t, conf) + + sendingSignal := make(chan struct{}) + + // Ensure the manager is not closed + require.False(t, h.mgr.closed.Load()) + + // sendTx will fail until it is called a retry-number of times + called := 0 + const retries = 4 + sendTx := func(ctx context.Context, tx *types.Transaction) (err error) { + called += 1 + // sendingSignal is used when the tx begins to be sent + if called == 1 { + sendingSignal <- struct{}{} + } + if called%retries == 0 { + txHash := tx.Hash() + h.backend.mine(&txHash, tx.GasFeeCap(), big.NewInt(1)) + } else { + time.Sleep(10 * time.Millisecond) + err = core.ErrNonceTooLow + } + return + } + h.backend.setTxSender(sendTx) + + // on the first call, we don't use the sending signal but we still need to drain it + go func() { + <-sendingSignal + }() + // demonstrate that a tx is sent, even when it must retry repeatedly + ctx := context.Background() + _, err := h.mgr.Send(ctx, TxCandidate{ + To: &common.Address{}, + }) + require.NoError(t, err) + require.Equal(t, retries, called) + called = 0 + // Ensure the manager is *still* not closed + require.False(t, h.mgr.closed.Load()) + + // on the second call, we close the manager while the tx is in progress by consuming the sending signal + go func() { + <-sendingSignal + h.mgr.Close() + }() + // demonstrate that a tx will cancel if it is in progress when the manager is closed + _, err = h.mgr.Send(ctx, TxCandidate{ + To: &common.Address{}, + }) + require.ErrorIs(t, ErrClosed, err) + // confirm that the tx was canceled before it retried to completion + require.Less(t, called, retries) + require.True(t, h.mgr.closed.Load()) + called = 0 + + // demonstrate that new calls to Send will also fail when the manager is closed + // there should be no need to capture the sending signal here because the manager is already closed and will return immediately + _, err = h.mgr.Send(ctx, TxCandidate{ + To: &common.Address{}, + }) + require.ErrorIs(t, ErrClosed, err) + // confirm that the tx was canceled before it ever made it to the backend + require.Equal(t, 0, called) +} + +// TestCloseWaitingForConfirmation ensures that the tx manager will wait for confirmation of a tx in flight, even when closed +func TestCloseWaitingForConfirmation(t *testing.T) { + // two confirmations required so that we can mine and not yet be fully confirmed + conf := configWithNumConfs(2) + h := newTestHarnessWithConfig(t, conf) + + // sendDone is a signal that the tx has been sent from the sendTx function + sendDone := make(chan struct{}) + // closeDone is a signal that the txmanager has closed + closeDone := make(chan struct{}) + + sendTx := func(ctx context.Context, tx *types.Transaction) error { + txHash := tx.Hash() + h.backend.mine(&txHash, tx.GasFeeCap(), big.NewInt(1)) + close(sendDone) + return nil + } + h.backend.setTxSender(sendTx) + + // this goroutine will close the manager when the tx sending is complete + // the transaction is not yet confirmed, so the manager will wait for confirmation + go func() { + <-sendDone + h.mgr.Close() + close(closeDone) + }() + + // this goroutine will complete confirmation of the tx when the manager is closed + // by forcing this to happen after close, we are able to observe a closing manager waiting for confirmation + go func() { + <-closeDone + h.backend.mine(nil, nil, big.NewInt(1)) + }() + + ctx := context.Background() + _, err := h.mgr.Send(ctx, TxCandidate{ + To: &common.Address{}, + }) + require.True(t, h.mgr.closed.Load()) + require.NoError(t, err) +} + +func TestMakeSidecar(t *testing.T) { + var blob eth.Blob + _, err := rand.Read(blob[:]) + require.NoError(t, err) + // get the field-elements into a valid range + for i := 0; i < 4096; i++ { + blob[32*i] &= 0b0011_1111 + } + sidecar, hashes, err := MakeSidecar([]*eth.Blob{&blob}) + require.NoError(t, err) + require.Equal(t, len(hashes), 1) + require.Equal(t, len(sidecar.Blobs), len(hashes)) + require.Equal(t, len(sidecar.Proofs), len(hashes)) + require.Equal(t, len(sidecar.Commitments), len(hashes)) + + for i, commit := range sidecar.Commitments { + require.NoError(t, eth.VerifyBlobProof((*eth.Blob)(&sidecar.Blobs[i]), commit, sidecar.Proofs[i]), "proof must be valid") + require.Equal(t, hashes[i], eth.KZGToVersionedHash(commit)) + } } diff --git a/op-service/util.go b/op-service/util.go index 81ffd1d9bc40..0a51147fd7d8 100644 --- a/op-service/util.go +++ b/op-service/util.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "os/signal" + "path/filepath" "reflect" "strings" "syscall" @@ -32,6 +33,11 @@ func ValidateEnvVars(prefix string, flags []cli.Flag, log log.Logger) { } } +func FlagNameToEnvVarName(f string, prefix string) string { + f = strings.ReplaceAll(strings.ReplaceAll(strings.ToUpper(f), ".", "_"), "-", "_") + return fmt.Sprintf("%s_%s", prefix, f) +} + func cliFlagsToEnvVars(flags []cli.Flag) map[string]struct{} { definedEnvVars := make(map[string]struct{}) for _, flag := range flags { @@ -62,6 +68,15 @@ func validateEnvVars(prefix string, providedEnvVars []string, definedEnvVars map return out } +// WarnOnDeprecatedFlags iterates through the provided deprecatedFlags and logs a warning for each that is set. +func WarnOnDeprecatedFlags(ctx *cli.Context, deprecatedFlags []cli.Flag, log log.Logger) { + for _, flag := range deprecatedFlags { + if ctx.IsSet(flag.Names()[0]) { + log.Warn("Found a deprecated flag which will be removed in a future version", "flag_name", flag.Names()[0]) + } + } +} + // ParseAddress parses an ETH address from a hex string. This method will fail if // the address is not a valid hexadecimal address. func ParseAddress(address string) (common.Address, error) { @@ -105,3 +120,25 @@ func CloseAction(fn func(ctx context.Context, shutdown <-chan struct{}) error) e return err } } + +// FindMonorepoRoot will recursively search upwards for a go.mod file. +// This depends on the structure of the monorepo having a go.mod file at the root. +func FindMonorepoRoot(startDir string) (string, error) { + dir, err := filepath.Abs(startDir) + if err != nil { + return "", err + } + for { + modulePath := filepath.Join(dir, "go.mod") + if _, err := os.Stat(modulePath); err == nil { + return dir, nil + } + parentDir := filepath.Dir(dir) + // Check if we reached the filesystem root + if parentDir == dir { + break + } + dir = parentDir + } + return "", fmt.Errorf("monorepo root not found") +} diff --git a/op-ufm/Makefile b/op-ufm/Makefile index 79604752a97d..7dbd96f11dcf 100644 --- a/op-ufm/Makefile +++ b/op-ufm/Makefile @@ -18,10 +18,19 @@ test: lint: go vet ./... -.PHONY: test +.PHONY: lint tls: kubectl get secrets op-ufm-client-tls -o yaml | yq '.data."tls.key"' | base64 --decode > tls/tls.key kubectl get secrets op-ufm-client-tls -o yaml | yq '.data."tls.crt"' | base64 --decode > tls/tls.crt kubectl get secrets op-ufm-client-tls -o yaml | yq '.data."ca.crt"' | base64 --decode > tls/ca.crt .PHONY: tls + +mod-tidy: + # Below GOPRIVATE line allows mod-tidy to be run immediately after + # releasing new versions. This bypasses the Go modules proxy, which + # can take a while to index new versions. + # + # See https://proxy.golang.org/ for more info. + export GOPRIVATE="github.com/ethereum-optimism" && go mod tidy +.PHONY: mod-tidy diff --git a/op-ufm/cmd/ufm/main.go b/op-ufm/cmd/ufm/main.go index ca2cac4d2c39..f4f753a40c85 100644 --- a/op-ufm/cmd/ufm/main.go +++ b/op-ufm/cmd/ufm/main.go @@ -8,10 +8,13 @@ import ( "os/signal" "syscall" - "github.com/ethereum-optimism/optimism/op-ufm/pkg/config" - "github.com/ethereum-optimism/optimism/op-ufm/pkg/service" + "golang.org/x/exp/slog" "github.com/ethereum/go-ethereum/log" + + oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-ufm/pkg/config" + "github.com/ethereum-optimism/optimism/op-ufm/pkg/service" ) var ( @@ -21,12 +24,8 @@ var ( ) func main() { - log.Root().SetHandler( - log.LvlFilterHandler( - log.LvlInfo, - log.StreamHandler(os.Stdout, log.JSONFormat()), - ), - ) + oplog.SetGlobalLogHandler(slog.NewJSONHandler( + os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) log.Info("initializing", "version", GitVersion, @@ -60,20 +59,16 @@ func initConfig(cfgFile string) *config.Config { } // update log level from config - logLevel, err := log.LvlFromString(cfg.LogLevel) + logLevel, err := oplog.LevelFromString(cfg.LogLevel) if err != nil { - logLevel = log.LvlInfo + logLevel = log.LevelInfo if cfg.LogLevel != "" { log.Warn("invalid server.log_level", "log_level", cfg.LogLevel) } } - log.Root().SetHandler( - log.LvlFilterHandler( - logLevel, - log.StreamHandler(os.Stdout, log.JSONFormat()), - ), - ) + oplog.SetGlobalLogHandler(slog.NewJSONHandler( + os.Stdout, &slog.HandlerOptions{Level: logLevel})) // readable parsed config jsonCfg, _ := json.MarshalIndent(cfg, "", " ") diff --git a/op-ufm/go.mod b/op-ufm/go.mod index a70a62a7f6f2..e00d1ad4d24a 100644 --- a/op-ufm/go.mod +++ b/op-ufm/go.mod @@ -1,16 +1,19 @@ module github.com/ethereum-optimism/optimism/op-ufm -go 1.20 +go 1.21 + +toolchain go1.21.6 require ( cloud.google.com/go/kms v1.12.1 github.com/BurntSushi/toml v1.3.2 - github.com/ethereum-optimism/optimism/op-service v0.10.14 - github.com/ethereum/go-ethereum v1.12.1 + github.com/ethereum-optimism/optimism v1.6.2-0.20240222202618-f707883038d5 + github.com/ethereum/go-ethereum v1.13.8 github.com/gorilla/mux v1.8.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.16.0 + github.com/prometheus/client_golang v1.19.0 github.com/rs/cors v1.9.0 + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa ) require ( @@ -18,72 +21,83 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.0 // indirect github.com/DataDog/zstd v1.5.2 // indirect - github.com/VictoriaMetrics/fastcache v1.10.0 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.7.0 // indirect + github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.13 // indirect - github.com/consensys/gnark-crypto v0.12.0 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/crate-crypto/go-kzg-4844 v0.3.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect + github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect - github.com/ethereum/c-kzg-4844 v0.3.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240306093353-c557df8e6f41 // indirect + github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/s2a-go v0.1.4 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.2.3 // indirect - github.com/klauspost/compress v1.15.15 // indirect + github.com/holiman/uint256 v1.2.4 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect - github.com/rivo/uniseg v0.3.4 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/rivo/uniseg v0.4.3 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect - github.com/tklauser/go-sysconf v0.3.10 // indirect - github.com/tklauser/numcpus v0.5.0 // indirect - github.com/urfave/cli v1.22.9 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/urfave/cli/v2 v2.27.1 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/oauth2 v0.10.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.16.1 // indirect google.golang.org/api v0.132.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect - google.golang.org/grpc v1.56.2 // indirect - google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect + google.golang.org/grpc v1.56.3 // indirect + google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) + +replace github.com/ethereum/go-ethereum v1.13.8 => github.com/ethereum-optimism/op-geth v1.101308.2-rc.2 + +replace github.com/ethereum-optimism/optimism => ../. diff --git a/op-ufm/go.sum b/op-ufm/go.sum index e015f1f29f77..a40bd9ece1ed 100644 --- a/op-ufm/go.sum +++ b/op-ufm/go.sum @@ -1,6 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk= +cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= @@ -9,35 +10,30 @@ cloud.google.com/go/iam v1.1.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94= cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk= cloud.google.com/go/kms v1.12.1 h1:xZmZuwy2cwzsocmKDOPu4BL7umg8QXagQx6fKVmf45U= cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= -github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= +github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= -github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/btcsuite/btcd v0.23.3 h1:4KH/JKy9WiCd+iUS9Mu0Zp7Dnj17TGdKrg9xc/FGj24= +github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd v0.24.0 h1:gL3uHE/IaFj6fcZSu03SvqPMSx7s/dPzfpG/atRwWdo= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -50,96 +46,75 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= +github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 h1:ytcWPaNPhNoGMWEhDvS3zToKcDpRsLuRolQJBVGdozk= -github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811/go.mod h1:Nb5lgvnQ2+oGlE/EyZy4+2/CxRh9KfvCXnag1vtpxVM= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4 h1:PuHFhOUMnD62r80dN+Ik5qco2drekgsUSVdcHsvllec= +github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4/go.mod h1:sEHm5NOXxyiAoKWhoFxT8xMgd/f3RA6qUqQ1BXKrh2E= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.12.0 h1:1OnSpOykNkUIBIBJKdhwy2p0JlW5o+Az02ICzZmvvdg= -github.com/consensys/gnark-crypto v0.12.0/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-kzg-4844 v0.3.0 h1:UBlWE0CgyFqqzTI+IFyCzA7A3Zw4iip6uzRv5NIXG0A= -github.com/crate-crypto/go-kzg-4844 v0.3.0/go.mod h1:SBP7ikXEgDnUPONgm33HtuDZEDtWa3L4QtN1ocJSEQ4= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= +github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/ethereum-optimism/optimism/op-service v0.10.14 h1:MC+rVwtPfX1aPAKA3855DQaCnhjjp4uFcSr8PY7HmaE= -github.com/ethereum-optimism/optimism/op-service v0.10.14/go.mod h1:8ay6Bs3YHaX+FbJRUGSbxBnXRtEbKXNHMhtJqATrBmY= -github.com/ethereum/c-kzg-4844 v0.3.0 h1:3Y3hD6l5i0dEYsBL50C+Om644kve3pNqoAcvE26o9zI= -github.com/ethereum/c-kzg-4844 v0.3.0/go.mod h1:WI2Nd82DMZAAZI1wV2neKGost9EKjvbpQR9OqE5Qqa8= -github.com/ethereum/go-ethereum v1.12.1 h1:1kXDPxhLfyySuQYIfRxVBGYuaHdxNNxevA73vjIwsgk= -github.com/ethereum/go-ethereum v1.12.1/go.mod h1:zKetLweqBR8ZS+1O9iJWI8DvmmD2NzD19apjEWDCsnw= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/ethereum-optimism/op-geth v1.101308.2-rc.2 h1:Tjm2n7/actyINbRIbqeDS+SyWAcIl+pRfOHODwW7lpQ= +github.com/ethereum-optimism/op-geth v1.101308.2-rc.2/go.mod h1:RPqVhnX00rJNys/YRDK4Wl4PvS6dgFrLqhsopIZOhEw= +github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240306093353-c557df8e6f41 h1:WKJvsRyW/YNgyT0P2x5U530ITOY8Dv9TrZnbliqSXd8= +github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240306093353-c557df8e6f41/go.mod h1:7xh2awFQqsiZxFrHKTgEd+InVfDRrkKVUIuK8SAFHp0= +github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= +github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/fjl/memsize v0.0.1 h1:+zhkb+dhUgx0/e+M8sF0QqiouvMQUiKR+QYvdxIOKcQ= +github.com/fjl/memsize v0.0.1/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -149,7 +124,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -165,7 +139,6 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -173,117 +146,70 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/go-bexpr v0.1.11 h1:6DqdA/KBjurGby9yTY0bmkathya0lfwF2SeuubCI7dY= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/go-bexpr v0.1.11/go.mod h1:f03lAo0duBlDIUMGCuad8oLcgejw4m7U+N8T+6Kz1AE= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= -github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= -github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw= +github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -292,241 +218,177 @@ github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= +github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= -github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= -github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= -github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= -github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= -github.com/tklauser/numcpus v0.5.0 h1:ooe7gN0fg6myJ0EKoTAf5hebTZrH52px3New/D9iJ+A= -github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw= -github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.24.1 h1:/QYYr7g0EhwXEML8jO+8OYt5trPnLHS0p3mrgExJ5NU= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= -golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -538,19 +400,16 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8= google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU= google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -558,10 +417,9 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= -google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -573,21 +431,14 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -596,9 +447,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/op-ufm/pkg/metrics/clients/signer.go b/op-ufm/pkg/metrics/clients/signer.go index 8a15463a81f5..6d0c413b7ed1 100644 --- a/op-ufm/pkg/metrics/clients/signer.go +++ b/op-ufm/pkg/metrics/clients/signer.go @@ -6,9 +6,10 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-ufm/pkg/metrics" + "github.com/ethereum/go-ethereum/common" - optls "github.com/ethereum-optimism/optimism/op-service/tls" signer "github.com/ethereum-optimism/optimism/op-service/signer" + optls "github.com/ethereum-optimism/optimism/op-service/tls" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" ) @@ -29,9 +30,9 @@ func NewSignerClient(providerName string, logger log.Logger, endpoint string, tl return &InstrumentedSignerClient{c: c, providerName: providerName}, nil } -func (i *InstrumentedSignerClient) SignTransaction(ctx context.Context, chainId *big.Int, tx *types.Transaction) (*types.Transaction, error) { +func (i *InstrumentedSignerClient) SignTransaction(ctx context.Context, chainId *big.Int, from *common.Address, tx *types.Transaction) (*types.Transaction, error) { start := time.Now() - tx, err := i.c.SignTransaction(ctx, chainId, tx) + tx, err := i.c.SignTransaction(ctx, chainId, *from, tx) if err != nil { metrics.RecordErrorDetails(i.providerName, "signer.SignTransaction", err) return nil, err diff --git a/op-ufm/pkg/provider/roundtrip.go b/op-ufm/pkg/provider/roundtrip.go index 3145abcd07ac..6de763cbcf38 100644 --- a/op-ufm/pkg/provider/roundtrip.go +++ b/op-ufm/pkg/provider/roundtrip.go @@ -57,8 +57,7 @@ func (p *Provider) RoundTrip(ctx context.Context) { } } - tx, err := p.createTx(ctx, client, nonce) - nonce = tx.Nonce() + from, tx, err := p.createTx(ctx, client, nonce) if err != nil { log.Error("cant create tx", "provider", p.name, @@ -66,8 +65,9 @@ func (p *Provider) RoundTrip(ctx context.Context) { "err", err) return } + nonce = tx.Nonce() - signedTx, err := p.sign(ctx, tx) + signedTx, err := p.sign(ctx, from, tx) if err != nil { log.Error("cant sign tx", "provider", p.name, @@ -192,16 +192,16 @@ func (p *Provider) RoundTrip(ctx context.Context) { "gasUsed", receipt.GasUsed) } -func (p *Provider) createTx(ctx context.Context, client *iclients.InstrumentedEthClient, nonce uint64) (*types.Transaction, error) { +func (p *Provider) createTx(ctx context.Context, client *iclients.InstrumentedEthClient, nonce uint64) (*common.Address, *types.Transaction, error) { var err error if nonce == 0 { nonce, err = client.PendingNonceAt(ctx, p.walletConfig.Address) if err != nil { - log.Error("cant get nounce", + log.Error("cant get nonce", "provider", p.name, "nonce", nonce, "err", err) - return nil, err + return nil, nil, err } } @@ -210,17 +210,21 @@ func (p *Provider) createTx(ctx context.Context, client *iclients.InstrumentedEt log.Error("cant get gas tip cap", "provider", p.name, "err", err) - return nil, err + return nil, nil, err } - gasTipCap = new(big.Int).Mul(gasTipCap, big.NewInt(110)) - gasTipCap = new(big.Int).Div(gasTipCap, big.NewInt(100)) + + // adjust gas tip cap by 110% + const GasTipCapAdjustmentMultiplier = 110 + const GasTipCapAdjustmentDivisor = 100 + gasTipCap = new(big.Int).Mul(gasTipCap, big.NewInt(GasTipCapAdjustmentMultiplier)) + gasTipCap = new(big.Int).Div(gasTipCap, big.NewInt(GasTipCapAdjustmentDivisor)) head, err := client.HeaderByNumber(ctx, nil) if err != nil { log.Error("cant get base fee from head", "provider", p.name, "err", err) - return nil, err + return nil, nil, err } baseFee := head.BaseFee @@ -252,7 +256,7 @@ func (p *Provider) createTx(ctx context.Context, client *iclients.InstrumentedEt log.Error("cant estimate gas", "provider", p.name, "err", err) - return nil, err + return nil, nil, err } dynamicTx.Gas = gas tx := types.NewTx(dynamicTx) @@ -268,14 +272,15 @@ func (p *Provider) createTx(ctx context.Context, client *iclients.InstrumentedEt "gasFeeCap", dynamicTx.GasFeeCap, ) - return tx, nil + return &addr, tx, nil } -func (p *Provider) sign(ctx context.Context, tx *types.Transaction) (*types.Transaction, error) { +func (p *Provider) sign(ctx context.Context, from *common.Address, tx *types.Transaction) (*types.Transaction, error) { if p.walletConfig.SignerMethod == "static" { log.Debug("using static signer") privateKey, err := crypto.HexToECDSA(p.walletConfig.PrivateKey) if err != nil { + log.Error("failed to parse private key", "err", err) return nil, err } return types.SignTx(tx, types.LatestSignerForChainID(&p.walletConfig.ChainID), privateKey) @@ -286,18 +291,15 @@ func (p *Provider) sign(ctx context.Context, tx *types.Transaction) (*types.Tran TLSKey: p.signerConfig.TLSKey, } client, err := iclients.NewSignerClient(p.name, log.Root(), p.signerConfig.URL, tlsConfig) - log.Debug("signerclient", - "client", client, - "err", err) - if err != nil { - return nil, err + if err != nil || client == nil { + log.Error("failed to create signer client", "err", err) } if client == nil { return nil, errors.New("could not initialize signer client") } - signedTx, err := client.SignTransaction(ctx, &p.walletConfig.ChainID, tx) + signedTx, err := client.SignTransaction(ctx, &p.walletConfig.ChainID, from, tx) if err != nil { return nil, err } diff --git a/op-ufm/tools/kmstool/main.go b/op-ufm/tools/kmstool/main.go index 2fea5f3f19d6..425e76147365 100644 --- a/op-ufm/tools/kmstool/main.go +++ b/op-ufm/tools/kmstool/main.go @@ -26,13 +26,13 @@ func main() { ctx := context.Background() client, err := kms.NewKeyManagementClient(ctx) if err != nil { - panic(fmt.Sprintf("failed to create kms client: %w", err)) + panic(fmt.Errorf("failed to create kms client: %w", err)) } defer client.Close() addr, err := resolveAddr(ctx, client, keyName) if err != nil { - panic(fmt.Sprintf("failed to retrieve the key: %w", err)) + panic(fmt.Errorf("failed to retrieve the key: %w", err)) } fmt.Printf("ethereum addr: %s", addr) println() diff --git a/op-wheel/Makefile b/op-wheel/Makefile index 6496e3bc8c54..3fe0c0a85b58 100644 --- a/op-wheel/Makefile +++ b/op-wheel/Makefile @@ -9,3 +9,6 @@ LDFLAGS := -ldflags "$(LDFLAGSSTRING)" op-wheel: env GO111MODULE=on GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) go build -v $(LDFLAGS) -o ./bin/op-wheel ./cmd + +.PHONY: \ + op-wheel diff --git a/op-wheel/cheat/cheat.go b/op-wheel/cheat/cheat.go index debffacc1182..1bf4c4bad97d 100644 --- a/op-wheel/cheat/cheat.go +++ b/op-wheel/cheat/cheat.go @@ -21,13 +21,13 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" ) -var HundredETH = big.NewInt(0).Mul(big.NewInt(100), big.NewInt(1000000000000000000)) +var HundredETH = big.NewInt(0).Mul(big.NewInt(100), big.NewInt(params.Ether)) type Cheater struct { // The database of the chain with the head block that we patch the state-root of, once the state is updated. @@ -78,12 +78,6 @@ func (ch *Cheater) Close() error { return ch.DB.Close() } -func openStorageTrie(s *state.StateDB, addr common.Address) (state.Trie, error) { - stateRoot := s.IntermediateRoot(true) - storageRoot := s.GetStorageRoot(addr) - return s.Database().OpenStorageTrie(stateRoot, addr, storageRoot) -} - type HeadFn func(header *types.Header, headState *state.StateDB) error // RunAndClose runs the given function on the head-state, and then persists any changes (if not ReadOnly), @@ -198,7 +192,7 @@ func StorageGet(address common.Address, key common.Hash, w io.Writer) HeadFn { // to another account (maybe even in a different database!). func StorageReadAll(address common.Address, w io.Writer) HeadFn { return func(_ *types.Header, headState *state.StateDB) error { - storage, err := openStorageTrie(headState, address) + storage, err := headState.OpenStorageTrie(address) if err != nil { return fmt.Errorf("failed to open storage trie of addr %s: %w", address, err) } @@ -235,14 +229,14 @@ func dbValueToHash(enc []byte) common.Hash { // Each difference is expressed with 1 character + or - to indicate the change from a to b, followed by key = value. func StorageDiff(out io.Writer, addressA, addressB common.Address) HeadFn { return func(_ *types.Header, headState *state.StateDB) error { - aStorage, err := openStorageTrie(headState, addressA) + aStorage, err := headState.OpenStorageTrie(addressA) if err != nil { return fmt.Errorf("failed to open storage trie of addr A %s: %w", addressA, err) } if aStorage == nil { return fmt.Errorf("no storage trie in state for account A %s", addressA) } - bStorage, err := openStorageTrie(headState, addressB) + bStorage, err := headState.OpenStorageTrie(addressB) if err != nil { return fmt.Errorf("failed to open storage trie of addr B %s: %w", addressB, err) } @@ -339,58 +333,6 @@ func StoragePatch(patch io.Reader, address common.Address) HeadFn { } } -type OvmOwnersConfig struct { - Network string `json:"network"` - Owner common.Address `json:"owner"` - Sequencer common.Address `json:"sequencer"` - Proposer common.Address `json:"proposer"` -} - -func OvmOwners(conf *OvmOwnersConfig) HeadFn { - return func(_ *types.Header, headState *state.StateDB) error { - var addressManager common.Address // Lib_AddressManager - var l1SBProxy common.Address // Proxy__OVM_L1StandardBridge - var l1XDMProxy common.Address // Proxy__OVM_L1CrossDomainMessenger - var l1ERC721BridgeProxy common.Address - switch conf.Network { - case "mainnet": - addressManager = common.HexToAddress("0xdE1FCfB0851916CA5101820A69b13a4E276bd81F") - l1SBProxy = common.HexToAddress("0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1") - l1XDMProxy = common.HexToAddress("0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1") - l1ERC721BridgeProxy = common.HexToAddress("0x5a7749f83b81B301cAb5f48EB8516B986DAef23D") - case "goerli": - addressManager = common.HexToAddress("0xa6f73589243a6A7a9023b1Fa0651b1d89c177111") - l1SBProxy = common.HexToAddress("0x636Af16bf2f682dD3109e60102b8E1A089FedAa8") - l1XDMProxy = common.HexToAddress("0x5086d1eEF304eb5284A0f6720f79403b4e9bE294") - l1ERC721BridgeProxy = common.HexToAddress("0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9") - default: - return fmt.Errorf("unknown network: %q", conf.Network) - } - // See Proxy.sol OWNER_KEY: https://eips.ethereum.org/EIPS/eip-1967#admin-address - ownerSlot := common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103") - - // Address manager owner - // Ownable, first storage slot - headState.SetState(addressManager, common.Hash{}, eth.AddressAsLeftPaddedHash(conf.Owner)) - // L1SB proxy owner - headState.SetState(l1SBProxy, ownerSlot, eth.AddressAsLeftPaddedHash(conf.Owner)) - // L1XDM owner - // 0x33 = 51. L1CrossDomainMessenger is L1CrossDomainMessenger (0) Lib_AddressResolver (1) OwnableUpgradeable (1, but covered by gap) + ContextUpgradeable (special gap of 50) and then _owner - headState.SetState(l1XDMProxy, common.Hash{31: 0x33}, eth.AddressAsLeftPaddedHash(conf.Owner)) - // L1 ERC721 bridge owner - headState.SetState(l1ERC721BridgeProxy, ownerSlot, eth.AddressAsLeftPaddedHash(conf.Owner)) - // Legacy sequencer/proposer addresses - // See AddressManager.sol "addresses" mapping(bytes32 => address), at slot position 1 - addressesSlot := common.BigToHash(big.NewInt(1)) - headState.SetState(addressManager, crypto.Keccak256Hash(crypto.Keccak256([]byte("OVM_Sequencer")), addressesSlot.Bytes()), eth.AddressAsLeftPaddedHash(conf.Sequencer)) - headState.SetState(addressManager, crypto.Keccak256Hash(crypto.Keccak256([]byte("OVM_Proposer")), addressesSlot.Bytes()), eth.AddressAsLeftPaddedHash(conf.Proposer)) - // Fund sequencer and proposer with 100 ETH - headState.SetBalance(conf.Sequencer, HundredETH) - headState.SetBalance(conf.Proposer, HundredETH) - return nil - } -} - func SetBalance(addr common.Address, amount *big.Int) HeadFn { return func(_ *types.Header, headState *state.StateDB) error { headState.SetBalance(addr, amount) diff --git a/op-wheel/cmd/main.go b/op-wheel/cmd/main.go index 29c726cddb21..03d29c72c055 100644 --- a/op-wheel/cmd/main.go +++ b/op-wheel/cmd/main.go @@ -27,12 +27,8 @@ func main() { app.Description = "Optimism Wheel is a CLI tool to direct the engine one way or the other with DB cheats and Engine API routines." app.Flags = []cli.Flag{wheel.GlobalGethLogLvlFlag} app.Before = func(c *cli.Context) error { - log.Root().SetHandler( - log.LvlFilterHandler( - c.Generic(wheel.GlobalGethLogLvlFlag.Name).(*oplog.LvlFlagValue).LogLvl(), - log.StreamHandler(os.Stdout, log.TerminalFormat(true)), - ), - ) + lvl := c.Generic(wheel.GlobalGethLogLvlFlag.Name).(*oplog.LevelFlagValue).Level() + oplog.SetGlobalLogHandler(log.NewTerminalHandlerWithLevel(os.Stdout, lvl, true)) return nil } app.Action = cli.ActionFunc(func(c *cli.Context) error { diff --git a/op-wheel/commands.go b/op-wheel/commands.go index b356c8711dab..908e62275879 100644 --- a/op-wheel/commands.go +++ b/op-wheel/commands.go @@ -18,12 +18,16 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum-optimism/optimism/op-node/rollup" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/client" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" + "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-wheel/cheat" "github.com/ethereum-optimism/optimism/op-wheel/engine" ) @@ -39,7 +43,7 @@ var ( Name: "geth-log-level", Usage: "Set the global geth logging level", EnvVars: prefixEnvVars("GETH_LOG_LEVEL"), - Value: oplog.NewLvlFlagValue(log.LvlError), + Value: oplog.NewLevelFlagValue(log.LevelError), } DataDirFlag = &cli.StringFlag{ Name: "data-dir", @@ -50,8 +54,9 @@ var ( } EngineEndpoint = &cli.StringFlag{ Name: "engine", - Usage: "Engine API RPC endpoint, can be HTTP/WS/IPC", + Usage: "Authenticated Engine API RPC endpoint, can be HTTP/WS/IPC", Required: true, + Value: "http://localhost:8551/", EnvVars: prefixEnvVars("ENGINE"), } EngineJWTPath = &cli.StringFlag{ @@ -61,6 +66,23 @@ var ( TakesFile: true, EnvVars: prefixEnvVars("ENGINE_JWT_SECRET"), } + EngineOpenEndpoint = &cli.StringFlag{ + Name: "engine.open", + Usage: "Open Engine API RPC endpoint, can be HTTP/WS/IPC", + Value: "http://localhost:8545/", + EnvVars: prefixEnvVars("ENGINE_OPEN"), + } + EngineVersion = &cli.IntFlag{ + Name: "engine.version", + Usage: "Engine API version to use for Engine calls (1, 2, or 3)", + EnvVars: prefixEnvVars("ENGINE_VERSION"), + Action: func(ctx *cli.Context, ev int) error { + if ev < 1 || ev > 3 { + return fmt.Errorf("invalid Engine API version: %d", ev) + } + return nil + }, + } FeeRecipientFlag = &cli.GenericFlag{ Name: "fee-recipient", Usage: "fee-recipient of the block building", @@ -92,6 +114,12 @@ var ( } ) +func withEngineFlags(flags ...cli.Flag) []cli.Flag { + return append(append(flags, + EngineEndpoint, EngineJWTPath, EngineOpenEndpoint, EngineVersion), + oplog.CLIFlags(envVarPrefix)...) +} + func ParseBuildingArgs(ctx *cli.Context) *engine.BlockBuildingSettings { return &engine.BlockBuildingSettings{ BlockTime: ctx.Uint64(BlockTimeFlag.Name), @@ -124,19 +152,84 @@ func CheatRawDBAction(readOnly bool, fn func(ctx *cli.Context, db ethdb.Database } } -func EngineAction(fn func(ctx *cli.Context, client client.RPC) error) cli.ActionFunc { +func EngineAction(fn func(ctx *cli.Context, client *sources.EngineAPIClient, lgr log.Logger) error) cli.ActionFunc { return func(ctx *cli.Context) error { - jwtData, err := os.ReadFile(ctx.String(EngineJWTPath.Name)) + lgr := initLogger(ctx) + rpc, err := initEngineRPC(ctx, lgr) if err != nil { - return fmt.Errorf("failed to read jwt: %w", err) + return fmt.Errorf("failed to dial Engine API endpoint %q: %w", + ctx.String(EngineEndpoint.Name), err) } - secret := common.HexToHash(strings.TrimSpace(string(jwtData))) - endpoint := ctx.String(EngineEndpoint.Name) - client, err := engine.DialClient(context.Background(), endpoint, secret) + evp, err := initVersionProvider(ctx, lgr) if err != nil { - return fmt.Errorf("failed to dial Engine API endpoint %q: %w", endpoint, err) + return fmt.Errorf("failed to init Engine version provider: %w", err) } - return fn(ctx, client) + client := sources.NewEngineAPIClient(rpc, lgr, evp) + return fn(ctx, client, lgr) + } +} + +func initLogger(ctx *cli.Context) log.Logger { + logCfg := oplog.ReadCLIConfig(ctx) + lgr := oplog.NewLogger(oplog.AppOut(ctx), logCfg) + oplog.SetGlobalLogHandler(lgr.Handler()) + return lgr +} + +func initEngineRPC(ctx *cli.Context, lgr log.Logger) (client.RPC, error) { + jwtData, err := os.ReadFile(ctx.String(EngineJWTPath.Name)) + if err != nil { + return nil, fmt.Errorf("failed to read jwt: %w", err) + } + secret := common.HexToHash(strings.TrimSpace(string(jwtData))) + endpoint := ctx.String(EngineEndpoint.Name) + return client.NewRPC(ctx.Context, lgr, endpoint, + client.WithGethRPCOptions(rpc.WithHTTPAuth(node.NewJWTAuth(secret)))) +} + +func initVersionProvider(ctx *cli.Context, lgr log.Logger) (sources.EngineVersionProvider, error) { + // static configuration takes precedent, if set + if ctx.IsSet(EngineVersion.Name) { + ev := ctx.Int(EngineVersion.Name) + return engine.StaticVersionProvider(ev), nil + } + + // otherwise get config from EL + rpc, err := initOpenEngineRPC(ctx, lgr) + if err != nil { + return nil, err + } + + cfg, err := engine.GetChainConfig(ctx.Context, rpc) + if err != nil { + return nil, err + } + return rollupFromGethConfig(cfg), nil +} + +func initOpenEngineRPC(ctx *cli.Context, lgr log.Logger) (client.RPC, error) { + openEP := ctx.String(EngineOpenEndpoint.Name) + rpc, err := client.NewRPC(ctx.Context, lgr, openEP) + if err != nil { + return nil, fmt.Errorf("failed to dial open Engine endpoint %q: %w", openEP, err) + } + return rpc, nil +} + +// rollupFromGethConfig returns a very incomplete rollup config with only the +// L2ChainID and (most) fork activation timestamps set. +// +// Because Delta was a pure CL fork, its time isn't set either. +// +// This incomplete [rollup.Config] can be used as a [sources.EngineVersionProvider]. +func rollupFromGethConfig(cfg *params.ChainConfig) *rollup.Config { + return &rollup.Config{ + L2ChainID: cfg.ChainID, + + RegolithTime: cfg.RegolithTime, + CanyonTime: cfg.CanyonTime, + EcotoneTime: cfg.EcotoneTime, + InteropTime: cfg.InteropTime, } } @@ -316,30 +409,6 @@ var ( return ch.RunAndClose(cheat.SetNonce(addrFlagValue("address", ctx), bigFlagValue("balance", ctx).Uint64())) }), } - CheatOvmOwnersCmd = &cli.Command{ - Name: "ovm-owners", - Flags: []cli.Flag{ - DataDirFlag, - &cli.StringFlag{ - Name: "config", - Usage: "Path to JSON config of OVM address replacements to apply.", - Required: true, - EnvVars: prefixEnvVars("OVM_OWNERS"), - Value: "ovm-owners.json", - }, - }, - Action: CheatAction(false, func(ctx *cli.Context, ch *cheat.Cheater) error { - confData, err := os.ReadFile(ctx.String("config")) - if err != nil { - return fmt.Errorf("failed to read OVM owners JSON config file: %w", err) - } - var conf cheat.OvmOwnersConfig - if err := json.Unmarshal(confData, &conf); err != nil { - return err - } - return ch.RunAndClose(cheat.OvmOwners(&conf)) - }), - } CheatPrintHeadBlock = &cli.Command{ Name: "head-block", Usage: "dump head block as JSON", @@ -374,41 +443,35 @@ var ( EngineBlockCmd = &cli.Command{ Name: "block", Usage: "build the next block using the Engine API", - Flags: []cli.Flag{ - EngineEndpoint, EngineJWTPath, + Flags: withEngineFlags( FeeRecipientFlag, RandaoFlag, BlockTimeFlag, BuildingTime, AllowGaps, - }, + ), // TODO: maybe support transaction and tx pool engine flags, since we use op-geth? // TODO: reorg flag // TODO: finalize/safe flag - Action: EngineAction(func(ctx *cli.Context, client client.RPC) error { + Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, _ log.Logger) error { settings := ParseBuildingArgs(ctx) - status, err := engine.Status(context.Background(), client) + status, err := engine.Status(context.Background(), client.RPC) if err != nil { return err } - payload, err := engine.BuildBlock(context.Background(), client, status, settings) + payloadEnv, err := engine.BuildBlock(context.Background(), client, status, settings) if err != nil { return err } - _, err = io.WriteString(ctx.App.Writer, payload.BlockHash.String()) - return err + fmt.Fprintln(ctx.App.Writer, payloadEnv.ExecutionPayload.BlockHash) + return nil }), } EngineAutoCmd = &cli.Command{ Name: "auto", Usage: "Run a proof-of-nothing chain with fixed block time.", Description: "The block time can be changed. The execution engine must be synced to a post-Merge state first.", - Flags: append(append([]cli.Flag{ - EngineEndpoint, EngineJWTPath, - FeeRecipientFlag, RandaoFlag, BlockTimeFlag, BuildingTime, AllowGaps, - }, oplog.CLIFlags(envVarPrefix)...), opmetrics.CLIFlags(envVarPrefix)...), - Action: EngineAction(func(ctx *cli.Context, client client.RPC) error { - logCfg := oplog.ReadCLIConfig(ctx) - l := oplog.NewLogger(oplog.AppOut(ctx), logCfg) - oplog.SetGlobalLogHandler(l.GetHandler()) - + Flags: append(withEngineFlags( + FeeRecipientFlag, RandaoFlag, BlockTimeFlag, BuildingTime, AllowGaps), + opmetrics.CLIFlags(envVarPrefix)...), + Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, l log.Logger) error { settings := ParseBuildingArgs(ctx) // TODO: finalize/safe flag @@ -435,9 +498,9 @@ var ( } EngineStatusCmd = &cli.Command{ Name: "status", - Flags: []cli.Flag{EngineEndpoint, EngineJWTPath}, - Action: EngineAction(func(ctx *cli.Context, client client.RPC) error { - stat, err := engine.Status(context.Background(), client) + Flags: withEngineFlags(), + Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, _ log.Logger) error { + stat, err := engine.Status(context.Background(), client.RPC) if err != nil { return err } @@ -448,16 +511,15 @@ var ( } EngineCopyCmd = &cli.Command{ Name: "copy", - Flags: []cli.Flag{ - EngineEndpoint, EngineJWTPath, + Flags: withEngineFlags( &cli.StringFlag{ Name: "source", Usage: "Unauthenticated regular eth JSON RPC to pull block data from, can be HTTP/WS/IPC.", Required: true, - EnvVars: prefixEnvVars("ENGINE"), + EnvVars: prefixEnvVars("SOURCE"), }, - }, - Action: EngineAction(func(ctx *cli.Context, dest client.RPC) error { + ), + Action: EngineAction(func(ctx *cli.Context, dest *sources.EngineAPIClient, _ log.Logger) error { rpcClient, err := rpc.DialOptions(context.Background(), ctx.String("source")) if err != nil { return fmt.Errorf("failed to dial engine source endpoint: %w", err) @@ -467,11 +529,37 @@ var ( }), } + EngineCopyPayloadCmd = &cli.Command{ + Name: "copy-payload", + Description: "Take the block by number from source and insert it to the engine with NewPayload. No other calls are made.", + Flags: withEngineFlags( + &cli.StringFlag{ + Name: "source", + Usage: "Unauthenticated regular eth JSON RPC to pull block data from, can be HTTP/WS/IPC.", + Required: true, + EnvVars: prefixEnvVars("SOURCE"), + }, + &cli.Uint64Flag{ + Name: "number", + Usage: "Block number to copy from the source", + Required: true, + EnvVars: prefixEnvVars("NUMBER"), + }, + ), + Action: EngineAction(func(ctx *cli.Context, dest *sources.EngineAPIClient, _ log.Logger) error { + rpcClient, err := rpc.DialOptions(context.Background(), ctx.String("source")) + if err != nil { + return fmt.Errorf("failed to dial engine source endpoint: %w", err) + } + source := client.NewBaseRPCClient(rpcClient) + return engine.CopyPayload(context.Background(), ctx.Uint64("number"), source, dest) + }), + } + EngineSetForkchoiceCmd = &cli.Command{ Name: "set-forkchoice", Description: "Set forkchoice, specify unsafe, safe and finalized blocks by number", - Flags: []cli.Flag{ - EngineEndpoint, EngineJWTPath, + Flags: withEngineFlags( &cli.Uint64Flag{ Name: "unsafe", Usage: "Block number of block to set as latest block", @@ -490,26 +578,81 @@ var ( Required: true, EnvVars: prefixEnvVars("FINALIZED"), }, - }, - Action: EngineAction(func(ctx *cli.Context, client client.RPC) error { + ), + Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, _ log.Logger) error { return engine.SetForkchoice(ctx.Context, client, ctx.Uint64("finalized"), ctx.Uint64("safe"), ctx.Uint64("unsafe")) }), } + EngineSetForkchoiceHashCmd = &cli.Command{ + Name: "set-forkchoice-by-hash", + Description: "Set forkchoice, specify unsafe, safe and finalized blocks by hash", + Flags: withEngineFlags( + &cli.StringFlag{ + Name: "unsafe", + Usage: "Block hash of block to set as latest block", + Required: true, + EnvVars: prefixEnvVars("UNSAFE"), + }, + &cli.StringFlag{ + Name: "safe", + Usage: "Block hash of block to set as safe block", + Required: true, + EnvVars: prefixEnvVars("SAFE"), + }, + &cli.StringFlag{ + Name: "finalized", + Usage: "Block hash of block to set as finalized block", + Required: true, + EnvVars: prefixEnvVars("FINALIZED"), + }, + ), + Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, _ log.Logger) error { + finalized := common.HexToHash(ctx.String("finalized")) + safe := common.HexToHash(ctx.String("safe")) + unsafe := common.HexToHash(ctx.String("unsafe")) + return engine.SetForkchoiceByHash(ctx.Context, client, finalized, safe, unsafe) + }), + } + + EngineRewindCmd = &cli.Command{ + Name: "rewind", + Description: "Rewind chain by number (destructive!)", + Flags: withEngineFlags( + &cli.Uint64Flag{ + Name: "to", + Usage: "Block number to rewind chain to", + Required: true, + EnvVars: prefixEnvVars("REWIND_TO"), + }, + &cli.BoolFlag{ + Name: "set-head", + Usage: "Whether to also call debug_setHead when rewinding", + EnvVars: prefixEnvVars("REWIND_SET_HEAD"), + }, + ), + Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, lgr log.Logger) error { + open, err := initOpenEngineRPC(ctx, lgr) + if err != nil { + return fmt.Errorf("failed to dial open RPC endpoint: %w", err) + } + return engine.Rewind(ctx.Context, lgr, client, open, ctx.Uint64("to"), ctx.Bool("set-head")) + }), + } + EngineJSONCmd = &cli.Command{ Name: "json", Description: "read json values from remaining args, or STDIN, and use them as RPC params to call the engine RPC method (first arg)", - Flags: []cli.Flag{ - EngineEndpoint, EngineJWTPath, + Flags: withEngineFlags( &cli.BoolFlag{ Name: "stdin", Usage: "Read params from stdin instead", Required: false, EnvVars: prefixEnvVars("STDIN"), }, - }, + ), ArgsUsage: " [params...]", - Action: EngineAction(func(ctx *cli.Context, client client.RPC) error { + Action: EngineAction(func(ctx *cli.Context, client *sources.EngineAPIClient, _ log.Logger) error { if ctx.NArg() == 0 { return fmt.Errorf("expected at least 1 argument: RPC method name") } @@ -520,7 +663,7 @@ var ( } else { args = ctx.Args().Tail() } - return engine.RawJSONInteraction(ctx.Context, client, ctx.Args().Get(0), args, r, ctx.App.Writer) + return engine.RawJSONInteraction(ctx.Context, client.RPC, ctx.Args().Get(0), args, r, ctx.App.Writer) }), } ) @@ -535,7 +678,6 @@ var CheatCmd = &cli.Command{ CheatSetBalanceCmd, CheatSetCodeCmd, CheatSetNonceCmd, - CheatOvmOwnersCmd, CheatPrintHeadBlock, CheatPrintHeadHeader, }, @@ -543,14 +685,17 @@ var CheatCmd = &cli.Command{ var EngineCmd = &cli.Command{ Name: "engine", - Usage: "Engine API commands to build/reorg/finalize blocks.", + Usage: "Engine API commands to build/reorg/rewind/finalize/copy blocks.", Description: "Each sub-command dials the engine API endpoint (with provided JWT secret) and then runs the action", Subcommands: []*cli.Command{ EngineBlockCmd, EngineAutoCmd, EngineStatusCmd, EngineCopyCmd, + EngineCopyPayloadCmd, EngineSetForkchoiceCmd, + EngineSetForkchoiceHashCmd, + EngineRewindCmd, EngineJSONCmd, }, } diff --git a/op-wheel/engine/engine.go b/op-wheel/engine/engine.go index 52fce956727b..c715d659afb8 100644 --- a/op-wheel/engine/engine.go +++ b/op-wheel/engine/engine.go @@ -10,48 +10,27 @@ import ( "strings" "time" - "github.com/ethereum/go-ethereum/beacon/engine" "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" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources" ) -type PayloadAttributesV2 struct { - Timestamp uint64 `json:"timestamp"` - Random common.Hash `json:"prevRandao"` - SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient"` - Withdrawals []*types.Withdrawal `json:"withdrawals"` -} - -func (p PayloadAttributesV2) MarshalJSON() ([]byte, error) { - type PayloadAttributes struct { - Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Random common.Hash `json:"prevRandao" gencodec:"required"` - SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"` - Withdrawals []*types.Withdrawal `json:"withdrawals"` - } - var enc PayloadAttributes - enc.Timestamp = hexutil.Uint64(p.Timestamp) - enc.Random = p.Random - enc.SuggestedFeeRecipient = p.SuggestedFeeRecipient - enc.Withdrawals = make([]*types.Withdrawal, 0) - return json.Marshal(&enc) -} - -func DialClient(ctx context.Context, endpoint string, jwtSecret [32]byte) (client.RPC, error) { - auth := node.NewJWTAuth(jwtSecret) +const ( + methodEthGetBlockByNumber = "eth_getBlockByNumber" + methodDebugChainConfig = "debug_chainConfig" + methodDebugSetHead = "debug_setHead" +) - rpcClient, err := rpc.DialOptions(ctx, endpoint, rpc.WithHTTPAuth(auth)) - if err != nil { - return nil, fmt.Errorf("failed to dial engine endpoint: %w", err) - } - return client.NewBaseRPCClient(rpcClient), nil +func GetChainConfig(ctx context.Context, open client.RPC) (cfg *params.ChainConfig, err error) { + err = open.CallContext(ctx, &cfg, methodDebugChainConfig) + return } type RPCBlock struct { @@ -77,49 +56,67 @@ func getHeader(ctx context.Context, client client.RPC, method string, tag string return header, nil } -func headSafeFinalized(ctx context.Context, client client.RPC) (head *types.Block, safe, finalized *types.Header, err error) { - head, err = getBlock(ctx, client, "eth_getBlockByNumber", "latest") +func headSafeFinalized(ctx context.Context, client client.RPC) (head, safe, finalized *types.Header, err error) { + head, err = getHeader(ctx, client, methodEthGetBlockByNumber, "latest") + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to get latest: %w", err) + } + safe, fin, err := safeFinalized(ctx, client) + return head, safe, fin, err +} + +func headBlockSafeFinalized(ctx context.Context, client client.RPC) (head *types.Block, safe, finalized *types.Header, err error) { + head, err = getBlock(ctx, client, methodEthGetBlockByNumber, "latest") if err != nil { - return nil, nil, nil, fmt.Errorf("failed to get block: %w", err) + return nil, nil, nil, fmt.Errorf("failed to get latest: %w", err) } - safe, err = getHeader(ctx, client, "eth_getBlockByNumber", "safe") + safe, fin, err := safeFinalized(ctx, client) + return head, safe, fin, err +} + +func safeFinalized(ctx context.Context, client client.RPC) (safe, finalized *types.Header, err error) { + safe, err = getHeader(ctx, client, methodEthGetBlockByNumber, "safe") if err != nil { - return head, nil, nil, fmt.Errorf("failed to get safe block: %w", err) + return nil, nil, fmt.Errorf("failed to get safe: %w", err) } - finalized, err = getHeader(ctx, client, "eth_getBlockByNumber", "finalized") + finalized, err = getHeader(ctx, client, methodEthGetBlockByNumber, "finalized") if err != nil { - return head, safe, nil, fmt.Errorf("failed to get finalized block: %w", err) + return safe, nil, fmt.Errorf("failed to get finalized: %w", err) } - return head, safe, finalized, nil + return safe, finalized, nil } -func insertBlock(ctx context.Context, client client.RPC, payload *engine.ExecutableData) error { - var payloadResult *engine.PayloadStatusV1 - if err := client.CallContext(ctx, &payloadResult, "engine_newPayloadV2", payload); err != nil { - return fmt.Errorf("failed to insert block %d: %w", payload.Number, err) +func insertBlock(ctx context.Context, client *sources.EngineAPIClient, payloadEnv *eth.ExecutionPayloadEnvelope) error { + payload := payloadEnv.ExecutionPayload + payloadResult, err := client.NewPayload(ctx, payload, payloadEnv.ParentBeaconBlockRoot) + if err != nil { + return fmt.Errorf("failed to insert block %d: %w", payload.BlockNumber, err) } - if payloadResult.Status != string(eth.ExecutionValid) { + if payloadResult.Status != eth.ExecutionValid { return fmt.Errorf("block insertion was not valid: %v", payloadResult.ValidationError) } return nil } -func updateForkchoice(ctx context.Context, client client.RPC, head, safe, finalized common.Hash) error { - var post engine.ForkChoiceResponse - if err := client.CallContext(ctx, &post, "engine_forkchoiceUpdatedV2", - engine.ForkchoiceStateV1{ - HeadBlockHash: head, - SafeBlockHash: safe, - FinalizedBlockHash: finalized, - }, nil); err != nil { - return fmt.Errorf("failed to set forkchoice with new block %s: %w", head, err) +func updateForkchoice(ctx context.Context, client *sources.EngineAPIClient, head, safe, finalized common.Hash) error { + res, err := client.ForkchoiceUpdate(ctx, ð.ForkchoiceState{ + HeadBlockHash: head, + SafeBlockHash: safe, + FinalizedBlockHash: finalized, + }, nil) + if err != nil { + return fmt.Errorf("failed to update forkchoice with new head %s: %w", head, err) } - if post.PayloadStatus.Status != string(eth.ExecutionValid) { - return fmt.Errorf("post-block forkchoice update was not valid: %v", post.PayloadStatus.ValidationError) + if res.PayloadStatus.Status != eth.ExecutionValid { + return fmt.Errorf("forkchoice update was not valid: %v", res.PayloadStatus.ValidationError) } return nil } +func debugSetHead(ctx context.Context, open client.RPC, head uint64) error { + return open.CallContext(ctx, nil, methodDebugSetHead, hexutil.Uint64(head)) +} + type BlockBuildingSettings struct { BlockTime uint64 // skip a block; timestamps will still increase in multiples of BlockTime like L1, but there may be gaps. @@ -129,7 +126,7 @@ type BlockBuildingSettings struct { BuildTime time.Duration } -func BuildBlock(ctx context.Context, client client.RPC, status *StatusData, settings *BlockBuildingSettings) (*engine.ExecutableData, error) { +func BuildBlock(ctx context.Context, client *sources.EngineAPIClient, status *StatusData, settings *BlockBuildingSettings) (*eth.ExecutionPayloadEnvelope, error) { timestamp := status.Head.Time + settings.BlockTime if settings.AllowGaps { now := uint64(time.Now().Unix()) @@ -137,20 +134,17 @@ func BuildBlock(ctx context.Context, client client.RPC, status *StatusData, sett timestamp = now - ((now - timestamp) % settings.BlockTime) } } - var pre engine.ForkChoiceResponse - if err := client.CallContext(ctx, &pre, "engine_forkchoiceUpdatedV2", - engine.ForkchoiceStateV1{ + attrs := newPayloadAttributes(client.EngineVersionProvider(), timestamp, settings.Random, settings.FeeRecipient) + pre, err := client.ForkchoiceUpdate(ctx, + ð.ForkchoiceState{ HeadBlockHash: status.Head.Hash, SafeBlockHash: status.Safe.Hash, FinalizedBlockHash: status.Finalized.Hash, - }, PayloadAttributesV2{ - Timestamp: timestamp, - Random: settings.Random, - SuggestedFeeRecipient: settings.FeeRecipient, - }); err != nil { + }, attrs) + if err != nil { return nil, fmt.Errorf("failed to set forkchoice when building new block: %w", err) } - if pre.PayloadStatus.Status != string(eth.ExecutionValid) { + if pre.PayloadStatus.Status != eth.ExecutionValid { return nil, fmt.Errorf("pre-block forkchoice update was not valid: %v", pre.PayloadStatus.ValidationError) } @@ -161,26 +155,45 @@ func BuildBlock(ctx context.Context, client client.RPC, status *StatusData, sett case <-time.After(settings.BuildTime): } - var payload *engine.ExecutionPayloadEnvelope - if err := client.CallContext(ctx, &payload, "engine_getPayloadV2", pre.PayloadID); err != nil { + payload, err := client.GetPayload(ctx, eth.PayloadInfo{ID: *pre.PayloadID, Timestamp: timestamp}) + if err != nil { return nil, fmt.Errorf("failed to get payload %v, %d time after instructing engine to build it: %w", pre.PayloadID, settings.BuildTime, err) } - if err := insertBlock(ctx, client, payload.ExecutionPayload); err != nil { + if err := insertBlock(ctx, client, payload); err != nil { return nil, err } if err := updateForkchoice(ctx, client, payload.ExecutionPayload.BlockHash, status.Safe.Hash, status.Finalized.Hash); err != nil { return nil, err } - return payload.ExecutionPayload, nil + return payload, nil +} + +func newPayloadAttributes(evp sources.EngineVersionProvider, timestamp uint64, prevRandao common.Hash, feeRecipient common.Address) *eth.PayloadAttributes { + pa := ð.PayloadAttributes{ + Timestamp: hexutil.Uint64(timestamp), + PrevRandao: eth.Bytes32(prevRandao), + SuggestedFeeRecipient: feeRecipient, + } + + ver := evp.ForkchoiceUpdatedVersion(pa) + if ver == eth.FCUV2 || ver == eth.FCUV3 { + withdrawals := make(types.Withdrawals, 0) + pa.Withdrawals = &withdrawals + } + if ver == eth.FCUV3 { + pa.ParentBeaconBlockRoot = new(common.Hash) + } + + return pa } -func Auto(ctx context.Context, metrics Metricer, client client.RPC, log log.Logger, shutdown <-chan struct{}, settings *BlockBuildingSettings) error { +func Auto(ctx context.Context, metrics Metricer, client *sources.EngineAPIClient, log log.Logger, shutdown <-chan struct{}, settings *BlockBuildingSettings) error { ticker := time.NewTicker(time.Millisecond * 100) defer ticker.Stop() - var lastPayload *engine.ExecutableData + var lastPayload *eth.ExecutionPayload var buildErr error for { select { @@ -194,7 +207,7 @@ func Auto(ctx context.Context, metrics Metricer, client client.RPC, log log.Logg blockTime := time.Duration(settings.BlockTime) * time.Second lastTime := uint64(0) if lastPayload != nil { - lastTime = lastPayload.Timestamp + lastTime = uint64(lastPayload.Timestamp) } buildTriggerTime := time.Unix(int64(lastTime), 0).Add(blockTime - settings.BuildTime) @@ -206,7 +219,7 @@ func Auto(ctx context.Context, metrics Metricer, client client.RPC, log log.Logg buildTime = 10 * time.Millisecond } buildErr = nil - status, err := Status(ctx, client) + status, err := Status(ctx, client.RPC) if err != nil { log.Error("failed to get pre-block engine status", "err", err) metrics.RecordBlockFail() @@ -220,7 +233,7 @@ func Auto(ctx context.Context, metrics Metricer, client client.RPC, log log.Logg // There are no gap slots, so we just go back 32 blocks. if status.Head.Number%32 == 0 { if status.Safe.Number+32 <= status.Head.Number { - safe, err := getHeader(ctx, client, "eth_getBlockByNumber", hexutil.Uint64(status.Head.Number-32).String()) + safe, err := getHeader(ctx, client.RPC, methodEthGetBlockByNumber, hexutil.Uint64(status.Head.Number-32).String()) if err != nil { buildErr = err log.Error("failed to find block for new safe block progress", "err", err) @@ -229,7 +242,7 @@ func Auto(ctx context.Context, metrics Metricer, client client.RPC, log log.Logg status.Safe = eth.L1BlockRef{Hash: safe.Hash(), Number: safe.Number.Uint64(), Time: safe.Time, ParentHash: safe.ParentHash} } if status.Finalized.Number+32 <= status.Safe.Number { - finalized, err := getHeader(ctx, client, "eth_getBlockByNumber", hexutil.Uint64(status.Safe.Number-32).String()) + finalized, err := getHeader(ctx, client.RPC, methodEthGetBlockByNumber, hexutil.Uint64(status.Safe.Number-32).String()) if err != nil { buildErr = err log.Error("failed to find block for new finalized block progress", "err", err) @@ -239,7 +252,7 @@ func Auto(ctx context.Context, metrics Metricer, client client.RPC, log log.Logg } } - payload, err := BuildBlock(ctx, client, status, &BlockBuildingSettings{ + payloadEnv, err := BuildBlock(ctx, client, status, &BlockBuildingSettings{ BlockTime: settings.BlockTime, AllowGaps: settings.AllowGaps, Random: settings.Random, @@ -251,12 +264,16 @@ func Auto(ctx context.Context, metrics Metricer, client client.RPC, log log.Logg log.Error("failed to produce block", "err", err) metrics.RecordBlockFail() } else { + payload := payloadEnv.ExecutionPayload lastPayload = payload - log.Info("created block", "hash", payload.BlockHash, "number", payload.Number, + log.Info("created block", "hash", payload.BlockHash, "number", payload.BlockNumber, "timestamp", payload.Timestamp, "txs", len(payload.Transactions), "gas", payload.GasUsed, "basefee", payload.BaseFeePerGas) - basefee, _ := new(big.Float).SetInt(payload.BaseFeePerGas).Float64() - metrics.RecordBlockStats(payload.BlockHash, payload.Number, payload.Timestamp, uint64(len(payload.Transactions)), payload.GasUsed, basefee) + basefee := (*uint256.Int)(&payload.BaseFeePerGas).Float64() + metrics.RecordBlockStats( + payload.BlockHash, uint64(payload.BlockNumber), uint64(payload.Timestamp), + uint64(len(payload.Transactions)), + uint64(payload.GasUsed), basefee) } } } @@ -274,7 +291,7 @@ type StatusData struct { } func Status(ctx context.Context, client client.RPC) (*StatusData, error) { - head, safe, finalized, err := headSafeFinalized(ctx, client) + head, safe, finalized, err := headBlockSafeFinalized(ctx, client) if err != nil { return nil, err } @@ -291,44 +308,73 @@ func Status(ctx context.Context, client client.RPC) (*StatusData, error) { // Copy takes the forkchoice state of copyFrom, and applies it to copyTo, and inserts the head-block. // The destination engine should then start syncing to this new chain if it has peers to do so. -func Copy(ctx context.Context, copyFrom client.RPC, copyTo client.RPC) error { - copyHead, copySafe, copyFinalized, err := headSafeFinalized(ctx, copyFrom) +func Copy(ctx context.Context, copyFrom client.RPC, copyTo *sources.EngineAPIClient) error { + copyHead, copySafe, copyFinalized, err := headBlockSafeFinalized(ctx, copyFrom) + if err != nil { + return err + } + payloadEnv, err := blockAsPayloadEnv(copyHead, copyTo.EngineVersionProvider()) if err != nil { return err } - payloadEnv := engine.BlockToExecutableData(copyHead, nil, nil) + if err := updateForkchoice(ctx, copyTo, copyHead.ParentHash(), copySafe.Hash(), copyFinalized.Hash()); err != nil { return err } - payload := payloadEnv.ExecutionPayload - if err := insertBlock(ctx, copyTo, payload); err != nil { + if err := insertBlock(ctx, copyTo, payloadEnv); err != nil { return err } - if err := updateForkchoice(ctx, copyTo, payload.BlockHash, copySafe.Hash(), copyFinalized.Hash()); err != nil { + if err := updateForkchoice(ctx, copyTo, + payloadEnv.ExecutionPayload.BlockHash, copySafe.Hash(), copyFinalized.Hash()); err != nil { return err } return nil } -func SetForkchoice(ctx context.Context, client client.RPC, finalizedNum, safeNum, unsafeNum uint64) error { +// CopyPaylod takes the execution payload at number & applies it via NewPayload to copyTo +func CopyPayload(ctx context.Context, number uint64, copyFrom client.RPC, copyTo *sources.EngineAPIClient) error { + copyHead, err := getBlock(ctx, copyFrom, methodEthGetBlockByNumber, hexutil.EncodeUint64(number)) + if err != nil { + return err + } + payloadEnv, err := blockAsPayloadEnv(copyHead, copyTo.EngineVersionProvider()) + if err != nil { + return err + } + if err := insertBlock(ctx, copyTo, payloadEnv); err != nil { + return err + } + return nil +} + +func blockAsPayloadEnv(block *types.Block, evp sources.EngineVersionProvider) (*eth.ExecutionPayloadEnvelope, error) { + var canyon *uint64 + // hack: if we're calling at least FCUV2, get empty withdrawals by setting Canyon before the block time + if v := evp.ForkchoiceUpdatedVersion(ð.PayloadAttributes{Timestamp: hexutil.Uint64(block.Time())}); v != eth.FCUV1 { + canyon = new(uint64) + } + return eth.BlockAsPayloadEnv(block, canyon) +} + +func SetForkchoice(ctx context.Context, client *sources.EngineAPIClient, finalizedNum, safeNum, unsafeNum uint64) error { if unsafeNum < safeNum { return fmt.Errorf("cannot set unsafe (%d) < safe (%d)", unsafeNum, safeNum) } if safeNum < finalizedNum { return fmt.Errorf("cannot set safe (%d) < finalized (%d)", safeNum, finalizedNum) } - head, err := getHeader(ctx, client, "eth_getBlockByNumber", "latest") + head, err := getHeader(ctx, client.RPC, methodEthGetBlockByNumber, "latest") if err != nil { return fmt.Errorf("failed to get latest block: %w", err) } if unsafeNum > head.Number.Uint64() { return fmt.Errorf("cannot set unsafe (%d) > latest (%d)", unsafeNum, head.Number.Uint64()) } - finalizedHeader, err := getHeader(ctx, client, "eth_getBlockByNumber", hexutil.Uint64(finalizedNum).String()) + finalizedHeader, err := getHeader(ctx, client.RPC, methodEthGetBlockByNumber, hexutil.Uint64(finalizedNum).String()) if err != nil { return fmt.Errorf("failed to get block %d to mark finalized: %w", finalizedNum, err) } - safeHeader, err := getHeader(ctx, client, "eth_getBlockByNumber", hexutil.Uint64(safeNum).String()) + safeHeader, err := getHeader(ctx, client.RPC, methodEthGetBlockByNumber, hexutil.Uint64(safeNum).String()) if err != nil { return fmt.Errorf("failed to get block %d to mark safe: %w", safeNum, err) } @@ -338,6 +384,50 @@ func SetForkchoice(ctx context.Context, client client.RPC, finalizedNum, safeNum return nil } +func SetForkchoiceByHash(ctx context.Context, client *sources.EngineAPIClient, finalized, safe, unsafe common.Hash) error { + if err := updateForkchoice(ctx, client, unsafe, safe, finalized); err != nil { + return fmt.Errorf("failed to update forkchoice: %w", err) + } + return nil +} + +func Rewind(ctx context.Context, lgr log.Logger, client *sources.EngineAPIClient, open client.RPC, to uint64, setHead bool) error { + unsafe, err := getHeader(ctx, open, methodEthGetBlockByNumber, hexutil.Uint64(to).String()) + if err != nil { + return fmt.Errorf("failed to get header %d: %w", to, err) + } + toUnsafe := eth.HeaderBlockID(unsafe) + + latest, safe, finalized, err := headSafeFinalized(ctx, open) + if err != nil { + return fmt.Errorf("failed to get current heads: %w", err) + } + + // when rewinding, don't increase unsafe/finalized tags + toSafe, toFinalized := toUnsafe, toUnsafe + if safe.Number.Uint64() < to { + toSafe = eth.HeaderBlockID(safe) + } + if finalized.Number.Uint64() < to { + toFinalized = eth.HeaderBlockID(finalized) + } + + lgr.Info("Rewinding chain", + "setHead", setHead, + "latest", eth.HeaderBlockID(latest), + "unsafe", toUnsafe, + "safe", toSafe, + "finalized", toFinalized, + ) + if setHead { + lgr.Debug("Calling "+methodDebugSetHead, "head", to) + if err := debugSetHead(ctx, open, to); err != nil { + return fmt.Errorf("failed to setHead %d: %w", to, err) + } + } + return SetForkchoiceByHash(ctx, client, toFinalized.Hash, toSafe.Hash, toUnsafe.Hash) +} + func RawJSONInteraction(ctx context.Context, client client.RPC, method string, args []string, input io.Reader, output io.Writer) error { var params []any if input != nil { diff --git a/op-wheel/engine/version_provider.go b/op-wheel/engine/version_provider.go new file mode 100644 index 000000000000..d3aaa377e1c4 --- /dev/null +++ b/op-wheel/engine/version_provider.go @@ -0,0 +1,44 @@ +package engine + +import ( + "strconv" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type StaticVersionProvider int + +func (v StaticVersionProvider) ForkchoiceUpdatedVersion(*eth.PayloadAttributes) eth.EngineAPIMethod { + switch int(v) { + case 1: + return eth.FCUV1 + case 2: + return eth.FCUV2 + case 3: + return eth.FCUV3 + default: + panic("invalid Engine API version: " + strconv.Itoa(int(v))) + } +} + +func (v StaticVersionProvider) NewPayloadVersion(uint64) eth.EngineAPIMethod { + switch int(v) { + case 1, 2: + return eth.NewPayloadV2 + case 3: + return eth.NewPayloadV3 + default: + panic("invalid Engine API version: " + strconv.Itoa(int(v))) + } +} + +func (v StaticVersionProvider) GetPayloadVersion(uint64) eth.EngineAPIMethod { + switch int(v) { + case 1, 2: + return eth.GetPayloadV2 + case 3: + return eth.GetPayloadV3 + default: + panic("invalid Engine API version: " + strconv.Itoa(int(v))) + } +} diff --git a/ops-bedrock/Dockerfile.stateviz b/ops-bedrock/Dockerfile.stateviz deleted file mode 100644 index 5aa5488169ec..000000000000 --- a/ops-bedrock/Dockerfile.stateviz +++ /dev/null @@ -1,22 +0,0 @@ -FROM golang:1.20.4-alpine3.16 as builder - -RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash - -COPY ./go.mod /app/go.mod -COPY ./go.sum /app/go.sum - -COPY ./op-bindings /app/op-bindings -COPY ./op-service /app/op-service - -WORKDIR /app/op-node -RUN go mod download -x - -COPY ./op-node /app/op-node - -RUN go build -o ./bin/stateviz ./cmd/stateviz - -FROM alpine:3.16 - -COPY --from=builder /app/op-node/bin/stateviz /usr/local/bin - -CMD ["stateviz"] diff --git a/ops-bedrock/docker-compose.yml b/ops-bedrock/docker-compose.yml index c8ea2f570775..25b1cfda8346 100644 --- a/ops-bedrock/docker-compose.yml +++ b/ops-bedrock/docker-compose.yml @@ -127,6 +127,9 @@ services: OP_PROPOSER_RESUBMISSION_TIMEOUT: "30s" OP_PROPOSER_LOG_TERMINAL: "true" OP_PROPOSER_L2OO_ADDRESS: "${L2OO_ADDRESS}" + OP_PROPOSER_GAME_FACTORY_ADDRESS: "${DGF_ADDRESS}" + OP_PROPOSER_GAME_TYPE: "${DG_TYPE}" + OP_PROPOSER_PROPOSAL_INTERVAL: "${PROPOSAL_INTERVAL}" OP_PROPOSER_PPROF_ENABLED: "true" OP_PROPOSER_METRICS_ENABLED: "true" OP_PROPOSER_ALLOW_NON_FINALIZED: "false" @@ -174,6 +177,39 @@ services: OP_BATCHER_SUB_SAFETY_MARGIN: 30 # SWS is 15, ChannelTimeout is 40 OP_BATCHER_MAX_PENDING_TX: 100 + op-challenger: + depends_on: + - op_stack_go_builder + - l1 + - l2 + - op-node + build: + context: ../ + dockerfile: ./op-challenger/Dockerfile + args: + OP_STACK_GO_BUILDER: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-stack-go:devnet + image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:devnet + environment: + OP_CHALLENGER_L1_ETH_RPC: http://l1:8545 + # Note: this will need to be updated to point to a L1 consensus node when there is one in the devnet + OP_CHALLENGER_L1_BEACON: "unset" + OP_CHALLENGER_ROLLUP_RPC: http://op-node:8545 + OP_CHALLENGER_TRACE_TYPE: cannon + OP_CHALLENGER_GAME_FACTORY_ADDRESS: ${DGF_ADDRESS} + # The devnet can't set the absolute prestate output root because the contracts are deployed in L1 genesis + # before the L2 genesis is known. + OP_CHALLENGER_UNSAFE_ALLOW_INVALID_PRESTATE: "true" + OP_CHALLENGER_DATADIR: temp/challenger-data + OP_CHALLENGER_CANNON_ROLLUP_CONFIG: ./.devnet/rollup.json + OP_CHALLENGER_CANNON_L2_GENESIS: ./.devnet/genesis-l2.json + OP_CHALLENGER_CANNON_BIN: ./cannon/bin/cannon + OP_CHALLENGER_CANNON_SERVER: ./op-program/bin/op-program + OP_CHALLENGER_CANNON_PRESTATE: ./op-program/bin/prestate.json + OP_CHALLENGER_CANNON_L2: http://l2:8545 + OP_CHALLENGER_MNEMONIC: test test test test test test test test test test test junk + OP_CHALLENGER_HD_PATH: "m/44'/60'/0'/0/4" + OP_CHALLENGER_NUM_CONFIRMATIONS: 1 + artifact-server: depends_on: - l1 @@ -184,17 +220,3 @@ services: - "${PWD}/../.devnet/:/usr/share/nginx/html/:ro" security_opt: - "no-new-privileges:true" - -# stateviz: -# build: -# context: ../ -# dockerfile: ./ops-bedrock/Dockerfile.stateviz -# command: -# - stateviz -# - -addr=0.0.0.0:8080 -# - -snapshot=/op_log/snapshot.log -# - -refresh=10s -# ports: -# - "9090:8080" -# volumes: -# - op_log:/op_log:ro diff --git a/ops-bedrock/entrypoint-l1.sh b/ops-bedrock/entrypoint-l1.sh index 4809810b573a..4468753313df 100644 --- a/ops-bedrock/entrypoint-l1.sh +++ b/ops-bedrock/entrypoint-l1.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -exu VERBOSITY=${GETH_VERBOSITY:-3} @@ -15,8 +15,8 @@ WS_PORT="${WS_PORT:-8546}" if [ ! -d "$GETH_KEYSTORE_DIR" ]; then echo "$GETH_KEYSTORE_DIR missing, running account import" echo -n "pwd" > "$GETH_DATA_DIR"/password - echo -n "$BLOCK_SIGNER_PRIVATE_KEY" | sed 's/0x//' > "$GETH_DATA_DIR"/block-signer-key - geth account import \ + echo -n "$BLOCK_SIGNER_PRIVATE_KEY" | sed 's/0x//' > "$GETH_DATA_DIR"/block-signer-key + geth account import \ --datadir="$GETH_DATA_DIR" \ --password="$GETH_DATA_DIR"/password \ "$GETH_DATA_DIR"/block-signer-key @@ -55,7 +55,6 @@ exec geth \ --nodiscover \ --maxpeers=1 \ --networkid=$CHAIN_ID \ - --triesInMemory=32 \ --unlock=$BLOCK_SIGNER_ADDRESS \ --mine \ --miner.etherbase=$BLOCK_SIGNER_ADDRESS \ diff --git a/ops-bedrock/entrypoint-l2.sh b/ops-bedrock/entrypoint-l2.sh index 58954f3731bf..8a6724564923 100644 --- a/ops-bedrock/entrypoint-l2.sh +++ b/ops-bedrock/entrypoint-l2.sh @@ -39,7 +39,7 @@ exec geth \ --syncmode=full \ --nodiscover \ --maxpeers=0 \ - --networkid=$CHAIN_ID \ + --networkid="$CHAIN_ID" \ --rpc.allow-unprotected-txs \ --authrpc.addr="0.0.0.0" \ --authrpc.port="8551" \ diff --git a/ops/check-changed/main.py b/ops/check-changed/main.py index fb3a9a458abf..8ce1a7bce9db 100644 --- a/ops/check-changed/main.py +++ b/ops/check-changed/main.py @@ -12,14 +12,16 @@ r'^\.github/\.*', r'^package\.json', r'ops/check-changed/.*', - r'^go\.mod', - r'^go\.sum', - r'ops/check-changed/.*' ] with open("../../nx.json") as file: nx_json_data = json.load(file) REBUILD_ALL_PATTERNS += nx_json_data["implicitDependencies"].keys() +GO_PATTERNS = [ + r'^go\.mod', + r'^go\.sum', +] + WHITELISTED_BRANCHES = { 'master', 'develop' @@ -55,8 +57,10 @@ def main(): - patterns = sys.argv[1].split(',') - patterns = patterns + REBUILD_ALL_PATTERNS + patterns = sys.argv[1].split(',') + REBUILD_ALL_PATTERNS + no_go_deps = os.getenv('CHECK_CHANGED_NO_GO_DEPS') + if no_go_deps is None: + patterns = patterns + GO_PATTERNS fp = os.path.realpath(__file__) monorepo_path = os.path.realpath(os.path.join(fp, '..', '..')) @@ -71,6 +75,15 @@ def main(): pr_urls = os.getenv('CIRCLE_PULL_REQUESTS', None) pr_urls = pr_urls.split(',') if pr_urls else [] + + # If we successfully extracted a PR number and did not find PRs from CIRCLE_PULL_REQUESTS, + # we are on a merge queue branch and can reconstruct the original PR URL from the PR number. + pr_number = extract_pr_number(current_branch) + if not pr_urls and pr_number is not None: + log.info('No PR URLs found but extracted branch number, constructing PR URL') + base_url = "https://github.com/ethereum-optimism/optimism/pull/" + pr_urls = [base_url + pr_number] + if len(pr_urls) == 0: log.info('Not a PR build, triggering build') exit_build() @@ -122,6 +135,15 @@ def match_path(path, patterns): return True return False +def extract_pr_number(branch_name): + # Merge queue branches are named: gh-readonly-queue/{base_branch}/pr-{number}-{sha} + match = re.search(r'/pr-(\d+)-', branch_name) + if match: + pr_number = match.group(1) + log.info('Extracted PR number: %s', pr_number) + return pr_number + else: + return None def exit_build(): sys.exit(0) diff --git a/ops/check-changed/requirements.txt b/ops/check-changed/requirements.txt index 2cd9e559bf96..943922a02a86 100644 --- a/ops/check-changed/requirements.txt +++ b/ops/check-changed/requirements.txt @@ -7,6 +7,6 @@ pycparser==2.21 PyGithub==1.57 PyJWT==2.6.0 PyNaCl==1.5.0 -requests==2.28.1 +requests==2.31.0 urllib3==1.26.18 wrapt==1.14.1 diff --git a/ops/docker/Dockerfile.packages b/ops/docker/Dockerfile.packages index e05febf6081e..a4ba78875fc3 100644 --- a/ops/docker/Dockerfile.packages +++ b/ops/docker/Dockerfile.packages @@ -57,6 +57,10 @@ RUN apt-get update && apt-get install -y \ libudev-dev \ --no-install-recommends +COPY /ops/docker/oplabs.crt /usr/local/share/ca-certificates/oplabs.crt +RUN chmod 644 /usr/local/share/ca-certificates/oplabs.crt \ + && update-ca-certificates + RUN npm install pnpm --global COPY --from=foundry /usr/local/bin/forge /usr/local/bin/forge @@ -69,7 +73,7 @@ WORKDIR /opt/optimism COPY --from=manifests /tmp/manifests ./ COPY *.json ./ -RUN pnpm install --frozen-lockfile +RUN pnpm install:ci COPY ./packages ./packages @@ -77,6 +81,8 @@ COPY .git/ ./.git COPY .gitmodules ./.gitmodules RUN git submodule update --init --recursive +COPY --from=1password/op:2 /usr/local/bin/op /usr/local/bin/op + RUN pnpm build ENTRYPOINT ["pnpm", "run"] @@ -86,10 +92,6 @@ WORKDIR /opt/optimism/packages/chain-mon # TODO keeping the rest of these here for now because they are being used # but we should really delete them we only need one image -FROM base as replica-mon -WORKDIR /opt/optimism/packages/chain-mon -CMD ["start:replica-mon"] - FROM base as balance-mon WORKDIR /opt/optimism/packages/chain-mon CMD ["start:balance-mon"] @@ -98,14 +100,26 @@ FROM base as drippie-mon WORKDIR /opt/optimism/packages/chain-mon CMD ["start:drippie-mon"] -FROM base as wd-mon +from base as fault-mon WORKDIR /opt/optimism/packages/chain-mon -CMD ["start:wd-mon"] +CMD ["start:fault-mon"] + +from base as multisig-mon +WORKDIR /opt/optimism/packages/multisig-mon +CMD ["start:multisig-mon"] + +FROM base as replica-mon +WORKDIR /opt/optimism/packages/chain-mon +CMD ["start:replica-mon"] FROM base as wallet-mon WORKDIR /opt/optimism/packages/chain-mon CMD ["start:wallet-mon"] -from base as fault-mon +FROM base as wd-mon WORKDIR /opt/optimism/packages/chain-mon -CMD ["start:fault-mon"] +CMD ["start:wd-mon"] + +FROM base as contracts-bedrock +WORKDIR /opt/optimism/packages/contracts-bedrock +CMD ["deploy"] diff --git a/ops/docker/ci-builder/Dockerfile b/ops/docker/ci-builder/Dockerfile index 38d6dacf9e70..5ef307482018 100644 --- a/ops/docker/ci-builder/Dockerfile +++ b/ops/docker/ci-builder/Dockerfile @@ -1,16 +1,20 @@ +# Copy docker buildx in order to generate the absolute prestate +# in the CI pipeline for reproducible fault proof builds +FROM --platform=linux/amd64 docker as buildx +COPY --from=docker/buildx-bin /buildx /usr/libexec/docker/cli-plugins/docker-buildx +RUN docker buildx version + FROM --platform=linux/amd64 debian:bullseye-slim as rust-build SHELL ["/bin/bash", "-c"] -WORKDIR /opt - ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ - apt-get install -y curl build-essential git clang lld curl + apt-get install -y build-essential git clang lld curl jq RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup.sh && \ chmod +x ./rustup.sh && \ - ./rustup.sh -y + sh rustup.sh -y # Install nightly toolchain RUN source $HOME/.profile && rustup update nightly @@ -20,23 +24,22 @@ RUN source $HOME/.profile && cargo install svm-rs # Only diff from upstream docker image is this clone instead # of COPY. We select a specific commit to use. -COPY ./.foundryrc ./.foundryrc -RUN git clone https://github.com/foundry-rs/foundry.git ./foundry \ - && cd foundry && git checkout $(cat ../.foundryrc) - -WORKDIR /opt/foundry +COPY ./versions.json ./versions.json +COPY ./ops/scripts/install-foundry.sh ./install-foundry.sh +RUN curl -L https://foundry.paradigm.xyz | bash RUN source $HOME/.profile && \ - cargo build --release && \ - strip /opt/foundry/target/release/forge && \ - strip /opt/foundry/target/release/cast && \ - strip /opt/foundry/target/release/anvil + ./install-foundry.sh && \ + cargo install svm-rs -FROM --platform=linux/amd64 ghcr.io/crytic/echidna/echidna:v2.0.4 as echidna-test +RUN strip /root/.foundry/bin/forge && \ + strip /root/.foundry/bin/cast && \ + strip /root/.foundry/bin/anvil && \ + strip /root/.cargo/bin/svm FROM --platform=linux/amd64 debian:bullseye-slim as go-build -RUN apt-get update && apt-get install -y curl ca-certificates +RUN apt-get update && apt-get install -y curl ca-certificates jq binutils ENV GO_VERSION=1.21.1 @@ -47,29 +50,32 @@ RUN curl -sL https://go.dev/dl/go$GO_VERSION.linux-amd64.tar.gz -o go$GO_VERSION ENV GOPATH=/go ENV PATH=/usr/local/go/bin:$GOPATH/bin:$PATH -# Install the specific version of abigen from .abigenrc -COPY ./.abigenrc ./.abigenrc -RUN go install github.com/ethereum/go-ethereum/cmd/abigen@$(cat .abigenrc) - -COPY ./.gethrc ./.gethrc -RUN go install github.com/ethereum/go-ethereum/cmd/geth@$(cat .gethrc) +# Install the specific version of abigen and geth from version control +COPY ./versions.json ./versions.json +RUN go install github.com/ethereum/go-ethereum/cmd/abigen@$(jq -r .abigen < versions.json) +RUN go install github.com/ethereum/go-ethereum/cmd/geth@$(jq -r .geth < versions.json) RUN go install gotest.tools/gotestsum@latest RUN go install github.com/vektra/mockery/v2@v2.28.1 RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.2 -FROM --platform=linux/amd64 python:3.11.4-slim-bullseye +# Strip binaries to reduce size +RUN strip /go/bin/gotestsum && \ + strip /go/bin/mockery && \ + strip /go/bin/golangci-lint && \ + strip /go/bin/abigen && \ + strip /go/bin/geth + +FROM --platform=linux/amd64 debian:bullseye-slim as base-builder ENV GOPATH=/go ENV PATH=/usr/local/go/bin:$GOPATH/bin:$PATH ENV PATH=/root/.cargo/bin:$PATH ENV DEBIAN_FRONTEND=noninteractive -# Create rust directories for copying the installation into -RUN mkdir /root/.cargo && mkdir /root/.cargo/bin && mkdir /root/.rustup - # copy the go installation, but not the module cache (cache will get stale, and would add a lot of weight) COPY --from=go-build /usr/local/go /usr/local/go + # copy tools COPY --from=go-build /go/bin/gotestsum /go/bin/gotestsum COPY --from=go-build /go/bin/mockery /go/bin/mockery @@ -77,40 +83,37 @@ COPY --from=go-build /go/bin/golangci-lint /go/bin/golangci-lint COPY --from=go-build /go/bin/abigen /usr/local/bin/abigen COPY --from=go-build /go/bin/geth /usr/local/bin/geth -# copy the rust installation, alongside the installed toolchains -COPY --from=rust-build /root/.cargo/bin /root/.cargo/bin -COPY --from=rust-build /root/.rustup /root/.rustup # copy tools -COPY --from=rust-build /opt/foundry/target/release/forge /usr/local/bin/forge -COPY --from=rust-build /opt/foundry/target/release/cast /usr/local/bin/cast -COPY --from=rust-build /opt/foundry/target/release/anvil /usr/local/bin/anvil - -COPY --from=echidna-test /usr/local/bin/echidna-test /usr/local/bin/echidna-test +COPY --from=rust-build /root/.foundry/bin/forge /usr/local/bin/forge +COPY --from=rust-build /root/.foundry/bin/cast /usr/local/bin/cast +COPY --from=rust-build /root/.foundry/bin/anvil /usr/local/bin/anvil +COPY --from=rust-build /root/.cargo/bin/svm /usr/local/bin/svm COPY .nvmrc .nvmrc +COPY ./versions.json ./versions.json ENV NODE_MAJOR=20 -ENV SLITHER_VERSION=0.10.0 -# note: python3 package in apt is python 3.9, while base image already has python 3.11 RUN /bin/sh -c set -eux; \ apt-get update; \ - apt-get install -y --no-install-recommends bash curl openssh-client git build-essential pkg-config libssl-dev clang libclang-dev ca-certificates jq gnupg binutils-mips-linux-gnu; \ + apt-get install -y --no-install-recommends bash curl openssh-client git build-essential ca-certificates jq gnupg binutils-mips-linux-gnu python3 python3-pip; \ mkdir -p /etc/apt/keyrings; \ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg; \ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list; \ + curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg; \ + chmod a+r /etc/apt/keyrings/docker.gpg; \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null; \ apt-get update; \ - apt-get install -y nodejs; \ + apt-get install -y nodejs docker-ce-cli; \ ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt; \ npm i -g depcheck; \ - pip install slither-analyzer==$SLITHER_VERSION capstone pyelftools; \ + pip install capstone pyelftools; \ curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | bash; \ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ rm -rf /var/lib/apt/lists/*; \ rm -rf /root/.cache/pip; \ rm -rf /root/.cache/npm; - RUN npm i -g pnpm && npm i -g yarn@1 && pnpm --version && yarn --version RUN svm install 0.5.17 && \ @@ -128,10 +131,27 @@ RUN echo "downloading and verifying Codecov uploader" && \ chmod +x /usr/local/bin/codecov && \ rm codecov +# Copy docker buildx +COPY --from=buildx /usr/libexec/docker/cli-plugins/docker-buildx /usr/libexec/docker/cli-plugins/docker-buildx + # within docker use bash SHELL ["/bin/bash", "-c"] + # set env to use bash ENV SHELL=/bin/bash ENV BASH=/bin/bash ENTRYPOINT ["/bin/bash", "-c"] + +FROM base-builder as rust-builder + +# Install clang & lld +RUN apt-get update && apt-get install -y clang lld + +# Copy the rust installation, alongside the installed toolchains +COPY --from=rust-build /root/.cargo /root/.cargo +COPY --from=rust-build /root/.rustup /root/.rustup + +# copy the rust installation, alongside the installed toolchains +COPY --from=rust-build /root/.cargo/bin /root/.cargo/bin +COPY --from=rust-build /root/.rustup /root/.rustup diff --git a/ops/docker/ci-builder/Dockerfile.dockerignore b/ops/docker/ci-builder/Dockerfile.dockerignore index ea0c3e144146..229d6f1165c2 100644 --- a/ops/docker/ci-builder/Dockerfile.dockerignore +++ b/ops/docker/ci-builder/Dockerfile.dockerignore @@ -1,5 +1,4 @@ * -!/.foundryrc -!/.abigenrc -!/.gethrc !/.nvmrc +!/versions.json +!/ops/scripts/install-foundry.sh diff --git a/ops/docker/op-stack-go/Dockerfile b/ops/docker/op-stack-go/Dockerfile index 7e75b3093729..c42a696c8a85 100644 --- a/ops/docker/op-stack-go/Dockerfile +++ b/ops/docker/op-stack-go/Dockerfile @@ -31,12 +31,13 @@ ARG OP_WHEEL_VERSION=v0.0.0 ARG OP_NODE_VERSION=v0.0.0 ARG OP_CHALLENGER_VERSION=v0.0.0 +ARG OP_DISPUTE_MON_VERSION=v0.0.0 ARG OP_BATCHER_VERSION=v0.0.0 ARG OP_PROPOSER_VERSION=v0.0.0 +ARG OP_CONDUCTOR_VERSION=v0.0.0 # separate docker-builds: -# - op-exporter # - op-ufm # - proxyd # - any JS/TS/smart-contract builds @@ -62,10 +63,14 @@ RUN --mount=type=cache,target=/root/.cache/go-build cd op-node && make op-node GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_NODE_VERSION" RUN --mount=type=cache,target=/root/.cache/go-build cd op-challenger && make op-challenger \ GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_CHALLENGER_VERSION" +RUN --mount=type=cache,target=/root/.cache/go-build cd op-dispute-mon && make op-dispute-mon \ + GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_DISPUTE_MON_VERSION" RUN --mount=type=cache,target=/root/.cache/go-build cd op-batcher && make op-batcher \ GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_BATCHER_VERSION" RUN --mount=type=cache,target=/root/.cache/go-build cd op-proposer && make op-proposer \ GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_PROPOSER_VERSION" +RUN --mount=type=cache,target=/root/.cache/go-build cd op-conductor && make op-conductor \ + GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_CONDUCTOR_VERSION" FROM alpine:3.18 @@ -78,7 +83,7 @@ COPY --from=builder /app/op-wheel/bin/op-wheel /usr/local/bin/ COPY --from=builder /app/op-node/bin/op-node /usr/local/bin/ COPY --from=builder /app/op-challenger/bin/op-challenger /usr/local/bin/ +COPY --from=builder /app/op-dispute-mon/bin/op-dispute-mon /usr/local/bin/ COPY --from=builder /app/op-batcher/bin/op-batcher /usr/local/bin/ COPY --from=builder /app/op-proposer/bin/op-proposer /usr/local/bin/ - - +COPY --from=builder /app/op-conductor/bin/op-conductor /usr/local/bin/ diff --git a/ops/docker/op-stack-go/Dockerfile.dockerignore b/ops/docker/op-stack-go/Dockerfile.dockerignore index 7ff25b323884..d131d2c3b0c2 100644 --- a/ops/docker/op-stack-go/Dockerfile.dockerignore +++ b/ops/docker/op-stack-go/Dockerfile.dockerignore @@ -8,6 +8,8 @@ !/op-bootnode !/op-chain-ops !/op-challenger +!/op-dispute-mon +!/op-conductor !/op-heartbeat !/op-node !/op-preimage @@ -15,6 +17,7 @@ !/op-proposer !/op-service !/op-wheel +!/op-plasma !/go.mod !/go.sum !/op-aws-sdk diff --git a/ops/docker/oplabs.crt b/ops/docker/oplabs.crt new file mode 100644 index 000000000000..196af66746e8 --- /dev/null +++ b/ops/docker/oplabs.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICEDCCAZagAwIBAgIUALLKhe49OFLAGb5Zt+DZlvpKScswCgYIKoZIzj0EAwMw +KTEQMA4GA1UEChMHT1AgTGFiczEVMBMGA1UEAxMMb3BsYWJzLmNsb3VkMB4XDTIy +MTIxOTE3MDQwNFoXDTMyMTIxNjE3MDQwM1owKTEQMA4GA1UEChMHT1AgTGFiczEV +MBMGA1UEAxMMb3BsYWJzLmNsb3VkMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEyCco +PpvE5IRv5S0zqmpE2VsbhVzB+hiQjbQO3J6j5L+pAvWjXGvjZblGvNi5PIVBCxvm +5UofdFrOCAiOdRfevhadv3zLzGUmoJ52iXCTPL01dlkQt5KUsoT+AU7GPW4Ko38w +fTAOBgNVHQ8BAf8EBAMCAaYwEgYDVR0TAQH/BAgwBgEB/wIBCjAdBgNVHQ4EFgQU +2AVLbBUBZcBOPkg8QCAOvSMrdj0wHwYDVR0jBBgwFoAU2AVLbBUBZcBOPkg8QCAO +vSMrdj0wFwYDVR0RBBAwDoIMb3BsYWJzLmNsb3VkMAoGCCqGSM49BAMDA2gAMGUC +MBuERHbRkWDwXm97jqKEGANU4VDBqgmRicdF7FspDqA5Zcpj+r+rQVaDlH0qvtxH +SQIxAL3fjNoC1Kon4kKmPQdp5KNhvGzOaoQiqbb5JuL3+j6f3x0ucLVD1yWP/V/+ +zZ/vlQ== +-----END CERTIFICATE----- diff --git a/ops/scripts/ci-docker-tag-op-stack-release.sh b/ops/scripts/ci-docker-tag-op-stack-release.sh index 040c76134fb7..62cf4b319dbd 100755 --- a/ops/scripts/ci-docker-tag-op-stack-release.sh +++ b/ops/scripts/ci-docker-tag-op-stack-release.sh @@ -6,7 +6,7 @@ DOCKER_REPO=$1 GIT_TAG=$2 GIT_SHA=$3 -IMAGE_NAME=$(echo "$GIT_TAG" | grep -Eow '^(ci-builder|proxyd|indexer|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)' || true) +IMAGE_NAME=$(echo "$GIT_TAG" | grep -Eow '^(ci-builder(-rust)?|chain-mon|proxyd|indexer|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)' || true) if [ -z "$IMAGE_NAME" ]; then echo "image name could not be parsed from git tag '$GIT_TAG'" exit 1 diff --git a/ops/scripts/find_release_tag.sh b/ops/scripts/find_release_tag.sh new file mode 100755 index 000000000000..9307dd2ac036 --- /dev/null +++ b/ops/scripts/find_release_tag.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +set -euo pipefail + +# Function to print usage +usage() { + echo "Usage: $0 [tag-prefix]" + echo " : The commit hash to check." + echo " [tag-prefix] : Optional. The prefix for tags to check. Default is 'op-node'." +} + +# Check for at least one argument +if [ "$#" -lt 1 ]; then + usage + exit 1 +fi + +commit_hash=$1 +tag_prefix=${2:-"op-node"} # Default tag prefix is "op-node" + +# Get all tags containing the commit, sorted by creation date +tags=$(git tag --contains "$commit_hash" --sort=taggerdate) + +# Find the first release tag with the given prefix +for tag in $tags; do + if [[ $tag == $tag_prefix/v* ]]; then + echo "First release tag containing commit $commit_hash: $tag" + exit 0 + fi +done + +echo "Commit $commit_hash is not in any $tag_prefix/v* release tag." diff --git a/ops/scripts/geth-version-checker.sh b/ops/scripts/geth-version-checker.sh index 22bf1d37b1b6..98d94e664136 100755 --- a/ops/scripts/geth-version-checker.sh +++ b/ops/scripts/geth-version-checker.sh @@ -1,23 +1,28 @@ #!/bin/bash +SCRIPTS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +MONOREPO_DIR=$(cd "$SCRIPTS_DIR/../../" && pwd) + # Extract the version from the geth command output GETH_VERSION="v$(geth version | grep '^Version:' | awk '{print $2}')" -# Read the version from the .gethrc file -GETHRC_VERSION=$(cat .gethrc) +# Read the version from the versions file +EXPECTED_GETH_VERSION=$(jq -r .geth < "$MONOREPO_DIR"/versions.json) -# Check if GETHRC_VERSION contains a '-'. If not, append '-stable'. -if [[ $GETHRC_VERSION != *-* ]]; then - GETHRC_VERSION="${GETHRC_VERSION}-stable" +# Check if EXPECTED_GETH_VERSION contains a '-'. If not, append '-stable'. +if [[ $EXPECTED_GETH_VERSION != *-* ]]; then + EXPECTED_GETH_VERSION="${EXPECTED_GETH_VERSION}-stable" fi # Compare the versions -if [[ "$GETH_VERSION" == "$GETHRC_VERSION" ]]; then +if [[ "$GETH_VERSION" == "$EXPECTED_GETH_VERSION" ]]; then echo "Geth version $GETH_VERSION is correct!" exit 0 else echo "Geth version does not match!" - echo "geth version: $GETH_VERSION" - echo ".gethrc version: $GETHRC_VERSION" + echo "Local geth version: $GETH_VERSION" + echo "Expected geth version: $EXPECTED_GETH_VERSION" exit 1 fi + + diff --git a/ops/scripts/install-foundry.sh b/ops/scripts/install-foundry.sh new file mode 100755 index 000000000000..5f1fc577e3b0 --- /dev/null +++ b/ops/scripts/install-foundry.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +SCRIPTS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +MONOREPO_DIR=$(cd "$SCRIPTS_DIR/../../" && pwd) + +# Grab the foundry commit hash. +SHA=$(jq -r .foundry < "$MONOREPO_DIR"/versions.json) + +# Check if there is a nightly tag corresponding to the commit hash +TAG="nightly-$SHA" + +# If the foundry repository exists and a branch is checked out, we need to abort +# any changes inside ~/.foundry/foundry-rs/foundry. This is because foundryup will +# attempt to pull the latest changes from the remote repository, which will fail +# if there are any uncommitted changes. +if [ -d ~/.foundry/foundry-rs/foundry ]; then + echo "Foundry repository exists! Aborting any changes..." + cd ~/.foundry/foundry-rs/foundry + git reset --hard + git clean -fd + cd - +fi + +# Create a temporary directory +TMP_DIR=$(mktemp -d) +echo "Created tempdir @ $TMP_DIR" + +# Clone the foundry repo temporarily. We do this to avoid the need for a personal access +# token to interact with the GitHub REST API, and clean it up after we're done. +git clone https://github.com/foundry-rs/foundry.git "$TMP_DIR" && cd "$TMP_DIR" + +# If the nightly tag exists, we can download the pre-built binaries rather than building +# from source. Otherwise, clone the repository, check out the commit SHA, and build `forge`, +# `cast`, `anvil`, and `chisel` from source. +if git rev-parse "$TAG" >/dev/null 2>&1; then + echo "Nightly tag exists! Downloading prebuilt binaries..." + foundryup -v "$TAG" +else + echo "Nightly tag doesn't exist! Building from source..." + foundryup -C "$SHA" +fi + +# Remove the temporary foundry repo; Used just for checking the nightly tag's existence. +rm -rf "$TMP_DIR" +echo "Removed tempdir @ $TMP_DIR" + + diff --git a/ops/scripts/newer-file.sh b/ops/scripts/newer-file.sh index c2bf7f69594a..e61224c6aaa9 100755 --- a/ops/scripts/newer-file.sh +++ b/ops/scripts/newer-file.sh @@ -12,8 +12,8 @@ else MOD_TIME_FMT="-c %Y" fi -FILE_1_AGE=$(stat $MOD_TIME_FMT "$1") -FILE_2_AGE=$(stat $MOD_TIME_FMT "$2") +FILE_1_AGE=$(stat "$MOD_TIME_FMT" "$1") +FILE_2_AGE=$(stat "$MOD_TIME_FMT" "$2") if [ "$FILE_1_AGE" -gt "$FILE_2_AGE" ]; then exit 0 diff --git a/ops/scripts/todo-checker.sh b/ops/scripts/todo-checker.sh index 621cf2ca811a..d90d97fc47c9 100755 --- a/ops/scripts/todo-checker.sh +++ b/ops/scripts/todo-checker.sh @@ -50,15 +50,15 @@ for arg in "$@"; do done # Use ripgrep to search for the pattern in all files within the repo -todos=$(rg -o --with-filename -n -g '!ops/scripts/todo-checker.sh' 'TODO\(([^)]+)\): [^,;]*') +todos=$(rg -o --with-filename -i -n -g '!ops/scripts/todo-checker.sh' 'TODO\(([^)]+)\): [^,;]*') # Check each TODO comment in the repo IFS=$'\n' # Set Internal Field Separator to newline for iteration for todo in $todos; do # Extract the text inside the parenthesis - FILE=$(echo $todo | awk -F':' '{print $1}') - LINE_NUM=$(echo $todo | awk -F':' '{print $2}') - ISSUE_REFERENCE=$(echo $todo | sed -n 's/.*TODO(\([^)]*\)).*/\1/p') + FILE=$(echo "$todo" | awk -F':' '{print $1}') + LINE_NUM=$(echo "$todo" | awk -F':' '{print $2}') + ISSUE_REFERENCE=$(echo "$todo" | sed -n 's/.*TODO(\([^)]*\)).*/\1/p') # Parse the format of the TODO comment. There are 3 supported formats: # * TODO(): (Default org & repo: "ethereum-optimism/monorepo") diff --git a/ops/tag-service/README.md b/ops/tag-service/README.md new file mode 100644 index 000000000000..b1fdc89f47b8 --- /dev/null +++ b/ops/tag-service/README.md @@ -0,0 +1,21 @@ +# Tag Service +Tag Service is a Github action which builds new tags and applies them to services in the monorepo. +It accepts: +* Service name +* Bump Amount [major, minor, patch] +* Prerelease and Finalize-Prerelease (to add/remove `rc` versions) + +It can be triggered from the Github Actions panel in the monorepo + +# Tag Tool +Tag Tool is a minimal rewrite of the Tag Service to let operators prepare and commit tags from commandline +It accepts: +* Service name +* Bump Amount [major, minor, patch, prerelease, finalize-prerelease] + +Tag Tool is meant to be run locally, and *does not* perform any write operations. Instead, it prints the git commands to console for the operator to use. + +Additionally, a special service name "op-stack" is available, which will bump versions for `op-node`, `op-batcher` and `op-proposer` from the highest semver amongst them. + +To run Tag Tool locally, the only dependency is `pip install semver` + diff --git a/ops/tag-service/tag-service.py b/ops/tag-service/tag-service.py index 37d875e6abbc..b88a03ad1292 100755 --- a/ops/tag-service/tag-service.py +++ b/ops/tag-service/tag-service.py @@ -11,16 +11,20 @@ # Minimum version numbers for packages migrating from legacy versioning. MIN_VERSIONS = { 'ci-builder': '0.6.0', + 'ci-builder-rust': '0.1.0', 'chain-mon': '0.2.2', 'indexer': '0.5.0', 'op-node': '0.10.14', 'op-batcher': '0.10.14', 'op-challenger': '0.0.4', + 'op-program': '0.0.0', + 'op-dispute-mon': '0.0.0', 'op-proposer': '0.10.14', 'op-ufm': '0.1.0', 'proxyd': '3.16.0', 'op-heartbeat': '0.1.0', 'ufm-metamask': '0.1.0', + 'op-contracts': '1.0.0', } VALID_BUMPS = ('major', 'minor', 'patch', 'prerelease', 'finalize-prerelease') diff --git a/ops/tag-service/tag-tool.py b/ops/tag-service/tag-tool.py new file mode 100644 index 000000000000..ddab04e00a4f --- /dev/null +++ b/ops/tag-service/tag-tool.py @@ -0,0 +1,94 @@ +import argparse +import subprocess +import re +import semver + +SERVICES = [ + 'ci-builder', + 'ci-builder-rust', + 'chain-mon', + 'indexer', + 'op-node', + 'op-batcher', + 'op-challenger', + 'op-dispute-mon', + 'op-proposer', + 'op-ufm', + 'proxyd', + 'op-heartbeat', + 'ufm-metamask', + 'op-contracts', + 'test', + 'op-stack', # special case for tagging op-node, op-batcher, and op-proposer together +] +VERSION_PATTERN = '^{service}/v\\d+\\.\\d+\\.\\d+(-rc\\.\\d+)?$' +GIT_TAG_COMMAND = 'git tag -a {tag} -m "{message}"' +GIT_PUSH_COMMAND = 'git push origin {tag}' + +def new_tag(service, version, bump): + if bump == 'major': + bumped = version.bump_major() + elif bump == 'minor': + bumped = version.bump_minor() + elif bump == 'patch': + bumped = version.bump_patch() + elif bump == 'prerelease': + bumped = version.bump_prerelease() + elif bump == 'finalize-prerelease': + bumped = version.finalize_version() + else: + raise Exception('Invalid bump type: {}'.format(bump)) + return f'{service}/v{bumped}' + +def latest_version(service): + # Get the list of tags from the git repository. + tags = subprocess.run(['git', 'tag', '--list', f'{service}/v*'], capture_output=True, check=True) \ + .stdout.decode('utf-8').splitlines() + # Filter out tags that don't match the service name, and tags for prerelease versions. + svc_versions = sorted([t.replace(f'{service}/v', '') for t in tags]) + if len(svc_versions) == 0: + raise Exception(f'No tags found for service: {service}') + return svc_versions[-1] + +def latest_among_services(services): + latest = '0.0.0' + for service in services: + candidate = latest_version(service) + if semver.compare(candidate, latest) > 0: + latest = candidate + return latest + +def main(): + parser = argparse.ArgumentParser(description='Create a new git tag for a service') + parser.add_argument('--service', type=str, help='The name of the Service') + parser.add_argument('--bump', type=str, help='The type of bump to apply to the version number') + parser.add_argument('--message', type=str, help='Message to include in git tag', default='[tag-tool-release]') + args = parser.parse_args() + + service = args.service + + if service == 'op-stack': + latest = latest_among_services(['op-node', 'op-batcher', 'op-proposer']) + else: + latest = latest_version(service) + + bumped = new_tag(service, semver.VersionInfo.parse(latest), args.bump) + + print(f'latest tag: {latest}') + print(f'new tag: {bumped}') + print('run the following commands to create the new tag:\n') + # special case for tagging op-node, op-batcher, and op-proposer together. All three would share the same semver + if args.service == 'op-stack': + print(GIT_TAG_COMMAND.format(tag=bumped.replace('op-stack', 'op-node'), message=args.message)) + print(GIT_PUSH_COMMAND.format(tag=bumped.replace('op-stack', 'op-node'))) + print(GIT_TAG_COMMAND.format(tag=bumped.replace('op-stack', 'op-batcher'), message=args.message)) + print(GIT_PUSH_COMMAND.format(tag=bumped.replace('op-stack', 'op-batcher'))) + print(GIT_TAG_COMMAND.format(tag=bumped.replace('op-stack', 'op-proposer'), message=args.message)) + print(GIT_PUSH_COMMAND.format(tag=bumped.replace('op-stack', 'op-proposer'))) + else: + print(GIT_TAG_COMMAND.format(tag=bumped, message=args.message)) + print(GIT_PUSH_COMMAND.format(tag=bumped)) + +if __name__ == "__main__": + main() + diff --git a/package.json b/package.json index 9a94eb9d18ff..f3cf78bca9d2 100644 --- a/package.json +++ b/package.json @@ -14,16 +14,15 @@ "build": "npx nx run-many --target=build", "test": "npx nx run-many --target=test", "issues": "./ops/scripts/todo-checker.sh", + "install:ci": "pnpm install --ignore-scripts --frozen-lockfile && pnpm rebuild nx", + "install:ci:offline": "pnpm install --ignore-scripts --offline --frozen-lockfile && pnpm rebuild nx", "lint": "npx nx run-many --target=lint", "test:coverage": "npx nx run-many --target=test:coverage", "lint:ts:check": "npx nx run-many --target=lint:ts:check", "lint:check": "npx nx run-many --target=lint:check", "lint:fix": "npx nx run-many --target=lint:fix", - "lint:specs:fix": "npx markdownlint-cli2-fix \"./specs/**/*.md\"", - "lint:specs:check": "npx markdownlint-cli2 \"./specs/**/*.md\"", - "lint:specs:toc": "npx doctoc '--title=**Table of Contents**' ./specs", + "lint:shellcheck": "find . -type f -name '*.sh' -not -path '*/node_modules/*' -not -path './packages/contracts-bedrock/lib/*' -not -path './packages/contracts-bedrock/kout*/*' -not -path './.husky/_/husky.sh' -exec sh -c 'echo \"Checking $1\"; shellcheck \"$1\"' _ {} \\;", "preinstall": "npx only-allow pnpm", - "postinstall": "patch-package", "ready": "pnpm lint && pnpm test", "prepare": "husky install", "release": "npx nx run-many --target=build --skip-nx-cache && pnpm changeset publish", @@ -31,52 +30,54 @@ "release:publish": "pnpm install --frozen-lockfile && npx nx run-many --target=build && pnpm build && changeset publish", "release:version": "changeset version && pnpm install --lockfile-only", "install:foundry": "curl -L https://foundry.paradigm.xyz | bash && pnpm update:foundry", - "update:foundry": "foundryup -C $(cat .foundryrc)", - "install:abigen": "go install github.com/ethereum/go-ethereum/cmd/abigen@$(cat .abigenrc)", + "update:foundry": "bash ./ops/scripts/install-foundry.sh", + "check:foundry": "bash ./packages/contracts-bedrock/scripts/checks/check-foundry-install.sh", + "install:kontrol": "curl -L https://kframework.org/install | bash && pnpm update:kontrol", + "update:kontrol": "kup install kontrol --version v$(jq -r .kontrol < versions.json)", + "install:abigen": "go install github.com/ethereum/go-ethereum/cmd/abigen@$(jq -r .abigen < versions.json)", "print:abigen": "abigen --version | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' -e 's/ /./g' -e 's/^/v/'", - "check:abigen": "[[ $(abigen --version | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' -e 's/ /./g' -e 's/^/v/') = $(cat .abigenrc) ]] && echo '✓ abigen versions match' || (echo '✗ abigen version mismatch. Run `pnpm upgrade:abigen` to upgrade.' && exit 1)", - "upgrade:abigen": "abigen --version | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' -e 's/ /./g' -e 's/^/v/' > .abigenrc" + "check:abigen": "[[ $(pnpm -s print:abigen) = $(cat versions.json | jq -r '.abigen') ]] && echo '✓ abigen versions match' || (echo '✗ abigen version mismatch. Run `pnpm upgrade:abigen` to upgrade.' && exit 1)", + "upgrade:abigen": "jq '.abigen = $v' --arg v $(pnpm -s print:abigen) <<<$(cat versions.json) > versions.json", + "install:slither": "pip3 install slither-analyzer==$(jq -r .slither < versions.json)", + "print:slither": "slither --version", + "check:slither": "[[ $(pnpm -s print:slither) = $(jq -r .slither < versions.json) ]] && echo '✓ slither versions match' || (echo '✗ slither version mismatch. Run `pnpm upgrade:slither` to upgrade.' && exit 1)", + "upgrade:slither": "jq '.slither = $v' --arg v $(pnpm -s print:slither) <<<$(cat versions.json) > versions.json" }, "devDependencies": { - "@babel/eslint-parser": "^7.18.2", + "@babel/eslint-parser": "^7.23.10", "@changesets/changelog-github": "^0.4.8", - "@types/chai": "^4.3.8", - "@types/chai-as-promised": "^7.1.4", - "@types/mocha": "^10.0.3", - "@types/node": "^20.8.9", - "@typescript-eslint/eslint-plugin": "^6.9.0", - "@typescript-eslint/parser": "^6.9.0", + "@types/chai": "^4.3.11", + "@types/chai-as-promised": "^7.1.8", + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.17", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "chai": "^4.3.10", "depcheck": "^1.4.7", "doctoc": "^2.2.0", - "eslint": "^8.52.0", - "eslint-config-prettier": "^8.3.0", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.29.0", - "eslint-plugin-jsdoc": "^35.1.2", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsdoc": "^48.0.6", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prefer-arrow": "^1.2.3", "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-promise": "^5.1.0", "eslint-plugin-react": "^7.24.0", - "eslint-plugin-unicorn": "^48.0.1", - "husky": "^8.0.3", - "lint-staged": "15.0.2", - "markdownlint": "^0.31.0", - "markdownlint-cli2": "0.4.0", + "eslint-plugin-unicorn": "^50.0.1", + "husky": "^9.0.10", + "lint-staged": "15.2.0", "mocha": "^10.2.0", - "nx": "17.0.2", + "nx": "18.1.2", "nyc": "^15.1.0", - "patch-package": "^8.0.0", "prettier": "^2.8.0", - "prettier-plugin-solidity": "^1.0.0-beta.13", "rimraf": "^5.0.5", "ts-mocha": "^10.0.0", - "typescript": "^5.2.2", + "typescript": "^5.3.3", "nx-cloud": "latest" }, "dependencies": { - "@changesets/cli": "^2.26.0", - "@codechecks/client": "^0.1.11" + "@changesets/cli": "^2.27.1" } } diff --git a/packages/chain-mon/.env.example b/packages/chain-mon/.env.example index 3e952b04ca07..0e10b0aaf530 100644 --- a/packages/chain-mon/.env.example +++ b/packages/chain-mon/.env.example @@ -8,6 +8,18 @@ BALANCE_MON__RPC= # JSON array in the format [{ "address":
, "nickname": }, ... ] BALANCE_MON__ACCOUNTS= + +############################################################################### +# ↓ multisig-mon ↓ # +############################################################################### + +# RPC pointing to network to monitor safe nonces on +MULTISIG_MON__RPC= + +# JSON array in the format [{ "address":
, "nickname": }, ... ] +MULTISIG_MON__ACCOUNTS= + + ############################################################################### # ↓ wallet-mon ↓ # ############################################################################### @@ -51,6 +63,20 @@ FAULT_DETECTOR__L2_RPC_PROVIDER= # --bedrock Whether or not the service is running against a Bedrock chain (env: FAULT_DETECTOR__BEDROCK) BEDROCK=true +############################################################################### +# ↓ initialized-upgraded-mon ↓ # +############################################################################### + +# RPC pointing to network to monitor +INITIALIZED_UPGRADED_MON__RPC= + +# The block number to start monitoring from +# Defaults to the first bedrock block if unset. +INITIALIZED_UPGRADED_MON__START_BLOCK_NUMBER= + +# JSON array in the format [{ "label": , "address":
}, ... ] +INITIALIZED_UPGRADED_MON__CONTRACTS= + # Optional Params # --startbatchindex Batch index to start checking from. For bedrock chains, this is the L2 height to start from (env: FAULT_DETECTOR__START_BATCH_INDEX) diff --git a/packages/chain-mon/CHANGELOG.md b/packages/chain-mon/CHANGELOG.md index 7d989cd321f0..fd80a56235f0 100644 --- a/packages/chain-mon/CHANGELOG.md +++ b/packages/chain-mon/CHANGELOG.md @@ -1,5 +1,66 @@ # @eth-optimism/drippie-mon +## 0.6.2 + +### Patch Changes + +- Updated dependencies [[`3ccd12fe5c8c4c5a6acbf370d474ffa8db816562`](https://github.com/ethereum-optimism/optimism/commit/3ccd12fe5c8c4c5a6acbf370d474ffa8db816562)]: + - @eth-optimism/sdk@3.2.2 + +## 0.6.1 + +### Patch Changes + +- Updated dependencies [[`a1329f21f33ecafe409990964d3af7bf05a8a756`](https://github.com/ethereum-optimism/optimism/commit/a1329f21f33ecafe409990964d3af7bf05a8a756)]: + - @eth-optimism/sdk@3.2.1 + +## 0.6.0 + +### Minor Changes + +- [#9334](https://github.com/ethereum-optimism/optimism/pull/9334) [`1ed50c44a5c4fb7244ede3b4c45ea7bbf144c1e5`](https://github.com/ethereum-optimism/optimism/commit/1ed50c44a5c4fb7244ede3b4c45ea7bbf144c1e5) Thanks [@smartcontracts](https://github.com/smartcontracts)! - Updates wd-mon inside chain-mon to support FPAC. + +### Patch Changes + +- Updated dependencies [[`1ed50c44a5c4fb7244ede3b4c45ea7bbf144c1e5`](https://github.com/ethereum-optimism/optimism/commit/1ed50c44a5c4fb7244ede3b4c45ea7bbf144c1e5), [`d99d425a4f73fba19ffcf180deb0ef48ff3b9a6a`](https://github.com/ethereum-optimism/optimism/commit/d99d425a4f73fba19ffcf180deb0ef48ff3b9a6a), [`79effc52e8b82d15b5eda43acf540ac6c5f8d5d7`](https://github.com/ethereum-optimism/optimism/commit/79effc52e8b82d15b5eda43acf540ac6c5f8d5d7), [`73a748575e7c3d67c293814a12bf41eee216163c`](https://github.com/ethereum-optimism/optimism/commit/73a748575e7c3d67c293814a12bf41eee216163c), [`44a2d9cec5f3b309b723b3e4dd8d29b5b70f1cc8`](https://github.com/ethereum-optimism/optimism/commit/44a2d9cec5f3b309b723b3e4dd8d29b5b70f1cc8)]: + - @eth-optimism/common-ts@0.8.8 + - @eth-optimism/sdk@3.2.0 + - @eth-optimism/contracts-bedrock@0.17.1 + +## 0.5.7 + +### Patch Changes + +- Updated dependencies [[`18becd7e4`](https://github.com/ethereum-optimism/optimism/commit/18becd7e457577c105f6bc03597e069334cb7433)]: + - @eth-optimism/sdk@3.1.8 + +## 0.5.6 + +### Patch Changes + +- Updated dependencies [[`6ec80fd19`](https://github.com/ethereum-optimism/optimism/commit/6ec80fd19d9155b17a0873672fb095d323f6e8fb)]: + - @eth-optimism/sdk@3.1.7 + +## 0.5.5 + +### Patch Changes + +- [#8306](https://github.com/ethereum-optimism/optimism/pull/8306) [`dcb252917`](https://github.com/ethereum-optimism/optimism/commit/dcb25291768ec0f2386486619971d5cd66fbb409) Thanks [@protolambda](https://github.com/protolambda)! - Fixed bug with custom chains not being able to set a custom portal address + +## 0.5.4 + +### Patch Changes + +- Updated dependencies [[`dd0e46986`](https://github.com/ethereum-optimism/optimism/commit/dd0e46986f19dcceb304fc48f2bd410685ecd179)]: + - @eth-optimism/sdk@3.1.6 + +## 0.5.3 + +### Patch Changes + +- Updated dependencies [[`2534eabb5`](https://github.com/ethereum-optimism/optimism/commit/2534eabb50afe76f176407f83cc1f1c606e6de69)]: + - @eth-optimism/sdk@3.1.5 + ## 0.5.2 ### Patch Changes diff --git a/packages/chain-mon/package.json b/packages/chain-mon/package.json index dcd3f4ad8965..540aaf3f7916 100644 --- a/packages/chain-mon/package.json +++ b/packages/chain-mon/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@eth-optimism/chain-mon", - "version": "0.5.2", + "version": "0.6.2", "description": "[Optimism] Chain monitoring services", "main": "dist/index", "types": "dist/index", @@ -10,22 +10,25 @@ ], "scripts": { "dev:balance-mon": "tsx watch ./src/balance-mon/service.ts", - "dev:wallet-mon": "tsx watch ./src/wallet-mon/service.ts", "dev:drippie-mon": "tsx watch ./src/drippie-mon/service.ts", - "dev:wd-mon": "tsx watch ./src/wd-mon/service.ts", "dev:fault-mon": "tsx watch ./src/fault-mon/service.ts", + "dev:multisig-mon": "tsx watch ./src/multisig-mon/service.ts", "dev:replica-mon": "tsx watch ./src/replica-mon/service.ts", + "dev:wallet-mon": "tsx watch ./src/wallet-mon/service.ts", + "dev:wd-mon": "tsx watch ./src/wd-mon/service.ts", + "dev:initialized-upgraded-mon": "tsx watch ./src/initialized-upgraded-mon/service.ts", "start:balance-mon": "tsx ./src/balance-mon/service.ts", - "start:wallet-mon": "tsx ./src/wallet-mon/service.ts", "start:drippie-mon": "tsx ./src/drippie-mon/service.ts", - "start:wd-mon": "tsx ./src/wd-mon/service.ts", "start:fault-mon": "tsx ./src/fault-mon/service.ts", + "start:multisig-mon": "tsx ./src/multisig-mon/service.ts", "start:replica-mon": "tsx ./src/replica-mon/service.ts", + "start:wallet-mon": "tsx ./src/wallet-mon/service.ts", + "start:wd-mon": "tsx ./src/wd-mon/service.ts", + "start:initialized-upgraded-mon": "tsx ./src/initialized-upgraded-mon/service.ts", "test": "hardhat test", "test:coverage": "nyc hardhat test && nyc merge .nyc_output coverage.json", "build": "tsc -p ./tsconfig.json", "clean": "rimraf dist/ ./tsconfig.tsbuildinfo", - "preinstall": "npx only-allow pnpm", "lint": "pnpm lint:fix && pnpm lint:check", "pre-commit": "lint-staged", "lint:fix": "pnpm lint:check --fix", @@ -52,15 +55,15 @@ "@types/dateformat": "^5.0.0", "chai-as-promised": "^7.1.1", "dateformat": "^4.5.1", - "dotenv": "^16.3.1", + "dotenv": "^16.4.5", "ethers": "^5.7.2" }, "devDependencies": { "@ethersproject/abstract-provider": "^5.7.0", "@nomiclabs/hardhat-ethers": "^2.2.3", "@nomiclabs/hardhat-waffle": "^2.0.6", - "hardhat": "^2.18.3", - "ts-node": "^10.9.1", - "tsx": "^3.14.0" + "hardhat": "^2.20.1", + "ts-node": "^10.9.2", + "tsx": "^4.7.0" } -} +} \ No newline at end of file diff --git a/packages/chain-mon/src/abi/IGnosisSafe.0.8.19.json b/packages/chain-mon/src/abi/IGnosisSafe.0.8.19.json new file mode 100644 index 000000000000..2153157f3871 --- /dev/null +++ b/packages/chain-mon/src/abi/IGnosisSafe.0.8.19.json @@ -0,0 +1,6991 @@ +{ + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "AddedOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "approvedHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "ApproveHash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "handler", + "type": "address" + } + ], + "name": "ChangedFallbackHandler", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "guard", + "type": "address" + } + ], + "name": "ChangedGuard", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + } + ], + "name": "ChangedThreshold", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "name": "DisabledModule", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "name": "EnabledModule", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "payment", + "type": "uint256" + } + ], + "name": "ExecutionFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "name": "ExecutionFromModuleFailure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "name": "ExecutionFromModuleSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "payment", + "type": "uint256" + } + ], + "name": "ExecutionSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "RemovedOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "owners", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "initializer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "fallbackHandler", + "type": "address" + } + ], + "name": "SafeSetup", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + } + ], + "name": "SignMsg", + "type": "event" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_threshold", + "type": "uint256" + } + ], + "name": "addOwnerWithThreshold", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hashToApprove", + "type": "bytes32" + } + ], + "name": "approveHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "approvedHashes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_threshold", + "type": "uint256" + } + ], + "name": "changeThreshold", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "dataHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signatures", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "requiredSignatures", + "type": "uint256" + } + ], + "name": "checkNSignatures", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "dataHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signatures", + "type": "bytes" + } + ], + "name": "checkSignatures", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "prevModule", + "type": "address" + }, + { + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "name": "disableModule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "domainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "name": "enableModule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "safeTxGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gasToken", + "type": "address" + }, + { + "internalType": "address", + "name": "refundReceiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "encodeTransactionData", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "safeTxGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gasToken", + "type": "address" + }, + { + "internalType": "address", + "name": "refundReceiver", + "type": "address" + }, + { + "internalType": "bytes", + "name": "signatures", + "type": "bytes" + } + ], + "name": "execTransaction", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + } + ], + "name": "execTransactionFromModule", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + } + ], + "name": "execTransactionFromModuleReturnData", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getChainId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "start", + "type": "address" + }, + { + "internalType": "uint256", + "name": "pageSize", + "type": "uint256" + } + ], + "name": "getModulesPaginated", + "outputs": [ + { + "internalType": "address[]", + "name": "array", + "type": "address[]" + }, + { + "internalType": "address", + "name": "next", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwners", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + } + ], + "name": "getStorageAt", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "safeTxGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gasToken", + "type": "address" + }, + { + "internalType": "address", + "name": "refundReceiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "getTransactionHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "name": "isModuleEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "isOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "prevOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_threshold", + "type": "uint256" + } + ], + "name": "removeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + } + ], + "name": "requiredTxGas", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "handler", + "type": "address" + } + ], + "name": "setFallbackHandler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guard", + "type": "address" + } + ], + "name": "setGuard", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_owners", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "_threshold", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "address", + "name": "fallbackHandler", + "type": "address" + }, + { + "internalType": "address", + "name": "paymentToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "payment", + "type": "uint256" + }, + { + "internalType": "address", + "name": "paymentReceiver", + "type": "address" + } + ], + "name": "setup", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "signedMessages", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "targetContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "calldataPayload", + "type": "bytes" + } + ], + "name": "simulateAndRevert", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "prevOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "swapOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": { + "object": "0x", + "sourceMap": "", + "linkReferences": {} + }, + "deployedBytecode": { + "object": "0x", + "sourceMap": "", + "linkReferences": {} + }, + "methodIdentifiers": { + "VERSION()": "ffa1ad74", + "addOwnerWithThreshold(address,uint256)": "0d582f13", + "approveHash(bytes32)": "d4d9bdcd", + "approvedHashes(address,bytes32)": "7d832974", + "changeThreshold(uint256)": "694e80c3", + "checkNSignatures(bytes32,bytes,bytes,uint256)": "12fb68e0", + "checkSignatures(bytes32,bytes,bytes)": "934f3a11", + "disableModule(address,address)": "e009cfde", + "domainSeparator()": "f698da25", + "enableModule(address)": "610b5925", + "encodeTransactionData(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,uint256)": "e86637db", + "execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)": "6a761202", + "execTransactionFromModule(address,uint256,bytes,uint8)": "468721a7", + "execTransactionFromModuleReturnData(address,uint256,bytes,uint8)": "5229073f", + "getChainId()": "3408e470", + "getModulesPaginated(address,uint256)": "cc2f8452", + "getOwners()": "a0e67e2b", + "getStorageAt(uint256,uint256)": "5624b25b", + "getThreshold()": "e75235b8", + "getTransactionHash(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,uint256)": "d8d11f78", + "isModuleEnabled(address)": "2d9ad53d", + "isOwner(address)": "2f54bf6e", + "nonce()": "affed0e0", + "removeOwner(address,address,uint256)": "f8dc5dd9", + "requiredTxGas(address,uint256,bytes,uint8)": "c4ca3a9c", + "setFallbackHandler(address)": "f08a0323", + "setGuard(address)": "e19a9dd9", + "setup(address[],uint256,address,bytes,address,address,uint256,address)": "b63e800d", + "signedMessages(bytes32)": "5ae6bd37", + "simulateAndRevert(address,bytes)": "b4faba09", + "swapOwner(address,address,address)": "e318b52b" + }, + "rawMetadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"AddedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"approvedHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ApproveHash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"handler\",\"type\":\"address\"}],\"name\":\"ChangedFallbackHandler\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"ChangedGuard\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"name\":\"ChangedThreshold\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"DisabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"EnabledModule\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleFailure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"ExecutionFromModuleSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"ExecutionSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"RemovedOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SafeReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"owners\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"initializer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fallbackHandler\",\"type\":\"address\"}],\"name\":\"SafeSetup\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"SignMsg\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"addOwnerWithThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashToApprove\",\"type\":\"bytes32\"}],\"name\":\"approveHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"approvedHashes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"changeThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredSignatures\",\"type\":\"uint256\"}],\"name\":\"checkNSignatures\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dataHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"}],\"name\":\"checkSignatures\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevModule\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"disableModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"enableModule\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enum Enum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"encodeTransactionData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enum Enum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signatures\",\"type\":\"bytes\"}],\"name\":\"execTransaction\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enum Enum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModule\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enum Enum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"execTransactionFromModuleReturnData\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"start\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getModulesPaginated\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"array\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"next\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwners\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"getStorageAt\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enum Enum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"safeTxGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"baseGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"gasToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"refundReceiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"getTransactionHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"module\",\"type\":\"address\"}],\"name\":\"isModuleEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"isOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"removeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"enum Enum.Operation\",\"name\":\"operation\",\"type\":\"uint8\"}],\"name\":\"requiredTxGas\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"handler\",\"type\":\"address\"}],\"name\":\"setFallbackHandler\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"setGuard\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"fallbackHandler\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"paymentToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymentReceiver\",\"type\":\"address\"}],\"name\":\"setup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"signedMessages\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"targetContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"calldataPayload\",\"type\":\"bytes\"}],\"name\":\"simulateAndRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"prevOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"swapOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"IGnosisSafe - Gnosis Safe Interface\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"scripts/interfaces/IGnosisSafe.sol\":\"IGnosisSafe\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"]},\"sources\":{\"scripts/interfaces/IGnosisSafe.sol\":{\"keccak256\":\"0xb9a55c98ef4d6a18260d6432f633a4bd6c5f540bfa80c4dc89c5ec33fd9aeec5\",\"license\":\"LGPL-3.0-only\",\"urls\":[\"bzz-raw://e953fc0cb723a9197006697e372f1729af1de1860a9845f2574f98aa9add72aa\",\"dweb:/ipfs/QmTdBba1DFqPNcaBmEFDSN8JmR7xPKwWno2vqnhmBjoGMD\"]}},\"version\":1}", + "metadata": { + "compiler": { + "version": "0.8.19+commit.7dd6d404" + }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + "indexed": false + } + ], + "type": "event", + "name": "AddedOwner", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "approvedHash", + "type": "bytes32", + "indexed": true + }, + { + "internalType": "address", + "name": "owner", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "ApproveHash", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "handler", + "type": "address", + "indexed": false + } + ], + "type": "event", + "name": "ChangedFallbackHandler", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guard", + "type": "address", + "indexed": false + } + ], + "type": "event", + "name": "ChangedGuard", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "ChangedThreshold", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "module", + "type": "address", + "indexed": false + } + ], + "type": "event", + "name": "DisabledModule", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "module", + "type": "address", + "indexed": false + } + ], + "type": "event", + "name": "EnabledModule", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32", + "indexed": false + }, + { + "internalType": "uint256", + "name": "payment", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "ExecutionFailure", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "module", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "ExecutionFromModuleFailure", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "module", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "ExecutionFromModuleSuccess", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32", + "indexed": false + }, + { + "internalType": "uint256", + "name": "payment", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "ExecutionSuccess", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + "indexed": false + } + ], + "type": "event", + "name": "RemovedOwner", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address", + "indexed": true + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "SafeReceived", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "initiator", + "type": "address", + "indexed": true + }, + { + "internalType": "address[]", + "name": "owners", + "type": "address[]", + "indexed": false + }, + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256", + "indexed": false + }, + { + "internalType": "address", + "name": "initializer", + "type": "address", + "indexed": false + }, + { + "internalType": "address", + "name": "fallbackHandler", + "type": "address", + "indexed": false + } + ], + "type": "event", + "name": "SafeSetup", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32", + "indexed": true + } + ], + "type": "event", + "name": "SignMsg", + "anonymous": false + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_threshold", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "addOwnerWithThreshold" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hashToApprove", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "approveHash" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function", + "name": "approvedHashes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ] + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_threshold", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "changeThreshold" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "dataHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signatures", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "requiredSignatures", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "name": "checkNSignatures" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "dataHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signatures", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function", + "name": "checkSignatures" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "prevModule", + "type": "address" + }, + { + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "disableModule" + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "domainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "enableModule" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "safeTxGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gasToken", + "type": "address" + }, + { + "internalType": "address", + "name": "refundReceiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "name": "encodeTransactionData", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "safeTxGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gasToken", + "type": "address" + }, + { + "internalType": "address", + "name": "refundReceiver", + "type": "address" + }, + { + "internalType": "bytes", + "name": "signatures", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function", + "name": "execTransaction", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "execTransactionFromModule", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "execTransactionFromModuleReturnData", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "getChainId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "start", + "type": "address" + }, + { + "internalType": "uint256", + "name": "pageSize", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "name": "getModulesPaginated", + "outputs": [ + { + "internalType": "address[]", + "name": "array", + "type": "address[]" + }, + { + "internalType": "address", + "name": "next", + "type": "address" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "getOwners", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ] + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "name": "getStorageAt", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "getThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "safeTxGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gasToken", + "type": "address" + }, + { + "internalType": "address", + "name": "refundReceiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "name": "getTransactionHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "module", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "isModuleEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "isOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "prevOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_threshold", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "removeOwner" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "requiredTxGas", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "handler", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "setFallbackHandler" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guard", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "setGuard" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_owners", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "_threshold", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "address", + "name": "fallbackHandler", + "type": "address" + }, + { + "internalType": "address", + "name": "paymentToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "payment", + "type": "uint256" + }, + { + "internalType": "address", + "name": "paymentReceiver", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "setup" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function", + "name": "signedMessages", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "targetContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "calldataPayload", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "simulateAndRevert" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "prevOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "swapOwner" + } + ], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "settings": { + "remappings": [ + "@cwia/=lib/clones-with-immutable-args/src/", + "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", + "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", + "@rari-capital/solmate/=lib/solmate/", + "clones-with-immutable-args/=lib/clones-with-immutable-args/src/", + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", + "openzeppelin-contracts/=lib/openzeppelin-contracts/", + "safe-contracts/=lib/safe-contracts/contracts/", + "solmate/=lib/solmate/src/" + ], + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "metadata": { + "bytecodeHash": "none" + }, + "compilationTarget": { + "scripts/interfaces/IGnosisSafe.sol": "IGnosisSafe" + }, + "libraries": {} + }, + "sources": { + "scripts/interfaces/IGnosisSafe.sol": { + "keccak256": "0xb9a55c98ef4d6a18260d6432f633a4bd6c5f540bfa80c4dc89c5ec33fd9aeec5", + "urls": [ + "bzz-raw://e953fc0cb723a9197006697e372f1729af1de1860a9845f2574f98aa9add72aa", + "dweb:/ipfs/QmTdBba1DFqPNcaBmEFDSN8JmR7xPKwWno2vqnhmBjoGMD" + ], + "license": "LGPL-3.0-only" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": {} + }, + "userdoc": { + "version": 1, + "kind": "user" + }, + "devdoc": { + "version": 1, + "kind": "dev", + "title": "IGnosisSafe - Gnosis Safe Interface" + }, + "ast": { + "absolutePath": "scripts/interfaces/IGnosisSafe.sol", + "id": 36017, + "exportedSymbols": { + "Enum": [ + 35629 + ], + "IGnosisSafe": [ + 36016 + ] + }, + "nodeType": "SourceUnit", + "src": "42:5070:43", + "nodes": [ + { + "id": 35624, + "nodeType": "PragmaDirective", + "src": "42:24:43", + "nodes": [], + "literals": [ + "solidity", + "^", + "0.8", + ".10" + ] + }, + { + "id": 35629, + "nodeType": "ContractDefinition", + "src": "172:88:43", + "nodes": [ + { + "id": 35628, + "nodeType": "EnumDefinition", + "src": "201:57:43", + "nodes": [], + "canonicalName": "Enum.Operation", + "members": [ + { + "id": 35626, + "name": "Call", + "nameLocation": "226:4:43", + "nodeType": "EnumValue", + "src": "226:4:43" + }, + { + "id": 35627, + "name": "DelegateCall", + "nameLocation": "240:12:43", + "nodeType": "EnumValue", + "src": "240:12:43" + } + ], + "name": "Operation", + "nameLocation": "206:9:43" + } + ], + "abstract": true, + "baseContracts": [], + "canonicalName": "Enum", + "contractDependencies": [], + "contractKind": "contract", + "documentation": { + "id": 35625, + "nodeType": "StructuredDocumentation", + "src": "68:104:43", + "text": "@title Enum - Collection of enums used in Safe contracts.\n @author Richard Meissner - @rmeissner" + }, + "fullyImplemented": true, + "linearizedBaseContracts": [ + 35629 + ], + "name": "Enum", + "nameLocation": "190:4:43", + "scope": 36017, + "usedErrors": [] + }, + { + "id": 36016, + "nodeType": "ContractDefinition", + "src": "309:4802:43", + "nodes": [ + { + "id": 35634, + "nodeType": "EventDefinition", + "src": "337:32:43", + "nodes": [], + "anonymous": false, + "eventSelector": "9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26", + "name": "AddedOwner", + "nameLocation": "343:10:43", + "parameters": { + "id": 35633, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35632, + "indexed": false, + "mutability": "mutable", + "name": "owner", + "nameLocation": "362:5:43", + "nodeType": "VariableDeclaration", + "scope": 35634, + "src": "354:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35631, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "354:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "353:15:43" + } + }, + { + "id": 35640, + "nodeType": "EventDefinition", + "src": "374:71:43", + "nodes": [], + "anonymous": false, + "eventSelector": "f2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c", + "name": "ApproveHash", + "nameLocation": "380:11:43", + "parameters": { + "id": 35639, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35636, + "indexed": true, + "mutability": "mutable", + "name": "approvedHash", + "nameLocation": "408:12:43", + "nodeType": "VariableDeclaration", + "scope": 35640, + "src": "392:28:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35635, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "392:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35638, + "indexed": true, + "mutability": "mutable", + "name": "owner", + "nameLocation": "438:5:43", + "nodeType": "VariableDeclaration", + "scope": 35640, + "src": "422:21:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35637, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "422:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "391:53:43" + } + }, + { + "id": 35644, + "nodeType": "EventDefinition", + "src": "450:46:43", + "nodes": [], + "anonymous": false, + "eventSelector": "5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b0", + "name": "ChangedFallbackHandler", + "nameLocation": "456:22:43", + "parameters": { + "id": 35643, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35642, + "indexed": false, + "mutability": "mutable", + "name": "handler", + "nameLocation": "487:7:43", + "nodeType": "VariableDeclaration", + "scope": 35644, + "src": "479:15:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35641, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "479:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "478:17:43" + } + }, + { + "id": 35648, + "nodeType": "EventDefinition", + "src": "501:34:43", + "nodes": [], + "anonymous": false, + "eventSelector": "1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2", + "name": "ChangedGuard", + "nameLocation": "507:12:43", + "parameters": { + "id": 35647, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35646, + "indexed": false, + "mutability": "mutable", + "name": "guard", + "nameLocation": "528:5:43", + "nodeType": "VariableDeclaration", + "scope": 35648, + "src": "520:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35645, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "520:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "519:15:43" + } + }, + { + "id": 35652, + "nodeType": "EventDefinition", + "src": "540:42:43", + "nodes": [], + "anonymous": false, + "eventSelector": "610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c93", + "name": "ChangedThreshold", + "nameLocation": "546:16:43", + "parameters": { + "id": 35651, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35650, + "indexed": false, + "mutability": "mutable", + "name": "threshold", + "nameLocation": "571:9:43", + "nodeType": "VariableDeclaration", + "scope": 35652, + "src": "563:17:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35649, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "563:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "562:19:43" + } + }, + { + "id": 35656, + "nodeType": "EventDefinition", + "src": "587:37:43", + "nodes": [], + "anonymous": false, + "eventSelector": "aab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace4054276", + "name": "DisabledModule", + "nameLocation": "593:14:43", + "parameters": { + "id": 35655, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35654, + "indexed": false, + "mutability": "mutable", + "name": "module", + "nameLocation": "616:6:43", + "nodeType": "VariableDeclaration", + "scope": 35656, + "src": "608:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35653, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "608:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "607:16:43" + } + }, + { + "id": 35660, + "nodeType": "EventDefinition", + "src": "629:36:43", + "nodes": [], + "anonymous": false, + "eventSelector": "ecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440", + "name": "EnabledModule", + "nameLocation": "635:13:43", + "parameters": { + "id": 35659, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35658, + "indexed": false, + "mutability": "mutable", + "name": "module", + "nameLocation": "657:6:43", + "nodeType": "VariableDeclaration", + "scope": 35660, + "src": "649:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35657, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "649:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "648:16:43" + } + }, + { + "id": 35666, + "nodeType": "EventDefinition", + "src": "670:56:43", + "nodes": [], + "anonymous": false, + "eventSelector": "23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23", + "name": "ExecutionFailure", + "nameLocation": "676:16:43", + "parameters": { + "id": 35665, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35662, + "indexed": false, + "mutability": "mutable", + "name": "txHash", + "nameLocation": "701:6:43", + "nodeType": "VariableDeclaration", + "scope": 35666, + "src": "693:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35661, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "693:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35664, + "indexed": false, + "mutability": "mutable", + "name": "payment", + "nameLocation": "717:7:43", + "nodeType": "VariableDeclaration", + "scope": 35666, + "src": "709:15:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35663, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "709:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "692:33:43" + } + }, + { + "id": 35670, + "nodeType": "EventDefinition", + "src": "731:57:43", + "nodes": [], + "anonymous": false, + "eventSelector": "acd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375", + "name": "ExecutionFromModuleFailure", + "nameLocation": "737:26:43", + "parameters": { + "id": 35669, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35668, + "indexed": true, + "mutability": "mutable", + "name": "module", + "nameLocation": "780:6:43", + "nodeType": "VariableDeclaration", + "scope": 35670, + "src": "764:22:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35667, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "764:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "763:24:43" + } + }, + { + "id": 35674, + "nodeType": "EventDefinition", + "src": "793:57:43", + "nodes": [], + "anonymous": false, + "eventSelector": "6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8", + "name": "ExecutionFromModuleSuccess", + "nameLocation": "799:26:43", + "parameters": { + "id": 35673, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35672, + "indexed": true, + "mutability": "mutable", + "name": "module", + "nameLocation": "842:6:43", + "nodeType": "VariableDeclaration", + "scope": 35674, + "src": "826:22:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35671, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "826:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "825:24:43" + } + }, + { + "id": 35680, + "nodeType": "EventDefinition", + "src": "855:56:43", + "nodes": [], + "anonymous": false, + "eventSelector": "442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e", + "name": "ExecutionSuccess", + "nameLocation": "861:16:43", + "parameters": { + "id": 35679, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35676, + "indexed": false, + "mutability": "mutable", + "name": "txHash", + "nameLocation": "886:6:43", + "nodeType": "VariableDeclaration", + "scope": 35680, + "src": "878:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35675, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "878:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35678, + "indexed": false, + "mutability": "mutable", + "name": "payment", + "nameLocation": "902:7:43", + "nodeType": "VariableDeclaration", + "scope": 35680, + "src": "894:15:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35677, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "894:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "877:33:43" + } + }, + { + "id": 35684, + "nodeType": "EventDefinition", + "src": "916:34:43", + "nodes": [], + "anonymous": false, + "eventSelector": "f8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf", + "name": "RemovedOwner", + "nameLocation": "922:12:43", + "parameters": { + "id": 35683, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35682, + "indexed": false, + "mutability": "mutable", + "name": "owner", + "nameLocation": "943:5:43", + "nodeType": "VariableDeclaration", + "scope": 35684, + "src": "935:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35681, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "935:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "934:15:43" + } + }, + { + "id": 35690, + "nodeType": "EventDefinition", + "src": "955:58:43", + "nodes": [], + "anonymous": false, + "eventSelector": "3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d", + "name": "SafeReceived", + "nameLocation": "961:12:43", + "parameters": { + "id": 35689, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35686, + "indexed": true, + "mutability": "mutable", + "name": "sender", + "nameLocation": "990:6:43", + "nodeType": "VariableDeclaration", + "scope": 35690, + "src": "974:22:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35685, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "974:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35688, + "indexed": false, + "mutability": "mutable", + "name": "value", + "nameLocation": "1006:5:43", + "nodeType": "VariableDeclaration", + "scope": 35690, + "src": "998:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35687, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "998:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "973:39:43" + } + }, + { + "id": 35703, + "nodeType": "EventDefinition", + "src": "1018:140:43", + "nodes": [], + "anonymous": false, + "eventSelector": "141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a8", + "name": "SafeSetup", + "nameLocation": "1024:9:43", + "parameters": { + "id": 35702, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35692, + "indexed": true, + "mutability": "mutable", + "name": "initiator", + "nameLocation": "1059:9:43", + "nodeType": "VariableDeclaration", + "scope": 35703, + "src": "1043:25:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35691, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1043:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35695, + "indexed": false, + "mutability": "mutable", + "name": "owners", + "nameLocation": "1080:6:43", + "nodeType": "VariableDeclaration", + "scope": 35703, + "src": "1070:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 35693, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1070:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 35694, + "nodeType": "ArrayTypeName", + "src": "1070:9:43", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35697, + "indexed": false, + "mutability": "mutable", + "name": "threshold", + "nameLocation": "1096:9:43", + "nodeType": "VariableDeclaration", + "scope": 35703, + "src": "1088:17:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35696, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1088:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35699, + "indexed": false, + "mutability": "mutable", + "name": "initializer", + "nameLocation": "1115:11:43", + "nodeType": "VariableDeclaration", + "scope": 35703, + "src": "1107:19:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35698, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1107:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35701, + "indexed": false, + "mutability": "mutable", + "name": "fallbackHandler", + "nameLocation": "1136:15:43", + "nodeType": "VariableDeclaration", + "scope": 35703, + "src": "1128:23:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35700, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1128:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "1033:124:43" + } + }, + { + "id": 35707, + "nodeType": "EventDefinition", + "src": "1163:39:43", + "nodes": [], + "anonymous": false, + "eventSelector": "e7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e4", + "name": "SignMsg", + "nameLocation": "1169:7:43", + "parameters": { + "id": 35706, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35705, + "indexed": true, + "mutability": "mutable", + "name": "msgHash", + "nameLocation": "1193:7:43", + "nodeType": "VariableDeclaration", + "scope": 35707, + "src": "1177:23:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35704, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1177:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1176:25:43" + } + }, + { + "id": 35712, + "nodeType": "FunctionDefinition", + "src": "1208:57:43", + "nodes": [], + "functionSelector": "ffa1ad74", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "VERSION", + "nameLocation": "1217:7:43", + "parameters": { + "id": 35708, + "nodeType": "ParameterList", + "parameters": [], + "src": "1224:2:43" + }, + "returnParameters": { + "id": 35711, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35710, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35712, + "src": "1250:13:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 35709, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "1250:6:43", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + } + ], + "src": "1249:15:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35719, + "nodeType": "FunctionDefinition", + "src": "1270:75:43", + "nodes": [], + "functionSelector": "0d582f13", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "addOwnerWithThreshold", + "nameLocation": "1279:21:43", + "parameters": { + "id": 35717, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35714, + "mutability": "mutable", + "name": "owner", + "nameLocation": "1309:5:43", + "nodeType": "VariableDeclaration", + "scope": 35719, + "src": "1301:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35713, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1301:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35716, + "mutability": "mutable", + "name": "_threshold", + "nameLocation": "1324:10:43", + "nodeType": "VariableDeclaration", + "scope": 35719, + "src": "1316:18:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35715, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1316:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1300:35:43" + }, + "returnParameters": { + "id": 35718, + "nodeType": "ParameterList", + "parameters": [], + "src": "1344:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35724, + "nodeType": "FunctionDefinition", + "src": "1350:53:43", + "nodes": [], + "functionSelector": "d4d9bdcd", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "approveHash", + "nameLocation": "1359:11:43", + "parameters": { + "id": 35722, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35721, + "mutability": "mutable", + "name": "hashToApprove", + "nameLocation": "1379:13:43", + "nodeType": "VariableDeclaration", + "scope": 35724, + "src": "1371:21:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35720, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1371:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1370:23:43" + }, + "returnParameters": { + "id": 35723, + "nodeType": "ParameterList", + "parameters": [], + "src": "1402:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35733, + "nodeType": "FunctionDefinition", + "src": "1408:74:43", + "nodes": [], + "functionSelector": "7d832974", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "approvedHashes", + "nameLocation": "1417:14:43", + "parameters": { + "id": 35729, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35726, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35733, + "src": "1432:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35725, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1432:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35728, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35733, + "src": "1441:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35727, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1441:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1431:18:43" + }, + "returnParameters": { + "id": 35732, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35731, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35733, + "src": "1473:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35730, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1473:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1472:9:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35738, + "nodeType": "FunctionDefinition", + "src": "1487:54:43", + "nodes": [], + "functionSelector": "694e80c3", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "changeThreshold", + "nameLocation": "1496:15:43", + "parameters": { + "id": 35736, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35735, + "mutability": "mutable", + "name": "_threshold", + "nameLocation": "1520:10:43", + "nodeType": "VariableDeclaration", + "scope": 35738, + "src": "1512:18:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35734, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1512:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1511:20:43" + }, + "returnParameters": { + "id": 35737, + "nodeType": "ParameterList", + "parameters": [], + "src": "1540:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35749, + "nodeType": "FunctionDefinition", + "src": "1546:184:43", + "nodes": [], + "functionSelector": "12fb68e0", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "checkNSignatures", + "nameLocation": "1555:16:43", + "parameters": { + "id": 35747, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35740, + "mutability": "mutable", + "name": "dataHash", + "nameLocation": "1589:8:43", + "nodeType": "VariableDeclaration", + "scope": 35749, + "src": "1581:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35739, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1581:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35742, + "mutability": "mutable", + "name": "data", + "nameLocation": "1620:4:43", + "nodeType": "VariableDeclaration", + "scope": 35749, + "src": "1607:17:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35741, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1607:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35744, + "mutability": "mutable", + "name": "signatures", + "nameLocation": "1647:10:43", + "nodeType": "VariableDeclaration", + "scope": 35749, + "src": "1634:23:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35743, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1634:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35746, + "mutability": "mutable", + "name": "requiredSignatures", + "nameLocation": "1675:18:43", + "nodeType": "VariableDeclaration", + "scope": 35749, + "src": "1667:26:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35745, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1667:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1571:128:43" + }, + "returnParameters": { + "id": 35748, + "nodeType": "ParameterList", + "parameters": [], + "src": "1729:0:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35758, + "nodeType": "FunctionDefinition", + "src": "1735:101:43", + "nodes": [], + "functionSelector": "934f3a11", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "checkSignatures", + "nameLocation": "1744:15:43", + "parameters": { + "id": 35756, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35751, + "mutability": "mutable", + "name": "dataHash", + "nameLocation": "1768:8:43", + "nodeType": "VariableDeclaration", + "scope": 35758, + "src": "1760:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35750, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1760:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35753, + "mutability": "mutable", + "name": "data", + "nameLocation": "1791:4:43", + "nodeType": "VariableDeclaration", + "scope": 35758, + "src": "1778:17:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35752, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1778:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35755, + "mutability": "mutable", + "name": "signatures", + "nameLocation": "1810:10:43", + "nodeType": "VariableDeclaration", + "scope": 35758, + "src": "1797:23:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35754, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1797:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "1759:62:43" + }, + "returnParameters": { + "id": 35757, + "nodeType": "ParameterList", + "parameters": [], + "src": "1835:0:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35765, + "nodeType": "FunctionDefinition", + "src": "1841:68:43", + "nodes": [], + "functionSelector": "e009cfde", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "disableModule", + "nameLocation": "1850:13:43", + "parameters": { + "id": 35763, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35760, + "mutability": "mutable", + "name": "prevModule", + "nameLocation": "1872:10:43", + "nodeType": "VariableDeclaration", + "scope": 35765, + "src": "1864:18:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35759, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1864:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35762, + "mutability": "mutable", + "name": "module", + "nameLocation": "1892:6:43", + "nodeType": "VariableDeclaration", + "scope": 35765, + "src": "1884:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35761, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1884:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "1863:36:43" + }, + "returnParameters": { + "id": 35764, + "nodeType": "ParameterList", + "parameters": [], + "src": "1908:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35770, + "nodeType": "FunctionDefinition", + "src": "1914:59:43", + "nodes": [], + "functionSelector": "f698da25", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "domainSeparator", + "nameLocation": "1923:15:43", + "parameters": { + "id": 35766, + "nodeType": "ParameterList", + "parameters": [], + "src": "1938:2:43" + }, + "returnParameters": { + "id": 35769, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35768, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35770, + "src": "1964:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35767, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1964:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1963:9:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35775, + "nodeType": "FunctionDefinition", + "src": "1978:47:43", + "nodes": [], + "functionSelector": "610b5925", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "enableModule", + "nameLocation": "1987:12:43", + "parameters": { + "id": 35773, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35772, + "mutability": "mutable", + "name": "module", + "nameLocation": "2008:6:43", + "nodeType": "VariableDeclaration", + "scope": 35775, + "src": "2000:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35771, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2000:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "1999:16:43" + }, + "returnParameters": { + "id": 35774, + "nodeType": "ParameterList", + "parameters": [], + "src": "2024:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35801, + "nodeType": "FunctionDefinition", + "src": "2030:362:43", + "nodes": [], + "functionSelector": "e86637db", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "encodeTransactionData", + "nameLocation": "2039:21:43", + "parameters": { + "id": 35797, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35777, + "mutability": "mutable", + "name": "to", + "nameLocation": "2078:2:43", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2070:10:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35776, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2070:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35779, + "mutability": "mutable", + "name": "value", + "nameLocation": "2098:5:43", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2090:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35778, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2090:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35781, + "mutability": "mutable", + "name": "data", + "nameLocation": "2126:4:43", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2113:17:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35780, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2113:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35784, + "mutability": "mutable", + "name": "operation", + "nameLocation": "2155:9:43", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2140:24:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + }, + "typeName": { + "id": 35783, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 35782, + "name": "Enum.Operation", + "nameLocations": [ + "2140:4:43", + "2145:9:43" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 35628, + "src": "2140:14:43" + }, + "referencedDeclaration": 35628, + "src": "2140:14:43", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35786, + "mutability": "mutable", + "name": "safeTxGas", + "nameLocation": "2182:9:43", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2174:17:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35785, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2174:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35788, + "mutability": "mutable", + "name": "baseGas", + "nameLocation": "2209:7:43", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2201:15:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35787, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2201:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35790, + "mutability": "mutable", + "name": "gasPrice", + "nameLocation": "2234:8:43", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2226:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35789, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2226:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35792, + "mutability": "mutable", + "name": "gasToken", + "nameLocation": "2260:8:43", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2252:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35791, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2252:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35794, + "mutability": "mutable", + "name": "refundReceiver", + "nameLocation": "2286:14:43", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2278:22:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35793, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2278:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35796, + "mutability": "mutable", + "name": "_nonce", + "nameLocation": "2318:6:43", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2310:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35795, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2310:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2060:270:43" + }, + "returnParameters": { + "id": 35800, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35799, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35801, + "src": "2378:12:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35798, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2378:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "2377:14:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35827, + "nodeType": "FunctionDefinition", + "src": "2397:368:43", + "nodes": [], + "functionSelector": "6a761202", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "execTransaction", + "nameLocation": "2406:15:43", + "parameters": { + "id": 35823, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35803, + "mutability": "mutable", + "name": "to", + "nameLocation": "2439:2:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2431:10:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35802, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2431:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35805, + "mutability": "mutable", + "name": "value", + "nameLocation": "2459:5:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2451:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35804, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2451:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35807, + "mutability": "mutable", + "name": "data", + "nameLocation": "2487:4:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2474:17:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35806, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2474:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35810, + "mutability": "mutable", + "name": "operation", + "nameLocation": "2516:9:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2501:24:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + }, + "typeName": { + "id": 35809, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 35808, + "name": "Enum.Operation", + "nameLocations": [ + "2501:4:43", + "2506:9:43" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 35628, + "src": "2501:14:43" + }, + "referencedDeclaration": 35628, + "src": "2501:14:43", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35812, + "mutability": "mutable", + "name": "safeTxGas", + "nameLocation": "2543:9:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2535:17:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35811, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2535:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35814, + "mutability": "mutable", + "name": "baseGas", + "nameLocation": "2570:7:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2562:15:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35813, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2562:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35816, + "mutability": "mutable", + "name": "gasPrice", + "nameLocation": "2595:8:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2587:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35815, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2587:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35818, + "mutability": "mutable", + "name": "gasToken", + "nameLocation": "2621:8:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2613:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35817, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2613:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35820, + "mutability": "mutable", + "name": "refundReceiver", + "nameLocation": "2647:14:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2639:22:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35819, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2639:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35822, + "mutability": "mutable", + "name": "signatures", + "nameLocation": "2684:10:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2671:23:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35821, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2671:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "2421:279:43" + }, + "returnParameters": { + "id": 35826, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35825, + "mutability": "mutable", + "name": "success", + "nameLocation": "2756:7:43", + "nodeType": "VariableDeclaration", + "scope": 35827, + "src": "2751:12:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 35824, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2751:4:43", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "2750:14:43" + }, + "scope": 36016, + "stateMutability": "payable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35841, + "nodeType": "FunctionDefinition", + "src": "2770:193:43", + "nodes": [], + "functionSelector": "468721a7", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "execTransactionFromModule", + "nameLocation": "2779:25:43", + "parameters": { + "id": 35837, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35829, + "mutability": "mutable", + "name": "to", + "nameLocation": "2822:2:43", + "nodeType": "VariableDeclaration", + "scope": 35841, + "src": "2814:10:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35828, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2814:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35831, + "mutability": "mutable", + "name": "value", + "nameLocation": "2842:5:43", + "nodeType": "VariableDeclaration", + "scope": 35841, + "src": "2834:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35830, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2834:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35833, + "mutability": "mutable", + "name": "data", + "nameLocation": "2870:4:43", + "nodeType": "VariableDeclaration", + "scope": 35841, + "src": "2857:17:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35832, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2857:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35836, + "mutability": "mutable", + "name": "operation", + "nameLocation": "2899:9:43", + "nodeType": "VariableDeclaration", + "scope": 35841, + "src": "2884:24:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + }, + "typeName": { + "id": 35835, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 35834, + "name": "Enum.Operation", + "nameLocations": [ + "2884:4:43", + "2889:9:43" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 35628, + "src": "2884:14:43" + }, + "referencedDeclaration": 35628, + "src": "2884:14:43", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + } + }, + "visibility": "internal" + } + ], + "src": "2804:110:43" + }, + "returnParameters": { + "id": 35840, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35839, + "mutability": "mutable", + "name": "success", + "nameLocation": "2954:7:43", + "nodeType": "VariableDeclaration", + "scope": 35841, + "src": "2949:12:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 35838, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2949:4:43", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "2948:14:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35857, + "nodeType": "FunctionDefinition", + "src": "2968:228:43", + "nodes": [], + "functionSelector": "5229073f", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "execTransactionFromModuleReturnData", + "nameLocation": "2977:35:43", + "parameters": { + "id": 35851, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35843, + "mutability": "mutable", + "name": "to", + "nameLocation": "3030:2:43", + "nodeType": "VariableDeclaration", + "scope": 35857, + "src": "3022:10:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35842, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3022:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35845, + "mutability": "mutable", + "name": "value", + "nameLocation": "3050:5:43", + "nodeType": "VariableDeclaration", + "scope": 35857, + "src": "3042:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35844, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3042:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35847, + "mutability": "mutable", + "name": "data", + "nameLocation": "3078:4:43", + "nodeType": "VariableDeclaration", + "scope": 35857, + "src": "3065:17:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35846, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3065:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35850, + "mutability": "mutable", + "name": "operation", + "nameLocation": "3107:9:43", + "nodeType": "VariableDeclaration", + "scope": 35857, + "src": "3092:24:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + }, + "typeName": { + "id": 35849, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 35848, + "name": "Enum.Operation", + "nameLocations": [ + "3092:4:43", + "3097:9:43" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 35628, + "src": "3092:14:43" + }, + "referencedDeclaration": 35628, + "src": "3092:14:43", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + } + }, + "visibility": "internal" + } + ], + "src": "3012:110:43" + }, + "returnParameters": { + "id": 35856, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35853, + "mutability": "mutable", + "name": "success", + "nameLocation": "3162:7:43", + "nodeType": "VariableDeclaration", + "scope": 35857, + "src": "3157:12:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 35852, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3157:4:43", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35855, + "mutability": "mutable", + "name": "returnData", + "nameLocation": "3184:10:43", + "nodeType": "VariableDeclaration", + "scope": 35857, + "src": "3171:23:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35854, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3171:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "3156:39:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35862, + "nodeType": "FunctionDefinition", + "src": "3201:54:43", + "nodes": [], + "functionSelector": "3408e470", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getChainId", + "nameLocation": "3210:10:43", + "parameters": { + "id": 35858, + "nodeType": "ParameterList", + "parameters": [], + "src": "3220:2:43" + }, + "returnParameters": { + "id": 35861, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35860, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35862, + "src": "3246:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35859, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3246:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3245:9:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35874, + "nodeType": "FunctionDefinition", + "src": "3260:169:43", + "nodes": [], + "functionSelector": "cc2f8452", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getModulesPaginated", + "nameLocation": "3269:19:43", + "parameters": { + "id": 35867, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35864, + "mutability": "mutable", + "name": "start", + "nameLocation": "3306:5:43", + "nodeType": "VariableDeclaration", + "scope": 35874, + "src": "3298:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35863, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3298:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35866, + "mutability": "mutable", + "name": "pageSize", + "nameLocation": "3329:8:43", + "nodeType": "VariableDeclaration", + "scope": 35874, + "src": "3321:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35865, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3321:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3288:55:43" + }, + "returnParameters": { + "id": 35873, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35870, + "mutability": "mutable", + "name": "array", + "nameLocation": "3408:5:43", + "nodeType": "VariableDeclaration", + "scope": 35874, + "src": "3391:22:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 35868, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3391:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 35869, + "nodeType": "ArrayTypeName", + "src": "3391:9:43", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35872, + "mutability": "mutable", + "name": "next", + "nameLocation": "3423:4:43", + "nodeType": "VariableDeclaration", + "scope": 35874, + "src": "3415:12:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35871, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3415:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "3390:38:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35880, + "nodeType": "FunctionDefinition", + "src": "3434:62:43", + "nodes": [], + "functionSelector": "a0e67e2b", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getOwners", + "nameLocation": "3443:9:43", + "parameters": { + "id": 35875, + "nodeType": "ParameterList", + "parameters": [], + "src": "3452:2:43" + }, + "returnParameters": { + "id": 35879, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35878, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35880, + "src": "3478:16:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 35876, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3478:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 35877, + "nodeType": "ArrayTypeName", + "src": "3478:9:43", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "visibility": "internal" + } + ], + "src": "3477:18:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35889, + "nodeType": "FunctionDefinition", + "src": "3501:91:43", + "nodes": [], + "functionSelector": "5624b25b", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getStorageAt", + "nameLocation": "3510:12:43", + "parameters": { + "id": 35885, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35882, + "mutability": "mutable", + "name": "offset", + "nameLocation": "3531:6:43", + "nodeType": "VariableDeclaration", + "scope": 35889, + "src": "3523:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35881, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3523:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35884, + "mutability": "mutable", + "name": "length", + "nameLocation": "3547:6:43", + "nodeType": "VariableDeclaration", + "scope": 35889, + "src": "3539:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35883, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3539:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3522:32:43" + }, + "returnParameters": { + "id": 35888, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35887, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35889, + "src": "3578:12:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35886, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3578:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "3577:14:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35894, + "nodeType": "FunctionDefinition", + "src": "3597:56:43", + "nodes": [], + "functionSelector": "e75235b8", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getThreshold", + "nameLocation": "3606:12:43", + "parameters": { + "id": 35890, + "nodeType": "ParameterList", + "parameters": [], + "src": "3618:2:43" + }, + "returnParameters": { + "id": 35893, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35892, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35894, + "src": "3644:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35891, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3644:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3643:9:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35920, + "nodeType": "FunctionDefinition", + "src": "3658:354:43", + "nodes": [], + "functionSelector": "d8d11f78", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getTransactionHash", + "nameLocation": "3667:18:43", + "parameters": { + "id": 35916, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35896, + "mutability": "mutable", + "name": "to", + "nameLocation": "3703:2:43", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "3695:10:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35895, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3695:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35898, + "mutability": "mutable", + "name": "value", + "nameLocation": "3723:5:43", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "3715:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35897, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3715:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35900, + "mutability": "mutable", + "name": "data", + "nameLocation": "3751:4:43", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "3738:17:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35899, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3738:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35903, + "mutability": "mutable", + "name": "operation", + "nameLocation": "3780:9:43", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "3765:24:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + }, + "typeName": { + "id": 35902, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 35901, + "name": "Enum.Operation", + "nameLocations": [ + "3765:4:43", + "3770:9:43" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 35628, + "src": "3765:14:43" + }, + "referencedDeclaration": 35628, + "src": "3765:14:43", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35905, + "mutability": "mutable", + "name": "safeTxGas", + "nameLocation": "3807:9:43", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "3799:17:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35904, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3799:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35907, + "mutability": "mutable", + "name": "baseGas", + "nameLocation": "3834:7:43", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "3826:15:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35906, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3826:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35909, + "mutability": "mutable", + "name": "gasPrice", + "nameLocation": "3859:8:43", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "3851:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35908, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3851:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35911, + "mutability": "mutable", + "name": "gasToken", + "nameLocation": "3885:8:43", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "3877:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35910, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3877:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35913, + "mutability": "mutable", + "name": "refundReceiver", + "nameLocation": "3911:14:43", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "3903:22:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35912, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3903:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35915, + "mutability": "mutable", + "name": "_nonce", + "nameLocation": "3943:6:43", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "3935:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35914, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3935:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3685:270:43" + }, + "returnParameters": { + "id": 35919, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35918, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35920, + "src": "4003:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35917, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4003:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "4002:9:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35927, + "nodeType": "FunctionDefinition", + "src": "4017:70:43", + "nodes": [], + "functionSelector": "2d9ad53d", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "isModuleEnabled", + "nameLocation": "4026:15:43", + "parameters": { + "id": 35923, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35922, + "mutability": "mutable", + "name": "module", + "nameLocation": "4050:6:43", + "nodeType": "VariableDeclaration", + "scope": 35927, + "src": "4042:14:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35921, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4042:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "4041:16:43" + }, + "returnParameters": { + "id": 35926, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35925, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35927, + "src": "4081:4:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 35924, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4081:4:43", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "4080:6:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35934, + "nodeType": "FunctionDefinition", + "src": "4092:61:43", + "nodes": [], + "functionSelector": "2f54bf6e", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "isOwner", + "nameLocation": "4101:7:43", + "parameters": { + "id": 35930, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35929, + "mutability": "mutable", + "name": "owner", + "nameLocation": "4117:5:43", + "nodeType": "VariableDeclaration", + "scope": 35934, + "src": "4109:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35928, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4109:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "4108:15:43" + }, + "returnParameters": { + "id": 35933, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35932, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35934, + "src": "4147:4:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 35931, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4147:4:43", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "4146:6:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35939, + "nodeType": "FunctionDefinition", + "src": "4158:49:43", + "nodes": [], + "functionSelector": "affed0e0", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "nonce", + "nameLocation": "4167:5:43", + "parameters": { + "id": 35935, + "nodeType": "ParameterList", + "parameters": [], + "src": "4172:2:43" + }, + "returnParameters": { + "id": 35938, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35937, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35939, + "src": "4198:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35936, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4198:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4197:9:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 35948, + "nodeType": "FunctionDefinition", + "src": "4212:84:43", + "nodes": [], + "functionSelector": "f8dc5dd9", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "removeOwner", + "nameLocation": "4221:11:43", + "parameters": { + "id": 35946, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35941, + "mutability": "mutable", + "name": "prevOwner", + "nameLocation": "4241:9:43", + "nodeType": "VariableDeclaration", + "scope": 35948, + "src": "4233:17:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35940, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4233:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35943, + "mutability": "mutable", + "name": "owner", + "nameLocation": "4260:5:43", + "nodeType": "VariableDeclaration", + "scope": 35948, + "src": "4252:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35942, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4252:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35945, + "mutability": "mutable", + "name": "_threshold", + "nameLocation": "4275:10:43", + "nodeType": "VariableDeclaration", + "scope": 35948, + "src": "4267:18:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35944, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4267:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4232:54:43" + }, + "returnParameters": { + "id": 35947, + "nodeType": "ParameterList", + "parameters": [], + "src": "4295:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35962, + "nodeType": "FunctionDefinition", + "src": "4301:176:43", + "nodes": [], + "functionSelector": "c4ca3a9c", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "requiredTxGas", + "nameLocation": "4310:13:43", + "parameters": { + "id": 35958, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35950, + "mutability": "mutable", + "name": "to", + "nameLocation": "4341:2:43", + "nodeType": "VariableDeclaration", + "scope": 35962, + "src": "4333:10:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35949, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4333:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35952, + "mutability": "mutable", + "name": "value", + "nameLocation": "4361:5:43", + "nodeType": "VariableDeclaration", + "scope": 35962, + "src": "4353:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35951, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4353:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35954, + "mutability": "mutable", + "name": "data", + "nameLocation": "4389:4:43", + "nodeType": "VariableDeclaration", + "scope": 35962, + "src": "4376:17:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35953, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4376:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35957, + "mutability": "mutable", + "name": "operation", + "nameLocation": "4418:9:43", + "nodeType": "VariableDeclaration", + "scope": 35962, + "src": "4403:24:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + }, + "typeName": { + "id": 35956, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 35955, + "name": "Enum.Operation", + "nameLocations": [ + "4403:4:43", + "4408:9:43" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 35628, + "src": "4403:14:43" + }, + "referencedDeclaration": 35628, + "src": "4403:14:43", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Operation_$35628", + "typeString": "enum Enum.Operation" + } + }, + "visibility": "internal" + } + ], + "src": "4323:110:43" + }, + "returnParameters": { + "id": 35961, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35960, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35962, + "src": "4468:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35959, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4468:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4467:9:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35967, + "nodeType": "FunctionDefinition", + "src": "4482:54:43", + "nodes": [], + "functionSelector": "f08a0323", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "setFallbackHandler", + "nameLocation": "4491:18:43", + "parameters": { + "id": 35965, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35964, + "mutability": "mutable", + "name": "handler", + "nameLocation": "4518:7:43", + "nodeType": "VariableDeclaration", + "scope": 35967, + "src": "4510:15:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35963, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4510:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "4509:17:43" + }, + "returnParameters": { + "id": 35966, + "nodeType": "ParameterList", + "parameters": [], + "src": "4535:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35972, + "nodeType": "FunctionDefinition", + "src": "4541:42:43", + "nodes": [], + "functionSelector": "e19a9dd9", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "setGuard", + "nameLocation": "4550:8:43", + "parameters": { + "id": 35970, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35969, + "mutability": "mutable", + "name": "guard", + "nameLocation": "4567:5:43", + "nodeType": "VariableDeclaration", + "scope": 35972, + "src": "4559:13:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35968, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4559:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "4558:15:43" + }, + "returnParameters": { + "id": 35971, + "nodeType": "ParameterList", + "parameters": [], + "src": "4582:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35992, + "nodeType": "FunctionDefinition", + "src": "4588:268:43", + "nodes": [], + "functionSelector": "b63e800d", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "setup", + "nameLocation": "4597:5:43", + "parameters": { + "id": 35990, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35975, + "mutability": "mutable", + "name": "_owners", + "nameLocation": "4629:7:43", + "nodeType": "VariableDeclaration", + "scope": 35992, + "src": "4612:24:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 35973, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4612:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 35974, + "nodeType": "ArrayTypeName", + "src": "4612:9:43", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35977, + "mutability": "mutable", + "name": "_threshold", + "nameLocation": "4654:10:43", + "nodeType": "VariableDeclaration", + "scope": 35992, + "src": "4646:18:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35976, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4646:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35979, + "mutability": "mutable", + "name": "to", + "nameLocation": "4682:2:43", + "nodeType": "VariableDeclaration", + "scope": 35992, + "src": "4674:10:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35978, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4674:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35981, + "mutability": "mutable", + "name": "data", + "nameLocation": "4707:4:43", + "nodeType": "VariableDeclaration", + "scope": 35992, + "src": "4694:17:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 35980, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4694:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35983, + "mutability": "mutable", + "name": "fallbackHandler", + "nameLocation": "4729:15:43", + "nodeType": "VariableDeclaration", + "scope": 35992, + "src": "4721:23:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35982, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4721:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35985, + "mutability": "mutable", + "name": "paymentToken", + "nameLocation": "4762:12:43", + "nodeType": "VariableDeclaration", + "scope": 35992, + "src": "4754:20:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35984, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4754:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35987, + "mutability": "mutable", + "name": "payment", + "nameLocation": "4792:7:43", + "nodeType": "VariableDeclaration", + "scope": 35992, + "src": "4784:15:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35986, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4784:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 35989, + "mutability": "mutable", + "name": "paymentReceiver", + "nameLocation": "4817:15:43", + "nodeType": "VariableDeclaration", + "scope": 35992, + "src": "4809:23:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 35988, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4809:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "4602:236:43" + }, + "returnParameters": { + "id": 35991, + "nodeType": "ParameterList", + "parameters": [], + "src": "4855:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 35999, + "nodeType": "FunctionDefinition", + "src": "4861:65:43", + "nodes": [], + "functionSelector": "5ae6bd37", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "signedMessages", + "nameLocation": "4870:14:43", + "parameters": { + "id": 35995, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35994, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35999, + "src": "4885:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 35993, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4885:7:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "4884:9:43" + }, + "returnParameters": { + "id": 35998, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 35997, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 35999, + "src": "4917:7:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 35996, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4917:7:43", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4916:9:43" + }, + "scope": 36016, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 36006, + "nodeType": "FunctionDefinition", + "src": "4931:90:43", + "nodes": [], + "functionSelector": "b4faba09", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "simulateAndRevert", + "nameLocation": "4940:17:43", + "parameters": { + "id": 36004, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 36001, + "mutability": "mutable", + "name": "targetContract", + "nameLocation": "4966:14:43", + "nodeType": "VariableDeclaration", + "scope": 36006, + "src": "4958:22:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 36000, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4958:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 36003, + "mutability": "mutable", + "name": "calldataPayload", + "nameLocation": "4995:15:43", + "nodeType": "VariableDeclaration", + "scope": 36006, + "src": "4982:28:43", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 36002, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4982:5:43", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "4957:54:43" + }, + "returnParameters": { + "id": 36005, + "nodeType": "ParameterList", + "parameters": [], + "src": "5020:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 36015, + "nodeType": "FunctionDefinition", + "src": "5026:83:43", + "nodes": [], + "functionSelector": "e318b52b", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "swapOwner", + "nameLocation": "5035:9:43", + "parameters": { + "id": 36013, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 36008, + "mutability": "mutable", + "name": "prevOwner", + "nameLocation": "5053:9:43", + "nodeType": "VariableDeclaration", + "scope": 36015, + "src": "5045:17:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 36007, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5045:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 36010, + "mutability": "mutable", + "name": "oldOwner", + "nameLocation": "5072:8:43", + "nodeType": "VariableDeclaration", + "scope": 36015, + "src": "5064:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 36009, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5064:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 36012, + "mutability": "mutable", + "name": "newOwner", + "nameLocation": "5090:8:43", + "nodeType": "VariableDeclaration", + "scope": 36015, + "src": "5082:16:43", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 36011, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5082:7:43", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "5044:55:43" + }, + "returnParameters": { + "id": 36014, + "nodeType": "ParameterList", + "parameters": [], + "src": "5108:0:43" + }, + "scope": 36016, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + } + ], + "abstract": false, + "baseContracts": [], + "canonicalName": "IGnosisSafe", + "contractDependencies": [], + "contractKind": "interface", + "documentation": { + "id": 35630, + "nodeType": "StructuredDocumentation", + "src": "262:47:43", + "text": "@title IGnosisSafe - Gnosis Safe Interface" + }, + "fullyImplemented": false, + "linearizedBaseContracts": [ + 36016 + ], + "name": "IGnosisSafe", + "nameLocation": "319:11:43", + "scope": 36017, + "usedErrors": [] + } + ], + "license": "LGPL-3.0-only" + }, + "id": 43 +} \ No newline at end of file diff --git a/packages/chain-mon/src/abi/OptimismPortal.json b/packages/chain-mon/src/abi/OptimismPortal.json new file mode 100644 index 000000000000..e6f1d9048fea --- /dev/null +++ b/packages/chain-mon/src/abi/OptimismPortal.json @@ -0,0 +1,11338 @@ +{ + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "opaqueData", + "type": "bytes" + } + ], + "name": "TransactionDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "withdrawalHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "name": "WithdrawalFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "withdrawalHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "WithdrawalProven", + "type": "event" + }, + { + "inputs": [], + "name": "GUARDIAN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "L2_ORACLE", + "outputs": [ + { + "internalType": "contract L2OutputOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SYSTEM_CONFIG", + "outputs": [ + { + "internalType": "contract SystemConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "_gasLimit", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "_isCreation", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "depositTransaction", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "donateETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct Types.WithdrawalTransaction", + "name": "_tx", + "type": "tuple" + } + ], + "name": "finalizeWithdrawalTransaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "finalizedWithdrawals", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "guardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract L2OutputOracle", + "name": "_l2Oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "_guardian", + "type": "address" + }, + { + "internalType": "contract SystemConfig", + "name": "_systemConfig", + "type": "address" + }, + { + "internalType": "bool", + "name": "_paused", + "type": "bool" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2OutputIndex", + "type": "uint256" + } + ], + "name": "isOutputFinalized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2Oracle", + "outputs": [ + { + "internalType": "contract L2OutputOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2Sender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_byteCount", + "type": "uint64" + } + ], + "name": "minimumGasLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "params", + "outputs": [ + { + "internalType": "uint128", + "name": "prevBaseFee", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "prevBoughtGas", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "prevBlockNum", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct Types.WithdrawalTransaction", + "name": "_tx", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "_l2OutputIndex", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "version", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "stateRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "messagePasserStorageRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "latestBlockhash", + "type": "bytes32" + } + ], + "internalType": "struct Types.OutputRootProof", + "name": "_outputRootProof", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "_withdrawalProof", + "type": "bytes[]" + } + ], + "name": "proveWithdrawalTransaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "provenWithdrawals", + "outputs": [ + { + "internalType": "bytes32", + "name": "outputRoot", + "type": "bytes32" + }, + { + "internalType": "uint128", + "name": "timestamp", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "l2OutputIndex", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "systemConfig", + "outputs": [ + { + "internalType": "contract SystemConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": { + "object": "0x60806040523480156200001157600080fd5b506200002260008080600162000028565b62000224565b600054600390610100900460ff161580156200004b575060005460ff8083169116105b620000b45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100908117909155603280546001600160a01b031990811661dead1790915560358054603680546001600160a01b0389811691861691909117909155603780548a831695169490941790935585151592891690930260ff19166001600160a81b0319909316929092171790556200013962000181565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600054610100900460ff16620001ee5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b61545c80620002346000396000f3fe60806040526004361061016d5760003560e01c80638b4c40b0116100cb578063a35d99df1161007f578063e9e05c4211610059578063e9e05c4214610573578063f049875014610586578063fecf9734146105b157600080fd5b8063a35d99df1461040d578063cff0ab9614610446578063e965084c146104e757600080fd5b80639b5f694a116100b05780639b5f694a1461037e5780639bf62d82146103b0578063a14238e7146103dd57600080fd5b80638b4c40b0146101925780638c3152e91461035e57600080fd5b806354fd4d50116101225780636dbffb78116101075780636dbffb78146102fe578063724c184c1461031e5780638456cb591461034957600080fd5b806354fd4d501461027e5780635c975abb146102d457600080fd5b80633f4ba83a116101535780633f4ba83a1461021c578063452a9320146102315780634870496f1461025e57600080fd5b80621c2ff61461019957806333d7e2bd146101ef57600080fd5b36610194576101923334620186a06000604051806020016040528060008152506105d1565b005b600080fd5b3480156101a557600080fd5b50603554610100900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101fb57600080fd5b506036546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022857600080fd5b5061019261086c565b34801561023d57600080fd5b506037546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026a57600080fd5b50610192610279366004614a4a565b610971565b34801561028a57600080fd5b506102c76040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b6040516101e69190614ba0565b3480156102e057600080fd5b506035546102ee9060ff1681565b60405190151581526020016101e6565b34801561030a57600080fd5b506102ee610319366004614bb3565b610fa6565b34801561032a57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101c5565b34801561035557600080fd5b50610192611065565b34801561036a57600080fd5b50610192610379366004614bcc565b611167565b34801561038a57600080fd5b506035546101c590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103bc57600080fd5b506032546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e957600080fd5b506102ee6103f8366004614bb3565b60336020526000908152604090205460ff1681565b34801561041957600080fd5b5061042d610428366004614c26565b611a2b565b60405167ffffffffffffffff90911681526020016101e6565b34801561045257600080fd5b506001546104ae906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101e6565b3480156104f357600080fd5b50610545610502366004614bb3565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101e6565b610192610581366004614c51565b6105d1565b34801561059257600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff166101c5565b3480156105bd57600080fd5b506101926105cc366004614ccc565b611a44565b8260005a905083156106885773ffffffffffffffffffffffffffffffffffffffff87161561068857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6106928351611a2b565b67ffffffffffffffff168567ffffffffffffffff161015610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161067f565b6201d4c0835111156107a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161067f565b333281146107c4575033731111000000000000000000000000000000001111015b600034888888886040516020016107df959493929190614d26565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161084f9190614ba0565b60405180910390a450506108638282611c52565b50505050505050565b60375473ffffffffffffffffffffffffffffffffffffffff163314610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e70617573650000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff16156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161067f565b6035546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101869052600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190614dab565b519050610b50610b4b36869003860186614e10565b611f7f565b8114610bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161067f565b6000610be987611fdb565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d035750805160355460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190614dab565b5114155b610d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161067f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610e589101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610e4e888a614e76565b8a6040013561200b565b610ee4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161067f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6035546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161105f9161010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190614dab565b602001516fffffffffffffffffffffffffffffffff1661202f565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff16331461110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20706175736500000000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610967565b60355460ff16156111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161067f565b600061128882611fdb565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161067f565b603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190614efa565b81602001516fffffffffffffffffffffffffffffffff1610156114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161067f565b6114ee81602001516fffffffffffffffffffffffffffffffff1661202f565b6115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60355460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff9091166004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561162c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116509190614dab565b825181519192501461170a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161067f565b61172981602001516fffffffffffffffffffffffffffffffff1661202f565b6117db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60008381526033602052604090205460ff161561187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161067f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161191c939291906120d4565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061198190841515815260200190565b60405180910390a2801580156119975750326001145b15611a24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161067f565b5050505050565b6000611a38826010614f42565b61105f90615208614f72565b600054600390610100900460ff16158015611a66575060005460ff8083169116105b611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100908117909155603280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811661dead17909155603580546036805473ffffffffffffffffffffffffffffffffffffffff89811691861691909117909155603780548a83169516949094179093558515159289169093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fffffffffffffffffffffff00000000000000000000000000000000000000000090931692909217179055611bed612132565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600154600090611c88907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9e565b90506000611c94612215565b90506000816020015160ff16826000015163ffffffff16611cb59190614fe4565b90508215611dec57600154600090611cec908390700100000000000000000000000000000000900467ffffffffffffffff1661504c565b90506000836040015160ff1683611d0391906150c0565b600154611d239084906fffffffffffffffffffffffffffffffff166150c0565b611d2d9190614fe4565b600154909150600090611d7e90611d579084906fffffffffffffffffffffffffffffffff1661517c565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166122db565b90506001861115611dad57611daa611d5782876040015160ff1660018a611da59190614f9e565b6122fa565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e1f908490700100000000000000000000000000000000900467ffffffffffffffff16614f72565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161067f565b600154600090611f2e906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166151f0565b90506000611f4048633b9aca0061234f565b611f4a908361522d565b905060005a611f599088614f9e565b905080821115611f7557611f75611f708284614f9e565b612366565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611fbe949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611fbe979096959101615241565b60008061201786612394565b9050612025818686866123c6565b9695505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561209e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c29190614efa565b6120cc9083615298565b421192915050565b60008060006120e48660006123f6565b90508061211a576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166121c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067f565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260365483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156122b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d691906152d5565b905090565b60006122f06122ea8585612414565b83612424565b90505b9392505050565b6000670de0b6b3a764000061233b6123128583614fe4565b61232490670de0b6b3a764000061504c565b61233685670de0b6b3a76400006150c0565b612433565b61234590866150c0565b6122f09190614fe4565b60008183101561235f57816122f3565b5090919050565b6000805a90505b825a6123799083614f9e565b101561238f5761238882615374565b915061236d565b505050565b606081805190602001206040516020016123b091815260200190565b6040516020818303038152906040529050919050565b60006123ed846123d7878686612464565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561235f57816122f3565b600081831261235f57816122f3565b60006122f3670de0b6b3a76400008361244b86612ee2565b61245591906150c0565b61245f9190614fe4565b613126565b606060008451116124d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161067f565b60006124dc84613365565b905060006124e986613451565b905060008460405160200161250091815260200190565b60405160208183030381529060405290506000805b8451811015612e59576000858281518110612532576125326153ac565b6020026020010151905084518311156125cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161067f565b82600003612686578051805160209182012060405161261b926125f592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067f565b6127dd565b80515160201161273c57805180516020918201206040516126b0926125f592910190815260200190565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161067f565b8051845160208087019190912082519190920120146127dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161067f565b6127e960106001615298565b816020015151036129c5578451830361295d576128238160200151601081518110612816576128166153ac565b60200260200101516134b4565b965060008751116128b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067f565b600186516128c49190614f9e565b8214612952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067f565b5050505050506122f3565b6000858481518110612971576129716153ac565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061299c5761299c6153ac565b602002602001015190506129af81613614565b95506129bc600186615298565b94505050612e46565b600281602001515103612dbe5760006129dd82613639565b90506000816000815181106129f4576129f46153ac565b016020015160f81c90506000612a0b6002836153db565b612a169060026153fd565b90506000612a27848360ff1661365d565b90506000612a358a8961365d565b90506000612a438383613693565b905080835114612ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067f565b60ff851660021480612aea575060ff85166003145b15612cd95780825114612b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067f565b612b998760200151600181518110612816576128166153ac565b9c5060008d5111612c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067f565b60018c51612c3a9190614f9e565b8814612cc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067f565b5050505050505050505050506122f3565b60ff85161580612cec575060ff85166001145b15612d2b57612d188760200151600181518110612d0b57612d0b6153ac565b6020026020010151613614565b9950612d24818a615298565b9850612db3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161067f565b505050505050612e46565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161067f565b5080612e5181615374565b915050612515565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161067f565b6000808213612f4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b60006060612f5a84613747565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361315757506000919050565b680755bf798b4a1bf1e582126131c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161067f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156133835761338361486a565b6040519080825280602002602001820160405280156133c857816020015b60408051808201909152606080825260208201528152602001906001900390816133a15790505b50915060005b8181101561344a5760405180604001604052808583815181106133f3576133f36153ac565b60200260200101518152602001613422868481518110613415576134156153ac565b602002602001015161381d565b815250838281518110613437576134376153ac565b60209081029190910101526001016133ce565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156134a9578060011b82018184015160001a8060041c8253600f81166001830153505060010161347b565b509295945050505050565b606060008060006134c485613830565b9194509250905060008160018111156134df576134df615420565b1461356c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067f565b6135768284615298565b855114613605576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161067f565b6123ed8560200151848461429d565b606060208260000151106136305761362b826134b4565b61105f565b61105f82614331565b606061105f6136588360200151600081518110612816576128166153ac565b613451565b60608251821061367c575060408051602081019091526000815261105f565b6122f3838384865161368e9190614f9e565b614347565b60008082518451106136a65782516136a9565b83515b90505b808210801561373057508282815181106136c8576136c86153ac565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613707576137076153ac565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613740578160010191506136ac565b5092915050565b60008082116137b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061105f61382b8361451f565b614608565b6000806000808460000151116138ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b6020840151805160001a607f8111613913576000600160009450945094505050614296565b60b78111613b21576000613928608083614f9e565b9050808760000151116139e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161067f565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613a5c57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613b0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161067f565b5060019550935060009250614296915050565b60bf8111613e6f576000613b3660b783614f9e565b905080876000015111613bf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161067f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c60378111613d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161067f565b613d9d8184615298565b895111613e52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161067f565b613e5d836001615298565b97509550600094506142969350505050565b60f78111613f50576000613e8460c083614f9e565b905080876000015111613f3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b600195509350849250614296915050565b6000613f5d60f783614f9e565b905080876000015111614018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161067f565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036140f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c603781116141ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161067f565b6141c48184615298565b895111614279576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b614284836001615298565b97509550600194506142969350505050565b9193909250565b60608167ffffffffffffffff8111156142b8576142b861486a565b6040519080825280601f01601f1916602001820160405280156142e2576020820181803683370190505b50905081156122f35760006142f78486615298565b90506020820160005b84811015614318578281015182820152602001614300565b84811115614327576000858301525b5050509392505050565b606061105f82602001516000846000015161429d565b60608182601f0110156143b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b828284011015614422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b8183018451101561448f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161067f565b6060821580156144ae5760405191506000825260208201604052614516565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156144e75780518352602092830192016144cf565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116145ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b50604080518082019091528151815260209182019181019190915290565b6060600080600061461885613830565b91945092509050600181600181111561463357614633615420565b146146c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067f565b84516146cc8385615298565b14614759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161067f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816147705790505093506000835b865181101561485e576000806147e36040518060400160405280858c600001516147c79190614f9e565b8152602001858c602001516147dc9190615298565b9052613830565b5091509150604051806040016040528083836147ff9190615298565b8152602001848b602001516148149190615298565b815250888581518110614829576148296153ac565b602090810291909101015261483f600185615298565b935061484b8183615298565b6148559084615298565b9250505061479d565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156148e0576148e061486a565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461490a57600080fd5b50565b600082601f83011261491e57600080fd5b813567ffffffffffffffff8111156149385761493861486a565b61496960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614899565b81815284602083860101111561497e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156149ad57600080fd5b60405160c0810167ffffffffffffffff82821081831117156149d1576149d161486a565b8160405282935084358352602085013591506149ec826148e8565b81602084015260408501359150614a02826148e8565b816040840152606085013560608401526080850135608084015260a0850135915080821115614a3057600080fd5b50614a3d8582860161490d565b60a0830152505092915050565b600080600080600085870360e0811215614a6357600080fd5b863567ffffffffffffffff80821115614a7b57600080fd5b614a878a838b0161499b565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614ac057600080fd5b60408901955060c0890135925080831115614ada57600080fd5b828901925089601f840112614aee57600080fd5b8235915080821115614aff57600080fd5b508860208260051b8401011115614b1557600080fd5b959894975092955050506020019190565b60005b83811015614b41578181015183820152602001614b29565b83811115614b50576000848401525b50505050565b60008151808452614b6e816020860160208601614b26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122f36020830184614b56565b600060208284031215614bc557600080fd5b5035919050565b600060208284031215614bde57600080fd5b813567ffffffffffffffff811115614bf557600080fd5b614c018482850161499b565b949350505050565b803567ffffffffffffffff81168114614c2157600080fd5b919050565b600060208284031215614c3857600080fd5b6122f382614c09565b80358015158114614c2157600080fd5b600080600080600060a08688031215614c6957600080fd5b8535614c74816148e8565b945060208601359350614c8960408701614c09565b9250614c9760608701614c41565b9150608086013567ffffffffffffffff811115614cb357600080fd5b614cbf8882890161490d565b9150509295509295909350565b60008060008060808587031215614ce257600080fd5b8435614ced816148e8565b93506020850135614cfd816148e8565b92506040850135614d0d816148e8565b9150614d1b60608601614c41565b905092959194509250565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614d7a816049850160208701614b26565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614c2157600080fd5b600060608284031215614dbd57600080fd5b6040516060810181811067ffffffffffffffff82111715614de057614de061486a565b60405282518152614df360208401614d8b565b6020820152614e0460408401614d8b565b60408201529392505050565b600060808284031215614e2257600080fd5b6040516080810181811067ffffffffffffffff82111715614e4557614e4561486a565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e9157614e9161486a565b8360051b6020614ea2818301614899565b868152918501918181019036841115614eba57600080fd5b865b84811015614eee57803586811115614ed45760008081fd5b614ee036828b0161490d565b845250918301918301614ebc565b50979650505050505050565b600060208284031215614f0c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614f6957614f69614f13565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f9557614f95614f13565b01949350505050565b600082821015614fb057614fb0614f13565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff357614ff3614fb5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504757615047614f13565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508657615086614f13565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150ba576150ba614f13565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561510157615101614f13565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513c5761513c614f13565b6000871292508782058712848416161561515857615158614f13565b8785058712818416161561516e5761516e614f13565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b6576151b6614f13565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151ea576151ea614f13565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561522857615228614f13565b500290565b60008261523c5761523c614fb5565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261528c60c0830184614b56565b98975050505050505050565b600082198211156152ab576152ab614f13565b500190565b805163ffffffff81168114614c2157600080fd5b805160ff81168114614c2157600080fd5b600060c082840312156152e757600080fd5b60405160c0810181811067ffffffffffffffff8211171561530a5761530a61486a565b604052615316836152b0565b8152615324602084016152c4565b6020820152615335604084016152c4565b6040820152615346606084016152b0565b6060820152615357608084016152b0565b608082015261536860a08401614d8b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153a5576153a5614f13565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806153ee576153ee614fb5565b8060ff84160691505092915050565b600060ff821660ff84168082101561541757615417614f13565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", + "sourceMap": "1135:20265:110:-:0;;;4982:219;;;;;;;;;-1:-1:-1;5006:188:110;5065:1;;;5179:4;5006:10;:188::i;:::-;1135:20265;;5491:423;4396:13:36;;2762:1:158;;4396:13:36;;;;;4395:14;:40;;;;-1:-1:-1;4413:12:36;;:22;;;;:12;;:22;4395:40;4387:99;;;;-1:-1:-1;;;4387:99:36;;216:2:285;4387:99:36;;;198:21:285;255:2;235:18;;;228:30;294:34;274:18;;;267:62;-1:-1:-1;;;345:18:285;;;338:44;399:19;;4387:99:36;;;;;;;;;4496:12;:22;;-1:-1:-1;;4528:20:36;4496:22;;;4528:20;4496:22;4528:20;;;;;;5710:8:110::1;:38:::0;;-1:-1:-1;;;;;;5710:38:110;;::::1;1337:42:158;5710:38:110;::::0;;;5758:8:::1;:20:::0;;5788:12:::1;:28:::0;;-1:-1:-1;;;;;5788:28:110;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;5826:8:::1;:20:::0;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;5856:16;::::1;;5758:20:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;5856:16:110;-1:-1:-1;;;;;;5856:16:110;;;;;;;::::1;::::0;;5882:25:::1;:23;:25::i;:::-;4585:5:36::0;4569:21;;-1:-1:-1;;4569:21:36;;;4605:20;;601:4:285;589:17;;571:36;;4605:20:36;;559:2:285;544:18;4605:20:36;;;;;;;5491:423:110;;;;;:::o;8362:180:112:-;4888:13:36;;;;;;;4880:69;;;;-1:-1:-1;;;4880:69:36;;820:2:285;4880:69:36;;;802:21:285;859:2;839:18;;;832:30;898:34;878:18;;;871:62;-1:-1:-1;;;949:18:285;;;942:41;1000:19;;4880:69:36;618:407:285;4880:69:36;8442:93:112::1;::::0;;::::1;::::0;::::1;::::0;;8472:6:::1;8442:93:::0;;;-1:-1:-1;8442:93:112::1;::::0;::::1;::::0;8519:12:::1;-1:-1:-1::0;;;;;8442:93:112::1;::::0;;;;;;;-1:-1:-1;;;8433:102:112::1;;:6;:102:::0;8362:180::o;618:407:285:-;1135:20265:110;;;;;;", + "linkReferences": {} + }, + "deployedBytecode": { + "object": "0x60806040526004361061016d5760003560e01c80638b4c40b0116100cb578063a35d99df1161007f578063e9e05c4211610059578063e9e05c4214610573578063f049875014610586578063fecf9734146105b157600080fd5b8063a35d99df1461040d578063cff0ab9614610446578063e965084c146104e757600080fd5b80639b5f694a116100b05780639b5f694a1461037e5780639bf62d82146103b0578063a14238e7146103dd57600080fd5b80638b4c40b0146101925780638c3152e91461035e57600080fd5b806354fd4d50116101225780636dbffb78116101075780636dbffb78146102fe578063724c184c1461031e5780638456cb591461034957600080fd5b806354fd4d501461027e5780635c975abb146102d457600080fd5b80633f4ba83a116101535780633f4ba83a1461021c578063452a9320146102315780634870496f1461025e57600080fd5b80621c2ff61461019957806333d7e2bd146101ef57600080fd5b36610194576101923334620186a06000604051806020016040528060008152506105d1565b005b600080fd5b3480156101a557600080fd5b50603554610100900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101fb57600080fd5b506036546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022857600080fd5b5061019261086c565b34801561023d57600080fd5b506037546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026a57600080fd5b50610192610279366004614a4a565b610971565b34801561028a57600080fd5b506102c76040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b6040516101e69190614ba0565b3480156102e057600080fd5b506035546102ee9060ff1681565b60405190151581526020016101e6565b34801561030a57600080fd5b506102ee610319366004614bb3565b610fa6565b34801561032a57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101c5565b34801561035557600080fd5b50610192611065565b34801561036a57600080fd5b50610192610379366004614bcc565b611167565b34801561038a57600080fd5b506035546101c590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103bc57600080fd5b506032546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e957600080fd5b506102ee6103f8366004614bb3565b60336020526000908152604090205460ff1681565b34801561041957600080fd5b5061042d610428366004614c26565b611a2b565b60405167ffffffffffffffff90911681526020016101e6565b34801561045257600080fd5b506001546104ae906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101e6565b3480156104f357600080fd5b50610545610502366004614bb3565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101e6565b610192610581366004614c51565b6105d1565b34801561059257600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff166101c5565b3480156105bd57600080fd5b506101926105cc366004614ccc565b611a44565b8260005a905083156106885773ffffffffffffffffffffffffffffffffffffffff87161561068857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6106928351611a2b565b67ffffffffffffffff168567ffffffffffffffff161015610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161067f565b6201d4c0835111156107a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161067f565b333281146107c4575033731111000000000000000000000000000000001111015b600034888888886040516020016107df959493929190614d26565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161084f9190614ba0565b60405180910390a450506108638282611c52565b50505050505050565b60375473ffffffffffffffffffffffffffffffffffffffff163314610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e70617573650000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff16156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161067f565b6035546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101869052600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190614dab565b519050610b50610b4b36869003860186614e10565b611f7f565b8114610bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161067f565b6000610be987611fdb565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d035750805160355460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190614dab565b5114155b610d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161067f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610e589101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610e4e888a614e76565b8a6040013561200b565b610ee4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161067f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6035546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161105f9161010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190614dab565b602001516fffffffffffffffffffffffffffffffff1661202f565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff16331461110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20706175736500000000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610967565b60355460ff16156111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161067f565b600061128882611fdb565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161067f565b603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190614efa565b81602001516fffffffffffffffffffffffffffffffff1610156114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161067f565b6114ee81602001516fffffffffffffffffffffffffffffffff1661202f565b6115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60355460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff9091166004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561162c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116509190614dab565b825181519192501461170a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161067f565b61172981602001516fffffffffffffffffffffffffffffffff1661202f565b6117db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60008381526033602052604090205460ff161561187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161067f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161191c939291906120d4565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061198190841515815260200190565b60405180910390a2801580156119975750326001145b15611a24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161067f565b5050505050565b6000611a38826010614f42565b61105f90615208614f72565b600054600390610100900460ff16158015611a66575060005460ff8083169116105b611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100908117909155603280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811661dead17909155603580546036805473ffffffffffffffffffffffffffffffffffffffff89811691861691909117909155603780548a83169516949094179093558515159289169093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fffffffffffffffffffffff00000000000000000000000000000000000000000090931692909217179055611bed612132565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600154600090611c88907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9e565b90506000611c94612215565b90506000816020015160ff16826000015163ffffffff16611cb59190614fe4565b90508215611dec57600154600090611cec908390700100000000000000000000000000000000900467ffffffffffffffff1661504c565b90506000836040015160ff1683611d0391906150c0565b600154611d239084906fffffffffffffffffffffffffffffffff166150c0565b611d2d9190614fe4565b600154909150600090611d7e90611d579084906fffffffffffffffffffffffffffffffff1661517c565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166122db565b90506001861115611dad57611daa611d5782876040015160ff1660018a611da59190614f9e565b6122fa565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e1f908490700100000000000000000000000000000000900467ffffffffffffffff16614f72565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161067f565b600154600090611f2e906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166151f0565b90506000611f4048633b9aca0061234f565b611f4a908361522d565b905060005a611f599088614f9e565b905080821115611f7557611f75611f708284614f9e565b612366565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611fbe949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611fbe979096959101615241565b60008061201786612394565b9050612025818686866123c6565b9695505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561209e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c29190614efa565b6120cc9083615298565b421192915050565b60008060006120e48660006123f6565b90508061211a576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166121c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067f565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260365483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156122b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d691906152d5565b905090565b60006122f06122ea8585612414565b83612424565b90505b9392505050565b6000670de0b6b3a764000061233b6123128583614fe4565b61232490670de0b6b3a764000061504c565b61233685670de0b6b3a76400006150c0565b612433565b61234590866150c0565b6122f09190614fe4565b60008183101561235f57816122f3565b5090919050565b6000805a90505b825a6123799083614f9e565b101561238f5761238882615374565b915061236d565b505050565b606081805190602001206040516020016123b091815260200190565b6040516020818303038152906040529050919050565b60006123ed846123d7878686612464565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561235f57816122f3565b600081831261235f57816122f3565b60006122f3670de0b6b3a76400008361244b86612ee2565b61245591906150c0565b61245f9190614fe4565b613126565b606060008451116124d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161067f565b60006124dc84613365565b905060006124e986613451565b905060008460405160200161250091815260200190565b60405160208183030381529060405290506000805b8451811015612e59576000858281518110612532576125326153ac565b6020026020010151905084518311156125cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161067f565b82600003612686578051805160209182012060405161261b926125f592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067f565b6127dd565b80515160201161273c57805180516020918201206040516126b0926125f592910190815260200190565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161067f565b8051845160208087019190912082519190920120146127dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161067f565b6127e960106001615298565b816020015151036129c5578451830361295d576128238160200151601081518110612816576128166153ac565b60200260200101516134b4565b965060008751116128b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067f565b600186516128c49190614f9e565b8214612952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067f565b5050505050506122f3565b6000858481518110612971576129716153ac565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061299c5761299c6153ac565b602002602001015190506129af81613614565b95506129bc600186615298565b94505050612e46565b600281602001515103612dbe5760006129dd82613639565b90506000816000815181106129f4576129f46153ac565b016020015160f81c90506000612a0b6002836153db565b612a169060026153fd565b90506000612a27848360ff1661365d565b90506000612a358a8961365d565b90506000612a438383613693565b905080835114612ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067f565b60ff851660021480612aea575060ff85166003145b15612cd95780825114612b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067f565b612b998760200151600181518110612816576128166153ac565b9c5060008d5111612c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067f565b60018c51612c3a9190614f9e565b8814612cc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067f565b5050505050505050505050506122f3565b60ff85161580612cec575060ff85166001145b15612d2b57612d188760200151600181518110612d0b57612d0b6153ac565b6020026020010151613614565b9950612d24818a615298565b9850612db3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161067f565b505050505050612e46565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161067f565b5080612e5181615374565b915050612515565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161067f565b6000808213612f4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b60006060612f5a84613747565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361315757506000919050565b680755bf798b4a1bf1e582126131c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161067f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156133835761338361486a565b6040519080825280602002602001820160405280156133c857816020015b60408051808201909152606080825260208201528152602001906001900390816133a15790505b50915060005b8181101561344a5760405180604001604052808583815181106133f3576133f36153ac565b60200260200101518152602001613422868481518110613415576134156153ac565b602002602001015161381d565b815250838281518110613437576134376153ac565b60209081029190910101526001016133ce565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156134a9578060011b82018184015160001a8060041c8253600f81166001830153505060010161347b565b509295945050505050565b606060008060006134c485613830565b9194509250905060008160018111156134df576134df615420565b1461356c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067f565b6135768284615298565b855114613605576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161067f565b6123ed8560200151848461429d565b606060208260000151106136305761362b826134b4565b61105f565b61105f82614331565b606061105f6136588360200151600081518110612816576128166153ac565b613451565b60608251821061367c575060408051602081019091526000815261105f565b6122f3838384865161368e9190614f9e565b614347565b60008082518451106136a65782516136a9565b83515b90505b808210801561373057508282815181106136c8576136c86153ac565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613707576137076153ac565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613740578160010191506136ac565b5092915050565b60008082116137b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061105f61382b8361451f565b614608565b6000806000808460000151116138ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b6020840151805160001a607f8111613913576000600160009450945094505050614296565b60b78111613b21576000613928608083614f9e565b9050808760000151116139e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161067f565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613a5c57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613b0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161067f565b5060019550935060009250614296915050565b60bf8111613e6f576000613b3660b783614f9e565b905080876000015111613bf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161067f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c60378111613d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161067f565b613d9d8184615298565b895111613e52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161067f565b613e5d836001615298565b97509550600094506142969350505050565b60f78111613f50576000613e8460c083614f9e565b905080876000015111613f3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b600195509350849250614296915050565b6000613f5d60f783614f9e565b905080876000015111614018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161067f565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036140f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c603781116141ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161067f565b6141c48184615298565b895111614279576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b614284836001615298565b97509550600194506142969350505050565b9193909250565b60608167ffffffffffffffff8111156142b8576142b861486a565b6040519080825280601f01601f1916602001820160405280156142e2576020820181803683370190505b50905081156122f35760006142f78486615298565b90506020820160005b84811015614318578281015182820152602001614300565b84811115614327576000858301525b5050509392505050565b606061105f82602001516000846000015161429d565b60608182601f0110156143b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b828284011015614422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b8183018451101561448f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161067f565b6060821580156144ae5760405191506000825260208201604052614516565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156144e75780518352602092830192016144cf565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116145ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b50604080518082019091528151815260209182019181019190915290565b6060600080600061461885613830565b91945092509050600181600181111561463357614633615420565b146146c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067f565b84516146cc8385615298565b14614759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161067f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816147705790505093506000835b865181101561485e576000806147e36040518060400160405280858c600001516147c79190614f9e565b8152602001858c602001516147dc9190615298565b9052613830565b5091509150604051806040016040528083836147ff9190615298565b8152602001848b602001516148149190615298565b815250888581518110614829576148296153ac565b602090810291909101015261483f600185615298565b935061484b8183615298565b6148559084615298565b9250505061479d565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156148e0576148e061486a565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461490a57600080fd5b50565b600082601f83011261491e57600080fd5b813567ffffffffffffffff8111156149385761493861486a565b61496960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614899565b81815284602083860101111561497e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156149ad57600080fd5b60405160c0810167ffffffffffffffff82821081831117156149d1576149d161486a565b8160405282935084358352602085013591506149ec826148e8565b81602084015260408501359150614a02826148e8565b816040840152606085013560608401526080850135608084015260a0850135915080821115614a3057600080fd5b50614a3d8582860161490d565b60a0830152505092915050565b600080600080600085870360e0811215614a6357600080fd5b863567ffffffffffffffff80821115614a7b57600080fd5b614a878a838b0161499b565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614ac057600080fd5b60408901955060c0890135925080831115614ada57600080fd5b828901925089601f840112614aee57600080fd5b8235915080821115614aff57600080fd5b508860208260051b8401011115614b1557600080fd5b959894975092955050506020019190565b60005b83811015614b41578181015183820152602001614b29565b83811115614b50576000848401525b50505050565b60008151808452614b6e816020860160208601614b26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122f36020830184614b56565b600060208284031215614bc557600080fd5b5035919050565b600060208284031215614bde57600080fd5b813567ffffffffffffffff811115614bf557600080fd5b614c018482850161499b565b949350505050565b803567ffffffffffffffff81168114614c2157600080fd5b919050565b600060208284031215614c3857600080fd5b6122f382614c09565b80358015158114614c2157600080fd5b600080600080600060a08688031215614c6957600080fd5b8535614c74816148e8565b945060208601359350614c8960408701614c09565b9250614c9760608701614c41565b9150608086013567ffffffffffffffff811115614cb357600080fd5b614cbf8882890161490d565b9150509295509295909350565b60008060008060808587031215614ce257600080fd5b8435614ced816148e8565b93506020850135614cfd816148e8565b92506040850135614d0d816148e8565b9150614d1b60608601614c41565b905092959194509250565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614d7a816049850160208701614b26565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614c2157600080fd5b600060608284031215614dbd57600080fd5b6040516060810181811067ffffffffffffffff82111715614de057614de061486a565b60405282518152614df360208401614d8b565b6020820152614e0460408401614d8b565b60408201529392505050565b600060808284031215614e2257600080fd5b6040516080810181811067ffffffffffffffff82111715614e4557614e4561486a565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e9157614e9161486a565b8360051b6020614ea2818301614899565b868152918501918181019036841115614eba57600080fd5b865b84811015614eee57803586811115614ed45760008081fd5b614ee036828b0161490d565b845250918301918301614ebc565b50979650505050505050565b600060208284031215614f0c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614f6957614f69614f13565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f9557614f95614f13565b01949350505050565b600082821015614fb057614fb0614f13565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff357614ff3614fb5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504757615047614f13565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508657615086614f13565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150ba576150ba614f13565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561510157615101614f13565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513c5761513c614f13565b6000871292508782058712848416161561515857615158614f13565b8785058712818416161561516e5761516e614f13565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b6576151b6614f13565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151ea576151ea614f13565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561522857615228614f13565b500290565b60008261523c5761523c614fb5565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261528c60c0830184614b56565b98975050505050505050565b600082198211156152ab576152ab614f13565b500190565b805163ffffffff81168114614c2157600080fd5b805160ff81168114614c2157600080fd5b600060c082840312156152e757600080fd5b60405160c0810181811067ffffffffffffffff8211171561530a5761530a61486a565b604052615316836152b0565b8152615324602084016152c4565b6020820152615335604084016152c4565b6040820152615346606084016152b0565b6060820152615357608084016152b0565b608082015261536860a08401614d8b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153a5576153a5614f13565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806153ee576153ee614fb5565b8060ff84160691505092915050565b600060ff821660ff84168082101561541757615417614f13565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", + "sourceMap": "1135:20265:110:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7915:86;7934:10;7946:9;1866:7;7984:5;7991:9;;;;;;;;;;;;7915:18;:86::i;:::-;1135:20265;;;;;5989:92;;;;;;;;;;-1:-1:-1;6066:8:110;;;;;;;5989:92;;;214:42:285;202:55;;;184:74;;172:2;157:18;5989:92:110;;;;;;;;2856:32;;;;;;;;;;-1:-1:-1;2856:32:110;;;;;;;;6664:180;;;;;;;;;;;;;:::i;3007:23::-;;;;;;;;;;-1:-1:-1;3007:23:110;;;;;;;;9088:3746;;;;;;;;;;-1:-1:-1;9088:3746:110;;;;;:::i;:::-;;:::i;4878:41::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;2618:18::-;;;;;;;;;;-1:-1:-1;2618:18:110;;;;;;;;;;;5224:14:285;;5217:22;5199:41;;5187:2;5172:18;2618::110;5059:187:285;20785:180:110;;;;;;;;;;-1:-1:-1;20785:180:110;;;;;:::i;:::-;;:::i;6321:84::-;;;;;;;;;;-1:-1:-1;6390:8:110;;;;6321:84;;6447:173;;;;;;;;;;;;;:::i;12947:4839::-;;;;;;;;;;-1:-1:-1;12947:4839:110;;;;;:::i;:::-;;:::i;2732:30::-;;;;;;;;;;-1:-1:-1;2732:30:110;;;;;;;;;;;2129:23;;;;;;;;;;-1:-1:-1;2129:23:110;;;;;;;;2243:52;;;;;;;;;;-1:-1:-1;2243:52:110;;;;;:::i;:::-;;;;;;;;;;;;;;;;7337:120;;;;;;;;;;-1:-1:-1;7337:120:110;;;;;:::i;:::-;;:::i;:::-;;;6539:18:285;6527:31;;;6509:50;;6497:2;6482:18;7337:120:110;6365:200:285;2999:28:112;;;;;;;;;;-1:-1:-1;2999:28:112;;;;;;;;;;;;;;;;;;;;;;;;;6798:34:285;6786:47;;;6768:66;;6853:18;6907:15;;;6902:2;6887:18;;6880:43;6959:15;;6939:18;;;6932:43;6756:2;6741:18;2999:28:112;6570:411:285;2377:61:110;;;;;;;;;;-1:-1:-1;2377:61:110;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7188:25:285;;;7232:34;7302:15;;;7297:2;7282:18;;7275:43;7354:15;;7334:18;;;7327:43;7176:2;7161:18;2377:61:110;6986:390:285;18516:1971:110;;;;;;:::i;:::-;;:::i;6154:98::-;;;;;;;;;;-1:-1:-1;6233:12:110;;;;6154:98;;5491:423;;;;;;;;;;-1:-1:-1;5491:423:110;;;;;:::i;:::-;;:::i;18516:1971::-;18722:9;3417:18:112;3438:9;3417:30;;18876:11:110::1;18872:136;;;18911:17;::::0;::::1;::::0;18903:94:::1;;;::::0;;::::1;::::0;;9067:2:285;18903:94:110::1;::::0;::::1;9049:21:285::0;9086:18;;;9079:30;;;;9145:34;9125:18;;;9118:62;9216:34;9196:18;;;9189:62;9268:19;;18903:94:110::1;;;;;;;;;19176:37;19199:5;:12;19176:15;:37::i;:::-;19163:50;;:9;:50;;;;19155:98;;;::::0;::::1;::::0;;9500:2:285;19155:98:110::1;::::0;::::1;9482:21:285::0;9539:2;9519:18;;;9512:30;9578:34;9558:18;;;9551:62;9649:5;9629:18;;;9622:33;9672:19;;19155:98:110::1;9298:399:285::0;19155:98:110::1;19648:7;19632:5;:12;:23;;19624:66;;;::::0;::::1;::::0;;9904:2:285;19624:66:110::1;::::0;::::1;9886:21:285::0;9943:2;9923:18;;;9916:30;9982:32;9962:18;;;9955:60;10032:18;;19624:66:110::1;9702:354:285::0;19624:66:110::1;19796:10;19834:9;19820:23:::0;::::1;19816:108;;-1:-1:-1::0;19902:10:110::1;741:42:204::0;1213:27;19816:108:110::1;20181:23;20224:9;20235:6;20243:9;20254:11;20267:5;20207:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;20181:92;;1716:1;20447:3;20420:60;;20441:4;20420:60;;;20469:10;20420:60;;;;;;:::i;:::-;;;;;;;;18737:1750;;3548:29:112::0;3557:7;3566:10;3548:8;:29::i;:::-;3339:245;18516:1971:110;;;;;;:::o;6664:180::-;6724:8;;;;6710:10;:22;6702:76;;;;;;;11133:2:285;6702:76:110;;;11115:21:285;11172:2;11152:18;;;11145:30;11211:34;11191:18;;;11184:62;11282:11;11262:18;;;11255:39;11311:19;;6702:76:110;10931:405:285;6702:76:110;6788:6;:14;;;;;;6817:20;;6826:10;184:74:285;;6817:20:110;;172:2:285;157:18;6817:20:110;;;;;;;;6664:180::o;9088:3746::-;4748:6;;;;:15;4740:50;;;;;;;11543:2:285;4740:50:110;;;11525:21:285;11582:2;11562:18;;;11555:30;11621:24;11601:18;;;11594:52;11663:18;;4740:50:110;11341:346:285;4740:50:110;9620:4:::1;9598:27;;:3;:10;;;:27;;::::0;9590:103:::1;;;::::0;::::1;::::0;;11894:2:285;9590:103:110::1;::::0;::::1;11876:21:285::0;11933:2;11913:18;;;11906:30;11972:34;11952:18;;;11945:62;12043:33;12023:18;;;12016:61;12094:19;;9590:103:110::1;11692:427:285::0;9590:103:110::1;9891:8;::::0;:36:::1;::::0;;;;::::1;::::0;::::1;12270:25:285::0;;;9870:18:110::1;::::0;9891:8:::1;::::0;::::1;;;::::0;:20:::1;::::0;12243:18:285;;9891:36:110::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47:::0;;-1:-1:-1;10072:45:110::1;;;::::0;;::::1;::::0;::::1;10100:16:::0;10072:45:::1;:::i;:::-;:27;:45::i;:::-;10058:10;:59;10037:135;;;::::0;::::1;::::0;;13978:2:285;10037:135:110::1;::::0;::::1;13960:21:285::0;14017:2;13997:18;;;13990:30;14056:34;14036:18;;;14029:62;14127:11;14107:18;;;14100:39;14156:19;;10037:135:110::1;13776:405:285::0;10037:135:110::1;10283:22;10308:27;10331:3;10308:22;:27::i;:::-;10345:40;10388:33:::0;;;:17:::1;:33;::::0;;;;;;;;10345:76;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;::::1;;::::0;;;;;;;10283:52;;-1:-1:-1;10345:76:110;10975:31;;:145:::1;;-1:-1:-1::0;11093:27:110;;11026:8:::1;::::0;11047:30:::1;::::0;;::::1;::::0;11026:52;;;;;14362:34:285;14350:47;;;11026:52:110::1;::::0;::::1;14332:66:285::0;11026:8:110::1;::::0;;::::1;;;::::0;:20:::1;::::0;14305:18:285;;11026:52:110::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:63:::0;:94:::1;;10975:145;10954:247;;;::::0;::::1;::::0;;14611:2:285;10954:247:110::1;::::0;::::1;14593:21:285::0;14650:2;14630:18;;;14623:30;14689:34;14669:18;;;14662:62;14760:25;14740:18;;;14733:53;14803:19;;10954:247:110::1;14409:419:285::0;10954:247:110::1;11481:147;::::0;;::::1;::::0;::::1;15007:25:285::0;;;11437:18:110::1;15048::285::0;;;15041:34;;;14980:18;;11481:147:110::1;::::0;;;;;::::1;::::0;;;;;;11458:180;;11481:147:::1;11458:180:::0;;::::1;::::0;12046:22;;::::1;12270:25:285::0;;;11458:180:110;-1:-1:-1;11991:161:110::1;::::0;12243:18:285;12046:22:110::1;::::0;;;;;::::1;::::0;;;11991:161;;::::1;::::0;;;::::1;::::0;;::::1;12046:22;11991:161:::0;::::1;::::0;12046:22;11991:161:::1;12079:16:::0;;11991:161:::1;:::i;:::-;12097:16;:41;;;11991:37;:161::i;:::-;11970:258;;;::::0;::::1;::::0;;16409:2:285;11970:258:110::1;::::0;::::1;16391:21:285::0;16448:2;16428:18;;;16421:30;16487:34;16467:18;;;16460:62;16558:20;16538:18;;;16531:48;16596:19;;11970:258:110::1;16207:414:285::0;11970:258:110::1;12546:165;::::0;;::::1;::::0;::::1;::::0;;;;;::::1;12632:15;12546:165:::0;::::1;;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;;-1:-1:-1;12510:33:110;;;:17:::1;:33:::0;;;;;:201;;;;;;;;;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;;::::0;;::::1;::::0;;;;12816:10;;::::1;::::0;12804;;::::1;::::0;12771:56;;::::1;::::0;;::::1;::::0;;;::::1;::::0;12528:14;;12771:56:::1;::::0;-1:-1:-1;12771:56:110::1;9353:3481;;;;9088:3746:::0;;;;;:::o;20785:180::-;20911:8;;:36;;;;;;;;12270:25:285;;;20859:4:110;;20882:76;;20911:8;;;;;;;:20;;12243:18:285;;20911:36:110;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;;;20882:76;;:28;:76::i;:::-;20875:83;20785:180;-1:-1:-1;;20785:180:110:o;6447:173::-;6505:8;;;;6491:10;:22;6483:74;;;;;;;16828:2:285;6483:74:110;;;16810:21:285;16867:2;16847:18;;;16840:30;16906:34;16886:18;;;16879:62;16977:9;16957:18;;;16950:37;17004:19;;6483:74:110;16626:403:285;6483:74:110;6567:6;:13;;;;6576:4;6567:13;;;6595:18;;6602:10;184:74:285;;6595:18:110;;172:2:285;157:18;6595::110;14:250:285;12947:4839:110;4748:6;;;;:15;4740:50;;;;;;;11543:2:285;4740:50:110;;;11525:21:285;11582:2;11562:18;;;11555:30;11621:24;11601:18;;;11594:52;11663:18;;4740:50:110;11341:346:285;4740:50:110;13315:8:::1;::::0;:39:::1;:8;1337:42:158;13315:39:110;13294:137;;;::::0;::::1;::::0;;17236:2:285;13294:137:110::1;::::0;::::1;17218:21:285::0;17275:2;17255:18;;;17248:30;17314:34;17294:18;;;17287:62;17385:33;17365:18;;;17358:61;17436:19;;13294:137:110::1;17034:427:285::0;13294:137:110::1;13514:22;13539:27;13562:3;13539:22;:27::i;:::-;13576:40;13619:33:::0;;;:17:::1;:33;::::0;;;;;;;13576:76;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;::::1;;::::0;;;;;;;13514:52;;-1:-1:-1;13902:31:110;;13894:94:::1;;;::::0;::::1;::::0;;17668:2:285;13894:94:110::1;::::0;::::1;17650:21:285::0;17707:2;17687:18;;;17680:30;17746:34;17726:18;;;17719:62;17817:20;17797:18;;;17790:48;17855:19;;13894:94:110::1;17466:414:285::0;13894:94:110::1;14305:8;;;;;;;;;;;:26;;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14275:16;:26;;;:58;;;;14254:180;;;::::0;::::1;::::0;;18276:2:285;14254:180:110::1;::::0;::::1;18258:21:285::0;18315:2;18295:18;;;18288:30;18354:34;18334:18;;;18327:62;18425:34;18405:18;;;18398:62;18497:13;18476:19;;;18469:42;18528:19;;14254:180:110::1;18074:479:285::0;14254:180:110::1;14824:56;14853:16;:26;;;14824:56;;:28;:56::i;:::-;14803:172;;;::::0;::::1;::::0;;18760:2:285;14803:172:110::1;::::0;::::1;18742:21:285::0;18799:2;18779:18;;;18772:30;18838:34;18818:18;;;18811:62;18909:34;18889:18;;;18882:62;18981:7;18960:19;;;18953:36;19006:19;;14803:172:110::1;18558:473:285::0;14803:172:110::1;15185:8;::::0;15206:30:::1;::::0;;::::1;::::0;15185:52;;;;;14362:34:285;14350:47;;;15185:52:110::1;::::0;::::1;14332:66:285::0;15146:36:110::1;::::0;15185:8:::1;::::0;::::1;;;::::0;:20:::1;::::0;14305:18:285;;15185:52:110::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15548:27:::0;;15525:19;;15146:91;;-1:-1:-1;15525:50:110::1;15504:170;;;::::0;::::1;::::0;;19238:2:285;15504:170:110::1;::::0;::::1;19220:21:285::0;19277:2;19257:18;;;19250:30;19316:34;19296:18;;;19289:62;19387:34;19367:18;;;19360:62;19459:11;19438:19;;;19431:40;19488:19;;15504:170:110::1;19036:477:285::0;15504:170:110::1;15773:48;15802:8;:18;;;15773:48;;:28;:48::i;:::-;15752:162;;;::::0;::::1;::::0;;19720:2:285;15752:162:110::1;::::0;::::1;19702:21:285::0;19759:2;19739:18;;;19732:30;19798:34;19778:18;;;19771:62;19869:34;19849:18;;;19842:62;19941:5;19920:19;;;19913:34;19964:19;;15752:162:110::1;19518:471:285::0;15752:162:110::1;16030:36;::::0;;;:20:::1;:36;::::0;;;;;::::1;;:45;16022:111;;;::::0;::::1;::::0;;20196:2:285;16022:111:110::1;::::0;::::1;20178:21:285::0;20235:2;20215:18;;;20208:30;20274:34;20254:18;;;20247:62;20345:23;20325:18;;;20318:51;20386:19;;16022:111:110::1;19994:417:285::0;16022:111:110::1;16213:36;::::0;;;:20:::1;:36;::::0;;;;;;;:43;;;::::1;16252:4;16213:43;::::0;;16361:10;;::::1;::::0;16350:8:::1;:21:::0;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;17030:10;::::1;::::0;17042:12:::1;::::0;::::1;::::0;17056:9:::1;::::0;::::1;::::0;17067:8:::1;::::0;::::1;::::0;17006:70:::1;::::0;17030:10;17042:12;17056:9;17006:23:::1;:70::i;:::-;17144:8;:38:::0;;;::::1;1337:42:158;17144:38:110;::::0;;17341:44:::1;::::0;16991:85;;-1:-1:-1;17361:14:110;;17341:44:::1;::::0;::::1;::::0;16991:85;5224:14:285;5217:22;5199:41;;5187:2;5172:18;;5059:187;17341:44:110::1;;;;;;;;17649:16:::0;::::1;::::0;::::1;:61;;-1:-1:-1::0;17669:9:110::1;1015:1:158;17669:41:110;17649:61;17645:135;;;17726:43;::::0;::::1;::::0;;20618:2:285;17726:43:110::1;::::0;::::1;20600:21:285::0;20657:2;20637:18;;;20630:30;20696:34;20676:18;;;20669:62;20767:3;20747:18;;;20740:31;20788:19;;17726:43:110::1;20416:397:285::0;17645:135:110::1;13049:4737;;;;12947:4839:::0;:::o;7337:120::-;7402:6;7427:15;:10;7440:2;7427:15;:::i;:::-;:23;;7445:5;7427:23;:::i;5491:423::-;4396:13:36;;2762:1:158;;4396:13:36;;;;;4395:14;:40;;;;-1:-1:-1;4413:12:36;;:22;;;;:12;;:22;4395:40;4387:99;;;;;;;21725:2:285;4387:99:36;;;21707:21:285;21764:2;21744:18;;;21737:30;21803:34;21783:18;;;21776:62;21874:16;21854:18;;;21847:44;21908:19;;4387:99:36;21523:410:285;4387:99:36;4496:12;:22;;4528:20;;4496:22;;;4528:20;4496:22;4528:20;;;;;;5710:8:110::1;:38:::0;;;;;::::1;1337:42:158;5710:38:110;::::0;;;5758:8:::1;:20:::0;;5788:12:::1;:28:::0;;5710:38:::1;5788:28:::0;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;5826:8:::1;:20:::0;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;5856:16;::::1;;5758:20:::0;;::::1;::::0;;::::1;4496:22:36::0;5856:16:110;;;;;;;;;::::1;::::0;;5882:25:::1;:23;:25::i;:::-;4585:5:36::0;4569:21;;;;;;4605:20;;22110:4:285;22098:17;;22080:36;;4605:20:36;;22068:2:285;22053:18;4605:20:36;;;;;;;5491:423:110;;;;;:::o;3817:4037:112:-;3984:6;:19;3949:17;;3969:34;;3984:19;;;;;3969:12;:34;:::i;:::-;3949:54;;4014:28;4045:17;:15;:17::i;:::-;4014:48;;4072:26;4171:6;:27;;;4163:36;;4128:6;:23;;;4120:32;;4113:87;;;;:::i;:::-;4072:128;-1:-1:-1;4215:13:112;;4211:2229;;4572:6;:20;4535:19;;4557:59;;4597:19;;4572:20;;;;;4557:59;:::i;:::-;4535:81;;4630:19;4761:6;:34;;;4753:43;;4724:19;:73;;;;:::i;:::-;4668:6;:18;4653:50;;4691:12;;4668:18;;4653:50;:::i;:::-;4652:146;;;;:::i;:::-;5017:6;:18;4630:168;;-1:-1:-1;4939:17:112;;4959:232;;5002:50;;4630:168;;5017:18;;5002:50;:::i;:::-;5091:6;:21;;;5083:30;;5153:6;:21;;;5145:30;;4959:16;:232::i;:::-;4939:252;;5468:1;5456:9;:13;5452:741;;;5741:437;5788:239;5845:10;5910:6;:34;;;5902:43;;6002:1;5990:9;:13;;;;:::i;:::-;5788:16;:239::i;5741:437::-;5728:450;;5452:741;6286:49;;6387:42;6349:24;6416:12;6387:42;;;6286:6;6387:42;-1:-1:-1;;4211:2229:112;6534:6;:31;;6558:7;;6534:6;:20;;:31;;6558:7;;6534:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;6652:6;:23;;;6644:32;;6611:6;:20;;;;;;;;;;;;6603:29;;6596:81;;6575:190;;;;;;;24367:2:285;6575:190:112;;;24349:21:285;24406:2;24386:18;;;24379:30;24445:34;24425:18;;;24418:62;24516:32;24496:18;;;24489:60;24566:19;;6575:190:112;24165:426:285;6575:190:112;6877:6;:18;6827:20;;6850:46;;6877:18;;6850:16;;;:46;:::i;:::-;6827:69;;7378:15;7411:31;7420:13;7435:6;7411:8;:31::i;:::-;7396:46;;:12;:46;:::i;:::-;7378:64;;7722:15;7754:9;7740:23;;:11;:23;:::i;:::-;7722:41;;7787:7;7777;:17;7773:75;;;7810:27;7819:17;7829:7;7819;:17;:::i;:::-;7810:8;:27::i;:::-;3881:3973;;;;;;3817:4037;;:::o;4937:384:162:-;5036:7;5113:16;:24;;;5155:16;:26;;;5199:16;:41;;;5258:16;:32;;;5085:219;;;;;;;;;;25185:25:285;;;25241:2;25226:18;;25219:34;;;;25284:2;25269:18;;25262:34;25327:2;25312:18;;25305:34;25172:3;25157:19;;24954:391;5085:219:162;;;;;;;;;;;;;5062:252;;;;;;5055:259;;4937:384;;;:::o;4432:211::-;4566:9;;4577:10;;;;;4589;;;;;4601:9;;;;4612:12;;;;4626:8;;;;4555:80;;4519:7;;4555:80;;4566:9;;4577:10;4626:8;4555:80;;:::i;1041:343:171:-;1234:11;1261:16;1280:19;1294:4;1280:13;:19::i;:::-;1261:38;;1318:59;1350:3;1355:6;1363;1371:5;1318:31;:59::i;:::-;1309:68;1041:343;-1:-1:-1;;;;;;1041:343:171:o;21218:180:110:-;21299:4;21353:8;;;;;;;;;;;:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21340:51;;:10;:51;:::i;:::-;21322:15;:69;;21218:180;-1:-1:-1;;21218:180:110:o;4419:2320:165:-;4589:4;4609:13;4632:15;4650:21;4660:7;4669:1;4650:9;:21::i;:::-;4632:39;;4782:10;4772:1146;;4894:10;4891:1;4884:21;5009:2;5005;4998:14;5747:56;5743:2;5736:68;5900:3;5896:2;5889:15;4772:1146;6666:4;6630;6589:9;6583:16;6549:2;6538:9;6534:18;6491:6;6449:7;6415:5;6389:309;6361:337;4419:2320;-1:-1:-1;;;;;;;4419:2320:165:o;8362:180:112:-;4888:13:36;;;;;;;4880:69;;;;;;;26346:2:285;4880:69:36;;;26328:21:285;26385:2;26365:18;;;26358:30;26424:34;26404:18;;;26397:62;26495:13;26475:18;;;26468:41;26526:19;;4880:69:36;26144:407:285;4880:69:36;8442:93:112::1;::::0;;::::1;::::0;::::1;::::0;;8472:6:::1;8442:93:::0;;;-1:-1:-1;8442:93:112::1;::::0;::::1;::::0;8519:12:::1;8442:93;;::::0;;;;;;;8433:102;::::1;;:6;:102:::0;8362:180::o;8548:152:110:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8664:12:110;;:29;;;;;;;-1:-1:-1;;8664:12:110;;;;;:27;;:29;;;;;-1:-1:-1;;8664:29:110;;;;;;:12;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8657:36;;8548:152;:::o;537:161:154:-;616:6;641:50;656:28;671:6;679:4;656:14;:28::i;:::-;686:4;641:14;:50::i;:::-;634:57;;537:161;;;;;;:::o;1040:228::-;1138:6;1257:4;1180:72;1213:19;1220:12;1257:4;1213:19;:::i;:::-;1205:28;;:4;:28;:::i;:::-;1235:16;:9;1247:4;1235:16;:::i;:::-;1180:24;:72::i;:::-;1164:89;;:12;:89;:::i;:::-;1163:98;;;;:::i;413:105:62:-;471:7;502:1;497;:6;;:14;;510:1;497:14;;;-1:-1:-1;506:1:62;;490:21;-1:-1:-1;413:105:62:o;407:192:155:-;461:9;484:18;505:9;484:30;;524:69;556:7;544:9;531:22;;:10;:22;:::i;:::-;:32;524:69;;;579:3;;;:::i;:::-;;;524:69;;;451:148;;407:192;:::o;2052:142:171:-;2116:18;2181:4;2171:15;;;;;;2154:33;;;;;;28115:19:285;;28159:2;28150:12;;27986:182;2154:33:171;;;;;;;;;;;;;2146:41;;2052:142;;;:::o;2253:281:170:-;2446:11;2482:45;2494:6;2502:24;2506:4;2512:6;2520:5;2502:3;:24::i;:::-;6693:17:156;;;;;;;6672;;;;;;;;;;:38;;6569:148;2482:45:170;2473:54;2253:281;-1:-1:-1;;;;;2253:281:170:o;3615:365:165:-;3696:4;3712:15;3931:2;3916:12;3909:5;3905:24;3901:33;3896:2;3887:7;3883:16;3879:56;3874:2;3867:5;3863:14;3860:76;3853:84;;3615:365;-1:-1:-1;;;;3615:365:165:o;311:102:64:-;367:6;397:1;392;:6;;:14;;405:1;392:14;;491:101;547:6;576:1;572;:5;:13;;584:1;572:13;;1208:273:88;1267:6;1391:36;491:4;1410:1;1399:8;1405:1;1399:5;:8::i;:::-;:12;;;;:::i;:::-;1398:28;;;;:::i;:::-;1391:6;:36::i;2830:6314:170:-;2923:19;2976:1;2962:4;:11;:15;2954:49;;;;;;;28375:2:285;2954:49:170;;;28357:21:285;28414:2;28394:18;;;28387:30;28453:23;28433:18;;;28426:51;28494:18;;2954:49:170;28173:345:285;2954:49:170;3014:23;3040:19;3052:6;3040:11;:19::i;:::-;3014:45;;3069:16;3088:21;3104:4;3088:15;:21::i;:::-;3069:40;;3119:26;3165:5;3148:23;;;;;;28115:19:285;;28159:2;28150:12;;27986:182;3148:23:170;;;;;;;;;;;;;3119:52;;3181:23;3295:9;3290:5790;3314:5;:12;3310:1;:16;3290:5790;;;3347:27;3377:5;3383:1;3377:8;;;;;;;;:::i;:::-;;;;;;;3347:38;;3516:3;:10;3497:15;:29;;3489:88;;;;;;;28914:2:285;3489:88:170;;;28896:21:285;28953:2;28933:18;;;28926:30;28992:34;28972:18;;;28965:62;29063:16;29043:18;;;29036:44;29097:19;;3489:88:170;28712:410:285;3489:88:170;3596:15;3615:1;3596:20;3592:837;;3768:19;;3758:30;;;;;;;3741:48;;3729:76;;3741:48;;3758:30;3741:48;28115:19:285;;;28159:2;28150:12;;27986:182;3741:48:170;;;;;;;;;;;;;3791:13;6693:17:156;;;;;;;6672;;;;;;;;;;:38;;6569:148;3729:76:170;3700:176;;;;;;;29329:2:285;3700:176:170;;;29311:21:285;29368:2;29348:18;;;29341:30;29407:31;29387:18;;;29380:59;29456:18;;3700:176:170;29127:353:285;3700:176:170;3592:837;;;3901:19;;:26;3931:2;-1:-1:-1;3897:532:170;;4097:19;;4087:30;;;;;;;4070:48;;4058:76;;4070:48;;4087:30;4070:48;28115:19:285;;;28159:2;28150:12;;27986:182;4058:76:170;4029:186;;;;;;;29687:2:285;4029:186:170;;;29669:21:285;29726:2;29706:18;;;29699:30;29765:34;29745:18;;;29738:62;29836:9;29816:18;;;29809:37;29863:19;;4029:186:170;29485:403:285;3897:532:170;4336:19;;6693:17:156;;;;;;;;;;6672;;;;;;;:38;4316:98:170;;;;;;;30095:2:285;4316:98:170;;;30077:21:285;30134:2;30114:18;;;30107:30;30173:34;30153:18;;;30146:62;30244:8;30224:18;;;30217:36;30270:19;;4316:98:170;29893:402:285;4316:98:170;936:14;803:2;949:1;936:14;:::i;:::-;4447:11;:19;;;:26;:48;4443:4627;;4538:3;:10;4519:15;:29;4515:1346;;5047:52;5067:11;:19;;;803:2;5067:31;;;;;;;;:::i;:::-;;;;;;;5047:19;:52::i;:::-;5038:61;;5145:1;5129:6;:13;:17;5121:89;;;;;;;30502:2:285;5121:89:170;;;30484:21:285;30541:2;30521:18;;;30514:30;30580:34;30560:18;;;30553:62;30651:29;30631:18;;;30624:57;30698:19;;5121:89:170;30300:423:285;5121:89:170;5322:1;5307:5;:12;:16;;;;:::i;:::-;5302:1;:21;5294:92;;;;;;;30930:2:285;5294:92:170;;;30912:21:285;30969:2;30949:18;;;30942:30;31008:34;30988:18;;;30981:62;31079:28;31059:18;;;31052:56;31125:19;;5294:92:170;30728:422:285;5294:92:170;5409:13;;;;;;;;4515:1346;5609:15;5633:3;5637:15;5633:20;;;;;;;;:::i;:::-;;;;;;;;;5627:27;;5609:45;;5676:33;5712:11;:19;;;5732:9;5712:30;;;;;;;;;;:::i;:::-;;;;;;;5676:66;;5780:20;5791:8;5780:10;:20::i;:::-;5764:36;-1:-1:-1;5822:20:170;5841:1;5822:20;;:::i;:::-;;;5447:414;;4443:4627;;;1105:1;5885:11;:19;;;:26;:59;5881:3189;;5964:17;5984:25;5997:11;5984:12;:25::i;:::-;5964:45;;6027:12;6048:4;6053:1;6048:7;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;6074:12:170;6094:10;6103:1;6048:7;6094:10;:::i;:::-;6089:16;;:1;:16;:::i;:::-;6074:31;;6123:26;6152:25;6164:4;6170:6;6152:25;;:11;:25::i;:::-;6123:54;;6195:25;6223:33;6235:3;6240:15;6223:11;:33::i;:::-;6195:61;;6274:26;6303:51;6326:13;6341:12;6303:22;:51::i;:::-;6274:80;;6661:18;6637:13;:20;:42;6608:171;;;;;;;31719:2:285;6608:171:170;;;31701:21:285;31758:2;31738:18;;;31731:30;31797:34;31777:18;;;31770:62;31868:28;31848:18;;;31841:56;31914:19;;6608:171:170;31517:422:285;6608:171:170;6802:26;;;1447:1;6802:26;;:55;;-1:-1:-1;6832:25:170;;;1553:1;6832:25;6802:55;6798:2169;;;7498:18;7475:12;:19;:41;7442:185;;;;;;;32146:2:285;7442:185:170;;;32128:21:285;32185:2;32165:18;;;32158:30;32224:34;32204:18;;;32197:62;32295:31;32275:18;;;32268:59;32344:19;;7442:185:170;31944:425:285;7442:185:170;7985:43;8005:11;:19;;;8025:1;8005:22;;;;;;;;:::i;7985:43::-;7976:52;;8074:1;8058:6;:13;:17;8050:87;;;;;;;32576:2:285;8050:87:170;;;32558:21:285;32615:2;32595:18;;;32588:30;32654:34;32634:18;;;32627:62;32725:27;32705:18;;;32698:55;32770:19;;8050:87:170;32374:421:285;8050:87:170;8249:1;8234:5;:12;:16;;;;:::i;:::-;8229:1;:21;8221:90;;;;;;;33002:2:285;8221:90:170;;;32984:21:285;33041:2;33021:18;;;33014:30;33080:34;33060:18;;;33053:62;33151:26;33131:18;;;33124:54;33195:19;;8221:90:170;32800:420:285;8221:90:170;8334:13;;;;;;;;;;;;;;6798:2169;8376:31;;;;;:65;;-1:-1:-1;8411:30:170;;;1339:1;8411:30;8376:65;8372:595;;;8748:34;8759:11;:19;;;8779:1;8759:22;;;;;;;;:::i;:::-;;;;;;;8748:10;:34::i;:::-;8732:50;-1:-1:-1;8804:37:170;8823:18;8804:37;;:::i;:::-;;;8372:595;;;8888:60;;;;;33427:2:285;8888:60:170;;;33409:21:285;33466:2;33446:18;;;33439:30;33505:34;33485:18;;;33478:62;33576:20;33556:18;;;33549:48;33614:19;;8888:60:170;33225:414:285;8372:595:170;5946:3035;;;;;;5881:3189;;;9005:50;;;;;33846:2:285;9005:50:170;;;33828:21:285;33885:2;33865:18;;;33858:30;33924:34;33904:18;;;33897:62;33995:10;33975:18;;;33968:38;34023:19;;9005:50:170;33644:404:285;5881:3189:170;-1:-1:-1;3328:3:170;;;;:::i;:::-;;;;3290:5790;;;-1:-1:-1;9090:47:170;;;;;34255:2:285;9090:47:170;;;34237:21:285;34294:2;34274:18;;;34267:30;34333:34;34313:18;;;34306:62;34404:7;34384:18;;;34377:35;34429:19;;9090:47:170;34053:401:285;4596:2947:88;4644:8;4700:1;4696;:5;4688:27;;;;;;;34661:2:285;4688:27:88;;;34643:21:285;34700:1;34680:18;;;34673:29;34738:11;34718:18;;;34711:39;34767:18;;4688:27:88;34459:332:285;4688:27:88;5107:8;5145:2;5125:16;5138:1;5125:4;:16::i;:::-;5118:29;5175:3;:7;;;5161:22;;;;5208:17;;;6001:31;5997:35;;6052:5;;5459:2;6051:13;;;6068:32;6050:50;6120:5;;6119:13;;6136:33;6118:51;6189:5;;6188:13;;6205:33;6187:51;6258:5;;6257:13;;6274:33;6256:51;6327:5;;6326:13;;6343:32;6325:50;6395:5;;6394:13;;6411:30;6393:48;5398:31;5394:35;;5449:5;;5448:13;;5465:32;5447:50;5517:5;;5516:13;;5533:32;5515:50;5585:5;;5584:13;;5583:50;;5653:5;;5652:13;;5651:50;;5721:5;;5720:13;;;5719:50;;5787:5;;;:46;;6735:10;7125:43;7120:48;7232:71;:75;;;;7227:80;;;;7380:72;7375:77;7523:3;7517:9;;;-1:-1:-1;;4596:2947:88:o;1487:3103::-;1536:8;1718:21;1713:1;:26;1709:40;;-1:-1:-1;1748:1:88;;1487:3103;-1:-1:-1;1487:3103:88:o;1709:40::-;1948:21;1943:1;:26;1939:54;;1971:22;;;;;34998:2:285;1971:22:88;;;34980:21:285;35037:2;35017:18;;;35010:30;35076:14;35056:18;;;35049:42;35108:18;;1971:22:88;34796:336:285;1939:54:88;2266:5;2260:2;2255:7;;;2254:17;;-1:-1:-1;2535:8:88;2601:2;2559:29;2548:7;;;2547:41;2591:5;2547:49;2546:57;;2629:29;2625:33;;2621:37;;;3300:35;;;3355:5;;2935:2;3354:13;;;3371:32;3353:50;3423:5;;3422:13;;3421:51;;3492:5;;3491:13;;3508:34;3490:52;3562:5;;3561:13;;3560:53;;3633:5;;3632:13;;3649:35;3631:53;2941:32;2874:31;2870:35;;2925:5;;2924:13;;2923:50;;;2998:5;;;:40;;3058:5;3057:13;;;3074:35;3056:53;3127:5;;;3136:40;3127:50;4002:10;4502:49;4489:62;4564:3;:7;;;;4488:84;;;;;;-1:-1:-1;;1487:3103:88:o;9434:390:170:-;9553:13;;9500:24;;9553:13;9585:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;9585:22:170;;;;;;;;;;;;;;;;9576:31;;9622:9;9617:201;9641:6;9637:1;:10;9617:201;;;9676:72;;;;;;;;9696:6;9703:1;9696:9;;;;;;;;:::i;:::-;;;;;;;9676:72;;;;9716:29;9735:6;9742:1;9735:9;;;;;;;;:::i;:::-;;;;;;;9716:18;:29::i;:::-;9676:72;;;9664:6;9671:1;9664:9;;;;;;;;:::i;:::-;;;;;;;;;;:84;9790:3;;9617:201;;;;9526:298;9434:390;;;:::o;4332:1978:156:-;4395:12;4419:21;4550:4;4544:11;4532:23;;4663:6;4657:13;4836:11;4830:4;4826:22;5195:4;5180:13;5176:24;5169:4;5165:9;5161:40;5151:8;5147:55;5141:4;5134:69;5293:13;5283:8;5276:31;;5434:4;5426:6;5422:17;5571:4;5561:8;5557:19;5662:4;5647:622;5675:11;5672:1;5669:18;5647:622;;;5854:1;5848:4;5844:12;5830;5826:31;5996:1;5984:10;5980:18;5974:25;5968:4;5963:37;6119:1;6113:4;6109:12;6101:6;6093:29;6249:4;6246:1;6242:12;6235:4;6227:6;6223:17;6215:40;-1:-1:-1;;5702:4:156;5695:12;5647:622;;;-1:-1:-1;6295:8:156;;4332:1978;-1:-1:-1;;;;;4332:1978:156:o;3993:464:168:-;4055:17;4085:18;4105;4125:20;4149:18;4163:3;4149:13;:18::i;:::-;4084:83;;-1:-1:-1;4084:83:168;-1:-1:-1;4084:83:168;-1:-1:-1;4198:21:168;4186:8;:33;;;;;;;;:::i;:::-;;4178:103;;;;;;;35528:2:285;4178:103:168;;;35510:21:285;35567:2;35547:18;;;35540:30;35606:34;35586:18;;;35579:62;35677:27;35657:18;;;35650:55;35722:19;;4178:103:168;35326:421:285;4178:103:168;4314:23;4327:10;4314;:23;:::i;:::-;4300:10;;:37;4292:102;;;;;;;35954:2:285;4292:102:168;;;35936:21:285;35993:2;35973:18;;;35966:30;36032:34;36012:18;;;36005:62;36103:22;36083:18;;;36076:50;36143:19;;4292:102:168;35752:416:285;4292:102:168;4412:38;4418:3;:7;;;4427:10;4439;4412:5;:38::i;10121:193:170:-;10195:16;10244:2;10229:5;:12;;;:17;:78;;10281:26;10301:5;10281:19;:26::i;:::-;10229:78;;;10249:29;10272:5;10249:22;:29::i;10495:172::-;10562:21;10606:54;10622:37;10642:5;:13;;;10656:1;10642:16;;;;;;;;:::i;10622:37::-;10606:15;:54::i;3805:237:156:-;3880:12;3918:6;:13;3908:6;:23;3904:70;;-1:-1:-1;3954:9:156;;;;;;;;;-1:-1:-1;3954:9:156;;3947:16;;3904:70;3990:45;3996:6;4004;4028;4012;:13;:22;;;;:::i;:::-;3990:5;:45::i;10892:321:170:-;10980:15;11007:11;11034:2;:9;11022:2;:9;:21;11021:47;;11059:2;:9;11021:47;;;11047:2;:9;11021:47;11007:61;;11078:129;11095:3;11085:7;:13;:43;;;;;11117:2;11120:7;11117:11;;;;;;;;:::i;:::-;;;;;;;;;11102:26;;;:2;11105:7;11102:11;;;;;;;;:::i;:::-;;;;;;;:26;11085:43;11078:129;;;11173:9;;;;;11078:129;;;10997:216;10892:321;;;;:::o;15328:575:88:-;15376:9;15409:1;15405;:5;15397:27;;;;;;;34661:2:285;15397:27:88;;;34643:21:285;34700:1;34680:18;;;34673:29;34738:11;34718:18;;;34711:39;34767:18;;15397:27:88;34459:332:285;15397:27:88;-1:-1:-1;15821:1:88;15473:34;-1:-1:-1;;15467:1:88;15463:49;15566:9;;;15546:18;15543:33;15540:1;15536:41;15530:48;15624:9;;;15612:10;15609:25;15606:1;15602:33;15596:40;15678:9;;;15670:6;15667:21;15664:1;15660:29;15654:36;15730:9;;;15724:4;15721:19;15718:1;15714:27;;;15708:34;;;15781:9;;;15776:3;15773:18;15770:1;15766:26;15760:33;15832:9;;;15824:18;;;15817:26;;15811:33;15876:9;;;-1:-1:-1;15862:25:88;;15328:575::o;3732:130:168:-;3791:21;3831:24;3840:14;3850:3;3840:9;:14::i;:::-;3831:8;:24::i;5246:4079::-;5335:15;5352;5369:17;5705:1;5692:3;:10;;;:14;5684:101;;;;;;;36375:2:285;5684:101:168;;;36357:21:285;36414:2;36394:18;;;36387:30;36453:34;36433:18;;;36426:62;36524:34;36504:18;;;36497:62;36596:12;36575:19;;;36568:41;36626:19;;5684:101:168;36173:478:285;5684:101:168;5816:7;;;;5898:10;;5796:17;5890:19;5943:4;5933:14;;5929:3390;;5999:1;6002;6005:21;5991:36;;;;;;;;;;5929:3390;6058:4;6048:6;:14;6044:3275;;6164:14;6181:13;6190:4;6181:6;:13;:::i;:::-;6164:30;;6247:6;6234:3;:10;;;:19;6209:140;;;;;;;36858:2:285;6209:140:168;;;36840:21:285;36897:2;36877:18;;;36870:30;36936:34;36916:18;;;36909:62;37007:34;36987:18;;;36980:62;37079:16;37058:19;;;37051:45;37113:19;;6209:140:168;36656:482:285;6209:140:168;6471:1;6462:11;;;6456:18;6476:14;6452:39;;6544:11;;;;:41;;-1:-1:-1;6559:26:168;;;;;;6544:41;6519:177;;;;;;;37345:2:285;6519:177:168;;;37327:21:285;37384:2;37364:18;;;37357:30;37423:34;37403:18;;;37396:62;37494:34;37474:18;;;37467:62;37566:15;37545:19;;;37538:44;37599:19;;6519:177:168;37143:481:285;6519:177:168;-1:-1:-1;6719:1:168;;-1:-1:-1;6722:6:168;-1:-1:-1;6730:21:168;;-1:-1:-1;6711:41:168;;-1:-1:-1;;6711:41:168;6044:3275;6783:4;6773:6;:14;6769:2550;;6831:19;6853:13;6862:4;6853:6;:13;:::i;:::-;6831:35;;6919:11;6906:3;:10;;;:24;6881:164;;;;;;;37831:2:285;6881:164:168;;;37813:21:285;37870:2;37850:18;;;37843:30;37909:34;37889:18;;;37882:62;37980:34;37960:18;;;37953:62;38052:19;38031;;;38024:48;38089:19;;6881:164:168;37629:485:285;6881:164:168;7167:1;7158:11;;7152:18;7172:14;7148:39;7060:25;7240:26;;;7215:143;;;;;;;38321:2:285;7215:143:168;;;38303:21:285;38360:2;38340:18;;;38333:30;38399:34;38379:18;;;38372:62;38470:34;38450:18;;;38443:62;38542:12;38521:19;;;38514:41;38572:19;;7215:143:168;38119:478:285;7215:143:168;7488:1;7479:11;;7473:18;7455:1;7451:19;;7446:3;7442:29;7438:54;7537:2;7528:11;;7520:96;;;;;;;38804:2:285;7520:96:168;;;38786:21:285;38843:2;38823:18;;;38816:30;38882:34;38862:18;;;38855:62;38953:34;38933:18;;;38926:62;39025:10;39004:19;;;38997:39;39053:19;;7520:96:168;38602:476:285;7520:96:168;7669:20;7683:6;7669:11;:20;:::i;:::-;7656:10;;:33;7631:168;;;;;;;39285:2:285;7631:168:168;;;39267:21:285;39324:2;39304:18;;;39297:30;39363:34;39343:18;;;39336:62;39434:34;39414:18;;;39407:62;39506:14;39485:19;;;39478:43;39538:19;;7631:168:168;39083:480:285;7631:168:168;7822:15;7826:11;7822:1;:15;:::i;:::-;7814:55;-1:-1:-1;7839:6:168;-1:-1:-1;7847:21:168;;-1:-1:-1;7814:55:168;;-1:-1:-1;;;;7814:55:168;6769:2550;7900:4;7890:6;:14;7886:1433;;8003:15;8021:13;8030:4;8021:6;:13;:::i;:::-;8003:31;;8070:7;8057:3;:10;;;:20;8049:107;;;;;;;39770:2:285;8049:107:168;;;39752:21:285;39809:2;39789:18;;;39782:30;39848:34;39828:18;;;39821:62;39919:34;39899:18;;;39892:62;39991:12;39970:19;;;39963:41;40021:19;;8049:107:168;39568:478:285;8049:107:168;8179:1;;-1:-1:-1;8182:7:168;-1:-1:-1;8179:1:168;;-1:-1:-1;8171:42:168;;-1:-1:-1;;8171:42:168;7886:1433;8270:20;8293:13;8302:4;8293:6;:13;:::i;:::-;8270:36;;8359:12;8346:3;:10;;;:25;8321:161;;;;;;;40253:2:285;8321:161:168;;;40235:21:285;40292:2;40272:18;;;40265:30;40331:34;40311:18;;;40304:62;40402:34;40382:18;;;40375:62;40474:15;40453:19;;;40446:44;40507:19;;8321:161:168;40051:481:285;8321:161:168;8604:1;8595:11;;8589:18;8609:14;8585:39;8497:25;8677:26;;;8652:141;;;;;;;40739:2:285;8652:141:168;;;40721:21:285;40778:2;40758:18;;;40751:30;40817:34;40797:18;;;40790:62;40888:34;40868:18;;;40861:62;40960:10;40939:19;;;40932:39;40988:19;;8652:141:168;40537:476:285;8652:141:168;8926:1;8917:11;;8911:18;8892:1;8888:20;;8883:3;8879:30;8875:55;8976:2;8966:12;;8958:95;;;;;;;41220:2:285;8958:95:168;;;41202:21:285;41259:2;41239:18;;;41232:30;41298:34;41278:18;;;41271:62;41369:34;41349:18;;;41342:62;41441:8;41420:19;;;41413:37;41467:19;;8958:95:168;41018:474:285;8958:95:168;9106:22;9121:7;9106:12;:22;:::i;:::-;9093:10;;:35;9068:168;;;;;;;41699:2:285;9068:168:168;;;41681:21:285;41738:2;41718:18;;;41711:30;41777:34;41757:18;;;41750:62;41848:34;41828:18;;;41821:62;41920:12;41899:19;;;41892:41;41950:19;;9068:168:168;41497:478:285;9068:168:168;9259:16;9263:12;9259:1;:16;:::i;:::-;9251:57;-1:-1:-1;9277:7:168;-1:-1:-1;9286:21:168;;-1:-1:-1;9251:57:168;;-1:-1:-1;;;;9251:57:168;5246:4079;;;;;;:::o;9585:780::-;9676:17;9722:7;9712:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9712:18:168;-1:-1:-1;9705:25:168;-1:-1:-1;9740:54:168;;9772:11;9740:54;10053:11;10067:36;10096:7;10088:4;10067:36;:::i;:::-;10053:50;;10158:2;10152:4;10148:13;10183:1;10197:87;10211:7;10208:1;10205:14;10197:87;;;10269:11;;;10263:18;10249:12;;;10242:40;10234:2;10227:10;10197:87;;;10307:7;10304:1;10301:14;10298:51;;;10345:1;10335:7;10329:4;10325:18;10318:29;10298:51;;;10122:237;9585:780;;;;;:::o;4847:137::-;4912:17;4948:29;4954:3;:7;;;4963:1;4966:3;:10;;;4948:5;:29::i;660:2816:156:-;752:12;824:7;808;818:2;808:12;:23;;800:50;;;;;;;42182:2:285;800:50:156;;;42164:21:285;42221:2;42201:18;;;42194:30;42260:16;42240:18;;;42233:44;42294:18;;800:50:156;41980:338:285;800:50:156;892:6;881:7;872:6;:16;:26;;864:53;;;;;;;42182:2:285;864:53:156;;;42164:21:285;42221:2;42201:18;;;42194:30;42260:16;42240:18;;;42233:44;42294:18;;864:53:156;41980:338:285;864:53:156;965:7;956:6;:16;939:6;:13;:33;;931:63;;;;;;;42525:2:285;931:63:156;;;42507:21:285;42564:2;42544:18;;;42537:30;42603:19;42583:18;;;42576:47;42640:18;;931:63:156;42323:341:285;931:63:156;1015:22;1078:15;;1106:1931;;;;3178:4;3172:11;3159:24;;3365:1;3354:9;3347:20;3413:4;3402:9;3398:20;3392:4;3385:34;1071:2362;;1106:1931;1288:4;1282:11;1269:24;;1947:2;1938:7;1934:16;2329:9;2322:17;2316:4;2312:28;2300:9;2289;2285:25;2281:60;2377:7;2373:2;2369:16;2629:6;2615:9;2608:17;2602:4;2598:28;2586:9;2578:6;2574:22;2570:57;2566:70;2403:389;2662:3;2658:2;2655:11;2403:389;;;2780:9;;2769:21;;2703:4;2695:13;;;;2735;2403:389;;;-1:-1:-1;;2810:26:156;;;3018:2;3001:11;3014:7;2997:25;2991:4;2984:39;-1:-1:-1;1071:2362:156;-1:-1:-1;3460:9:156;660:2816;-1:-1:-1;;;;660:2816:156:o;1298:390:168:-;-1:-1:-1;;;;;;;;;;;;;;;;;1453:1:168;1440:3;:10;:14;1432:101;;;;;;;36375:2:285;1432:101:168;;;36357:21:285;36414:2;36394:18;;;36387:30;36453:34;36433:18;;;36426:62;36524:34;36504:18;;;36497:62;36596:12;36575:19;;;36568:41;36626:19;;1432:101:168;36173:478:285;1432:101:168;-1:-1:-1;1640:41:168;;;;;;;;;1658:10;;1640:41;;1610:2;1601:12;;;1640:41;;;;;;;;1298:390::o;1840:1740::-;1901:21;1935:18;1955;1975:20;1999:18;2013:3;1999:13;:18::i;:::-;1934:83;;-1:-1:-1;1934:83:168;-1:-1:-1;1934:83:168;-1:-1:-1;2048:21:168;2036:8;:33;;;;;;;;:::i;:::-;;2028:102;;;;;;;42871:2:285;2028:102:168;;;42853:21:285;42910:2;42890:18;;;42883:30;42949:34;42929:18;;;42922:62;43020:26;43000:18;;;42993:54;43064:19;;2028:102:168;42669:420:285;2028:102:168;2176:10;;2149:23;2162:10;2149;:23;:::i;:::-;:37;2141:100;;;;;;;43296:2:285;2141:100:168;;;43278:21:285;43335:2;43315:18;;;43308:30;43374:34;43354:18;;;43347:62;43445:20;43425:18;;;43418:48;43483:19;;2141:100:168;43094:414:285;2141:100:168;2651:30;;;1123:2;2651:30;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;2651:30:168;;;;;;;;;;;;;;-1:-1:-1;2644:37:168;-1:-1:-1;2692:17:168;2740:10;2760:681;2776:10;;2767:19;;2760:681;;;2803:18;2823;2846:150;2877:105;;;;;;;;2908:6;2895:3;:10;;;:19;;;;:::i;:::-;2877:105;;;;2972:6;2961:3;:7;;;2940:38;;;;:::i;:::-;2877:105;;2846:13;:150::i;:::-;2802:194;;;;;3201:153;;;;;;;;3248:10;3235;:23;;;;:::i;:::-;3201:153;;;;3332:6;3321:3;:7;;;3300:38;;;;:::i;:::-;3201:153;;;3183:4;3188:9;3183:15;;;;;;;;:::i;:::-;;;;;;;;;;:171;3369:14;3382:1;3369:14;;:::i;:::-;;-1:-1:-1;3407:23:168;3420:10;3407;:23;:::i;:::-;3397:33;;;;:::i;:::-;;;2788:653;;2760:681;;;-1:-1:-1;3541:23:168;;-1:-1:-1;3548:4:168;;1840:1740;-1:-1:-1;;;1840:1740:168:o;753:184:285:-;805:77;802:1;795:88;902:4;899:1;892:15;926:4;923:1;916:15;942:334;1013:2;1007:9;1069:2;1059:13;;1074:66;1055:86;1043:99;;1172:18;1157:34;;1193:22;;;1154:62;1151:88;;;1219:18;;:::i;:::-;1255:2;1248:22;942:334;;-1:-1:-1;942:334:285:o;1281:154::-;1367:42;1360:5;1356:54;1349:5;1346:65;1336:93;;1425:1;1422;1415:12;1336:93;1281:154;:::o;1440:589::-;1482:5;1535:3;1528:4;1520:6;1516:17;1512:27;1502:55;;1553:1;1550;1543:12;1502:55;1589:6;1576:20;1615:18;1611:2;1608:26;1605:52;;;1637:18;;:::i;:::-;1681:114;1789:4;1720:66;1713:4;1709:2;1705:13;1701:86;1697:97;1681:114;:::i;:::-;1820:2;1811:7;1804:19;1866:3;1859:4;1854:2;1846:6;1842:15;1838:26;1835:35;1832:55;;;1883:1;1880;1873:12;1832:55;1948:2;1941:4;1933:6;1929:17;1922:4;1913:7;1909:18;1896:55;1996:1;1971:16;;;1989:4;1967:27;1960:38;;;;1975:7;1440:589;-1:-1:-1;;;1440:589:285:o;2034:1032::-;2102:5;2150:4;2138:9;2133:3;2129:19;2125:30;2122:50;;;2168:1;2165;2158:12;2122:50;2201:2;2195:9;2243:4;2235:6;2231:17;2267:18;2335:6;2323:10;2320:22;2315:2;2303:10;2300:18;2297:46;2294:72;;;2346:18;;:::i;:::-;2386:10;2382:2;2375:22;2415:6;2406:15;;2458:9;2445:23;2437:6;2430:39;2521:2;2510:9;2506:18;2493:32;2478:47;;2534:33;2559:7;2534:33;:::i;:::-;2600:7;2595:2;2587:6;2583:15;2576:32;2660:2;2649:9;2645:18;2632:32;2617:47;;2673:33;2698:7;2673:33;:::i;:::-;2739:7;2734:2;2726:6;2722:15;2715:32;2808:2;2797:9;2793:18;2780:32;2775:2;2767:6;2763:15;2756:57;2875:3;2864:9;2860:19;2847:33;2841:3;2833:6;2829:16;2822:59;2932:3;2921:9;2917:19;2904:33;2890:47;;2960:2;2952:6;2949:14;2946:34;;;2976:1;2973;2966:12;2946:34;;3014:45;3055:3;3046:6;3035:9;3031:22;3014:45;:::i;:::-;3008:3;3000:6;2996:16;2989:71;;;2034:1032;;;;:::o;3071:1173::-;3271:6;3279;3287;3295;3303;3347:9;3338:7;3334:23;3377:3;3373:2;3369:12;3366:32;;;3394:1;3391;3384:12;3366:32;3434:9;3421:23;3463:18;3504:2;3496:6;3493:14;3490:34;;;3520:1;3517;3510:12;3490:34;3543:72;3607:7;3598:6;3587:9;3583:22;3543:72;:::i;:::-;3533:82;;3662:2;3651:9;3647:18;3634:32;3624:42;;3759:3;3690:66;3686:2;3682:75;3678:85;3675:105;;;3776:1;3773;3766:12;3675:105;3814:2;3803:9;3799:18;3789:28;;3870:3;3859:9;3855:19;3842:33;3826:49;;3900:2;3890:8;3887:16;3884:36;;;3916:1;3913;3906:12;3884:36;3954:8;3943:9;3939:24;3929:34;;4001:7;3994:4;3990:2;3986:13;3982:27;3972:55;;4023:1;4020;4013:12;3972:55;4063:2;4050:16;4036:30;;4089:2;4081:6;4078:14;4075:34;;;4105:1;4102;4095:12;4075:34;;4158:7;4153:2;4143:6;4140:1;4136:14;4132:2;4128:23;4124:32;4121:45;4118:65;;;4179:1;4176;4169:12;4118:65;3071:1173;;;;-1:-1:-1;3071:1173:285;;-1:-1:-1;;;4210:2:285;4202:11;;4232:6;3071:1173::o;4249:258::-;4321:1;4331:113;4345:6;4342:1;4339:13;4331:113;;;4421:11;;;4415:18;4402:11;;;4395:39;4367:2;4360:10;4331:113;;;4462:6;4459:1;4456:13;4453:48;;;4497:1;4488:6;4483:3;4479:16;4472:27;4453:48;;4249:258;;;:::o;4512:317::-;4554:3;4592:5;4586:12;4619:6;4614:3;4607:19;4635:63;4691:6;4684:4;4679:3;4675:14;4668:4;4661:5;4657:16;4635:63;:::i;:::-;4743:2;4731:15;4748:66;4727:88;4718:98;;;;4818:4;4714:109;;4512:317;-1:-1:-1;;4512:317:285:o;4834:220::-;4983:2;4972:9;4965:21;4946:4;5003:45;5044:2;5033:9;5029:18;5021:6;5003:45;:::i;5251:180::-;5310:6;5363:2;5351:9;5342:7;5338:23;5334:32;5331:52;;;5379:1;5376;5369:12;5331:52;-1:-1:-1;5402:23:285;;5251:180;-1:-1:-1;5251:180:285:o;5436:374::-;5535:6;5588:2;5576:9;5567:7;5563:23;5559:32;5556:52;;;5604:1;5601;5594:12;5556:52;5644:9;5631:23;5677:18;5669:6;5666:30;5663:50;;;5709:1;5706;5699:12;5663:50;5732:72;5796:7;5787:6;5776:9;5772:22;5732:72;:::i;:::-;5722:82;5436:374;-1:-1:-1;;;;5436:374:285:o;6000:171::-;6067:20;;6127:18;6116:30;;6106:41;;6096:69;;6161:1;6158;6151:12;6096:69;6000:171;;;:::o;6176:184::-;6234:6;6287:2;6275:9;6266:7;6262:23;6258:32;6255:52;;;6303:1;6300;6293:12;6255:52;6326:28;6344:9;6326:28;:::i;7381:160::-;7446:20;;7502:13;;7495:21;7485:32;;7475:60;;7531:1;7528;7521:12;7546:665;7646:6;7654;7662;7670;7678;7731:3;7719:9;7710:7;7706:23;7702:33;7699:53;;;7748:1;7745;7738:12;7699:53;7787:9;7774:23;7806:31;7831:5;7806:31;:::i;:::-;7856:5;-1:-1:-1;7908:2:285;7893:18;;7880:32;;-1:-1:-1;7931:37:285;7964:2;7949:18;;7931:37;:::i;:::-;7921:47;;7987:35;8018:2;8007:9;8003:18;7987:35;:::i;:::-;7977:45;;8073:3;8062:9;8058:19;8045:33;8101:18;8093:6;8090:30;8087:50;;;8133:1;8130;8123:12;8087:50;8156:49;8197:7;8188:6;8177:9;8173:22;8156:49;:::i;:::-;8146:59;;;7546:665;;;;;;;;:::o;8216:644::-;8345:6;8353;8361;8369;8422:3;8410:9;8401:7;8397:23;8393:33;8390:53;;;8439:1;8436;8429:12;8390:53;8478:9;8465:23;8497:31;8522:5;8497:31;:::i;:::-;8547:5;-1:-1:-1;8604:2:285;8589:18;;8576:32;8617:33;8576:32;8617:33;:::i;:::-;8669:7;-1:-1:-1;8728:2:285;8713:18;;8700:32;8741:33;8700:32;8741:33;:::i;:::-;8793:7;-1:-1:-1;8819:35:285;8850:2;8835:18;;8819:35;:::i;:::-;8809:45;;8216:644;;;;;;;:::o;10061:642::-;10324:6;10319:3;10312:19;10361:6;10356:2;10351:3;10347:12;10340:28;10420:66;10411:6;10406:3;10402:16;10398:89;10393:2;10388:3;10384:12;10377:111;10541:6;10534:14;10527:22;10522:3;10518:32;10513:2;10508:3;10504:12;10497:54;10294:3;10580:6;10574:13;10596:60;10649:6;10644:2;10639:3;10635:12;10630:2;10622:6;10618:15;10596:60;:::i;:::-;10676:16;;;;10694:2;10672:25;;10061:642;-1:-1:-1;;;;;;10061:642:285:o;12306:192::-;12385:13;;12438:34;12427:46;;12417:57;;12407:85;;12488:1;12485;12478:12;12503:616;12606:6;12659:2;12647:9;12638:7;12634:23;12630:32;12627:52;;;12675:1;12672;12665:12;12627:52;12708:2;12702:9;12750:2;12742:6;12738:15;12819:6;12807:10;12804:22;12783:18;12771:10;12768:34;12765:62;12762:88;;;12830:18;;:::i;:::-;12866:2;12859:22;12905:16;;12890:32;;12955:49;13000:2;12985:18;;12955:49;:::i;:::-;12950:2;12942:6;12938:15;12931:74;13038:49;13083:2;13072:9;13068:18;13038:49;:::i;:::-;13033:2;13021:15;;13014:74;13025:6;12503:616;-1:-1:-1;;;12503:616:285:o;13124:647::-;13217:6;13270:3;13258:9;13249:7;13245:23;13241:33;13238:53;;;13287:1;13284;13277:12;13238:53;13320:2;13314:9;13362:3;13354:6;13350:16;13432:6;13420:10;13417:22;13396:18;13384:10;13381:34;13378:62;13375:88;;;13443:18;;:::i;:::-;13483:10;13479:2;13472:22;;13531:9;13518:23;13510:6;13503:39;13603:2;13592:9;13588:18;13575:32;13570:2;13562:6;13558:15;13551:57;13669:2;13658:9;13654:18;13641:32;13636:2;13628:6;13624:15;13617:57;13735:2;13724:9;13720:18;13707:32;13702:2;13694:6;13690:15;13683:57;13759:6;13749:16;;;13124:647;;;;:::o;15268:934::-;15404:9;15438:18;15479:2;15471:6;15468:14;15465:40;;;15485:18;;:::i;:::-;15531:6;15528:1;15524:14;15557:4;15581:28;15605:2;15601;15597:11;15581:28;:::i;:::-;15643:19;;;15713:14;;;;15678:12;;;;15750:14;15739:26;;15736:46;;;15778:1;15775;15768:12;15736:46;15802:5;15816:353;15832:6;15827:3;15824:15;15816:353;;;15918:3;15905:17;15954:2;15941:11;15938:19;15935:109;;;15998:1;16027:2;16023;16016:14;15935:109;16069:57;16111:14;16097:11;16090:5;16086:23;16069:57;:::i;:::-;16057:70;;-1:-1:-1;16147:12:285;;;;15849;;15816:353;;;-1:-1:-1;16191:5:285;15268:934;-1:-1:-1;;;;;;;15268:934:285:o;17885:184::-;17955:6;18008:2;17996:9;17987:7;17983:23;17979:32;17976:52;;;18024:1;18021;18014:12;17976:52;-1:-1:-1;18047:16:285;;17885:184;-1:-1:-1;17885:184:285:o;20818:::-;20870:77;20867:1;20860:88;20967:4;20964:1;20957:15;20991:4;20988:1;20981:15;21007:270;21046:7;21078:18;21123:2;21120:1;21116:10;21153:2;21150:1;21146:10;21209:3;21205:2;21201:12;21196:3;21193:21;21186:3;21179:11;21172:19;21168:47;21165:73;;;21218:18;;:::i;:::-;21258:13;;21007:270;-1:-1:-1;;;;21007:270:285:o;21282:236::-;21321:3;21349:18;21394:2;21391:1;21387:10;21424:2;21421:1;21417:10;21455:3;21451:2;21447:12;21442:3;21439:21;21436:47;;;21463:18;;:::i;:::-;21499:13;;21282:236;-1:-1:-1;;;;21282:236:285:o;22127:125::-;22167:4;22195:1;22192;22189:8;22186:34;;;22200:18;;:::i;:::-;-1:-1:-1;22237:9:285;;22127:125::o;22257:184::-;22309:77;22306:1;22299:88;22406:4;22403:1;22396:15;22430:4;22427:1;22420:15;22446:308;22485:1;22511;22501:35;;22516:18;;:::i;:::-;22633:66;22630:1;22627:73;22558:66;22555:1;22552:73;22548:153;22545:179;;;22704:18;;:::i;:::-;-1:-1:-1;22738:10:285;;22446:308::o;22759:369::-;22798:4;22834:1;22831;22827:9;22943:1;22875:66;22871:74;22868:1;22864:82;22859:2;22852:10;22848:99;22845:125;;;22950:18;;:::i;:::-;23069:1;23001:66;22997:74;22994:1;22990:82;22986:2;22982:91;22979:117;;;23076:18;;:::i;:::-;-1:-1:-1;;23113:9:285;;22759:369::o;23133:655::-;23172:7;23204:66;23296:1;23293;23289:9;23324:1;23321;23317:9;23369:1;23365:2;23361:10;23358:1;23355:17;23350:2;23346;23342:11;23338:35;23335:61;;;23376:18;;:::i;:::-;23415:66;23507:1;23504;23500:9;23554:1;23550:2;23545:11;23542:1;23538:19;23533:2;23529;23525:11;23521:37;23518:63;;;23561:18;;:::i;:::-;23607:1;23604;23600:9;23590:19;;23654:1;23650:2;23645:11;23642:1;23638:19;23633:2;23629;23625:11;23621:37;23618:63;;;23661:18;;:::i;:::-;23726:1;23722:2;23717:11;23714:1;23710:19;23705:2;23701;23697:11;23693:37;23690:63;;;23733:18;;:::i;:::-;-1:-1:-1;;;23773:9:285;;;;;23133:655;-1:-1:-1;;;23133:655:285:o;23793:367::-;23832:3;23867:1;23864;23860:9;23976:1;23908:66;23904:74;23901:1;23897:82;23892:2;23885:10;23881:99;23878:125;;;23983:18;;:::i;:::-;24102:1;24034:66;24030:74;24027:1;24023:82;24019:2;24015:91;24012:117;;;24109:18;;:::i;:::-;-1:-1:-1;;24145:9:285;;23793:367::o;24596:228::-;24636:7;24762:1;24694:66;24690:74;24687:1;24684:81;24679:1;24672:9;24665:17;24661:105;24658:131;;;24769:18;;:::i;:::-;-1:-1:-1;24809:9:285;;24596:228::o;24829:120::-;24869:1;24895;24885:35;;24900:18;;:::i;:::-;-1:-1:-1;24934:9:285;;24829:120::o;25350:656::-;25637:6;25626:9;25619:25;25600:4;25663:42;25753:2;25745:6;25741:15;25736:2;25725:9;25721:18;25714:43;25805:2;25797:6;25793:15;25788:2;25777:9;25773:18;25766:43;;25845:6;25840:2;25829:9;25825:18;25818:34;25889:6;25883:3;25872:9;25868:19;25861:35;25933:3;25927;25916:9;25912:19;25905:32;25954:46;25995:3;25984:9;25980:19;25972:6;25954:46;:::i;:::-;25946:54;25350:656;-1:-1:-1;;;;;;;;25350:656:285:o;26011:128::-;26051:3;26082:1;26078:6;26075:1;26072:13;26069:39;;;26088:18;;:::i;:::-;-1:-1:-1;26124:9:285;;26011:128::o;26556:167::-;26634:13;;26687:10;26676:22;;26666:33;;26656:61;;26713:1;26710;26703:12;26728:160;26805:13;;26858:4;26847:16;;26837:27;;26827:55;;26878:1;26875;26868:12;26893:888;26996:6;27049:3;27037:9;27028:7;27024:23;27020:33;27017:53;;;27066:1;27063;27056:12;27017:53;27099:2;27093:9;27141:3;27133:6;27129:16;27211:6;27199:10;27196:22;27175:18;27163:10;27160:34;27157:62;27154:88;;;27222:18;;:::i;:::-;27258:2;27251:22;27297:39;27326:9;27297:39;:::i;:::-;27289:6;27282:55;27370:47;27413:2;27402:9;27398:18;27370:47;:::i;:::-;27365:2;27357:6;27353:15;27346:72;27451:47;27494:2;27483:9;27479:18;27451:47;:::i;:::-;27446:2;27438:6;27434:15;27427:72;27532:48;27576:2;27565:9;27561:18;27532:48;:::i;:::-;27527:2;27519:6;27515:15;27508:73;27615:49;27659:3;27648:9;27644:19;27615:49;:::i;:::-;27609:3;27601:6;27597:16;27590:75;27699:50;27744:3;27733:9;27729:19;27699:50;:::i;:::-;27693:3;27681:16;;27674:76;27685:6;26893:888;-1:-1:-1;;;26893:888:285:o;27786:195::-;27825:3;27856:66;27849:5;27846:77;27843:103;;27926:18;;:::i;:::-;-1:-1:-1;27973:1:285;27962:13;;27786:195::o;28523:184::-;28575:77;28572:1;28565:88;28672:4;28669:1;28662:15;28696:4;28693:1;28686:15;31155:157;31185:1;31219:4;31216:1;31212:12;31243:3;31233:37;;31250:18;;:::i;:::-;31302:3;31295:4;31292:1;31288:12;31284:22;31279:27;;;31155:157;;;;:::o;31317:195::-;31355:4;31392;31389:1;31385:12;31424:4;31421:1;31417:12;31449:3;31444;31441:12;31438:38;;;31456:18;;:::i;:::-;31493:13;;;31317:195;-1:-1:-1;;;31317:195:285:o;35137:184::-;35189:77;35186:1;35179:88;35286:4;35283:1;35276:15;35310:4;35307:1;35300:15", + "linkReferences": {} + }, + "methodIdentifiers": { + "GUARDIAN()": "724c184c", + "L2_ORACLE()": "001c2ff6", + "SYSTEM_CONFIG()": "f0498750", + "depositTransaction(address,uint256,uint64,bool,bytes)": "e9e05c42", + "donateETH()": "8b4c40b0", + "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": "8c3152e9", + "finalizedWithdrawals(bytes32)": "a14238e7", + "guardian()": "452a9320", + "initialize(address,address,address,bool)": "fecf9734", + "isOutputFinalized(uint256)": "6dbffb78", + "l2Oracle()": "9b5f694a", + "l2Sender()": "9bf62d82", + "minimumGasLimit(uint64)": "a35d99df", + "params()": "cff0ab96", + "pause()": "8456cb59", + "paused()": "5c975abb", + "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": "4870496f", + "provenWithdrawals(bytes32)": "e965084c", + "systemConfig()": "33d7e2bd", + "unpause()": "3f4ba83a", + "version()": "54fd4d50" + }, + "rawMetadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"opaqueData\",\"type\":\"bytes\"}],\"name\":\"TransactionDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"WithdrawalProven\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GUARDIAN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SYSTEM_CONFIG\",\"outputs\":[{\"internalType\":\"contract SystemConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"_isCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"donateETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct Types.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_guardian\",\"type\":\"address\"},{\"internalType\":\"contract SystemConfig\",\"name\":\"_systemConfig\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"isOutputFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Oracle\",\"outputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_byteCount\",\"type\":\"uint64\"}],\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct Types.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"struct Types.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\"}],\"name\":\"proveWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"provenWithdrawals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2OutputIndex\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemConfig\",\"outputs\":[{\"internalType\":\"contract SystemConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"custom:proxied\":\"@title OptimismPortal\",\"events\":{\"Paused(address)\":{\"params\":{\"account\":\"Address of the account triggering the pause.\"}},\"TransactionDeposited(address,address,uint256,bytes)\":{\"params\":{\"from\":\"Address that triggered the deposit transaction.\",\"opaqueData\":\"ABI encoded deposit data to be parsed off-chain.\",\"to\":\"Address that the deposit transaction is directed to.\",\"version\":\"Version of this deposit transaction event.\"}},\"Unpaused(address)\":{\"params\":{\"account\":\"Address of the account triggering the unpause.\"}},\"WithdrawalFinalized(bytes32,bool)\":{\"params\":{\"success\":\"Whether the withdrawal transaction was successful.\",\"withdrawalHash\":\"Hash of the withdrawal transaction.\"}},\"WithdrawalProven(bytes32,address,address)\":{\"params\":{\"from\":\"Address that triggered the withdrawal transaction.\",\"to\":\"Address that the withdrawal transaction is directed to.\",\"withdrawalHash\":\"Hash of the withdrawal transaction.\"}}},\"kind\":\"dev\",\"methods\":{\"GUARDIAN()\":{\"custom:legacy\":\"\"},\"L2_ORACLE()\":{\"custom:legacy\":\"\"},\"SYSTEM_CONFIG()\":{\"custom:legacy\":\"\"},\"depositTransaction(address,uint256,uint64,bool,bytes)\":{\"params\":{\"_data\":\"Data to trigger the recipient with.\",\"_gasLimit\":\"Amount of L2 gas to purchase by burning gas on L1.\",\"_isCreation\":\"Whether or not the transaction is a contract creation.\",\"_to\":\"Target address on L2.\",\"_value\":\"ETH value to send to the recipient.\"}},\"finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))\":{\"params\":{\"_tx\":\"Withdrawal transaction to finalize.\"}},\"initialize(address,address,address,bool)\":{\"params\":{\"_guardian\":\"Address that can pause withdrawals.\",\"_l2Oracle\":\"Address of the L2OutputOracle contract.\",\"_paused\":\"Sets the contract's pausability state.\",\"_systemConfig\":\"Address of the SystemConfig contract.\"}},\"isOutputFinalized(uint256)\":{\"params\":{\"_l2OutputIndex\":\"Index of the L2 output to check.\"},\"returns\":{\"_0\":\"Whether or not the output is finalized.\"}},\"minimumGasLimit(uint64)\":{\"params\":{\"_byteCount\":\"Number of bytes in the calldata.\"},\"returns\":{\"_0\":\"The minimum gas limit for a deposit.\"}},\"proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])\":{\"params\":{\"_l2OutputIndex\":\"L2 output index to prove against.\",\"_outputRootProof\":\"Inclusion proof of the L2ToL1MessagePasser contract's storage root.\",\"_tx\":\"Withdrawal transaction to finalize.\",\"_withdrawalProof\":\"Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\"}}},\"stateVariables\":{\"guardian\":{\"custom:network-specific\":\"\"},\"l2Oracle\":{\"custom:network-specific\":\"\"},\"systemConfig\":{\"custom:network-specific\":\"\"},\"version\":{\"custom:semver\":\"1.10.0\"}},\"version\":1},\"userdoc\":{\"events\":{\"Paused(address)\":{\"notice\":\"Emitted when the pause is triggered.\"},\"TransactionDeposited(address,address,uint256,bytes)\":{\"notice\":\"Emitted when a transaction is deposited from L1 to L2. The parameters of this event are read by the rollup node and used to derive deposit transactions on L2.\"},\"Unpaused(address)\":{\"notice\":\"Emitted when the pause is lifted.\"},\"WithdrawalFinalized(bytes32,bool)\":{\"notice\":\"Emitted when a withdrawal transaction is finalized.\"},\"WithdrawalProven(bytes32,address,address)\":{\"notice\":\"Emitted when a withdrawal transaction is proven.\"}},\"kind\":\"user\",\"methods\":{\"GUARDIAN()\":{\"notice\":\"Getter for the Guardian\"},\"L2_ORACLE()\":{\"notice\":\"Getter for the L2OutputOracle\"},\"SYSTEM_CONFIG()\":{\"notice\":\"Getter for the SystemConfig\"},\"constructor\":{\"notice\":\"Constructs the OptimismPortal contract.\"},\"depositTransaction(address,uint256,uint64,bool,bytes)\":{\"notice\":\"Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in deriving deposit transactions. Note that if a deposit is made by a contract, its address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider using the CrossDomainMessenger contracts for a simpler developer experience.\"},\"donateETH()\":{\"notice\":\"Accepts ETH value without triggering a deposit to L2. This function mainly exists for the sake of the migration between the legacy Optimism system and Bedrock.\"},\"finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))\":{\"notice\":\"Finalizes a withdrawal transaction.\"},\"finalizedWithdrawals(bytes32)\":{\"notice\":\"A list of withdrawal hashes which have been successfully finalized.\"},\"guardian()\":{\"notice\":\"Address that has the ability to pause and unpause withdrawals.\"},\"initialize(address,address,address,bool)\":{\"notice\":\"Initializer.\"},\"isOutputFinalized(uint256)\":{\"notice\":\"Determine if a given output is finalized. Reverts if the call to L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\"},\"l2Oracle()\":{\"notice\":\"Address of the L2OutputOracle contract.\"},\"l2Sender()\":{\"notice\":\"Address of the L2 account which initiated a withdrawal in this transaction. If the of this variable is the default L2 sender address, then we are NOT inside of a call to finalizeWithdrawalTransaction.\"},\"minimumGasLimit(uint64)\":{\"notice\":\"Computes the minimum gas limit for a deposit. The minimum gas limit linearly increases based on the size of the calldata. This is to prevent users from creating L2 resource usage without paying for it. This function can be used when interacting with the portal to ensure forwards compatibility.\"},\"params()\":{\"notice\":\"EIP-1559 style gas parameters.\"},\"pause()\":{\"notice\":\"Pauses withdrawals.\"},\"paused()\":{\"notice\":\"Determines if cross domain messaging is paused. When set to true, withdrawals are paused. This may be removed in the future.\"},\"proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])\":{\"notice\":\"Proves a withdrawal transaction.\"},\"provenWithdrawals(bytes32)\":{\"notice\":\"A mapping of withdrawal hashes to `ProvenWithdrawal` data.\"},\"systemConfig()\":{\"notice\":\"Address of the SystemConfig contract.\"},\"unpause()\":{\"notice\":\"Unpauses withdrawals.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"notice\":\"The OptimismPortal is a low-level contract responsible for passing messages between L1 and L2. Messages sent directly to the OptimismPortal have no form of replayability. Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/L1/OptimismPortal.sol\":\"OptimismPortal\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"]},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"]},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]},\"src/L1/L2OutputOracle.sol\":{\"keccak256\":\"0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc\",\"dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN\"]},\"src/L1/OptimismPortal.sol\":{\"keccak256\":\"0xdca91a921b402d82b455d7f11027514e8a16dca906cf820b3afffe271beb8a13\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://688912b9d6005af8395d5c2eb5c4e3367a8be7b50ea97c34fc6a7ac0e2d8fd6a\",\"dweb:/ipfs/QmNPJDwHpNmJ5VPWAJB8muRpZxYeySZDVoV1TMVN7roijJ\"]},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"]},\"src/L1/SystemConfig.sol\":{\"keccak256\":\"0x4bbbc7868e948c44f29285a69383e93251a0c330a67929fb72def01cec060d4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1e7ea2f8b3d49bee9c753f107ede6eda93b2cc0e34d0643fa14ebbb26c19e71b\",\"dweb:/ipfs/QmRP81F8FRVXVZs6u2f2poEPDnbFZhNwNYxHgCVEhGpEmB\"]},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"]},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"]},\"src/libraries/Bytes.sol\":{\"keccak256\":\"0x827f47d123b0fdf3b08816d5b33831811704dbf4e554e53f2269354f6bba8859\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3137ac7204d30a245a8b0d67aa6da5286f1bd8c90379daab561f84963b6db782\",\"dweb:/ipfs/QmWRhisw3axJK833gUScs23ETh2MLFbVzzqzYVMKSDN3S9\"]},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"]},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"]},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"]},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"]},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"]},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"]},\"src/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x9ba74a3b0a11693e622380807d213d5d1250d974e18b2cd768da9cbe719a6778\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0808d721ed9e05707526ee134faa051d707a95ee6b8bd6e0b1972275da8e5723\",\"dweb:/ipfs/QmcTTPu9xgckfWdbFUAcr2RAgk3J6vzyR4FpV798TjFMeN\"]},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"]},\"src/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xf8ba770ee6666e73ae43184c700e9c704b2c4ace71f9e3c2227ddc11a8148b4c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4702ccee1fe44aea3ee01d59e6152eb755da083f786f00947fec4437c064fe74\",\"dweb:/ipfs/QmQjFj5J7hrEM1dxJjFszzW2Cs7g7eMhYNBXonF2DXBstE\"]},\"src/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0xeaff8315cfd21197bc6bc859c2decf5d4f4838c9c357c502cdf2b1eac863d288\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://79dcdcaa560aea51d138da4f5dc553a1808b6de090b2dc1629f18375edbff681\",\"dweb:/ipfs/QmbE4pUPhf5fLKW4W6cEjhQs55gEDvHmbmoBqkW1yz3bnw\"]},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"]},\"src/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"]}},\"version\":1}", + "metadata": { + "compiler": { + "version": "0.8.15+commit.e14f2714" + }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "version", + "type": "uint8", + "indexed": false + } + ], + "type": "event", + "name": "Initialized", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address", + "indexed": false + } + ], + "type": "event", + "name": "Paused", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + "indexed": true + }, + { + "internalType": "address", + "name": "to", + "type": "address", + "indexed": true + }, + { + "internalType": "uint256", + "name": "version", + "type": "uint256", + "indexed": true + }, + { + "internalType": "bytes", + "name": "opaqueData", + "type": "bytes", + "indexed": false + } + ], + "type": "event", + "name": "TransactionDeposited", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address", + "indexed": false + } + ], + "type": "event", + "name": "Unpaused", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "withdrawalHash", + "type": "bytes32", + "indexed": true + }, + { + "internalType": "bool", + "name": "success", + "type": "bool", + "indexed": false + } + ], + "type": "event", + "name": "WithdrawalFinalized", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "withdrawalHash", + "type": "bytes32", + "indexed": true + }, + { + "internalType": "address", + "name": "from", + "type": "address", + "indexed": true + }, + { + "internalType": "address", + "name": "to", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "WithdrawalProven", + "anonymous": false + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "GUARDIAN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "L2_ORACLE", + "outputs": [ + { + "internalType": "contract L2OutputOracle", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "SYSTEM_CONFIG", + "outputs": [ + { + "internalType": "contract SystemConfig", + "name": "", + "type": "address" + } + ] + }, + { + "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" + } + ], + "stateMutability": "payable", + "type": "function", + "name": "depositTransaction" + }, + { + "inputs": [], + "stateMutability": "payable", + "type": "function", + "name": "donateETH" + }, + { + "inputs": [ + { + "internalType": "struct Types.WithdrawalTransaction", + "name": "_tx", + "type": "tuple", + "components": [ + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ] + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "finalizeWithdrawalTransaction" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function", + "name": "finalizedWithdrawals", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "guardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "contract L2OutputOracle", + "name": "_l2Oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "_guardian", + "type": "address" + }, + { + "internalType": "contract SystemConfig", + "name": "_systemConfig", + "type": "address" + }, + { + "internalType": "bool", + "name": "_paused", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2OutputIndex", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "name": "isOutputFinalized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "l2Oracle", + "outputs": [ + { + "internalType": "contract L2OutputOracle", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "l2Sender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_byteCount", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function", + "name": "minimumGasLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "params", + "outputs": [ + { + "internalType": "uint128", + "name": "prevBaseFee", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "prevBoughtGas", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "prevBlockNum", + "type": "uint64" + } + ] + }, + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "function", + "name": "pause" + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [ + { + "internalType": "struct Types.WithdrawalTransaction", + "name": "_tx", + "type": "tuple", + "components": [ + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ] + }, + { + "internalType": "uint256", + "name": "_l2OutputIndex", + "type": "uint256" + }, + { + "internalType": "struct Types.OutputRootProof", + "name": "_outputRootProof", + "type": "tuple", + "components": [ + { + "internalType": "bytes32", + "name": "version", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "stateRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "messagePasserStorageRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "latestBlockhash", + "type": "bytes32" + } + ] + }, + { + "internalType": "bytes[]", + "name": "_withdrawalProof", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "proveWithdrawalTransaction" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function", + "name": "provenWithdrawals", + "outputs": [ + { + "internalType": "bytes32", + "name": "outputRoot", + "type": "bytes32" + }, + { + "internalType": "uint128", + "name": "timestamp", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "l2OutputIndex", + "type": "uint128" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "systemConfig", + "outputs": [ + { + "internalType": "contract SystemConfig", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "function", + "name": "unpause" + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ] + }, + { + "inputs": [], + "stateMutability": "payable", + "type": "receive" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "GUARDIAN()": { + "custom:legacy": "" + }, + "L2_ORACLE()": { + "custom:legacy": "" + }, + "SYSTEM_CONFIG()": { + "custom:legacy": "" + }, + "depositTransaction(address,uint256,uint64,bool,bytes)": { + "params": { + "_data": "Data to trigger the recipient with.", + "_gasLimit": "Amount of L2 gas to purchase by burning gas on L1.", + "_isCreation": "Whether or not the transaction is a contract creation.", + "_to": "Target address on L2.", + "_value": "ETH value to send to the recipient." + } + }, + "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": { + "params": { + "_tx": "Withdrawal transaction to finalize." + } + }, + "initialize(address,address,address,bool)": { + "params": { + "_guardian": "Address that can pause withdrawals.", + "_l2Oracle": "Address of the L2OutputOracle contract.", + "_paused": "Sets the contract's pausability state.", + "_systemConfig": "Address of the SystemConfig contract." + } + }, + "isOutputFinalized(uint256)": { + "params": { + "_l2OutputIndex": "Index of the L2 output to check." + }, + "returns": { + "_0": "Whether or not the output is finalized." + } + }, + "minimumGasLimit(uint64)": { + "params": { + "_byteCount": "Number of bytes in the calldata." + }, + "returns": { + "_0": "The minimum gas limit for a deposit." + } + }, + "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": { + "params": { + "_l2OutputIndex": "L2 output index to prove against.", + "_outputRootProof": "Inclusion proof of the L2ToL1MessagePasser contract's storage root.", + "_tx": "Withdrawal transaction to finalize.", + "_withdrawalProof": "Inclusion proof of the withdrawal in L2ToL1MessagePasser contract." + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "GUARDIAN()": { + "notice": "Getter for the Guardian" + }, + "L2_ORACLE()": { + "notice": "Getter for the L2OutputOracle" + }, + "SYSTEM_CONFIG()": { + "notice": "Getter for the SystemConfig" + }, + "constructor": { + "notice": "Constructs the OptimismPortal contract." + }, + "depositTransaction(address,uint256,uint64,bool,bytes)": { + "notice": "Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in deriving deposit transactions. Note that if a deposit is made by a contract, its address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider using the CrossDomainMessenger contracts for a simpler developer experience." + }, + "donateETH()": { + "notice": "Accepts ETH value without triggering a deposit to L2. This function mainly exists for the sake of the migration between the legacy Optimism system and Bedrock." + }, + "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": { + "notice": "Finalizes a withdrawal transaction." + }, + "finalizedWithdrawals(bytes32)": { + "notice": "A list of withdrawal hashes which have been successfully finalized." + }, + "guardian()": { + "notice": "Address that has the ability to pause and unpause withdrawals." + }, + "initialize(address,address,address,bool)": { + "notice": "Initializer." + }, + "isOutputFinalized(uint256)": { + "notice": "Determine if a given output is finalized. Reverts if the call to L2_ORACLE.getL2Output reverts. Returns a boolean otherwise." + }, + "l2Oracle()": { + "notice": "Address of the L2OutputOracle contract." + }, + "l2Sender()": { + "notice": "Address of the L2 account which initiated a withdrawal in this transaction. If the of this variable is the default L2 sender address, then we are NOT inside of a call to finalizeWithdrawalTransaction." + }, + "minimumGasLimit(uint64)": { + "notice": "Computes the minimum gas limit for a deposit. The minimum gas limit linearly increases based on the size of the calldata. This is to prevent users from creating L2 resource usage without paying for it. This function can be used when interacting with the portal to ensure forwards compatibility." + }, + "params()": { + "notice": "EIP-1559 style gas parameters." + }, + "pause()": { + "notice": "Pauses withdrawals." + }, + "paused()": { + "notice": "Determines if cross domain messaging is paused. When set to true, withdrawals are paused. This may be removed in the future." + }, + "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": { + "notice": "Proves a withdrawal transaction." + }, + "provenWithdrawals(bytes32)": { + "notice": "A mapping of withdrawal hashes to `ProvenWithdrawal` data." + }, + "systemConfig()": { + "notice": "Address of the SystemConfig contract." + }, + "unpause()": { + "notice": "Unpauses withdrawals." + }, + "version()": { + "notice": "Semantic version." + } + }, + "version": 1 + } + }, + "settings": { + "remappings": [ + "@cwia/=lib/clones-with-immutable-args/src/", + "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", + "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", + "@rari-capital/solmate/=lib/solmate/", + "clones-with-immutable-args/=lib/clones-with-immutable-args/src/", + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", + "openzeppelin-contracts/=lib/openzeppelin-contracts/", + "safe-contracts/=lib/safe-contracts/contracts/", + "solmate/=lib/solmate/src/" + ], + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "metadata": { + "bytecodeHash": "none" + }, + "compilationTarget": { + "src/L1/OptimismPortal.sol": "OptimismPortal" + }, + "libraries": {} + }, + "sources": { + "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol": { + "keccak256": "0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888", + "urls": [ + "bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a", + "dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol": { + "keccak256": "0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e", + "urls": [ + "bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497", + "dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol": { + "keccak256": "0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3", + "urls": [ + "bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4", + "dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol": { + "keccak256": "0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149", + "urls": [ + "bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c", + "dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol": { + "keccak256": "0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66", + "urls": [ + "bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f", + "dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts/contracts/utils/Address.sol": { + "keccak256": "0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10", + "urls": [ + "bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487", + "dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts/contracts/utils/math/Math.sol": { + "keccak256": "0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0", + "urls": [ + "bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929", + "dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol": { + "keccak256": "0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7", + "urls": [ + "bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689", + "dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy" + ], + "license": "MIT" + }, + "lib/solmate/src/utils/FixedPointMathLib.sol": { + "keccak256": "0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d", + "urls": [ + "bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c", + "dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8" + ], + "license": "MIT" + }, + "src/L1/L2OutputOracle.sol": { + "keccak256": "0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705", + "urls": [ + "bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc", + "dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN" + ], + "license": "MIT" + }, + "src/L1/OptimismPortal.sol": { + "keccak256": "0xdca91a921b402d82b455d7f11027514e8a16dca906cf820b3afffe271beb8a13", + "urls": [ + "bzz-raw://688912b9d6005af8395d5c2eb5c4e3367a8be7b50ea97c34fc6a7ac0e2d8fd6a", + "dweb:/ipfs/QmNPJDwHpNmJ5VPWAJB8muRpZxYeySZDVoV1TMVN7roijJ" + ], + "license": "MIT" + }, + "src/L1/ResourceMetering.sol": { + "keccak256": "0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588", + "urls": [ + "bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730", + "dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG" + ], + "license": "MIT" + }, + "src/L1/SystemConfig.sol": { + "keccak256": "0x4bbbc7868e948c44f29285a69383e93251a0c330a67929fb72def01cec060d4e", + "urls": [ + "bzz-raw://1e7ea2f8b3d49bee9c753f107ede6eda93b2cc0e34d0643fa14ebbb26c19e71b", + "dweb:/ipfs/QmRP81F8FRVXVZs6u2f2poEPDnbFZhNwNYxHgCVEhGpEmB" + ], + "license": "MIT" + }, + "src/libraries/Arithmetic.sol": { + "keccak256": "0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560", + "urls": [ + "bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee", + "dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm" + ], + "license": "MIT" + }, + "src/libraries/Burn.sol": { + "keccak256": "0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010", + "urls": [ + "bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f", + "dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb" + ], + "license": "MIT" + }, + "src/libraries/Bytes.sol": { + "keccak256": "0x827f47d123b0fdf3b08816d5b33831811704dbf4e554e53f2269354f6bba8859", + "urls": [ + "bzz-raw://3137ac7204d30a245a8b0d67aa6da5286f1bd8c90379daab561f84963b6db782", + "dweb:/ipfs/QmWRhisw3axJK833gUScs23ETh2MLFbVzzqzYVMKSDN3S9" + ], + "license": "MIT" + }, + "src/libraries/Constants.sol": { + "keccak256": "0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2", + "urls": [ + "bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7", + "dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC" + ], + "license": "MIT" + }, + "src/libraries/Encoding.sol": { + "keccak256": "0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b", + "urls": [ + "bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93", + "dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW" + ], + "license": "MIT" + }, + "src/libraries/Hashing.sol": { + "keccak256": "0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3", + "urls": [ + "bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b", + "dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf" + ], + "license": "MIT" + }, + "src/libraries/SafeCall.sol": { + "keccak256": "0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f", + "urls": [ + "bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a", + "dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq" + ], + "license": "MIT" + }, + "src/libraries/Storage.sol": { + "keccak256": "0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd", + "urls": [ + "bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480", + "dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4" + ], + "license": "MIT" + }, + "src/libraries/Types.sol": { + "keccak256": "0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4", + "urls": [ + "bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e", + "dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc" + ], + "license": "MIT" + }, + "src/libraries/rlp/RLPReader.sol": { + "keccak256": "0x9ba74a3b0a11693e622380807d213d5d1250d974e18b2cd768da9cbe719a6778", + "urls": [ + "bzz-raw://0808d721ed9e05707526ee134faa051d707a95ee6b8bd6e0b1972275da8e5723", + "dweb:/ipfs/QmcTTPu9xgckfWdbFUAcr2RAgk3J6vzyR4FpV798TjFMeN" + ], + "license": "MIT" + }, + "src/libraries/rlp/RLPWriter.sol": { + "keccak256": "0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6", + "urls": [ + "bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b", + "dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV" + ], + "license": "MIT" + }, + "src/libraries/trie/MerkleTrie.sol": { + "keccak256": "0xf8ba770ee6666e73ae43184c700e9c704b2c4ace71f9e3c2227ddc11a8148b4c", + "urls": [ + "bzz-raw://4702ccee1fe44aea3ee01d59e6152eb755da083f786f00947fec4437c064fe74", + "dweb:/ipfs/QmQjFj5J7hrEM1dxJjFszzW2Cs7g7eMhYNBXonF2DXBstE" + ], + "license": "MIT" + }, + "src/libraries/trie/SecureMerkleTrie.sol": { + "keccak256": "0xeaff8315cfd21197bc6bc859c2decf5d4f4838c9c357c502cdf2b1eac863d288", + "urls": [ + "bzz-raw://79dcdcaa560aea51d138da4f5dc553a1808b6de090b2dc1629f18375edbff681", + "dweb:/ipfs/QmbE4pUPhf5fLKW4W6cEjhQs55gEDvHmbmoBqkW1yz3bnw" + ], + "license": "MIT" + }, + "src/universal/ISemver.sol": { + "keccak256": "0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44", + "urls": [ + "bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a", + "dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR" + ], + "license": "MIT" + }, + "src/vendor/AddressAliasHelper.sol": { + "keccak256": "0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237", + "urls": [ + "bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88", + "dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR" + ], + "license": "Apache-2.0" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 32100, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 32103, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 60287, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "params", + "offset": 0, + "slot": "1", + "type": "t_struct(ResourceParams)60270_storage" + }, + { + "astId": 60292, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)48_storage" + }, + { + "astId": 59323, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "l2Sender", + "offset": 0, + "slot": "50", + "type": "t_address" + }, + { + "astId": 59328, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "finalizedWithdrawals", + "offset": 0, + "slot": "51", + "type": "t_mapping(t_bytes32,t_bool)" + }, + { + "astId": 59334, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "provenWithdrawals", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)59312_storage)" + }, + { + "astId": 59337, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "paused", + "offset": 0, + "slot": "53", + "type": "t_bool" + }, + { + "astId": 59341, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "l2Oracle", + "offset": 1, + "slot": "53", + "type": "t_contract(L2OutputOracle)59272" + }, + { + "astId": 59345, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "systemConfig", + "offset": 0, + "slot": "54", + "type": "t_contract(SystemConfig)61393" + }, + { + "astId": 59348, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "guardian", + "offset": 0, + "slot": "55", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)48_storage": { + "encoding": "inplace", + "label": "uint256[48]", + "numberOfBytes": "1536", + "base": "t_uint256" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(L2OutputOracle)59272": { + "encoding": "inplace", + "label": "contract L2OutputOracle", + "numberOfBytes": "20" + }, + "t_contract(SystemConfig)61393": { + "encoding": "inplace", + "label": "contract SystemConfig", + "numberOfBytes": "20" + }, + "t_mapping(t_bytes32,t_bool)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)59312_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal)", + "numberOfBytes": "32", + "value": "t_struct(ProvenWithdrawal)59312_storage" + }, + "t_struct(ProvenWithdrawal)59312_storage": { + "encoding": "inplace", + "label": "struct OptimismPortal.ProvenWithdrawal", + "numberOfBytes": "64", + "members": [ + { + "astId": 59307, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "outputRoot", + "offset": 0, + "slot": "0", + "type": "t_bytes32" + }, + { + "astId": 59309, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "timestamp", + "offset": 0, + "slot": "1", + "type": "t_uint128" + }, + { + "astId": 59311, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "l2OutputIndex", + "offset": 16, + "slot": "1", + "type": "t_uint128" + } + ] + }, + "t_struct(ResourceParams)60270_storage": { + "encoding": "inplace", + "label": "struct ResourceMetering.ResourceParams", + "numberOfBytes": "32", + "members": [ + { + "astId": 60265, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "prevBaseFee", + "offset": 0, + "slot": "0", + "type": "t_uint128" + }, + { + "astId": 60267, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "prevBoughtGas", + "offset": 16, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 60269, + "contract": "src/L1/OptimismPortal.sol:OptimismPortal", + "label": "prevBlockNum", + "offset": 24, + "slot": "0", + "type": "t_uint64" + } + ] + }, + "t_uint128": { + "encoding": "inplace", + "label": "uint128", + "numberOfBytes": "16" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + }, + "userdoc": { + "version": 1, + "kind": "user", + "methods": { + "GUARDIAN()": { + "notice": "Getter for the Guardian" + }, + "L2_ORACLE()": { + "notice": "Getter for the L2OutputOracle" + }, + "SYSTEM_CONFIG()": { + "notice": "Getter for the SystemConfig" + }, + "constructor": { + "notice": "Constructs the OptimismPortal contract." + }, + "depositTransaction(address,uint256,uint64,bool,bytes)": { + "notice": "Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in deriving deposit transactions. Note that if a deposit is made by a contract, its address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider using the CrossDomainMessenger contracts for a simpler developer experience." + }, + "donateETH()": { + "notice": "Accepts ETH value without triggering a deposit to L2. This function mainly exists for the sake of the migration between the legacy Optimism system and Bedrock." + }, + "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": { + "notice": "Finalizes a withdrawal transaction." + }, + "finalizedWithdrawals(bytes32)": { + "notice": "A list of withdrawal hashes which have been successfully finalized." + }, + "guardian()": { + "notice": "Address that has the ability to pause and unpause withdrawals." + }, + "initialize(address,address,address,bool)": { + "notice": "Initializer." + }, + "isOutputFinalized(uint256)": { + "notice": "Determine if a given output is finalized. Reverts if the call to L2_ORACLE.getL2Output reverts. Returns a boolean otherwise." + }, + "l2Oracle()": { + "notice": "Address of the L2OutputOracle contract." + }, + "l2Sender()": { + "notice": "Address of the L2 account which initiated a withdrawal in this transaction. If the of this variable is the default L2 sender address, then we are NOT inside of a call to finalizeWithdrawalTransaction." + }, + "minimumGasLimit(uint64)": { + "notice": "Computes the minimum gas limit for a deposit. The minimum gas limit linearly increases based on the size of the calldata. This is to prevent users from creating L2 resource usage without paying for it. This function can be used when interacting with the portal to ensure forwards compatibility." + }, + "params()": { + "notice": "EIP-1559 style gas parameters." + }, + "pause()": { + "notice": "Pauses withdrawals." + }, + "paused()": { + "notice": "Determines if cross domain messaging is paused. When set to true, withdrawals are paused. This may be removed in the future." + }, + "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": { + "notice": "Proves a withdrawal transaction." + }, + "provenWithdrawals(bytes32)": { + "notice": "A mapping of withdrawal hashes to `ProvenWithdrawal` data." + }, + "systemConfig()": { + "notice": "Address of the SystemConfig contract." + }, + "unpause()": { + "notice": "Unpauses withdrawals." + }, + "version()": { + "notice": "Semantic version." + } + }, + "events": { + "Paused(address)": { + "notice": "Emitted when the pause is triggered." + }, + "TransactionDeposited(address,address,uint256,bytes)": { + "notice": "Emitted when a transaction is deposited from L1 to L2. The parameters of this event are read by the rollup node and used to derive deposit transactions on L2." + }, + "Unpaused(address)": { + "notice": "Emitted when the pause is lifted." + }, + "WithdrawalFinalized(bytes32,bool)": { + "notice": "Emitted when a withdrawal transaction is finalized." + }, + "WithdrawalProven(bytes32,address,address)": { + "notice": "Emitted when a withdrawal transaction is proven." + } + }, + "notice": "The OptimismPortal is a low-level contract responsible for passing messages between L1 and L2. Messages sent directly to the OptimismPortal have no form of replayability. Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface." + }, + "devdoc": { + "version": 1, + "kind": "dev", + "methods": { + "GUARDIAN()": {}, + "L2_ORACLE()": {}, + "SYSTEM_CONFIG()": {}, + "depositTransaction(address,uint256,uint64,bool,bytes)": { + "params": { + "_data": "Data to trigger the recipient with.", + "_gasLimit": "Amount of L2 gas to purchase by burning gas on L1.", + "_isCreation": "Whether or not the transaction is a contract creation.", + "_to": "Target address on L2.", + "_value": "ETH value to send to the recipient." + } + }, + "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": { + "params": { + "_tx": "Withdrawal transaction to finalize." + } + }, + "initialize(address,address,address,bool)": { + "params": { + "_guardian": "Address that can pause withdrawals.", + "_l2Oracle": "Address of the L2OutputOracle contract.", + "_paused": "Sets the contract's pausability state.", + "_systemConfig": "Address of the SystemConfig contract." + } + }, + "isOutputFinalized(uint256)": { + "params": { + "_l2OutputIndex": "Index of the L2 output to check." + }, + "returns": { + "_0": "Whether or not the output is finalized." + } + }, + "minimumGasLimit(uint64)": { + "params": { + "_byteCount": "Number of bytes in the calldata." + }, + "returns": { + "_0": "The minimum gas limit for a deposit." + } + }, + "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": { + "params": { + "_l2OutputIndex": "L2 output index to prove against.", + "_outputRootProof": "Inclusion proof of the L2ToL1MessagePasser contract's storage root.", + "_tx": "Withdrawal transaction to finalize.", + "_withdrawalProof": "Inclusion proof of the withdrawal in L2ToL1MessagePasser contract." + } + } + }, + "events": { + "Paused(address)": { + "params": { + "account": "Address of the account triggering the pause." + } + }, + "TransactionDeposited(address,address,uint256,bytes)": { + "params": { + "from": "Address that triggered the deposit transaction.", + "opaqueData": "ABI encoded deposit data to be parsed off-chain.", + "to": "Address that the deposit transaction is directed to.", + "version": "Version of this deposit transaction event." + } + }, + "Unpaused(address)": { + "params": { + "account": "Address of the account triggering the unpause." + } + }, + "WithdrawalFinalized(bytes32,bool)": { + "params": { + "success": "Whether the withdrawal transaction was successful.", + "withdrawalHash": "Hash of the withdrawal transaction." + } + }, + "WithdrawalProven(bytes32,address,address)": { + "params": { + "from": "Address that triggered the withdrawal transaction.", + "to": "Address that the withdrawal transaction is directed to.", + "withdrawalHash": "Hash of the withdrawal transaction." + } + } + } + }, + "ast": { + "absolutePath": "src/L1/OptimismPortal.sol", + "id": 59998, + "exportedSymbols": { + "AddressAliasHelper": [ + 78127 + ], + "Constants": [ + 69571 + ], + "Hashing": [ + 70279 + ], + "ISemver": [ + 75669 + ], + "Initializable": [ + 32244 + ], + "L2OutputOracle": [ + 59272 + ], + "OptimismPortal": [ + 59997 + ], + "ResourceMetering": [ + 60599 + ], + "SafeCall": [ + 70479 + ], + "SecureMerkleTrie": [ + 72279 + ], + "SystemConfig": [ + 61393 + ], + "Types": [ + 70595 + ] + }, + "nodeType": "SourceUnit", + "src": "32:21369:110", + "nodes": [ + { + "id": 59274, + "nodeType": "PragmaDirective", + "src": "32:23:110", + "nodes": [], + "literals": [ + "solidity", + "0.8", + ".15" + ] + }, + { + "id": 59276, + "nodeType": "ImportDirective", + "src": "57:86:110", + "nodes": [], + "absolutePath": "lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol", + "file": "@openzeppelin/contracts/proxy/utils/Initializable.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 32245, + "symbolAliases": [ + { + "foreign": { + "id": 59275, + "name": "Initializable", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 32244, + "src": "66:13:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59278, + "nodeType": "ImportDirective", + "src": "144:54:110", + "nodes": [], + "absolutePath": "src/libraries/SafeCall.sol", + "file": "src/libraries/SafeCall.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 70480, + "symbolAliases": [ + { + "foreign": { + "id": 59277, + "name": "SafeCall", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 70479, + "src": "153:8:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59280, + "nodeType": "ImportDirective", + "src": "199:59:110", + "nodes": [], + "absolutePath": "src/L1/L2OutputOracle.sol", + "file": "src/L1/L2OutputOracle.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 59273, + "symbolAliases": [ + { + "foreign": { + "id": 59279, + "name": "L2OutputOracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59272, + "src": "208:14:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59282, + "nodeType": "ImportDirective", + "src": "259:55:110", + "nodes": [], + "absolutePath": "src/L1/SystemConfig.sol", + "file": "src/L1/SystemConfig.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 61394, + "symbolAliases": [ + { + "foreign": { + "id": 59281, + "name": "SystemConfig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 61393, + "src": "268:12:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59284, + "nodeType": "ImportDirective", + "src": "315:56:110", + "nodes": [], + "absolutePath": "src/libraries/Constants.sol", + "file": "src/libraries/Constants.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 69572, + "symbolAliases": [ + { + "foreign": { + "id": 59283, + "name": "Constants", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69571, + "src": "324:9:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59286, + "nodeType": "ImportDirective", + "src": "372:48:110", + "nodes": [], + "absolutePath": "src/libraries/Types.sol", + "file": "src/libraries/Types.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 70596, + "symbolAliases": [ + { + "foreign": { + "id": 59285, + "name": "Types", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 70595, + "src": "381:5:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59288, + "nodeType": "ImportDirective", + "src": "421:52:110", + "nodes": [], + "absolutePath": "src/libraries/Hashing.sol", + "file": "src/libraries/Hashing.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 70280, + "symbolAliases": [ + { + "foreign": { + "id": 59287, + "name": "Hashing", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 70279, + "src": "430:7:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59290, + "nodeType": "ImportDirective", + "src": "474:75:110", + "nodes": [], + "absolutePath": "src/libraries/trie/SecureMerkleTrie.sol", + "file": "src/libraries/trie/SecureMerkleTrie.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 72280, + "symbolAliases": [ + { + "foreign": { + "id": 59289, + "name": "SecureMerkleTrie", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 72279, + "src": "483:16:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59292, + "nodeType": "ImportDirective", + "src": "550:71:110", + "nodes": [], + "absolutePath": "src/vendor/AddressAliasHelper.sol", + "file": "src/vendor/AddressAliasHelper.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 78128, + "symbolAliases": [ + { + "foreign": { + "id": 59291, + "name": "AddressAliasHelper", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 78127, + "src": "559:18:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59294, + "nodeType": "ImportDirective", + "src": "622:63:110", + "nodes": [], + "absolutePath": "src/L1/ResourceMetering.sol", + "file": "src/L1/ResourceMetering.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 60600, + "symbolAliases": [ + { + "foreign": { + "id": 59293, + "name": "ResourceMetering", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 60599, + "src": "631:16:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59296, + "nodeType": "ImportDirective", + "src": "686:52:110", + "nodes": [], + "absolutePath": "src/universal/ISemver.sol", + "file": "src/universal/ISemver.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 75670, + "symbolAliases": [ + { + "foreign": { + "id": 59295, + "name": "ISemver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 75669, + "src": "695:7:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59298, + "nodeType": "ImportDirective", + "src": "739:56:110", + "nodes": [], + "absolutePath": "src/libraries/Constants.sol", + "file": "src/libraries/Constants.sol", + "nameLocation": "-1:-1:-1", + "scope": 59998, + "sourceUnit": 69572, + "symbolAliases": [ + { + "foreign": { + "id": 59297, + "name": "Constants", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69571, + "src": "748:9:110", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 59997, + "nodeType": "ContractDefinition", + "src": "1135:20265:110", + "nodes": [ + { + "id": 59312, + "nodeType": "StructDefinition", + "src": "1503:117:110", + "nodes": [], + "canonicalName": "OptimismPortal.ProvenWithdrawal", + "members": [ + { + "constant": false, + "id": 59307, + "mutability": "mutable", + "name": "outputRoot", + "nameLocation": "1545:10:110", + "nodeType": "VariableDeclaration", + "scope": 59312, + "src": "1537:18:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 59306, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1537:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59309, + "mutability": "mutable", + "name": "timestamp", + "nameLocation": "1573:9:110", + "nodeType": "VariableDeclaration", + "scope": 59312, + "src": "1565:17:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + }, + "typeName": { + "id": 59308, + "name": "uint128", + "nodeType": "ElementaryTypeName", + "src": "1565:7:110", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59311, + "mutability": "mutable", + "name": "l2OutputIndex", + "nameLocation": "1600:13:110", + "nodeType": "VariableDeclaration", + "scope": 59312, + "src": "1592:21:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + }, + "typeName": { + "id": 59310, + "name": "uint128", + "nodeType": "ElementaryTypeName", + "src": "1592:7:110", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + }, + "visibility": "internal" + } + ], + "name": "ProvenWithdrawal", + "nameLocation": "1510:16:110", + "scope": 59997, + "visibility": "public" + }, + { + "id": 59316, + "nodeType": "VariableDeclaration", + "src": "1672:45:110", + "nodes": [], + "constant": true, + "documentation": { + "id": 59313, + "nodeType": "StructuredDocumentation", + "src": "1626:41:110", + "text": "@notice Version of the deposit event." + }, + "mutability": "constant", + "name": "DEPOSIT_VERSION", + "nameLocation": "1698:15:110", + "scope": 59997, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 59314, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1672:7:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "30", + "id": 59315, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1716:1:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "visibility": "internal" + }, + { + "id": 59320, + "nodeType": "VariableDeclaration", + "src": "1813:60:110", + "nodes": [], + "constant": true, + "documentation": { + "id": 59317, + "nodeType": "StructuredDocumentation", + "src": "1724:84:110", + "text": "@notice The L2 gas limit set when eth is deposited using the receive() function." + }, + "mutability": "constant", + "name": "RECEIVE_DEFAULT_GAS_LIMIT", + "nameLocation": "1838:25:110", + "scope": 59997, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + }, + "typeName": { + "id": 59318, + "name": "uint64", + "nodeType": "ElementaryTypeName", + "src": "1813:6:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + "value": { + "hexValue": "3130305f303030", + "id": 59319, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1866:7:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_100000_by_1", + "typeString": "int_const 100000" + }, + "value": "100_000" + }, + "visibility": "internal" + }, + { + "id": 59323, + "nodeType": "VariableDeclaration", + "src": "2129:23:110", + "nodes": [], + "constant": false, + "documentation": { + "id": 59321, + "nodeType": "StructuredDocumentation", + "src": "1880:244:110", + "text": "@notice Address of the L2 account which initiated a withdrawal in this transaction.\n If the of this variable is the default L2 sender address, then we are NOT inside of\n a call to finalizeWithdrawalTransaction." + }, + "functionSelector": "9bf62d82", + "mutability": "mutable", + "name": "l2Sender", + "nameLocation": "2144:8:110", + "scope": 59997, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59322, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2129:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "public" + }, + { + "id": 59328, + "nodeType": "VariableDeclaration", + "src": "2243:52:110", + "nodes": [], + "constant": false, + "documentation": { + "id": 59324, + "nodeType": "StructuredDocumentation", + "src": "2159:79:110", + "text": "@notice A list of withdrawal hashes which have been successfully finalized." + }, + "functionSelector": "a14238e7", + "mutability": "mutable", + "name": "finalizedWithdrawals", + "nameLocation": "2275:20:110", + "scope": 59997, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_bool_$", + "typeString": "mapping(bytes32 => bool)" + }, + "typeName": { + "id": 59327, + "keyType": { + "id": 59325, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2251:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "2243:24:110", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_bool_$", + "typeString": "mapping(bytes32 => bool)" + }, + "valueType": { + "id": 59326, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2262:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + }, + "visibility": "public" + }, + { + "id": 59334, + "nodeType": "VariableDeclaration", + "src": "2377:61:110", + "nodes": [], + "constant": false, + "documentation": { + "id": 59329, + "nodeType": "StructuredDocumentation", + "src": "2302:70:110", + "text": "@notice A mapping of withdrawal hashes to `ProvenWithdrawal` data." + }, + "functionSelector": "e965084c", + "mutability": "mutable", + "name": "provenWithdrawals", + "nameLocation": "2421:17:110", + "scope": 59997, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_ProvenWithdrawal_$59312_storage_$", + "typeString": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal)" + }, + "typeName": { + "id": 59333, + "keyType": { + "id": 59330, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2385:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "2377:36:110", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_ProvenWithdrawal_$59312_storage_$", + "typeString": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal)" + }, + "valueType": { + "id": 59332, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59331, + "name": "ProvenWithdrawal", + "nodeType": "IdentifierPath", + "referencedDeclaration": 59312, + "src": "2396:16:110" + }, + "referencedDeclaration": 59312, + "src": "2396:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_storage_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal" + } + } + }, + "visibility": "public" + }, + { + "id": 59337, + "nodeType": "VariableDeclaration", + "src": "2618:18:110", + "nodes": [], + "constant": false, + "documentation": { + "id": 59335, + "nodeType": "StructuredDocumentation", + "src": "2445:168:110", + "text": "@notice Determines if cross domain messaging is paused.\n When set to true, withdrawals are paused.\n This may be removed in the future." + }, + "functionSelector": "5c975abb", + "mutability": "mutable", + "name": "paused", + "nameLocation": "2630:6:110", + "scope": 59997, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 59336, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2618:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "public" + }, + { + "id": 59341, + "nodeType": "VariableDeclaration", + "src": "2732:30:110", + "nodes": [], + "constant": false, + "documentation": { + "id": 59338, + "nodeType": "StructuredDocumentation", + "src": "2643:84:110", + "text": "@notice Address of the L2OutputOracle contract.\n @custom:network-specific" + }, + "functionSelector": "9b5f694a", + "mutability": "mutable", + "name": "l2Oracle", + "nameLocation": "2754:8:110", + "scope": 59997, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + }, + "typeName": { + "id": 59340, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59339, + "name": "L2OutputOracle", + "nodeType": "IdentifierPath", + "referencedDeclaration": 59272, + "src": "2732:14:110" + }, + "referencedDeclaration": 59272, + "src": "2732:14:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "visibility": "public" + }, + { + "id": 59345, + "nodeType": "VariableDeclaration", + "src": "2856:32:110", + "nodes": [], + "constant": false, + "documentation": { + "id": 59342, + "nodeType": "StructuredDocumentation", + "src": "2769:82:110", + "text": "@notice Address of the SystemConfig contract.\n @custom:network-specific" + }, + "functionSelector": "33d7e2bd", + "mutability": "mutable", + "name": "systemConfig", + "nameLocation": "2876:12:110", + "scope": 59997, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + }, + "typeName": { + "id": 59344, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59343, + "name": "SystemConfig", + "nodeType": "IdentifierPath", + "referencedDeclaration": 61393, + "src": "2856:12:110" + }, + "referencedDeclaration": 61393, + "src": "2856:12:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + } + }, + "visibility": "public" + }, + { + "id": 59348, + "nodeType": "VariableDeclaration", + "src": "3007:23:110", + "nodes": [], + "constant": false, + "documentation": { + "id": 59346, + "nodeType": "StructuredDocumentation", + "src": "2895:107:110", + "text": "@notice Address that has the ability to pause and unpause withdrawals.\n @custom:network-specific" + }, + "functionSelector": "452a9320", + "mutability": "mutable", + "name": "guardian", + "nameLocation": "3022:8:110", + "scope": 59997, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59347, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3007:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "public" + }, + { + "id": 59359, + "nodeType": "EventDefinition", + "src": "3541:112:110", + "nodes": [], + "anonymous": false, + "documentation": { + "id": 59349, + "nodeType": "StructuredDocumentation", + "src": "3037:499:110", + "text": "@notice Emitted when a transaction is deposited from L1 to L2.\n The parameters of this event are read by the rollup node and used to derive deposit\n transactions on L2.\n @param from Address that triggered the deposit transaction.\n @param to Address that the deposit transaction is directed to.\n @param version Version of this deposit transaction event.\n @param opaqueData ABI encoded deposit data to be parsed off-chain." + }, + "eventSelector": "b3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32", + "name": "TransactionDeposited", + "nameLocation": "3547:20:110", + "parameters": { + "id": 59358, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59351, + "indexed": true, + "mutability": "mutable", + "name": "from", + "nameLocation": "3584:4:110", + "nodeType": "VariableDeclaration", + "scope": 59359, + "src": "3568:20:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59350, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3568:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59353, + "indexed": true, + "mutability": "mutable", + "name": "to", + "nameLocation": "3606:2:110", + "nodeType": "VariableDeclaration", + "scope": 59359, + "src": "3590:18:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59352, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3590:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59355, + "indexed": true, + "mutability": "mutable", + "name": "version", + "nameLocation": "3626:7:110", + "nodeType": "VariableDeclaration", + "scope": 59359, + "src": "3610:23:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 59354, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3610:7:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59357, + "indexed": false, + "mutability": "mutable", + "name": "opaqueData", + "nameLocation": "3641:10:110", + "nodeType": "VariableDeclaration", + "scope": 59359, + "src": "3635:16:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 59356, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3635:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "3567:85:110" + } + }, + { + "id": 59368, + "nodeType": "EventDefinition", + "src": "3957:97:110", + "nodes": [], + "anonymous": false, + "documentation": { + "id": 59360, + "nodeType": "StructuredDocumentation", + "src": "3659:293:110", + "text": "@notice Emitted when a withdrawal transaction is proven.\n @param withdrawalHash Hash of the withdrawal transaction.\n @param from Address that triggered the withdrawal transaction.\n @param to Address that the withdrawal transaction is directed to." + }, + "eventSelector": "67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f62", + "name": "WithdrawalProven", + "nameLocation": "3963:16:110", + "parameters": { + "id": 59367, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59362, + "indexed": true, + "mutability": "mutable", + "name": "withdrawalHash", + "nameLocation": "3996:14:110", + "nodeType": "VariableDeclaration", + "scope": 59368, + "src": "3980:30:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 59361, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3980:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59364, + "indexed": true, + "mutability": "mutable", + "name": "from", + "nameLocation": "4028:4:110", + "nodeType": "VariableDeclaration", + "scope": 59368, + "src": "4012:20:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59363, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4012:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59366, + "indexed": true, + "mutability": "mutable", + "name": "to", + "nameLocation": "4050:2:110", + "nodeType": "VariableDeclaration", + "scope": 59368, + "src": "4034:18:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59365, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4034:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "3979:74:110" + } + }, + { + "id": 59375, + "nodeType": "EventDefinition", + "src": "4275:72:110", + "nodes": [], + "anonymous": false, + "documentation": { + "id": 59369, + "nodeType": "StructuredDocumentation", + "src": "4060:210:110", + "text": "@notice Emitted when a withdrawal transaction is finalized.\n @param withdrawalHash Hash of the withdrawal transaction.\n @param success Whether the withdrawal transaction was successful." + }, + "eventSelector": "db5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b", + "name": "WithdrawalFinalized", + "nameLocation": "4281:19:110", + "parameters": { + "id": 59374, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59371, + "indexed": true, + "mutability": "mutable", + "name": "withdrawalHash", + "nameLocation": "4317:14:110", + "nodeType": "VariableDeclaration", + "scope": 59375, + "src": "4301:30:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 59370, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4301:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59373, + "indexed": false, + "mutability": "mutable", + "name": "success", + "nameLocation": "4338:7:110", + "nodeType": "VariableDeclaration", + "scope": 59375, + "src": "4333:12:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 59372, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4333:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "4300:46:110" + } + }, + { + "id": 59380, + "nodeType": "EventDefinition", + "src": "4474:30:110", + "nodes": [], + "anonymous": false, + "documentation": { + "id": 59376, + "nodeType": "StructuredDocumentation", + "src": "4353:116:110", + "text": "@notice Emitted when the pause is triggered.\n @param account Address of the account triggering the pause." + }, + "eventSelector": "62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258", + "name": "Paused", + "nameLocation": "4480:6:110", + "parameters": { + "id": 59379, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59378, + "indexed": false, + "mutability": "mutable", + "name": "account", + "nameLocation": "4495:7:110", + "nodeType": "VariableDeclaration", + "scope": 59380, + "src": "4487:15:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59377, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4487:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "4486:17:110" + } + }, + { + "id": 59385, + "nodeType": "EventDefinition", + "src": "4630:32:110", + "nodes": [], + "anonymous": false, + "documentation": { + "id": 59381, + "nodeType": "StructuredDocumentation", + "src": "4510:115:110", + "text": "@notice Emitted when the pause is lifted.\n @param account Address of the account triggering the unpause." + }, + "eventSelector": "5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa", + "name": "Unpaused", + "nameLocation": "4636:8:110", + "parameters": { + "id": 59384, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59383, + "indexed": false, + "mutability": "mutable", + "name": "account", + "nameLocation": "4653:7:110", + "nodeType": "VariableDeclaration", + "scope": 59385, + "src": "4645:15:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59382, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4645:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "4644:17:110" + } + }, + { + "id": 59397, + "nodeType": "ModifierDefinition", + "src": "4705:103:110", + "nodes": [], + "body": { + "id": 59396, + "nodeType": "Block", + "src": "4730:78:110", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 59391, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 59389, + "name": "paused", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59337, + "src": "4748:6:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "66616c7365", + "id": 59390, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4758:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "4748:15:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a20706175736564", + "id": 59392, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4765:24:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b66caa771ead292be27065b6fdbf17fc2b4f01cda6f3a71dafb599bc9ced165d", + "typeString": "literal_string \"OptimismPortal: paused\"" + }, + "value": "OptimismPortal: paused" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_b66caa771ead292be27065b6fdbf17fc2b4f01cda6f3a71dafb599bc9ced165d", + "typeString": "literal_string \"OptimismPortal: paused\"" + } + ], + "id": 59388, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "4740:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59393, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4740:50:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59394, + "nodeType": "ExpressionStatement", + "src": "4740:50:110" + }, + { + "id": 59395, + "nodeType": "PlaceholderStatement", + "src": "4800:1:110" + } + ] + }, + "documentation": { + "id": 59386, + "nodeType": "StructuredDocumentation", + "src": "4668:32:110", + "text": "@notice Reverts when paused." + }, + "name": "whenNotPaused", + "nameLocation": "4714:13:110", + "parameters": { + "id": 59387, + "nodeType": "ParameterList", + "parameters": [], + "src": "4727:2:110" + }, + "virtual": false, + "visibility": "internal" + }, + { + "id": 59401, + "nodeType": "VariableDeclaration", + "src": "4878:41:110", + "nodes": [], + "baseFunctions": [ + 75668 + ], + "constant": true, + "documentation": { + "id": 59398, + "nodeType": "StructuredDocumentation", + "src": "4814:59:110", + "text": "@notice Semantic version.\n @custom:semver 1.10.0" + }, + "functionSelector": "54fd4d50", + "mutability": "constant", + "name": "version", + "nameLocation": "4901:7:110", + "scope": 59997, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 59399, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "4878:6:110", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": { + "hexValue": "312e31302e30", + "id": 59400, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4911:8:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_0da5b5e4c121ebd588f58cd2a27b23bac1ec4a69fdf68241600b139ec2a21f64", + "typeString": "literal_string \"1.10.0\"" + }, + "value": "1.10.0" + }, + "visibility": "public" + }, + { + "id": 59426, + "nodeType": "FunctionDefinition", + "src": "4982:219:110", + "nodes": [], + "body": { + "id": 59425, + "nodeType": "Block", + "src": "4996:205:110", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "hexValue": "30", + "id": 59409, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5065:1:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 59408, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5057:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 59407, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5057:7:110", + "typeDescriptions": {} + } + }, + "id": 59410, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5057:10:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 59406, + "name": "L2OutputOracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59272, + "src": "5042:14:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_L2OutputOracle_$59272_$", + "typeString": "type(contract L2OutputOracle)" + } + }, + "id": 59411, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5042:26:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + { + "arguments": [ + { + "hexValue": "30", + "id": 59414, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5101:1:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 59413, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5093:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 59412, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5093:7:110", + "typeDescriptions": {} + } + }, + "id": 59415, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5093:10:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "arguments": [ + { + "arguments": [ + { + "hexValue": "30", + "id": 59419, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5153:1:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 59418, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5145:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 59417, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5145:7:110", + "typeDescriptions": {} + } + }, + "id": 59420, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5145:10:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 59416, + "name": "SystemConfig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 61393, + "src": "5132:12:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SystemConfig_$61393_$", + "typeString": "type(contract SystemConfig)" + } + }, + "id": 59421, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5132:24:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + } + }, + { + "hexValue": "74727565", + "id": 59422, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5179:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 59405, + "name": "initialize", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59469, + "src": "5006:10:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_L2OutputOracle_$59272_$_t_address_$_t_contract$_SystemConfig_$61393_$_t_bool_$returns$__$", + "typeString": "function (contract L2OutputOracle,address,contract SystemConfig,bool)" + } + }, + "id": 59423, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [ + "_l2Oracle", + "_guardian", + "_systemConfig", + "_paused" + ], + "nodeType": "FunctionCall", + "src": "5006:188:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59424, + "nodeType": "ExpressionStatement", + "src": "5006:188:110" + } + ] + }, + "documentation": { + "id": 59402, + "nodeType": "StructuredDocumentation", + "src": "4926:51:110", + "text": "@notice Constructs the OptimismPortal contract." + }, + "implemented": true, + "kind": "constructor", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "parameters": { + "id": 59403, + "nodeType": "ParameterList", + "parameters": [], + "src": "4993:2:110" + }, + "returnParameters": { + "id": 59404, + "nodeType": "ParameterList", + "parameters": [], + "src": "4996:0:110" + }, + "scope": 59997, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "id": 59469, + "nodeType": "FunctionDefinition", + "src": "5491:423:110", + "nodes": [], + "body": { + "id": 59468, + "nodeType": "Block", + "src": "5700:214:110", + "nodes": [], + "statements": [ + { + "expression": { + "id": 59447, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 59444, + "name": "l2Sender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59323, + "src": "5710:8:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "expression": { + "id": 59445, + "name": "Constants", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69571, + "src": "5721:9:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Constants_$69571_$", + "typeString": "type(library Constants)" + } + }, + "id": 59446, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "DEFAULT_L2_SENDER", + "nodeType": "MemberAccess", + "referencedDeclaration": 69529, + "src": "5721:27:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "5710:38:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 59448, + "nodeType": "ExpressionStatement", + "src": "5710:38:110" + }, + { + "expression": { + "id": 59451, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 59449, + "name": "l2Oracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59341, + "src": "5758:8:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 59450, + "name": "_l2Oracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59430, + "src": "5769:9:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "src": "5758:20:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "id": 59452, + "nodeType": "ExpressionStatement", + "src": "5758:20:110" + }, + { + "expression": { + "id": 59455, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 59453, + "name": "systemConfig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59345, + "src": "5788:12:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 59454, + "name": "_systemConfig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59435, + "src": "5803:13:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + } + }, + "src": "5788:28:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + } + }, + "id": 59456, + "nodeType": "ExpressionStatement", + "src": "5788:28:110" + }, + { + "expression": { + "id": 59459, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 59457, + "name": "guardian", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59348, + "src": "5826:8:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 59458, + "name": "_guardian", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59432, + "src": "5837:9:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "5826:20:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 59460, + "nodeType": "ExpressionStatement", + "src": "5826:20:110" + }, + { + "expression": { + "id": 59463, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 59461, + "name": "paused", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59337, + "src": "5856:6:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 59462, + "name": "_paused", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59437, + "src": "5865:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5856:16:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 59464, + "nodeType": "ExpressionStatement", + "src": "5856:16:110" + }, + { + "expression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 59465, + "name": "__ResourceMetering_init", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 60598, + "src": "5882:23:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 59466, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5882:25:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59467, + "nodeType": "ExpressionStatement", + "src": "5882:25:110" + } + ] + }, + "documentation": { + "id": 59427, + "nodeType": "StructuredDocumentation", + "src": "5207:279:110", + "text": "@notice Initializer.\n @param _l2Oracle Address of the L2OutputOracle contract.\n @param _guardian Address that can pause withdrawals.\n @param _paused Sets the contract's pausability state.\n @param _systemConfig Address of the SystemConfig contract." + }, + "functionSelector": "fecf9734", + "implemented": true, + "kind": "function", + "modifiers": [ + { + "arguments": [ + { + "expression": { + "id": 59440, + "name": "Constants", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69571, + "src": "5673:9:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Constants_$69571_$", + "typeString": "type(library Constants)" + } + }, + "id": 59441, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "INITIALIZER", + "nodeType": "MemberAccess", + "referencedDeclaration": 69570, + "src": "5673:21:110", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "id": 59442, + "kind": "modifierInvocation", + "modifierName": { + "id": 59439, + "name": "reinitializer", + "nodeType": "IdentifierPath", + "referencedDeclaration": 32197, + "src": "5659:13:110" + }, + "nodeType": "ModifierInvocation", + "src": "5659:36:110" + } + ], + "name": "initialize", + "nameLocation": "5500:10:110", + "parameters": { + "id": 59438, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59430, + "mutability": "mutable", + "name": "_l2Oracle", + "nameLocation": "5535:9:110", + "nodeType": "VariableDeclaration", + "scope": 59469, + "src": "5520:24:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + }, + "typeName": { + "id": 59429, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59428, + "name": "L2OutputOracle", + "nodeType": "IdentifierPath", + "referencedDeclaration": 59272, + "src": "5520:14:110" + }, + "referencedDeclaration": 59272, + "src": "5520:14:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59432, + "mutability": "mutable", + "name": "_guardian", + "nameLocation": "5562:9:110", + "nodeType": "VariableDeclaration", + "scope": 59469, + "src": "5554:17:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59431, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5554:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59435, + "mutability": "mutable", + "name": "_systemConfig", + "nameLocation": "5594:13:110", + "nodeType": "VariableDeclaration", + "scope": 59469, + "src": "5581:26:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + }, + "typeName": { + "id": 59434, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59433, + "name": "SystemConfig", + "nodeType": "IdentifierPath", + "referencedDeclaration": 61393, + "src": "5581:12:110" + }, + "referencedDeclaration": 61393, + "src": "5581:12:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59437, + "mutability": "mutable", + "name": "_paused", + "nameLocation": "5622:7:110", + "nodeType": "VariableDeclaration", + "scope": 59469, + "src": "5617:12:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 59436, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "5617:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "5510:125:110" + }, + "returnParameters": { + "id": 59443, + "nodeType": "ParameterList", + "parameters": [], + "src": "5700:0:110" + }, + "scope": 59997, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "id": 59479, + "nodeType": "FunctionDefinition", + "src": "5989:92:110", + "nodes": [], + "body": { + "id": 59478, + "nodeType": "Block", + "src": "6049:32:110", + "nodes": [], + "statements": [ + { + "expression": { + "id": 59476, + "name": "l2Oracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59341, + "src": "6066:8:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "functionReturnParameters": 59475, + "id": 59477, + "nodeType": "Return", + "src": "6059:15:110" + } + ] + }, + "documentation": { + "id": 59470, + "nodeType": "StructuredDocumentation", + "src": "5920:64:110", + "text": "@notice Getter for the L2OutputOracle\n @custom:legacy" + }, + "functionSelector": "001c2ff6", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "L2_ORACLE", + "nameLocation": "5998:9:110", + "parameters": { + "id": 59471, + "nodeType": "ParameterList", + "parameters": [], + "src": "6007:2:110" + }, + "returnParameters": { + "id": 59475, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59474, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 59479, + "src": "6033:14:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + }, + "typeName": { + "id": 59473, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59472, + "name": "L2OutputOracle", + "nodeType": "IdentifierPath", + "referencedDeclaration": 59272, + "src": "6033:14:110" + }, + "referencedDeclaration": 59272, + "src": "6033:14:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "visibility": "internal" + } + ], + "src": "6032:16:110" + }, + "scope": 59997, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 59489, + "nodeType": "FunctionDefinition", + "src": "6154:98:110", + "nodes": [], + "body": { + "id": 59488, + "nodeType": "Block", + "src": "6216:36:110", + "nodes": [], + "statements": [ + { + "expression": { + "id": 59486, + "name": "systemConfig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59345, + "src": "6233:12:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + } + }, + "functionReturnParameters": 59485, + "id": 59487, + "nodeType": "Return", + "src": "6226:19:110" + } + ] + }, + "documentation": { + "id": 59480, + "nodeType": "StructuredDocumentation", + "src": "6087:62:110", + "text": "@notice Getter for the SystemConfig\n @custom:legacy" + }, + "functionSelector": "f0498750", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "SYSTEM_CONFIG", + "nameLocation": "6163:13:110", + "parameters": { + "id": 59481, + "nodeType": "ParameterList", + "parameters": [], + "src": "6176:2:110" + }, + "returnParameters": { + "id": 59485, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59484, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 59489, + "src": "6202:12:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + }, + "typeName": { + "id": 59483, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59482, + "name": "SystemConfig", + "nodeType": "IdentifierPath", + "referencedDeclaration": 61393, + "src": "6202:12:110" + }, + "referencedDeclaration": 61393, + "src": "6202:12:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + } + }, + "visibility": "internal" + } + ], + "src": "6201:14:110" + }, + "scope": 59997, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 59498, + "nodeType": "FunctionDefinition", + "src": "6321:84:110", + "nodes": [], + "body": { + "id": 59497, + "nodeType": "Block", + "src": "6373:32:110", + "nodes": [], + "statements": [ + { + "expression": { + "id": 59495, + "name": "guardian", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59348, + "src": "6390:8:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "functionReturnParameters": 59494, + "id": 59496, + "nodeType": "Return", + "src": "6383:15:110" + } + ] + }, + "documentation": { + "id": 59490, + "nodeType": "StructuredDocumentation", + "src": "6258:58:110", + "text": "@notice Getter for the Guardian\n @custom:legacy" + }, + "functionSelector": "724c184c", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "GUARDIAN", + "nameLocation": "6330:8:110", + "parameters": { + "id": 59491, + "nodeType": "ParameterList", + "parameters": [], + "src": "6338:2:110" + }, + "returnParameters": { + "id": 59494, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59493, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 59498, + "src": "6364:7:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59492, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "6364:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "6363:9:110" + }, + "scope": 59997, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 59520, + "nodeType": "FunctionDefinition", + "src": "6447:173:110", + "nodes": [], + "body": { + "id": 59519, + "nodeType": "Block", + "src": "6473:147:110", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 59506, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59503, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "6491:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 59504, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "6491:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 59505, + "name": "guardian", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59348, + "src": "6505:8:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "6491:22:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e2063616e207061757365", + "id": 59507, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6515:41:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_a662ad7462f0018e8b171ba19146984ad716c45a2c8d7c903bdd6e1628b95f08", + "typeString": "literal_string \"OptimismPortal: only guardian can pause\"" + }, + "value": "OptimismPortal: only guardian can pause" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_a662ad7462f0018e8b171ba19146984ad716c45a2c8d7c903bdd6e1628b95f08", + "typeString": "literal_string \"OptimismPortal: only guardian can pause\"" + } + ], + "id": 59502, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "6483:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59508, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6483:74:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59509, + "nodeType": "ExpressionStatement", + "src": "6483:74:110" + }, + { + "expression": { + "id": 59512, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 59510, + "name": "paused", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59337, + "src": "6567:6:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "hexValue": "74727565", + "id": 59511, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6576:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "6567:13:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 59513, + "nodeType": "ExpressionStatement", + "src": "6567:13:110" + }, + { + "eventCall": { + "arguments": [ + { + "expression": { + "id": 59515, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "6602:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 59516, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "6602:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 59514, + "name": "Paused", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59380, + "src": "6595:6:110", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 59517, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6595:18:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59518, + "nodeType": "EmitStatement", + "src": "6590:23:110" + } + ] + }, + "documentation": { + "id": 59499, + "nodeType": "StructuredDocumentation", + "src": "6411:31:110", + "text": "@notice Pauses withdrawals." + }, + "functionSelector": "8456cb59", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "pause", + "nameLocation": "6456:5:110", + "parameters": { + "id": 59500, + "nodeType": "ParameterList", + "parameters": [], + "src": "6461:2:110" + }, + "returnParameters": { + "id": 59501, + "nodeType": "ParameterList", + "parameters": [], + "src": "6473:0:110" + }, + "scope": 59997, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 59542, + "nodeType": "FunctionDefinition", + "src": "6664:180:110", + "nodes": [], + "body": { + "id": 59541, + "nodeType": "Block", + "src": "6692:152:110", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 59528, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59525, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "6710:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 59526, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "6710:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 59527, + "name": "guardian", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59348, + "src": "6724:8:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "6710:22:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e2063616e20756e7061757365", + "id": 59529, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6734:43:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_9b69e94c34df6db33f20b596e1e1d19a7e5843e1b38ae4395fe1bbf64e89e262", + "typeString": "literal_string \"OptimismPortal: only guardian can unpause\"" + }, + "value": "OptimismPortal: only guardian can unpause" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_9b69e94c34df6db33f20b596e1e1d19a7e5843e1b38ae4395fe1bbf64e89e262", + "typeString": "literal_string \"OptimismPortal: only guardian can unpause\"" + } + ], + "id": 59524, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "6702:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59530, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6702:76:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59531, + "nodeType": "ExpressionStatement", + "src": "6702:76:110" + }, + { + "expression": { + "id": 59534, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 59532, + "name": "paused", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59337, + "src": "6788:6:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "hexValue": "66616c7365", + "id": 59533, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6797:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "6788:14:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 59535, + "nodeType": "ExpressionStatement", + "src": "6788:14:110" + }, + { + "eventCall": { + "arguments": [ + { + "expression": { + "id": 59537, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "6826:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 59538, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "6826:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 59536, + "name": "Unpaused", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59385, + "src": "6817:8:110", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 59539, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6817:20:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59540, + "nodeType": "EmitStatement", + "src": "6812:25:110" + } + ] + }, + "documentation": { + "id": 59521, + "nodeType": "StructuredDocumentation", + "src": "6626:33:110", + "text": "@notice Unpauses withdrawals." + }, + "functionSelector": "3f4ba83a", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "unpause", + "nameLocation": "6673:7:110", + "parameters": { + "id": 59522, + "nodeType": "ParameterList", + "parameters": [], + "src": "6680:2:110" + }, + "returnParameters": { + "id": 59523, + "nodeType": "ParameterList", + "parameters": [], + "src": "6692:0:110" + }, + "scope": 59997, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 59557, + "nodeType": "FunctionDefinition", + "src": "7337:120:110", + "nodes": [], + "body": { + "id": 59556, + "nodeType": "Block", + "src": "7410:47:110", + "nodes": [], + "statements": [ + { + "expression": { + "commonType": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + }, + "id": 59554, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + }, + "id": 59552, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 59550, + "name": "_byteCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59545, + "src": "7427:10:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": { + "hexValue": "3136", + "id": 59551, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7440:2:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_16_by_1", + "typeString": "int_const 16" + }, + "value": "16" + }, + "src": "7427:15:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "hexValue": "3231303030", + "id": 59553, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7445:5:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_21000_by_1", + "typeString": "int_const 21000" + }, + "value": "21000" + }, + "src": "7427:23:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + "functionReturnParameters": 59549, + "id": 59555, + "nodeType": "Return", + "src": "7420:30:110" + } + ] + }, + "documentation": { + "id": 59543, + "nodeType": "StructuredDocumentation", + "src": "6850:482:110", + "text": "@notice Computes the minimum gas limit for a deposit.\n The minimum gas limit linearly increases based on the size of the calldata.\n This is to prevent users from creating L2 resource usage without paying for it.\n This function can be used when interacting with the portal to ensure forwards\n compatibility.\n @param _byteCount Number of bytes in the calldata.\n @return The minimum gas limit for a deposit." + }, + "functionSelector": "a35d99df", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "minimumGasLimit", + "nameLocation": "7346:15:110", + "parameters": { + "id": 59546, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59545, + "mutability": "mutable", + "name": "_byteCount", + "nameLocation": "7369:10:110", + "nodeType": "VariableDeclaration", + "scope": 59557, + "src": "7362:17:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + }, + "typeName": { + "id": 59544, + "name": "uint64", + "nodeType": "ElementaryTypeName", + "src": "7362:6:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + "visibility": "internal" + } + ], + "src": "7361:19:110" + }, + "returnParameters": { + "id": 59549, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59548, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 59557, + "src": "7402:6:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + }, + "typeName": { + "id": 59547, + "name": "uint64", + "nodeType": "ElementaryTypeName", + "src": "7402:6:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + "visibility": "internal" + } + ], + "src": "7401:8:110" + }, + "scope": 59997, + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + }, + { + "id": 59575, + "nodeType": "FunctionDefinition", + "src": "7878:130:110", + "nodes": [], + "body": { + "id": 59574, + "nodeType": "Block", + "src": "7905:103:110", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [ + { + "expression": { + "id": 59562, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "7934:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 59563, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "7934:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": { + "id": 59564, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "7946:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 59565, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "src": "7946:9:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 59566, + "name": "RECEIVE_DEFAULT_GAS_LIMIT", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59320, + "src": "7957:25:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + { + "hexValue": "66616c7365", + "id": 59567, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7984:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + { + "arguments": [ + { + "hexValue": "", + "id": 59570, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7997:2:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + }, + "value": "" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + } + ], + "id": 59569, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "7991:5:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes_storage_ptr_$", + "typeString": "type(bytes storage pointer)" + }, + "typeName": { + "id": 59568, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "7991:5:110", + "typeDescriptions": {} + } + }, + "id": 59571, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7991:9:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 59561, + "name": "depositTransaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59961, + "src": "7915:18:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_uint64_$_t_bool_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (address,uint256,uint64,bool,bytes memory)" + } + }, + "id": 59572, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7915:86:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59573, + "nodeType": "ExpressionStatement", + "src": "7915:86:110" + } + ] + }, + "documentation": { + "id": 59558, + "nodeType": "StructuredDocumentation", + "src": "7463:368:110", + "text": "@notice Accepts value so that users can send ETH directly to this contract and have the\n funds be deposited to their address on L2. This is intended as a convenience\n function for EOAs. Contracts should call the depositTransaction() function directly\n otherwise any deposited funds will be lost due to address aliasing." + }, + "implemented": true, + "kind": "receive", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "parameters": { + "id": 59559, + "nodeType": "ParameterList", + "parameters": [], + "src": "7885:2:110" + }, + "returnParameters": { + "id": 59560, + "nodeType": "ParameterList", + "parameters": [], + "src": "7905:0:110" + }, + "scope": 59997, + "stateMutability": "payable", + "virtual": false, + "visibility": "external" + }, + { + "id": 59580, + "nodeType": "FunctionDefinition", + "src": "8222:77:110", + "nodes": [], + "body": { + "id": 59579, + "nodeType": "Block", + "src": "8260:39:110", + "nodes": [], + "statements": [] + }, + "documentation": { + "id": 59576, + "nodeType": "StructuredDocumentation", + "src": "8014:203:110", + "text": "@notice Accepts ETH value without triggering a deposit to L2.\n This function mainly exists for the sake of the migration between the legacy\n Optimism system and Bedrock." + }, + "functionSelector": "8b4c40b0", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "donateETH", + "nameLocation": "8231:9:110", + "parameters": { + "id": 59577, + "nodeType": "ParameterList", + "parameters": [], + "src": "8240:2:110" + }, + "returnParameters": { + "id": 59578, + "nodeType": "ParameterList", + "parameters": [], + "src": "8260:0:110" + }, + "scope": 59997, + "stateMutability": "payable", + "virtual": false, + "visibility": "external" + }, + { + "id": 59593, + "nodeType": "FunctionDefinition", + "src": "8548:152:110", + "nodes": [], + "body": { + "id": 59592, + "nodeType": "Block", + "src": "8647:53:110", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "id": 59588, + "name": "systemConfig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59345, + "src": "8664:12:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SystemConfig_$61393", + "typeString": "contract SystemConfig" + } + }, + "id": 59589, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "resourceConfig", + "nodeType": "MemberAccess", + "referencedDeclaration": 61313, + "src": "8664:27:110", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_struct$_ResourceConfig_$60283_memory_ptr_$", + "typeString": "function () view external returns (struct ResourceMetering.ResourceConfig memory)" + } + }, + "id": 59590, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8664:29:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_struct$_ResourceConfig_$60283_memory_ptr", + "typeString": "struct ResourceMetering.ResourceConfig memory" + } + }, + "functionReturnParameters": 59587, + "id": 59591, + "nodeType": "Return", + "src": "8657:36:110" + } + ] + }, + "baseFunctions": [ + 60579 + ], + "documentation": { + "id": 59581, + "nodeType": "StructuredDocumentation", + "src": "8305:238:110", + "text": "@notice Getter for the resource config.\n Used internally by the ResourceMetering contract.\n The SystemConfig is the source of truth for the resource config.\n @return ResourceMetering ResourceConfig" + }, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_resourceConfig", + "nameLocation": "8557:15:110", + "overrides": { + "id": 59583, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "8589:8:110" + }, + "parameters": { + "id": 59582, + "nodeType": "ParameterList", + "parameters": [], + "src": "8572:2:110" + }, + "returnParameters": { + "id": 59587, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59586, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 59593, + "src": "8607:38:110", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ResourceConfig_$60283_memory_ptr", + "typeString": "struct ResourceMetering.ResourceConfig" + }, + "typeName": { + "id": 59585, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59584, + "name": "ResourceMetering.ResourceConfig", + "nodeType": "IdentifierPath", + "referencedDeclaration": 60283, + "src": "8607:31:110" + }, + "referencedDeclaration": 60283, + "src": "8607:31:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ResourceConfig_$60283_storage_ptr", + "typeString": "struct ResourceMetering.ResourceConfig" + } + }, + "visibility": "internal" + } + ], + "src": "8606:40:110" + }, + "scope": 59997, + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + }, + { + "id": 59725, + "nodeType": "FunctionDefinition", + "src": "9088:3746:110", + "nodes": [], + "body": { + "id": 59724, + "nodeType": "Block", + "src": "9353:3481:110", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 59617, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59611, + "name": "_tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59597, + "src": "9598:3:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + }, + "id": 59612, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "target", + "nodeType": "MemberAccess", + "referencedDeclaration": 70587, + "src": "9598:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "arguments": [ + { + "id": 59615, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "9620:4:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_OptimismPortal_$59997", + "typeString": "contract OptimismPortal" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_OptimismPortal_$59997", + "typeString": "contract OptimismPortal" + } + ], + "id": 59614, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "9612:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 59613, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "9612:7:110", + "typeDescriptions": {} + } + }, + "id": 59616, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9612:13:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "9598:27:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e64206d6573736167657320746f2074686520706f7274616c20636f6e7472616374", + "id": 59618, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9627:65:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_57e41062e2e7b97ddf730827f5249d28f602a3846dfe107ce36292fb1c029eb8", + "typeString": "literal_string \"OptimismPortal: you cannot send messages to the portal contract\"" + }, + "value": "OptimismPortal: you cannot send messages to the portal contract" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_57e41062e2e7b97ddf730827f5249d28f602a3846dfe107ce36292fb1c029eb8", + "typeString": "literal_string \"OptimismPortal: you cannot send messages to the portal contract\"" + } + ], + "id": 59610, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "9590:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59619, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9590:103:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59620, + "nodeType": "ExpressionStatement", + "src": "9590:103:110" + }, + { + "assignments": [ + 59622 + ], + "declarations": [ + { + "constant": false, + "id": 59622, + "mutability": "mutable", + "name": "outputRoot", + "nameLocation": "9878:10:110", + "nodeType": "VariableDeclaration", + "scope": 59724, + "src": "9870:18:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 59621, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9870:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 59628, + "initialValue": { + "expression": { + "arguments": [ + { + "id": 59625, + "name": "_l2OutputIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59599, + "src": "9912:14:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 59623, + "name": "l2Oracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59341, + "src": "9891:8:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "id": 59624, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getL2Output", + "nodeType": "MemberAccess", + "referencedDeclaration": 59112, + "src": "9891:20:110", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_uint256_$returns$_t_struct$_OutputProposal_$70553_memory_ptr_$", + "typeString": "function (uint256) view external returns (struct Types.OutputProposal memory)" + } + }, + "id": 59626, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9891:36:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputProposal_$70553_memory_ptr", + "typeString": "struct Types.OutputProposal memory" + } + }, + "id": 59627, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "outputRoot", + "nodeType": "MemberAccess", + "referencedDeclaration": 70548, + "src": "9891:47:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "9870:68:110" + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 59635, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 59630, + "name": "outputRoot", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59622, + "src": "10058:10:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "arguments": [ + { + "id": 59633, + "name": "_outputRootProof", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59602, + "src": "10100:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputRootProof_$70562_calldata_ptr", + "typeString": "struct Types.OutputRootProof calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_OutputRootProof_$70562_calldata_ptr", + "typeString": "struct Types.OutputRootProof calldata" + } + ], + "expression": { + "id": 59631, + "name": "Hashing", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 70279, + "src": "10072:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Hashing_$70279_$", + "typeString": "type(library Hashing)" + } + }, + "id": 59632, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "hashOutputRootProof", + "nodeType": "MemberAccess", + "referencedDeclaration": 70278, + "src": "10072:27:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_struct$_OutputRootProof_$70562_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (struct Types.OutputRootProof memory) pure returns (bytes32)" + } + }, + "id": 59634, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10072:45:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "10058:59:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a20696e76616c6964206f757470757420726f6f742070726f6f66", + "id": 59636, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10119:43:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_490ec653897228799e7e4c4af8b1fd3b4a0688df98d026b46afa352ce9876996", + "typeString": "literal_string \"OptimismPortal: invalid output root proof\"" + }, + "value": "OptimismPortal: invalid output root proof" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_490ec653897228799e7e4c4af8b1fd3b4a0688df98d026b46afa352ce9876996", + "typeString": "literal_string \"OptimismPortal: invalid output root proof\"" + } + ], + "id": 59629, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "10037:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59637, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10037:135:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59638, + "nodeType": "ExpressionStatement", + "src": "10037:135:110" + }, + { + "assignments": [ + 59640 + ], + "declarations": [ + { + "constant": false, + "id": 59640, + "mutability": "mutable", + "name": "withdrawalHash", + "nameLocation": "10291:14:110", + "nodeType": "VariableDeclaration", + "scope": 59724, + "src": "10283:22:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 59639, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10283:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 59645, + "initialValue": { + "arguments": [ + { + "id": 59643, + "name": "_tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59597, + "src": "10331:3:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + ], + "expression": { + "id": 59641, + "name": "Hashing", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 70279, + "src": "10308:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Hashing_$70279_$", + "typeString": "type(library Hashing)" + } + }, + "id": 59642, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "hashWithdrawal", + "nodeType": "MemberAccess", + "referencedDeclaration": 70254, + "src": "10308:22:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_struct$_WithdrawalTransaction_$70594_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (struct Types.WithdrawalTransaction memory) pure returns (bytes32)" + } + }, + "id": 59644, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10308:27:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "10283:52:110" + }, + { + "assignments": [ + 59648 + ], + "declarations": [ + { + "constant": false, + "id": 59648, + "mutability": "mutable", + "name": "provenWithdrawal", + "nameLocation": "10369:16:110", + "nodeType": "VariableDeclaration", + "scope": 59724, + "src": "10345:40:110", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal" + }, + "typeName": { + "id": 59647, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59646, + "name": "ProvenWithdrawal", + "nodeType": "IdentifierPath", + "referencedDeclaration": 59312, + "src": "10345:16:110" + }, + "referencedDeclaration": 59312, + "src": "10345:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_storage_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal" + } + }, + "visibility": "internal" + } + ], + "id": 59652, + "initialValue": { + "baseExpression": { + "id": 59649, + "name": "provenWithdrawals", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59334, + "src": "10388:17:110", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_ProvenWithdrawal_$59312_storage_$", + "typeString": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal storage ref)" + } + }, + "id": 59651, + "indexExpression": { + "id": 59650, + "name": "withdrawalHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59640, + "src": "10406:14:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10388:33:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_storage", + "typeString": "struct OptimismPortal.ProvenWithdrawal storage ref" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "10345:76:110" + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 59667, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + }, + "id": 59657, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59654, + "name": "provenWithdrawal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59648, + "src": "10975:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal memory" + } + }, + "id": 59655, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timestamp", + "nodeType": "MemberAccess", + "referencedDeclaration": 59309, + "src": "10975:26:110", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 59656, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11005:1:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "10975:31:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 59666, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "arguments": [ + { + "expression": { + "id": 59660, + "name": "provenWithdrawal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59648, + "src": "11047:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal memory" + } + }, + "id": 59661, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "l2OutputIndex", + "nodeType": "MemberAccess", + "referencedDeclaration": 59311, + "src": "11047:30:110", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + ], + "expression": { + "id": 59658, + "name": "l2Oracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59341, + "src": "11026:8:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "id": 59659, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getL2Output", + "nodeType": "MemberAccess", + "referencedDeclaration": 59112, + "src": "11026:20:110", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_uint256_$returns$_t_struct$_OutputProposal_$70553_memory_ptr_$", + "typeString": "function (uint256) view external returns (struct Types.OutputProposal memory)" + } + }, + "id": 59662, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11026:52:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputProposal_$70553_memory_ptr", + "typeString": "struct Types.OutputProposal memory" + } + }, + "id": 59663, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "outputRoot", + "nodeType": "MemberAccess", + "referencedDeclaration": 70548, + "src": "11026:63:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "expression": { + "id": 59664, + "name": "provenWithdrawal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59648, + "src": "11093:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal memory" + } + }, + "id": 59665, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "outputRoot", + "nodeType": "MemberAccess", + "referencedDeclaration": 59307, + "src": "11093:27:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "11026:94:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "10975:145:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a207769746864726177616c20686173682068617320616c7265616479206265656e2070726f76656e", + "id": 59668, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11134:57:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5238e365e021f6fd781c2264a5a09100f0670031b56dacfc224b453789ac1dd0", + "typeString": "literal_string \"OptimismPortal: withdrawal hash has already been proven\"" + }, + "value": "OptimismPortal: withdrawal hash has already been proven" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5238e365e021f6fd781c2264a5a09100f0670031b56dacfc224b453789ac1dd0", + "typeString": "literal_string \"OptimismPortal: withdrawal hash has already been proven\"" + } + ], + "id": 59653, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "10954:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59669, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10954:247:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59670, + "nodeType": "ExpressionStatement", + "src": "10954:247:110" + }, + { + "assignments": [ + 59672 + ], + "declarations": [ + { + "constant": false, + "id": 59672, + "mutability": "mutable", + "name": "storageKey", + "nameLocation": "11445:10:110", + "nodeType": "VariableDeclaration", + "scope": 59724, + "src": "11437:18:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 59671, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "11437:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 59683, + "initialValue": { + "arguments": [ + { + "arguments": [ + { + "id": 59676, + "name": "withdrawalHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59640, + "src": "11509:14:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "hexValue": "30", + "id": 59679, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11549:1:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 59678, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "11541:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 59677, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11541:7:110", + "typeDescriptions": {} + } + }, + "id": 59680, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11541:10:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 59674, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "11481:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 59675, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "11481:10:110", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 59681, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11481:147:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 59673, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -8, + "src": "11458:9:110", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 59682, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11458:180:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "11437:201:110" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "id": 59689, + "name": "storageKey", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59672, + "src": "12057:10:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 59687, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "12046:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 59688, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "12046:10:110", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 59690, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12046:22:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + { + "hexValue": "01", + "id": 59691, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "hexString", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12070:7:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2", + "typeString": "literal_string hex\"01\"" + }, + "value": "\u0001" + }, + { + "id": 59692, + "name": "_withdrawalProof", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59605, + "src": "12079:16:110", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + } + }, + { + "expression": { + "id": 59693, + "name": "_outputRootProof", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59602, + "src": "12097:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputRootProof_$70562_calldata_ptr", + "typeString": "struct Types.OutputRootProof calldata" + } + }, + "id": 59694, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "messagePasserStorageRoot", + "nodeType": "MemberAccess", + "referencedDeclaration": 70559, + "src": "12097:41:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + }, + { + "typeIdentifier": "t_stringliteral_5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2", + "typeString": "literal_string hex\"01\"" + }, + { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 59685, + "name": "SecureMerkleTrie", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 72279, + "src": "11991:16:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SecureMerkleTrie_$72279_$", + "typeString": "type(library SecureMerkleTrie)" + } + }, + "id": 59686, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "verifyInclusionProof", + "nodeType": "MemberAccess", + "referencedDeclaration": 72231, + "src": "11991:37:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_memory_ptr_$_t_bytes_memory_ptr_$_t_array$_t_bytes_memory_ptr_$dyn_memory_ptr_$_t_bytes32_$returns$_t_bool_$", + "typeString": "function (bytes memory,bytes memory,bytes memory[] memory,bytes32) pure returns (bool)" + } + }, + "id": 59695, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11991:161:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a20696e76616c6964207769746864726177616c20696e636c7573696f6e2070726f6f66", + "id": 59696, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12166:52:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_11b666636981dad70da1c1a9e87589eb7d9c042eacd4d25e887aac557f6cd6b9", + "typeString": "literal_string \"OptimismPortal: invalid withdrawal inclusion proof\"" + }, + "value": "OptimismPortal: invalid withdrawal inclusion proof" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_11b666636981dad70da1c1a9e87589eb7d9c042eacd4d25e887aac557f6cd6b9", + "typeString": "literal_string \"OptimismPortal: invalid withdrawal inclusion proof\"" + } + ], + "id": 59684, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "11970:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59697, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11970:258:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59698, + "nodeType": "ExpressionStatement", + "src": "11970:258:110" + }, + { + "expression": { + "id": 59714, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "baseExpression": { + "id": 59699, + "name": "provenWithdrawals", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59334, + "src": "12510:17:110", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_ProvenWithdrawal_$59312_storage_$", + "typeString": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal storage ref)" + } + }, + "id": 59701, + "indexExpression": { + "id": 59700, + "name": "withdrawalHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59640, + "src": "12528:14:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "12510:33:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_storage", + "typeString": "struct OptimismPortal.ProvenWithdrawal storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 59703, + "name": "outputRoot", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59622, + "src": "12589:10:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "expression": { + "id": 59706, + "name": "block", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -4, + "src": "12632:5:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_block", + "typeString": "block" + } + }, + "id": 59707, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "timestamp", + "nodeType": "MemberAccess", + "src": "12632:15:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 59705, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "12624:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint128_$", + "typeString": "type(uint128)" + }, + "typeName": { + "id": 59704, + "name": "uint128", + "nodeType": "ElementaryTypeName", + "src": "12624:7:110", + "typeDescriptions": {} + } + }, + "id": 59708, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12624:24:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + }, + { + "arguments": [ + { + "id": 59711, + "name": "_l2OutputIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59599, + "src": "12685:14:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 59710, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "12677:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint128_$", + "typeString": "type(uint128)" + }, + "typeName": { + "id": 59709, + "name": "uint128", + "nodeType": "ElementaryTypeName", + "src": "12677:7:110", + "typeDescriptions": {} + } + }, + "id": 59712, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12677:23:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + }, + { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + ], + "id": 59702, + "name": "ProvenWithdrawal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59312, + "src": "12546:16:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_ProvenWithdrawal_$59312_storage_ptr_$", + "typeString": "type(struct OptimismPortal.ProvenWithdrawal storage pointer)" + } + }, + "id": 59713, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [ + "outputRoot", + "timestamp", + "l2OutputIndex" + ], + "nodeType": "FunctionCall", + "src": "12546:165:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal memory" + } + }, + "src": "12510:201:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_storage", + "typeString": "struct OptimismPortal.ProvenWithdrawal storage ref" + } + }, + "id": 59715, + "nodeType": "ExpressionStatement", + "src": "12510:201:110" + }, + { + "eventCall": { + "arguments": [ + { + "id": 59717, + "name": "withdrawalHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59640, + "src": "12788:14:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": { + "id": 59718, + "name": "_tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59597, + "src": "12804:3:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + }, + "id": 59719, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": 70585, + "src": "12804:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": { + "id": 59720, + "name": "_tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59597, + "src": "12816:3:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + }, + "id": 59721, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "target", + "nodeType": "MemberAccess", + "referencedDeclaration": 70587, + "src": "12816:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 59716, + "name": "WithdrawalProven", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59368, + "src": "12771:16:110", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_address_$_t_address_$returns$__$", + "typeString": "function (bytes32,address,address)" + } + }, + "id": 59722, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12771:56:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59723, + "nodeType": "EmitStatement", + "src": "12766:61:110" + } + ] + }, + "documentation": { + "id": 59594, + "nodeType": "StructuredDocumentation", + "src": "8706:377:110", + "text": "@notice Proves a withdrawal transaction.\n @param _tx Withdrawal transaction to finalize.\n @param _l2OutputIndex L2 output index to prove against.\n @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root.\n @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract." + }, + "functionSelector": "4870496f", + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 59608, + "kind": "modifierInvocation", + "modifierName": { + "id": 59607, + "name": "whenNotPaused", + "nodeType": "IdentifierPath", + "referencedDeclaration": 59397, + "src": "9335:13:110" + }, + "nodeType": "ModifierInvocation", + "src": "9335:13:110" + } + ], + "name": "proveWithdrawalTransaction", + "nameLocation": "9097:26:110", + "parameters": { + "id": 59606, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59597, + "mutability": "mutable", + "name": "_tx", + "nameLocation": "9168:3:110", + "nodeType": "VariableDeclaration", + "scope": 59725, + "src": "9133:38:110", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction" + }, + "typeName": { + "id": 59596, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59595, + "name": "Types.WithdrawalTransaction", + "nodeType": "IdentifierPath", + "referencedDeclaration": 70594, + "src": "9133:27:110" + }, + "referencedDeclaration": 70594, + "src": "9133:27:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_storage_ptr", + "typeString": "struct Types.WithdrawalTransaction" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59599, + "mutability": "mutable", + "name": "_l2OutputIndex", + "nameLocation": "9189:14:110", + "nodeType": "VariableDeclaration", + "scope": 59725, + "src": "9181:22:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 59598, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9181:7:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59602, + "mutability": "mutable", + "name": "_outputRootProof", + "nameLocation": "9244:16:110", + "nodeType": "VariableDeclaration", + "scope": 59725, + "src": "9213:47:110", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputRootProof_$70562_calldata_ptr", + "typeString": "struct Types.OutputRootProof" + }, + "typeName": { + "id": 59601, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59600, + "name": "Types.OutputRootProof", + "nodeType": "IdentifierPath", + "referencedDeclaration": 70562, + "src": "9213:21:110" + }, + "referencedDeclaration": 70562, + "src": "9213:21:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputRootProof_$70562_storage_ptr", + "typeString": "struct Types.OutputRootProof" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59605, + "mutability": "mutable", + "name": "_withdrawalProof", + "nameLocation": "9287:16:110", + "nodeType": "VariableDeclaration", + "scope": 59725, + "src": "9270:33:110", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes[]" + }, + "typeName": { + "baseType": { + "id": 59603, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "9270:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "id": 59604, + "nodeType": "ArrayTypeName", + "src": "9270:7:110", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_storage_$dyn_storage_ptr", + "typeString": "bytes[]" + } + }, + "visibility": "internal" + } + ], + "src": "9123:186:110" + }, + "returnParameters": { + "id": 59609, + "nodeType": "ParameterList", + "parameters": [], + "src": "9353:0:110" + }, + "scope": 59997, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 59870, + "nodeType": "FunctionDefinition", + "src": "12947:4839:110", + "nodes": [], + "body": { + "id": 59869, + "nodeType": "Block", + "src": "13049:4737:110", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 59738, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 59735, + "name": "l2Sender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59323, + "src": "13315:8:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "id": 59736, + "name": "Constants", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69571, + "src": "13327:9:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Constants_$69571_$", + "typeString": "type(library Constants)" + } + }, + "id": 59737, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "DEFAULT_L2_SENDER", + "nodeType": "MemberAccess", + "referencedDeclaration": 69529, + "src": "13327:27:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "13315:39:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a2063616e206f6e6c792074726967676572206f6e65207769746864726177616c20706572207472616e73616374696f6e", + "id": 59739, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13356:65:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_452e6500a4013b85635a7a9b231d68a5197c7f7579d0b96d0b2f2e5fe6b5995b", + "typeString": "literal_string \"OptimismPortal: can only trigger one withdrawal per transaction\"" + }, + "value": "OptimismPortal: can only trigger one withdrawal per transaction" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_452e6500a4013b85635a7a9b231d68a5197c7f7579d0b96d0b2f2e5fe6b5995b", + "typeString": "literal_string \"OptimismPortal: can only trigger one withdrawal per transaction\"" + } + ], + "id": 59734, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "13294:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59740, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13294:137:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59741, + "nodeType": "ExpressionStatement", + "src": "13294:137:110" + }, + { + "assignments": [ + 59743 + ], + "declarations": [ + { + "constant": false, + "id": 59743, + "mutability": "mutable", + "name": "withdrawalHash", + "nameLocation": "13522:14:110", + "nodeType": "VariableDeclaration", + "scope": 59869, + "src": "13514:22:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 59742, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "13514:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 59748, + "initialValue": { + "arguments": [ + { + "id": 59746, + "name": "_tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59729, + "src": "13562:3:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + ], + "expression": { + "id": 59744, + "name": "Hashing", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 70279, + "src": "13539:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Hashing_$70279_$", + "typeString": "type(library Hashing)" + } + }, + "id": 59745, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "hashWithdrawal", + "nodeType": "MemberAccess", + "referencedDeclaration": 70254, + "src": "13539:22:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_struct$_WithdrawalTransaction_$70594_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (struct Types.WithdrawalTransaction memory) pure returns (bytes32)" + } + }, + "id": 59747, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13539:27:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "13514:52:110" + }, + { + "assignments": [ + 59751 + ], + "declarations": [ + { + "constant": false, + "id": 59751, + "mutability": "mutable", + "name": "provenWithdrawal", + "nameLocation": "13600:16:110", + "nodeType": "VariableDeclaration", + "scope": 59869, + "src": "13576:40:110", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal" + }, + "typeName": { + "id": 59750, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59749, + "name": "ProvenWithdrawal", + "nodeType": "IdentifierPath", + "referencedDeclaration": 59312, + "src": "13576:16:110" + }, + "referencedDeclaration": 59312, + "src": "13576:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_storage_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal" + } + }, + "visibility": "internal" + } + ], + "id": 59755, + "initialValue": { + "baseExpression": { + "id": 59752, + "name": "provenWithdrawals", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59334, + "src": "13619:17:110", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_ProvenWithdrawal_$59312_storage_$", + "typeString": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal storage ref)" + } + }, + "id": 59754, + "indexExpression": { + "id": 59753, + "name": "withdrawalHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59743, + "src": "13637:14:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "13619:33:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_storage", + "typeString": "struct OptimismPortal.ProvenWithdrawal storage ref" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "13576:76:110" + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + }, + "id": 59760, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59757, + "name": "provenWithdrawal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59751, + "src": "13902:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal memory" + } + }, + "id": 59758, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timestamp", + "nodeType": "MemberAccess", + "referencedDeclaration": 59309, + "src": "13902:26:110", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "hexValue": "30", + "id": 59759, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13932:1:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13902:31:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e6f74206265656e2070726f76656e20796574", + "id": 59761, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13935:52:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_bc94f9f4f2ecd47ddd807efca122bcc34325481f7fe9d60687e25c709aff1610", + "typeString": "literal_string \"OptimismPortal: withdrawal has not been proven yet\"" + }, + "value": "OptimismPortal: withdrawal has not been proven yet" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_bc94f9f4f2ecd47ddd807efca122bcc34325481f7fe9d60687e25c709aff1610", + "typeString": "literal_string \"OptimismPortal: withdrawal has not been proven yet\"" + } + ], + "id": 59756, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "13894:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59762, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13894:94:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59763, + "nodeType": "ExpressionStatement", + "src": "13894:94:110" + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 59770, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59765, + "name": "provenWithdrawal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59751, + "src": "14275:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal memory" + } + }, + "id": 59766, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timestamp", + "nodeType": "MemberAccess", + "referencedDeclaration": 59309, + "src": "14275:26:110", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "id": 59767, + "name": "l2Oracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59341, + "src": "14305:8:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "id": 59768, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "startingTimestamp", + "nodeType": "MemberAccess", + "referencedDeclaration": 58789, + "src": "14305:26:110", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint256_$", + "typeString": "function () view external returns (uint256)" + } + }, + "id": 59769, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14305:28:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "14275:58:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657374616d70206c657373207468616e204c32204f7261636c65207374617274696e672074696d657374616d70", + "id": 59771, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14347:77:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5c7c78dd7f8d5d79f2ff5ac1a4442209661a78fffa24392f88331b760a60bedd", + "typeString": "literal_string \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"" + }, + "value": "OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5c7c78dd7f8d5d79f2ff5ac1a4442209661a78fffa24392f88331b760a60bedd", + "typeString": "literal_string \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"" + } + ], + "id": 59764, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "14254:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59772, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14254:180:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59773, + "nodeType": "ExpressionStatement", + "src": "14254:180:110" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "expression": { + "id": 59776, + "name": "provenWithdrawal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59751, + "src": "14853:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal memory" + } + }, + "id": 59777, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timestamp", + "nodeType": "MemberAccess", + "referencedDeclaration": 59309, + "src": "14853:26:110", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + ], + "id": 59775, + "name": "_isFinalizationPeriodElapsed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59996, + "src": "14824:28:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_bool_$", + "typeString": "function (uint256) view returns (bool)" + } + }, + "id": 59778, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14824:56:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a2070726f76656e207769746864726177616c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c6170736564", + "id": 59779, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14894:71:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_98a66ca0d4a8e5a839585f0aa5b4b8fc94a946382443fc5580ee1ed6e6237f70", + "typeString": "literal_string \"OptimismPortal: proven withdrawal finalization period has not elapsed\"" + }, + "value": "OptimismPortal: proven withdrawal finalization period has not elapsed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_98a66ca0d4a8e5a839585f0aa5b4b8fc94a946382443fc5580ee1ed6e6237f70", + "typeString": "literal_string \"OptimismPortal: proven withdrawal finalization period has not elapsed\"" + } + ], + "id": 59774, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "14803:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59780, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14803:172:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59781, + "nodeType": "ExpressionStatement", + "src": "14803:172:110" + }, + { + "assignments": [ + 59786 + ], + "declarations": [ + { + "constant": false, + "id": 59786, + "mutability": "mutable", + "name": "proposal", + "nameLocation": "15174:8:110", + "nodeType": "VariableDeclaration", + "scope": 59869, + "src": "15146:36:110", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputProposal_$70553_memory_ptr", + "typeString": "struct Types.OutputProposal" + }, + "typeName": { + "id": 59785, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59784, + "name": "Types.OutputProposal", + "nodeType": "IdentifierPath", + "referencedDeclaration": 70553, + "src": "15146:20:110" + }, + "referencedDeclaration": 70553, + "src": "15146:20:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputProposal_$70553_storage_ptr", + "typeString": "struct Types.OutputProposal" + } + }, + "visibility": "internal" + } + ], + "id": 59792, + "initialValue": { + "arguments": [ + { + "expression": { + "id": 59789, + "name": "provenWithdrawal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59751, + "src": "15206:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal memory" + } + }, + "id": 59790, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "l2OutputIndex", + "nodeType": "MemberAccess", + "referencedDeclaration": 59311, + "src": "15206:30:110", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + ], + "expression": { + "id": 59787, + "name": "l2Oracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59341, + "src": "15185:8:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "id": 59788, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getL2Output", + "nodeType": "MemberAccess", + "referencedDeclaration": 59112, + "src": "15185:20:110", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_uint256_$returns$_t_struct$_OutputProposal_$70553_memory_ptr_$", + "typeString": "function (uint256) view external returns (struct Types.OutputProposal memory)" + } + }, + "id": 59791, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15185:52:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputProposal_$70553_memory_ptr", + "typeString": "struct Types.OutputProposal memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "15146:91:110" + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 59798, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59794, + "name": "proposal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59786, + "src": "15525:8:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputProposal_$70553_memory_ptr", + "typeString": "struct Types.OutputProposal memory" + } + }, + "id": 59795, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "outputRoot", + "nodeType": "MemberAccess", + "referencedDeclaration": 70548, + "src": "15525:19:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "id": 59796, + "name": "provenWithdrawal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59751, + "src": "15548:16:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ProvenWithdrawal_$59312_memory_ptr", + "typeString": "struct OptimismPortal.ProvenWithdrawal memory" + } + }, + "id": 59797, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "outputRoot", + "nodeType": "MemberAccess", + "referencedDeclaration": 59307, + "src": "15548:27:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "15525:50:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f76656e206973206e6f74207468652073616d652061732063757272656e74206f757470757420726f6f74", + "id": 59799, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "15589:75:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2bee9e90a055fc3fdea28727a1d039ffb281ae00c8962ca3262d0dabb187a280", + "typeString": "literal_string \"OptimismPortal: output root proven is not the same as current output root\"" + }, + "value": "OptimismPortal: output root proven is not the same as current output root" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_2bee9e90a055fc3fdea28727a1d039ffb281ae00c8962ca3262d0dabb187a280", + "typeString": "literal_string \"OptimismPortal: output root proven is not the same as current output root\"" + } + ], + "id": 59793, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "15504:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59800, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15504:170:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59801, + "nodeType": "ExpressionStatement", + "src": "15504:170:110" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "expression": { + "id": 59804, + "name": "proposal", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59786, + "src": "15802:8:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputProposal_$70553_memory_ptr", + "typeString": "struct Types.OutputProposal memory" + } + }, + "id": 59805, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timestamp", + "nodeType": "MemberAccess", + "referencedDeclaration": 70550, + "src": "15802:18:110", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + ], + "id": 59803, + "name": "_isFinalizationPeriodElapsed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59996, + "src": "15773:28:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_bool_$", + "typeString": "function (uint256) view returns (bool)" + } + }, + "id": 59806, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15773:48:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c6170736564", + "id": 59807, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "15835:69:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e2e53e5f2e5c146290963511529e48aa3e1570a42475ccc1fb3eba5190175c74", + "typeString": "literal_string \"OptimismPortal: output proposal finalization period has not elapsed\"" + }, + "value": "OptimismPortal: output proposal finalization period has not elapsed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e2e53e5f2e5c146290963511529e48aa3e1570a42475ccc1fb3eba5190175c74", + "typeString": "literal_string \"OptimismPortal: output proposal finalization period has not elapsed\"" + } + ], + "id": 59802, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "15752:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59808, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15752:162:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59809, + "nodeType": "ExpressionStatement", + "src": "15752:162:110" + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 59815, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "baseExpression": { + "id": 59811, + "name": "finalizedWithdrawals", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59328, + "src": "16030:20:110", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_bool_$", + "typeString": "mapping(bytes32 => bool)" + } + }, + "id": 59813, + "indexExpression": { + "id": 59812, + "name": "withdrawalHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59743, + "src": "16051:14:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "16030:36:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "66616c7365", + "id": 59814, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "16070:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "16030:45:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a207769746864726177616c2068617320616c7265616479206265656e2066696e616c697a6564", + "id": 59816, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "16077:55:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2a1157cbf4171a399f26106a5211324151853c78d2faca1fb1d3acbf755aa485", + "typeString": "literal_string \"OptimismPortal: withdrawal has already been finalized\"" + }, + "value": "OptimismPortal: withdrawal has already been finalized" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_2a1157cbf4171a399f26106a5211324151853c78d2faca1fb1d3acbf755aa485", + "typeString": "literal_string \"OptimismPortal: withdrawal has already been finalized\"" + } + ], + "id": 59810, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "16022:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59817, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16022:111:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59818, + "nodeType": "ExpressionStatement", + "src": "16022:111:110" + }, + { + "expression": { + "id": 59823, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "baseExpression": { + "id": 59819, + "name": "finalizedWithdrawals", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59328, + "src": "16213:20:110", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_bool_$", + "typeString": "mapping(bytes32 => bool)" + } + }, + "id": 59821, + "indexExpression": { + "id": 59820, + "name": "withdrawalHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59743, + "src": "16234:14:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "16213:36:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "hexValue": "74727565", + "id": 59822, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "16252:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "16213:43:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 59824, + "nodeType": "ExpressionStatement", + "src": "16213:43:110" + }, + { + "expression": { + "id": 59828, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 59825, + "name": "l2Sender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59323, + "src": "16350:8:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "expression": { + "id": 59826, + "name": "_tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59729, + "src": "16361:3:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + }, + "id": 59827, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": 70585, + "src": "16361:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "16350:21:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 59829, + "nodeType": "ExpressionStatement", + "src": "16350:21:110" + }, + { + "assignments": [ + 59831 + ], + "declarations": [ + { + "constant": false, + "id": 59831, + "mutability": "mutable", + "name": "success", + "nameLocation": "16996:7:110", + "nodeType": "VariableDeclaration", + "scope": 59869, + "src": "16991:12:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 59830, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "16991:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "id": 59843, + "initialValue": { + "arguments": [ + { + "expression": { + "id": 59834, + "name": "_tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59729, + "src": "17030:3:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + }, + "id": 59835, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "target", + "nodeType": "MemberAccess", + "referencedDeclaration": 70587, + "src": "17030:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": { + "id": 59836, + "name": "_tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59729, + "src": "17042:3:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + }, + "id": 59837, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "gasLimit", + "nodeType": "MemberAccess", + "referencedDeclaration": 70591, + "src": "17042:12:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "expression": { + "id": 59838, + "name": "_tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59729, + "src": "17056:3:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + }, + "id": 59839, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": 70589, + "src": "17056:9:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "expression": { + "id": 59840, + "name": "_tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59729, + "src": "17067:3:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction memory" + } + }, + "id": 59841, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": 70593, + "src": "17067:8:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": { + "id": 59832, + "name": "SafeCall", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 70479, + "src": "17006:8:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SafeCall_$70479_$", + "typeString": "type(library SafeCall)" + } + }, + "id": 59833, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "callWithMinGas", + "nodeType": "MemberAccess", + "referencedDeclaration": 70478, + "src": "17006:23:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bool_$", + "typeString": "function (address,uint256,uint256,bytes memory) returns (bool)" + } + }, + "id": 59842, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17006:70:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "16991:85:110" + }, + { + "expression": { + "id": 59847, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 59844, + "name": "l2Sender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59323, + "src": "17144:8:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "expression": { + "id": 59845, + "name": "Constants", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69571, + "src": "17155:9:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Constants_$69571_$", + "typeString": "type(library Constants)" + } + }, + "id": 59846, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "DEFAULT_L2_SENDER", + "nodeType": "MemberAccess", + "referencedDeclaration": 69529, + "src": "17155:27:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "17144:38:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 59848, + "nodeType": "ExpressionStatement", + "src": "17144:38:110" + }, + { + "eventCall": { + "arguments": [ + { + "id": 59850, + "name": "withdrawalHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59743, + "src": "17361:14:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 59851, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59831, + "src": "17377:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 59849, + "name": "WithdrawalFinalized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59375, + "src": "17341:19:110", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bool_$returns$__$", + "typeString": "function (bytes32,bool)" + } + }, + "id": 59852, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17341:44:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59853, + "nodeType": "EmitStatement", + "src": "17336:49:110" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 59862, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 59856, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 59854, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59831, + "src": "17649:7:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "66616c7365", + "id": 59855, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17660:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "17649:16:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 59861, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59857, + "name": "tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -26, + "src": "17669:2:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_transaction", + "typeString": "tx" + } + }, + "id": 59858, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "origin", + "nodeType": "MemberAccess", + "src": "17669:9:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "id": 59859, + "name": "Constants", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69571, + "src": "17682:9:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Constants_$69571_$", + "typeString": "type(library Constants)" + } + }, + "id": 59860, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "ESTIMATION_ADDRESS", + "nodeType": "MemberAccess", + "referencedDeclaration": 69525, + "src": "17682:28:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "17669:41:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "17649:61:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 59868, + "nodeType": "IfStatement", + "src": "17645:135:110", + "trueBody": { + "id": 59867, + "nodeType": "Block", + "src": "17712:68:110", + "statements": [ + { + "expression": { + "arguments": [ + { + "hexValue": "4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6564", + "id": 59864, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17733:35:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_a0543a16ebb14b11743ebd89913eeb3a89aab6ee2824b60e6e93ee3d5b6c55bb", + "typeString": "literal_string \"OptimismPortal: withdrawal failed\"" + }, + "value": "OptimismPortal: withdrawal failed" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_a0543a16ebb14b11743ebd89913eeb3a89aab6ee2824b60e6e93ee3d5b6c55bb", + "typeString": "literal_string \"OptimismPortal: withdrawal failed\"" + } + ], + "id": 59863, + "name": "revert", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -19, + -19 + ], + "referencedDeclaration": -19, + "src": "17726:6:110", + "typeDescriptions": { + "typeIdentifier": "t_function_revert_pure$_t_string_memory_ptr_$returns$__$", + "typeString": "function (string memory) pure" + } + }, + "id": 59865, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17726:43:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59866, + "nodeType": "ExpressionStatement", + "src": "17726:43:110" + } + ] + } + } + ] + }, + "documentation": { + "id": 59726, + "nodeType": "StructuredDocumentation", + "src": "12840:102:110", + "text": "@notice Finalizes a withdrawal transaction.\n @param _tx Withdrawal transaction to finalize." + }, + "functionSelector": "8c3152e9", + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 59732, + "kind": "modifierInvocation", + "modifierName": { + "id": 59731, + "name": "whenNotPaused", + "nodeType": "IdentifierPath", + "referencedDeclaration": 59397, + "src": "13035:13:110" + }, + "nodeType": "ModifierInvocation", + "src": "13035:13:110" + } + ], + "name": "finalizeWithdrawalTransaction", + "nameLocation": "12956:29:110", + "parameters": { + "id": 59730, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59729, + "mutability": "mutable", + "name": "_tx", + "nameLocation": "13021:3:110", + "nodeType": "VariableDeclaration", + "scope": 59870, + "src": "12986:38:110", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_memory_ptr", + "typeString": "struct Types.WithdrawalTransaction" + }, + "typeName": { + "id": 59728, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 59727, + "name": "Types.WithdrawalTransaction", + "nodeType": "IdentifierPath", + "referencedDeclaration": 70594, + "src": "12986:27:110" + }, + "referencedDeclaration": 70594, + "src": "12986:27:110", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WithdrawalTransaction_$70594_storage_ptr", + "typeString": "struct Types.WithdrawalTransaction" + } + }, + "visibility": "internal" + } + ], + "src": "12985:40:110" + }, + "returnParameters": { + "id": 59733, + "nodeType": "ParameterList", + "parameters": [], + "src": "13049:0:110" + }, + "scope": 59997, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "id": 59961, + "nodeType": "FunctionDefinition", + "src": "18516:1971:110", + "nodes": [], + "body": { + "id": 59960, + "nodeType": "Block", + "src": "18737:1750:110", + "nodes": [], + "statements": [ + { + "condition": { + "id": 59887, + "name": "_isCreation", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59879, + "src": "18876:11:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 59899, + "nodeType": "IfStatement", + "src": "18872:136:110", + "trueBody": { + "id": 59898, + "nodeType": "Block", + "src": "18889:119:110", + "statements": [ + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 59894, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 59889, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59873, + "src": "18911:3:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "arguments": [ + { + "hexValue": "30", + "id": 59892, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18926:1:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 59891, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "18918:7:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 59890, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18918:7:110", + "typeDescriptions": {} + } + }, + "id": 59893, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18918:10:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "18911:17:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646472657373283029207768656e206372656174696e67206120636f6e7472616374", + "id": 59895, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18930:66:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_35a8c36d4f7649c8575025c089af07faab9c54040307e9d6ec8463fe4050a639", + "typeString": "literal_string \"OptimismPortal: must send to address(0) when creating a contract\"" + }, + "value": "OptimismPortal: must send to address(0) when creating a contract" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_35a8c36d4f7649c8575025c089af07faab9c54040307e9d6ec8463fe4050a639", + "typeString": "literal_string \"OptimismPortal: must send to address(0) when creating a contract\"" + } + ], + "id": 59888, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "18903:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59896, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18903:94:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59897, + "nodeType": "ExpressionStatement", + "src": "18903:94:110" + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + }, + "id": 59909, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 59901, + "name": "_gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59877, + "src": "19163:9:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "arguments": [ + { + "arguments": [ + { + "expression": { + "id": 59905, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59881, + "src": "19199:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 59906, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "src": "19199:12:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 59904, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "19192:6:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint64_$", + "typeString": "type(uint64)" + }, + "typeName": { + "id": 59903, + "name": "uint64", + "nodeType": "ElementaryTypeName", + "src": "19192:6:110", + "typeDescriptions": {} + } + }, + "id": 59907, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19192:20:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + ], + "id": 59902, + "name": "minimumGasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59557, + "src": "19176:15:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint64_$returns$_t_uint64_$", + "typeString": "function (uint64) pure returns (uint64)" + } + }, + "id": 59908, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19176:37:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + "src": "19163:50:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d616c6c", + "id": 59910, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19215:37:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_0a0c886a0c5bbb9f3e1be0cff5d8eb64eb65c2a072ac278a98f80049a2d6c3f8", + "typeString": "literal_string \"OptimismPortal: gas limit too small\"" + }, + "value": "OptimismPortal: gas limit too small" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_0a0c886a0c5bbb9f3e1be0cff5d8eb64eb65c2a072ac278a98f80049a2d6c3f8", + "typeString": "literal_string \"OptimismPortal: gas limit too small\"" + } + ], + "id": 59900, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "19155:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59911, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19155:98:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59912, + "nodeType": "ExpressionStatement", + "src": "19155:98:110" + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 59917, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59914, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59881, + "src": "19632:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 59915, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "src": "19632:12:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "hexValue": "3132305f303030", + "id": 59916, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19648:7:110", + "typeDescriptions": { + "typeIdentifier": "t_rational_120000_by_1", + "typeString": "int_const 120000" + }, + "value": "120_000" + }, + "src": "19632:23:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "4f7074696d69736d506f7274616c3a206461746120746f6f206c61726765", + "id": 59918, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19657:32:110", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_ed1d4c6d62337124a330de9c9e42dcf809033e5ae909544279fbaee2e389020b", + "typeString": "literal_string \"OptimismPortal: data too large\"" + }, + "value": "OptimismPortal: data too large" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_ed1d4c6d62337124a330de9c9e42dcf809033e5ae909544279fbaee2e389020b", + "typeString": "literal_string \"OptimismPortal: data too large\"" + } + ], + "id": 59913, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "19624:7:110", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 59919, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19624:66:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59920, + "nodeType": "ExpressionStatement", + "src": "19624:66:110" + }, + { + "assignments": [ + 59922 + ], + "declarations": [ + { + "constant": false, + "id": 59922, + "mutability": "mutable", + "name": "from", + "nameLocation": "19789:4:110", + "nodeType": "VariableDeclaration", + "scope": 59960, + "src": "19781:12:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59921, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "19781:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "id": 59925, + "initialValue": { + "expression": { + "id": 59923, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "19796:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 59924, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "19796:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "19781:25:110" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 59930, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59926, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "19820:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 59927, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "19820:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "expression": { + "id": 59928, + "name": "tx", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -26, + "src": "19834:2:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_transaction", + "typeString": "tx" + } + }, + "id": 59929, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "origin", + "nodeType": "MemberAccess", + "src": "19834:9:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "19820:23:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 59940, + "nodeType": "IfStatement", + "src": "19816:108:110", + "trueBody": { + "id": 59939, + "nodeType": "Block", + "src": "19845:79:110", + "statements": [ + { + "expression": { + "id": 59937, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 59931, + "name": "from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59922, + "src": "19859:4:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "expression": { + "id": 59934, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "19902:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 59935, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "19902:10:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "id": 59932, + "name": "AddressAliasHelper", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 78127, + "src": "19866:18:110", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_AddressAliasHelper_$78127_$", + "typeString": "type(library AddressAliasHelper)" + } + }, + "id": 59933, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "applyL1ToL2Alias", + "nodeType": "MemberAccess", + "referencedDeclaration": 78104, + "src": "19866:35:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_address_$returns$_t_address_$", + "typeString": "function (address) pure returns (address)" + } + }, + "id": 59936, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19866:47:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "19859:54:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 59938, + "nodeType": "ExpressionStatement", + "src": "19859:54:110" + } + ] + } + }, + { + "assignments": [ + 59942 + ], + "declarations": [ + { + "constant": false, + "id": 59942, + "mutability": "mutable", + "name": "opaqueData", + "nameLocation": "20194:10:110", + "nodeType": "VariableDeclaration", + "scope": 59960, + "src": "20181:23:110", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 59941, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "20181:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 59952, + "initialValue": { + "arguments": [ + { + "expression": { + "id": 59945, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "20224:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 59946, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "src": "20224:9:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 59947, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59875, + "src": "20235:6:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 59948, + "name": "_gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59877, + "src": "20243:9:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + { + "id": 59949, + "name": "_isCreation", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59879, + "src": "20254:11:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "id": 59950, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59881, + "src": "20267:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": { + "id": 59943, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "20207:3:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 59944, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "src": "20207:16:110", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 59951, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20207:66:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "20181:92:110" + }, + { + "eventCall": { + "arguments": [ + { + "id": 59954, + "name": "from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59922, + "src": "20441:4:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 59955, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59873, + "src": "20447:3:110", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 59956, + "name": "DEPOSIT_VERSION", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59316, + "src": "20452:15:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 59957, + "name": "opaqueData", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59942, + "src": "20469:10:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 59953, + "name": "TransactionDeposited", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59359, + "src": "20420:20:110", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (address,address,uint256,bytes memory)" + } + }, + "id": 59958, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20420:60:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 59959, + "nodeType": "EmitStatement", + "src": "20415:65:110" + } + ] + }, + "documentation": { + "id": 59871, + "nodeType": "StructuredDocumentation", + "src": "17792:719:110", + "text": "@notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in\n deriving deposit transactions. Note that if a deposit is made by a contract, its\n address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider\n using the CrossDomainMessenger contracts for a simpler developer experience.\n @param _to Target address on L2.\n @param _value ETH value to send to the recipient.\n @param _gasLimit Amount of L2 gas to purchase by burning gas on L1.\n @param _isCreation Whether or not the transaction is a contract creation.\n @param _data Data to trigger the recipient with." + }, + "functionSelector": "e9e05c42", + "implemented": true, + "kind": "function", + "modifiers": [ + { + "arguments": [ + { + "id": 59884, + "name": "_gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59877, + "src": "18722:9:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + } + ], + "id": 59885, + "kind": "modifierInvocation", + "modifierName": { + "id": 59883, + "name": "metered", + "nodeType": "IdentifierPath", + "referencedDeclaration": 60309, + "src": "18714:7:110" + }, + "nodeType": "ModifierInvocation", + "src": "18714:18:110" + } + ], + "name": "depositTransaction", + "nameLocation": "18525:18:110", + "parameters": { + "id": 59882, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59873, + "mutability": "mutable", + "name": "_to", + "nameLocation": "18561:3:110", + "nodeType": "VariableDeclaration", + "scope": 59961, + "src": "18553:11:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 59872, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18553:7:110", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59875, + "mutability": "mutable", + "name": "_value", + "nameLocation": "18582:6:110", + "nodeType": "VariableDeclaration", + "scope": 59961, + "src": "18574:14:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 59874, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "18574:7:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59877, + "mutability": "mutable", + "name": "_gasLimit", + "nameLocation": "18605:9:110", + "nodeType": "VariableDeclaration", + "scope": 59961, + "src": "18598:16:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + }, + "typeName": { + "id": 59876, + "name": "uint64", + "nodeType": "ElementaryTypeName", + "src": "18598:6:110", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59879, + "mutability": "mutable", + "name": "_isCreation", + "nameLocation": "18629:11:110", + "nodeType": "VariableDeclaration", + "scope": 59961, + "src": "18624:16:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 59878, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "18624:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 59881, + "mutability": "mutable", + "name": "_data", + "nameLocation": "18663:5:110", + "nodeType": "VariableDeclaration", + "scope": 59961, + "src": "18650:18:110", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 59880, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "18650:5:110", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "18543:131:110" + }, + "returnParameters": { + "id": 59886, + "nodeType": "ParameterList", + "parameters": [], + "src": "18737:0:110" + }, + "scope": 59997, + "stateMutability": "payable", + "virtual": false, + "visibility": "public" + }, + { + "id": 59978, + "nodeType": "FunctionDefinition", + "src": "20785:180:110", + "nodes": [], + "body": { + "id": 59977, + "nodeType": "Block", + "src": "20865:100:110", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [ + { + "expression": { + "arguments": [ + { + "id": 59972, + "name": "_l2OutputIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59964, + "src": "20932:14:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 59970, + "name": "l2Oracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59341, + "src": "20911:8:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "id": 59971, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getL2Output", + "nodeType": "MemberAccess", + "referencedDeclaration": 59112, + "src": "20911:20:110", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_uint256_$returns$_t_struct$_OutputProposal_$70553_memory_ptr_$", + "typeString": "function (uint256) view external returns (struct Types.OutputProposal memory)" + } + }, + "id": 59973, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20911:36:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_struct$_OutputProposal_$70553_memory_ptr", + "typeString": "struct Types.OutputProposal memory" + } + }, + "id": 59974, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "timestamp", + "nodeType": "MemberAccess", + "referencedDeclaration": 70550, + "src": "20911:46:110", + "typeDescriptions": { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + ], + "id": 59969, + "name": "_isFinalizationPeriodElapsed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59996, + "src": "20882:28:110", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_bool_$", + "typeString": "function (uint256) view returns (bool)" + } + }, + "id": 59975, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20882:76:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 59968, + "id": 59976, + "nodeType": "Return", + "src": "20875:83:110" + } + ] + }, + "documentation": { + "id": 59962, + "nodeType": "StructuredDocumentation", + "src": "20493:287:110", + "text": "@notice Determine if a given output is finalized.\n Reverts if the call to L2_ORACLE.getL2Output reverts.\n Returns a boolean otherwise.\n @param _l2OutputIndex Index of the L2 output to check.\n @return Whether or not the output is finalized." + }, + "functionSelector": "6dbffb78", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "isOutputFinalized", + "nameLocation": "20794:17:110", + "parameters": { + "id": 59965, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59964, + "mutability": "mutable", + "name": "_l2OutputIndex", + "nameLocation": "20820:14:110", + "nodeType": "VariableDeclaration", + "scope": 59978, + "src": "20812:22:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 59963, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "20812:7:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "20811:24:110" + }, + "returnParameters": { + "id": 59968, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59967, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 59978, + "src": "20859:4:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 59966, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "20859:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "20858:6:110" + }, + "scope": 59997, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 59996, + "nodeType": "FunctionDefinition", + "src": "21218:180:110", + "nodes": [], + "body": { + "id": 59995, + "nodeType": "Block", + "src": "21305:93:110", + "nodes": [], + "statements": [ + { + "expression": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 59993, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 59986, + "name": "block", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -4, + "src": "21322:5:110", + "typeDescriptions": { + "typeIdentifier": "t_magic_block", + "typeString": "block" + } + }, + "id": 59987, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "timestamp", + "nodeType": "MemberAccess", + "src": "21322:15:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 59992, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 59988, + "name": "_timestamp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59981, + "src": "21340:10:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "id": 59989, + "name": "l2Oracle", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 59341, + "src": "21353:8:110", + "typeDescriptions": { + "typeIdentifier": "t_contract$_L2OutputOracle_$59272", + "typeString": "contract L2OutputOracle" + } + }, + "id": 59990, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "FINALIZATION_PERIOD_SECONDS", + "nodeType": "MemberAccess", + "referencedDeclaration": 58783, + "src": "21353:36:110", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint256_$", + "typeString": "function () view external returns (uint256)" + } + }, + "id": 59991, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21353:38:110", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "21340:51:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "21322:69:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 59985, + "id": 59994, + "nodeType": "Return", + "src": "21315:76:110" + } + ] + }, + "documentation": { + "id": 59979, + "nodeType": "StructuredDocumentation", + "src": "20971:242:110", + "text": "@notice Determines whether the finalization period has elapsed with respect to\n the provided block timestamp.\n @param _timestamp Timestamp to check.\n @return Whether or not the finalization period has elapsed." + }, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_isFinalizationPeriodElapsed", + "nameLocation": "21227:28:110", + "parameters": { + "id": 59982, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59981, + "mutability": "mutable", + "name": "_timestamp", + "nameLocation": "21264:10:110", + "nodeType": "VariableDeclaration", + "scope": 59996, + "src": "21256:18:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 59980, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "21256:7:110", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "21255:20:110" + }, + "returnParameters": { + "id": 59985, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 59984, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 59996, + "src": "21299:4:110", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 59983, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "21299:4:110", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "21298:6:110" + }, + "scope": 59997, + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + } + ], + "abstract": false, + "baseContracts": [ + { + "baseName": { + "id": 59300, + "name": "Initializable", + "nodeType": "IdentifierPath", + "referencedDeclaration": 32244, + "src": "1162:13:110" + }, + "id": 59301, + "nodeType": "InheritanceSpecifier", + "src": "1162:13:110" + }, + { + "baseName": { + "id": 59302, + "name": "ResourceMetering", + "nodeType": "IdentifierPath", + "referencedDeclaration": 60599, + "src": "1177:16:110" + }, + "id": 59303, + "nodeType": "InheritanceSpecifier", + "src": "1177:16:110" + }, + { + "baseName": { + "id": 59304, + "name": "ISemver", + "nodeType": "IdentifierPath", + "referencedDeclaration": 75669, + "src": "1195:7:110" + }, + "id": 59305, + "nodeType": "InheritanceSpecifier", + "src": "1195:7:110" + } + ], + "canonicalName": "OptimismPortal", + "contractDependencies": [], + "contractKind": "contract", + "documentation": { + "id": 59299, + "nodeType": "StructuredDocumentation", + "src": "797:338:110", + "text": "@custom:proxied\n @title OptimismPortal\n @notice The OptimismPortal is a low-level contract responsible for passing messages between L1\n and L2. Messages sent directly to the OptimismPortal have no form of replayability.\n Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface." + }, + "fullyImplemented": true, + "linearizedBaseContracts": [ + 59997, + 75669, + 60599, + 32244 + ], + "name": "OptimismPortal", + "nameLocation": "1144:14:110", + "scope": 59998, + "usedErrors": [] + } + ], + "license": "MIT" + }, + "id": 110 +} \ No newline at end of file diff --git a/packages/chain-mon/src/balance-mon/service.ts b/packages/chain-mon/src/balance-mon/service.ts index a18e2d73c1d4..3382fc8bc8bb 100644 --- a/packages/chain-mon/src/balance-mon/service.ts +++ b/packages/chain-mon/src/balance-mon/service.ts @@ -6,7 +6,6 @@ import { validators, } from '@eth-optimism/common-ts' import { Provider } from '@ethersproject/abstract-provider' -import { ethers } from 'ethers' import { version } from '../../package.json' @@ -45,7 +44,7 @@ export class BalanceMonService extends BaseServiceV2< }, accounts: { validator: validators.str, - desc: 'JSON array of [{ address, nickname }] to monitor balances of', + desc: 'JSON array of [{ address, nickname, safe }] to monitor balances and nonces of', public: true, }, }, @@ -70,9 +69,21 @@ export class BalanceMonService extends BaseServiceV2< protected async main(): Promise { for (const account of this.state.accounts) { - let balance: ethers.BigNumber try { - balance = await this.options.rpc.getBalance(account.address) + const balance = await this.options.rpc.getBalance(account.address) + this.logger.info(`got balance`, { + address: account.address, + nickname: account.nickname, + balance: balance.toString(), + }) + + // Parse the balance as an integer instead of via toNumber() to avoid ethers throwing an + // an error. We might get rounding errors but we don't need perfect precision here, just a + // generally accurate sense for what the current balance is. + this.metrics.balances.set( + { address: account.address, nickname: account.nickname }, + parseInt(balance.toString(), 10) + ) } catch (err) { this.logger.info(`got unexpected RPC error`, { section: 'balances', @@ -83,22 +94,7 @@ export class BalanceMonService extends BaseServiceV2< section: 'balances', name: 'getBalance', }) - continue } - - this.logger.info(`got balance`, { - address: account.address, - nickname: account.nickname, - balance: balance.toString(), - }) - - // Parse the balance as an integer instead of via toNumber() to avoid ethers throwing an - // an error. We might get rounding errors but we don't need perfect precision here, just a - // generally accurate sense for what the current balance is. - this.metrics.balances.set( - { address: account.address, nickname: account.nickname }, - parseInt(balance.toString(), 10) - ) } } } diff --git a/packages/chain-mon/src/fault-mon/README.md b/packages/chain-mon/src/fault-mon/README.md index 585b8eb28c02..eec7dcee7f70 100644 --- a/packages/chain-mon/src/fault-mon/README.md +++ b/packages/chain-mon/src/fault-mon/README.md @@ -16,7 +16,7 @@ pnpm build ## Running the service -Copy `.env.example` into a new file named `.env`, then set the environment variables listed there. Additional env setting are listed on `--help`. If running the fault detector against +Copy `.env.example` into a new file named `.env`, then set the environment variables listed there. Additional env settings are listed on `--help`. If running the fault detector against a custom op chain, the `OptimismPortal` contract addresses must also be set associated with the op-chain. Once your environment variables or flags have been set, run the service via: diff --git a/packages/chain-mon/src/fault-mon/service.ts b/packages/chain-mon/src/fault-mon/service.ts index f73c61b9fa32..63ef1cc95229 100644 --- a/packages/chain-mon/src/fault-mon/service.ts +++ b/packages/chain-mon/src/fault-mon/service.ts @@ -147,11 +147,10 @@ export class FaultDetector extends BaseServiceV2 { contracts.OptimismPortal = portalAddress this.logger.info('fetching L2OutputOracle contract from OptimismPortal') - const opts = { - portalAddress, + const portalContract = getOEContract('OptimismPortal', l2ChainId, { + address: portalAddress, signerOrProvider: this.options.l1RpcProvider, - } - const portalContract = getOEContract('OptimismPortal', l2ChainId, opts) + }) contracts.L2OutputOracle = await portalContract.L2_ORACLE() } diff --git a/packages/chain-mon/src/index.ts b/packages/chain-mon/src/index.ts index 98817368bbeb..9091eca096d6 100644 --- a/packages/chain-mon/src/index.ts +++ b/packages/chain-mon/src/index.ts @@ -1,5 +1,7 @@ export * from './balance-mon/service' export * from './drippie-mon/service' +export * from './fault-mon/index' +export * from './multisig-mon/service' export * from './wd-mon/service' export * from './wallet-mon/service' -export * from './fault-mon/index' +export * from './initialized-upgraded-mon/service' diff --git a/packages/chain-mon/src/initialized-upgraded-mon/service.ts b/packages/chain-mon/src/initialized-upgraded-mon/service.ts new file mode 100644 index 000000000000..5fe302063dd7 --- /dev/null +++ b/packages/chain-mon/src/initialized-upgraded-mon/service.ts @@ -0,0 +1,238 @@ +import { + BaseServiceV2, + StandardOptions, + Gauge, + Counter, + validators, + waitForProvider, +} from '@eth-optimism/common-ts' +import { getChainId, compareAddrs } from '@eth-optimism/core-utils' +import { Provider, TransactionResponse } from '@ethersproject/abstract-provider' +import mainnetConfig from '@eth-optimism/contracts-bedrock/deploy-config/mainnet.json' +import sepoliaConfig from '@eth-optimism/contracts-bedrock/deploy-config/sepolia.json' +import goerliConfig from '@eth-optimism/contracts-bedrock/deploy-config/goerli.json' + +import { version } from '../../package.json' + +const networks = { + 1: { + name: 'mainnet', + l1StartingBlockTag: mainnetConfig.l1StartingBlockTag, + }, + 10: { + name: 'op-mainnet', + l1StartingBlockTag: null, + }, + 11155111: { + name: 'sepolia', + l1StartingBlockTag: sepoliaConfig.l1StartingBlockTag, + }, + 11155420: { + name: 'op-sepolia', + l1StartingBlockTag: null, + }, + 5: { + name: 'goerli', + l1StartingBlockTag: goerliConfig.l1StartingBlockTag, + }, + 420: { + name: 'op-goerli', + l1StartingBlockTag: null, + }, +} + +// keccak256("Initialized(uint8)") = 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498 +const topic_initialized = + '0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498' + +// keccak256("Upgraded(address)") = 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b +const topic_upgraded = + '0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b' + +type InitializedUpgradedMonOptions = { + rpc: Provider + startBlockNumber: number + contracts: string +} + +type InitializedUpgradedMonMetrics = { + initializedCalls: Counter + upgradedCalls: Counter + unexpectedRpcErrors: Counter +} + +type InitializedUpgradedMonState = { + chainId: number + highestUncheckedBlockNumber: number + contracts: Array<{ label: string; address: string }> +} + +export class InitializedUpgradedMonService extends BaseServiceV2< + InitializedUpgradedMonOptions, + InitializedUpgradedMonMetrics, + InitializedUpgradedMonState +> { + constructor( + options?: Partial + ) { + super({ + version, + name: 'initialized-upgraded-mon', + loop: true, + options: { + loopIntervalMs: 1000, + ...options, + }, + optionsSpec: { + rpc: { + validator: validators.provider, + desc: 'Provider for network to monitor balances on', + }, + startBlockNumber: { + validator: validators.num, + default: -1, + desc: 'L1 block number to start checking from', + public: true, + }, + contracts: { + validator: validators.str, + desc: 'JSON array of [{ label, address }] to monitor contracts for', + public: true, + }, + }, + metricsSpec: { + initializedCalls: { + type: Gauge, + desc: 'Successful transactions to tracked contracts emitting initialized event', + labels: ['label', 'address'], + }, + upgradedCalls: { + type: Gauge, + desc: 'Successful transactions to tracked contracts emitting upgraded event', + labels: ['label', 'address'], + }, + unexpectedRpcErrors: { + type: Counter, + desc: 'Number of unexpected RPC errors', + labels: ['section', 'name'], + }, + }, + }) + } + + protected async init(): Promise { + // Connect to L1. + await waitForProvider(this.options.rpc, { + logger: this.logger, + name: 'L1', + }) + + this.state.chainId = await getChainId(this.options.rpc) + + const l1StartingBlockTag = networks[this.state.chainId].l1StartingBlockTag + + if (this.options.startBlockNumber === -1) { + const block_number = + l1StartingBlockTag != null + ? (await this.options.rpc.getBlock(l1StartingBlockTag)).number + : 0 + this.state.highestUncheckedBlockNumber = block_number + } else { + this.state.highestUncheckedBlockNumber = this.options.startBlockNumber + } + + try { + this.state.contracts = JSON.parse(this.options.contracts) + } catch (e) { + throw new Error( + 'unable to start service because provided options is not valid json' + ) + } + } + + protected async main(): Promise { + if ( + (await this.options.rpc.getBlockNumber()) < + this.state.highestUncheckedBlockNumber + ) { + this.logger.info('Waiting for new blocks') + return + } + + const block = await this.options.rpc.getBlock( + this.state.highestUncheckedBlockNumber + ) + this.logger.info('Checking block', { + number: block.number, + }) + + const transactions: TransactionResponse[] = [] + for (const txHash of block.transactions) { + const t = await this.options.rpc.getTransaction(txHash) + transactions.push(t) + } + + for (const transaction of transactions) { + for (const contract of this.state.contracts) { + const to = + transaction.to != null ? transaction.to : transaction['creates'] + if (compareAddrs(contract.address, to)) { + try { + const transactionReceipt = await transaction.wait() + for (const log of transactionReceipt.logs) { + if (log.topics.includes(topic_initialized)) { + this.metrics.initializedCalls.inc({ + label: contract.label, + address: contract.address, + }) + this.logger.info('initialized event', { + label: contract.label, + address: contract.address, + }) + } else if (log.topics.includes(topic_upgraded)) { + this.metrics.upgradedCalls.inc({ + label: contract.label, + address: contract.address, + }) + this.logger.info('upgraded event', { + label: contract.label, + address: contract.address, + }) + } + } + } catch (err) { + // If error is due to transaction failing, ignore transaction + if ( + err.message.length >= 18 && + err.message.slice(0, 18) === 'transaction failed' + ) { + break + } + // Otherwise, we have an unexpected RPC error + this.logger.info(`got unexpected RPC error`, { + section: 'creations', + name: 'NULL', + err, + }) + + this.metrics.unexpectedRpcErrors.inc({ + section: 'creations', + name: 'NULL', + }) + + return + } + } + } + } + this.logger.info('Checked block', { + number: this.state.highestUncheckedBlockNumber, + }) + this.state.highestUncheckedBlockNumber++ + } +} + +if (require.main === module) { + const service = new InitializedUpgradedMonService() + service.run() +} diff --git a/packages/chain-mon/src/multisig-mon/service.ts b/packages/chain-mon/src/multisig-mon/service.ts new file mode 100644 index 000000000000..bb50d18b3d9b --- /dev/null +++ b/packages/chain-mon/src/multisig-mon/service.ts @@ -0,0 +1,250 @@ +import { exec } from 'child_process' + +import { + BaseServiceV2, + StandardOptions, + Gauge, + Counter, + validators, +} from '@eth-optimism/common-ts' +import { Provider } from '@ethersproject/abstract-provider' +import { ethers } from 'ethers' + +import Safe from '../abi/IGnosisSafe.0.8.19.json' +import OptimismPortal from '../abi/OptimismPortal.json' +import { version } from '../../package.json' + +type MultisigMonOptions = { + rpc: Provider + accounts: string + onePassServiceToken: string +} + +type MultisigMonMetrics = { + safeNonce: Gauge + latestPreSignedPauseNonce: Gauge + pausedState: Gauge + unexpectedRpcErrors: Counter +} + +type MultisigMonState = { + accounts: Array<{ + nickname: string + safeAddress: string + optimismPortalAddress: string + vault: string + }> +} + +export class MultisigMonService extends BaseServiceV2< + MultisigMonOptions, + MultisigMonMetrics, + MultisigMonState +> { + constructor(options?: Partial) { + super({ + version, + name: 'multisig-mon', + loop: true, + options: { + loopIntervalMs: 60_000, + ...options, + }, + optionsSpec: { + rpc: { + validator: validators.provider, + desc: 'Provider for network to monitor balances on', + }, + accounts: { + validator: validators.str, + desc: 'JSON array of [{ nickname, safeAddress, optimismPortalAddress, vault }] to monitor', + public: true, + }, + onePassServiceToken: { + validator: validators.str, + desc: '1Password Service Token', + }, + }, + metricsSpec: { + safeNonce: { + type: Gauge, + desc: 'Safe nonce', + labels: ['address', 'nickname'], + }, + latestPreSignedPauseNonce: { + type: Gauge, + desc: 'Latest pre-signed pause nonce', + labels: ['address', 'nickname'], + }, + pausedState: { + type: Gauge, + desc: 'OptimismPortal paused state', + labels: ['address', 'nickname'], + }, + unexpectedRpcErrors: { + type: Counter, + desc: 'Number of unexpected RPC errors', + labels: ['section', 'name'], + }, + }, + }) + } + + protected async init(): Promise { + this.state.accounts = JSON.parse(this.options.accounts) + } + + protected async main(): Promise { + for (const account of this.state.accounts) { + // get the nonce 1pass + if (this.options.onePassServiceToken) { + await this.getOnePassNonce(account) + } + + // get the nonce from deployed safe + if (account.safeAddress) { + await this.getSafeNonce(account) + } + + // get the paused state of the OptimismPortal + if (account.optimismPortalAddress) { + await this.getPausedState(account) + } + } + } + + private async getPausedState(account: { + nickname: string + safeAddress: string + optimismPortalAddress: string + vault: string + }) { + try { + const optimismPortal = new ethers.Contract( + account.optimismPortalAddress, + OptimismPortal.abi, + this.options.rpc + ) + const paused = await optimismPortal.paused() + this.logger.info(`got paused state`, { + optimismPortalAddress: account.optimismPortalAddress, + nickname: account.nickname, + paused, + }) + + this.metrics.pausedState.set( + { address: account.optimismPortalAddress, nickname: account.nickname }, + paused ? 1 : 0 + ) + } catch (err) { + this.logger.error(`got unexpected RPC error`, { + section: 'pausedState', + name: 'getPausedState', + err, + }) + this.metrics.unexpectedRpcErrors.inc({ + section: 'pausedState', + name: 'getPausedState', + }) + } + } + + private async getOnePassNonce(account: { + nickname: string + safeAddress: string + optimismPortalAddress: string + vault: string + }) { + try { + exec( + `OP_SERVICE_ACCOUNT_TOKEN=${this.options.onePassServiceToken} op item list --format json --vault="${account.vault}"`, + (error, stdout, stderr) => { + if (error) { + this.logger.error(`got unexpected error from onepass: ${error}`, { + section: 'onePassNonce', + name: 'getOnePassNonce', + }) + return + } + if (stderr) { + this.logger.error(`got unexpected error from onepass`, { + section: 'onePassNonce', + name: 'getOnePassNonce', + stderr, + }) + return + } + const items = JSON.parse(stdout) + let latestNonce = -1 + this.logger.debug(`items in vault '${account.vault}':`) + for (const item of items) { + const title = item['title'] + this.logger.debug(`- ${title}`) + if (title.startsWith('ready-') && title.endsWith('.json')) { + const nonce = parseInt(title.substring(6, title.length - 5), 10) + if (nonce > latestNonce) { + latestNonce = nonce + } + } + } + this.metrics.latestPreSignedPauseNonce.set( + { address: account.safeAddress, nickname: account.nickname }, + latestNonce + ) + this.logger.debug(`latestNonce: ${latestNonce}`) + } + ) + } catch (err) { + this.logger.error(`got unexpected error from onepass`, { + section: 'onePassNonce', + name: 'getOnePassNonce', + err, + }) + this.metrics.unexpectedRpcErrors.inc({ + section: 'onePassNonce', + name: 'getOnePassNonce', + }) + } + } + + private async getSafeNonce(account: { + nickname: string + safeAddress: string + optimismPortalAddress: string + vault: string + }) { + try { + const safeContract = new ethers.Contract( + account.safeAddress, + Safe.abi, + this.options.rpc + ) + const safeNonce = await safeContract.nonce() + this.logger.info(`got nonce`, { + address: account.safeAddress, + nickname: account.nickname, + nonce: safeNonce.toString(), + }) + + this.metrics.safeNonce.set( + { address: account.safeAddress, nickname: account.nickname }, + parseInt(safeNonce.toString(), 10) + ) + } catch (err) { + this.logger.error(`got unexpected RPC error`, { + section: 'safeNonce', + name: 'getSafeNonce', + err, + }) + this.metrics.unexpectedRpcErrors.inc({ + section: 'safeNonce', + name: 'getSafeNonce', + }) + } + } +} + +if (require.main === module) { + const service = new MultisigMonService() + service.run() +} diff --git a/packages/chain-mon/src/wallet-mon/service.ts b/packages/chain-mon/src/wallet-mon/service.ts index 745b32f00302..819f18333dc1 100644 --- a/packages/chain-mon/src/wallet-mon/service.ts +++ b/packages/chain-mon/src/wallet-mon/service.ts @@ -10,8 +10,6 @@ import { getChainId, compareAddrs } from '@eth-optimism/core-utils' import { Provider, TransactionResponse } from '@ethersproject/abstract-provider' import mainnetConfig from '@eth-optimism/contracts-bedrock/deploy-config/mainnet.json' import goerliConfig from '@eth-optimism/contracts-bedrock/deploy-config/goerli.json' -import l2OutputOracleArtifactsMainnet from '@eth-optimism/contracts-bedrock/deployments/mainnet/L2OutputOracleProxy.json' -import l2OutputOracleArtifactsGoerli from '@eth-optimism/contracts-bedrock/deployments/goerli/L2OutputOracleProxy.json' import { version } from '../../package.json' @@ -23,7 +21,7 @@ const networks = { { label: 'Proposer', wallet: mainnetConfig.l2OutputOracleProposer, - target: l2OutputOracleArtifactsMainnet.address, + target: '0xdfe97868233d1aa22e815a266982f2cf17685a27', }, { label: 'Batcher', @@ -39,7 +37,7 @@ const networks = { { label: 'Proposer', wallet: goerliConfig.l2OutputOracleProposer, - target: l2OutputOracleArtifactsGoerli.address, + target: '0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0', }, { label: 'Batcher', diff --git a/packages/chain-mon/src/wd-mon/constants.ts b/packages/chain-mon/src/wd-mon/constants.ts new file mode 100644 index 000000000000..0021c0de2606 --- /dev/null +++ b/packages/chain-mon/src/wd-mon/constants.ts @@ -0,0 +1,21 @@ +import { L2ChainID } from '@eth-optimism/sdk' + +// TODO: Consider moving to `@eth-optimism/constants` and generating from superchain registry. +// @see https://github.com/ethereum-optimism/optimism/pull/9041 + +/** + * Mapping of L2ChainIDs to the L1 block numbers where the wd-mon service should start looking for + * withdrawals by default. L1 block numbers here are based on the block number in which the + * OptimismPortal proxy contract was deployed to L1. + */ +export const DEFAULT_STARTING_BLOCK_NUMBERS: { + [ChainID in L2ChainID]?: number +} = { + [L2ChainID.OPTIMISM]: 17365802 as const, + [L2ChainID.OPTIMISM_GOERLI]: 8299684 as const, + [L2ChainID.OPTIMISM_SEPOLIA]: 4071248 as const, + [L2ChainID.BASE_MAINNET]: 17482143 as const, + [L2ChainID.BASE_GOERLI]: 8411116 as const, + [L2ChainID.BASE_SEPOLIA]: 4370901 as const, + [L2ChainID.ZORA_MAINNET]: 17473938 as const, +} diff --git a/packages/chain-mon/src/wd-mon/helpers.ts b/packages/chain-mon/src/wd-mon/helpers.ts deleted file mode 100644 index ed00acde5aff..000000000000 --- a/packages/chain-mon/src/wd-mon/helpers.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Provider } from '@ethersproject/abstract-provider' -import { Logger } from '@eth-optimism/common-ts' - -/** - * Finds - * - * @param - * @param - * @param - * @returns - */ -export const getLastFinalizedBlock = async ( - l1RpcProvider: Provider, - faultProofWindow: number, - logger: Logger -): Promise => { - let guessWindowStartBlock - try { - const l1Block = await l1RpcProvider.getBlock('latest') - - // The time corresponding to the start of the FPW, based on the current block. - const windowStartTime = l1Block.timestamp - faultProofWindow - - // Use the FPW to find the block number that is the start of the FPW. - guessWindowStartBlock = l1Block.number - faultProofWindow / 12 - - let block = await l1RpcProvider.getBlock(guessWindowStartBlock) - while (block.timestamp > windowStartTime) { - guessWindowStartBlock-- - block = await l1RpcProvider.getBlock(guessWindowStartBlock) - } - return block.number - } catch (err) { - logger.fatal('error when calling querying for block', { - errors: err, - }) - throw new Error( - `unable to find block number ${guessWindowStartBlock || 'latest'}` - ) - } -} diff --git a/packages/chain-mon/src/wd-mon/service.ts b/packages/chain-mon/src/wd-mon/service.ts index 62f4066fe8e9..86e56e12562a 100644 --- a/packages/chain-mon/src/wd-mon/service.ts +++ b/packages/chain-mon/src/wd-mon/service.ts @@ -6,30 +6,35 @@ import { validators, waitForProvider, } from '@eth-optimism/common-ts' -import { CrossChainMessenger } from '@eth-optimism/sdk' +import { getOEContract, DEFAULT_L2_CONTRACT_ADDRESSES } from '@eth-optimism/sdk' import { getChainId, sleep } from '@eth-optimism/core-utils' import { Provider } from '@ethersproject/abstract-provider' -import { Event } from 'ethers' +import { ethers } from 'ethers' import dateformat from 'dateformat' import { version } from '../../package.json' -import { getLastFinalizedBlock as getLastFinalizedBlock } from './helpers' +import { DEFAULT_STARTING_BLOCK_NUMBERS } from './constants' type Options = { l1RpcProvider: Provider l2RpcProvider: Provider + optimismPortalAddress: string + l2ToL1MessagePasserAddress: string startBlockNumber: number + eventBlockRange: number sleepTimeMs: number } type Metrics = { + highestBlockNumber: Gauge withdrawalsValidated: Gauge isDetectingForgeries: Gauge nodeConnectionFailures: Gauge } type State = { - messenger: CrossChainMessenger + portal: ethers.Contract + messenger: ethers.Contract highestUncheckedBlockNumber: number faultProofWindow: number forgeryDetected: boolean @@ -54,12 +59,30 @@ export class WithdrawalMonitor extends BaseServiceV2 { validator: validators.provider, desc: 'Provider for interacting with L2', }, + optimismPortalAddress: { + validator: validators.address, + default: null, + desc: 'Address of the OptimismPortal proxy contract on L1', + public: true, + }, + l2ToL1MessagePasserAddress: { + validator: validators.address, + default: DEFAULT_L2_CONTRACT_ADDRESSES.BedrockMessagePasser as string, + desc: 'Address of the L2ToL1MessagePasser contract on L2', + public: true, + }, startBlockNumber: { validator: validators.num, default: -1, desc: 'L1 block number to start checking from', public: true, }, + eventBlockRange: { + validator: validators.num, + default: 2000, + desc: 'Number of blocks to query for events over per loop', + public: true, + }, sleepTimeMs: { validator: validators.num, default: 15000, @@ -68,6 +91,11 @@ export class WithdrawalMonitor extends BaseServiceV2 { }, }, metricsSpec: { + highestBlockNumber: { + type: Gauge, + desc: 'Highest block number (checked and known)', + labels: ['type'], + }, withdrawalsValidated: { type: Gauge, desc: 'Latest L1 Block (checked and known)', @@ -99,38 +127,41 @@ export class WithdrawalMonitor extends BaseServiceV2 { name: 'L2', }) - this.state.messenger = new CrossChainMessenger({ - l1SignerOrProvider: this.options.l1RpcProvider, - l2SignerOrProvider: this.options.l2RpcProvider, - l1ChainId: await getChainId(this.options.l1RpcProvider), - l2ChainId: await getChainId(this.options.l2RpcProvider), - bedrock: true, - }) + // Need L2 chain ID to resolve contract addresses. + const l2ChainId = await getChainId(this.options.l2RpcProvider) - // Not detected by default. - this.state.forgeryDetected = false + // Create the OptimismPortal contract instance. If the optimismPortal option is not provided + // then the SDK will attempt to resolve the address automatically based on the L2 chain ID. If + // the SDK isn't aware of the L2 chain ID then it will throw an error that makes it clear the + // user needs to provide this value explicitly. + this.state.portal = getOEContract('OptimismPortal', l2ChainId, { + signerOrProvider: this.options.l1RpcProvider, + address: this.options.optimismPortalAddress, + }) - this.state.faultProofWindow = - await this.state.messenger.getChallengePeriodSeconds() - this.logger.info( - `fault proof window is ${this.state.faultProofWindow} seconds` - ) + // Create the L2ToL1MessagePasser contract instance. If the l2ToL1MessagePasser option is not + // provided then we'll use the default address which typically should be correct. It's very + // unlikely that any user would change this address so this should work in 99% of cases. If we + // really wanted to be extra safe we could do some sanity checks to make sure the contract has + // the interface we need but doesn't seem important for now. + this.state.messenger = getOEContract('L2ToL1MessagePasser', l2ChainId, { + signerOrProvider: this.options.l2RpcProvider, + address: this.options.l2ToL1MessagePasserAddress, + }) - // Set the start block number. + // Previous versions of wd-mon would try to pick the starting block number automatically but + // this had the possibility of missing certain withdrawals if the service was restarted at the + // wrong time. Given the added complexity of finding a starting point automatically after FPAC, + // it's much easier to simply start a fixed block number than trying to do something fancy. Use + // the default configured in this service or use zero if no default is defined. + this.state.highestUncheckedBlockNumber = this.options.startBlockNumber if (this.options.startBlockNumber === -1) { - // We default to starting from the last finalized block. - this.state.highestUncheckedBlockNumber = await getLastFinalizedBlock( - this.options.l1RpcProvider, - this.state.faultProofWindow, - this.logger - ) - } else { - this.state.highestUncheckedBlockNumber = this.options.startBlockNumber + this.state.highestUncheckedBlockNumber = + DEFAULT_STARTING_BLOCK_NUMBERS[l2ChainId] || 0 } - this.logger.info(`starting L1 block height`, { - startBlockNumber: this.state.highestUncheckedBlockNumber, - }) + // Default state is that forgeries have not been detected. + this.state.forgeryDetected = false } // K8s healthcheck @@ -143,94 +174,131 @@ export class WithdrawalMonitor extends BaseServiceV2 { } async main(): Promise { - // Get current block number + // Get the latest L1 block number. let latestL1BlockNumber: number try { latestL1BlockNumber = await this.options.l1RpcProvider.getBlockNumber() } catch (err) { + // Log the issue so we can debug it. this.logger.error(`got error when connecting to node`, { error: err, node: 'l1', section: 'getBlockNumber', }) + + // Increment the metric so we can detect the issue. this.metrics.nodeConnectionFailures.inc({ layer: 'l1', section: 'getBlockNumber', }) - await sleep(this.options.sleepTimeMs) - return + + // Sleep for a little to give intermittent errors a chance to recover. + return sleep(this.options.sleepTimeMs) } - // See if we have a new unchecked block + // Update highest block number metrics so we can keep track of how the service is doing. + this.metrics.highestBlockNumber.set({ type: 'known' }, latestL1BlockNumber) + this.metrics.highestBlockNumber.set( + { type: 'checked' }, + this.state.highestUncheckedBlockNumber + ) + + // Check if the RPC provider is behind us for some reason. Can happen occasionally, + // particularly if connected to an RPC provider that load balances over multiple nodes that + // might not be perfectly in sync. if (latestL1BlockNumber <= this.state.highestUncheckedBlockNumber) { - // The RPC provider is behind us, wait a bit - await sleep(this.options.sleepTimeMs) - return + // Sleep for a little to give the RPC a chance to catch up. + return sleep(this.options.sleepTimeMs) } + // Generally better to use a relatively small block range because it means this service can be + // used alongside many different types of L1 nodes. For instance, Geth will typically only + // support a block range of 2000 blocks out of the box. + const toBlockNumber = Math.min( + this.state.highestUncheckedBlockNumber + this.options.eventBlockRange, + latestL1BlockNumber + ) + + // Useful to log this stuff just in case we get stuck or something. this.logger.info(`checking recent blocks`, { fromBlockNumber: this.state.highestUncheckedBlockNumber, - toBlockNumber: latestL1BlockNumber, + toBlockNumber, }) - // Perform the check - let proofEvents: Event[] + // Query for WithdrawalProven events within the specified block range. + let events: ethers.Event[] try { - // The query includes events in the blockNumbers given as the last two arguments - proofEvents = - await this.state.messenger.contracts.l1.OptimismPortal.queryFilter( - this.state.messenger.contracts.l1.OptimismPortal.filters.WithdrawalProven(), - this.state.highestUncheckedBlockNumber, - latestL1BlockNumber - ) + events = await this.state.portal.queryFilter( + this.state.portal.filters.WithdrawalProven(), + this.state.highestUncheckedBlockNumber, + toBlockNumber + ) } catch (err) { + // Log the issue so we can debug it. this.logger.error(`got error when connecting to node`, { error: err, node: 'l1', section: 'querying for WithdrawalProven events', }) + + // Increment the metric so we can detect the issue. this.metrics.nodeConnectionFailures.inc({ layer: 'l1', section: 'querying for WithdrawalProven events', }) - // connection error, wait then restart - await sleep(this.options.sleepTimeMs) - return + + // Sleep for a little to give intermittent errors a chance to recover. + return sleep(this.options.sleepTimeMs) } - for (const proofEvent of proofEvents) { - const exists = - await this.state.messenger.contracts.l2.BedrockMessagePasser.sentMessages( - proofEvent.args.withdrawalHash - ) - const block = await proofEvent.getBlock() - const now = new Date(block.timestamp * 1000) - const dateString = dateformat( - now, - 'mmmm dS, yyyy, h:MM:ss TT', - true // use UTC time - ) - const provenAt = `${dateString} UTC` + // Go over all the events and check if the withdrawal hash actually exists on L2. + for (const event of events) { + // Could consider using multicall here but this is efficient enough for now. + const hash = event.args.withdrawalHash + const exists = await this.state.messenger.sentMessages(hash) + + // Hopefully the withdrawal exists! if (exists) { - this.metrics.withdrawalsValidated.inc() + // Unlike below we don't grab the timestamp here because it adds an unnecessary request. this.logger.info(`valid withdrawal`, { - withdrawalHash: proofEvent.args.withdrawalHash, - provenAt, + withdrawalHash: event.args.withdrawalHash, }) + + // Bump the withdrawals metric so we can keep track. + this.metrics.withdrawalsValidated.inc() } else { + // Grab and format the timestamp so it's clear how much time is left. + const block = await event.getBlock() + const ts = `${dateformat( + new Date(block.timestamp * 1000), + 'mmmm dS, yyyy, h:MM:ss TT', + true + )} UTC` + + // Uh oh! this.logger.error(`withdrawalHash not seen on L2`, { - withdrawalHash: proofEvent.args.withdrawalHash, - provenAt, + withdrawalHash: event.args.withdrawalHash, + provenAt: ts, }) + + // Change to forgery state. this.state.forgeryDetected = true this.metrics.isDetectingForgeries.set(1) - return + + // Return early so that we never increment the highest unchecked block number and therefore + // will continue to loop on this forgery indefinitely. We probably want to change this + // behavior at some point so that we keep scanning for additional forgeries since the + // existence of one forgery likely implies the existence of many others. + return sleep(this.options.sleepTimeMs) } } - this.state.highestUncheckedBlockNumber = latestL1BlockNumber + 1 + // Increment the highest unchecked block number for the next loop. + this.state.highestUncheckedBlockNumber = toBlockNumber - // If we got through the above without throwing an error, we should be fine to reset. + // If we got through the above without throwing an error, we should be fine to reset. Only case + // where this is relevant is if something is detected as a forgery accidentally and the error + // doesn't happen again on the next loop. this.state.forgeryDetected = false this.metrics.isDetectingForgeries.set(0) } diff --git a/packages/chain-mon/test/fault-mon/helpers.spec.ts b/packages/chain-mon/test/fault-mon/helpers.spec.ts index 3a6b3d124c19..f62e484cece8 100644 --- a/packages/chain-mon/test/fault-mon/helpers.spec.ts +++ b/packages/chain-mon/test/fault-mon/helpers.spec.ts @@ -46,19 +46,18 @@ describe('helpers', () => { signer ) - const L2OutputOracleImplementation = await Factory__L2OutputOracle.deploy( - deployConfig.l2OutputOracleSubmissionInterval, - deployConfig.l2BlockTime, - deployConfig.finalizationPeriodSeconds - ) + const L2OutputOracleImplementation = await Factory__L2OutputOracle.deploy() await Proxy.upgradeToAndCall( L2OutputOracleImplementation.address, L2OutputOracleImplementation.interface.encodeFunctionData('initialize', [ + deployConfig.l2OutputOracleSubmissionInterval, + deployConfig.l2BlockTime, deployConfig.l2OutputOracleStartingBlockNumber, deployConfig.l2OutputOracleStartingTimestamp, deployConfig.l2OutputOracleProposer, deployConfig.l2OutputOracleChallenger, + deployConfig.finalizationPeriodSeconds, ]) ) diff --git a/packages/chain-mon/tsconfig.json b/packages/chain-mon/tsconfig.json index 51d474888dca..24967ddae693 100644 --- a/packages/chain-mon/tsconfig.json +++ b/packages/chain-mon/tsconfig.json @@ -6,6 +6,8 @@ }, "include": [ "package.json", + "src/abi/IGnosisSafe.0.8.19.json", + "src/abi/OptimismPortal.json", "src/**/*" ] } diff --git a/packages/common-ts/CHANGELOG.md b/packages/common-ts/CHANGELOG.md index 4b034ba17078..3d2733c11f53 100644 --- a/packages/common-ts/CHANGELOG.md +++ b/packages/common-ts/CHANGELOG.md @@ -1,5 +1,11 @@ # @eth-optimism/common-ts +## 0.8.8 + +### Patch Changes + +- [#9334](https://github.com/ethereum-optimism/optimism/pull/9334) [`1ed50c44a5c4fb7244ede3b4c45ea7bbf144c1e5`](https://github.com/ethereum-optimism/optimism/commit/1ed50c44a5c4fb7244ede3b4c45ea7bbf144c1e5) Thanks [@smartcontracts](https://github.com/smartcontracts)! - Adds a new validator for address types. + ## 0.8.7 ### Patch Changes diff --git a/packages/common-ts/package.json b/packages/common-ts/package.json index 72060a89145c..4ad287f66bd2 100644 --- a/packages/common-ts/package.json +++ b/packages/common-ts/package.json @@ -1,6 +1,6 @@ { "name": "@eth-optimism/common-ts", - "version": "0.8.7", + "version": "0.8.8", "description": "[Optimism] Advanced typescript tooling used by various services", "main": "dist/index", "types": "dist/index", @@ -12,7 +12,6 @@ "all": "pnpm clean && pnpm build && pnpm test && pnpm lint:fix && pnpm lint", "build": "tsc -p tsconfig.json", "clean": "rimraf dist/ ./tsconfig.tsbuildinfo", - "preinstall": "npx only-allow pnpm", "lint:check": "eslint . --max-warnings=0", "lint:fix": "pnpm lint:check --fix", "lint": "pnpm lint:fix && pnpm lint:check", @@ -35,18 +34,18 @@ }, "dependencies": { "@eth-optimism/core-utils": "workspace:*", - "@sentry/node": "^7.75.0", + "@sentry/node": "^7.99.0", "bcfg": "^0.2.1", "body-parser": "^1.20.2", "commander": "^11.1.0", - "dotenv": "^16.3.1", + "dotenv": "^16.4.5", "envalid": "^8.0.0", "ethers": "^5.7.2", "express": "^4.18.2", - "express-prom-bundle": "^6.6.0", + "express-prom-bundle": "^7.0.0", "lodash": "^4.17.21", "morgan": "^1.10.0", - "pino": "^8.16.1", + "pino": "^8.19.0", "pino-multi-stream": "^6.0.0", "pino-sentry": "^0.14.0", "prom-client": "^14.2.0" @@ -54,11 +53,11 @@ "devDependencies": { "@ethersproject/abstract-provider": "^5.7.0", "@ethersproject/abstract-signer": "^5.7.0", - "@types/express": "^4.17.19", - "@types/morgan": "^1.9.7", + "@types/express": "^4.17.21", + "@types/morgan": "^1.9.9", "@types/pino": "^7.0.5", - "@types/pino-multi-stream": "^5.1.5", + "@types/pino-multi-stream": "^5.1.6", "chai": "^4.3.10", - "supertest": "^6.3.3" + "supertest": "^6.3.4" } } diff --git a/packages/common-ts/src/base-service/base-service-v2.ts b/packages/common-ts/src/base-service/base-service-v2.ts index 79672e9b41e6..f4daa25fb18a 100644 --- a/packages/common-ts/src/base-service/base-service-v2.ts +++ b/packages/common-ts/src/base-service/base-service-v2.ts @@ -451,7 +451,7 @@ export abstract class BaseServiceV2< this.logger.info('waiting for main to complete') // if main is in the middle of running wait for it to complete await this.mainPromise - this.logger.info('main loop stoped.') + this.logger.info('main loop stopped.') // Shut down the metrics server if it's running. if (this.server) { diff --git a/packages/common-ts/src/base-service/validators.ts b/packages/common-ts/src/base-service/validators.ts index a919e700ac52..5eced2306707 100644 --- a/packages/common-ts/src/base-service/validators.ts +++ b/packages/common-ts/src/base-service/validators.ts @@ -49,6 +49,14 @@ const logLevel = makeValidator((input) => { } }) +const address = makeValidator((input) => { + if (!ethers.utils.isHexString(input, 20)) { + throw new Error(`expected input to be an address: ${input}`) + } else { + return input as `0x${string}` + } +}) + export const validators = { str, bool, @@ -63,4 +71,5 @@ export const validators = { jsonRpcProvider, staticJsonRpcProvider, logLevel, + address, } diff --git a/packages/common-ts/test/metrics.spec.ts b/packages/common-ts/test/metrics.spec.ts index eb837d1da50e..4a51fc2a9664 100644 --- a/packages/common-ts/test/metrics.spec.ts +++ b/packages/common-ts/test/metrics.spec.ts @@ -6,7 +6,7 @@ const expect = chai.expect import { Logger, LegacyMetrics, createMetricsServer } from '../src' describe('Metrics', () => { - it('shoud serve metrics', async () => { + it('should serve metrics', async () => { const metrics = new LegacyMetrics({ prefix: 'test_metrics', }) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 06d5f60a3ad8..d3f5f6634f59 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -1,711 +1,11 @@ -AdminFaucetAuthModuleTest:test_adminProof_verify_succeeds() (gas: 57573) -AdminFaucetAuthModuleTest:test_nonAdminProof_verify_succeeds() (gas: 59050) -AdminFaucetAuthModuleTest:test_proofWithWrongId_verify_succeeds() (gas: 60673) -AssetReceiverTest:test_constructor_succeeds() (gas: 9696) -AssetReceiverTest:test_receive_succeeds() (gas: 20844) -AssetReceiverTest:test_withdrawERC20_succeeds() (gas: 183383) -AssetReceiverTest:test_withdrawERC20_unauthorized_reverts() (gas: 153517) -AssetReceiverTest:test_withdrawERC20withAmount_succeeds() (gas: 182567) -AssetReceiverTest:test_withdrawERC20withAmount_unauthorized_reverts() (gas: 153528) -AssetReceiverTest:test_withdrawERC721_succeeds() (gas: 50755) -AssetReceiverTest:test_withdrawERC721_unauthorized_reverts() (gas: 51063) -AssetReceiverTest:test_withdrawETH_succeeds() (gas: 28344) -AssetReceiverTest:test_withdrawETH_unauthorized_reverts() (gas: 10680) -AssetReceiverTest:test_withdrawETHwithAmount_succeeds() (gas: 28241) -AssetReceiverTest:test_withdrawETHwithAmount_unauthorized_reverts() (gas: 10738) -AttestationStationTest:test_attest_bulk_succeeds() (gas: 703749) -AttestationStationTest:test_attest_individual_succeeds() (gas: 632087) -AttestationStationTest:test_attest_single_succeeds() (gas: 651325) -BlockOracle_Test:test_checkpointAndLoad_succeeds() (gas: 58396) -BlockOracle_Test:test_load_noBlockHash_reverts() (gas: 13681) -Bytes_slice_Test:test_slice_acrossMultipleWords_works() (gas: 9413) -Bytes_slice_Test:test_slice_acrossWords_works() (gas: 1430) -Bytes_slice_Test:test_slice_fromNonZeroIdx_works() (gas: 17240) -Bytes_slice_Test:test_slice_fromZeroIdx_works() (gas: 20804) -Bytes_toNibbles_Test:test_toNibbles_expectedResult128Bytes_works() (gas: 78882) -Bytes_toNibbles_Test:test_toNibbles_expectedResult5Bytes_works() (gas: 3992) -Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 823) -Constants_Test:test_eip1967Constants_succeeds() (gas: 453) -CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20435) -CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8461) -CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57494) -CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16610) -CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73522) -CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10554) -CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28289) -CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 73970) -CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32000) -CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91527) -CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13215) -CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35242) -CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52084) -CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48610) -CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12037) -CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13437) -CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12081) -CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81417) -CrossDomainOwnable_Test:test_onlyOwner_notOwner_reverts() (gas: 10597) -CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34883) -DelayedVetoable_Getters_Test:test_getters() (gas: 24466) -DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 36220) -DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 21867) -DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582) -DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395) -DisputeGameFactory_Owner_Test:test_owner_succeeds() (gas: 12581) -DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16042) -DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44301) -DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950) -DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642) -Drippie_Test:test_create_calledTwice_reverts() (gas: 168953) -Drippie_Test:test_create_succeeds() (gas: 183401) -Drippie_Test:test_drip_amount_succeeds() (gas: 285353) -Drippie_Test:test_drip_notExist_reverts() (gas: 14920) -Drippie_Test:test_drip_reentrant_reverts() (gas: 18875) -Drippie_Test:test_name_notExist_reverts() (gas: 16056) -Drippie_Test:test_notReentrant_zeroInterval_reverts() (gas: 18867) -Drippie_Test:test_not_active_reverts() (gas: 171162) -Drippie_Test:test_reentrant_succeeds() (gas: 180158) -Drippie_Test:test_set_statusNone_reverts() (gas: 168809) -Drippie_Test:test_set_statusSame_reverts() (gas: 169195) -Drippie_Test:test_set_status_succeeds() (gas: 198603) -Drippie_Test:test_shouldArchive_ifPaused_succeeds() (gas: 177348) -Drippie_Test:test_shouldNotAllowActive_ifArchived_reverts() (gas: 174669) -Drippie_Test:test_shouldNotAllowPaused_ifArchived_reverts() (gas: 174692) -Drippie_Test:test_shouldNotArchive_ifActive_reverts() (gas: 175732) -Drippie_Test:test_status_unauthorized_reverts() (gas: 167388) -Drippie_Test:test_trigger_oneFunction_succeeds() (gas: 338226) -Drippie_Test:test_trigger_twoFunctions_succeeds() (gas: 491907) -Drippie_Test:test_twice_inOneInterval_reverts() (gas: 303933) -FaucetTest:test_authAdmin_drip_succeeds() (gas: 366107) -FaucetTest:test_drip_afterTimeout_succeeds() (gas: 447891) -FaucetTest:test_drip_beforeTimeout_reverts() (gas: 378884) -FaucetTest:test_drip_disabledModule_reverts() (gas: 352401) -FaucetTest:test_drip_emitsEvent_succeeds() (gas: 369161) -FaucetTest:test_drip_githubSendsCorrectAmount_succeeds() (gas: 366607) -FaucetTest:test_drip_optimistNftSendsCorrectAmount_succeeds() (gas: 366551) -FaucetTest:test_drip_preventsReplayAttacks_succeeds() (gas: 369214) -FaucetTest:test_initialize_succeeds() (gas: 7626) -FaucetTest:test_nonAdmin_drip_fails() (gas: 262520) -FaucetTest:test_receive_succeeds() (gas: 17401) -FaucetTest:test_withdraw_nonAdmin_reverts() (gas: 13145) -FaucetTest:test_withdraw_succeeds() (gas: 78359) -FaultDisputeGame_ResolvesCorrectly_CorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 660000) -FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 666860) -FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 663563) -FaultDisputeGame_ResolvesCorrectly_CorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 666736) -FaultDisputeGame_ResolvesCorrectly_CorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 666049) -FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 652764) -FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 658252) -FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 655614) -FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 656552) -FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 656003) -FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 642642) -FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10409) -FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32328) -FaultDisputeGame_Test:test_gameData_succeeds() (gas: 32777) -FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8265) -FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57646) -FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 210650) -FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228466) -FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594025) -FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23175) -FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13300) -FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 147367) -FaultDisputeGame_Test:test_move_duplicateClaimsDifferentSubgames_succeeds() (gas: 556831) -FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 585853) -FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10980) -FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24644) -FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 151915) -FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 269432) -FaultDisputeGame_Test:test_resolve_claimAlreadyResolved_reverts() (gas: 272334) -FaultDisputeGame_Test:test_resolve_claimAtMaxDepthAlreadyResolved_reverts() (gas: 586606) -FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9754) -FaultDisputeGame_Test:test_resolve_outOfOrderResolution_reverts() (gas: 309015) -FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 139090) -FaultDisputeGame_Test:test_resolve_rootUncontestedButUnresolved_reverts() (gas: 15884) -FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 18428) -FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 51410) -FaultDisputeGame_Test:test_resolve_stepReached_succeeds() (gas: 498406) -FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 443357) -FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8232) -FeeVault_Test:test_constructor_succeeds() (gas: 18185) -GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354421) -GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952628) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 542325) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4054518) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 443561) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3489288) -GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 42714) -GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 90658) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 75076) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 75697) -GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143181) -GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8325) -GasPriceOracle_Test:test_decimals_succeeds() (gas: 6167) -GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8294) -GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10656) -GasPriceOracle_Test:test_overhead_succeeds() (gas: 10636) -GasPriceOracle_Test:test_scalar_succeeds() (gas: 10677) -GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5910) -GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5911) -GovernanceToken_Test:test_approve_succeeds() (gas: 133293) -GovernanceToken_Test:test_burnFrom_succeeds() (gas: 122733) -GovernanceToken_Test:test_burn_succeeds() (gas: 114588) -GovernanceToken_Test:test_constructor_succeeds() (gas: 21298) -GovernanceToken_Test:test_decreaseAllowance_succeeds() (gas: 137008) -GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 137118) -GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 17030) -GovernanceToken_Test:test_mint_fromOwner_succeeds() (gas: 108592) -GovernanceToken_Test:test_transferFrom_succeeds() (gas: 146273) -GovernanceToken_Test:test_transfer_succeeds() (gas: 138108) -Hashing_hashDepositSource_Test:test_hashDepositSource_succeeds() (gas: 633) -Initializer_Test:test_cannotReinitializeL1_succeeds() (gas: 98390) -L1BlockNumberTest:test_fallback_succeeds() (gas: 18655) -L1BlockNumberTest:test_getL1BlockNumber_succeeds() (gas: 10625) -L1BlockNumberTest:test_receive_succeeds() (gas: 25384) -L1BlockTest:test_basefee_succeeds() (gas: 7554) -L1BlockTest:test_hash_succeeds() (gas: 7576) -L1BlockTest:test_number_succeeds() (gas: 7629) -L1BlockTest:test_sequenceNumber_succeeds() (gas: 7630) -L1BlockTest:test_timestamp_succeeds() (gas: 7640) -L1BlockTest:test_updateValues_succeeds() (gas: 60482) -L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24781) -L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49384) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 212329) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 206087) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 126344) -L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 79599) -L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 200127) -L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 76590) -L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 60779) -L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12343) -L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 33133) -L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 392933) -L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1669172) -L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 87853) -L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24253) -L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62686) -L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37285) -L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 455269) -L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 70997) -L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35681) -L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60561) -L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35204) -L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 454966) -L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70823) -L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 18861) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 29475) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27220) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23241) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 24990) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 425245) -L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 514756) -L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 501934) -L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 720272) -L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 717849) -L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 22276) -L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 514789) -L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 502006) -L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 40759) -L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 54102) -L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 36551) -L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 36738) -L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 36623) -L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 498144) -L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 33452) -L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 34118) -L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 64673) -L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 28383) -L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 27239) -L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 615130) -L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8477) -L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 163749) -L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48913) -L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 31136) -L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11689) -L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 123957) -L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135812) -L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 49230) -L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10590) -L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 31453) -L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 26854) -L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 157156) -L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 34489) -L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 27183) -L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 29305) -L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 24641) -L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 154746) -L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 34271) -L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 21004) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 38661) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 246925) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27208) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23274) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 27124) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 179976) -L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 23902) -L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 46800) -L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 15216) -L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 20216) -L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 187875) -L2OutputOracle_constructor_Test:test_constructor_l2BlockTimeZero_reverts() (gas: 39022) -L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 39032) -L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 51777) -L2OutputOracle_constructor_Test:test_initialize_badTimestamp_reverts() (gas: 12353) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 217031) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 113258) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 21018) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_nonExistent_reverts() (gas: 111651) -L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 307411) -L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 185564) -L2OutputOracle_getter_Test:test_computeL2Timestamp_succeeds() (gas: 38198) -L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 269700) -L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17892) -L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 98188) -L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 98096) -L2OutputOracle_getter_Test:test_getL2Output_succeeds() (gas: 104600) -L2OutputOracle_getter_Test:test_latestBlockNumber_succeeds() (gas: 99129) -L2OutputOracle_getter_Test:test_nextBlockNumber_succeeds() (gas: 17447) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 28812) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_futureTimetamp_reverts() (gas: 30792) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_notProposer_reverts() (gas: 27928) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 103242) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unexpectedBlockNumber_reverts() (gas: 30526) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 31526) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_wrongFork_reverts() (gas: 31129) -L2OutputOracle_proposeL2Output_Test:test_proposeWithBlockhashAndHeight_succeeds() (gas: 97442) -L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 392297) -L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 392530) -L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 387821) -L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 396094) -L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 396456) -L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251807) -L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 388103) -L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 26132) -L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 26400) -L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 26159) -L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 96091) -L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 94945) -L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 45528) -L2StandardBridge_Test:test_initialize_succeeds() (gas: 26316) -L2StandardBridge_Test:test_receive_succeeds() (gas: 177125) -L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 143366) -L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16552) -L2ToL1MessagePasserTest:test_burn_succeeds() (gas: 112530) -L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract_succeeds() (gas: 70343) -L2ToL1MessagePasserTest:test_initiateWithdrawal_fromEOA_succeeds() (gas: 75830) -LegacyERC20ETH_Test:test_approve_doesNotExist_reverts() (gas: 10702) -LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10637) -LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6341) -LegacyERC20ETH_Test:test_decreaseAllowance_doesNotExist_reverts() (gas: 10724) -LegacyERC20ETH_Test:test_increaseAllowance_doesNotExist_reverts() (gas: 10690) -LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15476) -LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10627) -LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12957) -LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10755) -LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34524) -LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689) -LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8531) -LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 233535) -LivenessGuard_CheckTx_TestFails:test_checkTransaction_callerIsNotSafe_revert() (gas: 10358) -LivenessGuard_Constructor_Test:test_constructor_works() (gas: 1198965) -LivenessGuard_Getters_Test:test_getters_works() (gas: 10662) -LivenessGuard_OwnerManagement_Test:test_addOwner_succeeds() (gas: 274366) -LivenessGuard_OwnerManagement_Test:test_removeOwner_succeeds() (gas: 246263) -LivenessGuard_OwnerManagement_Test:test_swapOwner_succeeds() (gas: 284880) -LivenessGuard_ShowLiveness_Test:test_showLiveness_succeeds() (gas: 28831) -LivenessGuard_ShowLiveness_TestFail:test_showLiveness_callIsNotSafeOwner_reverts() (gas: 18770) -LivenessModule_CanRemove_Test:test_canRemove_works() (gas: 33026) -LivenessModule_CanRemove_TestFail:test_canRemove_notSafeOwner_reverts() (gas: 20489) -LivenessModule_Constructor_TestFail:test_constructor_minOwnersGreaterThanOwners_reverts() (gas: 83623) -LivenessModule_Constructor_TestFail:test_constructor_wrongThreshold_reverts() (gas: 92925) -LivenessModule_Get75PercentThreshold_Test:test_get75PercentThreshold_Works() (gas: 26339) -LivenessModule_Getters_Test:test_getters_works() (gas: 14853) -LivenessModule_RemoveOwners_Test:test_removeOwners_allOwners_succeeds() (gas: 1326177) -LivenessModule_RemoveOwners_Test:test_removeOwners_oneOwner_succeeds() (gas: 133975) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowEmptiedButNotShutDown_reverts() (gas: 1278643) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowMinButNotEmptied_reverts() (gas: 1281685) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_differentArrayLengths_reverts() (gas: 10502) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_guardChanged_reverts() (gas: 2839358) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_invalidThreshold_reverts() (gas: 69358) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRecently_reverts() (gas: 80971) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 617629) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1288036) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954) -MIPS_Test:test_add_succeeds() (gas: 122932) -MIPS_Test:test_addiSign_succeeds() (gas: 122923) -MIPS_Test:test_addi_succeeds() (gas: 123120) -MIPS_Test:test_addu_succeeds() (gas: 122974) -MIPS_Test:test_addui_succeeds() (gas: 123182) -MIPS_Test:test_and_succeeds() (gas: 122993) -MIPS_Test:test_andi_succeeds() (gas: 122926) -MIPS_Test:test_beq_succeeds() (gas: 203359) -MIPS_Test:test_bgez_succeeds() (gas: 122219) -MIPS_Test:test_bgtz_succeeds() (gas: 122140) -MIPS_Test:test_blez_succeeds() (gas: 122096) -MIPS_Test:test_bltz_succeeds() (gas: 122239) -MIPS_Test:test_bne_succeeds() (gas: 122305) -MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86514) -MIPS_Test:test_brk_succeeds() (gas: 122609) -MIPS_Test:test_clo_succeeds() (gas: 122661) -MIPS_Test:test_clone_succeeds() (gas: 122562) -MIPS_Test:test_clz_succeeds() (gas: 123132) -MIPS_Test:test_div_succeeds() (gas: 123111) -MIPS_Test:test_divu_succeeds() (gas: 123096) -MIPS_Test:test_exit_succeeds() (gas: 122611) -MIPS_Test:test_fcntl_succeeds() (gas: 204841) -MIPS_Test:test_illegal_instruction_fails() (gas: 91977) -MIPS_Test:test_invalid_root_fails() (gas: 436151) -MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121249) -MIPS_Test:test_jal_succeeds() (gas: 121238) -MIPS_Test:test_jalr_succeeds() (gas: 122357) -MIPS_Test:test_jr_succeeds() (gas: 122051) -MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85882) -MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120993) -MIPS_Test:test_jump_succeeds() (gas: 120923) -MIPS_Test:test_lb_succeeds() (gas: 128164) -MIPS_Test:test_lbu_succeeds() (gas: 128062) -MIPS_Test:test_lh_succeeds() (gas: 128185) -MIPS_Test:test_lhu_succeeds() (gas: 128102) -MIPS_Test:test_ll_succeeds() (gas: 128324) -MIPS_Test:test_lui_succeeds() (gas: 122205) -MIPS_Test:test_lw_succeeds() (gas: 127953) -MIPS_Test:test_lwl_succeeds() (gas: 243070) -MIPS_Test:test_lwr_succeeds() (gas: 243358) -MIPS_Test:test_mfhi_succeeds() (gas: 122566) -MIPS_Test:test_mflo_succeeds() (gas: 122695) -MIPS_Test:test_mmap_succeeds() (gas: 119529) -MIPS_Test:test_movn_succeeds() (gas: 204031) -MIPS_Test:test_movz_succeeds() (gas: 203899) -MIPS_Test:test_mthi_succeeds() (gas: 122610) -MIPS_Test:test_mtlo_succeeds() (gas: 122718) -MIPS_Test:test_mul_succeeds() (gas: 122210) -MIPS_Test:test_mult_succeeds() (gas: 122914) -MIPS_Test:test_multu_succeeds() (gas: 122951) -MIPS_Test:test_nor_succeeds() (gas: 123043) -MIPS_Test:test_or_succeeds() (gas: 123000) -MIPS_Test:test_ori_succeeds() (gas: 123003) -MIPS_Test:test_preimage_read_succeeds() (gas: 235481) -MIPS_Test:test_preimage_write_succeeds() (gas: 127551) -MIPS_Test:test_prestate_exited_succeeds() (gas: 113792) -MIPS_Test:test_sb_succeeds() (gas: 161501) -MIPS_Test:test_sc_succeeds() (gas: 161684) -MIPS_Test:test_sh_succeeds() (gas: 161538) -MIPS_Test:test_sll_succeeds() (gas: 122171) -MIPS_Test:test_sllv_succeeds() (gas: 122400) -MIPS_Test:test_slt_succeeds() (gas: 205226) -MIPS_Test:test_sltu_succeeds() (gas: 123217) -MIPS_Test:test_sra_succeeds() (gas: 122422) -MIPS_Test:test_srav_succeeds() (gas: 122690) -MIPS_Test:test_srl_succeeds() (gas: 122253) -MIPS_Test:test_srlv_succeeds() (gas: 122418) -MIPS_Test:test_step_abi_succeeds() (gas: 58467) -MIPS_Test:test_sub_succeeds() (gas: 123027) -MIPS_Test:test_subu_succeeds() (gas: 123024) -MIPS_Test:test_sw_succeeds() (gas: 161513) -MIPS_Test:test_swl_succeeds() (gas: 161574) -MIPS_Test:test_swr_succeeds() (gas: 161649) -MIPS_Test:test_xor_succeeds() (gas: 123028) -MIPS_Test:test_xori_succeeds() (gas: 123080) -MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5733) -MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889) -MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35845) -MerkleTrie_get_Test:test_get_invalidInternalNodeHash_reverts() (gas: 49654) -MerkleTrie_get_Test:test_get_nonexistentKey1_reverts() (gas: 54770) -MerkleTrie_get_Test:test_get_nonexistentKey2_reverts() (gas: 16699) -MerkleTrie_get_Test:test_get_smallerPathThanKey1_reverts() (gas: 51403) -MerkleTrie_get_Test:test_get_smallerPathThanKey2_reverts() (gas: 52884) -MerkleTrie_get_Test:test_get_validProof10_succeeds() (gas: 48845) -MerkleTrie_get_Test:test_get_validProof1_succeeds() (gas: 55970) -MerkleTrie_get_Test:test_get_validProof2_succeeds() (gas: 65861) -MerkleTrie_get_Test:test_get_validProof3_succeeds() (gas: 27309) -MerkleTrie_get_Test:test_get_validProof4_succeeds() (gas: 18105) -MerkleTrie_get_Test:test_get_validProof5_succeeds() (gas: 80701) -MerkleTrie_get_Test:test_get_validProof6_succeeds() (gas: 69460) -MerkleTrie_get_Test:test_get_validProof7_succeeds() (gas: 76158) -MerkleTrie_get_Test:test_get_validProof8_succeeds() (gas: 48802) -MerkleTrie_get_Test:test_get_validProof9_succeeds() (gas: 48802) -MerkleTrie_get_Test:test_get_wrongKeyProof_reverts() (gas: 50730) -MerkleTrie_get_Test:test_get_zeroBranchValueLength_reverts() (gas: 41684) -MerkleTrie_get_Test:test_get_zeroLengthKey_reverts() (gas: 3632) -MintManager_constructor_Test:test_constructor_succeeds() (gas: 10579) -MintManager_mint_Test:test_mint_afterPeriodElapsed_succeeds() (gas: 148117) -MintManager_mint_Test:test_mint_beforePeriodElapsed_reverts() (gas: 140433) -MintManager_mint_Test:test_mint_fromNotOwner_reverts() (gas: 10987) -MintManager_mint_Test:test_mint_fromOwner_succeeds() (gas: 137219) -MintManager_mint_Test:test_mint_moreThanCap_reverts() (gas: 142523) -MintManager_upgrade_Test:test_upgrade_fromNotOwner_reverts() (gas: 10974) -MintManager_upgrade_Test:test_upgrade_fromOwner_succeeds() (gas: 23434) -MintManager_upgrade_Test:test_upgrade_toZeroAddress_reverts() (gas: 11003) -Multichain:test_script_succeeds() (gas: 3078) -OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7621) -OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11164) -OptimismMintableERC20_Test:test_burn_succeeds() (gas: 50996) -OptimismMintableERC20_Test:test_erc165_supportsInterface_succeeds() (gas: 7787) -OptimismMintableERC20_Test:test_l1Token_succeeds() (gas: 7621) -OptimismMintableERC20_Test:test_l2Bridge_succeeds() (gas: 7621) -OptimismMintableERC20_Test:test_legacy_succeeds() (gas: 14322) -OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11165) -OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63544) -OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7667) -OptimismMintableERC721Factory_Test:test_constructor_succeeds() (gas: 8381) -OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_sameTwice_reverts() (gas: 8937393460516800045) -OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316169) -OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_zeroRemoteToken_reverts() (gas: 9493) -OptimismMintableERC721_Test:test_burn_notBridge_reverts() (gas: 136966) -OptimismMintableERC721_Test:test_burn_succeeds() (gas: 118832) -OptimismMintableERC721_Test:test_constructor_succeeds() (gas: 24162) -OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11121) -OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140547) -OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9005) -OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163441) -OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 9760) -OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1303953) -OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9570) -OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516769327) -OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1303943) -OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 11178) -OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16111) -OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26781) -OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 191521) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178667) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 182306) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41780) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 173953) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 181188) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 154740) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 219235) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 220983) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 38706) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 209679) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696162676) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 171302) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85805) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111317) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52973) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 58846) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 297494) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227596) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166699) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154430) -OptimismPortal_Test:test_constructor_succeeds() (gas: 28164) -OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14292) -OptimismPortal_Test:test_depositTransaction_createWithZeroValueForContract_succeeds() (gas: 76814) -OptimismPortal_Test:test_depositTransaction_createWithZeroValueForEOA_succeeds() (gas: 77115) -OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512149) -OptimismPortal_Test:test_depositTransaction_noValueContract_succeeds() (gas: 76767) -OptimismPortal_Test:test_depositTransaction_noValueEOA_succeeds() (gas: 77112) -OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14528) -OptimismPortal_Test:test_depositTransaction_withEthValueAndContractContractCreation_succeeds() (gas: 83773) -OptimismPortal_Test:test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() (gas: 75929) -OptimismPortal_Test:test_depositTransaction_withEthValueFromContract_succeeds() (gas: 83476) -OptimismPortal_Test:test_depositTransaction_withEthValueFromEOA_succeeds() (gas: 84069) -OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127617) -OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17430) -OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 24487) -OptimismPortal_Test:test_pause_succeeds() (gas: 27344) -OptimismPortal_Test:test_receive_succeeds() (gas: 127564) -OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 35651) -OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31514) -OptimismPortal_Test:test_unpause_succeeds() (gas: 27451) -OptimistAllowlistTest:test_constructor_succeeds() (gas: 16407) -OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49842) -OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49304) -OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestorWithFalsyValue_fails() (gas: 49544) -OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestor_succeeds() (gas: 53534) -OptimistAllowlistTest:test_isAllowedToMint_fromInvite_succeeds() (gas: 235508) -OptimistAllowlistTest:test_isAllowedToMint_fromWrongAllowlistAttestor_fails() (gas: 58311) -OptimistAllowlistTest:test_isAllowedToMint_fromWrongCoinbaseQuestAttestor_fails() (gas: 58268) -OptimistAllowlistTest:test_isAllowedToMint_fromWrongOptimistInviter_fails() (gas: 57601) -OptimistAllowlistTest:test_isAllowedToMint_withMultipleAttestations_succeeds() (gas: 324909) -OptimistAllowlistTest:test_isAllowedToMint_withoutAnyAttestations_fails() (gas: 23210) -OptimistInviterTest:test_claimInvite_claimBeforeMinCommitmentPeriod_reverts() (gas: 142819) -OptimistInviterTest:test_claimInvite_claimForSomeoneElse_succeeds() (gas: 245467) -OptimistInviterTest:test_claimInvite_replayingUsedNonce_reverts() (gas: 288437) -OptimistInviterTest:test_claimInvite_succeeds() (gas: 241374) -OptimistInviterTest:test_claimInvite_usingERC1271Wallet_succeeds() (gas: 245742) -OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentChain_reverts() (gas: 156587) -OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentContract_reverts() (gas: 156478) -OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentVersion_reverts() (gas: 155102) -OptimistInviterTest:test_claimInvite_whenIssuerHasNoInvitesLeft_reverts() (gas: 562110) -OptimistInviterTest:test_claimInvite_whenIssuerNeverReceivedInvites_reverts() (gas: 110711) -OptimistInviterTest:test_claimInvite_withIncorrectSignature_reverts() (gas: 253095) -OptimistInviterTest:test_claimInvite_withoutCommittingHash_reverts() (gas: 119210) -OptimistInviterTest:test_commitInvite_committingForSomeoneElse_succeeds() (gas: 140584) -OptimistInviterTest:test_commitInvite_committingForYourself_succeeds() (gas: 138628) -OptimistInviterTest:test_commitInvite_committingSameHashTwice_reverts() (gas: 142056) -OptimistInviterTest:test_grantInvites_adminAddingInvites_succeeds() (gas: 190757) -OptimistInviterTest:test_grantInvites_nonAdminAddingInvites_reverts() (gas: 14026) -OptimistInviterTest:test_initialize_succeeds() (gas: 10573) -OptimistTest:test_approve_soulbound_reverts() (gas: 70487) -OptimistTest:test_baseURI_returnsCorrectBaseURI_succeeds() (gas: 124568) -OptimistTest:test_burn_byNonOwner_reverts() (gas: 73197) -OptimistTest:test_burn_byOwner_succeeds() (gas: 54487) -OptimistTest:test_initialize_succeeds() (gas: 20840) -OptimistTest:test_mint_afterAllowlistAttestation_succeeds() (gas: 121465) -OptimistTest:test_mint_afterCoinbaseQuestAttestation_succeeds() (gas: 130362) -OptimistTest:test_mint_afterInviteClaimed_succeeds() (gas: 311331) -OptimistTest:test_mint_afterMultipleAttestations_succeeds() (gas: 377762) -OptimistTest:test_mint_forAlreadyMintedClaimer_reverts() (gas: 118023) -OptimistTest:test_mint_forNonAllowlistedClaimer_reverts() (gas: 29886) -OptimistTest:test_mint_secondaryMinter_succeeds() (gas: 72711) -OptimistTest:test_multicall_batchingClaimAndMint_succeeds() (gas: 308376) -OptimistTest:test_setApprovalForAll_soulbound_reverts() (gas: 74239) -OptimistTest:test_supportsInterface_returnsCorrectInterfaceForERC721_succeeds() (gas: 5805) -OptimistTest:test_tokenIdOfAddress_returnsOwnerID_succeeds() (gas: 63730) -OptimistTest:test_tokenURI_returnsCorrectTokenURI_succeeds() (gas: 195908) -OptimistTest:test_transferFrom_soulbound_reverts() (gas: 75512) -PreimageOracle_Test:test_keccak256PreimageKey_succeeds() (gas: 319) -PreimageOracle_Test:test_loadKeccak256PreimagePart_outOfBoundsOffset_reverts() (gas: 8971) -PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 76076) -PreimageOracle_Test:test_loadLocalData_multipleContexts_succeeds() (gas: 147718) -PreimageOracle_Test:test_loadLocalData_onePart_succeeds() (gas: 75905) -PreimageOracle_Test:test_loadLocalData_outOfBoundsOffset_reverts() (gas: 8882) -ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 52181) -ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 32301) -ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15508) -ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15520) -ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 36440) -ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15675) -ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51084) -ProxyAdmin_Test:test_chugsplashUpgradeAndCall_succeeds() (gas: 82311) -ProxyAdmin_Test:test_chugsplashUpgrade_succeeds() (gas: 48988) -ProxyAdmin_Test:test_delegateResolvedChangeProxyAdmin_succeeds() (gas: 33936) -ProxyAdmin_Test:test_delegateResolvedGetProxyAdmin_succeeds() (gas: 17691) -ProxyAdmin_Test:test_delegateResolvedGetProxyImplementation_succeeds() (gas: 62028) -ProxyAdmin_Test:test_delegateResolvedUpgradeAndCall_succeeds() (gas: 98039) -ProxyAdmin_Test:test_delegateResolvedUpgrade_succeeds() (gas: 58482) -ProxyAdmin_Test:test_erc1967ChangeProxyAdmin_succeeds() (gas: 34674) -ProxyAdmin_Test:test_erc1967GetProxyAdmin_succeeds() (gas: 15616) -ProxyAdmin_Test:test_erc1967GetProxyImplementation_succeeds() (gas: 52073) -ProxyAdmin_Test:test_erc1967UpgradeAndCall_succeeds() (gas: 78971) -ProxyAdmin_Test:test_erc1967Upgrade_succeeds() (gas: 50080) -ProxyAdmin_Test:test_isUpgrading_succeeds() (gas: 19442) -ProxyAdmin_Test:test_onlyOwner_notOwner_reverts() (gas: 22767) -ProxyAdmin_Test:test_owner_succeeds() (gas: 9738) -ProxyAdmin_Test:test_proxyType_succeeds() (gas: 20533) -ProxyAdmin_Test:test_setAddressManager_notOwner_reverts() (gas: 10578) -ProxyAdmin_Test:test_setImplementationName_notOwner_reverts() (gas: 11111) -ProxyAdmin_Test:test_setImplementationName_succeeds() (gas: 38945) -ProxyAdmin_Test:test_setProxyType_notOwner_reverts() (gas: 10814) -Proxy_Test:test_delegatesToImpl_succeeds() (gas: 45207) -Proxy_Test:test_implementationKey_succeeds() (gas: 20911) -Proxy_Test:test_implementation_isZeroAddress_reverts() (gas: 47628) -Proxy_Test:test_implementation_zeroAddressCaller_succeeds() (gas: 14752) -Proxy_Test:test_ownerKey_succeeds() (gas: 19067) -Proxy_Test:test_ownerProxyCall_notAdmin_succeeds() (gas: 35477) -Proxy_Test:test_proxyCallToImp_notAdmin_succeeds() (gas: 30010) -Proxy_Test:test_upgradeToAndCall_functionDoesNotExist_reverts() (gas: 107980) -Proxy_Test:test_upgradeToAndCall_isPayable_succeeds() (gas: 53744) -Proxy_Test:test_upgradeToAndCall_succeeds() (gas: 125192) -Proxy_Test:test_upgradeTo_clashingFunctionSignatures_succeeds() (gas: 101363) -RLPReader_readBytes_Test:test_readBytes_bytestring00_succeeds() (gas: 1863) -RLPReader_readBytes_Test:test_readBytes_bytestring01_succeeds() (gas: 1840) -RLPReader_readBytes_Test:test_readBytes_bytestring7f_succeeds() (gas: 1861) -RLPReader_readBytes_Test:test_readBytes_invalidListLength_reverts() (gas: 3903) -RLPReader_readBytes_Test:test_readBytes_invalidPrefix_reverts() (gas: 3961) -RLPReader_readBytes_Test:test_readBytes_invalidRemainder_reverts() (gas: 4155) -RLPReader_readBytes_Test:test_readBytes_invalidStringLength_reverts() (gas: 3857) -RLPReader_readBytes_Test:test_readBytes_revertListItem_reverts() (gas: 3998) -RLPReader_readList_Test:test_readList_dictTest1_succeeds() (gas: 23140) -RLPReader_readList_Test:test_readList_empty_succeeds() (gas: 4610) -RLPReader_readList_Test:test_readList_incorrectLengthInArray_reverts() (gas: 3976) -RLPReader_readList_Test:test_readList_int32Overflow2_reverts() (gas: 4139) -RLPReader_readList_Test:test_readList_int32Overflow_reverts() (gas: 4138) -RLPReader_readList_Test:test_readList_invalidRemainder_reverts() (gas: 4114) -RLPReader_readList_Test:test_readList_invalidShortList_reverts() (gas: 3967) -RLPReader_readList_Test:test_readList_invalidValue_reverts() (gas: 3878) -RLPReader_readList_Test:test_readList_leadingZerosInLongLengthArray1_reverts() (gas: 3982) -RLPReader_readList_Test:test_readList_leadingZerosInLongLengthArray2_reverts() (gas: 3945) -RLPReader_readList_Test:test_readList_leadingZerosInLongLengthList1_reverts() (gas: 3984) -RLPReader_readList_Test:test_readList_listLongerThan32Elements_reverts() (gas: 38612) -RLPReader_readList_Test:test_readList_listOfLists2_succeeds() (gas: 12122) -RLPReader_readList_Test:test_readList_listOfLists_succeeds() (gas: 9472) -RLPReader_readList_Test:test_readList_longList1_succeeds() (gas: 28354) -RLPReader_readList_Test:test_readList_longList2_succeeds() (gas: 196352) -RLPReader_readList_Test:test_readList_longListLessThan56Bytes_reverts() (gas: 4023) -RLPReader_readList_Test:test_readList_longStringLength_reverts() (gas: 3946) -RLPReader_readList_Test:test_readList_longStringLessThan56Bytes_reverts() (gas: 4009) -RLPReader_readList_Test:test_readList_multiList_succeeds() (gas: 11695) -RLPReader_readList_Test:test_readList_nonOptimalLongLengthArray1_reverts() (gas: 3999) -RLPReader_readList_Test:test_readList_nonOptimalLongLengthArray2_reverts() (gas: 4044) -RLPReader_readList_Test:test_readList_notEnoughContentForList1_reverts() (gas: 4115) -RLPReader_readList_Test:test_readList_notEnoughContentForList2_reverts() (gas: 4117) -RLPReader_readList_Test:test_readList_notEnoughContentForString1_reverts() (gas: 4072) -RLPReader_readList_Test:test_readList_notEnoughContentForString2_reverts() (gas: 4094) -RLPReader_readList_Test:test_readList_notLongEnough_reverts() (gas: 3955) -RLPReader_readList_Test:test_readList_shortListMax1_succeeds() (gas: 39602) -RLPWriter_writeList_Test:test_writeList_dictTest1_succeeds() (gas: 36979) -RLPWriter_writeList_Test:test_writeList_empty_succeeds() (gas: 1711) -RLPWriter_writeList_Test:test_writeList_listoflists2_succeeds() (gas: 16566) -RLPWriter_writeList_Test:test_writeList_listoflists_succeeds() (gas: 10841) -RLPWriter_writeList_Test:test_writeList_longlist1_succeeds() (gas: 40383) -RLPWriter_writeList_Test:test_writeList_longlist2_succeeds() (gas: 280754) -RLPWriter_writeList_Test:test_writeList_multiList_succeeds() (gas: 22446) -RLPWriter_writeList_Test:test_writeList_shortListMax1_succeeds() (gas: 36793) -RLPWriter_writeList_Test:test_writeList_stringList_succeeds() (gas: 10697) -RLPWriter_writeString_Test:test_writeString_bytestring00_succeeds() (gas: 951) -RLPWriter_writeString_Test:test_writeString_bytestring01_succeeds() (gas: 951) -RLPWriter_writeString_Test:test_writeString_bytestring7f_succeeds() (gas: 972) -RLPWriter_writeString_Test:test_writeString_empty_succeeds() (gas: 1633) -RLPWriter_writeString_Test:test_writeString_longstring2_succeeds() (gas: 258768) -RLPWriter_writeString_Test:test_writeString_longstring_succeeds() (gas: 16961) -RLPWriter_writeString_Test:test_writeString_shortstring2_succeeds() (gas: 15376) -RLPWriter_writeString_Test:test_writeString_shortstring_succeeds() (gas: 2470) -RLPWriter_writeUint_Test:test_writeUint_mediumint2_succeeds() (gas: 8721) -RLPWriter_writeUint_Test:test_writeUint_mediumint3_succeeds() (gas: 9098) -RLPWriter_writeUint_Test:test_writeUint_mediumint_succeeds() (gas: 8357) -RLPWriter_writeUint_Test:test_writeUint_smallint2_succeeds() (gas: 7249) -RLPWriter_writeUint_Test:test_writeUint_smallint3_succeeds() (gas: 7271) -RLPWriter_writeUint_Test:test_writeUint_smallint4_succeeds() (gas: 7272) -RLPWriter_writeUint_Test:test_writeUint_smallint_succeeds() (gas: 7250) -RLPWriter_writeUint_Test:test_writeUint_zero_succeeds() (gas: 7734) -ResolvedDelegateProxy_Test:test_fallback_addressManagerNotSet_reverts() (gas: 605906) -ResolvedDelegateProxy_Test:test_fallback_delegateCallBar_reverts() (gas: 24783) -ResourceMetering_Test:test_meter_denominatorEq1_reverts() (gas: 20024064) -ResourceMetering_Test:test_meter_initialResourceParams_succeeds() (gas: 12423) -ResourceMetering_Test:test_meter_updateNoGasDelta_succeeds() (gas: 2011591) -ResourceMetering_Test:test_meter_updateOneEmptyBlock_succeeds() (gas: 20894) -ResourceMetering_Test:test_meter_updateParamsNoChange_succeeds() (gas: 17217) -ResourceMetering_Test:test_meter_updateTenEmptyBlocks_succeeds() (gas: 23747) -ResourceMetering_Test:test_meter_updateTwoEmptyBlocks_succeeds() (gas: 23703) -ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20020816) -ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 19549) -SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1021670598) -SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1095190710) -Semver_Test:test_behindProxy_succeeds() (gas: 507558) -Semver_Test:test_version_succeeds() (gas: 9418) -SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 78333) -SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 46486) -SequencerFeeVault_Test:test_constructor_succeeds() (gas: 5526) -SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 5464) -SequencerFeeVault_Test:test_receive_succeeds() (gas: 17373) -SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9332) -SequencerFeeVault_Test:test_withdraw_toL1_succeeds() (gas: 171675) -SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11549) -StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 49936) -StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33072) -Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31821, ~: 31821) -Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31598, ~: 31598) -Storage_Roundtrip_Test:test_setGetUint_succeeds(bytes32,uint256) (runs: 64, μ: 30731, ~: 31664) -SystemConfig_Initialize_Test:test_initialize_events_succeeds() (gas: 71972) -SystemConfig_Initialize_Test:test_initialize_startBlockNoop_reverts() (gas: 81247) -SystemConfig_Initialize_Test:test_initialize_startBlockOverride_succeeds() (gas: 65143) -SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 64968) -SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 57177) -SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 15607) -SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 15577) -SystemConfig_Setters_TestFail:test_setGasLimit_notOwner_reverts() (gas: 15676) -SystemConfig_Setters_TestFail:test_setResourceConfig_badMinMax_reverts() (gas: 18541) -SystemConfig_Setters_TestFail:test_setResourceConfig_badPrecision_reverts() (gas: 21142) -SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas: 22146) -SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 16799) -SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 18578) -SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 15590) -TransactorTest:test_call_succeeds() (gas: 26709) -TransactorTest:test_call_unauthorized_reverts() (gas: 18117) -TransactorTest:test_constructor_succeeds() (gas: 9739) -TransactorTest:test_delegateCall_succeeds() (gas: 20909) -TransactorTest:test_delegateCall_unauthorized_reverts() (gas: 18124) -TransferOnionTest:test_constructor_succeeds() (gas: 564855) -TransferOnionTest:test_unwrap_succeeds() (gas: 724955) \ No newline at end of file +GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 356552) +GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2954737) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 549159) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4061135) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 450308) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3496057) +GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 59803) +GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92930) +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68360) +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 69013) +GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155551) \ No newline at end of file diff --git a/packages/contracts-bedrock/.gitignore b/packages/contracts-bedrock/.gitignore index 61b186e0d7d9..8b673a6cb333 100644 --- a/packages/contracts-bedrock/.gitignore +++ b/packages/contracts-bedrock/.gitignore @@ -3,12 +3,18 @@ artifacts forge-artifacts cache broadcast -typechain +kout-deployment +kout-proofs +test/kontrol/logs # Metrics coverage.out .resource-metering.csv +# Testing State +.testdata +kontrol_prove_report.xml + # Scripts scripts/go-ffi/go-ffi @@ -26,3 +32,6 @@ deployments/1337 # Devnet config which changes with each 'make devnet-up' deploy-config/devnetL1.json + +# Getting Started guide deploy config +deploy-config/getting-started.json diff --git a/packages/contracts-bedrock/.storage-layout b/packages/contracts-bedrock/.storage-layout deleted file mode 100644 index c0a4b57b5e56..000000000000 --- a/packages/contracts-bedrock/.storage-layout +++ /dev/null @@ -1,304 +0,0 @@ -======================= -👁👁 STORAGE LAYOUT snapshot 👁👁 -======================= - -======================= -➡ src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|--------------------|--------------------------|------|--------|-------|----------------------------------------------------------| -| spacer_0_0_20 | address | 0 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| _initialized | uint8 | 0 | 20 | 1 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| _initializing | bool | 0 | 21 | 1 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| spacer_1_0_1600 | uint256[50] | 1 | 0 | 1600 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| spacer_51_0_20 | address | 51 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| spacer_52_0_1568 | uint256[49] | 52 | 0 | 1568 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| spacer_101_0_1 | bool | 101 | 0 | 1 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| spacer_102_0_1568 | uint256[49] | 102 | 0 | 1568 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| spacer_151_0_32 | uint256 | 151 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| spacer_152_0_1568 | uint256[49] | 152 | 0 | 1568 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| spacer_201_0_32 | mapping(bytes32 => bool) | 201 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| spacer_202_0_32 | mapping(bytes32 => bool) | 202 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| successfulMessages | mapping(bytes32 => bool) | 203 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| xDomainMsgSender | address | 204 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| msgNonce | uint240 | 205 | 0 | 30 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| failedMessages | mapping(bytes32 => bool) | 206 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| __gap | uint256[42] | 207 | 0 | 1344 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | -| PORTAL | contract OptimismPortal | 249 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | - -======================= -➡ src/L1/L1StandardBridge.sol:L1StandardBridge -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|---------------|-------------------------------------------------|------|--------|-------|----------------------------------------------| -| _initialized | uint8 | 0 | 0 | 1 | src/L1/L1StandardBridge.sol:L1StandardBridge | -| _initializing | bool | 0 | 1 | 1 | src/L1/L1StandardBridge.sol:L1StandardBridge | -| spacer_0_2_20 | address | 0 | 2 | 20 | src/L1/L1StandardBridge.sol:L1StandardBridge | -| spacer_1_0_20 | address | 1 | 0 | 20 | src/L1/L1StandardBridge.sol:L1StandardBridge | -| deposits | mapping(address => mapping(address => uint256)) | 2 | 0 | 32 | src/L1/L1StandardBridge.sol:L1StandardBridge | -| messenger | contract CrossDomainMessenger | 3 | 0 | 20 | src/L1/L1StandardBridge.sol:L1StandardBridge | -| __gap | uint256[46] | 4 | 0 | 1472 | src/L1/L1StandardBridge.sol:L1StandardBridge | - -======================= -➡ src/L1/L2OutputOracle.sol:L2OutputOracle -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|---------------------|-------------------------------|------|--------|-------|------------------------------------------| -| _initialized | uint8 | 0 | 0 | 1 | src/L1/L2OutputOracle.sol:L2OutputOracle | -| _initializing | bool | 0 | 1 | 1 | src/L1/L2OutputOracle.sol:L2OutputOracle | -| startingBlockNumber | uint256 | 1 | 0 | 32 | src/L1/L2OutputOracle.sol:L2OutputOracle | -| startingTimestamp | uint256 | 2 | 0 | 32 | src/L1/L2OutputOracle.sol:L2OutputOracle | -| l2Outputs | struct Types.OutputProposal[] | 3 | 0 | 32 | src/L1/L2OutputOracle.sol:L2OutputOracle | -| challenger | address | 4 | 0 | 20 | src/L1/L2OutputOracle.sol:L2OutputOracle | -| proposer | address | 5 | 0 | 20 | src/L1/L2OutputOracle.sol:L2OutputOracle | - -======================= -➡ src/L1/OptimismPortal.sol:OptimismPortal -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|----------------------|------------------------------------------------------------|------|--------|-------|------------------------------------------| -| _initialized | uint8 | 0 | 0 | 1 | src/L1/OptimismPortal.sol:OptimismPortal | -| _initializing | bool | 0 | 1 | 1 | src/L1/OptimismPortal.sol:OptimismPortal | -| params | struct ResourceMetering.ResourceParams | 1 | 0 | 32 | src/L1/OptimismPortal.sol:OptimismPortal | -| __gap | uint256[48] | 2 | 0 | 1536 | src/L1/OptimismPortal.sol:OptimismPortal | -| l2Sender | address | 50 | 0 | 20 | src/L1/OptimismPortal.sol:OptimismPortal | -| finalizedWithdrawals | mapping(bytes32 => bool) | 51 | 0 | 32 | src/L1/OptimismPortal.sol:OptimismPortal | -| provenWithdrawals | mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal) | 52 | 0 | 32 | src/L1/OptimismPortal.sol:OptimismPortal | -| paused | bool | 53 | 0 | 1 | src/L1/OptimismPortal.sol:OptimismPortal | -| l2Oracle | contract L2OutputOracle | 53 | 1 | 20 | src/L1/OptimismPortal.sol:OptimismPortal | -| systemConfig | contract SystemConfig | 54 | 0 | 20 | src/L1/OptimismPortal.sol:OptimismPortal | -| guardian | address | 55 | 0 | 20 | src/L1/OptimismPortal.sol:OptimismPortal | - -======================= -➡ src/L1/SystemConfig.sol:SystemConfig -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|-----------------|----------------------------------------|------|--------|-------|--------------------------------------| -| _initialized | uint8 | 0 | 0 | 1 | src/L1/SystemConfig.sol:SystemConfig | -| _initializing | bool | 0 | 1 | 1 | src/L1/SystemConfig.sol:SystemConfig | -| __gap | uint256[50] | 1 | 0 | 1600 | src/L1/SystemConfig.sol:SystemConfig | -| _owner | address | 51 | 0 | 20 | src/L1/SystemConfig.sol:SystemConfig | -| __gap | uint256[49] | 52 | 0 | 1568 | src/L1/SystemConfig.sol:SystemConfig | -| overhead | uint256 | 101 | 0 | 32 | src/L1/SystemConfig.sol:SystemConfig | -| scalar | uint256 | 102 | 0 | 32 | src/L1/SystemConfig.sol:SystemConfig | -| batcherHash | bytes32 | 103 | 0 | 32 | src/L1/SystemConfig.sol:SystemConfig | -| gasLimit | uint64 | 104 | 0 | 8 | src/L1/SystemConfig.sol:SystemConfig | -| _resourceConfig | struct ResourceMetering.ResourceConfig | 105 | 0 | 32 | src/L1/SystemConfig.sol:SystemConfig | -| startBlock | uint256 | 106 | 0 | 32 | src/L1/SystemConfig.sol:SystemConfig | - -======================= -➡ src/L1/L1ERC721Bridge.sol:L1ERC721Bridge -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|---------------|------------------------------------------------------------------|------|--------|-------|------------------------------------------| -| _initialized | uint8 | 0 | 0 | 1 | src/L1/L1ERC721Bridge.sol:L1ERC721Bridge | -| _initializing | bool | 0 | 1 | 1 | src/L1/L1ERC721Bridge.sol:L1ERC721Bridge | -| messenger | contract CrossDomainMessenger | 0 | 2 | 20 | src/L1/L1ERC721Bridge.sol:L1ERC721Bridge | -| __gap | uint256[48] | 1 | 0 | 1536 | src/L1/L1ERC721Bridge.sol:L1ERC721Bridge | -| deposits | mapping(address => mapping(address => mapping(uint256 => bool))) | 49 | 0 | 32 | src/L1/L1ERC721Bridge.sol:L1ERC721Bridge | - -======================= -➡ src/legacy/DeployerWhitelist.sol:DeployerWhitelist -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|-----------|--------------------------|------|--------|-------|----------------------------------------------------| -| owner | address | 0 | 0 | 20 | src/legacy/DeployerWhitelist.sol:DeployerWhitelist | -| whitelist | mapping(address => bool) | 1 | 0 | 32 | src/legacy/DeployerWhitelist.sol:DeployerWhitelist | - -======================= -➡ src/L2/L1Block.sol:L1Block -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|----------------|---------|------|--------|-------|----------------------------| -| number | uint64 | 0 | 0 | 8 | src/L2/L1Block.sol:L1Block | -| timestamp | uint64 | 0 | 8 | 8 | src/L2/L1Block.sol:L1Block | -| basefee | uint256 | 1 | 0 | 32 | src/L2/L1Block.sol:L1Block | -| hash | bytes32 | 2 | 0 | 32 | src/L2/L1Block.sol:L1Block | -| sequenceNumber | uint64 | 3 | 0 | 8 | src/L2/L1Block.sol:L1Block | -| batcherHash | bytes32 | 4 | 0 | 32 | src/L2/L1Block.sol:L1Block | -| l1FeeOverhead | uint256 | 5 | 0 | 32 | src/L2/L1Block.sol:L1Block | -| l1FeeScalar | uint256 | 6 | 0 | 32 | src/L2/L1Block.sol:L1Block | - -======================= -➡ src/legacy/L1BlockNumber.sol:L1BlockNumber -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| - -======================= -➡ src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|--------------------|--------------------------|------|--------|-------|----------------------------------------------------------| -| spacer_0_0_20 | address | 0 | 0 | 20 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| _initialized | uint8 | 0 | 20 | 1 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| _initializing | bool | 0 | 21 | 1 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| spacer_1_0_1600 | uint256[50] | 1 | 0 | 1600 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| spacer_51_0_20 | address | 51 | 0 | 20 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| spacer_52_0_1568 | uint256[49] | 52 | 0 | 1568 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| spacer_101_0_1 | bool | 101 | 0 | 1 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| spacer_102_0_1568 | uint256[49] | 102 | 0 | 1568 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| spacer_151_0_32 | uint256 | 151 | 0 | 32 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| spacer_152_0_1568 | uint256[49] | 152 | 0 | 1568 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| spacer_201_0_32 | mapping(bytes32 => bool) | 201 | 0 | 32 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| spacer_202_0_32 | mapping(bytes32 => bool) | 202 | 0 | 32 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| successfulMessages | mapping(bytes32 => bool) | 203 | 0 | 32 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| xDomainMsgSender | address | 204 | 0 | 20 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| msgNonce | uint240 | 205 | 0 | 30 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| failedMessages | mapping(bytes32 => bool) | 206 | 0 | 32 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | -| __gap | uint256[42] | 207 | 0 | 1344 | src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger | - -======================= -➡ src/L2/L2StandardBridge.sol:L2StandardBridge -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|---------------|-------------------------------------------------|------|--------|-------|----------------------------------------------| -| _initialized | uint8 | 0 | 0 | 1 | src/L2/L2StandardBridge.sol:L2StandardBridge | -| _initializing | bool | 0 | 1 | 1 | src/L2/L2StandardBridge.sol:L2StandardBridge | -| spacer_0_2_20 | address | 0 | 2 | 20 | src/L2/L2StandardBridge.sol:L2StandardBridge | -| spacer_1_0_20 | address | 1 | 0 | 20 | src/L2/L2StandardBridge.sol:L2StandardBridge | -| deposits | mapping(address => mapping(address => uint256)) | 2 | 0 | 32 | src/L2/L2StandardBridge.sol:L2StandardBridge | -| messenger | contract CrossDomainMessenger | 3 | 0 | 20 | src/L2/L2StandardBridge.sol:L2StandardBridge | -| __gap | uint256[46] | 4 | 0 | 1472 | src/L2/L2StandardBridge.sol:L2StandardBridge | - -======================= -➡ src/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|--------------|--------------------------|------|--------|-------|----------------------------------------------------| -| sentMessages | mapping(bytes32 => bool) | 0 | 0 | 32 | src/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser | -| msgNonce | uint240 | 1 | 0 | 30 | src/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser | - -======================= -➡ src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|--------------|-------------------------------------------------|------|--------|-------|----------------------------------------------| -| _balances | mapping(address => uint256) | 0 | 0 | 32 | src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH | -| _allowances | mapping(address => mapping(address => uint256)) | 1 | 0 | 32 | src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH | -| _totalSupply | uint256 | 2 | 0 | 32 | src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH | -| _name | string | 3 | 0 | 32 | src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH | -| _symbol | string | 4 | 0 | 32 | src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH | - -======================= -➡ src/L2/SequencerFeeVault.sol:SequencerFeeVault -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|----------------|---------|------|--------|-------|------------------------------------------------| -| totalProcessed | uint256 | 0 | 0 | 32 | src/L2/SequencerFeeVault.sol:SequencerFeeVault | - -======================= -➡ src/L2/BaseFeeVault.sol:BaseFeeVault -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|----------------|---------|------|--------|-------|--------------------------------------| -| totalProcessed | uint256 | 0 | 0 | 32 | src/L2/BaseFeeVault.sol:BaseFeeVault | - -======================= -➡ src/L2/L1FeeVault.sol:L1FeeVault -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|----------------|---------|------|--------|-------|----------------------------------| -| totalProcessed | uint256 | 0 | 0 | 32 | src/L2/L1FeeVault.sol:L1FeeVault | - -======================= -➡ src/L2/L2ERC721Bridge.sol:L2ERC721Bridge -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|---------------|-------------------------------|------|--------|-------|------------------------------------------| -| _initialized | uint8 | 0 | 0 | 1 | src/L2/L2ERC721Bridge.sol:L2ERC721Bridge | -| _initializing | bool | 0 | 1 | 1 | src/L2/L2ERC721Bridge.sol:L2ERC721Bridge | -| messenger | contract CrossDomainMessenger | 0 | 2 | 20 | src/L2/L2ERC721Bridge.sol:L2ERC721Bridge | -| __gap | uint256[48] | 1 | 0 | 1536 | src/L2/L2ERC721Bridge.sol:L2ERC721Bridge | - -======================= -➡ src/vendor/WETH9.sol:WETH9 -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|-----------|-------------------------------------------------|------|--------|-------|----------------------------| -| name | string | 0 | 0 | 32 | src/vendor/WETH9.sol:WETH9 | -| symbol | string | 1 | 0 | 32 | src/vendor/WETH9.sol:WETH9 | -| decimals | uint8 | 2 | 0 | 1 | src/vendor/WETH9.sol:WETH9 | -| balanceOf | mapping(address => uint256) | 3 | 0 | 32 | src/vendor/WETH9.sol:WETH9 | -| allowance | mapping(address => mapping(address => uint256)) | 4 | 0 | 32 | src/vendor/WETH9.sol:WETH9 | - -======================= -➡ src/universal/ProxyAdmin.sol:ProxyAdmin -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|--------------------|-----------------------------------------------|------|--------|-------|-----------------------------------------| -| _owner | address | 0 | 0 | 20 | src/universal/ProxyAdmin.sol:ProxyAdmin | -| proxyType | mapping(address => enum ProxyAdmin.ProxyType) | 1 | 0 | 32 | src/universal/ProxyAdmin.sol:ProxyAdmin | -| implementationName | mapping(address => string) | 2 | 0 | 32 | src/universal/ProxyAdmin.sol:ProxyAdmin | -| addressManager | contract AddressManager | 3 | 0 | 20 | src/universal/ProxyAdmin.sol:ProxyAdmin | -| upgrading | bool | 3 | 20 | 1 | src/universal/ProxyAdmin.sol:ProxyAdmin | - -======================= -➡ src/universal/Proxy.sol:Proxy -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| - -======================= -➡ src/legacy/L1ChugSplashProxy.sol:L1ChugSplashProxy -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| - -======================= -➡ src/universal/OptimismMintableERC20.sol:OptimismMintableERC20 -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|--------------|-------------------------------------------------|------|--------|-------|---------------------------------------------------------------| -| _balances | mapping(address => uint256) | 0 | 0 | 32 | src/universal/OptimismMintableERC20.sol:OptimismMintableERC20 | -| _allowances | mapping(address => mapping(address => uint256)) | 1 | 0 | 32 | src/universal/OptimismMintableERC20.sol:OptimismMintableERC20 | -| _totalSupply | uint256 | 2 | 0 | 32 | src/universal/OptimismMintableERC20.sol:OptimismMintableERC20 | -| _name | string | 3 | 0 | 32 | src/universal/OptimismMintableERC20.sol:OptimismMintableERC20 | -| _symbol | string | 4 | 0 | 32 | src/universal/OptimismMintableERC20.sol:OptimismMintableERC20 | - -======================= -➡ src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|---------------|---------|------|--------|-------|-----------------------------------------------------------------------------| -| _initialized | uint8 | 0 | 0 | 1 | src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory | -| _initializing | bool | 0 | 1 | 1 | src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory | -| bridge | address | 0 | 2 | 20 | src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory | - -======================= -➡ src/dispute/DisputeGameFactory.sol:DisputeGameFactory -======================= - -| Name | Type | Slot | Offset | Bytes | Contract | -|------------------|--------------------------------------------|------|--------|-------|-------------------------------------------------------| -| _initialized | uint8 | 0 | 0 | 1 | src/dispute/DisputeGameFactory.sol:DisputeGameFactory | -| _initializing | bool | 0 | 1 | 1 | src/dispute/DisputeGameFactory.sol:DisputeGameFactory | -| __gap | uint256[50] | 1 | 0 | 1600 | src/dispute/DisputeGameFactory.sol:DisputeGameFactory | -| _owner | address | 51 | 0 | 20 | src/dispute/DisputeGameFactory.sol:DisputeGameFactory | -| __gap | uint256[49] | 52 | 0 | 1568 | src/dispute/DisputeGameFactory.sol:DisputeGameFactory | -| gameImpls | mapping(GameType => contract IDisputeGame) | 101 | 0 | 32 | src/dispute/DisputeGameFactory.sol:DisputeGameFactory | -| _disputeGames | mapping(Hash => GameId) | 102 | 0 | 32 | src/dispute/DisputeGameFactory.sol:DisputeGameFactory | -| _disputeGameList | GameId[] | 103 | 0 | 32 | src/dispute/DisputeGameFactory.sol:DisputeGameFactory | diff --git a/packages/contracts-bedrock/CHANGELOG.md b/packages/contracts-bedrock/CHANGELOG.md index 52af9bab0fb3..881f44272508 100644 --- a/packages/contracts-bedrock/CHANGELOG.md +++ b/packages/contracts-bedrock/CHANGELOG.md @@ -1,5 +1,11 @@ # @eth-optimism/contracts-bedrock +## 0.17.1 + +### Patch Changes + +- [#9415](https://github.com/ethereum-optimism/optimism/pull/9415) [`79effc52e8b82d15b5eda43acf540ac6c5f8d5d7`](https://github.com/ethereum-optimism/optimism/commit/79effc52e8b82d15b5eda43acf540ac6c5f8d5d7) Thanks [@nitaliano](https://github.com/nitaliano)! - Bumps version so fpac contracts exist for SDK to consume + ## 0.16.2 ### Patch Changes diff --git a/packages/contracts-bedrock/CONTRIBUTING.md b/packages/contracts-bedrock/CONTRIBUTING.md index cf55668c5e23..63c579dedf2f 100644 --- a/packages/contracts-bedrock/CONTRIBUTING.md +++ b/packages/contracts-bedrock/CONTRIBUTING.md @@ -55,7 +55,7 @@ Optimism's smart contracts are written in Solidity and we use [foundry](https:// 1. Make sure to `pnpm install` 1. [foundry](https://getfoundry.sh) 1. Foundry is built with [rust](https://www.rust-lang.org/tools/install), and this project uses a pinned version of foundry. Install the rust toolchain with `rustup`. - 1. Make sure to install the version of foundry used by `ci-builder`, defined in the `.foundryrc` file in the root of this repo. Once you have `foundryup` installed, there is a helper to do this: `pnpm install:foundry` + 1. Make sure to install the version of foundry used by `ci-builder`, defined in the `versions.json` file in the root of this repo under the `foundry` key. Once you have `foundryup` installed, there is a helper to do this: `pnpm install:foundry` 1. [golang](https://golang.org/doc/install) 1. [python](https://www.python.org/downloads/) @@ -86,26 +86,11 @@ To deploy the smart contracts on a local devnet, run `make devnet-up` in the mon ### Tools -#### Layout Locking - -We use a system called "layout locking" as a safety mechanism to prevent certain contract variables from being moved to different storage slots accidentally. -To lock a contract variable, add it to the `layout-lock.json` file which has the following format: - -```json -{ - "MyContractName": { - "myVariableName": { - "slot": 1, - "offset": 0, - "length": 32 - } - } -} -``` - -With the above config, the `validate-spacers` script will check that we have a contract called `MyContractName`, that the contract has a variable named `myVariableName`, and that the variable is in the correct position as defined in the lock file. -You should add things to the `layout-lock.json` file when you want those variables to **never** change. -Layout locking should be used in combination with diffing the `.storage-layout` file in CI. +#### Validate Spacing + +In order to make sure that we don't accidentally overwrite storage slots, contract storage layouts are checked to make sure spacing is correct. + +This uses the `.storage-layout` file to check contract spacing. Run `pnpm validate-spacers` to check the spacing of all contracts. #### Gas Snapshots diff --git a/packages/contracts-bedrock/README.md b/packages/contracts-bedrock/README.md index fd33f581433a..216e84b7af58 100644 --- a/packages/contracts-bedrock/README.md +++ b/packages/contracts-bedrock/README.md @@ -1,64 +1,279 @@ -# Optimism Smart Contracts (Bedrock) +# OP Stack Smart Contracts -[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=contracts-bedrock-tests)](https://codecov.io/gh/ethereum-optimism/optimism) +This package contains the L1 and L2 smart contracts for the OP Stack. +Detailed specifications for the contracts contained within this package can be found at [specs.optimism.io](https://specs.optimism.io). +High-level information about these contracts can be found within this README and within the [Optimism Developer Docs](https://docs.optimism.io). -This package contains the smart contracts that compose the on-chain component of Optimism's upcoming Bedrock upgrade. -We've tried to maintain 100% backwards compatibility with the existing system while also introducing new useful features. -You can find detailed specifications for the contracts contained within this package [here](../../specs). + + +## Table of Contents -A style guide we follow for writing contracts can be found [here](./STYLE_GUIDE.md). +- [Architecture Overview](#architecture-overview) + - [Core L1 Smart Contracts](#core-l1-smart-contracts) + - [Notes for Core L1 Smart Contracts](#notes-for-core-l1-smart-contracts) + - [Core L2 Smart Contracts](#core-l2-smart-contracts) + - [Notes for Core L2 Smart Contracts](#notes-for-core-l2-smart-contracts) + - [Smart Contract Proxies](#smart-contract-proxies) +- [External Usage](#external-usage) + - [Using OP Stack Contracts in Solidity](#using-op-stack-contracts-in-solidity) + - [Using OP Stack Contracts in JavaScript](#using-op-stack-contracts-in-javascript) + - [Deployed Addresses](#deployed-addresses) +- [Contributing](#contributing) + - [Contributing Guide](#contributing-guide) + - [Style Guide](#style-guide) +- [Deployment](#deployment) + - [Configuration](#configuration) + - [Execution](#execution) + - [Deploying a single contract](#deploying-a-single-contract) +- [Testing](#testing) + - [Test Setup](#test-setup) + - [Static Analysis](#static-analysis) -## Contracts Overview + -### Contracts deployed to L1 +## Architecture Overview -| Name | Proxy Type | Description | -| ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | -| [`L1CrossDomainMessenger`](../../specs/messengers.md) | [`ResolvedDelegateProxy`](./contracts/legacy/ResolvedDelegateProxy.sol) | High-level interface for sending messages to and receiving messages from Optimism | -| [`L1StandardBridge`](../../specs/bridges.md) | [`L1ChugSplashProxy`](./contracts/legacy/L1ChugSplashProxy.sol) | Standardized system for transferring ERC20 tokens to/from Optimism | -| [`L2OutputOracle`](../../specs/proposals.md#l2-output-oracle-smart-contract) | [`Proxy`](./contracts/universal/Proxy.sol) | Stores commitments to the state of Optimism which can be used by contracts on L1 to access L2 state | -| [`OptimismPortal`](../../specs/deposits.md#deposit-contract) | [`Proxy`](./contracts/universal/Proxy.sol) | Low-level message passing interface | -| [`OptimismMintableERC20Factory`](../../specs/predeploys.md#optimismmintableerc20factory) | [`Proxy`](./contracts/universal/Proxy.sol) | Deploys standard `OptimismMintableERC20` tokens that are compatible with either `StandardBridge` | -| [`ProxyAdmin`](../../specs/TODO) | - | Contract that can upgrade L1 contracts | +> **NOTE**: Smart contract names in the architecture diagrams below are links to source code. Click them! -### Contracts deployed to L2 +### Core L1 Smart Contracts -| Name | Proxy Type | Description | -| ---------------------------------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------ | -| [`GasPriceOracle`](../../specs/predeploys.md#ovm_gaspriceoracle) | [`Proxy`](./contracts/universal/Proxy.sol) | Stores L2 gas price configuration values | -| [`L1Block`](../../specs/predeploys.md#l1block) | [`Proxy`](./contracts/universal/Proxy.sol) | Stores L1 block context information (e.g., latest known L1 block hash) | -| [`L2CrossDomainMessenger`](../../specs/predeploys.md#l2crossdomainmessenger) | [`Proxy`](./contracts/universal/Proxy.sol) | High-level interface for sending messages to and receiving messages from L1 | -| [`L2StandardBridge`](../../specs/predeploys.md#l2standardbridge) | [`Proxy`](./contracts/universal/Proxy.sol) | Standardized system for transferring ERC20 tokens to/from L1 | -| [`L2ToL1MessagePasser`](../../specs/predeploys.md#ovm_l2tol1messagepasser) | [`Proxy`](./contracts/universal/Proxy.sol) | Low-level message passing interface | -| [`SequencerFeeVault`](../../specs/predeploys.md#sequencerfeevault) | [`Proxy`](./contracts/universal/Proxy.sol) | Vault for L2 transaction fees | -| [`OptimismMintableERC20Factory`](../../specs/predeploys.md#optimismmintableerc20factory) | [`Proxy`](./contracts/universal/Proxy.sol) | Deploys standard `OptimismMintableERC20` tokens that are compatible with either `StandardBridge` | -| [`L2ProxyAdmin`](../../specs/TODO) | - | Contract that can upgrade L2 contracts when sent a transaction from L1 | +Below you'll find an architecture diagram describing the core L1 smart contracts for the OP Stack. +Smart contracts that are considered "peripheral" and not core to the operation of the OP Stack system are described separately. -### Legacy and deprecated contracts +```mermaid +graph LR + subgraph "External Contracts" + ExternalERC20(External ERC20 Contracts) + ExternalERC721(External ERC721 Contracts) + end -| Name | Location | Proxy Type | Description | -| --------------------------------------------------------------- | -------- | ------------------------------------------ | ------------------------------------------------------------------------------------- | -| [`AddressManager`](./contracts/legacy/AddressManager.sol) | L1 | - | Legacy upgrade mechanism (unused in Bedrock) | -| [`DeployerWhitelist`](./contracts/legacy/DeployerWhitelist.sol) | L2 | [`Proxy`](./contracts/universal/Proxy.sol) | Legacy contract for managing allowed deployers (unused since EVM Equivalence upgrade) | -| [`L1BlockNumber`](./contracts/legacy/L1BlockNumber.sol) | L2 | [`Proxy`](./contracts/universal/Proxy.sol) | Legacy contract for accessing latest known L1 block number, replaced by `L1Block` | + subgraph "L1 Smart Contracts" + BatchDataEOA(Batch Inbox Address) + L1StandardBridge(L1StandardBridge) + L1ERC721Bridge(L1ERC721Bridge) + L1CrossDomainMessenger(L1CrossDomainMessenger) + L2OutputOracle(L2OutputOracle) + OptimismPortal(OptimismPortal) + SuperchainConfig(SuperchainConfig) + SystemConfig(SystemConfig) + end -## Installation + subgraph "User Interactions" + Users(Users) + end -We export contract ABIs, contract source code, and contract deployment information for this package via `npm`: + subgraph "System Interactions" + Batcher(Batcher) + Proposer(Proposer) + Guardian(Guardian) + end -```shell -npm install @eth-optimism/contracts-bedrock + subgraph "Layer 2 Interactions" + L2Nodes(Layer 2 Nodes) + end + + Batcher -->|publish transaction batches| BatchDataEOA + Proposer -->|propose state outputs| L2OutputOracle + Guardian -->|remove invalid state outputs| L2OutputOracle + + ExternalERC20 <-->|mint/burn/transfer| L1StandardBridge + ExternalERC721 <-->|mint/burn/transfer| L1ERC721Bridge + + L1StandardBridge <-->|send/receive message| L1CrossDomainMessenger + L1ERC721Bridge <-->|send/receive message| L1CrossDomainMessenger + L1CrossDomainMessenger <-->|package/send/receive message| OptimismPortal + L1StandardBridge -.->|query pause state| SuperchainConfig + L1ERC721Bridge -.->|query pause state| SuperchainConfig + L1CrossDomainMessenger -.->|query pause state| SuperchainConfig + OptimismPortal -.->|query pause state| SuperchainConfig + + OptimismPortal -.->|query config| SystemConfig + OptimismPortal -.->|query proposed states| L2OutputOracle + + Users <-->|deposit/withdraw ETH/ERC20| L1StandardBridge + Users <-->|deposit/withdraw ERC721| L1ERC721Bridge + Users -->|prove/execute withdrawal transactions| OptimismPortal + + L2Nodes -.->|fetch transaction batches| BatchDataEOA + L2Nodes -.->|verify output roots| L2OutputOracle + L2Nodes -.->|fetch deposit events| OptimismPortal + + classDef extContracts stroke:#ff9,stroke-width:2px; + classDef l1Contracts stroke:#bbf,stroke-width:2px; + classDef l1EOA stroke:#bbb,stroke-width:2px; + classDef userInt stroke:#f9a,stroke-width:2px; + classDef systemUser stroke:#f9a,stroke-width:2px; + classDef l2Nodes stroke:#333,stroke-width:2px + class ExternalERC20,ExternalERC721 extContracts; + class L1StandardBridge,L1ERC721Bridge,L1CrossDomainMessenger,L2OutputOracle,OptimismPortal,SuperchainConfig,SystemConfig l1Contracts; + class BatchDataEOA l1EOA; + class Users userInt; + class Batcher,Proposer,Guardian systemUser; + class L2Nodes l2Nodes; +``` + +#### Notes for Core L1 Smart Contracts + +- The `Batch Data Address` described above (**highlighted in GREY**) is *not* a smart contract and is instead simply an arbitrarily chosen account that is assumed to have no known private key. This account is typically chosen as the account `0xFF0000....` where `` is chain ID of the Layer 2 network for which the data is being posted. For instance, for OP Mainnet, this account is chosen as `0xFF00000000000000000000000000000000000010`. However, this is not a strict requirement and some OP Stack chains may not follow this convention. +- Smart contracts that sit behind `Proxy` contracts are **highlighted in BLUE**. Refer to the [Smart Contract Proxies](#smart-contract-proxies) section below to understand how these proxies are designed. + - The `L1CrossDomainMessenger` contract sits behind the [`ResolvedDelegateProxy`](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol) contract, a legacy proxy contract type used within older versions of the OP Stack. This proxy type is used exclusively for the `L1CrossDomainMessenger` to maintain backwards compatibility. + - The `L1StandardBridge` contract sits behind the [`L1ChugSplashProxy`](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol) contract, a legacy proxy contract type used within older versions of the OP Stack. This proxy type is used exclusively for the `L1StandardBridge` contract to maintain backwards compatibility. + +### Core L2 Smart Contracts + +Here you'll find an architecture diagram describing the core OP Stack smart contracts that exist natively on the L2 chain itself. + +```mermaid +graph LR + subgraph "Layer 1 (Ethereum)" + L1SmartContracts(L1 Smart Contracts) + end + + subgraph "L2 Client" + L2Node(L2 Node) + end + + subgraph "L2 System Contracts" + L1Block(L1Block) + GasPriceOracle(GasPriceOracle) + L1FeeVault(L1FeeVault) + BaseFeeVault(BaseFeeVault) + SequencerFeeVault(SequencerFeeVault) + end + + subgraph "L2 Bridge Contracts" + L2CrossDomainMessenger(L2CrossDomainMessenger) + L2ToL1MessagePasser(L2ToL1MessagePasser) + L2StandardBridge(L2StandardBridge) + L2ERC721Bridge(L2ERC721Bridge) + end + + subgraph "Transactions" + DepositTransaction(Deposit Transaction) + UserTransaction(User Transaction) + end + + subgraph "External Contracts" + ExternalERC20(External ERC20 Contracts) + ExternalERC721(External ERC721 Contracts) + end + + subgraph "Remaining L2 Universe" + OtherContracts(Any Contracts and Addresses) + end + + L2Node -.->|derives chain from| L1SmartContracts + L2Node -->|updates| L1Block + L2Node -->|distributes fees to| L1FeeVault + L2Node -->|distributes fees to| BaseFeeVault + L2Node -->|distributes fees to| SequencerFeeVault + L2Node -->|derives from deposits| DepositTransaction + L2Node -->|derives from chain data| UserTransaction + + UserTransaction -->|can trigger| OtherContracts + DepositTransaction -->|maybe triggers| L2CrossDomainMessenger + DepositTransaction -->|can trigger| OtherContracts + + ExternalERC20 <-->|mint/burn/transfer| L2StandardBridge + ExternalERC721 <-->|mint/burn/transfer| L2ERC721Bridge + + L2StandardBridge <-->|sends/receives messages| L2CrossDomainMessenger + L2ERC721Bridge <-->|sends/receives messages| L2CrossDomainMessenger + GasPriceOracle -.->|queries| L1Block + L2CrossDomainMessenger -->|sends messages| L2ToL1MessagePasser + + classDef extContracts stroke:#ff9,stroke-width:2px; + classDef l2Contracts stroke:#bbf,stroke-width:2px; + classDef transactions stroke:#fba,stroke-width:2px; + classDef l2Node stroke:#f9a,stroke-width:2px; + + class ExternalERC20,ExternalERC721 extContracts; + class L2CrossDomainMessenger,L2ToL1MessagePasser,L2StandardBridge,L2ERC721Bridge l2Contracts; + class L1Block,L1FeeVault,BaseFeeVault,SequencerFeeVault,GasPriceOracle l2Contracts; + class UserTransaction,DepositTransaction transactions; + class L2Node l2Node; +``` + +#### Notes for Core L2 Smart Contracts + +- Contracts highlighted as "L2 System Contracts" are updated or mutated automatically as part of the chain derivation process. Users typically do not mutate these contracts directly, except in the case of the `FeeVault` contracts where any user may trigger a withdrawal of collected fees to the pre-determined withdrawal address. +- Smart contracts that sit behind `Proxy` contracts are **highlighted in BLUE**. Refer to the [Smart Contract Proxies](#smart-contract-proxies) section below to understand how these proxies are designed. +- User interactions for the "L2 Bridge Contracts" have been omitted from this diagram but largely follow the same user interactions described in the architecture diagram for the [Core L1 Smart Contracts](#core-l1-smart-contracts). + +### Smart Contract Proxies + +Most L1 and L2 smart contracts for OP Stack chains today sit behind `Proxy` contracts that themselves are managed by a `ProxyAdmin` contract. +The `ProxyAdmin` contract is controlled by some `owner` address that can be any EOA or smart contract. +Below you'll find a diagram that explains the behavior of the typical proxy contract. + +```mermaid +graph LR + ProxyAdminOwner(Proxy Admin Owner) + ProxyAdmin(ProxyAdmin) + + subgraph "Logical Smart Contract" + Proxy(Proxy) + Implementation(Implementation) + end + + ProxyAdminOwner -->|manages| ProxyAdmin + ProxyAdmin -->|upgrades| Proxy + Proxy -->|delegatecall| Implementation + + classDef l1Contracts stroke:#bbf,stroke-width:2px; + classDef systemUser stroke:#f9a,stroke-width:2px; + class Proxy l1Contracts; + class ProxyAdminOwner systemUser; +``` + +## External Usage + +### Using OP Stack Contracts in Solidity + +OP Stack smart contracts are published to NPM and can be installed via: + +```sh +npm install @eth-optimism/contracts-bedrock. ``` +Refer to the [Optimism Developer Docs](https://docs.optimism.io/builders/dapp-developers/contracts/system-contracts#using-system-contracts-in-solidity) for additional information about how to use this package. + +### Using OP Stack Contracts in JavaScript + +Contract ABIs and addresses are published to NPM in a separate package and can be installed via: + +```sh +npm install @eth-optimism/contracts-ts +``` + +Refer to the [Optimism Developer Docs](https://docs.optimism.io/builders/dapp-developers/contracts/system-contracts#using-system-contracts-in-javascript) for additional information about how to use this package. + +### Deployed Addresses + +See the [Optimism Developer Docs](https://docs.optimism.io/chain/addresses) for the deployed addresses of these smart contracts for OP Mainnet and OP Sepolia. + ## Contributing -For all information about working on and contributing to Optimism's smart contracts, please see [CONTRIBUTING.md](./CONTRIBUTING.md) +### Contributing Guide + +Contributions to the OP Stack are always welcome. +Please refer to the [CONTRIBUTING.md](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/CONTRIBUTING.md) for more information about how to contribute to the OP Stack smart contracts. + +### Style Guide + +OP Stack smart contracts should be written according to the [STYLE_GUIDE.md](./STYLE_GUIDE.md) found within this repository. +Maintaining a consistent code style makes code easier to review and maintain, ultimately making the development process safer. ## Deployment The smart contracts are deployed using `foundry` with a `hardhat-deploy` compatibility layer. When the contracts are deployed, they will write a temp file to disk that can then be formatted into a `hardhat-deploy` style artifact by calling another script. +The addresses in the `deployments` directory will be read into the script based on the backend's chain id. +To manually define the set of addresses used in the script, set the `CONTRACT_ADDRESSES_PATH` env var to a path on the local +filesystem that points to a JSON file full of key value pairs where the keys are names of contracts and the +values are addresses. This works well with the JSON files in `superchain-ops`. + ### Configuration Create or modify a file `.json` inside of the [`deploy-config`](./deploy-config/) folder. @@ -67,6 +282,9 @@ The spec for the deploy config is defined by the `deployConfigSpec` located insi ### Execution +Before deploying the contracts, you can verify the state diff produced by the deploy script using the `runWithStateDiff()` function signature which produces the outputs inside [`snapshots/state-diff/`](./snapshots/state-diff). +Run the deployment with state diffs by executing: `forge script -vvv scripts/Deploy.s.sol:Deploy --sig 'runWithStateDiff()' --rpc-url $ETH_RPC_URL --broadcast --private-key $PRIVATE_KEY`. + 1. Set the env vars `ETH_RPC_URL`, `PRIVATE_KEY` and `ETHERSCAN_API_KEY` if contract verification is desired 1. Deploy the contracts with `forge script -vvv scripts/Deploy.s.sol:Deploy --rpc-url $ETH_RPC_URL --broadcast --private-key $PRIVATE_KEY` Pass the `--verify` flag to verify the deployments automatically with Etherscan. @@ -76,3 +294,32 @@ The spec for the deploy config is defined by the `deployConfigSpec` located insi All of the functions for deploying a single contract are `public` meaning that the `--sig` argument to `forge script` can be used to target the deployment of a single contract. + +## Testing + +### Test Setup + +The Solidity unit tests use the same codepaths to set up state that are used in production. The same L1 deploy script is used to deploy the L1 contracts for the in memory tests +and the L2 state is set up using the same L2 genesis generation code that is used for production and then loaded into foundry via the `vm.loadAllocs` cheatcode. This helps +to reduce the overhead of maintaining multiple ways to set up the state as well as give additional coverage to the "actual" way that the contracts are deployed. + +The L1 contract addresses are held in `deployments/hardhat/.deploy` and the L2 test state is held in a `.testdata` directory. The L1 addresses are used to create the L2 state +and it is possible for stale addresses to be pulled into the L2 state, causing tests to fail. Stale addresses may happen if the order of the L1 deployments happen differently +since some contracts are deployed using `CREATE`. Run `pnpm clean` and rerun the tests if they are failing for an unknown reason. + +### Static Analysis + +`contracts-bedrock` uses [slither](https://github.com/crytic/slither) as its primary static analysis tool. +Slither will be run against PRs as part of CI, and new findings will be reported as a comment on the PR. +CI will fail if there are any new findings of medium or higher severity, as configured in the repo's Settings > Code Security and Analysis > Code Scanning > Protection rules setting. + +There are two corresponding jobs in CI: one calls "Slither Analysis" and one called "Code scanning results / Slither". +The former will always pass if Slither runs successfully, and the latter will fail if there are any new findings of medium or higher severity. + +Existing findings can be found in the repo's Security tab > [Code Scanning](https://github.com/ethereum-optimism/optimism/security/code-scanning) section. +You can view findings for a specific PR using the `pr:{number}` filter, such [`pr:9405`](https://github.com/ethereum-optimism/optimism/security/code-scanning?query=is:open+pr:9405). + +For each finding, either fix it locally and push a new commit, or dismiss it through the PR comment's UI. + +Note that you can run slither locally by running `slither .`, but because it does not contain the triaged results from GitHub, it will be noisy. +Instead, you should run `slither ./path/to/contract.sol` to run it against a specific file. diff --git a/packages/contracts-bedrock/STYLE_GUIDE.md b/packages/contracts-bedrock/STYLE_GUIDE.md index 416e8f626a18..181521368c58 100644 --- a/packages/contracts-bedrock/STYLE_GUIDE.md +++ b/packages/contracts-bedrock/STYLE_GUIDE.md @@ -1,6 +1,6 @@ # Smart Contract Style Guide -This document providing guidance on how we organize and write our smart contracts. For cases where +This document provides guidance on how we organize and write our smart contracts. For cases where this document does not provide guidance, please refer to existing contracts for guidance, with priority on the `L2OutputOracle` and `OptimismPortal`. @@ -21,9 +21,10 @@ with additional rules. These are: We also have the following custom tags: - `@custom:proxied`: Add to a contract whenever it's meant to live behind a proxy. -- `@custom:upgradeable`: Add to a contract whenever it's meant to be used in an upgradeable contract. -- `@custom:semver`: Add to a constructor to indicate the version of a contract. +- `@custom:upgradeable`: Add to a contract whenever it's meant to be inherited by an upgradeable contract. +- `@custom:semver`: Add to `version` variable which indicate the contracts semver. - `@custom:legacy`: Add to an event or function when it only exists for legacy support. +- `@custom:network-specific`: Add to state variables which vary between OP Chains. #### Errors @@ -54,7 +55,7 @@ Immutable variables: - should have a hand written getter function This approach clearly indicates to the developer that the value is immutable, without exposing -the non-standard casing to the interface. It also ensure that we don’t need to break the ABIs if +the non-standard casing to the interface. It also ensures that we don’t need to break the ABIs if we switch between values being in storage and immutable. #### Spacers @@ -114,9 +115,14 @@ All test contracts and functions should be organized and named according to the These guidelines are also encoded in a script which can be run with: ``` -tsx scripts/forge-test-names.ts +tsx scripts/checks/check-test-names.ts ``` +#### Expect Revert with Low Level Calls + +There is a non-intuitive behavior in foundry tests, which is documented [here](https://book.getfoundry.sh/cheatcodes/expect-revert?highlight=expectrevert#expectrevert). +When testing for a revert on a low-level call, please use the `revertsAsExpected` pattern suggested there. + _Note: This is a work in progress, not all test files are compliant with these guidelines._ #### Organizing Principles @@ -153,7 +159,7 @@ Test contracts should be named one of the following according to their use: To minimize clutter, getter functions can be grouped together into a single test contract, ie. `TargetContract_Getters_Test`. -## Withdrawaing From Fee Vaults +## Withdrawing From Fee Vaults See the file `scripts/FeeVaultWithdrawal.s.sol` to withdraw from the L2 fee vaults. It includes instructions on how to run it. `foundry` is required. diff --git a/packages/contracts-bedrock/deploy-config/base-sepolia.json b/packages/contracts-bedrock/deploy-config/base-sepolia.json new file mode 100644 index 000000000000..f83a1c285782 --- /dev/null +++ b/packages/contracts-bedrock/deploy-config/base-sepolia.json @@ -0,0 +1,61 @@ +{ + "finalSystemOwner": "0x608081689Fe46936fB2fBDF7552CbB1D80ad4822", + + "l1StartingBlockTag": "safe", + + "l1ChainID": 11155111, + "l2ChainID": 84532, + "l1BlockTime": 12, + "l2BlockTime": 2, + + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + + "p2pSequencerAddress": "0xb830b99c95Ea32300039624Cb567d324D4b1D83C", + "batchInboxAddress": "0xFf00000000000000000000000000000000084532", + "batchSenderAddress": "0x6CDEbe940BC0F26850285cacA097C11c33103E47", + + "l2OutputOracleSubmissionInterval": 120, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleStartingTimestamp": 1695767904, + + "l2OutputOracleProposer": "0x20044a0d104E9e788A0C984A2B7eAe615afD046b", + "l2OutputOracleChallenger": "0xDa3037Ff70Ac92CD867c683BD807e5A484857405", + + "finalizationPeriodSeconds": 12, + + "proxyAdminOwner": "0x8937037a0bB08658e5A178C182e60b12f14720ce", + "baseFeeVaultRecipient": "0xc7dE632EC7f11634318856a57c5897f6a0bda3b0", + "l1FeeVaultRecipient": "0x9082AB367EAFe8887a88A1B9970BE2719007Cf6b", + "sequencerFeeVaultRecipient": "0x4cFDfb25b34b5e5E3932dA5C4F080194137AF20F", + + "baseFeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "sequencerFeeVaultWithdrawalNetwork": 0, + + "gasPriceOracleOverhead": 2100, + "gasPriceOracleScalar": 1000000, + + "governanceTokenSymbol": "NA", + "governanceTokenName": "NotApplicable", + "governanceTokenOwner": "0xEb5E931176714636563DC7BE4A10387D911BaE05", + + "l2GenesisBlockGasLimit": "0x17D7840", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + + "eip1559Denominator": 50, + "eip1559Elasticity": 10, + + "l2GenesisRegolithTimeOffset": "0x0", + + "finalSystemOwner": "0x608081689Fe46936fB2fBDF7552CbB1D80ad4822", + "superchainConfigGuardian": "0xA9FF930151130fd19DA1F03E5077AFB7C78F8503", + + "systemConfigStartBlock": 0, + "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" +} diff --git a/packages/contracts-bedrock/deploy-config/devnetL1-template.json b/packages/contracts-bedrock/deploy-config/devnetL1-template.json index 46b8f146b493..e9393aafcc6a 100644 --- a/packages/contracts-bedrock/deploy-config/devnetL1-template.json +++ b/packages/contracts-bedrock/deploy-config/devnetL1-template.json @@ -24,12 +24,12 @@ "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", - "baseFeeVaultWithdrawalNetwork": "remote", - "l1FeeVaultWithdrawalNetwork": "remote", - "sequencerFeeVaultWithdrawalNetwork": "remote", + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "sequencerFeeVaultWithdrawalNetwork": 0, "proxyAdminOwner": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", "finalSystemOwner": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", - "portalGuardian": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", + "superchainConfigGuardian": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", "finalizationPeriodSeconds": 2, "fundDevAccounts": true, "l2GenesisBlockBaseFeePerGas": "0x1", @@ -44,12 +44,27 @@ "eip1559Elasticity": 6, "l1GenesisBlockTimestamp": "0x64c811bf", "l2GenesisRegolithTimeOffset": "0x0", - "l2GenesisSpanBatchTimeOffset": "0x0", - "l2GenesisCanyonTimeOffset": "0x40", - "faultGameAbsolutePrestate": "0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98", - "faultGameMaxDepth": 30, - "faultGameMaxDuration": 1200, + "l2GenesisDeltaTimeOffset": null, + "l2GenesisCanyonTimeOffset": "0x0", "systemConfigStartBlock": 0, "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", - "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameAbsolutePrestate": "0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98", + "faultGameMaxDepth": 50, + "faultGameMaxDuration": 2400, + "faultGameGenesisBlock": 0, + "faultGameGenesisOutputRoot": "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + "faultGameSplitDepth": 14, + "faultGameWithdrawalDelay": 604800, + "preimageOracleMinProposalSize": 10000, + "preimageOracleChallengePeriod": 120, + "proofMaturityDelaySeconds": 12, + "disputeGameFinalityDelaySeconds": 6, + "respectedGameType": 0, + "useFaultProofs": false, + "usePlasma": false, + "daChallengeWindow": 160, + "daResolveWindow": 160, + "daBondSize": 1000000, + "daResolverRefundPercentage": 0 } diff --git a/packages/contracts-bedrock/deploy-config/getting-started.json b/packages/contracts-bedrock/deploy-config/getting-started.json deleted file mode 100644 index 7ac03cdc652d..000000000000 --- a/packages/contracts-bedrock/deploy-config/getting-started.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "finalSystemOwner": "ADMIN", - "portalGuardian": "ADMIN", - - "l1StartingBlockTag": "BLOCKHASH", - - "l1ChainID": 5, - "l2ChainID": 42069, - "l2BlockTime": 2, - "l1BlockTime": 12, - - "maxSequencerDrift": 600, - "sequencerWindowSize": 3600, - "channelTimeout": 300, - - "p2pSequencerAddress": "SEQUENCER", - "batchInboxAddress": "0xff00000000000000000000000000000000042069", - "batchSenderAddress": "BATCHER", - - "l2OutputOracleSubmissionInterval": 120, - "l2OutputOracleStartingBlockNumber": 0, - "l2OutputOracleStartingTimestamp": TIMESTAMP, - - "l2OutputOracleProposer": "PROPOSER", - "l2OutputOracleChallenger": "ADMIN", - - "finalizationPeriodSeconds": 12, - - "proxyAdminOwner": "ADMIN", - "baseFeeVaultRecipient": "ADMIN", - "l1FeeVaultRecipient": "ADMIN", - "sequencerFeeVaultRecipient": "ADMIN", - - "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", - "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", - "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", - "baseFeeVaultWithdrawalNetwork": 0, - "l1FeeVaultWithdrawalNetwork": 0, - "sequencerFeeVaultWithdrawalNetwork": 0, - - "gasPriceOracleOverhead": 2100, - "gasPriceOracleScalar": 1000000, - - "enableGovernance": true, - "governanceTokenSymbol": "OP", - "governanceTokenName": "Optimism", - "governanceTokenOwner": "ADMIN", - - "l2GenesisBlockGasLimit": "0x1c9c380", - "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", - "l2GenesisRegolithTimeOffset": "0x0", - - "eip1559Denominator": 50, - "eip1559DenominatorCanyon": 250, - "eip1559Elasticity": 10, - - "systemConfigStartBlock": 0, - - "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", - "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" -} diff --git a/packages/contracts-bedrock/deploy-config/goerli.json b/packages/contracts-bedrock/deploy-config/goerli.json index 5c084b4fd36c..2084f742c403 100644 --- a/packages/contracts-bedrock/deploy-config/goerli.json +++ b/packages/contracts-bedrock/deploy-config/goerli.json @@ -1,6 +1,6 @@ { "finalSystemOwner": "0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f", - "portalGuardian": "0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f", + "superchainConfigGuardian": "0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f", "l1StartingBlockTag": "0x6ffc1bf3754c01f6bb9fe057c1578b87a8571ce2e9be5ca14bace6eccfd336c7", "l1ChainID": 5, "l2ChainID": 420, @@ -40,6 +40,20 @@ "eip1559DenominatorCanyon": 250, "eip1559Elasticity": 10, "systemConfigStartBlock": 8300214, - "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", - "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" + "requiredProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000000", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000000", + "fundDevAccounts": false, + "faultGameAbsolutePrestate": "0x03e1255457128b9afd9acf93239c1d477bdff88624901f9ca8fe0783b756dbe0", + "faultGameMaxDepth": 73, + "faultGameMaxDuration": 604800, + "faultGameGenesisBlock": 4061224, + "faultGameGenesisOutputRoot": "0xd08055c58b2c5149565c636b44fad2c25b5ccddef1385a2cb721529d7480b242", + "faultGameSplitDepth": 32, + "faultGameWithdrawalDelay": 604800, + "preimageOracleMinProposalSize": 1800000, + "preimageOracleChallengePeriod": 86400, + "proofMaturityDelaySeconds": 604800, + "disputeGameFinalityDelaySeconds": 302400, + "respectedGameType": 0, + "useFaultProofs": true } diff --git a/packages/contracts-bedrock/deploy-config/hardhat.json b/packages/contracts-bedrock/deploy-config/hardhat.json index 3a59eb60ccb8..aa9cc17b9448 100644 --- a/packages/contracts-bedrock/deploy-config/hardhat.json +++ b/packages/contracts-bedrock/deploy-config/hardhat.json @@ -1,12 +1,12 @@ { "finalSystemOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", - "portalGuardian": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + "superchainConfigGuardian": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", "proxyAdminOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", "l1StartingBlockTag": "earliest", "l1ChainID": 900, "l2ChainID": 901, - "l2BlockTime": 1, - "l1BlockTime": 2, + "l2BlockTime": 2, + "l1BlockTime": 12, "maxSequencerDrift": 300, "sequencerWindowSize": 15, "channelTimeout": 40, @@ -14,8 +14,8 @@ "batchInboxAddress": "0xff00000000000000000000000000000000000000", "batchSenderAddress": "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", "l2OutputOracleSubmissionInterval": 6, - "l2OutputOracleStartingTimestamp": 0, - "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleStartingTimestamp": 1, + "l2OutputOracleStartingBlockNumber": 1, "gasPriceOracleOverhead": 2100, "gasPriceOracleScalar": 1000000, "l2OutputOracleProposer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", @@ -35,12 +35,31 @@ "governanceTokenName": "Optimism", "governanceTokenSymbol": "OP", "governanceTokenOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", - "finalizationPeriodSeconds": 2, + "finalizationPeriodSeconds": 36, "eip1559Denominator": 50, "eip1559DenominatorCanyon": 250, "eip1559Elasticity": 10, "l2GenesisRegolithTimeOffset": "0x0", "systemConfigStartBlock": 0, "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", - "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameAbsolutePrestate": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameMaxDepth": 8, + "faultGameMaxDuration": 2400, + "faultGameGenesisBlock": 0, + "faultGameGenesisOutputRoot": "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + "faultGameSplitDepth": 4, + "faultGameWithdrawalDelay": 604800, + "preimageOracleMinProposalSize": 10000, + "preimageOracleChallengePeriod": 120, + "proofMaturityDelaySeconds": 12, + "disputeGameFinalityDelaySeconds": 6, + "respectedGameType": 0, + "useFaultProofs": false, + "fundDevAccounts": false, + "usePlasma": false, + "daChallengeWindow": 100, + "daResolveWindow": 100, + "daBondSize": 1000, + "daResolverRefundPercentage": 50 } diff --git a/packages/contracts-bedrock/deploy-config/internal-devnet.json b/packages/contracts-bedrock/deploy-config/internal-devnet.json index 37b17b9fd72a..3dfca2607983 100644 --- a/packages/contracts-bedrock/deploy-config/internal-devnet.json +++ b/packages/contracts-bedrock/deploy-config/internal-devnet.json @@ -1,6 +1,6 @@ { "finalSystemOwner": "0x858F0751ef8B4067f0d2668C076BDB50a8549fbF", - "portalGuardian": "0x858F0751ef8B4067f0d2668C076BDB50a8549fbF", + "superchainConfigGuardian": "0x858F0751ef8B4067f0d2668C076BDB50a8549fbF", "l1StartingBlockTag": "0x19c7e6b18fe156e45f4cfef707294fd8f079fa9c30a7b7cd6ec1ce3682ec6a2e", "l1ChainID": 5, "l2ChainID": 998, diff --git a/packages/contracts-bedrock/deploy-config/mainnet.json b/packages/contracts-bedrock/deploy-config/mainnet.json index 5f956d632620..a6be1d7cf9ec 100644 --- a/packages/contracts-bedrock/deploy-config/mainnet.json +++ b/packages/contracts-bedrock/deploy-config/mainnet.json @@ -1,6 +1,6 @@ { "finalSystemOwner": "0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A", - "portalGuardian": "0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A", + "superchainConfigGuardian": "0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A", "l1StartingBlockTag": "0x438335a20d98863a4c0c97999eb2481921ccd28553eac6f913af7c12aec04108", "l1ChainID": 1, "l2ChainID": 10, diff --git a/packages/contracts-bedrock/deploy-config/pgn-sepolia.json b/packages/contracts-bedrock/deploy-config/pgn-sepolia.json index b404270bfe59..eda4eadfcd69 100644 --- a/packages/contracts-bedrock/deploy-config/pgn-sepolia.json +++ b/packages/contracts-bedrock/deploy-config/pgn-sepolia.json @@ -20,9 +20,9 @@ "batchInboxAddress": "0x454A2A86132C937AD4eFc8721f1b85418f92cbCe", "batchSenderAddress": "0x7224e05E6cF6E07aFBE1eFa09a3fA23A637DD485", "l2GenesisRegolithTimeOffset": "0x0", - "portalGuardian": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7", + "superchainConfigGuardian": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7", "l2OutputOracleSubmissionInterval": 180, - "l2OutputOracleStartingTimestamp": -1, + "l2OutputOracleStartingTimestamp": 1685727972, "l2OutputOracleProposer": "0xD457799C5ba870D609f21048c67a9b11aC611BF0", "l2GenesisBlockGasLimit": "0x1c9c380", "fundDevAccounts": false, @@ -34,5 +34,12 @@ "l2OutputOracleChallenger": "0x69F0FFc19504B57e9AE4B6D7694d028c3CD876F8", "baseFeeVaultWithdrawalNetwork": 0, "l1FeeVaultWithdrawalNetwork": 0, - "sequencerFeeVaultWithdrawalNetwork": 0 + "sequencerFeeVaultWithdrawalNetwork": 0, + "l2OutputOracleStartingBlockNumber": 0, + "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "systemConfigStartBlock": 0, + "requiredProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000001", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000001" } diff --git a/packages/contracts-bedrock/deploy-config/pgn.json b/packages/contracts-bedrock/deploy-config/pgn.json index 6f94b1c0ef8b..c333e3d84613 100644 --- a/packages/contracts-bedrock/deploy-config/pgn.json +++ b/packages/contracts-bedrock/deploy-config/pgn.json @@ -19,7 +19,7 @@ "batchInboxAddress": "0xC1B90E1e459aBBDcEc4DCF90dA45ba077d83BFc5", "batchSenderAddress": "0x99526b0e49A95833E734EB556A6aBaFFAb0Ee167", "l2GenesisRegolithTimeOffset": "0x0", - "portalGuardian": "0x39E13D1AB040F6EA58CE19998edCe01B3C365f84", + "superchainConfigGuardian": "0x39E13D1AB040F6EA58CE19998edCe01B3C365f84", "l2OutputOracleSubmissionInterval": 1800, "l2OutputOracleStartingTimestamp": -1, "l2OutputOracleProposer": "0x69968Ce0E92d9c101BAd81de55EFbcb69603cFe3", diff --git a/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json b/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json new file mode 100644 index 000000000000..7110b3ed3bbf --- /dev/null +++ b/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json @@ -0,0 +1,87 @@ +{ + "l1StartingBlockTag": "0x5639be97000fec7131a880b19b664cae43f975c773f628a08a9bb658c2a68df0", + "l1ChainID": 11155111, + "l2ChainID": 11155421, + "l2BlockTime": 2, + "finalizationPeriodSeconds": 12, + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0xa95b83e39aa78b00f12fe431865b563793d97af5", + "batchInboxAddress": "0xff00000000000000000000000000000011155421", + "batchSenderAddress": "0x19cc7073150d9f5888f09e0e9016d2a39667df14", + "l2OutputOracleSubmissionInterval": 120, + "l2OutputOracleStartingTimestamp": 1706484048, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleProposer": "0x95014c45078354ff839f14192228108eac82e00a", + "l2OutputOracleChallenger": "0x8c20c40180751d93e939dddee3517ae0d1ebead2", + "cliqueSignerAddress": "0x0000000000000000000000000000000000000000", + "l1UseClique": false, + "l1BlockTime": 12, + "l1GenesisBlockTimestamp": "0x0", + "l1GenesisBlockNonce": "0x0", + "l1GenesisBlockGasLimit": "0x0", + "l1GenesisBlockDifficulty": null, + "l1GenesisBlockMixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "l1GenesisBlockCoinbase": "0x0000000000000000000000000000000000000000", + "l1GenesisBlockNumber": "0x0", + "l1GenesisBlockGasUsed": "0x0", + "l1GenesisBlockParentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "l1GenesisBlockBaseFeePerGas": null, + "l2GenesisBlockNonce": "0x0", + "l2GenesisBlockGasLimit": "0x1c9c380", + "l2GenesisBlockDifficulty": null, + "l2GenesisBlockMixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "l2GenesisBlockNumber": "0x0", + "l2GenesisBlockGasUsed": "0x0", + "l2GenesisBlockParentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "l2GenesisRegolithTimeOffset": "0x0", + "l2GenesisCanyonTimeOffset": "0x0", + "l2GenesisDeltaTimeOffset": "0x0", + "l2GenesisBlockExtraData": null, + "proxyAdminOwner": "0x8c20c40180751d93e939dddee3517ae0d1ebead2", + "finalSystemOwner": "0x8c20c40180751d93e939dddee3517ae0d1ebead2", + "superchainConfigGuardian": "0x8c20c40180751d93e939dddee3517ae0d1ebead2", + "baseFeeVaultRecipient": "0x8c20c40180751d93e939dddee3517ae0d1ebead2", + "l1FeeVaultRecipient": "0x8c20c40180751d93e939dddee3517ae0d1ebead2", + "sequencerFeeVaultRecipient": "0x8c20c40180751d93e939dddee3517ae0d1ebead2", + "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "baseFeeVaultWithdrawalNetwork": 1, + "l1FeeVaultWithdrawalNetwork": 1, + "sequencerFeeVaultWithdrawalNetwork": 1, + "l1StandardBridgeProxy": "0x0000000000000000000000000000000000000000", + "l1CrossDomainMessengerProxy": "0x0000000000000000000000000000000000000000", + "l1ERC721BridgeProxy": "0x0000000000000000000000000000000000000000", + "systemConfigProxy": "0x0000000000000000000000000000000000000000", + "optimismPortalProxy": "0x0000000000000000000000000000000000000000", + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "enableGovernance": true, + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "governanceTokenOwner": "0x8c20c40180751d93e939dddee3517ae0d1ebead2", + "deploymentWaitConfirmations": 0, + "eip1559Elasticity": 6, + "eip1559Denominator": 250, + "eip1559DenominatorCanyon": 250, + "systemConfigStartBlock": 4071248, + "faultGameAbsolutePrestate": "0x031e3b504740d0b1264e8cf72b6dde0d497184cfb3f98e451c6be8b33bd3f808", + "faultGameMaxDepth": 73, + "faultGameMaxDuration": 604800, + "faultGameGenesisBlock": 0, + "faultGameGenesisOutputRoot": "0x91bd00ecd596a86c9f4e12c0646578e77022881c87c06ec6aa31e656d2730688", + "faultGameSplitDepth": 30, + "faultGameWithdrawalDelay": 604800, + "preimageOracleMinProposalSize": 126000, + "preimageOracleChallengePeriod": 86400, + "proofMaturityDelaySeconds": 604800, + "disputeGameFinalityDelaySeconds": 302400, + "respectedGameType": 0, + "useFaultProofs": true, + "fundDevAccounts": false, + "requiredProtocolVersion": "0x0000000000000000000000000000000000000005000000000000000000000000", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000005000000000000000000000000" +} diff --git a/packages/contracts-bedrock/deploy-config/sepolia.json b/packages/contracts-bedrock/deploy-config/sepolia.json index 642b167af9d8..50ca9de37ce2 100644 --- a/packages/contracts-bedrock/deploy-config/sepolia.json +++ b/packages/contracts-bedrock/deploy-config/sepolia.json @@ -1,6 +1,6 @@ { "finalSystemOwner": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", - "portalGuardian": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", + "superchainConfigGuardian": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", "l1StartingBlockTag": "0x48f520cf4ddaf34c8336e6e490632ea3cf1e5e93b0b2bc6e917557e31845371b", "l1ChainID": 11155111, "l2ChainID": 11155420, @@ -14,7 +14,7 @@ "batchSenderAddress": "0x8F23BB38F531600e5d8FDDaAEC41F13FaB46E98c", "l2OutputOracleSubmissionInterval": 120, "l2OutputOracleStartingBlockNumber": 0, - "l2OutputOracleStartingTimestamp": -1, + "l2OutputOracleStartingTimestamp": 1690493568, "l2OutputOracleProposer": "0x49277EE36A024120Ee218127354c4a3591dc90A9", "l2OutputOracleChallenger": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", "finalizationPeriodSeconds": 12, @@ -39,7 +39,21 @@ "eip1559Denominator": 50, "eip1559Elasticity": 6, "l2GenesisRegolithTimeOffset": "0x0", - "systemConfigStartBlock": 0, - "requiredProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000001", - "recommendedProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000001" + "systemConfigStartBlock": 4071248, + "requiredProtocolVersion": "0x0000000000000000000000000000000000000004000000000000000000000001", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000004000000000000000000000001", + "fundDevAccounts": false, + "faultGameAbsolutePrestate": "0x031e3b504740d0b1264e8cf72b6dde0d497184cfb3f98e451c6be8b33bd3f808", + "faultGameMaxDepth": 73, + "faultGameMaxDuration": 604800, + "faultGameGenesisBlock": 9496192, + "faultGameGenesisOutputRoot": "0x63b1cda487c072b020a57c1203f7c2921754005cadbd54bed7f558111b8278d8", + "faultGameSplitDepth": 30, + "faultGameWithdrawalDelay": 604800, + "preimageOracleMinProposalSize": 126000, + "preimageOracleChallengePeriod": 86400, + "proofMaturityDelaySeconds": 604800, + "disputeGameFinalityDelaySeconds": 302400, + "respectedGameType": 0, + "useFaultProofs": true } diff --git a/packages/contracts-bedrock/deploy-config/zora-goerli.json b/packages/contracts-bedrock/deploy-config/zora-goerli.json index 280d63f17726..7fab9eb144e1 100644 --- a/packages/contracts-bedrock/deploy-config/zora-goerli.json +++ b/packages/contracts-bedrock/deploy-config/zora-goerli.json @@ -20,7 +20,7 @@ "batchInboxAddress": "0xcF628E24aC574866D3d0a7CFE4e9DA7278b7ef13", "batchSenderAddress": "0x427c9a666d3b27873111cE3894712Bf64C6343A0", "l2GenesisRegolithTimeOffset": "0x0", - "portalGuardian": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7", + "superchainConfigGuardian": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7", "l2OutputOracleSubmissionInterval": 180, "l2OutputOracleStartingTimestamp": 0, "l2OutputOracleProposer": "0xa98B585654fC03E2fEa3FAB56E1C851E4f5c2B54", diff --git a/packages/contracts-bedrock/deploy-config/zora-sepolia.json b/packages/contracts-bedrock/deploy-config/zora-sepolia.json new file mode 100644 index 000000000000..18faf423d185 --- /dev/null +++ b/packages/contracts-bedrock/deploy-config/zora-sepolia.json @@ -0,0 +1,47 @@ +{ + "l1StartingBlockTag": "0xf782446a2487d900addb5d466a8597c7c543b59fa9aaa154d413830238f8798a", + "l1ChainID": 11155111, + "l2ChainID": 999999999, + "l2BlockTime": 2, + "l1BlockTime": 12, + "finalizationPeriodSeconds": 604800, + "finalSystemOwner": "0x23BA22Dd7923F3a3f2495bB32a6f3c9b9CD1EC6C", + "baseFeeVaultRecipient": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7", + "l1FeeVaultRecipient": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7", + "sequencerFeeVaultRecipient": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "governanceTokenOwner": "0x23BA22Dd7923F3a3f2495bB32a6f3c9b9CD1EC6C", + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0x3609513933100689bd1f84782529A99239842344", + "sequencerFeeVaultRecipient": "0xCb4Ba05b7f1F66B0F19Ae26561F6a3694a95768a", + "batchInboxAddress": "0xCd734290E4bd0200dAC631c7D4b9E8a33234e91f", + "batchSenderAddress": "0x3Cd868E221A3be64B161D596A7482257a99D857f", + "l2GenesisRegolithTimeOffset": "0x0", + "superchainConfigGuardian": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7", + "l2OutputOracleSubmissionInterval": 180, + "l2OutputOracleStartingTimestamp": 1698080004, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleProposer": "0xe8326a5839175dE7f467e66D8bB443aa70DA1c3e", + "sequencerFeeVaultWithdrawalNetwork": 0, + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l2GenesisBlockGasLimit": "0x1c9c380", + "fundDevAccounts": false, + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "eip1559Denominator": 50, + "eip1559Elasticity": 6, + "proxyAdminOwner": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7", + "baseFeeVaultRecipient": "0xba6fAD507A432402C64444Ed201025e060b34faB", + "l1FeeVaultRecipient": "0x91EFd7d4c6a2A04Ca59a05a4B8E07207D31a6589", + "l2OutputOracleChallenger": "0x45eFFbD799Ab49122eeEAB75B78D9C56A187F9A7", + "requiredProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000001", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000001" +} diff --git a/packages/contracts-bedrock/deploy-config/zora.json b/packages/contracts-bedrock/deploy-config/zora.json index a9ccd721f6c0..06aa62cb2568 100644 --- a/packages/contracts-bedrock/deploy-config/zora.json +++ b/packages/contracts-bedrock/deploy-config/zora.json @@ -19,7 +19,7 @@ "batchInboxAddress": "0x6F54Ca6F6EdE96662024Ffd61BFd18f3f4e34DFf", "batchSenderAddress": "0x625726c858dBF78c0125436C943Bf4b4bE9d9033", "l2GenesisRegolithTimeOffset": "0x0", - "portalGuardian": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542", + "superchainConfigGuardian": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542", "l2OutputOracleSubmissionInterval": 1800, "l2OutputOracleStartingTimestamp": -1, "l2OutputOracleProposer": "0x48247032092e7b0ecf5dEF611ad89eaf3fC888Dd", diff --git a/packages/contracts-bedrock/deployments/.gitinclude b/packages/contracts-bedrock/deployments/.gitinclude new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/contracts-bedrock/deployments/4202/.chainId b/packages/contracts-bedrock/deployments/4202/.chainId new file mode 100644 index 000000000000..edfd6052cc76 --- /dev/null +++ b/packages/contracts-bedrock/deployments/4202/.chainId @@ -0,0 +1 @@ +4202 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/.chainId b/packages/contracts-bedrock/deployments/goerli/.chainId deleted file mode 100644 index 7813681f5b41..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/.chainId +++ /dev/null @@ -1 +0,0 @@ -5 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/AddressManager.json b/packages/contracts-bedrock/deployments/goerli/AddressManager.json deleted file mode 100644 index b8a050ae83e7..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/AddressManager.json +++ /dev/null @@ -1,237 +0,0 @@ -{ - "address": "0xa6f73589243a6A7a9023b1Fa0651b1d89c177111", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "indexed": false, - "internalType": "address", - "name": "_newAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "_oldAddress", - "type": "address" - } - ], - "name": "AddressSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "getAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "address", - "name": "_address", - "type": "address" - } - ], - "name": "setAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0x5048d305a449374d0903384f23c112696557878bf4b1ac52e8e7530898cc03e8", - "receipt": { - "to": null, - "from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31", - "contractAddress": "0xa6f73589243a6A7a9023b1Fa0651b1d89c177111", - "transactionIndex": 6, - "gasUsed": "463444", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000001000000000000000001000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000200200000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x59b45b1099d0a874e3bbb89d53ec856f7a7ae3a98013b5be0d3ceff8172240b3", - "transactionHash": "0x5048d305a449374d0903384f23c112696557878bf4b1ac52e8e7530898cc03e8", - "logs": [ - { - "transactionIndex": 6, - "blockNumber": 7017076, - "transactionHash": "0x5048d305a449374d0903384f23c112696557878bf4b1ac52e8e7530898cc03e8", - "address": "0xa6f73589243a6A7a9023b1Fa0651b1d89c177111", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000003a605b442055df2898e18cf518feb2e2a6bd0d31" - ], - "data": "0x", - "logIndex": 103, - "blockHash": "0x59b45b1099d0a874e3bbb89d53ec856f7a7ae3a98013b5be0d3ceff8172240b3" - } - ], - "blockNumber": 7017076, - "cumulativeGasUsed": "3261100", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "5f4e2d2e170708499f05344e000df330", - "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_oldAddress\",\"type\":\"address\"}],\"name\":\"AddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getAddress(string)\":{\"params\":{\"_name\":\"Name to retrieve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setAddress(string,address)\":{\"params\":{\"_address\":\"Address to associate with the name.\",\"_name\":\"String name to associate an address with.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"Lib_AddressManager\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getAddress(string)\":{\"notice\":\"Retrieves the address associated with a given name.\"},\"setAddress(string,address)\":{\"notice\":\"Changes the address associated with a particular name.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/resolver/Lib_AddressManager.sol\":\"Lib_AddressManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6107028061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046105e4565b610184565b6100906100da366004610632565b6102d0565b6100746100ed36600461066f565b61030c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b610182600061043c565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610205576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161016f565b6000610210836104b1565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff000000000000000000000000000000000000000083161790925591519293501690610273908590610691565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006102df846104b1565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461038d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161016f565b73ffffffffffffffffffffffffffffffffffffffff8116610430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161016f565b6104398161043c565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016104c49190610691565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261052157600080fd5b813567ffffffffffffffff8082111561053c5761053c6104e1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610582576105826104e1565b8160405283815286602085880101111561059b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146105df57600080fd5b919050565b600080604083850312156105f757600080fd5b823567ffffffffffffffff81111561060e57600080fd5b61061a85828601610510565b925050610629602084016105bb565b90509250929050565b60006020828403121561064457600080fd5b813567ffffffffffffffff81111561065b57600080fd5b61066784828501610510565b949350505050565b60006020828403121561068157600080fd5b61068a826105bb565b9392505050565b6000825160005b818110156106b25760208186018101518583015201610698565b818111156106c1576000828501525b50919091019291505056fea2646970667358221220882d6a267e1fbcc015c1726b422a6847e08c6be7e987e8b5ec1f7e85aa5095bb64736f6c63430008090033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046105e4565b610184565b6100906100da366004610632565b6102d0565b6100746100ed36600461066f565b61030c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b610182600061043c565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610205576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161016f565b6000610210836104b1565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff000000000000000000000000000000000000000083161790925591519293501690610273908590610691565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006102df846104b1565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461038d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161016f565b73ffffffffffffffffffffffffffffffffffffffff8116610430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161016f565b6104398161043c565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016104c49190610691565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261052157600080fd5b813567ffffffffffffffff8082111561053c5761053c6104e1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610582576105826104e1565b8160405283815286602085880101111561059b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146105df57600080fd5b919050565b600080604083850312156105f757600080fd5b823567ffffffffffffffff81111561060e57600080fd5b61061a85828601610510565b925050610629602084016105bb565b90509250929050565b60006020828403121561064457600080fd5b813567ffffffffffffffff81111561065b57600080fd5b61066784828501610510565b949350505050565b60006020828403121561068157600080fd5b61068a826105bb565b9392505050565b6000825160005b818110156106b25760208186018101518583015201610698565b818111156106c1576000828501525b50919091019291505056fea2646970667358221220882d6a267e1fbcc015c1726b422a6847e08c6be7e987e8b5ec1f7e85aa5095bb64736f6c63430008090033", - "devdoc": { - "kind": "dev", - "methods": { - "getAddress(string)": { - "params": { - "_name": "Name to retrieve an address for." - }, - "returns": { - "_0": "Address associated with the given name." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "setAddress(string,address)": { - "params": { - "_address": "Address to associate with the name.", - "_name": "String name to associate an address with." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - } - }, - "title": "Lib_AddressManager", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "getAddress(string)": { - "notice": "Retrieves the address associated with a given name." - }, - "setAddress(string,address)": { - "notice": "Changes the address associated with a particular name." - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 393, - "contract": "contracts/libraries/resolver/Lib_AddressManager.sol:Lib_AddressManager", - "label": "_owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 7017, - "contract": "contracts/libraries/resolver/Lib_AddressManager.sol:Lib_AddressManager", - "label": "addresses", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_bytes32,t_address)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes32,t_address)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => address)", - "numberOfBytes": "32", - "value": "t_address" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/CheckBalanceHigh.json b/packages/contracts-bedrock/deployments/goerli/CheckBalanceHigh.json deleted file mode 100644 index 2ca0130add0c..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/CheckBalanceHigh.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "address": "0x7eC64a8a591bFf829ff6C8be76074D540ACb813F", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct CheckBalanceHigh.Params", - "name": "params", - "type": "tuple" - } - ], - "name": "_EventToExposeStructInABI__Params", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x1d1543b42c1a5404d3b1794a399239d1e3f40c10e865d0f2e4a362a349d30a6e", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 76, - "gasUsed": "176628", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x0b10b7612a1de5326e045069eb60151e2fa615ce7d342b13acb14ba165edddb1", - "transactionHash": "0x1d1543b42c1a5404d3b1794a399239d1e3f40c10e865d0f2e4a362a349d30a6e", - "logs": [], - "blockNumber": 8182666, - "cumulativeGasUsed": "10050194", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988", - "metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct CheckBalanceHigh.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"params\":{\"params\":\"Parameters to encode.\"}}},\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckBalanceHigh\",\"version\":1},\"userdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"notice\":\"External event used to help client-side tooling encode parameters.\"}},\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck for checking if an account's balance is above a given threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol\":\"CheckBalanceHigh\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckBalanceHigh\\n * @notice DripCheck for checking if an account's balance is above a given threshold.\\n */\\ncontract CheckBalanceHigh is IDripCheck {\\n struct Params {\\n address target;\\n uint256 threshold;\\n }\\n\\n /**\\n * @notice External event used to help client-side tooling encode parameters.\\n *\\n * @param params Parameters to encode.\\n */\\n event _EventToExposeStructInABI__Params(Params params);\\n\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check target balance is above threshold.\\n return params.target.balance > params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0xcb27d9e50a7c32406872b8fdc4ca62ee0d27372eb9077657f6d16f3cd3b58c85\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610239806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631119392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea26469706673582212203818d112b628fa60d8cffe88e7198c860e268b9375b8b118dacdbf531c397ef864736f6c63430008100033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631119392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea26469706673582212203818d112b628fa60d8cffe88e7198c860e268b9375b8b118dacdbf531c397ef864736f6c63430008100033", - "devdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256))": { - "params": { - "params": "Parameters to encode." - } - } - }, - "kind": "dev", - "methods": { - "check(bytes)": { - "params": { - "_params": "Encoded parameters for the drip check." - }, - "returns": { - "_0": "Whether the drip should be executed." - } - } - }, - "title": "CheckBalanceHigh", - "version": 1 - }, - "userdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256))": { - "notice": "External event used to help client-side tooling encode parameters." - } - }, - "kind": "user", - "methods": { - "check(bytes)": { - "notice": "Checks whether a drip should be executable." - } - }, - "notice": "DripCheck for checking if an account's balance is above a given threshold.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/CheckBalanceLow.json b/packages/contracts-bedrock/deployments/goerli/CheckBalanceLow.json deleted file mode 100644 index 35655ec4fb04..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/CheckBalanceLow.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "address": "0x381a4eFC2A2C914eA1889722bB4B44Fa6BD5b640", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct CheckBalanceLow.Params", - "name": "params", - "type": "tuple" - } - ], - "name": "_EventToExposeStructInABI__Params", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x27c46f8d4f3a93eb7388ebd9be8b8c4628a30de6b358f721e810e9c881a279e5", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 67, - "gasUsed": "176640", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4a6c891cb4fae11711c0494dae3ec8e90c64b1ff33e424de9db865098471e10d", - "transactionHash": "0x27c46f8d4f3a93eb7388ebd9be8b8c4628a30de6b358f721e810e9c881a279e5", - "logs": [], - "blockNumber": 8182667, - "cumulativeGasUsed": "14037277", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988", - "metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct CheckBalanceLow.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"params\":{\"params\":\"Parameters to encode.\"}}},\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckBalanceLow\",\"version\":1},\"userdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"notice\":\"External event used to help client-side tooling encode parameters.\"}},\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck for checking if an account's balance is below a given threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol\":\"CheckBalanceLow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckBalanceLow\\n * @notice DripCheck for checking if an account's balance is below a given threshold.\\n */\\ncontract CheckBalanceLow is IDripCheck {\\n struct Params {\\n address target;\\n uint256 threshold;\\n }\\n\\n /**\\n * @notice External event used to help client-side tooling encode parameters.\\n *\\n * @param params Parameters to encode.\\n */\\n event _EventToExposeStructInABI__Params(Params params);\\n\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check target ETH balance is below threshold.\\n return params.target.balance < params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0x6a1187a80093770931296d3360b1ecc7d17f69157fe88f628989b257548b564b\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610239806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea2646970667358221220cc86d01120737597addcccffd841244801dcb64ce402d73b8d8569a52348996464736f6c63430008100033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea2646970667358221220cc86d01120737597addcccffd841244801dcb64ce402d73b8d8569a52348996464736f6c63430008100033", - "devdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256))": { - "params": { - "params": "Parameters to encode." - } - } - }, - "kind": "dev", - "methods": { - "check(bytes)": { - "params": { - "_params": "Encoded parameters for the drip check." - }, - "returns": { - "_0": "Whether the drip should be executed." - } - } - }, - "title": "CheckBalanceLow", - "version": 1 - }, - "userdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256))": { - "notice": "External event used to help client-side tooling encode parameters." - } - }, - "kind": "user", - "methods": { - "check(bytes)": { - "notice": "Checks whether a drip should be executable." - } - }, - "notice": "DripCheck for checking if an account's balance is below a given threshold.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/CheckGelatoLow.json b/packages/contracts-bedrock/deployments/goerli/CheckGelatoLow.json deleted file mode 100644 index bef8d12d042b..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/CheckGelatoLow.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "address": "0x4f7CFc43f6D262a085F3b946cAC69E7a8E39BBAa", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "treasury", - "type": "address" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - } - ], - "indexed": false, - "internalType": "struct CheckGelatoLow.Params", - "name": "params", - "type": "tuple" - } - ], - "name": "_EventToExposeStructInABI__Params", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x6426a895e674bb8849028c089ed41d1b9179d8392adc9ad6d225cd53c53fe49c", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 61, - "gasUsed": "222032", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4b8ed6e59a8559084820c6f9514b9ddec7de519cbf6940131b43f939c63c4307", - "transactionHash": "0x6426a895e674bb8849028c089ed41d1b9179d8392adc9ad6d225cd53c53fe49c", - "logs": [], - "blockNumber": 8182670, - "cumulativeGasUsed": "12472395", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988", - "metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"treasury\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct CheckGelatoLow.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256,address))\":{\"params\":{\"params\":\"Parameters to encode.\"}}},\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckGelatoLow\",\"version\":1},\"userdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256,address))\":{\"notice\":\"External event used to help client-side tooling encode parameters.\"}},\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck for checking if an account's Gelato ETH balance is below some threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol\":\"CheckGelatoLow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\ninterface IGelatoTreasury {\\n function userTokenBalance(address _user, address _token) external view returns (uint256);\\n}\\n\\n/**\\n * @title CheckGelatoLow\\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\\n */\\ncontract CheckGelatoLow is IDripCheck {\\n struct Params {\\n address treasury;\\n uint256 threshold;\\n address recipient;\\n }\\n\\n /**\\n * @notice External event used to help client-side tooling encode parameters.\\n *\\n * @param params Parameters to encode.\\n */\\n event _EventToExposeStructInABI__Params(Params params);\\n\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check GelatoTreasury ETH balance is below threshold.\\n return\\n IGelatoTreasury(params.treasury).userTokenBalance(\\n params.recipient,\\n // Gelato represents ETH as 0xeeeee....eeeee\\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\\n ) < params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0x1a127a2c8955525cc2e5cd3c6703edc785c662a79222f524df4574cf47ddd864\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061030c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e366004610160565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610258565b6020810151815160408084015190517fb47064c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6024820152939450919291169063b47064c890604401602060405180830381865afa158015610105573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012991906102bd565b109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561017257600080fd5b813567ffffffffffffffff8082111561018a57600080fd5b818401915084601f83011261019e57600080fd5b8135818111156101b0576101b0610131565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f6576101f6610131565b8160405282815287602084870101111561020f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b805173ffffffffffffffffffffffffffffffffffffffff8116811461025357600080fd5b919050565b60006060828403121561026a57600080fd5b6040516060810181811067ffffffffffffffff8211171561028d5761028d610131565b6040526102998361022f565b8152602083015160208201526102b16040840161022f565b60408201529392505050565b6000602082840312156102cf57600080fd5b505191905056fea2646970667358221220d5d7b760af134f89109f20dbf88fd89e78bb4b81bed97f9aa45772b3775b388964736f6c63430008100033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e366004610160565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610258565b6020810151815160408084015190517fb47064c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6024820152939450919291169063b47064c890604401602060405180830381865afa158015610105573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012991906102bd565b109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561017257600080fd5b813567ffffffffffffffff8082111561018a57600080fd5b818401915084601f83011261019e57600080fd5b8135818111156101b0576101b0610131565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f6576101f6610131565b8160405282815287602084870101111561020f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b805173ffffffffffffffffffffffffffffffffffffffff8116811461025357600080fd5b919050565b60006060828403121561026a57600080fd5b6040516060810181811067ffffffffffffffff8211171561028d5761028d610131565b6040526102998361022f565b8152602083015160208201526102b16040840161022f565b60408201529392505050565b6000602082840312156102cf57600080fd5b505191905056fea2646970667358221220d5d7b760af134f89109f20dbf88fd89e78bb4b81bed97f9aa45772b3775b388964736f6c63430008100033", - "devdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256,address))": { - "params": { - "params": "Parameters to encode." - } - } - }, - "kind": "dev", - "methods": { - "check(bytes)": { - "params": { - "_params": "Encoded parameters for the drip check." - }, - "returns": { - "_0": "Whether the drip should be executed." - } - } - }, - "title": "CheckGelatoLow", - "version": 1 - }, - "userdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256,address))": { - "notice": "External event used to help client-side tooling encode parameters." - } - }, - "kind": "user", - "methods": { - "check(bytes)": { - "notice": "Checks whether a drip should be executable." - } - }, - "notice": "DripCheck for checking if an account's Gelato ETH balance is below some threshold.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/CheckTrue.json b/packages/contracts-bedrock/deployments/goerli/CheckTrue.json deleted file mode 100644 index 89a088d39722..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/CheckTrue.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "address": "0x5c741a38cb11424711231777D71689C458eE835D", - "abi": [ - { - "inputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "pure", - "type": "function" - } - ], - "transactionHash": "0xeacb73acd8f3d741e1a4a136e95cec43d21aef36b95611cdaa86c87066bfd087", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 81, - "gasUsed": "139230", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x396e72234d59683880032c4c9e6fd61a46b839b61c644c7bd180e02d565c3b14", - "transactionHash": "0xeacb73acd8f3d741e1a4a136e95cec43d21aef36b95611cdaa86c87066bfd087", - "logs": [], - "blockNumber": 8182671, - "cumulativeGasUsed": "17047212", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988", - "metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckTrue\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck that always returns true.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckTrue.sol\":\"CheckTrue\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckTrue.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckTrue\\n * @notice DripCheck that always returns true.\\n */\\ncontract CheckTrue is IDripCheck {\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory) external pure returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xf2f5474f12983c30ca4fe9d19e7f88e6d2262e4a6f779e86b4a2117498fdbea5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061018c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004461003e366004610087565b50600190565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561009957600080fd5b813567ffffffffffffffff808211156100b157600080fd5b818401915084601f8301126100c557600080fd5b8135818111156100d7576100d7610058565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561011d5761011d610058565b8160405282815287602084870101111561013657600080fd5b82602086016020830137600092810160200192909252509594505050505056fea26469706673582212200bb899cb0e5f9dce180ebe72a1dfade46ffc5ec3cab398d1f2af09e8b9ce76d164736f6c63430008100033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004461003e366004610087565b50600190565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561009957600080fd5b813567ffffffffffffffff808211156100b157600080fd5b818401915084601f8301126100c557600080fd5b8135818111156100d7576100d7610058565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561011d5761011d610058565b8160405282815287602084870101111561013657600080fd5b82602086016020830137600092810160200192909252509594505050505056fea26469706673582212200bb899cb0e5f9dce180ebe72a1dfade46ffc5ec3cab398d1f2af09e8b9ce76d164736f6c63430008100033", - "devdoc": { - "kind": "dev", - "methods": { - "check(bytes)": { - "params": { - "_params": "Encoded parameters for the drip check." - }, - "returns": { - "_0": "Whether the drip should be executed." - } - } - }, - "title": "CheckTrue", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "check(bytes)": { - "notice": "Checks whether a drip should be executable." - } - }, - "notice": "DripCheck that always returns true.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/Drippie.json b/packages/contracts-bedrock/deployments/goerli/Drippie.json deleted file mode 100644 index f4d72fe6deed..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/Drippie.json +++ /dev/null @@ -1,1054 +0,0 @@ -{ - "address": "0x44b3A2a040057eBafC601A78647e805fd58B1f50", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "nameref", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "components": [ - { - "internalType": "bool", - "name": "reentrant", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "interval", - "type": "uint256" - }, - { - "internalType": "contract IDripCheck", - "name": "dripcheck", - "type": "address" - }, - { - "internalType": "bytes", - "name": "checkparams", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "address payable", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct Drippie.DripAction[]", - "name": "actions", - "type": "tuple[]" - } - ], - "indexed": false, - "internalType": "struct Drippie.DripConfig", - "name": "config", - "type": "tuple" - } - ], - "name": "DripCreated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "nameref", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "indexed": false, - "internalType": "address", - "name": "executor", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - } - ], - "name": "DripExecuted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "nameref", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "indexed": false, - "internalType": "enum Drippie.DripStatus", - "name": "status", - "type": "uint8" - } - ], - "name": "DripStatusUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ReceivedETH", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewERC20", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "WithdrewERC721", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewETH", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "CALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "DELEGATECALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "components": [ - { - "internalType": "bool", - "name": "reentrant", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "interval", - "type": "uint256" - }, - { - "internalType": "contract IDripCheck", - "name": "dripcheck", - "type": "address" - }, - { - "internalType": "bytes", - "name": "checkparams", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "address payable", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct Drippie.DripAction[]", - "name": "actions", - "type": "tuple[]" - } - ], - "internalType": "struct Drippie.DripConfig", - "name": "_config", - "type": "tuple" - } - ], - "name": "create", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "drip", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "name": "drips", - "outputs": [ - { - "internalType": "enum Drippie.DripStatus", - "name": "status", - "type": "uint8" - }, - { - "components": [ - { - "internalType": "bool", - "name": "reentrant", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "interval", - "type": "uint256" - }, - { - "internalType": "contract IDripCheck", - "name": "dripcheck", - "type": "address" - }, - { - "internalType": "bytes", - "name": "checkparams", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "address payable", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct Drippie.DripAction[]", - "name": "actions", - "type": "tuple[]" - } - ], - "internalType": "struct Drippie.DripConfig", - "name": "config", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "last", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "count", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "executable", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "enum Drippie.DripStatus", - "name": "_status", - "type": "uint8" - } - ], - "name": "status", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC721", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_id", - "type": "uint256" - } - ], - "name": "withdrawERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x4bd4a6ab9e90105104d13049891298914961a4379c1cd25b636037d7f54e85b2", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 102, - "gasUsed": "2419585", - "logsBloom": "0x00000000000000000001000000000000000000000000000000000000000000000000100000000000000000000000080000000000000000000000000000000004000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000400000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000020000000000000000000000000000000000000000000000", - "blockHash": "0x59e68f7aa73c5c9e2c0c6bcf2eb9fdcc473be33538564b57202ef0fe89bfb61a", - "transactionHash": "0x4bd4a6ab9e90105104d13049891298914961a4379c1cd25b636037d7f54e85b2", - "logs": [ - { - "transactionIndex": 102, - "blockNumber": 8182665, - "transactionHash": "0x4bd4a6ab9e90105104d13049891298914961a4379c1cd25b636037d7f54e85b2", - "address": "0x44b3A2a040057eBafC601A78647e805fd58B1f50", - "topics": [ - "0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58" - ], - "data": "0x", - "logIndex": 274, - "blockHash": "0x59e68f7aa73c5c9e2c0c6bcf2eb9fdcc473be33538564b57202ef0fe89bfb61a" - } - ], - "blockNumber": 8182665, - "cumulativeGasUsed": "25052149", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988", - "metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"nameref\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"reentrant\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"interval\",\"type\":\"uint256\"},{\"internalType\":\"contract IDripCheck\",\"name\":\"dripcheck\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkparams\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address payable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Drippie.DripAction[]\",\"name\":\"actions\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"struct Drippie.DripConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DripCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"nameref\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"DripExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"nameref\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"enum Drippie.DripStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"DripStatusUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ReceivedETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewETH\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"CALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"DELEGATECALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"reentrant\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"interval\",\"type\":\"uint256\"},{\"internalType\":\"contract IDripCheck\",\"name\":\"dripcheck\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkparams\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address payable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Drippie.DripAction[]\",\"name\":\"actions\",\"type\":\"tuple[]\"}],\"internalType\":\"struct Drippie.DripConfig\",\"name\":\"_config\",\"type\":\"tuple\"}],\"name\":\"create\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"drip\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"name\":\"drips\",\"outputs\":[{\"internalType\":\"enum Drippie.DripStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"reentrant\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"interval\",\"type\":\"uint256\"},{\"internalType\":\"contract IDripCheck\",\"name\":\"dripcheck\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkparams\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address payable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Drippie.DripAction[]\",\"name\":\"actions\",\"type\":\"tuple[]\"}],\"internalType\":\"struct Drippie.DripConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"last\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"executable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"enum Drippie.DripStatus\",\"name\":\"_status\",\"type\":\"uint8\"}],\"name\":\"status\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC721\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"DripCreated(string,string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))\":{\"params\":{\"config\":\"Config for the created drip.\",\"name\":\"Unindexed name parameter (unhashed).\",\"nameref\":\"Indexed name parameter (hashed).\"}},\"DripExecuted(string,string,address,uint256)\":{\"params\":{\"executor\":\"Address that executed the drip.\",\"name\":\"Unindexed name parameter (unhashed).\",\"nameref\":\"Indexed name parameter (hashed).\",\"timestamp\":\"Time when the drip was executed.\"}},\"DripStatusUpdated(string,string,uint8)\":{\"params\":{\"name\":\"Unindexed name parameter (unhashed).\",\"nameref\":\"Indexed name parameter (hashed).\",\"status\":\"New drip status.\"}}},\"kind\":\"dev\",\"methods\":{\"CALL(address,bytes,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_target\":\"Address to call.\",\"_value\":\"ETH value to send with the call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"DELEGATECALL(address,bytes)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_target\":\"Address to call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"constructor\":{\"params\":{\"_owner\":\"Initial contract owner.\"}},\"create(string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))\":{\"params\":{\"_config\":\"Configuration for the drip.\",\"_name\":\"Name of the drip.\"}},\"drip(string)\":{\"params\":{\"_name\":\"Name of the drip to trigger.\"}},\"executable(string)\":{\"params\":{\"_name\":\"Drip to check.\"},\"returns\":{\"_0\":\"True if the drip is executable, reverts otherwise.\"}},\"status(string,uint8)\":{\"params\":{\"_name\":\"Name of the drip to update.\",\"_status\":\"New drip status.\"}},\"withdrawERC20(address,address)\":{\"params\":{\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC20(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount of ERC20 to withdraw.\",\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC721(address,address,uint256)\":{\"params\":{\"_asset\":\"ERC721 token to withdraw.\",\"_id\":\"Token ID of the ERC721 token to withdraw.\",\"_to\":\"Address to receive the ERC721 token.\"}},\"withdrawETH(address)\":{\"params\":{\"_to\":\"Address to receive the ETH balance.\"}},\"withdrawETH(address,uint256)\":{\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_to\":\"Address to receive the ETH balance.\"}}},\"title\":\"Drippie\",\"version\":1},\"userdoc\":{\"events\":{\"DripCreated(string,string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))\":{\"notice\":\"Emitted when a new drip is created.\"},\"DripExecuted(string,string,address,uint256)\":{\"notice\":\"Emitted when a drip is executed.\"},\"DripStatusUpdated(string,string,uint8)\":{\"notice\":\"Emitted when a drip status is updated.\"},\"ReceivedETH(address,uint256)\":{\"notice\":\"Emitted when ETH is received by this address.\"},\"WithdrewERC20(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewERC721(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewETH(address,address,uint256)\":{\"notice\":\"Emitted when ETH is withdrawn from this address.\"}},\"kind\":\"user\",\"methods\":{\"CALL(address,bytes,uint256)\":{\"notice\":\"Sends a CALL to a target address.\"},\"DELEGATECALL(address,bytes)\":{\"notice\":\"Sends a DELEGATECALL to a target address.\"},\"create(string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))\":{\"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.\"},\"drip(string)\":{\"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. Note that the drip check is executed only **once** at the beginning of the call to the drip function and will not be executed again between the drip actions within this call.\"},\"drips(string)\":{\"notice\":\"Maps from drip names to drip states.\"},\"executable(string)\":{\"notice\":\"Checks if a given drip is executable.\"},\"status(string,uint8)\":{\"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.\"},\"withdrawERC20(address,address)\":{\"notice\":\"Withdraws full ERC20 balance to the recipient.\"},\"withdrawERC20(address,address,uint256)\":{\"notice\":\"Withdraws partial ERC20 balance to the recipient.\"},\"withdrawERC721(address,address,uint256)\":{\"notice\":\"Withdraws ERC721 token to the recipient.\"},\"withdrawETH(address)\":{\"notice\":\"Withdraws full ETH balance to the recipient.\"},\"withdrawETH(address,uint256)\":{\"notice\":\"Withdraws partial ETH balance to the recipient.\"}},\"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.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/Drippie.sol\":\"Drippie\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@rari-capital/solmate/src/auth/Owned.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Simple single owner authorization mixin.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\\nabstract contract Owned {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event OwnerUpdated(address indexed user, address indexed newOwner);\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n address public owner;\\n\\n modifier onlyOwner() virtual {\\n require(msg.sender == owner, \\\"UNAUTHORIZED\\\");\\n\\n _;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(address _owner) {\\n owner = _owner;\\n\\n emit OwnerUpdated(address(0), _owner);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function setOwner(address newOwner) public virtual onlyOwner {\\n owner = newOwner;\\n\\n emit OwnerUpdated(msg.sender, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7e91c80b0dd1a14a19cb9e661b99924043adab6d9d893bbfcf3a6a3dc23a6743\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\\nabstract contract ERC20 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n uint8 public immutable decimals;\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) public balanceOf;\\n\\n mapping(address => mapping(address => uint256)) public allowance;\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 internal immutable INITIAL_CHAIN_ID;\\n\\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\\n\\n mapping(address => uint256) public nonces;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n uint8 _decimals\\n ) {\\n name = _name;\\n symbol = _symbol;\\n decimals = _decimals;\\n\\n INITIAL_CHAIN_ID = block.chainid;\\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 amount) public virtual returns (bool) {\\n allowance[msg.sender][spender] = amount;\\n\\n emit Approval(msg.sender, spender, amount);\\n\\n return true;\\n }\\n\\n function transfer(address to, uint256 amount) public virtual returns (bool) {\\n balanceOf[msg.sender] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(msg.sender, to, amount);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual returns (bool) {\\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\\n\\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\\n\\n balanceOf[from] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n return true;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(deadline >= block.timestamp, \\\"PERMIT_DEADLINE_EXPIRED\\\");\\n\\n // Unchecked because the only math done is incrementing\\n // the owner's nonce which cannot realistically overflow.\\n unchecked {\\n address recoveredAddress = ecrecover(\\n keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\",\\n DOMAIN_SEPARATOR(),\\n keccak256(\\n abi.encode(\\n keccak256(\\n \\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\"\\n ),\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n )\\n ),\\n v,\\n r,\\n s\\n );\\n\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"INVALID_SIGNER\\\");\\n\\n allowance[recoveredAddress][spender] = value;\\n }\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\\n }\\n\\n function computeDomainSeparator() internal view virtual returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name)),\\n keccak256(\\\"1\\\"),\\n block.chainid,\\n address(this)\\n )\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 amount) internal virtual {\\n totalSupply += amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(address(0), to, amount);\\n }\\n\\n function _burn(address from, uint256 amount) internal virtual {\\n balanceOf[from] -= amount;\\n\\n // Cannot underflow because a user's balance\\n // will never be larger than the total supply.\\n unchecked {\\n totalSupply -= amount;\\n }\\n\\n emit Transfer(from, address(0), amount);\\n }\\n}\\n\",\"keccak256\":\"0x43aa1509bb753f053143530705d9c4eee415691d26a4779769bf028a74e6ac69\",\"license\":\"MIT\"},\"@rari-capital/solmate/src/tokens/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\\n\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE/LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n function tokenURI(uint256 id) public view virtual returns (string memory);\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 BALANCE/OWNER STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) internal _ownerOf;\\n\\n mapping(address => uint256) internal _balanceOf;\\n\\n function ownerOf(uint256 id) public view virtual returns (address owner) {\\n require((owner = _ownerOf[id]) != address(0), \\\"NOT_MINTED\\\");\\n }\\n\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n require(owner != address(0), \\\"ZERO_ADDRESS\\\");\\n\\n return _balanceOf[owner];\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 APPROVAL STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) public getApproved;\\n\\n mapping(address => mapping(address => bool)) public isApprovedForAll;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(string memory _name, string memory _symbol) {\\n name = _name;\\n symbol = _symbol;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 id) public virtual {\\n address owner = _ownerOf[id];\\n\\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \\\"NOT_AUTHORIZED\\\");\\n\\n getApproved[id] = spender;\\n\\n emit Approval(owner, spender, id);\\n }\\n\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n isApprovedForAll[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(msg.sender, operator, approved);\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n require(from == _ownerOf[id], \\\"WRONG_FROM\\\");\\n\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(\\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\\n \\\"NOT_AUTHORIZED\\\"\\n );\\n\\n // Underflow of the sender's balance is impossible because we check for\\n // ownership above and the recipient's balance can't realistically overflow.\\n unchecked {\\n _balanceOf[from]--;\\n\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n delete getApproved[id];\\n\\n emit Transfer(from, to, id);\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n if (to.code.length != 0)\\n require(\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n bytes calldata data\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n if (to.code.length != 0)\\n require(\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC165 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return\\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 id) internal virtual {\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(_ownerOf[id] == address(0), \\\"ALREADY_MINTED\\\");\\n\\n // Counter overflow is incredibly unrealistic.\\n unchecked {\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n emit Transfer(address(0), to, id);\\n }\\n\\n function _burn(uint256 id) internal virtual {\\n address owner = _ownerOf[id];\\n\\n require(owner != address(0), \\\"NOT_MINTED\\\");\\n\\n // Ownership check above ensures no underflow.\\n unchecked {\\n _balanceOf[owner]--;\\n }\\n\\n delete _ownerOf[id];\\n\\n delete getApproved[id];\\n\\n emit Transfer(owner, address(0), id);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL SAFE MINT LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _safeMint(address to, uint256 id) internal virtual {\\n _mint(to, id);\\n\\n if (to.code.length != 0)\\n require(\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function _safeMint(\\n address to,\\n uint256 id,\\n bytes memory data\\n ) internal virtual {\\n _mint(to, id);\\n\\n if (to.code.length != 0)\\n require(\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n}\\n\\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721TokenReceiver {\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external virtual returns (bytes4) {\\n return ERC721TokenReceiver.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0xdac91feb466e74905737338d80cac5303eb7aedcbe76eda11c45eaa728451075\",\"license\":\"MIT\"},\"contracts/universal/AssetReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { ERC20 } from \\\"@rari-capital/solmate/src/tokens/ERC20.sol\\\";\\nimport { ERC721 } from \\\"@rari-capital/solmate/src/tokens/ERC721.sol\\\";\\nimport { Transactor } from \\\"./Transactor.sol\\\";\\n\\n/**\\n * @title AssetReceiver\\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\\n */\\ncontract AssetReceiver is Transactor {\\n /**\\n * @notice Emitted when ETH is received by this address.\\n *\\n * @param from Address that sent ETH to this contract.\\n * @param amount Amount of ETH received.\\n */\\n event ReceivedETH(address indexed from, uint256 amount);\\n\\n /**\\n * @notice Emitted when ETH is withdrawn from this address.\\n *\\n * @param withdrawer Address that triggered the withdrawal.\\n * @param recipient Address that received the withdrawal.\\n * @param amount ETH amount withdrawn.\\n */\\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\\n\\n /**\\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\\n *\\n * @param withdrawer Address that triggered the withdrawal.\\n * @param recipient Address that received the withdrawal.\\n * @param asset Address of the token being withdrawn.\\n * @param amount ERC20 amount withdrawn.\\n */\\n event WithdrewERC20(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 amount\\n );\\n\\n /**\\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\\n *\\n * @param withdrawer Address that triggered the withdrawal.\\n * @param recipient Address that received the withdrawal.\\n * @param asset Address of the token being withdrawn.\\n * @param id Token ID being withdrawn.\\n */\\n event WithdrewERC721(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 id\\n );\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Transactor(_owner) {}\\n\\n /**\\n * @notice Make sure we can receive ETH.\\n */\\n receive() external payable {\\n emit ReceivedETH(msg.sender, msg.value);\\n }\\n\\n /**\\n * @notice Withdraws full ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n */\\n function withdrawETH(address payable _to) external onlyOwner {\\n withdrawETH(_to, address(this).balance);\\n }\\n\\n /**\\n * @notice Withdraws partial ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n * @param _amount Amount of ETH to withdraw.\\n */\\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\\n // slither-disable-next-line reentrancy-unlimited-gas\\n (bool success, ) = _to.call{ value: _amount }(\\\"\\\");\\n emit WithdrewETH(msg.sender, _to, _amount);\\n }\\n\\n /**\\n * @notice Withdraws full ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n */\\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\\n }\\n\\n /**\\n * @notice Withdraws partial ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n * @param _amount Amount of ERC20 to withdraw.\\n */\\n function withdrawERC20(\\n ERC20 _asset,\\n address _to,\\n uint256 _amount\\n ) public onlyOwner {\\n // slither-disable-next-line unchecked-transfer\\n _asset.transfer(_to, _amount);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\\n }\\n\\n /**\\n * @notice Withdraws ERC721 token to the recipient.\\n *\\n * @param _asset ERC721 token to withdraw.\\n * @param _to Address to receive the ERC721 token.\\n * @param _id Token ID of the ERC721 token to withdraw.\\n */\\n function withdrawERC721(\\n ERC721 _asset,\\n address _to,\\n uint256 _id\\n ) external onlyOwner {\\n _asset.transferFrom(address(this), _to, _id);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\\n }\\n}\\n\",\"keccak256\":\"0x7e9bcbf8e23cb5f48e4eca605da6b7d96f88b9499e91a92cbf74d82e9e91cdf1\",\"license\":\"MIT\"},\"contracts/universal/Transactor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Owned } from \\\"@rari-capital/solmate/src/auth/Owned.sol\\\";\\n\\n/**\\n * @title Transactor\\n * @notice Transactor is a minimal contract that can send transactions.\\n */\\ncontract Transactor is Owned {\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Owned(_owner) {}\\n\\n /**\\n * Sends a CALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _value ETH value to send with the call.\\n *\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function CALL(\\n address _target,\\n bytes memory _data,\\n uint256 _value\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n return _target.call{ value: _value }(_data);\\n }\\n\\n /**\\n * Sends a DELEGATECALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n *\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function DELEGATECALL(address _target, bytes memory _data)\\n external\\n payable\\n onlyOwner\\n returns (bool, bytes memory)\\n {\\n // slither-disable-next-line controlled-delegatecall\\n return _target.delegatecall(_data);\\n }\\n}\\n\",\"keccak256\":\"0x6a9e687b2f333bcc8ade530325005cb67ab7f78fd31407d4f2274324e71fc0fb\",\"license\":\"MIT\"},\"contracts/universal/drippie/Drippie.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { AssetReceiver } from \\\"../AssetReceiver.sol\\\";\\nimport { IDripCheck } from \\\"./IDripCheck.sol\\\";\\n\\n/**\\n * @title Drippie\\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\\n * is called a \\\"drip\\\" and can be executed according to some condition (called a dripcheck)\\n * and an execution interval. Drips cannot be executed faster than the execution interval.\\n * Drips can trigger arbitrary contract calls where the calling contract is this contract\\n * address. Drips can also send ETH value, which makes them ideal for keeping addresses\\n * sufficiently funded with ETH. Drippie is designed to be connected with smart contract\\n * automation services so that drips can be executed automatically. However, Drippie is\\n * specifically designed to be separated from these services so that trust assumptions are\\n * better compartmentalized.\\n */\\ncontract Drippie is AssetReceiver {\\n /**\\n * @notice Enum representing different status options for a given drip.\\n *\\n * @custom:value NONE Drip does not exist.\\n * @custom:value PAUSED Drip is paused and cannot be executed until reactivated.\\n * @custom:value ACTIVE Drip is active and can be executed.\\n * @custom:value ARCHIVED Drip is archived and can no longer be executed or reactivated.\\n */\\n enum DripStatus {\\n NONE,\\n PAUSED,\\n ACTIVE,\\n ARCHIVED\\n }\\n\\n /**\\n * @notice Represents a drip action.\\n */\\n struct DripAction {\\n address payable target;\\n bytes data;\\n uint256 value;\\n }\\n\\n /**\\n * @notice Represents the configuration for a given drip.\\n */\\n struct DripConfig {\\n bool reentrant;\\n uint256 interval;\\n IDripCheck dripcheck;\\n bytes checkparams;\\n DripAction[] actions;\\n }\\n\\n /**\\n * @notice Represents the state of an active drip.\\n */\\n struct DripState {\\n DripStatus status;\\n DripConfig config;\\n uint256 last;\\n uint256 count;\\n }\\n\\n /**\\n * @notice Emitted when a new drip is created.\\n *\\n * @param nameref Indexed name parameter (hashed).\\n * @param name Unindexed name parameter (unhashed).\\n * @param config Config for the created drip.\\n */\\n event DripCreated(\\n // Emit name twice because indexed version is hashed.\\n string indexed nameref,\\n string name,\\n DripConfig config\\n );\\n\\n /**\\n * @notice Emitted when a drip status is updated.\\n *\\n * @param nameref Indexed name parameter (hashed).\\n * @param name Unindexed name parameter (unhashed).\\n * @param status New drip status.\\n */\\n event DripStatusUpdated(\\n // Emit name twice because indexed version is hashed.\\n string indexed nameref,\\n string name,\\n DripStatus status\\n );\\n\\n /**\\n * @notice Emitted when a drip is executed.\\n *\\n * @param nameref Indexed name parameter (hashed).\\n * @param name Unindexed name parameter (unhashed).\\n * @param executor Address that executed the drip.\\n * @param timestamp Time when the drip was executed.\\n */\\n event DripExecuted(\\n // Emit name twice because indexed version is hashed.\\n string indexed nameref,\\n string name,\\n address executor,\\n uint256 timestamp\\n );\\n\\n /**\\n * @notice Maps from drip names to drip states.\\n */\\n mapping(string => DripState) public drips;\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) AssetReceiver(_owner) {}\\n\\n /**\\n * @notice Creates a new drip with the given name and configuration. Once created, drips cannot\\n * be modified in any way (this is a security measure). If you want to update a drip,\\n * simply pause (and potentially archive) the existing drip and create a new one.\\n *\\n * @param _name Name of the drip.\\n * @param _config Configuration for the drip.\\n */\\n function create(string calldata _name, DripConfig calldata _config) external onlyOwner {\\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\\n // will ever set the status of a drip back to NONE after it's been created. This is why\\n // archival is a separate status.\\n require(\\n drips[_name].status == DripStatus.NONE,\\n \\\"Drippie: drip with that name already exists\\\"\\n );\\n\\n // Validate the drip interval, only allowing an interval of zero if the drip has explicitly\\n // been marked as reentrant. Prevents client-side bugs making a drip infinitely executable\\n // within the same block (of course, restricted by gas limits).\\n if (_config.reentrant) {\\n require(\\n _config.interval == 0,\\n \\\"Drippie: if allowing reentrant drip, must set interval to zero\\\"\\n );\\n } else {\\n require(\\n _config.interval > 0,\\n \\\"Drippie: interval must be greater than zero if drip is not reentrant\\\"\\n );\\n }\\n\\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\\n DripState storage state = drips[_name];\\n state.status = DripStatus.PAUSED;\\n state.config.reentrant = _config.reentrant;\\n state.config.interval = _config.interval;\\n state.config.dripcheck = _config.dripcheck;\\n state.config.checkparams = _config.checkparams;\\n\\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\\n for (uint256 i = 0; i < _config.actions.length; i++) {\\n state.config.actions.push(_config.actions[i]);\\n }\\n\\n // Tell the world!\\n emit DripCreated(_name, _name, _config);\\n }\\n\\n /**\\n * @notice Sets the status for a given drip. The behavior of this function depends on the\\n * status that the user is trying to set. A drip can always move between ACTIVE and\\n * PAUSED, but it can never move back to NONE and once ARCHIVED, it can never move back\\n * to ACTIVE or PAUSED.\\n *\\n * @param _name Name of the drip to update.\\n * @param _status New drip status.\\n */\\n function status(string calldata _name, DripStatus _status) external onlyOwner {\\n // Make sure we can never set drip status back to NONE. A simple security measure to\\n // prevent accidental overwrites if this code is ever updated down the line.\\n require(\\n _status != DripStatus.NONE,\\n \\\"Drippie: drip status can never be set back to NONE after creation\\\"\\n );\\n\\n // Load the drip status once to avoid unnecessary SLOADs.\\n DripStatus curr = drips[_name].status;\\n\\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\\n // seem to be any clear reason why you would want to do this, and it may save some gas in\\n // the case of a front-end bug.\\n require(\\n curr != DripStatus.NONE,\\n \\\"Drippie: drip with that name does not exist and cannot be updated\\\"\\n );\\n\\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\\n // point of archiving a drip.\\n require(\\n curr != DripStatus.ARCHIVED,\\n \\\"Drippie: drip with that name has been archived and cannot be updated\\\"\\n );\\n\\n // Although not strictly necessary, we make sure that the status here is actually changing.\\n // This may save the client some gas if there's a front-end bug and the user accidentally\\n // tries to \\\"change\\\" the status to the same value as before.\\n require(\\n curr != _status,\\n \\\"Drippie: cannot set drip status to the same status as its current status\\\"\\n );\\n\\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\\n // not allow users to archive active drips so that the effects of this action are more\\n // abundantly clear.\\n if (_status == DripStatus.ARCHIVED) {\\n require(\\n curr == DripStatus.PAUSED,\\n \\\"Drippie: drip must first be paused before being archived\\\"\\n );\\n }\\n\\n // If we made it here then we can safely update the status.\\n drips[_name].status = _status;\\n emit DripStatusUpdated(_name, _name, _status);\\n }\\n\\n /**\\n * @notice Checks if a given drip is executable.\\n *\\n * @param _name Drip to check.\\n *\\n * @return True if the drip is executable, reverts otherwise.\\n */\\n function executable(string calldata _name) public view returns (bool) {\\n DripState storage state = drips[_name];\\n\\n // Only allow active drips to be executed, an obvious security measure.\\n require(\\n state.status == DripStatus.ACTIVE,\\n \\\"Drippie: selected drip does not exist or is not currently active\\\"\\n );\\n\\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\\n // compromised recipient to just a single drip interval, after which the drip can be paused\\n // by the owner address.\\n require(\\n state.last + state.config.interval <= block.timestamp,\\n \\\"Drippie: drip interval has not elapsed since last drip\\\"\\n );\\n\\n // Make sure we're allowed to execute this drip.\\n require(\\n state.config.dripcheck.check(state.config.checkparams),\\n \\\"Drippie: dripcheck failed so drip is not yet ready to be triggered\\\"\\n );\\n\\n // Alright, we're good to execute.\\n return true;\\n }\\n\\n /**\\n * @notice Triggers a drip. This function is deliberately left as a public function because the\\n * assumption being made here is that setting the drip to ACTIVE is an affirmative\\n * signal that the drip should be executable according to the drip parameters, drip\\n * check, and drip interval. Note that drip parameters are read entirely from the state\\n * and are not supplied as user input, so there should not be any way for a\\n * non-authorized user to influence the behavior of the drip. Note that the drip check\\n * is executed only **once** at the beginning of the call to the drip function and will\\n * not be executed again between the drip actions within this call.\\n *\\n * @param _name Name of the drip to trigger.\\n */\\n function drip(string calldata _name) external {\\n DripState storage state = drips[_name];\\n\\n // Make sure the drip can be executed. Since executable reverts if the drip is not ready to\\n // be executed, we don't need to do an assertion that the returned value is true.\\n executable(_name);\\n\\n // Update the last execution time for this drip before the call. Note that it's entirely\\n // possible for a drip to be executed multiple times per block or even multiple times\\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\\n // block (since this will then prevent re-entrancy).\\n state.last = block.timestamp;\\n\\n // Update the number of times this drip has been executed. Although this increases the cost\\n // of using Drippie, it slightly simplifies the client-side by not having to worry about\\n // counting drips via events. Useful for monitoring the rate of drip execution.\\n state.count++;\\n\\n // Execute each action in the drip. We allow drips to have multiple actions because there\\n // are scenarios in which a contract must do multiple things atomically. For example, the\\n // contract may need to withdraw ETH from one account and then deposit that ETH into\\n // another account within the same transaction.\\n uint256 len = state.config.actions.length;\\n for (uint256 i = 0; i < len; i++) {\\n // Must be marked as \\\"storage\\\" because copying structs into memory is not yet supported\\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\\n // read what the rest of this section is doing.\\n DripAction storage action = state.config.actions[i];\\n\\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\\n // returndata.\\n // slither-disable-next-line calls-loop\\n (bool success, ) = action.target.call{ value: action.value }(action.data);\\n\\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\\n // the wrong data to the target contract), the recipient is not payable, or\\n // insufficient gas was supplied to this transaction. We revert so the drip can be\\n // fixed and triggered again later. Means we cannot emit an event to alert of the\\n // failure, but can reasonably be detected by off-chain services even without an event.\\n // Note that this forces the drip executor to supply sufficient gas to the call\\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\\n // not execute).\\n require(\\n success,\\n \\\"Drippie: drip was unsuccessful, please check your configuration for mistakes\\\"\\n );\\n }\\n\\n emit DripExecuted(_name, _name, msg.sender, block.timestamp);\\n }\\n}\\n\",\"keccak256\":\"0x60aac1f170b36ddd9523a48eccae75ad408ecbad6b32bcf5567e7f680ab10c94\",\"license\":\"MIT\"},\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b5060405162002b3138038062002b3183398101604081905262000034916200008c565b600080546001600160a01b0319166001600160a01b03831690811782556040518392839283929091907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908290a350505050620000be565b6000602082840312156200009f57600080fd5b81516001600160a01b0381168114620000b757600080fd5b9392505050565b612a6380620000ce6000396000f3fe6080604052600436106100e15760003560e01c80636e2d44ae1161007f5780639bc94d01116100595780639bc94d01146102b0578063e551cdaa146102d0578063edee6239146102f0578063fc3e3eba1461030357600080fd5b80636e2d44ae1461021d5780638da5cb5b1461023e5780639456fbcc1461029057600080fd5b80634782f779116100bb5780634782f779146101845780634d7fba6e146101a457806367148cd2146101dd578063690d8320146101fd57600080fd5b806313af4035146101225780634025feb21461014457806344004cc11461016457600080fd5b3661011d5760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561012e57600080fd5b5061014261013d366004611af9565b610333565b005b34801561015057600080fd5b5061014261015f366004611b1d565b61040f565b34801561017057600080fd5b5061014261017f366004611b1d565b610587565b34801561019057600080fd5b5061014261019f366004611b5e565b6106fe565b3480156101b057600080fd5b506101c46101bf366004611c2f565b610834565b6040516101d49493929190611d3a565b60405180910390f35b3480156101e957600080fd5b506101426101f8366004611e94565b610a66565b34801561020957600080fd5b50610142610218366004611af9565b610c6f565b61023061022b366004611ef6565b610ce3565b6040516101d4929190611f4f565b34801561024a57600080fd5b5060005461026b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d4565b34801561029c57600080fd5b506101426102ab366004611f6a565b610dc3565b3480156102bc57600080fd5b506101426102cb366004611fa3565b610ec4565b3480156102dc57600080fd5b506101426102eb366004611ffe565b611363565b6102306102fe366004612063565b61177f565b34801561030f57600080fd5b5061032361031e366004611e94565b61185c565b60405190151581526020016101d4565b60005473ffffffffffffffffffffffffffffffffffffffff16331461039f5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104765760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b1580156104ec57600080fd5b505af1158015610500573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a88460405161057a91815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ee5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015610663573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068791906120c1565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa8460405161057a91815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107655760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146107bf576040519150601f19603f3d011682016040523d82523d6000602084013e6107c4565b606091505b505090508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc8460405161082791815260200190565b60405180910390a3505050565b805160208183018101805160018083529383019483019490942093905282546040805160a081018252938501805460ff90811615158652600287015494860194909452600386015473ffffffffffffffffffffffffffffffffffffffff169185019190915260048501805493909216949392909160608401916108b6906120de565b80601f01602080910402602001604051908101604052809291908181526020018280546108e2906120de565b801561092f5780601f106109045761010080835404028352916020019161092f565b820191906000526020600020905b81548152906001019060200180831161091257829003601f168201915b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b82821015610a4e576000848152602090819020604080516060810190915260038502909101805473ffffffffffffffffffffffffffffffffffffffff16825260018101805492939192918401916109b3906120de565b80601f01602080910402602001604051908101604052809291908181526020018280546109df906120de565b8015610a2c5780601f10610a0157610100808354040283529160200191610a2c565b820191906000526020600020905b815481529060010190602001808311610a0f57829003601f168201915b505050505081526020016002820154815250508152602001906001019061095d565b50505091525050600682015460079092015490919084565b600060018383604051610a7a929190612131565b90815260200160405180910390209050610a94838361185c565b50426006820155600781018054906000610aad83612170565b9091555050600581015460005b81811015610c13576000836001016004018281548110610adc57610adc6121a8565b6000918252602082206003909102018054600282015460405192945073ffffffffffffffffffffffffffffffffffffffff90911691610b1f9060018601906121d7565b60006040518083038185875af1925050503d8060008114610b5c576040519150601f19603f3d011682016040523d82523d6000602084013e610b61565b606091505b5050905080610bfe5760405162461bcd60e51b815260206004820152604c60248201527f447269707069653a20647269702077617320756e7375636365737366756c2c2060448201527f706c6561736520636865636b20796f757220636f6e66696775726174696f6e2060648201527f666f72206d697374616b65730000000000000000000000000000000000000000608482015260a401610396565b50508080610c0b90612170565b915050610aba565b508383604051610c24929190612131565b60405180910390207fea21435419aad9c54a9d90e2522b6f60bd566401f36fcef661f5f5a28cc0d2c685853342604051610c619493929190612296565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cd65760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b610ce081476106fe565b50565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610d4e5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610d7491906122d3565b60006040518083038185875af1925050503d8060008114610db1576040519150601f19603f3d011682016040523d82523d6000602084013e610db6565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e2a5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610ec0908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610e9c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017f91906122ef565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f2b5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6000816003811115610f3f57610f3f611c80565b03610fd85760405162461bcd60e51b815260206004820152604160248201527f447269707069653a2064726970207374617475732063616e206e65766572206260448201527f6520736574206261636b20746f204e4f4e45206166746572206372656174696f60648201527f6e00000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b600060018484604051610fec929190612131565b9081526040519081900360200190205460ff169050600081600381111561101557611015611c80565b036110ae5760405162461bcd60e51b815260206004820152604160248201527f447269707069653a206472697020776974682074686174206e616d6520646f6560448201527f73206e6f7420657869737420616e642063616e6e6f742062652075706461746560648201527f6400000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b60038160038111156110c2576110c2611c80565b0361115c5760405162461bcd60e51b8152602060048201526044602482018190527f447269707069653a206472697020776974682074686174206e616d6520686173908201527f206265656e20617263686976656420616e642063616e6e6f742062652075706460648201527f6174656400000000000000000000000000000000000000000000000000000000608482015260a401610396565b81600381111561116e5761116e611c80565b81600381111561118057611180611c80565b036112195760405162461bcd60e51b815260206004820152604860248201527f447269707069653a2063616e6e6f74207365742064726970207374617475732060448201527f746f207468652073616d6520737461747573206173206974732063757272656e60648201527f7420737461747573000000000000000000000000000000000000000000000000608482015260a401610396565b600382600381111561122d5761122d611c80565b036112b957600181600381111561124657611246611c80565b146112b95760405162461bcd60e51b815260206004820152603860248201527f447269707069653a2064726970206d757374206669727374206265207061757360448201527f6564206265666f7265206265696e6720617263686976656400000000000000006064820152608401610396565b81600185856040516112cc929190612131565b90815260405190819003602001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600381111561131357611313611c80565b02179055508383604051611328929190612131565b60405180910390207f407cb3ad05e60ec498fb39417c7a4f6b82d5ba80f82fe512a37b02c93181a2a1858585604051610c6193929190612308565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113ca5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6000600184846040516113de929190612131565b9081526040519081900360200190205460ff16600381111561140257611402611c80565b146114755760405162461bcd60e51b815260206004820152602b60248201527f447269707069653a206472697020776974682074686174206e616d6520616c7260448201527f65616479206578697374730000000000000000000000000000000000000000006064820152608401610396565b611482602082018261232b565b15611504576020810135156114ff5760405162461bcd60e51b815260206004820152603e60248201527f447269707069653a20696620616c6c6f77696e67207265656e7472616e74206460448201527f7269702c206d7573742073657420696e74657276616c20746f207a65726f00006064820152608401610396565b6115a5565b60008160200135116115a55760405162461bcd60e51b8152602060048201526044602482018190527f447269707069653a20696e74657276616c206d75737420626520677265617465908201527f72207468616e207a65726f2069662064726970206973206e6f74207265656e7460648201527f72616e7400000000000000000000000000000000000000000000000000000000608482015260a401610396565b6000600184846040516115b9929190612131565b9081526040516020918190038201902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117815591506116009083018361232b565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556020820135600282015561164b6060830160408401611af9565b6003820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561169f6060830183612348565b60048301916116af9190836123fc565b5060005b6116c060808401846124f9565b905081101561173357600582016116da60808501856124f9565b838181106116ea576116ea6121a8565b90506020028101906116fc9190612561565b81546001810183556000928352602090922090916003020161171e8282612595565b5050808061172b90612170565b9150506116b3565b508383604051611744929190612131565b60405180910390207fe38d8d98e6cc66f6f520d483c6c5a89289681f897799c4c29d767cf57e76d9a6858585604051610c619392919061286a565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146117ea5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8373ffffffffffffffffffffffffffffffffffffffff168360405161180f91906122d3565b600060405180830381855af49150503d806000811461184a576040519150601f19603f3d011682016040523d82523d6000602084013e61184f565b606091505b50915091505b9250929050565b60008060018484604051611871929190612131565b90815260405190819003602001902090506002815460ff16600381111561189a5761189a611c80565b1461190f576040805162461bcd60e51b81526020600482015260248101919091527f447269707069653a2073656c6563746564206472697020646f6573206e6f742060448201527f6578697374206f72206973206e6f742063757272656e746c79206163746976656064820152608401610396565b60028101546006820154429161192491612971565b11156119985760405162461bcd60e51b815260206004820152603660248201527f447269707069653a206472697020696e74657276616c20686173206e6f74206560448201527f6c61707365642073696e6365206c6173742064726970000000000000000000006064820152608401610396565b60038101546040517fc64b3bb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063c64b3bb5906119f29060048086019101612984565b602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a3391906120c1565b611acb5760405162461bcd60e51b815260206004820152604260248201527f447269707069653a2064726970636865636b206661696c656420736f2064726960448201527f70206973206e6f742079657420726561647920746f206265207472696767657260648201527f6564000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b60019150505b92915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce057600080fd5b600060208284031215611b0b57600080fd5b8135611b1681611ad7565b9392505050565b600080600060608486031215611b3257600080fd5b8335611b3d81611ad7565b92506020840135611b4d81611ad7565b929592945050506040919091013590565b60008060408385031215611b7157600080fd5b8235611b7c81611ad7565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115611bd457611bd4611b8a565b604051601f8501601f19908116603f01168101908282118183101715611bfc57611bfc611b8a565b81604052809350858152868686011115611c1557600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215611c4157600080fd5b813567ffffffffffffffff811115611c5857600080fd5b8201601f81018413611c6957600080fd5b611c7884823560208401611bb9565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110611ce6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60005b83811015611d05578181015183820152602001611ced565b50506000910152565b60008151808452611d26816020860160208601611cea565b601f01601f19169290920160200192915050565b611d448186611caf565b600060206080818401528551151560808401528086015160a084015260408087015173ffffffffffffffffffffffffffffffffffffffff80821660c0870152606091508189015160a060e0880152611da0610120880182611d0e565b60808b01518882037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80016101008a0152805180835291925086019086830190600581901b8401880160005b82811015611e3657601f1986830301845284518781511683528a810151898c850152611e198a850182611d0e565b918b0151938b0193909352948a0194938a01939150600101611deb565b50968a019b909b52505050509093019390935250949350505050565b60008083601f840112611e6457600080fd5b50813567ffffffffffffffff811115611e7c57600080fd5b60208301915083602082850101111561185557600080fd5b60008060208385031215611ea757600080fd5b823567ffffffffffffffff811115611ebe57600080fd5b611eca85828601611e52565b90969095509350505050565b600082601f830112611ee757600080fd5b611b1683833560208501611bb9565b600080600060608486031215611f0b57600080fd5b8335611f1681611ad7565b9250602084013567ffffffffffffffff811115611f3257600080fd5b611f3e86828701611ed6565b925050604084013590509250925092565b8215158152604060208201526000611c786040830184611d0e565b60008060408385031215611f7d57600080fd5b8235611f8881611ad7565b91506020830135611f9881611ad7565b809150509250929050565b600080600060408486031215611fb857600080fd5b833567ffffffffffffffff811115611fcf57600080fd5b611fdb86828701611e52565b909450925050602084013560048110611ff357600080fd5b809150509250925092565b60008060006040848603121561201357600080fd5b833567ffffffffffffffff8082111561202b57600080fd5b61203787838801611e52565b9095509350602086013591508082111561205057600080fd5b50840160a08187031215611ff357600080fd5b6000806040838503121561207657600080fd5b823561208181611ad7565b9150602083013567ffffffffffffffff81111561209d57600080fd5b6120a985828601611ed6565b9150509250929050565b8015158114610ce057600080fd5b6000602082840312156120d357600080fd5b8151611b16816120b3565b600181811c908216806120f257607f821691505b60208210810361212b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036121a1576121a1612141565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083546121e5816120de565b600182811680156121fd57600181146122305761225f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008416875282151583028701945061225f565b8760005260208060002060005b858110156122565781548a82015290840190820161223d565b50505082870194505b50929695505050505050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6060815260006122aa60608301868861226b565b73ffffffffffffffffffffffffffffffffffffffff949094166020830152506040015292915050565b600082516122e5818460208701611cea565b9190910192915050565b60006020828403121561230157600080fd5b5051919050565b60408152600061231c60408301858761226b565b9050611c786020830184611caf565b60006020828403121561233d57600080fd5b8135611b16816120b3565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261237d57600080fd5b83018035915067ffffffffffffffff82111561239857600080fd5b60200191503681900382131561185557600080fd5b601f8211156123f757600081815260208120601f850160051c810160208610156123d45750805b601f850160051c820191505b818110156123f3578281556001016123e0565b5050505b505050565b67ffffffffffffffff83111561241457612414611b8a565b6124288361242283546120de565b836123ad565b6000601f84116001811461247a57600085156124445750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556124f2565b600083815260209020601f19861690835b828110156124ab578685013582556020948501946001909201910161248b565b50868210156124e6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261252e57600080fd5b83018035915067ffffffffffffffff82111561254957600080fd5b6020019150600581901b360382131561185557600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126122e557600080fd5b81356125a081611ad7565b73ffffffffffffffffffffffffffffffffffffffff81167fffffffffffffffffffffffff00000000000000000000000000000000000000008354161782555060018082016020808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261261a57600080fd5b8501803567ffffffffffffffff81111561263357600080fd5b803603838301131561264457600080fd5b6126588161265286546120de565b866123ad565b6000601f8211600181146126ac576000831561267657508382018501355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b178655612723565b600086815260209020601f19841690835b828110156126dc578685018801358255938701939089019087016126bd565b5084821015612719577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c198785880101351681555b50508683881b0186555b50505050505050604082013560028201555050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261276d57600080fd5b830160208101925035905067ffffffffffffffff81111561278d57600080fd5b80360382131561185557600080fd5b81835260006020808501808196508560051b81019150846000805b8881101561285c578385038a5282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18936030181126127f5578283fd5b88016060813561280481611ad7565b73ffffffffffffffffffffffffffffffffffffffff16875261282882890183612738565b828a8a015261283a838a01828461226b565b60409485013599909401989098525050998601999450918501916001016127b7565b509298975050505050505050565b60408152600061287e60408301858761226b565b82810360208401528335612891816120b3565b151581526020848101359082015260408401356128ad81611ad7565b73ffffffffffffffffffffffffffffffffffffffff1660408201526128d56060850185612738565b60a060608401526128ea60a08401828461226b565b91505060808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261292257600080fd5b850160208101903567ffffffffffffffff81111561293f57600080fd5b8060051b360382131561295157600080fd5b838303608085015261296483828461279c565b9998505050505050505050565b80820180821115611ad157611ad1612141565b6000602080835260008454612998816120de565b808487015260406001808416600081146129b957600181146129f157612a1f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a01019550612a1f565b896000528660002060005b85811015612a175781548b82018601529083019088016129fc565b8a0184019650505b50939897505050505050505056fea26469706673582212208d60ccb026b0dcc2e3511887db1b30dfd98f123af2a2a96714cbeca8ed21494464736f6c63430008100033", - "deployedBytecode": "0x6080604052600436106100e15760003560e01c80636e2d44ae1161007f5780639bc94d01116100595780639bc94d01146102b0578063e551cdaa146102d0578063edee6239146102f0578063fc3e3eba1461030357600080fd5b80636e2d44ae1461021d5780638da5cb5b1461023e5780639456fbcc1461029057600080fd5b80634782f779116100bb5780634782f779146101845780634d7fba6e146101a457806367148cd2146101dd578063690d8320146101fd57600080fd5b806313af4035146101225780634025feb21461014457806344004cc11461016457600080fd5b3661011d5760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561012e57600080fd5b5061014261013d366004611af9565b610333565b005b34801561015057600080fd5b5061014261015f366004611b1d565b61040f565b34801561017057600080fd5b5061014261017f366004611b1d565b610587565b34801561019057600080fd5b5061014261019f366004611b5e565b6106fe565b3480156101b057600080fd5b506101c46101bf366004611c2f565b610834565b6040516101d49493929190611d3a565b60405180910390f35b3480156101e957600080fd5b506101426101f8366004611e94565b610a66565b34801561020957600080fd5b50610142610218366004611af9565b610c6f565b61023061022b366004611ef6565b610ce3565b6040516101d4929190611f4f565b34801561024a57600080fd5b5060005461026b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d4565b34801561029c57600080fd5b506101426102ab366004611f6a565b610dc3565b3480156102bc57600080fd5b506101426102cb366004611fa3565b610ec4565b3480156102dc57600080fd5b506101426102eb366004611ffe565b611363565b6102306102fe366004612063565b61177f565b34801561030f57600080fd5b5061032361031e366004611e94565b61185c565b60405190151581526020016101d4565b60005473ffffffffffffffffffffffffffffffffffffffff16331461039f5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104765760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b1580156104ec57600080fd5b505af1158015610500573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a88460405161057a91815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ee5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015610663573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068791906120c1565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa8460405161057a91815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107655760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146107bf576040519150601f19603f3d011682016040523d82523d6000602084013e6107c4565b606091505b505090508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc8460405161082791815260200190565b60405180910390a3505050565b805160208183018101805160018083529383019483019490942093905282546040805160a081018252938501805460ff90811615158652600287015494860194909452600386015473ffffffffffffffffffffffffffffffffffffffff169185019190915260048501805493909216949392909160608401916108b6906120de565b80601f01602080910402602001604051908101604052809291908181526020018280546108e2906120de565b801561092f5780601f106109045761010080835404028352916020019161092f565b820191906000526020600020905b81548152906001019060200180831161091257829003601f168201915b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b82821015610a4e576000848152602090819020604080516060810190915260038502909101805473ffffffffffffffffffffffffffffffffffffffff16825260018101805492939192918401916109b3906120de565b80601f01602080910402602001604051908101604052809291908181526020018280546109df906120de565b8015610a2c5780601f10610a0157610100808354040283529160200191610a2c565b820191906000526020600020905b815481529060010190602001808311610a0f57829003601f168201915b505050505081526020016002820154815250508152602001906001019061095d565b50505091525050600682015460079092015490919084565b600060018383604051610a7a929190612131565b90815260200160405180910390209050610a94838361185c565b50426006820155600781018054906000610aad83612170565b9091555050600581015460005b81811015610c13576000836001016004018281548110610adc57610adc6121a8565b6000918252602082206003909102018054600282015460405192945073ffffffffffffffffffffffffffffffffffffffff90911691610b1f9060018601906121d7565b60006040518083038185875af1925050503d8060008114610b5c576040519150601f19603f3d011682016040523d82523d6000602084013e610b61565b606091505b5050905080610bfe5760405162461bcd60e51b815260206004820152604c60248201527f447269707069653a20647269702077617320756e7375636365737366756c2c2060448201527f706c6561736520636865636b20796f757220636f6e66696775726174696f6e2060648201527f666f72206d697374616b65730000000000000000000000000000000000000000608482015260a401610396565b50508080610c0b90612170565b915050610aba565b508383604051610c24929190612131565b60405180910390207fea21435419aad9c54a9d90e2522b6f60bd566401f36fcef661f5f5a28cc0d2c685853342604051610c619493929190612296565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cd65760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b610ce081476106fe565b50565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610d4e5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610d7491906122d3565b60006040518083038185875af1925050503d8060008114610db1576040519150601f19603f3d011682016040523d82523d6000602084013e610db6565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e2a5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610ec0908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610e9c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017f91906122ef565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f2b5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6000816003811115610f3f57610f3f611c80565b03610fd85760405162461bcd60e51b815260206004820152604160248201527f447269707069653a2064726970207374617475732063616e206e65766572206260448201527f6520736574206261636b20746f204e4f4e45206166746572206372656174696f60648201527f6e00000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b600060018484604051610fec929190612131565b9081526040519081900360200190205460ff169050600081600381111561101557611015611c80565b036110ae5760405162461bcd60e51b815260206004820152604160248201527f447269707069653a206472697020776974682074686174206e616d6520646f6560448201527f73206e6f7420657869737420616e642063616e6e6f742062652075706461746560648201527f6400000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b60038160038111156110c2576110c2611c80565b0361115c5760405162461bcd60e51b8152602060048201526044602482018190527f447269707069653a206472697020776974682074686174206e616d6520686173908201527f206265656e20617263686976656420616e642063616e6e6f742062652075706460648201527f6174656400000000000000000000000000000000000000000000000000000000608482015260a401610396565b81600381111561116e5761116e611c80565b81600381111561118057611180611c80565b036112195760405162461bcd60e51b815260206004820152604860248201527f447269707069653a2063616e6e6f74207365742064726970207374617475732060448201527f746f207468652073616d6520737461747573206173206974732063757272656e60648201527f7420737461747573000000000000000000000000000000000000000000000000608482015260a401610396565b600382600381111561122d5761122d611c80565b036112b957600181600381111561124657611246611c80565b146112b95760405162461bcd60e51b815260206004820152603860248201527f447269707069653a2064726970206d757374206669727374206265207061757360448201527f6564206265666f7265206265696e6720617263686976656400000000000000006064820152608401610396565b81600185856040516112cc929190612131565b90815260405190819003602001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600381111561131357611313611c80565b02179055508383604051611328929190612131565b60405180910390207f407cb3ad05e60ec498fb39417c7a4f6b82d5ba80f82fe512a37b02c93181a2a1858585604051610c6193929190612308565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113ca5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6000600184846040516113de929190612131565b9081526040519081900360200190205460ff16600381111561140257611402611c80565b146114755760405162461bcd60e51b815260206004820152602b60248201527f447269707069653a206472697020776974682074686174206e616d6520616c7260448201527f65616479206578697374730000000000000000000000000000000000000000006064820152608401610396565b611482602082018261232b565b15611504576020810135156114ff5760405162461bcd60e51b815260206004820152603e60248201527f447269707069653a20696620616c6c6f77696e67207265656e7472616e74206460448201527f7269702c206d7573742073657420696e74657276616c20746f207a65726f00006064820152608401610396565b6115a5565b60008160200135116115a55760405162461bcd60e51b8152602060048201526044602482018190527f447269707069653a20696e74657276616c206d75737420626520677265617465908201527f72207468616e207a65726f2069662064726970206973206e6f74207265656e7460648201527f72616e7400000000000000000000000000000000000000000000000000000000608482015260a401610396565b6000600184846040516115b9929190612131565b9081526040516020918190038201902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117815591506116009083018361232b565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556020820135600282015561164b6060830160408401611af9565b6003820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561169f6060830183612348565b60048301916116af9190836123fc565b5060005b6116c060808401846124f9565b905081101561173357600582016116da60808501856124f9565b838181106116ea576116ea6121a8565b90506020028101906116fc9190612561565b81546001810183556000928352602090922090916003020161171e8282612595565b5050808061172b90612170565b9150506116b3565b508383604051611744929190612131565b60405180910390207fe38d8d98e6cc66f6f520d483c6c5a89289681f897799c4c29d767cf57e76d9a6858585604051610c619392919061286a565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146117ea5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8373ffffffffffffffffffffffffffffffffffffffff168360405161180f91906122d3565b600060405180830381855af49150503d806000811461184a576040519150601f19603f3d011682016040523d82523d6000602084013e61184f565b606091505b50915091505b9250929050565b60008060018484604051611871929190612131565b90815260405190819003602001902090506002815460ff16600381111561189a5761189a611c80565b1461190f576040805162461bcd60e51b81526020600482015260248101919091527f447269707069653a2073656c6563746564206472697020646f6573206e6f742060448201527f6578697374206f72206973206e6f742063757272656e746c79206163746976656064820152608401610396565b60028101546006820154429161192491612971565b11156119985760405162461bcd60e51b815260206004820152603660248201527f447269707069653a206472697020696e74657276616c20686173206e6f74206560448201527f6c61707365642073696e6365206c6173742064726970000000000000000000006064820152608401610396565b60038101546040517fc64b3bb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063c64b3bb5906119f29060048086019101612984565b602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a3391906120c1565b611acb5760405162461bcd60e51b815260206004820152604260248201527f447269707069653a2064726970636865636b206661696c656420736f2064726960448201527f70206973206e6f742079657420726561647920746f206265207472696767657260648201527f6564000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b60019150505b92915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce057600080fd5b600060208284031215611b0b57600080fd5b8135611b1681611ad7565b9392505050565b600080600060608486031215611b3257600080fd5b8335611b3d81611ad7565b92506020840135611b4d81611ad7565b929592945050506040919091013590565b60008060408385031215611b7157600080fd5b8235611b7c81611ad7565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115611bd457611bd4611b8a565b604051601f8501601f19908116603f01168101908282118183101715611bfc57611bfc611b8a565b81604052809350858152868686011115611c1557600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215611c4157600080fd5b813567ffffffffffffffff811115611c5857600080fd5b8201601f81018413611c6957600080fd5b611c7884823560208401611bb9565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110611ce6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60005b83811015611d05578181015183820152602001611ced565b50506000910152565b60008151808452611d26816020860160208601611cea565b601f01601f19169290920160200192915050565b611d448186611caf565b600060206080818401528551151560808401528086015160a084015260408087015173ffffffffffffffffffffffffffffffffffffffff80821660c0870152606091508189015160a060e0880152611da0610120880182611d0e565b60808b01518882037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80016101008a0152805180835291925086019086830190600581901b8401880160005b82811015611e3657601f1986830301845284518781511683528a810151898c850152611e198a850182611d0e565b918b0151938b0193909352948a0194938a01939150600101611deb565b50968a019b909b52505050509093019390935250949350505050565b60008083601f840112611e6457600080fd5b50813567ffffffffffffffff811115611e7c57600080fd5b60208301915083602082850101111561185557600080fd5b60008060208385031215611ea757600080fd5b823567ffffffffffffffff811115611ebe57600080fd5b611eca85828601611e52565b90969095509350505050565b600082601f830112611ee757600080fd5b611b1683833560208501611bb9565b600080600060608486031215611f0b57600080fd5b8335611f1681611ad7565b9250602084013567ffffffffffffffff811115611f3257600080fd5b611f3e86828701611ed6565b925050604084013590509250925092565b8215158152604060208201526000611c786040830184611d0e565b60008060408385031215611f7d57600080fd5b8235611f8881611ad7565b91506020830135611f9881611ad7565b809150509250929050565b600080600060408486031215611fb857600080fd5b833567ffffffffffffffff811115611fcf57600080fd5b611fdb86828701611e52565b909450925050602084013560048110611ff357600080fd5b809150509250925092565b60008060006040848603121561201357600080fd5b833567ffffffffffffffff8082111561202b57600080fd5b61203787838801611e52565b9095509350602086013591508082111561205057600080fd5b50840160a08187031215611ff357600080fd5b6000806040838503121561207657600080fd5b823561208181611ad7565b9150602083013567ffffffffffffffff81111561209d57600080fd5b6120a985828601611ed6565b9150509250929050565b8015158114610ce057600080fd5b6000602082840312156120d357600080fd5b8151611b16816120b3565b600181811c908216806120f257607f821691505b60208210810361212b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036121a1576121a1612141565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083546121e5816120de565b600182811680156121fd57600181146122305761225f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008416875282151583028701945061225f565b8760005260208060002060005b858110156122565781548a82015290840190820161223d565b50505082870194505b50929695505050505050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6060815260006122aa60608301868861226b565b73ffffffffffffffffffffffffffffffffffffffff949094166020830152506040015292915050565b600082516122e5818460208701611cea565b9190910192915050565b60006020828403121561230157600080fd5b5051919050565b60408152600061231c60408301858761226b565b9050611c786020830184611caf565b60006020828403121561233d57600080fd5b8135611b16816120b3565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261237d57600080fd5b83018035915067ffffffffffffffff82111561239857600080fd5b60200191503681900382131561185557600080fd5b601f8211156123f757600081815260208120601f850160051c810160208610156123d45750805b601f850160051c820191505b818110156123f3578281556001016123e0565b5050505b505050565b67ffffffffffffffff83111561241457612414611b8a565b6124288361242283546120de565b836123ad565b6000601f84116001811461247a57600085156124445750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556124f2565b600083815260209020601f19861690835b828110156124ab578685013582556020948501946001909201910161248b565b50868210156124e6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261252e57600080fd5b83018035915067ffffffffffffffff82111561254957600080fd5b6020019150600581901b360382131561185557600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126122e557600080fd5b81356125a081611ad7565b73ffffffffffffffffffffffffffffffffffffffff81167fffffffffffffffffffffffff00000000000000000000000000000000000000008354161782555060018082016020808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261261a57600080fd5b8501803567ffffffffffffffff81111561263357600080fd5b803603838301131561264457600080fd5b6126588161265286546120de565b866123ad565b6000601f8211600181146126ac576000831561267657508382018501355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b178655612723565b600086815260209020601f19841690835b828110156126dc578685018801358255938701939089019087016126bd565b5084821015612719577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c198785880101351681555b50508683881b0186555b50505050505050604082013560028201555050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261276d57600080fd5b830160208101925035905067ffffffffffffffff81111561278d57600080fd5b80360382131561185557600080fd5b81835260006020808501808196508560051b81019150846000805b8881101561285c578385038a5282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18936030181126127f5578283fd5b88016060813561280481611ad7565b73ffffffffffffffffffffffffffffffffffffffff16875261282882890183612738565b828a8a015261283a838a01828461226b565b60409485013599909401989098525050998601999450918501916001016127b7565b509298975050505050505050565b60408152600061287e60408301858761226b565b82810360208401528335612891816120b3565b151581526020848101359082015260408401356128ad81611ad7565b73ffffffffffffffffffffffffffffffffffffffff1660408201526128d56060850185612738565b60a060608401526128ea60a08401828461226b565b91505060808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261292257600080fd5b850160208101903567ffffffffffffffff81111561293f57600080fd5b8060051b360382131561295157600080fd5b838303608085015261296483828461279c565b9998505050505050505050565b80820180821115611ad157611ad1612141565b6000602080835260008454612998816120de565b808487015260406001808416600081146129b957600181146129f157612a1f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a01019550612a1f565b896000528660002060005b85811015612a175781548b82018601529083019088016129fc565b8a0184019650505b50939897505050505050505056fea26469706673582212208d60ccb026b0dcc2e3511887db1b30dfd98f123af2a2a96714cbeca8ed21494464736f6c63430008100033", - "devdoc": { - "events": { - "DripCreated(string,string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))": { - "params": { - "config": "Config for the created drip.", - "name": "Unindexed name parameter (unhashed).", - "nameref": "Indexed name parameter (hashed)." - } - }, - "DripExecuted(string,string,address,uint256)": { - "params": { - "executor": "Address that executed the drip.", - "name": "Unindexed name parameter (unhashed).", - "nameref": "Indexed name parameter (hashed).", - "timestamp": "Time when the drip was executed." - } - }, - "DripStatusUpdated(string,string,uint8)": { - "params": { - "name": "Unindexed name parameter (unhashed).", - "nameref": "Indexed name parameter (hashed).", - "status": "New drip status." - } - } - }, - "kind": "dev", - "methods": { - "CALL(address,bytes,uint256)": { - "params": { - "_data": "Data to send with the call.", - "_target": "Address to call.", - "_value": "ETH value to send with the call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "DELEGATECALL(address,bytes)": { - "params": { - "_data": "Data to send with the call.", - "_target": "Address to call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "constructor": { - "params": { - "_owner": "Initial contract owner." - } - }, - "create(string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))": { - "params": { - "_config": "Configuration for the drip.", - "_name": "Name of the drip." - } - }, - "drip(string)": { - "params": { - "_name": "Name of the drip to trigger." - } - }, - "executable(string)": { - "params": { - "_name": "Drip to check." - }, - "returns": { - "_0": "True if the drip is executable, reverts otherwise." - } - }, - "status(string,uint8)": { - "params": { - "_name": "Name of the drip to update.", - "_status": "New drip status." - } - }, - "withdrawERC20(address,address)": { - "params": { - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC20(address,address,uint256)": { - "params": { - "_amount": "Amount of ERC20 to withdraw.", - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC721(address,address,uint256)": { - "params": { - "_asset": "ERC721 token to withdraw.", - "_id": "Token ID of the ERC721 token to withdraw.", - "_to": "Address to receive the ERC721 token." - } - }, - "withdrawETH(address)": { - "params": { - "_to": "Address to receive the ETH balance." - } - }, - "withdrawETH(address,uint256)": { - "params": { - "_amount": "Amount of ETH to withdraw.", - "_to": "Address to receive the ETH balance." - } - } - }, - "title": "Drippie", - "version": 1 - }, - "userdoc": { - "events": { - "DripCreated(string,string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))": { - "notice": "Emitted when a new drip is created." - }, - "DripExecuted(string,string,address,uint256)": { - "notice": "Emitted when a drip is executed." - }, - "DripStatusUpdated(string,string,uint8)": { - "notice": "Emitted when a drip status is updated." - }, - "ReceivedETH(address,uint256)": { - "notice": "Emitted when ETH is received by this address." - }, - "WithdrewERC20(address,address,address,uint256)": { - "notice": "Emitted when ERC20 tokens are withdrawn from this address." - }, - "WithdrewERC721(address,address,address,uint256)": { - "notice": "Emitted when ERC20 tokens are withdrawn from this address." - }, - "WithdrewETH(address,address,uint256)": { - "notice": "Emitted when ETH is withdrawn from this address." - } - }, - "kind": "user", - "methods": { - "CALL(address,bytes,uint256)": { - "notice": "Sends a CALL to a target address." - }, - "DELEGATECALL(address,bytes)": { - "notice": "Sends a DELEGATECALL to a target address." - }, - "create(string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))": { - "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." - }, - "drip(string)": { - "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. Note that the drip check is executed only **once** at the beginning of the call to the drip function and will not be executed again between the drip actions within this call." - }, - "drips(string)": { - "notice": "Maps from drip names to drip states." - }, - "executable(string)": { - "notice": "Checks if a given drip is executable." - }, - "status(string,uint8)": { - "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." - }, - "withdrawERC20(address,address)": { - "notice": "Withdraws full ERC20 balance to the recipient." - }, - "withdrawERC20(address,address,uint256)": { - "notice": "Withdraws partial ERC20 balance to the recipient." - }, - "withdrawERC721(address,address,uint256)": { - "notice": "Withdraws ERC721 token to the recipient." - }, - "withdrawETH(address)": { - "notice": "Withdraws full ETH balance to the recipient." - }, - "withdrawETH(address,uint256)": { - "notice": "Withdraws partial ETH balance to the recipient." - } - }, - "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.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 10, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 1431, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "drips", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_string_memory_ptr,t_struct(DripState)1394_storage)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_address_payable": { - "encoding": "inplace", - "label": "address payable", - "numberOfBytes": "20" - }, - "t_array(t_struct(DripAction)1369_storage)dyn_storage": { - "base": "t_struct(DripAction)1369_storage", - "encoding": "dynamic_array", - "label": "struct Drippie.DripAction[]", - "numberOfBytes": "32" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_storage": { - "encoding": "bytes", - "label": "bytes", - "numberOfBytes": "32" - }, - "t_contract(IDripCheck)1794": { - "encoding": "inplace", - "label": "contract IDripCheck", - "numberOfBytes": "20" - }, - "t_enum(DripStatus)1362": { - "encoding": "inplace", - "label": "enum Drippie.DripStatus", - "numberOfBytes": "1" - }, - "t_mapping(t_string_memory_ptr,t_struct(DripState)1394_storage)": { - "encoding": "mapping", - "key": "t_string_memory_ptr", - "label": "mapping(string => struct Drippie.DripState)", - "numberOfBytes": "32", - "value": "t_struct(DripState)1394_storage" - }, - "t_string_memory_ptr": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(DripAction)1369_storage": { - "encoding": "inplace", - "label": "struct Drippie.DripAction", - "members": [ - { - "astId": 1364, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "target", - "offset": 0, - "slot": "0", - "type": "t_address_payable" - }, - { - "astId": 1366, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "data", - "offset": 0, - "slot": "1", - "type": "t_bytes_storage" - }, - { - "astId": 1368, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "value", - "offset": 0, - "slot": "2", - "type": "t_uint256" - } - ], - "numberOfBytes": "96" - }, - "t_struct(DripConfig)1383_storage": { - "encoding": "inplace", - "label": "struct Drippie.DripConfig", - "members": [ - { - "astId": 1371, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "reentrant", - "offset": 0, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 1373, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "interval", - "offset": 0, - "slot": "1", - "type": "t_uint256" - }, - { - "astId": 1376, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "dripcheck", - "offset": 0, - "slot": "2", - "type": "t_contract(IDripCheck)1794" - }, - { - "astId": 1378, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "checkparams", - "offset": 0, - "slot": "3", - "type": "t_bytes_storage" - }, - { - "astId": 1382, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "actions", - "offset": 0, - "slot": "4", - "type": "t_array(t_struct(DripAction)1369_storage)dyn_storage" - } - ], - "numberOfBytes": "160" - }, - "t_struct(DripState)1394_storage": { - "encoding": "inplace", - "label": "struct Drippie.DripState", - "members": [ - { - "astId": 1386, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "status", - "offset": 0, - "slot": "0", - "type": "t_enum(DripStatus)1362" - }, - { - "astId": 1389, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "config", - "offset": 0, - "slot": "1", - "type": "t_struct(DripConfig)1383_storage" - }, - { - "astId": 1391, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "last", - "offset": 0, - "slot": "6", - "type": "t_uint256" - }, - { - "astId": 1393, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "count", - "offset": 0, - "slot": "7", - "type": "t_uint256" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/L1CrossDomainMessenger.json b/packages/contracts-bedrock/deployments/goerli/L1CrossDomainMessenger.json deleted file mode 100644 index efb216f3a0fa..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/L1CrossDomainMessenger.json +++ /dev/null @@ -1,772 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "msgHash", - "type": "bytes32" - } - ], - "name": "FailedRelayedMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "msgHash", - "type": "bytes32" - } - ], - "name": "RelayedMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "message", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "messageNonce", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - } - ], - "name": "SentMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "SentMessageExtension1", - "type": "event" - }, - { - "inputs": [], - "name": "MESSAGE_VERSION", - "outputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_CALLDATA_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_MESSENGER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PORTAL", - "outputs": [ - { - "internalType": "contract OptimismPortal", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_CALL_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_CONSTANT_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_GAS_CHECK_BUFFER", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_RESERVED_GAS", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - } - ], - "name": "baseGas", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "failedMessages", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract OptimismPortal", - "name": "_portal", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "messageNonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "portal", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "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": "_minGasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - } - ], - "name": "relayMessage", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - } - ], - "name": "sendMessage", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "successfulMessages", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "xDomainMessageSender", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0xDa2332D0a7608919Cd331B1304Cd179129a90495", - "args": [], - "bytecode": "0x60a06040523480156200001157600080fd5b507342000000000000000000000000000000000000076080526200003660006200003c565b620001ea565b600054600390600160a81b900460ff1615801562000068575060005460ff808316600160a01b90920416105b620000d15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b60008054600160a81b61ffff60a01b19909116600160a01b60ff85160260ff60a81b19161717905560f980546001600160a01b0319166001600160a01b0384161790556200011e62000165565b6000805460ff60a81b1916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054600160a81b900460ff16620001d45760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000c8565b60cc80546001600160a01b03191661dead179055565b608051611cee620002146000396000818161033b0152818161048a01526114ef0152611cee6000f3fe60806040526004361061015f5760003560e01c80636e296e45116100c0578063b1b1b20911610074578063c4d66de811610059578063c4d66de8146103ed578063d764ad0b1461040d578063ecc704281461042057600080fd5b8063b1b1b2091461039d578063b28ade25146103cd57600080fd5b80638cbeeef2116100a55780638cbeeef2146102505780639fce812c14610329578063a4e7f8bd1461035d57600080fd5b80636e296e45146102fd57806383a740741461031257600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146102665780635644cfdf146102bc5780636425666b146102d257600080fd5b80633f827a5a146102285780634c1d6a691461025057600080fd5b80630ff754ea116101485780630ff754ea146101ac5780632828d7e8146101fe5780633dbb202b1461021357600080fd5b8063028f85f7146101645780630c56849814610197575b600080fd5b34801561017057600080fd5b50610179601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101a357600080fd5b50610179603f81565b3480156101b857600080fd5b5060f9546101d99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018e565b34801561020a57600080fd5b50610179604081565b6102266102213660046117ba565b610485565b005b34801561023457600080fd5b5061023d600181565b60405161ffff909116815260200161018e565b34801561025c57600080fd5b50610179619c4081565b34801561027257600080fd5b506102af6040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b60405161018e919061188c565b3480156102c857600080fd5b5061017961138881565b3480156102de57600080fd5b5060f95473ffffffffffffffffffffffffffffffffffffffff166101d9565b34801561030957600080fd5b506101d96106e9565b34801561031e57600080fd5b5061017962030d4081565b34801561033557600080fd5b506101d97f000000000000000000000000000000000000000000000000000000000000000081565b34801561036957600080fd5b5061038d6103783660046118a6565b60ce6020526000908152604090205460ff1681565b604051901515815260200161018e565b3480156103a957600080fd5b5061038d6103b83660046118a6565b60cb6020526000908152604090205460ff1681565b3480156103d957600080fd5b506101796103e83660046118bf565b6107d5565b3480156103f957600080fd5b50610226610408366004611913565b610843565b61022661041b366004611930565b610a47565b34801561042c57600080fd5b5061047760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b60405190815260200161018e565b6105be7f00000000000000000000000000000000000000000000000000000000000000006104b48585856107d5565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061052060cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c60405160240161053c97969594939291906119ff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526112d3565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561064360cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b86604051610655959493929190611a5e565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6107f1604063ffffffff8816611adb565b6107fb9190611b0b565b610806601088611adb565b6108139062030d40611b59565b61081d9190611b59565b6108279190611b59565b6108319190611b59565b61083b9190611b59565b949350505050565b6000546003907501000000000000000000000000000000000000000000900460ff16158015610891575060005460ff8083167401000000000000000000000000000000000000000090920416105b61091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107af565b6000805475010000000000000000000000000000000000000000007fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000060ff8516027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff161717905560f980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556109e561136c565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60f087901c60028110610b02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107af565b8061ffff16600003610bf7576000610b53878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250611445915050565b600081815260cb602052604090205490915060ff1615610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107af565b505b6000610c3d898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146492505050565b9050610c47611487565b15610c7f57853414610c5b57610c5b611b85565b600081815260ce602052604090205460ff1615610c7a57610c7a611b85565b610dd1565b3415610d33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107af565b600081815260ce602052604090205460ff16610dd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107af565b610dda8761157d565b15610e8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107af565b600081815260cb602052604090205460ff1615610f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107af565b610f4d85610f3e611388619c40611b59565b67ffffffffffffffff166115c3565b1580610f73575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561108c57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b50506112c5565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061111d88619c405a6110e09190611bb4565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115e192505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111b457600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112c1565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b5050505b50505050505050565b905090565b60f9546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611334908890839089906000908990600401611bcb565b6000604051808303818588803b15801561134d57600080fd5b505af1158015611361573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107af565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611453858585856115fb565b805190602001209050949350505050565b6000611474878787878787611694565b8051906020012090509695505050505050565b60f95460009073ffffffffffffffffffffffffffffffffffffffff16331480156112ce575060f954604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691639bf62d829160048083019260209291908290030181865afa15801561153d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115619190611c23565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff82163014806115bd575060f95473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116149493929190611c40565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60608686868686866040516024016116b196959493929190611c8a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461175557600080fd5b50565b60008083601f84011261176a57600080fd5b50813567ffffffffffffffff81111561178257600080fd5b60208301915083602082850101111561179a57600080fd5b9250929050565b803563ffffffff811681146117b557600080fd5b919050565b600080600080606085870312156117d057600080fd5b84356117db81611733565b9350602085013567ffffffffffffffff8111156117f757600080fd5b61180387828801611758565b90945092506118169050604086016117a1565b905092959194509250565b6000815180845260005b818110156118475760208185018101518683018201520161182b565b81811115611859576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061189f6020830184611821565b9392505050565b6000602082840312156118b857600080fd5b5035919050565b6000806000604084860312156118d457600080fd5b833567ffffffffffffffff8111156118eb57600080fd5b6118f786828701611758565b909450925061190a9050602085016117a1565b90509250925092565b60006020828403121561192557600080fd5b813561189f81611733565b600080600080600080600060c0888a03121561194b57600080fd5b87359650602088013561195d81611733565b9550604088013561196d81611733565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561199757600080fd5b6119a38a828b01611758565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611a5160c0830184866119b6565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611a8e6080830186886119b6565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611b0257611b02611aac565b02949350505050565b600067ffffffffffffffff80841680611b4d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b7c57611b7c611aac565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611bc657611bc6611aac565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611c1860a0830184611821565b979650505050505050565b600060208284031215611c3557600080fd5b815161189f81611733565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611c796080830185611821565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611cd560c0830184611821565b9897505050505050505056fea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061015f5760003560e01c80636e296e45116100c0578063b1b1b20911610074578063c4d66de811610059578063c4d66de8146103ed578063d764ad0b1461040d578063ecc704281461042057600080fd5b8063b1b1b2091461039d578063b28ade25146103cd57600080fd5b80638cbeeef2116100a55780638cbeeef2146102505780639fce812c14610329578063a4e7f8bd1461035d57600080fd5b80636e296e45146102fd57806383a740741461031257600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146102665780635644cfdf146102bc5780636425666b146102d257600080fd5b80633f827a5a146102285780634c1d6a691461025057600080fd5b80630ff754ea116101485780630ff754ea146101ac5780632828d7e8146101fe5780633dbb202b1461021357600080fd5b8063028f85f7146101645780630c56849814610197575b600080fd5b34801561017057600080fd5b50610179601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101a357600080fd5b50610179603f81565b3480156101b857600080fd5b5060f9546101d99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018e565b34801561020a57600080fd5b50610179604081565b6102266102213660046117ba565b610485565b005b34801561023457600080fd5b5061023d600181565b60405161ffff909116815260200161018e565b34801561025c57600080fd5b50610179619c4081565b34801561027257600080fd5b506102af6040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b60405161018e919061188c565b3480156102c857600080fd5b5061017961138881565b3480156102de57600080fd5b5060f95473ffffffffffffffffffffffffffffffffffffffff166101d9565b34801561030957600080fd5b506101d96106e9565b34801561031e57600080fd5b5061017962030d4081565b34801561033557600080fd5b506101d97f000000000000000000000000000000000000000000000000000000000000000081565b34801561036957600080fd5b5061038d6103783660046118a6565b60ce6020526000908152604090205460ff1681565b604051901515815260200161018e565b3480156103a957600080fd5b5061038d6103b83660046118a6565b60cb6020526000908152604090205460ff1681565b3480156103d957600080fd5b506101796103e83660046118bf565b6107d5565b3480156103f957600080fd5b50610226610408366004611913565b610843565b61022661041b366004611930565b610a47565b34801561042c57600080fd5b5061047760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b60405190815260200161018e565b6105be7f00000000000000000000000000000000000000000000000000000000000000006104b48585856107d5565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061052060cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c60405160240161053c97969594939291906119ff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526112d3565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561064360cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b86604051610655959493929190611a5e565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6107f1604063ffffffff8816611adb565b6107fb9190611b0b565b610806601088611adb565b6108139062030d40611b59565b61081d9190611b59565b6108279190611b59565b6108319190611b59565b61083b9190611b59565b949350505050565b6000546003907501000000000000000000000000000000000000000000900460ff16158015610891575060005460ff8083167401000000000000000000000000000000000000000090920416105b61091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107af565b6000805475010000000000000000000000000000000000000000007fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000060ff8516027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff161717905560f980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556109e561136c565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60f087901c60028110610b02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107af565b8061ffff16600003610bf7576000610b53878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250611445915050565b600081815260cb602052604090205490915060ff1615610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107af565b505b6000610c3d898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146492505050565b9050610c47611487565b15610c7f57853414610c5b57610c5b611b85565b600081815260ce602052604090205460ff1615610c7a57610c7a611b85565b610dd1565b3415610d33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107af565b600081815260ce602052604090205460ff16610dd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107af565b610dda8761157d565b15610e8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107af565b600081815260cb602052604090205460ff1615610f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107af565b610f4d85610f3e611388619c40611b59565b67ffffffffffffffff166115c3565b1580610f73575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561108c57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b50506112c5565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061111d88619c405a6110e09190611bb4565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115e192505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111b457600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112c1565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b5050505b50505050505050565b905090565b60f9546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611334908890839089906000908990600401611bcb565b6000604051808303818588803b15801561134d57600080fd5b505af1158015611361573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107af565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611453858585856115fb565b805190602001209050949350505050565b6000611474878787878787611694565b8051906020012090509695505050505050565b60f95460009073ffffffffffffffffffffffffffffffffffffffff16331480156112ce575060f954604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691639bf62d829160048083019260209291908290030181865afa15801561153d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115619190611c23565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff82163014806115bd575060f95473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116149493929190611c40565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60608686868686866040516024016116b196959493929190611c8a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461175557600080fd5b50565b60008083601f84011261176a57600080fd5b50813567ffffffffffffffff81111561178257600080fd5b60208301915083602082850101111561179a57600080fd5b9250929050565b803563ffffffff811681146117b557600080fd5b919050565b600080600080606085870312156117d057600080fd5b84356117db81611733565b9350602085013567ffffffffffffffff8111156117f757600080fd5b61180387828801611758565b90945092506118169050604086016117a1565b905092959194509250565b6000815180845260005b818110156118475760208185018101518683018201520161182b565b81811115611859576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061189f6020830184611821565b9392505050565b6000602082840312156118b857600080fd5b5035919050565b6000806000604084860312156118d457600080fd5b833567ffffffffffffffff8111156118eb57600080fd5b6118f786828701611758565b909450925061190a9050602085016117a1565b90509250925092565b60006020828403121561192557600080fd5b813561189f81611733565b600080600080600080600060c0888a03121561194b57600080fd5b87359650602088013561195d81611733565b9550604088013561196d81611733565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561199757600080fd5b6119a38a828b01611758565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611a5160c0830184866119b6565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611a8e6080830186886119b6565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611b0257611b02611aac565b02949350505050565b600067ffffffffffffffff80841680611b4d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b7c57611b7c611aac565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611bc657611bc6611aac565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611c1860a0830184611821565b979650505050505050565b600060208284031215611c3557600080fd5b815161189f81611733565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611c796080830185611821565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611cd560c0830184611821565b9897505050505050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "baseGas(bytes,uint32)": { - "params": { - "_message": "Message to compute the amount of required gas for.", - "_minGasLimit": "Minimum desired gas limit when message goes to target." - }, - "returns": { - "_0": "Amount of gas required to guarantee message receipt." - } - }, - "initialize(address)": { - "params": { - "_portal": "Address of the OptimismPortal contract on this network." - } - }, - "messageNonce()": { - "returns": { - "_0": "Nonce of the next message to be sent, with added message version." - } - }, - "relayMessage(uint256,address,address,uint256,uint256,bytes)": { - "params": { - "_message": "Message to send to the target.", - "_minGasLimit": "Minimum amount of gas that the message can be executed with.", - "_nonce": "Nonce of the message being relayed.", - "_sender": "Address of the user who sent the message.", - "_target": "Address that the message is targeted at.", - "_value": "ETH value to send with the message." - } - }, - "sendMessage(address,bytes,uint32)": { - "params": { - "_message": "Message to trigger the target address with.", - "_minGasLimit": "Minimum gas limit that the message can be executed with.", - "_target": "Target contract or wallet address." - } - }, - "xDomainMessageSender()": { - "returns": { - "_0": "Address of the sender of the currently executing message on the other chain." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true}],\"type\":\"event\",\"name\":\"FailedRelayedMessage\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true}],\"type\":\"event\",\"name\":\"RelayedMessage\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\",\"indexed\":false}],\"type\":\"event\",\"name\":\"SentMessage\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false}],\"type\":\"event\",\"name\":\"SentMessageExtension1\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"PORTAL\",\"outputs\":[{\"internalType\":\"contract OptimismPortal\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_CALL_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_RESERVED_GAS\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"contract OptimismPortal\",\"name\":\"_portal\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"portal\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"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\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"relayMessage\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"sendMessage\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"baseGas(bytes,uint32)\":{\"params\":{\"_message\":\"Message to compute the amount of required gas for.\",\"_minGasLimit\":\"Minimum desired gas limit when message goes to target.\"},\"returns\":{\"_0\":\"Amount of gas required to guarantee message receipt.\"}},\"initialize(address)\":{\"params\":{\"_portal\":\"Address of the OptimismPortal contract on this network.\"}},\"messageNonce()\":{\"returns\":{\"_0\":\"Nonce of the next message to be sent, with added message version.\"}},\"relayMessage(uint256,address,address,uint256,uint256,bytes)\":{\"params\":{\"_message\":\"Message to send to the target.\",\"_minGasLimit\":\"Minimum amount of gas that the message can be executed with.\",\"_nonce\":\"Nonce of the message being relayed.\",\"_sender\":\"Address of the user who sent the message.\",\"_target\":\"Address that the message is targeted at.\",\"_value\":\"ETH value to send with the message.\"}},\"sendMessage(address,bytes,uint32)\":{\"params\":{\"_message\":\"Message to trigger the target address with.\",\"_minGasLimit\":\"Minimum gas limit that the message can be executed with.\",\"_target\":\"Target contract or wallet address.\"}},\"xDomainMessageSender()\":{\"returns\":{\"_0\":\"Address of the sender of the currently executing message on the other chain.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"MESSAGE_VERSION()\":{\"notice\":\"Current message version identifier.\"},\"MIN_GAS_CALLDATA_OVERHEAD()\":{\"notice\":\"Extra gas added to base gas for each byte of calldata in a message.\"},\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()\":{\"notice\":\"Denominator for dynamic overhead added to the base gas for a message.\"},\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR()\":{\"notice\":\"Numerator for dynamic overhead added to the base gas for a message.\"},\"OTHER_MESSENGER()\":{\"notice\":\"Address of the paired CrossDomainMessenger contract on the other chain.\"},\"PORTAL()\":{\"notice\":\"Address of the OptimismPortal. The public getter for this is legacy and will be removed in the future. Use `portal()` instead.\"},\"RELAY_CALL_OVERHEAD()\":{\"notice\":\"Gas reserved for performing the external call in `relayMessage`.\"},\"RELAY_CONSTANT_OVERHEAD()\":{\"notice\":\"Constant overhead added to the base gas for a message.\"},\"RELAY_GAS_CHECK_BUFFER()\":{\"notice\":\"Gas reserved for the execution between the `hasMinGas` check and the external call in `relayMessage`.\"},\"RELAY_RESERVED_GAS()\":{\"notice\":\"Gas reserved for finalizing the execution of `relayMessage` after the safe call.\"},\"baseGas(bytes,uint32)\":{\"notice\":\"Computes the amount of gas required to guarantee that a given message will be received on the other chain without running out of gas. Guaranteeing that a message will not run out of gas is important because this ensures that a message can always be replayed on the other chain if it fails to execute completely.\"},\"constructor\":{\"notice\":\"Constructs the L1CrossDomainMessenger contract.\"},\"failedMessages(bytes32)\":{\"notice\":\"Mapping of message hashes to a boolean if and only if the message has failed to be executed at least once. A message will not be present in this mapping if it successfully executed on the first attempt.\"},\"initialize(address)\":{\"notice\":\"Initializes the contract.\"},\"messageNonce()\":{\"notice\":\"Retrieves the next message nonce. Message version will be added to the upper two bytes of the message nonce. Message version allows us to treat messages as having different structures.\"},\"portal()\":{\"notice\":\"Getter for the OptimismPortal address.\"},\"relayMessage(uint256,address,address,uint256,uint256,bytes)\":{\"notice\":\"Relays a message that was sent by the other CrossDomainMessenger contract. Can only be executed via cross-chain call from the other messenger OR if the message was already received once and is currently being replayed.\"},\"sendMessage(address,bytes,uint32)\":{\"notice\":\"Sends a message to some target address on the other chain. Note that if the call always reverts, then the message will be unrelayable, and any ETH sent will be permanently locked. The same will occur if the target on the other chain is considered unsafe (see the _isUnsafeTarget() function).\"},\"successfulMessages(bytes32)\":{\"notice\":\"Mapping of message hashes to boolean receipt values. Note that a message will only be present in this mapping if it has successfully been relayed on this chain, and can therefore not be relayed again.\"},\"version()\":{\"notice\":\"Semantic version.\"},\"xDomainMessageSender()\":{\"notice\":\"Retrieves the address of the contract or wallet that initiated the currently executing message on the other chain. Will throw an error if there is no message currently being executed. Allows the recipient of a call to see who triggered it.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L1CrossDomainMessenger.sol\":\"L1CrossDomainMessenger\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L1CrossDomainMessenger.sol\":{\"keccak256\":\"0xe3fdf4102a94b9383f1ca917499ffeb8dd9be6317ef4ed9626a5ff44daf54461\",\"urls\":[\"bzz-raw://1c1a5f8612f0b170350e2436a64695c3e7fffd04ea1a617a64eacd4d2342a07c\",\"dweb:/ipfs/QmdoehaP6a9kyWR73LqRdqSCShiXKePwM7WJedwikvYR1w\"],\"license\":\"MIT\"},\"src/L1/L2OutputOracle.sol\":{\"keccak256\":\"0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705\",\"urls\":[\"bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc\",\"dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN\"],\"license\":\"MIT\"},\"src/L1/OptimismPortal.sol\":{\"keccak256\":\"0xdca91a921b402d82b455d7f11027514e8a16dca906cf820b3afffe271beb8a13\",\"urls\":[\"bzz-raw://688912b9d6005af8395d5c2eb5c4e3367a8be7b50ea97c34fc6a7ac0e2d8fd6a\",\"dweb:/ipfs/QmNPJDwHpNmJ5VPWAJB8muRpZxYeySZDVoV1TMVN7roijJ\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L1/SystemConfig.sol\":{\"keccak256\":\"0x2b4005c512ab947da105305e3db913b0d7884a954d0aa602f90f7b02188dcda6\",\"urls\":[\"bzz-raw://cc68c9ec4e1aebdd9dba39c7516d38e40a4472b708dfaca1fb9a4742d346db47\",\"dweb:/ipfs/QmX8moXk9cb47tRefi6q15oQAAt18MHEdQojWhrXxz5ykK\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Bytes.sol\":{\"keccak256\":\"0x827f47d123b0fdf3b08816d5b33831811704dbf4e554e53f2269354f6bba8859\",\"urls\":[\"bzz-raw://3137ac7204d30a245a8b0d67aa6da5286f1bd8c90379daab561f84963b6db782\",\"dweb:/ipfs/QmWRhisw3axJK833gUScs23ETh2MLFbVzzqzYVMKSDN3S9\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/Predeploys.sol\":{\"keccak256\":\"0x5af3a849f68f7c9108858ebac5c769da8f1c0309b5c0cb42eb5cbb15e3fe6058\",\"urls\":[\"bzz-raw://6ffe76429a96d274577be66627eddad5cd05ad36d0cb6b9b3c3f9fa8a609dd7e\",\"dweb:/ipfs/QmVhWnB7Avg684TEQ9BExWqSN1YfLehUTWoqpjymeQEQHm\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x9ba74a3b0a11693e622380807d213d5d1250d974e18b2cd768da9cbe719a6778\",\"urls\":[\"bzz-raw://0808d721ed9e05707526ee134faa051d707a95ee6b8bd6e0b1972275da8e5723\",\"dweb:/ipfs/QmcTTPu9xgckfWdbFUAcr2RAgk3J6vzyR4FpV798TjFMeN\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xf8ba770ee6666e73ae43184c700e9c704b2c4ace71f9e3c2227ddc11a8148b4c\",\"urls\":[\"bzz-raw://4702ccee1fe44aea3ee01d59e6152eb755da083f786f00947fec4437c064fe74\",\"dweb:/ipfs/QmQjFj5J7hrEM1dxJjFszzW2Cs7g7eMhYNBXonF2DXBstE\"],\"license\":\"MIT\"},\"src/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0xeaff8315cfd21197bc6bc859c2decf5d4f4838c9c357c502cdf2b1eac863d288\",\"urls\":[\"bzz-raw://79dcdcaa560aea51d138da4f5dc553a1808b6de090b2dc1629f18375edbff681\",\"dweb:/ipfs/QmbE4pUPhf5fLKW4W6cEjhQs55gEDvHmbmoBqkW1yz3bnw\"],\"license\":\"MIT\"},\"src/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x4302ae78bcafde2737d4048bbf8fdb3dd4cd7254c015b91dfa14fdaafd412f4a\",\"urls\":[\"bzz-raw://78d3d1823ad4e1fba15921a0a361b452c85d111e2d53cbbed11a8632782ea8f3\",\"dweb:/ipfs/QmVc2rTRpn7g7WAUxDShSuy6dY5zmtbJ7hHC6sT9PcD3Gj\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"],\"license\":\"Apache-2.0\"}},\"version\":1}", - "numDeployments": 4, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 75492, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_0_0_20", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 29536, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "_initialized", - "offset": 20, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 29539, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "_initializing", - "offset": 21, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 75499, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_1_0_1600", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 75502, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_51_0_20", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 75507, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_52_0_1568", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 75510, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_101_0_1", - "offset": 0, - "slot": "101", - "type": "t_bool" - }, - { - "astId": 75515, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_102_0_1568", - "offset": 0, - "slot": "102", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 75518, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_151_0_32", - "offset": 0, - "slot": "151", - "type": "t_uint256" - }, - { - "astId": 75523, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_152_0_1568", - "offset": 0, - "slot": "152", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 75528, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_201_0_32", - "offset": 0, - "slot": "201", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75533, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_202_0_32", - "offset": 0, - "slot": "202", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75581, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "successfulMessages", - "offset": 0, - "slot": "203", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75584, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "xDomainMsgSender", - "offset": 0, - "slot": "204", - "type": "t_address" - }, - { - "astId": 75587, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "msgNonce", - "offset": 0, - "slot": "205", - "type": "t_uint240" - }, - { - "astId": 75592, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "failedMessages", - "offset": 0, - "slot": "206", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75597, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "__gap", - "offset": 0, - "slot": "207", - "type": "t_array(t_uint256)42_storage" - }, - { - "astId": 58828, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "PORTAL", - "offset": 0, - "slot": "249", - "type": "t_contract(OptimismPortal)60892" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)42_storage": { - "encoding": "inplace", - "label": "uint256[42]", - "numberOfBytes": "1344", - "base": "t_uint256" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_contract(OptimismPortal)60892": { - "encoding": "inplace", - "label": "contract OptimismPortal", - "numberOfBytes": "20" - }, - "t_mapping(t_bytes32,t_bool)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_uint240": { - "encoding": "inplace", - "label": "uint240", - "numberOfBytes": "30" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x93e9104cda59b927c1ccc9d7db759149d49d0fe93ec7290bed8cf813be222bc0", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSAGE_VERSION()": { - "notice": "Current message version identifier." - }, - "MIN_GAS_CALLDATA_OVERHEAD()": { - "notice": "Extra gas added to base gas for each byte of calldata in a message." - }, - "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()": { - "notice": "Denominator for dynamic overhead added to the base gas for a message." - }, - "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR()": { - "notice": "Numerator for dynamic overhead added to the base gas for a message." - }, - "OTHER_MESSENGER()": { - "notice": "Address of the paired CrossDomainMessenger contract on the other chain." - }, - "PORTAL()": { - "notice": "Address of the OptimismPortal. The public getter for this is legacy and will be removed in the future. Use `portal()` instead." - }, - "RELAY_CALL_OVERHEAD()": { - "notice": "Gas reserved for performing the external call in `relayMessage`." - }, - "RELAY_CONSTANT_OVERHEAD()": { - "notice": "Constant overhead added to the base gas for a message." - }, - "RELAY_GAS_CHECK_BUFFER()": { - "notice": "Gas reserved for the execution between the `hasMinGas` check and the external call in `relayMessage`." - }, - "RELAY_RESERVED_GAS()": { - "notice": "Gas reserved for finalizing the execution of `relayMessage` after the safe call." - }, - "baseGas(bytes,uint32)": { - "notice": "Computes the amount of gas required to guarantee that a given message will be received on the other chain without running out of gas. Guaranteeing that a message will not run out of gas is important because this ensures that a message can always be replayed on the other chain if it fails to execute completely." - }, - "constructor": { - "notice": "Constructs the L1CrossDomainMessenger contract." - }, - "failedMessages(bytes32)": { - "notice": "Mapping of message hashes to a boolean if and only if the message has failed to be executed at least once. A message will not be present in this mapping if it successfully executed on the first attempt." - }, - "initialize(address)": { - "notice": "Initializes the contract." - }, - "messageNonce()": { - "notice": "Retrieves the next message nonce. Message version will be added to the upper two bytes of the message nonce. Message version allows us to treat messages as having different structures." - }, - "portal()": { - "notice": "Getter for the OptimismPortal address." - }, - "relayMessage(uint256,address,address,uint256,uint256,bytes)": { - "notice": "Relays a message that was sent by the other CrossDomainMessenger contract. Can only be executed via cross-chain call from the other messenger OR if the message was already received once and is currently being replayed." - }, - "sendMessage(address,bytes,uint32)": { - "notice": "Sends a message to some target address on the other chain. Note that if the call always reverts, then the message will be unrelayable, and any ETH sent will be permanently locked. The same will occur if the target on the other chain is considered unsafe (see the _isUnsafeTarget() function)." - }, - "successfulMessages(bytes32)": { - "notice": "Mapping of message hashes to boolean receipt values. Note that a message will only be present in this mapping if it has successfully been relayed on this chain, and can therefore not be relayed again." - }, - "version()": { - "notice": "Semantic version." - }, - "xDomainMessageSender()": { - "notice": "Retrieves the address of the contract or wallet that initiated the currently executing message on the other chain. Will throw an error if there is no message currently being executed. Allows the recipient of a call to see who triggered it." - } - }, - "events": { - "FailedRelayedMessage(bytes32)": { - "notice": "Emitted whenever a message fails to be relayed on this chain." - }, - "RelayedMessage(bytes32)": { - "notice": "Emitted whenever a message is successfully relayed on this chain." - }, - "SentMessage(address,address,bytes,uint256,uint256)": { - "notice": "Emitted whenever a message is sent to the other chain." - }, - "SentMessageExtension1(address,uint256)": { - "notice": "Additional event data to emit, required as of Bedrock. Cannot be merged with the SentMessage event without breaking the ABI of this contract, this is good enough." - } - }, - "notice": "The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible for sending and receiving data on the L1 side. Users are encouraged to use this interface instead of interacting with lower-level contracts directly." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/L1CrossDomainMessengerProxy.json b/packages/contracts-bedrock/deployments/goerli/L1CrossDomainMessengerProxy.json deleted file mode 100644 index 1ea3f212cbde..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/L1CrossDomainMessengerProxy.json +++ /dev/null @@ -1,119 +0,0 @@ -{ - "address": "0x5086d1eEF304eb5284A0f6720f79403b4e9bE294", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_libAddressManager", - "type": "address" - }, - { - "internalType": "string", - "name": "_implementationName", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "stateMutability": "payable", - "type": "fallback" - } - ], - "transactionHash": "0xc547cd677c4bcb87deead498c827b1dfcfd5d14826f58a0f7416a46024a03e85", - "receipt": { - "to": null, - "from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31", - "contractAddress": "0x5086d1eEF304eb5284A0f6720f79403b4e9bE294", - "transactionIndex": 13, - "gasUsed": "291461", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x3e18927a7be75d3ac2b6f54f8c40d781756e78327f9cedd8dff5e79dd49403ff", - "transactionHash": "0xc547cd677c4bcb87deead498c827b1dfcfd5d14826f58a0f7416a46024a03e85", - "logs": [], - "blockNumber": 7017129, - "cumulativeGasUsed": "1033610", - "status": 1, - "byzantium": true - }, - "args": [ - "0xa6f73589243a6A7a9023b1Fa0651b1d89c177111", - "OVM_L1CrossDomainMessenger" - ], - "numDeployments": 1, - "solcInputHash": "76c096070f4b72a86045eb6ab63709ed", - "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_implementationName\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_implementationName\":\"implementationName of the contract to proxy to.\",\"_libAddressManager\":\"Address of the Lib_AddressManager.\"}}},\"title\":\"Lib_ResolvedDelegateProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol\":\"Lib_ResolvedDelegateProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_ResolvedDelegateProxy\\n */\\ncontract Lib_ResolvedDelegateProxy {\\n /*************\\n * Variables *\\n *************/\\n\\n // Using mappings to store fields to avoid overwriting storage slots in the\\n // implementation contract. For example, instead of storing these fields at\\n // storage slot `0` & `1`, they are stored at `keccak256(key + slot)`.\\n // See: https://solidity.readthedocs.io/en/v0.7.0/internals/layout_in_storage.html\\n // NOTE: Do not use this code in your own contract system.\\n // There is a known flaw in this contract, and we will remove it from the repository\\n // in the near future. Due to the very limited way that we are using it, this flaw is\\n // not an issue in our system.\\n mapping(address => string) private implementationName;\\n mapping(address => Lib_AddressManager) private addressManager;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Lib_AddressManager.\\n * @param _implementationName implementationName of the contract to proxy to.\\n */\\n constructor(address _libAddressManager, string memory _implementationName) {\\n addressManager[address(this)] = Lib_AddressManager(_libAddressManager);\\n implementationName[address(this)] = _implementationName;\\n }\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n fallback() external payable {\\n address target = addressManager[address(this)].getAddress(\\n (implementationName[address(this)])\\n );\\n\\n require(target != address(0), \\\"Target address must be initialized.\\\");\\n\\n // slither-disable-next-line controlled-delegatecall\\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\\n\\n if (success == true) {\\n assembly {\\n return(add(returndata, 0x20), mload(returndata))\\n }\\n } else {\\n assembly {\\n revert(add(returndata, 0x20), mload(returndata))\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x987774d18365ed25f5be61198e8b241728db6f97c6f2496f4a35bf9dbe0bda2b\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506040516105b53803806105b583398101604081905261002f91610125565b30600090815260016020908152604080832080546001600160a01b0319166001600160a01b038716179055828252909120825161006e92840190610076565b505050610252565b82805461008290610217565b90600052602060002090601f0160209004810192826100a457600085556100ea565b82601f106100bd57805160ff19168380011785556100ea565b828001600101855582156100ea579182015b828111156100ea5782518255916020019190600101906100cf565b506100f69291506100fa565b5090565b5b808211156100f657600081556001016100fb565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561013857600080fd5b82516001600160a01b038116811461014f57600080fd5b602084810151919350906001600160401b038082111561016e57600080fd5b818601915086601f83011261018257600080fd5b8151818111156101945761019461010f565b604051601f8201601f19908116603f011681019083821181831017156101bc576101bc61010f565b8160405282815289868487010111156101d457600080fd5b600093505b828410156101f657848401860151818501870152928501926101d9565b828411156102075760008684830101525b8096505050505050509250929050565b600181811c9082168061022b57607f821691505b6020821081141561024c57634e487b7160e01b600052602260045260246000fd5b50919050565b610354806102616000396000f3fe608060408181523060009081526001602090815282822054908290529181207fbf40fac1000000000000000000000000000000000000000000000000000000009093529173ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061006d9060846101f2565b60206040518083038186803b15801561008557600080fd5b505afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906102d1565b905073ffffffffffffffffffffffffffffffffffffffff8116610166576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5461726765742061646472657373206d75737420626520696e697469616c697a60448201527f65642e0000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1660003660405161019192919061030e565b600060405180830381855af49150503d80600081146101cc576040519150601f19603f3d011682016040523d82523d6000602084013e6101d1565b606091505b509092509050600182151514156101ea57805160208201f35b805160208201fd5b600060208083526000845481600182811c91508083168061021457607f831692505b85831081141561024b577f4e487b710000000000000000000000000000000000000000000000000000000085526022600452602485fd5b8786018381526020018180156102685760018114610297576102c2565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616825287820196506102c2565b60008b81526020902060005b868110156102bc578154848201529085019089016102a3565b83019750505b50949998505050505050505050565b6000602082840312156102e357600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461030757600080fd5b9392505050565b818382376000910190815291905056fea2646970667358221220d66a7dad92a7f7528f41181719174e1d244423b8bb730d2884645c76cfa0944064736f6c63430008090033", - "deployedBytecode": "0x608060408181523060009081526001602090815282822054908290529181207fbf40fac1000000000000000000000000000000000000000000000000000000009093529173ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061006d9060846101f2565b60206040518083038186803b15801561008557600080fd5b505afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906102d1565b905073ffffffffffffffffffffffffffffffffffffffff8116610166576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5461726765742061646472657373206d75737420626520696e697469616c697a60448201527f65642e0000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1660003660405161019192919061030e565b600060405180830381855af49150503d80600081146101cc576040519150601f19603f3d011682016040523d82523d6000602084013e6101d1565b606091505b509092509050600182151514156101ea57805160208201f35b805160208201fd5b600060208083526000845481600182811c91508083168061021457607f831692505b85831081141561024b577f4e487b710000000000000000000000000000000000000000000000000000000085526022600452602485fd5b8786018381526020018180156102685760018114610297576102c2565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616825287820196506102c2565b60008b81526020902060005b868110156102bc578154848201529085019089016102a3565b83019750505b50949998505050505050505050565b6000602082840312156102e357600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461030757600080fd5b9392505050565b818382376000910190815291905056fea2646970667358221220d66a7dad92a7f7528f41181719174e1d244423b8bb730d2884645c76cfa0944064736f6c63430008090033", - "devdoc": { - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_implementationName": "implementationName of the contract to proxy to.", - "_libAddressManager": "Address of the Lib_AddressManager." - } - } - }, - "title": "Lib_ResolvedDelegateProxy", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 7129, - "contract": "contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol:Lib_ResolvedDelegateProxy", - "label": "implementationName", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_address,t_string_storage)" - }, - { - "astId": 7134, - "contract": "contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol:Lib_ResolvedDelegateProxy", - "label": "addressManager", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_address,t_contract(Lib_AddressManager)7084)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_contract(Lib_AddressManager)7084": { - "encoding": "inplace", - "label": "contract Lib_AddressManager", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_contract(Lib_AddressManager)7084)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => contract Lib_AddressManager)", - "numberOfBytes": "32", - "value": "t_contract(Lib_AddressManager)7084" - }, - "t_mapping(t_address,t_string_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => string)", - "numberOfBytes": "32", - "value": "t_string_storage" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/L1ERC721Bridge.json b/packages/contracts-bedrock/deployments/goerli/L1ERC721Bridge.json deleted file mode 100644 index de86c406ab20..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/L1ERC721Bridge.json +++ /dev/null @@ -1,525 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC721BridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC721BridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "inputs": [], - "name": "MESSENGER", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_BRIDGE", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC721To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "deposits", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "_messenger", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "messenger", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "otherBridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x806C2d0d2BDDFf9279CB2A8722F9117f0b0aDE73", - "args": [], - "bytecode": "0x60a060405234801561001057600080fd5b50734200000000000000000000000000000000000014610034565b60405180910390fd5b6001600160a01b031660805261004a600061004f565b6101cb565b600054600390610100900460ff16158015610071575060005460ff8083169116105b6100d45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161002b565b6000805461ffff191660ff8316176101001790556100f182610136565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054610100900460ff166101a15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161002b565b600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6080516112116101fb600039600081816101cd0152818161023b015281816103350152610bf101526112116000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80637f46ddb211610076578063aa5574521161005b578063aa55745214610213578063c4d66de814610226578063c89701a21461023957600080fd5b80637f46ddb2146101c8578063927ede2d146101ef57600080fd5b806354fd4d50116100a757806354fd4d50146101285780635d93a3fc14610171578063761f4493146101b557600080fd5b80633687011a146100c35780633cb747bf146100d8575b600080fd5b6100d66100d1366004610e47565b61025f565b005b6000546100fe9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101646040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b60405161011f9190610f35565b6101a561017f366004610f4f565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b604051901515815260200161011f565b6100d66101c3366004610f90565b61030b565b6100fe7f000000000000000000000000000000000000000000000000000000000000000081565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166100fe565b6100d6610221366004611028565b610776565b6100d661023436600461109f565b610832565b7f00000000000000000000000000000000000000000000000000000000000000006100fe565b333b156102f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b610303868633338888888861097c565b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314801561041357507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fb91906110bc565b73ffffffffffffffffffffffffffffffffffffffff16145b61049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f74686572206272696467650060648201526084016102ea565b3073ffffffffffffffffffffffffffffffffffffffff881603610544576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff161515600114610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c31204272696467650000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156106d357600080fd5b505af11580156106e7573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107659493929190611122565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f7420626520616464726573732830290000000000000000000000000000000060648201526084016102ea565b610829878733888888888861097c565b50505050505050565b600054600390610100900460ff16158015610854575060005460ff8083169116105b6108e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016102ea565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561091a82610cdc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b73ffffffffffffffffffffffffffffffffffffffff8716610a1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f74206265206164647265737328302900000000000000000000000000000060648201526084016102ea565b600063761f449360e01b888a8989898888604051602401610a469796959493929190611162565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610b8657600080fd5b505af1158015610b9a573d6000803e3d6000fd5b50506000546040517f3dbb202b0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169250633dbb202b9150610c1d907f000000000000000000000000000000000000000000000000000000000000000090859089906004016111bf565b600060405180830381600087803b158015610c3757600080fd5b505af1158015610c4b573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610cc99493929190611122565b60405180910390a4505050505050505050565b600054610100900460ff16610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ea565b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610de257600080fd5b50565b803563ffffffff81168114610df957600080fd5b919050565b60008083601f840112610e1057600080fd5b50813567ffffffffffffffff811115610e2857600080fd5b602083019150836020828501011115610e4057600080fd5b9250929050565b60008060008060008060a08789031215610e6057600080fd5b8635610e6b81610dc0565b95506020870135610e7b81610dc0565b945060408701359350610e9060608801610de5565b9250608087013567ffffffffffffffff811115610eac57600080fd5b610eb889828a01610dfe565b979a9699509497509295939492505050565b6000815180845260005b81811015610ef057602081850181015186830182015201610ed4565b81811115610f02576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f486020830184610eca565b9392505050565b600080600060608486031215610f6457600080fd5b8335610f6f81610dc0565b92506020840135610f7f81610dc0565b929592945050506040919091013590565b600080600080600080600060c0888a031215610fab57600080fd5b8735610fb681610dc0565b96506020880135610fc681610dc0565b95506040880135610fd681610dc0565b94506060880135610fe681610dc0565b93506080880135925060a088013567ffffffffffffffff81111561100957600080fd5b6110158a828b01610dfe565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561104357600080fd5b873561104e81610dc0565b9650602088013561105e81610dc0565b9550604088013561106e81610dc0565b94506060880135935061108360808901610de5565b925060a088013567ffffffffffffffff81111561100957600080fd5b6000602082840312156110b157600080fd5b8135610f4881610dc0565b6000602082840312156110ce57600080fd5b8151610f4881610dc0565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006111586060830184866110d9565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a08301526111b260c0830184866110d9565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006111ee6060830185610eca565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c80637f46ddb211610076578063aa5574521161005b578063aa55745214610213578063c4d66de814610226578063c89701a21461023957600080fd5b80637f46ddb2146101c8578063927ede2d146101ef57600080fd5b806354fd4d50116100a757806354fd4d50146101285780635d93a3fc14610171578063761f4493146101b557600080fd5b80633687011a146100c35780633cb747bf146100d8575b600080fd5b6100d66100d1366004610e47565b61025f565b005b6000546100fe9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101646040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b60405161011f9190610f35565b6101a561017f366004610f4f565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b604051901515815260200161011f565b6100d66101c3366004610f90565b61030b565b6100fe7f000000000000000000000000000000000000000000000000000000000000000081565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166100fe565b6100d6610221366004611028565b610776565b6100d661023436600461109f565b610832565b7f00000000000000000000000000000000000000000000000000000000000000006100fe565b333b156102f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b610303868633338888888861097c565b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314801561041357507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fb91906110bc565b73ffffffffffffffffffffffffffffffffffffffff16145b61049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f74686572206272696467650060648201526084016102ea565b3073ffffffffffffffffffffffffffffffffffffffff881603610544576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff161515600114610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c31204272696467650000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156106d357600080fd5b505af11580156106e7573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107659493929190611122565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f7420626520616464726573732830290000000000000000000000000000000060648201526084016102ea565b610829878733888888888861097c565b50505050505050565b600054600390610100900460ff16158015610854575060005460ff8083169116105b6108e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016102ea565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561091a82610cdc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b73ffffffffffffffffffffffffffffffffffffffff8716610a1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f74206265206164647265737328302900000000000000000000000000000060648201526084016102ea565b600063761f449360e01b888a8989898888604051602401610a469796959493929190611162565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610b8657600080fd5b505af1158015610b9a573d6000803e3d6000fd5b50506000546040517f3dbb202b0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169250633dbb202b9150610c1d907f000000000000000000000000000000000000000000000000000000000000000090859089906004016111bf565b600060405180830381600087803b158015610c3757600080fd5b505af1158015610c4b573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610cc99493929190611122565b60405180910390a4505050505050505050565b600054610100900460ff16610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ea565b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610de257600080fd5b50565b803563ffffffff81168114610df957600080fd5b919050565b60008083601f840112610e1057600080fd5b50813567ffffffffffffffff811115610e2857600080fd5b602083019150836020828501011115610e4057600080fd5b9250929050565b60008060008060008060a08789031215610e6057600080fd5b8635610e6b81610dc0565b95506020870135610e7b81610dc0565b945060408701359350610e9060608801610de5565b9250608087013567ffffffffffffffff811115610eac57600080fd5b610eb889828a01610dfe565b979a9699509497509295939492505050565b6000815180845260005b81811015610ef057602081850181015186830182015201610ed4565b81811115610f02576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f486020830184610eca565b9392505050565b600080600060608486031215610f6457600080fd5b8335610f6f81610dc0565b92506020840135610f7f81610dc0565b929592945050506040919091013590565b600080600080600080600060c0888a031215610fab57600080fd5b8735610fb681610dc0565b96506020880135610fc681610dc0565b95506040880135610fd681610dc0565b94506060880135610fe681610dc0565b93506080880135925060a088013567ffffffffffffffff81111561100957600080fd5b6110158a828b01610dfe565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561104357600080fd5b873561104e81610dc0565b9650602088013561105e81610dc0565b9550604088013561106e81610dc0565b94506060880135935061108360808901610de5565b925060a088013567ffffffffffffffff81111561100957600080fd5b6000602082840312156110b157600080fd5b8135610f4881610dc0565b6000602082840312156110ce57600080fd5b8151610f4881610dc0565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006111586060830184866110d9565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a08301526111b260c0830184866110d9565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006111ee6060830185610eca565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "bridgeERC721(address,address,uint256,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.", - "_localToken": "Address of the ERC721 on this domain.", - "_minGasLimit": "Minimum gas limit for the bridge message on the other domain.", - "_remoteToken": "Address of the ERC721 on the remote domain.", - "_tokenId": "Token ID to bridge." - } - }, - "bridgeERC721To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.", - "_localToken": "Address of the ERC721 on this domain.", - "_minGasLimit": "Minimum gas limit for the bridge message on the other domain.", - "_remoteToken": "Address of the ERC721 on the remote domain.", - "_to": "Address to receive the token on the other domain.", - "_tokenId": "Token ID to bridge." - } - }, - "finalizeBridgeERC721(address,address,address,address,uint256,bytes)": { - "params": { - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_from": "Address that triggered the bridge on the other domain.", - "_localToken": "Address of the ERC721 token on this domain.", - "_remoteToken": "Address of the ERC721 token on the other domain.", - "_to": "Address to receive the token on this domain.", - "_tokenId": "ID of the token being deposited." - } - }, - "initialize(address)": { - "params": { - "_messenger": "Address of the CrossDomainMessenger on this network." - } - }, - "otherBridge()": { - "returns": { - "_0": "Address of the bridge on the other network." - } - } - }, - "title": "L1ERC721Bridge" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC721BridgeFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC721BridgeInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC721\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC721To\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeBridgeERC721\"},{\"inputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"_messenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bridgeERC721(address,address,uint256,uint32,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.\",\"_localToken\":\"Address of the ERC721 on this domain.\",\"_minGasLimit\":\"Minimum gas limit for the bridge message on the other domain.\",\"_remoteToken\":\"Address of the ERC721 on the remote domain.\",\"_tokenId\":\"Token ID to bridge.\"}},\"bridgeERC721To(address,address,address,uint256,uint32,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.\",\"_localToken\":\"Address of the ERC721 on this domain.\",\"_minGasLimit\":\"Minimum gas limit for the bridge message on the other domain.\",\"_remoteToken\":\"Address of the ERC721 on the remote domain.\",\"_to\":\"Address to receive the token on the other domain.\",\"_tokenId\":\"Token ID to bridge.\"}},\"finalizeBridgeERC721(address,address,address,address,uint256,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_from\":\"Address that triggered the bridge on the other domain.\",\"_localToken\":\"Address of the ERC721 token on this domain.\",\"_remoteToken\":\"Address of the ERC721 token on the other domain.\",\"_to\":\"Address to receive the token on this domain.\",\"_tokenId\":\"ID of the token being deposited.\"}},\"initialize(address)\":{\"params\":{\"_messenger\":\"Address of the CrossDomainMessenger on this network.\"}},\"otherBridge()\":{\"returns\":{\"_0\":\"Address of the bridge on the other network.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"MESSENGER()\":{\"notice\":\"Getter for messenger contract.\"},\"OTHER_BRIDGE()\":{\"notice\":\"Address of the bridge on the other network.\"},\"bridgeERC721(address,address,uint256,uint32,bytes)\":{\"notice\":\"Initiates a bridge of an NFT to the caller's account on the other chain. Note that this function can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` function after ensuring that the recipient address on the remote chain exists. Also note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\"},\"bridgeERC721To(address,address,address,uint256,uint32,bytes)\":{\"notice\":\"Initiates a bridge of an NFT to some recipient's account on the other chain. Note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\"},\"constructor\":{\"notice\":\"Constructs the contract.\"},\"deposits(address,address,uint256)\":{\"notice\":\"Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token by ID was deposited for a given L2 token.\"},\"finalizeBridgeERC721(address,address,address,address,uint256,bytes)\":{\"notice\":\"Completes an ERC721 bridge from the other domain and sends the ERC721 token to the recipient on this domain.\"},\"initialize(address)\":{\"notice\":\"Initializes the contract.\"},\"messenger()\":{\"notice\":\"Messenger contract on this domain.\"},\"otherBridge()\":{\"notice\":\"Getter for other bridge address.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L1ERC721Bridge.sol\":\"L1ERC721Bridge\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"urls\":[\"bzz-raw://20a97f891d06f0fe91560ea1a142aaa26fdd22bed1b51606b7d48f670deeb50f\",\"dweb:/ipfs/QmTbCtZKChpaX5H2iRiTDMcSz29GSLCpTCDgJpcMR4wg8x\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"urls\":[\"bzz-raw://26fef835622b46a5ba08b3ef6b46a22e94b5f285d0f0fb66b703bd30217d2c34\",\"dweb:/ipfs/QmZ548qdwfL1qF7aXz3xh1GCdTiST81kGGuKRqVUfYmPZR\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L1ERC721Bridge.sol\":{\"keccak256\":\"0xfcbde0f08cd5601aac88a40ee9224f59af9c7f5c404d67f37cbb0abd5f298b1f\",\"urls\":[\"bzz-raw://f1d26441cb269c4e1d45b2739342c016d8ec461dcb99c30da6e649e58d3b376d\",\"dweb:/ipfs/QmU4sYC5ZBGWtgwV2isLp8pXhvNum34d6Fsdsj7UNLEcUw\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L2/L2ERC721Bridge.sol\":{\"keccak256\":\"0xcc0de3ee4e726fe4a0a52a0684fc30454a49190d600c7cbeade798ae020d70f6\",\"urls\":[\"bzz-raw://bfa81e6c23f59237794bce97ad55cca091980c3db50bb295f836ab20cb58e4c8\",\"dweb:/ipfs/QmSpfckbZeoCEAASqxWdFm7t8q6Rqkqwk2jQFSCKEBXEVs\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/Predeploys.sol\":{\"keccak256\":\"0x5af3a849f68f7c9108858ebac5c769da8f1c0309b5c0cb42eb5cbb15e3fe6058\",\"urls\":[\"bzz-raw://6ffe76429a96d274577be66627eddad5cd05ad36d0cb6b9b3c3f9fa8a609dd7e\",\"dweb:/ipfs/QmVhWnB7Avg684TEQ9BExWqSN1YfLehUTWoqpjymeQEQHm\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x4302ae78bcafde2737d4048bbf8fdb3dd4cd7254c015b91dfa14fdaafd412f4a\",\"urls\":[\"bzz-raw://78d3d1823ad4e1fba15921a0a361b452c85d111e2d53cbbed11a8632782ea8f3\",\"dweb:/ipfs/QmVc2rTRpn7g7WAUxDShSuy6dY5zmtbJ7hHC6sT9PcD3Gj\"],\"license\":\"MIT\"},\"src/universal/ERC721Bridge.sol\":{\"keccak256\":\"0x1aba1c039fa759d7d081e0d60c5d742e8d3147f0eda19af5c17cf291b4f53213\",\"urls\":[\"bzz-raw://a3581c48036bf901da4dd823f4b2fc65870414a116b32ed042d89778a2027e3f\",\"dweb:/ipfs/QmVqTCMR6NroWCQzjc1vkznHp1XbNFSYXNDgrvXUDEuZoA\"],\"license\":\"MIT\"},\"src/universal/IOptimismMintableERC721.sol\":{\"keccak256\":\"0xb3a65b067e67a9e1fa0493401c8d247970377c6725eba4e7b02ce8099c4f4f52\",\"urls\":[\"bzz-raw://86bb6864027560ade2f4ced6a6e34213cbff8002977dc365377e5a0b473cf17b\",\"dweb:/ipfs/QmQvjtodTK27as1g1PzsYk9NyJJ3X6a6251o1vrBwx7DPT\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 76028, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "messenger", - "offset": 2, - "slot": "0", - "type": "t_contract(CrossDomainMessenger)76013" - }, - { - "astId": 76036, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)48_storage" - }, - { - "astId": 58984, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "deposits", - "offset": 0, - "slot": "49", - "type": "t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint256,t_bool)))" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)48_storage": { - "encoding": "inplace", - "label": "uint256[48]", - "numberOfBytes": "1536", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(CrossDomainMessenger)76013": { - "encoding": "inplace", - "label": "contract CrossDomainMessenger", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint256,t_bool)))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => mapping(uint256 => bool)))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_mapping(t_uint256,t_bool))" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_bool))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(uint256 => bool))", - "numberOfBytes": "32", - "value": "t_mapping(t_uint256,t_bool)" - }, - "t_mapping(t_uint256,t_bool)": { - "encoding": "mapping", - "key": "t_uint256", - "label": "mapping(uint256 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x0ec4e7357fd7c3e3661a350cd839c720467242a7a5a895cb032cb08a52ea7021", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSENGER()": { - "notice": "Getter for messenger contract." - }, - "OTHER_BRIDGE()": { - "notice": "Address of the bridge on the other network." - }, - "bridgeERC721(address,address,uint256,uint32,bytes)": { - "notice": "Initiates a bridge of an NFT to the caller's account on the other chain. Note that this function can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` function after ensuring that the recipient address on the remote chain exists. Also note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "bridgeERC721To(address,address,address,uint256,uint32,bytes)": { - "notice": "Initiates a bridge of an NFT to some recipient's account on the other chain. Note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "constructor": { - "notice": "Constructs the contract." - }, - "deposits(address,address,uint256)": { - "notice": "Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token by ID was deposited for a given L2 token." - }, - "finalizeBridgeERC721(address,address,address,address,uint256,bytes)": { - "notice": "Completes an ERC721 bridge from the other domain and sends the ERC721 token to the recipient on this domain." - }, - "initialize(address)": { - "notice": "Initializes the contract." - }, - "messenger()": { - "notice": "Messenger contract on this domain." - }, - "otherBridge()": { - "notice": "Getter for other bridge address." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ERC721BridgeFinalized(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC721 bridge from the other network is finalized." - }, - "ERC721BridgeInitiated(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC721 bridge to the other network is initiated." - } - }, - "notice": "The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract acts as an escrow for ERC721 tokens deposited into L2." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/L1ERC721BridgeProxy.json b/packages/contracts-bedrock/deployments/goerli/L1ERC721BridgeProxy.json deleted file mode 100644 index f233a6c393e0..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/L1ERC721BridgeProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x2e68ff6e214e003d7fc8bd56962ea3751c85096b16bf1a40896c1262ea0e3753", - "receipt": { - "to": null, - "from": "0x5c679a57e018F5F146838138d3E032Ef4913D551", - "contractAddress": "0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9", - "transactionIndex": 31, - "gasUsed": "532674", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000801000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x3c4e33fc274b073565a640b6f1ee49845ea951b4d73f1645aef83dd70c110ba8", - "transactionHash": "0x2e68ff6e214e003d7fc8bd56962ea3751c85096b16bf1a40896c1262ea0e3753", - "logs": [ - { - "transactionIndex": 31, - "blockNumber": 7682740, - "transactionHash": "0x2e68ff6e214e003d7fc8bd56962ea3751c85096b16bf1a40896c1262ea0e3753", - "address": "0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c679a57e018f5f146838138d3e032ef4913d551", - "logIndex": 76, - "blockHash": "0x3c4e33fc274b073565a640b6f1ee49845ea951b4d73f1645aef83dd70c110ba8" - } - ], - "blockNumber": 7682740, - "cumulativeGasUsed": "22398486", - "status": 1, - "byzantium": true - }, - "args": [ - "0x5c679a57e018F5F146838138d3E032Ef4913D551" - ], - "numDeployments": 1, - "solcInputHash": "ab9b77493f35e63b7a63fb2fa8d618b4", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n external\\n payable\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() external proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() external proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/L1StandardBridge.json b/packages/contracts-bedrock/deployments/goerli/L1StandardBridge.json deleted file mode 100644 index ee1aa5df92f3..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/L1StandardBridge.json +++ /dev/null @@ -1,1122 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20BridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20BridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20DepositInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20WithdrawalFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHBridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHBridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHDepositInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHWithdrawalFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "inputs": [], - "name": "MESSENGER", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_BRIDGE", - "outputs": [ - { - "internalType": "contract StandardBridge", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC20To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeETHTo", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositERC20To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositETHTo", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "deposits", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeERC20Withdrawal", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeETHWithdrawal", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "_messenger", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l2TokenBridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "messenger", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "otherBridge", - "outputs": [ - { - "internalType": "contract StandardBridge", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0xcfBCbA6d9E84A3c4FaE0eda9684cE39a09aa2c8A", - "args": [], - "bytecode": "0x60a06040523480156200001157600080fd5b507342000000000000000000000000000000000000106080526200003660006200003c565b620001bb565b600054600390610100900460ff161580156200005f575060005460ff8083169116105b620000c85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620000e7826200012c565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054610100900460ff16620001995760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000bf565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b608051612a44620001fa60003960008181610379015281816104300152818161057001528181610a22015281816113d80152611a8b0152612a446000f3fe6080604052600436106101635760003560e01c806387087623116100c0578063a9f9e67511610074578063c4d66de811610059578063c4d66de8146104c5578063c89701a214610421578063e11013dd146104e557600080fd5b8063a9f9e67514610492578063b1a1a882146104b257600080fd5b806391c49bf8116100a557806391c49bf814610421578063927ede2d146104545780639a2ac6d51461047f57600080fd5b806387087623146103bb5780638f601f66146103db57600080fd5b8063540abf731161011757806358a997f6116100fc57806358a997f6146103475780637f46ddb214610367578063838b25201461039b57600080fd5b8063540abf73146102d157806354fd4d50146102f157600080fd5b80631532ec34116101485780631532ec34146102545780631635f5fd146102675780633cb747bf1461027a57600080fd5b80630166a07a1461022157806309fc88431461024157600080fd5b3661021c57333b156101fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61021a333362030d40604051806020016040528060008152506104f8565b005b600080fd5b34801561022d57600080fd5b5061021a61023c36600461248b565b61050b565b61021a61024f36600461253c565b6108d2565b61021a61026236600461258f565b6109a9565b61021a61027536600461258f565b6109bd565b34801561028657600080fd5b506003546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102dd57600080fd5b5061021a6102ec366004612602565b610e33565b3480156102fd57600080fd5b5061033a6040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516102c891906126ef565b34801561035357600080fd5b5061021a610362366004612702565b610e78565b34801561037357600080fd5b506102a77f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a757600080fd5b5061021a6103b6366004612602565b610f4c565b3480156103c757600080fd5b5061021a6103d6366004612702565b610f91565b3480156103e757600080fd5b506104136103f6366004612785565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102c8565b34801561042d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102a7565b34801561046057600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102a7565b61021a61048d3660046127be565b611065565b34801561049e57600080fd5b5061021a6104ad36600461248b565b6110a7565b61021a6104c036600461253c565b6110b6565b3480156104d157600080fd5b5061021a6104e0366004612821565b611187565b61021a6104f33660046127be565b6112d1565b6105058484348585611314565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff16331480156105fa5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e2919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b6106ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b6106b5876114fa565b15610803576106c4878761155c565b610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107e657600080fd5b505af11580156107fa573d6000803e3d6000fd5b50505050610885565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461084190849061288a565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561088590858561167c565b6108c9878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175092505050565b50505050505050565b333b15610961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b505050565b6109b685858585856109bd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610aac5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b823414610bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101f3565b3073ffffffffffffffffffffffffffffffffffffffff851603610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101f3565b610d7f85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117de92505050565b6000610d9c855a8660405180602001604052806000815250611851565b905080610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b505050505050565b6108c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b333b15610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b6108c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b333b15611020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b61050533858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b6108c98787878787878761050b565b333b15611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b600054600390610100900460ff161580156111a9575060005460ff8083169116105b611235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101f3565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561126f82611bc2565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6105053385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b8234146113a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101f3565b6113af85858584611ca0565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b9085907f0000000000000000000000000000000000000000000000000000000000000000907f1635f5fd000000000000000000000000000000000000000000000000000000009061142e908b908b9086908a906024016128a1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526114c1929188906004016128ea565b6000604051808303818588803b1580156114da57600080fd5b505af11580156114ee573d6000803e3d6000fd5b50505050505050505050565b6000611526827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b806115565750611556827fec4fc8e300000000000000000000000000000000000000000000000000000000611d13565b92915050565b6000611588837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b15611631578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fc919061283e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611556565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109a49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611d36565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516117c89392919061292f565b60405180910390a4610e2b868686868686611e42565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631848460405161183d92919061296d565b60405180910390a361050584848484611eca565b600080600080845160208601878a8af19695505050505050565b611874876114fa565b156119c257611883878761155c565b611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b50505050611a56565b6119e473ffffffffffffffffffffffffffffffffffffffff8816863086611f37565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611a22908490612986565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611a64878787878786611f95565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b907f0000000000000000000000000000000000000000000000000000000000000000907f0166a07a0000000000000000000000000000000000000000000000000000000090611ae5908b908d908c908c908c908b9060240161299e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611b78929187906004016128ea565b600060405180830381600087803b158015611b9257600080fd5b505af1158015611ba6573d6000803e3d6000fd5b5050505050505050505050565b6108c98787878787878761186b565b600054610100900460ff16611c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101f3565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611cff92919061296d565b60405180910390a361050584848484612023565b6000611d1e83612082565b8015611d2f5750611d2f83836120e6565b9392505050565b6000611d98826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b59092919063ffffffff16565b8051909150156109a45780806020019051810190611db691906129f9565b6109a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101f3565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611eba9392919061292f565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f2992919061296d565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105059085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116ce565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161200d9392919061292f565b60405180910390a4610e2b8686868686866121cc565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f2992919061296d565b60006120ae827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e6565b801561155657506120df827fffffffff000000000000000000000000000000000000000000000000000000006120e6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219e575060208210155b80156121aa5750600081115b979650505050505050565b60606121c48484600085612244565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611eba9392919061292f565b6060824710156122d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101f3565b73ffffffffffffffffffffffffffffffffffffffff85163b612354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161237d9190612a1b565b60006040518083038185875af1925050503d80600081146123ba576040519150601f19603f3d011682016040523d82523d6000602084013e6123bf565b606091505b50915091506121aa828286606083156123d9575081611d2f565b8251156123e95782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f391906126ef565b73ffffffffffffffffffffffffffffffffffffffff8116811461243f57600080fd5b50565b60008083601f84011261245457600080fd5b50813567ffffffffffffffff81111561246c57600080fd5b60208301915083602082850101111561248457600080fd5b9250929050565b600080600080600080600060c0888a0312156124a657600080fd5b87356124b18161241d565b965060208801356124c18161241d565b955060408801356124d18161241d565b945060608801356124e18161241d565b93506080880135925060a088013567ffffffffffffffff81111561250457600080fd5b6125108a828b01612442565b989b979a50959850939692959293505050565b803563ffffffff8116811461253757600080fd5b919050565b60008060006040848603121561255157600080fd5b61255a84612523565b9250602084013567ffffffffffffffff81111561257657600080fd5b61258286828701612442565b9497909650939450505050565b6000806000806000608086880312156125a757600080fd5b85356125b28161241d565b945060208601356125c28161241d565b935060408601359250606086013567ffffffffffffffff8111156125e557600080fd5b6125f188828901612442565b969995985093965092949392505050565b600080600080600080600060c0888a03121561261d57600080fd5b87356126288161241d565b965060208801356126388161241d565b955060408801356126488161241d565b94506060880135935061265d60808901612523565b925060a088013567ffffffffffffffff81111561250457600080fd5b60005b8381101561269457818101518382015260200161267c565b838111156105055750506000910152565b600081518084526126bd816020860160208601612679565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d2f60208301846126a5565b60008060008060008060a0878903121561271b57600080fd5b86356127268161241d565b955060208701356127368161241d565b94506040870135935061274b60608801612523565b9250608087013567ffffffffffffffff81111561276757600080fd5b61277389828a01612442565b979a9699509497509295939492505050565b6000806040838503121561279857600080fd5b82356127a38161241d565b915060208301356127b38161241d565b809150509250929050565b600080600080606085870312156127d457600080fd5b84356127df8161241d565b93506127ed60208601612523565b9250604085013567ffffffffffffffff81111561280957600080fd5b61281587828801612442565b95989497509550505050565b60006020828403121561283357600080fd5b8135611d2f8161241d565b60006020828403121561285057600080fd5b8151611d2f8161241d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561289c5761289c61285b565b500390565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128e060808301846126a5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061291960608301856126a5565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296460608301846126a5565b95945050505050565b8281526040602082015260006121c460408301846126a5565b600082198211156129995761299961285b565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526129ed60c08301846126a5565b98975050505050505050565b600060208284031215612a0b57600080fd5b81518015158114611d2f57600080fd5b60008251612a2d818460208701612679565b919091019291505056fea164736f6c634300080f000a", - "deployedBytecode": "0x6080604052600436106101635760003560e01c806387087623116100c0578063a9f9e67511610074578063c4d66de811610059578063c4d66de8146104c5578063c89701a214610421578063e11013dd146104e557600080fd5b8063a9f9e67514610492578063b1a1a882146104b257600080fd5b806391c49bf8116100a557806391c49bf814610421578063927ede2d146104545780639a2ac6d51461047f57600080fd5b806387087623146103bb5780638f601f66146103db57600080fd5b8063540abf731161011757806358a997f6116100fc57806358a997f6146103475780637f46ddb214610367578063838b25201461039b57600080fd5b8063540abf73146102d157806354fd4d50146102f157600080fd5b80631532ec34116101485780631532ec34146102545780631635f5fd146102675780633cb747bf1461027a57600080fd5b80630166a07a1461022157806309fc88431461024157600080fd5b3661021c57333b156101fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61021a333362030d40604051806020016040528060008152506104f8565b005b600080fd5b34801561022d57600080fd5b5061021a61023c36600461248b565b61050b565b61021a61024f36600461253c565b6108d2565b61021a61026236600461258f565b6109a9565b61021a61027536600461258f565b6109bd565b34801561028657600080fd5b506003546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102dd57600080fd5b5061021a6102ec366004612602565b610e33565b3480156102fd57600080fd5b5061033a6040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516102c891906126ef565b34801561035357600080fd5b5061021a610362366004612702565b610e78565b34801561037357600080fd5b506102a77f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a757600080fd5b5061021a6103b6366004612602565b610f4c565b3480156103c757600080fd5b5061021a6103d6366004612702565b610f91565b3480156103e757600080fd5b506104136103f6366004612785565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102c8565b34801561042d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102a7565b34801561046057600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102a7565b61021a61048d3660046127be565b611065565b34801561049e57600080fd5b5061021a6104ad36600461248b565b6110a7565b61021a6104c036600461253c565b6110b6565b3480156104d157600080fd5b5061021a6104e0366004612821565b611187565b61021a6104f33660046127be565b6112d1565b6105058484348585611314565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff16331480156105fa5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e2919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b6106ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b6106b5876114fa565b15610803576106c4878761155c565b610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107e657600080fd5b505af11580156107fa573d6000803e3d6000fd5b50505050610885565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461084190849061288a565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561088590858561167c565b6108c9878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175092505050565b50505050505050565b333b15610961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b505050565b6109b685858585856109bd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610aac5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b823414610bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101f3565b3073ffffffffffffffffffffffffffffffffffffffff851603610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101f3565b610d7f85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117de92505050565b6000610d9c855a8660405180602001604052806000815250611851565b905080610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b505050505050565b6108c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b333b15610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b6108c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b333b15611020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b61050533858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b6108c98787878787878761050b565b333b15611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b600054600390610100900460ff161580156111a9575060005460ff8083169116105b611235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101f3565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561126f82611bc2565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6105053385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b8234146113a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101f3565b6113af85858584611ca0565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b9085907f0000000000000000000000000000000000000000000000000000000000000000907f1635f5fd000000000000000000000000000000000000000000000000000000009061142e908b908b9086908a906024016128a1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526114c1929188906004016128ea565b6000604051808303818588803b1580156114da57600080fd5b505af11580156114ee573d6000803e3d6000fd5b50505050505050505050565b6000611526827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b806115565750611556827fec4fc8e300000000000000000000000000000000000000000000000000000000611d13565b92915050565b6000611588837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b15611631578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fc919061283e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611556565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109a49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611d36565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516117c89392919061292f565b60405180910390a4610e2b868686868686611e42565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631848460405161183d92919061296d565b60405180910390a361050584848484611eca565b600080600080845160208601878a8af19695505050505050565b611874876114fa565b156119c257611883878761155c565b611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b50505050611a56565b6119e473ffffffffffffffffffffffffffffffffffffffff8816863086611f37565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611a22908490612986565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611a64878787878786611f95565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b907f0000000000000000000000000000000000000000000000000000000000000000907f0166a07a0000000000000000000000000000000000000000000000000000000090611ae5908b908d908c908c908c908b9060240161299e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611b78929187906004016128ea565b600060405180830381600087803b158015611b9257600080fd5b505af1158015611ba6573d6000803e3d6000fd5b5050505050505050505050565b6108c98787878787878761186b565b600054610100900460ff16611c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101f3565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611cff92919061296d565b60405180910390a361050584848484612023565b6000611d1e83612082565b8015611d2f5750611d2f83836120e6565b9392505050565b6000611d98826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b59092919063ffffffff16565b8051909150156109a45780806020019051810190611db691906129f9565b6109a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101f3565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611eba9392919061292f565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f2992919061296d565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105059085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116ce565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161200d9392919061292f565b60405180910390a4610e2b8686868686866121cc565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f2992919061296d565b60006120ae827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e6565b801561155657506120df827fffffffff000000000000000000000000000000000000000000000000000000006120e6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219e575060208210155b80156121aa5750600081115b979650505050505050565b60606121c48484600085612244565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611eba9392919061292f565b6060824710156122d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101f3565b73ffffffffffffffffffffffffffffffffffffffff85163b612354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161237d9190612a1b565b60006040518083038185875af1925050503d80600081146123ba576040519150601f19603f3d011682016040523d82523d6000602084013e6123bf565b606091505b50915091506121aa828286606083156123d9575081611d2f565b8251156123e95782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f391906126ef565b73ffffffffffffffffffffffffffffffffffffffff8116811461243f57600080fd5b50565b60008083601f84011261245457600080fd5b50813567ffffffffffffffff81111561246c57600080fd5b60208301915083602082850101111561248457600080fd5b9250929050565b600080600080600080600060c0888a0312156124a657600080fd5b87356124b18161241d565b965060208801356124c18161241d565b955060408801356124d18161241d565b945060608801356124e18161241d565b93506080880135925060a088013567ffffffffffffffff81111561250457600080fd5b6125108a828b01612442565b989b979a50959850939692959293505050565b803563ffffffff8116811461253757600080fd5b919050565b60008060006040848603121561255157600080fd5b61255a84612523565b9250602084013567ffffffffffffffff81111561257657600080fd5b61258286828701612442565b9497909650939450505050565b6000806000806000608086880312156125a757600080fd5b85356125b28161241d565b945060208601356125c28161241d565b935060408601359250606086013567ffffffffffffffff8111156125e557600080fd5b6125f188828901612442565b969995985093965092949392505050565b600080600080600080600060c0888a03121561261d57600080fd5b87356126288161241d565b965060208801356126388161241d565b955060408801356126488161241d565b94506060880135935061265d60808901612523565b925060a088013567ffffffffffffffff81111561250457600080fd5b60005b8381101561269457818101518382015260200161267c565b838111156105055750506000910152565b600081518084526126bd816020860160208601612679565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d2f60208301846126a5565b60008060008060008060a0878903121561271b57600080fd5b86356127268161241d565b955060208701356127368161241d565b94506040870135935061274b60608801612523565b9250608087013567ffffffffffffffff81111561276757600080fd5b61277389828a01612442565b979a9699509497509295939492505050565b6000806040838503121561279857600080fd5b82356127a38161241d565b915060208301356127b38161241d565b809150509250929050565b600080600080606085870312156127d457600080fd5b84356127df8161241d565b93506127ed60208601612523565b9250604085013567ffffffffffffffff81111561280957600080fd5b61281587828801612442565b95989497509550505050565b60006020828403121561283357600080fd5b8135611d2f8161241d565b60006020828403121561285057600080fd5b8151611d2f8161241d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561289c5761289c61285b565b500390565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128e060808301846126a5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061291960608301856126a5565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296460608301846126a5565b95945050505050565b8281526040602082015260006121c460408301846126a5565b600082198211156129995761299961285b565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526129ed60c08301846126a5565b98975050505050505050565b600060208284031215612a0b57600080fd5b81518015158114611d2f57600080fd5b60008251612a2d818460208701612679565b919091019291505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "MESSENGER()": {}, - "bridgeERC20(address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of local tokens to deposit.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_localToken": "Address of the ERC20 on this chain.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_remoteToken": "Address of the corresponding token on the remote chain." - } - }, - "bridgeERC20To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of local tokens to deposit.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_localToken": "Address of the ERC20 on this chain.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_remoteToken": "Address of the corresponding token on the remote chain.", - "_to": "Address of the receiver." - } - }, - "bridgeETH(uint32,bytes)": { - "params": { - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with." - } - }, - "bridgeETHTo(address,uint32,bytes)": { - "params": { - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_to": "Address of the receiver." - } - }, - "depositERC20(address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of the ERC20 to deposit.", - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_l1Token": "Address of the L1 token being deposited.", - "_l2Token": "Address of the corresponding token on L2.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2." - } - }, - "depositERC20To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of the ERC20 to deposit.", - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_l1Token": "Address of the L1 token being deposited.", - "_l2Token": "Address of the corresponding token on L2.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2.", - "_to": "Address of the recipient on L2." - } - }, - "depositETH(uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2." - } - }, - "depositETHTo(address,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2.", - "_to": "Address of the recipient on L2." - } - }, - "finalizeBridgeERC20(address,address,address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of the ERC20 being bridged.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_from": "Address of the sender.", - "_localToken": "Address of the ERC20 on this chain.", - "_remoteToken": "Address of the corresponding token on the remote chain.", - "_to": "Address of the receiver." - } - }, - "finalizeBridgeETH(address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of ETH being bridged.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_from": "Address of the sender.", - "_to": "Address of the receiver." - } - }, - "finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of the ERC20 to withdraw.", - "_extraData": "Optional data forwarded from L2.", - "_from": "Address of the withdrawer on L2.", - "_l1Token": "Address of the token on L1.", - "_l2Token": "Address of the corresponding token on L2.", - "_to": "Address of the recipient on L1." - } - }, - "finalizeETHWithdrawal(address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of ETH to withdraw.", - "_extraData": "Optional data forwarded from L2.", - "_from": "Address of the withdrawer on L2.", - "_to": "Address of the recipient on L1." - } - }, - "l2TokenBridge()": { - "returns": { - "_0": "Address of the corresponding L2 bridge contract." - } - } - }, - "events": { - "ERC20DepositInitiated(address,address,address,address,uint256,bytes)": { - "params": { - "amount": "Amount of the ERC20 deposited.", - "extraData": "Extra data attached to the deposit.", - "from": "Address of the depositor.", - "l1Token": "Address of the token on L1.", - "l2Token": "Address of the corresponding token on L2.", - "to": "Address of the recipient on L2." - } - }, - "ERC20WithdrawalFinalized(address,address,address,address,uint256,bytes)": { - "params": { - "amount": "Amount of the ERC20 withdrawn.", - "extraData": "Extra data attached to the withdrawal.", - "from": "Address of the withdrawer.", - "l1Token": "Address of the token on L1.", - "l2Token": "Address of the corresponding token on L2.", - "to": "Address of the recipient on L1." - } - }, - "ETHDepositInitiated(address,address,uint256,bytes)": { - "params": { - "amount": "Amount of ETH deposited.", - "extraData": "Extra data attached to the deposit.", - "from": "Address of the depositor.", - "to": "Address of the recipient on L2." - } - }, - "ETHWithdrawalFinalized(address,address,uint256,bytes)": { - "params": { - "amount": "Amount of ETH withdrawn.", - "extraData": "Extra data attached to the withdrawal.", - "from": "Address of the withdrawer.", - "to": "Address of the recipient on L1." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20BridgeFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20BridgeInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20DepositInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20WithdrawalFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHBridgeFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHBridgeInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHDepositInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHWithdrawalFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"contract StandardBridge\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC20\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC20To\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"bridgeETH\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"bridgeETHTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"depositERC20\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"depositERC20To\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"depositETH\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"depositETHTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeBridgeERC20\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"finalizeBridgeETH\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeERC20Withdrawal\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"finalizeETHWithdrawal\"},{\"inputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"_messenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2TokenBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"contract StandardBridge\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"MESSENGER()\":{\"custom:legacy\":\"@return Messenger contract on this domain.\"},\"bridgeERC20(address,address,uint256,uint32,bytes)\":{\"params\":{\"_amount\":\"Amount of local tokens to deposit.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\"}},\"bridgeERC20To(address,address,address,uint256,uint32,bytes)\":{\"params\":{\"_amount\":\"Amount of local tokens to deposit.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\",\"_to\":\"Address of the receiver.\"}},\"bridgeETH(uint32,bytes)\":{\"params\":{\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\"}},\"bridgeETHTo(address,uint32,bytes)\":{\"params\":{\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_to\":\"Address of the receiver.\"}},\"depositERC20(address,address,uint256,uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ERC20 tokens into the sender's account on L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_l1Token\":\"Address of the L1 token being deposited.\",\"_l2Token\":\"Address of the corresponding token on L2.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\"}},\"depositERC20To(address,address,address,uint256,uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ERC20 tokens into a target account on L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_l1Token\":\"Address of the L1 token being deposited.\",\"_l2Token\":\"Address of the corresponding token on L2.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\",\"_to\":\"Address of the recipient on L2.\"}},\"depositETH(uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ETH into the sender's account on L2.\",\"params\":{\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\"}},\"depositETHTo(address,uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ETH into a target account on L2. Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will be locked in the L2StandardBridge. ETH may be recoverable if the call can be successfully replayed by increasing the amount of gas supplied to the call. If the call will fail for any amount of gas, then the ETH will be locked permanently.\",\"params\":{\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\",\"_to\":\"Address of the recipient on L2.\"}},\"finalizeBridgeERC20(address,address,address,address,uint256,bytes)\":{\"params\":{\"_amount\":\"Amount of the ERC20 being bridged.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_from\":\"Address of the sender.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\",\"_to\":\"Address of the receiver.\"}},\"finalizeBridgeETH(address,address,uint256,bytes)\":{\"params\":{\"_amount\":\"Amount of ETH being bridged.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_from\":\"Address of the sender.\",\"_to\":\"Address of the receiver.\"}},\"finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)\":{\"custom:legacy\":\"@notice Finalizes a withdrawal of ERC20 tokens from L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to withdraw.\",\"_extraData\":\"Optional data forwarded from L2.\",\"_from\":\"Address of the withdrawer on L2.\",\"_l1Token\":\"Address of the token on L1.\",\"_l2Token\":\"Address of the corresponding token on L2.\",\"_to\":\"Address of the recipient on L1.\"}},\"finalizeETHWithdrawal(address,address,uint256,bytes)\":{\"custom:legacy\":\"@notice Finalizes a withdrawal of ETH from L2.\",\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_extraData\":\"Optional data forwarded from L2.\",\"_from\":\"Address of the withdrawer on L2.\",\"_to\":\"Address of the recipient on L1.\"}},\"l2TokenBridge()\":{\"custom:legacy\":\"@notice Retrieves the access of the corresponding L2 bridge contract.\",\"returns\":{\"_0\":\"Address of the corresponding L2 bridge contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"MESSENGER()\":{\"notice\":\"Getter for messenger contract.\"},\"OTHER_BRIDGE()\":{\"notice\":\"Corresponding bridge on the other domain. This public getter is deprecated and will be removed in the future. Please use `otherBridge` instead. This can safely be an immutable because for the L1StandardBridge, it will be set to the L2StandardBridge address, which is the same for all OP Stack chains. For the L2StandardBridge, there are not multiple proxies using the same implementation.\"},\"bridgeERC20(address,address,uint256,uint32,bytes)\":{\"notice\":\"Sends ERC20 tokens to the sender's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain.\"},\"bridgeERC20To(address,address,address,uint256,uint32,bytes)\":{\"notice\":\"Sends ERC20 tokens to a receiver's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain.\"},\"bridgeETH(uint32,bytes)\":{\"notice\":\"Sends ETH to the sender's address on the other chain.\"},\"bridgeETHTo(address,uint32,bytes)\":{\"notice\":\"Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a smart contract and the call fails, the ETH will be temporarily locked in the StandardBridge on the other chain until the call is replayed. If the call cannot be replayed with any amount of gas (call always reverts), then the ETH will be permanently locked in the StandardBridge on the other chain. ETH will also be locked if the receiver is the other bridge, because finalizeBridgeETH will revert in that case.\"},\"constructor\":{\"notice\":\"Constructs the L1StandardBridge contract.\"},\"deposits(address,address)\":{\"notice\":\"Mapping that stores deposits for a given pair of local and remote tokens.\"},\"finalizeBridgeERC20(address,address,address,address,uint256,bytes)\":{\"notice\":\"Finalizes an ERC20 bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain.\"},\"finalizeBridgeETH(address,address,uint256,bytes)\":{\"notice\":\"Finalizes an ETH bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain.\"},\"initialize(address)\":{\"notice\":\"Initializer\"},\"messenger()\":{\"notice\":\"Messenger contract on this domain. This public getter is deprecated and will be removed in the future. Please use `messenger` instead.\"},\"otherBridge()\":{\"notice\":\"Getter for the remote domain bridge contract.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L1StandardBridge.sol\":\"L1StandardBridge\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"urls\":[\"bzz-raw://11756f42121f6541a35a8339ea899ee7514cfaa2e6d740625fcc844419296aa6\",\"dweb:/ipfs/QmekMuk6BY4DAjzeXr4MSbKdgoqqsZnA8JPtuyWc6CwXHf\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L1StandardBridge.sol\":{\"keccak256\":\"0x6838bb9b120c2c55e5f86591180053fd213141310c59a7856c55289079e26818\",\"urls\":[\"bzz-raw://193330432139af7aa03e97e0bb451c8204cc0f63452edc2312fe9465f36cf48c\",\"dweb:/ipfs/Qmchazs1JtQ84dCjVUFFHFQxpL8Byh4RCEWVGVfXqZbPNi\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/Predeploys.sol\":{\"keccak256\":\"0x5af3a849f68f7c9108858ebac5c769da8f1c0309b5c0cb42eb5cbb15e3fe6058\",\"urls\":[\"bzz-raw://6ffe76429a96d274577be66627eddad5cd05ad36d0cb6b9b3c3f9fa8a609dd7e\",\"dweb:/ipfs/QmVhWnB7Avg684TEQ9BExWqSN1YfLehUTWoqpjymeQEQHm\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x4302ae78bcafde2737d4048bbf8fdb3dd4cd7254c015b91dfa14fdaafd412f4a\",\"urls\":[\"bzz-raw://78d3d1823ad4e1fba15921a0a361b452c85d111e2d53cbbed11a8632782ea8f3\",\"dweb:/ipfs/QmVc2rTRpn7g7WAUxDShSuy6dY5zmtbJ7hHC6sT9PcD3Gj\"],\"license\":\"MIT\"},\"src/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x6f8133b39efcbcbd5088f195dfacf1bedc3146508429c3865443909af735a04c\",\"urls\":[\"bzz-raw://adc36971e2e120458769f050428d9d2b0504516660345020c2521ee46e6d8abf\",\"dweb:/ipfs/QmPbFusQkZgGKpU8Fv5JoqL4oVeJtM3yqnhRGLY9eZT5zZ\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x39af021e492020fbeb5401371010d4a2fb69debe9596dbbead7bcd7fae248b0b\",\"urls\":[\"bzz-raw://dbeea52e586d2d7de55491a660ca76f75167ba6b43b65d29564864ee9c34a174\",\"dweb:/ipfs/QmS23vFqQxyUXhGuV1nSowZZS93CUkSnsb41uuyRtSeAED\"],\"license\":\"MIT\"},\"src/universal/Semver.sol\":{\"keccak256\":\"0x9de68ce536aee1aa616b4bf88d7ccc335460e6edd0e7170bdbf94c4fe3d41c60\",\"urls\":[\"bzz-raw://d5909c0b049b03a2bc24816ecf15b0aaf18c04a963174e1eba7624321bef330d\",\"dweb:/ipfs/QmeqdutwZWHqQMXauNR6WY8PrUpfsTiWTQyanbnGM9QqzT\"],\"license\":\"MIT\"},\"src/universal/StandardBridge.sol\":{\"keccak256\":\"0xc6ab09f73ee243757df19b3304b6ca289af84c2ce3ea4bf370a89c39c6ae5b04\",\"urls\":[\"bzz-raw://f5a3a6a7240ddb7c78b446e0647b7f5e7a8948b368a59d433efd70e927ea5c32\",\"dweb:/ipfs/QmVjEgX5LtCKz7HauTag8ukFgt5edPCVAsve6Mb3mKnXJN\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 78131, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "spacer_0_2_20", - "offset": 2, - "slot": "0", - "type": "t_address" - }, - { - "astId": 78134, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "spacer_1_0_20", - "offset": 0, - "slot": "1", - "type": "t_address" - }, - { - "astId": 78141, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "deposits", - "offset": 0, - "slot": "2", - "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" - }, - { - "astId": 78145, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "messenger", - "offset": 0, - "slot": "3", - "type": "t_contract(CrossDomainMessenger)76013" - }, - { - "astId": 78150, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "__gap", - "offset": 0, - "slot": "4", - "type": "t_array(t_uint256)46_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)46_storage": { - "encoding": "inplace", - "label": "uint256[46]", - "numberOfBytes": "1472", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(CrossDomainMessenger)76013": { - "encoding": "inplace", - "label": "contract CrossDomainMessenger", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_mapping(t_address,t_uint256))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => uint256))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_uint256)" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x335acbd74ae547ea85211e98c88696b8cfeff66094aca9ebda721a39bf5a3eda", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSENGER()": { - "notice": "Getter for messenger contract." - }, - "OTHER_BRIDGE()": { - "notice": "Corresponding bridge on the other domain. This public getter is deprecated and will be removed in the future. Please use `otherBridge` instead. This can safely be an immutable because for the L1StandardBridge, it will be set to the L2StandardBridge address, which is the same for all OP Stack chains. For the L2StandardBridge, there are not multiple proxies using the same implementation." - }, - "bridgeERC20(address,address,uint256,uint32,bytes)": { - "notice": "Sends ERC20 tokens to the sender's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain." - }, - "bridgeERC20To(address,address,address,uint256,uint32,bytes)": { - "notice": "Sends ERC20 tokens to a receiver's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain." - }, - "bridgeETH(uint32,bytes)": { - "notice": "Sends ETH to the sender's address on the other chain." - }, - "bridgeETHTo(address,uint32,bytes)": { - "notice": "Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a smart contract and the call fails, the ETH will be temporarily locked in the StandardBridge on the other chain until the call is replayed. If the call cannot be replayed with any amount of gas (call always reverts), then the ETH will be permanently locked in the StandardBridge on the other chain. ETH will also be locked if the receiver is the other bridge, because finalizeBridgeETH will revert in that case." - }, - "constructor": { - "notice": "Constructs the L1StandardBridge contract." - }, - "deposits(address,address)": { - "notice": "Mapping that stores deposits for a given pair of local and remote tokens." - }, - "finalizeBridgeERC20(address,address,address,address,uint256,bytes)": { - "notice": "Finalizes an ERC20 bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain." - }, - "finalizeBridgeETH(address,address,uint256,bytes)": { - "notice": "Finalizes an ETH bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain." - }, - "initialize(address)": { - "notice": "Initializer" - }, - "messenger()": { - "notice": "Messenger contract on this domain. This public getter is deprecated and will be removed in the future. Please use `messenger` instead." - }, - "otherBridge()": { - "notice": "Getter for the remote domain bridge contract." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ERC20BridgeFinalized(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC20 bridge is finalized on this chain." - }, - "ERC20BridgeInitiated(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC20 bridge is initiated to the other chain." - }, - "ETHBridgeFinalized(address,address,uint256,bytes)": { - "notice": "Emitted when an ETH bridge is finalized on this chain." - }, - "ETHBridgeInitiated(address,address,uint256,bytes)": { - "notice": "Emitted when an ETH bridge is initiated to the other chain." - } - }, - "notice": "The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and L2. In the case that an ERC20 token is native to L1, it will be escrowed within this contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was stored within this contract. After Bedrock, ETH is instead stored inside the OptimismPortal contract. NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples of some token types that may not be properly supported by this contract include, but are not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/L1StandardBridgeProxy.json b/packages/contracts-bedrock/deployments/goerli/L1StandardBridgeProxy.json deleted file mode 100644 index 040726460d21..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/L1StandardBridgeProxy.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "address": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_code", - "type": "bytes" - } - ], - "name": "setCode", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_key", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_value", - "type": "bytes32" - } - ], - "name": "setStorage", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0xd57130025124776619229f980ae08c3097156ab127c897fa9ef17e29bf757a16", - "receipt": { - "to": null, - "from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31", - "contractAddress": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8", - "transactionIndex": 8, - "gasUsed": "614417", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x85ce123b23be93051e83bc9d6dd2bf7817ee0fd338b936684c821020b8285393", - "transactionHash": "0xd57130025124776619229f980ae08c3097156ab127c897fa9ef17e29bf757a16", - "logs": [], - "blockNumber": 7017137, - "cumulativeGasUsed": "5543459", - "status": 1, - "byzantium": true - }, - "args": [ - "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31" - ], - "numDeployments": 1, - "solcInputHash": "0a41276e1e61949b5de1e4f1cd89fb6c", - "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"getImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"setCode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_value\",\"type\":\"bytes32\"}],\"name\":\"setStorage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_owner\":\"Address of the initial contract owner.\"}},\"getImplementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"getOwner()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"setCode(bytes)\":{\"params\":{\"_code\":\"New contract code to run inside this contract.\"}},\"setOwner(address)\":{\"params\":{\"_owner\":\"New owner of the proxy contract.\"}},\"setStorage(bytes32,bytes32)\":{\"params\":{\"_key\":\"Storage key to modify.\",\"_value\":\"New value for the storage key.\"}}},\"title\":\"L1ChugSplashProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getImplementation()\":{\"notice\":\"Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"getOwner()\":{\"notice\":\"Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"setCode(bytes)\":{\"notice\":\"Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner.\"},\"setOwner(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"setStorage(bytes32,bytes32)\":{\"notice\":\"Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/chugsplash/L1ChugSplashProxy.sol\":\"L1ChugSplashProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/chugsplash/L1ChugSplashProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { iL1ChugSplashDeployer } from \\\"./interfaces/iL1ChugSplashDeployer.sol\\\";\\n\\n/**\\n * @title L1ChugSplashProxy\\n * @dev Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\\n * functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty!\\n *\\n * Note for future developers: do NOT make anything in this contract 'public' unless you know what\\n * you're doing. Anything public can potentially have a function signature that conflicts with a\\n * signature attached to the implementation contract. Public functions SHOULD always have the\\n * 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that\\n * modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\\n */\\ncontract L1ChugSplashProxy {\\n /*************\\n * Constants *\\n *************/\\n\\n // \\\"Magic\\\" prefix. When prepended to some arbitrary bytecode and used to create a contract, the\\n // appended bytecode will be deployed as given.\\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _owner Address of the initial contract owner.\\n */\\n constructor(address _owner) {\\n _setOwner(_owner);\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n /**\\n * Blocks a function from being called when the parent signals that the system should be paused\\n * via an isUpgrading function.\\n */\\n modifier onlyWhenNotPaused() {\\n address owner = _getOwner();\\n\\n // We do a low-level call because there's no guarantee that the owner actually *is* an\\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\\n // it turns out that it isn't the right type of contract.\\n (bool success, bytes memory returndata) = owner.staticcall(\\n abi.encodeWithSelector(iL1ChugSplashDeployer.isUpgrading.selector)\\n );\\n\\n // If the call was unsuccessful then we assume that there's no \\\"isUpgrading\\\" method and we\\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\\n // long. If this isn't the case then we can safely ignore the result.\\n if (success && returndata.length == 32) {\\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\\n // case that the isUpgrading function returned something other than 0 or 1. But we only\\n // really care about the case where this value is 0 (= false).\\n uint256 ret = abi.decode(returndata, (uint256));\\n require(ret == 0, \\\"L1ChugSplashProxy: system is currently being upgraded\\\");\\n }\\n\\n _;\\n }\\n\\n /**\\n * Makes a proxy call instead of triggering the given function when the caller is either the\\n * owner or the zero address. Caller can only ever be the zero address if this function is\\n * being called off-chain via eth_call, which is totally fine and can be convenient for\\n * client-side tooling. Avoids situations where the proxy and implementation share a sighash\\n * and the proxy function ends up being called instead of the implementation one.\\n *\\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If there's a\\n * way for someone to send a transaction with msg.sender == address(0) in any real context then\\n * we have much bigger problems. Primary reason to include this additional allowed sender is\\n * because the owner address can be changed dynamically and we do not want clients to have to\\n * keep track of the current owner in order to make an eth_call that doesn't trigger the\\n * proxied contract.\\n */\\n // slither-disable-next-line incorrect-modifier\\n modifier proxyCallIfNotOwner() {\\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the code that should be running behind this proxy. Note that this scheme is a bit\\n * different from the standard proxy scheme where one would typically deploy the code\\n * separately and then set the implementation address. We're doing it this way because it gives\\n * us a lot more freedom on the client side. Can only be triggered by the contract owner.\\n * @param _code New contract code to run inside this contract.\\n */\\n // slither-disable-next-line external-function\\n function setCode(bytes memory _code) public proxyCallIfNotOwner {\\n // Get the code hash of the current implementation.\\n address implementation = _getImplementation();\\n\\n // If the code hash matches the new implementation then we return early.\\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\\n return;\\n }\\n\\n // Create the deploycode by appending the magic prefix.\\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\\n\\n // Deploy the code and set the new implementation address.\\n address newImplementation;\\n assembly {\\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\\n }\\n\\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\\n // actually fail this check. Should only happen if the contract creation from above runs\\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\\n // should be doing this check anyway though.\\n require(\\n _getAccountCodeHash(newImplementation) == keccak256(_code),\\n \\\"L1ChugSplashProxy: code was not correctly deployed.\\\"\\n );\\n\\n _setImplementation(newImplementation);\\n }\\n\\n /**\\n * Modifies some storage slot within the proxy contract. Gives us a lot of power to perform\\n * upgrades in a more transparent way. Only callable by the owner.\\n * @param _key Storage key to modify.\\n * @param _value New value for the storage key.\\n */\\n // slither-disable-next-line external-function\\n function setStorage(bytes32 _key, bytes32 _value) public proxyCallIfNotOwner {\\n assembly {\\n sstore(_key, _value)\\n }\\n }\\n\\n /**\\n * Changes the owner of the proxy contract. Only callable by the owner.\\n * @param _owner New owner of the proxy contract.\\n */\\n // slither-disable-next-line external-function\\n function setOwner(address _owner) public proxyCallIfNotOwner {\\n _setOwner(_owner);\\n }\\n\\n /**\\n * Queries the owner of the proxy contract. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Owner address.\\n */\\n // slither-disable-next-line external-function\\n function getOwner() public proxyCallIfNotOwner returns (address) {\\n return _getOwner();\\n }\\n\\n /**\\n * Queries the implementation address. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Implementation address.\\n */\\n // slither-disable-next-line external-function\\n function getImplementation() public proxyCallIfNotOwner returns (address) {\\n return _getImplementation();\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Sets the implementation address.\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n }\\n\\n /**\\n * Queries the implementation address.\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address implementation;\\n assembly {\\n implementation := sload(IMPLEMENTATION_KEY)\\n }\\n return implementation;\\n }\\n\\n /**\\n * Changes the owner of the proxy contract.\\n * @param _owner New owner of the proxy contract.\\n */\\n function _setOwner(address _owner) internal {\\n assembly {\\n sstore(OWNER_KEY, _owner)\\n }\\n }\\n\\n /**\\n * Queries the owner of the proxy contract.\\n * @return Owner address.\\n */\\n function _getOwner() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n\\n /**\\n * Gets the code hash for a given account.\\n * @param _account Address of the account to get a code hash for.\\n * @return Code hash for the account.\\n */\\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\\n bytes32 codeHash;\\n assembly {\\n codeHash := extcodehash(_account)\\n }\\n return codeHash;\\n }\\n\\n /**\\n * Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal onlyWhenNotPaused {\\n address implementation = _getImplementation();\\n\\n require(implementation != address(0), \\\"L1ChugSplashProxy: implementation is not set yet\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3cb52dfdc2706992572dd5621ae89ba919fd20539b73488a455d564f16f1b8d\",\"license\":\"MIT\"},\"contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title iL1ChugSplashDeployer\\n */\\ninterface iL1ChugSplashDeployer {\\n function isUpgrading() external view returns (bool);\\n}\\n\",\"keccak256\":\"0x9a496d99f111c1091f0c33d6bfc7802a522baa7235614b0014f35e4bbe280e57\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50604051610a5d380380610a5d83398101604081905261002f9161005d565b610057817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b5061008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b6109c18061009c6000396000f3fe60806040526004361061005a5760003560e01c8063893d20e811610043578063893d20e8146100a45780639b0b0fda146100e2578063aaf10f42146101025761005a565b806313af4035146100645780636c5d4ad014610084575b610062610117565b005b34801561007057600080fd5b5061006261007f366004610792565b6103ba565b34801561009057600080fd5b5061006261009f3660046107fe565b61044b565b3480156100b057600080fd5b506100b9610601565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee57600080fd5b506100626100fd3660046108cd565b610698565b34801561010e57600080fd5b506100b9610706565b60006101417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb7947262000000000000000000000000000000000000000000000000000000001790529051919250600091829173ffffffffffffffffffffffffffffffffffffffff8516916101c3919061092a565b600060405180830381855afa9150503d80600081146101fe576040519150601f19603f3d011682016040523d82523d6000602084013e610203565b606091505b5091509150818015610216575080516020145b156102c8576000818060200190518101906102319190610936565b905080156102c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d2069732063757260448201527f72656e746c79206265696e67207570677261646564000000000000000000000060648201526084015b60405180910390fd5b505b60006102f27f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201527f6e206973206e6f7420736574207965740000000000000000000000000000000060648201526084016102bd565b3660008037600080366000845af43d6000803e806103b4573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610413575033155b1561044357610440817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b50565b610440610117565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104a4575033155b156104435760006104d37f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b9050803f8251602084012014156104e8575050565b60405160009061051e907f600d380380600d6000396000f30000000000000000000000000000000000000090859060200161094f565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146105d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527f636f72726563746c79206465706c6f7965642e0000000000000000000000000060648201526084016102bd565b6105fb817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50505050565b600061062b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610662575033155b1561068d57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b610695610117565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806106f1575033155b156106fa579055565b610702610117565b5050565b60006107307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610767575033155b1561068d57507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000602082840312156107a457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146107c857600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561081057600080fd5b813567ffffffffffffffff8082111561082857600080fd5b818401915084601f83011261083c57600080fd5b81358181111561084e5761084e6107cf565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610894576108946107cf565b816040528281528760208487010111156108ad57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156108e057600080fd5b50508035926020909101359150565b6000815160005b8181101561091057602081850181015186830152016108f6565b8181111561091f576000828601525b509290920192915050565b60006107c882846108ef565b60006020828403121561094857600080fd5b5051919050565b7fffffffffffffffffffffffffff00000000000000000000000000000000000000831681526000610983600d8301846108ef565b94935050505056fea2646970667358221220aea34fd8cdcf3a9cced029d5f7b1e628f42ad1514501878e0040df2afddb6e7164736f6c63430008090033", - "deployedBytecode": "0x60806040526004361061005a5760003560e01c8063893d20e811610043578063893d20e8146100a45780639b0b0fda146100e2578063aaf10f42146101025761005a565b806313af4035146100645780636c5d4ad014610084575b610062610117565b005b34801561007057600080fd5b5061006261007f366004610792565b6103ba565b34801561009057600080fd5b5061006261009f3660046107fe565b61044b565b3480156100b057600080fd5b506100b9610601565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee57600080fd5b506100626100fd3660046108cd565b610698565b34801561010e57600080fd5b506100b9610706565b60006101417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb7947262000000000000000000000000000000000000000000000000000000001790529051919250600091829173ffffffffffffffffffffffffffffffffffffffff8516916101c3919061092a565b600060405180830381855afa9150503d80600081146101fe576040519150601f19603f3d011682016040523d82523d6000602084013e610203565b606091505b5091509150818015610216575080516020145b156102c8576000818060200190518101906102319190610936565b905080156102c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d2069732063757260448201527f72656e746c79206265696e67207570677261646564000000000000000000000060648201526084015b60405180910390fd5b505b60006102f27f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201527f6e206973206e6f7420736574207965740000000000000000000000000000000060648201526084016102bd565b3660008037600080366000845af43d6000803e806103b4573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610413575033155b1561044357610440817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b50565b610440610117565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104a4575033155b156104435760006104d37f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b9050803f8251602084012014156104e8575050565b60405160009061051e907f600d380380600d6000396000f30000000000000000000000000000000000000090859060200161094f565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146105d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527f636f72726563746c79206465706c6f7965642e0000000000000000000000000060648201526084016102bd565b6105fb817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50505050565b600061062b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610662575033155b1561068d57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b610695610117565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806106f1575033155b156106fa579055565b610702610117565b5050565b60006107307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610767575033155b1561068d57507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000602082840312156107a457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146107c857600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561081057600080fd5b813567ffffffffffffffff8082111561082857600080fd5b818401915084601f83011261083c57600080fd5b81358181111561084e5761084e6107cf565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610894576108946107cf565b816040528281528760208487010111156108ad57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156108e057600080fd5b50508035926020909101359150565b6000815160005b8181101561091057602081850181015186830152016108f6565b8181111561091f576000828601525b509290920192915050565b60006107c882846108ef565b60006020828403121561094857600080fd5b5051919050565b7fffffffffffffffffffffffffff00000000000000000000000000000000000000831681526000610983600d8301846108ef565b94935050505056fea2646970667358221220aea34fd8cdcf3a9cced029d5f7b1e628f42ad1514501878e0040df2afddb6e7164736f6c63430008090033", - "devdoc": { - "details": "Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!", - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_owner": "Address of the initial contract owner." - } - }, - "getImplementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "getOwner()": { - "returns": { - "_0": "Owner address." - } - }, - "setCode(bytes)": { - "params": { - "_code": "New contract code to run inside this contract." - } - }, - "setOwner(address)": { - "params": { - "_owner": "New owner of the proxy contract." - } - }, - "setStorage(bytes32,bytes32)": { - "params": { - "_key": "Storage key to modify.", - "_value": "New value for the storage key." - } - } - }, - "title": "L1ChugSplashProxy", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "getImplementation()": { - "notice": "Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)." - }, - "getOwner()": { - "notice": "Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)." - }, - "setCode(bytes)": { - "notice": "Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner." - }, - "setOwner(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "setStorage(bytes32,bytes32)": { - "notice": "Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner." - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/L2OutputOracle.json b/packages/contracts-bedrock/deployments/goerli/L2OutputOracle.json deleted file mode 100644 index ae7d019c5d08..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/L2OutputOracle.json +++ /dev/null @@ -1,817 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "uint256", - "name": "_submissionInterval", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_l2BlockTime", - "type": "uint256" - }, - { - "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": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "l2OutputIndex", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "l2BlockNumber", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "l1Timestamp", - "type": "uint256" - } - ], - "name": "OutputProposed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "prevNextOutputIndex", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "newNextOutputIndex", - "type": "uint256" - } - ], - "name": "OutputsDeleted", - "type": "event" - }, - { - "inputs": [], - "name": "CHALLENGER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "FINALIZATION_PERIOD_SECONDS", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_BLOCK_TIME", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PROPOSER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SUBMISSION_INTERVAL", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "challenger", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - } - ], - "name": "computeL2Timestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - } - ], - "name": "deleteL2Outputs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "finalizationPeriodSeconds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - } - ], - "name": "getL2Output", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint128", - "name": "timestamp", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "l2BlockNumber", - "type": "uint128" - } - ], - "internalType": "struct Types.OutputProposal", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - } - ], - "name": "getL2OutputAfter", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint128", - "name": "timestamp", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "l2BlockNumber", - "type": "uint128" - } - ], - "internalType": "struct Types.OutputProposal", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - } - ], - "name": "getL2OutputIndexAfter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_startingBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_startingTimestamp", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_proposer", - "type": "address" - }, - { - "internalType": "address", - "name": "_challenger", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l2BlockTime", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "latestBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "latestOutputIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nextBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nextOutputIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_l1BlockHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_l1BlockNumber", - "type": "uint256" - } - ], - "name": "proposeL2Output", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "proposer", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "startingBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "startingTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "submissionInterval", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0xdb515F91fAA93d894586bA45FEe58d511FDAEC32", - "args": [], - "bytecode": "0x60e06040523480156200001157600080fd5b50604051620018ae380380620018ae8339810160408190526200003491620002f3565b60008211620000b05760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e203000000000000000000000000060648201526084015b60405180910390fd5b60008311620001285760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e20300000000000006064820152608401620000a7565b608083905260a082905260c08190526200014660008080806200014f565b50505062000322565b600054600390610100900460ff1615801562000172575060005460ff8083169116105b620001d75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000a7565b6000805461ffff191660ff83161761010017905542841115620002715760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401620000a7565b60028490556001859055600580546001600160a01b038581166001600160a01b03199283161790925560048054928516929091169190911790556000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6000806000606084860312156200030957600080fd5b8351925060208401519150604084015190509250925092565b60805160a05160c0516115326200037c600039600081816104b3015281816105710152610beb0152600081816101a1015281816103b9015261127401526000818161021f0152818161053b01526112c201526115326000f3fe60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec334814610517578063e1a41bcf1461052c578063f4daa2911461055f57600080fd5b8063ce5db8d6146104a4578063cf8e5cf0146104d7578063d1de856c146104f757600080fd5b8063a25ae557116100b0578063a25ae557146103f0578063a8e4fb901461044c578063bffa7f0f1461047957600080fd5b806389c44cbb1461038a57806393991af3146103aa5780639aaab648146103dd57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa51461033e5780637f00642014610354578063887862721461037457600080fd5b806369f16eec146102e95780636abcf563146102fe5780636b4d98dd1461031357600080fd5b8063529933df11610169578063529933df1461020d578063534db0e21461024157806354fd4d501461029357600080fd5b80622134cc1461018f578063019e2729146101d65780634599c788146101f8575b600080fd5b34801561019b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101e257600080fd5b506101f66101f136600461131c565b610593565b005b34801561020457600080fd5b506101c36107f2565b34801561021957600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561024d57600080fd5b5060045461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cd565b34801561029f57600080fd5b506102dc6040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101cd9190611362565b3480156102f557600080fd5b506101c3610865565b34801561030a57600080fd5b506003546101c3565b34801561031f57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1661026e565b34801561034a57600080fd5b506101c360015481565b34801561036057600080fd5b506101c361036f3660046113d5565b610877565b34801561038057600080fd5b506101c360025481565b34801561039657600080fd5b506101f66103a53660046113d5565b610a8b565b3480156103b657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b6101f66103eb3660046113ee565b610d43565b3480156103fc57600080fd5b5061041061040b3660046113d5565b6111a4565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101cd565b34801561045857600080fd5b5060055461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561048557600080fd5b5060055473ffffffffffffffffffffffffffffffffffffffff1661026e565b3480156104b057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b3480156104e357600080fd5b506104106104f23660046113d5565b611238565b34801561050357600080fd5b506101c36105123660046113d5565b611270565b34801561052357600080fd5b506101c36112be565b34801561053857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b34801561056b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b600054600390610100900460ff161580156105b5575060005460ff8083169116105b610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790554284111561072e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161063d565b600284905560018590556005805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556004805492851692909116919091179055600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6003546000901561085c576003805461080d9060019061144f565b8154811061081d5761081d611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b6003546000906108609060019061144f565b60006108816107f2565b821115610936576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546109eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546000905b80821015610a845760006002610a088385611495565b610a1291906114ad565b90508460038281548110610a2857610a28611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610a7a57610a73816001611495565b9250610a7e565b8091505b506109f2565b5092915050565b60045473ffffffffffffffffffffffffffffffffffffffff163314610b32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161063d565b6003548110610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b7f000000000000000000000000000000000000000000000000000000000000000060038281548110610c1d57610c1d611466565b6000918252602090912060016002909202010154610c4d906fffffffffffffffffffffffffffffffff164261144f565b10610d00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161063d565b6000610d0b60035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60055473ffffffffffffffffffffffffffffffffffffffff163314610e10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b610e186112be565b8314610ecc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161063d565b42610ed684611270565b10610f63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161063d565b83610ff0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161063d565b81156110ac57818140146110ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161063d565b826110b660035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2426040516110e891815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b6040805160608101825260008082526020820181905291810191909152600382815481106111d4576111d4611466565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b6040805160608101825260008082526020820181905291810191909152600361126083610877565b815481106111d4576111d4611466565b60007f0000000000000000000000000000000000000000000000000000000000000000600154836112a1919061144f565b6112ab91906114e8565b6002546112b89190611495565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006112e96107f2565b6108609190611495565b803573ffffffffffffffffffffffffffffffffffffffff8116811461131757600080fd5b919050565b6000806000806080858703121561133257600080fd5b8435935060208501359250611349604086016112f3565b9150611357606086016112f3565b905092959194509250565b600060208083528351808285015260005b8181101561138f57858101830151858201604001528201611373565b818111156113a1576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156113e757600080fd5b5035919050565b6000806000806080858703121561140457600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561146157611461611420565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082198211156114a8576114a8611420565b500190565b6000826114e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561152057611520611420565b50029056fea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec334814610517578063e1a41bcf1461052c578063f4daa2911461055f57600080fd5b8063ce5db8d6146104a4578063cf8e5cf0146104d7578063d1de856c146104f757600080fd5b8063a25ae557116100b0578063a25ae557146103f0578063a8e4fb901461044c578063bffa7f0f1461047957600080fd5b806389c44cbb1461038a57806393991af3146103aa5780639aaab648146103dd57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa51461033e5780637f00642014610354578063887862721461037457600080fd5b806369f16eec146102e95780636abcf563146102fe5780636b4d98dd1461031357600080fd5b8063529933df11610169578063529933df1461020d578063534db0e21461024157806354fd4d501461029357600080fd5b80622134cc1461018f578063019e2729146101d65780634599c788146101f8575b600080fd5b34801561019b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101e257600080fd5b506101f66101f136600461131c565b610593565b005b34801561020457600080fd5b506101c36107f2565b34801561021957600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561024d57600080fd5b5060045461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cd565b34801561029f57600080fd5b506102dc6040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101cd9190611362565b3480156102f557600080fd5b506101c3610865565b34801561030a57600080fd5b506003546101c3565b34801561031f57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1661026e565b34801561034a57600080fd5b506101c360015481565b34801561036057600080fd5b506101c361036f3660046113d5565b610877565b34801561038057600080fd5b506101c360025481565b34801561039657600080fd5b506101f66103a53660046113d5565b610a8b565b3480156103b657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b6101f66103eb3660046113ee565b610d43565b3480156103fc57600080fd5b5061041061040b3660046113d5565b6111a4565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101cd565b34801561045857600080fd5b5060055461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561048557600080fd5b5060055473ffffffffffffffffffffffffffffffffffffffff1661026e565b3480156104b057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b3480156104e357600080fd5b506104106104f23660046113d5565b611238565b34801561050357600080fd5b506101c36105123660046113d5565b611270565b34801561052357600080fd5b506101c36112be565b34801561053857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b34801561056b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b600054600390610100900460ff161580156105b5575060005460ff8083169116105b610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790554284111561072e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161063d565b600284905560018590556005805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556004805492851692909116919091179055600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6003546000901561085c576003805461080d9060019061144f565b8154811061081d5761081d611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b6003546000906108609060019061144f565b60006108816107f2565b821115610936576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546109eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546000905b80821015610a845760006002610a088385611495565b610a1291906114ad565b90508460038281548110610a2857610a28611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610a7a57610a73816001611495565b9250610a7e565b8091505b506109f2565b5092915050565b60045473ffffffffffffffffffffffffffffffffffffffff163314610b32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161063d565b6003548110610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b7f000000000000000000000000000000000000000000000000000000000000000060038281548110610c1d57610c1d611466565b6000918252602090912060016002909202010154610c4d906fffffffffffffffffffffffffffffffff164261144f565b10610d00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161063d565b6000610d0b60035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60055473ffffffffffffffffffffffffffffffffffffffff163314610e10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b610e186112be565b8314610ecc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161063d565b42610ed684611270565b10610f63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161063d565b83610ff0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161063d565b81156110ac57818140146110ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161063d565b826110b660035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2426040516110e891815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b6040805160608101825260008082526020820181905291810191909152600382815481106111d4576111d4611466565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b6040805160608101825260008082526020820181905291810191909152600361126083610877565b815481106111d4576111d4611466565b60007f0000000000000000000000000000000000000000000000000000000000000000600154836112a1919061144f565b6112ab91906114e8565b6002546112b89190611495565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006112e96107f2565b6108609190611495565b803573ffffffffffffffffffffffffffffffffffffffff8116811461131757600080fd5b919050565b6000806000806080858703121561133257600080fd5b8435935060208501359250611349604086016112f3565b9150611357606086016112f3565b905092959194509250565b600060208083528351808285015260005b8181101561138f57858101830151858201604001528201611373565b818111156113a1576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156113e757600080fd5b5035919050565b6000806000806080858703121561140457600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561146157611461611420565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082198211156114a8576114a8611420565b500190565b6000826114e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561152057611520611420565b50029056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "CHALLENGER()": {}, - "PROPOSER()": {}, - "computeL2Timestamp(uint256)": { - "params": { - "_l2BlockNumber": "The L2 block number of the target block." - }, - "returns": { - "_0": "L2 timestamp of the given block." - } - }, - "constructor": { - "params": { - "_finalizationPeriodSeconds": "The amount of time that must pass for an output proposal", - "_l2BlockTime": "The time per L2 block, in seconds.", - "_submissionInterval": "Interval in blocks at which checkpoints must be submitted." - } - }, - "deleteL2Outputs(uint256)": { - "params": { - "_l2OutputIndex": "Index of the first L2 output to be deleted. All outputs after this output will also be deleted." - } - }, - "getL2Output(uint256)": { - "params": { - "_l2OutputIndex": "Index of the output to return." - }, - "returns": { - "_0": "The output at the given index." - } - }, - "getL2OutputAfter(uint256)": { - "params": { - "_l2BlockNumber": "L2 block number to find a checkpoint for." - }, - "returns": { - "_0": "First checkpoint that commits to the given L2 block number." - } - }, - "getL2OutputIndexAfter(uint256)": { - "params": { - "_l2BlockNumber": "L2 block number to find a checkpoint for." - }, - "returns": { - "_0": "Index of the first checkpoint that commits to the given L2 block number." - } - }, - "initialize(uint256,uint256,address,address)": { - "params": { - "_challenger": "The address of the challenger.", - "_proposer": "The address of the proposer.", - "_startingBlockNumber": "Block number for the first recoded L2 block.", - "_startingTimestamp": "Timestamp for the first recoded L2 block." - } - }, - "latestBlockNumber()": { - "returns": { - "_0": "Latest submitted L2 block number." - } - }, - "latestOutputIndex()": { - "returns": { - "_0": "The number of outputs that have been proposed." - } - }, - "nextBlockNumber()": { - "returns": { - "_0": "Next L2 block number." - } - }, - "nextOutputIndex()": { - "returns": { - "_0": "The index of the next output to be proposed." - } - }, - "proposeL2Output(bytes32,uint256,bytes32,uint256)": { - "params": { - "_l1BlockHash": "A block hash which must be included in the current chain.", - "_l1BlockNumber": "The block number with the specified block hash.", - "_l2BlockNumber": "The L2 block number that resulted in _outputRoot.", - "_outputRoot": "The L2 output of the checkpoint block." - } - } - }, - "events": { - "OutputProposed(bytes32,uint256,uint256,uint256)": { - "params": { - "l1Timestamp": "The L1 timestamp when proposed.", - "l2BlockNumber": "The L2 block number of the output root.", - "l2OutputIndex": "The index of the output in the l2Outputs array.", - "outputRoot": "The output root." - } - }, - "OutputsDeleted(uint256,uint256)": { - "params": { - "newNextOutputIndex": "Next L2 output index after the deletion.", - "prevNextOutputIndex": "Next L2 output index before the deletion." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_submissionInterval\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_finalizationPeriodSeconds\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"l2OutputIndex\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"l2BlockNumber\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"l1Timestamp\",\"type\":\"uint256\",\"indexed\":false}],\"type\":\"event\",\"name\":\"OutputProposed\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"prevNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"newNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OutputsDeleted\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"CHALLENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L2_BLOCK_TIME\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"PROPOSER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"challenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"computeL2Timestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"deleteL2Outputs\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"finalizationPeriodSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getL2Output\",\"outputs\":[{\"internalType\":\"struct Types.OutputProposal\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}]}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getL2OutputAfter\",\"outputs\":[{\"internalType\":\"struct Types.OutputProposal\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}]}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getL2OutputIndexAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_proposer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_challenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2BlockTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"latestBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"latestOutputIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"nextBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"nextOutputIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1BlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"proposeL2Output\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"proposer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"startingBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"startingTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"submissionInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"CHALLENGER()\":{\"custom:legacy\":\"\"},\"PROPOSER()\":{\"custom:legacy\":\"\"},\"computeL2Timestamp(uint256)\":{\"params\":{\"_l2BlockNumber\":\"The L2 block number of the target block.\"},\"returns\":{\"_0\":\"L2 timestamp of the given block.\"}},\"constructor\":{\"params\":{\"_finalizationPeriodSeconds\":\"The amount of time that must pass for an output proposal\",\"_l2BlockTime\":\"The time per L2 block, in seconds.\",\"_submissionInterval\":\"Interval in blocks at which checkpoints must be submitted.\"}},\"deleteL2Outputs(uint256)\":{\"params\":{\"_l2OutputIndex\":\"Index of the first L2 output to be deleted. All outputs after this output will also be deleted.\"}},\"getL2Output(uint256)\":{\"params\":{\"_l2OutputIndex\":\"Index of the output to return.\"},\"returns\":{\"_0\":\"The output at the given index.\"}},\"getL2OutputAfter(uint256)\":{\"params\":{\"_l2BlockNumber\":\"L2 block number to find a checkpoint for.\"},\"returns\":{\"_0\":\"First checkpoint that commits to the given L2 block number.\"}},\"getL2OutputIndexAfter(uint256)\":{\"params\":{\"_l2BlockNumber\":\"L2 block number to find a checkpoint for.\"},\"returns\":{\"_0\":\"Index of the first checkpoint that commits to the given L2 block number.\"}},\"initialize(uint256,uint256,address,address)\":{\"params\":{\"_challenger\":\"The address of the challenger.\",\"_proposer\":\"The address of the proposer.\",\"_startingBlockNumber\":\"Block number for the first recoded L2 block.\",\"_startingTimestamp\":\"Timestamp for the first recoded L2 block.\"}},\"latestBlockNumber()\":{\"returns\":{\"_0\":\"Latest submitted L2 block number.\"}},\"latestOutputIndex()\":{\"returns\":{\"_0\":\"The number of outputs that have been proposed.\"}},\"nextBlockNumber()\":{\"returns\":{\"_0\":\"Next L2 block number.\"}},\"nextOutputIndex()\":{\"returns\":{\"_0\":\"The index of the next output to be proposed.\"}},\"proposeL2Output(bytes32,uint256,bytes32,uint256)\":{\"params\":{\"_l1BlockHash\":\"A block hash which must be included in the current chain.\",\"_l1BlockNumber\":\"The block number with the specified block hash.\",\"_l2BlockNumber\":\"The L2 block number that resulted in _outputRoot.\",\"_outputRoot\":\"The L2 output of the checkpoint block.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"CHALLENGER()\":{\"notice\":\"Getter for the challenger address. This will be removed in the future, use `challenger` instead.\"},\"L2_BLOCK_TIME()\":{\"notice\":\"The time between L2 blocks in seconds. Once set, this value MUST NOT be modified. Public getter is legacy and will be removed in the future. Use `l2BlockTime` instead.\"},\"PROPOSER()\":{\"notice\":\"Getter for the proposer address. This will be removed in the future, use `proposer` instead.\"},\"SUBMISSION_INTERVAL()\":{\"notice\":\"The interval in L2 blocks at which checkpoints must be submitted. Although this is immutable, it can safely be modified by upgrading the implementation contract. Public getter is legacy and will be removed in the future. Use `submissionInterval` instead.\"},\"challenger()\":{\"notice\":\"The address of the challenger. Can be updated via reinitialize.\"},\"computeL2Timestamp(uint256)\":{\"notice\":\"Returns the L2 timestamp corresponding to a given L2 block number.\"},\"constructor\":{\"notice\":\"Constructs the L2OutputOracle contract.\"},\"deleteL2Outputs(uint256)\":{\"notice\":\"Deletes all output proposals after and including the proposal that corresponds to the given output index. Only the challenger address can delete outputs.\"},\"finalizationPeriodSeconds()\":{\"notice\":\"Getter for the finalization period.\"},\"getL2Output(uint256)\":{\"notice\":\"Returns an output by index. Needed to return a struct instead of a tuple.\"},\"getL2OutputAfter(uint256)\":{\"notice\":\"Returns the L2 output proposal that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block.\"},\"getL2OutputIndexAfter(uint256)\":{\"notice\":\"Returns the index of the L2 output that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block.\"},\"initialize(uint256,uint256,address,address)\":{\"notice\":\"Initializer.\"},\"l2BlockTime()\":{\"notice\":\"Getter for the L2 block time.\"},\"latestBlockNumber()\":{\"notice\":\"Returns the block number of the latest submitted L2 output proposal. If no proposals been submitted yet then this function will return the starting block number.\"},\"latestOutputIndex()\":{\"notice\":\"Returns the number of outputs that have been proposed. Will revert if no outputs have been proposed yet.\"},\"nextBlockNumber()\":{\"notice\":\"Computes the block number of the next L2 block that needs to be checkpointed.\"},\"nextOutputIndex()\":{\"notice\":\"Returns the index of the next output to be proposed.\"},\"proposeL2Output(bytes32,uint256,bytes32,uint256)\":{\"notice\":\"Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp must be equal to the current value returned by `nextTimestamp()` in order to be accepted. This function may only be called by the Proposer.\"},\"proposer()\":{\"notice\":\"The address of the proposer. Can be updated via reinitialize.\"},\"startingBlockNumber()\":{\"notice\":\"The number of the first L2 block recorded in this contract.\"},\"startingTimestamp()\":{\"notice\":\"The timestamp of the first L2 block recorded in this contract.\"},\"submissionInterval()\":{\"notice\":\"Getter for the output proposal submission interval.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L2OutputOracle.sol\":\"L2OutputOracle\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L2OutputOracle.sol\":{\"keccak256\":\"0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705\",\"urls\":[\"bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc\",\"dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 59681, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "startingBlockNumber", - "offset": 0, - "slot": "1", - "type": "t_uint256" - }, - { - "astId": 59684, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "startingTimestamp", - "offset": 0, - "slot": "2", - "type": "t_uint256" - }, - { - "astId": 59689, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "l2Outputs", - "offset": 0, - "slot": "3", - "type": "t_array(t_struct(OutputProposal)71419_storage)dyn_storage" - }, - { - "astId": 59692, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "challenger", - "offset": 0, - "slot": "4", - "type": "t_address" - }, - { - "astId": 59695, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "proposer", - "offset": 0, - "slot": "5", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_struct(OutputProposal)71419_storage)dyn_storage": { - "encoding": "dynamic_array", - "label": "struct Types.OutputProposal[]", - "numberOfBytes": "32", - "base": "t_struct(OutputProposal)71419_storage" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_struct(OutputProposal)71419_storage": { - "encoding": "inplace", - "label": "struct Types.OutputProposal", - "numberOfBytes": "64", - "members": [ - { - "astId": 71414, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "outputRoot", - "offset": 0, - "slot": "0", - "type": "t_bytes32" - }, - { - "astId": 71416, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "timestamp", - "offset": 0, - "slot": "1", - "type": "t_uint128" - }, - { - "astId": 71418, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "l2BlockNumber", - "offset": 16, - "slot": "1", - "type": "t_uint128" - } - ] - }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x04967474706b357893b9dfdfd8e8ab8d4a2cb3c4e8561d76b5149f4c5e92ad0a", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "CHALLENGER()": { - "notice": "Getter for the challenger address. This will be removed in the future, use `challenger` instead." - }, - "L2_BLOCK_TIME()": { - "notice": "The time between L2 blocks in seconds. Once set, this value MUST NOT be modified. Public getter is legacy and will be removed in the future. Use `l2BlockTime` instead." - }, - "PROPOSER()": { - "notice": "Getter for the proposer address. This will be removed in the future, use `proposer` instead." - }, - "SUBMISSION_INTERVAL()": { - "notice": "The interval in L2 blocks at which checkpoints must be submitted. Although this is immutable, it can safely be modified by upgrading the implementation contract. Public getter is legacy and will be removed in the future. Use `submissionInterval` instead." - }, - "challenger()": { - "notice": "The address of the challenger. Can be updated via reinitialize." - }, - "computeL2Timestamp(uint256)": { - "notice": "Returns the L2 timestamp corresponding to a given L2 block number." - }, - "constructor": { - "notice": "Constructs the L2OutputOracle contract." - }, - "deleteL2Outputs(uint256)": { - "notice": "Deletes all output proposals after and including the proposal that corresponds to the given output index. Only the challenger address can delete outputs." - }, - "finalizationPeriodSeconds()": { - "notice": "Getter for the finalization period." - }, - "getL2Output(uint256)": { - "notice": "Returns an output by index. Needed to return a struct instead of a tuple." - }, - "getL2OutputAfter(uint256)": { - "notice": "Returns the L2 output proposal that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block." - }, - "getL2OutputIndexAfter(uint256)": { - "notice": "Returns the index of the L2 output that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block." - }, - "initialize(uint256,uint256,address,address)": { - "notice": "Initializer." - }, - "l2BlockTime()": { - "notice": "Getter for the L2 block time." - }, - "latestBlockNumber()": { - "notice": "Returns the block number of the latest submitted L2 output proposal. If no proposals been submitted yet then this function will return the starting block number." - }, - "latestOutputIndex()": { - "notice": "Returns the number of outputs that have been proposed. Will revert if no outputs have been proposed yet." - }, - "nextBlockNumber()": { - "notice": "Computes the block number of the next L2 block that needs to be checkpointed." - }, - "nextOutputIndex()": { - "notice": "Returns the index of the next output to be proposed." - }, - "proposeL2Output(bytes32,uint256,bytes32,uint256)": { - "notice": "Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp must be equal to the current value returned by `nextTimestamp()` in order to be accepted. This function may only be called by the Proposer." - }, - "proposer()": { - "notice": "The address of the proposer. Can be updated via reinitialize." - }, - "startingBlockNumber()": { - "notice": "The number of the first L2 block recorded in this contract." - }, - "startingTimestamp()": { - "notice": "The timestamp of the first L2 block recorded in this contract." - }, - "submissionInterval()": { - "notice": "Getter for the output proposal submission interval." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "OutputProposed(bytes32,uint256,uint256,uint256)": { - "notice": "Emitted when an output is proposed." - }, - "OutputsDeleted(uint256,uint256)": { - "notice": "Emitted when outputs are deleted." - } - }, - "notice": "The L2OutputOracle contains an array of L2 state outputs, where each output is a commitment to the state of the L2 chain. Other contracts like the OptimismPortal use these outputs to verify information about the state of L2." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/L2OutputOracleProxy.json b/packages/contracts-bedrock/deployments/goerli/L2OutputOracleProxy.json deleted file mode 100644 index dc44266faa39..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/L2OutputOracleProxy.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x20ddfee1cf52769675d3921f016b9ca4f2cc6d6b107dcf6f3ed1b452f985c2db", - "receipt": { - "to": null, - "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078", - "contractAddress": "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", - "transactionIndex": 13, - "gasUsed": "523800", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000010000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000100000000000000000", - "blockHash": "0xb88a44a833cf2fea693fa468365ef085d8a755757db02a9d0a09e2b507fb00bc", - "transactionHash": "0x20ddfee1cf52769675d3921f016b9ca4f2cc6d6b107dcf6f3ed1b452f985c2db", - "logs": [ - { - "transactionIndex": 13, - "blockNumber": 8299683, - "transactionHash": "0x20ddfee1cf52769675d3921f016b9ca4f2cc6d6b107dcf6f3ed1b452f985c2db", - "address": "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d3670863c3f4b24d7b107900f0b75d4bbc6e0d", - "logIndex": 22, - "blockHash": "0xb88a44a833cf2fea693fa468365ef085d8a755757db02a9d0a09e2b507fb00bc" - } - ], - "blockNumber": 8299683, - "cumulativeGasUsed": "1695349", - "status": 1, - "byzantium": true - }, - "args": [ - "0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d" - ], - "numDeployments": 1, - "solcInputHash": "672fbec9734a08fc34112408d6dc7f7b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\",\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/OptimismMintableERC20Factory.json b/packages/contracts-bedrock/deployments/goerli/OptimismMintableERC20Factory.json deleted file mode 100644 index e7d2e45f747e..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/OptimismMintableERC20Factory.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "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": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "deployer", - "type": "address" - } - ], - "name": "OptimismMintableERC20Created", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - } - ], - "name": "StandardL2TokenCreated", - "type": "event" - }, - { - "inputs": [], - "name": "BRIDGE", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "bridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createOptimismMintableERC20", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "uint8", - "name": "_decimals", - "type": "uint8" - } - ], - "name": "createOptimismMintableERC20WithDecimals", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createStandardL2Token", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_bridge", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x373B66bd178cb2716D5A9596B1a42Ed39b87A535", - "args": [], - "bytecode": "0x608060405234801561001057600080fd5b5061001b6000610020565b610118565b600054600390610100900460ff16158015610042575060005460ff8083169116105b6100a95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805461010060ff841661ffff19909216821717610100600160b01b03191661ff0019620100006001600160a01b0387160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6123cf806101276000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b611ad880620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe6101406040523480156200001257600080fd5b5060405162001ad838038062001ad8833981016040819052620000359162000178565b600160026000858560036200004b8382620002b3565b5060046200005a8282620002b3565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037f565b80516001600160a01b0381168114620000a657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d357600080fd5b81516001600160401b0380821115620000f057620000f0620000ab565b604051601f8301601f19908116603f011681019082821181831017156200011b576200011b620000ab565b816040528381526020925086838588010111156200013857600080fd5b600091505b838210156200015c57858201830151818301840152908201906200013d565b838211156200016e5760008385830101525b9695505050505050565b600080600080600060a086880312156200019157600080fd5b6200019c866200008e565b9450620001ac602087016200008e565b60408701519094506001600160401b0380821115620001ca57600080fd5b620001d889838a01620000c1565b94506060880151915080821115620001ef57600080fd5b50620001fe88828901620000c1565b925050608086015160ff811681146200021657600080fd5b809150509295509295909350565b600181811c908216806200023957607f821691505b6020821081036200025a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ae57600081815260208120601f850160051c81016020861015620002895750805b601f850160051c820191505b81811015620002aa5782815560010162000295565b5050505b505050565b81516001600160401b03811115620002cf57620002cf620000ab565b620002e781620002e0845462000224565b8462000260565b602080601f8311600181146200031f5760008415620003065750858301515b600019600386901b1c1916600185901b178555620002aa565b600085815260208120601f198616915b8281101562000350578886015182559484019460019091019084016200032f565b50858210156200036f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003eb6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", - "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b611ad880620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe6101406040523480156200001257600080fd5b5060405162001ad838038062001ad8833981016040819052620000359162000178565b600160026000858560036200004b8382620002b3565b5060046200005a8282620002b3565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037f565b80516001600160a01b0381168114620000a657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d357600080fd5b81516001600160401b0380821115620000f057620000f0620000ab565b604051601f8301601f19908116603f011681019082821181831017156200011b576200011b620000ab565b816040528381526020925086838588010111156200013857600080fd5b600091505b838210156200015c57858201830151818301840152908201906200013d565b838211156200016e5760008385830101525b9695505050505050565b600080600080600060a086880312156200019157600080fd5b6200019c866200008e565b9450620001ac602087016200008e565b60408701519094506001600160401b0380821115620001ca57600080fd5b620001d889838a01620000c1565b94506060880151915080821115620001ef57600080fd5b50620001fe88828901620000c1565b925050608086015160ff811681146200021657600080fd5b809150509295509295909350565b600181811c908216806200023957607f821691505b6020821081036200025a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ae57600081815260208120601f850160051c81016020861015620002895750805b601f850160051c820191505b81811015620002aa5782815560010162000295565b5050505b505050565b81516001600160401b03811115620002cf57620002cf620000ab565b620002e781620002e0845462000224565b8462000260565b602080601f8311600181146200031f5760008415620003065750858301515b600019600386901b1c1916600185901b178555620002aa565b600085815260208120601f198616915b8281101562000350578886015182559484019460019091019084016200032f565b50858210156200036f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003eb6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "BRIDGE()": {}, - "createOptimismMintableERC20(address,string,string)": { - "params": { - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "createOptimismMintableERC20WithDecimals(address,string,string,uint8)": { - "params": { - "_decimals": "ERC20 decimals", - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "createStandardL2Token(address,string,string)": { - "params": { - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "initialize(address)": { - "params": { - "_bridge": "Address of the StandardBridge on this chain." - } - } - }, - "events": { - "OptimismMintableERC20Created(address,address,address)": { - "params": { - "deployer": "Address of the account that deployed the token.", - "localToken": "Address of the created token on the local chain.", - "remoteToken": "Address of the corresponding token on the remote chain." - } - }, - "StandardL2TokenCreated(address,address)": { - "params": { - "localToken": "Address of the created token on the local chain.", - "remoteToken": "Address of the token on the remote chain." - } - } - }, - "title": "OptimismMintableERC20Factory" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"OptimismMintableERC20Created\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"StandardL2TokenCreated\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"createOptimismMintableERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"_decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"createOptimismMintableERC20WithDecimals\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"createStandardL2Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"BRIDGE()\":{\"custom:legacy\":\"\"},\"createOptimismMintableERC20(address,string,string)\":{\"params\":{\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"createOptimismMintableERC20WithDecimals(address,string,string,uint8)\":{\"params\":{\"_decimals\":\"ERC20 decimals\",\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"createStandardL2Token(address,string,string)\":{\"custom:legacy\":\"@notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the newer createOptimismMintableERC20 function, which has a more intuitive name.\",\"params\":{\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"initialize(address)\":{\"params\":{\"_bridge\":\"Address of the StandardBridge on this chain.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BRIDGE()\":{\"notice\":\"Returns the address of the StandardBridge on this chain. This is a legacy getter, use `bridge` instead.\"},\"bridge()\":{\"notice\":\"Address of the StandardBridge on this chain.\"},\"constructor\":{\"notice\":\"The semver MUST be bumped any time that there is a change in the OptimismMintableERC20 token contract since this contract is responsible for deploying OptimismMintableERC20 contracts.\"},\"createOptimismMintableERC20(address,string,string)\":{\"notice\":\"Creates an instance of the OptimismMintableERC20 contract.\"},\"createOptimismMintableERC20WithDecimals(address,string,string,uint8)\":{\"notice\":\"Creates an instance of the OptimismMintableERC20 contract, with specified decimals.\"},\"initialize(address)\":{\"notice\":\"Initializer.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/OptimismMintableERC20Factory.sol\":\"OptimismMintableERC20Factory\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x6f8133b39efcbcbd5088f195dfacf1bedc3146508429c3865443909af735a04c\",\"urls\":[\"bzz-raw://adc36971e2e120458769f050428d9d2b0504516660345020c2521ee46e6d8abf\",\"dweb:/ipfs/QmPbFusQkZgGKpU8Fv5JoqL4oVeJtM3yqnhRGLY9eZT5zZ\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x39af021e492020fbeb5401371010d4a2fb69debe9596dbbead7bcd7fae248b0b\",\"urls\":[\"bzz-raw://dbeea52e586d2d7de55491a660ca76f75167ba6b43b65d29564864ee9c34a174\",\"dweb:/ipfs/QmS23vFqQxyUXhGuV1nSowZZS93CUkSnsb41uuyRtSeAED\"],\"license\":\"MIT\"},\"src/universal/OptimismMintableERC20Factory.sol\":{\"keccak256\":\"0x60862069899142dc4803d5f5754fd22339980bf74cfc4e2573bb59ff88a99c69\",\"urls\":[\"bzz-raw://8018f9fb11105ab80d4d6fb0bceabf8435d20d0883efa95070ae9e9983e3895c\",\"dweb:/ipfs/Qmf2ghxThySJA1pRvZfj3Q9yJwAZHSxwXAV9GDEqXxEWY9\"],\"license\":\"MIT\"},\"src/universal/Semver.sol\":{\"keccak256\":\"0x9de68ce536aee1aa616b4bf88d7ccc335460e6edd0e7170bdbf94c4fe3d41c60\",\"urls\":[\"bzz-raw://d5909c0b049b03a2bc24816ecf15b0aaf18c04a963174e1eba7624321bef330d\",\"dweb:/ipfs/QmeqdutwZWHqQMXauNR6WY8PrUpfsTiWTQyanbnGM9QqzT\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 5, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 76782, - "contract": "src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory", - "label": "bridge", - "offset": 2, - "slot": "0", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0xd84a03bef7be22fbd6e3f10e95fe63f5a187b2055a3e35f69b3018b28eeb609e", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "BRIDGE()": { - "notice": "Returns the address of the StandardBridge on this chain. This is a legacy getter, use `bridge` instead." - }, - "bridge()": { - "notice": "Address of the StandardBridge on this chain." - }, - "constructor": { - "notice": "The semver MUST be bumped any time that there is a change in the OptimismMintableERC20 token contract since this contract is responsible for deploying OptimismMintableERC20 contracts." - }, - "createOptimismMintableERC20(address,string,string)": { - "notice": "Creates an instance of the OptimismMintableERC20 contract." - }, - "createOptimismMintableERC20WithDecimals(address,string,string,uint8)": { - "notice": "Creates an instance of the OptimismMintableERC20 contract, with specified decimals." - }, - "initialize(address)": { - "notice": "Initializer." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "OptimismMintableERC20Created(address,address,address)": { - "notice": "Emitted whenever a new OptimismMintableERC20 is created." - } - }, - "notice": "OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20 contracts on the network it's deployed to. Simplifies the deployment process for users who may be less familiar with deploying smart contracts. Designed to be backwards compatible with the older StandardL2ERC20Factory contract." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/OptimismMintableERC20FactoryProxy.json b/packages/contracts-bedrock/deployments/goerli/OptimismMintableERC20FactoryProxy.json deleted file mode 100644 index e3d233bd6354..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/OptimismMintableERC20FactoryProxy.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0x883dcF8B05364083D849D8bD226bC8Cb4c42F9C5", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x644dfa60d2e46b047a87d67362580323e8a90cafb9921983a41f3bb02caf8616", - "receipt": { - "to": null, - "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078", - "contractAddress": "0x883dcF8B05364083D849D8bD226bC8Cb4c42F9C5", - "transactionIndex": 42, - "gasUsed": "523800", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000002000000000000000000000000000000000000800000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb6ba4f180c713ba5841f814d52de09d6863565d893d932a705283abfb127f3a4", - "transactionHash": "0x644dfa60d2e46b047a87d67362580323e8a90cafb9921983a41f3bb02caf8616", - "logs": [ - { - "transactionIndex": 42, - "blockNumber": 8299686, - "transactionHash": "0x644dfa60d2e46b047a87d67362580323e8a90cafb9921983a41f3bb02caf8616", - "address": "0x883dcF8B05364083D849D8bD226bC8Cb4c42F9C5", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d3670863c3f4b24d7b107900f0b75d4bbc6e0d", - "logIndex": 114, - "blockHash": "0xb6ba4f180c713ba5841f814d52de09d6863565d893d932a705283abfb127f3a4" - } - ], - "blockNumber": 8299686, - "cumulativeGasUsed": "8264141", - "status": 1, - "byzantium": true - }, - "args": [ - "0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d" - ], - "numDeployments": 1, - "solcInputHash": "672fbec9734a08fc34112408d6dc7f7b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\",\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/OptimismPortal.json b/packages/contracts-bedrock/deployments/goerli/OptimismPortal.json deleted file mode 100644 index 714a726c8cf9..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/OptimismPortal.json +++ /dev/null @@ -1,970 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Paused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "version", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "opaqueData", - "type": "bytes" - } - ], - "name": "TransactionDeposited", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Unpaused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "withdrawalHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "name": "WithdrawalFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "withdrawalHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "WithdrawalProven", - "type": "event" - }, - { - "inputs": [], - "name": "GUARDIAN", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_ORACLE", - "outputs": [ - { - "internalType": "contract L2OutputOracle", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SYSTEM_CONFIG", - "outputs": [ - { - "internalType": "contract SystemConfig", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "_isCreation", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "depositTransaction", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "donateETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "internalType": "struct Types.WithdrawalTransaction", - "name": "_tx", - "type": "tuple" - } - ], - "name": "finalizeWithdrawalTransaction", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "finalizedWithdrawals", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "guardian", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract L2OutputOracle", - "name": "_l2Oracle", - "type": "address" - }, - { - "internalType": "address", - "name": "_guardian", - "type": "address" - }, - { - "internalType": "contract SystemConfig", - "name": "_systemConfig", - "type": "address" - }, - { - "internalType": "bool", - "name": "_paused", - "type": "bool" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - } - ], - "name": "isOutputFinalized", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l2Oracle", - "outputs": [ - { - "internalType": "contract L2OutputOracle", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l2Sender", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "_byteCount", - "type": "uint64" - } - ], - "name": "minimumGasLimit", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "params", - "outputs": [ - { - "internalType": "uint128", - "name": "prevBaseFee", - "type": "uint128" - }, - { - "internalType": "uint64", - "name": "prevBoughtGas", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "prevBlockNum", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "paused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "internalType": "struct Types.WithdrawalTransaction", - "name": "_tx", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "version", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "stateRoot", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "messagePasserStorageRoot", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "latestBlockhash", - "type": "bytes32" - } - ], - "internalType": "struct Types.OutputRootProof", - "name": "_outputRootProof", - "type": "tuple" - }, - { - "internalType": "bytes[]", - "name": "_withdrawalProof", - "type": "bytes[]" - } - ], - "name": "proveWithdrawalTransaction", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "provenWithdrawals", - "outputs": [ - { - "internalType": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint128", - "name": "timestamp", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "l2OutputIndex", - "type": "uint128" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "systemConfig", - "outputs": [ - { - "internalType": "contract SystemConfig", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "unpause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0xD14AA6C7B6D92803F3910Ec1DADCCd0757341862", - "args": [], - "bytecode": "0x60806040523480156200001157600080fd5b506200002260008080600162000028565b62000224565b600054600390610100900460ff161580156200004b575060005460ff8083169116105b620000b45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100908117909155603280546001600160a01b031990811661dead1790915560358054603680546001600160a01b0389811691861691909117909155603780548a831695169490941790935585151592891690930260ff19166001600160a81b0319909316929092171790556200013962000181565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600054610100900460ff16620001ee5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b61545c80620002346000396000f3fe60806040526004361061016d5760003560e01c80638b4c40b0116100cb578063a35d99df1161007f578063e9e05c4211610059578063e9e05c4214610573578063f049875014610586578063fecf9734146105b157600080fd5b8063a35d99df1461040d578063cff0ab9614610446578063e965084c146104e757600080fd5b80639b5f694a116100b05780639b5f694a1461037e5780639bf62d82146103b0578063a14238e7146103dd57600080fd5b80638b4c40b0146101925780638c3152e91461035e57600080fd5b806354fd4d50116101225780636dbffb78116101075780636dbffb78146102fe578063724c184c1461031e5780638456cb591461034957600080fd5b806354fd4d501461027e5780635c975abb146102d457600080fd5b80633f4ba83a116101535780633f4ba83a1461021c578063452a9320146102315780634870496f1461025e57600080fd5b80621c2ff61461019957806333d7e2bd146101ef57600080fd5b36610194576101923334620186a06000604051806020016040528060008152506105d1565b005b600080fd5b3480156101a557600080fd5b50603554610100900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101fb57600080fd5b506036546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022857600080fd5b5061019261086c565b34801561023d57600080fd5b506037546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026a57600080fd5b50610192610279366004614a4a565b610971565b34801561028a57600080fd5b506102c76040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b6040516101e69190614ba0565b3480156102e057600080fd5b506035546102ee9060ff1681565b60405190151581526020016101e6565b34801561030a57600080fd5b506102ee610319366004614bb3565b610fa6565b34801561032a57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101c5565b34801561035557600080fd5b50610192611065565b34801561036a57600080fd5b50610192610379366004614bcc565b611167565b34801561038a57600080fd5b506035546101c590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103bc57600080fd5b506032546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e957600080fd5b506102ee6103f8366004614bb3565b60336020526000908152604090205460ff1681565b34801561041957600080fd5b5061042d610428366004614c26565b611a2b565b60405167ffffffffffffffff90911681526020016101e6565b34801561045257600080fd5b506001546104ae906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101e6565b3480156104f357600080fd5b50610545610502366004614bb3565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101e6565b610192610581366004614c51565b6105d1565b34801561059257600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff166101c5565b3480156105bd57600080fd5b506101926105cc366004614ccc565b611a44565b8260005a905083156106885773ffffffffffffffffffffffffffffffffffffffff87161561068857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6106928351611a2b565b67ffffffffffffffff168567ffffffffffffffff161015610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161067f565b6201d4c0835111156107a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161067f565b333281146107c4575033731111000000000000000000000000000000001111015b600034888888886040516020016107df959493929190614d26565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161084f9190614ba0565b60405180910390a450506108638282611c52565b50505050505050565b60375473ffffffffffffffffffffffffffffffffffffffff163314610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e70617573650000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff16156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161067f565b6035546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101869052600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190614dab565b519050610b50610b4b36869003860186614e10565b611f7f565b8114610bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161067f565b6000610be987611fdb565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d035750805160355460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190614dab565b5114155b610d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161067f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610e589101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610e4e888a614e76565b8a6040013561200b565b610ee4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161067f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6035546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161105f9161010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190614dab565b602001516fffffffffffffffffffffffffffffffff1661202f565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff16331461110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20706175736500000000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610967565b60355460ff16156111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161067f565b600061128882611fdb565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161067f565b603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190614efa565b81602001516fffffffffffffffffffffffffffffffff1610156114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161067f565b6114ee81602001516fffffffffffffffffffffffffffffffff1661202f565b6115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60355460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff9091166004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561162c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116509190614dab565b825181519192501461170a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161067f565b61172981602001516fffffffffffffffffffffffffffffffff1661202f565b6117db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60008381526033602052604090205460ff161561187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161067f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161191c939291906120d4565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061198190841515815260200190565b60405180910390a2801580156119975750326001145b15611a24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161067f565b5050505050565b6000611a38826010614f42565b61105f90615208614f72565b600054600390610100900460ff16158015611a66575060005460ff8083169116105b611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100908117909155603280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811661dead17909155603580546036805473ffffffffffffffffffffffffffffffffffffffff89811691861691909117909155603780548a83169516949094179093558515159289169093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fffffffffffffffffffffff00000000000000000000000000000000000000000090931692909217179055611bed612132565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600154600090611c88907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9e565b90506000611c94612215565b90506000816020015160ff16826000015163ffffffff16611cb59190614fe4565b90508215611dec57600154600090611cec908390700100000000000000000000000000000000900467ffffffffffffffff1661504c565b90506000836040015160ff1683611d0391906150c0565b600154611d239084906fffffffffffffffffffffffffffffffff166150c0565b611d2d9190614fe4565b600154909150600090611d7e90611d579084906fffffffffffffffffffffffffffffffff1661517c565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166122db565b90506001861115611dad57611daa611d5782876040015160ff1660018a611da59190614f9e565b6122fa565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e1f908490700100000000000000000000000000000000900467ffffffffffffffff16614f72565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161067f565b600154600090611f2e906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166151f0565b90506000611f4048633b9aca0061234f565b611f4a908361522d565b905060005a611f599088614f9e565b905080821115611f7557611f75611f708284614f9e565b612366565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611fbe949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611fbe979096959101615241565b60008061201786612394565b9050612025818686866123c6565b9695505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561209e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c29190614efa565b6120cc9083615298565b421192915050565b60008060006120e48660006123f6565b90508061211a576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166121c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067f565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260365483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156122b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d691906152d5565b905090565b60006122f06122ea8585612414565b83612424565b90505b9392505050565b6000670de0b6b3a764000061233b6123128583614fe4565b61232490670de0b6b3a764000061504c565b61233685670de0b6b3a76400006150c0565b612433565b61234590866150c0565b6122f09190614fe4565b60008183101561235f57816122f3565b5090919050565b6000805a90505b825a6123799083614f9e565b101561238f5761238882615374565b915061236d565b505050565b606081805190602001206040516020016123b091815260200190565b6040516020818303038152906040529050919050565b60006123ed846123d7878686612464565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561235f57816122f3565b600081831261235f57816122f3565b60006122f3670de0b6b3a76400008361244b86612ee2565b61245591906150c0565b61245f9190614fe4565b613126565b606060008451116124d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161067f565b60006124dc84613365565b905060006124e986613451565b905060008460405160200161250091815260200190565b60405160208183030381529060405290506000805b8451811015612e59576000858281518110612532576125326153ac565b6020026020010151905084518311156125cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161067f565b82600003612686578051805160209182012060405161261b926125f592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067f565b6127dd565b80515160201161273c57805180516020918201206040516126b0926125f592910190815260200190565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161067f565b8051845160208087019190912082519190920120146127dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161067f565b6127e960106001615298565b816020015151036129c5578451830361295d576128238160200151601081518110612816576128166153ac565b60200260200101516134b4565b965060008751116128b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067f565b600186516128c49190614f9e565b8214612952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067f565b5050505050506122f3565b6000858481518110612971576129716153ac565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061299c5761299c6153ac565b602002602001015190506129af81613614565b95506129bc600186615298565b94505050612e46565b600281602001515103612dbe5760006129dd82613639565b90506000816000815181106129f4576129f46153ac565b016020015160f81c90506000612a0b6002836153db565b612a169060026153fd565b90506000612a27848360ff1661365d565b90506000612a358a8961365d565b90506000612a438383613693565b905080835114612ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067f565b60ff851660021480612aea575060ff85166003145b15612cd95780825114612b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067f565b612b998760200151600181518110612816576128166153ac565b9c5060008d5111612c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067f565b60018c51612c3a9190614f9e565b8814612cc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067f565b5050505050505050505050506122f3565b60ff85161580612cec575060ff85166001145b15612d2b57612d188760200151600181518110612d0b57612d0b6153ac565b6020026020010151613614565b9950612d24818a615298565b9850612db3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161067f565b505050505050612e46565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161067f565b5080612e5181615374565b915050612515565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161067f565b6000808213612f4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b60006060612f5a84613747565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361315757506000919050565b680755bf798b4a1bf1e582126131c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161067f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156133835761338361486a565b6040519080825280602002602001820160405280156133c857816020015b60408051808201909152606080825260208201528152602001906001900390816133a15790505b50915060005b8181101561344a5760405180604001604052808583815181106133f3576133f36153ac565b60200260200101518152602001613422868481518110613415576134156153ac565b602002602001015161381d565b815250838281518110613437576134376153ac565b60209081029190910101526001016133ce565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156134a9578060011b82018184015160001a8060041c8253600f81166001830153505060010161347b565b509295945050505050565b606060008060006134c485613830565b9194509250905060008160018111156134df576134df615420565b1461356c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067f565b6135768284615298565b855114613605576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161067f565b6123ed8560200151848461429d565b606060208260000151106136305761362b826134b4565b61105f565b61105f82614331565b606061105f6136588360200151600081518110612816576128166153ac565b613451565b60608251821061367c575060408051602081019091526000815261105f565b6122f3838384865161368e9190614f9e565b614347565b60008082518451106136a65782516136a9565b83515b90505b808210801561373057508282815181106136c8576136c86153ac565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613707576137076153ac565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613740578160010191506136ac565b5092915050565b60008082116137b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061105f61382b8361451f565b614608565b6000806000808460000151116138ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b6020840151805160001a607f8111613913576000600160009450945094505050614296565b60b78111613b21576000613928608083614f9e565b9050808760000151116139e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161067f565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613a5c57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613b0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161067f565b5060019550935060009250614296915050565b60bf8111613e6f576000613b3660b783614f9e565b905080876000015111613bf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161067f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c60378111613d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161067f565b613d9d8184615298565b895111613e52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161067f565b613e5d836001615298565b97509550600094506142969350505050565b60f78111613f50576000613e8460c083614f9e565b905080876000015111613f3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b600195509350849250614296915050565b6000613f5d60f783614f9e565b905080876000015111614018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161067f565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036140f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c603781116141ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161067f565b6141c48184615298565b895111614279576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b614284836001615298565b97509550600194506142969350505050565b9193909250565b60608167ffffffffffffffff8111156142b8576142b861486a565b6040519080825280601f01601f1916602001820160405280156142e2576020820181803683370190505b50905081156122f35760006142f78486615298565b90506020820160005b84811015614318578281015182820152602001614300565b84811115614327576000858301525b5050509392505050565b606061105f82602001516000846000015161429d565b60608182601f0110156143b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b828284011015614422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b8183018451101561448f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161067f565b6060821580156144ae5760405191506000825260208201604052614516565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156144e75780518352602092830192016144cf565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116145ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b50604080518082019091528151815260209182019181019190915290565b6060600080600061461885613830565b91945092509050600181600181111561463357614633615420565b146146c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067f565b84516146cc8385615298565b14614759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161067f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816147705790505093506000835b865181101561485e576000806147e36040518060400160405280858c600001516147c79190614f9e565b8152602001858c602001516147dc9190615298565b9052613830565b5091509150604051806040016040528083836147ff9190615298565b8152602001848b602001516148149190615298565b815250888581518110614829576148296153ac565b602090810291909101015261483f600185615298565b935061484b8183615298565b6148559084615298565b9250505061479d565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156148e0576148e061486a565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461490a57600080fd5b50565b600082601f83011261491e57600080fd5b813567ffffffffffffffff8111156149385761493861486a565b61496960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614899565b81815284602083860101111561497e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156149ad57600080fd5b60405160c0810167ffffffffffffffff82821081831117156149d1576149d161486a565b8160405282935084358352602085013591506149ec826148e8565b81602084015260408501359150614a02826148e8565b816040840152606085013560608401526080850135608084015260a0850135915080821115614a3057600080fd5b50614a3d8582860161490d565b60a0830152505092915050565b600080600080600085870360e0811215614a6357600080fd5b863567ffffffffffffffff80821115614a7b57600080fd5b614a878a838b0161499b565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614ac057600080fd5b60408901955060c0890135925080831115614ada57600080fd5b828901925089601f840112614aee57600080fd5b8235915080821115614aff57600080fd5b508860208260051b8401011115614b1557600080fd5b959894975092955050506020019190565b60005b83811015614b41578181015183820152602001614b29565b83811115614b50576000848401525b50505050565b60008151808452614b6e816020860160208601614b26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122f36020830184614b56565b600060208284031215614bc557600080fd5b5035919050565b600060208284031215614bde57600080fd5b813567ffffffffffffffff811115614bf557600080fd5b614c018482850161499b565b949350505050565b803567ffffffffffffffff81168114614c2157600080fd5b919050565b600060208284031215614c3857600080fd5b6122f382614c09565b80358015158114614c2157600080fd5b600080600080600060a08688031215614c6957600080fd5b8535614c74816148e8565b945060208601359350614c8960408701614c09565b9250614c9760608701614c41565b9150608086013567ffffffffffffffff811115614cb357600080fd5b614cbf8882890161490d565b9150509295509295909350565b60008060008060808587031215614ce257600080fd5b8435614ced816148e8565b93506020850135614cfd816148e8565b92506040850135614d0d816148e8565b9150614d1b60608601614c41565b905092959194509250565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614d7a816049850160208701614b26565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614c2157600080fd5b600060608284031215614dbd57600080fd5b6040516060810181811067ffffffffffffffff82111715614de057614de061486a565b60405282518152614df360208401614d8b565b6020820152614e0460408401614d8b565b60408201529392505050565b600060808284031215614e2257600080fd5b6040516080810181811067ffffffffffffffff82111715614e4557614e4561486a565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e9157614e9161486a565b8360051b6020614ea2818301614899565b868152918501918181019036841115614eba57600080fd5b865b84811015614eee57803586811115614ed45760008081fd5b614ee036828b0161490d565b845250918301918301614ebc565b50979650505050505050565b600060208284031215614f0c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614f6957614f69614f13565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f9557614f95614f13565b01949350505050565b600082821015614fb057614fb0614f13565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff357614ff3614fb5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504757615047614f13565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508657615086614f13565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150ba576150ba614f13565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561510157615101614f13565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513c5761513c614f13565b6000871292508782058712848416161561515857615158614f13565b8785058712818416161561516e5761516e614f13565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b6576151b6614f13565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151ea576151ea614f13565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561522857615228614f13565b500290565b60008261523c5761523c614fb5565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261528c60c0830184614b56565b98975050505050505050565b600082198211156152ab576152ab614f13565b500190565b805163ffffffff81168114614c2157600080fd5b805160ff81168114614c2157600080fd5b600060c082840312156152e757600080fd5b60405160c0810181811067ffffffffffffffff8211171561530a5761530a61486a565b604052615316836152b0565b8152615324602084016152c4565b6020820152615335604084016152c4565b6040820152615346606084016152b0565b6060820152615357608084016152b0565b608082015261536860a08401614d8b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153a5576153a5614f13565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806153ee576153ee614fb5565b8060ff84160691505092915050565b600060ff821660ff84168082101561541757615417614f13565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061016d5760003560e01c80638b4c40b0116100cb578063a35d99df1161007f578063e9e05c4211610059578063e9e05c4214610573578063f049875014610586578063fecf9734146105b157600080fd5b8063a35d99df1461040d578063cff0ab9614610446578063e965084c146104e757600080fd5b80639b5f694a116100b05780639b5f694a1461037e5780639bf62d82146103b0578063a14238e7146103dd57600080fd5b80638b4c40b0146101925780638c3152e91461035e57600080fd5b806354fd4d50116101225780636dbffb78116101075780636dbffb78146102fe578063724c184c1461031e5780638456cb591461034957600080fd5b806354fd4d501461027e5780635c975abb146102d457600080fd5b80633f4ba83a116101535780633f4ba83a1461021c578063452a9320146102315780634870496f1461025e57600080fd5b80621c2ff61461019957806333d7e2bd146101ef57600080fd5b36610194576101923334620186a06000604051806020016040528060008152506105d1565b005b600080fd5b3480156101a557600080fd5b50603554610100900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101fb57600080fd5b506036546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022857600080fd5b5061019261086c565b34801561023d57600080fd5b506037546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026a57600080fd5b50610192610279366004614a4a565b610971565b34801561028a57600080fd5b506102c76040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b6040516101e69190614ba0565b3480156102e057600080fd5b506035546102ee9060ff1681565b60405190151581526020016101e6565b34801561030a57600080fd5b506102ee610319366004614bb3565b610fa6565b34801561032a57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101c5565b34801561035557600080fd5b50610192611065565b34801561036a57600080fd5b50610192610379366004614bcc565b611167565b34801561038a57600080fd5b506035546101c590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103bc57600080fd5b506032546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e957600080fd5b506102ee6103f8366004614bb3565b60336020526000908152604090205460ff1681565b34801561041957600080fd5b5061042d610428366004614c26565b611a2b565b60405167ffffffffffffffff90911681526020016101e6565b34801561045257600080fd5b506001546104ae906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101e6565b3480156104f357600080fd5b50610545610502366004614bb3565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101e6565b610192610581366004614c51565b6105d1565b34801561059257600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff166101c5565b3480156105bd57600080fd5b506101926105cc366004614ccc565b611a44565b8260005a905083156106885773ffffffffffffffffffffffffffffffffffffffff87161561068857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6106928351611a2b565b67ffffffffffffffff168567ffffffffffffffff161015610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161067f565b6201d4c0835111156107a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161067f565b333281146107c4575033731111000000000000000000000000000000001111015b600034888888886040516020016107df959493929190614d26565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161084f9190614ba0565b60405180910390a450506108638282611c52565b50505050505050565b60375473ffffffffffffffffffffffffffffffffffffffff163314610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e70617573650000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff16156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161067f565b6035546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101869052600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190614dab565b519050610b50610b4b36869003860186614e10565b611f7f565b8114610bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161067f565b6000610be987611fdb565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d035750805160355460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190614dab565b5114155b610d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161067f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610e589101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610e4e888a614e76565b8a6040013561200b565b610ee4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161067f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6035546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161105f9161010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190614dab565b602001516fffffffffffffffffffffffffffffffff1661202f565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff16331461110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20706175736500000000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610967565b60355460ff16156111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161067f565b600061128882611fdb565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161067f565b603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190614efa565b81602001516fffffffffffffffffffffffffffffffff1610156114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161067f565b6114ee81602001516fffffffffffffffffffffffffffffffff1661202f565b6115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60355460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff9091166004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561162c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116509190614dab565b825181519192501461170a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161067f565b61172981602001516fffffffffffffffffffffffffffffffff1661202f565b6117db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60008381526033602052604090205460ff161561187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161067f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161191c939291906120d4565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061198190841515815260200190565b60405180910390a2801580156119975750326001145b15611a24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161067f565b5050505050565b6000611a38826010614f42565b61105f90615208614f72565b600054600390610100900460ff16158015611a66575060005460ff8083169116105b611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100908117909155603280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811661dead17909155603580546036805473ffffffffffffffffffffffffffffffffffffffff89811691861691909117909155603780548a83169516949094179093558515159289169093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fffffffffffffffffffffff00000000000000000000000000000000000000000090931692909217179055611bed612132565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600154600090611c88907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9e565b90506000611c94612215565b90506000816020015160ff16826000015163ffffffff16611cb59190614fe4565b90508215611dec57600154600090611cec908390700100000000000000000000000000000000900467ffffffffffffffff1661504c565b90506000836040015160ff1683611d0391906150c0565b600154611d239084906fffffffffffffffffffffffffffffffff166150c0565b611d2d9190614fe4565b600154909150600090611d7e90611d579084906fffffffffffffffffffffffffffffffff1661517c565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166122db565b90506001861115611dad57611daa611d5782876040015160ff1660018a611da59190614f9e565b6122fa565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e1f908490700100000000000000000000000000000000900467ffffffffffffffff16614f72565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161067f565b600154600090611f2e906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166151f0565b90506000611f4048633b9aca0061234f565b611f4a908361522d565b905060005a611f599088614f9e565b905080821115611f7557611f75611f708284614f9e565b612366565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611fbe949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611fbe979096959101615241565b60008061201786612394565b9050612025818686866123c6565b9695505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561209e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c29190614efa565b6120cc9083615298565b421192915050565b60008060006120e48660006123f6565b90508061211a576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166121c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067f565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260365483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156122b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d691906152d5565b905090565b60006122f06122ea8585612414565b83612424565b90505b9392505050565b6000670de0b6b3a764000061233b6123128583614fe4565b61232490670de0b6b3a764000061504c565b61233685670de0b6b3a76400006150c0565b612433565b61234590866150c0565b6122f09190614fe4565b60008183101561235f57816122f3565b5090919050565b6000805a90505b825a6123799083614f9e565b101561238f5761238882615374565b915061236d565b505050565b606081805190602001206040516020016123b091815260200190565b6040516020818303038152906040529050919050565b60006123ed846123d7878686612464565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561235f57816122f3565b600081831261235f57816122f3565b60006122f3670de0b6b3a76400008361244b86612ee2565b61245591906150c0565b61245f9190614fe4565b613126565b606060008451116124d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161067f565b60006124dc84613365565b905060006124e986613451565b905060008460405160200161250091815260200190565b60405160208183030381529060405290506000805b8451811015612e59576000858281518110612532576125326153ac565b6020026020010151905084518311156125cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161067f565b82600003612686578051805160209182012060405161261b926125f592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067f565b6127dd565b80515160201161273c57805180516020918201206040516126b0926125f592910190815260200190565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161067f565b8051845160208087019190912082519190920120146127dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161067f565b6127e960106001615298565b816020015151036129c5578451830361295d576128238160200151601081518110612816576128166153ac565b60200260200101516134b4565b965060008751116128b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067f565b600186516128c49190614f9e565b8214612952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067f565b5050505050506122f3565b6000858481518110612971576129716153ac565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061299c5761299c6153ac565b602002602001015190506129af81613614565b95506129bc600186615298565b94505050612e46565b600281602001515103612dbe5760006129dd82613639565b90506000816000815181106129f4576129f46153ac565b016020015160f81c90506000612a0b6002836153db565b612a169060026153fd565b90506000612a27848360ff1661365d565b90506000612a358a8961365d565b90506000612a438383613693565b905080835114612ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067f565b60ff851660021480612aea575060ff85166003145b15612cd95780825114612b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067f565b612b998760200151600181518110612816576128166153ac565b9c5060008d5111612c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067f565b60018c51612c3a9190614f9e565b8814612cc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067f565b5050505050505050505050506122f3565b60ff85161580612cec575060ff85166001145b15612d2b57612d188760200151600181518110612d0b57612d0b6153ac565b6020026020010151613614565b9950612d24818a615298565b9850612db3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161067f565b505050505050612e46565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161067f565b5080612e5181615374565b915050612515565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161067f565b6000808213612f4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b60006060612f5a84613747565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361315757506000919050565b680755bf798b4a1bf1e582126131c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161067f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156133835761338361486a565b6040519080825280602002602001820160405280156133c857816020015b60408051808201909152606080825260208201528152602001906001900390816133a15790505b50915060005b8181101561344a5760405180604001604052808583815181106133f3576133f36153ac565b60200260200101518152602001613422868481518110613415576134156153ac565b602002602001015161381d565b815250838281518110613437576134376153ac565b60209081029190910101526001016133ce565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156134a9578060011b82018184015160001a8060041c8253600f81166001830153505060010161347b565b509295945050505050565b606060008060006134c485613830565b9194509250905060008160018111156134df576134df615420565b1461356c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067f565b6135768284615298565b855114613605576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161067f565b6123ed8560200151848461429d565b606060208260000151106136305761362b826134b4565b61105f565b61105f82614331565b606061105f6136588360200151600081518110612816576128166153ac565b613451565b60608251821061367c575060408051602081019091526000815261105f565b6122f3838384865161368e9190614f9e565b614347565b60008082518451106136a65782516136a9565b83515b90505b808210801561373057508282815181106136c8576136c86153ac565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613707576137076153ac565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613740578160010191506136ac565b5092915050565b60008082116137b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061105f61382b8361451f565b614608565b6000806000808460000151116138ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b6020840151805160001a607f8111613913576000600160009450945094505050614296565b60b78111613b21576000613928608083614f9e565b9050808760000151116139e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161067f565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613a5c57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613b0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161067f565b5060019550935060009250614296915050565b60bf8111613e6f576000613b3660b783614f9e565b905080876000015111613bf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161067f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c60378111613d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161067f565b613d9d8184615298565b895111613e52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161067f565b613e5d836001615298565b97509550600094506142969350505050565b60f78111613f50576000613e8460c083614f9e565b905080876000015111613f3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b600195509350849250614296915050565b6000613f5d60f783614f9e565b905080876000015111614018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161067f565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036140f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c603781116141ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161067f565b6141c48184615298565b895111614279576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b614284836001615298565b97509550600194506142969350505050565b9193909250565b60608167ffffffffffffffff8111156142b8576142b861486a565b6040519080825280601f01601f1916602001820160405280156142e2576020820181803683370190505b50905081156122f35760006142f78486615298565b90506020820160005b84811015614318578281015182820152602001614300565b84811115614327576000858301525b5050509392505050565b606061105f82602001516000846000015161429d565b60608182601f0110156143b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b828284011015614422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b8183018451101561448f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161067f565b6060821580156144ae5760405191506000825260208201604052614516565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156144e75780518352602092830192016144cf565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116145ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b50604080518082019091528151815260209182019181019190915290565b6060600080600061461885613830565b91945092509050600181600181111561463357614633615420565b146146c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067f565b84516146cc8385615298565b14614759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161067f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816147705790505093506000835b865181101561485e576000806147e36040518060400160405280858c600001516147c79190614f9e565b8152602001858c602001516147dc9190615298565b9052613830565b5091509150604051806040016040528083836147ff9190615298565b8152602001848b602001516148149190615298565b815250888581518110614829576148296153ac565b602090810291909101015261483f600185615298565b935061484b8183615298565b6148559084615298565b9250505061479d565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156148e0576148e061486a565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461490a57600080fd5b50565b600082601f83011261491e57600080fd5b813567ffffffffffffffff8111156149385761493861486a565b61496960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614899565b81815284602083860101111561497e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156149ad57600080fd5b60405160c0810167ffffffffffffffff82821081831117156149d1576149d161486a565b8160405282935084358352602085013591506149ec826148e8565b81602084015260408501359150614a02826148e8565b816040840152606085013560608401526080850135608084015260a0850135915080821115614a3057600080fd5b50614a3d8582860161490d565b60a0830152505092915050565b600080600080600085870360e0811215614a6357600080fd5b863567ffffffffffffffff80821115614a7b57600080fd5b614a878a838b0161499b565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614ac057600080fd5b60408901955060c0890135925080831115614ada57600080fd5b828901925089601f840112614aee57600080fd5b8235915080821115614aff57600080fd5b508860208260051b8401011115614b1557600080fd5b959894975092955050506020019190565b60005b83811015614b41578181015183820152602001614b29565b83811115614b50576000848401525b50505050565b60008151808452614b6e816020860160208601614b26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122f36020830184614b56565b600060208284031215614bc557600080fd5b5035919050565b600060208284031215614bde57600080fd5b813567ffffffffffffffff811115614bf557600080fd5b614c018482850161499b565b949350505050565b803567ffffffffffffffff81168114614c2157600080fd5b919050565b600060208284031215614c3857600080fd5b6122f382614c09565b80358015158114614c2157600080fd5b600080600080600060a08688031215614c6957600080fd5b8535614c74816148e8565b945060208601359350614c8960408701614c09565b9250614c9760608701614c41565b9150608086013567ffffffffffffffff811115614cb357600080fd5b614cbf8882890161490d565b9150509295509295909350565b60008060008060808587031215614ce257600080fd5b8435614ced816148e8565b93506020850135614cfd816148e8565b92506040850135614d0d816148e8565b9150614d1b60608601614c41565b905092959194509250565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614d7a816049850160208701614b26565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614c2157600080fd5b600060608284031215614dbd57600080fd5b6040516060810181811067ffffffffffffffff82111715614de057614de061486a565b60405282518152614df360208401614d8b565b6020820152614e0460408401614d8b565b60408201529392505050565b600060808284031215614e2257600080fd5b6040516080810181811067ffffffffffffffff82111715614e4557614e4561486a565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e9157614e9161486a565b8360051b6020614ea2818301614899565b868152918501918181019036841115614eba57600080fd5b865b84811015614eee57803586811115614ed45760008081fd5b614ee036828b0161490d565b845250918301918301614ebc565b50979650505050505050565b600060208284031215614f0c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614f6957614f69614f13565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f9557614f95614f13565b01949350505050565b600082821015614fb057614fb0614f13565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff357614ff3614fb5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504757615047614f13565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508657615086614f13565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150ba576150ba614f13565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561510157615101614f13565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513c5761513c614f13565b6000871292508782058712848416161561515857615158614f13565b8785058712818416161561516e5761516e614f13565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b6576151b6614f13565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151ea576151ea614f13565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561522857615228614f13565b500290565b60008261523c5761523c614fb5565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261528c60c0830184614b56565b98975050505050505050565b600082198211156152ab576152ab614f13565b500190565b805163ffffffff81168114614c2157600080fd5b805160ff81168114614c2157600080fd5b600060c082840312156152e757600080fd5b60405160c0810181811067ffffffffffffffff8211171561530a5761530a61486a565b604052615316836152b0565b8152615324602084016152c4565b6020820152615335604084016152c4565b6040820152615346606084016152b0565b6060820152615357608084016152b0565b608082015261536860a08401614d8b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153a5576153a5614f13565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806153ee576153ee614fb5565b8060ff84160691505092915050565b600060ff821660ff84168082101561541757615417614f13565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "GUARDIAN()": {}, - "L2_ORACLE()": {}, - "SYSTEM_CONFIG()": {}, - "depositTransaction(address,uint256,uint64,bool,bytes)": { - "params": { - "_data": "Data to trigger the recipient with.", - "_gasLimit": "Amount of L2 gas to purchase by burning gas on L1.", - "_isCreation": "Whether or not the transaction is a contract creation.", - "_to": "Target address on L2.", - "_value": "ETH value to send to the recipient." - } - }, - "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": { - "params": { - "_tx": "Withdrawal transaction to finalize." - } - }, - "initialize(address,address,address,bool)": { - "params": { - "_guardian": "Address that can pause withdrawals.", - "_l2Oracle": "Address of the L2OutputOracle contract.", - "_paused": "Sets the contract's pausability state.", - "_systemConfig": "Address of the SystemConfig contract." - } - }, - "isOutputFinalized(uint256)": { - "params": { - "_l2OutputIndex": "Index of the L2 output to check." - }, - "returns": { - "_0": "Whether or not the output is finalized." - } - }, - "minimumGasLimit(uint64)": { - "params": { - "_byteCount": "Number of bytes in the calldata." - }, - "returns": { - "_0": "The minimum gas limit for a deposit." - } - }, - "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": { - "params": { - "_l2OutputIndex": "L2 output index to prove against.", - "_outputRootProof": "Inclusion proof of the L2ToL1MessagePasser contract's storage root.", - "_tx": "Withdrawal transaction to finalize.", - "_withdrawalProof": "Inclusion proof of the withdrawal in L2ToL1MessagePasser contract." - } - } - }, - "events": { - "Paused(address)": { - "params": { - "account": "Address of the account triggering the pause." - } - }, - "TransactionDeposited(address,address,uint256,bytes)": { - "params": { - "from": "Address that triggered the deposit transaction.", - "opaqueData": "ABI encoded deposit data to be parsed off-chain.", - "to": "Address that the deposit transaction is directed to.", - "version": "Version of this deposit transaction event." - } - }, - "Unpaused(address)": { - "params": { - "account": "Address of the account triggering the unpause." - } - }, - "WithdrawalFinalized(bytes32,bool)": { - "params": { - "success": "Whether the withdrawal transaction was successful.", - "withdrawalHash": "Hash of the withdrawal transaction." - } - }, - "WithdrawalProven(bytes32,address,address)": { - "params": { - "from": "Address that triggered the withdrawal transaction.", - "to": "Address that the withdrawal transaction is directed to.", - "withdrawalHash": "Hash of the withdrawal transaction." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Paused\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"bytes\",\"name\":\"opaqueData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"TransactionDeposited\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Unpaused\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\",\"indexed\":false}],\"type\":\"event\",\"name\":\"WithdrawalFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"WithdrawalProven\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"GUARDIAN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"SYSTEM_CONFIG\",\"outputs\":[{\"internalType\":\"contract SystemConfig\",\"name\":\"\",\"type\":\"address\"}]},{\"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\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"depositTransaction\"},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"donateETH\"},{\"inputs\":[{\"internalType\":\"struct Types.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeWithdrawalTransaction\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"guardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_guardian\",\"type\":\"address\"},{\"internalType\":\"contract SystemConfig\",\"name\":\"_systemConfig\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"isOutputFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2Oracle\",\"outputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_byteCount\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"pause\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"struct Types.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}]},{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"},{\"internalType\":\"struct Types.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}]},{\"internalType\":\"bytes[]\",\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"proveWithdrawalTransaction\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"provenWithdrawals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2OutputIndex\",\"type\":\"uint128\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"systemConfig\",\"outputs\":[{\"internalType\":\"contract SystemConfig\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"unpause\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"GUARDIAN()\":{\"custom:legacy\":\"\"},\"L2_ORACLE()\":{\"custom:legacy\":\"\"},\"SYSTEM_CONFIG()\":{\"custom:legacy\":\"\"},\"depositTransaction(address,uint256,uint64,bool,bytes)\":{\"params\":{\"_data\":\"Data to trigger the recipient with.\",\"_gasLimit\":\"Amount of L2 gas to purchase by burning gas on L1.\",\"_isCreation\":\"Whether or not the transaction is a contract creation.\",\"_to\":\"Target address on L2.\",\"_value\":\"ETH value to send to the recipient.\"}},\"finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))\":{\"params\":{\"_tx\":\"Withdrawal transaction to finalize.\"}},\"initialize(address,address,address,bool)\":{\"params\":{\"_guardian\":\"Address that can pause withdrawals.\",\"_l2Oracle\":\"Address of the L2OutputOracle contract.\",\"_paused\":\"Sets the contract's pausability state.\",\"_systemConfig\":\"Address of the SystemConfig contract.\"}},\"isOutputFinalized(uint256)\":{\"params\":{\"_l2OutputIndex\":\"Index of the L2 output to check.\"},\"returns\":{\"_0\":\"Whether or not the output is finalized.\"}},\"minimumGasLimit(uint64)\":{\"params\":{\"_byteCount\":\"Number of bytes in the calldata.\"},\"returns\":{\"_0\":\"The minimum gas limit for a deposit.\"}},\"proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])\":{\"params\":{\"_l2OutputIndex\":\"L2 output index to prove against.\",\"_outputRootProof\":\"Inclusion proof of the L2ToL1MessagePasser contract's storage root.\",\"_tx\":\"Withdrawal transaction to finalize.\",\"_withdrawalProof\":\"Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"GUARDIAN()\":{\"notice\":\"Getter for the Guardian\"},\"L2_ORACLE()\":{\"notice\":\"Getter for the L2OutputOracle\"},\"SYSTEM_CONFIG()\":{\"notice\":\"Getter for the SystemConfig\"},\"constructor\":{\"notice\":\"Constructs the OptimismPortal contract.\"},\"depositTransaction(address,uint256,uint64,bool,bytes)\":{\"notice\":\"Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in deriving deposit transactions. Note that if a deposit is made by a contract, its address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider using the CrossDomainMessenger contracts for a simpler developer experience.\"},\"donateETH()\":{\"notice\":\"Accepts ETH value without triggering a deposit to L2. This function mainly exists for the sake of the migration between the legacy Optimism system and Bedrock.\"},\"finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))\":{\"notice\":\"Finalizes a withdrawal transaction.\"},\"finalizedWithdrawals(bytes32)\":{\"notice\":\"A list of withdrawal hashes which have been successfully finalized.\"},\"guardian()\":{\"notice\":\"Address that has the ability to pause and unpause withdrawals.\"},\"initialize(address,address,address,bool)\":{\"notice\":\"Initializer.\"},\"isOutputFinalized(uint256)\":{\"notice\":\"Determine if a given output is finalized. Reverts if the call to L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\"},\"l2Oracle()\":{\"notice\":\"Address of the L2OutputOracle contract.\"},\"l2Sender()\":{\"notice\":\"Address of the L2 account which initiated a withdrawal in this transaction. If the of this variable is the default L2 sender address, then we are NOT inside of a call to finalizeWithdrawalTransaction.\"},\"minimumGasLimit(uint64)\":{\"notice\":\"Computes the minimum gas limit for a deposit. The minimum gas limit linearly increases based on the size of the calldata. This is to prevent users from creating L2 resource usage without paying for it. This function can be used when interacting with the portal to ensure forwards compatibility.\"},\"params()\":{\"notice\":\"EIP-1559 style gas parameters.\"},\"pause()\":{\"notice\":\"Pauses withdrawals.\"},\"paused()\":{\"notice\":\"Determines if cross domain messaging is paused. When set to true, withdrawals are paused. This may be removed in the future.\"},\"proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])\":{\"notice\":\"Proves a withdrawal transaction.\"},\"provenWithdrawals(bytes32)\":{\"notice\":\"A mapping of withdrawal hashes to `ProvenWithdrawal` data.\"},\"systemConfig()\":{\"notice\":\"Address of the SystemConfig contract.\"},\"unpause()\":{\"notice\":\"Unpauses withdrawals.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/OptimismPortal.sol\":\"OptimismPortal\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L2OutputOracle.sol\":{\"keccak256\":\"0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705\",\"urls\":[\"bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc\",\"dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN\"],\"license\":\"MIT\"},\"src/L1/OptimismPortal.sol\":{\"keccak256\":\"0xdca91a921b402d82b455d7f11027514e8a16dca906cf820b3afffe271beb8a13\",\"urls\":[\"bzz-raw://688912b9d6005af8395d5c2eb5c4e3367a8be7b50ea97c34fc6a7ac0e2d8fd6a\",\"dweb:/ipfs/QmNPJDwHpNmJ5VPWAJB8muRpZxYeySZDVoV1TMVN7roijJ\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L1/SystemConfig.sol\":{\"keccak256\":\"0x2b4005c512ab947da105305e3db913b0d7884a954d0aa602f90f7b02188dcda6\",\"urls\":[\"bzz-raw://cc68c9ec4e1aebdd9dba39c7516d38e40a4472b708dfaca1fb9a4742d346db47\",\"dweb:/ipfs/QmX8moXk9cb47tRefi6q15oQAAt18MHEdQojWhrXxz5ykK\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Bytes.sol\":{\"keccak256\":\"0x827f47d123b0fdf3b08816d5b33831811704dbf4e554e53f2269354f6bba8859\",\"urls\":[\"bzz-raw://3137ac7204d30a245a8b0d67aa6da5286f1bd8c90379daab561f84963b6db782\",\"dweb:/ipfs/QmWRhisw3axJK833gUScs23ETh2MLFbVzzqzYVMKSDN3S9\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x9ba74a3b0a11693e622380807d213d5d1250d974e18b2cd768da9cbe719a6778\",\"urls\":[\"bzz-raw://0808d721ed9e05707526ee134faa051d707a95ee6b8bd6e0b1972275da8e5723\",\"dweb:/ipfs/QmcTTPu9xgckfWdbFUAcr2RAgk3J6vzyR4FpV798TjFMeN\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xf8ba770ee6666e73ae43184c700e9c704b2c4ace71f9e3c2227ddc11a8148b4c\",\"urls\":[\"bzz-raw://4702ccee1fe44aea3ee01d59e6152eb755da083f786f00947fec4437c064fe74\",\"dweb:/ipfs/QmQjFj5J7hrEM1dxJjFszzW2Cs7g7eMhYNBXonF2DXBstE\"],\"license\":\"MIT\"},\"src/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0xeaff8315cfd21197bc6bc859c2decf5d4f4838c9c357c502cdf2b1eac863d288\",\"urls\":[\"bzz-raw://79dcdcaa560aea51d138da4f5dc553a1808b6de090b2dc1629f18375edbff681\",\"dweb:/ipfs/QmbE4pUPhf5fLKW4W6cEjhQs55gEDvHmbmoBqkW1yz3bnw\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"],\"license\":\"Apache-2.0\"}},\"version\":1}", - "numDeployments": 4, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 61182, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "params", - "offset": 0, - "slot": "1", - "type": "t_struct(ResourceParams)61165_storage" - }, - { - "astId": 61187, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "__gap", - "offset": 0, - "slot": "2", - "type": "t_array(t_uint256)48_storage" - }, - { - "astId": 60218, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "l2Sender", - "offset": 0, - "slot": "50", - "type": "t_address" - }, - { - "astId": 60223, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "finalizedWithdrawals", - "offset": 0, - "slot": "51", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 60229, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "provenWithdrawals", - "offset": 0, - "slot": "52", - "type": "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)60207_storage)" - }, - { - "astId": 60232, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "paused", - "offset": 0, - "slot": "53", - "type": "t_bool" - }, - { - "astId": 60236, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "l2Oracle", - "offset": 1, - "slot": "53", - "type": "t_contract(L2OutputOracle)60167" - }, - { - "astId": 60240, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "systemConfig", - "offset": 0, - "slot": "54", - "type": "t_contract(SystemConfig)62287" - }, - { - "astId": 60243, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "guardian", - "offset": 0, - "slot": "55", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)48_storage": { - "encoding": "inplace", - "label": "uint256[48]", - "numberOfBytes": "1536", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_contract(L2OutputOracle)60167": { - "encoding": "inplace", - "label": "contract L2OutputOracle", - "numberOfBytes": "20" - }, - "t_contract(SystemConfig)62287": { - "encoding": "inplace", - "label": "contract SystemConfig", - "numberOfBytes": "20" - }, - "t_mapping(t_bytes32,t_bool)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)60207_storage)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal)", - "numberOfBytes": "32", - "value": "t_struct(ProvenWithdrawal)60207_storage" - }, - "t_struct(ProvenWithdrawal)60207_storage": { - "encoding": "inplace", - "label": "struct OptimismPortal.ProvenWithdrawal", - "numberOfBytes": "64", - "members": [ - { - "astId": 60202, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "outputRoot", - "offset": 0, - "slot": "0", - "type": "t_bytes32" - }, - { - "astId": 60204, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "timestamp", - "offset": 0, - "slot": "1", - "type": "t_uint128" - }, - { - "astId": 60206, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "l2OutputIndex", - "offset": 16, - "slot": "1", - "type": "t_uint128" - } - ] - }, - "t_struct(ResourceParams)61165_storage": { - "encoding": "inplace", - "label": "struct ResourceMetering.ResourceParams", - "numberOfBytes": "32", - "members": [ - { - "astId": 61160, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "prevBaseFee", - "offset": 0, - "slot": "0", - "type": "t_uint128" - }, - { - "astId": 61162, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "prevBoughtGas", - "offset": 16, - "slot": "0", - "type": "t_uint64" - }, - { - "astId": 61164, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "prevBlockNum", - "offset": 24, - "slot": "0", - "type": "t_uint64" - } - ] - }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0xc09daa029700464aad63de5c568af17b24c08adac5e9e3f1952db9047df62f6b", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "GUARDIAN()": { - "notice": "Getter for the Guardian" - }, - "L2_ORACLE()": { - "notice": "Getter for the L2OutputOracle" - }, - "SYSTEM_CONFIG()": { - "notice": "Getter for the SystemConfig" - }, - "constructor": { - "notice": "Constructs the OptimismPortal contract." - }, - "depositTransaction(address,uint256,uint64,bool,bytes)": { - "notice": "Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in deriving deposit transactions. Note that if a deposit is made by a contract, its address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider using the CrossDomainMessenger contracts for a simpler developer experience." - }, - "donateETH()": { - "notice": "Accepts ETH value without triggering a deposit to L2. This function mainly exists for the sake of the migration between the legacy Optimism system and Bedrock." - }, - "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": { - "notice": "Finalizes a withdrawal transaction." - }, - "finalizedWithdrawals(bytes32)": { - "notice": "A list of withdrawal hashes which have been successfully finalized." - }, - "guardian()": { - "notice": "Address that has the ability to pause and unpause withdrawals." - }, - "initialize(address,address,address,bool)": { - "notice": "Initializer." - }, - "isOutputFinalized(uint256)": { - "notice": "Determine if a given output is finalized. Reverts if the call to L2_ORACLE.getL2Output reverts. Returns a boolean otherwise." - }, - "l2Oracle()": { - "notice": "Address of the L2OutputOracle contract." - }, - "l2Sender()": { - "notice": "Address of the L2 account which initiated a withdrawal in this transaction. If the of this variable is the default L2 sender address, then we are NOT inside of a call to finalizeWithdrawalTransaction." - }, - "minimumGasLimit(uint64)": { - "notice": "Computes the minimum gas limit for a deposit. The minimum gas limit linearly increases based on the size of the calldata. This is to prevent users from creating L2 resource usage without paying for it. This function can be used when interacting with the portal to ensure forwards compatibility." - }, - "params()": { - "notice": "EIP-1559 style gas parameters." - }, - "pause()": { - "notice": "Pauses withdrawals." - }, - "paused()": { - "notice": "Determines if cross domain messaging is paused. When set to true, withdrawals are paused. This may be removed in the future." - }, - "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": { - "notice": "Proves a withdrawal transaction." - }, - "provenWithdrawals(bytes32)": { - "notice": "A mapping of withdrawal hashes to `ProvenWithdrawal` data." - }, - "systemConfig()": { - "notice": "Address of the SystemConfig contract." - }, - "unpause()": { - "notice": "Unpauses withdrawals." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "Paused(address)": { - "notice": "Emitted when the pause is triggered." - }, - "TransactionDeposited(address,address,uint256,bytes)": { - "notice": "Emitted when a transaction is deposited from L1 to L2. The parameters of this event are read by the rollup node and used to derive deposit transactions on L2." - }, - "Unpaused(address)": { - "notice": "Emitted when the pause is lifted." - }, - "WithdrawalFinalized(bytes32,bool)": { - "notice": "Emitted when a withdrawal transaction is finalized." - }, - "WithdrawalProven(bytes32,address,address)": { - "notice": "Emitted when a withdrawal transaction is proven." - } - }, - "notice": "The OptimismPortal is a low-level contract responsible for passing messages between L1 and L2. Messages sent directly to the OptimismPortal have no form of replayability. Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/OptimismPortalProxy.json b/packages/contracts-bedrock/deployments/goerli/OptimismPortalProxy.json deleted file mode 100644 index 5e2760f63a6d..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/OptimismPortalProxy.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0xa04905ce7658945cde6348e5e8044cb37a6397c53d5acf0144172beb150cb7a7", - "receipt": { - "to": null, - "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078", - "contractAddress": "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", - "transactionIndex": 22, - "gasUsed": "523800", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000010000000000000000000000000000000000000000000000000", - "blockHash": "0x96b7fbc6e5fafa9f7b84079d192b2120b4e3188c1e0d4d0023bf9a5a6466acd4", - "transactionHash": "0xa04905ce7658945cde6348e5e8044cb37a6397c53d5acf0144172beb150cb7a7", - "logs": [ - { - "transactionIndex": 22, - "blockNumber": 8299684, - "transactionHash": "0xa04905ce7658945cde6348e5e8044cb37a6397c53d5acf0144172beb150cb7a7", - "address": "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d3670863c3f4b24d7b107900f0b75d4bbc6e0d", - "logIndex": 52, - "blockHash": "0x96b7fbc6e5fafa9f7b84079d192b2120b4e3188c1e0d4d0023bf9a5a6466acd4" - } - ], - "blockNumber": 8299684, - "cumulativeGasUsed": "4365507", - "status": 1, - "byzantium": true - }, - "args": [ - "0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d" - ], - "numDeployments": 1, - "solcInputHash": "672fbec9734a08fc34112408d6dc7f7b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\",\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/PortalSender.json b/packages/contracts-bedrock/deployments/goerli/PortalSender.json deleted file mode 100644 index 0a18c5368fdc..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/PortalSender.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "address": "0xe7FACd39531ee3C313330E93B4d7a8B8A3c84Aa4", - "abi": [ - { - "inputs": [ - { - "internalType": "contract OptimismPortal", - "name": "_portal", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "PORTAL", - "outputs": [ - { - "internalType": "contract OptimismPortal", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "donate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0x2440cbd5dd9690dab099a0e62e4064c02f7cbca54f0bd60933da46c834d18d92", - "receipt": { - "to": null, - "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078", - "contractAddress": "0xe7FACd39531ee3C313330E93B4d7a8B8A3c84Aa4", - "transactionIndex": 34, - "gasUsed": "118144", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf5bae9de168a815dde2f1dc82cb3753a0a08a5269029a8135a7b8bf9323f1f2e", - "transactionHash": "0x2440cbd5dd9690dab099a0e62e4064c02f7cbca54f0bd60933da46c834d18d92", - "logs": [], - "blockNumber": 8299695, - "cumulativeGasUsed": "11116294", - "status": 1, - "byzantium": true - }, - "args": [ - "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383" - ], - "numDeployments": 1, - "solcInputHash": "672fbec9734a08fc34112408d6dc7f7b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract OptimismPortal\",\"name\":\"_portal\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"PORTAL\",\"outputs\":[{\"internalType\":\"contract OptimismPortal\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"donate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_portal\":\"Address of the OptimismPortal contract.\"}}},\"title\":\"PortalSender\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"PORTAL()\":{\"notice\":\"Address of the OptimismPortal contract.\"},\"donate()\":{\"notice\":\"Sends balance of this contract to the OptimismPortal.\"}},\"notice\":\"The PortalSender is a simple intermediate contract that will transfer the balance of the L1StandardBridge to the OptimismPortal during the Bedrock migration.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/deployment/PortalSender.sol\":\"PortalSender\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L1/L2OutputOracle.sol\":{\"keccak256\":\"0xaa706785b6c6e01b21b47d050a19f83d6afaf8a1db152d0e48463eea55c0c366\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://84f6a9884c4cf7edf499e4182bd9db03876e33df66a0b64307e2c7b997c150b7\",\"dweb:/ipfs/QmR2prJL6HGxPjVjbW5o96C9ekavkarNEy2v11yCGxrdfX\"]},\"contracts/L1/OptimismPortal.sol\":{\"keccak256\":\"0xc9fa6b522c76e6f8de364b4e6f58ebcd073a47b37fb343e444687429bbc2b49e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b3ee3b286e2f5930ee0ec98864c6f51b0d33820678760b668689487a67771f48\",\"dweb:/ipfs/Qmb1KbJXBGzohdyzw5hsMkaEVtPjEEW5BdvDRAUN9Fv7Vy\"]},\"contracts/L1/ResourceMetering.sol\":{\"keccak256\":\"0x23045734df51c2f237d0def7f5e6dda69304bb3cfb554c6c1e934c4c8b07cecc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e6f84a34b842702c3ab4b06da997903046556f3f809716763a351b9f379b7e07\",\"dweb:/ipfs/QmQPyWcbuAMhghZdGSPwSBQdQgZi5hk6Bdg4s7qxaHpcMw\"]},\"contracts/deployment/PortalSender.sol\":{\"keccak256\":\"0xe60d88036d9aa8f8e80a4108ee30ad987564ad996af87a79ba92f6ca35852881\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a4be187cd3d5926592491f722dfa1b1c41a8f4f1abdc8cf3883964f70acb0a44\",\"dweb:/ipfs/QmYsAK4YcRHmPoex2eX2x1r6N76AMk3rdBHHmp6gUT73Fa\"]},\"contracts/libraries/Arithmetic.sol\":{\"keccak256\":\"0xc8858039f87e48e6f18c1af8bc0b03e57cfef564acddfd06e4d91e3db7ac5ed6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2fc79af1e844aa6dc1c68067bfe1d359df8d4e9a3e8881afb3bcfcbf68071714\",\"dweb:/ipfs/QmcNC4k8zmvwj4kZizSenTiWbx2DJQPbwqXXLF4iMbkRVD\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Bytes.sol\":{\"keccak256\":\"0x7aca6593fadf438ee9cd090d8fdc8f94a5202a2eb7f764c9a86f207712d87a48\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://aac32157885c5a08bd0bc7dcd5511f66db12bb20d0c263dd7be9f58b91538fc1\",\"dweb:/ipfs/Qmb1iG11Z53yt9wNbGsuTvoydJXFosDDpWwRSADKyqiCjw\"]},\"contracts/libraries/Constants.sol\":{\"keccak256\":\"0x50a2b69a5e9246945ee1588278753feae90285ff7e675369f0cc5b64acea333c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://75153213766bd271cce59d5284a4a0d2f6283e3c6a9dc31b8ce20a3a4c28c066\",\"dweb:/ipfs/QmcbpwMLYuKUPahVYJ3W7sfntQgHk9RTuR2DUzFMrfPMQr\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/SafeCall.sol\":{\"keccak256\":\"0xbb0621c028c18e9d5a54cf1a8136cf2e77f161de48aeb8d911e230f6b280c9ed\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://924ecc629c7642bc19e2f8a390f1b946d22862c8889453da681b5bc1a45d7703\",\"dweb:/ipfs/QmbNknQ8pzssXDXGVjXxzZ8zh1YnNCWtRJVepiM1TnqoqQ\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x822e7c7ac5d45eac20551ba602d8bff3d22db3538fb32be42c1ab12d7bfca110\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://970823854723de895ca7a24d34269e886a20824c75f706cb41541893b7c78838\",\"dweb:/ipfs/QmSQbEECeTxgUT65pK7Czc4ovAv2FdQ9EHyi5Z8mZgNkXc\"]},\"contracts/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x50763c897f0fe84cb067985ec4d7c5721ce9004a69cf0327f96f8982ee8ca412\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://603af847b43933b075f9aac3a7b3cd65041ffe6d732826695458ca9575e1a809\",\"dweb:/ipfs/QmfByFEaCxT9y1VtqoLi5EsXZ9ihkPfj6g5x7pcPoQ7q2K\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xd27fc945d6dd2821636d840f3766f817823c8e9fbfdb87c2da7c73e4292d2f7f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://497cec37d09ebcdc8d1cccac608a4a0b9b9d83eac6cc7c9e8b73c4c6644e2209\",\"dweb:/ipfs/QmUYMsCcgU6epspvKV9Y6anHyyMb4hd1xVzUZheBY9mfG7\"]},\"contracts/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0x61b03a03779cb1f75cea3b88af16fdfd10629029b4b2d6be5238e71af8ef1b5f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1212951af291c0e033a7119b42de5cad6b6bf32da26777da7c2419e76fa8f314\",\"dweb:/ipfs/QmYbnifDmL6UkP9D1X9GaNLR1Q8wYwmDNeYqkJ71bycaE5\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x979b13465de4996a1105850abbf48abe7f71d5e18a8d4af318597ee14c165fdf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d0881ed7d8371fe1c12b931334e107746fa97d9ecd6aa3c0fca0c0db8581474e\",\"dweb:/ipfs/QmQ9UFwZgWkyFAHrzTtS7m6rghZ8nP9QybEuJ5y9vux5Gv\"]},\"contracts/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"]},\"node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]}},\"version\":1}", - "bytecode": "0x60a060405234801561001057600080fd5b506040516101b53803806101b583398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b6080516101256100906000396000818160400152609701526101256000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80630ff754ea1461003b578063ed88c68e1461008b575b600080fd5b6100627f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b610093610095565b005b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638b4c40b0476040518263ffffffff1660e01b81526004016000604051808303818588803b1580156100fd57600080fd5b505af1158015610111573d6000803e3d6000fd5b505050505056fea164736f6c634300080f000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80630ff754ea1461003b578063ed88c68e1461008b575b600080fd5b6100627f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b610093610095565b005b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638b4c40b0476040518263ffffffff1660e01b81526004016000604051808303818588803b1580156100fd57600080fd5b505af1158015610111573d6000803e3d6000fd5b505050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_portal": "Address of the OptimismPortal contract." - } - } - }, - "title": "PortalSender" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "PORTAL()": { - "notice": "Address of the OptimismPortal contract." - }, - "donate()": { - "notice": "Sends balance of this contract to the OptimismPortal." - } - }, - "notice": "The PortalSender is a simple intermediate contract that will transfer the balance of the L1StandardBridge to the OptimismPortal during the Bedrock migration." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/ProtocolVersions.json b/packages/contracts-bedrock/deployments/goerli/ProtocolVersions.json deleted file mode 100644 index 01adc2635496..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/ProtocolVersions.json +++ /dev/null @@ -1,407 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "version", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "enum ProtocolVersions.UpdateType", - "name": "updateType", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "ConfigUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "RECOMMENDED_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "REQUIRED_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "ProtocolVersion", - "name": "_required", - "type": "uint256" - }, - { - "internalType": "ProtocolVersion", - "name": "_recommended", - "type": "uint256" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "recommended", - "outputs": [ - { - "internalType": "ProtocolVersion", - "name": "out_", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "required", - "outputs": [ - { - "internalType": "ProtocolVersion", - "name": "out_", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "ProtocolVersion", - "name": "_recommended", - "type": "uint256" - } - ], - "name": "setRecommended", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "ProtocolVersion", - "name": "_required", - "type": "uint256" - } - ], - "name": "setRequired", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "args": [], - "bytecode": "0x60806040523480156200001157600080fd5b506200002261dead60008062000028565b620004c9565b600054600390610100900460ff161580156200004b575060005460ff8083169116105b620000b45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620000d26200013a565b620000dd84620001a2565b620000e88362000221565b620000f382620002d1565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b600054610100900460ff16620001965760405162461bcd60e51b815260206004820152602b602482015260008051602062000e9683398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b620001a062000332565b565b620001ac62000399565b6001600160a01b038116620002135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620000ab565b6200021e81620003f5565b50565b620002676200025260017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16200044b565b60001b826200044760201b620004f51760201c565b6000816040516020016200027d91815260200190565b60408051601f19818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051620002c5919062000471565b60405180910390a35050565b620003026200025260017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6200044b565b6000816040516020016200031891815260200190565b60408051601f198184030181529190529050600162000292565b600054610100900460ff166200038e5760405162461bcd60e51b815260206004820152602b602482015260008051602062000e9683398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b620001a033620003f5565b6033546001600160a01b03163314620001a05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000ab565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b9055565b6000828210156200046c57634e487b7160e01b600052601160045260246000fd5b500390565b600060208083528351808285015260005b81811015620004a05785810183015185820160400152820162000482565b81811115620004b3576000604083870101525b50601f01601f1916929092016040019392505050565b6109bd80620004d96000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e736600461085d565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161010091906108e1565b6100ec61016036600461085d565b61021d565b6100ec61022e565b6100ec61017b366004610924565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103ad565b6100f66103e6565b6100ec6101c6366004610957565b610416565b6100f66104ca565b6100f6600081565b6101e36104f9565b6101ec8161057a565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b81565b6102256104f9565b6101ec81610632565b6102366104f9565b61024060006106ac565b565b600054600390610100900460ff16158015610264575060005460ff8083169116105b6102f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561032e610723565b61033784610416565b6103408361057a565b61034982610632565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b60006103e16103dd60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b5490565b905090565b60006103e16103dd60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b61041e6104f9565b73ffffffffffffffffffffffffffffffffffffffff81166104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102ec565b6101ec816106ac565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102ec565b6105ad6105a860017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b829055565b6000816040516020016105c291815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161062691906108e1565b60405180910390a35050565b6106606105a860017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b60008160405160200161067591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060016105f5565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240600054610100900460ff16610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240336106ac565b60006020828403121561086f57600080fd5b5035919050565b6000815180845260005b8181101561089c57602081850181015186830182015201610880565b818111156108ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006108f46020830184610876565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091f57600080fd5b919050565b60008060006060848603121561093957600080fd5b610942846108fb565b95602085013595506040909401359392505050565b60006020828403121561096957600080fd5b6108f4826108fb565b6000828210156109ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e736600461085d565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161010091906108e1565b6100ec61016036600461085d565b61021d565b6100ec61022e565b6100ec61017b366004610924565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103ad565b6100f66103e6565b6100ec6101c6366004610957565b610416565b6100f66104ca565b6100f6600081565b6101e36104f9565b6101ec8161057a565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b81565b6102256104f9565b6101ec81610632565b6102366104f9565b61024060006106ac565b565b600054600390610100900460ff16158015610264575060005460ff8083169116105b6102f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561032e610723565b61033784610416565b6103408361057a565b61034982610632565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b60006103e16103dd60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b5490565b905090565b60006103e16103dd60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b61041e6104f9565b73ffffffffffffffffffffffffffffffffffffffff81166104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102ec565b6101ec816106ac565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102ec565b6105ad6105a860017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b829055565b6000816040516020016105c291815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161062691906108e1565b60405180910390a35050565b6106606105a860017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b60008160405160200161067591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060016105f5565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240600054610100900460ff16610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240336106ac565b60006020828403121561086f57600080fd5b5035919050565b6000815180845260005b8181101561089c57602081850181015186830182015201610880565b818111156108ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006108f46020830184610876565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091f57600080fd5b919050565b60008060006060848603121561093957600080fd5b610942846108fb565b95602085013595506040909401359392505050565b60006020828403121561096957600080fd5b6108f4826108fb565b6000828210156109ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "initialize(address,uint256,uint256)": { - "params": { - "_owner": "Initial owner of the contract.", - "_recommended": "Recommended protocol version to operate on thi chain.", - "_required": "Required protocol version to operate on this chain." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "recommended()": { - "returns": { - "out_": "Recommended protocol version to sync to the head of the chain." - } - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "required()": { - "returns": { - "out_": "Required protocol version to sync to the head of the chain." - } - }, - "setRecommended(uint256)": { - "params": { - "_recommended": "New recommended protocol version." - } - }, - "setRequired(uint256)": { - "params": { - "_required": "New required protocol version." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "params": { - "data": "Encoded update data.", - "updateType": "Type of update.", - "version": "ProtocolVersion version." - } - } - }, - "title": "ProtocolVersions" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"enum ProtocolVersions.UpdateType\",\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ConfigUpdate\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RECOMMENDED_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"REQUIRED_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"ProtocolVersion\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"ProtocolVersion\",\"name\":\"_recommended\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"recommended\",\"outputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"out_\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"renounceOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"required\",\"outputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"out_\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"_recommended\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setRecommended\"},{\"inputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"_required\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setRequired\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address,uint256,uint256)\":{\"params\":{\"_owner\":\"Initial owner of the contract.\",\"_recommended\":\"Recommended protocol version to operate on thi chain.\",\"_required\":\"Required protocol version to operate on this chain.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"recommended()\":{\"returns\":{\"out_\":\"Recommended protocol version to sync to the head of the chain.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"required()\":{\"returns\":{\"out_\":\"Required protocol version to sync to the head of the chain.\"}},\"setRecommended(uint256)\":{\"params\":{\"_recommended\":\"New recommended protocol version.\"}},\"setRequired(uint256)\":{\"params\":{\"_required\":\"New required protocol version.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"RECOMMENDED_SLOT()\":{\"notice\":\"Storage slot that the recommended protocol version is stored at.\"},\"REQUIRED_SLOT()\":{\"notice\":\"Storage slot that the required protocol version is stored at.\"},\"VERSION()\":{\"notice\":\"Version identifier, used for upgrades.\"},\"constructor\":{\"notice\":\"Constructs the ProtocolVersion contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)` A zero version is considered empty and is ignored by nodes.\"},\"initialize(address,uint256,uint256)\":{\"notice\":\"Initializer.\"},\"recommended()\":{\"notice\":\"High level getter for the recommended protocol version.\"},\"required()\":{\"notice\":\"High level getter for the required protocol version.\"},\"setRecommended(uint256)\":{\"notice\":\"Updates the recommended protocol version. Can only be called by the owner.\"},\"setRequired(uint256)\":{\"notice\":\"Updates the required protocol version. Can only be called by the owner.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/ProtocolVersions.sol\":\"ProtocolVersions\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ProtocolVersions.sol\":{\"keccak256\":\"0xa283721c36e2ba3ea1c61faebc364a8884bf3a276f80374cc8017d0e23ea1dfc\",\"urls\":[\"bzz-raw://4ee23cbc9772213c637c767747e5fb1db7c3f0f17d6a1ff576b638f25c6799e8\",\"dweb:/ipfs/QmfKZfFC6fyhQdLk2YrjVBL6eRX1d9CTrPHj7fNPUNXmEq\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 3, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 29536, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 29539, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 31067, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 29408, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 29528, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x668fd8fa1ddfef9a1e20ad56c48e379721d506fbce8f40c80c733ce43e2150c2", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "RECOMMENDED_SLOT()": { - "notice": "Storage slot that the recommended protocol version is stored at." - }, - "REQUIRED_SLOT()": { - "notice": "Storage slot that the required protocol version is stored at." - }, - "VERSION()": { - "notice": "Version identifier, used for upgrades." - }, - "constructor": { - "notice": "Constructs the ProtocolVersion contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)` A zero version is considered empty and is ignored by nodes." - }, - "initialize(address,uint256,uint256)": { - "notice": "Initializer." - }, - "recommended()": { - "notice": "High level getter for the recommended protocol version." - }, - "required()": { - "notice": "High level getter for the required protocol version." - }, - "setRecommended(uint256)": { - "notice": "Updates the recommended protocol version. Can only be called by the owner." - }, - "setRequired(uint256)": { - "notice": "Updates the required protocol version. Can only be called by the owner." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "notice": "Emitted when configuration is updated." - } - }, - "notice": "The ProtocolVersions contract is used to manage superchain protocol version information." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/ProtocolVersionsProxy.json b/packages/contracts-bedrock/deployments/goerli/ProtocolVersionsProxy.json deleted file mode 100644 index f5624f846eb1..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/ProtocolVersionsProxy.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0x0C24F5098774aA366827D667494e9F889f7cFc08", - "args": [ - "0x0a08E04c73f22C65D6dBFF20f87171240df6E519" - ], - "bytecode": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"AdminChanged\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Upgraded\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"changeAdmin\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"upgradeTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/Proxy.sol\":\"Proxy\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xcbdb44713cb15af4c542ef51f2be9e32da0bb4ffc72a03953b38870955023fc3\",\"urls\":[\"bzz-raw://0d7663f5fac06c6344f68aa531d7e9a4e0ba9d2d3a6a3ad8d5bbec4b9b9ca202\",\"dweb:/ipfs/QmbMAZcVwf7syjhKyj3LjwsNMVZiQUPaV5D1zEr4r57v6H\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0x8fcbc468fa4924f81538d4a6674031e12b62b61a88e869fdf099158a0d0c6a19\",\"urls\":[\"bzz-raw://fc7b9bca6c12fdd38e556650ec1eda3cccb0de4d474d2e97904cbd483b147359\",\"dweb:/ipfs/QmW4oKjDtHJj4cNfMhMLDteQEHSUuZtwrrFUJRnZCbQTJd\"],\"license\":\"MIT\"},\"src/universal/Proxy.sol\":{\"keccak256\":\"0xc56de5e39cd44eaeb93f0f8705dd07f4a89f66d5c186522532cf899a104cdbca\",\"urls\":[\"bzz-raw://cd1b595148fa62a798343a23e3330e79fef7d747f039d664482044be9ec0ccf3\",\"dweb:/ipfs/QmeAft6H9wbc9zZZ3prtRaBGGzcPy9yExKAhZHjp1iZ8UF\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 1, - "receipt": { - "transactionHash": "0x697aec3f4cd721a0094428e0f01051d8c355e66e3a81ad4b037f1cd4e888317b", - "transactionIndex": "0x3", - "blockHash": "0x7b58250d6876d9f305908605607e2c4ef8866244d7c2a6d59fabb927f7aa92de", - "blockNumber": "0x948895", - "from": "0x0a08E04c73f22C65D6dBFF20f87171240df6E519", - "to": null, - "cumulativeGasUsed": "0xfee48", - "gasUsed": "0x80250", - "contractAddress": "0x0C24F5098774aA366827D667494e9F889f7cFc08", - "logs": [ - { - "address": "0x0C24F5098774aA366827D667494e9F889f7cFc08", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a08e04c73f22c65d6dbff20f87171240df6e519", - "blockHash": "0x7b58250d6876d9f305908605607e2c4ef8866244d7c2a6d59fabb927f7aa92de", - "blockNumber": "0x948895", - "transactionHash": "0x697aec3f4cd721a0094428e0f01051d8c355e66e3a81ad4b037f1cd4e888317b", - "transactionIndex": "0x3", - "logIndex": "0x5", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000008000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb2d05e0c" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [], - "types": {} - }, - "transactionHash": "0x697aec3f4cd721a0094428e0f01051d8c355e66e3a81ad4b037f1cd4e888317b", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/ProxyAdmin.json b/packages/contracts-bedrock/deployments/goerli/ProxyAdmin.json deleted file mode 100644 index 703a55cc1eae..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/ProxyAdmin.json +++ /dev/null @@ -1,576 +0,0 @@ -{ - "address": "0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "addressManager", - "outputs": [ - { - "internalType": "contract AddressManager", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "_newAdmin", - "type": "address" - } - ], - "name": "changeProxyAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - } - ], - "name": "getProxyAdmin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_proxy", - "type": "address" - } - ], - "name": "getProxyImplementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "implementationName", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isUpgrading", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "proxyType", - "outputs": [ - { - "internalType": "enum ProxyAdmin.ProxyType", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "address", - "name": "_address", - "type": "address" - } - ], - "name": "setAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract AddressManager", - "name": "_address", - "type": "address" - } - ], - "name": "setAddressManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_address", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "setImplementationName", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_address", - "type": "address" - }, - { - "internalType": "enum ProxyAdmin.ProxyType", - "name": "_type", - "type": "uint8" - } - ], - "name": "setProxyType", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "_upgrading", - "type": "bool" - } - ], - "name": "setUpgrading", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgrade", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - } - ], - "transactionHash": "0x1945e7f290b6347aef2843fb9aff577e6d7b6ab0280088dd9151db13e4169549", - "receipt": { - "to": null, - "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078", - "contractAddress": "0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d", - "transactionIndex": 24, - "gasUsed": "1483537", - "logsBloom": "0x00000000008000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400002000000000000000000000010000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000400", - "blockHash": "0xf4b8cf8bae5715632f5d24fa7465ef6796e00022c4edff51b191313b5cc91866", - "transactionHash": "0x1945e7f290b6347aef2843fb9aff577e6d7b6ab0280088dd9151db13e4169549", - "logs": [ - { - "transactionIndex": 24, - "blockNumber": 8299682, - "transactionHash": "0x1945e7f290b6347aef2843fb9aff577e6d7b6ab0280088dd9151db13e4169549", - "address": "0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000956a5152d0f498dba0c5966577bb44262f8f7078" - ], - "data": "0x", - "logIndex": 75, - "blockHash": "0xf4b8cf8bae5715632f5d24fa7465ef6796e00022c4edff51b191313b5cc91866" - }, - { - "transactionIndex": 24, - "blockNumber": 8299682, - "transactionHash": "0x1945e7f290b6347aef2843fb9aff577e6d7b6ab0280088dd9151db13e4169549", - "address": "0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x000000000000000000000000956a5152d0f498dba0c5966577bb44262f8f7078", - "0x000000000000000000000000956a5152d0f498dba0c5966577bb44262f8f7078" - ], - "data": "0x", - "logIndex": 76, - "blockHash": "0xf4b8cf8bae5715632f5d24fa7465ef6796e00022c4edff51b191313b5cc91866" - } - ], - "blockNumber": 8299682, - "cumulativeGasUsed": "5783338", - "status": 1, - "byzantium": true - }, - "args": [ - "0x956a5152D0f498dBA0c5966577bb44262F8F7078" - ], - "numDeployments": 1, - "solcInputHash": "672fbec9734a08fc34112408d6dc7f7b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"contract AddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"implementationName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"proxyType\",\"outputs\":[{\"internalType\":\"enum ProxyAdmin.ProxyType\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract AddressManager\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddressManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"setImplementationName\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"enum ProxyAdmin.ProxyType\",\"name\":\"_type\",\"type\":\"uint8\"}],\"name\":\"setProxyType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_upgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"params\":{\"_newAdmin\":\"Address of the new proxy admin.\",\"_proxy\":\"Address of the proxy to update.\"}},\"constructor\":{\"params\":{\"_owner\":\"Address of the initial owner of this contract.\"}},\"getProxyAdmin(address)\":{\"params\":{\"_proxy\":\"Address of the proxy to get the admin of.\"},\"returns\":{\"_0\":\"Address of the admin of the proxy.\"}},\"getProxyImplementation(address)\":{\"params\":{\"_proxy\":\"Address of the proxy to get the implementation of.\"},\"returns\":{\"_0\":\"Address of the implementation of the proxy.\"}},\"isUpgrading()\":{\"custom:legacy\":\"@notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\",\"returns\":{\"_0\":\"Whether or not there is an upgrade going on. May not actually tell you whether an upgrade is going on, since we don't currently plan to use this variable for anything other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setAddress(string,address)\":{\"custom:legacy\":\"@notice Set an address in the address manager. Since only the owner of the AddressManager can directly modify addresses and the ProxyAdmin will own the AddressManager, this gives the owner of the ProxyAdmin the ability to modify addresses directly.\",\"params\":{\"_address\":\"Address to attach to the given name.\",\"_name\":\"Name to set within the AddressManager.\"}},\"setAddressManager(address)\":{\"params\":{\"_address\":\"Address of the AddressManager.\"}},\"setImplementationName(address,string)\":{\"params\":{\"_address\":\"Address of the ResolvedDelegateProxy.\",\"_name\":\"Name of the implementation for the proxy.\"}},\"setProxyType(address,uint8)\":{\"params\":{\"_address\":\"Address of the proxy.\",\"_type\":\"Type of the proxy.\"}},\"setUpgrading(bool)\":{\"custom:legacy\":\"@notice Set the upgrading status for the Chugsplash proxy type.\",\"params\":{\"_upgrading\":\"Whether or not the system is upgrading.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"params\":{\"_implementation\":\"Address of the new implementation address.\",\"_proxy\":\"Address of the proxy to upgrade.\"}},\"upgradeAndCall(address,address,bytes)\":{\"params\":{\"_data\":\"Data to trigger the new implementation with.\",\"_implementation\":\"Address of the new implementation address.\",\"_proxy\":\"Address of the proxy to upgrade.\"}}},\"title\":\"ProxyAdmin\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addressManager()\":{\"notice\":\"The address of the address manager, this is required to manage the ResolvedDelegateProxy type.\"},\"changeProxyAdmin(address,address)\":{\"notice\":\"Updates the admin of the given proxy address.\"},\"getProxyAdmin(address)\":{\"notice\":\"Returns the admin of the given proxy address.\"},\"getProxyImplementation(address)\":{\"notice\":\"Returns the implementation of the given proxy address.\"},\"implementationName(address)\":{\"notice\":\"A reverse mapping of addresses to names held in the AddressManager. This must be manually kept up to date with changes in the AddressManager for this contract to be able to work as an admin for the ResolvedDelegateProxy type.\"},\"proxyType(address)\":{\"notice\":\"A mapping of proxy types, used for backwards compatibility.\"},\"setAddressManager(address)\":{\"notice\":\"Set the address of the AddressManager. This is required to manage legacy ResolvedDelegateProxy type proxy contracts.\"},\"setImplementationName(address,string)\":{\"notice\":\"Sets the implementation name for a given address. Only required for ResolvedDelegateProxy type proxies that have an implementation name.\"},\"setProxyType(address,uint8)\":{\"notice\":\"Sets the proxy type for a given address. Only required for non-standard (legacy) proxy types.\"},\"upgrade(address,address)\":{\"notice\":\"Changes a proxy's implementation contract.\"},\"upgradeAndCall(address,address,bytes)\":{\"notice\":\"Changes a proxy's implementation contract and delegatecalls the new implementation with some given data. Useful for atomic upgrade-and-initialize calls.\"}},\"notice\":\"This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy, based on the OpenZeppelin implementation. It has backwards compatibility logic to work with the various types of proxies that have been deployed by Optimism in the past.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/legacy/AddressManager.sol\":{\"keccak256\":\"0x7a353d4c92eed32665fd2f0023c55054901293cf7a6e14ca108229d87c047b10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b92ba23601d1951271729a20db931a45639d9376b7c8e2705c23dc360833715a\",\"dweb:/ipfs/QmTKwYLNYYBKZpd31VNBANmguVUwFZifSg7joHSgLZjZCj\"]},\"contracts/legacy/L1ChugSplashProxy.sol\":{\"keccak256\":\"0x6ae7bf6ea9ac0e3511ee4cb15d946589da0dd35098ff762c0b2903d064f24875\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://02028d86c1d38563021d5ead5282271ccdf1c03a24f2eaee056ae2157f0554ee\",\"dweb:/ipfs/QmW9urkBBRTmZ8FjL5Y5zWbdnRhPDruxCCLnpr2CTkozKM\"]},\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\",\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\"]},\"contracts/universal/ProxyAdmin.sol\":{\"keccak256\":\"0x7326011ac425cc9ab4760c29ca559342d4832633b5019a9a61b9e63067374e2a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7d3541272c48443f0b339998553e44600b7bcb4f949e5c94acb5a3acfce19399\",\"dweb:/ipfs/QmNSd9jxACWg8bZE8EgxmRdXwLUQixVs4oiugrVegapUe4\"]},\"node_modules/@openzeppelin/contracts/access/Ownable.sol\":{\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://40fb1b5102468f783961d0af743f91b9980cf66b50d1d12009f6bb1869cea4d2\",\"dweb:/ipfs/QmYqEbJML4jB1GHbzD4cUZDtJg5wVwNm3vDJq1GbyDus8y\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"]}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b5060405162001a5f38038062001a5f8339810160408190526200003491620000a1565b6200003f3362000051565b6200004a8162000051565b50620000d3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208284031215620000b457600080fd5b81516001600160a01b0381168114620000cc57600080fd5b9392505050565b61197c80620000e36000396000f3fe60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "changeProxyAdmin(address,address)": { - "params": { - "_newAdmin": "Address of the new proxy admin.", - "_proxy": "Address of the proxy to update." - } - }, - "constructor": { - "params": { - "_owner": "Address of the initial owner of this contract." - } - }, - "getProxyAdmin(address)": { - "params": { - "_proxy": "Address of the proxy to get the admin of." - }, - "returns": { - "_0": "Address of the admin of the proxy." - } - }, - "getProxyImplementation(address)": { - "params": { - "_proxy": "Address of the proxy to get the implementation of." - }, - "returns": { - "_0": "Address of the implementation of the proxy." - } - }, - "isUpgrading()": { - "returns": { - "_0": "Whether or not there is an upgrade going on. May not actually tell you whether an upgrade is going on, since we don't currently plan to use this variable for anything other than a legacy indicator to fix a UX bug in the ChugSplash proxy." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "setAddress(string,address)": { - "params": { - "_address": "Address to attach to the given name.", - "_name": "Name to set within the AddressManager." - } - }, - "setAddressManager(address)": { - "params": { - "_address": "Address of the AddressManager." - } - }, - "setImplementationName(address,string)": { - "params": { - "_address": "Address of the ResolvedDelegateProxy.", - "_name": "Name of the implementation for the proxy." - } - }, - "setProxyType(address,uint8)": { - "params": { - "_address": "Address of the proxy.", - "_type": "Type of the proxy." - } - }, - "setUpgrading(bool)": { - "params": { - "_upgrading": "Whether or not the system is upgrading." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - }, - "upgrade(address,address)": { - "params": { - "_implementation": "Address of the new implementation address.", - "_proxy": "Address of the proxy to upgrade." - } - }, - "upgradeAndCall(address,address,bytes)": { - "params": { - "_data": "Data to trigger the new implementation with.", - "_implementation": "Address of the new implementation address.", - "_proxy": "Address of the proxy to upgrade." - } - } - }, - "title": "ProxyAdmin" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "addressManager()": { - "notice": "The address of the address manager, this is required to manage the ResolvedDelegateProxy type." - }, - "changeProxyAdmin(address,address)": { - "notice": "Updates the admin of the given proxy address." - }, - "getProxyAdmin(address)": { - "notice": "Returns the admin of the given proxy address." - }, - "getProxyImplementation(address)": { - "notice": "Returns the implementation of the given proxy address." - }, - "implementationName(address)": { - "notice": "A reverse mapping of addresses to names held in the AddressManager. This must be manually kept up to date with changes in the AddressManager for this contract to be able to work as an admin for the ResolvedDelegateProxy type." - }, - "proxyType(address)": { - "notice": "A mapping of proxy types, used for backwards compatibility." - }, - "setAddressManager(address)": { - "notice": "Set the address of the AddressManager. This is required to manage legacy ResolvedDelegateProxy type proxy contracts." - }, - "setImplementationName(address,string)": { - "notice": "Sets the implementation name for a given address. Only required for ResolvedDelegateProxy type proxies that have an implementation name." - }, - "setProxyType(address,uint8)": { - "notice": "Sets the proxy type for a given address. Only required for non-standard (legacy) proxy types." - }, - "upgrade(address,address)": { - "notice": "Changes a proxy's implementation contract." - }, - "upgradeAndCall(address,address,bytes)": { - "notice": "Changes a proxy's implementation contract and delegatecalls the new implementation with some given data. Useful for atomic upgrade-and-initialize calls." - } - }, - "notice": "This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy, based on the OpenZeppelin implementation. It has backwards compatibility logic to work with the various types of proxies that have been deployed by Optimism in the past." - }, - "storageLayout": { - "storage": [ - { - "astId": 40375, - "contract": "contracts/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "_owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 38436, - "contract": "contracts/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "proxyType", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_address,t_enum(ProxyType)38430)" - }, - { - "astId": 38441, - "contract": "contracts/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "implementationName", - "offset": 0, - "slot": "2", - "type": "t_mapping(t_address,t_string_storage)" - }, - { - "astId": 38445, - "contract": "contracts/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "addressManager", - "offset": 0, - "slot": "3", - "type": "t_contract(AddressManager)5619" - }, - { - "astId": 38448, - "contract": "contracts/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "upgrading", - "offset": 20, - "slot": "3", - "type": "t_bool" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(AddressManager)5619": { - "encoding": "inplace", - "label": "contract AddressManager", - "numberOfBytes": "20" - }, - "t_enum(ProxyType)38430": { - "encoding": "inplace", - "label": "enum ProxyAdmin.ProxyType", - "numberOfBytes": "1" - }, - "t_mapping(t_address,t_enum(ProxyType)38430)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => enum ProxyAdmin.ProxyType)", - "numberOfBytes": "32", - "value": "t_enum(ProxyType)38430" - }, - "t_mapping(t_address,t_string_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => string)", - "numberOfBytes": "32", - "value": "t_string_storage" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/SystemConfig.json b/packages/contracts-bedrock/deployments/goerli/SystemConfig.json deleted file mode 100644 index 05116a352b91..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/SystemConfig.json +++ /dev/null @@ -1,1197 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "version", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "enum SystemConfig.UpdateType", - "name": "updateType", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "ConfigUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "BATCH_INBOX_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_CROSS_DOMAIN_MESSENGER_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_ERC_721_BRIDGE_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_STANDARD_BRIDGE_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_OUTPUT_ORACLE_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMISM_PORTAL_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "UNSAFE_BLOCK_SIGNER_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "batchInbox", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "batcherHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "gasLimit", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_overhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_scalar", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_batcherHash", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - }, - { - "internalType": "address", - "name": "_unsafeBlockSigner", - "type": "address" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "_config", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "_startBlock", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_batchInbox", - "type": "address" - }, - { - "components": [ - { - "internalType": "address", - "name": "l1CrossDomainMessenger", - "type": "address" - }, - { - "internalType": "address", - "name": "l1ERC721Bridge", - "type": "address" - }, - { - "internalType": "address", - "name": "l1StandardBridge", - "type": "address" - }, - { - "internalType": "address", - "name": "l2OutputOracle", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismPortal", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismMintableERC20Factory", - "type": "address" - } - ], - "internalType": "struct SystemConfig.Addresses", - "name": "_addresses", - "type": "tuple" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l1CrossDomainMessenger", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1ERC721Bridge", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1StandardBridge", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l2OutputOracle", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minimumGasLimit", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "optimismMintableERC20Factory", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "optimismPortal", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "overhead", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "resourceConfig", - "outputs": [ - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "scalar", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_batcherHash", - "type": "bytes32" - } - ], - "name": "setBatcherHash", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_overhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_scalar", - "type": "uint256" - } - ], - "name": "setGasConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - } - ], - "name": "setGasLimit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "_config", - "type": "tuple" - } - ], - "name": "setResourceConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_unsafeBlockSigner", - "type": "address" - } - ], - "name": "setUnsafeBlockSigner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "startBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "unsafeBlockSigner", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "args": [], - "bytecode": "0x60806040523480156200001157600080fd5b506040805160c080820183526001808352602080840182905260028486015260006060808601829052608080870183905260a08088018490528851968701895283875293860183905296850182905284018190529483018590528201849052620000909361dead93909283928392909183919060001990839062000096565b62000ccc565b600054600390610100900460ff16158015620000b9575060005460ff8083169116105b620001225760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620001406200043a565b6200014b8b620004a2565b620001568862000521565b620001628a8a62000573565b6200016d87620005d7565b620001788662000674565b620001be620001a960017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59862000ba9565b60001b84620006dc60201b62000d211760201c565b62000208620001ef60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063762000ba9565b60001b8360000151620006dc60201b62000d211760201c565b620002526200023960017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a862000ba9565b60001b8360200151620006dc60201b62000d211760201c565b6200029c6200028360017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637762000ba9565b60001b8360400151620006dc60201b62000d211760201c565b620002e6620002cd60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a687181662000ba9565b60001b8360600151620006dc60201b62000d211760201c565b620003306200031760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad62000ba9565b60001b8360800151620006dc60201b62000d211760201c565b6200037a6200036160017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d62000ba9565b60001b8360a00151620006dc60201b62000d211760201c565b6200038584620006e0565b62000390856200070d565b6200039a62000a51565b6001600160401b0316876001600160401b03161015620003ec5760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b600054610100900460ff16620004965760405162461bcd60e51b815260206004820152602b60248201526000805160206200285f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000119565b620004a062000a7e565b565b620004ac62000ae5565b6001600160a01b038116620005135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000119565b6200051e8162000b41565b50565b60678190556040805160208082018490528251808303909101815290820190915260005b60006000805160206200283f8339815191528360405162000567919062000bc3565b60405180910390a35050565b60658290556066819055604080516020810184905290810182905260009060600160408051601f198184030181529190529050600160006000805160206200283f83398151915283604051620005ca919062000bc3565b60405180910390a3505050565b620005e162000a51565b6001600160401b0316816001600160401b03161015620006335760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b606880546001600160401b0319166001600160401b038316908117909155604080516020808201939093528151808203909301835281019052600262000545565b620006ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0882620006dc60201b62000d211760201c565b604080516001600160a01b03831660208201526000910160408051601f198184030181529190529050600362000545565b9055565b8015801590620006f05750606a54155b15620006fb57606a55565b606a546000036200051e5743606a5550565b8060a001516001600160801b0316816060015163ffffffff1611156200079c5760405162461bcd60e51b815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840162000119565b6001816040015160ff16116200080d5760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201526e65206c6172676572207468616e203160881b606482015260840162000119565b606854608082015182516001600160401b03909216916200082f919062000c1b565b63ffffffff161115620008745760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b6000816020015160ff1611620008e55760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201526e06965722063616e6e6f74206265203608c1b606482015260840162000119565b8051602082015163ffffffff82169160ff909116906200090790829062000c46565b62000913919062000c78565b63ffffffff16146200098e5760405162461bcd60e51b815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840162000119565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff96871664ffffffffff199095169490941764010000000060ff948516021764ffffffffff60281b191665010000000000939092169290920263ffffffff60301b19161766010000000000009185169190910217600160501b600160f01b0319166a01000000000000000000009390941692909202600160701b600160f01b03191692909217600160701b6001600160801b0390921691909102179055565b60695460009062000a799063ffffffff6a010000000000000000000082048116911662000ca7565b905090565b600054610100900460ff1662000ada5760405162461bcd60e51b815260206004820152602b60248201526000805160206200285f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000119565b620004a03362000b41565b6033546001600160a01b03163314620004a05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000119565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052601160045260246000fd5b60008282101562000bbe5762000bbe62000b93565b500390565b600060208083528351808285015260005b8181101562000bf25785810183015185820160400152820162000bd4565b8181111562000c05576000604083870101525b50601f01601f1916929092016040019392505050565b600063ffffffff80831681851680830382111562000c3d5762000c3d62000b93565b01949350505050565b600063ffffffff8084168062000c6c57634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b600063ffffffff8083168185168183048111821515161562000c9e5762000c9e62000b93565b02949350505050565b60006001600160401b0382811684821680830382111562000c3d5762000c3d62000b93565b611b438062000cdc6000396000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c8063935f029e1161012a578063cc731b02116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610575578063fd32aa0f1461057d578063ffa1ad741461058557600080fd5b8063f45e65d814610558578063f68016b71461056157600080fd5b8063cc731b0214610400578063dac6e63a14610534578063e81b2c6d1461053c578063f2fde38b1461054557600080fd5b8063bc49ce5f116100f9578063bc49ce5f146103ca578063c4e8ddfa146103d2578063c71973f6146103da578063c9b26f61146103ed57600080fd5b8063935f029e146103945780639b7d7f0a146103a7578063a7119869146103af578063b40a817c146103b757600080fd5b80634add321d116101bd57806354fd4d501161018c57806361d157681161017157806361d1576814610366578063715018a61461036e5780638da5cb5b1461037657600080fd5b806354fd4d50146103155780635d73369c1461035e57600080fd5b80634add321d146102b25780634d9f1559146102d35780634f16540b146102db5780635228a6ac1461030257600080fd5b806318d13918116101f957806318d139181461028457806319f5cea8146102995780631fd19ee1146102a157806348cd4cb1146102a957600080fd5b806306c926571461022b578063078f29cf146102465780630a49cb03146102735780630c18c1621461027b575b600080fd5b61023361058d565b6040519081526020015b60405180910390f35b61024e6105bb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023d565b61024e6105f4565b61023360655481565b610297610292366004611677565b610624565b005b610233610638565b61024e610663565b610233606a5481565b6102ba61068d565b60405167ffffffffffffffff909116815260200161023d565b61024e6106b3565b6102337f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b610297610310366004611807565b6106e3565b6103516040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b60405161023d91906119aa565b610233610a79565b610233610aa4565b610297610acf565b60335473ffffffffffffffffffffffffffffffffffffffff1661024e565b6102976103a23660046119bd565b610ae3565b61024e610af9565b61024e610b29565b6102976103c53660046119df565b610b59565b610233610b6a565b61024e610b95565b6102976103e83660046119fa565b610bc5565b6102976103fb366004611a16565b610bd6565b6104c46040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b60405161023d9190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61024e610be7565b61023360675481565b610297610553366004611677565b610c17565b61023360665481565b6068546102ba9067ffffffffffffffff1681565b610233610ccb565b610233610cf6565b610233600081565b6105b860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b81565b60006105ef6105eb60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b5490565b905090565b60006105ef6105eb60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b61062c610d25565b61063581610da6565b50565b6105b860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60006105ef7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b6069546000906105ef9063ffffffff6a0100000000000000000000820481169116611a75565b60006105ef6105eb60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b600054600390610100900460ff16158015610705575060005460ff8083169116105b610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556107cf610e63565b6107d88b610c17565b6107e188610f02565b6107eb8a8a610f2a565b6107f487610fbb565b6107fd86610da6565b61083061082b60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b849055565b61086461085e60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b83519055565b61089b61089260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60208401519055565b6108d26108c960017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b60408401519055565b61090961090060017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b60608401519055565b61094061093760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b60808401519055565b61097761096e60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60a08401519055565b61098084611099565b610989856110c3565b61099161068d565b67ffffffffffffffff168767ffffffffffffffff161015610a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b6105b860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b6105b860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b610ad7610d25565b610ae16000611537565b565b610aeb610d25565b610af58282610f2a565b5050565b60006105ef6105eb60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60006105ef6105eb60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b610b61610d25565b61063581610fbb565b6105b860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b60006105ef6105eb60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b610bcd610d25565b610635816110c3565b610bde610d25565b61063581610f02565b60006105ef6105eb60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b610c1f610d25565b73ffffffffffffffffffffffffffffffffffffffff8116610cc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161078d565b61063581611537565b6105b860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b6105b860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161078d565b610dcf7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610e5791906119aa565b60405180910390a35050565b600054610100900460ff16610efa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae16115ae565b6067819055604080516020808201849052825180830390910181529082019091526000610e26565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae91906119aa565b60405180910390a3505050565b610fc361068d565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610e26565b80158015906110a85750606a54155b156110b257606a55565b606a546000036106355743606a5550565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611173576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840161078d565b6001816040015160ff161161120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e20310000000000000000000000000000000000606482015260840161078d565b6068546080820151825167ffffffffffffffff9092169161122b9190611aa1565b63ffffffff161115611299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b6000816020015160ff1611611330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f7420626520300000000000000000000000000000000000606482015260840161078d565b8051602082015163ffffffff82169160ff90911690611350908290611ac0565b61135a9190611b0a565b63ffffffff16146113ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840161078d565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae133611537565b803573ffffffffffffffffffffffffffffffffffffffff8116811461167257600080fd5b919050565b60006020828403121561168957600080fd5b6116928261164e565b9392505050565b803567ffffffffffffffff8116811461167257600080fd5b60405160c0810167ffffffffffffffff811182821017156116fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff8116811461167257600080fd5b803560ff8116811461167257600080fd5b600060c0828403121561173857600080fd5b60405160c0810181811067ffffffffffffffff82111715611782577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061179183611701565b815261179f60208401611715565b60208201526117b060408401611715565b60408201526117c160608401611701565b60608201526117d260808401611701565b608082015260a08301356fffffffffffffffffffffffffffffffff811681146117fa57600080fd5b60a0919091015292915050565b6000806000806000806000806000808a8c0361028081121561182857600080fd5b6118318c61164e565b9a5060208c0135995060408c0135985060608c0135975061185460808d01611699565b965061186260a08d0161164e565b95506118718d60c08e01611726565b94506101808c013593506118886101a08d0161164e565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe40820112156118ba57600080fd5b506118c36116b1565b6118d06101c08d0161164e565b81526118df6101e08d0161164e565b60208201526118f16102008d0161164e565b60408201526119036102208d0161164e565b60608201526119156102408d0161164e565b60808201526119276102608d0161164e565b60a0820152809150509295989b9194979a5092959850565b6000815180845260005b8181101561196557602081850181015186830182015201611949565b81811115611977576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611692602083018461193f565b600080604083850312156119d057600080fd5b50508035926020909101359150565b6000602082840312156119f157600080fd5b61169282611699565b600060c08284031215611a0c57600080fd5b6116928383611726565b600060208284031215611a2857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611a7057611a70611a2f565b500390565b600067ffffffffffffffff808316818516808303821115611a9857611a98611a2f565b01949350505050565b600063ffffffff808316818516808303821115611a9857611a98611a2f565b600063ffffffff80841680611afe577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611b2d57611b2d611a2f565b0294935050505056fea164736f6c634300080f000a53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77001d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102265760003560e01c8063935f029e1161012a578063cc731b02116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610575578063fd32aa0f1461057d578063ffa1ad741461058557600080fd5b8063f45e65d814610558578063f68016b71461056157600080fd5b8063cc731b0214610400578063dac6e63a14610534578063e81b2c6d1461053c578063f2fde38b1461054557600080fd5b8063bc49ce5f116100f9578063bc49ce5f146103ca578063c4e8ddfa146103d2578063c71973f6146103da578063c9b26f61146103ed57600080fd5b8063935f029e146103945780639b7d7f0a146103a7578063a7119869146103af578063b40a817c146103b757600080fd5b80634add321d116101bd57806354fd4d501161018c57806361d157681161017157806361d1576814610366578063715018a61461036e5780638da5cb5b1461037657600080fd5b806354fd4d50146103155780635d73369c1461035e57600080fd5b80634add321d146102b25780634d9f1559146102d35780634f16540b146102db5780635228a6ac1461030257600080fd5b806318d13918116101f957806318d139181461028457806319f5cea8146102995780631fd19ee1146102a157806348cd4cb1146102a957600080fd5b806306c926571461022b578063078f29cf146102465780630a49cb03146102735780630c18c1621461027b575b600080fd5b61023361058d565b6040519081526020015b60405180910390f35b61024e6105bb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023d565b61024e6105f4565b61023360655481565b610297610292366004611677565b610624565b005b610233610638565b61024e610663565b610233606a5481565b6102ba61068d565b60405167ffffffffffffffff909116815260200161023d565b61024e6106b3565b6102337f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b610297610310366004611807565b6106e3565b6103516040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b60405161023d91906119aa565b610233610a79565b610233610aa4565b610297610acf565b60335473ffffffffffffffffffffffffffffffffffffffff1661024e565b6102976103a23660046119bd565b610ae3565b61024e610af9565b61024e610b29565b6102976103c53660046119df565b610b59565b610233610b6a565b61024e610b95565b6102976103e83660046119fa565b610bc5565b6102976103fb366004611a16565b610bd6565b6104c46040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b60405161023d9190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61024e610be7565b61023360675481565b610297610553366004611677565b610c17565b61023360665481565b6068546102ba9067ffffffffffffffff1681565b610233610ccb565b610233610cf6565b610233600081565b6105b860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b81565b60006105ef6105eb60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b5490565b905090565b60006105ef6105eb60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b61062c610d25565b61063581610da6565b50565b6105b860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60006105ef7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b6069546000906105ef9063ffffffff6a0100000000000000000000820481169116611a75565b60006105ef6105eb60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b600054600390610100900460ff16158015610705575060005460ff8083169116105b610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556107cf610e63565b6107d88b610c17565b6107e188610f02565b6107eb8a8a610f2a565b6107f487610fbb565b6107fd86610da6565b61083061082b60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b849055565b61086461085e60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b83519055565b61089b61089260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60208401519055565b6108d26108c960017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b60408401519055565b61090961090060017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b60608401519055565b61094061093760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b60808401519055565b61097761096e60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60a08401519055565b61098084611099565b610989856110c3565b61099161068d565b67ffffffffffffffff168767ffffffffffffffff161015610a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b6105b860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b6105b860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b610ad7610d25565b610ae16000611537565b565b610aeb610d25565b610af58282610f2a565b5050565b60006105ef6105eb60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60006105ef6105eb60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b610b61610d25565b61063581610fbb565b6105b860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b60006105ef6105eb60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b610bcd610d25565b610635816110c3565b610bde610d25565b61063581610f02565b60006105ef6105eb60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b610c1f610d25565b73ffffffffffffffffffffffffffffffffffffffff8116610cc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161078d565b61063581611537565b6105b860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b6105b860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161078d565b610dcf7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610e5791906119aa565b60405180910390a35050565b600054610100900460ff16610efa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae16115ae565b6067819055604080516020808201849052825180830390910181529082019091526000610e26565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae91906119aa565b60405180910390a3505050565b610fc361068d565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610e26565b80158015906110a85750606a54155b156110b257606a55565b606a546000036106355743606a5550565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611173576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840161078d565b6001816040015160ff161161120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e20310000000000000000000000000000000000606482015260840161078d565b6068546080820151825167ffffffffffffffff9092169161122b9190611aa1565b63ffffffff161115611299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b6000816020015160ff1611611330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f7420626520300000000000000000000000000000000000606482015260840161078d565b8051602082015163ffffffff82169160ff90911690611350908290611ac0565b61135a9190611b0a565b63ffffffff16146113ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840161078d565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae133611537565b803573ffffffffffffffffffffffffffffffffffffffff8116811461167257600080fd5b919050565b60006020828403121561168957600080fd5b6116928261164e565b9392505050565b803567ffffffffffffffff8116811461167257600080fd5b60405160c0810167ffffffffffffffff811182821017156116fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff8116811461167257600080fd5b803560ff8116811461167257600080fd5b600060c0828403121561173857600080fd5b60405160c0810181811067ffffffffffffffff82111715611782577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061179183611701565b815261179f60208401611715565b60208201526117b060408401611715565b60408201526117c160608401611701565b60608201526117d260808401611701565b608082015260a08301356fffffffffffffffffffffffffffffffff811681146117fa57600080fd5b60a0919091015292915050565b6000806000806000806000806000808a8c0361028081121561182857600080fd5b6118318c61164e565b9a5060208c0135995060408c0135985060608c0135975061185460808d01611699565b965061186260a08d0161164e565b95506118718d60c08e01611726565b94506101808c013593506118886101a08d0161164e565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe40820112156118ba57600080fd5b506118c36116b1565b6118d06101c08d0161164e565b81526118df6101e08d0161164e565b60208201526118f16102008d0161164e565b60408201526119036102208d0161164e565b60608201526119156102408d0161164e565b60808201526119276102608d0161164e565b60a0820152809150509295989b9194979a5092959850565b6000815180845260005b8181101561196557602081850181015186830182015201611949565b81811115611977576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611692602083018461193f565b600080604083850312156119d057600080fd5b50508035926020909101359150565b6000602082840312156119f157600080fd5b61169282611699565b600060c08284031215611a0c57600080fd5b6116928383611726565b600060208284031215611a2857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611a7057611a70611a2f565b500390565b600067ffffffffffffffff808316818516808303821115611a9857611a98611a2f565b01949350505050565b600063ffffffff808316818516808303821115611a9857611a98611a2f565b600063ffffffff80841680611afe577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611b2d57611b2d611a2f565b0294935050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))": { - "params": { - "_addresses": "Set of L1 contract addresses. These should be the proxies.", - "_batchInbox": "Batch inbox address. An identifier for the op-node to find canonical data.", - "_batcherHash": "Initial batcher hash.", - "_config": "Initial ResourceConfig.", - "_gasLimit": "Initial gas limit.", - "_overhead": "Initial overhead value.", - "_owner": "Initial owner of the contract.", - "_scalar": "Initial scalar value.", - "_startBlock": "Starting block for the op-node to search for logs from. Contracts that were deployed before this field existed need to have this field set manually via an override. Newly deployed contracts should set this value to uint256(0).", - "_unsafeBlockSigner": "Initial unsafe block signer address." - } - }, - "minimumGasLimit()": { - "returns": { - "_0": "uint64 Minimum gas limit." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "resourceConfig()": { - "returns": { - "_0": "ResourceConfig" - } - }, - "setBatcherHash(bytes32)": { - "params": { - "_batcherHash": "New batcher hash." - } - }, - "setGasConfig(uint256,uint256)": { - "params": { - "_overhead": "New overhead value.", - "_scalar": "New scalar value." - } - }, - "setGasLimit(uint64)": { - "params": { - "_gasLimit": "New gas limit." - } - }, - "setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))": { - "params": { - "_config": "The new resource config values." - } - }, - "setUnsafeBlockSigner(address)": { - "params": { - "_unsafeBlockSigner": "New unsafe block signer address." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - }, - "unsafeBlockSigner()": { - "returns": { - "addr_": "Address of the unsafe block signer." - } - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "params": { - "data": "Encoded update data.", - "updateType": "Type of update.", - "version": "SystemConfig version." - } - } - }, - "title": "SystemConfig" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"enum SystemConfig.UpdateType\",\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ConfigUpdate\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"BATCH_INBOX_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L1_CROSS_DOMAIN_MESSENGER_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L1_ERC_721_BRIDGE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L1_STANDARD_BRIDGE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L2_OUTPUT_ORACLE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OPTIMISM_PORTAL_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"UNSAFE_BLOCK_SIGNER_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"batchInbox\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"batcherHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"gasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_scalar\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_batcherHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"_unsafeBlockSigner\",\"type\":\"address\"},{\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"_config\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}]},{\"internalType\":\"uint256\",\"name\":\"_startBlock\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_batchInbox\",\"type\":\"address\"},{\"internalType\":\"struct SystemConfig.Addresses\",\"name\":\"_addresses\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"address\",\"name\":\"l1CrossDomainMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1ERC721Bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1StandardBridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l2OutputOracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismPortal\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismMintableERC20Factory\",\"type\":\"address\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l1CrossDomainMessenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l1ERC721Bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l1StandardBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2OutputOracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"optimismMintableERC20Factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"optimismPortal\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"overhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"renounceOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"resourceConfig\",\"outputs\":[{\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}]}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"scalar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_batcherHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setBatcherHash\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_scalar\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setGasConfig\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setGasLimit\"},{\"inputs\":[{\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"_config\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setResourceConfig\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_unsafeBlockSigner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setUnsafeBlockSigner\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"startBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"unsafeBlockSigner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))\":{\"params\":{\"_addresses\":\"Set of L1 contract addresses. These should be the proxies.\",\"_batchInbox\":\"Batch inbox address. An identifier for the op-node to find canonical data.\",\"_batcherHash\":\"Initial batcher hash.\",\"_config\":\"Initial ResourceConfig.\",\"_gasLimit\":\"Initial gas limit.\",\"_overhead\":\"Initial overhead value.\",\"_owner\":\"Initial owner of the contract.\",\"_scalar\":\"Initial scalar value.\",\"_startBlock\":\"Starting block for the op-node to search for logs from. Contracts that were deployed before this field existed need to have this field set manually via an override. Newly deployed contracts should set this value to uint256(0).\",\"_unsafeBlockSigner\":\"Initial unsafe block signer address.\"}},\"minimumGasLimit()\":{\"returns\":{\"_0\":\"uint64 Minimum gas limit.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"resourceConfig()\":{\"returns\":{\"_0\":\"ResourceConfig\"}},\"setBatcherHash(bytes32)\":{\"params\":{\"_batcherHash\":\"New batcher hash.\"}},\"setGasConfig(uint256,uint256)\":{\"params\":{\"_overhead\":\"New overhead value.\",\"_scalar\":\"New scalar value.\"}},\"setGasLimit(uint64)\":{\"params\":{\"_gasLimit\":\"New gas limit.\"}},\"setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))\":{\"params\":{\"_config\":\"The new resource config values.\"}},\"setUnsafeBlockSigner(address)\":{\"params\":{\"_unsafeBlockSigner\":\"New unsafe block signer address.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unsafeBlockSigner()\":{\"returns\":{\"addr_\":\"Address of the unsafe block signer.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BATCH_INBOX_SLOT()\":{\"notice\":\"Storage slot that the batch inbox address is stored at.\"},\"L1_CROSS_DOMAIN_MESSENGER_SLOT()\":{\"notice\":\"Storage slot that the L1CrossDomainMessenger address is stored at.\"},\"L1_ERC_721_BRIDGE_SLOT()\":{\"notice\":\"Storage slot that the L1ERC721Bridge address is stored at.\"},\"L1_STANDARD_BRIDGE_SLOT()\":{\"notice\":\"Storage slot that the L1StandardBridge address is stored at.\"},\"L2_OUTPUT_ORACLE_SLOT()\":{\"notice\":\"Storage slot that the L2OutputOracle address is stored at.\"},\"OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT()\":{\"notice\":\"Storage slot that the OptimismMintableERC20Factory address is stored at.\"},\"OPTIMISM_PORTAL_SLOT()\":{\"notice\":\"Storage slot that the OptimismPortal address is stored at.\"},\"UNSAFE_BLOCK_SIGNER_SLOT()\":{\"notice\":\"Storage slot that the unsafe block signer is stored at. Storing it at this deterministic storage slot allows for decoupling the storage layout from the way that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value.\"},\"VERSION()\":{\"notice\":\"Version identifier, used for upgrades.\"},\"batchInbox()\":{\"notice\":\"Getter for the BatchInbox address.\"},\"batcherHash()\":{\"notice\":\"Identifier for the batcher. For version 1 of this configuration, this is represented as an address left-padded with zeros to 32 bytes.\"},\"constructor\":{\"notice\":\"Constructs the SystemConfig contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)`\"},\"gasLimit()\":{\"notice\":\"L2 block gas limit.\"},\"initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))\":{\"notice\":\"Initializer. The resource config must be set before the require check.\"},\"l1CrossDomainMessenger()\":{\"notice\":\"Getter for the L1CrossDomainMessenger address.\"},\"l1ERC721Bridge()\":{\"notice\":\"Getter for the L1ERC721Bridge address.\"},\"l1StandardBridge()\":{\"notice\":\"Getter for the L1StandardBridge address.\"},\"l2OutputOracle()\":{\"notice\":\"Getter for the L2OutputOracle address.\"},\"minimumGasLimit()\":{\"notice\":\"Returns the minimum L2 gas limit that can be safely set for the system to operate. The L2 gas limit must be larger than or equal to the amount of gas that is allocated for deposits per block plus the amount of gas that is allocated for the system transaction. This function is used to determine if changes to parameters are safe.\"},\"optimismMintableERC20Factory()\":{\"notice\":\"Getter for the OptimismMintableERC20Factory address.\"},\"optimismPortal()\":{\"notice\":\"Getter for the OptimismPortal address.\"},\"overhead()\":{\"notice\":\"Fixed L2 gas overhead. Used as part of the L2 fee calculation.\"},\"resourceConfig()\":{\"notice\":\"A getter for the resource config. Ensures that the struct is returned instead of a tuple.\"},\"scalar()\":{\"notice\":\"Dynamic L2 gas overhead. Used as part of the L2 fee calculation.\"},\"setBatcherHash(bytes32)\":{\"notice\":\"Updates the batcher hash. Can only be called by the owner.\"},\"setGasConfig(uint256,uint256)\":{\"notice\":\"Updates gas config. Can only be called by the owner.\"},\"setGasLimit(uint64)\":{\"notice\":\"Updates the L2 gas limit. Can only be called by the owner.\"},\"setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))\":{\"notice\":\"An external setter for the resource config. In the future, this method may emit an event that the `op-node` picks up for when the resource config is changed.\"},\"setUnsafeBlockSigner(address)\":{\"notice\":\"Updates the unsafe block signer address. Can only be called by the owner.\"},\"startBlock()\":{\"notice\":\"The block at which the op-node can start searching for logs from.\"},\"unsafeBlockSigner()\":{\"notice\":\"High level getter for the unsafe block signer address. Unsafe blocks can be propagated across the p2p network if they are signed by the key corresponding to this address.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/SystemConfig.sol\":\"SystemConfig\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L1/SystemConfig.sol\":{\"keccak256\":\"0x4bbbc7868e948c44f29285a69383e93251a0c330a67929fb72def01cec060d4e\",\"urls\":[\"bzz-raw://1e7ea2f8b3d49bee9c753f107ede6eda93b2cc0e34d0643fa14ebbb26c19e71b\",\"dweb:/ipfs/QmRP81F8FRVXVZs6u2f2poEPDnbFZhNwNYxHgCVEhGpEmB\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 6, - "receipt": { - "transactionHash": "0x4bfbbbc994d0ebd60a667d5f00818c6e5ce02148713734796ddc2918070d59ed", - "transactionIndex": "0x3", - "blockHash": "0x28d3a10e81b2ea28788ad35a3dcb922b92a2d9b634d551eb1d0eb9a5be84371c", - "blockNumber": "0x95b3e3", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "cumulativeGasUsed": "0x2288bb", - "gasUsed": "0x1ae55a", - "contractAddress": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "logs": [ - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c" - ], - "data": "0x", - "blockHash": "0x28d3a10e81b2ea28788ad35a3dcb922b92a2d9b634d551eb1d0eb9a5be84371c", - "blockNumber": "0x95b3e3", - "transactionHash": "0x4bfbbbc994d0ebd60a667d5f00818c6e5ce02148713734796ddc2918070d59ed", - "transactionIndex": "0x3", - "logIndex": "0x0", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "0x000000000000000000000000000000000000000000000000000000000000dead" - ], - "data": "0x", - "blockHash": "0x28d3a10e81b2ea28788ad35a3dcb922b92a2d9b634d551eb1d0eb9a5be84371c", - "blockNumber": "0x95b3e3", - "transactionHash": "0x4bfbbbc994d0ebd60a667d5f00818c6e5ce02148713734796ddc2918070d59ed", - "transactionIndex": "0x3", - "logIndex": "0x1", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x28d3a10e81b2ea28788ad35a3dcb922b92a2d9b634d551eb1d0eb9a5be84371c", - "blockNumber": "0x95b3e3", - "transactionHash": "0x4bfbbbc994d0ebd60a667d5f00818c6e5ce02148713734796ddc2918070d59ed", - "transactionIndex": "0x3", - "logIndex": "0x2", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000001" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x28d3a10e81b2ea28788ad35a3dcb922b92a2d9b634d551eb1d0eb9a5be84371c", - "blockNumber": "0x95b3e3", - "transactionHash": "0x4bfbbbc994d0ebd60a667d5f00818c6e5ce02148713734796ddc2918070d59ed", - "transactionIndex": "0x3", - "logIndex": "0x3", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001", - "blockHash": "0x28d3a10e81b2ea28788ad35a3dcb922b92a2d9b634d551eb1d0eb9a5be84371c", - "blockNumber": "0x95b3e3", - "transactionHash": "0x4bfbbbc994d0ebd60a667d5f00818c6e5ce02148713734796ddc2918070d59ed", - "transactionIndex": "0x3", - "logIndex": "0x4", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000003" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x28d3a10e81b2ea28788ad35a3dcb922b92a2d9b634d551eb1d0eb9a5be84371c", - "blockNumber": "0x95b3e3", - "transactionHash": "0x4bfbbbc994d0ebd60a667d5f00818c6e5ce02148713734796ddc2918070d59ed", - "transactionIndex": "0x3", - "logIndex": "0x5", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000003", - "blockHash": "0x28d3a10e81b2ea28788ad35a3dcb922b92a2d9b634d551eb1d0eb9a5be84371c", - "blockNumber": "0x95b3e3", - "transactionHash": "0x4bfbbbc994d0ebd60a667d5f00818c6e5ce02148713734796ddc2918070d59ed", - "transactionIndex": "0x3", - "logIndex": "0x6", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x04000000000010000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000020008000000000000040000000000000000000000100000000000000001000000040000000000000000000000000000020000000000000000000800000000000000002000000000000000400000000000000000000004040000000000000000001080000000000000000000000000000001000000000100000400000000000000800000000000000000400000000400000000000000000000040000000000000000000000000000000060000000000000000008000000000000000080000000008000000000008000000000", - "type": "0x2", - "effectiveGasPrice": "0xb2d05e07" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 29536, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 29539, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 31067, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 29408, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 29528, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 61640, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "overhead", - "offset": 0, - "slot": "101", - "type": "t_uint256" - }, - { - "astId": 61643, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "scalar", - "offset": 0, - "slot": "102", - "type": "t_uint256" - }, - { - "astId": 61646, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "batcherHash", - "offset": 0, - "slot": "103", - "type": "t_bytes32" - }, - { - "astId": 61649, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "gasLimit", - "offset": 0, - "slot": "104", - "type": "t_uint64" - }, - { - "astId": 61653, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_resourceConfig", - "offset": 0, - "slot": "105", - "type": "t_struct(ResourceConfig)61178_storage" - }, - { - "astId": 61666, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "startBlock", - "offset": 0, - "slot": "106", - "type": "t_uint256" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_struct(ResourceConfig)61178_storage": { - "encoding": "inplace", - "label": "struct ResourceMetering.ResourceConfig", - "numberOfBytes": "32", - "members": [ - { - "astId": 61167, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "maxResourceLimit", - "offset": 0, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 61169, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "elasticityMultiplier", - "offset": 4, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 61171, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "baseFeeMaxChangeDenominator", - "offset": 5, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 61173, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "minimumBaseFee", - "offset": 6, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 61175, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "systemTxMaxGas", - "offset": 10, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 61177, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "maximumBaseFee", - "offset": 14, - "slot": "0", - "type": "t_uint128" - } - ] - }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "encoding": "inplace", - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x4bfbbbc994d0ebd60a667d5f00818c6e5ce02148713734796ddc2918070d59ed", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "BATCH_INBOX_SLOT()": { - "notice": "Storage slot that the batch inbox address is stored at." - }, - "L1_CROSS_DOMAIN_MESSENGER_SLOT()": { - "notice": "Storage slot that the L1CrossDomainMessenger address is stored at." - }, - "L1_ERC_721_BRIDGE_SLOT()": { - "notice": "Storage slot that the L1ERC721Bridge address is stored at." - }, - "L1_STANDARD_BRIDGE_SLOT()": { - "notice": "Storage slot that the L1StandardBridge address is stored at." - }, - "L2_OUTPUT_ORACLE_SLOT()": { - "notice": "Storage slot that the L2OutputOracle address is stored at." - }, - "OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT()": { - "notice": "Storage slot that the OptimismMintableERC20Factory address is stored at." - }, - "OPTIMISM_PORTAL_SLOT()": { - "notice": "Storage slot that the OptimismPortal address is stored at." - }, - "UNSAFE_BLOCK_SIGNER_SLOT()": { - "notice": "Storage slot that the unsafe block signer is stored at. Storing it at this deterministic storage slot allows for decoupling the storage layout from the way that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value." - }, - "VERSION()": { - "notice": "Version identifier, used for upgrades." - }, - "batchInbox()": { - "notice": "Getter for the BatchInbox address." - }, - "batcherHash()": { - "notice": "Identifier for the batcher. For version 1 of this configuration, this is represented as an address left-padded with zeros to 32 bytes." - }, - "constructor": { - "notice": "Constructs the SystemConfig contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)`" - }, - "gasLimit()": { - "notice": "L2 block gas limit." - }, - "initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))": { - "notice": "Initializer. The resource config must be set before the require check." - }, - "l1CrossDomainMessenger()": { - "notice": "Getter for the L1CrossDomainMessenger address." - }, - "l1ERC721Bridge()": { - "notice": "Getter for the L1ERC721Bridge address." - }, - "l1StandardBridge()": { - "notice": "Getter for the L1StandardBridge address." - }, - "l2OutputOracle()": { - "notice": "Getter for the L2OutputOracle address." - }, - "minimumGasLimit()": { - "notice": "Returns the minimum L2 gas limit that can be safely set for the system to operate. The L2 gas limit must be larger than or equal to the amount of gas that is allocated for deposits per block plus the amount of gas that is allocated for the system transaction. This function is used to determine if changes to parameters are safe." - }, - "optimismMintableERC20Factory()": { - "notice": "Getter for the OptimismMintableERC20Factory address." - }, - "optimismPortal()": { - "notice": "Getter for the OptimismPortal address." - }, - "overhead()": { - "notice": "Fixed L2 gas overhead. Used as part of the L2 fee calculation." - }, - "resourceConfig()": { - "notice": "A getter for the resource config. Ensures that the struct is returned instead of a tuple." - }, - "scalar()": { - "notice": "Dynamic L2 gas overhead. Used as part of the L2 fee calculation." - }, - "setBatcherHash(bytes32)": { - "notice": "Updates the batcher hash. Can only be called by the owner." - }, - "setGasConfig(uint256,uint256)": { - "notice": "Updates gas config. Can only be called by the owner." - }, - "setGasLimit(uint64)": { - "notice": "Updates the L2 gas limit. Can only be called by the owner." - }, - "setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))": { - "notice": "An external setter for the resource config. In the future, this method may emit an event that the `op-node` picks up for when the resource config is changed." - }, - "setUnsafeBlockSigner(address)": { - "notice": "Updates the unsafe block signer address. Can only be called by the owner." - }, - "startBlock()": { - "notice": "The block at which the op-node can start searching for logs from." - }, - "unsafeBlockSigner()": { - "notice": "High level getter for the unsafe block signer address. Unsafe blocks can be propagated across the p2p network if they are signed by the key corresponding to this address." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "notice": "Emitted when configuration is updated." - } - }, - "notice": "The SystemConfig contract is used to manage configuration of an Optimism network. All configuration is stored on L1 and picked up by L2 as part of the derviation of the L2 chain." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/SystemConfigProxy.json b/packages/contracts-bedrock/deployments/goerli/SystemConfigProxy.json deleted file mode 100644 index 2e8d067d4c45..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/SystemConfigProxy.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x1548358880f322e0aa66a35e43c8b572e1f9bac6891ef8833c6ed7479d459050", - "receipt": { - "to": null, - "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078", - "contractAddress": "0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60", - "transactionIndex": 40, - "gasUsed": "523800", - "logsBloom": "0x00000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000400000000000000000000000000000000000000000000000000000000000000000000000100000000000000", - "blockHash": "0x5de788459065d418b2cee8cbbd8fbd6745ede0f93f7c59e7bb08a3d69b5ba009", - "transactionHash": "0x1548358880f322e0aa66a35e43c8b572e1f9bac6891ef8833c6ed7479d459050", - "logs": [ - { - "transactionIndex": 40, - "blockNumber": 8299687, - "transactionHash": "0x1548358880f322e0aa66a35e43c8b572e1f9bac6891ef8833c6ed7479d459050", - "address": "0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d3670863c3f4b24d7b107900f0b75d4bbc6e0d", - "logIndex": 147, - "blockHash": "0x5de788459065d418b2cee8cbbd8fbd6745ede0f93f7c59e7bb08a3d69b5ba009" - } - ], - "blockNumber": 8299687, - "cumulativeGasUsed": "8112613", - "status": 1, - "byzantium": true - }, - "args": [ - "0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d" - ], - "numDeployments": 1, - "solcInputHash": "672fbec9734a08fc34112408d6dc7f7b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\",\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/SystemDictator.json b/packages/contracts-bedrock/deployments/goerli/SystemDictator.json deleted file mode 100644 index f682c217aee9..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/SystemDictator.json +++ /dev/null @@ -1,1158 +0,0 @@ -{ - "address": "0xCdD9F7C335bFDF3eaBDB4dF29f7417Ce8552A833", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "EXIT_1_NO_RETURN_STEP", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PROXY_TRANSFER_STEP", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "config", - "outputs": [ - { - "components": [ - { - "internalType": "contract AddressManager", - "name": "addressManager", - "type": "address" - }, - { - "internalType": "contract ProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, - { - "internalType": "address", - "name": "controller", - "type": "address" - }, - { - "internalType": "address", - "name": "finalOwner", - "type": "address" - } - ], - "internalType": "struct SystemDictator.GlobalConfig", - "name": "globalConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "l2OutputOracleProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismPortalProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1CrossDomainMessengerProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1StandardBridgeProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismMintableERC20FactoryProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1ERC721BridgeProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "systemConfigProxy", - "type": "address" - } - ], - "internalType": "struct SystemDictator.ProxyAddressConfig", - "name": "proxyAddressConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "contract L2OutputOracle", - "name": "l2OutputOracleImpl", - "type": "address" - }, - { - "internalType": "contract OptimismPortal", - "name": "optimismPortalImpl", - "type": "address" - }, - { - "internalType": "contract L1CrossDomainMessenger", - "name": "l1CrossDomainMessengerImpl", - "type": "address" - }, - { - "internalType": "contract L1StandardBridge", - "name": "l1StandardBridgeImpl", - "type": "address" - }, - { - "internalType": "contract OptimismMintableERC20Factory", - "name": "optimismMintableERC20FactoryImpl", - "type": "address" - }, - { - "internalType": "contract L1ERC721Bridge", - "name": "l1ERC721BridgeImpl", - "type": "address" - }, - { - "internalType": "contract PortalSender", - "name": "portalSenderImpl", - "type": "address" - }, - { - "internalType": "contract SystemConfig", - "name": "systemConfigImpl", - "type": "address" - } - ], - "internalType": "struct SystemDictator.ImplementationAddressConfig", - "name": "implementationAddressConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "overhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "scalar", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "batcherHash", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "gasLimit", - "type": "uint64" - }, - { - "internalType": "address", - "name": "unsafeBlockSigner", - "type": "address" - } - ], - "internalType": "struct SystemDictator.SystemConfigConfig", - "name": "systemConfigConfig", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentStep", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "dynamicConfigSet", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "exit1", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "finalize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "finalized", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "components": [ - { - "internalType": "contract AddressManager", - "name": "addressManager", - "type": "address" - }, - { - "internalType": "contract ProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, - { - "internalType": "address", - "name": "controller", - "type": "address" - }, - { - "internalType": "address", - "name": "finalOwner", - "type": "address" - } - ], - "internalType": "struct SystemDictator.GlobalConfig", - "name": "globalConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "l2OutputOracleProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismPortalProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1CrossDomainMessengerProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1StandardBridgeProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismMintableERC20FactoryProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1ERC721BridgeProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "systemConfigProxy", - "type": "address" - } - ], - "internalType": "struct SystemDictator.ProxyAddressConfig", - "name": "proxyAddressConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "contract L2OutputOracle", - "name": "l2OutputOracleImpl", - "type": "address" - }, - { - "internalType": "contract OptimismPortal", - "name": "optimismPortalImpl", - "type": "address" - }, - { - "internalType": "contract L1CrossDomainMessenger", - "name": "l1CrossDomainMessengerImpl", - "type": "address" - }, - { - "internalType": "contract L1StandardBridge", - "name": "l1StandardBridgeImpl", - "type": "address" - }, - { - "internalType": "contract OptimismMintableERC20Factory", - "name": "optimismMintableERC20FactoryImpl", - "type": "address" - }, - { - "internalType": "contract L1ERC721Bridge", - "name": "l1ERC721BridgeImpl", - "type": "address" - }, - { - "internalType": "contract PortalSender", - "name": "portalSenderImpl", - "type": "address" - }, - { - "internalType": "contract SystemConfig", - "name": "systemConfigImpl", - "type": "address" - } - ], - "internalType": "struct SystemDictator.ImplementationAddressConfig", - "name": "implementationAddressConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "overhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "scalar", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "batcherHash", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "gasLimit", - "type": "uint64" - }, - { - "internalType": "address", - "name": "unsafeBlockSigner", - "type": "address" - } - ], - "internalType": "struct SystemDictator.SystemConfigConfig", - "name": "systemConfigConfig", - "type": "tuple" - } - ], - "internalType": "struct SystemDictator.DeployConfig", - "name": "_config", - "type": "tuple" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l2OutputOracleDynamicConfig", - "outputs": [ - { - "internalType": "uint256", - "name": "l2OutputOracleStartingBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l2OutputOracleStartingTimestamp", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "oldL1CrossDomainMessenger", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step1", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step2", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step3", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step4", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step5", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step6", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "l2OutputOracleStartingBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l2OutputOracleStartingTimestamp", - "type": "uint256" - } - ], - "internalType": "struct SystemDictator.L2OutputOracleDynamicConfig", - "name": "_l2OutputOracleDynamicConfig", - "type": "tuple" - } - ], - "name": "updateL2OutputOracleDynamicConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0xd690383a9a67077a377af6436e8e2ec96b2de52f87b3c6022a9735be3c2ad00e", - "receipt": { - "to": null, - "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078", - "contractAddress": "0xCdD9F7C335bFDF3eaBDB4dF29f7417Ce8552A833", - "transactionIndex": 17, - "gasUsed": "2874326", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1f18d07ddb20ae302240bca1013adc9b239070038c71c82c22c7f1f5c1f15058", - "transactionHash": "0xd690383a9a67077a377af6436e8e2ec96b2de52f87b3c6022a9735be3c2ad00e", - "logs": [], - "blockNumber": 8299697, - "cumulativeGasUsed": "9427783", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "672fbec9734a08fc34112408d6dc7f7b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"EXIT_1_NO_RETURN_STEP\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PROXY_TRANSFER_STEP\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"config\",\"outputs\":[{\"components\":[{\"internalType\":\"contract AddressManager\",\"name\":\"addressManager\",\"type\":\"address\"},{\"internalType\":\"contract ProxyAdmin\",\"name\":\"proxyAdmin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"finalOwner\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.GlobalConfig\",\"name\":\"globalConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"l2OutputOracleProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismPortalProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1CrossDomainMessengerProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1StandardBridgeProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismMintableERC20FactoryProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1ERC721BridgeProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"systemConfigProxy\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.ProxyAddressConfig\",\"name\":\"proxyAddressConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"l2OutputOracleImpl\",\"type\":\"address\"},{\"internalType\":\"contract OptimismPortal\",\"name\":\"optimismPortalImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1CrossDomainMessenger\",\"name\":\"l1CrossDomainMessengerImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1StandardBridge\",\"name\":\"l1StandardBridgeImpl\",\"type\":\"address\"},{\"internalType\":\"contract OptimismMintableERC20Factory\",\"name\":\"optimismMintableERC20FactoryImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1ERC721Bridge\",\"name\":\"l1ERC721BridgeImpl\",\"type\":\"address\"},{\"internalType\":\"contract PortalSender\",\"name\":\"portalSenderImpl\",\"type\":\"address\"},{\"internalType\":\"contract SystemConfig\",\"name\":\"systemConfigImpl\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.ImplementationAddressConfig\",\"name\":\"implementationAddressConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"scalar\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"batcherHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"unsafeBlockSigner\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.SystemConfigConfig\",\"name\":\"systemConfigConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentStep\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dynamicConfigSet\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"exit1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"finalize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"finalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"contract AddressManager\",\"name\":\"addressManager\",\"type\":\"address\"},{\"internalType\":\"contract ProxyAdmin\",\"name\":\"proxyAdmin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"finalOwner\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.GlobalConfig\",\"name\":\"globalConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"l2OutputOracleProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismPortalProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1CrossDomainMessengerProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1StandardBridgeProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismMintableERC20FactoryProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1ERC721BridgeProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"systemConfigProxy\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.ProxyAddressConfig\",\"name\":\"proxyAddressConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"l2OutputOracleImpl\",\"type\":\"address\"},{\"internalType\":\"contract OptimismPortal\",\"name\":\"optimismPortalImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1CrossDomainMessenger\",\"name\":\"l1CrossDomainMessengerImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1StandardBridge\",\"name\":\"l1StandardBridgeImpl\",\"type\":\"address\"},{\"internalType\":\"contract OptimismMintableERC20Factory\",\"name\":\"optimismMintableERC20FactoryImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1ERC721Bridge\",\"name\":\"l1ERC721BridgeImpl\",\"type\":\"address\"},{\"internalType\":\"contract PortalSender\",\"name\":\"portalSenderImpl\",\"type\":\"address\"},{\"internalType\":\"contract SystemConfig\",\"name\":\"systemConfigImpl\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.ImplementationAddressConfig\",\"name\":\"implementationAddressConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"scalar\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"batcherHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"unsafeBlockSigner\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.SystemConfigConfig\",\"name\":\"systemConfigConfig\",\"type\":\"tuple\"}],\"internalType\":\"struct SystemDictator.DeployConfig\",\"name\":\"_config\",\"type\":\"tuple\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2OutputOracleDynamicConfig\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"l2OutputOracleStartingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l2OutputOracleStartingTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldL1CrossDomainMessenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step3\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step4\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step5\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step6\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"l2OutputOracleStartingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l2OutputOracleStartingTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"struct SystemDictator.L2OutputOracleDynamicConfig\",\"name\":\"_l2OutputOracleDynamicConfig\",\"type\":\"tuple\"}],\"name\":\"updateL2OutputOracleDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(((address,address,address,address),(address,address,address,address,address,address,address),(address,address,address,address,address,address,address,address),(address,uint256,uint256,bytes32,uint64,address)))\":{\"params\":{\"_config\":\"System configuration.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"updateL2OutputOracleDynamicConfig((uint256,uint256))\":{\"params\":{\"_l2OutputOracleDynamicConfig\":\"Dynamic L2OutputOracle config.\"}}},\"title\":\"SystemDictator\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"EXIT_1_NO_RETURN_STEP()\":{\"notice\":\"Step after which exit 1 can no longer be used.\"},\"PROXY_TRANSFER_STEP()\":{\"notice\":\"Step where proxy ownership is transferred.\"},\"config()\":{\"notice\":\"System configuration.\"},\"currentStep()\":{\"notice\":\"Current step;\"},\"dynamicConfigSet()\":{\"notice\":\"Whether or not dynamic config has been set.\"},\"exit1()\":{\"notice\":\"First exit point, can only be called before step 3 is executed.\"},\"finalize()\":{\"notice\":\"Tranfers admin ownership to the final owner.\"},\"finalized()\":{\"notice\":\"Whether or not the deployment is finalized.\"},\"l2OutputOracleDynamicConfig()\":{\"notice\":\"Dynamic configuration for the L2OutputOracle.\"},\"oldL1CrossDomainMessenger()\":{\"notice\":\"Address of the old L1CrossDomainMessenger implementation.\"},\"step1()\":{\"notice\":\"Configures the ProxyAdmin contract.\"},\"step2()\":{\"notice\":\"Pauses the system by shutting down the L1CrossDomainMessenger and setting the deposit halt flag to tell the Sequencer's DTL to stop accepting deposits.\"},\"step3()\":{\"notice\":\"Removes deprecated addresses from the AddressManager.\"},\"step4()\":{\"notice\":\"Transfers system ownership to the ProxyAdmin.\"},\"step5()\":{\"notice\":\"Upgrades and initializes proxy contracts.\"},\"step6()\":{\"notice\":\"Unpauses the system at which point the system should be fully operational.\"},\"updateL2OutputOracleDynamicConfig((uint256,uint256))\":{\"notice\":\"Allows the owner to update dynamic L2OutputOracle config.\"}},\"notice\":\"The SystemDictator is responsible for coordinating the deployment of a full Bedrock system. The SystemDictator is designed to support both fresh network deployments and upgrades to existing pre-Bedrock systems.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/deployment/SystemDictator.sol\":\"SystemDictator\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L1/L1CrossDomainMessenger.sol\":{\"keccak256\":\"0x73c9ef994396ea551b56ce6c96d7bff8dc825b22e6f31e7b10e38d2c38be2373\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2e713ca338ff223b4076a25554d4ba72ffeca4ed0bb161b170e4ed3ab0724e9f\",\"dweb:/ipfs/QmS1tFSzbcTdkPUeP6dMxrvDSna5JYrK1rTbukfzcU4MbM\"]},\"contracts/L1/L1ERC721Bridge.sol\":{\"keccak256\":\"0x9a410440dad639aa9b8facb8d99ad5a74e868fa20d75274f545a539cfd965745\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://dd46b6bb8428d2e17ff15664a46e23b9e93188520b047dd406800792dd928118\",\"dweb:/ipfs/QmYode1mDZdLj7UdA8QqD8dDQFgst52DeFh8kn33njZJqh\"]},\"contracts/L1/L1StandardBridge.sol\":{\"keccak256\":\"0x19d06e31748c911064f6ee2b5d729468912cb2d055c1d847f266502f7857be22\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6bde1feaf637ea86ecd88605f312e4e85fe2a87d225859e2fbb183af8c283551\",\"dweb:/ipfs/QmVrTipEETDCat52cCYestK3AvUj1KrV9t2HrXJcMq58Tp\"]},\"contracts/L1/L2OutputOracle.sol\":{\"keccak256\":\"0xaa706785b6c6e01b21b47d050a19f83d6afaf8a1db152d0e48463eea55c0c366\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://84f6a9884c4cf7edf499e4182bd9db03876e33df66a0b64307e2c7b997c150b7\",\"dweb:/ipfs/QmR2prJL6HGxPjVjbW5o96C9ekavkarNEy2v11yCGxrdfX\"]},\"contracts/L1/OptimismPortal.sol\":{\"keccak256\":\"0xc9fa6b522c76e6f8de364b4e6f58ebcd073a47b37fb343e444687429bbc2b49e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b3ee3b286e2f5930ee0ec98864c6f51b0d33820678760b668689487a67771f48\",\"dweb:/ipfs/Qmb1KbJXBGzohdyzw5hsMkaEVtPjEEW5BdvDRAUN9Fv7Vy\"]},\"contracts/L1/ResourceMetering.sol\":{\"keccak256\":\"0x23045734df51c2f237d0def7f5e6dda69304bb3cfb554c6c1e934c4c8b07cecc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e6f84a34b842702c3ab4b06da997903046556f3f809716763a351b9f379b7e07\",\"dweb:/ipfs/QmQPyWcbuAMhghZdGSPwSBQdQgZi5hk6Bdg4s7qxaHpcMw\"]},\"contracts/L1/SystemConfig.sol\":{\"keccak256\":\"0xedc693eef1f791d8e4bf8e607481b82ab334b9eddc66e3a35f0ab3a7da6035d1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fe90c341ae0410d56f8ccf75b26aed89419558897fb815ff1133d0a1d726e810\",\"dweb:/ipfs/QmafjYWpfgPauDCKj2w8NTwa91HUQKgjYj5XjK5rPSjMsG\"]},\"contracts/L2/L2ERC721Bridge.sol\":{\"keccak256\":\"0x2ab1b8168d443b8c5fb6806fca9396d9ac8d0371c05b15992e1b38be22c4ca48\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c2df3e2944950a83eb9d6b7217a21a7d557ee08620962f9db4c6e53fb76cf7af\",\"dweb:/ipfs/QmZ124uFjoyK6pWiHRYVRhF5tr2wcUcGgsTF4G355ntL5N\"]},\"contracts/deployment/PortalSender.sol\":{\"keccak256\":\"0xe60d88036d9aa8f8e80a4108ee30ad987564ad996af87a79ba92f6ca35852881\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a4be187cd3d5926592491f722dfa1b1c41a8f4f1abdc8cf3883964f70acb0a44\",\"dweb:/ipfs/QmYsAK4YcRHmPoex2eX2x1r6N76AMk3rdBHHmp6gUT73Fa\"]},\"contracts/deployment/SystemDictator.sol\":{\"keccak256\":\"0x7ffcfb6bff9df395a113579141d762367e3144c058e6cb3abfec8ccc91e14c5a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4cf872132f3937d4a830e93bc7680f5749cccc0a0c0dd461b7782a922b9ab0d4\",\"dweb:/ipfs/QmWbNRKsBLD998mYvGD5cLKVmkdK27SXYYCByocin5oyoe\"]},\"contracts/legacy/AddressManager.sol\":{\"keccak256\":\"0x7a353d4c92eed32665fd2f0023c55054901293cf7a6e14ca108229d87c047b10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b92ba23601d1951271729a20db931a45639d9376b7c8e2705c23dc360833715a\",\"dweb:/ipfs/QmTKwYLNYYBKZpd31VNBANmguVUwFZifSg7joHSgLZjZCj\"]},\"contracts/legacy/L1ChugSplashProxy.sol\":{\"keccak256\":\"0x6ae7bf6ea9ac0e3511ee4cb15d946589da0dd35098ff762c0b2903d064f24875\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://02028d86c1d38563021d5ead5282271ccdf1c03a24f2eaee056ae2157f0554ee\",\"dweb:/ipfs/QmW9urkBBRTmZ8FjL5Y5zWbdnRhPDruxCCLnpr2CTkozKM\"]},\"contracts/libraries/Arithmetic.sol\":{\"keccak256\":\"0xc8858039f87e48e6f18c1af8bc0b03e57cfef564acddfd06e4d91e3db7ac5ed6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2fc79af1e844aa6dc1c68067bfe1d359df8d4e9a3e8881afb3bcfcbf68071714\",\"dweb:/ipfs/QmcNC4k8zmvwj4kZizSenTiWbx2DJQPbwqXXLF4iMbkRVD\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Bytes.sol\":{\"keccak256\":\"0x7aca6593fadf438ee9cd090d8fdc8f94a5202a2eb7f764c9a86f207712d87a48\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://aac32157885c5a08bd0bc7dcd5511f66db12bb20d0c263dd7be9f58b91538fc1\",\"dweb:/ipfs/Qmb1iG11Z53yt9wNbGsuTvoydJXFosDDpWwRSADKyqiCjw\"]},\"contracts/libraries/Constants.sol\":{\"keccak256\":\"0x50a2b69a5e9246945ee1588278753feae90285ff7e675369f0cc5b64acea333c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://75153213766bd271cce59d5284a4a0d2f6283e3c6a9dc31b8ce20a3a4c28c066\",\"dweb:/ipfs/QmcbpwMLYuKUPahVYJ3W7sfntQgHk9RTuR2DUzFMrfPMQr\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/Predeploys.sol\":{\"keccak256\":\"0xbf404ace304548f9824262f3efa079191f4fe9d475518c45f37626f3596a6c4b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://43122a0cd40564a776ea49186c4a3c9bf1a0fc74a542d850ff0bacfb072d013f\",\"dweb:/ipfs/QmWkwNAywCZGhTrXtNbkRq3gzdm9MRBPiRVVtBhH9sHyAk\"]},\"contracts/libraries/SafeCall.sol\":{\"keccak256\":\"0xbb0621c028c18e9d5a54cf1a8136cf2e77f161de48aeb8d911e230f6b280c9ed\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://924ecc629c7642bc19e2f8a390f1b946d22862c8889453da681b5bc1a45d7703\",\"dweb:/ipfs/QmbNknQ8pzssXDXGVjXxzZ8zh1YnNCWtRJVepiM1TnqoqQ\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x822e7c7ac5d45eac20551ba602d8bff3d22db3538fb32be42c1ab12d7bfca110\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://970823854723de895ca7a24d34269e886a20824c75f706cb41541893b7c78838\",\"dweb:/ipfs/QmSQbEECeTxgUT65pK7Czc4ovAv2FdQ9EHyi5Z8mZgNkXc\"]},\"contracts/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x50763c897f0fe84cb067985ec4d7c5721ce9004a69cf0327f96f8982ee8ca412\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://603af847b43933b075f9aac3a7b3cd65041ffe6d732826695458ca9575e1a809\",\"dweb:/ipfs/QmfByFEaCxT9y1VtqoLi5EsXZ9ihkPfj6g5x7pcPoQ7q2K\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xd27fc945d6dd2821636d840f3766f817823c8e9fbfdb87c2da7c73e4292d2f7f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://497cec37d09ebcdc8d1cccac608a4a0b9b9d83eac6cc7c9e8b73c4c6644e2209\",\"dweb:/ipfs/QmUYMsCcgU6epspvKV9Y6anHyyMb4hd1xVzUZheBY9mfG7\"]},\"contracts/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0x61b03a03779cb1f75cea3b88af16fdfd10629029b4b2d6be5238e71af8ef1b5f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1212951af291c0e033a7119b42de5cad6b6bf32da26777da7c2419e76fa8f314\",\"dweb:/ipfs/QmYbnifDmL6UkP9D1X9GaNLR1Q8wYwmDNeYqkJ71bycaE5\"]},\"contracts/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0xa8efcda6e2fec4edc379fa9128d9ae9c257c278f94c6b265fc267764d4006213\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://56f739b6a7ed1d2eda132365c112edbf5646c36ffbac1d85f753311d11df421b\",\"dweb:/ipfs/QmaCXcw3tSKHuQm3VqAggSEAGqr3k6Ru5cfLZyGpCShhQz\"]},\"contracts/universal/ERC721Bridge.sol\":{\"keccak256\":\"0xb47389fbec63e85b2d04fce538fe1b8e048278d631729458b70e32a31971c092\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7133f38e3d8d1911738057b1d4523989abd7cd029797b1d3b59cda29d42e9704\",\"dweb:/ipfs/QmUN31CLssESHrBwWA3WYP5L2xESo9Q4aq2Exua1e8UtUW\"]},\"contracts/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0xaafd7b92930a022efa765be7c6c693e36e005c73e7486b37244d7e63cd4ac432\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a9fa58ca28cd600fd9913495b65cf52cada126e76b9ceb37894ff7993b77d791\",\"dweb:/ipfs/QmcSDqAxfY4nQrcEcUp3AQcazqQTfqBXZeocUt9wsAiA6x\"]},\"contracts/universal/IOptimismMintableERC721.sol\":{\"keccak256\":\"0xf1a3dd4452df8882a65a31c5e2e8de7872b08cf078be7a5a7da51e6f75c53ad3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b09a2560cae35ca4789fe1ff5edb2bae9fa7dcda115a55f7ccdcc974a2e37526\",\"dweb:/ipfs/QmPQeTvrJ4SJpng5VGZNMf1u85NWxrdus4gGn8xYkHddKM\"]},\"contracts/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0xe77679aa54e918825fc2332f528085cd344874809853475e1502afe4b46de4e9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af64115cc7aa940c74fb9129fa01c85bb05e70e7b148c1dcf263789de1138479\",\"dweb:/ipfs/QmbnTbs4jbCsrhbfLDjnzAz5h47LsRHn9TJoPdJwRuQV3S\"]},\"contracts/universal/OptimismMintableERC20Factory.sol\":{\"keccak256\":\"0xf010ac4b7b9c9a65b06fe21c8234c1a9366286f8e286f822bfb595413f6887c5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b879b8a1e3151e0b7aa7befd4d0fa95a3bd7c1236ac777087d6d68fdeaffebc8\",\"dweb:/ipfs/QmRmyXgQk5bXW3giPdPtwVoFFt8nofDnTUa3Kmy4WAuPsL\"]},\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\",\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\"]},\"contracts/universal/ProxyAdmin.sol\":{\"keccak256\":\"0x7326011ac425cc9ab4760c29ca559342d4832633b5019a9a61b9e63067374e2a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7d3541272c48443f0b339998553e44600b7bcb4f949e5c94acb5a3acfce19399\",\"dweb:/ipfs/QmNSd9jxACWg8bZE8EgxmRdXwLUQixVs4oiugrVegapUe4\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x979b13465de4996a1105850abbf48abe7f71d5e18a8d4af318597ee14c165fdf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d0881ed7d8371fe1c12b931334e107746fa97d9ecd6aa3c0fca0c0db8581474e\",\"dweb:/ipfs/QmQ9UFwZgWkyFAHrzTtS7m6rghZ8nP9QybEuJ5y9vux5Gv\"]},\"contracts/universal/StandardBridge.sol\":{\"keccak256\":\"0x3751c9d342180b37f06c1a48366e785d424bb5bc43ee7468dd7062089808ddb2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5d2aecf267e340472f634af99bfec816472b61c2d99ac6e4ea48424bb486b2e1\",\"dweb:/ipfs/QmbRG1gTEy3h55reCb7ne7DWjR1zvtj7Yv9dJaPzCkLRbr\"]},\"contracts/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"]},\"node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"]},\"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"node_modules/@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\":{\"keccak256\":\"0x40c636b4572ff5f1dc50cf22097e93c0723ee14eff87e99ac2b02636eeca1250\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9c7d1f5e15633ab912b74c2f57e24559e66b03232300d4b27ff0f25bc452ecad\",\"dweb:/ipfs/QmYTJkc1cntYkKQ1Tu11nBcJLakiy93Tjytc4XHELo4GmR\"]},\"node_modules/@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"keccak256\":\"0x8cc03c5ac17e8a7396e487cda41fc1f1dfdb91db7d528e6da84bee3b6dd7e167\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://607818f1b44548c2d8268176f73cdb290e1faed971b1061930d92698366e2a11\",\"dweb:/ipfs/QmQibMe3r5no95b6q7isGT5R75V8xSofWEDLXzp95b7LgZ\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"]},\"node_modules/@openzeppelin/contracts/access/Ownable.sol\":{\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://40fb1b5102468f783961d0af743f91b9980cf66b50d1d12009f6bb1869cea4d2\",\"dweb:/ipfs/QmYqEbJML4jB1GHbzD4cUZDtJg5wVwNm3vDJq1GbyDus8y\"]},\"node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://11756f42121f6541a35a8339ea899ee7514cfaa2e6d740625fcc844419296aa6\",\"dweb:/ipfs/QmekMuk6BY4DAjzeXr4MSbKdgoqqsZnA8JPtuyWc6CwXHf\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://20a97f891d06f0fe91560ea1a142aaa26fdd22bed1b51606b7d48f670deeb50f\",\"dweb:/ipfs/QmTbCtZKChpaX5H2iRiTDMcSz29GSLCpTCDgJpcMR4wg8x\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://26fef835622b46a5ba08b3ef6b46a22e94b5f285d0f0fb66b703bd30217d2c34\",\"dweb:/ipfs/QmZ548qdwfL1qF7aXz3xh1GCdTiST81kGGuKRqVUfYmPZR\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061337d806100206000396000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806389cb7343116100d8578063d40a71fb1161008c578063f2fde38b11610066578063f2fde38b1461042c578063fb5d73761461043f578063fe6b1ddf1461044757600080fd5b8063d40a71fb14610414578063df4ec2491461041c578063eb7c6f721461042457600080fd5b80638f4ed333116100bd5780638f4ed333146103d2578063b3f05b97146103da578063cf03c22d146103ed57600080fd5b806389cb7343146103715780638da5cb5b1461039357600080fd5b80635bc34f711161012f578063715018a611610114578063715018a61461020357806379502c551461020b5780637d1d95a61461036957600080fd5b80635bc34f71146101e35780636c4a5b1e146101f057600080fd5b806345f003641161016057806345f00364146101be5780634bb278f3146101d35780634fb4bcec146101db57600080fd5b8063204c881c1461017c578063289c6af7146101a4575b600080fd5b607d54607e5461018a919082565b604080519283526020830191909152015b60405180910390f35b6101ac600381565b60405160ff909116815260200161019b565b6101d16101cc3660046128b9565b61044f565b005b6101d1610491565b6101d161077d565b607f546101ac9060ff1681565b6101d16101fe366004612bf3565b6111ec565b6101d16115f7565b604080516080808201835260655473ffffffffffffffffffffffffffffffffffffffff908116835260665481166020808501919091526067548216848601526068548216606080860191909152855160e0808201885260695485168252606a54851682850152606b54851682890152606c54851682840152606d54851682870152606e54851660a080840191909152606f54861660c080850191909152895161010081018b52607054881681526071548816818801526072548816818c01526073548816818701526074548816818a015260755488168184015260765488168183015260775488169381019390935289519081018a526078548716815260795495810195909552607a5498850198909852607b5492840192909252607c5467ffffffffffffffff81169584019590955268010000000000000000909404909216948101949094526103599384565b60405161019b9493929190612cb8565b6101ac600481565b607f5461038390610100900460ff1681565b604051901515815260200161019b565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101d161160b565b607f546103839062010000900460ff1681565b607f546103ad906301000000900473ffffffffffffffffffffffffffffffffffffffff1681565b6101d161189d565b6101d1611b3e565b6101d161200c565b6101d161043a366004612e6d565b612117565b6101d16121ce565b6101d16123d5565b6104576125c3565b8051607d5560200151607e55607f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b6104996125c3565b606b546068546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b15801561050857600080fd5b505af115801561051c573d6000803e3d6000fd5b50506066546068546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201529116925063f2fde38b9150602401600060405180830381600087803b15801561058f57600080fd5b505af11580156105a3573d6000803e3d6000fd5b5050607f54600460ff90911611915061074e9050576065546068546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b15801561062757600080fd5b505af115801561063b573d6000803e3d6000fd5b5050606c546068546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911692506313af40359150602401600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b5050606e546068546040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169250638f2839709150602401600060405180830381600087803b15801561073557600080fd5b505af1158015610749573d6000803e3d6000fd5b505050505b607f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff1662010000179055565b6107856125c3565b607f5460059060ff168114610821576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f657000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b607f54610100900460ff166108b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f53797374656d4469637461746f723a2064796e616d6963206f7261636c65206360448201527f6f6e666967206973206e6f742079657420696e697469616c697a6564000000006064820152608401610818565b606654606954607054607d54607e546040516024810192909252604482015273ffffffffffffffffffffffffffffffffffffffff93841693639623609d938116921690606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe4a3011600000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526109ad93929190600401612f07565b600060405180830381600087803b1580156109c757600080fd5b505af11580156109db573d6000803e3d6000fd5b5050606654606a546071546040805160048082526024820183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8129fc1c0000000000000000000000000000000000000000000000000000000017905291517f9623609d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9586169750639623609d9650610a9895948516949390931692909101612f07565b600060405180830381600087803b158015610ab257600080fd5b505af1158015610ac6573d6000803e3d6000fd5b5050606654606b546072546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610b4457600080fd5b505af1158015610b58573d6000803e3d6000fd5b5050606b546040517fc4d66de800000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116925063c4d66de89150602401600060405180830381600087803b158015610bc757600080fd5b505af1925050508015610bd8575060015b610d3557610be4612f40565b806308c379a003610cab5750610bf8612f5c565b80610c035750610cad565b7f7a2a4e26842155ea933fe6eb6e3137eb5a296dcdf55721c552be7b4c3cc2375981604051602001610c359190613004565b604051602081830303815290604052805190602001201481604051602001610c5d9190613020565b60405160208183030381529060405290610ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610818919061308b565b5050610d35565b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f53797374656d4469637461746f723a20756e6578706563746564206572726f7260448201527f20696e697469616c697a696e67204c3158444d20286e6f20726561736f6e29006064820152608401610818565b606654606c546076546040805160048082526024820183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fed88c68e0000000000000000000000000000000000000000000000000000000017905291517f9623609d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff95861695639623609d95610deb95908216949116929101612f07565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b5050606654606c546073546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610e9757600080fd5b505af1158015610eab573d6000803e3d6000fd5b5050606654606d546074546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610f2957600080fd5b505af1158015610f3d573d6000803e3d6000fd5b5050606654606e546075546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610fbb57600080fd5b505af1158015610fcf573d6000803e3d6000fd5b5050606654606f54607754607854607954607a54607b54607c5460405173ffffffffffffffffffffffffffffffffffffffff958616602482015260448101949094526064840192909252608483015267ffffffffffffffff811660a4830152680100000000000000009004821660c48201529381169550639623609d94509182169291169060e401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8f974d7f00000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815261110693929190600401612f07565b600060405180830381600087803b15801561112057600080fd5b505af1158015611134573d6000803e3d6000fd5b5050606b54604080517f8456cb59000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169350638456cb59925060048181019260009290919082900301818387803b1580156111a457600080fd5b505af11580156111b8573d6000803e3d6000fd5b5050607f805460ff169250905060006111d0836130cd565b91906101000a81548160ff021916908360ff1602179055505050565b600054610100900460ff161580801561120c5750600054600160ff909116105b806112265750303b158015611226575060005460ff166001145b6112b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610818565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561131057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b81518051606580547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560208084015160668054841691851691909117905560408085015160678054851691861691909117905560609485015160688054851691861691909117905581870151805160698054861691871691909117905580830151606a8054861691871691909117905580820151606b8054861691871691909117905580860151606c80548616918716919091179055608080820151606d8054871691881691909117905560a080830151606e8054881691891691909117905560c092830151606f80548816918916919091179055838a01518051607080548916918a1691909117905580860151607180548916918a1691909117905580850151607280548916918a1691909117905580890151607380548916918a1691909117905580830151607480548916918a1691909117905580820151607580548916918a169190911790559283015160768054881691891691909117905560e09092015160778054871691881691909117905586890151805160788054909716908816179095559284015160795590830151607a5593820151607b55810151607c8054929094015167ffffffffffffffff9091167fffffffff0000000000000000000000000000000000000000000000000000000090921691909117680100000000000000009190921602179055607f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561156e612644565b6067546115909073ffffffffffffffffffffffffffffffffffffffff166126e3565b80156115f357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6115ff6125c3565b61160960006126e3565b565b6116136125c3565b607f5460029060ff1681146116aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f65700000000000000000000000000000000000000000000000000000000000006064820152608401610818565b6065546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac1906116fe906004016130ec565b602060405180830381865afa15801561171b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173f919061312f565b607f80547fffffffffffffffffff0000000000000000000000000000000000000000ffffff16630100000073ffffffffffffffffffffffffffffffffffffffff938416021790556065546040517f9b2ea4bd000000000000000000000000000000000000000000000000000000008152911690639b2ea4bd906117c79060009060040161314c565b600060405180830381600087803b1580156117e157600080fd5b505af11580156117f5573d6000803e3d6000fd5b5050606554604080517f9b2ea4bd0000000000000000000000000000000000000000000000000000000081526004810191909152601160448201527f44544c5f534855544f46465f424c4f434b000000000000000000000000000000606482015273ffffffffffffffffffffffffffffffffffffffff43811660248301529091169250639b2ea4bd91506084015b600060405180830381600087803b1580156111a457600080fd5b6118a56125c3565b607f5460019060ff16811461193c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f65700000000000000000000000000000000000000000000000000000000000006064820152608401610818565b6066546065546040517f0652b57a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911690630652b57a90602401600060405180830381600087803b1580156119ab57600080fd5b505af11580156119bf573d6000803e3d6000fd5b5050606654606b546040517f8d52d4a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450638d52d4a09350611a2192909116906002906004016131ad565b600060405180830381600087803b158015611a3b57600080fd5b505af1158015611a4f573d6000803e3d6000fd5b5050606654606b546040517f860f7cda00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316945063860f7cda9350611aae929091169060040161320e565b600060405180830381600087803b158015611ac857600080fd5b505af1158015611adc573d6000803e3d6000fd5b5050606654606c546040517f8d52d4a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450638d52d4a0935061188392909116906001906004016131ad565b611b466125c3565b607f5460039060ff168114611bdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f65700000000000000000000000000000000000000000000000000000000000006064820152608401610818565b60006040518061022001604052806040518060400160405280601d81526020017f4f564d5f43616e6f6e6963616c5472616e73616374696f6e436861696e00000081525081526020016040518060400160405280601a81526020017f4f564d5f4c3243726f7373446f6d61696e4d657373656e67657200000000000081525081526020016040518060600160405280602281526020016133076022913981526020016040518060400160405280600d81526020017f4f564d5f53657175656e6365720000000000000000000000000000000000000081525081526020016040518060400160405280600c81526020017f4f564d5f50726f706f7365720000000000000000000000000000000000000000815250815260200160405180606001604052806025815260200161332960259139815260200160405180606001604052806023815260200161334e602391398152604080518082018252601d81527f4f564d5f43616e6f6e6963616c5472616e73616374696f6e436861696e0000006020828101919091528084019190915281518083018352601881527f4f564d5f5374617465436f6d6d69746d656e74436861696e0000000000000000818301528284015281518083018352600f81527f4f564d5f426f6e644d616e61676572000000000000000000000000000000000081830152606084015281518083018352601481527f4f564d5f457865637574696f6e4d616e616765720000000000000000000000008183015260808401528151808301835260118082527f4f564d5f467261756456657269666965720000000000000000000000000000008284015260a085019190915282518084018452601781527f4f564d5f53746174654d616e61676572466163746f72790000000000000000008184015260c085015282518084018452601c81527f4f564d5f53746174655472616e736974696f6e6572466163746f7279000000008184015260e0850152825180840184529081527f4f564d5f536166657479436865636b65720000000000000000000000000000008183015261010084015281518083018352601981527f4f564d5f4c314d756c74694d65737361676552656c6179657200000000000000818301526101208401528151808301909252600b82527f426f6e644d616e616765720000000000000000000000000000000000000000009082015261014090910152905060005b6011811015611ff75760655473ffffffffffffffffffffffffffffffffffffffff16639b2ea4bd838360118110611f8e57611f8e613267565b602002015160006040518363ffffffff1660e01b8152600401611fb2929190613296565b600060405180830381600087803b158015611fcc57600080fd5b505af1158015611fe0573d6000803e3d6000fd5b505050508080611fef906132ce565b915050611f55565b5050607f805460ff169060006111d0836130cd565b6120146125c3565b607f5460069060ff1681146120ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f65700000000000000000000000000000000000000000000000000000000000006064820152608401610818565b606b54604080517f3f4ba83a000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921691633f4ba83a9160048181019260009290919082900301818387803b1580156111a457600080fd5b61211f6125c3565b73ffffffffffffffffffffffffffffffffffffffff81166121c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610818565b6121cb816126e3565b50565b6121d66125c3565b607f5460049060ff16811461226d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f65700000000000000000000000000000000000000000000000000000000000006064820152608401610818565b6065546066546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b1580156122dc57600080fd5b505af11580156122f0573d6000803e3d6000fd5b5050606c546066546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911692506313af40359150602401600060405180830381600087803b15801561236357600080fd5b505af1158015612377573d6000803e3d6000fd5b5050606e546066546040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169250638f2839709150602401611883565b6123dd6125c3565b607f5460ff16600314612472576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f53797374656d4469637461746f723a2063616e206f6e6c79206578697431206260448201527f65666f72652073746570203320697320657865637574656400000000000000006064820152608401610818565b606554607f546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831692639b2ea4bd926124d59263010000009091049091169060040161314c565b600060405180830381600087803b1580156124ef57600080fd5b505af1158015612503573d6000803e3d6000fd5b5050606554604080517f9b2ea4bd0000000000000000000000000000000000000000000000000000000081526004810191909152601160448201527f44544c5f534855544f46465f424c4f434b00000000000000000000000000000060648201526000602482015273ffffffffffffffffffffffffffffffffffffffff9091169250639b2ea4bd9150608401600060405180830381600087803b1580156125a957600080fd5b505af11580156125bd573d6000803e3d6000fd5b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314611609576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610818565b600054610100900460ff166126db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610818565b61160961275a565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166127f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610818565b611609336126e3565b6080810181811067ffffffffffffffff82111715612841577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405250565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff821117156128b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040525050565b6000604082840312156128cb57600080fd5b6040516040810181811067ffffffffffffffff82111715612915577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052823581526020928301359281019290925250919050565b73ffffffffffffffffffffffffffffffffffffffff811681146121cb57600080fd5b803561295c8161292f565b919050565b600060e0828403121561297357600080fd5b60405160e0810181811067ffffffffffffffff821117156129bd577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508082356129ce8161292f565b815260208301356129de8161292f565b60208201526129ef60408401612951565b6040820152612a0060608401612951565b6060820152612a1160808401612951565b6080820152612a2260a08401612951565b60a0820152612a3360c08401612951565b60c08201525092915050565b6000610100808385031215612a5357600080fd5b6040519081019067ffffffffffffffff82118183101715612a9d577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b81604052809250612aad84612951565b8152612abb60208501612951565b6020820152612acc60408501612951565b6040820152612add60608501612951565b6060820152612aee60808501612951565b6080820152612aff60a08501612951565b60a0820152612b1060c08501612951565b60c0820152612b2160e08501612951565b60e0820152505092915050565b600060c08284031215612b4057600080fd5b60405160c0810167ffffffffffffffff8282108183111715612b8b577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8160405282935084359150612b9f8261292f565b818352602085013560208401526040850135604084015260608501356060840152608085013591508082168214612bd557600080fd5b506080820152612be760a08401612951565b60a08201525092915050565b6000818303610320811215612c0757600080fd5b604051612c13816127fa565b6080821215612c2157600080fd5b6040519150612c2f826127fa565b8335612c3a8161292f565b82526020840135612c4a8161292f565b60208301526040840135612c5d8161292f565b60408301526060840135612c708161292f565b6060830152818152612c858560808601612961565b6020820152612c98856101608601612a3f565b6040820152612cab856102608601612b2e565b6060820152949350505050565b60006103208201905073ffffffffffffffffffffffffffffffffffffffff8087511683528060208801511660208401528060408801511660408401528060608801511660608401528086511660808401528060208701511660a08401528060408701511660c08401528060608701511660e0840152806080870151166101008401525060a0850151612d6361012084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c085015173ffffffffffffffffffffffffffffffffffffffff811661014084015250835173ffffffffffffffffffffffffffffffffffffffff90811661016084015260208501518116610180840152604085015181166101a0840152606085015181166101c0840152608085015181166101e084015260a0850151811661020084015260c0850151811661022084015260e085015116610240830152825173ffffffffffffffffffffffffffffffffffffffff908116610260840152602084015161028084015260408401516102a084015260608401516102c0840152608084015167ffffffffffffffff166102e084015260a0840151166103008301525b95945050505050565b600060208284031215612e7f57600080fd5b8135612e8a8161292f565b9392505050565b60005b83811015612eac578181015183820152602001612e94565b838111156125bd5750506000910152565b60008151808452612ed5816020860160208601612e91565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff808616835280851660208401525060606040830152612e646060830184612ebd565b600060033d1115612f595760046000803e5060005160e01c5b90565b600060443d1015612f6a5790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff8160248401118184111715612fb857505050505090565b8285019150815181811115612fd05750505050505090565b843d8701016020828501011115612fea5750505050505090565b612ff960208286010187612847565b509095945050505050565b60008251613016818460208701612e91565b9190910192915050565b7f53797374656d4469637461746f723a20756e6578706563746564206572726f7281527f20696e697469616c697a696e67204c3158444d3a20000000000000000000000060208201526000825161307e816035850160208701612e91565b9190910160350192915050565b602081526000612e8a6020830184612ebd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff81036130e3576130e361309e565b60010192915050565b60208152600061312960208301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b92915050565b60006020828403121561314157600080fd5b8151612e8a8161292f565b60408152600061318960408301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b905073ffffffffffffffffffffffffffffffffffffffff8316602083015292915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040810160038310613201577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8260208301529392505050565b73ffffffffffffffffffffffffffffffffffffffff82168152604060208201526000612e8a60408301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040815260006132a96040830185612ebd565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036132ff576132ff61309e565b506001019056fe4f564d5f4465636f6d7072657373696f6e507265636f6d70696c65416464726573734f564d5f436861696e53746f72616765436f6e7461696e65722d4354432d626174636865734f564d5f436861696e53746f72616765436f6e7461696e65722d4354432d7175657565a164736f6c634300080f000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101775760003560e01c806389cb7343116100d8578063d40a71fb1161008c578063f2fde38b11610066578063f2fde38b1461042c578063fb5d73761461043f578063fe6b1ddf1461044757600080fd5b8063d40a71fb14610414578063df4ec2491461041c578063eb7c6f721461042457600080fd5b80638f4ed333116100bd5780638f4ed333146103d2578063b3f05b97146103da578063cf03c22d146103ed57600080fd5b806389cb7343146103715780638da5cb5b1461039357600080fd5b80635bc34f711161012f578063715018a611610114578063715018a61461020357806379502c551461020b5780637d1d95a61461036957600080fd5b80635bc34f71146101e35780636c4a5b1e146101f057600080fd5b806345f003641161016057806345f00364146101be5780634bb278f3146101d35780634fb4bcec146101db57600080fd5b8063204c881c1461017c578063289c6af7146101a4575b600080fd5b607d54607e5461018a919082565b604080519283526020830191909152015b60405180910390f35b6101ac600381565b60405160ff909116815260200161019b565b6101d16101cc3660046128b9565b61044f565b005b6101d1610491565b6101d161077d565b607f546101ac9060ff1681565b6101d16101fe366004612bf3565b6111ec565b6101d16115f7565b604080516080808201835260655473ffffffffffffffffffffffffffffffffffffffff908116835260665481166020808501919091526067548216848601526068548216606080860191909152855160e0808201885260695485168252606a54851682850152606b54851682890152606c54851682840152606d54851682870152606e54851660a080840191909152606f54861660c080850191909152895161010081018b52607054881681526071548816818801526072548816818c01526073548816818701526074548816818a015260755488168184015260765488168183015260775488169381019390935289519081018a526078548716815260795495810195909552607a5498850198909852607b5492840192909252607c5467ffffffffffffffff81169584019590955268010000000000000000909404909216948101949094526103599384565b60405161019b9493929190612cb8565b6101ac600481565b607f5461038390610100900460ff1681565b604051901515815260200161019b565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101d161160b565b607f546103839062010000900460ff1681565b607f546103ad906301000000900473ffffffffffffffffffffffffffffffffffffffff1681565b6101d161189d565b6101d1611b3e565b6101d161200c565b6101d161043a366004612e6d565b612117565b6101d16121ce565b6101d16123d5565b6104576125c3565b8051607d5560200151607e55607f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b6104996125c3565b606b546068546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b15801561050857600080fd5b505af115801561051c573d6000803e3d6000fd5b50506066546068546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201529116925063f2fde38b9150602401600060405180830381600087803b15801561058f57600080fd5b505af11580156105a3573d6000803e3d6000fd5b5050607f54600460ff90911611915061074e9050576065546068546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b15801561062757600080fd5b505af115801561063b573d6000803e3d6000fd5b5050606c546068546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911692506313af40359150602401600060405180830381600087803b1580156106ae57600080fd5b505af11580156106c2573d6000803e3d6000fd5b5050606e546068546040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169250638f2839709150602401600060405180830381600087803b15801561073557600080fd5b505af1158015610749573d6000803e3d6000fd5b505050505b607f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff1662010000179055565b6107856125c3565b607f5460059060ff168114610821576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f657000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b607f54610100900460ff166108b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f53797374656d4469637461746f723a2064796e616d6963206f7261636c65206360448201527f6f6e666967206973206e6f742079657420696e697469616c697a6564000000006064820152608401610818565b606654606954607054607d54607e546040516024810192909252604482015273ffffffffffffffffffffffffffffffffffffffff93841693639623609d938116921690606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe4a3011600000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526109ad93929190600401612f07565b600060405180830381600087803b1580156109c757600080fd5b505af11580156109db573d6000803e3d6000fd5b5050606654606a546071546040805160048082526024820183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8129fc1c0000000000000000000000000000000000000000000000000000000017905291517f9623609d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9586169750639623609d9650610a9895948516949390931692909101612f07565b600060405180830381600087803b158015610ab257600080fd5b505af1158015610ac6573d6000803e3d6000fd5b5050606654606b546072546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610b4457600080fd5b505af1158015610b58573d6000803e3d6000fd5b5050606b546040517fc4d66de800000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116925063c4d66de89150602401600060405180830381600087803b158015610bc757600080fd5b505af1925050508015610bd8575060015b610d3557610be4612f40565b806308c379a003610cab5750610bf8612f5c565b80610c035750610cad565b7f7a2a4e26842155ea933fe6eb6e3137eb5a296dcdf55721c552be7b4c3cc2375981604051602001610c359190613004565b604051602081830303815290604052805190602001201481604051602001610c5d9190613020565b60405160208183030381529060405290610ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610818919061308b565b5050610d35565b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f53797374656d4469637461746f723a20756e6578706563746564206572726f7260448201527f20696e697469616c697a696e67204c3158444d20286e6f20726561736f6e29006064820152608401610818565b606654606c546076546040805160048082526024820183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fed88c68e0000000000000000000000000000000000000000000000000000000017905291517f9623609d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff95861695639623609d95610deb95908216949116929101612f07565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b5050606654606c546073546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610e9757600080fd5b505af1158015610eab573d6000803e3d6000fd5b5050606654606d546074546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610f2957600080fd5b505af1158015610f3d573d6000803e3d6000fd5b5050606654606e546075546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610fbb57600080fd5b505af1158015610fcf573d6000803e3d6000fd5b5050606654606f54607754607854607954607a54607b54607c5460405173ffffffffffffffffffffffffffffffffffffffff958616602482015260448101949094526064840192909252608483015267ffffffffffffffff811660a4830152680100000000000000009004821660c48201529381169550639623609d94509182169291169060e401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8f974d7f00000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815261110693929190600401612f07565b600060405180830381600087803b15801561112057600080fd5b505af1158015611134573d6000803e3d6000fd5b5050606b54604080517f8456cb59000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169350638456cb59925060048181019260009290919082900301818387803b1580156111a457600080fd5b505af11580156111b8573d6000803e3d6000fd5b5050607f805460ff169250905060006111d0836130cd565b91906101000a81548160ff021916908360ff1602179055505050565b600054610100900460ff161580801561120c5750600054600160ff909116105b806112265750303b158015611226575060005460ff166001145b6112b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610818565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561131057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b81518051606580547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560208084015160668054841691851691909117905560408085015160678054851691861691909117905560609485015160688054851691861691909117905581870151805160698054861691871691909117905580830151606a8054861691871691909117905580820151606b8054861691871691909117905580860151606c80548616918716919091179055608080820151606d8054871691881691909117905560a080830151606e8054881691891691909117905560c092830151606f80548816918916919091179055838a01518051607080548916918a1691909117905580860151607180548916918a1691909117905580850151607280548916918a1691909117905580890151607380548916918a1691909117905580830151607480548916918a1691909117905580820151607580548916918a169190911790559283015160768054881691891691909117905560e09092015160778054871691881691909117905586890151805160788054909716908816179095559284015160795590830151607a5593820151607b55810151607c8054929094015167ffffffffffffffff9091167fffffffff0000000000000000000000000000000000000000000000000000000090921691909117680100000000000000009190921602179055607f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561156e612644565b6067546115909073ffffffffffffffffffffffffffffffffffffffff166126e3565b80156115f357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6115ff6125c3565b61160960006126e3565b565b6116136125c3565b607f5460029060ff1681146116aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f65700000000000000000000000000000000000000000000000000000000000006064820152608401610818565b6065546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac1906116fe906004016130ec565b602060405180830381865afa15801561171b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173f919061312f565b607f80547fffffffffffffffffff0000000000000000000000000000000000000000ffffff16630100000073ffffffffffffffffffffffffffffffffffffffff938416021790556065546040517f9b2ea4bd000000000000000000000000000000000000000000000000000000008152911690639b2ea4bd906117c79060009060040161314c565b600060405180830381600087803b1580156117e157600080fd5b505af11580156117f5573d6000803e3d6000fd5b5050606554604080517f9b2ea4bd0000000000000000000000000000000000000000000000000000000081526004810191909152601160448201527f44544c5f534855544f46465f424c4f434b000000000000000000000000000000606482015273ffffffffffffffffffffffffffffffffffffffff43811660248301529091169250639b2ea4bd91506084015b600060405180830381600087803b1580156111a457600080fd5b6118a56125c3565b607f5460019060ff16811461193c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f65700000000000000000000000000000000000000000000000000000000000006064820152608401610818565b6066546065546040517f0652b57a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911690630652b57a90602401600060405180830381600087803b1580156119ab57600080fd5b505af11580156119bf573d6000803e3d6000fd5b5050606654606b546040517f8d52d4a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450638d52d4a09350611a2192909116906002906004016131ad565b600060405180830381600087803b158015611a3b57600080fd5b505af1158015611a4f573d6000803e3d6000fd5b5050606654606b546040517f860f7cda00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316945063860f7cda9350611aae929091169060040161320e565b600060405180830381600087803b158015611ac857600080fd5b505af1158015611adc573d6000803e3d6000fd5b5050606654606c546040517f8d52d4a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450638d52d4a0935061188392909116906001906004016131ad565b611b466125c3565b607f5460039060ff168114611bdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f65700000000000000000000000000000000000000000000000000000000000006064820152608401610818565b60006040518061022001604052806040518060400160405280601d81526020017f4f564d5f43616e6f6e6963616c5472616e73616374696f6e436861696e00000081525081526020016040518060400160405280601a81526020017f4f564d5f4c3243726f7373446f6d61696e4d657373656e67657200000000000081525081526020016040518060600160405280602281526020016133076022913981526020016040518060400160405280600d81526020017f4f564d5f53657175656e6365720000000000000000000000000000000000000081525081526020016040518060400160405280600c81526020017f4f564d5f50726f706f7365720000000000000000000000000000000000000000815250815260200160405180606001604052806025815260200161332960259139815260200160405180606001604052806023815260200161334e602391398152604080518082018252601d81527f4f564d5f43616e6f6e6963616c5472616e73616374696f6e436861696e0000006020828101919091528084019190915281518083018352601881527f4f564d5f5374617465436f6d6d69746d656e74436861696e0000000000000000818301528284015281518083018352600f81527f4f564d5f426f6e644d616e61676572000000000000000000000000000000000081830152606084015281518083018352601481527f4f564d5f457865637574696f6e4d616e616765720000000000000000000000008183015260808401528151808301835260118082527f4f564d5f467261756456657269666965720000000000000000000000000000008284015260a085019190915282518084018452601781527f4f564d5f53746174654d616e61676572466163746f72790000000000000000008184015260c085015282518084018452601c81527f4f564d5f53746174655472616e736974696f6e6572466163746f7279000000008184015260e0850152825180840184529081527f4f564d5f536166657479436865636b65720000000000000000000000000000008183015261010084015281518083018352601981527f4f564d5f4c314d756c74694d65737361676552656c6179657200000000000000818301526101208401528151808301909252600b82527f426f6e644d616e616765720000000000000000000000000000000000000000009082015261014090910152905060005b6011811015611ff75760655473ffffffffffffffffffffffffffffffffffffffff16639b2ea4bd838360118110611f8e57611f8e613267565b602002015160006040518363ffffffff1660e01b8152600401611fb2929190613296565b600060405180830381600087803b158015611fcc57600080fd5b505af1158015611fe0573d6000803e3d6000fd5b505050508080611fef906132ce565b915050611f55565b5050607f805460ff169060006111d0836130cd565b6120146125c3565b607f5460069060ff1681146120ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f65700000000000000000000000000000000000000000000000000000000000006064820152608401610818565b606b54604080517f3f4ba83a000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff90921691633f4ba83a9160048181019260009290919082900301818387803b1580156111a457600080fd5b61211f6125c3565b73ffffffffffffffffffffffffffffffffffffffff81166121c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610818565b6121cb816126e3565b50565b6121d66125c3565b607f5460049060ff16811461226d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4261736553797374656d4469637461746f723a20696e636f727265637420737460448201527f65700000000000000000000000000000000000000000000000000000000000006064820152608401610818565b6065546066546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b1580156122dc57600080fd5b505af11580156122f0573d6000803e3d6000fd5b5050606c546066546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911692506313af40359150602401600060405180830381600087803b15801561236357600080fd5b505af1158015612377573d6000803e3d6000fd5b5050606e546066546040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169250638f2839709150602401611883565b6123dd6125c3565b607f5460ff16600314612472576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f53797374656d4469637461746f723a2063616e206f6e6c79206578697431206260448201527f65666f72652073746570203320697320657865637574656400000000000000006064820152608401610818565b606554607f546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831692639b2ea4bd926124d59263010000009091049091169060040161314c565b600060405180830381600087803b1580156124ef57600080fd5b505af1158015612503573d6000803e3d6000fd5b5050606554604080517f9b2ea4bd0000000000000000000000000000000000000000000000000000000081526004810191909152601160448201527f44544c5f534855544f46465f424c4f434b00000000000000000000000000000060648201526000602482015273ffffffffffffffffffffffffffffffffffffffff9091169250639b2ea4bd9150608401600060405180830381600087803b1580156125a957600080fd5b505af11580156125bd573d6000803e3d6000fd5b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314611609576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610818565b600054610100900460ff166126db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610818565b61160961275a565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166127f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610818565b611609336126e3565b6080810181811067ffffffffffffffff82111715612841577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405250565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff821117156128b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040525050565b6000604082840312156128cb57600080fd5b6040516040810181811067ffffffffffffffff82111715612915577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052823581526020928301359281019290925250919050565b73ffffffffffffffffffffffffffffffffffffffff811681146121cb57600080fd5b803561295c8161292f565b919050565b600060e0828403121561297357600080fd5b60405160e0810181811067ffffffffffffffff821117156129bd577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508082356129ce8161292f565b815260208301356129de8161292f565b60208201526129ef60408401612951565b6040820152612a0060608401612951565b6060820152612a1160808401612951565b6080820152612a2260a08401612951565b60a0820152612a3360c08401612951565b60c08201525092915050565b6000610100808385031215612a5357600080fd5b6040519081019067ffffffffffffffff82118183101715612a9d577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b81604052809250612aad84612951565b8152612abb60208501612951565b6020820152612acc60408501612951565b6040820152612add60608501612951565b6060820152612aee60808501612951565b6080820152612aff60a08501612951565b60a0820152612b1060c08501612951565b60c0820152612b2160e08501612951565b60e0820152505092915050565b600060c08284031215612b4057600080fd5b60405160c0810167ffffffffffffffff8282108183111715612b8b577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8160405282935084359150612b9f8261292f565b818352602085013560208401526040850135604084015260608501356060840152608085013591508082168214612bd557600080fd5b506080820152612be760a08401612951565b60a08201525092915050565b6000818303610320811215612c0757600080fd5b604051612c13816127fa565b6080821215612c2157600080fd5b6040519150612c2f826127fa565b8335612c3a8161292f565b82526020840135612c4a8161292f565b60208301526040840135612c5d8161292f565b60408301526060840135612c708161292f565b6060830152818152612c858560808601612961565b6020820152612c98856101608601612a3f565b6040820152612cab856102608601612b2e565b6060820152949350505050565b60006103208201905073ffffffffffffffffffffffffffffffffffffffff8087511683528060208801511660208401528060408801511660408401528060608801511660608401528086511660808401528060208701511660a08401528060408701511660c08401528060608701511660e0840152806080870151166101008401525060a0850151612d6361012084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c085015173ffffffffffffffffffffffffffffffffffffffff811661014084015250835173ffffffffffffffffffffffffffffffffffffffff90811661016084015260208501518116610180840152604085015181166101a0840152606085015181166101c0840152608085015181166101e084015260a0850151811661020084015260c0850151811661022084015260e085015116610240830152825173ffffffffffffffffffffffffffffffffffffffff908116610260840152602084015161028084015260408401516102a084015260608401516102c0840152608084015167ffffffffffffffff166102e084015260a0840151166103008301525b95945050505050565b600060208284031215612e7f57600080fd5b8135612e8a8161292f565b9392505050565b60005b83811015612eac578181015183820152602001612e94565b838111156125bd5750506000910152565b60008151808452612ed5816020860160208601612e91565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff808616835280851660208401525060606040830152612e646060830184612ebd565b600060033d1115612f595760046000803e5060005160e01c5b90565b600060443d1015612f6a5790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff8160248401118184111715612fb857505050505090565b8285019150815181811115612fd05750505050505090565b843d8701016020828501011115612fea5750505050505090565b612ff960208286010187612847565b509095945050505050565b60008251613016818460208701612e91565b9190910192915050565b7f53797374656d4469637461746f723a20756e6578706563746564206572726f7281527f20696e697469616c697a696e67204c3158444d3a20000000000000000000000060208201526000825161307e816035850160208701612e91565b9190910160350192915050565b602081526000612e8a6020830184612ebd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff81036130e3576130e361309e565b60010192915050565b60208152600061312960208301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b92915050565b60006020828403121561314157600080fd5b8151612e8a8161292f565b60408152600061318960408301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b905073ffffffffffffffffffffffffffffffffffffffff8316602083015292915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040810160038310613201577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8260208301529392505050565b73ffffffffffffffffffffffffffffffffffffffff82168152604060208201526000612e8a60408301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040815260006132a96040830185612ebd565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036132ff576132ff61309e565b506001019056fe4f564d5f4465636f6d7072657373696f6e507265636f6d70696c65416464726573734f564d5f436861696e53746f72616765436f6e7461696e65722d4354432d626174636865734f564d5f436861696e53746f72616765436f6e7461696e65722d4354432d7175657565a164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "initialize(((address,address,address,address),(address,address,address,address,address,address,address),(address,address,address,address,address,address,address,address),(address,uint256,uint256,bytes32,uint64,address)))": { - "params": { - "_config": "System configuration." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - }, - "updateL2OutputOracleDynamicConfig((uint256,uint256))": { - "params": { - "_l2OutputOracleDynamicConfig": "Dynamic L2OutputOracle config." - } - } - }, - "title": "SystemDictator" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "EXIT_1_NO_RETURN_STEP()": { - "notice": "Step after which exit 1 can no longer be used." - }, - "PROXY_TRANSFER_STEP()": { - "notice": "Step where proxy ownership is transferred." - }, - "config()": { - "notice": "System configuration." - }, - "currentStep()": { - "notice": "Current step;" - }, - "dynamicConfigSet()": { - "notice": "Whether or not dynamic config has been set." - }, - "exit1()": { - "notice": "First exit point, can only be called before step 3 is executed." - }, - "finalize()": { - "notice": "Tranfers admin ownership to the final owner." - }, - "finalized()": { - "notice": "Whether or not the deployment is finalized." - }, - "l2OutputOracleDynamicConfig()": { - "notice": "Dynamic configuration for the L2OutputOracle." - }, - "oldL1CrossDomainMessenger()": { - "notice": "Address of the old L1CrossDomainMessenger implementation." - }, - "step1()": { - "notice": "Configures the ProxyAdmin contract." - }, - "step2()": { - "notice": "Pauses the system by shutting down the L1CrossDomainMessenger and setting the deposit halt flag to tell the Sequencer's DTL to stop accepting deposits." - }, - "step3()": { - "notice": "Removes deprecated addresses from the AddressManager." - }, - "step4()": { - "notice": "Transfers system ownership to the ProxyAdmin." - }, - "step5()": { - "notice": "Upgrades and initializes proxy contracts." - }, - "step6()": { - "notice": "Unpauses the system at which point the system should be fully operational." - }, - "updateL2OutputOracleDynamicConfig((uint256,uint256))": { - "notice": "Allows the owner to update dynamic L2OutputOracle config." - } - }, - "notice": "The SystemDictator is responsible for coordinating the deployment of a full Bedrock system. The SystemDictator is designed to support both fresh network deployments and upgrades to existing pre-Bedrock systems." - }, - "storageLayout": { - "storage": [ - { - "astId": 39752, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 39755, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 40366, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 39624, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 39744, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 3575, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "config", - "offset": 0, - "slot": "101", - "type": "t_struct(DeployConfig)3563_storage" - }, - { - "astId": 3579, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l2OutputOracleDynamicConfig", - "offset": 0, - "slot": "125", - "type": "t_struct(L2OutputOracleDynamicConfig)3537_storage" - }, - { - "astId": 3582, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "currentStep", - "offset": 0, - "slot": "127", - "type": "t_uint8" - }, - { - "astId": 3585, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "dynamicConfigSet", - "offset": 1, - "slot": "127", - "type": "t_bool" - }, - { - "astId": 3588, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "finalized", - "offset": 2, - "slot": "127", - "type": "t_bool" - }, - { - "astId": 3591, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "oldL1CrossDomainMessenger", - "offset": 3, - "slot": "127", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_contract(AddressManager)5619": { - "encoding": "inplace", - "label": "contract AddressManager", - "numberOfBytes": "20" - }, - "t_contract(L1CrossDomainMessenger)135": { - "encoding": "inplace", - "label": "contract L1CrossDomainMessenger", - "numberOfBytes": "20" - }, - "t_contract(L1ERC721Bridge)335": { - "encoding": "inplace", - "label": "contract L1ERC721Bridge", - "numberOfBytes": "20" - }, - "t_contract(L1StandardBridge)663": { - "encoding": "inplace", - "label": "contract L1StandardBridge", - "numberOfBytes": "20" - }, - "t_contract(L2OutputOracle)1088": { - "encoding": "inplace", - "label": "contract L2OutputOracle", - "numberOfBytes": "20" - }, - "t_contract(OptimismMintableERC20Factory)37809": { - "encoding": "inplace", - "label": "contract OptimismMintableERC20Factory", - "numberOfBytes": "20" - }, - "t_contract(OptimismPortal)1639": { - "encoding": "inplace", - "label": "contract OptimismPortal", - "numberOfBytes": "20" - }, - "t_contract(PortalSender)3450": { - "encoding": "inplace", - "label": "contract PortalSender", - "numberOfBytes": "20" - }, - "t_contract(ProxyAdmin)38861": { - "encoding": "inplace", - "label": "contract ProxyAdmin", - "numberOfBytes": "20" - }, - "t_contract(SystemConfig)2199": { - "encoding": "inplace", - "label": "contract SystemConfig", - "numberOfBytes": "20" - }, - "t_struct(DeployConfig)3563_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.DeployConfig", - "numberOfBytes": "768", - "members": [ - { - "astId": 3553, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "globalConfig", - "offset": 0, - "slot": "0", - "type": "t_struct(GlobalConfig)3492_storage" - }, - { - "astId": 3556, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "proxyAddressConfig", - "offset": 0, - "slot": "4", - "type": "t_struct(ProxyAddressConfig)3507_storage" - }, - { - "astId": 3559, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "implementationAddressConfig", - "offset": 0, - "slot": "11", - "type": "t_struct(ImplementationAddressConfig)3532_storage" - }, - { - "astId": 3562, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "systemConfigConfig", - "offset": 0, - "slot": "19", - "type": "t_struct(SystemConfigConfig)3550_storage" - } - ] - }, - "t_struct(GlobalConfig)3492_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.GlobalConfig", - "numberOfBytes": "128", - "members": [ - { - "astId": 3484, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "addressManager", - "offset": 0, - "slot": "0", - "type": "t_contract(AddressManager)5619" - }, - { - "astId": 3487, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "proxyAdmin", - "offset": 0, - "slot": "1", - "type": "t_contract(ProxyAdmin)38861" - }, - { - "astId": 3489, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "controller", - "offset": 0, - "slot": "2", - "type": "t_address" - }, - { - "astId": 3491, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "finalOwner", - "offset": 0, - "slot": "3", - "type": "t_address" - } - ] - }, - "t_struct(ImplementationAddressConfig)3532_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.ImplementationAddressConfig", - "numberOfBytes": "256", - "members": [ - { - "astId": 3510, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l2OutputOracleImpl", - "offset": 0, - "slot": "0", - "type": "t_contract(L2OutputOracle)1088" - }, - { - "astId": 3513, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "optimismPortalImpl", - "offset": 0, - "slot": "1", - "type": "t_contract(OptimismPortal)1639" - }, - { - "astId": 3516, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1CrossDomainMessengerImpl", - "offset": 0, - "slot": "2", - "type": "t_contract(L1CrossDomainMessenger)135" - }, - { - "astId": 3519, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1StandardBridgeImpl", - "offset": 0, - "slot": "3", - "type": "t_contract(L1StandardBridge)663" - }, - { - "astId": 3522, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "optimismMintableERC20FactoryImpl", - "offset": 0, - "slot": "4", - "type": "t_contract(OptimismMintableERC20Factory)37809" - }, - { - "astId": 3525, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1ERC721BridgeImpl", - "offset": 0, - "slot": "5", - "type": "t_contract(L1ERC721Bridge)335" - }, - { - "astId": 3528, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "portalSenderImpl", - "offset": 0, - "slot": "6", - "type": "t_contract(PortalSender)3450" - }, - { - "astId": 3531, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "systemConfigImpl", - "offset": 0, - "slot": "7", - "type": "t_contract(SystemConfig)2199" - } - ] - }, - "t_struct(L2OutputOracleDynamicConfig)3537_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.L2OutputOracleDynamicConfig", - "numberOfBytes": "64", - "members": [ - { - "astId": 3534, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l2OutputOracleStartingBlockNumber", - "offset": 0, - "slot": "0", - "type": "t_uint256" - }, - { - "astId": 3536, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l2OutputOracleStartingTimestamp", - "offset": 0, - "slot": "1", - "type": "t_uint256" - } - ] - }, - "t_struct(ProxyAddressConfig)3507_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.ProxyAddressConfig", - "numberOfBytes": "224", - "members": [ - { - "astId": 3494, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l2OutputOracleProxy", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 3496, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "optimismPortalProxy", - "offset": 0, - "slot": "1", - "type": "t_address" - }, - { - "astId": 3498, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1CrossDomainMessengerProxy", - "offset": 0, - "slot": "2", - "type": "t_address" - }, - { - "astId": 3500, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1StandardBridgeProxy", - "offset": 0, - "slot": "3", - "type": "t_address" - }, - { - "astId": 3502, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "optimismMintableERC20FactoryProxy", - "offset": 0, - "slot": "4", - "type": "t_address" - }, - { - "astId": 3504, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1ERC721BridgeProxy", - "offset": 0, - "slot": "5", - "type": "t_address" - }, - { - "astId": 3506, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "systemConfigProxy", - "offset": 0, - "slot": "6", - "type": "t_address" - } - ] - }, - "t_struct(SystemConfigConfig)3550_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.SystemConfigConfig", - "numberOfBytes": "160", - "members": [ - { - "astId": 3539, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 3541, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "overhead", - "offset": 0, - "slot": "1", - "type": "t_uint256" - }, - { - "astId": 3543, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "scalar", - "offset": 0, - "slot": "2", - "type": "t_uint256" - }, - { - "astId": 3545, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "batcherHash", - "offset": 0, - "slot": "3", - "type": "t_bytes32" - }, - { - "astId": 3547, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "gasLimit", - "offset": 0, - "slot": "4", - "type": "t_uint64" - }, - { - "astId": 3549, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "unsafeBlockSigner", - "offset": 8, - "slot": "4", - "type": "t_address" - } - ] - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/SystemDictatorProxy.json b/packages/contracts-bedrock/deployments/goerli/SystemDictatorProxy.json deleted file mode 100644 index 3da70c541f0c..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/SystemDictatorProxy.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0x1f0613A44c9a8ECE7B3A2e0CdBdF0F5B47A50971", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x9718b83cec53331007bb38bbce3481e739784c1e3ea892d32f56a68de7bd2583", - "receipt": { - "to": null, - "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078", - "contractAddress": "0x1f0613A44c9a8ECE7B3A2e0CdBdF0F5B47A50971", - "transactionIndex": 19, - "gasUsed": "523812", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000800000000000000000000000020000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x00e82f0ff03295b36f55417ba53194c468787db6efdeee96ea3b87c5ad87c2e7", - "transactionHash": "0x9718b83cec53331007bb38bbce3481e739784c1e3ea892d32f56a68de7bd2583", - "logs": [ - { - "transactionIndex": 19, - "blockNumber": 8299688, - "transactionHash": "0x9718b83cec53331007bb38bbce3481e739784c1e3ea892d32f56a68de7bd2583", - "address": "0x1f0613A44c9a8ECE7B3A2e0CdBdF0F5B47A50971", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000956a5152d0f498dba0c5966577bb44262f8f7078", - "logIndex": 41, - "blockHash": "0x00e82f0ff03295b36f55417ba53194c468787db6efdeee96ea3b87c5ad87c2e7" - } - ], - "blockNumber": 8299688, - "cumulativeGasUsed": "3019562", - "status": 1, - "byzantium": true - }, - "args": [ - "0x956a5152D0f498dBA0c5966577bb44262F8F7078" - ], - "numDeployments": 1, - "solcInputHash": "672fbec9734a08fc34112408d6dc7f7b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\",\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/solcInputs/1488cae0dec1a45bfa23bc28dafed7e1.json b/packages/contracts-bedrock/deployments/goerli/solcInputs/1488cae0dec1a45bfa23bc28dafed7e1.json deleted file mode 100644 index 359b0f6a7683..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/solcInputs/1488cae0dec1a45bfa23bc28dafed7e1.json +++ /dev/null @@ -1,552 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/L1/L1CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismPortal } from \"./OptimismPortal.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1CrossDomainMessenger\n * @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible\n * for sending and receiving data on the L1 side. Users are encouraged to use this\n * interface instead of interacting with lower-level contracts directly.\n */\ncontract L1CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @notice Address of the OptimismPortal.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _portal Address of the OptimismPortal contract on this network.\n */\n constructor(OptimismPortal _portal)\n Semver(1, 1, 0)\n CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER)\n {\n PORTAL = _portal;\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return msg.sender == address(PORTAL) && PORTAL.l2Sender() == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(PORTAL);\n }\n}\n" - }, - "contracts/L1/L1ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { IERC721 } from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L1ERC721Bridge\n * @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as an escrow for ERC721 tokens deposited into L2.\n */\ncontract L1ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token\n * by ID was deposited for a given L2 token.\n */\n mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L1ERC721Bridge: local token cannot be self\");\n\n // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.\n require(\n deposits[_localToken][_remoteToken][_tokenId] == true,\n \"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\"\n );\n\n // Mark that the token ID for this L1/L2 token pair is no longer escrowed in the L1\n // Bridge.\n deposits[_localToken][_remoteToken][_tokenId] = false;\n\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the\n // withdrawer.\n IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L1ERC721Bridge: remote token cannot be address(0)\");\n\n // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)\n bytes memory message = abi.encodeWithSelector(\n L2ERC721Bridge.finalizeBridgeERC721.selector,\n _remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Lock token into bridge\n deposits[_localToken][_remoteToken][_tokenId] = true;\n IERC721(_localToken).transferFrom(_from, address(this), _tokenId);\n\n // Send calldata into L2\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L1/L1StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1StandardBridge\n * @notice The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L1, it will be escrowed within this\n * contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was\n * stored within this contract. After Bedrock, ETH is instead stored inside the\n * OptimismPortal contract.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L1StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated.\n *\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of ETH deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ETHDepositInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized.\n *\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of ETH withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 withdrawal is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _messenger Address of the L1CrossDomainMessenger.\n */\n constructor(address payable _messenger)\n Semver(1, 1, 0)\n StandardBridge(_messenger, payable(Predeploys.L2_STANDARD_BRIDGE))\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into the sender's account on L2.\n *\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETH(uint32 _minGasLimit, bytes calldata _extraData) external payable onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into a target account on L2.\n * Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will\n * be locked in the L2StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n *\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable {\n _initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into the sender's account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20(\n address _l1Token,\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual onlyEOA {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into a target account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20To(\n address _l1Token,\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ETH from L2.\n *\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of ETH to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeETHWithdrawal(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ERC20 tokens from L2.\n *\n * @param _l1Token Address of the token on L1.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of the ERC20 to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeERC20Withdrawal(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external {\n finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L2 bridge contract.\n *\n * @return Address of the corresponding L2 bridge contract.\n */\n function l2TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @notice Internal function for initiating an ETH deposit.\n *\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateETHDeposit(\n address _from,\n address _to,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Internal function for initiating an ERC20 deposit.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateERC20Deposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHDepositInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHDepositInitiated(_from, _to, _amount, _extraData);\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHWithdrawalFinalized event followed by the ETHBridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData);\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20DepositInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20DepositInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20WithdrawalFinalized event followed by the ERC20BridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20WithdrawalFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L1/L2OutputOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\n/**\n * @custom:proxied\n * @title L2OutputOracle\n * @notice The L2OutputOracle contains an array of L2 state outputs, where each output is a\n * commitment to the state of the L2 chain. Other contracts like the OptimismPortal use\n * these outputs to verify information about the state of L2.\n */\ncontract L2OutputOracle is Initializable, Semver {\n /**\n * @notice The interval in L2 blocks at which checkpoints must be submitted. Although this is\n * immutable, it can safely be modified by upgrading the implementation contract.\n */\n uint256 public immutable SUBMISSION_INTERVAL;\n\n /**\n * @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified.\n */\n uint256 public immutable L2_BLOCK_TIME;\n\n /**\n * @notice The address of the challenger. Can be updated via upgrade.\n */\n address public immutable CHALLENGER;\n\n /**\n * @notice The address of the proposer. Can be updated via upgrade.\n */\n address public immutable PROPOSER;\n\n /**\n * @notice Minimum time (in seconds) that must elapse before a withdrawal can be finalized.\n */\n uint256 public immutable FINALIZATION_PERIOD_SECONDS;\n\n /**\n * @notice The number of the first L2 block recorded in this contract.\n */\n uint256 public startingBlockNumber;\n\n /**\n * @notice The timestamp of the first L2 block recorded in this contract.\n */\n uint256 public startingTimestamp;\n\n /**\n * @notice Array of L2 output proposals.\n */\n Types.OutputProposal[] internal l2Outputs;\n\n /**\n * @notice Emitted when an output is proposed.\n *\n * @param outputRoot The output root.\n * @param l2OutputIndex The index of the output in the l2Outputs array.\n * @param l2BlockNumber The L2 block number of the output root.\n * @param l1Timestamp The L1 timestamp when proposed.\n */\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n /**\n * @notice Emitted when outputs are deleted.\n *\n * @param prevNextOutputIndex Next L2 output index before the deletion.\n * @param newNextOutputIndex Next L2 output index after the deletion.\n */\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n /**\n * @custom:semver 1.2.0\n *\n * @param _submissionInterval Interval in blocks at which checkpoints must be submitted.\n * @param _l2BlockTime The time per L2 block, in seconds.\n * @param _startingBlockNumber The number of the first L2 block.\n * @param _startingTimestamp The timestamp of the first L2 block.\n * @param _proposer The address of the proposer.\n * @param _challenger The address of the challenger.\n */\n constructor(\n uint256 _submissionInterval,\n uint256 _l2BlockTime,\n uint256 _startingBlockNumber,\n uint256 _startingTimestamp,\n address _proposer,\n address _challenger,\n uint256 _finalizationPeriodSeconds\n ) Semver(1, 2, 0) {\n require(_l2BlockTime > 0, \"L2OutputOracle: L2 block time must be greater than 0\");\n require(\n _submissionInterval > _l2BlockTime,\n \"L2OutputOracle: submission interval must be greater than L2 block time\"\n );\n\n SUBMISSION_INTERVAL = _submissionInterval;\n L2_BLOCK_TIME = _l2BlockTime;\n PROPOSER = _proposer;\n CHALLENGER = _challenger;\n FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;\n\n initialize(_startingBlockNumber, _startingTimestamp);\n }\n\n /**\n * @notice Initializer.\n *\n * @param _startingBlockNumber Block number for the first recoded L2 block.\n * @param _startingTimestamp Timestamp for the first recoded L2 block.\n */\n function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp)\n public\n initializer\n {\n require(\n _startingTimestamp <= block.timestamp,\n \"L2OutputOracle: starting L2 timestamp must be less than current time\"\n );\n\n startingTimestamp = _startingTimestamp;\n startingBlockNumber = _startingBlockNumber;\n }\n\n /**\n * @notice Deletes all output proposals after and including the proposal that corresponds to\n * the given output index. Only the challenger address can delete outputs.\n *\n * @param _l2OutputIndex Index of the first L2 output to be deleted. All outputs after this\n * output will also be deleted.\n */\n // solhint-disable-next-line ordering\n function deleteL2Outputs(uint256 _l2OutputIndex) external {\n require(\n msg.sender == CHALLENGER,\n \"L2OutputOracle: only the challenger address can delete outputs\"\n );\n\n // Make sure we're not *increasing* the length of the array.\n require(\n _l2OutputIndex < l2Outputs.length,\n \"L2OutputOracle: cannot delete outputs after the latest output index\"\n );\n\n // Do not allow deleting any outputs that have already been finalized.\n require(\n block.timestamp - l2Outputs[_l2OutputIndex].timestamp < FINALIZATION_PERIOD_SECONDS,\n \"L2OutputOracle: cannot delete outputs that have already been finalized\"\n );\n\n uint256 prevNextL2OutputIndex = nextOutputIndex();\n\n // Use assembly to delete the array elements because Solidity doesn't allow it.\n assembly {\n sstore(l2Outputs.slot, _l2OutputIndex)\n }\n\n emit OutputsDeleted(prevNextL2OutputIndex, _l2OutputIndex);\n }\n\n /**\n * @notice Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp\n * must be equal to the current value returned by `nextTimestamp()` in order to be\n * accepted. This function may only be called by the Proposer.\n *\n * @param _outputRoot The L2 output of the checkpoint block.\n * @param _l2BlockNumber The L2 block number that resulted in _outputRoot.\n * @param _l1BlockHash A block hash which must be included in the current chain.\n * @param _l1BlockNumber The block number with the specified block hash.\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external payable {\n require(\n msg.sender == PROPOSER,\n \"L2OutputOracle: only the proposer address can propose new outputs\"\n );\n\n require(\n _l2BlockNumber == nextBlockNumber(),\n \"L2OutputOracle: block number must be equal to next expected block number\"\n );\n\n require(\n computeL2Timestamp(_l2BlockNumber) < block.timestamp,\n \"L2OutputOracle: cannot propose L2 output in the future\"\n );\n\n require(\n _outputRoot != bytes32(0),\n \"L2OutputOracle: L2 output proposal cannot be the zero hash\"\n );\n\n if (_l1BlockHash != bytes32(0)) {\n // This check allows the proposer to propose an output based on a given L1 block,\n // without fear that it will be reorged out.\n // It will also revert if the blockheight provided is more than 256 blocks behind the\n // chain tip (as the hash will return as zero). This does open the door to a griefing\n // attack in which the proposer's submission is censored until the block is no longer\n // retrievable, if the proposer is experiencing this attack it can simply leave out the\n // blockhash value, and delay submission until it is confident that the L1 block is\n // finalized.\n require(\n blockhash(_l1BlockNumber) == _l1BlockHash,\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n }\n\n emit OutputProposed(_outputRoot, nextOutputIndex(), _l2BlockNumber, block.timestamp);\n\n l2Outputs.push(\n Types.OutputProposal({\n outputRoot: _outputRoot,\n timestamp: uint128(block.timestamp),\n l2BlockNumber: uint128(_l2BlockNumber)\n })\n );\n }\n\n /**\n * @notice Returns an output by index. Exists because Solidity's array access will return a\n * tuple instead of a struct.\n *\n * @param _l2OutputIndex Index of the output to return.\n *\n * @return The output at the given index.\n */\n function getL2Output(uint256 _l2OutputIndex)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[_l2OutputIndex];\n }\n\n /**\n * @notice Returns the index of the L2 output that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return Index of the first checkpoint that commits to the given L2 block number.\n */\n function getL2OutputIndexAfter(uint256 _l2BlockNumber) public view returns (uint256) {\n // Make sure an output for this block number has actually been proposed.\n require(\n _l2BlockNumber <= latestBlockNumber(),\n \"L2OutputOracle: cannot get output for a block that has not been proposed\"\n );\n\n // Make sure there's at least one output proposed.\n require(\n l2Outputs.length > 0,\n \"L2OutputOracle: cannot get output as no outputs have been proposed yet\"\n );\n\n // Find the output via binary search, guaranteed to exist.\n uint256 lo = 0;\n uint256 hi = l2Outputs.length;\n while (lo < hi) {\n uint256 mid = (lo + hi) / 2;\n if (l2Outputs[mid].l2BlockNumber < _l2BlockNumber) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n return lo;\n }\n\n /**\n * @notice Returns the L2 output proposal that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return First checkpoint that commits to the given L2 block number.\n */\n function getL2OutputAfter(uint256 _l2BlockNumber)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)];\n }\n\n /**\n * @notice Returns the number of outputs that have been proposed. Will revert if no outputs\n * have been proposed yet.\n *\n * @return The number of outputs that have been proposed.\n */\n function latestOutputIndex() external view returns (uint256) {\n return l2Outputs.length - 1;\n }\n\n /**\n * @notice Returns the index of the next output to be proposed.\n *\n * @return The index of the next output to be proposed.\n */\n function nextOutputIndex() public view returns (uint256) {\n return l2Outputs.length;\n }\n\n /**\n * @notice Returns the block number of the latest submitted L2 output proposal. If no proposals\n * been submitted yet then this function will return the starting block number.\n *\n * @return Latest submitted L2 block number.\n */\n function latestBlockNumber() public view returns (uint256) {\n return\n l2Outputs.length == 0\n ? startingBlockNumber\n : l2Outputs[l2Outputs.length - 1].l2BlockNumber;\n }\n\n /**\n * @notice Computes the block number of the next L2 block that needs to be checkpointed.\n *\n * @return Next L2 block number.\n */\n function nextBlockNumber() public view returns (uint256) {\n return latestBlockNumber() + SUBMISSION_INTERVAL;\n }\n\n /**\n * @notice Returns the L2 timestamp corresponding to a given L2 block number.\n *\n * @param _l2BlockNumber The L2 block number of the target block.\n *\n * @return L2 timestamp of the given block.\n */\n function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {\n return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME);\n }\n}\n" - }, - "contracts/L1/OptimismPortal.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { L2OutputOracle } from \"./L2OutputOracle.sol\";\nimport { SystemConfig } from \"./SystemConfig.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { SecureMerkleTrie } from \"../libraries/trie/SecureMerkleTrie.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title OptimismPortal\n * @notice The OptimismPortal is a low-level contract responsible for passing messages between L1\n * and L2. Messages sent directly to the OptimismPortal have no form of replayability.\n * Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface.\n */\ncontract OptimismPortal is Initializable, ResourceMetering, Semver {\n /**\n * @notice Represents a proven withdrawal.\n *\n * @custom:field outputRoot Root of the L2 output this was proven against.\n * @custom:field timestamp Timestamp at whcih the withdrawal was proven.\n * @custom:field l2OutputIndex Index of the output this was proven against.\n */\n struct ProvenWithdrawal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2OutputIndex;\n }\n\n /**\n * @notice Version of the deposit event.\n */\n uint256 internal constant DEPOSIT_VERSION = 0;\n\n /**\n * @notice The L2 gas limit set when eth is deposited using the receive() function.\n */\n uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Address of the L2OutputOracle contract.\n */\n L2OutputOracle public immutable L2_ORACLE;\n\n /**\n * @notice Address of the SystemConfig contract.\n */\n SystemConfig public immutable SYSTEM_CONFIG;\n\n /**\n * @notice Address that has the ability to pause and unpause withdrawals.\n */\n address public immutable GUARDIAN;\n\n /**\n * @notice Address of the L2 account which initiated a withdrawal in this transaction. If the\n * of this variable is the default L2 sender address, then we are NOT inside of a call\n * to finalizeWithdrawalTransaction.\n */\n address public l2Sender;\n\n /**\n * @notice A list of withdrawal hashes which have been successfully finalized.\n */\n mapping(bytes32 => bool) public finalizedWithdrawals;\n\n /**\n * @notice A mapping of withdrawal hashes to `ProvenWithdrawal` data.\n */\n mapping(bytes32 => ProvenWithdrawal) public provenWithdrawals;\n\n /**\n * @notice Determines if cross domain messaging is paused. When set to true,\n * deposits and withdrawals are paused. This may be removed in the\n * future.\n */\n bool public paused;\n\n /**\n * @notice Emitted when a transaction is deposited from L1 to L2. The parameters of this event\n * are read by the rollup node and used to derive deposit transactions on L2.\n *\n * @param from Address that triggered the deposit transaction.\n * @param to Address that the deposit transaction is directed to.\n * @param version Version of this deposit transaction event.\n * @param opaqueData ABI encoded deposit data to be parsed off-chain.\n */\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is proven.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n */\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is finalized.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n * @param success Whether the withdrawal transaction was successful.\n */\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n\n /**\n * @notice Emitted when the pause is triggered.\n *\n * @param account Address of the account triggering the pause.\n */\n event Paused(address account);\n\n /**\n * @notice Emitted when the pause is lifted.\n *\n * @param account Address of the account triggering the unpause.\n */\n event Unpaused(address account);\n\n /**\n * @notice Reverts when paused.\n */\n modifier whenNotPaused() {\n require(paused == false, \"OptimismPortal: paused\");\n _;\n }\n\n /**\n * @custom:semver 1.3.0\n *\n * @param _l2Oracle Address of the L2OutputOracle contract.\n * @param _guardian Address that can pause deposits and withdrawals.\n * @param _paused Sets the contract's pausability state.\n * @param _config Address of the SystemConfig contract.\n */\n constructor(\n L2OutputOracle _l2Oracle,\n address _guardian,\n bool _paused,\n SystemConfig _config\n ) Semver(1, 3, 0) {\n L2_ORACLE = _l2Oracle;\n GUARDIAN = _guardian;\n SYSTEM_CONFIG = _config;\n initialize(_paused);\n }\n\n /**\n * @notice Initializer.\n */\n function initialize(bool _paused) public initializer {\n l2Sender = Constants.DEFAULT_L2_SENDER;\n paused = _paused;\n __ResourceMetering_init();\n }\n\n /**\n * @notice Pause deposits and withdrawals.\n */\n function pause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can pause\");\n paused = true;\n emit Paused(msg.sender);\n }\n\n /**\n * @notice Unpause deposits and withdrawals.\n */\n function unpause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can unpause\");\n paused = false;\n emit Unpaused(msg.sender);\n }\n\n /**\n * @notice Accepts value so that users can send ETH directly to this contract and have the\n * funds be deposited to their address on L2. This is intended as a convenience\n * function for EOAs. Contracts should call the depositTransaction() function directly\n * otherwise any deposited funds will be lost due to address aliasing.\n */\n // solhint-disable-next-line ordering\n receive() external payable {\n depositTransaction(msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes(\"\"));\n }\n\n /**\n * @notice Accepts ETH value without triggering a deposit to L2. This function mainly exists\n * for the sake of the migration between the legacy Optimism system and Bedrock.\n */\n function donateETH() external payable {\n // Intentionally empty.\n }\n\n /**\n * @notice Getter for the resource config. Used internally by the ResourceMetering\n * contract. The SystemConfig is the source of truth for the resource config.\n *\n * @return ResourceMetering.ResourceConfig\n */\n function _resourceConfig()\n internal\n view\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return SYSTEM_CONFIG.resourceConfig();\n }\n\n /**\n * @notice Proves a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n * @param _l2OutputIndex L2 output index to prove against.\n * @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root.\n * @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\n */\n function proveWithdrawalTransaction(\n Types.WithdrawalTransaction memory _tx,\n uint256 _l2OutputIndex,\n Types.OutputRootProof calldata _outputRootProof,\n bytes[] calldata _withdrawalProof\n ) external whenNotPaused {\n // Prevent users from creating a deposit transaction where this address is the message\n // sender on L2. Because this is checked here, we do not need to check again in\n // `finalizeWithdrawalTransaction`.\n require(\n _tx.target != address(this),\n \"OptimismPortal: you cannot send messages to the portal contract\"\n );\n\n // Get the output root and load onto the stack to prevent multiple mloads. This will\n // revert if there is no output root for the given block number.\n bytes32 outputRoot = L2_ORACLE.getL2Output(_l2OutputIndex).outputRoot;\n\n // Verify that the output root can be generated with the elements in the proof.\n require(\n outputRoot == Hashing.hashOutputRootProof(_outputRootProof),\n \"OptimismPortal: invalid output root proof\"\n );\n\n // Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // We generally want to prevent users from proving the same withdrawal multiple times\n // because each successive proof will update the timestamp. A malicious user can take\n // advantage of this to prevent other users from finalizing their withdrawal. However,\n // since withdrawals are proven before an output root is finalized, we need to allow users\n // to re-prove their withdrawal only in the case that the output root for their specified\n // output index has been updated.\n require(\n provenWithdrawal.timestamp == 0 ||\n L2_ORACLE.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot !=\n provenWithdrawal.outputRoot,\n \"OptimismPortal: withdrawal hash has already been proven\"\n );\n\n // Compute the storage slot of the withdrawal hash in the L2ToL1MessagePasser contract.\n // Refer to the Solidity documentation for more information on how storage layouts are\n // computed for mappings.\n bytes32 storageKey = keccak256(\n abi.encode(\n withdrawalHash,\n uint256(0) // The withdrawals mapping is at the first slot in the layout.\n )\n );\n\n // Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract\n // on L2. If this is true, under the assumption that the SecureMerkleTrie does not have\n // bugs, then we know that this withdrawal was actually triggered on L2 and can therefore\n // be relayed on L1.\n require(\n SecureMerkleTrie.verifyInclusionProof(\n abi.encode(storageKey),\n hex\"01\",\n _withdrawalProof,\n _outputRootProof.messagePasserStorageRoot\n ),\n \"OptimismPortal: invalid withdrawal inclusion proof\"\n );\n\n // Designate the withdrawalHash as proven by storing the `outputRoot`, `timestamp`, and\n // `l2BlockNumber` in the `provenWithdrawals` mapping. A `withdrawalHash` can only be\n // proven once unless it is submitted again with a different outputRoot.\n provenWithdrawals[withdrawalHash] = ProvenWithdrawal({\n outputRoot: outputRoot,\n timestamp: uint128(block.timestamp),\n l2OutputIndex: uint128(_l2OutputIndex)\n });\n\n // Emit a `WithdrawalProven` event.\n emit WithdrawalProven(withdrawalHash, _tx.sender, _tx.target);\n }\n\n /**\n * @notice Finalizes a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n */\n function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx)\n external\n whenNotPaused\n {\n // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other\n // than the default value when a withdrawal transaction is being finalized. This check is\n // a defacto reentrancy guard.\n require(\n l2Sender == Constants.DEFAULT_L2_SENDER,\n \"OptimismPortal: can only trigger one withdrawal per transaction\"\n );\n\n // Grab the proven withdrawal from the `provenWithdrawals` map.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // A withdrawal can only be finalized if it has been proven. We know that a withdrawal has\n // been proven at least once when its timestamp is non-zero. Unproven withdrawals will have\n // a timestamp of zero.\n require(\n provenWithdrawal.timestamp != 0,\n \"OptimismPortal: withdrawal has not been proven yet\"\n );\n\n // As a sanity check, we make sure that the proven withdrawal's timestamp is greater than\n // starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of\n // safety against weird bugs in the proving step.\n require(\n provenWithdrawal.timestamp >= L2_ORACLE.startingTimestamp(),\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n\n // A proven withdrawal must wait at least the finalization period before it can be\n // finalized. This waiting period can elapse in parallel with the waiting period for the\n // output the withdrawal was proven against. In effect, this means that the minimum\n // withdrawal time is proposal submission time + finalization period.\n require(\n _isFinalizationPeriodElapsed(provenWithdrawal.timestamp),\n \"OptimismPortal: proven withdrawal finalization period has not elapsed\"\n );\n\n // Grab the OutputProposal from the L2OutputOracle, will revert if the output that\n // corresponds to the given index has not been proposed yet.\n Types.OutputProposal memory proposal = L2_ORACLE.getL2Output(\n provenWithdrawal.l2OutputIndex\n );\n\n // Check that the output root that was used to prove the withdrawal is the same as the\n // current output root for the given output index. An output root may change if it is\n // deleted by the challenger address and then re-proposed.\n require(\n proposal.outputRoot == provenWithdrawal.outputRoot,\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n\n // Check that the output proposal has also been finalized.\n require(\n _isFinalizationPeriodElapsed(proposal.timestamp),\n \"OptimismPortal: output proposal finalization period has not elapsed\"\n );\n\n // Check that this withdrawal has not already been finalized, this is replay protection.\n require(\n finalizedWithdrawals[withdrawalHash] == false,\n \"OptimismPortal: withdrawal has already been finalized\"\n );\n\n // Mark the withdrawal as finalized so it can't be replayed.\n finalizedWithdrawals[withdrawalHash] = true;\n\n // Set the l2Sender so contracts know who triggered this withdrawal on L2.\n l2Sender = _tx.sender;\n\n // Trigger the call to the target contract. We use a custom low level method\n // SafeCall.callWithMinGas to ensure two key properties\n // 1. Target contracts cannot force this call to run out of gas by returning a very large\n // amount of data (and this is OK because we don't care about the returndata here).\n // 2. The amount of gas provided to the call to the target contract is at least the gas\n // limit specified by the user. If there is not enough gas in the callframe to\n // accomplish this, `callWithMinGas` will revert.\n // Additionally, if there is not enough gas remaining to complete the execution after the\n // call returns, this function will revert.\n bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data);\n\n // Reset the l2Sender back to the default value.\n l2Sender = Constants.DEFAULT_L2_SENDER;\n\n // All withdrawals are immediately finalized. Replayability can\n // be achieved through contracts built on top of this contract\n emit WithdrawalFinalized(withdrawalHash, success);\n\n // Reverting here is useful for determining the exact gas cost to successfully execute the\n // sub call to the target contract if the minimum gas limit specified by the user would not\n // be sufficient to execute the sub call.\n if (success == false && tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"OptimismPortal: withdrawal failed\");\n }\n }\n\n /**\n * @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in\n * deriving deposit transactions. Note that if a deposit is made by a contract, its\n * address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider\n * using the CrossDomainMessenger contracts for a simpler developer experience.\n *\n * @param _to Target address on L2.\n * @param _value ETH value to send to the recipient.\n * @param _gasLimit Minimum L2 gas limit (can be greater than or equal to this value).\n * @param _isCreation Whether or not the transaction is a contract creation.\n * @param _data Data to trigger the recipient with.\n */\n function depositTransaction(\n address _to,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable metered(_gasLimit) {\n // Just to be safe, make sure that people specify address(0) as the target when doing\n // contract creations.\n if (_isCreation) {\n require(\n _to == address(0),\n \"OptimismPortal: must send to address(0) when creating a contract\"\n );\n }\n\n // Prevent depositing transactions that have too small of a gas limit.\n require(_gasLimit >= 21_000, \"OptimismPortal: gas limit must cover instrinsic gas cost\");\n\n // Transform the from-address to its alias if the caller is a contract.\n address from = msg.sender;\n if (msg.sender != tx.origin) {\n from = AddressAliasHelper.applyL1ToL2Alias(msg.sender);\n }\n\n // Compute the opaque data that will be emitted as part of the TransactionDeposited event.\n // We use opaque data so that we can update the TransactionDeposited event in the future\n // without breaking the current interface.\n bytes memory opaqueData = abi.encodePacked(\n msg.value,\n _value,\n _gasLimit,\n _isCreation,\n _data\n );\n\n // Emit a TransactionDeposited event so that the rollup node can derive a deposit\n // transaction for this deposit.\n emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);\n }\n\n /**\n * @notice Determine if a given output is finalized. Reverts if the call to\n * L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\n *\n * @param _l2OutputIndex Index of the L2 output to check.\n *\n * @return Whether or not the output is finalized.\n */\n function isOutputFinalized(uint256 _l2OutputIndex) external view returns (bool) {\n return _isFinalizationPeriodElapsed(L2_ORACLE.getL2Output(_l2OutputIndex).timestamp);\n }\n\n /**\n * @notice Determines whether the finalization period has elapsed w/r/t a given timestamp.\n *\n * @param _timestamp Timestamp to check.\n *\n * @return Whether or not the finalization period has elapsed.\n */\n function _isFinalizationPeriodElapsed(uint256 _timestamp) internal view returns (bool) {\n return block.timestamp > _timestamp + L2_ORACLE.FINALIZATION_PERIOD_SECONDS();\n }\n}\n" - }, - "contracts/L1/ResourceMetering.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\n\n/**\n * @custom:upgradeable\n * @title ResourceMetering\n * @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing\n * updates automatically based on current demand.\n */\nabstract contract ResourceMetering is Initializable {\n /**\n * @notice Represents the various parameters that control the way in which resources are\n * metered. Corresponds to the EIP-1559 resource metering system.\n *\n * @custom:field prevBaseFee Base fee from the previous block(s).\n * @custom:field prevBoughtGas Amount of gas bought so far in the current block.\n * @custom:field prevBlockNum Last block number that the base fee was updated.\n */\n struct ResourceParams {\n uint128 prevBaseFee;\n uint64 prevBoughtGas;\n uint64 prevBlockNum;\n }\n\n /**\n * @notice Represents the configuration for the EIP-1559 based curve for the deposit gas\n * market. These values should be set with care as it is possible to set them in\n * a way that breaks the deposit gas market. The target resource limit is defined as\n * maxResourceLimit / elasticityMultiplier. This struct was designed to fit within a\n * single word. There is additional space for additions in the future.\n *\n * @custom:field maxResourceLimit Represents the maximum amount of deposit gas that\n * can be purchased per block.\n * @custom:field elasticityMultiplier Determines the target resource limit along with\n * the resource limit.\n * @custom:field baseFeeMaxChangeDenominator Determines max change on fee per block.\n * @custom:field minimumBaseFee The min deposit base fee, it is clamped to this\n * value.\n * @custom:field systemTxMaxGas The amount of gas supplied to the system\n * transaction. This should be set to the same number\n * that the op-node sets as the gas limit for the\n * system transaction.\n * @custom:field maximumBaseFee The max deposit base fee, it is clamped to this\n * value.\n */\n struct ResourceConfig {\n uint32 maxResourceLimit;\n uint8 elasticityMultiplier;\n uint8 baseFeeMaxChangeDenominator;\n uint32 minimumBaseFee;\n uint32 systemTxMaxGas;\n uint128 maximumBaseFee;\n }\n\n /**\n * @notice EIP-1559 style gas parameters.\n */\n ResourceParams public params;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[48] private __gap;\n\n /**\n * @notice Meters access to a function based an amount of a requested resource.\n *\n * @param _amount Amount of the resource requested.\n */\n modifier metered(uint64 _amount) {\n // Record initial gas amount so we can refund for it later.\n uint256 initialGas = gasleft();\n\n // Run the underlying function.\n _;\n\n // Run the metering function.\n _metered(_amount, initialGas);\n }\n\n /**\n * @notice An internal function that holds all of the logic for metering a resource.\n *\n * @param _amount Amount of the resource requested.\n * @param _initialGas The amount of gas before any modifier execution.\n */\n function _metered(uint64 _amount, uint256 _initialGas) internal {\n // Update block number and base fee if necessary.\n uint256 blockDiff = block.number - params.prevBlockNum;\n\n ResourceConfig memory config = _resourceConfig();\n int256 targetResourceLimit = int256(uint256(config.maxResourceLimit)) /\n int256(uint256(config.elasticityMultiplier));\n\n if (blockDiff > 0) {\n // Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate\n // at which deposits can be created and therefore limit the potential for deposits to\n // spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.\n int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit;\n int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) /\n (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));\n\n // Update base fee by adding the base fee delta and clamp the resulting value between\n // min and max.\n int256 newBaseFee = Arithmetic.clamp({\n _value: int256(uint256(params.prevBaseFee)) + baseFeeDelta,\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n\n // If we skipped more than one block, we also need to account for every empty block.\n // Empty block means there was no demand for deposits in that block, so we should\n // reflect this lack of demand in the fee.\n if (blockDiff > 1) {\n // Update the base fee by repeatedly applying the exponent 1-(1/change_denominator)\n // blockDiff - 1 times. Simulates multiple empty blocks. Clamp the resulting value\n // between min and max.\n newBaseFee = Arithmetic.clamp({\n _value: Arithmetic.cdexp({\n _coefficient: newBaseFee,\n _denominator: int256(uint256(config.baseFeeMaxChangeDenominator)),\n _exponent: int256(blockDiff - 1)\n }),\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n }\n\n // Update new base fee, reset bought gas, and update block number.\n params.prevBaseFee = uint128(uint256(newBaseFee));\n params.prevBoughtGas = 0;\n params.prevBlockNum = uint64(block.number);\n }\n\n // Make sure we can actually buy the resource amount requested by the user.\n params.prevBoughtGas += _amount;\n require(\n int256(uint256(params.prevBoughtGas)) <= int256(uint256(config.maxResourceLimit)),\n \"ResourceMetering: cannot buy more gas than available gas limit\"\n );\n\n // Determine the amount of ETH to be paid.\n uint256 resourceCost = uint256(_amount) * uint256(params.prevBaseFee);\n\n // We currently charge for this ETH amount as an L1 gas burn, so we convert the ETH amount\n // into gas by dividing by the L1 base fee. We assume a minimum base fee of 1 gwei to avoid\n // division by zero for L1s that don't support 1559 or to avoid excessive gas burns during\n // periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei\n // during any 1 day period in the last 5 years, so should be fine.\n uint256 gasCost = resourceCost / Math.max(block.basefee, 1 gwei);\n\n // Give the user a refund based on the amount of gas they used to do all of the work up to\n // this point. Since we're at the end of the modifier, this should be pretty accurate. Acts\n // effectively like a dynamic stipend (with a minimum value).\n uint256 usedGas = _initialGas - gasleft();\n if (gasCost > usedGas) {\n Burn.gas(gasCost - usedGas);\n }\n }\n\n /**\n * @notice Virtual function that returns the resource config. Contracts that inherit this\n * contract must implement this function.\n *\n * @return ResourceConfig\n */\n function _resourceConfig() internal virtual returns (ResourceConfig memory);\n\n /**\n * @notice Sets initial resource parameter values. This function must either be called by the\n * initializer function of an upgradeable child contract.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __ResourceMetering_init() internal onlyInitializing {\n params = ResourceParams({\n prevBaseFee: 1 gwei,\n prevBoughtGas: 0,\n prevBlockNum: uint64(block.number)\n });\n }\n}\n" - }, - "contracts/L1/SystemConfig.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\n\n/**\n * @title SystemConfig\n * @notice The SystemConfig contract is used to manage configuration of an Optimism network. All\n * configuration is stored on L1 and picked up by L2 as part of the derviation of the L2\n * chain.\n */\ncontract SystemConfig is OwnableUpgradeable, Semver {\n /**\n * @notice Enum representing different types of updates.\n *\n * @custom:value BATCHER Represents an update to the batcher hash.\n * @custom:value GAS_CONFIG Represents an update to txn fee config on L2.\n * @custom:value GAS_LIMIT Represents an update to gas limit on L2.\n * @custom:value UNSAFE_BLOCK_SIGNER Represents an update to the signer key for unsafe\n * block distrubution.\n */\n enum UpdateType {\n BATCHER,\n GAS_CONFIG,\n GAS_LIMIT,\n UNSAFE_BLOCK_SIGNER\n }\n\n /**\n * @notice Version identifier, used for upgrades.\n */\n uint256 public constant VERSION = 0;\n\n /**\n * @notice Storage slot that the unsafe block signer is stored at. Storing it at this\n * deterministic storage slot allows for decoupling the storage layout from the way\n * that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value.\n */\n bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256(\"systemconfig.unsafeblocksigner\");\n\n /**\n * @notice Minimum gas limit. This should not be lower than the maximum deposit gas resource\n * limit in the ResourceMetering contract used by OptimismPortal, to ensure the L2\n * block always has sufficient gas to process deposits.\n */\n uint64 public constant MINIMUM_GAS_LIMIT = 8_000_000;\n\n /**\n * @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public overhead;\n\n /**\n * @notice Dynamic L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public scalar;\n\n /**\n * @notice Identifier for the batcher. For version 1 of this configuration, this is represented\n * as an address left-padded with zeros to 32 bytes.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice L2 block gas limit.\n */\n uint64 public gasLimit;\n\n /**\n * @notice The configuration for the deposit fee market. Used by the OptimismPortal\n * to meter the cost of buying L2 gas on L1. Set as internal and wrapped with a getter\n * so that the struct is returned instead of a tuple.\n */\n ResourceMetering.ResourceConfig internal _resourceConfig;\n\n /**\n * @notice Emitted when configuration is updated\n *\n * @param version SystemConfig version.\n * @param updateType Type of update.\n * @param data Encoded update data.\n */\n event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial resource config.\n */\n constructor(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) Semver(1, 1, 0) {\n initialize({\n _owner: _owner,\n _overhead: _overhead,\n _scalar: _scalar,\n _batcherHash: _batcherHash,\n _gasLimit: _gasLimit,\n _unsafeBlockSigner: _unsafeBlockSigner,\n _config: _config\n });\n }\n\n /**\n * @notice Initializer. The resource config must be set before the\n * require check.\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial ResourceConfig.\n */\n function initialize(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) public initializer {\n __Ownable_init();\n transferOwnership(_owner);\n overhead = _overhead;\n scalar = _scalar;\n batcherHash = _batcherHash;\n gasLimit = _gasLimit;\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n _setResourceConfig(_config);\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n }\n\n /**\n * @notice Returns the minimum L2 gas limit that can be safely set for the system to\n * operate. The L2 gas limit must be larger than or equal to the amount of\n * gas that is allocated for deposits per block plus the amount of gas that\n * is allocated for the system transaction.\n * This function is used to determine if changes to parameters are safe.\n *\n * @return uint64\n */\n function minimumGasLimit() public view returns (uint64) {\n return uint64(_resourceConfig.maxResourceLimit) + uint64(_resourceConfig.systemTxMaxGas);\n }\n\n /**\n * @notice High level getter for the unsafe block signer address. Unsafe blocks can be\n * propagated across the p2p network if they are signed by the key corresponding to\n * this address.\n *\n * @return Address of the unsafe block signer.\n */\n // solhint-disable-next-line ordering\n function unsafeBlockSigner() external view returns (address) {\n address addr;\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n addr := sload(slot)\n }\n return addr;\n }\n\n /**\n * @notice Updates the unsafe block signer address.\n *\n * @param _unsafeBlockSigner New unsafe block signer address.\n */\n function setUnsafeBlockSigner(address _unsafeBlockSigner) external onlyOwner {\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n\n bytes memory data = abi.encode(_unsafeBlockSigner);\n emit ConfigUpdate(VERSION, UpdateType.UNSAFE_BLOCK_SIGNER, data);\n }\n\n /**\n * @notice Updates the batcher hash.\n *\n * @param _batcherHash New batcher hash.\n */\n function setBatcherHash(bytes32 _batcherHash) external onlyOwner {\n batcherHash = _batcherHash;\n\n bytes memory data = abi.encode(_batcherHash);\n emit ConfigUpdate(VERSION, UpdateType.BATCHER, data);\n }\n\n /**\n * @notice Updates gas config.\n *\n * @param _overhead New overhead value.\n * @param _scalar New scalar value.\n */\n function setGasConfig(uint256 _overhead, uint256 _scalar) external onlyOwner {\n overhead = _overhead;\n scalar = _scalar;\n\n bytes memory data = abi.encode(_overhead, _scalar);\n emit ConfigUpdate(VERSION, UpdateType.GAS_CONFIG, data);\n }\n\n /**\n * @notice Updates the L2 gas limit.\n *\n * @param _gasLimit New gas limit.\n */\n function setGasLimit(uint64 _gasLimit) external onlyOwner {\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n gasLimit = _gasLimit;\n\n bytes memory data = abi.encode(_gasLimit);\n emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data);\n }\n\n /**\n * @notice Low level setter for the unsafe block signer address. This function exists to\n * deduplicate code around storing the unsafeBlockSigner address in storage.\n *\n * @param _unsafeBlockSigner New unsafeBlockSigner value.\n */\n function _setUnsafeBlockSigner(address _unsafeBlockSigner) internal {\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n sstore(slot, _unsafeBlockSigner)\n }\n }\n\n /**\n * @notice A getter for the resource config. Ensures that the struct is\n * returned instead of a tuple.\n *\n * @return ResourceConfig\n */\n function resourceConfig() external view returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig;\n }\n\n /**\n * @notice An external setter for the resource config. In the future, this\n * method may emit an event that the `op-node` picks up for when the\n * resource config is changed.\n *\n * @param _config The new resource config values.\n */\n function setResourceConfig(ResourceMetering.ResourceConfig memory _config) external onlyOwner {\n _setResourceConfig(_config);\n }\n\n /**\n * @notice An internal setter for the resource config. Ensures that the\n * config is sane before storing it by checking for invariants.\n *\n * @param _config The new resource config.\n */\n function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal {\n // Min base fee must be less than or equal to max base fee.\n require(\n _config.minimumBaseFee <= _config.maximumBaseFee,\n \"SystemConfig: min base fee must be less than max base\"\n );\n // Base fee change denominator must be greater than 0.\n require(_config.baseFeeMaxChangeDenominator > 0, \"SystemConfig: denominator cannot be 0\");\n // Max resource limit plus system tx gas must be less than or equal to the L2 gas limit.\n // The gas limit must be increased before these values can be increased.\n require(\n _config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit,\n \"SystemConfig: gas limit too low\"\n );\n // Elasticity multiplier must be greater than 0.\n require(\n _config.elasticityMultiplier > 0,\n \"SystemConfig: elasticity multiplier cannot be 0\"\n );\n // No precision loss when computing target resource limit.\n require(\n ((_config.maxResourceLimit / _config.elasticityMultiplier) *\n _config.elasticityMultiplier) == _config.maxResourceLimit,\n \"SystemConfig: precision loss with target resource limit\"\n );\n\n _resourceConfig = _config;\n }\n}\n" - }, - "contracts/L2/BaseFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000019\n * @title BaseFeeVault\n * @notice The BaseFeeVault accumulates the base fee that is paid by transactions.\n */\ncontract BaseFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 0, 0) {}\n}\n" - }, - "contracts/L2/CrossDomainOwnable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\n/**\n * @title CrossDomainOwnable\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is only safe to be used if the\n * CrossDomainMessenger system is bypassed and the caller on L1 is calling the\n * OptimismPortal directly.\n */\nabstract contract CrossDomainOwnable is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `msg.sender` is the owner of the contract.\n */\n function _checkOwner() internal view override {\n require(\n owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender),\n \"CrossDomainOwnable: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable2\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is meant to be used with systems that use\n * the CrossDomainMessenger system. It will not work if the OptimismPortal is used\n * directly.\n */\nabstract contract CrossDomainOwnable2 is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable2: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable2: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable3\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on either L1 or L2. Note that this contract is meant to be used with systems\n * that use the CrossDomainMessenger system. It will not work if the OptimismPortal is\n * used directly.\n */\nabstract contract CrossDomainOwnable3 is Ownable {\n /**\n * @notice If true, the contract uses the cross domain _checkOwner function override. If false\n * it uses the standard Ownable _checkOwner function.\n */\n bool public isLocal = true;\n\n /**\n * @notice Emits when ownership of the contract is transferred. Includes the\n * isLocal field in addition to the standard `Ownable` OwnershipTransferred event.\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n /**\n * @notice Allows for ownership to be transferred with specifying the locality.\n * @param _owner The new owner of the contract.\n * @param _isLocal Configures the locality of the ownership.\n */\n function transferOwnership(address _owner, bool _isLocal) external onlyOwner {\n require(_owner != address(0), \"CrossDomainOwnable3: new owner is the zero address\");\n\n address oldOwner = owner();\n _transferOwnership(_owner);\n isLocal = _isLocal;\n\n emit OwnershipTransferred(oldOwner, _owner, _isLocal);\n }\n\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n if (isLocal) {\n require(owner() == msg.sender, \"CrossDomainOwnable3: caller is not the owner\");\n } else {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable3: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable3: caller is not the owner\"\n );\n }\n }\n}\n" - }, - "contracts/L2/GasPriceOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000000F\n * @title GasPriceOracle\n * @notice This contract maintains the variables responsible for computing the L1 portion of the\n * total fee charged on L2. Before Bedrock, this contract held variables in state that were\n * read during the state transition function to compute the L1 portion of the transaction\n * fee. After Bedrock, this contract now simply proxies the L1Block contract, which has\n * the values used to compute the L1 portion of the fee in its state.\n *\n * The contract exposes an API that is useful for knowing how large the L1 portion of the\n * transaction fee will be. The following events were deprecated with Bedrock:\n * - event OverheadUpdated(uint256 overhead);\n * - event ScalarUpdated(uint256 scalar);\n * - event DecimalsUpdated(uint256 decimals);\n */\ncontract GasPriceOracle is Semver {\n /**\n * @notice Number of decimals used in the scalar.\n */\n uint256 public constant DECIMALS = 6;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Computes the L1 portion of the fee based on the size of the rlp encoded input\n * transaction, the current L1 base fee, and the various dynamic parameters.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.\n *\n * @return L1 fee that should be paid for the tx\n */\n function getL1Fee(bytes memory _data) external view returns (uint256) {\n uint256 l1GasUsed = getL1GasUsed(_data);\n uint256 l1Fee = l1GasUsed * l1BaseFee();\n uint256 divisor = 10**DECIMALS;\n uint256 unscaled = l1Fee * scalar();\n uint256 scaled = unscaled / divisor;\n return scaled;\n }\n\n /**\n * @notice Retrieves the current gas price (base fee).\n *\n * @return Current L2 gas price (base fee).\n */\n function gasPrice() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current base fee.\n *\n * @return Current L2 base fee.\n */\n function baseFee() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current fee overhead.\n *\n * @return Current fee overhead.\n */\n function overhead() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead();\n }\n\n /**\n * @notice Retrieves the current fee scalar.\n *\n * @return Current fee scalar.\n */\n function scalar() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar();\n }\n\n /**\n * @notice Retrieves the latest known L1 base fee.\n *\n * @return Latest known L1 base fee.\n */\n function l1BaseFee() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee();\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the number of decimals used in the scalar.\n *\n * @return Number of decimals used in the scalar.\n */\n function decimals() public pure returns (uint256) {\n return DECIMALS;\n }\n\n /**\n * @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which\n * represents the per-transaction gas overhead of posting the transaction and state\n * roots to L1. Adds 68 bytes of padding to account for the fact that the input does\n * not have a signature.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for.\n *\n * @return Amount of L1 gas used to publish the transaction.\n */\n function getL1GasUsed(bytes memory _data) public view returns (uint256) {\n uint256 total = 0;\n uint256 length = _data.length;\n for (uint256 i = 0; i < length; i++) {\n if (_data[i] == 0) {\n total += 4;\n } else {\n total += 16;\n }\n }\n uint256 unsigned = total + overhead();\n return unsigned + (68 * 16);\n }\n}\n" - }, - "contracts/L2/L1Block.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000015\n * @title L1Block\n * @notice The L1Block predeploy gives users access to information about the last known L1 block.\n * Values within this contract are updated once per epoch (every L1 block) and can only be\n * set by the \"depositor\" account, a special system address. Depositor account transactions\n * are created by the protocol whenever we move to a new epoch.\n */\ncontract L1Block is Semver {\n /**\n * @notice Address of the special depositor account.\n */\n address public constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001;\n\n /**\n * @notice The latest L1 block number known by the L2 system.\n */\n uint64 public number;\n\n /**\n * @notice The latest L1 timestamp known by the L2 system.\n */\n uint64 public timestamp;\n\n /**\n * @notice The latest L1 basefee.\n */\n uint256 public basefee;\n\n /**\n * @notice The latest L1 blockhash.\n */\n bytes32 public hash;\n\n /**\n * @notice The number of L2 blocks in the same epoch.\n */\n uint64 public sequenceNumber;\n\n /**\n * @notice The versioned hash to authenticate the batcher by.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice The overhead value applied to the L1 portion of the transaction\n * fee.\n */\n uint256 public l1FeeOverhead;\n\n /**\n * @notice The scalar value applied to the L1 portion of the transaction fee.\n */\n uint256 public l1FeeScalar;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Updates the L1 block values.\n *\n * @param _number L1 blocknumber.\n * @param _timestamp L1 timestamp.\n * @param _basefee L1 basefee.\n * @param _hash L1 blockhash.\n * @param _sequenceNumber Number of L2 blocks since epoch start.\n * @param _batcherHash Versioned hash to authenticate batcher by.\n * @param _l1FeeOverhead L1 fee overhead.\n * @param _l1FeeScalar L1 fee scalar.\n */\n function setL1BlockValues(\n uint64 _number,\n uint64 _timestamp,\n uint256 _basefee,\n bytes32 _hash,\n uint64 _sequenceNumber,\n bytes32 _batcherHash,\n uint256 _l1FeeOverhead,\n uint256 _l1FeeScalar\n ) external {\n require(\n msg.sender == DEPOSITOR_ACCOUNT,\n \"L1Block: only the depositor account can set L1 block values\"\n );\n\n number = _number;\n timestamp = _timestamp;\n basefee = _basefee;\n hash = _hash;\n sequenceNumber = _sequenceNumber;\n batcherHash = _batcherHash;\n l1FeeOverhead = _l1FeeOverhead;\n l1FeeScalar = _l1FeeScalar;\n }\n}\n" - }, - "contracts/L2/L1FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000001A\n * @title L1FeeVault\n * @notice The L1FeeVault accumulates the L1 portion of the transaction fees.\n */\ncontract L1FeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 0, 0) {}\n}\n" - }, - "contracts/L2/L2CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { L2ToL1MessagePasser } from \"./L2ToL1MessagePasser.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000007\n * @title L2CrossDomainMessenger\n * @notice The L2CrossDomainMessenger is a high-level interface for message passing between L1 and\n * L2 on the L2 side. Users are generally encouraged to use this contract instead of lower\n * level message passing contracts.\n */\ncontract L2CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.\n */\n constructor(address _l1CrossDomainMessenger)\n Semver(1, 1, 0)\n CrossDomainMessenger(_l1CrossDomainMessenger)\n {\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote messenger. Use otherMessenger going forward.\n *\n * @return Address of the L1CrossDomainMessenger contract.\n */\n function l1CrossDomainMessenger() public view returns (address) {\n return OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{\n value: _value\n }(_to, _gasLimit, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(Predeploys.L2_TO_L1_MESSAGE_PASSER);\n }\n}\n" - }, - "contracts/L2/L2ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { IOptimismMintableERC721 } from \"../universal/IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L2ERC721Bridge\n * @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.\n * This contract also acts as a burner for tokens being withdrawn.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n */\ncontract L2ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L1. Data supplied here will not be used to\n * execute any code on L1 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L2ERC721Bridge: local token cannot be self\");\n\n // Note that supportsInterface makes a callback to the _localToken address which is user\n // provided.\n require(\n ERC165Checker.supportsInterface(_localToken, type(IOptimismMintableERC721).interfaceId),\n \"L2ERC721Bridge: local token interface is not compliant\"\n );\n\n require(\n _remoteToken == IOptimismMintableERC721(_localToken).remoteToken(),\n \"L2ERC721Bridge: wrong remote token for Optimism Mintable ERC721 local token\"\n );\n\n // When a deposit is finalized, we give the NFT with the same tokenId to the account\n // on L2. Note that safeMint makes a callback to the _to address which is user provided.\n IOptimismMintableERC721(_localToken).safeMint(_to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L2ERC721Bridge: remote token cannot be address(0)\");\n\n // Check that the withdrawal is being initiated by the NFT owner\n require(\n _from == IOptimismMintableERC721(_localToken).ownerOf(_tokenId),\n \"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\"\n );\n\n // Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)\n // slither-disable-next-line reentrancy-events\n address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();\n require(\n remoteToken == _remoteToken,\n \"L2ERC721Bridge: remote token does not match given value\"\n );\n\n // When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2\n // usage\n // slither-disable-next-line reentrancy-events\n IOptimismMintableERC721(_localToken).burn(_from, _tokenId);\n\n bytes memory message = abi.encodeWithSelector(\n L1ERC721Bridge.finalizeBridgeERC721.selector,\n remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Send message to L1 bridge\n // slither-disable-next-line reentrancy-events\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L2/L2StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000010\n * @title L2StandardBridge\n * @notice The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L2, it will be escrowed within this\n * contract. If the ERC20 token is native to L1, it will be burnt.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L2StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal from L2 to L1 is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _otherBridge Address of the L1StandardBridge.\n */\n constructor(address payable _otherBridge)\n Semver(1, 1, 0)\n StandardBridge(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER), _otherBridge)\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateWithdrawal(\n Predeploys.LEGACY_ERC20_ETH,\n msg.sender,\n msg.sender,\n msg.value,\n RECEIVE_DEFAULT_GAS_LIMIT,\n bytes(\"\")\n );\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdraw(\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual onlyEOA {\n _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1 to a target account on L1.\n * Note that if ETH is sent to a contract on L1 and the call fails, then that ETH will\n * be locked in the L1StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20To` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdrawTo(\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual {\n _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a deposit from L1 to L2. To finalize a deposit of ether, use address(0)\n * and the l1Token and the Legacy ERC20 ether predeploy address as the l2Token.\n *\n * @param _l1Token Address of the L1 token to deposit.\n * @param _l2Token Address of the corresponding L2 token.\n * @param _from Address of the depositor.\n * @param _to Address of the recipient.\n * @param _amount Amount of the tokens being deposited.\n * @param _extraData Extra data attached to the deposit.\n */\n function finalizeDeposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable virtual {\n if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n } else {\n finalizeBridgeERC20(_l2Token, _l1Token, _from, _to, _amount, _extraData);\n }\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L1 bridge contract.\n *\n * @return Address of the corresponding L1 bridge contract.\n */\n function l1TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @custom:legacy\n * @notice Internal function to a withdrawal from L2 to L1 to a target account on L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _from Address of the withdrawer.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function _initiateWithdrawal(\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {\n _initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);\n } else {\n address l1Token = OptimismMintableERC20(_l2Token).l1Token();\n _initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ETHBridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ERC20BridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L2/L2ToL1MessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000016\n * @title L2ToL1MessagePasser\n * @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from\n * L2 to L1 can be stored. The storage root of this contract is pulled up to the top level\n * of the L2 output to reduce the cost of proving the existence of sent messages.\n */\ncontract L2ToL1MessagePasser is Semver {\n /**\n * @notice The L1 gas limit set when eth is withdrawn using the receive() function.\n */\n uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Includes the message hashes for all withdrawals\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @notice A unique value hashed with each withdrawal.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Emitted any time a withdrawal is initiated.\n *\n * @param nonce Unique value corresponding to each withdrawal.\n * @param sender The L2 account address which initiated the withdrawal.\n * @param target The L1 account address the call will be send to.\n * @param value The ETH value submitted for withdrawal, to be forwarded to the target.\n * @param gasLimit The minimum amount of gas that must be provided when withdrawing.\n * @param data The data to be forwarded to the target on L1.\n * @param withdrawalHash The hash of the withdrawal.\n */\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n /**\n * @notice Emitted when the balance of this contract is burned.\n *\n * @param amount Amount of ETh that was burned.\n */\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Allows users to withdraw ETH by sending directly to this contract.\n */\n receive() external payable {\n initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @notice Removes all ETH held by this contract from the state. Used to prevent the amount of\n * ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to\n * create a contract and self-destruct it to itself. Anyone can call this function. Not\n * incentivized since this function is very cheap.\n */\n function burn() external {\n uint256 balance = address(this).balance;\n Burn.eth(balance);\n emit WithdrawerBalanceBurnt(balance);\n }\n\n /**\n * @notice Sends a message from L2 to L1.\n *\n * @param _target Address to call on L1 execution.\n * @param _gasLimit Minimum gas limit for executing the message on L1.\n * @param _data Data to forward to L1 target.\n */\n function initiateWithdrawal(\n address _target,\n uint256 _gasLimit,\n bytes memory _data\n ) public payable {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messageNonce(),\n sender: msg.sender,\n target: _target,\n value: msg.value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n sentMessages[withdrawalHash] = true;\n\n emit MessagePassed(\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _gasLimit,\n _data,\n withdrawalHash\n );\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n}\n" - }, - "contracts/L2/SequencerFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000011\n * @title SequencerFeeVault\n * @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during\n * transaction processing and block production.\n */\ncontract SequencerFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 0, 0) {}\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the recipient address.\n *\n * @return The recipient address.\n */\n function l1FeeWallet() public view returns (address) {\n return RECIPIENT;\n }\n}\n" - }, - "contracts/deployment/PortalSender.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/**\n * @title PortalSender\n * @notice The PortalSender is a simple intermediate contract that will transfer the balance of the\n * L1StandardBridge to the OptimismPortal during the Bedrock migration.\n */\ncontract PortalSender {\n /**\n * @notice Address of the OptimismPortal contract.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @param _portal Address of the OptimismPortal contract.\n */\n constructor(OptimismPortal _portal) {\n PORTAL = _portal;\n }\n\n /**\n * @notice Sends balance of this contract to the OptimismPortal.\n */\n function donate() public {\n PORTAL.donateETH{ value: address(this).balance }();\n }\n}\n" - }, - "contracts/deployment/SystemDictator.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { PortalSender } from \"./PortalSender.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @title SystemDictator\n * @notice The SystemDictator is responsible for coordinating the deployment of a full Bedrock\n * system. The SystemDictator is designed to support both fresh network deployments and\n * upgrades to existing pre-Bedrock systems.\n */\ncontract SystemDictator is OwnableUpgradeable {\n /**\n * @notice Basic system configuration.\n */\n struct GlobalConfig {\n AddressManager addressManager;\n ProxyAdmin proxyAdmin;\n address controller;\n address finalOwner;\n }\n\n /**\n * @notice Set of proxy addresses.\n */\n struct ProxyAddressConfig {\n address l2OutputOracleProxy;\n address optimismPortalProxy;\n address l1CrossDomainMessengerProxy;\n address l1StandardBridgeProxy;\n address optimismMintableERC20FactoryProxy;\n address l1ERC721BridgeProxy;\n address systemConfigProxy;\n }\n\n /**\n * @notice Set of implementation addresses.\n */\n struct ImplementationAddressConfig {\n L2OutputOracle l2OutputOracleImpl;\n OptimismPortal optimismPortalImpl;\n L1CrossDomainMessenger l1CrossDomainMessengerImpl;\n L1StandardBridge l1StandardBridgeImpl;\n OptimismMintableERC20Factory optimismMintableERC20FactoryImpl;\n L1ERC721Bridge l1ERC721BridgeImpl;\n PortalSender portalSenderImpl;\n SystemConfig systemConfigImpl;\n }\n\n /**\n * @notice Dynamic L2OutputOracle config.\n */\n struct L2OutputOracleDynamicConfig {\n uint256 l2OutputOracleStartingBlockNumber;\n uint256 l2OutputOracleStartingTimestamp;\n }\n\n /**\n * @notice Values for the system config contract.\n */\n struct SystemConfigConfig {\n address owner;\n uint256 overhead;\n uint256 scalar;\n bytes32 batcherHash;\n uint64 gasLimit;\n address unsafeBlockSigner;\n ResourceMetering.ResourceConfig resourceConfig;\n }\n\n /**\n * @notice Combined system configuration.\n */\n struct DeployConfig {\n GlobalConfig globalConfig;\n ProxyAddressConfig proxyAddressConfig;\n ImplementationAddressConfig implementationAddressConfig;\n SystemConfigConfig systemConfigConfig;\n }\n\n /**\n * @notice Step after which exit 1 can no longer be used.\n */\n uint8 public constant EXIT_1_NO_RETURN_STEP = 3;\n\n /**\n * @notice Step where proxy ownership is transferred.\n */\n uint8 public constant PROXY_TRANSFER_STEP = 4;\n\n /**\n * @notice System configuration.\n */\n DeployConfig public config;\n\n /**\n * @notice Dynamic configuration for the L2OutputOracle.\n */\n L2OutputOracleDynamicConfig public l2OutputOracleDynamicConfig;\n\n /**\n * @notice Dynamic configuration for the OptimismPortal. Determines\n * if the system should be paused when initialized.\n */\n bool public optimismPortalDynamicConfig;\n\n /**\n * @notice Current step;\n */\n uint8 public currentStep;\n\n /**\n * @notice Whether or not dynamic config has been set.\n */\n bool public dynamicConfigSet;\n\n /**\n * @notice Whether or not the deployment is finalized.\n */\n bool public finalized;\n\n /**\n * @notice Whether or not the deployment has been exited.\n */\n bool public exited;\n\n /**\n * @notice Address of the old L1CrossDomainMessenger implementation.\n */\n address public oldL1CrossDomainMessenger;\n\n /**\n * @notice Checks that the current step is the expected step, then bumps the current step.\n *\n * @param _step Current step.\n */\n modifier step(uint8 _step) {\n require(!finalized, \"SystemDictator: already finalized\");\n require(!exited, \"SystemDictator: already exited\");\n require(currentStep == _step, \"SystemDictator: incorrect step\");\n _;\n currentStep++;\n }\n\n /**\n * @notice Constructor required to ensure that the implementation of the SystemDictator is\n * initialized upon deployment.\n */\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n // Using this shorter variable as an alias for address(0) just prevents us from having to\n // to use a new line for every single parameter.\n address zero = address(0);\n initialize(\n DeployConfig(\n GlobalConfig(AddressManager(zero), ProxyAdmin(zero), zero, zero),\n ProxyAddressConfig(zero, zero, zero, zero, zero, zero, zero),\n ImplementationAddressConfig(\n L2OutputOracle(zero),\n OptimismPortal(payable(zero)),\n L1CrossDomainMessenger(zero),\n L1StandardBridge(payable(zero)),\n OptimismMintableERC20Factory(zero),\n L1ERC721Bridge(zero),\n PortalSender(zero),\n SystemConfig(zero)\n ),\n SystemConfigConfig(zero, 0, 0, bytes32(0), 0, zero, rcfg)\n )\n );\n }\n\n /**\n * @param _config System configuration.\n */\n function initialize(DeployConfig memory _config) public initializer {\n config = _config;\n currentStep = 1;\n __Ownable_init();\n _transferOwnership(config.globalConfig.controller);\n }\n\n /**\n * @notice Allows the owner to update dynamic config.\n *\n * @param _l2OutputOracleDynamicConfig Dynamic L2OutputOracle config.\n * @param _optimismPortalDynamicConfig Dynamic OptimismPortal config.\n */\n function updateDynamicConfig(\n L2OutputOracleDynamicConfig memory _l2OutputOracleDynamicConfig,\n bool _optimismPortalDynamicConfig\n ) external onlyOwner {\n l2OutputOracleDynamicConfig = _l2OutputOracleDynamicConfig;\n optimismPortalDynamicConfig = _optimismPortalDynamicConfig;\n dynamicConfigSet = true;\n }\n\n /**\n * @notice Configures the ProxyAdmin contract.\n */\n function step1() external onlyOwner step(1) {\n // Set the AddressManager in the ProxyAdmin.\n config.globalConfig.proxyAdmin.setAddressManager(config.globalConfig.addressManager);\n\n // Set the L1CrossDomainMessenger to the RESOLVED proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n ProxyAdmin.ProxyType.RESOLVED\n );\n\n // Set the implementation name for the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.setImplementationName(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Set the L1StandardBridge to the CHUGSPLASH proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1StandardBridgeProxy,\n ProxyAdmin.ProxyType.CHUGSPLASH\n );\n\n // Upgrade and initialize the SystemConfig so the Sequencer can start up.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.systemConfigProxy),\n address(config.implementationAddressConfig.systemConfigImpl),\n abi.encodeCall(\n SystemConfig.initialize,\n (\n config.systemConfigConfig.owner,\n config.systemConfigConfig.overhead,\n config.systemConfigConfig.scalar,\n config.systemConfigConfig.batcherHash,\n config.systemConfigConfig.gasLimit,\n config.systemConfigConfig.unsafeBlockSigner,\n config.systemConfigConfig.resourceConfig\n )\n )\n );\n }\n\n /**\n * @notice Pauses the system by shutting down the L1CrossDomainMessenger and setting the\n * deposit halt flag to tell the Sequencer's DTL to stop accepting deposits.\n */\n function step2() external onlyOwner step(2) {\n // Store the address of the old L1CrossDomainMessenger implementation. We will need this\n // address in the case that we have to exit early.\n oldL1CrossDomainMessenger = config.globalConfig.addressManager.getAddress(\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Temporarily brick the L1CrossDomainMessenger by setting its implementation address to\n // address(0) which will cause the ResolvedDelegateProxy to revert. Better than pausing\n // the L1CrossDomainMessenger via pause() because it can be easily reverted.\n config.globalConfig.addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(0));\n\n // Set the DTL shutoff block, which will tell the DTL to stop syncing new deposits from the\n // CanonicalTransactionChain. We do this by setting an address in the AddressManager\n // because the DTL already has a reference to the AddressManager and this way we don't also\n // need to give it a reference to the SystemDictator.\n config.globalConfig.addressManager.setAddress(\n \"DTL_SHUTOFF_BLOCK\",\n address(uint160(block.number))\n );\n }\n\n /**\n * @notice Removes deprecated addresses from the AddressManager.\n */\n function step3() external onlyOwner step(EXIT_1_NO_RETURN_STEP) {\n // Remove all deprecated addresses from the AddressManager\n string[17] memory deprecated = [\n \"OVM_CanonicalTransactionChain\",\n \"OVM_L2CrossDomainMessenger\",\n \"OVM_DecompressionPrecompileAddress\",\n \"OVM_Sequencer\",\n \"OVM_Proposer\",\n \"OVM_ChainStorageContainer-CTC-batches\",\n \"OVM_ChainStorageContainer-CTC-queue\",\n \"OVM_CanonicalTransactionChain\",\n \"OVM_StateCommitmentChain\",\n \"OVM_BondManager\",\n \"OVM_ExecutionManager\",\n \"OVM_FraudVerifier\",\n \"OVM_StateManagerFactory\",\n \"OVM_StateTransitionerFactory\",\n \"OVM_SafetyChecker\",\n \"OVM_L1MultiMessageRelayer\",\n \"BondManager\"\n ];\n\n for (uint256 i = 0; i < deprecated.length; i++) {\n config.globalConfig.addressManager.setAddress(deprecated[i], address(0));\n }\n }\n\n /**\n * @notice Transfers system ownership to the ProxyAdmin.\n */\n function step4() external onlyOwner step(PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the ProxyAdmin.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1StandardBridge to the ProxyAdmin.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the ProxyAdmin.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.proxyAdmin)\n );\n }\n\n /**\n * @notice Upgrades and initializes proxy contracts.\n */\n function step5() external onlyOwner step(5) {\n // Dynamic config must be set before we can initialize the L2OutputOracle.\n require(dynamicConfigSet, \"SystemDictator: dynamic oracle config is not yet initialized\");\n\n // Upgrade and initialize the L2OutputOracle.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l2OutputOracleProxy),\n address(config.implementationAddressConfig.l2OutputOracleImpl),\n abi.encodeCall(\n L2OutputOracle.initialize,\n (\n l2OutputOracleDynamicConfig.l2OutputOracleStartingBlockNumber,\n l2OutputOracleDynamicConfig.l2OutputOracleStartingTimestamp\n )\n )\n );\n\n // Upgrade and initialize the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.optimismPortalProxy),\n address(config.implementationAddressConfig.optimismPortalImpl),\n abi.encodeCall(OptimismPortal.initialize, (optimismPortalDynamicConfig))\n );\n\n // Upgrade the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1CrossDomainMessengerProxy),\n address(config.implementationAddressConfig.l1CrossDomainMessengerImpl)\n );\n\n // Try to initialize the L1CrossDomainMessenger, only fail if it's already been initialized.\n try\n L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy)\n .initialize()\n {\n // L1CrossDomainMessenger is the one annoying edge case difference between existing\n // networks and fresh networks because in existing networks it'll already be\n // initialized but in fresh networks it won't be. Try/catch is the easiest and most\n // consistent way to handle this because initialized() is not exposed publicly.\n } catch Error(string memory reason) {\n require(\n keccak256(abi.encodePacked(reason)) ==\n keccak256(\"Initializable: contract is already initialized\"),\n string.concat(\"SystemDictator: unexpected error initializing L1XDM: \", reason)\n );\n } catch {\n revert(\"SystemDictator: unexpected error initializing L1XDM (no reason)\");\n }\n\n // Transfer ETH from the L1StandardBridge to the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.portalSenderImpl),\n abi.encodeCall(PortalSender.donate, ())\n );\n\n // Upgrade the L1StandardBridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.l1StandardBridgeImpl)\n );\n\n // Upgrade the OptimismMintableERC20Factory (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.optimismMintableERC20FactoryProxy),\n address(config.implementationAddressConfig.optimismMintableERC20FactoryImpl)\n );\n\n // Upgrade the L1ERC721Bridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1ERC721BridgeProxy),\n address(config.implementationAddressConfig.l1ERC721BridgeImpl)\n );\n }\n\n /**\n * @notice Tranfers admin ownership to the final owner.\n */\n function finalize() external onlyOwner {\n // Transfer ownership of the ProxyAdmin to the final owner.\n config.globalConfig.proxyAdmin.transferOwnership(config.globalConfig.finalOwner);\n\n // Optionally also transfer AddressManager and L1StandardBridge if we still own it. Might\n // happen if we're exiting early.\n if (currentStep <= PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the final owner.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1StandardBridge to the final owner.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the final owner.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.finalOwner)\n );\n }\n\n // Mark the deployment as finalized.\n finalized = true;\n }\n\n /**\n * @notice First exit point, can only be called before step 3 is executed.\n */\n function exit1() external onlyOwner {\n require(\n currentStep == EXIT_1_NO_RETURN_STEP,\n \"SystemDictator: can only exit1 before step 3 is executed\"\n );\n\n // Reset the L1CrossDomainMessenger to the old implementation.\n config.globalConfig.addressManager.setAddress(\n \"OVM_L1CrossDomainMessenger\",\n oldL1CrossDomainMessenger\n );\n\n // Unset the DTL shutoff block which will allow the DTL to sync again.\n config.globalConfig.addressManager.setAddress(\"DTL_SHUTOFF_BLOCK\", address(0));\n\n // Mark the deployment as exited.\n exited = true;\n }\n}\n" - }, - "contracts/echidna/FuzzAddressAliasing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract EchidnaFuzzAddressAliasing {\n bool internal failedRoundtrip;\n\n /**\n * @notice Takes an address to be aliased with AddressAliasHelper and then unaliased\n * and updates the test contract's state indicating if the round trip encoding\n * failed.\n */\n function testRoundTrip(address addr) public {\n // Alias our address\n address aliasedAddr = AddressAliasHelper.applyL1ToL2Alias(addr);\n\n // Unalias our address\n address undoneAliasAddr = AddressAliasHelper.undoL1ToL2Alias(aliasedAddr);\n\n // If our round trip aliasing did not return the original result, set our state.\n if (addr != undoneAliasAddr) {\n failedRoundtrip = true;\n }\n }\n\n /**\n * @custom:invariant Address aliases are always able to be undone.\n *\n * Asserts that an address that has been aliased with `applyL1ToL2Alias` can always\n * be unaliased with `undoL1ToL2Alias`.\n */\n function echidna_round_trip_aliasing() public view returns (bool) {\n // ASSERTION: The round trip aliasing done in testRoundTrip(...) should never fail.\n return !failedRoundtrip;\n }\n}\n" - }, - "contracts/echidna/FuzzBurn.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\n\ncontract EchidnaFuzzBurnEth is StdUtils {\n bool internal failedEthBurn;\n\n /**\n * @notice Takes an integer amount of eth to burn through the Burn library and\n * updates the contract state if an incorrect amount of eth moved from the contract\n */\n function testBurn(uint256 _value) public {\n // cache the contract's eth balance\n uint256 preBurnBalance = address(this).balance;\n uint256 value = bound(_value, 0, preBurnBalance);\n\n // execute a burn of _value eth\n Burn.eth(value);\n\n // check that exactly value eth was transfered from the contract\n unchecked {\n if (address(this).balance != preBurnBalance - value) {\n failedEthBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `eth(uint256)` always burns the exact amount of eth passed.\n *\n * Asserts that when `Burn.eth(uint256)` is called, it always burns the exact amount\n * of ETH passed to the function.\n */\n function echidna_burn_eth() public view returns (bool) {\n // ASSERTION: The amount burned should always match the amount passed exactly\n return !failedEthBurn;\n }\n}\n\ncontract EchidnaFuzzBurnGas is StdUtils {\n bool internal failedGasBurn;\n\n /**\n * @notice Takes an integer amount of gas to burn through the Burn library and\n * updates the contract state if at least that amount of gas was not burned\n * by the library\n */\n function testGas(uint256 _value) public {\n // cap the value to the max resource limit\n uint256 MAX_RESOURCE_LIMIT = 8_000_000;\n uint256 value = bound(_value, 0, MAX_RESOURCE_LIMIT);\n\n // cache the contract's current remaining gas\n uint256 preBurnGas = gasleft();\n\n // execute the gas burn\n Burn.gas(value);\n\n // cache the remaining gas post burn\n uint256 postBurnGas = gasleft();\n\n // check that at least value gas was burnt (and that there was no underflow)\n unchecked {\n if (postBurnGas - preBurnGas > value || preBurnGas - value > preBurnGas) {\n failedGasBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `gas(uint256)` always burns at least the amount of gas passed.\n *\n * Asserts that when `Burn.gas(uint256)` is called, it always burns at least the amount\n * of gas passed to the function.\n */\n function echidna_burn_gas() public view returns (bool) {\n // ASSERTION: The amount of gas burned should be strictly greater than the\n // the amount passed as _value (minimum _value + whatever minor overhead to\n // the value after the call)\n return !failedGasBurn;\n }\n}\n" - }, - "contracts/echidna/FuzzEncoding.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzEncoding {\n bool internal failedRoundtripAToB;\n bool internal failedRoundtripBToA;\n\n /**\n * @notice Takes a pair of integers to be encoded into a versioned nonce with the\n * Encoding library and then decoded and updates the test contract's state\n * indicating if the round trip encoding failed.\n */\n function testRoundTripAToB(uint240 _nonce, uint16 _version) public {\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(encodedVersionedNonce);\n\n // If our round trip encoding did not return the original result, set our state.\n if ((decodedNonce != _nonce) || (decodedVersion != _version)) {\n failedRoundtripAToB = true;\n }\n }\n\n /**\n * @notice Takes an integer representing a packed version and nonce and attempts\n * to decode them using the Encoding library before re-encoding and updates\n * the test contract's state indicating if the round trip encoding failed.\n */\n function testRoundTripBToA(uint256 _versionedNonce) public {\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(_versionedNonce);\n\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(decodedNonce, decodedVersion);\n\n // If our round trip encoding did not return the original result, set our state.\n if (encodedVersionedNonce != _versionedNonce) {\n failedRoundtripBToA = true;\n }\n }\n\n /**\n * @custom:invariant `testRoundTripAToB` never fails.\n *\n * Asserts that a raw versioned nonce can be encoded / decoded to reach the same raw value.\n */\n function echidna_round_trip_encoding_AToB() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripAToB(...)\n return !failedRoundtripAToB;\n }\n\n /**\n * @custom:invariant `testRoundTripBToA` never fails.\n *\n * Asserts that an encoded versioned nonce can always be decoded / re-encoded to reach\n * the same encoded value.\n */\n function echidna_round_trip_encoding_BToA() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripBToA should never\n // fail.\n return !failedRoundtripBToA;\n }\n}\n" - }, - "contracts/echidna/FuzzHashing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzHashing {\n bool internal failedCrossDomainHashHighVersion;\n bool internal failedCrossDomainHashV0;\n bool internal failedCrossDomainHashV1;\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash with a randomly\n * generated version. Only schema versions 0 and 1 are supported and all others should revert.\n */\n function testHashCrossDomainMessageHighVersion(\n uint16 _version,\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // hash the cross domain message. we don't need to store the result since the function\n // validates and should revert if an invalid version (>1) is encoded\n Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);\n\n // check that execution never makes it this far for an invalid version\n if (_version > 1) {\n failedCrossDomainHashHighVersion = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v0 schema\n * and compares the output of a call to the unversioned function to the v0 function directly\n */\n function testHashCrossDomainMessageV0(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 0\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 0);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n encodedNonce\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV0 = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v1 schema\n * and compares the output of a call to the unversioned function to the v1 function directly\n */\n function testHashCrossDomainMessageV1(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 1\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 1);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV1 = true;\n }\n }\n\n /**\n * @custom:invariant `hashCrossDomainMessage` reverts if `version` is > `1`.\n *\n * The `hashCrossDomainMessage` function should always revert if the `version` passed is > `1`.\n */\n function echidna_hash_xdomain_msg_high_version() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage will never succeed for a version > 1\n return !failedCrossDomainHashHighVersion;\n }\n\n /**\n * @custom:invariant `version` = `0`: `hashCrossDomainMessage` and `hashCrossDomainMessageV0`\n * are equivalent.\n *\n * If the version passed is 0, `hashCrossDomainMessage` and `hashCrossDomainMessageV0` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_0() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV0\n // should always match when the version passed is 0\n return !failedCrossDomainHashV0;\n }\n\n /**\n * @custom:invariant `version` = `1`: `hashCrossDomainMessage` and `hashCrossDomainMessageV1`\n * are equivalent.\n *\n * If the version passed is 1, `hashCrossDomainMessage` and `hashCrossDomainMessageV1` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_1() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV1\n // should always match when the version passed is 1\n return !failedCrossDomainHashV1;\n }\n}\n" - }, - "contracts/echidna/FuzzOptimismPortal.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzOptimismPortal {\n OptimismPortal internal portal;\n bool internal failedToComplete;\n\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n SystemConfig systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: rcfg\n });\n\n portal = new OptimismPortal({\n _l2Oracle: L2OutputOracle(address(0)),\n _guardian: address(0),\n _paused: false,\n _config: systemConfig\n });\n }\n\n // A test intended to identify any unexpected halting conditions\n function testDepositTransactionCompletes(\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable {\n failedToComplete = true;\n require(!_isCreation || _to == address(0), \"EchidnaFuzzOptimismPortal: invalid test case.\");\n portal.depositTransaction{ value: _mint }(_to, _value, _gasLimit, _isCreation, _data);\n failedToComplete = false;\n }\n\n /**\n * @custom:invariant Deposits of any value should always succeed unless\n * `_to` = `address(0)` or `_isCreation` = `true`.\n *\n * All deposits, barring creation transactions and transactions sent to `address(0)`,\n * should always succeed.\n */\n function echidna_deposit_completes() public view returns (bool) {\n return !failedToComplete;\n }\n}\n" - }, - "contracts/echidna/FuzzResourceMetering.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzResourceMetering is ResourceMetering, StdUtils {\n bool internal failedMaxGasPerBlock;\n bool internal failedRaiseBaseFee;\n bool internal failedLowerBaseFee;\n bool internal failedNeverBelowMinBaseFee;\n bool internal failedMaxRaiseBaseFeePerBlock;\n bool internal failedMaxLowerBaseFeePerBlock;\n\n // Used as a special flag for the purpose of identifying unchecked math errors specifically\n // in the test contracts, not the target contracts themselves.\n bool internal underflow;\n\n constructor() {\n initialize();\n }\n\n function initialize() internal initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public pure returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n return rcfg;\n }\n\n /**\n * @notice Takes the necessary parameters to allow us to burn arbitrary amounts of gas to test\n * the underlying resource metering/gas market logic\n */\n function testBurn(uint256 _gasToBurn, bool _raiseBaseFee) public {\n // Part 1: we cache the current param values and do some basic checks on them.\n uint256 cachedPrevBaseFee = uint256(params.prevBaseFee);\n uint256 cachedPrevBoughtGas = uint256(params.prevBoughtGas);\n uint256 cachedPrevBlockNum = uint256(params.prevBlockNum);\n\n ResourceMetering.ResourceConfig memory rcfg = resourceConfig();\n uint256 targetResourceLimit = uint256(rcfg.maxResourceLimit) /\n uint256(rcfg.elasticityMultiplier);\n\n // check that the last block's base fee hasn't dropped below the minimum\n if (cachedPrevBaseFee < uint256(rcfg.minimumBaseFee)) {\n failedNeverBelowMinBaseFee = true;\n }\n // check that the last block didn't consume more than the max amount of gas\n if (cachedPrevBoughtGas > uint256(rcfg.maxResourceLimit)) {\n failedMaxGasPerBlock = true;\n }\n\n // Part2: we perform the gas burn\n\n // force the gasToBurn into the correct range based on whether we intend to\n // raise or lower the baseFee after this block, respectively\n uint256 gasToBurn;\n if (_raiseBaseFee) {\n gasToBurn = bound(\n _gasToBurn,\n uint256(targetResourceLimit),\n uint256(rcfg.maxResourceLimit)\n );\n } else {\n gasToBurn = bound(_gasToBurn, 0, targetResourceLimit);\n }\n\n _burnInternal(uint64(gasToBurn));\n\n // Part 3: we run checks and modify our invariant flags based on the updated params values\n\n // Calculate the maximum allowed baseFee change (per block)\n uint256 maxBaseFeeChange = cachedPrevBaseFee / uint256(rcfg.baseFeeMaxChangeDenominator);\n\n // If the last block used more than the target amount of gas (and there were no\n // empty blocks in between), ensure this block's baseFee increased, but not by\n // more than the max amount per block\n if (\n (cachedPrevBoughtGas > uint256(targetResourceLimit)) &&\n (uint256(params.prevBlockNum) - cachedPrevBlockNum == 1)\n ) {\n failedRaiseBaseFee = failedRaiseBaseFee || (params.prevBaseFee <= cachedPrevBaseFee);\n failedMaxRaiseBaseFeePerBlock =\n failedMaxRaiseBaseFeePerBlock ||\n ((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);\n }\n\n // If the last block used less than the target amount of gas, (or was empty),\n // ensure that: this block's baseFee was decreased, but not by more than the max amount\n if (\n (cachedPrevBoughtGas < uint256(targetResourceLimit)) ||\n (uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)\n ) {\n // Invariant: baseFee should decrease\n failedLowerBaseFee =\n failedLowerBaseFee ||\n (uint256(params.prevBaseFee) > cachedPrevBaseFee);\n\n if (params.prevBlockNum - cachedPrevBlockNum == 1) {\n // No empty blocks\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n } else if (params.prevBlockNum - cachedPrevBlockNum > 1) {\n // We have at least one empty block\n // Update the maxBaseFeeChange to account for multiple blocks having passed\n unchecked {\n maxBaseFeeChange = uint256(\n int256(cachedPrevBaseFee) -\n Arithmetic.clamp(\n Arithmetic.cdexp(\n int256(cachedPrevBaseFee),\n int256(uint256(rcfg.baseFeeMaxChangeDenominator)),\n int256(uint256(params.prevBlockNum) - cachedPrevBlockNum)\n ),\n int256(uint256(rcfg.minimumBaseFee)),\n int256(uint256(rcfg.maximumBaseFee))\n )\n );\n }\n\n // Detect an underflow in the previous calculation.\n // Without using unchecked above, and detecting the underflow here, echidna would\n // otherwise ignore the revert.\n underflow = underflow || maxBaseFeeChange > cachedPrevBaseFee;\n\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n }\n }\n }\n\n function _burnInternal(uint64 _gasToBurn) private metered(_gasToBurn) {}\n\n /**\n * @custom:invariant The base fee should increase if the last block used more\n * than the target amount of gas\n *\n * If the last block used more than the target amount of gas (and there were no\n * empty blocks in between), ensure this block's baseFee increased, but not by\n * more than the max amount per block.\n */\n function echidna_high_usage_raise_baseFee() public view returns (bool) {\n return !failedRaiseBaseFee;\n }\n\n /**\n * @custom:invariant The base fee should decrease if the last block used less\n * than the target amount of gas\n *\n * If the previous block used less than the target amount of gas, the base fee should decrease,\n * but not more than the max amount.\n */\n function echidna_low_usage_lower_baseFee() public view returns (bool) {\n return !failedLowerBaseFee;\n }\n\n /**\n * @custom:invariant A block's base fee should never be below `MINIMUM_BASE_FEE`\n *\n * This test asserts that a block's base fee can never drop below the\n * `MINIMUM_BASE_FEE` threshold.\n */\n function echidna_never_below_min_baseFee() public view returns (bool) {\n return !failedNeverBelowMinBaseFee;\n }\n\n /**\n * @custom:invariant A block can never consume more than `MAX_RESOURCE_LIMIT` gas.\n *\n * This test asserts that a block can never consume more than the `MAX_RESOURCE_LIMIT`\n * gas threshold.\n */\n function echidna_never_above_max_gas_limit() public view returns (bool) {\n return !failedMaxGasPerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be raised more than the max base fee change.\n *\n * After a block consumes more gas than the target gas, the base fee cannot be raised\n * more than the maximum amount allowed. The max base fee change (per-block) is derived\n * as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_increase() public view returns (bool) {\n return !failedMaxRaiseBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be lowered more than the max base fee change.\n *\n * After a block consumes less than the target gas, the base fee cannot be lowered more\n * than the maximum amount allowed. The max base fee change (per-block) is derived as\n *follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_decrease() public view returns (bool) {\n return !failedMaxLowerBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The `maxBaseFeeChange` calculation over multiple blocks can never\n * underflow.\n *\n * When calculating the `maxBaseFeeChange` after multiple empty blocks, the calculation\n * should never be allowed to underflow.\n */\n function echidna_underflow() public view returns (bool) {\n return !underflow;\n }\n}\n" - }, - "contracts/governance/GovernanceToken.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:predeploy 0x4200000000000000000000000000000000000042\n * @title GovernanceToken\n * @notice The Optimism token used in governance and supporting voting and delegation. Implements\n * EIP 2612 allowing signed approvals. Contract is \"owned\" by a `MintManager` instance with\n * permission to the `mint` function only, for the purposes of enforcing the token inflation\n * schedule.\n */\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\n constructor() ERC20(\"Optimism\", \"OP\") ERC20Permit(\"Optimism\") {}\n\n /**\n * @notice Allows the owner to mint tokens.\n *\n * @param _account The account receiving minted tokens.\n * @param _amount The amount of tokens to mint.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n /**\n * @notice Callback called after a token transfer.\n *\n * @param from The account sending tokens.\n * @param to The account receiving tokens.\n * @param amount The amount of tokens being transfered.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20, ERC20Votes) {\n super._afterTokenTransfer(from, to, amount);\n }\n\n /**\n * @notice Internal mint function.\n *\n * @param to The account receiving minted tokens.\n * @param amount The amount of tokens to mint.\n */\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._mint(to, amount);\n }\n\n /**\n * @notice Internal burn function.\n *\n * @param account The account that tokens will be burned from.\n * @param amount The amount of tokens that will be burned.\n */\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._burn(account, amount);\n }\n}\n" - }, - "contracts/governance/MintManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./GovernanceToken.sol\";\n\n/**\n * @title MintManager\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\n * Contract acts as the token \"mint manager\" with permission to the `mint` function only.\n * Currently permitted to mint once per year of up to 2% of the total token supply.\n * Upgradable to allow changes in the inflation schedule.\n */\ncontract MintManager is Ownable {\n /**\n * @notice The GovernanceToken that the MintManager can mint tokens\n */\n GovernanceToken public immutable governanceToken;\n\n /**\n * @notice The amount of tokens that can be minted per year. The value is a fixed\n * point number with 4 decimals.\n */\n uint256 public constant MINT_CAP = 20; // 2%\n\n /**\n * @notice The number of decimals for the MINT_CAP.\n */\n uint256 public constant DENOMINATOR = 1000;\n\n /**\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\n * be minted again.\n */\n uint256 public constant MINT_PERIOD = 365 days;\n\n /**\n * @notice Tracks the time of last mint.\n */\n uint256 public mintPermittedAfter;\n\n /**\n * @param _upgrader The owner of this contract\n * @param _governanceToken The governance token this contract can mint\n * tokens of\n */\n constructor(address _upgrader, address _governanceToken) {\n transferOwnership(_upgrader);\n governanceToken = GovernanceToken(_governanceToken);\n }\n\n /**\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\n *\n * @param _account Address to mint new tokens to.\n * @param _amount Amount of tokens to be minted.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n if (mintPermittedAfter > 0) {\n require(\n mintPermittedAfter <= block.timestamp,\n \"MintManager: minting not permitted yet\"\n );\n\n require(\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\n \"MintManager: mint amount exceeds cap\"\n );\n }\n\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\n governanceToken.mint(_account, _amount);\n }\n\n /**\n * @notice Upgrade the owner of the governance token to a new MintManager.\n *\n * @param _newMintManager The MintManager to upgrade to.\n */\n function upgrade(address _newMintManager) public onlyOwner {\n require(\n _newMintManager != address(0),\n \"MintManager: mint manager cannot be the zero address\"\n );\n\n governanceToken.transferOwnership(_newMintManager);\n }\n}\n" - }, - "contracts/legacy/AddressManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:legacy\n * @title AddressManager\n * @notice AddressManager is a legacy contract that was used in the old version of the Optimism\n * system to manage a registry of string names to addresses. We now use a more standard\n * proxy system instead, but this contract is still necessary for backwards compatibility\n * with several older contracts.\n */\ncontract AddressManager is Ownable {\n /**\n * @notice Mapping of the hashes of string names to addresses.\n */\n mapping(bytes32 => address) private addresses;\n\n /**\n * @notice Emitted when an address is modified in the registry.\n *\n * @param name String name being set in the registry.\n * @param newAddress Address set for the given name.\n * @param oldAddress Address that was previously set for the given name.\n */\n event AddressSet(string indexed name, address newAddress, address oldAddress);\n\n /**\n * @notice Changes the address associated with a particular name.\n *\n * @param _name String name to associate an address with.\n * @param _address Address to associate with the name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n bytes32 nameHash = _getNameHash(_name);\n address oldAddress = addresses[nameHash];\n addresses[nameHash] = _address;\n\n emit AddressSet(_name, _address, oldAddress);\n }\n\n /**\n * @notice Retrieves the address associated with a given name.\n *\n * @param _name Name to retrieve an address for.\n *\n * @return Address associated with the given name.\n */\n function getAddress(string memory _name) external view returns (address) {\n return addresses[_getNameHash(_name)];\n }\n\n /**\n * @notice Computes the hash of a name.\n *\n * @param _name Name to compute a hash for.\n *\n * @return Hash of the given name.\n */\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(_name));\n }\n}\n" - }, - "contracts/legacy/DeployerWhitelist.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000002\n * @title DeployerWhitelist\n * @notice DeployerWhitelist is a legacy contract that was originally used to act as a whitelist of\n * addresses allowed to the Optimism network. The DeployerWhitelist has since been\n * disabled, but the code is kept in state for the sake of full backwards compatibility.\n * As of the Bedrock upgrade, the DeployerWhitelist is completely unused by the Optimism\n * system and could, in theory, be removed entirely.\n */\ncontract DeployerWhitelist is Semver {\n /**\n * @notice Address of the owner of this contract. Note that when this address is set to\n * address(0), the whitelist is disabled.\n */\n address public owner;\n\n /**\n * @notice Mapping of deployer addresses to boolean whitelist status.\n */\n mapping(address => bool) public whitelist;\n\n /**\n * @notice Emitted when the owner of this contract changes.\n *\n * @param oldOwner Address of the previous owner.\n * @param newOwner Address of the new owner.\n */\n event OwnerChanged(address oldOwner, address newOwner);\n\n /**\n * @notice Emitted when the whitelist status of a deployer changes.\n *\n * @param deployer Address of the deployer.\n * @param whitelisted Boolean indicating whether the deployer is whitelisted.\n */\n event WhitelistStatusChanged(address deployer, bool whitelisted);\n\n /**\n * @notice Emitted when the whitelist is disabled.\n *\n * @param oldOwner Address of the final owner of the whitelist.\n */\n event WhitelistDisabled(address oldOwner);\n\n /**\n * @notice Blocks functions to anyone except the contract owner.\n */\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"DeployerWhitelist: function can only be called by the owner of this contract\"\n );\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Adds or removes an address from the deployment whitelist.\n *\n * @param _deployer Address to update permissions for.\n * @param _isWhitelisted Whether or not the address is whitelisted.\n */\n function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external onlyOwner {\n whitelist[_deployer] = _isWhitelisted;\n emit WhitelistStatusChanged(_deployer, _isWhitelisted);\n }\n\n /**\n * @notice Updates the owner of this contract.\n *\n * @param _owner Address of the new owner.\n */\n function setOwner(address _owner) external onlyOwner {\n // Prevent users from setting the whitelist owner to address(0) except via\n // enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to\n // any other address that doesn't have a corresponding knowable private key.\n require(\n _owner != address(0),\n \"DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment\"\n );\n\n emit OwnerChanged(owner, _owner);\n owner = _owner;\n }\n\n /**\n * @notice Permanently enables arbitrary contract deployment and deletes the owner.\n */\n function enableArbitraryContractDeployment() external onlyOwner {\n emit WhitelistDisabled(owner);\n owner = address(0);\n }\n\n /**\n * @notice Checks whether an address is allowed to deploy contracts.\n *\n * @param _deployer Address to check.\n *\n * @return Whether or not the address can deploy contracts.\n */\n function isDeployerAllowed(address _deployer) external view returns (bool) {\n return (owner == address(0) || whitelist[_deployer]);\n }\n}\n" - }, - "contracts/legacy/L1BlockNumber.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000013\n * @title L1BlockNumber\n * @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract\n * in the old version of the Optimism system. Only necessary for backwards compatibility.\n * If you want to access the L1 block number going forward, you should use the L1Block\n * contract instead.\n */\ncontract L1BlockNumber is Semver {\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Returns the L1 block number.\n */\n receive() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Returns the L1 block number.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Retrieves the latest L1 block number.\n *\n * @return Latest L1 block number.\n */\n function getL1BlockNumber() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).number();\n }\n}\n" - }, - "contracts/legacy/L1ChugSplashProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title IL1ChugSplashDeployer\n */\ninterface IL1ChugSplashDeployer {\n function isUpgrading() external view returns (bool);\n}\n\n/**\n * @custom:legacy\n * @title L1ChugSplashProxy\n * @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\n * functions `setCode` and `setStorage` for changing the code or storage of the contract.\n *\n * Note for future developers: do NOT make anything in this contract 'public' unless you\n * know what you're doing. Anything public can potentially have a function signature that\n * conflicts with a signature attached to the implementation contract. Public functions\n * SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good\n * reason not to have that modifier. And there almost certainly is not a good reason to not\n * have that modifier. Beware!\n */\ncontract L1ChugSplashProxy {\n /**\n * @notice \"Magic\" prefix. When prepended to some arbitrary bytecode and used to create a\n * contract, the appended bytecode will be deployed as given.\n */\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice Blocks a function from being called when the parent signals that the system should\n * be paused via an isUpgrading function.\n */\n modifier onlyWhenNotPaused() {\n address owner = _getOwner();\n\n // We do a low-level call because there's no guarantee that the owner actually *is* an\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\n // it turns out that it isn't the right type of contract.\n (bool success, bytes memory returndata) = owner.staticcall(\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)\n );\n\n // If the call was unsuccessful then we assume that there's no \"isUpgrading\" method and we\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\n // long. If this isn't the case then we can safely ignore the result.\n if (success && returndata.length == 32) {\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\n // case that the isUpgrading function returned something other than 0 or 1. But we only\n // really care about the case where this value is 0 (= false).\n uint256 ret = abi.decode(returndata, (uint256));\n require(ret == 0, \"L1ChugSplashProxy: system is currently being upgraded\");\n }\n\n _;\n }\n\n /**\n * @notice Makes a proxy call instead of triggering the given function when the caller is\n * either the owner or the zero address. Caller can only ever be the zero address if\n * this function is being called off-chain via eth_call, which is totally fine and can\n * be convenient for client-side tooling. Avoids situations where the proxy and\n * implementation share a sighash and the proxy function ends up being called instead\n * of the implementation one.\n *\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If\n * there's a way for someone to send a transaction with msg.sender == address(0) in any\n * real context then we have much bigger problems. Primary reason to include this\n * additional allowed sender is because the owner address can be changed dynamically\n * and we do not want clients to have to keep track of the current owner in order to\n * make an eth_call that doesn't trigger the proxied contract.\n */\n // slither-disable-next-line incorrect-modifier\n modifier proxyCallIfNotOwner() {\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @param _owner Address of the initial contract owner.\n */\n constructor(address _owner) {\n _setOwner(_owner);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Sets the code that should be running behind this proxy.\n *\n * Note: This scheme is a bit different from the standard proxy scheme where one would\n * typically deploy the code separately and then set the implementation address. We're\n * doing it this way because it gives us a lot more freedom on the client side. Can\n * only be triggered by the contract owner.\n *\n * @param _code New contract code to run inside this contract.\n */\n function setCode(bytes memory _code) external proxyCallIfNotOwner {\n // Get the code hash of the current implementation.\n address implementation = _getImplementation();\n\n // If the code hash matches the new implementation then we return early.\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\n return;\n }\n\n // Create the deploycode by appending the magic prefix.\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\n\n // Deploy the code and set the new implementation address.\n address newImplementation;\n assembly {\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\n }\n\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\n // actually fail this check. Should only happen if the contract creation from above runs\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\n // should be doing this check anyway though.\n require(\n _getAccountCodeHash(newImplementation) == keccak256(_code),\n \"L1ChugSplashProxy: code was not correctly deployed\"\n );\n\n _setImplementation(newImplementation);\n }\n\n /**\n * @notice Modifies some storage slot within the proxy contract. Gives us a lot of power to\n * perform upgrades in a more transparent way. Only callable by the owner.\n *\n * @param _key Storage key to modify.\n * @param _value New value for the storage key.\n */\n function setStorage(bytes32 _key, bytes32 _value) external proxyCallIfNotOwner {\n assembly {\n sstore(_key, _value)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _owner New owner of the proxy contract.\n */\n function setOwner(address _owner) external proxyCallIfNotOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Queries the owner of the proxy contract. Can only be called by the owner OR by\n * making an eth_call and setting the \"from\" address to address(0).\n *\n * @return Owner address.\n */\n function getOwner() external proxyCallIfNotOwner returns (address) {\n return _getOwner();\n }\n\n /**\n * @notice Queries the implementation address. Can only be called by the owner OR by making an\n * eth_call and setting the \"from\" address to address(0).\n *\n * @return Implementation address.\n */\n function getImplementation() external proxyCallIfNotOwner returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _owner New owner of the proxy contract.\n */\n function _setOwner(address _owner) internal {\n assembly {\n sstore(OWNER_KEY, _owner)\n }\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal onlyWhenNotPaused {\n address implementation = _getImplementation();\n\n require(implementation != address(0), \"L1ChugSplashProxy: implementation is not set yet\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address implementation;\n assembly {\n implementation := sload(IMPLEMENTATION_KEY)\n }\n return implementation;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getOwner() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n\n /**\n * @notice Gets the code hash for a given account.\n *\n * @param _account Address of the account to get a code hash for.\n *\n * @return Code hash for the account.\n */\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\n bytes32 codeHash;\n assembly {\n codeHash := extcodehash(_account)\n }\n return codeHash;\n }\n}\n" - }, - "contracts/legacy/LegacyERC20ETH.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000\n * @title LegacyERC20ETH\n * @notice LegacyERC20ETH is a legacy contract that held ETH balances before the Bedrock upgrade.\n * All ETH balances held within this contract were migrated to the state trie as part of\n * the Bedrock upgrade. Functions within this contract that mutate state were already\n * disabled as part of the EVM equivalence upgrade.\n */\ncontract LegacyERC20ETH is OptimismMintableERC20 {\n /**\n * @notice Initializes the contract as an Optimism Mintable ERC20.\n */\n constructor()\n OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), \"Ether\", \"ETH\")\n {}\n\n /**\n * @notice Returns the ETH balance of the target account. Overrides the base behavior of the\n * contract to preserve the invariant that the balance within this contract always\n * matches the balance in the state trie.\n *\n * @param _who Address of the account to query.\n *\n * @return The ETH balance of the target account.\n */\n function balanceOf(address _who) public view virtual override returns (uint256) {\n return address(_who).balance;\n }\n\n /**\n * @custom:blocked\n * @notice Mints some amount of ETH.\n */\n function mint(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: mint is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Burns some amount of ETH.\n */\n function burn(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: burn is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers some amount of ETH.\n */\n function transfer(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transfer is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Approves a spender to spend some amount of ETH.\n */\n function approve(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: approve is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers funds from some sender account.\n */\n function transferFrom(\n address,\n address,\n uint256\n ) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transferFrom is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Increases the allowance of a spender.\n */\n function increaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Decreases the allowance of a spender.\n */\n function decreaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n }\n}\n" - }, - "contracts/legacy/LegacyMessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000000\n * @title LegacyMessagePasser\n * @notice The LegacyMessagePasser was the low-level mechanism used to send messages from L2 to L1\n * before the Bedrock upgrade. It is now deprecated in favor of the new MessagePasser.\n */\ncontract LegacyMessagePasser is Semver {\n /**\n * @notice Mapping of sent message hashes to boolean status.\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Passes a message to L1.\n *\n * @param _message Message to pass to L1.\n */\n function passMessageToL1(bytes memory _message) external {\n sentMessages[keccak256(abi.encodePacked(_message, msg.sender))] = true;\n }\n}\n" - }, - "contracts/legacy/LegacyMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ILegacyMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @title LegacyMintableERC20\n * @notice The legacy implementation of the OptimismMintableERC20. This\n * contract is deprecated and should no longer be used.\n */\ncontract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {\n /**\n * @notice Emitted when the token is minted by the bridge.\n */\n event Mint(address indexed _account, uint256 _amount);\n\n /**\n * @notice Emitted when a token is burned by the bridge.\n */\n event Burn(address indexed _account, uint256 _amount);\n\n /**\n * @notice The token on the remote domain.\n */\n address public l1Token;\n\n /**\n * @notice The local bridge.\n */\n address public l2Bridge;\n\n /**\n * @param _l2Bridge Address of the L2 standard bridge.\n * @param _l1Token Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _l2Bridge,\n address _l1Token,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) {\n l1Token = _l1Token;\n l2Bridge = _l2Bridge;\n }\n\n /**\n * @notice Modifier that requires the contract was called by the bridge.\n */\n modifier onlyL2Bridge() {\n require(msg.sender == l2Bridge, \"Only L2 Bridge can mint and burn\");\n _;\n }\n\n /**\n * @notice EIP165 implementation.\n */\n function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n\n /**\n * @notice Only the bridge can mint tokens.\n * @param _to The account receiving tokens.\n * @param _amount The amount of tokens to receive.\n */\n function mint(address _to, uint256 _amount) public virtual onlyL2Bridge {\n _mint(_to, _amount);\n\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Only the bridge can burn tokens.\n * @param _from The account having tokens burnt.\n * @param _amount The amount of tokens being burnt.\n */\n function burn(address _from, uint256 _amount) public virtual onlyL2Bridge {\n _burn(_from, _amount);\n\n emit Burn(_from, _amount);\n }\n}\n" - }, - "contracts/legacy/ResolvedDelegateProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressManager } from \"./AddressManager.sol\";\n\n/**\n * @custom:legacy\n * @title ResolvedDelegateProxy\n * @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to\n * resolve the implementation address. We're maintaining this contract for backwards\n * compatibility so we can manage all legacy proxies where necessary.\n */\ncontract ResolvedDelegateProxy {\n /**\n * @notice Mapping used to store the implementation name that corresponds to this contract. A\n * mapping was originally used as a way to bypass the same issue normally solved by\n * storing the implementation address in a specific storage slot that does not conflict\n * with any other storage slot. Generally NOT a safe solution but works as long as the\n * implementation does not also keep a mapping in the first storage slot.\n */\n mapping(address => string) private implementationName;\n\n /**\n * @notice Mapping used to store the address of the AddressManager contract where the\n * implementation address will be resolved from. Same concept here as with the above\n * mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping\n * in the second storage slot.\n */\n mapping(address => AddressManager) private addressManager;\n\n /**\n * @param _addressManager Address of the AddressManager.\n * @param _implementationName implementationName of the contract to proxy to.\n */\n constructor(AddressManager _addressManager, string memory _implementationName) {\n addressManager[address(this)] = _addressManager;\n implementationName[address(this)] = _implementationName;\n }\n\n /**\n * @notice Fallback, performs a delegatecall to the resolved implementation address.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n address target = addressManager[address(this)].getAddress(\n (implementationName[address(this)])\n );\n\n require(target != address(0), \"ResolvedDelegateProxy: target address must be initialized\");\n\n // slither-disable-next-line controlled-delegatecall\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\n\n if (success == true) {\n assembly {\n return(add(returndata, 0x20), mload(returndata))\n }\n } else {\n assembly {\n revert(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n" - }, - "contracts/libraries/Arithmetic.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { SignedMath } from \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport { FixedPointMathLib } from \"@rari-capital/solmate/src/utils/FixedPointMathLib.sol\";\n\n/**\n * @title Arithmetic\n * @notice Even more math than before.\n */\nlibrary Arithmetic {\n /**\n * @notice Clamps a value between a minimum and maximum.\n *\n * @param _value The value to clamp.\n * @param _min The minimum value.\n * @param _max The maximum value.\n *\n * @return The clamped value.\n */\n function clamp(\n int256 _value,\n int256 _min,\n int256 _max\n ) internal pure returns (int256) {\n return SignedMath.min(SignedMath.max(_value, _min), _max);\n }\n\n /**\n * @notice (c)oefficient (d)enominator (exp)onentiation function.\n * Returns the result of: c * (1 - 1/d)^exp.\n *\n * @param _coefficient Coefficient of the function.\n * @param _denominator Fractional denominator.\n * @param _exponent Power function exponent.\n *\n * @return Result of c * (1 - 1/d)^exp.\n */\n function cdexp(\n int256 _coefficient,\n int256 _denominator,\n int256 _exponent\n ) internal pure returns (int256) {\n return\n (_coefficient *\n (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;\n }\n}\n" - }, - "contracts/libraries/Burn.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Burn\n * @notice Utilities for burning stuff.\n */\nlibrary Burn {\n /**\n * Burns a given amount of ETH.\n *\n * @param _amount Amount of ETH to burn.\n */\n function eth(uint256 _amount) internal {\n new Burner{ value: _amount }();\n }\n\n /**\n * Burns a given amount of gas.\n *\n * @param _amount Amount of gas to burn.\n */\n function gas(uint256 _amount) internal view {\n uint256 i = 0;\n uint256 initialGas = gasleft();\n while (initialGas - gasleft() < _amount) {\n ++i;\n }\n }\n}\n\n/**\n * @title Burner\n * @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to\n * the contract from the circulating supply. Self-destructing is the only way to remove ETH\n * from the circulating supply.\n */\ncontract Burner {\n constructor() payable {\n selfdestruct(payable(address(this)));\n }\n}\n" - }, - "contracts/libraries/Bytes.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Bytes\n * @notice Bytes is a library for manipulating byte arrays.\n */\nlibrary Bytes {\n /**\n * @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\n * @notice Slices a byte array with a given starting index and length. Returns a new byte array\n * as opposed to a pointer to the original array. Will throw if trying to slice more\n * bytes than exist in the array.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n * @param _length Length of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n ) internal pure returns (bytes memory) {\n unchecked {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_start + _length >= _start, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n }\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n /**\n * @notice Slices a byte array with a given starting index up to the end of the original byte\n * array. Returns a new array rathern than a pointer to the original.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\n if (_start >= _bytes.length) {\n return bytes(\"\");\n }\n return slice(_bytes, _start, _bytes.length - _start);\n }\n\n /**\n * @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.\n * Resulting nibble array will be exactly twice as long as the input byte array.\n *\n * @param _bytes Input byte array to convert.\n *\n * @return Resulting nibble array.\n */\n function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n uint256 bytesLength = _bytes.length;\n bytes memory nibbles = new bytes(bytesLength * 2);\n bytes1 b;\n\n for (uint256 i = 0; i < bytesLength; ) {\n b = _bytes[i];\n nibbles[i * 2] = b >> 4;\n nibbles[i * 2 + 1] = b & 0x0f;\n unchecked {\n ++i;\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Compares two byte arrays by comparing their keccak256 hashes.\n *\n * @param _bytes First byte array to compare.\n * @param _other Second byte array to compare.\n *\n * @return True if the two byte arrays are equal, false otherwise.\n */\n function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n return keccak256(_bytes) == keccak256(_other);\n }\n}\n" - }, - "contracts/libraries/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n/**\n * @title Constants\n * @notice Constants is a library for storing constants. Simple! Don't put everything in here, just\n * the stuff used in multiple contracts. Constants that only apply to a single contract\n * should be defined in that contract instead.\n */\nlibrary Constants {\n /**\n * @notice Special address to be used as the tx origin for gas estimation calls in the\n * OptimismPortal and CrossDomainMessenger calls. You only need to use this address if\n * the minimum gas limit specified by the user is not actually enough to execute the\n * given message and you're attempting to estimate the actual necessary gas limit. We\n * use address(1) because it's the ecrecover precompile and therefore guaranteed to\n * never have any code on any EVM chain.\n */\n address internal constant ESTIMATION_ADDRESS = address(1);\n\n /**\n * @notice Value used for the L2 sender storage slot in both the OptimismPortal and the\n * CrossDomainMessenger contracts before an actual sender is set. This value is\n * non-zero to reduce the gas cost of message passing transactions.\n */\n address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;\n\n /**\n * @notice Returns the default values for the ResourceConfig. These are the recommended values\n * for a production network.\n */\n function DEFAULT_RESOURCE_CONFIG()\n internal\n pure\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n return config;\n }\n}\n" - }, - "contracts/libraries/Encoding.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Hashing } from \"./Hashing.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\n\n/**\n * @title Encoding\n * @notice Encoding handles Optimism's various different encoding schemes.\n */\nlibrary Encoding {\n /**\n * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\n * to the L2 system. Useful for searching for a deposit in the L2 system. The\n * transaction is prefixed with 0x7e to identify its EIP-2718 type.\n *\n * @param _tx User deposit transaction to encode.\n *\n * @return RLP encoded L2 deposit transaction.\n */\n function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes memory)\n {\n bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\n bytes[] memory raw = new bytes[](8);\n raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\n raw[1] = RLPWriter.writeAddress(_tx.from);\n raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\"\") : RLPWriter.writeAddress(_tx.to);\n raw[3] = RLPWriter.writeUint(_tx.mint);\n raw[4] = RLPWriter.writeUint(_tx.value);\n raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\n raw[6] = RLPWriter.writeBool(false);\n raw[7] = RLPWriter.writeBytes(_tx.data);\n return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\n }\n\n /**\n * @notice Encodes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n (, uint16 version) = decodeVersionedNonce(_nonce);\n if (version == 0) {\n return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Encoding: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Encodes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _data,\n _nonce\n );\n }\n\n /**\n * @notice Encodes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(uint256,address,address,uint256,uint256,bytes)\",\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n }\n\n /**\n * @notice Adds a version number into the first two bytes of a message nonce.\n *\n * @param _nonce Message nonce to encode into.\n * @param _version Version number to encode into the message nonce.\n *\n * @return Message nonce with version encoded into the first two bytes.\n */\n function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\n uint256 nonce;\n assembly {\n nonce := or(shl(240, _version), _nonce)\n }\n return nonce;\n }\n\n /**\n * @notice Pulls the version out of a version-encoded nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n *\n * @return Nonce without encoded version.\n * @return Version of the message.\n */\n function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\n uint240 nonce;\n uint16 version;\n assembly {\n nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n version := shr(240, _nonce)\n }\n return (nonce, version);\n }\n}\n" - }, - "contracts/libraries/Hashing.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Encoding } from \"./Encoding.sol\";\n\n/**\n * @title Hashing\n * @notice Hashing handles Optimism's various different hashing schemes.\n */\nlibrary Hashing {\n /**\n * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\n * given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\n * system.\n *\n * @param _tx User deposit transaction to hash.\n *\n * @return Hash of the RLP encoded L2 deposit transaction.\n */\n function hashDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return keccak256(Encoding.encodeDepositTransaction(_tx));\n }\n\n /**\n * @notice Computes the deposit transaction's \"source hash\", a value that guarantees the hash\n * of the L2 transaction that corresponds to a deposit is unique and is\n * deterministically generated from L1 transaction data.\n *\n * @param _l1BlockHash Hash of the L1 block where the deposit was included.\n * @param _logIndex The index of the log that created the deposit transaction.\n *\n * @return Hash of the deposit transaction's \"source hash\".\n */\n function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)\n internal\n pure\n returns (bytes32)\n {\n bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\n return keccak256(abi.encode(bytes32(0), depositId));\n }\n\n /**\n * @notice Hashes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n if (version == 0) {\n return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Hashing: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Hashes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes32) {\n return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));\n }\n\n /**\n * @notice Hashes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n return\n keccak256(\n Encoding.encodeCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n )\n );\n }\n\n /**\n * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\n *\n * @param _tx Withdrawal transaction to hash.\n *\n * @return Hashed withdrawal transaction.\n */\n function hashWithdrawal(Types.WithdrawalTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\n );\n }\n\n /**\n * @notice Hashes the various elements of an output root proof into an output root hash which\n * can be used to check if the proof is valid.\n *\n * @param _outputRootProof Output root proof which should hash to an output root.\n *\n * @return Hashed output root proof.\n */\n function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(\n _outputRootProof.version,\n _outputRootProof.stateRoot,\n _outputRootProof.messagePasserStorageRoot,\n _outputRootProof.latestBlockhash\n )\n );\n }\n}\n" - }, - "contracts/libraries/LegacyCrossDomainUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n// Importing from the legacy contracts package causes issues with the build of the contract bindings\n// so we just copy the library here from\n// /packages/contracts/contracts/libraries/bridge/Lib_CrossDomainUtils.sol at commit\n// 7866168c\n/**\n * @title LegacyCrossDomainUtils\n */\nlibrary LegacyCrossDomainUtils {\n /**\n * Generates the correct cross domain calldata for a message.\n * @param _target Target contract address.\n * @param _sender Message sender address.\n * @param _message Message to send to the target.\n * @param _messageNonce Nonce for the provided message.\n * @return ABI encoded cross domain calldata.\n */\n function encodeXDomainCalldata(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _message,\n _messageNonce\n );\n }\n}\n" - }, - "contracts/libraries/Predeploys.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Predeploys\n * @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.\n */\nlibrary Predeploys {\n /**\n * @notice Address of the L2ToL1MessagePasser predeploy.\n */\n address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;\n\n /**\n * @notice Address of the L2CrossDomainMessenger predeploy.\n */\n address internal constant L2_CROSS_DOMAIN_MESSENGER =\n 0x4200000000000000000000000000000000000007;\n\n /**\n * @notice Address of the L2StandardBridge predeploy.\n */\n address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\n\n /**\n * @notice Address of the L2ERC721Bridge predeploy.\n */\n address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;\n\n /**\n * @notice Address of the SequencerFeeWallet predeploy.\n */\n address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;\n\n /**\n * @notice Address of the OptimismMintableERC20Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY =\n 0x4200000000000000000000000000000000000012;\n\n /**\n * @notice Address of the OptimismMintableERC721Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY =\n 0x4200000000000000000000000000000000000017;\n\n /**\n * @notice Address of the L1Block predeploy.\n */\n address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;\n\n /**\n * @notice Address of the GasPriceOracle predeploy. Includes fee information\n * and helpers for computing the L1 portion of the transaction fee.\n */\n address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;\n\n /**\n * @custom:legacy\n * @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger\n * or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.\n */\n address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\n\n /**\n * @custom:legacy\n * @notice Address of the DeployerWhitelist predeploy. No longer active.\n */\n address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the\n * state trie as of the Bedrock upgrade. Contract has been locked and write functions\n * can no longer be accessed.\n */\n address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;\n\n /**\n * @custom:legacy\n * @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy\n * instead, which exposes more information about the L1 state.\n */\n address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated\n * L2ToL1MessagePasser contract instead.\n */\n address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\n\n /**\n * @notice Address of the ProxyAdmin predeploy.\n */\n address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;\n\n /**\n * @notice Address of the BaseFeeVault predeploy.\n */\n address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;\n\n /**\n * @notice Address of the L1FeeVault predeploy.\n */\n address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;\n\n /**\n * @notice Address of the GovernanceToken predeploy.\n */\n address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042;\n}\n" - }, - "contracts/libraries/SafeCall.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title SafeCall\n * @notice Perform low level safe calls\n */\nlibrary SafeCall {\n /**\n * @notice Perform a low level call without copying any returndata\n *\n * @param _target Address to call\n * @param _gas Amount of gas to pass to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function call(\n address _target,\n uint256 _gas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n }\n return _success;\n }\n\n /**\n * @notice Perform a low level call without copying any returndata. This function\n * will revert if the call cannot be performed with the specified minimum\n * gas.\n *\n * @param _target Address to call\n * @param _minGas The minimum amount of gas that may be passed to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function callWithMinGas(\n address _target,\n uint256 _minGas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n // Assertion: gasleft() >= ((_minGas + 200) * 64) / 63\n //\n // Because EIP-150 ensures that, a maximum of 63/64ths of the remaining gas in the call\n // frame may be passed to a subcontext, we need to ensure that the gas will not be\n // truncated to hold this function's invariant: \"If a call is performed by\n // `callWithMinGas`, it must receive at least the specified minimum gas limit.\" In\n // addition, exactly 51 gas is consumed between the below `GAS` opcode and the `CALL`\n // opcode, so it is factored in with some extra room for error.\n if lt(gas(), div(mul(64, add(_minGas, 200)), 63)) {\n // Store the \"Error(string)\" selector in scratch space.\n mstore(0, 0x08c379a0)\n // Store the pointer to the string length in scratch space.\n mstore(32, 32)\n // Store the string.\n //\n // SAFETY:\n // - We pad the beginning of the string with two zero bytes as well as the\n // length (24) to ensure that we override the free memory pointer at offset\n // 0x40. This is necessary because the free memory pointer is likely to\n // be greater than 1 byte when this function is called, but it is incredibly\n // unlikely that it will be greater than 3 bytes. As for the data within\n // 0x60, it is ensured that it is 0 due to 0x60 being the zero offset.\n // - It's fine to clobber the free memory pointer, we're reverting.\n mstore(88, 0x0000185361666543616c6c3a204e6f7420656e6f75676820676173)\n\n // Revert with 'Error(\"SafeCall: Not enough gas\")'\n revert(28, 100)\n }\n\n // The call will be supplied at least (((_minGas + 200) * 64) / 63) - 49 gas due to the\n // above assertion. This ensures that, in all circumstances, the call will\n // receive at least the minimum amount of gas specified.\n // We can prove this property by solving the inequalities:\n // ((((_minGas + 200) * 64) / 63) - 49) >= _minGas\n // ((((_minGas + 200) * 64) / 63) - 51) * (63 / 64) >= _minGas\n // Both inequalities hold true for all possible values of `_minGas`.\n _success := call(\n gas(), // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0x00, // outloc\n 0x00 // outlen\n )\n }\n return _success;\n }\n}\n" - }, - "contracts/libraries/Types.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Types\n * @notice Contains various types used throughout the Optimism contract system.\n */\nlibrary Types {\n /**\n * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\n * timestamp that the output root is posted. This timestamp is used to verify that the\n * finalization period has passed since the output root was submitted.\n *\n * @custom:field outputRoot Hash of the L2 output.\n * @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.\n * @custom:field l2BlockNumber L2 block number that the output corresponds to.\n */\n struct OutputProposal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2BlockNumber;\n }\n\n /**\n * @notice Struct representing the elements that are hashed together to generate an output root\n * which itself represents a snapshot of the L2 state.\n *\n * @custom:field version Version of the output root.\n * @custom:field stateRoot Root of the state trie at the block of this output.\n * @custom:field messagePasserStorageRoot Root of the message passer storage trie.\n * @custom:field latestBlockhash Hash of the block this output was generated from.\n */\n struct OutputRootProof {\n bytes32 version;\n bytes32 stateRoot;\n bytes32 messagePasserStorageRoot;\n bytes32 latestBlockhash;\n }\n\n /**\n * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n * user (as opposed to a system deposit transaction generated by the system).\n *\n * @custom:field from Address of the sender of the transaction.\n * @custom:field to Address of the recipient of the transaction.\n * @custom:field isCreation True if the transaction is a contract creation.\n * @custom:field value Value to send to the recipient.\n * @custom:field mint Amount of ETH to mint.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n * @custom:field l1BlockHash Hash of the block the transaction was submitted in.\n * @custom:field logIndex Index of the log in the block the transaction was submitted in.\n */\n struct UserDepositTransaction {\n address from;\n address to;\n bool isCreation;\n uint256 value;\n uint256 mint;\n uint64 gasLimit;\n bytes data;\n bytes32 l1BlockHash;\n uint256 logIndex;\n }\n\n /**\n * @notice Struct representing a withdrawal transaction.\n *\n * @custom:field nonce Nonce of the withdrawal transaction\n * @custom:field sender Address of the sender of the transaction.\n * @custom:field target Address of the recipient of the transaction.\n * @custom:field value Value to send to the recipient.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n */\n struct WithdrawalTransaction {\n uint256 nonce;\n address sender;\n address target;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPReader.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\n/**\n * @custom:attribution https://github.com/hamdiallam/Solidity-RLP\n * @title RLPReader\n * @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted\n * from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with\n * various tweaks to improve readability.\n */\nlibrary RLPReader {\n /**\n * Custom pointer type to avoid confusion between pointers and uint256s.\n */\n type MemoryPointer is uint256;\n\n /**\n * @notice RLP item types.\n *\n * @custom:value DATA_ITEM Represents an RLP data item (NOT a list).\n * @custom:value LIST_ITEM Represents an RLP list item.\n */\n enum RLPItemType {\n DATA_ITEM,\n LIST_ITEM\n }\n\n /**\n * @notice Struct representing an RLP item.\n *\n * @custom:field length Length of the RLP item.\n * @custom:field ptr Pointer to the RLP item in memory.\n */\n struct RLPItem {\n uint256 length;\n MemoryPointer ptr;\n }\n\n /**\n * @notice Max list length that this library will accept.\n */\n uint256 internal constant MAX_LIST_LENGTH = 32;\n\n /**\n * @notice Converts bytes to a reference to memory position and length.\n *\n * @param _in Input bytes to convert.\n *\n * @return Output memory reference.\n */\n function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n // Empty arrays are not RLP items.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr;\n assembly {\n ptr := add(_in, 32)\n }\n\n return RLPItem({ length: _in.length, ptr: ptr });\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.LIST_ITEM,\n \"RLPReader: decoded item type for list is not a list item\"\n );\n\n require(\n listOffset + listLength == _in.length,\n \"RLPReader: list item has an invalid data remainder\"\n );\n\n // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n // writing to the length. Since we can't know the number of RLP items without looping over\n // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n // simply set a reasonable maximum list length and decrease the size before we finish.\n RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n uint256 itemCount = 0;\n uint256 offset = listOffset;\n while (offset < _in.length) {\n (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n RLPItem({\n length: _in.length - offset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n })\n );\n\n // We don't need to check itemCount < out.length explicitly because Solidity already\n // handles this check on our behalf, we'd just be wasting gas.\n out[itemCount] = RLPItem({\n length: itemLength + itemOffset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n });\n\n itemCount += 1;\n offset += itemOffset + itemLength;\n }\n\n // Decrease the array size to match the actual item count.\n assembly {\n mstore(out, itemCount)\n }\n\n return out;\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n return readList(toRLPItem(_in));\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.DATA_ITEM,\n \"RLPReader: decoded item type for bytes is not a data item\"\n );\n\n require(\n _in.length == itemOffset + itemLength,\n \"RLPReader: bytes value contains an invalid remainder\"\n );\n\n return _copy(_in.ptr, itemOffset, itemLength);\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n return readBytes(toRLPItem(_in));\n }\n\n /**\n * @notice Reads the raw bytes of an RLP item.\n *\n * @param _in RLP item to read.\n *\n * @return Raw RLP bytes.\n */\n function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n return _copy(_in.ptr, 0, _in.length);\n }\n\n /**\n * @notice Decodes the length of an RLP item.\n *\n * @param _in RLP item to decode.\n *\n * @return Offset of the encoded data.\n * @return Length of the encoded data.\n * @return RLP item type (LIST_ITEM or DATA_ITEM).\n */\n function _decodeLength(RLPItem memory _in)\n private\n pure\n returns (\n uint256,\n uint256,\n RLPItemType\n )\n {\n // Short-circuit if there's nothing to decode, note that we perform this check when\n // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass\n // that function and create an RLP item directly. So we need to check this anyway.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr = _in.ptr;\n uint256 prefix;\n assembly {\n prefix := byte(0, mload(ptr))\n }\n\n if (prefix <= 0x7f) {\n // Single byte.\n return (0, 1, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xb7) {\n // Short string.\n\n // slither-disable-next-line variable-scope\n uint256 strLen = prefix - 0x80;\n\n require(\n _in.length > strLen,\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n strLen != 1 || firstByteOfContent >= 0x80,\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n\n return (1, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xbf) {\n // Long string.\n uint256 lenOfStrLen = prefix - 0xb7;\n\n require(\n _in.length > lenOfStrLen,\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n\n uint256 strLen;\n assembly {\n strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))\n }\n\n require(\n strLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long string)\"\n );\n\n require(\n _in.length > lenOfStrLen + strLen,\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n\n return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xf7) {\n // Short list.\n // slither-disable-next-line variable-scope\n uint256 listLen = prefix - 0xc0;\n\n require(\n _in.length > listLen,\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n\n return (1, listLen, RLPItemType.LIST_ITEM);\n } else {\n // Long list.\n uint256 lenOfListLen = prefix - 0xf7;\n\n require(\n _in.length > lenOfListLen,\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long list)\"\n );\n\n uint256 listLen;\n assembly {\n listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))\n }\n\n require(\n listLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long list)\"\n );\n\n require(\n _in.length > lenOfListLen + listLen,\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n\n return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n }\n }\n\n /**\n * @notice Copies the bytes from a memory location.\n *\n * @param _src Pointer to the location to read from.\n * @param _offset Offset to start reading from.\n * @param _length Number of bytes to read.\n *\n * @return Copied bytes.\n */\n function _copy(\n MemoryPointer _src,\n uint256 _offset,\n uint256 _length\n ) private pure returns (bytes memory) {\n bytes memory out = new bytes(_length);\n if (_length == 0) {\n return out;\n }\n\n // Mostly based on Solidity's copy_memory_to_memory:\n // solhint-disable max-line-length\n // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114\n uint256 src = MemoryPointer.unwrap(_src) + _offset;\n assembly {\n let dest := add(out, 32)\n let i := 0\n for {\n\n } lt(i, _length) {\n i := add(i, 32)\n } {\n mstore(add(dest, i), mload(add(src, i)))\n }\n\n if gt(i, _length) {\n mstore(add(dest, _length), 0)\n }\n }\n\n return out;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPWriter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\n * @title RLPWriter\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\n * RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\n * modifications to improve legibility.\n */\nlibrary RLPWriter {\n /**\n * @notice RLP encodes a byte string.\n *\n * @param _in The byte string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_in.length == 1 && uint8(_in[0]) < 128) {\n encoded = _in;\n } else {\n encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n }\n\n return encoded;\n }\n\n /**\n * @notice RLP encodes a list of RLP encoded byte byte strings.\n *\n * @param _in The list of RLP encoded byte strings.\n *\n * @return The RLP encoded list of items in bytes.\n */\n function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n bytes memory list = _flatten(_in);\n return abi.encodePacked(_writeLength(list.length, 192), list);\n }\n\n /**\n * @notice RLP encodes a string.\n *\n * @param _in The string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeString(string memory _in) internal pure returns (bytes memory) {\n return writeBytes(bytes(_in));\n }\n\n /**\n * @notice RLP encodes an address.\n *\n * @param _in The address to encode.\n *\n * @return The RLP encoded address in bytes.\n */\n function writeAddress(address _in) internal pure returns (bytes memory) {\n return writeBytes(abi.encodePacked(_in));\n }\n\n /**\n * @notice RLP encodes a uint.\n *\n * @param _in The uint256 to encode.\n *\n * @return The RLP encoded uint256 in bytes.\n */\n function writeUint(uint256 _in) internal pure returns (bytes memory) {\n return writeBytes(_toBinary(_in));\n }\n\n /**\n * @notice RLP encodes a bool.\n *\n * @param _in The bool to encode.\n *\n * @return The RLP encoded bool in bytes.\n */\n function writeBool(bool _in) internal pure returns (bytes memory) {\n bytes memory encoded = new bytes(1);\n encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n return encoded;\n }\n\n /**\n * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\n *\n * @param _len The length of the string or the payload.\n * @param _offset 128 if item is string, 192 if item is list.\n *\n * @return RLP encoded bytes.\n */\n function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_len < 56) {\n encoded = new bytes(1);\n encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n } else {\n uint256 lenLen;\n uint256 i = 1;\n while (_len / i != 0) {\n lenLen++;\n i *= 256;\n }\n\n encoded = new bytes(lenLen + 1);\n encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n for (i = 1; i <= lenLen; i++) {\n encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n }\n }\n\n return encoded;\n }\n\n /**\n * @notice Encode integer in big endian binary form with no leading zeroes.\n *\n * @param _x The integer to encode.\n *\n * @return RLP encoded bytes.\n */\n function _toBinary(uint256 _x) private pure returns (bytes memory) {\n bytes memory b = abi.encodePacked(_x);\n\n uint256 i = 0;\n for (; i < 32; i++) {\n if (b[i] != 0) {\n break;\n }\n }\n\n bytes memory res = new bytes(32 - i);\n for (uint256 j = 0; j < res.length; j++) {\n res[j] = b[i++];\n }\n\n return res;\n }\n\n /**\n * @custom:attribution https://github.com/Arachnid/solidity-stringutils\n * @notice Copies a piece of memory to another location.\n *\n * @param _dest Destination location.\n * @param _src Source location.\n * @param _len Length of memory to copy.\n */\n function _memcpy(\n uint256 _dest,\n uint256 _src,\n uint256 _len\n ) private pure {\n uint256 dest = _dest;\n uint256 src = _src;\n uint256 len = _len;\n\n for (; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n uint256 mask;\n unchecked {\n mask = 256**(32 - len) - 1;\n }\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /**\n * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\n * @notice Flattens a list of byte strings into one byte string.\n *\n * @param _list List of byte strings to flatten.\n *\n * @return The flattened byte string.\n */\n function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n if (_list.length == 0) {\n return new bytes(0);\n }\n\n uint256 len;\n uint256 i = 0;\n for (; i < _list.length; i++) {\n len += _list[i].length;\n }\n\n bytes memory flattened = new bytes(len);\n uint256 flattenedPtr;\n assembly {\n flattenedPtr := add(flattened, 0x20)\n }\n\n for (i = 0; i < _list.length; i++) {\n bytes memory item = _list[i];\n\n uint256 listPtr;\n assembly {\n listPtr := add(item, 0x20)\n }\n\n _memcpy(flattenedPtr, listPtr, item.length);\n flattenedPtr += _list[i].length;\n }\n\n return flattened;\n }\n}\n" - }, - "contracts/libraries/trie/MerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Bytes } from \"../Bytes.sol\";\nimport { RLPReader } from \"../rlp/RLPReader.sol\";\n\n/**\n * @title MerkleTrie\n * @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie\n * inclusion proofs. By default, this library assumes a hexary trie. One can change the\n * trie radix constant to support other trie radixes.\n */\nlibrary MerkleTrie {\n /**\n * @notice Struct representing a node in the trie.\n *\n * @custom:field encoded The RLP-encoded node.\n * @custom:field decoded The RLP-decoded node.\n */\n struct TrieNode {\n bytes encoded;\n RLPReader.RLPItem[] decoded;\n }\n\n /**\n * @notice Determines the number of elements per branch node.\n */\n uint256 internal constant TREE_RADIX = 16;\n\n /**\n * @notice Branch nodes have TREE_RADIX elements and one value element.\n */\n uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\n\n /**\n * @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.\n */\n uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\n\n /**\n * @notice Prefix for even-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_EVEN = 0;\n\n /**\n * @notice Prefix for odd-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_ODD = 1;\n\n /**\n * @notice Prefix for even-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_EVEN = 2;\n\n /**\n * @notice Prefix for odd-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_ODD = 3;\n\n /**\n * @notice Verifies a proof that a given key/value pair is present in the trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n return Bytes.equal(_value, get(_key, _proof, _root));\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n require(_key.length > 0, \"MerkleTrie: empty key\");\n\n TrieNode[] memory proof = _parseProof(_proof);\n bytes memory key = Bytes.toNibbles(_key);\n bytes memory currentNodeID = abi.encodePacked(_root);\n uint256 currentKeyIndex = 0;\n\n // Proof is top-down, so we start at the first element (root).\n for (uint256 i = 0; i < proof.length; i++) {\n TrieNode memory currentNode = proof[i];\n\n // Key index should never exceed total key length or we'll be out of bounds.\n require(\n currentKeyIndex <= key.length,\n \"MerkleTrie: key index exceeds total key length\"\n );\n\n if (currentKeyIndex == 0) {\n // First proof element is always the root node.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid root hash\"\n );\n } else if (currentNode.encoded.length >= 32) {\n // Nodes 32 bytes or larger are hashed inside branch nodes.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid large internal hash\"\n );\n } else {\n // Nodes smaller than 32 bytes aren't hashed.\n require(\n Bytes.equal(currentNode.encoded, currentNodeID),\n \"MerkleTrie: invalid internal node hash\"\n );\n }\n\n if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\n if (currentKeyIndex == key.length) {\n // Value is the last element of the decoded list (for branch nodes). There's\n // some ambiguity in the Merkle trie specification because bytes(0) is a\n // valid value to place into the trie, but for branch nodes bytes(0) can exist\n // even when the value wasn't explicitly placed there. Geth treats a value of\n // bytes(0) as \"key does not exist\" and so we do the same.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (branch)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (branch)\"\n );\n\n return value;\n } else {\n // We're not at the end of the key yet.\n // Figure out what the next node ID should be and continue.\n uint8 branchKey = uint8(key[currentKeyIndex]);\n RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\n currentNodeID = _getNodeID(nextNode);\n currentKeyIndex += 1;\n }\n } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\n bytes memory path = _getNodePath(currentNode);\n uint8 prefix = uint8(path[0]);\n uint8 offset = 2 - (prefix % 2);\n bytes memory pathRemainder = Bytes.slice(path, offset);\n bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);\n uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\n\n // Whether this is a leaf node or an extension node, the path remainder MUST be a\n // prefix of the key remainder (or be equal to the key remainder) or the proof is\n // considered invalid.\n require(\n pathRemainder.length == sharedNibbleLength,\n \"MerkleTrie: path remainder must share all nibbles with key\"\n );\n\n if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\n // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid,\n // the key remainder must be exactly equal to the path remainder. We already\n // did the necessary byte comparison, so it's more efficient here to check that\n // the key remainder length equals the shared nibble length, which implies\n // equality with the path remainder (since we already did the same check with\n // the path remainder and the shared nibble length).\n require(\n keyRemainder.length == sharedNibbleLength,\n \"MerkleTrie: key remainder must be identical to path remainder\"\n );\n\n // Our Merkle Trie is designed specifically for the purposes of the Ethereum\n // state trie. Empty values are not allowed in the state trie, so we can safely\n // say that if the value is empty, the key should not exist and the proof is\n // invalid.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[1]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (leaf)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (leaf)\"\n );\n\n return value;\n } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\n // Prefix of 0 or 1 means this is an extension node. We move onto the next node\n // in the proof and increment the key index by the length of the path remainder\n // which is equal to the shared nibble length.\n currentNodeID = _getNodeID(currentNode.decoded[1]);\n currentKeyIndex += sharedNibbleLength;\n } else {\n revert(\"MerkleTrie: received a node with an unknown prefix\");\n }\n } else {\n revert(\"MerkleTrie: received an unparseable node\");\n }\n }\n\n revert(\"MerkleTrie: ran out of proof elements\");\n }\n\n /**\n * @notice Parses an array of proof elements into a new array that contains both the original\n * encoded element and the RLP-decoded element.\n *\n * @param _proof Array of proof elements to parse.\n *\n * @return Proof parsed into easily accessible structs.\n */\n function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {\n uint256 length = _proof.length;\n TrieNode[] memory proof = new TrieNode[](length);\n for (uint256 i = 0; i < length; ) {\n proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });\n unchecked {\n ++i;\n }\n }\n return proof;\n }\n\n /**\n * @notice Picks out the ID for a node. Node ID is referred to as the \"hash\" within the\n * specification, but nodes < 32 bytes are not actually hashed.\n *\n * @param _node Node to pull an ID for.\n *\n * @return ID for the node, depending on the size of its contents.\n */\n function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {\n return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);\n }\n\n /**\n * @notice Gets the path for a leaf or extension node.\n *\n * @param _node Node to get a path for.\n *\n * @return Node path, converted to an array of nibbles.\n */\n function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {\n return Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0]));\n }\n\n /**\n * @notice Utility; determines the number of nibbles shared between two nibble arrays.\n *\n * @param _a First nibble array.\n * @param _b Second nibble array.\n *\n * @return Number of shared nibbles.\n */\n function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\n private\n pure\n returns (uint256)\n {\n uint256 shared;\n uint256 max = (_a.length < _b.length) ? _a.length : _b.length;\n for (; shared < max && _a[shared] == _b[shared]; ) {\n unchecked {\n ++shared;\n }\n }\n return shared;\n }\n}\n" - }, - "contracts/libraries/trie/SecureMerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/* Library Imports */\nimport { MerkleTrie } from \"./MerkleTrie.sol\";\n\n/**\n * @title SecureMerkleTrie\n * @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input\n * keys. Ethereum's state trie hashes input keys before storing them.\n */\nlibrary SecureMerkleTrie {\n /**\n * @notice Verifies a proof that a given key/value pair is present in the Merkle trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.get(key, _proof, _root);\n }\n\n /**\n * @notice Computes the hashed version of the input key.\n *\n * @param _key Key to hash.\n *\n * @return Hashed version of the key.\n */\n function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {\n return abi.encodePacked(keccak256(_key));\n }\n}\n" - }, - "contracts/periphery/TransferOnion.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title TransferOnion\n * @notice TransferOnion is a hash onion for distributing tokens. The shell commits\n * to an ordered list of the token transfers and can be permissionlessly\n * unwrapped in order. The SENDER must `approve` this contract as\n * `transferFrom` is used to move the token balances.\n */\ncontract TransferOnion is ReentrancyGuard {\n using SafeERC20 for ERC20;\n\n /**\n * @notice Struct representing a layer of the onion.\n */\n struct Layer {\n address recipient;\n uint256 amount;\n bytes32 shell;\n }\n\n /**\n * @notice Address of the token to distribute.\n */\n ERC20 public immutable TOKEN;\n\n /**\n * @notice Address of the account to distribute tokens from.\n */\n address public immutable SENDER;\n\n /**\n * @notice Current shell hash.\n */\n bytes32 public shell;\n\n /**\n * @param _token Address of the token to distribute.\n * @param _sender Address of the sender to distribute from.\n * @param _shell Initial shell of the onion.\n */\n constructor(\n ERC20 _token,\n address _sender,\n bytes32 _shell\n ) {\n TOKEN = _token;\n SENDER = _sender;\n shell = _shell;\n }\n\n /**\n * @notice Peels layers from the onion and distributes tokens.\n *\n * @param _layers Array of onion layers to peel.\n */\n function peel(Layer[] memory _layers) public nonReentrant {\n bytes32 tempShell = shell;\n uint256 length = _layers.length;\n for (uint256 i = 0; i < length; ) {\n Layer memory layer = _layers[i];\n\n // Confirm that the onion layer is correct.\n require(\n keccak256(abi.encode(layer.recipient, layer.amount, layer.shell)) == tempShell,\n \"TransferOnion: what are you doing in my swamp?\"\n );\n\n // Update the onion layer.\n tempShell = layer.shell;\n\n // Transfer the tokens.\n TOKEN.safeTransferFrom(SENDER, layer.recipient, layer.amount);\n\n // Unchecked increment to save some gas.\n unchecked {\n ++i;\n }\n }\n\n shell = tempShell;\n }\n}\n" - }, - "contracts/test/AddressAliasHelper.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract AddressAliasHelper_applyAndUndo_Test is Test {\n /**\n * @notice Tests that applying and then undoing an alias results in the original address.\n */\n function testFuzz_applyAndUndo_succeeds(address _address) external {\n address aliased = AddressAliasHelper.applyL1ToL2Alias(_address);\n address unaliased = AddressAliasHelper.undoL1ToL2Alias(aliased);\n assertEq(_address, unaliased);\n }\n}\n" - }, - "contracts/test/BenchmarkTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test } from \"forge-std/Test.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport \"./CommonTest.t.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n// Free function for setting the prevBaseFee param in the OptimismPortal.\nfunction setPrevBaseFee(\n Vm _vm,\n address _op,\n uint128 _prevBaseFee\n) {\n _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee));\n}\n\ncontract SetPrevBaseFee_Test is Portal_Initializer {\n function test_setPrevBaseFee_succeeds() external {\n setPrevBaseFee(vm, address(op), 100 gwei);\n (uint128 prevBaseFee, , uint64 prevBlockNum) = op.params();\n assertEq(uint256(prevBaseFee), 100 gwei);\n assertEq(uint256(prevBlockNum), block.number);\n }\n}\n\n// Tests for obtaining pure gas cost estimates for commonly used functions.\n// The objective with these benchmarks is to strip down the actual test functions\n// so that they are nothing more than the call we want measure the gas cost of.\n// In order to achieve this we make no assertions, and handle everything else in the setUp()\n// function.\ncontract GasBenchMark_OptimismPortal is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n bytes32 _outputRoot;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n\n // Get withdrawal proof data we can use for testing.\n bytes32 _storageRoot;\n bytes32 _stateRoot;\n (_stateRoot, _storageRoot, _outputRoot, , _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public virtual override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n function test_depositTransaction_benchmark() external {\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_depositTransaction_benchmark_1() external {\n setPrevBaseFee(vm, address(op), 1 gwei);\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_proveWithdrawalTransaction_benchmark() external {\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n}\n\ncontract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {\n function test_sendMessage_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n\n function test_sendMessage_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), alice, 100000, true);\n vm.startPrank(alice, alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n }\n\n function test_depositETH_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositETH_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositERC20_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n\n function test_depositERC20_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), address(L1Bridge), 100, true);\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.startPrank(address(L1Bridge.messenger()));\n vm.deal(address(L1Bridge.messenger()), 100);\n }\n\n function test_finalizeETHWithdrawal_benchmark() external {\n // TODO: Make this more accurate. It is underestimating the cost because it pranks\n // the call coming from the messenger, which bypasses the portal\n // and oracle.\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer {\n uint256 nextBlockNumber;\n\n function setUp() public override {\n super.setUp();\n nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.startPrank(proposer);\n }\n\n function test_proposeL2Output_benchmark() external {\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n}\n" - }, - "contracts/test/Bytes.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Bytes } from \"../libraries/Bytes.sol\";\n\ncontract Bytes_slice_Test is Test {\n /**\n * @notice Tests that the `slice` function works as expected when starting from index 0.\n */\n function test_slice_fromZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check if all possible slices starting from index 0 are correct.\n assertEq(Bytes.slice(input, 0, 0), hex\"\");\n assertEq(Bytes.slice(input, 0, 1), hex\"11\");\n assertEq(Bytes.slice(input, 0, 2), hex\"1122\");\n assertEq(Bytes.slice(input, 0, 3), hex\"112233\");\n assertEq(Bytes.slice(input, 0, 4), hex\"11223344\");\n assertEq(Bytes.slice(input, 0, 5), hex\"1122334455\");\n assertEq(Bytes.slice(input, 0, 6), hex\"112233445566\");\n assertEq(Bytes.slice(input, 0, 7), hex\"11223344556677\");\n assertEq(Bytes.slice(input, 0, 8), hex\"1122334455667788\");\n assertEq(Bytes.slice(input, 0, 9), hex\"112233445566778899\");\n assertEq(Bytes.slice(input, 0, 10), hex\"11223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when starting from indices [1, 9]\n * with lengths [1, 9], in reverse order.\n */\n function test_slice_fromNonZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check correctness of slices starting from indexes [1, 9]\n // and spanning [1, 9] bytes, in reverse order\n assertEq(Bytes.slice(input, 9, 1), hex\"00\");\n assertEq(Bytes.slice(input, 8, 2), hex\"9900\");\n assertEq(Bytes.slice(input, 7, 3), hex\"889900\");\n assertEq(Bytes.slice(input, 6, 4), hex\"77889900\");\n assertEq(Bytes.slice(input, 5, 5), hex\"6677889900\");\n assertEq(Bytes.slice(input, 4, 6), hex\"556677889900\");\n assertEq(Bytes.slice(input, 3, 7), hex\"44556677889900\");\n assertEq(Bytes.slice(input, 2, 8), hex\"3344556677889900\");\n assertEq(Bytes.slice(input, 1, 9), hex\"223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple words\n * in memory. In this case, we test that a 2 byte slice between the 32nd byte of the\n * first word and the 1st byte of the second word is correct.\n */\n function test_slice_acrossWords_works() public {\n bytes\n memory input = hex\"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000\";\n\n assertEq(Bytes.slice(input, 31, 2), hex\"1122\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple\n * words in memory. In this case, we test that a 34 byte slice between 3 separate words\n * returns the correct result.\n */\n function test_slice_acrossMultipleWords_works() public {\n bytes\n memory input = hex\"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000\";\n bytes\n memory expected = hex\"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11\";\n\n assertEq(Bytes.slice(input, 31, 34), expected);\n }\n\n /**\n * @notice Tests that, when given an input bytes array of length `n`, the `slice` function will\n * always revert if `_start + _length > n`.\n */\n function testFuzz_slice_outOfBounds_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // We want a valid start index and a length that will not overflow.\n vm.assume(_start < _input.length && _length < type(uint256).max - 31);\n // But, we want an invalid slice length.\n vm.assume(_start + _length > _input.length);\n\n vm.expectRevert(\"slice_outOfBounds\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,\n * the `slice` function reverts.\n */\n function testFuzz_slice_lengthOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that the `_length` will overflow if a number >= 31 is added to it.\n vm.assume(_length > type(uint256).max - 31);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a start index `n` that is greater than\n * `type(uint256).max - n`, the `slice` function reverts.\n */\n function testFuzz_slice_rangeOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that `_length` is a realistic length of a slice. This is to make sure\n // we revert on the correct require statement.\n vm.assume(_length < _input.length);\n // Ensure that `_start` will overflow if `_length` is added to it.\n vm.assume(_start > type(uint256).max - _length);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that the `slice` function correctly updates the free memory pointer depending\n * on the length of the slice.\n */\n function testFuzz_slice_memorySafety_succeeds(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // The start should never be more than the length of the input bytes array - 1\n vm.assume(_start < _input.length);\n // The length should never be more than the length of the input bytes array - the starting\n // slice index.\n vm.assume(_length <= _input.length - _start);\n\n // Grab the free memory pointer before the slice operation\n uint64 initPtr;\n assembly {\n initPtr := mload(0x40)\n }\n uint64 expectedPtr = uint64(initPtr + 0x20 + ((_length + 0x1f) & ~uint256(0x1f)));\n\n // Ensure that all memory outside of the expected range is safe.\n vm.expectSafeMemory(initPtr, expectedPtr);\n\n // Slice the input bytes array from `_start` to `_start + _length`\n bytes memory slice = Bytes.slice(_input, _start, _length);\n\n // Grab the free memory pointer after the slice operation\n uint64 finalPtr;\n assembly {\n finalPtr := mload(0x40)\n }\n\n // The free memory pointer should have been updated properly\n if (_length == 0) {\n // If the slice length is zero, only 32 bytes of memory should have been allocated.\n assertEq(finalPtr, initPtr + 0x20);\n } else {\n // If the slice length is greater than zero, the memory allocated should be the\n // length of the slice rounded up to the next 32 byte word + 32 bytes for the\n // length of the byte array.\n //\n // Note that we use a slightly less efficient, but equivalent method of rounding\n // up `_length` to the next multiple of 32 than is used in the `slice` function.\n // This is to diff test the method used in `slice`.\n uint64 _expectedPtr = uint64(initPtr + 0x20 + (((_length + 0x1F) >> 5) << 5));\n assertEq(finalPtr, _expectedPtr);\n\n // Sanity check for equivalence of the rounding methods.\n assertEq(_expectedPtr, expectedPtr);\n }\n\n // The slice length should be equal to `_length`\n assertEq(slice.length, _length);\n }\n}\n\ncontract Bytes_toNibbles_Test is Test {\n /**\n * @notice Diffs the test Solidity version of `toNibbles` against the Yul version.\n *\n * @param _bytes The `bytes` array to convert to nibbles.\n *\n * @return Yul version of `toNibbles` applied to `_bytes`.\n */\n function _toNibblesYul(bytes memory _bytes) internal pure returns (bytes memory) {\n // Allocate memory for the `nibbles` array.\n bytes memory nibbles = new bytes(_bytes.length << 1);\n\n assembly {\n // Load the length of the passed bytes array from memory\n let bytesLength := mload(_bytes)\n\n // Store the memory offset of the _bytes array's contents on the stack\n let bytesStart := add(_bytes, 0x20)\n\n // Store the memory offset of the nibbles array's contents on the stack\n let nibblesStart := add(nibbles, 0x20)\n\n // Loop through each byte in the input array\n for {\n let i := 0x00\n } lt(i, bytesLength) {\n i := add(i, 0x01)\n } {\n // Get the starting offset of the next 2 bytes in the nibbles array\n let offset := add(nibblesStart, shl(0x01, i))\n\n // Load the byte at the current index within the `_bytes` array\n let b := byte(0x00, mload(add(bytesStart, i)))\n\n // Pull out the first nibble and store it in the new array\n mstore8(offset, shr(0x04, b))\n // Pull out the second nibble and store it in the new array\n mstore8(add(offset, 0x01), and(b, 0x0F))\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Tests that, given an input of 5 bytes, the `toNibbles` function returns an array of\n * 10 nibbles corresponding to the input data.\n */\n function test_toNibbles_expectedResult5Bytes_works() public {\n bytes memory input = hex\"1234567890\";\n bytes memory expected = hex\"01020304050607080900\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 128 bytes, the `toNibbles` function returns an array\n * of 256 nibbles corresponding to the input data. This test exists to ensure that,\n * given a large input, the `toNibbles` function works as expected.\n */\n function test_toNibbles_expectedResult128Bytes_works() public {\n bytes\n memory input = hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f\";\n bytes\n memory expected = hex\"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 0 bytes, the `toNibbles` function returns a zero\n * length array.\n */\n function test_toNibbles_zeroLengthInput_works() public {\n bytes memory input = hex\"\";\n bytes memory expected = hex\"\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length, 0);\n assertEq(expected.length, 0);\n assertEq(actual.length, 0);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Test that the `toNibbles` function in the `Bytes` library is equivalent to the Yul\n * implementation.\n */\n function testDiff_toNibbles_succeeds(bytes memory _input) public {\n assertEq(Bytes.toNibbles(_input), _toNibblesYul(_input));\n }\n}\n\ncontract Bytes_equal_Test is Test {\n /**\n * @notice Manually checks equality of two dynamic `bytes` arrays in memory.\n *\n * @param _a The first `bytes` array to compare.\n * @param _b The second `bytes` array to compare.\n *\n * @return True if the two `bytes` arrays are equal in memory.\n */\n function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) {\n bool _eq;\n assembly {\n _eq := and(\n // Check if the contents of the two bytes arrays are equal in memory.\n eq(keccak256(add(0x20, _a), mload(_a)), keccak256(add(0x20, _b), mload(_b))),\n // Check if the length of the two bytes arrays are equal in memory.\n // This is redundant given the above check, but included for completeness.\n eq(mload(_a), mload(_b))\n )\n }\n return _eq;\n }\n\n /**\n * @notice Tests that the `equal` function in the `Bytes` library returns `false` if given two\n * non-equal byte arrays.\n */\n function testFuzz_equal_notEqual_works(bytes memory _a, bytes memory _b) public {\n vm.assume(!manualEq(_a, _b));\n assertFalse(Bytes.equal(_a, _b));\n }\n\n /**\n * @notice Test whether or not the `equal` function in the `Bytes` library is equivalent to\n * manually checking equality of the two dynamic `bytes` arrays in memory.\n */\n function testDiff_equal_works(bytes memory _a, bytes memory _b) public {\n assertEq(Bytes.equal(_a, _b), manualEq(_a, _b));\n }\n}\n" - }, - "contracts/test/CommonTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test, StdUtils } from \"forge-std/Test.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { IL1ChugSplashDeployer } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { LegacyMintableERC20 } from \"../legacy/LegacyMintableERC20.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract CommonTest is Test {\n address alice = address(128);\n address bob = address(256);\n address multisig = address(512);\n\n address immutable ZERO_ADDRESS = address(0);\n address immutable NON_ZERO_ADDRESS = address(1);\n uint256 immutable NON_ZERO_VALUE = 100;\n uint256 immutable ZERO_VALUE = 0;\n uint64 immutable NON_ZERO_GASLIMIT = 50000;\n bytes32 nonZeroHash = keccak256(abi.encode(\"NON_ZERO\"));\n bytes NON_ZERO_DATA = hex\"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000\";\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n FFIInterface ffi;\n\n function setUp() public virtual {\n // Give alice and bob some ETH\n vm.deal(alice, 1 << 16);\n vm.deal(bob, 1 << 16);\n vm.deal(multisig, 1 << 16);\n\n vm.label(alice, \"alice\");\n vm.label(bob, \"bob\");\n vm.label(multisig, \"multisig\");\n\n // Make sure we have a non-zero base fee\n vm.fee(1000000000);\n\n ffi = new FFIInterface();\n }\n\n function emitTransactionDeposited(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) internal {\n emit TransactionDeposited(\n _from,\n _to,\n 0,\n abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)\n );\n }\n}\n\ncontract L2OutputOracle_Initializer is CommonTest {\n // Test target\n L2OutputOracle oracle;\n L2OutputOracle oracleImpl;\n\n L2ToL1MessagePasser messagePasser =\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));\n\n // Constructor arguments\n address internal proposer = 0x000000000000000000000000000000000000AbBa;\n address internal owner = 0x000000000000000000000000000000000000ACDC;\n uint256 internal submissionInterval = 1800;\n uint256 internal l2BlockTime = 2;\n uint256 internal startingBlockNumber = 200;\n uint256 internal startingTimestamp = 1000;\n address guardian;\n\n // Test data\n uint256 initL1Time;\n\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n // Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output\n function warpToProposeTime(uint256 _nextBlockNumber) public {\n vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1);\n }\n\n function setUp() public virtual override {\n super.setUp();\n guardian = makeAddr(\"guardian\");\n\n // By default the first block has timestamp and number zero, which will cause underflows in the\n // tests, so we'll move forward to these block values.\n initL1Time = startingTimestamp + 1;\n vm.warp(initL1Time);\n vm.roll(startingBlockNumber);\n // Deploy the L2OutputOracle and transfer owernship to the proposer\n oracleImpl = new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: startingTimestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(oracleImpl),\n abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp))\n );\n oracle = L2OutputOracle(address(proxy));\n vm.label(address(oracle), \"L2OutputOracle\");\n\n // Set the L2ToL1MessagePasser at the correct address\n vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code);\n\n vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, \"L2ToL1MessagePasser\");\n }\n}\n\ncontract Portal_Initializer is L2OutputOracle_Initializer {\n // Test target\n OptimismPortal internal opImpl;\n OptimismPortal internal op;\n SystemConfig systemConfig;\n\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n\n systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: config\n });\n\n opImpl = new OptimismPortal({\n _l2Oracle: oracle,\n _guardian: guardian,\n _paused: true,\n _config: systemConfig\n });\n\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(opImpl),\n abi.encodeWithSelector(OptimismPortal.initialize.selector, false)\n );\n op = OptimismPortal(payable(address(proxy)));\n vm.label(address(op), \"OptimismPortal\");\n }\n}\n\ncontract Messenger_Initializer is Portal_Initializer {\n AddressManager internal addressManager;\n L1CrossDomainMessenger internal L1Messenger;\n L2CrossDomainMessenger internal L2Messenger =\n L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);\n\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event RelayedMessage(bytes32 indexed msgHash);\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 mint,\n uint256 value,\n uint64 gasLimit,\n bool isCreation,\n bytes data\n );\n\n event WhatHappened(bool success, bytes returndata);\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the address manager\n vm.prank(multisig);\n addressManager = new AddressManager();\n\n // Setup implementation\n L1CrossDomainMessenger L1MessengerImpl = new L1CrossDomainMessenger(op);\n\n // Setup the address manager and proxy\n vm.prank(multisig);\n addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(L1MessengerImpl));\n ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(\n addressManager,\n \"OVM_L1CrossDomainMessenger\"\n );\n L1Messenger = L1CrossDomainMessenger(address(proxy));\n L1Messenger.initialize();\n\n vm.etch(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n address(new L2CrossDomainMessenger(address(L1Messenger))).code\n );\n\n L2Messenger.initialize();\n\n // Label addresses\n vm.label(address(addressManager), \"AddressManager\");\n vm.label(address(L1MessengerImpl), \"L1CrossDomainMessenger_Impl\");\n vm.label(address(L1Messenger), \"L1CrossDomainMessenger_Proxy\");\n vm.label(Predeploys.LEGACY_ERC20_ETH, \"LegacyERC20ETH\");\n vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, \"L2CrossDomainMessenger\");\n\n vm.label(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n \"L1CrossDomainMessenger_aliased\"\n );\n }\n}\n\ncontract Bridge_Initializer is Messenger_Initializer {\n L1StandardBridge L1Bridge;\n L2StandardBridge L2Bridge;\n OptimismMintableERC20Factory L2TokenFactory;\n OptimismMintableERC20Factory L1TokenFactory;\n ERC20 L1Token;\n ERC20 BadL1Token;\n OptimismMintableERC20 L2Token;\n LegacyMintableERC20 LegacyL2Token;\n ERC20 NativeL2Token;\n ERC20 BadL2Token;\n OptimismMintableERC20 RemoteL1Token;\n\n event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data\n );\n\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFailed(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.label(Predeploys.L2_STANDARD_BRIDGE, \"L2StandardBridge\");\n vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, \"OptimismMintableERC20Factory\");\n\n // Deploy the L1 bridge and initialize it with the address of the\n // L1CrossDomainMessenger\n L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig);\n vm.mockCall(\n multisig,\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector),\n abi.encode(true)\n );\n vm.startPrank(multisig);\n proxy.setCode(address(new L1StandardBridge(payable(address(L1Messenger)))).code);\n vm.clearMockedCalls();\n address L1Bridge_Impl = proxy.getImplementation();\n vm.stopPrank();\n\n L1Bridge = L1StandardBridge(payable(address(proxy)));\n\n vm.label(address(proxy), \"L1StandardBridge_Proxy\");\n vm.label(address(L1Bridge_Impl), \"L1StandardBridge_Impl\");\n\n // Deploy the L2StandardBridge, move it to the correct predeploy\n // address and then initialize it\n L2StandardBridge l2B = new L2StandardBridge(payable(proxy));\n vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(l2B).code);\n L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));\n\n // Set up the L2 mintable token factory\n OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(\n Predeploys.L2_STANDARD_BRIDGE\n );\n vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code);\n L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);\n\n vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code);\n\n L1Token = new ERC20(\"Native L1 Token\", \"L1T\");\n\n LegacyL2Token = new LegacyMintableERC20({\n _l2Bridge: address(L2Bridge),\n _l1Token: address(L1Token),\n _name: string.concat(\"LegacyL2-\", L1Token.name()),\n _symbol: string.concat(\"LegacyL2-\", L1Token.symbol())\n });\n vm.label(address(LegacyL2Token), \"LegacyMintableERC20\");\n\n // Deploy the L2 ERC20 now\n L2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(L1Token),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n BadL2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n NativeL2Token = new ERC20(\"Native L2 Token\", \"L2T\");\n L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge));\n\n RemoteL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(NativeL2Token),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n\n BadL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n }\n}\n\ncontract ERC721Bridge_Initializer is Messenger_Initializer {\n L1ERC721Bridge L1Bridge;\n L2ERC721Bridge L2Bridge;\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the L1ERC721Bridge.\n L1Bridge = new L1ERC721Bridge(address(L1Messenger), Predeploys.L2_ERC721_BRIDGE);\n\n // Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.\n vm.etch(\n Predeploys.L2_ERC721_BRIDGE,\n address(new L2ERC721Bridge(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(L1Bridge)))\n .code\n );\n\n // Set up a reference to the L2ERC721Bridge.\n L2Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);\n\n // Label the L1 and L2 bridges.\n vm.label(address(L1Bridge), \"L1ERC721Bridge\");\n vm.label(address(L2Bridge), \"L2ERC721Bridge\");\n }\n}\n\ncontract FFIInterface is Test {\n function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx)\n external\n returns (\n bytes32,\n bytes32,\n bytes32,\n bytes32,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"getProveWithdrawalTransactionInputs\";\n cmds[2] = vm.toString(_tx.nonce);\n cmds[3] = vm.toString(_tx.sender);\n cmds[4] = vm.toString(_tx.target);\n cmds[5] = vm.toString(_tx.value);\n cmds[6] = vm.toString(_tx.gasLimit);\n cmds[7] = vm.toString(_tx.data);\n\n bytes memory result = vm.ffi(cmds);\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[]));\n\n return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof);\n }\n\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashWithdrawal(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashWithdrawal\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashOutputRootProof(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external returns (bytes32) {\n string[] memory cmds = new string[](6);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashOutputRootProof\";\n cmds[2] = Strings.toHexString(uint256(_version));\n cmds[3] = Strings.toHexString(uint256(_stateRoot));\n cmds[4] = Strings.toHexString(uint256(_messagePasserStorageRoot));\n cmds[5] = Strings.toHexString(uint256(_latestBlockhash));\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashDepositTransaction(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external returns (bytes32) {\n string[] memory cmds = new string[](10);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashDepositTransaction\";\n cmds[2] = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n cmds[3] = vm.toString(_logIndex);\n cmds[4] = vm.toString(_from);\n cmds[5] = vm.toString(_to);\n cmds[6] = vm.toString(_mint);\n cmds[7] = vm.toString(_value);\n cmds[8] = vm.toString(_gas);\n cmds[9] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function encodeDepositTransaction(Types.UserDepositTransaction calldata txn)\n external\n returns (bytes memory)\n {\n string[] memory cmds = new string[](11);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeDepositTransaction\";\n cmds[2] = vm.toString(txn.from);\n cmds[3] = vm.toString(txn.to);\n cmds[4] = vm.toString(txn.value);\n cmds[5] = vm.toString(txn.mint);\n cmds[6] = vm.toString(txn.gasLimit);\n cmds[7] = vm.toString(txn.isCreation);\n cmds[8] = vm.toString(txn.data);\n cmds[9] = vm.toString(txn.l1BlockHash);\n cmds[10] = vm.toString(txn.logIndex);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes memory) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) {\n string[] memory cmds = new string[](3);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"decodeVersionedNonce\";\n cmds[2] = vm.toString(nonce);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (uint256, uint256));\n }\n\n function getMerkleTrieFuzzCase(string memory variant)\n external\n returns (\n bytes32,\n bytes memory,\n bytes memory,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](5);\n cmds[0] = \"./test-case-generator/fuzz\";\n cmds[1] = \"-m\";\n cmds[2] = \"trie\";\n cmds[3] = \"-v\";\n cmds[4] = variant;\n\n return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[]));\n }\n}\n\n// Used for testing a future upgrade beyond the current implementations.\n// We include some variables so that we can sanity check accessing storage values after an upgrade.\ncontract NextImpl is Initializable {\n // Initializable occupies the zero-th slot.\n bytes32 slot1;\n bytes32[19] __gap;\n bytes32 slot21;\n bytes32 public constant slot21Init = bytes32(hex\"1337\");\n\n function initialize() public reinitializer(2) {\n // Slot21 is unused by an of our upgradeable contracts.\n // This is used to verify that we can access this value after an upgrade.\n slot21 = slot21Init;\n }\n}\n\ncontract Reverter {\n fallback() external {\n revert();\n }\n}\n\n// Useful for testing reentrancy guards\ncontract CallerCaller {\n event WhatHappened(bool success, bytes returndata);\n\n fallback() external {\n (bool success, bytes memory returndata) = msg.sender.call(msg.data);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n\n// Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard.\ncontract ConfigurableCaller {\n bool doRevert = true;\n address target;\n bytes payload;\n\n event WhatHappened(bool success, bytes returndata);\n\n /**\n * @notice Call the configured target with the configured payload OR revert.\n */\n function call() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n } else {\n (bool success, bytes memory returndata) = address(target).call(payload);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n }\n\n /**\n * @notice Set whether or not to have `call` revert.\n */\n function setDoRevert(bool _doRevert) external {\n doRevert = _doRevert;\n }\n\n /**\n * @notice Set the target for the call made in `call`.\n */\n function setTarget(address _target) external {\n target = _target;\n }\n\n /**\n * @notice Set the payload for the call made in `call`.\n */\n function setPayload(bytes calldata _payload) external {\n payload = _payload;\n }\n\n /**\n * @notice Fallback function that reverts if `doRevert` is true.\n * Otherwise, it does nothing.\n */\n fallback() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n }\n }\n}\n" - }, - "contracts/test/CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, CallerCaller } from \"./CommonTest.t.sol\";\n\n// CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2\n// CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract.\ncontract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {\n // Ensure that baseGas passes for the max value of _minGasLimit,\n // this is about 4 Billion.\n function test_baseGas_succeeds() external view {\n L1Messenger.baseGas(hex\"ff\", type(uint32).max);\n }\n\n // Fuzz for other values which might cause a revert in baseGas.\n function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view {\n L1Messenger.baseGas(hex\"ff\", _minGasLimit);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest, Portal_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable } from \"../L2/CrossDomainOwnable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Vm, VmSafe } from \"forge-std/Vm.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract XDomainSetter is CrossDomainOwnable {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable_Test is CommonTest {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n setter = new XDomainSetter();\n }\n\n // Check that the revert message is correct\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable: caller is not the owner\");\n setter.set(1);\n }\n\n // Check that making a call can set the value properly\n function test_onlyOwner_succeeds() external {\n assertEq(setter.value(), 0);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(setter.owner()));\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n\ncontract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n\n vm.prank(alice);\n setter = new XDomainSetter();\n }\n\n function test_depositTransaction_crossDomainOwner_succeeds() external {\n vm.recordLogs();\n\n vm.prank(alice);\n op.depositTransaction({\n _to: address(setter),\n _value: 0,\n _gasLimit: 21_000,\n _isCreation: false,\n _data: abi.encodeWithSelector(XDomainSetter.set.selector, 1)\n });\n\n // Simulate the operation of the `op-node` by parsing data\n // from logs\n VmSafe.Log[] memory logs = vm.getRecordedLogs();\n // Only 1 log emitted\n assertEq(logs.length, 1);\n\n VmSafe.Log memory log = logs[0];\n\n // It is the expected topic\n bytes32 topic = log.topics[0];\n assertEq(topic, keccak256(\"TransactionDeposited(address,address,uint256,bytes)\"));\n\n // from is indexed and the first argument to the event.\n bytes32 _from = log.topics[1];\n address from = Bytes32AddressLib.fromLast20Bytes(_from);\n\n assertEq(AddressAliasHelper.undoL1ToL2Alias(from), alice);\n\n // Make a call from the \"from\" value received from the log.\n // In theory the opaque data could be parsed from the log\n // and passed to a low level call to \"to\", but calling set\n // directly on the setter is good enough.\n vm.prank(from);\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable2.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable2 } from \"../L2/CrossDomainOwnable2.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter2 is CrossDomainOwnable2 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable2_Test is Messenger_Initializer {\n XDomainSetter2 setter;\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter2();\n }\n\n function test_onlyOwner_notMessenger_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice));\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the owner\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner2_reverts() external {\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_onlyOwner_succeeds() external {\n address owner = setter.owner();\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n owner,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter2.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable3.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable3 } from \"../L2/CrossDomainOwnable3.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter3 is CrossDomainOwnable3 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable3_Test is Messenger_Initializer {\n XDomainSetter3 setter;\n\n /**\n * @notice OpenZeppelin Ownable.sol transferOwnership event\n */\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @notice CrossDomainOwnable3.sol transferOwnership event\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter3();\n }\n\n function test_constructor_succeeds() public {\n assertEq(setter.owner(), alice);\n assertEq(setter.isLocal(), true);\n }\n\n function test_localOnlyOwner_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_transferOwnership_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n }\n\n function test_crossDomainOnlyOwner_notOwner_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob);\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_crossDomainOnlyOwner_notOwner2_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter3.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_crossDomainOnlyOwner_notMessenger_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_transferOwnership_zeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"CrossDomainOwnable3: new owner is the zero address\");\n setter.transferOwnership({ _owner: address(0), _isLocal: true });\n }\n\n function test_transferOwnership_noLocalZeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"Ownable: new owner is the zero address\");\n setter.transferOwnership(address(0));\n }\n\n function test_localOnlyOwner_succeeds() public {\n assertEq(setter.isLocal(), true);\n vm.prank(setter.owner());\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n\n function test_localTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, true);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n\n assertEq(setter.isLocal(), true);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n /**\n * @notice The existing transferOwnership(address) method\n * still exists on the contract\n */\n function test_transferOwnershipNoLocal_succeeds() public {\n bool isLocal = setter.isLocal();\n\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n\n vm.prank(setter.owner());\n setter.transferOwnership(bob);\n\n // isLocal has not changed\n assertEq(setter.isLocal(), isLocal);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n function test_crossDomainTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n bob,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter3.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/DeployerWhitelist.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { DeployerWhitelist } from \"../legacy/DeployerWhitelist.sol\";\n\ncontract DeployerWhitelist_Test is CommonTest {\n DeployerWhitelist list;\n\n function setUp() public virtual override {\n list = new DeployerWhitelist();\n }\n\n // The owner should be address(0)\n function test_owner_succeeds() external {\n assertEq(list.owner(), address(0));\n }\n\n // The storage slot for the owner must be the same\n function test_storageSlots_succeeds() external {\n vm.prank(list.owner());\n list.setOwner(address(1));\n\n assertEq(bytes32(uint256(1)), vm.load(address(list), bytes32(uint256(0))));\n }\n}\n" - }, - "contracts/test/Encoding.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Encoding_Test is CommonTest {\n function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external {\n (uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(\n Encoding.encodeVersionedNonce(_nonce, _version)\n );\n assertEq(version, _version);\n assertEq(nonce, _nonce);\n }\n\n function testDiff_decodeVersionedNonce_succeeds(uint240 _nonce, uint16 _version) external {\n uint256 nonce = uint256(Encoding.encodeVersionedNonce(_nonce, _version));\n (uint256 decodedNonce, uint256 decodedVersion) = ffi.decodeVersionedNonce(nonce);\n\n assertEq(_version, uint16(decodedVersion));\n\n assertEq(_nonce, uint240(decodedNonce));\n }\n\n function testDiff_encodeCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint8 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint8 version = _version % 2;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory encoding = Encoding.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n bytes memory _encoding = ffi.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n assertEq(encoding, _encoding);\n }\n\n function testFuzz_encodeCrossDomainMessageV0_matchesLegacy_succeeds(\n uint240 _nonce,\n address _sender,\n address _target,\n bytes memory _data\n ) external {\n uint8 version = 0;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory legacyEncoding = LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _data,\n nonce\n );\n\n bytes memory bedrockEncoding = Encoding.encodeCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n nonce\n );\n\n assertEq(legacyEncoding, bedrockEncoding);\n }\n\n function testDiff_encodeDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bool isCreate,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n Types.UserDepositTransaction memory t = Types.UserDepositTransaction(\n _from,\n _to,\n isCreate,\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n );\n\n bytes memory txn = Encoding.encodeDepositTransaction(t);\n bytes memory _txn = ffi.encodeDepositTransaction(t);\n\n assertEq(txn, _txn);\n }\n}\n" - }, - "contracts/test/FeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { L1FeeVault } from \"../L2/L1FeeVault.sol\";\nimport { BaseFeeVault } from \"../L2/BaseFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n// Test the implementations of the FeeVault\ncontract FeeVault_Test is Bridge_Initializer {\n BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));\n L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT));\n\n address constant recipient = address(0x10000);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.BASE_FEE_VAULT, address(new BaseFeeVault(recipient)).code);\n vm.etch(Predeploys.L1_FEE_VAULT, address(new L1FeeVault(recipient)).code);\n\n vm.label(Predeploys.BASE_FEE_VAULT, \"BaseFeeVault\");\n vm.label(Predeploys.L1_FEE_VAULT, \"L1FeeVault\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(baseFeeVault.RECIPIENT(), recipient);\n assertEq(l1FeeVault.RECIPIENT(), recipient);\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n}\n" - }, - "contracts/test/GasPriceOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GasPriceOracle } from \"../L2/GasPriceOracle.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract GasPriceOracle_Test is CommonTest {\n event OverheadUpdated(uint256);\n event ScalarUpdated(uint256);\n event DecimalsUpdated(uint256);\n\n GasPriceOracle gasOracle;\n L1Block l1Block;\n address depositor;\n\n // set the initial L1 context values\n uint64 constant number = 10;\n uint64 constant timestamp = 11;\n uint256 constant basefee = 100;\n bytes32 constant hash = bytes32(uint256(64));\n uint64 constant sequenceNumber = 0;\n bytes32 constant batcherHash = bytes32(uint256(777));\n uint256 constant l1FeeOverhead = 310;\n uint256 constant l1FeeScalar = 10;\n\n function setUp() public virtual override {\n super.setUp();\n // place the L1Block contract at the predeploy address\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n\n l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n depositor = l1Block.DEPOSITOR_ACCOUNT();\n\n // We are not setting the gas oracle at its predeploy\n // address for simplicity purposes. Nothing in this test\n // requires it to be at a particular address\n gasOracle = new GasPriceOracle();\n\n vm.prank(depositor);\n l1Block.setL1BlockValues({\n _number: number,\n _timestamp: timestamp,\n _basefee: basefee,\n _hash: hash,\n _sequenceNumber: sequenceNumber,\n _batcherHash: batcherHash,\n _l1FeeOverhead: l1FeeOverhead,\n _l1FeeScalar: l1FeeScalar\n });\n }\n\n function test_l1BaseFee_succeeds() external {\n assertEq(gasOracle.l1BaseFee(), basefee);\n }\n\n function test_gasPrice_succeeds() external {\n vm.fee(100);\n uint256 gasPrice = gasOracle.gasPrice();\n assertEq(gasPrice, 100);\n }\n\n function test_baseFee_succeeds() external {\n vm.fee(64);\n uint256 gasPrice = gasOracle.baseFee();\n assertEq(gasPrice, 64);\n }\n\n function test_scalar_succeeds() external {\n assertEq(gasOracle.scalar(), l1FeeScalar);\n }\n\n function test_overhead_succeeds() external {\n assertEq(gasOracle.overhead(), l1FeeOverhead);\n }\n\n function test_decimals_succeeds() external {\n assertEq(gasOracle.decimals(), 6);\n assertEq(gasOracle.DECIMALS(), 6);\n }\n\n // Removed in bedrock\n function test_setGasPrice_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setGasPrice(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n\n // Removed in bedrock\n function test_setL1BaseFee_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setL1BaseFee(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n}\n" - }, - "contracts/test/GovernanceToken.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract GovernanceToken_Test is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n\n function setUp() public virtual override {\n super.setUp();\n vm.prank(owner);\n gov = new GovernanceToken();\n }\n\n function test_constructor_succeeds() external {\n assertEq(gov.owner(), owner);\n assertEq(gov.name(), \"Optimism\");\n assertEq(gov.symbol(), \"OP\");\n assertEq(gov.decimals(), 18);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_mint_fromOwner_succeeds() external {\n // Mint 100 tokens.\n vm.prank(owner);\n gov.mint(owner, 100);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 100);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_mint_fromNotOwner_reverts() external {\n // Mint 100 tokens as rando.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n gov.mint(owner, 100);\n\n // Balance does not update.\n assertEq(gov.balanceOf(owner), 0);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_burn_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando burns their tokens.\n vm.prank(rando);\n gov.burn(50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_burnFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to burn 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner burns 50 tokens from rando.\n vm.prank(owner);\n gov.burnFrom(rando, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_transfer_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando transfers 50 tokens to owner.\n vm.prank(rando);\n gov.transfer(owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_approve_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n\n function test_transferFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner transfers 50 tokens from rando to owner.\n vm.prank(owner);\n gov.transferFrom(rando, owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_increaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Rando increases allowance by 50 tokens.\n vm.prank(rando);\n gov.increaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 100);\n }\n\n function test_decreaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 100 tokens.\n vm.prank(rando);\n gov.approve(owner, 100);\n\n // Rando decreases allowance by 50 tokens.\n vm.prank(rando);\n gov.decreaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n}\n" - }, - "contracts/test/Hashing.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Hashing_hashDepositSource_Test is CommonTest {\n /**\n * @notice Tests that hashDepositSource returns the correct hash in a simple case.\n */\n function test_hashDepositSource_succeeds() external {\n assertEq(\n Hashing.hashDepositSource(\n 0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,\n 0x1\n ),\n 0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc\n );\n }\n}\n\ncontract Hashing_hashCrossDomainMessage_Test is CommonTest {\n /**\n * @notice Tests that hashCrossDomainMessage returns the correct hash in a simple case.\n */\n function testDiff_hashCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint16 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Ensure the version is valid.\n uint16 version = uint16(bound(uint256(_version), 0, 1));\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n assertEq(\n Hashing.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data),\n ffi.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n\n /**\n * @notice Tests that hashCrossDomainMessageV0 matches the hash of the legacy encoding.\n */\n function testFuzz_hashCrossDomainMessageV0_matchesLegacy_succeeds(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) external {\n assertEq(\n keccak256(\n LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _message,\n _messageNonce\n )\n ),\n Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _messageNonce)\n );\n }\n}\n\ncontract Hashing_hashWithdrawal_Test is CommonTest {\n /**\n * @notice Tests that hashWithdrawal returns the correct hash in a simple case.\n */\n function testDiff_hashWithdrawal_succeeds(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n assertEq(\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)\n ),\n ffi.hashWithdrawal(_nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n}\n\ncontract Hashing_hashOutputRootProof_Test is CommonTest {\n /**\n * @notice Tests that hashOutputRootProof returns the correct hash in a simple case.\n */\n function testDiff_hashOutputRootProof_succeeds(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external {\n assertEq(\n Hashing.hashOutputRootProof(\n Types.OutputRootProof({\n version: _version,\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _messagePasserStorageRoot,\n latestBlockhash: _latestBlockhash\n })\n ),\n ffi.hashOutputRootProof(\n _version,\n _stateRoot,\n _messagePasserStorageRoot,\n _latestBlockhash\n )\n );\n }\n}\n\ncontract Hashing_hashDepositTransaction_Test is CommonTest {\n /**\n * @notice Tests that hashDepositTransaction returns the correct hash in a simple case.\n */\n function testDiff_hashDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n assertEq(\n Hashing.hashDepositTransaction(\n Types.UserDepositTransaction(\n _from,\n _to,\n false, // isCreate\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n )\n ),\n ffi.hashDepositTransaction(_from, _to, _mint, _value, _gas, _data, _logIndex)\n );\n }\n}\n" - }, - "contracts/test/L1Block.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\ncontract L1BlockTest is CommonTest {\n L1Block lb;\n address depositor;\n bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));\n\n function setUp() public virtual override {\n super.setUp();\n lb = new L1Block();\n depositor = lb.DEPOSITOR_ACCOUNT();\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: uint64(1),\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: NON_ZERO_HASH,\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(0),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function testFuzz_updatesValues_succeeds(\n uint64 n,\n uint64 t,\n uint256 b,\n bytes32 h,\n uint64 s,\n bytes32 bt,\n uint256 fo,\n uint256 fs\n ) external {\n vm.prank(depositor);\n lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs);\n assertEq(lb.number(), n);\n assertEq(lb.timestamp(), t);\n assertEq(lb.basefee(), b);\n assertEq(lb.hash(), h);\n assertEq(lb.sequenceNumber(), s);\n assertEq(lb.batcherHash(), bt);\n assertEq(lb.l1FeeOverhead(), fo);\n assertEq(lb.l1FeeScalar(), fs);\n }\n\n function test_number_succeeds() external {\n assertEq(lb.number(), uint64(1));\n }\n\n function test_timestamp_succeeds() external {\n assertEq(lb.timestamp(), uint64(2));\n }\n\n function test_basefee_succeeds() external {\n assertEq(lb.basefee(), 3);\n }\n\n function test_hash_succeeds() external {\n assertEq(lb.hash(), NON_ZERO_HASH);\n }\n\n function test_sequenceNumber_succeeds() external {\n assertEq(lb.sequenceNumber(), uint64(4));\n }\n\n function test_updateValues_succeeds() external {\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: type(uint64).max,\n _timestamp: type(uint64).max,\n _basefee: type(uint256).max,\n _hash: keccak256(abi.encode(1)),\n _sequenceNumber: type(uint64).max,\n _batcherHash: bytes32(type(uint256).max),\n _l1FeeOverhead: type(uint256).max,\n _l1FeeScalar: type(uint256).max\n });\n }\n}\n" - }, - "contracts/test/L1BlockNumber.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { L1BlockNumber } from \"../legacy/L1BlockNumber.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract L1BlockNumberTest is Test {\n L1Block lb;\n L1BlockNumber bn;\n\n uint64 constant number = 99;\n\n function setUp() external {\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n lb = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n bn = new L1BlockNumber();\n vm.prank(lb.DEPOSITOR_ACCOUNT());\n\n lb.setL1BlockValues({\n _number: number,\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: bytes32(uint256(10)),\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(uint256(0)),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function test_getL1BlockNumber_succeeds() external {\n assertEq(bn.getL1BlockNumber(), number);\n }\n\n function test_fallback_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n\n function test_receive_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call{ value: 1 }(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n}\n" - }, - "contracts/test/L1CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle_Initializer } from \"./L2OutputOracle.t.sol\";\n\n/* Libraries */\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n/* Target contract dependencies */\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/* Target contract */\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\n\ncontract L1CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n // the version is encoded in the nonce\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce());\n assertEq(version, L1Messenger.MESSAGE_VERSION());\n }\n\n // sendMessage: should be able to send a single message\n // TODO: this same test needs to be done with the legacy message type\n // by setting the message version to 0\n function test_sendMessage_succeeds() external {\n // deposit transaction on the optimism portal should be called\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n )\n );\n\n // TransactionDeposited event\n vm.expectEmit(true, true, true, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n );\n\n // SentMessage event\n vm.expectEmit(true, true, true, true);\n emit SentMessage(recipient, alice, hex\"ff\", L1Messenger.messageNonce(), 100);\n\n // SentMessageExtension1 event\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(alice, 0);\n\n vm.prank(alice);\n L1Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n // sendMessage: should be able to send the same message twice\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L1Messenger.messageNonce());\n }\n\n function test_xDomainSender_notSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // xDomainMessageSender: should return the xDomainMsgSender address\n // TODO: might need a test contract\n // function test_xDomainSenderSetCorrectly() external {}\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(address(op));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n // relayMessage: should send a successful call to the target contract\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.expectCall(target, hex\"1111\");\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n // set the target to be the OptimismPortal\n address target = address(op);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.prank(address(op));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n\n vm.store(address(op), 0, bytes32(abi.encode(sender)));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: should revert if eth is sent from a contract other than the standard bridge\n function test_replayMessage_withValue_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.expectRevert(\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n L1Messenger.relayMessage{ value: 100 }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n vm.expectCall(target, hex\"1111\");\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n // relayMessage: Should revert if the recipient is trying to reenter with the\n // same message.\n function test_relayMessage_reentrancySameMessage_reverts() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory callMessage = abi.encodeWithSelector(caller.call.selector);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Set the portal's `l2Sender` to the `sender`.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(uint256(uint160(sender))));\n\n // Act as the portal and call the `relayMessage` function with the `innerMessage`.\n vm.prank(address(op));\n vm.expectCall(target, callMessage);\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message failed to be relayed\n assertFalse(L1Messenger.successfulMessages(hash));\n assertTrue(L1Messenger.failedMessages(hash));\n\n // Set the configurable caller's target to `L1Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L1Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L1Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n callMessage\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with the same message hash. The reentrancy attempt should\n // revert.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(\n false,\n abi.encodeWithSignature(\"Error(string)\", \"ReentrancyGuard: reentrant call\")\n );\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message still failed to be relayed.\n assertFalse(L1Messenger.successfulMessages(hash));\n assertTrue(L1Messenger.failedMessages(hash));\n }\n\n // relayMessage: should not revert if the recipient reenters `relayMessage` with a different\n // message hash.\n function test_relayMessage_reentrancyDiffMessage_succeeds() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory messageA = abi.encodeWithSelector(caller.call.selector);\n bytes memory messageB = hex\"\";\n\n bytes32 hashA = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n bytes32 hashB = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Set the portal's `l2Sender` to the `sender`.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(uint256(uint160(sender))));\n\n // Act as the portal and call the `relayMessage` function with both `messageA` and `messageB`.\n vm.startPrank(address(op));\n\n vm.expectCall(target, messageA);\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n vm.expectCall(target, messageB);\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Stop acting as the portal\n vm.stopPrank();\n\n // Assert that both messages failed to be relayed\n assertFalse(L1Messenger.successfulMessages(hashA));\n assertFalse(L1Messenger.successfulMessages(hashB));\n assertTrue(L1Messenger.failedMessages(hashA));\n assertTrue(L1Messenger.failedMessages(hashB));\n\n // Set the configurable caller's target to `L1Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L1Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L1Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageB\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with messageB. The reentrancy attempt should succeed\n // because the message hashes are different.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(true, hex\"\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n\n // Assert that both messages are now in the `successfulMessages` mapping.\n assertTrue(L1Messenger.successfulMessages(hashA));\n assertTrue(L1Messenger.successfulMessages(hashB));\n }\n\n function test_relayMessage_legacy_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyOldReplay_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Mark legacy message as already relayed.\n uint256 successfulMessagesSlot = 203;\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex\"1111\", 0);\n bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot));\n vm.store(address(L1Messenger), slot, bytes32(uint256(1)));\n\n // Expect revert.\n vm.expectRevert(\"CrossDomainMessenger: legacy withdrawal already relayed\");\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was not relayed.\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyRetryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect FailedRelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacyRetryAfterSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message has already been relayed\");\n\n // Retry the message again.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n}\n" - }, - "contracts/test/L1ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L1ERC721Bridge_Test is Messenger_Initializer {\n TestERC721 internal localToken;\n TestERC721 internal remoteToken;\n L1ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L1ERC721Bridge(address(L1Messenger), otherBridge);\n localToken = new TestERC721();\n remoteToken = new TestERC721();\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L1ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L1Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L1Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notEscrowed_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n" - }, - "contracts/test/L1StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\n\ncontract L1StandardBridge_Getter_Test is Bridge_Initializer {\n function test_getters_succeeds() external {\n assert(L1Bridge.l2TokenBridge() == address(L2Bridge));\n assert(L1Bridge.OTHER_BRIDGE() == L2Bridge);\n assert(L1Bridge.messenger() == L1Messenger);\n assert(L1Bridge.MESSENGER() == L1Messenger);\n assertEq(L1Bridge.version(), \"1.1.0\");\n }\n}\n\ncontract L1StandardBridge_Initialize_Test is Bridge_Initializer {\n function test_initialize_succeeds() external {\n assertEq(address(L1Bridge.messenger()), address(L1Messenger));\n\n assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE);\n\n assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE);\n }\n}\n\ncontract L1StandardBridge_Initialize_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_Receive_Test is Bridge_Initializer {\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(op).balance, 0);\n\n // The legacy event must be emitted for backwards compatibility\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n ),\n 200_000\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L1Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(op).balance, 100);\n }\n}\n\ncontract L1StandardBridge_Receive_TestFail {}\n\ncontract PreBridgeETH is Bridge_Initializer {\n function _preBridgeETH(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 500,\n hex\"dead\"\n );\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex\"dead\")\n );\n }\n vm.expectCall(\n address(L1Messenger),\n 500,\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 50000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 500,\n 50000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 50000);\n vm.expectCall(\n address(op),\n 500,\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 500,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(500),\n uint256(500),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 500, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 500, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 50000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 500);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETH_Test is PreBridgeETH {\n // depositETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_depositETH_succeeds() external {\n _preBridgeETH({ isLegacy: true });\n L1Bridge.depositETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_BridgeETH_Test is PreBridgeETH {\n // BridgeETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETH_succeeds() external {\n _preBridgeETH({ isLegacy: false });\n L1Bridge.bridgeETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer {\n function test_depositETH_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, address(L1Token).code);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice);\n L1Bridge.depositETH{ value: 1 }(300, hex\"\");\n }\n}\n\ncontract PreBridgeETHTo is Bridge_Initializer {\n function _preBridgeETHTo(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex\"dead\")\n );\n }\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n bob,\n 600,\n hex\"dead\"\n );\n\n // the L1 bridge should call\n // L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 60000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 600,\n 60000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 60000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 600,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(600),\n uint256(600),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, bob, 600, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, bob, 600, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 60000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 600);\n\n // deposit eth to bob\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo {\n // depositETHTo\n // - emits ETHDepositInitiated\n // - calls optimismPortal.depositTransaction\n // - EOA or contract can call\n // - ETH ends up in the optimismPortal\n function test_depositETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: true });\n L1Bridge.depositETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo {\n // BridgeETHTo\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: false });\n L1Bridge.bridgeETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // depositERC20\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - only callable by EOA\n function test_depositERC20_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Deal Alice's ERC20 State\n deal(address(L1Token), alice, 100000, true);\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n // The L1Bridge should transfer alice's tokens to itself\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)\n );\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n vm.prank(alice);\n L1Bridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex\"\");\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n }\n}\n\ncontract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer {\n function test_depositERC20_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, hex\"ffff\");\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice, alice);\n L1Bridge.depositERC20(address(0), address(0), 100, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {\n // depositERC20To\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - callable by a contract\n function test_depositERC20To_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n bob,\n 1000,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n deal(address(L1Token), alice, 100000, true);\n\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)\n );\n\n vm.prank(alice);\n L1Bridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex\"\");\n\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 1000);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeETHWithdrawal\n // - emits ETHWithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeETHWithdrawal_succeeds() external {\n uint256 aliceBalance = alice.balance;\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHWithdrawalFinalized(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n vm.expectCall(alice, hex\"\");\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n // ensure that the messenger has ETH to call with\n vm.deal(address(L1Bridge.messenger()), 100);\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n\n assertEq(address(L1Bridge.messenger()).balance, 0);\n assertEq(aliceBalance + 100, alice.balance);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeERC20Withdrawal\n // - updates bridge.deposits\n // - emits ERC20WithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeERC20Withdrawal_succeeds() external {\n deal(address(L1Token), address(L1Bridge), 100, true);\n\n uint256 slot = stdstore\n .target(address(L1Bridge))\n .sig(\"deposits(address,address)\")\n .with_key(address(L1Token))\n .with_key(address(L2Token))\n .find();\n\n // Give the L1 bridge some ERC20 tokens\n vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)\n );\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n assertEq(L1Token.balanceOf(address(L1Bridge)), 0);\n assertEq(L1Token.balanceOf(address(alice)), 100);\n }\n}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer {\n function test_finalizeERC20Withdrawal_notMessenger_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(28));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n\n function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(address(0)))\n );\n vm.prank(address(L1Bridge.messenger()));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer {\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L1Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L1Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce());\n assertEq(version, L2Messenger.MESSAGE_VERSION());\n }\n\n function test_sendMessage_succeeds() external {\n bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage(\n L2Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n );\n vm.expectCall(\n address(messagePasser),\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData\n )\n );\n\n // MessagePassed event\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(L2Messenger),\n address(L1Messenger),\n 0,\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData,\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messagePasser.messageNonce(),\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: L2Messenger.baseGas(hex\"ff\", 100),\n data: xDomainCallData\n })\n )\n );\n\n vm.prank(alice);\n L2Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L2Messenger.messageNonce();\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L2Messenger.messageNonce());\n }\n\n function test_xDomainSender_senderNotSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 2), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n vm.expectCall(target, hex\"1111\");\n\n vm.prank(caller);\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L2Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L2Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n address target = address(messagePasser);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory message = hex\"1111\";\n\n vm.prank(caller);\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retry_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n uint256 value = 100;\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(caller), value);\n vm.prank(caller);\n L2Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L2Messenger.successfulMessages(hash), false);\n assertEq(L2Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L2Messenger.successfulMessages(hash), true);\n assertEq(L2Messenger.failedMessages(hash), true);\n }\n\n // relayMessage: Should revert if the recipient is trying to reenter with the\n // same message.\n function test_relayMessage_reentrancySameMessage_reverts() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = address(L1Messenger);\n address l1XDMAlias = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory callMessage = abi.encodeWithSelector(caller.call.selector);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Act as the L1XDM and call the `relayMessage` function with the `innerMessage`.\n vm.prank(l1XDMAlias);\n vm.expectCall(target, callMessage);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message failed to be relayed\n assertFalse(L2Messenger.successfulMessages(hash));\n assertTrue(L2Messenger.failedMessages(hash));\n\n // Set the configurable caller's target to `L2Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L2Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L2Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with the same message hash. The reentrancy attempt should\n // revert.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(\n false,\n abi.encodeWithSignature(\"Error(string)\", \"ReentrancyGuard: reentrant call\")\n );\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message still failed to be relayed.\n assertFalse(L2Messenger.successfulMessages(hash));\n assertTrue(L2Messenger.failedMessages(hash));\n }\n\n // relayMessage: should not revert if the recipient reenters `relayMessage` with a different\n // message hash.\n function test_relayMessage_reentrancyDiffMessage_succeeds() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = address(L1Messenger);\n address l1XDMAlias = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory messageA = abi.encodeWithSelector(caller.call.selector);\n bytes memory messageB = hex\"\";\n\n bytes32 hashA = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n bytes32 hashB = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Act as the L1XDM and call the `relayMessage` function with both `messageA` and `messageB`.\n vm.startPrank(l1XDMAlias);\n\n vm.expectCall(target, messageA);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n vm.expectCall(target, messageB);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Stop acting as the L1XDM\n vm.stopPrank();\n\n // Assert that both messages failed to be relayed\n assertFalse(L2Messenger.successfulMessages(hashA));\n assertFalse(L2Messenger.successfulMessages(hashB));\n assertTrue(L2Messenger.failedMessages(hashA));\n assertTrue(L2Messenger.failedMessages(hashB));\n\n // Set the configurable caller's target to `L2Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L2Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L2Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageB\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with messageB. The reentrancy attempt should succeed\n // because the message hashes are different.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(true, hex\"\");\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n\n // Assert that both messages are now in the `successfulMessages` mapping.\n assertTrue(L2Messenger.successfulMessages(hashA));\n assertTrue(L2Messenger.successfulMessages(hashB));\n }\n}\n" - }, - "contracts/test/L2ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract TestMintableERC721 is OptimismMintableERC721 {\n constructor(address _bridge, address _remoteToken)\n OptimismMintableERC721(_bridge, 1, _remoteToken, \"Test\", \"TST\")\n {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L2ERC721Bridge_Test is Messenger_Initializer {\n TestMintableERC721 internal localToken;\n TestERC721 internal remoteToken;\n L2ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L2ERC721Bridge(address(L2Messenger), otherBridge);\n remoteToken = new TestERC721();\n localToken = new TestMintableERC721(address(bridge), address(remoteToken));\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L2ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L2Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L2Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L1ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_interfaceNotCompliant_reverts() external {\n // Create a non-compliant token\n NonCompliantERC721 nonCompliantToken = new NonCompliantERC721(alice);\n\n // Bridge the non-compliant token.\n vm.prank(alice);\n bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex\"5678\");\n\n // Attempt to finalize the withdrawal. Should revert because the token does not claim\n // to be compliant with the `IOptimismMintableERC721` interface.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token interface is not compliant\");\n bridge.finalizeBridgeERC721(\n address(address(nonCompliantToken)),\n address(address(0x01)),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_alreadyExists_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721: token already minted\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n\n/**\n * @dev A non-compliant ERC721 token that does not implement the full ERC721 interface.\n *\n * This is used to test that the bridge will revert if the token does not claim to support\n * the ERC721 interface.\n */\ncontract NonCompliantERC721 {\n address internal immutable owner;\n\n constructor(address _owner) {\n owner = _owner;\n }\n\n function ownerOf(uint256) external view returns (address) {\n return owner;\n }\n\n function remoteToken() external pure returns (address) {\n return address(0x01);\n }\n\n function burn(address, uint256) external {\n // Do nothing.\n }\n\n function supportsInterface(bytes4) external pure returns (bool) {\n return false;\n }\n}\n" - }, - "contracts/test/L2OutputOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { L2OutputOracle_Initializer, NextImpl } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2OutputOracleTest is L2OutputOracle_Initializer {\n bytes32 proposedOutput1 = keccak256(abi.encode(1));\n\n function test_constructor_succeeds() external {\n assertEq(oracle.PROPOSER(), proposer);\n assertEq(oracle.CHALLENGER(), owner);\n assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);\n assertEq(oracle.latestBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingTimestamp(), startingTimestamp);\n }\n\n function test_constructor_badTimestamp_reverts() external {\n vm.expectRevert(\"L2OutputOracle: starting L2 timestamp must be less than current time\");\n\n // startingTimestamp is in the future\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp + 1,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function test_constructor_l2BlockTimeZero_reverts() external {\n vm.expectRevert(\"L2OutputOracle: L2 block time must be greater than 0\");\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: 0,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function testFuzz_constructor_submissionIntervalLteL2BlockTime_reverts(\n uint256 _submissionInterval,\n uint256 _l2BlockTime\n ) external {\n // Bound the _l2blockTime to be in the range of [1, type(uint256).max]\n _l2BlockTime = bound(_l2BlockTime, 1, type(uint256).max);\n // Roll the block number to _l2blockTime (the starting L2 timestamp must be less than or equal to the current time)\n vm.roll(_l2BlockTime);\n // Bound _submissionInterval to be less than or equal to _l2BlockTime\n _submissionInterval = bound(_submissionInterval, 0, _l2BlockTime);\n\n vm.expectRevert(\"L2OutputOracle: submission interval must be greater than L2 block time\");\n new L2OutputOracle({\n _submissionInterval: _submissionInterval,\n _l2BlockTime: _l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n /****************\n * Getter Tests *\n ****************/\n\n // Test: latestBlockNumber() should return the correct value\n function test_latestBlockNumber_succeeds() external {\n uint256 proposedNumber = oracle.nextBlockNumber();\n\n // Roll to after the block number we'll propose\n warpToProposeTime(proposedNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0);\n assertEq(oracle.latestBlockNumber(), proposedNumber);\n }\n\n // Test: getL2Output() should return the correct value\n function test_getL2Output_succeeds() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0);\n\n Types.OutputProposal memory proposal = oracle.getL2Output(nextOutputIndex);\n assertEq(proposal.outputRoot, proposedOutput1);\n assertEq(proposal.timestamp, block.timestamp);\n\n // The block number is larger than the latest proposed output:\n vm.expectRevert(stdError.indexOOBError);\n oracle.getL2Output(nextOutputIndex + 1);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is exact block\n function test_getL2OutputIndexAfter_sameBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with exact same block as proposed returns the proposal.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is previous block\n function test_getL2OutputIndexAfter_previousBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with previous block returns the proposal too.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 - 1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value during binary search\n function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n bytes32 output2 = keccak256(abi.encode(2));\n uint256 nextBlockNumber2 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber2);\n vm.prank(proposer);\n oracle.proposeL2Output(output2, nextBlockNumber2, 0, 0);\n\n bytes32 output3 = keccak256(abi.encode(3));\n uint256 nextBlockNumber3 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber3);\n vm.prank(proposer);\n oracle.proposeL2Output(output3, nextBlockNumber3, 0, 0);\n\n bytes32 output4 = keccak256(abi.encode(4));\n uint256 nextBlockNumber4 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber4);\n vm.prank(proposer);\n oracle.proposeL2Output(output4, nextBlockNumber4, 0, 0);\n\n // Querying with a block number between the first and second proposal\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 + 1);\n assertEq(index1, 1);\n\n // Querying with a block number between the second and third proposal\n uint256 index2 = oracle.getL2OutputIndexAfter(nextBlockNumber2 + 1);\n assertEq(index2, 2);\n\n // Querying with a block number between the third and fourth proposal\n uint256 index3 = oracle.getL2OutputIndexAfter(nextBlockNumber3 + 1);\n assertEq(index3, 3);\n }\n\n // Test: getL2OutputIndexAfter() reverts when no output exists yet\n function test_getL2OutputIndexAfter_noOutputsExis_reverts() external {\n vm.expectRevert(\"L2OutputOracle: cannot get output as no outputs have been proposed yet\");\n oracle.getL2OutputIndexAfter(0);\n }\n\n // Test: nextBlockNumber() should return the correct value\n function test_nextBlockNumber_succeeds() external {\n assertEq(\n oracle.nextBlockNumber(),\n // The return value should match this arithmetic\n oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL()\n );\n }\n\n function test_computeL2Timestamp_succeeds() external {\n // reverts if timestamp is too low\n vm.expectRevert(stdError.arithmeticError);\n oracle.computeL2Timestamp(startingBlockNumber - 1);\n\n // returns the correct value...\n // ... for the very first block\n assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);\n\n // ... for the first block after the starting block\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 1),\n startingTimestamp + l2BlockTime\n );\n\n // ... for some other block number\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 96024),\n startingTimestamp + l2BlockTime * 96024\n );\n }\n\n /*****************************\n * Propose Tests - Happy Path *\n *****************************/\n\n // Test: proposeL2Output succeeds when given valid input, and no block hash and number are\n // specified.\n function test_proposeL2Output_proposeAnotherOutput_succeeds() public {\n bytes32 proposedOutput2 = keccak256(abi.encode());\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n uint256 proposedNumber = oracle.latestBlockNumber();\n\n // Ensure the submissionInterval is enforced\n assertEq(nextBlockNumber, proposedNumber + submissionInterval);\n\n vm.roll(nextBlockNumber + 1);\n\n vm.expectEmit(true, true, true, true);\n emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp);\n\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output succeeds when given valid input, and when a block hash and number are\n // specified for reorg protection.\n function test_proposeWithBlockhashAndHeight_succeeds() external {\n // Get the number and hash of a previous block in the chain\n uint256 prevL1BlockNumber = block.number - 1;\n bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber);\n }\n\n /***************************\n * Propose Tests - Sad Path *\n ***************************/\n\n // Test: proposeL2Output fails if called by a party that is not the proposer.\n function test_proposeL2Output_notProposer_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n\n vm.prank(address(128));\n vm.expectRevert(\"L2OutputOracle: only the proposer address can propose new outputs\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails given a zero blockhash.\n function test_proposeL2Output_emptyOutput_reverts() external {\n bytes32 outputToPropose = bytes32(0);\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: L2 output proposal cannot be the zero hash\");\n oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if the block number doesn't match the next expected number.\n function test_proposeL2Output_unexpectedBlockNumber_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: block number must be equal to next expected block number\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);\n }\n\n // Test: proposeL2Output fails if it would have a timestamp in the future.\n function test_proposeL2Output_futureTimetamp_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber);\n vm.warp(nextTimestamp);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: cannot propose L2 output in the future\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if a non-existent L1 block hash and number are provided for reorg\n // protection.\n function test_proposeL2Output_wrongFork_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(\n nonZeroHash,\n nextBlockNumber,\n bytes32(uint256(0x01)),\n block.number - 1\n );\n }\n\n // Test: proposeL2Output fails when given valid input, but the block hash and number do not\n // match.\n function test_proposeL2Output_unmatchedBlockhash_reverts() external {\n // Move ahead to block 100 so that we can reference historical blocks\n vm.roll(100);\n\n // Get the number and hash of a previous block in the chain\n uint256 l1BlockNumber = block.number - 1;\n bytes32 l1BlockHash = blockhash(l1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n\n // This will fail when foundry no longer returns zerod block hashes\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);\n }\n\n /*****************************\n * Delete Tests - Happy Path *\n *****************************/\n\n function test_deleteOutputs_singleOutput_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 1);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex);\n oracle.deleteL2Outputs(latestOutputIndex);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n function test_deleteOutputs_multipleOutputs_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 3);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n /***************************\n * Delete Tests - Sad Path *\n ***************************/\n\n function test_deleteL2Outputs_ifNotChallenger_reverts() external {\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.expectRevert(\"L2OutputOracle: only the challenger address can delete outputs\");\n oracle.deleteL2Outputs(latestBlockNumber);\n }\n\n function test_deleteL2Outputs_nonExistent_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestBlockNumber + 1);\n }\n\n function test_deleteL2Outputs_afterLatest_reverts() external {\n // Start by proposing three outputs\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Delete the latest two outputs\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n vm.prank(owner);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // Now try to delete the same output again\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n }\n\n function test_deleteL2Outputs_finalized_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Warp past the finalization period + 1 second\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n\n // Try to delete a finalized output\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs that have already been finalized\");\n oracle.deleteL2Outputs(latestOutputIndex);\n }\n}\n\ncontract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {\n Proxy internal proxy;\n\n function setUp() public override {\n super.setUp();\n proxy = Proxy(payable(address(oracle)));\n }\n\n function test_initValuesOnProxy_succeeds() external {\n assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());\n assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());\n assertEq(startingBlockNumber, oracleImpl.startingBlockNumber());\n assertEq(startingTimestamp, oracleImpl.startingTimestamp());\n\n assertEq(proposer, oracleImpl.PROPOSER());\n assertEq(owner, oracleImpl.CHALLENGER());\n }\n\n function test_initializeProxy_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(payable(proxy)).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_initializeImpl_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(oracleImpl).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(oracle), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(oracle), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(oracle)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/L2StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { console } from \"forge-std/console.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\ncontract L2StandardBridge_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n function test_initialize_succeeds() external {\n assertEq(address(L2Bridge.messenger()), address(L2Messenger));\n assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge));\n assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge));\n }\n\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(messagePasser).balance, 0);\n uint256 nonce = L2Messenger.messageNonce();\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 200_000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 100,\n 200_000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 100,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n // L2ToL1MessagePasser will emit a MessagePassed event\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 100,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 200_000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 100);\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L2Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(messagePasser).balance, 100);\n }\n\n // withrdraw\n // - requires amount == msg.value\n function test_withdraw_insufficientValue_reverts() external {\n assertEq(address(messagePasser).balance, 0);\n\n vm.expectRevert(\"StandardBridge: bridging ETH must include sufficient ETH value\");\n vm.prank(alice, alice);\n L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex\"\");\n }\n\n /**\n * @notice Use the legacy `withdraw` interface on the L2StandardBridge to\n * withdraw ether from L2 to L1.\n */\n function test_withdraw_ether_succeeds() external {\n assertTrue(alice.balance >= 100);\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0);\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated({\n l1Token: address(0),\n l2Token: Predeploys.LEGACY_ERC20_ETH,\n from: alice,\n to: alice,\n amount: 100,\n data: hex\"\"\n });\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex\"\" });\n\n vm.prank(alice, alice);\n L2Bridge.withdraw{ value: 100 }({\n _l2Token: Predeploys.LEGACY_ERC20_ETH,\n _amount: 100,\n _minGasLimit: 1000,\n _extraData: hex\"\"\n });\n\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 100);\n }\n}\n\ncontract PreBridgeERC20 is Bridge_Initializer {\n // withdraw and BridgeERC20 should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20(bool _isLegacy, address _l2Token) internal {\n // Alice has 100 L2Token\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(_l2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex\"\")\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20.selector,\n _l2Token,\n address(L1Token),\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n _l2Token,\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {\n // withdraw\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_withdraw_withdrawingERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // BridgeERC20\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdrawLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) });\n L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_bridgeLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) });\n L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdraw_notEOA_reverts() external {\n // This contract has 100 L2Token\n deal(address(L2Token), address(this), 100, true);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n }\n}\n\ncontract PreBridgeERC20To is Bridge_Initializer {\n // withdrawTo and BridgeERC20To should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal {\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(L2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n bob,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.withdrawTo.selector,\n _l2Token,\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20To.selector,\n _l2Token,\n address(L1Token),\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {\n // withdrawTo\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_withdrawTo_withdrawingERC20_succeeds() external {\n _preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // bridgeERC20To\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20To_succeeds() external {\n _preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex\"\");\n assertEq(L2Token.balanceOf(alice), 0);\n }\n}\n\ncontract L2StandardBridge_Bridge_Test is Bridge_Initializer {\n // finalizeDeposit\n // - only callable by l1TokenBridge\n // - supported token pair emits DepositFinalized\n // - invalid deposit calls Withdrawer.initiateWithdrawal\n function test_finalizeDeposit_depositingERC20_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex\"\");\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeDeposit_depositingETH_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(\n address(L2Token), // localToken\n address(L1Token), // remoteToken\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Messenger), 100, hex\"\");\n }\n}\n\ncontract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L2Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true);\n emit DepositFinalized(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2ToL1MessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\n\ncontract L2ToL1MessagePasserTest is CommonTest {\n L2ToL1MessagePasser messagePasser;\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new L2ToL1MessagePasser();\n }\n\n function testFuzz_initiateWithdrawal_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint256 nonce = messagePasser.messageNonce();\n\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: _value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash);\n\n vm.deal(_sender, _value);\n vm.prank(_sender);\n messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);\n\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0)));\n\n assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1)));\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by a contract\n function test_initiateWithdrawal_fromContract_succeeds() external {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\"\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\",\n withdrawalHash\n );\n\n vm.deal(address(this), 2**64);\n messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex\"\");\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by an EOA\n function test_initiateWithdrawal_fromEOA_succeeds() external {\n uint256 gasLimit = 64000;\n address target = address(4);\n uint256 value = 100;\n bytes memory data = hex\"ff\";\n uint256 nonce = messagePasser.messageNonce();\n\n // EOA emulation\n vm.prank(alice, alice);\n vm.deal(alice, 2**64);\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data)\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash);\n\n messagePasser.initiateWithdrawal{ value: value }(target, gasLimit, data);\n\n // the sent messages mapping is filled\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n // the nonce increments\n assertEq(nonce + 1, messagePasser.messageNonce());\n }\n\n // Test: burn should destroy the ETH held in the contract\n function test_burn_succeeds() external {\n messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n NON_ZERO_GASLIMIT,\n NON_ZERO_DATA\n );\n\n assertEq(address(messagePasser).balance, NON_ZERO_VALUE);\n vm.expectEmit(true, false, false, false);\n emit WithdrawerBalanceBurnt(NON_ZERO_VALUE);\n messagePasser.burn();\n\n // The Withdrawer should have no balance\n assertEq(address(messagePasser).balance, 0);\n }\n}\n" - }, - "contracts/test/LegacyERC20ETH.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyERC20ETH_Test is CommonTest {\n LegacyERC20ETH eth;\n\n function setUp() public virtual override {\n super.setUp();\n eth = new LegacyERC20ETH();\n }\n\n function test_metadata_succeeds() external {\n assertEq(eth.name(), \"Ether\");\n assertEq(eth.symbol(), \"ETH\");\n assertEq(eth.decimals(), 18);\n }\n\n function test_crossDomain_succeeds() external {\n assertEq(eth.l2Bridge(), Predeploys.L2_STANDARD_BRIDGE);\n assertEq(eth.l1Token(), address(0));\n }\n\n function test_transfer_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transfer is disabled\");\n eth.transfer(alice, 100);\n }\n\n function test_approve_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: approve is disabled\");\n eth.approve(alice, 100);\n }\n\n function test_transferFrom_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transferFrom is disabled\");\n eth.transferFrom(bob, alice, 100);\n }\n\n function test_increaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n eth.increaseAllowance(alice, 100);\n }\n\n function test_decreaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n eth.decreaseAllowance(alice, 100);\n }\n\n function test_mint_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: mint is disabled\");\n eth.mint(alice, 100);\n }\n\n function test_burn_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: burn is disabled\");\n eth.burn(alice, 100);\n }\n}\n" - }, - "contracts/test/LegacyMessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyMessagePasser } from \"../legacy/LegacyMessagePasser.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyMessagePasser_Test is CommonTest {\n LegacyMessagePasser messagePasser;\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new LegacyMessagePasser();\n }\n\n function test_passMessageToL1_succeeds() external {\n vm.prank(alice);\n messagePasser.passMessageToL1(hex\"ff\");\n assert(messagePasser.sentMessages(keccak256(abi.encodePacked(hex\"ff\", alice))));\n }\n}\n" - }, - "contracts/test/MerkleTrie.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MerkleTrie } from \"../libraries/trie/MerkleTrie.sol\";\n\ncontract MerkleTrie_get_Test is CommonTest {\n function test_get_validProof1_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579326262\";\n bytes memory val = hex\"6176616c32\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof2_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[\n 2\n ] = hex\"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof3_succeeds() external {\n bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof4_succeeds() external {\n bytes32 root = 0x37956bab6bba472308146808d5311ac19cb4a7daae5df7efcc0f32badc97f55e;\n bytes memory key = hex\"6b6579316161\";\n bytes memory val = hex\"3031323334\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"ce87206b6579316161853031323334\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof5_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657931\";\n bytes\n memory val = hex\"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof6_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657932\";\n bytes memory val = hex\"73686f7274\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[2] = hex\"df808080808080c9823262856176616c338080808080808080808573686f7274\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof7_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657933\";\n bytes memory val = hex\"31323334353637383930313233343536373839303132333435363738393031\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof8_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"61\";\n bytes memory val = hex\"61\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22061\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof9_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"62\";\n bytes memory val = hex\"62\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22062\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof10_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"63\";\n bytes memory val = hex\"63\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22063\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_nonexistentKey1_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b657932\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_nonexistentKey2_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"616e7972616e646f6d6b6579\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_wrongKeyProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579316161\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[2] = hex\"d687206e6f746865728d33343938683472697568677765\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_corruptedProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579326262\";\n bytes[] memory proof = new bytes[](5);\n proof[0] = hex\"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[\n 2\n ] = hex\"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 3\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[4] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidDataRemainder_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa000000000000000000000000000000\";\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidInternalNodeHash_reverts() external {\n bytes32 root = 0xa827dff1a657bb9bb9a1c3abe9db173e2f1359f15eb06f1647ea21ac7c95d8fa;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157\";\n proof[\n 1\n ] = hex\"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080\";\n proof[2] = hex\"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroBranchValueLength_reverts() external {\n bytes32 root = 0xe04b3589eef96b237cd49ccb5dcf6e654a47682bfa0961d563ab843f7ad1e035;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](2);\n proof[0] = hex\"dd8200aad98080808080808080808080c43b82aabbc43c82aacc80808080\";\n proof[1] = hex\"d98080808080808080808080c43b82aabbc43c82aacc80808080\";\n\n vm.expectRevert(\"MerkleTrie: value length must be greater than zero (branch)\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroLengthKey_reverts() external {\n bytes32 root = 0x54157fd62cdf2f474e7bfec2d3cd581e807bee38488c9590cb887add98936b73;\n bytes memory key = hex\"\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"c78320f00082b443\";\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey1_reverts() external {\n bytes32 root = 0xa513ba530659356fb7588a2c831944e80fd8aedaa5a4dc36f918152be2be0605;\n bytes memory key = hex\"01\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"db10d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[1] = hex\"d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[2] = hex\"c582202381aa\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey2_reverts() external {\n bytes32 root = 0xa06abffaec4ebe8ccde595f4547b864b4421b21c1fc699973f94710c9bc17979;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905\";\n proof[\n 1\n ] = hex\"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080\";\n proof[2] = hex\"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_extraProofElements_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](4);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa\";\n proof[3] = hex\"c32081aa\";\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_validProofs_succeeds(bytes4) external {\n // Generate a test case with a valid proof of inclusion for the k/v pair in the trie.\n (bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi\n .getMerkleTrieFuzzCase(\"valid\");\n\n // Assert that our expected value is equal to our actual value.\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidRoot_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"valid\"\n );\n\n bytes32 rootHash = keccak256(abi.encodePacked(root));\n vm.expectRevert(\"MerkleTrie: invalid root hash\");\n MerkleTrie.get(key, proof, rootHash);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_extraProofElements_reverts(bytes4) external {\n // Generate an invalid test case with an extra proof element attached to an otherwise\n // valid proof of inclusion for the passed k/v.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"extra_proof_elems\"\n );\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external {\n // Generate an invalid test case where a long proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_large_internal_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid large internal hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external {\n // Generate an invalid test case where a small proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_internal_node_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_corruptedProof_reverts(bytes4) external {\n // Generate an invalid test case where the proof is malformed.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"corrupted_proof\"\n );\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidDataRemainder_reverts(bytes4) external {\n // Generate an invalid test case where a random element of the proof has more bytes than the\n // length designates within the RLP list encoding.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_data_remainder\"\n );\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_prefixedValidKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and a valid key that is prefixed\n // with random bytes\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"prefixed_valid_key\"\n );\n\n // Ambiguous revert check- all that we care is that it *does* fail. This case may\n // fail within different branches.\n vm.expectRevert();\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_emptyKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and an empty key\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"empty_key\"\n );\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_partialProof_reverts(bytes4) external {\n // Get a random test case with a valid trie / partially correct proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"partial_proof\"\n );\n\n vm.expectRevert(\"MerkleTrie: ran out of proof elements\");\n MerkleTrie.get(key, proof, root);\n }\n}\n" - }, - "contracts/test/MintManager.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MintManager } from \"../governance/MintManager.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract MintManager_Initializer is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n MintManager internal manager;\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.prank(owner);\n gov = new GovernanceToken();\n\n vm.prank(owner);\n manager = new MintManager(owner, address(gov));\n\n vm.prank(owner);\n gov.transferOwnership(address(manager));\n }\n}\n\ncontract MintManager_constructor_Test is MintManager_Initializer {\n /**\n * @notice Tests that the constructor properly configures the contract.\n */\n function test_constructor_succeeds() external {\n assertEq(manager.owner(), owner);\n assertEq(address(manager.governanceToken()), address(gov));\n }\n}\n\ncontract MintManager_mint_Test is MintManager_Initializer {\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner.\n */\n function test_mint_fromOwner_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the mint function reverts when called by a non-owner.\n */\n function test_mint_fromNotOwner_reverts() external {\n // Mint from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.mint(owner, 100);\n }\n\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner a second\n * time after the mint period has elapsed.\n */\n function test_mint_afterPeriodElapsed_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again after period elapsed (2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n manager.mint(owner, 2);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 102);\n }\n\n /**\n * @notice Tests that the mint function always reverts when called before the mint period has\n * elapsed, even if the caller is the owner.\n */\n function test_mint_beforePeriodElapsed_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: minting not permitted yet\");\n manager.mint(owner, 100);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the owner cannot mint more than the mint cap.\n */\n function test_mint_moreThanCap_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again (greater than 2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint amount exceeds cap\");\n manager.mint(owner, 3);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n}\n\ncontract MintManager_upgrade_Test is MintManager_Initializer {\n /**\n * @notice Tests that the owner can upgrade the mint manager.\n */\n function test_upgrade_fromOwner_succeeds() external {\n // Upgrade to new manager.\n vm.prank(owner);\n manager.upgrade(rando);\n\n // New manager is rando.\n assertEq(gov.owner(), rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when called by a non-owner.\n */\n function test_upgrade_fromNotOwner_reverts() external {\n // Upgrade from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.upgrade(rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when attempting to update to the zero\n * address, even if the caller is the owner.\n */\n function test_upgrade_toZeroAddress_reverts() external {\n // Upgrade to zero address fails.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint manager cannot be the zero address\");\n manager.upgrade(address(0));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport {\n ILegacyMintableERC20,\n IOptimismMintableERC20\n} from \"../universal/IOptimismMintableERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract OptimismMintableERC20_Test is Bridge_Initializer {\n event Mint(address indexed account, uint256 amount);\n event Burn(address indexed account, uint256 amount);\n\n function test_semver_succeeds() external {\n assertEq(L2Token.version(), \"1.0.0\");\n }\n\n function test_remoteToken_succeeds() external {\n assertEq(L2Token.remoteToken(), address(L1Token));\n }\n\n function test_bridge_succeeds() external {\n assertEq(L2Token.bridge(), address(L2Bridge));\n }\n\n function test_l1Token_succeeds() external {\n assertEq(L2Token.l1Token(), address(L1Token));\n }\n\n function test_l2Bridge_succeeds() external {\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_legacy_succeeds() external {\n // Getters for the remote token\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.l1Token(), address(L1Token));\n // Getters for the bridge\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_mint_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 100);\n }\n\n function test_mint_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.mint(alice, 100);\n }\n\n function test_burn_succeeds() external {\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_burn_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.burn(alice, 100);\n }\n\n function test_erc165_supportsInterface_succeeds() external {\n // The assertEq calls in this test are comparing the manual calculation of the iface,\n // with what is returned by the solidity's type().interfaceId, just to be safe.\n bytes4 iface1 = bytes4(keccak256(\"supportsInterface(bytes4)\"));\n assertEq(iface1, type(IERC165).interfaceId);\n assert(L2Token.supportsInterface(iface1));\n\n bytes4 iface2 = L2Token.l1Token.selector ^ L2Token.mint.selector ^ L2Token.burn.selector;\n assertEq(iface2, type(ILegacyMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface2));\n\n bytes4 iface3 = L2Token.remoteToken.selector ^\n L2Token.bridge.selector ^\n L2Token.mint.selector ^\n L2Token.burn.selector;\n assertEq(iface3, type(IOptimismMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface3));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\n\ncontract OptimismMintableTokenFactory_Test is Bridge_Initializer {\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_bridge_succeeds() external {\n assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge));\n }\n\n function test_createStandardL2Token_succeeds() external {\n address remote = address(4);\n address local = LibRLP.computeAddress(address(L2TokenFactory), 2);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_sameTwice_succeeds() external {\n address remote = address(4);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n\n address local = LibRLP.computeAddress(address(L2TokenFactory), 3);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_remoteIsZero_succeeds() external {\n address remote = address(0);\n vm.expectRevert(\"OptimismMintableERC20Factory: must provide remote token address\");\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract OptimismMintableERC721_Test is ERC721Bridge_Initializer {\n ERC721 internal L1Token;\n OptimismMintableERC721 internal L2Token;\n\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n event Mint(address indexed account, uint256 tokenId);\n\n event Burn(address indexed account, uint256 tokenId);\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n L1Token = new ERC721(\"L1Token\", \"L1T\");\n L2Token = new OptimismMintableERC721(\n address(L2Bridge),\n 1,\n address(L1Token),\n \"L2Token\",\n \"L2T\"\n );\n\n // Label the addresses for nice traces.\n vm.label(address(L1Token), \"L1ERC721Token\");\n vm.label(address(L2Token), \"L2ERC721Token\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(L2Token.name(), \"L2Token\");\n assertEq(L2Token.symbol(), \"L2T\");\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.remoteChainId(), 1);\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.REMOTE_CHAIN_ID(), 1);\n assertEq(L2Token.version(), \"1.0.0\");\n }\n\n function test_safeMint_succeeds() external {\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(address(0), alice, 1);\n\n // Expect a mint event.\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 1);\n\n // Mint the token.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token should be owned by alice.\n assertEq(L2Token.ownerOf(1), alice);\n }\n\n function test_safeMint_notBridge_reverts() external {\n // Try to mint the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.safeMint(alice, 1);\n }\n\n function test_burn_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(alice, address(0), 1);\n\n // Expect a burn event.\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 1);\n\n // Burn the token.\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 1);\n\n // Token should be owned by address(0).\n vm.expectRevert(\"ERC721: invalid token ID\");\n L2Token.ownerOf(1);\n }\n\n function test_burn_notBridge_reverts() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Try to burn the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.burn(alice, 1);\n }\n\n function test_tokenURI_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token URI should be correct.\n assertEq(\n L2Token.tokenURI(1),\n string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(address(L1Token)), 20),\n \"@\",\n Strings.toString(1),\n \"/tokenURI?uint256=\",\n Strings.toString(1)\n )\n )\n );\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\n\ncontract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {\n OptimismMintableERC721Factory internal factory;\n\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n factory = new OptimismMintableERC721Factory(address(L2Bridge), 1);\n\n // Label the addresses for nice traces.\n vm.label(address(factory), \"OptimismMintableERC721Factory\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(factory.BRIDGE(), address(L2Bridge));\n assertEq(factory.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_succeeds() external {\n // Predict the address based on the factory address and nonce.\n address predicted = LibRLP.computeAddress(address(factory), 1);\n\n // Expect a token creation event.\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC721Created(predicted, address(1234), alice);\n\n // Create the token.\n vm.prank(alice);\n OptimismMintableERC721 created = OptimismMintableERC721(\n factory.createOptimismMintableERC721(address(1234), \"L2Token\", \"L2T\")\n );\n\n // Token address should be correct.\n assertEq(address(created), predicted);\n\n // Should be marked as created by the factory.\n assertEq(factory.isOptimismMintableERC721(address(created)), true);\n\n // Token should've been constructed correctly.\n assertEq(created.name(), \"L2Token\");\n assertEq(created.symbol(), \"L2T\");\n assertEq(created.REMOTE_TOKEN(), address(1234));\n assertEq(created.BRIDGE(), address(L2Bridge));\n assertEq(created.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_zeroRemoteToken_reverts() external {\n // Try to create a token with a zero remote token address.\n vm.expectRevert(\"OptimismMintableERC721Factory: L1 token address cannot be address(0)\");\n factory.createOptimismMintableERC721(address(0), \"L2Token\", \"L2T\");\n }\n}\n" - }, - "contracts/test/OptimismPortal.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { Portal_Initializer, CommonTest, NextImpl } from \"./CommonTest.t.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\ncontract OptimismPortal_Test is Portal_Initializer {\n event Paused(address);\n event Unpaused(address);\n\n function test_constructor_succeeds() external {\n assertEq(address(op.L2_ORACLE()), address(oracle));\n assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD);\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be paused by the GUARDIAN\n */\n function test_pause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n assertEq(op.paused(), false);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Paused(guardian);\n\n vm.prank(guardian);\n op.pause();\n\n assertEq(op.paused(), true);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not the\n * GUARDIAN calls `pause()`\n */\n function test_pause_onlyGuardian_reverts() external {\n assertEq(op.paused(), false);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can pause\");\n vm.prank(alice);\n op.pause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be unpaused by the GUARDIAN\n */\n function test_unpause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Unpaused(guardian);\n vm.prank(guardian);\n op.unpause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not\n * the GUARDIAN calls `unpause()`\n */\n function test_unpause_onlyGuardian_reverts() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can unpause\");\n vm.prank(alice);\n op.unpause();\n\n assertEq(op.paused(), true);\n }\n\n function test_receive_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex\"\");\n\n // give alice money and send as an eoa\n vm.deal(alice, 2**64);\n vm.prank(alice, alice);\n (bool s, ) = address(op).call{ value: 100 }(hex\"\");\n\n assert(s);\n assertEq(address(op).balance, 100);\n }\n\n // Test: depositTransaction fails when contract creation has a non-zero destination address\n function test_depositTransaction_contractCreation_reverts() external {\n // contract creation must have a target of address(0)\n vm.expectRevert(\"OptimismPortal: must send to address(0) when creating a contract\");\n op.depositTransaction(address(1), 1, 0, true, hex\"\");\n }\n\n /**\n * @notice Prevent gasless deposits from being force processed in L2 by\n * ensuring that they have a large enough gas limit set.\n */\n function test_depositTransaction_smallGasLimit_reverts() external {\n vm.expectRevert(\"OptimismPortal: gas limit must cover instrinsic gas cost\");\n op.depositTransaction({\n _to: address(1),\n _value: 0,\n _gasLimit: 0,\n _isCreation: false,\n _data: hex\"\"\n });\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a tx with 0 value\n function test_depositTransaction_noValueEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a tx with 0 value\n function test_depositTransaction_noValueContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndContractContractCreation_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n function test_simple_isOutputFinalized_succeeds() external {\n uint256 ts = block.timestamp;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))\n )\n );\n\n // warp to the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS());\n assertEq(op.isOutputFinalized(0), false);\n\n // warp past the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n assertEq(op.isOutputFinalized(0), true);\n }\n\n function test_isOutputFinalized_succeeds() external {\n uint256 checkpoint = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n vm.roll(checkpoint);\n vm.warp(oracle.computeL2Timestamp(checkpoint) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0);\n\n // warp to the final second of the finalization period\n uint256 finalizationHorizon = block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS();\n vm.warp(finalizationHorizon);\n // The checkpointed block should not be finalized until 1 second from now.\n assertEq(op.isOutputFinalized(nextOutputIndex), false);\n // Nor should a block after it\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n\n // warp past the finalization period\n vm.warp(finalizationHorizon + 1);\n // It should now be finalized.\n assertEq(op.isOutputFinalized(nextOutputIndex), true);\n // But not the block after it.\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n }\n}\n\ncontract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n // Utility function used in the subsequent test. This is necessary to assert that the\n // reentrant call will revert.\n function callPortalAndExpectRevert() external payable {\n vm.expectRevert(\"OptimismPortal: can only trigger one withdrawal per transaction\");\n // Arguments here don't matter, as the require check is the first thing that happens.\n // We assume that this has already been proven.\n op.finalizeWithdrawalTransaction(_defaultTx);\n // Assert that the withdrawal was not finalized.\n assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));\n }\n\n /**\n * @notice Proving withdrawal transactions should revert when paused\n */\n function test_proveWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.proveWithdrawalTransaction({\n _tx: _defaultTx,\n _l2OutputIndex: _proposedOutputIndex,\n _outputRootProof: _outputRootProof,\n _withdrawalProof: _withdrawalProof\n });\n }\n\n // Test: proveWithdrawalTransaction cannot prove a withdrawal with itself (the OptimismPortal) as the target.\n function test_proveWithdrawalTransaction_onSelfCall_reverts() external {\n _defaultTx.target = address(op);\n vm.expectRevert(\"OptimismPortal: you cannot send messages to the portal contract\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the outputRootProof does not match the output root\n function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external {\n // Modify the version to invalidate the withdrawal proof.\n _outputRootProof.version = bytes32(uint256(1));\n vm.expectRevert(\"OptimismPortal: invalid output root proof\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the proof is invalid due to non-existence of\n // the withdrawal.\n function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external {\n // modify the default test values to invalidate the proof.\n _defaultTx.data = hex\"abcd\";\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the passed transaction's withdrawalHash has\n // already been proven.\n function test_proveWithdrawalTransaction_replayProve_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: withdrawal hash has already been proven\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root has changed AND the l2BlockNumber stays the same.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in the OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a different output root within the `provenWithdrawals` mapping without\n // touching the l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root + output index + l2BlockNumber changes.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds()\n external\n {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a dummy output root within the `provenWithdrawals` mapping without touching the\n // l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle\n Types.OutputProposal memory proposal = op.L2_ORACLE().getL2Output(_proposedOutputIndex);\n\n // Propose the same output root again, creating the same output at a different index + l2BlockNumber.\n vm.startPrank(op.L2_ORACLE().PROPOSER());\n op.L2_ORACLE().proposeL2Output(\n proposal.outputRoot,\n op.L2_ORACLE().nextBlockNumber(),\n blockhash(block.number),\n block.number\n );\n vm.stopPrank();\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot + a different output index\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex + 1,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds and emits the WithdrawalProven event.\n function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: finalizeWithdrawalTransaction succeeds and emits the WithdrawalFinalized event.\n function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, false, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore + 100);\n }\n\n /**\n * @notice Finalizing withdrawal transactions should revert when paused\n */\n function test_finalizeWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has not been proven.\n function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectRevert(\"OptimismPortal: withdrawal has not been proven yet\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if withdrawal not proven long enough ago.\n function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Mock a call where the resulting output root is anything but the original output root. In\n // this case we just use bytes32(uint256(1)).\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(bytes32(uint256(1)), _proposedBlockNumber)\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the provenWithdrawal's timestamp is less\n // than the L2 output oracle's starting timestamp\n function test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a startingTimestamp change on the L2 Oracle\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSignature(\"startingTimestamp()\"),\n abi.encode(block.timestamp + 1)\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output root proven is not the same as the\n // output root at the time of finalization.\n function test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock an outputRoot change on the output proposal before attempting\n // to finalize the withdrawal.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n bytes32(uint256(0)),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output proposal's timestamp has\n // not passed the finalization period.\n function test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a timestamp change on the output proposal that has not passed the\n // finalization period.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(block.timestamp + 1),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\"OptimismPortal: output proposal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction fails because the target reverts,\n // and emits the WithdrawalFinalized event with success=false.\n function test_finalizeWithdrawalTransaction_targetFails_fails() external {\n uint256 bobBalanceBefore = address(bob).balance;\n vm.etch(bob, hex\"fe\"); // Contract with just the invalid opcode.\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, false);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the finalization period has not yet passed.\n function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external {\n // Setup the Oracle to return an output with a recent timestamp\n uint256 recentTimestamp = block.timestamp - 1000;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(recentTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has already been finalized.\n function test_finalizeWithdrawalTransaction_onReplay_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if insufficient gas is supplied.\n function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external {\n // This number was identified through trial and error.\n uint256 gasLimit = 150_000;\n Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: gasLimit,\n data: hex\"\"\n });\n\n // Get updated proof inputs.\n (bytes32 stateRoot, bytes32 storageRoot, , , bytes[] memory withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(insufficientGasTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n Hashing.hashOutputRootProof(outputRootProof),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n insufficientGasTx,\n _proposedOutputIndex,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectRevert(\"SafeCall: Not enough gas\");\n op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if a sub-call attempts to finalize another\n // withdrawal.\n function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Copy and modify the default test values to attempt a reentrant call by first calling to\n // this contract's callPortalAndExpectRevert() function above.\n Types.WithdrawalTransaction memory _testTx = _defaultTx;\n _testTx.target = address(this);\n _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector);\n\n // Get modified proof inputs.\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_testTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp.\n uint256 finalizedTimestamp = block.timestamp - oracle.FINALIZATION_PERIOD_SECONDS() - 1;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n outputRoot,\n uint128(finalizedTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(withdrawalHash, alice, address(this));\n op.proveWithdrawalTransaction(\n _testTx,\n _proposedBlockNumber,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectCall(address(this), _testTx.data);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_testTx);\n\n // Ensure that bob's balance was not changed by the reentrant call.\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n function testDiff_finalizeWithdrawalTransaction_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Cannot call the optimism portal\n vm.assume(_target != address(op));\n // Total ETH supply is currently about 120M ETH.\n uint256 value = bound(_value, 0, 200_000_000 ether);\n uint256 gasLimit = bound(_gasLimit, 0, 50_000_000);\n uint256 nonce = messagePasser.messageNonce();\n Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: value,\n gasLimit: gasLimit,\n data: _data\n });\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_tx);\n\n Types.OutputRootProof memory proof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n\n // Ensure the values returned from ffi are correct\n assertEq(outputRoot, Hashing.hashOutputRootProof(proof));\n assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx));\n\n // Mock the call to the oracle\n vm.mockCall(\n address(oracle),\n abi.encodeWithSelector(oracle.getL2Output.selector),\n abi.encode(outputRoot, 0)\n );\n\n // Start the withdrawal, it must be initiated by the _sender and the\n // correct value must be passed along\n vm.deal(_tx.sender, _tx.value);\n vm.prank(_tx.sender);\n messagePasser.initiateWithdrawal{ value: _tx.value }(_tx.target, _tx.gasLimit, _tx.data);\n\n // Ensure that the sentMessages is correct\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n op.proveWithdrawalTransaction(\n _tx,\n 100, // l2BlockNumber\n proof,\n withdrawalProof\n );\n }\n}\n\ncontract OptimismPortalUpgradeable_Test is Portal_Initializer {\n Proxy internal proxy;\n uint64 initialBlockNum;\n\n function setUp() public override {\n super.setUp();\n initialBlockNum = uint64(block.number);\n proxy = Proxy(payable(address(op)));\n }\n\n function test_params_initValuesOnProxy_succeeds() external {\n OptimismPortal p = OptimismPortal(payable(address(proxy)));\n\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = p.params();\n\n ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig();\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_initialize_cannotInitProxy_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(payable(proxy)).initialize(false);\n }\n\n function test_initialize_cannotInitImpl_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(opImpl).initialize(false);\n }\n\n function test_upgradeToAndCall_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(op), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(op)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/Proxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract SimpleStorage {\n mapping(uint256 => uint256) internal store;\n\n function get(uint256 key) external payable returns (uint256) {\n return store[key];\n }\n\n function set(uint256 key, uint256 value) external payable {\n store[key] = value;\n }\n}\n\ncontract Clasher {\n function upgradeTo(address) external pure {\n revert(\"upgradeTo\");\n }\n}\n\ncontract Proxy_Test is Test {\n event Upgraded(address indexed implementation);\n event AdminChanged(address previousAdmin, address newAdmin);\n\n address alice = address(64);\n\n bytes32 internal constant IMPLEMENTATION_KEY =\n bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1);\n\n bytes32 internal constant OWNER_KEY = bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1);\n\n Proxy proxy;\n SimpleStorage simpleStorage;\n\n function setUp() external {\n // Deploy a proxy and simple storage contract as\n // the implementation\n proxy = new Proxy(alice);\n simpleStorage = new SimpleStorage();\n\n vm.prank(alice);\n proxy.upgradeTo(address(simpleStorage));\n }\n\n function test_implementationKey_succeeds() external {\n // The hardcoded implementation key should be correct\n vm.prank(alice);\n proxy.upgradeTo(address(6));\n\n bytes32 key = vm.load(address(proxy), IMPLEMENTATION_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(6));\n }\n\n function test_ownerKey_succeeds() external {\n // The hardcoded owner key should be correct\n vm.prank(alice);\n proxy.changeAdmin(address(6));\n\n bytes32 key = vm.load(address(proxy), OWNER_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(address(6));\n address owner = proxy.admin();\n assertEq(owner, address(6));\n }\n\n function test_proxyCallToImp_notAdmin_succeeds() external {\n // The implementation does not have a `upgradeTo`\n // method, calling `upgradeTo` not as the owner\n // should revert.\n vm.expectRevert();\n proxy.upgradeTo(address(64));\n\n // Call `upgradeTo` as the owner, it should succeed\n // and emit the `Upgraded` event.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(64));\n vm.prank(alice);\n proxy.upgradeTo(address(64));\n\n // Get the implementation as the owner\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(64));\n }\n\n function test_ownerProxyCall_notAdmin_succeeds() external {\n // Calling `changeAdmin` not as the owner should revert\n // as the implementation does not have a `changeAdmin` method.\n vm.expectRevert();\n proxy.changeAdmin(address(1));\n\n // Call `changeAdmin` as the owner, it should succeed\n // and emit the `AdminChanged` event.\n vm.expectEmit(true, true, true, true);\n emit AdminChanged(alice, address(1));\n vm.prank(alice);\n proxy.changeAdmin(address(1));\n\n // Calling `admin` not as the owner should\n // revert as the implementation does not have\n // a `admin` method.\n vm.expectRevert();\n proxy.admin();\n\n // Calling `admin` as the owner should work.\n vm.prank(address(1));\n address owner = proxy.admin();\n assertEq(owner, address(1));\n }\n\n function test_delegatesToImpl_succeeds() external {\n // Call the storage setter on the proxy\n SimpleStorage(address(proxy)).set(1, 1);\n\n // The key should not be set in the implementation\n uint256 result = simpleStorage.get(1);\n assertEq(result, 0);\n {\n // The key should be set in the proxy\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n\n {\n // The owner should be able to call through the proxy\n // when there is not a function selector crash\n vm.prank(alice);\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n }\n\n function test_upgradeToAndCall_succeeds() external {\n {\n // There should be nothing in the current proxy storage\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 0);\n }\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(simpleStorage));\n vm.prank(alice);\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The call should have impacted the state\n uint256 result = SimpleStorage(address(proxy)).get(1);\n assertEq(result, 1);\n }\n\n function test_upgradeToAndCall_functionDoesNotExist_reverts() external {\n // Get the current implementation address\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call. This reverts because the calldata doesn't\n // match a function on the implementation.\n vm.expectRevert(\"Proxy: delegatecall to new implementation contract failed\");\n vm.prank(alice);\n proxy.upgradeToAndCall(address(simpleStorage), hex\"\");\n\n // The implementation address should have not\n // updated because the call to `upgradeToAndCall`\n // reverted.\n vm.prank(alice);\n address postImpl = proxy.implementation();\n assertEq(impl, postImpl);\n\n // The attempt to `upgradeToAndCall`\n // should revert when it is not called by the owner.\n vm.expectRevert();\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n }\n\n function test_upgradeToAndCall_isPayable_succeeds() external {\n // Give alice some funds\n vm.deal(alice, 1 ether);\n // Set the implementation and call and send\n // value.\n vm.prank(alice);\n proxy.upgradeToAndCall{ value: 1 ether }(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The implementation address should be correct\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // The proxy should have a balance\n assertEq(address(proxy).balance, 1 ether);\n }\n\n function test_upgradeTo_clashingFunctionSignatures_succeeds() external {\n // Clasher has a clashing function with the proxy.\n Clasher clasher = new Clasher();\n\n // Set the clasher as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(clasher));\n\n {\n // Assert that the implementation was set properly.\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(clasher));\n }\n\n // Call the clashing function on the proxy\n // not as the owner so that the call passes through.\n // The implementation will revert so we can be\n // sure that the call passed through.\n vm.expectRevert(bytes(\"upgradeTo\"));\n proxy.upgradeTo(address(0));\n\n {\n // Now call the clashing function as the owner\n // and be sure that it doesn't pass through to\n // the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(0));\n }\n }\n\n // Allow for `eth_call` to call proxy methods\n // by setting \"from\" to `address(0)`.\n function test_implementation_zeroAddressCaller_succeeds() external {\n vm.prank(address(0));\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n }\n\n function test_implementation_isZeroAddress_reverts() external {\n // Set `address(0)` as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n\n (bool success, bytes memory returndata) = address(proxy).call(hex\"\");\n assertEq(success, false);\n\n bytes memory err = abi.encodeWithSignature(\n \"Error(string)\",\n \"Proxy: implementation not initialized\"\n );\n\n assertEq(returndata, err);\n }\n}\n" - }, - "contracts/test/ProxyAdmin.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { SimpleStorage } from \"./Proxy.t.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\n\ncontract ProxyAdmin_Test is Test {\n address alice = address(64);\n\n Proxy proxy;\n L1ChugSplashProxy chugsplash;\n ResolvedDelegateProxy resolved;\n\n AddressManager addressManager;\n\n ProxyAdmin admin;\n\n SimpleStorage implementation;\n\n function setUp() external {\n // Deploy the proxy admin\n admin = new ProxyAdmin(alice);\n // Deploy the standard proxy\n proxy = new Proxy(address(admin));\n\n // Deploy the legacy L1ChugSplashProxy with the admin as the owner\n chugsplash = new L1ChugSplashProxy(address(admin));\n\n // Deploy the legacy AddressManager\n addressManager = new AddressManager();\n // The proxy admin must be the new owner of the address manager\n addressManager.transferOwnership(address(admin));\n // Deploy a legacy ResolvedDelegateProxy with the name `a`.\n // Whatever `a` is set to in AddressManager will be the address\n // that is used for the implementation.\n resolved = new ResolvedDelegateProxy(addressManager, \"a\");\n\n // Impersonate alice for setting up the admin.\n vm.startPrank(alice);\n // Set the address of the address manager in the admin so that it\n // can resolve the implementation address of legacy\n // ResolvedDelegateProxy based proxies.\n admin.setAddressManager(addressManager);\n // Set the reverse lookup of the ResolvedDelegateProxy\n // proxy\n admin.setImplementationName(address(resolved), \"a\");\n\n // Set the proxy types\n admin.setProxyType(address(proxy), ProxyAdmin.ProxyType.ERC1967);\n admin.setProxyType(address(chugsplash), ProxyAdmin.ProxyType.CHUGSPLASH);\n admin.setProxyType(address(resolved), ProxyAdmin.ProxyType.RESOLVED);\n vm.stopPrank();\n\n implementation = new SimpleStorage();\n }\n\n function test_setImplementationName_succeeds() external {\n vm.prank(alice);\n admin.setImplementationName(address(1), \"foo\");\n assertEq(admin.implementationName(address(1)), \"foo\");\n }\n\n function test_setAddressManager_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setAddressManager(AddressManager((address(0))));\n }\n\n function test_setImplementationName_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setImplementationName(address(0), \"foo\");\n }\n\n function test_setProxyType_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setProxyType(address(0), ProxyAdmin.ProxyType.CHUGSPLASH);\n }\n\n function test_owner_succeeds() external {\n assertEq(admin.owner(), alice);\n }\n\n function test_proxyType_succeeds() external {\n assertEq(uint256(admin.proxyType(address(proxy))), uint256(ProxyAdmin.ProxyType.ERC1967));\n assertEq(\n uint256(admin.proxyType(address(chugsplash))),\n uint256(ProxyAdmin.ProxyType.CHUGSPLASH)\n );\n assertEq(\n uint256(admin.proxyType(address(resolved))),\n uint256(ProxyAdmin.ProxyType.RESOLVED)\n );\n }\n\n function test_erc1967GetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(proxy));\n }\n\n function test_chugsplashGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(resolved));\n }\n\n function getProxyImplementation(address payable _proxy) internal {\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(0));\n }\n\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n }\n\n function test_erc1967GetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(resolved));\n }\n\n function getProxyAdmin(address payable _proxy) internal {\n address owner = admin.getProxyAdmin(_proxy);\n assertEq(owner, address(admin));\n }\n\n function test_erc1967ChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(resolved));\n }\n\n function changeProxyAdmin(address payable _proxy) internal {\n ProxyAdmin.ProxyType proxyType = admin.proxyType(address(_proxy));\n\n vm.prank(alice);\n admin.changeProxyAdmin(_proxy, address(128));\n\n // The proxy is no longer the admin and can\n // no longer call the proxy interface except for\n // the ResolvedDelegate type on which anybody can\n // call the admin interface.\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n vm.expectRevert(\"Proxy: implementation not initialized\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n vm.expectRevert(\"L1ChugSplashProxy: implementation is not set yet\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n // Just an empty block to show that all cases are covered\n } else {\n vm.expectRevert(\"ProxyAdmin: unknown proxy type\");\n }\n\n // Call the proxy contract directly to get the admin.\n // Different proxy types have different interfaces.\n vm.prank(address(128));\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n assertEq(Proxy(payable(_proxy)).admin(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n assertEq(L1ChugSplashProxy(payable(_proxy)).getOwner(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n assertEq(addressManager.owner(), address(128));\n } else {\n assert(false);\n }\n }\n\n function test_erc1967Upgrade_succeeds() external {\n upgrade(payable(proxy));\n }\n\n function test_chugsplashUpgrade_succeeds() external {\n upgrade(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgrade_succeeds() external {\n upgrade(payable(resolved));\n }\n\n function upgrade(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n\n function test_erc1967UpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(proxy));\n }\n\n function test_chugsplashUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(resolved));\n }\n\n function upgradeAndCall(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgradeAndCall(\n _proxy,\n address(implementation),\n abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1)\n );\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n\n uint256 got = SimpleStorage(address(_proxy)).get(1);\n assertEq(got, 1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.changeProxyAdmin(payable(proxy), address(0));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgrade(payable(proxy), address(implementation));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgradeAndCall(payable(proxy), address(implementation), hex\"\");\n }\n\n function test_isUpgrading_succeeds() external {\n assertEq(false, admin.isUpgrading());\n\n vm.prank(alice);\n admin.setUpgrading(true);\n assertEq(true, admin.isUpgrading());\n }\n}\n" - }, - "contracts/test/RLP.t.sol": { - "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\n/**\n * @title LibRLP\n * @notice Via https://github.com/Rari-Capital/solmate/issues/207.\n */\nlibrary LibRLP {\n using Bytes32AddressLib for bytes32;\n\n function computeAddress(address deployer, uint256 nonce) internal pure returns (address) {\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))\n .fromLast20Bytes();\n if (nonce <= 0x7f)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))\n .fromLast20Bytes();\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= type(uint8).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd7),\n bytes1(0x94),\n deployer,\n bytes1(0x81),\n uint8(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint16).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd8),\n bytes1(0x94),\n deployer,\n bytes1(0x82),\n uint16(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint24).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd9),\n bytes1(0x94),\n deployer,\n bytes1(0x83),\n uint24(nonce)\n )\n ).fromLast20Bytes();\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return\n keccak256(\n abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))\n ).fromLast20Bytes();\n }\n}\n" - }, - "contracts/test/RLPReader.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { RLPReader } from \"../libraries/rlp/RLPReader.sol\";\n\ncontract RLPReader_readBytes_Test is CommonTest {\n function test_readBytes_bytestring00_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"00\"), hex\"00\");\n }\n\n function test_readBytes_bytestring01_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"01\"), hex\"01\");\n }\n\n function test_readBytes_bytestring7f_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"7f\"), hex\"7f\");\n }\n\n function test_readBytes_revertListItem_reverts() external {\n vm.expectRevert(\"RLPReader: decoded item type for bytes is not a data item\");\n RLPReader.readBytes(hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_readBytes_invalidStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n RLPReader.readBytes(hex\"b9\");\n }\n\n function test_readBytes_invalidListLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n RLPReader.readBytes(hex\"ff\");\n }\n\n function test_readBytes_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: bytes value contains an invalid remainder\");\n RLPReader.readBytes(hex\"800a\");\n }\n\n function test_readBytes_invalidPrefix_reverts() external {\n vm.expectRevert(\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n RLPReader.readBytes(hex\"810a\");\n }\n}\n\ncontract RLPReader_readList_Test is CommonTest {\n function test_readList_empty_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c0\");\n assertEq(list.length, 0);\n }\n\n function test_readList_multiList_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c6827a77c10401\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"827a77\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c104\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"01\");\n }\n\n function test_readList_shortListMax1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n\n assertEq(list.length, 11);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[4]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[5]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[6]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[7]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[8]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[9]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[10]), hex\"8471776572\");\n }\n\n function test_readList_longList1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n\n assertEq(list.length, 4);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"cf84617364668471776572847a786376\");\n }\n\n function test_readList_longList2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n assertEq(list.length, 32);\n\n for (uint256 i = 0; i < 32; i++) {\n assertEq(RLPReader.readRawBytes(list[i]), hex\"cf84617364668471776572847a786376\");\n }\n }\n\n function test_readList_listLongerThan32Elements_reverts() external {\n vm.expectRevert(stdError.indexOOBError);\n RLPReader.readList(\n hex\"e1454545454545454545454545454545454545454545454545454545454545454545\"\n );\n }\n\n function test_readList_listOfLists_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c4c2c0c0c0\");\n assertEq(list.length, 2);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c2c0c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c0\");\n }\n\n function test_readList_listOfLists2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c7c0c1c0c3c0c1c0\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c1c0\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"c3c0c1c0\");\n }\n\n function test_readList_dictTest1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n assertEq(list.length, 4);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"ca846b6579318476616c31\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"ca846b6579328476616c32\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"ca846b6579338476616c33\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"ca846b6579348476616c34\");\n }\n\n function test_readList_invalidShortList_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efdebd\");\n }\n\n function test_readList_longStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efb83600\");\n }\n\n function test_readList_notLongEnough_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(\n hex\"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n );\n }\n\n function test_readList_int32Overflow_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"bf0f000000000000021111\");\n }\n\n function test_readList_int32Overflow2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ff0f000000000000021111\");\n }\n\n function test_readList_incorrectLengthInArray_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(hex\"b800\");\n }\n\n function test_readList_leadingZerosInLongLengthList1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must not have any leading zeros (long list)\");\n RLPReader.readList(\n hex\"fb00000040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_nonOptimalLongLengthArray1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b81000112233445566778899aabbccddeeff\");\n }\n\n function test_readList_nonOptimalLongLengthArray2_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b801ff\");\n }\n\n function test_readList_invalidValue_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n RLPReader.readList(hex\"91\");\n }\n\n function test_readList_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n RLPReader.readList(hex\"c000\");\n }\n\n function test_readList_notEnoughContentForString1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"ba010000aabbccddeeff\");\n }\n\n function test_readList_notEnoughContentForString2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"b840ffeeddccbbaa99887766554433221100\");\n }\n\n function test_readList_notEnoughContentForList1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"f90180\");\n }\n\n function test_readList_notEnoughContentForList2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ffffffffffffffffff0001020304050607\");\n }\n\n function test_readList_longStringLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b80100\");\n }\n\n function test_readList_longListLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long list)\");\n RLPReader.readList(hex\"f80100\");\n }\n}\n" - }, - "contracts/test/RLPWriter.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { RLPWriter } from \"../libraries/rlp/RLPWriter.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\n\ncontract RLPWriter_writeString_Test is CommonTest {\n function test_writeString_empty_succeeds() external {\n assertEq(RLPWriter.writeString(\"\"), hex\"80\");\n }\n\n function test_writeString_bytestring00_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0000\"), hex\"00\");\n }\n\n function test_writeString_bytestring01_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0001\"), hex\"01\");\n }\n\n function test_writeString_bytestring7f_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u007F\"), hex\"7f\");\n }\n\n function test_writeString_shortstring_succeeds() external {\n assertEq(RLPWriter.writeString(\"dog\"), hex\"83646f67\");\n }\n\n function test_writeString_shortstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing eli\"),\n hex\"b74c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69\"\n );\n }\n\n function test_writeString_longstring_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing elit\"),\n hex\"b8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974\"\n );\n }\n\n function test_writeString_longstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\n \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat\"\n ),\n hex\"b904004c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742e20437572616269747572206d6175726973206d61676e612c20737573636970697420736564207665686963756c61206e6f6e2c20696163756c697320666175636962757320746f72746f722e2050726f696e20737573636970697420756c74726963696573206d616c6573756164612e204475697320746f72746f7220656c69742c2064696374756d2071756973207472697374697175652065752c20756c7472696365732061742072697375732e204d6f72626920612065737420696d70657264696574206d6920756c6c616d636f7270657220616c6971756574207375736369706974206e6563206c6f72656d2e2041656e65616e2071756973206c656f206d6f6c6c69732c2076756c70757461746520656c6974207661726975732c20636f6e73657175617420656e696d2e204e756c6c6120756c74726963657320747572706973206a7573746f2c20657420706f73756572652075726e6120636f6e7365637465747572206e65632e2050726f696e206e6f6e20636f6e76616c6c6973206d657475732e20446f6e65632074656d706f7220697073756d20696e206d617572697320636f6e67756520736f6c6c696369747564696e2e20566573746962756c756d20616e746520697073756d207072696d697320696e206661756369627573206f726369206c756374757320657420756c74726963657320706f737565726520637562696c69612043757261653b2053757370656e646973736520636f6e76616c6c69732073656d2076656c206d617373612066617563696275732c2065676574206c6163696e6961206c616375732074656d706f722e204e756c6c61207175697320756c747269636965732070757275732e2050726f696e20617563746f722072686f6e637573206e69626820636f6e64696d656e74756d206d6f6c6c69732e20416c697175616d20636f6e73657175617420656e696d206174206d65747573206c75637475732c206120656c656966656e6420707572757320656765737461732e20437572616269747572206174206e696268206d657475732e204e616d20626962656e64756d2c206e6571756520617420617563746f72207472697374697175652c206c6f72656d206c696265726f20616c697175657420617263752c206e6f6e20696e74657264756d2074656c6c7573206c65637475732073697420616d65742065726f732e20437261732072686f6e6375732c206d65747573206163206f726e617265206375727375732c20646f6c6f72206a7573746f20756c747269636573206d657475732c20617420756c6c616d636f7270657220766f6c7574706174\"\n );\n }\n}\n\ncontract RLPWriter_writeUint_Test is CommonTest {\n function test_writeUint_zero_succeeds() external {\n assertEq(RLPWriter.writeUint(0x0), hex\"80\");\n }\n\n function test_writeUint_smallint_succeeds() external {\n assertEq(RLPWriter.writeUint(1), hex\"01\");\n }\n\n function test_writeUint_smallint2_succeeds() external {\n assertEq(RLPWriter.writeUint(16), hex\"10\");\n }\n\n function test_writeUint_smallint3_succeeds() external {\n assertEq(RLPWriter.writeUint(79), hex\"4f\");\n }\n\n function test_writeUint_smallint4_succeeds() external {\n assertEq(RLPWriter.writeUint(127), hex\"7f\");\n }\n\n function test_writeUint_mediumint_succeeds() external {\n assertEq(RLPWriter.writeUint(128), hex\"8180\");\n }\n\n function test_writeUint_mediumint2_succeeds() external {\n assertEq(RLPWriter.writeUint(1000), hex\"8203e8\");\n }\n\n function test_writeUint_mediumint3_succeeds() external {\n assertEq(RLPWriter.writeUint(100000), hex\"830186a0\");\n }\n}\n\ncontract RLPWriter_writeList_Test is CommonTest {\n function test_writeList_empty_succeeds() external {\n assertEq(RLPWriter.writeList(new bytes[](0)), hex\"c0\");\n }\n\n function test_writeList_stringList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeString(\"dog\");\n list[1] = RLPWriter.writeString(\"god\");\n list[2] = RLPWriter.writeString(\"cat\");\n\n assertEq(RLPWriter.writeList(list), hex\"cc83646f6783676f6483636174\");\n }\n\n function test_writeList_multiList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeUint(4);\n\n list[0] = RLPWriter.writeString(\"zw\");\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeUint(1);\n\n assertEq(RLPWriter.writeList(list), hex\"c6827a77c10401\");\n }\n\n function test_writeList_shortListMax1_succeeds() external {\n bytes[] memory list = new bytes[](11);\n list[0] = RLPWriter.writeString(\"asdf\");\n list[1] = RLPWriter.writeString(\"qwer\");\n list[2] = RLPWriter.writeString(\"zxcv\");\n list[3] = RLPWriter.writeString(\"asdf\");\n list[4] = RLPWriter.writeString(\"qwer\");\n list[5] = RLPWriter.writeString(\"zxcv\");\n list[6] = RLPWriter.writeString(\"asdf\");\n list[7] = RLPWriter.writeString(\"qwer\");\n list[8] = RLPWriter.writeString(\"zxcv\");\n list[9] = RLPWriter.writeString(\"asdf\");\n list[10] = RLPWriter.writeString(\"qwer\");\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n }\n\n function test_writeList_longlist1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list2);\n list[3] = RLPWriter.writeList(list2);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_longlist2_succeeds() external {\n bytes[] memory list = new bytes[](32);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n for (uint256 i = 0; i < 32; i++) {\n list[i] = RLPWriter.writeList(list2);\n }\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_listoflists_succeeds() external {\n // [ [ [], [] ], [] ]\n bytes[] memory list = new bytes[](2);\n bytes[] memory list2 = new bytes[](2);\n\n list2[0] = RLPWriter.writeList(new bytes[](0));\n list2[1] = RLPWriter.writeList(new bytes[](0));\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(new bytes[](0));\n\n assertEq(RLPWriter.writeList(list), hex\"c4c2c0c0c0\");\n }\n\n function test_writeList_listoflists2_succeeds() external {\n // [ [], [[]], [ [], [[]] ] ]\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeList(new bytes[](0));\n\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeList(new bytes[](0));\n\n list[1] = RLPWriter.writeList(list2);\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeList(new bytes[](0));\n list3[1] = RLPWriter.writeList(list2);\n\n list[2] = RLPWriter.writeList(list3);\n\n assertEq(RLPWriter.writeList(list), hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_writeList_dictTest1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n\n bytes[] memory list1 = new bytes[](2);\n list1[0] = RLPWriter.writeString(\"key1\");\n list1[1] = RLPWriter.writeString(\"val1\");\n\n bytes[] memory list2 = new bytes[](2);\n list2[0] = RLPWriter.writeString(\"key2\");\n list2[1] = RLPWriter.writeString(\"val2\");\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeString(\"key3\");\n list3[1] = RLPWriter.writeString(\"val3\");\n\n bytes[] memory list4 = new bytes[](2);\n list4[0] = RLPWriter.writeString(\"key4\");\n list4[1] = RLPWriter.writeString(\"val4\");\n\n list[0] = RLPWriter.writeList(list1);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list3);\n list[3] = RLPWriter.writeList(list4);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n }\n}\n" - }, - "contracts/test/ResolvedDelegateProxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\n\ncontract ResolvedDelegateProxy_Test is Test {\n AddressManager internal addressManager;\n SimpleImplementation internal impl;\n SimpleImplementation internal proxy;\n\n function setUp() public {\n // Set up the address manager.\n addressManager = new AddressManager();\n impl = new SimpleImplementation();\n addressManager.setAddress(\"SimpleImplementation\", address(impl));\n\n // Set up the proxy.\n proxy = SimpleImplementation(\n address(new ResolvedDelegateProxy(addressManager, \"SimpleImplementation\"))\n );\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall succeeds.\n function testFuzz_fallback_delegateCallFoo_succeeds(uint256 x) public {\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.foo.selector, x));\n assertEq(proxy.foo(x), x);\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall reverts.\n function test_fallback_delegateCallBar_reverts() public {\n vm.expectRevert(\"SimpleImplementation: revert\");\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.bar.selector));\n proxy.bar();\n }\n\n // Tests that the proxy fallback reverts as expected if the implementation within the\n // address manager is not set.\n function test_fallback_addressManagerNotSet_reverts() public {\n AddressManager am = new AddressManager();\n SimpleImplementation p = SimpleImplementation(\n address(new ResolvedDelegateProxy(am, \"SimpleImplementation\"))\n );\n\n vm.expectRevert(\"ResolvedDelegateProxy: target address must be initialized\");\n p.foo(0);\n }\n}\n\ncontract SimpleImplementation {\n function foo(uint256 _x) public pure returns (uint256) {\n return _x;\n }\n\n function bar() public pure {\n revert(\"SimpleImplementation: revert\");\n }\n}\n" - }, - "contracts/test/ResourceMetering.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract MeterUser is ResourceMetering {\n constructor() {\n initialize();\n }\n\n function initialize() public initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public pure returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function use(uint64 _amount) public metered(_amount) {}\n\n function set(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) public {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n}\n\n/**\n * @title ResourceConfig\n * @notice The tests are based on the default config values. It is expected that\n * the config values used in these tests are ran in production.\n */\ncontract ResourceMetering_Test is Test {\n MeterUser internal meter;\n uint64 initialBlockNum;\n\n function setUp() public {\n meter = new MeterUser();\n initialBlockNum = uint64(block.number);\n }\n\n function test_meter_initialResourceParams_succeeds() external {\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_updateParamsNoChange_succeeds() external {\n meter.use(0); // equivalent to just updating the base fee and block number\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n meter.use(0);\n (uint128 postBaseFee, uint64 postBoughtGas, uint64 postBlockNum) = meter.params();\n\n assertEq(postBaseFee, prevBaseFee);\n assertEq(postBoughtGas, prevBoughtGas);\n assertEq(postBlockNum, prevBlockNum);\n }\n\n function test_meter_updateOneEmptyBlock_succeeds() external {\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 1);\n }\n\n function test_meter_updateTwoEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 2);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 2);\n }\n\n function test_meter_updateTenEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 10);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 10);\n }\n\n function test_meter_updateNoGasDelta_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint256 target = uint256(rcfg.maxResourceLimit) / uint256(rcfg.elasticityMultiplier);\n meter.use(uint64(target));\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1000000000);\n assertEq(prevBoughtGas, target);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_useMax_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n meter.use(target * elasticityMultiplier);\n\n (, uint64 prevBoughtGas, ) = meter.params();\n assertEq(prevBoughtGas, target * elasticityMultiplier);\n\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 postBaseFee, , ) = meter.params();\n assertEq(postBaseFee, 2125000000);\n }\n\n function test_meter_useMoreThanMax_reverts() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.expectRevert(\"ResourceMetering: cannot buy more gas than available gas limit\");\n meter.use(target * elasticityMultiplier + 1);\n }\n\n // Demonstrates that the resource metering arithmetic can tolerate very large gaps between\n // deposits.\n function testFuzz_meter_largeBlockDiff_succeeds(uint64 _amount, uint256 _blockDiff) external {\n // This test fails if the following line is commented out.\n // At 12 seconds per block, this number is effectively unreachable.\n vm.assume(_blockDiff < 433576281058164217753225238677900874458691);\n\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.assume(_amount < target * elasticityMultiplier);\n vm.roll(initialBlockNum + _blockDiff);\n meter.use(_amount);\n }\n}\n\n/**\n * @title CustomMeterUser\n * @notice A simple wrapper around `ResourceMetering` that allows the initial\n * params to be set in the constructor.\n */\ncontract CustomMeterUser is ResourceMetering {\n uint256 public startGas;\n uint256 public endGas;\n\n constructor(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function use(uint64 _amount) public returns (uint256) {\n uint256 initialGas = gasleft();\n _metered(_amount, initialGas);\n return initialGas - gasleft();\n }\n}\n\n/**\n * @title ArtifactResourceMetering_Test\n * @notice A table test that sets the state of the ResourceParams and then requests\n * various amounts of gas. This test ensures that a wide range of values\n * can safely be used with the `ResourceMetering` contract.\n * It also writes a CSV file to disk that includes useful information\n * about how much gas is used and how expensive it is in USD terms to\n * purchase the deposit gas.\n */\ncontract ArtifactResourceMetering_Test is Test {\n uint128 internal minimumBaseFee;\n uint128 internal maximumBaseFee;\n uint64 internal maxResourceLimit;\n uint64 internal targetResourceLimit;\n\n string internal outfile;\n\n // keccak256(abi.encodeWithSignature(\"Error(string)\", \"ResourceMetering: cannot buy more gas than available gas limit\"))\n bytes32 internal cannotBuyMoreGas =\n 0x84edc668cfd5e050b8999f43ff87a1faaa93e5f935b20bc1dd4d3ff157ccf429;\n // keccak256(abi.encodeWithSignature(\"Panic(uint256)\", 0x11))\n bytes32 internal overflowErr =\n 0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;\n // keccak256(hex\"\")\n bytes32 internal emptyReturnData =\n 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n\n /**\n * @notice Sets up the tests by getting constants from the ResourceMetering\n * contract.\n */\n function setUp() public {\n vm.roll(1_000_000);\n\n MeterUser base = new MeterUser();\n ResourceMetering.ResourceConfig memory rcfg = base.resourceConfig();\n minimumBaseFee = uint128(rcfg.minimumBaseFee);\n maximumBaseFee = rcfg.maximumBaseFee;\n maxResourceLimit = uint64(rcfg.maxResourceLimit);\n targetResourceLimit = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n\n outfile = string.concat(vm.projectRoot(), \"/.resource-metering.csv\");\n try vm.removeFile(outfile) {} catch {}\n }\n\n /**\n * @notice Generate a CSV file. The call to `meter` should be called with at\n * most the L1 block gas limit. Without specifying the amount of\n * gas, it can take very long to execute.\n */\n function test_meter_generateArtifact_succeeds() external {\n vm.writeLine(\n outfile,\n \"prevBaseFee,prevBoughtGas,prevBlockNumDiff,l1BaseFee,requestedGas,gasConsumed,ethPrice,usdCost,success\"\n );\n\n // prevBaseFee value in ResourceParams\n uint128[] memory prevBaseFees = new uint128[](5);\n prevBaseFees[0] = minimumBaseFee;\n prevBaseFees[1] = maximumBaseFee;\n prevBaseFees[2] = uint128(50 gwei);\n prevBaseFees[3] = uint128(100 gwei);\n prevBaseFees[4] = uint128(200 gwei);\n\n // prevBoughtGas value in ResourceParams\n uint64[] memory prevBoughtGases = new uint64[](1);\n prevBoughtGases[0] = uint64(0);\n\n // prevBlockNum diff, simulates blocks with no deposits when non zero\n uint64[] memory prevBlockNumDiffs = new uint64[](2);\n prevBlockNumDiffs[0] = 0;\n prevBlockNumDiffs[1] = 1;\n\n // The amount of L2 gas that a user requests\n uint64[] memory requestedGases = new uint64[](3);\n requestedGases[0] = maxResourceLimit;\n requestedGases[1] = targetResourceLimit;\n requestedGases[2] = uint64(100_000);\n\n // The L1 base fee\n uint256[] memory l1BaseFees = new uint256[](4);\n l1BaseFees[0] = 1 gwei;\n l1BaseFees[1] = 50 gwei;\n l1BaseFees[2] = 75 gwei;\n l1BaseFees[3] = 100 gwei;\n\n // USD price of 1 ether\n uint256[] memory ethPrices = new uint256[](2);\n ethPrices[0] = 1600;\n ethPrices[1] = 3200;\n\n // Iterate over all of the test values and run a test\n for (uint256 i; i < prevBaseFees.length; i++) {\n for (uint256 j; j < prevBoughtGases.length; j++) {\n for (uint256 k; k < prevBlockNumDiffs.length; k++) {\n for (uint256 l; l < requestedGases.length; l++) {\n for (uint256 m; m < l1BaseFees.length; m++) {\n for (uint256 n; n < ethPrices.length; n++) {\n uint256 snapshotId = vm.snapshot();\n\n uint128 prevBaseFee = prevBaseFees[i];\n uint64 prevBoughtGas = prevBoughtGases[j];\n uint64 prevBlockNumDiff = prevBlockNumDiffs[k];\n uint64 requestedGas = requestedGases[l];\n uint256 l1BaseFee = l1BaseFees[m];\n uint256 ethPrice = ethPrices[n];\n string memory result = \"success\";\n\n vm.fee(l1BaseFee);\n\n CustomMeterUser meter = new CustomMeterUser({\n _prevBaseFee: prevBaseFee,\n _prevBoughtGas: prevBoughtGas,\n _prevBlockNum: uint64(block.number)\n });\n\n vm.roll(block.number + prevBlockNumDiff);\n\n // Call the metering code and catch the various\n // types of errors.\n uint256 gasConsumed = 0;\n try meter.use{ gas: 30_000_000 }(requestedGas) returns (\n uint256 _gasConsumed\n ) {\n gasConsumed = _gasConsumed;\n } catch (bytes memory err) {\n bytes32 hash = keccak256(err);\n if (hash == cannotBuyMoreGas) {\n result = \"ResourceMetering: cannot buy more gas than available gas limit\";\n } else if (hash == overflowErr) {\n result = \"arithmetic overflow/underflow\";\n } else if (hash == emptyReturnData) {\n result = \"out of gas\";\n } else {\n result = \"UNKNOWN ERROR\";\n }\n }\n\n // Compute the USD cost of the gas used\n uint256 usdCost = (gasConsumed * l1BaseFee * ethPrice) / 1 ether;\n\n vm.writeLine(\n outfile,\n string.concat(\n vm.toString(prevBaseFee),\n \",\",\n vm.toString(prevBoughtGas),\n \",\",\n vm.toString(prevBlockNumDiff),\n \",\",\n vm.toString(l1BaseFee),\n \",\",\n vm.toString(requestedGas),\n \",\",\n vm.toString(gasConsumed),\n \",\",\n \"$\",\n vm.toString(ethPrice),\n \",\",\n \"$\",\n vm.toString(usdCost),\n \",\",\n result\n )\n );\n\n assertTrue(vm.revertTo(snapshotId));\n }\n }\n }\n }\n }\n }\n }\n}\n" - }, - "contracts/test/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\n\ncontract SafeCall_call_Test is CommonTest {\n function testFuzz_call_succeeds(\n address from,\n address to,\n uint256 gas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCall(to, value, data);\n vm.prank(from);\n bool success = SafeCall.call(to, gas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function testFuzz_callWithMinGas_hasEnough_succeeds(\n address from,\n address to,\n uint64 minGas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n // Bound minGas to [0, l1_block_gas_limit]\n minGas = uint64(bound(minGas, 0, 30_000_000));\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCallMinGas(to, value, minGas, data);\n vm.prank(from);\n bool success = SafeCall.callWithMinGas(to, minGas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function test_callWithMinGas_noLeakageLow_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 5000; i < 50_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 26,071 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 26_071) {\n assertFalse(caller.makeSafeCall(i, 25_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 25_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 25_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n\n function test_callWithMinGas_noLeakageHigh_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 15_200_000; i < 15_300_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 15,238,769 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 15_238_769) {\n assertFalse(caller.makeSafeCall(i, 15_000_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 15_000_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 15_000_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n}\n\ncontract SimpleSafeCaller {\n uint256 public a;\n\n function makeSafeCall(uint64 gas, uint64 minGas) external returns (bool) {\n return\n SafeCall.call(\n address(this),\n gas,\n 0,\n abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas)\n );\n }\n\n function makeSafeCallMinGas(uint64 minGas) external returns (bool) {\n return\n SafeCall.callWithMinGas(\n address(this),\n minGas,\n 0,\n abi.encodeWithSelector(this.setA.selector, 1)\n );\n }\n\n function setA(uint256 _a) external {\n a = _a;\n }\n}\n" - }, - "contracts/test/Semver.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\n\n/**\n * @notice Test the Semver contract that is used for semantic versioning\n * of various contracts.\n */\ncontract Semver_Test is CommonTest {\n /**\n * @notice Global semver contract deployed in setUp. This is used in\n * the test cases.\n */\n Semver semver;\n\n /**\n * @notice Deploy a Semver contract\n */\n function setUp() public virtual override {\n semver = new Semver(7, 8, 0);\n }\n\n /**\n * @notice Test the version getter\n */\n function test_version_succeeds() external {\n assertEq(semver.version(), \"7.8.0\");\n }\n\n /**\n * @notice Since the versions are all immutable, they should\n * be able to be accessed from behind a proxy without needing\n * to initialize the contract.\n */\n function test_behindProxy_succeeds() external {\n Proxy proxy = new Proxy(alice);\n vm.prank(alice);\n proxy.upgradeTo(address(semver));\n\n assertEq(Semver(address(proxy)).version(), \"7.8.0\");\n }\n}\n" - }, - "contracts/test/SequencerFeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { SequencerFeeVault } from \"../L2/SequencerFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract SequencerFeeVault_Test is Bridge_Initializer {\n SequencerFeeVault vault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET));\n address constant recipient = address(256);\n\n event Withdrawal(uint256 value, address to, address from);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.SEQUENCER_FEE_WALLET, address(new SequencerFeeVault(recipient)).code);\n vm.label(Predeploys.SEQUENCER_FEE_WALLET, \"SequencerFeeVault\");\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n\n function test_constructor_succeeds() external {\n assertEq(vault.l1FeeWallet(), recipient);\n }\n\n function test_receive_succeeds() external {\n uint256 balance = address(vault).balance;\n\n vm.prank(alice);\n (bool success, ) = address(vault).call{ value: 100 }(hex\"\");\n\n assertEq(success, true);\n assertEq(address(vault).balance, balance + 100);\n }\n\n function test_withdraw_notEnough_reverts() external {\n assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());\n\n vm.expectRevert(\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n vault.withdraw();\n }\n\n function test_withdraw_succeeds() external {\n uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1;\n vm.deal(address(vault), amount);\n\n // No ether has been withdrawn yet\n assertEq(vault.totalProcessed(), 0);\n\n vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));\n emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));\n\n // The entire vault's balance is withdrawn\n vm.expectCall(\n Predeploys.L2_STANDARD_BRIDGE,\n address(vault).balance,\n abi.encodeWithSelector(\n StandardBridge.bridgeETHTo.selector,\n vault.l1FeeWallet(),\n 35_000,\n bytes(\"\")\n )\n );\n\n vault.withdraw();\n\n // The withdrawal was successful\n assertEq(vault.totalProcessed(), amount);\n }\n}\n" - }, - "contracts/test/StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport {\n OptimismMintableERC20,\n ILegacyMintableERC20\n} from \"../universal/OptimismMintableERC20.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/**\n * @title StandardBridgeTester\n * @notice Simple wrapper around the StandardBridge contract that exposes\n * internal functions so they can be more easily tested directly.\n */\ncontract StandardBridgeTester is StandardBridge {\n constructor(address payable _messenger, address payable _otherBridge)\n StandardBridge(_messenger, _otherBridge)\n {}\n\n function isOptimismMintableERC20(address _token) external view returns (bool) {\n return _isOptimismMintableERC20(_token);\n }\n\n function isCorrectTokenPair(address _mintableToken, address _otherToken)\n external\n view\n returns (bool)\n {\n return _isCorrectTokenPair(_mintableToken, _otherToken);\n }\n\n receive() external payable override {}\n}\n\n/**\n * @title LegacyMintable\n * @notice Simple implementation of the legacy OptimismMintableERC20.\n */\ncontract LegacyMintable is ERC20, ILegacyMintableERC20 {\n constructor(string memory _name, string memory _ticker) ERC20(_name, _ticker) {}\n\n function l1Token() external pure returns (address) {\n return address(0);\n }\n\n function mint(address _to, uint256 _amount) external pure {}\n\n function burn(address _from, uint256 _amount) external pure {}\n\n /**\n * @notice Implements ERC165. This implementation should not be changed as\n * it is how the actual legacy optimism mintable token does the\n * check. Allows for testing against code that is has been deployed,\n * assuming different compiler version is no problem.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n}\n\n/**\n * @title StandardBridge_Stateless_Test\n * @notice Tests internal functions that require no existing state or contract\n * interactions with the messenger.\n */\ncontract StandardBridge_Stateless_Test is CommonTest {\n StandardBridgeTester internal bridge;\n OptimismMintableERC20 internal mintable;\n ERC20 internal erc20;\n LegacyMintable internal legacy;\n\n function setUp() public override {\n super.setUp();\n\n bridge = new StandardBridgeTester({\n _messenger: payable(address(0)),\n _otherBridge: payable(address(0))\n });\n\n mintable = new OptimismMintableERC20({\n _bridge: address(0),\n _remoteToken: address(0),\n _name: \"Stonks\",\n _symbol: \"STONK\"\n });\n\n erc20 = new ERC20(\"Altcoin\", \"ALT\");\n legacy = new LegacyMintable(\"Legacy\", \"LEG\");\n }\n\n /**\n * @notice Test coverage for identifying OptimismMintableERC20 tokens.\n * This function should return true for both modern and legacy\n * OptimismMintableERC20 tokens and false for any accounts that\n * do not implement the interface.\n */\n function test_isOptimismMintableERC20_succeeds() external {\n // Both the modern and legacy mintable tokens should return true\n assertTrue(bridge.isOptimismMintableERC20(address(mintable)));\n assertTrue(bridge.isOptimismMintableERC20(address(legacy)));\n // A regular ERC20 should return false\n assertFalse(bridge.isOptimismMintableERC20(address(erc20)));\n // Non existent contracts should return false and not revert\n assertEq(address(0x20).code.length, 0);\n assertFalse(bridge.isOptimismMintableERC20(address(0x20)));\n }\n\n /**\n * @notice Test coverage of isCorrectTokenPair under different types of\n * tokens.\n */\n function test_isCorrectTokenPair_succeeds() external {\n // Modern + known to be correct remote token\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.remoteToken()));\n // Modern + known to be correct l1Token (legacy interface)\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.l1Token()));\n // Modern + known to be incorrect remote token\n assertTrue(mintable.remoteToken() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(mintable), address(0x20)));\n // Legacy + known to be correct l1Token\n assertTrue(bridge.isCorrectTokenPair(address(legacy), legacy.l1Token()));\n // Legacy + known to be incorrect l1Token\n assertTrue(legacy.l1Token() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(legacy), address(0x20)));\n // A token that doesn't support either modern or legacy interface\n // will revert\n vm.expectRevert();\n bridge.isCorrectTokenPair(address(erc20), address(1));\n }\n}\n" - }, - "contracts/test/SystemConfig.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract SystemConfig_Init is CommonTest {\n SystemConfig sysConf;\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n sysConf = new SystemConfig({\n _owner: alice,\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: config\n });\n }\n}\n\ncontract SystemConfig_Initialize_TestFail is SystemConfig_Init {\n function test_initialize_lowGasLimit_reverts() external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n\n ResourceMetering.ResourceConfig memory cfg = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n new SystemConfig({\n _owner: alice,\n _overhead: 0,\n _scalar: 0,\n _batcherHash: bytes32(hex\"\"),\n _gasLimit: minimumGasLimit - 1,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n }\n}\n\ncontract SystemConfig_Setters_TestFail is SystemConfig_Init {\n function test_setBatcherHash_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setBatcherHash(bytes32(hex\"\"));\n }\n\n function test_setGasConfig_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasConfig(0, 0);\n }\n\n function test_setGasLimit_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasLimit(0);\n }\n\n function test_setUnsafeBlockSigner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setUnsafeBlockSigner(address(0x20));\n }\n\n function test_setResourceConfig_notOwner_reverts() external {\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badMinMax_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 2 gwei,\n maximumBaseFee: 1 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: min base fee must be less than max base\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_zeroDenominator_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 0,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: denominator cannot be 0\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_lowGasLimit_reverts() external {\n uint64 gasLimit = sysConf.gasLimit();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: uint32(gasLimit),\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: uint32(gasLimit),\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badPrecision_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 11,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: precision loss with target resource limit\");\n sysConf.setResourceConfig(config);\n }\n}\n\ncontract SystemConfig_Setters_Test is SystemConfig_Init {\n event ConfigUpdate(\n uint256 indexed version,\n SystemConfig.UpdateType indexed updateType,\n bytes data\n );\n\n function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash));\n\n vm.prank(sysConf.owner());\n sysConf.setBatcherHash(newBatcherHash);\n assertEq(sysConf.batcherHash(), newBatcherHash);\n }\n\n function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.GAS_CONFIG,\n abi.encode(newOverhead, newScalar)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setGasConfig(newOverhead, newScalar);\n assertEq(sysConf.overhead(), newOverhead);\n assertEq(sysConf.scalar(), newScalar);\n }\n\n function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {\n uint64 minimumGasLimit = sysConf.MINIMUM_GAS_LIMIT();\n newGasLimit = uint64(\n bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))\n );\n\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit));\n\n vm.prank(sysConf.owner());\n sysConf.setGasLimit(newGasLimit);\n assertEq(sysConf.gasLimit(), newGasLimit);\n }\n\n function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER,\n abi.encode(newUnsafeSigner)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setUnsafeBlockSigner(newUnsafeSigner);\n assertEq(sysConf.unsafeBlockSigner(), newUnsafeSigner);\n }\n}\n" - }, - "contracts/test/TransferOnion.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { TransferOnion } from \"../periphery/TransferOnion.sol\";\n\n/**\n * @title TransferOnionTest\n * @notice Test coverage of TransferOnion\n */\ncontract TransferOnionTest is Test {\n /**\n * @notice TransferOnion\n */\n TransferOnion internal onion;\n\n /**\n * @notice token constructor arg\n */\n address internal _token;\n\n /**\n * @notice sender constructor arg\n */\n address internal _sender;\n\n /**\n * @notice Sets up addresses, deploys contracts and funds the owner.\n */\n function setUp() public {\n ERC20 token = new ERC20(\"Token\", \"TKN\");\n _token = address(token);\n _sender = makeAddr(\"sender\");\n }\n\n /**\n * @notice Deploy the TransferOnion with a dummy shell\n */\n function _deploy() public {\n _deploy(bytes32(0));\n }\n\n /**\n * @notice Deploy the TransferOnion with a specific shell\n */\n function _deploy(bytes32 _shell) public {\n onion = new TransferOnion({ _token: ERC20(_token), _sender: _sender, _shell: _shell });\n }\n\n /**\n * @notice Build the onion data\n */\n function _onionize(TransferOnion.Layer[] memory _layers)\n public\n pure\n returns (bytes32, TransferOnion.Layer[] memory)\n {\n uint256 length = _layers.length;\n bytes32 hash = bytes32(0);\n for (uint256 i; i < length; i++) {\n TransferOnion.Layer memory layer = _layers[i];\n _layers[i].shell = hash;\n hash = keccak256(abi.encode(layer.recipient, layer.amount, hash));\n }\n return (hash, _layers);\n }\n\n /**\n * @notice The constructor sets the variables as expected\n */\n function test_constructor_succeeds() external {\n _deploy();\n\n assertEq(address(onion.TOKEN()), _token);\n assertEq(onion.SENDER(), _sender);\n assertEq(onion.shell(), bytes32(0));\n }\n\n /**\n * @notice unwrap\n */\n function test_unwrap_succeeds() external {\n // Commit to transferring tiny amounts of tokens\n TransferOnion.Layer[] memory _layers = new TransferOnion.Layer[](2);\n _layers[0] = TransferOnion.Layer(address(1), 1, bytes32(0));\n _layers[1] = TransferOnion.Layer(address(2), 2, bytes32(0));\n\n // Build the onion shell\n (bytes32 shell, TransferOnion.Layer[] memory layers) = _onionize(_layers);\n _deploy(shell);\n\n assertEq(onion.shell(), shell);\n\n address token = address(onion.TOKEN());\n address sender = onion.SENDER();\n\n // give 3 units of token to sender\n deal(token, onion.SENDER(), 3);\n vm.prank(sender);\n ERC20(token).approve(address(onion), 3);\n\n // To build the inputs, to `peel`, need to reverse the list\n TransferOnion.Layer[] memory inputs = new TransferOnion.Layer[](2);\n int256 length = int256(layers.length);\n for (int256 i = length - 1; i >= 0; i--) {\n uint256 ui = uint256(i);\n uint256 revidx = uint256(length) - ui - 1;\n TransferOnion.Layer memory layer = layers[ui];\n inputs[revidx] = layer;\n }\n\n // The accounts have no balance\n assertEq(ERC20(_token).balanceOf(address(1)), 0);\n assertEq(ERC20(_token).balanceOf(address(2)), 0);\n\n onion.peel(inputs);\n\n // Now the accounts have the expected balance\n assertEq(ERC20(_token).balanceOf(address(1)), 1);\n assertEq(ERC20(_token).balanceOf(address(2)), 2);\n }\n}\n" - }, - "contracts/test/invariants/CrossDomainMessenger.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { OptimismPortal } from \"../../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../../L1/L1CrossDomainMessenger.sol\";\nimport { Messenger_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\nimport { Predeploys } from \"../../libraries/Predeploys.sol\";\nimport { Encoding } from \"../../libraries/Encoding.sol\";\nimport { Hashing } from \"../../libraries/Hashing.sol\";\n\ncontract RelayActor is StdUtils {\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n uint256 public numHashes;\n bytes32[] public hashes;\n bool public reverted = false;\n\n OptimismPortal op;\n L1CrossDomainMessenger xdm;\n Vm vm;\n\n constructor(\n OptimismPortal _op,\n L1CrossDomainMessenger _xdm,\n Vm _vm\n ) {\n op = _op;\n xdm = _xdm;\n vm = _vm;\n }\n\n /**\n * Relays a message to the `L1CrossDomainMessenger` with a random `version`, `_minGasLimit`\n * and `_message`.\n */\n function relay(\n uint16 _version,\n uint32 _minGasLimit,\n bytes memory _message\n ) external {\n address target = address(0x04); // ID precompile\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Restrict `_minGasLimit` to a number in the range of the block gas limit.\n _minGasLimit = uint32(bound(_minGasLimit, 0, block.gaslimit));\n\n // Restrict version to the range of [0, 1]\n _version = _version % 2;\n\n // Compute the cross domain message hash and store it in `hashes`.\n // The `relayMessage` function will always encode the message as a version 1\n // message after checking that the V0 hash has not already been relayed.\n bytes32 _hash = Hashing.hashCrossDomainMessageV1(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n 0, // value\n _minGasLimit,\n _message\n );\n\n // Act as the optimism portal and call `relayMessage` on the `L1CrossDomainMessenger` with\n // the outer min gas limit.\n vm.startPrank(address(op));\n vm.expectCall(target, _message);\n try\n xdm.relayMessage{ gas: xdm.baseGas(_message, _minGasLimit) }(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n 0, // value\n _minGasLimit,\n _message\n )\n {} catch {\n // If any of these calls revert, set `reverted` to true to fail the invariant test.\n // NOTE: This is to get around forge's invariant fuzzer ignoring reverted calls\n // to this function.\n reverted = true;\n }\n vm.stopPrank();\n\n hashes.push(_hash);\n numHashes += 1;\n }\n}\n\ncontract XDM_MinGasLimits is Messenger_Initializer {\n RelayActor actor;\n\n function setUp() public virtual override {\n // Set up the `L1CrossDomainMessenger` and `OptimismPortal` contracts.\n super.setUp();\n\n // Deploy a relay actor\n actor = new RelayActor(op, L1Messenger, vm);\n\n // Target the `RelayActor` contract\n targetContract(address(actor));\n\n // Target the actor's `relay` function\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.relay.selector;\n targetSelector(FuzzSelector({ addr: address(actor), selectors: selectors }));\n }\n\n /**\n * @custom:invariant A call to `relayMessage` should never revert if at least the proper minimum\n * gas limits are supplied.\n *\n * There are two minimum gas limits here:\n *\n * - The outer min gas limit is for the call from the `OptimismPortal` to the\n * `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function\n * with the `message` and inner limit.\n *\n * - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target\n * contract.\n */\n function invariant_minGasLimits() public {\n uint256 length = actor.numHashes();\n for (uint256 i = 0; i < length; ++i) {\n bytes32 hash = actor.hashes(i);\n // the message hash is in the successfulMessages mapping\n assertTrue(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertFalse(L1Messenger.failedMessages(hash));\n }\n assertFalse(actor.reverted());\n }\n}\n" - }, - "contracts/test/invariants/L2OutputOracle.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { L2OutputOracle_Initializer } from \"../CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../../L1/L2OutputOracle.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\n\ncontract L2OutputOracle_Proposer {\n L2OutputOracle internal oracle;\n Vm internal vm;\n\n constructor(L2OutputOracle _oracle, Vm _vm) {\n oracle = _oracle;\n vm = _vm;\n }\n\n /**\n * @dev Allows the actor to propose an L2 output to the `L2OutputOracle`\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external {\n // Act as the proposer and propose a new output.\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _l2BlockNumber, _l1BlockHash, _l1BlockNumber);\n }\n}\n\ncontract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_Initializer {\n L2OutputOracle_Proposer internal actor;\n\n function setUp() public override {\n super.setUp();\n\n // Create a proposer actor.\n actor = new L2OutputOracle_Proposer(oracle, vm);\n\n // Set the target contract to the proposer actor.\n targetContract(address(actor));\n\n // Set the target selector for `proposeL2Output`\n // `proposeL2Output` is the only function we care about, as it is the only function\n // that can modify the `l2Outputs` array in the oracle.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.proposeL2Output.selector;\n FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The block number of the output root proposals should monotonically\n * increase.\n *\n * When a new output is submitted, it should never be allowed to correspond to a block\n * number that is less than the current output.\n */\n function invariant_monotonicBlockNumIncrease() external {\n // Assert that the block number of proposals must monotonically increase.\n assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber());\n }\n}\n" - }, - "contracts/test/invariants/OptimismPortal.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Portal_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\n\ncontract OptimismPortal_Invariant_Harness is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n function setUp() public virtual override {\n super.setUp();\n\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n}\n\ncontract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization\n * period has not elapsed.\n *\n * A withdrawal that has been proven should not be able to be finalized until after\n * the finalization period has elapsed.\n */\n function invariant_cannotFinalizeBeforePeriodHasPassed() external {\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Finalize the withdrawal transaction.\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal\n * has already been finalized.\n *\n * Ensures that there is no chain of calls that can be made that allows a withdrawal\n * to be finalized twice.\n */\n function invariant_cannotFinalizeTwice() external {\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant A withdrawal should **always** be able to be finalized\n * `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.\n *\n * This invariant asserts that there is no chain of calls that can be made that\n * will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS`\n * after it was successfully proven.\n */\n function invariant_canAlwaysFinalize() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value);\n }\n}\n" - }, - "contracts/test/invariants/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { SafeCall } from \"../../libraries/SafeCall.sol\";\n\ncontract SafeCall_Succeeds_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, false);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n }\n\n /**\n * @custom:invariant If `callWithMinGas` performs a call, then it must always\n * provide at least the specified minimum gas limit to the subcontext.\n *\n * If the check for remaining gas in `SafeCall.callWithMinGas` passes, the\n * subcontext of the call below it must be provided at least `minGas` gas.\n */\n function invariant_callWithMinGas_alwaysForwardsMinGas_succeeds() public {\n assertEq(actor.numCalls(), 0, \"no failed calls allowed\");\n }\n\n function performSafeCallMinGas(uint64 minGas) external {\n SafeCall.callWithMinGas(address(0), minGas, 0, hex\"\");\n }\n}\n\ncontract SafeCall_Fails_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, true);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n }\n\n /**\n * @custom:invariant `callWithMinGas` reverts if there is not enough gas to pass\n * to the subcontext.\n *\n * If there is not enough gas in the callframe to ensure that `callWithMinGas`\n * can provide the specified minimum gas limit to the subcontext of the call,\n * then `callWithMinGas` must revert.\n */\n function invariant_callWithMinGas_neverForwardsMinGas_reverts() public {\n assertEq(actor.numCalls(), 0, \"no successful calls allowed\");\n }\n\n function performSafeCallMinGas(uint64 minGas) external {\n SafeCall.callWithMinGas(address(0), minGas, 0, hex\"\");\n }\n}\n\ncontract SafeCaller_Actor is StdUtils {\n bool internal immutable FAILS;\n\n Vm internal vm;\n uint256 public numCalls;\n\n constructor(Vm _vm, bool _fails) {\n vm = _vm;\n FAILS = _fails;\n }\n\n function performSafeCallMinGas(uint64 gas, uint64 minGas) external {\n if (FAILS) {\n // Bound the minimum gas amount to [2500, type(uint48).max]\n minGas = uint64(bound(minGas, 2500, type(uint48).max));\n // Bound the gas passed to [minGas, (((minGas + 200) * 64) / 63)]\n gas = uint64(bound(gas, minGas, (((minGas + 200) * 64) / 63)));\n } else {\n // Bound the minimum gas amount to [2500, type(uint48).max]\n minGas = uint64(bound(minGas, 2500, type(uint48).max));\n // Bound the gas passed to [(((minGas + 200) * 64) / 63) + 500, type(uint64).max]\n gas = uint64(bound(gas, (((minGas + 200) * 64) / 63) + 500, type(uint64).max));\n }\n\n vm.expectCallMinGas(address(0x00), 0, minGas, hex\"\");\n bool success = SafeCall.call(\n msg.sender,\n gas,\n 0,\n abi.encodeWithSelector(0x2ae57a41, minGas)\n );\n\n if (success && FAILS) numCalls++;\n if (!FAILS && !success) numCalls++;\n }\n}\n" - }, - "contracts/test/invariants/SystemConfig.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { SystemConfig } from \"../../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../../L1/ResourceMetering.sol\";\nimport { Constants } from \"../../libraries/Constants.sol\";\n\ncontract SystemConfig_GasLimitLowerBound_Invariant is Test {\n SystemConfig public config;\n\n function setUp() public {\n ResourceMetering.ResourceConfig memory cfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n config = new SystemConfig({\n _owner: address(0xbeef),\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n\n // Set the target contract to the `config`\n targetContract(address(config));\n // Set the target sender to the `config`'s owner (0xbeef)\n targetSender(address(0xbeef));\n // Set the target selector for `setGasLimit`\n // `setGasLimit` is the only function we care about, as it is the only function\n // that can modify the gas limit within the SystemConfig.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = config.setGasLimit.selector;\n FuzzSelector memory selector = FuzzSelector({\n addr: address(config),\n selectors: selectors\n });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The gas limit of the `SystemConfig` contract can never be lower\n * than the hard-coded lower bound.\n */\n function invariant_gasLimitLowerBound() external {\n assertTrue(config.gasLimit() >= config.MINIMUM_GAS_LIMIT());\n }\n}\n" - }, - "contracts/universal/CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer0\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * libAddressManager variable used to exist. Must be the first contract in the inheritance\n * tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer0 {\n /**\n * @custom:legacy\n * @custom:spacer libAddressManager\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n}\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer1\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * PausableUpgradable and OwnableUpgradeable variables used to exist. Must be\n * the third contract in the inheritance tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer1 {\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable via OwnableUpgradeable.\n *\n */\n uint256[50] private spacer_1_0_1600;\n\n /**\n * @custom:legacy\n * @custom:spacer _owner\n * @notice Spacer for backwards compatibility.\n * Come from OpenZeppelin OwnableUpgradeable.\n */\n address private spacer_51_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable via PausableUpgradable.\n */\n uint256[49] private spacer_52_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer _paused\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n bool private spacer_101_0_1;\n\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n uint256[49] private spacer_102_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer ReentrancyGuardUpgradeable's `_status` field.\n * @notice Spacer for backwards compatibility\n */\n uint256 private spacer_151_0_32;\n\n /**\n * @custom:spacer ReentrancyGuardUpgradeable\n * @notice Spacer for backwards compatibility\n */\n uint256[49] private __gap_reentrancy_guard;\n\n /**\n * @custom:legacy\n * @custom:spacer blockedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_201_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer relayedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_202_0_32;\n}\n\n/**\n * @custom:upgradeable\n * @title CrossDomainMessenger\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\n * cross-chain messenger contracts. It's designed to be a universal interface that only\n * needs to be extended slightly to provide low-level message passing functionality on each\n * chain it's deployed on. Currently only designed for message passing between two paired\n * chains and does not support one-to-many interactions.\n *\n * Any changes to this contract MUST result in a semver bump for contracts that inherit it.\n */\nabstract contract CrossDomainMessenger is\n CrossDomainMessengerLegacySpacer0,\n Initializable,\n CrossDomainMessengerLegacySpacer1\n{\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Constant overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_CONSTANT_OVERHEAD = 200_000;\n\n /**\n * @notice Numerator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 1016;\n\n /**\n * @notice Denominator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 1000;\n\n /**\n * @notice Extra gas added to base gas for each byte of calldata in a message.\n */\n uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\n\n /**\n * @notice Address of the paired CrossDomainMessenger contract on the other chain.\n */\n address public immutable OTHER_MESSENGER;\n\n /**\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n * be present in this mapping if it has successfully been relayed on this chain, and\n * can therefore not be relayed again.\n */\n mapping(bytes32 => bool) public successfulMessages;\n\n /**\n * @notice Address of the sender of the currently executing message on the other chain. If the\n * value of this variable is the default value (0x00000000...dead) then no message is\n * currently being executed. Use the xDomainMessageSender getter which will throw an\n * error if this is the case.\n */\n address internal xDomainMsgSender;\n\n /**\n * @notice Nonce for the next message to be sent, without the message version applied. Use the\n * messageNonce getter which will insert the message version into the nonce to give you\n * the actual nonce to be used for the message.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Mapping of message hashes to a boolean if and only if the message has failed to be\n * executed at least once. A message will not be present in this mapping if it\n * successfully executed on the first attempt.\n */\n mapping(bytes32 => bool) public failedMessages;\n\n /**\n * @notice A mapping of hashes to reentrancy locks.\n */\n mapping(bytes32 => bool) internal reentrancyLocks;\n\n /**\n * @notice Reserve extra slots in the storage layout for future upgrades.\n * A gap size of 41 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[41] private __gap;\n\n /**\n * @notice Emitted whenever a message is sent to the other chain.\n *\n * @param target Address of the recipient of the message.\n * @param sender Address of the sender of the message.\n * @param message Message to trigger the recipient address with.\n * @param messageNonce Unique nonce attached to the message.\n * @param gasLimit Minimum gas limit that the message can be executed with.\n */\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n /**\n * @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the\n * SentMessage event without breaking the ABI of this contract, this is good enough.\n *\n * @param sender Address of the sender of the message.\n * @param value ETH value sent along with the message to the recipient.\n */\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n /**\n * @notice Emitted whenever a message is successfully relayed on this chain.\n *\n * @param msgHash Hash of the message that was relayed.\n */\n event RelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @notice Emitted whenever a message fails to be relayed on this chain.\n *\n * @param msgHash Hash of the message that failed to be relayed.\n */\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @param _otherMessenger Address of the messenger on the paired chain.\n */\n constructor(address _otherMessenger) {\n OTHER_MESSENGER = _otherMessenger;\n }\n\n /**\n * @notice Sends a message to some target address on the other chain. Note that if the call\n * always reverts, then the message will be unrelayable, and any ETH sent will be\n * permanently locked. The same will occur if the target on the other chain is\n * considered unsafe (see the _isUnsafeTarget() function).\n *\n * @param _target Target contract or wallet address.\n * @param _message Message to trigger the target address with.\n * @param _minGasLimit Minimum gas limit that the message can be executed with.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _minGasLimit\n ) external payable {\n // Triggers a message to the other messenger. Note that the amount of gas provided to the\n // message is the amount of gas requested by the user PLUS the base gas value. We want to\n // guarantee the property that the call to the target contract will always have at least\n // the minimum gas limit specified by the user.\n _sendMessage(\n OTHER_MESSENGER,\n baseGas(_message, _minGasLimit),\n msg.value,\n abi.encodeWithSelector(\n this.relayMessage.selector,\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _minGasLimit,\n _message\n )\n );\n\n emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit);\n emit SentMessageExtension1(msg.sender, msg.value);\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\n * be executed via cross-chain call from the other messenger OR if the message was\n * already received once and is currently being replayed.\n *\n * @param _nonce Nonce of the message being relayed.\n * @param _sender Address of the user who sent the message.\n * @param _target Address that the message is targeted at.\n * @param _value ETH value to send with the message.\n * @param _minGasLimit Minimum amount of gas that the message can be executed with.\n * @param _message Message to send to the target.\n */\n function relayMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _minGasLimit,\n bytes calldata _message\n ) external payable {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n require(\n version < 2,\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // If the message is version 0, then it's a migrated legacy withdrawal. We therefore need\n // to check that the legacy version of the message has not already been relayed.\n if (version == 0) {\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce);\n require(\n successfulMessages[oldHash] == false,\n \"CrossDomainMessenger: legacy withdrawal already relayed\"\n );\n }\n\n // We use the v1 message hash as the unique identifier for the message because it commits\n // to the value and minimum gas limit of the message.\n bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _minGasLimit,\n _message\n );\n\n // Check if the reentrancy lock for the `versionedHash` is already set.\n if (reentrancyLocks[versionedHash]) {\n revert(\"ReentrancyGuard: reentrant call\");\n }\n // Trigger the reentrancy lock for `versionedHash`\n reentrancyLocks[versionedHash] = true;\n\n if (_isOtherMessenger()) {\n // These properties should always hold when the message is first submitted (as\n // opposed to being replayed).\n assert(msg.value == _value);\n assert(!failedMessages[versionedHash]);\n } else {\n require(\n msg.value == 0,\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n\n require(\n failedMessages[versionedHash],\n \"CrossDomainMessenger: message cannot be replayed\"\n );\n }\n\n require(\n _isUnsafeTarget(_target) == false,\n \"CrossDomainMessenger: cannot send message to blocked system address\"\n );\n\n require(\n successfulMessages[versionedHash] == false,\n \"CrossDomainMessenger: message has already been relayed\"\n );\n\n xDomainMsgSender = _sender;\n bool success = SafeCall.callWithMinGas(_target, _minGasLimit, _value, _message);\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n\n if (success) {\n successfulMessages[versionedHash] = true;\n emit RelayedMessage(versionedHash);\n } else {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n }\n\n // Clear the reentrancy lock for `versionedHash`\n reentrancyLocks[versionedHash] = false;\n }\n\n /**\n * @notice Retrieves the address of the contract or wallet that initiated the currently\n * executing message on the other chain. Will throw an error if there is no message\n * currently being executed. Allows the recipient of a call to see who triggered it.\n *\n * @return Address of the sender of the currently executing message on the other chain.\n */\n function xDomainMessageSender() external view returns (address) {\n require(\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER,\n \"CrossDomainMessenger: xDomainMessageSender is not set\"\n );\n\n return xDomainMsgSender;\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n\n /**\n * @notice Computes the amount of gas required to guarantee that a given message will be\n * received on the other chain without running out of gas. Guaranteeing that a message\n * will not run out of gas is important because this ensures that a message can always\n * be replayed on the other chain if it fails to execute completely.\n *\n * @param _message Message to compute the amount of required gas for.\n * @param _minGasLimit Minimum desired gas limit when message goes to target.\n *\n * @return Amount of gas required to guarantee message receipt.\n */\n function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {\n // We peform the following math on uint64s to avoid overflow errors. Multiplying the\n // by MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR would otherwise limit the _minGasLimit to\n // type(uint32).max / MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR ~= 4.2m.\n return\n // Dynamic overhead\n ((uint64(_minGasLimit) * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\n MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\n // Calldata overhead\n (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\n // Constant overhead\n MIN_GAS_CONSTANT_OVERHEAD;\n }\n\n /**\n * @notice Intializer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __CrossDomainMessenger_init() internal onlyInitializing {\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n }\n\n /**\n * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @param _to Recipient of the message on the other chain.\n * @param _gasLimit Minimum gas limit the message can be executed with.\n * @param _value Amount of ETH to send with the message.\n * @param _data Message data.\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal virtual;\n\n /**\n * @notice Checks whether the message is coming from the other messenger. Implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @return Whether the message is coming from the other messenger.\n */\n function _isOtherMessenger() internal view virtual returns (bool);\n\n /**\n * @notice Checks whether a given call target is a system address that could cause the\n * messenger to peform an unsafe action. This is NOT a mechanism for blocking user\n * addresses. This is ONLY used to prevent the execution of messages to specific\n * system addresses that could cause security issues, e.g., having the\n * CrossDomainMessenger send messages to itself.\n *\n * @param _target Address of the contract to check.\n *\n * @return Whether or not the address is an unsafe system address.\n */\n function _isUnsafeTarget(address _target) internal view virtual returns (bool);\n}\n" - }, - "contracts/universal/ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721Bridge\n * @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.\n */\nabstract contract ERC721Bridge {\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Address of the bridge on the other network.\n */\n address public immutable OTHER_BRIDGE;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[49] private __gap;\n\n /**\n * @notice Emitted when an ERC721 bridge to the other network is initiated.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC721 bridge from the other network is finalized.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) && MESSENGER.xDomainMessageSender() == OTHER_BRIDGE,\n \"ERC721Bridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge) {\n require(_messenger != address(0), \"ERC721Bridge: messenger cannot be address(0)\");\n require(_otherBridge != address(0), \"ERC721Bridge: other bridge cannot be address(0)\");\n\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = _otherBridge;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for other bridge address.\n *\n * @return Address of the bridge on the other network.\n */\n function otherBridge() external view returns (address) {\n return OTHER_BRIDGE;\n }\n\n /**\n * @notice Initiates a bridge of an NFT to the caller's account on the other chain. Note that\n * this function can only be called by EOAs. Smart contract wallets should use the\n * `bridgeERC721To` function after ensuring that the recipient address on the remote\n * chain exists. Also note that the current owner of the token on this chain must\n * approve this contract to operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721(\n address _localToken,\n address _remoteToken,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n // Modifier requiring sender to be EOA. This prevents against a user error that would occur\n // if the sender is a smart contract wallet that has a different address on the remote chain\n // (or doesn't have an address on the remote chain at all). The user would fail to receive\n // the NFT if they use this function because it sends the NFT to the same address as the\n // caller. This check could be bypassed by a malicious contract via initcode, but it takes\n // care of the user error we want to avoid.\n require(!Address.isContract(msg.sender), \"ERC721Bridge: account is not externally owned\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note\n * that the current owner of the token on this chain must approve this contract to\n * operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n require(_to != address(0), \"ERC721Bridge: nft recipient cannot be address(0)\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Internal function for initiating a token bridge to the other domain.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _from Address of the sender on this domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other domain. Data supplied here will\n * not be used to execute any code on the other domain and is only emitted\n * as extra data for the convenience of off-chain tooling.\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal virtual;\n}\n" - }, - "contracts/universal/FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n/**\n * @title FeeVault\n * @notice The FeeVault contract contains the basic logic for the various different vault contracts\n * used to hold fee revenue generated by the L2 system.\n */\nabstract contract FeeVault {\n /**\n * @notice Emits each time that a withdrawal occurs.\n *\n * @param value Amount that was withdrawn (in wei).\n * @param to Address that the funds were sent to.\n * @param from Address that triggered the withdrawal.\n */\n event Withdrawal(uint256 value, address to, address from);\n\n /**\n * @notice Minimum balance before a withdrawal can be triggered.\n */\n uint256 public immutable MIN_WITHDRAWAL_AMOUNT;\n\n /**\n * @notice Wallet that will receive the fees on L1.\n */\n address public immutable RECIPIENT;\n\n /**\n * @notice The minimum gas limit for the FeeVault withdrawal transaction.\n */\n uint32 internal constant WITHDRAWAL_MIN_GAS = 35_000;\n\n /**\n * @notice Total amount of wei processed by the contract.\n */\n uint256 public totalProcessed;\n\n /**\n * @param _recipient Wallet that will receive the fees on L1.\n * @param _minWithdrawalAmount Minimum balance before a withdrawal can be triggered.\n */\n constructor(address _recipient, uint256 _minWithdrawalAmount) {\n MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;\n RECIPIENT = _recipient;\n }\n\n /**\n * @notice Allow the contract to receive ETH.\n */\n receive() external payable {}\n\n /**\n * @notice Triggers a withdrawal of funds to the L1 fee wallet.\n */\n function withdraw() external {\n require(\n address(this).balance >= MIN_WITHDRAWAL_AMOUNT,\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n\n uint256 value = address(this).balance;\n totalProcessed += value;\n\n emit Withdrawal(value, RECIPIENT, msg.sender);\n\n L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }(\n RECIPIENT,\n WITHDRAWAL_MIN_GAS,\n bytes(\"\")\n );\n }\n}\n" - }, - "contracts/universal/IOptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @title IOptimismMintableERC20\n * @notice This interface is available on the OptimismMintableERC20 contract. We declare it as a\n * separate interface so that it can be used in custom implementations of\n * OptimismMintableERC20.\n */\ninterface IOptimismMintableERC20 is IERC165 {\n function remoteToken() external view returns (address);\n\n function bridge() external returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n\n/**\n * @custom:legacy\n * @title ILegacyMintableERC20\n * @notice This interface was available on the legacy L2StandardERC20 contract. It remains available\n * on the OptimismMintableERC20 contract for backwards compatibility.\n */\ninterface ILegacyMintableERC20 is IERC165 {\n function l1Token() external view returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n" - }, - "contracts/universal/IOptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\n/**\n * @title IOptimismMintableERC721\n * @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.\n * Tokens that follow this standard can be easily transferred across the ERC721 bridge.\n */\ninterface IOptimismMintableERC721 is IERC721Enumerable {\n /**\n * @notice Emitted when a token is minted.\n *\n * @param account Address of the account the token was minted to.\n * @param tokenId Token ID of the minted token.\n */\n event Mint(address indexed account, uint256 tokenId);\n\n /**\n * @notice Emitted when a token is burned.\n *\n * @param account Address of the account the token was burned from.\n * @param tokenId Token ID of the burned token.\n */\n event Burn(address indexed account, uint256 tokenId);\n\n /**\n * @notice Mints some token ID for a user, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * @param _to Address of the user to mint the token for.\n * @param _tokenId Token ID to mint.\n */\n function safeMint(address _to, uint256 _tokenId) external;\n\n /**\n * @notice Burns a token ID from a user.\n *\n * @param _from Address of the user to burn the token from.\n * @param _tokenId Token ID to burn.\n */\n function burn(address _from, uint256 _tokenId) external;\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function REMOTE_CHAIN_ID() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function REMOTE_TOKEN() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function BRIDGE() external view returns (address);\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function remoteChainId() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function remoteToken() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function bridge() external view returns (address);\n}\n" - }, - "contracts/universal/OptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { ILegacyMintableERC20, IOptimismMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC20\n * @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed\n * to allow the StandardBridge contracts to mint and burn tokens. This makes it possible to\n * use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa.\n * Designed to be backwards compatible with the older StandardL2ERC20 token which was only\n * meant for use on L2.\n */\ncontract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, Semver {\n /**\n * @notice Address of the corresponding version of this token on the remote chain.\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @notice Address of the StandardBridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Emitted whenever tokens are minted for an account.\n *\n * @param account Address of the account tokens are being minted for.\n * @param amount Amount of tokens minted.\n */\n event Mint(address indexed account, uint256 amount);\n\n /**\n * @notice Emitted whenever tokens are burned from an account.\n *\n * @param account Address of the account tokens are being burned from.\n * @param amount Amount of tokens burned.\n */\n event Burn(address indexed account, uint256 amount);\n\n /**\n * @notice A modifier that only allows the bridge to call\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC20: only bridge can mint and burn\");\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the L2 standard bridge.\n * @param _remoteToken Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _bridge,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) Semver(1, 0, 0) {\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n }\n\n /**\n * @notice Allows the StandardBridge on this network to mint tokens.\n *\n * @param _to Address to mint tokens to.\n * @param _amount Amount of tokens to mint.\n */\n function mint(address _to, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _mint(_to, _amount);\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Allows the StandardBridge on this network to burn tokens.\n *\n * @param _from Address to burn tokens from.\n * @param _amount Amount of tokens to burn.\n */\n function burn(address _from, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _burn(_from, _amount);\n emit Burn(_from, _amount);\n }\n\n /**\n * @notice ERC165 interface check function.\n *\n * @param _interfaceId Interface ID to check.\n *\n * @return Whether or not the interface is supported by this contract.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 iface1 = type(IERC165).interfaceId;\n // Interface corresponding to the legacy L2StandardERC20.\n bytes4 iface2 = type(ILegacyMintableERC20).interfaceId;\n // Interface corresponding to the updated OptimismMintableERC20 (this contract).\n bytes4 iface3 = type(IOptimismMintableERC20).interfaceId;\n return _interfaceId == iface1 || _interfaceId == iface2 || _interfaceId == iface3;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote token. Use REMOTE_TOKEN going forward.\n */\n function l1Token() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the bridge. Use BRIDGE going forward.\n */\n function l2Bridge() public view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for REMOTE_TOKEN.\n */\n function remoteToken() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for BRIDGE.\n */\n function bridge() public view returns (address) {\n return BRIDGE;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC20Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Contract Imports */\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000012\n * @title OptimismMintableERC20Factory\n * @notice OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20\n * contracts on the network it's deployed to. Simplifies the deployment process for users\n * who may be less familiar with deploying smart contracts. Designed to be backwards\n * compatible with the older StandardL2ERC20Factory contract.\n */\ncontract OptimismMintableERC20Factory is Semver {\n /**\n * @notice Address of the StandardBridge on this chain.\n */\n address public immutable BRIDGE;\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a new OptimismMintableERC20 is created. Legacy version of the newer\n * OptimismMintableERC20Created event. We recommend relying on that event instead.\n *\n * @param remoteToken Address of the token on the remote chain.\n * @param localToken Address of the created token on the local chain.\n */\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC20 is created.\n *\n * @param localToken Address of the created token on the local chain.\n * @param remoteToken Address of the corresponding token on the remote chain.\n * @param deployer Address of the account that deployed the token.\n */\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC20 token contract since this contract\n * is responsible for deploying OptimismMintableERC20 contracts.\n *\n * @param _bridge Address of the StandardBridge on this chain.\n */\n constructor(address _bridge) Semver(1, 1, 0) {\n BRIDGE = _bridge;\n }\n\n /**\n * @custom:legacy\n * @notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the\n * newer createOptimismMintableERC20 function, which has a more intuitive name.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createStandardL2Token(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n return createOptimismMintableERC20(_remoteToken, _name, _symbol);\n }\n\n /**\n * @notice Creates an instance of the OptimismMintableERC20 contract.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createOptimismMintableERC20(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) public returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC20Factory: must provide remote token address\"\n );\n\n address localToken = address(\n new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol)\n );\n\n // Emit the old event too for legacy support.\n emit StandardL2TokenCreated(_remoteToken, localToken);\n\n // Emit the updated event. The arguments here differ from the legacy event, but\n // are consistent with the ordering used in StandardBridge events.\n emit OptimismMintableERC20Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n ERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { IOptimismMintableERC721 } from \"./IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC721\n * @notice This contract is the remote representation for some token that lives on another network,\n * typically an Optimism representation of an Ethereum-based token. Standard reference\n * implementation that can be extended or modified according to your needs.\n */\ncontract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Semver {\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Base token URI for this token.\n */\n string public baseTokenURI;\n\n /**\n * @notice Modifier that prevents callers other than the bridge from calling the function.\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC721: only bridge can call this function\");\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the bridge on this network.\n * @param _remoteChainId Chain ID where the remote token is deployed.\n * @param _remoteToken Address of the corresponding token on the other network.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n constructor(\n address _bridge,\n uint256 _remoteChainId,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) Semver(1, 0, 0) {\n require(_bridge != address(0), \"OptimismMintableERC721: bridge cannot be address(0)\");\n require(_remoteChainId != 0, \"OptimismMintableERC721: remote chain id cannot be zero\");\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721: remote token cannot be address(0)\"\n );\n\n REMOTE_CHAIN_ID = _remoteChainId;\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n\n // Creates a base URI in the format specified by EIP-681:\n // https://eips.ethereum.org/EIPS/eip-681\n baseTokenURI = string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(_remoteToken), 20),\n \"@\",\n Strings.toString(_remoteChainId),\n \"/tokenURI?uint256=\"\n )\n );\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteChainId() external view returns (uint256) {\n return REMOTE_CHAIN_ID;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteToken() external view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function bridge() external view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function safeMint(address _to, uint256 _tokenId) external virtual onlyBridge {\n _safeMint(_to, _tokenId);\n\n emit Mint(_to, _tokenId);\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function burn(address _from, uint256 _tokenId) external virtual onlyBridge {\n _burn(_tokenId);\n\n emit Burn(_from, _tokenId);\n }\n\n /**\n * @notice Checks if a given interface ID is supported by this contract.\n *\n * @param _interfaceId The interface ID to check.\n *\n * @return True if the interface ID is supported, false otherwise.\n */\n function supportsInterface(bytes4 _interfaceId)\n public\n view\n override(ERC721Enumerable, IERC165)\n returns (bool)\n {\n bytes4 iface1 = type(IERC165).interfaceId;\n bytes4 iface2 = type(IOptimismMintableERC721).interfaceId;\n return\n _interfaceId == iface1 ||\n _interfaceId == iface2 ||\n super.supportsInterface(_interfaceId);\n }\n\n /**\n * @notice Returns the base token URI.\n *\n * @return Base token URI.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return baseTokenURI;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismMintableERC721 } from \"./OptimismMintableERC721.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @title OptimismMintableERC721Factory\n * @notice Factory contract for creating OptimismMintableERC721 contracts.\n */\ncontract OptimismMintableERC721Factory is Semver {\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Chain ID for the remote network.\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @notice Tracks addresses created by this factory.\n */\n mapping(address => bool) public isOptimismMintableERC721;\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC721 contract is created.\n *\n * @param localToken Address of the token on the this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param deployer Address of the initiator of the deployment\n */\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.1.0\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC721 token contract since this contract\n * is responsible for deploying OptimismMintableERC721 contracts.\n *\n * @param _bridge Address of the ERC721 bridge on this network.\n * @param _remoteChainId Chain ID for the remote network.\n */\n constructor(address _bridge, uint256 _remoteChainId) Semver(1, 1, 0) {\n BRIDGE = _bridge;\n REMOTE_CHAIN_ID = _remoteChainId;\n }\n\n /**\n * @notice Creates an instance of the standard ERC721.\n *\n * @param _remoteToken Address of the corresponding token on the other domain.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n function createOptimismMintableERC721(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721Factory: L1 token address cannot be address(0)\"\n );\n\n address localToken = address(\n new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)\n );\n\n isOptimismMintableERC721[localToken] = true;\n emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/Proxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Proxy\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\n * if the caller is address(0), meaning that the call originated from an off-chain\n * simulation.\n */\ncontract Proxy {\n /**\n * @notice The storage slot that holds the address of the implementation.\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice The storage slot that holds the address of the owner.\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice An event that is emitted each time the implementation is changed. This event is part\n * of the EIP-1967 specification.\n *\n * @param implementation The address of the implementation contract\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\n * EIP-1967 specification.\n *\n * @param previousAdmin The previous owner of the contract\n * @param newAdmin The new owner of the contract\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\n * eth_call to interact with this proxy without needing to use low-level storage\n * inspection. We assume that nobody is able to trigger calls from address(0) during\n * normal EVM execution.\n */\n modifier proxyCallIfNotAdmin() {\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\n * EIP-1967 admin storage slot so that accidental storage collision with the\n * implementation is not possible.\n *\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\n * transparent proxy interface.\n */\n constructor(address _admin) {\n _changeAdmin(_admin);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Set the implementation contract address. The code at the given address will execute\n * when this contract is called.\n *\n * @param _implementation Address of the implementation contract.\n */\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\n _setImplementation(_implementation);\n }\n\n /**\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\n * atomic execution of initialization-based upgrades.\n *\n * @param _implementation Address of the implementation contract.\n * @param _data Calldata to delegatecall the new implementation with.\n */\n function upgradeToAndCall(address _implementation, bytes calldata _data)\n external\n payable\n proxyCallIfNotAdmin\n returns (bytes memory)\n {\n _setImplementation(_implementation);\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\n require(success, \"Proxy: delegatecall to new implementation contract failed\");\n return returndata;\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _admin New owner of the proxy contract.\n */\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\n _changeAdmin(_admin);\n }\n\n /**\n * @notice Gets the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function admin() external proxyCallIfNotAdmin returns (address) {\n return _getAdmin();\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function implementation() external proxyCallIfNotAdmin returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n emit Upgraded(_implementation);\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _admin New owner of the proxy contract.\n */\n function _changeAdmin(address _admin) internal {\n address previous = _getAdmin();\n assembly {\n sstore(OWNER_KEY, _admin)\n }\n emit AdminChanged(previous, _admin);\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal {\n address impl = _getImplementation();\n require(impl != address(0), \"Proxy: implementation not initialized\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address impl;\n assembly {\n impl := sload(IMPLEMENTATION_KEY)\n }\n return impl;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getAdmin() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n}\n" - }, - "contracts/universal/ProxyAdmin.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { Proxy } from \"./Proxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\n\n/**\n * @title IStaticERC1967Proxy\n * @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface.\n */\ninterface IStaticERC1967Proxy {\n function implementation() external view returns (address);\n\n function admin() external view returns (address);\n}\n\n/**\n * @title IStaticL1ChugSplashProxy\n * @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface.\n */\ninterface IStaticL1ChugSplashProxy {\n function getImplementation() external view returns (address);\n\n function getOwner() external view returns (address);\n}\n\n/**\n * @title ProxyAdmin\n * @notice This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy,\n * based on the OpenZeppelin implementation. It has backwards compatibility logic to work\n * with the various types of proxies that have been deployed by Optimism in the past.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @notice The proxy types that the ProxyAdmin can manage.\n *\n * @custom:value ERC1967 Represents an ERC1967 compliant transparent proxy interface.\n * @custom:value CHUGSPLASH Represents the Chugsplash proxy interface (legacy).\n * @custom:value RESOLVED Represents the ResolvedDelegate proxy (legacy).\n */\n enum ProxyType {\n ERC1967,\n CHUGSPLASH,\n RESOLVED\n }\n\n /**\n * @notice A mapping of proxy types, used for backwards compatibility.\n */\n mapping(address => ProxyType) public proxyType;\n\n /**\n * @notice A reverse mapping of addresses to names held in the AddressManager. This must be\n * manually kept up to date with changes in the AddressManager for this contract\n * to be able to work as an admin for the ResolvedDelegateProxy type.\n */\n mapping(address => string) public implementationName;\n\n /**\n * @notice The address of the address manager, this is required to manage the\n * ResolvedDelegateProxy type.\n */\n AddressManager public addressManager;\n\n /**\n * @notice A legacy upgrading indicator used by the old Chugsplash Proxy.\n */\n bool internal upgrading;\n\n /**\n * @param _owner Address of the initial owner of this contract.\n */\n constructor(address _owner) Ownable() {\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the proxy type for a given address. Only required for non-standard (legacy)\n * proxy types.\n *\n * @param _address Address of the proxy.\n * @param _type Type of the proxy.\n */\n function setProxyType(address _address, ProxyType _type) external onlyOwner {\n proxyType[_address] = _type;\n }\n\n /**\n * @notice Sets the implementation name for a given address. Only required for\n * ResolvedDelegateProxy type proxies that have an implementation name.\n *\n * @param _address Address of the ResolvedDelegateProxy.\n * @param _name Name of the implementation for the proxy.\n */\n function setImplementationName(address _address, string memory _name) external onlyOwner {\n implementationName[_address] = _name;\n }\n\n /**\n * @notice Set the address of the AddressManager. This is required to manage legacy\n * ResolvedDelegateProxy type proxy contracts.\n *\n * @param _address Address of the AddressManager.\n */\n function setAddressManager(AddressManager _address) external onlyOwner {\n addressManager = _address;\n }\n\n /**\n * @custom:legacy\n * @notice Set an address in the address manager. Since only the owner of the AddressManager\n * can directly modify addresses and the ProxyAdmin will own the AddressManager, this\n * gives the owner of the ProxyAdmin the ability to modify addresses directly.\n *\n * @param _name Name to set within the AddressManager.\n * @param _address Address to attach to the given name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n addressManager.setAddress(_name, _address);\n }\n\n /**\n * @custom:legacy\n * @notice Set the upgrading status for the Chugsplash proxy type.\n *\n * @param _upgrading Whether or not the system is upgrading.\n */\n function setUpgrading(bool _upgrading) external onlyOwner {\n upgrading = _upgrading;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\n *\n * @return Whether or not there is an upgrade going on. May not actually tell you whether an\n * upgrade is going on, since we don't currently plan to use this variable for anything\n * other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\n */\n function isUpgrading() external view returns (bool) {\n return upgrading;\n }\n\n /**\n * @notice Returns the implementation of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the implementation of.\n *\n * @return Address of the implementation of the proxy.\n */\n function getProxyImplementation(address _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).implementation();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getImplementation();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.getAddress(implementationName[_proxy]);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Returns the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the admin of.\n *\n * @return Address of the admin of the proxy.\n */\n function getProxyAdmin(address payable _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).admin();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getOwner();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.owner();\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Updates the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to update.\n * @param _newAdmin Address of the new proxy admin.\n */\n function changeProxyAdmin(address payable _proxy, address _newAdmin) external onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).changeAdmin(_newAdmin);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setOwner(_newAdmin);\n } else if (ptype == ProxyType.RESOLVED) {\n addressManager.transferOwnership(_newAdmin);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n */\n function upgrade(address payable _proxy, address _implementation) public onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeTo(_implementation);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setStorage(\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n bytes32(uint256(uint160(_implementation)))\n );\n } else if (ptype == ProxyType.RESOLVED) {\n string memory name = implementationName[_proxy];\n addressManager.setAddress(name, _implementation);\n } else {\n // It should not be possible to retrieve a ProxyType value which is not matched by\n // one of the previous conditions.\n assert(false);\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract and delegatecalls the new implementation\n * with some given data. Useful for atomic upgrade-and-initialize calls.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n * @param _data Data to trigger the new implementation with.\n */\n function upgradeAndCall(\n address payable _proxy,\n address _implementation,\n bytes memory _data\n ) external payable onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);\n } else {\n // reverts if proxy type is unknown\n upgrade(_proxy, _implementation);\n (bool success, ) = _proxy.call{ value: msg.value }(_data);\n require(success, \"ProxyAdmin: call to proxy after upgrade failed\");\n }\n }\n}\n" - }, - "contracts/universal/Semver.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n" - }, - "contracts/universal/StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { IOptimismMintableERC20, ILegacyMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"./OptimismMintableERC20.sol\";\n\n/**\n * @custom:upgradeable\n * @title StandardBridge\n * @notice StandardBridge is a base contract for the L1 and L2 standard ERC20 bridges. It handles\n * the core bridging logic, including escrowing tokens that are native to the local chain\n * and minting/burning tokens that are native to the remote chain.\n */\nabstract contract StandardBridge {\n using SafeERC20 for IERC20;\n\n /**\n * @notice The L2 gas limit set when eth is depoisited using the receive() function.\n */\n uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000;\n\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Corresponding bridge on the other domain.\n */\n StandardBridge public immutable OTHER_BRIDGE;\n\n /**\n * @custom:legacy\n * @custom:spacer messenger\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer l2TokenBridge\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_1_0_20;\n\n /**\n * @notice Mapping that stores deposits for a given pair of local and remote tokens.\n */\n mapping(address => mapping(address => uint256)) public deposits;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n * A gap size of 47 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[47] private __gap;\n\n /**\n * @notice Emitted when an ETH bridge is initiated to the other chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ETH bridge is finalized on this chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is initiated to the other chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is finalized on this chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Only allow EOAs to call the functions. Note that this is not safe against contracts\n * calling code within their constructors, but also doesn't really matter since we're\n * just trying to prevent users accidentally depositing with smart contract wallets.\n */\n modifier onlyEOA() {\n require(\n !Address.isContract(msg.sender),\n \"StandardBridge: function can only be called from an EOA\"\n );\n _;\n }\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) &&\n MESSENGER.xDomainMessageSender() == address(OTHER_BRIDGE),\n \"StandardBridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of CrossDomainMessenger on this network.\n * @param _otherBridge Address of the other StandardBridge contract.\n */\n constructor(address payable _messenger, address payable _otherBridge) {\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = StandardBridge(_otherBridge);\n }\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n * Must be implemented by contracts that inherit.\n */\n receive() external payable virtual;\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @notice Sends ETH to the sender's address on the other chain.\n *\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETH(uint32 _minGasLimit, bytes calldata _extraData) public payable onlyEOA {\n _initiateBridgeETH(msg.sender, msg.sender, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a\n * smart contract and the call fails, the ETH will be temporarily locked in the\n * StandardBridge on the other chain until the call is replayed. If the call cannot be\n * replayed with any amount of gas (call always reverts), then the ETH will be\n * permanently locked in the StandardBridge on the other chain. ETH will also\n * be locked if the receiver is the other bridge, because finalizeBridgeETH will revert\n * in that case.\n *\n * @param _to Address of the receiver.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public payable {\n _initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ERC20 tokens to the sender's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20(\n address _localToken,\n address _remoteToken,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual onlyEOA {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public payable onlyOtherBridge {\n require(msg.value == _amount, \"StandardBridge: amount sent does not match amount required\");\n require(_to != address(this), \"StandardBridge: cannot send to self\");\n require(_to != address(MESSENGER), \"StandardBridge: cannot send to messenger\");\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n\n bool success = SafeCall.call(_to, gasleft(), _amount, hex\"\");\n require(success, \"StandardBridge: ETH transfer failed\");\n }\n\n /**\n * @notice Finalizes an ERC20 bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public onlyOtherBridge {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).mint(_to, _amount);\n } else {\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] - _amount;\n IERC20(_localToken).safeTransfer(_to, _amount);\n }\n\n // Emit the correct events. By default this will be ERC20BridgeFinalized, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Initiates a bridge of ETH through the CrossDomainMessenger.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n require(\n msg.value == _amount,\n \"StandardBridge: bridging ETH must include sufficient ETH value\"\n );\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage{ value: _amount }(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeETH.selector,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).burn(_from, _amount);\n } else {\n IERC20(_localToken).safeTransferFrom(_from, address(this), _amount);\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] + _amount;\n }\n\n // Emit the correct events. By default this will be ERC20BridgeInitiated, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeERC20.selector,\n // Because this call will be executed on the remote chain, we reverse the order of\n // the remote and local token addresses relative to their order in the\n // finalizeBridgeERC20 function.\n _remoteToken,\n _localToken,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Checks if a given address is an OptimismMintableERC20. Not perfect, but good enough.\n * Just the way we like it.\n *\n * @param _token Address of the token to check.\n *\n * @return True if the token is an OptimismMintableERC20.\n */\n function _isOptimismMintableERC20(address _token) internal view returns (bool) {\n return\n ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId) ||\n ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);\n }\n\n /**\n * @notice Checks if the \"other token\" is the correct pair token for the OptimismMintableERC20.\n * Calls can be saved in the future by combining this logic with\n * `_isOptimismMintableERC20`.\n *\n * @param _mintableToken OptimismMintableERC20 to check against.\n * @param _otherToken Pair token to check.\n *\n * @return True if the other token is the correct pair token for the OptimismMintableERC20.\n */\n function _isCorrectTokenPair(address _mintableToken, address _otherToken)\n internal\n view\n returns (bool)\n {\n if (\n ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)\n ) {\n return _otherToken == ILegacyMintableERC20(_mintableToken).l1Token();\n } else {\n return _otherToken == IOptimismMintableERC20(_mintableToken).remoteToken();\n }\n }\n\n /** @notice Emits the ETHBridgeInitiated event and if necessary the appropriate legacy event\n * when an ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ETHBridgeFinalized and if necessary the appropriate legacy event when an\n * ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeInitiated event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeFinalized event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/vendor/AddressAliasHelper.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.0;\n\nlibrary AddressAliasHelper {\n uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n /// @notice Utility function that converts the address in the L1 that submitted a tx to\n /// the inbox to the msg.sender viewed in the L2\n /// @param l1Address the address in the L1 that triggered the tx to L2\n /// @return l2Address L2 address as viewed in msg.sender\n function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {\n unchecked {\n l2Address = address(uint160(l1Address) + offset);\n }\n }\n\n /// @notice Utility function that converts the msg.sender viewed in the L2 to the\n /// address in the L1 that submitted a tx to the inbox\n /// @param l2Address L2 address as viewed in msg.sender\n /// @return l1Address the address in the L1 that triggered the tx to L2\n function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {\n unchecked {\n l1Address = address(uint160(l2Address) - offset);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/governance/utils/IVotes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20Permit.sol\";\nimport \"../../../utils/math/Math.sol\";\nimport \"../../../governance/utils/IVotes.sol\";\nimport \"../../../utils/math/SafeCast.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20Votes is IVotes, ERC20Permit {\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCast.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = Math.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSA.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"./IERC721Enumerable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n // Mapping from owner to list of owned token IDs\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n // Mapping from token ID to index of the owner tokens list\n mapping(uint256 => uint256) private _ownedTokensIndex;\n\n // Array with all token ids, used for enumeration\n uint256[] private _allTokens;\n\n // Mapping from token id to position in the allTokens array\n mapping(uint256 => uint256) private _allTokensIndex;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n return _ownedTokens[owner][index];\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _allTokens.length;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721Enumerable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n return _allTokens[index];\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n if (from == address(0)) {\n _addTokenToAllTokensEnumeration(tokenId);\n } else if (from != to) {\n _removeTokenFromOwnerEnumeration(from, tokenId);\n }\n if (to == address(0)) {\n _removeTokenFromAllTokensEnumeration(tokenId);\n } else if (to != from) {\n _addTokenToOwnerEnumeration(to, tokenId);\n }\n }\n\n /**\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\n * @param to address representing the new owner of the given token ID\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n */\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n uint256 length = ERC721.balanceOf(to);\n _ownedTokens[to][length] = tokenId;\n _ownedTokensIndex[tokenId] = length;\n }\n\n /**\n * @dev Private function to add a token to this extension's token tracking data structures.\n * @param tokenId uint256 ID of the token to be added to the tokens list\n */\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n _allTokensIndex[tokenId] = _allTokens.length;\n _allTokens.push(tokenId);\n }\n\n /**\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n * @param from address representing the previous owner of the given token ID\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n */\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary\n if (tokenIndex != lastTokenIndex) {\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n }\n\n // This also deletes the contents at the last position of the array\n delete _ownedTokensIndex[tokenId];\n delete _ownedTokens[from][lastTokenIndex];\n }\n\n /**\n * @dev Private function to remove a token from this extension's token tracking data structures.\n * This has O(1) time complexity, but alters the order of the _allTokens array.\n * @param tokenId uint256 ID of the token to be removed from the tokens list\n */\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = _allTokens.length - 1;\n uint256 tokenIndex = _allTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n // This also deletes the contents at the last position of the array\n delete _allTokensIndex[tokenId];\n _allTokens.pop();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Counters.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface,\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n _supportsERC165Interface(account, type(IERC165).interfaceId) &&\n !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)\n internal\n view\n returns (bool[] memory)\n {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in _interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!_supportsERC165Interface(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n * Interface identification is specified in ERC-165.\n */\n function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/Bytes32AddressLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Library for converting between addresses and bytes32 values.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)\nlibrary Bytes32AddressLib {\n function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {\n return bytes32(bytes20(addressValue));\n }\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n /*//////////////////////////////////////////////////////////////\n SIMPLIFIED FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n }\n\n function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n }\n\n function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n }\n\n function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n }\n\n function powWad(int256 x, int256 y) internal pure returns (int256) {\n // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\n return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\n }\n\n function expWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n // When the result is < 0.5 we return zero. This happens when\n // x <= floor(log(0.5e18) * 1e18) ~ -42e18\n if (x <= -42139678854452767551) return 0;\n\n // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\n // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\n if (x >= 135305999368893231589) revert(\"EXP_OVERFLOW\");\n\n // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\n // for more intermediate precision and a binary basis. This base conversion\n // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n x = (x << 78) / 5**18;\n\n // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\n x = x - k * 54916777467707473351141471128;\n\n // k is in the range [-61, 195].\n\n // Evaluate using a (6, 7)-term rational approximation.\n // p is made monic, we'll multiply by a scale factor later.\n int256 y = x + 1346386616545796478920950773328;\n y = ((y * x) >> 96) + 57155421227552351082224309758442;\n int256 p = y + x - 94201549194550492254356042504812;\n p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n p = p * x + (4385272521454847904659076985693276 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n int256 q = x - 2855989394907223263936484059900;\n q = ((q * x) >> 96) + 50020603652535783019961831881945;\n q = ((q * x) >> 96) - 533845033583426703283633433725380;\n q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial won't have zeros in the domain as all its roots are complex.\n // No scaling is necessary because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r should be in the range (0.09, 0.25) * 2**96.\n\n // We now need to multiply r by:\n // * the scale factor s = ~6.031367120.\n // * the 2**k factor from the range reduction.\n // * the 1e18 / 2**96 factor for base conversion.\n // We do this all at once, with an intermediate result in 2**213\n // basis, so the final right shift is always by a positive amount.\n r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\n }\n }\n\n function lnWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n require(x > 0, \"UNDEFINED\");\n\n // We want to convert x from 10**18 fixed point to 2**96 fixed point.\n // We do this by multiplying by 2**96 / 10**18. But since\n // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\n // and add ln(2**96 / 10**18) at the end.\n\n // Reduce range of x to (1, 2) * 2**96\n // ln(2^k * x) = k * ln(2) + ln(x)\n int256 k = int256(log2(uint256(x))) - 96;\n x <<= uint256(159 - k);\n x = int256(uint256(x) >> 159);\n\n // Evaluate using a (8, 8)-term rational approximation.\n // p is made monic, we will multiply by a scale factor later.\n int256 p = x + 3273285459638523848632254066296;\n p = ((p * x) >> 96) + 24828157081833163892658089445524;\n p = ((p * x) >> 96) + 43456485725739037958740375743393;\n p = ((p * x) >> 96) - 11111509109440967052023855526967;\n p = ((p * x) >> 96) - 45023709667254063763336534515857;\n p = ((p * x) >> 96) - 14706773417378608786704636184526;\n p = p * x - (795164235651350426258249787498 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n // q is monic by convention.\n int256 q = x + 5573035233440673466300451813936;\n q = ((q * x) >> 96) + 71694874799317883764090561454958;\n q = ((q * x) >> 96) + 283447036172924575727196451306956;\n q = ((q * x) >> 96) + 401686690394027663651624208769553;\n q = ((q * x) >> 96) + 204048457590392012362485061816622;\n q = ((q * x) >> 96) + 31853899698501571402653359427138;\n q = ((q * x) >> 96) + 909429971244387300277376558375;\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial is known not to have zeros in the domain.\n // No scaling required because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r is in the range (0, 0.125) * 2**96\n\n // Finalization, we need to:\n // * multiply by the scale factor s = 5.549…\n // * add ln(2**96 / 10**18)\n // * add k * ln(2)\n // * multiply by 10**18 / 2**96 = 5**18 >> 78\n\n // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\n r *= 1677202110996718588342820967067443963516166;\n // add ln(2) * k * 5e18 * 2**192\n r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\n // add ln(2**96 / 10**18) * 5e18 * 2**192\n r += 600920179829731861736702779321621459595472258049074101567377883020018308;\n // base conversion: mul 2**18 / 2**192\n r >>= 174;\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n LOW LEVEL FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function mulDivDown(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // Divide z by the denominator.\n z := div(z, denominator)\n }\n }\n\n function mulDivUp(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // First, divide z - 1 by the denominator and add 1.\n // We allow z - 1 to underflow if z is 0, because we multiply the\n // end result by 0 if z is zero, ensuring we return 0 if z is zero.\n z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\n }\n }\n\n function rpow(\n uint256 x,\n uint256 n,\n uint256 scalar\n ) internal pure returns (uint256 z) {\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n // 0 ** 0 = 1\n z := scalar\n }\n default {\n // 0 ** n = 0\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n // If n is even, store scalar in z for now.\n z := scalar\n }\n default {\n // If n is odd, store x in z for now.\n z := x\n }\n\n // Shifting right by 1 is like dividing by 2.\n let half := shr(1, scalar)\n\n for {\n // Shift n right by 1 before looping to halve it.\n n := shr(1, n)\n } n {\n // Shift n right by 1 each iteration to halve it.\n n := shr(1, n)\n } {\n // Revert immediately if x ** 2 would overflow.\n // Equivalent to iszero(eq(div(xx, x), x)) here.\n if shr(128, x) {\n revert(0, 0)\n }\n\n // Store x squared.\n let xx := mul(x, x)\n\n // Round to the nearest number.\n let xxRound := add(xx, half)\n\n // Revert if xx + half overflowed.\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n\n // Set x to scaled xxRound.\n x := div(xxRound, scalar)\n\n // If n is even:\n if mod(n, 2) {\n // Compute z * x.\n let zx := mul(z, x)\n\n // If z * x overflowed:\n if iszero(eq(div(zx, x), z)) {\n // Revert if x is non-zero.\n if iszero(iszero(x)) {\n revert(0, 0)\n }\n }\n\n // Round to the nearest number.\n let zxRound := add(zx, half)\n\n // Revert if zx + half overflowed.\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n\n // Return properly scaled zxRound.\n z := div(zxRound, scalar)\n }\n }\n }\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n GENERAL NUMBER UTILITIES\n //////////////////////////////////////////////////////////////*/\n\n function sqrt(uint256 x) internal pure returns (uint256 z) {\n assembly {\n let y := x // We start y at x, which will help us make our initial estimate.\n\n z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n // We check y >= 2^(k + 8) but shift right by k bits\n // each branch to ensure that if x >= 256, then y >= 256.\n if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n y := shr(128, y)\n z := shl(64, z)\n }\n if iszero(lt(y, 0x1000000000000000000)) {\n y := shr(64, y)\n z := shl(32, z)\n }\n if iszero(lt(y, 0x10000000000)) {\n y := shr(32, y)\n z := shl(16, z)\n }\n if iszero(lt(y, 0x1000000)) {\n y := shr(16, y)\n z := shl(8, z)\n }\n\n // Goal was to get z*z*y within a small factor of x. More iterations could\n // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n // There is no overflow risk here since y < 2^136 after the first branch above.\n z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n\n // If x+1 is a perfect square, the Babylonian method cycles between\n // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n z := sub(z, lt(div(x, z), z))\n }\n }\n\n function log2(uint256 x) internal pure returns (uint256 r) {\n require(x > 0, \"UNDEFINED\");\n\n assembly {\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\n r := or(r, shl(3, lt(0xff, shr(r, x))))\n r := or(r, shl(2, lt(0xf, shr(r, x))))\n r := or(r, shl(1, lt(0x3, shr(r, x))))\n r := or(r, lt(0x1, shr(r, x)))\n }\n }\n}\n" - }, - "node_modules/ds-test/src/test.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.5.0;\n\ncontract DSTest {\n event log (string);\n event logs (bytes);\n\n event log_address (address);\n event log_bytes32 (bytes32);\n event log_int (int);\n event log_uint (uint);\n event log_bytes (bytes);\n event log_string (string);\n\n event log_named_address (string key, address val);\n event log_named_bytes32 (string key, bytes32 val);\n event log_named_decimal_int (string key, int val, uint decimals);\n event log_named_decimal_uint (string key, uint val, uint decimals);\n event log_named_int (string key, int val);\n event log_named_uint (string key, uint val);\n event log_named_bytes (string key, bytes val);\n event log_named_string (string key, string val);\n\n bool public IS_TEST = true;\n bool private _failed;\n\n address constant HEVM_ADDRESS =\n address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));\n\n modifier mayRevert() { _; }\n modifier testopts(string memory) { _; }\n\n function failed() public returns (bool) {\n if (_failed) {\n return _failed;\n } else {\n bool globalFailed = false;\n if (hasHEVMContext()) {\n (, bytes memory retdata) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"load(address,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"))\n )\n );\n globalFailed = abi.decode(retdata, (bool));\n }\n return globalFailed;\n }\n } \n\n function fail() internal {\n if (hasHEVMContext()) {\n (bool status, ) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"store(address,bytes32,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"), bytes32(uint256(0x01)))\n )\n );\n status; // Silence compiler warnings\n }\n _failed = true;\n }\n\n function hasHEVMContext() internal view returns (bool) {\n uint256 hevmCodeSize = 0;\n assembly {\n hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D)\n }\n return hevmCodeSize > 0;\n }\n\n modifier logs_gas() {\n uint startGas = gasleft();\n _;\n uint endGas = gasleft();\n emit log_named_uint(\"gas\", startGas - endGas);\n }\n\n function assertTrue(bool condition) internal {\n if (!condition) {\n emit log(\"Error: Assertion Failed\");\n fail();\n }\n }\n\n function assertTrue(bool condition, string memory err) internal {\n if (!condition) {\n emit log_named_string(\"Error\", err);\n assertTrue(condition);\n }\n }\n\n function assertEq(address a, address b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [address]\");\n emit log_named_address(\" Expected\", b);\n emit log_named_address(\" Actual\", a);\n fail();\n }\n }\n function assertEq(address a, address b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes32 a, bytes32 b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bytes32]\");\n emit log_named_bytes32(\" Expected\", b);\n emit log_named_bytes32(\" Actual\", a);\n fail();\n }\n }\n function assertEq(bytes32 a, bytes32 b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq32(bytes32 a, bytes32 b) internal {\n assertEq(a, b);\n }\n function assertEq32(bytes32 a, bytes32 b, string memory err) internal {\n assertEq(a, b, err);\n }\n\n function assertEq(int a, int b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [int]\");\n emit log_named_int(\" Expected\", b);\n emit log_named_int(\" Actual\", a);\n fail();\n }\n }\n function assertEq(int a, int b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq(uint a, uint b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [uint]\");\n emit log_named_uint(\" Expected\", b);\n emit log_named_uint(\" Actual\", a);\n fail();\n }\n }\n function assertEq(uint a, uint b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEqDecimal(int a, int b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Expected\", b, decimals);\n emit log_named_decimal_int(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Expected\", b, decimals);\n emit log_named_decimal_uint(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n\n function assertGt(uint a, uint b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGt(uint a, uint b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGt(int a, int b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGt(int a, int b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGtDecimal(int a, int b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n\n function assertGe(uint a, uint b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGe(uint a, uint b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGe(int a, int b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGe(int a, int b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGeDecimal(int a, int b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertLt(uint a, uint b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLt(uint a, uint b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLt(int a, int b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLt(int a, int b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLtDecimal(int a, int b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n\n function assertLe(uint a, uint b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLe(uint a, uint b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLe(int a, int b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLe(int a, int b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLeDecimal(int a, int b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLeDecimal(a, b, decimals);\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertEq(string memory a, string memory b) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log(\"Error: a == b not satisfied [string]\");\n emit log_named_string(\" Expected\", b);\n emit log_named_string(\" Actual\", a);\n fail();\n }\n }\n function assertEq(string memory a, string memory b, string memory err) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {\n ok = true;\n if (a.length == b.length) {\n for (uint i = 0; i < a.length; i++) {\n if (a[i] != b[i]) {\n ok = false;\n }\n }\n } else {\n ok = false;\n }\n }\n function assertEq0(bytes memory a, bytes memory b) internal {\n if (!checkEq0(a, b)) {\n emit log(\"Error: a == b not satisfied [bytes]\");\n emit log_named_bytes(\" Expected\", b);\n emit log_named_bytes(\" Actual\", a);\n fail();\n }\n }\n function assertEq0(bytes memory a, bytes memory b, string memory err) internal {\n if (!checkEq0(a, b)) {\n emit log_named_string(\"Error\", err);\n assertEq0(a, b);\n }\n }\n}\n" - }, - "node_modules/forge-std/src/Base.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {StdStorage} from \"./StdStorage.sol\";\nimport {Vm, VmSafe} from \"./Vm.sol\";\n\nabstract contract CommonBase {\n // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.\n address internal constant VM_ADDRESS = address(uint160(uint256(keccak256(\"hevm cheat code\"))));\n // console.sol and console2.sol work by executing a staticcall to this address.\n address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;\n // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38.\n address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256(\"foundry default caller\"))));\n // Address of the test contract, deployed by the DEFAULT_SENDER.\n address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;\n // Deterministic deployment address of the Multicall3 contract.\n address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11;\n\n uint256 internal constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n Vm internal constant vm = Vm(VM_ADDRESS);\n StdStorage internal stdstore;\n}\n\nabstract contract TestBase is CommonBase {}\n\nabstract contract ScriptBase is CommonBase {\n // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);\n}\n" - }, - "node_modules/forge-std/src/StdAssertions.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {DSTest} from \"ds-test/test.sol\";\nimport {stdMath} from \"./StdMath.sol\";\n\nabstract contract StdAssertions is DSTest {\n event log_array(uint256[] val);\n event log_array(int256[] val);\n event log_array(address[] val);\n event log_named_array(string key, uint256[] val);\n event log_named_array(string key, int256[] val);\n event log_named_array(string key, address[] val);\n\n function fail(string memory err) internal virtual {\n emit log_named_string(\"Error\", err);\n fail();\n }\n\n function assertFalse(bool data) internal virtual {\n assertTrue(!data);\n }\n\n function assertFalse(bool data, string memory err) internal virtual {\n assertTrue(!data, err);\n }\n\n function assertEq(bool a, bool b) internal virtual {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bool]\");\n emit log_named_string(\" Left\", a ? \"true\" : \"false\");\n emit log_named_string(\" Right\", b ? \"true\" : \"false\");\n fail();\n }\n }\n\n function assertEq(bool a, bool b, string memory err) internal virtual {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes memory a, bytes memory b) internal virtual {\n assertEq0(a, b);\n }\n\n function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual {\n assertEq0(a, b, err);\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [uint[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [int[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(address[] memory a, address[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [address[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n // Legacy helper\n function assertEqUint(uint256 a, uint256 b) internal virtual {\n assertEq(uint256(a), uint256(b));\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100%\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals,\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual {\n assertEqCall(target, callDataA, target, callDataB, true);\n }\n\n function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB)\n internal\n virtual\n {\n assertEqCall(targetA, callDataA, targetB, callDataB, true);\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData)\n internal\n virtual\n {\n assertEqCall(target, callDataA, target, callDataB, strictRevertData);\n }\n\n function assertEqCall(\n address targetA,\n bytes memory callDataA,\n address targetB,\n bytes memory callDataB,\n bool strictRevertData\n ) internal virtual {\n (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA);\n (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB);\n\n if (successA && successB) {\n assertEq(returnDataA, returnDataB, \"Call return data does not match\");\n }\n\n if (!successA && !successB && strictRevertData) {\n assertEq(returnDataA, returnDataB, \"Call revert data does not match\");\n }\n\n if (!successA && successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call revert data\", returnDataA);\n emit log_named_bytes(\" Right call return data\", returnDataB);\n fail();\n }\n\n if (successA && !successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call return data\", returnDataA);\n emit log_named_bytes(\" Right call revert data\", returnDataB);\n fail();\n }\n }\n}\n" - }, - "node_modules/forge-std/src/StdChains.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n/**\n * StdChains provides information about EVM compatible chains that can be used in scripts/tests.\n * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are\n * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of\n * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the\n * alias used in this contract, which can be found as the first argument to the\n * `setChainWithDefaultRpcUrl` call in the `initialize` function.\n *\n * There are two main ways to use this contract:\n * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or\n * `setChain(string memory chainAlias, Chain memory chain)`\n * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`.\n *\n * The first time either of those are used, chains are initialized with the default set of RPC URLs.\n * This is done in `initialize`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in\n * `defaultRpcUrls`.\n *\n * The `setChain` function is straightforward, and it simply saves off the given chain data.\n *\n * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say\n * we want to retrieve `mainnet`'s RPC URL:\n * - If you haven't set any mainnet chain info with `setChain`, you haven't specified that\n * chain in `foundry.toml` and no env var is set, the default data and RPC URL will be returned.\n * - If you have set a mainnet RPC URL in `foundry.toml` it will return that, if valid (e.g. if\n * a URL is given or if an environment variable is given and that environment variable exists).\n * Otherwise, the default data is returned.\n * - If you specified data with `setChain` it will return that.\n *\n * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.\n */\nabstract contract StdChains {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private initialized;\n\n struct ChainData {\n string name;\n uint256 chainId;\n string rpcUrl;\n }\n\n struct Chain {\n // The chain name.\n string name;\n // The chain's Chain ID.\n uint256 chainId;\n // The chain's alias. (i.e. what gets specified in `foundry.toml`).\n string chainAlias;\n // A default RPC endpoint for this chain.\n // NOTE: This default RPC URL is included for convenience to facilitate quick tests and\n // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy\n // usage as you will be throttled and this is a disservice to others who need this endpoint.\n string rpcUrl;\n }\n\n // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data.\n mapping(string => Chain) private chains;\n // Maps from the chain's alias to it's default RPC URL.\n mapping(string => string) private defaultRpcUrls;\n // Maps from a chain ID to it's alias.\n mapping(uint256 => string) private idToAlias;\n\n bool private fallbackToDefaultRpcUrls = true;\n\n // The RPC URL will be fetched from config or defaultRpcUrls if possible.\n function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) {\n require(bytes(chainAlias).length != 0, \"StdChains getChain(string): Chain alias cannot be the empty string.\");\n\n initialize();\n chain = chains[chainAlias];\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(string): Chain with alias \\\"\", chainAlias, \"\\\" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n function getChain(uint256 chainId) internal virtual returns (Chain memory chain) {\n require(chainId != 0, \"StdChains getChain(uint256): Chain ID cannot be 0.\");\n initialize();\n string memory chainAlias = idToAlias[chainId];\n\n chain = chains[chainAlias];\n\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(uint256): Chain with ID \", vm.toString(chainId), \" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, ChainData memory chain) internal virtual {\n require(\n bytes(chainAlias).length != 0,\n \"StdChains setChain(string,ChainData): Chain alias cannot be the empty string.\"\n );\n\n require(chain.chainId != 0, \"StdChains setChain(string,ChainData): Chain ID cannot be 0.\");\n\n initialize();\n string memory foundAlias = idToAlias[chain.chainId];\n\n require(\n bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)),\n string(\n abi.encodePacked(\n \"StdChains setChain(string,ChainData): Chain ID \",\n vm.toString(chain.chainId),\n \" already used by \\\"\",\n foundAlias,\n \"\\\".\"\n )\n )\n );\n\n uint256 oldChainId = chains[chainAlias].chainId;\n delete idToAlias[oldChainId];\n\n chains[chainAlias] =\n Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl});\n idToAlias[chain.chainId] = chainAlias;\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, Chain memory chain) internal virtual {\n setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl}));\n }\n\n function _toUpper(string memory str) private pure returns (string memory) {\n bytes memory strb = bytes(str);\n bytes memory copy = new bytes(strb.length);\n for (uint256 i = 0; i < strb.length; i++) {\n bytes1 b = strb[i];\n if (b >= 0x61 && b <= 0x7A) {\n copy[i] = bytes1(uint8(b) - 32);\n } else {\n copy[i] = b;\n }\n }\n return string(copy);\n }\n\n // lookup rpcUrl, in descending order of priority:\n // current -> config (foundry.toml) -> environment variable -> default\n function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) {\n if (bytes(chain.rpcUrl).length == 0) {\n try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) {\n chain.rpcUrl = configRpcUrl;\n } catch (bytes memory err) {\n string memory envName = string(abi.encodePacked(_toUpper(chainAlias), \"_RPC_URL\"));\n if (fallbackToDefaultRpcUrls) {\n chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]);\n } else {\n chain.rpcUrl = vm.envString(envName);\n }\n // distinguish 'not found' from 'cannot read'\n bytes memory notFoundError =\n abi.encodeWithSignature(\"CheatCodeError\", string(abi.encodePacked(\"invalid rpc url \", chainAlias)));\n if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, err), mload(err))\n }\n }\n }\n }\n return chain;\n }\n\n function setFallbackToDefaultRpcUrls(bool useDefault) internal {\n fallbackToDefaultRpcUrls = useDefault;\n }\n\n function initialize() private {\n if (initialized) return;\n\n initialized = true;\n\n // If adding an RPC here, make sure to test the default RPC URL in `testRpcs`\n setChainWithDefaultRpcUrl(\"anvil\", ChainData(\"Anvil\", 31337, \"http://127.0.0.1:8545\"));\n setChainWithDefaultRpcUrl(\n \"mainnet\", ChainData(\"Mainnet\", 1, \"https://mainnet.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"goerli\", ChainData(\"Goerli\", 5, \"https://goerli.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"sepolia\", ChainData(\"Sepolia\", 11155111, \"https://sepolia.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\"optimism\", ChainData(\"Optimism\", 10, \"https://mainnet.optimism.io\"));\n setChainWithDefaultRpcUrl(\"optimism_goerli\", ChainData(\"Optimism Goerli\", 420, \"https://goerli.optimism.io\"));\n setChainWithDefaultRpcUrl(\"arbitrum_one\", ChainData(\"Arbitrum One\", 42161, \"https://arb1.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\n \"arbitrum_one_goerli\", ChainData(\"Arbitrum One Goerli\", 421613, \"https://goerli-rollup.arbitrum.io/rpc\")\n );\n setChainWithDefaultRpcUrl(\"arbitrum_nova\", ChainData(\"Arbitrum Nova\", 42170, \"https://nova.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\"polygon\", ChainData(\"Polygon\", 137, \"https://polygon-rpc.com\"));\n setChainWithDefaultRpcUrl(\n \"polygon_mumbai\", ChainData(\"Polygon Mumbai\", 80001, \"https://rpc-mumbai.maticvigil.com\")\n );\n setChainWithDefaultRpcUrl(\"avalanche\", ChainData(\"Avalanche\", 43114, \"https://api.avax.network/ext/bc/C/rpc\"));\n setChainWithDefaultRpcUrl(\n \"avalanche_fuji\", ChainData(\"Avalanche Fuji\", 43113, \"https://api.avax-test.network/ext/bc/C/rpc\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain\", ChainData(\"BNB Smart Chain\", 56, \"https://bsc-dataseed1.binance.org\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain_testnet\",\n ChainData(\"BNB Smart Chain Testnet\", 97, \"https://rpc.ankr.com/bsc_testnet_chapel\")\n );\n setChainWithDefaultRpcUrl(\"gnosis_chain\", ChainData(\"Gnosis Chain\", 100, \"https://rpc.gnosischain.com\"));\n }\n\n // set chain info, with priority to chainAlias' rpc url in foundry.toml\n function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private {\n string memory rpcUrl = chain.rpcUrl;\n defaultRpcUrls[chainAlias] = rpcUrl;\n chain.rpcUrl = \"\";\n setChain(chainAlias, chain);\n chain.rpcUrl = rpcUrl; // restore argument\n }\n}\n" - }, - "node_modules/forge-std/src/StdCheats.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdCheatsSafe {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private gasMeteringOff;\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawTx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n // json value name = function\n string functionSig;\n bytes32 hash;\n // json value name = tx\n RawTx1559Detail txDetail;\n // json value name = type\n string opcode;\n }\n\n struct RawTx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n bytes gas;\n bytes nonce;\n address to;\n bytes txType;\n bytes value;\n }\n\n struct Tx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n bytes32 hash;\n Tx1559Detail txDetail;\n string opcode;\n }\n\n struct Tx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n uint256 gas;\n uint256 nonce;\n address to;\n uint256 txType;\n uint256 value;\n }\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct TxLegacy {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n string hash;\n string opcode;\n TxDetailLegacy transaction;\n }\n\n struct TxDetailLegacy {\n AccessList[] accessList;\n uint256 chainId;\n bytes data;\n address from;\n uint256 gas;\n uint256 gasPrice;\n bytes32 hash;\n uint256 nonce;\n bytes1 opcode;\n bytes32 r;\n bytes32 s;\n uint256 txType;\n address to;\n uint8 v;\n uint256 value;\n }\n\n struct AccessList {\n address accessAddress;\n bytes32[] storageKeys;\n }\n\n // Data structures to parse Receipt objects from the broadcast artifact.\n // The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawReceipt {\n bytes32 blockHash;\n bytes blockNumber;\n address contractAddress;\n bytes cumulativeGasUsed;\n bytes effectiveGasPrice;\n address from;\n bytes gasUsed;\n RawReceiptLog[] logs;\n bytes logsBloom;\n bytes status;\n address to;\n bytes32 transactionHash;\n bytes transactionIndex;\n }\n\n struct Receipt {\n bytes32 blockHash;\n uint256 blockNumber;\n address contractAddress;\n uint256 cumulativeGasUsed;\n uint256 effectiveGasPrice;\n address from;\n uint256 gasUsed;\n ReceiptLog[] logs;\n bytes logsBloom;\n uint256 status;\n address to;\n bytes32 transactionHash;\n uint256 transactionIndex;\n }\n\n // Data structures to parse the entire broadcast artifact, assuming the\n // transactions conform to EIP1559.\n\n struct EIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n Receipt[] receipts;\n uint256 timestamp;\n Tx1559[] transactions;\n TxReturn[] txReturns;\n }\n\n struct RawEIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n RawReceipt[] receipts;\n TxReturn[] txReturns;\n uint256 timestamp;\n RawTx1559[] transactions;\n }\n\n struct RawReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n bytes blockNumber;\n bytes data;\n bytes logIndex;\n bool removed;\n bytes32[] topics;\n bytes32 transactionHash;\n bytes transactionIndex;\n bytes transactionLogIndex;\n }\n\n struct ReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n uint256 blockNumber;\n bytes data;\n uint256 logIndex;\n bytes32[] topics;\n uint256 transactionIndex;\n uint256 transactionLogIndex;\n bool removed;\n }\n\n struct TxReturn {\n string internalType;\n string value;\n }\n\n function assumeNoPrecompiles(address addr) internal virtual {\n // Assembly required since `block.chainid` was introduced in 0.8.0.\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n assumeNoPrecompiles(addr, chainId);\n }\n\n function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual {\n // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific\n // address), but the same rationale for excluding them applies so we include those too.\n\n // These should be present on all EVM-compatible chains.\n vm.assume(addr < address(0x1) || addr > address(0x9));\n\n // forgefmt: disable-start\n if (chainId == 10 || chainId == 420) {\n // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21\n vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800));\n } else if (chainId == 42161 || chainId == 421613) {\n // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains\n vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068));\n } else if (chainId == 43114 || chainId == 43113) {\n // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59\n vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff));\n vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF));\n vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff));\n }\n // forgefmt: disable-end\n }\n\n function readEIP1559ScriptArtifact(string memory path)\n internal\n view\n virtual\n returns (EIP1559ScriptArtifact memory)\n {\n string memory data = vm.readFile(path);\n bytes memory parsedData = vm.parseJson(data);\n RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact));\n EIP1559ScriptArtifact memory artifact;\n artifact.libraries = rawArtifact.libraries;\n artifact.path = rawArtifact.path;\n artifact.timestamp = rawArtifact.timestamp;\n artifact.pending = rawArtifact.pending;\n artifact.txReturns = rawArtifact.txReturns;\n artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts);\n artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions);\n return artifact;\n }\n\n function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) {\n Tx1559[] memory txs = new Tx1559[](rawTxs.length);\n for (uint256 i; i < rawTxs.length; i++) {\n txs[i] = rawToConvertedEIPTx1559(rawTxs[i]);\n }\n return txs;\n }\n\n function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) {\n Tx1559 memory transaction;\n transaction.arguments = rawTx.arguments;\n transaction.contractName = rawTx.contractName;\n transaction.functionSig = rawTx.functionSig;\n transaction.hash = rawTx.hash;\n transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail);\n transaction.opcode = rawTx.opcode;\n return transaction;\n }\n\n function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail)\n internal\n pure\n virtual\n returns (Tx1559Detail memory)\n {\n Tx1559Detail memory txDetail;\n txDetail.data = rawDetail.data;\n txDetail.from = rawDetail.from;\n txDetail.to = rawDetail.to;\n txDetail.nonce = _bytesToUint(rawDetail.nonce);\n txDetail.txType = _bytesToUint(rawDetail.txType);\n txDetail.value = _bytesToUint(rawDetail.value);\n txDetail.gas = _bytesToUint(rawDetail.gas);\n txDetail.accessList = rawDetail.accessList;\n return txDetail;\n }\n\n function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".transactions\");\n RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[]));\n return rawToConvertedEIPTx1559s(rawTxs);\n }\n\n function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".transactions[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559));\n return rawToConvertedEIPTx1559(rawTx);\n }\n\n // Analogous to readTransactions, but for receipts.\n function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".receipts\");\n RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[]));\n return rawToConvertedReceipts(rawReceipts);\n }\n\n function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".receipts[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt));\n return rawToConvertedReceipt(rawReceipt);\n }\n\n function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) {\n Receipt[] memory receipts = new Receipt[](rawReceipts.length);\n for (uint256 i; i < rawReceipts.length; i++) {\n receipts[i] = rawToConvertedReceipt(rawReceipts[i]);\n }\n return receipts;\n }\n\n function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) {\n Receipt memory receipt;\n receipt.blockHash = rawReceipt.blockHash;\n receipt.to = rawReceipt.to;\n receipt.from = rawReceipt.from;\n receipt.contractAddress = rawReceipt.contractAddress;\n receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice);\n receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed);\n receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed);\n receipt.status = _bytesToUint(rawReceipt.status);\n receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex);\n receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber);\n receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs);\n receipt.logsBloom = rawReceipt.logsBloom;\n receipt.transactionHash = rawReceipt.transactionHash;\n return receipt;\n }\n\n function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs)\n internal\n pure\n virtual\n returns (ReceiptLog[] memory)\n {\n ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length);\n for (uint256 i; i < rawLogs.length; i++) {\n logs[i].logAddress = rawLogs[i].logAddress;\n logs[i].blockHash = rawLogs[i].blockHash;\n logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber);\n logs[i].data = rawLogs[i].data;\n logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex);\n logs[i].topics = rawLogs[i].topics;\n logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex);\n logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex);\n logs[i].removed = rawLogs[i].removed;\n }\n return logs;\n }\n\n // Deploy a contract by fetching the contract bytecode from\n // the artifacts directory\n // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))`\n function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes): Deployment failed.\");\n }\n\n function deployCode(string memory what) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string): Deployment failed.\");\n }\n\n /// @dev deploy contract with value on construction\n function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes,uint256): Deployment failed.\");\n }\n\n function deployCode(string memory what, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,uint256): Deployment failed.\");\n }\n\n // creates a labeled address and the corresponding private key\n function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) {\n privateKey = uint256(keccak256(abi.encodePacked(name)));\n addr = vm.addr(privateKey);\n vm.label(addr, name);\n }\n\n // creates a labeled address\n function makeAddr(string memory name) internal virtual returns (address addr) {\n (addr,) = makeAddrAndKey(name);\n }\n\n function deriveRememberKey(string memory mnemonic, uint32 index)\n internal\n virtual\n returns (address who, uint256 privateKey)\n {\n privateKey = vm.deriveKey(mnemonic, index);\n who = vm.rememberKey(privateKey);\n }\n\n function _bytesToUint(bytes memory b) private pure returns (uint256) {\n require(b.length <= 32, \"StdCheats _bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n function isFork() internal view virtual returns (bool status) {\n try vm.activeFork() {\n status = true;\n } catch (bytes memory) {}\n }\n\n modifier skipWhenForking() {\n if (!isFork()) {\n _;\n }\n }\n\n modifier skipWhenNotForking() {\n if (isFork()) {\n _;\n }\n }\n\n modifier noGasMetering() {\n vm.pauseGasMetering();\n // To prevent turning gas monitoring back on with nested functions that use this modifier,\n // we check if gasMetering started in the off position. If it did, we don't want to turn\n // it back on until we exit the top level function that used the modifier\n //\n // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well.\n // funcA will have `gasStartedOff` as false, funcB will have it as true,\n // so we only turn metering back on at the end of the funcA\n bool gasStartedOff = gasMeteringOff;\n gasMeteringOff = true;\n\n _;\n\n // if gas metering was on when this modifier was called, turn it back on at the end\n if (!gasStartedOff) {\n gasMeteringOff = false;\n vm.resumeGasMetering();\n }\n }\n\n // a cheat for fuzzing addresses that are payable only\n // see https://github.com/foundry-rs/foundry/issues/3631\n function assumePayable(address addr) internal virtual {\n (bool success,) = payable(addr).call{value: 0}(\"\");\n vm.assume(success);\n }\n}\n\n// Wrappers around cheatcodes to avoid footguns\nabstract contract StdCheats is StdCheatsSafe {\n using stdStorage for StdStorage;\n\n StdStorage private stdstore;\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n // Skip forward or rewind time by the specified number of seconds\n function skip(uint256 time) internal virtual {\n vm.warp(block.timestamp + time);\n }\n\n function rewind(uint256 time) internal virtual {\n vm.warp(block.timestamp - time);\n }\n\n // Setup a prank from an address that has some ether\n function hoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender, origin);\n }\n\n function hoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender, origin);\n }\n\n // Start perpetual prank from an address that has some ether\n function startHoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender);\n }\n\n function startHoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender);\n }\n\n // Start perpetual prank from an address that has some ether\n // tx.origin is set to the origin parameter\n function startHoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender, origin);\n }\n\n function startHoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender, origin);\n }\n\n function changePrank(address msgSender) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender);\n }\n\n function changePrank(address msgSender, address txOrigin) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender, txOrigin);\n }\n\n // The same as Vm's `deal`\n // Use the alternative signature for ERC20 tokens\n function deal(address to, uint256 give) internal virtual {\n vm.deal(to, give);\n }\n\n // Set the balance of an account for any ERC20 token\n // Use the alternative signature to update `totalSupply`\n function deal(address token, address to, uint256 give) internal virtual {\n deal(token, to, give, false);\n }\n\n // Set the balance of an account for any ERC1155 token\n // Use the alternative signature to update `totalSupply`\n function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual {\n dealERC1155(token, to, id, give, false);\n }\n\n function deal(address token, address to, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd));\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0x18160ddd).checked_write(totSup);\n }\n }\n\n function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x00fdd58e, to, id));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0xbd85b039, id));\n require(\n totSupData.length != 0,\n \"StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply.\"\n );\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup);\n }\n }\n\n function dealERC721(address token, address to, uint256 id) internal virtual {\n // check if token id is already minted and the actual owner.\n (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id));\n require(successMinted, \"StdCheats deal(address,address,uint,bool): id not minted.\");\n\n // get owner current balance\n (, bytes memory fromBalData) = token.call(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address))));\n uint256 fromPrevBal = abi.decode(fromBalData, (uint256));\n\n // get new user current balance\n (, bytes memory toBalData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 toPrevBal = abi.decode(toBalData, (uint256));\n\n // update balances\n stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal);\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal);\n\n // update owner\n stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to);\n }\n}\n" - }, - "node_modules/forge-std/src/StdError.sol": { - "content": "// SPDX-License-Identifier: MIT\n// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdError {\n bytes public constant assertionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x01);\n bytes public constant arithmeticError = abi.encodeWithSignature(\"Panic(uint256)\", 0x11);\n bytes public constant divisionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x12);\n bytes public constant enumConversionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x21);\n bytes public constant encodeStorageError = abi.encodeWithSignature(\"Panic(uint256)\", 0x22);\n bytes public constant popError = abi.encodeWithSignature(\"Panic(uint256)\", 0x31);\n bytes public constant indexOOBError = abi.encodeWithSignature(\"Panic(uint256)\", 0x32);\n bytes public constant memOverflowError = abi.encodeWithSignature(\"Panic(uint256)\", 0x41);\n bytes public constant zeroVarError = abi.encodeWithSignature(\"Panic(uint256)\", 0x51);\n}\n" - }, - "node_modules/forge-std/src/StdInvariant.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ncontract StdInvariant {\n struct FuzzSelector {\n address addr;\n bytes4[] selectors;\n }\n\n address[] private _excludedContracts;\n address[] private _excludedSenders;\n address[] private _targetedContracts;\n address[] private _targetedSenders;\n\n string[] private _excludedArtifacts;\n string[] private _targetedArtifacts;\n\n FuzzSelector[] private _targetedArtifactSelectors;\n FuzzSelector[] private _targetedSelectors;\n\n // Functions for users:\n // These are intended to be called in tests.\n\n function excludeContract(address newExcludedContract_) internal {\n _excludedContracts.push(newExcludedContract_);\n }\n\n function excludeSender(address newExcludedSender_) internal {\n _excludedSenders.push(newExcludedSender_);\n }\n\n function excludeArtifact(string memory newExcludedArtifact_) internal {\n _excludedArtifacts.push(newExcludedArtifact_);\n }\n\n function targetArtifact(string memory newTargetedArtifact_) internal {\n _targetedArtifacts.push(newTargetedArtifact_);\n }\n\n function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal {\n _targetedArtifactSelectors.push(newTargetedArtifactSelector_);\n }\n\n function targetContract(address newTargetedContract_) internal {\n _targetedContracts.push(newTargetedContract_);\n }\n\n function targetSelector(FuzzSelector memory newTargetedSelector_) internal {\n _targetedSelectors.push(newTargetedSelector_);\n }\n\n function targetSender(address newTargetedSender_) internal {\n _targetedSenders.push(newTargetedSender_);\n }\n\n // Functions for forge:\n // These are called by forge to run invariant tests and don't need to be called in tests.\n\n function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) {\n excludedArtifacts_ = _excludedArtifacts;\n }\n\n function excludeContracts() public view returns (address[] memory excludedContracts_) {\n excludedContracts_ = _excludedContracts;\n }\n\n function excludeSenders() public view returns (address[] memory excludedSenders_) {\n excludedSenders_ = _excludedSenders;\n }\n\n function targetArtifacts() public view returns (string[] memory targetedArtifacts_) {\n targetedArtifacts_ = _targetedArtifacts;\n }\n\n function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) {\n targetedArtifactSelectors_ = _targetedArtifactSelectors;\n }\n\n function targetContracts() public view returns (address[] memory targetedContracts_) {\n targetedContracts_ = _targetedContracts;\n }\n\n function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) {\n targetedSelectors_ = _targetedSelectors;\n }\n\n function targetSenders() public view returns (address[] memory targetedSenders_) {\n targetedSenders_ = _targetedSenders;\n }\n}\n" - }, - "node_modules/forge-std/src/StdJson.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing JSON files\n// To parse:\n// ```\n// using stdJson for string;\n// string memory json = vm.readFile(\"some_peth\");\n// json.parseUint(\"\");\n// ```\n// To write:\n// ```\n// using stdJson for string;\n// string memory json = \"deploymentArtifact\";\n// Contract contract = new Contract();\n// json.serialize(\"contractAddress\", address(contract));\n// json = json.serialize(\"deploymentTimes\", uint(1));\n// // store the stringified JSON to the 'json' variable we have been using as a key\n// // as we won't need it any longer\n// string memory json2 = \"finalArtifact\";\n// string memory final = json2.serialize(\"depArtifact\", json);\n// final.write(\"\");\n// ```\n\nlibrary stdJson {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJson(json, key);\n }\n\n function readUint(string memory json, string memory key) internal returns (uint256) {\n return vm.parseJsonUint(json, key);\n }\n\n function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) {\n return vm.parseJsonUintArray(json, key);\n }\n\n function readInt(string memory json, string memory key) internal returns (int256) {\n return vm.parseJsonInt(json, key);\n }\n\n function readIntArray(string memory json, string memory key) internal returns (int256[] memory) {\n return vm.parseJsonIntArray(json, key);\n }\n\n function readBytes32(string memory json, string memory key) internal returns (bytes32) {\n return vm.parseJsonBytes32(json, key);\n }\n\n function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) {\n return vm.parseJsonBytes32Array(json, key);\n }\n\n function readString(string memory json, string memory key) internal returns (string memory) {\n return vm.parseJsonString(json, key);\n }\n\n function readStringArray(string memory json, string memory key) internal returns (string[] memory) {\n return vm.parseJsonStringArray(json, key);\n }\n\n function readAddress(string memory json, string memory key) internal returns (address) {\n return vm.parseJsonAddress(json, key);\n }\n\n function readAddressArray(string memory json, string memory key) internal returns (address[] memory) {\n return vm.parseJsonAddressArray(json, key);\n }\n\n function readBool(string memory json, string memory key) internal returns (bool) {\n return vm.parseJsonBool(json, key);\n }\n\n function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) {\n return vm.parseJsonBoolArray(json, key);\n }\n\n function readBytes(string memory json, string memory key) internal returns (bytes memory) {\n return vm.parseJsonBytes(json, key);\n }\n\n function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) {\n return vm.parseJsonBytesArray(json, key);\n }\n\n function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bool[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function write(string memory jsonKey, string memory path) internal {\n vm.writeJson(jsonKey, path);\n }\n\n function write(string memory jsonKey, string memory path, string memory valueKey) internal {\n vm.writeJson(jsonKey, path, valueKey);\n }\n}\n" - }, - "node_modules/forge-std/src/StdMath.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdMath {\n int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n function abs(int256 a) internal pure returns (uint256) {\n // Required or it will fail when `a = type(int256).min`\n if (a == INT256_MIN) {\n return 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n }\n\n return uint256(a > 0 ? a : -a);\n }\n\n function delta(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a - b : b - a;\n }\n\n function delta(int256 a, int256 b) internal pure returns (uint256) {\n // a and b are of the same sign\n // this works thanks to two's complement, the left-most bit is the sign bit\n if ((a ^ b) > -1) {\n return delta(abs(a), abs(b));\n }\n\n // a and b are of opposite signs\n return abs(a) + abs(b);\n }\n\n function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n\n return absDelta * 1e18 / b;\n }\n\n function percentDelta(int256 a, int256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n uint256 absB = abs(b);\n\n return absDelta * 1e18 / absB;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nstruct StdStorage {\n mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots;\n mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds;\n bytes32[] _keys;\n bytes4 _sig;\n uint256 _depth;\n address _target;\n bytes32 _set;\n}\n\nlibrary stdStorageSafe {\n event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot);\n event WARNING_UninitedSlot(address who, uint256 slot);\n\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return bytes4(keccak256(bytes(sigStr)));\n }\n\n /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against\n // slot complexity:\n // if flat, will be bytes32(uint256(uint));\n // if map, will be keccak256(abi.encode(key, uint(slot)));\n // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));\n // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);\n function find(StdStorage storage self) internal returns (uint256) {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n // calldata to test against\n if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n vm.record();\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n (bytes32[] memory reads,) = vm.accesses(address(who));\n if (reads.length == 1) {\n bytes32 curr = vm.load(who, reads[0]);\n if (curr == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[0]));\n }\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n } else if (reads.length > 1) {\n for (uint256 i = 0; i < reads.length; i++) {\n bytes32 prev = vm.load(who, reads[i]);\n if (prev == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[i]));\n }\n // store\n vm.store(who, reads[i], bytes32(hex\"1337\"));\n bool success;\n bytes memory rdat;\n {\n (success, rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n if (success && fdat == bytes32(hex\"1337\")) {\n // we found which of the slots is the actual one\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n vm.store(who, reads[i], prev);\n break;\n }\n vm.store(who, reads[i], prev);\n }\n } else {\n revert(\"stdStorage find(StdStorage): No storage use detected for target.\");\n }\n\n require(\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))],\n \"stdStorage find(StdStorage): Slot(s) not found.\"\n );\n\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n self._target = _target;\n return self;\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n self._sig = _sig;\n return self;\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n self._sig = sigs(_sig);\n return self;\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n self._keys.push(bytes32(uint256(uint160(who))));\n return self;\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n self._keys.push(bytes32(amt));\n return self;\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n self._keys.push(key);\n return self;\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n self._depth = _depth;\n return self;\n }\n\n function read(StdStorage storage self) private returns (bytes memory) {\n address t = self._target;\n uint256 s = find(self);\n return abi.encode(vm.load(t, bytes32(s)));\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return abi.decode(read(self), (bytes32));\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n int256 v = read_int(self);\n if (v == 0) return false;\n if (v == 1) return true;\n revert(\"stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool.\");\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return abi.decode(read(self), (address));\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return abi.decode(read(self), (uint256));\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return abi.decode(read(self), (int256));\n }\n\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n\nlibrary stdStorage {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return stdStorageSafe.sigs(sigStr);\n }\n\n function find(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.find(self);\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n return stdStorageSafe.target(self, _target);\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, who);\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, amt);\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, key);\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n return stdStorageSafe.depth(self, _depth);\n }\n\n function checked_write(StdStorage storage self, address who) internal {\n checked_write(self, bytes32(uint256(uint160(who))));\n }\n\n function checked_write(StdStorage storage self, uint256 amt) internal {\n checked_write(self, bytes32(amt));\n }\n\n function checked_write(StdStorage storage self, bool write) internal {\n bytes32 t;\n /// @solidity memory-safe-assembly\n assembly {\n t := write\n }\n checked_write(self, t);\n }\n\n function checked_write(StdStorage storage self, bytes32 set) internal {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n find(self);\n }\n bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]);\n\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n bytes32 curr = vm.load(who, slot);\n\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n vm.store(who, slot, set);\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return stdStorageSafe.read_bytes32(self);\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n return stdStorageSafe.read_bool(self);\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return stdStorageSafe.read_address(self);\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.read_uint(self);\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return stdStorageSafe.read_int(self);\n }\n\n // Private function so needs to be copied over\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n // Private function so needs to be copied over\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStyle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nlibrary StdStyle {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n string constant RED = \"\\u001b[91m\";\n string constant GREEN = \"\\u001b[92m\";\n string constant YELLOW = \"\\u001b[93m\";\n string constant BLUE = \"\\u001b[94m\";\n string constant MAGENTA = \"\\u001b[95m\";\n string constant CYAN = \"\\u001b[96m\";\n string constant BOLD = \"\\u001b[1m\";\n string constant DIM = \"\\u001b[2m\";\n string constant ITALIC = \"\\u001b[3m\";\n string constant UNDERLINE = \"\\u001b[4m\";\n string constant INVERSE = \"\\u001b[7m\";\n string constant RESET = \"\\u001b[0m\";\n\n function styleConcat(string memory style, string memory self) private pure returns (string memory) {\n return string(abi.encodePacked(style, self, RESET));\n }\n\n function red(string memory self) internal pure returns (string memory) {\n return styleConcat(RED, self);\n }\n\n function red(uint256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(int256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(address self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(bool self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes(bytes memory self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes32(bytes32 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function green(string memory self) internal pure returns (string memory) {\n return styleConcat(GREEN, self);\n }\n\n function green(uint256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(int256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(address self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(bool self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes(bytes memory self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes32(bytes32 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function yellow(string memory self) internal pure returns (string memory) {\n return styleConcat(YELLOW, self);\n }\n\n function yellow(uint256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(int256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(address self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(bool self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes(bytes memory self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes32(bytes32 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function blue(string memory self) internal pure returns (string memory) {\n return styleConcat(BLUE, self);\n }\n\n function blue(uint256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(int256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(address self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(bool self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes(bytes memory self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes32(bytes32 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function magenta(string memory self) internal pure returns (string memory) {\n return styleConcat(MAGENTA, self);\n }\n\n function magenta(uint256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(int256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(address self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(bool self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes(bytes memory self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes32(bytes32 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function cyan(string memory self) internal pure returns (string memory) {\n return styleConcat(CYAN, self);\n }\n\n function cyan(uint256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(int256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(address self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(bool self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes(bytes memory self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes32(bytes32 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function bold(string memory self) internal pure returns (string memory) {\n return styleConcat(BOLD, self);\n }\n\n function bold(uint256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(int256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(address self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(bool self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes(bytes memory self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes32(bytes32 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function dim(string memory self) internal pure returns (string memory) {\n return styleConcat(DIM, self);\n }\n\n function dim(uint256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(int256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(address self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(bool self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes(bytes memory self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes32(bytes32 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function italic(string memory self) internal pure returns (string memory) {\n return styleConcat(ITALIC, self);\n }\n\n function italic(uint256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(int256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(address self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(bool self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes(bytes memory self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes32(bytes32 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function underline(string memory self) internal pure returns (string memory) {\n return styleConcat(UNDERLINE, self);\n }\n\n function underline(uint256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(int256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(address self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(bool self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes(bytes memory self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes32(bytes32 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function inverse(string memory self) internal pure returns (string memory) {\n return styleConcat(INVERSE, self);\n }\n\n function inverse(uint256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(int256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(address self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(bool self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes(bytes memory self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes32(bytes32 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n}\n" - }, - "node_modules/forge-std/src/StdUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {IMulticall3} from \"./interfaces/IMulticall3.sol\";\n// TODO Remove import.\nimport {VmSafe} from \"./Vm.sol\";\n\nabstract contract StdUtils {\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n //////////////////////////////////////////////////////////////////////////*/\n\n IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;\n uint256 private constant INT256_MIN_ABS =\n 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n /*//////////////////////////////////////////////////////////////////////////\n INTERNAL FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n require(min <= max, \"StdUtils bound(uint256,uint256,uint256): Max is less than min.\");\n // If x is between min and max, return x directly. This is to ensure that dictionary values\n // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188\n if (x >= min && x <= max) return x;\n\n uint256 size = max - min + 1;\n\n // If the value is 0, 1, 2, 3, warp that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side.\n // This helps ensure coverage of the min/max values.\n if (x <= 3 && size > x) return min + x;\n if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x);\n\n // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.\n if (x > max) {\n uint256 diff = x - max;\n uint256 rem = diff % size;\n if (rem == 0) return max;\n result = min + rem - 1;\n } else if (x < min) {\n uint256 diff = min - x;\n uint256 rem = diff % size;\n if (rem == 0) return min;\n result = max - rem + 1;\n }\n }\n\n function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) {\n result = _bound(x, min, max);\n console2_log(\"Bound Result\", result);\n }\n\n function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) {\n require(min <= max, \"StdUtils bound(int256,int256,int256): Max is less than min.\");\n\n // Shifting all int256 values to uint256 to use _bound function. The range of two types are:\n // int256 : -(2**255) ~ (2**255 - 1)\n // uint256: 0 ~ (2**256 - 1)\n // So, add 2**255, INT256_MIN_ABS to the integer values.\n //\n // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow.\n // So, use `~uint256(x) + 1` instead.\n uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS);\n uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS);\n uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS);\n\n uint256 y = _bound(_x, _min, _max);\n\n // To move it back to int256 value, subtract INT256_MIN_ABS at here.\n result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS);\n console2_log(\"Bound result\", vm.toString(result));\n }\n\n function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {\n require(b.length <= 32, \"StdUtils bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce\n /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol)\n function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) {\n // forgefmt: disable-start\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))));\n if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))));\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce))));\n if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce))));\n if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce))));\n // forgefmt: disable-end\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return addressFromLast20Bytes(\n keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce)))\n );\n }\n\n function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer)\n internal\n pure\n virtual\n returns (address)\n {\n return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash)));\n }\n\n /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer\n function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) {\n return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY);\n }\n\n /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) {\n return hashInitCode(creationCode, \"\");\n }\n\n /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n /// @param args the ABI-encoded arguments to the constructor of C\n function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(creationCode, args));\n }\n\n // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses.\n function getTokenBalances(address token, address[] memory addresses)\n internal\n virtual\n returns (uint256[] memory balances)\n {\n uint256 tokenCodeSize;\n assembly {\n tokenCodeSize := extcodesize(token)\n }\n require(tokenCodeSize > 0, \"StdUtils getTokenBalances(address,address[]): Token address is not a contract.\");\n\n // ABI encode the aggregate call to Multicall3.\n uint256 length = addresses.length;\n IMulticall3.Call[] memory calls = new IMulticall3.Call[](length);\n for (uint256 i = 0; i < length; ++i) {\n // 0x70a08231 = bytes4(\"balanceOf(address)\"))\n calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))});\n }\n\n // Make the aggregate call.\n (, bytes[] memory returnData) = multicall.aggregate(calls);\n\n // ABI decode the return data and return the balances.\n balances = new uint256[](length);\n for (uint256 i = 0; i < length; ++i) {\n balances[i] = abi.decode(returnData[i], (uint256));\n }\n }\n\n /*//////////////////////////////////////////////////////////////////////////\n PRIVATE FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere.\n\n function console2_log(string memory p0, uint256 p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n status;\n }\n\n function console2_log(string memory p0, string memory p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n status;\n }\n}\n" - }, - "node_modules/forge-std/src/Test.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// 💬 ABOUT\n// Standard Library's default Test\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {StdAssertions} from \"./StdAssertions.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheats} from \"./StdCheats.sol\";\nimport {stdError} from \"./StdError.sol\";\nimport {StdInvariant} from \"./StdInvariant.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {Vm} from \"./Vm.sol\";\nimport {StdStyle} from \"./StdStyle.sol\";\n\n// 📦 BOILERPLATE\nimport {TestBase} from \"./Base.sol\";\nimport {DSTest} from \"ds-test/test.sol\";\n\n// ⭐️ TEST\nabstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase {\n// Note: IS_TEST() must return true.\n// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76.\n}\n" - }, - "node_modules/forge-std/src/Vm.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// Cheatcodes are marked as view/pure/none using the following rules:\n// 0. A call's observable behaviour includes its return value, logs, reverts and state writes,\n// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc),\n// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`,\n// 3. Otherwise you're `pure`.\n\ninterface VmSafe {\n struct Log {\n bytes32[] topics;\n bytes data;\n address emitter;\n }\n\n struct Rpc {\n string key;\n string url;\n }\n\n struct FsMetadata {\n bool isDir;\n bool isSymlink;\n uint256 length;\n bool readOnly;\n uint256 modified;\n uint256 accessed;\n uint256 created;\n }\n\n // Loads a storage slot from an address\n function load(address target, bytes32 slot) external view returns (bytes32 data);\n // Signs data\n function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);\n // Gets the address for a given private key\n function addr(uint256 privateKey) external pure returns (address keyAddr);\n // Gets the nonce of an account\n function getNonce(address account) external view returns (uint64 nonce);\n // Performs a foreign function call via the terminal\n function ffi(string[] calldata commandInput) external returns (bytes memory result);\n // Sets environment variables\n function setEnv(string calldata name, string calldata value) external;\n // Reads environment variables, (name) => (value)\n function envBool(string calldata name) external view returns (bool value);\n function envUint(string calldata name) external view returns (uint256 value);\n function envInt(string calldata name) external view returns (int256 value);\n function envAddress(string calldata name) external view returns (address value);\n function envBytes32(string calldata name) external view returns (bytes32 value);\n function envString(string calldata name) external view returns (string memory value);\n function envBytes(string calldata name) external view returns (bytes memory value);\n // Reads environment variables as arrays\n function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value);\n function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value);\n function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value);\n function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);\n function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value);\n function envString(string calldata name, string calldata delim) external view returns (string[] memory value);\n function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value);\n // Read environment variables with default value\n function envOr(string calldata name, bool defaultValue) external returns (bool value);\n function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value);\n function envOr(string calldata name, int256 defaultValue) external returns (int256 value);\n function envOr(string calldata name, address defaultValue) external returns (address value);\n function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value);\n function envOr(string calldata name, string calldata defaultValue) external returns (string memory value);\n function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value);\n // Read environment variables as arrays with default value\n function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue)\n external\n returns (bool[] memory value);\n function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue)\n external\n returns (uint256[] memory value);\n function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue)\n external\n returns (int256[] memory value);\n function envOr(string calldata name, string calldata delim, address[] calldata defaultValue)\n external\n returns (address[] memory value);\n function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue)\n external\n returns (bytes32[] memory value);\n function envOr(string calldata name, string calldata delim, string[] calldata defaultValue)\n external\n returns (string[] memory value);\n function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue)\n external\n returns (bytes[] memory value);\n // Records all storage reads and writes\n function record() external;\n // Gets all accessed reads and write slot from a recording session, for a given address\n function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots);\n // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file\n function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode);\n // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file\n function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode);\n // Labels an address in call traces\n function label(address account, string calldata newLabel) external;\n // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain\n function broadcast() external;\n // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain\n function broadcast(address signer) external;\n // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain\n function broadcast(uint256 privateKey) external;\n // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain\n function startBroadcast() external;\n // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain\n function startBroadcast(address signer) external;\n // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain\n function startBroadcast(uint256 privateKey) external;\n // Stops collecting onchain transactions\n function stopBroadcast() external;\n // Reads the entire content of file to string\n function readFile(string calldata path) external view returns (string memory data);\n // Reads the entire content of file as binary. Path is relative to the project root.\n function readFileBinary(string calldata path) external view returns (bytes memory data);\n // Get the path of the current project root\n function projectRoot() external view returns (string memory path);\n // Get the metadata for a file/directory\n function fsMetadata(string calldata fileOrDir) external returns (FsMetadata memory metadata);\n // Reads next line of file to string\n function readLine(string calldata path) external view returns (string memory line);\n // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does.\n function writeFile(string calldata path, string calldata data) external;\n // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does.\n // Path is relative to the project root.\n function writeFileBinary(string calldata path, bytes calldata data) external;\n // Writes line to file, creating a file if it does not exist.\n function writeLine(string calldata path, string calldata data) external;\n // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine.\n function closeFile(string calldata path) external;\n // Removes file. This cheatcode will revert in the following situations, but is not limited to just these cases:\n // - Path points to a directory.\n // - The file doesn't exist.\n // - The user lacks permissions to remove the file.\n function removeFile(string calldata path) external;\n // Convert values to a string\n function toString(address value) external pure returns (string memory stringifiedValue);\n function toString(bytes calldata value) external pure returns (string memory stringifiedValue);\n function toString(bytes32 value) external pure returns (string memory stringifiedValue);\n function toString(bool value) external pure returns (string memory stringifiedValue);\n function toString(uint256 value) external pure returns (string memory stringifiedValue);\n function toString(int256 value) external pure returns (string memory stringifiedValue);\n // Convert values from a string\n function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue);\n function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue);\n function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue);\n function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue);\n function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue);\n function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue);\n // Record all the transaction logs\n function recordLogs() external;\n // Gets all the recorded logs\n function getRecordedLogs() external returns (Log[] memory logs);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index}\n function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index}\n function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index)\n external\n pure\n returns (uint256 privateKey);\n // Adds a private key to the local forge wallet and returns the address\n function rememberKey(uint256 privateKey) external returns (address keyAddr);\n //\n // parseJson\n //\n // ----\n // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects\n // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in\n // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that\n // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded\n // as tuples, with the attributes in the order in which they are defined.\n // For example: json = { 'a': 1, 'b': 0xa4tb......3xs}\n // a: uint256\n // b: address\n // To decode that json, we need to define a struct or a tuple as follows:\n // struct json = { uint256 a; address b; }\n // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to\n // decode the tuple in that order, and thus fail.\n // ----\n // Given a string of JSON, return it as ABI-encoded\n function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData);\n function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData);\n\n // The following parseJson cheatcodes will do type coercion, for the type that they indicate.\n // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12'\n // and hex numbers '0xEF'.\n // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not\n // a JSON object.\n function parseJsonUint(string calldata, string calldata) external returns (uint256);\n function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory);\n function parseJsonInt(string calldata, string calldata) external returns (int256);\n function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory);\n function parseJsonBool(string calldata, string calldata) external returns (bool);\n function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory);\n function parseJsonAddress(string calldata, string calldata) external returns (address);\n function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory);\n function parseJsonString(string calldata, string calldata) external returns (string memory);\n function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory);\n function parseJsonBytes(string calldata, string calldata) external returns (bytes memory);\n function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory);\n function parseJsonBytes32(string calldata, string calldata) external returns (bytes32);\n function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory);\n\n // Serialize a key and value to a JSON object stored in-memory that can be later written to a file\n // It returns the stringified version of the specific JSON file up to that moment.\n function serializeBool(string calldata objectKey, string calldata valueKey, bool value)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256 value)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address value)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string calldata value)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value)\n external\n returns (string memory json);\n\n function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values)\n external\n returns (string memory json);\n\n //\n // writeJson\n //\n // ----\n // Write a serialized JSON object to a file. If the file exists, it will be overwritten.\n // Let's assume we want to write the following JSON to a file:\n //\n // { \"boolean\": true, \"number\": 342, \"object\": { \"title\": \"finally json serialization\" } }\n //\n // ```\n // string memory json1 = \"some key\";\n // vm.serializeBool(json1, \"boolean\", true);\n // vm.serializeBool(json1, \"number\", uint256(342));\n // json2 = \"some other key\";\n // string memory output = vm.serializeString(json2, \"title\", \"finally json serialization\");\n // string memory finalJson = vm.serialize(json1, \"object\", output);\n // vm.writeJson(finalJson, \"./output/example.json\");\n // ```\n // The critical insight is that every invocation of serialization will return the stringified version of the JSON\n // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version\n // to serialize them as values to another JSON object.\n //\n // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..)\n // will find the object in-memory that is keyed by \"some key\".\n function writeJson(string calldata json, string calldata path) external;\n // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = \n // This is useful to replace a specific value of a JSON file, without having to parse the entire thing\n function writeJson(string calldata json, string calldata path, string calldata valueKey) external;\n // Returns the RPC url for the given alias\n function rpcUrl(string calldata rpcAlias) external view returns (string memory json);\n // Returns all rpc urls and their aliases `[alias, url][]`\n function rpcUrls() external view returns (string[2][] memory urls);\n // Returns all rpc urls and their aliases as structs.\n function rpcUrlStructs() external view returns (Rpc[] memory urls);\n // If the condition is false, discard this run's fuzz inputs and generate new ones.\n function assume(bool condition) external pure;\n // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused.\n function pauseGasMetering() external;\n // Resumes gas metering (i.e. gas usage is counted again). Noop if already on.\n function resumeGasMetering() external;\n}\n\ninterface Vm is VmSafe {\n // Sets block.timestamp\n function warp(uint256 newTimestamp) external;\n // Sets block.height\n function roll(uint256 newHeight) external;\n // Sets block.basefee\n function fee(uint256 newBasefee) external;\n // Sets block.difficulty\n function difficulty(uint256 newDifficulty) external;\n // Sets block.chainid\n function chainId(uint256 newChainId) external;\n // Stores a value to an address' storage slot.\n function store(address target, bytes32 slot, bytes32 value) external;\n // Sets the nonce of an account; must be higher than the current nonce of the account\n function setNonce(address account, uint64 newNonce) external;\n // Sets the *next* call's msg.sender to be the input address\n function prank(address msgSender) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called\n function startPrank(address msgSender) external;\n // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input\n function prank(address msgSender, address txOrigin) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input\n function startPrank(address msgSender, address txOrigin) external;\n // Resets subsequent calls' msg.sender to be `address(this)`\n function stopPrank() external;\n // Sets an address' balance\n function deal(address account, uint256 newBalance) external;\n // Sets an address' code\n function etch(address target, bytes calldata newRuntimeBytecode) external;\n // Expects an error on next call\n function expectRevert(bytes calldata revertData) external;\n function expectRevert(bytes4 revertData) external;\n function expectRevert() external;\n\n // Prepare an expected log with all four checks enabled.\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data.\n // Second form also checks supplied address against emitting contract.\n function expectEmit() external;\n function expectEmit(address emitter) external;\n\n // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData).\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data (as specified by the booleans).\n // Second form also checks supplied address against emitting contract.\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external;\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter)\n external;\n\n // Mocks a call to an address, returning specified data.\n // Calldata can either be strict or a partial match, e.g. if you only\n // pass a Solidity selector to the expected calldata, then the entire Solidity\n // function will be mocked.\n function mockCall(address callee, bytes calldata data, bytes calldata returnData) external;\n // Mocks a call to an address with a specific msg.value, returning specified data.\n // Calldata match takes precedence over msg.value in case of ambiguity.\n function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external;\n // Clears all mocked calls\n function clearMockedCalls() external;\n // Expects a call to an address with the specified calldata.\n // Calldata can either be a strict or a partial match\n function expectCall(address callee, bytes calldata data) external;\n // Expects a call to an address with the specified msg.value and calldata\n function expectCall(address callee, uint256 msgValue, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value, gas, and calldata.\n function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas.\n function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other\n // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set.\n function expectSafeMemory(uint64 min, uint64 max) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext.\n // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges\n // to the set.\n function expectSafeMemoryCall(uint64 min, uint64 max) external;\n // Sets block.coinbase\n function coinbase(address newCoinbase) external;\n // Snapshot the current state of the evm.\n // Returns the id of the snapshot that was created.\n // To revert a snapshot use `revertTo`\n function snapshot() external returns (uint256 snapshotId);\n // Revert the state of the EVM to a previous snapshot\n // Takes the snapshot id to revert to.\n // This deletes the snapshot and all snapshots taken after the given snapshot id.\n function revertTo(uint256 snapshotId) external returns (bool success);\n // Creates a new fork with the given endpoint and block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction,\n // and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before\n // the transaction, returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active.\n function selectFork(uint256 forkId) external;\n /// Returns the identifier of the currently active fork. Reverts if no fork is currently active.\n function activeFork() external view returns (uint256 forkId);\n // Updates the currently active fork to given block number\n // This is similar to `roll` but for the currently active fork\n function rollFork(uint256 blockNumber) external;\n // Updates the currently active fork to given transaction\n // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block\n function rollFork(bytes32 txHash) external;\n // Updates the given fork to given block number\n function rollFork(uint256 forkId, uint256 blockNumber) external;\n // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block\n function rollFork(uint256 forkId, bytes32 txHash) external;\n // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup\n // Meaning, changes made to the state of this account will be kept when switching forks\n function makePersistent(address account) external;\n function makePersistent(address account0, address account1) external;\n function makePersistent(address account0, address account1, address account2) external;\n function makePersistent(address[] calldata accounts) external;\n // Revokes persistent status from the address, previously added via `makePersistent`\n function revokePersistent(address account) external;\n function revokePersistent(address[] calldata accounts) external;\n // Returns true if the account is marked as persistent\n function isPersistent(address account) external view returns (bool persistent);\n // In forking mode, explicitly grant the given address cheatcode access\n function allowCheatcodes(address account) external;\n // Fetches the given transaction from the active fork and executes it on the current state\n function transact(bytes32 txHash) external;\n // Fetches the given transaction from the given fork and executes it on the current state\n function transact(uint256 forkId, bytes32 txHash) external;\n}\n" - }, - "node_modules/forge-std/src/console.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n }\n\n function logUint(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n }\n\n function log(uint p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n }\n\n function log(uint p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n }\n\n function log(uint p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n }\n\n function log(string memory p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/console2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\n/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should\n/// use `int256` and `uint256`. This modified version fixes that. This version is recommended\n/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in\n/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`.\n/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178\nlibrary console2 {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function log(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint256 p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n }\n\n function log(uint256 p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n }\n\n function log(uint256 p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n }\n\n function log(uint256 p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n }\n\n function log(string memory p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n }\n\n function log(string memory p0, int256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,int256)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/interfaces/IMulticall3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ninterface IMulticall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint256 value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n function aggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes[] memory returnData);\n\n function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);\n\n function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData);\n\n function blockAndAggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n\n function getBasefee() external view returns (uint256 basefee);\n\n function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash);\n\n function getBlockNumber() external view returns (uint256 blockNumber);\n\n function getChainId() external view returns (uint256 chainid);\n\n function getCurrentBlockCoinbase() external view returns (address coinbase);\n\n function getCurrentBlockDifficulty() external view returns (uint256 difficulty);\n\n function getCurrentBlockGasLimit() external view returns (uint256 gaslimit);\n\n function getCurrentBlockTimestamp() external view returns (uint256 timestamp);\n\n function getEthBalance(address addr) external view returns (uint256 balance);\n\n function getLastBlockHash() external view returns (bytes32 blockHash);\n\n function tryAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (Result[] memory returnData);\n\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n}\n" - } - }, - "settings": { - "remappings": [ - "@openzeppelin/=node_modules/@openzeppelin/", - "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", - "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", - "@rari-capital/=node_modules/@rari-capital/", - "@rari-capital/solmate/=node_modules/@rari-capital/solmate/", - "ds-test/=node_modules/ds-test/src/", - "forge-std/=node_modules/forge-std/src/" - ], - "optimizer": { - "enabled": true, - "runs": 999999 - }, - "metadata": { - "bytecodeHash": "none" - }, - "outputSelection": { - "*": { - "": [ - "ast" - ], - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "storageLayout", - "devdoc", - "userdoc" - ] - } - }, - "evmVersion": "london", - "libraries": {} - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/solcInputs/672fbec9734a08fc34112408d6dc7f7b.json b/packages/contracts-bedrock/deployments/goerli/solcInputs/672fbec9734a08fc34112408d6dc7f7b.json deleted file mode 100644 index 5d4c6cfd35a4..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/solcInputs/672fbec9734a08fc34112408d6dc7f7b.json +++ /dev/null @@ -1,522 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/L1/L1CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismPortal } from \"./OptimismPortal.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1CrossDomainMessenger\n * @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible\n * for sending and receiving data on the L1 side. Users are encouraged to use this\n * interface instead of interacting with lower-level contracts directly.\n */\ncontract L1CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @notice Address of the OptimismPortal.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _portal Address of the OptimismPortal contract on this network.\n */\n constructor(OptimismPortal _portal)\n Semver(1, 0, 0)\n CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER)\n {\n PORTAL = _portal;\n initialize(address(0));\n }\n\n /**\n * @notice Initializer.\n *\n * @param _owner Address of the initial owner of this contract.\n */\n function initialize(address _owner) public initializer {\n __CrossDomainMessenger_init();\n _transferOwnership(_owner);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return msg.sender == address(PORTAL) && PORTAL.l2Sender() == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(PORTAL);\n }\n}\n" - }, - "contracts/L1/L1ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { IERC721 } from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L1ERC721Bridge\n * @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as an escrow for ERC721 tokens deposited into L2.\n */\ncontract L1ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token\n * by ID was deposited for a given L2 token.\n */\n mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 0, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L1ERC721Bridge: local token cannot be self\");\n\n // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.\n require(\n deposits[_localToken][_remoteToken][_tokenId] == true,\n \"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\"\n );\n\n // Mark that the token ID for this L1/L2 token pair is no longer escrowed in the L1\n // Bridge.\n deposits[_localToken][_remoteToken][_tokenId] = false;\n\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the\n // withdrawer.\n IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"ERC721Bridge: remote token cannot be address(0)\");\n\n // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)\n bytes memory message = abi.encodeWithSelector(\n L2ERC721Bridge.finalizeBridgeERC721.selector,\n _remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Lock token into bridge\n deposits[_localToken][_remoteToken][_tokenId] = true;\n IERC721(_localToken).transferFrom(_from, address(this), _tokenId);\n\n // Send calldata into L2\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L1/L1StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1StandardBridge\n * @notice The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L1, it will be escrowed within this\n * contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was\n * stored within this contract. After Bedrock, ETH is instead stored inside the\n * OptimismPortal contract.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L1StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated.\n *\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of ETH deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ETHDepositInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized.\n *\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of ETH withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 withdrawal is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the L1CrossDomainMessenger.\n */\n constructor(address payable _messenger)\n Semver(1, 0, 0)\n StandardBridge(_messenger, payable(Predeploys.L2_STANDARD_BRIDGE))\n {}\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ERC20 tokens from L2.\n *\n * @param _l1Token Address of the token on L1.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of the ERC20 to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeERC20Withdrawal(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n emit ERC20WithdrawalFinalized(_l1Token, _l2Token, _from, _to, _amount, _extraData);\n finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into the sender's account on L2.\n *\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETH(uint32 _minGasLimit, bytes calldata _extraData) external payable onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into a target account on L2.\n * Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will\n * be locked in the L2StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n *\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable {\n _initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into the sender's account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20(\n address _l1Token,\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual onlyEOA {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into a target account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20To(\n address _l1Token,\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ETH from L2.\n *\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of ETH to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeETHWithdrawal(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable onlyOtherBridge {\n emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData);\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L2 bridge contract.\n *\n * @return Address of the corresponding L2 bridge contract.\n */\n function l2TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @notice Internal function for initiating an ETH deposit.\n *\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateETHDeposit(\n address _from,\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal {\n emit ETHDepositInitiated(_from, _to, msg.value, _extraData);\n _initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Internal function for initiating an ERC20 deposit.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateERC20Deposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal {\n emit ERC20DepositInitiated(_l1Token, _l2Token, _from, _to, _amount, _extraData);\n _initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n}\n" - }, - "contracts/L1/L2OutputOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\n/**\n * @custom:proxied\n * @title L2OutputOracle\n * @notice The L2OutputOracle contains an array of L2 state outputs, where each output is a\n * commitment to the state of the L2 chain. Other contracts like the OptimismPortal use\n * these outputs to verify information about the state of L2.\n */\ncontract L2OutputOracle is Initializable, Semver {\n /**\n * @notice The interval in L2 blocks at which checkpoints must be submitted. Although this is\n * immutable, it can safely be modified by upgrading the implementation contract.\n */\n uint256 public immutable SUBMISSION_INTERVAL;\n\n /**\n * @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified.\n */\n uint256 public immutable L2_BLOCK_TIME;\n\n /**\n * @notice The address of the challenger. Can be updated via upgrade.\n */\n address public immutable CHALLENGER;\n\n /**\n * @notice The address of the proposer. Can be updated via upgrade.\n */\n address public immutable PROPOSER;\n\n /**\n * @notice The number of the first L2 block recorded in this contract.\n */\n uint256 public startingBlockNumber;\n\n /**\n * @notice The timestamp of the first L2 block recorded in this contract.\n */\n uint256 public startingTimestamp;\n\n /**\n * @notice Array of L2 output proposals.\n */\n Types.OutputProposal[] internal l2Outputs;\n\n /**\n * @notice Emitted when an output is proposed.\n *\n * @param outputRoot The output root.\n * @param l2OutputIndex The index of the output in the l2Outputs array.\n * @param l2BlockNumber The L2 block number of the output root.\n * @param l1Timestamp The L1 timestamp when proposed.\n */\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n /**\n * @notice Emitted when outputs are deleted.\n *\n * @param prevNextOutputIndex Next L2 output index before the deletion.\n * @param newNextOutputIndex Next L2 output index after the deletion.\n */\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _submissionInterval Interval in blocks at which checkpoints must be submitted.\n * @param _l2BlockTime The time per L2 block, in seconds.\n * @param _startingBlockNumber The number of the first L2 block.\n * @param _startingTimestamp The timestamp of the first L2 block.\n * @param _proposer The address of the proposer.\n * @param _challenger The address of the challenger.\n */\n constructor(\n uint256 _submissionInterval,\n uint256 _l2BlockTime,\n uint256 _startingBlockNumber,\n uint256 _startingTimestamp,\n address _proposer,\n address _challenger\n ) Semver(1, 0, 0) {\n SUBMISSION_INTERVAL = _submissionInterval;\n L2_BLOCK_TIME = _l2BlockTime;\n PROPOSER = _proposer;\n CHALLENGER = _challenger;\n\n initialize(_startingBlockNumber, _startingTimestamp);\n }\n\n /**\n * @notice Initializer.\n *\n * @param _startingBlockNumber Block number for the first recoded L2 block.\n * @param _startingTimestamp Timestamp for the first recoded L2 block.\n */\n function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp)\n public\n initializer\n {\n require(\n _startingTimestamp <= block.timestamp,\n \"L2OutputOracle: starting L2 timestamp must be less than current time\"\n );\n\n startingTimestamp = _startingTimestamp;\n startingBlockNumber = _startingBlockNumber;\n }\n\n /**\n * @notice Deletes all output proposals after and including the proposal that corresponds to\n * the given output index. Only the challenger address can delete outputs.\n *\n * @param _l2OutputIndex Index of the first L2 output to be deleted. All outputs after this\n * output will also be deleted.\n */\n // solhint-disable-next-line ordering\n function deleteL2Outputs(uint256 _l2OutputIndex) external {\n require(\n msg.sender == CHALLENGER,\n \"L2OutputOracle: only the challenger address can delete outputs\"\n );\n\n // Make sure we're not *increasing* the length of the array.\n require(\n _l2OutputIndex < l2Outputs.length,\n \"L2OutputOracle: cannot delete outputs after the latest output index\"\n );\n\n uint256 prevNextL2OutputIndex = nextOutputIndex();\n\n // Use assembly to delete the array elements because Solidity doesn't allow it.\n assembly {\n sstore(l2Outputs.slot, _l2OutputIndex)\n }\n\n emit OutputsDeleted(prevNextL2OutputIndex, _l2OutputIndex);\n }\n\n /**\n * @notice Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp\n * must be equal to the current value returned by `nextTimestamp()` in order to be\n * accepted. This function may only be called by the Proposer.\n *\n * @param _outputRoot The L2 output of the checkpoint block.\n * @param _l2BlockNumber The L2 block number that resulted in _outputRoot.\n * @param _l1BlockHash A block hash which must be included in the current chain.\n * @param _l1BlockNumber The block number with the specified block hash.\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external payable {\n require(\n msg.sender == PROPOSER,\n \"L2OutputOracle: only the proposer address can propose new outputs\"\n );\n\n require(\n _l2BlockNumber == nextBlockNumber(),\n \"L2OutputOracle: block number must be equal to next expected block number\"\n );\n\n require(\n computeL2Timestamp(_l2BlockNumber) < block.timestamp,\n \"L2OutputOracle: cannot propose L2 output in the future\"\n );\n\n require(\n _outputRoot != bytes32(0),\n \"L2OutputOracle: L2 output proposal cannot be the zero hash\"\n );\n\n if (_l1BlockHash != bytes32(0)) {\n // This check allows the proposer to propose an output based on a given L1 block,\n // without fear that it will be reorged out.\n // It will also revert if the blockheight provided is more than 256 blocks behind the\n // chain tip (as the hash will return as zero). This does open the door to a griefing\n // attack in which the proposer's submission is censored until the block is no longer\n // retrievable, if the proposer is experiencing this attack it can simply leave out the\n // blockhash value, and delay submission until it is confident that the L1 block is\n // finalized.\n require(\n blockhash(_l1BlockNumber) == _l1BlockHash,\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n }\n\n emit OutputProposed(_outputRoot, nextOutputIndex(), _l2BlockNumber, block.timestamp);\n\n l2Outputs.push(\n Types.OutputProposal({\n outputRoot: _outputRoot,\n timestamp: uint128(block.timestamp),\n l2BlockNumber: uint128(_l2BlockNumber)\n })\n );\n }\n\n /**\n * @notice Returns an output by index. Exists because Solidity's array access will return a\n * tuple instead of a struct.\n *\n * @param _l2OutputIndex Index of the output to return.\n *\n * @return The output at the given index.\n */\n function getL2Output(uint256 _l2OutputIndex)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[_l2OutputIndex];\n }\n\n /**\n * @notice Returns the index of the L2 output that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return Index of the first checkpoint that commits to the given L2 block number.\n */\n function getL2OutputIndexAfter(uint256 _l2BlockNumber) public view returns (uint256) {\n // Make sure an output for this block number has actually been proposed.\n require(\n _l2BlockNumber <= latestBlockNumber(),\n \"L2OutputOracle: cannot get output for a block that has not been proposed\"\n );\n\n // Make sure there's at least one output proposed.\n require(\n l2Outputs.length > 0,\n \"L2OutputOracle: cannot get output as no outputs have been proposed yet\"\n );\n\n // Find the output via binary search, guaranteed to exist.\n uint256 lo = 0;\n uint256 hi = l2Outputs.length;\n while (lo < hi) {\n uint256 mid = (lo + hi) / 2;\n if (l2Outputs[mid].l2BlockNumber < _l2BlockNumber) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n return lo;\n }\n\n /**\n * @notice Returns the L2 output proposal that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return First checkpoint that commits to the given L2 block number.\n */\n function getL2OutputAfter(uint256 _l2BlockNumber)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)];\n }\n\n /**\n * @notice Returns the number of outputs that have been proposed. Will revert if no outputs\n * have been proposed yet.\n *\n * @return The number of outputs that have been proposed.\n */\n function latestOutputIndex() external view returns (uint256) {\n return l2Outputs.length - 1;\n }\n\n /**\n * @notice Returns the index of the next output to be proposed.\n *\n * @return The index of the next output to be proposed.\n */\n function nextOutputIndex() public view returns (uint256) {\n return l2Outputs.length;\n }\n\n /**\n * @notice Returns the block number of the latest submitted L2 output proposal. If no proposals\n * been submitted yet then this function will return the starting block number.\n *\n * @return Latest submitted L2 block number.\n */\n function latestBlockNumber() public view returns (uint256) {\n return\n l2Outputs.length == 0\n ? startingBlockNumber\n : l2Outputs[l2Outputs.length - 1].l2BlockNumber;\n }\n\n /**\n * @notice Computes the block number of the next L2 block that needs to be checkpointed.\n *\n * @return Next L2 block number.\n */\n function nextBlockNumber() public view returns (uint256) {\n return latestBlockNumber() + SUBMISSION_INTERVAL;\n }\n\n /**\n * @notice Returns the L2 timestamp corresponding to a given L2 block number.\n *\n * @param _l2BlockNumber The L2 block number of the target block.\n *\n * @return L2 timestamp of the given block.\n */\n function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {\n return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME);\n }\n}\n" - }, - "contracts/L1/OptimismPortal.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { L2OutputOracle } from \"./L2OutputOracle.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { SecureMerkleTrie } from \"../libraries/trie/SecureMerkleTrie.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title OptimismPortal\n * @notice The OptimismPortal is a low-level contract responsible for passing messages between L1\n * and L2. Messages sent directly to the OptimismPortal have no form of replayability.\n * Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface.\n */\ncontract OptimismPortal is Initializable, ResourceMetering, Semver {\n /**\n * @notice Represents a proven withdrawal.\n *\n * @custom:field outputRoot Root of the L2 output this was proven against.\n * @custom:field timestamp Timestamp at whcih the withdrawal was proven.\n * @custom:field l2OutputIndex Index of the output this was proven against.\n */\n struct ProvenWithdrawal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2OutputIndex;\n }\n\n /**\n * @notice Version of the deposit event.\n */\n uint256 internal constant DEPOSIT_VERSION = 0;\n\n /**\n * @notice The L2 gas limit set when eth is deposited using the receive() function.\n */\n uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Additional gas reserved for clean up after finalizing a transaction withdrawal.\n */\n uint256 internal constant FINALIZE_GAS_BUFFER = 20_000;\n\n /**\n * @notice Minimum time (in seconds) that must elapse before a withdrawal can be finalized.\n */\n uint256 public immutable FINALIZATION_PERIOD_SECONDS;\n\n /**\n * @notice Address of the L2OutputOracle.\n */\n L2OutputOracle public immutable L2_ORACLE;\n\n /**\n * @notice Address of the L2 account which initiated a withdrawal in this transaction. If the\n * of this variable is the default L2 sender address, then we are NOT inside of a call\n * to finalizeWithdrawalTransaction.\n */\n address public l2Sender;\n\n /**\n * @notice A list of withdrawal hashes which have been successfully finalized.\n */\n mapping(bytes32 => bool) public finalizedWithdrawals;\n\n /**\n * @notice A mapping of withdrawal hashes to `ProvenWithdrawal` data.\n */\n mapping(bytes32 => ProvenWithdrawal) public provenWithdrawals;\n\n /**\n * @notice Emitted when a transaction is deposited from L1 to L2. The parameters of this event\n * are read by the rollup node and used to derive deposit transactions on L2.\n *\n * @param from Address that triggered the deposit transaction.\n * @param to Address that the deposit transaction is directed to.\n * @param version Version of this deposit transaction event.\n * @param opaqueData ABI encoded deposit data to be parsed off-chain.\n */\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is proven.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n */\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is finalized.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n * @param success Whether the withdrawal transaction was successful.\n */\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _l2Oracle Address of the L2OutputOracle contract.\n * @param _finalizationPeriodSeconds Output finalization time in seconds.\n */\n constructor(L2OutputOracle _l2Oracle, uint256 _finalizationPeriodSeconds) Semver(1, 0, 0) {\n L2_ORACLE = _l2Oracle;\n FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n l2Sender = Constants.DEFAULT_L2_SENDER;\n __ResourceMetering_init();\n }\n\n /**\n * @notice Accepts value so that users can send ETH directly to this contract and have the\n * funds be deposited to their address on L2. This is intended as a convenience\n * function for EOAs. Contracts should call the depositTransaction() function directly\n * otherwise any deposited funds will be lost due to address aliasing.\n */\n // solhint-disable-next-line ordering\n receive() external payable {\n depositTransaction(msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes(\"\"));\n }\n\n /**\n * @notice Accepts ETH value without triggering a deposit to L2. This function mainly exists\n * for the sake of the migration between the legacy Optimism system and Bedrock.\n */\n function donateETH() external payable {\n // Intentionally empty.\n }\n\n /**\n * @notice Proves a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n * @param _l2OutputIndex L2 output index to prove against.\n * @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root.\n * @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\n */\n function proveWithdrawalTransaction(\n Types.WithdrawalTransaction memory _tx,\n uint256 _l2OutputIndex,\n Types.OutputRootProof calldata _outputRootProof,\n bytes[] calldata _withdrawalProof\n ) external {\n // Prevent users from creating a deposit transaction where this address is the message\n // sender on L2. Because this is checked here, we do not need to check again in\n // `finalizeWithdrawalTransaction`.\n require(\n _tx.target != address(this),\n \"OptimismPortal: you cannot send messages to the portal contract\"\n );\n\n // Get the output root and load onto the stack to prevent multiple mloads. This will\n // revert if there is no output root for the given block number.\n bytes32 outputRoot = L2_ORACLE.getL2Output(_l2OutputIndex).outputRoot;\n\n // Verify that the output root can be generated with the elements in the proof.\n require(\n outputRoot == Hashing.hashOutputRootProof(_outputRootProof),\n \"OptimismPortal: invalid output root proof\"\n );\n\n // Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // We generally want to prevent users from proving the same withdrawal multiple times\n // because each successive proof will update the timestamp. A malicious user can take\n // advantage of this to prevent other users from finalizing their withdrawal. However,\n // since withdrawals are proven before an output root is finalized, we need to allow users\n // to re-prove their withdrawal only in the case that the output root for their specified\n // output index has been updated.\n require(\n provenWithdrawal.timestamp == 0 ||\n (_l2OutputIndex == provenWithdrawal.l2OutputIndex &&\n outputRoot != provenWithdrawal.outputRoot),\n \"OptimismPortal: withdrawal hash has already been proven\"\n );\n\n // Compute the storage slot of the withdrawal hash in the L2ToL1MessagePasser contract.\n // Refer to the Solidity documentation for more information on how storage layouts are\n // computed for mappings.\n bytes32 storageKey = keccak256(\n abi.encode(\n withdrawalHash,\n uint256(0) // The withdrawals mapping is at the first slot in the layout.\n )\n );\n\n // Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract\n // on L2. If this is true, under the assumption that the SecureMerkleTrie does not have\n // bugs, then we know that this withdrawal was actually triggered on L2 and can therefore\n // be relayed on L1.\n require(\n SecureMerkleTrie.verifyInclusionProof(\n abi.encode(storageKey),\n hex\"01\",\n _withdrawalProof,\n _outputRootProof.messagePasserStorageRoot\n ),\n \"OptimismPortal: invalid withdrawal inclusion proof\"\n );\n\n // Designate the withdrawalHash as proven by storing the `outputRoot`, `timestamp`, and\n // `l2BlockNumber` in the `provenWithdrawals` mapping. A `withdrawalHash` can only be\n // proven once unless it is submitted again with a different outputRoot.\n provenWithdrawals[withdrawalHash] = ProvenWithdrawal({\n outputRoot: outputRoot,\n timestamp: uint128(block.timestamp),\n l2OutputIndex: uint128(_l2OutputIndex)\n });\n\n // Emit a `WithdrawalProven` event.\n emit WithdrawalProven(withdrawalHash, _tx.sender, _tx.target);\n }\n\n /**\n * @notice Finalizes a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n */\n function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx) external {\n // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other\n // than the default value when a withdrawal transaction is being finalized. This check is\n // a defacto reentrancy guard.\n require(\n l2Sender == Constants.DEFAULT_L2_SENDER,\n \"OptimismPortal: can only trigger one withdrawal per transaction\"\n );\n\n // Grab the proven withdrawal from the `provenWithdrawals` map.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // A withdrawal can only be finalized if it has been proven. We know that a withdrawal has\n // been proven at least once when its timestamp is non-zero. Unproven withdrawals will have\n // a timestamp of zero.\n require(\n provenWithdrawal.timestamp != 0,\n \"OptimismPortal: withdrawal has not been proven yet\"\n );\n\n // As a sanity check, we make sure that the proven withdrawal's timestamp is greater than\n // starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of\n // safety against weird bugs in the proving step.\n require(\n provenWithdrawal.timestamp >= L2_ORACLE.startingTimestamp(),\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n\n // A proven withdrawal must wait at least the finalization period before it can be\n // finalized. This waiting period can elapse in parallel with the waiting period for the\n // output the withdrawal was proven against. In effect, this means that the minimum\n // withdrawal time is proposal submission time + finalization period.\n require(\n _isFinalizationPeriodElapsed(provenWithdrawal.timestamp),\n \"OptimismPortal: proven withdrawal finalization period has not elapsed\"\n );\n\n // Grab the OutputProposal from the L2OutputOracle, will revert if the output that\n // corresponds to the given index has not been proposed yet.\n Types.OutputProposal memory proposal = L2_ORACLE.getL2Output(\n provenWithdrawal.l2OutputIndex\n );\n\n // Check that the output root that was used to prove the withdrawal is the same as the\n // current output root for the given output index. An output root may change if it is\n // deleted by the challenger address and then re-proposed.\n require(\n proposal.outputRoot == provenWithdrawal.outputRoot,\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n\n // Check that the output proposal has also been finalized.\n require(\n _isFinalizationPeriodElapsed(proposal.timestamp),\n \"OptimismPortal: output proposal finalization period has not elapsed\"\n );\n\n // Check that this withdrawal has not already been finalized, this is replay protection.\n require(\n finalizedWithdrawals[withdrawalHash] == false,\n \"OptimismPortal: withdrawal has already been finalized\"\n );\n\n // Mark the withdrawal as finalized so it can't be replayed.\n finalizedWithdrawals[withdrawalHash] = true;\n\n // We want to maintain the property that the amount of gas supplied to the call to the\n // target contract is at least the gas limit specified by the user. We can do this by\n // enforcing that, at this point in time, we still have gaslimit + buffer gas available.\n require(\n gasleft() >= _tx.gasLimit + FINALIZE_GAS_BUFFER,\n \"OptimismPortal: insufficient gas to finalize withdrawal\"\n );\n\n // Set the l2Sender so contracts know who triggered this withdrawal on L2.\n l2Sender = _tx.sender;\n\n // Trigger the call to the target contract. We use SafeCall because we don't\n // care about the returndata and we don't want target contracts to be able to force this\n // call to run out of gas via a returndata bomb.\n bool success = SafeCall.call(\n _tx.target,\n gasleft() - FINALIZE_GAS_BUFFER,\n _tx.value,\n _tx.data\n );\n\n // Reset the l2Sender back to the default value.\n l2Sender = Constants.DEFAULT_L2_SENDER;\n\n // All withdrawals are immediately finalized. Replayability can\n // be achieved through contracts built on top of this contract\n emit WithdrawalFinalized(withdrawalHash, success);\n\n // Reverting here is useful for determining the exact gas cost to successfully execute the\n // sub call to the target contract if the minimum gas limit specified by the user would not\n // be sufficient to execute the sub call.\n if (success == false && tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"OptimismPortal: withdrawal failed\");\n }\n }\n\n /**\n * @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in\n * deriving deposit transactions. Note that if a deposit is made by a contract, its\n * address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider\n * using the CrossDomainMessenger contracts for a simpler developer experience.\n *\n * @param _to Target address on L2.\n * @param _value ETH value to send to the recipient.\n * @param _gasLimit Minimum L2 gas limit (can be greater than or equal to this value).\n * @param _isCreation Whether or not the transaction is a contract creation.\n * @param _data Data to trigger the recipient with.\n */\n function depositTransaction(\n address _to,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable metered(_gasLimit) {\n // Just to be safe, make sure that people specify address(0) as the target when doing\n // contract creations.\n if (_isCreation) {\n require(\n _to == address(0),\n \"OptimismPortal: must send to address(0) when creating a contract\"\n );\n }\n\n // Transform the from-address to its alias if the caller is a contract.\n address from = msg.sender;\n if (msg.sender != tx.origin) {\n from = AddressAliasHelper.applyL1ToL2Alias(msg.sender);\n }\n\n // Compute the opaque data that will be emitted as part of the TransactionDeposited event.\n // We use opaque data so that we can update the TransactionDeposited event in the future\n // without breaking the current interface.\n bytes memory opaqueData = abi.encodePacked(\n msg.value,\n _value,\n _gasLimit,\n _isCreation,\n _data\n );\n\n // Emit a TransactionDeposited event so that the rollup node can derive a deposit\n // transaction for this deposit.\n emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);\n }\n\n /**\n * @notice Determine if a given output is finalized. Reverts if the call to\n * L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\n *\n * @param _l2OutputIndex Index of the L2 output to check.\n *\n * @return Whether or not the output is finalized.\n */\n function isOutputFinalized(uint256 _l2OutputIndex) external view returns (bool) {\n return _isFinalizationPeriodElapsed(L2_ORACLE.getL2Output(_l2OutputIndex).timestamp);\n }\n\n /**\n * @notice Determines whether the finalization period has elapsed w/r/t a given timestamp.\n *\n * @param _timestamp Timestamp to check.\n *\n * @return Whether or not the finalization period has elapsed.\n */\n function _isFinalizationPeriodElapsed(uint256 _timestamp) internal view returns (bool) {\n return block.timestamp > _timestamp + FINALIZATION_PERIOD_SECONDS;\n }\n}\n" - }, - "contracts/L1/ResourceMetering.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\n\n/**\n * @custom:upgradeable\n * @title ResourceMetering\n * @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing\n * updates automatically based on current demand.\n */\nabstract contract ResourceMetering is Initializable {\n /**\n * @notice Represents the various parameters that control the way in which resources are\n * metered. Corresponds to the EIP-1559 resource metering system.\n *\n * @custom:field prevBaseFee Base fee from the previous block(s).\n * @custom:field prevBoughtGas Amount of gas bought so far in the current block.\n * @custom:field prevBlockNum Last block number that the base fee was updated.\n */\n struct ResourceParams {\n uint128 prevBaseFee;\n uint64 prevBoughtGas;\n uint64 prevBlockNum;\n }\n\n /**\n * @notice Maximum amount of the resource that can be used within this block.\n */\n int256 public constant MAX_RESOURCE_LIMIT = 8_000_000;\n\n /**\n * @notice Along with the resource limit, determines the target resource limit.\n */\n int256 public constant ELASTICITY_MULTIPLIER = 4;\n\n /**\n * @notice Target amount of the resource that should be used within this block.\n */\n int256 public constant TARGET_RESOURCE_LIMIT = MAX_RESOURCE_LIMIT / ELASTICITY_MULTIPLIER;\n\n /**\n * @notice Denominator that determines max change on fee per block.\n */\n int256 public constant BASE_FEE_MAX_CHANGE_DENOMINATOR = 8;\n\n /**\n * @notice Minimum base fee value, cannot go lower than this.\n */\n int256 public constant MINIMUM_BASE_FEE = 10_000;\n\n /**\n * @notice Maximum base fee value, cannot go higher than this.\n */\n int256 public constant MAXIMUM_BASE_FEE = int256(uint256(type(uint128).max));\n\n /**\n * @notice Initial base fee value.\n */\n uint128 public constant INITIAL_BASE_FEE = 1_000_000_000;\n\n /**\n * @notice EIP-1559 style gas parameters.\n */\n ResourceParams public params;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[48] private __gap;\n\n /**\n * @notice Meters access to a function based an amount of a requested resource.\n *\n * @param _amount Amount of the resource requested.\n */\n modifier metered(uint64 _amount) {\n // Record initial gas amount so we can refund for it later.\n uint256 initialGas = gasleft();\n\n // Run the underlying function.\n _;\n\n // Update block number and base fee if necessary.\n uint256 blockDiff = block.number - params.prevBlockNum;\n if (blockDiff > 0) {\n // Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate\n // at which deposits can be created and therefore limit the potential for deposits to\n // spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.\n int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - TARGET_RESOURCE_LIMIT;\n int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) /\n TARGET_RESOURCE_LIMIT /\n BASE_FEE_MAX_CHANGE_DENOMINATOR;\n\n // Update base fee by adding the base fee delta and clamp the resulting value between\n // min and max.\n int256 newBaseFee = Arithmetic.clamp(\n int256(uint256(params.prevBaseFee)) + baseFeeDelta,\n MINIMUM_BASE_FEE,\n MAXIMUM_BASE_FEE\n );\n\n // If we skipped more than one block, we also need to account for every empty block.\n // Empty block means there was no demand for deposits in that block, so we should\n // reflect this lack of demand in the fee.\n if (blockDiff > 1) {\n // Update the base fee by repeatedly applying the exponent 1-(1/change_denominator)\n // blockDiff - 1 times. Simulates multiple empty blocks. Clamp the resulting value\n // between min and max.\n newBaseFee = Arithmetic.clamp(\n Arithmetic.cdexp(\n newBaseFee,\n BASE_FEE_MAX_CHANGE_DENOMINATOR,\n int256(blockDiff - 1)\n ),\n MINIMUM_BASE_FEE,\n MAXIMUM_BASE_FEE\n );\n }\n\n // Update new base fee, reset bought gas, and update block number.\n params.prevBaseFee = uint128(uint256(newBaseFee));\n params.prevBoughtGas = 0;\n params.prevBlockNum = uint64(block.number);\n }\n\n // Make sure we can actually buy the resource amount requested by the user.\n params.prevBoughtGas += _amount;\n require(\n int256(uint256(params.prevBoughtGas)) <= MAX_RESOURCE_LIMIT,\n \"ResourceMetering: cannot buy more gas than available gas limit\"\n );\n\n // Determine the amount of ETH to be paid.\n uint256 resourceCost = _amount * params.prevBaseFee;\n\n // We currently charge for this ETH amount as an L1 gas burn, so we convert the ETH amount\n // into gas by dividing by the L1 base fee. We assume a minimum base fee of 1 gwei to avoid\n // division by zero for L1s that don't support 1559 or to avoid excessive gas burns during\n // periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei\n // during any 1 day period in the last 5 years, so should be fine.\n uint256 gasCost = resourceCost / Math.max(block.basefee, 1000000000);\n\n // Give the user a refund based on the amount of gas they used to do all of the work up to\n // this point. Since we're at the end of the modifier, this should be pretty accurate. Acts\n // effectively like a dynamic stipend (with a minimum value).\n uint256 usedGas = initialGas - gasleft();\n if (gasCost > usedGas) {\n Burn.gas(gasCost - usedGas);\n }\n }\n\n /**\n * @notice Sets initial resource parameter values. This function must either be called by the\n * initializer function of an upgradeable child contract.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __ResourceMetering_init() internal onlyInitializing {\n params = ResourceParams({\n prevBaseFee: INITIAL_BASE_FEE,\n prevBoughtGas: 0,\n prevBlockNum: uint64(block.number)\n });\n }\n}\n" - }, - "contracts/L1/SystemConfig.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title SystemConfig\n * @notice The SystemConfig contract is used to manage configuration of an Optimism network. All\n * configuration is stored on L1 and picked up by L2 as part of the derviation of the L2\n * chain.\n */\ncontract SystemConfig is OwnableUpgradeable, Semver {\n /**\n * @notice Enum representing different types of updates.\n *\n * @custom:value BATCHER Represents an update to the batcher hash.\n * @custom:value GAS_CONFIG Represents an update to txn fee config on L2.\n * @custom:value GAS_LIMIT Represents an update to gas limit on L2.\n * @custom:value UNSAFE_BLOCK_SIGNER Represents an update to the signer key for unsafe\n * block distrubution.\n */\n enum UpdateType {\n BATCHER,\n GAS_CONFIG,\n GAS_LIMIT,\n UNSAFE_BLOCK_SIGNER\n }\n\n /**\n * @notice Version identifier, used for upgrades.\n */\n uint256 public constant VERSION = 0;\n\n /**\n * @notice Storage slot that the unsafe block signer is stored at. Storing it at this\n * deterministic storage slot allows for decoupling the storage layout from the way\n * that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value.\n */\n bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256(\"systemconfig.unsafeblocksigner\");\n\n /**\n * @notice Minimum gas limit. This should not be lower than the maximum deposit gas resource\n * limit in the ResourceMetering contract used by OptimismPortal, to ensure the L2\n * block always has sufficient gas to process deposits.\n */\n uint64 public constant MINIMUM_GAS_LIMIT = 8_000_000;\n\n /**\n * @notice Fixed L2 gas overhead.\n */\n uint256 public overhead;\n\n /**\n * @notice Dynamic L2 gas overhead.\n */\n uint256 public scalar;\n\n /**\n * @notice Identifier for the batcher. For version 1 of this configuration, this is represented\n * as an address left-padded with zeros to 32 bytes.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice L2 gas limit.\n */\n uint64 public gasLimit;\n\n /**\n * @notice Emitted when configuration is updated\n *\n * @param version SystemConfig version.\n * @param updateType Type of update.\n * @param data Encoded update data.\n */\n event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n */\n constructor(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner\n ) Semver(1, 0, 0) {\n initialize(_owner, _overhead, _scalar, _batcherHash, _gasLimit, _unsafeBlockSigner);\n }\n\n /**\n * @notice Initializer.\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n */\n function initialize(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner\n ) public initializer {\n require(_gasLimit >= MINIMUM_GAS_LIMIT, \"SystemConfig: gas limit too low\");\n __Ownable_init();\n transferOwnership(_owner);\n overhead = _overhead;\n scalar = _scalar;\n batcherHash = _batcherHash;\n gasLimit = _gasLimit;\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n }\n\n /**\n * @notice High level getter for the unsafe block signer address.\n * Unsafe blocks can be propagated across the p2p network\n * if they are signed by the key corresponding to this address.\n */\n function unsafeBlockSigner() public view returns (address) {\n address addr;\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n addr := sload(slot)\n }\n return addr;\n }\n\n /**\n * @notice Updates the batcher hash.\n *\n * @param _batcherHash New batcher hash.\n */\n // solhint-disable-next-line ordering\n function setBatcherHash(bytes32 _batcherHash) external onlyOwner {\n batcherHash = _batcherHash;\n\n bytes memory data = abi.encode(_batcherHash);\n emit ConfigUpdate(VERSION, UpdateType.BATCHER, data);\n }\n\n /**\n * @notice Updates gas config.\n *\n * @param _overhead New overhead value.\n * @param _scalar New scalar value.\n */\n function setGasConfig(uint256 _overhead, uint256 _scalar) external onlyOwner {\n overhead = _overhead;\n scalar = _scalar;\n\n bytes memory data = abi.encode(_overhead, _scalar);\n emit ConfigUpdate(VERSION, UpdateType.GAS_CONFIG, data);\n }\n\n function setUnsafeBlockSigner(address _unsafeBlockSigner) external onlyOwner {\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n\n bytes memory data = abi.encode(_unsafeBlockSigner);\n emit ConfigUpdate(VERSION, UpdateType.UNSAFE_BLOCK_SIGNER, data);\n }\n\n /**\n * @notice Low level setter for the unsafe block signer address.\n * This function exists to deduplicate code around storing\n * the unsafeBlockSigner address in storage.\n *\n * @param _unsafeBlockSigner New unsafeBlockSigner value\n */\n function _setUnsafeBlockSigner(address _unsafeBlockSigner) internal {\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n sstore(slot, _unsafeBlockSigner)\n }\n }\n\n /**\n * @notice Updates the L2 gas limit.\n *\n * @param _gasLimit New gas limit.\n */\n function setGasLimit(uint64 _gasLimit) external onlyOwner {\n require(_gasLimit >= MINIMUM_GAS_LIMIT, \"SystemConfig: gas limit too low\");\n gasLimit = _gasLimit;\n\n bytes memory data = abi.encode(_gasLimit);\n emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data);\n }\n}\n" - }, - "contracts/L2/BaseFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000019\n * @title BaseFeeVault\n * @notice The BaseFeeVault accumulates the base fee that is paid by transactions.\n */\ncontract BaseFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 0, 0) {}\n}\n" - }, - "contracts/L2/CrossDomainOwnable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\n/**\n * @title CrossDomainOwnable\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is only safe to be used if the\n * CrossDomainMessenger system is bypassed and the caller on L1 is calling the\n * OptimismPortal directly.\n */\nabstract contract CrossDomainOwnable is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `msg.sender` is the owner of the contract.\n */\n function _checkOwner() internal view override {\n require(\n owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender),\n \"CrossDomainOwnable: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable2\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is meant to be used with systems that use\n * the CrossDomainMessenger system. It will not work if the OptimismPortal is used\n * directly.\n */\nabstract contract CrossDomainOwnable2 is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable2: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable2: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/GasPriceOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000000F\n * @title GasPriceOracle\n * @notice This contract maintains the variables responsible for computing the L1 portion of the\n * total fee charged on L2. Before Bedrock, this contract held variables in state that were\n * read during the state transition function to compute the L1 portion of the transaction\n * fee. After Bedrock, this contract now simply proxies the L1Block contract, which has\n * the values used to compute the L1 portion of the fee in its state.\n *\n * The contract exposes an API that is useful for knowing how large the L1 portion of the\n * transaction fee will be. The following events were deprecated with Bedrock:\n * - event OverheadUpdated(uint256 overhead);\n * - event ScalarUpdated(uint256 scalar);\n * - event DecimalsUpdated(uint256 decimals);\n */\ncontract GasPriceOracle is Semver {\n /**\n * @notice Number of decimals used in the scalar.\n */\n uint256 public constant DECIMALS = 6;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Computes the L1 portion of the fee based on the size of the rlp encoded input\n * transaction, the current L1 base fee, and the various dynamic parameters.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.\n *\n * @return L1 fee that should be paid for the tx\n */\n function getL1Fee(bytes memory _data) external view returns (uint256) {\n uint256 l1GasUsed = getL1GasUsed(_data);\n uint256 l1Fee = l1GasUsed * l1BaseFee();\n uint256 divisor = 10**DECIMALS;\n uint256 unscaled = l1Fee * scalar();\n uint256 scaled = unscaled / divisor;\n return scaled;\n }\n\n /**\n * @notice Retrieves the current gas price (base fee).\n *\n * @return Current L2 gas price (base fee).\n */\n function gasPrice() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current base fee.\n *\n * @return Current L2 base fee.\n */\n function baseFee() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current fee overhead.\n *\n * @return Current fee overhead.\n */\n function overhead() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead();\n }\n\n /**\n * @notice Retrieves the current fee scalar.\n *\n * @return Current fee scalar.\n */\n function scalar() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar();\n }\n\n /**\n * @notice Retrieves the latest known L1 base fee.\n *\n * @return Latest known L1 base fee.\n */\n function l1BaseFee() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee();\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the number of decimals used in the scalar.\n *\n * @return Number of decimals used in the scalar.\n */\n function decimals() public pure returns (uint256) {\n return DECIMALS;\n }\n\n /**\n * @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which\n * represents the per-transaction gas overhead of posting the transaction and state\n * roots to L1. Adds 68 bytes of padding to account for the fact that the input does\n * not have a signature.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for.\n *\n * @return Amount of L1 gas used to publish the transaction.\n */\n function getL1GasUsed(bytes memory _data) public view returns (uint256) {\n uint256 total = 0;\n uint256 length = _data.length;\n for (uint256 i = 0; i < length; i++) {\n if (_data[i] == 0) {\n total += 4;\n } else {\n total += 16;\n }\n }\n uint256 unsigned = total + overhead();\n return unsigned + (68 * 16);\n }\n}\n" - }, - "contracts/L2/L1Block.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000015\n * @title L1Block\n * @notice The L1Block predeploy gives users access to information about the last known L1 block.\n * Values within this contract are updated once per epoch (every L1 block) and can only be\n * set by the \"depositor\" account, a special system address. Depositor account transactions\n * are created by the protocol whenever we move to a new epoch.\n */\ncontract L1Block is Semver {\n /**\n * @notice Address of the special depositor account.\n */\n address public constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001;\n\n /**\n * @notice The latest L1 block number known by the L2 system.\n */\n uint64 public number;\n\n /**\n * @notice The latest L1 timestamp known by the L2 system.\n */\n uint64 public timestamp;\n\n /**\n * @notice The latest L1 basefee.\n */\n uint256 public basefee;\n\n /**\n * @notice The latest L1 blockhash.\n */\n bytes32 public hash;\n\n /**\n * @notice The number of L2 blocks in the same epoch.\n */\n uint64 public sequenceNumber;\n\n /**\n * @notice The versioned hash to authenticate the batcher by.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice The overhead value applied to the L1 portion of the transaction\n * fee.\n */\n uint256 public l1FeeOverhead;\n\n /**\n * @notice The scalar value applied to the L1 portion of the transaction fee.\n */\n uint256 public l1FeeScalar;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Updates the L1 block values.\n *\n * @param _number L1 blocknumber.\n * @param _timestamp L1 timestamp.\n * @param _basefee L1 basefee.\n * @param _hash L1 blockhash.\n * @param _sequenceNumber Number of L2 blocks since epoch start.\n * @param _batcherHash Versioned hash to authenticate batcher by.\n * @param _l1FeeOverhead L1 fee overhead.\n * @param _l1FeeScalar L1 fee scalar.\n */\n function setL1BlockValues(\n uint64 _number,\n uint64 _timestamp,\n uint256 _basefee,\n bytes32 _hash,\n uint64 _sequenceNumber,\n bytes32 _batcherHash,\n uint256 _l1FeeOverhead,\n uint256 _l1FeeScalar\n ) external {\n require(\n msg.sender == DEPOSITOR_ACCOUNT,\n \"L1Block: only the depositor account can set L1 block values\"\n );\n\n number = _number;\n timestamp = _timestamp;\n basefee = _basefee;\n hash = _hash;\n sequenceNumber = _sequenceNumber;\n batcherHash = _batcherHash;\n l1FeeOverhead = _l1FeeOverhead;\n l1FeeScalar = _l1FeeScalar;\n }\n}\n" - }, - "contracts/L2/L1FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000001A\n * @title L1FeeVault\n * @notice The L1FeeVault accumulates the L1 portion of the transaction fees.\n */\ncontract L1FeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 0, 0) {}\n}\n" - }, - "contracts/L2/L2CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { L2ToL1MessagePasser } from \"./L2ToL1MessagePasser.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000007\n * @title L2CrossDomainMessenger\n * @notice The L2CrossDomainMessenger is a high-level interface for message passing between L1 and\n * L2 on the L2 side. Users are generally encouraged to use this contract instead of lower\n * level message passing contracts.\n */\ncontract L2CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.\n */\n constructor(address _l1CrossDomainMessenger)\n Semver(1, 0, 0)\n CrossDomainMessenger(_l1CrossDomainMessenger)\n {\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote messenger. Use otherMessenger going forward.\n *\n * @return Address of the L1CrossDomainMessenger contract.\n */\n function l1CrossDomainMessenger() public view returns (address) {\n return OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{\n value: _value\n }(_to, _gasLimit, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(Predeploys.L2_TO_L1_MESSAGE_PASSER);\n }\n}\n" - }, - "contracts/L2/L2ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { IOptimismMintableERC721 } from \"../universal/IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L2ERC721Bridge\n * @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.\n * This contract also acts as a burner for tokens being withdrawn.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n */\ncontract L2ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 0, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L1. Data supplied here will not be used to\n * execute any code on L1 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L2ERC721Bridge: local token cannot be self\");\n\n // Note that supportsInterface makes a callback to the _localToken address which is user\n // provided.\n require(\n ERC165Checker.supportsInterface(_localToken, type(IOptimismMintableERC721).interfaceId),\n \"L2ERC721Bridge: local token interface is not compliant\"\n );\n\n require(\n _remoteToken == IOptimismMintableERC721(_localToken).remoteToken(),\n \"L2ERC721Bridge: wrong remote token for Optimism Mintable ERC721 local token\"\n );\n\n // When a deposit is finalized, we give the NFT with the same tokenId to the account\n // on L2. Note that safeMint makes a callback to the _to address which is user provided.\n IOptimismMintableERC721(_localToken).safeMint(_to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"ERC721Bridge: remote token cannot be address(0)\");\n\n // Check that the withdrawal is being initiated by the NFT owner\n require(\n _from == IOptimismMintableERC721(_localToken).ownerOf(_tokenId),\n \"Withdrawal is not being initiated by NFT owner\"\n );\n\n // Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)\n // slither-disable-next-line reentrancy-events\n address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();\n require(\n remoteToken == _remoteToken,\n \"L2ERC721Bridge: remote token does not match given value\"\n );\n\n // When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2\n // usage\n // slither-disable-next-line reentrancy-events\n IOptimismMintableERC721(_localToken).burn(_from, _tokenId);\n\n bytes memory message = abi.encodeWithSelector(\n L1ERC721Bridge.finalizeBridgeERC721.selector,\n remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Send message to L1 bridge\n // slither-disable-next-line reentrancy-events\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L2/L2StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000010\n * @title L2StandardBridge\n * @notice The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L2, it will be escrowed within this\n * contract. If the ERC20 token is native to L1, it will be burnt.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L2StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal from L2 to L1 is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _otherBridge Address of the L1StandardBridge.\n */\n constructor(address payable _otherBridge)\n Semver(1, 0, 0)\n StandardBridge(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER), _otherBridge)\n {}\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdraw(\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual onlyEOA {\n _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1 to a target account on L1.\n * Note that if ETH is sent to a contract on L1 and the call fails, then that ETH will\n * be locked in the L1StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdrawTo(\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual {\n _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a deposit from L1 to L2.\n *\n * @param _l1Token Address of the L1 token to deposit.\n * @param _l2Token Address of the corresponding L2 token.\n * @param _from Address of the depositor.\n * @param _to Address of the recipient.\n * @param _amount Amount of the tokens being deposited.\n * @param _extraData Extra data attached to the deposit.\n */\n function finalizeDeposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable virtual {\n if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n } else {\n finalizeBridgeERC20(_l2Token, _l1Token, _from, _to, _amount, _extraData);\n }\n\n emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L1 bridge contract.\n *\n * @return Address of the corresponding L1 bridge contract.\n */\n function l1TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @custom:legacy\n * @notice Internal function to a withdrawal from L2 to L1 to a target account on L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _from Address of the withdrawer.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function _initiateWithdrawal(\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal {\n address l1Token = OptimismMintableERC20(_l2Token).l1Token();\n if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {\n _initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);\n } else {\n _initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n\n emit WithdrawalInitiated(l1Token, _l2Token, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L2/L2ToL1MessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000016\n * @title L2ToL1MessagePasser\n * @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from\n * L2 to L1 can be stored. The storage root of this contract is pulled up to the top level\n * of the L2 output to reduce the cost of proving the existence of sent messages.\n */\ncontract L2ToL1MessagePasser is Semver {\n /**\n * @notice The L1 gas limit set when eth is withdrawn using the receive() function.\n */\n uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Includes the message hashes for all withdrawals\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @notice A unique value hashed with each withdrawal.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Emitted any time a withdrawal is initiated.\n *\n * @param nonce Unique value corresponding to each withdrawal.\n * @param sender The L2 account address which initiated the withdrawal.\n * @param target The L1 account address the call will be send to.\n * @param value The ETH value submitted for withdrawal, to be forwarded to the target.\n * @param gasLimit The minimum amount of gas that must be provided when withdrawing.\n * @param data The data to be forwarded to the target on L1.\n * @param withdrawalHash The hash of the withdrawal.\n */\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n /**\n * @notice Emitted when the balance of this contract is burned.\n *\n * @param amount Amount of ETh that was burned.\n */\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Allows users to withdraw ETH by sending directly to this contract.\n */\n receive() external payable {\n initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @notice Removes all ETH held by this contract from the state. Used to prevent the amount of\n * ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to\n * create a contract and self-destruct it to itself. Anyone can call this function. Not\n * incentivized since this function is very cheap.\n */\n function burn() external {\n uint256 balance = address(this).balance;\n Burn.eth(balance);\n emit WithdrawerBalanceBurnt(balance);\n }\n\n /**\n * @notice Sends a message from L2 to L1.\n *\n * @param _target Address to call on L1 execution.\n * @param _gasLimit Minimum gas limit for executing the message on L1.\n * @param _data Data to forward to L1 target.\n */\n function initiateWithdrawal(\n address _target,\n uint256 _gasLimit,\n bytes memory _data\n ) public payable {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messageNonce(),\n sender: msg.sender,\n target: _target,\n value: msg.value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n sentMessages[withdrawalHash] = true;\n\n emit MessagePassed(\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _gasLimit,\n _data,\n withdrawalHash\n );\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n}\n" - }, - "contracts/L2/SequencerFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000011\n * @title SequencerFeeVault\n * @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during\n * transaction processing and block production.\n */\ncontract SequencerFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 0, 0) {}\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the recipient address.\n *\n * @return The recipient address.\n */\n function l1FeeWallet() public view returns (address) {\n return RECIPIENT;\n }\n}\n" - }, - "contracts/deployment/PortalSender.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/**\n * @title PortalSender\n * @notice The PortalSender is a simple intermediate contract that will transfer the balance of the\n * L1StandardBridge to the OptimismPortal during the Bedrock migration.\n */\ncontract PortalSender {\n /**\n * @notice Address of the OptimismPortal contract.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @param _portal Address of the OptimismPortal contract.\n */\n constructor(OptimismPortal _portal) {\n PORTAL = _portal;\n }\n\n /**\n * @notice Sends balance of this contract to the OptimismPortal.\n */\n function donate() public {\n PORTAL.donateETH{ value: address(this).balance }();\n }\n}\n" - }, - "contracts/deployment/SystemDictator.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { PortalSender } from \"./PortalSender.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\n\n/**\n * @title SystemDictator\n * @notice The SystemDictator is responsible for coordinating the deployment of a full Bedrock\n * system. The SystemDictator is designed to support both fresh network deployments and\n * upgrades to existing pre-Bedrock systems.\n */\ncontract SystemDictator is OwnableUpgradeable {\n /**\n * @notice Basic system configuration.\n */\n struct GlobalConfig {\n AddressManager addressManager;\n ProxyAdmin proxyAdmin;\n address controller;\n address finalOwner;\n }\n\n /**\n * @notice Set of proxy addresses.\n */\n struct ProxyAddressConfig {\n address l2OutputOracleProxy;\n address optimismPortalProxy;\n address l1CrossDomainMessengerProxy;\n address l1StandardBridgeProxy;\n address optimismMintableERC20FactoryProxy;\n address l1ERC721BridgeProxy;\n address systemConfigProxy;\n }\n\n /**\n * @notice Set of implementation addresses.\n */\n struct ImplementationAddressConfig {\n L2OutputOracle l2OutputOracleImpl;\n OptimismPortal optimismPortalImpl;\n L1CrossDomainMessenger l1CrossDomainMessengerImpl;\n L1StandardBridge l1StandardBridgeImpl;\n OptimismMintableERC20Factory optimismMintableERC20FactoryImpl;\n L1ERC721Bridge l1ERC721BridgeImpl;\n PortalSender portalSenderImpl;\n SystemConfig systemConfigImpl;\n }\n\n /**\n * @notice Dynamic L2OutputOracle config.\n */\n struct L2OutputOracleDynamicConfig {\n uint256 l2OutputOracleStartingBlockNumber;\n uint256 l2OutputOracleStartingTimestamp;\n }\n\n /**\n * @notice Values for the system config contract.\n */\n struct SystemConfigConfig {\n address owner;\n uint256 overhead;\n uint256 scalar;\n bytes32 batcherHash;\n uint64 gasLimit;\n address unsafeBlockSigner;\n }\n\n /**\n * @notice Combined system configuration.\n */\n struct DeployConfig {\n GlobalConfig globalConfig;\n ProxyAddressConfig proxyAddressConfig;\n ImplementationAddressConfig implementationAddressConfig;\n SystemConfigConfig systemConfigConfig;\n }\n\n /**\n * @notice Step after which exit 1 can no longer be used.\n */\n uint8 public constant EXIT_1_NO_RETURN_STEP = 3;\n\n /**\n * @notice Step where proxy ownership is transferred.\n */\n uint8 public constant PROXY_TRANSFER_STEP = 4;\n\n /**\n * @notice System configuration.\n */\n DeployConfig public config;\n\n /**\n * @notice Dynamic configuration for the L2OutputOracle.\n */\n L2OutputOracleDynamicConfig public l2OutputOracleDynamicConfig;\n\n /**\n * @notice Current step;\n */\n uint8 public currentStep;\n\n /**\n * @notice Whether or not dynamic config has been set.\n */\n bool public dynamicConfigSet;\n\n /**\n * @notice Whether or not the deployment is finalized.\n */\n bool public finalized;\n\n /**\n * @notice Address of the old L1CrossDomainMessenger implementation.\n */\n address public oldL1CrossDomainMessenger;\n\n /**\n * @notice Checks that the current step is the expected step, then bumps the current step.\n *\n * @param _step Current step.\n */\n modifier step(uint8 _step) {\n require(currentStep == _step, \"BaseSystemDictator: incorrect step\");\n _;\n currentStep++;\n }\n\n /**\n * @param _config System configuration.\n */\n function initialize(DeployConfig memory _config) public initializer {\n config = _config;\n currentStep = 1;\n __Ownable_init();\n _transferOwnership(config.globalConfig.controller);\n }\n\n /**\n * @notice Allows the owner to update dynamic L2OutputOracle config.\n *\n * @param _l2OutputOracleDynamicConfig Dynamic L2OutputOracle config.\n */\n function updateL2OutputOracleDynamicConfig(\n L2OutputOracleDynamicConfig memory _l2OutputOracleDynamicConfig\n ) external onlyOwner {\n l2OutputOracleDynamicConfig = _l2OutputOracleDynamicConfig;\n dynamicConfigSet = true;\n }\n\n /**\n * @notice Configures the ProxyAdmin contract.\n */\n function step1() external onlyOwner step(1) {\n // Set the AddressManager in the ProxyAdmin.\n config.globalConfig.proxyAdmin.setAddressManager(config.globalConfig.addressManager);\n\n // Set the L1CrossDomainMessenger to the RESOLVED proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n ProxyAdmin.ProxyType.RESOLVED\n );\n\n // Set the implementation name for the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.setImplementationName(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Set the L1StandardBridge to the CHUGSPLASH proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1StandardBridgeProxy,\n ProxyAdmin.ProxyType.CHUGSPLASH\n );\n }\n\n /**\n * @notice Pauses the system by shutting down the L1CrossDomainMessenger and setting the\n * deposit halt flag to tell the Sequencer's DTL to stop accepting deposits.\n */\n function step2() external onlyOwner step(2) {\n // Store the address of the old L1CrossDomainMessenger implementation. We will need this\n // address in the case that we have to exit early.\n oldL1CrossDomainMessenger = config.globalConfig.addressManager.getAddress(\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Temporarily brick the L1CrossDomainMessenger by setting its implementation address to\n // address(0) which will cause the ResolvedDelegateProxy to revert. Better than pausing\n // the L1CrossDomainMessenger via pause() because it can be easily reverted.\n config.globalConfig.addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(0));\n\n // Set the DTL shutoff block, which will tell the DTL to stop syncing new deposits from the\n // CanonicalTransactionChain. We do this by setting an address in the AddressManager\n // because the DTL already has a reference to the AddressManager and this way we don't also\n // need to give it a reference to the SystemDictator.\n config.globalConfig.addressManager.setAddress(\n \"DTL_SHUTOFF_BLOCK\",\n address(uint160(block.number))\n );\n }\n\n /**\n * @notice Removes deprecated addresses from the AddressManager.\n */\n function step3() external onlyOwner step(EXIT_1_NO_RETURN_STEP) {\n // Remove all deprecated addresses from the AddressManager\n string[17] memory deprecated = [\n \"OVM_CanonicalTransactionChain\",\n \"OVM_L2CrossDomainMessenger\",\n \"OVM_DecompressionPrecompileAddress\",\n \"OVM_Sequencer\",\n \"OVM_Proposer\",\n \"OVM_ChainStorageContainer-CTC-batches\",\n \"OVM_ChainStorageContainer-CTC-queue\",\n \"OVM_CanonicalTransactionChain\",\n \"OVM_StateCommitmentChain\",\n \"OVM_BondManager\",\n \"OVM_ExecutionManager\",\n \"OVM_FraudVerifier\",\n \"OVM_StateManagerFactory\",\n \"OVM_StateTransitionerFactory\",\n \"OVM_SafetyChecker\",\n \"OVM_L1MultiMessageRelayer\",\n \"BondManager\"\n ];\n\n for (uint256 i = 0; i < deprecated.length; i++) {\n config.globalConfig.addressManager.setAddress(deprecated[i], address(0));\n }\n }\n\n /**\n * @notice Transfers system ownership to the ProxyAdmin.\n */\n function step4() external onlyOwner step(PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the ProxyAdmin.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1StandardBridge to the ProxyAdmin.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the ProxyAdmin.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.proxyAdmin)\n );\n }\n\n /**\n * @notice Upgrades and initializes proxy contracts.\n */\n function step5() external onlyOwner step(5) {\n // Dynamic config must be set before we can initialize the L2OutputOracle.\n require(dynamicConfigSet, \"SystemDictator: dynamic oracle config is not yet initialized\");\n\n // Upgrade and initialize the L2OutputOracle.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l2OutputOracleProxy),\n address(config.implementationAddressConfig.l2OutputOracleImpl),\n abi.encodeCall(\n L2OutputOracle.initialize,\n (\n l2OutputOracleDynamicConfig.l2OutputOracleStartingBlockNumber,\n l2OutputOracleDynamicConfig.l2OutputOracleStartingTimestamp\n )\n )\n );\n\n // Upgrade and initialize the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.optimismPortalProxy),\n address(config.implementationAddressConfig.optimismPortalImpl),\n abi.encodeCall(OptimismPortal.initialize, ())\n );\n\n // Upgrade the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1CrossDomainMessengerProxy),\n address(config.implementationAddressConfig.l1CrossDomainMessengerImpl)\n );\n\n // Try to initialize the L1CrossDomainMessenger, only fail if it's already been initialized.\n try\n L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy)\n .initialize(address(this))\n {\n // L1CrossDomainMessenger is the one annoying edge case difference between existing\n // networks and fresh networks because in existing networks it'll already be\n // initialized but in fresh networks it won't be. Try/catch is the easiest and most\n // consistent way to handle this because initialized() is not exposed publicly.\n } catch Error(string memory reason) {\n require(\n keccak256(abi.encodePacked(reason)) ==\n keccak256(\"Initializable: contract is already initialized\"),\n string.concat(\"SystemDictator: unexpected error initializing L1XDM: \", reason)\n );\n } catch {\n revert(\"SystemDictator: unexpected error initializing L1XDM (no reason)\");\n }\n\n // Transfer ETH from the L1StandardBridge to the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.portalSenderImpl),\n abi.encodeCall(PortalSender.donate, ())\n );\n\n // Upgrade the L1StandardBridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.l1StandardBridgeImpl)\n );\n\n // Upgrade the OptimismMintableERC20Factory (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.optimismMintableERC20FactoryProxy),\n address(config.implementationAddressConfig.optimismMintableERC20FactoryImpl)\n );\n\n // Upgrade the L1ERC721Bridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1ERC721BridgeProxy),\n address(config.implementationAddressConfig.l1ERC721BridgeImpl)\n );\n\n // Upgrade and initialize the SystemConfig.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.systemConfigProxy),\n address(config.implementationAddressConfig.systemConfigImpl),\n abi.encodeCall(\n SystemConfig.initialize,\n (\n config.systemConfigConfig.owner,\n config.systemConfigConfig.overhead,\n config.systemConfigConfig.scalar,\n config.systemConfigConfig.batcherHash,\n config.systemConfigConfig.gasLimit,\n config.systemConfigConfig.unsafeBlockSigner\n )\n )\n );\n\n // Pause the L1CrossDomainMessenger, chance to check that everything is OK.\n L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy).pause();\n }\n\n /**\n * @notice Unpauses the system at which point the system should be fully operational.\n */\n function step6() external onlyOwner step(6) {\n // Unpause the L1CrossDomainMessenger.\n L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy).unpause();\n }\n\n /**\n * @notice Tranfers admin ownership to the final owner.\n */\n function finalize() external onlyOwner {\n // Transfer ownership of the L1CrossDomainMessenger to the final owner.\n L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy)\n .transferOwnership(config.globalConfig.finalOwner);\n\n // Transfer ownership of the ProxyAdmin to the final owner.\n config.globalConfig.proxyAdmin.transferOwnership(config.globalConfig.finalOwner);\n\n // Optionally also transfer AddressManager and L1StandardBridge if we still own it. Might\n // happen if we're exiting early.\n if (currentStep <= PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the final owner.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1StandardBridge to the final owner.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the final owner.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.finalOwner)\n );\n }\n\n finalized = true;\n }\n\n /**\n * @notice First exit point, can only be called before step 3 is executed.\n */\n function exit1() external onlyOwner {\n require(\n currentStep == EXIT_1_NO_RETURN_STEP,\n \"SystemDictator: can only exit1 before step 3 is executed\"\n );\n\n // Reset the L1CrossDomainMessenger to the old implementation.\n config.globalConfig.addressManager.setAddress(\n \"OVM_L1CrossDomainMessenger\",\n oldL1CrossDomainMessenger\n );\n\n // Unset the DTL shutoff block which will allow the DTL to sync again.\n config.globalConfig.addressManager.setAddress(\"DTL_SHUTOFF_BLOCK\", address(0));\n }\n}\n" - }, - "contracts/echidna/FuzzAddressAliasing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract EchidnaFuzzAddressAliasing {\n bool internal failedRoundtrip;\n\n /**\n * @notice Takes an address to be aliased with AddressAliasHelper and then unaliased\n * and updates the test contract's state indicating if the round trip encoding\n * failed.\n */\n function testRoundTrip(address addr) public {\n // Alias our address\n address aliasedAddr = AddressAliasHelper.applyL1ToL2Alias(addr);\n\n // Unalias our address\n address undoneAliasAddr = AddressAliasHelper.undoL1ToL2Alias(aliasedAddr);\n\n // If our round trip aliasing did not return the original result, set our state.\n if (addr != undoneAliasAddr) {\n failedRoundtrip = true;\n }\n }\n\n /**\n * @custom:invariant Address aliases are always able to be undone.\n *\n * Asserts that an address that has been aliased with `applyL1ToL2Alias` can always\n * be unaliased with `undoL1ToL2Alias`.\n */\n function echidna_round_trip_aliasing() public view returns (bool) {\n // ASSERTION: The round trip aliasing done in testRoundTrip(...) should never fail.\n return !failedRoundtrip;\n }\n}\n" - }, - "contracts/echidna/FuzzBurn.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\n\ncontract EchidnaFuzzBurnEth is StdUtils {\n bool internal failedEthBurn;\n\n /**\n * @notice Takes an integer amount of eth to burn through the Burn library and\n * updates the contract state if an incorrect amount of eth moved from the contract\n */\n function testBurn(uint256 _value) public {\n // cache the contract's eth balance\n uint256 preBurnBalance = address(this).balance;\n uint256 value = bound(_value, 0, preBurnBalance);\n\n // execute a burn of _value eth\n Burn.eth(value);\n\n // check that exactly value eth was transfered from the contract\n unchecked {\n if (address(this).balance != preBurnBalance - value) {\n failedEthBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `eth(uint256)` always burns the exact amount of eth passed.\n *\n * Asserts that when `Burn.eth(uint256)` is called, it always burns the exact amount\n * of ETH passed to the function.\n */\n function echidna_burn_eth() public view returns (bool) {\n // ASSERTION: The amount burned should always match the amount passed exactly\n return !failedEthBurn;\n }\n}\n\ncontract EchidnaFuzzBurnGas is StdUtils {\n bool internal failedGasBurn;\n\n /**\n * @notice Takes an integer amount of gas to burn through the Burn library and\n * updates the contract state if at least that amount of gas was not burned\n * by the library\n */\n function testGas(uint256 _value) public {\n // cap the value to the max resource limit\n uint256 MAX_RESOURCE_LIMIT = 8_000_000;\n uint256 value = bound(_value, 0, MAX_RESOURCE_LIMIT);\n\n // cache the contract's current remaining gas\n uint256 preBurnGas = gasleft();\n\n // execute the gas burn\n Burn.gas(value);\n\n // cache the remaining gas post burn\n uint256 postBurnGas = gasleft();\n\n // check that at least value gas was burnt (and that there was no underflow)\n unchecked {\n if (postBurnGas - preBurnGas > value || preBurnGas - value > preBurnGas) {\n failedGasBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `gas(uint256)` always burns at least the amount of gas passed.\n *\n * Asserts that when `Burn.gas(uint256)` is called, it always burns at least the amount\n * of gas passed to the function.\n */\n function echidna_burn_gas() public view returns (bool) {\n // ASSERTION: The amount of gas burned should be strictly greater than the\n // the amount passed as _value (minimum _value + whatever minor overhead to\n // the value after the call)\n return !failedGasBurn;\n }\n}\n" - }, - "contracts/echidna/FuzzEncoding.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzEncoding {\n bool internal failedRoundtripAToB;\n bool internal failedRoundtripBToA;\n\n /**\n * @notice Takes a pair of integers to be encoded into a versioned nonce with the\n * Encoding library and then decoded and updates the test contract's state\n * indicating if the round trip encoding failed.\n */\n function testRoundTripAToB(uint240 _nonce, uint16 _version) public {\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(encodedVersionedNonce);\n\n // If our round trip encoding did not return the original result, set our state.\n if ((decodedNonce != _nonce) || (decodedVersion != _version)) {\n failedRoundtripAToB = true;\n }\n }\n\n /**\n * @notice Takes an integer representing a packed version and nonce and attempts\n * to decode them using the Encoding library before re-encoding and updates\n * the test contract's state indicating if the round trip encoding failed.\n */\n function testRoundTripBToA(uint256 _versionedNonce) public {\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(_versionedNonce);\n\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(decodedNonce, decodedVersion);\n\n // If our round trip encoding did not return the original result, set our state.\n if (encodedVersionedNonce != _versionedNonce) {\n failedRoundtripBToA = true;\n }\n }\n\n /**\n * @custom:invariant `testRoundTripAToB` never fails.\n *\n * Asserts that a raw versioned nonce can be encoded / decoded to reach the same raw value.\n */\n function echidna_round_trip_encoding_AToB() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripAToB(...)\n return !failedRoundtripAToB;\n }\n\n /**\n * @custom:invariant `testRoundTripBToA` never fails.\n *\n * Asserts that an encoded versioned nonce can always be decoded / re-encoded to reach\n * the same encoded value.\n */\n function echidna_round_trip_encoding_BToA() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripBToA should never\n // fail.\n return !failedRoundtripBToA;\n }\n}\n" - }, - "contracts/echidna/FuzzHashing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzHashing {\n bool internal failedCrossDomainHashHighVersion;\n bool internal failedCrossDomainHashV0;\n bool internal failedCrossDomainHashV1;\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash with a randomly\n * generated version. Only schema versions 0 and 1 are supported and all others should revert.\n */\n function testHashCrossDomainMessageHighVersion(\n uint16 _version,\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // hash the cross domain message. we don't need to store the result since the function\n // validates and should revert if an invalid version (>1) is encoded\n Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);\n\n // check that execution never makes it this far for an invalid version\n if (_version > 1) {\n failedCrossDomainHashHighVersion = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v0 schema\n * and compares the output of a call to the unversioned function to the v0 function directly\n */\n function testHashCrossDomainMessageV0(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 0\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 0);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n encodedNonce\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV0 = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v1 schema\n * and compares the output of a call to the unversioned function to the v1 function directly\n */\n function testHashCrossDomainMessageV1(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 1\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 1);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV1 = true;\n }\n }\n\n /**\n * @custom:invariant `hashCrossDomainMessage` reverts if `version` is > `1`.\n *\n * The `hashCrossDomainMessage` function should always revert if the `version` passed is > `1`.\n */\n function echidna_hash_xdomain_msg_high_version() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage will never succeed for a version > 1\n return !failedCrossDomainHashHighVersion;\n }\n\n /**\n * @custom:invariant `version` = `0`: `hashCrossDomainMessage` and `hashCrossDomainMessageV0`\n * are equivalent.\n *\n * If the version passed is 0, `hashCrossDomainMessage` and `hashCrossDomainMessageV0` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_0() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV0\n // should always match when the version passed is 0\n return !failedCrossDomainHashV0;\n }\n\n /**\n * @custom:invariant `version` = `1`: `hashCrossDomainMessage` and `hashCrossDomainMessageV1`\n * are equivalent.\n *\n * If the version passed is 1, `hashCrossDomainMessage` and `hashCrossDomainMessageV1` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_1() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV1\n // should always match when the version passed is 1\n return !failedCrossDomainHashV1;\n }\n}\n" - }, - "contracts/echidna/FuzzOptimismPortal.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract EchidnaFuzzOptimismPortal {\n OptimismPortal internal portal;\n bool internal failedToComplete;\n\n constructor() {\n portal = new OptimismPortal(L2OutputOracle(address(0)), 10);\n }\n\n // A test intended to identify any unexpected halting conditions\n function testDepositTransactionCompletes(\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable {\n failedToComplete = true;\n require(!_isCreation || _to == address(0), \"EchidnaFuzzOptimismPortal: invalid test case.\");\n portal.depositTransaction{ value: _mint }(_to, _value, _gasLimit, _isCreation, _data);\n failedToComplete = false;\n }\n\n /**\n * @custom:invariant Deposits of any value should always succeed unless\n * `_to` = `address(0)` or `_isCreation` = `true`.\n *\n * All deposits, barring creation transactions and transactions sent to `address(0)`,\n * should always succeed.\n */\n function echidna_deposit_completes() public view returns (bool) {\n return !failedToComplete;\n }\n}\n" - }, - "contracts/echidna/FuzzResourceMetering.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\n\ncontract EchidnaFuzzResourceMetering is ResourceMetering, StdUtils {\n bool internal failedMaxGasPerBlock;\n bool internal failedRaiseBaseFee;\n bool internal failedLowerBaseFee;\n bool internal failedNeverBelowMinBaseFee;\n bool internal failedMaxRaiseBaseFeePerBlock;\n bool internal failedMaxLowerBaseFeePerBlock;\n\n // Used as a special flag for the purpose of identifying unchecked math errors specifically\n // in the test contracts, not the target contracts themselves.\n bool internal underflow;\n\n constructor() {\n initialize();\n }\n\n function initialize() internal initializer {\n __ResourceMetering_init();\n }\n\n /**\n * @notice Takes the necessary parameters to allow us to burn arbitrary amounts of gas to test\n * the underlying resource metering/gas market logic\n */\n function testBurn(uint256 _gasToBurn, bool _raiseBaseFee) public {\n // Part 1: we cache the current param values and do some basic checks on them.\n uint256 cachedPrevBaseFee = uint256(params.prevBaseFee);\n uint256 cachedPrevBoughtGas = uint256(params.prevBoughtGas);\n uint256 cachedPrevBlockNum = uint256(params.prevBlockNum);\n\n // check that the last block's base fee hasn't dropped below the minimum\n if (cachedPrevBaseFee < uint256(MINIMUM_BASE_FEE)) {\n failedNeverBelowMinBaseFee = true;\n }\n // check that the last block didn't consume more than the max amount of gas\n if (cachedPrevBoughtGas > uint256(MAX_RESOURCE_LIMIT)) {\n failedMaxGasPerBlock = true;\n }\n\n // Part2: we perform the gas burn\n\n // force the gasToBurn into the correct range based on whether we intend to\n // raise or lower the baseFee after this block, respectively\n uint256 gasToBurn;\n if (_raiseBaseFee) {\n gasToBurn = bound(\n _gasToBurn,\n uint256(TARGET_RESOURCE_LIMIT),\n uint256(MAX_RESOURCE_LIMIT)\n );\n } else {\n gasToBurn = bound(_gasToBurn, 0, uint256(TARGET_RESOURCE_LIMIT));\n }\n\n _burnInternal(uint64(gasToBurn));\n\n // Part 3: we run checks and modify our invariant flags based on the updated params values\n\n // Calculate the maximum allowed baseFee change (per block)\n uint256 maxBaseFeeChange = cachedPrevBaseFee / uint256(BASE_FEE_MAX_CHANGE_DENOMINATOR);\n\n // If the last block used more than the target amount of gas (and there were no\n // empty blocks in between), ensure this block's baseFee increased, but not by\n // more than the max amount per block\n if (\n (cachedPrevBoughtGas > uint256(TARGET_RESOURCE_LIMIT)) &&\n (uint256(params.prevBlockNum) - cachedPrevBlockNum == 1)\n ) {\n failedRaiseBaseFee = failedRaiseBaseFee || (params.prevBaseFee <= cachedPrevBaseFee);\n failedMaxRaiseBaseFeePerBlock =\n failedMaxRaiseBaseFeePerBlock ||\n ((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);\n }\n\n // If the last block used less than the target amount of gas, (or was empty),\n // ensure that: this block's baseFee was decreased, but not by more than the max amount\n if (\n (cachedPrevBoughtGas < uint256(TARGET_RESOURCE_LIMIT)) ||\n (uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)\n ) {\n // Invariant: baseFee should decrease\n failedLowerBaseFee =\n failedLowerBaseFee ||\n (uint256(params.prevBaseFee) > cachedPrevBaseFee);\n\n if (params.prevBlockNum - cachedPrevBlockNum == 1) {\n // No empty blocks\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n } else if (params.prevBlockNum - cachedPrevBlockNum > 1) {\n // We have at least one empty block\n // Update the maxBaseFeeChange to account for multiple blocks having passed\n unchecked {\n maxBaseFeeChange = uint256(\n int256(cachedPrevBaseFee) -\n Arithmetic.clamp(\n Arithmetic.cdexp(\n int256(cachedPrevBaseFee),\n BASE_FEE_MAX_CHANGE_DENOMINATOR,\n int256(uint256(params.prevBlockNum) - cachedPrevBlockNum)\n ),\n MINIMUM_BASE_FEE,\n MAXIMUM_BASE_FEE\n )\n );\n }\n\n // Detect an underflow in the previous calculation.\n // Without using unchecked above, and detecting the underflow here, echidna would\n // otherwise ignore the revert.\n underflow = underflow || maxBaseFeeChange > cachedPrevBaseFee;\n\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n }\n }\n }\n\n function _burnInternal(uint64 _gasToBurn) private metered(_gasToBurn) {}\n\n /**\n * @custom:invariant The base fee should increase if the last block used more\n * than the target amount of gas\n *\n * If the last block used more than the target amount of gas (and there were no\n * empty blocks in between), ensure this block's baseFee increased, but not by\n * more than the max amount per block.\n */\n function echidna_high_usage_raise_baseFee() public view returns (bool) {\n return !failedRaiseBaseFee;\n }\n\n /**\n * @custom:invariant The base fee should decrease if the last block used less\n * than the target amount of gas\n *\n * If the previous block used less than the target amount of gas, the base fee should decrease,\n * but not more than the max amount.\n */\n function echidna_low_usage_lower_baseFee() public view returns (bool) {\n return !failedLowerBaseFee;\n }\n\n /**\n * @custom:invariant A block's base fee should never be below `MINIMUM_BASE_FEE`\n *\n * This test asserts that a block's base fee can never drop below the\n * `MINIMUM_BASE_FEE` threshold.\n */\n function echidna_never_below_min_baseFee() public view returns (bool) {\n return !failedNeverBelowMinBaseFee;\n }\n\n /**\n * @custom:invariant A block can never consume more than `MAX_RESOURCE_LIMIT` gas.\n *\n * This test asserts that a block can never consume more than the `MAX_RESOURCE_LIMIT`\n * gas threshold.\n */\n function echidna_never_above_max_gas_limit() public view returns (bool) {\n return !failedMaxGasPerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be raised more than the max base fee change.\n *\n * After a block consumes more gas than the target gas, the base fee cannot be raised\n * more than the maximum amount allowed. The max base fee change (per-block) is derived\n * as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_increase() public view returns (bool) {\n return !failedMaxRaiseBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be lowered more than the max base fee change.\n *\n * After a block consumes less than the target gas, the base fee cannot be lowered more\n * than the maximum amount allowed. The max base fee change (per-block) is derived as\n *follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_decrease() public view returns (bool) {\n return !failedMaxLowerBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The `maxBaseFeeChange` calculation over multiple blocks can never\n * underflow.\n *\n * When calculating the `maxBaseFeeChange` after multiple empty blocks, the calculation\n * should never be allowed to underflow.\n */\n function echidna_underflow() public view returns (bool) {\n return !underflow;\n }\n}\n" - }, - "contracts/governance/GovernanceToken.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:predeploy 0x4200000000000000000000000000000000000042\n * @title GovernanceToken\n * @notice The Optimism token used in governance and supporting voting and delegation. Implements\n * EIP 2612 allowing signed approvals. Contract is \"owned\" by a `MintManager` instance with\n * permission to the `mint` function only, for the purposes of enforcing the token inflation\n * schedule.\n */\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\n constructor() ERC20(\"Optimism\", \"OP\") ERC20Permit(\"Optimism\") {}\n\n /**\n * @notice Allows the owner to mint tokens.\n *\n * @param _account The account receiving minted tokens.\n * @param _amount The amount of tokens to mint.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n /**\n * @notice Callback called after a token transfer.\n *\n * @param from The account sending tokens.\n * @param to The account receiving tokens.\n * @param amount The amount of tokens being transfered.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20, ERC20Votes) {\n super._afterTokenTransfer(from, to, amount);\n }\n\n /**\n * @notice Internal mint function.\n *\n * @param to The account receiving minted tokens.\n * @param amount The amount of tokens to mint.\n */\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._mint(to, amount);\n }\n\n /**\n * @notice Internal burn function.\n *\n * @param account The account that tokens will be burned from.\n * @param amount The amount of tokens that will be burned.\n */\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._burn(account, amount);\n }\n}\n" - }, - "contracts/governance/MintManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./GovernanceToken.sol\";\n\n/**\n * @title MintManager\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\n * Contract acts as the token \"mint manager\" with permission to the `mint` function only.\n * Currently permitted to mint once per year of up to 2% of the total token supply.\n * Upgradable to allow changes in the inflation schedule.\n */\ncontract MintManager is Ownable {\n /**\n * @notice The GovernanceToken that the MintManager can mint tokens\n */\n GovernanceToken public immutable governanceToken;\n\n /**\n * @notice The amount of tokens that can be minted per year. The value is a fixed\n * point number with 4 decimals.\n */\n uint256 public constant MINT_CAP = 20; // 2%\n\n /**\n * @notice The number of decimals for the MINT_CAP.\n */\n uint256 public constant DENOMINATOR = 1000;\n\n /**\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\n * be minted again.\n */\n uint256 public constant MINT_PERIOD = 365 days;\n\n /**\n * @notice Tracks the time of last mint.\n */\n uint256 public mintPermittedAfter;\n\n /**\n * @param _upgrader The owner of this contract\n * @param _governanceToken The governance token this contract can mint\n * tokens of\n */\n constructor(address _upgrader, address _governanceToken) {\n transferOwnership(_upgrader);\n governanceToken = GovernanceToken(_governanceToken);\n }\n\n /**\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\n *\n * @param _account Address to mint new tokens to.\n * @param _amount Amount of tokens to be minted.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n if (mintPermittedAfter > 0) {\n require(\n mintPermittedAfter <= block.timestamp,\n \"MintManager: minting not permitted yet\"\n );\n\n require(\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\n \"MintManager: mint amount exceeds cap\"\n );\n }\n\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\n governanceToken.mint(_account, _amount);\n }\n\n /**\n * @notice Upgrade the owner of the governance token to a new MintManager.\n *\n * @param _newMintManager The MintManager to upgrade to.\n */\n function upgrade(address _newMintManager) public onlyOwner {\n require(\n _newMintManager != address(0),\n \"MintManager: mint manager cannot be the zero address\"\n );\n\n governanceToken.transferOwnership(_newMintManager);\n }\n}\n" - }, - "contracts/legacy/AddressManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:legacy\n * @title AddressManager\n * @notice AddressManager is a legacy contract that was used in the old version of the Optimism\n * system to manage a registry of string names to addresses. We now use a more standard\n * proxy system instead, but this contract is still necessary for backwards compatibility\n * with several older contracts.\n */\ncontract AddressManager is Ownable {\n /**\n * @notice Mapping of the hashes of string names to addresses.\n */\n mapping(bytes32 => address) private addresses;\n\n /**\n * @notice Emitted when an address is modified in the registry.\n *\n * @param name String name being set in the registry.\n * @param newAddress Address set for the given name.\n * @param oldAddress Address that was previously set for the given name.\n */\n event AddressSet(string indexed name, address newAddress, address oldAddress);\n\n /**\n * @notice Changes the address associated with a particular name.\n *\n * @param _name String name to associate an address with.\n * @param _address Address to associate with the name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n bytes32 nameHash = _getNameHash(_name);\n address oldAddress = addresses[nameHash];\n addresses[nameHash] = _address;\n\n emit AddressSet(_name, _address, oldAddress);\n }\n\n /**\n * @notice Retrieves the address associated with a given name.\n *\n * @param _name Name to retrieve an address for.\n *\n * @return Address associated with the given name.\n */\n function getAddress(string memory _name) external view returns (address) {\n return addresses[_getNameHash(_name)];\n }\n\n /**\n * @notice Computes the hash of a name.\n *\n * @param _name Name to compute a hash for.\n *\n * @return Hash of the given name.\n */\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(_name));\n }\n}\n" - }, - "contracts/legacy/DeployerWhitelist.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000002\n * @title DeployerWhitelist\n * @notice DeployerWhitelist is a legacy contract that was originally used to act as a whitelist of\n * addresses allowed to the Optimism network. The DeployerWhitelist has since been\n * disabled, but the code is kept in state for the sake of full backwards compatibility.\n * As of the Bedrock upgrade, the DeployerWhitelist is completely unused by the Optimism\n * system and could, in theory, be removed entirely.\n */\ncontract DeployerWhitelist is Semver {\n /**\n * @notice Address of the owner of this contract. Note that when this address is set to\n * address(0), the whitelist is disabled.\n */\n address public owner;\n\n /**\n * @notice Mapping of deployer addresses to boolean whitelist status.\n */\n mapping(address => bool) public whitelist;\n\n /**\n * @notice Emitted when the owner of this contract changes.\n *\n * @param oldOwner Address of the previous owner.\n * @param newOwner Address of the new owner.\n */\n event OwnerChanged(address oldOwner, address newOwner);\n\n /**\n * @notice Emitted when the whitelist status of a deployer changes.\n *\n * @param deployer Address of the deployer.\n * @param whitelisted Boolean indicating whether the deployer is whitelisted.\n */\n event WhitelistStatusChanged(address deployer, bool whitelisted);\n\n /**\n * @notice Emitted when the whitelist is disabled.\n *\n * @param oldOwner Address of the final owner of the whitelist.\n */\n event WhitelistDisabled(address oldOwner);\n\n /**\n * @notice Blocks functions to anyone except the contract owner.\n */\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"DeployerWhitelist: function can only be called by the owner of this contract\"\n );\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Adds or removes an address from the deployment whitelist.\n *\n * @param _deployer Address to update permissions for.\n * @param _isWhitelisted Whether or not the address is whitelisted.\n */\n function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external onlyOwner {\n whitelist[_deployer] = _isWhitelisted;\n emit WhitelistStatusChanged(_deployer, _isWhitelisted);\n }\n\n /**\n * @notice Updates the owner of this contract.\n *\n * @param _owner Address of the new owner.\n */\n function setOwner(address _owner) external onlyOwner {\n // Prevent users from setting the whitelist owner to address(0) except via\n // enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to\n // any other address that doesn't have a corresponding knowable private key.\n require(\n _owner != address(0),\n \"DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment\"\n );\n\n emit OwnerChanged(owner, _owner);\n owner = _owner;\n }\n\n /**\n * @notice Permanently enables arbitrary contract deployment and deletes the owner.\n */\n function enableArbitraryContractDeployment() external onlyOwner {\n emit WhitelistDisabled(owner);\n owner = address(0);\n }\n\n /**\n * @notice Checks whether an address is allowed to deploy contracts.\n *\n * @param _deployer Address to check.\n *\n * @return Whether or not the address can deploy contracts.\n */\n function isDeployerAllowed(address _deployer) external view returns (bool) {\n return (owner == address(0) || whitelist[_deployer]);\n }\n}\n" - }, - "contracts/legacy/L1BlockNumber.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000013\n * @title L1BlockNumber\n * @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract\n * in the old version of the Optimism system. Only necessary for backwards compatibility.\n * If you want to access the L1 block number going forward, you should use the L1Block\n * contract instead.\n */\ncontract L1BlockNumber is Semver {\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Returns the L1 block number.\n */\n receive() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Returns the L1 block number.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Retrieves the latest L1 block number.\n *\n * @return Latest L1 block number.\n */\n function getL1BlockNumber() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).number();\n }\n}\n" - }, - "contracts/legacy/L1ChugSplashProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title IL1ChugSplashDeployer\n */\ninterface IL1ChugSplashDeployer {\n function isUpgrading() external view returns (bool);\n}\n\n/**\n * @custom:legacy\n * @title L1ChugSplashProxy\n * @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\n * functions `setCode` and `setStorage` for changing the code or storage of the contract.\n *\n * Note for future developers: do NOT make anything in this contract 'public' unless you\n * know what you're doing. Anything public can potentially have a function signature that\n * conflicts with a signature attached to the implementation contract. Public functions\n * SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good\n * reason not to have that modifier. And there almost certainly is not a good reason to not\n * have that modifier. Beware!\n */\ncontract L1ChugSplashProxy {\n /**\n * @notice \"Magic\" prefix. When prepended to some arbitrary bytecode and used to create a\n * contract, the appended bytecode will be deployed as given.\n */\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice Blocks a function from being called when the parent signals that the system should\n * be paused via an isUpgrading function.\n */\n modifier onlyWhenNotPaused() {\n address owner = _getOwner();\n\n // We do a low-level call because there's no guarantee that the owner actually *is* an\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\n // it turns out that it isn't the right type of contract.\n (bool success, bytes memory returndata) = owner.staticcall(\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)\n );\n\n // If the call was unsuccessful then we assume that there's no \"isUpgrading\" method and we\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\n // long. If this isn't the case then we can safely ignore the result.\n if (success && returndata.length == 32) {\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\n // case that the isUpgrading function returned something other than 0 or 1. But we only\n // really care about the case where this value is 0 (= false).\n uint256 ret = abi.decode(returndata, (uint256));\n require(ret == 0, \"L1ChugSplashProxy: system is currently being upgraded\");\n }\n\n _;\n }\n\n /**\n * @notice Makes a proxy call instead of triggering the given function when the caller is\n * either the owner or the zero address. Caller can only ever be the zero address if\n * this function is being called off-chain via eth_call, which is totally fine and can\n * be convenient for client-side tooling. Avoids situations where the proxy and\n * implementation share a sighash and the proxy function ends up being called instead\n * of the implementation one.\n *\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If\n * there's a way for someone to send a transaction with msg.sender == address(0) in any\n * real context then we have much bigger problems. Primary reason to include this\n * additional allowed sender is because the owner address can be changed dynamically\n * and we do not want clients to have to keep track of the current owner in order to\n * make an eth_call that doesn't trigger the proxied contract.\n */\n // slither-disable-next-line incorrect-modifier\n modifier proxyCallIfNotOwner() {\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @param _owner Address of the initial contract owner.\n */\n constructor(address _owner) {\n _setOwner(_owner);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Sets the code that should be running behind this proxy.\n *\n * Note: This scheme is a bit different from the standard proxy scheme where one would\n * typically deploy the code separately and then set the implementation address. We're\n * doing it this way because it gives us a lot more freedom on the client side. Can\n * only be triggered by the contract owner.\n *\n * @param _code New contract code to run inside this contract.\n */\n function setCode(bytes memory _code) external proxyCallIfNotOwner {\n // Get the code hash of the current implementation.\n address implementation = _getImplementation();\n\n // If the code hash matches the new implementation then we return early.\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\n return;\n }\n\n // Create the deploycode by appending the magic prefix.\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\n\n // Deploy the code and set the new implementation address.\n address newImplementation;\n assembly {\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\n }\n\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\n // actually fail this check. Should only happen if the contract creation from above runs\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\n // should be doing this check anyway though.\n require(\n _getAccountCodeHash(newImplementation) == keccak256(_code),\n \"L1ChugSplashProxy: code was not correctly deployed\"\n );\n\n _setImplementation(newImplementation);\n }\n\n /**\n * @notice Modifies some storage slot within the proxy contract. Gives us a lot of power to\n * perform upgrades in a more transparent way. Only callable by the owner.\n *\n * @param _key Storage key to modify.\n * @param _value New value for the storage key.\n */\n function setStorage(bytes32 _key, bytes32 _value) external proxyCallIfNotOwner {\n assembly {\n sstore(_key, _value)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _owner New owner of the proxy contract.\n */\n function setOwner(address _owner) external proxyCallIfNotOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Queries the owner of the proxy contract. Can only be called by the owner OR by\n * making an eth_call and setting the \"from\" address to address(0).\n *\n * @return Owner address.\n */\n function getOwner() external proxyCallIfNotOwner returns (address) {\n return _getOwner();\n }\n\n /**\n * @notice Queries the implementation address. Can only be called by the owner OR by making an\n * eth_call and setting the \"from\" address to address(0).\n *\n * @return Implementation address.\n */\n function getImplementation() external proxyCallIfNotOwner returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _owner New owner of the proxy contract.\n */\n function _setOwner(address _owner) internal {\n assembly {\n sstore(OWNER_KEY, _owner)\n }\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal onlyWhenNotPaused {\n address implementation = _getImplementation();\n\n require(implementation != address(0), \"L1ChugSplashProxy: implementation is not set yet\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address implementation;\n assembly {\n implementation := sload(IMPLEMENTATION_KEY)\n }\n return implementation;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getOwner() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n\n /**\n * @notice Gets the code hash for a given account.\n *\n * @param _account Address of the account to get a code hash for.\n *\n * @return Code hash for the account.\n */\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\n bytes32 codeHash;\n assembly {\n codeHash := extcodehash(_account)\n }\n return codeHash;\n }\n}\n" - }, - "contracts/legacy/LegacyERC20ETH.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000\n * @title LegacyERC20ETH\n * @notice LegacyERC20ETH is a legacy contract that held ETH balances before the Bedrock upgrade.\n * All ETH balances held within this contract were migrated to the state trie as part of\n * the Bedrock upgrade. Functions within this contract that mutate state were already\n * disabled as part of the EVM equivalence upgrade.\n */\ncontract LegacyERC20ETH is OptimismMintableERC20 {\n /**\n * @notice Initializes the contract as an Optimism Mintable ERC20.\n */\n constructor()\n OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), \"Ether\", \"ETH\")\n {}\n\n /**\n * @notice Returns the ETH balance of the target account. Overrides the base behavior of the\n * contract to preserve the invariant that the balance within this contract always\n * matches the balance in the state trie.\n *\n * @param _who Address of the account to query.\n *\n * @return The ETH balance of the target account.\n */\n function balanceOf(address _who) public view virtual override returns (uint256) {\n return address(_who).balance;\n }\n\n /**\n * @custom:blocked\n * @notice Mints some amount of ETH.\n */\n function mint(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: mint is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Burns some amount of ETH.\n */\n function burn(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: burn is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers some amount of ETH.\n */\n function transfer(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transfer is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Approves a spender to spend some amount of ETH.\n */\n function approve(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: approve is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers funds from some sender account.\n */\n function transferFrom(\n address,\n address,\n uint256\n ) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transferFrom is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Increases the allowance of a spender.\n */\n function increaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Decreases the allowance of a spender.\n */\n function decreaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n }\n}\n" - }, - "contracts/legacy/LegacyMessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000000\n * @title LegacyMessagePasser\n * @notice The LegacyMessagePasser was the low-level mechanism used to send messages from L2 to L1\n * before the Bedrock upgrade. It is now deprecated in favor of the new MessagePasser.\n */\ncontract LegacyMessagePasser is Semver {\n /**\n * @notice Mapping of sent message hashes to boolean status.\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Passes a message to L1.\n *\n * @param _message Message to pass to L1.\n */\n function passMessageToL1(bytes memory _message) external {\n sentMessages[keccak256(abi.encodePacked(_message, msg.sender))] = true;\n }\n}\n" - }, - "contracts/legacy/ResolvedDelegateProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressManager } from \"./AddressManager.sol\";\n\n/**\n * @custom:legacy\n * @title ResolvedDelegateProxy\n * @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to\n * resolve the implementation address. We're maintaining this contract for backwards\n * compatibility so we can manage all legacy proxies where necessary.\n */\ncontract ResolvedDelegateProxy {\n /**\n * @notice Mapping used to store the implementation name that corresponds to this contract. A\n * mapping was originally used as a way to bypass the same issue normally solved by\n * storing the implementation address in a specific storage slot that does not conflict\n * with any other storage slot. Generally NOT a safe solution but works as long as the\n * implementation does not also keep a mapping in the first storage slot.\n */\n mapping(address => string) private implementationName;\n\n /**\n * @notice Mapping used to store the address of the AddressManager contract where the\n * implementation address will be resolved from. Same concept here as with the above\n * mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping\n * in the second storage slot.\n */\n mapping(address => AddressManager) private addressManager;\n\n /**\n * @param _addressManager Address of the AddressManager.\n * @param _implementationName implementationName of the contract to proxy to.\n */\n constructor(AddressManager _addressManager, string memory _implementationName) {\n addressManager[address(this)] = _addressManager;\n implementationName[address(this)] = _implementationName;\n }\n\n /**\n * @notice Fallback, performs a delegatecall to the resolved implementation address.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n address target = addressManager[address(this)].getAddress(\n (implementationName[address(this)])\n );\n\n require(target != address(0), \"ResolvedDelegateProxy: target address must be initialized\");\n\n // slither-disable-next-line controlled-delegatecall\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\n\n if (success == true) {\n assembly {\n return(add(returndata, 0x20), mload(returndata))\n }\n } else {\n assembly {\n revert(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n" - }, - "contracts/libraries/Arithmetic.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { SignedMath } from \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport { FixedPointMathLib } from \"@rari-capital/solmate/src/utils/FixedPointMathLib.sol\";\n\n/**\n * @title Arithmetic\n * @notice Even more math than before.\n */\nlibrary Arithmetic {\n /**\n * @notice Clamps a value between a minimum and maximum.\n *\n * @param _value The value to clamp.\n * @param _min The minimum value.\n * @param _max The maximum value.\n *\n * @return The clamped value.\n */\n function clamp(\n int256 _value,\n int256 _min,\n int256 _max\n ) internal pure returns (int256) {\n return SignedMath.min(SignedMath.max(_value, _min), _max);\n }\n\n /**\n * @notice (c)oefficient (d)enominator (exp)onentiation function.\n * Returns the result of: c * (1 - 1/d)^exp.\n *\n * @param _coefficient Coefficient of the function.\n * @param _denominator Fractional denominator.\n * @param _exponent Power function exponent.\n *\n * @return Result of c * (1 - 1/d)^exp.\n */\n function cdexp(\n int256 _coefficient,\n int256 _denominator,\n int256 _exponent\n ) internal pure returns (int256) {\n return\n (_coefficient *\n (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;\n }\n}\n" - }, - "contracts/libraries/Burn.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Burn\n * @notice Utilities for burning stuff.\n */\nlibrary Burn {\n /**\n * Burns a given amount of ETH.\n *\n * @param _amount Amount of ETH to burn.\n */\n function eth(uint256 _amount) internal {\n new Burner{ value: _amount }();\n }\n\n /**\n * Burns a given amount of gas.\n *\n * @param _amount Amount of gas to burn.\n */\n function gas(uint256 _amount) internal view {\n uint256 i = 0;\n uint256 initialGas = gasleft();\n while (initialGas - gasleft() < _amount) {\n ++i;\n }\n }\n}\n\n/**\n * @title Burner\n * @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to\n * the contract from the circulating supply. Self-destructing is the only way to remove ETH\n * from the circulating supply.\n */\ncontract Burner {\n constructor() payable {\n selfdestruct(payable(address(this)));\n }\n}\n" - }, - "contracts/libraries/Bytes.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Bytes\n * @notice Bytes is a library for manipulating byte arrays.\n */\nlibrary Bytes {\n /**\n * @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\n * @notice Slices a byte array with a given starting index and length. Returns a new byte array\n * as opposed to a pointer to the original array. Will throw if trying to slice more\n * bytes than exist in the array.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n * @param _length Length of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n ) internal pure returns (bytes memory) {\n unchecked {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_start + _length >= _start, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n }\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n /**\n * @notice Slices a byte array with a given starting index up to the end of the original byte\n * array. Returns a new array rathern than a pointer to the original.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\n if (_start >= _bytes.length) {\n return bytes(\"\");\n }\n return slice(_bytes, _start, _bytes.length - _start);\n }\n\n /**\n * @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.\n * Resulting nibble array will be exactly twice as long as the input byte array.\n *\n * @param _bytes Input byte array to convert.\n *\n * @return Resulting nibble array.\n */\n function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n uint256 bytesLength = _bytes.length;\n bytes memory nibbles = new bytes(bytesLength * 2);\n bytes1 b;\n\n for (uint256 i = 0; i < bytesLength; ) {\n b = _bytes[i];\n nibbles[i * 2] = b >> 4;\n nibbles[i * 2 + 1] = b & 0x0f;\n unchecked {\n ++i;\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Compares two byte arrays by comparing their keccak256 hashes.\n *\n * @param _bytes First byte array to compare.\n * @param _other Second byte array to compare.\n *\n * @return True if the two byte arrays are equal, false otherwise.\n */\n function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n return keccak256(_bytes) == keccak256(_other);\n }\n}\n" - }, - "contracts/libraries/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Constants\n * @notice Constants is a library for storing constants. Simple! Don't put everything in here, just\n * the stuff used in multiple contracts. Constants that only apply to a single contract\n * should be defined in that contract instead.\n */\nlibrary Constants {\n /**\n * @notice Special address to be used as the tx origin for gas estimation calls in the\n * OptimismPortal and CrossDomainMessenger calls. You only need to use this address if\n * the minimum gas limit specified by the user is not actually enough to execute the\n * given message and you're attempting to estimate the actual necessary gas limit. We\n * use address(1) because it's the ecrecover precompile and therefore guaranteed to\n * never have any code on any EVM chain.\n */\n address internal constant ESTIMATION_ADDRESS = address(1);\n\n /**\n * @notice Value used for the L2 sender storage slot in both the OptimismPortal and the\n * CrossDomainMessenger contracts before an actual sender is set. This value is\n * non-zero to reduce the gas cost of message passing transactions.\n */\n address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;\n}\n" - }, - "contracts/libraries/Encoding.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Hashing } from \"./Hashing.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\n\n/**\n * @title Encoding\n * @notice Encoding handles Optimism's various different encoding schemes.\n */\nlibrary Encoding {\n /**\n * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\n * to the L2 system. Useful for searching for a deposit in the L2 system. The\n * transaction is prefixed with 0x7e to identify its EIP-2718 type.\n *\n * @param _tx User deposit transaction to encode.\n *\n * @return RLP encoded L2 deposit transaction.\n */\n function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes memory)\n {\n bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\n bytes[] memory raw = new bytes[](8);\n raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\n raw[1] = RLPWriter.writeAddress(_tx.from);\n raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\"\") : RLPWriter.writeAddress(_tx.to);\n raw[3] = RLPWriter.writeUint(_tx.mint);\n raw[4] = RLPWriter.writeUint(_tx.value);\n raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\n raw[6] = RLPWriter.writeBool(false);\n raw[7] = RLPWriter.writeBytes(_tx.data);\n return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\n }\n\n /**\n * @notice Encodes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n (, uint16 version) = decodeVersionedNonce(_nonce);\n if (version == 0) {\n return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Encoding: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Encodes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _data,\n _nonce\n );\n }\n\n /**\n * @notice Encodes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(uint256,address,address,uint256,uint256,bytes)\",\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n }\n\n /**\n * @notice Adds a version number into the first two bytes of a message nonce.\n *\n * @param _nonce Message nonce to encode into.\n * @param _version Version number to encode into the message nonce.\n *\n * @return Message nonce with version encoded into the first two bytes.\n */\n function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\n uint256 nonce;\n assembly {\n nonce := or(shl(240, _version), _nonce)\n }\n return nonce;\n }\n\n /**\n * @notice Pulls the version out of a version-encoded nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n *\n * @return Nonce without encoded version.\n * @return Version of the message.\n */\n function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\n uint240 nonce;\n uint16 version;\n assembly {\n nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n version := shr(240, _nonce)\n }\n return (nonce, version);\n }\n}\n" - }, - "contracts/libraries/Hashing.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Encoding } from \"./Encoding.sol\";\n\n/**\n * @title Hashing\n * @notice Hashing handles Optimism's various different hashing schemes.\n */\nlibrary Hashing {\n /**\n * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\n * given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\n * system.\n *\n * @param _tx User deposit transaction to hash.\n *\n * @return Hash of the RLP encoded L2 deposit transaction.\n */\n function hashDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return keccak256(Encoding.encodeDepositTransaction(_tx));\n }\n\n /**\n * @notice Computes the deposit transaction's \"source hash\", a value that guarantees the hash\n * of the L2 transaction that corresponds to a deposit is unique and is\n * deterministically generated from L1 transaction data.\n *\n * @param _l1BlockHash Hash of the L1 block where the deposit was included.\n * @param _logIndex The index of the log that created the deposit transaction.\n *\n * @return Hash of the deposit transaction's \"source hash\".\n */\n function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)\n internal\n pure\n returns (bytes32)\n {\n bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\n return keccak256(abi.encode(bytes32(0), depositId));\n }\n\n /**\n * @notice Hashes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n if (version == 0) {\n return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Hashing: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Hashes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes32) {\n return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));\n }\n\n /**\n * @notice Hashes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n return\n keccak256(\n Encoding.encodeCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n )\n );\n }\n\n /**\n * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\n *\n * @param _tx Withdrawal transaction to hash.\n *\n * @return Hashed withdrawal transaction.\n */\n function hashWithdrawal(Types.WithdrawalTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\n );\n }\n\n /**\n * @notice Hashes the various elements of an output root proof into an output root hash which\n * can be used to check if the proof is valid.\n *\n * @param _outputRootProof Output root proof which should hash to an output root.\n *\n * @return Hashed output root proof.\n */\n function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(\n _outputRootProof.version,\n _outputRootProof.stateRoot,\n _outputRootProof.messagePasserStorageRoot,\n _outputRootProof.latestBlockhash\n )\n );\n }\n}\n" - }, - "contracts/libraries/Predeploys.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Predeploys\n * @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.\n */\nlibrary Predeploys {\n /**\n * @notice Address of the L2ToL1MessagePasser predeploy.\n */\n address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;\n\n /**\n * @notice Address of the L2CrossDomainMessenger predeploy.\n */\n address internal constant L2_CROSS_DOMAIN_MESSENGER =\n 0x4200000000000000000000000000000000000007;\n\n /**\n * @notice Address of the L2StandardBridge predeploy.\n */\n address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\n\n /**\n * @notice Address of the L2ERC721Bridge predeploy.\n */\n address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;\n\n /**\n * @notice Address of the SequencerFeeWallet predeploy.\n */\n address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;\n\n /**\n * @notice Address of the OptimismMintableERC20Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY =\n 0x4200000000000000000000000000000000000012;\n\n /**\n * @notice Address of the OptimismMintableERC721Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY =\n 0x4200000000000000000000000000000000000017;\n\n /**\n * @notice Address of the L1Block predeploy.\n */\n address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;\n\n /**\n * @notice Address of the GasPriceOracle predeploy. Includes fee information\n * and helpers for computing the L1 portion of the transaction fee.\n */\n address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;\n\n /**\n * @custom:legacy\n * @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger\n * or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.\n */\n address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\n\n /**\n * @custom:legacy\n * @notice Address of the DeployerWhitelist predeploy. No longer active.\n */\n address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the\n * state trie as of the Bedrock upgrade. Contract has been locked and write functions\n * can no longer be accessed.\n */\n address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;\n\n /**\n * @custom:legacy\n * @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy\n * instead, which exposes more information about the L1 state.\n */\n address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated\n * L2ToL1MessagePasser contract instead.\n */\n address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\n\n /**\n * @notice Address of the ProxyAdmin predeploy.\n */\n address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;\n\n /**\n * @notice Address of the BaseFeeVault predeploy.\n */\n address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;\n\n /**\n * @notice Address of the L1FeeVault predeploy.\n */\n address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;\n}\n" - }, - "contracts/libraries/SafeCall.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title SafeCall\n * @notice Perform low level safe calls\n */\nlibrary SafeCall {\n /**\n * @notice Perform a low level call without copying any returndata\n *\n * @param _target Address to call\n * @param _gas Amount of gas to pass to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function call(\n address _target,\n uint256 _gas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 0x20), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n }\n return _success;\n }\n}\n" - }, - "contracts/libraries/Types.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Types\n * @notice Contains various types used throughout the Optimism contract system.\n */\nlibrary Types {\n /**\n * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\n * timestamp that the output root is posted. This timestamp is used to verify that the\n * finalization period has passed since the output root was submitted.\n *\n * @custom:field outputRoot Hash of the L2 output.\n * @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.\n * @custom:field l2BlockNumber L2 block number that the output corresponds to.\n */\n struct OutputProposal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2BlockNumber;\n }\n\n /**\n * @notice Struct representing the elements that are hashed together to generate an output root\n * which itself represents a snapshot of the L2 state.\n *\n * @custom:field version Version of the output root.\n * @custom:field stateRoot Root of the state trie at the block of this output.\n * @custom:field messagePasserStorageRoot Root of the message passer storage trie.\n * @custom:field latestBlockhash Hash of the block this output was generated from.\n */\n struct OutputRootProof {\n bytes32 version;\n bytes32 stateRoot;\n bytes32 messagePasserStorageRoot;\n bytes32 latestBlockhash;\n }\n\n /**\n * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n * user (as opposed to a system deposit transaction generated by the system).\n *\n * @custom:field from Address of the sender of the transaction.\n * @custom:field to Address of the recipient of the transaction.\n * @custom:field isCreation True if the transaction is a contract creation.\n * @custom:field value Value to send to the recipient.\n * @custom:field mint Amount of ETH to mint.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n * @custom:field l1BlockHash Hash of the block the transaction was submitted in.\n * @custom:field logIndex Index of the log in the block the transaction was submitted in.\n */\n struct UserDepositTransaction {\n address from;\n address to;\n bool isCreation;\n uint256 value;\n uint256 mint;\n uint64 gasLimit;\n bytes data;\n bytes32 l1BlockHash;\n uint256 logIndex;\n }\n\n /**\n * @notice Struct representing a withdrawal transaction.\n *\n * @custom:field nonce Nonce of the withdrawal transaction\n * @custom:field sender Address of the sender of the transaction.\n * @custom:field target Address of the recipient of the transaction.\n * @custom:field value Value to send to the recipient.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n */\n struct WithdrawalTransaction {\n uint256 nonce;\n address sender;\n address target;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPReader.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\n/**\n * @custom:attribution https://github.com/hamdiallam/Solidity-RLP\n * @title RLPReader\n * @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted\n * from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with\n * various tweaks to improve readability.\n */\nlibrary RLPReader {\n /**\n * Custom pointer type to avoid confusion between pointers and uint256s.\n */\n type MemoryPointer is uint256;\n\n /**\n * @notice RLP item types.\n *\n * @custom:value DATA_ITEM Represents an RLP data item (NOT a list).\n * @custom:value LIST_ITEM Represents an RLP list item.\n */\n enum RLPItemType {\n DATA_ITEM,\n LIST_ITEM\n }\n\n /**\n * @notice Struct representing an RLP item.\n *\n * @custom:field length Length of the RLP item.\n * @custom:field ptr Pointer to the RLP item in memory.\n */\n struct RLPItem {\n uint256 length;\n MemoryPointer ptr;\n }\n\n /**\n * @notice Max list length that this library will accept.\n */\n uint256 internal constant MAX_LIST_LENGTH = 32;\n\n /**\n * @notice Converts bytes to a reference to memory position and length.\n *\n * @param _in Input bytes to convert.\n *\n * @return Output memory reference.\n */\n function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n // Empty arrays are not RLP items.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr;\n assembly {\n ptr := add(_in, 32)\n }\n\n return RLPItem({ length: _in.length, ptr: ptr });\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.LIST_ITEM,\n \"RLPReader: decoded item type for list is not a list item\"\n );\n\n require(\n listOffset + listLength == _in.length,\n \"RLPReader: list item has an invalid data remainder\"\n );\n\n // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n // writing to the length. Since we can't know the number of RLP items without looping over\n // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n // simply set a reasonable maximum list length and decrease the size before we finish.\n RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n uint256 itemCount = 0;\n uint256 offset = listOffset;\n while (offset < _in.length) {\n (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n RLPItem({\n length: _in.length - offset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n })\n );\n\n // We don't need to check itemCount < out.length explicitly because Solidity already\n // handles this check on our behalf, we'd just be wasting gas.\n out[itemCount] = RLPItem({\n length: itemLength + itemOffset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n });\n\n itemCount += 1;\n offset += itemOffset + itemLength;\n }\n\n // Decrease the array size to match the actual item count.\n assembly {\n mstore(out, itemCount)\n }\n\n return out;\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n return readList(toRLPItem(_in));\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.DATA_ITEM,\n \"RLPReader: decoded item type for bytes is not a data item\"\n );\n\n require(\n _in.length == itemOffset + itemLength,\n \"RLPReader: bytes value contains an invalid remainder\"\n );\n\n return _copy(_in.ptr, itemOffset, itemLength);\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n return readBytes(toRLPItem(_in));\n }\n\n /**\n * @notice Reads the raw bytes of an RLP item.\n *\n * @param _in RLP item to read.\n *\n * @return Raw RLP bytes.\n */\n function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n return _copy(_in.ptr, 0, _in.length);\n }\n\n /**\n * @notice Decodes the length of an RLP item.\n *\n * @param _in RLP item to decode.\n *\n * @return Offset of the encoded data.\n * @return Length of the encoded data.\n * @return RLP item type (LIST_ITEM or DATA_ITEM).\n */\n function _decodeLength(RLPItem memory _in)\n private\n pure\n returns (\n uint256,\n uint256,\n RLPItemType\n )\n {\n // Short-circuit if there's nothing to decode, note that we perform this check when\n // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass\n // that function and create an RLP item directly. So we need to check this anyway.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr = _in.ptr;\n uint256 prefix;\n assembly {\n prefix := byte(0, mload(ptr))\n }\n\n if (prefix <= 0x7f) {\n // Single byte.\n return (0, 1, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xb7) {\n // Short string.\n\n // slither-disable-next-line variable-scope\n uint256 strLen = prefix - 0x80;\n\n require(\n _in.length > strLen,\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n strLen != 1 || firstByteOfContent >= 0x80,\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n\n return (1, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xbf) {\n // Long string.\n uint256 lenOfStrLen = prefix - 0xb7;\n\n require(\n _in.length > lenOfStrLen,\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n\n uint256 strLen;\n assembly {\n strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))\n }\n\n require(\n strLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long string)\"\n );\n\n require(\n _in.length > lenOfStrLen + strLen,\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n\n return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xf7) {\n // Short list.\n // slither-disable-next-line variable-scope\n uint256 listLen = prefix - 0xc0;\n\n require(\n _in.length > listLen,\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n\n return (1, listLen, RLPItemType.LIST_ITEM);\n } else {\n // Long list.\n uint256 lenOfListLen = prefix - 0xf7;\n\n require(\n _in.length > lenOfListLen,\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long list)\"\n );\n\n uint256 listLen;\n assembly {\n listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))\n }\n\n require(\n listLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long list)\"\n );\n\n require(\n _in.length > lenOfListLen + listLen,\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n\n return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n }\n }\n\n /**\n * @notice Copies the bytes from a memory location.\n *\n * @param _src Pointer to the location to read from.\n * @param _offset Offset to start reading from.\n * @param _length Number of bytes to read.\n *\n * @return Copied bytes.\n */\n function _copy(\n MemoryPointer _src,\n uint256 _offset,\n uint256 _length\n ) private pure returns (bytes memory) {\n bytes memory out = new bytes(_length);\n if (_length == 0) {\n return out;\n }\n\n // Mostly based on Solidity's copy_memory_to_memory:\n // solhint-disable max-line-length\n // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114\n uint256 src = MemoryPointer.unwrap(_src) + _offset;\n assembly {\n let dest := add(out, 32)\n let i := 0\n for {\n\n } lt(i, _length) {\n i := add(i, 32)\n } {\n mstore(add(dest, i), mload(add(src, i)))\n }\n\n if gt(i, _length) {\n mstore(add(dest, _length), 0)\n }\n }\n\n return out;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPWriter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\n * @title RLPWriter\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\n * RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\n * modifications to improve legibility.\n */\nlibrary RLPWriter {\n /**\n * @notice RLP encodes a byte string.\n *\n * @param _in The byte string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_in.length == 1 && uint8(_in[0]) < 128) {\n encoded = _in;\n } else {\n encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n }\n\n return encoded;\n }\n\n /**\n * @notice RLP encodes a list of RLP encoded byte byte strings.\n *\n * @param _in The list of RLP encoded byte strings.\n *\n * @return The RLP encoded list of items in bytes.\n */\n function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n bytes memory list = _flatten(_in);\n return abi.encodePacked(_writeLength(list.length, 192), list);\n }\n\n /**\n * @notice RLP encodes a string.\n *\n * @param _in The string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeString(string memory _in) internal pure returns (bytes memory) {\n return writeBytes(bytes(_in));\n }\n\n /**\n * @notice RLP encodes an address.\n *\n * @param _in The address to encode.\n *\n * @return The RLP encoded address in bytes.\n */\n function writeAddress(address _in) internal pure returns (bytes memory) {\n return writeBytes(abi.encodePacked(_in));\n }\n\n /**\n * @notice RLP encodes a uint.\n *\n * @param _in The uint256 to encode.\n *\n * @return The RLP encoded uint256 in bytes.\n */\n function writeUint(uint256 _in) internal pure returns (bytes memory) {\n return writeBytes(_toBinary(_in));\n }\n\n /**\n * @notice RLP encodes a bool.\n *\n * @param _in The bool to encode.\n *\n * @return The RLP encoded bool in bytes.\n */\n function writeBool(bool _in) internal pure returns (bytes memory) {\n bytes memory encoded = new bytes(1);\n encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n return encoded;\n }\n\n /**\n * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\n *\n * @param _len The length of the string or the payload.\n * @param _offset 128 if item is string, 192 if item is list.\n *\n * @return RLP encoded bytes.\n */\n function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_len < 56) {\n encoded = new bytes(1);\n encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n } else {\n uint256 lenLen;\n uint256 i = 1;\n while (_len / i != 0) {\n lenLen++;\n i *= 256;\n }\n\n encoded = new bytes(lenLen + 1);\n encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n for (i = 1; i <= lenLen; i++) {\n encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n }\n }\n\n return encoded;\n }\n\n /**\n * @notice Encode integer in big endian binary form with no leading zeroes.\n *\n * @param _x The integer to encode.\n *\n * @return RLP encoded bytes.\n */\n function _toBinary(uint256 _x) private pure returns (bytes memory) {\n bytes memory b = abi.encodePacked(_x);\n\n uint256 i = 0;\n for (; i < 32; i++) {\n if (b[i] != 0) {\n break;\n }\n }\n\n bytes memory res = new bytes(32 - i);\n for (uint256 j = 0; j < res.length; j++) {\n res[j] = b[i++];\n }\n\n return res;\n }\n\n /**\n * @custom:attribution https://github.com/Arachnid/solidity-stringutils\n * @notice Copies a piece of memory to another location.\n *\n * @param _dest Destination location.\n * @param _src Source location.\n * @param _len Length of memory to copy.\n */\n function _memcpy(\n uint256 _dest,\n uint256 _src,\n uint256 _len\n ) private pure {\n uint256 dest = _dest;\n uint256 src = _src;\n uint256 len = _len;\n\n for (; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n uint256 mask;\n unchecked {\n mask = 256**(32 - len) - 1;\n }\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /**\n * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\n * @notice Flattens a list of byte strings into one byte string.\n *\n * @param _list List of byte strings to flatten.\n *\n * @return The flattened byte string.\n */\n function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n if (_list.length == 0) {\n return new bytes(0);\n }\n\n uint256 len;\n uint256 i = 0;\n for (; i < _list.length; i++) {\n len += _list[i].length;\n }\n\n bytes memory flattened = new bytes(len);\n uint256 flattenedPtr;\n assembly {\n flattenedPtr := add(flattened, 0x20)\n }\n\n for (i = 0; i < _list.length; i++) {\n bytes memory item = _list[i];\n\n uint256 listPtr;\n assembly {\n listPtr := add(item, 0x20)\n }\n\n _memcpy(flattenedPtr, listPtr, item.length);\n flattenedPtr += _list[i].length;\n }\n\n return flattened;\n }\n}\n" - }, - "contracts/libraries/trie/MerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Bytes } from \"../Bytes.sol\";\nimport { RLPReader } from \"../rlp/RLPReader.sol\";\n\n/**\n * @title MerkleTrie\n * @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie\n * inclusion proofs. By default, this library assumes a hexary trie. One can change the\n * trie radix constant to support other trie radixes.\n */\nlibrary MerkleTrie {\n /**\n * @notice Struct representing a node in the trie.\n *\n * @custom:field encoded The RLP-encoded node.\n * @custom:field decoded The RLP-decoded node.\n */\n struct TrieNode {\n bytes encoded;\n RLPReader.RLPItem[] decoded;\n }\n\n /**\n * @notice Determines the number of elements per branch node.\n */\n uint256 internal constant TREE_RADIX = 16;\n\n /**\n * @notice Branch nodes have TREE_RADIX elements and one value element.\n */\n uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\n\n /**\n * @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.\n */\n uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\n\n /**\n * @notice Prefix for even-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_EVEN = 0;\n\n /**\n * @notice Prefix for odd-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_ODD = 1;\n\n /**\n * @notice Prefix for even-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_EVEN = 2;\n\n /**\n * @notice Prefix for odd-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_ODD = 3;\n\n /**\n * @notice Verifies a proof that a given key/value pair is present in the trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n return Bytes.equal(_value, get(_key, _proof, _root));\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n require(_key.length > 0, \"MerkleTrie: empty key\");\n\n TrieNode[] memory proof = _parseProof(_proof);\n bytes memory key = Bytes.toNibbles(_key);\n bytes memory currentNodeID = abi.encodePacked(_root);\n uint256 currentKeyIndex = 0;\n\n // Proof is top-down, so we start at the first element (root).\n for (uint256 i = 0; i < proof.length; i++) {\n TrieNode memory currentNode = proof[i];\n\n // Key index should never exceed total key length or we'll be out of bounds.\n require(\n currentKeyIndex <= key.length,\n \"MerkleTrie: key index exceeds total key length\"\n );\n\n if (currentKeyIndex == 0) {\n // First proof element is always the root node.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid root hash\"\n );\n } else if (currentNode.encoded.length >= 32) {\n // Nodes 32 bytes or larger are hashed inside branch nodes.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid large internal hash\"\n );\n } else {\n // Nodes smaller than 32 bytes aren't hashed.\n require(\n Bytes.equal(currentNode.encoded, currentNodeID),\n \"MerkleTrie: invalid internal node hash\"\n );\n }\n\n if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\n if (currentKeyIndex == key.length) {\n // Value is the last element of the decoded list (for branch nodes). There's\n // some ambiguity in the Merkle trie specification because bytes(0) is a\n // valid value to place into the trie, but for branch nodes bytes(0) can exist\n // even when the value wasn't explicitly placed there. Geth treats a value of\n // bytes(0) as \"key does not exist\" and so we do the same.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (branch)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (branch)\"\n );\n\n return value;\n } else {\n // We're not at the end of the key yet.\n // Figure out what the next node ID should be and continue.\n uint8 branchKey = uint8(key[currentKeyIndex]);\n RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\n currentNodeID = _getNodeID(nextNode);\n currentKeyIndex += 1;\n }\n } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\n bytes memory path = _getNodePath(currentNode);\n uint8 prefix = uint8(path[0]);\n uint8 offset = 2 - (prefix % 2);\n bytes memory pathRemainder = Bytes.slice(path, offset);\n bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);\n uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\n\n // Whether this is a leaf node or an extension node, the path remainder MUST be a\n // prefix of the key remainder (or be equal to the key remainder) or the proof is\n // considered invalid.\n require(\n pathRemainder.length == sharedNibbleLength,\n \"MerkleTrie: path remainder must share all nibbles with key\"\n );\n\n if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\n // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid,\n // the key remainder must be exactly equal to the path remainder. We already\n // did the necessary byte comparison, so it's more efficient here to check that\n // the key remainder length equals the shared nibble length, which implies\n // equality with the path remainder (since we already did the same check with\n // the path remainder and the shared nibble length).\n require(\n keyRemainder.length == sharedNibbleLength,\n \"MerkleTrie: key remainder must be identical to path remainder\"\n );\n\n // Our Merkle Trie is designed specifically for the purposes of the Ethereum\n // state trie. Empty values are not allowed in the state trie, so we can safely\n // say that if the value is empty, the key should not exist and the proof is\n // invalid.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[1]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (leaf)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (leaf)\"\n );\n\n return value;\n } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\n // Prefix of 0 or 1 means this is an extension node. We move onto the next node\n // in the proof and increment the key index by the length of the path remainder\n // which is equal to the shared nibble length.\n currentNodeID = _getNodeID(currentNode.decoded[1]);\n currentKeyIndex += sharedNibbleLength;\n } else {\n revert(\"MerkleTrie: received a node with an unknown prefix\");\n }\n } else {\n revert(\"MerkleTrie: received an unparseable node\");\n }\n }\n\n revert(\"MerkleTrie: ran out of proof elements\");\n }\n\n /**\n * @notice Parses an array of proof elements into a new array that contains both the original\n * encoded element and the RLP-decoded element.\n *\n * @param _proof Array of proof elements to parse.\n *\n * @return Proof parsed into easily accessible structs.\n */\n function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {\n uint256 length = _proof.length;\n TrieNode[] memory proof = new TrieNode[](length);\n for (uint256 i = 0; i < length; ) {\n proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });\n unchecked {\n ++i;\n }\n }\n return proof;\n }\n\n /**\n * @notice Picks out the ID for a node. Node ID is referred to as the \"hash\" within the\n * specification, but nodes < 32 bytes are not actually hashed.\n *\n * @param _node Node to pull an ID for.\n *\n * @return ID for the node, depending on the size of its contents.\n */\n function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {\n return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);\n }\n\n /**\n * @notice Gets the path for a leaf or extension node.\n *\n * @param _node Node to get a path for.\n *\n * @return Node path, converted to an array of nibbles.\n */\n function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {\n return Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0]));\n }\n\n /**\n * @notice Utility; determines the number of nibbles shared between two nibble arrays.\n *\n * @param _a First nibble array.\n * @param _b Second nibble array.\n *\n * @return Number of shared nibbles.\n */\n function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\n private\n pure\n returns (uint256)\n {\n uint256 shared;\n uint256 max = (_a.length < _b.length) ? _a.length : _b.length;\n for (; shared < max && _a[shared] == _b[shared]; ) {\n unchecked {\n ++shared;\n }\n }\n return shared;\n }\n}\n" - }, - "contracts/libraries/trie/SecureMerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/* Library Imports */\nimport { MerkleTrie } from \"./MerkleTrie.sol\";\n\n/**\n * @title SecureMerkleTrie\n * @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input\n * keys. Ethereum's state trie hashes input keys before storing them.\n */\nlibrary SecureMerkleTrie {\n /**\n * @notice Verifies a proof that a given key/value pair is present in the Merkle trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.get(key, _proof, _root);\n }\n\n /**\n * @notice Computes the hashed version of the input key.\n *\n * @param _key Key to hash.\n *\n * @return Hashed version of the key.\n */\n function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {\n return abi.encodePacked(keccak256(_key));\n }\n}\n" - }, - "contracts/test/AddressAliasHelper.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract AddressAliasHelper_Test is Test {\n function testFuzz_applyAndUndo_succeeds(address _address) external {\n address aliased = AddressAliasHelper.applyL1ToL2Alias(_address);\n address unaliased = AddressAliasHelper.undoL1ToL2Alias(aliased);\n assertEq(_address, unaliased);\n }\n}\n" - }, - "contracts/test/BenchmarkTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test } from \"forge-std/Test.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport \"./CommonTest.t.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\nuint128 constant INITIAL_BASE_FEE = 1_000_000_000;\n\n// Free function for setting the prevBaseFee param in the OptimismPortal.\nfunction setPrevBaseFee(\n Vm _vm,\n address _op,\n uint128 _prevBaseFee\n) {\n _vm.store(\n address(_op),\n bytes32(uint256(1)),\n bytes32(\n abi.encode(\n ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: 0,\n prevBlockNum: uint64(block.number)\n })\n )\n )\n );\n}\n\n// Tests for obtaining pure gas cost estimates for commonly used functions.\n// The objective with these benchmarks is to strip down the actual test functions\n// so that they are nothing more than the call we want measure the gas cost of.\n// In order to achieve this we make no assertions, and handle everything else in the setUp()\n// function.\ncontract GasBenchMark_OptimismPortal is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n bytes32 _outputRoot;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n\n // Get withdrawal proof data we can use for testing.\n bytes32 _storageRoot;\n bytes32 _stateRoot;\n (_stateRoot, _storageRoot, _outputRoot, , _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n op.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n function test_depositTransaction_benchmark() external {\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_depositTransaction_benchmark_1() external {\n setPrevBaseFee(vm, address(op), INITIAL_BASE_FEE);\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_proveWithdrawalTransaction_benchmark() external {\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n}\n\ncontract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {\n function test_sendMessage_benchmark_0() external {\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n\n function test_sendMessage_benchmark_1() external {\n setPrevBaseFee(vm, address(op), INITIAL_BASE_FEE);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), alice, 100000, true);\n vm.startPrank(alice, alice);\n }\n\n function test_depositETH_benchmark_0() external {\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositETH_benchmark_1() external {\n setPrevBaseFee(vm, address(op), INITIAL_BASE_FEE);\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositERC20_benchmark_0() external {\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositERC20_benchmark_1() external {\n setPrevBaseFee(vm, address(op), INITIAL_BASE_FEE);\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), address(L1Bridge), 100, true);\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.startPrank(address(L1Bridge.messenger()));\n vm.deal(address(L1Bridge.messenger()), 100);\n }\n\n function test_finalizeETHWithdrawal_benchmark() external {\n // TODO: Make this more accurate. It is underestimating the cost because it pranks\n // the call coming from the messenger, which bypasses the portal\n // and oracle.\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer {\n uint256 nextBlockNumber;\n\n function setUp() public override {\n super.setUp();\n nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.startPrank(proposer);\n }\n\n function test_proposeL2Output_benchmark() external {\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n}\n" - }, - "contracts/test/Bytes.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Bytes } from \"../libraries/Bytes.sol\";\n\n/// @title BytesTest\ncontract Bytes_Test is Test {\n /// @dev Tests that the `slice` function works as expected when starting from\n /// index 0.\n function test_slice_fromZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check if all possible slices starting from index 0 are correct.\n assertEq(Bytes.slice(input, 0, 0), hex\"\");\n assertEq(Bytes.slice(input, 0, 1), hex\"11\");\n assertEq(Bytes.slice(input, 0, 2), hex\"1122\");\n assertEq(Bytes.slice(input, 0, 3), hex\"112233\");\n assertEq(Bytes.slice(input, 0, 4), hex\"11223344\");\n assertEq(Bytes.slice(input, 0, 5), hex\"1122334455\");\n assertEq(Bytes.slice(input, 0, 6), hex\"112233445566\");\n assertEq(Bytes.slice(input, 0, 7), hex\"11223344556677\");\n assertEq(Bytes.slice(input, 0, 8), hex\"1122334455667788\");\n assertEq(Bytes.slice(input, 0, 9), hex\"112233445566778899\");\n assertEq(Bytes.slice(input, 0, 10), hex\"11223344556677889900\");\n }\n\n /// @dev Tests that the `slice` function works as expected when starting from\n /// indexes [1, 9] with lengths [1, 9], in reverse order.\n function test_slice_fromNonZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check correctness of slices starting from indexes [1, 9]\n // and spanning [1, 9] bytes, in reverse order\n assertEq(Bytes.slice(input, 9, 1), hex\"00\");\n assertEq(Bytes.slice(input, 8, 2), hex\"9900\");\n assertEq(Bytes.slice(input, 7, 3), hex\"889900\");\n assertEq(Bytes.slice(input, 6, 4), hex\"77889900\");\n assertEq(Bytes.slice(input, 5, 5), hex\"6677889900\");\n assertEq(Bytes.slice(input, 4, 6), hex\"556677889900\");\n assertEq(Bytes.slice(input, 3, 7), hex\"44556677889900\");\n assertEq(Bytes.slice(input, 2, 8), hex\"3344556677889900\");\n assertEq(Bytes.slice(input, 1, 9), hex\"223344556677889900\");\n }\n\n /// @dev Tests that the `slice` function works as expected when slicing between\n /// multiple words in memory. In this case, we test that a 2 byte slice between\n /// the 32nd byte of the first word and the 1st byte of the second word is\n /// correct.\n function test_slice_acrossWords_works() public {\n bytes\n memory input = hex\"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000\";\n\n assertEq(Bytes.slice(input, 31, 2), hex\"1122\");\n }\n\n /// @dev Tests that the `slice` function works as expected when slicing between\n /// multiple words in memory. In this case, we test that a 34 byte slice between\n /// 3 separate words returns the correct result.\n function test_slice_acrossMultipleWords_works() public {\n bytes\n memory input = hex\"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000\";\n bytes\n memory expected = hex\"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11\";\n\n assertEq(Bytes.slice(input, 31, 34), expected);\n }\n\n /// @dev Tests that, when given an input bytes array of length `n`,\n /// the `slice` function will always revert if `_start + _length > n`.\n function testFuzz_slice_outOfBounds_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // We want a valid start index and a length that will not overflow.\n vm.assume(_start < _input.length && _length < type(uint256).max - 31);\n // But, we want an invalid slice length.\n vm.assume(_start + _length > _input.length);\n\n vm.expectRevert(\"slice_outOfBounds\");\n Bytes.slice(_input, _start, _length);\n }\n\n /// @dev Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,\n /// the `slice` function reverts.\n function testFuzz_slice_lengthOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that the `_length` will overflow if a number >= 31 is added to it.\n vm.assume(_length > type(uint256).max - 31);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /// @dev Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,\n /// the `slice` function reverts.\n function testFuzz_slice_rangeOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that `_length` is a realistic length of a slice. This is to make sure\n // we revert on the correct require statement.\n vm.assume(_length < _input.length);\n // Ensure that `_start` will overflow if `_length` is added to it.\n vm.assume(_start > type(uint256).max - _length);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /// @dev Tests that, given an input of 5 bytes, the `toNibbles` function returns\n /// an array of 10 nibbles corresponding to the input data.\n function test_toNibbles_expectedResult5Bytes_works() public {\n bytes memory input = hex\"1234567890\";\n bytes memory expected = hex\"01020304050607080900\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /// @dev Tests that, given an input of 128 bytes, the `toNibbles` function returns\n /// an array of 256 nibbles corresponding to the input data.\n /// This test exists to ensure that, given a large input, the `toNibbles` function\n /// works as expected.\n function test_toNibbles_expectedResult128Bytes_works() public {\n bytes\n memory input = hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f\";\n bytes\n memory expected = hex\"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /// @dev Tests that, given an input of 0 bytes, the `toNibbles` function returns\n /// a zero length array.\n function test_toNibbles_zeroLengthInput_works() public {\n bytes memory input = hex\"\";\n bytes memory expected = hex\"\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length, 0);\n assertEq(expected.length, 0);\n assertEq(actual.length, 0);\n assertEq(actual, expected);\n }\n\n /// @dev Test that the `toNibbles` function in the `Bytes` library is equivalent to the\n /// Yul implementation.\n function testDiff_toNibbles_succeeds(bytes memory _input) public {\n assertEq(Bytes.toNibbles(_input), toNibblesYul(_input));\n }\n\n /// @dev Test that the `equal` function in the `Bytes` library returns `false` if given\n /// two non-equal byte arrays.\n function testFuzz_equal_notEqual_works(bytes memory _a, bytes memory _b) public {\n vm.assume(!manualEq(_a, _b));\n assertFalse(Bytes.equal(_a, _b));\n }\n\n /// @dev Test whether or not the `equal` function in the `Bytes` library is equivalent\n /// to manually checking equality of the two dynamic `bytes` arrays in memory.\n function testDiff_equal_works(bytes memory _a, bytes memory _b) public {\n assertEq(Bytes.equal(_a, _b), manualEq(_a, _b));\n }\n\n ////////////////////////////////////////////////////////////////\n // HELPERS //\n ////////////////////////////////////////////////////////////////\n\n /// @dev Utility function to manually check equality of two dynamic `bytes` arrays in memory.\n function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) {\n bool _eq;\n assembly {\n _eq := and(\n // Check if the contents of the two bytes arrays are equal in memory.\n eq(keccak256(add(0x20, _a), mload(_a)), keccak256(add(0x20, _b), mload(_b))),\n // Check if the length of the two bytes arrays are equal in memory.\n // This is redundant given the above check, but included for completeness.\n eq(mload(_a), mload(_b))\n )\n }\n return _eq;\n }\n\n /// @dev Utility function to diff test Solidity version of `toNibbles`\n function toNibblesYul(bytes memory _bytes) internal pure returns (bytes memory) {\n // Allocate memory for the `nibbles` array.\n bytes memory nibbles = new bytes(_bytes.length << 1);\n\n assembly {\n // Load the length of the passed bytes array from memory\n let bytesLength := mload(_bytes)\n\n // Store the memory offset of the _bytes array's contents on the stack\n let bytesStart := add(_bytes, 0x20)\n\n // Store the memory offset of the nibbles array's contents on the stack\n let nibblesStart := add(nibbles, 0x20)\n\n // Loop through each byte in the input array\n for {\n let i := 0x00\n } lt(i, bytesLength) {\n i := add(i, 0x01)\n } {\n // Get the starting offset of the next 2 bytes in the nibbles array\n let offset := add(nibblesStart, shl(0x01, i))\n\n // Load the byte at the current index within the `_bytes` array\n let b := byte(0x00, mload(add(bytesStart, i)))\n\n // Pull out the first nibble and store it in the new array\n mstore8(offset, shr(0x04, b))\n // Pull out the second nibble and store it in the new array\n mstore8(add(offset, 0x01), and(b, 0x0F))\n }\n }\n\n return nibbles;\n }\n}\n" - }, - "contracts/test/CommonTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test, StdUtils } from \"forge-std/Test.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { IL1ChugSplashDeployer } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\ncontract CommonTest is Test {\n address alice = address(128);\n address bob = address(256);\n address multisig = address(512);\n\n address immutable ZERO_ADDRESS = address(0);\n address immutable NON_ZERO_ADDRESS = address(1);\n uint256 immutable NON_ZERO_VALUE = 100;\n uint256 immutable ZERO_VALUE = 0;\n uint64 immutable NON_ZERO_GASLIMIT = 50000;\n bytes32 nonZeroHash = keccak256(abi.encode(\"NON_ZERO\"));\n bytes NON_ZERO_DATA = hex\"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000\";\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n FFIInterface ffi;\n\n function _setUp() public {\n // Give alice and bob some ETH\n vm.deal(alice, 1 << 16);\n vm.deal(bob, 1 << 16);\n vm.deal(multisig, 1 << 16);\n\n vm.label(alice, \"alice\");\n vm.label(bob, \"bob\");\n vm.label(multisig, \"multisig\");\n\n // Make sure we have a non-zero base fee\n vm.fee(1000000000);\n\n ffi = new FFIInterface();\n }\n\n function emitTransactionDeposited(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) internal {\n emit TransactionDeposited(\n _from,\n _to,\n 0,\n abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)\n );\n }\n}\n\ncontract L2OutputOracle_Initializer is CommonTest {\n // Test target\n L2OutputOracle oracle;\n L2OutputOracle oracleImpl;\n\n L2ToL1MessagePasser messagePasser =\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));\n\n // Constructor arguments\n address internal proposer = 0x000000000000000000000000000000000000AbBa;\n address internal owner = 0x000000000000000000000000000000000000ACDC;\n uint256 internal submissionInterval = 1800;\n uint256 internal l2BlockTime = 2;\n uint256 internal startingBlockNumber = 200;\n uint256 internal startingTimestamp = 1000;\n\n // Test data\n uint256 initL1Time;\n\n // Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output\n function warpToProposeTime(uint256 _nextBlockNumber) public {\n vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1);\n }\n\n function setUp() public virtual {\n _setUp();\n\n // By default the first block has timestamp and number zero, which will cause underflows in the\n // tests, so we'll move forward to these block values.\n initL1Time = startingTimestamp + 1;\n vm.warp(initL1Time);\n vm.roll(startingBlockNumber);\n // Deploy the L2OutputOracle and transfer owernship to the proposer\n oracleImpl = new L2OutputOracle(\n submissionInterval,\n l2BlockTime,\n startingBlockNumber,\n startingTimestamp,\n proposer,\n owner\n );\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(oracleImpl),\n abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp))\n );\n oracle = L2OutputOracle(address(proxy));\n vm.label(address(oracle), \"L2OutputOracle\");\n\n // Set the L2ToL1MessagePasser at the correct address\n vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code);\n\n vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, \"L2ToL1MessagePasser\");\n }\n}\n\ncontract Portal_Initializer is L2OutputOracle_Initializer {\n // Test target\n OptimismPortal opImpl;\n OptimismPortal op;\n\n function setUp() public virtual override {\n L2OutputOracle_Initializer.setUp();\n\n opImpl = new OptimismPortal(oracle, 7 days);\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(opImpl),\n abi.encodeWithSelector(OptimismPortal.initialize.selector)\n );\n op = OptimismPortal(payable(address(proxy)));\n }\n}\n\ncontract Messenger_Initializer is L2OutputOracle_Initializer {\n OptimismPortal op;\n AddressManager addressManager;\n L1CrossDomainMessenger L1Messenger;\n L2CrossDomainMessenger L2Messenger =\n L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);\n\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event RelayedMessage(bytes32 indexed msgHash);\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 mint,\n uint256 value,\n uint64 gasLimit,\n bool isCreation,\n bytes data\n );\n\n event WithdrawalFinalized(bytes32 indexed, bool success);\n\n event WhatHappened(bool success, bytes returndata);\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the OptimismPortal\n op = new OptimismPortal(oracle, 7 days);\n vm.label(address(op), \"OptimismPortal\");\n\n // Deploy the address manager\n vm.prank(multisig);\n addressManager = new AddressManager();\n\n // Setup implementation\n L1CrossDomainMessenger L1MessengerImpl = new L1CrossDomainMessenger(op);\n\n // Setup the address manager and proxy\n vm.prank(multisig);\n addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(L1MessengerImpl));\n ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(\n addressManager,\n \"OVM_L1CrossDomainMessenger\"\n );\n L1Messenger = L1CrossDomainMessenger(address(proxy));\n L1Messenger.initialize(alice);\n\n vm.etch(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n address(new L2CrossDomainMessenger(address(L1Messenger))).code\n );\n\n L2Messenger.initialize();\n\n // Label addresses\n vm.label(address(addressManager), \"AddressManager\");\n vm.label(address(L1MessengerImpl), \"L1CrossDomainMessenger_Impl\");\n vm.label(address(L1Messenger), \"L1CrossDomainMessenger_Proxy\");\n vm.label(Predeploys.LEGACY_ERC20_ETH, \"LegacyERC20ETH\");\n vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, \"L2CrossDomainMessenger\");\n\n vm.label(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n \"L1CrossDomainMessenger_aliased\"\n );\n }\n}\n\ncontract Bridge_Initializer is Messenger_Initializer {\n L1StandardBridge L1Bridge;\n L2StandardBridge L2Bridge;\n OptimismMintableERC20Factory L2TokenFactory;\n OptimismMintableERC20Factory L1TokenFactory;\n ERC20 L1Token;\n ERC20 BadL1Token;\n OptimismMintableERC20 L2Token;\n ERC20 NativeL2Token;\n ERC20 BadL2Token;\n OptimismMintableERC20 RemoteL1Token;\n\n event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data\n );\n\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFailed(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.label(Predeploys.L2_STANDARD_BRIDGE, \"L2StandardBridge\");\n vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, \"OptimismMintableERC20Factory\");\n\n // Deploy the L1 bridge and initialize it with the address of the\n // L1CrossDomainMessenger\n L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig);\n vm.mockCall(\n multisig,\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector),\n abi.encode(true)\n );\n vm.startPrank(multisig);\n proxy.setCode(address(new L1StandardBridge(payable(address(L1Messenger)))).code);\n vm.clearMockedCalls();\n address L1Bridge_Impl = proxy.getImplementation();\n vm.stopPrank();\n\n L1Bridge = L1StandardBridge(payable(address(proxy)));\n\n vm.label(address(proxy), \"L1StandardBridge_Proxy\");\n vm.label(address(L1Bridge_Impl), \"L1StandardBridge_Impl\");\n\n // Deploy the L2StandardBridge, move it to the correct predeploy\n // address and then initialize it\n L2StandardBridge l2B = new L2StandardBridge(payable(proxy));\n vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(l2B).code);\n L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));\n\n // Set up the L2 mintable token factory\n OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(\n Predeploys.L2_STANDARD_BRIDGE\n );\n vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code);\n L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);\n\n vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code);\n\n L1Token = new ERC20(\"Native L1 Token\", \"L1T\");\n\n // Deploy the L2 ERC20 now\n L2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(L1Token),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n BadL2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n NativeL2Token = new ERC20(\"Native L2 Token\", \"L2T\");\n L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge));\n\n RemoteL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(NativeL2Token),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n\n BadL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n }\n}\n\ncontract ERC721Bridge_Initializer is Messenger_Initializer {\n L1ERC721Bridge L1Bridge;\n L2ERC721Bridge L2Bridge;\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the L1ERC721Bridge.\n L1Bridge = new L1ERC721Bridge(address(L1Messenger), Predeploys.L2_ERC721_BRIDGE);\n\n // Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.\n vm.etch(\n Predeploys.L2_ERC721_BRIDGE,\n address(new L2ERC721Bridge(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(L1Bridge)))\n .code\n );\n\n // Set up a reference to the L2ERC721Bridge.\n L2Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);\n\n // Label the L1 and L2 bridges.\n vm.label(address(L1Bridge), \"L1ERC721Bridge\");\n vm.label(address(L2Bridge), \"L2ERC721Bridge\");\n }\n}\n\ncontract FFIInterface is Test {\n function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx)\n external\n returns (\n bytes32,\n bytes32,\n bytes32,\n bytes32,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](9);\n cmds[0] = \"node\";\n cmds[1] = \"dist/scripts/differential-testing.js\";\n cmds[2] = \"getProveWithdrawalTransactionInputs\";\n cmds[3] = vm.toString(_tx.nonce);\n cmds[4] = vm.toString(_tx.sender);\n cmds[5] = vm.toString(_tx.target);\n cmds[6] = vm.toString(_tx.value);\n cmds[7] = vm.toString(_tx.gasLimit);\n cmds[8] = vm.toString(_tx.data);\n\n bytes memory result = vm.ffi(cmds);\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[]));\n\n return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof);\n }\n\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](9);\n cmds[0] = \"node\";\n cmds[1] = \"dist/scripts/differential-testing.js\";\n cmds[2] = \"hashCrossDomainMessage\";\n cmds[3] = vm.toString(_nonce);\n cmds[4] = vm.toString(_sender);\n cmds[5] = vm.toString(_target);\n cmds[6] = vm.toString(_value);\n cmds[7] = vm.toString(_gasLimit);\n cmds[8] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashWithdrawal(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](9);\n cmds[0] = \"node\";\n cmds[1] = \"dist/scripts/differential-testing.js\";\n cmds[2] = \"hashWithdrawal\";\n cmds[3] = vm.toString(_nonce);\n cmds[4] = vm.toString(_sender);\n cmds[5] = vm.toString(_target);\n cmds[6] = vm.toString(_value);\n cmds[7] = vm.toString(_gasLimit);\n cmds[8] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashOutputRootProof(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external returns (bytes32) {\n string[] memory cmds = new string[](7);\n cmds[0] = \"node\";\n cmds[1] = \"dist/scripts/differential-testing.js\";\n cmds[2] = \"hashOutputRootProof\";\n cmds[3] = Strings.toHexString(uint256(_version));\n cmds[4] = Strings.toHexString(uint256(_stateRoot));\n cmds[5] = Strings.toHexString(uint256(_messagePasserStorageRoot));\n cmds[6] = Strings.toHexString(uint256(_latestBlockhash));\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashDepositTransaction(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint256 _logIndex\n ) external returns (bytes32) {\n string[] memory cmds = new string[](11);\n cmds[0] = \"node\";\n cmds[1] = \"dist/scripts/differential-testing.js\";\n cmds[2] = \"hashDepositTransaction\";\n cmds[3] = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n cmds[4] = vm.toString(_logIndex);\n cmds[5] = vm.toString(_from);\n cmds[6] = vm.toString(_to);\n cmds[7] = vm.toString(_mint);\n cmds[8] = vm.toString(_value);\n cmds[9] = vm.toString(_gas);\n cmds[10] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function encodeDepositTransaction(Types.UserDepositTransaction calldata txn)\n external\n returns (bytes memory)\n {\n string[] memory cmds = new string[](12);\n cmds[0] = \"node\";\n cmds[1] = \"dist/scripts/differential-testing.js\";\n cmds[2] = \"encodeDepositTransaction\";\n cmds[3] = vm.toString(txn.from);\n cmds[4] = vm.toString(txn.to);\n cmds[5] = vm.toString(txn.value);\n cmds[6] = vm.toString(txn.mint);\n cmds[7] = vm.toString(txn.gasLimit);\n cmds[8] = vm.toString(txn.isCreation);\n cmds[9] = vm.toString(txn.data);\n cmds[10] = vm.toString(txn.l1BlockHash);\n cmds[11] = vm.toString(txn.logIndex);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes memory) {\n string[] memory cmds = new string[](9);\n cmds[0] = \"node\";\n cmds[1] = \"dist/scripts/differential-testing.js\";\n cmds[2] = \"encodeCrossDomainMessage\";\n cmds[3] = vm.toString(_nonce);\n cmds[4] = vm.toString(_sender);\n cmds[5] = vm.toString(_target);\n cmds[6] = vm.toString(_value);\n cmds[7] = vm.toString(_gasLimit);\n cmds[8] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) {\n string[] memory cmds = new string[](4);\n cmds[0] = \"node\";\n cmds[1] = \"dist/scripts/differential-testing.js\";\n cmds[2] = \"decodeVersionedNonce\";\n cmds[3] = vm.toString(nonce);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (uint256, uint256));\n }\n\n function getMerkleTrieFuzzCase(string memory variant)\n external\n returns (\n bytes32,\n bytes memory,\n bytes memory,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](5);\n cmds[0] = \"./test-case-generator/fuzz\";\n cmds[1] = \"-m\";\n cmds[2] = \"trie\";\n cmds[3] = \"-v\";\n cmds[4] = variant;\n\n return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[]));\n }\n}\n\n// Used for testing a future upgrade beyond the current implementations.\n// We include some variables so that we can sanity check accessing storage values after an upgrade.\ncontract NextImpl is Initializable {\n // Initializable occupies the zero-th slot.\n bytes32 slot1;\n bytes32[19] __gap;\n bytes32 slot21;\n bytes32 public constant slot21Init = bytes32(hex\"1337\");\n\n function initialize() public reinitializer(2) {\n // Slot21 is unused by an of our upgradeable contracts.\n // This is used to verify that we can access this value after an upgrade.\n slot21 = slot21Init;\n }\n}\n\ncontract Reverter {\n fallback() external {\n revert();\n }\n}\n\n// Useful for testing reentrancy guards\ncontract CallerCaller {\n event WhatHappened(bool success, bytes returndata);\n\n fallback() external {\n (bool success, bytes memory returndata) = msg.sender.call(msg.data);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n" - }, - "contracts/test/CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, CallerCaller } from \"./CommonTest.t.sol\";\n\n// CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2\n// CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract.\ncontract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {\n // Ensure that baseGas passes for the max value of _minGasLimit,\n // this is about 4 Billion.\n function test_baseGas_succeeds() external view {\n L1Messenger.baseGas(hex\"ff\", type(uint32).max);\n }\n\n // Fuzz for other values which might cause a revert in baseGas.\n function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view {\n L1Messenger.baseGas(hex\"ff\", _minGasLimit);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest, Portal_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable } from \"../L2/CrossDomainOwnable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Vm, VmSafe } from \"forge-std/Vm.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract XDomainSetter is CrossDomainOwnable {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable_Test is CommonTest {\n XDomainSetter setter;\n\n function setUp() external {\n setter = new XDomainSetter();\n }\n\n // Check that the revert message is correct\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable: caller is not the owner\");\n setter.set(1);\n }\n\n // Check that making a call can set the value properly\n function test_onlyOwner_succeeds() external {\n assertEq(setter.value(), 0);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(setter.owner()));\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n\ncontract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n\n vm.prank(alice);\n setter = new XDomainSetter();\n }\n\n function test_depositTransaction_crossDomainOwner_succeeds() external {\n vm.recordLogs();\n\n vm.prank(alice);\n op.depositTransaction(\n address(setter),\n 0,\n 10000,\n false,\n abi.encodeWithSelector(XDomainSetter.set.selector, 1)\n );\n\n // Simulate the operation of the `op-node` by parsing data\n // from logs\n VmSafe.Log[] memory logs = vm.getRecordedLogs();\n // Only 1 log emitted\n assertEq(logs.length, 1);\n\n VmSafe.Log memory log = logs[0];\n\n // It is the expected topic\n bytes32 topic = log.topics[0];\n assertEq(topic, keccak256(\"TransactionDeposited(address,address,uint256,bytes)\"));\n\n // from is indexed and the first argument to the event.\n bytes32 _from = log.topics[1];\n address from = Bytes32AddressLib.fromLast20Bytes(_from);\n\n assertEq(AddressAliasHelper.undoL1ToL2Alias(from), alice);\n\n // Make a call from the \"from\" value received from the log.\n // In theory the opaque data could be parsed from the log\n // and passed to a low level call to \"to\", but calling set\n // directly on the setter is good enough.\n vm.prank(from);\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable2.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable2 } from \"../L2/CrossDomainOwnable2.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter2 is CrossDomainOwnable2 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable2_Test is Messenger_Initializer {\n XDomainSetter2 setter;\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter2();\n }\n\n function test_onlyOwner_notMessenger_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice));\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the owner\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner2_reverts() external {\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_onlyOwner_succeeds() external {\n address owner = setter.owner();\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n owner,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter2.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/DeployerWhitelist.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { DeployerWhitelist } from \"../legacy/DeployerWhitelist.sol\";\n\ncontract DeployerWhitelist_Test is CommonTest {\n DeployerWhitelist list;\n\n function setUp() external {\n list = new DeployerWhitelist();\n }\n\n // The owner should be address(0)\n function test_owner_succeeds() external {\n assertEq(list.owner(), address(0));\n }\n\n // The storage slot for the owner must be the same\n function test_storageSlots_succeeds() external {\n vm.prank(list.owner());\n list.setOwner(address(1));\n\n assertEq(bytes32(uint256(1)), vm.load(address(list), bytes32(uint256(0))));\n }\n}\n" - }, - "contracts/test/Encoding.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract Encoding_Test is CommonTest {\n function setUp() external {\n _setUp();\n }\n\n function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external {\n (uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(\n Encoding.encodeVersionedNonce(_nonce, _version)\n );\n assertEq(version, _version);\n assertEq(nonce, _nonce);\n }\n\n function testDiff_decodeVersionedNonce_succeeds(uint240 _nonce, uint16 _version) external {\n uint256 nonce = uint256(Encoding.encodeVersionedNonce(_nonce, _version));\n (uint256 decodedNonce, uint256 decodedVersion) = ffi.decodeVersionedNonce(nonce);\n\n assertEq(_version, uint16(decodedVersion));\n\n assertEq(_nonce, uint240(decodedNonce));\n }\n\n function testDiff_encodeCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint8 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint8 version = _version % 2;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory encoding = Encoding.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n bytes memory _encoding = ffi.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n assertEq(encoding, _encoding);\n }\n\n function testDiff_encodeDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bool isCreate,\n bytes memory _data,\n uint256 _logIndex\n ) external {\n Types.UserDepositTransaction memory t = Types.UserDepositTransaction(\n _from,\n _to,\n isCreate,\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n );\n\n bytes memory txn = Encoding.encodeDepositTransaction(t);\n bytes memory _txn = ffi.encodeDepositTransaction(t);\n\n assertEq(txn, _txn);\n }\n}\n" - }, - "contracts/test/FeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { L1FeeVault } from \"../L2/L1FeeVault.sol\";\nimport { BaseFeeVault } from \"../L2/BaseFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n// Test the implementations of the FeeVault\ncontract FeeVault_Test is Bridge_Initializer {\n BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));\n L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT));\n\n address constant recipient = address(0x10000);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.BASE_FEE_VAULT, address(new BaseFeeVault(recipient)).code);\n vm.etch(Predeploys.L1_FEE_VAULT, address(new L1FeeVault(recipient)).code);\n }\n\n function test_constructor_succeeds() external {\n assertEq(baseFeeVault.RECIPIENT(), recipient);\n assertEq(l1FeeVault.RECIPIENT(), recipient);\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n}\n" - }, - "contracts/test/GasPriceOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GasPriceOracle } from \"../L2/GasPriceOracle.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract GasPriceOracle_Test is CommonTest {\n event OverheadUpdated(uint256);\n event ScalarUpdated(uint256);\n event DecimalsUpdated(uint256);\n\n GasPriceOracle gasOracle;\n L1Block l1Block;\n address depositor;\n\n // set the initial L1 context values\n uint64 constant number = 10;\n uint64 constant timestamp = 11;\n uint256 constant basefee = 100;\n bytes32 constant hash = bytes32(uint256(64));\n uint64 constant sequenceNumber = 0;\n bytes32 constant batcherHash = bytes32(uint256(777));\n uint256 constant l1FeeOverhead = 310;\n uint256 constant l1FeeScalar = 10;\n\n function setUp() external {\n // place the L1Block contract at the predeploy address\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n\n l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n depositor = l1Block.DEPOSITOR_ACCOUNT();\n\n // We are not setting the gas oracle at its predeploy\n // address for simplicity purposes. Nothing in this test\n // requires it to be at a particular address\n gasOracle = new GasPriceOracle();\n\n vm.prank(depositor);\n l1Block.setL1BlockValues({\n _number: number,\n _timestamp: timestamp,\n _basefee: basefee,\n _hash: hash,\n _sequenceNumber: sequenceNumber,\n _batcherHash: batcherHash,\n _l1FeeOverhead: l1FeeOverhead,\n _l1FeeScalar: l1FeeScalar\n });\n }\n\n function test_l1BaseFee_succeeds() external {\n assertEq(gasOracle.l1BaseFee(), basefee);\n }\n\n function test_gasPrice_succeeds() external {\n vm.fee(100);\n uint256 gasPrice = gasOracle.gasPrice();\n assertEq(gasPrice, 100);\n }\n\n function test_baseFee_succeeds() external {\n vm.fee(64);\n uint256 gasPrice = gasOracle.baseFee();\n assertEq(gasPrice, 64);\n }\n\n function test_scalar_succeeds() external {\n assertEq(gasOracle.scalar(), l1FeeScalar);\n }\n\n function test_overhead_succeeds() external {\n assertEq(gasOracle.overhead(), l1FeeOverhead);\n }\n\n function test_decimals_succeeds() external {\n assertEq(gasOracle.decimals(), 6);\n assertEq(gasOracle.DECIMALS(), 6);\n }\n\n // Removed in bedrock\n function test_setGasPrice_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setGasPrice(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n\n // Removed in bedrock\n function test_setL1BaseFee_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setL1BaseFee(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n}\n" - }, - "contracts/test/GovernanceToken.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract GovernanceToken_Test is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n\n function setUp() external {\n vm.prank(owner);\n gov = new GovernanceToken();\n }\n\n function test_constructor_succeeds() external {\n assertEq(gov.owner(), owner);\n assertEq(gov.name(), \"Optimism\");\n assertEq(gov.symbol(), \"OP\");\n assertEq(gov.decimals(), 18);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_mint_fromOwner_succeeds() external {\n // Mint 100 tokens.\n vm.prank(owner);\n gov.mint(owner, 100);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 100);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_mint_fromNotOwner_reverts() external {\n // Mint 100 tokens as rando.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n gov.mint(owner, 100);\n\n // Balance does not update.\n assertEq(gov.balanceOf(owner), 0);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_burn_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando burns their tokens.\n vm.prank(rando);\n gov.burn(50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_burnFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to burn 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner burns 50 tokens from rando.\n vm.prank(owner);\n gov.burnFrom(rando, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_transfer_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando transfers 50 tokens to owner.\n vm.prank(rando);\n gov.transfer(owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_approve_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n\n function test_transferFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner transfers 50 tokens from rando to owner.\n vm.prank(owner);\n gov.transferFrom(rando, owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_increaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Rando increases allowance by 50 tokens.\n vm.prank(rando);\n gov.increaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 100);\n }\n\n function test_decreaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 100 tokens.\n vm.prank(rando);\n gov.approve(owner, 100);\n\n // Rando decreases allowance by 50 tokens.\n vm.prank(rando);\n gov.decreaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n}\n" - }, - "contracts/test/Hashing.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract Hashing_Test is CommonTest {\n function setUp() external {\n _setUp();\n }\n\n function test_hashDepositSource_succeeds() external {\n bytes32 sourceHash = Hashing.hashDepositSource(\n 0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,\n 0x1\n );\n\n assertEq(sourceHash, 0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc);\n }\n\n function testDiff_hashCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint16 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Ensure the version is valid\n uint16 version = uint16(bound(uint256(_version), 0, 1));\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes32 _hash = ffi.hashCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n assertEq(hash, _hash);\n }\n\n function testDiff_hashWithdrawal_succeeds(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n bytes32 hash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)\n );\n\n bytes32 _hash = ffi.hashWithdrawal(_nonce, _sender, _target, _value, _gasLimit, _data);\n\n assertEq(hash, _hash);\n }\n\n function testDiff_hashOutputRootProof_succeeds(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external {\n Types.OutputRootProof memory proof = Types.OutputRootProof({\n version: _version,\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _messagePasserStorageRoot,\n latestBlockhash: _latestBlockhash\n });\n\n bytes32 hash = Hashing.hashOutputRootProof(proof);\n\n bytes32 _hash = ffi.hashOutputRootProof(\n _version,\n _stateRoot,\n _messagePasserStorageRoot,\n _latestBlockhash\n );\n\n assertEq(hash, _hash);\n }\n\n // TODO(tynes): foundry bug cannot serialize\n // bytes32 as strings with vm.toString\n function testDiff_hashDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint256 _logIndex\n ) external {\n bytes32 hash = Hashing.hashDepositTransaction(\n Types.UserDepositTransaction(\n _from,\n _to,\n false, // isCreate\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n )\n );\n\n bytes32 _hash = ffi.hashDepositTransaction(\n _from,\n _to,\n _mint,\n _value,\n _gas,\n _data,\n _logIndex\n );\n\n assertEq(hash, _hash);\n }\n}\n" - }, - "contracts/test/L1Block.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\ncontract L1BlockTest is CommonTest {\n L1Block lb;\n address depositor;\n bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));\n\n function setUp() external {\n lb = new L1Block();\n depositor = lb.DEPOSITOR_ACCOUNT();\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: uint64(1),\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: NON_ZERO_HASH,\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(0),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function testFuzz_updatesValues_succeeds(\n uint64 n,\n uint64 t,\n uint256 b,\n bytes32 h,\n uint64 s,\n bytes32 bt,\n uint256 fo,\n uint256 fs\n ) external {\n vm.prank(depositor);\n lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs);\n assertEq(lb.number(), n);\n assertEq(lb.timestamp(), t);\n assertEq(lb.basefee(), b);\n assertEq(lb.hash(), h);\n assertEq(lb.sequenceNumber(), s);\n assertEq(lb.batcherHash(), bt);\n assertEq(lb.l1FeeOverhead(), fo);\n assertEq(lb.l1FeeScalar(), fs);\n }\n\n function test_number_succeeds() external {\n assertEq(lb.number(), uint64(1));\n }\n\n function test_timestamp_succeeds() external {\n assertEq(lb.timestamp(), uint64(2));\n }\n\n function test_basefee_succeeds() external {\n assertEq(lb.basefee(), 3);\n }\n\n function test_hash_succeeds() external {\n assertEq(lb.hash(), NON_ZERO_HASH);\n }\n\n function test_sequenceNumber_succeeds() external {\n assertEq(lb.sequenceNumber(), uint64(4));\n }\n\n function test_updateValues_succeeds() external {\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: type(uint64).max,\n _timestamp: type(uint64).max,\n _basefee: type(uint256).max,\n _hash: keccak256(abi.encode(1)),\n _sequenceNumber: type(uint64).max,\n _batcherHash: bytes32(type(uint256).max),\n _l1FeeOverhead: type(uint256).max,\n _l1FeeScalar: type(uint256).max\n });\n }\n}\n" - }, - "contracts/test/L1BlockNumber.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { L1BlockNumber } from \"../legacy/L1BlockNumber.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract L1BlockNumberTest is Test {\n L1Block lb;\n L1BlockNumber bn;\n\n uint64 constant number = 99;\n\n function setUp() external {\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n lb = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n bn = new L1BlockNumber();\n vm.prank(lb.DEPOSITOR_ACCOUNT());\n\n lb.setL1BlockValues({\n _number: number,\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: bytes32(uint256(10)),\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(uint256(0)),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function test_getL1BlockNumber_succeeds() external {\n assertEq(bn.getL1BlockNumber(), number);\n }\n\n function test_fallback_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n\n function test_receive_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call{ value: 1 }(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n}\n" - }, - "contracts/test/L1CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Messenger_Initializer, Reverter, CallerCaller } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle_Initializer } from \"./L2OutputOracle.t.sol\";\n\n/* Libraries */\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n/* Target contract dependencies */\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/* Target contract */\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\n\ncontract L1CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n function setUp() public override {\n super.setUp();\n }\n\n // pause: should pause the contract when called by the current owner\n function test_pause_succeeds() external {\n vm.prank(alice);\n L1Messenger.pause();\n assert(L1Messenger.paused());\n }\n\n // pause: should not pause the contract when called by account other than the owner\n function test_pause_callerIsNotOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n vm.prank(address(0xABBA));\n L1Messenger.pause();\n }\n\n // unpause: should unpause the contract when called by the current owner\n function test_unpause_succeeds() external {\n vm.prank(alice);\n L1Messenger.pause();\n assert(L1Messenger.paused());\n\n vm.prank(alice);\n L1Messenger.unpause();\n assert(!L1Messenger.paused());\n }\n\n // unpause: should not unpause the contract when called by account other than the owner\n function test_unpause_callerIsNotOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n vm.prank(address(0xABBA));\n L1Messenger.unpause();\n }\n\n // the version is encoded in the nonce\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce());\n assertEq(version, L1Messenger.MESSAGE_VERSION());\n }\n\n // sendMessage: should be able to send a single message\n // TODO: this same test needs to be done with the legacy message type\n // by setting the message version to 0\n function test_sendMessage_succeeds() external {\n // deposit transaction on the optimism portal should be called\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n )\n );\n\n // TransactionDeposited event\n vm.expectEmit(true, true, true, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n );\n\n // SentMessage event\n vm.expectEmit(true, true, true, true);\n emit SentMessage(recipient, alice, hex\"ff\", L1Messenger.messageNonce(), 100);\n\n // SentMessageExtension1 event\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(alice, 0);\n\n vm.prank(alice);\n L1Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n // sendMessage: should be able to send the same message twice\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L1Messenger.messageNonce());\n }\n\n function test_xDomainSender_notSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // xDomainMessageSender: should return the xDomainMsgSender address\n // TODO: might need a test contract\n // function test_xDomainSenderSetCorrectly() external {}\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(address(op));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 2), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n // relayMessage: should send a successful call to the target contract\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.expectCall(target, hex\"1111\");\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n // set the target to be the OptimismPortal\n address target = address(op);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.prank(address(op));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n\n vm.store(address(op), 0, bytes32(abi.encode(sender)));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: should revert if eth is sent from a contract other than the standard bridge\n function test_replayMessage_withValue_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.expectRevert(\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n L1Messenger.relayMessage{ value: 100 }(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should revert if paused\n function test_relayMessage_paused_reverts() external {\n vm.prank(L1Messenger.owner());\n L1Messenger.pause();\n\n vm.expectRevert(\"Pausable: paused\");\n L1Messenger.relayMessage(0, address(0), address(0), 0, 0, hex\"\");\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n vm.expectCall(target, hex\"1111\");\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n // relayMessage: should revert if recipient is trying to reenter\n function test_relayMessage_reentrancy_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = abi.encodeWithSelector(\n L1Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.etch(target, address(new CallerCaller()).code);\n\n vm.expectEmit(true, true, true, true, target);\n\n emit WhatHappened(\n false,\n abi.encodeWithSignature(\"Error(string)\", \"ReentrancyGuard: reentrant call\")\n );\n\n vm.prank(address(op));\n vm.expectCall(target, message);\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n 0, // value\n 0,\n message\n );\n\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacy_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce(0, 0),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 0), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyOldReplay_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce(0, 0),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Mark legacy message as already relayed.\n uint256 successfulMessagesSlot = 203;\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex\"1111\", 0);\n bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot));\n vm.store(address(L1Messenger), slot, bytes32(uint256(1)));\n\n // Expect revert.\n vm.expectRevert(\"CrossDomainMessenger: legacy withdrawal already relayed\");\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 0), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was not relayed.\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyRetryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce(0, 0),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect FailedRelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 0), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 0), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacyRetryAfterSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce(0, 0),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 0), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 0), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce(0, 0),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 0), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 0), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message has already been relayed\");\n\n // Retry the message again.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 0), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n}\n" - }, - "contracts/test/L1ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L1ERC721Bridge_Test is Messenger_Initializer {\n TestERC721 internal localToken;\n TestERC721 internal remoteToken;\n L1ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L1ERC721Bridge(address(L1Messenger), otherBridge);\n localToken = new TestERC721();\n remoteToken = new TestERC721();\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L1ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L1Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L1Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notEscrowed_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n" - }, - "contracts/test/L1StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\n\ncontract L1StandardBridge_Getter_Test is Bridge_Initializer {\n function test_getters_succeeds() external {\n assert(L1Bridge.l2TokenBridge() == address(L2Bridge));\n assert(L1Bridge.OTHER_BRIDGE() == L2Bridge);\n assert(L1Bridge.messenger() == L1Messenger);\n assert(L1Bridge.MESSENGER() == L1Messenger);\n assertEq(L1Bridge.version(), \"1.0.0\");\n }\n}\n\ncontract L1StandardBridge_Initialize_Test is Bridge_Initializer {\n function test_initialize_succeeds() external {\n assertEq(address(L1Bridge.messenger()), address(L1Messenger));\n\n assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE);\n\n assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE);\n }\n}\n\ncontract L1StandardBridge_Initialize_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_Receive_Test is Bridge_Initializer {\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(op).balance, 0);\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n ),\n 200_000\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L1Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(op).balance, 100);\n }\n}\n\ncontract L1StandardBridge_Receive_TestFail {}\n\ncontract L1StandardBridge_DepositETH_Test is Bridge_Initializer {\n // depositETH\n // - emits ETHDepositInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_depositETH_succeeds() external {\n assertEq(address(op).balance, 0);\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeInitiated(alice, alice, 500, hex\"ff\");\n\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 500,\n hex\"ff\"\n ),\n 50000\n )\n );\n\n vm.prank(alice, alice);\n L1Bridge.depositETH{ value: 500 }(50000, hex\"ff\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer {\n function test_depositETH_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, address(L1Token).code);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice);\n L1Bridge.depositETH{ value: 1 }(300, hex\"\");\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_Test is Bridge_Initializer {\n // depositETHTo\n // - emits ETHDepositInitiated\n // - calls optimismPortal.depositTransaction\n // - EOA or contract can call\n // - ETH ends up in the optimismPortal\n function test_depositETHTo_succeeds() external {\n assertEq(address(op).balance, 0);\n\n vm.expectEmit(true, true, true, true);\n emit ETHDepositInitiated(alice, bob, 600, hex\"dead\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeInitiated(alice, bob, 600, hex\"dead\");\n\n // depositETHTo on the L1 bridge should be called\n vm.expectCall(\n address(L1Bridge),\n abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 1000, hex\"dead\")\n );\n\n // the L1 bridge should call\n // L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n bob,\n 600,\n hex\"dead\"\n ),\n 1000\n )\n );\n\n // TODO: assert on OptimismPortal being called\n // and the event being emitted correctly\n\n // deposit eth to bob\n vm.prank(alice, alice);\n L1Bridge.depositETHTo{ value: 600 }(bob, 1000, hex\"dead\");\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // depositERC20\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - only callable by EOA\n function test_depositERC20_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n deal(address(L1Token), alice, 100000, true);\n\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n // The L1Bridge should transfer alice's tokens\n // to itself\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)\n );\n\n // TODO: optimismPortal.depositTransaction call + event\n\n vm.prank(alice);\n L1Bridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex\"\");\n\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n }\n}\n\ncontract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer {\n function test_depositERC20_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, hex\"ffff\");\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice, alice);\n L1Bridge.depositERC20(address(0), address(0), 100, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {\n // depositERC20To\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - callable by a contract\n function test_depositERC20To_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n deal(address(L1Token), alice, 100000, true);\n\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)\n );\n\n vm.prank(alice);\n L1Bridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex\"\");\n\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 1000);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeETHWithdrawal\n // - emits ETHWithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeETHWithdrawal_succeeds() external {\n uint256 aliceBalance = alice.balance;\n\n vm.expectEmit(true, true, true, true);\n emit ETHWithdrawalFinalized(alice, alice, 100, hex\"\");\n\n vm.expectCall(alice, hex\"\");\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n // ensure that the messenger has ETH to call with\n vm.deal(address(L1Bridge.messenger()), 100);\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n\n assertEq(address(L1Bridge.messenger()).balance, 0);\n assertEq(aliceBalance + 100, alice.balance);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeERC20Withdrawal\n // - updates bridge.deposits\n // - emits ERC20WithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeERC20Withdrawal_succeeds() external {\n deal(address(L1Token), address(L1Bridge), 100, true);\n\n uint256 slot = stdstore\n .target(address(L1Bridge))\n .sig(\"deposits(address,address)\")\n .with_key(address(L1Token))\n .with_key(address(L2Token))\n .find();\n\n // Give the L1 bridge some ERC20 tokens\n vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n\n vm.expectEmit(true, true, true, true);\n emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)\n );\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n assertEq(L1Token.balanceOf(address(L1Bridge)), 0);\n assertEq(L1Token.balanceOf(address(alice)), 100);\n }\n}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer {\n function test_finalizeERC20Withdrawal_notMessenger_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(28));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n\n function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(address(0)))\n );\n vm.prank(address(L1Bridge.messenger()));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n}\n\n// Todo: move these next two contracts into a test file specific to the direction agnostic\n// StandardBridge interface\ncontract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer {\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L1Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L1Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, CallerCaller } from \"./CommonTest.t.sol\";\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_pause_succeeds() external {\n L2Messenger.pause();\n assert(L2Messenger.paused());\n }\n\n function test_pause_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n vm.prank(address(0xABBA));\n L2Messenger.pause();\n }\n\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce());\n assertEq(version, L2Messenger.MESSAGE_VERSION());\n }\n\n function test_sendMessage_succeeds() external {\n bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage(\n L2Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n );\n vm.expectCall(\n address(messagePasser),\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData\n )\n );\n\n // MessagePassed event\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(L2Messenger),\n address(L1Messenger),\n 0,\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData,\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messagePasser.messageNonce(),\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: L2Messenger.baseGas(hex\"ff\", 100),\n data: xDomainCallData\n })\n )\n );\n\n vm.prank(alice);\n L2Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L2Messenger.messageNonce();\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L2Messenger.messageNonce());\n }\n\n function test_xDomainSender_senderNotSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 2), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n vm.expectCall(target, hex\"1111\");\n\n vm.prank(caller);\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L2Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L2Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n address target = address(messagePasser);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory message = hex\"1111\";\n\n vm.prank(caller);\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should revert if paused\n function test_relayMessage_paused_reverts() external {\n vm.prank(L2Messenger.owner());\n L2Messenger.pause();\n\n vm.expectRevert(\"Pausable: paused\");\n L2Messenger.relayMessage(0, address(0), address(0), 0, 0, hex\"\");\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retry_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n uint256 value = 100;\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(caller), value);\n vm.prank(caller);\n L2Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L2Messenger.successfulMessages(hash), false);\n assertEq(L2Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L2Messenger.successfulMessages(hash), true);\n assertEq(L2Messenger.failedMessages(hash), true);\n }\n\n // relayMessage: should revert if recipient is trying to reenter\n function test_relayMessage_reentrancy_reverts() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory message = abi.encodeWithSelector(\n L2Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n\n vm.etch(target, address(new CallerCaller()).code);\n\n vm.expectEmit(true, true, true, true, target);\n\n emit WhatHappened(\n false,\n abi.encodeWithSignature(\"Error(string)\", \"ReentrancyGuard: reentrant call\")\n );\n\n vm.prank(caller);\n vm.expectCall(target, message);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n 0, // value\n 0,\n message\n );\n\n assertEq(L2Messenger.successfulMessages(hash), false);\n assertEq(L2Messenger.failedMessages(hash), true);\n }\n}\n" - }, - "contracts/test/L2ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract TestMintableERC721 is OptimismMintableERC721 {\n constructor(address _bridge, address _remoteToken)\n OptimismMintableERC721(_bridge, 1, _remoteToken, \"Test\", \"TST\")\n {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L2ERC721Bridge_Test is Messenger_Initializer {\n TestMintableERC721 internal localToken;\n TestERC721 internal remoteToken;\n L2ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L2ERC721Bridge(address(L2Messenger), otherBridge);\n remoteToken = new TestERC721();\n localToken = new TestMintableERC721(address(bridge), address(remoteToken));\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L2ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L2Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L2Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L1ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_alreadyExists_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721: token already minted\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n" - }, - "contracts/test/L2OutputOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { L2OutputOracle_Initializer, NextImpl } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2OutputOracleTest is L2OutputOracle_Initializer {\n bytes32 proposedOutput1 = keccak256(abi.encode(1));\n\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_constructor_succeeds() external {\n assertEq(oracle.PROPOSER(), proposer);\n assertEq(oracle.CHALLENGER(), owner);\n assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);\n assertEq(oracle.latestBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingTimestamp(), startingTimestamp);\n }\n\n function test_constructor_badTimestamp_reverts() external {\n vm.expectRevert(\"L2OutputOracle: starting L2 timestamp must be less than current time\");\n\n new L2OutputOracle(\n submissionInterval,\n l2BlockTime,\n startingBlockNumber,\n // startingTimestamp is in the future\n block.timestamp + 1,\n proposer,\n owner\n );\n }\n\n /****************\n * Getter Tests *\n ****************/\n\n // Test: latestBlockNumber() should return the correct value\n function test_latestBlockNumber_succeeds() external {\n uint256 proposedNumber = oracle.nextBlockNumber();\n\n // Roll to after the block number we'll propose\n warpToProposeTime(proposedNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0);\n assertEq(oracle.latestBlockNumber(), proposedNumber);\n }\n\n // Test: getL2Output() should return the correct value\n function test_getL2Output_succeeds() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0);\n\n Types.OutputProposal memory proposal = oracle.getL2Output(nextOutputIndex);\n assertEq(proposal.outputRoot, proposedOutput1);\n assertEq(proposal.timestamp, block.timestamp);\n\n // The block number is larger than the latest proposed output:\n vm.expectRevert(stdError.indexOOBError);\n oracle.getL2Output(nextOutputIndex + 1);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is exact block\n function test_getL2OutputIndexAfter_sameBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with exact same block as proposed returns the proposal.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is previous block\n function test_getL2OutputIndexAfter_previousBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with previous block returns the proposal too.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 - 1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value during binary search\n function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n bytes32 output2 = keccak256(abi.encode(2));\n uint256 nextBlockNumber2 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber2);\n vm.prank(proposer);\n oracle.proposeL2Output(output2, nextBlockNumber2, 0, 0);\n\n bytes32 output3 = keccak256(abi.encode(3));\n uint256 nextBlockNumber3 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber3);\n vm.prank(proposer);\n oracle.proposeL2Output(output3, nextBlockNumber3, 0, 0);\n\n bytes32 output4 = keccak256(abi.encode(4));\n uint256 nextBlockNumber4 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber4);\n vm.prank(proposer);\n oracle.proposeL2Output(output4, nextBlockNumber4, 0, 0);\n\n // Querying with a block number between the first and second proposal\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 + 1);\n assertEq(index1, 1);\n\n // Querying with a block number between the second and third proposal\n uint256 index2 = oracle.getL2OutputIndexAfter(nextBlockNumber2 + 1);\n assertEq(index2, 2);\n\n // Querying with a block number between the third and fourth proposal\n uint256 index3 = oracle.getL2OutputIndexAfter(nextBlockNumber3 + 1);\n assertEq(index3, 3);\n }\n\n // Test: getL2OutputIndexAfter() reverts when no output exists yet\n function test_getL2OutputIndexAfter_noOutputsExis_reverts() external {\n vm.expectRevert(\"L2OutputOracle: cannot get output as no outputs have been proposed yet\");\n oracle.getL2OutputIndexAfter(0);\n }\n\n // Test: nextBlockNumber() should return the correct value\n function test_nextBlockNumber_succeeds() external {\n assertEq(\n oracle.nextBlockNumber(),\n // The return value should match this arithmetic\n oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL()\n );\n }\n\n function test_computeL2Timestamp_succeeds() external {\n // reverts if timestamp is too low\n vm.expectRevert(stdError.arithmeticError);\n oracle.computeL2Timestamp(startingBlockNumber - 1);\n\n // returns the correct value...\n // ... for the very first block\n assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);\n\n // ... for the first block after the starting block\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 1),\n startingTimestamp + l2BlockTime\n );\n\n // ... for some other block number\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 96024),\n startingTimestamp + l2BlockTime * 96024\n );\n }\n\n /*****************************\n * Propose Tests - Happy Path *\n *****************************/\n\n // Test: proposeL2Output succeeds when given valid input, and no block hash and number are\n // specified.\n function test_proposeL2Output_proposeAnotherOutput_succeeds() public {\n bytes32 proposedOutput2 = keccak256(abi.encode());\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n uint256 proposedNumber = oracle.latestBlockNumber();\n\n // Ensure the submissionInterval is enforced\n assertEq(nextBlockNumber, proposedNumber + submissionInterval);\n\n vm.roll(nextBlockNumber + 1);\n\n vm.expectEmit(true, true, true, true);\n emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp);\n\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output succeeds when given valid input, and when a block hash and number are\n // specified for reorg protection.\n function test_proposeWithBlockhashAndHeight_succeeds() external {\n // Get the number and hash of a previous block in the chain\n uint256 prevL1BlockNumber = block.number - 1;\n bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber);\n }\n\n /***************************\n * Propose Tests - Sad Path *\n ***************************/\n\n // Test: proposeL2Output fails if called by a party that is not the proposer.\n function test_proposeL2Output_notProposer_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n\n vm.prank(address(128));\n vm.expectRevert(\"L2OutputOracle: only the proposer address can propose new outputs\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails given a zero blockhash.\n function test_proposeL2Output_emptyOutput_reverts() external {\n bytes32 outputToPropose = bytes32(0);\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: L2 output proposal cannot be the zero hash\");\n oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if the block number doesn't match the next expected number.\n function test_proposeL2Output_unexpectedBlockNumber_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: block number must be equal to next expected block number\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);\n }\n\n // Test: proposeL2Output fails if it would have a timestamp in the future.\n function test_proposeL2Output_futureTimetamp_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber);\n vm.warp(nextTimestamp);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: cannot propose L2 output in the future\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if a non-existent L1 block hash and number are provided for reorg\n // protection.\n function test_proposeL2Output_wrongFork_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(\n nonZeroHash,\n nextBlockNumber,\n bytes32(uint256(0x01)),\n block.number - 1\n );\n }\n\n // Test: proposeL2Output fails when given valid input, but the block hash and number do not\n // match.\n function test_proposeL2Output_unmatchedBlockhash_reverts() external {\n // Move ahead to block 100 so that we can reference historical blocks\n vm.roll(100);\n\n // Get the number and hash of a previous block in the chain\n uint256 l1BlockNumber = block.number - 1;\n bytes32 l1BlockHash = blockhash(l1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n\n // This will fail when foundry no longer returns zerod block hashes\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);\n }\n\n /*****************************\n * Delete Tests - Happy Path *\n *****************************/\n\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n function test_deleteOutputs_singleOutput_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 1);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex);\n oracle.deleteL2Outputs(latestOutputIndex);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n function test_deleteOutputs_multipleOutputs_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 3);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n /***************************\n * Delete Tests - Sad Path *\n ***************************/\n\n function test_deleteL2Outputs_ifNotChallenger_reverts() external {\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.expectRevert(\"L2OutputOracle: only the challenger address can delete outputs\");\n oracle.deleteL2Outputs(latestBlockNumber);\n }\n\n function test_deleteL2Outputs_nonExistent_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestBlockNumber + 1);\n }\n\n function test_deleteL2Outputs_afterLatest_reverts() external {\n // Start by proposing three outputs\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Delete the latest two outputs\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n vm.prank(owner);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // Now try to delete the same output again\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n }\n}\n\ncontract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {\n Proxy internal proxy;\n\n function setUp() public override {\n super.setUp();\n proxy = Proxy(payable(address(oracle)));\n }\n\n function test_initValuesOnProxy_succeeds() external {\n assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());\n assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());\n assertEq(startingBlockNumber, oracleImpl.startingBlockNumber());\n assertEq(startingTimestamp, oracleImpl.startingTimestamp());\n\n assertEq(proposer, oracleImpl.PROPOSER());\n assertEq(owner, oracleImpl.CHALLENGER());\n }\n\n function test_initializeProxy_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(payable(proxy)).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_initializeImpl_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(oracleImpl).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(oracle), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(oracle), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(oracle)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/L2StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { console } from \"forge-std/console.sol\";\n\ncontract L2StandardBridge_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_initialize_succeeds() external {\n assertEq(address(L2Bridge.messenger()), address(L2Messenger));\n assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge));\n assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge));\n }\n\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(messagePasser).balance, 0);\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n // TODO: L2Messenger should be called\n // TODO: L2ToL1MessagePasser should be called\n // TODO: withdrawal hash should be computed correctly\n // TODO: events from each contract\n\n vm.prank(alice, alice);\n (bool success, ) = address(L2Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(messagePasser).balance, 100);\n }\n\n // withrdraw\n // - requires amount == msg.value\n function test_withdraw_insufficientValue_reverts() external {\n assertEq(address(messagePasser).balance, 0);\n\n vm.expectRevert(\"StandardBridge: bridging ETH must include sufficient ETH value\");\n vm.prank(alice, alice);\n L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex\"\");\n }\n\n // withdraw\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_withdraw_succeeds() external {\n // Alice has 100 L2Token\n deal(address(L2Token), alice, 100, true);\n assertEq(L2Token.balanceOf(alice), 100);\n\n vm.prank(alice, alice);\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n\n // TODO: events and calls\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdraw_notEOA_reverts() external {\n // This contract has 100 L2Token\n deal(address(L2Token), address(this), 100, true);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n }\n\n // withdrawTo\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_withdrawTo_succeeds() external {\n deal(address(L2Token), alice, 100, true);\n\n vm.prank(alice, alice);\n L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex\"\");\n\n // TODO: events and calls\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // finalizeDeposit\n // - only callable by l1TokenBridge\n // - supported token pair emits DepositFinalized\n // - invalid deposit calls Withdrawer.initiateWithdrawal\n function test_finalizeDeposit_succeeds() external {\n // TODO: events and calls\n\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(\n address(L2Token), // localToken\n address(L1Token), // remoteToken\n alice,\n alice,\n 100,\n hex\"\"\n );\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Messenger), 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2ToL1MessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\n\ncontract L2ToL1MessagePasserTest is CommonTest {\n L2ToL1MessagePasser messagePasser;\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n function setUp() public virtual {\n messagePasser = new L2ToL1MessagePasser();\n }\n\n function testFuzz_initiateWithdrawal_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint256 nonce = messagePasser.messageNonce();\n\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: _value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash);\n\n vm.deal(_sender, _value);\n vm.prank(_sender);\n messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);\n\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0)));\n\n assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1)));\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by a contract\n function test_initiateWithdrawal_fromContract_succeeds() external {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\"\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\",\n withdrawalHash\n );\n\n vm.deal(address(this), 2**64);\n messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex\"\");\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by an EOA\n function test_initiateWithdrawal_fromEOA_succeeds() external {\n uint256 gasLimit = 64000;\n address target = address(4);\n uint256 value = 100;\n bytes memory data = hex\"ff\";\n uint256 nonce = messagePasser.messageNonce();\n\n // EOA emulation\n vm.prank(alice, alice);\n vm.deal(alice, 2**64);\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data)\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash);\n\n messagePasser.initiateWithdrawal{ value: value }(target, gasLimit, data);\n\n // the sent messages mapping is filled\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n // the nonce increments\n assertEq(nonce + 1, messagePasser.messageNonce());\n }\n\n // Test: burn should destroy the ETH held in the contract\n function test_burn_succeeds() external {\n messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n NON_ZERO_GASLIMIT,\n NON_ZERO_DATA\n );\n\n assertEq(address(messagePasser).balance, NON_ZERO_VALUE);\n vm.expectEmit(true, false, false, false);\n emit WithdrawerBalanceBurnt(NON_ZERO_VALUE);\n messagePasser.burn();\n\n // The Withdrawer should have no balance\n assertEq(address(messagePasser).balance, 0);\n }\n}\n" - }, - "contracts/test/LegacyERC20ETH.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyERC20ETH_Test is CommonTest {\n LegacyERC20ETH eth;\n\n function setUp() external {\n eth = new LegacyERC20ETH();\n }\n\n function test_metadata_succeeds() external {\n assertEq(eth.name(), \"Ether\");\n assertEq(eth.symbol(), \"ETH\");\n assertEq(eth.decimals(), 18);\n }\n\n function test_crossDomain_succeeds() external {\n assertEq(eth.l2Bridge(), Predeploys.L2_STANDARD_BRIDGE);\n assertEq(eth.l1Token(), address(0));\n }\n\n function test_transfer_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transfer is disabled\");\n eth.transfer(alice, 100);\n }\n\n function test_approve_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: approve is disabled\");\n eth.approve(alice, 100);\n }\n\n function test_transferFrom_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transferFrom is disabled\");\n eth.transferFrom(bob, alice, 100);\n }\n\n function test_increaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n eth.increaseAllowance(alice, 100);\n }\n\n function test_decreaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n eth.decreaseAllowance(alice, 100);\n }\n\n function test_mint_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: mint is disabled\");\n eth.mint(alice, 100);\n }\n\n function test_burn_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: burn is disabled\");\n eth.burn(alice, 100);\n }\n}\n" - }, - "contracts/test/LegacyMessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyMessagePasser } from \"../legacy/LegacyMessagePasser.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyMessagePasser_Test is CommonTest {\n LegacyMessagePasser messagePasser;\n\n function setUp() external {\n messagePasser = new LegacyMessagePasser();\n }\n\n function test_passMessageToL1_succeeds() external {\n vm.prank(alice);\n messagePasser.passMessageToL1(hex\"ff\");\n assert(messagePasser.sentMessages(keccak256(abi.encodePacked(hex\"ff\", alice))));\n }\n}\n" - }, - "contracts/test/MerkleTrie.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MerkleTrie } from \"../libraries/trie/MerkleTrie.sol\";\n\ncontract MerkleTrie_Test is CommonTest {\n function setUp() public {\n _setUp();\n }\n\n function test_get_validProof1_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579326262\";\n bytes memory val = hex\"6176616c32\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof2_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[\n 2\n ] = hex\"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof3_succeeds() external {\n bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof4_succeeds() external {\n bytes32 root = 0x37956bab6bba472308146808d5311ac19cb4a7daae5df7efcc0f32badc97f55e;\n bytes memory key = hex\"6b6579316161\";\n bytes memory val = hex\"3031323334\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"ce87206b6579316161853031323334\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof5_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657931\";\n bytes\n memory val = hex\"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof6_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657932\";\n bytes memory val = hex\"73686f7274\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[2] = hex\"df808080808080c9823262856176616c338080808080808080808573686f7274\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof7_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657933\";\n bytes memory val = hex\"31323334353637383930313233343536373839303132333435363738393031\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof8_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"61\";\n bytes memory val = hex\"61\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22061\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof9_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"62\";\n bytes memory val = hex\"62\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22062\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof10_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"63\";\n bytes memory val = hex\"63\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22063\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_nonexistentKey1_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b657932\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_nonexistentKey2_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"616e7972616e646f6d6b6579\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_wrongKeyProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579316161\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[2] = hex\"d687206e6f746865728d33343938683472697568677765\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_corruptedProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579326262\";\n bytes[] memory proof = new bytes[](5);\n proof[0] = hex\"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[\n 2\n ] = hex\"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 3\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[4] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidDataRemainder_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa000000000000000000000000000000\";\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidInternalNodeHash_reverts() external {\n bytes32 root = 0xa827dff1a657bb9bb9a1c3abe9db173e2f1359f15eb06f1647ea21ac7c95d8fa;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157\";\n proof[\n 1\n ] = hex\"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080\";\n proof[2] = hex\"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroBranchValueLength_reverts() external {\n bytes32 root = 0xe04b3589eef96b237cd49ccb5dcf6e654a47682bfa0961d563ab843f7ad1e035;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](2);\n proof[0] = hex\"dd8200aad98080808080808080808080c43b82aabbc43c82aacc80808080\";\n proof[1] = hex\"d98080808080808080808080c43b82aabbc43c82aacc80808080\";\n\n vm.expectRevert(\"MerkleTrie: value length must be greater than zero (branch)\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroLengthKey_reverts() external {\n bytes32 root = 0x54157fd62cdf2f474e7bfec2d3cd581e807bee38488c9590cb887add98936b73;\n bytes memory key = hex\"\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"c78320f00082b443\";\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey1_reverts() external {\n bytes32 root = 0xa513ba530659356fb7588a2c831944e80fd8aedaa5a4dc36f918152be2be0605;\n bytes memory key = hex\"01\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"db10d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[1] = hex\"d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[2] = hex\"c582202381aa\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey2_reverts() external {\n bytes32 root = 0xa06abffaec4ebe8ccde595f4547b864b4421b21c1fc699973f94710c9bc17979;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905\";\n proof[\n 1\n ] = hex\"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080\";\n proof[2] = hex\"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_extraProofElements_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](4);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa\";\n proof[3] = hex\"c32081aa\";\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_validProofs_succeeds(bytes4) external {\n // Generate a test case with a valid proof of inclusion for the k/v pair in the trie.\n (bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi\n .getMerkleTrieFuzzCase(\"valid\");\n\n // Assert that our expected value is equal to our actual value.\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidRoot_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"valid\"\n );\n\n bytes32 rootHash = keccak256(abi.encodePacked(root));\n vm.expectRevert(\"MerkleTrie: invalid root hash\");\n MerkleTrie.get(key, proof, rootHash);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_extraProofElements_reverts(bytes4) external {\n // Generate an invalid test case with an extra proof element attached to an otherwise\n // valid proof of inclusion for the passed k/v.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"extra_proof_elems\"\n );\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external {\n // Generate an invalid test case where a long proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_large_internal_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid large internal hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external {\n // Generate an invalid test case where a small proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_internal_node_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_corruptedProof_reverts(bytes4) external {\n // Generate an invalid test case where the proof is malformed.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"corrupted_proof\"\n );\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidDataRemainder_reverts(bytes4) external {\n // Generate an invalid test case where a random element of the proof has more bytes than the\n // length designates within the RLP list encoding.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_data_remainder\"\n );\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_prefixedValidKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and a valid key that is prefixed\n // with random bytes\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"prefixed_valid_key\"\n );\n\n // Ambiguous revert check- all that we care is that it *does* fail. This case may\n // fail within different branches.\n vm.expectRevert();\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_emptyKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and an empty key\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"empty_key\"\n );\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_partialProof_reverts(bytes4) external {\n // Get a random test case with a valid trie / partially correct proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"partial_proof\"\n );\n\n vm.expectRevert(\"MerkleTrie: ran out of proof elements\");\n MerkleTrie.get(key, proof, root);\n }\n}\n" - }, - "contracts/test/MintManager.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MintManager } from \"../governance/MintManager.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract MintManager_Test is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n MintManager internal manager;\n\n function setUp() external {\n vm.prank(owner);\n gov = new GovernanceToken();\n\n vm.prank(owner);\n manager = new MintManager(owner, address(gov));\n\n vm.prank(owner);\n gov.transferOwnership(address(manager));\n }\n\n function test_constructor_succeeds() external {\n assertEq(manager.owner(), owner);\n assertEq(address(manager.governanceToken()), address(gov));\n }\n\n function test_mint_fromOwner_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n function test_mint_fromNotOwner_reverts() external {\n // Mint from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.mint(owner, 100);\n }\n\n function test_mint_afterPeriodElapsed_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again after period elapsed (2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n manager.mint(owner, 2);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 102);\n }\n\n function test_mint_beforePeriodElapsed_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: minting not permitted yet\");\n manager.mint(owner, 100);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n function test_mint_moreThanCap_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again (greater than 2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint amount exceeds cap\");\n manager.mint(owner, 3);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n function test_upgrade_fromOwner_succeeds() external {\n // Upgrade to new manager.\n vm.prank(owner);\n manager.upgrade(rando);\n\n // New manager is rando.\n assertEq(gov.owner(), rando);\n }\n\n function test_upgrade_fromNotOwner_reverts() external {\n // Upgrade from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.upgrade(rando);\n }\n\n function test_upgrade_toZeroAddress_reverts() external {\n // Upgrade to zero address fails.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint manager cannot be the zero address\");\n manager.upgrade(address(0));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport {\n ILegacyMintableERC20,\n IOptimismMintableERC20\n} from \"../universal/IOptimismMintableERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract OptimismMintableERC20_Test is Bridge_Initializer {\n event Mint(address indexed account, uint256 amount);\n event Burn(address indexed account, uint256 amount);\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_remoteToken_succeeds() external {\n assertEq(L2Token.remoteToken(), address(L1Token));\n }\n\n function test_bridge_succeeds() external {\n assertEq(L2Token.bridge(), address(L2Bridge));\n }\n\n function test_l1Token_succeeds() external {\n assertEq(L2Token.l1Token(), address(L1Token));\n }\n\n function test_l2Bridge_succeeds() external {\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_legacy_succeeds() external {\n // Getters for the remote token\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.l1Token(), address(L1Token));\n // Getters for the bridge\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_mint_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 100);\n }\n\n function test_mint_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.mint(alice, 100);\n }\n\n function test_burn_succeeds() external {\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_burn_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.burn(alice, 100);\n }\n\n function test_erc165_supportsInterface_succeeds() external {\n // The assertEq calls in this test are comparing the manual calculation of the iface,\n // with what is returned by the solidity's type().interfaceId, just to be safe.\n bytes4 iface1 = bytes4(keccak256(\"supportsInterface(bytes4)\"));\n assertEq(iface1, type(IERC165).interfaceId);\n assert(L2Token.supportsInterface(iface1));\n\n bytes4 iface2 = L2Token.l1Token.selector ^ L2Token.mint.selector ^ L2Token.burn.selector;\n assertEq(iface2, type(ILegacyMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface2));\n\n bytes4 iface3 = L2Token.remoteToken.selector ^\n L2Token.bridge.selector ^\n L2Token.mint.selector ^\n L2Token.burn.selector;\n assertEq(iface3, type(IOptimismMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface3));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\n\ncontract OptimismMintableTokenFactory_Test is Bridge_Initializer {\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_bridge_succeeds() external {\n assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge));\n }\n\n function test_createStandardL2Token_succeeds() external {\n address remote = address(4);\n address local = LibRLP.computeAddress(address(L2TokenFactory), 2);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_sameTwice_succeeds() external {\n address remote = address(4);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n\n address local = LibRLP.computeAddress(address(L2TokenFactory), 3);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_remoteIsZero_succeeds() external {\n address remote = address(0);\n vm.expectRevert(\"OptimismMintableERC20Factory: must provide remote token address\");\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract OptimismMintableERC721_Test is ERC721Bridge_Initializer {\n ERC721 internal L1Token;\n OptimismMintableERC721 internal L2Token;\n\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n event Mint(address indexed account, uint256 tokenId);\n\n event Burn(address indexed account, uint256 tokenId);\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n L1Token = new ERC721(\"L1Token\", \"L1T\");\n L2Token = new OptimismMintableERC721(\n address(L2Bridge),\n 1,\n address(L1Token),\n \"L2Token\",\n \"L2T\"\n );\n\n // Label the addresses for nice traces.\n vm.label(address(L1Token), \"L1ERC721Token\");\n vm.label(address(L2Token), \"L2ERC721Token\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(L2Token.name(), \"L2Token\");\n assertEq(L2Token.symbol(), \"L2T\");\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.remoteChainId(), 1);\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_safeMint_succeeds() external {\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(address(0), alice, 1);\n\n // Expect a mint event.\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 1);\n\n // Mint the token.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token should be owned by alice.\n assertEq(L2Token.ownerOf(1), alice);\n }\n\n function test_safeMint_notBridge_reverts() external {\n // Try to mint the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.safeMint(alice, 1);\n }\n\n function test_burn_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(alice, address(0), 1);\n\n // Expect a burn event.\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 1);\n\n // Burn the token.\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 1);\n\n // Token should be owned by address(0).\n vm.expectRevert(\"ERC721: invalid token ID\");\n L2Token.ownerOf(1);\n }\n\n function test_burn_notBridge_reverts() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Try to burn the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.burn(alice, 1);\n }\n\n function test_tokenURI_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token URI should be correct.\n assertEq(\n L2Token.tokenURI(1),\n string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(address(L1Token)), 20),\n \"@\",\n Strings.toString(1),\n \"/tokenURI?uint256=\",\n Strings.toString(1)\n )\n )\n );\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\n\ncontract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {\n OptimismMintableERC721Factory internal factory;\n\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n factory = new OptimismMintableERC721Factory(address(L2Bridge), 1);\n\n // Label the addresses for nice traces.\n vm.label(address(factory), \"OptimismMintableERC721Factory\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(factory.BRIDGE(), address(L2Bridge));\n assertEq(factory.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_succeeds() external {\n // Predict the address based on the factory address and nonce.\n address predicted = LibRLP.computeAddress(address(factory), 1);\n\n // Expect a token creation event.\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC721Created(predicted, address(1234), alice);\n\n // Create the token.\n vm.prank(alice);\n OptimismMintableERC721 created = OptimismMintableERC721(\n factory.createOptimismMintableERC721(address(1234), \"L2Token\", \"L2T\")\n );\n\n // Token address should be correct.\n assertEq(address(created), predicted);\n\n // Should be marked as created by the factory.\n assertEq(factory.isOptimismMintableERC721(address(created)), true);\n\n // Token should've been constructed correctly.\n assertEq(created.name(), \"L2Token\");\n assertEq(created.symbol(), \"L2T\");\n assertEq(created.REMOTE_TOKEN(), address(1234));\n assertEq(created.BRIDGE(), address(L2Bridge));\n assertEq(created.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_zeroRemoteToken_reverts() external {\n // Try to create a token with a zero remote token address.\n vm.expectRevert(\"OptimismMintableERC721Factory: L1 token address cannot be address(0)\");\n factory.createOptimismMintableERC721(address(0), \"L2Token\", \"L2T\");\n }\n}\n" - }, - "contracts/test/OptimismPortal.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { Portal_Initializer, CommonTest, NextImpl } from \"./CommonTest.t.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\n\ncontract OptimismPortal_Test is Portal_Initializer {\n function test_constructor_succeeds() external {\n assertEq(op.FINALIZATION_PERIOD_SECONDS(), 7 days);\n assertEq(address(op.L2_ORACLE()), address(oracle));\n assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD);\n }\n\n function test_receive_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex\"\");\n\n // give alice money and send as an eoa\n vm.deal(alice, 2**64);\n vm.prank(alice, alice);\n (bool s, ) = address(op).call{ value: 100 }(hex\"\");\n\n assert(s);\n assertEq(address(op).balance, 100);\n }\n\n // Test: depositTransaction fails when contract creation has a non-zero destination address\n function test_depositTransaction_contractCreation_reverts() external {\n // contract creation must have a target of address(0)\n vm.expectRevert(\"OptimismPortal: must send to address(0) when creating a contract\");\n op.depositTransaction(address(1), 1, 0, true, hex\"\");\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a tx with 0 value\n function test_depositTransaction_noValueEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a tx with 0 value\n function test_depositTransaction_noValueContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndContractContractCreation_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n function test_simple_isOutputFinalized_succeeds() external {\n uint256 ts = block.timestamp;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))\n )\n );\n\n // warp to the finalization period\n vm.warp(ts + op.FINALIZATION_PERIOD_SECONDS());\n assertEq(op.isOutputFinalized(0), false);\n\n // warp past the finalization period\n vm.warp(ts + op.FINALIZATION_PERIOD_SECONDS() + 1);\n assertEq(op.isOutputFinalized(0), true);\n }\n\n function test_isOutputFinalized_succeeds() external {\n uint256 checkpoint = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n vm.roll(checkpoint);\n vm.warp(oracle.computeL2Timestamp(checkpoint) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0);\n\n // warp to the final second of the finalization period\n uint256 finalizationHorizon = block.timestamp + op.FINALIZATION_PERIOD_SECONDS();\n vm.warp(finalizationHorizon);\n // The checkpointed block should not be finalized until 1 second from now.\n assertEq(op.isOutputFinalized(nextOutputIndex), false);\n // Nor should a block after it\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n\n // warp past the finalization period\n vm.warp(finalizationHorizon + 1);\n // It should now be finalized.\n assertEq(op.isOutputFinalized(nextOutputIndex), true);\n // But not the block after it.\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n }\n}\n\ncontract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n op.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n // Utility function used in the subsequent test. This is necessary to assert that the\n // reentrant call will revert.\n function callPortalAndExpectRevert() external payable {\n vm.expectRevert(\"OptimismPortal: can only trigger one withdrawal per transaction\");\n // Arguments here don't matter, as the require check is the first thing that happens.\n // We assume that this has already been proven.\n op.finalizeWithdrawalTransaction(_defaultTx);\n // Assert that the withdrawal was not finalized.\n assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));\n }\n\n // Test: proveWithdrawalTransaction cannot prove a withdrawal with itself (the OptimismPortal) as the target.\n function test_proveWithdrawalTransaction_onSelfCall_reverts() external {\n _defaultTx.target = address(op);\n vm.expectRevert(\"OptimismPortal: you cannot send messages to the portal contract\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the outputRootProof does not match the output root\n function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external {\n // Modify the version to invalidate the withdrawal proof.\n _outputRootProof.version = bytes32(uint256(1));\n vm.expectRevert(\"OptimismPortal: invalid output root proof\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the proof is invalid due to non-existence of\n // the withdrawal.\n function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external {\n // modify the default test values to invalidate the proof.\n _defaultTx.data = hex\"abcd\";\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the passed transaction's withdrawalHash has\n // already been proven.\n function test_proveWithdrawalTransaction_replayProve_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: withdrawal hash has already been proven\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root has changed AND the l2BlockNumber stays the same.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a different output root within the `provenWithdrawals` mapping without\n // touching the l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds and emits the WithdrawalProven event.\n function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: finalizeWithdrawalTransaction succeeds and emits the WithdrawalFinalized event.\n function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, false, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore + 100);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has not been proven.\n function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectRevert(\"OptimismPortal: withdrawal has not been proven yet\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if withdrawal not proven long enough ago.\n function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Mock a call where the resulting output root is anything but the original output root. In\n // this case we just use bytes32(uint256(1)).\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(bytes32(uint256(1)), _proposedBlockNumber)\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the provenWithdrawal's timestamp is less\n // than the L2 output oracle's starting timestamp\n function test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a startingTimestamp change on the L2 Oracle\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSignature(\"startingTimestamp()\"),\n abi.encode(block.timestamp + 1)\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output root proven is not the same as the\n // output root at the time of finalization.\n function test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock an outputRoot change on the output proposal before attempting\n // to finalize the withdrawal.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n bytes32(uint256(0)),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output proposal's timestamp has\n // not passed the finalization period.\n function test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a timestamp change on the output proposal that has not passed the\n // finalization period.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(block.timestamp + 1),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\"OptimismPortal: output proposal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction fails because the target reverts,\n // and emits the WithdrawalFinalized event with success=false.\n function test_finalizeWithdrawalTransaction_targetFails_fails() external {\n uint256 bobBalanceBefore = address(bob).balance;\n vm.etch(bob, hex\"fe\"); // Contract with just the invalid opcode.\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, false);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the finalization period has not yet passed.\n function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external {\n // Setup the Oracle to return an output with a recent timestamp\n uint256 recentTimestamp = block.timestamp - 1000;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(recentTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has already been finalized.\n function test_finalizeWithdrawalTransaction_onReplay_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if insufficient gas is supplied.\n function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external {\n // This number was identified through trial and error.\n uint256 gasLimit = 150_000;\n Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: gasLimit,\n data: hex\"\"\n });\n\n // Get updated proof inputs.\n (bytes32 stateRoot, bytes32 storageRoot, , , bytes[] memory withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(insufficientGasTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n Hashing.hashOutputRootProof(outputRootProof),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n insufficientGasTx,\n _proposedOutputIndex,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectRevert(\"OptimismPortal: insufficient gas to finalize withdrawal\");\n op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if a sub-call attempts to finalize another\n // withdrawal.\n function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Copy and modify the default test values to attempt a reentrant call by first calling to\n // this contract's callPortalAndExpectRevert() function above.\n Types.WithdrawalTransaction memory _testTx = _defaultTx;\n _testTx.target = address(this);\n _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector);\n\n // Get modified proof inputs.\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_testTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp.\n uint256 finalizedTimestamp = block.timestamp - op.FINALIZATION_PERIOD_SECONDS() - 1;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n outputRoot,\n uint128(finalizedTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(withdrawalHash, alice, address(this));\n op.proveWithdrawalTransaction(\n _testTx,\n _proposedBlockNumber,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectCall(address(this), _testTx.data);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_testTx);\n\n // Ensure that bob's balance was not changed by the reentrant call.\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n function testDiff_finalizeWithdrawalTransaction_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Cannot call the optimism portal\n vm.assume(_target != address(op));\n // Total ETH supply is currently about 120M ETH.\n uint256 value = bound(_value, 0, 200_000_000 ether);\n uint256 gasLimit = bound(_gasLimit, 0, 50_000_000);\n uint256 nonce = messagePasser.messageNonce();\n Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: value,\n gasLimit: gasLimit,\n data: _data\n });\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_tx);\n\n Types.OutputRootProof memory proof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n\n // Ensure the values returned from ffi are correct\n assertEq(outputRoot, Hashing.hashOutputRootProof(proof));\n assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx));\n\n // Mock the call to the oracle\n vm.mockCall(\n address(oracle),\n abi.encodeWithSelector(oracle.getL2Output.selector),\n abi.encode(outputRoot, 0)\n );\n\n // Start the withdrawal, it must be initiated by the _sender and the\n // correct value must be passed along\n vm.deal(_tx.sender, _tx.value);\n vm.prank(_tx.sender);\n messagePasser.initiateWithdrawal{ value: _tx.value }(_tx.target, _tx.gasLimit, _tx.data);\n\n // Ensure that the sentMessages is correct\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n op.proveWithdrawalTransaction(\n _tx,\n 100, // l2BlockNumber\n proof,\n withdrawalProof\n );\n }\n}\n\ncontract OptimismPortalUpgradeable_Test is Portal_Initializer {\n Proxy internal proxy;\n uint64 initialBlockNum;\n\n function setUp() public override {\n super.setUp();\n initialBlockNum = uint64(block.number);\n proxy = Proxy(payable(address(op)));\n }\n\n function test_params_initValuesOnProxy_succeeds() external {\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = OptimismPortal(\n payable(address(proxy))\n ).params();\n assertEq(prevBaseFee, opImpl.INITIAL_BASE_FEE());\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_initialize_cannotInitProxy_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(payable(proxy)).initialize();\n }\n\n function test_initialize_cannotInitImpl_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(opImpl).initialize();\n }\n\n function test_upgradeToAndCall_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(op), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(op)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/Proxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract SimpleStorage {\n mapping(uint256 => uint256) internal store;\n\n function get(uint256 key) external payable returns (uint256) {\n return store[key];\n }\n\n function set(uint256 key, uint256 value) external payable {\n store[key] = value;\n }\n}\n\ncontract Clasher {\n function upgradeTo(address) external pure {\n revert(\"upgradeTo\");\n }\n}\n\ncontract Proxy_Test is Test {\n event Upgraded(address indexed implementation);\n event AdminChanged(address previousAdmin, address newAdmin);\n\n address alice = address(64);\n\n bytes32 internal constant IMPLEMENTATION_KEY =\n bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1);\n\n bytes32 internal constant OWNER_KEY = bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1);\n\n Proxy proxy;\n SimpleStorage simpleStorage;\n\n function setUp() external {\n // Deploy a proxy and simple storage contract as\n // the implementation\n proxy = new Proxy(alice);\n simpleStorage = new SimpleStorage();\n\n vm.prank(alice);\n proxy.upgradeTo(address(simpleStorage));\n }\n\n function test_implementationKey_succeeds() external {\n // The hardcoded implementation key should be correct\n vm.prank(alice);\n proxy.upgradeTo(address(6));\n\n bytes32 key = vm.load(address(proxy), IMPLEMENTATION_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(6));\n }\n\n function test_ownerKey_succeeds() external {\n // The hardcoded owner key should be correct\n vm.prank(alice);\n proxy.changeAdmin(address(6));\n\n bytes32 key = vm.load(address(proxy), OWNER_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(address(6));\n address owner = proxy.admin();\n assertEq(owner, address(6));\n }\n\n function test_proxyCallToImp_notAdmin_succeeds() external {\n // The implementation does not have a `upgradeTo`\n // method, calling `upgradeTo` not as the owner\n // should revert.\n vm.expectRevert();\n proxy.upgradeTo(address(64));\n\n // Call `upgradeTo` as the owner, it should succeed\n // and emit the `Upgraded` event.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(64));\n vm.prank(alice);\n proxy.upgradeTo(address(64));\n\n // Get the implementation as the owner\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(64));\n }\n\n function test_ownerProxyCall_notAdmin_succeeds() external {\n // Calling `changeAdmin` not as the owner should revert\n // as the implementation does not have a `changeAdmin` method.\n vm.expectRevert();\n proxy.changeAdmin(address(1));\n\n // Call `changeAdmin` as the owner, it should succeed\n // and emit the `AdminChanged` event.\n vm.expectEmit(true, true, true, true);\n emit AdminChanged(alice, address(1));\n vm.prank(alice);\n proxy.changeAdmin(address(1));\n\n // Calling `admin` not as the owner should\n // revert as the implementation does not have\n // a `admin` method.\n vm.expectRevert();\n proxy.admin();\n\n // Calling `admin` as the owner should work.\n vm.prank(address(1));\n address owner = proxy.admin();\n assertEq(owner, address(1));\n }\n\n function test_delegatesToImpl_succeeds() external {\n // Call the storage setter on the proxy\n SimpleStorage(address(proxy)).set(1, 1);\n\n // The key should not be set in the implementation\n uint256 result = simpleStorage.get(1);\n assertEq(result, 0);\n {\n // The key should be set in the proxy\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n\n {\n // The owner should be able to call through the proxy\n // when there is not a function selector crash\n vm.prank(alice);\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n }\n\n function test_upgradeToAndCall_succeeds() external {\n {\n // There should be nothing in the current proxy storage\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 0);\n }\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(simpleStorage));\n vm.prank(alice);\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The call should have impacted the state\n uint256 result = SimpleStorage(address(proxy)).get(1);\n assertEq(result, 1);\n }\n\n function test_upgradeToAndCall_functionDoesNotExist_reverts() external {\n // Get the current implementation address\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call. This reverts because the calldata doesn't\n // match a function on the implementation.\n vm.expectRevert(\"Proxy: delegatecall to new implementation contract failed\");\n vm.prank(alice);\n proxy.upgradeToAndCall(address(simpleStorage), hex\"\");\n\n // The implementation address should have not\n // updated because the call to `upgradeToAndCall`\n // reverted.\n vm.prank(alice);\n address postImpl = proxy.implementation();\n assertEq(impl, postImpl);\n\n // The attempt to `upgradeToAndCall`\n // should revert when it is not called by the owner.\n vm.expectRevert();\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n }\n\n function test_upgradeToAndCall_isPayable_succeeds() external {\n // Give alice some funds\n vm.deal(alice, 1 ether);\n // Set the implementation and call and send\n // value.\n vm.prank(alice);\n proxy.upgradeToAndCall{ value: 1 ether }(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The implementation address should be correct\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // The proxy should have a balance\n assertEq(address(proxy).balance, 1 ether);\n }\n\n function test_upgradeTo_clashingFunctionSignatures_succeeds() external {\n // Clasher has a clashing function with the proxy.\n Clasher clasher = new Clasher();\n\n // Set the clasher as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(clasher));\n\n {\n // Assert that the implementation was set properly.\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(clasher));\n }\n\n // Call the clashing function on the proxy\n // not as the owner so that the call passes through.\n // The implementation will revert so we can be\n // sure that the call passed through.\n vm.expectRevert(bytes(\"upgradeTo\"));\n proxy.upgradeTo(address(0));\n\n {\n // Now call the clashing function as the owner\n // and be sure that it doesn't pass through to\n // the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(0));\n }\n }\n\n // Allow for `eth_call` to call proxy methods\n // by setting \"from\" to `address(0)`.\n function test_implementation_zeroAddressCaller_succeeds() external {\n vm.prank(address(0));\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n }\n\n function test_implementation_isZeroAddress_reverts() external {\n // Set `address(0)` as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n\n (bool success, bytes memory returndata) = address(proxy).call(hex\"\");\n assertEq(success, false);\n\n bytes memory err = abi.encodeWithSignature(\n \"Error(string)\",\n \"Proxy: implementation not initialized\"\n );\n\n assertEq(returndata, err);\n }\n}\n" - }, - "contracts/test/ProxyAdmin.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { SimpleStorage } from \"./Proxy.t.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\n\ncontract ProxyAdmin_Test is Test {\n address alice = address(64);\n\n Proxy proxy;\n L1ChugSplashProxy chugsplash;\n ResolvedDelegateProxy resolved;\n\n AddressManager addressManager;\n\n ProxyAdmin admin;\n\n SimpleStorage implementation;\n\n function setUp() external {\n // Deploy the proxy admin\n admin = new ProxyAdmin(alice);\n // Deploy the standard proxy\n proxy = new Proxy(address(admin));\n\n // Deploy the legacy L1ChugSplashProxy with the admin as the owner\n chugsplash = new L1ChugSplashProxy(address(admin));\n\n // Deploy the legacy AddressManager\n addressManager = new AddressManager();\n // The proxy admin must be the new owner of the address manager\n addressManager.transferOwnership(address(admin));\n // Deploy a legacy ResolvedDelegateProxy with the name `a`.\n // Whatever `a` is set to in AddressManager will be the address\n // that is used for the implementation.\n resolved = new ResolvedDelegateProxy(addressManager, \"a\");\n\n // Impersonate alice for setting up the admin.\n vm.startPrank(alice);\n // Set the address of the address manager in the admin so that it\n // can resolve the implementation address of legacy\n // ResolvedDelegateProxy based proxies.\n admin.setAddressManager(addressManager);\n // Set the reverse lookup of the ResolvedDelegateProxy\n // proxy\n admin.setImplementationName(address(resolved), \"a\");\n\n // Set the proxy types\n admin.setProxyType(address(proxy), ProxyAdmin.ProxyType.ERC1967);\n admin.setProxyType(address(chugsplash), ProxyAdmin.ProxyType.CHUGSPLASH);\n admin.setProxyType(address(resolved), ProxyAdmin.ProxyType.RESOLVED);\n vm.stopPrank();\n\n implementation = new SimpleStorage();\n }\n\n function test_setImplementationName_succeeds() external {\n vm.prank(alice);\n admin.setImplementationName(address(1), \"foo\");\n assertEq(admin.implementationName(address(1)), \"foo\");\n }\n\n function test_setAddressManager_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setAddressManager(AddressManager((address(0))));\n }\n\n function test_setImplementationName_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setImplementationName(address(0), \"foo\");\n }\n\n function test_setProxyType_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setProxyType(address(0), ProxyAdmin.ProxyType.CHUGSPLASH);\n }\n\n function test_owner_succeeds() external {\n assertEq(admin.owner(), alice);\n }\n\n function test_proxyType_succeeds() external {\n assertEq(uint256(admin.proxyType(address(proxy))), uint256(ProxyAdmin.ProxyType.ERC1967));\n assertEq(\n uint256(admin.proxyType(address(chugsplash))),\n uint256(ProxyAdmin.ProxyType.CHUGSPLASH)\n );\n assertEq(\n uint256(admin.proxyType(address(resolved))),\n uint256(ProxyAdmin.ProxyType.RESOLVED)\n );\n }\n\n function test_erc1967GetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(proxy));\n }\n\n function test_chugsplashGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(resolved));\n }\n\n function getProxyImplementation(address payable _proxy) internal {\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(0));\n }\n\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n }\n\n function test_erc1967GetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(resolved));\n }\n\n function getProxyAdmin(address payable _proxy) internal {\n address owner = admin.getProxyAdmin(_proxy);\n assertEq(owner, address(admin));\n }\n\n function test_erc1967ChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(resolved));\n }\n\n function changeProxyAdmin(address payable _proxy) internal {\n ProxyAdmin.ProxyType proxyType = admin.proxyType(address(_proxy));\n\n vm.prank(alice);\n admin.changeProxyAdmin(_proxy, address(128));\n\n // The proxy is no longer the admin and can\n // no longer call the proxy interface except for\n // the ResolvedDelegate type on which anybody can\n // call the admin interface.\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n vm.expectRevert(\"Proxy: implementation not initialized\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n vm.expectRevert(\"L1ChugSplashProxy: implementation is not set yet\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n // Just an empty block to show that all cases are covered\n } else {\n vm.expectRevert(\"ProxyAdmin: unknown proxy type\");\n }\n\n // Call the proxy contract directly to get the admin.\n // Different proxy types have different interfaces.\n vm.prank(address(128));\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n assertEq(Proxy(payable(_proxy)).admin(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n assertEq(L1ChugSplashProxy(payable(_proxy)).getOwner(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n assertEq(addressManager.owner(), address(128));\n } else {\n assert(false);\n }\n }\n\n function test_erc1967Upgrade_succeeds() external {\n upgrade(payable(proxy));\n }\n\n function test_chugsplashUpgrade_succeeds() external {\n upgrade(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgrade_succeeds() external {\n upgrade(payable(resolved));\n }\n\n function upgrade(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n\n function test_erc1967UpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(proxy));\n }\n\n function test_chugsplashUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(resolved));\n }\n\n function upgradeAndCall(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgradeAndCall(\n _proxy,\n address(implementation),\n abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1)\n );\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n\n uint256 got = SimpleStorage(address(_proxy)).get(1);\n assertEq(got, 1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.changeProxyAdmin(payable(proxy), address(0));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgrade(payable(proxy), address(implementation));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgradeAndCall(payable(proxy), address(implementation), hex\"\");\n }\n\n function test_isUpgrading_succeeds() external {\n assertEq(false, admin.isUpgrading());\n\n vm.prank(alice);\n admin.setUpgrading(true);\n assertEq(true, admin.isUpgrading());\n }\n}\n" - }, - "contracts/test/RLP.t.sol": { - "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\n/**\n * @title LibRLP\n * @notice Via https://github.com/Rari-Capital/solmate/issues/207.\n */\nlibrary LibRLP {\n using Bytes32AddressLib for bytes32;\n\n function computeAddress(address deployer, uint256 nonce) internal pure returns (address) {\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))\n .fromLast20Bytes();\n if (nonce <= 0x7f)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))\n .fromLast20Bytes();\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= type(uint8).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd7),\n bytes1(0x94),\n deployer,\n bytes1(0x81),\n uint8(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint16).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd8),\n bytes1(0x94),\n deployer,\n bytes1(0x82),\n uint16(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint24).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd9),\n bytes1(0x94),\n deployer,\n bytes1(0x83),\n uint24(nonce)\n )\n ).fromLast20Bytes();\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return\n keccak256(\n abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))\n ).fromLast20Bytes();\n }\n}\n" - }, - "contracts/test/RLPReader.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { RLPReader } from \"../libraries/rlp/RLPReader.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { stdError } from \"forge-std/Test.sol\";\n\ncontract RLPReader_Test is CommonTest {\n function test_readBytes_bytestring00_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"00\"), hex\"00\");\n }\n\n function test_readBytes_bytestring01_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"01\"), hex\"01\");\n }\n\n function test_readBytes_bytestring7f_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"7f\"), hex\"7f\");\n }\n\n function test_readBytes_revertListItem_reverts() external {\n vm.expectRevert(\"RLPReader: decoded item type for bytes is not a data item\");\n RLPReader.readBytes(hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_readBytes_invalidStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n RLPReader.readBytes(hex\"b9\");\n }\n\n function test_readBytes_invalidListLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n RLPReader.readBytes(hex\"ff\");\n }\n\n function test_readBytes_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: bytes value contains an invalid remainder\");\n RLPReader.readBytes(hex\"800a\");\n }\n\n function test_readBytes_invalidPrefix_reverts() external {\n vm.expectRevert(\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n RLPReader.readBytes(hex\"810a\");\n }\n\n function test_readList_empty_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c0\");\n assertEq(list.length, 0);\n }\n\n function test_readList_multiList_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c6827a77c10401\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"827a77\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c104\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"01\");\n }\n\n function test_readList_shortListMax1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n\n assertEq(list.length, 11);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[4]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[5]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[6]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[7]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[8]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[9]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[10]), hex\"8471776572\");\n }\n\n function test_readList_longList1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n\n assertEq(list.length, 4);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"cf84617364668471776572847a786376\");\n }\n\n function test_readList_longList2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n assertEq(list.length, 32);\n\n for (uint256 i = 0; i < 32; i++) {\n assertEq(RLPReader.readRawBytes(list[i]), hex\"cf84617364668471776572847a786376\");\n }\n }\n\n function test_readList_listLongerThan32Elements_reverts() external {\n vm.expectRevert(stdError.indexOOBError);\n RLPReader.readList(\n hex\"e1454545454545454545454545454545454545454545454545454545454545454545\"\n );\n }\n\n function test_readList_listOfLists_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c4c2c0c0c0\");\n assertEq(list.length, 2);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c2c0c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c0\");\n }\n\n function test_readList_listOfLists2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c7c0c1c0c3c0c1c0\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c1c0\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"c3c0c1c0\");\n }\n\n function test_readList_dictTest1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n assertEq(list.length, 4);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"ca846b6579318476616c31\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"ca846b6579328476616c32\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"ca846b6579338476616c33\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"ca846b6579348476616c34\");\n }\n\n function test_readList_invalidShortList_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efdebd\");\n }\n\n function test_readList_longStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efb83600\");\n }\n\n function test_readList_notLongEnough_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(\n hex\"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n );\n }\n\n function test_readList_int32Overflow_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"bf0f000000000000021111\");\n }\n\n function test_readList_int32Overflow2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ff0f000000000000021111\");\n }\n\n function test_readList_incorrectLengthInArray_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(hex\"b800\");\n }\n\n function test_readList_leadingZerosInLongLengthList1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must not have any leading zeros (long list)\");\n RLPReader.readList(\n hex\"fb00000040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_nonOptimalLongLengthArray1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b81000112233445566778899aabbccddeeff\");\n }\n\n function test_readList_nonOptimalLongLengthArray2_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b801ff\");\n }\n\n function test_readList_invalidValue_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n RLPReader.readList(hex\"91\");\n }\n\n function test_readList_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n RLPReader.readList(hex\"c000\");\n }\n\n function test_readList_notEnoughContentForString1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"ba010000aabbccddeeff\");\n }\n\n function test_readList_notEnoughContentForString2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"b840ffeeddccbbaa99887766554433221100\");\n }\n\n function test_readList_notEnoughContentForList1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"f90180\");\n }\n\n function test_readList_notEnoughContentForList2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ffffffffffffffffff0001020304050607\");\n }\n\n function test_readList_longStringLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b80100\");\n }\n\n function test_readList_longListLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long list)\");\n RLPReader.readList(hex\"f80100\");\n }\n}\n" - }, - "contracts/test/RLPWriter.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { RLPWriter } from \"../libraries/rlp/RLPWriter.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\n\ncontract RLPWriter_Test is CommonTest {\n function test_writeString_empty_succeeds() external {\n assertEq(RLPWriter.writeString(\"\"), hex\"80\");\n }\n\n function test_writeString_bytestring00_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0000\"), hex\"00\");\n }\n\n function test_writeString_bytestring01_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0001\"), hex\"01\");\n }\n\n function test_writeString_bytestring7f_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u007F\"), hex\"7f\");\n }\n\n function test_writeString_shortstring_succeeds() external {\n assertEq(RLPWriter.writeString(\"dog\"), hex\"83646f67\");\n }\n\n function test_writeString_shortstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing eli\"),\n hex\"b74c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69\"\n );\n }\n\n function test_writeString_longstring_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing elit\"),\n hex\"b8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974\"\n );\n }\n\n function test_writeString_longstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\n \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat\"\n ),\n hex\"b904004c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742e20437572616269747572206d6175726973206d61676e612c20737573636970697420736564207665686963756c61206e6f6e2c20696163756c697320666175636962757320746f72746f722e2050726f696e20737573636970697420756c74726963696573206d616c6573756164612e204475697320746f72746f7220656c69742c2064696374756d2071756973207472697374697175652065752c20756c7472696365732061742072697375732e204d6f72626920612065737420696d70657264696574206d6920756c6c616d636f7270657220616c6971756574207375736369706974206e6563206c6f72656d2e2041656e65616e2071756973206c656f206d6f6c6c69732c2076756c70757461746520656c6974207661726975732c20636f6e73657175617420656e696d2e204e756c6c6120756c74726963657320747572706973206a7573746f2c20657420706f73756572652075726e6120636f6e7365637465747572206e65632e2050726f696e206e6f6e20636f6e76616c6c6973206d657475732e20446f6e65632074656d706f7220697073756d20696e206d617572697320636f6e67756520736f6c6c696369747564696e2e20566573746962756c756d20616e746520697073756d207072696d697320696e206661756369627573206f726369206c756374757320657420756c74726963657320706f737565726520637562696c69612043757261653b2053757370656e646973736520636f6e76616c6c69732073656d2076656c206d617373612066617563696275732c2065676574206c6163696e6961206c616375732074656d706f722e204e756c6c61207175697320756c747269636965732070757275732e2050726f696e20617563746f722072686f6e637573206e69626820636f6e64696d656e74756d206d6f6c6c69732e20416c697175616d20636f6e73657175617420656e696d206174206d65747573206c75637475732c206120656c656966656e6420707572757320656765737461732e20437572616269747572206174206e696268206d657475732e204e616d20626962656e64756d2c206e6571756520617420617563746f72207472697374697175652c206c6f72656d206c696265726f20616c697175657420617263752c206e6f6e20696e74657264756d2074656c6c7573206c65637475732073697420616d65742065726f732e20437261732072686f6e6375732c206d65747573206163206f726e617265206375727375732c20646f6c6f72206a7573746f20756c747269636573206d657475732c20617420756c6c616d636f7270657220766f6c7574706174\"\n );\n }\n\n function test_writeUint_zero_succeeds() external {\n assertEq(RLPWriter.writeUint(0x0), hex\"80\");\n }\n\n function test_writeUint_smallint_succeeds() external {\n assertEq(RLPWriter.writeUint(1), hex\"01\");\n }\n\n function test_writeUint_smallint2_succeeds() external {\n assertEq(RLPWriter.writeUint(16), hex\"10\");\n }\n\n function test_writeUint_smallint3_succeeds() external {\n assertEq(RLPWriter.writeUint(79), hex\"4f\");\n }\n\n function test_writeUint_smallint4_succeeds() external {\n assertEq(RLPWriter.writeUint(127), hex\"7f\");\n }\n\n function test_writeUint_mediumint_succeeds() external {\n assertEq(RLPWriter.writeUint(128), hex\"8180\");\n }\n\n function test_writeUint_mediumint2_succeeds() external {\n assertEq(RLPWriter.writeUint(1000), hex\"8203e8\");\n }\n\n function test_writeUint_mediumint3_succeeds() external {\n assertEq(RLPWriter.writeUint(100000), hex\"830186a0\");\n }\n\n function test_writeList_empty_succeeds() external {\n assertEq(RLPWriter.writeList(new bytes[](0)), hex\"c0\");\n }\n\n function test_writeList_stringList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeString(\"dog\");\n list[1] = RLPWriter.writeString(\"god\");\n list[2] = RLPWriter.writeString(\"cat\");\n\n assertEq(RLPWriter.writeList(list), hex\"cc83646f6783676f6483636174\");\n }\n\n function test_writeList_multiList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeUint(4);\n\n list[0] = RLPWriter.writeString(\"zw\");\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeUint(1);\n\n assertEq(RLPWriter.writeList(list), hex\"c6827a77c10401\");\n }\n\n function test_writeList_shortListMax1_succeeds() external {\n bytes[] memory list = new bytes[](11);\n list[0] = RLPWriter.writeString(\"asdf\");\n list[1] = RLPWriter.writeString(\"qwer\");\n list[2] = RLPWriter.writeString(\"zxcv\");\n list[3] = RLPWriter.writeString(\"asdf\");\n list[4] = RLPWriter.writeString(\"qwer\");\n list[5] = RLPWriter.writeString(\"zxcv\");\n list[6] = RLPWriter.writeString(\"asdf\");\n list[7] = RLPWriter.writeString(\"qwer\");\n list[8] = RLPWriter.writeString(\"zxcv\");\n list[9] = RLPWriter.writeString(\"asdf\");\n list[10] = RLPWriter.writeString(\"qwer\");\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n }\n\n function test_writeList_longlist1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list2);\n list[3] = RLPWriter.writeList(list2);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_longlist2_succeeds() external {\n bytes[] memory list = new bytes[](32);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n for (uint256 i = 0; i < 32; i++) {\n list[i] = RLPWriter.writeList(list2);\n }\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_listoflists_succeeds() external {\n // [ [ [], [] ], [] ]\n bytes[] memory list = new bytes[](2);\n bytes[] memory list2 = new bytes[](2);\n\n list2[0] = RLPWriter.writeList(new bytes[](0));\n list2[1] = RLPWriter.writeList(new bytes[](0));\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(new bytes[](0));\n\n assertEq(RLPWriter.writeList(list), hex\"c4c2c0c0c0\");\n }\n\n function test_writeList_listoflists2_succeeds() external {\n // [ [], [[]], [ [], [[]] ] ]\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeList(new bytes[](0));\n\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeList(new bytes[](0));\n\n list[1] = RLPWriter.writeList(list2);\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeList(new bytes[](0));\n list3[1] = RLPWriter.writeList(list2);\n\n list[2] = RLPWriter.writeList(list3);\n\n assertEq(RLPWriter.writeList(list), hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_writeList_dictTest1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n\n bytes[] memory list1 = new bytes[](2);\n list1[0] = RLPWriter.writeString(\"key1\");\n list1[1] = RLPWriter.writeString(\"val1\");\n\n bytes[] memory list2 = new bytes[](2);\n list2[0] = RLPWriter.writeString(\"key2\");\n list2[1] = RLPWriter.writeString(\"val2\");\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeString(\"key3\");\n list3[1] = RLPWriter.writeString(\"val3\");\n\n bytes[] memory list4 = new bytes[](2);\n list4[0] = RLPWriter.writeString(\"key4\");\n list4[1] = RLPWriter.writeString(\"val4\");\n\n list[0] = RLPWriter.writeList(list1);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list3);\n list[3] = RLPWriter.writeList(list4);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n }\n}\n" - }, - "contracts/test/ResourceMetering.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\n\ncontract MeterUser is ResourceMetering {\n constructor() {\n initialize();\n }\n\n function initialize() public initializer {\n __ResourceMetering_init();\n }\n\n function use(uint64 _amount) public metered(_amount) {}\n}\n\ncontract ResourceMetering_Test is CommonTest {\n MeterUser internal meter;\n uint64 initialBlockNum;\n\n function setUp() external {\n _setUp();\n meter = new MeterUser();\n initialBlockNum = uint64(block.number);\n }\n\n function test_meter_initialResourceParams_succeeds() external {\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, meter.INITIAL_BASE_FEE());\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_updateParamsNoChange_succeeds() external {\n meter.use(0); // equivalent to just updating the base fee and block number\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n meter.use(0);\n (uint128 postBaseFee, uint64 postBoughtGas, uint64 postBlockNum) = meter.params();\n\n assertEq(postBaseFee, prevBaseFee);\n assertEq(postBoughtGas, prevBoughtGas);\n assertEq(postBlockNum, prevBlockNum);\n }\n\n function test_meter_updateOneEmptyBlock_succeeds() external {\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n // Base fee decreases by 12.5%\n assertEq(prevBaseFee, 875000000);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 1);\n }\n\n function test_meter_updateTwoEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 2);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 765624999);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 2);\n }\n\n function test_meter_updateTenEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 10);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 263075576);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 10);\n }\n\n function test_meter_updateNoGasDelta_succeeds() external {\n uint64 target = uint64(uint256(meter.TARGET_RESOURCE_LIMIT()));\n meter.use(target);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1000000000);\n assertEq(prevBoughtGas, target);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_useMax_succeeds() external {\n uint64 target = uint64(uint256(meter.TARGET_RESOURCE_LIMIT()));\n uint64 elasticity = uint64(uint256(meter.ELASTICITY_MULTIPLIER()));\n meter.use(target * elasticity);\n\n (, uint64 prevBoughtGas, ) = meter.params();\n assertEq(prevBoughtGas, target * elasticity);\n\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 postBaseFee, , ) = meter.params();\n // Base fee increases by 1/8 the difference\n assertEq(postBaseFee, 1375000000);\n }\n\n function test_meter_useMoreThanMax_reverts() external {\n uint64 target = uint64(uint256(meter.TARGET_RESOURCE_LIMIT()));\n uint64 elasticity = uint64(uint256(meter.ELASTICITY_MULTIPLIER()));\n vm.expectRevert(\"ResourceMetering: cannot buy more gas than available gas limit\");\n meter.use(target * elasticity + 1);\n }\n}\n" - }, - "contracts/test/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\n\ncontract SafeCall_Test is CommonTest {\n function testFuzz_safeCall_succeeds(\n address from,\n address to,\n uint256 gas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles\n vm.assume(uint160(to) > 10);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n // don't send funds to self\n vm.assume(from != to);\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n vm.expectCall(to, value, data);\n\n vm.prank(from);\n bool success = SafeCall.call(to, gas, value, data);\n\n assertEq(success, true, \"call not successful\");\n assertEq(to.balance, value, \"to balance received\");\n assertEq(from.balance, 0, \"from balance not drained\");\n }\n}\n" - }, - "contracts/test/Semver.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\n\n/**\n * @notice Test the Semver contract that is used for semantic versioning\n * of various contracts.\n */\ncontract Semver_Test is CommonTest {\n /**\n * @notice Global semver contract deployed in setUp. This is used in\n * the test cases.\n */\n Semver semver;\n\n /**\n * @notice Deploy a Semver contract\n */\n function setUp() external {\n semver = new Semver(7, 8, 0);\n }\n\n /**\n * @notice Test the version getter\n */\n function test_version_succeeds() external {\n assertEq(semver.version(), \"7.8.0\");\n }\n\n /**\n * @notice Since the versions are all immutable, they should\n * be able to be accessed from behind a proxy without needing\n * to initialize the contract.\n */\n function test_behindProxy_succeeds() external {\n Proxy proxy = new Proxy(alice);\n vm.prank(alice);\n proxy.upgradeTo(address(semver));\n\n assertEq(Semver(address(proxy)).version(), \"7.8.0\");\n }\n}\n" - }, - "contracts/test/SequencerFeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { SequencerFeeVault } from \"../L2/SequencerFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract SequencerFeeVault_Test is Bridge_Initializer {\n SequencerFeeVault vault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET));\n address constant recipient = address(256);\n\n event Withdrawal(uint256 value, address to, address from);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.SEQUENCER_FEE_WALLET, address(new SequencerFeeVault(recipient)).code);\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n\n function test_constructor_succeeds() external {\n assertEq(vault.l1FeeWallet(), recipient);\n }\n\n function test_receive_succeeds() external {\n assertEq(address(vault).balance, 0);\n\n vm.prank(alice);\n (bool success, ) = address(vault).call{ value: 100 }(hex\"\");\n\n assertEq(success, true);\n assertEq(address(vault).balance, 100);\n }\n\n function test_withdraw_notEnough_reverts() external {\n assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());\n\n vm.expectRevert(\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n vault.withdraw();\n }\n\n function test_withdraw_succeeds() external {\n uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1;\n vm.deal(address(vault), amount);\n\n // No ether has been withdrawn yet\n assertEq(vault.totalProcessed(), 0);\n\n vm.expectEmit(true, true, true, true);\n emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));\n\n // The entire vault's balance is withdrawn\n vm.expectCall(\n Predeploys.L2_STANDARD_BRIDGE,\n address(vault).balance,\n abi.encodeWithSelector(\n StandardBridge.bridgeETHTo.selector,\n vault.l1FeeWallet(),\n 20000,\n bytes(\"\")\n )\n );\n\n vault.withdraw();\n\n // The withdrawal was successful\n assertEq(vault.totalProcessed(), amount);\n }\n}\n" - }, - "contracts/test/SystemConfig.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\n\ncontract SystemConfig_Init is CommonTest {\n SystemConfig sysConf;\n\n function setUp() external {\n sysConf = new SystemConfig({\n _owner: alice,\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 9_000_000,\n _unsafeBlockSigner: address(1)\n });\n }\n}\n\ncontract SystemConfig_Initialize_TestFail is CommonTest {\n function test_initialize_lowGasLimit_reverts() external {\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n\n // The minimum gas limit defined in SystemConfig:\n uint64 MINIMUM_GAS_LIMIT = 8_000_000;\n new SystemConfig({\n _owner: alice,\n _overhead: 0,\n _scalar: 0,\n _batcherHash: bytes32(hex\"\"),\n _gasLimit: MINIMUM_GAS_LIMIT - 1,\n _unsafeBlockSigner: address(1)\n });\n }\n}\n\ncontract SystemConfig_Setters_TestFail is SystemConfig_Init {\n function test_setBatcherHash_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setBatcherHash(bytes32(hex\"\"));\n }\n\n function test_setGasConfig_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasConfig(0, 0);\n }\n\n function test_setGasLimit_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasLimit(0);\n }\n\n function test_setUnsafeBlockSigner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setUnsafeBlockSigner(address(0x20));\n }\n}\n\ncontract SystemConfig_Setters_Test is SystemConfig_Init {\n event ConfigUpdate(\n uint256 indexed version,\n SystemConfig.UpdateType indexed updateType,\n bytes data\n );\n\n function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash));\n\n vm.prank(sysConf.owner());\n sysConf.setBatcherHash(newBatcherHash);\n assertEq(sysConf.batcherHash(), newBatcherHash);\n }\n\n function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.GAS_CONFIG,\n abi.encode(newOverhead, newScalar)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setGasConfig(newOverhead, newScalar);\n assertEq(sysConf.overhead(), newOverhead);\n assertEq(sysConf.scalar(), newScalar);\n }\n\n function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {\n uint64 minimumGasLimit = sysConf.MINIMUM_GAS_LIMIT();\n newGasLimit = uint64(\n bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))\n );\n\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit));\n\n vm.prank(sysConf.owner());\n sysConf.setGasLimit(newGasLimit);\n assertEq(sysConf.gasLimit(), newGasLimit);\n }\n\n function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER,\n abi.encode(newUnsafeSigner)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setUnsafeBlockSigner(newUnsafeSigner);\n assertEq(sysConf.unsafeBlockSigner(), newUnsafeSigner);\n }\n}\n" - }, - "contracts/test/invariants/CrossDomainMessenger.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { InvariantTest } from \"forge-std/InvariantTest.sol\";\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { OptimismPortal } from \"../../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../../L1/L1CrossDomainMessenger.sol\";\nimport { Messenger_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\nimport { Predeploys } from \"../../libraries/Predeploys.sol\";\nimport { Encoding } from \"../../libraries/Encoding.sol\";\nimport { Hashing } from \"../../libraries/Hashing.sol\";\n\ncontract RelayActor is StdUtils {\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n uint256 public numHashes;\n bytes32[] public hashes;\n bool public reverted = false;\n\n OptimismPortal op;\n L1CrossDomainMessenger xdm;\n Vm vm;\n\n constructor(\n OptimismPortal _op,\n L1CrossDomainMessenger _xdm,\n Vm _vm\n ) {\n op = _op;\n xdm = _xdm;\n vm = _vm;\n }\n\n /**\n * Relays a message to the `L1CrossDomainMessenger` with a random `version`, `_minGasLimit`\n * and `_message`.\n */\n function relay(\n uint16 _version,\n uint32 _minGasLimit,\n bytes memory _message\n ) external {\n address target = address(0x04); // ID precompile\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Restrict `_minGasLimit` to a number in the range of the block gas limit.\n _minGasLimit = uint32(bound(_minGasLimit, 0, block.gaslimit));\n\n // Restrict version to the range of [0, 1]\n _version = _version % 2;\n\n // Compute the cross domain message hash and store it in `hashes`.\n // The `relayMessage` function will always encode the message as a version 1\n // message after checking that the V0 hash has not already been relayed.\n bytes32 _hash = Hashing.hashCrossDomainMessageV1(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n 0, // value\n _minGasLimit,\n _message\n );\n\n // Act as the optimism portal and call `relayMessage` on the `L1CrossDomainMessenger` with\n // the outer min gas limit.\n vm.startPrank(address(op));\n vm.expectCall(target, _message);\n try\n xdm.relayMessage{ gas: xdm.baseGas(_message, _minGasLimit) }(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n 0, // value\n _minGasLimit,\n _message\n )\n {} catch {\n // If any of these calls revert, set `reverted` to true to fail the invariant test.\n // NOTE: This is to get around forge's invariant fuzzer ignoring reverted calls\n // to this function.\n reverted = true;\n }\n vm.stopPrank();\n\n hashes.push(_hash);\n numHashes += 1;\n }\n}\n\ncontract XDM_MinGasLimits is Messenger_Initializer, InvariantTest {\n RelayActor actor;\n\n function setUp() public override {\n // Set up the `L1CrossDomainMessenger` and `OptimismPortal` contracts.\n super.setUp();\n\n // Deploy a relay actor\n actor = new RelayActor(op, L1Messenger, vm);\n\n // Target the `RelayActor` contract\n targetContract(address(actor));\n\n // Target the actor's `relay` function\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.relay.selector;\n targetSelector(FuzzSelector({ addr: address(actor), selectors: selectors }));\n }\n\n /**\n * @custom:invariant A call to `relayMessage` should never revert if at least the proper minimum\n * gas limits are supplied.\n *\n * There are two minimum gas limits here:\n *\n * - The outer min gas limit is for the call from the `OptimismPortal` to the\n * `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function\n * with the `message` and inner limit.\n *\n * - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target\n * contract.\n */\n function invariant_minGasLimits() public {\n uint256 length = actor.numHashes();\n for (uint256 i = 0; i < length; ++i) {\n bytes32 hash = actor.hashes(i);\n // the message hash is in the successfulMessages mapping\n assertTrue(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertFalse(L1Messenger.failedMessages(hash));\n }\n assertFalse(actor.reverted());\n }\n}\n" - }, - "contracts/test/invariants/L2OutputOracle.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { InvariantTest } from \"forge-std/InvariantTest.sol\";\nimport { L2OutputOracle_Initializer } from \"../CommonTest.t.sol\";\n\ncontract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is\n InvariantTest,\n L2OutputOracle_Initializer\n{\n function setUp() public override {\n super.setUp();\n\n // Set the target contract to the oracle proxy\n targetContract(address(oracle));\n // Set the target sender to the proposer\n targetSender(address(proposer));\n // Set the target selector for `proposeL2Output`\n // `proposeL2Output` is the only function we care about, as it is the only function\n // that can modify the `l2Outputs` array in the oracle.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = oracle.proposeL2Output.selector;\n FuzzSelector memory selector = FuzzSelector({\n addr: address(oracle),\n selectors: selectors\n });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The block number of the output root proposals should monotonically\n * increase.\n *\n * When a new output is submitted, it should never be allowed to correspond to a block\n * number that is less than the current output.\n */\n function invariant_monotonicBlockNumIncrease() external {\n // Assert that the block number of proposals must monotonically increase.\n assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber());\n }\n}\n" - }, - "contracts/test/invariants/OptimismPortal.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { InvariantTest } from \"forge-std/InvariantTest.sol\";\nimport { Portal_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\n\ncontract OptimismPortal_Invariant_Harness is Portal_Initializer, InvariantTest {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n function setUp() public virtual override {\n super.setUp();\n\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n op.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n}\n\ncontract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization\n * period has not elapsed.\n *\n * A withdrawal that has been proven should not be able to be finalized until after\n * the finalization period has elapsed.\n */\n function invariant_cannotFinalizeBeforePeriodHasPassed() external {\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Finalize the withdrawal transaction.\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal\n * has already been finalized.\n *\n * Ensures that there is no chain of calls that can be made that allows a withdrawal\n * to be finalized twice.\n */\n function invariant_cannotFinalizeTwice() external {\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant A withdrawal should **always** be able to be finalized\n * `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.\n *\n * This invariant asserts that there is no chain of calls that can be made that\n * will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS`\n * after it was successfully proven.\n */\n function invariant_canAlwaysFinalize() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value);\n }\n}\n" - }, - "contracts/test/invariants/SystemConfig.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { InvariantTest } from \"forge-std/InvariantTest.sol\";\nimport { StdAssertions } from \"forge-std/StdAssertions.sol\";\nimport { SystemConfig } from \"../../L1/SystemConfig.sol\";\n\ncontract SystemConfig_GasLimitLowerBound_Invariant is InvariantTest, StdAssertions {\n SystemConfig public config;\n\n function setUp() public {\n config = new SystemConfig({\n _owner: address(0xbeef),\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 8_000_000,\n _unsafeBlockSigner: address(1)\n });\n\n // Set the target contract to the `config`\n targetContract(address(config));\n // Set the target sender to the `config`'s owner (0xbeef)\n targetSender(address(0xbeef));\n // Set the target selector for `setGasLimit`\n // `setGasLimit` is the only function we care about, as it is the only function\n // that can modify the gas limit within the SystemConfig.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = config.setGasLimit.selector;\n FuzzSelector memory selector = FuzzSelector({\n addr: address(config),\n selectors: selectors\n });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The gas limit of the `SystemConfig` contract can never be lower\n * than the hard-coded lower bound.\n */\n function invariant_gasLimitLowerBound() external {\n assertTrue(config.gasLimit() >= config.MINIMUM_GAS_LIMIT());\n }\n}\n" - }, - "contracts/universal/CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {\n PausableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * libAddressManager variable used to exist. Must be the first contract in the inheritance\n * tree of the CrossDomainMessenger\n */\ncontract CrossDomainMessengerLegacySpacer {\n /**\n * @custom:legacy\n * @custom:spacer libAddressManager\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n}\n\n/**\n * @custom:upgradeable\n * @title CrossDomainMessenger\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\n * cross-chain messenger contracts. It's designed to be a universal interface that only\n * needs to be extended slightly to provide low-level message passing functionality on each\n * chain it's deployed on. Currently only designed for message passing between two paired\n * chains and does not support one-to-many interactions.\n */\nabstract contract CrossDomainMessenger is\n CrossDomainMessengerLegacySpacer,\n OwnableUpgradeable,\n PausableUpgradeable,\n ReentrancyGuardUpgradeable\n{\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Constant overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_CONSTANT_OVERHEAD = 200_000;\n\n /**\n * @notice Numerator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 1016;\n\n /**\n * @notice Denominator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 1000;\n\n /**\n * @notice Extra gas added to base gas for each byte of calldata in a message.\n */\n uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\n\n /**\n * @notice Minimum amount of gas required to relay a message.\n */\n uint256 internal constant RELAY_GAS_REQUIRED = 45_000;\n\n /**\n * @notice Amount of gas held in reserve to guarantee that relay execution completes.\n */\n uint256 internal constant RELAY_GAS_BUFFER = RELAY_GAS_REQUIRED - 5000;\n\n /**\n * @notice Address of the paired CrossDomainMessenger contract on the other chain.\n */\n address public immutable OTHER_MESSENGER;\n\n /**\n * @custom:legacy\n * @custom:spacer blockedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_201_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer relayedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_202_0_32;\n\n /**\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n * be present in this mapping if it has successfully been relayed on this chain, and\n * can therefore not be relayed again.\n */\n mapping(bytes32 => bool) public successfulMessages;\n\n /**\n * @notice Address of the sender of the currently executing message on the other chain. If the\n * value of this variable is the default value (0x00000000...dead) then no message is\n * currently being executed. Use the xDomainMessageSender getter which will throw an\n * error if this is the case.\n */\n address internal xDomainMsgSender;\n\n /**\n * @notice Nonce for the next message to be sent, without the message version applied. Use the\n * messageNonce getter which will insert the message version into the nonce to give you\n * the actual nonce to be used for the message.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Mapping of message hashes to a boolean if and only if the message has failed to be\n * executed at least once. A message will not be present in this mapping if it\n * successfully executed on the first attempt.\n */\n mapping(bytes32 => bool) public failedMessages;\n\n /**\n * @notice Reserve extra slots in the storage layout for future upgrades.\n * A gap size of 41 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[42] private __gap;\n\n /**\n * @notice Emitted whenever a message is sent to the other chain.\n *\n * @param target Address of the recipient of the message.\n * @param sender Address of the sender of the message.\n * @param message Message to trigger the recipient address with.\n * @param messageNonce Unique nonce attached to the message.\n * @param gasLimit Minimum gas limit that the message can be executed with.\n */\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n /**\n * @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the\n * SentMessage event without breaking the ABI of this contract, this is good enough.\n *\n * @param sender Address of the sender of the message.\n * @param value ETH value sent along with the message to the recipient.\n */\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n /**\n * @notice Emitted whenever a message is successfully relayed on this chain.\n *\n * @param msgHash Hash of the message that was relayed.\n */\n event RelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @notice Emitted whenever a message fails to be relayed on this chain.\n *\n * @param msgHash Hash of the message that failed to be relayed.\n */\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @param _otherMessenger Address of the messenger on the paired chain.\n */\n constructor(address _otherMessenger) {\n OTHER_MESSENGER = _otherMessenger;\n }\n\n /**\n * @notice Allows the owner of this contract to temporarily pause message relaying. Backup\n * security mechanism just in case. Owner should be the same as the upgrade wallet to\n * maintain the security model of the system as a whole.\n */\n function pause() external onlyOwner {\n _pause();\n }\n\n /**\n * @notice Allows the owner of this contract to resume message relaying once paused.\n */\n function unpause() external onlyOwner {\n _unpause();\n }\n\n /**\n * @notice Sends a message to some target address on the other chain. Note that if the call\n * always reverts, then the message will be unrelayable, and any ETH sent will be\n * permanently locked. The same will occur if the target on the other chain is\n * considered unsafe (see the _isUnsafeTarget() function).\n *\n * @param _target Target contract or wallet address.\n * @param _message Message to trigger the target address with.\n * @param _minGasLimit Minimum gas limit that the message can be executed with.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _minGasLimit\n ) external payable {\n // Triggers a message to the other messenger. Note that the amount of gas provided to the\n // message is the amount of gas requested by the user PLUS the base gas value. We want to\n // guarantee the property that the call to the target contract will always have at least\n // the minimum gas limit specified by the user.\n _sendMessage(\n OTHER_MESSENGER,\n baseGas(_message, _minGasLimit),\n msg.value,\n abi.encodeWithSelector(\n this.relayMessage.selector,\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _minGasLimit,\n _message\n )\n );\n\n emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit);\n emit SentMessageExtension1(msg.sender, msg.value);\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\n * be executed via cross-chain call from the other messenger OR if the message was\n * already received once and is currently being replayed.\n *\n * @param _nonce Nonce of the message being relayed.\n * @param _sender Address of the user who sent the message.\n * @param _target Address that the message is targeted at.\n * @param _value ETH value to send with the message.\n * @param _minGasLimit Minimum amount of gas that the message can be executed with.\n * @param _message Message to send to the target.\n */\n function relayMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _minGasLimit,\n bytes calldata _message\n ) external payable nonReentrant whenNotPaused {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n require(\n version < 2,\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // If the message is version 0, then it's a migrated legacy withdrawal. We therefore need\n // to check that the legacy version of the message has not already been relayed.\n if (version == 0) {\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce);\n require(\n successfulMessages[oldHash] == false,\n \"CrossDomainMessenger: legacy withdrawal already relayed\"\n );\n }\n\n // We use the v1 message hash as the unique identifier for the message because it commits\n // to the value and minimum gas limit of the message.\n bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _minGasLimit,\n _message\n );\n\n if (_isOtherMessenger()) {\n // These properties should always hold when the message is first submitted (as\n // opposed to being replayed).\n assert(msg.value == _value);\n assert(!failedMessages[versionedHash]);\n } else {\n require(\n msg.value == 0,\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n\n require(\n failedMessages[versionedHash],\n \"CrossDomainMessenger: message cannot be replayed\"\n );\n }\n\n require(\n _isUnsafeTarget(_target) == false,\n \"CrossDomainMessenger: cannot send message to blocked system address\"\n );\n\n require(\n successfulMessages[versionedHash] == false,\n \"CrossDomainMessenger: message has already been relayed\"\n );\n\n require(\n gasleft() >= _minGasLimit + RELAY_GAS_REQUIRED,\n \"CrossDomainMessenger: insufficient gas to relay message\"\n );\n\n xDomainMsgSender = _sender;\n bool success = SafeCall.call(_target, gasleft() - RELAY_GAS_BUFFER, _value, _message);\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n\n if (success == true) {\n successfulMessages[versionedHash] = true;\n emit RelayedMessage(versionedHash);\n } else {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n }\n }\n\n /**\n * @notice Retrieves the address of the contract or wallet that initiated the currently\n * executing message on the other chain. Will throw an error if there is no message\n * currently being executed. Allows the recipient of a call to see who triggered it.\n *\n * @return Address of the sender of the currently executing message on the other chain.\n */\n function xDomainMessageSender() external view returns (address) {\n require(\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER,\n \"CrossDomainMessenger: xDomainMessageSender is not set\"\n );\n\n return xDomainMsgSender;\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n\n /**\n * @notice Computes the amount of gas required to guarantee that a given message will be\n * received on the other chain without running out of gas. Guaranteeing that a message\n * will not run out of gas is important because this ensures that a message can always\n * be replayed on the other chain if it fails to execute completely.\n *\n * @param _message Message to compute the amount of required gas for.\n * @param _minGasLimit Minimum desired gas limit when message goes to target.\n *\n * @return Amount of gas required to guarantee message receipt.\n */\n function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {\n // We peform the following math on uint64s to avoid overflow errors. Multiplying the\n // by MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR would otherwise limit the _minGasLimit to\n // type(uint32).max / MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR ~= 4.2m.\n return\n // Dynamic overhead\n ((uint64(_minGasLimit) * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\n MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\n // Calldata overhead\n (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\n // Constant overhead\n MIN_GAS_CONSTANT_OVERHEAD;\n }\n\n /**\n * @notice Intializer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __CrossDomainMessenger_init() internal onlyInitializing {\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n __Context_init_unchained();\n __Ownable_init_unchained();\n __Pausable_init_unchained();\n __ReentrancyGuard_init_unchained();\n }\n\n /**\n * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @param _to Recipient of the message on the other chain.\n * @param _gasLimit Minimum gas limit the message can be executed with.\n * @param _value Amount of ETH to send with the message.\n * @param _data Message data.\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal virtual;\n\n /**\n * @notice Checks whether the message is coming from the other messenger. Implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @return Whether the message is coming from the other messenger.\n */\n function _isOtherMessenger() internal view virtual returns (bool);\n\n /**\n * @notice Checks whether a given call target is a system address that could cause the\n * messenger to peform an unsafe action. This is NOT a mechanism for blocking user\n * addresses. This is ONLY used to prevent the execution of messages to specific\n * system addresses that could cause security issues, e.g., having the\n * CrossDomainMessenger send messages to itself.\n *\n * @param _target Address of the contract to check.\n *\n * @return Whether or not the address is an unsafe system address.\n */\n function _isUnsafeTarget(address _target) internal view virtual returns (bool);\n}\n" - }, - "contracts/universal/ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721Bridge\n * @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.\n */\nabstract contract ERC721Bridge {\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Address of the bridge on the other network.\n */\n address public immutable OTHER_BRIDGE;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[49] private __gap;\n\n /**\n * @notice Emitted when an ERC721 bridge to the other network is initiated.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC721 bridge from the other network is finalized.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) && MESSENGER.xDomainMessageSender() == OTHER_BRIDGE,\n \"ERC721Bridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge) {\n require(_messenger != address(0), \"ERC721Bridge: messenger cannot be address(0)\");\n require(_otherBridge != address(0), \"ERC721Bridge: other bridge cannot be address(0)\");\n\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = _otherBridge;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for other bridge address.\n *\n * @return Address of the bridge on the other network.\n */\n function otherBridge() external view returns (address) {\n return OTHER_BRIDGE;\n }\n\n /**\n * @notice Initiates a bridge of an NFT to the caller's account on the other chain. Note that\n * this function can only be called by EOAs. Smart contract wallets should use the\n * `bridgeERC721To` function after ensuring that the recipient address on the remote\n * chain exists. Also note that the current owner of the token on this chain must\n * approve this contract to operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721(\n address _localToken,\n address _remoteToken,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n // Modifier requiring sender to be EOA. This prevents against a user error that would occur\n // if the sender is a smart contract wallet that has a different address on the remote chain\n // (or doesn't have an address on the remote chain at all). The user would fail to receive\n // the NFT if they use this function because it sends the NFT to the same address as the\n // caller. This check could be bypassed by a malicious contract via initcode, but it takes\n // care of the user error we want to avoid.\n require(!Address.isContract(msg.sender), \"ERC721Bridge: account is not externally owned\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note\n * that the current owner of the token on this chain must approve this contract to\n * operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n require(_to != address(0), \"ERC721Bridge: nft recipient cannot be address(0)\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Internal function for initiating a token bridge to the other domain.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _from Address of the sender on this domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other domain. Data supplied here will\n * not be used to execute any code on the other domain and is only emitted\n * as extra data for the convenience of off-chain tooling.\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal virtual;\n}\n" - }, - "contracts/universal/FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n/**\n * @title FeeVault\n * @notice The FeeVault contract contains the basic logic for the various different vault contracts\n * used to hold fee revenue generated by the L2 system.\n */\nabstract contract FeeVault {\n /**\n * @notice Emits each time that a withdrawal occurs.\n *\n * @param value Amount that was withdrawn (in wei).\n * @param to Address that the funds were sent to.\n * @param from Address that triggered the withdrawal.\n */\n event Withdrawal(uint256 value, address to, address from);\n\n /**\n * @notice Minimum balance before a withdrawal can be triggered.\n */\n uint256 public immutable MIN_WITHDRAWAL_AMOUNT;\n\n /**\n * @notice Wallet that will receive the fees on L1.\n */\n address public immutable RECIPIENT;\n\n /**\n * @notice Total amount of wei processed by the contract.\n */\n uint256 public totalProcessed;\n\n /**\n * @param _recipient Wallet that will receive the fees on L1.\n * @param _minWithdrawalAmount Minimum balance before a withdrawal can be triggered.\n */\n constructor(address _recipient, uint256 _minWithdrawalAmount) {\n MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;\n RECIPIENT = _recipient;\n }\n\n /**\n * @notice Allow the contract to receive ETH.\n */\n receive() external payable {}\n\n /**\n * @notice Triggers a withdrawal of funds to the L1 fee wallet.\n */\n function withdraw() external {\n require(\n address(this).balance >= MIN_WITHDRAWAL_AMOUNT,\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n\n uint256 value = address(this).balance;\n totalProcessed += value;\n\n emit Withdrawal(value, RECIPIENT, msg.sender);\n\n L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }(\n RECIPIENT,\n 20000,\n bytes(\"\")\n );\n }\n}\n" - }, - "contracts/universal/IOptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @title IOptimismMintableERC20\n * @notice This interface is available on the OptimismMintableERC20 contract. We declare it as a\n * separate interface so that it can be used in custom implementations of\n * OptimismMintableERC20.\n */\ninterface IOptimismMintableERC20 {\n function remoteToken() external returns (address);\n\n function bridge() external returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n\n/**\n * @custom:legacy\n * @title ILegacyMintableERC20\n * @notice This interface was available on the legacy L2StandardERC20 contract. It remains available\n * on the OptimismMintableERC20 contract for backwards compatibility.\n */\ninterface ILegacyMintableERC20 is IERC165 {\n function l1Token() external returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n" - }, - "contracts/universal/IOptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\n/**\n * @title IOptimismMintableERC721\n * @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.\n * Tokens that follow this standard can be easily transferred across the ERC721 bridge.\n */\ninterface IOptimismMintableERC721 is IERC721Enumerable {\n /**\n * @notice Emitted when a token is minted.\n *\n * @param account Address of the account the token was minted to.\n * @param tokenId Token ID of the minted token.\n */\n event Mint(address indexed account, uint256 tokenId);\n\n /**\n * @notice Emitted when a token is burned.\n *\n * @param account Address of the account the token was burned from.\n * @param tokenId Token ID of the burned token.\n */\n event Burn(address indexed account, uint256 tokenId);\n\n /**\n * @notice Mints some token ID for a user, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * @param _to Address of the user to mint the token for.\n * @param _tokenId Token ID to mint.\n */\n function safeMint(address _to, uint256 _tokenId) external;\n\n /**\n * @notice Burns a token ID from a user.\n *\n * @param _from Address of the user to burn the token from.\n * @param _tokenId Token ID to burn.\n */\n function burn(address _from, uint256 _tokenId) external;\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function REMOTE_CHAIN_ID() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function REMOTE_TOKEN() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function BRIDGE() external view returns (address);\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function remoteChainId() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function remoteToken() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function bridge() external view returns (address);\n}\n" - }, - "contracts/universal/OptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { ILegacyMintableERC20, IOptimismMintableERC20 } from \"./IOptimismMintableERC20.sol\";\n\n/**\n * @title OptimismMintableERC20\n * @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed\n * to allow the StandardBridge contracts to mint and burn tokens. This makes it possible to\n * use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa.\n * Designed to be backwards compatible with the older StandardL2ERC20 token which was only\n * meant for use on L2.\n */\ncontract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20 {\n /**\n * @notice Address of the corresponding version of this token on the remote chain.\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @notice Address of the StandardBridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Emitted whenever tokens are minted for an account.\n *\n * @param account Address of the account tokens are being minted for.\n * @param amount Amount of tokens minted.\n */\n event Mint(address indexed account, uint256 amount);\n\n /**\n * @notice Emitted whenever tokens are burned from an account.\n *\n * @param account Address of the account tokens are being burned from.\n * @param amount Amount of tokens burned.\n */\n event Burn(address indexed account, uint256 amount);\n\n /**\n * @notice A modifier that only allows the bridge to call\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC20: only bridge can mint and burn\");\n _;\n }\n\n /**\n * @param _bridge Address of the L2 standard bridge.\n * @param _remoteToken Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _bridge,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) {\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n }\n\n /**\n * @notice Allows the StandardBridge on this network to mint tokens.\n *\n * @param _to Address to mint tokens to.\n * @param _amount Amount of tokens to mint.\n */\n function mint(address _to, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _mint(_to, _amount);\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Allows the StandardBridge on this network to burn tokens.\n *\n * @param _from Address to burn tokens from.\n * @param _amount Amount of tokens to burn.\n */\n function burn(address _from, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _burn(_from, _amount);\n emit Burn(_from, _amount);\n }\n\n /**\n * @notice ERC165 interface check function.\n *\n * @param _interfaceId Interface ID to check.\n *\n * @return Whether or not the interface is supported by this contract.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 iface1 = type(IERC165).interfaceId;\n // Interface corresponding to the legacy L2StandardERC20.\n bytes4 iface2 = type(ILegacyMintableERC20).interfaceId;\n // Interface corresponding to the updated OptimismMintableERC20 (this contract).\n bytes4 iface3 = type(IOptimismMintableERC20).interfaceId;\n return _interfaceId == iface1 || _interfaceId == iface2 || _interfaceId == iface3;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote token. Use REMOTE_TOKEN going forward.\n */\n function l1Token() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the bridge. Use BRIDGE going forward.\n */\n function l2Bridge() public view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for REMOTE_TOKEN.\n */\n function remoteToken() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for BRIDGE.\n */\n function bridge() public view returns (address) {\n return BRIDGE;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC20Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Contract Imports */\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000012\n * @title OptimismMintableERC20Factory\n * @notice OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20\n * contracts on the network it's deployed to. Simplifies the deployment process for users\n * who may be less familiar with deploying smart contracts. Designed to be backwards\n * compatible with the older StandardL2ERC20Factory contract.\n */\ncontract OptimismMintableERC20Factory is Semver {\n /**\n * @notice Address of the StandardBridge on this chain.\n */\n address public immutable BRIDGE;\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a new OptimismMintableERC20 is created. Legacy version of the newer\n * OptimismMintableERC20Created event. We recommend relying on that event instead.\n *\n * @param remoteToken Address of the token on the remote chain.\n * @param localToken Address of the created token on the local chain.\n */\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC20 is created.\n *\n * @param localToken Address of the created token on the local chain.\n * @param remoteToken Address of the corresponding token on the remote chain.\n * @param deployer Address of the account that deployed the token.\n */\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the StandardBridge on this chain.\n */\n constructor(address _bridge) Semver(1, 0, 0) {\n BRIDGE = _bridge;\n }\n\n /**\n * @custom:legacy\n * @notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the\n * newer createOptimismMintableERC20 function, which has a more intuitive name.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createStandardL2Token(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n return createOptimismMintableERC20(_remoteToken, _name, _symbol);\n }\n\n /**\n * @notice Creates an instance of the OptimismMintableERC20 contract.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createOptimismMintableERC20(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) public returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC20Factory: must provide remote token address\"\n );\n\n address localToken = address(\n new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol)\n );\n\n // Emit the old event too for legacy support.\n emit StandardL2TokenCreated(_remoteToken, localToken);\n\n // Emit the updated event. The arguments here differ from the legacy event, but\n // are consistent with the ordering used in StandardBridge events.\n emit OptimismMintableERC20Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {\n ERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { IOptimismMintableERC721 } from \"./IOptimismMintableERC721.sol\";\n\n/**\n * @title OptimismMintableERC721\n * @notice This contract is the remote representation for some token that lives on another network,\n * typically an Optimism representation of an Ethereum-based token. Standard reference\n * implementation that can be extended or modified according to your needs.\n */\ncontract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721 {\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Base token URI for this token.\n */\n string public baseTokenURI;\n\n /**\n * @notice Modifier that prevents callers other than the bridge from calling the function.\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC721: only bridge can call this function\");\n _;\n }\n\n /**\n * @param _bridge Address of the bridge on this network.\n * @param _remoteChainId Chain ID where the remote token is deployed.\n * @param _remoteToken Address of the corresponding token on the other network.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n constructor(\n address _bridge,\n uint256 _remoteChainId,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n require(_bridge != address(0), \"OptimismMintableERC721: bridge cannot be address(0)\");\n require(_remoteChainId != 0, \"OptimismMintableERC721: remote chain id cannot be zero\");\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721: remote token cannot be address(0)\"\n );\n\n REMOTE_CHAIN_ID = _remoteChainId;\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n\n // Creates a base URI in the format specified by EIP-681:\n // https://eips.ethereum.org/EIPS/eip-681\n baseTokenURI = string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(_remoteToken), 20),\n \"@\",\n Strings.toString(_remoteChainId),\n \"/tokenURI?uint256=\"\n )\n );\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteChainId() external view returns (uint256) {\n return REMOTE_CHAIN_ID;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteToken() external view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function bridge() external view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function safeMint(address _to, uint256 _tokenId) external virtual onlyBridge {\n _safeMint(_to, _tokenId);\n\n emit Mint(_to, _tokenId);\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function burn(address _from, uint256 _tokenId) external virtual onlyBridge {\n _burn(_tokenId);\n\n emit Burn(_from, _tokenId);\n }\n\n /**\n * @notice Checks if a given interface ID is supported by this contract.\n *\n * @param _interfaceId The interface ID to check.\n *\n * @return True if the interface ID is supported, false otherwise.\n */\n function supportsInterface(bytes4 _interfaceId)\n public\n view\n override(ERC721Enumerable, IERC165)\n returns (bool)\n {\n bytes4 iface1 = type(IERC165).interfaceId;\n bytes4 iface2 = type(IOptimismMintableERC721).interfaceId;\n return\n _interfaceId == iface1 ||\n _interfaceId == iface2 ||\n super.supportsInterface(_interfaceId);\n }\n\n /**\n * @notice Returns the base token URI.\n *\n * @return Base token URI.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return baseTokenURI;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismMintableERC721 } from \"./OptimismMintableERC721.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @title OptimismMintableERC721Factory\n * @notice Factory contract for creating OptimismMintableERC721 contracts.\n */\ncontract OptimismMintableERC721Factory is Semver {\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Chain ID for the remote network.\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @notice Tracks addresses created by this factory.\n */\n mapping(address => bool) public isOptimismMintableERC721;\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC721 contract is created.\n *\n * @param localToken Address of the token on the this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param deployer Address of the initiator of the deployment\n */\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the ERC721 bridge on this network.\n * @param _remoteChainId Chain ID for the remote network.\n */\n constructor(address _bridge, uint256 _remoteChainId) Semver(1, 0, 0) {\n BRIDGE = _bridge;\n REMOTE_CHAIN_ID = _remoteChainId;\n }\n\n /**\n * @notice Creates an instance of the standard ERC721.\n *\n * @param _remoteToken Address of the corresponding token on the other domain.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n function createOptimismMintableERC721(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721Factory: L1 token address cannot be address(0)\"\n );\n\n address localToken = address(\n new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)\n );\n\n isOptimismMintableERC721[localToken] = true;\n emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/Proxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Proxy\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\n * if the caller is address(0), meaning that the call originated from an off-chain\n * simulation.\n */\ncontract Proxy {\n /**\n * @notice The storage slot that holds the address of the implementation.\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice The storage slot that holds the address of the owner.\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice An event that is emitted each time the implementation is changed. This event is part\n * of the EIP-1967 specification.\n *\n * @param implementation The address of the implementation contract\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\n * EIP-1967 specification.\n *\n * @param previousAdmin The previous owner of the contract\n * @param newAdmin The new owner of the contract\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\n * eth_call to interact with this proxy without needing to use low-level storage\n * inspection. We assume that nobody is able to trigger calls from address(0) during\n * normal EVM execution.\n */\n modifier proxyCallIfNotAdmin() {\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\n * EIP-1967 admin storage slot so that accidental storage collision with the\n * implementation is not possible.\n *\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\n * transparent proxy interface.\n */\n constructor(address _admin) {\n _changeAdmin(_admin);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Set the implementation contract address. The code at the given address will execute\n * when this contract is called.\n *\n * @param _implementation Address of the implementation contract.\n */\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\n _setImplementation(_implementation);\n }\n\n /**\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\n * atomic execution of initialization-based upgrades.\n *\n * @param _implementation Address of the implementation contract.\n * @param _data Calldata to delegatecall the new implementation with.\n */\n function upgradeToAndCall(address _implementation, bytes calldata _data)\n external\n payable\n proxyCallIfNotAdmin\n returns (bytes memory)\n {\n _setImplementation(_implementation);\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\n require(success, \"Proxy: delegatecall to new implementation contract failed\");\n return returndata;\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _admin New owner of the proxy contract.\n */\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\n _changeAdmin(_admin);\n }\n\n /**\n * @notice Gets the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function admin() external proxyCallIfNotAdmin returns (address) {\n return _getAdmin();\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function implementation() external proxyCallIfNotAdmin returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n emit Upgraded(_implementation);\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _admin New owner of the proxy contract.\n */\n function _changeAdmin(address _admin) internal {\n address previous = _getAdmin();\n assembly {\n sstore(OWNER_KEY, _admin)\n }\n emit AdminChanged(previous, _admin);\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal {\n address impl = _getImplementation();\n require(impl != address(0), \"Proxy: implementation not initialized\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address impl;\n assembly {\n impl := sload(IMPLEMENTATION_KEY)\n }\n return impl;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getAdmin() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n}\n" - }, - "contracts/universal/ProxyAdmin.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { Proxy } from \"./Proxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\n\n/**\n * @title IStaticERC1967Proxy\n * @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface.\n */\ninterface IStaticERC1967Proxy {\n function implementation() external view returns (address);\n\n function admin() external view returns (address);\n}\n\n/**\n * @title IStaticL1ChugSplashProxy\n * @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface.\n */\ninterface IStaticL1ChugSplashProxy {\n function getImplementation() external view returns (address);\n\n function getOwner() external view returns (address);\n}\n\n/**\n * @title ProxyAdmin\n * @notice This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy,\n * based on the OpenZeppelin implementation. It has backwards compatibility logic to work\n * with the various types of proxies that have been deployed by Optimism in the past.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @notice The proxy types that the ProxyAdmin can manage.\n *\n * @custom:value ERC1967 Represents an ERC1967 compliant transparent proxy interface.\n * @custom:value CHUGSPLASH Represents the Chugsplash proxy interface (legacy).\n * @custom:value RESOLVED Represents the ResolvedDelegate proxy (legacy).\n */\n enum ProxyType {\n ERC1967,\n CHUGSPLASH,\n RESOLVED\n }\n\n /**\n * @notice A mapping of proxy types, used for backwards compatibility.\n */\n mapping(address => ProxyType) public proxyType;\n\n /**\n * @notice A reverse mapping of addresses to names held in the AddressManager. This must be\n * manually kept up to date with changes in the AddressManager for this contract\n * to be able to work as an admin for the ResolvedDelegateProxy type.\n */\n mapping(address => string) public implementationName;\n\n /**\n * @notice The address of the address manager, this is required to manage the\n * ResolvedDelegateProxy type.\n */\n AddressManager public addressManager;\n\n /**\n * @notice A legacy upgrading indicator used by the old Chugsplash Proxy.\n */\n bool internal upgrading;\n\n /**\n * @param _owner Address of the initial owner of this contract.\n */\n constructor(address _owner) Ownable() {\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the proxy type for a given address. Only required for non-standard (legacy)\n * proxy types.\n *\n * @param _address Address of the proxy.\n * @param _type Type of the proxy.\n */\n function setProxyType(address _address, ProxyType _type) external onlyOwner {\n proxyType[_address] = _type;\n }\n\n /**\n * @notice Sets the implementation name for a given address. Only required for\n * ResolvedDelegateProxy type proxies that have an implementation name.\n *\n * @param _address Address of the ResolvedDelegateProxy.\n * @param _name Name of the implementation for the proxy.\n */\n function setImplementationName(address _address, string memory _name) external onlyOwner {\n implementationName[_address] = _name;\n }\n\n /**\n * @notice Set the address of the AddressManager. This is required to manage legacy\n * ResolvedDelegateProxy type proxy contracts.\n *\n * @param _address Address of the AddressManager.\n */\n function setAddressManager(AddressManager _address) external onlyOwner {\n addressManager = _address;\n }\n\n /**\n * @custom:legacy\n * @notice Set an address in the address manager. Since only the owner of the AddressManager\n * can directly modify addresses and the ProxyAdmin will own the AddressManager, this\n * gives the owner of the ProxyAdmin the ability to modify addresses directly.\n *\n * @param _name Name to set within the AddressManager.\n * @param _address Address to attach to the given name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n addressManager.setAddress(_name, _address);\n }\n\n /**\n * @custom:legacy\n * @notice Set the upgrading status for the Chugsplash proxy type.\n *\n * @param _upgrading Whether or not the system is upgrading.\n */\n function setUpgrading(bool _upgrading) external onlyOwner {\n upgrading = _upgrading;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\n *\n * @return Whether or not there is an upgrade going on. May not actually tell you whether an\n * upgrade is going on, since we don't currently plan to use this variable for anything\n * other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\n */\n function isUpgrading() external view returns (bool) {\n return upgrading;\n }\n\n /**\n * @notice Returns the implementation of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the implementation of.\n *\n * @return Address of the implementation of the proxy.\n */\n function getProxyImplementation(address _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).implementation();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getImplementation();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.getAddress(implementationName[_proxy]);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Returns the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the admin of.\n *\n * @return Address of the admin of the proxy.\n */\n function getProxyAdmin(address payable _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).admin();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getOwner();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.owner();\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Updates the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to update.\n * @param _newAdmin Address of the new proxy admin.\n */\n function changeProxyAdmin(address payable _proxy, address _newAdmin) external onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).changeAdmin(_newAdmin);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setOwner(_newAdmin);\n } else if (ptype == ProxyType.RESOLVED) {\n addressManager.transferOwnership(_newAdmin);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n */\n function upgrade(address payable _proxy, address _implementation) public onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeTo(_implementation);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setStorage(\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n bytes32(uint256(uint160(_implementation)))\n );\n } else if (ptype == ProxyType.RESOLVED) {\n string memory name = implementationName[_proxy];\n addressManager.setAddress(name, _implementation);\n } else {\n // It should not be possible to retrieve a ProxyType value which is not matched by\n // one of the previous conditions.\n assert(false);\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract and delegatecalls the new implementation\n * with some given data. Useful for atomic upgrade-and-initialize calls.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n * @param _data Data to trigger the new implementation with.\n */\n function upgradeAndCall(\n address payable _proxy,\n address _implementation,\n bytes memory _data\n ) external payable onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);\n } else {\n // reverts if proxy type is unknown\n upgrade(_proxy, _implementation);\n (bool success, ) = _proxy.call{ value: msg.value }(_data);\n require(success, \"ProxyAdmin: call to proxy after upgrade failed\");\n }\n }\n}\n" - }, - "contracts/universal/Semver.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n" - }, - "contracts/universal/StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { IOptimismMintableERC20, ILegacyMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"./OptimismMintableERC20.sol\";\n\n/**\n * @custom:upgradeable\n * @title StandardBridge\n * @notice StandardBridge is a base contract for the L1 and L2 standard ERC20 bridges. It handles\n * the core bridging logic, including escrowing tokens that are native to the local chain\n * and minting/burning tokens that are native to the remote chain.\n */\nabstract contract StandardBridge {\n using SafeERC20 for IERC20;\n\n /**\n * @notice The L2 gas limit set when eth is depoisited using the receive() function.\n */\n uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000;\n\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Corresponding bridge on the other domain.\n */\n StandardBridge public immutable OTHER_BRIDGE;\n\n /**\n * @custom:legacy\n * @custom:spacer messenger\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer l2TokenBridge\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_1_0_20;\n\n /**\n * @notice Mapping that stores deposits for a given pair of local and remote tokens.\n */\n mapping(address => mapping(address => uint256)) public deposits;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n * A gap size of 47 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[47] private __gap;\n\n /**\n * @notice Emitted when an ETH bridge is initiated to the other chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ETH bridge is finalized on this chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is initiated to the other chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is finalized on this chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Only allow EOAs to call the functions. Note that this is not safe against contracts\n * calling code within their constructors, but also doesn't really matter since we're\n * just trying to prevent users accidentally depositing with smart contract wallets.\n */\n modifier onlyEOA() {\n require(\n !Address.isContract(msg.sender),\n \"StandardBridge: function can only be called from an EOA\"\n );\n _;\n }\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) &&\n MESSENGER.xDomainMessageSender() == address(OTHER_BRIDGE),\n \"StandardBridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of CrossDomainMessenger on this network.\n * @param _otherBridge Address of the other StandardBridge contract.\n */\n constructor(address payable _messenger, address payable _otherBridge) {\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = StandardBridge(_otherBridge);\n }\n\n /**\n * @notice Allows EOAs to deposit ETH by sending directly to the bridge.\n */\n receive() external payable onlyEOA {\n _initiateBridgeETH(msg.sender, msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @notice Sends ETH to the sender's address on the other chain.\n *\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETH(uint32 _minGasLimit, bytes calldata _extraData) public payable onlyEOA {\n _initiateBridgeETH(msg.sender, msg.sender, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a\n * smart contract and the call fails, the ETH will be temporarily locked in the\n * StandardBridge on the other chain until the call is replayed. If the call cannot be\n * replayed with any amount of gas (call always reverts), then the ETH will be\n * permanently locked in the StandardBridge on the other chain. ETH will also\n * be locked if the receiver is the other bridge, because finalizeBridgeETH will revert\n * in that case.\n *\n * @param _to Address of the receiver.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public payable {\n _initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ERC20 tokens to the sender's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20(\n address _localToken,\n address _remoteToken,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual onlyEOA {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public payable onlyOtherBridge {\n require(msg.value == _amount, \"StandardBridge: amount sent does not match amount required\");\n require(_to != address(this), \"StandardBridge: cannot send to self\");\n require(_to != address(MESSENGER), \"StandardBridge: cannot send to messenger\");\n\n emit ETHBridgeFinalized(_from, _to, _amount, _extraData);\n\n bool success = SafeCall.call(_to, gasleft(), _amount, hex\"\");\n require(success, \"StandardBridge: ETH transfer failed\");\n }\n\n /**\n * @notice Finalizes an ERC20 bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public onlyOtherBridge {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).mint(_to, _amount);\n } else {\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] - _amount;\n IERC20(_localToken).safeTransfer(_to, _amount);\n }\n\n emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Initiates a bridge of ETH through the CrossDomainMessenger.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n require(\n msg.value == _amount,\n \"StandardBridge: bridging ETH must include sufficient ETH value\"\n );\n\n emit ETHBridgeInitiated(_from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage{ value: _amount }(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeETH.selector,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).burn(_from, _amount);\n } else {\n IERC20(_localToken).safeTransferFrom(_from, address(this), _amount);\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] + _amount;\n }\n\n emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeERC20.selector,\n // Because this call will be executed on the remote chain, we reverse the order of\n // the remote and local token addresses relative to their order in the\n // finalizeBridgeERC20 function.\n _remoteToken,\n _localToken,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Checks if a given address is an OptimismMintableERC20. Not perfect, but good enough.\n * Just the way we like it.\n *\n * @param _token Address of the token to check.\n *\n * @return True if the token is an OptimismMintableERC20.\n */\n function _isOptimismMintableERC20(address _token) internal view returns (bool) {\n return\n ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId) ||\n ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);\n }\n\n /**\n * @notice Checks if the \"other token\" is the correct pair token for the OptimismMintableERC20.\n *\n * @param _mintableToken OptimismMintableERC20 to check against.\n * @param _otherToken Pair token to check.\n *\n * @return True if the other token is the correct pair token for the OptimismMintableERC20.\n */\n function _isCorrectTokenPair(address _mintableToken, address _otherToken)\n internal\n view\n returns (bool)\n {\n return _otherToken == OptimismMintableERC20(_mintableToken).l1Token();\n }\n}\n" - }, - "contracts/vendor/AddressAliasHelper.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.0;\n\nlibrary AddressAliasHelper {\n uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n /// @notice Utility function that converts the address in the L1 that submitted a tx to\n /// the inbox to the msg.sender viewed in the L2\n /// @param l1Address the address in the L1 that triggered the tx to L2\n /// @return l2Address L2 address as viewed in msg.sender\n function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {\n unchecked {\n l2Address = address(uint160(l1Address) + offset);\n }\n }\n\n /// @notice Utility function that converts the msg.sender viewed in the L2 to the\n /// address in the L1 that submitted a tx to the inbox\n /// @param l2Address L2 address as viewed in msg.sender\n /// @return l1Address the address in the L1 that triggered the tx to L2\n function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {\n unchecked {\n l1Address = address(uint160(l2Address) - offset);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/governance/utils/IVotes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20Permit.sol\";\nimport \"../../../utils/math/Math.sol\";\nimport \"../../../governance/utils/IVotes.sol\";\nimport \"../../../utils/math/SafeCast.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20Votes is IVotes, ERC20Permit {\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCast.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = Math.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSA.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"./IERC721Enumerable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n // Mapping from owner to list of owned token IDs\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n // Mapping from token ID to index of the owner tokens list\n mapping(uint256 => uint256) private _ownedTokensIndex;\n\n // Array with all token ids, used for enumeration\n uint256[] private _allTokens;\n\n // Mapping from token id to position in the allTokens array\n mapping(uint256 => uint256) private _allTokensIndex;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n return _ownedTokens[owner][index];\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _allTokens.length;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721Enumerable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n return _allTokens[index];\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n if (from == address(0)) {\n _addTokenToAllTokensEnumeration(tokenId);\n } else if (from != to) {\n _removeTokenFromOwnerEnumeration(from, tokenId);\n }\n if (to == address(0)) {\n _removeTokenFromAllTokensEnumeration(tokenId);\n } else if (to != from) {\n _addTokenToOwnerEnumeration(to, tokenId);\n }\n }\n\n /**\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\n * @param to address representing the new owner of the given token ID\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n */\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n uint256 length = ERC721.balanceOf(to);\n _ownedTokens[to][length] = tokenId;\n _ownedTokensIndex[tokenId] = length;\n }\n\n /**\n * @dev Private function to add a token to this extension's token tracking data structures.\n * @param tokenId uint256 ID of the token to be added to the tokens list\n */\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n _allTokensIndex[tokenId] = _allTokens.length;\n _allTokens.push(tokenId);\n }\n\n /**\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n * @param from address representing the previous owner of the given token ID\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n */\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary\n if (tokenIndex != lastTokenIndex) {\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n }\n\n // This also deletes the contents at the last position of the array\n delete _ownedTokensIndex[tokenId];\n delete _ownedTokens[from][lastTokenIndex];\n }\n\n /**\n * @dev Private function to remove a token from this extension's token tracking data structures.\n * This has O(1) time complexity, but alters the order of the _allTokens array.\n * @param tokenId uint256 ID of the token to be removed from the tokens list\n */\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = _allTokens.length - 1;\n uint256 tokenIndex = _allTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n // This also deletes the contents at the last position of the array\n delete _allTokensIndex[tokenId];\n _allTokens.pop();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Counters.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface,\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n _supportsERC165Interface(account, type(IERC165).interfaceId) &&\n !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)\n internal\n view\n returns (bool[] memory)\n {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in _interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!_supportsERC165Interface(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n * Interface identification is specified in ERC-165.\n */\n function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/Bytes32AddressLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Library for converting between addresses and bytes32 values.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)\nlibrary Bytes32AddressLib {\n function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {\n return bytes32(bytes20(addressValue));\n }\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n /*//////////////////////////////////////////////////////////////\n SIMPLIFIED FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n }\n\n function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n }\n\n function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n }\n\n function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n }\n\n function powWad(int256 x, int256 y) internal pure returns (int256) {\n // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\n return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\n }\n\n function expWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n // When the result is < 0.5 we return zero. This happens when\n // x <= floor(log(0.5e18) * 1e18) ~ -42e18\n if (x <= -42139678854452767551) return 0;\n\n // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\n // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\n if (x >= 135305999368893231589) revert(\"EXP_OVERFLOW\");\n\n // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\n // for more intermediate precision and a binary basis. This base conversion\n // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n x = (x << 78) / 5**18;\n\n // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\n x = x - k * 54916777467707473351141471128;\n\n // k is in the range [-61, 195].\n\n // Evaluate using a (6, 7)-term rational approximation.\n // p is made monic, we'll multiply by a scale factor later.\n int256 y = x + 1346386616545796478920950773328;\n y = ((y * x) >> 96) + 57155421227552351082224309758442;\n int256 p = y + x - 94201549194550492254356042504812;\n p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n p = p * x + (4385272521454847904659076985693276 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n int256 q = x - 2855989394907223263936484059900;\n q = ((q * x) >> 96) + 50020603652535783019961831881945;\n q = ((q * x) >> 96) - 533845033583426703283633433725380;\n q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial won't have zeros in the domain as all its roots are complex.\n // No scaling is necessary because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r should be in the range (0.09, 0.25) * 2**96.\n\n // We now need to multiply r by:\n // * the scale factor s = ~6.031367120.\n // * the 2**k factor from the range reduction.\n // * the 1e18 / 2**96 factor for base conversion.\n // We do this all at once, with an intermediate result in 2**213\n // basis, so the final right shift is always by a positive amount.\n r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\n }\n }\n\n function lnWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n require(x > 0, \"UNDEFINED\");\n\n // We want to convert x from 10**18 fixed point to 2**96 fixed point.\n // We do this by multiplying by 2**96 / 10**18. But since\n // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\n // and add ln(2**96 / 10**18) at the end.\n\n // Reduce range of x to (1, 2) * 2**96\n // ln(2^k * x) = k * ln(2) + ln(x)\n int256 k = int256(log2(uint256(x))) - 96;\n x <<= uint256(159 - k);\n x = int256(uint256(x) >> 159);\n\n // Evaluate using a (8, 8)-term rational approximation.\n // p is made monic, we will multiply by a scale factor later.\n int256 p = x + 3273285459638523848632254066296;\n p = ((p * x) >> 96) + 24828157081833163892658089445524;\n p = ((p * x) >> 96) + 43456485725739037958740375743393;\n p = ((p * x) >> 96) - 11111509109440967052023855526967;\n p = ((p * x) >> 96) - 45023709667254063763336534515857;\n p = ((p * x) >> 96) - 14706773417378608786704636184526;\n p = p * x - (795164235651350426258249787498 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n // q is monic by convention.\n int256 q = x + 5573035233440673466300451813936;\n q = ((q * x) >> 96) + 71694874799317883764090561454958;\n q = ((q * x) >> 96) + 283447036172924575727196451306956;\n q = ((q * x) >> 96) + 401686690394027663651624208769553;\n q = ((q * x) >> 96) + 204048457590392012362485061816622;\n q = ((q * x) >> 96) + 31853899698501571402653359427138;\n q = ((q * x) >> 96) + 909429971244387300277376558375;\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial is known not to have zeros in the domain.\n // No scaling required because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r is in the range (0, 0.125) * 2**96\n\n // Finalization, we need to:\n // * multiply by the scale factor s = 5.549…\n // * add ln(2**96 / 10**18)\n // * add k * ln(2)\n // * multiply by 10**18 / 2**96 = 5**18 >> 78\n\n // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\n r *= 1677202110996718588342820967067443963516166;\n // add ln(2) * k * 5e18 * 2**192\n r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\n // add ln(2**96 / 10**18) * 5e18 * 2**192\n r += 600920179829731861736702779321621459595472258049074101567377883020018308;\n // base conversion: mul 2**18 / 2**192\n r >>= 174;\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n LOW LEVEL FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function mulDivDown(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // Divide z by the denominator.\n z := div(z, denominator)\n }\n }\n\n function mulDivUp(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // First, divide z - 1 by the denominator and add 1.\n // We allow z - 1 to underflow if z is 0, because we multiply the\n // end result by 0 if z is zero, ensuring we return 0 if z is zero.\n z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\n }\n }\n\n function rpow(\n uint256 x,\n uint256 n,\n uint256 scalar\n ) internal pure returns (uint256 z) {\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n // 0 ** 0 = 1\n z := scalar\n }\n default {\n // 0 ** n = 0\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n // If n is even, store scalar in z for now.\n z := scalar\n }\n default {\n // If n is odd, store x in z for now.\n z := x\n }\n\n // Shifting right by 1 is like dividing by 2.\n let half := shr(1, scalar)\n\n for {\n // Shift n right by 1 before looping to halve it.\n n := shr(1, n)\n } n {\n // Shift n right by 1 each iteration to halve it.\n n := shr(1, n)\n } {\n // Revert immediately if x ** 2 would overflow.\n // Equivalent to iszero(eq(div(xx, x), x)) here.\n if shr(128, x) {\n revert(0, 0)\n }\n\n // Store x squared.\n let xx := mul(x, x)\n\n // Round to the nearest number.\n let xxRound := add(xx, half)\n\n // Revert if xx + half overflowed.\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n\n // Set x to scaled xxRound.\n x := div(xxRound, scalar)\n\n // If n is even:\n if mod(n, 2) {\n // Compute z * x.\n let zx := mul(z, x)\n\n // If z * x overflowed:\n if iszero(eq(div(zx, x), z)) {\n // Revert if x is non-zero.\n if iszero(iszero(x)) {\n revert(0, 0)\n }\n }\n\n // Round to the nearest number.\n let zxRound := add(zx, half)\n\n // Revert if zx + half overflowed.\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n\n // Return properly scaled zxRound.\n z := div(zxRound, scalar)\n }\n }\n }\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n GENERAL NUMBER UTILITIES\n //////////////////////////////////////////////////////////////*/\n\n function sqrt(uint256 x) internal pure returns (uint256 z) {\n assembly {\n let y := x // We start y at x, which will help us make our initial estimate.\n\n z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n // We check y >= 2^(k + 8) but shift right by k bits\n // each branch to ensure that if x >= 256, then y >= 256.\n if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n y := shr(128, y)\n z := shl(64, z)\n }\n if iszero(lt(y, 0x1000000000000000000)) {\n y := shr(64, y)\n z := shl(32, z)\n }\n if iszero(lt(y, 0x10000000000)) {\n y := shr(32, y)\n z := shl(16, z)\n }\n if iszero(lt(y, 0x1000000)) {\n y := shr(16, y)\n z := shl(8, z)\n }\n\n // Goal was to get z*z*y within a small factor of x. More iterations could\n // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n // There is no overflow risk here since y < 2^136 after the first branch above.\n z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n\n // If x+1 is a perfect square, the Babylonian method cycles between\n // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n z := sub(z, lt(div(x, z), z))\n }\n }\n\n function log2(uint256 x) internal pure returns (uint256 r) {\n require(x > 0, \"UNDEFINED\");\n\n assembly {\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\n r := or(r, shl(3, lt(0xff, shr(r, x))))\n r := or(r, shl(2, lt(0xf, shr(r, x))))\n r := or(r, shl(1, lt(0x3, shr(r, x))))\n r := or(r, lt(0x1, shr(r, x)))\n }\n }\n}\n" - }, - "node_modules/ds-test/src/test.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.5.0;\n\ncontract DSTest {\n event log (string);\n event logs (bytes);\n\n event log_address (address);\n event log_bytes32 (bytes32);\n event log_int (int);\n event log_uint (uint);\n event log_bytes (bytes);\n event log_string (string);\n\n event log_named_address (string key, address val);\n event log_named_bytes32 (string key, bytes32 val);\n event log_named_decimal_int (string key, int val, uint decimals);\n event log_named_decimal_uint (string key, uint val, uint decimals);\n event log_named_int (string key, int val);\n event log_named_uint (string key, uint val);\n event log_named_bytes (string key, bytes val);\n event log_named_string (string key, string val);\n\n bool public IS_TEST = true;\n bool private _failed;\n\n address constant HEVM_ADDRESS =\n address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));\n\n modifier mayRevert() { _; }\n modifier testopts(string memory) { _; }\n\n function failed() public returns (bool) {\n if (_failed) {\n return _failed;\n } else {\n bool globalFailed = false;\n if (hasHEVMContext()) {\n (, bytes memory retdata) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"load(address,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"))\n )\n );\n globalFailed = abi.decode(retdata, (bool));\n }\n return globalFailed;\n }\n } \n\n function fail() internal {\n if (hasHEVMContext()) {\n (bool status, ) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"store(address,bytes32,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"), bytes32(uint256(0x01)))\n )\n );\n status; // Silence compiler warnings\n }\n _failed = true;\n }\n\n function hasHEVMContext() internal view returns (bool) {\n uint256 hevmCodeSize = 0;\n assembly {\n hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D)\n }\n return hevmCodeSize > 0;\n }\n\n modifier logs_gas() {\n uint startGas = gasleft();\n _;\n uint endGas = gasleft();\n emit log_named_uint(\"gas\", startGas - endGas);\n }\n\n function assertTrue(bool condition) internal {\n if (!condition) {\n emit log(\"Error: Assertion Failed\");\n fail();\n }\n }\n\n function assertTrue(bool condition, string memory err) internal {\n if (!condition) {\n emit log_named_string(\"Error\", err);\n assertTrue(condition);\n }\n }\n\n function assertEq(address a, address b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [address]\");\n emit log_named_address(\" Expected\", b);\n emit log_named_address(\" Actual\", a);\n fail();\n }\n }\n function assertEq(address a, address b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes32 a, bytes32 b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bytes32]\");\n emit log_named_bytes32(\" Expected\", b);\n emit log_named_bytes32(\" Actual\", a);\n fail();\n }\n }\n function assertEq(bytes32 a, bytes32 b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq32(bytes32 a, bytes32 b) internal {\n assertEq(a, b);\n }\n function assertEq32(bytes32 a, bytes32 b, string memory err) internal {\n assertEq(a, b, err);\n }\n\n function assertEq(int a, int b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [int]\");\n emit log_named_int(\" Expected\", b);\n emit log_named_int(\" Actual\", a);\n fail();\n }\n }\n function assertEq(int a, int b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq(uint a, uint b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [uint]\");\n emit log_named_uint(\" Expected\", b);\n emit log_named_uint(\" Actual\", a);\n fail();\n }\n }\n function assertEq(uint a, uint b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEqDecimal(int a, int b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Expected\", b, decimals);\n emit log_named_decimal_int(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Expected\", b, decimals);\n emit log_named_decimal_uint(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n\n function assertGt(uint a, uint b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGt(uint a, uint b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGt(int a, int b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGt(int a, int b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGtDecimal(int a, int b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n\n function assertGe(uint a, uint b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGe(uint a, uint b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGe(int a, int b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGe(int a, int b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGeDecimal(int a, int b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertLt(uint a, uint b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLt(uint a, uint b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLt(int a, int b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLt(int a, int b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLtDecimal(int a, int b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n\n function assertLe(uint a, uint b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLe(uint a, uint b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLe(int a, int b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLe(int a, int b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLeDecimal(int a, int b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLeDecimal(a, b, decimals);\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertEq(string memory a, string memory b) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log(\"Error: a == b not satisfied [string]\");\n emit log_named_string(\" Expected\", b);\n emit log_named_string(\" Actual\", a);\n fail();\n }\n }\n function assertEq(string memory a, string memory b, string memory err) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {\n ok = true;\n if (a.length == b.length) {\n for (uint i = 0; i < a.length; i++) {\n if (a[i] != b[i]) {\n ok = false;\n }\n }\n } else {\n ok = false;\n }\n }\n function assertEq0(bytes memory a, bytes memory b) internal {\n if (!checkEq0(a, b)) {\n emit log(\"Error: a == b not satisfied [bytes]\");\n emit log_named_bytes(\" Expected\", b);\n emit log_named_bytes(\" Actual\", a);\n fail();\n }\n }\n function assertEq0(bytes memory a, bytes memory b, string memory err) internal {\n if (!checkEq0(a, b)) {\n emit log_named_string(\"Error\", err);\n assertEq0(a, b);\n }\n }\n}\n" - }, - "node_modules/forge-std/src/Base.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {StdStorage} from \"./StdStorage.sol\";\nimport {Vm, VmSafe} from \"./Vm.sol\";\n\nabstract contract CommonBase {\n // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.\n address internal constant VM_ADDRESS = address(uint160(uint256(keccak256(\"hevm cheat code\"))));\n // console.sol and console2.sol work by executing a staticcall to this address.\n address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;\n // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38.\n address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256(\"foundry default caller\"))));\n // Address of the test contract, deployed by the DEFAULT_SENDER.\n address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;\n\n uint256 internal constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n Vm internal constant vm = Vm(VM_ADDRESS);\n StdStorage internal stdstore;\n}\n\nabstract contract TestBase is CommonBase {}\n\nabstract contract ScriptBase is CommonBase {\n // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);\n}\n" - }, - "node_modules/forge-std/src/InvariantTest.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ncontract InvariantTest {\n struct FuzzSelector {\n address addr;\n bytes4[] selectors;\n }\n\n address[] private _excludedContracts;\n address[] private _excludedSenders;\n address[] private _targetedContracts;\n address[] private _targetedSenders;\n\n string[] private _excludedArtifacts;\n string[] private _targetedArtifacts;\n\n FuzzSelector[] internal _targetedArtifactSelectors;\n FuzzSelector[] internal _targetedSelectors;\n\n function excludeArtifact(string memory newExcludedArtifact_) internal {\n _excludedArtifacts.push(newExcludedArtifact_);\n }\n\n function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) {\n require(_excludedArtifacts.length != uint256(0), \"NO_EXCLUDED_ARTIFACTS\");\n excludedArtifacts_ = _excludedArtifacts;\n }\n\n function excludeContract(address newExcludedContract_) internal {\n _excludedContracts.push(newExcludedContract_);\n }\n\n function excludeContracts() public view returns (address[] memory excludedContracts_) {\n require(_excludedContracts.length != uint256(0), \"NO_EXCLUDED_CONTRACTS\");\n excludedContracts_ = _excludedContracts;\n }\n\n function excludeSender(address newExcludedSender_) internal {\n _excludedSenders.push(newExcludedSender_);\n }\n\n function excludeSenders() public view returns (address[] memory excludedSenders_) {\n require(_excludedSenders.length != uint256(0), \"NO_EXCLUDED_SENDERS\");\n excludedSenders_ = _excludedSenders;\n }\n\n function targetArtifact(string memory newTargetedArtifact_) internal {\n _targetedArtifacts.push(newTargetedArtifact_);\n }\n\n function targetArtifacts() public view returns (string[] memory targetedArtifacts_) {\n require(_targetedArtifacts.length != uint256(0), \"NO_TARGETED_ARTIFACTS\");\n targetedArtifacts_ = _targetedArtifacts;\n }\n\n function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal {\n _targetedArtifactSelectors.push(newTargetedArtifactSelector_);\n }\n\n function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) {\n require(targetedArtifactSelectors_.length != uint256(0), \"NO_TARGETED_ARTIFACT_SELECTORS\");\n targetedArtifactSelectors_ = _targetedArtifactSelectors;\n }\n\n function targetContract(address newTargetedContract_) internal {\n _targetedContracts.push(newTargetedContract_);\n }\n\n function targetContracts() public view returns (address[] memory targetedContracts_) {\n require(_targetedContracts.length != uint256(0), \"NO_TARGETED_CONTRACTS\");\n targetedContracts_ = _targetedContracts;\n }\n\n function targetSelector(FuzzSelector memory newTargetedSelector_) internal {\n _targetedSelectors.push(newTargetedSelector_);\n }\n\n function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) {\n require(targetedSelectors_.length != uint256(0), \"NO_TARGETED_SELECTORS\");\n targetedSelectors_ = _targetedSelectors;\n }\n\n function targetSender(address newTargetedSender_) internal {\n _targetedSenders.push(newTargetedSender_);\n }\n\n function targetSenders() public view returns (address[] memory targetedSenders_) {\n require(_targetedSenders.length != uint256(0), \"NO_TARGETED_SENDERS\");\n targetedSenders_ = _targetedSenders;\n }\n}\n" - }, - "node_modules/forge-std/src/StdAssertions.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {DSTest} from \"ds-test/test.sol\";\nimport {stdMath} from \"./StdMath.sol\";\n\nabstract contract StdAssertions is DSTest {\n event log_array(uint256[] val);\n event log_array(int256[] val);\n event log_array(address[] val);\n event log_named_array(string key, uint256[] val);\n event log_named_array(string key, int256[] val);\n event log_named_array(string key, address[] val);\n\n function fail(string memory err) internal virtual {\n emit log_named_string(\"Error\", err);\n fail();\n }\n\n function assertFalse(bool data) internal virtual {\n assertTrue(!data);\n }\n\n function assertFalse(bool data, string memory err) internal virtual {\n assertTrue(!data, err);\n }\n\n function assertEq(bool a, bool b) internal virtual {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bool]\");\n emit log_named_string(\" Expected\", b ? \"true\" : \"false\");\n emit log_named_string(\" Actual\", a ? \"true\" : \"false\");\n fail();\n }\n }\n\n function assertEq(bool a, bool b, string memory err) internal virtual {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes memory a, bytes memory b) internal virtual {\n assertEq0(a, b);\n }\n\n function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual {\n assertEq0(a, b, err);\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [uint[]]\");\n emit log_named_array(\" Expected\", b);\n emit log_named_array(\" Actual\", a);\n fail();\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [int[]]\");\n emit log_named_array(\" Expected\", b);\n emit log_named_array(\" Actual\", a);\n fail();\n }\n }\n\n function assertEq(address[] memory a, address[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [address[]]\");\n emit log_named_array(\" Expected\", b);\n emit log_named_array(\" Actual\", a);\n fail();\n }\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n // Legacy helper\n function assertEqUint(uint256 a, uint256 b) internal virtual {\n assertEq(uint256(a), uint256(b));\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Expected\", b);\n emit log_named_uint(\" Actual\", a);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Expected\", b);\n emit log_named_int(\" Actual\", a);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100%\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Expected\", b);\n emit log_named_uint(\" Actual\", a);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the expected is 0, actual must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual {\n if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Expected\", b);\n emit log_named_int(\" Actual\", a);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the expected is 0, actual must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n}\n" - }, - "node_modules/forge-std/src/StdChains.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n/**\n * StdChains provides information about EVM compatible chains that can be used in scripts/tests.\n * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are\n * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of\n * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the\n * alias used in this contract, which can be found as the first argument to the\n * `setChainWithDefaultRpcUrl` call in the `initialize` function.\n *\n * There are two main ways to use this contract:\n * 1. Set a chain with `setChain(string memory chainAlias, Chain memory chain)`\n * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`.\n *\n * The first time either of those are used, chains are initialized with the default set of RPC URLs.\n * This is done in `initialize`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in\n * `defaultRpcUrls`.\n *\n * The `setChain` function is straightforward, and it simply saves off the given chain data.\n *\n * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say\n * we want to retrieve `mainnet`'s RPC URL:\n * - If you haven't set any mainnet chain info with `setChain` and you haven't specified that\n * chain in `foundry.toml`, the default data and RPC URL will be returned.\n * - If you have set a mainnet RPC URL in `foundry.toml` it will return that, if valid (e.g. if\n * a URL is given or if an environment variable is given and that environment variable exists).\n * Otherwise, the default data is returned.\n * - If you specified data with `setChain` it will return that.\n *\n * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> defaults.\n */\nabstract contract StdChains {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private initialized;\n\n struct Chain {\n // The chain name.\n string name;\n // The chain's Chain ID.\n uint256 chainId;\n // A default RPC endpoint for this chain.\n // NOTE: This default RPC URL is included for convenience to facilitate quick tests and\n // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy\n // usage as you will be throttled and this is a disservice to others who need this endpoint.\n string rpcUrl;\n }\n\n // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data.\n mapping(string => Chain) private chains;\n // Maps from the chain's alias to it's default RPC URL.\n mapping(string => string) private defaultRpcUrls;\n // Maps from a chain ID to it's alias.\n mapping(uint256 => string) private idToAlias;\n\n // The RPC URL will be fetched from config or defaultRpcUrls if possible.\n function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) {\n require(bytes(chainAlias).length != 0, \"StdChains getChain(string): Chain alias cannot be the empty string.\");\n\n initialize();\n chain = chains[chainAlias];\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(string): Chain with alias \\\"\", chainAlias, \"\\\" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n function getChain(uint256 chainId) internal virtual returns (Chain memory chain) {\n require(chainId != 0, \"StdChains getChain(uint256): Chain ID cannot be 0.\");\n initialize();\n string memory chainAlias = idToAlias[chainId];\n\n chain = chains[chainAlias];\n\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(uint256): Chain with ID \", vm.toString(chainId), \" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, Chain memory chain) internal virtual {\n require(\n bytes(chainAlias).length != 0, \"StdChains setChain(string,Chain): Chain alias cannot be the empty string.\"\n );\n\n require(chain.chainId != 0, \"StdChains setChain(string,Chain): Chain ID cannot be 0.\");\n\n initialize();\n string memory foundAlias = idToAlias[chain.chainId];\n\n require(\n bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)),\n string(\n abi.encodePacked(\n \"StdChains setChain(string,Chain): Chain ID \",\n vm.toString(chain.chainId),\n \" already used by \\\"\",\n foundAlias,\n \"\\\".\"\n )\n )\n );\n\n uint256 oldChainId = chains[chainAlias].chainId;\n delete idToAlias[oldChainId];\n\n chains[chainAlias] = chain;\n idToAlias[chain.chainId] = chainAlias;\n }\n\n // lookup rpcUrl, in descending order of priority:\n // current -> config (foundry.toml) -> default\n function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain)\n private\n view\n returns (Chain memory)\n {\n if (bytes(chain.rpcUrl).length == 0) {\n try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) {\n chain.rpcUrl = configRpcUrl;\n } catch (bytes memory err) {\n chain.rpcUrl = defaultRpcUrls[chainAlias];\n // distinguish 'not found' from 'cannot read'\n bytes memory notFoundError =\n abi.encodeWithSignature(\"CheatCodeError\", string(abi.encodePacked(\"invalid rpc url \", chainAlias)));\n if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, err), mload(err))\n }\n }\n }\n }\n return chain;\n }\n\n function initialize() private {\n if (initialized) return;\n\n initialized = true;\n\n // If adding an RPC here, make sure to test the default RPC URL in `testRpcs`\n setChainWithDefaultRpcUrl(\"anvil\", Chain(\"Anvil\", 31337, \"http://127.0.0.1:8545\"));\n setChainWithDefaultRpcUrl(\n \"mainnet\", Chain(\"Mainnet\", 1, \"https://mainnet.infura.io/v3/6770454bc6ea42c58aac12978531b93f\")\n );\n setChainWithDefaultRpcUrl(\n \"goerli\", Chain(\"Goerli\", 5, \"https://goerli.infura.io/v3/6770454bc6ea42c58aac12978531b93f\")\n );\n setChainWithDefaultRpcUrl(\n \"sepolia\", Chain(\"Sepolia\", 11155111, \"https://sepolia.infura.io/v3/6770454bc6ea42c58aac12978531b93f\")\n );\n setChainWithDefaultRpcUrl(\"optimism\", Chain(\"Optimism\", 10, \"https://mainnet.optimism.io\"));\n setChainWithDefaultRpcUrl(\"optimism_goerli\", Chain(\"Optimism Goerli\", 420, \"https://goerli.optimism.io\"));\n setChainWithDefaultRpcUrl(\"arbitrum_one\", Chain(\"Arbitrum One\", 42161, \"https://arb1.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\n \"arbitrum_one_goerli\", Chain(\"Arbitrum One Goerli\", 421613, \"https://goerli-rollup.arbitrum.io/rpc\")\n );\n setChainWithDefaultRpcUrl(\"arbitrum_nova\", Chain(\"Arbitrum Nova\", 42170, \"https://nova.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\"polygon\", Chain(\"Polygon\", 137, \"https://polygon-rpc.com\"));\n setChainWithDefaultRpcUrl(\"polygon_mumbai\", Chain(\"Polygon Mumbai\", 80001, \"https://rpc-mumbai.maticvigil.com\"));\n setChainWithDefaultRpcUrl(\"avalanche\", Chain(\"Avalanche\", 43114, \"https://api.avax.network/ext/bc/C/rpc\"));\n setChainWithDefaultRpcUrl(\n \"avalanche_fuji\", Chain(\"Avalanche Fuji\", 43113, \"https://api.avax-test.network/ext/bc/C/rpc\")\n );\n setChainWithDefaultRpcUrl(\"bnb_smart_chain\", Chain(\"BNB Smart Chain\", 56, \"https://bsc-dataseed1.binance.org\"));\n setChainWithDefaultRpcUrl(\"bnb_smart_chain_testnet\", Chain(\"BNB Smart Chain Testnet\", 97, \"https://data-seed-prebsc-1-s1.binance.org:8545\"));// forgefmt: disable-line\n setChainWithDefaultRpcUrl(\"gnosis_chain\", Chain(\"Gnosis Chain\", 100, \"https://rpc.gnosischain.com\"));\n }\n\n // set chain info, with priority to chainAlias' rpc url in foundry.toml\n function setChainWithDefaultRpcUrl(string memory chainAlias, Chain memory chain) private {\n string memory rpcUrl = chain.rpcUrl;\n defaultRpcUrls[chainAlias] = rpcUrl;\n chain.rpcUrl = \"\";\n setChain(chainAlias, chain);\n chain.rpcUrl = rpcUrl; // restore argument\n }\n}\n" - }, - "node_modules/forge-std/src/StdCheats.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdCheatsSafe {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private gasMeteringOff;\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawTx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n // json value name = function\n string functionSig;\n bytes32 hash;\n // json value name = tx\n RawTx1559Detail txDetail;\n // json value name = type\n string opcode;\n }\n\n struct RawTx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n bytes gas;\n bytes nonce;\n address to;\n bytes txType;\n bytes value;\n }\n\n struct Tx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n bytes32 hash;\n Tx1559Detail txDetail;\n string opcode;\n }\n\n struct Tx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n uint256 gas;\n uint256 nonce;\n address to;\n uint256 txType;\n uint256 value;\n }\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct TxLegacy {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n string hash;\n string opcode;\n TxDetailLegacy transaction;\n }\n\n struct TxDetailLegacy {\n AccessList[] accessList;\n uint256 chainId;\n bytes data;\n address from;\n uint256 gas;\n uint256 gasPrice;\n bytes32 hash;\n uint256 nonce;\n bytes1 opcode;\n bytes32 r;\n bytes32 s;\n uint256 txType;\n address to;\n uint8 v;\n uint256 value;\n }\n\n struct AccessList {\n address accessAddress;\n bytes32[] storageKeys;\n }\n\n // Data structures to parse Receipt objects from the broadcast artifact.\n // The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawReceipt {\n bytes32 blockHash;\n bytes blockNumber;\n address contractAddress;\n bytes cumulativeGasUsed;\n bytes effectiveGasPrice;\n address from;\n bytes gasUsed;\n RawReceiptLog[] logs;\n bytes logsBloom;\n bytes status;\n address to;\n bytes32 transactionHash;\n bytes transactionIndex;\n }\n\n struct Receipt {\n bytes32 blockHash;\n uint256 blockNumber;\n address contractAddress;\n uint256 cumulativeGasUsed;\n uint256 effectiveGasPrice;\n address from;\n uint256 gasUsed;\n ReceiptLog[] logs;\n bytes logsBloom;\n uint256 status;\n address to;\n bytes32 transactionHash;\n uint256 transactionIndex;\n }\n\n // Data structures to parse the entire broadcast artifact, assuming the\n // transactions conform to EIP1559.\n\n struct EIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n Receipt[] receipts;\n uint256 timestamp;\n Tx1559[] transactions;\n TxReturn[] txReturns;\n }\n\n struct RawEIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n RawReceipt[] receipts;\n TxReturn[] txReturns;\n uint256 timestamp;\n RawTx1559[] transactions;\n }\n\n struct RawReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n bytes blockNumber;\n bytes data;\n bytes logIndex;\n bool removed;\n bytes32[] topics;\n bytes32 transactionHash;\n bytes transactionIndex;\n bytes transactionLogIndex;\n }\n\n struct ReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n uint256 blockNumber;\n bytes data;\n uint256 logIndex;\n bytes32[] topics;\n uint256 transactionIndex;\n uint256 transactionLogIndex;\n bool removed;\n }\n\n struct TxReturn {\n string internalType;\n string value;\n }\n\n function assumeNoPrecompiles(address addr) internal virtual {\n // Assembly required since `block.chainid` was introduced in 0.8.0.\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n assumeNoPrecompiles(addr, chainId);\n }\n\n function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual {\n // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific\n // address), but the same rationale for excluding them applies so we include those too.\n\n // These should be present on all EVM-compatible chains.\n vm.assume(addr < address(0x1) || addr > address(0x9));\n\n // forgefmt: disable-start\n if (chainId == 10 || chainId == 420) {\n // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21\n vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800));\n } else if (chainId == 42161 || chainId == 421613) {\n // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains\n vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068));\n } else if (chainId == 43114 || chainId == 43113) {\n // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59\n vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff));\n vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF));\n vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff));\n }\n // forgefmt: disable-end\n }\n\n function readEIP1559ScriptArtifact(string memory path)\n internal\n view\n virtual\n returns (EIP1559ScriptArtifact memory)\n {\n string memory data = vm.readFile(path);\n bytes memory parsedData = vm.parseJson(data);\n RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact));\n EIP1559ScriptArtifact memory artifact;\n artifact.libraries = rawArtifact.libraries;\n artifact.path = rawArtifact.path;\n artifact.timestamp = rawArtifact.timestamp;\n artifact.pending = rawArtifact.pending;\n artifact.txReturns = rawArtifact.txReturns;\n artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts);\n artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions);\n return artifact;\n }\n\n function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) {\n Tx1559[] memory txs = new Tx1559[](rawTxs.length);\n for (uint256 i; i < rawTxs.length; i++) {\n txs[i] = rawToConvertedEIPTx1559(rawTxs[i]);\n }\n return txs;\n }\n\n function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) {\n Tx1559 memory transaction;\n transaction.arguments = rawTx.arguments;\n transaction.contractName = rawTx.contractName;\n transaction.functionSig = rawTx.functionSig;\n transaction.hash = rawTx.hash;\n transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail);\n transaction.opcode = rawTx.opcode;\n return transaction;\n }\n\n function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail)\n internal\n pure\n virtual\n returns (Tx1559Detail memory)\n {\n Tx1559Detail memory txDetail;\n txDetail.data = rawDetail.data;\n txDetail.from = rawDetail.from;\n txDetail.to = rawDetail.to;\n txDetail.nonce = _bytesToUint(rawDetail.nonce);\n txDetail.txType = _bytesToUint(rawDetail.txType);\n txDetail.value = _bytesToUint(rawDetail.value);\n txDetail.gas = _bytesToUint(rawDetail.gas);\n txDetail.accessList = rawDetail.accessList;\n return txDetail;\n }\n\n function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".transactions\");\n RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[]));\n return rawToConvertedEIPTx1559s(rawTxs);\n }\n\n function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".transactions[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559));\n return rawToConvertedEIPTx1559(rawTx);\n }\n\n // Analogous to readTransactions, but for receipts.\n function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".receipts\");\n RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[]));\n return rawToConvertedReceipts(rawReceipts);\n }\n\n function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".receipts[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt));\n return rawToConvertedReceipt(rawReceipt);\n }\n\n function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) {\n Receipt[] memory receipts = new Receipt[](rawReceipts.length);\n for (uint256 i; i < rawReceipts.length; i++) {\n receipts[i] = rawToConvertedReceipt(rawReceipts[i]);\n }\n return receipts;\n }\n\n function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) {\n Receipt memory receipt;\n receipt.blockHash = rawReceipt.blockHash;\n receipt.to = rawReceipt.to;\n receipt.from = rawReceipt.from;\n receipt.contractAddress = rawReceipt.contractAddress;\n receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice);\n receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed);\n receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed);\n receipt.status = _bytesToUint(rawReceipt.status);\n receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex);\n receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber);\n receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs);\n receipt.logsBloom = rawReceipt.logsBloom;\n receipt.transactionHash = rawReceipt.transactionHash;\n return receipt;\n }\n\n function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs)\n internal\n pure\n virtual\n returns (ReceiptLog[] memory)\n {\n ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length);\n for (uint256 i; i < rawLogs.length; i++) {\n logs[i].logAddress = rawLogs[i].logAddress;\n logs[i].blockHash = rawLogs[i].blockHash;\n logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber);\n logs[i].data = rawLogs[i].data;\n logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex);\n logs[i].topics = rawLogs[i].topics;\n logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex);\n logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex);\n logs[i].removed = rawLogs[i].removed;\n }\n return logs;\n }\n\n // Deploy a contract by fetching the contract bytecode from\n // the artifacts directory\n // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))`\n function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes): Deployment failed.\");\n }\n\n function deployCode(string memory what) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string): Deployment failed.\");\n }\n\n /// @dev deploy contract with value on construction\n function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes,uint256): Deployment failed.\");\n }\n\n function deployCode(string memory what, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,uint256): Deployment failed.\");\n }\n\n // creates a labeled address and the corresponding private key\n function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) {\n privateKey = uint256(keccak256(abi.encodePacked(name)));\n addr = vm.addr(privateKey);\n vm.label(addr, name);\n }\n\n // creates a labeled address\n function makeAddr(string memory name) internal virtual returns (address addr) {\n (addr,) = makeAddrAndKey(name);\n }\n\n function deriveRememberKey(string memory mnemonic, uint32 index)\n internal\n virtual\n returns (address who, uint256 privateKey)\n {\n privateKey = vm.deriveKey(mnemonic, index);\n who = vm.rememberKey(privateKey);\n }\n\n function _bytesToUint(bytes memory b) private pure returns (uint256) {\n require(b.length <= 32, \"StdCheats _bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n function isFork() internal view virtual returns (bool status) {\n try vm.activeFork() {\n status = true;\n } catch (bytes memory) {}\n }\n\n modifier skipWhenForking() {\n if (!isFork()) {\n _;\n }\n }\n\n modifier skipWhenNotForking() {\n if (isFork()) {\n _;\n }\n }\n\n modifier noGasMetering() {\n vm.pauseGasMetering();\n // To prevent turning gas monitoring back on with nested functions that use this modifier,\n // we check if gasMetering started in the off position. If it did, we don't want to turn\n // it back on until we exit the top level function that used the modifier\n //\n // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well.\n // funcA will have `gasStartedOff` as false, funcB will have it as true,\n // so we only turn metering back on at the end of the funcA\n bool gasStartedOff = gasMeteringOff;\n gasMeteringOff = true;\n\n _;\n\n // if gas metering was on when this modifier was called, turn it back on at the end\n if (!gasStartedOff) {\n gasMeteringOff = false;\n vm.resumeGasMetering();\n }\n }\n}\n\n// Wrappers around cheatcodes to avoid footguns\nabstract contract StdCheats is StdCheatsSafe {\n using stdStorage for StdStorage;\n\n StdStorage private stdstore;\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n // Skip forward or rewind time by the specified number of seconds\n function skip(uint256 time) internal virtual {\n vm.warp(block.timestamp + time);\n }\n\n function rewind(uint256 time) internal virtual {\n vm.warp(block.timestamp - time);\n }\n\n // Setup a prank from an address that has some ether\n function hoax(address who) internal virtual {\n vm.deal(who, 1 << 128);\n vm.prank(who);\n }\n\n function hoax(address who, uint256 give) internal virtual {\n vm.deal(who, give);\n vm.prank(who);\n }\n\n function hoax(address who, address origin) internal virtual {\n vm.deal(who, 1 << 128);\n vm.prank(who, origin);\n }\n\n function hoax(address who, address origin, uint256 give) internal virtual {\n vm.deal(who, give);\n vm.prank(who, origin);\n }\n\n // Start perpetual prank from an address that has some ether\n function startHoax(address who) internal virtual {\n vm.deal(who, 1 << 128);\n vm.startPrank(who);\n }\n\n function startHoax(address who, uint256 give) internal virtual {\n vm.deal(who, give);\n vm.startPrank(who);\n }\n\n // Start perpetual prank from an address that has some ether\n // tx.origin is set to the origin parameter\n function startHoax(address who, address origin) internal virtual {\n vm.deal(who, 1 << 128);\n vm.startPrank(who, origin);\n }\n\n function startHoax(address who, address origin, uint256 give) internal virtual {\n vm.deal(who, give);\n vm.startPrank(who, origin);\n }\n\n function changePrank(address who) internal virtual {\n vm.stopPrank();\n vm.startPrank(who);\n }\n\n // The same as Vm's `deal`\n // Use the alternative signature for ERC20 tokens\n function deal(address to, uint256 give) internal virtual {\n vm.deal(to, give);\n }\n\n // Set the balance of an account for any ERC20 token\n // Use the alternative signature to update `totalSupply`\n function deal(address token, address to, uint256 give) internal virtual {\n deal(token, to, give, false);\n }\n\n function deal(address token, address to, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd));\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0x18160ddd).checked_write(totSup);\n }\n }\n}\n" - }, - "node_modules/forge-std/src/StdError.sol": { - "content": "// SPDX-License-Identifier: MIT\n// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdError {\n bytes public constant assertionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x01);\n bytes public constant arithmeticError = abi.encodeWithSignature(\"Panic(uint256)\", 0x11);\n bytes public constant divisionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x12);\n bytes public constant enumConversionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x21);\n bytes public constant encodeStorageError = abi.encodeWithSignature(\"Panic(uint256)\", 0x22);\n bytes public constant popError = abi.encodeWithSignature(\"Panic(uint256)\", 0x31);\n bytes public constant indexOOBError = abi.encodeWithSignature(\"Panic(uint256)\", 0x32);\n bytes public constant memOverflowError = abi.encodeWithSignature(\"Panic(uint256)\", 0x41);\n bytes public constant zeroVarError = abi.encodeWithSignature(\"Panic(uint256)\", 0x51);\n}\n" - }, - "node_modules/forge-std/src/StdJson.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing JSON files\n// To parse:\n// ```\n// using stdJson for string;\n// string memory json = vm.readFile(\"some_peth\");\n// json.parseUint(\"\");\n// ```\n// To write:\n// ```\n// using stdJson for string;\n// string memory json = \"deploymentArtifact\";\n// Contract contract = new Contract();\n// json.serialize(\"contractAddress\", address(contract));\n// json = json.serialize(\"deploymentTimes\", uint(1));\n// // store the stringified JSON to the 'json' variable we have been using as a key\n// // as we won't need it any longer\n// string memory json2 = \"finalArtifact\";\n// string memory final = json2.serialize(\"depArtifact\", json);\n// final.write(\"\");\n// ```\n\nlibrary stdJson {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJson(json, key);\n }\n\n function readUint(string memory json, string memory key) internal pure returns (uint256) {\n return abi.decode(vm.parseJson(json, key), (uint256));\n }\n\n function readUintArray(string memory json, string memory key) internal pure returns (uint256[] memory) {\n return abi.decode(vm.parseJson(json, key), (uint256[]));\n }\n\n function readInt(string memory json, string memory key) internal pure returns (int256) {\n return abi.decode(vm.parseJson(json, key), (int256));\n }\n\n function readIntArray(string memory json, string memory key) internal pure returns (int256[] memory) {\n return abi.decode(vm.parseJson(json, key), (int256[]));\n }\n\n function readBytes32(string memory json, string memory key) internal pure returns (bytes32) {\n return abi.decode(vm.parseJson(json, key), (bytes32));\n }\n\n function readBytes32Array(string memory json, string memory key) internal pure returns (bytes32[] memory) {\n return abi.decode(vm.parseJson(json, key), (bytes32[]));\n }\n\n function readString(string memory json, string memory key) internal pure returns (string memory) {\n return abi.decode(vm.parseJson(json, key), (string));\n }\n\n function readStringArray(string memory json, string memory key) internal pure returns (string[] memory) {\n return abi.decode(vm.parseJson(json, key), (string[]));\n }\n\n function readAddress(string memory json, string memory key) internal pure returns (address) {\n return abi.decode(vm.parseJson(json, key), (address));\n }\n\n function readAddressArray(string memory json, string memory key) internal pure returns (address[] memory) {\n return abi.decode(vm.parseJson(json, key), (address[]));\n }\n\n function readBool(string memory json, string memory key) internal pure returns (bool) {\n return abi.decode(vm.parseJson(json, key), (bool));\n }\n\n function readBoolArray(string memory json, string memory key) internal pure returns (bool[] memory) {\n return abi.decode(vm.parseJson(json, key), (bool[]));\n }\n\n function readBytes(string memory json, string memory key) internal pure returns (bytes memory) {\n return abi.decode(vm.parseJson(json, key), (bytes));\n }\n\n function readBytesArray(string memory json, string memory key) internal pure returns (bytes[] memory) {\n return abi.decode(vm.parseJson(json, key), (bytes[]));\n }\n\n function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bool[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function write(string memory jsonKey, string memory path) internal {\n vm.writeJson(jsonKey, path);\n }\n\n function write(string memory jsonKey, string memory path, string memory valueKey) internal {\n vm.writeJson(jsonKey, path, valueKey);\n }\n}\n" - }, - "node_modules/forge-std/src/StdMath.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdMath {\n int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n function abs(int256 a) internal pure returns (uint256) {\n // Required or it will fail when `a = type(int256).min`\n if (a == INT256_MIN) {\n return 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n }\n\n return uint256(a > 0 ? a : -a);\n }\n\n function delta(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a - b : b - a;\n }\n\n function delta(int256 a, int256 b) internal pure returns (uint256) {\n // a and b are of the same sign\n // this works thanks to two's complement, the left-most bit is the sign bit\n if ((a ^ b) > -1) {\n return delta(abs(a), abs(b));\n }\n\n // a and b are of opposite signs\n return abs(a) + abs(b);\n }\n\n function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n\n return absDelta * 1e18 / b;\n }\n\n function percentDelta(int256 a, int256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n uint256 absB = abs(b);\n\n return absDelta * 1e18 / absB;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nstruct StdStorage {\n mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots;\n mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds;\n bytes32[] _keys;\n bytes4 _sig;\n uint256 _depth;\n address _target;\n bytes32 _set;\n}\n\nlibrary stdStorageSafe {\n event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot);\n event WARNING_UninitedSlot(address who, uint256 slot);\n\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return bytes4(keccak256(bytes(sigStr)));\n }\n\n /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against\n // slot complexity:\n // if flat, will be bytes32(uint256(uint));\n // if map, will be keccak256(abi.encode(key, uint(slot)));\n // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));\n // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);\n function find(StdStorage storage self) internal returns (uint256) {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n // calldata to test against\n if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n vm.record();\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n (bytes32[] memory reads,) = vm.accesses(address(who));\n if (reads.length == 1) {\n bytes32 curr = vm.load(who, reads[0]);\n if (curr == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[0]));\n }\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n } else if (reads.length > 1) {\n for (uint256 i = 0; i < reads.length; i++) {\n bytes32 prev = vm.load(who, reads[i]);\n if (prev == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[i]));\n }\n // store\n vm.store(who, reads[i], bytes32(hex\"1337\"));\n bool success;\n bytes memory rdat;\n {\n (success, rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n if (success && fdat == bytes32(hex\"1337\")) {\n // we found which of the slots is the actual one\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n vm.store(who, reads[i], prev);\n break;\n }\n vm.store(who, reads[i], prev);\n }\n } else {\n require(false, \"stdStorage find(StdStorage): No storage use detected for target.\");\n }\n\n require(\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))],\n \"stdStorage find(StdStorage): Slot(s) not found.\"\n );\n\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n self._target = _target;\n return self;\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n self._sig = _sig;\n return self;\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n self._sig = sigs(_sig);\n return self;\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n self._keys.push(bytes32(uint256(uint160(who))));\n return self;\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n self._keys.push(bytes32(amt));\n return self;\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n self._keys.push(key);\n return self;\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n self._depth = _depth;\n return self;\n }\n\n function read(StdStorage storage self) private returns (bytes memory) {\n address t = self._target;\n uint256 s = find(self);\n return abi.encode(vm.load(t, bytes32(s)));\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return abi.decode(read(self), (bytes32));\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n int256 v = read_int(self);\n if (v == 0) return false;\n if (v == 1) return true;\n revert(\"stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool.\");\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return abi.decode(read(self), (address));\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return abi.decode(read(self), (uint256));\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return abi.decode(read(self), (int256));\n }\n\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n\nlibrary stdStorage {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return stdStorageSafe.sigs(sigStr);\n }\n\n function find(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.find(self);\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n return stdStorageSafe.target(self, _target);\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, who);\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, amt);\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, key);\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n return stdStorageSafe.depth(self, _depth);\n }\n\n function checked_write(StdStorage storage self, address who) internal {\n checked_write(self, bytes32(uint256(uint160(who))));\n }\n\n function checked_write(StdStorage storage self, uint256 amt) internal {\n checked_write(self, bytes32(amt));\n }\n\n function checked_write(StdStorage storage self, bool write) internal {\n bytes32 t;\n /// @solidity memory-safe-assembly\n assembly {\n t := write\n }\n checked_write(self, t);\n }\n\n function checked_write(StdStorage storage self, bytes32 set) internal {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n find(self);\n }\n bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]);\n\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n bytes32 curr = vm.load(who, slot);\n\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n vm.store(who, slot, set);\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return stdStorageSafe.read_bytes32(self);\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n return stdStorageSafe.read_bool(self);\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return stdStorageSafe.read_address(self);\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.read_uint(self);\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return stdStorageSafe.read_int(self);\n }\n\n // Private function so needs to be copied over\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n // Private function so needs to be copied over\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n" - }, - "node_modules/forge-std/src/StdUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\n// TODO Remove import.\nimport {VmSafe} from \"./Vm.sol\";\n\nabstract contract StdUtils {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;\n\n uint256 private constant INT256_MIN_ABS =\n 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n require(min <= max, \"StdUtils bound(uint256,uint256,uint256): Max is less than min.\");\n // If x is between min and max, return x directly. This is to ensure that dictionary values\n // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188\n if (x >= min && x <= max) return x;\n\n uint256 size = max - min + 1;\n\n // If the value is 0, 1, 2, 3, warp that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side.\n // This helps ensure coverage of the min/max values.\n if (x <= 3 && size > x) return min + x;\n if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x);\n\n // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.\n if (x > max) {\n uint256 diff = x - max;\n uint256 rem = diff % size;\n if (rem == 0) return max;\n result = min + rem - 1;\n } else if (x < min) {\n uint256 diff = min - x;\n uint256 rem = diff % size;\n if (rem == 0) return min;\n result = max - rem + 1;\n }\n }\n\n function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) {\n result = _bound(x, min, max);\n console2_log(\"Bound Result\", result);\n }\n\n function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) {\n require(min <= max, \"StdUtils bound(int256,int256,int256): Max is less than min.\");\n\n // Shifting all int256 values to uint256 to use _bound function. The range of two types are:\n // int256 : -(2**255) ~ (2**255 - 1)\n // uint256: 0 ~ (2**256 - 1)\n // So, add 2**255, INT256_MIN_ABS to the integer values.\n //\n // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow.\n // So, use `~uint256(x) + 1` instead.\n uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS);\n uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS);\n uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS);\n\n uint256 y = _bound(_x, _min, _max);\n\n // To move it back to int256 value, subtract INT256_MIN_ABS at here.\n result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS);\n console2_log(\"Bound result\", vm.toString(result));\n }\n\n /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce\n /// @notice adapated from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol)\n function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) {\n // forgefmt: disable-start\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))));\n if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))));\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce))));\n if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce))));\n if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce))));\n // forgefmt: disable-end\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return addressFromLast20Bytes(\n keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce)))\n );\n }\n\n function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer)\n internal\n pure\n virtual\n returns (address)\n {\n return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash)));\n }\n\n function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {\n require(b.length <= 32, \"StdUtils bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere.\n\n function console2_log(string memory p0, uint256 p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n status;\n }\n\n function console2_log(string memory p0, string memory p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n status;\n }\n}\n" - }, - "node_modules/forge-std/src/Test.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\n// 💬 ABOUT\n// Standard Library's default Test\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {StdAssertions} from \"./StdAssertions.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheats} from \"./StdCheats.sol\";\nimport {stdError} from \"./StdError.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {Vm} from \"./Vm.sol\";\n\n// 📦 BOILERPLATE\nimport {TestBase} from \"./Base.sol\";\nimport {DSTest} from \"ds-test/test.sol\";\n\n// ⭐️ TEST\nabstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdUtils, TestBase {\n// Note: IS_TEST() must return true.\n// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76.\n}\n" - }, - "node_modules/forge-std/src/Vm.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// Cheatcodes are marked as view/pure/none using the following rules:\n// 0. A call's observable behaviour includes its return value, logs, reverts and state writes,\n// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc),\n// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`,\n// 3. Otherwise you're `pure`.\n\ninterface VmSafe {\n struct Log {\n bytes32[] topics;\n bytes data;\n address emitter;\n }\n\n struct Rpc {\n string key;\n string url;\n }\n\n struct FsMetadata {\n bool isDir;\n bool isSymlink;\n uint256 length;\n bool readOnly;\n uint256 modified;\n uint256 accessed;\n uint256 created;\n }\n\n // Loads a storage slot from an address\n function load(address target, bytes32 slot) external view returns (bytes32 data);\n // Signs data\n function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);\n // Gets the address for a given private key\n function addr(uint256 privateKey) external pure returns (address keyAddr);\n // Gets the nonce of an account\n function getNonce(address account) external view returns (uint64 nonce);\n // Performs a foreign function call via the terminal\n function ffi(string[] calldata commandInput) external returns (bytes memory result);\n // Sets environment variables\n function setEnv(string calldata name, string calldata value) external;\n // Reads environment variables, (name) => (value)\n function envBool(string calldata name) external view returns (bool value);\n function envUint(string calldata name) external view returns (uint256 value);\n function envInt(string calldata name) external view returns (int256 value);\n function envAddress(string calldata name) external view returns (address value);\n function envBytes32(string calldata name) external view returns (bytes32 value);\n function envString(string calldata name) external view returns (string memory value);\n function envBytes(string calldata name) external view returns (bytes memory value);\n // Reads environment variables as arrays\n function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value);\n function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value);\n function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value);\n function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);\n function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value);\n function envString(string calldata name, string calldata delim) external view returns (string[] memory value);\n function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value);\n // Read environment variables with default value\n function envOr(string calldata name, bool defaultValue) external returns (bool value);\n function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value);\n function envOr(string calldata name, int256 defaultValue) external returns (int256 value);\n function envOr(string calldata name, address defaultValue) external returns (address value);\n function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value);\n function envOr(string calldata name, string calldata defaultValue) external returns (string memory value);\n function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value);\n // Read environment variables as arrays with default value\n function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue)\n external\n returns (bool[] memory value);\n function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue)\n external\n returns (uint256[] memory value);\n function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue)\n external\n returns (int256[] memory value);\n function envOr(string calldata name, string calldata delim, address[] calldata defaultValue)\n external\n returns (address[] memory value);\n function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue)\n external\n returns (bytes32[] memory value);\n function envOr(string calldata name, string calldata delim, string[] calldata defaultValue)\n external\n returns (string[] memory value);\n function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue)\n external\n returns (bytes[] memory value);\n // Records all storage reads and writes\n function record() external;\n // Gets all accessed reads and write slot from a recording session, for a given address\n function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots);\n // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file\n function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode);\n // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file\n function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode);\n // Labels an address in call traces\n function label(address account, string calldata newLabel) external;\n // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain\n function broadcast() external;\n // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain\n function broadcast(address signer) external;\n // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain\n function broadcast(uint256 privateKey) external;\n // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain\n function startBroadcast() external;\n // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain\n function startBroadcast(address signer) external;\n // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain\n function startBroadcast(uint256 privateKey) external;\n // Stops collecting onchain transactions\n function stopBroadcast() external;\n // Reads the entire content of file to string\n function readFile(string calldata path) external view returns (string memory data);\n // Reads the entire content of file as binary. Path is relative to the project root.\n function readFileBinary(string calldata path) external view returns (bytes memory data);\n // Get the path of the current project root\n function projectRoot() external view returns (string memory path);\n // Get the metadata for a file/directory\n function fsMetadata(string calldata fileOrDir) external returns (FsMetadata memory metadata);\n // Reads next line of file to string\n function readLine(string calldata path) external view returns (string memory line);\n // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does.\n function writeFile(string calldata path, string calldata data) external;\n // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does.\n // Path is relative to the project root.\n function writeFileBinary(string calldata path, bytes calldata data) external;\n // Writes line to file, creating a file if it does not exist.\n function writeLine(string calldata path, string calldata data) external;\n // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine.\n function closeFile(string calldata path) external;\n // Removes file. This cheatcode will revert in the following situations, but is not limited to just these cases:\n // - Path points to a directory.\n // - The file doesn't exist.\n // - The user lacks permissions to remove the file.\n function removeFile(string calldata path) external;\n // Convert values to a string\n function toString(address value) external pure returns (string memory stringifiedValue);\n function toString(bytes calldata value) external pure returns (string memory stringifiedValue);\n function toString(bytes32 value) external pure returns (string memory stringifiedValue);\n function toString(bool value) external pure returns (string memory stringifiedValue);\n function toString(uint256 value) external pure returns (string memory stringifiedValue);\n function toString(int256 value) external pure returns (string memory stringifiedValue);\n // Convert values from a string\n function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue);\n function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue);\n function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue);\n function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue);\n function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue);\n function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue);\n // Record all the transaction logs\n function recordLogs() external;\n // Gets all the recorded logs\n function getRecordedLogs() external returns (Log[] memory logs);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index}\n function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index}\n function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index)\n external\n pure\n returns (uint256 privateKey);\n // Adds a private key to the local forge wallet and returns the address\n function rememberKey(uint256 privateKey) external returns (address keyAddr);\n //\n // parseJson\n //\n // ----\n // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects\n // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in\n // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that\n // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded\n // as tuples, with the attributes in the order in which they are defined.\n // For example: json = { 'a': 1, 'b': 0xa4tb......3xs}\n // a: uint256\n // b: address\n // To decode that json, we need to define a struct or a tuple as follows:\n // struct json = { uint256 a; address b; }\n // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to\n // decode the tuple in that order, and thus fail.\n // ----\n // Given a string of JSON, return it as ABI-encoded\n function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData);\n function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData);\n\n // Serialize a key and value to a JSON object stored in-memory that can be later written to a file\n // It returns the stringified version of the specific JSON file up to that moment.\n function serializeBool(string calldata objectKey, string calldata valueKey, bool value)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256 value)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address value)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string calldata value)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value)\n external\n returns (string memory json);\n\n function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values)\n external\n returns (string memory json);\n\n //\n // writeJson\n //\n // ----\n // Write a serialized JSON object to a file. If the file exists, it will be overwritten.\n // Let's assume we want to write the following JSON to a file:\n //\n // { \"boolean\": true, \"number\": 342, \"object\": { \"title\": \"finally json serialization\" } }\n //\n // ```\n // string memory json1 = \"some key\";\n // vm.serializeBool(json1, \"boolean\", true);\n // vm.serializeBool(json1, \"number\", uint256(342));\n // json2 = \"some other key\";\n // string memory output = vm.serializeString(json2, \"title\", \"finally json serialization\");\n // string memory finalJson = vm.serialize(json1, \"object\", output);\n // vm.writeJson(finalJson, \"./output/example.json\");\n // ```\n // The critical insight is that every invocation of serialization will return the stringified version of the JSON\n // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version\n // to serialize them as values to another JSON object.\n //\n // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..)\n // will find the object in-memory that is keyed by \"some key\".\n function writeJson(string calldata json, string calldata path) external;\n // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = \n // This is useful to replace a specific value of a JSON file, without having to parse the entire thing\n function writeJson(string calldata json, string calldata path, string calldata valueKey) external;\n // Returns the RPC url for the given alias\n function rpcUrl(string calldata rpcAlias) external view returns (string memory json);\n // Returns all rpc urls and their aliases `[alias, url][]`\n function rpcUrls() external view returns (string[2][] memory urls);\n // Returns all rpc urls and their aliases as structs.\n function rpcUrlStructs() external view returns (Rpc[] memory urls);\n // If the condition is false, discard this run's fuzz inputs and generate new ones.\n function assume(bool condition) external pure;\n // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused.\n function pauseGasMetering() external;\n // Resumes gas metering (i.e. gas usage is counted again). Noop if already on.\n function resumeGasMetering() external;\n}\n\ninterface Vm is VmSafe {\n // Sets block.timestamp\n function warp(uint256 newTimestamp) external;\n // Sets block.height\n function roll(uint256 newHeight) external;\n // Sets block.basefee\n function fee(uint256 newBasefee) external;\n // Sets block.difficulty\n function difficulty(uint256 newDifficulty) external;\n // Sets block.chainid\n function chainId(uint256 newChainId) external;\n // Stores a value to an address' storage slot.\n function store(address target, bytes32 slot, bytes32 value) external;\n // Sets the nonce of an account; must be higher than the current nonce of the account\n function setNonce(address account, uint64 newNonce) external;\n // Sets the *next* call's msg.sender to be the input address\n function prank(address msgSender) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called\n function startPrank(address msgSender) external;\n // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input\n function prank(address msgSender, address txOrigin) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input\n function startPrank(address msgSender, address txOrigin) external;\n // Resets subsequent calls' msg.sender to be `address(this)`\n function stopPrank() external;\n // Sets an address' balance\n function deal(address account, uint256 newBalance) external;\n // Sets an address' code\n function etch(address target, bytes calldata newRuntimeBytecode) external;\n // Expects an error on next call\n function expectRevert(bytes calldata revertData) external;\n function expectRevert(bytes4 revertData) external;\n function expectRevert() external;\n // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData).\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data (as specified by the booleans)\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external;\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter)\n external;\n // Mocks a call to an address, returning specified data.\n // Calldata can either be strict or a partial match, e.g. if you only\n // pass a Solidity selector to the expected calldata, then the entire Solidity\n // function will be mocked.\n function mockCall(address callee, bytes calldata data, bytes calldata returnData) external;\n // Mocks a call to an address with a specific msg.value, returning specified data.\n // Calldata match takes precedence over msg.value in case of ambiguity.\n function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external;\n // Clears all mocked calls\n function clearMockedCalls() external;\n // Expects a call to an address with the specified calldata.\n // Calldata can either be a strict or a partial match\n function expectCall(address callee, bytes calldata data) external;\n // Expects a call to an address with the specified msg.value and calldata\n function expectCall(address callee, uint256 msgValue, bytes calldata data) external;\n // Sets block.coinbase\n function coinbase(address newCoinbase) external;\n // Snapshot the current state of the evm.\n // Returns the id of the snapshot that was created.\n // To revert a snapshot use `revertTo`\n function snapshot() external returns (uint256 snapshotId);\n // Revert the state of the EVM to a previous snapshot\n // Takes the snapshot id to revert to.\n // This deletes the snapshot and all snapshots taken after the given snapshot id.\n function revertTo(uint256 snapshotId) external returns (bool success);\n // Creates a new fork with the given endpoint and block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction,\n // and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before\n // the transaction, returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active.\n function selectFork(uint256 forkId) external;\n /// Returns the identifier of the currently active fork. Reverts if no fork is currently active.\n function activeFork() external view returns (uint256 forkId);\n // Updates the currently active fork to given block number\n // This is similar to `roll` but for the currently active fork\n function rollFork(uint256 blockNumber) external;\n // Updates the currently active fork to given transaction\n // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block\n function rollFork(bytes32 txHash) external;\n // Updates the given fork to given block number\n function rollFork(uint256 forkId, uint256 blockNumber) external;\n // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block\n function rollFork(uint256 forkId, bytes32 txHash) external;\n // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup\n // Meaning, changes made to the state of this account will be kept when switching forks\n function makePersistent(address account) external;\n function makePersistent(address account0, address account1) external;\n function makePersistent(address account0, address account1, address account2) external;\n function makePersistent(address[] calldata accounts) external;\n // Revokes persistent status from the address, previously added via `makePersistent`\n function revokePersistent(address account) external;\n function revokePersistent(address[] calldata accounts) external;\n // Returns true if the account is marked as persistent\n function isPersistent(address account) external view returns (bool persistent);\n // In forking mode, explicitly grant the given address cheatcode access\n function allowCheatcodes(address account) external;\n // Fetches the given transaction from the active fork and executes it on the current state\n function transact(bytes32 txHash) external;\n // Fetches the given transaction from the given fork and executes it on the current state\n function transact(uint256 forkId, bytes32 txHash) external;\n}\n" - }, - "node_modules/forge-std/src/console.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n }\n\n function logUint(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n }\n\n function log(uint p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n }\n\n function log(uint p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n }\n\n function log(uint p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n }\n\n function log(string memory p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/console2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\n/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should\n/// use `int256` and `uint256`. This modified version fixes that. This version is recommended\n/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in\n/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`.\n/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178\nlibrary console2 {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function log(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint256 p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n }\n\n function log(uint256 p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n }\n\n function log(uint256 p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n }\n\n function log(uint256 p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n }\n\n function log(string memory p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n }\n\n function log(string memory p0, int256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,int256)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - } - }, - "settings": { - "remappings": [ - "@openzeppelin/=node_modules/@openzeppelin/", - "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", - "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", - "@rari-capital/=node_modules/@rari-capital/", - "@rari-capital/solmate/=node_modules/@rari-capital/solmate/", - "ds-test/=node_modules/ds-test/src/", - "forge-std/=node_modules/forge-std/src/" - ], - "optimizer": { - "enabled": true, - "runs": 999999 - }, - "metadata": { - "bytecodeHash": "none" - }, - "outputSelection": { - "*": { - "": [ - "ast" - ], - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "storageLayout", - "devdoc", - "userdoc" - ] - } - }, - "evmVersion": "london", - "libraries": {} - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/solcInputs/86f4d300b3e19ace2c129703d85e47d6.json b/packages/contracts-bedrock/deployments/goerli/solcInputs/86f4d300b3e19ace2c129703d85e47d6.json deleted file mode 100644 index f1c72d28761e..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/solcInputs/86f4d300b3e19ace2c129703d85e47d6.json +++ /dev/null @@ -1,552 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/L1/L1CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismPortal } from \"./OptimismPortal.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1CrossDomainMessenger\n * @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible\n * for sending and receiving data on the L1 side. Users are encouraged to use this\n * interface instead of interacting with lower-level contracts directly.\n */\ncontract L1CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @notice Address of the OptimismPortal.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @custom:semver 1.4.0\n *\n * @param _portal Address of the OptimismPortal contract on this network.\n */\n constructor(OptimismPortal _portal)\n Semver(1, 4, 0)\n CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER)\n {\n PORTAL = _portal;\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return msg.sender == address(PORTAL) && PORTAL.l2Sender() == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(PORTAL);\n }\n}\n" - }, - "contracts/L1/L1ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { IERC721 } from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L1ERC721Bridge\n * @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as an escrow for ERC721 tokens deposited into L2.\n */\ncontract L1ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token\n * by ID was deposited for a given L2 token.\n */\n mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;\n\n /**\n * @custom:semver 1.1.1\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 1)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L1ERC721Bridge: local token cannot be self\");\n\n // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.\n require(\n deposits[_localToken][_remoteToken][_tokenId] == true,\n \"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\"\n );\n\n // Mark that the token ID for this L1/L2 token pair is no longer escrowed in the L1\n // Bridge.\n deposits[_localToken][_remoteToken][_tokenId] = false;\n\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the\n // withdrawer.\n IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L1ERC721Bridge: remote token cannot be address(0)\");\n\n // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)\n bytes memory message = abi.encodeWithSelector(\n L2ERC721Bridge.finalizeBridgeERC721.selector,\n _remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Lock token into bridge\n deposits[_localToken][_remoteToken][_tokenId] = true;\n IERC721(_localToken).transferFrom(_from, address(this), _tokenId);\n\n // Send calldata into L2\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L1/L1StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1StandardBridge\n * @notice The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L1, it will be escrowed within this\n * contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was\n * stored within this contract. After Bedrock, ETH is instead stored inside the\n * OptimismPortal contract.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L1StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated.\n *\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of ETH deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ETHDepositInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized.\n *\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of ETH withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 withdrawal is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _messenger Address of the L1CrossDomainMessenger.\n */\n constructor(address payable _messenger)\n Semver(1, 1, 0)\n StandardBridge(_messenger, payable(Predeploys.L2_STANDARD_BRIDGE))\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into the sender's account on L2.\n *\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETH(uint32 _minGasLimit, bytes calldata _extraData) external payable onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into a target account on L2.\n * Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will\n * be locked in the L2StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n *\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable {\n _initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into the sender's account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20(\n address _l1Token,\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual onlyEOA {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into a target account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20To(\n address _l1Token,\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ETH from L2.\n *\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of ETH to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeETHWithdrawal(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ERC20 tokens from L2.\n *\n * @param _l1Token Address of the token on L1.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of the ERC20 to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeERC20Withdrawal(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external {\n finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L2 bridge contract.\n *\n * @return Address of the corresponding L2 bridge contract.\n */\n function l2TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @notice Internal function for initiating an ETH deposit.\n *\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateETHDeposit(\n address _from,\n address _to,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Internal function for initiating an ERC20 deposit.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateERC20Deposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHDepositInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHDepositInitiated(_from, _to, _amount, _extraData);\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHWithdrawalFinalized event followed by the ETHBridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData);\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20DepositInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20DepositInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20WithdrawalFinalized event followed by the ERC20BridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20WithdrawalFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L1/L2OutputOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\n/**\n * @custom:proxied\n * @title L2OutputOracle\n * @notice The L2OutputOracle contains an array of L2 state outputs, where each output is a\n * commitment to the state of the L2 chain. Other contracts like the OptimismPortal use\n * these outputs to verify information about the state of L2.\n */\ncontract L2OutputOracle is Initializable, Semver {\n /**\n * @notice The interval in L2 blocks at which checkpoints must be submitted. Although this is\n * immutable, it can safely be modified by upgrading the implementation contract.\n */\n uint256 public immutable SUBMISSION_INTERVAL;\n\n /**\n * @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified.\n */\n uint256 public immutable L2_BLOCK_TIME;\n\n /**\n * @notice The address of the challenger. Can be updated via upgrade.\n */\n address public immutable CHALLENGER;\n\n /**\n * @notice The address of the proposer. Can be updated via upgrade.\n */\n address public immutable PROPOSER;\n\n /**\n * @notice Minimum time (in seconds) that must elapse before a withdrawal can be finalized.\n */\n uint256 public immutable FINALIZATION_PERIOD_SECONDS;\n\n /**\n * @notice The number of the first L2 block recorded in this contract.\n */\n uint256 public startingBlockNumber;\n\n /**\n * @notice The timestamp of the first L2 block recorded in this contract.\n */\n uint256 public startingTimestamp;\n\n /**\n * @notice Array of L2 output proposals.\n */\n Types.OutputProposal[] internal l2Outputs;\n\n /**\n * @notice Emitted when an output is proposed.\n *\n * @param outputRoot The output root.\n * @param l2OutputIndex The index of the output in the l2Outputs array.\n * @param l2BlockNumber The L2 block number of the output root.\n * @param l1Timestamp The L1 timestamp when proposed.\n */\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n /**\n * @notice Emitted when outputs are deleted.\n *\n * @param prevNextOutputIndex Next L2 output index before the deletion.\n * @param newNextOutputIndex Next L2 output index after the deletion.\n */\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n /**\n * @custom:semver 1.3.0\n *\n * @param _submissionInterval Interval in blocks at which checkpoints must be submitted.\n * @param _l2BlockTime The time per L2 block, in seconds.\n * @param _startingBlockNumber The number of the first L2 block.\n * @param _startingTimestamp The timestamp of the first L2 block.\n * @param _proposer The address of the proposer.\n * @param _challenger The address of the challenger.\n */\n constructor(\n uint256 _submissionInterval,\n uint256 _l2BlockTime,\n uint256 _startingBlockNumber,\n uint256 _startingTimestamp,\n address _proposer,\n address _challenger,\n uint256 _finalizationPeriodSeconds\n ) Semver(1, 3, 0) {\n require(_l2BlockTime > 0, \"L2OutputOracle: L2 block time must be greater than 0\");\n require(\n _submissionInterval > 0,\n \"L2OutputOracle: submission interval must be greater than 0\"\n );\n\n SUBMISSION_INTERVAL = _submissionInterval;\n L2_BLOCK_TIME = _l2BlockTime;\n PROPOSER = _proposer;\n CHALLENGER = _challenger;\n FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;\n\n initialize(_startingBlockNumber, _startingTimestamp);\n }\n\n /**\n * @notice Initializer.\n *\n * @param _startingBlockNumber Block number for the first recoded L2 block.\n * @param _startingTimestamp Timestamp for the first recoded L2 block.\n */\n function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp)\n public\n initializer\n {\n require(\n _startingTimestamp <= block.timestamp,\n \"L2OutputOracle: starting L2 timestamp must be less than current time\"\n );\n\n startingTimestamp = _startingTimestamp;\n startingBlockNumber = _startingBlockNumber;\n }\n\n /**\n * @notice Deletes all output proposals after and including the proposal that corresponds to\n * the given output index. Only the challenger address can delete outputs.\n *\n * @param _l2OutputIndex Index of the first L2 output to be deleted. All outputs after this\n * output will also be deleted.\n */\n // solhint-disable-next-line ordering\n function deleteL2Outputs(uint256 _l2OutputIndex) external {\n require(\n msg.sender == CHALLENGER,\n \"L2OutputOracle: only the challenger address can delete outputs\"\n );\n\n // Make sure we're not *increasing* the length of the array.\n require(\n _l2OutputIndex < l2Outputs.length,\n \"L2OutputOracle: cannot delete outputs after the latest output index\"\n );\n\n // Do not allow deleting any outputs that have already been finalized.\n require(\n block.timestamp - l2Outputs[_l2OutputIndex].timestamp < FINALIZATION_PERIOD_SECONDS,\n \"L2OutputOracle: cannot delete outputs that have already been finalized\"\n );\n\n uint256 prevNextL2OutputIndex = nextOutputIndex();\n\n // Use assembly to delete the array elements because Solidity doesn't allow it.\n assembly {\n sstore(l2Outputs.slot, _l2OutputIndex)\n }\n\n emit OutputsDeleted(prevNextL2OutputIndex, _l2OutputIndex);\n }\n\n /**\n * @notice Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp\n * must be equal to the current value returned by `nextTimestamp()` in order to be\n * accepted. This function may only be called by the Proposer.\n *\n * @param _outputRoot The L2 output of the checkpoint block.\n * @param _l2BlockNumber The L2 block number that resulted in _outputRoot.\n * @param _l1BlockHash A block hash which must be included in the current chain.\n * @param _l1BlockNumber The block number with the specified block hash.\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external payable {\n require(\n msg.sender == PROPOSER,\n \"L2OutputOracle: only the proposer address can propose new outputs\"\n );\n\n require(\n _l2BlockNumber == nextBlockNumber(),\n \"L2OutputOracle: block number must be equal to next expected block number\"\n );\n\n require(\n computeL2Timestamp(_l2BlockNumber) < block.timestamp,\n \"L2OutputOracle: cannot propose L2 output in the future\"\n );\n\n require(\n _outputRoot != bytes32(0),\n \"L2OutputOracle: L2 output proposal cannot be the zero hash\"\n );\n\n if (_l1BlockHash != bytes32(0)) {\n // This check allows the proposer to propose an output based on a given L1 block,\n // without fear that it will be reorged out.\n // It will also revert if the blockheight provided is more than 256 blocks behind the\n // chain tip (as the hash will return as zero). This does open the door to a griefing\n // attack in which the proposer's submission is censored until the block is no longer\n // retrievable, if the proposer is experiencing this attack it can simply leave out the\n // blockhash value, and delay submission until it is confident that the L1 block is\n // finalized.\n require(\n blockhash(_l1BlockNumber) == _l1BlockHash,\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n }\n\n emit OutputProposed(_outputRoot, nextOutputIndex(), _l2BlockNumber, block.timestamp);\n\n l2Outputs.push(\n Types.OutputProposal({\n outputRoot: _outputRoot,\n timestamp: uint128(block.timestamp),\n l2BlockNumber: uint128(_l2BlockNumber)\n })\n );\n }\n\n /**\n * @notice Returns an output by index. Exists because Solidity's array access will return a\n * tuple instead of a struct.\n *\n * @param _l2OutputIndex Index of the output to return.\n *\n * @return The output at the given index.\n */\n function getL2Output(uint256 _l2OutputIndex)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[_l2OutputIndex];\n }\n\n /**\n * @notice Returns the index of the L2 output that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return Index of the first checkpoint that commits to the given L2 block number.\n */\n function getL2OutputIndexAfter(uint256 _l2BlockNumber) public view returns (uint256) {\n // Make sure an output for this block number has actually been proposed.\n require(\n _l2BlockNumber <= latestBlockNumber(),\n \"L2OutputOracle: cannot get output for a block that has not been proposed\"\n );\n\n // Make sure there's at least one output proposed.\n require(\n l2Outputs.length > 0,\n \"L2OutputOracle: cannot get output as no outputs have been proposed yet\"\n );\n\n // Find the output via binary search, guaranteed to exist.\n uint256 lo = 0;\n uint256 hi = l2Outputs.length;\n while (lo < hi) {\n uint256 mid = (lo + hi) / 2;\n if (l2Outputs[mid].l2BlockNumber < _l2BlockNumber) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n return lo;\n }\n\n /**\n * @notice Returns the L2 output proposal that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return First checkpoint that commits to the given L2 block number.\n */\n function getL2OutputAfter(uint256 _l2BlockNumber)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)];\n }\n\n /**\n * @notice Returns the number of outputs that have been proposed. Will revert if no outputs\n * have been proposed yet.\n *\n * @return The number of outputs that have been proposed.\n */\n function latestOutputIndex() external view returns (uint256) {\n return l2Outputs.length - 1;\n }\n\n /**\n * @notice Returns the index of the next output to be proposed.\n *\n * @return The index of the next output to be proposed.\n */\n function nextOutputIndex() public view returns (uint256) {\n return l2Outputs.length;\n }\n\n /**\n * @notice Returns the block number of the latest submitted L2 output proposal. If no proposals\n * been submitted yet then this function will return the starting block number.\n *\n * @return Latest submitted L2 block number.\n */\n function latestBlockNumber() public view returns (uint256) {\n return\n l2Outputs.length == 0\n ? startingBlockNumber\n : l2Outputs[l2Outputs.length - 1].l2BlockNumber;\n }\n\n /**\n * @notice Computes the block number of the next L2 block that needs to be checkpointed.\n *\n * @return Next L2 block number.\n */\n function nextBlockNumber() public view returns (uint256) {\n return latestBlockNumber() + SUBMISSION_INTERVAL;\n }\n\n /**\n * @notice Returns the L2 timestamp corresponding to a given L2 block number.\n *\n * @param _l2BlockNumber The L2 block number of the target block.\n *\n * @return L2 timestamp of the given block.\n */\n function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {\n return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME);\n }\n}\n" - }, - "contracts/L1/OptimismPortal.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { L2OutputOracle } from \"./L2OutputOracle.sol\";\nimport { SystemConfig } from \"./SystemConfig.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { SecureMerkleTrie } from \"../libraries/trie/SecureMerkleTrie.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title OptimismPortal\n * @notice The OptimismPortal is a low-level contract responsible for passing messages between L1\n * and L2. Messages sent directly to the OptimismPortal have no form of replayability.\n * Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface.\n */\ncontract OptimismPortal is Initializable, ResourceMetering, Semver {\n /**\n * @notice Represents a proven withdrawal.\n *\n * @custom:field outputRoot Root of the L2 output this was proven against.\n * @custom:field timestamp Timestamp at whcih the withdrawal was proven.\n * @custom:field l2OutputIndex Index of the output this was proven against.\n */\n struct ProvenWithdrawal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2OutputIndex;\n }\n\n /**\n * @notice Version of the deposit event.\n */\n uint256 internal constant DEPOSIT_VERSION = 0;\n\n /**\n * @notice The L2 gas limit set when eth is deposited using the receive() function.\n */\n uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Address of the L2OutputOracle contract.\n */\n L2OutputOracle public immutable L2_ORACLE;\n\n /**\n * @notice Address of the SystemConfig contract.\n */\n SystemConfig public immutable SYSTEM_CONFIG;\n\n /**\n * @notice Address that has the ability to pause and unpause withdrawals.\n */\n address public immutable GUARDIAN;\n\n /**\n * @notice Address of the L2 account which initiated a withdrawal in this transaction. If the\n * of this variable is the default L2 sender address, then we are NOT inside of a call\n * to finalizeWithdrawalTransaction.\n */\n address public l2Sender;\n\n /**\n * @notice A list of withdrawal hashes which have been successfully finalized.\n */\n mapping(bytes32 => bool) public finalizedWithdrawals;\n\n /**\n * @notice A mapping of withdrawal hashes to `ProvenWithdrawal` data.\n */\n mapping(bytes32 => ProvenWithdrawal) public provenWithdrawals;\n\n /**\n * @notice Determines if cross domain messaging is paused. When set to true,\n * withdrawals are paused. This may be removed in the future.\n */\n bool public paused;\n\n /**\n * @notice Emitted when a transaction is deposited from L1 to L2. The parameters of this event\n * are read by the rollup node and used to derive deposit transactions on L2.\n *\n * @param from Address that triggered the deposit transaction.\n * @param to Address that the deposit transaction is directed to.\n * @param version Version of this deposit transaction event.\n * @param opaqueData ABI encoded deposit data to be parsed off-chain.\n */\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is proven.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n */\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is finalized.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n * @param success Whether the withdrawal transaction was successful.\n */\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n\n /**\n * @notice Emitted when the pause is triggered.\n *\n * @param account Address of the account triggering the pause.\n */\n event Paused(address account);\n\n /**\n * @notice Emitted when the pause is lifted.\n *\n * @param account Address of the account triggering the unpause.\n */\n event Unpaused(address account);\n\n /**\n * @notice Reverts when paused.\n */\n modifier whenNotPaused() {\n require(paused == false, \"OptimismPortal: paused\");\n _;\n }\n\n /**\n * @custom:semver 1.6.0\n *\n * @param _l2Oracle Address of the L2OutputOracle contract.\n * @param _guardian Address that can pause deposits and withdrawals.\n * @param _paused Sets the contract's pausability state.\n * @param _config Address of the SystemConfig contract.\n */\n constructor(\n L2OutputOracle _l2Oracle,\n address _guardian,\n bool _paused,\n SystemConfig _config\n ) Semver(1, 6, 0) {\n L2_ORACLE = _l2Oracle;\n GUARDIAN = _guardian;\n SYSTEM_CONFIG = _config;\n initialize(_paused);\n }\n\n /**\n * @notice Initializer.\n */\n function initialize(bool _paused) public initializer {\n l2Sender = Constants.DEFAULT_L2_SENDER;\n paused = _paused;\n __ResourceMetering_init();\n }\n\n /**\n * @notice Pause deposits and withdrawals.\n */\n function pause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can pause\");\n paused = true;\n emit Paused(msg.sender);\n }\n\n /**\n * @notice Unpause deposits and withdrawals.\n */\n function unpause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can unpause\");\n paused = false;\n emit Unpaused(msg.sender);\n }\n\n /**\n * @notice Computes the minimum gas limit for a deposit. The minimum gas limit\n * linearly increases based on the size of the calldata. This is to prevent\n * users from creating L2 resource usage without paying for it. This function\n * can be used when interacting with the portal to ensure forwards compatibility.\n *\n */\n function minimumGasLimit(uint64 _byteCount) public pure returns (uint64) {\n return _byteCount * 16 + 21000;\n }\n\n /**\n * @notice Accepts value so that users can send ETH directly to this contract and have the\n * funds be deposited to their address on L2. This is intended as a convenience\n * function for EOAs. Contracts should call the depositTransaction() function directly\n * otherwise any deposited funds will be lost due to address aliasing.\n */\n // solhint-disable-next-line ordering\n receive() external payable {\n depositTransaction(msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes(\"\"));\n }\n\n /**\n * @notice Accepts ETH value without triggering a deposit to L2. This function mainly exists\n * for the sake of the migration between the legacy Optimism system and Bedrock.\n */\n function donateETH() external payable {\n // Intentionally empty.\n }\n\n /**\n * @notice Getter for the resource config. Used internally by the ResourceMetering\n * contract. The SystemConfig is the source of truth for the resource config.\n *\n * @return ResourceMetering.ResourceConfig\n */\n function _resourceConfig()\n internal\n view\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return SYSTEM_CONFIG.resourceConfig();\n }\n\n /**\n * @notice Proves a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n * @param _l2OutputIndex L2 output index to prove against.\n * @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root.\n * @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\n */\n function proveWithdrawalTransaction(\n Types.WithdrawalTransaction memory _tx,\n uint256 _l2OutputIndex,\n Types.OutputRootProof calldata _outputRootProof,\n bytes[] calldata _withdrawalProof\n ) external whenNotPaused {\n // Prevent users from creating a deposit transaction where this address is the message\n // sender on L2. Because this is checked here, we do not need to check again in\n // `finalizeWithdrawalTransaction`.\n require(\n _tx.target != address(this),\n \"OptimismPortal: you cannot send messages to the portal contract\"\n );\n\n // Get the output root and load onto the stack to prevent multiple mloads. This will\n // revert if there is no output root for the given block number.\n bytes32 outputRoot = L2_ORACLE.getL2Output(_l2OutputIndex).outputRoot;\n\n // Verify that the output root can be generated with the elements in the proof.\n require(\n outputRoot == Hashing.hashOutputRootProof(_outputRootProof),\n \"OptimismPortal: invalid output root proof\"\n );\n\n // Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // We generally want to prevent users from proving the same withdrawal multiple times\n // because each successive proof will update the timestamp. A malicious user can take\n // advantage of this to prevent other users from finalizing their withdrawal. However,\n // since withdrawals are proven before an output root is finalized, we need to allow users\n // to re-prove their withdrawal only in the case that the output root for their specified\n // output index has been updated.\n require(\n provenWithdrawal.timestamp == 0 ||\n L2_ORACLE.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot !=\n provenWithdrawal.outputRoot,\n \"OptimismPortal: withdrawal hash has already been proven\"\n );\n\n // Compute the storage slot of the withdrawal hash in the L2ToL1MessagePasser contract.\n // Refer to the Solidity documentation for more information on how storage layouts are\n // computed for mappings.\n bytes32 storageKey = keccak256(\n abi.encode(\n withdrawalHash,\n uint256(0) // The withdrawals mapping is at the first slot in the layout.\n )\n );\n\n // Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract\n // on L2. If this is true, under the assumption that the SecureMerkleTrie does not have\n // bugs, then we know that this withdrawal was actually triggered on L2 and can therefore\n // be relayed on L1.\n require(\n SecureMerkleTrie.verifyInclusionProof(\n abi.encode(storageKey),\n hex\"01\",\n _withdrawalProof,\n _outputRootProof.messagePasserStorageRoot\n ),\n \"OptimismPortal: invalid withdrawal inclusion proof\"\n );\n\n // Designate the withdrawalHash as proven by storing the `outputRoot`, `timestamp`, and\n // `l2BlockNumber` in the `provenWithdrawals` mapping. A `withdrawalHash` can only be\n // proven once unless it is submitted again with a different outputRoot.\n provenWithdrawals[withdrawalHash] = ProvenWithdrawal({\n outputRoot: outputRoot,\n timestamp: uint128(block.timestamp),\n l2OutputIndex: uint128(_l2OutputIndex)\n });\n\n // Emit a `WithdrawalProven` event.\n emit WithdrawalProven(withdrawalHash, _tx.sender, _tx.target);\n }\n\n /**\n * @notice Finalizes a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n */\n function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx)\n external\n whenNotPaused\n {\n // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other\n // than the default value when a withdrawal transaction is being finalized. This check is\n // a defacto reentrancy guard.\n require(\n l2Sender == Constants.DEFAULT_L2_SENDER,\n \"OptimismPortal: can only trigger one withdrawal per transaction\"\n );\n\n // Grab the proven withdrawal from the `provenWithdrawals` map.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // A withdrawal can only be finalized if it has been proven. We know that a withdrawal has\n // been proven at least once when its timestamp is non-zero. Unproven withdrawals will have\n // a timestamp of zero.\n require(\n provenWithdrawal.timestamp != 0,\n \"OptimismPortal: withdrawal has not been proven yet\"\n );\n\n // As a sanity check, we make sure that the proven withdrawal's timestamp is greater than\n // starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of\n // safety against weird bugs in the proving step.\n require(\n provenWithdrawal.timestamp >= L2_ORACLE.startingTimestamp(),\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n\n // A proven withdrawal must wait at least the finalization period before it can be\n // finalized. This waiting period can elapse in parallel with the waiting period for the\n // output the withdrawal was proven against. In effect, this means that the minimum\n // withdrawal time is proposal submission time + finalization period.\n require(\n _isFinalizationPeriodElapsed(provenWithdrawal.timestamp),\n \"OptimismPortal: proven withdrawal finalization period has not elapsed\"\n );\n\n // Grab the OutputProposal from the L2OutputOracle, will revert if the output that\n // corresponds to the given index has not been proposed yet.\n Types.OutputProposal memory proposal = L2_ORACLE.getL2Output(\n provenWithdrawal.l2OutputIndex\n );\n\n // Check that the output root that was used to prove the withdrawal is the same as the\n // current output root for the given output index. An output root may change if it is\n // deleted by the challenger address and then re-proposed.\n require(\n proposal.outputRoot == provenWithdrawal.outputRoot,\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n\n // Check that the output proposal has also been finalized.\n require(\n _isFinalizationPeriodElapsed(proposal.timestamp),\n \"OptimismPortal: output proposal finalization period has not elapsed\"\n );\n\n // Check that this withdrawal has not already been finalized, this is replay protection.\n require(\n finalizedWithdrawals[withdrawalHash] == false,\n \"OptimismPortal: withdrawal has already been finalized\"\n );\n\n // Mark the withdrawal as finalized so it can't be replayed.\n finalizedWithdrawals[withdrawalHash] = true;\n\n // Set the l2Sender so contracts know who triggered this withdrawal on L2.\n l2Sender = _tx.sender;\n\n // Trigger the call to the target contract. We use a custom low level method\n // SafeCall.callWithMinGas to ensure two key properties\n // 1. Target contracts cannot force this call to run out of gas by returning a very large\n // amount of data (and this is OK because we don't care about the returndata here).\n // 2. The amount of gas provided to the execution context of the target is at least the\n // gas limit specified by the user. If there is not enough gas in the current context\n // to accomplish this, `callWithMinGas` will revert.\n bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data);\n\n // Reset the l2Sender back to the default value.\n l2Sender = Constants.DEFAULT_L2_SENDER;\n\n // All withdrawals are immediately finalized. Replayability can\n // be achieved through contracts built on top of this contract\n emit WithdrawalFinalized(withdrawalHash, success);\n\n // Reverting here is useful for determining the exact gas cost to successfully execute the\n // sub call to the target contract if the minimum gas limit specified by the user would not\n // be sufficient to execute the sub call.\n if (success == false && tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"OptimismPortal: withdrawal failed\");\n }\n }\n\n /**\n * @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in\n * deriving deposit transactions. Note that if a deposit is made by a contract, its\n * address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider\n * using the CrossDomainMessenger contracts for a simpler developer experience.\n *\n * @param _to Target address on L2.\n * @param _value ETH value to send to the recipient.\n * @param _gasLimit Minimum L2 gas limit (can be greater than or equal to this value).\n * @param _isCreation Whether or not the transaction is a contract creation.\n * @param _data Data to trigger the recipient with.\n */\n function depositTransaction(\n address _to,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable metered(_gasLimit) {\n // Just to be safe, make sure that people specify address(0) as the target when doing\n // contract creations.\n if (_isCreation) {\n require(\n _to == address(0),\n \"OptimismPortal: must send to address(0) when creating a contract\"\n );\n }\n\n // Prevent depositing transactions that have too small of a gas limit. Users should pay\n // more for more resource usage.\n require(\n _gasLimit >= minimumGasLimit(uint64(_data.length)),\n \"OptimismPortal: gas limit too small\"\n );\n\n // Prevent the creation of deposit transactions that have too much calldata. This gives an\n // upper limit on the size of unsafe blocks over the p2p network. 120kb is chosen to ensure\n // that the transaction can fit into the p2p network policy of 128kb even though deposit\n // transactions are not gossipped over the p2p network.\n require(_data.length <= 120_000, \"OptimismPortal: data too large\");\n\n // Transform the from-address to its alias if the caller is a contract.\n address from = msg.sender;\n if (msg.sender != tx.origin) {\n from = AddressAliasHelper.applyL1ToL2Alias(msg.sender);\n }\n\n // Compute the opaque data that will be emitted as part of the TransactionDeposited event.\n // We use opaque data so that we can update the TransactionDeposited event in the future\n // without breaking the current interface.\n bytes memory opaqueData = abi.encodePacked(\n msg.value,\n _value,\n _gasLimit,\n _isCreation,\n _data\n );\n\n // Emit a TransactionDeposited event so that the rollup node can derive a deposit\n // transaction for this deposit.\n emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);\n }\n\n /**\n * @notice Determine if a given output is finalized. Reverts if the call to\n * L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\n *\n * @param _l2OutputIndex Index of the L2 output to check.\n *\n * @return Whether or not the output is finalized.\n */\n function isOutputFinalized(uint256 _l2OutputIndex) external view returns (bool) {\n return _isFinalizationPeriodElapsed(L2_ORACLE.getL2Output(_l2OutputIndex).timestamp);\n }\n\n /**\n * @notice Determines whether the finalization period has elapsed w/r/t a given timestamp.\n *\n * @param _timestamp Timestamp to check.\n *\n * @return Whether or not the finalization period has elapsed.\n */\n function _isFinalizationPeriodElapsed(uint256 _timestamp) internal view returns (bool) {\n return block.timestamp > _timestamp + L2_ORACLE.FINALIZATION_PERIOD_SECONDS();\n }\n}\n" - }, - "contracts/L1/ResourceMetering.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\n\n/**\n * @custom:upgradeable\n * @title ResourceMetering\n * @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing\n * updates automatically based on current demand.\n */\nabstract contract ResourceMetering is Initializable {\n /**\n * @notice Represents the various parameters that control the way in which resources are\n * metered. Corresponds to the EIP-1559 resource metering system.\n *\n * @custom:field prevBaseFee Base fee from the previous block(s).\n * @custom:field prevBoughtGas Amount of gas bought so far in the current block.\n * @custom:field prevBlockNum Last block number that the base fee was updated.\n */\n struct ResourceParams {\n uint128 prevBaseFee;\n uint64 prevBoughtGas;\n uint64 prevBlockNum;\n }\n\n /**\n * @notice Represents the configuration for the EIP-1559 based curve for the deposit gas\n * market. These values should be set with care as it is possible to set them in\n * a way that breaks the deposit gas market. The target resource limit is defined as\n * maxResourceLimit / elasticityMultiplier. This struct was designed to fit within a\n * single word. There is additional space for additions in the future.\n *\n * @custom:field maxResourceLimit Represents the maximum amount of deposit gas that\n * can be purchased per block.\n * @custom:field elasticityMultiplier Determines the target resource limit along with\n * the resource limit.\n * @custom:field baseFeeMaxChangeDenominator Determines max change on fee per block.\n * @custom:field minimumBaseFee The min deposit base fee, it is clamped to this\n * value.\n * @custom:field systemTxMaxGas The amount of gas supplied to the system\n * transaction. This should be set to the same number\n * that the op-node sets as the gas limit for the\n * system transaction.\n * @custom:field maximumBaseFee The max deposit base fee, it is clamped to this\n * value.\n */\n struct ResourceConfig {\n uint32 maxResourceLimit;\n uint8 elasticityMultiplier;\n uint8 baseFeeMaxChangeDenominator;\n uint32 minimumBaseFee;\n uint32 systemTxMaxGas;\n uint128 maximumBaseFee;\n }\n\n /**\n * @notice EIP-1559 style gas parameters.\n */\n ResourceParams public params;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[48] private __gap;\n\n /**\n * @notice Meters access to a function based an amount of a requested resource.\n *\n * @param _amount Amount of the resource requested.\n */\n modifier metered(uint64 _amount) {\n // Record initial gas amount so we can refund for it later.\n uint256 initialGas = gasleft();\n\n // Run the underlying function.\n _;\n\n // Run the metering function.\n _metered(_amount, initialGas);\n }\n\n /**\n * @notice An internal function that holds all of the logic for metering a resource.\n *\n * @param _amount Amount of the resource requested.\n * @param _initialGas The amount of gas before any modifier execution.\n */\n function _metered(uint64 _amount, uint256 _initialGas) internal {\n // Update block number and base fee if necessary.\n uint256 blockDiff = block.number - params.prevBlockNum;\n\n ResourceConfig memory config = _resourceConfig();\n int256 targetResourceLimit = int256(uint256(config.maxResourceLimit)) /\n int256(uint256(config.elasticityMultiplier));\n\n if (blockDiff > 0) {\n // Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate\n // at which deposits can be created and therefore limit the potential for deposits to\n // spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.\n int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit;\n int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) /\n (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));\n\n // Update base fee by adding the base fee delta and clamp the resulting value between\n // min and max.\n int256 newBaseFee = Arithmetic.clamp({\n _value: int256(uint256(params.prevBaseFee)) + baseFeeDelta,\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n\n // If we skipped more than one block, we also need to account for every empty block.\n // Empty block means there was no demand for deposits in that block, so we should\n // reflect this lack of demand in the fee.\n if (blockDiff > 1) {\n // Update the base fee by repeatedly applying the exponent 1-(1/change_denominator)\n // blockDiff - 1 times. Simulates multiple empty blocks. Clamp the resulting value\n // between min and max.\n newBaseFee = Arithmetic.clamp({\n _value: Arithmetic.cdexp({\n _coefficient: newBaseFee,\n _denominator: int256(uint256(config.baseFeeMaxChangeDenominator)),\n _exponent: int256(blockDiff - 1)\n }),\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n }\n\n // Update new base fee, reset bought gas, and update block number.\n params.prevBaseFee = uint128(uint256(newBaseFee));\n params.prevBoughtGas = 0;\n params.prevBlockNum = uint64(block.number);\n }\n\n // Make sure we can actually buy the resource amount requested by the user.\n params.prevBoughtGas += _amount;\n require(\n int256(uint256(params.prevBoughtGas)) <= int256(uint256(config.maxResourceLimit)),\n \"ResourceMetering: cannot buy more gas than available gas limit\"\n );\n\n // Determine the amount of ETH to be paid.\n uint256 resourceCost = uint256(_amount) * uint256(params.prevBaseFee);\n\n // We currently charge for this ETH amount as an L1 gas burn, so we convert the ETH amount\n // into gas by dividing by the L1 base fee. We assume a minimum base fee of 1 gwei to avoid\n // division by zero for L1s that don't support 1559 or to avoid excessive gas burns during\n // periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei\n // during any 1 day period in the last 5 years, so should be fine.\n uint256 gasCost = resourceCost / Math.max(block.basefee, 1 gwei);\n\n // Give the user a refund based on the amount of gas they used to do all of the work up to\n // this point. Since we're at the end of the modifier, this should be pretty accurate. Acts\n // effectively like a dynamic stipend (with a minimum value).\n uint256 usedGas = _initialGas - gasleft();\n if (gasCost > usedGas) {\n Burn.gas(gasCost - usedGas);\n }\n }\n\n /**\n * @notice Virtual function that returns the resource config. Contracts that inherit this\n * contract must implement this function.\n *\n * @return ResourceConfig\n */\n function _resourceConfig() internal virtual returns (ResourceConfig memory);\n\n /**\n * @notice Sets initial resource parameter values. This function must either be called by the\n * initializer function of an upgradeable child contract.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __ResourceMetering_init() internal onlyInitializing {\n params = ResourceParams({\n prevBaseFee: 1 gwei,\n prevBoughtGas: 0,\n prevBlockNum: uint64(block.number)\n });\n }\n}\n" - }, - "contracts/L1/SystemConfig.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\n\n/**\n * @title SystemConfig\n * @notice The SystemConfig contract is used to manage configuration of an Optimism network. All\n * configuration is stored on L1 and picked up by L2 as part of the derviation of the L2\n * chain.\n */\ncontract SystemConfig is OwnableUpgradeable, Semver {\n /**\n * @notice Enum representing different types of updates.\n *\n * @custom:value BATCHER Represents an update to the batcher hash.\n * @custom:value GAS_CONFIG Represents an update to txn fee config on L2.\n * @custom:value GAS_LIMIT Represents an update to gas limit on L2.\n * @custom:value UNSAFE_BLOCK_SIGNER Represents an update to the signer key for unsafe\n * block distrubution.\n */\n enum UpdateType {\n BATCHER,\n GAS_CONFIG,\n GAS_LIMIT,\n UNSAFE_BLOCK_SIGNER\n }\n\n /**\n * @notice Version identifier, used for upgrades.\n */\n uint256 public constant VERSION = 0;\n\n /**\n * @notice Storage slot that the unsafe block signer is stored at. Storing it at this\n * deterministic storage slot allows for decoupling the storage layout from the way\n * that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value.\n */\n bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256(\"systemconfig.unsafeblocksigner\");\n\n /**\n * @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public overhead;\n\n /**\n * @notice Dynamic L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public scalar;\n\n /**\n * @notice Identifier for the batcher. For version 1 of this configuration, this is represented\n * as an address left-padded with zeros to 32 bytes.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice L2 block gas limit.\n */\n uint64 public gasLimit;\n\n /**\n * @notice The configuration for the deposit fee market. Used by the OptimismPortal\n * to meter the cost of buying L2 gas on L1. Set as internal and wrapped with a getter\n * so that the struct is returned instead of a tuple.\n */\n ResourceMetering.ResourceConfig internal _resourceConfig;\n\n /**\n * @notice Emitted when configuration is updated\n *\n * @param version SystemConfig version.\n * @param updateType Type of update.\n * @param data Encoded update data.\n */\n event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);\n\n /**\n * @custom:semver 1.3.0\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial resource config.\n */\n constructor(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) Semver(1, 3, 0) {\n initialize({\n _owner: _owner,\n _overhead: _overhead,\n _scalar: _scalar,\n _batcherHash: _batcherHash,\n _gasLimit: _gasLimit,\n _unsafeBlockSigner: _unsafeBlockSigner,\n _config: _config\n });\n }\n\n /**\n * @notice Initializer. The resource config must be set before the\n * require check.\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial ResourceConfig.\n */\n function initialize(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) public initializer {\n __Ownable_init();\n transferOwnership(_owner);\n overhead = _overhead;\n scalar = _scalar;\n batcherHash = _batcherHash;\n gasLimit = _gasLimit;\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n _setResourceConfig(_config);\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n }\n\n /**\n * @notice Returns the minimum L2 gas limit that can be safely set for the system to\n * operate. The L2 gas limit must be larger than or equal to the amount of\n * gas that is allocated for deposits per block plus the amount of gas that\n * is allocated for the system transaction.\n * This function is used to determine if changes to parameters are safe.\n *\n * @return uint64\n */\n function minimumGasLimit() public view returns (uint64) {\n return uint64(_resourceConfig.maxResourceLimit) + uint64(_resourceConfig.systemTxMaxGas);\n }\n\n /**\n * @notice High level getter for the unsafe block signer address. Unsafe blocks can be\n * propagated across the p2p network if they are signed by the key corresponding to\n * this address.\n *\n * @return Address of the unsafe block signer.\n */\n // solhint-disable-next-line ordering\n function unsafeBlockSigner() external view returns (address) {\n address addr;\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n addr := sload(slot)\n }\n return addr;\n }\n\n /**\n * @notice Updates the unsafe block signer address.\n *\n * @param _unsafeBlockSigner New unsafe block signer address.\n */\n function setUnsafeBlockSigner(address _unsafeBlockSigner) external onlyOwner {\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n\n bytes memory data = abi.encode(_unsafeBlockSigner);\n emit ConfigUpdate(VERSION, UpdateType.UNSAFE_BLOCK_SIGNER, data);\n }\n\n /**\n * @notice Updates the batcher hash.\n *\n * @param _batcherHash New batcher hash.\n */\n function setBatcherHash(bytes32 _batcherHash) external onlyOwner {\n batcherHash = _batcherHash;\n\n bytes memory data = abi.encode(_batcherHash);\n emit ConfigUpdate(VERSION, UpdateType.BATCHER, data);\n }\n\n /**\n * @notice Updates gas config.\n *\n * @param _overhead New overhead value.\n * @param _scalar New scalar value.\n */\n function setGasConfig(uint256 _overhead, uint256 _scalar) external onlyOwner {\n overhead = _overhead;\n scalar = _scalar;\n\n bytes memory data = abi.encode(_overhead, _scalar);\n emit ConfigUpdate(VERSION, UpdateType.GAS_CONFIG, data);\n }\n\n /**\n * @notice Updates the L2 gas limit.\n *\n * @param _gasLimit New gas limit.\n */\n function setGasLimit(uint64 _gasLimit) external onlyOwner {\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n gasLimit = _gasLimit;\n\n bytes memory data = abi.encode(_gasLimit);\n emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data);\n }\n\n /**\n * @notice Low level setter for the unsafe block signer address. This function exists to\n * deduplicate code around storing the unsafeBlockSigner address in storage.\n *\n * @param _unsafeBlockSigner New unsafeBlockSigner value.\n */\n function _setUnsafeBlockSigner(address _unsafeBlockSigner) internal {\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n sstore(slot, _unsafeBlockSigner)\n }\n }\n\n /**\n * @notice A getter for the resource config. Ensures that the struct is\n * returned instead of a tuple.\n *\n * @return ResourceConfig\n */\n function resourceConfig() external view returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig;\n }\n\n /**\n * @notice An external setter for the resource config. In the future, this\n * method may emit an event that the `op-node` picks up for when the\n * resource config is changed.\n *\n * @param _config The new resource config values.\n */\n function setResourceConfig(ResourceMetering.ResourceConfig memory _config) external onlyOwner {\n _setResourceConfig(_config);\n }\n\n /**\n * @notice An internal setter for the resource config. Ensures that the\n * config is sane before storing it by checking for invariants.\n *\n * @param _config The new resource config.\n */\n function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal {\n // Min base fee must be less than or equal to max base fee.\n require(\n _config.minimumBaseFee <= _config.maximumBaseFee,\n \"SystemConfig: min base fee must be less than max base\"\n );\n // Base fee change denominator must be greater than 1.\n require(\n _config.baseFeeMaxChangeDenominator > 1,\n \"SystemConfig: denominator must be larger than 1\"\n );\n // Max resource limit plus system tx gas must be less than or equal to the L2 gas limit.\n // The gas limit must be increased before these values can be increased.\n require(\n _config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit,\n \"SystemConfig: gas limit too low\"\n );\n // Elasticity multiplier must be greater than 0.\n require(\n _config.elasticityMultiplier > 0,\n \"SystemConfig: elasticity multiplier cannot be 0\"\n );\n // No precision loss when computing target resource limit.\n require(\n ((_config.maxResourceLimit / _config.elasticityMultiplier) *\n _config.elasticityMultiplier) == _config.maxResourceLimit,\n \"SystemConfig: precision loss with target resource limit\"\n );\n\n _resourceConfig = _config;\n }\n}\n" - }, - "contracts/L2/BaseFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000019\n * @title BaseFeeVault\n * @notice The BaseFeeVault accumulates the base fee that is paid by transactions.\n */\ncontract BaseFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n}\n" - }, - "contracts/L2/CrossDomainOwnable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\n/**\n * @title CrossDomainOwnable\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is only safe to be used if the\n * CrossDomainMessenger system is bypassed and the caller on L1 is calling the\n * OptimismPortal directly.\n */\nabstract contract CrossDomainOwnable is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `msg.sender` is the owner of the contract.\n */\n function _checkOwner() internal view override {\n require(\n owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender),\n \"CrossDomainOwnable: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable2\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is meant to be used with systems that use\n * the CrossDomainMessenger system. It will not work if the OptimismPortal is used\n * directly.\n */\nabstract contract CrossDomainOwnable2 is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable2: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable2: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable3\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on either L1 or L2. Note that this contract is meant to be used with systems\n * that use the CrossDomainMessenger system. It will not work if the OptimismPortal is\n * used directly.\n */\nabstract contract CrossDomainOwnable3 is Ownable {\n /**\n * @notice If true, the contract uses the cross domain _checkOwner function override. If false\n * it uses the standard Ownable _checkOwner function.\n */\n bool public isLocal = true;\n\n /**\n * @notice Emits when ownership of the contract is transferred. Includes the\n * isLocal field in addition to the standard `Ownable` OwnershipTransferred event.\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n /**\n * @notice Allows for ownership to be transferred with specifying the locality.\n * @param _owner The new owner of the contract.\n * @param _isLocal Configures the locality of the ownership.\n */\n function transferOwnership(address _owner, bool _isLocal) external onlyOwner {\n require(_owner != address(0), \"CrossDomainOwnable3: new owner is the zero address\");\n\n address oldOwner = owner();\n _transferOwnership(_owner);\n isLocal = _isLocal;\n\n emit OwnershipTransferred(oldOwner, _owner, _isLocal);\n }\n\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n if (isLocal) {\n require(owner() == msg.sender, \"CrossDomainOwnable3: caller is not the owner\");\n } else {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable3: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable3: caller is not the owner\"\n );\n }\n }\n}\n" - }, - "contracts/L2/GasPriceOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000000F\n * @title GasPriceOracle\n * @notice This contract maintains the variables responsible for computing the L1 portion of the\n * total fee charged on L2. Before Bedrock, this contract held variables in state that were\n * read during the state transition function to compute the L1 portion of the transaction\n * fee. After Bedrock, this contract now simply proxies the L1Block contract, which has\n * the values used to compute the L1 portion of the fee in its state.\n *\n * The contract exposes an API that is useful for knowing how large the L1 portion of the\n * transaction fee will be. The following events were deprecated with Bedrock:\n * - event OverheadUpdated(uint256 overhead);\n * - event ScalarUpdated(uint256 scalar);\n * - event DecimalsUpdated(uint256 decimals);\n */\ncontract GasPriceOracle is Semver {\n /**\n * @notice Number of decimals used in the scalar.\n */\n uint256 public constant DECIMALS = 6;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Computes the L1 portion of the fee based on the size of the rlp encoded input\n * transaction, the current L1 base fee, and the various dynamic parameters.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.\n *\n * @return L1 fee that should be paid for the tx\n */\n function getL1Fee(bytes memory _data) external view returns (uint256) {\n uint256 l1GasUsed = getL1GasUsed(_data);\n uint256 l1Fee = l1GasUsed * l1BaseFee();\n uint256 divisor = 10**DECIMALS;\n uint256 unscaled = l1Fee * scalar();\n uint256 scaled = unscaled / divisor;\n return scaled;\n }\n\n /**\n * @notice Retrieves the current gas price (base fee).\n *\n * @return Current L2 gas price (base fee).\n */\n function gasPrice() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current base fee.\n *\n * @return Current L2 base fee.\n */\n function baseFee() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current fee overhead.\n *\n * @return Current fee overhead.\n */\n function overhead() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead();\n }\n\n /**\n * @notice Retrieves the current fee scalar.\n *\n * @return Current fee scalar.\n */\n function scalar() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar();\n }\n\n /**\n * @notice Retrieves the latest known L1 base fee.\n *\n * @return Latest known L1 base fee.\n */\n function l1BaseFee() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee();\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the number of decimals used in the scalar.\n *\n * @return Number of decimals used in the scalar.\n */\n function decimals() public pure returns (uint256) {\n return DECIMALS;\n }\n\n /**\n * @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which\n * represents the per-transaction gas overhead of posting the transaction and state\n * roots to L1. Adds 68 bytes of padding to account for the fact that the input does\n * not have a signature.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for.\n *\n * @return Amount of L1 gas used to publish the transaction.\n */\n function getL1GasUsed(bytes memory _data) public view returns (uint256) {\n uint256 total = 0;\n uint256 length = _data.length;\n for (uint256 i = 0; i < length; i++) {\n if (_data[i] == 0) {\n total += 4;\n } else {\n total += 16;\n }\n }\n uint256 unsigned = total + overhead();\n return unsigned + (68 * 16);\n }\n}\n" - }, - "contracts/L2/L1Block.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000015\n * @title L1Block\n * @notice The L1Block predeploy gives users access to information about the last known L1 block.\n * Values within this contract are updated once per epoch (every L1 block) and can only be\n * set by the \"depositor\" account, a special system address. Depositor account transactions\n * are created by the protocol whenever we move to a new epoch.\n */\ncontract L1Block is Semver {\n /**\n * @notice Address of the special depositor account.\n */\n address public constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001;\n\n /**\n * @notice The latest L1 block number known by the L2 system.\n */\n uint64 public number;\n\n /**\n * @notice The latest L1 timestamp known by the L2 system.\n */\n uint64 public timestamp;\n\n /**\n * @notice The latest L1 basefee.\n */\n uint256 public basefee;\n\n /**\n * @notice The latest L1 blockhash.\n */\n bytes32 public hash;\n\n /**\n * @notice The number of L2 blocks in the same epoch.\n */\n uint64 public sequenceNumber;\n\n /**\n * @notice The versioned hash to authenticate the batcher by.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice The overhead value applied to the L1 portion of the transaction\n * fee.\n */\n uint256 public l1FeeOverhead;\n\n /**\n * @notice The scalar value applied to the L1 portion of the transaction fee.\n */\n uint256 public l1FeeScalar;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Updates the L1 block values.\n *\n * @param _number L1 blocknumber.\n * @param _timestamp L1 timestamp.\n * @param _basefee L1 basefee.\n * @param _hash L1 blockhash.\n * @param _sequenceNumber Number of L2 blocks since epoch start.\n * @param _batcherHash Versioned hash to authenticate batcher by.\n * @param _l1FeeOverhead L1 fee overhead.\n * @param _l1FeeScalar L1 fee scalar.\n */\n function setL1BlockValues(\n uint64 _number,\n uint64 _timestamp,\n uint256 _basefee,\n bytes32 _hash,\n uint64 _sequenceNumber,\n bytes32 _batcherHash,\n uint256 _l1FeeOverhead,\n uint256 _l1FeeScalar\n ) external {\n require(\n msg.sender == DEPOSITOR_ACCOUNT,\n \"L1Block: only the depositor account can set L1 block values\"\n );\n\n number = _number;\n timestamp = _timestamp;\n basefee = _basefee;\n hash = _hash;\n sequenceNumber = _sequenceNumber;\n batcherHash = _batcherHash;\n l1FeeOverhead = _l1FeeOverhead;\n l1FeeScalar = _l1FeeScalar;\n }\n}\n" - }, - "contracts/L2/L1FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000001A\n * @title L1FeeVault\n * @notice The L1FeeVault accumulates the L1 portion of the transaction fees.\n */\ncontract L1FeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n}\n" - }, - "contracts/L2/L2CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { L2ToL1MessagePasser } from \"./L2ToL1MessagePasser.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000007\n * @title L2CrossDomainMessenger\n * @notice The L2CrossDomainMessenger is a high-level interface for message passing between L1 and\n * L2 on the L2 side. Users are generally encouraged to use this contract instead of lower\n * level message passing contracts.\n */\ncontract L2CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @custom:semver 1.4.0\n *\n * @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.\n */\n constructor(address _l1CrossDomainMessenger)\n Semver(1, 4, 0)\n CrossDomainMessenger(_l1CrossDomainMessenger)\n {\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote messenger. Use otherMessenger going forward.\n *\n * @return Address of the L1CrossDomainMessenger contract.\n */\n function l1CrossDomainMessenger() public view returns (address) {\n return OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{\n value: _value\n }(_to, _gasLimit, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(Predeploys.L2_TO_L1_MESSAGE_PASSER);\n }\n}\n" - }, - "contracts/L2/L2ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { IOptimismMintableERC721 } from \"../universal/IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L2ERC721Bridge\n * @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.\n * This contract also acts as a burner for tokens being withdrawn.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n */\ncontract L2ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L1. Data supplied here will not be used to\n * execute any code on L1 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L2ERC721Bridge: local token cannot be self\");\n\n // Note that supportsInterface makes a callback to the _localToken address which is user\n // provided.\n require(\n ERC165Checker.supportsInterface(_localToken, type(IOptimismMintableERC721).interfaceId),\n \"L2ERC721Bridge: local token interface is not compliant\"\n );\n\n require(\n _remoteToken == IOptimismMintableERC721(_localToken).remoteToken(),\n \"L2ERC721Bridge: wrong remote token for Optimism Mintable ERC721 local token\"\n );\n\n // When a deposit is finalized, we give the NFT with the same tokenId to the account\n // on L2. Note that safeMint makes a callback to the _to address which is user provided.\n IOptimismMintableERC721(_localToken).safeMint(_to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L2ERC721Bridge: remote token cannot be address(0)\");\n\n // Check that the withdrawal is being initiated by the NFT owner\n require(\n _from == IOptimismMintableERC721(_localToken).ownerOf(_tokenId),\n \"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\"\n );\n\n // Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)\n // slither-disable-next-line reentrancy-events\n address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();\n require(\n remoteToken == _remoteToken,\n \"L2ERC721Bridge: remote token does not match given value\"\n );\n\n // When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2\n // usage\n // slither-disable-next-line reentrancy-events\n IOptimismMintableERC721(_localToken).burn(_from, _tokenId);\n\n bytes memory message = abi.encodeWithSelector(\n L1ERC721Bridge.finalizeBridgeERC721.selector,\n remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Send message to L1 bridge\n // slither-disable-next-line reentrancy-events\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L2/L2StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000010\n * @title L2StandardBridge\n * @notice The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L2, it will be escrowed within this\n * contract. If the ERC20 token is native to L1, it will be burnt.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L2StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal from L2 to L1 is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _otherBridge Address of the L1StandardBridge.\n */\n constructor(address payable _otherBridge)\n Semver(1, 1, 0)\n StandardBridge(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER), _otherBridge)\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateWithdrawal(\n Predeploys.LEGACY_ERC20_ETH,\n msg.sender,\n msg.sender,\n msg.value,\n RECEIVE_DEFAULT_GAS_LIMIT,\n bytes(\"\")\n );\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdraw(\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual onlyEOA {\n _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1 to a target account on L1.\n * Note that if ETH is sent to a contract on L1 and the call fails, then that ETH will\n * be locked in the L1StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20To` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdrawTo(\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual {\n _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a deposit from L1 to L2. To finalize a deposit of ether, use address(0)\n * and the l1Token and the Legacy ERC20 ether predeploy address as the l2Token.\n *\n * @param _l1Token Address of the L1 token to deposit.\n * @param _l2Token Address of the corresponding L2 token.\n * @param _from Address of the depositor.\n * @param _to Address of the recipient.\n * @param _amount Amount of the tokens being deposited.\n * @param _extraData Extra data attached to the deposit.\n */\n function finalizeDeposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable virtual {\n if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n } else {\n finalizeBridgeERC20(_l2Token, _l1Token, _from, _to, _amount, _extraData);\n }\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L1 bridge contract.\n *\n * @return Address of the corresponding L1 bridge contract.\n */\n function l1TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @custom:legacy\n * @notice Internal function to a withdrawal from L2 to L1 to a target account on L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _from Address of the withdrawer.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function _initiateWithdrawal(\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {\n _initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);\n } else {\n address l1Token = OptimismMintableERC20(_l2Token).l1Token();\n _initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ETHBridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ERC20BridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L2/L2ToL1MessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000016\n * @title L2ToL1MessagePasser\n * @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from\n * L2 to L1 can be stored. The storage root of this contract is pulled up to the top level\n * of the L2 output to reduce the cost of proving the existence of sent messages.\n */\ncontract L2ToL1MessagePasser is Semver {\n /**\n * @notice The L1 gas limit set when eth is withdrawn using the receive() function.\n */\n uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Includes the message hashes for all withdrawals\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @notice A unique value hashed with each withdrawal.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Emitted any time a withdrawal is initiated.\n *\n * @param nonce Unique value corresponding to each withdrawal.\n * @param sender The L2 account address which initiated the withdrawal.\n * @param target The L1 account address the call will be send to.\n * @param value The ETH value submitted for withdrawal, to be forwarded to the target.\n * @param gasLimit The minimum amount of gas that must be provided when withdrawing.\n * @param data The data to be forwarded to the target on L1.\n * @param withdrawalHash The hash of the withdrawal.\n */\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n /**\n * @notice Emitted when the balance of this contract is burned.\n *\n * @param amount Amount of ETh that was burned.\n */\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Allows users to withdraw ETH by sending directly to this contract.\n */\n receive() external payable {\n initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @notice Removes all ETH held by this contract from the state. Used to prevent the amount of\n * ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to\n * create a contract and self-destruct it to itself. Anyone can call this function. Not\n * incentivized since this function is very cheap.\n */\n function burn() external {\n uint256 balance = address(this).balance;\n Burn.eth(balance);\n emit WithdrawerBalanceBurnt(balance);\n }\n\n /**\n * @notice Sends a message from L2 to L1.\n *\n * @param _target Address to call on L1 execution.\n * @param _gasLimit Minimum gas limit for executing the message on L1.\n * @param _data Data to forward to L1 target.\n */\n function initiateWithdrawal(\n address _target,\n uint256 _gasLimit,\n bytes memory _data\n ) public payable {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messageNonce(),\n sender: msg.sender,\n target: _target,\n value: msg.value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n sentMessages[withdrawalHash] = true;\n\n emit MessagePassed(\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _gasLimit,\n _data,\n withdrawalHash\n );\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n}\n" - }, - "contracts/L2/SequencerFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000011\n * @title SequencerFeeVault\n * @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during\n * transaction processing and block production.\n */\ncontract SequencerFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the recipient address.\n *\n * @return The recipient address.\n */\n function l1FeeWallet() public view returns (address) {\n return RECIPIENT;\n }\n}\n" - }, - "contracts/deployment/PortalSender.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/**\n * @title PortalSender\n * @notice The PortalSender is a simple intermediate contract that will transfer the balance of the\n * L1StandardBridge to the OptimismPortal during the Bedrock migration.\n */\ncontract PortalSender {\n /**\n * @notice Address of the OptimismPortal contract.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @param _portal Address of the OptimismPortal contract.\n */\n constructor(OptimismPortal _portal) {\n PORTAL = _portal;\n }\n\n /**\n * @notice Sends balance of this contract to the OptimismPortal.\n */\n function donate() public {\n PORTAL.donateETH{ value: address(this).balance }();\n }\n}\n" - }, - "contracts/deployment/SystemDictator.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { PortalSender } from \"./PortalSender.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @title SystemDictator\n * @notice The SystemDictator is responsible for coordinating the deployment of a full Bedrock\n * system. The SystemDictator is designed to support both fresh network deployments and\n * upgrades to existing pre-Bedrock systems.\n */\ncontract SystemDictator is OwnableUpgradeable {\n /**\n * @notice Basic system configuration.\n */\n struct GlobalConfig {\n AddressManager addressManager;\n ProxyAdmin proxyAdmin;\n address controller;\n address finalOwner;\n }\n\n /**\n * @notice Set of proxy addresses.\n */\n struct ProxyAddressConfig {\n address l2OutputOracleProxy;\n address optimismPortalProxy;\n address l1CrossDomainMessengerProxy;\n address l1StandardBridgeProxy;\n address optimismMintableERC20FactoryProxy;\n address l1ERC721BridgeProxy;\n address systemConfigProxy;\n }\n\n /**\n * @notice Set of implementation addresses.\n */\n struct ImplementationAddressConfig {\n L2OutputOracle l2OutputOracleImpl;\n OptimismPortal optimismPortalImpl;\n L1CrossDomainMessenger l1CrossDomainMessengerImpl;\n L1StandardBridge l1StandardBridgeImpl;\n OptimismMintableERC20Factory optimismMintableERC20FactoryImpl;\n L1ERC721Bridge l1ERC721BridgeImpl;\n PortalSender portalSenderImpl;\n SystemConfig systemConfigImpl;\n }\n\n /**\n * @notice Dynamic L2OutputOracle config.\n */\n struct L2OutputOracleDynamicConfig {\n uint256 l2OutputOracleStartingBlockNumber;\n uint256 l2OutputOracleStartingTimestamp;\n }\n\n /**\n * @notice Values for the system config contract.\n */\n struct SystemConfigConfig {\n address owner;\n uint256 overhead;\n uint256 scalar;\n bytes32 batcherHash;\n uint64 gasLimit;\n address unsafeBlockSigner;\n ResourceMetering.ResourceConfig resourceConfig;\n }\n\n /**\n * @notice Combined system configuration.\n */\n struct DeployConfig {\n GlobalConfig globalConfig;\n ProxyAddressConfig proxyAddressConfig;\n ImplementationAddressConfig implementationAddressConfig;\n SystemConfigConfig systemConfigConfig;\n }\n\n /**\n * @notice Step after which exit 1 can no longer be used.\n */\n uint8 public constant EXIT_1_NO_RETURN_STEP = 3;\n\n /**\n * @notice Step where proxy ownership is transferred.\n */\n uint8 public constant PROXY_TRANSFER_STEP = 4;\n\n /**\n * @notice System configuration.\n */\n DeployConfig public config;\n\n /**\n * @notice Dynamic configuration for the L2OutputOracle.\n */\n L2OutputOracleDynamicConfig public l2OutputOracleDynamicConfig;\n\n /**\n * @notice Dynamic configuration for the OptimismPortal. Determines\n * if the system should be paused when initialized.\n */\n bool public optimismPortalDynamicConfig;\n\n /**\n * @notice Current step;\n */\n uint8 public currentStep;\n\n /**\n * @notice Whether or not dynamic config has been set.\n */\n bool public dynamicConfigSet;\n\n /**\n * @notice Whether or not the deployment is finalized.\n */\n bool public finalized;\n\n /**\n * @notice Whether or not the deployment has been exited.\n */\n bool public exited;\n\n /**\n * @notice Address of the old L1CrossDomainMessenger implementation.\n */\n address public oldL1CrossDomainMessenger;\n\n /**\n * @notice Checks that the current step is the expected step, then bumps the current step.\n *\n * @param _step Current step.\n */\n modifier step(uint8 _step) {\n require(!finalized, \"SystemDictator: already finalized\");\n require(!exited, \"SystemDictator: already exited\");\n require(currentStep == _step, \"SystemDictator: incorrect step\");\n _;\n currentStep++;\n }\n\n /**\n * @notice Constructor required to ensure that the implementation of the SystemDictator is\n * initialized upon deployment.\n */\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n // Using this shorter variable as an alias for address(0) just prevents us from having to\n // to use a new line for every single parameter.\n address zero = address(0);\n initialize(\n DeployConfig(\n GlobalConfig(AddressManager(zero), ProxyAdmin(zero), zero, zero),\n ProxyAddressConfig(zero, zero, zero, zero, zero, zero, zero),\n ImplementationAddressConfig(\n L2OutputOracle(zero),\n OptimismPortal(payable(zero)),\n L1CrossDomainMessenger(zero),\n L1StandardBridge(payable(zero)),\n OptimismMintableERC20Factory(zero),\n L1ERC721Bridge(zero),\n PortalSender(zero),\n SystemConfig(zero)\n ),\n SystemConfigConfig(zero, 0, 0, bytes32(0), 0, zero, rcfg)\n )\n );\n }\n\n /**\n * @param _config System configuration.\n */\n function initialize(DeployConfig memory _config) public initializer {\n config = _config;\n currentStep = 1;\n __Ownable_init();\n _transferOwnership(config.globalConfig.controller);\n }\n\n /**\n * @notice Allows the owner to update dynamic config.\n *\n * @param _l2OutputOracleDynamicConfig Dynamic L2OutputOracle config.\n * @param _optimismPortalDynamicConfig Dynamic OptimismPortal config.\n */\n function updateDynamicConfig(\n L2OutputOracleDynamicConfig memory _l2OutputOracleDynamicConfig,\n bool _optimismPortalDynamicConfig\n ) external onlyOwner {\n l2OutputOracleDynamicConfig = _l2OutputOracleDynamicConfig;\n optimismPortalDynamicConfig = _optimismPortalDynamicConfig;\n dynamicConfigSet = true;\n }\n\n /**\n * @notice Configures the ProxyAdmin contract.\n */\n function step1() public onlyOwner step(1) {\n // Set the AddressManager in the ProxyAdmin.\n config.globalConfig.proxyAdmin.setAddressManager(config.globalConfig.addressManager);\n\n // Set the L1CrossDomainMessenger to the RESOLVED proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n ProxyAdmin.ProxyType.RESOLVED\n );\n\n // Set the implementation name for the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.setImplementationName(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Set the L1StandardBridge to the CHUGSPLASH proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1StandardBridgeProxy,\n ProxyAdmin.ProxyType.CHUGSPLASH\n );\n\n // Upgrade and initialize the SystemConfig so the Sequencer can start up.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.systemConfigProxy),\n address(config.implementationAddressConfig.systemConfigImpl),\n abi.encodeCall(\n SystemConfig.initialize,\n (\n config.systemConfigConfig.owner,\n config.systemConfigConfig.overhead,\n config.systemConfigConfig.scalar,\n config.systemConfigConfig.batcherHash,\n config.systemConfigConfig.gasLimit,\n config.systemConfigConfig.unsafeBlockSigner,\n config.systemConfigConfig.resourceConfig\n )\n )\n );\n }\n\n /**\n * @notice Pauses the system by shutting down the L1CrossDomainMessenger and setting the\n * deposit halt flag to tell the Sequencer's DTL to stop accepting deposits.\n */\n function step2() public onlyOwner step(2) {\n // Store the address of the old L1CrossDomainMessenger implementation. We will need this\n // address in the case that we have to exit early.\n oldL1CrossDomainMessenger = config.globalConfig.addressManager.getAddress(\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Temporarily brick the L1CrossDomainMessenger by setting its implementation address to\n // address(0) which will cause the ResolvedDelegateProxy to revert. Better than pausing\n // the L1CrossDomainMessenger via pause() because it can be easily reverted.\n config.globalConfig.addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(0));\n\n // Set the DTL shutoff block, which will tell the DTL to stop syncing new deposits from the\n // CanonicalTransactionChain. We do this by setting an address in the AddressManager\n // because the DTL already has a reference to the AddressManager and this way we don't also\n // need to give it a reference to the SystemDictator.\n config.globalConfig.addressManager.setAddress(\n \"DTL_SHUTOFF_BLOCK\",\n address(uint160(block.number))\n );\n }\n\n /**\n * @notice Removes deprecated addresses from the AddressManager.\n */\n function step3() external onlyOwner step(EXIT_1_NO_RETURN_STEP) {\n // Remove all deprecated addresses from the AddressManager\n string[17] memory deprecated = [\n \"OVM_CanonicalTransactionChain\",\n \"OVM_L2CrossDomainMessenger\",\n \"OVM_DecompressionPrecompileAddress\",\n \"OVM_Sequencer\",\n \"OVM_Proposer\",\n \"OVM_ChainStorageContainer-CTC-batches\",\n \"OVM_ChainStorageContainer-CTC-queue\",\n \"OVM_CanonicalTransactionChain\",\n \"OVM_StateCommitmentChain\",\n \"OVM_BondManager\",\n \"OVM_ExecutionManager\",\n \"OVM_FraudVerifier\",\n \"OVM_StateManagerFactory\",\n \"OVM_StateTransitionerFactory\",\n \"OVM_SafetyChecker\",\n \"OVM_L1MultiMessageRelayer\",\n \"BondManager\"\n ];\n\n for (uint256 i = 0; i < deprecated.length; i++) {\n config.globalConfig.addressManager.setAddress(deprecated[i], address(0));\n }\n }\n\n /**\n * @notice Transfers system ownership to the ProxyAdmin.\n */\n function step4() external onlyOwner step(PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the ProxyAdmin.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1StandardBridge to the ProxyAdmin.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the ProxyAdmin.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.proxyAdmin)\n );\n }\n\n /**\n * @notice Upgrades and initializes proxy contracts.\n */\n function step5() external onlyOwner step(5) {\n // Dynamic config must be set before we can initialize the L2OutputOracle.\n require(dynamicConfigSet, \"SystemDictator: dynamic oracle config is not yet initialized\");\n\n // Upgrade and initialize the L2OutputOracle.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l2OutputOracleProxy),\n address(config.implementationAddressConfig.l2OutputOracleImpl),\n abi.encodeCall(\n L2OutputOracle.initialize,\n (\n l2OutputOracleDynamicConfig.l2OutputOracleStartingBlockNumber,\n l2OutputOracleDynamicConfig.l2OutputOracleStartingTimestamp\n )\n )\n );\n\n // Upgrade and initialize the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.optimismPortalProxy),\n address(config.implementationAddressConfig.optimismPortalImpl),\n abi.encodeCall(OptimismPortal.initialize, (optimismPortalDynamicConfig))\n );\n\n // Upgrade the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1CrossDomainMessengerProxy),\n address(config.implementationAddressConfig.l1CrossDomainMessengerImpl)\n );\n\n // Try to initialize the L1CrossDomainMessenger, only fail if it's already been initialized.\n try\n L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy)\n .initialize()\n {\n // L1CrossDomainMessenger is the one annoying edge case difference between existing\n // networks and fresh networks because in existing networks it'll already be\n // initialized but in fresh networks it won't be. Try/catch is the easiest and most\n // consistent way to handle this because initialized() is not exposed publicly.\n } catch Error(string memory reason) {\n require(\n keccak256(abi.encodePacked(reason)) ==\n keccak256(\"Initializable: contract is already initialized\"),\n string.concat(\"SystemDictator: unexpected error initializing L1XDM: \", reason)\n );\n } catch {\n revert(\"SystemDictator: unexpected error initializing L1XDM (no reason)\");\n }\n\n // Transfer ETH from the L1StandardBridge to the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.portalSenderImpl),\n abi.encodeCall(PortalSender.donate, ())\n );\n\n // Upgrade the L1StandardBridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.l1StandardBridgeImpl)\n );\n\n // Upgrade the OptimismMintableERC20Factory (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.optimismMintableERC20FactoryProxy),\n address(config.implementationAddressConfig.optimismMintableERC20FactoryImpl)\n );\n\n // Upgrade the L1ERC721Bridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1ERC721BridgeProxy),\n address(config.implementationAddressConfig.l1ERC721BridgeImpl)\n );\n }\n\n /**\n * @notice Calls the first 2 steps of the migration process.\n */\n function phase1() external onlyOwner {\n step1();\n step2();\n }\n\n /**\n * @notice Tranfers admin ownership to the final owner.\n */\n function finalize() external onlyOwner {\n // Transfer ownership of the ProxyAdmin to the final owner.\n config.globalConfig.proxyAdmin.transferOwnership(config.globalConfig.finalOwner);\n\n // Optionally also transfer AddressManager and L1StandardBridge if we still own it. Might\n // happen if we're exiting early.\n if (currentStep <= PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the final owner.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1StandardBridge to the final owner.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the final owner.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.finalOwner)\n );\n }\n\n // Mark the deployment as finalized.\n finalized = true;\n }\n\n /**\n * @notice First exit point, can only be called before step 3 is executed.\n */\n function exit1() external onlyOwner {\n require(\n currentStep == EXIT_1_NO_RETURN_STEP,\n \"SystemDictator: can only exit1 before step 3 is executed\"\n );\n\n // Reset the L1CrossDomainMessenger to the old implementation.\n config.globalConfig.addressManager.setAddress(\n \"OVM_L1CrossDomainMessenger\",\n oldL1CrossDomainMessenger\n );\n\n // Unset the DTL shutoff block which will allow the DTL to sync again.\n config.globalConfig.addressManager.setAddress(\"DTL_SHUTOFF_BLOCK\", address(0));\n\n // Mark the deployment as exited.\n exited = true;\n }\n}\n" - }, - "contracts/echidna/FuzzAddressAliasing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract EchidnaFuzzAddressAliasing {\n bool internal failedRoundtrip;\n\n /**\n * @notice Takes an address to be aliased with AddressAliasHelper and then unaliased\n * and updates the test contract's state indicating if the round trip encoding\n * failed.\n */\n function testRoundTrip(address addr) public {\n // Alias our address\n address aliasedAddr = AddressAliasHelper.applyL1ToL2Alias(addr);\n\n // Unalias our address\n address undoneAliasAddr = AddressAliasHelper.undoL1ToL2Alias(aliasedAddr);\n\n // If our round trip aliasing did not return the original result, set our state.\n if (addr != undoneAliasAddr) {\n failedRoundtrip = true;\n }\n }\n\n /**\n * @custom:invariant Address aliases are always able to be undone.\n *\n * Asserts that an address that has been aliased with `applyL1ToL2Alias` can always\n * be unaliased with `undoL1ToL2Alias`.\n */\n function echidna_round_trip_aliasing() public view returns (bool) {\n // ASSERTION: The round trip aliasing done in testRoundTrip(...) should never fail.\n return !failedRoundtrip;\n }\n}\n" - }, - "contracts/echidna/FuzzBurn.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\n\ncontract EchidnaFuzzBurnEth is StdUtils {\n bool internal failedEthBurn;\n\n /**\n * @notice Takes an integer amount of eth to burn through the Burn library and\n * updates the contract state if an incorrect amount of eth moved from the contract\n */\n function testBurn(uint256 _value) public {\n // cache the contract's eth balance\n uint256 preBurnBalance = address(this).balance;\n uint256 value = bound(_value, 0, preBurnBalance);\n\n // execute a burn of _value eth\n Burn.eth(value);\n\n // check that exactly value eth was transfered from the contract\n unchecked {\n if (address(this).balance != preBurnBalance - value) {\n failedEthBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `eth(uint256)` always burns the exact amount of eth passed.\n *\n * Asserts that when `Burn.eth(uint256)` is called, it always burns the exact amount\n * of ETH passed to the function.\n */\n function echidna_burn_eth() public view returns (bool) {\n // ASSERTION: The amount burned should always match the amount passed exactly\n return !failedEthBurn;\n }\n}\n\ncontract EchidnaFuzzBurnGas is StdUtils {\n bool internal failedGasBurn;\n\n /**\n * @notice Takes an integer amount of gas to burn through the Burn library and\n * updates the contract state if at least that amount of gas was not burned\n * by the library\n */\n function testGas(uint256 _value) public {\n // cap the value to the max resource limit\n uint256 MAX_RESOURCE_LIMIT = 8_000_000;\n uint256 value = bound(_value, 0, MAX_RESOURCE_LIMIT);\n\n // cache the contract's current remaining gas\n uint256 preBurnGas = gasleft();\n\n // execute the gas burn\n Burn.gas(value);\n\n // cache the remaining gas post burn\n uint256 postBurnGas = gasleft();\n\n // check that at least value gas was burnt (and that there was no underflow)\n unchecked {\n if (postBurnGas - preBurnGas > value || preBurnGas - value > preBurnGas) {\n failedGasBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `gas(uint256)` always burns at least the amount of gas passed.\n *\n * Asserts that when `Burn.gas(uint256)` is called, it always burns at least the amount\n * of gas passed to the function.\n */\n function echidna_burn_gas() public view returns (bool) {\n // ASSERTION: The amount of gas burned should be strictly greater than the\n // the amount passed as _value (minimum _value + whatever minor overhead to\n // the value after the call)\n return !failedGasBurn;\n }\n}\n" - }, - "contracts/echidna/FuzzEncoding.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzEncoding {\n bool internal failedRoundtripAToB;\n bool internal failedRoundtripBToA;\n\n /**\n * @notice Takes a pair of integers to be encoded into a versioned nonce with the\n * Encoding library and then decoded and updates the test contract's state\n * indicating if the round trip encoding failed.\n */\n function testRoundTripAToB(uint240 _nonce, uint16 _version) public {\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(encodedVersionedNonce);\n\n // If our round trip encoding did not return the original result, set our state.\n if ((decodedNonce != _nonce) || (decodedVersion != _version)) {\n failedRoundtripAToB = true;\n }\n }\n\n /**\n * @notice Takes an integer representing a packed version and nonce and attempts\n * to decode them using the Encoding library before re-encoding and updates\n * the test contract's state indicating if the round trip encoding failed.\n */\n function testRoundTripBToA(uint256 _versionedNonce) public {\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(_versionedNonce);\n\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(decodedNonce, decodedVersion);\n\n // If our round trip encoding did not return the original result, set our state.\n if (encodedVersionedNonce != _versionedNonce) {\n failedRoundtripBToA = true;\n }\n }\n\n /**\n * @custom:invariant `testRoundTripAToB` never fails.\n *\n * Asserts that a raw versioned nonce can be encoded / decoded to reach the same raw value.\n */\n function echidna_round_trip_encoding_AToB() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripAToB(...)\n return !failedRoundtripAToB;\n }\n\n /**\n * @custom:invariant `testRoundTripBToA` never fails.\n *\n * Asserts that an encoded versioned nonce can always be decoded / re-encoded to reach\n * the same encoded value.\n */\n function echidna_round_trip_encoding_BToA() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripBToA should never\n // fail.\n return !failedRoundtripBToA;\n }\n}\n" - }, - "contracts/echidna/FuzzHashing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzHashing {\n bool internal failedCrossDomainHashHighVersion;\n bool internal failedCrossDomainHashV0;\n bool internal failedCrossDomainHashV1;\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash with a randomly\n * generated version. Only schema versions 0 and 1 are supported and all others should revert.\n */\n function testHashCrossDomainMessageHighVersion(\n uint16 _version,\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // hash the cross domain message. we don't need to store the result since the function\n // validates and should revert if an invalid version (>1) is encoded\n Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);\n\n // check that execution never makes it this far for an invalid version\n if (_version > 1) {\n failedCrossDomainHashHighVersion = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v0 schema\n * and compares the output of a call to the unversioned function to the v0 function directly\n */\n function testHashCrossDomainMessageV0(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 0\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 0);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n encodedNonce\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV0 = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v1 schema\n * and compares the output of a call to the unversioned function to the v1 function directly\n */\n function testHashCrossDomainMessageV1(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 1\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 1);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV1 = true;\n }\n }\n\n /**\n * @custom:invariant `hashCrossDomainMessage` reverts if `version` is > `1`.\n *\n * The `hashCrossDomainMessage` function should always revert if the `version` passed is > `1`.\n */\n function echidna_hash_xdomain_msg_high_version() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage will never succeed for a version > 1\n return !failedCrossDomainHashHighVersion;\n }\n\n /**\n * @custom:invariant `version` = `0`: `hashCrossDomainMessage` and `hashCrossDomainMessageV0`\n * are equivalent.\n *\n * If the version passed is 0, `hashCrossDomainMessage` and `hashCrossDomainMessageV0` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_0() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV0\n // should always match when the version passed is 0\n return !failedCrossDomainHashV0;\n }\n\n /**\n * @custom:invariant `version` = `1`: `hashCrossDomainMessage` and `hashCrossDomainMessageV1`\n * are equivalent.\n *\n * If the version passed is 1, `hashCrossDomainMessage` and `hashCrossDomainMessageV1` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_1() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV1\n // should always match when the version passed is 1\n return !failedCrossDomainHashV1;\n }\n}\n" - }, - "contracts/echidna/FuzzOptimismPortal.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzOptimismPortal {\n OptimismPortal internal portal;\n bool internal failedToComplete;\n\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n SystemConfig systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: rcfg\n });\n\n portal = new OptimismPortal({\n _l2Oracle: L2OutputOracle(address(0)),\n _guardian: address(0),\n _paused: false,\n _config: systemConfig\n });\n }\n\n // A test intended to identify any unexpected halting conditions\n function testDepositTransactionCompletes(\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable {\n failedToComplete = true;\n require(!_isCreation || _to == address(0), \"EchidnaFuzzOptimismPortal: invalid test case.\");\n portal.depositTransaction{ value: _mint }(_to, _value, _gasLimit, _isCreation, _data);\n failedToComplete = false;\n }\n\n /**\n * @custom:invariant Deposits of any value should always succeed unless\n * `_to` = `address(0)` or `_isCreation` = `true`.\n *\n * All deposits, barring creation transactions and transactions sent to `address(0)`,\n * should always succeed.\n */\n function echidna_deposit_completes() public view returns (bool) {\n return !failedToComplete;\n }\n}\n" - }, - "contracts/echidna/FuzzResourceMetering.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzResourceMetering is ResourceMetering, StdUtils {\n bool internal failedMaxGasPerBlock;\n bool internal failedRaiseBaseFee;\n bool internal failedLowerBaseFee;\n bool internal failedNeverBelowMinBaseFee;\n bool internal failedMaxRaiseBaseFeePerBlock;\n bool internal failedMaxLowerBaseFeePerBlock;\n\n // Used as a special flag for the purpose of identifying unchecked math errors specifically\n // in the test contracts, not the target contracts themselves.\n bool internal underflow;\n\n constructor() {\n initialize();\n }\n\n function initialize() internal initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public pure returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n return rcfg;\n }\n\n /**\n * @notice Takes the necessary parameters to allow us to burn arbitrary amounts of gas to test\n * the underlying resource metering/gas market logic\n */\n function testBurn(uint256 _gasToBurn, bool _raiseBaseFee) public {\n // Part 1: we cache the current param values and do some basic checks on them.\n uint256 cachedPrevBaseFee = uint256(params.prevBaseFee);\n uint256 cachedPrevBoughtGas = uint256(params.prevBoughtGas);\n uint256 cachedPrevBlockNum = uint256(params.prevBlockNum);\n\n ResourceMetering.ResourceConfig memory rcfg = resourceConfig();\n uint256 targetResourceLimit = uint256(rcfg.maxResourceLimit) /\n uint256(rcfg.elasticityMultiplier);\n\n // check that the last block's base fee hasn't dropped below the minimum\n if (cachedPrevBaseFee < uint256(rcfg.minimumBaseFee)) {\n failedNeverBelowMinBaseFee = true;\n }\n // check that the last block didn't consume more than the max amount of gas\n if (cachedPrevBoughtGas > uint256(rcfg.maxResourceLimit)) {\n failedMaxGasPerBlock = true;\n }\n\n // Part2: we perform the gas burn\n\n // force the gasToBurn into the correct range based on whether we intend to\n // raise or lower the baseFee after this block, respectively\n uint256 gasToBurn;\n if (_raiseBaseFee) {\n gasToBurn = bound(\n _gasToBurn,\n uint256(targetResourceLimit),\n uint256(rcfg.maxResourceLimit)\n );\n } else {\n gasToBurn = bound(_gasToBurn, 0, targetResourceLimit);\n }\n\n _burnInternal(uint64(gasToBurn));\n\n // Part 3: we run checks and modify our invariant flags based on the updated params values\n\n // Calculate the maximum allowed baseFee change (per block)\n uint256 maxBaseFeeChange = cachedPrevBaseFee / uint256(rcfg.baseFeeMaxChangeDenominator);\n\n // If the last block used more than the target amount of gas (and there were no\n // empty blocks in between), ensure this block's baseFee increased, but not by\n // more than the max amount per block\n if (\n (cachedPrevBoughtGas > uint256(targetResourceLimit)) &&\n (uint256(params.prevBlockNum) - cachedPrevBlockNum == 1)\n ) {\n failedRaiseBaseFee = failedRaiseBaseFee || (params.prevBaseFee <= cachedPrevBaseFee);\n failedMaxRaiseBaseFeePerBlock =\n failedMaxRaiseBaseFeePerBlock ||\n ((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);\n }\n\n // If the last block used less than the target amount of gas, (or was empty),\n // ensure that: this block's baseFee was decreased, but not by more than the max amount\n if (\n (cachedPrevBoughtGas < uint256(targetResourceLimit)) ||\n (uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)\n ) {\n // Invariant: baseFee should decrease\n failedLowerBaseFee =\n failedLowerBaseFee ||\n (uint256(params.prevBaseFee) > cachedPrevBaseFee);\n\n if (params.prevBlockNum - cachedPrevBlockNum == 1) {\n // No empty blocks\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n } else if (params.prevBlockNum - cachedPrevBlockNum > 1) {\n // We have at least one empty block\n // Update the maxBaseFeeChange to account for multiple blocks having passed\n unchecked {\n maxBaseFeeChange = uint256(\n int256(cachedPrevBaseFee) -\n Arithmetic.clamp(\n Arithmetic.cdexp(\n int256(cachedPrevBaseFee),\n int256(uint256(rcfg.baseFeeMaxChangeDenominator)),\n int256(uint256(params.prevBlockNum) - cachedPrevBlockNum)\n ),\n int256(uint256(rcfg.minimumBaseFee)),\n int256(uint256(rcfg.maximumBaseFee))\n )\n );\n }\n\n // Detect an underflow in the previous calculation.\n // Without using unchecked above, and detecting the underflow here, echidna would\n // otherwise ignore the revert.\n underflow = underflow || maxBaseFeeChange > cachedPrevBaseFee;\n\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n }\n }\n }\n\n function _burnInternal(uint64 _gasToBurn) private metered(_gasToBurn) {}\n\n /**\n * @custom:invariant The base fee should increase if the last block used more\n * than the target amount of gas\n *\n * If the last block used more than the target amount of gas (and there were no\n * empty blocks in between), ensure this block's baseFee increased, but not by\n * more than the max amount per block.\n */\n function echidna_high_usage_raise_baseFee() public view returns (bool) {\n return !failedRaiseBaseFee;\n }\n\n /**\n * @custom:invariant The base fee should decrease if the last block used less\n * than the target amount of gas\n *\n * If the previous block used less than the target amount of gas, the base fee should decrease,\n * but not more than the max amount.\n */\n function echidna_low_usage_lower_baseFee() public view returns (bool) {\n return !failedLowerBaseFee;\n }\n\n /**\n * @custom:invariant A block's base fee should never be below `MINIMUM_BASE_FEE`\n *\n * This test asserts that a block's base fee can never drop below the\n * `MINIMUM_BASE_FEE` threshold.\n */\n function echidna_never_below_min_baseFee() public view returns (bool) {\n return !failedNeverBelowMinBaseFee;\n }\n\n /**\n * @custom:invariant A block can never consume more than `MAX_RESOURCE_LIMIT` gas.\n *\n * This test asserts that a block can never consume more than the `MAX_RESOURCE_LIMIT`\n * gas threshold.\n */\n function echidna_never_above_max_gas_limit() public view returns (bool) {\n return !failedMaxGasPerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be raised more than the max base fee change.\n *\n * After a block consumes more gas than the target gas, the base fee cannot be raised\n * more than the maximum amount allowed. The max base fee change (per-block) is derived\n * as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_increase() public view returns (bool) {\n return !failedMaxRaiseBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be lowered more than the max base fee change.\n *\n * After a block consumes less than the target gas, the base fee cannot be lowered more\n * than the maximum amount allowed. The max base fee change (per-block) is derived as\n *follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_decrease() public view returns (bool) {\n return !failedMaxLowerBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The `maxBaseFeeChange` calculation over multiple blocks can never\n * underflow.\n *\n * When calculating the `maxBaseFeeChange` after multiple empty blocks, the calculation\n * should never be allowed to underflow.\n */\n function echidna_underflow() public view returns (bool) {\n return !underflow;\n }\n}\n" - }, - "contracts/governance/GovernanceToken.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:predeploy 0x4200000000000000000000000000000000000042\n * @title GovernanceToken\n * @notice The Optimism token used in governance and supporting voting and delegation. Implements\n * EIP 2612 allowing signed approvals. Contract is \"owned\" by a `MintManager` instance with\n * permission to the `mint` function only, for the purposes of enforcing the token inflation\n * schedule.\n */\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\n constructor() ERC20(\"Optimism\", \"OP\") ERC20Permit(\"Optimism\") {}\n\n /**\n * @notice Allows the owner to mint tokens.\n *\n * @param _account The account receiving minted tokens.\n * @param _amount The amount of tokens to mint.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n /**\n * @notice Callback called after a token transfer.\n *\n * @param from The account sending tokens.\n * @param to The account receiving tokens.\n * @param amount The amount of tokens being transfered.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20, ERC20Votes) {\n super._afterTokenTransfer(from, to, amount);\n }\n\n /**\n * @notice Internal mint function.\n *\n * @param to The account receiving minted tokens.\n * @param amount The amount of tokens to mint.\n */\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._mint(to, amount);\n }\n\n /**\n * @notice Internal burn function.\n *\n * @param account The account that tokens will be burned from.\n * @param amount The amount of tokens that will be burned.\n */\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._burn(account, amount);\n }\n}\n" - }, - "contracts/governance/MintManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./GovernanceToken.sol\";\n\n/**\n * @title MintManager\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\n * Contract acts as the token \"mint manager\" with permission to the `mint` function only.\n * Currently permitted to mint once per year of up to 2% of the total token supply.\n * Upgradable to allow changes in the inflation schedule.\n */\ncontract MintManager is Ownable {\n /**\n * @notice The GovernanceToken that the MintManager can mint tokens\n */\n GovernanceToken public immutable governanceToken;\n\n /**\n * @notice The amount of tokens that can be minted per year. The value is a fixed\n * point number with 4 decimals.\n */\n uint256 public constant MINT_CAP = 20; // 2%\n\n /**\n * @notice The number of decimals for the MINT_CAP.\n */\n uint256 public constant DENOMINATOR = 1000;\n\n /**\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\n * be minted again.\n */\n uint256 public constant MINT_PERIOD = 365 days;\n\n /**\n * @notice Tracks the time of last mint.\n */\n uint256 public mintPermittedAfter;\n\n /**\n * @param _upgrader The owner of this contract\n * @param _governanceToken The governance token this contract can mint\n * tokens of\n */\n constructor(address _upgrader, address _governanceToken) {\n transferOwnership(_upgrader);\n governanceToken = GovernanceToken(_governanceToken);\n }\n\n /**\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\n *\n * @param _account Address to mint new tokens to.\n * @param _amount Amount of tokens to be minted.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n if (mintPermittedAfter > 0) {\n require(\n mintPermittedAfter <= block.timestamp,\n \"MintManager: minting not permitted yet\"\n );\n\n require(\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\n \"MintManager: mint amount exceeds cap\"\n );\n }\n\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\n governanceToken.mint(_account, _amount);\n }\n\n /**\n * @notice Upgrade the owner of the governance token to a new MintManager.\n *\n * @param _newMintManager The MintManager to upgrade to.\n */\n function upgrade(address _newMintManager) public onlyOwner {\n require(\n _newMintManager != address(0),\n \"MintManager: mint manager cannot be the zero address\"\n );\n\n governanceToken.transferOwnership(_newMintManager);\n }\n}\n" - }, - "contracts/legacy/AddressManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:legacy\n * @title AddressManager\n * @notice AddressManager is a legacy contract that was used in the old version of the Optimism\n * system to manage a registry of string names to addresses. We now use a more standard\n * proxy system instead, but this contract is still necessary for backwards compatibility\n * with several older contracts.\n */\ncontract AddressManager is Ownable {\n /**\n * @notice Mapping of the hashes of string names to addresses.\n */\n mapping(bytes32 => address) private addresses;\n\n /**\n * @notice Emitted when an address is modified in the registry.\n *\n * @param name String name being set in the registry.\n * @param newAddress Address set for the given name.\n * @param oldAddress Address that was previously set for the given name.\n */\n event AddressSet(string indexed name, address newAddress, address oldAddress);\n\n /**\n * @notice Changes the address associated with a particular name.\n *\n * @param _name String name to associate an address with.\n * @param _address Address to associate with the name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n bytes32 nameHash = _getNameHash(_name);\n address oldAddress = addresses[nameHash];\n addresses[nameHash] = _address;\n\n emit AddressSet(_name, _address, oldAddress);\n }\n\n /**\n * @notice Retrieves the address associated with a given name.\n *\n * @param _name Name to retrieve an address for.\n *\n * @return Address associated with the given name.\n */\n function getAddress(string memory _name) external view returns (address) {\n return addresses[_getNameHash(_name)];\n }\n\n /**\n * @notice Computes the hash of a name.\n *\n * @param _name Name to compute a hash for.\n *\n * @return Hash of the given name.\n */\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(_name));\n }\n}\n" - }, - "contracts/legacy/DeployerWhitelist.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000002\n * @title DeployerWhitelist\n * @notice DeployerWhitelist is a legacy contract that was originally used to act as a whitelist of\n * addresses allowed to the Optimism network. The DeployerWhitelist has since been\n * disabled, but the code is kept in state for the sake of full backwards compatibility.\n * As of the Bedrock upgrade, the DeployerWhitelist is completely unused by the Optimism\n * system and could, in theory, be removed entirely.\n */\ncontract DeployerWhitelist is Semver {\n /**\n * @notice Address of the owner of this contract. Note that when this address is set to\n * address(0), the whitelist is disabled.\n */\n address public owner;\n\n /**\n * @notice Mapping of deployer addresses to boolean whitelist status.\n */\n mapping(address => bool) public whitelist;\n\n /**\n * @notice Emitted when the owner of this contract changes.\n *\n * @param oldOwner Address of the previous owner.\n * @param newOwner Address of the new owner.\n */\n event OwnerChanged(address oldOwner, address newOwner);\n\n /**\n * @notice Emitted when the whitelist status of a deployer changes.\n *\n * @param deployer Address of the deployer.\n * @param whitelisted Boolean indicating whether the deployer is whitelisted.\n */\n event WhitelistStatusChanged(address deployer, bool whitelisted);\n\n /**\n * @notice Emitted when the whitelist is disabled.\n *\n * @param oldOwner Address of the final owner of the whitelist.\n */\n event WhitelistDisabled(address oldOwner);\n\n /**\n * @notice Blocks functions to anyone except the contract owner.\n */\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"DeployerWhitelist: function can only be called by the owner of this contract\"\n );\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Adds or removes an address from the deployment whitelist.\n *\n * @param _deployer Address to update permissions for.\n * @param _isWhitelisted Whether or not the address is whitelisted.\n */\n function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external onlyOwner {\n whitelist[_deployer] = _isWhitelisted;\n emit WhitelistStatusChanged(_deployer, _isWhitelisted);\n }\n\n /**\n * @notice Updates the owner of this contract.\n *\n * @param _owner Address of the new owner.\n */\n function setOwner(address _owner) external onlyOwner {\n // Prevent users from setting the whitelist owner to address(0) except via\n // enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to\n // any other address that doesn't have a corresponding knowable private key.\n require(\n _owner != address(0),\n \"DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment\"\n );\n\n emit OwnerChanged(owner, _owner);\n owner = _owner;\n }\n\n /**\n * @notice Permanently enables arbitrary contract deployment and deletes the owner.\n */\n function enableArbitraryContractDeployment() external onlyOwner {\n emit WhitelistDisabled(owner);\n owner = address(0);\n }\n\n /**\n * @notice Checks whether an address is allowed to deploy contracts.\n *\n * @param _deployer Address to check.\n *\n * @return Whether or not the address can deploy contracts.\n */\n function isDeployerAllowed(address _deployer) external view returns (bool) {\n return (owner == address(0) || whitelist[_deployer]);\n }\n}\n" - }, - "contracts/legacy/L1BlockNumber.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000013\n * @title L1BlockNumber\n * @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract\n * in the old version of the Optimism system. Only necessary for backwards compatibility.\n * If you want to access the L1 block number going forward, you should use the L1Block\n * contract instead.\n */\ncontract L1BlockNumber is Semver {\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Returns the L1 block number.\n */\n receive() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Returns the L1 block number.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Retrieves the latest L1 block number.\n *\n * @return Latest L1 block number.\n */\n function getL1BlockNumber() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).number();\n }\n}\n" - }, - "contracts/legacy/L1ChugSplashProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title IL1ChugSplashDeployer\n */\ninterface IL1ChugSplashDeployer {\n function isUpgrading() external view returns (bool);\n}\n\n/**\n * @custom:legacy\n * @title L1ChugSplashProxy\n * @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\n * functions `setCode` and `setStorage` for changing the code or storage of the contract.\n *\n * Note for future developers: do NOT make anything in this contract 'public' unless you\n * know what you're doing. Anything public can potentially have a function signature that\n * conflicts with a signature attached to the implementation contract. Public functions\n * SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good\n * reason not to have that modifier. And there almost certainly is not a good reason to not\n * have that modifier. Beware!\n */\ncontract L1ChugSplashProxy {\n /**\n * @notice \"Magic\" prefix. When prepended to some arbitrary bytecode and used to create a\n * contract, the appended bytecode will be deployed as given.\n */\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice Blocks a function from being called when the parent signals that the system should\n * be paused via an isUpgrading function.\n */\n modifier onlyWhenNotPaused() {\n address owner = _getOwner();\n\n // We do a low-level call because there's no guarantee that the owner actually *is* an\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\n // it turns out that it isn't the right type of contract.\n (bool success, bytes memory returndata) = owner.staticcall(\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)\n );\n\n // If the call was unsuccessful then we assume that there's no \"isUpgrading\" method and we\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\n // long. If this isn't the case then we can safely ignore the result.\n if (success && returndata.length == 32) {\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\n // case that the isUpgrading function returned something other than 0 or 1. But we only\n // really care about the case where this value is 0 (= false).\n uint256 ret = abi.decode(returndata, (uint256));\n require(ret == 0, \"L1ChugSplashProxy: system is currently being upgraded\");\n }\n\n _;\n }\n\n /**\n * @notice Makes a proxy call instead of triggering the given function when the caller is\n * either the owner or the zero address. Caller can only ever be the zero address if\n * this function is being called off-chain via eth_call, which is totally fine and can\n * be convenient for client-side tooling. Avoids situations where the proxy and\n * implementation share a sighash and the proxy function ends up being called instead\n * of the implementation one.\n *\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If\n * there's a way for someone to send a transaction with msg.sender == address(0) in any\n * real context then we have much bigger problems. Primary reason to include this\n * additional allowed sender is because the owner address can be changed dynamically\n * and we do not want clients to have to keep track of the current owner in order to\n * make an eth_call that doesn't trigger the proxied contract.\n */\n // slither-disable-next-line incorrect-modifier\n modifier proxyCallIfNotOwner() {\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @param _owner Address of the initial contract owner.\n */\n constructor(address _owner) {\n _setOwner(_owner);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Sets the code that should be running behind this proxy.\n *\n * Note: This scheme is a bit different from the standard proxy scheme where one would\n * typically deploy the code separately and then set the implementation address. We're\n * doing it this way because it gives us a lot more freedom on the client side. Can\n * only be triggered by the contract owner.\n *\n * @param _code New contract code to run inside this contract.\n */\n function setCode(bytes memory _code) external proxyCallIfNotOwner {\n // Get the code hash of the current implementation.\n address implementation = _getImplementation();\n\n // If the code hash matches the new implementation then we return early.\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\n return;\n }\n\n // Create the deploycode by appending the magic prefix.\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\n\n // Deploy the code and set the new implementation address.\n address newImplementation;\n assembly {\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\n }\n\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\n // actually fail this check. Should only happen if the contract creation from above runs\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\n // should be doing this check anyway though.\n require(\n _getAccountCodeHash(newImplementation) == keccak256(_code),\n \"L1ChugSplashProxy: code was not correctly deployed\"\n );\n\n _setImplementation(newImplementation);\n }\n\n /**\n * @notice Modifies some storage slot within the proxy contract. Gives us a lot of power to\n * perform upgrades in a more transparent way. Only callable by the owner.\n *\n * @param _key Storage key to modify.\n * @param _value New value for the storage key.\n */\n function setStorage(bytes32 _key, bytes32 _value) external proxyCallIfNotOwner {\n assembly {\n sstore(_key, _value)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _owner New owner of the proxy contract.\n */\n function setOwner(address _owner) external proxyCallIfNotOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Queries the owner of the proxy contract. Can only be called by the owner OR by\n * making an eth_call and setting the \"from\" address to address(0).\n *\n * @return Owner address.\n */\n function getOwner() external proxyCallIfNotOwner returns (address) {\n return _getOwner();\n }\n\n /**\n * @notice Queries the implementation address. Can only be called by the owner OR by making an\n * eth_call and setting the \"from\" address to address(0).\n *\n * @return Implementation address.\n */\n function getImplementation() external proxyCallIfNotOwner returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _owner New owner of the proxy contract.\n */\n function _setOwner(address _owner) internal {\n assembly {\n sstore(OWNER_KEY, _owner)\n }\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal onlyWhenNotPaused {\n address implementation = _getImplementation();\n\n require(implementation != address(0), \"L1ChugSplashProxy: implementation is not set yet\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address implementation;\n assembly {\n implementation := sload(IMPLEMENTATION_KEY)\n }\n return implementation;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getOwner() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n\n /**\n * @notice Gets the code hash for a given account.\n *\n * @param _account Address of the account to get a code hash for.\n *\n * @return Code hash for the account.\n */\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\n bytes32 codeHash;\n assembly {\n codeHash := extcodehash(_account)\n }\n return codeHash;\n }\n}\n" - }, - "contracts/legacy/LegacyERC20ETH.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000\n * @title LegacyERC20ETH\n * @notice LegacyERC20ETH is a legacy contract that held ETH balances before the Bedrock upgrade.\n * All ETH balances held within this contract were migrated to the state trie as part of\n * the Bedrock upgrade. Functions within this contract that mutate state were already\n * disabled as part of the EVM equivalence upgrade.\n */\ncontract LegacyERC20ETH is OptimismMintableERC20 {\n /**\n * @notice Initializes the contract as an Optimism Mintable ERC20.\n */\n constructor()\n OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), \"Ether\", \"ETH\")\n {}\n\n /**\n * @notice Returns the ETH balance of the target account. Overrides the base behavior of the\n * contract to preserve the invariant that the balance within this contract always\n * matches the balance in the state trie.\n *\n * @param _who Address of the account to query.\n *\n * @return The ETH balance of the target account.\n */\n function balanceOf(address _who) public view virtual override returns (uint256) {\n return address(_who).balance;\n }\n\n /**\n * @custom:blocked\n * @notice Mints some amount of ETH.\n */\n function mint(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: mint is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Burns some amount of ETH.\n */\n function burn(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: burn is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers some amount of ETH.\n */\n function transfer(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transfer is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Approves a spender to spend some amount of ETH.\n */\n function approve(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: approve is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers funds from some sender account.\n */\n function transferFrom(\n address,\n address,\n uint256\n ) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transferFrom is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Increases the allowance of a spender.\n */\n function increaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Decreases the allowance of a spender.\n */\n function decreaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n }\n}\n" - }, - "contracts/legacy/LegacyMessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000000\n * @title LegacyMessagePasser\n * @notice The LegacyMessagePasser was the low-level mechanism used to send messages from L2 to L1\n * before the Bedrock upgrade. It is now deprecated in favor of the new MessagePasser.\n */\ncontract LegacyMessagePasser is Semver {\n /**\n * @notice Mapping of sent message hashes to boolean status.\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Passes a message to L1.\n *\n * @param _message Message to pass to L1.\n */\n function passMessageToL1(bytes memory _message) external {\n sentMessages[keccak256(abi.encodePacked(_message, msg.sender))] = true;\n }\n}\n" - }, - "contracts/legacy/LegacyMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ILegacyMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @title LegacyMintableERC20\n * @notice The legacy implementation of the OptimismMintableERC20. This\n * contract is deprecated and should no longer be used.\n */\ncontract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {\n /**\n * @notice Emitted when the token is minted by the bridge.\n */\n event Mint(address indexed _account, uint256 _amount);\n\n /**\n * @notice Emitted when a token is burned by the bridge.\n */\n event Burn(address indexed _account, uint256 _amount);\n\n /**\n * @notice The token on the remote domain.\n */\n address public l1Token;\n\n /**\n * @notice The local bridge.\n */\n address public l2Bridge;\n\n /**\n * @param _l2Bridge Address of the L2 standard bridge.\n * @param _l1Token Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _l2Bridge,\n address _l1Token,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) {\n l1Token = _l1Token;\n l2Bridge = _l2Bridge;\n }\n\n /**\n * @notice Modifier that requires the contract was called by the bridge.\n */\n modifier onlyL2Bridge() {\n require(msg.sender == l2Bridge, \"Only L2 Bridge can mint and burn\");\n _;\n }\n\n /**\n * @notice EIP165 implementation.\n */\n function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n\n /**\n * @notice Only the bridge can mint tokens.\n * @param _to The account receiving tokens.\n * @param _amount The amount of tokens to receive.\n */\n function mint(address _to, uint256 _amount) public virtual onlyL2Bridge {\n _mint(_to, _amount);\n\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Only the bridge can burn tokens.\n * @param _from The account having tokens burnt.\n * @param _amount The amount of tokens being burnt.\n */\n function burn(address _from, uint256 _amount) public virtual onlyL2Bridge {\n _burn(_from, _amount);\n\n emit Burn(_from, _amount);\n }\n}\n" - }, - "contracts/legacy/ResolvedDelegateProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressManager } from \"./AddressManager.sol\";\n\n/**\n * @custom:legacy\n * @title ResolvedDelegateProxy\n * @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to\n * resolve the implementation address. We're maintaining this contract for backwards\n * compatibility so we can manage all legacy proxies where necessary.\n */\ncontract ResolvedDelegateProxy {\n /**\n * @notice Mapping used to store the implementation name that corresponds to this contract. A\n * mapping was originally used as a way to bypass the same issue normally solved by\n * storing the implementation address in a specific storage slot that does not conflict\n * with any other storage slot. Generally NOT a safe solution but works as long as the\n * implementation does not also keep a mapping in the first storage slot.\n */\n mapping(address => string) private implementationName;\n\n /**\n * @notice Mapping used to store the address of the AddressManager contract where the\n * implementation address will be resolved from. Same concept here as with the above\n * mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping\n * in the second storage slot.\n */\n mapping(address => AddressManager) private addressManager;\n\n /**\n * @param _addressManager Address of the AddressManager.\n * @param _implementationName implementationName of the contract to proxy to.\n */\n constructor(AddressManager _addressManager, string memory _implementationName) {\n addressManager[address(this)] = _addressManager;\n implementationName[address(this)] = _implementationName;\n }\n\n /**\n * @notice Fallback, performs a delegatecall to the resolved implementation address.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n address target = addressManager[address(this)].getAddress(\n (implementationName[address(this)])\n );\n\n require(target != address(0), \"ResolvedDelegateProxy: target address must be initialized\");\n\n // slither-disable-next-line controlled-delegatecall\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\n\n if (success == true) {\n assembly {\n return(add(returndata, 0x20), mload(returndata))\n }\n } else {\n assembly {\n revert(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n" - }, - "contracts/libraries/Arithmetic.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { SignedMath } from \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport { FixedPointMathLib } from \"@rari-capital/solmate/src/utils/FixedPointMathLib.sol\";\n\n/**\n * @title Arithmetic\n * @notice Even more math than before.\n */\nlibrary Arithmetic {\n /**\n * @notice Clamps a value between a minimum and maximum.\n *\n * @param _value The value to clamp.\n * @param _min The minimum value.\n * @param _max The maximum value.\n *\n * @return The clamped value.\n */\n function clamp(\n int256 _value,\n int256 _min,\n int256 _max\n ) internal pure returns (int256) {\n return SignedMath.min(SignedMath.max(_value, _min), _max);\n }\n\n /**\n * @notice (c)oefficient (d)enominator (exp)onentiation function.\n * Returns the result of: c * (1 - 1/d)^exp.\n *\n * @param _coefficient Coefficient of the function.\n * @param _denominator Fractional denominator.\n * @param _exponent Power function exponent.\n *\n * @return Result of c * (1 - 1/d)^exp.\n */\n function cdexp(\n int256 _coefficient,\n int256 _denominator,\n int256 _exponent\n ) internal pure returns (int256) {\n return\n (_coefficient *\n (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;\n }\n}\n" - }, - "contracts/libraries/Burn.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Burn\n * @notice Utilities for burning stuff.\n */\nlibrary Burn {\n /**\n * Burns a given amount of ETH.\n *\n * @param _amount Amount of ETH to burn.\n */\n function eth(uint256 _amount) internal {\n new Burner{ value: _amount }();\n }\n\n /**\n * Burns a given amount of gas.\n *\n * @param _amount Amount of gas to burn.\n */\n function gas(uint256 _amount) internal view {\n uint256 i = 0;\n uint256 initialGas = gasleft();\n while (initialGas - gasleft() < _amount) {\n ++i;\n }\n }\n}\n\n/**\n * @title Burner\n * @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to\n * the contract from the circulating supply. Self-destructing is the only way to remove ETH\n * from the circulating supply.\n */\ncontract Burner {\n constructor() payable {\n selfdestruct(payable(address(this)));\n }\n}\n" - }, - "contracts/libraries/Bytes.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Bytes\n * @notice Bytes is a library for manipulating byte arrays.\n */\nlibrary Bytes {\n /**\n * @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\n * @notice Slices a byte array with a given starting index and length. Returns a new byte array\n * as opposed to a pointer to the original array. Will throw if trying to slice more\n * bytes than exist in the array.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n * @param _length Length of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n ) internal pure returns (bytes memory) {\n unchecked {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_start + _length >= _start, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n }\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n /**\n * @notice Slices a byte array with a given starting index up to the end of the original byte\n * array. Returns a new array rathern than a pointer to the original.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\n if (_start >= _bytes.length) {\n return bytes(\"\");\n }\n return slice(_bytes, _start, _bytes.length - _start);\n }\n\n /**\n * @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.\n * Resulting nibble array will be exactly twice as long as the input byte array.\n *\n * @param _bytes Input byte array to convert.\n *\n * @return Resulting nibble array.\n */\n function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n uint256 bytesLength = _bytes.length;\n bytes memory nibbles = new bytes(bytesLength * 2);\n bytes1 b;\n\n for (uint256 i = 0; i < bytesLength; ) {\n b = _bytes[i];\n nibbles[i * 2] = b >> 4;\n nibbles[i * 2 + 1] = b & 0x0f;\n unchecked {\n ++i;\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Compares two byte arrays by comparing their keccak256 hashes.\n *\n * @param _bytes First byte array to compare.\n * @param _other Second byte array to compare.\n *\n * @return True if the two byte arrays are equal, false otherwise.\n */\n function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n return keccak256(_bytes) == keccak256(_other);\n }\n}\n" - }, - "contracts/libraries/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n/**\n * @title Constants\n * @notice Constants is a library for storing constants. Simple! Don't put everything in here, just\n * the stuff used in multiple contracts. Constants that only apply to a single contract\n * should be defined in that contract instead.\n */\nlibrary Constants {\n /**\n * @notice Special address to be used as the tx origin for gas estimation calls in the\n * OptimismPortal and CrossDomainMessenger calls. You only need to use this address if\n * the minimum gas limit specified by the user is not actually enough to execute the\n * given message and you're attempting to estimate the actual necessary gas limit. We\n * use address(1) because it's the ecrecover precompile and therefore guaranteed to\n * never have any code on any EVM chain.\n */\n address internal constant ESTIMATION_ADDRESS = address(1);\n\n /**\n * @notice Value used for the L2 sender storage slot in both the OptimismPortal and the\n * CrossDomainMessenger contracts before an actual sender is set. This value is\n * non-zero to reduce the gas cost of message passing transactions.\n */\n address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;\n\n /**\n * @notice Returns the default values for the ResourceConfig. These are the recommended values\n * for a production network.\n */\n function DEFAULT_RESOURCE_CONFIG()\n internal\n pure\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n return config;\n }\n}\n" - }, - "contracts/libraries/Encoding.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Hashing } from \"./Hashing.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\n\n/**\n * @title Encoding\n * @notice Encoding handles Optimism's various different encoding schemes.\n */\nlibrary Encoding {\n /**\n * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\n * to the L2 system. Useful for searching for a deposit in the L2 system. The\n * transaction is prefixed with 0x7e to identify its EIP-2718 type.\n *\n * @param _tx User deposit transaction to encode.\n *\n * @return RLP encoded L2 deposit transaction.\n */\n function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes memory)\n {\n bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\n bytes[] memory raw = new bytes[](8);\n raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\n raw[1] = RLPWriter.writeAddress(_tx.from);\n raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\"\") : RLPWriter.writeAddress(_tx.to);\n raw[3] = RLPWriter.writeUint(_tx.mint);\n raw[4] = RLPWriter.writeUint(_tx.value);\n raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\n raw[6] = RLPWriter.writeBool(false);\n raw[7] = RLPWriter.writeBytes(_tx.data);\n return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\n }\n\n /**\n * @notice Encodes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n (, uint16 version) = decodeVersionedNonce(_nonce);\n if (version == 0) {\n return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Encoding: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Encodes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _data,\n _nonce\n );\n }\n\n /**\n * @notice Encodes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(uint256,address,address,uint256,uint256,bytes)\",\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n }\n\n /**\n * @notice Adds a version number into the first two bytes of a message nonce.\n *\n * @param _nonce Message nonce to encode into.\n * @param _version Version number to encode into the message nonce.\n *\n * @return Message nonce with version encoded into the first two bytes.\n */\n function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\n uint256 nonce;\n assembly {\n nonce := or(shl(240, _version), _nonce)\n }\n return nonce;\n }\n\n /**\n * @notice Pulls the version out of a version-encoded nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n *\n * @return Nonce without encoded version.\n * @return Version of the message.\n */\n function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\n uint240 nonce;\n uint16 version;\n assembly {\n nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n version := shr(240, _nonce)\n }\n return (nonce, version);\n }\n}\n" - }, - "contracts/libraries/Hashing.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Encoding } from \"./Encoding.sol\";\n\n/**\n * @title Hashing\n * @notice Hashing handles Optimism's various different hashing schemes.\n */\nlibrary Hashing {\n /**\n * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\n * given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\n * system.\n *\n * @param _tx User deposit transaction to hash.\n *\n * @return Hash of the RLP encoded L2 deposit transaction.\n */\n function hashDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return keccak256(Encoding.encodeDepositTransaction(_tx));\n }\n\n /**\n * @notice Computes the deposit transaction's \"source hash\", a value that guarantees the hash\n * of the L2 transaction that corresponds to a deposit is unique and is\n * deterministically generated from L1 transaction data.\n *\n * @param _l1BlockHash Hash of the L1 block where the deposit was included.\n * @param _logIndex The index of the log that created the deposit transaction.\n *\n * @return Hash of the deposit transaction's \"source hash\".\n */\n function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)\n internal\n pure\n returns (bytes32)\n {\n bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\n return keccak256(abi.encode(bytes32(0), depositId));\n }\n\n /**\n * @notice Hashes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n if (version == 0) {\n return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Hashing: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Hashes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes32) {\n return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));\n }\n\n /**\n * @notice Hashes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n return\n keccak256(\n Encoding.encodeCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n )\n );\n }\n\n /**\n * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\n *\n * @param _tx Withdrawal transaction to hash.\n *\n * @return Hashed withdrawal transaction.\n */\n function hashWithdrawal(Types.WithdrawalTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\n );\n }\n\n /**\n * @notice Hashes the various elements of an output root proof into an output root hash which\n * can be used to check if the proof is valid.\n *\n * @param _outputRootProof Output root proof which should hash to an output root.\n *\n * @return Hashed output root proof.\n */\n function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(\n _outputRootProof.version,\n _outputRootProof.stateRoot,\n _outputRootProof.messagePasserStorageRoot,\n _outputRootProof.latestBlockhash\n )\n );\n }\n}\n" - }, - "contracts/libraries/LegacyCrossDomainUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n// Importing from the legacy contracts package causes issues with the build of the contract bindings\n// so we just copy the library here from\n// /packages/contracts/contracts/libraries/bridge/Lib_CrossDomainUtils.sol at commit\n// 7866168c\n/**\n * @title LegacyCrossDomainUtils\n */\nlibrary LegacyCrossDomainUtils {\n /**\n * Generates the correct cross domain calldata for a message.\n * @param _target Target contract address.\n * @param _sender Message sender address.\n * @param _message Message to send to the target.\n * @param _messageNonce Nonce for the provided message.\n * @return ABI encoded cross domain calldata.\n */\n function encodeXDomainCalldata(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _message,\n _messageNonce\n );\n }\n}\n" - }, - "contracts/libraries/Predeploys.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Predeploys\n * @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.\n */\nlibrary Predeploys {\n /**\n * @notice Address of the L2ToL1MessagePasser predeploy.\n */\n address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;\n\n /**\n * @notice Address of the L2CrossDomainMessenger predeploy.\n */\n address internal constant L2_CROSS_DOMAIN_MESSENGER =\n 0x4200000000000000000000000000000000000007;\n\n /**\n * @notice Address of the L2StandardBridge predeploy.\n */\n address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\n\n /**\n * @notice Address of the L2ERC721Bridge predeploy.\n */\n address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;\n\n /**\n * @notice Address of the SequencerFeeWallet predeploy.\n */\n address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;\n\n /**\n * @notice Address of the OptimismMintableERC20Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY =\n 0x4200000000000000000000000000000000000012;\n\n /**\n * @notice Address of the OptimismMintableERC721Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY =\n 0x4200000000000000000000000000000000000017;\n\n /**\n * @notice Address of the L1Block predeploy.\n */\n address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;\n\n /**\n * @notice Address of the GasPriceOracle predeploy. Includes fee information\n * and helpers for computing the L1 portion of the transaction fee.\n */\n address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;\n\n /**\n * @custom:legacy\n * @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger\n * or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.\n */\n address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\n\n /**\n * @custom:legacy\n * @notice Address of the DeployerWhitelist predeploy. No longer active.\n */\n address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the\n * state trie as of the Bedrock upgrade. Contract has been locked and write functions\n * can no longer be accessed.\n */\n address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;\n\n /**\n * @custom:legacy\n * @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy\n * instead, which exposes more information about the L1 state.\n */\n address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated\n * L2ToL1MessagePasser contract instead.\n */\n address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\n\n /**\n * @notice Address of the ProxyAdmin predeploy.\n */\n address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;\n\n /**\n * @notice Address of the BaseFeeVault predeploy.\n */\n address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;\n\n /**\n * @notice Address of the L1FeeVault predeploy.\n */\n address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;\n\n /**\n * @notice Address of the GovernanceToken predeploy.\n */\n address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042;\n}\n" - }, - "contracts/libraries/SafeCall.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title SafeCall\n * @notice Perform low level safe calls\n */\nlibrary SafeCall {\n /**\n * @notice Perform a low level call without copying any returndata\n *\n * @param _target Address to call\n * @param _gas Amount of gas to pass to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function call(\n address _target,\n uint256 _gas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n }\n return _success;\n }\n\n /**\n * @notice Helper function to determine if there is sufficient gas remaining within the context\n * to guarantee that the minimum gas requirement for a call will be met as well as\n * optionally reserving a specified amount of gas for after the call has concluded.\n * @param _minGas The minimum amount of gas that may be passed to the target context.\n * @param _reservedGas Optional amount of gas to reserve for the caller after the execution\n * of the target context.\n * @return `true` if there is enough gas remaining to safely supply `_minGas` to the target\n * context as well as reserve `_reservedGas` for the caller after the execution of\n * the target context.\n * @dev !!!!! FOOTGUN ALERT !!!!!\n * 1.) The 40_000 base buffer is to account for the worst case of the dynamic cost of the\n * `CALL` opcode's `address_access_cost`, `positive_value_cost`, and\n * `value_to_empty_account_cost` factors with an added buffer of 5,700 gas. It is\n * still possible to self-rekt by initiating a withdrawal with a minimum gas limit\n * that does not account for the `memory_expansion_cost` & `code_execution_cost`\n * factors of the dynamic cost of the `CALL` opcode.\n * 2.) This function should *directly* precede the external call if possible. There is an\n * added buffer to account for gas consumed between this check and the call, but it\n * is only 5,700 gas.\n * 3.) Because EIP-150 ensures that a maximum of 63/64ths of the remaining gas in the call\n * frame may be passed to a subcontext, we need to ensure that the gas will not be\n * truncated.\n * 4.) Use wisely. This function is not a silver bullet.\n */\n function hasMinGas(uint256 _minGas, uint256 _reservedGas) internal view returns (bool) {\n bool _hasMinGas;\n assembly {\n // Equation: gas × 63 ≥ minGas × 64 + 63(40_000 + reservedGas)\n _hasMinGas := iszero(\n lt(mul(gas(), 63), add(mul(_minGas, 64), mul(add(40000, _reservedGas), 63)))\n )\n }\n return _hasMinGas;\n }\n\n /**\n * @notice Perform a low level call without copying any returndata. This function\n * will revert if the call cannot be performed with the specified minimum\n * gas.\n *\n * @param _target Address to call\n * @param _minGas The minimum amount of gas that may be passed to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function callWithMinGas(\n address _target,\n uint256 _minGas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n bool _hasMinGas = hasMinGas(_minGas, 0);\n assembly {\n // Assertion: gasleft() >= (_minGas * 64) / 63 + 40_000\n if iszero(_hasMinGas) {\n // Store the \"Error(string)\" selector in scratch space.\n mstore(0, 0x08c379a0)\n // Store the pointer to the string length in scratch space.\n mstore(32, 32)\n // Store the string.\n //\n // SAFETY:\n // - We pad the beginning of the string with two zero bytes as well as the\n // length (24) to ensure that we override the free memory pointer at offset\n // 0x40. This is necessary because the free memory pointer is likely to\n // be greater than 1 byte when this function is called, but it is incredibly\n // unlikely that it will be greater than 3 bytes. As for the data within\n // 0x60, it is ensured that it is 0 due to 0x60 being the zero offset.\n // - It's fine to clobber the free memory pointer, we're reverting.\n mstore(88, 0x0000185361666543616c6c3a204e6f7420656e6f75676820676173)\n\n // Revert with 'Error(\"SafeCall: Not enough gas\")'\n revert(28, 100)\n }\n\n // The call will be supplied at least ((_minGas * 64) / 63) gas due to the\n // above assertion. This ensures that, in all circumstances (except for when the\n // `_minGas` does not account for the `memory_expansion_cost` and `code_execution_cost`\n // factors of the dynamic cost of the `CALL` opcode), the call will receive at least\n // the minimum amount of gas specified.\n _success := call(\n gas(), // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0x00, // outloc\n 0x00 // outlen\n )\n }\n return _success;\n }\n}\n" - }, - "contracts/libraries/Types.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Types\n * @notice Contains various types used throughout the Optimism contract system.\n */\nlibrary Types {\n /**\n * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\n * timestamp that the output root is posted. This timestamp is used to verify that the\n * finalization period has passed since the output root was submitted.\n *\n * @custom:field outputRoot Hash of the L2 output.\n * @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.\n * @custom:field l2BlockNumber L2 block number that the output corresponds to.\n */\n struct OutputProposal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2BlockNumber;\n }\n\n /**\n * @notice Struct representing the elements that are hashed together to generate an output root\n * which itself represents a snapshot of the L2 state.\n *\n * @custom:field version Version of the output root.\n * @custom:field stateRoot Root of the state trie at the block of this output.\n * @custom:field messagePasserStorageRoot Root of the message passer storage trie.\n * @custom:field latestBlockhash Hash of the block this output was generated from.\n */\n struct OutputRootProof {\n bytes32 version;\n bytes32 stateRoot;\n bytes32 messagePasserStorageRoot;\n bytes32 latestBlockhash;\n }\n\n /**\n * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n * user (as opposed to a system deposit transaction generated by the system).\n *\n * @custom:field from Address of the sender of the transaction.\n * @custom:field to Address of the recipient of the transaction.\n * @custom:field isCreation True if the transaction is a contract creation.\n * @custom:field value Value to send to the recipient.\n * @custom:field mint Amount of ETH to mint.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n * @custom:field l1BlockHash Hash of the block the transaction was submitted in.\n * @custom:field logIndex Index of the log in the block the transaction was submitted in.\n */\n struct UserDepositTransaction {\n address from;\n address to;\n bool isCreation;\n uint256 value;\n uint256 mint;\n uint64 gasLimit;\n bytes data;\n bytes32 l1BlockHash;\n uint256 logIndex;\n }\n\n /**\n * @notice Struct representing a withdrawal transaction.\n *\n * @custom:field nonce Nonce of the withdrawal transaction\n * @custom:field sender Address of the sender of the transaction.\n * @custom:field target Address of the recipient of the transaction.\n * @custom:field value Value to send to the recipient.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n */\n struct WithdrawalTransaction {\n uint256 nonce;\n address sender;\n address target;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPReader.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\n/**\n * @custom:attribution https://github.com/hamdiallam/Solidity-RLP\n * @title RLPReader\n * @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted\n * from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with\n * various tweaks to improve readability.\n */\nlibrary RLPReader {\n /**\n * Custom pointer type to avoid confusion between pointers and uint256s.\n */\n type MemoryPointer is uint256;\n\n /**\n * @notice RLP item types.\n *\n * @custom:value DATA_ITEM Represents an RLP data item (NOT a list).\n * @custom:value LIST_ITEM Represents an RLP list item.\n */\n enum RLPItemType {\n DATA_ITEM,\n LIST_ITEM\n }\n\n /**\n * @notice Struct representing an RLP item.\n *\n * @custom:field length Length of the RLP item.\n * @custom:field ptr Pointer to the RLP item in memory.\n */\n struct RLPItem {\n uint256 length;\n MemoryPointer ptr;\n }\n\n /**\n * @notice Max list length that this library will accept.\n */\n uint256 internal constant MAX_LIST_LENGTH = 32;\n\n /**\n * @notice Converts bytes to a reference to memory position and length.\n *\n * @param _in Input bytes to convert.\n *\n * @return Output memory reference.\n */\n function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n // Empty arrays are not RLP items.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr;\n assembly {\n ptr := add(_in, 32)\n }\n\n return RLPItem({ length: _in.length, ptr: ptr });\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.LIST_ITEM,\n \"RLPReader: decoded item type for list is not a list item\"\n );\n\n require(\n listOffset + listLength == _in.length,\n \"RLPReader: list item has an invalid data remainder\"\n );\n\n // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n // writing to the length. Since we can't know the number of RLP items without looping over\n // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n // simply set a reasonable maximum list length and decrease the size before we finish.\n RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n uint256 itemCount = 0;\n uint256 offset = listOffset;\n while (offset < _in.length) {\n (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n RLPItem({\n length: _in.length - offset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n })\n );\n\n // We don't need to check itemCount < out.length explicitly because Solidity already\n // handles this check on our behalf, we'd just be wasting gas.\n out[itemCount] = RLPItem({\n length: itemLength + itemOffset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n });\n\n itemCount += 1;\n offset += itemOffset + itemLength;\n }\n\n // Decrease the array size to match the actual item count.\n assembly {\n mstore(out, itemCount)\n }\n\n return out;\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n return readList(toRLPItem(_in));\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.DATA_ITEM,\n \"RLPReader: decoded item type for bytes is not a data item\"\n );\n\n require(\n _in.length == itemOffset + itemLength,\n \"RLPReader: bytes value contains an invalid remainder\"\n );\n\n return _copy(_in.ptr, itemOffset, itemLength);\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n return readBytes(toRLPItem(_in));\n }\n\n /**\n * @notice Reads the raw bytes of an RLP item.\n *\n * @param _in RLP item to read.\n *\n * @return Raw RLP bytes.\n */\n function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n return _copy(_in.ptr, 0, _in.length);\n }\n\n /**\n * @notice Decodes the length of an RLP item.\n *\n * @param _in RLP item to decode.\n *\n * @return Offset of the encoded data.\n * @return Length of the encoded data.\n * @return RLP item type (LIST_ITEM or DATA_ITEM).\n */\n function _decodeLength(RLPItem memory _in)\n private\n pure\n returns (\n uint256,\n uint256,\n RLPItemType\n )\n {\n // Short-circuit if there's nothing to decode, note that we perform this check when\n // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass\n // that function and create an RLP item directly. So we need to check this anyway.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr = _in.ptr;\n uint256 prefix;\n assembly {\n prefix := byte(0, mload(ptr))\n }\n\n if (prefix <= 0x7f) {\n // Single byte.\n return (0, 1, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xb7) {\n // Short string.\n\n // slither-disable-next-line variable-scope\n uint256 strLen = prefix - 0x80;\n\n require(\n _in.length > strLen,\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n strLen != 1 || firstByteOfContent >= 0x80,\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n\n return (1, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xbf) {\n // Long string.\n uint256 lenOfStrLen = prefix - 0xb7;\n\n require(\n _in.length > lenOfStrLen,\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n\n uint256 strLen;\n assembly {\n strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))\n }\n\n require(\n strLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long string)\"\n );\n\n require(\n _in.length > lenOfStrLen + strLen,\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n\n return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xf7) {\n // Short list.\n // slither-disable-next-line variable-scope\n uint256 listLen = prefix - 0xc0;\n\n require(\n _in.length > listLen,\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n\n return (1, listLen, RLPItemType.LIST_ITEM);\n } else {\n // Long list.\n uint256 lenOfListLen = prefix - 0xf7;\n\n require(\n _in.length > lenOfListLen,\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long list)\"\n );\n\n uint256 listLen;\n assembly {\n listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))\n }\n\n require(\n listLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long list)\"\n );\n\n require(\n _in.length > lenOfListLen + listLen,\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n\n return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n }\n }\n\n /**\n * @notice Copies the bytes from a memory location.\n *\n * @param _src Pointer to the location to read from.\n * @param _offset Offset to start reading from.\n * @param _length Number of bytes to read.\n *\n * @return Copied bytes.\n */\n function _copy(\n MemoryPointer _src,\n uint256 _offset,\n uint256 _length\n ) private pure returns (bytes memory) {\n bytes memory out = new bytes(_length);\n if (_length == 0) {\n return out;\n }\n\n // Mostly based on Solidity's copy_memory_to_memory:\n // solhint-disable max-line-length\n // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114\n uint256 src = MemoryPointer.unwrap(_src) + _offset;\n assembly {\n let dest := add(out, 32)\n let i := 0\n for {\n\n } lt(i, _length) {\n i := add(i, 32)\n } {\n mstore(add(dest, i), mload(add(src, i)))\n }\n\n if gt(i, _length) {\n mstore(add(dest, _length), 0)\n }\n }\n\n return out;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPWriter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\n * @title RLPWriter\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\n * RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\n * modifications to improve legibility.\n */\nlibrary RLPWriter {\n /**\n * @notice RLP encodes a byte string.\n *\n * @param _in The byte string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_in.length == 1 && uint8(_in[0]) < 128) {\n encoded = _in;\n } else {\n encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n }\n\n return encoded;\n }\n\n /**\n * @notice RLP encodes a list of RLP encoded byte byte strings.\n *\n * @param _in The list of RLP encoded byte strings.\n *\n * @return The RLP encoded list of items in bytes.\n */\n function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n bytes memory list = _flatten(_in);\n return abi.encodePacked(_writeLength(list.length, 192), list);\n }\n\n /**\n * @notice RLP encodes a string.\n *\n * @param _in The string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeString(string memory _in) internal pure returns (bytes memory) {\n return writeBytes(bytes(_in));\n }\n\n /**\n * @notice RLP encodes an address.\n *\n * @param _in The address to encode.\n *\n * @return The RLP encoded address in bytes.\n */\n function writeAddress(address _in) internal pure returns (bytes memory) {\n return writeBytes(abi.encodePacked(_in));\n }\n\n /**\n * @notice RLP encodes a uint.\n *\n * @param _in The uint256 to encode.\n *\n * @return The RLP encoded uint256 in bytes.\n */\n function writeUint(uint256 _in) internal pure returns (bytes memory) {\n return writeBytes(_toBinary(_in));\n }\n\n /**\n * @notice RLP encodes a bool.\n *\n * @param _in The bool to encode.\n *\n * @return The RLP encoded bool in bytes.\n */\n function writeBool(bool _in) internal pure returns (bytes memory) {\n bytes memory encoded = new bytes(1);\n encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n return encoded;\n }\n\n /**\n * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\n *\n * @param _len The length of the string or the payload.\n * @param _offset 128 if item is string, 192 if item is list.\n *\n * @return RLP encoded bytes.\n */\n function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_len < 56) {\n encoded = new bytes(1);\n encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n } else {\n uint256 lenLen;\n uint256 i = 1;\n while (_len / i != 0) {\n lenLen++;\n i *= 256;\n }\n\n encoded = new bytes(lenLen + 1);\n encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n for (i = 1; i <= lenLen; i++) {\n encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n }\n }\n\n return encoded;\n }\n\n /**\n * @notice Encode integer in big endian binary form with no leading zeroes.\n *\n * @param _x The integer to encode.\n *\n * @return RLP encoded bytes.\n */\n function _toBinary(uint256 _x) private pure returns (bytes memory) {\n bytes memory b = abi.encodePacked(_x);\n\n uint256 i = 0;\n for (; i < 32; i++) {\n if (b[i] != 0) {\n break;\n }\n }\n\n bytes memory res = new bytes(32 - i);\n for (uint256 j = 0; j < res.length; j++) {\n res[j] = b[i++];\n }\n\n return res;\n }\n\n /**\n * @custom:attribution https://github.com/Arachnid/solidity-stringutils\n * @notice Copies a piece of memory to another location.\n *\n * @param _dest Destination location.\n * @param _src Source location.\n * @param _len Length of memory to copy.\n */\n function _memcpy(\n uint256 _dest,\n uint256 _src,\n uint256 _len\n ) private pure {\n uint256 dest = _dest;\n uint256 src = _src;\n uint256 len = _len;\n\n for (; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n uint256 mask;\n unchecked {\n mask = 256**(32 - len) - 1;\n }\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /**\n * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\n * @notice Flattens a list of byte strings into one byte string.\n *\n * @param _list List of byte strings to flatten.\n *\n * @return The flattened byte string.\n */\n function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n if (_list.length == 0) {\n return new bytes(0);\n }\n\n uint256 len;\n uint256 i = 0;\n for (; i < _list.length; i++) {\n len += _list[i].length;\n }\n\n bytes memory flattened = new bytes(len);\n uint256 flattenedPtr;\n assembly {\n flattenedPtr := add(flattened, 0x20)\n }\n\n for (i = 0; i < _list.length; i++) {\n bytes memory item = _list[i];\n\n uint256 listPtr;\n assembly {\n listPtr := add(item, 0x20)\n }\n\n _memcpy(flattenedPtr, listPtr, item.length);\n flattenedPtr += _list[i].length;\n }\n\n return flattened;\n }\n}\n" - }, - "contracts/libraries/trie/MerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Bytes } from \"../Bytes.sol\";\nimport { RLPReader } from \"../rlp/RLPReader.sol\";\n\n/**\n * @title MerkleTrie\n * @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie\n * inclusion proofs. By default, this library assumes a hexary trie. One can change the\n * trie radix constant to support other trie radixes.\n */\nlibrary MerkleTrie {\n /**\n * @notice Struct representing a node in the trie.\n *\n * @custom:field encoded The RLP-encoded node.\n * @custom:field decoded The RLP-decoded node.\n */\n struct TrieNode {\n bytes encoded;\n RLPReader.RLPItem[] decoded;\n }\n\n /**\n * @notice Determines the number of elements per branch node.\n */\n uint256 internal constant TREE_RADIX = 16;\n\n /**\n * @notice Branch nodes have TREE_RADIX elements and one value element.\n */\n uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\n\n /**\n * @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.\n */\n uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\n\n /**\n * @notice Prefix for even-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_EVEN = 0;\n\n /**\n * @notice Prefix for odd-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_ODD = 1;\n\n /**\n * @notice Prefix for even-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_EVEN = 2;\n\n /**\n * @notice Prefix for odd-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_ODD = 3;\n\n /**\n * @notice Verifies a proof that a given key/value pair is present in the trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n return Bytes.equal(_value, get(_key, _proof, _root));\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n require(_key.length > 0, \"MerkleTrie: empty key\");\n\n TrieNode[] memory proof = _parseProof(_proof);\n bytes memory key = Bytes.toNibbles(_key);\n bytes memory currentNodeID = abi.encodePacked(_root);\n uint256 currentKeyIndex = 0;\n\n // Proof is top-down, so we start at the first element (root).\n for (uint256 i = 0; i < proof.length; i++) {\n TrieNode memory currentNode = proof[i];\n\n // Key index should never exceed total key length or we'll be out of bounds.\n require(\n currentKeyIndex <= key.length,\n \"MerkleTrie: key index exceeds total key length\"\n );\n\n if (currentKeyIndex == 0) {\n // First proof element is always the root node.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid root hash\"\n );\n } else if (currentNode.encoded.length >= 32) {\n // Nodes 32 bytes or larger are hashed inside branch nodes.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid large internal hash\"\n );\n } else {\n // Nodes smaller than 32 bytes aren't hashed.\n require(\n Bytes.equal(currentNode.encoded, currentNodeID),\n \"MerkleTrie: invalid internal node hash\"\n );\n }\n\n if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\n if (currentKeyIndex == key.length) {\n // Value is the last element of the decoded list (for branch nodes). There's\n // some ambiguity in the Merkle trie specification because bytes(0) is a\n // valid value to place into the trie, but for branch nodes bytes(0) can exist\n // even when the value wasn't explicitly placed there. Geth treats a value of\n // bytes(0) as \"key does not exist\" and so we do the same.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (branch)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (branch)\"\n );\n\n return value;\n } else {\n // We're not at the end of the key yet.\n // Figure out what the next node ID should be and continue.\n uint8 branchKey = uint8(key[currentKeyIndex]);\n RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\n currentNodeID = _getNodeID(nextNode);\n currentKeyIndex += 1;\n }\n } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\n bytes memory path = _getNodePath(currentNode);\n uint8 prefix = uint8(path[0]);\n uint8 offset = 2 - (prefix % 2);\n bytes memory pathRemainder = Bytes.slice(path, offset);\n bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);\n uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\n\n // Whether this is a leaf node or an extension node, the path remainder MUST be a\n // prefix of the key remainder (or be equal to the key remainder) or the proof is\n // considered invalid.\n require(\n pathRemainder.length == sharedNibbleLength,\n \"MerkleTrie: path remainder must share all nibbles with key\"\n );\n\n if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\n // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid,\n // the key remainder must be exactly equal to the path remainder. We already\n // did the necessary byte comparison, so it's more efficient here to check that\n // the key remainder length equals the shared nibble length, which implies\n // equality with the path remainder (since we already did the same check with\n // the path remainder and the shared nibble length).\n require(\n keyRemainder.length == sharedNibbleLength,\n \"MerkleTrie: key remainder must be identical to path remainder\"\n );\n\n // Our Merkle Trie is designed specifically for the purposes of the Ethereum\n // state trie. Empty values are not allowed in the state trie, so we can safely\n // say that if the value is empty, the key should not exist and the proof is\n // invalid.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[1]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (leaf)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (leaf)\"\n );\n\n return value;\n } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\n // Prefix of 0 or 1 means this is an extension node. We move onto the next node\n // in the proof and increment the key index by the length of the path remainder\n // which is equal to the shared nibble length.\n currentNodeID = _getNodeID(currentNode.decoded[1]);\n currentKeyIndex += sharedNibbleLength;\n } else {\n revert(\"MerkleTrie: received a node with an unknown prefix\");\n }\n } else {\n revert(\"MerkleTrie: received an unparseable node\");\n }\n }\n\n revert(\"MerkleTrie: ran out of proof elements\");\n }\n\n /**\n * @notice Parses an array of proof elements into a new array that contains both the original\n * encoded element and the RLP-decoded element.\n *\n * @param _proof Array of proof elements to parse.\n *\n * @return Proof parsed into easily accessible structs.\n */\n function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {\n uint256 length = _proof.length;\n TrieNode[] memory proof = new TrieNode[](length);\n for (uint256 i = 0; i < length; ) {\n proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });\n unchecked {\n ++i;\n }\n }\n return proof;\n }\n\n /**\n * @notice Picks out the ID for a node. Node ID is referred to as the \"hash\" within the\n * specification, but nodes < 32 bytes are not actually hashed.\n *\n * @param _node Node to pull an ID for.\n *\n * @return ID for the node, depending on the size of its contents.\n */\n function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {\n return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);\n }\n\n /**\n * @notice Gets the path for a leaf or extension node.\n *\n * @param _node Node to get a path for.\n *\n * @return Node path, converted to an array of nibbles.\n */\n function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {\n return Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0]));\n }\n\n /**\n * @notice Utility; determines the number of nibbles shared between two nibble arrays.\n *\n * @param _a First nibble array.\n * @param _b Second nibble array.\n *\n * @return Number of shared nibbles.\n */\n function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\n private\n pure\n returns (uint256)\n {\n uint256 shared;\n uint256 max = (_a.length < _b.length) ? _a.length : _b.length;\n for (; shared < max && _a[shared] == _b[shared]; ) {\n unchecked {\n ++shared;\n }\n }\n return shared;\n }\n}\n" - }, - "contracts/libraries/trie/SecureMerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/* Library Imports */\nimport { MerkleTrie } from \"./MerkleTrie.sol\";\n\n/**\n * @title SecureMerkleTrie\n * @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input\n * keys. Ethereum's state trie hashes input keys before storing them.\n */\nlibrary SecureMerkleTrie {\n /**\n * @notice Verifies a proof that a given key/value pair is present in the Merkle trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.get(key, _proof, _root);\n }\n\n /**\n * @notice Computes the hashed version of the input key.\n *\n * @param _key Key to hash.\n *\n * @return Hashed version of the key.\n */\n function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {\n return abi.encodePacked(keccak256(_key));\n }\n}\n" - }, - "contracts/periphery/TransferOnion.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title TransferOnion\n * @notice TransferOnion is a hash onion for distributing tokens. The shell commits\n * to an ordered list of the token transfers and can be permissionlessly\n * unwrapped in order. The SENDER must `approve` this contract as\n * `transferFrom` is used to move the token balances.\n */\ncontract TransferOnion is ReentrancyGuard {\n using SafeERC20 for ERC20;\n\n /**\n * @notice Struct representing a layer of the onion.\n */\n struct Layer {\n address recipient;\n uint256 amount;\n bytes32 shell;\n }\n\n /**\n * @notice Address of the token to distribute.\n */\n ERC20 public immutable TOKEN;\n\n /**\n * @notice Address of the account to distribute tokens from.\n */\n address public immutable SENDER;\n\n /**\n * @notice Current shell hash.\n */\n bytes32 public shell;\n\n /**\n * @param _token Address of the token to distribute.\n * @param _sender Address of the sender to distribute from.\n * @param _shell Initial shell of the onion.\n */\n constructor(\n ERC20 _token,\n address _sender,\n bytes32 _shell\n ) {\n TOKEN = _token;\n SENDER = _sender;\n shell = _shell;\n }\n\n /**\n * @notice Peels layers from the onion and distributes tokens.\n *\n * @param _layers Array of onion layers to peel.\n */\n function peel(Layer[] memory _layers) public nonReentrant {\n bytes32 tempShell = shell;\n uint256 length = _layers.length;\n for (uint256 i = 0; i < length; ) {\n Layer memory layer = _layers[i];\n\n // Confirm that the onion layer is correct.\n require(\n keccak256(abi.encode(layer.recipient, layer.amount, layer.shell)) == tempShell,\n \"TransferOnion: what are you doing in my swamp?\"\n );\n\n // Update the onion layer.\n tempShell = layer.shell;\n\n // Transfer the tokens.\n TOKEN.safeTransferFrom(SENDER, layer.recipient, layer.amount);\n\n // Unchecked increment to save some gas.\n unchecked {\n ++i;\n }\n }\n\n shell = tempShell;\n }\n}\n" - }, - "contracts/test/AddressAliasHelper.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract AddressAliasHelper_applyAndUndo_Test is Test {\n /**\n * @notice Tests that applying and then undoing an alias results in the original address.\n */\n function testFuzz_applyAndUndo_succeeds(address _address) external {\n address aliased = AddressAliasHelper.applyL1ToL2Alias(_address);\n address unaliased = AddressAliasHelper.undoL1ToL2Alias(aliased);\n assertEq(_address, unaliased);\n }\n}\n" - }, - "contracts/test/BenchmarkTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test } from \"forge-std/Test.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport \"./CommonTest.t.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n// Free function for setting the prevBaseFee param in the OptimismPortal.\nfunction setPrevBaseFee(\n Vm _vm,\n address _op,\n uint128 _prevBaseFee\n) {\n _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee));\n}\n\ncontract SetPrevBaseFee_Test is Portal_Initializer {\n function test_setPrevBaseFee_succeeds() external {\n setPrevBaseFee(vm, address(op), 100 gwei);\n (uint128 prevBaseFee, , uint64 prevBlockNum) = op.params();\n assertEq(uint256(prevBaseFee), 100 gwei);\n assertEq(uint256(prevBlockNum), block.number);\n }\n}\n\n// Tests for obtaining pure gas cost estimates for commonly used functions.\n// The objective with these benchmarks is to strip down the actual test functions\n// so that they are nothing more than the call we want measure the gas cost of.\n// In order to achieve this we make no assertions, and handle everything else in the setUp()\n// function.\ncontract GasBenchMark_OptimismPortal is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n bytes32 _outputRoot;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n\n // Get withdrawal proof data we can use for testing.\n bytes32 _storageRoot;\n bytes32 _stateRoot;\n (_stateRoot, _storageRoot, _outputRoot, , _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public virtual override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n function test_depositTransaction_benchmark() external {\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_depositTransaction_benchmark_1() external {\n setPrevBaseFee(vm, address(op), 1 gwei);\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_proveWithdrawalTransaction_benchmark() external {\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n}\n\ncontract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {\n function test_sendMessage_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n\n function test_sendMessage_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), alice, 100000, true);\n vm.startPrank(alice, alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n }\n\n function test_depositETH_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositETH_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositERC20_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n\n function test_depositERC20_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), address(L1Bridge), 100, true);\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.startPrank(address(L1Bridge.messenger()));\n vm.deal(address(L1Bridge.messenger()), 100);\n }\n\n function test_finalizeETHWithdrawal_benchmark() external {\n // TODO: Make this more accurate. It is underestimating the cost because it pranks\n // the call coming from the messenger, which bypasses the portal\n // and oracle.\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer {\n uint256 nextBlockNumber;\n\n function setUp() public override {\n super.setUp();\n nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.startPrank(proposer);\n }\n\n function test_proposeL2Output_benchmark() external {\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n}\n" - }, - "contracts/test/Bytes.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Bytes } from \"../libraries/Bytes.sol\";\n\ncontract Bytes_slice_Test is Test {\n /**\n * @notice Tests that the `slice` function works as expected when starting from index 0.\n */\n function test_slice_fromZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check if all possible slices starting from index 0 are correct.\n assertEq(Bytes.slice(input, 0, 0), hex\"\");\n assertEq(Bytes.slice(input, 0, 1), hex\"11\");\n assertEq(Bytes.slice(input, 0, 2), hex\"1122\");\n assertEq(Bytes.slice(input, 0, 3), hex\"112233\");\n assertEq(Bytes.slice(input, 0, 4), hex\"11223344\");\n assertEq(Bytes.slice(input, 0, 5), hex\"1122334455\");\n assertEq(Bytes.slice(input, 0, 6), hex\"112233445566\");\n assertEq(Bytes.slice(input, 0, 7), hex\"11223344556677\");\n assertEq(Bytes.slice(input, 0, 8), hex\"1122334455667788\");\n assertEq(Bytes.slice(input, 0, 9), hex\"112233445566778899\");\n assertEq(Bytes.slice(input, 0, 10), hex\"11223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when starting from indices [1, 9]\n * with lengths [1, 9], in reverse order.\n */\n function test_slice_fromNonZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check correctness of slices starting from indexes [1, 9]\n // and spanning [1, 9] bytes, in reverse order\n assertEq(Bytes.slice(input, 9, 1), hex\"00\");\n assertEq(Bytes.slice(input, 8, 2), hex\"9900\");\n assertEq(Bytes.slice(input, 7, 3), hex\"889900\");\n assertEq(Bytes.slice(input, 6, 4), hex\"77889900\");\n assertEq(Bytes.slice(input, 5, 5), hex\"6677889900\");\n assertEq(Bytes.slice(input, 4, 6), hex\"556677889900\");\n assertEq(Bytes.slice(input, 3, 7), hex\"44556677889900\");\n assertEq(Bytes.slice(input, 2, 8), hex\"3344556677889900\");\n assertEq(Bytes.slice(input, 1, 9), hex\"223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple words\n * in memory. In this case, we test that a 2 byte slice between the 32nd byte of the\n * first word and the 1st byte of the second word is correct.\n */\n function test_slice_acrossWords_works() public {\n bytes\n memory input = hex\"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000\";\n\n assertEq(Bytes.slice(input, 31, 2), hex\"1122\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple\n * words in memory. In this case, we test that a 34 byte slice between 3 separate words\n * returns the correct result.\n */\n function test_slice_acrossMultipleWords_works() public {\n bytes\n memory input = hex\"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000\";\n bytes\n memory expected = hex\"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11\";\n\n assertEq(Bytes.slice(input, 31, 34), expected);\n }\n\n /**\n * @notice Tests that, when given an input bytes array of length `n`, the `slice` function will\n * always revert if `_start + _length > n`.\n */\n function testFuzz_slice_outOfBounds_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // We want a valid start index and a length that will not overflow.\n vm.assume(_start < _input.length && _length < type(uint256).max - 31);\n // But, we want an invalid slice length.\n vm.assume(_start + _length > _input.length);\n\n vm.expectRevert(\"slice_outOfBounds\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,\n * the `slice` function reverts.\n */\n function testFuzz_slice_lengthOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that the `_length` will overflow if a number >= 31 is added to it.\n vm.assume(_length > type(uint256).max - 31);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a start index `n` that is greater than\n * `type(uint256).max - n`, the `slice` function reverts.\n */\n function testFuzz_slice_rangeOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that `_length` is a realistic length of a slice. This is to make sure\n // we revert on the correct require statement.\n vm.assume(_length < _input.length);\n // Ensure that `_start` will overflow if `_length` is added to it.\n vm.assume(_start > type(uint256).max - _length);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that the `slice` function correctly updates the free memory pointer depending\n * on the length of the slice.\n */\n function testFuzz_slice_memorySafety_succeeds(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // The start should never be more than the length of the input bytes array - 1\n vm.assume(_start < _input.length);\n // The length should never be more than the length of the input bytes array - the starting\n // slice index.\n vm.assume(_length <= _input.length - _start);\n\n // Grab the free memory pointer before the slice operation\n uint64 initPtr;\n assembly {\n initPtr := mload(0x40)\n }\n uint64 expectedPtr = uint64(initPtr + 0x20 + ((_length + 0x1f) & ~uint256(0x1f)));\n\n // Ensure that all memory outside of the expected range is safe.\n vm.expectSafeMemory(initPtr, expectedPtr);\n\n // Slice the input bytes array from `_start` to `_start + _length`\n bytes memory slice = Bytes.slice(_input, _start, _length);\n\n // Grab the free memory pointer after the slice operation\n uint64 finalPtr;\n assembly {\n finalPtr := mload(0x40)\n }\n\n // The free memory pointer should have been updated properly\n if (_length == 0) {\n // If the slice length is zero, only 32 bytes of memory should have been allocated.\n assertEq(finalPtr, initPtr + 0x20);\n } else {\n // If the slice length is greater than zero, the memory allocated should be the\n // length of the slice rounded up to the next 32 byte word + 32 bytes for the\n // length of the byte array.\n //\n // Note that we use a slightly less efficient, but equivalent method of rounding\n // up `_length` to the next multiple of 32 than is used in the `slice` function.\n // This is to diff test the method used in `slice`.\n uint64 _expectedPtr = uint64(initPtr + 0x20 + (((_length + 0x1F) >> 5) << 5));\n assertEq(finalPtr, _expectedPtr);\n\n // Sanity check for equivalence of the rounding methods.\n assertEq(_expectedPtr, expectedPtr);\n }\n\n // The slice length should be equal to `_length`\n assertEq(slice.length, _length);\n }\n}\n\ncontract Bytes_toNibbles_Test is Test {\n /**\n * @notice Diffs the test Solidity version of `toNibbles` against the Yul version.\n *\n * @param _bytes The `bytes` array to convert to nibbles.\n *\n * @return Yul version of `toNibbles` applied to `_bytes`.\n */\n function _toNibblesYul(bytes memory _bytes) internal pure returns (bytes memory) {\n // Allocate memory for the `nibbles` array.\n bytes memory nibbles = new bytes(_bytes.length << 1);\n\n assembly {\n // Load the length of the passed bytes array from memory\n let bytesLength := mload(_bytes)\n\n // Store the memory offset of the _bytes array's contents on the stack\n let bytesStart := add(_bytes, 0x20)\n\n // Store the memory offset of the nibbles array's contents on the stack\n let nibblesStart := add(nibbles, 0x20)\n\n // Loop through each byte in the input array\n for {\n let i := 0x00\n } lt(i, bytesLength) {\n i := add(i, 0x01)\n } {\n // Get the starting offset of the next 2 bytes in the nibbles array\n let offset := add(nibblesStart, shl(0x01, i))\n\n // Load the byte at the current index within the `_bytes` array\n let b := byte(0x00, mload(add(bytesStart, i)))\n\n // Pull out the first nibble and store it in the new array\n mstore8(offset, shr(0x04, b))\n // Pull out the second nibble and store it in the new array\n mstore8(add(offset, 0x01), and(b, 0x0F))\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Tests that, given an input of 5 bytes, the `toNibbles` function returns an array of\n * 10 nibbles corresponding to the input data.\n */\n function test_toNibbles_expectedResult5Bytes_works() public {\n bytes memory input = hex\"1234567890\";\n bytes memory expected = hex\"01020304050607080900\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 128 bytes, the `toNibbles` function returns an array\n * of 256 nibbles corresponding to the input data. This test exists to ensure that,\n * given a large input, the `toNibbles` function works as expected.\n */\n function test_toNibbles_expectedResult128Bytes_works() public {\n bytes\n memory input = hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f\";\n bytes\n memory expected = hex\"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 0 bytes, the `toNibbles` function returns a zero\n * length array.\n */\n function test_toNibbles_zeroLengthInput_works() public {\n bytes memory input = hex\"\";\n bytes memory expected = hex\"\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length, 0);\n assertEq(expected.length, 0);\n assertEq(actual.length, 0);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Test that the `toNibbles` function in the `Bytes` library is equivalent to the Yul\n * implementation.\n */\n function testDiff_toNibbles_succeeds(bytes memory _input) public {\n assertEq(Bytes.toNibbles(_input), _toNibblesYul(_input));\n }\n}\n\ncontract Bytes_equal_Test is Test {\n /**\n * @notice Manually checks equality of two dynamic `bytes` arrays in memory.\n *\n * @param _a The first `bytes` array to compare.\n * @param _b The second `bytes` array to compare.\n *\n * @return True if the two `bytes` arrays are equal in memory.\n */\n function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) {\n bool _eq;\n assembly {\n _eq := and(\n // Check if the contents of the two bytes arrays are equal in memory.\n eq(keccak256(add(0x20, _a), mload(_a)), keccak256(add(0x20, _b), mload(_b))),\n // Check if the length of the two bytes arrays are equal in memory.\n // This is redundant given the above check, but included for completeness.\n eq(mload(_a), mload(_b))\n )\n }\n return _eq;\n }\n\n /**\n * @notice Tests that the `equal` function in the `Bytes` library returns `false` if given two\n * non-equal byte arrays.\n */\n function testFuzz_equal_notEqual_works(bytes memory _a, bytes memory _b) public {\n vm.assume(!manualEq(_a, _b));\n assertFalse(Bytes.equal(_a, _b));\n }\n\n /**\n * @notice Test whether or not the `equal` function in the `Bytes` library is equivalent to\n * manually checking equality of the two dynamic `bytes` arrays in memory.\n */\n function testDiff_equal_works(bytes memory _a, bytes memory _b) public {\n assertEq(Bytes.equal(_a, _b), manualEq(_a, _b));\n }\n}\n" - }, - "contracts/test/CommonTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test, StdUtils } from \"forge-std/Test.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { IL1ChugSplashDeployer } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { LegacyMintableERC20 } from \"../legacy/LegacyMintableERC20.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract CommonTest is Test {\n address alice = address(128);\n address bob = address(256);\n address multisig = address(512);\n\n address immutable ZERO_ADDRESS = address(0);\n address immutable NON_ZERO_ADDRESS = address(1);\n uint256 immutable NON_ZERO_VALUE = 100;\n uint256 immutable ZERO_VALUE = 0;\n uint64 immutable NON_ZERO_GASLIMIT = 50000;\n bytes32 nonZeroHash = keccak256(abi.encode(\"NON_ZERO\"));\n bytes NON_ZERO_DATA = hex\"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000\";\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n FFIInterface ffi;\n\n function setUp() public virtual {\n // Give alice and bob some ETH\n vm.deal(alice, 1 << 16);\n vm.deal(bob, 1 << 16);\n vm.deal(multisig, 1 << 16);\n\n vm.label(alice, \"alice\");\n vm.label(bob, \"bob\");\n vm.label(multisig, \"multisig\");\n\n // Make sure we have a non-zero base fee\n vm.fee(1000000000);\n\n ffi = new FFIInterface();\n }\n\n function emitTransactionDeposited(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) internal {\n emit TransactionDeposited(\n _from,\n _to,\n 0,\n abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)\n );\n }\n}\n\ncontract L2OutputOracle_Initializer is CommonTest {\n // Test target\n L2OutputOracle oracle;\n L2OutputOracle oracleImpl;\n\n L2ToL1MessagePasser messagePasser =\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));\n\n // Constructor arguments\n address internal proposer = 0x000000000000000000000000000000000000AbBa;\n address internal owner = 0x000000000000000000000000000000000000ACDC;\n uint256 internal submissionInterval = 1800;\n uint256 internal l2BlockTime = 2;\n uint256 internal startingBlockNumber = 200;\n uint256 internal startingTimestamp = 1000;\n address guardian;\n\n // Test data\n uint256 initL1Time;\n\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n // Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output\n function warpToProposeTime(uint256 _nextBlockNumber) public {\n vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1);\n }\n\n function setUp() public virtual override {\n super.setUp();\n guardian = makeAddr(\"guardian\");\n\n // By default the first block has timestamp and number zero, which will cause underflows in the\n // tests, so we'll move forward to these block values.\n initL1Time = startingTimestamp + 1;\n vm.warp(initL1Time);\n vm.roll(startingBlockNumber);\n // Deploy the L2OutputOracle and transfer owernship to the proposer\n oracleImpl = new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: startingTimestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(oracleImpl),\n abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp))\n );\n oracle = L2OutputOracle(address(proxy));\n vm.label(address(oracle), \"L2OutputOracle\");\n\n // Set the L2ToL1MessagePasser at the correct address\n vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code);\n\n vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, \"L2ToL1MessagePasser\");\n }\n}\n\ncontract Portal_Initializer is L2OutputOracle_Initializer {\n // Test target\n OptimismPortal internal opImpl;\n OptimismPortal internal op;\n SystemConfig systemConfig;\n\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n\n systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: config\n });\n\n opImpl = new OptimismPortal({\n _l2Oracle: oracle,\n _guardian: guardian,\n _paused: true,\n _config: systemConfig\n });\n\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(opImpl),\n abi.encodeWithSelector(OptimismPortal.initialize.selector, false)\n );\n op = OptimismPortal(payable(address(proxy)));\n vm.label(address(op), \"OptimismPortal\");\n }\n}\n\ncontract Messenger_Initializer is Portal_Initializer {\n AddressManager internal addressManager;\n L1CrossDomainMessenger internal L1Messenger;\n L2CrossDomainMessenger internal L2Messenger =\n L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);\n\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event RelayedMessage(bytes32 indexed msgHash);\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 mint,\n uint256 value,\n uint64 gasLimit,\n bool isCreation,\n bytes data\n );\n\n event WhatHappened(bool success, bytes returndata);\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the address manager\n vm.prank(multisig);\n addressManager = new AddressManager();\n\n // Setup implementation\n L1CrossDomainMessenger L1MessengerImpl = new L1CrossDomainMessenger(op);\n\n // Setup the address manager and proxy\n vm.prank(multisig);\n addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(L1MessengerImpl));\n ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(\n addressManager,\n \"OVM_L1CrossDomainMessenger\"\n );\n L1Messenger = L1CrossDomainMessenger(address(proxy));\n L1Messenger.initialize();\n\n vm.etch(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n address(new L2CrossDomainMessenger(address(L1Messenger))).code\n );\n\n L2Messenger.initialize();\n\n // Label addresses\n vm.label(address(addressManager), \"AddressManager\");\n vm.label(address(L1MessengerImpl), \"L1CrossDomainMessenger_Impl\");\n vm.label(address(L1Messenger), \"L1CrossDomainMessenger_Proxy\");\n vm.label(Predeploys.LEGACY_ERC20_ETH, \"LegacyERC20ETH\");\n vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, \"L2CrossDomainMessenger\");\n\n vm.label(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n \"L1CrossDomainMessenger_aliased\"\n );\n }\n}\n\ncontract Bridge_Initializer is Messenger_Initializer {\n L1StandardBridge L1Bridge;\n L2StandardBridge L2Bridge;\n OptimismMintableERC20Factory L2TokenFactory;\n OptimismMintableERC20Factory L1TokenFactory;\n ERC20 L1Token;\n ERC20 BadL1Token;\n OptimismMintableERC20 L2Token;\n LegacyMintableERC20 LegacyL2Token;\n ERC20 NativeL2Token;\n ERC20 BadL2Token;\n OptimismMintableERC20 RemoteL1Token;\n\n event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data\n );\n\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFailed(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.label(Predeploys.L2_STANDARD_BRIDGE, \"L2StandardBridge\");\n vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, \"OptimismMintableERC20Factory\");\n\n // Deploy the L1 bridge and initialize it with the address of the\n // L1CrossDomainMessenger\n L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig);\n vm.mockCall(\n multisig,\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector),\n abi.encode(true)\n );\n vm.startPrank(multisig);\n proxy.setCode(address(new L1StandardBridge(payable(address(L1Messenger)))).code);\n vm.clearMockedCalls();\n address L1Bridge_Impl = proxy.getImplementation();\n vm.stopPrank();\n\n L1Bridge = L1StandardBridge(payable(address(proxy)));\n\n vm.label(address(proxy), \"L1StandardBridge_Proxy\");\n vm.label(address(L1Bridge_Impl), \"L1StandardBridge_Impl\");\n\n // Deploy the L2StandardBridge, move it to the correct predeploy\n // address and then initialize it\n L2StandardBridge l2B = new L2StandardBridge(payable(proxy));\n vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(l2B).code);\n L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));\n\n // Set up the L2 mintable token factory\n OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(\n Predeploys.L2_STANDARD_BRIDGE\n );\n vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code);\n L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);\n\n vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code);\n\n L1Token = new ERC20(\"Native L1 Token\", \"L1T\");\n\n LegacyL2Token = new LegacyMintableERC20({\n _l2Bridge: address(L2Bridge),\n _l1Token: address(L1Token),\n _name: string.concat(\"LegacyL2-\", L1Token.name()),\n _symbol: string.concat(\"LegacyL2-\", L1Token.symbol())\n });\n vm.label(address(LegacyL2Token), \"LegacyMintableERC20\");\n\n // Deploy the L2 ERC20 now\n L2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(L1Token),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n BadL2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n NativeL2Token = new ERC20(\"Native L2 Token\", \"L2T\");\n L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge));\n\n RemoteL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(NativeL2Token),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n\n BadL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n }\n}\n\ncontract ERC721Bridge_Initializer is Messenger_Initializer {\n L1ERC721Bridge L1Bridge;\n L2ERC721Bridge L2Bridge;\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the L1ERC721Bridge.\n L1Bridge = new L1ERC721Bridge(address(L1Messenger), Predeploys.L2_ERC721_BRIDGE);\n\n // Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.\n vm.etch(\n Predeploys.L2_ERC721_BRIDGE,\n address(new L2ERC721Bridge(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(L1Bridge)))\n .code\n );\n\n // Set up a reference to the L2ERC721Bridge.\n L2Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);\n\n // Label the L1 and L2 bridges.\n vm.label(address(L1Bridge), \"L1ERC721Bridge\");\n vm.label(address(L2Bridge), \"L2ERC721Bridge\");\n }\n}\n\ncontract FFIInterface is Test {\n function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx)\n external\n returns (\n bytes32,\n bytes32,\n bytes32,\n bytes32,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"getProveWithdrawalTransactionInputs\";\n cmds[2] = vm.toString(_tx.nonce);\n cmds[3] = vm.toString(_tx.sender);\n cmds[4] = vm.toString(_tx.target);\n cmds[5] = vm.toString(_tx.value);\n cmds[6] = vm.toString(_tx.gasLimit);\n cmds[7] = vm.toString(_tx.data);\n\n bytes memory result = vm.ffi(cmds);\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[]));\n\n return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof);\n }\n\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashWithdrawal(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashWithdrawal\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashOutputRootProof(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external returns (bytes32) {\n string[] memory cmds = new string[](6);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashOutputRootProof\";\n cmds[2] = Strings.toHexString(uint256(_version));\n cmds[3] = Strings.toHexString(uint256(_stateRoot));\n cmds[4] = Strings.toHexString(uint256(_messagePasserStorageRoot));\n cmds[5] = Strings.toHexString(uint256(_latestBlockhash));\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashDepositTransaction(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external returns (bytes32) {\n string[] memory cmds = new string[](10);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashDepositTransaction\";\n cmds[2] = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n cmds[3] = vm.toString(_logIndex);\n cmds[4] = vm.toString(_from);\n cmds[5] = vm.toString(_to);\n cmds[6] = vm.toString(_mint);\n cmds[7] = vm.toString(_value);\n cmds[8] = vm.toString(_gas);\n cmds[9] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function encodeDepositTransaction(Types.UserDepositTransaction calldata txn)\n external\n returns (bytes memory)\n {\n string[] memory cmds = new string[](11);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeDepositTransaction\";\n cmds[2] = vm.toString(txn.from);\n cmds[3] = vm.toString(txn.to);\n cmds[4] = vm.toString(txn.value);\n cmds[5] = vm.toString(txn.mint);\n cmds[6] = vm.toString(txn.gasLimit);\n cmds[7] = vm.toString(txn.isCreation);\n cmds[8] = vm.toString(txn.data);\n cmds[9] = vm.toString(txn.l1BlockHash);\n cmds[10] = vm.toString(txn.logIndex);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes memory) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) {\n string[] memory cmds = new string[](3);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"decodeVersionedNonce\";\n cmds[2] = vm.toString(nonce);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (uint256, uint256));\n }\n\n function getMerkleTrieFuzzCase(string memory variant)\n external\n returns (\n bytes32,\n bytes memory,\n bytes memory,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](5);\n cmds[0] = \"./test-case-generator/fuzz\";\n cmds[1] = \"-m\";\n cmds[2] = \"trie\";\n cmds[3] = \"-v\";\n cmds[4] = variant;\n\n return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[]));\n }\n}\n\n// Used for testing a future upgrade beyond the current implementations.\n// We include some variables so that we can sanity check accessing storage values after an upgrade.\ncontract NextImpl is Initializable {\n // Initializable occupies the zero-th slot.\n bytes32 slot1;\n bytes32[19] __gap;\n bytes32 slot21;\n bytes32 public constant slot21Init = bytes32(hex\"1337\");\n\n function initialize() public reinitializer(2) {\n // Slot21 is unused by an of our upgradeable contracts.\n // This is used to verify that we can access this value after an upgrade.\n slot21 = slot21Init;\n }\n}\n\ncontract Reverter {\n fallback() external {\n revert();\n }\n}\n\n// Useful for testing reentrancy guards\ncontract CallerCaller {\n event WhatHappened(bool success, bytes returndata);\n\n fallback() external {\n (bool success, bytes memory returndata) = msg.sender.call(msg.data);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n\n// Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard.\ncontract ConfigurableCaller {\n bool doRevert = true;\n address target;\n bytes payload;\n\n event WhatHappened(bool success, bytes returndata);\n\n /**\n * @notice Call the configured target with the configured payload OR revert.\n */\n function call() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n } else {\n (bool success, bytes memory returndata) = address(target).call(payload);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n }\n\n /**\n * @notice Set whether or not to have `call` revert.\n */\n function setDoRevert(bool _doRevert) external {\n doRevert = _doRevert;\n }\n\n /**\n * @notice Set the target for the call made in `call`.\n */\n function setTarget(address _target) external {\n target = _target;\n }\n\n /**\n * @notice Set the payload for the call made in `call`.\n */\n function setPayload(bytes calldata _payload) external {\n payload = _payload;\n }\n\n /**\n * @notice Fallback function that reverts if `doRevert` is true.\n * Otherwise, it does nothing.\n */\n fallback() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n }\n }\n}\n" - }, - "contracts/test/CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, CallerCaller, CommonTest } from \"./CommonTest.t.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\n\n// Libraries\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n// CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2\n// CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract.\ncontract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {\n // Ensure that baseGas passes for the max value of _minGasLimit,\n // this is about 4 Billion.\n function test_baseGas_succeeds() external view {\n L1Messenger.baseGas(hex\"ff\", type(uint32).max);\n }\n\n // Fuzz for other values which might cause a revert in baseGas.\n function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view {\n L1Messenger.baseGas(hex\"ff\", _minGasLimit);\n }\n\n /**\n * @notice The baseGas function should always return a value greater than\n * or equal to the minimum gas limit value on the OptimismPortal.\n * This guarantees that the messengers will always pass sufficient\n * gas to the OptimismPortal.\n */\n function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit)\n external\n {\n vm.assume(_data.length <= type(uint64).max);\n uint64 baseGas = L1Messenger.baseGas(_data, _minGasLimit);\n uint64 minGasLimit = op.minimumGasLimit(uint64(_data.length));\n assertTrue(baseGas >= minGasLimit);\n }\n}\n\n/**\n * @title ExternalRelay\n * @notice A mock external contract called via the SafeCall inside\n * the CrossDomainMessenger's `relayMessage` function.\n */\ncontract ExternalRelay is CommonTest {\n address internal op;\n address internal fuzzedSender;\n L1CrossDomainMessenger internal L1Messenger;\n\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n constructor(L1CrossDomainMessenger _l1Messenger, address _op) {\n L1Messenger = _l1Messenger;\n op = _op;\n }\n\n /**\n * @notice Internal helper function to relay a message and perform assertions.\n */\n function _internalRelay(address _innerSender) internal {\n address initialSender = L1Messenger.xDomainMessageSender();\n\n bytes memory callMessage = getCallData();\n\n bytes32 hash = Hashing.hashCrossDomainMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: _innerSender,\n _target: address(this),\n _value: 0,\n _gasLimit: 0,\n _data: callMessage\n });\n\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n vm.prank(address(op));\n L1Messenger.relayMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: _innerSender,\n _target: address(this),\n _value: 0,\n _minGasLimit: 0,\n _message: callMessage\n });\n\n assertTrue(L1Messenger.failedMessages(hash));\n assertFalse(L1Messenger.successfulMessages(hash));\n assertEq(initialSender, L1Messenger.xDomainMessageSender());\n }\n\n /**\n * @notice externalCallWithMinGas is called by the CrossDomainMessenger.\n */\n function externalCallWithMinGas() external payable {\n for (uint256 i = 0; i < 10; i++) {\n address _innerSender;\n unchecked {\n _innerSender = address(uint160(uint256(uint160(fuzzedSender)) + i));\n }\n _internalRelay(_innerSender);\n }\n }\n\n /**\n * @notice Helper function to get the callData for an `externalCallWithMinGas\n */\n function getCallData() public pure returns (bytes memory) {\n return abi.encodeWithSelector(ExternalRelay.externalCallWithMinGas.selector);\n }\n\n /**\n * @notice Helper function to set the fuzzed sender\n */\n function setFuzzedSender(address _fuzzedSender) public {\n fuzzedSender = _fuzzedSender;\n }\n}\n\n/**\n * @title CrossDomainMessenger_RelayMessage_Test\n * @notice Fuzz tests re-entrancy into the CrossDomainMessenger relayMessage function.\n */\ncontract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer {\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n ExternalRelay public er;\n\n function setUp() public override {\n super.setUp();\n er = new ExternalRelay(L1Messenger, address(op));\n }\n\n /**\n * @dev This test mocks an OptimismPortal call to the L1CrossDomainMessenger via\n * the relayMessage function. The relayMessage function will then use SafeCall's\n * callWithMinGas to call the target with call data packed in the callMessage.\n * For this test, the callWithMinGas will call the mock ExternalRelay test contract\n * defined above, executing the externalCallWithMinGas function which will try to\n * re-enter the CrossDomainMessenger's relayMessage function, resulting in that message\n * being recorded as failed.\n */\n function testFuzz_relayMessageReenter_succeeds(address _sender, uint256 _gasLimit) external {\n vm.assume(_sender != Predeploys.L2_CROSS_DOMAIN_MESSENGER);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n er.setFuzzedSender(_sender);\n address target = address(er);\n bytes memory callMessage = er.getCallData();\n\n vm.expectCall(target, callMessage);\n\n uint64 gasLimit = uint64(bound(_gasLimit, 0, 30_000_000));\n\n bytes32 hash = Hashing.hashCrossDomainMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: sender,\n _target: target,\n _value: 0,\n _gasLimit: gasLimit,\n _data: callMessage\n });\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n L1Messenger.relayMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: sender,\n _target: target,\n _value: 0,\n _minGasLimit: gasLimit,\n _message: callMessage\n });\n\n assertTrue(L1Messenger.successfulMessages(hash));\n assertEq(L1Messenger.failedMessages(hash), false);\n\n // Ensures that the `xDomainMsgSender` is set back to `Predeploys.L2_CROSS_DOMAIN_MESSENGER`\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest, Portal_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable } from \"../L2/CrossDomainOwnable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Vm, VmSafe } from \"forge-std/Vm.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract XDomainSetter is CrossDomainOwnable {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable_Test is CommonTest {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n setter = new XDomainSetter();\n }\n\n // Check that the revert message is correct\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable: caller is not the owner\");\n setter.set(1);\n }\n\n // Check that making a call can set the value properly\n function test_onlyOwner_succeeds() external {\n assertEq(setter.value(), 0);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(setter.owner()));\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n\ncontract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n\n vm.prank(alice);\n setter = new XDomainSetter();\n }\n\n function test_depositTransaction_crossDomainOwner_succeeds() external {\n vm.recordLogs();\n\n vm.prank(alice);\n op.depositTransaction({\n _to: address(setter),\n _value: 0,\n _gasLimit: 30_000,\n _isCreation: false,\n _data: abi.encodeWithSelector(XDomainSetter.set.selector, 1)\n });\n\n // Simulate the operation of the `op-node` by parsing data\n // from logs\n VmSafe.Log[] memory logs = vm.getRecordedLogs();\n // Only 1 log emitted\n assertEq(logs.length, 1);\n\n VmSafe.Log memory log = logs[0];\n\n // It is the expected topic\n bytes32 topic = log.topics[0];\n assertEq(topic, keccak256(\"TransactionDeposited(address,address,uint256,bytes)\"));\n\n // from is indexed and the first argument to the event.\n bytes32 _from = log.topics[1];\n address from = Bytes32AddressLib.fromLast20Bytes(_from);\n\n assertEq(AddressAliasHelper.undoL1ToL2Alias(from), alice);\n\n // Make a call from the \"from\" value received from the log.\n // In theory the opaque data could be parsed from the log\n // and passed to a low level call to \"to\", but calling set\n // directly on the setter is good enough.\n vm.prank(from);\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable2.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable2 } from \"../L2/CrossDomainOwnable2.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter2 is CrossDomainOwnable2 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable2_Test is Messenger_Initializer {\n XDomainSetter2 setter;\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter2();\n }\n\n function test_onlyOwner_notMessenger_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice));\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the owner\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner2_reverts() external {\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_onlyOwner_succeeds() external {\n address owner = setter.owner();\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n owner,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter2.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable3.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable3 } from \"../L2/CrossDomainOwnable3.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter3 is CrossDomainOwnable3 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable3_Test is Messenger_Initializer {\n XDomainSetter3 setter;\n\n /**\n * @notice OpenZeppelin Ownable.sol transferOwnership event\n */\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @notice CrossDomainOwnable3.sol transferOwnership event\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter3();\n }\n\n function test_constructor_succeeds() public {\n assertEq(setter.owner(), alice);\n assertEq(setter.isLocal(), true);\n }\n\n function test_localOnlyOwner_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_transferOwnership_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n }\n\n function test_crossDomainOnlyOwner_notOwner_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob);\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_crossDomainOnlyOwner_notOwner2_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter3.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_crossDomainOnlyOwner_notMessenger_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_transferOwnership_zeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"CrossDomainOwnable3: new owner is the zero address\");\n setter.transferOwnership({ _owner: address(0), _isLocal: true });\n }\n\n function test_transferOwnership_noLocalZeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"Ownable: new owner is the zero address\");\n setter.transferOwnership(address(0));\n }\n\n function test_localOnlyOwner_succeeds() public {\n assertEq(setter.isLocal(), true);\n vm.prank(setter.owner());\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n\n function test_localTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, true);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n\n assertEq(setter.isLocal(), true);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n /**\n * @notice The existing transferOwnership(address) method\n * still exists on the contract\n */\n function test_transferOwnershipNoLocal_succeeds() public {\n bool isLocal = setter.isLocal();\n\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n\n vm.prank(setter.owner());\n setter.transferOwnership(bob);\n\n // isLocal has not changed\n assertEq(setter.isLocal(), isLocal);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n function test_crossDomainTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n bob,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter3.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/DeployerWhitelist.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { DeployerWhitelist } from \"../legacy/DeployerWhitelist.sol\";\n\ncontract DeployerWhitelist_Test is CommonTest {\n DeployerWhitelist list;\n\n function setUp() public virtual override {\n list = new DeployerWhitelist();\n }\n\n // The owner should be address(0)\n function test_owner_succeeds() external {\n assertEq(list.owner(), address(0));\n }\n\n // The storage slot for the owner must be the same\n function test_storageSlots_succeeds() external {\n vm.prank(list.owner());\n list.setOwner(address(1));\n\n assertEq(bytes32(uint256(1)), vm.load(address(list), bytes32(uint256(0))));\n }\n}\n" - }, - "contracts/test/Encoding.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Encoding_Test is CommonTest {\n function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external {\n (uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(\n Encoding.encodeVersionedNonce(_nonce, _version)\n );\n assertEq(version, _version);\n assertEq(nonce, _nonce);\n }\n\n function testDiff_decodeVersionedNonce_succeeds(uint240 _nonce, uint16 _version) external {\n uint256 nonce = uint256(Encoding.encodeVersionedNonce(_nonce, _version));\n (uint256 decodedNonce, uint256 decodedVersion) = ffi.decodeVersionedNonce(nonce);\n\n assertEq(_version, uint16(decodedVersion));\n\n assertEq(_nonce, uint240(decodedNonce));\n }\n\n function testDiff_encodeCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint8 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint8 version = _version % 2;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory encoding = Encoding.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n bytes memory _encoding = ffi.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n assertEq(encoding, _encoding);\n }\n\n function testFuzz_encodeCrossDomainMessageV0_matchesLegacy_succeeds(\n uint240 _nonce,\n address _sender,\n address _target,\n bytes memory _data\n ) external {\n uint8 version = 0;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory legacyEncoding = LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _data,\n nonce\n );\n\n bytes memory bedrockEncoding = Encoding.encodeCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n nonce\n );\n\n assertEq(legacyEncoding, bedrockEncoding);\n }\n\n function testDiff_encodeDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bool isCreate,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n Types.UserDepositTransaction memory t = Types.UserDepositTransaction(\n _from,\n _to,\n isCreate,\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n );\n\n bytes memory txn = Encoding.encodeDepositTransaction(t);\n bytes memory _txn = ffi.encodeDepositTransaction(t);\n\n assertEq(txn, _txn);\n }\n}\n" - }, - "contracts/test/FeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { L1FeeVault } from \"../L2/L1FeeVault.sol\";\nimport { BaseFeeVault } from \"../L2/BaseFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n// Test the implementations of the FeeVault\ncontract FeeVault_Test is Bridge_Initializer {\n BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));\n L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT));\n\n address constant recipient = address(0x10000);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.BASE_FEE_VAULT, address(new BaseFeeVault(recipient)).code);\n vm.etch(Predeploys.L1_FEE_VAULT, address(new L1FeeVault(recipient)).code);\n\n vm.label(Predeploys.BASE_FEE_VAULT, \"BaseFeeVault\");\n vm.label(Predeploys.L1_FEE_VAULT, \"L1FeeVault\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(baseFeeVault.RECIPIENT(), recipient);\n assertEq(l1FeeVault.RECIPIENT(), recipient);\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n}\n" - }, - "contracts/test/GasPriceOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GasPriceOracle } from \"../L2/GasPriceOracle.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract GasPriceOracle_Test is CommonTest {\n event OverheadUpdated(uint256);\n event ScalarUpdated(uint256);\n event DecimalsUpdated(uint256);\n\n GasPriceOracle gasOracle;\n L1Block l1Block;\n address depositor;\n\n // set the initial L1 context values\n uint64 constant number = 10;\n uint64 constant timestamp = 11;\n uint256 constant basefee = 100;\n bytes32 constant hash = bytes32(uint256(64));\n uint64 constant sequenceNumber = 0;\n bytes32 constant batcherHash = bytes32(uint256(777));\n uint256 constant l1FeeOverhead = 310;\n uint256 constant l1FeeScalar = 10;\n\n function setUp() public virtual override {\n super.setUp();\n // place the L1Block contract at the predeploy address\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n\n l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n depositor = l1Block.DEPOSITOR_ACCOUNT();\n\n // We are not setting the gas oracle at its predeploy\n // address for simplicity purposes. Nothing in this test\n // requires it to be at a particular address\n gasOracle = new GasPriceOracle();\n\n vm.prank(depositor);\n l1Block.setL1BlockValues({\n _number: number,\n _timestamp: timestamp,\n _basefee: basefee,\n _hash: hash,\n _sequenceNumber: sequenceNumber,\n _batcherHash: batcherHash,\n _l1FeeOverhead: l1FeeOverhead,\n _l1FeeScalar: l1FeeScalar\n });\n }\n\n function test_l1BaseFee_succeeds() external {\n assertEq(gasOracle.l1BaseFee(), basefee);\n }\n\n function test_gasPrice_succeeds() external {\n vm.fee(100);\n uint256 gasPrice = gasOracle.gasPrice();\n assertEq(gasPrice, 100);\n }\n\n function test_baseFee_succeeds() external {\n vm.fee(64);\n uint256 gasPrice = gasOracle.baseFee();\n assertEq(gasPrice, 64);\n }\n\n function test_scalar_succeeds() external {\n assertEq(gasOracle.scalar(), l1FeeScalar);\n }\n\n function test_overhead_succeeds() external {\n assertEq(gasOracle.overhead(), l1FeeOverhead);\n }\n\n function test_decimals_succeeds() external {\n assertEq(gasOracle.decimals(), 6);\n assertEq(gasOracle.DECIMALS(), 6);\n }\n\n // Removed in bedrock\n function test_setGasPrice_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setGasPrice(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n\n // Removed in bedrock\n function test_setL1BaseFee_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setL1BaseFee(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n}\n" - }, - "contracts/test/GovernanceToken.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract GovernanceToken_Test is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n\n function setUp() public virtual override {\n super.setUp();\n vm.prank(owner);\n gov = new GovernanceToken();\n }\n\n function test_constructor_succeeds() external {\n assertEq(gov.owner(), owner);\n assertEq(gov.name(), \"Optimism\");\n assertEq(gov.symbol(), \"OP\");\n assertEq(gov.decimals(), 18);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_mint_fromOwner_succeeds() external {\n // Mint 100 tokens.\n vm.prank(owner);\n gov.mint(owner, 100);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 100);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_mint_fromNotOwner_reverts() external {\n // Mint 100 tokens as rando.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n gov.mint(owner, 100);\n\n // Balance does not update.\n assertEq(gov.balanceOf(owner), 0);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_burn_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando burns their tokens.\n vm.prank(rando);\n gov.burn(50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_burnFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to burn 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner burns 50 tokens from rando.\n vm.prank(owner);\n gov.burnFrom(rando, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_transfer_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando transfers 50 tokens to owner.\n vm.prank(rando);\n gov.transfer(owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_approve_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n\n function test_transferFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner transfers 50 tokens from rando to owner.\n vm.prank(owner);\n gov.transferFrom(rando, owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_increaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Rando increases allowance by 50 tokens.\n vm.prank(rando);\n gov.increaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 100);\n }\n\n function test_decreaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 100 tokens.\n vm.prank(rando);\n gov.approve(owner, 100);\n\n // Rando decreases allowance by 50 tokens.\n vm.prank(rando);\n gov.decreaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n}\n" - }, - "contracts/test/Hashing.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Hashing_hashDepositSource_Test is CommonTest {\n /**\n * @notice Tests that hashDepositSource returns the correct hash in a simple case.\n */\n function test_hashDepositSource_succeeds() external {\n assertEq(\n Hashing.hashDepositSource(\n 0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,\n 0x1\n ),\n 0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc\n );\n }\n}\n\ncontract Hashing_hashCrossDomainMessage_Test is CommonTest {\n /**\n * @notice Tests that hashCrossDomainMessage returns the correct hash in a simple case.\n */\n function testDiff_hashCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint16 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Ensure the version is valid.\n uint16 version = uint16(bound(uint256(_version), 0, 1));\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n assertEq(\n Hashing.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data),\n ffi.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n\n /**\n * @notice Tests that hashCrossDomainMessageV0 matches the hash of the legacy encoding.\n */\n function testFuzz_hashCrossDomainMessageV0_matchesLegacy_succeeds(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) external {\n assertEq(\n keccak256(\n LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _message,\n _messageNonce\n )\n ),\n Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _messageNonce)\n );\n }\n}\n\ncontract Hashing_hashWithdrawal_Test is CommonTest {\n /**\n * @notice Tests that hashWithdrawal returns the correct hash in a simple case.\n */\n function testDiff_hashWithdrawal_succeeds(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n assertEq(\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)\n ),\n ffi.hashWithdrawal(_nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n}\n\ncontract Hashing_hashOutputRootProof_Test is CommonTest {\n /**\n * @notice Tests that hashOutputRootProof returns the correct hash in a simple case.\n */\n function testDiff_hashOutputRootProof_succeeds(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external {\n assertEq(\n Hashing.hashOutputRootProof(\n Types.OutputRootProof({\n version: _version,\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _messagePasserStorageRoot,\n latestBlockhash: _latestBlockhash\n })\n ),\n ffi.hashOutputRootProof(\n _version,\n _stateRoot,\n _messagePasserStorageRoot,\n _latestBlockhash\n )\n );\n }\n}\n\ncontract Hashing_hashDepositTransaction_Test is CommonTest {\n /**\n * @notice Tests that hashDepositTransaction returns the correct hash in a simple case.\n */\n function testDiff_hashDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n assertEq(\n Hashing.hashDepositTransaction(\n Types.UserDepositTransaction(\n _from,\n _to,\n false, // isCreate\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n )\n ),\n ffi.hashDepositTransaction(_from, _to, _mint, _value, _gas, _data, _logIndex)\n );\n }\n}\n" - }, - "contracts/test/L1Block.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\ncontract L1BlockTest is CommonTest {\n L1Block lb;\n address depositor;\n bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));\n\n function setUp() public virtual override {\n super.setUp();\n lb = new L1Block();\n depositor = lb.DEPOSITOR_ACCOUNT();\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: uint64(1),\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: NON_ZERO_HASH,\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(0),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function testFuzz_updatesValues_succeeds(\n uint64 n,\n uint64 t,\n uint256 b,\n bytes32 h,\n uint64 s,\n bytes32 bt,\n uint256 fo,\n uint256 fs\n ) external {\n vm.prank(depositor);\n lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs);\n assertEq(lb.number(), n);\n assertEq(lb.timestamp(), t);\n assertEq(lb.basefee(), b);\n assertEq(lb.hash(), h);\n assertEq(lb.sequenceNumber(), s);\n assertEq(lb.batcherHash(), bt);\n assertEq(lb.l1FeeOverhead(), fo);\n assertEq(lb.l1FeeScalar(), fs);\n }\n\n function test_number_succeeds() external {\n assertEq(lb.number(), uint64(1));\n }\n\n function test_timestamp_succeeds() external {\n assertEq(lb.timestamp(), uint64(2));\n }\n\n function test_basefee_succeeds() external {\n assertEq(lb.basefee(), 3);\n }\n\n function test_hash_succeeds() external {\n assertEq(lb.hash(), NON_ZERO_HASH);\n }\n\n function test_sequenceNumber_succeeds() external {\n assertEq(lb.sequenceNumber(), uint64(4));\n }\n\n function test_updateValues_succeeds() external {\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: type(uint64).max,\n _timestamp: type(uint64).max,\n _basefee: type(uint256).max,\n _hash: keccak256(abi.encode(1)),\n _sequenceNumber: type(uint64).max,\n _batcherHash: bytes32(type(uint256).max),\n _l1FeeOverhead: type(uint256).max,\n _l1FeeScalar: type(uint256).max\n });\n }\n}\n" - }, - "contracts/test/L1BlockNumber.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { L1BlockNumber } from \"../legacy/L1BlockNumber.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract L1BlockNumberTest is Test {\n L1Block lb;\n L1BlockNumber bn;\n\n uint64 constant number = 99;\n\n function setUp() external {\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n lb = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n bn = new L1BlockNumber();\n vm.prank(lb.DEPOSITOR_ACCOUNT());\n\n lb.setL1BlockValues({\n _number: number,\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: bytes32(uint256(10)),\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(uint256(0)),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function test_getL1BlockNumber_succeeds() external {\n assertEq(bn.getL1BlockNumber(), number);\n }\n\n function test_fallback_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n\n function test_receive_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call{ value: 1 }(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n}\n" - }, - "contracts/test/L1CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle_Initializer } from \"./L2OutputOracle.t.sol\";\n\n/* Libraries */\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n/* Target contract dependencies */\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/* Target contract */\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\n\ncontract L1CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n // the version is encoded in the nonce\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce());\n assertEq(version, L1Messenger.MESSAGE_VERSION());\n }\n\n // sendMessage: should be able to send a single message\n // TODO: this same test needs to be done with the legacy message type\n // by setting the message version to 0\n function test_sendMessage_succeeds() external {\n // deposit transaction on the optimism portal should be called\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n )\n );\n\n // TransactionDeposited event\n vm.expectEmit(true, true, true, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n );\n\n // SentMessage event\n vm.expectEmit(true, true, true, true);\n emit SentMessage(recipient, alice, hex\"ff\", L1Messenger.messageNonce(), 100);\n\n // SentMessageExtension1 event\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(alice, 0);\n\n vm.prank(alice);\n L1Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n // sendMessage: should be able to send the same message twice\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L1Messenger.messageNonce());\n }\n\n function test_xDomainSender_notSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(address(op));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n // relayMessage: should send a successful call to the target contract\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.expectCall(target, hex\"1111\");\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n // set the target to be the OptimismPortal\n address target = address(op);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.prank(address(op));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n\n vm.store(address(op), 0, bytes32(abi.encode(sender)));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: should revert if eth is sent from a contract other than the standard bridge\n function test_replayMessage_withValue_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.expectRevert(\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n L1Messenger.relayMessage{ value: 100 }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n vm.expectCall(target, hex\"1111\");\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacy_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyOldReplay_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Mark legacy message as already relayed.\n uint256 successfulMessagesSlot = 203;\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex\"1111\", 0);\n bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot));\n vm.store(address(L1Messenger), slot, bytes32(uint256(1)));\n\n // Expect revert.\n vm.expectRevert(\"CrossDomainMessenger: legacy withdrawal already relayed\");\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was not relayed.\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyRetryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect FailedRelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacyRetryAfterSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message has already been relayed\");\n\n // Retry the message again.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n}\n" - }, - "contracts/test/L1ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L1ERC721Bridge_Test is Messenger_Initializer {\n TestERC721 internal localToken;\n TestERC721 internal remoteToken;\n L1ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L1ERC721Bridge(address(L1Messenger), otherBridge);\n localToken = new TestERC721();\n remoteToken = new TestERC721();\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L1ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L1Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L1Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notEscrowed_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n" - }, - "contracts/test/L1StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\n\ncontract L1StandardBridge_Getter_Test is Bridge_Initializer {\n function test_getters_succeeds() external {\n assert(L1Bridge.l2TokenBridge() == address(L2Bridge));\n assert(L1Bridge.OTHER_BRIDGE() == L2Bridge);\n assert(L1Bridge.messenger() == L1Messenger);\n assert(L1Bridge.MESSENGER() == L1Messenger);\n assertEq(L1Bridge.version(), \"1.1.0\");\n }\n}\n\ncontract L1StandardBridge_Initialize_Test is Bridge_Initializer {\n function test_initialize_succeeds() external {\n assertEq(address(L1Bridge.messenger()), address(L1Messenger));\n\n assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE);\n\n assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE);\n }\n}\n\ncontract L1StandardBridge_Initialize_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_Receive_Test is Bridge_Initializer {\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(op).balance, 0);\n\n // The legacy event must be emitted for backwards compatibility\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n ),\n 200_000\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L1Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(op).balance, 100);\n }\n}\n\ncontract L1StandardBridge_Receive_TestFail {}\n\ncontract PreBridgeETH is Bridge_Initializer {\n function _preBridgeETH(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 500,\n hex\"dead\"\n );\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex\"dead\")\n );\n }\n vm.expectCall(\n address(L1Messenger),\n 500,\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 50000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 500,\n 50000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 50000);\n vm.expectCall(\n address(op),\n 500,\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 500,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(500),\n uint256(500),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 500, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 500, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 50000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 500);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETH_Test is PreBridgeETH {\n // depositETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_depositETH_succeeds() external {\n _preBridgeETH({ isLegacy: true });\n L1Bridge.depositETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_BridgeETH_Test is PreBridgeETH {\n // BridgeETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETH_succeeds() external {\n _preBridgeETH({ isLegacy: false });\n L1Bridge.bridgeETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer {\n function test_depositETH_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, address(L1Token).code);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice);\n L1Bridge.depositETH{ value: 1 }(300, hex\"\");\n }\n}\n\ncontract PreBridgeETHTo is Bridge_Initializer {\n function _preBridgeETHTo(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex\"dead\")\n );\n }\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n bob,\n 600,\n hex\"dead\"\n );\n\n // the L1 bridge should call\n // L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 60000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 600,\n 60000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 60000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 600,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(600),\n uint256(600),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, bob, 600, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, bob, 600, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 60000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 600);\n\n // deposit eth to bob\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo {\n // depositETHTo\n // - emits ETHDepositInitiated\n // - calls optimismPortal.depositTransaction\n // - EOA or contract can call\n // - ETH ends up in the optimismPortal\n function test_depositETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: true });\n L1Bridge.depositETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo {\n // BridgeETHTo\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: false });\n L1Bridge.bridgeETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // depositERC20\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - only callable by EOA\n function test_depositERC20_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Deal Alice's ERC20 State\n deal(address(L1Token), alice, 100000, true);\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n // The L1Bridge should transfer alice's tokens to itself\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)\n );\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n vm.prank(alice);\n L1Bridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex\"\");\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n }\n}\n\ncontract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer {\n function test_depositERC20_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, hex\"ffff\");\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice, alice);\n L1Bridge.depositERC20(address(0), address(0), 100, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {\n // depositERC20To\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - callable by a contract\n function test_depositERC20To_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n bob,\n 1000,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n deal(address(L1Token), alice, 100000, true);\n\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)\n );\n\n vm.prank(alice);\n L1Bridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex\"\");\n\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 1000);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeETHWithdrawal\n // - emits ETHWithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeETHWithdrawal_succeeds() external {\n uint256 aliceBalance = alice.balance;\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHWithdrawalFinalized(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n vm.expectCall(alice, hex\"\");\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n // ensure that the messenger has ETH to call with\n vm.deal(address(L1Bridge.messenger()), 100);\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n\n assertEq(address(L1Bridge.messenger()).balance, 0);\n assertEq(aliceBalance + 100, alice.balance);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeERC20Withdrawal\n // - updates bridge.deposits\n // - emits ERC20WithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeERC20Withdrawal_succeeds() external {\n deal(address(L1Token), address(L1Bridge), 100, true);\n\n uint256 slot = stdstore\n .target(address(L1Bridge))\n .sig(\"deposits(address,address)\")\n .with_key(address(L1Token))\n .with_key(address(L2Token))\n .find();\n\n // Give the L1 bridge some ERC20 tokens\n vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)\n );\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n assertEq(L1Token.balanceOf(address(L1Bridge)), 0);\n assertEq(L1Token.balanceOf(address(alice)), 100);\n }\n}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer {\n function test_finalizeERC20Withdrawal_notMessenger_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(28));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n\n function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(address(0)))\n );\n vm.prank(address(L1Bridge.messenger()));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer {\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L1Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L1Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce());\n assertEq(version, L2Messenger.MESSAGE_VERSION());\n }\n\n function test_sendMessage_succeeds() external {\n bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage(\n L2Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n );\n vm.expectCall(\n address(messagePasser),\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData\n )\n );\n\n // MessagePassed event\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(L2Messenger),\n address(L1Messenger),\n 0,\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData,\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messagePasser.messageNonce(),\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: L2Messenger.baseGas(hex\"ff\", 100),\n data: xDomainCallData\n })\n )\n );\n\n vm.prank(alice);\n L2Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L2Messenger.messageNonce();\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L2Messenger.messageNonce());\n }\n\n function test_xDomainSender_senderNotSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 2), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n vm.expectCall(target, hex\"1111\");\n\n vm.prank(caller);\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L2Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L2Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n address target = address(messagePasser);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory message = hex\"1111\";\n\n vm.prank(caller);\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retry_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n uint256 value = 100;\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(caller), value);\n vm.prank(caller);\n L2Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L2Messenger.successfulMessages(hash), false);\n assertEq(L2Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L2Messenger.successfulMessages(hash), true);\n assertEq(L2Messenger.failedMessages(hash), true);\n }\n}\n" - }, - "contracts/test/L2ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract TestMintableERC721 is OptimismMintableERC721 {\n constructor(address _bridge, address _remoteToken)\n OptimismMintableERC721(_bridge, 1, _remoteToken, \"Test\", \"TST\")\n {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L2ERC721Bridge_Test is Messenger_Initializer {\n TestMintableERC721 internal localToken;\n TestERC721 internal remoteToken;\n L2ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L2ERC721Bridge(address(L2Messenger), otherBridge);\n remoteToken = new TestERC721();\n localToken = new TestMintableERC721(address(bridge), address(remoteToken));\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L2ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L2Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L2Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L1ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_interfaceNotCompliant_reverts() external {\n // Create a non-compliant token\n NonCompliantERC721 nonCompliantToken = new NonCompliantERC721(alice);\n\n // Bridge the non-compliant token.\n vm.prank(alice);\n bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex\"5678\");\n\n // Attempt to finalize the withdrawal. Should revert because the token does not claim\n // to be compliant with the `IOptimismMintableERC721` interface.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token interface is not compliant\");\n bridge.finalizeBridgeERC721(\n address(address(nonCompliantToken)),\n address(address(0x01)),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_alreadyExists_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721: token already minted\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n\n/**\n * @dev A non-compliant ERC721 token that does not implement the full ERC721 interface.\n *\n * This is used to test that the bridge will revert if the token does not claim to support\n * the ERC721 interface.\n */\ncontract NonCompliantERC721 {\n address internal immutable owner;\n\n constructor(address _owner) {\n owner = _owner;\n }\n\n function ownerOf(uint256) external view returns (address) {\n return owner;\n }\n\n function remoteToken() external pure returns (address) {\n return address(0x01);\n }\n\n function burn(address, uint256) external {\n // Do nothing.\n }\n\n function supportsInterface(bytes4) external pure returns (bool) {\n return false;\n }\n}\n" - }, - "contracts/test/L2OutputOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { L2OutputOracle_Initializer, NextImpl } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2OutputOracleTest is L2OutputOracle_Initializer {\n bytes32 proposedOutput1 = keccak256(abi.encode(1));\n\n function test_constructor_succeeds() external {\n assertEq(oracle.PROPOSER(), proposer);\n assertEq(oracle.CHALLENGER(), owner);\n assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);\n assertEq(oracle.latestBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingTimestamp(), startingTimestamp);\n }\n\n function test_constructor_badTimestamp_reverts() external {\n vm.expectRevert(\"L2OutputOracle: starting L2 timestamp must be less than current time\");\n\n // startingTimestamp is in the future\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp + 1,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function test_constructor_l2BlockTimeZero_reverts() external {\n vm.expectRevert(\"L2OutputOracle: L2 block time must be greater than 0\");\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: 0,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function test_constructor_submissionInterval_reverts() external {\n vm.expectRevert(\"L2OutputOracle: submission interval must be greater than 0\");\n new L2OutputOracle({\n _submissionInterval: 0,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n /****************\n * Getter Tests *\n ****************/\n\n // Test: latestBlockNumber() should return the correct value\n function test_latestBlockNumber_succeeds() external {\n uint256 proposedNumber = oracle.nextBlockNumber();\n\n // Roll to after the block number we'll propose\n warpToProposeTime(proposedNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0);\n assertEq(oracle.latestBlockNumber(), proposedNumber);\n }\n\n // Test: getL2Output() should return the correct value\n function test_getL2Output_succeeds() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0);\n\n Types.OutputProposal memory proposal = oracle.getL2Output(nextOutputIndex);\n assertEq(proposal.outputRoot, proposedOutput1);\n assertEq(proposal.timestamp, block.timestamp);\n\n // The block number is larger than the latest proposed output:\n vm.expectRevert(stdError.indexOOBError);\n oracle.getL2Output(nextOutputIndex + 1);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is exact block\n function test_getL2OutputIndexAfter_sameBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with exact same block as proposed returns the proposal.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is previous block\n function test_getL2OutputIndexAfter_previousBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with previous block returns the proposal too.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 - 1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value during binary search\n function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n bytes32 output2 = keccak256(abi.encode(2));\n uint256 nextBlockNumber2 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber2);\n vm.prank(proposer);\n oracle.proposeL2Output(output2, nextBlockNumber2, 0, 0);\n\n bytes32 output3 = keccak256(abi.encode(3));\n uint256 nextBlockNumber3 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber3);\n vm.prank(proposer);\n oracle.proposeL2Output(output3, nextBlockNumber3, 0, 0);\n\n bytes32 output4 = keccak256(abi.encode(4));\n uint256 nextBlockNumber4 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber4);\n vm.prank(proposer);\n oracle.proposeL2Output(output4, nextBlockNumber4, 0, 0);\n\n // Querying with a block number between the first and second proposal\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 + 1);\n assertEq(index1, 1);\n\n // Querying with a block number between the second and third proposal\n uint256 index2 = oracle.getL2OutputIndexAfter(nextBlockNumber2 + 1);\n assertEq(index2, 2);\n\n // Querying with a block number between the third and fourth proposal\n uint256 index3 = oracle.getL2OutputIndexAfter(nextBlockNumber3 + 1);\n assertEq(index3, 3);\n }\n\n // Test: getL2OutputIndexAfter() reverts when no output exists yet\n function test_getL2OutputIndexAfter_noOutputsExis_reverts() external {\n vm.expectRevert(\"L2OutputOracle: cannot get output as no outputs have been proposed yet\");\n oracle.getL2OutputIndexAfter(0);\n }\n\n // Test: nextBlockNumber() should return the correct value\n function test_nextBlockNumber_succeeds() external {\n assertEq(\n oracle.nextBlockNumber(),\n // The return value should match this arithmetic\n oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL()\n );\n }\n\n function test_computeL2Timestamp_succeeds() external {\n // reverts if timestamp is too low\n vm.expectRevert(stdError.arithmeticError);\n oracle.computeL2Timestamp(startingBlockNumber - 1);\n\n // returns the correct value...\n // ... for the very first block\n assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);\n\n // ... for the first block after the starting block\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 1),\n startingTimestamp + l2BlockTime\n );\n\n // ... for some other block number\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 96024),\n startingTimestamp + l2BlockTime * 96024\n );\n }\n\n /*****************************\n * Propose Tests - Happy Path *\n *****************************/\n\n // Test: proposeL2Output succeeds when given valid input, and no block hash and number are\n // specified.\n function test_proposeL2Output_proposeAnotherOutput_succeeds() public {\n bytes32 proposedOutput2 = keccak256(abi.encode());\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n uint256 proposedNumber = oracle.latestBlockNumber();\n\n // Ensure the submissionInterval is enforced\n assertEq(nextBlockNumber, proposedNumber + submissionInterval);\n\n vm.roll(nextBlockNumber + 1);\n\n vm.expectEmit(true, true, true, true);\n emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp);\n\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output succeeds when given valid input, and when a block hash and number are\n // specified for reorg protection.\n function test_proposeWithBlockhashAndHeight_succeeds() external {\n // Get the number and hash of a previous block in the chain\n uint256 prevL1BlockNumber = block.number - 1;\n bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber);\n }\n\n /***************************\n * Propose Tests - Sad Path *\n ***************************/\n\n // Test: proposeL2Output fails if called by a party that is not the proposer.\n function test_proposeL2Output_notProposer_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n\n vm.prank(address(128));\n vm.expectRevert(\"L2OutputOracle: only the proposer address can propose new outputs\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails given a zero blockhash.\n function test_proposeL2Output_emptyOutput_reverts() external {\n bytes32 outputToPropose = bytes32(0);\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: L2 output proposal cannot be the zero hash\");\n oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if the block number doesn't match the next expected number.\n function test_proposeL2Output_unexpectedBlockNumber_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: block number must be equal to next expected block number\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);\n }\n\n // Test: proposeL2Output fails if it would have a timestamp in the future.\n function test_proposeL2Output_futureTimetamp_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber);\n vm.warp(nextTimestamp);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: cannot propose L2 output in the future\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if a non-existent L1 block hash and number are provided for reorg\n // protection.\n function test_proposeL2Output_wrongFork_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(\n nonZeroHash,\n nextBlockNumber,\n bytes32(uint256(0x01)),\n block.number - 1\n );\n }\n\n // Test: proposeL2Output fails when given valid input, but the block hash and number do not\n // match.\n function test_proposeL2Output_unmatchedBlockhash_reverts() external {\n // Move ahead to block 100 so that we can reference historical blocks\n vm.roll(100);\n\n // Get the number and hash of a previous block in the chain\n uint256 l1BlockNumber = block.number - 1;\n bytes32 l1BlockHash = blockhash(l1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n\n // This will fail when foundry no longer returns zerod block hashes\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);\n }\n\n /*****************************\n * Delete Tests - Happy Path *\n *****************************/\n\n function test_deleteOutputs_singleOutput_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 1);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex);\n oracle.deleteL2Outputs(latestOutputIndex);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n function test_deleteOutputs_multipleOutputs_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 3);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n /***************************\n * Delete Tests - Sad Path *\n ***************************/\n\n function test_deleteL2Outputs_ifNotChallenger_reverts() external {\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.expectRevert(\"L2OutputOracle: only the challenger address can delete outputs\");\n oracle.deleteL2Outputs(latestBlockNumber);\n }\n\n function test_deleteL2Outputs_nonExistent_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestBlockNumber + 1);\n }\n\n function test_deleteL2Outputs_afterLatest_reverts() external {\n // Start by proposing three outputs\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Delete the latest two outputs\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n vm.prank(owner);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // Now try to delete the same output again\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n }\n\n function test_deleteL2Outputs_finalized_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Warp past the finalization period + 1 second\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n\n // Try to delete a finalized output\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs that have already been finalized\");\n oracle.deleteL2Outputs(latestOutputIndex);\n }\n}\n\ncontract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {\n Proxy internal proxy;\n\n function setUp() public override {\n super.setUp();\n proxy = Proxy(payable(address(oracle)));\n }\n\n function test_initValuesOnProxy_succeeds() external {\n assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());\n assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());\n assertEq(startingBlockNumber, oracleImpl.startingBlockNumber());\n assertEq(startingTimestamp, oracleImpl.startingTimestamp());\n\n assertEq(proposer, oracleImpl.PROPOSER());\n assertEq(owner, oracleImpl.CHALLENGER());\n }\n\n function test_initializeProxy_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(payable(proxy)).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_initializeImpl_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(oracleImpl).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(oracle), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(oracle), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(oracle)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/L2StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { console } from \"forge-std/console.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\ncontract L2StandardBridge_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n function test_initialize_succeeds() external {\n assertEq(address(L2Bridge.messenger()), address(L2Messenger));\n assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge));\n assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge));\n }\n\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(messagePasser).balance, 0);\n uint256 nonce = L2Messenger.messageNonce();\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 200_000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 100,\n 200_000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 100,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n // L2ToL1MessagePasser will emit a MessagePassed event\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 100,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 200_000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 100);\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L2Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(messagePasser).balance, 100);\n }\n\n // withrdraw\n // - requires amount == msg.value\n function test_withdraw_insufficientValue_reverts() external {\n assertEq(address(messagePasser).balance, 0);\n\n vm.expectRevert(\"StandardBridge: bridging ETH must include sufficient ETH value\");\n vm.prank(alice, alice);\n L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex\"\");\n }\n\n /**\n * @notice Use the legacy `withdraw` interface on the L2StandardBridge to\n * withdraw ether from L2 to L1.\n */\n function test_withdraw_ether_succeeds() external {\n assertTrue(alice.balance >= 100);\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0);\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated({\n l1Token: address(0),\n l2Token: Predeploys.LEGACY_ERC20_ETH,\n from: alice,\n to: alice,\n amount: 100,\n data: hex\"\"\n });\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex\"\" });\n\n vm.prank(alice, alice);\n L2Bridge.withdraw{ value: 100 }({\n _l2Token: Predeploys.LEGACY_ERC20_ETH,\n _amount: 100,\n _minGasLimit: 1000,\n _extraData: hex\"\"\n });\n\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 100);\n }\n}\n\ncontract PreBridgeERC20 is Bridge_Initializer {\n // withdraw and BridgeERC20 should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20(bool _isLegacy, address _l2Token) internal {\n // Alice has 100 L2Token\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(_l2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex\"\")\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20.selector,\n _l2Token,\n address(L1Token),\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n _l2Token,\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {\n // withdraw\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_withdraw_withdrawingERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // BridgeERC20\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdrawLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) });\n L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_bridgeLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) });\n L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdraw_notEOA_reverts() external {\n // This contract has 100 L2Token\n deal(address(L2Token), address(this), 100, true);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n }\n}\n\ncontract PreBridgeERC20To is Bridge_Initializer {\n // withdrawTo and BridgeERC20To should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal {\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(L2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n bob,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.withdrawTo.selector,\n _l2Token,\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20To.selector,\n _l2Token,\n address(L1Token),\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {\n // withdrawTo\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_withdrawTo_withdrawingERC20_succeeds() external {\n _preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // bridgeERC20To\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20To_succeeds() external {\n _preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex\"\");\n assertEq(L2Token.balanceOf(alice), 0);\n }\n}\n\ncontract L2StandardBridge_Bridge_Test is Bridge_Initializer {\n // finalizeDeposit\n // - only callable by l1TokenBridge\n // - supported token pair emits DepositFinalized\n // - invalid deposit calls Withdrawer.initiateWithdrawal\n function test_finalizeDeposit_depositingERC20_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex\"\");\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeDeposit_depositingETH_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(\n address(L2Token), // localToken\n address(L1Token), // remoteToken\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Messenger), 100, hex\"\");\n }\n}\n\ncontract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L2Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true);\n emit DepositFinalized(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2ToL1MessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\n\ncontract L2ToL1MessagePasserTest is CommonTest {\n L2ToL1MessagePasser messagePasser;\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new L2ToL1MessagePasser();\n }\n\n function testFuzz_initiateWithdrawal_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint256 nonce = messagePasser.messageNonce();\n\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: _value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash);\n\n vm.deal(_sender, _value);\n vm.prank(_sender);\n messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);\n\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0)));\n\n assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1)));\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by a contract\n function test_initiateWithdrawal_fromContract_succeeds() external {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\"\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\",\n withdrawalHash\n );\n\n vm.deal(address(this), 2**64);\n messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex\"\");\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by an EOA\n function test_initiateWithdrawal_fromEOA_succeeds() external {\n uint256 gasLimit = 64000;\n address target = address(4);\n uint256 value = 100;\n bytes memory data = hex\"ff\";\n uint256 nonce = messagePasser.messageNonce();\n\n // EOA emulation\n vm.prank(alice, alice);\n vm.deal(alice, 2**64);\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data)\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash);\n\n messagePasser.initiateWithdrawal{ value: value }(target, gasLimit, data);\n\n // the sent messages mapping is filled\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n // the nonce increments\n assertEq(nonce + 1, messagePasser.messageNonce());\n }\n\n // Test: burn should destroy the ETH held in the contract\n function test_burn_succeeds() external {\n messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n NON_ZERO_GASLIMIT,\n NON_ZERO_DATA\n );\n\n assertEq(address(messagePasser).balance, NON_ZERO_VALUE);\n vm.expectEmit(true, false, false, false);\n emit WithdrawerBalanceBurnt(NON_ZERO_VALUE);\n messagePasser.burn();\n\n // The Withdrawer should have no balance\n assertEq(address(messagePasser).balance, 0);\n }\n}\n" - }, - "contracts/test/LegacyERC20ETH.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyERC20ETH_Test is CommonTest {\n LegacyERC20ETH eth;\n\n function setUp() public virtual override {\n super.setUp();\n eth = new LegacyERC20ETH();\n }\n\n function test_metadata_succeeds() external {\n assertEq(eth.name(), \"Ether\");\n assertEq(eth.symbol(), \"ETH\");\n assertEq(eth.decimals(), 18);\n }\n\n function test_crossDomain_succeeds() external {\n assertEq(eth.l2Bridge(), Predeploys.L2_STANDARD_BRIDGE);\n assertEq(eth.l1Token(), address(0));\n }\n\n function test_transfer_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transfer is disabled\");\n eth.transfer(alice, 100);\n }\n\n function test_approve_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: approve is disabled\");\n eth.approve(alice, 100);\n }\n\n function test_transferFrom_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transferFrom is disabled\");\n eth.transferFrom(bob, alice, 100);\n }\n\n function test_increaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n eth.increaseAllowance(alice, 100);\n }\n\n function test_decreaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n eth.decreaseAllowance(alice, 100);\n }\n\n function test_mint_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: mint is disabled\");\n eth.mint(alice, 100);\n }\n\n function test_burn_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: burn is disabled\");\n eth.burn(alice, 100);\n }\n}\n" - }, - "contracts/test/LegacyMessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyMessagePasser } from \"../legacy/LegacyMessagePasser.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyMessagePasser_Test is CommonTest {\n LegacyMessagePasser messagePasser;\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new LegacyMessagePasser();\n }\n\n function test_passMessageToL1_succeeds() external {\n vm.prank(alice);\n messagePasser.passMessageToL1(hex\"ff\");\n assert(messagePasser.sentMessages(keccak256(abi.encodePacked(hex\"ff\", alice))));\n }\n}\n" - }, - "contracts/test/MerkleTrie.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MerkleTrie } from \"../libraries/trie/MerkleTrie.sol\";\n\ncontract MerkleTrie_get_Test is CommonTest {\n function test_get_validProof1_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579326262\";\n bytes memory val = hex\"6176616c32\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof2_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[\n 2\n ] = hex\"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof3_succeeds() external {\n bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof4_succeeds() external {\n bytes32 root = 0x37956bab6bba472308146808d5311ac19cb4a7daae5df7efcc0f32badc97f55e;\n bytes memory key = hex\"6b6579316161\";\n bytes memory val = hex\"3031323334\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"ce87206b6579316161853031323334\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof5_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657931\";\n bytes\n memory val = hex\"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof6_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657932\";\n bytes memory val = hex\"73686f7274\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[2] = hex\"df808080808080c9823262856176616c338080808080808080808573686f7274\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof7_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657933\";\n bytes memory val = hex\"31323334353637383930313233343536373839303132333435363738393031\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof8_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"61\";\n bytes memory val = hex\"61\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22061\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof9_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"62\";\n bytes memory val = hex\"62\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22062\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof10_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"63\";\n bytes memory val = hex\"63\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22063\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_nonexistentKey1_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b657932\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_nonexistentKey2_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"616e7972616e646f6d6b6579\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_wrongKeyProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579316161\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[2] = hex\"d687206e6f746865728d33343938683472697568677765\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_corruptedProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579326262\";\n bytes[] memory proof = new bytes[](5);\n proof[0] = hex\"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[\n 2\n ] = hex\"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 3\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[4] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidDataRemainder_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa000000000000000000000000000000\";\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidInternalNodeHash_reverts() external {\n bytes32 root = 0xa827dff1a657bb9bb9a1c3abe9db173e2f1359f15eb06f1647ea21ac7c95d8fa;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157\";\n proof[\n 1\n ] = hex\"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080\";\n proof[2] = hex\"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroBranchValueLength_reverts() external {\n bytes32 root = 0xe04b3589eef96b237cd49ccb5dcf6e654a47682bfa0961d563ab843f7ad1e035;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](2);\n proof[0] = hex\"dd8200aad98080808080808080808080c43b82aabbc43c82aacc80808080\";\n proof[1] = hex\"d98080808080808080808080c43b82aabbc43c82aacc80808080\";\n\n vm.expectRevert(\"MerkleTrie: value length must be greater than zero (branch)\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroLengthKey_reverts() external {\n bytes32 root = 0x54157fd62cdf2f474e7bfec2d3cd581e807bee38488c9590cb887add98936b73;\n bytes memory key = hex\"\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"c78320f00082b443\";\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey1_reverts() external {\n bytes32 root = 0xa513ba530659356fb7588a2c831944e80fd8aedaa5a4dc36f918152be2be0605;\n bytes memory key = hex\"01\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"db10d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[1] = hex\"d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[2] = hex\"c582202381aa\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey2_reverts() external {\n bytes32 root = 0xa06abffaec4ebe8ccde595f4547b864b4421b21c1fc699973f94710c9bc17979;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905\";\n proof[\n 1\n ] = hex\"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080\";\n proof[2] = hex\"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_extraProofElements_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](4);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa\";\n proof[3] = hex\"c32081aa\";\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_validProofs_succeeds(bytes4) external {\n // Generate a test case with a valid proof of inclusion for the k/v pair in the trie.\n (bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi\n .getMerkleTrieFuzzCase(\"valid\");\n\n // Assert that our expected value is equal to our actual value.\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidRoot_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"valid\"\n );\n\n bytes32 rootHash = keccak256(abi.encodePacked(root));\n vm.expectRevert(\"MerkleTrie: invalid root hash\");\n MerkleTrie.get(key, proof, rootHash);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_extraProofElements_reverts(bytes4) external {\n // Generate an invalid test case with an extra proof element attached to an otherwise\n // valid proof of inclusion for the passed k/v.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"extra_proof_elems\"\n );\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external {\n // Generate an invalid test case where a long proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_large_internal_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid large internal hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external {\n // Generate an invalid test case where a small proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_internal_node_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_corruptedProof_reverts(bytes4) external {\n // Generate an invalid test case where the proof is malformed.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"corrupted_proof\"\n );\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidDataRemainder_reverts(bytes4) external {\n // Generate an invalid test case where a random element of the proof has more bytes than the\n // length designates within the RLP list encoding.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_data_remainder\"\n );\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_prefixedValidKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and a valid key that is prefixed\n // with random bytes\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"prefixed_valid_key\"\n );\n\n // Ambiguous revert check- all that we care is that it *does* fail. This case may\n // fail within different branches.\n vm.expectRevert();\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_emptyKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and an empty key\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"empty_key\"\n );\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_partialProof_reverts(bytes4) external {\n // Get a random test case with a valid trie / partially correct proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"partial_proof\"\n );\n\n vm.expectRevert(\"MerkleTrie: ran out of proof elements\");\n MerkleTrie.get(key, proof, root);\n }\n}\n" - }, - "contracts/test/MintManager.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MintManager } from \"../governance/MintManager.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract MintManager_Initializer is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n MintManager internal manager;\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.prank(owner);\n gov = new GovernanceToken();\n\n vm.prank(owner);\n manager = new MintManager(owner, address(gov));\n\n vm.prank(owner);\n gov.transferOwnership(address(manager));\n }\n}\n\ncontract MintManager_constructor_Test is MintManager_Initializer {\n /**\n * @notice Tests that the constructor properly configures the contract.\n */\n function test_constructor_succeeds() external {\n assertEq(manager.owner(), owner);\n assertEq(address(manager.governanceToken()), address(gov));\n }\n}\n\ncontract MintManager_mint_Test is MintManager_Initializer {\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner.\n */\n function test_mint_fromOwner_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the mint function reverts when called by a non-owner.\n */\n function test_mint_fromNotOwner_reverts() external {\n // Mint from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.mint(owner, 100);\n }\n\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner a second\n * time after the mint period has elapsed.\n */\n function test_mint_afterPeriodElapsed_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again after period elapsed (2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n manager.mint(owner, 2);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 102);\n }\n\n /**\n * @notice Tests that the mint function always reverts when called before the mint period has\n * elapsed, even if the caller is the owner.\n */\n function test_mint_beforePeriodElapsed_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: minting not permitted yet\");\n manager.mint(owner, 100);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the owner cannot mint more than the mint cap.\n */\n function test_mint_moreThanCap_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again (greater than 2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint amount exceeds cap\");\n manager.mint(owner, 3);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n}\n\ncontract MintManager_upgrade_Test is MintManager_Initializer {\n /**\n * @notice Tests that the owner can upgrade the mint manager.\n */\n function test_upgrade_fromOwner_succeeds() external {\n // Upgrade to new manager.\n vm.prank(owner);\n manager.upgrade(rando);\n\n // New manager is rando.\n assertEq(gov.owner(), rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when called by a non-owner.\n */\n function test_upgrade_fromNotOwner_reverts() external {\n // Upgrade from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.upgrade(rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when attempting to update to the zero\n * address, even if the caller is the owner.\n */\n function test_upgrade_toZeroAddress_reverts() external {\n // Upgrade to zero address fails.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint manager cannot be the zero address\");\n manager.upgrade(address(0));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport {\n ILegacyMintableERC20,\n IOptimismMintableERC20\n} from \"../universal/IOptimismMintableERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract OptimismMintableERC20_Test is Bridge_Initializer {\n event Mint(address indexed account, uint256 amount);\n event Burn(address indexed account, uint256 amount);\n\n function test_semver_succeeds() external {\n assertEq(L2Token.version(), \"1.0.0\");\n }\n\n function test_remoteToken_succeeds() external {\n assertEq(L2Token.remoteToken(), address(L1Token));\n }\n\n function test_bridge_succeeds() external {\n assertEq(L2Token.bridge(), address(L2Bridge));\n }\n\n function test_l1Token_succeeds() external {\n assertEq(L2Token.l1Token(), address(L1Token));\n }\n\n function test_l2Bridge_succeeds() external {\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_legacy_succeeds() external {\n // Getters for the remote token\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.l1Token(), address(L1Token));\n // Getters for the bridge\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_mint_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 100);\n }\n\n function test_mint_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.mint(alice, 100);\n }\n\n function test_burn_succeeds() external {\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_burn_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.burn(alice, 100);\n }\n\n function test_erc165_supportsInterface_succeeds() external {\n // The assertEq calls in this test are comparing the manual calculation of the iface,\n // with what is returned by the solidity's type().interfaceId, just to be safe.\n bytes4 iface1 = bytes4(keccak256(\"supportsInterface(bytes4)\"));\n assertEq(iface1, type(IERC165).interfaceId);\n assert(L2Token.supportsInterface(iface1));\n\n bytes4 iface2 = L2Token.l1Token.selector ^ L2Token.mint.selector ^ L2Token.burn.selector;\n assertEq(iface2, type(ILegacyMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface2));\n\n bytes4 iface3 = L2Token.remoteToken.selector ^\n L2Token.bridge.selector ^\n L2Token.mint.selector ^\n L2Token.burn.selector;\n assertEq(iface3, type(IOptimismMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface3));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\n\ncontract OptimismMintableTokenFactory_Test is Bridge_Initializer {\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_bridge_succeeds() external {\n assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge));\n }\n\n function test_createStandardL2Token_succeeds() external {\n address remote = address(4);\n address local = LibRLP.computeAddress(address(L2TokenFactory), 2);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_sameTwice_succeeds() external {\n address remote = address(4);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n\n address local = LibRLP.computeAddress(address(L2TokenFactory), 3);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_remoteIsZero_succeeds() external {\n address remote = address(0);\n vm.expectRevert(\"OptimismMintableERC20Factory: must provide remote token address\");\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721, IERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport {\n OptimismMintableERC721,\n IOptimismMintableERC721\n} from \"../universal/OptimismMintableERC721.sol\";\n\ncontract OptimismMintableERC721_Test is ERC721Bridge_Initializer {\n ERC721 internal L1Token;\n OptimismMintableERC721 internal L2Token;\n\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n event Mint(address indexed account, uint256 tokenId);\n\n event Burn(address indexed account, uint256 tokenId);\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n L1Token = new ERC721(\"L1Token\", \"L1T\");\n L2Token = new OptimismMintableERC721(\n address(L2Bridge),\n 1,\n address(L1Token),\n \"L2Token\",\n \"L2T\"\n );\n\n // Label the addresses for nice traces.\n vm.label(address(L1Token), \"L1ERC721Token\");\n vm.label(address(L2Token), \"L2ERC721Token\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(L2Token.name(), \"L2Token\");\n assertEq(L2Token.symbol(), \"L2T\");\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.remoteChainId(), 1);\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.REMOTE_CHAIN_ID(), 1);\n assertEq(L2Token.version(), \"1.1.0\");\n }\n\n /**\n * @notice Ensure that the contract supports the expected interfaces.\n */\n function test_supportsInterfaces_succeeds() external {\n // Checks if the contract supports the IOptimismMintableERC721 interface.\n assertTrue(L2Token.supportsInterface(type(IOptimismMintableERC721).interfaceId));\n // Checks if the contract supports the IERC721Enumerable interface.\n assertTrue(L2Token.supportsInterface(type(IERC721Enumerable).interfaceId));\n // Checks if the contract supports the IERC721 interface.\n assertTrue(L2Token.supportsInterface(type(IERC721).interfaceId));\n // Checks if the contract supports the IERC165 interface.\n assertTrue(L2Token.supportsInterface(type(IERC165).interfaceId));\n }\n\n function test_safeMint_succeeds() external {\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(address(0), alice, 1);\n\n // Expect a mint event.\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 1);\n\n // Mint the token.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token should be owned by alice.\n assertEq(L2Token.ownerOf(1), alice);\n }\n\n function test_safeMint_notBridge_reverts() external {\n // Try to mint the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.safeMint(alice, 1);\n }\n\n function test_burn_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(alice, address(0), 1);\n\n // Expect a burn event.\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 1);\n\n // Burn the token.\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 1);\n\n // Token should be owned by address(0).\n vm.expectRevert(\"ERC721: invalid token ID\");\n L2Token.ownerOf(1);\n }\n\n function test_burn_notBridge_reverts() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Try to burn the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.burn(alice, 1);\n }\n\n function test_tokenURI_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token URI should be correct.\n assertEq(\n L2Token.tokenURI(1),\n string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(address(L1Token)), 20),\n \"@\",\n Strings.toString(1),\n \"/tokenURI?uint256=\",\n Strings.toString(1)\n )\n )\n );\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\n\ncontract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {\n OptimismMintableERC721Factory internal factory;\n\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n factory = new OptimismMintableERC721Factory(address(L2Bridge), 1);\n\n // Label the addresses for nice traces.\n vm.label(address(factory), \"OptimismMintableERC721Factory\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(factory.BRIDGE(), address(L2Bridge));\n assertEq(factory.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_succeeds() external {\n // Predict the address based on the factory address and nonce.\n address predicted = LibRLP.computeAddress(address(factory), 1);\n\n // Expect a token creation event.\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC721Created(predicted, address(1234), alice);\n\n // Create the token.\n vm.prank(alice);\n OptimismMintableERC721 created = OptimismMintableERC721(\n factory.createOptimismMintableERC721(address(1234), \"L2Token\", \"L2T\")\n );\n\n // Token address should be correct.\n assertEq(address(created), predicted);\n\n // Should be marked as created by the factory.\n assertEq(factory.isOptimismMintableERC721(address(created)), true);\n\n // Token should've been constructed correctly.\n assertEq(created.name(), \"L2Token\");\n assertEq(created.symbol(), \"L2T\");\n assertEq(created.REMOTE_TOKEN(), address(1234));\n assertEq(created.BRIDGE(), address(L2Bridge));\n assertEq(created.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_zeroRemoteToken_reverts() external {\n // Try to create a token with a zero remote token address.\n vm.expectRevert(\"OptimismMintableERC721Factory: L1 token address cannot be address(0)\");\n factory.createOptimismMintableERC721(address(0), \"L2Token\", \"L2T\");\n }\n}\n" - }, - "contracts/test/OptimismPortal.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { Portal_Initializer, CommonTest, NextImpl } from \"./CommonTest.t.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\ncontract OptimismPortal_Test is Portal_Initializer {\n event Paused(address);\n event Unpaused(address);\n\n function test_constructor_succeeds() external {\n assertEq(address(op.L2_ORACLE()), address(oracle));\n assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD);\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be paused by the GUARDIAN\n */\n function test_pause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n assertEq(op.paused(), false);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Paused(guardian);\n\n vm.prank(guardian);\n op.pause();\n\n assertEq(op.paused(), true);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not the\n * GUARDIAN calls `pause()`\n */\n function test_pause_onlyGuardian_reverts() external {\n assertEq(op.paused(), false);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can pause\");\n vm.prank(alice);\n op.pause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be unpaused by the GUARDIAN\n */\n function test_unpause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Unpaused(guardian);\n vm.prank(guardian);\n op.unpause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not\n * the GUARDIAN calls `unpause()`\n */\n function test_unpause_onlyGuardian_reverts() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can unpause\");\n vm.prank(alice);\n op.unpause();\n\n assertEq(op.paused(), true);\n }\n\n function test_receive_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex\"\");\n\n // give alice money and send as an eoa\n vm.deal(alice, 2**64);\n vm.prank(alice, alice);\n (bool s, ) = address(op).call{ value: 100 }(hex\"\");\n\n assert(s);\n assertEq(address(op).balance, 100);\n }\n\n // Test: depositTransaction fails when contract creation has a non-zero destination address\n function test_depositTransaction_contractCreation_reverts() external {\n // contract creation must have a target of address(0)\n vm.expectRevert(\"OptimismPortal: must send to address(0) when creating a contract\");\n op.depositTransaction(address(1), 1, 0, true, hex\"\");\n }\n\n /**\n * @notice Prevent deposits from being too large to have a sane upper bound\n * on unsafe blocks sent over the p2p network.\n */\n function test_depositTransaction_largeData_reverts() external {\n uint256 size = 120_001;\n uint64 gasLimit = op.minimumGasLimit(uint64(size));\n vm.expectRevert(\"OptimismPortal: data too large\");\n op.depositTransaction({\n _to: address(0),\n _value: 0,\n _gasLimit: gasLimit,\n _isCreation: false,\n _data: new bytes(size)\n });\n }\n\n /**\n * @notice Prevent gasless deposits from being force processed in L2 by\n * ensuring that they have a large enough gas limit set.\n */\n function test_depositTransaction_smallGasLimit_reverts() external {\n vm.expectRevert(\"OptimismPortal: gas limit too small\");\n op.depositTransaction({\n _to: address(1),\n _value: 0,\n _gasLimit: 0,\n _isCreation: false,\n _data: hex\"\"\n });\n }\n\n /**\n * @notice Fuzz for too small of gas limits\n */\n function testFuzz_depositTransaction_smallGasLimit_succeeds(\n bytes memory _data,\n bool _shouldFail\n ) external {\n vm.assume(_data.length <= type(uint64).max);\n\n uint64 gasLimit = op.minimumGasLimit(uint64(_data.length));\n if (_shouldFail) {\n gasLimit = uint64(bound(gasLimit, 0, gasLimit - 1));\n vm.expectRevert(\"OptimismPortal: gas limit too small\");\n }\n\n op.depositTransaction({\n _to: address(0x40),\n _value: 0,\n _gasLimit: gasLimit,\n _isCreation: false,\n _data: _data\n });\n }\n\n /**\n * @notice Ensure that the 0 calldata case is covered and there is a linearly\n * increasing gas limit for larger calldata sizes.\n */\n function test_minimumGasLimit_succeeds() external {\n assertEq(op.minimumGasLimit(0), 21_000);\n assertTrue(op.minimumGasLimit(2) > op.minimumGasLimit(1));\n assertTrue(op.minimumGasLimit(3) > op.minimumGasLimit(2));\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a tx with 0 value\n function test_depositTransaction_noValueEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a tx with 0 value\n function test_depositTransaction_noValueContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndContractContractCreation_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n function test_simple_isOutputFinalized_succeeds() external {\n uint256 ts = block.timestamp;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))\n )\n );\n\n // warp to the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS());\n assertEq(op.isOutputFinalized(0), false);\n\n // warp past the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n assertEq(op.isOutputFinalized(0), true);\n }\n\n function test_isOutputFinalized_succeeds() external {\n uint256 checkpoint = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n vm.roll(checkpoint);\n vm.warp(oracle.computeL2Timestamp(checkpoint) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0);\n\n // warp to the final second of the finalization period\n uint256 finalizationHorizon = block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS();\n vm.warp(finalizationHorizon);\n // The checkpointed block should not be finalized until 1 second from now.\n assertEq(op.isOutputFinalized(nextOutputIndex), false);\n // Nor should a block after it\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n\n // warp past the finalization period\n vm.warp(finalizationHorizon + 1);\n // It should now be finalized.\n assertEq(op.isOutputFinalized(nextOutputIndex), true);\n // But not the block after it.\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n }\n}\n\ncontract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n // Utility function used in the subsequent test. This is necessary to assert that the\n // reentrant call will revert.\n function callPortalAndExpectRevert() external payable {\n vm.expectRevert(\"OptimismPortal: can only trigger one withdrawal per transaction\");\n // Arguments here don't matter, as the require check is the first thing that happens.\n // We assume that this has already been proven.\n op.finalizeWithdrawalTransaction(_defaultTx);\n // Assert that the withdrawal was not finalized.\n assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));\n }\n\n /**\n * @notice Proving withdrawal transactions should revert when paused\n */\n function test_proveWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.proveWithdrawalTransaction({\n _tx: _defaultTx,\n _l2OutputIndex: _proposedOutputIndex,\n _outputRootProof: _outputRootProof,\n _withdrawalProof: _withdrawalProof\n });\n }\n\n // Test: proveWithdrawalTransaction cannot prove a withdrawal with itself (the OptimismPortal) as the target.\n function test_proveWithdrawalTransaction_onSelfCall_reverts() external {\n _defaultTx.target = address(op);\n vm.expectRevert(\"OptimismPortal: you cannot send messages to the portal contract\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the outputRootProof does not match the output root\n function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external {\n // Modify the version to invalidate the withdrawal proof.\n _outputRootProof.version = bytes32(uint256(1));\n vm.expectRevert(\"OptimismPortal: invalid output root proof\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the proof is invalid due to non-existence of\n // the withdrawal.\n function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external {\n // modify the default test values to invalidate the proof.\n _defaultTx.data = hex\"abcd\";\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the passed transaction's withdrawalHash has\n // already been proven.\n function test_proveWithdrawalTransaction_replayProve_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: withdrawal hash has already been proven\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root has changed AND the l2BlockNumber stays the same.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in the OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a different output root within the `provenWithdrawals` mapping without\n // touching the l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root + output index + l2BlockNumber changes.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds()\n external\n {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a dummy output root within the `provenWithdrawals` mapping without touching the\n // l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle\n Types.OutputProposal memory proposal = op.L2_ORACLE().getL2Output(_proposedOutputIndex);\n\n // Propose the same output root again, creating the same output at a different index + l2BlockNumber.\n vm.startPrank(op.L2_ORACLE().PROPOSER());\n op.L2_ORACLE().proposeL2Output(\n proposal.outputRoot,\n op.L2_ORACLE().nextBlockNumber(),\n blockhash(block.number),\n block.number\n );\n vm.stopPrank();\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot + a different output index\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex + 1,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds and emits the WithdrawalProven event.\n function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: finalizeWithdrawalTransaction succeeds and emits the WithdrawalFinalized event.\n function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, false, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore + 100);\n }\n\n /**\n * @notice Finalizing withdrawal transactions should revert when paused\n */\n function test_finalizeWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has not been proven.\n function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectRevert(\"OptimismPortal: withdrawal has not been proven yet\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if withdrawal not proven long enough ago.\n function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Mock a call where the resulting output root is anything but the original output root. In\n // this case we just use bytes32(uint256(1)).\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(bytes32(uint256(1)), _proposedBlockNumber)\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the provenWithdrawal's timestamp is less\n // than the L2 output oracle's starting timestamp\n function test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a startingTimestamp change on the L2 Oracle\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSignature(\"startingTimestamp()\"),\n abi.encode(block.timestamp + 1)\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output root proven is not the same as the\n // output root at the time of finalization.\n function test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock an outputRoot change on the output proposal before attempting\n // to finalize the withdrawal.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n bytes32(uint256(0)),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output proposal's timestamp has\n // not passed the finalization period.\n function test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a timestamp change on the output proposal that has not passed the\n // finalization period.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(block.timestamp + 1),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\"OptimismPortal: output proposal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction fails because the target reverts,\n // and emits the WithdrawalFinalized event with success=false.\n function test_finalizeWithdrawalTransaction_targetFails_fails() external {\n uint256 bobBalanceBefore = address(bob).balance;\n vm.etch(bob, hex\"fe\"); // Contract with just the invalid opcode.\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, false);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the finalization period has not yet passed.\n function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external {\n // Setup the Oracle to return an output with a recent timestamp\n uint256 recentTimestamp = block.timestamp - 1000;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(recentTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has already been finalized.\n function test_finalizeWithdrawalTransaction_onReplay_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if insufficient gas is supplied.\n function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external {\n // This number was identified through trial and error.\n uint256 gasLimit = 150_000;\n Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: gasLimit,\n data: hex\"\"\n });\n\n // Get updated proof inputs.\n (bytes32 stateRoot, bytes32 storageRoot, , , bytes[] memory withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(insufficientGasTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n Hashing.hashOutputRootProof(outputRootProof),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n insufficientGasTx,\n _proposedOutputIndex,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectRevert(\"SafeCall: Not enough gas\");\n op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if a sub-call attempts to finalize another\n // withdrawal.\n function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Copy and modify the default test values to attempt a reentrant call by first calling to\n // this contract's callPortalAndExpectRevert() function above.\n Types.WithdrawalTransaction memory _testTx = _defaultTx;\n _testTx.target = address(this);\n _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector);\n\n // Get modified proof inputs.\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_testTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp.\n uint256 finalizedTimestamp = block.timestamp - oracle.FINALIZATION_PERIOD_SECONDS() - 1;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n outputRoot,\n uint128(finalizedTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(withdrawalHash, alice, address(this));\n op.proveWithdrawalTransaction(\n _testTx,\n _proposedBlockNumber,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectCall(address(this), _testTx.data);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_testTx);\n\n // Ensure that bob's balance was not changed by the reentrant call.\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n function testDiff_finalizeWithdrawalTransaction_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n vm.assume(\n _target != address(op) && // Cannot call the optimism portal or a contract\n _target.code.length == 0 && // No accounts with code\n _target != CONSOLE && // The console has no code but behaves like a contract\n uint160(_target) > 9 // No precompiles (or zero address)\n );\n\n // Total ETH supply is currently about 120M ETH.\n uint256 value = bound(_value, 0, 200_000_000 ether);\n vm.deal(address(op), value);\n\n uint256 gasLimit = bound(_gasLimit, 0, 50_000_000);\n uint256 nonce = messagePasser.messageNonce();\n\n // Get a withdrawal transaction and mock proof from the differential testing script.\n Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: value,\n gasLimit: gasLimit,\n data: _data\n });\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_tx);\n\n // Create the output root proof\n Types.OutputRootProof memory proof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n\n // Ensure the values returned from ffi are correct\n assertEq(outputRoot, Hashing.hashOutputRootProof(proof));\n assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx));\n\n // Setup the Oracle to return the outputRoot\n vm.mockCall(\n address(oracle),\n abi.encodeWithSelector(oracle.getL2Output.selector),\n abi.encode(outputRoot, block.timestamp, 100)\n );\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _tx,\n 100, // l2BlockNumber\n proof,\n withdrawalProof\n );\n (bytes32 _root, , ) = op.provenWithdrawals(withdrawalHash);\n assertTrue(_root != bytes32(0));\n\n // Warp past the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Finalize the withdrawal transaction\n vm.expectCallMinGas(_tx.target, _tx.value, uint64(_tx.gasLimit), _tx.data);\n op.finalizeWithdrawalTransaction(_tx);\n assertTrue(op.finalizedWithdrawals(withdrawalHash));\n }\n}\n\ncontract OptimismPortalUpgradeable_Test is Portal_Initializer {\n Proxy internal proxy;\n uint64 initialBlockNum;\n\n function setUp() public override {\n super.setUp();\n initialBlockNum = uint64(block.number);\n proxy = Proxy(payable(address(op)));\n }\n\n function test_params_initValuesOnProxy_succeeds() external {\n OptimismPortal p = OptimismPortal(payable(address(proxy)));\n\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = p.params();\n\n ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig();\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_initialize_cannotInitProxy_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(payable(proxy)).initialize(false);\n }\n\n function test_initialize_cannotInitImpl_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(opImpl).initialize(false);\n }\n\n function test_upgradeToAndCall_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(op), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(op)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n\n/**\n * @title OptimismPortalResourceFuzz_Test\n * @dev Test various values of the resource metering config to ensure that deposits cannot be\n * broken by changing the config.\n */\ncontract OptimismPortalResourceFuzz_Test is Portal_Initializer {\n /**\n * @dev The max gas limit observed throughout this test. Setting this too high can cause\n * the test to take too long to run.\n */\n uint256 constant MAX_GAS_LIMIT = 30_000_000;\n\n /**\n * @dev Test that various values of the resource metering config will not break deposits.\n */\n function testFuzz_systemConfigDeposit_succeeds(\n uint32 _maxResourceLimit,\n uint8 _elasticityMultiplier,\n uint8 _baseFeeMaxChangeDenominator,\n uint32 _minimumBaseFee,\n uint32 _systemTxMaxGas,\n uint128 _maximumBaseFee,\n uint64 _gasLimit,\n uint64 _prevBoughtGas,\n uint128 _prevBaseFee,\n uint8 _blockDiff\n ) external {\n // Get the set system gas limit\n uint64 gasLimit = systemConfig.gasLimit();\n // Bound resource config\n _maxResourceLimit = uint32(bound(_maxResourceLimit, 21000, MAX_GAS_LIMIT / 8));\n _gasLimit = uint64(bound(_gasLimit, 21000, _maxResourceLimit));\n _prevBaseFee = uint128(bound(_prevBaseFee, 0, 3 gwei));\n // Prevent values that would cause reverts\n vm.assume(gasLimit >= _gasLimit);\n vm.assume(_minimumBaseFee < _maximumBaseFee);\n vm.assume(_baseFeeMaxChangeDenominator > 1);\n vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit);\n vm.assume(_elasticityMultiplier > 0);\n vm.assume(\n ((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) ==\n _maxResourceLimit\n );\n _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit));\n _blockDiff = uint8(bound(_blockDiff, 0, 3));\n\n // Create a resource config to mock the call to the system config with\n ResourceMetering.ResourceConfig memory rcfg = ResourceMetering.ResourceConfig({\n maxResourceLimit: _maxResourceLimit,\n elasticityMultiplier: _elasticityMultiplier,\n baseFeeMaxChangeDenominator: _baseFeeMaxChangeDenominator,\n minimumBaseFee: _minimumBaseFee,\n systemTxMaxGas: _systemTxMaxGas,\n maximumBaseFee: _maximumBaseFee\n });\n vm.mockCall(\n address(systemConfig),\n abi.encodeWithSelector(systemConfig.resourceConfig.selector),\n abi.encode(rcfg)\n );\n\n // Set the resource params\n uint256 _prevBlockNum = block.number - _blockDiff;\n vm.store(\n address(op),\n bytes32(uint256(1)),\n bytes32((_prevBlockNum << 192) | (uint256(_prevBoughtGas) << 128) | _prevBaseFee)\n );\n // Ensure that the storage setting is correct\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = op.params();\n assertEq(prevBaseFee, _prevBaseFee);\n assertEq(prevBoughtGas, _prevBoughtGas);\n assertEq(prevBlockNum, _prevBlockNum);\n\n // Do a deposit, should not revert\n op.depositTransaction{ gas: MAX_GAS_LIMIT }({\n _to: address(0x20),\n _value: 0x40,\n _gasLimit: _gasLimit,\n _isCreation: false,\n _data: hex\"\"\n });\n }\n}\n" - }, - "contracts/test/Proxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract SimpleStorage {\n mapping(uint256 => uint256) internal store;\n\n function get(uint256 key) external payable returns (uint256) {\n return store[key];\n }\n\n function set(uint256 key, uint256 value) external payable {\n store[key] = value;\n }\n}\n\ncontract Clasher {\n function upgradeTo(address) external pure {\n revert(\"upgradeTo\");\n }\n}\n\ncontract Proxy_Test is Test {\n event Upgraded(address indexed implementation);\n event AdminChanged(address previousAdmin, address newAdmin);\n\n address alice = address(64);\n\n bytes32 internal constant IMPLEMENTATION_KEY =\n bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1);\n\n bytes32 internal constant OWNER_KEY = bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1);\n\n Proxy proxy;\n SimpleStorage simpleStorage;\n\n function setUp() external {\n // Deploy a proxy and simple storage contract as\n // the implementation\n proxy = new Proxy(alice);\n simpleStorage = new SimpleStorage();\n\n vm.prank(alice);\n proxy.upgradeTo(address(simpleStorage));\n }\n\n function test_implementationKey_succeeds() external {\n // The hardcoded implementation key should be correct\n vm.prank(alice);\n proxy.upgradeTo(address(6));\n\n bytes32 key = vm.load(address(proxy), IMPLEMENTATION_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(6));\n }\n\n function test_ownerKey_succeeds() external {\n // The hardcoded owner key should be correct\n vm.prank(alice);\n proxy.changeAdmin(address(6));\n\n bytes32 key = vm.load(address(proxy), OWNER_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(address(6));\n address owner = proxy.admin();\n assertEq(owner, address(6));\n }\n\n function test_proxyCallToImp_notAdmin_succeeds() external {\n // The implementation does not have a `upgradeTo`\n // method, calling `upgradeTo` not as the owner\n // should revert.\n vm.expectRevert();\n proxy.upgradeTo(address(64));\n\n // Call `upgradeTo` as the owner, it should succeed\n // and emit the `Upgraded` event.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(64));\n vm.prank(alice);\n proxy.upgradeTo(address(64));\n\n // Get the implementation as the owner\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(64));\n }\n\n function test_ownerProxyCall_notAdmin_succeeds() external {\n // Calling `changeAdmin` not as the owner should revert\n // as the implementation does not have a `changeAdmin` method.\n vm.expectRevert();\n proxy.changeAdmin(address(1));\n\n // Call `changeAdmin` as the owner, it should succeed\n // and emit the `AdminChanged` event.\n vm.expectEmit(true, true, true, true);\n emit AdminChanged(alice, address(1));\n vm.prank(alice);\n proxy.changeAdmin(address(1));\n\n // Calling `admin` not as the owner should\n // revert as the implementation does not have\n // a `admin` method.\n vm.expectRevert();\n proxy.admin();\n\n // Calling `admin` as the owner should work.\n vm.prank(address(1));\n address owner = proxy.admin();\n assertEq(owner, address(1));\n }\n\n function test_delegatesToImpl_succeeds() external {\n // Call the storage setter on the proxy\n SimpleStorage(address(proxy)).set(1, 1);\n\n // The key should not be set in the implementation\n uint256 result = simpleStorage.get(1);\n assertEq(result, 0);\n {\n // The key should be set in the proxy\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n\n {\n // The owner should be able to call through the proxy\n // when there is not a function selector crash\n vm.prank(alice);\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n }\n\n function test_upgradeToAndCall_succeeds() external {\n {\n // There should be nothing in the current proxy storage\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 0);\n }\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(simpleStorage));\n vm.prank(alice);\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The call should have impacted the state\n uint256 result = SimpleStorage(address(proxy)).get(1);\n assertEq(result, 1);\n }\n\n function test_upgradeToAndCall_functionDoesNotExist_reverts() external {\n // Get the current implementation address\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call. This reverts because the calldata doesn't\n // match a function on the implementation.\n vm.expectRevert(\"Proxy: delegatecall to new implementation contract failed\");\n vm.prank(alice);\n proxy.upgradeToAndCall(address(simpleStorage), hex\"\");\n\n // The implementation address should have not\n // updated because the call to `upgradeToAndCall`\n // reverted.\n vm.prank(alice);\n address postImpl = proxy.implementation();\n assertEq(impl, postImpl);\n\n // The attempt to `upgradeToAndCall`\n // should revert when it is not called by the owner.\n vm.expectRevert();\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n }\n\n function test_upgradeToAndCall_isPayable_succeeds() external {\n // Give alice some funds\n vm.deal(alice, 1 ether);\n // Set the implementation and call and send\n // value.\n vm.prank(alice);\n proxy.upgradeToAndCall{ value: 1 ether }(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The implementation address should be correct\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // The proxy should have a balance\n assertEq(address(proxy).balance, 1 ether);\n }\n\n function test_upgradeTo_clashingFunctionSignatures_succeeds() external {\n // Clasher has a clashing function with the proxy.\n Clasher clasher = new Clasher();\n\n // Set the clasher as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(clasher));\n\n {\n // Assert that the implementation was set properly.\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(clasher));\n }\n\n // Call the clashing function on the proxy\n // not as the owner so that the call passes through.\n // The implementation will revert so we can be\n // sure that the call passed through.\n vm.expectRevert(bytes(\"upgradeTo\"));\n proxy.upgradeTo(address(0));\n\n {\n // Now call the clashing function as the owner\n // and be sure that it doesn't pass through to\n // the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(0));\n }\n }\n\n // Allow for `eth_call` to call proxy methods\n // by setting \"from\" to `address(0)`.\n function test_implementation_zeroAddressCaller_succeeds() external {\n vm.prank(address(0));\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n }\n\n function test_implementation_isZeroAddress_reverts() external {\n // Set `address(0)` as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n\n (bool success, bytes memory returndata) = address(proxy).call(hex\"\");\n assertEq(success, false);\n\n bytes memory err = abi.encodeWithSignature(\n \"Error(string)\",\n \"Proxy: implementation not initialized\"\n );\n\n assertEq(returndata, err);\n }\n}\n" - }, - "contracts/test/ProxyAdmin.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { SimpleStorage } from \"./Proxy.t.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\n\ncontract ProxyAdmin_Test is Test {\n address alice = address(64);\n\n Proxy proxy;\n L1ChugSplashProxy chugsplash;\n ResolvedDelegateProxy resolved;\n\n AddressManager addressManager;\n\n ProxyAdmin admin;\n\n SimpleStorage implementation;\n\n function setUp() external {\n // Deploy the proxy admin\n admin = new ProxyAdmin(alice);\n // Deploy the standard proxy\n proxy = new Proxy(address(admin));\n\n // Deploy the legacy L1ChugSplashProxy with the admin as the owner\n chugsplash = new L1ChugSplashProxy(address(admin));\n\n // Deploy the legacy AddressManager\n addressManager = new AddressManager();\n // The proxy admin must be the new owner of the address manager\n addressManager.transferOwnership(address(admin));\n // Deploy a legacy ResolvedDelegateProxy with the name `a`.\n // Whatever `a` is set to in AddressManager will be the address\n // that is used for the implementation.\n resolved = new ResolvedDelegateProxy(addressManager, \"a\");\n\n // Impersonate alice for setting up the admin.\n vm.startPrank(alice);\n // Set the address of the address manager in the admin so that it\n // can resolve the implementation address of legacy\n // ResolvedDelegateProxy based proxies.\n admin.setAddressManager(addressManager);\n // Set the reverse lookup of the ResolvedDelegateProxy\n // proxy\n admin.setImplementationName(address(resolved), \"a\");\n\n // Set the proxy types\n admin.setProxyType(address(proxy), ProxyAdmin.ProxyType.ERC1967);\n admin.setProxyType(address(chugsplash), ProxyAdmin.ProxyType.CHUGSPLASH);\n admin.setProxyType(address(resolved), ProxyAdmin.ProxyType.RESOLVED);\n vm.stopPrank();\n\n implementation = new SimpleStorage();\n }\n\n function test_setImplementationName_succeeds() external {\n vm.prank(alice);\n admin.setImplementationName(address(1), \"foo\");\n assertEq(admin.implementationName(address(1)), \"foo\");\n }\n\n function test_setAddressManager_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setAddressManager(AddressManager((address(0))));\n }\n\n function test_setImplementationName_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setImplementationName(address(0), \"foo\");\n }\n\n function test_setProxyType_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setProxyType(address(0), ProxyAdmin.ProxyType.CHUGSPLASH);\n }\n\n function test_owner_succeeds() external {\n assertEq(admin.owner(), alice);\n }\n\n function test_proxyType_succeeds() external {\n assertEq(uint256(admin.proxyType(address(proxy))), uint256(ProxyAdmin.ProxyType.ERC1967));\n assertEq(\n uint256(admin.proxyType(address(chugsplash))),\n uint256(ProxyAdmin.ProxyType.CHUGSPLASH)\n );\n assertEq(\n uint256(admin.proxyType(address(resolved))),\n uint256(ProxyAdmin.ProxyType.RESOLVED)\n );\n }\n\n function test_erc1967GetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(proxy));\n }\n\n function test_chugsplashGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(resolved));\n }\n\n function getProxyImplementation(address payable _proxy) internal {\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(0));\n }\n\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n }\n\n function test_erc1967GetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(resolved));\n }\n\n function getProxyAdmin(address payable _proxy) internal {\n address owner = admin.getProxyAdmin(_proxy);\n assertEq(owner, address(admin));\n }\n\n function test_erc1967ChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(resolved));\n }\n\n function changeProxyAdmin(address payable _proxy) internal {\n ProxyAdmin.ProxyType proxyType = admin.proxyType(address(_proxy));\n\n vm.prank(alice);\n admin.changeProxyAdmin(_proxy, address(128));\n\n // The proxy is no longer the admin and can\n // no longer call the proxy interface except for\n // the ResolvedDelegate type on which anybody can\n // call the admin interface.\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n vm.expectRevert(\"Proxy: implementation not initialized\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n vm.expectRevert(\"L1ChugSplashProxy: implementation is not set yet\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n // Just an empty block to show that all cases are covered\n } else {\n vm.expectRevert(\"ProxyAdmin: unknown proxy type\");\n }\n\n // Call the proxy contract directly to get the admin.\n // Different proxy types have different interfaces.\n vm.prank(address(128));\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n assertEq(Proxy(payable(_proxy)).admin(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n assertEq(L1ChugSplashProxy(payable(_proxy)).getOwner(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n assertEq(addressManager.owner(), address(128));\n } else {\n assert(false);\n }\n }\n\n function test_erc1967Upgrade_succeeds() external {\n upgrade(payable(proxy));\n }\n\n function test_chugsplashUpgrade_succeeds() external {\n upgrade(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgrade_succeeds() external {\n upgrade(payable(resolved));\n }\n\n function upgrade(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n\n function test_erc1967UpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(proxy));\n }\n\n function test_chugsplashUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(resolved));\n }\n\n function upgradeAndCall(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgradeAndCall(\n _proxy,\n address(implementation),\n abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1)\n );\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n\n uint256 got = SimpleStorage(address(_proxy)).get(1);\n assertEq(got, 1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.changeProxyAdmin(payable(proxy), address(0));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgrade(payable(proxy), address(implementation));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgradeAndCall(payable(proxy), address(implementation), hex\"\");\n }\n\n function test_isUpgrading_succeeds() external {\n assertEq(false, admin.isUpgrading());\n\n vm.prank(alice);\n admin.setUpgrading(true);\n assertEq(true, admin.isUpgrading());\n }\n}\n" - }, - "contracts/test/RLP.t.sol": { - "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\n/**\n * @title LibRLP\n * @notice Via https://github.com/Rari-Capital/solmate/issues/207.\n */\nlibrary LibRLP {\n using Bytes32AddressLib for bytes32;\n\n function computeAddress(address deployer, uint256 nonce) internal pure returns (address) {\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))\n .fromLast20Bytes();\n if (nonce <= 0x7f)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))\n .fromLast20Bytes();\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= type(uint8).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd7),\n bytes1(0x94),\n deployer,\n bytes1(0x81),\n uint8(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint16).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd8),\n bytes1(0x94),\n deployer,\n bytes1(0x82),\n uint16(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint24).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd9),\n bytes1(0x94),\n deployer,\n bytes1(0x83),\n uint24(nonce)\n )\n ).fromLast20Bytes();\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return\n keccak256(\n abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))\n ).fromLast20Bytes();\n }\n}\n" - }, - "contracts/test/RLPReader.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { RLPReader } from \"../libraries/rlp/RLPReader.sol\";\n\ncontract RLPReader_readBytes_Test is CommonTest {\n function test_readBytes_bytestring00_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"00\"), hex\"00\");\n }\n\n function test_readBytes_bytestring01_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"01\"), hex\"01\");\n }\n\n function test_readBytes_bytestring7f_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"7f\"), hex\"7f\");\n }\n\n function test_readBytes_revertListItem_reverts() external {\n vm.expectRevert(\"RLPReader: decoded item type for bytes is not a data item\");\n RLPReader.readBytes(hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_readBytes_invalidStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n RLPReader.readBytes(hex\"b9\");\n }\n\n function test_readBytes_invalidListLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n RLPReader.readBytes(hex\"ff\");\n }\n\n function test_readBytes_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: bytes value contains an invalid remainder\");\n RLPReader.readBytes(hex\"800a\");\n }\n\n function test_readBytes_invalidPrefix_reverts() external {\n vm.expectRevert(\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n RLPReader.readBytes(hex\"810a\");\n }\n}\n\ncontract RLPReader_readList_Test is CommonTest {\n function test_readList_empty_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c0\");\n assertEq(list.length, 0);\n }\n\n function test_readList_multiList_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c6827a77c10401\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"827a77\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c104\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"01\");\n }\n\n function test_readList_shortListMax1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n\n assertEq(list.length, 11);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[4]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[5]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[6]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[7]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[8]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[9]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[10]), hex\"8471776572\");\n }\n\n function test_readList_longList1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n\n assertEq(list.length, 4);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"cf84617364668471776572847a786376\");\n }\n\n function test_readList_longList2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n assertEq(list.length, 32);\n\n for (uint256 i = 0; i < 32; i++) {\n assertEq(RLPReader.readRawBytes(list[i]), hex\"cf84617364668471776572847a786376\");\n }\n }\n\n function test_readList_listLongerThan32Elements_reverts() external {\n vm.expectRevert(stdError.indexOOBError);\n RLPReader.readList(\n hex\"e1454545454545454545454545454545454545454545454545454545454545454545\"\n );\n }\n\n function test_readList_listOfLists_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c4c2c0c0c0\");\n assertEq(list.length, 2);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c2c0c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c0\");\n }\n\n function test_readList_listOfLists2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c7c0c1c0c3c0c1c0\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c1c0\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"c3c0c1c0\");\n }\n\n function test_readList_dictTest1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n assertEq(list.length, 4);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"ca846b6579318476616c31\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"ca846b6579328476616c32\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"ca846b6579338476616c33\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"ca846b6579348476616c34\");\n }\n\n function test_readList_invalidShortList_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efdebd\");\n }\n\n function test_readList_longStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efb83600\");\n }\n\n function test_readList_notLongEnough_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(\n hex\"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n );\n }\n\n function test_readList_int32Overflow_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"bf0f000000000000021111\");\n }\n\n function test_readList_int32Overflow2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ff0f000000000000021111\");\n }\n\n function test_readList_incorrectLengthInArray_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(hex\"b800\");\n }\n\n function test_readList_leadingZerosInLongLengthList1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must not have any leading zeros (long list)\");\n RLPReader.readList(\n hex\"fb00000040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_nonOptimalLongLengthArray1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b81000112233445566778899aabbccddeeff\");\n }\n\n function test_readList_nonOptimalLongLengthArray2_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b801ff\");\n }\n\n function test_readList_invalidValue_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n RLPReader.readList(hex\"91\");\n }\n\n function test_readList_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n RLPReader.readList(hex\"c000\");\n }\n\n function test_readList_notEnoughContentForString1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"ba010000aabbccddeeff\");\n }\n\n function test_readList_notEnoughContentForString2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"b840ffeeddccbbaa99887766554433221100\");\n }\n\n function test_readList_notEnoughContentForList1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"f90180\");\n }\n\n function test_readList_notEnoughContentForList2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ffffffffffffffffff0001020304050607\");\n }\n\n function test_readList_longStringLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b80100\");\n }\n\n function test_readList_longListLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long list)\");\n RLPReader.readList(hex\"f80100\");\n }\n}\n" - }, - "contracts/test/RLPWriter.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { RLPWriter } from \"../libraries/rlp/RLPWriter.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\n\ncontract RLPWriter_writeString_Test is CommonTest {\n function test_writeString_empty_succeeds() external {\n assertEq(RLPWriter.writeString(\"\"), hex\"80\");\n }\n\n function test_writeString_bytestring00_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0000\"), hex\"00\");\n }\n\n function test_writeString_bytestring01_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0001\"), hex\"01\");\n }\n\n function test_writeString_bytestring7f_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u007F\"), hex\"7f\");\n }\n\n function test_writeString_shortstring_succeeds() external {\n assertEq(RLPWriter.writeString(\"dog\"), hex\"83646f67\");\n }\n\n function test_writeString_shortstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing eli\"),\n hex\"b74c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69\"\n );\n }\n\n function test_writeString_longstring_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing elit\"),\n hex\"b8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974\"\n );\n }\n\n function test_writeString_longstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\n \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat\"\n ),\n hex\"b904004c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742e20437572616269747572206d6175726973206d61676e612c20737573636970697420736564207665686963756c61206e6f6e2c20696163756c697320666175636962757320746f72746f722e2050726f696e20737573636970697420756c74726963696573206d616c6573756164612e204475697320746f72746f7220656c69742c2064696374756d2071756973207472697374697175652065752c20756c7472696365732061742072697375732e204d6f72626920612065737420696d70657264696574206d6920756c6c616d636f7270657220616c6971756574207375736369706974206e6563206c6f72656d2e2041656e65616e2071756973206c656f206d6f6c6c69732c2076756c70757461746520656c6974207661726975732c20636f6e73657175617420656e696d2e204e756c6c6120756c74726963657320747572706973206a7573746f2c20657420706f73756572652075726e6120636f6e7365637465747572206e65632e2050726f696e206e6f6e20636f6e76616c6c6973206d657475732e20446f6e65632074656d706f7220697073756d20696e206d617572697320636f6e67756520736f6c6c696369747564696e2e20566573746962756c756d20616e746520697073756d207072696d697320696e206661756369627573206f726369206c756374757320657420756c74726963657320706f737565726520637562696c69612043757261653b2053757370656e646973736520636f6e76616c6c69732073656d2076656c206d617373612066617563696275732c2065676574206c6163696e6961206c616375732074656d706f722e204e756c6c61207175697320756c747269636965732070757275732e2050726f696e20617563746f722072686f6e637573206e69626820636f6e64696d656e74756d206d6f6c6c69732e20416c697175616d20636f6e73657175617420656e696d206174206d65747573206c75637475732c206120656c656966656e6420707572757320656765737461732e20437572616269747572206174206e696268206d657475732e204e616d20626962656e64756d2c206e6571756520617420617563746f72207472697374697175652c206c6f72656d206c696265726f20616c697175657420617263752c206e6f6e20696e74657264756d2074656c6c7573206c65637475732073697420616d65742065726f732e20437261732072686f6e6375732c206d65747573206163206f726e617265206375727375732c20646f6c6f72206a7573746f20756c747269636573206d657475732c20617420756c6c616d636f7270657220766f6c7574706174\"\n );\n }\n}\n\ncontract RLPWriter_writeUint_Test is CommonTest {\n function test_writeUint_zero_succeeds() external {\n assertEq(RLPWriter.writeUint(0x0), hex\"80\");\n }\n\n function test_writeUint_smallint_succeeds() external {\n assertEq(RLPWriter.writeUint(1), hex\"01\");\n }\n\n function test_writeUint_smallint2_succeeds() external {\n assertEq(RLPWriter.writeUint(16), hex\"10\");\n }\n\n function test_writeUint_smallint3_succeeds() external {\n assertEq(RLPWriter.writeUint(79), hex\"4f\");\n }\n\n function test_writeUint_smallint4_succeeds() external {\n assertEq(RLPWriter.writeUint(127), hex\"7f\");\n }\n\n function test_writeUint_mediumint_succeeds() external {\n assertEq(RLPWriter.writeUint(128), hex\"8180\");\n }\n\n function test_writeUint_mediumint2_succeeds() external {\n assertEq(RLPWriter.writeUint(1000), hex\"8203e8\");\n }\n\n function test_writeUint_mediumint3_succeeds() external {\n assertEq(RLPWriter.writeUint(100000), hex\"830186a0\");\n }\n}\n\ncontract RLPWriter_writeList_Test is CommonTest {\n function test_writeList_empty_succeeds() external {\n assertEq(RLPWriter.writeList(new bytes[](0)), hex\"c0\");\n }\n\n function test_writeList_stringList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeString(\"dog\");\n list[1] = RLPWriter.writeString(\"god\");\n list[2] = RLPWriter.writeString(\"cat\");\n\n assertEq(RLPWriter.writeList(list), hex\"cc83646f6783676f6483636174\");\n }\n\n function test_writeList_multiList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeUint(4);\n\n list[0] = RLPWriter.writeString(\"zw\");\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeUint(1);\n\n assertEq(RLPWriter.writeList(list), hex\"c6827a77c10401\");\n }\n\n function test_writeList_shortListMax1_succeeds() external {\n bytes[] memory list = new bytes[](11);\n list[0] = RLPWriter.writeString(\"asdf\");\n list[1] = RLPWriter.writeString(\"qwer\");\n list[2] = RLPWriter.writeString(\"zxcv\");\n list[3] = RLPWriter.writeString(\"asdf\");\n list[4] = RLPWriter.writeString(\"qwer\");\n list[5] = RLPWriter.writeString(\"zxcv\");\n list[6] = RLPWriter.writeString(\"asdf\");\n list[7] = RLPWriter.writeString(\"qwer\");\n list[8] = RLPWriter.writeString(\"zxcv\");\n list[9] = RLPWriter.writeString(\"asdf\");\n list[10] = RLPWriter.writeString(\"qwer\");\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n }\n\n function test_writeList_longlist1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list2);\n list[3] = RLPWriter.writeList(list2);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_longlist2_succeeds() external {\n bytes[] memory list = new bytes[](32);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n for (uint256 i = 0; i < 32; i++) {\n list[i] = RLPWriter.writeList(list2);\n }\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_listoflists_succeeds() external {\n // [ [ [], [] ], [] ]\n bytes[] memory list = new bytes[](2);\n bytes[] memory list2 = new bytes[](2);\n\n list2[0] = RLPWriter.writeList(new bytes[](0));\n list2[1] = RLPWriter.writeList(new bytes[](0));\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(new bytes[](0));\n\n assertEq(RLPWriter.writeList(list), hex\"c4c2c0c0c0\");\n }\n\n function test_writeList_listoflists2_succeeds() external {\n // [ [], [[]], [ [], [[]] ] ]\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeList(new bytes[](0));\n\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeList(new bytes[](0));\n\n list[1] = RLPWriter.writeList(list2);\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeList(new bytes[](0));\n list3[1] = RLPWriter.writeList(list2);\n\n list[2] = RLPWriter.writeList(list3);\n\n assertEq(RLPWriter.writeList(list), hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_writeList_dictTest1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n\n bytes[] memory list1 = new bytes[](2);\n list1[0] = RLPWriter.writeString(\"key1\");\n list1[1] = RLPWriter.writeString(\"val1\");\n\n bytes[] memory list2 = new bytes[](2);\n list2[0] = RLPWriter.writeString(\"key2\");\n list2[1] = RLPWriter.writeString(\"val2\");\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeString(\"key3\");\n list3[1] = RLPWriter.writeString(\"val3\");\n\n bytes[] memory list4 = new bytes[](2);\n list4[0] = RLPWriter.writeString(\"key4\");\n list4[1] = RLPWriter.writeString(\"val4\");\n\n list[0] = RLPWriter.writeList(list1);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list3);\n list[3] = RLPWriter.writeList(list4);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n }\n}\n" - }, - "contracts/test/ResolvedDelegateProxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\n\ncontract ResolvedDelegateProxy_Test is Test {\n AddressManager internal addressManager;\n SimpleImplementation internal impl;\n SimpleImplementation internal proxy;\n\n function setUp() public {\n // Set up the address manager.\n addressManager = new AddressManager();\n impl = new SimpleImplementation();\n addressManager.setAddress(\"SimpleImplementation\", address(impl));\n\n // Set up the proxy.\n proxy = SimpleImplementation(\n address(new ResolvedDelegateProxy(addressManager, \"SimpleImplementation\"))\n );\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall succeeds.\n function testFuzz_fallback_delegateCallFoo_succeeds(uint256 x) public {\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.foo.selector, x));\n assertEq(proxy.foo(x), x);\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall reverts.\n function test_fallback_delegateCallBar_reverts() public {\n vm.expectRevert(\"SimpleImplementation: revert\");\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.bar.selector));\n proxy.bar();\n }\n\n // Tests that the proxy fallback reverts as expected if the implementation within the\n // address manager is not set.\n function test_fallback_addressManagerNotSet_reverts() public {\n AddressManager am = new AddressManager();\n SimpleImplementation p = SimpleImplementation(\n address(new ResolvedDelegateProxy(am, \"SimpleImplementation\"))\n );\n\n vm.expectRevert(\"ResolvedDelegateProxy: target address must be initialized\");\n p.foo(0);\n }\n}\n\ncontract SimpleImplementation {\n function foo(uint256 _x) public pure returns (uint256) {\n return _x;\n }\n\n function bar() public pure {\n revert(\"SimpleImplementation: revert\");\n }\n}\n" - }, - "contracts/test/ResourceMetering.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract MeterUser is ResourceMetering {\n ResourceMetering.ResourceConfig public innerConfig;\n\n constructor() {\n initialize();\n innerConfig = Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function initialize() public initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public view returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n view\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return innerConfig;\n }\n\n function use(uint64 _amount) public metered(_amount) {}\n\n function set(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) public {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n\n function setParams(ResourceMetering.ResourceConfig memory newConfig) public {\n innerConfig = newConfig;\n }\n}\n\n/**\n * @title ResourceConfig\n * @notice The tests are based on the default config values. It is expected that\n * the config values used in these tests are ran in production.\n */\ncontract ResourceMetering_Test is Test {\n MeterUser internal meter;\n uint64 initialBlockNum;\n\n function setUp() public {\n meter = new MeterUser();\n initialBlockNum = uint64(block.number);\n }\n\n function test_meter_initialResourceParams_succeeds() external {\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_updateParamsNoChange_succeeds() external {\n meter.use(0); // equivalent to just updating the base fee and block number\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n meter.use(0);\n (uint128 postBaseFee, uint64 postBoughtGas, uint64 postBlockNum) = meter.params();\n\n assertEq(postBaseFee, prevBaseFee);\n assertEq(postBoughtGas, prevBoughtGas);\n assertEq(postBlockNum, prevBlockNum);\n }\n\n function test_meter_updateOneEmptyBlock_succeeds() external {\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 1);\n }\n\n function test_meter_updateTwoEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 2);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 2);\n }\n\n function test_meter_updateTenEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 10);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 10);\n }\n\n function test_meter_updateNoGasDelta_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint256 target = uint256(rcfg.maxResourceLimit) / uint256(rcfg.elasticityMultiplier);\n meter.use(uint64(target));\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1000000000);\n assertEq(prevBoughtGas, target);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_useMax_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n meter.use(target * elasticityMultiplier);\n\n (, uint64 prevBoughtGas, ) = meter.params();\n assertEq(prevBoughtGas, target * elasticityMultiplier);\n\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 postBaseFee, , ) = meter.params();\n assertEq(postBaseFee, 2125000000);\n }\n\n /**\n * @notice This tests that the metered modifier reverts if\n * the ResourceConfig baseFeeMaxChangeDenominator\n * is set to 1.\n * Since the metered modifier internally calls\n * solmate's powWad function, it will revert\n * with the error string \"UNDEFINED\" since the\n * first parameter will be computed as 0.\n */\n function test_meter_denominatorEq1_reverts() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n rcfg.baseFeeMaxChangeDenominator = 1;\n meter.setParams(rcfg);\n meter.use(target * elasticityMultiplier);\n\n (, uint64 prevBoughtGas, ) = meter.params();\n assertEq(prevBoughtGas, target * elasticityMultiplier);\n\n vm.roll(initialBlockNum + 2);\n\n vm.expectRevert(\"UNDEFINED\");\n meter.use(0);\n }\n\n function test_meter_useMoreThanMax_reverts() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.expectRevert(\"ResourceMetering: cannot buy more gas than available gas limit\");\n meter.use(target * elasticityMultiplier + 1);\n }\n\n // Demonstrates that the resource metering arithmetic can tolerate very large gaps between\n // deposits.\n function testFuzz_meter_largeBlockDiff_succeeds(uint64 _amount, uint256 _blockDiff) external {\n // This test fails if the following line is commented out.\n // At 12 seconds per block, this number is effectively unreachable.\n vm.assume(_blockDiff < 433576281058164217753225238677900874458691);\n\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.assume(_amount < target * elasticityMultiplier);\n vm.roll(initialBlockNum + _blockDiff);\n meter.use(_amount);\n }\n}\n\n/**\n * @title CustomMeterUser\n * @notice A simple wrapper around `ResourceMetering` that allows the initial\n * params to be set in the constructor.\n */\ncontract CustomMeterUser is ResourceMetering {\n uint256 public startGas;\n uint256 public endGas;\n\n constructor(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function use(uint64 _amount) public returns (uint256) {\n uint256 initialGas = gasleft();\n _metered(_amount, initialGas);\n return initialGas - gasleft();\n }\n}\n\n/**\n * @title ArtifactResourceMetering_Test\n * @notice A table test that sets the state of the ResourceParams and then requests\n * various amounts of gas. This test ensures that a wide range of values\n * can safely be used with the `ResourceMetering` contract.\n * It also writes a CSV file to disk that includes useful information\n * about how much gas is used and how expensive it is in USD terms to\n * purchase the deposit gas.\n */\ncontract ArtifactResourceMetering_Test is Test {\n uint128 internal minimumBaseFee;\n uint128 internal maximumBaseFee;\n uint64 internal maxResourceLimit;\n uint64 internal targetResourceLimit;\n\n string internal outfile;\n\n // keccak256(abi.encodeWithSignature(\"Error(string)\", \"ResourceMetering: cannot buy more gas than available gas limit\"))\n bytes32 internal cannotBuyMoreGas =\n 0x84edc668cfd5e050b8999f43ff87a1faaa93e5f935b20bc1dd4d3ff157ccf429;\n // keccak256(abi.encodeWithSignature(\"Panic(uint256)\", 0x11))\n bytes32 internal overflowErr =\n 0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;\n // keccak256(hex\"\")\n bytes32 internal emptyReturnData =\n 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n\n /**\n * @notice Sets up the tests by getting constants from the ResourceMetering\n * contract.\n */\n function setUp() public {\n vm.roll(1_000_000);\n\n MeterUser base = new MeterUser();\n ResourceMetering.ResourceConfig memory rcfg = base.resourceConfig();\n minimumBaseFee = uint128(rcfg.minimumBaseFee);\n maximumBaseFee = rcfg.maximumBaseFee;\n maxResourceLimit = uint64(rcfg.maxResourceLimit);\n targetResourceLimit = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n\n outfile = string.concat(vm.projectRoot(), \"/.resource-metering.csv\");\n try vm.removeFile(outfile) {} catch {}\n }\n\n /**\n * @notice Generate a CSV file. The call to `meter` should be called with at\n * most the L1 block gas limit. Without specifying the amount of\n * gas, it can take very long to execute.\n */\n function test_meter_generateArtifact_succeeds() external {\n vm.writeLine(\n outfile,\n \"prevBaseFee,prevBoughtGas,prevBlockNumDiff,l1BaseFee,requestedGas,gasConsumed,ethPrice,usdCost,success\"\n );\n\n // prevBaseFee value in ResourceParams\n uint128[] memory prevBaseFees = new uint128[](5);\n prevBaseFees[0] = minimumBaseFee;\n prevBaseFees[1] = maximumBaseFee;\n prevBaseFees[2] = uint128(50 gwei);\n prevBaseFees[3] = uint128(100 gwei);\n prevBaseFees[4] = uint128(200 gwei);\n\n // prevBoughtGas value in ResourceParams\n uint64[] memory prevBoughtGases = new uint64[](1);\n prevBoughtGases[0] = uint64(0);\n\n // prevBlockNum diff, simulates blocks with no deposits when non zero\n uint64[] memory prevBlockNumDiffs = new uint64[](2);\n prevBlockNumDiffs[0] = 0;\n prevBlockNumDiffs[1] = 1;\n\n // The amount of L2 gas that a user requests\n uint64[] memory requestedGases = new uint64[](3);\n requestedGases[0] = maxResourceLimit;\n requestedGases[1] = targetResourceLimit;\n requestedGases[2] = uint64(100_000);\n\n // The L1 base fee\n uint256[] memory l1BaseFees = new uint256[](4);\n l1BaseFees[0] = 1 gwei;\n l1BaseFees[1] = 50 gwei;\n l1BaseFees[2] = 75 gwei;\n l1BaseFees[3] = 100 gwei;\n\n // USD price of 1 ether\n uint256[] memory ethPrices = new uint256[](2);\n ethPrices[0] = 1600;\n ethPrices[1] = 3200;\n\n // Iterate over all of the test values and run a test\n for (uint256 i; i < prevBaseFees.length; i++) {\n for (uint256 j; j < prevBoughtGases.length; j++) {\n for (uint256 k; k < prevBlockNumDiffs.length; k++) {\n for (uint256 l; l < requestedGases.length; l++) {\n for (uint256 m; m < l1BaseFees.length; m++) {\n for (uint256 n; n < ethPrices.length; n++) {\n uint256 snapshotId = vm.snapshot();\n\n uint128 prevBaseFee = prevBaseFees[i];\n uint64 prevBoughtGas = prevBoughtGases[j];\n uint64 prevBlockNumDiff = prevBlockNumDiffs[k];\n uint64 requestedGas = requestedGases[l];\n uint256 l1BaseFee = l1BaseFees[m];\n uint256 ethPrice = ethPrices[n];\n string memory result = \"success\";\n\n vm.fee(l1BaseFee);\n\n CustomMeterUser meter = new CustomMeterUser({\n _prevBaseFee: prevBaseFee,\n _prevBoughtGas: prevBoughtGas,\n _prevBlockNum: uint64(block.number)\n });\n\n vm.roll(block.number + prevBlockNumDiff);\n\n // Call the metering code and catch the various\n // types of errors.\n uint256 gasConsumed = 0;\n try meter.use{ gas: 30_000_000 }(requestedGas) returns (\n uint256 _gasConsumed\n ) {\n gasConsumed = _gasConsumed;\n } catch (bytes memory err) {\n bytes32 hash = keccak256(err);\n if (hash == cannotBuyMoreGas) {\n result = \"ResourceMetering: cannot buy more gas than available gas limit\";\n } else if (hash == overflowErr) {\n result = \"arithmetic overflow/underflow\";\n } else if (hash == emptyReturnData) {\n result = \"out of gas\";\n } else {\n result = \"UNKNOWN ERROR\";\n }\n }\n\n // Compute the USD cost of the gas used\n uint256 usdCost = (gasConsumed * l1BaseFee * ethPrice) / 1 ether;\n\n vm.writeLine(\n outfile,\n string.concat(\n vm.toString(prevBaseFee),\n \",\",\n vm.toString(prevBoughtGas),\n \",\",\n vm.toString(prevBlockNumDiff),\n \",\",\n vm.toString(l1BaseFee),\n \",\",\n vm.toString(requestedGas),\n \",\",\n vm.toString(gasConsumed),\n \",\",\n \"$\",\n vm.toString(ethPrice),\n \",\",\n \"$\",\n vm.toString(usdCost),\n \",\",\n result\n )\n );\n\n assertTrue(vm.revertTo(snapshotId));\n }\n }\n }\n }\n }\n }\n }\n}\n" - }, - "contracts/test/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\n\ncontract SafeCall_Test is CommonTest {\n function testFuzz_call_succeeds(\n address from,\n address to,\n uint256 gas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n // don't call the ffi interface\n vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCall(to, value, data);\n vm.prank(from);\n bool success = SafeCall.call(to, gas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function testFuzz_callWithMinGas_hasEnough_succeeds(\n address from,\n address to,\n uint64 minGas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n // don't call the FFIInterface\n vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n // Bound minGas to [0, l1_block_gas_limit]\n minGas = uint64(bound(minGas, 0, 30_000_000));\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCallMinGas(to, value, minGas, data);\n vm.prank(from);\n bool success = SafeCall.callWithMinGas(to, minGas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function test_callWithMinGas_noLeakageLow_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 40_000; i < 100_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 65_907 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 65_907) {\n assertFalse(caller.makeSafeCall(i, 25_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 25_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 25_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n\n function test_callWithMinGas_noLeakageHigh_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 15_200_000; i < 15_300_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 15_278_606 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 15_278_606) {\n assertFalse(caller.makeSafeCall(i, 15_000_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 15_000_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 15_000_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n}\n\ncontract SimpleSafeCaller {\n uint256 public a;\n\n function makeSafeCall(uint64 gas, uint64 minGas) external returns (bool) {\n return\n SafeCall.call(\n address(this),\n gas,\n 0,\n abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas)\n );\n }\n\n function makeSafeCallMinGas(uint64 minGas) external returns (bool) {\n return\n SafeCall.callWithMinGas(\n address(this),\n minGas,\n 0,\n abi.encodeWithSelector(this.setA.selector, 1)\n );\n }\n\n function setA(uint256 _a) external {\n a = _a;\n }\n}\n" - }, - "contracts/test/Semver.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\n\n/**\n * @notice Test the Semver contract that is used for semantic versioning\n * of various contracts.\n */\ncontract Semver_Test is CommonTest {\n /**\n * @notice Global semver contract deployed in setUp. This is used in\n * the test cases.\n */\n Semver semver;\n\n /**\n * @notice Deploy a Semver contract\n */\n function setUp() public virtual override {\n semver = new Semver(7, 8, 0);\n }\n\n /**\n * @notice Test the version getter\n */\n function test_version_succeeds() external {\n assertEq(semver.version(), \"7.8.0\");\n }\n\n /**\n * @notice Since the versions are all immutable, they should\n * be able to be accessed from behind a proxy without needing\n * to initialize the contract.\n */\n function test_behindProxy_succeeds() external {\n Proxy proxy = new Proxy(alice);\n vm.prank(alice);\n proxy.upgradeTo(address(semver));\n\n assertEq(Semver(address(proxy)).version(), \"7.8.0\");\n }\n}\n" - }, - "contracts/test/SequencerFeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { SequencerFeeVault } from \"../L2/SequencerFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract SequencerFeeVault_Test is Bridge_Initializer {\n SequencerFeeVault vault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET));\n address constant recipient = address(256);\n\n event Withdrawal(uint256 value, address to, address from);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.SEQUENCER_FEE_WALLET, address(new SequencerFeeVault(recipient)).code);\n vm.label(Predeploys.SEQUENCER_FEE_WALLET, \"SequencerFeeVault\");\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n\n function test_constructor_succeeds() external {\n assertEq(vault.l1FeeWallet(), recipient);\n }\n\n function test_receive_succeeds() external {\n uint256 balance = address(vault).balance;\n\n vm.prank(alice);\n (bool success, ) = address(vault).call{ value: 100 }(hex\"\");\n\n assertEq(success, true);\n assertEq(address(vault).balance, balance + 100);\n }\n\n function test_withdraw_notEnough_reverts() external {\n assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());\n\n vm.expectRevert(\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n vault.withdraw();\n }\n\n function test_withdraw_succeeds() external {\n uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1;\n vm.deal(address(vault), amount);\n\n // No ether has been withdrawn yet\n assertEq(vault.totalProcessed(), 0);\n\n vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));\n emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));\n\n // The entire vault's balance is withdrawn\n vm.expectCall(\n Predeploys.L2_STANDARD_BRIDGE,\n address(vault).balance,\n abi.encodeWithSelector(\n StandardBridge.bridgeETHTo.selector,\n vault.l1FeeWallet(),\n 35_000,\n bytes(\"\")\n )\n );\n\n vault.withdraw();\n\n // The withdrawal was successful\n assertEq(vault.totalProcessed(), amount);\n }\n}\n" - }, - "contracts/test/StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport {\n OptimismMintableERC20,\n ILegacyMintableERC20\n} from \"../universal/OptimismMintableERC20.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/**\n * @title StandardBridgeTester\n * @notice Simple wrapper around the StandardBridge contract that exposes\n * internal functions so they can be more easily tested directly.\n */\ncontract StandardBridgeTester is StandardBridge {\n constructor(address payable _messenger, address payable _otherBridge)\n StandardBridge(_messenger, _otherBridge)\n {}\n\n function isOptimismMintableERC20(address _token) external view returns (bool) {\n return _isOptimismMintableERC20(_token);\n }\n\n function isCorrectTokenPair(address _mintableToken, address _otherToken)\n external\n view\n returns (bool)\n {\n return _isCorrectTokenPair(_mintableToken, _otherToken);\n }\n\n receive() external payable override {}\n}\n\n/**\n * @title LegacyMintable\n * @notice Simple implementation of the legacy OptimismMintableERC20.\n */\ncontract LegacyMintable is ERC20, ILegacyMintableERC20 {\n constructor(string memory _name, string memory _ticker) ERC20(_name, _ticker) {}\n\n function l1Token() external pure returns (address) {\n return address(0);\n }\n\n function mint(address _to, uint256 _amount) external pure {}\n\n function burn(address _from, uint256 _amount) external pure {}\n\n /**\n * @notice Implements ERC165. This implementation should not be changed as\n * it is how the actual legacy optimism mintable token does the\n * check. Allows for testing against code that is has been deployed,\n * assuming different compiler version is no problem.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n}\n\n/**\n * @title StandardBridge_Stateless_Test\n * @notice Tests internal functions that require no existing state or contract\n * interactions with the messenger.\n */\ncontract StandardBridge_Stateless_Test is CommonTest {\n StandardBridgeTester internal bridge;\n OptimismMintableERC20 internal mintable;\n ERC20 internal erc20;\n LegacyMintable internal legacy;\n\n function setUp() public override {\n super.setUp();\n\n bridge = new StandardBridgeTester({\n _messenger: payable(address(0)),\n _otherBridge: payable(address(0))\n });\n\n mintable = new OptimismMintableERC20({\n _bridge: address(0),\n _remoteToken: address(0),\n _name: \"Stonks\",\n _symbol: \"STONK\"\n });\n\n erc20 = new ERC20(\"Altcoin\", \"ALT\");\n legacy = new LegacyMintable(\"Legacy\", \"LEG\");\n }\n\n /**\n * @notice Test coverage for identifying OptimismMintableERC20 tokens.\n * This function should return true for both modern and legacy\n * OptimismMintableERC20 tokens and false for any accounts that\n * do not implement the interface.\n */\n function test_isOptimismMintableERC20_succeeds() external {\n // Both the modern and legacy mintable tokens should return true\n assertTrue(bridge.isOptimismMintableERC20(address(mintable)));\n assertTrue(bridge.isOptimismMintableERC20(address(legacy)));\n // A regular ERC20 should return false\n assertFalse(bridge.isOptimismMintableERC20(address(erc20)));\n // Non existent contracts should return false and not revert\n assertEq(address(0x20).code.length, 0);\n assertFalse(bridge.isOptimismMintableERC20(address(0x20)));\n }\n\n /**\n * @notice Test coverage of isCorrectTokenPair under different types of\n * tokens.\n */\n function test_isCorrectTokenPair_succeeds() external {\n // Modern + known to be correct remote token\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.remoteToken()));\n // Modern + known to be correct l1Token (legacy interface)\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.l1Token()));\n // Modern + known to be incorrect remote token\n assertTrue(mintable.remoteToken() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(mintable), address(0x20)));\n // Legacy + known to be correct l1Token\n assertTrue(bridge.isCorrectTokenPair(address(legacy), legacy.l1Token()));\n // Legacy + known to be incorrect l1Token\n assertTrue(legacy.l1Token() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(legacy), address(0x20)));\n // A token that doesn't support either modern or legacy interface\n // will revert\n vm.expectRevert();\n bridge.isCorrectTokenPair(address(erc20), address(1));\n }\n}\n" - }, - "contracts/test/SystemConfig.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract SystemConfig_Init is CommonTest {\n SystemConfig sysConf;\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n sysConf = new SystemConfig({\n _owner: alice,\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: config\n });\n }\n}\n\ncontract SystemConfig_Initialize_TestFail is SystemConfig_Init {\n function test_initialize_lowGasLimit_reverts() external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n\n ResourceMetering.ResourceConfig memory cfg = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n new SystemConfig({\n _owner: alice,\n _overhead: 0,\n _scalar: 0,\n _batcherHash: bytes32(hex\"\"),\n _gasLimit: minimumGasLimit - 1,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n }\n}\n\ncontract SystemConfig_Setters_TestFail is SystemConfig_Init {\n function test_setBatcherHash_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setBatcherHash(bytes32(hex\"\"));\n }\n\n function test_setGasConfig_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasConfig(0, 0);\n }\n\n function test_setGasLimit_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasLimit(0);\n }\n\n function test_setUnsafeBlockSigner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setUnsafeBlockSigner(address(0x20));\n }\n\n function test_setResourceConfig_notOwner_reverts() external {\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badMinMax_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 2 gwei,\n maximumBaseFee: 1 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: min base fee must be less than max base\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_zeroDenominator_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 0,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: denominator must be larger than 1\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_lowGasLimit_reverts() external {\n uint64 gasLimit = sysConf.gasLimit();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: uint32(gasLimit),\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: uint32(gasLimit),\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badPrecision_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 11,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: precision loss with target resource limit\");\n sysConf.setResourceConfig(config);\n }\n}\n\ncontract SystemConfig_Setters_Test is SystemConfig_Init {\n event ConfigUpdate(\n uint256 indexed version,\n SystemConfig.UpdateType indexed updateType,\n bytes data\n );\n\n function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash));\n\n vm.prank(sysConf.owner());\n sysConf.setBatcherHash(newBatcherHash);\n assertEq(sysConf.batcherHash(), newBatcherHash);\n }\n\n function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.GAS_CONFIG,\n abi.encode(newOverhead, newScalar)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setGasConfig(newOverhead, newScalar);\n assertEq(sysConf.overhead(), newOverhead);\n assertEq(sysConf.scalar(), newScalar);\n }\n\n function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n newGasLimit = uint64(\n bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))\n );\n\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit));\n\n vm.prank(sysConf.owner());\n sysConf.setGasLimit(newGasLimit);\n assertEq(sysConf.gasLimit(), newGasLimit);\n }\n\n function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER,\n abi.encode(newUnsafeSigner)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setUnsafeBlockSigner(newUnsafeSigner);\n assertEq(sysConf.unsafeBlockSigner(), newUnsafeSigner);\n }\n}\n" - }, - "contracts/test/TransferOnion.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { TransferOnion } from \"../periphery/TransferOnion.sol\";\n\n/**\n * @title TransferOnionTest\n * @notice Test coverage of TransferOnion\n */\ncontract TransferOnionTest is Test {\n /**\n * @notice TransferOnion\n */\n TransferOnion internal onion;\n\n /**\n * @notice token constructor arg\n */\n address internal _token;\n\n /**\n * @notice sender constructor arg\n */\n address internal _sender;\n\n /**\n * @notice Sets up addresses, deploys contracts and funds the owner.\n */\n function setUp() public {\n ERC20 token = new ERC20(\"Token\", \"TKN\");\n _token = address(token);\n _sender = makeAddr(\"sender\");\n }\n\n /**\n * @notice Deploy the TransferOnion with a dummy shell\n */\n function _deploy() public {\n _deploy(bytes32(0));\n }\n\n /**\n * @notice Deploy the TransferOnion with a specific shell\n */\n function _deploy(bytes32 _shell) public {\n onion = new TransferOnion({ _token: ERC20(_token), _sender: _sender, _shell: _shell });\n }\n\n /**\n * @notice Build the onion data\n */\n function _onionize(TransferOnion.Layer[] memory _layers)\n public\n pure\n returns (bytes32, TransferOnion.Layer[] memory)\n {\n uint256 length = _layers.length;\n bytes32 hash = bytes32(0);\n for (uint256 i; i < length; i++) {\n TransferOnion.Layer memory layer = _layers[i];\n _layers[i].shell = hash;\n hash = keccak256(abi.encode(layer.recipient, layer.amount, hash));\n }\n return (hash, _layers);\n }\n\n /**\n * @notice The constructor sets the variables as expected\n */\n function test_constructor_succeeds() external {\n _deploy();\n\n assertEq(address(onion.TOKEN()), _token);\n assertEq(onion.SENDER(), _sender);\n assertEq(onion.shell(), bytes32(0));\n }\n\n /**\n * @notice unwrap\n */\n function test_unwrap_succeeds() external {\n // Commit to transferring tiny amounts of tokens\n TransferOnion.Layer[] memory _layers = new TransferOnion.Layer[](2);\n _layers[0] = TransferOnion.Layer(address(1), 1, bytes32(0));\n _layers[1] = TransferOnion.Layer(address(2), 2, bytes32(0));\n\n // Build the onion shell\n (bytes32 shell, TransferOnion.Layer[] memory layers) = _onionize(_layers);\n _deploy(shell);\n\n assertEq(onion.shell(), shell);\n\n address token = address(onion.TOKEN());\n address sender = onion.SENDER();\n\n // give 3 units of token to sender\n deal(token, onion.SENDER(), 3);\n vm.prank(sender);\n ERC20(token).approve(address(onion), 3);\n\n // To build the inputs, to `peel`, need to reverse the list\n TransferOnion.Layer[] memory inputs = new TransferOnion.Layer[](2);\n int256 length = int256(layers.length);\n for (int256 i = length - 1; i >= 0; i--) {\n uint256 ui = uint256(i);\n uint256 revidx = uint256(length) - ui - 1;\n TransferOnion.Layer memory layer = layers[ui];\n inputs[revidx] = layer;\n }\n\n // The accounts have no balance\n assertEq(ERC20(_token).balanceOf(address(1)), 0);\n assertEq(ERC20(_token).balanceOf(address(2)), 0);\n\n onion.peel(inputs);\n\n // Now the accounts have the expected balance\n assertEq(ERC20(_token).balanceOf(address(1)), 1);\n assertEq(ERC20(_token).balanceOf(address(2)), 2);\n }\n}\n" - }, - "contracts/test/invariants/CrossDomainMessenger.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { OptimismPortal } from \"../../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../../L1/L1CrossDomainMessenger.sol\";\nimport { Messenger_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\nimport { Predeploys } from \"../../libraries/Predeploys.sol\";\nimport { Constants } from \"../../libraries/Constants.sol\";\nimport { Encoding } from \"../../libraries/Encoding.sol\";\nimport { Hashing } from \"../../libraries/Hashing.sol\";\n\ncontract RelayActor is StdUtils {\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n uint256 public numHashes;\n bytes32[] public hashes;\n bool public reverted = false;\n\n OptimismPortal op;\n L1CrossDomainMessenger xdm;\n Vm vm;\n bool doFail;\n\n constructor(\n OptimismPortal _op,\n L1CrossDomainMessenger _xdm,\n Vm _vm,\n bool _doFail\n ) {\n op = _op;\n xdm = _xdm;\n vm = _vm;\n doFail = _doFail;\n }\n\n /**\n * Relays a message to the `L1CrossDomainMessenger` with a random `version`, and `_message`.\n */\n function relay(\n uint8 _version,\n uint8 _value,\n bytes memory _message\n ) external {\n address target = address(0x04); // ID precompile\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Set the minimum gas limit to the cost of the identity precompile's execution for\n // the given message.\n // ID Precompile cost can be determined by calculating: 15 + 3 * data_word_length\n uint32 minGasLimit = uint32(15 + 3 * ((_message.length + 31) / 32));\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Restrict version to the range of [0, 1]\n _version = _version % 2;\n\n // Restrict the value to the range of [0, 1]\n // This is just so we get variance of calls with and without value. The ID precompile\n // will not reject value being sent to it.\n _value = _value % 2;\n\n // If the message should succeed, supply it `baseGas`. If not, supply it an amount of\n // gas that is too low to complete the call.\n uint256 gas = doFail\n ? bound(minGasLimit, 60_000, 80_000)\n : xdm.baseGas(_message, minGasLimit);\n\n // Compute the cross domain message hash and store it in `hashes`.\n // The `relayMessage` function will always encode the message as a version 1\n // message after checking that the V0 hash has not already been relayed.\n bytes32 _hash = Hashing.hashCrossDomainMessageV1(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n _value,\n minGasLimit,\n _message\n );\n hashes.push(_hash);\n numHashes += 1;\n\n // Make sure we've got a fresh message.\n vm.assume(xdm.successfulMessages(_hash) == false && xdm.failedMessages(_hash) == false);\n\n // Act as the optimism portal and call `relayMessage` on the `L1CrossDomainMessenger` with\n // the outer min gas limit.\n vm.startPrank(address(op));\n if (!doFail) {\n vm.expectCallMinGas(address(0x04), _value, minGasLimit, _message);\n }\n try\n xdm.relayMessage{ gas: gas, value: _value }(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n _value,\n minGasLimit,\n _message\n )\n {} catch {\n // If any of these calls revert, set `reverted` to true to fail the invariant test.\n // NOTE: This is to get around forge's invariant fuzzer ignoring reverted calls\n // to this function.\n reverted = true;\n }\n vm.stopPrank();\n }\n}\n\ncontract XDM_MinGasLimits is Messenger_Initializer {\n RelayActor actor;\n\n function init(bool doFail) public virtual {\n // Set up the `L1CrossDomainMessenger` and `OptimismPortal` contracts.\n super.setUp();\n\n // Deploy a relay actor\n actor = new RelayActor(op, L1Messenger, vm, doFail);\n\n // Give the portal some ether to send to `relayMessage`\n vm.deal(address(op), type(uint128).max);\n\n // Target the `RelayActor` contract\n targetContract(address(actor));\n\n // Don't allow the estimation address to be the sender\n excludeSender(Constants.ESTIMATION_ADDRESS);\n\n // Target the actor's `relay` function\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.relay.selector;\n targetSelector(FuzzSelector({ addr: address(actor), selectors: selectors }));\n }\n}\n\ncontract XDM_MinGasLimits_Succeeds is XDM_MinGasLimits {\n function setUp() public override {\n // Don't fail\n super.init(false);\n }\n\n /**\n * @custom:invariant A call to `relayMessage` should succeed if at least the minimum gas limit\n * can be supplied to the target context, there is enough gas to complete\n * execution of `relayMessage` after the target context's execution is\n * finished, and the target context did not revert.\n *\n * There are two minimum gas limits here:\n *\n * - The outer min gas limit is for the call from the `OptimismPortal` to the\n * `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function\n * with the `message` and inner limit.\n *\n * - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target\n * contract.\n */\n function invariant_minGasLimits() external {\n uint256 length = actor.numHashes();\n for (uint256 i = 0; i < length; ++i) {\n bytes32 hash = actor.hashes(i);\n // The message hash is set in the successfulMessages mapping\n assertTrue(L1Messenger.successfulMessages(hash));\n // The message hash is not set in the failedMessages mapping\n assertFalse(L1Messenger.failedMessages(hash));\n }\n assertFalse(actor.reverted());\n }\n}\n\ncontract XDM_MinGasLimits_Reverts is XDM_MinGasLimits {\n function setUp() public override {\n // Do fail\n super.init(true);\n }\n\n /**\n * @custom:invariant A call to `relayMessage` should assign the message hash to the\n * `failedMessages` mapping if not enough gas is supplied to forward\n * `minGasLimit` to the target context or if there is not enough gas to\n * complete execution of `relayMessage` after the target context's execution\n * is finished.\n *\n * There are two minimum gas limits here:\n *\n * - The outer min gas limit is for the call from the `OptimismPortal` to the\n * `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function\n * with the `message` and inner limit.\n *\n * - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target\n * contract.\n */\n function invariant_minGasLimits() external {\n uint256 length = actor.numHashes();\n for (uint256 i = 0; i < length; ++i) {\n bytes32 hash = actor.hashes(i);\n // The message hash is not set in the successfulMessages mapping\n assertFalse(L1Messenger.successfulMessages(hash));\n // The message hash is set in the failedMessages mapping\n assertTrue(L1Messenger.failedMessages(hash));\n }\n assertFalse(actor.reverted());\n }\n}\n" - }, - "contracts/test/invariants/L2OutputOracle.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { L2OutputOracle_Initializer } from \"../CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../../L1/L2OutputOracle.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\n\ncontract L2OutputOracle_Proposer {\n L2OutputOracle internal oracle;\n Vm internal vm;\n\n constructor(L2OutputOracle _oracle, Vm _vm) {\n oracle = _oracle;\n vm = _vm;\n }\n\n /**\n * @dev Allows the actor to propose an L2 output to the `L2OutputOracle`\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external {\n // Act as the proposer and propose a new output.\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _l2BlockNumber, _l1BlockHash, _l1BlockNumber);\n }\n}\n\ncontract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_Initializer {\n L2OutputOracle_Proposer internal actor;\n\n function setUp() public override {\n super.setUp();\n\n // Create a proposer actor.\n actor = new L2OutputOracle_Proposer(oracle, vm);\n\n // Set the target contract to the proposer actor.\n targetContract(address(actor));\n\n // Set the target selector for `proposeL2Output`\n // `proposeL2Output` is the only function we care about, as it is the only function\n // that can modify the `l2Outputs` array in the oracle.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.proposeL2Output.selector;\n FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The block number of the output root proposals should monotonically\n * increase.\n *\n * When a new output is submitted, it should never be allowed to correspond to a block\n * number that is less than the current output.\n */\n function invariant_monotonicBlockNumIncrease() external {\n // Assert that the block number of proposals must monotonically increase.\n assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber());\n }\n}\n" - }, - "contracts/test/invariants/OptimismPortal.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Portal_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\n\ncontract OptimismPortal_Invariant_Harness is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n function setUp() public virtual override {\n super.setUp();\n\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n}\n\ncontract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization\n * period has not elapsed.\n *\n * A withdrawal that has been proven should not be able to be finalized until after\n * the finalization period has elapsed.\n */\n function invariant_cannotFinalizeBeforePeriodHasPassed() external {\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Finalize the withdrawal transaction.\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal\n * has already been finalized.\n *\n * Ensures that there is no chain of calls that can be made that allows a withdrawal\n * to be finalized twice.\n */\n function invariant_cannotFinalizeTwice() external {\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant A withdrawal should **always** be able to be finalized\n * `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.\n *\n * This invariant asserts that there is no chain of calls that can be made that\n * will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS`\n * after it was successfully proven.\n */\n function invariant_canAlwaysFinalize() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value);\n }\n}\n" - }, - "contracts/test/invariants/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { SafeCall } from \"../../libraries/SafeCall.sol\";\n\ncontract SafeCall_Succeeds_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, false);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n\n // Give the actor some ETH to work with\n vm.deal(address(actor), type(uint128).max);\n }\n\n /**\n * @custom:invariant If `callWithMinGas` performs a call, then it must always\n * provide at least the specified minimum gas limit to the subcontext.\n *\n * If the check for remaining gas in `SafeCall.callWithMinGas` passes, the\n * subcontext of the call below it must be provided at least `minGas` gas.\n */\n function invariant_callWithMinGas_alwaysForwardsMinGas_succeeds() public {\n assertEq(actor.numCalls(), 0, \"no failed calls allowed\");\n }\n\n function performSafeCallMinGas(address to, uint64 minGas) external payable {\n SafeCall.callWithMinGas(to, minGas, msg.value, hex\"\");\n }\n}\n\ncontract SafeCall_Fails_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, true);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n\n // Give the actor some ETH to work with\n vm.deal(address(actor), type(uint128).max);\n }\n\n /**\n * @custom:invariant `callWithMinGas` reverts if there is not enough gas to pass\n * to the subcontext.\n *\n * If there is not enough gas in the callframe to ensure that `callWithMinGas`\n * can provide the specified minimum gas limit to the subcontext of the call,\n * then `callWithMinGas` must revert.\n */\n function invariant_callWithMinGas_neverForwardsMinGas_reverts() public {\n assertEq(actor.numCalls(), 0, \"no successful calls allowed\");\n }\n\n function performSafeCallMinGas(address to, uint64 minGas) external payable {\n SafeCall.callWithMinGas(to, minGas, msg.value, hex\"\");\n }\n}\n\ncontract SafeCaller_Actor is StdUtils {\n bool internal immutable FAILS;\n\n Vm internal vm;\n uint256 public numCalls;\n\n constructor(Vm _vm, bool _fails) {\n vm = _vm;\n FAILS = _fails;\n }\n\n function performSafeCallMinGas(\n uint64 gas,\n uint64 minGas,\n address to,\n uint8 value\n ) external {\n // Only send to EOAs - we exclude the console as it has no code but reverts when called\n // with a selector that doesn't exist due to the foundry hook.\n vm.assume(to.code.length == 0 && to != 0x000000000000000000636F6e736F6c652e6c6f67);\n\n // Bound the minimum gas amount to [2500, type(uint48).max]\n minGas = uint64(bound(minGas, 2500, type(uint48).max));\n if (FAILS) {\n // Bound the gas passed to [minGas, ((minGas * 64) / 63)]\n gas = uint64(bound(gas, minGas, (minGas * 64) / 63));\n } else {\n // Bound the gas passed to\n // [((minGas * 64) / 63) + 40_000 + 1000, type(uint64).max]\n // The extra 1000 gas is to account for the gas used by the `SafeCall.call` call\n // itself.\n gas = uint64(bound(gas, ((minGas * 64) / 63) + 40_000 + 1000, type(uint64).max));\n }\n\n vm.expectCallMinGas(to, value, minGas, hex\"\");\n bool success = SafeCall.call(\n msg.sender,\n gas,\n value,\n abi.encodeWithSelector(\n SafeCall_Succeeds_Invariants.performSafeCallMinGas.selector,\n to,\n minGas\n )\n );\n\n if (success && FAILS) numCalls++;\n if (!FAILS && !success) numCalls++;\n }\n}\n" - }, - "contracts/test/invariants/SystemConfig.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { SystemConfig } from \"../../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../../L1/ResourceMetering.sol\";\nimport { Constants } from \"../../libraries/Constants.sol\";\n\ncontract SystemConfig_GasLimitLowerBound_Invariant is Test {\n SystemConfig public config;\n\n function setUp() public {\n ResourceMetering.ResourceConfig memory cfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n config = new SystemConfig({\n _owner: address(0xbeef),\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n\n // Set the target contract to the `config`\n targetContract(address(config));\n // Set the target sender to the `config`'s owner (0xbeef)\n targetSender(address(0xbeef));\n // Set the target selector for `setGasLimit`\n // `setGasLimit` is the only function we care about, as it is the only function\n // that can modify the gas limit within the SystemConfig.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = config.setGasLimit.selector;\n FuzzSelector memory selector = FuzzSelector({\n addr: address(config),\n selectors: selectors\n });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The gas limit of the `SystemConfig` contract can never be lower\n * than the hard-coded lower bound.\n */\n function invariant_gasLimitLowerBound() external {\n assertTrue(config.gasLimit() >= config.minimumGasLimit());\n }\n}\n" - }, - "contracts/universal/CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer0\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * libAddressManager variable used to exist. Must be the first contract in the inheritance\n * tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer0 {\n /**\n * @custom:legacy\n * @custom:spacer libAddressManager\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n}\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer1\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * PausableUpgradable and OwnableUpgradeable variables used to exist. Must be\n * the third contract in the inheritance tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer1 {\n /**\n * @custom:legacy\n * @custom:spacer ContextUpgradable's __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable.\n *\n */\n uint256[50] private spacer_1_0_1600;\n\n /**\n * @custom:legacy\n * @custom:spacer OwnableUpgradeable's _owner\n * @notice Spacer for backwards compatibility.\n * Come from OpenZeppelin OwnableUpgradeable.\n */\n address private spacer_51_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer OwnableUpgradeable's __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * OwnableUpgradeable.\n */\n uint256[49] private spacer_52_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer PausableUpgradable's _paused\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n bool private spacer_101_0_1;\n\n /**\n * @custom:legacy\n * @custom:spacer PausableUpgradable's __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n uint256[49] private spacer_102_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer ReentrancyGuardUpgradeable's `_status` field.\n * @notice Spacer for backwards compatibility.\n */\n uint256 private spacer_151_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer ReentrancyGuardUpgradeable's __gap\n * @notice Spacer for backwards compatibility.\n */\n uint256[49] private spacer_152_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer blockedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_201_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer relayedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_202_0_32;\n}\n\n/**\n * @custom:upgradeable\n * @title CrossDomainMessenger\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\n * cross-chain messenger contracts. It's designed to be a universal interface that only\n * needs to be extended slightly to provide low-level message passing functionality on each\n * chain it's deployed on. Currently only designed for message passing between two paired\n * chains and does not support one-to-many interactions.\n *\n * Any changes to this contract MUST result in a semver bump for contracts that inherit it.\n */\nabstract contract CrossDomainMessenger is\n CrossDomainMessengerLegacySpacer0,\n Initializable,\n CrossDomainMessengerLegacySpacer1\n{\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Constant overhead added to the base gas for a message.\n */\n uint64 public constant RELAY_CONSTANT_OVERHEAD = 200_000;\n\n /**\n * @notice Numerator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 64;\n\n /**\n * @notice Denominator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 63;\n\n /**\n * @notice Extra gas added to base gas for each byte of calldata in a message.\n */\n uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\n\n /**\n * @notice Gas reserved for performing the external call in `relayMessage`.\n */\n uint64 public constant RELAY_CALL_OVERHEAD = 40_000;\n\n /**\n * @notice Gas reserved for finalizing the execution of `relayMessage` after the safe call.\n */\n uint64 public constant RELAY_RESERVED_GAS = 40_000;\n\n /**\n * @notice Gas reserved for the execution between the `hasMinGas` check and the external\n * call in `relayMessage`.\n */\n uint64 public constant RELAY_GAS_CHECK_BUFFER = 5_000;\n\n /**\n * @notice Address of the paired CrossDomainMessenger contract on the other chain.\n */\n address public immutable OTHER_MESSENGER;\n\n /**\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n * be present in this mapping if it has successfully been relayed on this chain, and\n * can therefore not be relayed again.\n */\n mapping(bytes32 => bool) public successfulMessages;\n\n /**\n * @notice Address of the sender of the currently executing message on the other chain. If the\n * value of this variable is the default value (0x00000000...dead) then no message is\n * currently being executed. Use the xDomainMessageSender getter which will throw an\n * error if this is the case.\n */\n address internal xDomainMsgSender;\n\n /**\n * @notice Nonce for the next message to be sent, without the message version applied. Use the\n * messageNonce getter which will insert the message version into the nonce to give you\n * the actual nonce to be used for the message.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Mapping of message hashes to a boolean if and only if the message has failed to be\n * executed at least once. A message will not be present in this mapping if it\n * successfully executed on the first attempt.\n */\n mapping(bytes32 => bool) public failedMessages;\n\n /**\n * @notice Reserve extra slots in the storage layout for future upgrades.\n * A gap size of 41 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[42] private __gap;\n\n /**\n * @notice Emitted whenever a message is sent to the other chain.\n *\n * @param target Address of the recipient of the message.\n * @param sender Address of the sender of the message.\n * @param message Message to trigger the recipient address with.\n * @param messageNonce Unique nonce attached to the message.\n * @param gasLimit Minimum gas limit that the message can be executed with.\n */\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n /**\n * @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the\n * SentMessage event without breaking the ABI of this contract, this is good enough.\n *\n * @param sender Address of the sender of the message.\n * @param value ETH value sent along with the message to the recipient.\n */\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n /**\n * @notice Emitted whenever a message is successfully relayed on this chain.\n *\n * @param msgHash Hash of the message that was relayed.\n */\n event RelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @notice Emitted whenever a message fails to be relayed on this chain.\n *\n * @param msgHash Hash of the message that failed to be relayed.\n */\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @param _otherMessenger Address of the messenger on the paired chain.\n */\n constructor(address _otherMessenger) {\n OTHER_MESSENGER = _otherMessenger;\n }\n\n /**\n * @notice Sends a message to some target address on the other chain. Note that if the call\n * always reverts, then the message will be unrelayable, and any ETH sent will be\n * permanently locked. The same will occur if the target on the other chain is\n * considered unsafe (see the _isUnsafeTarget() function).\n *\n * @param _target Target contract or wallet address.\n * @param _message Message to trigger the target address with.\n * @param _minGasLimit Minimum gas limit that the message can be executed with.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _minGasLimit\n ) external payable {\n // Triggers a message to the other messenger. Note that the amount of gas provided to the\n // message is the amount of gas requested by the user PLUS the base gas value. We want to\n // guarantee the property that the call to the target contract will always have at least\n // the minimum gas limit specified by the user.\n _sendMessage(\n OTHER_MESSENGER,\n baseGas(_message, _minGasLimit),\n msg.value,\n abi.encodeWithSelector(\n this.relayMessage.selector,\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _minGasLimit,\n _message\n )\n );\n\n emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit);\n emit SentMessageExtension1(msg.sender, msg.value);\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\n * be executed via cross-chain call from the other messenger OR if the message was\n * already received once and is currently being replayed.\n *\n * @param _nonce Nonce of the message being relayed.\n * @param _sender Address of the user who sent the message.\n * @param _target Address that the message is targeted at.\n * @param _value ETH value to send with the message.\n * @param _minGasLimit Minimum amount of gas that the message can be executed with.\n * @param _message Message to send to the target.\n */\n function relayMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _minGasLimit,\n bytes calldata _message\n ) external payable {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n require(\n version < 2,\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // If the message is version 0, then it's a migrated legacy withdrawal. We therefore need\n // to check that the legacy version of the message has not already been relayed.\n if (version == 0) {\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce);\n require(\n successfulMessages[oldHash] == false,\n \"CrossDomainMessenger: legacy withdrawal already relayed\"\n );\n }\n\n // We use the v1 message hash as the unique identifier for the message because it commits\n // to the value and minimum gas limit of the message.\n bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _minGasLimit,\n _message\n );\n\n if (_isOtherMessenger()) {\n // These properties should always hold when the message is first submitted (as\n // opposed to being replayed).\n assert(msg.value == _value);\n assert(!failedMessages[versionedHash]);\n } else {\n require(\n msg.value == 0,\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n\n require(\n failedMessages[versionedHash],\n \"CrossDomainMessenger: message cannot be replayed\"\n );\n }\n\n require(\n _isUnsafeTarget(_target) == false,\n \"CrossDomainMessenger: cannot send message to blocked system address\"\n );\n\n require(\n successfulMessages[versionedHash] == false,\n \"CrossDomainMessenger: message has already been relayed\"\n );\n\n // If there is not enough gas left to perform the external call and finish the execution,\n // return early and assign the message to the failedMessages mapping.\n // We are asserting that we have enough gas to:\n // 1. Call the target contract (_minGasLimit + RELAY_CALL_OVERHEAD + RELAY_GAS_CHECK_BUFFER)\n // 1.a. The RELAY_CALL_OVERHEAD is included in `hasMinGas`.\n // 2. Finish the execution after the external call (RELAY_RESERVED_GAS).\n //\n // If `xDomainMsgSender` is not the default L2 sender, this function\n // is being re-entered. This marks the message as failed to allow it to be replayed.\n if (\n !SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER) ||\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER\n ) {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n\n return;\n }\n\n xDomainMsgSender = _sender;\n bool success = SafeCall.call(_target, gasleft() - RELAY_RESERVED_GAS, _value, _message);\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n\n if (success) {\n successfulMessages[versionedHash] = true;\n emit RelayedMessage(versionedHash);\n } else {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n }\n }\n\n /**\n * @notice Retrieves the address of the contract or wallet that initiated the currently\n * executing message on the other chain. Will throw an error if there is no message\n * currently being executed. Allows the recipient of a call to see who triggered it.\n *\n * @return Address of the sender of the currently executing message on the other chain.\n */\n function xDomainMessageSender() external view returns (address) {\n require(\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER,\n \"CrossDomainMessenger: xDomainMessageSender is not set\"\n );\n\n return xDomainMsgSender;\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n\n /**\n * @notice Computes the amount of gas required to guarantee that a given message will be\n * received on the other chain without running out of gas. Guaranteeing that a message\n * will not run out of gas is important because this ensures that a message can always\n * be replayed on the other chain if it fails to execute completely.\n *\n * @param _message Message to compute the amount of required gas for.\n * @param _minGasLimit Minimum desired gas limit when message goes to target.\n *\n * @return Amount of gas required to guarantee message receipt.\n */\n function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {\n return\n // Constant overhead\n RELAY_CONSTANT_OVERHEAD +\n // Calldata overhead\n (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\n // Dynamic overhead (EIP-150)\n ((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\n MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\n // Gas reserved for the worst-case cost of 3/5 of the `CALL` opcode's dynamic gas\n // factors. (Conservative)\n RELAY_CALL_OVERHEAD +\n // Relay reserved gas (to ensure execution of `relayMessage` completes after the\n // subcontext finishes executing) (Conservative)\n RELAY_RESERVED_GAS +\n // Gas reserved for the execution between the `hasMinGas` check and the `CALL`\n // opcode. (Conservative)\n RELAY_GAS_CHECK_BUFFER;\n }\n\n /**\n * @notice Intializer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __CrossDomainMessenger_init() internal onlyInitializing {\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n }\n\n /**\n * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @param _to Recipient of the message on the other chain.\n * @param _gasLimit Minimum gas limit the message can be executed with.\n * @param _value Amount of ETH to send with the message.\n * @param _data Message data.\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal virtual;\n\n /**\n * @notice Checks whether the message is coming from the other messenger. Implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @return Whether the message is coming from the other messenger.\n */\n function _isOtherMessenger() internal view virtual returns (bool);\n\n /**\n * @notice Checks whether a given call target is a system address that could cause the\n * messenger to peform an unsafe action. This is NOT a mechanism for blocking user\n * addresses. This is ONLY used to prevent the execution of messages to specific\n * system addresses that could cause security issues, e.g., having the\n * CrossDomainMessenger send messages to itself.\n *\n * @param _target Address of the contract to check.\n *\n * @return Whether or not the address is an unsafe system address.\n */\n function _isUnsafeTarget(address _target) internal view virtual returns (bool);\n}\n" - }, - "contracts/universal/ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721Bridge\n * @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.\n */\nabstract contract ERC721Bridge {\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Address of the bridge on the other network.\n */\n address public immutable OTHER_BRIDGE;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[49] private __gap;\n\n /**\n * @notice Emitted when an ERC721 bridge to the other network is initiated.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC721 bridge from the other network is finalized.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) && MESSENGER.xDomainMessageSender() == OTHER_BRIDGE,\n \"ERC721Bridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge) {\n require(_messenger != address(0), \"ERC721Bridge: messenger cannot be address(0)\");\n require(_otherBridge != address(0), \"ERC721Bridge: other bridge cannot be address(0)\");\n\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = _otherBridge;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for other bridge address.\n *\n * @return Address of the bridge on the other network.\n */\n function otherBridge() external view returns (address) {\n return OTHER_BRIDGE;\n }\n\n /**\n * @notice Initiates a bridge of an NFT to the caller's account on the other chain. Note that\n * this function can only be called by EOAs. Smart contract wallets should use the\n * `bridgeERC721To` function after ensuring that the recipient address on the remote\n * chain exists. Also note that the current owner of the token on this chain must\n * approve this contract to operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721(\n address _localToken,\n address _remoteToken,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n // Modifier requiring sender to be EOA. This prevents against a user error that would occur\n // if the sender is a smart contract wallet that has a different address on the remote chain\n // (or doesn't have an address on the remote chain at all). The user would fail to receive\n // the NFT if they use this function because it sends the NFT to the same address as the\n // caller. This check could be bypassed by a malicious contract via initcode, but it takes\n // care of the user error we want to avoid.\n require(!Address.isContract(msg.sender), \"ERC721Bridge: account is not externally owned\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note\n * that the current owner of the token on this chain must approve this contract to\n * operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n require(_to != address(0), \"ERC721Bridge: nft recipient cannot be address(0)\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Internal function for initiating a token bridge to the other domain.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _from Address of the sender on this domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other domain. Data supplied here will\n * not be used to execute any code on the other domain and is only emitted\n * as extra data for the convenience of off-chain tooling.\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal virtual;\n}\n" - }, - "contracts/universal/FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n/**\n * @title FeeVault\n * @notice The FeeVault contract contains the basic logic for the various different vault contracts\n * used to hold fee revenue generated by the L2 system.\n */\nabstract contract FeeVault {\n /**\n * @notice Emits each time that a withdrawal occurs.\n *\n * @param value Amount that was withdrawn (in wei).\n * @param to Address that the funds were sent to.\n * @param from Address that triggered the withdrawal.\n */\n event Withdrawal(uint256 value, address to, address from);\n\n /**\n * @notice Minimum balance before a withdrawal can be triggered.\n */\n uint256 public immutable MIN_WITHDRAWAL_AMOUNT;\n\n /**\n * @notice Wallet that will receive the fees on L1.\n */\n address public immutable RECIPIENT;\n\n /**\n * @notice The minimum gas limit for the FeeVault withdrawal transaction.\n */\n uint32 internal constant WITHDRAWAL_MIN_GAS = 35_000;\n\n /**\n * @notice Total amount of wei processed by the contract.\n */\n uint256 public totalProcessed;\n\n /**\n * @param _recipient Wallet that will receive the fees on L1.\n * @param _minWithdrawalAmount Minimum balance before a withdrawal can be triggered.\n */\n constructor(address _recipient, uint256 _minWithdrawalAmount) {\n MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;\n RECIPIENT = _recipient;\n }\n\n /**\n * @notice Allow the contract to receive ETH.\n */\n receive() external payable {}\n\n /**\n * @notice Triggers a withdrawal of funds to the L1 fee wallet.\n */\n function withdraw() external {\n require(\n address(this).balance >= MIN_WITHDRAWAL_AMOUNT,\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n\n uint256 value = address(this).balance;\n totalProcessed += value;\n\n emit Withdrawal(value, RECIPIENT, msg.sender);\n\n L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }(\n RECIPIENT,\n WITHDRAWAL_MIN_GAS,\n bytes(\"\")\n );\n }\n}\n" - }, - "contracts/universal/IOptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @title IOptimismMintableERC20\n * @notice This interface is available on the OptimismMintableERC20 contract. We declare it as a\n * separate interface so that it can be used in custom implementations of\n * OptimismMintableERC20.\n */\ninterface IOptimismMintableERC20 is IERC165 {\n function remoteToken() external view returns (address);\n\n function bridge() external returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n\n/**\n * @custom:legacy\n * @title ILegacyMintableERC20\n * @notice This interface was available on the legacy L2StandardERC20 contract. It remains available\n * on the OptimismMintableERC20 contract for backwards compatibility.\n */\ninterface ILegacyMintableERC20 is IERC165 {\n function l1Token() external view returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n" - }, - "contracts/universal/IOptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\n/**\n * @title IOptimismMintableERC721\n * @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.\n * Tokens that follow this standard can be easily transferred across the ERC721 bridge.\n */\ninterface IOptimismMintableERC721 is IERC721Enumerable {\n /**\n * @notice Emitted when a token is minted.\n *\n * @param account Address of the account the token was minted to.\n * @param tokenId Token ID of the minted token.\n */\n event Mint(address indexed account, uint256 tokenId);\n\n /**\n * @notice Emitted when a token is burned.\n *\n * @param account Address of the account the token was burned from.\n * @param tokenId Token ID of the burned token.\n */\n event Burn(address indexed account, uint256 tokenId);\n\n /**\n * @notice Mints some token ID for a user, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * @param _to Address of the user to mint the token for.\n * @param _tokenId Token ID to mint.\n */\n function safeMint(address _to, uint256 _tokenId) external;\n\n /**\n * @notice Burns a token ID from a user.\n *\n * @param _from Address of the user to burn the token from.\n * @param _tokenId Token ID to burn.\n */\n function burn(address _from, uint256 _tokenId) external;\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function REMOTE_CHAIN_ID() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function REMOTE_TOKEN() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function BRIDGE() external view returns (address);\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function remoteChainId() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function remoteToken() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function bridge() external view returns (address);\n}\n" - }, - "contracts/universal/OptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { ILegacyMintableERC20, IOptimismMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC20\n * @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed\n * to allow the StandardBridge contracts to mint and burn tokens. This makes it possible to\n * use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa.\n * Designed to be backwards compatible with the older StandardL2ERC20 token which was only\n * meant for use on L2.\n */\ncontract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, Semver {\n /**\n * @notice Address of the corresponding version of this token on the remote chain.\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @notice Address of the StandardBridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Emitted whenever tokens are minted for an account.\n *\n * @param account Address of the account tokens are being minted for.\n * @param amount Amount of tokens minted.\n */\n event Mint(address indexed account, uint256 amount);\n\n /**\n * @notice Emitted whenever tokens are burned from an account.\n *\n * @param account Address of the account tokens are being burned from.\n * @param amount Amount of tokens burned.\n */\n event Burn(address indexed account, uint256 amount);\n\n /**\n * @notice A modifier that only allows the bridge to call\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC20: only bridge can mint and burn\");\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the L2 standard bridge.\n * @param _remoteToken Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _bridge,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) Semver(1, 0, 0) {\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n }\n\n /**\n * @notice Allows the StandardBridge on this network to mint tokens.\n *\n * @param _to Address to mint tokens to.\n * @param _amount Amount of tokens to mint.\n */\n function mint(address _to, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _mint(_to, _amount);\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Allows the StandardBridge on this network to burn tokens.\n *\n * @param _from Address to burn tokens from.\n * @param _amount Amount of tokens to burn.\n */\n function burn(address _from, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _burn(_from, _amount);\n emit Burn(_from, _amount);\n }\n\n /**\n * @notice ERC165 interface check function.\n *\n * @param _interfaceId Interface ID to check.\n *\n * @return Whether or not the interface is supported by this contract.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 iface1 = type(IERC165).interfaceId;\n // Interface corresponding to the legacy L2StandardERC20.\n bytes4 iface2 = type(ILegacyMintableERC20).interfaceId;\n // Interface corresponding to the updated OptimismMintableERC20 (this contract).\n bytes4 iface3 = type(IOptimismMintableERC20).interfaceId;\n return _interfaceId == iface1 || _interfaceId == iface2 || _interfaceId == iface3;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote token. Use REMOTE_TOKEN going forward.\n */\n function l1Token() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the bridge. Use BRIDGE going forward.\n */\n function l2Bridge() public view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for REMOTE_TOKEN.\n */\n function remoteToken() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for BRIDGE.\n */\n function bridge() public view returns (address) {\n return BRIDGE;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC20Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Contract Imports */\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000012\n * @title OptimismMintableERC20Factory\n * @notice OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20\n * contracts on the network it's deployed to. Simplifies the deployment process for users\n * who may be less familiar with deploying smart contracts. Designed to be backwards\n * compatible with the older StandardL2ERC20Factory contract.\n */\ncontract OptimismMintableERC20Factory is Semver {\n /**\n * @notice Address of the StandardBridge on this chain.\n */\n address public immutable BRIDGE;\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a new OptimismMintableERC20 is created. Legacy version of the newer\n * OptimismMintableERC20Created event. We recommend relying on that event instead.\n *\n * @param remoteToken Address of the token on the remote chain.\n * @param localToken Address of the created token on the local chain.\n */\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC20 is created.\n *\n * @param localToken Address of the created token on the local chain.\n * @param remoteToken Address of the corresponding token on the remote chain.\n * @param deployer Address of the account that deployed the token.\n */\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC20 token contract since this contract\n * is responsible for deploying OptimismMintableERC20 contracts.\n *\n * @param _bridge Address of the StandardBridge on this chain.\n */\n constructor(address _bridge) Semver(1, 1, 0) {\n BRIDGE = _bridge;\n }\n\n /**\n * @custom:legacy\n * @notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the\n * newer createOptimismMintableERC20 function, which has a more intuitive name.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createStandardL2Token(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n return createOptimismMintableERC20(_remoteToken, _name, _symbol);\n }\n\n /**\n * @notice Creates an instance of the OptimismMintableERC20 contract.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createOptimismMintableERC20(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) public returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC20Factory: must provide remote token address\"\n );\n\n address localToken = address(\n new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol)\n );\n\n // Emit the old event too for legacy support.\n emit StandardL2TokenCreated(_remoteToken, localToken);\n\n // Emit the updated event. The arguments here differ from the legacy event, but\n // are consistent with the ordering used in StandardBridge events.\n emit OptimismMintableERC20Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n ERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { IOptimismMintableERC721 } from \"./IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC721\n * @notice This contract is the remote representation for some token that lives on another network,\n * typically an Optimism representation of an Ethereum-based token. Standard reference\n * implementation that can be extended or modified according to your needs.\n */\ncontract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Semver {\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Base token URI for this token.\n */\n string public baseTokenURI;\n\n /**\n * @notice Modifier that prevents callers other than the bridge from calling the function.\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC721: only bridge can call this function\");\n _;\n }\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _bridge Address of the bridge on this network.\n * @param _remoteChainId Chain ID where the remote token is deployed.\n * @param _remoteToken Address of the corresponding token on the other network.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n constructor(\n address _bridge,\n uint256 _remoteChainId,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) Semver(1, 1, 0) {\n require(_bridge != address(0), \"OptimismMintableERC721: bridge cannot be address(0)\");\n require(_remoteChainId != 0, \"OptimismMintableERC721: remote chain id cannot be zero\");\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721: remote token cannot be address(0)\"\n );\n\n REMOTE_CHAIN_ID = _remoteChainId;\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n\n // Creates a base URI in the format specified by EIP-681:\n // https://eips.ethereum.org/EIPS/eip-681\n baseTokenURI = string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(_remoteToken), 20),\n \"@\",\n Strings.toString(_remoteChainId),\n \"/tokenURI?uint256=\"\n )\n );\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteChainId() external view returns (uint256) {\n return REMOTE_CHAIN_ID;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteToken() external view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function bridge() external view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function safeMint(address _to, uint256 _tokenId) external virtual onlyBridge {\n _safeMint(_to, _tokenId);\n\n emit Mint(_to, _tokenId);\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function burn(address _from, uint256 _tokenId) external virtual onlyBridge {\n _burn(_tokenId);\n\n emit Burn(_from, _tokenId);\n }\n\n /**\n * @notice Checks if a given interface ID is supported by this contract.\n *\n * @param _interfaceId The interface ID to check.\n *\n * @return True if the interface ID is supported, false otherwise.\n */\n function supportsInterface(bytes4 _interfaceId)\n public\n view\n override(ERC721Enumerable, IERC165)\n returns (bool)\n {\n bytes4 iface = type(IOptimismMintableERC721).interfaceId;\n return _interfaceId == iface || super.supportsInterface(_interfaceId);\n }\n\n /**\n * @notice Returns the base token URI.\n *\n * @return Base token URI.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return baseTokenURI;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismMintableERC721 } from \"./OptimismMintableERC721.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @title OptimismMintableERC721Factory\n * @notice Factory contract for creating OptimismMintableERC721 contracts.\n */\ncontract OptimismMintableERC721Factory is Semver {\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Chain ID for the remote network.\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @notice Tracks addresses created by this factory.\n */\n mapping(address => bool) public isOptimismMintableERC721;\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC721 contract is created.\n *\n * @param localToken Address of the token on the this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param deployer Address of the initiator of the deployment\n */\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.2.0\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC721 token contract since this contract\n * is responsible for deploying OptimismMintableERC721 contracts.\n *\n * @param _bridge Address of the ERC721 bridge on this network.\n * @param _remoteChainId Chain ID for the remote network.\n */\n constructor(address _bridge, uint256 _remoteChainId) Semver(1, 2, 0) {\n BRIDGE = _bridge;\n REMOTE_CHAIN_ID = _remoteChainId;\n }\n\n /**\n * @notice Creates an instance of the standard ERC721.\n *\n * @param _remoteToken Address of the corresponding token on the other domain.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n function createOptimismMintableERC721(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721Factory: L1 token address cannot be address(0)\"\n );\n\n address localToken = address(\n new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)\n );\n\n isOptimismMintableERC721[localToken] = true;\n emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/Proxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Proxy\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\n * if the caller is address(0), meaning that the call originated from an off-chain\n * simulation.\n */\ncontract Proxy {\n /**\n * @notice The storage slot that holds the address of the implementation.\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice The storage slot that holds the address of the owner.\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice An event that is emitted each time the implementation is changed. This event is part\n * of the EIP-1967 specification.\n *\n * @param implementation The address of the implementation contract\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\n * EIP-1967 specification.\n *\n * @param previousAdmin The previous owner of the contract\n * @param newAdmin The new owner of the contract\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\n * eth_call to interact with this proxy without needing to use low-level storage\n * inspection. We assume that nobody is able to trigger calls from address(0) during\n * normal EVM execution.\n */\n modifier proxyCallIfNotAdmin() {\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\n * EIP-1967 admin storage slot so that accidental storage collision with the\n * implementation is not possible.\n *\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\n * transparent proxy interface.\n */\n constructor(address _admin) {\n _changeAdmin(_admin);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Set the implementation contract address. The code at the given address will execute\n * when this contract is called.\n *\n * @param _implementation Address of the implementation contract.\n */\n function upgradeTo(address _implementation) public virtual proxyCallIfNotAdmin {\n _setImplementation(_implementation);\n }\n\n /**\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\n * atomic execution of initialization-based upgrades.\n *\n * @param _implementation Address of the implementation contract.\n * @param _data Calldata to delegatecall the new implementation with.\n */\n function upgradeToAndCall(address _implementation, bytes calldata _data)\n public\n payable\n virtual\n proxyCallIfNotAdmin\n returns (bytes memory)\n {\n _setImplementation(_implementation);\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\n require(success, \"Proxy: delegatecall to new implementation contract failed\");\n return returndata;\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _admin New owner of the proxy contract.\n */\n function changeAdmin(address _admin) public virtual proxyCallIfNotAdmin {\n _changeAdmin(_admin);\n }\n\n /**\n * @notice Gets the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function admin() public virtual proxyCallIfNotAdmin returns (address) {\n return _getAdmin();\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function implementation() public virtual proxyCallIfNotAdmin returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n emit Upgraded(_implementation);\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _admin New owner of the proxy contract.\n */\n function _changeAdmin(address _admin) internal {\n address previous = _getAdmin();\n assembly {\n sstore(OWNER_KEY, _admin)\n }\n emit AdminChanged(previous, _admin);\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal {\n address impl = _getImplementation();\n require(impl != address(0), \"Proxy: implementation not initialized\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address impl;\n assembly {\n impl := sload(IMPLEMENTATION_KEY)\n }\n return impl;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getAdmin() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n}\n" - }, - "contracts/universal/ProxyAdmin.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { Proxy } from \"./Proxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\n\n/**\n * @title IStaticERC1967Proxy\n * @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface.\n */\ninterface IStaticERC1967Proxy {\n function implementation() external view returns (address);\n\n function admin() external view returns (address);\n}\n\n/**\n * @title IStaticL1ChugSplashProxy\n * @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface.\n */\ninterface IStaticL1ChugSplashProxy {\n function getImplementation() external view returns (address);\n\n function getOwner() external view returns (address);\n}\n\n/**\n * @title ProxyAdmin\n * @notice This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy,\n * based on the OpenZeppelin implementation. It has backwards compatibility logic to work\n * with the various types of proxies that have been deployed by Optimism in the past.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @notice The proxy types that the ProxyAdmin can manage.\n *\n * @custom:value ERC1967 Represents an ERC1967 compliant transparent proxy interface.\n * @custom:value CHUGSPLASH Represents the Chugsplash proxy interface (legacy).\n * @custom:value RESOLVED Represents the ResolvedDelegate proxy (legacy).\n */\n enum ProxyType {\n ERC1967,\n CHUGSPLASH,\n RESOLVED\n }\n\n /**\n * @notice A mapping of proxy types, used for backwards compatibility.\n */\n mapping(address => ProxyType) public proxyType;\n\n /**\n * @notice A reverse mapping of addresses to names held in the AddressManager. This must be\n * manually kept up to date with changes in the AddressManager for this contract\n * to be able to work as an admin for the ResolvedDelegateProxy type.\n */\n mapping(address => string) public implementationName;\n\n /**\n * @notice The address of the address manager, this is required to manage the\n * ResolvedDelegateProxy type.\n */\n AddressManager public addressManager;\n\n /**\n * @notice A legacy upgrading indicator used by the old Chugsplash Proxy.\n */\n bool internal upgrading;\n\n /**\n * @param _owner Address of the initial owner of this contract.\n */\n constructor(address _owner) Ownable() {\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the proxy type for a given address. Only required for non-standard (legacy)\n * proxy types.\n *\n * @param _address Address of the proxy.\n * @param _type Type of the proxy.\n */\n function setProxyType(address _address, ProxyType _type) external onlyOwner {\n proxyType[_address] = _type;\n }\n\n /**\n * @notice Sets the implementation name for a given address. Only required for\n * ResolvedDelegateProxy type proxies that have an implementation name.\n *\n * @param _address Address of the ResolvedDelegateProxy.\n * @param _name Name of the implementation for the proxy.\n */\n function setImplementationName(address _address, string memory _name) external onlyOwner {\n implementationName[_address] = _name;\n }\n\n /**\n * @notice Set the address of the AddressManager. This is required to manage legacy\n * ResolvedDelegateProxy type proxy contracts.\n *\n * @param _address Address of the AddressManager.\n */\n function setAddressManager(AddressManager _address) external onlyOwner {\n addressManager = _address;\n }\n\n /**\n * @custom:legacy\n * @notice Set an address in the address manager. Since only the owner of the AddressManager\n * can directly modify addresses and the ProxyAdmin will own the AddressManager, this\n * gives the owner of the ProxyAdmin the ability to modify addresses directly.\n *\n * @param _name Name to set within the AddressManager.\n * @param _address Address to attach to the given name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n addressManager.setAddress(_name, _address);\n }\n\n /**\n * @custom:legacy\n * @notice Set the upgrading status for the Chugsplash proxy type.\n *\n * @param _upgrading Whether or not the system is upgrading.\n */\n function setUpgrading(bool _upgrading) external onlyOwner {\n upgrading = _upgrading;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\n *\n * @return Whether or not there is an upgrade going on. May not actually tell you whether an\n * upgrade is going on, since we don't currently plan to use this variable for anything\n * other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\n */\n function isUpgrading() external view returns (bool) {\n return upgrading;\n }\n\n /**\n * @notice Returns the implementation of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the implementation of.\n *\n * @return Address of the implementation of the proxy.\n */\n function getProxyImplementation(address _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).implementation();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getImplementation();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.getAddress(implementationName[_proxy]);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Returns the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the admin of.\n *\n * @return Address of the admin of the proxy.\n */\n function getProxyAdmin(address payable _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).admin();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getOwner();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.owner();\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Updates the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to update.\n * @param _newAdmin Address of the new proxy admin.\n */\n function changeProxyAdmin(address payable _proxy, address _newAdmin) external onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).changeAdmin(_newAdmin);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setOwner(_newAdmin);\n } else if (ptype == ProxyType.RESOLVED) {\n addressManager.transferOwnership(_newAdmin);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n */\n function upgrade(address payable _proxy, address _implementation) public onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeTo(_implementation);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setStorage(\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n bytes32(uint256(uint160(_implementation)))\n );\n } else if (ptype == ProxyType.RESOLVED) {\n string memory name = implementationName[_proxy];\n addressManager.setAddress(name, _implementation);\n } else {\n // It should not be possible to retrieve a ProxyType value which is not matched by\n // one of the previous conditions.\n assert(false);\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract and delegatecalls the new implementation\n * with some given data. Useful for atomic upgrade-and-initialize calls.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n * @param _data Data to trigger the new implementation with.\n */\n function upgradeAndCall(\n address payable _proxy,\n address _implementation,\n bytes memory _data\n ) external payable onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);\n } else {\n // reverts if proxy type is unknown\n upgrade(_proxy, _implementation);\n (bool success, ) = _proxy.call{ value: msg.value }(_data);\n require(success, \"ProxyAdmin: call to proxy after upgrade failed\");\n }\n }\n}\n" - }, - "contracts/universal/Semver.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n" - }, - "contracts/universal/StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { IOptimismMintableERC20, ILegacyMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"./OptimismMintableERC20.sol\";\n\n/**\n * @custom:upgradeable\n * @title StandardBridge\n * @notice StandardBridge is a base contract for the L1 and L2 standard ERC20 bridges. It handles\n * the core bridging logic, including escrowing tokens that are native to the local chain\n * and minting/burning tokens that are native to the remote chain.\n */\nabstract contract StandardBridge {\n using SafeERC20 for IERC20;\n\n /**\n * @notice The L2 gas limit set when eth is depoisited using the receive() function.\n */\n uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000;\n\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Corresponding bridge on the other domain.\n */\n StandardBridge public immutable OTHER_BRIDGE;\n\n /**\n * @custom:legacy\n * @custom:spacer messenger\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer l2TokenBridge\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_1_0_20;\n\n /**\n * @notice Mapping that stores deposits for a given pair of local and remote tokens.\n */\n mapping(address => mapping(address => uint256)) public deposits;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n * A gap size of 47 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[47] private __gap;\n\n /**\n * @notice Emitted when an ETH bridge is initiated to the other chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ETH bridge is finalized on this chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is initiated to the other chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is finalized on this chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Only allow EOAs to call the functions. Note that this is not safe against contracts\n * calling code within their constructors, but also doesn't really matter since we're\n * just trying to prevent users accidentally depositing with smart contract wallets.\n */\n modifier onlyEOA() {\n require(\n !Address.isContract(msg.sender),\n \"StandardBridge: function can only be called from an EOA\"\n );\n _;\n }\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) &&\n MESSENGER.xDomainMessageSender() == address(OTHER_BRIDGE),\n \"StandardBridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of CrossDomainMessenger on this network.\n * @param _otherBridge Address of the other StandardBridge contract.\n */\n constructor(address payable _messenger, address payable _otherBridge) {\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = StandardBridge(_otherBridge);\n }\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n * Must be implemented by contracts that inherit.\n */\n receive() external payable virtual;\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @notice Sends ETH to the sender's address on the other chain.\n *\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETH(uint32 _minGasLimit, bytes calldata _extraData) public payable onlyEOA {\n _initiateBridgeETH(msg.sender, msg.sender, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a\n * smart contract and the call fails, the ETH will be temporarily locked in the\n * StandardBridge on the other chain until the call is replayed. If the call cannot be\n * replayed with any amount of gas (call always reverts), then the ETH will be\n * permanently locked in the StandardBridge on the other chain. ETH will also\n * be locked if the receiver is the other bridge, because finalizeBridgeETH will revert\n * in that case.\n *\n * @param _to Address of the receiver.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public payable {\n _initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ERC20 tokens to the sender's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20(\n address _localToken,\n address _remoteToken,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual onlyEOA {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public payable onlyOtherBridge {\n require(msg.value == _amount, \"StandardBridge: amount sent does not match amount required\");\n require(_to != address(this), \"StandardBridge: cannot send to self\");\n require(_to != address(MESSENGER), \"StandardBridge: cannot send to messenger\");\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n\n bool success = SafeCall.call(_to, gasleft(), _amount, hex\"\");\n require(success, \"StandardBridge: ETH transfer failed\");\n }\n\n /**\n * @notice Finalizes an ERC20 bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public onlyOtherBridge {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).mint(_to, _amount);\n } else {\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] - _amount;\n IERC20(_localToken).safeTransfer(_to, _amount);\n }\n\n // Emit the correct events. By default this will be ERC20BridgeFinalized, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Initiates a bridge of ETH through the CrossDomainMessenger.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n require(\n msg.value == _amount,\n \"StandardBridge: bridging ETH must include sufficient ETH value\"\n );\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage{ value: _amount }(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeETH.selector,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).burn(_from, _amount);\n } else {\n IERC20(_localToken).safeTransferFrom(_from, address(this), _amount);\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] + _amount;\n }\n\n // Emit the correct events. By default this will be ERC20BridgeInitiated, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeERC20.selector,\n // Because this call will be executed on the remote chain, we reverse the order of\n // the remote and local token addresses relative to their order in the\n // finalizeBridgeERC20 function.\n _remoteToken,\n _localToken,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Checks if a given address is an OptimismMintableERC20. Not perfect, but good enough.\n * Just the way we like it.\n *\n * @param _token Address of the token to check.\n *\n * @return True if the token is an OptimismMintableERC20.\n */\n function _isOptimismMintableERC20(address _token) internal view returns (bool) {\n return\n ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId) ||\n ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);\n }\n\n /**\n * @notice Checks if the \"other token\" is the correct pair token for the OptimismMintableERC20.\n * Calls can be saved in the future by combining this logic with\n * `_isOptimismMintableERC20`.\n *\n * @param _mintableToken OptimismMintableERC20 to check against.\n * @param _otherToken Pair token to check.\n *\n * @return True if the other token is the correct pair token for the OptimismMintableERC20.\n */\n function _isCorrectTokenPair(address _mintableToken, address _otherToken)\n internal\n view\n returns (bool)\n {\n if (\n ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)\n ) {\n return _otherToken == ILegacyMintableERC20(_mintableToken).l1Token();\n } else {\n return _otherToken == IOptimismMintableERC20(_mintableToken).remoteToken();\n }\n }\n\n /** @notice Emits the ETHBridgeInitiated event and if necessary the appropriate legacy event\n * when an ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ETHBridgeFinalized and if necessary the appropriate legacy event when an\n * ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeInitiated event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeFinalized event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/vendor/AddressAliasHelper.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.0;\n\nlibrary AddressAliasHelper {\n uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n /// @notice Utility function that converts the address in the L1 that submitted a tx to\n /// the inbox to the msg.sender viewed in the L2\n /// @param l1Address the address in the L1 that triggered the tx to L2\n /// @return l2Address L2 address as viewed in msg.sender\n function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {\n unchecked {\n l2Address = address(uint160(l1Address) + offset);\n }\n }\n\n /// @notice Utility function that converts the msg.sender viewed in the L2 to the\n /// address in the L1 that submitted a tx to the inbox\n /// @param l2Address L2 address as viewed in msg.sender\n /// @return l1Address the address in the L1 that triggered the tx to L2\n function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {\n unchecked {\n l1Address = address(uint160(l2Address) - offset);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/governance/utils/IVotes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20Permit.sol\";\nimport \"../../../utils/math/Math.sol\";\nimport \"../../../governance/utils/IVotes.sol\";\nimport \"../../../utils/math/SafeCast.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20Votes is IVotes, ERC20Permit {\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCast.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = Math.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSA.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"./IERC721Enumerable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n // Mapping from owner to list of owned token IDs\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n // Mapping from token ID to index of the owner tokens list\n mapping(uint256 => uint256) private _ownedTokensIndex;\n\n // Array with all token ids, used for enumeration\n uint256[] private _allTokens;\n\n // Mapping from token id to position in the allTokens array\n mapping(uint256 => uint256) private _allTokensIndex;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n return _ownedTokens[owner][index];\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _allTokens.length;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721Enumerable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n return _allTokens[index];\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n if (from == address(0)) {\n _addTokenToAllTokensEnumeration(tokenId);\n } else if (from != to) {\n _removeTokenFromOwnerEnumeration(from, tokenId);\n }\n if (to == address(0)) {\n _removeTokenFromAllTokensEnumeration(tokenId);\n } else if (to != from) {\n _addTokenToOwnerEnumeration(to, tokenId);\n }\n }\n\n /**\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\n * @param to address representing the new owner of the given token ID\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n */\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n uint256 length = ERC721.balanceOf(to);\n _ownedTokens[to][length] = tokenId;\n _ownedTokensIndex[tokenId] = length;\n }\n\n /**\n * @dev Private function to add a token to this extension's token tracking data structures.\n * @param tokenId uint256 ID of the token to be added to the tokens list\n */\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n _allTokensIndex[tokenId] = _allTokens.length;\n _allTokens.push(tokenId);\n }\n\n /**\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n * @param from address representing the previous owner of the given token ID\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n */\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary\n if (tokenIndex != lastTokenIndex) {\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n }\n\n // This also deletes the contents at the last position of the array\n delete _ownedTokensIndex[tokenId];\n delete _ownedTokens[from][lastTokenIndex];\n }\n\n /**\n * @dev Private function to remove a token from this extension's token tracking data structures.\n * This has O(1) time complexity, but alters the order of the _allTokens array.\n * @param tokenId uint256 ID of the token to be removed from the tokens list\n */\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = _allTokens.length - 1;\n uint256 tokenIndex = _allTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n // This also deletes the contents at the last position of the array\n delete _allTokensIndex[tokenId];\n _allTokens.pop();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Counters.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface,\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n _supportsERC165Interface(account, type(IERC165).interfaceId) &&\n !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)\n internal\n view\n returns (bool[] memory)\n {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in _interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!_supportsERC165Interface(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n * Interface identification is specified in ERC-165.\n */\n function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/Bytes32AddressLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Library for converting between addresses and bytes32 values.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)\nlibrary Bytes32AddressLib {\n function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {\n return bytes32(bytes20(addressValue));\n }\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n /*//////////////////////////////////////////////////////////////\n SIMPLIFIED FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n }\n\n function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n }\n\n function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n }\n\n function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n }\n\n function powWad(int256 x, int256 y) internal pure returns (int256) {\n // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\n return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\n }\n\n function expWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n // When the result is < 0.5 we return zero. This happens when\n // x <= floor(log(0.5e18) * 1e18) ~ -42e18\n if (x <= -42139678854452767551) return 0;\n\n // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\n // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\n if (x >= 135305999368893231589) revert(\"EXP_OVERFLOW\");\n\n // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\n // for more intermediate precision and a binary basis. This base conversion\n // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n x = (x << 78) / 5**18;\n\n // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\n x = x - k * 54916777467707473351141471128;\n\n // k is in the range [-61, 195].\n\n // Evaluate using a (6, 7)-term rational approximation.\n // p is made monic, we'll multiply by a scale factor later.\n int256 y = x + 1346386616545796478920950773328;\n y = ((y * x) >> 96) + 57155421227552351082224309758442;\n int256 p = y + x - 94201549194550492254356042504812;\n p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n p = p * x + (4385272521454847904659076985693276 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n int256 q = x - 2855989394907223263936484059900;\n q = ((q * x) >> 96) + 50020603652535783019961831881945;\n q = ((q * x) >> 96) - 533845033583426703283633433725380;\n q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial won't have zeros in the domain as all its roots are complex.\n // No scaling is necessary because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r should be in the range (0.09, 0.25) * 2**96.\n\n // We now need to multiply r by:\n // * the scale factor s = ~6.031367120.\n // * the 2**k factor from the range reduction.\n // * the 1e18 / 2**96 factor for base conversion.\n // We do this all at once, with an intermediate result in 2**213\n // basis, so the final right shift is always by a positive amount.\n r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\n }\n }\n\n function lnWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n require(x > 0, \"UNDEFINED\");\n\n // We want to convert x from 10**18 fixed point to 2**96 fixed point.\n // We do this by multiplying by 2**96 / 10**18. But since\n // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\n // and add ln(2**96 / 10**18) at the end.\n\n // Reduce range of x to (1, 2) * 2**96\n // ln(2^k * x) = k * ln(2) + ln(x)\n int256 k = int256(log2(uint256(x))) - 96;\n x <<= uint256(159 - k);\n x = int256(uint256(x) >> 159);\n\n // Evaluate using a (8, 8)-term rational approximation.\n // p is made monic, we will multiply by a scale factor later.\n int256 p = x + 3273285459638523848632254066296;\n p = ((p * x) >> 96) + 24828157081833163892658089445524;\n p = ((p * x) >> 96) + 43456485725739037958740375743393;\n p = ((p * x) >> 96) - 11111509109440967052023855526967;\n p = ((p * x) >> 96) - 45023709667254063763336534515857;\n p = ((p * x) >> 96) - 14706773417378608786704636184526;\n p = p * x - (795164235651350426258249787498 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n // q is monic by convention.\n int256 q = x + 5573035233440673466300451813936;\n q = ((q * x) >> 96) + 71694874799317883764090561454958;\n q = ((q * x) >> 96) + 283447036172924575727196451306956;\n q = ((q * x) >> 96) + 401686690394027663651624208769553;\n q = ((q * x) >> 96) + 204048457590392012362485061816622;\n q = ((q * x) >> 96) + 31853899698501571402653359427138;\n q = ((q * x) >> 96) + 909429971244387300277376558375;\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial is known not to have zeros in the domain.\n // No scaling required because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r is in the range (0, 0.125) * 2**96\n\n // Finalization, we need to:\n // * multiply by the scale factor s = 5.549…\n // * add ln(2**96 / 10**18)\n // * add k * ln(2)\n // * multiply by 10**18 / 2**96 = 5**18 >> 78\n\n // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\n r *= 1677202110996718588342820967067443963516166;\n // add ln(2) * k * 5e18 * 2**192\n r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\n // add ln(2**96 / 10**18) * 5e18 * 2**192\n r += 600920179829731861736702779321621459595472258049074101567377883020018308;\n // base conversion: mul 2**18 / 2**192\n r >>= 174;\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n LOW LEVEL FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function mulDivDown(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // Divide z by the denominator.\n z := div(z, denominator)\n }\n }\n\n function mulDivUp(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // First, divide z - 1 by the denominator and add 1.\n // We allow z - 1 to underflow if z is 0, because we multiply the\n // end result by 0 if z is zero, ensuring we return 0 if z is zero.\n z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\n }\n }\n\n function rpow(\n uint256 x,\n uint256 n,\n uint256 scalar\n ) internal pure returns (uint256 z) {\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n // 0 ** 0 = 1\n z := scalar\n }\n default {\n // 0 ** n = 0\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n // If n is even, store scalar in z for now.\n z := scalar\n }\n default {\n // If n is odd, store x in z for now.\n z := x\n }\n\n // Shifting right by 1 is like dividing by 2.\n let half := shr(1, scalar)\n\n for {\n // Shift n right by 1 before looping to halve it.\n n := shr(1, n)\n } n {\n // Shift n right by 1 each iteration to halve it.\n n := shr(1, n)\n } {\n // Revert immediately if x ** 2 would overflow.\n // Equivalent to iszero(eq(div(xx, x), x)) here.\n if shr(128, x) {\n revert(0, 0)\n }\n\n // Store x squared.\n let xx := mul(x, x)\n\n // Round to the nearest number.\n let xxRound := add(xx, half)\n\n // Revert if xx + half overflowed.\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n\n // Set x to scaled xxRound.\n x := div(xxRound, scalar)\n\n // If n is even:\n if mod(n, 2) {\n // Compute z * x.\n let zx := mul(z, x)\n\n // If z * x overflowed:\n if iszero(eq(div(zx, x), z)) {\n // Revert if x is non-zero.\n if iszero(iszero(x)) {\n revert(0, 0)\n }\n }\n\n // Round to the nearest number.\n let zxRound := add(zx, half)\n\n // Revert if zx + half overflowed.\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n\n // Return properly scaled zxRound.\n z := div(zxRound, scalar)\n }\n }\n }\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n GENERAL NUMBER UTILITIES\n //////////////////////////////////////////////////////////////*/\n\n function sqrt(uint256 x) internal pure returns (uint256 z) {\n assembly {\n let y := x // We start y at x, which will help us make our initial estimate.\n\n z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n // We check y >= 2^(k + 8) but shift right by k bits\n // each branch to ensure that if x >= 256, then y >= 256.\n if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n y := shr(128, y)\n z := shl(64, z)\n }\n if iszero(lt(y, 0x1000000000000000000)) {\n y := shr(64, y)\n z := shl(32, z)\n }\n if iszero(lt(y, 0x10000000000)) {\n y := shr(32, y)\n z := shl(16, z)\n }\n if iszero(lt(y, 0x1000000)) {\n y := shr(16, y)\n z := shl(8, z)\n }\n\n // Goal was to get z*z*y within a small factor of x. More iterations could\n // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n // There is no overflow risk here since y < 2^136 after the first branch above.\n z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n\n // If x+1 is a perfect square, the Babylonian method cycles between\n // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n z := sub(z, lt(div(x, z), z))\n }\n }\n\n function log2(uint256 x) internal pure returns (uint256 r) {\n require(x > 0, \"UNDEFINED\");\n\n assembly {\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\n r := or(r, shl(3, lt(0xff, shr(r, x))))\n r := or(r, shl(2, lt(0xf, shr(r, x))))\n r := or(r, shl(1, lt(0x3, shr(r, x))))\n r := or(r, lt(0x1, shr(r, x)))\n }\n }\n}\n" - }, - "node_modules/ds-test/src/test.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.5.0;\n\ncontract DSTest {\n event log (string);\n event logs (bytes);\n\n event log_address (address);\n event log_bytes32 (bytes32);\n event log_int (int);\n event log_uint (uint);\n event log_bytes (bytes);\n event log_string (string);\n\n event log_named_address (string key, address val);\n event log_named_bytes32 (string key, bytes32 val);\n event log_named_decimal_int (string key, int val, uint decimals);\n event log_named_decimal_uint (string key, uint val, uint decimals);\n event log_named_int (string key, int val);\n event log_named_uint (string key, uint val);\n event log_named_bytes (string key, bytes val);\n event log_named_string (string key, string val);\n\n bool public IS_TEST = true;\n bool private _failed;\n\n address constant HEVM_ADDRESS =\n address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));\n\n modifier mayRevert() { _; }\n modifier testopts(string memory) { _; }\n\n function failed() public returns (bool) {\n if (_failed) {\n return _failed;\n } else {\n bool globalFailed = false;\n if (hasHEVMContext()) {\n (, bytes memory retdata) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"load(address,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"))\n )\n );\n globalFailed = abi.decode(retdata, (bool));\n }\n return globalFailed;\n }\n } \n\n function fail() internal {\n if (hasHEVMContext()) {\n (bool status, ) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"store(address,bytes32,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"), bytes32(uint256(0x01)))\n )\n );\n status; // Silence compiler warnings\n }\n _failed = true;\n }\n\n function hasHEVMContext() internal view returns (bool) {\n uint256 hevmCodeSize = 0;\n assembly {\n hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D)\n }\n return hevmCodeSize > 0;\n }\n\n modifier logs_gas() {\n uint startGas = gasleft();\n _;\n uint endGas = gasleft();\n emit log_named_uint(\"gas\", startGas - endGas);\n }\n\n function assertTrue(bool condition) internal {\n if (!condition) {\n emit log(\"Error: Assertion Failed\");\n fail();\n }\n }\n\n function assertTrue(bool condition, string memory err) internal {\n if (!condition) {\n emit log_named_string(\"Error\", err);\n assertTrue(condition);\n }\n }\n\n function assertEq(address a, address b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [address]\");\n emit log_named_address(\" Expected\", b);\n emit log_named_address(\" Actual\", a);\n fail();\n }\n }\n function assertEq(address a, address b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes32 a, bytes32 b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bytes32]\");\n emit log_named_bytes32(\" Expected\", b);\n emit log_named_bytes32(\" Actual\", a);\n fail();\n }\n }\n function assertEq(bytes32 a, bytes32 b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq32(bytes32 a, bytes32 b) internal {\n assertEq(a, b);\n }\n function assertEq32(bytes32 a, bytes32 b, string memory err) internal {\n assertEq(a, b, err);\n }\n\n function assertEq(int a, int b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [int]\");\n emit log_named_int(\" Expected\", b);\n emit log_named_int(\" Actual\", a);\n fail();\n }\n }\n function assertEq(int a, int b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq(uint a, uint b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [uint]\");\n emit log_named_uint(\" Expected\", b);\n emit log_named_uint(\" Actual\", a);\n fail();\n }\n }\n function assertEq(uint a, uint b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEqDecimal(int a, int b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Expected\", b, decimals);\n emit log_named_decimal_int(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Expected\", b, decimals);\n emit log_named_decimal_uint(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n\n function assertGt(uint a, uint b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGt(uint a, uint b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGt(int a, int b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGt(int a, int b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGtDecimal(int a, int b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n\n function assertGe(uint a, uint b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGe(uint a, uint b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGe(int a, int b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGe(int a, int b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGeDecimal(int a, int b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertLt(uint a, uint b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLt(uint a, uint b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLt(int a, int b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLt(int a, int b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLtDecimal(int a, int b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n\n function assertLe(uint a, uint b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLe(uint a, uint b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLe(int a, int b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLe(int a, int b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLeDecimal(int a, int b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLeDecimal(a, b, decimals);\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertEq(string memory a, string memory b) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log(\"Error: a == b not satisfied [string]\");\n emit log_named_string(\" Expected\", b);\n emit log_named_string(\" Actual\", a);\n fail();\n }\n }\n function assertEq(string memory a, string memory b, string memory err) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {\n ok = true;\n if (a.length == b.length) {\n for (uint i = 0; i < a.length; i++) {\n if (a[i] != b[i]) {\n ok = false;\n }\n }\n } else {\n ok = false;\n }\n }\n function assertEq0(bytes memory a, bytes memory b) internal {\n if (!checkEq0(a, b)) {\n emit log(\"Error: a == b not satisfied [bytes]\");\n emit log_named_bytes(\" Expected\", b);\n emit log_named_bytes(\" Actual\", a);\n fail();\n }\n }\n function assertEq0(bytes memory a, bytes memory b, string memory err) internal {\n if (!checkEq0(a, b)) {\n emit log_named_string(\"Error\", err);\n assertEq0(a, b);\n }\n }\n}\n" - }, - "node_modules/forge-std/src/Base.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {StdStorage} from \"./StdStorage.sol\";\nimport {Vm, VmSafe} from \"./Vm.sol\";\n\nabstract contract CommonBase {\n // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.\n address internal constant VM_ADDRESS = address(uint160(uint256(keccak256(\"hevm cheat code\"))));\n // console.sol and console2.sol work by executing a staticcall to this address.\n address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;\n // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38.\n address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256(\"foundry default caller\"))));\n // Address of the test contract, deployed by the DEFAULT_SENDER.\n address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;\n // Deterministic deployment address of the Multicall3 contract.\n address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11;\n\n uint256 internal constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n Vm internal constant vm = Vm(VM_ADDRESS);\n StdStorage internal stdstore;\n}\n\nabstract contract TestBase is CommonBase {}\n\nabstract contract ScriptBase is CommonBase {\n // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);\n}\n" - }, - "node_modules/forge-std/src/StdAssertions.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {DSTest} from \"ds-test/test.sol\";\nimport {stdMath} from \"./StdMath.sol\";\n\nabstract contract StdAssertions is DSTest {\n event log_array(uint256[] val);\n event log_array(int256[] val);\n event log_array(address[] val);\n event log_named_array(string key, uint256[] val);\n event log_named_array(string key, int256[] val);\n event log_named_array(string key, address[] val);\n\n function fail(string memory err) internal virtual {\n emit log_named_string(\"Error\", err);\n fail();\n }\n\n function assertFalse(bool data) internal virtual {\n assertTrue(!data);\n }\n\n function assertFalse(bool data, string memory err) internal virtual {\n assertTrue(!data, err);\n }\n\n function assertEq(bool a, bool b) internal virtual {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bool]\");\n emit log_named_string(\" Left\", a ? \"true\" : \"false\");\n emit log_named_string(\" Right\", b ? \"true\" : \"false\");\n fail();\n }\n }\n\n function assertEq(bool a, bool b, string memory err) internal virtual {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes memory a, bytes memory b) internal virtual {\n assertEq0(a, b);\n }\n\n function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual {\n assertEq0(a, b, err);\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [uint[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [int[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(address[] memory a, address[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [address[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n // Legacy helper\n function assertEqUint(uint256 a, uint256 b) internal virtual {\n assertEq(uint256(a), uint256(b));\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100%\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals,\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual {\n assertEqCall(target, callDataA, target, callDataB, true);\n }\n\n function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB)\n internal\n virtual\n {\n assertEqCall(targetA, callDataA, targetB, callDataB, true);\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData)\n internal\n virtual\n {\n assertEqCall(target, callDataA, target, callDataB, strictRevertData);\n }\n\n function assertEqCall(\n address targetA,\n bytes memory callDataA,\n address targetB,\n bytes memory callDataB,\n bool strictRevertData\n ) internal virtual {\n (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA);\n (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB);\n\n if (successA && successB) {\n assertEq(returnDataA, returnDataB, \"Call return data does not match\");\n }\n\n if (!successA && !successB && strictRevertData) {\n assertEq(returnDataA, returnDataB, \"Call revert data does not match\");\n }\n\n if (!successA && successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call revert data\", returnDataA);\n emit log_named_bytes(\" Right call return data\", returnDataB);\n fail();\n }\n\n if (successA && !successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call return data\", returnDataA);\n emit log_named_bytes(\" Right call revert data\", returnDataB);\n fail();\n }\n }\n}\n" - }, - "node_modules/forge-std/src/StdChains.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n/**\n * StdChains provides information about EVM compatible chains that can be used in scripts/tests.\n * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are\n * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of\n * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the\n * alias used in this contract, which can be found as the first argument to the\n * `setChainWithDefaultRpcUrl` call in the `initialize` function.\n *\n * There are two main ways to use this contract:\n * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or\n * `setChain(string memory chainAlias, Chain memory chain)`\n * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`.\n *\n * The first time either of those are used, chains are initialized with the default set of RPC URLs.\n * This is done in `initialize`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in\n * `defaultRpcUrls`.\n *\n * The `setChain` function is straightforward, and it simply saves off the given chain data.\n *\n * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say\n * we want to retrieve `mainnet`'s RPC URL:\n * - If you haven't set any mainnet chain info with `setChain`, you haven't specified that\n * chain in `foundry.toml` and no env var is set, the default data and RPC URL will be returned.\n * - If you have set a mainnet RPC URL in `foundry.toml` it will return that, if valid (e.g. if\n * a URL is given or if an environment variable is given and that environment variable exists).\n * Otherwise, the default data is returned.\n * - If you specified data with `setChain` it will return that.\n *\n * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.\n */\nabstract contract StdChains {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private initialized;\n\n struct ChainData {\n string name;\n uint256 chainId;\n string rpcUrl;\n }\n\n struct Chain {\n // The chain name.\n string name;\n // The chain's Chain ID.\n uint256 chainId;\n // The chain's alias. (i.e. what gets specified in `foundry.toml`).\n string chainAlias;\n // A default RPC endpoint for this chain.\n // NOTE: This default RPC URL is included for convenience to facilitate quick tests and\n // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy\n // usage as you will be throttled and this is a disservice to others who need this endpoint.\n string rpcUrl;\n }\n\n // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data.\n mapping(string => Chain) private chains;\n // Maps from the chain's alias to it's default RPC URL.\n mapping(string => string) private defaultRpcUrls;\n // Maps from a chain ID to it's alias.\n mapping(uint256 => string) private idToAlias;\n\n bool private fallbackToDefaultRpcUrls = true;\n\n // The RPC URL will be fetched from config or defaultRpcUrls if possible.\n function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) {\n require(bytes(chainAlias).length != 0, \"StdChains getChain(string): Chain alias cannot be the empty string.\");\n\n initialize();\n chain = chains[chainAlias];\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(string): Chain with alias \\\"\", chainAlias, \"\\\" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n function getChain(uint256 chainId) internal virtual returns (Chain memory chain) {\n require(chainId != 0, \"StdChains getChain(uint256): Chain ID cannot be 0.\");\n initialize();\n string memory chainAlias = idToAlias[chainId];\n\n chain = chains[chainAlias];\n\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(uint256): Chain with ID \", vm.toString(chainId), \" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, ChainData memory chain) internal virtual {\n require(\n bytes(chainAlias).length != 0,\n \"StdChains setChain(string,ChainData): Chain alias cannot be the empty string.\"\n );\n\n require(chain.chainId != 0, \"StdChains setChain(string,ChainData): Chain ID cannot be 0.\");\n\n initialize();\n string memory foundAlias = idToAlias[chain.chainId];\n\n require(\n bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)),\n string(\n abi.encodePacked(\n \"StdChains setChain(string,ChainData): Chain ID \",\n vm.toString(chain.chainId),\n \" already used by \\\"\",\n foundAlias,\n \"\\\".\"\n )\n )\n );\n\n uint256 oldChainId = chains[chainAlias].chainId;\n delete idToAlias[oldChainId];\n\n chains[chainAlias] =\n Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl});\n idToAlias[chain.chainId] = chainAlias;\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, Chain memory chain) internal virtual {\n setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl}));\n }\n\n function _toUpper(string memory str) private pure returns (string memory) {\n bytes memory strb = bytes(str);\n bytes memory copy = new bytes(strb.length);\n for (uint256 i = 0; i < strb.length; i++) {\n bytes1 b = strb[i];\n if (b >= 0x61 && b <= 0x7A) {\n copy[i] = bytes1(uint8(b) - 32);\n } else {\n copy[i] = b;\n }\n }\n return string(copy);\n }\n\n // lookup rpcUrl, in descending order of priority:\n // current -> config (foundry.toml) -> environment variable -> default\n function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) {\n if (bytes(chain.rpcUrl).length == 0) {\n try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) {\n chain.rpcUrl = configRpcUrl;\n } catch (bytes memory err) {\n string memory envName = string(abi.encodePacked(_toUpper(chainAlias), \"_RPC_URL\"));\n if (fallbackToDefaultRpcUrls) {\n chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]);\n } else {\n chain.rpcUrl = vm.envString(envName);\n }\n // distinguish 'not found' from 'cannot read'\n bytes memory notFoundError =\n abi.encodeWithSignature(\"CheatCodeError\", string(abi.encodePacked(\"invalid rpc url \", chainAlias)));\n if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, err), mload(err))\n }\n }\n }\n }\n return chain;\n }\n\n function setFallbackToDefaultRpcUrls(bool useDefault) internal {\n fallbackToDefaultRpcUrls = useDefault;\n }\n\n function initialize() private {\n if (initialized) return;\n\n initialized = true;\n\n // If adding an RPC here, make sure to test the default RPC URL in `testRpcs`\n setChainWithDefaultRpcUrl(\"anvil\", ChainData(\"Anvil\", 31337, \"http://127.0.0.1:8545\"));\n setChainWithDefaultRpcUrl(\n \"mainnet\", ChainData(\"Mainnet\", 1, \"https://mainnet.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"goerli\", ChainData(\"Goerli\", 5, \"https://goerli.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"sepolia\", ChainData(\"Sepolia\", 11155111, \"https://sepolia.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\"optimism\", ChainData(\"Optimism\", 10, \"https://mainnet.optimism.io\"));\n setChainWithDefaultRpcUrl(\"optimism_goerli\", ChainData(\"Optimism Goerli\", 420, \"https://goerli.optimism.io\"));\n setChainWithDefaultRpcUrl(\"arbitrum_one\", ChainData(\"Arbitrum One\", 42161, \"https://arb1.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\n \"arbitrum_one_goerli\", ChainData(\"Arbitrum One Goerli\", 421613, \"https://goerli-rollup.arbitrum.io/rpc\")\n );\n setChainWithDefaultRpcUrl(\"arbitrum_nova\", ChainData(\"Arbitrum Nova\", 42170, \"https://nova.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\"polygon\", ChainData(\"Polygon\", 137, \"https://polygon-rpc.com\"));\n setChainWithDefaultRpcUrl(\n \"polygon_mumbai\", ChainData(\"Polygon Mumbai\", 80001, \"https://rpc-mumbai.maticvigil.com\")\n );\n setChainWithDefaultRpcUrl(\"avalanche\", ChainData(\"Avalanche\", 43114, \"https://api.avax.network/ext/bc/C/rpc\"));\n setChainWithDefaultRpcUrl(\n \"avalanche_fuji\", ChainData(\"Avalanche Fuji\", 43113, \"https://api.avax-test.network/ext/bc/C/rpc\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain\", ChainData(\"BNB Smart Chain\", 56, \"https://bsc-dataseed1.binance.org\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain_testnet\",\n ChainData(\"BNB Smart Chain Testnet\", 97, \"https://rpc.ankr.com/bsc_testnet_chapel\")\n );\n setChainWithDefaultRpcUrl(\"gnosis_chain\", ChainData(\"Gnosis Chain\", 100, \"https://rpc.gnosischain.com\"));\n }\n\n // set chain info, with priority to chainAlias' rpc url in foundry.toml\n function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private {\n string memory rpcUrl = chain.rpcUrl;\n defaultRpcUrls[chainAlias] = rpcUrl;\n chain.rpcUrl = \"\";\n setChain(chainAlias, chain);\n chain.rpcUrl = rpcUrl; // restore argument\n }\n}\n" - }, - "node_modules/forge-std/src/StdCheats.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdCheatsSafe {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private gasMeteringOff;\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawTx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n // json value name = function\n string functionSig;\n bytes32 hash;\n // json value name = tx\n RawTx1559Detail txDetail;\n // json value name = type\n string opcode;\n }\n\n struct RawTx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n bytes gas;\n bytes nonce;\n address to;\n bytes txType;\n bytes value;\n }\n\n struct Tx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n bytes32 hash;\n Tx1559Detail txDetail;\n string opcode;\n }\n\n struct Tx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n uint256 gas;\n uint256 nonce;\n address to;\n uint256 txType;\n uint256 value;\n }\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct TxLegacy {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n string hash;\n string opcode;\n TxDetailLegacy transaction;\n }\n\n struct TxDetailLegacy {\n AccessList[] accessList;\n uint256 chainId;\n bytes data;\n address from;\n uint256 gas;\n uint256 gasPrice;\n bytes32 hash;\n uint256 nonce;\n bytes1 opcode;\n bytes32 r;\n bytes32 s;\n uint256 txType;\n address to;\n uint8 v;\n uint256 value;\n }\n\n struct AccessList {\n address accessAddress;\n bytes32[] storageKeys;\n }\n\n // Data structures to parse Receipt objects from the broadcast artifact.\n // The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawReceipt {\n bytes32 blockHash;\n bytes blockNumber;\n address contractAddress;\n bytes cumulativeGasUsed;\n bytes effectiveGasPrice;\n address from;\n bytes gasUsed;\n RawReceiptLog[] logs;\n bytes logsBloom;\n bytes status;\n address to;\n bytes32 transactionHash;\n bytes transactionIndex;\n }\n\n struct Receipt {\n bytes32 blockHash;\n uint256 blockNumber;\n address contractAddress;\n uint256 cumulativeGasUsed;\n uint256 effectiveGasPrice;\n address from;\n uint256 gasUsed;\n ReceiptLog[] logs;\n bytes logsBloom;\n uint256 status;\n address to;\n bytes32 transactionHash;\n uint256 transactionIndex;\n }\n\n // Data structures to parse the entire broadcast artifact, assuming the\n // transactions conform to EIP1559.\n\n struct EIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n Receipt[] receipts;\n uint256 timestamp;\n Tx1559[] transactions;\n TxReturn[] txReturns;\n }\n\n struct RawEIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n RawReceipt[] receipts;\n TxReturn[] txReturns;\n uint256 timestamp;\n RawTx1559[] transactions;\n }\n\n struct RawReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n bytes blockNumber;\n bytes data;\n bytes logIndex;\n bool removed;\n bytes32[] topics;\n bytes32 transactionHash;\n bytes transactionIndex;\n bytes transactionLogIndex;\n }\n\n struct ReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n uint256 blockNumber;\n bytes data;\n uint256 logIndex;\n bytes32[] topics;\n uint256 transactionIndex;\n uint256 transactionLogIndex;\n bool removed;\n }\n\n struct TxReturn {\n string internalType;\n string value;\n }\n\n function assumeNoPrecompiles(address addr) internal virtual {\n // Assembly required since `block.chainid` was introduced in 0.8.0.\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n assumeNoPrecompiles(addr, chainId);\n }\n\n function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual {\n // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific\n // address), but the same rationale for excluding them applies so we include those too.\n\n // These should be present on all EVM-compatible chains.\n vm.assume(addr < address(0x1) || addr > address(0x9));\n\n // forgefmt: disable-start\n if (chainId == 10 || chainId == 420) {\n // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21\n vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800));\n } else if (chainId == 42161 || chainId == 421613) {\n // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains\n vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068));\n } else if (chainId == 43114 || chainId == 43113) {\n // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59\n vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff));\n vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF));\n vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff));\n }\n // forgefmt: disable-end\n }\n\n function readEIP1559ScriptArtifact(string memory path)\n internal\n view\n virtual\n returns (EIP1559ScriptArtifact memory)\n {\n string memory data = vm.readFile(path);\n bytes memory parsedData = vm.parseJson(data);\n RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact));\n EIP1559ScriptArtifact memory artifact;\n artifact.libraries = rawArtifact.libraries;\n artifact.path = rawArtifact.path;\n artifact.timestamp = rawArtifact.timestamp;\n artifact.pending = rawArtifact.pending;\n artifact.txReturns = rawArtifact.txReturns;\n artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts);\n artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions);\n return artifact;\n }\n\n function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) {\n Tx1559[] memory txs = new Tx1559[](rawTxs.length);\n for (uint256 i; i < rawTxs.length; i++) {\n txs[i] = rawToConvertedEIPTx1559(rawTxs[i]);\n }\n return txs;\n }\n\n function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) {\n Tx1559 memory transaction;\n transaction.arguments = rawTx.arguments;\n transaction.contractName = rawTx.contractName;\n transaction.functionSig = rawTx.functionSig;\n transaction.hash = rawTx.hash;\n transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail);\n transaction.opcode = rawTx.opcode;\n return transaction;\n }\n\n function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail)\n internal\n pure\n virtual\n returns (Tx1559Detail memory)\n {\n Tx1559Detail memory txDetail;\n txDetail.data = rawDetail.data;\n txDetail.from = rawDetail.from;\n txDetail.to = rawDetail.to;\n txDetail.nonce = _bytesToUint(rawDetail.nonce);\n txDetail.txType = _bytesToUint(rawDetail.txType);\n txDetail.value = _bytesToUint(rawDetail.value);\n txDetail.gas = _bytesToUint(rawDetail.gas);\n txDetail.accessList = rawDetail.accessList;\n return txDetail;\n }\n\n function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".transactions\");\n RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[]));\n return rawToConvertedEIPTx1559s(rawTxs);\n }\n\n function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".transactions[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559));\n return rawToConvertedEIPTx1559(rawTx);\n }\n\n // Analogous to readTransactions, but for receipts.\n function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".receipts\");\n RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[]));\n return rawToConvertedReceipts(rawReceipts);\n }\n\n function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".receipts[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt));\n return rawToConvertedReceipt(rawReceipt);\n }\n\n function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) {\n Receipt[] memory receipts = new Receipt[](rawReceipts.length);\n for (uint256 i; i < rawReceipts.length; i++) {\n receipts[i] = rawToConvertedReceipt(rawReceipts[i]);\n }\n return receipts;\n }\n\n function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) {\n Receipt memory receipt;\n receipt.blockHash = rawReceipt.blockHash;\n receipt.to = rawReceipt.to;\n receipt.from = rawReceipt.from;\n receipt.contractAddress = rawReceipt.contractAddress;\n receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice);\n receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed);\n receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed);\n receipt.status = _bytesToUint(rawReceipt.status);\n receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex);\n receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber);\n receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs);\n receipt.logsBloom = rawReceipt.logsBloom;\n receipt.transactionHash = rawReceipt.transactionHash;\n return receipt;\n }\n\n function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs)\n internal\n pure\n virtual\n returns (ReceiptLog[] memory)\n {\n ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length);\n for (uint256 i; i < rawLogs.length; i++) {\n logs[i].logAddress = rawLogs[i].logAddress;\n logs[i].blockHash = rawLogs[i].blockHash;\n logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber);\n logs[i].data = rawLogs[i].data;\n logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex);\n logs[i].topics = rawLogs[i].topics;\n logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex);\n logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex);\n logs[i].removed = rawLogs[i].removed;\n }\n return logs;\n }\n\n // Deploy a contract by fetching the contract bytecode from\n // the artifacts directory\n // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))`\n function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes): Deployment failed.\");\n }\n\n function deployCode(string memory what) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string): Deployment failed.\");\n }\n\n /// @dev deploy contract with value on construction\n function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes,uint256): Deployment failed.\");\n }\n\n function deployCode(string memory what, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,uint256): Deployment failed.\");\n }\n\n // creates a labeled address and the corresponding private key\n function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) {\n privateKey = uint256(keccak256(abi.encodePacked(name)));\n addr = vm.addr(privateKey);\n vm.label(addr, name);\n }\n\n // creates a labeled address\n function makeAddr(string memory name) internal virtual returns (address addr) {\n (addr,) = makeAddrAndKey(name);\n }\n\n function deriveRememberKey(string memory mnemonic, uint32 index)\n internal\n virtual\n returns (address who, uint256 privateKey)\n {\n privateKey = vm.deriveKey(mnemonic, index);\n who = vm.rememberKey(privateKey);\n }\n\n function _bytesToUint(bytes memory b) private pure returns (uint256) {\n require(b.length <= 32, \"StdCheats _bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n function isFork() internal view virtual returns (bool status) {\n try vm.activeFork() {\n status = true;\n } catch (bytes memory) {}\n }\n\n modifier skipWhenForking() {\n if (!isFork()) {\n _;\n }\n }\n\n modifier skipWhenNotForking() {\n if (isFork()) {\n _;\n }\n }\n\n modifier noGasMetering() {\n vm.pauseGasMetering();\n // To prevent turning gas monitoring back on with nested functions that use this modifier,\n // we check if gasMetering started in the off position. If it did, we don't want to turn\n // it back on until we exit the top level function that used the modifier\n //\n // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well.\n // funcA will have `gasStartedOff` as false, funcB will have it as true,\n // so we only turn metering back on at the end of the funcA\n bool gasStartedOff = gasMeteringOff;\n gasMeteringOff = true;\n\n _;\n\n // if gas metering was on when this modifier was called, turn it back on at the end\n if (!gasStartedOff) {\n gasMeteringOff = false;\n vm.resumeGasMetering();\n }\n }\n\n // a cheat for fuzzing addresses that are payable only\n // see https://github.com/foundry-rs/foundry/issues/3631\n function assumePayable(address addr) internal virtual {\n (bool success,) = payable(addr).call{value: 0}(\"\");\n vm.assume(success);\n }\n}\n\n// Wrappers around cheatcodes to avoid footguns\nabstract contract StdCheats is StdCheatsSafe {\n using stdStorage for StdStorage;\n\n StdStorage private stdstore;\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n // Skip forward or rewind time by the specified number of seconds\n function skip(uint256 time) internal virtual {\n vm.warp(block.timestamp + time);\n }\n\n function rewind(uint256 time) internal virtual {\n vm.warp(block.timestamp - time);\n }\n\n // Setup a prank from an address that has some ether\n function hoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender, origin);\n }\n\n function hoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender, origin);\n }\n\n // Start perpetual prank from an address that has some ether\n function startHoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender);\n }\n\n function startHoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender);\n }\n\n // Start perpetual prank from an address that has some ether\n // tx.origin is set to the origin parameter\n function startHoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender, origin);\n }\n\n function startHoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender, origin);\n }\n\n function changePrank(address msgSender) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender);\n }\n\n function changePrank(address msgSender, address txOrigin) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender, txOrigin);\n }\n\n // The same as Vm's `deal`\n // Use the alternative signature for ERC20 tokens\n function deal(address to, uint256 give) internal virtual {\n vm.deal(to, give);\n }\n\n // Set the balance of an account for any ERC20 token\n // Use the alternative signature to update `totalSupply`\n function deal(address token, address to, uint256 give) internal virtual {\n deal(token, to, give, false);\n }\n\n // Set the balance of an account for any ERC1155 token\n // Use the alternative signature to update `totalSupply`\n function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual {\n dealERC1155(token, to, id, give, false);\n }\n\n function deal(address token, address to, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd));\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0x18160ddd).checked_write(totSup);\n }\n }\n\n function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x00fdd58e, to, id));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0xbd85b039, id));\n require(\n totSupData.length != 0,\n \"StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply.\"\n );\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup);\n }\n }\n\n function dealERC721(address token, address to, uint256 id) internal virtual {\n // check if token id is already minted and the actual owner.\n (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id));\n require(successMinted, \"StdCheats deal(address,address,uint,bool): id not minted.\");\n\n // get owner current balance\n (, bytes memory fromBalData) = token.call(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address))));\n uint256 fromPrevBal = abi.decode(fromBalData, (uint256));\n\n // get new user current balance\n (, bytes memory toBalData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 toPrevBal = abi.decode(toBalData, (uint256));\n\n // update balances\n stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal);\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal);\n\n // update owner\n stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to);\n }\n}\n" - }, - "node_modules/forge-std/src/StdError.sol": { - "content": "// SPDX-License-Identifier: MIT\n// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdError {\n bytes public constant assertionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x01);\n bytes public constant arithmeticError = abi.encodeWithSignature(\"Panic(uint256)\", 0x11);\n bytes public constant divisionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x12);\n bytes public constant enumConversionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x21);\n bytes public constant encodeStorageError = abi.encodeWithSignature(\"Panic(uint256)\", 0x22);\n bytes public constant popError = abi.encodeWithSignature(\"Panic(uint256)\", 0x31);\n bytes public constant indexOOBError = abi.encodeWithSignature(\"Panic(uint256)\", 0x32);\n bytes public constant memOverflowError = abi.encodeWithSignature(\"Panic(uint256)\", 0x41);\n bytes public constant zeroVarError = abi.encodeWithSignature(\"Panic(uint256)\", 0x51);\n}\n" - }, - "node_modules/forge-std/src/StdInvariant.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ncontract StdInvariant {\n struct FuzzSelector {\n address addr;\n bytes4[] selectors;\n }\n\n address[] private _excludedContracts;\n address[] private _excludedSenders;\n address[] private _targetedContracts;\n address[] private _targetedSenders;\n\n string[] private _excludedArtifacts;\n string[] private _targetedArtifacts;\n\n FuzzSelector[] private _targetedArtifactSelectors;\n FuzzSelector[] private _targetedSelectors;\n\n // Functions for users:\n // These are intended to be called in tests.\n\n function excludeContract(address newExcludedContract_) internal {\n _excludedContracts.push(newExcludedContract_);\n }\n\n function excludeSender(address newExcludedSender_) internal {\n _excludedSenders.push(newExcludedSender_);\n }\n\n function excludeArtifact(string memory newExcludedArtifact_) internal {\n _excludedArtifacts.push(newExcludedArtifact_);\n }\n\n function targetArtifact(string memory newTargetedArtifact_) internal {\n _targetedArtifacts.push(newTargetedArtifact_);\n }\n\n function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal {\n _targetedArtifactSelectors.push(newTargetedArtifactSelector_);\n }\n\n function targetContract(address newTargetedContract_) internal {\n _targetedContracts.push(newTargetedContract_);\n }\n\n function targetSelector(FuzzSelector memory newTargetedSelector_) internal {\n _targetedSelectors.push(newTargetedSelector_);\n }\n\n function targetSender(address newTargetedSender_) internal {\n _targetedSenders.push(newTargetedSender_);\n }\n\n // Functions for forge:\n // These are called by forge to run invariant tests and don't need to be called in tests.\n\n function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) {\n excludedArtifacts_ = _excludedArtifacts;\n }\n\n function excludeContracts() public view returns (address[] memory excludedContracts_) {\n excludedContracts_ = _excludedContracts;\n }\n\n function excludeSenders() public view returns (address[] memory excludedSenders_) {\n excludedSenders_ = _excludedSenders;\n }\n\n function targetArtifacts() public view returns (string[] memory targetedArtifacts_) {\n targetedArtifacts_ = _targetedArtifacts;\n }\n\n function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) {\n targetedArtifactSelectors_ = _targetedArtifactSelectors;\n }\n\n function targetContracts() public view returns (address[] memory targetedContracts_) {\n targetedContracts_ = _targetedContracts;\n }\n\n function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) {\n targetedSelectors_ = _targetedSelectors;\n }\n\n function targetSenders() public view returns (address[] memory targetedSenders_) {\n targetedSenders_ = _targetedSenders;\n }\n}\n" - }, - "node_modules/forge-std/src/StdJson.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing JSON files\n// To parse:\n// ```\n// using stdJson for string;\n// string memory json = vm.readFile(\"some_peth\");\n// json.parseUint(\"\");\n// ```\n// To write:\n// ```\n// using stdJson for string;\n// string memory json = \"deploymentArtifact\";\n// Contract contract = new Contract();\n// json.serialize(\"contractAddress\", address(contract));\n// json = json.serialize(\"deploymentTimes\", uint(1));\n// // store the stringified JSON to the 'json' variable we have been using as a key\n// // as we won't need it any longer\n// string memory json2 = \"finalArtifact\";\n// string memory final = json2.serialize(\"depArtifact\", json);\n// final.write(\"\");\n// ```\n\nlibrary stdJson {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJson(json, key);\n }\n\n function readUint(string memory json, string memory key) internal returns (uint256) {\n return vm.parseJsonUint(json, key);\n }\n\n function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) {\n return vm.parseJsonUintArray(json, key);\n }\n\n function readInt(string memory json, string memory key) internal returns (int256) {\n return vm.parseJsonInt(json, key);\n }\n\n function readIntArray(string memory json, string memory key) internal returns (int256[] memory) {\n return vm.parseJsonIntArray(json, key);\n }\n\n function readBytes32(string memory json, string memory key) internal returns (bytes32) {\n return vm.parseJsonBytes32(json, key);\n }\n\n function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) {\n return vm.parseJsonBytes32Array(json, key);\n }\n\n function readString(string memory json, string memory key) internal returns (string memory) {\n return vm.parseJsonString(json, key);\n }\n\n function readStringArray(string memory json, string memory key) internal returns (string[] memory) {\n return vm.parseJsonStringArray(json, key);\n }\n\n function readAddress(string memory json, string memory key) internal returns (address) {\n return vm.parseJsonAddress(json, key);\n }\n\n function readAddressArray(string memory json, string memory key) internal returns (address[] memory) {\n return vm.parseJsonAddressArray(json, key);\n }\n\n function readBool(string memory json, string memory key) internal returns (bool) {\n return vm.parseJsonBool(json, key);\n }\n\n function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) {\n return vm.parseJsonBoolArray(json, key);\n }\n\n function readBytes(string memory json, string memory key) internal returns (bytes memory) {\n return vm.parseJsonBytes(json, key);\n }\n\n function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) {\n return vm.parseJsonBytesArray(json, key);\n }\n\n function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bool[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function write(string memory jsonKey, string memory path) internal {\n vm.writeJson(jsonKey, path);\n }\n\n function write(string memory jsonKey, string memory path, string memory valueKey) internal {\n vm.writeJson(jsonKey, path, valueKey);\n }\n}\n" - }, - "node_modules/forge-std/src/StdMath.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdMath {\n int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n function abs(int256 a) internal pure returns (uint256) {\n // Required or it will fail when `a = type(int256).min`\n if (a == INT256_MIN) {\n return 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n }\n\n return uint256(a > 0 ? a : -a);\n }\n\n function delta(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a - b : b - a;\n }\n\n function delta(int256 a, int256 b) internal pure returns (uint256) {\n // a and b are of the same sign\n // this works thanks to two's complement, the left-most bit is the sign bit\n if ((a ^ b) > -1) {\n return delta(abs(a), abs(b));\n }\n\n // a and b are of opposite signs\n return abs(a) + abs(b);\n }\n\n function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n\n return absDelta * 1e18 / b;\n }\n\n function percentDelta(int256 a, int256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n uint256 absB = abs(b);\n\n return absDelta * 1e18 / absB;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nstruct StdStorage {\n mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots;\n mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds;\n bytes32[] _keys;\n bytes4 _sig;\n uint256 _depth;\n address _target;\n bytes32 _set;\n}\n\nlibrary stdStorageSafe {\n event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot);\n event WARNING_UninitedSlot(address who, uint256 slot);\n\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return bytes4(keccak256(bytes(sigStr)));\n }\n\n /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against\n // slot complexity:\n // if flat, will be bytes32(uint256(uint));\n // if map, will be keccak256(abi.encode(key, uint(slot)));\n // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));\n // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);\n function find(StdStorage storage self) internal returns (uint256) {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n // calldata to test against\n if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n vm.record();\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n (bytes32[] memory reads,) = vm.accesses(address(who));\n if (reads.length == 1) {\n bytes32 curr = vm.load(who, reads[0]);\n if (curr == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[0]));\n }\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n } else if (reads.length > 1) {\n for (uint256 i = 0; i < reads.length; i++) {\n bytes32 prev = vm.load(who, reads[i]);\n if (prev == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[i]));\n }\n // store\n vm.store(who, reads[i], bytes32(hex\"1337\"));\n bool success;\n bytes memory rdat;\n {\n (success, rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n if (success && fdat == bytes32(hex\"1337\")) {\n // we found which of the slots is the actual one\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n vm.store(who, reads[i], prev);\n break;\n }\n vm.store(who, reads[i], prev);\n }\n } else {\n revert(\"stdStorage find(StdStorage): No storage use detected for target.\");\n }\n\n require(\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))],\n \"stdStorage find(StdStorage): Slot(s) not found.\"\n );\n\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n self._target = _target;\n return self;\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n self._sig = _sig;\n return self;\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n self._sig = sigs(_sig);\n return self;\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n self._keys.push(bytes32(uint256(uint160(who))));\n return self;\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n self._keys.push(bytes32(amt));\n return self;\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n self._keys.push(key);\n return self;\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n self._depth = _depth;\n return self;\n }\n\n function read(StdStorage storage self) private returns (bytes memory) {\n address t = self._target;\n uint256 s = find(self);\n return abi.encode(vm.load(t, bytes32(s)));\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return abi.decode(read(self), (bytes32));\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n int256 v = read_int(self);\n if (v == 0) return false;\n if (v == 1) return true;\n revert(\"stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool.\");\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return abi.decode(read(self), (address));\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return abi.decode(read(self), (uint256));\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return abi.decode(read(self), (int256));\n }\n\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n\nlibrary stdStorage {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return stdStorageSafe.sigs(sigStr);\n }\n\n function find(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.find(self);\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n return stdStorageSafe.target(self, _target);\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, who);\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, amt);\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, key);\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n return stdStorageSafe.depth(self, _depth);\n }\n\n function checked_write(StdStorage storage self, address who) internal {\n checked_write(self, bytes32(uint256(uint160(who))));\n }\n\n function checked_write(StdStorage storage self, uint256 amt) internal {\n checked_write(self, bytes32(amt));\n }\n\n function checked_write(StdStorage storage self, bool write) internal {\n bytes32 t;\n /// @solidity memory-safe-assembly\n assembly {\n t := write\n }\n checked_write(self, t);\n }\n\n function checked_write(StdStorage storage self, bytes32 set) internal {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n find(self);\n }\n bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]);\n\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n bytes32 curr = vm.load(who, slot);\n\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n vm.store(who, slot, set);\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return stdStorageSafe.read_bytes32(self);\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n return stdStorageSafe.read_bool(self);\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return stdStorageSafe.read_address(self);\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.read_uint(self);\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return stdStorageSafe.read_int(self);\n }\n\n // Private function so needs to be copied over\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n // Private function so needs to be copied over\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStyle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nlibrary StdStyle {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n string constant RED = \"\\u001b[91m\";\n string constant GREEN = \"\\u001b[92m\";\n string constant YELLOW = \"\\u001b[93m\";\n string constant BLUE = \"\\u001b[94m\";\n string constant MAGENTA = \"\\u001b[95m\";\n string constant CYAN = \"\\u001b[96m\";\n string constant BOLD = \"\\u001b[1m\";\n string constant DIM = \"\\u001b[2m\";\n string constant ITALIC = \"\\u001b[3m\";\n string constant UNDERLINE = \"\\u001b[4m\";\n string constant INVERSE = \"\\u001b[7m\";\n string constant RESET = \"\\u001b[0m\";\n\n function styleConcat(string memory style, string memory self) private pure returns (string memory) {\n return string(abi.encodePacked(style, self, RESET));\n }\n\n function red(string memory self) internal pure returns (string memory) {\n return styleConcat(RED, self);\n }\n\n function red(uint256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(int256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(address self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(bool self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes(bytes memory self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes32(bytes32 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function green(string memory self) internal pure returns (string memory) {\n return styleConcat(GREEN, self);\n }\n\n function green(uint256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(int256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(address self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(bool self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes(bytes memory self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes32(bytes32 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function yellow(string memory self) internal pure returns (string memory) {\n return styleConcat(YELLOW, self);\n }\n\n function yellow(uint256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(int256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(address self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(bool self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes(bytes memory self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes32(bytes32 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function blue(string memory self) internal pure returns (string memory) {\n return styleConcat(BLUE, self);\n }\n\n function blue(uint256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(int256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(address self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(bool self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes(bytes memory self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes32(bytes32 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function magenta(string memory self) internal pure returns (string memory) {\n return styleConcat(MAGENTA, self);\n }\n\n function magenta(uint256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(int256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(address self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(bool self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes(bytes memory self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes32(bytes32 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function cyan(string memory self) internal pure returns (string memory) {\n return styleConcat(CYAN, self);\n }\n\n function cyan(uint256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(int256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(address self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(bool self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes(bytes memory self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes32(bytes32 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function bold(string memory self) internal pure returns (string memory) {\n return styleConcat(BOLD, self);\n }\n\n function bold(uint256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(int256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(address self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(bool self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes(bytes memory self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes32(bytes32 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function dim(string memory self) internal pure returns (string memory) {\n return styleConcat(DIM, self);\n }\n\n function dim(uint256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(int256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(address self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(bool self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes(bytes memory self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes32(bytes32 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function italic(string memory self) internal pure returns (string memory) {\n return styleConcat(ITALIC, self);\n }\n\n function italic(uint256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(int256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(address self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(bool self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes(bytes memory self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes32(bytes32 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function underline(string memory self) internal pure returns (string memory) {\n return styleConcat(UNDERLINE, self);\n }\n\n function underline(uint256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(int256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(address self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(bool self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes(bytes memory self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes32(bytes32 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function inverse(string memory self) internal pure returns (string memory) {\n return styleConcat(INVERSE, self);\n }\n\n function inverse(uint256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(int256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(address self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(bool self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes(bytes memory self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes32(bytes32 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n}\n" - }, - "node_modules/forge-std/src/StdUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {IMulticall3} from \"./interfaces/IMulticall3.sol\";\n// TODO Remove import.\nimport {VmSafe} from \"./Vm.sol\";\n\nabstract contract StdUtils {\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n //////////////////////////////////////////////////////////////////////////*/\n\n IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;\n uint256 private constant INT256_MIN_ABS =\n 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n /*//////////////////////////////////////////////////////////////////////////\n INTERNAL FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n require(min <= max, \"StdUtils bound(uint256,uint256,uint256): Max is less than min.\");\n // If x is between min and max, return x directly. This is to ensure that dictionary values\n // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188\n if (x >= min && x <= max) return x;\n\n uint256 size = max - min + 1;\n\n // If the value is 0, 1, 2, 3, warp that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side.\n // This helps ensure coverage of the min/max values.\n if (x <= 3 && size > x) return min + x;\n if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x);\n\n // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.\n if (x > max) {\n uint256 diff = x - max;\n uint256 rem = diff % size;\n if (rem == 0) return max;\n result = min + rem - 1;\n } else if (x < min) {\n uint256 diff = min - x;\n uint256 rem = diff % size;\n if (rem == 0) return min;\n result = max - rem + 1;\n }\n }\n\n function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) {\n result = _bound(x, min, max);\n console2_log(\"Bound Result\", result);\n }\n\n function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) {\n require(min <= max, \"StdUtils bound(int256,int256,int256): Max is less than min.\");\n\n // Shifting all int256 values to uint256 to use _bound function. The range of two types are:\n // int256 : -(2**255) ~ (2**255 - 1)\n // uint256: 0 ~ (2**256 - 1)\n // So, add 2**255, INT256_MIN_ABS to the integer values.\n //\n // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow.\n // So, use `~uint256(x) + 1` instead.\n uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS);\n uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS);\n uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS);\n\n uint256 y = _bound(_x, _min, _max);\n\n // To move it back to int256 value, subtract INT256_MIN_ABS at here.\n result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS);\n console2_log(\"Bound result\", vm.toString(result));\n }\n\n function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {\n require(b.length <= 32, \"StdUtils bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce\n /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol)\n function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) {\n // forgefmt: disable-start\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))));\n if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))));\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce))));\n if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce))));\n if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce))));\n // forgefmt: disable-end\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return addressFromLast20Bytes(\n keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce)))\n );\n }\n\n function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer)\n internal\n pure\n virtual\n returns (address)\n {\n return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash)));\n }\n\n /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer\n function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) {\n return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY);\n }\n\n /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) {\n return hashInitCode(creationCode, \"\");\n }\n\n /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n /// @param args the ABI-encoded arguments to the constructor of C\n function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(creationCode, args));\n }\n\n // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses.\n function getTokenBalances(address token, address[] memory addresses)\n internal\n virtual\n returns (uint256[] memory balances)\n {\n uint256 tokenCodeSize;\n assembly {\n tokenCodeSize := extcodesize(token)\n }\n require(tokenCodeSize > 0, \"StdUtils getTokenBalances(address,address[]): Token address is not a contract.\");\n\n // ABI encode the aggregate call to Multicall3.\n uint256 length = addresses.length;\n IMulticall3.Call[] memory calls = new IMulticall3.Call[](length);\n for (uint256 i = 0; i < length; ++i) {\n // 0x70a08231 = bytes4(\"balanceOf(address)\"))\n calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))});\n }\n\n // Make the aggregate call.\n (, bytes[] memory returnData) = multicall.aggregate(calls);\n\n // ABI decode the return data and return the balances.\n balances = new uint256[](length);\n for (uint256 i = 0; i < length; ++i) {\n balances[i] = abi.decode(returnData[i], (uint256));\n }\n }\n\n /*//////////////////////////////////////////////////////////////////////////\n PRIVATE FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere.\n\n function console2_log(string memory p0, uint256 p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n status;\n }\n\n function console2_log(string memory p0, string memory p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n status;\n }\n}\n" - }, - "node_modules/forge-std/src/Test.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// 💬 ABOUT\n// Standard Library's default Test\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {StdAssertions} from \"./StdAssertions.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheats} from \"./StdCheats.sol\";\nimport {stdError} from \"./StdError.sol\";\nimport {StdInvariant} from \"./StdInvariant.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {Vm} from \"./Vm.sol\";\nimport {StdStyle} from \"./StdStyle.sol\";\n\n// 📦 BOILERPLATE\nimport {TestBase} from \"./Base.sol\";\nimport {DSTest} from \"ds-test/test.sol\";\n\n// ⭐️ TEST\nabstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase {\n// Note: IS_TEST() must return true.\n// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76.\n}\n" - }, - "node_modules/forge-std/src/Vm.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// Cheatcodes are marked as view/pure/none using the following rules:\n// 0. A call's observable behaviour includes its return value, logs, reverts and state writes,\n// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc),\n// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`,\n// 3. Otherwise you're `pure`.\n\ninterface VmSafe {\n struct Log {\n bytes32[] topics;\n bytes data;\n address emitter;\n }\n\n struct Rpc {\n string key;\n string url;\n }\n\n struct FsMetadata {\n bool isDir;\n bool isSymlink;\n uint256 length;\n bool readOnly;\n uint256 modified;\n uint256 accessed;\n uint256 created;\n }\n\n // Loads a storage slot from an address\n function load(address target, bytes32 slot) external view returns (bytes32 data);\n // Signs data\n function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);\n // Gets the address for a given private key\n function addr(uint256 privateKey) external pure returns (address keyAddr);\n // Gets the nonce of an account\n function getNonce(address account) external view returns (uint64 nonce);\n // Performs a foreign function call via the terminal\n function ffi(string[] calldata commandInput) external returns (bytes memory result);\n // Sets environment variables\n function setEnv(string calldata name, string calldata value) external;\n // Reads environment variables, (name) => (value)\n function envBool(string calldata name) external view returns (bool value);\n function envUint(string calldata name) external view returns (uint256 value);\n function envInt(string calldata name) external view returns (int256 value);\n function envAddress(string calldata name) external view returns (address value);\n function envBytes32(string calldata name) external view returns (bytes32 value);\n function envString(string calldata name) external view returns (string memory value);\n function envBytes(string calldata name) external view returns (bytes memory value);\n // Reads environment variables as arrays\n function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value);\n function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value);\n function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value);\n function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);\n function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value);\n function envString(string calldata name, string calldata delim) external view returns (string[] memory value);\n function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value);\n // Read environment variables with default value\n function envOr(string calldata name, bool defaultValue) external returns (bool value);\n function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value);\n function envOr(string calldata name, int256 defaultValue) external returns (int256 value);\n function envOr(string calldata name, address defaultValue) external returns (address value);\n function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value);\n function envOr(string calldata name, string calldata defaultValue) external returns (string memory value);\n function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value);\n // Read environment variables as arrays with default value\n function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue)\n external\n returns (bool[] memory value);\n function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue)\n external\n returns (uint256[] memory value);\n function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue)\n external\n returns (int256[] memory value);\n function envOr(string calldata name, string calldata delim, address[] calldata defaultValue)\n external\n returns (address[] memory value);\n function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue)\n external\n returns (bytes32[] memory value);\n function envOr(string calldata name, string calldata delim, string[] calldata defaultValue)\n external\n returns (string[] memory value);\n function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue)\n external\n returns (bytes[] memory value);\n // Records all storage reads and writes\n function record() external;\n // Gets all accessed reads and write slot from a recording session, for a given address\n function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots);\n // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file\n function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode);\n // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file\n function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode);\n // Labels an address in call traces\n function label(address account, string calldata newLabel) external;\n // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain\n function broadcast() external;\n // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain\n function broadcast(address signer) external;\n // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain\n function broadcast(uint256 privateKey) external;\n // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain\n function startBroadcast() external;\n // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain\n function startBroadcast(address signer) external;\n // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain\n function startBroadcast(uint256 privateKey) external;\n // Stops collecting onchain transactions\n function stopBroadcast() external;\n // Reads the entire content of file to string\n function readFile(string calldata path) external view returns (string memory data);\n // Reads the entire content of file as binary. Path is relative to the project root.\n function readFileBinary(string calldata path) external view returns (bytes memory data);\n // Get the path of the current project root\n function projectRoot() external view returns (string memory path);\n // Get the metadata for a file/directory\n function fsMetadata(string calldata fileOrDir) external returns (FsMetadata memory metadata);\n // Reads next line of file to string\n function readLine(string calldata path) external view returns (string memory line);\n // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does.\n function writeFile(string calldata path, string calldata data) external;\n // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does.\n // Path is relative to the project root.\n function writeFileBinary(string calldata path, bytes calldata data) external;\n // Writes line to file, creating a file if it does not exist.\n function writeLine(string calldata path, string calldata data) external;\n // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine.\n function closeFile(string calldata path) external;\n // Removes file. This cheatcode will revert in the following situations, but is not limited to just these cases:\n // - Path points to a directory.\n // - The file doesn't exist.\n // - The user lacks permissions to remove the file.\n function removeFile(string calldata path) external;\n // Convert values to a string\n function toString(address value) external pure returns (string memory stringifiedValue);\n function toString(bytes calldata value) external pure returns (string memory stringifiedValue);\n function toString(bytes32 value) external pure returns (string memory stringifiedValue);\n function toString(bool value) external pure returns (string memory stringifiedValue);\n function toString(uint256 value) external pure returns (string memory stringifiedValue);\n function toString(int256 value) external pure returns (string memory stringifiedValue);\n // Convert values from a string\n function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue);\n function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue);\n function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue);\n function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue);\n function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue);\n function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue);\n // Record all the transaction logs\n function recordLogs() external;\n // Gets all the recorded logs\n function getRecordedLogs() external returns (Log[] memory logs);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index}\n function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index}\n function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index)\n external\n pure\n returns (uint256 privateKey);\n // Adds a private key to the local forge wallet and returns the address\n function rememberKey(uint256 privateKey) external returns (address keyAddr);\n //\n // parseJson\n //\n // ----\n // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects\n // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in\n // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that\n // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded\n // as tuples, with the attributes in the order in which they are defined.\n // For example: json = { 'a': 1, 'b': 0xa4tb......3xs}\n // a: uint256\n // b: address\n // To decode that json, we need to define a struct or a tuple as follows:\n // struct json = { uint256 a; address b; }\n // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to\n // decode the tuple in that order, and thus fail.\n // ----\n // Given a string of JSON, return it as ABI-encoded\n function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData);\n function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData);\n\n // The following parseJson cheatcodes will do type coercion, for the type that they indicate.\n // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12'\n // and hex numbers '0xEF'.\n // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not\n // a JSON object.\n function parseJsonUint(string calldata, string calldata) external returns (uint256);\n function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory);\n function parseJsonInt(string calldata, string calldata) external returns (int256);\n function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory);\n function parseJsonBool(string calldata, string calldata) external returns (bool);\n function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory);\n function parseJsonAddress(string calldata, string calldata) external returns (address);\n function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory);\n function parseJsonString(string calldata, string calldata) external returns (string memory);\n function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory);\n function parseJsonBytes(string calldata, string calldata) external returns (bytes memory);\n function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory);\n function parseJsonBytes32(string calldata, string calldata) external returns (bytes32);\n function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory);\n\n // Serialize a key and value to a JSON object stored in-memory that can be later written to a file\n // It returns the stringified version of the specific JSON file up to that moment.\n function serializeBool(string calldata objectKey, string calldata valueKey, bool value)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256 value)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address value)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string calldata value)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value)\n external\n returns (string memory json);\n\n function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values)\n external\n returns (string memory json);\n\n //\n // writeJson\n //\n // ----\n // Write a serialized JSON object to a file. If the file exists, it will be overwritten.\n // Let's assume we want to write the following JSON to a file:\n //\n // { \"boolean\": true, \"number\": 342, \"object\": { \"title\": \"finally json serialization\" } }\n //\n // ```\n // string memory json1 = \"some key\";\n // vm.serializeBool(json1, \"boolean\", true);\n // vm.serializeBool(json1, \"number\", uint256(342));\n // json2 = \"some other key\";\n // string memory output = vm.serializeString(json2, \"title\", \"finally json serialization\");\n // string memory finalJson = vm.serialize(json1, \"object\", output);\n // vm.writeJson(finalJson, \"./output/example.json\");\n // ```\n // The critical insight is that every invocation of serialization will return the stringified version of the JSON\n // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version\n // to serialize them as values to another JSON object.\n //\n // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..)\n // will find the object in-memory that is keyed by \"some key\".\n function writeJson(string calldata json, string calldata path) external;\n // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = \n // This is useful to replace a specific value of a JSON file, without having to parse the entire thing\n function writeJson(string calldata json, string calldata path, string calldata valueKey) external;\n // Returns the RPC url for the given alias\n function rpcUrl(string calldata rpcAlias) external view returns (string memory json);\n // Returns all rpc urls and their aliases `[alias, url][]`\n function rpcUrls() external view returns (string[2][] memory urls);\n // Returns all rpc urls and their aliases as structs.\n function rpcUrlStructs() external view returns (Rpc[] memory urls);\n // If the condition is false, discard this run's fuzz inputs and generate new ones.\n function assume(bool condition) external pure;\n // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused.\n function pauseGasMetering() external;\n // Resumes gas metering (i.e. gas usage is counted again). Noop if already on.\n function resumeGasMetering() external;\n}\n\ninterface Vm is VmSafe {\n // Sets block.timestamp\n function warp(uint256 newTimestamp) external;\n // Sets block.height\n function roll(uint256 newHeight) external;\n // Sets block.basefee\n function fee(uint256 newBasefee) external;\n // Sets block.difficulty\n function difficulty(uint256 newDifficulty) external;\n // Sets block.chainid\n function chainId(uint256 newChainId) external;\n // Stores a value to an address' storage slot.\n function store(address target, bytes32 slot, bytes32 value) external;\n // Sets the nonce of an account; must be higher than the current nonce of the account\n function setNonce(address account, uint64 newNonce) external;\n // Sets the *next* call's msg.sender to be the input address\n function prank(address msgSender) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called\n function startPrank(address msgSender) external;\n // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input\n function prank(address msgSender, address txOrigin) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input\n function startPrank(address msgSender, address txOrigin) external;\n // Resets subsequent calls' msg.sender to be `address(this)`\n function stopPrank() external;\n // Sets an address' balance\n function deal(address account, uint256 newBalance) external;\n // Sets an address' code\n function etch(address target, bytes calldata newRuntimeBytecode) external;\n // Expects an error on next call\n function expectRevert(bytes calldata revertData) external;\n function expectRevert(bytes4 revertData) external;\n function expectRevert() external;\n\n // Prepare an expected log with all four checks enabled.\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data.\n // Second form also checks supplied address against emitting contract.\n function expectEmit() external;\n function expectEmit(address emitter) external;\n\n // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData).\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data (as specified by the booleans).\n // Second form also checks supplied address against emitting contract.\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external;\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter)\n external;\n\n // Mocks a call to an address, returning specified data.\n // Calldata can either be strict or a partial match, e.g. if you only\n // pass a Solidity selector to the expected calldata, then the entire Solidity\n // function will be mocked.\n function mockCall(address callee, bytes calldata data, bytes calldata returnData) external;\n // Mocks a call to an address with a specific msg.value, returning specified data.\n // Calldata match takes precedence over msg.value in case of ambiguity.\n function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external;\n // Clears all mocked calls\n function clearMockedCalls() external;\n // Expects a call to an address with the specified calldata.\n // Calldata can either be a strict or a partial match\n function expectCall(address callee, bytes calldata data) external;\n // Expects a call to an address with the specified msg.value and calldata\n function expectCall(address callee, uint256 msgValue, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value, gas, and calldata.\n function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas.\n function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other\n // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set.\n function expectSafeMemory(uint64 min, uint64 max) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext.\n // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges\n // to the set.\n function expectSafeMemoryCall(uint64 min, uint64 max) external;\n // Sets block.coinbase\n function coinbase(address newCoinbase) external;\n // Snapshot the current state of the evm.\n // Returns the id of the snapshot that was created.\n // To revert a snapshot use `revertTo`\n function snapshot() external returns (uint256 snapshotId);\n // Revert the state of the EVM to a previous snapshot\n // Takes the snapshot id to revert to.\n // This deletes the snapshot and all snapshots taken after the given snapshot id.\n function revertTo(uint256 snapshotId) external returns (bool success);\n // Creates a new fork with the given endpoint and block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction,\n // and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before\n // the transaction, returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active.\n function selectFork(uint256 forkId) external;\n /// Returns the identifier of the currently active fork. Reverts if no fork is currently active.\n function activeFork() external view returns (uint256 forkId);\n // Updates the currently active fork to given block number\n // This is similar to `roll` but for the currently active fork\n function rollFork(uint256 blockNumber) external;\n // Updates the currently active fork to given transaction\n // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block\n function rollFork(bytes32 txHash) external;\n // Updates the given fork to given block number\n function rollFork(uint256 forkId, uint256 blockNumber) external;\n // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block\n function rollFork(uint256 forkId, bytes32 txHash) external;\n // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup\n // Meaning, changes made to the state of this account will be kept when switching forks\n function makePersistent(address account) external;\n function makePersistent(address account0, address account1) external;\n function makePersistent(address account0, address account1, address account2) external;\n function makePersistent(address[] calldata accounts) external;\n // Revokes persistent status from the address, previously added via `makePersistent`\n function revokePersistent(address account) external;\n function revokePersistent(address[] calldata accounts) external;\n // Returns true if the account is marked as persistent\n function isPersistent(address account) external view returns (bool persistent);\n // In forking mode, explicitly grant the given address cheatcode access\n function allowCheatcodes(address account) external;\n // Fetches the given transaction from the active fork and executes it on the current state\n function transact(bytes32 txHash) external;\n // Fetches the given transaction from the given fork and executes it on the current state\n function transact(uint256 forkId, bytes32 txHash) external;\n}\n" - }, - "node_modules/forge-std/src/console.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n }\n\n function logUint(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n }\n\n function log(uint p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n }\n\n function log(uint p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n }\n\n function log(uint p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n }\n\n function log(string memory p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/console2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\n/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should\n/// use `int256` and `uint256`. This modified version fixes that. This version is recommended\n/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in\n/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`.\n/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178\nlibrary console2 {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function log(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint256 p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n }\n\n function log(uint256 p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n }\n\n function log(uint256 p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n }\n\n function log(uint256 p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n }\n\n function log(string memory p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n }\n\n function log(string memory p0, int256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,int256)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/interfaces/IMulticall3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ninterface IMulticall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint256 value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n function aggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes[] memory returnData);\n\n function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);\n\n function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData);\n\n function blockAndAggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n\n function getBasefee() external view returns (uint256 basefee);\n\n function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash);\n\n function getBlockNumber() external view returns (uint256 blockNumber);\n\n function getChainId() external view returns (uint256 chainid);\n\n function getCurrentBlockCoinbase() external view returns (address coinbase);\n\n function getCurrentBlockDifficulty() external view returns (uint256 difficulty);\n\n function getCurrentBlockGasLimit() external view returns (uint256 gaslimit);\n\n function getCurrentBlockTimestamp() external view returns (uint256 timestamp);\n\n function getEthBalance(address addr) external view returns (uint256 balance);\n\n function getLastBlockHash() external view returns (bytes32 blockHash);\n\n function tryAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (Result[] memory returnData);\n\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n}\n" - } - }, - "settings": { - "remappings": [ - "@openzeppelin/=node_modules/@openzeppelin/", - "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", - "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", - "@rari-capital/=node_modules/@rari-capital/", - "@rari-capital/solmate/=node_modules/@rari-capital/solmate/", - "ds-test/=node_modules/ds-test/src/", - "forge-std/=node_modules/forge-std/src/" - ], - "optimizer": { - "enabled": true, - "runs": 999999 - }, - "metadata": { - "bytecodeHash": "none" - }, - "outputSelection": { - "*": { - "": [ - "ast" - ], - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "storageLayout", - "devdoc", - "userdoc" - ] - } - }, - "evmVersion": "london", - "libraries": {} - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/goerli/solcInputs/b86bd90311e4718458829d4a71bc5df9.json b/packages/contracts-bedrock/deployments/goerli/solcInputs/b86bd90311e4718458829d4a71bc5df9.json deleted file mode 100644 index 82819b8dc9ce..000000000000 --- a/packages/contracts-bedrock/deployments/goerli/solcInputs/b86bd90311e4718458829d4a71bc5df9.json +++ /dev/null @@ -1,552 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/L1/L1CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismPortal } from \"./OptimismPortal.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1CrossDomainMessenger\n * @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible\n * for sending and receiving data on the L1 side. Users are encouraged to use this\n * interface instead of interacting with lower-level contracts directly.\n */\ncontract L1CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @notice Address of the OptimismPortal.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _portal Address of the OptimismPortal contract on this network.\n */\n constructor(OptimismPortal _portal)\n Semver(1, 1, 0)\n CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER)\n {\n PORTAL = _portal;\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return msg.sender == address(PORTAL) && PORTAL.l2Sender() == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(PORTAL);\n }\n}\n" - }, - "contracts/L1/L1ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { IERC721 } from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L1ERC721Bridge\n * @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as an escrow for ERC721 tokens deposited into L2.\n */\ncontract L1ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token\n * by ID was deposited for a given L2 token.\n */\n mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L1ERC721Bridge: local token cannot be self\");\n\n // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.\n require(\n deposits[_localToken][_remoteToken][_tokenId] == true,\n \"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\"\n );\n\n // Mark that the token ID for this L1/L2 token pair is no longer escrowed in the L1\n // Bridge.\n deposits[_localToken][_remoteToken][_tokenId] = false;\n\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the\n // withdrawer.\n IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L1ERC721Bridge: remote token cannot be address(0)\");\n\n // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)\n bytes memory message = abi.encodeWithSelector(\n L2ERC721Bridge.finalizeBridgeERC721.selector,\n _remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Lock token into bridge\n deposits[_localToken][_remoteToken][_tokenId] = true;\n IERC721(_localToken).transferFrom(_from, address(this), _tokenId);\n\n // Send calldata into L2\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L1/L1StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1StandardBridge\n * @notice The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L1, it will be escrowed within this\n * contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was\n * stored within this contract. After Bedrock, ETH is instead stored inside the\n * OptimismPortal contract.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L1StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated.\n *\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of ETH deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ETHDepositInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized.\n *\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of ETH withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 withdrawal is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _messenger Address of the L1CrossDomainMessenger.\n */\n constructor(address payable _messenger)\n Semver(1, 1, 0)\n StandardBridge(_messenger, payable(Predeploys.L2_STANDARD_BRIDGE))\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into the sender's account on L2.\n *\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETH(uint32 _minGasLimit, bytes calldata _extraData) external payable onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into a target account on L2.\n * Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will\n * be locked in the L2StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n *\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable {\n _initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into the sender's account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20(\n address _l1Token,\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual onlyEOA {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into a target account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20To(\n address _l1Token,\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ETH from L2.\n *\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of ETH to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeETHWithdrawal(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ERC20 tokens from L2.\n *\n * @param _l1Token Address of the token on L1.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of the ERC20 to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeERC20Withdrawal(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external {\n finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L2 bridge contract.\n *\n * @return Address of the corresponding L2 bridge contract.\n */\n function l2TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @notice Internal function for initiating an ETH deposit.\n *\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateETHDeposit(\n address _from,\n address _to,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Internal function for initiating an ERC20 deposit.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateERC20Deposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHDepositInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHDepositInitiated(_from, _to, _amount, _extraData);\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHWithdrawalFinalized event followed by the ETHBridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData);\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20DepositInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20DepositInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20WithdrawalFinalized event followed by the ERC20BridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20WithdrawalFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L1/L2OutputOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\n/**\n * @custom:proxied\n * @title L2OutputOracle\n * @notice The L2OutputOracle contains an array of L2 state outputs, where each output is a\n * commitment to the state of the L2 chain. Other contracts like the OptimismPortal use\n * these outputs to verify information about the state of L2.\n */\ncontract L2OutputOracle is Initializable, Semver {\n /**\n * @notice The interval in L2 blocks at which checkpoints must be submitted. Although this is\n * immutable, it can safely be modified by upgrading the implementation contract.\n */\n uint256 public immutable SUBMISSION_INTERVAL;\n\n /**\n * @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified.\n */\n uint256 public immutable L2_BLOCK_TIME;\n\n /**\n * @notice The address of the challenger. Can be updated via upgrade.\n */\n address public immutable CHALLENGER;\n\n /**\n * @notice The address of the proposer. Can be updated via upgrade.\n */\n address public immutable PROPOSER;\n\n /**\n * @notice Minimum time (in seconds) that must elapse before a withdrawal can be finalized.\n */\n uint256 public immutable FINALIZATION_PERIOD_SECONDS;\n\n /**\n * @notice The number of the first L2 block recorded in this contract.\n */\n uint256 public startingBlockNumber;\n\n /**\n * @notice The timestamp of the first L2 block recorded in this contract.\n */\n uint256 public startingTimestamp;\n\n /**\n * @notice Array of L2 output proposals.\n */\n Types.OutputProposal[] internal l2Outputs;\n\n /**\n * @notice Emitted when an output is proposed.\n *\n * @param outputRoot The output root.\n * @param l2OutputIndex The index of the output in the l2Outputs array.\n * @param l2BlockNumber The L2 block number of the output root.\n * @param l1Timestamp The L1 timestamp when proposed.\n */\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n /**\n * @notice Emitted when outputs are deleted.\n *\n * @param prevNextOutputIndex Next L2 output index before the deletion.\n * @param newNextOutputIndex Next L2 output index after the deletion.\n */\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n /**\n * @custom:semver 1.2.0\n *\n * @param _submissionInterval Interval in blocks at which checkpoints must be submitted.\n * @param _l2BlockTime The time per L2 block, in seconds.\n * @param _startingBlockNumber The number of the first L2 block.\n * @param _startingTimestamp The timestamp of the first L2 block.\n * @param _proposer The address of the proposer.\n * @param _challenger The address of the challenger.\n */\n constructor(\n uint256 _submissionInterval,\n uint256 _l2BlockTime,\n uint256 _startingBlockNumber,\n uint256 _startingTimestamp,\n address _proposer,\n address _challenger,\n uint256 _finalizationPeriodSeconds\n ) Semver(1, 2, 0) {\n require(_l2BlockTime > 0, \"L2OutputOracle: L2 block time must be greater than 0\");\n require(\n _submissionInterval > _l2BlockTime,\n \"L2OutputOracle: submission interval must be greater than L2 block time\"\n );\n\n SUBMISSION_INTERVAL = _submissionInterval;\n L2_BLOCK_TIME = _l2BlockTime;\n PROPOSER = _proposer;\n CHALLENGER = _challenger;\n FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;\n\n initialize(_startingBlockNumber, _startingTimestamp);\n }\n\n /**\n * @notice Initializer.\n *\n * @param _startingBlockNumber Block number for the first recoded L2 block.\n * @param _startingTimestamp Timestamp for the first recoded L2 block.\n */\n function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp)\n public\n initializer\n {\n require(\n _startingTimestamp <= block.timestamp,\n \"L2OutputOracle: starting L2 timestamp must be less than current time\"\n );\n\n startingTimestamp = _startingTimestamp;\n startingBlockNumber = _startingBlockNumber;\n }\n\n /**\n * @notice Deletes all output proposals after and including the proposal that corresponds to\n * the given output index. Only the challenger address can delete outputs.\n *\n * @param _l2OutputIndex Index of the first L2 output to be deleted. All outputs after this\n * output will also be deleted.\n */\n // solhint-disable-next-line ordering\n function deleteL2Outputs(uint256 _l2OutputIndex) external {\n require(\n msg.sender == CHALLENGER,\n \"L2OutputOracle: only the challenger address can delete outputs\"\n );\n\n // Make sure we're not *increasing* the length of the array.\n require(\n _l2OutputIndex < l2Outputs.length,\n \"L2OutputOracle: cannot delete outputs after the latest output index\"\n );\n\n // Do not allow deleting any outputs that have already been finalized.\n require(\n block.timestamp - l2Outputs[_l2OutputIndex].timestamp < FINALIZATION_PERIOD_SECONDS,\n \"L2OutputOracle: cannot delete outputs that have already been finalized\"\n );\n\n uint256 prevNextL2OutputIndex = nextOutputIndex();\n\n // Use assembly to delete the array elements because Solidity doesn't allow it.\n assembly {\n sstore(l2Outputs.slot, _l2OutputIndex)\n }\n\n emit OutputsDeleted(prevNextL2OutputIndex, _l2OutputIndex);\n }\n\n /**\n * @notice Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp\n * must be equal to the current value returned by `nextTimestamp()` in order to be\n * accepted. This function may only be called by the Proposer.\n *\n * @param _outputRoot The L2 output of the checkpoint block.\n * @param _l2BlockNumber The L2 block number that resulted in _outputRoot.\n * @param _l1BlockHash A block hash which must be included in the current chain.\n * @param _l1BlockNumber The block number with the specified block hash.\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external payable {\n require(\n msg.sender == PROPOSER,\n \"L2OutputOracle: only the proposer address can propose new outputs\"\n );\n\n require(\n _l2BlockNumber == nextBlockNumber(),\n \"L2OutputOracle: block number must be equal to next expected block number\"\n );\n\n require(\n computeL2Timestamp(_l2BlockNumber) < block.timestamp,\n \"L2OutputOracle: cannot propose L2 output in the future\"\n );\n\n require(\n _outputRoot != bytes32(0),\n \"L2OutputOracle: L2 output proposal cannot be the zero hash\"\n );\n\n if (_l1BlockHash != bytes32(0)) {\n // This check allows the proposer to propose an output based on a given L1 block,\n // without fear that it will be reorged out.\n // It will also revert if the blockheight provided is more than 256 blocks behind the\n // chain tip (as the hash will return as zero). This does open the door to a griefing\n // attack in which the proposer's submission is censored until the block is no longer\n // retrievable, if the proposer is experiencing this attack it can simply leave out the\n // blockhash value, and delay submission until it is confident that the L1 block is\n // finalized.\n require(\n blockhash(_l1BlockNumber) == _l1BlockHash,\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n }\n\n emit OutputProposed(_outputRoot, nextOutputIndex(), _l2BlockNumber, block.timestamp);\n\n l2Outputs.push(\n Types.OutputProposal({\n outputRoot: _outputRoot,\n timestamp: uint128(block.timestamp),\n l2BlockNumber: uint128(_l2BlockNumber)\n })\n );\n }\n\n /**\n * @notice Returns an output by index. Exists because Solidity's array access will return a\n * tuple instead of a struct.\n *\n * @param _l2OutputIndex Index of the output to return.\n *\n * @return The output at the given index.\n */\n function getL2Output(uint256 _l2OutputIndex)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[_l2OutputIndex];\n }\n\n /**\n * @notice Returns the index of the L2 output that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return Index of the first checkpoint that commits to the given L2 block number.\n */\n function getL2OutputIndexAfter(uint256 _l2BlockNumber) public view returns (uint256) {\n // Make sure an output for this block number has actually been proposed.\n require(\n _l2BlockNumber <= latestBlockNumber(),\n \"L2OutputOracle: cannot get output for a block that has not been proposed\"\n );\n\n // Make sure there's at least one output proposed.\n require(\n l2Outputs.length > 0,\n \"L2OutputOracle: cannot get output as no outputs have been proposed yet\"\n );\n\n // Find the output via binary search, guaranteed to exist.\n uint256 lo = 0;\n uint256 hi = l2Outputs.length;\n while (lo < hi) {\n uint256 mid = (lo + hi) / 2;\n if (l2Outputs[mid].l2BlockNumber < _l2BlockNumber) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n return lo;\n }\n\n /**\n * @notice Returns the L2 output proposal that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return First checkpoint that commits to the given L2 block number.\n */\n function getL2OutputAfter(uint256 _l2BlockNumber)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)];\n }\n\n /**\n * @notice Returns the number of outputs that have been proposed. Will revert if no outputs\n * have been proposed yet.\n *\n * @return The number of outputs that have been proposed.\n */\n function latestOutputIndex() external view returns (uint256) {\n return l2Outputs.length - 1;\n }\n\n /**\n * @notice Returns the index of the next output to be proposed.\n *\n * @return The index of the next output to be proposed.\n */\n function nextOutputIndex() public view returns (uint256) {\n return l2Outputs.length;\n }\n\n /**\n * @notice Returns the block number of the latest submitted L2 output proposal. If no proposals\n * been submitted yet then this function will return the starting block number.\n *\n * @return Latest submitted L2 block number.\n */\n function latestBlockNumber() public view returns (uint256) {\n return\n l2Outputs.length == 0\n ? startingBlockNumber\n : l2Outputs[l2Outputs.length - 1].l2BlockNumber;\n }\n\n /**\n * @notice Computes the block number of the next L2 block that needs to be checkpointed.\n *\n * @return Next L2 block number.\n */\n function nextBlockNumber() public view returns (uint256) {\n return latestBlockNumber() + SUBMISSION_INTERVAL;\n }\n\n /**\n * @notice Returns the L2 timestamp corresponding to a given L2 block number.\n *\n * @param _l2BlockNumber The L2 block number of the target block.\n *\n * @return L2 timestamp of the given block.\n */\n function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {\n return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME);\n }\n}\n" - }, - "contracts/L1/OptimismPortal.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { L2OutputOracle } from \"./L2OutputOracle.sol\";\nimport { SystemConfig } from \"./SystemConfig.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { SecureMerkleTrie } from \"../libraries/trie/SecureMerkleTrie.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title OptimismPortal\n * @notice The OptimismPortal is a low-level contract responsible for passing messages between L1\n * and L2. Messages sent directly to the OptimismPortal have no form of replayability.\n * Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface.\n */\ncontract OptimismPortal is Initializable, ResourceMetering, Semver {\n /**\n * @notice Represents a proven withdrawal.\n *\n * @custom:field outputRoot Root of the L2 output this was proven against.\n * @custom:field timestamp Timestamp at whcih the withdrawal was proven.\n * @custom:field l2OutputIndex Index of the output this was proven against.\n */\n struct ProvenWithdrawal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2OutputIndex;\n }\n\n /**\n * @notice Version of the deposit event.\n */\n uint256 internal constant DEPOSIT_VERSION = 0;\n\n /**\n * @notice The L2 gas limit set when eth is deposited using the receive() function.\n */\n uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Address of the L2OutputOracle contract.\n */\n L2OutputOracle public immutable L2_ORACLE;\n\n /**\n * @notice Address of the SystemConfig contract.\n */\n SystemConfig public immutable SYSTEM_CONFIG;\n\n /**\n * @notice Address that has the ability to pause and unpause withdrawals.\n */\n address public immutable GUARDIAN;\n\n /**\n * @notice Address of the L2 account which initiated a withdrawal in this transaction. If the\n * of this variable is the default L2 sender address, then we are NOT inside of a call\n * to finalizeWithdrawalTransaction.\n */\n address public l2Sender;\n\n /**\n * @notice A list of withdrawal hashes which have been successfully finalized.\n */\n mapping(bytes32 => bool) public finalizedWithdrawals;\n\n /**\n * @notice A mapping of withdrawal hashes to `ProvenWithdrawal` data.\n */\n mapping(bytes32 => ProvenWithdrawal) public provenWithdrawals;\n\n /**\n * @notice Determines if cross domain messaging is paused. When set to true,\n * deposits and withdrawals are paused. This may be removed in the\n * future.\n */\n bool public paused;\n\n /**\n * @notice Emitted when a transaction is deposited from L1 to L2. The parameters of this event\n * are read by the rollup node and used to derive deposit transactions on L2.\n *\n * @param from Address that triggered the deposit transaction.\n * @param to Address that the deposit transaction is directed to.\n * @param version Version of this deposit transaction event.\n * @param opaqueData ABI encoded deposit data to be parsed off-chain.\n */\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is proven.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n */\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is finalized.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n * @param success Whether the withdrawal transaction was successful.\n */\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n\n /**\n * @notice Emitted when the pause is triggered.\n *\n * @param account Address of the account triggering the pause.\n */\n event Paused(address account);\n\n /**\n * @notice Emitted when the pause is lifted.\n *\n * @param account Address of the account triggering the unpause.\n */\n event Unpaused(address account);\n\n /**\n * @notice Reverts when paused.\n */\n modifier whenNotPaused() {\n require(paused == false, \"OptimismPortal: paused\");\n _;\n }\n\n /**\n * @custom:semver 1.3.0\n *\n * @param _l2Oracle Address of the L2OutputOracle contract.\n * @param _guardian Address that can pause deposits and withdrawals.\n * @param _paused Sets the contract's pausability state.\n * @param _config Address of the SystemConfig contract.\n */\n constructor(\n L2OutputOracle _l2Oracle,\n address _guardian,\n bool _paused,\n SystemConfig _config\n ) Semver(1, 3, 0) {\n L2_ORACLE = _l2Oracle;\n GUARDIAN = _guardian;\n SYSTEM_CONFIG = _config;\n initialize(_paused);\n }\n\n /**\n * @notice Initializer.\n */\n function initialize(bool _paused) public initializer {\n l2Sender = Constants.DEFAULT_L2_SENDER;\n paused = _paused;\n __ResourceMetering_init();\n }\n\n /**\n * @notice Pause deposits and withdrawals.\n */\n function pause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can pause\");\n paused = true;\n emit Paused(msg.sender);\n }\n\n /**\n * @notice Unpause deposits and withdrawals.\n */\n function unpause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can unpause\");\n paused = false;\n emit Unpaused(msg.sender);\n }\n\n /**\n * @notice Accepts value so that users can send ETH directly to this contract and have the\n * funds be deposited to their address on L2. This is intended as a convenience\n * function for EOAs. Contracts should call the depositTransaction() function directly\n * otherwise any deposited funds will be lost due to address aliasing.\n */\n // solhint-disable-next-line ordering\n receive() external payable {\n depositTransaction(msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes(\"\"));\n }\n\n /**\n * @notice Accepts ETH value without triggering a deposit to L2. This function mainly exists\n * for the sake of the migration between the legacy Optimism system and Bedrock.\n */\n function donateETH() external payable {\n // Intentionally empty.\n }\n\n /**\n * @notice Getter for the resource config. Used internally by the ResourceMetering\n * contract. The SystemConfig is the source of truth for the resource config.\n *\n * @return ResourceMetering.ResourceConfig\n */\n function _resourceConfig()\n internal\n view\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return SYSTEM_CONFIG.resourceConfig();\n }\n\n /**\n * @notice Proves a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n * @param _l2OutputIndex L2 output index to prove against.\n * @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root.\n * @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\n */\n function proveWithdrawalTransaction(\n Types.WithdrawalTransaction memory _tx,\n uint256 _l2OutputIndex,\n Types.OutputRootProof calldata _outputRootProof,\n bytes[] calldata _withdrawalProof\n ) external whenNotPaused {\n // Prevent users from creating a deposit transaction where this address is the message\n // sender on L2. Because this is checked here, we do not need to check again in\n // `finalizeWithdrawalTransaction`.\n require(\n _tx.target != address(this),\n \"OptimismPortal: you cannot send messages to the portal contract\"\n );\n\n // Get the output root and load onto the stack to prevent multiple mloads. This will\n // revert if there is no output root for the given block number.\n bytes32 outputRoot = L2_ORACLE.getL2Output(_l2OutputIndex).outputRoot;\n\n // Verify that the output root can be generated with the elements in the proof.\n require(\n outputRoot == Hashing.hashOutputRootProof(_outputRootProof),\n \"OptimismPortal: invalid output root proof\"\n );\n\n // Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // We generally want to prevent users from proving the same withdrawal multiple times\n // because each successive proof will update the timestamp. A malicious user can take\n // advantage of this to prevent other users from finalizing their withdrawal. However,\n // since withdrawals are proven before an output root is finalized, we need to allow users\n // to re-prove their withdrawal only in the case that the output root for their specified\n // output index has been updated.\n require(\n provenWithdrawal.timestamp == 0 ||\n L2_ORACLE.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot !=\n provenWithdrawal.outputRoot,\n \"OptimismPortal: withdrawal hash has already been proven\"\n );\n\n // Compute the storage slot of the withdrawal hash in the L2ToL1MessagePasser contract.\n // Refer to the Solidity documentation for more information on how storage layouts are\n // computed for mappings.\n bytes32 storageKey = keccak256(\n abi.encode(\n withdrawalHash,\n uint256(0) // The withdrawals mapping is at the first slot in the layout.\n )\n );\n\n // Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract\n // on L2. If this is true, under the assumption that the SecureMerkleTrie does not have\n // bugs, then we know that this withdrawal was actually triggered on L2 and can therefore\n // be relayed on L1.\n require(\n SecureMerkleTrie.verifyInclusionProof(\n abi.encode(storageKey),\n hex\"01\",\n _withdrawalProof,\n _outputRootProof.messagePasserStorageRoot\n ),\n \"OptimismPortal: invalid withdrawal inclusion proof\"\n );\n\n // Designate the withdrawalHash as proven by storing the `outputRoot`, `timestamp`, and\n // `l2BlockNumber` in the `provenWithdrawals` mapping. A `withdrawalHash` can only be\n // proven once unless it is submitted again with a different outputRoot.\n provenWithdrawals[withdrawalHash] = ProvenWithdrawal({\n outputRoot: outputRoot,\n timestamp: uint128(block.timestamp),\n l2OutputIndex: uint128(_l2OutputIndex)\n });\n\n // Emit a `WithdrawalProven` event.\n emit WithdrawalProven(withdrawalHash, _tx.sender, _tx.target);\n }\n\n /**\n * @notice Finalizes a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n */\n function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx)\n external\n whenNotPaused\n {\n // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other\n // than the default value when a withdrawal transaction is being finalized. This check is\n // a defacto reentrancy guard.\n require(\n l2Sender == Constants.DEFAULT_L2_SENDER,\n \"OptimismPortal: can only trigger one withdrawal per transaction\"\n );\n\n // Grab the proven withdrawal from the `provenWithdrawals` map.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // A withdrawal can only be finalized if it has been proven. We know that a withdrawal has\n // been proven at least once when its timestamp is non-zero. Unproven withdrawals will have\n // a timestamp of zero.\n require(\n provenWithdrawal.timestamp != 0,\n \"OptimismPortal: withdrawal has not been proven yet\"\n );\n\n // As a sanity check, we make sure that the proven withdrawal's timestamp is greater than\n // starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of\n // safety against weird bugs in the proving step.\n require(\n provenWithdrawal.timestamp >= L2_ORACLE.startingTimestamp(),\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n\n // A proven withdrawal must wait at least the finalization period before it can be\n // finalized. This waiting period can elapse in parallel with the waiting period for the\n // output the withdrawal was proven against. In effect, this means that the minimum\n // withdrawal time is proposal submission time + finalization period.\n require(\n _isFinalizationPeriodElapsed(provenWithdrawal.timestamp),\n \"OptimismPortal: proven withdrawal finalization period has not elapsed\"\n );\n\n // Grab the OutputProposal from the L2OutputOracle, will revert if the output that\n // corresponds to the given index has not been proposed yet.\n Types.OutputProposal memory proposal = L2_ORACLE.getL2Output(\n provenWithdrawal.l2OutputIndex\n );\n\n // Check that the output root that was used to prove the withdrawal is the same as the\n // current output root for the given output index. An output root may change if it is\n // deleted by the challenger address and then re-proposed.\n require(\n proposal.outputRoot == provenWithdrawal.outputRoot,\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n\n // Check that the output proposal has also been finalized.\n require(\n _isFinalizationPeriodElapsed(proposal.timestamp),\n \"OptimismPortal: output proposal finalization period has not elapsed\"\n );\n\n // Check that this withdrawal has not already been finalized, this is replay protection.\n require(\n finalizedWithdrawals[withdrawalHash] == false,\n \"OptimismPortal: withdrawal has already been finalized\"\n );\n\n // Mark the withdrawal as finalized so it can't be replayed.\n finalizedWithdrawals[withdrawalHash] = true;\n\n // Set the l2Sender so contracts know who triggered this withdrawal on L2.\n l2Sender = _tx.sender;\n\n // Trigger the call to the target contract. We use a custom low level method\n // SafeCall.callWithMinGas to ensure two key properties\n // 1. Target contracts cannot force this call to run out of gas by returning a very large\n // amount of data (and this is OK because we don't care about the returndata here).\n // 2. The amount of gas provided to the call to the target contract is at least the gas\n // limit specified by the user. If there is not enough gas in the callframe to\n // accomplish this, `callWithMinGas` will revert.\n // Additionally, if there is not enough gas remaining to complete the execution after the\n // call returns, this function will revert.\n bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data);\n\n // Reset the l2Sender back to the default value.\n l2Sender = Constants.DEFAULT_L2_SENDER;\n\n // All withdrawals are immediately finalized. Replayability can\n // be achieved through contracts built on top of this contract\n emit WithdrawalFinalized(withdrawalHash, success);\n\n // Reverting here is useful for determining the exact gas cost to successfully execute the\n // sub call to the target contract if the minimum gas limit specified by the user would not\n // be sufficient to execute the sub call.\n if (success == false && tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"OptimismPortal: withdrawal failed\");\n }\n }\n\n /**\n * @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in\n * deriving deposit transactions. Note that if a deposit is made by a contract, its\n * address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider\n * using the CrossDomainMessenger contracts for a simpler developer experience.\n *\n * @param _to Target address on L2.\n * @param _value ETH value to send to the recipient.\n * @param _gasLimit Minimum L2 gas limit (can be greater than or equal to this value).\n * @param _isCreation Whether or not the transaction is a contract creation.\n * @param _data Data to trigger the recipient with.\n */\n function depositTransaction(\n address _to,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable metered(_gasLimit) {\n // Just to be safe, make sure that people specify address(0) as the target when doing\n // contract creations.\n if (_isCreation) {\n require(\n _to == address(0),\n \"OptimismPortal: must send to address(0) when creating a contract\"\n );\n }\n\n // Prevent depositing transactions that have too small of a gas limit.\n require(_gasLimit >= 21_000, \"OptimismPortal: gas limit must cover instrinsic gas cost\");\n\n // Transform the from-address to its alias if the caller is a contract.\n address from = msg.sender;\n if (msg.sender != tx.origin) {\n from = AddressAliasHelper.applyL1ToL2Alias(msg.sender);\n }\n\n // Compute the opaque data that will be emitted as part of the TransactionDeposited event.\n // We use opaque data so that we can update the TransactionDeposited event in the future\n // without breaking the current interface.\n bytes memory opaqueData = abi.encodePacked(\n msg.value,\n _value,\n _gasLimit,\n _isCreation,\n _data\n );\n\n // Emit a TransactionDeposited event so that the rollup node can derive a deposit\n // transaction for this deposit.\n emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);\n }\n\n /**\n * @notice Determine if a given output is finalized. Reverts if the call to\n * L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\n *\n * @param _l2OutputIndex Index of the L2 output to check.\n *\n * @return Whether or not the output is finalized.\n */\n function isOutputFinalized(uint256 _l2OutputIndex) external view returns (bool) {\n return _isFinalizationPeriodElapsed(L2_ORACLE.getL2Output(_l2OutputIndex).timestamp);\n }\n\n /**\n * @notice Determines whether the finalization period has elapsed w/r/t a given timestamp.\n *\n * @param _timestamp Timestamp to check.\n *\n * @return Whether or not the finalization period has elapsed.\n */\n function _isFinalizationPeriodElapsed(uint256 _timestamp) internal view returns (bool) {\n return block.timestamp > _timestamp + L2_ORACLE.FINALIZATION_PERIOD_SECONDS();\n }\n}\n" - }, - "contracts/L1/ResourceMetering.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\n\n/**\n * @custom:upgradeable\n * @title ResourceMetering\n * @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing\n * updates automatically based on current demand.\n */\nabstract contract ResourceMetering is Initializable {\n /**\n * @notice Represents the various parameters that control the way in which resources are\n * metered. Corresponds to the EIP-1559 resource metering system.\n *\n * @custom:field prevBaseFee Base fee from the previous block(s).\n * @custom:field prevBoughtGas Amount of gas bought so far in the current block.\n * @custom:field prevBlockNum Last block number that the base fee was updated.\n */\n struct ResourceParams {\n uint128 prevBaseFee;\n uint64 prevBoughtGas;\n uint64 prevBlockNum;\n }\n\n /**\n * @notice Represents the configuration for the EIP-1559 based curve for the deposit gas\n * market. These values should be set with care as it is possible to set them in\n * a way that breaks the deposit gas market. The target resource limit is defined as\n * maxResourceLimit / elasticityMultiplier. This struct was designed to fit within a\n * single word. There is additional space for additions in the future.\n *\n * @custom:field maxResourceLimit Represents the maximum amount of deposit gas that\n * can be purchased per block.\n * @custom:field elasticityMultiplier Determines the target resource limit along with\n * the resource limit.\n * @custom:field baseFeeMaxChangeDenominator Determines max change on fee per block.\n * @custom:field minimumBaseFee The min deposit base fee, it is clamped to this\n * value.\n * @custom:field systemTxMaxGas The amount of gas supplied to the system\n * transaction. This should be set to the same number\n * that the op-node sets as the gas limit for the\n * system transaction.\n * @custom:field maximumBaseFee The max deposit base fee, it is clamped to this\n * value.\n */\n struct ResourceConfig {\n uint32 maxResourceLimit;\n uint8 elasticityMultiplier;\n uint8 baseFeeMaxChangeDenominator;\n uint32 minimumBaseFee;\n uint32 systemTxMaxGas;\n uint128 maximumBaseFee;\n }\n\n /**\n * @notice EIP-1559 style gas parameters.\n */\n ResourceParams public params;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[48] private __gap;\n\n /**\n * @notice Meters access to a function based an amount of a requested resource.\n *\n * @param _amount Amount of the resource requested.\n */\n modifier metered(uint64 _amount) {\n // Record initial gas amount so we can refund for it later.\n uint256 initialGas = gasleft();\n\n // Run the underlying function.\n _;\n\n // Run the metering function.\n _metered(_amount, initialGas);\n }\n\n /**\n * @notice An internal function that holds all of the logic for metering a resource.\n *\n * @param _amount Amount of the resource requested.\n * @param _initialGas The amount of gas before any modifier execution.\n */\n function _metered(uint64 _amount, uint256 _initialGas) internal {\n // Update block number and base fee if necessary.\n uint256 blockDiff = block.number - params.prevBlockNum;\n\n ResourceConfig memory config = _resourceConfig();\n int256 targetResourceLimit = int256(uint256(config.maxResourceLimit)) /\n int256(uint256(config.elasticityMultiplier));\n\n if (blockDiff > 0) {\n // Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate\n // at which deposits can be created and therefore limit the potential for deposits to\n // spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.\n int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit;\n int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) /\n (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));\n\n // Update base fee by adding the base fee delta and clamp the resulting value between\n // min and max.\n int256 newBaseFee = Arithmetic.clamp({\n _value: int256(uint256(params.prevBaseFee)) + baseFeeDelta,\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n\n // If we skipped more than one block, we also need to account for every empty block.\n // Empty block means there was no demand for deposits in that block, so we should\n // reflect this lack of demand in the fee.\n if (blockDiff > 1) {\n // Update the base fee by repeatedly applying the exponent 1-(1/change_denominator)\n // blockDiff - 1 times. Simulates multiple empty blocks. Clamp the resulting value\n // between min and max.\n newBaseFee = Arithmetic.clamp({\n _value: Arithmetic.cdexp({\n _coefficient: newBaseFee,\n _denominator: int256(uint256(config.baseFeeMaxChangeDenominator)),\n _exponent: int256(blockDiff - 1)\n }),\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n }\n\n // Update new base fee, reset bought gas, and update block number.\n params.prevBaseFee = uint128(uint256(newBaseFee));\n params.prevBoughtGas = 0;\n params.prevBlockNum = uint64(block.number);\n }\n\n // Make sure we can actually buy the resource amount requested by the user.\n params.prevBoughtGas += _amount;\n require(\n int256(uint256(params.prevBoughtGas)) <= int256(uint256(config.maxResourceLimit)),\n \"ResourceMetering: cannot buy more gas than available gas limit\"\n );\n\n // Determine the amount of ETH to be paid.\n uint256 resourceCost = uint256(_amount) * uint256(params.prevBaseFee);\n\n // We currently charge for this ETH amount as an L1 gas burn, so we convert the ETH amount\n // into gas by dividing by the L1 base fee. We assume a minimum base fee of 1 gwei to avoid\n // division by zero for L1s that don't support 1559 or to avoid excessive gas burns during\n // periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei\n // during any 1 day period in the last 5 years, so should be fine.\n uint256 gasCost = resourceCost / Math.max(block.basefee, 1 gwei);\n\n // Give the user a refund based on the amount of gas they used to do all of the work up to\n // this point. Since we're at the end of the modifier, this should be pretty accurate. Acts\n // effectively like a dynamic stipend (with a minimum value).\n uint256 usedGas = _initialGas - gasleft();\n if (gasCost > usedGas) {\n Burn.gas(gasCost - usedGas);\n }\n }\n\n /**\n * @notice Virtual function that returns the resource config. Contracts that inherit this\n * contract must implement this function.\n *\n * @return ResourceConfig\n */\n function _resourceConfig() internal virtual returns (ResourceConfig memory);\n\n /**\n * @notice Sets initial resource parameter values. This function must either be called by the\n * initializer function of an upgradeable child contract.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __ResourceMetering_init() internal onlyInitializing {\n params = ResourceParams({\n prevBaseFee: 1 gwei,\n prevBoughtGas: 0,\n prevBlockNum: uint64(block.number)\n });\n }\n}\n" - }, - "contracts/L1/SystemConfig.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\n\n/**\n * @title SystemConfig\n * @notice The SystemConfig contract is used to manage configuration of an Optimism network. All\n * configuration is stored on L1 and picked up by L2 as part of the derviation of the L2\n * chain.\n */\ncontract SystemConfig is OwnableUpgradeable, Semver {\n /**\n * @notice Enum representing different types of updates.\n *\n * @custom:value BATCHER Represents an update to the batcher hash.\n * @custom:value GAS_CONFIG Represents an update to txn fee config on L2.\n * @custom:value GAS_LIMIT Represents an update to gas limit on L2.\n * @custom:value UNSAFE_BLOCK_SIGNER Represents an update to the signer key for unsafe\n * block distrubution.\n */\n enum UpdateType {\n BATCHER,\n GAS_CONFIG,\n GAS_LIMIT,\n UNSAFE_BLOCK_SIGNER\n }\n\n /**\n * @notice Version identifier, used for upgrades.\n */\n uint256 public constant VERSION = 0;\n\n /**\n * @notice Storage slot that the unsafe block signer is stored at. Storing it at this\n * deterministic storage slot allows for decoupling the storage layout from the way\n * that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value.\n */\n bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256(\"systemconfig.unsafeblocksigner\");\n\n /**\n * @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public overhead;\n\n /**\n * @notice Dynamic L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public scalar;\n\n /**\n * @notice Identifier for the batcher. For version 1 of this configuration, this is represented\n * as an address left-padded with zeros to 32 bytes.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice L2 block gas limit.\n */\n uint64 public gasLimit;\n\n /**\n * @notice The configuration for the deposit fee market. Used by the OptimismPortal\n * to meter the cost of buying L2 gas on L1. Set as internal and wrapped with a getter\n * so that the struct is returned instead of a tuple.\n */\n ResourceMetering.ResourceConfig internal _resourceConfig;\n\n /**\n * @notice Emitted when configuration is updated\n *\n * @param version SystemConfig version.\n * @param updateType Type of update.\n * @param data Encoded update data.\n */\n event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);\n\n /**\n * @custom:semver 1.2.0\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial resource config.\n */\n constructor(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) Semver(1, 2, 0) {\n initialize({\n _owner: _owner,\n _overhead: _overhead,\n _scalar: _scalar,\n _batcherHash: _batcherHash,\n _gasLimit: _gasLimit,\n _unsafeBlockSigner: _unsafeBlockSigner,\n _config: _config\n });\n }\n\n /**\n * @notice Initializer. The resource config must be set before the\n * require check.\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial ResourceConfig.\n */\n function initialize(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) public initializer {\n __Ownable_init();\n transferOwnership(_owner);\n overhead = _overhead;\n scalar = _scalar;\n batcherHash = _batcherHash;\n gasLimit = _gasLimit;\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n _setResourceConfig(_config);\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n }\n\n /**\n * @notice Returns the minimum L2 gas limit that can be safely set for the system to\n * operate. The L2 gas limit must be larger than or equal to the amount of\n * gas that is allocated for deposits per block plus the amount of gas that\n * is allocated for the system transaction.\n * This function is used to determine if changes to parameters are safe.\n *\n * @return uint64\n */\n function minimumGasLimit() public view returns (uint64) {\n return uint64(_resourceConfig.maxResourceLimit) + uint64(_resourceConfig.systemTxMaxGas);\n }\n\n /**\n * @notice High level getter for the unsafe block signer address. Unsafe blocks can be\n * propagated across the p2p network if they are signed by the key corresponding to\n * this address.\n *\n * @return Address of the unsafe block signer.\n */\n // solhint-disable-next-line ordering\n function unsafeBlockSigner() external view returns (address) {\n address addr;\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n addr := sload(slot)\n }\n return addr;\n }\n\n /**\n * @notice Updates the unsafe block signer address.\n *\n * @param _unsafeBlockSigner New unsafe block signer address.\n */\n function setUnsafeBlockSigner(address _unsafeBlockSigner) external onlyOwner {\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n\n bytes memory data = abi.encode(_unsafeBlockSigner);\n emit ConfigUpdate(VERSION, UpdateType.UNSAFE_BLOCK_SIGNER, data);\n }\n\n /**\n * @notice Updates the batcher hash.\n *\n * @param _batcherHash New batcher hash.\n */\n function setBatcherHash(bytes32 _batcherHash) external onlyOwner {\n batcherHash = _batcherHash;\n\n bytes memory data = abi.encode(_batcherHash);\n emit ConfigUpdate(VERSION, UpdateType.BATCHER, data);\n }\n\n /**\n * @notice Updates gas config.\n *\n * @param _overhead New overhead value.\n * @param _scalar New scalar value.\n */\n function setGasConfig(uint256 _overhead, uint256 _scalar) external onlyOwner {\n overhead = _overhead;\n scalar = _scalar;\n\n bytes memory data = abi.encode(_overhead, _scalar);\n emit ConfigUpdate(VERSION, UpdateType.GAS_CONFIG, data);\n }\n\n /**\n * @notice Updates the L2 gas limit.\n *\n * @param _gasLimit New gas limit.\n */\n function setGasLimit(uint64 _gasLimit) external onlyOwner {\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n gasLimit = _gasLimit;\n\n bytes memory data = abi.encode(_gasLimit);\n emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data);\n }\n\n /**\n * @notice Low level setter for the unsafe block signer address. This function exists to\n * deduplicate code around storing the unsafeBlockSigner address in storage.\n *\n * @param _unsafeBlockSigner New unsafeBlockSigner value.\n */\n function _setUnsafeBlockSigner(address _unsafeBlockSigner) internal {\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n sstore(slot, _unsafeBlockSigner)\n }\n }\n\n /**\n * @notice A getter for the resource config. Ensures that the struct is\n * returned instead of a tuple.\n *\n * @return ResourceConfig\n */\n function resourceConfig() external view returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig;\n }\n\n /**\n * @notice An external setter for the resource config. In the future, this\n * method may emit an event that the `op-node` picks up for when the\n * resource config is changed.\n *\n * @param _config The new resource config values.\n */\n function setResourceConfig(ResourceMetering.ResourceConfig memory _config) external onlyOwner {\n _setResourceConfig(_config);\n }\n\n /**\n * @notice An internal setter for the resource config. Ensures that the\n * config is sane before storing it by checking for invariants.\n *\n * @param _config The new resource config.\n */\n function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal {\n // Min base fee must be less than or equal to max base fee.\n require(\n _config.minimumBaseFee <= _config.maximumBaseFee,\n \"SystemConfig: min base fee must be less than max base\"\n );\n // Base fee change denominator must be greater than 0.\n require(_config.baseFeeMaxChangeDenominator > 0, \"SystemConfig: denominator cannot be 0\");\n // Max resource limit plus system tx gas must be less than or equal to the L2 gas limit.\n // The gas limit must be increased before these values can be increased.\n require(\n _config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit,\n \"SystemConfig: gas limit too low\"\n );\n // Elasticity multiplier must be greater than 0.\n require(\n _config.elasticityMultiplier > 0,\n \"SystemConfig: elasticity multiplier cannot be 0\"\n );\n // No precision loss when computing target resource limit.\n require(\n ((_config.maxResourceLimit / _config.elasticityMultiplier) *\n _config.elasticityMultiplier) == _config.maxResourceLimit,\n \"SystemConfig: precision loss with target resource limit\"\n );\n\n _resourceConfig = _config;\n }\n}\n" - }, - "contracts/L2/BaseFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000019\n * @title BaseFeeVault\n * @notice The BaseFeeVault accumulates the base fee that is paid by transactions.\n */\ncontract BaseFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 0, 0) {}\n}\n" - }, - "contracts/L2/CrossDomainOwnable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\n/**\n * @title CrossDomainOwnable\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is only safe to be used if the\n * CrossDomainMessenger system is bypassed and the caller on L1 is calling the\n * OptimismPortal directly.\n */\nabstract contract CrossDomainOwnable is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `msg.sender` is the owner of the contract.\n */\n function _checkOwner() internal view override {\n require(\n owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender),\n \"CrossDomainOwnable: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable2\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is meant to be used with systems that use\n * the CrossDomainMessenger system. It will not work if the OptimismPortal is used\n * directly.\n */\nabstract contract CrossDomainOwnable2 is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable2: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable2: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable3\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on either L1 or L2. Note that this contract is meant to be used with systems\n * that use the CrossDomainMessenger system. It will not work if the OptimismPortal is\n * used directly.\n */\nabstract contract CrossDomainOwnable3 is Ownable {\n /**\n * @notice If true, the contract uses the cross domain _checkOwner function override. If false\n * it uses the standard Ownable _checkOwner function.\n */\n bool public isLocal = true;\n\n /**\n * @notice Emits when ownership of the contract is transferred. Includes the\n * isLocal field in addition to the standard `Ownable` OwnershipTransferred event.\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n /**\n * @notice Allows for ownership to be transferred with specifying the locality.\n * @param _owner The new owner of the contract.\n * @param _isLocal Configures the locality of the ownership.\n */\n function transferOwnership(address _owner, bool _isLocal) external onlyOwner {\n require(_owner != address(0), \"CrossDomainOwnable3: new owner is the zero address\");\n\n address oldOwner = owner();\n _transferOwnership(_owner);\n isLocal = _isLocal;\n\n emit OwnershipTransferred(oldOwner, _owner, _isLocal);\n }\n\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n if (isLocal) {\n require(owner() == msg.sender, \"CrossDomainOwnable3: caller is not the owner\");\n } else {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable3: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable3: caller is not the owner\"\n );\n }\n }\n}\n" - }, - "contracts/L2/GasPriceOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000000F\n * @title GasPriceOracle\n * @notice This contract maintains the variables responsible for computing the L1 portion of the\n * total fee charged on L2. Before Bedrock, this contract held variables in state that were\n * read during the state transition function to compute the L1 portion of the transaction\n * fee. After Bedrock, this contract now simply proxies the L1Block contract, which has\n * the values used to compute the L1 portion of the fee in its state.\n *\n * The contract exposes an API that is useful for knowing how large the L1 portion of the\n * transaction fee will be. The following events were deprecated with Bedrock:\n * - event OverheadUpdated(uint256 overhead);\n * - event ScalarUpdated(uint256 scalar);\n * - event DecimalsUpdated(uint256 decimals);\n */\ncontract GasPriceOracle is Semver {\n /**\n * @notice Number of decimals used in the scalar.\n */\n uint256 public constant DECIMALS = 6;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Computes the L1 portion of the fee based on the size of the rlp encoded input\n * transaction, the current L1 base fee, and the various dynamic parameters.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.\n *\n * @return L1 fee that should be paid for the tx\n */\n function getL1Fee(bytes memory _data) external view returns (uint256) {\n uint256 l1GasUsed = getL1GasUsed(_data);\n uint256 l1Fee = l1GasUsed * l1BaseFee();\n uint256 divisor = 10**DECIMALS;\n uint256 unscaled = l1Fee * scalar();\n uint256 scaled = unscaled / divisor;\n return scaled;\n }\n\n /**\n * @notice Retrieves the current gas price (base fee).\n *\n * @return Current L2 gas price (base fee).\n */\n function gasPrice() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current base fee.\n *\n * @return Current L2 base fee.\n */\n function baseFee() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current fee overhead.\n *\n * @return Current fee overhead.\n */\n function overhead() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead();\n }\n\n /**\n * @notice Retrieves the current fee scalar.\n *\n * @return Current fee scalar.\n */\n function scalar() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar();\n }\n\n /**\n * @notice Retrieves the latest known L1 base fee.\n *\n * @return Latest known L1 base fee.\n */\n function l1BaseFee() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee();\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the number of decimals used in the scalar.\n *\n * @return Number of decimals used in the scalar.\n */\n function decimals() public pure returns (uint256) {\n return DECIMALS;\n }\n\n /**\n * @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which\n * represents the per-transaction gas overhead of posting the transaction and state\n * roots to L1. Adds 68 bytes of padding to account for the fact that the input does\n * not have a signature.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for.\n *\n * @return Amount of L1 gas used to publish the transaction.\n */\n function getL1GasUsed(bytes memory _data) public view returns (uint256) {\n uint256 total = 0;\n uint256 length = _data.length;\n for (uint256 i = 0; i < length; i++) {\n if (_data[i] == 0) {\n total += 4;\n } else {\n total += 16;\n }\n }\n uint256 unsigned = total + overhead();\n return unsigned + (68 * 16);\n }\n}\n" - }, - "contracts/L2/L1Block.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000015\n * @title L1Block\n * @notice The L1Block predeploy gives users access to information about the last known L1 block.\n * Values within this contract are updated once per epoch (every L1 block) and can only be\n * set by the \"depositor\" account, a special system address. Depositor account transactions\n * are created by the protocol whenever we move to a new epoch.\n */\ncontract L1Block is Semver {\n /**\n * @notice Address of the special depositor account.\n */\n address public constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001;\n\n /**\n * @notice The latest L1 block number known by the L2 system.\n */\n uint64 public number;\n\n /**\n * @notice The latest L1 timestamp known by the L2 system.\n */\n uint64 public timestamp;\n\n /**\n * @notice The latest L1 basefee.\n */\n uint256 public basefee;\n\n /**\n * @notice The latest L1 blockhash.\n */\n bytes32 public hash;\n\n /**\n * @notice The number of L2 blocks in the same epoch.\n */\n uint64 public sequenceNumber;\n\n /**\n * @notice The versioned hash to authenticate the batcher by.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice The overhead value applied to the L1 portion of the transaction\n * fee.\n */\n uint256 public l1FeeOverhead;\n\n /**\n * @notice The scalar value applied to the L1 portion of the transaction fee.\n */\n uint256 public l1FeeScalar;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Updates the L1 block values.\n *\n * @param _number L1 blocknumber.\n * @param _timestamp L1 timestamp.\n * @param _basefee L1 basefee.\n * @param _hash L1 blockhash.\n * @param _sequenceNumber Number of L2 blocks since epoch start.\n * @param _batcherHash Versioned hash to authenticate batcher by.\n * @param _l1FeeOverhead L1 fee overhead.\n * @param _l1FeeScalar L1 fee scalar.\n */\n function setL1BlockValues(\n uint64 _number,\n uint64 _timestamp,\n uint256 _basefee,\n bytes32 _hash,\n uint64 _sequenceNumber,\n bytes32 _batcherHash,\n uint256 _l1FeeOverhead,\n uint256 _l1FeeScalar\n ) external {\n require(\n msg.sender == DEPOSITOR_ACCOUNT,\n \"L1Block: only the depositor account can set L1 block values\"\n );\n\n number = _number;\n timestamp = _timestamp;\n basefee = _basefee;\n hash = _hash;\n sequenceNumber = _sequenceNumber;\n batcherHash = _batcherHash;\n l1FeeOverhead = _l1FeeOverhead;\n l1FeeScalar = _l1FeeScalar;\n }\n}\n" - }, - "contracts/L2/L1FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000001A\n * @title L1FeeVault\n * @notice The L1FeeVault accumulates the L1 portion of the transaction fees.\n */\ncontract L1FeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 0, 0) {}\n}\n" - }, - "contracts/L2/L2CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { L2ToL1MessagePasser } from \"./L2ToL1MessagePasser.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000007\n * @title L2CrossDomainMessenger\n * @notice The L2CrossDomainMessenger is a high-level interface for message passing between L1 and\n * L2 on the L2 side. Users are generally encouraged to use this contract instead of lower\n * level message passing contracts.\n */\ncontract L2CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.\n */\n constructor(address _l1CrossDomainMessenger)\n Semver(1, 1, 0)\n CrossDomainMessenger(_l1CrossDomainMessenger)\n {\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote messenger. Use otherMessenger going forward.\n *\n * @return Address of the L1CrossDomainMessenger contract.\n */\n function l1CrossDomainMessenger() public view returns (address) {\n return OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{\n value: _value\n }(_to, _gasLimit, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(Predeploys.L2_TO_L1_MESSAGE_PASSER);\n }\n}\n" - }, - "contracts/L2/L2ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { IOptimismMintableERC721 } from \"../universal/IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L2ERC721Bridge\n * @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.\n * This contract also acts as a burner for tokens being withdrawn.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n */\ncontract L2ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L1. Data supplied here will not be used to\n * execute any code on L1 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L2ERC721Bridge: local token cannot be self\");\n\n // Note that supportsInterface makes a callback to the _localToken address which is user\n // provided.\n require(\n ERC165Checker.supportsInterface(_localToken, type(IOptimismMintableERC721).interfaceId),\n \"L2ERC721Bridge: local token interface is not compliant\"\n );\n\n require(\n _remoteToken == IOptimismMintableERC721(_localToken).remoteToken(),\n \"L2ERC721Bridge: wrong remote token for Optimism Mintable ERC721 local token\"\n );\n\n // When a deposit is finalized, we give the NFT with the same tokenId to the account\n // on L2. Note that safeMint makes a callback to the _to address which is user provided.\n IOptimismMintableERC721(_localToken).safeMint(_to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L2ERC721Bridge: remote token cannot be address(0)\");\n\n // Check that the withdrawal is being initiated by the NFT owner\n require(\n _from == IOptimismMintableERC721(_localToken).ownerOf(_tokenId),\n \"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\"\n );\n\n // Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)\n // slither-disable-next-line reentrancy-events\n address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();\n require(\n remoteToken == _remoteToken,\n \"L2ERC721Bridge: remote token does not match given value\"\n );\n\n // When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2\n // usage\n // slither-disable-next-line reentrancy-events\n IOptimismMintableERC721(_localToken).burn(_from, _tokenId);\n\n bytes memory message = abi.encodeWithSelector(\n L1ERC721Bridge.finalizeBridgeERC721.selector,\n remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Send message to L1 bridge\n // slither-disable-next-line reentrancy-events\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L2/L2StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000010\n * @title L2StandardBridge\n * @notice The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L2, it will be escrowed within this\n * contract. If the ERC20 token is native to L1, it will be burnt.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L2StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal from L2 to L1 is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _otherBridge Address of the L1StandardBridge.\n */\n constructor(address payable _otherBridge)\n Semver(1, 1, 0)\n StandardBridge(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER), _otherBridge)\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateWithdrawal(\n Predeploys.LEGACY_ERC20_ETH,\n msg.sender,\n msg.sender,\n msg.value,\n RECEIVE_DEFAULT_GAS_LIMIT,\n bytes(\"\")\n );\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdraw(\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual onlyEOA {\n _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1 to a target account on L1.\n * Note that if ETH is sent to a contract on L1 and the call fails, then that ETH will\n * be locked in the L1StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20To` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdrawTo(\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual {\n _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a deposit from L1 to L2. To finalize a deposit of ether, use address(0)\n * and the l1Token and the Legacy ERC20 ether predeploy address as the l2Token.\n *\n * @param _l1Token Address of the L1 token to deposit.\n * @param _l2Token Address of the corresponding L2 token.\n * @param _from Address of the depositor.\n * @param _to Address of the recipient.\n * @param _amount Amount of the tokens being deposited.\n * @param _extraData Extra data attached to the deposit.\n */\n function finalizeDeposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable virtual {\n if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n } else {\n finalizeBridgeERC20(_l2Token, _l1Token, _from, _to, _amount, _extraData);\n }\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L1 bridge contract.\n *\n * @return Address of the corresponding L1 bridge contract.\n */\n function l1TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @custom:legacy\n * @notice Internal function to a withdrawal from L2 to L1 to a target account on L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _from Address of the withdrawer.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function _initiateWithdrawal(\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {\n _initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);\n } else {\n address l1Token = OptimismMintableERC20(_l2Token).l1Token();\n _initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ETHBridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ERC20BridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L2/L2ToL1MessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000016\n * @title L2ToL1MessagePasser\n * @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from\n * L2 to L1 can be stored. The storage root of this contract is pulled up to the top level\n * of the L2 output to reduce the cost of proving the existence of sent messages.\n */\ncontract L2ToL1MessagePasser is Semver {\n /**\n * @notice The L1 gas limit set when eth is withdrawn using the receive() function.\n */\n uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Includes the message hashes for all withdrawals\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @notice A unique value hashed with each withdrawal.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Emitted any time a withdrawal is initiated.\n *\n * @param nonce Unique value corresponding to each withdrawal.\n * @param sender The L2 account address which initiated the withdrawal.\n * @param target The L1 account address the call will be send to.\n * @param value The ETH value submitted for withdrawal, to be forwarded to the target.\n * @param gasLimit The minimum amount of gas that must be provided when withdrawing.\n * @param data The data to be forwarded to the target on L1.\n * @param withdrawalHash The hash of the withdrawal.\n */\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n /**\n * @notice Emitted when the balance of this contract is burned.\n *\n * @param amount Amount of ETh that was burned.\n */\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Allows users to withdraw ETH by sending directly to this contract.\n */\n receive() external payable {\n initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @notice Removes all ETH held by this contract from the state. Used to prevent the amount of\n * ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to\n * create a contract and self-destruct it to itself. Anyone can call this function. Not\n * incentivized since this function is very cheap.\n */\n function burn() external {\n uint256 balance = address(this).balance;\n Burn.eth(balance);\n emit WithdrawerBalanceBurnt(balance);\n }\n\n /**\n * @notice Sends a message from L2 to L1.\n *\n * @param _target Address to call on L1 execution.\n * @param _gasLimit Minimum gas limit for executing the message on L1.\n * @param _data Data to forward to L1 target.\n */\n function initiateWithdrawal(\n address _target,\n uint256 _gasLimit,\n bytes memory _data\n ) public payable {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messageNonce(),\n sender: msg.sender,\n target: _target,\n value: msg.value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n sentMessages[withdrawalHash] = true;\n\n emit MessagePassed(\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _gasLimit,\n _data,\n withdrawalHash\n );\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n}\n" - }, - "contracts/L2/SequencerFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000011\n * @title SequencerFeeVault\n * @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during\n * transaction processing and block production.\n */\ncontract SequencerFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 0, 0) {}\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the recipient address.\n *\n * @return The recipient address.\n */\n function l1FeeWallet() public view returns (address) {\n return RECIPIENT;\n }\n}\n" - }, - "contracts/deployment/PortalSender.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/**\n * @title PortalSender\n * @notice The PortalSender is a simple intermediate contract that will transfer the balance of the\n * L1StandardBridge to the OptimismPortal during the Bedrock migration.\n */\ncontract PortalSender {\n /**\n * @notice Address of the OptimismPortal contract.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @param _portal Address of the OptimismPortal contract.\n */\n constructor(OptimismPortal _portal) {\n PORTAL = _portal;\n }\n\n /**\n * @notice Sends balance of this contract to the OptimismPortal.\n */\n function donate() public {\n PORTAL.donateETH{ value: address(this).balance }();\n }\n}\n" - }, - "contracts/deployment/SystemDictator.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { PortalSender } from \"./PortalSender.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @title SystemDictator\n * @notice The SystemDictator is responsible for coordinating the deployment of a full Bedrock\n * system. The SystemDictator is designed to support both fresh network deployments and\n * upgrades to existing pre-Bedrock systems.\n */\ncontract SystemDictator is OwnableUpgradeable {\n /**\n * @notice Basic system configuration.\n */\n struct GlobalConfig {\n AddressManager addressManager;\n ProxyAdmin proxyAdmin;\n address controller;\n address finalOwner;\n }\n\n /**\n * @notice Set of proxy addresses.\n */\n struct ProxyAddressConfig {\n address l2OutputOracleProxy;\n address optimismPortalProxy;\n address l1CrossDomainMessengerProxy;\n address l1StandardBridgeProxy;\n address optimismMintableERC20FactoryProxy;\n address l1ERC721BridgeProxy;\n address systemConfigProxy;\n }\n\n /**\n * @notice Set of implementation addresses.\n */\n struct ImplementationAddressConfig {\n L2OutputOracle l2OutputOracleImpl;\n OptimismPortal optimismPortalImpl;\n L1CrossDomainMessenger l1CrossDomainMessengerImpl;\n L1StandardBridge l1StandardBridgeImpl;\n OptimismMintableERC20Factory optimismMintableERC20FactoryImpl;\n L1ERC721Bridge l1ERC721BridgeImpl;\n PortalSender portalSenderImpl;\n SystemConfig systemConfigImpl;\n }\n\n /**\n * @notice Dynamic L2OutputOracle config.\n */\n struct L2OutputOracleDynamicConfig {\n uint256 l2OutputOracleStartingBlockNumber;\n uint256 l2OutputOracleStartingTimestamp;\n }\n\n /**\n * @notice Values for the system config contract.\n */\n struct SystemConfigConfig {\n address owner;\n uint256 overhead;\n uint256 scalar;\n bytes32 batcherHash;\n uint64 gasLimit;\n address unsafeBlockSigner;\n ResourceMetering.ResourceConfig resourceConfig;\n }\n\n /**\n * @notice Combined system configuration.\n */\n struct DeployConfig {\n GlobalConfig globalConfig;\n ProxyAddressConfig proxyAddressConfig;\n ImplementationAddressConfig implementationAddressConfig;\n SystemConfigConfig systemConfigConfig;\n }\n\n /**\n * @notice Step after which exit 1 can no longer be used.\n */\n uint8 public constant EXIT_1_NO_RETURN_STEP = 3;\n\n /**\n * @notice Step where proxy ownership is transferred.\n */\n uint8 public constant PROXY_TRANSFER_STEP = 4;\n\n /**\n * @notice System configuration.\n */\n DeployConfig public config;\n\n /**\n * @notice Dynamic configuration for the L2OutputOracle.\n */\n L2OutputOracleDynamicConfig public l2OutputOracleDynamicConfig;\n\n /**\n * @notice Dynamic configuration for the OptimismPortal. Determines\n * if the system should be paused when initialized.\n */\n bool public optimismPortalDynamicConfig;\n\n /**\n * @notice Current step;\n */\n uint8 public currentStep;\n\n /**\n * @notice Whether or not dynamic config has been set.\n */\n bool public dynamicConfigSet;\n\n /**\n * @notice Whether or not the deployment is finalized.\n */\n bool public finalized;\n\n /**\n * @notice Whether or not the deployment has been exited.\n */\n bool public exited;\n\n /**\n * @notice Address of the old L1CrossDomainMessenger implementation.\n */\n address public oldL1CrossDomainMessenger;\n\n /**\n * @notice Checks that the current step is the expected step, then bumps the current step.\n *\n * @param _step Current step.\n */\n modifier step(uint8 _step) {\n require(!finalized, \"SystemDictator: already finalized\");\n require(!exited, \"SystemDictator: already exited\");\n require(currentStep == _step, \"SystemDictator: incorrect step\");\n _;\n currentStep++;\n }\n\n /**\n * @notice Constructor required to ensure that the implementation of the SystemDictator is\n * initialized upon deployment.\n */\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n // Using this shorter variable as an alias for address(0) just prevents us from having to\n // to use a new line for every single parameter.\n address zero = address(0);\n initialize(\n DeployConfig(\n GlobalConfig(AddressManager(zero), ProxyAdmin(zero), zero, zero),\n ProxyAddressConfig(zero, zero, zero, zero, zero, zero, zero),\n ImplementationAddressConfig(\n L2OutputOracle(zero),\n OptimismPortal(payable(zero)),\n L1CrossDomainMessenger(zero),\n L1StandardBridge(payable(zero)),\n OptimismMintableERC20Factory(zero),\n L1ERC721Bridge(zero),\n PortalSender(zero),\n SystemConfig(zero)\n ),\n SystemConfigConfig(zero, 0, 0, bytes32(0), 0, zero, rcfg)\n )\n );\n }\n\n /**\n * @param _config System configuration.\n */\n function initialize(DeployConfig memory _config) public initializer {\n config = _config;\n currentStep = 1;\n __Ownable_init();\n _transferOwnership(config.globalConfig.controller);\n }\n\n /**\n * @notice Allows the owner to update dynamic config.\n *\n * @param _l2OutputOracleDynamicConfig Dynamic L2OutputOracle config.\n * @param _optimismPortalDynamicConfig Dynamic OptimismPortal config.\n */\n function updateDynamicConfig(\n L2OutputOracleDynamicConfig memory _l2OutputOracleDynamicConfig,\n bool _optimismPortalDynamicConfig\n ) external onlyOwner {\n l2OutputOracleDynamicConfig = _l2OutputOracleDynamicConfig;\n optimismPortalDynamicConfig = _optimismPortalDynamicConfig;\n dynamicConfigSet = true;\n }\n\n /**\n * @notice Configures the ProxyAdmin contract.\n */\n function step1() external onlyOwner step(1) {\n // Set the AddressManager in the ProxyAdmin.\n config.globalConfig.proxyAdmin.setAddressManager(config.globalConfig.addressManager);\n\n // Set the L1CrossDomainMessenger to the RESOLVED proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n ProxyAdmin.ProxyType.RESOLVED\n );\n\n // Set the implementation name for the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.setImplementationName(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Set the L1StandardBridge to the CHUGSPLASH proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1StandardBridgeProxy,\n ProxyAdmin.ProxyType.CHUGSPLASH\n );\n\n // Upgrade and initialize the SystemConfig so the Sequencer can start up.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.systemConfigProxy),\n address(config.implementationAddressConfig.systemConfigImpl),\n abi.encodeCall(\n SystemConfig.initialize,\n (\n config.systemConfigConfig.owner,\n config.systemConfigConfig.overhead,\n config.systemConfigConfig.scalar,\n config.systemConfigConfig.batcherHash,\n config.systemConfigConfig.gasLimit,\n config.systemConfigConfig.unsafeBlockSigner,\n config.systemConfigConfig.resourceConfig\n )\n )\n );\n }\n\n /**\n * @notice Pauses the system by shutting down the L1CrossDomainMessenger and setting the\n * deposit halt flag to tell the Sequencer's DTL to stop accepting deposits.\n */\n function step2() external onlyOwner step(2) {\n // Store the address of the old L1CrossDomainMessenger implementation. We will need this\n // address in the case that we have to exit early.\n oldL1CrossDomainMessenger = config.globalConfig.addressManager.getAddress(\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Temporarily brick the L1CrossDomainMessenger by setting its implementation address to\n // address(0) which will cause the ResolvedDelegateProxy to revert. Better than pausing\n // the L1CrossDomainMessenger via pause() because it can be easily reverted.\n config.globalConfig.addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(0));\n\n // Set the DTL shutoff block, which will tell the DTL to stop syncing new deposits from the\n // CanonicalTransactionChain. We do this by setting an address in the AddressManager\n // because the DTL already has a reference to the AddressManager and this way we don't also\n // need to give it a reference to the SystemDictator.\n config.globalConfig.addressManager.setAddress(\n \"DTL_SHUTOFF_BLOCK\",\n address(uint160(block.number))\n );\n }\n\n /**\n * @notice Removes deprecated addresses from the AddressManager.\n */\n function step3() external onlyOwner step(EXIT_1_NO_RETURN_STEP) {\n // Remove all deprecated addresses from the AddressManager\n string[17] memory deprecated = [\n \"OVM_CanonicalTransactionChain\",\n \"OVM_L2CrossDomainMessenger\",\n \"OVM_DecompressionPrecompileAddress\",\n \"OVM_Sequencer\",\n \"OVM_Proposer\",\n \"OVM_ChainStorageContainer-CTC-batches\",\n \"OVM_ChainStorageContainer-CTC-queue\",\n \"OVM_CanonicalTransactionChain\",\n \"OVM_StateCommitmentChain\",\n \"OVM_BondManager\",\n \"OVM_ExecutionManager\",\n \"OVM_FraudVerifier\",\n \"OVM_StateManagerFactory\",\n \"OVM_StateTransitionerFactory\",\n \"OVM_SafetyChecker\",\n \"OVM_L1MultiMessageRelayer\",\n \"BondManager\"\n ];\n\n for (uint256 i = 0; i < deprecated.length; i++) {\n config.globalConfig.addressManager.setAddress(deprecated[i], address(0));\n }\n }\n\n /**\n * @notice Transfers system ownership to the ProxyAdmin.\n */\n function step4() external onlyOwner step(PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the ProxyAdmin.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1StandardBridge to the ProxyAdmin.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the ProxyAdmin.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.proxyAdmin)\n );\n }\n\n /**\n * @notice Upgrades and initializes proxy contracts.\n */\n function step5() external onlyOwner step(5) {\n // Dynamic config must be set before we can initialize the L2OutputOracle.\n require(dynamicConfigSet, \"SystemDictator: dynamic oracle config is not yet initialized\");\n\n // Upgrade and initialize the L2OutputOracle.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l2OutputOracleProxy),\n address(config.implementationAddressConfig.l2OutputOracleImpl),\n abi.encodeCall(\n L2OutputOracle.initialize,\n (\n l2OutputOracleDynamicConfig.l2OutputOracleStartingBlockNumber,\n l2OutputOracleDynamicConfig.l2OutputOracleStartingTimestamp\n )\n )\n );\n\n // Upgrade and initialize the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.optimismPortalProxy),\n address(config.implementationAddressConfig.optimismPortalImpl),\n abi.encodeCall(OptimismPortal.initialize, (optimismPortalDynamicConfig))\n );\n\n // Upgrade the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1CrossDomainMessengerProxy),\n address(config.implementationAddressConfig.l1CrossDomainMessengerImpl)\n );\n\n // Try to initialize the L1CrossDomainMessenger, only fail if it's already been initialized.\n try\n L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy)\n .initialize()\n {\n // L1CrossDomainMessenger is the one annoying edge case difference between existing\n // networks and fresh networks because in existing networks it'll already be\n // initialized but in fresh networks it won't be. Try/catch is the easiest and most\n // consistent way to handle this because initialized() is not exposed publicly.\n } catch Error(string memory reason) {\n require(\n keccak256(abi.encodePacked(reason)) ==\n keccak256(\"Initializable: contract is already initialized\"),\n string.concat(\"SystemDictator: unexpected error initializing L1XDM: \", reason)\n );\n } catch {\n revert(\"SystemDictator: unexpected error initializing L1XDM (no reason)\");\n }\n\n // Transfer ETH from the L1StandardBridge to the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.portalSenderImpl),\n abi.encodeCall(PortalSender.donate, ())\n );\n\n // Upgrade the L1StandardBridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.l1StandardBridgeImpl)\n );\n\n // Upgrade the OptimismMintableERC20Factory (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.optimismMintableERC20FactoryProxy),\n address(config.implementationAddressConfig.optimismMintableERC20FactoryImpl)\n );\n\n // Upgrade the L1ERC721Bridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1ERC721BridgeProxy),\n address(config.implementationAddressConfig.l1ERC721BridgeImpl)\n );\n }\n\n /**\n * @notice Tranfers admin ownership to the final owner.\n */\n function finalize() external onlyOwner {\n // Transfer ownership of the ProxyAdmin to the final owner.\n config.globalConfig.proxyAdmin.transferOwnership(config.globalConfig.finalOwner);\n\n // Optionally also transfer AddressManager and L1StandardBridge if we still own it. Might\n // happen if we're exiting early.\n if (currentStep <= PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the final owner.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1StandardBridge to the final owner.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the final owner.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.finalOwner)\n );\n }\n\n // Mark the deployment as finalized.\n finalized = true;\n }\n\n /**\n * @notice First exit point, can only be called before step 3 is executed.\n */\n function exit1() external onlyOwner {\n require(\n currentStep == EXIT_1_NO_RETURN_STEP,\n \"SystemDictator: can only exit1 before step 3 is executed\"\n );\n\n // Reset the L1CrossDomainMessenger to the old implementation.\n config.globalConfig.addressManager.setAddress(\n \"OVM_L1CrossDomainMessenger\",\n oldL1CrossDomainMessenger\n );\n\n // Unset the DTL shutoff block which will allow the DTL to sync again.\n config.globalConfig.addressManager.setAddress(\"DTL_SHUTOFF_BLOCK\", address(0));\n\n // Mark the deployment as exited.\n exited = true;\n }\n}\n" - }, - "contracts/echidna/FuzzAddressAliasing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract EchidnaFuzzAddressAliasing {\n bool internal failedRoundtrip;\n\n /**\n * @notice Takes an address to be aliased with AddressAliasHelper and then unaliased\n * and updates the test contract's state indicating if the round trip encoding\n * failed.\n */\n function testRoundTrip(address addr) public {\n // Alias our address\n address aliasedAddr = AddressAliasHelper.applyL1ToL2Alias(addr);\n\n // Unalias our address\n address undoneAliasAddr = AddressAliasHelper.undoL1ToL2Alias(aliasedAddr);\n\n // If our round trip aliasing did not return the original result, set our state.\n if (addr != undoneAliasAddr) {\n failedRoundtrip = true;\n }\n }\n\n /**\n * @custom:invariant Address aliases are always able to be undone.\n *\n * Asserts that an address that has been aliased with `applyL1ToL2Alias` can always\n * be unaliased with `undoL1ToL2Alias`.\n */\n function echidna_round_trip_aliasing() public view returns (bool) {\n // ASSERTION: The round trip aliasing done in testRoundTrip(...) should never fail.\n return !failedRoundtrip;\n }\n}\n" - }, - "contracts/echidna/FuzzBurn.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\n\ncontract EchidnaFuzzBurnEth is StdUtils {\n bool internal failedEthBurn;\n\n /**\n * @notice Takes an integer amount of eth to burn through the Burn library and\n * updates the contract state if an incorrect amount of eth moved from the contract\n */\n function testBurn(uint256 _value) public {\n // cache the contract's eth balance\n uint256 preBurnBalance = address(this).balance;\n uint256 value = bound(_value, 0, preBurnBalance);\n\n // execute a burn of _value eth\n Burn.eth(value);\n\n // check that exactly value eth was transfered from the contract\n unchecked {\n if (address(this).balance != preBurnBalance - value) {\n failedEthBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `eth(uint256)` always burns the exact amount of eth passed.\n *\n * Asserts that when `Burn.eth(uint256)` is called, it always burns the exact amount\n * of ETH passed to the function.\n */\n function echidna_burn_eth() public view returns (bool) {\n // ASSERTION: The amount burned should always match the amount passed exactly\n return !failedEthBurn;\n }\n}\n\ncontract EchidnaFuzzBurnGas is StdUtils {\n bool internal failedGasBurn;\n\n /**\n * @notice Takes an integer amount of gas to burn through the Burn library and\n * updates the contract state if at least that amount of gas was not burned\n * by the library\n */\n function testGas(uint256 _value) public {\n // cap the value to the max resource limit\n uint256 MAX_RESOURCE_LIMIT = 8_000_000;\n uint256 value = bound(_value, 0, MAX_RESOURCE_LIMIT);\n\n // cache the contract's current remaining gas\n uint256 preBurnGas = gasleft();\n\n // execute the gas burn\n Burn.gas(value);\n\n // cache the remaining gas post burn\n uint256 postBurnGas = gasleft();\n\n // check that at least value gas was burnt (and that there was no underflow)\n unchecked {\n if (postBurnGas - preBurnGas > value || preBurnGas - value > preBurnGas) {\n failedGasBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `gas(uint256)` always burns at least the amount of gas passed.\n *\n * Asserts that when `Burn.gas(uint256)` is called, it always burns at least the amount\n * of gas passed to the function.\n */\n function echidna_burn_gas() public view returns (bool) {\n // ASSERTION: The amount of gas burned should be strictly greater than the\n // the amount passed as _value (minimum _value + whatever minor overhead to\n // the value after the call)\n return !failedGasBurn;\n }\n}\n" - }, - "contracts/echidna/FuzzEncoding.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzEncoding {\n bool internal failedRoundtripAToB;\n bool internal failedRoundtripBToA;\n\n /**\n * @notice Takes a pair of integers to be encoded into a versioned nonce with the\n * Encoding library and then decoded and updates the test contract's state\n * indicating if the round trip encoding failed.\n */\n function testRoundTripAToB(uint240 _nonce, uint16 _version) public {\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(encodedVersionedNonce);\n\n // If our round trip encoding did not return the original result, set our state.\n if ((decodedNonce != _nonce) || (decodedVersion != _version)) {\n failedRoundtripAToB = true;\n }\n }\n\n /**\n * @notice Takes an integer representing a packed version and nonce and attempts\n * to decode them using the Encoding library before re-encoding and updates\n * the test contract's state indicating if the round trip encoding failed.\n */\n function testRoundTripBToA(uint256 _versionedNonce) public {\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(_versionedNonce);\n\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(decodedNonce, decodedVersion);\n\n // If our round trip encoding did not return the original result, set our state.\n if (encodedVersionedNonce != _versionedNonce) {\n failedRoundtripBToA = true;\n }\n }\n\n /**\n * @custom:invariant `testRoundTripAToB` never fails.\n *\n * Asserts that a raw versioned nonce can be encoded / decoded to reach the same raw value.\n */\n function echidna_round_trip_encoding_AToB() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripAToB(...)\n return !failedRoundtripAToB;\n }\n\n /**\n * @custom:invariant `testRoundTripBToA` never fails.\n *\n * Asserts that an encoded versioned nonce can always be decoded / re-encoded to reach\n * the same encoded value.\n */\n function echidna_round_trip_encoding_BToA() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripBToA should never\n // fail.\n return !failedRoundtripBToA;\n }\n}\n" - }, - "contracts/echidna/FuzzHashing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzHashing {\n bool internal failedCrossDomainHashHighVersion;\n bool internal failedCrossDomainHashV0;\n bool internal failedCrossDomainHashV1;\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash with a randomly\n * generated version. Only schema versions 0 and 1 are supported and all others should revert.\n */\n function testHashCrossDomainMessageHighVersion(\n uint16 _version,\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // hash the cross domain message. we don't need to store the result since the function\n // validates and should revert if an invalid version (>1) is encoded\n Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);\n\n // check that execution never makes it this far for an invalid version\n if (_version > 1) {\n failedCrossDomainHashHighVersion = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v0 schema\n * and compares the output of a call to the unversioned function to the v0 function directly\n */\n function testHashCrossDomainMessageV0(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 0\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 0);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n encodedNonce\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV0 = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v1 schema\n * and compares the output of a call to the unversioned function to the v1 function directly\n */\n function testHashCrossDomainMessageV1(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 1\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 1);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV1 = true;\n }\n }\n\n /**\n * @custom:invariant `hashCrossDomainMessage` reverts if `version` is > `1`.\n *\n * The `hashCrossDomainMessage` function should always revert if the `version` passed is > `1`.\n */\n function echidna_hash_xdomain_msg_high_version() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage will never succeed for a version > 1\n return !failedCrossDomainHashHighVersion;\n }\n\n /**\n * @custom:invariant `version` = `0`: `hashCrossDomainMessage` and `hashCrossDomainMessageV0`\n * are equivalent.\n *\n * If the version passed is 0, `hashCrossDomainMessage` and `hashCrossDomainMessageV0` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_0() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV0\n // should always match when the version passed is 0\n return !failedCrossDomainHashV0;\n }\n\n /**\n * @custom:invariant `version` = `1`: `hashCrossDomainMessage` and `hashCrossDomainMessageV1`\n * are equivalent.\n *\n * If the version passed is 1, `hashCrossDomainMessage` and `hashCrossDomainMessageV1` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_1() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV1\n // should always match when the version passed is 1\n return !failedCrossDomainHashV1;\n }\n}\n" - }, - "contracts/echidna/FuzzOptimismPortal.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzOptimismPortal {\n OptimismPortal internal portal;\n bool internal failedToComplete;\n\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n SystemConfig systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: rcfg\n });\n\n portal = new OptimismPortal({\n _l2Oracle: L2OutputOracle(address(0)),\n _guardian: address(0),\n _paused: false,\n _config: systemConfig\n });\n }\n\n // A test intended to identify any unexpected halting conditions\n function testDepositTransactionCompletes(\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable {\n failedToComplete = true;\n require(!_isCreation || _to == address(0), \"EchidnaFuzzOptimismPortal: invalid test case.\");\n portal.depositTransaction{ value: _mint }(_to, _value, _gasLimit, _isCreation, _data);\n failedToComplete = false;\n }\n\n /**\n * @custom:invariant Deposits of any value should always succeed unless\n * `_to` = `address(0)` or `_isCreation` = `true`.\n *\n * All deposits, barring creation transactions and transactions sent to `address(0)`,\n * should always succeed.\n */\n function echidna_deposit_completes() public view returns (bool) {\n return !failedToComplete;\n }\n}\n" - }, - "contracts/echidna/FuzzResourceMetering.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzResourceMetering is ResourceMetering, StdUtils {\n bool internal failedMaxGasPerBlock;\n bool internal failedRaiseBaseFee;\n bool internal failedLowerBaseFee;\n bool internal failedNeverBelowMinBaseFee;\n bool internal failedMaxRaiseBaseFeePerBlock;\n bool internal failedMaxLowerBaseFeePerBlock;\n\n // Used as a special flag for the purpose of identifying unchecked math errors specifically\n // in the test contracts, not the target contracts themselves.\n bool internal underflow;\n\n constructor() {\n initialize();\n }\n\n function initialize() internal initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public pure returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n return rcfg;\n }\n\n /**\n * @notice Takes the necessary parameters to allow us to burn arbitrary amounts of gas to test\n * the underlying resource metering/gas market logic\n */\n function testBurn(uint256 _gasToBurn, bool _raiseBaseFee) public {\n // Part 1: we cache the current param values and do some basic checks on them.\n uint256 cachedPrevBaseFee = uint256(params.prevBaseFee);\n uint256 cachedPrevBoughtGas = uint256(params.prevBoughtGas);\n uint256 cachedPrevBlockNum = uint256(params.prevBlockNum);\n\n ResourceMetering.ResourceConfig memory rcfg = resourceConfig();\n uint256 targetResourceLimit = uint256(rcfg.maxResourceLimit) /\n uint256(rcfg.elasticityMultiplier);\n\n // check that the last block's base fee hasn't dropped below the minimum\n if (cachedPrevBaseFee < uint256(rcfg.minimumBaseFee)) {\n failedNeverBelowMinBaseFee = true;\n }\n // check that the last block didn't consume more than the max amount of gas\n if (cachedPrevBoughtGas > uint256(rcfg.maxResourceLimit)) {\n failedMaxGasPerBlock = true;\n }\n\n // Part2: we perform the gas burn\n\n // force the gasToBurn into the correct range based on whether we intend to\n // raise or lower the baseFee after this block, respectively\n uint256 gasToBurn;\n if (_raiseBaseFee) {\n gasToBurn = bound(\n _gasToBurn,\n uint256(targetResourceLimit),\n uint256(rcfg.maxResourceLimit)\n );\n } else {\n gasToBurn = bound(_gasToBurn, 0, targetResourceLimit);\n }\n\n _burnInternal(uint64(gasToBurn));\n\n // Part 3: we run checks and modify our invariant flags based on the updated params values\n\n // Calculate the maximum allowed baseFee change (per block)\n uint256 maxBaseFeeChange = cachedPrevBaseFee / uint256(rcfg.baseFeeMaxChangeDenominator);\n\n // If the last block used more than the target amount of gas (and there were no\n // empty blocks in between), ensure this block's baseFee increased, but not by\n // more than the max amount per block\n if (\n (cachedPrevBoughtGas > uint256(targetResourceLimit)) &&\n (uint256(params.prevBlockNum) - cachedPrevBlockNum == 1)\n ) {\n failedRaiseBaseFee = failedRaiseBaseFee || (params.prevBaseFee <= cachedPrevBaseFee);\n failedMaxRaiseBaseFeePerBlock =\n failedMaxRaiseBaseFeePerBlock ||\n ((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);\n }\n\n // If the last block used less than the target amount of gas, (or was empty),\n // ensure that: this block's baseFee was decreased, but not by more than the max amount\n if (\n (cachedPrevBoughtGas < uint256(targetResourceLimit)) ||\n (uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)\n ) {\n // Invariant: baseFee should decrease\n failedLowerBaseFee =\n failedLowerBaseFee ||\n (uint256(params.prevBaseFee) > cachedPrevBaseFee);\n\n if (params.prevBlockNum - cachedPrevBlockNum == 1) {\n // No empty blocks\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n } else if (params.prevBlockNum - cachedPrevBlockNum > 1) {\n // We have at least one empty block\n // Update the maxBaseFeeChange to account for multiple blocks having passed\n unchecked {\n maxBaseFeeChange = uint256(\n int256(cachedPrevBaseFee) -\n Arithmetic.clamp(\n Arithmetic.cdexp(\n int256(cachedPrevBaseFee),\n int256(uint256(rcfg.baseFeeMaxChangeDenominator)),\n int256(uint256(params.prevBlockNum) - cachedPrevBlockNum)\n ),\n int256(uint256(rcfg.minimumBaseFee)),\n int256(uint256(rcfg.maximumBaseFee))\n )\n );\n }\n\n // Detect an underflow in the previous calculation.\n // Without using unchecked above, and detecting the underflow here, echidna would\n // otherwise ignore the revert.\n underflow = underflow || maxBaseFeeChange > cachedPrevBaseFee;\n\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n }\n }\n }\n\n function _burnInternal(uint64 _gasToBurn) private metered(_gasToBurn) {}\n\n /**\n * @custom:invariant The base fee should increase if the last block used more\n * than the target amount of gas\n *\n * If the last block used more than the target amount of gas (and there were no\n * empty blocks in between), ensure this block's baseFee increased, but not by\n * more than the max amount per block.\n */\n function echidna_high_usage_raise_baseFee() public view returns (bool) {\n return !failedRaiseBaseFee;\n }\n\n /**\n * @custom:invariant The base fee should decrease if the last block used less\n * than the target amount of gas\n *\n * If the previous block used less than the target amount of gas, the base fee should decrease,\n * but not more than the max amount.\n */\n function echidna_low_usage_lower_baseFee() public view returns (bool) {\n return !failedLowerBaseFee;\n }\n\n /**\n * @custom:invariant A block's base fee should never be below `MINIMUM_BASE_FEE`\n *\n * This test asserts that a block's base fee can never drop below the\n * `MINIMUM_BASE_FEE` threshold.\n */\n function echidna_never_below_min_baseFee() public view returns (bool) {\n return !failedNeverBelowMinBaseFee;\n }\n\n /**\n * @custom:invariant A block can never consume more than `MAX_RESOURCE_LIMIT` gas.\n *\n * This test asserts that a block can never consume more than the `MAX_RESOURCE_LIMIT`\n * gas threshold.\n */\n function echidna_never_above_max_gas_limit() public view returns (bool) {\n return !failedMaxGasPerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be raised more than the max base fee change.\n *\n * After a block consumes more gas than the target gas, the base fee cannot be raised\n * more than the maximum amount allowed. The max base fee change (per-block) is derived\n * as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_increase() public view returns (bool) {\n return !failedMaxRaiseBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be lowered more than the max base fee change.\n *\n * After a block consumes less than the target gas, the base fee cannot be lowered more\n * than the maximum amount allowed. The max base fee change (per-block) is derived as\n *follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_decrease() public view returns (bool) {\n return !failedMaxLowerBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The `maxBaseFeeChange` calculation over multiple blocks can never\n * underflow.\n *\n * When calculating the `maxBaseFeeChange` after multiple empty blocks, the calculation\n * should never be allowed to underflow.\n */\n function echidna_underflow() public view returns (bool) {\n return !underflow;\n }\n}\n" - }, - "contracts/governance/GovernanceToken.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:predeploy 0x4200000000000000000000000000000000000042\n * @title GovernanceToken\n * @notice The Optimism token used in governance and supporting voting and delegation. Implements\n * EIP 2612 allowing signed approvals. Contract is \"owned\" by a `MintManager` instance with\n * permission to the `mint` function only, for the purposes of enforcing the token inflation\n * schedule.\n */\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\n constructor() ERC20(\"Optimism\", \"OP\") ERC20Permit(\"Optimism\") {}\n\n /**\n * @notice Allows the owner to mint tokens.\n *\n * @param _account The account receiving minted tokens.\n * @param _amount The amount of tokens to mint.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n /**\n * @notice Callback called after a token transfer.\n *\n * @param from The account sending tokens.\n * @param to The account receiving tokens.\n * @param amount The amount of tokens being transfered.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20, ERC20Votes) {\n super._afterTokenTransfer(from, to, amount);\n }\n\n /**\n * @notice Internal mint function.\n *\n * @param to The account receiving minted tokens.\n * @param amount The amount of tokens to mint.\n */\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._mint(to, amount);\n }\n\n /**\n * @notice Internal burn function.\n *\n * @param account The account that tokens will be burned from.\n * @param amount The amount of tokens that will be burned.\n */\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._burn(account, amount);\n }\n}\n" - }, - "contracts/governance/MintManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./GovernanceToken.sol\";\n\n/**\n * @title MintManager\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\n * Contract acts as the token \"mint manager\" with permission to the `mint` function only.\n * Currently permitted to mint once per year of up to 2% of the total token supply.\n * Upgradable to allow changes in the inflation schedule.\n */\ncontract MintManager is Ownable {\n /**\n * @notice The GovernanceToken that the MintManager can mint tokens\n */\n GovernanceToken public immutable governanceToken;\n\n /**\n * @notice The amount of tokens that can be minted per year. The value is a fixed\n * point number with 4 decimals.\n */\n uint256 public constant MINT_CAP = 20; // 2%\n\n /**\n * @notice The number of decimals for the MINT_CAP.\n */\n uint256 public constant DENOMINATOR = 1000;\n\n /**\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\n * be minted again.\n */\n uint256 public constant MINT_PERIOD = 365 days;\n\n /**\n * @notice Tracks the time of last mint.\n */\n uint256 public mintPermittedAfter;\n\n /**\n * @param _upgrader The owner of this contract\n * @param _governanceToken The governance token this contract can mint\n * tokens of\n */\n constructor(address _upgrader, address _governanceToken) {\n transferOwnership(_upgrader);\n governanceToken = GovernanceToken(_governanceToken);\n }\n\n /**\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\n *\n * @param _account Address to mint new tokens to.\n * @param _amount Amount of tokens to be minted.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n if (mintPermittedAfter > 0) {\n require(\n mintPermittedAfter <= block.timestamp,\n \"MintManager: minting not permitted yet\"\n );\n\n require(\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\n \"MintManager: mint amount exceeds cap\"\n );\n }\n\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\n governanceToken.mint(_account, _amount);\n }\n\n /**\n * @notice Upgrade the owner of the governance token to a new MintManager.\n *\n * @param _newMintManager The MintManager to upgrade to.\n */\n function upgrade(address _newMintManager) public onlyOwner {\n require(\n _newMintManager != address(0),\n \"MintManager: mint manager cannot be the zero address\"\n );\n\n governanceToken.transferOwnership(_newMintManager);\n }\n}\n" - }, - "contracts/legacy/AddressManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:legacy\n * @title AddressManager\n * @notice AddressManager is a legacy contract that was used in the old version of the Optimism\n * system to manage a registry of string names to addresses. We now use a more standard\n * proxy system instead, but this contract is still necessary for backwards compatibility\n * with several older contracts.\n */\ncontract AddressManager is Ownable {\n /**\n * @notice Mapping of the hashes of string names to addresses.\n */\n mapping(bytes32 => address) private addresses;\n\n /**\n * @notice Emitted when an address is modified in the registry.\n *\n * @param name String name being set in the registry.\n * @param newAddress Address set for the given name.\n * @param oldAddress Address that was previously set for the given name.\n */\n event AddressSet(string indexed name, address newAddress, address oldAddress);\n\n /**\n * @notice Changes the address associated with a particular name.\n *\n * @param _name String name to associate an address with.\n * @param _address Address to associate with the name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n bytes32 nameHash = _getNameHash(_name);\n address oldAddress = addresses[nameHash];\n addresses[nameHash] = _address;\n\n emit AddressSet(_name, _address, oldAddress);\n }\n\n /**\n * @notice Retrieves the address associated with a given name.\n *\n * @param _name Name to retrieve an address for.\n *\n * @return Address associated with the given name.\n */\n function getAddress(string memory _name) external view returns (address) {\n return addresses[_getNameHash(_name)];\n }\n\n /**\n * @notice Computes the hash of a name.\n *\n * @param _name Name to compute a hash for.\n *\n * @return Hash of the given name.\n */\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(_name));\n }\n}\n" - }, - "contracts/legacy/DeployerWhitelist.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000002\n * @title DeployerWhitelist\n * @notice DeployerWhitelist is a legacy contract that was originally used to act as a whitelist of\n * addresses allowed to the Optimism network. The DeployerWhitelist has since been\n * disabled, but the code is kept in state for the sake of full backwards compatibility.\n * As of the Bedrock upgrade, the DeployerWhitelist is completely unused by the Optimism\n * system and could, in theory, be removed entirely.\n */\ncontract DeployerWhitelist is Semver {\n /**\n * @notice Address of the owner of this contract. Note that when this address is set to\n * address(0), the whitelist is disabled.\n */\n address public owner;\n\n /**\n * @notice Mapping of deployer addresses to boolean whitelist status.\n */\n mapping(address => bool) public whitelist;\n\n /**\n * @notice Emitted when the owner of this contract changes.\n *\n * @param oldOwner Address of the previous owner.\n * @param newOwner Address of the new owner.\n */\n event OwnerChanged(address oldOwner, address newOwner);\n\n /**\n * @notice Emitted when the whitelist status of a deployer changes.\n *\n * @param deployer Address of the deployer.\n * @param whitelisted Boolean indicating whether the deployer is whitelisted.\n */\n event WhitelistStatusChanged(address deployer, bool whitelisted);\n\n /**\n * @notice Emitted when the whitelist is disabled.\n *\n * @param oldOwner Address of the final owner of the whitelist.\n */\n event WhitelistDisabled(address oldOwner);\n\n /**\n * @notice Blocks functions to anyone except the contract owner.\n */\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"DeployerWhitelist: function can only be called by the owner of this contract\"\n );\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Adds or removes an address from the deployment whitelist.\n *\n * @param _deployer Address to update permissions for.\n * @param _isWhitelisted Whether or not the address is whitelisted.\n */\n function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external onlyOwner {\n whitelist[_deployer] = _isWhitelisted;\n emit WhitelistStatusChanged(_deployer, _isWhitelisted);\n }\n\n /**\n * @notice Updates the owner of this contract.\n *\n * @param _owner Address of the new owner.\n */\n function setOwner(address _owner) external onlyOwner {\n // Prevent users from setting the whitelist owner to address(0) except via\n // enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to\n // any other address that doesn't have a corresponding knowable private key.\n require(\n _owner != address(0),\n \"DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment\"\n );\n\n emit OwnerChanged(owner, _owner);\n owner = _owner;\n }\n\n /**\n * @notice Permanently enables arbitrary contract deployment and deletes the owner.\n */\n function enableArbitraryContractDeployment() external onlyOwner {\n emit WhitelistDisabled(owner);\n owner = address(0);\n }\n\n /**\n * @notice Checks whether an address is allowed to deploy contracts.\n *\n * @param _deployer Address to check.\n *\n * @return Whether or not the address can deploy contracts.\n */\n function isDeployerAllowed(address _deployer) external view returns (bool) {\n return (owner == address(0) || whitelist[_deployer]);\n }\n}\n" - }, - "contracts/legacy/L1BlockNumber.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000013\n * @title L1BlockNumber\n * @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract\n * in the old version of the Optimism system. Only necessary for backwards compatibility.\n * If you want to access the L1 block number going forward, you should use the L1Block\n * contract instead.\n */\ncontract L1BlockNumber is Semver {\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Returns the L1 block number.\n */\n receive() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Returns the L1 block number.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Retrieves the latest L1 block number.\n *\n * @return Latest L1 block number.\n */\n function getL1BlockNumber() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).number();\n }\n}\n" - }, - "contracts/legacy/L1ChugSplashProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title IL1ChugSplashDeployer\n */\ninterface IL1ChugSplashDeployer {\n function isUpgrading() external view returns (bool);\n}\n\n/**\n * @custom:legacy\n * @title L1ChugSplashProxy\n * @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\n * functions `setCode` and `setStorage` for changing the code or storage of the contract.\n *\n * Note for future developers: do NOT make anything in this contract 'public' unless you\n * know what you're doing. Anything public can potentially have a function signature that\n * conflicts with a signature attached to the implementation contract. Public functions\n * SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good\n * reason not to have that modifier. And there almost certainly is not a good reason to not\n * have that modifier. Beware!\n */\ncontract L1ChugSplashProxy {\n /**\n * @notice \"Magic\" prefix. When prepended to some arbitrary bytecode and used to create a\n * contract, the appended bytecode will be deployed as given.\n */\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice Blocks a function from being called when the parent signals that the system should\n * be paused via an isUpgrading function.\n */\n modifier onlyWhenNotPaused() {\n address owner = _getOwner();\n\n // We do a low-level call because there's no guarantee that the owner actually *is* an\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\n // it turns out that it isn't the right type of contract.\n (bool success, bytes memory returndata) = owner.staticcall(\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)\n );\n\n // If the call was unsuccessful then we assume that there's no \"isUpgrading\" method and we\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\n // long. If this isn't the case then we can safely ignore the result.\n if (success && returndata.length == 32) {\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\n // case that the isUpgrading function returned something other than 0 or 1. But we only\n // really care about the case where this value is 0 (= false).\n uint256 ret = abi.decode(returndata, (uint256));\n require(ret == 0, \"L1ChugSplashProxy: system is currently being upgraded\");\n }\n\n _;\n }\n\n /**\n * @notice Makes a proxy call instead of triggering the given function when the caller is\n * either the owner or the zero address. Caller can only ever be the zero address if\n * this function is being called off-chain via eth_call, which is totally fine and can\n * be convenient for client-side tooling. Avoids situations where the proxy and\n * implementation share a sighash and the proxy function ends up being called instead\n * of the implementation one.\n *\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If\n * there's a way for someone to send a transaction with msg.sender == address(0) in any\n * real context then we have much bigger problems. Primary reason to include this\n * additional allowed sender is because the owner address can be changed dynamically\n * and we do not want clients to have to keep track of the current owner in order to\n * make an eth_call that doesn't trigger the proxied contract.\n */\n // slither-disable-next-line incorrect-modifier\n modifier proxyCallIfNotOwner() {\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @param _owner Address of the initial contract owner.\n */\n constructor(address _owner) {\n _setOwner(_owner);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Sets the code that should be running behind this proxy.\n *\n * Note: This scheme is a bit different from the standard proxy scheme where one would\n * typically deploy the code separately and then set the implementation address. We're\n * doing it this way because it gives us a lot more freedom on the client side. Can\n * only be triggered by the contract owner.\n *\n * @param _code New contract code to run inside this contract.\n */\n function setCode(bytes memory _code) external proxyCallIfNotOwner {\n // Get the code hash of the current implementation.\n address implementation = _getImplementation();\n\n // If the code hash matches the new implementation then we return early.\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\n return;\n }\n\n // Create the deploycode by appending the magic prefix.\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\n\n // Deploy the code and set the new implementation address.\n address newImplementation;\n assembly {\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\n }\n\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\n // actually fail this check. Should only happen if the contract creation from above runs\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\n // should be doing this check anyway though.\n require(\n _getAccountCodeHash(newImplementation) == keccak256(_code),\n \"L1ChugSplashProxy: code was not correctly deployed\"\n );\n\n _setImplementation(newImplementation);\n }\n\n /**\n * @notice Modifies some storage slot within the proxy contract. Gives us a lot of power to\n * perform upgrades in a more transparent way. Only callable by the owner.\n *\n * @param _key Storage key to modify.\n * @param _value New value for the storage key.\n */\n function setStorage(bytes32 _key, bytes32 _value) external proxyCallIfNotOwner {\n assembly {\n sstore(_key, _value)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _owner New owner of the proxy contract.\n */\n function setOwner(address _owner) external proxyCallIfNotOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Queries the owner of the proxy contract. Can only be called by the owner OR by\n * making an eth_call and setting the \"from\" address to address(0).\n *\n * @return Owner address.\n */\n function getOwner() external proxyCallIfNotOwner returns (address) {\n return _getOwner();\n }\n\n /**\n * @notice Queries the implementation address. Can only be called by the owner OR by making an\n * eth_call and setting the \"from\" address to address(0).\n *\n * @return Implementation address.\n */\n function getImplementation() external proxyCallIfNotOwner returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _owner New owner of the proxy contract.\n */\n function _setOwner(address _owner) internal {\n assembly {\n sstore(OWNER_KEY, _owner)\n }\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal onlyWhenNotPaused {\n address implementation = _getImplementation();\n\n require(implementation != address(0), \"L1ChugSplashProxy: implementation is not set yet\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address implementation;\n assembly {\n implementation := sload(IMPLEMENTATION_KEY)\n }\n return implementation;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getOwner() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n\n /**\n * @notice Gets the code hash for a given account.\n *\n * @param _account Address of the account to get a code hash for.\n *\n * @return Code hash for the account.\n */\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\n bytes32 codeHash;\n assembly {\n codeHash := extcodehash(_account)\n }\n return codeHash;\n }\n}\n" - }, - "contracts/legacy/LegacyERC20ETH.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000\n * @title LegacyERC20ETH\n * @notice LegacyERC20ETH is a legacy contract that held ETH balances before the Bedrock upgrade.\n * All ETH balances held within this contract were migrated to the state trie as part of\n * the Bedrock upgrade. Functions within this contract that mutate state were already\n * disabled as part of the EVM equivalence upgrade.\n */\ncontract LegacyERC20ETH is OptimismMintableERC20 {\n /**\n * @notice Initializes the contract as an Optimism Mintable ERC20.\n */\n constructor()\n OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), \"Ether\", \"ETH\")\n {}\n\n /**\n * @notice Returns the ETH balance of the target account. Overrides the base behavior of the\n * contract to preserve the invariant that the balance within this contract always\n * matches the balance in the state trie.\n *\n * @param _who Address of the account to query.\n *\n * @return The ETH balance of the target account.\n */\n function balanceOf(address _who) public view virtual override returns (uint256) {\n return address(_who).balance;\n }\n\n /**\n * @custom:blocked\n * @notice Mints some amount of ETH.\n */\n function mint(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: mint is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Burns some amount of ETH.\n */\n function burn(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: burn is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers some amount of ETH.\n */\n function transfer(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transfer is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Approves a spender to spend some amount of ETH.\n */\n function approve(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: approve is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers funds from some sender account.\n */\n function transferFrom(\n address,\n address,\n uint256\n ) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transferFrom is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Increases the allowance of a spender.\n */\n function increaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Decreases the allowance of a spender.\n */\n function decreaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n }\n}\n" - }, - "contracts/legacy/LegacyMessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000000\n * @title LegacyMessagePasser\n * @notice The LegacyMessagePasser was the low-level mechanism used to send messages from L2 to L1\n * before the Bedrock upgrade. It is now deprecated in favor of the new MessagePasser.\n */\ncontract LegacyMessagePasser is Semver {\n /**\n * @notice Mapping of sent message hashes to boolean status.\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Passes a message to L1.\n *\n * @param _message Message to pass to L1.\n */\n function passMessageToL1(bytes memory _message) external {\n sentMessages[keccak256(abi.encodePacked(_message, msg.sender))] = true;\n }\n}\n" - }, - "contracts/legacy/LegacyMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ILegacyMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @title LegacyMintableERC20\n * @notice The legacy implementation of the OptimismMintableERC20. This\n * contract is deprecated and should no longer be used.\n */\ncontract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {\n /**\n * @notice Emitted when the token is minted by the bridge.\n */\n event Mint(address indexed _account, uint256 _amount);\n\n /**\n * @notice Emitted when a token is burned by the bridge.\n */\n event Burn(address indexed _account, uint256 _amount);\n\n /**\n * @notice The token on the remote domain.\n */\n address public l1Token;\n\n /**\n * @notice The local bridge.\n */\n address public l2Bridge;\n\n /**\n * @param _l2Bridge Address of the L2 standard bridge.\n * @param _l1Token Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _l2Bridge,\n address _l1Token,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) {\n l1Token = _l1Token;\n l2Bridge = _l2Bridge;\n }\n\n /**\n * @notice Modifier that requires the contract was called by the bridge.\n */\n modifier onlyL2Bridge() {\n require(msg.sender == l2Bridge, \"Only L2 Bridge can mint and burn\");\n _;\n }\n\n /**\n * @notice EIP165 implementation.\n */\n function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n\n /**\n * @notice Only the bridge can mint tokens.\n * @param _to The account receiving tokens.\n * @param _amount The amount of tokens to receive.\n */\n function mint(address _to, uint256 _amount) public virtual onlyL2Bridge {\n _mint(_to, _amount);\n\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Only the bridge can burn tokens.\n * @param _from The account having tokens burnt.\n * @param _amount The amount of tokens being burnt.\n */\n function burn(address _from, uint256 _amount) public virtual onlyL2Bridge {\n _burn(_from, _amount);\n\n emit Burn(_from, _amount);\n }\n}\n" - }, - "contracts/legacy/ResolvedDelegateProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressManager } from \"./AddressManager.sol\";\n\n/**\n * @custom:legacy\n * @title ResolvedDelegateProxy\n * @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to\n * resolve the implementation address. We're maintaining this contract for backwards\n * compatibility so we can manage all legacy proxies where necessary.\n */\ncontract ResolvedDelegateProxy {\n /**\n * @notice Mapping used to store the implementation name that corresponds to this contract. A\n * mapping was originally used as a way to bypass the same issue normally solved by\n * storing the implementation address in a specific storage slot that does not conflict\n * with any other storage slot. Generally NOT a safe solution but works as long as the\n * implementation does not also keep a mapping in the first storage slot.\n */\n mapping(address => string) private implementationName;\n\n /**\n * @notice Mapping used to store the address of the AddressManager contract where the\n * implementation address will be resolved from. Same concept here as with the above\n * mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping\n * in the second storage slot.\n */\n mapping(address => AddressManager) private addressManager;\n\n /**\n * @param _addressManager Address of the AddressManager.\n * @param _implementationName implementationName of the contract to proxy to.\n */\n constructor(AddressManager _addressManager, string memory _implementationName) {\n addressManager[address(this)] = _addressManager;\n implementationName[address(this)] = _implementationName;\n }\n\n /**\n * @notice Fallback, performs a delegatecall to the resolved implementation address.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n address target = addressManager[address(this)].getAddress(\n (implementationName[address(this)])\n );\n\n require(target != address(0), \"ResolvedDelegateProxy: target address must be initialized\");\n\n // slither-disable-next-line controlled-delegatecall\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\n\n if (success == true) {\n assembly {\n return(add(returndata, 0x20), mload(returndata))\n }\n } else {\n assembly {\n revert(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n" - }, - "contracts/libraries/Arithmetic.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { SignedMath } from \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport { FixedPointMathLib } from \"@rari-capital/solmate/src/utils/FixedPointMathLib.sol\";\n\n/**\n * @title Arithmetic\n * @notice Even more math than before.\n */\nlibrary Arithmetic {\n /**\n * @notice Clamps a value between a minimum and maximum.\n *\n * @param _value The value to clamp.\n * @param _min The minimum value.\n * @param _max The maximum value.\n *\n * @return The clamped value.\n */\n function clamp(\n int256 _value,\n int256 _min,\n int256 _max\n ) internal pure returns (int256) {\n return SignedMath.min(SignedMath.max(_value, _min), _max);\n }\n\n /**\n * @notice (c)oefficient (d)enominator (exp)onentiation function.\n * Returns the result of: c * (1 - 1/d)^exp.\n *\n * @param _coefficient Coefficient of the function.\n * @param _denominator Fractional denominator.\n * @param _exponent Power function exponent.\n *\n * @return Result of c * (1 - 1/d)^exp.\n */\n function cdexp(\n int256 _coefficient,\n int256 _denominator,\n int256 _exponent\n ) internal pure returns (int256) {\n return\n (_coefficient *\n (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;\n }\n}\n" - }, - "contracts/libraries/Burn.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Burn\n * @notice Utilities for burning stuff.\n */\nlibrary Burn {\n /**\n * Burns a given amount of ETH.\n *\n * @param _amount Amount of ETH to burn.\n */\n function eth(uint256 _amount) internal {\n new Burner{ value: _amount }();\n }\n\n /**\n * Burns a given amount of gas.\n *\n * @param _amount Amount of gas to burn.\n */\n function gas(uint256 _amount) internal view {\n uint256 i = 0;\n uint256 initialGas = gasleft();\n while (initialGas - gasleft() < _amount) {\n ++i;\n }\n }\n}\n\n/**\n * @title Burner\n * @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to\n * the contract from the circulating supply. Self-destructing is the only way to remove ETH\n * from the circulating supply.\n */\ncontract Burner {\n constructor() payable {\n selfdestruct(payable(address(this)));\n }\n}\n" - }, - "contracts/libraries/Bytes.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Bytes\n * @notice Bytes is a library for manipulating byte arrays.\n */\nlibrary Bytes {\n /**\n * @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\n * @notice Slices a byte array with a given starting index and length. Returns a new byte array\n * as opposed to a pointer to the original array. Will throw if trying to slice more\n * bytes than exist in the array.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n * @param _length Length of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n ) internal pure returns (bytes memory) {\n unchecked {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_start + _length >= _start, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n }\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n /**\n * @notice Slices a byte array with a given starting index up to the end of the original byte\n * array. Returns a new array rathern than a pointer to the original.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\n if (_start >= _bytes.length) {\n return bytes(\"\");\n }\n return slice(_bytes, _start, _bytes.length - _start);\n }\n\n /**\n * @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.\n * Resulting nibble array will be exactly twice as long as the input byte array.\n *\n * @param _bytes Input byte array to convert.\n *\n * @return Resulting nibble array.\n */\n function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n uint256 bytesLength = _bytes.length;\n bytes memory nibbles = new bytes(bytesLength * 2);\n bytes1 b;\n\n for (uint256 i = 0; i < bytesLength; ) {\n b = _bytes[i];\n nibbles[i * 2] = b >> 4;\n nibbles[i * 2 + 1] = b & 0x0f;\n unchecked {\n ++i;\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Compares two byte arrays by comparing their keccak256 hashes.\n *\n * @param _bytes First byte array to compare.\n * @param _other Second byte array to compare.\n *\n * @return True if the two byte arrays are equal, false otherwise.\n */\n function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n return keccak256(_bytes) == keccak256(_other);\n }\n}\n" - }, - "contracts/libraries/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n/**\n * @title Constants\n * @notice Constants is a library for storing constants. Simple! Don't put everything in here, just\n * the stuff used in multiple contracts. Constants that only apply to a single contract\n * should be defined in that contract instead.\n */\nlibrary Constants {\n /**\n * @notice Special address to be used as the tx origin for gas estimation calls in the\n * OptimismPortal and CrossDomainMessenger calls. You only need to use this address if\n * the minimum gas limit specified by the user is not actually enough to execute the\n * given message and you're attempting to estimate the actual necessary gas limit. We\n * use address(1) because it's the ecrecover precompile and therefore guaranteed to\n * never have any code on any EVM chain.\n */\n address internal constant ESTIMATION_ADDRESS = address(1);\n\n /**\n * @notice Value used for the L2 sender storage slot in both the OptimismPortal and the\n * CrossDomainMessenger contracts before an actual sender is set. This value is\n * non-zero to reduce the gas cost of message passing transactions.\n */\n address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;\n\n /**\n * @notice Returns the default values for the ResourceConfig. These are the recommended values\n * for a production network.\n */\n function DEFAULT_RESOURCE_CONFIG()\n internal\n pure\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n return config;\n }\n}\n" - }, - "contracts/libraries/Encoding.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Hashing } from \"./Hashing.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\n\n/**\n * @title Encoding\n * @notice Encoding handles Optimism's various different encoding schemes.\n */\nlibrary Encoding {\n /**\n * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\n * to the L2 system. Useful for searching for a deposit in the L2 system. The\n * transaction is prefixed with 0x7e to identify its EIP-2718 type.\n *\n * @param _tx User deposit transaction to encode.\n *\n * @return RLP encoded L2 deposit transaction.\n */\n function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes memory)\n {\n bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\n bytes[] memory raw = new bytes[](8);\n raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\n raw[1] = RLPWriter.writeAddress(_tx.from);\n raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\"\") : RLPWriter.writeAddress(_tx.to);\n raw[3] = RLPWriter.writeUint(_tx.mint);\n raw[4] = RLPWriter.writeUint(_tx.value);\n raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\n raw[6] = RLPWriter.writeBool(false);\n raw[7] = RLPWriter.writeBytes(_tx.data);\n return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\n }\n\n /**\n * @notice Encodes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n (, uint16 version) = decodeVersionedNonce(_nonce);\n if (version == 0) {\n return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Encoding: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Encodes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _data,\n _nonce\n );\n }\n\n /**\n * @notice Encodes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(uint256,address,address,uint256,uint256,bytes)\",\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n }\n\n /**\n * @notice Adds a version number into the first two bytes of a message nonce.\n *\n * @param _nonce Message nonce to encode into.\n * @param _version Version number to encode into the message nonce.\n *\n * @return Message nonce with version encoded into the first two bytes.\n */\n function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\n uint256 nonce;\n assembly {\n nonce := or(shl(240, _version), _nonce)\n }\n return nonce;\n }\n\n /**\n * @notice Pulls the version out of a version-encoded nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n *\n * @return Nonce without encoded version.\n * @return Version of the message.\n */\n function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\n uint240 nonce;\n uint16 version;\n assembly {\n nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n version := shr(240, _nonce)\n }\n return (nonce, version);\n }\n}\n" - }, - "contracts/libraries/Hashing.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Encoding } from \"./Encoding.sol\";\n\n/**\n * @title Hashing\n * @notice Hashing handles Optimism's various different hashing schemes.\n */\nlibrary Hashing {\n /**\n * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\n * given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\n * system.\n *\n * @param _tx User deposit transaction to hash.\n *\n * @return Hash of the RLP encoded L2 deposit transaction.\n */\n function hashDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return keccak256(Encoding.encodeDepositTransaction(_tx));\n }\n\n /**\n * @notice Computes the deposit transaction's \"source hash\", a value that guarantees the hash\n * of the L2 transaction that corresponds to a deposit is unique and is\n * deterministically generated from L1 transaction data.\n *\n * @param _l1BlockHash Hash of the L1 block where the deposit was included.\n * @param _logIndex The index of the log that created the deposit transaction.\n *\n * @return Hash of the deposit transaction's \"source hash\".\n */\n function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)\n internal\n pure\n returns (bytes32)\n {\n bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\n return keccak256(abi.encode(bytes32(0), depositId));\n }\n\n /**\n * @notice Hashes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n if (version == 0) {\n return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Hashing: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Hashes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes32) {\n return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));\n }\n\n /**\n * @notice Hashes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n return\n keccak256(\n Encoding.encodeCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n )\n );\n }\n\n /**\n * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\n *\n * @param _tx Withdrawal transaction to hash.\n *\n * @return Hashed withdrawal transaction.\n */\n function hashWithdrawal(Types.WithdrawalTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\n );\n }\n\n /**\n * @notice Hashes the various elements of an output root proof into an output root hash which\n * can be used to check if the proof is valid.\n *\n * @param _outputRootProof Output root proof which should hash to an output root.\n *\n * @return Hashed output root proof.\n */\n function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(\n _outputRootProof.version,\n _outputRootProof.stateRoot,\n _outputRootProof.messagePasserStorageRoot,\n _outputRootProof.latestBlockhash\n )\n );\n }\n}\n" - }, - "contracts/libraries/LegacyCrossDomainUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n// Importing from the legacy contracts package causes issues with the build of the contract bindings\n// so we just copy the library here from\n// /packages/contracts/contracts/libraries/bridge/Lib_CrossDomainUtils.sol at commit\n// 7866168c\n/**\n * @title LegacyCrossDomainUtils\n */\nlibrary LegacyCrossDomainUtils {\n /**\n * Generates the correct cross domain calldata for a message.\n * @param _target Target contract address.\n * @param _sender Message sender address.\n * @param _message Message to send to the target.\n * @param _messageNonce Nonce for the provided message.\n * @return ABI encoded cross domain calldata.\n */\n function encodeXDomainCalldata(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _message,\n _messageNonce\n );\n }\n}\n" - }, - "contracts/libraries/Predeploys.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Predeploys\n * @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.\n */\nlibrary Predeploys {\n /**\n * @notice Address of the L2ToL1MessagePasser predeploy.\n */\n address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;\n\n /**\n * @notice Address of the L2CrossDomainMessenger predeploy.\n */\n address internal constant L2_CROSS_DOMAIN_MESSENGER =\n 0x4200000000000000000000000000000000000007;\n\n /**\n * @notice Address of the L2StandardBridge predeploy.\n */\n address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\n\n /**\n * @notice Address of the L2ERC721Bridge predeploy.\n */\n address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;\n\n /**\n * @notice Address of the SequencerFeeWallet predeploy.\n */\n address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;\n\n /**\n * @notice Address of the OptimismMintableERC20Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY =\n 0x4200000000000000000000000000000000000012;\n\n /**\n * @notice Address of the OptimismMintableERC721Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY =\n 0x4200000000000000000000000000000000000017;\n\n /**\n * @notice Address of the L1Block predeploy.\n */\n address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;\n\n /**\n * @notice Address of the GasPriceOracle predeploy. Includes fee information\n * and helpers for computing the L1 portion of the transaction fee.\n */\n address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;\n\n /**\n * @custom:legacy\n * @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger\n * or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.\n */\n address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\n\n /**\n * @custom:legacy\n * @notice Address of the DeployerWhitelist predeploy. No longer active.\n */\n address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the\n * state trie as of the Bedrock upgrade. Contract has been locked and write functions\n * can no longer be accessed.\n */\n address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;\n\n /**\n * @custom:legacy\n * @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy\n * instead, which exposes more information about the L1 state.\n */\n address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated\n * L2ToL1MessagePasser contract instead.\n */\n address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\n\n /**\n * @notice Address of the ProxyAdmin predeploy.\n */\n address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;\n\n /**\n * @notice Address of the BaseFeeVault predeploy.\n */\n address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;\n\n /**\n * @notice Address of the L1FeeVault predeploy.\n */\n address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;\n\n /**\n * @notice Address of the GovernanceToken predeploy.\n */\n address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042;\n}\n" - }, - "contracts/libraries/SafeCall.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title SafeCall\n * @notice Perform low level safe calls\n */\nlibrary SafeCall {\n /**\n * @notice Perform a low level call without copying any returndata\n *\n * @param _target Address to call\n * @param _gas Amount of gas to pass to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function call(\n address _target,\n uint256 _gas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n }\n return _success;\n }\n\n /**\n * @notice Perform a low level call without copying any returndata. This function\n * will revert if the call cannot be performed with the specified minimum\n * gas.\n *\n * @param _target Address to call\n * @param _minGas The minimum amount of gas that may be passed to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function callWithMinGas(\n address _target,\n uint256 _minGas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n // Assertion: gasleft() >= ((_minGas + 200) * 64) / 63\n //\n // Because EIP-150 ensures that, a maximum of 63/64ths of the remaining gas in the call\n // frame may be passed to a subcontext, we need to ensure that the gas will not be\n // truncated to hold this function's invariant: \"If a call is performed by\n // `callWithMinGas`, it must receive at least the specified minimum gas limit.\" In\n // addition, exactly 51 gas is consumed between the below `GAS` opcode and the `CALL`\n // opcode, so it is factored in with some extra room for error.\n if lt(gas(), div(mul(64, add(_minGas, 200)), 63)) {\n // Store the \"Error(string)\" selector in scratch space.\n mstore(0, 0x08c379a0)\n // Store the pointer to the string length in scratch space.\n mstore(32, 32)\n // Store the string.\n //\n // SAFETY:\n // - We pad the beginning of the string with two zero bytes as well as the\n // length (24) to ensure that we override the free memory pointer at offset\n // 0x40. This is necessary because the free memory pointer is likely to\n // be greater than 1 byte when this function is called, but it is incredibly\n // unlikely that it will be greater than 3 bytes. As for the data within\n // 0x60, it is ensured that it is 0 due to 0x60 being the zero offset.\n // - It's fine to clobber the free memory pointer, we're reverting.\n mstore(88, 0x0000185361666543616c6c3a204e6f7420656e6f75676820676173)\n\n // Revert with 'Error(\"SafeCall: Not enough gas\")'\n revert(28, 100)\n }\n\n // The call will be supplied at least (((_minGas + 200) * 64) / 63) - 49 gas due to the\n // above assertion. This ensures that, in all circumstances, the call will\n // receive at least the minimum amount of gas specified.\n // We can prove this property by solving the inequalities:\n // ((((_minGas + 200) * 64) / 63) - 49) >= _minGas\n // ((((_minGas + 200) * 64) / 63) - 51) * (63 / 64) >= _minGas\n // Both inequalities hold true for all possible values of `_minGas`.\n _success := call(\n gas(), // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0x00, // outloc\n 0x00 // outlen\n )\n }\n return _success;\n }\n}\n" - }, - "contracts/libraries/Types.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Types\n * @notice Contains various types used throughout the Optimism contract system.\n */\nlibrary Types {\n /**\n * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\n * timestamp that the output root is posted. This timestamp is used to verify that the\n * finalization period has passed since the output root was submitted.\n *\n * @custom:field outputRoot Hash of the L2 output.\n * @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.\n * @custom:field l2BlockNumber L2 block number that the output corresponds to.\n */\n struct OutputProposal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2BlockNumber;\n }\n\n /**\n * @notice Struct representing the elements that are hashed together to generate an output root\n * which itself represents a snapshot of the L2 state.\n *\n * @custom:field version Version of the output root.\n * @custom:field stateRoot Root of the state trie at the block of this output.\n * @custom:field messagePasserStorageRoot Root of the message passer storage trie.\n * @custom:field latestBlockhash Hash of the block this output was generated from.\n */\n struct OutputRootProof {\n bytes32 version;\n bytes32 stateRoot;\n bytes32 messagePasserStorageRoot;\n bytes32 latestBlockhash;\n }\n\n /**\n * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n * user (as opposed to a system deposit transaction generated by the system).\n *\n * @custom:field from Address of the sender of the transaction.\n * @custom:field to Address of the recipient of the transaction.\n * @custom:field isCreation True if the transaction is a contract creation.\n * @custom:field value Value to send to the recipient.\n * @custom:field mint Amount of ETH to mint.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n * @custom:field l1BlockHash Hash of the block the transaction was submitted in.\n * @custom:field logIndex Index of the log in the block the transaction was submitted in.\n */\n struct UserDepositTransaction {\n address from;\n address to;\n bool isCreation;\n uint256 value;\n uint256 mint;\n uint64 gasLimit;\n bytes data;\n bytes32 l1BlockHash;\n uint256 logIndex;\n }\n\n /**\n * @notice Struct representing a withdrawal transaction.\n *\n * @custom:field nonce Nonce of the withdrawal transaction\n * @custom:field sender Address of the sender of the transaction.\n * @custom:field target Address of the recipient of the transaction.\n * @custom:field value Value to send to the recipient.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n */\n struct WithdrawalTransaction {\n uint256 nonce;\n address sender;\n address target;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPReader.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\n/**\n * @custom:attribution https://github.com/hamdiallam/Solidity-RLP\n * @title RLPReader\n * @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted\n * from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with\n * various tweaks to improve readability.\n */\nlibrary RLPReader {\n /**\n * Custom pointer type to avoid confusion between pointers and uint256s.\n */\n type MemoryPointer is uint256;\n\n /**\n * @notice RLP item types.\n *\n * @custom:value DATA_ITEM Represents an RLP data item (NOT a list).\n * @custom:value LIST_ITEM Represents an RLP list item.\n */\n enum RLPItemType {\n DATA_ITEM,\n LIST_ITEM\n }\n\n /**\n * @notice Struct representing an RLP item.\n *\n * @custom:field length Length of the RLP item.\n * @custom:field ptr Pointer to the RLP item in memory.\n */\n struct RLPItem {\n uint256 length;\n MemoryPointer ptr;\n }\n\n /**\n * @notice Max list length that this library will accept.\n */\n uint256 internal constant MAX_LIST_LENGTH = 32;\n\n /**\n * @notice Converts bytes to a reference to memory position and length.\n *\n * @param _in Input bytes to convert.\n *\n * @return Output memory reference.\n */\n function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n // Empty arrays are not RLP items.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr;\n assembly {\n ptr := add(_in, 32)\n }\n\n return RLPItem({ length: _in.length, ptr: ptr });\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.LIST_ITEM,\n \"RLPReader: decoded item type for list is not a list item\"\n );\n\n require(\n listOffset + listLength == _in.length,\n \"RLPReader: list item has an invalid data remainder\"\n );\n\n // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n // writing to the length. Since we can't know the number of RLP items without looping over\n // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n // simply set a reasonable maximum list length and decrease the size before we finish.\n RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n uint256 itemCount = 0;\n uint256 offset = listOffset;\n while (offset < _in.length) {\n (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n RLPItem({\n length: _in.length - offset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n })\n );\n\n // We don't need to check itemCount < out.length explicitly because Solidity already\n // handles this check on our behalf, we'd just be wasting gas.\n out[itemCount] = RLPItem({\n length: itemLength + itemOffset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n });\n\n itemCount += 1;\n offset += itemOffset + itemLength;\n }\n\n // Decrease the array size to match the actual item count.\n assembly {\n mstore(out, itemCount)\n }\n\n return out;\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n return readList(toRLPItem(_in));\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.DATA_ITEM,\n \"RLPReader: decoded item type for bytes is not a data item\"\n );\n\n require(\n _in.length == itemOffset + itemLength,\n \"RLPReader: bytes value contains an invalid remainder\"\n );\n\n return _copy(_in.ptr, itemOffset, itemLength);\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n return readBytes(toRLPItem(_in));\n }\n\n /**\n * @notice Reads the raw bytes of an RLP item.\n *\n * @param _in RLP item to read.\n *\n * @return Raw RLP bytes.\n */\n function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n return _copy(_in.ptr, 0, _in.length);\n }\n\n /**\n * @notice Decodes the length of an RLP item.\n *\n * @param _in RLP item to decode.\n *\n * @return Offset of the encoded data.\n * @return Length of the encoded data.\n * @return RLP item type (LIST_ITEM or DATA_ITEM).\n */\n function _decodeLength(RLPItem memory _in)\n private\n pure\n returns (\n uint256,\n uint256,\n RLPItemType\n )\n {\n // Short-circuit if there's nothing to decode, note that we perform this check when\n // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass\n // that function and create an RLP item directly. So we need to check this anyway.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr = _in.ptr;\n uint256 prefix;\n assembly {\n prefix := byte(0, mload(ptr))\n }\n\n if (prefix <= 0x7f) {\n // Single byte.\n return (0, 1, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xb7) {\n // Short string.\n\n // slither-disable-next-line variable-scope\n uint256 strLen = prefix - 0x80;\n\n require(\n _in.length > strLen,\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n strLen != 1 || firstByteOfContent >= 0x80,\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n\n return (1, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xbf) {\n // Long string.\n uint256 lenOfStrLen = prefix - 0xb7;\n\n require(\n _in.length > lenOfStrLen,\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n\n uint256 strLen;\n assembly {\n strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))\n }\n\n require(\n strLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long string)\"\n );\n\n require(\n _in.length > lenOfStrLen + strLen,\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n\n return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xf7) {\n // Short list.\n // slither-disable-next-line variable-scope\n uint256 listLen = prefix - 0xc0;\n\n require(\n _in.length > listLen,\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n\n return (1, listLen, RLPItemType.LIST_ITEM);\n } else {\n // Long list.\n uint256 lenOfListLen = prefix - 0xf7;\n\n require(\n _in.length > lenOfListLen,\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long list)\"\n );\n\n uint256 listLen;\n assembly {\n listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))\n }\n\n require(\n listLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long list)\"\n );\n\n require(\n _in.length > lenOfListLen + listLen,\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n\n return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n }\n }\n\n /**\n * @notice Copies the bytes from a memory location.\n *\n * @param _src Pointer to the location to read from.\n * @param _offset Offset to start reading from.\n * @param _length Number of bytes to read.\n *\n * @return Copied bytes.\n */\n function _copy(\n MemoryPointer _src,\n uint256 _offset,\n uint256 _length\n ) private pure returns (bytes memory) {\n bytes memory out = new bytes(_length);\n if (_length == 0) {\n return out;\n }\n\n // Mostly based on Solidity's copy_memory_to_memory:\n // solhint-disable max-line-length\n // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114\n uint256 src = MemoryPointer.unwrap(_src) + _offset;\n assembly {\n let dest := add(out, 32)\n let i := 0\n for {\n\n } lt(i, _length) {\n i := add(i, 32)\n } {\n mstore(add(dest, i), mload(add(src, i)))\n }\n\n if gt(i, _length) {\n mstore(add(dest, _length), 0)\n }\n }\n\n return out;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPWriter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\n * @title RLPWriter\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\n * RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\n * modifications to improve legibility.\n */\nlibrary RLPWriter {\n /**\n * @notice RLP encodes a byte string.\n *\n * @param _in The byte string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_in.length == 1 && uint8(_in[0]) < 128) {\n encoded = _in;\n } else {\n encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n }\n\n return encoded;\n }\n\n /**\n * @notice RLP encodes a list of RLP encoded byte byte strings.\n *\n * @param _in The list of RLP encoded byte strings.\n *\n * @return The RLP encoded list of items in bytes.\n */\n function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n bytes memory list = _flatten(_in);\n return abi.encodePacked(_writeLength(list.length, 192), list);\n }\n\n /**\n * @notice RLP encodes a string.\n *\n * @param _in The string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeString(string memory _in) internal pure returns (bytes memory) {\n return writeBytes(bytes(_in));\n }\n\n /**\n * @notice RLP encodes an address.\n *\n * @param _in The address to encode.\n *\n * @return The RLP encoded address in bytes.\n */\n function writeAddress(address _in) internal pure returns (bytes memory) {\n return writeBytes(abi.encodePacked(_in));\n }\n\n /**\n * @notice RLP encodes a uint.\n *\n * @param _in The uint256 to encode.\n *\n * @return The RLP encoded uint256 in bytes.\n */\n function writeUint(uint256 _in) internal pure returns (bytes memory) {\n return writeBytes(_toBinary(_in));\n }\n\n /**\n * @notice RLP encodes a bool.\n *\n * @param _in The bool to encode.\n *\n * @return The RLP encoded bool in bytes.\n */\n function writeBool(bool _in) internal pure returns (bytes memory) {\n bytes memory encoded = new bytes(1);\n encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n return encoded;\n }\n\n /**\n * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\n *\n * @param _len The length of the string or the payload.\n * @param _offset 128 if item is string, 192 if item is list.\n *\n * @return RLP encoded bytes.\n */\n function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_len < 56) {\n encoded = new bytes(1);\n encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n } else {\n uint256 lenLen;\n uint256 i = 1;\n while (_len / i != 0) {\n lenLen++;\n i *= 256;\n }\n\n encoded = new bytes(lenLen + 1);\n encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n for (i = 1; i <= lenLen; i++) {\n encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n }\n }\n\n return encoded;\n }\n\n /**\n * @notice Encode integer in big endian binary form with no leading zeroes.\n *\n * @param _x The integer to encode.\n *\n * @return RLP encoded bytes.\n */\n function _toBinary(uint256 _x) private pure returns (bytes memory) {\n bytes memory b = abi.encodePacked(_x);\n\n uint256 i = 0;\n for (; i < 32; i++) {\n if (b[i] != 0) {\n break;\n }\n }\n\n bytes memory res = new bytes(32 - i);\n for (uint256 j = 0; j < res.length; j++) {\n res[j] = b[i++];\n }\n\n return res;\n }\n\n /**\n * @custom:attribution https://github.com/Arachnid/solidity-stringutils\n * @notice Copies a piece of memory to another location.\n *\n * @param _dest Destination location.\n * @param _src Source location.\n * @param _len Length of memory to copy.\n */\n function _memcpy(\n uint256 _dest,\n uint256 _src,\n uint256 _len\n ) private pure {\n uint256 dest = _dest;\n uint256 src = _src;\n uint256 len = _len;\n\n for (; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n uint256 mask;\n unchecked {\n mask = 256**(32 - len) - 1;\n }\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /**\n * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\n * @notice Flattens a list of byte strings into one byte string.\n *\n * @param _list List of byte strings to flatten.\n *\n * @return The flattened byte string.\n */\n function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n if (_list.length == 0) {\n return new bytes(0);\n }\n\n uint256 len;\n uint256 i = 0;\n for (; i < _list.length; i++) {\n len += _list[i].length;\n }\n\n bytes memory flattened = new bytes(len);\n uint256 flattenedPtr;\n assembly {\n flattenedPtr := add(flattened, 0x20)\n }\n\n for (i = 0; i < _list.length; i++) {\n bytes memory item = _list[i];\n\n uint256 listPtr;\n assembly {\n listPtr := add(item, 0x20)\n }\n\n _memcpy(flattenedPtr, listPtr, item.length);\n flattenedPtr += _list[i].length;\n }\n\n return flattened;\n }\n}\n" - }, - "contracts/libraries/trie/MerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Bytes } from \"../Bytes.sol\";\nimport { RLPReader } from \"../rlp/RLPReader.sol\";\n\n/**\n * @title MerkleTrie\n * @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie\n * inclusion proofs. By default, this library assumes a hexary trie. One can change the\n * trie radix constant to support other trie radixes.\n */\nlibrary MerkleTrie {\n /**\n * @notice Struct representing a node in the trie.\n *\n * @custom:field encoded The RLP-encoded node.\n * @custom:field decoded The RLP-decoded node.\n */\n struct TrieNode {\n bytes encoded;\n RLPReader.RLPItem[] decoded;\n }\n\n /**\n * @notice Determines the number of elements per branch node.\n */\n uint256 internal constant TREE_RADIX = 16;\n\n /**\n * @notice Branch nodes have TREE_RADIX elements and one value element.\n */\n uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\n\n /**\n * @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.\n */\n uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\n\n /**\n * @notice Prefix for even-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_EVEN = 0;\n\n /**\n * @notice Prefix for odd-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_ODD = 1;\n\n /**\n * @notice Prefix for even-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_EVEN = 2;\n\n /**\n * @notice Prefix for odd-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_ODD = 3;\n\n /**\n * @notice Verifies a proof that a given key/value pair is present in the trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n return Bytes.equal(_value, get(_key, _proof, _root));\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n require(_key.length > 0, \"MerkleTrie: empty key\");\n\n TrieNode[] memory proof = _parseProof(_proof);\n bytes memory key = Bytes.toNibbles(_key);\n bytes memory currentNodeID = abi.encodePacked(_root);\n uint256 currentKeyIndex = 0;\n\n // Proof is top-down, so we start at the first element (root).\n for (uint256 i = 0; i < proof.length; i++) {\n TrieNode memory currentNode = proof[i];\n\n // Key index should never exceed total key length or we'll be out of bounds.\n require(\n currentKeyIndex <= key.length,\n \"MerkleTrie: key index exceeds total key length\"\n );\n\n if (currentKeyIndex == 0) {\n // First proof element is always the root node.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid root hash\"\n );\n } else if (currentNode.encoded.length >= 32) {\n // Nodes 32 bytes or larger are hashed inside branch nodes.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid large internal hash\"\n );\n } else {\n // Nodes smaller than 32 bytes aren't hashed.\n require(\n Bytes.equal(currentNode.encoded, currentNodeID),\n \"MerkleTrie: invalid internal node hash\"\n );\n }\n\n if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\n if (currentKeyIndex == key.length) {\n // Value is the last element of the decoded list (for branch nodes). There's\n // some ambiguity in the Merkle trie specification because bytes(0) is a\n // valid value to place into the trie, but for branch nodes bytes(0) can exist\n // even when the value wasn't explicitly placed there. Geth treats a value of\n // bytes(0) as \"key does not exist\" and so we do the same.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (branch)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (branch)\"\n );\n\n return value;\n } else {\n // We're not at the end of the key yet.\n // Figure out what the next node ID should be and continue.\n uint8 branchKey = uint8(key[currentKeyIndex]);\n RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\n currentNodeID = _getNodeID(nextNode);\n currentKeyIndex += 1;\n }\n } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\n bytes memory path = _getNodePath(currentNode);\n uint8 prefix = uint8(path[0]);\n uint8 offset = 2 - (prefix % 2);\n bytes memory pathRemainder = Bytes.slice(path, offset);\n bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);\n uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\n\n // Whether this is a leaf node or an extension node, the path remainder MUST be a\n // prefix of the key remainder (or be equal to the key remainder) or the proof is\n // considered invalid.\n require(\n pathRemainder.length == sharedNibbleLength,\n \"MerkleTrie: path remainder must share all nibbles with key\"\n );\n\n if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\n // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid,\n // the key remainder must be exactly equal to the path remainder. We already\n // did the necessary byte comparison, so it's more efficient here to check that\n // the key remainder length equals the shared nibble length, which implies\n // equality with the path remainder (since we already did the same check with\n // the path remainder and the shared nibble length).\n require(\n keyRemainder.length == sharedNibbleLength,\n \"MerkleTrie: key remainder must be identical to path remainder\"\n );\n\n // Our Merkle Trie is designed specifically for the purposes of the Ethereum\n // state trie. Empty values are not allowed in the state trie, so we can safely\n // say that if the value is empty, the key should not exist and the proof is\n // invalid.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[1]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (leaf)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (leaf)\"\n );\n\n return value;\n } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\n // Prefix of 0 or 1 means this is an extension node. We move onto the next node\n // in the proof and increment the key index by the length of the path remainder\n // which is equal to the shared nibble length.\n currentNodeID = _getNodeID(currentNode.decoded[1]);\n currentKeyIndex += sharedNibbleLength;\n } else {\n revert(\"MerkleTrie: received a node with an unknown prefix\");\n }\n } else {\n revert(\"MerkleTrie: received an unparseable node\");\n }\n }\n\n revert(\"MerkleTrie: ran out of proof elements\");\n }\n\n /**\n * @notice Parses an array of proof elements into a new array that contains both the original\n * encoded element and the RLP-decoded element.\n *\n * @param _proof Array of proof elements to parse.\n *\n * @return Proof parsed into easily accessible structs.\n */\n function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {\n uint256 length = _proof.length;\n TrieNode[] memory proof = new TrieNode[](length);\n for (uint256 i = 0; i < length; ) {\n proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });\n unchecked {\n ++i;\n }\n }\n return proof;\n }\n\n /**\n * @notice Picks out the ID for a node. Node ID is referred to as the \"hash\" within the\n * specification, but nodes < 32 bytes are not actually hashed.\n *\n * @param _node Node to pull an ID for.\n *\n * @return ID for the node, depending on the size of its contents.\n */\n function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {\n return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);\n }\n\n /**\n * @notice Gets the path for a leaf or extension node.\n *\n * @param _node Node to get a path for.\n *\n * @return Node path, converted to an array of nibbles.\n */\n function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {\n return Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0]));\n }\n\n /**\n * @notice Utility; determines the number of nibbles shared between two nibble arrays.\n *\n * @param _a First nibble array.\n * @param _b Second nibble array.\n *\n * @return Number of shared nibbles.\n */\n function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\n private\n pure\n returns (uint256)\n {\n uint256 shared;\n uint256 max = (_a.length < _b.length) ? _a.length : _b.length;\n for (; shared < max && _a[shared] == _b[shared]; ) {\n unchecked {\n ++shared;\n }\n }\n return shared;\n }\n}\n" - }, - "contracts/libraries/trie/SecureMerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/* Library Imports */\nimport { MerkleTrie } from \"./MerkleTrie.sol\";\n\n/**\n * @title SecureMerkleTrie\n * @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input\n * keys. Ethereum's state trie hashes input keys before storing them.\n */\nlibrary SecureMerkleTrie {\n /**\n * @notice Verifies a proof that a given key/value pair is present in the Merkle trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.get(key, _proof, _root);\n }\n\n /**\n * @notice Computes the hashed version of the input key.\n *\n * @param _key Key to hash.\n *\n * @return Hashed version of the key.\n */\n function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {\n return abi.encodePacked(keccak256(_key));\n }\n}\n" - }, - "contracts/periphery/TransferOnion.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title TransferOnion\n * @notice TransferOnion is a hash onion for distributing tokens. The shell commits\n * to an ordered list of the token transfers and can be permissionlessly\n * unwrapped in order. The SENDER must `approve` this contract as\n * `transferFrom` is used to move the token balances.\n */\ncontract TransferOnion is ReentrancyGuard {\n using SafeERC20 for ERC20;\n\n /**\n * @notice Struct representing a layer of the onion.\n */\n struct Layer {\n address recipient;\n uint256 amount;\n bytes32 shell;\n }\n\n /**\n * @notice Address of the token to distribute.\n */\n ERC20 public immutable TOKEN;\n\n /**\n * @notice Address of the account to distribute tokens from.\n */\n address public immutable SENDER;\n\n /**\n * @notice Current shell hash.\n */\n bytes32 public shell;\n\n /**\n * @param _token Address of the token to distribute.\n * @param _sender Address of the sender to distribute from.\n * @param _shell Initial shell of the onion.\n */\n constructor(\n ERC20 _token,\n address _sender,\n bytes32 _shell\n ) {\n TOKEN = _token;\n SENDER = _sender;\n shell = _shell;\n }\n\n /**\n * @notice Peels layers from the onion and distributes tokens.\n *\n * @param _layers Array of onion layers to peel.\n */\n function peel(Layer[] memory _layers) public nonReentrant {\n bytes32 tempShell = shell;\n uint256 length = _layers.length;\n for (uint256 i = 0; i < length; ) {\n Layer memory layer = _layers[i];\n\n // Confirm that the onion layer is correct.\n require(\n keccak256(abi.encode(layer.recipient, layer.amount, layer.shell)) == tempShell,\n \"TransferOnion: what are you doing in my swamp?\"\n );\n\n // Update the onion layer.\n tempShell = layer.shell;\n\n // Transfer the tokens.\n TOKEN.safeTransferFrom(SENDER, layer.recipient, layer.amount);\n\n // Unchecked increment to save some gas.\n unchecked {\n ++i;\n }\n }\n\n shell = tempShell;\n }\n}\n" - }, - "contracts/test/AddressAliasHelper.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract AddressAliasHelper_applyAndUndo_Test is Test {\n /**\n * @notice Tests that applying and then undoing an alias results in the original address.\n */\n function testFuzz_applyAndUndo_succeeds(address _address) external {\n address aliased = AddressAliasHelper.applyL1ToL2Alias(_address);\n address unaliased = AddressAliasHelper.undoL1ToL2Alias(aliased);\n assertEq(_address, unaliased);\n }\n}\n" - }, - "contracts/test/BenchmarkTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test } from \"forge-std/Test.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport \"./CommonTest.t.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n// Free function for setting the prevBaseFee param in the OptimismPortal.\nfunction setPrevBaseFee(\n Vm _vm,\n address _op,\n uint128 _prevBaseFee\n) {\n _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee));\n}\n\ncontract SetPrevBaseFee_Test is Portal_Initializer {\n function test_setPrevBaseFee_succeeds() external {\n setPrevBaseFee(vm, address(op), 100 gwei);\n (uint128 prevBaseFee, , uint64 prevBlockNum) = op.params();\n assertEq(uint256(prevBaseFee), 100 gwei);\n assertEq(uint256(prevBlockNum), block.number);\n }\n}\n\n// Tests for obtaining pure gas cost estimates for commonly used functions.\n// The objective with these benchmarks is to strip down the actual test functions\n// so that they are nothing more than the call we want measure the gas cost of.\n// In order to achieve this we make no assertions, and handle everything else in the setUp()\n// function.\ncontract GasBenchMark_OptimismPortal is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n bytes32 _outputRoot;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n\n // Get withdrawal proof data we can use for testing.\n bytes32 _storageRoot;\n bytes32 _stateRoot;\n (_stateRoot, _storageRoot, _outputRoot, , _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public virtual override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n function test_depositTransaction_benchmark() external {\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_depositTransaction_benchmark_1() external {\n setPrevBaseFee(vm, address(op), 1 gwei);\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_proveWithdrawalTransaction_benchmark() external {\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n}\n\ncontract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {\n function test_sendMessage_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n\n function test_sendMessage_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), alice, 100000, true);\n vm.startPrank(alice, alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n }\n\n function test_depositETH_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositETH_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositERC20_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n\n function test_depositERC20_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), address(L1Bridge), 100, true);\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.startPrank(address(L1Bridge.messenger()));\n vm.deal(address(L1Bridge.messenger()), 100);\n }\n\n function test_finalizeETHWithdrawal_benchmark() external {\n // TODO: Make this more accurate. It is underestimating the cost because it pranks\n // the call coming from the messenger, which bypasses the portal\n // and oracle.\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer {\n uint256 nextBlockNumber;\n\n function setUp() public override {\n super.setUp();\n nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.startPrank(proposer);\n }\n\n function test_proposeL2Output_benchmark() external {\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n}\n" - }, - "contracts/test/Bytes.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Bytes } from \"../libraries/Bytes.sol\";\n\ncontract Bytes_slice_Test is Test {\n /**\n * @notice Tests that the `slice` function works as expected when starting from index 0.\n */\n function test_slice_fromZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check if all possible slices starting from index 0 are correct.\n assertEq(Bytes.slice(input, 0, 0), hex\"\");\n assertEq(Bytes.slice(input, 0, 1), hex\"11\");\n assertEq(Bytes.slice(input, 0, 2), hex\"1122\");\n assertEq(Bytes.slice(input, 0, 3), hex\"112233\");\n assertEq(Bytes.slice(input, 0, 4), hex\"11223344\");\n assertEq(Bytes.slice(input, 0, 5), hex\"1122334455\");\n assertEq(Bytes.slice(input, 0, 6), hex\"112233445566\");\n assertEq(Bytes.slice(input, 0, 7), hex\"11223344556677\");\n assertEq(Bytes.slice(input, 0, 8), hex\"1122334455667788\");\n assertEq(Bytes.slice(input, 0, 9), hex\"112233445566778899\");\n assertEq(Bytes.slice(input, 0, 10), hex\"11223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when starting from indices [1, 9]\n * with lengths [1, 9], in reverse order.\n */\n function test_slice_fromNonZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check correctness of slices starting from indexes [1, 9]\n // and spanning [1, 9] bytes, in reverse order\n assertEq(Bytes.slice(input, 9, 1), hex\"00\");\n assertEq(Bytes.slice(input, 8, 2), hex\"9900\");\n assertEq(Bytes.slice(input, 7, 3), hex\"889900\");\n assertEq(Bytes.slice(input, 6, 4), hex\"77889900\");\n assertEq(Bytes.slice(input, 5, 5), hex\"6677889900\");\n assertEq(Bytes.slice(input, 4, 6), hex\"556677889900\");\n assertEq(Bytes.slice(input, 3, 7), hex\"44556677889900\");\n assertEq(Bytes.slice(input, 2, 8), hex\"3344556677889900\");\n assertEq(Bytes.slice(input, 1, 9), hex\"223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple words\n * in memory. In this case, we test that a 2 byte slice between the 32nd byte of the\n * first word and the 1st byte of the second word is correct.\n */\n function test_slice_acrossWords_works() public {\n bytes\n memory input = hex\"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000\";\n\n assertEq(Bytes.slice(input, 31, 2), hex\"1122\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple\n * words in memory. In this case, we test that a 34 byte slice between 3 separate words\n * returns the correct result.\n */\n function test_slice_acrossMultipleWords_works() public {\n bytes\n memory input = hex\"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000\";\n bytes\n memory expected = hex\"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11\";\n\n assertEq(Bytes.slice(input, 31, 34), expected);\n }\n\n /**\n * @notice Tests that, when given an input bytes array of length `n`, the `slice` function will\n * always revert if `_start + _length > n`.\n */\n function testFuzz_slice_outOfBounds_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // We want a valid start index and a length that will not overflow.\n vm.assume(_start < _input.length && _length < type(uint256).max - 31);\n // But, we want an invalid slice length.\n vm.assume(_start + _length > _input.length);\n\n vm.expectRevert(\"slice_outOfBounds\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,\n * the `slice` function reverts.\n */\n function testFuzz_slice_lengthOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that the `_length` will overflow if a number >= 31 is added to it.\n vm.assume(_length > type(uint256).max - 31);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a start index `n` that is greater than\n * `type(uint256).max - n`, the `slice` function reverts.\n */\n function testFuzz_slice_rangeOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that `_length` is a realistic length of a slice. This is to make sure\n // we revert on the correct require statement.\n vm.assume(_length < _input.length);\n // Ensure that `_start` will overflow if `_length` is added to it.\n vm.assume(_start > type(uint256).max - _length);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that the `slice` function correctly updates the free memory pointer depending\n * on the length of the slice.\n */\n function testFuzz_slice_memorySafety_succeeds(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // The start should never be more than the length of the input bytes array - 1\n vm.assume(_start < _input.length);\n // The length should never be more than the length of the input bytes array - the starting\n // slice index.\n vm.assume(_length <= _input.length - _start);\n\n // Grab the free memory pointer before the slice operation\n uint64 initPtr;\n assembly {\n initPtr := mload(0x40)\n }\n uint64 expectedPtr = uint64(initPtr + 0x20 + ((_length + 0x1f) & ~uint256(0x1f)));\n\n // Ensure that all memory outside of the expected range is safe.\n vm.expectSafeMemory(initPtr, expectedPtr);\n\n // Slice the input bytes array from `_start` to `_start + _length`\n bytes memory slice = Bytes.slice(_input, _start, _length);\n\n // Grab the free memory pointer after the slice operation\n uint64 finalPtr;\n assembly {\n finalPtr := mload(0x40)\n }\n\n // The free memory pointer should have been updated properly\n if (_length == 0) {\n // If the slice length is zero, only 32 bytes of memory should have been allocated.\n assertEq(finalPtr, initPtr + 0x20);\n } else {\n // If the slice length is greater than zero, the memory allocated should be the\n // length of the slice rounded up to the next 32 byte word + 32 bytes for the\n // length of the byte array.\n //\n // Note that we use a slightly less efficient, but equivalent method of rounding\n // up `_length` to the next multiple of 32 than is used in the `slice` function.\n // This is to diff test the method used in `slice`.\n uint64 _expectedPtr = uint64(initPtr + 0x20 + (((_length + 0x1F) >> 5) << 5));\n assertEq(finalPtr, _expectedPtr);\n\n // Sanity check for equivalence of the rounding methods.\n assertEq(_expectedPtr, expectedPtr);\n }\n\n // The slice length should be equal to `_length`\n assertEq(slice.length, _length);\n }\n}\n\ncontract Bytes_toNibbles_Test is Test {\n /**\n * @notice Diffs the test Solidity version of `toNibbles` against the Yul version.\n *\n * @param _bytes The `bytes` array to convert to nibbles.\n *\n * @return Yul version of `toNibbles` applied to `_bytes`.\n */\n function _toNibblesYul(bytes memory _bytes) internal pure returns (bytes memory) {\n // Allocate memory for the `nibbles` array.\n bytes memory nibbles = new bytes(_bytes.length << 1);\n\n assembly {\n // Load the length of the passed bytes array from memory\n let bytesLength := mload(_bytes)\n\n // Store the memory offset of the _bytes array's contents on the stack\n let bytesStart := add(_bytes, 0x20)\n\n // Store the memory offset of the nibbles array's contents on the stack\n let nibblesStart := add(nibbles, 0x20)\n\n // Loop through each byte in the input array\n for {\n let i := 0x00\n } lt(i, bytesLength) {\n i := add(i, 0x01)\n } {\n // Get the starting offset of the next 2 bytes in the nibbles array\n let offset := add(nibblesStart, shl(0x01, i))\n\n // Load the byte at the current index within the `_bytes` array\n let b := byte(0x00, mload(add(bytesStart, i)))\n\n // Pull out the first nibble and store it in the new array\n mstore8(offset, shr(0x04, b))\n // Pull out the second nibble and store it in the new array\n mstore8(add(offset, 0x01), and(b, 0x0F))\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Tests that, given an input of 5 bytes, the `toNibbles` function returns an array of\n * 10 nibbles corresponding to the input data.\n */\n function test_toNibbles_expectedResult5Bytes_works() public {\n bytes memory input = hex\"1234567890\";\n bytes memory expected = hex\"01020304050607080900\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 128 bytes, the `toNibbles` function returns an array\n * of 256 nibbles corresponding to the input data. This test exists to ensure that,\n * given a large input, the `toNibbles` function works as expected.\n */\n function test_toNibbles_expectedResult128Bytes_works() public {\n bytes\n memory input = hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f\";\n bytes\n memory expected = hex\"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 0 bytes, the `toNibbles` function returns a zero\n * length array.\n */\n function test_toNibbles_zeroLengthInput_works() public {\n bytes memory input = hex\"\";\n bytes memory expected = hex\"\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length, 0);\n assertEq(expected.length, 0);\n assertEq(actual.length, 0);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Test that the `toNibbles` function in the `Bytes` library is equivalent to the Yul\n * implementation.\n */\n function testDiff_toNibbles_succeeds(bytes memory _input) public {\n assertEq(Bytes.toNibbles(_input), _toNibblesYul(_input));\n }\n}\n\ncontract Bytes_equal_Test is Test {\n /**\n * @notice Manually checks equality of two dynamic `bytes` arrays in memory.\n *\n * @param _a The first `bytes` array to compare.\n * @param _b The second `bytes` array to compare.\n *\n * @return True if the two `bytes` arrays are equal in memory.\n */\n function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) {\n bool _eq;\n assembly {\n _eq := and(\n // Check if the contents of the two bytes arrays are equal in memory.\n eq(keccak256(add(0x20, _a), mload(_a)), keccak256(add(0x20, _b), mload(_b))),\n // Check if the length of the two bytes arrays are equal in memory.\n // This is redundant given the above check, but included for completeness.\n eq(mload(_a), mload(_b))\n )\n }\n return _eq;\n }\n\n /**\n * @notice Tests that the `equal` function in the `Bytes` library returns `false` if given two\n * non-equal byte arrays.\n */\n function testFuzz_equal_notEqual_works(bytes memory _a, bytes memory _b) public {\n vm.assume(!manualEq(_a, _b));\n assertFalse(Bytes.equal(_a, _b));\n }\n\n /**\n * @notice Test whether or not the `equal` function in the `Bytes` library is equivalent to\n * manually checking equality of the two dynamic `bytes` arrays in memory.\n */\n function testDiff_equal_works(bytes memory _a, bytes memory _b) public {\n assertEq(Bytes.equal(_a, _b), manualEq(_a, _b));\n }\n}\n" - }, - "contracts/test/CommonTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test, StdUtils } from \"forge-std/Test.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { IL1ChugSplashDeployer } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { LegacyMintableERC20 } from \"../legacy/LegacyMintableERC20.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract CommonTest is Test {\n address alice = address(128);\n address bob = address(256);\n address multisig = address(512);\n\n address immutable ZERO_ADDRESS = address(0);\n address immutable NON_ZERO_ADDRESS = address(1);\n uint256 immutable NON_ZERO_VALUE = 100;\n uint256 immutable ZERO_VALUE = 0;\n uint64 immutable NON_ZERO_GASLIMIT = 50000;\n bytes32 nonZeroHash = keccak256(abi.encode(\"NON_ZERO\"));\n bytes NON_ZERO_DATA = hex\"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000\";\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n FFIInterface ffi;\n\n function setUp() public virtual {\n // Give alice and bob some ETH\n vm.deal(alice, 1 << 16);\n vm.deal(bob, 1 << 16);\n vm.deal(multisig, 1 << 16);\n\n vm.label(alice, \"alice\");\n vm.label(bob, \"bob\");\n vm.label(multisig, \"multisig\");\n\n // Make sure we have a non-zero base fee\n vm.fee(1000000000);\n\n ffi = new FFIInterface();\n }\n\n function emitTransactionDeposited(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) internal {\n emit TransactionDeposited(\n _from,\n _to,\n 0,\n abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)\n );\n }\n}\n\ncontract L2OutputOracle_Initializer is CommonTest {\n // Test target\n L2OutputOracle oracle;\n L2OutputOracle oracleImpl;\n\n L2ToL1MessagePasser messagePasser =\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));\n\n // Constructor arguments\n address internal proposer = 0x000000000000000000000000000000000000AbBa;\n address internal owner = 0x000000000000000000000000000000000000ACDC;\n uint256 internal submissionInterval = 1800;\n uint256 internal l2BlockTime = 2;\n uint256 internal startingBlockNumber = 200;\n uint256 internal startingTimestamp = 1000;\n address guardian;\n\n // Test data\n uint256 initL1Time;\n\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n // Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output\n function warpToProposeTime(uint256 _nextBlockNumber) public {\n vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1);\n }\n\n function setUp() public virtual override {\n super.setUp();\n guardian = makeAddr(\"guardian\");\n\n // By default the first block has timestamp and number zero, which will cause underflows in the\n // tests, so we'll move forward to these block values.\n initL1Time = startingTimestamp + 1;\n vm.warp(initL1Time);\n vm.roll(startingBlockNumber);\n // Deploy the L2OutputOracle and transfer owernship to the proposer\n oracleImpl = new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: startingTimestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(oracleImpl),\n abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp))\n );\n oracle = L2OutputOracle(address(proxy));\n vm.label(address(oracle), \"L2OutputOracle\");\n\n // Set the L2ToL1MessagePasser at the correct address\n vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code);\n\n vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, \"L2ToL1MessagePasser\");\n }\n}\n\ncontract Portal_Initializer is L2OutputOracle_Initializer {\n // Test target\n OptimismPortal internal opImpl;\n OptimismPortal internal op;\n SystemConfig systemConfig;\n\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n\n systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: config\n });\n\n opImpl = new OptimismPortal({\n _l2Oracle: oracle,\n _guardian: guardian,\n _paused: true,\n _config: systemConfig\n });\n\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(opImpl),\n abi.encodeWithSelector(OptimismPortal.initialize.selector, false)\n );\n op = OptimismPortal(payable(address(proxy)));\n vm.label(address(op), \"OptimismPortal\");\n }\n}\n\ncontract Messenger_Initializer is Portal_Initializer {\n AddressManager internal addressManager;\n L1CrossDomainMessenger internal L1Messenger;\n L2CrossDomainMessenger internal L2Messenger =\n L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);\n\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event RelayedMessage(bytes32 indexed msgHash);\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 mint,\n uint256 value,\n uint64 gasLimit,\n bool isCreation,\n bytes data\n );\n\n event WhatHappened(bool success, bytes returndata);\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the address manager\n vm.prank(multisig);\n addressManager = new AddressManager();\n\n // Setup implementation\n L1CrossDomainMessenger L1MessengerImpl = new L1CrossDomainMessenger(op);\n\n // Setup the address manager and proxy\n vm.prank(multisig);\n addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(L1MessengerImpl));\n ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(\n addressManager,\n \"OVM_L1CrossDomainMessenger\"\n );\n L1Messenger = L1CrossDomainMessenger(address(proxy));\n L1Messenger.initialize();\n\n vm.etch(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n address(new L2CrossDomainMessenger(address(L1Messenger))).code\n );\n\n L2Messenger.initialize();\n\n // Label addresses\n vm.label(address(addressManager), \"AddressManager\");\n vm.label(address(L1MessengerImpl), \"L1CrossDomainMessenger_Impl\");\n vm.label(address(L1Messenger), \"L1CrossDomainMessenger_Proxy\");\n vm.label(Predeploys.LEGACY_ERC20_ETH, \"LegacyERC20ETH\");\n vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, \"L2CrossDomainMessenger\");\n\n vm.label(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n \"L1CrossDomainMessenger_aliased\"\n );\n }\n}\n\ncontract Bridge_Initializer is Messenger_Initializer {\n L1StandardBridge L1Bridge;\n L2StandardBridge L2Bridge;\n OptimismMintableERC20Factory L2TokenFactory;\n OptimismMintableERC20Factory L1TokenFactory;\n ERC20 L1Token;\n ERC20 BadL1Token;\n OptimismMintableERC20 L2Token;\n LegacyMintableERC20 LegacyL2Token;\n ERC20 NativeL2Token;\n ERC20 BadL2Token;\n OptimismMintableERC20 RemoteL1Token;\n\n event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data\n );\n\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFailed(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.label(Predeploys.L2_STANDARD_BRIDGE, \"L2StandardBridge\");\n vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, \"OptimismMintableERC20Factory\");\n\n // Deploy the L1 bridge and initialize it with the address of the\n // L1CrossDomainMessenger\n L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig);\n vm.mockCall(\n multisig,\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector),\n abi.encode(true)\n );\n vm.startPrank(multisig);\n proxy.setCode(address(new L1StandardBridge(payable(address(L1Messenger)))).code);\n vm.clearMockedCalls();\n address L1Bridge_Impl = proxy.getImplementation();\n vm.stopPrank();\n\n L1Bridge = L1StandardBridge(payable(address(proxy)));\n\n vm.label(address(proxy), \"L1StandardBridge_Proxy\");\n vm.label(address(L1Bridge_Impl), \"L1StandardBridge_Impl\");\n\n // Deploy the L2StandardBridge, move it to the correct predeploy\n // address and then initialize it\n L2StandardBridge l2B = new L2StandardBridge(payable(proxy));\n vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(l2B).code);\n L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));\n\n // Set up the L2 mintable token factory\n OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(\n Predeploys.L2_STANDARD_BRIDGE\n );\n vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code);\n L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);\n\n vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code);\n\n L1Token = new ERC20(\"Native L1 Token\", \"L1T\");\n\n LegacyL2Token = new LegacyMintableERC20({\n _l2Bridge: address(L2Bridge),\n _l1Token: address(L1Token),\n _name: string.concat(\"LegacyL2-\", L1Token.name()),\n _symbol: string.concat(\"LegacyL2-\", L1Token.symbol())\n });\n vm.label(address(LegacyL2Token), \"LegacyMintableERC20\");\n\n // Deploy the L2 ERC20 now\n L2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(L1Token),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n BadL2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n NativeL2Token = new ERC20(\"Native L2 Token\", \"L2T\");\n L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge));\n\n RemoteL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(NativeL2Token),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n\n BadL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n }\n}\n\ncontract ERC721Bridge_Initializer is Messenger_Initializer {\n L1ERC721Bridge L1Bridge;\n L2ERC721Bridge L2Bridge;\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the L1ERC721Bridge.\n L1Bridge = new L1ERC721Bridge(address(L1Messenger), Predeploys.L2_ERC721_BRIDGE);\n\n // Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.\n vm.etch(\n Predeploys.L2_ERC721_BRIDGE,\n address(new L2ERC721Bridge(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(L1Bridge)))\n .code\n );\n\n // Set up a reference to the L2ERC721Bridge.\n L2Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);\n\n // Label the L1 and L2 bridges.\n vm.label(address(L1Bridge), \"L1ERC721Bridge\");\n vm.label(address(L2Bridge), \"L2ERC721Bridge\");\n }\n}\n\ncontract FFIInterface is Test {\n function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx)\n external\n returns (\n bytes32,\n bytes32,\n bytes32,\n bytes32,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"getProveWithdrawalTransactionInputs\";\n cmds[2] = vm.toString(_tx.nonce);\n cmds[3] = vm.toString(_tx.sender);\n cmds[4] = vm.toString(_tx.target);\n cmds[5] = vm.toString(_tx.value);\n cmds[6] = vm.toString(_tx.gasLimit);\n cmds[7] = vm.toString(_tx.data);\n\n bytes memory result = vm.ffi(cmds);\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[]));\n\n return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof);\n }\n\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashWithdrawal(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashWithdrawal\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashOutputRootProof(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external returns (bytes32) {\n string[] memory cmds = new string[](6);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashOutputRootProof\";\n cmds[2] = Strings.toHexString(uint256(_version));\n cmds[3] = Strings.toHexString(uint256(_stateRoot));\n cmds[4] = Strings.toHexString(uint256(_messagePasserStorageRoot));\n cmds[5] = Strings.toHexString(uint256(_latestBlockhash));\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashDepositTransaction(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external returns (bytes32) {\n string[] memory cmds = new string[](10);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashDepositTransaction\";\n cmds[2] = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n cmds[3] = vm.toString(_logIndex);\n cmds[4] = vm.toString(_from);\n cmds[5] = vm.toString(_to);\n cmds[6] = vm.toString(_mint);\n cmds[7] = vm.toString(_value);\n cmds[8] = vm.toString(_gas);\n cmds[9] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function encodeDepositTransaction(Types.UserDepositTransaction calldata txn)\n external\n returns (bytes memory)\n {\n string[] memory cmds = new string[](11);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeDepositTransaction\";\n cmds[2] = vm.toString(txn.from);\n cmds[3] = vm.toString(txn.to);\n cmds[4] = vm.toString(txn.value);\n cmds[5] = vm.toString(txn.mint);\n cmds[6] = vm.toString(txn.gasLimit);\n cmds[7] = vm.toString(txn.isCreation);\n cmds[8] = vm.toString(txn.data);\n cmds[9] = vm.toString(txn.l1BlockHash);\n cmds[10] = vm.toString(txn.logIndex);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes memory) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) {\n string[] memory cmds = new string[](3);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"decodeVersionedNonce\";\n cmds[2] = vm.toString(nonce);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (uint256, uint256));\n }\n\n function getMerkleTrieFuzzCase(string memory variant)\n external\n returns (\n bytes32,\n bytes memory,\n bytes memory,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](5);\n cmds[0] = \"./test-case-generator/fuzz\";\n cmds[1] = \"-m\";\n cmds[2] = \"trie\";\n cmds[3] = \"-v\";\n cmds[4] = variant;\n\n return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[]));\n }\n}\n\n// Used for testing a future upgrade beyond the current implementations.\n// We include some variables so that we can sanity check accessing storage values after an upgrade.\ncontract NextImpl is Initializable {\n // Initializable occupies the zero-th slot.\n bytes32 slot1;\n bytes32[19] __gap;\n bytes32 slot21;\n bytes32 public constant slot21Init = bytes32(hex\"1337\");\n\n function initialize() public reinitializer(2) {\n // Slot21 is unused by an of our upgradeable contracts.\n // This is used to verify that we can access this value after an upgrade.\n slot21 = slot21Init;\n }\n}\n\ncontract Reverter {\n fallback() external {\n revert();\n }\n}\n\n// Useful for testing reentrancy guards\ncontract CallerCaller {\n event WhatHappened(bool success, bytes returndata);\n\n fallback() external {\n (bool success, bytes memory returndata) = msg.sender.call(msg.data);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n\n// Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard.\ncontract ConfigurableCaller {\n bool doRevert = true;\n address target;\n bytes payload;\n\n event WhatHappened(bool success, bytes returndata);\n\n /**\n * @notice Call the configured target with the configured payload OR revert.\n */\n function call() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n } else {\n (bool success, bytes memory returndata) = address(target).call(payload);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n }\n\n /**\n * @notice Set whether or not to have `call` revert.\n */\n function setDoRevert(bool _doRevert) external {\n doRevert = _doRevert;\n }\n\n /**\n * @notice Set the target for the call made in `call`.\n */\n function setTarget(address _target) external {\n target = _target;\n }\n\n /**\n * @notice Set the payload for the call made in `call`.\n */\n function setPayload(bytes calldata _payload) external {\n payload = _payload;\n }\n\n /**\n * @notice Fallback function that reverts if `doRevert` is true.\n * Otherwise, it does nothing.\n */\n fallback() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n }\n }\n}\n" - }, - "contracts/test/CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, CallerCaller } from \"./CommonTest.t.sol\";\n\n// CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2\n// CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract.\ncontract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {\n // Ensure that baseGas passes for the max value of _minGasLimit,\n // this is about 4 Billion.\n function test_baseGas_succeeds() external view {\n L1Messenger.baseGas(hex\"ff\", type(uint32).max);\n }\n\n // Fuzz for other values which might cause a revert in baseGas.\n function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view {\n L1Messenger.baseGas(hex\"ff\", _minGasLimit);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest, Portal_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable } from \"../L2/CrossDomainOwnable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Vm, VmSafe } from \"forge-std/Vm.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract XDomainSetter is CrossDomainOwnable {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable_Test is CommonTest {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n setter = new XDomainSetter();\n }\n\n // Check that the revert message is correct\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable: caller is not the owner\");\n setter.set(1);\n }\n\n // Check that making a call can set the value properly\n function test_onlyOwner_succeeds() external {\n assertEq(setter.value(), 0);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(setter.owner()));\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n\ncontract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n\n vm.prank(alice);\n setter = new XDomainSetter();\n }\n\n function test_depositTransaction_crossDomainOwner_succeeds() external {\n vm.recordLogs();\n\n vm.prank(alice);\n op.depositTransaction({\n _to: address(setter),\n _value: 0,\n _gasLimit: 21_000,\n _isCreation: false,\n _data: abi.encodeWithSelector(XDomainSetter.set.selector, 1)\n });\n\n // Simulate the operation of the `op-node` by parsing data\n // from logs\n VmSafe.Log[] memory logs = vm.getRecordedLogs();\n // Only 1 log emitted\n assertEq(logs.length, 1);\n\n VmSafe.Log memory log = logs[0];\n\n // It is the expected topic\n bytes32 topic = log.topics[0];\n assertEq(topic, keccak256(\"TransactionDeposited(address,address,uint256,bytes)\"));\n\n // from is indexed and the first argument to the event.\n bytes32 _from = log.topics[1];\n address from = Bytes32AddressLib.fromLast20Bytes(_from);\n\n assertEq(AddressAliasHelper.undoL1ToL2Alias(from), alice);\n\n // Make a call from the \"from\" value received from the log.\n // In theory the opaque data could be parsed from the log\n // and passed to a low level call to \"to\", but calling set\n // directly on the setter is good enough.\n vm.prank(from);\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable2.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable2 } from \"../L2/CrossDomainOwnable2.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter2 is CrossDomainOwnable2 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable2_Test is Messenger_Initializer {\n XDomainSetter2 setter;\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter2();\n }\n\n function test_onlyOwner_notMessenger_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice));\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the owner\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner2_reverts() external {\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_onlyOwner_succeeds() external {\n address owner = setter.owner();\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n owner,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter2.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable3.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable3 } from \"../L2/CrossDomainOwnable3.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter3 is CrossDomainOwnable3 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable3_Test is Messenger_Initializer {\n XDomainSetter3 setter;\n\n /**\n * @notice OpenZeppelin Ownable.sol transferOwnership event\n */\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @notice CrossDomainOwnable3.sol transferOwnership event\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter3();\n }\n\n function test_constructor_succeeds() public {\n assertEq(setter.owner(), alice);\n assertEq(setter.isLocal(), true);\n }\n\n function test_localOnlyOwner_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_transferOwnership_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n }\n\n function test_crossDomainOnlyOwner_notOwner_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob);\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_crossDomainOnlyOwner_notOwner2_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter3.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_crossDomainOnlyOwner_notMessenger_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_transferOwnership_zeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"CrossDomainOwnable3: new owner is the zero address\");\n setter.transferOwnership({ _owner: address(0), _isLocal: true });\n }\n\n function test_transferOwnership_noLocalZeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"Ownable: new owner is the zero address\");\n setter.transferOwnership(address(0));\n }\n\n function test_localOnlyOwner_succeeds() public {\n assertEq(setter.isLocal(), true);\n vm.prank(setter.owner());\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n\n function test_localTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, true);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n\n assertEq(setter.isLocal(), true);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n /**\n * @notice The existing transferOwnership(address) method\n * still exists on the contract\n */\n function test_transferOwnershipNoLocal_succeeds() public {\n bool isLocal = setter.isLocal();\n\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n\n vm.prank(setter.owner());\n setter.transferOwnership(bob);\n\n // isLocal has not changed\n assertEq(setter.isLocal(), isLocal);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n function test_crossDomainTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n bob,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter3.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/DeployerWhitelist.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { DeployerWhitelist } from \"../legacy/DeployerWhitelist.sol\";\n\ncontract DeployerWhitelist_Test is CommonTest {\n DeployerWhitelist list;\n\n function setUp() public virtual override {\n list = new DeployerWhitelist();\n }\n\n // The owner should be address(0)\n function test_owner_succeeds() external {\n assertEq(list.owner(), address(0));\n }\n\n // The storage slot for the owner must be the same\n function test_storageSlots_succeeds() external {\n vm.prank(list.owner());\n list.setOwner(address(1));\n\n assertEq(bytes32(uint256(1)), vm.load(address(list), bytes32(uint256(0))));\n }\n}\n" - }, - "contracts/test/Encoding.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Encoding_Test is CommonTest {\n function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external {\n (uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(\n Encoding.encodeVersionedNonce(_nonce, _version)\n );\n assertEq(version, _version);\n assertEq(nonce, _nonce);\n }\n\n function testDiff_decodeVersionedNonce_succeeds(uint240 _nonce, uint16 _version) external {\n uint256 nonce = uint256(Encoding.encodeVersionedNonce(_nonce, _version));\n (uint256 decodedNonce, uint256 decodedVersion) = ffi.decodeVersionedNonce(nonce);\n\n assertEq(_version, uint16(decodedVersion));\n\n assertEq(_nonce, uint240(decodedNonce));\n }\n\n function testDiff_encodeCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint8 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint8 version = _version % 2;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory encoding = Encoding.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n bytes memory _encoding = ffi.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n assertEq(encoding, _encoding);\n }\n\n function testFuzz_encodeCrossDomainMessageV0_matchesLegacy_succeeds(\n uint240 _nonce,\n address _sender,\n address _target,\n bytes memory _data\n ) external {\n uint8 version = 0;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory legacyEncoding = LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _data,\n nonce\n );\n\n bytes memory bedrockEncoding = Encoding.encodeCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n nonce\n );\n\n assertEq(legacyEncoding, bedrockEncoding);\n }\n\n function testDiff_encodeDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bool isCreate,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n Types.UserDepositTransaction memory t = Types.UserDepositTransaction(\n _from,\n _to,\n isCreate,\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n );\n\n bytes memory txn = Encoding.encodeDepositTransaction(t);\n bytes memory _txn = ffi.encodeDepositTransaction(t);\n\n assertEq(txn, _txn);\n }\n}\n" - }, - "contracts/test/FeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { L1FeeVault } from \"../L2/L1FeeVault.sol\";\nimport { BaseFeeVault } from \"../L2/BaseFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n// Test the implementations of the FeeVault\ncontract FeeVault_Test is Bridge_Initializer {\n BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));\n L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT));\n\n address constant recipient = address(0x10000);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.BASE_FEE_VAULT, address(new BaseFeeVault(recipient)).code);\n vm.etch(Predeploys.L1_FEE_VAULT, address(new L1FeeVault(recipient)).code);\n\n vm.label(Predeploys.BASE_FEE_VAULT, \"BaseFeeVault\");\n vm.label(Predeploys.L1_FEE_VAULT, \"L1FeeVault\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(baseFeeVault.RECIPIENT(), recipient);\n assertEq(l1FeeVault.RECIPIENT(), recipient);\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n}\n" - }, - "contracts/test/GasPriceOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GasPriceOracle } from \"../L2/GasPriceOracle.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract GasPriceOracle_Test is CommonTest {\n event OverheadUpdated(uint256);\n event ScalarUpdated(uint256);\n event DecimalsUpdated(uint256);\n\n GasPriceOracle gasOracle;\n L1Block l1Block;\n address depositor;\n\n // set the initial L1 context values\n uint64 constant number = 10;\n uint64 constant timestamp = 11;\n uint256 constant basefee = 100;\n bytes32 constant hash = bytes32(uint256(64));\n uint64 constant sequenceNumber = 0;\n bytes32 constant batcherHash = bytes32(uint256(777));\n uint256 constant l1FeeOverhead = 310;\n uint256 constant l1FeeScalar = 10;\n\n function setUp() public virtual override {\n super.setUp();\n // place the L1Block contract at the predeploy address\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n\n l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n depositor = l1Block.DEPOSITOR_ACCOUNT();\n\n // We are not setting the gas oracle at its predeploy\n // address for simplicity purposes. Nothing in this test\n // requires it to be at a particular address\n gasOracle = new GasPriceOracle();\n\n vm.prank(depositor);\n l1Block.setL1BlockValues({\n _number: number,\n _timestamp: timestamp,\n _basefee: basefee,\n _hash: hash,\n _sequenceNumber: sequenceNumber,\n _batcherHash: batcherHash,\n _l1FeeOverhead: l1FeeOverhead,\n _l1FeeScalar: l1FeeScalar\n });\n }\n\n function test_l1BaseFee_succeeds() external {\n assertEq(gasOracle.l1BaseFee(), basefee);\n }\n\n function test_gasPrice_succeeds() external {\n vm.fee(100);\n uint256 gasPrice = gasOracle.gasPrice();\n assertEq(gasPrice, 100);\n }\n\n function test_baseFee_succeeds() external {\n vm.fee(64);\n uint256 gasPrice = gasOracle.baseFee();\n assertEq(gasPrice, 64);\n }\n\n function test_scalar_succeeds() external {\n assertEq(gasOracle.scalar(), l1FeeScalar);\n }\n\n function test_overhead_succeeds() external {\n assertEq(gasOracle.overhead(), l1FeeOverhead);\n }\n\n function test_decimals_succeeds() external {\n assertEq(gasOracle.decimals(), 6);\n assertEq(gasOracle.DECIMALS(), 6);\n }\n\n // Removed in bedrock\n function test_setGasPrice_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setGasPrice(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n\n // Removed in bedrock\n function test_setL1BaseFee_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setL1BaseFee(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n}\n" - }, - "contracts/test/GovernanceToken.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract GovernanceToken_Test is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n\n function setUp() public virtual override {\n super.setUp();\n vm.prank(owner);\n gov = new GovernanceToken();\n }\n\n function test_constructor_succeeds() external {\n assertEq(gov.owner(), owner);\n assertEq(gov.name(), \"Optimism\");\n assertEq(gov.symbol(), \"OP\");\n assertEq(gov.decimals(), 18);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_mint_fromOwner_succeeds() external {\n // Mint 100 tokens.\n vm.prank(owner);\n gov.mint(owner, 100);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 100);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_mint_fromNotOwner_reverts() external {\n // Mint 100 tokens as rando.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n gov.mint(owner, 100);\n\n // Balance does not update.\n assertEq(gov.balanceOf(owner), 0);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_burn_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando burns their tokens.\n vm.prank(rando);\n gov.burn(50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_burnFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to burn 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner burns 50 tokens from rando.\n vm.prank(owner);\n gov.burnFrom(rando, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_transfer_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando transfers 50 tokens to owner.\n vm.prank(rando);\n gov.transfer(owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_approve_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n\n function test_transferFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner transfers 50 tokens from rando to owner.\n vm.prank(owner);\n gov.transferFrom(rando, owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_increaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Rando increases allowance by 50 tokens.\n vm.prank(rando);\n gov.increaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 100);\n }\n\n function test_decreaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 100 tokens.\n vm.prank(rando);\n gov.approve(owner, 100);\n\n // Rando decreases allowance by 50 tokens.\n vm.prank(rando);\n gov.decreaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n}\n" - }, - "contracts/test/Hashing.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Hashing_hashDepositSource_Test is CommonTest {\n /**\n * @notice Tests that hashDepositSource returns the correct hash in a simple case.\n */\n function test_hashDepositSource_succeeds() external {\n assertEq(\n Hashing.hashDepositSource(\n 0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,\n 0x1\n ),\n 0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc\n );\n }\n}\n\ncontract Hashing_hashCrossDomainMessage_Test is CommonTest {\n /**\n * @notice Tests that hashCrossDomainMessage returns the correct hash in a simple case.\n */\n function testDiff_hashCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint16 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Ensure the version is valid.\n uint16 version = uint16(bound(uint256(_version), 0, 1));\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n assertEq(\n Hashing.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data),\n ffi.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n\n /**\n * @notice Tests that hashCrossDomainMessageV0 matches the hash of the legacy encoding.\n */\n function testFuzz_hashCrossDomainMessageV0_matchesLegacy_succeeds(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) external {\n assertEq(\n keccak256(\n LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _message,\n _messageNonce\n )\n ),\n Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _messageNonce)\n );\n }\n}\n\ncontract Hashing_hashWithdrawal_Test is CommonTest {\n /**\n * @notice Tests that hashWithdrawal returns the correct hash in a simple case.\n */\n function testDiff_hashWithdrawal_succeeds(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n assertEq(\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)\n ),\n ffi.hashWithdrawal(_nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n}\n\ncontract Hashing_hashOutputRootProof_Test is CommonTest {\n /**\n * @notice Tests that hashOutputRootProof returns the correct hash in a simple case.\n */\n function testDiff_hashOutputRootProof_succeeds(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external {\n assertEq(\n Hashing.hashOutputRootProof(\n Types.OutputRootProof({\n version: _version,\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _messagePasserStorageRoot,\n latestBlockhash: _latestBlockhash\n })\n ),\n ffi.hashOutputRootProof(\n _version,\n _stateRoot,\n _messagePasserStorageRoot,\n _latestBlockhash\n )\n );\n }\n}\n\ncontract Hashing_hashDepositTransaction_Test is CommonTest {\n /**\n * @notice Tests that hashDepositTransaction returns the correct hash in a simple case.\n */\n function testDiff_hashDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n assertEq(\n Hashing.hashDepositTransaction(\n Types.UserDepositTransaction(\n _from,\n _to,\n false, // isCreate\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n )\n ),\n ffi.hashDepositTransaction(_from, _to, _mint, _value, _gas, _data, _logIndex)\n );\n }\n}\n" - }, - "contracts/test/L1Block.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\ncontract L1BlockTest is CommonTest {\n L1Block lb;\n address depositor;\n bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));\n\n function setUp() public virtual override {\n super.setUp();\n lb = new L1Block();\n depositor = lb.DEPOSITOR_ACCOUNT();\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: uint64(1),\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: NON_ZERO_HASH,\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(0),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function testFuzz_updatesValues_succeeds(\n uint64 n,\n uint64 t,\n uint256 b,\n bytes32 h,\n uint64 s,\n bytes32 bt,\n uint256 fo,\n uint256 fs\n ) external {\n vm.prank(depositor);\n lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs);\n assertEq(lb.number(), n);\n assertEq(lb.timestamp(), t);\n assertEq(lb.basefee(), b);\n assertEq(lb.hash(), h);\n assertEq(lb.sequenceNumber(), s);\n assertEq(lb.batcherHash(), bt);\n assertEq(lb.l1FeeOverhead(), fo);\n assertEq(lb.l1FeeScalar(), fs);\n }\n\n function test_number_succeeds() external {\n assertEq(lb.number(), uint64(1));\n }\n\n function test_timestamp_succeeds() external {\n assertEq(lb.timestamp(), uint64(2));\n }\n\n function test_basefee_succeeds() external {\n assertEq(lb.basefee(), 3);\n }\n\n function test_hash_succeeds() external {\n assertEq(lb.hash(), NON_ZERO_HASH);\n }\n\n function test_sequenceNumber_succeeds() external {\n assertEq(lb.sequenceNumber(), uint64(4));\n }\n\n function test_updateValues_succeeds() external {\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: type(uint64).max,\n _timestamp: type(uint64).max,\n _basefee: type(uint256).max,\n _hash: keccak256(abi.encode(1)),\n _sequenceNumber: type(uint64).max,\n _batcherHash: bytes32(type(uint256).max),\n _l1FeeOverhead: type(uint256).max,\n _l1FeeScalar: type(uint256).max\n });\n }\n}\n" - }, - "contracts/test/L1BlockNumber.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { L1BlockNumber } from \"../legacy/L1BlockNumber.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract L1BlockNumberTest is Test {\n L1Block lb;\n L1BlockNumber bn;\n\n uint64 constant number = 99;\n\n function setUp() external {\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n lb = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n bn = new L1BlockNumber();\n vm.prank(lb.DEPOSITOR_ACCOUNT());\n\n lb.setL1BlockValues({\n _number: number,\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: bytes32(uint256(10)),\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(uint256(0)),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function test_getL1BlockNumber_succeeds() external {\n assertEq(bn.getL1BlockNumber(), number);\n }\n\n function test_fallback_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n\n function test_receive_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call{ value: 1 }(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n}\n" - }, - "contracts/test/L1CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle_Initializer } from \"./L2OutputOracle.t.sol\";\n\n/* Libraries */\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n/* Target contract dependencies */\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/* Target contract */\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\n\ncontract L1CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n // the version is encoded in the nonce\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce());\n assertEq(version, L1Messenger.MESSAGE_VERSION());\n }\n\n // sendMessage: should be able to send a single message\n // TODO: this same test needs to be done with the legacy message type\n // by setting the message version to 0\n function test_sendMessage_succeeds() external {\n // deposit transaction on the optimism portal should be called\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n )\n );\n\n // TransactionDeposited event\n vm.expectEmit(true, true, true, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n );\n\n // SentMessage event\n vm.expectEmit(true, true, true, true);\n emit SentMessage(recipient, alice, hex\"ff\", L1Messenger.messageNonce(), 100);\n\n // SentMessageExtension1 event\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(alice, 0);\n\n vm.prank(alice);\n L1Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n // sendMessage: should be able to send the same message twice\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L1Messenger.messageNonce());\n }\n\n function test_xDomainSender_notSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // xDomainMessageSender: should return the xDomainMsgSender address\n // TODO: might need a test contract\n // function test_xDomainSenderSetCorrectly() external {}\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(address(op));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n // relayMessage: should send a successful call to the target contract\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.expectCall(target, hex\"1111\");\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n // set the target to be the OptimismPortal\n address target = address(op);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.prank(address(op));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n\n vm.store(address(op), 0, bytes32(abi.encode(sender)));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: should revert if eth is sent from a contract other than the standard bridge\n function test_replayMessage_withValue_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.expectRevert(\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n L1Messenger.relayMessage{ value: 100 }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n vm.expectCall(target, hex\"1111\");\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n // relayMessage: Should revert if the recipient is trying to reenter with the\n // same message.\n function test_relayMessage_reentrancySameMessage_reverts() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory callMessage = abi.encodeWithSelector(caller.call.selector);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Set the portal's `l2Sender` to the `sender`.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(uint256(uint160(sender))));\n\n // Act as the portal and call the `relayMessage` function with the `innerMessage`.\n vm.prank(address(op));\n vm.expectCall(target, callMessage);\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message failed to be relayed\n assertFalse(L1Messenger.successfulMessages(hash));\n assertTrue(L1Messenger.failedMessages(hash));\n\n // Set the configurable caller's target to `L1Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L1Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L1Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n callMessage\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with the same message hash. The reentrancy attempt should\n // revert.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(\n false,\n abi.encodeWithSignature(\"Error(string)\", \"ReentrancyGuard: reentrant call\")\n );\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message still failed to be relayed.\n assertFalse(L1Messenger.successfulMessages(hash));\n assertTrue(L1Messenger.failedMessages(hash));\n }\n\n // relayMessage: should not revert if the recipient reenters `relayMessage` with a different\n // message hash.\n function test_relayMessage_reentrancyDiffMessage_succeeds() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory messageA = abi.encodeWithSelector(caller.call.selector);\n bytes memory messageB = hex\"\";\n\n bytes32 hashA = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n bytes32 hashB = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Set the portal's `l2Sender` to the `sender`.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(uint256(uint160(sender))));\n\n // Act as the portal and call the `relayMessage` function with both `messageA` and `messageB`.\n vm.startPrank(address(op));\n\n vm.expectCall(target, messageA);\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n vm.expectCall(target, messageB);\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Stop acting as the portal\n vm.stopPrank();\n\n // Assert that both messages failed to be relayed\n assertFalse(L1Messenger.successfulMessages(hashA));\n assertFalse(L1Messenger.successfulMessages(hashB));\n assertTrue(L1Messenger.failedMessages(hashA));\n assertTrue(L1Messenger.failedMessages(hashB));\n\n // Set the configurable caller's target to `L1Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L1Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L1Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageB\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with messageB. The reentrancy attempt should succeed\n // because the message hashes are different.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(true, hex\"\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n\n // Assert that both messages are now in the `successfulMessages` mapping.\n assertTrue(L1Messenger.successfulMessages(hashA));\n assertTrue(L1Messenger.successfulMessages(hashB));\n }\n\n function test_relayMessage_legacy_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyOldReplay_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Mark legacy message as already relayed.\n uint256 successfulMessagesSlot = 203;\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex\"1111\", 0);\n bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot));\n vm.store(address(L1Messenger), slot, bytes32(uint256(1)));\n\n // Expect revert.\n vm.expectRevert(\"CrossDomainMessenger: legacy withdrawal already relayed\");\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was not relayed.\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyRetryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect FailedRelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacyRetryAfterSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message has already been relayed\");\n\n // Retry the message again.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n}\n" - }, - "contracts/test/L1ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L1ERC721Bridge_Test is Messenger_Initializer {\n TestERC721 internal localToken;\n TestERC721 internal remoteToken;\n L1ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L1ERC721Bridge(address(L1Messenger), otherBridge);\n localToken = new TestERC721();\n remoteToken = new TestERC721();\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L1ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L1Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L1Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notEscrowed_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n" - }, - "contracts/test/L1StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\n\ncontract L1StandardBridge_Getter_Test is Bridge_Initializer {\n function test_getters_succeeds() external {\n assert(L1Bridge.l2TokenBridge() == address(L2Bridge));\n assert(L1Bridge.OTHER_BRIDGE() == L2Bridge);\n assert(L1Bridge.messenger() == L1Messenger);\n assert(L1Bridge.MESSENGER() == L1Messenger);\n assertEq(L1Bridge.version(), \"1.1.0\");\n }\n}\n\ncontract L1StandardBridge_Initialize_Test is Bridge_Initializer {\n function test_initialize_succeeds() external {\n assertEq(address(L1Bridge.messenger()), address(L1Messenger));\n\n assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE);\n\n assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE);\n }\n}\n\ncontract L1StandardBridge_Initialize_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_Receive_Test is Bridge_Initializer {\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(op).balance, 0);\n\n // The legacy event must be emitted for backwards compatibility\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n ),\n 200_000\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L1Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(op).balance, 100);\n }\n}\n\ncontract L1StandardBridge_Receive_TestFail {}\n\ncontract PreBridgeETH is Bridge_Initializer {\n function _preBridgeETH(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 500,\n hex\"dead\"\n );\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex\"dead\")\n );\n }\n vm.expectCall(\n address(L1Messenger),\n 500,\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 50000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 500,\n 50000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 50000);\n vm.expectCall(\n address(op),\n 500,\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 500,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(500),\n uint256(500),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 500, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 500, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 50000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 500);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETH_Test is PreBridgeETH {\n // depositETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_depositETH_succeeds() external {\n _preBridgeETH({ isLegacy: true });\n L1Bridge.depositETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_BridgeETH_Test is PreBridgeETH {\n // BridgeETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETH_succeeds() external {\n _preBridgeETH({ isLegacy: false });\n L1Bridge.bridgeETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer {\n function test_depositETH_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, address(L1Token).code);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice);\n L1Bridge.depositETH{ value: 1 }(300, hex\"\");\n }\n}\n\ncontract PreBridgeETHTo is Bridge_Initializer {\n function _preBridgeETHTo(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex\"dead\")\n );\n }\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n bob,\n 600,\n hex\"dead\"\n );\n\n // the L1 bridge should call\n // L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 60000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 600,\n 60000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 60000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 600,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(600),\n uint256(600),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, bob, 600, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, bob, 600, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 60000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 600);\n\n // deposit eth to bob\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo {\n // depositETHTo\n // - emits ETHDepositInitiated\n // - calls optimismPortal.depositTransaction\n // - EOA or contract can call\n // - ETH ends up in the optimismPortal\n function test_depositETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: true });\n L1Bridge.depositETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo {\n // BridgeETHTo\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: false });\n L1Bridge.bridgeETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // depositERC20\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - only callable by EOA\n function test_depositERC20_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Deal Alice's ERC20 State\n deal(address(L1Token), alice, 100000, true);\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n // The L1Bridge should transfer alice's tokens to itself\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)\n );\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n vm.prank(alice);\n L1Bridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex\"\");\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n }\n}\n\ncontract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer {\n function test_depositERC20_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, hex\"ffff\");\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice, alice);\n L1Bridge.depositERC20(address(0), address(0), 100, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {\n // depositERC20To\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - callable by a contract\n function test_depositERC20To_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n bob,\n 1000,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n deal(address(L1Token), alice, 100000, true);\n\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)\n );\n\n vm.prank(alice);\n L1Bridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex\"\");\n\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 1000);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeETHWithdrawal\n // - emits ETHWithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeETHWithdrawal_succeeds() external {\n uint256 aliceBalance = alice.balance;\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHWithdrawalFinalized(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n vm.expectCall(alice, hex\"\");\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n // ensure that the messenger has ETH to call with\n vm.deal(address(L1Bridge.messenger()), 100);\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n\n assertEq(address(L1Bridge.messenger()).balance, 0);\n assertEq(aliceBalance + 100, alice.balance);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeERC20Withdrawal\n // - updates bridge.deposits\n // - emits ERC20WithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeERC20Withdrawal_succeeds() external {\n deal(address(L1Token), address(L1Bridge), 100, true);\n\n uint256 slot = stdstore\n .target(address(L1Bridge))\n .sig(\"deposits(address,address)\")\n .with_key(address(L1Token))\n .with_key(address(L2Token))\n .find();\n\n // Give the L1 bridge some ERC20 tokens\n vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)\n );\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n assertEq(L1Token.balanceOf(address(L1Bridge)), 0);\n assertEq(L1Token.balanceOf(address(alice)), 100);\n }\n}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer {\n function test_finalizeERC20Withdrawal_notMessenger_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(28));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n\n function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(address(0)))\n );\n vm.prank(address(L1Bridge.messenger()));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer {\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L1Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L1Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce());\n assertEq(version, L2Messenger.MESSAGE_VERSION());\n }\n\n function test_sendMessage_succeeds() external {\n bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage(\n L2Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n );\n vm.expectCall(\n address(messagePasser),\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData\n )\n );\n\n // MessagePassed event\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(L2Messenger),\n address(L1Messenger),\n 0,\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData,\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messagePasser.messageNonce(),\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: L2Messenger.baseGas(hex\"ff\", 100),\n data: xDomainCallData\n })\n )\n );\n\n vm.prank(alice);\n L2Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L2Messenger.messageNonce();\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L2Messenger.messageNonce());\n }\n\n function test_xDomainSender_senderNotSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 2), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n vm.expectCall(target, hex\"1111\");\n\n vm.prank(caller);\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L2Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L2Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n address target = address(messagePasser);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory message = hex\"1111\";\n\n vm.prank(caller);\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retry_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n uint256 value = 100;\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(caller), value);\n vm.prank(caller);\n L2Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L2Messenger.successfulMessages(hash), false);\n assertEq(L2Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L2Messenger.successfulMessages(hash), true);\n assertEq(L2Messenger.failedMessages(hash), true);\n }\n\n // relayMessage: Should revert if the recipient is trying to reenter with the\n // same message.\n function test_relayMessage_reentrancySameMessage_reverts() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = address(L1Messenger);\n address l1XDMAlias = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory callMessage = abi.encodeWithSelector(caller.call.selector);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Act as the L1XDM and call the `relayMessage` function with the `innerMessage`.\n vm.prank(l1XDMAlias);\n vm.expectCall(target, callMessage);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message failed to be relayed\n assertFalse(L2Messenger.successfulMessages(hash));\n assertTrue(L2Messenger.failedMessages(hash));\n\n // Set the configurable caller's target to `L2Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L2Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L2Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with the same message hash. The reentrancy attempt should\n // revert.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(\n false,\n abi.encodeWithSignature(\"Error(string)\", \"ReentrancyGuard: reentrant call\")\n );\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message still failed to be relayed.\n assertFalse(L2Messenger.successfulMessages(hash));\n assertTrue(L2Messenger.failedMessages(hash));\n }\n\n // relayMessage: should not revert if the recipient reenters `relayMessage` with a different\n // message hash.\n function test_relayMessage_reentrancyDiffMessage_succeeds() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = address(L1Messenger);\n address l1XDMAlias = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory messageA = abi.encodeWithSelector(caller.call.selector);\n bytes memory messageB = hex\"\";\n\n bytes32 hashA = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n bytes32 hashB = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Act as the L1XDM and call the `relayMessage` function with both `messageA` and `messageB`.\n vm.startPrank(l1XDMAlias);\n\n vm.expectCall(target, messageA);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n vm.expectCall(target, messageB);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Stop acting as the L1XDM\n vm.stopPrank();\n\n // Assert that both messages failed to be relayed\n assertFalse(L2Messenger.successfulMessages(hashA));\n assertFalse(L2Messenger.successfulMessages(hashB));\n assertTrue(L2Messenger.failedMessages(hashA));\n assertTrue(L2Messenger.failedMessages(hashB));\n\n // Set the configurable caller's target to `L2Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L2Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L2Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageB\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with messageB. The reentrancy attempt should succeed\n // because the message hashes are different.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(true, hex\"\");\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n\n // Assert that both messages are now in the `successfulMessages` mapping.\n assertTrue(L2Messenger.successfulMessages(hashA));\n assertTrue(L2Messenger.successfulMessages(hashB));\n }\n}\n" - }, - "contracts/test/L2ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract TestMintableERC721 is OptimismMintableERC721 {\n constructor(address _bridge, address _remoteToken)\n OptimismMintableERC721(_bridge, 1, _remoteToken, \"Test\", \"TST\")\n {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L2ERC721Bridge_Test is Messenger_Initializer {\n TestMintableERC721 internal localToken;\n TestERC721 internal remoteToken;\n L2ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L2ERC721Bridge(address(L2Messenger), otherBridge);\n remoteToken = new TestERC721();\n localToken = new TestMintableERC721(address(bridge), address(remoteToken));\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L2ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L2Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L2Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L1ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_interfaceNotCompliant_reverts() external {\n // Create a non-compliant token\n NonCompliantERC721 nonCompliantToken = new NonCompliantERC721(alice);\n\n // Bridge the non-compliant token.\n vm.prank(alice);\n bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex\"5678\");\n\n // Attempt to finalize the withdrawal. Should revert because the token does not claim\n // to be compliant with the `IOptimismMintableERC721` interface.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token interface is not compliant\");\n bridge.finalizeBridgeERC721(\n address(address(nonCompliantToken)),\n address(address(0x01)),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_alreadyExists_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721: token already minted\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n\n/**\n * @dev A non-compliant ERC721 token that does not implement the full ERC721 interface.\n *\n * This is used to test that the bridge will revert if the token does not claim to support\n * the ERC721 interface.\n */\ncontract NonCompliantERC721 {\n address internal immutable owner;\n\n constructor(address _owner) {\n owner = _owner;\n }\n\n function ownerOf(uint256) external view returns (address) {\n return owner;\n }\n\n function remoteToken() external pure returns (address) {\n return address(0x01);\n }\n\n function burn(address, uint256) external {\n // Do nothing.\n }\n\n function supportsInterface(bytes4) external pure returns (bool) {\n return false;\n }\n}\n" - }, - "contracts/test/L2OutputOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { L2OutputOracle_Initializer, NextImpl } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2OutputOracleTest is L2OutputOracle_Initializer {\n bytes32 proposedOutput1 = keccak256(abi.encode(1));\n\n function test_constructor_succeeds() external {\n assertEq(oracle.PROPOSER(), proposer);\n assertEq(oracle.CHALLENGER(), owner);\n assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);\n assertEq(oracle.latestBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingTimestamp(), startingTimestamp);\n }\n\n function test_constructor_badTimestamp_reverts() external {\n vm.expectRevert(\"L2OutputOracle: starting L2 timestamp must be less than current time\");\n\n // startingTimestamp is in the future\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp + 1,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function test_constructor_l2BlockTimeZero_reverts() external {\n vm.expectRevert(\"L2OutputOracle: L2 block time must be greater than 0\");\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: 0,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function testFuzz_constructor_submissionIntervalLteL2BlockTime_reverts(\n uint256 _submissionInterval,\n uint256 _l2BlockTime\n ) external {\n // Bound the _l2blockTime to be in the range of [1, type(uint256).max]\n _l2BlockTime = bound(_l2BlockTime, 1, type(uint256).max);\n // Roll the block number to _l2blockTime (the starting L2 timestamp must be less than or equal to the current time)\n vm.roll(_l2BlockTime);\n // Bound _submissionInterval to be less than or equal to _l2BlockTime\n _submissionInterval = bound(_submissionInterval, 0, _l2BlockTime);\n\n vm.expectRevert(\"L2OutputOracle: submission interval must be greater than L2 block time\");\n new L2OutputOracle({\n _submissionInterval: _submissionInterval,\n _l2BlockTime: _l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n /****************\n * Getter Tests *\n ****************/\n\n // Test: latestBlockNumber() should return the correct value\n function test_latestBlockNumber_succeeds() external {\n uint256 proposedNumber = oracle.nextBlockNumber();\n\n // Roll to after the block number we'll propose\n warpToProposeTime(proposedNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0);\n assertEq(oracle.latestBlockNumber(), proposedNumber);\n }\n\n // Test: getL2Output() should return the correct value\n function test_getL2Output_succeeds() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0);\n\n Types.OutputProposal memory proposal = oracle.getL2Output(nextOutputIndex);\n assertEq(proposal.outputRoot, proposedOutput1);\n assertEq(proposal.timestamp, block.timestamp);\n\n // The block number is larger than the latest proposed output:\n vm.expectRevert(stdError.indexOOBError);\n oracle.getL2Output(nextOutputIndex + 1);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is exact block\n function test_getL2OutputIndexAfter_sameBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with exact same block as proposed returns the proposal.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is previous block\n function test_getL2OutputIndexAfter_previousBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with previous block returns the proposal too.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 - 1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value during binary search\n function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n bytes32 output2 = keccak256(abi.encode(2));\n uint256 nextBlockNumber2 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber2);\n vm.prank(proposer);\n oracle.proposeL2Output(output2, nextBlockNumber2, 0, 0);\n\n bytes32 output3 = keccak256(abi.encode(3));\n uint256 nextBlockNumber3 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber3);\n vm.prank(proposer);\n oracle.proposeL2Output(output3, nextBlockNumber3, 0, 0);\n\n bytes32 output4 = keccak256(abi.encode(4));\n uint256 nextBlockNumber4 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber4);\n vm.prank(proposer);\n oracle.proposeL2Output(output4, nextBlockNumber4, 0, 0);\n\n // Querying with a block number between the first and second proposal\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 + 1);\n assertEq(index1, 1);\n\n // Querying with a block number between the second and third proposal\n uint256 index2 = oracle.getL2OutputIndexAfter(nextBlockNumber2 + 1);\n assertEq(index2, 2);\n\n // Querying with a block number between the third and fourth proposal\n uint256 index3 = oracle.getL2OutputIndexAfter(nextBlockNumber3 + 1);\n assertEq(index3, 3);\n }\n\n // Test: getL2OutputIndexAfter() reverts when no output exists yet\n function test_getL2OutputIndexAfter_noOutputsExis_reverts() external {\n vm.expectRevert(\"L2OutputOracle: cannot get output as no outputs have been proposed yet\");\n oracle.getL2OutputIndexAfter(0);\n }\n\n // Test: nextBlockNumber() should return the correct value\n function test_nextBlockNumber_succeeds() external {\n assertEq(\n oracle.nextBlockNumber(),\n // The return value should match this arithmetic\n oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL()\n );\n }\n\n function test_computeL2Timestamp_succeeds() external {\n // reverts if timestamp is too low\n vm.expectRevert(stdError.arithmeticError);\n oracle.computeL2Timestamp(startingBlockNumber - 1);\n\n // returns the correct value...\n // ... for the very first block\n assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);\n\n // ... for the first block after the starting block\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 1),\n startingTimestamp + l2BlockTime\n );\n\n // ... for some other block number\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 96024),\n startingTimestamp + l2BlockTime * 96024\n );\n }\n\n /*****************************\n * Propose Tests - Happy Path *\n *****************************/\n\n // Test: proposeL2Output succeeds when given valid input, and no block hash and number are\n // specified.\n function test_proposeL2Output_proposeAnotherOutput_succeeds() public {\n bytes32 proposedOutput2 = keccak256(abi.encode());\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n uint256 proposedNumber = oracle.latestBlockNumber();\n\n // Ensure the submissionInterval is enforced\n assertEq(nextBlockNumber, proposedNumber + submissionInterval);\n\n vm.roll(nextBlockNumber + 1);\n\n vm.expectEmit(true, true, true, true);\n emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp);\n\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output succeeds when given valid input, and when a block hash and number are\n // specified for reorg protection.\n function test_proposeWithBlockhashAndHeight_succeeds() external {\n // Get the number and hash of a previous block in the chain\n uint256 prevL1BlockNumber = block.number - 1;\n bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber);\n }\n\n /***************************\n * Propose Tests - Sad Path *\n ***************************/\n\n // Test: proposeL2Output fails if called by a party that is not the proposer.\n function test_proposeL2Output_notProposer_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n\n vm.prank(address(128));\n vm.expectRevert(\"L2OutputOracle: only the proposer address can propose new outputs\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails given a zero blockhash.\n function test_proposeL2Output_emptyOutput_reverts() external {\n bytes32 outputToPropose = bytes32(0);\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: L2 output proposal cannot be the zero hash\");\n oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if the block number doesn't match the next expected number.\n function test_proposeL2Output_unexpectedBlockNumber_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: block number must be equal to next expected block number\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);\n }\n\n // Test: proposeL2Output fails if it would have a timestamp in the future.\n function test_proposeL2Output_futureTimetamp_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber);\n vm.warp(nextTimestamp);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: cannot propose L2 output in the future\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if a non-existent L1 block hash and number are provided for reorg\n // protection.\n function test_proposeL2Output_wrongFork_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(\n nonZeroHash,\n nextBlockNumber,\n bytes32(uint256(0x01)),\n block.number - 1\n );\n }\n\n // Test: proposeL2Output fails when given valid input, but the block hash and number do not\n // match.\n function test_proposeL2Output_unmatchedBlockhash_reverts() external {\n // Move ahead to block 100 so that we can reference historical blocks\n vm.roll(100);\n\n // Get the number and hash of a previous block in the chain\n uint256 l1BlockNumber = block.number - 1;\n bytes32 l1BlockHash = blockhash(l1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n\n // This will fail when foundry no longer returns zerod block hashes\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);\n }\n\n /*****************************\n * Delete Tests - Happy Path *\n *****************************/\n\n function test_deleteOutputs_singleOutput_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 1);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex);\n oracle.deleteL2Outputs(latestOutputIndex);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n function test_deleteOutputs_multipleOutputs_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 3);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n /***************************\n * Delete Tests - Sad Path *\n ***************************/\n\n function test_deleteL2Outputs_ifNotChallenger_reverts() external {\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.expectRevert(\"L2OutputOracle: only the challenger address can delete outputs\");\n oracle.deleteL2Outputs(latestBlockNumber);\n }\n\n function test_deleteL2Outputs_nonExistent_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestBlockNumber + 1);\n }\n\n function test_deleteL2Outputs_afterLatest_reverts() external {\n // Start by proposing three outputs\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Delete the latest two outputs\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n vm.prank(owner);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // Now try to delete the same output again\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n }\n\n function test_deleteL2Outputs_finalized_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Warp past the finalization period + 1 second\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n\n // Try to delete a finalized output\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs that have already been finalized\");\n oracle.deleteL2Outputs(latestOutputIndex);\n }\n}\n\ncontract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {\n Proxy internal proxy;\n\n function setUp() public override {\n super.setUp();\n proxy = Proxy(payable(address(oracle)));\n }\n\n function test_initValuesOnProxy_succeeds() external {\n assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());\n assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());\n assertEq(startingBlockNumber, oracleImpl.startingBlockNumber());\n assertEq(startingTimestamp, oracleImpl.startingTimestamp());\n\n assertEq(proposer, oracleImpl.PROPOSER());\n assertEq(owner, oracleImpl.CHALLENGER());\n }\n\n function test_initializeProxy_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(payable(proxy)).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_initializeImpl_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(oracleImpl).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(oracle), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(oracle), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(oracle)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/L2StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { console } from \"forge-std/console.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\ncontract L2StandardBridge_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n function test_initialize_succeeds() external {\n assertEq(address(L2Bridge.messenger()), address(L2Messenger));\n assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge));\n assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge));\n }\n\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(messagePasser).balance, 0);\n uint256 nonce = L2Messenger.messageNonce();\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 200_000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 100,\n 200_000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 100,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n // L2ToL1MessagePasser will emit a MessagePassed event\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 100,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 200_000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 100);\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L2Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(messagePasser).balance, 100);\n }\n\n // withrdraw\n // - requires amount == msg.value\n function test_withdraw_insufficientValue_reverts() external {\n assertEq(address(messagePasser).balance, 0);\n\n vm.expectRevert(\"StandardBridge: bridging ETH must include sufficient ETH value\");\n vm.prank(alice, alice);\n L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex\"\");\n }\n\n /**\n * @notice Use the legacy `withdraw` interface on the L2StandardBridge to\n * withdraw ether from L2 to L1.\n */\n function test_withdraw_ether_succeeds() external {\n assertTrue(alice.balance >= 100);\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0);\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated({\n l1Token: address(0),\n l2Token: Predeploys.LEGACY_ERC20_ETH,\n from: alice,\n to: alice,\n amount: 100,\n data: hex\"\"\n });\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex\"\" });\n\n vm.prank(alice, alice);\n L2Bridge.withdraw{ value: 100 }({\n _l2Token: Predeploys.LEGACY_ERC20_ETH,\n _amount: 100,\n _minGasLimit: 1000,\n _extraData: hex\"\"\n });\n\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 100);\n }\n}\n\ncontract PreBridgeERC20 is Bridge_Initializer {\n // withdraw and BridgeERC20 should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20(bool _isLegacy, address _l2Token) internal {\n // Alice has 100 L2Token\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(_l2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex\"\")\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20.selector,\n _l2Token,\n address(L1Token),\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n _l2Token,\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {\n // withdraw\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_withdraw_withdrawingERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // BridgeERC20\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdrawLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) });\n L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_bridgeLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) });\n L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdraw_notEOA_reverts() external {\n // This contract has 100 L2Token\n deal(address(L2Token), address(this), 100, true);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n }\n}\n\ncontract PreBridgeERC20To is Bridge_Initializer {\n // withdrawTo and BridgeERC20To should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal {\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(L2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n bob,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.withdrawTo.selector,\n _l2Token,\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20To.selector,\n _l2Token,\n address(L1Token),\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {\n // withdrawTo\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_withdrawTo_withdrawingERC20_succeeds() external {\n _preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // bridgeERC20To\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20To_succeeds() external {\n _preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex\"\");\n assertEq(L2Token.balanceOf(alice), 0);\n }\n}\n\ncontract L2StandardBridge_Bridge_Test is Bridge_Initializer {\n // finalizeDeposit\n // - only callable by l1TokenBridge\n // - supported token pair emits DepositFinalized\n // - invalid deposit calls Withdrawer.initiateWithdrawal\n function test_finalizeDeposit_depositingERC20_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex\"\");\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeDeposit_depositingETH_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(\n address(L2Token), // localToken\n address(L1Token), // remoteToken\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Messenger), 100, hex\"\");\n }\n}\n\ncontract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L2Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true);\n emit DepositFinalized(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2ToL1MessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\n\ncontract L2ToL1MessagePasserTest is CommonTest {\n L2ToL1MessagePasser messagePasser;\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new L2ToL1MessagePasser();\n }\n\n function testFuzz_initiateWithdrawal_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint256 nonce = messagePasser.messageNonce();\n\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: _value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash);\n\n vm.deal(_sender, _value);\n vm.prank(_sender);\n messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);\n\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0)));\n\n assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1)));\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by a contract\n function test_initiateWithdrawal_fromContract_succeeds() external {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\"\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\",\n withdrawalHash\n );\n\n vm.deal(address(this), 2**64);\n messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex\"\");\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by an EOA\n function test_initiateWithdrawal_fromEOA_succeeds() external {\n uint256 gasLimit = 64000;\n address target = address(4);\n uint256 value = 100;\n bytes memory data = hex\"ff\";\n uint256 nonce = messagePasser.messageNonce();\n\n // EOA emulation\n vm.prank(alice, alice);\n vm.deal(alice, 2**64);\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data)\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash);\n\n messagePasser.initiateWithdrawal{ value: value }(target, gasLimit, data);\n\n // the sent messages mapping is filled\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n // the nonce increments\n assertEq(nonce + 1, messagePasser.messageNonce());\n }\n\n // Test: burn should destroy the ETH held in the contract\n function test_burn_succeeds() external {\n messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n NON_ZERO_GASLIMIT,\n NON_ZERO_DATA\n );\n\n assertEq(address(messagePasser).balance, NON_ZERO_VALUE);\n vm.expectEmit(true, false, false, false);\n emit WithdrawerBalanceBurnt(NON_ZERO_VALUE);\n messagePasser.burn();\n\n // The Withdrawer should have no balance\n assertEq(address(messagePasser).balance, 0);\n }\n}\n" - }, - "contracts/test/LegacyERC20ETH.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyERC20ETH_Test is CommonTest {\n LegacyERC20ETH eth;\n\n function setUp() public virtual override {\n super.setUp();\n eth = new LegacyERC20ETH();\n }\n\n function test_metadata_succeeds() external {\n assertEq(eth.name(), \"Ether\");\n assertEq(eth.symbol(), \"ETH\");\n assertEq(eth.decimals(), 18);\n }\n\n function test_crossDomain_succeeds() external {\n assertEq(eth.l2Bridge(), Predeploys.L2_STANDARD_BRIDGE);\n assertEq(eth.l1Token(), address(0));\n }\n\n function test_transfer_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transfer is disabled\");\n eth.transfer(alice, 100);\n }\n\n function test_approve_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: approve is disabled\");\n eth.approve(alice, 100);\n }\n\n function test_transferFrom_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transferFrom is disabled\");\n eth.transferFrom(bob, alice, 100);\n }\n\n function test_increaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n eth.increaseAllowance(alice, 100);\n }\n\n function test_decreaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n eth.decreaseAllowance(alice, 100);\n }\n\n function test_mint_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: mint is disabled\");\n eth.mint(alice, 100);\n }\n\n function test_burn_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: burn is disabled\");\n eth.burn(alice, 100);\n }\n}\n" - }, - "contracts/test/LegacyMessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyMessagePasser } from \"../legacy/LegacyMessagePasser.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyMessagePasser_Test is CommonTest {\n LegacyMessagePasser messagePasser;\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new LegacyMessagePasser();\n }\n\n function test_passMessageToL1_succeeds() external {\n vm.prank(alice);\n messagePasser.passMessageToL1(hex\"ff\");\n assert(messagePasser.sentMessages(keccak256(abi.encodePacked(hex\"ff\", alice))));\n }\n}\n" - }, - "contracts/test/MerkleTrie.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MerkleTrie } from \"../libraries/trie/MerkleTrie.sol\";\n\ncontract MerkleTrie_get_Test is CommonTest {\n function test_get_validProof1_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579326262\";\n bytes memory val = hex\"6176616c32\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof2_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[\n 2\n ] = hex\"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof3_succeeds() external {\n bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof4_succeeds() external {\n bytes32 root = 0x37956bab6bba472308146808d5311ac19cb4a7daae5df7efcc0f32badc97f55e;\n bytes memory key = hex\"6b6579316161\";\n bytes memory val = hex\"3031323334\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"ce87206b6579316161853031323334\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof5_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657931\";\n bytes\n memory val = hex\"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof6_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657932\";\n bytes memory val = hex\"73686f7274\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[2] = hex\"df808080808080c9823262856176616c338080808080808080808573686f7274\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof7_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657933\";\n bytes memory val = hex\"31323334353637383930313233343536373839303132333435363738393031\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof8_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"61\";\n bytes memory val = hex\"61\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22061\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof9_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"62\";\n bytes memory val = hex\"62\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22062\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof10_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"63\";\n bytes memory val = hex\"63\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22063\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_nonexistentKey1_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b657932\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_nonexistentKey2_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"616e7972616e646f6d6b6579\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_wrongKeyProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579316161\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[2] = hex\"d687206e6f746865728d33343938683472697568677765\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_corruptedProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579326262\";\n bytes[] memory proof = new bytes[](5);\n proof[0] = hex\"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[\n 2\n ] = hex\"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 3\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[4] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidDataRemainder_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa000000000000000000000000000000\";\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidInternalNodeHash_reverts() external {\n bytes32 root = 0xa827dff1a657bb9bb9a1c3abe9db173e2f1359f15eb06f1647ea21ac7c95d8fa;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157\";\n proof[\n 1\n ] = hex\"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080\";\n proof[2] = hex\"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroBranchValueLength_reverts() external {\n bytes32 root = 0xe04b3589eef96b237cd49ccb5dcf6e654a47682bfa0961d563ab843f7ad1e035;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](2);\n proof[0] = hex\"dd8200aad98080808080808080808080c43b82aabbc43c82aacc80808080\";\n proof[1] = hex\"d98080808080808080808080c43b82aabbc43c82aacc80808080\";\n\n vm.expectRevert(\"MerkleTrie: value length must be greater than zero (branch)\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroLengthKey_reverts() external {\n bytes32 root = 0x54157fd62cdf2f474e7bfec2d3cd581e807bee38488c9590cb887add98936b73;\n bytes memory key = hex\"\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"c78320f00082b443\";\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey1_reverts() external {\n bytes32 root = 0xa513ba530659356fb7588a2c831944e80fd8aedaa5a4dc36f918152be2be0605;\n bytes memory key = hex\"01\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"db10d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[1] = hex\"d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[2] = hex\"c582202381aa\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey2_reverts() external {\n bytes32 root = 0xa06abffaec4ebe8ccde595f4547b864b4421b21c1fc699973f94710c9bc17979;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905\";\n proof[\n 1\n ] = hex\"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080\";\n proof[2] = hex\"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_extraProofElements_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](4);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa\";\n proof[3] = hex\"c32081aa\";\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_validProofs_succeeds(bytes4) external {\n // Generate a test case with a valid proof of inclusion for the k/v pair in the trie.\n (bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi\n .getMerkleTrieFuzzCase(\"valid\");\n\n // Assert that our expected value is equal to our actual value.\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidRoot_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"valid\"\n );\n\n bytes32 rootHash = keccak256(abi.encodePacked(root));\n vm.expectRevert(\"MerkleTrie: invalid root hash\");\n MerkleTrie.get(key, proof, rootHash);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_extraProofElements_reverts(bytes4) external {\n // Generate an invalid test case with an extra proof element attached to an otherwise\n // valid proof of inclusion for the passed k/v.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"extra_proof_elems\"\n );\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external {\n // Generate an invalid test case where a long proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_large_internal_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid large internal hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external {\n // Generate an invalid test case where a small proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_internal_node_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_corruptedProof_reverts(bytes4) external {\n // Generate an invalid test case where the proof is malformed.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"corrupted_proof\"\n );\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidDataRemainder_reverts(bytes4) external {\n // Generate an invalid test case where a random element of the proof has more bytes than the\n // length designates within the RLP list encoding.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_data_remainder\"\n );\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_prefixedValidKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and a valid key that is prefixed\n // with random bytes\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"prefixed_valid_key\"\n );\n\n // Ambiguous revert check- all that we care is that it *does* fail. This case may\n // fail within different branches.\n vm.expectRevert();\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_emptyKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and an empty key\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"empty_key\"\n );\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_partialProof_reverts(bytes4) external {\n // Get a random test case with a valid trie / partially correct proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"partial_proof\"\n );\n\n vm.expectRevert(\"MerkleTrie: ran out of proof elements\");\n MerkleTrie.get(key, proof, root);\n }\n}\n" - }, - "contracts/test/MintManager.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MintManager } from \"../governance/MintManager.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract MintManager_Initializer is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n MintManager internal manager;\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.prank(owner);\n gov = new GovernanceToken();\n\n vm.prank(owner);\n manager = new MintManager(owner, address(gov));\n\n vm.prank(owner);\n gov.transferOwnership(address(manager));\n }\n}\n\ncontract MintManager_constructor_Test is MintManager_Initializer {\n /**\n * @notice Tests that the constructor properly configures the contract.\n */\n function test_constructor_succeeds() external {\n assertEq(manager.owner(), owner);\n assertEq(address(manager.governanceToken()), address(gov));\n }\n}\n\ncontract MintManager_mint_Test is MintManager_Initializer {\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner.\n */\n function test_mint_fromOwner_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the mint function reverts when called by a non-owner.\n */\n function test_mint_fromNotOwner_reverts() external {\n // Mint from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.mint(owner, 100);\n }\n\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner a second\n * time after the mint period has elapsed.\n */\n function test_mint_afterPeriodElapsed_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again after period elapsed (2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n manager.mint(owner, 2);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 102);\n }\n\n /**\n * @notice Tests that the mint function always reverts when called before the mint period has\n * elapsed, even if the caller is the owner.\n */\n function test_mint_beforePeriodElapsed_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: minting not permitted yet\");\n manager.mint(owner, 100);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the owner cannot mint more than the mint cap.\n */\n function test_mint_moreThanCap_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again (greater than 2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint amount exceeds cap\");\n manager.mint(owner, 3);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n}\n\ncontract MintManager_upgrade_Test is MintManager_Initializer {\n /**\n * @notice Tests that the owner can upgrade the mint manager.\n */\n function test_upgrade_fromOwner_succeeds() external {\n // Upgrade to new manager.\n vm.prank(owner);\n manager.upgrade(rando);\n\n // New manager is rando.\n assertEq(gov.owner(), rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when called by a non-owner.\n */\n function test_upgrade_fromNotOwner_reverts() external {\n // Upgrade from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.upgrade(rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when attempting to update to the zero\n * address, even if the caller is the owner.\n */\n function test_upgrade_toZeroAddress_reverts() external {\n // Upgrade to zero address fails.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint manager cannot be the zero address\");\n manager.upgrade(address(0));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport {\n ILegacyMintableERC20,\n IOptimismMintableERC20\n} from \"../universal/IOptimismMintableERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract OptimismMintableERC20_Test is Bridge_Initializer {\n event Mint(address indexed account, uint256 amount);\n event Burn(address indexed account, uint256 amount);\n\n function test_semver_succeeds() external {\n assertEq(L2Token.version(), \"1.0.0\");\n }\n\n function test_remoteToken_succeeds() external {\n assertEq(L2Token.remoteToken(), address(L1Token));\n }\n\n function test_bridge_succeeds() external {\n assertEq(L2Token.bridge(), address(L2Bridge));\n }\n\n function test_l1Token_succeeds() external {\n assertEq(L2Token.l1Token(), address(L1Token));\n }\n\n function test_l2Bridge_succeeds() external {\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_legacy_succeeds() external {\n // Getters for the remote token\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.l1Token(), address(L1Token));\n // Getters for the bridge\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_mint_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 100);\n }\n\n function test_mint_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.mint(alice, 100);\n }\n\n function test_burn_succeeds() external {\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_burn_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.burn(alice, 100);\n }\n\n function test_erc165_supportsInterface_succeeds() external {\n // The assertEq calls in this test are comparing the manual calculation of the iface,\n // with what is returned by the solidity's type().interfaceId, just to be safe.\n bytes4 iface1 = bytes4(keccak256(\"supportsInterface(bytes4)\"));\n assertEq(iface1, type(IERC165).interfaceId);\n assert(L2Token.supportsInterface(iface1));\n\n bytes4 iface2 = L2Token.l1Token.selector ^ L2Token.mint.selector ^ L2Token.burn.selector;\n assertEq(iface2, type(ILegacyMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface2));\n\n bytes4 iface3 = L2Token.remoteToken.selector ^\n L2Token.bridge.selector ^\n L2Token.mint.selector ^\n L2Token.burn.selector;\n assertEq(iface3, type(IOptimismMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface3));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\n\ncontract OptimismMintableTokenFactory_Test is Bridge_Initializer {\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_bridge_succeeds() external {\n assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge));\n }\n\n function test_createStandardL2Token_succeeds() external {\n address remote = address(4);\n address local = LibRLP.computeAddress(address(L2TokenFactory), 2);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_sameTwice_succeeds() external {\n address remote = address(4);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n\n address local = LibRLP.computeAddress(address(L2TokenFactory), 3);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_remoteIsZero_succeeds() external {\n address remote = address(0);\n vm.expectRevert(\"OptimismMintableERC20Factory: must provide remote token address\");\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract OptimismMintableERC721_Test is ERC721Bridge_Initializer {\n ERC721 internal L1Token;\n OptimismMintableERC721 internal L2Token;\n\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n event Mint(address indexed account, uint256 tokenId);\n\n event Burn(address indexed account, uint256 tokenId);\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n L1Token = new ERC721(\"L1Token\", \"L1T\");\n L2Token = new OptimismMintableERC721(\n address(L2Bridge),\n 1,\n address(L1Token),\n \"L2Token\",\n \"L2T\"\n );\n\n // Label the addresses for nice traces.\n vm.label(address(L1Token), \"L1ERC721Token\");\n vm.label(address(L2Token), \"L2ERC721Token\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(L2Token.name(), \"L2Token\");\n assertEq(L2Token.symbol(), \"L2T\");\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.remoteChainId(), 1);\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.REMOTE_CHAIN_ID(), 1);\n assertEq(L2Token.version(), \"1.0.0\");\n }\n\n function test_safeMint_succeeds() external {\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(address(0), alice, 1);\n\n // Expect a mint event.\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 1);\n\n // Mint the token.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token should be owned by alice.\n assertEq(L2Token.ownerOf(1), alice);\n }\n\n function test_safeMint_notBridge_reverts() external {\n // Try to mint the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.safeMint(alice, 1);\n }\n\n function test_burn_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(alice, address(0), 1);\n\n // Expect a burn event.\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 1);\n\n // Burn the token.\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 1);\n\n // Token should be owned by address(0).\n vm.expectRevert(\"ERC721: invalid token ID\");\n L2Token.ownerOf(1);\n }\n\n function test_burn_notBridge_reverts() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Try to burn the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.burn(alice, 1);\n }\n\n function test_tokenURI_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token URI should be correct.\n assertEq(\n L2Token.tokenURI(1),\n string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(address(L1Token)), 20),\n \"@\",\n Strings.toString(1),\n \"/tokenURI?uint256=\",\n Strings.toString(1)\n )\n )\n );\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\n\ncontract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {\n OptimismMintableERC721Factory internal factory;\n\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n factory = new OptimismMintableERC721Factory(address(L2Bridge), 1);\n\n // Label the addresses for nice traces.\n vm.label(address(factory), \"OptimismMintableERC721Factory\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(factory.BRIDGE(), address(L2Bridge));\n assertEq(factory.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_succeeds() external {\n // Predict the address based on the factory address and nonce.\n address predicted = LibRLP.computeAddress(address(factory), 1);\n\n // Expect a token creation event.\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC721Created(predicted, address(1234), alice);\n\n // Create the token.\n vm.prank(alice);\n OptimismMintableERC721 created = OptimismMintableERC721(\n factory.createOptimismMintableERC721(address(1234), \"L2Token\", \"L2T\")\n );\n\n // Token address should be correct.\n assertEq(address(created), predicted);\n\n // Should be marked as created by the factory.\n assertEq(factory.isOptimismMintableERC721(address(created)), true);\n\n // Token should've been constructed correctly.\n assertEq(created.name(), \"L2Token\");\n assertEq(created.symbol(), \"L2T\");\n assertEq(created.REMOTE_TOKEN(), address(1234));\n assertEq(created.BRIDGE(), address(L2Bridge));\n assertEq(created.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_zeroRemoteToken_reverts() external {\n // Try to create a token with a zero remote token address.\n vm.expectRevert(\"OptimismMintableERC721Factory: L1 token address cannot be address(0)\");\n factory.createOptimismMintableERC721(address(0), \"L2Token\", \"L2T\");\n }\n}\n" - }, - "contracts/test/OptimismPortal.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { Portal_Initializer, CommonTest, NextImpl } from \"./CommonTest.t.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\ncontract OptimismPortal_Test is Portal_Initializer {\n event Paused(address);\n event Unpaused(address);\n\n function test_constructor_succeeds() external {\n assertEq(address(op.L2_ORACLE()), address(oracle));\n assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD);\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be paused by the GUARDIAN\n */\n function test_pause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n assertEq(op.paused(), false);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Paused(guardian);\n\n vm.prank(guardian);\n op.pause();\n\n assertEq(op.paused(), true);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not the\n * GUARDIAN calls `pause()`\n */\n function test_pause_onlyGuardian_reverts() external {\n assertEq(op.paused(), false);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can pause\");\n vm.prank(alice);\n op.pause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be unpaused by the GUARDIAN\n */\n function test_unpause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Unpaused(guardian);\n vm.prank(guardian);\n op.unpause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not\n * the GUARDIAN calls `unpause()`\n */\n function test_unpause_onlyGuardian_reverts() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can unpause\");\n vm.prank(alice);\n op.unpause();\n\n assertEq(op.paused(), true);\n }\n\n function test_receive_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex\"\");\n\n // give alice money and send as an eoa\n vm.deal(alice, 2**64);\n vm.prank(alice, alice);\n (bool s, ) = address(op).call{ value: 100 }(hex\"\");\n\n assert(s);\n assertEq(address(op).balance, 100);\n }\n\n // Test: depositTransaction fails when contract creation has a non-zero destination address\n function test_depositTransaction_contractCreation_reverts() external {\n // contract creation must have a target of address(0)\n vm.expectRevert(\"OptimismPortal: must send to address(0) when creating a contract\");\n op.depositTransaction(address(1), 1, 0, true, hex\"\");\n }\n\n /**\n * @notice Prevent gasless deposits from being force processed in L2 by\n * ensuring that they have a large enough gas limit set.\n */\n function test_depositTransaction_smallGasLimit_reverts() external {\n vm.expectRevert(\"OptimismPortal: gas limit must cover instrinsic gas cost\");\n op.depositTransaction({\n _to: address(1),\n _value: 0,\n _gasLimit: 0,\n _isCreation: false,\n _data: hex\"\"\n });\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a tx with 0 value\n function test_depositTransaction_noValueEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a tx with 0 value\n function test_depositTransaction_noValueContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndContractContractCreation_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n function test_simple_isOutputFinalized_succeeds() external {\n uint256 ts = block.timestamp;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))\n )\n );\n\n // warp to the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS());\n assertEq(op.isOutputFinalized(0), false);\n\n // warp past the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n assertEq(op.isOutputFinalized(0), true);\n }\n\n function test_isOutputFinalized_succeeds() external {\n uint256 checkpoint = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n vm.roll(checkpoint);\n vm.warp(oracle.computeL2Timestamp(checkpoint) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0);\n\n // warp to the final second of the finalization period\n uint256 finalizationHorizon = block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS();\n vm.warp(finalizationHorizon);\n // The checkpointed block should not be finalized until 1 second from now.\n assertEq(op.isOutputFinalized(nextOutputIndex), false);\n // Nor should a block after it\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n\n // warp past the finalization period\n vm.warp(finalizationHorizon + 1);\n // It should now be finalized.\n assertEq(op.isOutputFinalized(nextOutputIndex), true);\n // But not the block after it.\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n }\n}\n\ncontract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n // Utility function used in the subsequent test. This is necessary to assert that the\n // reentrant call will revert.\n function callPortalAndExpectRevert() external payable {\n vm.expectRevert(\"OptimismPortal: can only trigger one withdrawal per transaction\");\n // Arguments here don't matter, as the require check is the first thing that happens.\n // We assume that this has already been proven.\n op.finalizeWithdrawalTransaction(_defaultTx);\n // Assert that the withdrawal was not finalized.\n assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));\n }\n\n /**\n * @notice Proving withdrawal transactions should revert when paused\n */\n function test_proveWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.proveWithdrawalTransaction({\n _tx: _defaultTx,\n _l2OutputIndex: _proposedOutputIndex,\n _outputRootProof: _outputRootProof,\n _withdrawalProof: _withdrawalProof\n });\n }\n\n // Test: proveWithdrawalTransaction cannot prove a withdrawal with itself (the OptimismPortal) as the target.\n function test_proveWithdrawalTransaction_onSelfCall_reverts() external {\n _defaultTx.target = address(op);\n vm.expectRevert(\"OptimismPortal: you cannot send messages to the portal contract\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the outputRootProof does not match the output root\n function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external {\n // Modify the version to invalidate the withdrawal proof.\n _outputRootProof.version = bytes32(uint256(1));\n vm.expectRevert(\"OptimismPortal: invalid output root proof\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the proof is invalid due to non-existence of\n // the withdrawal.\n function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external {\n // modify the default test values to invalidate the proof.\n _defaultTx.data = hex\"abcd\";\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the passed transaction's withdrawalHash has\n // already been proven.\n function test_proveWithdrawalTransaction_replayProve_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: withdrawal hash has already been proven\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root has changed AND the l2BlockNumber stays the same.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in the OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a different output root within the `provenWithdrawals` mapping without\n // touching the l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root + output index + l2BlockNumber changes.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds()\n external\n {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a dummy output root within the `provenWithdrawals` mapping without touching the\n // l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle\n Types.OutputProposal memory proposal = op.L2_ORACLE().getL2Output(_proposedOutputIndex);\n\n // Propose the same output root again, creating the same output at a different index + l2BlockNumber.\n vm.startPrank(op.L2_ORACLE().PROPOSER());\n op.L2_ORACLE().proposeL2Output(\n proposal.outputRoot,\n op.L2_ORACLE().nextBlockNumber(),\n blockhash(block.number),\n block.number\n );\n vm.stopPrank();\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot + a different output index\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex + 1,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds and emits the WithdrawalProven event.\n function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: finalizeWithdrawalTransaction succeeds and emits the WithdrawalFinalized event.\n function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, false, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore + 100);\n }\n\n /**\n * @notice Finalizing withdrawal transactions should revert when paused\n */\n function test_finalizeWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has not been proven.\n function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectRevert(\"OptimismPortal: withdrawal has not been proven yet\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if withdrawal not proven long enough ago.\n function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Mock a call where the resulting output root is anything but the original output root. In\n // this case we just use bytes32(uint256(1)).\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(bytes32(uint256(1)), _proposedBlockNumber)\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the provenWithdrawal's timestamp is less\n // than the L2 output oracle's starting timestamp\n function test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a startingTimestamp change on the L2 Oracle\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSignature(\"startingTimestamp()\"),\n abi.encode(block.timestamp + 1)\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output root proven is not the same as the\n // output root at the time of finalization.\n function test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock an outputRoot change on the output proposal before attempting\n // to finalize the withdrawal.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n bytes32(uint256(0)),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output proposal's timestamp has\n // not passed the finalization period.\n function test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a timestamp change on the output proposal that has not passed the\n // finalization period.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(block.timestamp + 1),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\"OptimismPortal: output proposal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction fails because the target reverts,\n // and emits the WithdrawalFinalized event with success=false.\n function test_finalizeWithdrawalTransaction_targetFails_fails() external {\n uint256 bobBalanceBefore = address(bob).balance;\n vm.etch(bob, hex\"fe\"); // Contract with just the invalid opcode.\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, false);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the finalization period has not yet passed.\n function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external {\n // Setup the Oracle to return an output with a recent timestamp\n uint256 recentTimestamp = block.timestamp - 1000;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(recentTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has already been finalized.\n function test_finalizeWithdrawalTransaction_onReplay_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if insufficient gas is supplied.\n function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external {\n // This number was identified through trial and error.\n uint256 gasLimit = 150_000;\n Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: gasLimit,\n data: hex\"\"\n });\n\n // Get updated proof inputs.\n (bytes32 stateRoot, bytes32 storageRoot, , , bytes[] memory withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(insufficientGasTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n Hashing.hashOutputRootProof(outputRootProof),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n insufficientGasTx,\n _proposedOutputIndex,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectRevert(\"SafeCall: Not enough gas\");\n op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if a sub-call attempts to finalize another\n // withdrawal.\n function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Copy and modify the default test values to attempt a reentrant call by first calling to\n // this contract's callPortalAndExpectRevert() function above.\n Types.WithdrawalTransaction memory _testTx = _defaultTx;\n _testTx.target = address(this);\n _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector);\n\n // Get modified proof inputs.\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_testTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp.\n uint256 finalizedTimestamp = block.timestamp - oracle.FINALIZATION_PERIOD_SECONDS() - 1;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n outputRoot,\n uint128(finalizedTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(withdrawalHash, alice, address(this));\n op.proveWithdrawalTransaction(\n _testTx,\n _proposedBlockNumber,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectCall(address(this), _testTx.data);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_testTx);\n\n // Ensure that bob's balance was not changed by the reentrant call.\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n function testDiff_finalizeWithdrawalTransaction_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Cannot call the optimism portal\n vm.assume(_target != address(op));\n // Total ETH supply is currently about 120M ETH.\n uint256 value = bound(_value, 0, 200_000_000 ether);\n uint256 gasLimit = bound(_gasLimit, 0, 50_000_000);\n uint256 nonce = messagePasser.messageNonce();\n Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: value,\n gasLimit: gasLimit,\n data: _data\n });\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_tx);\n\n Types.OutputRootProof memory proof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n\n // Ensure the values returned from ffi are correct\n assertEq(outputRoot, Hashing.hashOutputRootProof(proof));\n assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx));\n\n // Mock the call to the oracle\n vm.mockCall(\n address(oracle),\n abi.encodeWithSelector(oracle.getL2Output.selector),\n abi.encode(outputRoot, 0)\n );\n\n // Start the withdrawal, it must be initiated by the _sender and the\n // correct value must be passed along\n vm.deal(_tx.sender, _tx.value);\n vm.prank(_tx.sender);\n messagePasser.initiateWithdrawal{ value: _tx.value }(_tx.target, _tx.gasLimit, _tx.data);\n\n // Ensure that the sentMessages is correct\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n op.proveWithdrawalTransaction(\n _tx,\n 100, // l2BlockNumber\n proof,\n withdrawalProof\n );\n }\n}\n\ncontract OptimismPortalUpgradeable_Test is Portal_Initializer {\n Proxy internal proxy;\n uint64 initialBlockNum;\n\n function setUp() public override {\n super.setUp();\n initialBlockNum = uint64(block.number);\n proxy = Proxy(payable(address(op)));\n }\n\n function test_params_initValuesOnProxy_succeeds() external {\n OptimismPortal p = OptimismPortal(payable(address(proxy)));\n\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = p.params();\n\n ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig();\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_initialize_cannotInitProxy_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(payable(proxy)).initialize(false);\n }\n\n function test_initialize_cannotInitImpl_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(opImpl).initialize(false);\n }\n\n function test_upgradeToAndCall_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(op), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(op)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/Proxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract SimpleStorage {\n mapping(uint256 => uint256) internal store;\n\n function get(uint256 key) external payable returns (uint256) {\n return store[key];\n }\n\n function set(uint256 key, uint256 value) external payable {\n store[key] = value;\n }\n}\n\ncontract Clasher {\n function upgradeTo(address) external pure {\n revert(\"upgradeTo\");\n }\n}\n\ncontract Proxy_Test is Test {\n event Upgraded(address indexed implementation);\n event AdminChanged(address previousAdmin, address newAdmin);\n\n address alice = address(64);\n\n bytes32 internal constant IMPLEMENTATION_KEY =\n bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1);\n\n bytes32 internal constant OWNER_KEY = bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1);\n\n Proxy proxy;\n SimpleStorage simpleStorage;\n\n function setUp() external {\n // Deploy a proxy and simple storage contract as\n // the implementation\n proxy = new Proxy(alice);\n simpleStorage = new SimpleStorage();\n\n vm.prank(alice);\n proxy.upgradeTo(address(simpleStorage));\n }\n\n function test_implementationKey_succeeds() external {\n // The hardcoded implementation key should be correct\n vm.prank(alice);\n proxy.upgradeTo(address(6));\n\n bytes32 key = vm.load(address(proxy), IMPLEMENTATION_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(6));\n }\n\n function test_ownerKey_succeeds() external {\n // The hardcoded owner key should be correct\n vm.prank(alice);\n proxy.changeAdmin(address(6));\n\n bytes32 key = vm.load(address(proxy), OWNER_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(address(6));\n address owner = proxy.admin();\n assertEq(owner, address(6));\n }\n\n function test_proxyCallToImp_notAdmin_succeeds() external {\n // The implementation does not have a `upgradeTo`\n // method, calling `upgradeTo` not as the owner\n // should revert.\n vm.expectRevert();\n proxy.upgradeTo(address(64));\n\n // Call `upgradeTo` as the owner, it should succeed\n // and emit the `Upgraded` event.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(64));\n vm.prank(alice);\n proxy.upgradeTo(address(64));\n\n // Get the implementation as the owner\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(64));\n }\n\n function test_ownerProxyCall_notAdmin_succeeds() external {\n // Calling `changeAdmin` not as the owner should revert\n // as the implementation does not have a `changeAdmin` method.\n vm.expectRevert();\n proxy.changeAdmin(address(1));\n\n // Call `changeAdmin` as the owner, it should succeed\n // and emit the `AdminChanged` event.\n vm.expectEmit(true, true, true, true);\n emit AdminChanged(alice, address(1));\n vm.prank(alice);\n proxy.changeAdmin(address(1));\n\n // Calling `admin` not as the owner should\n // revert as the implementation does not have\n // a `admin` method.\n vm.expectRevert();\n proxy.admin();\n\n // Calling `admin` as the owner should work.\n vm.prank(address(1));\n address owner = proxy.admin();\n assertEq(owner, address(1));\n }\n\n function test_delegatesToImpl_succeeds() external {\n // Call the storage setter on the proxy\n SimpleStorage(address(proxy)).set(1, 1);\n\n // The key should not be set in the implementation\n uint256 result = simpleStorage.get(1);\n assertEq(result, 0);\n {\n // The key should be set in the proxy\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n\n {\n // The owner should be able to call through the proxy\n // when there is not a function selector crash\n vm.prank(alice);\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n }\n\n function test_upgradeToAndCall_succeeds() external {\n {\n // There should be nothing in the current proxy storage\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 0);\n }\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(simpleStorage));\n vm.prank(alice);\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The call should have impacted the state\n uint256 result = SimpleStorage(address(proxy)).get(1);\n assertEq(result, 1);\n }\n\n function test_upgradeToAndCall_functionDoesNotExist_reverts() external {\n // Get the current implementation address\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call. This reverts because the calldata doesn't\n // match a function on the implementation.\n vm.expectRevert(\"Proxy: delegatecall to new implementation contract failed\");\n vm.prank(alice);\n proxy.upgradeToAndCall(address(simpleStorage), hex\"\");\n\n // The implementation address should have not\n // updated because the call to `upgradeToAndCall`\n // reverted.\n vm.prank(alice);\n address postImpl = proxy.implementation();\n assertEq(impl, postImpl);\n\n // The attempt to `upgradeToAndCall`\n // should revert when it is not called by the owner.\n vm.expectRevert();\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n }\n\n function test_upgradeToAndCall_isPayable_succeeds() external {\n // Give alice some funds\n vm.deal(alice, 1 ether);\n // Set the implementation and call and send\n // value.\n vm.prank(alice);\n proxy.upgradeToAndCall{ value: 1 ether }(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The implementation address should be correct\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // The proxy should have a balance\n assertEq(address(proxy).balance, 1 ether);\n }\n\n function test_upgradeTo_clashingFunctionSignatures_succeeds() external {\n // Clasher has a clashing function with the proxy.\n Clasher clasher = new Clasher();\n\n // Set the clasher as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(clasher));\n\n {\n // Assert that the implementation was set properly.\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(clasher));\n }\n\n // Call the clashing function on the proxy\n // not as the owner so that the call passes through.\n // The implementation will revert so we can be\n // sure that the call passed through.\n vm.expectRevert(bytes(\"upgradeTo\"));\n proxy.upgradeTo(address(0));\n\n {\n // Now call the clashing function as the owner\n // and be sure that it doesn't pass through to\n // the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(0));\n }\n }\n\n // Allow for `eth_call` to call proxy methods\n // by setting \"from\" to `address(0)`.\n function test_implementation_zeroAddressCaller_succeeds() external {\n vm.prank(address(0));\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n }\n\n function test_implementation_isZeroAddress_reverts() external {\n // Set `address(0)` as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n\n (bool success, bytes memory returndata) = address(proxy).call(hex\"\");\n assertEq(success, false);\n\n bytes memory err = abi.encodeWithSignature(\n \"Error(string)\",\n \"Proxy: implementation not initialized\"\n );\n\n assertEq(returndata, err);\n }\n}\n" - }, - "contracts/test/ProxyAdmin.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { SimpleStorage } from \"./Proxy.t.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\n\ncontract ProxyAdmin_Test is Test {\n address alice = address(64);\n\n Proxy proxy;\n L1ChugSplashProxy chugsplash;\n ResolvedDelegateProxy resolved;\n\n AddressManager addressManager;\n\n ProxyAdmin admin;\n\n SimpleStorage implementation;\n\n function setUp() external {\n // Deploy the proxy admin\n admin = new ProxyAdmin(alice);\n // Deploy the standard proxy\n proxy = new Proxy(address(admin));\n\n // Deploy the legacy L1ChugSplashProxy with the admin as the owner\n chugsplash = new L1ChugSplashProxy(address(admin));\n\n // Deploy the legacy AddressManager\n addressManager = new AddressManager();\n // The proxy admin must be the new owner of the address manager\n addressManager.transferOwnership(address(admin));\n // Deploy a legacy ResolvedDelegateProxy with the name `a`.\n // Whatever `a` is set to in AddressManager will be the address\n // that is used for the implementation.\n resolved = new ResolvedDelegateProxy(addressManager, \"a\");\n\n // Impersonate alice for setting up the admin.\n vm.startPrank(alice);\n // Set the address of the address manager in the admin so that it\n // can resolve the implementation address of legacy\n // ResolvedDelegateProxy based proxies.\n admin.setAddressManager(addressManager);\n // Set the reverse lookup of the ResolvedDelegateProxy\n // proxy\n admin.setImplementationName(address(resolved), \"a\");\n\n // Set the proxy types\n admin.setProxyType(address(proxy), ProxyAdmin.ProxyType.ERC1967);\n admin.setProxyType(address(chugsplash), ProxyAdmin.ProxyType.CHUGSPLASH);\n admin.setProxyType(address(resolved), ProxyAdmin.ProxyType.RESOLVED);\n vm.stopPrank();\n\n implementation = new SimpleStorage();\n }\n\n function test_setImplementationName_succeeds() external {\n vm.prank(alice);\n admin.setImplementationName(address(1), \"foo\");\n assertEq(admin.implementationName(address(1)), \"foo\");\n }\n\n function test_setAddressManager_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setAddressManager(AddressManager((address(0))));\n }\n\n function test_setImplementationName_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setImplementationName(address(0), \"foo\");\n }\n\n function test_setProxyType_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setProxyType(address(0), ProxyAdmin.ProxyType.CHUGSPLASH);\n }\n\n function test_owner_succeeds() external {\n assertEq(admin.owner(), alice);\n }\n\n function test_proxyType_succeeds() external {\n assertEq(uint256(admin.proxyType(address(proxy))), uint256(ProxyAdmin.ProxyType.ERC1967));\n assertEq(\n uint256(admin.proxyType(address(chugsplash))),\n uint256(ProxyAdmin.ProxyType.CHUGSPLASH)\n );\n assertEq(\n uint256(admin.proxyType(address(resolved))),\n uint256(ProxyAdmin.ProxyType.RESOLVED)\n );\n }\n\n function test_erc1967GetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(proxy));\n }\n\n function test_chugsplashGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(resolved));\n }\n\n function getProxyImplementation(address payable _proxy) internal {\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(0));\n }\n\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n }\n\n function test_erc1967GetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(resolved));\n }\n\n function getProxyAdmin(address payable _proxy) internal {\n address owner = admin.getProxyAdmin(_proxy);\n assertEq(owner, address(admin));\n }\n\n function test_erc1967ChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(resolved));\n }\n\n function changeProxyAdmin(address payable _proxy) internal {\n ProxyAdmin.ProxyType proxyType = admin.proxyType(address(_proxy));\n\n vm.prank(alice);\n admin.changeProxyAdmin(_proxy, address(128));\n\n // The proxy is no longer the admin and can\n // no longer call the proxy interface except for\n // the ResolvedDelegate type on which anybody can\n // call the admin interface.\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n vm.expectRevert(\"Proxy: implementation not initialized\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n vm.expectRevert(\"L1ChugSplashProxy: implementation is not set yet\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n // Just an empty block to show that all cases are covered\n } else {\n vm.expectRevert(\"ProxyAdmin: unknown proxy type\");\n }\n\n // Call the proxy contract directly to get the admin.\n // Different proxy types have different interfaces.\n vm.prank(address(128));\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n assertEq(Proxy(payable(_proxy)).admin(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n assertEq(L1ChugSplashProxy(payable(_proxy)).getOwner(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n assertEq(addressManager.owner(), address(128));\n } else {\n assert(false);\n }\n }\n\n function test_erc1967Upgrade_succeeds() external {\n upgrade(payable(proxy));\n }\n\n function test_chugsplashUpgrade_succeeds() external {\n upgrade(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgrade_succeeds() external {\n upgrade(payable(resolved));\n }\n\n function upgrade(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n\n function test_erc1967UpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(proxy));\n }\n\n function test_chugsplashUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(resolved));\n }\n\n function upgradeAndCall(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgradeAndCall(\n _proxy,\n address(implementation),\n abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1)\n );\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n\n uint256 got = SimpleStorage(address(_proxy)).get(1);\n assertEq(got, 1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.changeProxyAdmin(payable(proxy), address(0));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgrade(payable(proxy), address(implementation));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgradeAndCall(payable(proxy), address(implementation), hex\"\");\n }\n\n function test_isUpgrading_succeeds() external {\n assertEq(false, admin.isUpgrading());\n\n vm.prank(alice);\n admin.setUpgrading(true);\n assertEq(true, admin.isUpgrading());\n }\n}\n" - }, - "contracts/test/RLP.t.sol": { - "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\n/**\n * @title LibRLP\n * @notice Via https://github.com/Rari-Capital/solmate/issues/207.\n */\nlibrary LibRLP {\n using Bytes32AddressLib for bytes32;\n\n function computeAddress(address deployer, uint256 nonce) internal pure returns (address) {\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))\n .fromLast20Bytes();\n if (nonce <= 0x7f)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))\n .fromLast20Bytes();\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= type(uint8).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd7),\n bytes1(0x94),\n deployer,\n bytes1(0x81),\n uint8(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint16).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd8),\n bytes1(0x94),\n deployer,\n bytes1(0x82),\n uint16(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint24).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd9),\n bytes1(0x94),\n deployer,\n bytes1(0x83),\n uint24(nonce)\n )\n ).fromLast20Bytes();\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return\n keccak256(\n abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))\n ).fromLast20Bytes();\n }\n}\n" - }, - "contracts/test/RLPReader.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { RLPReader } from \"../libraries/rlp/RLPReader.sol\";\n\ncontract RLPReader_readBytes_Test is CommonTest {\n function test_readBytes_bytestring00_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"00\"), hex\"00\");\n }\n\n function test_readBytes_bytestring01_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"01\"), hex\"01\");\n }\n\n function test_readBytes_bytestring7f_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"7f\"), hex\"7f\");\n }\n\n function test_readBytes_revertListItem_reverts() external {\n vm.expectRevert(\"RLPReader: decoded item type for bytes is not a data item\");\n RLPReader.readBytes(hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_readBytes_invalidStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n RLPReader.readBytes(hex\"b9\");\n }\n\n function test_readBytes_invalidListLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n RLPReader.readBytes(hex\"ff\");\n }\n\n function test_readBytes_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: bytes value contains an invalid remainder\");\n RLPReader.readBytes(hex\"800a\");\n }\n\n function test_readBytes_invalidPrefix_reverts() external {\n vm.expectRevert(\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n RLPReader.readBytes(hex\"810a\");\n }\n}\n\ncontract RLPReader_readList_Test is CommonTest {\n function test_readList_empty_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c0\");\n assertEq(list.length, 0);\n }\n\n function test_readList_multiList_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c6827a77c10401\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"827a77\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c104\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"01\");\n }\n\n function test_readList_shortListMax1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n\n assertEq(list.length, 11);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[4]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[5]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[6]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[7]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[8]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[9]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[10]), hex\"8471776572\");\n }\n\n function test_readList_longList1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n\n assertEq(list.length, 4);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"cf84617364668471776572847a786376\");\n }\n\n function test_readList_longList2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n assertEq(list.length, 32);\n\n for (uint256 i = 0; i < 32; i++) {\n assertEq(RLPReader.readRawBytes(list[i]), hex\"cf84617364668471776572847a786376\");\n }\n }\n\n function test_readList_listLongerThan32Elements_reverts() external {\n vm.expectRevert(stdError.indexOOBError);\n RLPReader.readList(\n hex\"e1454545454545454545454545454545454545454545454545454545454545454545\"\n );\n }\n\n function test_readList_listOfLists_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c4c2c0c0c0\");\n assertEq(list.length, 2);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c2c0c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c0\");\n }\n\n function test_readList_listOfLists2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c7c0c1c0c3c0c1c0\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c1c0\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"c3c0c1c0\");\n }\n\n function test_readList_dictTest1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n assertEq(list.length, 4);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"ca846b6579318476616c31\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"ca846b6579328476616c32\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"ca846b6579338476616c33\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"ca846b6579348476616c34\");\n }\n\n function test_readList_invalidShortList_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efdebd\");\n }\n\n function test_readList_longStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efb83600\");\n }\n\n function test_readList_notLongEnough_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(\n hex\"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n );\n }\n\n function test_readList_int32Overflow_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"bf0f000000000000021111\");\n }\n\n function test_readList_int32Overflow2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ff0f000000000000021111\");\n }\n\n function test_readList_incorrectLengthInArray_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(hex\"b800\");\n }\n\n function test_readList_leadingZerosInLongLengthList1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must not have any leading zeros (long list)\");\n RLPReader.readList(\n hex\"fb00000040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_nonOptimalLongLengthArray1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b81000112233445566778899aabbccddeeff\");\n }\n\n function test_readList_nonOptimalLongLengthArray2_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b801ff\");\n }\n\n function test_readList_invalidValue_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n RLPReader.readList(hex\"91\");\n }\n\n function test_readList_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n RLPReader.readList(hex\"c000\");\n }\n\n function test_readList_notEnoughContentForString1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"ba010000aabbccddeeff\");\n }\n\n function test_readList_notEnoughContentForString2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"b840ffeeddccbbaa99887766554433221100\");\n }\n\n function test_readList_notEnoughContentForList1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"f90180\");\n }\n\n function test_readList_notEnoughContentForList2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ffffffffffffffffff0001020304050607\");\n }\n\n function test_readList_longStringLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b80100\");\n }\n\n function test_readList_longListLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long list)\");\n RLPReader.readList(hex\"f80100\");\n }\n}\n" - }, - "contracts/test/RLPWriter.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { RLPWriter } from \"../libraries/rlp/RLPWriter.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\n\ncontract RLPWriter_writeString_Test is CommonTest {\n function test_writeString_empty_succeeds() external {\n assertEq(RLPWriter.writeString(\"\"), hex\"80\");\n }\n\n function test_writeString_bytestring00_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0000\"), hex\"00\");\n }\n\n function test_writeString_bytestring01_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0001\"), hex\"01\");\n }\n\n function test_writeString_bytestring7f_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u007F\"), hex\"7f\");\n }\n\n function test_writeString_shortstring_succeeds() external {\n assertEq(RLPWriter.writeString(\"dog\"), hex\"83646f67\");\n }\n\n function test_writeString_shortstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing eli\"),\n hex\"b74c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69\"\n );\n }\n\n function test_writeString_longstring_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing elit\"),\n hex\"b8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974\"\n );\n }\n\n function test_writeString_longstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\n \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat\"\n ),\n hex\"b904004c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742e20437572616269747572206d6175726973206d61676e612c20737573636970697420736564207665686963756c61206e6f6e2c20696163756c697320666175636962757320746f72746f722e2050726f696e20737573636970697420756c74726963696573206d616c6573756164612e204475697320746f72746f7220656c69742c2064696374756d2071756973207472697374697175652065752c20756c7472696365732061742072697375732e204d6f72626920612065737420696d70657264696574206d6920756c6c616d636f7270657220616c6971756574207375736369706974206e6563206c6f72656d2e2041656e65616e2071756973206c656f206d6f6c6c69732c2076756c70757461746520656c6974207661726975732c20636f6e73657175617420656e696d2e204e756c6c6120756c74726963657320747572706973206a7573746f2c20657420706f73756572652075726e6120636f6e7365637465747572206e65632e2050726f696e206e6f6e20636f6e76616c6c6973206d657475732e20446f6e65632074656d706f7220697073756d20696e206d617572697320636f6e67756520736f6c6c696369747564696e2e20566573746962756c756d20616e746520697073756d207072696d697320696e206661756369627573206f726369206c756374757320657420756c74726963657320706f737565726520637562696c69612043757261653b2053757370656e646973736520636f6e76616c6c69732073656d2076656c206d617373612066617563696275732c2065676574206c6163696e6961206c616375732074656d706f722e204e756c6c61207175697320756c747269636965732070757275732e2050726f696e20617563746f722072686f6e637573206e69626820636f6e64696d656e74756d206d6f6c6c69732e20416c697175616d20636f6e73657175617420656e696d206174206d65747573206c75637475732c206120656c656966656e6420707572757320656765737461732e20437572616269747572206174206e696268206d657475732e204e616d20626962656e64756d2c206e6571756520617420617563746f72207472697374697175652c206c6f72656d206c696265726f20616c697175657420617263752c206e6f6e20696e74657264756d2074656c6c7573206c65637475732073697420616d65742065726f732e20437261732072686f6e6375732c206d65747573206163206f726e617265206375727375732c20646f6c6f72206a7573746f20756c747269636573206d657475732c20617420756c6c616d636f7270657220766f6c7574706174\"\n );\n }\n}\n\ncontract RLPWriter_writeUint_Test is CommonTest {\n function test_writeUint_zero_succeeds() external {\n assertEq(RLPWriter.writeUint(0x0), hex\"80\");\n }\n\n function test_writeUint_smallint_succeeds() external {\n assertEq(RLPWriter.writeUint(1), hex\"01\");\n }\n\n function test_writeUint_smallint2_succeeds() external {\n assertEq(RLPWriter.writeUint(16), hex\"10\");\n }\n\n function test_writeUint_smallint3_succeeds() external {\n assertEq(RLPWriter.writeUint(79), hex\"4f\");\n }\n\n function test_writeUint_smallint4_succeeds() external {\n assertEq(RLPWriter.writeUint(127), hex\"7f\");\n }\n\n function test_writeUint_mediumint_succeeds() external {\n assertEq(RLPWriter.writeUint(128), hex\"8180\");\n }\n\n function test_writeUint_mediumint2_succeeds() external {\n assertEq(RLPWriter.writeUint(1000), hex\"8203e8\");\n }\n\n function test_writeUint_mediumint3_succeeds() external {\n assertEq(RLPWriter.writeUint(100000), hex\"830186a0\");\n }\n}\n\ncontract RLPWriter_writeList_Test is CommonTest {\n function test_writeList_empty_succeeds() external {\n assertEq(RLPWriter.writeList(new bytes[](0)), hex\"c0\");\n }\n\n function test_writeList_stringList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeString(\"dog\");\n list[1] = RLPWriter.writeString(\"god\");\n list[2] = RLPWriter.writeString(\"cat\");\n\n assertEq(RLPWriter.writeList(list), hex\"cc83646f6783676f6483636174\");\n }\n\n function test_writeList_multiList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeUint(4);\n\n list[0] = RLPWriter.writeString(\"zw\");\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeUint(1);\n\n assertEq(RLPWriter.writeList(list), hex\"c6827a77c10401\");\n }\n\n function test_writeList_shortListMax1_succeeds() external {\n bytes[] memory list = new bytes[](11);\n list[0] = RLPWriter.writeString(\"asdf\");\n list[1] = RLPWriter.writeString(\"qwer\");\n list[2] = RLPWriter.writeString(\"zxcv\");\n list[3] = RLPWriter.writeString(\"asdf\");\n list[4] = RLPWriter.writeString(\"qwer\");\n list[5] = RLPWriter.writeString(\"zxcv\");\n list[6] = RLPWriter.writeString(\"asdf\");\n list[7] = RLPWriter.writeString(\"qwer\");\n list[8] = RLPWriter.writeString(\"zxcv\");\n list[9] = RLPWriter.writeString(\"asdf\");\n list[10] = RLPWriter.writeString(\"qwer\");\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n }\n\n function test_writeList_longlist1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list2);\n list[3] = RLPWriter.writeList(list2);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_longlist2_succeeds() external {\n bytes[] memory list = new bytes[](32);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n for (uint256 i = 0; i < 32; i++) {\n list[i] = RLPWriter.writeList(list2);\n }\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_listoflists_succeeds() external {\n // [ [ [], [] ], [] ]\n bytes[] memory list = new bytes[](2);\n bytes[] memory list2 = new bytes[](2);\n\n list2[0] = RLPWriter.writeList(new bytes[](0));\n list2[1] = RLPWriter.writeList(new bytes[](0));\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(new bytes[](0));\n\n assertEq(RLPWriter.writeList(list), hex\"c4c2c0c0c0\");\n }\n\n function test_writeList_listoflists2_succeeds() external {\n // [ [], [[]], [ [], [[]] ] ]\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeList(new bytes[](0));\n\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeList(new bytes[](0));\n\n list[1] = RLPWriter.writeList(list2);\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeList(new bytes[](0));\n list3[1] = RLPWriter.writeList(list2);\n\n list[2] = RLPWriter.writeList(list3);\n\n assertEq(RLPWriter.writeList(list), hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_writeList_dictTest1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n\n bytes[] memory list1 = new bytes[](2);\n list1[0] = RLPWriter.writeString(\"key1\");\n list1[1] = RLPWriter.writeString(\"val1\");\n\n bytes[] memory list2 = new bytes[](2);\n list2[0] = RLPWriter.writeString(\"key2\");\n list2[1] = RLPWriter.writeString(\"val2\");\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeString(\"key3\");\n list3[1] = RLPWriter.writeString(\"val3\");\n\n bytes[] memory list4 = new bytes[](2);\n list4[0] = RLPWriter.writeString(\"key4\");\n list4[1] = RLPWriter.writeString(\"val4\");\n\n list[0] = RLPWriter.writeList(list1);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list3);\n list[3] = RLPWriter.writeList(list4);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n }\n}\n" - }, - "contracts/test/ResolvedDelegateProxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\n\ncontract ResolvedDelegateProxy_Test is Test {\n AddressManager internal addressManager;\n SimpleImplementation internal impl;\n SimpleImplementation internal proxy;\n\n function setUp() public {\n // Set up the address manager.\n addressManager = new AddressManager();\n impl = new SimpleImplementation();\n addressManager.setAddress(\"SimpleImplementation\", address(impl));\n\n // Set up the proxy.\n proxy = SimpleImplementation(\n address(new ResolvedDelegateProxy(addressManager, \"SimpleImplementation\"))\n );\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall succeeds.\n function testFuzz_fallback_delegateCallFoo_succeeds(uint256 x) public {\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.foo.selector, x));\n assertEq(proxy.foo(x), x);\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall reverts.\n function test_fallback_delegateCallBar_reverts() public {\n vm.expectRevert(\"SimpleImplementation: revert\");\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.bar.selector));\n proxy.bar();\n }\n\n // Tests that the proxy fallback reverts as expected if the implementation within the\n // address manager is not set.\n function test_fallback_addressManagerNotSet_reverts() public {\n AddressManager am = new AddressManager();\n SimpleImplementation p = SimpleImplementation(\n address(new ResolvedDelegateProxy(am, \"SimpleImplementation\"))\n );\n\n vm.expectRevert(\"ResolvedDelegateProxy: target address must be initialized\");\n p.foo(0);\n }\n}\n\ncontract SimpleImplementation {\n function foo(uint256 _x) public pure returns (uint256) {\n return _x;\n }\n\n function bar() public pure {\n revert(\"SimpleImplementation: revert\");\n }\n}\n" - }, - "contracts/test/ResourceMetering.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract MeterUser is ResourceMetering {\n constructor() {\n initialize();\n }\n\n function initialize() public initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public pure returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function use(uint64 _amount) public metered(_amount) {}\n\n function set(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) public {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n}\n\n/**\n * @title ResourceConfig\n * @notice The tests are based on the default config values. It is expected that\n * the config values used in these tests are ran in production.\n */\ncontract ResourceMetering_Test is Test {\n MeterUser internal meter;\n uint64 initialBlockNum;\n\n function setUp() public {\n meter = new MeterUser();\n initialBlockNum = uint64(block.number);\n }\n\n function test_meter_initialResourceParams_succeeds() external {\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_updateParamsNoChange_succeeds() external {\n meter.use(0); // equivalent to just updating the base fee and block number\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n meter.use(0);\n (uint128 postBaseFee, uint64 postBoughtGas, uint64 postBlockNum) = meter.params();\n\n assertEq(postBaseFee, prevBaseFee);\n assertEq(postBoughtGas, prevBoughtGas);\n assertEq(postBlockNum, prevBlockNum);\n }\n\n function test_meter_updateOneEmptyBlock_succeeds() external {\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 1);\n }\n\n function test_meter_updateTwoEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 2);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 2);\n }\n\n function test_meter_updateTenEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 10);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 10);\n }\n\n function test_meter_updateNoGasDelta_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint256 target = uint256(rcfg.maxResourceLimit) / uint256(rcfg.elasticityMultiplier);\n meter.use(uint64(target));\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1000000000);\n assertEq(prevBoughtGas, target);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_useMax_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n meter.use(target * elasticityMultiplier);\n\n (, uint64 prevBoughtGas, ) = meter.params();\n assertEq(prevBoughtGas, target * elasticityMultiplier);\n\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 postBaseFee, , ) = meter.params();\n assertEq(postBaseFee, 2125000000);\n }\n\n function test_meter_useMoreThanMax_reverts() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.expectRevert(\"ResourceMetering: cannot buy more gas than available gas limit\");\n meter.use(target * elasticityMultiplier + 1);\n }\n\n // Demonstrates that the resource metering arithmetic can tolerate very large gaps between\n // deposits.\n function testFuzz_meter_largeBlockDiff_succeeds(uint64 _amount, uint256 _blockDiff) external {\n // This test fails if the following line is commented out.\n // At 12 seconds per block, this number is effectively unreachable.\n vm.assume(_blockDiff < 433576281058164217753225238677900874458691);\n\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.assume(_amount < target * elasticityMultiplier);\n vm.roll(initialBlockNum + _blockDiff);\n meter.use(_amount);\n }\n}\n\n/**\n * @title CustomMeterUser\n * @notice A simple wrapper around `ResourceMetering` that allows the initial\n * params to be set in the constructor.\n */\ncontract CustomMeterUser is ResourceMetering {\n uint256 public startGas;\n uint256 public endGas;\n\n constructor(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function use(uint64 _amount) public returns (uint256) {\n uint256 initialGas = gasleft();\n _metered(_amount, initialGas);\n return initialGas - gasleft();\n }\n}\n\n/**\n * @title ArtifactResourceMetering_Test\n * @notice A table test that sets the state of the ResourceParams and then requests\n * various amounts of gas. This test ensures that a wide range of values\n * can safely be used with the `ResourceMetering` contract.\n * It also writes a CSV file to disk that includes useful information\n * about how much gas is used and how expensive it is in USD terms to\n * purchase the deposit gas.\n */\ncontract ArtifactResourceMetering_Test is Test {\n uint128 internal minimumBaseFee;\n uint128 internal maximumBaseFee;\n uint64 internal maxResourceLimit;\n uint64 internal targetResourceLimit;\n\n string internal outfile;\n\n // keccak256(abi.encodeWithSignature(\"Error(string)\", \"ResourceMetering: cannot buy more gas than available gas limit\"))\n bytes32 internal cannotBuyMoreGas =\n 0x84edc668cfd5e050b8999f43ff87a1faaa93e5f935b20bc1dd4d3ff157ccf429;\n // keccak256(abi.encodeWithSignature(\"Panic(uint256)\", 0x11))\n bytes32 internal overflowErr =\n 0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;\n // keccak256(hex\"\")\n bytes32 internal emptyReturnData =\n 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n\n /**\n * @notice Sets up the tests by getting constants from the ResourceMetering\n * contract.\n */\n function setUp() public {\n vm.roll(1_000_000);\n\n MeterUser base = new MeterUser();\n ResourceMetering.ResourceConfig memory rcfg = base.resourceConfig();\n minimumBaseFee = uint128(rcfg.minimumBaseFee);\n maximumBaseFee = rcfg.maximumBaseFee;\n maxResourceLimit = uint64(rcfg.maxResourceLimit);\n targetResourceLimit = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n\n outfile = string.concat(vm.projectRoot(), \"/.resource-metering.csv\");\n try vm.removeFile(outfile) {} catch {}\n }\n\n /**\n * @notice Generate a CSV file. The call to `meter` should be called with at\n * most the L1 block gas limit. Without specifying the amount of\n * gas, it can take very long to execute.\n */\n function test_meter_generateArtifact_succeeds() external {\n vm.writeLine(\n outfile,\n \"prevBaseFee,prevBoughtGas,prevBlockNumDiff,l1BaseFee,requestedGas,gasConsumed,ethPrice,usdCost,success\"\n );\n\n // prevBaseFee value in ResourceParams\n uint128[] memory prevBaseFees = new uint128[](5);\n prevBaseFees[0] = minimumBaseFee;\n prevBaseFees[1] = maximumBaseFee;\n prevBaseFees[2] = uint128(50 gwei);\n prevBaseFees[3] = uint128(100 gwei);\n prevBaseFees[4] = uint128(200 gwei);\n\n // prevBoughtGas value in ResourceParams\n uint64[] memory prevBoughtGases = new uint64[](1);\n prevBoughtGases[0] = uint64(0);\n\n // prevBlockNum diff, simulates blocks with no deposits when non zero\n uint64[] memory prevBlockNumDiffs = new uint64[](2);\n prevBlockNumDiffs[0] = 0;\n prevBlockNumDiffs[1] = 1;\n\n // The amount of L2 gas that a user requests\n uint64[] memory requestedGases = new uint64[](3);\n requestedGases[0] = maxResourceLimit;\n requestedGases[1] = targetResourceLimit;\n requestedGases[2] = uint64(100_000);\n\n // The L1 base fee\n uint256[] memory l1BaseFees = new uint256[](4);\n l1BaseFees[0] = 1 gwei;\n l1BaseFees[1] = 50 gwei;\n l1BaseFees[2] = 75 gwei;\n l1BaseFees[3] = 100 gwei;\n\n // USD price of 1 ether\n uint256[] memory ethPrices = new uint256[](2);\n ethPrices[0] = 1600;\n ethPrices[1] = 3200;\n\n // Iterate over all of the test values and run a test\n for (uint256 i; i < prevBaseFees.length; i++) {\n for (uint256 j; j < prevBoughtGases.length; j++) {\n for (uint256 k; k < prevBlockNumDiffs.length; k++) {\n for (uint256 l; l < requestedGases.length; l++) {\n for (uint256 m; m < l1BaseFees.length; m++) {\n for (uint256 n; n < ethPrices.length; n++) {\n uint256 snapshotId = vm.snapshot();\n\n uint128 prevBaseFee = prevBaseFees[i];\n uint64 prevBoughtGas = prevBoughtGases[j];\n uint64 prevBlockNumDiff = prevBlockNumDiffs[k];\n uint64 requestedGas = requestedGases[l];\n uint256 l1BaseFee = l1BaseFees[m];\n uint256 ethPrice = ethPrices[n];\n string memory result = \"success\";\n\n vm.fee(l1BaseFee);\n\n CustomMeterUser meter = new CustomMeterUser({\n _prevBaseFee: prevBaseFee,\n _prevBoughtGas: prevBoughtGas,\n _prevBlockNum: uint64(block.number)\n });\n\n vm.roll(block.number + prevBlockNumDiff);\n\n // Call the metering code and catch the various\n // types of errors.\n uint256 gasConsumed = 0;\n try meter.use{ gas: 30_000_000 }(requestedGas) returns (\n uint256 _gasConsumed\n ) {\n gasConsumed = _gasConsumed;\n } catch (bytes memory err) {\n bytes32 hash = keccak256(err);\n if (hash == cannotBuyMoreGas) {\n result = \"ResourceMetering: cannot buy more gas than available gas limit\";\n } else if (hash == overflowErr) {\n result = \"arithmetic overflow/underflow\";\n } else if (hash == emptyReturnData) {\n result = \"out of gas\";\n } else {\n result = \"UNKNOWN ERROR\";\n }\n }\n\n // Compute the USD cost of the gas used\n uint256 usdCost = (gasConsumed * l1BaseFee * ethPrice) / 1 ether;\n\n vm.writeLine(\n outfile,\n string.concat(\n vm.toString(prevBaseFee),\n \",\",\n vm.toString(prevBoughtGas),\n \",\",\n vm.toString(prevBlockNumDiff),\n \",\",\n vm.toString(l1BaseFee),\n \",\",\n vm.toString(requestedGas),\n \",\",\n vm.toString(gasConsumed),\n \",\",\n \"$\",\n vm.toString(ethPrice),\n \",\",\n \"$\",\n vm.toString(usdCost),\n \",\",\n result\n )\n );\n\n assertTrue(vm.revertTo(snapshotId));\n }\n }\n }\n }\n }\n }\n }\n}\n" - }, - "contracts/test/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\n\ncontract SafeCall_call_Test is CommonTest {\n function testFuzz_call_succeeds(\n address from,\n address to,\n uint256 gas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCall(to, value, data);\n vm.prank(from);\n bool success = SafeCall.call(to, gas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function testFuzz_callWithMinGas_hasEnough_succeeds(\n address from,\n address to,\n uint64 minGas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n // Bound minGas to [0, l1_block_gas_limit]\n minGas = uint64(bound(minGas, 0, 30_000_000));\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCallMinGas(to, value, minGas, data);\n vm.prank(from);\n bool success = SafeCall.callWithMinGas(to, minGas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function test_callWithMinGas_noLeakageLow_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 5000; i < 50_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 26,071 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 26_071) {\n assertFalse(caller.makeSafeCall(i, 25_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 25_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 25_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n\n function test_callWithMinGas_noLeakageHigh_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 15_200_000; i < 15_300_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 15,238,769 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 15_238_769) {\n assertFalse(caller.makeSafeCall(i, 15_000_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 15_000_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 15_000_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n}\n\ncontract SimpleSafeCaller {\n uint256 public a;\n\n function makeSafeCall(uint64 gas, uint64 minGas) external returns (bool) {\n return\n SafeCall.call(\n address(this),\n gas,\n 0,\n abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas)\n );\n }\n\n function makeSafeCallMinGas(uint64 minGas) external returns (bool) {\n return\n SafeCall.callWithMinGas(\n address(this),\n minGas,\n 0,\n abi.encodeWithSelector(this.setA.selector, 1)\n );\n }\n\n function setA(uint256 _a) external {\n a = _a;\n }\n}\n" - }, - "contracts/test/Semver.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\n\n/**\n * @notice Test the Semver contract that is used for semantic versioning\n * of various contracts.\n */\ncontract Semver_Test is CommonTest {\n /**\n * @notice Global semver contract deployed in setUp. This is used in\n * the test cases.\n */\n Semver semver;\n\n /**\n * @notice Deploy a Semver contract\n */\n function setUp() public virtual override {\n semver = new Semver(7, 8, 0);\n }\n\n /**\n * @notice Test the version getter\n */\n function test_version_succeeds() external {\n assertEq(semver.version(), \"7.8.0\");\n }\n\n /**\n * @notice Since the versions are all immutable, they should\n * be able to be accessed from behind a proxy without needing\n * to initialize the contract.\n */\n function test_behindProxy_succeeds() external {\n Proxy proxy = new Proxy(alice);\n vm.prank(alice);\n proxy.upgradeTo(address(semver));\n\n assertEq(Semver(address(proxy)).version(), \"7.8.0\");\n }\n}\n" - }, - "contracts/test/SequencerFeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { SequencerFeeVault } from \"../L2/SequencerFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract SequencerFeeVault_Test is Bridge_Initializer {\n SequencerFeeVault vault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET));\n address constant recipient = address(256);\n\n event Withdrawal(uint256 value, address to, address from);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.SEQUENCER_FEE_WALLET, address(new SequencerFeeVault(recipient)).code);\n vm.label(Predeploys.SEQUENCER_FEE_WALLET, \"SequencerFeeVault\");\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n\n function test_constructor_succeeds() external {\n assertEq(vault.l1FeeWallet(), recipient);\n }\n\n function test_receive_succeeds() external {\n uint256 balance = address(vault).balance;\n\n vm.prank(alice);\n (bool success, ) = address(vault).call{ value: 100 }(hex\"\");\n\n assertEq(success, true);\n assertEq(address(vault).balance, balance + 100);\n }\n\n function test_withdraw_notEnough_reverts() external {\n assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());\n\n vm.expectRevert(\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n vault.withdraw();\n }\n\n function test_withdraw_succeeds() external {\n uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1;\n vm.deal(address(vault), amount);\n\n // No ether has been withdrawn yet\n assertEq(vault.totalProcessed(), 0);\n\n vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));\n emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));\n\n // The entire vault's balance is withdrawn\n vm.expectCall(\n Predeploys.L2_STANDARD_BRIDGE,\n address(vault).balance,\n abi.encodeWithSelector(\n StandardBridge.bridgeETHTo.selector,\n vault.l1FeeWallet(),\n 35_000,\n bytes(\"\")\n )\n );\n\n vault.withdraw();\n\n // The withdrawal was successful\n assertEq(vault.totalProcessed(), amount);\n }\n}\n" - }, - "contracts/test/StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport {\n OptimismMintableERC20,\n ILegacyMintableERC20\n} from \"../universal/OptimismMintableERC20.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/**\n * @title StandardBridgeTester\n * @notice Simple wrapper around the StandardBridge contract that exposes\n * internal functions so they can be more easily tested directly.\n */\ncontract StandardBridgeTester is StandardBridge {\n constructor(address payable _messenger, address payable _otherBridge)\n StandardBridge(_messenger, _otherBridge)\n {}\n\n function isOptimismMintableERC20(address _token) external view returns (bool) {\n return _isOptimismMintableERC20(_token);\n }\n\n function isCorrectTokenPair(address _mintableToken, address _otherToken)\n external\n view\n returns (bool)\n {\n return _isCorrectTokenPair(_mintableToken, _otherToken);\n }\n\n receive() external payable override {}\n}\n\n/**\n * @title LegacyMintable\n * @notice Simple implementation of the legacy OptimismMintableERC20.\n */\ncontract LegacyMintable is ERC20, ILegacyMintableERC20 {\n constructor(string memory _name, string memory _ticker) ERC20(_name, _ticker) {}\n\n function l1Token() external pure returns (address) {\n return address(0);\n }\n\n function mint(address _to, uint256 _amount) external pure {}\n\n function burn(address _from, uint256 _amount) external pure {}\n\n /**\n * @notice Implements ERC165. This implementation should not be changed as\n * it is how the actual legacy optimism mintable token does the\n * check. Allows for testing against code that is has been deployed,\n * assuming different compiler version is no problem.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n}\n\n/**\n * @title StandardBridge_Stateless_Test\n * @notice Tests internal functions that require no existing state or contract\n * interactions with the messenger.\n */\ncontract StandardBridge_Stateless_Test is CommonTest {\n StandardBridgeTester internal bridge;\n OptimismMintableERC20 internal mintable;\n ERC20 internal erc20;\n LegacyMintable internal legacy;\n\n function setUp() public override {\n super.setUp();\n\n bridge = new StandardBridgeTester({\n _messenger: payable(address(0)),\n _otherBridge: payable(address(0))\n });\n\n mintable = new OptimismMintableERC20({\n _bridge: address(0),\n _remoteToken: address(0),\n _name: \"Stonks\",\n _symbol: \"STONK\"\n });\n\n erc20 = new ERC20(\"Altcoin\", \"ALT\");\n legacy = new LegacyMintable(\"Legacy\", \"LEG\");\n }\n\n /**\n * @notice Test coverage for identifying OptimismMintableERC20 tokens.\n * This function should return true for both modern and legacy\n * OptimismMintableERC20 tokens and false for any accounts that\n * do not implement the interface.\n */\n function test_isOptimismMintableERC20_succeeds() external {\n // Both the modern and legacy mintable tokens should return true\n assertTrue(bridge.isOptimismMintableERC20(address(mintable)));\n assertTrue(bridge.isOptimismMintableERC20(address(legacy)));\n // A regular ERC20 should return false\n assertFalse(bridge.isOptimismMintableERC20(address(erc20)));\n // Non existent contracts should return false and not revert\n assertEq(address(0x20).code.length, 0);\n assertFalse(bridge.isOptimismMintableERC20(address(0x20)));\n }\n\n /**\n * @notice Test coverage of isCorrectTokenPair under different types of\n * tokens.\n */\n function test_isCorrectTokenPair_succeeds() external {\n // Modern + known to be correct remote token\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.remoteToken()));\n // Modern + known to be correct l1Token (legacy interface)\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.l1Token()));\n // Modern + known to be incorrect remote token\n assertTrue(mintable.remoteToken() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(mintable), address(0x20)));\n // Legacy + known to be correct l1Token\n assertTrue(bridge.isCorrectTokenPair(address(legacy), legacy.l1Token()));\n // Legacy + known to be incorrect l1Token\n assertTrue(legacy.l1Token() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(legacy), address(0x20)));\n // A token that doesn't support either modern or legacy interface\n // will revert\n vm.expectRevert();\n bridge.isCorrectTokenPair(address(erc20), address(1));\n }\n}\n" - }, - "contracts/test/SystemConfig.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract SystemConfig_Init is CommonTest {\n SystemConfig sysConf;\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n sysConf = new SystemConfig({\n _owner: alice,\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: config\n });\n }\n}\n\ncontract SystemConfig_Initialize_TestFail is SystemConfig_Init {\n function test_initialize_lowGasLimit_reverts() external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n\n ResourceMetering.ResourceConfig memory cfg = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n new SystemConfig({\n _owner: alice,\n _overhead: 0,\n _scalar: 0,\n _batcherHash: bytes32(hex\"\"),\n _gasLimit: minimumGasLimit - 1,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n }\n}\n\ncontract SystemConfig_Setters_TestFail is SystemConfig_Init {\n function test_setBatcherHash_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setBatcherHash(bytes32(hex\"\"));\n }\n\n function test_setGasConfig_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasConfig(0, 0);\n }\n\n function test_setGasLimit_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasLimit(0);\n }\n\n function test_setUnsafeBlockSigner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setUnsafeBlockSigner(address(0x20));\n }\n\n function test_setResourceConfig_notOwner_reverts() external {\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badMinMax_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 2 gwei,\n maximumBaseFee: 1 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: min base fee must be less than max base\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_zeroDenominator_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 0,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: denominator cannot be 0\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_lowGasLimit_reverts() external {\n uint64 gasLimit = sysConf.gasLimit();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: uint32(gasLimit),\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: uint32(gasLimit),\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badPrecision_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 11,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: precision loss with target resource limit\");\n sysConf.setResourceConfig(config);\n }\n}\n\ncontract SystemConfig_Setters_Test is SystemConfig_Init {\n event ConfigUpdate(\n uint256 indexed version,\n SystemConfig.UpdateType indexed updateType,\n bytes data\n );\n\n function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash));\n\n vm.prank(sysConf.owner());\n sysConf.setBatcherHash(newBatcherHash);\n assertEq(sysConf.batcherHash(), newBatcherHash);\n }\n\n function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.GAS_CONFIG,\n abi.encode(newOverhead, newScalar)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setGasConfig(newOverhead, newScalar);\n assertEq(sysConf.overhead(), newOverhead);\n assertEq(sysConf.scalar(), newScalar);\n }\n\n function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n newGasLimit = uint64(\n bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))\n );\n\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit));\n\n vm.prank(sysConf.owner());\n sysConf.setGasLimit(newGasLimit);\n assertEq(sysConf.gasLimit(), newGasLimit);\n }\n\n function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER,\n abi.encode(newUnsafeSigner)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setUnsafeBlockSigner(newUnsafeSigner);\n assertEq(sysConf.unsafeBlockSigner(), newUnsafeSigner);\n }\n}\n" - }, - "contracts/test/TransferOnion.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { TransferOnion } from \"../periphery/TransferOnion.sol\";\n\n/**\n * @title TransferOnionTest\n * @notice Test coverage of TransferOnion\n */\ncontract TransferOnionTest is Test {\n /**\n * @notice TransferOnion\n */\n TransferOnion internal onion;\n\n /**\n * @notice token constructor arg\n */\n address internal _token;\n\n /**\n * @notice sender constructor arg\n */\n address internal _sender;\n\n /**\n * @notice Sets up addresses, deploys contracts and funds the owner.\n */\n function setUp() public {\n ERC20 token = new ERC20(\"Token\", \"TKN\");\n _token = address(token);\n _sender = makeAddr(\"sender\");\n }\n\n /**\n * @notice Deploy the TransferOnion with a dummy shell\n */\n function _deploy() public {\n _deploy(bytes32(0));\n }\n\n /**\n * @notice Deploy the TransferOnion with a specific shell\n */\n function _deploy(bytes32 _shell) public {\n onion = new TransferOnion({ _token: ERC20(_token), _sender: _sender, _shell: _shell });\n }\n\n /**\n * @notice Build the onion data\n */\n function _onionize(TransferOnion.Layer[] memory _layers)\n public\n pure\n returns (bytes32, TransferOnion.Layer[] memory)\n {\n uint256 length = _layers.length;\n bytes32 hash = bytes32(0);\n for (uint256 i; i < length; i++) {\n TransferOnion.Layer memory layer = _layers[i];\n _layers[i].shell = hash;\n hash = keccak256(abi.encode(layer.recipient, layer.amount, hash));\n }\n return (hash, _layers);\n }\n\n /**\n * @notice The constructor sets the variables as expected\n */\n function test_constructor_succeeds() external {\n _deploy();\n\n assertEq(address(onion.TOKEN()), _token);\n assertEq(onion.SENDER(), _sender);\n assertEq(onion.shell(), bytes32(0));\n }\n\n /**\n * @notice unwrap\n */\n function test_unwrap_succeeds() external {\n // Commit to transferring tiny amounts of tokens\n TransferOnion.Layer[] memory _layers = new TransferOnion.Layer[](2);\n _layers[0] = TransferOnion.Layer(address(1), 1, bytes32(0));\n _layers[1] = TransferOnion.Layer(address(2), 2, bytes32(0));\n\n // Build the onion shell\n (bytes32 shell, TransferOnion.Layer[] memory layers) = _onionize(_layers);\n _deploy(shell);\n\n assertEq(onion.shell(), shell);\n\n address token = address(onion.TOKEN());\n address sender = onion.SENDER();\n\n // give 3 units of token to sender\n deal(token, onion.SENDER(), 3);\n vm.prank(sender);\n ERC20(token).approve(address(onion), 3);\n\n // To build the inputs, to `peel`, need to reverse the list\n TransferOnion.Layer[] memory inputs = new TransferOnion.Layer[](2);\n int256 length = int256(layers.length);\n for (int256 i = length - 1; i >= 0; i--) {\n uint256 ui = uint256(i);\n uint256 revidx = uint256(length) - ui - 1;\n TransferOnion.Layer memory layer = layers[ui];\n inputs[revidx] = layer;\n }\n\n // The accounts have no balance\n assertEq(ERC20(_token).balanceOf(address(1)), 0);\n assertEq(ERC20(_token).balanceOf(address(2)), 0);\n\n onion.peel(inputs);\n\n // Now the accounts have the expected balance\n assertEq(ERC20(_token).balanceOf(address(1)), 1);\n assertEq(ERC20(_token).balanceOf(address(2)), 2);\n }\n}\n" - }, - "contracts/test/invariants/CrossDomainMessenger.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { OptimismPortal } from \"../../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../../L1/L1CrossDomainMessenger.sol\";\nimport { Messenger_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\nimport { Predeploys } from \"../../libraries/Predeploys.sol\";\nimport { Encoding } from \"../../libraries/Encoding.sol\";\nimport { Hashing } from \"../../libraries/Hashing.sol\";\n\ncontract RelayActor is StdUtils {\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n uint256 public numHashes;\n bytes32[] public hashes;\n bool public reverted = false;\n\n OptimismPortal op;\n L1CrossDomainMessenger xdm;\n Vm vm;\n\n constructor(\n OptimismPortal _op,\n L1CrossDomainMessenger _xdm,\n Vm _vm\n ) {\n op = _op;\n xdm = _xdm;\n vm = _vm;\n }\n\n /**\n * Relays a message to the `L1CrossDomainMessenger` with a random `version`, `_minGasLimit`\n * and `_message`.\n */\n function relay(\n uint16 _version,\n uint32 _minGasLimit,\n bytes memory _message\n ) external {\n address target = address(0x04); // ID precompile\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Restrict `_minGasLimit` to a number in the range of the block gas limit.\n _minGasLimit = uint32(bound(_minGasLimit, 0, block.gaslimit));\n\n // Restrict version to the range of [0, 1]\n _version = _version % 2;\n\n // Compute the cross domain message hash and store it in `hashes`.\n // The `relayMessage` function will always encode the message as a version 1\n // message after checking that the V0 hash has not already been relayed.\n bytes32 _hash = Hashing.hashCrossDomainMessageV1(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n 0, // value\n _minGasLimit,\n _message\n );\n\n // Act as the optimism portal and call `relayMessage` on the `L1CrossDomainMessenger` with\n // the outer min gas limit.\n vm.startPrank(address(op));\n vm.expectCall(target, _message);\n try\n xdm.relayMessage{ gas: xdm.baseGas(_message, _minGasLimit) }(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n 0, // value\n _minGasLimit,\n _message\n )\n {} catch {\n // If any of these calls revert, set `reverted` to true to fail the invariant test.\n // NOTE: This is to get around forge's invariant fuzzer ignoring reverted calls\n // to this function.\n reverted = true;\n }\n vm.stopPrank();\n\n hashes.push(_hash);\n numHashes += 1;\n }\n}\n\ncontract XDM_MinGasLimits is Messenger_Initializer {\n RelayActor actor;\n\n function setUp() public virtual override {\n // Set up the `L1CrossDomainMessenger` and `OptimismPortal` contracts.\n super.setUp();\n\n // Deploy a relay actor\n actor = new RelayActor(op, L1Messenger, vm);\n\n // Target the `RelayActor` contract\n targetContract(address(actor));\n\n // Target the actor's `relay` function\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.relay.selector;\n targetSelector(FuzzSelector({ addr: address(actor), selectors: selectors }));\n }\n\n /**\n * @custom:invariant A call to `relayMessage` should never revert if at least the proper minimum\n * gas limits are supplied.\n *\n * There are two minimum gas limits here:\n *\n * - The outer min gas limit is for the call from the `OptimismPortal` to the\n * `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function\n * with the `message` and inner limit.\n *\n * - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target\n * contract.\n */\n function invariant_minGasLimits() public {\n uint256 length = actor.numHashes();\n for (uint256 i = 0; i < length; ++i) {\n bytes32 hash = actor.hashes(i);\n // the message hash is in the successfulMessages mapping\n assertTrue(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertFalse(L1Messenger.failedMessages(hash));\n }\n assertFalse(actor.reverted());\n }\n}\n" - }, - "contracts/test/invariants/L2OutputOracle.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { L2OutputOracle_Initializer } from \"../CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../../L1/L2OutputOracle.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\n\ncontract L2OutputOracle_Proposer {\n L2OutputOracle internal oracle;\n Vm internal vm;\n\n constructor(L2OutputOracle _oracle, Vm _vm) {\n oracle = _oracle;\n vm = _vm;\n }\n\n /**\n * @dev Allows the actor to propose an L2 output to the `L2OutputOracle`\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external {\n // Act as the proposer and propose a new output.\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _l2BlockNumber, _l1BlockHash, _l1BlockNumber);\n }\n}\n\ncontract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_Initializer {\n L2OutputOracle_Proposer internal actor;\n\n function setUp() public override {\n super.setUp();\n\n // Create a proposer actor.\n actor = new L2OutputOracle_Proposer(oracle, vm);\n\n // Set the target contract to the proposer actor.\n targetContract(address(actor));\n\n // Set the target selector for `proposeL2Output`\n // `proposeL2Output` is the only function we care about, as it is the only function\n // that can modify the `l2Outputs` array in the oracle.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.proposeL2Output.selector;\n FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The block number of the output root proposals should monotonically\n * increase.\n *\n * When a new output is submitted, it should never be allowed to correspond to a block\n * number that is less than the current output.\n */\n function invariant_monotonicBlockNumIncrease() external {\n // Assert that the block number of proposals must monotonically increase.\n assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber());\n }\n}\n" - }, - "contracts/test/invariants/OptimismPortal.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Portal_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\n\ncontract OptimismPortal_Invariant_Harness is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n function setUp() public virtual override {\n super.setUp();\n\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n}\n\ncontract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization\n * period has not elapsed.\n *\n * A withdrawal that has been proven should not be able to be finalized until after\n * the finalization period has elapsed.\n */\n function invariant_cannotFinalizeBeforePeriodHasPassed() external {\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Finalize the withdrawal transaction.\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal\n * has already been finalized.\n *\n * Ensures that there is no chain of calls that can be made that allows a withdrawal\n * to be finalized twice.\n */\n function invariant_cannotFinalizeTwice() external {\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant A withdrawal should **always** be able to be finalized\n * `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.\n *\n * This invariant asserts that there is no chain of calls that can be made that\n * will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS`\n * after it was successfully proven.\n */\n function invariant_canAlwaysFinalize() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value);\n }\n}\n" - }, - "contracts/test/invariants/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { SafeCall } from \"../../libraries/SafeCall.sol\";\n\ncontract SafeCall_Succeeds_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, false);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n }\n\n /**\n * @custom:invariant If `callWithMinGas` performs a call, then it must always\n * provide at least the specified minimum gas limit to the subcontext.\n *\n * If the check for remaining gas in `SafeCall.callWithMinGas` passes, the\n * subcontext of the call below it must be provided at least `minGas` gas.\n */\n function invariant_callWithMinGas_alwaysForwardsMinGas_succeeds() public {\n assertEq(actor.numCalls(), 0, \"no failed calls allowed\");\n }\n\n function performSafeCallMinGas(uint64 minGas) external {\n SafeCall.callWithMinGas(address(0), minGas, 0, hex\"\");\n }\n}\n\ncontract SafeCall_Fails_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, true);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n }\n\n /**\n * @custom:invariant `callWithMinGas` reverts if there is not enough gas to pass\n * to the subcontext.\n *\n * If there is not enough gas in the callframe to ensure that `callWithMinGas`\n * can provide the specified minimum gas limit to the subcontext of the call,\n * then `callWithMinGas` must revert.\n */\n function invariant_callWithMinGas_neverForwardsMinGas_reverts() public {\n assertEq(actor.numCalls(), 0, \"no successful calls allowed\");\n }\n\n function performSafeCallMinGas(uint64 minGas) external {\n SafeCall.callWithMinGas(address(0), minGas, 0, hex\"\");\n }\n}\n\ncontract SafeCaller_Actor is StdUtils {\n bool internal immutable FAILS;\n\n Vm internal vm;\n uint256 public numCalls;\n\n constructor(Vm _vm, bool _fails) {\n vm = _vm;\n FAILS = _fails;\n }\n\n function performSafeCallMinGas(uint64 gas, uint64 minGas) external {\n if (FAILS) {\n // Bound the minimum gas amount to [2500, type(uint48).max]\n minGas = uint64(bound(minGas, 2500, type(uint48).max));\n // Bound the gas passed to [minGas, (((minGas + 200) * 64) / 63)]\n gas = uint64(bound(gas, minGas, (((minGas + 200) * 64) / 63)));\n } else {\n // Bound the minimum gas amount to [2500, type(uint48).max]\n minGas = uint64(bound(minGas, 2500, type(uint48).max));\n // Bound the gas passed to [(((minGas + 200) * 64) / 63) + 500, type(uint64).max]\n gas = uint64(bound(gas, (((minGas + 200) * 64) / 63) + 500, type(uint64).max));\n }\n\n vm.expectCallMinGas(address(0x00), 0, minGas, hex\"\");\n bool success = SafeCall.call(\n msg.sender,\n gas,\n 0,\n abi.encodeWithSelector(0x2ae57a41, minGas)\n );\n\n if (success && FAILS) numCalls++;\n if (!FAILS && !success) numCalls++;\n }\n}\n" - }, - "contracts/test/invariants/SystemConfig.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { SystemConfig } from \"../../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../../L1/ResourceMetering.sol\";\nimport { Constants } from \"../../libraries/Constants.sol\";\n\ncontract SystemConfig_GasLimitLowerBound_Invariant is Test {\n SystemConfig public config;\n\n function setUp() public {\n ResourceMetering.ResourceConfig memory cfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n config = new SystemConfig({\n _owner: address(0xbeef),\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n\n // Set the target contract to the `config`\n targetContract(address(config));\n // Set the target sender to the `config`'s owner (0xbeef)\n targetSender(address(0xbeef));\n // Set the target selector for `setGasLimit`\n // `setGasLimit` is the only function we care about, as it is the only function\n // that can modify the gas limit within the SystemConfig.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = config.setGasLimit.selector;\n FuzzSelector memory selector = FuzzSelector({\n addr: address(config),\n selectors: selectors\n });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The gas limit of the `SystemConfig` contract can never be lower\n * than the hard-coded lower bound.\n */\n function invariant_gasLimitLowerBound() external {\n assertTrue(config.gasLimit() >= config.minimumGasLimit());\n }\n}\n" - }, - "contracts/universal/CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer0\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * libAddressManager variable used to exist. Must be the first contract in the inheritance\n * tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer0 {\n /**\n * @custom:legacy\n * @custom:spacer libAddressManager\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n}\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer1\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * PausableUpgradable and OwnableUpgradeable variables used to exist. Must be\n * the third contract in the inheritance tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer1 {\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable via OwnableUpgradeable.\n *\n */\n uint256[50] private spacer_1_0_1600;\n\n /**\n * @custom:legacy\n * @custom:spacer _owner\n * @notice Spacer for backwards compatibility.\n * Come from OpenZeppelin OwnableUpgradeable.\n */\n address private spacer_51_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable via PausableUpgradable.\n */\n uint256[49] private spacer_52_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer _paused\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n bool private spacer_101_0_1;\n\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n uint256[49] private spacer_102_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer ReentrancyGuardUpgradeable's `_status` field.\n * @notice Spacer for backwards compatibility\n */\n uint256 private spacer_151_0_32;\n\n /**\n * @custom:spacer ReentrancyGuardUpgradeable\n * @notice Spacer for backwards compatibility\n */\n uint256[49] private __gap_reentrancy_guard;\n\n /**\n * @custom:legacy\n * @custom:spacer blockedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_201_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer relayedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_202_0_32;\n}\n\n/**\n * @custom:upgradeable\n * @title CrossDomainMessenger\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\n * cross-chain messenger contracts. It's designed to be a universal interface that only\n * needs to be extended slightly to provide low-level message passing functionality on each\n * chain it's deployed on. Currently only designed for message passing between two paired\n * chains and does not support one-to-many interactions.\n *\n * Any changes to this contract MUST result in a semver bump for contracts that inherit it.\n */\nabstract contract CrossDomainMessenger is\n CrossDomainMessengerLegacySpacer0,\n Initializable,\n CrossDomainMessengerLegacySpacer1\n{\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Constant overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_CONSTANT_OVERHEAD = 200_000;\n\n /**\n * @notice Numerator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 1016;\n\n /**\n * @notice Denominator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 1000;\n\n /**\n * @notice Extra gas added to base gas for each byte of calldata in a message.\n */\n uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\n\n /**\n * @notice Address of the paired CrossDomainMessenger contract on the other chain.\n */\n address public immutable OTHER_MESSENGER;\n\n /**\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n * be present in this mapping if it has successfully been relayed on this chain, and\n * can therefore not be relayed again.\n */\n mapping(bytes32 => bool) public successfulMessages;\n\n /**\n * @notice Address of the sender of the currently executing message on the other chain. If the\n * value of this variable is the default value (0x00000000...dead) then no message is\n * currently being executed. Use the xDomainMessageSender getter which will throw an\n * error if this is the case.\n */\n address internal xDomainMsgSender;\n\n /**\n * @notice Nonce for the next message to be sent, without the message version applied. Use the\n * messageNonce getter which will insert the message version into the nonce to give you\n * the actual nonce to be used for the message.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Mapping of message hashes to a boolean if and only if the message has failed to be\n * executed at least once. A message will not be present in this mapping if it\n * successfully executed on the first attempt.\n */\n mapping(bytes32 => bool) public failedMessages;\n\n /**\n * @notice A mapping of hashes to reentrancy locks.\n */\n mapping(bytes32 => bool) internal reentrancyLocks;\n\n /**\n * @notice Reserve extra slots in the storage layout for future upgrades.\n * A gap size of 41 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[41] private __gap;\n\n /**\n * @notice Emitted whenever a message is sent to the other chain.\n *\n * @param target Address of the recipient of the message.\n * @param sender Address of the sender of the message.\n * @param message Message to trigger the recipient address with.\n * @param messageNonce Unique nonce attached to the message.\n * @param gasLimit Minimum gas limit that the message can be executed with.\n */\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n /**\n * @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the\n * SentMessage event without breaking the ABI of this contract, this is good enough.\n *\n * @param sender Address of the sender of the message.\n * @param value ETH value sent along with the message to the recipient.\n */\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n /**\n * @notice Emitted whenever a message is successfully relayed on this chain.\n *\n * @param msgHash Hash of the message that was relayed.\n */\n event RelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @notice Emitted whenever a message fails to be relayed on this chain.\n *\n * @param msgHash Hash of the message that failed to be relayed.\n */\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @param _otherMessenger Address of the messenger on the paired chain.\n */\n constructor(address _otherMessenger) {\n OTHER_MESSENGER = _otherMessenger;\n }\n\n /**\n * @notice Sends a message to some target address on the other chain. Note that if the call\n * always reverts, then the message will be unrelayable, and any ETH sent will be\n * permanently locked. The same will occur if the target on the other chain is\n * considered unsafe (see the _isUnsafeTarget() function).\n *\n * @param _target Target contract or wallet address.\n * @param _message Message to trigger the target address with.\n * @param _minGasLimit Minimum gas limit that the message can be executed with.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _minGasLimit\n ) external payable {\n // Triggers a message to the other messenger. Note that the amount of gas provided to the\n // message is the amount of gas requested by the user PLUS the base gas value. We want to\n // guarantee the property that the call to the target contract will always have at least\n // the minimum gas limit specified by the user.\n _sendMessage(\n OTHER_MESSENGER,\n baseGas(_message, _minGasLimit),\n msg.value,\n abi.encodeWithSelector(\n this.relayMessage.selector,\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _minGasLimit,\n _message\n )\n );\n\n emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit);\n emit SentMessageExtension1(msg.sender, msg.value);\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\n * be executed via cross-chain call from the other messenger OR if the message was\n * already received once and is currently being replayed.\n *\n * @param _nonce Nonce of the message being relayed.\n * @param _sender Address of the user who sent the message.\n * @param _target Address that the message is targeted at.\n * @param _value ETH value to send with the message.\n * @param _minGasLimit Minimum amount of gas that the message can be executed with.\n * @param _message Message to send to the target.\n */\n function relayMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _minGasLimit,\n bytes calldata _message\n ) external payable {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n require(\n version < 2,\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // If the message is version 0, then it's a migrated legacy withdrawal. We therefore need\n // to check that the legacy version of the message has not already been relayed.\n if (version == 0) {\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce);\n require(\n successfulMessages[oldHash] == false,\n \"CrossDomainMessenger: legacy withdrawal already relayed\"\n );\n }\n\n // We use the v1 message hash as the unique identifier for the message because it commits\n // to the value and minimum gas limit of the message.\n bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _minGasLimit,\n _message\n );\n\n // Check if the reentrancy lock for the `versionedHash` is already set.\n if (reentrancyLocks[versionedHash]) {\n revert(\"ReentrancyGuard: reentrant call\");\n }\n // Trigger the reentrancy lock for `versionedHash`\n reentrancyLocks[versionedHash] = true;\n\n if (_isOtherMessenger()) {\n // These properties should always hold when the message is first submitted (as\n // opposed to being replayed).\n assert(msg.value == _value);\n assert(!failedMessages[versionedHash]);\n } else {\n require(\n msg.value == 0,\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n\n require(\n failedMessages[versionedHash],\n \"CrossDomainMessenger: message cannot be replayed\"\n );\n }\n\n require(\n _isUnsafeTarget(_target) == false,\n \"CrossDomainMessenger: cannot send message to blocked system address\"\n );\n\n require(\n successfulMessages[versionedHash] == false,\n \"CrossDomainMessenger: message has already been relayed\"\n );\n\n xDomainMsgSender = _sender;\n bool success = SafeCall.callWithMinGas(_target, _minGasLimit, _value, _message);\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n\n if (success) {\n successfulMessages[versionedHash] = true;\n emit RelayedMessage(versionedHash);\n } else {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n }\n\n // Clear the reentrancy lock for `versionedHash`\n reentrancyLocks[versionedHash] = false;\n }\n\n /**\n * @notice Retrieves the address of the contract or wallet that initiated the currently\n * executing message on the other chain. Will throw an error if there is no message\n * currently being executed. Allows the recipient of a call to see who triggered it.\n *\n * @return Address of the sender of the currently executing message on the other chain.\n */\n function xDomainMessageSender() external view returns (address) {\n require(\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER,\n \"CrossDomainMessenger: xDomainMessageSender is not set\"\n );\n\n return xDomainMsgSender;\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n\n /**\n * @notice Computes the amount of gas required to guarantee that a given message will be\n * received on the other chain without running out of gas. Guaranteeing that a message\n * will not run out of gas is important because this ensures that a message can always\n * be replayed on the other chain if it fails to execute completely.\n *\n * @param _message Message to compute the amount of required gas for.\n * @param _minGasLimit Minimum desired gas limit when message goes to target.\n *\n * @return Amount of gas required to guarantee message receipt.\n */\n function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {\n // We peform the following math on uint64s to avoid overflow errors. Multiplying the\n // by MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR would otherwise limit the _minGasLimit to\n // type(uint32).max / MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR ~= 4.2m.\n return\n // Dynamic overhead\n ((uint64(_minGasLimit) * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\n MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\n // Calldata overhead\n (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\n // Constant overhead\n MIN_GAS_CONSTANT_OVERHEAD;\n }\n\n /**\n * @notice Intializer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __CrossDomainMessenger_init() internal onlyInitializing {\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n }\n\n /**\n * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @param _to Recipient of the message on the other chain.\n * @param _gasLimit Minimum gas limit the message can be executed with.\n * @param _value Amount of ETH to send with the message.\n * @param _data Message data.\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal virtual;\n\n /**\n * @notice Checks whether the message is coming from the other messenger. Implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @return Whether the message is coming from the other messenger.\n */\n function _isOtherMessenger() internal view virtual returns (bool);\n\n /**\n * @notice Checks whether a given call target is a system address that could cause the\n * messenger to peform an unsafe action. This is NOT a mechanism for blocking user\n * addresses. This is ONLY used to prevent the execution of messages to specific\n * system addresses that could cause security issues, e.g., having the\n * CrossDomainMessenger send messages to itself.\n *\n * @param _target Address of the contract to check.\n *\n * @return Whether or not the address is an unsafe system address.\n */\n function _isUnsafeTarget(address _target) internal view virtual returns (bool);\n}\n" - }, - "contracts/universal/ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721Bridge\n * @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.\n */\nabstract contract ERC721Bridge {\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Address of the bridge on the other network.\n */\n address public immutable OTHER_BRIDGE;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[49] private __gap;\n\n /**\n * @notice Emitted when an ERC721 bridge to the other network is initiated.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC721 bridge from the other network is finalized.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) && MESSENGER.xDomainMessageSender() == OTHER_BRIDGE,\n \"ERC721Bridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge) {\n require(_messenger != address(0), \"ERC721Bridge: messenger cannot be address(0)\");\n require(_otherBridge != address(0), \"ERC721Bridge: other bridge cannot be address(0)\");\n\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = _otherBridge;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for other bridge address.\n *\n * @return Address of the bridge on the other network.\n */\n function otherBridge() external view returns (address) {\n return OTHER_BRIDGE;\n }\n\n /**\n * @notice Initiates a bridge of an NFT to the caller's account on the other chain. Note that\n * this function can only be called by EOAs. Smart contract wallets should use the\n * `bridgeERC721To` function after ensuring that the recipient address on the remote\n * chain exists. Also note that the current owner of the token on this chain must\n * approve this contract to operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721(\n address _localToken,\n address _remoteToken,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n // Modifier requiring sender to be EOA. This prevents against a user error that would occur\n // if the sender is a smart contract wallet that has a different address on the remote chain\n // (or doesn't have an address on the remote chain at all). The user would fail to receive\n // the NFT if they use this function because it sends the NFT to the same address as the\n // caller. This check could be bypassed by a malicious contract via initcode, but it takes\n // care of the user error we want to avoid.\n require(!Address.isContract(msg.sender), \"ERC721Bridge: account is not externally owned\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note\n * that the current owner of the token on this chain must approve this contract to\n * operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n require(_to != address(0), \"ERC721Bridge: nft recipient cannot be address(0)\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Internal function for initiating a token bridge to the other domain.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _from Address of the sender on this domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other domain. Data supplied here will\n * not be used to execute any code on the other domain and is only emitted\n * as extra data for the convenience of off-chain tooling.\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal virtual;\n}\n" - }, - "contracts/universal/FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n/**\n * @title FeeVault\n * @notice The FeeVault contract contains the basic logic for the various different vault contracts\n * used to hold fee revenue generated by the L2 system.\n */\nabstract contract FeeVault {\n /**\n * @notice Emits each time that a withdrawal occurs.\n *\n * @param value Amount that was withdrawn (in wei).\n * @param to Address that the funds were sent to.\n * @param from Address that triggered the withdrawal.\n */\n event Withdrawal(uint256 value, address to, address from);\n\n /**\n * @notice Minimum balance before a withdrawal can be triggered.\n */\n uint256 public immutable MIN_WITHDRAWAL_AMOUNT;\n\n /**\n * @notice Wallet that will receive the fees on L1.\n */\n address public immutable RECIPIENT;\n\n /**\n * @notice The minimum gas limit for the FeeVault withdrawal transaction.\n */\n uint32 internal constant WITHDRAWAL_MIN_GAS = 35_000;\n\n /**\n * @notice Total amount of wei processed by the contract.\n */\n uint256 public totalProcessed;\n\n /**\n * @param _recipient Wallet that will receive the fees on L1.\n * @param _minWithdrawalAmount Minimum balance before a withdrawal can be triggered.\n */\n constructor(address _recipient, uint256 _minWithdrawalAmount) {\n MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;\n RECIPIENT = _recipient;\n }\n\n /**\n * @notice Allow the contract to receive ETH.\n */\n receive() external payable {}\n\n /**\n * @notice Triggers a withdrawal of funds to the L1 fee wallet.\n */\n function withdraw() external {\n require(\n address(this).balance >= MIN_WITHDRAWAL_AMOUNT,\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n\n uint256 value = address(this).balance;\n totalProcessed += value;\n\n emit Withdrawal(value, RECIPIENT, msg.sender);\n\n L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }(\n RECIPIENT,\n WITHDRAWAL_MIN_GAS,\n bytes(\"\")\n );\n }\n}\n" - }, - "contracts/universal/IOptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @title IOptimismMintableERC20\n * @notice This interface is available on the OptimismMintableERC20 contract. We declare it as a\n * separate interface so that it can be used in custom implementations of\n * OptimismMintableERC20.\n */\ninterface IOptimismMintableERC20 is IERC165 {\n function remoteToken() external view returns (address);\n\n function bridge() external returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n\n/**\n * @custom:legacy\n * @title ILegacyMintableERC20\n * @notice This interface was available on the legacy L2StandardERC20 contract. It remains available\n * on the OptimismMintableERC20 contract for backwards compatibility.\n */\ninterface ILegacyMintableERC20 is IERC165 {\n function l1Token() external view returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n" - }, - "contracts/universal/IOptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\n/**\n * @title IOptimismMintableERC721\n * @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.\n * Tokens that follow this standard can be easily transferred across the ERC721 bridge.\n */\ninterface IOptimismMintableERC721 is IERC721Enumerable {\n /**\n * @notice Emitted when a token is minted.\n *\n * @param account Address of the account the token was minted to.\n * @param tokenId Token ID of the minted token.\n */\n event Mint(address indexed account, uint256 tokenId);\n\n /**\n * @notice Emitted when a token is burned.\n *\n * @param account Address of the account the token was burned from.\n * @param tokenId Token ID of the burned token.\n */\n event Burn(address indexed account, uint256 tokenId);\n\n /**\n * @notice Mints some token ID for a user, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * @param _to Address of the user to mint the token for.\n * @param _tokenId Token ID to mint.\n */\n function safeMint(address _to, uint256 _tokenId) external;\n\n /**\n * @notice Burns a token ID from a user.\n *\n * @param _from Address of the user to burn the token from.\n * @param _tokenId Token ID to burn.\n */\n function burn(address _from, uint256 _tokenId) external;\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function REMOTE_CHAIN_ID() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function REMOTE_TOKEN() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function BRIDGE() external view returns (address);\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function remoteChainId() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function remoteToken() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function bridge() external view returns (address);\n}\n" - }, - "contracts/universal/OptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { ILegacyMintableERC20, IOptimismMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC20\n * @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed\n * to allow the StandardBridge contracts to mint and burn tokens. This makes it possible to\n * use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa.\n * Designed to be backwards compatible with the older StandardL2ERC20 token which was only\n * meant for use on L2.\n */\ncontract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, Semver {\n /**\n * @notice Address of the corresponding version of this token on the remote chain.\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @notice Address of the StandardBridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Emitted whenever tokens are minted for an account.\n *\n * @param account Address of the account tokens are being minted for.\n * @param amount Amount of tokens minted.\n */\n event Mint(address indexed account, uint256 amount);\n\n /**\n * @notice Emitted whenever tokens are burned from an account.\n *\n * @param account Address of the account tokens are being burned from.\n * @param amount Amount of tokens burned.\n */\n event Burn(address indexed account, uint256 amount);\n\n /**\n * @notice A modifier that only allows the bridge to call\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC20: only bridge can mint and burn\");\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the L2 standard bridge.\n * @param _remoteToken Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _bridge,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) Semver(1, 0, 0) {\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n }\n\n /**\n * @notice Allows the StandardBridge on this network to mint tokens.\n *\n * @param _to Address to mint tokens to.\n * @param _amount Amount of tokens to mint.\n */\n function mint(address _to, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _mint(_to, _amount);\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Allows the StandardBridge on this network to burn tokens.\n *\n * @param _from Address to burn tokens from.\n * @param _amount Amount of tokens to burn.\n */\n function burn(address _from, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _burn(_from, _amount);\n emit Burn(_from, _amount);\n }\n\n /**\n * @notice ERC165 interface check function.\n *\n * @param _interfaceId Interface ID to check.\n *\n * @return Whether or not the interface is supported by this contract.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 iface1 = type(IERC165).interfaceId;\n // Interface corresponding to the legacy L2StandardERC20.\n bytes4 iface2 = type(ILegacyMintableERC20).interfaceId;\n // Interface corresponding to the updated OptimismMintableERC20 (this contract).\n bytes4 iface3 = type(IOptimismMintableERC20).interfaceId;\n return _interfaceId == iface1 || _interfaceId == iface2 || _interfaceId == iface3;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote token. Use REMOTE_TOKEN going forward.\n */\n function l1Token() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the bridge. Use BRIDGE going forward.\n */\n function l2Bridge() public view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for REMOTE_TOKEN.\n */\n function remoteToken() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for BRIDGE.\n */\n function bridge() public view returns (address) {\n return BRIDGE;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC20Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Contract Imports */\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000012\n * @title OptimismMintableERC20Factory\n * @notice OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20\n * contracts on the network it's deployed to. Simplifies the deployment process for users\n * who may be less familiar with deploying smart contracts. Designed to be backwards\n * compatible with the older StandardL2ERC20Factory contract.\n */\ncontract OptimismMintableERC20Factory is Semver {\n /**\n * @notice Address of the StandardBridge on this chain.\n */\n address public immutable BRIDGE;\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a new OptimismMintableERC20 is created. Legacy version of the newer\n * OptimismMintableERC20Created event. We recommend relying on that event instead.\n *\n * @param remoteToken Address of the token on the remote chain.\n * @param localToken Address of the created token on the local chain.\n */\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC20 is created.\n *\n * @param localToken Address of the created token on the local chain.\n * @param remoteToken Address of the corresponding token on the remote chain.\n * @param deployer Address of the account that deployed the token.\n */\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC20 token contract since this contract\n * is responsible for deploying OptimismMintableERC20 contracts.\n *\n * @param _bridge Address of the StandardBridge on this chain.\n */\n constructor(address _bridge) Semver(1, 1, 0) {\n BRIDGE = _bridge;\n }\n\n /**\n * @custom:legacy\n * @notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the\n * newer createOptimismMintableERC20 function, which has a more intuitive name.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createStandardL2Token(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n return createOptimismMintableERC20(_remoteToken, _name, _symbol);\n }\n\n /**\n * @notice Creates an instance of the OptimismMintableERC20 contract.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createOptimismMintableERC20(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) public returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC20Factory: must provide remote token address\"\n );\n\n address localToken = address(\n new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol)\n );\n\n // Emit the old event too for legacy support.\n emit StandardL2TokenCreated(_remoteToken, localToken);\n\n // Emit the updated event. The arguments here differ from the legacy event, but\n // are consistent with the ordering used in StandardBridge events.\n emit OptimismMintableERC20Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n ERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { IOptimismMintableERC721 } from \"./IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC721\n * @notice This contract is the remote representation for some token that lives on another network,\n * typically an Optimism representation of an Ethereum-based token. Standard reference\n * implementation that can be extended or modified according to your needs.\n */\ncontract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Semver {\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Base token URI for this token.\n */\n string public baseTokenURI;\n\n /**\n * @notice Modifier that prevents callers other than the bridge from calling the function.\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC721: only bridge can call this function\");\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the bridge on this network.\n * @param _remoteChainId Chain ID where the remote token is deployed.\n * @param _remoteToken Address of the corresponding token on the other network.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n constructor(\n address _bridge,\n uint256 _remoteChainId,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) Semver(1, 0, 0) {\n require(_bridge != address(0), \"OptimismMintableERC721: bridge cannot be address(0)\");\n require(_remoteChainId != 0, \"OptimismMintableERC721: remote chain id cannot be zero\");\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721: remote token cannot be address(0)\"\n );\n\n REMOTE_CHAIN_ID = _remoteChainId;\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n\n // Creates a base URI in the format specified by EIP-681:\n // https://eips.ethereum.org/EIPS/eip-681\n baseTokenURI = string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(_remoteToken), 20),\n \"@\",\n Strings.toString(_remoteChainId),\n \"/tokenURI?uint256=\"\n )\n );\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteChainId() external view returns (uint256) {\n return REMOTE_CHAIN_ID;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteToken() external view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function bridge() external view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function safeMint(address _to, uint256 _tokenId) external virtual onlyBridge {\n _safeMint(_to, _tokenId);\n\n emit Mint(_to, _tokenId);\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function burn(address _from, uint256 _tokenId) external virtual onlyBridge {\n _burn(_tokenId);\n\n emit Burn(_from, _tokenId);\n }\n\n /**\n * @notice Checks if a given interface ID is supported by this contract.\n *\n * @param _interfaceId The interface ID to check.\n *\n * @return True if the interface ID is supported, false otherwise.\n */\n function supportsInterface(bytes4 _interfaceId)\n public\n view\n override(ERC721Enumerable, IERC165)\n returns (bool)\n {\n bytes4 iface1 = type(IERC165).interfaceId;\n bytes4 iface2 = type(IOptimismMintableERC721).interfaceId;\n return\n _interfaceId == iface1 ||\n _interfaceId == iface2 ||\n super.supportsInterface(_interfaceId);\n }\n\n /**\n * @notice Returns the base token URI.\n *\n * @return Base token URI.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return baseTokenURI;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismMintableERC721 } from \"./OptimismMintableERC721.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @title OptimismMintableERC721Factory\n * @notice Factory contract for creating OptimismMintableERC721 contracts.\n */\ncontract OptimismMintableERC721Factory is Semver {\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Chain ID for the remote network.\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @notice Tracks addresses created by this factory.\n */\n mapping(address => bool) public isOptimismMintableERC721;\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC721 contract is created.\n *\n * @param localToken Address of the token on the this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param deployer Address of the initiator of the deployment\n */\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.1.0\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC721 token contract since this contract\n * is responsible for deploying OptimismMintableERC721 contracts.\n *\n * @param _bridge Address of the ERC721 bridge on this network.\n * @param _remoteChainId Chain ID for the remote network.\n */\n constructor(address _bridge, uint256 _remoteChainId) Semver(1, 1, 0) {\n BRIDGE = _bridge;\n REMOTE_CHAIN_ID = _remoteChainId;\n }\n\n /**\n * @notice Creates an instance of the standard ERC721.\n *\n * @param _remoteToken Address of the corresponding token on the other domain.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n function createOptimismMintableERC721(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721Factory: L1 token address cannot be address(0)\"\n );\n\n address localToken = address(\n new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)\n );\n\n isOptimismMintableERC721[localToken] = true;\n emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/Proxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Proxy\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\n * if the caller is address(0), meaning that the call originated from an off-chain\n * simulation.\n */\ncontract Proxy {\n /**\n * @notice The storage slot that holds the address of the implementation.\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice The storage slot that holds the address of the owner.\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice An event that is emitted each time the implementation is changed. This event is part\n * of the EIP-1967 specification.\n *\n * @param implementation The address of the implementation contract\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\n * EIP-1967 specification.\n *\n * @param previousAdmin The previous owner of the contract\n * @param newAdmin The new owner of the contract\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\n * eth_call to interact with this proxy without needing to use low-level storage\n * inspection. We assume that nobody is able to trigger calls from address(0) during\n * normal EVM execution.\n */\n modifier proxyCallIfNotAdmin() {\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\n * EIP-1967 admin storage slot so that accidental storage collision with the\n * implementation is not possible.\n *\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\n * transparent proxy interface.\n */\n constructor(address _admin) {\n _changeAdmin(_admin);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Set the implementation contract address. The code at the given address will execute\n * when this contract is called.\n *\n * @param _implementation Address of the implementation contract.\n */\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\n _setImplementation(_implementation);\n }\n\n /**\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\n * atomic execution of initialization-based upgrades.\n *\n * @param _implementation Address of the implementation contract.\n * @param _data Calldata to delegatecall the new implementation with.\n */\n function upgradeToAndCall(address _implementation, bytes calldata _data)\n external\n payable\n proxyCallIfNotAdmin\n returns (bytes memory)\n {\n _setImplementation(_implementation);\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\n require(success, \"Proxy: delegatecall to new implementation contract failed\");\n return returndata;\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _admin New owner of the proxy contract.\n */\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\n _changeAdmin(_admin);\n }\n\n /**\n * @notice Gets the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function admin() external proxyCallIfNotAdmin returns (address) {\n return _getAdmin();\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function implementation() external proxyCallIfNotAdmin returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n emit Upgraded(_implementation);\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _admin New owner of the proxy contract.\n */\n function _changeAdmin(address _admin) internal {\n address previous = _getAdmin();\n assembly {\n sstore(OWNER_KEY, _admin)\n }\n emit AdminChanged(previous, _admin);\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal {\n address impl = _getImplementation();\n require(impl != address(0), \"Proxy: implementation not initialized\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address impl;\n assembly {\n impl := sload(IMPLEMENTATION_KEY)\n }\n return impl;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getAdmin() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n}\n" - }, - "contracts/universal/ProxyAdmin.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { Proxy } from \"./Proxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\n\n/**\n * @title IStaticERC1967Proxy\n * @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface.\n */\ninterface IStaticERC1967Proxy {\n function implementation() external view returns (address);\n\n function admin() external view returns (address);\n}\n\n/**\n * @title IStaticL1ChugSplashProxy\n * @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface.\n */\ninterface IStaticL1ChugSplashProxy {\n function getImplementation() external view returns (address);\n\n function getOwner() external view returns (address);\n}\n\n/**\n * @title ProxyAdmin\n * @notice This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy,\n * based on the OpenZeppelin implementation. It has backwards compatibility logic to work\n * with the various types of proxies that have been deployed by Optimism in the past.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @notice The proxy types that the ProxyAdmin can manage.\n *\n * @custom:value ERC1967 Represents an ERC1967 compliant transparent proxy interface.\n * @custom:value CHUGSPLASH Represents the Chugsplash proxy interface (legacy).\n * @custom:value RESOLVED Represents the ResolvedDelegate proxy (legacy).\n */\n enum ProxyType {\n ERC1967,\n CHUGSPLASH,\n RESOLVED\n }\n\n /**\n * @notice A mapping of proxy types, used for backwards compatibility.\n */\n mapping(address => ProxyType) public proxyType;\n\n /**\n * @notice A reverse mapping of addresses to names held in the AddressManager. This must be\n * manually kept up to date with changes in the AddressManager for this contract\n * to be able to work as an admin for the ResolvedDelegateProxy type.\n */\n mapping(address => string) public implementationName;\n\n /**\n * @notice The address of the address manager, this is required to manage the\n * ResolvedDelegateProxy type.\n */\n AddressManager public addressManager;\n\n /**\n * @notice A legacy upgrading indicator used by the old Chugsplash Proxy.\n */\n bool internal upgrading;\n\n /**\n * @param _owner Address of the initial owner of this contract.\n */\n constructor(address _owner) Ownable() {\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the proxy type for a given address. Only required for non-standard (legacy)\n * proxy types.\n *\n * @param _address Address of the proxy.\n * @param _type Type of the proxy.\n */\n function setProxyType(address _address, ProxyType _type) external onlyOwner {\n proxyType[_address] = _type;\n }\n\n /**\n * @notice Sets the implementation name for a given address. Only required for\n * ResolvedDelegateProxy type proxies that have an implementation name.\n *\n * @param _address Address of the ResolvedDelegateProxy.\n * @param _name Name of the implementation for the proxy.\n */\n function setImplementationName(address _address, string memory _name) external onlyOwner {\n implementationName[_address] = _name;\n }\n\n /**\n * @notice Set the address of the AddressManager. This is required to manage legacy\n * ResolvedDelegateProxy type proxy contracts.\n *\n * @param _address Address of the AddressManager.\n */\n function setAddressManager(AddressManager _address) external onlyOwner {\n addressManager = _address;\n }\n\n /**\n * @custom:legacy\n * @notice Set an address in the address manager. Since only the owner of the AddressManager\n * can directly modify addresses and the ProxyAdmin will own the AddressManager, this\n * gives the owner of the ProxyAdmin the ability to modify addresses directly.\n *\n * @param _name Name to set within the AddressManager.\n * @param _address Address to attach to the given name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n addressManager.setAddress(_name, _address);\n }\n\n /**\n * @custom:legacy\n * @notice Set the upgrading status for the Chugsplash proxy type.\n *\n * @param _upgrading Whether or not the system is upgrading.\n */\n function setUpgrading(bool _upgrading) external onlyOwner {\n upgrading = _upgrading;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\n *\n * @return Whether or not there is an upgrade going on. May not actually tell you whether an\n * upgrade is going on, since we don't currently plan to use this variable for anything\n * other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\n */\n function isUpgrading() external view returns (bool) {\n return upgrading;\n }\n\n /**\n * @notice Returns the implementation of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the implementation of.\n *\n * @return Address of the implementation of the proxy.\n */\n function getProxyImplementation(address _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).implementation();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getImplementation();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.getAddress(implementationName[_proxy]);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Returns the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the admin of.\n *\n * @return Address of the admin of the proxy.\n */\n function getProxyAdmin(address payable _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).admin();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getOwner();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.owner();\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Updates the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to update.\n * @param _newAdmin Address of the new proxy admin.\n */\n function changeProxyAdmin(address payable _proxy, address _newAdmin) external onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).changeAdmin(_newAdmin);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setOwner(_newAdmin);\n } else if (ptype == ProxyType.RESOLVED) {\n addressManager.transferOwnership(_newAdmin);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n */\n function upgrade(address payable _proxy, address _implementation) public onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeTo(_implementation);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setStorage(\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n bytes32(uint256(uint160(_implementation)))\n );\n } else if (ptype == ProxyType.RESOLVED) {\n string memory name = implementationName[_proxy];\n addressManager.setAddress(name, _implementation);\n } else {\n // It should not be possible to retrieve a ProxyType value which is not matched by\n // one of the previous conditions.\n assert(false);\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract and delegatecalls the new implementation\n * with some given data. Useful for atomic upgrade-and-initialize calls.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n * @param _data Data to trigger the new implementation with.\n */\n function upgradeAndCall(\n address payable _proxy,\n address _implementation,\n bytes memory _data\n ) external payable onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);\n } else {\n // reverts if proxy type is unknown\n upgrade(_proxy, _implementation);\n (bool success, ) = _proxy.call{ value: msg.value }(_data);\n require(success, \"ProxyAdmin: call to proxy after upgrade failed\");\n }\n }\n}\n" - }, - "contracts/universal/Semver.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n" - }, - "contracts/universal/StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { IOptimismMintableERC20, ILegacyMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"./OptimismMintableERC20.sol\";\n\n/**\n * @custom:upgradeable\n * @title StandardBridge\n * @notice StandardBridge is a base contract for the L1 and L2 standard ERC20 bridges. It handles\n * the core bridging logic, including escrowing tokens that are native to the local chain\n * and minting/burning tokens that are native to the remote chain.\n */\nabstract contract StandardBridge {\n using SafeERC20 for IERC20;\n\n /**\n * @notice The L2 gas limit set when eth is depoisited using the receive() function.\n */\n uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000;\n\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Corresponding bridge on the other domain.\n */\n StandardBridge public immutable OTHER_BRIDGE;\n\n /**\n * @custom:legacy\n * @custom:spacer messenger\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer l2TokenBridge\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_1_0_20;\n\n /**\n * @notice Mapping that stores deposits for a given pair of local and remote tokens.\n */\n mapping(address => mapping(address => uint256)) public deposits;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n * A gap size of 47 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[47] private __gap;\n\n /**\n * @notice Emitted when an ETH bridge is initiated to the other chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ETH bridge is finalized on this chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is initiated to the other chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is finalized on this chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Only allow EOAs to call the functions. Note that this is not safe against contracts\n * calling code within their constructors, but also doesn't really matter since we're\n * just trying to prevent users accidentally depositing with smart contract wallets.\n */\n modifier onlyEOA() {\n require(\n !Address.isContract(msg.sender),\n \"StandardBridge: function can only be called from an EOA\"\n );\n _;\n }\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) &&\n MESSENGER.xDomainMessageSender() == address(OTHER_BRIDGE),\n \"StandardBridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of CrossDomainMessenger on this network.\n * @param _otherBridge Address of the other StandardBridge contract.\n */\n constructor(address payable _messenger, address payable _otherBridge) {\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = StandardBridge(_otherBridge);\n }\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n * Must be implemented by contracts that inherit.\n */\n receive() external payable virtual;\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @notice Sends ETH to the sender's address on the other chain.\n *\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETH(uint32 _minGasLimit, bytes calldata _extraData) public payable onlyEOA {\n _initiateBridgeETH(msg.sender, msg.sender, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a\n * smart contract and the call fails, the ETH will be temporarily locked in the\n * StandardBridge on the other chain until the call is replayed. If the call cannot be\n * replayed with any amount of gas (call always reverts), then the ETH will be\n * permanently locked in the StandardBridge on the other chain. ETH will also\n * be locked if the receiver is the other bridge, because finalizeBridgeETH will revert\n * in that case.\n *\n * @param _to Address of the receiver.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public payable {\n _initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ERC20 tokens to the sender's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20(\n address _localToken,\n address _remoteToken,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual onlyEOA {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public payable onlyOtherBridge {\n require(msg.value == _amount, \"StandardBridge: amount sent does not match amount required\");\n require(_to != address(this), \"StandardBridge: cannot send to self\");\n require(_to != address(MESSENGER), \"StandardBridge: cannot send to messenger\");\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n\n bool success = SafeCall.call(_to, gasleft(), _amount, hex\"\");\n require(success, \"StandardBridge: ETH transfer failed\");\n }\n\n /**\n * @notice Finalizes an ERC20 bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public onlyOtherBridge {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).mint(_to, _amount);\n } else {\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] - _amount;\n IERC20(_localToken).safeTransfer(_to, _amount);\n }\n\n // Emit the correct events. By default this will be ERC20BridgeFinalized, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Initiates a bridge of ETH through the CrossDomainMessenger.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n require(\n msg.value == _amount,\n \"StandardBridge: bridging ETH must include sufficient ETH value\"\n );\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage{ value: _amount }(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeETH.selector,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).burn(_from, _amount);\n } else {\n IERC20(_localToken).safeTransferFrom(_from, address(this), _amount);\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] + _amount;\n }\n\n // Emit the correct events. By default this will be ERC20BridgeInitiated, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeERC20.selector,\n // Because this call will be executed on the remote chain, we reverse the order of\n // the remote and local token addresses relative to their order in the\n // finalizeBridgeERC20 function.\n _remoteToken,\n _localToken,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Checks if a given address is an OptimismMintableERC20. Not perfect, but good enough.\n * Just the way we like it.\n *\n * @param _token Address of the token to check.\n *\n * @return True if the token is an OptimismMintableERC20.\n */\n function _isOptimismMintableERC20(address _token) internal view returns (bool) {\n return\n ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId) ||\n ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);\n }\n\n /**\n * @notice Checks if the \"other token\" is the correct pair token for the OptimismMintableERC20.\n * Calls can be saved in the future by combining this logic with\n * `_isOptimismMintableERC20`.\n *\n * @param _mintableToken OptimismMintableERC20 to check against.\n * @param _otherToken Pair token to check.\n *\n * @return True if the other token is the correct pair token for the OptimismMintableERC20.\n */\n function _isCorrectTokenPair(address _mintableToken, address _otherToken)\n internal\n view\n returns (bool)\n {\n if (\n ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)\n ) {\n return _otherToken == ILegacyMintableERC20(_mintableToken).l1Token();\n } else {\n return _otherToken == IOptimismMintableERC20(_mintableToken).remoteToken();\n }\n }\n\n /** @notice Emits the ETHBridgeInitiated event and if necessary the appropriate legacy event\n * when an ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ETHBridgeFinalized and if necessary the appropriate legacy event when an\n * ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeInitiated event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeFinalized event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/vendor/AddressAliasHelper.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.0;\n\nlibrary AddressAliasHelper {\n uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n /// @notice Utility function that converts the address in the L1 that submitted a tx to\n /// the inbox to the msg.sender viewed in the L2\n /// @param l1Address the address in the L1 that triggered the tx to L2\n /// @return l2Address L2 address as viewed in msg.sender\n function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {\n unchecked {\n l2Address = address(uint160(l1Address) + offset);\n }\n }\n\n /// @notice Utility function that converts the msg.sender viewed in the L2 to the\n /// address in the L1 that submitted a tx to the inbox\n /// @param l2Address L2 address as viewed in msg.sender\n /// @return l1Address the address in the L1 that triggered the tx to L2\n function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {\n unchecked {\n l1Address = address(uint160(l2Address) - offset);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/governance/utils/IVotes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20Permit.sol\";\nimport \"../../../utils/math/Math.sol\";\nimport \"../../../governance/utils/IVotes.sol\";\nimport \"../../../utils/math/SafeCast.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20Votes is IVotes, ERC20Permit {\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCast.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = Math.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSA.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"./IERC721Enumerable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n // Mapping from owner to list of owned token IDs\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n // Mapping from token ID to index of the owner tokens list\n mapping(uint256 => uint256) private _ownedTokensIndex;\n\n // Array with all token ids, used for enumeration\n uint256[] private _allTokens;\n\n // Mapping from token id to position in the allTokens array\n mapping(uint256 => uint256) private _allTokensIndex;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n return _ownedTokens[owner][index];\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _allTokens.length;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721Enumerable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n return _allTokens[index];\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n if (from == address(0)) {\n _addTokenToAllTokensEnumeration(tokenId);\n } else if (from != to) {\n _removeTokenFromOwnerEnumeration(from, tokenId);\n }\n if (to == address(0)) {\n _removeTokenFromAllTokensEnumeration(tokenId);\n } else if (to != from) {\n _addTokenToOwnerEnumeration(to, tokenId);\n }\n }\n\n /**\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\n * @param to address representing the new owner of the given token ID\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n */\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n uint256 length = ERC721.balanceOf(to);\n _ownedTokens[to][length] = tokenId;\n _ownedTokensIndex[tokenId] = length;\n }\n\n /**\n * @dev Private function to add a token to this extension's token tracking data structures.\n * @param tokenId uint256 ID of the token to be added to the tokens list\n */\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n _allTokensIndex[tokenId] = _allTokens.length;\n _allTokens.push(tokenId);\n }\n\n /**\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n * @param from address representing the previous owner of the given token ID\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n */\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary\n if (tokenIndex != lastTokenIndex) {\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n }\n\n // This also deletes the contents at the last position of the array\n delete _ownedTokensIndex[tokenId];\n delete _ownedTokens[from][lastTokenIndex];\n }\n\n /**\n * @dev Private function to remove a token from this extension's token tracking data structures.\n * This has O(1) time complexity, but alters the order of the _allTokens array.\n * @param tokenId uint256 ID of the token to be removed from the tokens list\n */\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = _allTokens.length - 1;\n uint256 tokenIndex = _allTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n // This also deletes the contents at the last position of the array\n delete _allTokensIndex[tokenId];\n _allTokens.pop();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Counters.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface,\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n _supportsERC165Interface(account, type(IERC165).interfaceId) &&\n !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)\n internal\n view\n returns (bool[] memory)\n {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in _interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!_supportsERC165Interface(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n * Interface identification is specified in ERC-165.\n */\n function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/Bytes32AddressLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Library for converting between addresses and bytes32 values.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)\nlibrary Bytes32AddressLib {\n function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {\n return bytes32(bytes20(addressValue));\n }\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n /*//////////////////////////////////////////////////////////////\n SIMPLIFIED FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n }\n\n function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n }\n\n function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n }\n\n function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n }\n\n function powWad(int256 x, int256 y) internal pure returns (int256) {\n // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\n return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\n }\n\n function expWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n // When the result is < 0.5 we return zero. This happens when\n // x <= floor(log(0.5e18) * 1e18) ~ -42e18\n if (x <= -42139678854452767551) return 0;\n\n // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\n // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\n if (x >= 135305999368893231589) revert(\"EXP_OVERFLOW\");\n\n // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\n // for more intermediate precision and a binary basis. This base conversion\n // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n x = (x << 78) / 5**18;\n\n // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\n x = x - k * 54916777467707473351141471128;\n\n // k is in the range [-61, 195].\n\n // Evaluate using a (6, 7)-term rational approximation.\n // p is made monic, we'll multiply by a scale factor later.\n int256 y = x + 1346386616545796478920950773328;\n y = ((y * x) >> 96) + 57155421227552351082224309758442;\n int256 p = y + x - 94201549194550492254356042504812;\n p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n p = p * x + (4385272521454847904659076985693276 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n int256 q = x - 2855989394907223263936484059900;\n q = ((q * x) >> 96) + 50020603652535783019961831881945;\n q = ((q * x) >> 96) - 533845033583426703283633433725380;\n q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial won't have zeros in the domain as all its roots are complex.\n // No scaling is necessary because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r should be in the range (0.09, 0.25) * 2**96.\n\n // We now need to multiply r by:\n // * the scale factor s = ~6.031367120.\n // * the 2**k factor from the range reduction.\n // * the 1e18 / 2**96 factor for base conversion.\n // We do this all at once, with an intermediate result in 2**213\n // basis, so the final right shift is always by a positive amount.\n r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\n }\n }\n\n function lnWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n require(x > 0, \"UNDEFINED\");\n\n // We want to convert x from 10**18 fixed point to 2**96 fixed point.\n // We do this by multiplying by 2**96 / 10**18. But since\n // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\n // and add ln(2**96 / 10**18) at the end.\n\n // Reduce range of x to (1, 2) * 2**96\n // ln(2^k * x) = k * ln(2) + ln(x)\n int256 k = int256(log2(uint256(x))) - 96;\n x <<= uint256(159 - k);\n x = int256(uint256(x) >> 159);\n\n // Evaluate using a (8, 8)-term rational approximation.\n // p is made monic, we will multiply by a scale factor later.\n int256 p = x + 3273285459638523848632254066296;\n p = ((p * x) >> 96) + 24828157081833163892658089445524;\n p = ((p * x) >> 96) + 43456485725739037958740375743393;\n p = ((p * x) >> 96) - 11111509109440967052023855526967;\n p = ((p * x) >> 96) - 45023709667254063763336534515857;\n p = ((p * x) >> 96) - 14706773417378608786704636184526;\n p = p * x - (795164235651350426258249787498 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n // q is monic by convention.\n int256 q = x + 5573035233440673466300451813936;\n q = ((q * x) >> 96) + 71694874799317883764090561454958;\n q = ((q * x) >> 96) + 283447036172924575727196451306956;\n q = ((q * x) >> 96) + 401686690394027663651624208769553;\n q = ((q * x) >> 96) + 204048457590392012362485061816622;\n q = ((q * x) >> 96) + 31853899698501571402653359427138;\n q = ((q * x) >> 96) + 909429971244387300277376558375;\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial is known not to have zeros in the domain.\n // No scaling required because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r is in the range (0, 0.125) * 2**96\n\n // Finalization, we need to:\n // * multiply by the scale factor s = 5.549…\n // * add ln(2**96 / 10**18)\n // * add k * ln(2)\n // * multiply by 10**18 / 2**96 = 5**18 >> 78\n\n // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\n r *= 1677202110996718588342820967067443963516166;\n // add ln(2) * k * 5e18 * 2**192\n r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\n // add ln(2**96 / 10**18) * 5e18 * 2**192\n r += 600920179829731861736702779321621459595472258049074101567377883020018308;\n // base conversion: mul 2**18 / 2**192\n r >>= 174;\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n LOW LEVEL FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function mulDivDown(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // Divide z by the denominator.\n z := div(z, denominator)\n }\n }\n\n function mulDivUp(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // First, divide z - 1 by the denominator and add 1.\n // We allow z - 1 to underflow if z is 0, because we multiply the\n // end result by 0 if z is zero, ensuring we return 0 if z is zero.\n z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\n }\n }\n\n function rpow(\n uint256 x,\n uint256 n,\n uint256 scalar\n ) internal pure returns (uint256 z) {\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n // 0 ** 0 = 1\n z := scalar\n }\n default {\n // 0 ** n = 0\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n // If n is even, store scalar in z for now.\n z := scalar\n }\n default {\n // If n is odd, store x in z for now.\n z := x\n }\n\n // Shifting right by 1 is like dividing by 2.\n let half := shr(1, scalar)\n\n for {\n // Shift n right by 1 before looping to halve it.\n n := shr(1, n)\n } n {\n // Shift n right by 1 each iteration to halve it.\n n := shr(1, n)\n } {\n // Revert immediately if x ** 2 would overflow.\n // Equivalent to iszero(eq(div(xx, x), x)) here.\n if shr(128, x) {\n revert(0, 0)\n }\n\n // Store x squared.\n let xx := mul(x, x)\n\n // Round to the nearest number.\n let xxRound := add(xx, half)\n\n // Revert if xx + half overflowed.\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n\n // Set x to scaled xxRound.\n x := div(xxRound, scalar)\n\n // If n is even:\n if mod(n, 2) {\n // Compute z * x.\n let zx := mul(z, x)\n\n // If z * x overflowed:\n if iszero(eq(div(zx, x), z)) {\n // Revert if x is non-zero.\n if iszero(iszero(x)) {\n revert(0, 0)\n }\n }\n\n // Round to the nearest number.\n let zxRound := add(zx, half)\n\n // Revert if zx + half overflowed.\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n\n // Return properly scaled zxRound.\n z := div(zxRound, scalar)\n }\n }\n }\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n GENERAL NUMBER UTILITIES\n //////////////////////////////////////////////////////////////*/\n\n function sqrt(uint256 x) internal pure returns (uint256 z) {\n assembly {\n let y := x // We start y at x, which will help us make our initial estimate.\n\n z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n // We check y >= 2^(k + 8) but shift right by k bits\n // each branch to ensure that if x >= 256, then y >= 256.\n if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n y := shr(128, y)\n z := shl(64, z)\n }\n if iszero(lt(y, 0x1000000000000000000)) {\n y := shr(64, y)\n z := shl(32, z)\n }\n if iszero(lt(y, 0x10000000000)) {\n y := shr(32, y)\n z := shl(16, z)\n }\n if iszero(lt(y, 0x1000000)) {\n y := shr(16, y)\n z := shl(8, z)\n }\n\n // Goal was to get z*z*y within a small factor of x. More iterations could\n // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n // There is no overflow risk here since y < 2^136 after the first branch above.\n z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n\n // If x+1 is a perfect square, the Babylonian method cycles between\n // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n z := sub(z, lt(div(x, z), z))\n }\n }\n\n function log2(uint256 x) internal pure returns (uint256 r) {\n require(x > 0, \"UNDEFINED\");\n\n assembly {\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\n r := or(r, shl(3, lt(0xff, shr(r, x))))\n r := or(r, shl(2, lt(0xf, shr(r, x))))\n r := or(r, shl(1, lt(0x3, shr(r, x))))\n r := or(r, lt(0x1, shr(r, x)))\n }\n }\n}\n" - }, - "node_modules/ds-test/src/test.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.5.0;\n\ncontract DSTest {\n event log (string);\n event logs (bytes);\n\n event log_address (address);\n event log_bytes32 (bytes32);\n event log_int (int);\n event log_uint (uint);\n event log_bytes (bytes);\n event log_string (string);\n\n event log_named_address (string key, address val);\n event log_named_bytes32 (string key, bytes32 val);\n event log_named_decimal_int (string key, int val, uint decimals);\n event log_named_decimal_uint (string key, uint val, uint decimals);\n event log_named_int (string key, int val);\n event log_named_uint (string key, uint val);\n event log_named_bytes (string key, bytes val);\n event log_named_string (string key, string val);\n\n bool public IS_TEST = true;\n bool private _failed;\n\n address constant HEVM_ADDRESS =\n address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));\n\n modifier mayRevert() { _; }\n modifier testopts(string memory) { _; }\n\n function failed() public returns (bool) {\n if (_failed) {\n return _failed;\n } else {\n bool globalFailed = false;\n if (hasHEVMContext()) {\n (, bytes memory retdata) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"load(address,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"))\n )\n );\n globalFailed = abi.decode(retdata, (bool));\n }\n return globalFailed;\n }\n } \n\n function fail() internal {\n if (hasHEVMContext()) {\n (bool status, ) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"store(address,bytes32,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"), bytes32(uint256(0x01)))\n )\n );\n status; // Silence compiler warnings\n }\n _failed = true;\n }\n\n function hasHEVMContext() internal view returns (bool) {\n uint256 hevmCodeSize = 0;\n assembly {\n hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D)\n }\n return hevmCodeSize > 0;\n }\n\n modifier logs_gas() {\n uint startGas = gasleft();\n _;\n uint endGas = gasleft();\n emit log_named_uint(\"gas\", startGas - endGas);\n }\n\n function assertTrue(bool condition) internal {\n if (!condition) {\n emit log(\"Error: Assertion Failed\");\n fail();\n }\n }\n\n function assertTrue(bool condition, string memory err) internal {\n if (!condition) {\n emit log_named_string(\"Error\", err);\n assertTrue(condition);\n }\n }\n\n function assertEq(address a, address b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [address]\");\n emit log_named_address(\" Expected\", b);\n emit log_named_address(\" Actual\", a);\n fail();\n }\n }\n function assertEq(address a, address b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes32 a, bytes32 b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bytes32]\");\n emit log_named_bytes32(\" Expected\", b);\n emit log_named_bytes32(\" Actual\", a);\n fail();\n }\n }\n function assertEq(bytes32 a, bytes32 b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq32(bytes32 a, bytes32 b) internal {\n assertEq(a, b);\n }\n function assertEq32(bytes32 a, bytes32 b, string memory err) internal {\n assertEq(a, b, err);\n }\n\n function assertEq(int a, int b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [int]\");\n emit log_named_int(\" Expected\", b);\n emit log_named_int(\" Actual\", a);\n fail();\n }\n }\n function assertEq(int a, int b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq(uint a, uint b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [uint]\");\n emit log_named_uint(\" Expected\", b);\n emit log_named_uint(\" Actual\", a);\n fail();\n }\n }\n function assertEq(uint a, uint b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEqDecimal(int a, int b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Expected\", b, decimals);\n emit log_named_decimal_int(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Expected\", b, decimals);\n emit log_named_decimal_uint(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n\n function assertGt(uint a, uint b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGt(uint a, uint b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGt(int a, int b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGt(int a, int b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGtDecimal(int a, int b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n\n function assertGe(uint a, uint b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGe(uint a, uint b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGe(int a, int b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGe(int a, int b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGeDecimal(int a, int b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertLt(uint a, uint b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLt(uint a, uint b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLt(int a, int b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLt(int a, int b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLtDecimal(int a, int b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n\n function assertLe(uint a, uint b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLe(uint a, uint b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLe(int a, int b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLe(int a, int b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLeDecimal(int a, int b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLeDecimal(a, b, decimals);\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertEq(string memory a, string memory b) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log(\"Error: a == b not satisfied [string]\");\n emit log_named_string(\" Expected\", b);\n emit log_named_string(\" Actual\", a);\n fail();\n }\n }\n function assertEq(string memory a, string memory b, string memory err) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {\n ok = true;\n if (a.length == b.length) {\n for (uint i = 0; i < a.length; i++) {\n if (a[i] != b[i]) {\n ok = false;\n }\n }\n } else {\n ok = false;\n }\n }\n function assertEq0(bytes memory a, bytes memory b) internal {\n if (!checkEq0(a, b)) {\n emit log(\"Error: a == b not satisfied [bytes]\");\n emit log_named_bytes(\" Expected\", b);\n emit log_named_bytes(\" Actual\", a);\n fail();\n }\n }\n function assertEq0(bytes memory a, bytes memory b, string memory err) internal {\n if (!checkEq0(a, b)) {\n emit log_named_string(\"Error\", err);\n assertEq0(a, b);\n }\n }\n}\n" - }, - "node_modules/forge-std/src/Base.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {StdStorage} from \"./StdStorage.sol\";\nimport {Vm, VmSafe} from \"./Vm.sol\";\n\nabstract contract CommonBase {\n // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.\n address internal constant VM_ADDRESS = address(uint160(uint256(keccak256(\"hevm cheat code\"))));\n // console.sol and console2.sol work by executing a staticcall to this address.\n address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;\n // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38.\n address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256(\"foundry default caller\"))));\n // Address of the test contract, deployed by the DEFAULT_SENDER.\n address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;\n // Deterministic deployment address of the Multicall3 contract.\n address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11;\n\n uint256 internal constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n Vm internal constant vm = Vm(VM_ADDRESS);\n StdStorage internal stdstore;\n}\n\nabstract contract TestBase is CommonBase {}\n\nabstract contract ScriptBase is CommonBase {\n // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);\n}\n" - }, - "node_modules/forge-std/src/StdAssertions.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {DSTest} from \"ds-test/test.sol\";\nimport {stdMath} from \"./StdMath.sol\";\n\nabstract contract StdAssertions is DSTest {\n event log_array(uint256[] val);\n event log_array(int256[] val);\n event log_array(address[] val);\n event log_named_array(string key, uint256[] val);\n event log_named_array(string key, int256[] val);\n event log_named_array(string key, address[] val);\n\n function fail(string memory err) internal virtual {\n emit log_named_string(\"Error\", err);\n fail();\n }\n\n function assertFalse(bool data) internal virtual {\n assertTrue(!data);\n }\n\n function assertFalse(bool data, string memory err) internal virtual {\n assertTrue(!data, err);\n }\n\n function assertEq(bool a, bool b) internal virtual {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bool]\");\n emit log_named_string(\" Left\", a ? \"true\" : \"false\");\n emit log_named_string(\" Right\", b ? \"true\" : \"false\");\n fail();\n }\n }\n\n function assertEq(bool a, bool b, string memory err) internal virtual {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes memory a, bytes memory b) internal virtual {\n assertEq0(a, b);\n }\n\n function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual {\n assertEq0(a, b, err);\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [uint[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [int[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(address[] memory a, address[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [address[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n // Legacy helper\n function assertEqUint(uint256 a, uint256 b) internal virtual {\n assertEq(uint256(a), uint256(b));\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100%\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals,\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual {\n assertEqCall(target, callDataA, target, callDataB, true);\n }\n\n function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB)\n internal\n virtual\n {\n assertEqCall(targetA, callDataA, targetB, callDataB, true);\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData)\n internal\n virtual\n {\n assertEqCall(target, callDataA, target, callDataB, strictRevertData);\n }\n\n function assertEqCall(\n address targetA,\n bytes memory callDataA,\n address targetB,\n bytes memory callDataB,\n bool strictRevertData\n ) internal virtual {\n (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA);\n (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB);\n\n if (successA && successB) {\n assertEq(returnDataA, returnDataB, \"Call return data does not match\");\n }\n\n if (!successA && !successB && strictRevertData) {\n assertEq(returnDataA, returnDataB, \"Call revert data does not match\");\n }\n\n if (!successA && successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call revert data\", returnDataA);\n emit log_named_bytes(\" Right call return data\", returnDataB);\n fail();\n }\n\n if (successA && !successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call return data\", returnDataA);\n emit log_named_bytes(\" Right call revert data\", returnDataB);\n fail();\n }\n }\n}\n" - }, - "node_modules/forge-std/src/StdChains.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n/**\n * StdChains provides information about EVM compatible chains that can be used in scripts/tests.\n * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are\n * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of\n * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the\n * alias used in this contract, which can be found as the first argument to the\n * `setChainWithDefaultRpcUrl` call in the `initialize` function.\n *\n * There are two main ways to use this contract:\n * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or\n * `setChain(string memory chainAlias, Chain memory chain)`\n * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`.\n *\n * The first time either of those are used, chains are initialized with the default set of RPC URLs.\n * This is done in `initialize`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in\n * `defaultRpcUrls`.\n *\n * The `setChain` function is straightforward, and it simply saves off the given chain data.\n *\n * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say\n * we want to retrieve `mainnet`'s RPC URL:\n * - If you haven't set any mainnet chain info with `setChain`, you haven't specified that\n * chain in `foundry.toml` and no env var is set, the default data and RPC URL will be returned.\n * - If you have set a mainnet RPC URL in `foundry.toml` it will return that, if valid (e.g. if\n * a URL is given or if an environment variable is given and that environment variable exists).\n * Otherwise, the default data is returned.\n * - If you specified data with `setChain` it will return that.\n *\n * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.\n */\nabstract contract StdChains {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private initialized;\n\n struct ChainData {\n string name;\n uint256 chainId;\n string rpcUrl;\n }\n\n struct Chain {\n // The chain name.\n string name;\n // The chain's Chain ID.\n uint256 chainId;\n // The chain's alias. (i.e. what gets specified in `foundry.toml`).\n string chainAlias;\n // A default RPC endpoint for this chain.\n // NOTE: This default RPC URL is included for convenience to facilitate quick tests and\n // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy\n // usage as you will be throttled and this is a disservice to others who need this endpoint.\n string rpcUrl;\n }\n\n // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data.\n mapping(string => Chain) private chains;\n // Maps from the chain's alias to it's default RPC URL.\n mapping(string => string) private defaultRpcUrls;\n // Maps from a chain ID to it's alias.\n mapping(uint256 => string) private idToAlias;\n\n bool private fallbackToDefaultRpcUrls = true;\n\n // The RPC URL will be fetched from config or defaultRpcUrls if possible.\n function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) {\n require(bytes(chainAlias).length != 0, \"StdChains getChain(string): Chain alias cannot be the empty string.\");\n\n initialize();\n chain = chains[chainAlias];\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(string): Chain with alias \\\"\", chainAlias, \"\\\" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n function getChain(uint256 chainId) internal virtual returns (Chain memory chain) {\n require(chainId != 0, \"StdChains getChain(uint256): Chain ID cannot be 0.\");\n initialize();\n string memory chainAlias = idToAlias[chainId];\n\n chain = chains[chainAlias];\n\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(uint256): Chain with ID \", vm.toString(chainId), \" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, ChainData memory chain) internal virtual {\n require(\n bytes(chainAlias).length != 0,\n \"StdChains setChain(string,ChainData): Chain alias cannot be the empty string.\"\n );\n\n require(chain.chainId != 0, \"StdChains setChain(string,ChainData): Chain ID cannot be 0.\");\n\n initialize();\n string memory foundAlias = idToAlias[chain.chainId];\n\n require(\n bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)),\n string(\n abi.encodePacked(\n \"StdChains setChain(string,ChainData): Chain ID \",\n vm.toString(chain.chainId),\n \" already used by \\\"\",\n foundAlias,\n \"\\\".\"\n )\n )\n );\n\n uint256 oldChainId = chains[chainAlias].chainId;\n delete idToAlias[oldChainId];\n\n chains[chainAlias] =\n Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl});\n idToAlias[chain.chainId] = chainAlias;\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, Chain memory chain) internal virtual {\n setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl}));\n }\n\n function _toUpper(string memory str) private pure returns (string memory) {\n bytes memory strb = bytes(str);\n bytes memory copy = new bytes(strb.length);\n for (uint256 i = 0; i < strb.length; i++) {\n bytes1 b = strb[i];\n if (b >= 0x61 && b <= 0x7A) {\n copy[i] = bytes1(uint8(b) - 32);\n } else {\n copy[i] = b;\n }\n }\n return string(copy);\n }\n\n // lookup rpcUrl, in descending order of priority:\n // current -> config (foundry.toml) -> environment variable -> default\n function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) {\n if (bytes(chain.rpcUrl).length == 0) {\n try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) {\n chain.rpcUrl = configRpcUrl;\n } catch (bytes memory err) {\n string memory envName = string(abi.encodePacked(_toUpper(chainAlias), \"_RPC_URL\"));\n if (fallbackToDefaultRpcUrls) {\n chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]);\n } else {\n chain.rpcUrl = vm.envString(envName);\n }\n // distinguish 'not found' from 'cannot read'\n bytes memory notFoundError =\n abi.encodeWithSignature(\"CheatCodeError\", string(abi.encodePacked(\"invalid rpc url \", chainAlias)));\n if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, err), mload(err))\n }\n }\n }\n }\n return chain;\n }\n\n function setFallbackToDefaultRpcUrls(bool useDefault) internal {\n fallbackToDefaultRpcUrls = useDefault;\n }\n\n function initialize() private {\n if (initialized) return;\n\n initialized = true;\n\n // If adding an RPC here, make sure to test the default RPC URL in `testRpcs`\n setChainWithDefaultRpcUrl(\"anvil\", ChainData(\"Anvil\", 31337, \"http://127.0.0.1:8545\"));\n setChainWithDefaultRpcUrl(\n \"mainnet\", ChainData(\"Mainnet\", 1, \"https://mainnet.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"goerli\", ChainData(\"Goerli\", 5, \"https://goerli.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"sepolia\", ChainData(\"Sepolia\", 11155111, \"https://sepolia.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\"optimism\", ChainData(\"Optimism\", 10, \"https://mainnet.optimism.io\"));\n setChainWithDefaultRpcUrl(\"optimism_goerli\", ChainData(\"Optimism Goerli\", 420, \"https://goerli.optimism.io\"));\n setChainWithDefaultRpcUrl(\"arbitrum_one\", ChainData(\"Arbitrum One\", 42161, \"https://arb1.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\n \"arbitrum_one_goerli\", ChainData(\"Arbitrum One Goerli\", 421613, \"https://goerli-rollup.arbitrum.io/rpc\")\n );\n setChainWithDefaultRpcUrl(\"arbitrum_nova\", ChainData(\"Arbitrum Nova\", 42170, \"https://nova.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\"polygon\", ChainData(\"Polygon\", 137, \"https://polygon-rpc.com\"));\n setChainWithDefaultRpcUrl(\n \"polygon_mumbai\", ChainData(\"Polygon Mumbai\", 80001, \"https://rpc-mumbai.maticvigil.com\")\n );\n setChainWithDefaultRpcUrl(\"avalanche\", ChainData(\"Avalanche\", 43114, \"https://api.avax.network/ext/bc/C/rpc\"));\n setChainWithDefaultRpcUrl(\n \"avalanche_fuji\", ChainData(\"Avalanche Fuji\", 43113, \"https://api.avax-test.network/ext/bc/C/rpc\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain\", ChainData(\"BNB Smart Chain\", 56, \"https://bsc-dataseed1.binance.org\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain_testnet\",\n ChainData(\"BNB Smart Chain Testnet\", 97, \"https://rpc.ankr.com/bsc_testnet_chapel\")\n );\n setChainWithDefaultRpcUrl(\"gnosis_chain\", ChainData(\"Gnosis Chain\", 100, \"https://rpc.gnosischain.com\"));\n }\n\n // set chain info, with priority to chainAlias' rpc url in foundry.toml\n function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private {\n string memory rpcUrl = chain.rpcUrl;\n defaultRpcUrls[chainAlias] = rpcUrl;\n chain.rpcUrl = \"\";\n setChain(chainAlias, chain);\n chain.rpcUrl = rpcUrl; // restore argument\n }\n}\n" - }, - "node_modules/forge-std/src/StdCheats.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdCheatsSafe {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private gasMeteringOff;\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawTx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n // json value name = function\n string functionSig;\n bytes32 hash;\n // json value name = tx\n RawTx1559Detail txDetail;\n // json value name = type\n string opcode;\n }\n\n struct RawTx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n bytes gas;\n bytes nonce;\n address to;\n bytes txType;\n bytes value;\n }\n\n struct Tx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n bytes32 hash;\n Tx1559Detail txDetail;\n string opcode;\n }\n\n struct Tx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n uint256 gas;\n uint256 nonce;\n address to;\n uint256 txType;\n uint256 value;\n }\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct TxLegacy {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n string hash;\n string opcode;\n TxDetailLegacy transaction;\n }\n\n struct TxDetailLegacy {\n AccessList[] accessList;\n uint256 chainId;\n bytes data;\n address from;\n uint256 gas;\n uint256 gasPrice;\n bytes32 hash;\n uint256 nonce;\n bytes1 opcode;\n bytes32 r;\n bytes32 s;\n uint256 txType;\n address to;\n uint8 v;\n uint256 value;\n }\n\n struct AccessList {\n address accessAddress;\n bytes32[] storageKeys;\n }\n\n // Data structures to parse Receipt objects from the broadcast artifact.\n // The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawReceipt {\n bytes32 blockHash;\n bytes blockNumber;\n address contractAddress;\n bytes cumulativeGasUsed;\n bytes effectiveGasPrice;\n address from;\n bytes gasUsed;\n RawReceiptLog[] logs;\n bytes logsBloom;\n bytes status;\n address to;\n bytes32 transactionHash;\n bytes transactionIndex;\n }\n\n struct Receipt {\n bytes32 blockHash;\n uint256 blockNumber;\n address contractAddress;\n uint256 cumulativeGasUsed;\n uint256 effectiveGasPrice;\n address from;\n uint256 gasUsed;\n ReceiptLog[] logs;\n bytes logsBloom;\n uint256 status;\n address to;\n bytes32 transactionHash;\n uint256 transactionIndex;\n }\n\n // Data structures to parse the entire broadcast artifact, assuming the\n // transactions conform to EIP1559.\n\n struct EIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n Receipt[] receipts;\n uint256 timestamp;\n Tx1559[] transactions;\n TxReturn[] txReturns;\n }\n\n struct RawEIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n RawReceipt[] receipts;\n TxReturn[] txReturns;\n uint256 timestamp;\n RawTx1559[] transactions;\n }\n\n struct RawReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n bytes blockNumber;\n bytes data;\n bytes logIndex;\n bool removed;\n bytes32[] topics;\n bytes32 transactionHash;\n bytes transactionIndex;\n bytes transactionLogIndex;\n }\n\n struct ReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n uint256 blockNumber;\n bytes data;\n uint256 logIndex;\n bytes32[] topics;\n uint256 transactionIndex;\n uint256 transactionLogIndex;\n bool removed;\n }\n\n struct TxReturn {\n string internalType;\n string value;\n }\n\n function assumeNoPrecompiles(address addr) internal virtual {\n // Assembly required since `block.chainid` was introduced in 0.8.0.\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n assumeNoPrecompiles(addr, chainId);\n }\n\n function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual {\n // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific\n // address), but the same rationale for excluding them applies so we include those too.\n\n // These should be present on all EVM-compatible chains.\n vm.assume(addr < address(0x1) || addr > address(0x9));\n\n // forgefmt: disable-start\n if (chainId == 10 || chainId == 420) {\n // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21\n vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800));\n } else if (chainId == 42161 || chainId == 421613) {\n // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains\n vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068));\n } else if (chainId == 43114 || chainId == 43113) {\n // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59\n vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff));\n vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF));\n vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff));\n }\n // forgefmt: disable-end\n }\n\n function readEIP1559ScriptArtifact(string memory path)\n internal\n view\n virtual\n returns (EIP1559ScriptArtifact memory)\n {\n string memory data = vm.readFile(path);\n bytes memory parsedData = vm.parseJson(data);\n RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact));\n EIP1559ScriptArtifact memory artifact;\n artifact.libraries = rawArtifact.libraries;\n artifact.path = rawArtifact.path;\n artifact.timestamp = rawArtifact.timestamp;\n artifact.pending = rawArtifact.pending;\n artifact.txReturns = rawArtifact.txReturns;\n artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts);\n artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions);\n return artifact;\n }\n\n function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) {\n Tx1559[] memory txs = new Tx1559[](rawTxs.length);\n for (uint256 i; i < rawTxs.length; i++) {\n txs[i] = rawToConvertedEIPTx1559(rawTxs[i]);\n }\n return txs;\n }\n\n function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) {\n Tx1559 memory transaction;\n transaction.arguments = rawTx.arguments;\n transaction.contractName = rawTx.contractName;\n transaction.functionSig = rawTx.functionSig;\n transaction.hash = rawTx.hash;\n transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail);\n transaction.opcode = rawTx.opcode;\n return transaction;\n }\n\n function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail)\n internal\n pure\n virtual\n returns (Tx1559Detail memory)\n {\n Tx1559Detail memory txDetail;\n txDetail.data = rawDetail.data;\n txDetail.from = rawDetail.from;\n txDetail.to = rawDetail.to;\n txDetail.nonce = _bytesToUint(rawDetail.nonce);\n txDetail.txType = _bytesToUint(rawDetail.txType);\n txDetail.value = _bytesToUint(rawDetail.value);\n txDetail.gas = _bytesToUint(rawDetail.gas);\n txDetail.accessList = rawDetail.accessList;\n return txDetail;\n }\n\n function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".transactions\");\n RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[]));\n return rawToConvertedEIPTx1559s(rawTxs);\n }\n\n function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".transactions[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559));\n return rawToConvertedEIPTx1559(rawTx);\n }\n\n // Analogous to readTransactions, but for receipts.\n function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".receipts\");\n RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[]));\n return rawToConvertedReceipts(rawReceipts);\n }\n\n function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".receipts[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt));\n return rawToConvertedReceipt(rawReceipt);\n }\n\n function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) {\n Receipt[] memory receipts = new Receipt[](rawReceipts.length);\n for (uint256 i; i < rawReceipts.length; i++) {\n receipts[i] = rawToConvertedReceipt(rawReceipts[i]);\n }\n return receipts;\n }\n\n function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) {\n Receipt memory receipt;\n receipt.blockHash = rawReceipt.blockHash;\n receipt.to = rawReceipt.to;\n receipt.from = rawReceipt.from;\n receipt.contractAddress = rawReceipt.contractAddress;\n receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice);\n receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed);\n receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed);\n receipt.status = _bytesToUint(rawReceipt.status);\n receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex);\n receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber);\n receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs);\n receipt.logsBloom = rawReceipt.logsBloom;\n receipt.transactionHash = rawReceipt.transactionHash;\n return receipt;\n }\n\n function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs)\n internal\n pure\n virtual\n returns (ReceiptLog[] memory)\n {\n ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length);\n for (uint256 i; i < rawLogs.length; i++) {\n logs[i].logAddress = rawLogs[i].logAddress;\n logs[i].blockHash = rawLogs[i].blockHash;\n logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber);\n logs[i].data = rawLogs[i].data;\n logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex);\n logs[i].topics = rawLogs[i].topics;\n logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex);\n logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex);\n logs[i].removed = rawLogs[i].removed;\n }\n return logs;\n }\n\n // Deploy a contract by fetching the contract bytecode from\n // the artifacts directory\n // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))`\n function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes): Deployment failed.\");\n }\n\n function deployCode(string memory what) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string): Deployment failed.\");\n }\n\n /// @dev deploy contract with value on construction\n function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes,uint256): Deployment failed.\");\n }\n\n function deployCode(string memory what, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,uint256): Deployment failed.\");\n }\n\n // creates a labeled address and the corresponding private key\n function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) {\n privateKey = uint256(keccak256(abi.encodePacked(name)));\n addr = vm.addr(privateKey);\n vm.label(addr, name);\n }\n\n // creates a labeled address\n function makeAddr(string memory name) internal virtual returns (address addr) {\n (addr,) = makeAddrAndKey(name);\n }\n\n function deriveRememberKey(string memory mnemonic, uint32 index)\n internal\n virtual\n returns (address who, uint256 privateKey)\n {\n privateKey = vm.deriveKey(mnemonic, index);\n who = vm.rememberKey(privateKey);\n }\n\n function _bytesToUint(bytes memory b) private pure returns (uint256) {\n require(b.length <= 32, \"StdCheats _bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n function isFork() internal view virtual returns (bool status) {\n try vm.activeFork() {\n status = true;\n } catch (bytes memory) {}\n }\n\n modifier skipWhenForking() {\n if (!isFork()) {\n _;\n }\n }\n\n modifier skipWhenNotForking() {\n if (isFork()) {\n _;\n }\n }\n\n modifier noGasMetering() {\n vm.pauseGasMetering();\n // To prevent turning gas monitoring back on with nested functions that use this modifier,\n // we check if gasMetering started in the off position. If it did, we don't want to turn\n // it back on until we exit the top level function that used the modifier\n //\n // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well.\n // funcA will have `gasStartedOff` as false, funcB will have it as true,\n // so we only turn metering back on at the end of the funcA\n bool gasStartedOff = gasMeteringOff;\n gasMeteringOff = true;\n\n _;\n\n // if gas metering was on when this modifier was called, turn it back on at the end\n if (!gasStartedOff) {\n gasMeteringOff = false;\n vm.resumeGasMetering();\n }\n }\n\n // a cheat for fuzzing addresses that are payable only\n // see https://github.com/foundry-rs/foundry/issues/3631\n function assumePayable(address addr) internal virtual {\n (bool success,) = payable(addr).call{value: 0}(\"\");\n vm.assume(success);\n }\n}\n\n// Wrappers around cheatcodes to avoid footguns\nabstract contract StdCheats is StdCheatsSafe {\n using stdStorage for StdStorage;\n\n StdStorage private stdstore;\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n // Skip forward or rewind time by the specified number of seconds\n function skip(uint256 time) internal virtual {\n vm.warp(block.timestamp + time);\n }\n\n function rewind(uint256 time) internal virtual {\n vm.warp(block.timestamp - time);\n }\n\n // Setup a prank from an address that has some ether\n function hoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender, origin);\n }\n\n function hoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender, origin);\n }\n\n // Start perpetual prank from an address that has some ether\n function startHoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender);\n }\n\n function startHoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender);\n }\n\n // Start perpetual prank from an address that has some ether\n // tx.origin is set to the origin parameter\n function startHoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender, origin);\n }\n\n function startHoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender, origin);\n }\n\n function changePrank(address msgSender) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender);\n }\n\n function changePrank(address msgSender, address txOrigin) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender, txOrigin);\n }\n\n // The same as Vm's `deal`\n // Use the alternative signature for ERC20 tokens\n function deal(address to, uint256 give) internal virtual {\n vm.deal(to, give);\n }\n\n // Set the balance of an account for any ERC20 token\n // Use the alternative signature to update `totalSupply`\n function deal(address token, address to, uint256 give) internal virtual {\n deal(token, to, give, false);\n }\n\n // Set the balance of an account for any ERC1155 token\n // Use the alternative signature to update `totalSupply`\n function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual {\n dealERC1155(token, to, id, give, false);\n }\n\n function deal(address token, address to, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd));\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0x18160ddd).checked_write(totSup);\n }\n }\n\n function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x00fdd58e, to, id));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0xbd85b039, id));\n require(\n totSupData.length != 0,\n \"StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply.\"\n );\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup);\n }\n }\n\n function dealERC721(address token, address to, uint256 id) internal virtual {\n // check if token id is already minted and the actual owner.\n (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id));\n require(successMinted, \"StdCheats deal(address,address,uint,bool): id not minted.\");\n\n // get owner current balance\n (, bytes memory fromBalData) = token.call(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address))));\n uint256 fromPrevBal = abi.decode(fromBalData, (uint256));\n\n // get new user current balance\n (, bytes memory toBalData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 toPrevBal = abi.decode(toBalData, (uint256));\n\n // update balances\n stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal);\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal);\n\n // update owner\n stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to);\n }\n}\n" - }, - "node_modules/forge-std/src/StdError.sol": { - "content": "// SPDX-License-Identifier: MIT\n// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdError {\n bytes public constant assertionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x01);\n bytes public constant arithmeticError = abi.encodeWithSignature(\"Panic(uint256)\", 0x11);\n bytes public constant divisionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x12);\n bytes public constant enumConversionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x21);\n bytes public constant encodeStorageError = abi.encodeWithSignature(\"Panic(uint256)\", 0x22);\n bytes public constant popError = abi.encodeWithSignature(\"Panic(uint256)\", 0x31);\n bytes public constant indexOOBError = abi.encodeWithSignature(\"Panic(uint256)\", 0x32);\n bytes public constant memOverflowError = abi.encodeWithSignature(\"Panic(uint256)\", 0x41);\n bytes public constant zeroVarError = abi.encodeWithSignature(\"Panic(uint256)\", 0x51);\n}\n" - }, - "node_modules/forge-std/src/StdInvariant.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ncontract StdInvariant {\n struct FuzzSelector {\n address addr;\n bytes4[] selectors;\n }\n\n address[] private _excludedContracts;\n address[] private _excludedSenders;\n address[] private _targetedContracts;\n address[] private _targetedSenders;\n\n string[] private _excludedArtifacts;\n string[] private _targetedArtifacts;\n\n FuzzSelector[] private _targetedArtifactSelectors;\n FuzzSelector[] private _targetedSelectors;\n\n // Functions for users:\n // These are intended to be called in tests.\n\n function excludeContract(address newExcludedContract_) internal {\n _excludedContracts.push(newExcludedContract_);\n }\n\n function excludeSender(address newExcludedSender_) internal {\n _excludedSenders.push(newExcludedSender_);\n }\n\n function excludeArtifact(string memory newExcludedArtifact_) internal {\n _excludedArtifacts.push(newExcludedArtifact_);\n }\n\n function targetArtifact(string memory newTargetedArtifact_) internal {\n _targetedArtifacts.push(newTargetedArtifact_);\n }\n\n function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal {\n _targetedArtifactSelectors.push(newTargetedArtifactSelector_);\n }\n\n function targetContract(address newTargetedContract_) internal {\n _targetedContracts.push(newTargetedContract_);\n }\n\n function targetSelector(FuzzSelector memory newTargetedSelector_) internal {\n _targetedSelectors.push(newTargetedSelector_);\n }\n\n function targetSender(address newTargetedSender_) internal {\n _targetedSenders.push(newTargetedSender_);\n }\n\n // Functions for forge:\n // These are called by forge to run invariant tests and don't need to be called in tests.\n\n function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) {\n excludedArtifacts_ = _excludedArtifacts;\n }\n\n function excludeContracts() public view returns (address[] memory excludedContracts_) {\n excludedContracts_ = _excludedContracts;\n }\n\n function excludeSenders() public view returns (address[] memory excludedSenders_) {\n excludedSenders_ = _excludedSenders;\n }\n\n function targetArtifacts() public view returns (string[] memory targetedArtifacts_) {\n targetedArtifacts_ = _targetedArtifacts;\n }\n\n function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) {\n targetedArtifactSelectors_ = _targetedArtifactSelectors;\n }\n\n function targetContracts() public view returns (address[] memory targetedContracts_) {\n targetedContracts_ = _targetedContracts;\n }\n\n function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) {\n targetedSelectors_ = _targetedSelectors;\n }\n\n function targetSenders() public view returns (address[] memory targetedSenders_) {\n targetedSenders_ = _targetedSenders;\n }\n}\n" - }, - "node_modules/forge-std/src/StdJson.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing JSON files\n// To parse:\n// ```\n// using stdJson for string;\n// string memory json = vm.readFile(\"some_peth\");\n// json.parseUint(\"\");\n// ```\n// To write:\n// ```\n// using stdJson for string;\n// string memory json = \"deploymentArtifact\";\n// Contract contract = new Contract();\n// json.serialize(\"contractAddress\", address(contract));\n// json = json.serialize(\"deploymentTimes\", uint(1));\n// // store the stringified JSON to the 'json' variable we have been using as a key\n// // as we won't need it any longer\n// string memory json2 = \"finalArtifact\";\n// string memory final = json2.serialize(\"depArtifact\", json);\n// final.write(\"\");\n// ```\n\nlibrary stdJson {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJson(json, key);\n }\n\n function readUint(string memory json, string memory key) internal returns (uint256) {\n return vm.parseJsonUint(json, key);\n }\n\n function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) {\n return vm.parseJsonUintArray(json, key);\n }\n\n function readInt(string memory json, string memory key) internal returns (int256) {\n return vm.parseJsonInt(json, key);\n }\n\n function readIntArray(string memory json, string memory key) internal returns (int256[] memory) {\n return vm.parseJsonIntArray(json, key);\n }\n\n function readBytes32(string memory json, string memory key) internal returns (bytes32) {\n return vm.parseJsonBytes32(json, key);\n }\n\n function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) {\n return vm.parseJsonBytes32Array(json, key);\n }\n\n function readString(string memory json, string memory key) internal returns (string memory) {\n return vm.parseJsonString(json, key);\n }\n\n function readStringArray(string memory json, string memory key) internal returns (string[] memory) {\n return vm.parseJsonStringArray(json, key);\n }\n\n function readAddress(string memory json, string memory key) internal returns (address) {\n return vm.parseJsonAddress(json, key);\n }\n\n function readAddressArray(string memory json, string memory key) internal returns (address[] memory) {\n return vm.parseJsonAddressArray(json, key);\n }\n\n function readBool(string memory json, string memory key) internal returns (bool) {\n return vm.parseJsonBool(json, key);\n }\n\n function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) {\n return vm.parseJsonBoolArray(json, key);\n }\n\n function readBytes(string memory json, string memory key) internal returns (bytes memory) {\n return vm.parseJsonBytes(json, key);\n }\n\n function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) {\n return vm.parseJsonBytesArray(json, key);\n }\n\n function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bool[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function write(string memory jsonKey, string memory path) internal {\n vm.writeJson(jsonKey, path);\n }\n\n function write(string memory jsonKey, string memory path, string memory valueKey) internal {\n vm.writeJson(jsonKey, path, valueKey);\n }\n}\n" - }, - "node_modules/forge-std/src/StdMath.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdMath {\n int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n function abs(int256 a) internal pure returns (uint256) {\n // Required or it will fail when `a = type(int256).min`\n if (a == INT256_MIN) {\n return 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n }\n\n return uint256(a > 0 ? a : -a);\n }\n\n function delta(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a - b : b - a;\n }\n\n function delta(int256 a, int256 b) internal pure returns (uint256) {\n // a and b are of the same sign\n // this works thanks to two's complement, the left-most bit is the sign bit\n if ((a ^ b) > -1) {\n return delta(abs(a), abs(b));\n }\n\n // a and b are of opposite signs\n return abs(a) + abs(b);\n }\n\n function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n\n return absDelta * 1e18 / b;\n }\n\n function percentDelta(int256 a, int256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n uint256 absB = abs(b);\n\n return absDelta * 1e18 / absB;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nstruct StdStorage {\n mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots;\n mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds;\n bytes32[] _keys;\n bytes4 _sig;\n uint256 _depth;\n address _target;\n bytes32 _set;\n}\n\nlibrary stdStorageSafe {\n event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot);\n event WARNING_UninitedSlot(address who, uint256 slot);\n\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return bytes4(keccak256(bytes(sigStr)));\n }\n\n /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against\n // slot complexity:\n // if flat, will be bytes32(uint256(uint));\n // if map, will be keccak256(abi.encode(key, uint(slot)));\n // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));\n // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);\n function find(StdStorage storage self) internal returns (uint256) {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n // calldata to test against\n if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n vm.record();\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n (bytes32[] memory reads,) = vm.accesses(address(who));\n if (reads.length == 1) {\n bytes32 curr = vm.load(who, reads[0]);\n if (curr == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[0]));\n }\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n } else if (reads.length > 1) {\n for (uint256 i = 0; i < reads.length; i++) {\n bytes32 prev = vm.load(who, reads[i]);\n if (prev == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[i]));\n }\n // store\n vm.store(who, reads[i], bytes32(hex\"1337\"));\n bool success;\n bytes memory rdat;\n {\n (success, rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n if (success && fdat == bytes32(hex\"1337\")) {\n // we found which of the slots is the actual one\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n vm.store(who, reads[i], prev);\n break;\n }\n vm.store(who, reads[i], prev);\n }\n } else {\n revert(\"stdStorage find(StdStorage): No storage use detected for target.\");\n }\n\n require(\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))],\n \"stdStorage find(StdStorage): Slot(s) not found.\"\n );\n\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n self._target = _target;\n return self;\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n self._sig = _sig;\n return self;\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n self._sig = sigs(_sig);\n return self;\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n self._keys.push(bytes32(uint256(uint160(who))));\n return self;\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n self._keys.push(bytes32(amt));\n return self;\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n self._keys.push(key);\n return self;\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n self._depth = _depth;\n return self;\n }\n\n function read(StdStorage storage self) private returns (bytes memory) {\n address t = self._target;\n uint256 s = find(self);\n return abi.encode(vm.load(t, bytes32(s)));\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return abi.decode(read(self), (bytes32));\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n int256 v = read_int(self);\n if (v == 0) return false;\n if (v == 1) return true;\n revert(\"stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool.\");\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return abi.decode(read(self), (address));\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return abi.decode(read(self), (uint256));\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return abi.decode(read(self), (int256));\n }\n\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n\nlibrary stdStorage {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return stdStorageSafe.sigs(sigStr);\n }\n\n function find(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.find(self);\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n return stdStorageSafe.target(self, _target);\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, who);\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, amt);\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, key);\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n return stdStorageSafe.depth(self, _depth);\n }\n\n function checked_write(StdStorage storage self, address who) internal {\n checked_write(self, bytes32(uint256(uint160(who))));\n }\n\n function checked_write(StdStorage storage self, uint256 amt) internal {\n checked_write(self, bytes32(amt));\n }\n\n function checked_write(StdStorage storage self, bool write) internal {\n bytes32 t;\n /// @solidity memory-safe-assembly\n assembly {\n t := write\n }\n checked_write(self, t);\n }\n\n function checked_write(StdStorage storage self, bytes32 set) internal {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n find(self);\n }\n bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]);\n\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n bytes32 curr = vm.load(who, slot);\n\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n vm.store(who, slot, set);\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return stdStorageSafe.read_bytes32(self);\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n return stdStorageSafe.read_bool(self);\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return stdStorageSafe.read_address(self);\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.read_uint(self);\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return stdStorageSafe.read_int(self);\n }\n\n // Private function so needs to be copied over\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n // Private function so needs to be copied over\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStyle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nlibrary StdStyle {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n string constant RED = \"\\u001b[91m\";\n string constant GREEN = \"\\u001b[92m\";\n string constant YELLOW = \"\\u001b[93m\";\n string constant BLUE = \"\\u001b[94m\";\n string constant MAGENTA = \"\\u001b[95m\";\n string constant CYAN = \"\\u001b[96m\";\n string constant BOLD = \"\\u001b[1m\";\n string constant DIM = \"\\u001b[2m\";\n string constant ITALIC = \"\\u001b[3m\";\n string constant UNDERLINE = \"\\u001b[4m\";\n string constant INVERSE = \"\\u001b[7m\";\n string constant RESET = \"\\u001b[0m\";\n\n function styleConcat(string memory style, string memory self) private pure returns (string memory) {\n return string(abi.encodePacked(style, self, RESET));\n }\n\n function red(string memory self) internal pure returns (string memory) {\n return styleConcat(RED, self);\n }\n\n function red(uint256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(int256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(address self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(bool self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes(bytes memory self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes32(bytes32 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function green(string memory self) internal pure returns (string memory) {\n return styleConcat(GREEN, self);\n }\n\n function green(uint256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(int256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(address self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(bool self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes(bytes memory self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes32(bytes32 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function yellow(string memory self) internal pure returns (string memory) {\n return styleConcat(YELLOW, self);\n }\n\n function yellow(uint256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(int256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(address self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(bool self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes(bytes memory self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes32(bytes32 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function blue(string memory self) internal pure returns (string memory) {\n return styleConcat(BLUE, self);\n }\n\n function blue(uint256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(int256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(address self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(bool self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes(bytes memory self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes32(bytes32 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function magenta(string memory self) internal pure returns (string memory) {\n return styleConcat(MAGENTA, self);\n }\n\n function magenta(uint256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(int256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(address self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(bool self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes(bytes memory self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes32(bytes32 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function cyan(string memory self) internal pure returns (string memory) {\n return styleConcat(CYAN, self);\n }\n\n function cyan(uint256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(int256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(address self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(bool self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes(bytes memory self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes32(bytes32 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function bold(string memory self) internal pure returns (string memory) {\n return styleConcat(BOLD, self);\n }\n\n function bold(uint256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(int256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(address self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(bool self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes(bytes memory self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes32(bytes32 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function dim(string memory self) internal pure returns (string memory) {\n return styleConcat(DIM, self);\n }\n\n function dim(uint256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(int256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(address self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(bool self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes(bytes memory self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes32(bytes32 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function italic(string memory self) internal pure returns (string memory) {\n return styleConcat(ITALIC, self);\n }\n\n function italic(uint256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(int256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(address self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(bool self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes(bytes memory self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes32(bytes32 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function underline(string memory self) internal pure returns (string memory) {\n return styleConcat(UNDERLINE, self);\n }\n\n function underline(uint256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(int256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(address self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(bool self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes(bytes memory self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes32(bytes32 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function inverse(string memory self) internal pure returns (string memory) {\n return styleConcat(INVERSE, self);\n }\n\n function inverse(uint256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(int256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(address self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(bool self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes(bytes memory self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes32(bytes32 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n}\n" - }, - "node_modules/forge-std/src/StdUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {IMulticall3} from \"./interfaces/IMulticall3.sol\";\n// TODO Remove import.\nimport {VmSafe} from \"./Vm.sol\";\n\nabstract contract StdUtils {\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n //////////////////////////////////////////////////////////////////////////*/\n\n IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;\n uint256 private constant INT256_MIN_ABS =\n 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n /*//////////////////////////////////////////////////////////////////////////\n INTERNAL FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n require(min <= max, \"StdUtils bound(uint256,uint256,uint256): Max is less than min.\");\n // If x is between min and max, return x directly. This is to ensure that dictionary values\n // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188\n if (x >= min && x <= max) return x;\n\n uint256 size = max - min + 1;\n\n // If the value is 0, 1, 2, 3, warp that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side.\n // This helps ensure coverage of the min/max values.\n if (x <= 3 && size > x) return min + x;\n if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x);\n\n // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.\n if (x > max) {\n uint256 diff = x - max;\n uint256 rem = diff % size;\n if (rem == 0) return max;\n result = min + rem - 1;\n } else if (x < min) {\n uint256 diff = min - x;\n uint256 rem = diff % size;\n if (rem == 0) return min;\n result = max - rem + 1;\n }\n }\n\n function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) {\n result = _bound(x, min, max);\n console2_log(\"Bound Result\", result);\n }\n\n function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) {\n require(min <= max, \"StdUtils bound(int256,int256,int256): Max is less than min.\");\n\n // Shifting all int256 values to uint256 to use _bound function. The range of two types are:\n // int256 : -(2**255) ~ (2**255 - 1)\n // uint256: 0 ~ (2**256 - 1)\n // So, add 2**255, INT256_MIN_ABS to the integer values.\n //\n // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow.\n // So, use `~uint256(x) + 1` instead.\n uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS);\n uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS);\n uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS);\n\n uint256 y = _bound(_x, _min, _max);\n\n // To move it back to int256 value, subtract INT256_MIN_ABS at here.\n result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS);\n console2_log(\"Bound result\", vm.toString(result));\n }\n\n function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {\n require(b.length <= 32, \"StdUtils bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce\n /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol)\n function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) {\n // forgefmt: disable-start\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))));\n if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))));\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce))));\n if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce))));\n if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce))));\n // forgefmt: disable-end\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return addressFromLast20Bytes(\n keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce)))\n );\n }\n\n function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer)\n internal\n pure\n virtual\n returns (address)\n {\n return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash)));\n }\n\n /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer\n function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) {\n return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY);\n }\n\n /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) {\n return hashInitCode(creationCode, \"\");\n }\n\n /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n /// @param args the ABI-encoded arguments to the constructor of C\n function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(creationCode, args));\n }\n\n // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses.\n function getTokenBalances(address token, address[] memory addresses)\n internal\n virtual\n returns (uint256[] memory balances)\n {\n uint256 tokenCodeSize;\n assembly {\n tokenCodeSize := extcodesize(token)\n }\n require(tokenCodeSize > 0, \"StdUtils getTokenBalances(address,address[]): Token address is not a contract.\");\n\n // ABI encode the aggregate call to Multicall3.\n uint256 length = addresses.length;\n IMulticall3.Call[] memory calls = new IMulticall3.Call[](length);\n for (uint256 i = 0; i < length; ++i) {\n // 0x70a08231 = bytes4(\"balanceOf(address)\"))\n calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))});\n }\n\n // Make the aggregate call.\n (, bytes[] memory returnData) = multicall.aggregate(calls);\n\n // ABI decode the return data and return the balances.\n balances = new uint256[](length);\n for (uint256 i = 0; i < length; ++i) {\n balances[i] = abi.decode(returnData[i], (uint256));\n }\n }\n\n /*//////////////////////////////////////////////////////////////////////////\n PRIVATE FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere.\n\n function console2_log(string memory p0, uint256 p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n status;\n }\n\n function console2_log(string memory p0, string memory p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n status;\n }\n}\n" - }, - "node_modules/forge-std/src/Test.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// 💬 ABOUT\n// Standard Library's default Test\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {StdAssertions} from \"./StdAssertions.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheats} from \"./StdCheats.sol\";\nimport {stdError} from \"./StdError.sol\";\nimport {StdInvariant} from \"./StdInvariant.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {Vm} from \"./Vm.sol\";\nimport {StdStyle} from \"./StdStyle.sol\";\n\n// 📦 BOILERPLATE\nimport {TestBase} from \"./Base.sol\";\nimport {DSTest} from \"ds-test/test.sol\";\n\n// ⭐️ TEST\nabstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase {\n// Note: IS_TEST() must return true.\n// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76.\n}\n" - }, - "node_modules/forge-std/src/Vm.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// Cheatcodes are marked as view/pure/none using the following rules:\n// 0. A call's observable behaviour includes its return value, logs, reverts and state writes,\n// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc),\n// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`,\n// 3. Otherwise you're `pure`.\n\ninterface VmSafe {\n struct Log {\n bytes32[] topics;\n bytes data;\n address emitter;\n }\n\n struct Rpc {\n string key;\n string url;\n }\n\n struct FsMetadata {\n bool isDir;\n bool isSymlink;\n uint256 length;\n bool readOnly;\n uint256 modified;\n uint256 accessed;\n uint256 created;\n }\n\n // Loads a storage slot from an address\n function load(address target, bytes32 slot) external view returns (bytes32 data);\n // Signs data\n function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);\n // Gets the address for a given private key\n function addr(uint256 privateKey) external pure returns (address keyAddr);\n // Gets the nonce of an account\n function getNonce(address account) external view returns (uint64 nonce);\n // Performs a foreign function call via the terminal\n function ffi(string[] calldata commandInput) external returns (bytes memory result);\n // Sets environment variables\n function setEnv(string calldata name, string calldata value) external;\n // Reads environment variables, (name) => (value)\n function envBool(string calldata name) external view returns (bool value);\n function envUint(string calldata name) external view returns (uint256 value);\n function envInt(string calldata name) external view returns (int256 value);\n function envAddress(string calldata name) external view returns (address value);\n function envBytes32(string calldata name) external view returns (bytes32 value);\n function envString(string calldata name) external view returns (string memory value);\n function envBytes(string calldata name) external view returns (bytes memory value);\n // Reads environment variables as arrays\n function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value);\n function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value);\n function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value);\n function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);\n function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value);\n function envString(string calldata name, string calldata delim) external view returns (string[] memory value);\n function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value);\n // Read environment variables with default value\n function envOr(string calldata name, bool defaultValue) external returns (bool value);\n function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value);\n function envOr(string calldata name, int256 defaultValue) external returns (int256 value);\n function envOr(string calldata name, address defaultValue) external returns (address value);\n function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value);\n function envOr(string calldata name, string calldata defaultValue) external returns (string memory value);\n function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value);\n // Read environment variables as arrays with default value\n function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue)\n external\n returns (bool[] memory value);\n function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue)\n external\n returns (uint256[] memory value);\n function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue)\n external\n returns (int256[] memory value);\n function envOr(string calldata name, string calldata delim, address[] calldata defaultValue)\n external\n returns (address[] memory value);\n function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue)\n external\n returns (bytes32[] memory value);\n function envOr(string calldata name, string calldata delim, string[] calldata defaultValue)\n external\n returns (string[] memory value);\n function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue)\n external\n returns (bytes[] memory value);\n // Records all storage reads and writes\n function record() external;\n // Gets all accessed reads and write slot from a recording session, for a given address\n function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots);\n // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file\n function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode);\n // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file\n function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode);\n // Labels an address in call traces\n function label(address account, string calldata newLabel) external;\n // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain\n function broadcast() external;\n // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain\n function broadcast(address signer) external;\n // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain\n function broadcast(uint256 privateKey) external;\n // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain\n function startBroadcast() external;\n // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain\n function startBroadcast(address signer) external;\n // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain\n function startBroadcast(uint256 privateKey) external;\n // Stops collecting onchain transactions\n function stopBroadcast() external;\n // Reads the entire content of file to string\n function readFile(string calldata path) external view returns (string memory data);\n // Reads the entire content of file as binary. Path is relative to the project root.\n function readFileBinary(string calldata path) external view returns (bytes memory data);\n // Get the path of the current project root\n function projectRoot() external view returns (string memory path);\n // Get the metadata for a file/directory\n function fsMetadata(string calldata fileOrDir) external returns (FsMetadata memory metadata);\n // Reads next line of file to string\n function readLine(string calldata path) external view returns (string memory line);\n // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does.\n function writeFile(string calldata path, string calldata data) external;\n // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does.\n // Path is relative to the project root.\n function writeFileBinary(string calldata path, bytes calldata data) external;\n // Writes line to file, creating a file if it does not exist.\n function writeLine(string calldata path, string calldata data) external;\n // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine.\n function closeFile(string calldata path) external;\n // Removes file. This cheatcode will revert in the following situations, but is not limited to just these cases:\n // - Path points to a directory.\n // - The file doesn't exist.\n // - The user lacks permissions to remove the file.\n function removeFile(string calldata path) external;\n // Convert values to a string\n function toString(address value) external pure returns (string memory stringifiedValue);\n function toString(bytes calldata value) external pure returns (string memory stringifiedValue);\n function toString(bytes32 value) external pure returns (string memory stringifiedValue);\n function toString(bool value) external pure returns (string memory stringifiedValue);\n function toString(uint256 value) external pure returns (string memory stringifiedValue);\n function toString(int256 value) external pure returns (string memory stringifiedValue);\n // Convert values from a string\n function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue);\n function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue);\n function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue);\n function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue);\n function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue);\n function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue);\n // Record all the transaction logs\n function recordLogs() external;\n // Gets all the recorded logs\n function getRecordedLogs() external returns (Log[] memory logs);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index}\n function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index}\n function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index)\n external\n pure\n returns (uint256 privateKey);\n // Adds a private key to the local forge wallet and returns the address\n function rememberKey(uint256 privateKey) external returns (address keyAddr);\n //\n // parseJson\n //\n // ----\n // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects\n // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in\n // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that\n // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded\n // as tuples, with the attributes in the order in which they are defined.\n // For example: json = { 'a': 1, 'b': 0xa4tb......3xs}\n // a: uint256\n // b: address\n // To decode that json, we need to define a struct or a tuple as follows:\n // struct json = { uint256 a; address b; }\n // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to\n // decode the tuple in that order, and thus fail.\n // ----\n // Given a string of JSON, return it as ABI-encoded\n function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData);\n function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData);\n\n // The following parseJson cheatcodes will do type coercion, for the type that they indicate.\n // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12'\n // and hex numbers '0xEF'.\n // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not\n // a JSON object.\n function parseJsonUint(string calldata, string calldata) external returns (uint256);\n function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory);\n function parseJsonInt(string calldata, string calldata) external returns (int256);\n function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory);\n function parseJsonBool(string calldata, string calldata) external returns (bool);\n function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory);\n function parseJsonAddress(string calldata, string calldata) external returns (address);\n function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory);\n function parseJsonString(string calldata, string calldata) external returns (string memory);\n function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory);\n function parseJsonBytes(string calldata, string calldata) external returns (bytes memory);\n function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory);\n function parseJsonBytes32(string calldata, string calldata) external returns (bytes32);\n function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory);\n\n // Serialize a key and value to a JSON object stored in-memory that can be later written to a file\n // It returns the stringified version of the specific JSON file up to that moment.\n function serializeBool(string calldata objectKey, string calldata valueKey, bool value)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256 value)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address value)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string calldata value)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value)\n external\n returns (string memory json);\n\n function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values)\n external\n returns (string memory json);\n\n //\n // writeJson\n //\n // ----\n // Write a serialized JSON object to a file. If the file exists, it will be overwritten.\n // Let's assume we want to write the following JSON to a file:\n //\n // { \"boolean\": true, \"number\": 342, \"object\": { \"title\": \"finally json serialization\" } }\n //\n // ```\n // string memory json1 = \"some key\";\n // vm.serializeBool(json1, \"boolean\", true);\n // vm.serializeBool(json1, \"number\", uint256(342));\n // json2 = \"some other key\";\n // string memory output = vm.serializeString(json2, \"title\", \"finally json serialization\");\n // string memory finalJson = vm.serialize(json1, \"object\", output);\n // vm.writeJson(finalJson, \"./output/example.json\");\n // ```\n // The critical insight is that every invocation of serialization will return the stringified version of the JSON\n // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version\n // to serialize them as values to another JSON object.\n //\n // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..)\n // will find the object in-memory that is keyed by \"some key\".\n function writeJson(string calldata json, string calldata path) external;\n // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = \n // This is useful to replace a specific value of a JSON file, without having to parse the entire thing\n function writeJson(string calldata json, string calldata path, string calldata valueKey) external;\n // Returns the RPC url for the given alias\n function rpcUrl(string calldata rpcAlias) external view returns (string memory json);\n // Returns all rpc urls and their aliases `[alias, url][]`\n function rpcUrls() external view returns (string[2][] memory urls);\n // Returns all rpc urls and their aliases as structs.\n function rpcUrlStructs() external view returns (Rpc[] memory urls);\n // If the condition is false, discard this run's fuzz inputs and generate new ones.\n function assume(bool condition) external pure;\n // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused.\n function pauseGasMetering() external;\n // Resumes gas metering (i.e. gas usage is counted again). Noop if already on.\n function resumeGasMetering() external;\n}\n\ninterface Vm is VmSafe {\n // Sets block.timestamp\n function warp(uint256 newTimestamp) external;\n // Sets block.height\n function roll(uint256 newHeight) external;\n // Sets block.basefee\n function fee(uint256 newBasefee) external;\n // Sets block.difficulty\n function difficulty(uint256 newDifficulty) external;\n // Sets block.chainid\n function chainId(uint256 newChainId) external;\n // Stores a value to an address' storage slot.\n function store(address target, bytes32 slot, bytes32 value) external;\n // Sets the nonce of an account; must be higher than the current nonce of the account\n function setNonce(address account, uint64 newNonce) external;\n // Sets the *next* call's msg.sender to be the input address\n function prank(address msgSender) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called\n function startPrank(address msgSender) external;\n // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input\n function prank(address msgSender, address txOrigin) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input\n function startPrank(address msgSender, address txOrigin) external;\n // Resets subsequent calls' msg.sender to be `address(this)`\n function stopPrank() external;\n // Sets an address' balance\n function deal(address account, uint256 newBalance) external;\n // Sets an address' code\n function etch(address target, bytes calldata newRuntimeBytecode) external;\n // Expects an error on next call\n function expectRevert(bytes calldata revertData) external;\n function expectRevert(bytes4 revertData) external;\n function expectRevert() external;\n\n // Prepare an expected log with all four checks enabled.\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data.\n // Second form also checks supplied address against emitting contract.\n function expectEmit() external;\n function expectEmit(address emitter) external;\n\n // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData).\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data (as specified by the booleans).\n // Second form also checks supplied address against emitting contract.\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external;\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter)\n external;\n\n // Mocks a call to an address, returning specified data.\n // Calldata can either be strict or a partial match, e.g. if you only\n // pass a Solidity selector to the expected calldata, then the entire Solidity\n // function will be mocked.\n function mockCall(address callee, bytes calldata data, bytes calldata returnData) external;\n // Mocks a call to an address with a specific msg.value, returning specified data.\n // Calldata match takes precedence over msg.value in case of ambiguity.\n function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external;\n // Clears all mocked calls\n function clearMockedCalls() external;\n // Expects a call to an address with the specified calldata.\n // Calldata can either be a strict or a partial match\n function expectCall(address callee, bytes calldata data) external;\n // Expects a call to an address with the specified msg.value and calldata\n function expectCall(address callee, uint256 msgValue, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value, gas, and calldata.\n function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas.\n function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other\n // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set.\n function expectSafeMemory(uint64 min, uint64 max) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext.\n // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges\n // to the set.\n function expectSafeMemoryCall(uint64 min, uint64 max) external;\n // Sets block.coinbase\n function coinbase(address newCoinbase) external;\n // Snapshot the current state of the evm.\n // Returns the id of the snapshot that was created.\n // To revert a snapshot use `revertTo`\n function snapshot() external returns (uint256 snapshotId);\n // Revert the state of the EVM to a previous snapshot\n // Takes the snapshot id to revert to.\n // This deletes the snapshot and all snapshots taken after the given snapshot id.\n function revertTo(uint256 snapshotId) external returns (bool success);\n // Creates a new fork with the given endpoint and block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction,\n // and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before\n // the transaction, returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active.\n function selectFork(uint256 forkId) external;\n /// Returns the identifier of the currently active fork. Reverts if no fork is currently active.\n function activeFork() external view returns (uint256 forkId);\n // Updates the currently active fork to given block number\n // This is similar to `roll` but for the currently active fork\n function rollFork(uint256 blockNumber) external;\n // Updates the currently active fork to given transaction\n // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block\n function rollFork(bytes32 txHash) external;\n // Updates the given fork to given block number\n function rollFork(uint256 forkId, uint256 blockNumber) external;\n // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block\n function rollFork(uint256 forkId, bytes32 txHash) external;\n // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup\n // Meaning, changes made to the state of this account will be kept when switching forks\n function makePersistent(address account) external;\n function makePersistent(address account0, address account1) external;\n function makePersistent(address account0, address account1, address account2) external;\n function makePersistent(address[] calldata accounts) external;\n // Revokes persistent status from the address, previously added via `makePersistent`\n function revokePersistent(address account) external;\n function revokePersistent(address[] calldata accounts) external;\n // Returns true if the account is marked as persistent\n function isPersistent(address account) external view returns (bool persistent);\n // In forking mode, explicitly grant the given address cheatcode access\n function allowCheatcodes(address account) external;\n // Fetches the given transaction from the active fork and executes it on the current state\n function transact(bytes32 txHash) external;\n // Fetches the given transaction from the given fork and executes it on the current state\n function transact(uint256 forkId, bytes32 txHash) external;\n}\n" - }, - "node_modules/forge-std/src/console.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n }\n\n function logUint(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n }\n\n function log(uint p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n }\n\n function log(uint p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n }\n\n function log(uint p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n }\n\n function log(string memory p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/console2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\n/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should\n/// use `int256` and `uint256`. This modified version fixes that. This version is recommended\n/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in\n/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`.\n/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178\nlibrary console2 {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function log(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint256 p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n }\n\n function log(uint256 p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n }\n\n function log(uint256 p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n }\n\n function log(uint256 p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n }\n\n function log(string memory p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n }\n\n function log(string memory p0, int256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,int256)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/interfaces/IMulticall3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ninterface IMulticall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint256 value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n function aggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes[] memory returnData);\n\n function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);\n\n function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData);\n\n function blockAndAggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n\n function getBasefee() external view returns (uint256 basefee);\n\n function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash);\n\n function getBlockNumber() external view returns (uint256 blockNumber);\n\n function getChainId() external view returns (uint256 chainid);\n\n function getCurrentBlockCoinbase() external view returns (address coinbase);\n\n function getCurrentBlockDifficulty() external view returns (uint256 difficulty);\n\n function getCurrentBlockGasLimit() external view returns (uint256 gaslimit);\n\n function getCurrentBlockTimestamp() external view returns (uint256 timestamp);\n\n function getEthBalance(address addr) external view returns (uint256 balance);\n\n function getLastBlockHash() external view returns (bytes32 blockHash);\n\n function tryAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (Result[] memory returnData);\n\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n}\n" - } - }, - "settings": { - "remappings": [ - "@openzeppelin/=node_modules/@openzeppelin/", - "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", - "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", - "@rari-capital/=node_modules/@rari-capital/", - "@rari-capital/solmate/=node_modules/@rari-capital/solmate/", - "ds-test/=node_modules/ds-test/src/", - "forge-std/=node_modules/forge-std/src/" - ], - "optimizer": { - "enabled": true, - "runs": 999999 - }, - "metadata": { - "bytecodeHash": "none" - }, - "outputSelection": { - "*": { - "": [ - "ast" - ], - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "storageLayout", - "devdoc", - "userdoc" - ] - } - }, - "evmVersion": "london", - "libraries": {} - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/.chainId b/packages/contracts-bedrock/deployments/mainnet/.chainId deleted file mode 100644 index 56a6051ca2b0..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/.chainId +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/AddressManager.json b/packages/contracts-bedrock/deployments/mainnet/AddressManager.json deleted file mode 100644 index 0bb340041f27..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/AddressManager.json +++ /dev/null @@ -1,236 +0,0 @@ -{ - "address": "0xdE1FCfB0851916CA5101820A69b13a4E276bd81F", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "indexed": false, - "internalType": "address", - "name": "_newAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "_oldAddress", - "type": "address" - } - ], - "name": "AddressSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "getAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "address", - "name": "_address", - "type": "address" - } - ], - "name": "setAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0x8803c67a0032b8dea6b0e3a9d2ff1708346a41a8d2945d4e84e5d81862f1cb54", - "receipt": { - "to": null, - "from": "0x9996571372066A1545D3435C6935e3F9593A7eF5", - "contractAddress": "0xdE1FCfB0851916CA5101820A69b13a4E276bd81F", - "transactionIndex": 43, - "gasUsed": "425357", - "logsBloom": "0x00800000002000000000000000000000000000000000000000800000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000001000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000040000000000000000000000000000000000000000000", - "blockHash": "0x6eeca8dcaa51370f0048dcc0569ebb0c62ba9841e5414b362aa15915c29428d1", - "transactionHash": "0x8803c67a0032b8dea6b0e3a9d2ff1708346a41a8d2945d4e84e5d81862f1cb54", - "logs": [ - { - "transactionIndex": 43, - "blockNumber": 12686687, - "transactionHash": "0x8803c67a0032b8dea6b0e3a9d2ff1708346a41a8d2945d4e84e5d81862f1cb54", - "address": "0xdE1FCfB0851916CA5101820A69b13a4E276bd81F", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000009996571372066a1545d3435c6935e3f9593a7ef5" - ], - "data": "0x", - "logIndex": 195, - "blockHash": "0x6eeca8dcaa51370f0048dcc0569ebb0c62ba9841e5414b362aa15915c29428d1" - } - ], - "blockNumber": 12686687, - "cumulativeGasUsed": "6131161", - "status": 1, - "byzantium": true - }, - "args": [], - "solcInputHash": "ef3f334bac4d7e77d91b457a0d89ab0a", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_oldAddress\",\"type\":\"address\"}],\"name\":\"AddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getAddress(string)\":{\"params\":{\"_name\":\"Name to retrieve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setAddress(string,address)\":{\"params\":{\"_address\":\"Address to associate with the name.\",\"_name\":\"String name to associate an address with.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"Lib_AddressManager\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getAddress(string)\":{\"notice\":\"Retrieves the address associated with a given name.\"},\"setAddress(string,address)\":{\"notice\":\"Changes the address associated with a particular name.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol\":\"Lib_AddressManager\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x15e2d5bd4c28a88548074c54d220e8086f638a71ed07e6b3ba5a70066fcf458d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(\\n string indexed _name,\\n address _newAddress,\\n address _oldAddress\\n );\\n\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping (bytes32 => address) private addresses;\\n\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(\\n string memory _name,\\n address _address\\n )\\n external\\n onlyOwner\\n {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(\\n _name,\\n _address,\\n oldAddress\\n );\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(\\n string memory _name\\n )\\n external\\n view\\n returns (\\n address\\n )\\n {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(\\n string memory _name\\n )\\n internal\\n pure\\n returns (\\n bytes32\\n )\\n {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0x636defb785a5c6650d101def6790d9104724cc7570e0d875138624d069eed257\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50600061001b61006a565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35061006e565b3390565b6106478061007d6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063715018a61461005c5780638da5cb5b146100665780639b2ea4bd1461008a578063bf40fac11461013b578063f2fde38b146101e1575b600080fd5b610064610207565b005b61006e6102c5565b604080516001600160a01b039092168252519081900360200190f35b610064600480360360408110156100a057600080fd5b8101906020810181356401000000008111156100bb57600080fd5b8201836020820111156100cd57600080fd5b803590602001918460018302840111640100000000831117156100ef57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b031691506102d49050565b61006e6004803603602081101561015157600080fd5b81019060208101813564010000000081111561016c57600080fd5b82018360208201111561017e57600080fd5b803590602001918460018302840111640100000000831117156101a057600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061042d945050505050565b610064600480360360208110156101f757600080fd5b50356001600160a01b031661045c565b61020f610570565b6001600160a01b03166102206102c5565b6001600160a01b03161461027b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6102dc610570565b6001600160a01b03166102ed6102c5565b6001600160a01b031614610348576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600061035383610574565b60008181526001602090815260409182902080546001600160a01b038781166001600160a01b0319831617909255925187519495509216928692918291908401908083835b602083106103b75780518252601f199092019160209182019101610398565b51815160001960209485036101000a01908116901991909116179052604080519490920184900384206001600160a01b03808b16865288169185019190915281519095507f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c94509283900301919050a250505050565b60006001600061043c84610574565b81526020810191909152604001600020546001600160a01b031692915050565b610464610570565b6001600160a01b03166104756102c5565b6001600160a01b0316146104d0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166105155760405162461bcd60e51b81526004018080602001828103825260268152602001806105ec6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6000816040516020018082805190602001908083835b602083106105a95780518252601f19909201916020918201910161058a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905091905056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a2646970667358221220b47b03a0c984a0faed73425d34ee172acb8f5010c64751f78c7f645cf8dc2aad64736f6c63430007060033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c8063715018a61461005c5780638da5cb5b146100665780639b2ea4bd1461008a578063bf40fac11461013b578063f2fde38b146101e1575b600080fd5b610064610207565b005b61006e6102c5565b604080516001600160a01b039092168252519081900360200190f35b610064600480360360408110156100a057600080fd5b8101906020810181356401000000008111156100bb57600080fd5b8201836020820111156100cd57600080fd5b803590602001918460018302840111640100000000831117156100ef57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b031691506102d49050565b61006e6004803603602081101561015157600080fd5b81019060208101813564010000000081111561016c57600080fd5b82018360208201111561017e57600080fd5b803590602001918460018302840111640100000000831117156101a057600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061042d945050505050565b610064600480360360208110156101f757600080fd5b50356001600160a01b031661045c565b61020f610570565b6001600160a01b03166102206102c5565b6001600160a01b03161461027b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6102dc610570565b6001600160a01b03166102ed6102c5565b6001600160a01b031614610348576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600061035383610574565b60008181526001602090815260409182902080546001600160a01b038781166001600160a01b0319831617909255925187519495509216928692918291908401908083835b602083106103b75780518252601f199092019160209182019101610398565b51815160001960209485036101000a01908116901991909116179052604080519490920184900384206001600160a01b03808b16865288169185019190915281519095507f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c94509283900301919050a250505050565b60006001600061043c84610574565b81526020810191909152604001600020546001600160a01b031692915050565b610464610570565b6001600160a01b03166104756102c5565b6001600160a01b0316146104d0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166105155760405162461bcd60e51b81526004018080602001828103825260268152602001806105ec6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6000816040516020018082805190602001908083835b602083106105a95780518252601f19909201916020918201910161058a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905091905056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a2646970667358221220b47b03a0c984a0faed73425d34ee172acb8f5010c64751f78c7f645cf8dc2aad64736f6c63430007060033", - "devdoc": { - "kind": "dev", - "methods": { - "getAddress(string)": { - "params": { - "_name": "Name to retrieve an address for." - }, - "returns": { - "_0": "Address associated with the given name." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "setAddress(string,address)": { - "params": { - "_address": "Address to associate with the name.", - "_name": "String name to associate an address with." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - } - }, - "title": "Lib_AddressManager", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "getAddress(string)": { - "notice": "Retrieves the address associated with a given name." - }, - "setAddress(string,address)": { - "notice": "Changes the address associated with a particular name." - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 664, - "contract": "contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol:Lib_AddressManager", - "label": "_owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 15229, - "contract": "contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol:Lib_AddressManager", - "label": "addresses", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_bytes32,t_address)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes32,t_address)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => address)", - "numberOfBytes": "32", - "value": "t_address" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/AssetReceiver.json b/packages/contracts-bedrock/deployments/mainnet/AssetReceiver.json deleted file mode 100644 index 352f7018e222..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/AssetReceiver.json +++ /dev/null @@ -1,505 +0,0 @@ -{ - "address": "0x15DdA60616Ffca20371ED1659dBB78E888f65556", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ReceivedETH", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewERC20", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "WithdrewERC721", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewETH", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_gas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "CALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_gas", - "type": "uint256" - } - ], - "name": "DELEGATECALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC721", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_id", - "type": "uint256" - } - ], - "name": "withdrawERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0xb71ff0a1159385a03ad097a57d1cb37b62c5d6bc82be2e642a8d25d4ff4e1814", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 31, - "gasUsed": "887432", - "logsBloom": "0x00100000000000000001000000000000000000000000000000000000000000000000100000000000000000100000080000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000020000000000000000000000000000000000000000000000", - "blockHash": "0x2b65d7c70a739ca85d8fd598096aa680cd2eb267e73036afd4cb974edebda524", - "transactionHash": "0xb71ff0a1159385a03ad097a57d1cb37b62c5d6bc82be2e642a8d25d4ff4e1814", - "logs": [ - { - "transactionIndex": 31, - "blockNumber": 14904330, - "transactionHash": "0xb71ff0a1159385a03ad097a57d1cb37b62c5d6bc82be2e642a8d25d4ff4e1814", - "address": "0x15DdA60616Ffca20371ED1659dBB78E888f65556", - "topics": [ - "0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58" - ], - "data": "0x", - "logIndex": 57, - "blockHash": "0x2b65d7c70a739ca85d8fd598096aa680cd2eb267e73036afd4cb974edebda524" - } - ], - "blockNumber": 14904330, - "cumulativeGasUsed": "3130678", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 2, - "solcInputHash": "66d28de48de020e62747d42ffe3118e7", - "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ReceivedETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewETH\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"CALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"}],\"name\":\"DELEGATECALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC721\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\",\"_value\":\"ETH value to send with the call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"DELEGATECALL(address,bytes,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"constructor\":{\"params\":{\"_owner\":\"Initial contract owner.\"}},\"withdrawERC20(address,address)\":{\"params\":{\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC20(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount of ERC20 to withdraw.\",\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC721(address,address,uint256)\":{\"params\":{\"_asset\":\"ERC721 token to withdraw.\",\"_id\":\"Token ID of the ERC721 token to withdraw.\",\"_to\":\"Address to receive the ERC721 token.\"}},\"withdrawETH(address)\":{\"params\":{\"_to\":\"Address to receive the ETH balance.\"}},\"withdrawETH(address,uint256)\":{\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_to\":\"Address to receive the ETH balance.\"}}},\"title\":\"AssetReceiver\",\"version\":1},\"userdoc\":{\"events\":{\"ReceivedETH(address,uint256)\":{\"notice\":\"Emitted when ETH is received by this address.\"},\"WithdrewERC20(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewERC721(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC721 tokens are withdrawn from this address.\"},\"WithdrewETH(address,address,uint256)\":{\"notice\":\"Emitted when ETH is withdrawn from this address.\"}},\"kind\":\"user\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"notice\":\"Sends a CALL to a target address.\"},\"DELEGATECALL(address,bytes,uint256)\":{\"notice\":\"Sends a DELEGATECALL to a target address.\"},\"withdrawERC20(address,address)\":{\"notice\":\"Withdraws full ERC20 balance to the recipient.\"},\"withdrawERC20(address,address,uint256)\":{\"notice\":\"Withdraws partial ERC20 balance to the recipient.\"},\"withdrawERC721(address,address,uint256)\":{\"notice\":\"Withdraws ERC721 token to the recipient.\"},\"withdrawETH(address)\":{\"notice\":\"Withdraws full ETH balance to the recipient.\"},\"withdrawETH(address,uint256)\":{\"notice\":\"Withdraws partial ETH balance to the recipient.\"}},\"notice\":\"AssetReceiver is a minimal contract for receiving funds assets in the form of either ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/AssetReceiver.sol\":\"AssetReceiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@rari-capital/solmate/src/auth/Owned.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Simple single owner authorization mixin.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\\nabstract contract Owned {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event OwnerUpdated(address indexed user, address indexed newOwner);\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n address public owner;\\n\\n modifier onlyOwner() virtual {\\n require(msg.sender == owner, \\\"UNAUTHORIZED\\\");\\n\\n _;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(address _owner) {\\n owner = _owner;\\n\\n emit OwnerUpdated(address(0), _owner);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function setOwner(address newOwner) public virtual onlyOwner {\\n owner = newOwner;\\n\\n emit OwnerUpdated(msg.sender, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7e91c80b0dd1a14a19cb9e661b99924043adab6d9d893bbfcf3a6a3dc23a6743\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\\nabstract contract ERC20 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n uint8 public immutable decimals;\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) public balanceOf;\\n\\n mapping(address => mapping(address => uint256)) public allowance;\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 internal immutable INITIAL_CHAIN_ID;\\n\\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\\n\\n mapping(address => uint256) public nonces;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n uint8 _decimals\\n ) {\\n name = _name;\\n symbol = _symbol;\\n decimals = _decimals;\\n\\n INITIAL_CHAIN_ID = block.chainid;\\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 amount) public virtual returns (bool) {\\n allowance[msg.sender][spender] = amount;\\n\\n emit Approval(msg.sender, spender, amount);\\n\\n return true;\\n }\\n\\n function transfer(address to, uint256 amount) public virtual returns (bool) {\\n balanceOf[msg.sender] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(msg.sender, to, amount);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual returns (bool) {\\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\\n\\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\\n\\n balanceOf[from] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n return true;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(deadline >= block.timestamp, \\\"PERMIT_DEADLINE_EXPIRED\\\");\\n\\n // Unchecked because the only math done is incrementing\\n // the owner's nonce which cannot realistically overflow.\\n unchecked {\\n address recoveredAddress = ecrecover(\\n keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\",\\n DOMAIN_SEPARATOR(),\\n keccak256(\\n abi.encode(\\n keccak256(\\n \\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\"\\n ),\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n )\\n ),\\n v,\\n r,\\n s\\n );\\n\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"INVALID_SIGNER\\\");\\n\\n allowance[recoveredAddress][spender] = value;\\n }\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\\n }\\n\\n function computeDomainSeparator() internal view virtual returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name)),\\n keccak256(\\\"1\\\"),\\n block.chainid,\\n address(this)\\n )\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 amount) internal virtual {\\n totalSupply += amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(address(0), to, amount);\\n }\\n\\n function _burn(address from, uint256 amount) internal virtual {\\n balanceOf[from] -= amount;\\n\\n // Cannot underflow because a user's balance\\n // will never be larger than the total supply.\\n unchecked {\\n totalSupply -= amount;\\n }\\n\\n emit Transfer(from, address(0), amount);\\n }\\n}\\n\",\"keccak256\":\"0x0240f7703cff32a61ee3e9fbb339e09a944260432a9ef37debf3692b1a6c8049\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\\n\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE/LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n function tokenURI(uint256 id) public view virtual returns (string memory);\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 BALANCE/OWNER STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) internal _ownerOf;\\n\\n mapping(address => uint256) internal _balanceOf;\\n\\n function ownerOf(uint256 id) public view virtual returns (address owner) {\\n require((owner = _ownerOf[id]) != address(0), \\\"NOT_MINTED\\\");\\n }\\n\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n require(owner != address(0), \\\"ZERO_ADDRESS\\\");\\n\\n return _balanceOf[owner];\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 APPROVAL STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) public getApproved;\\n\\n mapping(address => mapping(address => bool)) public isApprovedForAll;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(string memory _name, string memory _symbol) {\\n name = _name;\\n symbol = _symbol;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 id) public virtual {\\n address owner = _ownerOf[id];\\n\\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \\\"NOT_AUTHORIZED\\\");\\n\\n getApproved[id] = spender;\\n\\n emit Approval(owner, spender, id);\\n }\\n\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n isApprovedForAll[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(msg.sender, operator, approved);\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n require(from == _ownerOf[id], \\\"WRONG_FROM\\\");\\n\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(\\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\\n \\\"NOT_AUTHORIZED\\\"\\n );\\n\\n // Underflow of the sender's balance is impossible because we check for\\n // ownership above and the recipient's balance can't realistically overflow.\\n unchecked {\\n _balanceOf[from]--;\\n\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n delete getApproved[id];\\n\\n emit Transfer(from, to, id);\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n bytes calldata data\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC165 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return\\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 id) internal virtual {\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(_ownerOf[id] == address(0), \\\"ALREADY_MINTED\\\");\\n\\n // Counter overflow is incredibly unrealistic.\\n unchecked {\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n emit Transfer(address(0), to, id);\\n }\\n\\n function _burn(uint256 id) internal virtual {\\n address owner = _ownerOf[id];\\n\\n require(owner != address(0), \\\"NOT_MINTED\\\");\\n\\n // Ownership check above ensures no underflow.\\n unchecked {\\n _balanceOf[owner]--;\\n }\\n\\n delete _ownerOf[id];\\n\\n delete getApproved[id];\\n\\n emit Transfer(owner, address(0), id);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL SAFE MINT LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _safeMint(address to, uint256 id) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function _safeMint(\\n address to,\\n uint256 id,\\n bytes memory data\\n ) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n}\\n\\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721TokenReceiver {\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external virtual returns (bytes4) {\\n return ERC721TokenReceiver.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0xb59c7c25eca386f39da4819a9f70f89b73b7583d5f5127a83ffe5339800b1183\",\"license\":\"AGPL-3.0-only\"},\"contracts/universal/AssetReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { ERC20 } from \\\"@rari-capital/solmate/src/tokens/ERC20.sol\\\";\\nimport { ERC721 } from \\\"@rari-capital/solmate/src/tokens/ERC721.sol\\\";\\nimport { Transactor } from \\\"./Transactor.sol\\\";\\n\\n/**\\n * @title AssetReceiver\\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\\n */\\ncontract AssetReceiver is Transactor {\\n /**\\n * Emitted when ETH is received by this address.\\n */\\n event ReceivedETH(address indexed from, uint256 amount);\\n\\n /**\\n * Emitted when ETH is withdrawn from this address.\\n */\\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\\n\\n /**\\n * Emitted when ERC20 tokens are withdrawn from this address.\\n */\\n event WithdrewERC20(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 amount\\n );\\n\\n /**\\n * Emitted when ERC721 tokens are withdrawn from this address.\\n */\\n event WithdrewERC721(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 id\\n );\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Transactor(_owner) {}\\n\\n /**\\n * Make sure we can receive ETH.\\n */\\n receive() external payable {\\n emit ReceivedETH(msg.sender, msg.value);\\n }\\n\\n /**\\n * Withdraws full ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n */\\n function withdrawETH(address payable _to) external onlyOwner {\\n withdrawETH(_to, address(this).balance);\\n }\\n\\n /**\\n * Withdraws partial ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n * @param _amount Amount of ETH to withdraw.\\n */\\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\\n // slither-disable-next-line reentrancy-unlimited-gas\\n _to.transfer(_amount);\\n emit WithdrewETH(msg.sender, _to, _amount);\\n }\\n\\n /**\\n * Withdraws full ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n */\\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\\n }\\n\\n /**\\n * Withdraws partial ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n * @param _amount Amount of ERC20 to withdraw.\\n */\\n function withdrawERC20(\\n ERC20 _asset,\\n address _to,\\n uint256 _amount\\n ) public onlyOwner {\\n // slither-disable-next-line unchecked-transfer\\n _asset.transfer(_to, _amount);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\\n }\\n\\n /**\\n * Withdraws ERC721 token to the recipient.\\n *\\n * @param _asset ERC721 token to withdraw.\\n * @param _to Address to receive the ERC721 token.\\n * @param _id Token ID of the ERC721 token to withdraw.\\n */\\n function withdrawERC721(\\n ERC721 _asset,\\n address _to,\\n uint256 _id\\n ) external onlyOwner {\\n _asset.transferFrom(address(this), _to, _id);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\\n }\\n}\\n\",\"keccak256\":\"0x1f82aff6f4e5a4bebebbfb4a2e0e4378ef9bc5bee8b81f88b27fc0ce73546d5f\",\"license\":\"MIT\"},\"contracts/universal/Transactor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { Owned } from \\\"@rari-capital/solmate/src/auth/Owned.sol\\\";\\n\\n/**\\n * @title Transactor\\n * @notice Transactor is a minimal contract that can send transactions.\\n */\\ncontract Transactor is Owned {\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Owned(_owner) {}\\n\\n /**\\n * Sends a CALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @param _value ETH value to send with the call.\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function CALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas,\\n uint256 _value\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n return _target.call{ gas: _gas, value: _value }(_data);\\n }\\n\\n /**\\n * Sends a DELEGATECALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function DELEGATECALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n // slither-disable-next-line controlled-delegatecall\\n return _target.delegatecall{ gas: _gas }(_data);\\n }\\n}\\n\",\"keccak256\":\"0xfe0d9c05a423d36775047e3285f76b874f8b887444d412a0d680c302c3b06a50\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50604051610f6e380380610f6e83398101604081905261002f91610081565b600080546001600160a01b0319166001600160a01b038316908117825560405183928392917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908290a35050506100b1565b60006020828403121561009357600080fd5b81516001600160a01b03811681146100aa57600080fd5b9392505050565b610eae806100c06000396000f3fe60806040526004361061009a5760003560e01c80635cef8b4a116100695780638da5cb5b1161004e5780638da5cb5b146101a75780639456fbcc146101f95780639e73dbea1461021957600080fd5b80635cef8b4a1461015d578063690d83201461018757600080fd5b806313af4035146100db5780634025feb2146100fd57806344004cc11461011d5780634782f7791461013d57600080fd5b366100d65760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b3480156100e757600080fd5b506100fb6100f6366004610b3a565b61022c565b005b34801561010957600080fd5b506100fb610118366004610b5e565b610322565b34801561012957600080fd5b506100fb610138366004610b5e565b6104b4565b34801561014957600080fd5b506100fb610158366004610b9f565b610654565b61017061016b366004610ca5565b61076a565b60405161017e929190610d2e565b60405180910390f35b34801561019357600080fd5b506100fb6101a2366004610b3a565b610863565b3480156101b357600080fd5b506000546101d49073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161017e565b34801561020557600080fd5b506100fb610214366004610d88565b6108f1565b610170610227366004610dc1565b610a1b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561041957600080fd5b505af115801561042d573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8846040516104a791815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b1580156105a557600080fd5b505af11580156105b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105dd9190610e21565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa846040516104a791815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610718573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8473ffffffffffffffffffffffffffffffffffffffff1683856040516108159190610e43565b6000604051808303818686f4925050503d8060008114610851576040519150601f19603f3d011682016040523d82523d6000602084013e610856565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6108ee8147610654565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610a17908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101389190610e5f565b5050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610aa0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8573ffffffffffffffffffffffffffffffffffffffff16848487604051610ac79190610e43565b600060405180830381858888f193505050503d8060008114610b05576040519150601f19603f3d011682016040523d82523d6000602084013e610b0a565b606091505b509150915094509492505050565b73ffffffffffffffffffffffffffffffffffffffff811681146108ee57600080fd5b600060208284031215610b4c57600080fd5b8135610b5781610b18565b9392505050565b600080600060608486031215610b7357600080fd5b8335610b7e81610b18565b92506020840135610b8e81610b18565b929592945050506040919091013590565b60008060408385031215610bb257600080fd5b8235610bbd81610b18565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610c0b57600080fd5b813567ffffffffffffffff80821115610c2657610c26610bcb565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610c6c57610c6c610bcb565b81604052838152866020858801011115610c8557600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215610cba57600080fd5b8335610cc581610b18565b9250602084013567ffffffffffffffff811115610ce157600080fd5b610ced86828701610bfa565b925050604084013590509250925092565b60005b83811015610d19578181015183820152602001610d01565b83811115610d28576000848401525b50505050565b82151581526040602082015260008251806040840152610d55816060850160208701610cfe565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b60008060408385031215610d9b57600080fd5b8235610da681610b18565b91506020830135610db681610b18565b809150509250929050565b60008060008060808587031215610dd757600080fd5b8435610de281610b18565b9350602085013567ffffffffffffffff811115610dfe57600080fd5b610e0a87828801610bfa565b949794965050505060408301359260600135919050565b600060208284031215610e3357600080fd5b81518015158114610b5757600080fd5b60008251610e55818460208701610cfe565b9190910192915050565b600060208284031215610e7157600080fd5b505191905056fea2646970667358221220a79fda18860baa011a378f2e4963a1c9eb8fa5184c5fd3130308ce3c35ba96da64736f6c63430008090033", - "deployedBytecode": "0x60806040526004361061009a5760003560e01c80635cef8b4a116100695780638da5cb5b1161004e5780638da5cb5b146101a75780639456fbcc146101f95780639e73dbea1461021957600080fd5b80635cef8b4a1461015d578063690d83201461018757600080fd5b806313af4035146100db5780634025feb2146100fd57806344004cc11461011d5780634782f7791461013d57600080fd5b366100d65760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b3480156100e757600080fd5b506100fb6100f6366004610b3a565b61022c565b005b34801561010957600080fd5b506100fb610118366004610b5e565b610322565b34801561012957600080fd5b506100fb610138366004610b5e565b6104b4565b34801561014957600080fd5b506100fb610158366004610b9f565b610654565b61017061016b366004610ca5565b61076a565b60405161017e929190610d2e565b60405180910390f35b34801561019357600080fd5b506100fb6101a2366004610b3a565b610863565b3480156101b357600080fd5b506000546101d49073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161017e565b34801561020557600080fd5b506100fb610214366004610d88565b6108f1565b610170610227366004610dc1565b610a1b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561041957600080fd5b505af115801561042d573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8846040516104a791815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b1580156105a557600080fd5b505af11580156105b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105dd9190610e21565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa846040516104a791815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610718573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8473ffffffffffffffffffffffffffffffffffffffff1683856040516108159190610e43565b6000604051808303818686f4925050503d8060008114610851576040519150601f19603f3d011682016040523d82523d6000602084013e610856565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6108ee8147610654565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610a17908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101389190610e5f565b5050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610aa0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8573ffffffffffffffffffffffffffffffffffffffff16848487604051610ac79190610e43565b600060405180830381858888f193505050503d8060008114610b05576040519150601f19603f3d011682016040523d82523d6000602084013e610b0a565b606091505b509150915094509492505050565b73ffffffffffffffffffffffffffffffffffffffff811681146108ee57600080fd5b600060208284031215610b4c57600080fd5b8135610b5781610b18565b9392505050565b600080600060608486031215610b7357600080fd5b8335610b7e81610b18565b92506020840135610b8e81610b18565b929592945050506040919091013590565b60008060408385031215610bb257600080fd5b8235610bbd81610b18565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610c0b57600080fd5b813567ffffffffffffffff80821115610c2657610c26610bcb565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610c6c57610c6c610bcb565b81604052838152866020858801011115610c8557600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215610cba57600080fd5b8335610cc581610b18565b9250602084013567ffffffffffffffff811115610ce157600080fd5b610ced86828701610bfa565b925050604084013590509250925092565b60005b83811015610d19578181015183820152602001610d01565b83811115610d28576000848401525b50505050565b82151581526040602082015260008251806040840152610d55816060850160208701610cfe565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b60008060408385031215610d9b57600080fd5b8235610da681610b18565b91506020830135610db681610b18565b809150509250929050565b60008060008060808587031215610dd757600080fd5b8435610de281610b18565b9350602085013567ffffffffffffffff811115610dfe57600080fd5b610e0a87828801610bfa565b949794965050505060408301359260600135919050565b600060208284031215610e3357600080fd5b81518015158114610b5757600080fd5b60008251610e55818460208701610cfe565b9190910192915050565b600060208284031215610e7157600080fd5b505191905056fea2646970667358221220a79fda18860baa011a378f2e4963a1c9eb8fa5184c5fd3130308ce3c35ba96da64736f6c63430008090033", - "devdoc": { - "kind": "dev", - "methods": { - "CALL(address,bytes,uint256,uint256)": { - "params": { - "_data": "Data to send with the call.", - "_gas": "Amount of gas to send with the call.", - "_target": "Address to call.", - "_value": "ETH value to send with the call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "DELEGATECALL(address,bytes,uint256)": { - "params": { - "_data": "Data to send with the call.", - "_gas": "Amount of gas to send with the call.", - "_target": "Address to call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "constructor": { - "params": { - "_owner": "Initial contract owner." - } - }, - "withdrawERC20(address,address)": { - "params": { - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC20(address,address,uint256)": { - "params": { - "_amount": "Amount of ERC20 to withdraw.", - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC721(address,address,uint256)": { - "params": { - "_asset": "ERC721 token to withdraw.", - "_id": "Token ID of the ERC721 token to withdraw.", - "_to": "Address to receive the ERC721 token." - } - }, - "withdrawETH(address)": { - "params": { - "_to": "Address to receive the ETH balance." - } - }, - "withdrawETH(address,uint256)": { - "params": { - "_amount": "Amount of ETH to withdraw.", - "_to": "Address to receive the ETH balance." - } - } - }, - "title": "AssetReceiver", - "version": 1 - }, - "userdoc": { - "events": { - "ReceivedETH(address,uint256)": { - "notice": "Emitted when ETH is received by this address." - }, - "WithdrewERC20(address,address,address,uint256)": { - "notice": "Emitted when ERC20 tokens are withdrawn from this address." - }, - "WithdrewERC721(address,address,address,uint256)": { - "notice": "Emitted when ERC721 tokens are withdrawn from this address." - }, - "WithdrewETH(address,address,uint256)": { - "notice": "Emitted when ETH is withdrawn from this address." - } - }, - "kind": "user", - "methods": { - "CALL(address,bytes,uint256,uint256)": { - "notice": "Sends a CALL to a target address." - }, - "DELEGATECALL(address,bytes,uint256)": { - "notice": "Sends a DELEGATECALL to a target address." - }, - "withdrawERC20(address,address)": { - "notice": "Withdraws full ERC20 balance to the recipient." - }, - "withdrawERC20(address,address,uint256)": { - "notice": "Withdraws partial ERC20 balance to the recipient." - }, - "withdrawERC721(address,address,uint256)": { - "notice": "Withdraws ERC721 token to the recipient." - }, - "withdrawETH(address)": { - "notice": "Withdraws full ETH balance to the recipient." - }, - "withdrawETH(address,uint256)": { - "notice": "Withdraws partial ETH balance to the recipient." - } - }, - "notice": "AssetReceiver is a minimal contract for receiving funds assets in the form of either ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 10, - "contract": "contracts/universal/AssetReceiver.sol:AssetReceiver", - "label": "owner", - "offset": 0, - "slot": "0", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/CheckBalanceHigh.json b/packages/contracts-bedrock/deployments/mainnet/CheckBalanceHigh.json deleted file mode 100644 index a38a2f0a8748..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/CheckBalanceHigh.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "address": "0x7eC64a8a591bFf829ff6C8be76074D540ACb813F", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct CheckBalanceHigh.Params", - "name": "params", - "type": "tuple" - } - ], - "name": "_EventToExposeStructInABI__Params", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x29af2bb56b520b9f7115dd3f4deda3dec0d6db0dfe45ef6a440a1f1b678242be", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 158, - "gasUsed": "176628", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x64d24a3fac9011c7cb71b7811a78d0220251808bd5b4c5c71ac234ca77e1f792", - "transactionHash": "0x29af2bb56b520b9f7115dd3f4deda3dec0d6db0dfe45ef6a440a1f1b678242be", - "logs": [], - "blockNumber": 16485623, - "cumulativeGasUsed": "13944967", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 2, - "solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988", - "metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct CheckBalanceHigh.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"params\":{\"params\":\"Parameters to encode.\"}}},\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckBalanceHigh\",\"version\":1},\"userdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"notice\":\"External event used to help client-side tooling encode parameters.\"}},\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck for checking if an account's balance is above a given threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol\":\"CheckBalanceHigh\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckBalanceHigh\\n * @notice DripCheck for checking if an account's balance is above a given threshold.\\n */\\ncontract CheckBalanceHigh is IDripCheck {\\n struct Params {\\n address target;\\n uint256 threshold;\\n }\\n\\n /**\\n * @notice External event used to help client-side tooling encode parameters.\\n *\\n * @param params Parameters to encode.\\n */\\n event _EventToExposeStructInABI__Params(Params params);\\n\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check target balance is above threshold.\\n return params.target.balance > params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0xcb27d9e50a7c32406872b8fdc4ca62ee0d27372eb9077657f6d16f3cd3b58c85\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610239806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631119392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea26469706673582212203818d112b628fa60d8cffe88e7198c860e268b9375b8b118dacdbf531c397ef864736f6c63430008100033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631119392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea26469706673582212203818d112b628fa60d8cffe88e7198c860e268b9375b8b118dacdbf531c397ef864736f6c63430008100033", - "devdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256))": { - "params": { - "params": "Parameters to encode." - } - } - }, - "kind": "dev", - "methods": { - "check(bytes)": { - "params": { - "_params": "Encoded parameters for the drip check." - }, - "returns": { - "_0": "Whether the drip should be executed." - } - } - }, - "title": "CheckBalanceHigh", - "version": 1 - }, - "userdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256))": { - "notice": "External event used to help client-side tooling encode parameters." - } - }, - "kind": "user", - "methods": { - "check(bytes)": { - "notice": "Checks whether a drip should be executable." - } - }, - "notice": "DripCheck for checking if an account's balance is above a given threshold.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/CheckBalanceLow.json b/packages/contracts-bedrock/deployments/mainnet/CheckBalanceLow.json deleted file mode 100644 index 7080cf7b3fb7..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/CheckBalanceLow.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "address": "0x381a4eFC2A2C914eA1889722bB4B44Fa6BD5b640", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct CheckBalanceLow.Params", - "name": "params", - "type": "tuple" - } - ], - "name": "_EventToExposeStructInABI__Params", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x914ed8cd67ba7ae6117f48f54d28a8bc95c024bcf81892fb5e3ef7cc3e6816bf", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 142, - "gasUsed": "176640", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1146150967938fa2bc31b565eec819de4993de51c9f26921139c6c5251316d68", - "transactionHash": "0x914ed8cd67ba7ae6117f48f54d28a8bc95c024bcf81892fb5e3ef7cc3e6816bf", - "logs": [], - "blockNumber": 16485625, - "cumulativeGasUsed": "11747659", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 2, - "solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988", - "metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct CheckBalanceLow.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"params\":{\"params\":\"Parameters to encode.\"}}},\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckBalanceLow\",\"version\":1},\"userdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"notice\":\"External event used to help client-side tooling encode parameters.\"}},\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck for checking if an account's balance is below a given threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol\":\"CheckBalanceLow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckBalanceLow\\n * @notice DripCheck for checking if an account's balance is below a given threshold.\\n */\\ncontract CheckBalanceLow is IDripCheck {\\n struct Params {\\n address target;\\n uint256 threshold;\\n }\\n\\n /**\\n * @notice External event used to help client-side tooling encode parameters.\\n *\\n * @param params Parameters to encode.\\n */\\n event _EventToExposeStructInABI__Params(Params params);\\n\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check target ETH balance is below threshold.\\n return params.target.balance < params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0x6a1187a80093770931296d3360b1ecc7d17f69157fe88f628989b257548b564b\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610239806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea2646970667358221220cc86d01120737597addcccffd841244801dcb64ce402d73b8d8569a52348996464736f6c63430008100033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea2646970667358221220cc86d01120737597addcccffd841244801dcb64ce402d73b8d8569a52348996464736f6c63430008100033", - "devdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256))": { - "params": { - "params": "Parameters to encode." - } - } - }, - "kind": "dev", - "methods": { - "check(bytes)": { - "params": { - "_params": "Encoded parameters for the drip check." - }, - "returns": { - "_0": "Whether the drip should be executed." - } - } - }, - "title": "CheckBalanceLow", - "version": 1 - }, - "userdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256))": { - "notice": "External event used to help client-side tooling encode parameters." - } - }, - "kind": "user", - "methods": { - "check(bytes)": { - "notice": "Checks whether a drip should be executable." - } - }, - "notice": "DripCheck for checking if an account's balance is below a given threshold.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/CheckGelatoLow.json b/packages/contracts-bedrock/deployments/mainnet/CheckGelatoLow.json deleted file mode 100644 index c030a4477879..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/CheckGelatoLow.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "address": "0x4f7CFc43f6D262a085F3b946cAC69E7a8E39BBAa", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "treasury", - "type": "address" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - } - ], - "indexed": false, - "internalType": "struct CheckGelatoLow.Params", - "name": "params", - "type": "tuple" - } - ], - "name": "_EventToExposeStructInABI__Params", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x18d80365aa0edda05af40c91fa32c610df2101f8c388d274cb50b882f5147167", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 47, - "gasUsed": "222032", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe3b313c0071bf10c41546a0f95ad53cda542f1b487fe1452e137ef652a0089a1", - "transactionHash": "0x18d80365aa0edda05af40c91fa32c610df2101f8c388d274cb50b882f5147167", - "logs": [], - "blockNumber": 16485627, - "cumulativeGasUsed": "5224175", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 2, - "solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988", - "metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"treasury\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct CheckGelatoLow.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256,address))\":{\"params\":{\"params\":\"Parameters to encode.\"}}},\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckGelatoLow\",\"version\":1},\"userdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256,address))\":{\"notice\":\"External event used to help client-side tooling encode parameters.\"}},\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck for checking if an account's Gelato ETH balance is below some threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol\":\"CheckGelatoLow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\ninterface IGelatoTreasury {\\n function userTokenBalance(address _user, address _token) external view returns (uint256);\\n}\\n\\n/**\\n * @title CheckGelatoLow\\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\\n */\\ncontract CheckGelatoLow is IDripCheck {\\n struct Params {\\n address treasury;\\n uint256 threshold;\\n address recipient;\\n }\\n\\n /**\\n * @notice External event used to help client-side tooling encode parameters.\\n *\\n * @param params Parameters to encode.\\n */\\n event _EventToExposeStructInABI__Params(Params params);\\n\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check GelatoTreasury ETH balance is below threshold.\\n return\\n IGelatoTreasury(params.treasury).userTokenBalance(\\n params.recipient,\\n // Gelato represents ETH as 0xeeeee....eeeee\\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\\n ) < params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0x1a127a2c8955525cc2e5cd3c6703edc785c662a79222f524df4574cf47ddd864\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061030c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e366004610160565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610258565b6020810151815160408084015190517fb47064c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6024820152939450919291169063b47064c890604401602060405180830381865afa158015610105573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012991906102bd565b109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561017257600080fd5b813567ffffffffffffffff8082111561018a57600080fd5b818401915084601f83011261019e57600080fd5b8135818111156101b0576101b0610131565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f6576101f6610131565b8160405282815287602084870101111561020f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b805173ffffffffffffffffffffffffffffffffffffffff8116811461025357600080fd5b919050565b60006060828403121561026a57600080fd5b6040516060810181811067ffffffffffffffff8211171561028d5761028d610131565b6040526102998361022f565b8152602083015160208201526102b16040840161022f565b60408201529392505050565b6000602082840312156102cf57600080fd5b505191905056fea2646970667358221220d5d7b760af134f89109f20dbf88fd89e78bb4b81bed97f9aa45772b3775b388964736f6c63430008100033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e366004610160565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610258565b6020810151815160408084015190517fb47064c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6024820152939450919291169063b47064c890604401602060405180830381865afa158015610105573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012991906102bd565b109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561017257600080fd5b813567ffffffffffffffff8082111561018a57600080fd5b818401915084601f83011261019e57600080fd5b8135818111156101b0576101b0610131565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f6576101f6610131565b8160405282815287602084870101111561020f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b805173ffffffffffffffffffffffffffffffffffffffff8116811461025357600080fd5b919050565b60006060828403121561026a57600080fd5b6040516060810181811067ffffffffffffffff8211171561028d5761028d610131565b6040526102998361022f565b8152602083015160208201526102b16040840161022f565b60408201529392505050565b6000602082840312156102cf57600080fd5b505191905056fea2646970667358221220d5d7b760af134f89109f20dbf88fd89e78bb4b81bed97f9aa45772b3775b388964736f6c63430008100033", - "devdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256,address))": { - "params": { - "params": "Parameters to encode." - } - } - }, - "kind": "dev", - "methods": { - "check(bytes)": { - "params": { - "_params": "Encoded parameters for the drip check." - }, - "returns": { - "_0": "Whether the drip should be executed." - } - } - }, - "title": "CheckGelatoLow", - "version": 1 - }, - "userdoc": { - "events": { - "_EventToExposeStructInABI__Params((address,uint256,address))": { - "notice": "External event used to help client-side tooling encode parameters." - } - }, - "kind": "user", - "methods": { - "check(bytes)": { - "notice": "Checks whether a drip should be executable." - } - }, - "notice": "DripCheck for checking if an account's Gelato ETH balance is below some threshold.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/CheckTrue.json b/packages/contracts-bedrock/deployments/mainnet/CheckTrue.json deleted file mode 100644 index 54ec93a5ad54..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/CheckTrue.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "address": "0x5c741a38cb11424711231777D71689C458eE835D", - "abi": [ - { - "inputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "pure", - "type": "function" - } - ], - "transactionHash": "0xf9c55443c3afb82190503b06ac5914eb3ea85179ec1572a0f22d781452f624dd", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 129, - "gasUsed": "139230", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5a37331d49bcc789cd37c2dd45be47bb35724fd974aab0573e8b6eb58f1690e5", - "transactionHash": "0xf9c55443c3afb82190503b06ac5914eb3ea85179ec1572a0f22d781452f624dd", - "logs": [], - "blockNumber": 16485630, - "cumulativeGasUsed": "13196107", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 2, - "solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988", - "metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckTrue\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck that always returns true.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckTrue.sol\":\"CheckTrue\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckTrue.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckTrue\\n * @notice DripCheck that always returns true.\\n */\\ncontract CheckTrue is IDripCheck {\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory) external pure returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xf2f5474f12983c30ca4fe9d19e7f88e6d2262e4a6f779e86b4a2117498fdbea5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061018c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004461003e366004610087565b50600190565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561009957600080fd5b813567ffffffffffffffff808211156100b157600080fd5b818401915084601f8301126100c557600080fd5b8135818111156100d7576100d7610058565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561011d5761011d610058565b8160405282815287602084870101111561013657600080fd5b82602086016020830137600092810160200192909252509594505050505056fea26469706673582212200bb899cb0e5f9dce180ebe72a1dfade46ffc5ec3cab398d1f2af09e8b9ce76d164736f6c63430008100033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004461003e366004610087565b50600190565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561009957600080fd5b813567ffffffffffffffff808211156100b157600080fd5b818401915084601f8301126100c557600080fd5b8135818111156100d7576100d7610058565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561011d5761011d610058565b8160405282815287602084870101111561013657600080fd5b82602086016020830137600092810160200192909252509594505050505056fea26469706673582212200bb899cb0e5f9dce180ebe72a1dfade46ffc5ec3cab398d1f2af09e8b9ce76d164736f6c63430008100033", - "devdoc": { - "kind": "dev", - "methods": { - "check(bytes)": { - "params": { - "_params": "Encoded parameters for the drip check." - }, - "returns": { - "_0": "Whether the drip should be executed." - } - } - }, - "title": "CheckTrue", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "check(bytes)": { - "notice": "Checks whether a drip should be executable." - } - }, - "notice": "DripCheck that always returns true.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/Drippie.json b/packages/contracts-bedrock/deployments/mainnet/Drippie.json deleted file mode 100644 index 5a7c32a96996..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/Drippie.json +++ /dev/null @@ -1,1054 +0,0 @@ -{ - "address": "0x44b3A2a040057eBafC601A78647e805fd58B1f50", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "nameref", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "components": [ - { - "internalType": "bool", - "name": "reentrant", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "interval", - "type": "uint256" - }, - { - "internalType": "contract IDripCheck", - "name": "dripcheck", - "type": "address" - }, - { - "internalType": "bytes", - "name": "checkparams", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "address payable", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct Drippie.DripAction[]", - "name": "actions", - "type": "tuple[]" - } - ], - "indexed": false, - "internalType": "struct Drippie.DripConfig", - "name": "config", - "type": "tuple" - } - ], - "name": "DripCreated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "nameref", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "indexed": false, - "internalType": "address", - "name": "executor", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - } - ], - "name": "DripExecuted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "nameref", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "indexed": false, - "internalType": "enum Drippie.DripStatus", - "name": "status", - "type": "uint8" - } - ], - "name": "DripStatusUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ReceivedETH", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewERC20", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "WithdrewERC721", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewETH", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "CALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "DELEGATECALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "components": [ - { - "internalType": "bool", - "name": "reentrant", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "interval", - "type": "uint256" - }, - { - "internalType": "contract IDripCheck", - "name": "dripcheck", - "type": "address" - }, - { - "internalType": "bytes", - "name": "checkparams", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "address payable", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct Drippie.DripAction[]", - "name": "actions", - "type": "tuple[]" - } - ], - "internalType": "struct Drippie.DripConfig", - "name": "_config", - "type": "tuple" - } - ], - "name": "create", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "drip", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "name": "drips", - "outputs": [ - { - "internalType": "enum Drippie.DripStatus", - "name": "status", - "type": "uint8" - }, - { - "components": [ - { - "internalType": "bool", - "name": "reentrant", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "interval", - "type": "uint256" - }, - { - "internalType": "contract IDripCheck", - "name": "dripcheck", - "type": "address" - }, - { - "internalType": "bytes", - "name": "checkparams", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "address payable", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct Drippie.DripAction[]", - "name": "actions", - "type": "tuple[]" - } - ], - "internalType": "struct Drippie.DripConfig", - "name": "config", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "last", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "count", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "executable", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "enum Drippie.DripStatus", - "name": "_status", - "type": "uint8" - } - ], - "name": "status", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC721", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_id", - "type": "uint256" - } - ], - "name": "withdrawERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0xba5b80505317eddf6bacd476eb97124d4d9c85f7a91433f977bf171d5555d897", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 142, - "gasUsed": "2419585", - "logsBloom": "0x00000000000000000001000000000000000000000000000000000000000000000000100000000000000000000000080000000000000000000000000000000004000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000400000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000020000000000000000000000000000000000000000000000", - "blockHash": "0x99cd54a5b44c3158251a863f70ce60ffe923d5500e0f828b2188a2a64f44ff65", - "transactionHash": "0xba5b80505317eddf6bacd476eb97124d4d9c85f7a91433f977bf171d5555d897", - "logs": [ - { - "transactionIndex": 142, - "blockNumber": 16485618, - "transactionHash": "0xba5b80505317eddf6bacd476eb97124d4d9c85f7a91433f977bf171d5555d897", - "address": "0x44b3A2a040057eBafC601A78647e805fd58B1f50", - "topics": [ - "0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58" - ], - "data": "0x", - "logIndex": 312, - "blockHash": "0x99cd54a5b44c3158251a863f70ce60ffe923d5500e0f828b2188a2a64f44ff65" - } - ], - "blockNumber": 16485618, - "cumulativeGasUsed": "16386332", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 2, - "solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988", - "metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"nameref\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"reentrant\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"interval\",\"type\":\"uint256\"},{\"internalType\":\"contract IDripCheck\",\"name\":\"dripcheck\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkparams\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address payable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Drippie.DripAction[]\",\"name\":\"actions\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"struct Drippie.DripConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DripCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"nameref\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"DripExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"nameref\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"enum Drippie.DripStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"DripStatusUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ReceivedETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewETH\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"CALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"DELEGATECALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"reentrant\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"interval\",\"type\":\"uint256\"},{\"internalType\":\"contract IDripCheck\",\"name\":\"dripcheck\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkparams\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address payable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Drippie.DripAction[]\",\"name\":\"actions\",\"type\":\"tuple[]\"}],\"internalType\":\"struct Drippie.DripConfig\",\"name\":\"_config\",\"type\":\"tuple\"}],\"name\":\"create\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"drip\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"name\":\"drips\",\"outputs\":[{\"internalType\":\"enum Drippie.DripStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"reentrant\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"interval\",\"type\":\"uint256\"},{\"internalType\":\"contract IDripCheck\",\"name\":\"dripcheck\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkparams\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address payable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Drippie.DripAction[]\",\"name\":\"actions\",\"type\":\"tuple[]\"}],\"internalType\":\"struct Drippie.DripConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"last\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"executable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"enum Drippie.DripStatus\",\"name\":\"_status\",\"type\":\"uint8\"}],\"name\":\"status\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC721\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"DripCreated(string,string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))\":{\"params\":{\"config\":\"Config for the created drip.\",\"name\":\"Unindexed name parameter (unhashed).\",\"nameref\":\"Indexed name parameter (hashed).\"}},\"DripExecuted(string,string,address,uint256)\":{\"params\":{\"executor\":\"Address that executed the drip.\",\"name\":\"Unindexed name parameter (unhashed).\",\"nameref\":\"Indexed name parameter (hashed).\",\"timestamp\":\"Time when the drip was executed.\"}},\"DripStatusUpdated(string,string,uint8)\":{\"params\":{\"name\":\"Unindexed name parameter (unhashed).\",\"nameref\":\"Indexed name parameter (hashed).\",\"status\":\"New drip status.\"}}},\"kind\":\"dev\",\"methods\":{\"CALL(address,bytes,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_target\":\"Address to call.\",\"_value\":\"ETH value to send with the call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"DELEGATECALL(address,bytes)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_target\":\"Address to call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"constructor\":{\"params\":{\"_owner\":\"Initial contract owner.\"}},\"create(string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))\":{\"params\":{\"_config\":\"Configuration for the drip.\",\"_name\":\"Name of the drip.\"}},\"drip(string)\":{\"params\":{\"_name\":\"Name of the drip to trigger.\"}},\"executable(string)\":{\"params\":{\"_name\":\"Drip to check.\"},\"returns\":{\"_0\":\"True if the drip is executable, reverts otherwise.\"}},\"status(string,uint8)\":{\"params\":{\"_name\":\"Name of the drip to update.\",\"_status\":\"New drip status.\"}},\"withdrawERC20(address,address)\":{\"params\":{\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC20(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount of ERC20 to withdraw.\",\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC721(address,address,uint256)\":{\"params\":{\"_asset\":\"ERC721 token to withdraw.\",\"_id\":\"Token ID of the ERC721 token to withdraw.\",\"_to\":\"Address to receive the ERC721 token.\"}},\"withdrawETH(address)\":{\"params\":{\"_to\":\"Address to receive the ETH balance.\"}},\"withdrawETH(address,uint256)\":{\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_to\":\"Address to receive the ETH balance.\"}}},\"title\":\"Drippie\",\"version\":1},\"userdoc\":{\"events\":{\"DripCreated(string,string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))\":{\"notice\":\"Emitted when a new drip is created.\"},\"DripExecuted(string,string,address,uint256)\":{\"notice\":\"Emitted when a drip is executed.\"},\"DripStatusUpdated(string,string,uint8)\":{\"notice\":\"Emitted when a drip status is updated.\"},\"ReceivedETH(address,uint256)\":{\"notice\":\"Emitted when ETH is received by this address.\"},\"WithdrewERC20(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewERC721(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewETH(address,address,uint256)\":{\"notice\":\"Emitted when ETH is withdrawn from this address.\"}},\"kind\":\"user\",\"methods\":{\"CALL(address,bytes,uint256)\":{\"notice\":\"Sends a CALL to a target address.\"},\"DELEGATECALL(address,bytes)\":{\"notice\":\"Sends a DELEGATECALL to a target address.\"},\"create(string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))\":{\"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.\"},\"drip(string)\":{\"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. Note that the drip check is executed only **once** at the beginning of the call to the drip function and will not be executed again between the drip actions within this call.\"},\"drips(string)\":{\"notice\":\"Maps from drip names to drip states.\"},\"executable(string)\":{\"notice\":\"Checks if a given drip is executable.\"},\"status(string,uint8)\":{\"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.\"},\"withdrawERC20(address,address)\":{\"notice\":\"Withdraws full ERC20 balance to the recipient.\"},\"withdrawERC20(address,address,uint256)\":{\"notice\":\"Withdraws partial ERC20 balance to the recipient.\"},\"withdrawERC721(address,address,uint256)\":{\"notice\":\"Withdraws ERC721 token to the recipient.\"},\"withdrawETH(address)\":{\"notice\":\"Withdraws full ETH balance to the recipient.\"},\"withdrawETH(address,uint256)\":{\"notice\":\"Withdraws partial ETH balance to the recipient.\"}},\"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.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/Drippie.sol\":\"Drippie\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@rari-capital/solmate/src/auth/Owned.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Simple single owner authorization mixin.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\\nabstract contract Owned {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event OwnerUpdated(address indexed user, address indexed newOwner);\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n address public owner;\\n\\n modifier onlyOwner() virtual {\\n require(msg.sender == owner, \\\"UNAUTHORIZED\\\");\\n\\n _;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(address _owner) {\\n owner = _owner;\\n\\n emit OwnerUpdated(address(0), _owner);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function setOwner(address newOwner) public virtual onlyOwner {\\n owner = newOwner;\\n\\n emit OwnerUpdated(msg.sender, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7e91c80b0dd1a14a19cb9e661b99924043adab6d9d893bbfcf3a6a3dc23a6743\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\\nabstract contract ERC20 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n uint8 public immutable decimals;\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) public balanceOf;\\n\\n mapping(address => mapping(address => uint256)) public allowance;\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 internal immutable INITIAL_CHAIN_ID;\\n\\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\\n\\n mapping(address => uint256) public nonces;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n uint8 _decimals\\n ) {\\n name = _name;\\n symbol = _symbol;\\n decimals = _decimals;\\n\\n INITIAL_CHAIN_ID = block.chainid;\\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 amount) public virtual returns (bool) {\\n allowance[msg.sender][spender] = amount;\\n\\n emit Approval(msg.sender, spender, amount);\\n\\n return true;\\n }\\n\\n function transfer(address to, uint256 amount) public virtual returns (bool) {\\n balanceOf[msg.sender] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(msg.sender, to, amount);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual returns (bool) {\\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\\n\\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\\n\\n balanceOf[from] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n return true;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(deadline >= block.timestamp, \\\"PERMIT_DEADLINE_EXPIRED\\\");\\n\\n // Unchecked because the only math done is incrementing\\n // the owner's nonce which cannot realistically overflow.\\n unchecked {\\n address recoveredAddress = ecrecover(\\n keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\",\\n DOMAIN_SEPARATOR(),\\n keccak256(\\n abi.encode(\\n keccak256(\\n \\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\"\\n ),\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n )\\n ),\\n v,\\n r,\\n s\\n );\\n\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"INVALID_SIGNER\\\");\\n\\n allowance[recoveredAddress][spender] = value;\\n }\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\\n }\\n\\n function computeDomainSeparator() internal view virtual returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name)),\\n keccak256(\\\"1\\\"),\\n block.chainid,\\n address(this)\\n )\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 amount) internal virtual {\\n totalSupply += amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(address(0), to, amount);\\n }\\n\\n function _burn(address from, uint256 amount) internal virtual {\\n balanceOf[from] -= amount;\\n\\n // Cannot underflow because a user's balance\\n // will never be larger than the total supply.\\n unchecked {\\n totalSupply -= amount;\\n }\\n\\n emit Transfer(from, address(0), amount);\\n }\\n}\\n\",\"keccak256\":\"0x43aa1509bb753f053143530705d9c4eee415691d26a4779769bf028a74e6ac69\",\"license\":\"MIT\"},\"@rari-capital/solmate/src/tokens/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\\n\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE/LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n function tokenURI(uint256 id) public view virtual returns (string memory);\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 BALANCE/OWNER STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) internal _ownerOf;\\n\\n mapping(address => uint256) internal _balanceOf;\\n\\n function ownerOf(uint256 id) public view virtual returns (address owner) {\\n require((owner = _ownerOf[id]) != address(0), \\\"NOT_MINTED\\\");\\n }\\n\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n require(owner != address(0), \\\"ZERO_ADDRESS\\\");\\n\\n return _balanceOf[owner];\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 APPROVAL STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) public getApproved;\\n\\n mapping(address => mapping(address => bool)) public isApprovedForAll;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(string memory _name, string memory _symbol) {\\n name = _name;\\n symbol = _symbol;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 id) public virtual {\\n address owner = _ownerOf[id];\\n\\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \\\"NOT_AUTHORIZED\\\");\\n\\n getApproved[id] = spender;\\n\\n emit Approval(owner, spender, id);\\n }\\n\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n isApprovedForAll[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(msg.sender, operator, approved);\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n require(from == _ownerOf[id], \\\"WRONG_FROM\\\");\\n\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(\\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\\n \\\"NOT_AUTHORIZED\\\"\\n );\\n\\n // Underflow of the sender's balance is impossible because we check for\\n // ownership above and the recipient's balance can't realistically overflow.\\n unchecked {\\n _balanceOf[from]--;\\n\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n delete getApproved[id];\\n\\n emit Transfer(from, to, id);\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n if (to.code.length != 0)\\n require(\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n bytes calldata data\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n if (to.code.length != 0)\\n require(\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC165 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return\\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 id) internal virtual {\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(_ownerOf[id] == address(0), \\\"ALREADY_MINTED\\\");\\n\\n // Counter overflow is incredibly unrealistic.\\n unchecked {\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n emit Transfer(address(0), to, id);\\n }\\n\\n function _burn(uint256 id) internal virtual {\\n address owner = _ownerOf[id];\\n\\n require(owner != address(0), \\\"NOT_MINTED\\\");\\n\\n // Ownership check above ensures no underflow.\\n unchecked {\\n _balanceOf[owner]--;\\n }\\n\\n delete _ownerOf[id];\\n\\n delete getApproved[id];\\n\\n emit Transfer(owner, address(0), id);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL SAFE MINT LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _safeMint(address to, uint256 id) internal virtual {\\n _mint(to, id);\\n\\n if (to.code.length != 0)\\n require(\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function _safeMint(\\n address to,\\n uint256 id,\\n bytes memory data\\n ) internal virtual {\\n _mint(to, id);\\n\\n if (to.code.length != 0)\\n require(\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n}\\n\\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721TokenReceiver {\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external virtual returns (bytes4) {\\n return ERC721TokenReceiver.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0xdac91feb466e74905737338d80cac5303eb7aedcbe76eda11c45eaa728451075\",\"license\":\"MIT\"},\"contracts/universal/AssetReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { ERC20 } from \\\"@rari-capital/solmate/src/tokens/ERC20.sol\\\";\\nimport { ERC721 } from \\\"@rari-capital/solmate/src/tokens/ERC721.sol\\\";\\nimport { Transactor } from \\\"./Transactor.sol\\\";\\n\\n/**\\n * @title AssetReceiver\\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\\n */\\ncontract AssetReceiver is Transactor {\\n /**\\n * @notice Emitted when ETH is received by this address.\\n *\\n * @param from Address that sent ETH to this contract.\\n * @param amount Amount of ETH received.\\n */\\n event ReceivedETH(address indexed from, uint256 amount);\\n\\n /**\\n * @notice Emitted when ETH is withdrawn from this address.\\n *\\n * @param withdrawer Address that triggered the withdrawal.\\n * @param recipient Address that received the withdrawal.\\n * @param amount ETH amount withdrawn.\\n */\\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\\n\\n /**\\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\\n *\\n * @param withdrawer Address that triggered the withdrawal.\\n * @param recipient Address that received the withdrawal.\\n * @param asset Address of the token being withdrawn.\\n * @param amount ERC20 amount withdrawn.\\n */\\n event WithdrewERC20(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 amount\\n );\\n\\n /**\\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\\n *\\n * @param withdrawer Address that triggered the withdrawal.\\n * @param recipient Address that received the withdrawal.\\n * @param asset Address of the token being withdrawn.\\n * @param id Token ID being withdrawn.\\n */\\n event WithdrewERC721(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 id\\n );\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Transactor(_owner) {}\\n\\n /**\\n * @notice Make sure we can receive ETH.\\n */\\n receive() external payable {\\n emit ReceivedETH(msg.sender, msg.value);\\n }\\n\\n /**\\n * @notice Withdraws full ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n */\\n function withdrawETH(address payable _to) external onlyOwner {\\n withdrawETH(_to, address(this).balance);\\n }\\n\\n /**\\n * @notice Withdraws partial ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n * @param _amount Amount of ETH to withdraw.\\n */\\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\\n // slither-disable-next-line reentrancy-unlimited-gas\\n (bool success, ) = _to.call{ value: _amount }(\\\"\\\");\\n emit WithdrewETH(msg.sender, _to, _amount);\\n }\\n\\n /**\\n * @notice Withdraws full ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n */\\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\\n }\\n\\n /**\\n * @notice Withdraws partial ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n * @param _amount Amount of ERC20 to withdraw.\\n */\\n function withdrawERC20(\\n ERC20 _asset,\\n address _to,\\n uint256 _amount\\n ) public onlyOwner {\\n // slither-disable-next-line unchecked-transfer\\n _asset.transfer(_to, _amount);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\\n }\\n\\n /**\\n * @notice Withdraws ERC721 token to the recipient.\\n *\\n * @param _asset ERC721 token to withdraw.\\n * @param _to Address to receive the ERC721 token.\\n * @param _id Token ID of the ERC721 token to withdraw.\\n */\\n function withdrawERC721(\\n ERC721 _asset,\\n address _to,\\n uint256 _id\\n ) external onlyOwner {\\n _asset.transferFrom(address(this), _to, _id);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\\n }\\n}\\n\",\"keccak256\":\"0x7e9bcbf8e23cb5f48e4eca605da6b7d96f88b9499e91a92cbf74d82e9e91cdf1\",\"license\":\"MIT\"},\"contracts/universal/Transactor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Owned } from \\\"@rari-capital/solmate/src/auth/Owned.sol\\\";\\n\\n/**\\n * @title Transactor\\n * @notice Transactor is a minimal contract that can send transactions.\\n */\\ncontract Transactor is Owned {\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Owned(_owner) {}\\n\\n /**\\n * Sends a CALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _value ETH value to send with the call.\\n *\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function CALL(\\n address _target,\\n bytes memory _data,\\n uint256 _value\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n return _target.call{ value: _value }(_data);\\n }\\n\\n /**\\n * Sends a DELEGATECALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n *\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function DELEGATECALL(address _target, bytes memory _data)\\n external\\n payable\\n onlyOwner\\n returns (bool, bytes memory)\\n {\\n // slither-disable-next-line controlled-delegatecall\\n return _target.delegatecall(_data);\\n }\\n}\\n\",\"keccak256\":\"0x6a9e687b2f333bcc8ade530325005cb67ab7f78fd31407d4f2274324e71fc0fb\",\"license\":\"MIT\"},\"contracts/universal/drippie/Drippie.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { AssetReceiver } from \\\"../AssetReceiver.sol\\\";\\nimport { IDripCheck } from \\\"./IDripCheck.sol\\\";\\n\\n/**\\n * @title Drippie\\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\\n * is called a \\\"drip\\\" and can be executed according to some condition (called a dripcheck)\\n * and an execution interval. Drips cannot be executed faster than the execution interval.\\n * Drips can trigger arbitrary contract calls where the calling contract is this contract\\n * address. Drips can also send ETH value, which makes them ideal for keeping addresses\\n * sufficiently funded with ETH. Drippie is designed to be connected with smart contract\\n * automation services so that drips can be executed automatically. However, Drippie is\\n * specifically designed to be separated from these services so that trust assumptions are\\n * better compartmentalized.\\n */\\ncontract Drippie is AssetReceiver {\\n /**\\n * @notice Enum representing different status options for a given drip.\\n *\\n * @custom:value NONE Drip does not exist.\\n * @custom:value PAUSED Drip is paused and cannot be executed until reactivated.\\n * @custom:value ACTIVE Drip is active and can be executed.\\n * @custom:value ARCHIVED Drip is archived and can no longer be executed or reactivated.\\n */\\n enum DripStatus {\\n NONE,\\n PAUSED,\\n ACTIVE,\\n ARCHIVED\\n }\\n\\n /**\\n * @notice Represents a drip action.\\n */\\n struct DripAction {\\n address payable target;\\n bytes data;\\n uint256 value;\\n }\\n\\n /**\\n * @notice Represents the configuration for a given drip.\\n */\\n struct DripConfig {\\n bool reentrant;\\n uint256 interval;\\n IDripCheck dripcheck;\\n bytes checkparams;\\n DripAction[] actions;\\n }\\n\\n /**\\n * @notice Represents the state of an active drip.\\n */\\n struct DripState {\\n DripStatus status;\\n DripConfig config;\\n uint256 last;\\n uint256 count;\\n }\\n\\n /**\\n * @notice Emitted when a new drip is created.\\n *\\n * @param nameref Indexed name parameter (hashed).\\n * @param name Unindexed name parameter (unhashed).\\n * @param config Config for the created drip.\\n */\\n event DripCreated(\\n // Emit name twice because indexed version is hashed.\\n string indexed nameref,\\n string name,\\n DripConfig config\\n );\\n\\n /**\\n * @notice Emitted when a drip status is updated.\\n *\\n * @param nameref Indexed name parameter (hashed).\\n * @param name Unindexed name parameter (unhashed).\\n * @param status New drip status.\\n */\\n event DripStatusUpdated(\\n // Emit name twice because indexed version is hashed.\\n string indexed nameref,\\n string name,\\n DripStatus status\\n );\\n\\n /**\\n * @notice Emitted when a drip is executed.\\n *\\n * @param nameref Indexed name parameter (hashed).\\n * @param name Unindexed name parameter (unhashed).\\n * @param executor Address that executed the drip.\\n * @param timestamp Time when the drip was executed.\\n */\\n event DripExecuted(\\n // Emit name twice because indexed version is hashed.\\n string indexed nameref,\\n string name,\\n address executor,\\n uint256 timestamp\\n );\\n\\n /**\\n * @notice Maps from drip names to drip states.\\n */\\n mapping(string => DripState) public drips;\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) AssetReceiver(_owner) {}\\n\\n /**\\n * @notice Creates a new drip with the given name and configuration. Once created, drips cannot\\n * be modified in any way (this is a security measure). If you want to update a drip,\\n * simply pause (and potentially archive) the existing drip and create a new one.\\n *\\n * @param _name Name of the drip.\\n * @param _config Configuration for the drip.\\n */\\n function create(string calldata _name, DripConfig calldata _config) external onlyOwner {\\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\\n // will ever set the status of a drip back to NONE after it's been created. This is why\\n // archival is a separate status.\\n require(\\n drips[_name].status == DripStatus.NONE,\\n \\\"Drippie: drip with that name already exists\\\"\\n );\\n\\n // Validate the drip interval, only allowing an interval of zero if the drip has explicitly\\n // been marked as reentrant. Prevents client-side bugs making a drip infinitely executable\\n // within the same block (of course, restricted by gas limits).\\n if (_config.reentrant) {\\n require(\\n _config.interval == 0,\\n \\\"Drippie: if allowing reentrant drip, must set interval to zero\\\"\\n );\\n } else {\\n require(\\n _config.interval > 0,\\n \\\"Drippie: interval must be greater than zero if drip is not reentrant\\\"\\n );\\n }\\n\\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\\n DripState storage state = drips[_name];\\n state.status = DripStatus.PAUSED;\\n state.config.reentrant = _config.reentrant;\\n state.config.interval = _config.interval;\\n state.config.dripcheck = _config.dripcheck;\\n state.config.checkparams = _config.checkparams;\\n\\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\\n for (uint256 i = 0; i < _config.actions.length; i++) {\\n state.config.actions.push(_config.actions[i]);\\n }\\n\\n // Tell the world!\\n emit DripCreated(_name, _name, _config);\\n }\\n\\n /**\\n * @notice Sets the status for a given drip. The behavior of this function depends on the\\n * status that the user is trying to set. A drip can always move between ACTIVE and\\n * PAUSED, but it can never move back to NONE and once ARCHIVED, it can never move back\\n * to ACTIVE or PAUSED.\\n *\\n * @param _name Name of the drip to update.\\n * @param _status New drip status.\\n */\\n function status(string calldata _name, DripStatus _status) external onlyOwner {\\n // Make sure we can never set drip status back to NONE. A simple security measure to\\n // prevent accidental overwrites if this code is ever updated down the line.\\n require(\\n _status != DripStatus.NONE,\\n \\\"Drippie: drip status can never be set back to NONE after creation\\\"\\n );\\n\\n // Load the drip status once to avoid unnecessary SLOADs.\\n DripStatus curr = drips[_name].status;\\n\\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\\n // seem to be any clear reason why you would want to do this, and it may save some gas in\\n // the case of a front-end bug.\\n require(\\n curr != DripStatus.NONE,\\n \\\"Drippie: drip with that name does not exist and cannot be updated\\\"\\n );\\n\\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\\n // point of archiving a drip.\\n require(\\n curr != DripStatus.ARCHIVED,\\n \\\"Drippie: drip with that name has been archived and cannot be updated\\\"\\n );\\n\\n // Although not strictly necessary, we make sure that the status here is actually changing.\\n // This may save the client some gas if there's a front-end bug and the user accidentally\\n // tries to \\\"change\\\" the status to the same value as before.\\n require(\\n curr != _status,\\n \\\"Drippie: cannot set drip status to the same status as its current status\\\"\\n );\\n\\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\\n // not allow users to archive active drips so that the effects of this action are more\\n // abundantly clear.\\n if (_status == DripStatus.ARCHIVED) {\\n require(\\n curr == DripStatus.PAUSED,\\n \\\"Drippie: drip must first be paused before being archived\\\"\\n );\\n }\\n\\n // If we made it here then we can safely update the status.\\n drips[_name].status = _status;\\n emit DripStatusUpdated(_name, _name, _status);\\n }\\n\\n /**\\n * @notice Checks if a given drip is executable.\\n *\\n * @param _name Drip to check.\\n *\\n * @return True if the drip is executable, reverts otherwise.\\n */\\n function executable(string calldata _name) public view returns (bool) {\\n DripState storage state = drips[_name];\\n\\n // Only allow active drips to be executed, an obvious security measure.\\n require(\\n state.status == DripStatus.ACTIVE,\\n \\\"Drippie: selected drip does not exist or is not currently active\\\"\\n );\\n\\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\\n // compromised recipient to just a single drip interval, after which the drip can be paused\\n // by the owner address.\\n require(\\n state.last + state.config.interval <= block.timestamp,\\n \\\"Drippie: drip interval has not elapsed since last drip\\\"\\n );\\n\\n // Make sure we're allowed to execute this drip.\\n require(\\n state.config.dripcheck.check(state.config.checkparams),\\n \\\"Drippie: dripcheck failed so drip is not yet ready to be triggered\\\"\\n );\\n\\n // Alright, we're good to execute.\\n return true;\\n }\\n\\n /**\\n * @notice Triggers a drip. This function is deliberately left as a public function because the\\n * assumption being made here is that setting the drip to ACTIVE is an affirmative\\n * signal that the drip should be executable according to the drip parameters, drip\\n * check, and drip interval. Note that drip parameters are read entirely from the state\\n * and are not supplied as user input, so there should not be any way for a\\n * non-authorized user to influence the behavior of the drip. Note that the drip check\\n * is executed only **once** at the beginning of the call to the drip function and will\\n * not be executed again between the drip actions within this call.\\n *\\n * @param _name Name of the drip to trigger.\\n */\\n function drip(string calldata _name) external {\\n DripState storage state = drips[_name];\\n\\n // Make sure the drip can be executed. Since executable reverts if the drip is not ready to\\n // be executed, we don't need to do an assertion that the returned value is true.\\n executable(_name);\\n\\n // Update the last execution time for this drip before the call. Note that it's entirely\\n // possible for a drip to be executed multiple times per block or even multiple times\\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\\n // block (since this will then prevent re-entrancy).\\n state.last = block.timestamp;\\n\\n // Update the number of times this drip has been executed. Although this increases the cost\\n // of using Drippie, it slightly simplifies the client-side by not having to worry about\\n // counting drips via events. Useful for monitoring the rate of drip execution.\\n state.count++;\\n\\n // Execute each action in the drip. We allow drips to have multiple actions because there\\n // are scenarios in which a contract must do multiple things atomically. For example, the\\n // contract may need to withdraw ETH from one account and then deposit that ETH into\\n // another account within the same transaction.\\n uint256 len = state.config.actions.length;\\n for (uint256 i = 0; i < len; i++) {\\n // Must be marked as \\\"storage\\\" because copying structs into memory is not yet supported\\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\\n // read what the rest of this section is doing.\\n DripAction storage action = state.config.actions[i];\\n\\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\\n // returndata.\\n // slither-disable-next-line calls-loop\\n (bool success, ) = action.target.call{ value: action.value }(action.data);\\n\\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\\n // the wrong data to the target contract), the recipient is not payable, or\\n // insufficient gas was supplied to this transaction. We revert so the drip can be\\n // fixed and triggered again later. Means we cannot emit an event to alert of the\\n // failure, but can reasonably be detected by off-chain services even without an event.\\n // Note that this forces the drip executor to supply sufficient gas to the call\\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\\n // not execute).\\n require(\\n success,\\n \\\"Drippie: drip was unsuccessful, please check your configuration for mistakes\\\"\\n );\\n }\\n\\n emit DripExecuted(_name, _name, msg.sender, block.timestamp);\\n }\\n}\\n\",\"keccak256\":\"0x60aac1f170b36ddd9523a48eccae75ad408ecbad6b32bcf5567e7f680ab10c94\",\"license\":\"MIT\"},\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b5060405162002b3138038062002b3183398101604081905262000034916200008c565b600080546001600160a01b0319166001600160a01b03831690811782556040518392839283929091907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908290a350505050620000be565b6000602082840312156200009f57600080fd5b81516001600160a01b0381168114620000b757600080fd5b9392505050565b612a6380620000ce6000396000f3fe6080604052600436106100e15760003560e01c80636e2d44ae1161007f5780639bc94d01116100595780639bc94d01146102b0578063e551cdaa146102d0578063edee6239146102f0578063fc3e3eba1461030357600080fd5b80636e2d44ae1461021d5780638da5cb5b1461023e5780639456fbcc1461029057600080fd5b80634782f779116100bb5780634782f779146101845780634d7fba6e146101a457806367148cd2146101dd578063690d8320146101fd57600080fd5b806313af4035146101225780634025feb21461014457806344004cc11461016457600080fd5b3661011d5760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561012e57600080fd5b5061014261013d366004611af9565b610333565b005b34801561015057600080fd5b5061014261015f366004611b1d565b61040f565b34801561017057600080fd5b5061014261017f366004611b1d565b610587565b34801561019057600080fd5b5061014261019f366004611b5e565b6106fe565b3480156101b057600080fd5b506101c46101bf366004611c2f565b610834565b6040516101d49493929190611d3a565b60405180910390f35b3480156101e957600080fd5b506101426101f8366004611e94565b610a66565b34801561020957600080fd5b50610142610218366004611af9565b610c6f565b61023061022b366004611ef6565b610ce3565b6040516101d4929190611f4f565b34801561024a57600080fd5b5060005461026b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d4565b34801561029c57600080fd5b506101426102ab366004611f6a565b610dc3565b3480156102bc57600080fd5b506101426102cb366004611fa3565b610ec4565b3480156102dc57600080fd5b506101426102eb366004611ffe565b611363565b6102306102fe366004612063565b61177f565b34801561030f57600080fd5b5061032361031e366004611e94565b61185c565b60405190151581526020016101d4565b60005473ffffffffffffffffffffffffffffffffffffffff16331461039f5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104765760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b1580156104ec57600080fd5b505af1158015610500573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a88460405161057a91815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ee5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015610663573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068791906120c1565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa8460405161057a91815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107655760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146107bf576040519150601f19603f3d011682016040523d82523d6000602084013e6107c4565b606091505b505090508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc8460405161082791815260200190565b60405180910390a3505050565b805160208183018101805160018083529383019483019490942093905282546040805160a081018252938501805460ff90811615158652600287015494860194909452600386015473ffffffffffffffffffffffffffffffffffffffff169185019190915260048501805493909216949392909160608401916108b6906120de565b80601f01602080910402602001604051908101604052809291908181526020018280546108e2906120de565b801561092f5780601f106109045761010080835404028352916020019161092f565b820191906000526020600020905b81548152906001019060200180831161091257829003601f168201915b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b82821015610a4e576000848152602090819020604080516060810190915260038502909101805473ffffffffffffffffffffffffffffffffffffffff16825260018101805492939192918401916109b3906120de565b80601f01602080910402602001604051908101604052809291908181526020018280546109df906120de565b8015610a2c5780601f10610a0157610100808354040283529160200191610a2c565b820191906000526020600020905b815481529060010190602001808311610a0f57829003601f168201915b505050505081526020016002820154815250508152602001906001019061095d565b50505091525050600682015460079092015490919084565b600060018383604051610a7a929190612131565b90815260200160405180910390209050610a94838361185c565b50426006820155600781018054906000610aad83612170565b9091555050600581015460005b81811015610c13576000836001016004018281548110610adc57610adc6121a8565b6000918252602082206003909102018054600282015460405192945073ffffffffffffffffffffffffffffffffffffffff90911691610b1f9060018601906121d7565b60006040518083038185875af1925050503d8060008114610b5c576040519150601f19603f3d011682016040523d82523d6000602084013e610b61565b606091505b5050905080610bfe5760405162461bcd60e51b815260206004820152604c60248201527f447269707069653a20647269702077617320756e7375636365737366756c2c2060448201527f706c6561736520636865636b20796f757220636f6e66696775726174696f6e2060648201527f666f72206d697374616b65730000000000000000000000000000000000000000608482015260a401610396565b50508080610c0b90612170565b915050610aba565b508383604051610c24929190612131565b60405180910390207fea21435419aad9c54a9d90e2522b6f60bd566401f36fcef661f5f5a28cc0d2c685853342604051610c619493929190612296565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cd65760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b610ce081476106fe565b50565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610d4e5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610d7491906122d3565b60006040518083038185875af1925050503d8060008114610db1576040519150601f19603f3d011682016040523d82523d6000602084013e610db6565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e2a5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610ec0908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610e9c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017f91906122ef565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f2b5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6000816003811115610f3f57610f3f611c80565b03610fd85760405162461bcd60e51b815260206004820152604160248201527f447269707069653a2064726970207374617475732063616e206e65766572206260448201527f6520736574206261636b20746f204e4f4e45206166746572206372656174696f60648201527f6e00000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b600060018484604051610fec929190612131565b9081526040519081900360200190205460ff169050600081600381111561101557611015611c80565b036110ae5760405162461bcd60e51b815260206004820152604160248201527f447269707069653a206472697020776974682074686174206e616d6520646f6560448201527f73206e6f7420657869737420616e642063616e6e6f742062652075706461746560648201527f6400000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b60038160038111156110c2576110c2611c80565b0361115c5760405162461bcd60e51b8152602060048201526044602482018190527f447269707069653a206472697020776974682074686174206e616d6520686173908201527f206265656e20617263686976656420616e642063616e6e6f742062652075706460648201527f6174656400000000000000000000000000000000000000000000000000000000608482015260a401610396565b81600381111561116e5761116e611c80565b81600381111561118057611180611c80565b036112195760405162461bcd60e51b815260206004820152604860248201527f447269707069653a2063616e6e6f74207365742064726970207374617475732060448201527f746f207468652073616d6520737461747573206173206974732063757272656e60648201527f7420737461747573000000000000000000000000000000000000000000000000608482015260a401610396565b600382600381111561122d5761122d611c80565b036112b957600181600381111561124657611246611c80565b146112b95760405162461bcd60e51b815260206004820152603860248201527f447269707069653a2064726970206d757374206669727374206265207061757360448201527f6564206265666f7265206265696e6720617263686976656400000000000000006064820152608401610396565b81600185856040516112cc929190612131565b90815260405190819003602001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600381111561131357611313611c80565b02179055508383604051611328929190612131565b60405180910390207f407cb3ad05e60ec498fb39417c7a4f6b82d5ba80f82fe512a37b02c93181a2a1858585604051610c6193929190612308565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113ca5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6000600184846040516113de929190612131565b9081526040519081900360200190205460ff16600381111561140257611402611c80565b146114755760405162461bcd60e51b815260206004820152602b60248201527f447269707069653a206472697020776974682074686174206e616d6520616c7260448201527f65616479206578697374730000000000000000000000000000000000000000006064820152608401610396565b611482602082018261232b565b15611504576020810135156114ff5760405162461bcd60e51b815260206004820152603e60248201527f447269707069653a20696620616c6c6f77696e67207265656e7472616e74206460448201527f7269702c206d7573742073657420696e74657276616c20746f207a65726f00006064820152608401610396565b6115a5565b60008160200135116115a55760405162461bcd60e51b8152602060048201526044602482018190527f447269707069653a20696e74657276616c206d75737420626520677265617465908201527f72207468616e207a65726f2069662064726970206973206e6f74207265656e7460648201527f72616e7400000000000000000000000000000000000000000000000000000000608482015260a401610396565b6000600184846040516115b9929190612131565b9081526040516020918190038201902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117815591506116009083018361232b565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556020820135600282015561164b6060830160408401611af9565b6003820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561169f6060830183612348565b60048301916116af9190836123fc565b5060005b6116c060808401846124f9565b905081101561173357600582016116da60808501856124f9565b838181106116ea576116ea6121a8565b90506020028101906116fc9190612561565b81546001810183556000928352602090922090916003020161171e8282612595565b5050808061172b90612170565b9150506116b3565b508383604051611744929190612131565b60405180910390207fe38d8d98e6cc66f6f520d483c6c5a89289681f897799c4c29d767cf57e76d9a6858585604051610c619392919061286a565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146117ea5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8373ffffffffffffffffffffffffffffffffffffffff168360405161180f91906122d3565b600060405180830381855af49150503d806000811461184a576040519150601f19603f3d011682016040523d82523d6000602084013e61184f565b606091505b50915091505b9250929050565b60008060018484604051611871929190612131565b90815260405190819003602001902090506002815460ff16600381111561189a5761189a611c80565b1461190f576040805162461bcd60e51b81526020600482015260248101919091527f447269707069653a2073656c6563746564206472697020646f6573206e6f742060448201527f6578697374206f72206973206e6f742063757272656e746c79206163746976656064820152608401610396565b60028101546006820154429161192491612971565b11156119985760405162461bcd60e51b815260206004820152603660248201527f447269707069653a206472697020696e74657276616c20686173206e6f74206560448201527f6c61707365642073696e6365206c6173742064726970000000000000000000006064820152608401610396565b60038101546040517fc64b3bb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063c64b3bb5906119f29060048086019101612984565b602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a3391906120c1565b611acb5760405162461bcd60e51b815260206004820152604260248201527f447269707069653a2064726970636865636b206661696c656420736f2064726960448201527f70206973206e6f742079657420726561647920746f206265207472696767657260648201527f6564000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b60019150505b92915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce057600080fd5b600060208284031215611b0b57600080fd5b8135611b1681611ad7565b9392505050565b600080600060608486031215611b3257600080fd5b8335611b3d81611ad7565b92506020840135611b4d81611ad7565b929592945050506040919091013590565b60008060408385031215611b7157600080fd5b8235611b7c81611ad7565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115611bd457611bd4611b8a565b604051601f8501601f19908116603f01168101908282118183101715611bfc57611bfc611b8a565b81604052809350858152868686011115611c1557600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215611c4157600080fd5b813567ffffffffffffffff811115611c5857600080fd5b8201601f81018413611c6957600080fd5b611c7884823560208401611bb9565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110611ce6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60005b83811015611d05578181015183820152602001611ced565b50506000910152565b60008151808452611d26816020860160208601611cea565b601f01601f19169290920160200192915050565b611d448186611caf565b600060206080818401528551151560808401528086015160a084015260408087015173ffffffffffffffffffffffffffffffffffffffff80821660c0870152606091508189015160a060e0880152611da0610120880182611d0e565b60808b01518882037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80016101008a0152805180835291925086019086830190600581901b8401880160005b82811015611e3657601f1986830301845284518781511683528a810151898c850152611e198a850182611d0e565b918b0151938b0193909352948a0194938a01939150600101611deb565b50968a019b909b52505050509093019390935250949350505050565b60008083601f840112611e6457600080fd5b50813567ffffffffffffffff811115611e7c57600080fd5b60208301915083602082850101111561185557600080fd5b60008060208385031215611ea757600080fd5b823567ffffffffffffffff811115611ebe57600080fd5b611eca85828601611e52565b90969095509350505050565b600082601f830112611ee757600080fd5b611b1683833560208501611bb9565b600080600060608486031215611f0b57600080fd5b8335611f1681611ad7565b9250602084013567ffffffffffffffff811115611f3257600080fd5b611f3e86828701611ed6565b925050604084013590509250925092565b8215158152604060208201526000611c786040830184611d0e565b60008060408385031215611f7d57600080fd5b8235611f8881611ad7565b91506020830135611f9881611ad7565b809150509250929050565b600080600060408486031215611fb857600080fd5b833567ffffffffffffffff811115611fcf57600080fd5b611fdb86828701611e52565b909450925050602084013560048110611ff357600080fd5b809150509250925092565b60008060006040848603121561201357600080fd5b833567ffffffffffffffff8082111561202b57600080fd5b61203787838801611e52565b9095509350602086013591508082111561205057600080fd5b50840160a08187031215611ff357600080fd5b6000806040838503121561207657600080fd5b823561208181611ad7565b9150602083013567ffffffffffffffff81111561209d57600080fd5b6120a985828601611ed6565b9150509250929050565b8015158114610ce057600080fd5b6000602082840312156120d357600080fd5b8151611b16816120b3565b600181811c908216806120f257607f821691505b60208210810361212b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036121a1576121a1612141565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083546121e5816120de565b600182811680156121fd57600181146122305761225f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008416875282151583028701945061225f565b8760005260208060002060005b858110156122565781548a82015290840190820161223d565b50505082870194505b50929695505050505050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6060815260006122aa60608301868861226b565b73ffffffffffffffffffffffffffffffffffffffff949094166020830152506040015292915050565b600082516122e5818460208701611cea565b9190910192915050565b60006020828403121561230157600080fd5b5051919050565b60408152600061231c60408301858761226b565b9050611c786020830184611caf565b60006020828403121561233d57600080fd5b8135611b16816120b3565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261237d57600080fd5b83018035915067ffffffffffffffff82111561239857600080fd5b60200191503681900382131561185557600080fd5b601f8211156123f757600081815260208120601f850160051c810160208610156123d45750805b601f850160051c820191505b818110156123f3578281556001016123e0565b5050505b505050565b67ffffffffffffffff83111561241457612414611b8a565b6124288361242283546120de565b836123ad565b6000601f84116001811461247a57600085156124445750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556124f2565b600083815260209020601f19861690835b828110156124ab578685013582556020948501946001909201910161248b565b50868210156124e6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261252e57600080fd5b83018035915067ffffffffffffffff82111561254957600080fd5b6020019150600581901b360382131561185557600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126122e557600080fd5b81356125a081611ad7565b73ffffffffffffffffffffffffffffffffffffffff81167fffffffffffffffffffffffff00000000000000000000000000000000000000008354161782555060018082016020808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261261a57600080fd5b8501803567ffffffffffffffff81111561263357600080fd5b803603838301131561264457600080fd5b6126588161265286546120de565b866123ad565b6000601f8211600181146126ac576000831561267657508382018501355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b178655612723565b600086815260209020601f19841690835b828110156126dc578685018801358255938701939089019087016126bd565b5084821015612719577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c198785880101351681555b50508683881b0186555b50505050505050604082013560028201555050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261276d57600080fd5b830160208101925035905067ffffffffffffffff81111561278d57600080fd5b80360382131561185557600080fd5b81835260006020808501808196508560051b81019150846000805b8881101561285c578385038a5282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18936030181126127f5578283fd5b88016060813561280481611ad7565b73ffffffffffffffffffffffffffffffffffffffff16875261282882890183612738565b828a8a015261283a838a01828461226b565b60409485013599909401989098525050998601999450918501916001016127b7565b509298975050505050505050565b60408152600061287e60408301858761226b565b82810360208401528335612891816120b3565b151581526020848101359082015260408401356128ad81611ad7565b73ffffffffffffffffffffffffffffffffffffffff1660408201526128d56060850185612738565b60a060608401526128ea60a08401828461226b565b91505060808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261292257600080fd5b850160208101903567ffffffffffffffff81111561293f57600080fd5b8060051b360382131561295157600080fd5b838303608085015261296483828461279c565b9998505050505050505050565b80820180821115611ad157611ad1612141565b6000602080835260008454612998816120de565b808487015260406001808416600081146129b957600181146129f157612a1f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a01019550612a1f565b896000528660002060005b85811015612a175781548b82018601529083019088016129fc565b8a0184019650505b50939897505050505050505056fea26469706673582212208d60ccb026b0dcc2e3511887db1b30dfd98f123af2a2a96714cbeca8ed21494464736f6c63430008100033", - "deployedBytecode": "0x6080604052600436106100e15760003560e01c80636e2d44ae1161007f5780639bc94d01116100595780639bc94d01146102b0578063e551cdaa146102d0578063edee6239146102f0578063fc3e3eba1461030357600080fd5b80636e2d44ae1461021d5780638da5cb5b1461023e5780639456fbcc1461029057600080fd5b80634782f779116100bb5780634782f779146101845780634d7fba6e146101a457806367148cd2146101dd578063690d8320146101fd57600080fd5b806313af4035146101225780634025feb21461014457806344004cc11461016457600080fd5b3661011d5760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561012e57600080fd5b5061014261013d366004611af9565b610333565b005b34801561015057600080fd5b5061014261015f366004611b1d565b61040f565b34801561017057600080fd5b5061014261017f366004611b1d565b610587565b34801561019057600080fd5b5061014261019f366004611b5e565b6106fe565b3480156101b057600080fd5b506101c46101bf366004611c2f565b610834565b6040516101d49493929190611d3a565b60405180910390f35b3480156101e957600080fd5b506101426101f8366004611e94565b610a66565b34801561020957600080fd5b50610142610218366004611af9565b610c6f565b61023061022b366004611ef6565b610ce3565b6040516101d4929190611f4f565b34801561024a57600080fd5b5060005461026b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d4565b34801561029c57600080fd5b506101426102ab366004611f6a565b610dc3565b3480156102bc57600080fd5b506101426102cb366004611fa3565b610ec4565b3480156102dc57600080fd5b506101426102eb366004611ffe565b611363565b6102306102fe366004612063565b61177f565b34801561030f57600080fd5b5061032361031e366004611e94565b61185c565b60405190151581526020016101d4565b60005473ffffffffffffffffffffffffffffffffffffffff16331461039f5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104765760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b1580156104ec57600080fd5b505af1158015610500573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a88460405161057a91815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ee5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015610663573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068791906120c1565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa8460405161057a91815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107655760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146107bf576040519150601f19603f3d011682016040523d82523d6000602084013e6107c4565b606091505b505090508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc8460405161082791815260200190565b60405180910390a3505050565b805160208183018101805160018083529383019483019490942093905282546040805160a081018252938501805460ff90811615158652600287015494860194909452600386015473ffffffffffffffffffffffffffffffffffffffff169185019190915260048501805493909216949392909160608401916108b6906120de565b80601f01602080910402602001604051908101604052809291908181526020018280546108e2906120de565b801561092f5780601f106109045761010080835404028352916020019161092f565b820191906000526020600020905b81548152906001019060200180831161091257829003601f168201915b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b82821015610a4e576000848152602090819020604080516060810190915260038502909101805473ffffffffffffffffffffffffffffffffffffffff16825260018101805492939192918401916109b3906120de565b80601f01602080910402602001604051908101604052809291908181526020018280546109df906120de565b8015610a2c5780601f10610a0157610100808354040283529160200191610a2c565b820191906000526020600020905b815481529060010190602001808311610a0f57829003601f168201915b505050505081526020016002820154815250508152602001906001019061095d565b50505091525050600682015460079092015490919084565b600060018383604051610a7a929190612131565b90815260200160405180910390209050610a94838361185c565b50426006820155600781018054906000610aad83612170565b9091555050600581015460005b81811015610c13576000836001016004018281548110610adc57610adc6121a8565b6000918252602082206003909102018054600282015460405192945073ffffffffffffffffffffffffffffffffffffffff90911691610b1f9060018601906121d7565b60006040518083038185875af1925050503d8060008114610b5c576040519150601f19603f3d011682016040523d82523d6000602084013e610b61565b606091505b5050905080610bfe5760405162461bcd60e51b815260206004820152604c60248201527f447269707069653a20647269702077617320756e7375636365737366756c2c2060448201527f706c6561736520636865636b20796f757220636f6e66696775726174696f6e2060648201527f666f72206d697374616b65730000000000000000000000000000000000000000608482015260a401610396565b50508080610c0b90612170565b915050610aba565b508383604051610c24929190612131565b60405180910390207fea21435419aad9c54a9d90e2522b6f60bd566401f36fcef661f5f5a28cc0d2c685853342604051610c619493929190612296565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cd65760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b610ce081476106fe565b50565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610d4e5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610d7491906122d3565b60006040518083038185875af1925050503d8060008114610db1576040519150601f19603f3d011682016040523d82523d6000602084013e610db6565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e2a5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610ec0908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610e9c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017f91906122ef565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f2b5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6000816003811115610f3f57610f3f611c80565b03610fd85760405162461bcd60e51b815260206004820152604160248201527f447269707069653a2064726970207374617475732063616e206e65766572206260448201527f6520736574206261636b20746f204e4f4e45206166746572206372656174696f60648201527f6e00000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b600060018484604051610fec929190612131565b9081526040519081900360200190205460ff169050600081600381111561101557611015611c80565b036110ae5760405162461bcd60e51b815260206004820152604160248201527f447269707069653a206472697020776974682074686174206e616d6520646f6560448201527f73206e6f7420657869737420616e642063616e6e6f742062652075706461746560648201527f6400000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b60038160038111156110c2576110c2611c80565b0361115c5760405162461bcd60e51b8152602060048201526044602482018190527f447269707069653a206472697020776974682074686174206e616d6520686173908201527f206265656e20617263686976656420616e642063616e6e6f742062652075706460648201527f6174656400000000000000000000000000000000000000000000000000000000608482015260a401610396565b81600381111561116e5761116e611c80565b81600381111561118057611180611c80565b036112195760405162461bcd60e51b815260206004820152604860248201527f447269707069653a2063616e6e6f74207365742064726970207374617475732060448201527f746f207468652073616d6520737461747573206173206974732063757272656e60648201527f7420737461747573000000000000000000000000000000000000000000000000608482015260a401610396565b600382600381111561122d5761122d611c80565b036112b957600181600381111561124657611246611c80565b146112b95760405162461bcd60e51b815260206004820152603860248201527f447269707069653a2064726970206d757374206669727374206265207061757360448201527f6564206265666f7265206265696e6720617263686976656400000000000000006064820152608401610396565b81600185856040516112cc929190612131565b90815260405190819003602001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600381111561131357611313611c80565b02179055508383604051611328929190612131565b60405180910390207f407cb3ad05e60ec498fb39417c7a4f6b82d5ba80f82fe512a37b02c93181a2a1858585604051610c6193929190612308565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113ca5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6000600184846040516113de929190612131565b9081526040519081900360200190205460ff16600381111561140257611402611c80565b146114755760405162461bcd60e51b815260206004820152602b60248201527f447269707069653a206472697020776974682074686174206e616d6520616c7260448201527f65616479206578697374730000000000000000000000000000000000000000006064820152608401610396565b611482602082018261232b565b15611504576020810135156114ff5760405162461bcd60e51b815260206004820152603e60248201527f447269707069653a20696620616c6c6f77696e67207265656e7472616e74206460448201527f7269702c206d7573742073657420696e74657276616c20746f207a65726f00006064820152608401610396565b6115a5565b60008160200135116115a55760405162461bcd60e51b8152602060048201526044602482018190527f447269707069653a20696e74657276616c206d75737420626520677265617465908201527f72207468616e207a65726f2069662064726970206973206e6f74207265656e7460648201527f72616e7400000000000000000000000000000000000000000000000000000000608482015260a401610396565b6000600184846040516115b9929190612131565b9081526040516020918190038201902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117815591506116009083018361232b565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556020820135600282015561164b6060830160408401611af9565b6003820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561169f6060830183612348565b60048301916116af9190836123fc565b5060005b6116c060808401846124f9565b905081101561173357600582016116da60808501856124f9565b838181106116ea576116ea6121a8565b90506020028101906116fc9190612561565b81546001810183556000928352602090922090916003020161171e8282612595565b5050808061172b90612170565b9150506116b3565b508383604051611744929190612131565b60405180910390207fe38d8d98e6cc66f6f520d483c6c5a89289681f897799c4c29d767cf57e76d9a6858585604051610c619392919061286a565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146117ea5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8373ffffffffffffffffffffffffffffffffffffffff168360405161180f91906122d3565b600060405180830381855af49150503d806000811461184a576040519150601f19603f3d011682016040523d82523d6000602084013e61184f565b606091505b50915091505b9250929050565b60008060018484604051611871929190612131565b90815260405190819003602001902090506002815460ff16600381111561189a5761189a611c80565b1461190f576040805162461bcd60e51b81526020600482015260248101919091527f447269707069653a2073656c6563746564206472697020646f6573206e6f742060448201527f6578697374206f72206973206e6f742063757272656e746c79206163746976656064820152608401610396565b60028101546006820154429161192491612971565b11156119985760405162461bcd60e51b815260206004820152603660248201527f447269707069653a206472697020696e74657276616c20686173206e6f74206560448201527f6c61707365642073696e6365206c6173742064726970000000000000000000006064820152608401610396565b60038101546040517fc64b3bb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063c64b3bb5906119f29060048086019101612984565b602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a3391906120c1565b611acb5760405162461bcd60e51b815260206004820152604260248201527f447269707069653a2064726970636865636b206661696c656420736f2064726960448201527f70206973206e6f742079657420726561647920746f206265207472696767657260648201527f6564000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b60019150505b92915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ce057600080fd5b600060208284031215611b0b57600080fd5b8135611b1681611ad7565b9392505050565b600080600060608486031215611b3257600080fd5b8335611b3d81611ad7565b92506020840135611b4d81611ad7565b929592945050506040919091013590565b60008060408385031215611b7157600080fd5b8235611b7c81611ad7565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115611bd457611bd4611b8a565b604051601f8501601f19908116603f01168101908282118183101715611bfc57611bfc611b8a565b81604052809350858152868686011115611c1557600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215611c4157600080fd5b813567ffffffffffffffff811115611c5857600080fd5b8201601f81018413611c6957600080fd5b611c7884823560208401611bb9565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110611ce6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60005b83811015611d05578181015183820152602001611ced565b50506000910152565b60008151808452611d26816020860160208601611cea565b601f01601f19169290920160200192915050565b611d448186611caf565b600060206080818401528551151560808401528086015160a084015260408087015173ffffffffffffffffffffffffffffffffffffffff80821660c0870152606091508189015160a060e0880152611da0610120880182611d0e565b60808b01518882037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80016101008a0152805180835291925086019086830190600581901b8401880160005b82811015611e3657601f1986830301845284518781511683528a810151898c850152611e198a850182611d0e565b918b0151938b0193909352948a0194938a01939150600101611deb565b50968a019b909b52505050509093019390935250949350505050565b60008083601f840112611e6457600080fd5b50813567ffffffffffffffff811115611e7c57600080fd5b60208301915083602082850101111561185557600080fd5b60008060208385031215611ea757600080fd5b823567ffffffffffffffff811115611ebe57600080fd5b611eca85828601611e52565b90969095509350505050565b600082601f830112611ee757600080fd5b611b1683833560208501611bb9565b600080600060608486031215611f0b57600080fd5b8335611f1681611ad7565b9250602084013567ffffffffffffffff811115611f3257600080fd5b611f3e86828701611ed6565b925050604084013590509250925092565b8215158152604060208201526000611c786040830184611d0e565b60008060408385031215611f7d57600080fd5b8235611f8881611ad7565b91506020830135611f9881611ad7565b809150509250929050565b600080600060408486031215611fb857600080fd5b833567ffffffffffffffff811115611fcf57600080fd5b611fdb86828701611e52565b909450925050602084013560048110611ff357600080fd5b809150509250925092565b60008060006040848603121561201357600080fd5b833567ffffffffffffffff8082111561202b57600080fd5b61203787838801611e52565b9095509350602086013591508082111561205057600080fd5b50840160a08187031215611ff357600080fd5b6000806040838503121561207657600080fd5b823561208181611ad7565b9150602083013567ffffffffffffffff81111561209d57600080fd5b6120a985828601611ed6565b9150509250929050565b8015158114610ce057600080fd5b6000602082840312156120d357600080fd5b8151611b16816120b3565b600181811c908216806120f257607f821691505b60208210810361212b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036121a1576121a1612141565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083546121e5816120de565b600182811680156121fd57600181146122305761225f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008416875282151583028701945061225f565b8760005260208060002060005b858110156122565781548a82015290840190820161223d565b50505082870194505b50929695505050505050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6060815260006122aa60608301868861226b565b73ffffffffffffffffffffffffffffffffffffffff949094166020830152506040015292915050565b600082516122e5818460208701611cea565b9190910192915050565b60006020828403121561230157600080fd5b5051919050565b60408152600061231c60408301858761226b565b9050611c786020830184611caf565b60006020828403121561233d57600080fd5b8135611b16816120b3565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261237d57600080fd5b83018035915067ffffffffffffffff82111561239857600080fd5b60200191503681900382131561185557600080fd5b601f8211156123f757600081815260208120601f850160051c810160208610156123d45750805b601f850160051c820191505b818110156123f3578281556001016123e0565b5050505b505050565b67ffffffffffffffff83111561241457612414611b8a565b6124288361242283546120de565b836123ad565b6000601f84116001811461247a57600085156124445750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556124f2565b600083815260209020601f19861690835b828110156124ab578685013582556020948501946001909201910161248b565b50868210156124e6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261252e57600080fd5b83018035915067ffffffffffffffff82111561254957600080fd5b6020019150600581901b360382131561185557600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126122e557600080fd5b81356125a081611ad7565b73ffffffffffffffffffffffffffffffffffffffff81167fffffffffffffffffffffffff00000000000000000000000000000000000000008354161782555060018082016020808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261261a57600080fd5b8501803567ffffffffffffffff81111561263357600080fd5b803603838301131561264457600080fd5b6126588161265286546120de565b866123ad565b6000601f8211600181146126ac576000831561267657508382018501355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b178655612723565b600086815260209020601f19841690835b828110156126dc578685018801358255938701939089019087016126bd565b5084821015612719577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c198785880101351681555b50508683881b0186555b50505050505050604082013560028201555050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261276d57600080fd5b830160208101925035905067ffffffffffffffff81111561278d57600080fd5b80360382131561185557600080fd5b81835260006020808501808196508560051b81019150846000805b8881101561285c578385038a5282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18936030181126127f5578283fd5b88016060813561280481611ad7565b73ffffffffffffffffffffffffffffffffffffffff16875261282882890183612738565b828a8a015261283a838a01828461226b565b60409485013599909401989098525050998601999450918501916001016127b7565b509298975050505050505050565b60408152600061287e60408301858761226b565b82810360208401528335612891816120b3565b151581526020848101359082015260408401356128ad81611ad7565b73ffffffffffffffffffffffffffffffffffffffff1660408201526128d56060850185612738565b60a060608401526128ea60a08401828461226b565b91505060808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261292257600080fd5b850160208101903567ffffffffffffffff81111561293f57600080fd5b8060051b360382131561295157600080fd5b838303608085015261296483828461279c565b9998505050505050505050565b80820180821115611ad157611ad1612141565b6000602080835260008454612998816120de565b808487015260406001808416600081146129b957600181146129f157612a1f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a01019550612a1f565b896000528660002060005b85811015612a175781548b82018601529083019088016129fc565b8a0184019650505b50939897505050505050505056fea26469706673582212208d60ccb026b0dcc2e3511887db1b30dfd98f123af2a2a96714cbeca8ed21494464736f6c63430008100033", - "devdoc": { - "events": { - "DripCreated(string,string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))": { - "params": { - "config": "Config for the created drip.", - "name": "Unindexed name parameter (unhashed).", - "nameref": "Indexed name parameter (hashed)." - } - }, - "DripExecuted(string,string,address,uint256)": { - "params": { - "executor": "Address that executed the drip.", - "name": "Unindexed name parameter (unhashed).", - "nameref": "Indexed name parameter (hashed).", - "timestamp": "Time when the drip was executed." - } - }, - "DripStatusUpdated(string,string,uint8)": { - "params": { - "name": "Unindexed name parameter (unhashed).", - "nameref": "Indexed name parameter (hashed).", - "status": "New drip status." - } - } - }, - "kind": "dev", - "methods": { - "CALL(address,bytes,uint256)": { - "params": { - "_data": "Data to send with the call.", - "_target": "Address to call.", - "_value": "ETH value to send with the call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "DELEGATECALL(address,bytes)": { - "params": { - "_data": "Data to send with the call.", - "_target": "Address to call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "constructor": { - "params": { - "_owner": "Initial contract owner." - } - }, - "create(string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))": { - "params": { - "_config": "Configuration for the drip.", - "_name": "Name of the drip." - } - }, - "drip(string)": { - "params": { - "_name": "Name of the drip to trigger." - } - }, - "executable(string)": { - "params": { - "_name": "Drip to check." - }, - "returns": { - "_0": "True if the drip is executable, reverts otherwise." - } - }, - "status(string,uint8)": { - "params": { - "_name": "Name of the drip to update.", - "_status": "New drip status." - } - }, - "withdrawERC20(address,address)": { - "params": { - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC20(address,address,uint256)": { - "params": { - "_amount": "Amount of ERC20 to withdraw.", - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC721(address,address,uint256)": { - "params": { - "_asset": "ERC721 token to withdraw.", - "_id": "Token ID of the ERC721 token to withdraw.", - "_to": "Address to receive the ERC721 token." - } - }, - "withdrawETH(address)": { - "params": { - "_to": "Address to receive the ETH balance." - } - }, - "withdrawETH(address,uint256)": { - "params": { - "_amount": "Amount of ETH to withdraw.", - "_to": "Address to receive the ETH balance." - } - } - }, - "title": "Drippie", - "version": 1 - }, - "userdoc": { - "events": { - "DripCreated(string,string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))": { - "notice": "Emitted when a new drip is created." - }, - "DripExecuted(string,string,address,uint256)": { - "notice": "Emitted when a drip is executed." - }, - "DripStatusUpdated(string,string,uint8)": { - "notice": "Emitted when a drip status is updated." - }, - "ReceivedETH(address,uint256)": { - "notice": "Emitted when ETH is received by this address." - }, - "WithdrewERC20(address,address,address,uint256)": { - "notice": "Emitted when ERC20 tokens are withdrawn from this address." - }, - "WithdrewERC721(address,address,address,uint256)": { - "notice": "Emitted when ERC20 tokens are withdrawn from this address." - }, - "WithdrewETH(address,address,uint256)": { - "notice": "Emitted when ETH is withdrawn from this address." - } - }, - "kind": "user", - "methods": { - "CALL(address,bytes,uint256)": { - "notice": "Sends a CALL to a target address." - }, - "DELEGATECALL(address,bytes)": { - "notice": "Sends a DELEGATECALL to a target address." - }, - "create(string,(bool,uint256,address,bytes,(address,bytes,uint256)[]))": { - "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." - }, - "drip(string)": { - "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. Note that the drip check is executed only **once** at the beginning of the call to the drip function and will not be executed again between the drip actions within this call." - }, - "drips(string)": { - "notice": "Maps from drip names to drip states." - }, - "executable(string)": { - "notice": "Checks if a given drip is executable." - }, - "status(string,uint8)": { - "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." - }, - "withdrawERC20(address,address)": { - "notice": "Withdraws full ERC20 balance to the recipient." - }, - "withdrawERC20(address,address,uint256)": { - "notice": "Withdraws partial ERC20 balance to the recipient." - }, - "withdrawERC721(address,address,uint256)": { - "notice": "Withdraws ERC721 token to the recipient." - }, - "withdrawETH(address)": { - "notice": "Withdraws full ETH balance to the recipient." - }, - "withdrawETH(address,uint256)": { - "notice": "Withdraws partial ETH balance to the recipient." - } - }, - "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.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 10, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 1431, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "drips", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_string_memory_ptr,t_struct(DripState)1394_storage)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_address_payable": { - "encoding": "inplace", - "label": "address payable", - "numberOfBytes": "20" - }, - "t_array(t_struct(DripAction)1369_storage)dyn_storage": { - "base": "t_struct(DripAction)1369_storage", - "encoding": "dynamic_array", - "label": "struct Drippie.DripAction[]", - "numberOfBytes": "32" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_storage": { - "encoding": "bytes", - "label": "bytes", - "numberOfBytes": "32" - }, - "t_contract(IDripCheck)1794": { - "encoding": "inplace", - "label": "contract IDripCheck", - "numberOfBytes": "20" - }, - "t_enum(DripStatus)1362": { - "encoding": "inplace", - "label": "enum Drippie.DripStatus", - "numberOfBytes": "1" - }, - "t_mapping(t_string_memory_ptr,t_struct(DripState)1394_storage)": { - "encoding": "mapping", - "key": "t_string_memory_ptr", - "label": "mapping(string => struct Drippie.DripState)", - "numberOfBytes": "32", - "value": "t_struct(DripState)1394_storage" - }, - "t_string_memory_ptr": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(DripAction)1369_storage": { - "encoding": "inplace", - "label": "struct Drippie.DripAction", - "members": [ - { - "astId": 1364, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "target", - "offset": 0, - "slot": "0", - "type": "t_address_payable" - }, - { - "astId": 1366, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "data", - "offset": 0, - "slot": "1", - "type": "t_bytes_storage" - }, - { - "astId": 1368, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "value", - "offset": 0, - "slot": "2", - "type": "t_uint256" - } - ], - "numberOfBytes": "96" - }, - "t_struct(DripConfig)1383_storage": { - "encoding": "inplace", - "label": "struct Drippie.DripConfig", - "members": [ - { - "astId": 1371, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "reentrant", - "offset": 0, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 1373, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "interval", - "offset": 0, - "slot": "1", - "type": "t_uint256" - }, - { - "astId": 1376, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "dripcheck", - "offset": 0, - "slot": "2", - "type": "t_contract(IDripCheck)1794" - }, - { - "astId": 1378, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "checkparams", - "offset": 0, - "slot": "3", - "type": "t_bytes_storage" - }, - { - "astId": 1382, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "actions", - "offset": 0, - "slot": "4", - "type": "t_array(t_struct(DripAction)1369_storage)dyn_storage" - } - ], - "numberOfBytes": "160" - }, - "t_struct(DripState)1394_storage": { - "encoding": "inplace", - "label": "struct Drippie.DripState", - "members": [ - { - "astId": 1386, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "status", - "offset": 0, - "slot": "0", - "type": "t_enum(DripStatus)1362" - }, - { - "astId": 1389, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "config", - "offset": 0, - "slot": "1", - "type": "t_struct(DripConfig)1383_storage" - }, - { - "astId": 1391, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "last", - "offset": 0, - "slot": "6", - "type": "t_uint256" - }, - { - "astId": 1393, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "count", - "offset": 0, - "slot": "7", - "type": "t_uint256" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/L1CrossDomainMessenger.json b/packages/contracts-bedrock/deployments/mainnet/L1CrossDomainMessenger.json deleted file mode 100644 index 8be23c6179f0..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/L1CrossDomainMessenger.json +++ /dev/null @@ -1,772 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "msgHash", - "type": "bytes32" - } - ], - "name": "FailedRelayedMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "msgHash", - "type": "bytes32" - } - ], - "name": "RelayedMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "message", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "messageNonce", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - } - ], - "name": "SentMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "SentMessageExtension1", - "type": "event" - }, - { - "inputs": [], - "name": "MESSAGE_VERSION", - "outputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_CALLDATA_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_MESSENGER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PORTAL", - "outputs": [ - { - "internalType": "contract OptimismPortal", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_CALL_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_CONSTANT_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_GAS_CHECK_BUFFER", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_RESERVED_GAS", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - } - ], - "name": "baseGas", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "failedMessages", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract OptimismPortal", - "name": "_portal", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "messageNonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "portal", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "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": "_minGasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - } - ], - "name": "relayMessage", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - } - ], - "name": "sendMessage", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "successfulMessages", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "xDomainMessageSender", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0xDa2332D0a7608919Cd331B1304Cd179129a90495", - "args": [], - "bytecode": "0x60a06040523480156200001157600080fd5b507342000000000000000000000000000000000000076080526200003660006200003c565b620001ea565b600054600390600160a81b900460ff1615801562000068575060005460ff808316600160a01b90920416105b620000d15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b60008054600160a81b61ffff60a01b19909116600160a01b60ff85160260ff60a81b19161717905560f980546001600160a01b0319166001600160a01b0384161790556200011e62000165565b6000805460ff60a81b1916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054600160a81b900460ff16620001d45760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000c8565b60cc80546001600160a01b03191661dead179055565b608051611cee620002146000396000818161033b0152818161048a01526114ef0152611cee6000f3fe60806040526004361061015f5760003560e01c80636e296e45116100c0578063b1b1b20911610074578063c4d66de811610059578063c4d66de8146103ed578063d764ad0b1461040d578063ecc704281461042057600080fd5b8063b1b1b2091461039d578063b28ade25146103cd57600080fd5b80638cbeeef2116100a55780638cbeeef2146102505780639fce812c14610329578063a4e7f8bd1461035d57600080fd5b80636e296e45146102fd57806383a740741461031257600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146102665780635644cfdf146102bc5780636425666b146102d257600080fd5b80633f827a5a146102285780634c1d6a691461025057600080fd5b80630ff754ea116101485780630ff754ea146101ac5780632828d7e8146101fe5780633dbb202b1461021357600080fd5b8063028f85f7146101645780630c56849814610197575b600080fd5b34801561017057600080fd5b50610179601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101a357600080fd5b50610179603f81565b3480156101b857600080fd5b5060f9546101d99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018e565b34801561020a57600080fd5b50610179604081565b6102266102213660046117ba565b610485565b005b34801561023457600080fd5b5061023d600181565b60405161ffff909116815260200161018e565b34801561025c57600080fd5b50610179619c4081565b34801561027257600080fd5b506102af6040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b60405161018e919061188c565b3480156102c857600080fd5b5061017961138881565b3480156102de57600080fd5b5060f95473ffffffffffffffffffffffffffffffffffffffff166101d9565b34801561030957600080fd5b506101d96106e9565b34801561031e57600080fd5b5061017962030d4081565b34801561033557600080fd5b506101d97f000000000000000000000000000000000000000000000000000000000000000081565b34801561036957600080fd5b5061038d6103783660046118a6565b60ce6020526000908152604090205460ff1681565b604051901515815260200161018e565b3480156103a957600080fd5b5061038d6103b83660046118a6565b60cb6020526000908152604090205460ff1681565b3480156103d957600080fd5b506101796103e83660046118bf565b6107d5565b3480156103f957600080fd5b50610226610408366004611913565b610843565b61022661041b366004611930565b610a47565b34801561042c57600080fd5b5061047760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b60405190815260200161018e565b6105be7f00000000000000000000000000000000000000000000000000000000000000006104b48585856107d5565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061052060cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c60405160240161053c97969594939291906119ff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526112d3565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561064360cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b86604051610655959493929190611a5e565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6107f1604063ffffffff8816611adb565b6107fb9190611b0b565b610806601088611adb565b6108139062030d40611b59565b61081d9190611b59565b6108279190611b59565b6108319190611b59565b61083b9190611b59565b949350505050565b6000546003907501000000000000000000000000000000000000000000900460ff16158015610891575060005460ff8083167401000000000000000000000000000000000000000090920416105b61091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107af565b6000805475010000000000000000000000000000000000000000007fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000060ff8516027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff161717905560f980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556109e561136c565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60f087901c60028110610b02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107af565b8061ffff16600003610bf7576000610b53878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250611445915050565b600081815260cb602052604090205490915060ff1615610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107af565b505b6000610c3d898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146492505050565b9050610c47611487565b15610c7f57853414610c5b57610c5b611b85565b600081815260ce602052604090205460ff1615610c7a57610c7a611b85565b610dd1565b3415610d33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107af565b600081815260ce602052604090205460ff16610dd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107af565b610dda8761157d565b15610e8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107af565b600081815260cb602052604090205460ff1615610f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107af565b610f4d85610f3e611388619c40611b59565b67ffffffffffffffff166115c3565b1580610f73575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561108c57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b50506112c5565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061111d88619c405a6110e09190611bb4565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115e192505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111b457600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112c1565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b5050505b50505050505050565b905090565b60f9546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611334908890839089906000908990600401611bcb565b6000604051808303818588803b15801561134d57600080fd5b505af1158015611361573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107af565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611453858585856115fb565b805190602001209050949350505050565b6000611474878787878787611694565b8051906020012090509695505050505050565b60f95460009073ffffffffffffffffffffffffffffffffffffffff16331480156112ce575060f954604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691639bf62d829160048083019260209291908290030181865afa15801561153d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115619190611c23565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff82163014806115bd575060f95473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116149493929190611c40565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60608686868686866040516024016116b196959493929190611c8a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461175557600080fd5b50565b60008083601f84011261176a57600080fd5b50813567ffffffffffffffff81111561178257600080fd5b60208301915083602082850101111561179a57600080fd5b9250929050565b803563ffffffff811681146117b557600080fd5b919050565b600080600080606085870312156117d057600080fd5b84356117db81611733565b9350602085013567ffffffffffffffff8111156117f757600080fd5b61180387828801611758565b90945092506118169050604086016117a1565b905092959194509250565b6000815180845260005b818110156118475760208185018101518683018201520161182b565b81811115611859576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061189f6020830184611821565b9392505050565b6000602082840312156118b857600080fd5b5035919050565b6000806000604084860312156118d457600080fd5b833567ffffffffffffffff8111156118eb57600080fd5b6118f786828701611758565b909450925061190a9050602085016117a1565b90509250925092565b60006020828403121561192557600080fd5b813561189f81611733565b600080600080600080600060c0888a03121561194b57600080fd5b87359650602088013561195d81611733565b9550604088013561196d81611733565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561199757600080fd5b6119a38a828b01611758565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611a5160c0830184866119b6565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611a8e6080830186886119b6565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611b0257611b02611aac565b02949350505050565b600067ffffffffffffffff80841680611b4d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b7c57611b7c611aac565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611bc657611bc6611aac565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611c1860a0830184611821565b979650505050505050565b600060208284031215611c3557600080fd5b815161189f81611733565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611c796080830185611821565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611cd560c0830184611821565b9897505050505050505056fea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061015f5760003560e01c80636e296e45116100c0578063b1b1b20911610074578063c4d66de811610059578063c4d66de8146103ed578063d764ad0b1461040d578063ecc704281461042057600080fd5b8063b1b1b2091461039d578063b28ade25146103cd57600080fd5b80638cbeeef2116100a55780638cbeeef2146102505780639fce812c14610329578063a4e7f8bd1461035d57600080fd5b80636e296e45146102fd57806383a740741461031257600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146102665780635644cfdf146102bc5780636425666b146102d257600080fd5b80633f827a5a146102285780634c1d6a691461025057600080fd5b80630ff754ea116101485780630ff754ea146101ac5780632828d7e8146101fe5780633dbb202b1461021357600080fd5b8063028f85f7146101645780630c56849814610197575b600080fd5b34801561017057600080fd5b50610179601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101a357600080fd5b50610179603f81565b3480156101b857600080fd5b5060f9546101d99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018e565b34801561020a57600080fd5b50610179604081565b6102266102213660046117ba565b610485565b005b34801561023457600080fd5b5061023d600181565b60405161ffff909116815260200161018e565b34801561025c57600080fd5b50610179619c4081565b34801561027257600080fd5b506102af6040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b60405161018e919061188c565b3480156102c857600080fd5b5061017961138881565b3480156102de57600080fd5b5060f95473ffffffffffffffffffffffffffffffffffffffff166101d9565b34801561030957600080fd5b506101d96106e9565b34801561031e57600080fd5b5061017962030d4081565b34801561033557600080fd5b506101d97f000000000000000000000000000000000000000000000000000000000000000081565b34801561036957600080fd5b5061038d6103783660046118a6565b60ce6020526000908152604090205460ff1681565b604051901515815260200161018e565b3480156103a957600080fd5b5061038d6103b83660046118a6565b60cb6020526000908152604090205460ff1681565b3480156103d957600080fd5b506101796103e83660046118bf565b6107d5565b3480156103f957600080fd5b50610226610408366004611913565b610843565b61022661041b366004611930565b610a47565b34801561042c57600080fd5b5061047760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b60405190815260200161018e565b6105be7f00000000000000000000000000000000000000000000000000000000000000006104b48585856107d5565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061052060cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c60405160240161053c97969594939291906119ff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526112d3565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561064360cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b86604051610655959493929190611a5e565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6107f1604063ffffffff8816611adb565b6107fb9190611b0b565b610806601088611adb565b6108139062030d40611b59565b61081d9190611b59565b6108279190611b59565b6108319190611b59565b61083b9190611b59565b949350505050565b6000546003907501000000000000000000000000000000000000000000900460ff16158015610891575060005460ff8083167401000000000000000000000000000000000000000090920416105b61091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107af565b6000805475010000000000000000000000000000000000000000007fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000060ff8516027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff161717905560f980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556109e561136c565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60f087901c60028110610b02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107af565b8061ffff16600003610bf7576000610b53878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250611445915050565b600081815260cb602052604090205490915060ff1615610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107af565b505b6000610c3d898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146492505050565b9050610c47611487565b15610c7f57853414610c5b57610c5b611b85565b600081815260ce602052604090205460ff1615610c7a57610c7a611b85565b610dd1565b3415610d33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107af565b600081815260ce602052604090205460ff16610dd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107af565b610dda8761157d565b15610e8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107af565b600081815260cb602052604090205460ff1615610f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107af565b610f4d85610f3e611388619c40611b59565b67ffffffffffffffff166115c3565b1580610f73575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561108c57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b50506112c5565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061111d88619c405a6110e09190611bb4565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115e192505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111b457600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112c1565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b5050505b50505050505050565b905090565b60f9546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611334908890839089906000908990600401611bcb565b6000604051808303818588803b15801561134d57600080fd5b505af1158015611361573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107af565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611453858585856115fb565b805190602001209050949350505050565b6000611474878787878787611694565b8051906020012090509695505050505050565b60f95460009073ffffffffffffffffffffffffffffffffffffffff16331480156112ce575060f954604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691639bf62d829160048083019260209291908290030181865afa15801561153d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115619190611c23565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff82163014806115bd575060f95473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116149493929190611c40565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60608686868686866040516024016116b196959493929190611c8a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461175557600080fd5b50565b60008083601f84011261176a57600080fd5b50813567ffffffffffffffff81111561178257600080fd5b60208301915083602082850101111561179a57600080fd5b9250929050565b803563ffffffff811681146117b557600080fd5b919050565b600080600080606085870312156117d057600080fd5b84356117db81611733565b9350602085013567ffffffffffffffff8111156117f757600080fd5b61180387828801611758565b90945092506118169050604086016117a1565b905092959194509250565b6000815180845260005b818110156118475760208185018101518683018201520161182b565b81811115611859576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061189f6020830184611821565b9392505050565b6000602082840312156118b857600080fd5b5035919050565b6000806000604084860312156118d457600080fd5b833567ffffffffffffffff8111156118eb57600080fd5b6118f786828701611758565b909450925061190a9050602085016117a1565b90509250925092565b60006020828403121561192557600080fd5b813561189f81611733565b600080600080600080600060c0888a03121561194b57600080fd5b87359650602088013561195d81611733565b9550604088013561196d81611733565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561199757600080fd5b6119a38a828b01611758565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611a5160c0830184866119b6565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611a8e6080830186886119b6565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611b0257611b02611aac565b02949350505050565b600067ffffffffffffffff80841680611b4d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b7c57611b7c611aac565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611bc657611bc6611aac565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611c1860a0830184611821565b979650505050505050565b600060208284031215611c3557600080fd5b815161189f81611733565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611c796080830185611821565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611cd560c0830184611821565b9897505050505050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "baseGas(bytes,uint32)": { - "params": { - "_message": "Message to compute the amount of required gas for.", - "_minGasLimit": "Minimum desired gas limit when message goes to target." - }, - "returns": { - "_0": "Amount of gas required to guarantee message receipt." - } - }, - "initialize(address)": { - "params": { - "_portal": "Address of the OptimismPortal contract on this network." - } - }, - "messageNonce()": { - "returns": { - "_0": "Nonce of the next message to be sent, with added message version." - } - }, - "relayMessage(uint256,address,address,uint256,uint256,bytes)": { - "params": { - "_message": "Message to send to the target.", - "_minGasLimit": "Minimum amount of gas that the message can be executed with.", - "_nonce": "Nonce of the message being relayed.", - "_sender": "Address of the user who sent the message.", - "_target": "Address that the message is targeted at.", - "_value": "ETH value to send with the message." - } - }, - "sendMessage(address,bytes,uint32)": { - "params": { - "_message": "Message to trigger the target address with.", - "_minGasLimit": "Minimum gas limit that the message can be executed with.", - "_target": "Target contract or wallet address." - } - }, - "xDomainMessageSender()": { - "returns": { - "_0": "Address of the sender of the currently executing message on the other chain." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true}],\"type\":\"event\",\"name\":\"FailedRelayedMessage\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true}],\"type\":\"event\",\"name\":\"RelayedMessage\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\",\"indexed\":false}],\"type\":\"event\",\"name\":\"SentMessage\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false}],\"type\":\"event\",\"name\":\"SentMessageExtension1\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"PORTAL\",\"outputs\":[{\"internalType\":\"contract OptimismPortal\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_CALL_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_RESERVED_GAS\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"contract OptimismPortal\",\"name\":\"_portal\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"portal\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"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\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"relayMessage\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"sendMessage\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"baseGas(bytes,uint32)\":{\"params\":{\"_message\":\"Message to compute the amount of required gas for.\",\"_minGasLimit\":\"Minimum desired gas limit when message goes to target.\"},\"returns\":{\"_0\":\"Amount of gas required to guarantee message receipt.\"}},\"initialize(address)\":{\"params\":{\"_portal\":\"Address of the OptimismPortal contract on this network.\"}},\"messageNonce()\":{\"returns\":{\"_0\":\"Nonce of the next message to be sent, with added message version.\"}},\"relayMessage(uint256,address,address,uint256,uint256,bytes)\":{\"params\":{\"_message\":\"Message to send to the target.\",\"_minGasLimit\":\"Minimum amount of gas that the message can be executed with.\",\"_nonce\":\"Nonce of the message being relayed.\",\"_sender\":\"Address of the user who sent the message.\",\"_target\":\"Address that the message is targeted at.\",\"_value\":\"ETH value to send with the message.\"}},\"sendMessage(address,bytes,uint32)\":{\"params\":{\"_message\":\"Message to trigger the target address with.\",\"_minGasLimit\":\"Minimum gas limit that the message can be executed with.\",\"_target\":\"Target contract or wallet address.\"}},\"xDomainMessageSender()\":{\"returns\":{\"_0\":\"Address of the sender of the currently executing message on the other chain.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"MESSAGE_VERSION()\":{\"notice\":\"Current message version identifier.\"},\"MIN_GAS_CALLDATA_OVERHEAD()\":{\"notice\":\"Extra gas added to base gas for each byte of calldata in a message.\"},\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()\":{\"notice\":\"Denominator for dynamic overhead added to the base gas for a message.\"},\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR()\":{\"notice\":\"Numerator for dynamic overhead added to the base gas for a message.\"},\"OTHER_MESSENGER()\":{\"notice\":\"Address of the paired CrossDomainMessenger contract on the other chain.\"},\"PORTAL()\":{\"notice\":\"Address of the OptimismPortal. The public getter for this is legacy and will be removed in the future. Use `portal()` instead.\"},\"RELAY_CALL_OVERHEAD()\":{\"notice\":\"Gas reserved for performing the external call in `relayMessage`.\"},\"RELAY_CONSTANT_OVERHEAD()\":{\"notice\":\"Constant overhead added to the base gas for a message.\"},\"RELAY_GAS_CHECK_BUFFER()\":{\"notice\":\"Gas reserved for the execution between the `hasMinGas` check and the external call in `relayMessage`.\"},\"RELAY_RESERVED_GAS()\":{\"notice\":\"Gas reserved for finalizing the execution of `relayMessage` after the safe call.\"},\"baseGas(bytes,uint32)\":{\"notice\":\"Computes the amount of gas required to guarantee that a given message will be received on the other chain without running out of gas. Guaranteeing that a message will not run out of gas is important because this ensures that a message can always be replayed on the other chain if it fails to execute completely.\"},\"constructor\":{\"notice\":\"Constructs the L1CrossDomainMessenger contract.\"},\"failedMessages(bytes32)\":{\"notice\":\"Mapping of message hashes to a boolean if and only if the message has failed to be executed at least once. A message will not be present in this mapping if it successfully executed on the first attempt.\"},\"initialize(address)\":{\"notice\":\"Initializes the contract.\"},\"messageNonce()\":{\"notice\":\"Retrieves the next message nonce. Message version will be added to the upper two bytes of the message nonce. Message version allows us to treat messages as having different structures.\"},\"portal()\":{\"notice\":\"Getter for the OptimismPortal address.\"},\"relayMessage(uint256,address,address,uint256,uint256,bytes)\":{\"notice\":\"Relays a message that was sent by the other CrossDomainMessenger contract. Can only be executed via cross-chain call from the other messenger OR if the message was already received once and is currently being replayed.\"},\"sendMessage(address,bytes,uint32)\":{\"notice\":\"Sends a message to some target address on the other chain. Note that if the call always reverts, then the message will be unrelayable, and any ETH sent will be permanently locked. The same will occur if the target on the other chain is considered unsafe (see the _isUnsafeTarget() function).\"},\"successfulMessages(bytes32)\":{\"notice\":\"Mapping of message hashes to boolean receipt values. Note that a message will only be present in this mapping if it has successfully been relayed on this chain, and can therefore not be relayed again.\"},\"version()\":{\"notice\":\"Semantic version.\"},\"xDomainMessageSender()\":{\"notice\":\"Retrieves the address of the contract or wallet that initiated the currently executing message on the other chain. Will throw an error if there is no message currently being executed. Allows the recipient of a call to see who triggered it.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L1CrossDomainMessenger.sol\":\"L1CrossDomainMessenger\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L1CrossDomainMessenger.sol\":{\"keccak256\":\"0xe3fdf4102a94b9383f1ca917499ffeb8dd9be6317ef4ed9626a5ff44daf54461\",\"urls\":[\"bzz-raw://1c1a5f8612f0b170350e2436a64695c3e7fffd04ea1a617a64eacd4d2342a07c\",\"dweb:/ipfs/QmdoehaP6a9kyWR73LqRdqSCShiXKePwM7WJedwikvYR1w\"],\"license\":\"MIT\"},\"src/L1/L2OutputOracle.sol\":{\"keccak256\":\"0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705\",\"urls\":[\"bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc\",\"dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN\"],\"license\":\"MIT\"},\"src/L1/OptimismPortal.sol\":{\"keccak256\":\"0xdca91a921b402d82b455d7f11027514e8a16dca906cf820b3afffe271beb8a13\",\"urls\":[\"bzz-raw://688912b9d6005af8395d5c2eb5c4e3367a8be7b50ea97c34fc6a7ac0e2d8fd6a\",\"dweb:/ipfs/QmNPJDwHpNmJ5VPWAJB8muRpZxYeySZDVoV1TMVN7roijJ\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L1/SystemConfig.sol\":{\"keccak256\":\"0x4bbbc7868e948c44f29285a69383e93251a0c330a67929fb72def01cec060d4e\",\"urls\":[\"bzz-raw://1e7ea2f8b3d49bee9c753f107ede6eda93b2cc0e34d0643fa14ebbb26c19e71b\",\"dweb:/ipfs/QmRP81F8FRVXVZs6u2f2poEPDnbFZhNwNYxHgCVEhGpEmB\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Bytes.sol\":{\"keccak256\":\"0x827f47d123b0fdf3b08816d5b33831811704dbf4e554e53f2269354f6bba8859\",\"urls\":[\"bzz-raw://3137ac7204d30a245a8b0d67aa6da5286f1bd8c90379daab561f84963b6db782\",\"dweb:/ipfs/QmWRhisw3axJK833gUScs23ETh2MLFbVzzqzYVMKSDN3S9\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/Predeploys.sol\":{\"keccak256\":\"0x5af3a849f68f7c9108858ebac5c769da8f1c0309b5c0cb42eb5cbb15e3fe6058\",\"urls\":[\"bzz-raw://6ffe76429a96d274577be66627eddad5cd05ad36d0cb6b9b3c3f9fa8a609dd7e\",\"dweb:/ipfs/QmVhWnB7Avg684TEQ9BExWqSN1YfLehUTWoqpjymeQEQHm\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x9ba74a3b0a11693e622380807d213d5d1250d974e18b2cd768da9cbe719a6778\",\"urls\":[\"bzz-raw://0808d721ed9e05707526ee134faa051d707a95ee6b8bd6e0b1972275da8e5723\",\"dweb:/ipfs/QmcTTPu9xgckfWdbFUAcr2RAgk3J6vzyR4FpV798TjFMeN\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xf8ba770ee6666e73ae43184c700e9c704b2c4ace71f9e3c2227ddc11a8148b4c\",\"urls\":[\"bzz-raw://4702ccee1fe44aea3ee01d59e6152eb755da083f786f00947fec4437c064fe74\",\"dweb:/ipfs/QmQjFj5J7hrEM1dxJjFszzW2Cs7g7eMhYNBXonF2DXBstE\"],\"license\":\"MIT\"},\"src/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0xeaff8315cfd21197bc6bc859c2decf5d4f4838c9c357c502cdf2b1eac863d288\",\"urls\":[\"bzz-raw://79dcdcaa560aea51d138da4f5dc553a1808b6de090b2dc1629f18375edbff681\",\"dweb:/ipfs/QmbE4pUPhf5fLKW4W6cEjhQs55gEDvHmbmoBqkW1yz3bnw\"],\"license\":\"MIT\"},\"src/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x4302ae78bcafde2737d4048bbf8fdb3dd4cd7254c015b91dfa14fdaafd412f4a\",\"urls\":[\"bzz-raw://78d3d1823ad4e1fba15921a0a361b452c85d111e2d53cbbed11a8632782ea8f3\",\"dweb:/ipfs/QmVc2rTRpn7g7WAUxDShSuy6dY5zmtbJ7hHC6sT9PcD3Gj\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"],\"license\":\"Apache-2.0\"}},\"version\":1}", - "numDeployments": 2, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 75013, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_0_0_20", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 29536, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "_initialized", - "offset": 20, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 29539, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "_initializing", - "offset": 21, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 75020, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_1_0_1600", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 75023, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_51_0_20", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 75028, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_52_0_1568", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 75031, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_101_0_1", - "offset": 0, - "slot": "101", - "type": "t_bool" - }, - { - "astId": 75036, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_102_0_1568", - "offset": 0, - "slot": "102", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 75039, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_151_0_32", - "offset": 0, - "slot": "151", - "type": "t_uint256" - }, - { - "astId": 75044, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_152_0_1568", - "offset": 0, - "slot": "152", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 75049, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_201_0_32", - "offset": 0, - "slot": "201", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75054, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_202_0_32", - "offset": 0, - "slot": "202", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75102, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "successfulMessages", - "offset": 0, - "slot": "203", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75105, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "xDomainMsgSender", - "offset": 0, - "slot": "204", - "type": "t_address" - }, - { - "astId": 75108, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "msgNonce", - "offset": 0, - "slot": "205", - "type": "t_uint240" - }, - { - "astId": 75113, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "failedMessages", - "offset": 0, - "slot": "206", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75118, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "__gap", - "offset": 0, - "slot": "207", - "type": "t_array(t_uint256)42_storage" - }, - { - "astId": 58481, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "PORTAL", - "offset": 0, - "slot": "249", - "type": "t_contract(OptimismPortal)60545" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)42_storage": { - "encoding": "inplace", - "label": "uint256[42]", - "numberOfBytes": "1344", - "base": "t_uint256" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_contract(OptimismPortal)60545": { - "encoding": "inplace", - "label": "contract OptimismPortal", - "numberOfBytes": "20" - }, - "t_mapping(t_bytes32,t_bool)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_uint240": { - "encoding": "inplace", - "label": "uint240", - "numberOfBytes": "30" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x526e8310c1c7d4278246e50dd7ecf7c6677e7c4c0be7a130985fa52806851526", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSAGE_VERSION()": { - "notice": "Current message version identifier." - }, - "MIN_GAS_CALLDATA_OVERHEAD()": { - "notice": "Extra gas added to base gas for each byte of calldata in a message." - }, - "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()": { - "notice": "Denominator for dynamic overhead added to the base gas for a message." - }, - "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR()": { - "notice": "Numerator for dynamic overhead added to the base gas for a message." - }, - "OTHER_MESSENGER()": { - "notice": "Address of the paired CrossDomainMessenger contract on the other chain." - }, - "PORTAL()": { - "notice": "Address of the OptimismPortal. The public getter for this is legacy and will be removed in the future. Use `portal()` instead." - }, - "RELAY_CALL_OVERHEAD()": { - "notice": "Gas reserved for performing the external call in `relayMessage`." - }, - "RELAY_CONSTANT_OVERHEAD()": { - "notice": "Constant overhead added to the base gas for a message." - }, - "RELAY_GAS_CHECK_BUFFER()": { - "notice": "Gas reserved for the execution between the `hasMinGas` check and the external call in `relayMessage`." - }, - "RELAY_RESERVED_GAS()": { - "notice": "Gas reserved for finalizing the execution of `relayMessage` after the safe call." - }, - "baseGas(bytes,uint32)": { - "notice": "Computes the amount of gas required to guarantee that a given message will be received on the other chain without running out of gas. Guaranteeing that a message will not run out of gas is important because this ensures that a message can always be replayed on the other chain if it fails to execute completely." - }, - "constructor": { - "notice": "Constructs the L1CrossDomainMessenger contract." - }, - "failedMessages(bytes32)": { - "notice": "Mapping of message hashes to a boolean if and only if the message has failed to be executed at least once. A message will not be present in this mapping if it successfully executed on the first attempt." - }, - "initialize(address)": { - "notice": "Initializes the contract." - }, - "messageNonce()": { - "notice": "Retrieves the next message nonce. Message version will be added to the upper two bytes of the message nonce. Message version allows us to treat messages as having different structures." - }, - "portal()": { - "notice": "Getter for the OptimismPortal address." - }, - "relayMessage(uint256,address,address,uint256,uint256,bytes)": { - "notice": "Relays a message that was sent by the other CrossDomainMessenger contract. Can only be executed via cross-chain call from the other messenger OR if the message was already received once and is currently being replayed." - }, - "sendMessage(address,bytes,uint32)": { - "notice": "Sends a message to some target address on the other chain. Note that if the call always reverts, then the message will be unrelayable, and any ETH sent will be permanently locked. The same will occur if the target on the other chain is considered unsafe (see the _isUnsafeTarget() function)." - }, - "successfulMessages(bytes32)": { - "notice": "Mapping of message hashes to boolean receipt values. Note that a message will only be present in this mapping if it has successfully been relayed on this chain, and can therefore not be relayed again." - }, - "version()": { - "notice": "Semantic version." - }, - "xDomainMessageSender()": { - "notice": "Retrieves the address of the contract or wallet that initiated the currently executing message on the other chain. Will throw an error if there is no message currently being executed. Allows the recipient of a call to see who triggered it." - } - }, - "events": { - "FailedRelayedMessage(bytes32)": { - "notice": "Emitted whenever a message fails to be relayed on this chain." - }, - "RelayedMessage(bytes32)": { - "notice": "Emitted whenever a message is successfully relayed on this chain." - }, - "SentMessage(address,address,bytes,uint256,uint256)": { - "notice": "Emitted whenever a message is sent to the other chain." - }, - "SentMessageExtension1(address,uint256)": { - "notice": "Additional event data to emit, required as of Bedrock. Cannot be merged with the SentMessage event without breaking the ABI of this contract, this is good enough." - } - }, - "notice": "The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible for sending and receiving data on the L1 side. Users are encouraged to use this interface instead of interacting with lower-level contracts directly." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/L1CrossDomainMessengerProxy.json b/packages/contracts-bedrock/deployments/mainnet/L1CrossDomainMessengerProxy.json deleted file mode 100644 index 363133f4ec6c..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/L1CrossDomainMessengerProxy.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "address": "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_libAddressManager", - "type": "address" - }, - { - "internalType": "string", - "name": "_implementationName", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "stateMutability": "payable", - "type": "fallback" - } - ], - "transactionHash": "0x3061bc0332ef45e8809cee450c3c487eba2520084c71ff38da85459aee6b9a1d", - "receipt": { - "to": null, - "from": "0x9996571372066A1545D3435C6935e3F9593A7eF5", - "contractAddress": "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1", - "transactionIndex": 153, - "gasUsed": "225024", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xd4ac3db2a7b6711dabac13ef84b398e86c647e5a24f0ffdd3458b3c66ab6cef1", - "transactionHash": "0x3061bc0332ef45e8809cee450c3c487eba2520084c71ff38da85459aee6b9a1d", - "logs": [], - "blockNumber": 12686757, - "cumulativeGasUsed": "11815865", - "status": 1, - "byzantium": true - }, - "args": [ - "0xdE1FCfB0851916CA5101820A69b13a4E276bd81F", - "OVM_L1CrossDomainMessenger" - ], - "solcInputHash": "ef3f334bac4d7e77d91b457a0d89ab0a", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_implementationName\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_implementationName\":\"implementationName of the contract to proxy to.\",\"_libAddressManager\":\"Address of the Lib_AddressManager.\"}}},\"title\":\"Lib_ResolvedDelegateProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol\":\"Lib_ResolvedDelegateProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x15e2d5bd4c28a88548074c54d220e8086f638a71ed07e6b3ba5a70066fcf458d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(\\n string indexed _name,\\n address _newAddress,\\n address _oldAddress\\n );\\n\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping (bytes32 => address) private addresses;\\n\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(\\n string memory _name,\\n address _address\\n )\\n external\\n onlyOwner\\n {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(\\n _name,\\n _address,\\n oldAddress\\n );\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(\\n string memory _name\\n )\\n external\\n view\\n returns (\\n address\\n )\\n {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(\\n string memory _name\\n )\\n internal\\n pure\\n returns (\\n bytes32\\n )\\n {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0x636defb785a5c6650d101def6790d9104724cc7570e0d875138624d069eed257\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_ResolvedDelegateProxy\\n */\\ncontract Lib_ResolvedDelegateProxy {\\n\\n /*************\\n * Variables *\\n *************/\\n\\n // Using mappings to store fields to avoid overwriting storage slots in the\\n // implementation contract. For example, instead of storing these fields at\\n // storage slot `0` & `1`, they are stored at `keccak256(key + slot)`.\\n // See: https://solidity.readthedocs.io/en/v0.7.0/internals/layout_in_storage.html\\n // NOTE: Do not use this code in your own contract system.\\n // There is a known flaw in this contract, and we will remove it from the repository\\n // in the near future. Due to the very limited way that we are using it, this flaw is\\n // not an issue in our system.\\n mapping (address => string) private implementationName;\\n mapping (address => Lib_AddressManager) private addressManager;\\n\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Lib_AddressManager.\\n * @param _implementationName implementationName of the contract to proxy to.\\n */\\n constructor(\\n address _libAddressManager,\\n string memory _implementationName\\n ) {\\n addressManager[address(this)] = Lib_AddressManager(_libAddressManager);\\n implementationName[address(this)] = _implementationName;\\n }\\n\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n fallback()\\n external\\n payable\\n {\\n address target = addressManager[address(this)].getAddress(\\n (implementationName[address(this)])\\n );\\n\\n require(\\n target != address(0),\\n \\\"Target address must be initialized.\\\"\\n );\\n\\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\\n\\n if (success == true) {\\n assembly {\\n return(add(returndata, 0x20), mload(returndata))\\n }\\n } else {\\n assembly {\\n revert(add(returndata, 0x20), mload(returndata))\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfaecb051b37f1d87d588cafb17a575723cbdf7c3c2079772110f33e747e05027\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506040516104083803806104088339818101604052604081101561003357600080fd5b81516020830180516040519294929383019291908464010000000082111561005a57600080fd5b90830190602082018581111561006f57600080fd5b825164010000000081118282018810171561008957600080fd5b82525081516020918201929091019080838360005b838110156100b657818101518382015260200161009e565b50505050905090810190601f1680156100e35780820380516001836020036101000a031916815260200191505b5060409081523060009081526001602090815282822080546001600160a01b0319166001600160a01b038a16179055818152919020855161012c95509093509085019150610134565b5050506101d5565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261016a57600085556101b0565b82601f1061018357805160ff19168380011785556101b0565b828001600101855582156101b0579182015b828111156101b0578251825591602001919060010190610195565b506101bc9291506101c0565b5090565b5b808211156101bc57600081556001016101c1565b610224806101e46000396000f3fe60806040818152306000908152600160208181528383205483825293832063bf40fac160e01b909552608490815284546002610100938216159390930260001901169190910460a481905291936001600160a01b039093169263bf40fac192909190819060c490849080156100b55780601f1061008a576101008083540402835291602001916100b5565b820191906000526020600020905b81548152906001019060200180831161009857829003601f168201915b50509250505060206040518083038186803b1580156100d357600080fd5b505afa1580156100e7573d6000803e3d6000fd5b505050506040513d60208110156100fd57600080fd5b505190506001600160a01b0381166101465760405162461bcd60e51b81526004018080602001828103825260238152602001806101cc6023913960400191505060405180910390fd5b600080826001600160a01b03166000366040518083838082843760405192019450600093509091505080830381855af49150503d80600081146101a5576040519150601f19603f3d011682016040523d82523d6000602084013e6101aa565b606091505b509092509050600182151514156101c357805160208201f35b805160208201fdfe5461726765742061646472657373206d75737420626520696e697469616c697a65642ea2646970667358221220d96dd78b72a44c11bfa8efb98d29ee53776a02c67052599da176325fcbf95b6464736f6c63430007060033", - "deployedBytecode": "0x60806040818152306000908152600160208181528383205483825293832063bf40fac160e01b909552608490815284546002610100938216159390930260001901169190910460a481905291936001600160a01b039093169263bf40fac192909190819060c490849080156100b55780601f1061008a576101008083540402835291602001916100b5565b820191906000526020600020905b81548152906001019060200180831161009857829003601f168201915b50509250505060206040518083038186803b1580156100d357600080fd5b505afa1580156100e7573d6000803e3d6000fd5b505050506040513d60208110156100fd57600080fd5b505190506001600160a01b0381166101465760405162461bcd60e51b81526004018080602001828103825260238152602001806101cc6023913960400191505060405180910390fd5b600080826001600160a01b03166000366040518083838082843760405192019450600093509091505080830381855af49150503d80600081146101a5576040519150601f19603f3d011682016040523d82523d6000602084013e6101aa565b606091505b509092509050600182151514156101c357805160208201f35b805160208201fdfe5461726765742061646472657373206d75737420626520696e697469616c697a65642ea2646970667358221220d96dd78b72a44c11bfa8efb98d29ee53776a02c67052599da176325fcbf95b6464736f6c63430007060033", - "devdoc": { - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_implementationName": "implementationName of the contract to proxy to.", - "_libAddressManager": "Address of the Lib_AddressManager." - } - } - }, - "title": "Lib_ResolvedDelegateProxy", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 15340, - "contract": "contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol:Lib_ResolvedDelegateProxy", - "label": "implementationName", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_address,t_string_storage)" - }, - { - "astId": 15344, - "contract": "contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol:Lib_ResolvedDelegateProxy", - "label": "addressManager", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_address,t_contract(Lib_AddressManager)15296)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_contract(Lib_AddressManager)15296": { - "encoding": "inplace", - "label": "contract Lib_AddressManager", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_contract(Lib_AddressManager)15296)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => contract Lib_AddressManager)", - "numberOfBytes": "32", - "value": "t_contract(Lib_AddressManager)15296" - }, - "t_mapping(t_address,t_string_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => string)", - "numberOfBytes": "32", - "value": "t_string_storage" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/L1ERC721Bridge.json b/packages/contracts-bedrock/deployments/mainnet/L1ERC721Bridge.json deleted file mode 100644 index b9af96e9a073..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/L1ERC721Bridge.json +++ /dev/null @@ -1,525 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC721BridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC721BridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "inputs": [], - "name": "MESSENGER", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_BRIDGE", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC721To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "deposits", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "_messenger", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "messenger", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "otherBridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x806C2d0d2BDDFf9279CB2A8722F9117f0b0aDE73", - "args": [], - "bytecode": "0x60a060405234801561001057600080fd5b50734200000000000000000000000000000000000014610034565b60405180910390fd5b6001600160a01b031660805261004a600061004f565b6101cb565b600054600390610100900460ff16158015610071575060005460ff8083169116105b6100d45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161002b565b6000805461ffff191660ff8316176101001790556100f182610136565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054610100900460ff166101a15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161002b565b600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6080516112116101fb600039600081816101cd0152818161023b015281816103350152610bf101526112116000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80637f46ddb211610076578063aa5574521161005b578063aa55745214610213578063c4d66de814610226578063c89701a21461023957600080fd5b80637f46ddb2146101c8578063927ede2d146101ef57600080fd5b806354fd4d50116100a757806354fd4d50146101285780635d93a3fc14610171578063761f4493146101b557600080fd5b80633687011a146100c35780633cb747bf146100d8575b600080fd5b6100d66100d1366004610e47565b61025f565b005b6000546100fe9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101646040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b60405161011f9190610f35565b6101a561017f366004610f4f565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b604051901515815260200161011f565b6100d66101c3366004610f90565b61030b565b6100fe7f000000000000000000000000000000000000000000000000000000000000000081565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166100fe565b6100d6610221366004611028565b610776565b6100d661023436600461109f565b610832565b7f00000000000000000000000000000000000000000000000000000000000000006100fe565b333b156102f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b610303868633338888888861097c565b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314801561041357507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fb91906110bc565b73ffffffffffffffffffffffffffffffffffffffff16145b61049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f74686572206272696467650060648201526084016102ea565b3073ffffffffffffffffffffffffffffffffffffffff881603610544576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff161515600114610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c31204272696467650000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156106d357600080fd5b505af11580156106e7573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107659493929190611122565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f7420626520616464726573732830290000000000000000000000000000000060648201526084016102ea565b610829878733888888888861097c565b50505050505050565b600054600390610100900460ff16158015610854575060005460ff8083169116105b6108e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016102ea565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561091a82610cdc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b73ffffffffffffffffffffffffffffffffffffffff8716610a1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f74206265206164647265737328302900000000000000000000000000000060648201526084016102ea565b600063761f449360e01b888a8989898888604051602401610a469796959493929190611162565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610b8657600080fd5b505af1158015610b9a573d6000803e3d6000fd5b50506000546040517f3dbb202b0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169250633dbb202b9150610c1d907f000000000000000000000000000000000000000000000000000000000000000090859089906004016111bf565b600060405180830381600087803b158015610c3757600080fd5b505af1158015610c4b573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610cc99493929190611122565b60405180910390a4505050505050505050565b600054610100900460ff16610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ea565b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610de257600080fd5b50565b803563ffffffff81168114610df957600080fd5b919050565b60008083601f840112610e1057600080fd5b50813567ffffffffffffffff811115610e2857600080fd5b602083019150836020828501011115610e4057600080fd5b9250929050565b60008060008060008060a08789031215610e6057600080fd5b8635610e6b81610dc0565b95506020870135610e7b81610dc0565b945060408701359350610e9060608801610de5565b9250608087013567ffffffffffffffff811115610eac57600080fd5b610eb889828a01610dfe565b979a9699509497509295939492505050565b6000815180845260005b81811015610ef057602081850181015186830182015201610ed4565b81811115610f02576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f486020830184610eca565b9392505050565b600080600060608486031215610f6457600080fd5b8335610f6f81610dc0565b92506020840135610f7f81610dc0565b929592945050506040919091013590565b600080600080600080600060c0888a031215610fab57600080fd5b8735610fb681610dc0565b96506020880135610fc681610dc0565b95506040880135610fd681610dc0565b94506060880135610fe681610dc0565b93506080880135925060a088013567ffffffffffffffff81111561100957600080fd5b6110158a828b01610dfe565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561104357600080fd5b873561104e81610dc0565b9650602088013561105e81610dc0565b9550604088013561106e81610dc0565b94506060880135935061108360808901610de5565b925060a088013567ffffffffffffffff81111561100957600080fd5b6000602082840312156110b157600080fd5b8135610f4881610dc0565b6000602082840312156110ce57600080fd5b8151610f4881610dc0565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006111586060830184866110d9565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a08301526111b260c0830184866110d9565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006111ee6060830185610eca565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c80637f46ddb211610076578063aa5574521161005b578063aa55745214610213578063c4d66de814610226578063c89701a21461023957600080fd5b80637f46ddb2146101c8578063927ede2d146101ef57600080fd5b806354fd4d50116100a757806354fd4d50146101285780635d93a3fc14610171578063761f4493146101b557600080fd5b80633687011a146100c35780633cb747bf146100d8575b600080fd5b6100d66100d1366004610e47565b61025f565b005b6000546100fe9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101646040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b60405161011f9190610f35565b6101a561017f366004610f4f565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b604051901515815260200161011f565b6100d66101c3366004610f90565b61030b565b6100fe7f000000000000000000000000000000000000000000000000000000000000000081565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166100fe565b6100d6610221366004611028565b610776565b6100d661023436600461109f565b610832565b7f00000000000000000000000000000000000000000000000000000000000000006100fe565b333b156102f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b610303868633338888888861097c565b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314801561041357507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fb91906110bc565b73ffffffffffffffffffffffffffffffffffffffff16145b61049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f74686572206272696467650060648201526084016102ea565b3073ffffffffffffffffffffffffffffffffffffffff881603610544576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff161515600114610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c31204272696467650000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156106d357600080fd5b505af11580156106e7573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107659493929190611122565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f7420626520616464726573732830290000000000000000000000000000000060648201526084016102ea565b610829878733888888888861097c565b50505050505050565b600054600390610100900460ff16158015610854575060005460ff8083169116105b6108e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016102ea565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561091a82610cdc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b73ffffffffffffffffffffffffffffffffffffffff8716610a1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f74206265206164647265737328302900000000000000000000000000000060648201526084016102ea565b600063761f449360e01b888a8989898888604051602401610a469796959493929190611162565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610b8657600080fd5b505af1158015610b9a573d6000803e3d6000fd5b50506000546040517f3dbb202b0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169250633dbb202b9150610c1d907f000000000000000000000000000000000000000000000000000000000000000090859089906004016111bf565b600060405180830381600087803b158015610c3757600080fd5b505af1158015610c4b573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610cc99493929190611122565b60405180910390a4505050505050505050565b600054610100900460ff16610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ea565b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610de257600080fd5b50565b803563ffffffff81168114610df957600080fd5b919050565b60008083601f840112610e1057600080fd5b50813567ffffffffffffffff811115610e2857600080fd5b602083019150836020828501011115610e4057600080fd5b9250929050565b60008060008060008060a08789031215610e6057600080fd5b8635610e6b81610dc0565b95506020870135610e7b81610dc0565b945060408701359350610e9060608801610de5565b9250608087013567ffffffffffffffff811115610eac57600080fd5b610eb889828a01610dfe565b979a9699509497509295939492505050565b6000815180845260005b81811015610ef057602081850181015186830182015201610ed4565b81811115610f02576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f486020830184610eca565b9392505050565b600080600060608486031215610f6457600080fd5b8335610f6f81610dc0565b92506020840135610f7f81610dc0565b929592945050506040919091013590565b600080600080600080600060c0888a031215610fab57600080fd5b8735610fb681610dc0565b96506020880135610fc681610dc0565b95506040880135610fd681610dc0565b94506060880135610fe681610dc0565b93506080880135925060a088013567ffffffffffffffff81111561100957600080fd5b6110158a828b01610dfe565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561104357600080fd5b873561104e81610dc0565b9650602088013561105e81610dc0565b9550604088013561106e81610dc0565b94506060880135935061108360808901610de5565b925060a088013567ffffffffffffffff81111561100957600080fd5b6000602082840312156110b157600080fd5b8135610f4881610dc0565b6000602082840312156110ce57600080fd5b8151610f4881610dc0565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006111586060830184866110d9565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a08301526111b260c0830184866110d9565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006111ee6060830185610eca565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "bridgeERC721(address,address,uint256,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.", - "_localToken": "Address of the ERC721 on this domain.", - "_minGasLimit": "Minimum gas limit for the bridge message on the other domain.", - "_remoteToken": "Address of the ERC721 on the remote domain.", - "_tokenId": "Token ID to bridge." - } - }, - "bridgeERC721To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.", - "_localToken": "Address of the ERC721 on this domain.", - "_minGasLimit": "Minimum gas limit for the bridge message on the other domain.", - "_remoteToken": "Address of the ERC721 on the remote domain.", - "_to": "Address to receive the token on the other domain.", - "_tokenId": "Token ID to bridge." - } - }, - "finalizeBridgeERC721(address,address,address,address,uint256,bytes)": { - "params": { - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_from": "Address that triggered the bridge on the other domain.", - "_localToken": "Address of the ERC721 token on this domain.", - "_remoteToken": "Address of the ERC721 token on the other domain.", - "_to": "Address to receive the token on this domain.", - "_tokenId": "ID of the token being deposited." - } - }, - "initialize(address)": { - "params": { - "_messenger": "Address of the CrossDomainMessenger on this network." - } - }, - "otherBridge()": { - "returns": { - "_0": "Address of the bridge on the other network." - } - } - }, - "title": "L1ERC721Bridge" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC721BridgeFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC721BridgeInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC721\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC721To\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeBridgeERC721\"},{\"inputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"_messenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bridgeERC721(address,address,uint256,uint32,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.\",\"_localToken\":\"Address of the ERC721 on this domain.\",\"_minGasLimit\":\"Minimum gas limit for the bridge message on the other domain.\",\"_remoteToken\":\"Address of the ERC721 on the remote domain.\",\"_tokenId\":\"Token ID to bridge.\"}},\"bridgeERC721To(address,address,address,uint256,uint32,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.\",\"_localToken\":\"Address of the ERC721 on this domain.\",\"_minGasLimit\":\"Minimum gas limit for the bridge message on the other domain.\",\"_remoteToken\":\"Address of the ERC721 on the remote domain.\",\"_to\":\"Address to receive the token on the other domain.\",\"_tokenId\":\"Token ID to bridge.\"}},\"finalizeBridgeERC721(address,address,address,address,uint256,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_from\":\"Address that triggered the bridge on the other domain.\",\"_localToken\":\"Address of the ERC721 token on this domain.\",\"_remoteToken\":\"Address of the ERC721 token on the other domain.\",\"_to\":\"Address to receive the token on this domain.\",\"_tokenId\":\"ID of the token being deposited.\"}},\"initialize(address)\":{\"params\":{\"_messenger\":\"Address of the CrossDomainMessenger on this network.\"}},\"otherBridge()\":{\"returns\":{\"_0\":\"Address of the bridge on the other network.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"MESSENGER()\":{\"notice\":\"Getter for messenger contract.\"},\"OTHER_BRIDGE()\":{\"notice\":\"Address of the bridge on the other network.\"},\"bridgeERC721(address,address,uint256,uint32,bytes)\":{\"notice\":\"Initiates a bridge of an NFT to the caller's account on the other chain. Note that this function can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` function after ensuring that the recipient address on the remote chain exists. Also note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\"},\"bridgeERC721To(address,address,address,uint256,uint32,bytes)\":{\"notice\":\"Initiates a bridge of an NFT to some recipient's account on the other chain. Note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\"},\"constructor\":{\"notice\":\"Constructs the contract.\"},\"deposits(address,address,uint256)\":{\"notice\":\"Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token by ID was deposited for a given L2 token.\"},\"finalizeBridgeERC721(address,address,address,address,uint256,bytes)\":{\"notice\":\"Completes an ERC721 bridge from the other domain and sends the ERC721 token to the recipient on this domain.\"},\"initialize(address)\":{\"notice\":\"Initializes the contract.\"},\"messenger()\":{\"notice\":\"Messenger contract on this domain.\"},\"otherBridge()\":{\"notice\":\"Getter for other bridge address.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L1ERC721Bridge.sol\":\"L1ERC721Bridge\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"urls\":[\"bzz-raw://20a97f891d06f0fe91560ea1a142aaa26fdd22bed1b51606b7d48f670deeb50f\",\"dweb:/ipfs/QmTbCtZKChpaX5H2iRiTDMcSz29GSLCpTCDgJpcMR4wg8x\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"urls\":[\"bzz-raw://26fef835622b46a5ba08b3ef6b46a22e94b5f285d0f0fb66b703bd30217d2c34\",\"dweb:/ipfs/QmZ548qdwfL1qF7aXz3xh1GCdTiST81kGGuKRqVUfYmPZR\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L1ERC721Bridge.sol\":{\"keccak256\":\"0xfcbde0f08cd5601aac88a40ee9224f59af9c7f5c404d67f37cbb0abd5f298b1f\",\"urls\":[\"bzz-raw://f1d26441cb269c4e1d45b2739342c016d8ec461dcb99c30da6e649e58d3b376d\",\"dweb:/ipfs/QmU4sYC5ZBGWtgwV2isLp8pXhvNum34d6Fsdsj7UNLEcUw\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L2/L2ERC721Bridge.sol\":{\"keccak256\":\"0xcc0de3ee4e726fe4a0a52a0684fc30454a49190d600c7cbeade798ae020d70f6\",\"urls\":[\"bzz-raw://bfa81e6c23f59237794bce97ad55cca091980c3db50bb295f836ab20cb58e4c8\",\"dweb:/ipfs/QmSpfckbZeoCEAASqxWdFm7t8q6Rqkqwk2jQFSCKEBXEVs\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/Predeploys.sol\":{\"keccak256\":\"0x5af3a849f68f7c9108858ebac5c769da8f1c0309b5c0cb42eb5cbb15e3fe6058\",\"urls\":[\"bzz-raw://6ffe76429a96d274577be66627eddad5cd05ad36d0cb6b9b3c3f9fa8a609dd7e\",\"dweb:/ipfs/QmVhWnB7Avg684TEQ9BExWqSN1YfLehUTWoqpjymeQEQHm\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x4302ae78bcafde2737d4048bbf8fdb3dd4cd7254c015b91dfa14fdaafd412f4a\",\"urls\":[\"bzz-raw://78d3d1823ad4e1fba15921a0a361b452c85d111e2d53cbbed11a8632782ea8f3\",\"dweb:/ipfs/QmVc2rTRpn7g7WAUxDShSuy6dY5zmtbJ7hHC6sT9PcD3Gj\"],\"license\":\"MIT\"},\"src/universal/ERC721Bridge.sol\":{\"keccak256\":\"0x1aba1c039fa759d7d081e0d60c5d742e8d3147f0eda19af5c17cf291b4f53213\",\"urls\":[\"bzz-raw://a3581c48036bf901da4dd823f4b2fc65870414a116b32ed042d89778a2027e3f\",\"dweb:/ipfs/QmVqTCMR6NroWCQzjc1vkznHp1XbNFSYXNDgrvXUDEuZoA\"],\"license\":\"MIT\"},\"src/universal/IOptimismMintableERC721.sol\":{\"keccak256\":\"0xb3a65b067e67a9e1fa0493401c8d247970377c6725eba4e7b02ce8099c4f4f52\",\"urls\":[\"bzz-raw://86bb6864027560ade2f4ced6a6e34213cbff8002977dc365377e5a0b473cf17b\",\"dweb:/ipfs/QmQvjtodTK27as1g1PzsYk9NyJJ3X6a6251o1vrBwx7DPT\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 2, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 75549, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "messenger", - "offset": 2, - "slot": "0", - "type": "t_contract(CrossDomainMessenger)75534" - }, - { - "astId": 75557, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)48_storage" - }, - { - "astId": 58637, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "deposits", - "offset": 0, - "slot": "49", - "type": "t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint256,t_bool)))" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)48_storage": { - "encoding": "inplace", - "label": "uint256[48]", - "numberOfBytes": "1536", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(CrossDomainMessenger)75534": { - "encoding": "inplace", - "label": "contract CrossDomainMessenger", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint256,t_bool)))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => mapping(uint256 => bool)))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_mapping(t_uint256,t_bool))" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_bool))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(uint256 => bool))", - "numberOfBytes": "32", - "value": "t_mapping(t_uint256,t_bool)" - }, - "t_mapping(t_uint256,t_bool)": { - "encoding": "mapping", - "key": "t_uint256", - "label": "mapping(uint256 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0xd3deadba9121b516e8005639f785bf7d6db2d8089880d88878e9641cc564d313", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSENGER()": { - "notice": "Getter for messenger contract." - }, - "OTHER_BRIDGE()": { - "notice": "Address of the bridge on the other network." - }, - "bridgeERC721(address,address,uint256,uint32,bytes)": { - "notice": "Initiates a bridge of an NFT to the caller's account on the other chain. Note that this function can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` function after ensuring that the recipient address on the remote chain exists. Also note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "bridgeERC721To(address,address,address,uint256,uint32,bytes)": { - "notice": "Initiates a bridge of an NFT to some recipient's account on the other chain. Note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "constructor": { - "notice": "Constructs the contract." - }, - "deposits(address,address,uint256)": { - "notice": "Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token by ID was deposited for a given L2 token." - }, - "finalizeBridgeERC721(address,address,address,address,uint256,bytes)": { - "notice": "Completes an ERC721 bridge from the other domain and sends the ERC721 token to the recipient on this domain." - }, - "initialize(address)": { - "notice": "Initializes the contract." - }, - "messenger()": { - "notice": "Messenger contract on this domain." - }, - "otherBridge()": { - "notice": "Getter for other bridge address." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ERC721BridgeFinalized(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC721 bridge from the other network is finalized." - }, - "ERC721BridgeInitiated(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC721 bridge to the other network is initiated." - } - }, - "notice": "The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract acts as an escrow for ERC721 tokens deposited into L2." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/L1ERC721BridgeProxy.json b/packages/contracts-bedrock/deployments/mainnet/L1ERC721BridgeProxy.json deleted file mode 100644 index 6be5dc01aedd..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/L1ERC721BridgeProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x5a7749f83b81B301cAb5f48EB8516B986DAef23D", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x7583d011cf1593fb1ffc79b097b0a365192c87dfdccbf860e1ad3f1425a305ef", - "receipt": { - "to": null, - "from": "0x53A6eecC2dD4795Fcc68940ddc6B4d53Bd88Bd9E", - "contractAddress": "0x5a7749f83b81B301cAb5f48EB8516B986DAef23D", - "transactionIndex": 140, - "gasUsed": "532674", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000800000000000000000000000000", - "blockHash": "0xa5c98ae09c1db0857551a9eaca6d88e1bff5f8103814795c0ed1e7863e16a6d5", - "transactionHash": "0x7583d011cf1593fb1ffc79b097b0a365192c87dfdccbf860e1ad3f1425a305ef", - "logs": [ - { - "transactionIndex": 140, - "blockNumber": 15677422, - "transactionHash": "0x7583d011cf1593fb1ffc79b097b0a365192c87dfdccbf860e1ad3f1425a305ef", - "address": "0x5a7749f83b81B301cAb5f48EB8516B986DAef23D", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053a6eecc2dd4795fcc68940ddc6b4d53bd88bd9e", - "logIndex": 251, - "blockHash": "0xa5c98ae09c1db0857551a9eaca6d88e1bff5f8103814795c0ed1e7863e16a6d5" - } - ], - "blockNumber": 15677422, - "cumulativeGasUsed": "12586381", - "status": 1, - "byzantium": true - }, - "args": [ - "0x53A6eecC2dD4795Fcc68940ddc6B4d53Bd88Bd9E" - ], - "numDeployments": 1, - "solcInputHash": "ab9b77493f35e63b7a63fb2fa8d618b4", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n external\\n payable\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() external proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() external proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/L1StandardBridge.json b/packages/contracts-bedrock/deployments/mainnet/L1StandardBridge.json deleted file mode 100644 index 03c2d8ed82bd..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/L1StandardBridge.json +++ /dev/null @@ -1,1122 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20BridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20BridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20DepositInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20WithdrawalFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHBridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHBridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHDepositInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHWithdrawalFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "inputs": [], - "name": "MESSENGER", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_BRIDGE", - "outputs": [ - { - "internalType": "contract StandardBridge", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC20To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeETHTo", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositERC20To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositETHTo", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "deposits", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeERC20Withdrawal", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeETHWithdrawal", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "_messenger", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l2TokenBridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "messenger", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "otherBridge", - "outputs": [ - { - "internalType": "contract StandardBridge", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0xcfBCbA6d9E84A3c4FaE0eda9684cE39a09aa2c8A", - "args": [], - "bytecode": "0x60a06040523480156200001157600080fd5b507342000000000000000000000000000000000000106080526200003660006200003c565b620001bb565b600054600390610100900460ff161580156200005f575060005460ff8083169116105b620000c85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620000e7826200012c565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054610100900460ff16620001995760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000bf565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b608051612a44620001fa60003960008181610379015281816104300152818161057001528181610a22015281816113d80152611a8b0152612a446000f3fe6080604052600436106101635760003560e01c806387087623116100c0578063a9f9e67511610074578063c4d66de811610059578063c4d66de8146104c5578063c89701a214610421578063e11013dd146104e557600080fd5b8063a9f9e67514610492578063b1a1a882146104b257600080fd5b806391c49bf8116100a557806391c49bf814610421578063927ede2d146104545780639a2ac6d51461047f57600080fd5b806387087623146103bb5780638f601f66146103db57600080fd5b8063540abf731161011757806358a997f6116100fc57806358a997f6146103475780637f46ddb214610367578063838b25201461039b57600080fd5b8063540abf73146102d157806354fd4d50146102f157600080fd5b80631532ec34116101485780631532ec34146102545780631635f5fd146102675780633cb747bf1461027a57600080fd5b80630166a07a1461022157806309fc88431461024157600080fd5b3661021c57333b156101fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61021a333362030d40604051806020016040528060008152506104f8565b005b600080fd5b34801561022d57600080fd5b5061021a61023c36600461248b565b61050b565b61021a61024f36600461253c565b6108d2565b61021a61026236600461258f565b6109a9565b61021a61027536600461258f565b6109bd565b34801561028657600080fd5b506003546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102dd57600080fd5b5061021a6102ec366004612602565b610e33565b3480156102fd57600080fd5b5061033a6040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516102c891906126ef565b34801561035357600080fd5b5061021a610362366004612702565b610e78565b34801561037357600080fd5b506102a77f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a757600080fd5b5061021a6103b6366004612602565b610f4c565b3480156103c757600080fd5b5061021a6103d6366004612702565b610f91565b3480156103e757600080fd5b506104136103f6366004612785565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102c8565b34801561042d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102a7565b34801561046057600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102a7565b61021a61048d3660046127be565b611065565b34801561049e57600080fd5b5061021a6104ad36600461248b565b6110a7565b61021a6104c036600461253c565b6110b6565b3480156104d157600080fd5b5061021a6104e0366004612821565b611187565b61021a6104f33660046127be565b6112d1565b6105058484348585611314565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff16331480156105fa5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e2919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b6106ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b6106b5876114fa565b15610803576106c4878761155c565b610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107e657600080fd5b505af11580156107fa573d6000803e3d6000fd5b50505050610885565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461084190849061288a565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561088590858561167c565b6108c9878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175092505050565b50505050505050565b333b15610961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b505050565b6109b685858585856109bd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610aac5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b823414610bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101f3565b3073ffffffffffffffffffffffffffffffffffffffff851603610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101f3565b610d7f85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117de92505050565b6000610d9c855a8660405180602001604052806000815250611851565b905080610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b505050505050565b6108c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b333b15610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b6108c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b333b15611020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b61050533858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b6108c98787878787878761050b565b333b15611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b600054600390610100900460ff161580156111a9575060005460ff8083169116105b611235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101f3565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561126f82611bc2565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6105053385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b8234146113a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101f3565b6113af85858584611ca0565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b9085907f0000000000000000000000000000000000000000000000000000000000000000907f1635f5fd000000000000000000000000000000000000000000000000000000009061142e908b908b9086908a906024016128a1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526114c1929188906004016128ea565b6000604051808303818588803b1580156114da57600080fd5b505af11580156114ee573d6000803e3d6000fd5b50505050505050505050565b6000611526827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b806115565750611556827fec4fc8e300000000000000000000000000000000000000000000000000000000611d13565b92915050565b6000611588837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b15611631578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fc919061283e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611556565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109a49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611d36565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516117c89392919061292f565b60405180910390a4610e2b868686868686611e42565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631848460405161183d92919061296d565b60405180910390a361050584848484611eca565b600080600080845160208601878a8af19695505050505050565b611874876114fa565b156119c257611883878761155c565b611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b50505050611a56565b6119e473ffffffffffffffffffffffffffffffffffffffff8816863086611f37565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611a22908490612986565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611a64878787878786611f95565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b907f0000000000000000000000000000000000000000000000000000000000000000907f0166a07a0000000000000000000000000000000000000000000000000000000090611ae5908b908d908c908c908c908b9060240161299e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611b78929187906004016128ea565b600060405180830381600087803b158015611b9257600080fd5b505af1158015611ba6573d6000803e3d6000fd5b5050505050505050505050565b6108c98787878787878761186b565b600054610100900460ff16611c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101f3565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611cff92919061296d565b60405180910390a361050584848484612023565b6000611d1e83612082565b8015611d2f5750611d2f83836120e6565b9392505050565b6000611d98826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b59092919063ffffffff16565b8051909150156109a45780806020019051810190611db691906129f9565b6109a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101f3565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611eba9392919061292f565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f2992919061296d565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105059085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116ce565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161200d9392919061292f565b60405180910390a4610e2b8686868686866121cc565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f2992919061296d565b60006120ae827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e6565b801561155657506120df827fffffffff000000000000000000000000000000000000000000000000000000006120e6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219e575060208210155b80156121aa5750600081115b979650505050505050565b60606121c48484600085612244565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611eba9392919061292f565b6060824710156122d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101f3565b73ffffffffffffffffffffffffffffffffffffffff85163b612354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161237d9190612a1b565b60006040518083038185875af1925050503d80600081146123ba576040519150601f19603f3d011682016040523d82523d6000602084013e6123bf565b606091505b50915091506121aa828286606083156123d9575081611d2f565b8251156123e95782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f391906126ef565b73ffffffffffffffffffffffffffffffffffffffff8116811461243f57600080fd5b50565b60008083601f84011261245457600080fd5b50813567ffffffffffffffff81111561246c57600080fd5b60208301915083602082850101111561248457600080fd5b9250929050565b600080600080600080600060c0888a0312156124a657600080fd5b87356124b18161241d565b965060208801356124c18161241d565b955060408801356124d18161241d565b945060608801356124e18161241d565b93506080880135925060a088013567ffffffffffffffff81111561250457600080fd5b6125108a828b01612442565b989b979a50959850939692959293505050565b803563ffffffff8116811461253757600080fd5b919050565b60008060006040848603121561255157600080fd5b61255a84612523565b9250602084013567ffffffffffffffff81111561257657600080fd5b61258286828701612442565b9497909650939450505050565b6000806000806000608086880312156125a757600080fd5b85356125b28161241d565b945060208601356125c28161241d565b935060408601359250606086013567ffffffffffffffff8111156125e557600080fd5b6125f188828901612442565b969995985093965092949392505050565b600080600080600080600060c0888a03121561261d57600080fd5b87356126288161241d565b965060208801356126388161241d565b955060408801356126488161241d565b94506060880135935061265d60808901612523565b925060a088013567ffffffffffffffff81111561250457600080fd5b60005b8381101561269457818101518382015260200161267c565b838111156105055750506000910152565b600081518084526126bd816020860160208601612679565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d2f60208301846126a5565b60008060008060008060a0878903121561271b57600080fd5b86356127268161241d565b955060208701356127368161241d565b94506040870135935061274b60608801612523565b9250608087013567ffffffffffffffff81111561276757600080fd5b61277389828a01612442565b979a9699509497509295939492505050565b6000806040838503121561279857600080fd5b82356127a38161241d565b915060208301356127b38161241d565b809150509250929050565b600080600080606085870312156127d457600080fd5b84356127df8161241d565b93506127ed60208601612523565b9250604085013567ffffffffffffffff81111561280957600080fd5b61281587828801612442565b95989497509550505050565b60006020828403121561283357600080fd5b8135611d2f8161241d565b60006020828403121561285057600080fd5b8151611d2f8161241d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561289c5761289c61285b565b500390565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128e060808301846126a5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061291960608301856126a5565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296460608301846126a5565b95945050505050565b8281526040602082015260006121c460408301846126a5565b600082198211156129995761299961285b565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526129ed60c08301846126a5565b98975050505050505050565b600060208284031215612a0b57600080fd5b81518015158114611d2f57600080fd5b60008251612a2d818460208701612679565b919091019291505056fea164736f6c634300080f000a", - "deployedBytecode": "0x6080604052600436106101635760003560e01c806387087623116100c0578063a9f9e67511610074578063c4d66de811610059578063c4d66de8146104c5578063c89701a214610421578063e11013dd146104e557600080fd5b8063a9f9e67514610492578063b1a1a882146104b257600080fd5b806391c49bf8116100a557806391c49bf814610421578063927ede2d146104545780639a2ac6d51461047f57600080fd5b806387087623146103bb5780638f601f66146103db57600080fd5b8063540abf731161011757806358a997f6116100fc57806358a997f6146103475780637f46ddb214610367578063838b25201461039b57600080fd5b8063540abf73146102d157806354fd4d50146102f157600080fd5b80631532ec34116101485780631532ec34146102545780631635f5fd146102675780633cb747bf1461027a57600080fd5b80630166a07a1461022157806309fc88431461024157600080fd5b3661021c57333b156101fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61021a333362030d40604051806020016040528060008152506104f8565b005b600080fd5b34801561022d57600080fd5b5061021a61023c36600461248b565b61050b565b61021a61024f36600461253c565b6108d2565b61021a61026236600461258f565b6109a9565b61021a61027536600461258f565b6109bd565b34801561028657600080fd5b506003546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102dd57600080fd5b5061021a6102ec366004612602565b610e33565b3480156102fd57600080fd5b5061033a6040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516102c891906126ef565b34801561035357600080fd5b5061021a610362366004612702565b610e78565b34801561037357600080fd5b506102a77f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a757600080fd5b5061021a6103b6366004612602565b610f4c565b3480156103c757600080fd5b5061021a6103d6366004612702565b610f91565b3480156103e757600080fd5b506104136103f6366004612785565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102c8565b34801561042d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102a7565b34801561046057600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102a7565b61021a61048d3660046127be565b611065565b34801561049e57600080fd5b5061021a6104ad36600461248b565b6110a7565b61021a6104c036600461253c565b6110b6565b3480156104d157600080fd5b5061021a6104e0366004612821565b611187565b61021a6104f33660046127be565b6112d1565b6105058484348585611314565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff16331480156105fa5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e2919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b6106ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b6106b5876114fa565b15610803576106c4878761155c565b610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107e657600080fd5b505af11580156107fa573d6000803e3d6000fd5b50505050610885565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461084190849061288a565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561088590858561167c565b6108c9878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175092505050565b50505050505050565b333b15610961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b505050565b6109b685858585856109bd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610aac5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b823414610bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101f3565b3073ffffffffffffffffffffffffffffffffffffffff851603610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101f3565b610d7f85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117de92505050565b6000610d9c855a8660405180602001604052806000815250611851565b905080610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b505050505050565b6108c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b333b15610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b6108c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b333b15611020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b61050533858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b6108c98787878787878761050b565b333b15611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b600054600390610100900460ff161580156111a9575060005460ff8083169116105b611235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101f3565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561126f82611bc2565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6105053385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b8234146113a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101f3565b6113af85858584611ca0565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b9085907f0000000000000000000000000000000000000000000000000000000000000000907f1635f5fd000000000000000000000000000000000000000000000000000000009061142e908b908b9086908a906024016128a1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526114c1929188906004016128ea565b6000604051808303818588803b1580156114da57600080fd5b505af11580156114ee573d6000803e3d6000fd5b50505050505050505050565b6000611526827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b806115565750611556827fec4fc8e300000000000000000000000000000000000000000000000000000000611d13565b92915050565b6000611588837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b15611631578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fc919061283e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611556565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109a49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611d36565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516117c89392919061292f565b60405180910390a4610e2b868686868686611e42565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631848460405161183d92919061296d565b60405180910390a361050584848484611eca565b600080600080845160208601878a8af19695505050505050565b611874876114fa565b156119c257611883878761155c565b611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b50505050611a56565b6119e473ffffffffffffffffffffffffffffffffffffffff8816863086611f37565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611a22908490612986565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611a64878787878786611f95565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b907f0000000000000000000000000000000000000000000000000000000000000000907f0166a07a0000000000000000000000000000000000000000000000000000000090611ae5908b908d908c908c908c908b9060240161299e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611b78929187906004016128ea565b600060405180830381600087803b158015611b9257600080fd5b505af1158015611ba6573d6000803e3d6000fd5b5050505050505050505050565b6108c98787878787878761186b565b600054610100900460ff16611c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101f3565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611cff92919061296d565b60405180910390a361050584848484612023565b6000611d1e83612082565b8015611d2f5750611d2f83836120e6565b9392505050565b6000611d98826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b59092919063ffffffff16565b8051909150156109a45780806020019051810190611db691906129f9565b6109a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101f3565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611eba9392919061292f565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f2992919061296d565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105059085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116ce565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161200d9392919061292f565b60405180910390a4610e2b8686868686866121cc565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f2992919061296d565b60006120ae827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e6565b801561155657506120df827fffffffff000000000000000000000000000000000000000000000000000000006120e6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219e575060208210155b80156121aa5750600081115b979650505050505050565b60606121c48484600085612244565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611eba9392919061292f565b6060824710156122d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101f3565b73ffffffffffffffffffffffffffffffffffffffff85163b612354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161237d9190612a1b565b60006040518083038185875af1925050503d80600081146123ba576040519150601f19603f3d011682016040523d82523d6000602084013e6123bf565b606091505b50915091506121aa828286606083156123d9575081611d2f565b8251156123e95782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f391906126ef565b73ffffffffffffffffffffffffffffffffffffffff8116811461243f57600080fd5b50565b60008083601f84011261245457600080fd5b50813567ffffffffffffffff81111561246c57600080fd5b60208301915083602082850101111561248457600080fd5b9250929050565b600080600080600080600060c0888a0312156124a657600080fd5b87356124b18161241d565b965060208801356124c18161241d565b955060408801356124d18161241d565b945060608801356124e18161241d565b93506080880135925060a088013567ffffffffffffffff81111561250457600080fd5b6125108a828b01612442565b989b979a50959850939692959293505050565b803563ffffffff8116811461253757600080fd5b919050565b60008060006040848603121561255157600080fd5b61255a84612523565b9250602084013567ffffffffffffffff81111561257657600080fd5b61258286828701612442565b9497909650939450505050565b6000806000806000608086880312156125a757600080fd5b85356125b28161241d565b945060208601356125c28161241d565b935060408601359250606086013567ffffffffffffffff8111156125e557600080fd5b6125f188828901612442565b969995985093965092949392505050565b600080600080600080600060c0888a03121561261d57600080fd5b87356126288161241d565b965060208801356126388161241d565b955060408801356126488161241d565b94506060880135935061265d60808901612523565b925060a088013567ffffffffffffffff81111561250457600080fd5b60005b8381101561269457818101518382015260200161267c565b838111156105055750506000910152565b600081518084526126bd816020860160208601612679565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d2f60208301846126a5565b60008060008060008060a0878903121561271b57600080fd5b86356127268161241d565b955060208701356127368161241d565b94506040870135935061274b60608801612523565b9250608087013567ffffffffffffffff81111561276757600080fd5b61277389828a01612442565b979a9699509497509295939492505050565b6000806040838503121561279857600080fd5b82356127a38161241d565b915060208301356127b38161241d565b809150509250929050565b600080600080606085870312156127d457600080fd5b84356127df8161241d565b93506127ed60208601612523565b9250604085013567ffffffffffffffff81111561280957600080fd5b61281587828801612442565b95989497509550505050565b60006020828403121561283357600080fd5b8135611d2f8161241d565b60006020828403121561285057600080fd5b8151611d2f8161241d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561289c5761289c61285b565b500390565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128e060808301846126a5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061291960608301856126a5565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296460608301846126a5565b95945050505050565b8281526040602082015260006121c460408301846126a5565b600082198211156129995761299961285b565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526129ed60c08301846126a5565b98975050505050505050565b600060208284031215612a0b57600080fd5b81518015158114611d2f57600080fd5b60008251612a2d818460208701612679565b919091019291505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "MESSENGER()": {}, - "bridgeERC20(address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of local tokens to deposit.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_localToken": "Address of the ERC20 on this chain.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_remoteToken": "Address of the corresponding token on the remote chain." - } - }, - "bridgeERC20To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of local tokens to deposit.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_localToken": "Address of the ERC20 on this chain.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_remoteToken": "Address of the corresponding token on the remote chain.", - "_to": "Address of the receiver." - } - }, - "bridgeETH(uint32,bytes)": { - "params": { - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with." - } - }, - "bridgeETHTo(address,uint32,bytes)": { - "params": { - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_to": "Address of the receiver." - } - }, - "depositERC20(address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of the ERC20 to deposit.", - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_l1Token": "Address of the L1 token being deposited.", - "_l2Token": "Address of the corresponding token on L2.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2." - } - }, - "depositERC20To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of the ERC20 to deposit.", - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_l1Token": "Address of the L1 token being deposited.", - "_l2Token": "Address of the corresponding token on L2.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2.", - "_to": "Address of the recipient on L2." - } - }, - "depositETH(uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2." - } - }, - "depositETHTo(address,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2.", - "_to": "Address of the recipient on L2." - } - }, - "finalizeBridgeERC20(address,address,address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of the ERC20 being bridged.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_from": "Address of the sender.", - "_localToken": "Address of the ERC20 on this chain.", - "_remoteToken": "Address of the corresponding token on the remote chain.", - "_to": "Address of the receiver." - } - }, - "finalizeBridgeETH(address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of ETH being bridged.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_from": "Address of the sender.", - "_to": "Address of the receiver." - } - }, - "finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of the ERC20 to withdraw.", - "_extraData": "Optional data forwarded from L2.", - "_from": "Address of the withdrawer on L2.", - "_l1Token": "Address of the token on L1.", - "_l2Token": "Address of the corresponding token on L2.", - "_to": "Address of the recipient on L1." - } - }, - "finalizeETHWithdrawal(address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of ETH to withdraw.", - "_extraData": "Optional data forwarded from L2.", - "_from": "Address of the withdrawer on L2.", - "_to": "Address of the recipient on L1." - } - }, - "l2TokenBridge()": { - "returns": { - "_0": "Address of the corresponding L2 bridge contract." - } - } - }, - "events": { - "ERC20DepositInitiated(address,address,address,address,uint256,bytes)": { - "params": { - "amount": "Amount of the ERC20 deposited.", - "extraData": "Extra data attached to the deposit.", - "from": "Address of the depositor.", - "l1Token": "Address of the token on L1.", - "l2Token": "Address of the corresponding token on L2.", - "to": "Address of the recipient on L2." - } - }, - "ERC20WithdrawalFinalized(address,address,address,address,uint256,bytes)": { - "params": { - "amount": "Amount of the ERC20 withdrawn.", - "extraData": "Extra data attached to the withdrawal.", - "from": "Address of the withdrawer.", - "l1Token": "Address of the token on L1.", - "l2Token": "Address of the corresponding token on L2.", - "to": "Address of the recipient on L1." - } - }, - "ETHDepositInitiated(address,address,uint256,bytes)": { - "params": { - "amount": "Amount of ETH deposited.", - "extraData": "Extra data attached to the deposit.", - "from": "Address of the depositor.", - "to": "Address of the recipient on L2." - } - }, - "ETHWithdrawalFinalized(address,address,uint256,bytes)": { - "params": { - "amount": "Amount of ETH withdrawn.", - "extraData": "Extra data attached to the withdrawal.", - "from": "Address of the withdrawer.", - "to": "Address of the recipient on L1." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20BridgeFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20BridgeInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20DepositInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20WithdrawalFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHBridgeFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHBridgeInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHDepositInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHWithdrawalFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"contract StandardBridge\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC20\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC20To\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"bridgeETH\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"bridgeETHTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"depositERC20\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"depositERC20To\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"depositETH\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"depositETHTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeBridgeERC20\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"finalizeBridgeETH\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeERC20Withdrawal\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"finalizeETHWithdrawal\"},{\"inputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"_messenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2TokenBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"contract StandardBridge\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"MESSENGER()\":{\"custom:legacy\":\"@return Messenger contract on this domain.\"},\"bridgeERC20(address,address,uint256,uint32,bytes)\":{\"params\":{\"_amount\":\"Amount of local tokens to deposit.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\"}},\"bridgeERC20To(address,address,address,uint256,uint32,bytes)\":{\"params\":{\"_amount\":\"Amount of local tokens to deposit.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\",\"_to\":\"Address of the receiver.\"}},\"bridgeETH(uint32,bytes)\":{\"params\":{\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\"}},\"bridgeETHTo(address,uint32,bytes)\":{\"params\":{\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_to\":\"Address of the receiver.\"}},\"depositERC20(address,address,uint256,uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ERC20 tokens into the sender's account on L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_l1Token\":\"Address of the L1 token being deposited.\",\"_l2Token\":\"Address of the corresponding token on L2.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\"}},\"depositERC20To(address,address,address,uint256,uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ERC20 tokens into a target account on L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_l1Token\":\"Address of the L1 token being deposited.\",\"_l2Token\":\"Address of the corresponding token on L2.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\",\"_to\":\"Address of the recipient on L2.\"}},\"depositETH(uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ETH into the sender's account on L2.\",\"params\":{\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\"}},\"depositETHTo(address,uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ETH into a target account on L2. Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will be locked in the L2StandardBridge. ETH may be recoverable if the call can be successfully replayed by increasing the amount of gas supplied to the call. If the call will fail for any amount of gas, then the ETH will be locked permanently.\",\"params\":{\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\",\"_to\":\"Address of the recipient on L2.\"}},\"finalizeBridgeERC20(address,address,address,address,uint256,bytes)\":{\"params\":{\"_amount\":\"Amount of the ERC20 being bridged.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_from\":\"Address of the sender.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\",\"_to\":\"Address of the receiver.\"}},\"finalizeBridgeETH(address,address,uint256,bytes)\":{\"params\":{\"_amount\":\"Amount of ETH being bridged.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_from\":\"Address of the sender.\",\"_to\":\"Address of the receiver.\"}},\"finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)\":{\"custom:legacy\":\"@notice Finalizes a withdrawal of ERC20 tokens from L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to withdraw.\",\"_extraData\":\"Optional data forwarded from L2.\",\"_from\":\"Address of the withdrawer on L2.\",\"_l1Token\":\"Address of the token on L1.\",\"_l2Token\":\"Address of the corresponding token on L2.\",\"_to\":\"Address of the recipient on L1.\"}},\"finalizeETHWithdrawal(address,address,uint256,bytes)\":{\"custom:legacy\":\"@notice Finalizes a withdrawal of ETH from L2.\",\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_extraData\":\"Optional data forwarded from L2.\",\"_from\":\"Address of the withdrawer on L2.\",\"_to\":\"Address of the recipient on L1.\"}},\"l2TokenBridge()\":{\"custom:legacy\":\"@notice Retrieves the access of the corresponding L2 bridge contract.\",\"returns\":{\"_0\":\"Address of the corresponding L2 bridge contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"MESSENGER()\":{\"notice\":\"Getter for messenger contract.\"},\"OTHER_BRIDGE()\":{\"notice\":\"Corresponding bridge on the other domain. This public getter is deprecated and will be removed in the future. Please use `otherBridge` instead. This can safely be an immutable because for the L1StandardBridge, it will be set to the L2StandardBridge address, which is the same for all OP Stack chains. For the L2StandardBridge, there are not multiple proxies using the same implementation.\"},\"bridgeERC20(address,address,uint256,uint32,bytes)\":{\"notice\":\"Sends ERC20 tokens to the sender's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain.\"},\"bridgeERC20To(address,address,address,uint256,uint32,bytes)\":{\"notice\":\"Sends ERC20 tokens to a receiver's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain.\"},\"bridgeETH(uint32,bytes)\":{\"notice\":\"Sends ETH to the sender's address on the other chain.\"},\"bridgeETHTo(address,uint32,bytes)\":{\"notice\":\"Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a smart contract and the call fails, the ETH will be temporarily locked in the StandardBridge on the other chain until the call is replayed. If the call cannot be replayed with any amount of gas (call always reverts), then the ETH will be permanently locked in the StandardBridge on the other chain. ETH will also be locked if the receiver is the other bridge, because finalizeBridgeETH will revert in that case.\"},\"constructor\":{\"notice\":\"Constructs the L1StandardBridge contract.\"},\"deposits(address,address)\":{\"notice\":\"Mapping that stores deposits for a given pair of local and remote tokens.\"},\"finalizeBridgeERC20(address,address,address,address,uint256,bytes)\":{\"notice\":\"Finalizes an ERC20 bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain.\"},\"finalizeBridgeETH(address,address,uint256,bytes)\":{\"notice\":\"Finalizes an ETH bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain.\"},\"initialize(address)\":{\"notice\":\"Initializer\"},\"messenger()\":{\"notice\":\"Messenger contract on this domain. This public getter is deprecated and will be removed in the future. Please use `messenger` instead.\"},\"otherBridge()\":{\"notice\":\"Getter for the remote domain bridge contract.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L1StandardBridge.sol\":\"L1StandardBridge\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"urls\":[\"bzz-raw://11756f42121f6541a35a8339ea899ee7514cfaa2e6d740625fcc844419296aa6\",\"dweb:/ipfs/QmekMuk6BY4DAjzeXr4MSbKdgoqqsZnA8JPtuyWc6CwXHf\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L1StandardBridge.sol\":{\"keccak256\":\"0x6838bb9b120c2c55e5f86591180053fd213141310c59a7856c55289079e26818\",\"urls\":[\"bzz-raw://193330432139af7aa03e97e0bb451c8204cc0f63452edc2312fe9465f36cf48c\",\"dweb:/ipfs/Qmchazs1JtQ84dCjVUFFHFQxpL8Byh4RCEWVGVfXqZbPNi\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/Predeploys.sol\":{\"keccak256\":\"0x5af3a849f68f7c9108858ebac5c769da8f1c0309b5c0cb42eb5cbb15e3fe6058\",\"urls\":[\"bzz-raw://6ffe76429a96d274577be66627eddad5cd05ad36d0cb6b9b3c3f9fa8a609dd7e\",\"dweb:/ipfs/QmVhWnB7Avg684TEQ9BExWqSN1YfLehUTWoqpjymeQEQHm\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x4302ae78bcafde2737d4048bbf8fdb3dd4cd7254c015b91dfa14fdaafd412f4a\",\"urls\":[\"bzz-raw://78d3d1823ad4e1fba15921a0a361b452c85d111e2d53cbbed11a8632782ea8f3\",\"dweb:/ipfs/QmVc2rTRpn7g7WAUxDShSuy6dY5zmtbJ7hHC6sT9PcD3Gj\"],\"license\":\"MIT\"},\"src/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x6f8133b39efcbcbd5088f195dfacf1bedc3146508429c3865443909af735a04c\",\"urls\":[\"bzz-raw://adc36971e2e120458769f050428d9d2b0504516660345020c2521ee46e6d8abf\",\"dweb:/ipfs/QmPbFusQkZgGKpU8Fv5JoqL4oVeJtM3yqnhRGLY9eZT5zZ\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x39af021e492020fbeb5401371010d4a2fb69debe9596dbbead7bcd7fae248b0b\",\"urls\":[\"bzz-raw://dbeea52e586d2d7de55491a660ca76f75167ba6b43b65d29564864ee9c34a174\",\"dweb:/ipfs/QmS23vFqQxyUXhGuV1nSowZZS93CUkSnsb41uuyRtSeAED\"],\"license\":\"MIT\"},\"src/universal/Semver.sol\":{\"keccak256\":\"0x9de68ce536aee1aa616b4bf88d7ccc335460e6edd0e7170bdbf94c4fe3d41c60\",\"urls\":[\"bzz-raw://d5909c0b049b03a2bc24816ecf15b0aaf18c04a963174e1eba7624321bef330d\",\"dweb:/ipfs/QmeqdutwZWHqQMXauNR6WY8PrUpfsTiWTQyanbnGM9QqzT\"],\"license\":\"MIT\"},\"src/universal/StandardBridge.sol\":{\"keccak256\":\"0xc6ab09f73ee243757df19b3304b6ca289af84c2ce3ea4bf370a89c39c6ae5b04\",\"urls\":[\"bzz-raw://f5a3a6a7240ddb7c78b446e0647b7f5e7a8948b368a59d433efd70e927ea5c32\",\"dweb:/ipfs/QmVjEgX5LtCKz7HauTag8ukFgt5edPCVAsve6Mb3mKnXJN\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 2, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 77650, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "spacer_0_2_20", - "offset": 2, - "slot": "0", - "type": "t_address" - }, - { - "astId": 77653, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "spacer_1_0_20", - "offset": 0, - "slot": "1", - "type": "t_address" - }, - { - "astId": 77660, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "deposits", - "offset": 0, - "slot": "2", - "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" - }, - { - "astId": 77664, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "messenger", - "offset": 0, - "slot": "3", - "type": "t_contract(CrossDomainMessenger)75534" - }, - { - "astId": 77669, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "__gap", - "offset": 0, - "slot": "4", - "type": "t_array(t_uint256)46_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)46_storage": { - "encoding": "inplace", - "label": "uint256[46]", - "numberOfBytes": "1472", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(CrossDomainMessenger)75534": { - "encoding": "inplace", - "label": "contract CrossDomainMessenger", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_mapping(t_address,t_uint256))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => uint256))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_uint256)" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x8ce28138f3c8011f31062c645f45841bf876c5320b528e069535fa200552d919", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSENGER()": { - "notice": "Getter for messenger contract." - }, - "OTHER_BRIDGE()": { - "notice": "Corresponding bridge on the other domain. This public getter is deprecated and will be removed in the future. Please use `otherBridge` instead. This can safely be an immutable because for the L1StandardBridge, it will be set to the L2StandardBridge address, which is the same for all OP Stack chains. For the L2StandardBridge, there are not multiple proxies using the same implementation." - }, - "bridgeERC20(address,address,uint256,uint32,bytes)": { - "notice": "Sends ERC20 tokens to the sender's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain." - }, - "bridgeERC20To(address,address,address,uint256,uint32,bytes)": { - "notice": "Sends ERC20 tokens to a receiver's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain." - }, - "bridgeETH(uint32,bytes)": { - "notice": "Sends ETH to the sender's address on the other chain." - }, - "bridgeETHTo(address,uint32,bytes)": { - "notice": "Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a smart contract and the call fails, the ETH will be temporarily locked in the StandardBridge on the other chain until the call is replayed. If the call cannot be replayed with any amount of gas (call always reverts), then the ETH will be permanently locked in the StandardBridge on the other chain. ETH will also be locked if the receiver is the other bridge, because finalizeBridgeETH will revert in that case." - }, - "constructor": { - "notice": "Constructs the L1StandardBridge contract." - }, - "deposits(address,address)": { - "notice": "Mapping that stores deposits for a given pair of local and remote tokens." - }, - "finalizeBridgeERC20(address,address,address,address,uint256,bytes)": { - "notice": "Finalizes an ERC20 bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain." - }, - "finalizeBridgeETH(address,address,uint256,bytes)": { - "notice": "Finalizes an ETH bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain." - }, - "initialize(address)": { - "notice": "Initializer" - }, - "messenger()": { - "notice": "Messenger contract on this domain. This public getter is deprecated and will be removed in the future. Please use `messenger` instead." - }, - "otherBridge()": { - "notice": "Getter for the remote domain bridge contract." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ERC20BridgeFinalized(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC20 bridge is finalized on this chain." - }, - "ERC20BridgeInitiated(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC20 bridge is initiated to the other chain." - }, - "ETHBridgeFinalized(address,address,uint256,bytes)": { - "notice": "Emitted when an ETH bridge is finalized on this chain." - }, - "ETHBridgeInitiated(address,address,uint256,bytes)": { - "notice": "Emitted when an ETH bridge is initiated to the other chain." - } - }, - "notice": "The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and L2. In the case that an ERC20 token is native to L1, it will be escrowed within this contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was stored within this contract. After Bedrock, ETH is instead stored inside the OptimismPortal contract. NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples of some token types that may not be properly supported by this contract include, but are not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/L1StandardBridgeProxy.json b/packages/contracts-bedrock/deployments/mainnet/L1StandardBridgeProxy.json deleted file mode 100644 index 4e1fbf899bfb..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/L1StandardBridgeProxy.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "address": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_code", - "type": "bytes" - } - ], - "name": "setCode", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_key", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_value", - "type": "bytes32" - } - ], - "name": "setStorage", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0x3fb736def76e27e507bc4e451e5498f1f1beee3e82e6aa67ecef434c638a04ac", - "receipt": { - "to": null, - "from": "0x9996571372066A1545D3435C6935e3F9593A7eF5", - "contractAddress": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1", - "transactionIndex": 70, - "gasUsed": "471232", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb6578d9e60cce4713437b5cf0898dd7040c9284e178aadfb7dfbb590f4f083af", - "transactionHash": "0x3fb736def76e27e507bc4e451e5498f1f1beee3e82e6aa67ecef434c638a04ac", - "logs": [], - "blockNumber": 12686786, - "cumulativeGasUsed": "6551653", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9996571372066A1545D3435C6935e3F9593A7eF5" - ], - "solcInputHash": "7531d7762a77038a37e7490a7b4b176f", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"getImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"setCode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_value\",\"type\":\"bytes32\"}],\"name\":\"setStorage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_owner\":\"Address of the initial contract owner.\"}},\"getImplementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"getOwner()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"setCode(bytes)\":{\"params\":{\"_code\":\"New contract code to run inside this contract.\"}},\"setOwner(address)\":{\"params\":{\"_owner\":\"New owner of the proxy contract.\"}},\"setStorage(bytes32,bytes32)\":{\"params\":{\"_key\":\"Storage key to modify.\",\"_value\":\"New value for the storage key.\"}}},\"title\":\"L1ChugSplashProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getImplementation()\":{\"notice\":\"Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"getOwner()\":{\"notice\":\"Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"setCode(bytes)\":{\"notice\":\"Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner.\"},\"setOwner(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"setStorage(bytes32,bytes32)\":{\"notice\":\"Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/chugsplash/L1ChugSplashProxy.sol\":\"L1ChugSplashProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/chugsplash/L1ChugSplashProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\n\\nimport { iL1ChugSplashDeployer } from \\\"./interfaces/iL1ChugSplashDeployer.sol\\\";\\n\\n/**\\n * @title L1ChugSplashProxy\\n * @dev Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\\n * functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty!\\n *\\n * Note for future developers: do NOT make anything in this contract 'public' unless you know what\\n * you're doing. Anything public can potentially have a function signature that conflicts with a\\n * signature attached to the implementation contract. Public functions SHOULD always have the\\n * 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that\\n * modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\\n */\\ncontract L1ChugSplashProxy {\\n\\n /*************\\n * Constants *\\n *************/\\n\\n // \\\"Magic\\\" prefix. When prepended to some arbitrary bytecode and used to create a contract, the\\n // appended bytecode will be deployed as given.\\n bytes13 constant internal DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 constant internal IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n bytes32 constant internal OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n\\n /***************\\n * Constructor *\\n ***************/\\n \\n /**\\n * @param _owner Address of the initial contract owner.\\n */\\n constructor(\\n address _owner\\n ) {\\n _setOwner(_owner);\\n }\\n\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n /**\\n * Blocks a function from being called when the parent signals that the system should be paused\\n * via an isUpgrading function.\\n */\\n modifier onlyWhenNotPaused() {\\n address owner = _getOwner();\\n\\n // We do a low-level call because there's no guarantee that the owner actually *is* an\\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\\n // it turns out that it isn't the right type of contract.\\n (bool success, bytes memory returndata) = owner.staticcall(\\n abi.encodeWithSelector(\\n iL1ChugSplashDeployer.isUpgrading.selector\\n )\\n );\\n\\n // If the call was unsuccessful then we assume that there's no \\\"isUpgrading\\\" method and we\\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\\n // long. If this isn't the case then we can safely ignore the result.\\n if (success && returndata.length == 32) {\\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\\n // case that the isUpgrading function returned something other than 0 or 1. But we only\\n // really care about the case where this value is 0 (= false).\\n uint256 ret = abi.decode(returndata, (uint256));\\n require(\\n ret == 0,\\n \\\"L1ChugSplashProxy: system is currently being upgraded\\\"\\n );\\n }\\n\\n _;\\n }\\n\\n /**\\n * Makes a proxy call instead of triggering the given function when the caller is either the\\n * owner or the zero address. Caller can only ever be the zero address if this function is\\n * being called off-chain via eth_call, which is totally fine and can be convenient for\\n * client-side tooling. Avoids situations where the proxy and implementation share a sighash\\n * and the proxy function ends up being called instead of the implementation one.\\n *\\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If there's a\\n * way for someone to send a transaction with msg.sender == address(0) in any real context then\\n * we have much bigger problems. Primary reason to include this additional allowed sender is\\n * because the owner address can be changed dynamically and we do not want clients to have to\\n * keep track of the current owner in order to make an eth_call that doesn't trigger the\\n * proxied contract.\\n */\\n modifier proxyCallIfNotOwner() {\\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n fallback()\\n external\\n payable\\n {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the code that should be running behind this proxy. Note that this scheme is a bit\\n * different from the standard proxy scheme where one would typically deploy the code\\n * separately and then set the implementation address. We're doing it this way because it gives\\n * us a lot more freedom on the client side. Can only be triggered by the contract owner.\\n * @param _code New contract code to run inside this contract.\\n */\\n function setCode(\\n bytes memory _code\\n )\\n proxyCallIfNotOwner\\n public\\n {\\n // Get the code hash of the current implementation.\\n address implementation = _getImplementation();\\n\\n // If the code hash matches the new implementation then we return early.\\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\\n return;\\n }\\n\\n // Create the deploycode by appending the magic prefix.\\n bytes memory deploycode = abi.encodePacked(\\n DEPLOY_CODE_PREFIX,\\n _code\\n );\\n\\n // Deploy the code and set the new implementation address.\\n address newImplementation;\\n assembly {\\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\\n }\\n\\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\\n // actually fail this check. Should only happen if the contract creation from above runs\\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\\n // should be doing this check anyway though.\\n require(\\n _getAccountCodeHash(newImplementation) == keccak256(_code),\\n \\\"L1ChugSplashProxy: code was not correctly deployed.\\\"\\n );\\n\\n _setImplementation(newImplementation);\\n }\\n\\n /**\\n * Modifies some storage slot within the proxy contract. Gives us a lot of power to perform\\n * upgrades in a more transparent way. Only callable by the owner.\\n * @param _key Storage key to modify.\\n * @param _value New value for the storage key.\\n */\\n function setStorage(\\n bytes32 _key,\\n bytes32 _value\\n )\\n proxyCallIfNotOwner\\n public\\n {\\n assembly {\\n sstore(_key, _value)\\n }\\n }\\n\\n /**\\n * Changes the owner of the proxy contract. Only callable by the owner.\\n * @param _owner New owner of the proxy contract.\\n */\\n function setOwner(\\n address _owner\\n )\\n proxyCallIfNotOwner\\n public\\n {\\n _setOwner(_owner);\\n }\\n\\n /**\\n * Queries the owner of the proxy contract. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Owner address.\\n */\\n function getOwner()\\n proxyCallIfNotOwner\\n public\\n returns (\\n address\\n )\\n {\\n return _getOwner();\\n }\\n\\n /**\\n * Queries the implementation address. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Implementation address.\\n */\\n function getImplementation()\\n proxyCallIfNotOwner\\n public\\n returns (\\n address\\n )\\n {\\n return _getImplementation();\\n }\\n\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Sets the implementation address.\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(\\n address _implementation\\n )\\n internal\\n {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n }\\n\\n /**\\n * Queries the implementation address.\\n * @return Implementation address.\\n */\\n function _getImplementation()\\n internal\\n view\\n returns (\\n address\\n )\\n {\\n address implementation;\\n assembly {\\n implementation := sload(IMPLEMENTATION_KEY)\\n }\\n return implementation;\\n }\\n\\n /**\\n * Changes the owner of the proxy contract.\\n * @param _owner New owner of the proxy contract.\\n */\\n function _setOwner(\\n address _owner\\n )\\n internal\\n {\\n assembly {\\n sstore(OWNER_KEY, _owner)\\n }\\n }\\n\\n /**\\n * Queries the owner of the proxy contract.\\n * @return Owner address.\\n */\\n function _getOwner()\\n internal\\n view \\n returns (\\n address\\n )\\n {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n\\n /**\\n * Gets the code hash for a given account.\\n * @param _account Address of the account to get a code hash for.\\n * @return Code hash for the account.\\n */\\n function _getAccountCodeHash(\\n address _account\\n )\\n internal\\n view\\n returns (\\n bytes32\\n )\\n {\\n bytes32 codeHash;\\n assembly {\\n codeHash := extcodehash(_account)\\n }\\n return codeHash;\\n }\\n\\n /**\\n * Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall()\\n onlyWhenNotPaused\\n internal\\n {\\n address implementation = _getImplementation();\\n\\n require(\\n implementation != address(0),\\n \\\"L1ChugSplashProxy: implementation is not set yet\\\"\\n );\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n \\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0x654af4f1d1aab76467c49fcce992eaf3522040ed806d656d98735c50ac235eeb\",\"license\":\"MIT\"},\"contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\n\\n/**\\n * @title iL1ChugSplashDeployer\\n */\\ninterface iL1ChugSplashDeployer {\\n function isUpgrading()\\n external\\n view\\n returns (\\n bool\\n );\\n}\\n\",\"keccak256\":\"0xdab3ecb1ce03376523cd2f2ce5f991389c388829c56907987da01d99d3fc44c7\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506040516107983803806107988339818101604052602081101561003357600080fd5b505161003e81610044565b50610068565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b610721806100776000396000f3fe60806040526004361061004a5760003560e01c806313af4035146100545780636c5d4ad014610087578063893d20e81461013a5780639b0b0fda1461016b578063aaf10f421461019b575b6100526101b0565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661036c565b34801561009357600080fd5b50610052600480360360208110156100aa57600080fd5b8101906020810181356401000000008111156100c557600080fd5b8201836020820111156100d757600080fd5b803590602001918460018302840111640100000000831117156100f957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103af945050505050565b34801561014657600080fd5b5061014f610505565b604080516001600160a01b039092168252519081900360200190f35b34801561017757600080fd5b506100526004803603604081101561018e57600080fd5b508035906020013561054b565b3480156101a757600080fd5b5061014f610589565b60006101ba6105bd565b60408051600481526024810182526020810180516001600160e01b0316635bca393160e11b1781529151815193945060009384936001600160a01b0387169392918291908083835b602083106102215780518252601f199092019160209182019101610202565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114610281576040519150601f19603f3d011682016040523d82523d6000602084013e610286565b606091505b5091509150818015610299575080516020145b156102f85760008180602001905160208110156102b557600080fd5b5051905080156102f65760405162461bcd60e51b81526004018080602001828103825260358152602001806106b76035913960400191505060405180910390fd5b505b60006103026105e2565b90506001600160a01b0381166103495760405162461bcd60e51b81526004018080602001828103825260308152602001806106546030913960400191505060405180910390fd5b3660008037600080366000845af43d6000803e80610366573d6000fd5b503d6000f35b6103746105bd565b6001600160a01b0316336001600160a01b03161480610391575033155b156103a45761039f81610607565b6103ac565b6103ac6101b0565b50565b6103b76105bd565b6001600160a01b0316336001600160a01b031614806103d4575033155b156103a45760006103e36105e2565b90506103ee8161062b565b825160208401201415610401575061039f565b60006c600d380380600d6000396000f360981b83604051602001808372ffffffffffffffffffffffffffffffffffffff19168152600d0182805190602001908083835b602083106104635780518252601f199092019160209182019101610444565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052905060008151602083016000f0905083805190602001206104b88261062b565b146104f45760405162461bcd60e51b81526004018080602001828103825260338152602001806106846033913960400191505060405180910390fd5b6104fd8161062f565b5050506103ac565b600061050f6105bd565b6001600160a01b0316336001600160a01b0316148061052c575033155b15610540576105396105bd565b9050610548565b6105486101b0565b90565b6105536105bd565b6001600160a01b0316336001600160a01b03161480610570575033155b1561057d57808255610585565b6105856101b0565b5050565b60006105936105bd565b6001600160a01b0316336001600160a01b031614806105b0575033155b15610540576105396105e2565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b3f90565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5556fe4c314368756753706c61736850726f78793a20696d706c656d656e746174696f6e206973206e6f7420736574207965744c314368756753706c61736850726f78793a20636f646520776173206e6f7420636f72726563746c79206465706c6f7965642e4c314368756753706c61736850726f78793a2073797374656d2069732063757272656e746c79206265696e67207570677261646564a26469706673582212202e20c1d0062b5a698d49624edce72a713b117e88f4cd70877869b53519c1d1f964736f6c63430007060033", - "deployedBytecode": "0x60806040526004361061004a5760003560e01c806313af4035146100545780636c5d4ad014610087578063893d20e81461013a5780639b0b0fda1461016b578063aaf10f421461019b575b6100526101b0565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661036c565b34801561009357600080fd5b50610052600480360360208110156100aa57600080fd5b8101906020810181356401000000008111156100c557600080fd5b8201836020820111156100d757600080fd5b803590602001918460018302840111640100000000831117156100f957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103af945050505050565b34801561014657600080fd5b5061014f610505565b604080516001600160a01b039092168252519081900360200190f35b34801561017757600080fd5b506100526004803603604081101561018e57600080fd5b508035906020013561054b565b3480156101a757600080fd5b5061014f610589565b60006101ba6105bd565b60408051600481526024810182526020810180516001600160e01b0316635bca393160e11b1781529151815193945060009384936001600160a01b0387169392918291908083835b602083106102215780518252601f199092019160209182019101610202565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114610281576040519150601f19603f3d011682016040523d82523d6000602084013e610286565b606091505b5091509150818015610299575080516020145b156102f85760008180602001905160208110156102b557600080fd5b5051905080156102f65760405162461bcd60e51b81526004018080602001828103825260358152602001806106b76035913960400191505060405180910390fd5b505b60006103026105e2565b90506001600160a01b0381166103495760405162461bcd60e51b81526004018080602001828103825260308152602001806106546030913960400191505060405180910390fd5b3660008037600080366000845af43d6000803e80610366573d6000fd5b503d6000f35b6103746105bd565b6001600160a01b0316336001600160a01b03161480610391575033155b156103a45761039f81610607565b6103ac565b6103ac6101b0565b50565b6103b76105bd565b6001600160a01b0316336001600160a01b031614806103d4575033155b156103a45760006103e36105e2565b90506103ee8161062b565b825160208401201415610401575061039f565b60006c600d380380600d6000396000f360981b83604051602001808372ffffffffffffffffffffffffffffffffffffff19168152600d0182805190602001908083835b602083106104635780518252601f199092019160209182019101610444565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052905060008151602083016000f0905083805190602001206104b88261062b565b146104f45760405162461bcd60e51b81526004018080602001828103825260338152602001806106846033913960400191505060405180910390fd5b6104fd8161062f565b5050506103ac565b600061050f6105bd565b6001600160a01b0316336001600160a01b0316148061052c575033155b15610540576105396105bd565b9050610548565b6105486101b0565b90565b6105536105bd565b6001600160a01b0316336001600160a01b03161480610570575033155b1561057d57808255610585565b6105856101b0565b5050565b60006105936105bd565b6001600160a01b0316336001600160a01b031614806105b0575033155b15610540576105396105e2565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b3f90565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5556fe4c314368756753706c61736850726f78793a20696d706c656d656e746174696f6e206973206e6f7420736574207965744c314368756753706c61736850726f78793a20636f646520776173206e6f7420636f72726563746c79206465706c6f7965642e4c314368756753706c61736850726f78793a2073797374656d2069732063757272656e746c79206265696e67207570677261646564a26469706673582212202e20c1d0062b5a698d49624edce72a713b117e88f4cd70877869b53519c1d1f964736f6c63430007060033", - "devdoc": { - "details": "Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!", - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_owner": "Address of the initial contract owner." - } - }, - "getImplementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "getOwner()": { - "returns": { - "_0": "Owner address." - } - }, - "setCode(bytes)": { - "params": { - "_code": "New contract code to run inside this contract." - } - }, - "setOwner(address)": { - "params": { - "_owner": "New owner of the proxy contract." - } - }, - "setStorage(bytes32,bytes32)": { - "params": { - "_key": "Storage key to modify.", - "_value": "New value for the storage key." - } - } - }, - "title": "L1ChugSplashProxy", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "getImplementation()": { - "notice": "Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)." - }, - "getOwner()": { - "notice": "Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)." - }, - "setCode(bytes)": { - "notice": "Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner." - }, - "setOwner(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "setStorage(bytes32,bytes32)": { - "notice": "Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner." - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/L2OutputOracle.json b/packages/contracts-bedrock/deployments/mainnet/L2OutputOracle.json deleted file mode 100644 index ae9da3da298d..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/L2OutputOracle.json +++ /dev/null @@ -1,817 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "uint256", - "name": "_submissionInterval", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_l2BlockTime", - "type": "uint256" - }, - { - "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": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "l2OutputIndex", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "l2BlockNumber", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "l1Timestamp", - "type": "uint256" - } - ], - "name": "OutputProposed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "prevNextOutputIndex", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "newNextOutputIndex", - "type": "uint256" - } - ], - "name": "OutputsDeleted", - "type": "event" - }, - { - "inputs": [], - "name": "CHALLENGER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "FINALIZATION_PERIOD_SECONDS", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_BLOCK_TIME", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PROPOSER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SUBMISSION_INTERVAL", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "challenger", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - } - ], - "name": "computeL2Timestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - } - ], - "name": "deleteL2Outputs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "finalizationPeriodSeconds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - } - ], - "name": "getL2Output", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint128", - "name": "timestamp", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "l2BlockNumber", - "type": "uint128" - } - ], - "internalType": "struct Types.OutputProposal", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - } - ], - "name": "getL2OutputAfter", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint128", - "name": "timestamp", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "l2BlockNumber", - "type": "uint128" - } - ], - "internalType": "struct Types.OutputProposal", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - } - ], - "name": "getL2OutputIndexAfter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_startingBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_startingTimestamp", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_proposer", - "type": "address" - }, - { - "internalType": "address", - "name": "_challenger", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l2BlockTime", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "latestBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "latestOutputIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nextBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nextOutputIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_l1BlockHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_l1BlockNumber", - "type": "uint256" - } - ], - "name": "proposeL2Output", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "proposer", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "startingBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "startingTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "submissionInterval", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0xB48B1827BC7218b1aB7B000b4f0416DF8F14B16A", - "args": [], - "bytecode": "0x60e06040523480156200001157600080fd5b50604051620018ae380380620018ae8339810160408190526200003491620002f3565b60008211620000b05760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e203000000000000000000000000060648201526084015b60405180910390fd5b60008311620001285760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e20300000000000006064820152608401620000a7565b608083905260a082905260c08190526200014660008080806200014f565b50505062000322565b600054600390610100900460ff1615801562000172575060005460ff8083169116105b620001d75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000a7565b6000805461ffff191660ff83161761010017905542841115620002715760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401620000a7565b60028490556001859055600580546001600160a01b038581166001600160a01b03199283161790925560048054928516929091169190911790556000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6000806000606084860312156200030957600080fd5b8351925060208401519150604084015190509250925092565b60805160a05160c0516115326200037c600039600081816104b3015281816105710152610beb0152600081816101a1015281816103b9015261127401526000818161021f0152818161053b01526112c201526115326000f3fe60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec334814610517578063e1a41bcf1461052c578063f4daa2911461055f57600080fd5b8063ce5db8d6146104a4578063cf8e5cf0146104d7578063d1de856c146104f757600080fd5b8063a25ae557116100b0578063a25ae557146103f0578063a8e4fb901461044c578063bffa7f0f1461047957600080fd5b806389c44cbb1461038a57806393991af3146103aa5780639aaab648146103dd57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa51461033e5780637f00642014610354578063887862721461037457600080fd5b806369f16eec146102e95780636abcf563146102fe5780636b4d98dd1461031357600080fd5b8063529933df11610169578063529933df1461020d578063534db0e21461024157806354fd4d501461029357600080fd5b80622134cc1461018f578063019e2729146101d65780634599c788146101f8575b600080fd5b34801561019b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101e257600080fd5b506101f66101f136600461131c565b610593565b005b34801561020457600080fd5b506101c36107f2565b34801561021957600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561024d57600080fd5b5060045461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cd565b34801561029f57600080fd5b506102dc6040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101cd9190611362565b3480156102f557600080fd5b506101c3610865565b34801561030a57600080fd5b506003546101c3565b34801561031f57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1661026e565b34801561034a57600080fd5b506101c360015481565b34801561036057600080fd5b506101c361036f3660046113d5565b610877565b34801561038057600080fd5b506101c360025481565b34801561039657600080fd5b506101f66103a53660046113d5565b610a8b565b3480156103b657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b6101f66103eb3660046113ee565b610d43565b3480156103fc57600080fd5b5061041061040b3660046113d5565b6111a4565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101cd565b34801561045857600080fd5b5060055461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561048557600080fd5b5060055473ffffffffffffffffffffffffffffffffffffffff1661026e565b3480156104b057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b3480156104e357600080fd5b506104106104f23660046113d5565b611238565b34801561050357600080fd5b506101c36105123660046113d5565b611270565b34801561052357600080fd5b506101c36112be565b34801561053857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b34801561056b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b600054600390610100900460ff161580156105b5575060005460ff8083169116105b610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790554284111561072e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161063d565b600284905560018590556005805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556004805492851692909116919091179055600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6003546000901561085c576003805461080d9060019061144f565b8154811061081d5761081d611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b6003546000906108609060019061144f565b60006108816107f2565b821115610936576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546109eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546000905b80821015610a845760006002610a088385611495565b610a1291906114ad565b90508460038281548110610a2857610a28611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610a7a57610a73816001611495565b9250610a7e565b8091505b506109f2565b5092915050565b60045473ffffffffffffffffffffffffffffffffffffffff163314610b32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161063d565b6003548110610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b7f000000000000000000000000000000000000000000000000000000000000000060038281548110610c1d57610c1d611466565b6000918252602090912060016002909202010154610c4d906fffffffffffffffffffffffffffffffff164261144f565b10610d00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161063d565b6000610d0b60035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60055473ffffffffffffffffffffffffffffffffffffffff163314610e10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b610e186112be565b8314610ecc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161063d565b42610ed684611270565b10610f63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161063d565b83610ff0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161063d565b81156110ac57818140146110ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161063d565b826110b660035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2426040516110e891815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b6040805160608101825260008082526020820181905291810191909152600382815481106111d4576111d4611466565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b6040805160608101825260008082526020820181905291810191909152600361126083610877565b815481106111d4576111d4611466565b60007f0000000000000000000000000000000000000000000000000000000000000000600154836112a1919061144f565b6112ab91906114e8565b6002546112b89190611495565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006112e96107f2565b6108609190611495565b803573ffffffffffffffffffffffffffffffffffffffff8116811461131757600080fd5b919050565b6000806000806080858703121561133257600080fd5b8435935060208501359250611349604086016112f3565b9150611357606086016112f3565b905092959194509250565b600060208083528351808285015260005b8181101561138f57858101830151858201604001528201611373565b818111156113a1576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156113e757600080fd5b5035919050565b6000806000806080858703121561140457600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561146157611461611420565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082198211156114a8576114a8611420565b500190565b6000826114e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561152057611520611420565b50029056fea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec334814610517578063e1a41bcf1461052c578063f4daa2911461055f57600080fd5b8063ce5db8d6146104a4578063cf8e5cf0146104d7578063d1de856c146104f757600080fd5b8063a25ae557116100b0578063a25ae557146103f0578063a8e4fb901461044c578063bffa7f0f1461047957600080fd5b806389c44cbb1461038a57806393991af3146103aa5780639aaab648146103dd57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa51461033e5780637f00642014610354578063887862721461037457600080fd5b806369f16eec146102e95780636abcf563146102fe5780636b4d98dd1461031357600080fd5b8063529933df11610169578063529933df1461020d578063534db0e21461024157806354fd4d501461029357600080fd5b80622134cc1461018f578063019e2729146101d65780634599c788146101f8575b600080fd5b34801561019b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101e257600080fd5b506101f66101f136600461131c565b610593565b005b34801561020457600080fd5b506101c36107f2565b34801561021957600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561024d57600080fd5b5060045461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cd565b34801561029f57600080fd5b506102dc6040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101cd9190611362565b3480156102f557600080fd5b506101c3610865565b34801561030a57600080fd5b506003546101c3565b34801561031f57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1661026e565b34801561034a57600080fd5b506101c360015481565b34801561036057600080fd5b506101c361036f3660046113d5565b610877565b34801561038057600080fd5b506101c360025481565b34801561039657600080fd5b506101f66103a53660046113d5565b610a8b565b3480156103b657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b6101f66103eb3660046113ee565b610d43565b3480156103fc57600080fd5b5061041061040b3660046113d5565b6111a4565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101cd565b34801561045857600080fd5b5060055461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561048557600080fd5b5060055473ffffffffffffffffffffffffffffffffffffffff1661026e565b3480156104b057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b3480156104e357600080fd5b506104106104f23660046113d5565b611238565b34801561050357600080fd5b506101c36105123660046113d5565b611270565b34801561052357600080fd5b506101c36112be565b34801561053857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b34801561056b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b600054600390610100900460ff161580156105b5575060005460ff8083169116105b610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790554284111561072e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161063d565b600284905560018590556005805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556004805492851692909116919091179055600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6003546000901561085c576003805461080d9060019061144f565b8154811061081d5761081d611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b6003546000906108609060019061144f565b60006108816107f2565b821115610936576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546109eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546000905b80821015610a845760006002610a088385611495565b610a1291906114ad565b90508460038281548110610a2857610a28611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610a7a57610a73816001611495565b9250610a7e565b8091505b506109f2565b5092915050565b60045473ffffffffffffffffffffffffffffffffffffffff163314610b32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161063d565b6003548110610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b7f000000000000000000000000000000000000000000000000000000000000000060038281548110610c1d57610c1d611466565b6000918252602090912060016002909202010154610c4d906fffffffffffffffffffffffffffffffff164261144f565b10610d00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161063d565b6000610d0b60035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60055473ffffffffffffffffffffffffffffffffffffffff163314610e10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b610e186112be565b8314610ecc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161063d565b42610ed684611270565b10610f63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161063d565b83610ff0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161063d565b81156110ac57818140146110ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161063d565b826110b660035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2426040516110e891815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b6040805160608101825260008082526020820181905291810191909152600382815481106111d4576111d4611466565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b6040805160608101825260008082526020820181905291810191909152600361126083610877565b815481106111d4576111d4611466565b60007f0000000000000000000000000000000000000000000000000000000000000000600154836112a1919061144f565b6112ab91906114e8565b6002546112b89190611495565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006112e96107f2565b6108609190611495565b803573ffffffffffffffffffffffffffffffffffffffff8116811461131757600080fd5b919050565b6000806000806080858703121561133257600080fd5b8435935060208501359250611349604086016112f3565b9150611357606086016112f3565b905092959194509250565b600060208083528351808285015260005b8181101561138f57858101830151858201604001528201611373565b818111156113a1576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156113e757600080fd5b5035919050565b6000806000806080858703121561140457600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561146157611461611420565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082198211156114a8576114a8611420565b500190565b6000826114e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561152057611520611420565b50029056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "CHALLENGER()": {}, - "PROPOSER()": {}, - "computeL2Timestamp(uint256)": { - "params": { - "_l2BlockNumber": "The L2 block number of the target block." - }, - "returns": { - "_0": "L2 timestamp of the given block." - } - }, - "constructor": { - "params": { - "_finalizationPeriodSeconds": "The amount of time that must pass for an output proposal", - "_l2BlockTime": "The time per L2 block, in seconds.", - "_submissionInterval": "Interval in blocks at which checkpoints must be submitted." - } - }, - "deleteL2Outputs(uint256)": { - "params": { - "_l2OutputIndex": "Index of the first L2 output to be deleted. All outputs after this output will also be deleted." - } - }, - "getL2Output(uint256)": { - "params": { - "_l2OutputIndex": "Index of the output to return." - }, - "returns": { - "_0": "The output at the given index." - } - }, - "getL2OutputAfter(uint256)": { - "params": { - "_l2BlockNumber": "L2 block number to find a checkpoint for." - }, - "returns": { - "_0": "First checkpoint that commits to the given L2 block number." - } - }, - "getL2OutputIndexAfter(uint256)": { - "params": { - "_l2BlockNumber": "L2 block number to find a checkpoint for." - }, - "returns": { - "_0": "Index of the first checkpoint that commits to the given L2 block number." - } - }, - "initialize(uint256,uint256,address,address)": { - "params": { - "_challenger": "The address of the challenger.", - "_proposer": "The address of the proposer.", - "_startingBlockNumber": "Block number for the first recoded L2 block.", - "_startingTimestamp": "Timestamp for the first recoded L2 block." - } - }, - "latestBlockNumber()": { - "returns": { - "_0": "Latest submitted L2 block number." - } - }, - "latestOutputIndex()": { - "returns": { - "_0": "The number of outputs that have been proposed." - } - }, - "nextBlockNumber()": { - "returns": { - "_0": "Next L2 block number." - } - }, - "nextOutputIndex()": { - "returns": { - "_0": "The index of the next output to be proposed." - } - }, - "proposeL2Output(bytes32,uint256,bytes32,uint256)": { - "params": { - "_l1BlockHash": "A block hash which must be included in the current chain.", - "_l1BlockNumber": "The block number with the specified block hash.", - "_l2BlockNumber": "The L2 block number that resulted in _outputRoot.", - "_outputRoot": "The L2 output of the checkpoint block." - } - } - }, - "events": { - "OutputProposed(bytes32,uint256,uint256,uint256)": { - "params": { - "l1Timestamp": "The L1 timestamp when proposed.", - "l2BlockNumber": "The L2 block number of the output root.", - "l2OutputIndex": "The index of the output in the l2Outputs array.", - "outputRoot": "The output root." - } - }, - "OutputsDeleted(uint256,uint256)": { - "params": { - "newNextOutputIndex": "Next L2 output index after the deletion.", - "prevNextOutputIndex": "Next L2 output index before the deletion." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_submissionInterval\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_finalizationPeriodSeconds\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"l2OutputIndex\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"l2BlockNumber\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"l1Timestamp\",\"type\":\"uint256\",\"indexed\":false}],\"type\":\"event\",\"name\":\"OutputProposed\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"prevNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"newNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OutputsDeleted\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"CHALLENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L2_BLOCK_TIME\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"PROPOSER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"challenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"computeL2Timestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"deleteL2Outputs\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"finalizationPeriodSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getL2Output\",\"outputs\":[{\"internalType\":\"struct Types.OutputProposal\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}]}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getL2OutputAfter\",\"outputs\":[{\"internalType\":\"struct Types.OutputProposal\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}]}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getL2OutputIndexAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_proposer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_challenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2BlockTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"latestBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"latestOutputIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"nextBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"nextOutputIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1BlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"proposeL2Output\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"proposer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"startingBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"startingTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"submissionInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"CHALLENGER()\":{\"custom:legacy\":\"\"},\"PROPOSER()\":{\"custom:legacy\":\"\"},\"computeL2Timestamp(uint256)\":{\"params\":{\"_l2BlockNumber\":\"The L2 block number of the target block.\"},\"returns\":{\"_0\":\"L2 timestamp of the given block.\"}},\"constructor\":{\"params\":{\"_finalizationPeriodSeconds\":\"The amount of time that must pass for an output proposal\",\"_l2BlockTime\":\"The time per L2 block, in seconds.\",\"_submissionInterval\":\"Interval in blocks at which checkpoints must be submitted.\"}},\"deleteL2Outputs(uint256)\":{\"params\":{\"_l2OutputIndex\":\"Index of the first L2 output to be deleted. All outputs after this output will also be deleted.\"}},\"getL2Output(uint256)\":{\"params\":{\"_l2OutputIndex\":\"Index of the output to return.\"},\"returns\":{\"_0\":\"The output at the given index.\"}},\"getL2OutputAfter(uint256)\":{\"params\":{\"_l2BlockNumber\":\"L2 block number to find a checkpoint for.\"},\"returns\":{\"_0\":\"First checkpoint that commits to the given L2 block number.\"}},\"getL2OutputIndexAfter(uint256)\":{\"params\":{\"_l2BlockNumber\":\"L2 block number to find a checkpoint for.\"},\"returns\":{\"_0\":\"Index of the first checkpoint that commits to the given L2 block number.\"}},\"initialize(uint256,uint256,address,address)\":{\"params\":{\"_challenger\":\"The address of the challenger.\",\"_proposer\":\"The address of the proposer.\",\"_startingBlockNumber\":\"Block number for the first recoded L2 block.\",\"_startingTimestamp\":\"Timestamp for the first recoded L2 block.\"}},\"latestBlockNumber()\":{\"returns\":{\"_0\":\"Latest submitted L2 block number.\"}},\"latestOutputIndex()\":{\"returns\":{\"_0\":\"The number of outputs that have been proposed.\"}},\"nextBlockNumber()\":{\"returns\":{\"_0\":\"Next L2 block number.\"}},\"nextOutputIndex()\":{\"returns\":{\"_0\":\"The index of the next output to be proposed.\"}},\"proposeL2Output(bytes32,uint256,bytes32,uint256)\":{\"params\":{\"_l1BlockHash\":\"A block hash which must be included in the current chain.\",\"_l1BlockNumber\":\"The block number with the specified block hash.\",\"_l2BlockNumber\":\"The L2 block number that resulted in _outputRoot.\",\"_outputRoot\":\"The L2 output of the checkpoint block.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"CHALLENGER()\":{\"notice\":\"Getter for the challenger address. This will be removed in the future, use `challenger` instead.\"},\"L2_BLOCK_TIME()\":{\"notice\":\"The time between L2 blocks in seconds. Once set, this value MUST NOT be modified. Public getter is legacy and will be removed in the future. Use `l2BlockTime` instead.\"},\"PROPOSER()\":{\"notice\":\"Getter for the proposer address. This will be removed in the future, use `proposer` instead.\"},\"SUBMISSION_INTERVAL()\":{\"notice\":\"The interval in L2 blocks at which checkpoints must be submitted. Although this is immutable, it can safely be modified by upgrading the implementation contract. Public getter is legacy and will be removed in the future. Use `submissionInterval` instead.\"},\"challenger()\":{\"notice\":\"The address of the challenger. Can be updated via reinitialize.\"},\"computeL2Timestamp(uint256)\":{\"notice\":\"Returns the L2 timestamp corresponding to a given L2 block number.\"},\"constructor\":{\"notice\":\"Constructs the L2OutputOracle contract.\"},\"deleteL2Outputs(uint256)\":{\"notice\":\"Deletes all output proposals after and including the proposal that corresponds to the given output index. Only the challenger address can delete outputs.\"},\"finalizationPeriodSeconds()\":{\"notice\":\"Getter for the finalization period.\"},\"getL2Output(uint256)\":{\"notice\":\"Returns an output by index. Needed to return a struct instead of a tuple.\"},\"getL2OutputAfter(uint256)\":{\"notice\":\"Returns the L2 output proposal that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block.\"},\"getL2OutputIndexAfter(uint256)\":{\"notice\":\"Returns the index of the L2 output that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block.\"},\"initialize(uint256,uint256,address,address)\":{\"notice\":\"Initializer.\"},\"l2BlockTime()\":{\"notice\":\"Getter for the L2 block time.\"},\"latestBlockNumber()\":{\"notice\":\"Returns the block number of the latest submitted L2 output proposal. If no proposals been submitted yet then this function will return the starting block number.\"},\"latestOutputIndex()\":{\"notice\":\"Returns the number of outputs that have been proposed. Will revert if no outputs have been proposed yet.\"},\"nextBlockNumber()\":{\"notice\":\"Computes the block number of the next L2 block that needs to be checkpointed.\"},\"nextOutputIndex()\":{\"notice\":\"Returns the index of the next output to be proposed.\"},\"proposeL2Output(bytes32,uint256,bytes32,uint256)\":{\"notice\":\"Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp must be equal to the current value returned by `nextTimestamp()` in order to be accepted. This function may only be called by the Proposer.\"},\"proposer()\":{\"notice\":\"The address of the proposer. Can be updated via reinitialize.\"},\"startingBlockNumber()\":{\"notice\":\"The number of the first L2 block recorded in this contract.\"},\"startingTimestamp()\":{\"notice\":\"The timestamp of the first L2 block recorded in this contract.\"},\"submissionInterval()\":{\"notice\":\"Getter for the output proposal submission interval.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L2OutputOracle.sol\":\"L2OutputOracle\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L2OutputOracle.sol\":{\"keccak256\":\"0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705\",\"urls\":[\"bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc\",\"dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 2, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 59334, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "startingBlockNumber", - "offset": 0, - "slot": "1", - "type": "t_uint256" - }, - { - "astId": 59337, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "startingTimestamp", - "offset": 0, - "slot": "2", - "type": "t_uint256" - }, - { - "astId": 59342, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "l2Outputs", - "offset": 0, - "slot": "3", - "type": "t_array(t_struct(OutputProposal)71073_storage)dyn_storage" - }, - { - "astId": 59345, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "challenger", - "offset": 0, - "slot": "4", - "type": "t_address" - }, - { - "astId": 59348, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "proposer", - "offset": 0, - "slot": "5", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_struct(OutputProposal)71073_storage)dyn_storage": { - "encoding": "dynamic_array", - "label": "struct Types.OutputProposal[]", - "numberOfBytes": "32", - "base": "t_struct(OutputProposal)71073_storage" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_struct(OutputProposal)71073_storage": { - "encoding": "inplace", - "label": "struct Types.OutputProposal", - "numberOfBytes": "64", - "members": [ - { - "astId": 71068, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "outputRoot", - "offset": 0, - "slot": "0", - "type": "t_bytes32" - }, - { - "astId": 71070, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "timestamp", - "offset": 0, - "slot": "1", - "type": "t_uint128" - }, - { - "astId": 71072, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "l2BlockNumber", - "offset": 16, - "slot": "1", - "type": "t_uint128" - } - ] - }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x565a488c01592b4ff53ccc2c0a842f0975ac1957ac67358deffc5ca07b2640ef", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "CHALLENGER()": { - "notice": "Getter for the challenger address. This will be removed in the future, use `challenger` instead." - }, - "L2_BLOCK_TIME()": { - "notice": "The time between L2 blocks in seconds. Once set, this value MUST NOT be modified. Public getter is legacy and will be removed in the future. Use `l2BlockTime` instead." - }, - "PROPOSER()": { - "notice": "Getter for the proposer address. This will be removed in the future, use `proposer` instead." - }, - "SUBMISSION_INTERVAL()": { - "notice": "The interval in L2 blocks at which checkpoints must be submitted. Although this is immutable, it can safely be modified by upgrading the implementation contract. Public getter is legacy and will be removed in the future. Use `submissionInterval` instead." - }, - "challenger()": { - "notice": "The address of the challenger. Can be updated via reinitialize." - }, - "computeL2Timestamp(uint256)": { - "notice": "Returns the L2 timestamp corresponding to a given L2 block number." - }, - "constructor": { - "notice": "Constructs the L2OutputOracle contract." - }, - "deleteL2Outputs(uint256)": { - "notice": "Deletes all output proposals after and including the proposal that corresponds to the given output index. Only the challenger address can delete outputs." - }, - "finalizationPeriodSeconds()": { - "notice": "Getter for the finalization period." - }, - "getL2Output(uint256)": { - "notice": "Returns an output by index. Needed to return a struct instead of a tuple." - }, - "getL2OutputAfter(uint256)": { - "notice": "Returns the L2 output proposal that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block." - }, - "getL2OutputIndexAfter(uint256)": { - "notice": "Returns the index of the L2 output that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block." - }, - "initialize(uint256,uint256,address,address)": { - "notice": "Initializer." - }, - "l2BlockTime()": { - "notice": "Getter for the L2 block time." - }, - "latestBlockNumber()": { - "notice": "Returns the block number of the latest submitted L2 output proposal. If no proposals been submitted yet then this function will return the starting block number." - }, - "latestOutputIndex()": { - "notice": "Returns the number of outputs that have been proposed. Will revert if no outputs have been proposed yet." - }, - "nextBlockNumber()": { - "notice": "Computes the block number of the next L2 block that needs to be checkpointed." - }, - "nextOutputIndex()": { - "notice": "Returns the index of the next output to be proposed." - }, - "proposeL2Output(bytes32,uint256,bytes32,uint256)": { - "notice": "Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp must be equal to the current value returned by `nextTimestamp()` in order to be accepted. This function may only be called by the Proposer." - }, - "proposer()": { - "notice": "The address of the proposer. Can be updated via reinitialize." - }, - "startingBlockNumber()": { - "notice": "The number of the first L2 block recorded in this contract." - }, - "startingTimestamp()": { - "notice": "The timestamp of the first L2 block recorded in this contract." - }, - "submissionInterval()": { - "notice": "Getter for the output proposal submission interval." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "OutputProposed(bytes32,uint256,uint256,uint256)": { - "notice": "Emitted when an output is proposed." - }, - "OutputsDeleted(uint256,uint256)": { - "notice": "Emitted when outputs are deleted." - } - }, - "notice": "The L2OutputOracle contains an array of L2 state outputs, where each output is a commitment to the state of the L2 chain. Other contracts like the OptimismPortal use these outputs to verify information about the state of L2." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/L2OutputOracleProxy.json b/packages/contracts-bedrock/deployments/mainnet/L2OutputOracleProxy.json deleted file mode 100644 index e0b918270152..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/L2OutputOracleProxy.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0xdfe97868233d1aa22e815a266982f2cf17685a27", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x615bd360561ef00aff4b75adda59f04e792a2f0f17d518d4906a892cf677b5ed", - "receipt": { - "to": null, - "from": "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960", - "contractAddress": "0xdfe97868233d1aa22e815a266982f2cf17685a27", - "transactionIndex": 90, - "gasUsed": "523960", - "logsBloom": "0x00000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000001000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xde6e8af7a3ffcf7716ac9153f6b44c92945f293cb0b6c5decf66ff6d1050ccae", - "transactionHash": "0x615bd360561ef00aff4b75adda59f04e792a2f0f17d518d4906a892cf677b5ed", - "logs": [ - { - "transactionIndex": 90, - "blockNumber": 17365801, - "transactionHash": "0x615bd360561ef00aff4b75adda59f04e792a2f0f17d518d4906a892cf677b5ed", - "address": "0xdfe97868233d1aa22e815a266982f2cf17685a27", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000543ba4aadbab8f9025686bd03993043599c6fb04", - "logIndex": 271, - "blockHash": "0xde6e8af7a3ffcf7716ac9153f6b44c92945f293cb0b6c5decf66ff6d1050ccae" - } - ], - "blockNumber": 17365801, - "cumulativeGasUsed": "9803453", - "status": 1, - "byzantium": true - }, - "args": [ - "0x543bA4AADBAb8f9025686Bd03993043599c6fB04" - ], - "numDeployments": 1, - "solcInputHash": "13ac93d026822f719ad110af836d1582", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33b903585eb9cfc60a70bcdf4ee44220b173caff16dfb9071cd0668c7a551265\",\"dweb:/ipfs/QmXHUZ9brinN1WS9i63ocRQsQidY96WePDBhBsFRhDmVjr\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/OptimismMintableERC20Factory.json b/packages/contracts-bedrock/deployments/mainnet/OptimismMintableERC20Factory.json deleted file mode 100644 index f68bcda2b225..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/OptimismMintableERC20Factory.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "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": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "deployer", - "type": "address" - } - ], - "name": "OptimismMintableERC20Created", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - } - ], - "name": "StandardL2TokenCreated", - "type": "event" - }, - { - "inputs": [], - "name": "BRIDGE", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "bridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createOptimismMintableERC20", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "uint8", - "name": "_decimals", - "type": "uint8" - } - ], - "name": "createOptimismMintableERC20WithDecimals", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createStandardL2Token", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_bridge", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x373B66bd178cb2716D5A9596B1a42Ed39b87A535", - "args": [], - "bytecode": "0x608060405234801561001057600080fd5b5061001b6000610020565b610118565b600054600390610100900460ff16158015610042575060005460ff8083169116105b6100a95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805461010060ff841661ffff19909216821717610100600160b01b03191661ff0019620100006001600160a01b0387160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6123cf806101276000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b611ad880620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe6101406040523480156200001257600080fd5b5060405162001ad838038062001ad8833981016040819052620000359162000178565b600160026000858560036200004b8382620002b3565b5060046200005a8282620002b3565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037f565b80516001600160a01b0381168114620000a657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d357600080fd5b81516001600160401b0380821115620000f057620000f0620000ab565b604051601f8301601f19908116603f011681019082821181831017156200011b576200011b620000ab565b816040528381526020925086838588010111156200013857600080fd5b600091505b838210156200015c57858201830151818301840152908201906200013d565b838211156200016e5760008385830101525b9695505050505050565b600080600080600060a086880312156200019157600080fd5b6200019c866200008e565b9450620001ac602087016200008e565b60408701519094506001600160401b0380821115620001ca57600080fd5b620001d889838a01620000c1565b94506060880151915080821115620001ef57600080fd5b50620001fe88828901620000c1565b925050608086015160ff811681146200021657600080fd5b809150509295509295909350565b600181811c908216806200023957607f821691505b6020821081036200025a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ae57600081815260208120601f850160051c81016020861015620002895750805b601f850160051c820191505b81811015620002aa5782815560010162000295565b5050505b505050565b81516001600160401b03811115620002cf57620002cf620000ab565b620002e781620002e0845462000224565b8462000260565b602080601f8311600181146200031f5760008415620003065750858301515b600019600386901b1c1916600185901b178555620002aa565b600085815260208120601f198616915b8281101562000350578886015182559484019460019091019084016200032f565b50858210156200036f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003eb6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", - "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b611ad880620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe6101406040523480156200001257600080fd5b5060405162001ad838038062001ad8833981016040819052620000359162000178565b600160026000858560036200004b8382620002b3565b5060046200005a8282620002b3565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037f565b80516001600160a01b0381168114620000a657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d357600080fd5b81516001600160401b0380821115620000f057620000f0620000ab565b604051601f8301601f19908116603f011681019082821181831017156200011b576200011b620000ab565b816040528381526020925086838588010111156200013857600080fd5b600091505b838210156200015c57858201830151818301840152908201906200013d565b838211156200016e5760008385830101525b9695505050505050565b600080600080600060a086880312156200019157600080fd5b6200019c866200008e565b9450620001ac602087016200008e565b60408701519094506001600160401b0380821115620001ca57600080fd5b620001d889838a01620000c1565b94506060880151915080821115620001ef57600080fd5b50620001fe88828901620000c1565b925050608086015160ff811681146200021657600080fd5b809150509295509295909350565b600181811c908216806200023957607f821691505b6020821081036200025a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ae57600081815260208120601f850160051c81016020861015620002895750805b601f850160051c820191505b81811015620002aa5782815560010162000295565b5050505b505050565b81516001600160401b03811115620002cf57620002cf620000ab565b620002e781620002e0845462000224565b8462000260565b602080601f8311600181146200031f5760008415620003065750858301515b600019600386901b1c1916600185901b178555620002aa565b600085815260208120601f198616915b8281101562000350578886015182559484019460019091019084016200032f565b50858210156200036f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003eb6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "BRIDGE()": {}, - "createOptimismMintableERC20(address,string,string)": { - "params": { - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "createOptimismMintableERC20WithDecimals(address,string,string,uint8)": { - "params": { - "_decimals": "ERC20 decimals", - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "createStandardL2Token(address,string,string)": { - "params": { - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "initialize(address)": { - "params": { - "_bridge": "Address of the StandardBridge on this chain." - } - } - }, - "events": { - "OptimismMintableERC20Created(address,address,address)": { - "params": { - "deployer": "Address of the account that deployed the token.", - "localToken": "Address of the created token on the local chain.", - "remoteToken": "Address of the corresponding token on the remote chain." - } - }, - "StandardL2TokenCreated(address,address)": { - "params": { - "localToken": "Address of the created token on the local chain.", - "remoteToken": "Address of the token on the remote chain." - } - } - }, - "title": "OptimismMintableERC20Factory" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"OptimismMintableERC20Created\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"StandardL2TokenCreated\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"createOptimismMintableERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"_decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"createOptimismMintableERC20WithDecimals\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"createStandardL2Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"BRIDGE()\":{\"custom:legacy\":\"\"},\"createOptimismMintableERC20(address,string,string)\":{\"params\":{\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"createOptimismMintableERC20WithDecimals(address,string,string,uint8)\":{\"params\":{\"_decimals\":\"ERC20 decimals\",\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"createStandardL2Token(address,string,string)\":{\"custom:legacy\":\"@notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the newer createOptimismMintableERC20 function, which has a more intuitive name.\",\"params\":{\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"initialize(address)\":{\"params\":{\"_bridge\":\"Address of the StandardBridge on this chain.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BRIDGE()\":{\"notice\":\"Returns the address of the StandardBridge on this chain. This is a legacy getter, use `bridge` instead.\"},\"bridge()\":{\"notice\":\"Address of the StandardBridge on this chain.\"},\"constructor\":{\"notice\":\"The semver MUST be bumped any time that there is a change in the OptimismMintableERC20 token contract since this contract is responsible for deploying OptimismMintableERC20 contracts.\"},\"createOptimismMintableERC20(address,string,string)\":{\"notice\":\"Creates an instance of the OptimismMintableERC20 contract.\"},\"createOptimismMintableERC20WithDecimals(address,string,string,uint8)\":{\"notice\":\"Creates an instance of the OptimismMintableERC20 contract, with specified decimals.\"},\"initialize(address)\":{\"notice\":\"Initializer.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/OptimismMintableERC20Factory.sol\":\"OptimismMintableERC20Factory\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x6f8133b39efcbcbd5088f195dfacf1bedc3146508429c3865443909af735a04c\",\"urls\":[\"bzz-raw://adc36971e2e120458769f050428d9d2b0504516660345020c2521ee46e6d8abf\",\"dweb:/ipfs/QmPbFusQkZgGKpU8Fv5JoqL4oVeJtM3yqnhRGLY9eZT5zZ\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x39af021e492020fbeb5401371010d4a2fb69debe9596dbbead7bcd7fae248b0b\",\"urls\":[\"bzz-raw://dbeea52e586d2d7de55491a660ca76f75167ba6b43b65d29564864ee9c34a174\",\"dweb:/ipfs/QmS23vFqQxyUXhGuV1nSowZZS93CUkSnsb41uuyRtSeAED\"],\"license\":\"MIT\"},\"src/universal/OptimismMintableERC20Factory.sol\":{\"keccak256\":\"0x60862069899142dc4803d5f5754fd22339980bf74cfc4e2573bb59ff88a99c69\",\"urls\":[\"bzz-raw://8018f9fb11105ab80d4d6fb0bceabf8435d20d0883efa95070ae9e9983e3895c\",\"dweb:/ipfs/Qmf2ghxThySJA1pRvZfj3Q9yJwAZHSxwXAV9GDEqXxEWY9\"],\"license\":\"MIT\"},\"src/universal/Semver.sol\":{\"keccak256\":\"0x9de68ce536aee1aa616b4bf88d7ccc335460e6edd0e7170bdbf94c4fe3d41c60\",\"urls\":[\"bzz-raw://d5909c0b049b03a2bc24816ecf15b0aaf18c04a963174e1eba7624321bef330d\",\"dweb:/ipfs/QmeqdutwZWHqQMXauNR6WY8PrUpfsTiWTQyanbnGM9QqzT\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 2, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 76303, - "contract": "src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory", - "label": "bridge", - "offset": 2, - "slot": "0", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0xeebcd491eb8713084bb8faecbce88997f5e83b0b17fc49247a74fac89e5cb361", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "BRIDGE()": { - "notice": "Returns the address of the StandardBridge on this chain. This is a legacy getter, use `bridge` instead." - }, - "bridge()": { - "notice": "Address of the StandardBridge on this chain." - }, - "constructor": { - "notice": "The semver MUST be bumped any time that there is a change in the OptimismMintableERC20 token contract since this contract is responsible for deploying OptimismMintableERC20 contracts." - }, - "createOptimismMintableERC20(address,string,string)": { - "notice": "Creates an instance of the OptimismMintableERC20 contract." - }, - "createOptimismMintableERC20WithDecimals(address,string,string,uint8)": { - "notice": "Creates an instance of the OptimismMintableERC20 contract, with specified decimals." - }, - "initialize(address)": { - "notice": "Initializer." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "OptimismMintableERC20Created(address,address,address)": { - "notice": "Emitted whenever a new OptimismMintableERC20 is created." - } - }, - "notice": "OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20 contracts on the network it's deployed to. Simplifies the deployment process for users who may be less familiar with deploying smart contracts. Designed to be backwards compatible with the older StandardL2ERC20Factory contract." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/OptimismMintableERC20FactoryProxy.json b/packages/contracts-bedrock/deployments/mainnet/OptimismMintableERC20FactoryProxy.json deleted file mode 100644 index c52844b225ad..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/OptimismMintableERC20FactoryProxy.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0x75505a97BD334E7BD3C476893285569C4136Fa0F", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x4c2e632670c595a93c9c92fe2c0154130c5e3869758ba1c2119274f44280bb59", - "receipt": { - "to": null, - "from": "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960", - "contractAddress": "0x75505a97BD334E7BD3C476893285569C4136Fa0F", - "transactionIndex": 102, - "gasUsed": "523960", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000100000000000000000020000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x21734904e880a46f858627a4ac837db2f58e61c30a3669e001ff6fdde604ccf5", - "transactionHash": "0x4c2e632670c595a93c9c92fe2c0154130c5e3869758ba1c2119274f44280bb59", - "logs": [ - { - "transactionIndex": 102, - "blockNumber": 17365803, - "transactionHash": "0x4c2e632670c595a93c9c92fe2c0154130c5e3869758ba1c2119274f44280bb59", - "address": "0x75505a97BD334E7BD3C476893285569C4136Fa0F", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000543ba4aadbab8f9025686bd03993043599c6fb04", - "logIndex": 293, - "blockHash": "0x21734904e880a46f858627a4ac837db2f58e61c30a3669e001ff6fdde604ccf5" - } - ], - "blockNumber": 17365803, - "cumulativeGasUsed": "13364850", - "status": 1, - "byzantium": true - }, - "args": [ - "0x543bA4AADBAb8f9025686Bd03993043599c6fB04" - ], - "numDeployments": 1, - "solcInputHash": "13ac93d026822f719ad110af836d1582", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33b903585eb9cfc60a70bcdf4ee44220b173caff16dfb9071cd0668c7a551265\",\"dweb:/ipfs/QmXHUZ9brinN1WS9i63ocRQsQidY96WePDBhBsFRhDmVjr\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/OptimismPortal.json b/packages/contracts-bedrock/deployments/mainnet/OptimismPortal.json deleted file mode 100644 index 501d0716fffc..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/OptimismPortal.json +++ /dev/null @@ -1,970 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Paused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "version", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "opaqueData", - "type": "bytes" - } - ], - "name": "TransactionDeposited", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Unpaused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "withdrawalHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "name": "WithdrawalFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "withdrawalHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "WithdrawalProven", - "type": "event" - }, - { - "inputs": [], - "name": "GUARDIAN", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_ORACLE", - "outputs": [ - { - "internalType": "contract L2OutputOracle", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SYSTEM_CONFIG", - "outputs": [ - { - "internalType": "contract SystemConfig", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "_isCreation", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "depositTransaction", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "donateETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "internalType": "struct Types.WithdrawalTransaction", - "name": "_tx", - "type": "tuple" - } - ], - "name": "finalizeWithdrawalTransaction", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "finalizedWithdrawals", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "guardian", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract L2OutputOracle", - "name": "_l2Oracle", - "type": "address" - }, - { - "internalType": "address", - "name": "_guardian", - "type": "address" - }, - { - "internalType": "contract SystemConfig", - "name": "_systemConfig", - "type": "address" - }, - { - "internalType": "bool", - "name": "_paused", - "type": "bool" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - } - ], - "name": "isOutputFinalized", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l2Oracle", - "outputs": [ - { - "internalType": "contract L2OutputOracle", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l2Sender", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "_byteCount", - "type": "uint64" - } - ], - "name": "minimumGasLimit", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "params", - "outputs": [ - { - "internalType": "uint128", - "name": "prevBaseFee", - "type": "uint128" - }, - { - "internalType": "uint64", - "name": "prevBoughtGas", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "prevBlockNum", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "paused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "internalType": "struct Types.WithdrawalTransaction", - "name": "_tx", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "version", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "stateRoot", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "messagePasserStorageRoot", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "latestBlockhash", - "type": "bytes32" - } - ], - "internalType": "struct Types.OutputRootProof", - "name": "_outputRootProof", - "type": "tuple" - }, - { - "internalType": "bytes[]", - "name": "_withdrawalProof", - "type": "bytes[]" - } - ], - "name": "proveWithdrawalTransaction", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "provenWithdrawals", - "outputs": [ - { - "internalType": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint128", - "name": "timestamp", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "l2OutputIndex", - "type": "uint128" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "systemConfig", - "outputs": [ - { - "internalType": "contract SystemConfig", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "unpause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0xD14AA6C7B6D92803F3910Ec1DADCCd0757341862", - "args": [], - "bytecode": "0x60806040523480156200001157600080fd5b506200002260008080600162000028565b62000224565b600054600390610100900460ff161580156200004b575060005460ff8083169116105b620000b45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100908117909155603280546001600160a01b031990811661dead1790915560358054603680546001600160a01b0389811691861691909117909155603780548a831695169490941790935585151592891690930260ff19166001600160a81b0319909316929092171790556200013962000181565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600054610100900460ff16620001ee5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b61545c80620002346000396000f3fe60806040526004361061016d5760003560e01c80638b4c40b0116100cb578063a35d99df1161007f578063e9e05c4211610059578063e9e05c4214610573578063f049875014610586578063fecf9734146105b157600080fd5b8063a35d99df1461040d578063cff0ab9614610446578063e965084c146104e757600080fd5b80639b5f694a116100b05780639b5f694a1461037e5780639bf62d82146103b0578063a14238e7146103dd57600080fd5b80638b4c40b0146101925780638c3152e91461035e57600080fd5b806354fd4d50116101225780636dbffb78116101075780636dbffb78146102fe578063724c184c1461031e5780638456cb591461034957600080fd5b806354fd4d501461027e5780635c975abb146102d457600080fd5b80633f4ba83a116101535780633f4ba83a1461021c578063452a9320146102315780634870496f1461025e57600080fd5b80621c2ff61461019957806333d7e2bd146101ef57600080fd5b36610194576101923334620186a06000604051806020016040528060008152506105d1565b005b600080fd5b3480156101a557600080fd5b50603554610100900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101fb57600080fd5b506036546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022857600080fd5b5061019261086c565b34801561023d57600080fd5b506037546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026a57600080fd5b50610192610279366004614a4a565b610971565b34801561028a57600080fd5b506102c76040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b6040516101e69190614ba0565b3480156102e057600080fd5b506035546102ee9060ff1681565b60405190151581526020016101e6565b34801561030a57600080fd5b506102ee610319366004614bb3565b610fa6565b34801561032a57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101c5565b34801561035557600080fd5b50610192611065565b34801561036a57600080fd5b50610192610379366004614bcc565b611167565b34801561038a57600080fd5b506035546101c590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103bc57600080fd5b506032546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e957600080fd5b506102ee6103f8366004614bb3565b60336020526000908152604090205460ff1681565b34801561041957600080fd5b5061042d610428366004614c26565b611a2b565b60405167ffffffffffffffff90911681526020016101e6565b34801561045257600080fd5b506001546104ae906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101e6565b3480156104f357600080fd5b50610545610502366004614bb3565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101e6565b610192610581366004614c51565b6105d1565b34801561059257600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff166101c5565b3480156105bd57600080fd5b506101926105cc366004614ccc565b611a44565b8260005a905083156106885773ffffffffffffffffffffffffffffffffffffffff87161561068857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6106928351611a2b565b67ffffffffffffffff168567ffffffffffffffff161015610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161067f565b6201d4c0835111156107a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161067f565b333281146107c4575033731111000000000000000000000000000000001111015b600034888888886040516020016107df959493929190614d26565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161084f9190614ba0565b60405180910390a450506108638282611c52565b50505050505050565b60375473ffffffffffffffffffffffffffffffffffffffff163314610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e70617573650000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff16156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161067f565b6035546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101869052600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190614dab565b519050610b50610b4b36869003860186614e10565b611f7f565b8114610bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161067f565b6000610be987611fdb565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d035750805160355460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190614dab565b5114155b610d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161067f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610e589101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610e4e888a614e76565b8a6040013561200b565b610ee4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161067f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6035546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161105f9161010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190614dab565b602001516fffffffffffffffffffffffffffffffff1661202f565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff16331461110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20706175736500000000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610967565b60355460ff16156111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161067f565b600061128882611fdb565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161067f565b603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190614efa565b81602001516fffffffffffffffffffffffffffffffff1610156114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161067f565b6114ee81602001516fffffffffffffffffffffffffffffffff1661202f565b6115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60355460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff9091166004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561162c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116509190614dab565b825181519192501461170a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161067f565b61172981602001516fffffffffffffffffffffffffffffffff1661202f565b6117db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60008381526033602052604090205460ff161561187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161067f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161191c939291906120d4565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061198190841515815260200190565b60405180910390a2801580156119975750326001145b15611a24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161067f565b5050505050565b6000611a38826010614f42565b61105f90615208614f72565b600054600390610100900460ff16158015611a66575060005460ff8083169116105b611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100908117909155603280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811661dead17909155603580546036805473ffffffffffffffffffffffffffffffffffffffff89811691861691909117909155603780548a83169516949094179093558515159289169093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fffffffffffffffffffffff00000000000000000000000000000000000000000090931692909217179055611bed612132565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600154600090611c88907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9e565b90506000611c94612215565b90506000816020015160ff16826000015163ffffffff16611cb59190614fe4565b90508215611dec57600154600090611cec908390700100000000000000000000000000000000900467ffffffffffffffff1661504c565b90506000836040015160ff1683611d0391906150c0565b600154611d239084906fffffffffffffffffffffffffffffffff166150c0565b611d2d9190614fe4565b600154909150600090611d7e90611d579084906fffffffffffffffffffffffffffffffff1661517c565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166122db565b90506001861115611dad57611daa611d5782876040015160ff1660018a611da59190614f9e565b6122fa565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e1f908490700100000000000000000000000000000000900467ffffffffffffffff16614f72565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161067f565b600154600090611f2e906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166151f0565b90506000611f4048633b9aca0061234f565b611f4a908361522d565b905060005a611f599088614f9e565b905080821115611f7557611f75611f708284614f9e565b612366565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611fbe949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611fbe979096959101615241565b60008061201786612394565b9050612025818686866123c6565b9695505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561209e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c29190614efa565b6120cc9083615298565b421192915050565b60008060006120e48660006123f6565b90508061211a576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166121c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067f565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260365483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156122b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d691906152d5565b905090565b60006122f06122ea8585612414565b83612424565b90505b9392505050565b6000670de0b6b3a764000061233b6123128583614fe4565b61232490670de0b6b3a764000061504c565b61233685670de0b6b3a76400006150c0565b612433565b61234590866150c0565b6122f09190614fe4565b60008183101561235f57816122f3565b5090919050565b6000805a90505b825a6123799083614f9e565b101561238f5761238882615374565b915061236d565b505050565b606081805190602001206040516020016123b091815260200190565b6040516020818303038152906040529050919050565b60006123ed846123d7878686612464565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561235f57816122f3565b600081831261235f57816122f3565b60006122f3670de0b6b3a76400008361244b86612ee2565b61245591906150c0565b61245f9190614fe4565b613126565b606060008451116124d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161067f565b60006124dc84613365565b905060006124e986613451565b905060008460405160200161250091815260200190565b60405160208183030381529060405290506000805b8451811015612e59576000858281518110612532576125326153ac565b6020026020010151905084518311156125cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161067f565b82600003612686578051805160209182012060405161261b926125f592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067f565b6127dd565b80515160201161273c57805180516020918201206040516126b0926125f592910190815260200190565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161067f565b8051845160208087019190912082519190920120146127dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161067f565b6127e960106001615298565b816020015151036129c5578451830361295d576128238160200151601081518110612816576128166153ac565b60200260200101516134b4565b965060008751116128b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067f565b600186516128c49190614f9e565b8214612952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067f565b5050505050506122f3565b6000858481518110612971576129716153ac565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061299c5761299c6153ac565b602002602001015190506129af81613614565b95506129bc600186615298565b94505050612e46565b600281602001515103612dbe5760006129dd82613639565b90506000816000815181106129f4576129f46153ac565b016020015160f81c90506000612a0b6002836153db565b612a169060026153fd565b90506000612a27848360ff1661365d565b90506000612a358a8961365d565b90506000612a438383613693565b905080835114612ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067f565b60ff851660021480612aea575060ff85166003145b15612cd95780825114612b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067f565b612b998760200151600181518110612816576128166153ac565b9c5060008d5111612c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067f565b60018c51612c3a9190614f9e565b8814612cc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067f565b5050505050505050505050506122f3565b60ff85161580612cec575060ff85166001145b15612d2b57612d188760200151600181518110612d0b57612d0b6153ac565b6020026020010151613614565b9950612d24818a615298565b9850612db3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161067f565b505050505050612e46565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161067f565b5080612e5181615374565b915050612515565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161067f565b6000808213612f4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b60006060612f5a84613747565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361315757506000919050565b680755bf798b4a1bf1e582126131c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161067f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156133835761338361486a565b6040519080825280602002602001820160405280156133c857816020015b60408051808201909152606080825260208201528152602001906001900390816133a15790505b50915060005b8181101561344a5760405180604001604052808583815181106133f3576133f36153ac565b60200260200101518152602001613422868481518110613415576134156153ac565b602002602001015161381d565b815250838281518110613437576134376153ac565b60209081029190910101526001016133ce565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156134a9578060011b82018184015160001a8060041c8253600f81166001830153505060010161347b565b509295945050505050565b606060008060006134c485613830565b9194509250905060008160018111156134df576134df615420565b1461356c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067f565b6135768284615298565b855114613605576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161067f565b6123ed8560200151848461429d565b606060208260000151106136305761362b826134b4565b61105f565b61105f82614331565b606061105f6136588360200151600081518110612816576128166153ac565b613451565b60608251821061367c575060408051602081019091526000815261105f565b6122f3838384865161368e9190614f9e565b614347565b60008082518451106136a65782516136a9565b83515b90505b808210801561373057508282815181106136c8576136c86153ac565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613707576137076153ac565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613740578160010191506136ac565b5092915050565b60008082116137b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061105f61382b8361451f565b614608565b6000806000808460000151116138ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b6020840151805160001a607f8111613913576000600160009450945094505050614296565b60b78111613b21576000613928608083614f9e565b9050808760000151116139e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161067f565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613a5c57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613b0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161067f565b5060019550935060009250614296915050565b60bf8111613e6f576000613b3660b783614f9e565b905080876000015111613bf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161067f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c60378111613d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161067f565b613d9d8184615298565b895111613e52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161067f565b613e5d836001615298565b97509550600094506142969350505050565b60f78111613f50576000613e8460c083614f9e565b905080876000015111613f3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b600195509350849250614296915050565b6000613f5d60f783614f9e565b905080876000015111614018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161067f565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036140f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c603781116141ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161067f565b6141c48184615298565b895111614279576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b614284836001615298565b97509550600194506142969350505050565b9193909250565b60608167ffffffffffffffff8111156142b8576142b861486a565b6040519080825280601f01601f1916602001820160405280156142e2576020820181803683370190505b50905081156122f35760006142f78486615298565b90506020820160005b84811015614318578281015182820152602001614300565b84811115614327576000858301525b5050509392505050565b606061105f82602001516000846000015161429d565b60608182601f0110156143b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b828284011015614422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b8183018451101561448f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161067f565b6060821580156144ae5760405191506000825260208201604052614516565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156144e75780518352602092830192016144cf565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116145ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b50604080518082019091528151815260209182019181019190915290565b6060600080600061461885613830565b91945092509050600181600181111561463357614633615420565b146146c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067f565b84516146cc8385615298565b14614759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161067f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816147705790505093506000835b865181101561485e576000806147e36040518060400160405280858c600001516147c79190614f9e565b8152602001858c602001516147dc9190615298565b9052613830565b5091509150604051806040016040528083836147ff9190615298565b8152602001848b602001516148149190615298565b815250888581518110614829576148296153ac565b602090810291909101015261483f600185615298565b935061484b8183615298565b6148559084615298565b9250505061479d565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156148e0576148e061486a565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461490a57600080fd5b50565b600082601f83011261491e57600080fd5b813567ffffffffffffffff8111156149385761493861486a565b61496960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614899565b81815284602083860101111561497e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156149ad57600080fd5b60405160c0810167ffffffffffffffff82821081831117156149d1576149d161486a565b8160405282935084358352602085013591506149ec826148e8565b81602084015260408501359150614a02826148e8565b816040840152606085013560608401526080850135608084015260a0850135915080821115614a3057600080fd5b50614a3d8582860161490d565b60a0830152505092915050565b600080600080600085870360e0811215614a6357600080fd5b863567ffffffffffffffff80821115614a7b57600080fd5b614a878a838b0161499b565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614ac057600080fd5b60408901955060c0890135925080831115614ada57600080fd5b828901925089601f840112614aee57600080fd5b8235915080821115614aff57600080fd5b508860208260051b8401011115614b1557600080fd5b959894975092955050506020019190565b60005b83811015614b41578181015183820152602001614b29565b83811115614b50576000848401525b50505050565b60008151808452614b6e816020860160208601614b26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122f36020830184614b56565b600060208284031215614bc557600080fd5b5035919050565b600060208284031215614bde57600080fd5b813567ffffffffffffffff811115614bf557600080fd5b614c018482850161499b565b949350505050565b803567ffffffffffffffff81168114614c2157600080fd5b919050565b600060208284031215614c3857600080fd5b6122f382614c09565b80358015158114614c2157600080fd5b600080600080600060a08688031215614c6957600080fd5b8535614c74816148e8565b945060208601359350614c8960408701614c09565b9250614c9760608701614c41565b9150608086013567ffffffffffffffff811115614cb357600080fd5b614cbf8882890161490d565b9150509295509295909350565b60008060008060808587031215614ce257600080fd5b8435614ced816148e8565b93506020850135614cfd816148e8565b92506040850135614d0d816148e8565b9150614d1b60608601614c41565b905092959194509250565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614d7a816049850160208701614b26565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614c2157600080fd5b600060608284031215614dbd57600080fd5b6040516060810181811067ffffffffffffffff82111715614de057614de061486a565b60405282518152614df360208401614d8b565b6020820152614e0460408401614d8b565b60408201529392505050565b600060808284031215614e2257600080fd5b6040516080810181811067ffffffffffffffff82111715614e4557614e4561486a565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e9157614e9161486a565b8360051b6020614ea2818301614899565b868152918501918181019036841115614eba57600080fd5b865b84811015614eee57803586811115614ed45760008081fd5b614ee036828b0161490d565b845250918301918301614ebc565b50979650505050505050565b600060208284031215614f0c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614f6957614f69614f13565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f9557614f95614f13565b01949350505050565b600082821015614fb057614fb0614f13565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff357614ff3614fb5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504757615047614f13565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508657615086614f13565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150ba576150ba614f13565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561510157615101614f13565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513c5761513c614f13565b6000871292508782058712848416161561515857615158614f13565b8785058712818416161561516e5761516e614f13565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b6576151b6614f13565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151ea576151ea614f13565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561522857615228614f13565b500290565b60008261523c5761523c614fb5565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261528c60c0830184614b56565b98975050505050505050565b600082198211156152ab576152ab614f13565b500190565b805163ffffffff81168114614c2157600080fd5b805160ff81168114614c2157600080fd5b600060c082840312156152e757600080fd5b60405160c0810181811067ffffffffffffffff8211171561530a5761530a61486a565b604052615316836152b0565b8152615324602084016152c4565b6020820152615335604084016152c4565b6040820152615346606084016152b0565b6060820152615357608084016152b0565b608082015261536860a08401614d8b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153a5576153a5614f13565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806153ee576153ee614fb5565b8060ff84160691505092915050565b600060ff821660ff84168082101561541757615417614f13565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061016d5760003560e01c80638b4c40b0116100cb578063a35d99df1161007f578063e9e05c4211610059578063e9e05c4214610573578063f049875014610586578063fecf9734146105b157600080fd5b8063a35d99df1461040d578063cff0ab9614610446578063e965084c146104e757600080fd5b80639b5f694a116100b05780639b5f694a1461037e5780639bf62d82146103b0578063a14238e7146103dd57600080fd5b80638b4c40b0146101925780638c3152e91461035e57600080fd5b806354fd4d50116101225780636dbffb78116101075780636dbffb78146102fe578063724c184c1461031e5780638456cb591461034957600080fd5b806354fd4d501461027e5780635c975abb146102d457600080fd5b80633f4ba83a116101535780633f4ba83a1461021c578063452a9320146102315780634870496f1461025e57600080fd5b80621c2ff61461019957806333d7e2bd146101ef57600080fd5b36610194576101923334620186a06000604051806020016040528060008152506105d1565b005b600080fd5b3480156101a557600080fd5b50603554610100900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101fb57600080fd5b506036546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022857600080fd5b5061019261086c565b34801561023d57600080fd5b506037546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026a57600080fd5b50610192610279366004614a4a565b610971565b34801561028a57600080fd5b506102c76040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b6040516101e69190614ba0565b3480156102e057600080fd5b506035546102ee9060ff1681565b60405190151581526020016101e6565b34801561030a57600080fd5b506102ee610319366004614bb3565b610fa6565b34801561032a57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101c5565b34801561035557600080fd5b50610192611065565b34801561036a57600080fd5b50610192610379366004614bcc565b611167565b34801561038a57600080fd5b506035546101c590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103bc57600080fd5b506032546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e957600080fd5b506102ee6103f8366004614bb3565b60336020526000908152604090205460ff1681565b34801561041957600080fd5b5061042d610428366004614c26565b611a2b565b60405167ffffffffffffffff90911681526020016101e6565b34801561045257600080fd5b506001546104ae906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101e6565b3480156104f357600080fd5b50610545610502366004614bb3565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101e6565b610192610581366004614c51565b6105d1565b34801561059257600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff166101c5565b3480156105bd57600080fd5b506101926105cc366004614ccc565b611a44565b8260005a905083156106885773ffffffffffffffffffffffffffffffffffffffff87161561068857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6106928351611a2b565b67ffffffffffffffff168567ffffffffffffffff161015610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161067f565b6201d4c0835111156107a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161067f565b333281146107c4575033731111000000000000000000000000000000001111015b600034888888886040516020016107df959493929190614d26565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161084f9190614ba0565b60405180910390a450506108638282611c52565b50505050505050565b60375473ffffffffffffffffffffffffffffffffffffffff163314610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e70617573650000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff16156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161067f565b6035546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101869052600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190614dab565b519050610b50610b4b36869003860186614e10565b611f7f565b8114610bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161067f565b6000610be987611fdb565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d035750805160355460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190614dab565b5114155b610d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161067f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610e589101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610e4e888a614e76565b8a6040013561200b565b610ee4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161067f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6035546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161105f9161010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190614dab565b602001516fffffffffffffffffffffffffffffffff1661202f565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff16331461110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20706175736500000000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610967565b60355460ff16156111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161067f565b600061128882611fdb565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161067f565b603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190614efa565b81602001516fffffffffffffffffffffffffffffffff1610156114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161067f565b6114ee81602001516fffffffffffffffffffffffffffffffff1661202f565b6115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60355460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff9091166004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561162c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116509190614dab565b825181519192501461170a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161067f565b61172981602001516fffffffffffffffffffffffffffffffff1661202f565b6117db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60008381526033602052604090205460ff161561187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161067f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161191c939291906120d4565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061198190841515815260200190565b60405180910390a2801580156119975750326001145b15611a24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161067f565b5050505050565b6000611a38826010614f42565b61105f90615208614f72565b600054600390610100900460ff16158015611a66575060005460ff8083169116105b611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100908117909155603280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811661dead17909155603580546036805473ffffffffffffffffffffffffffffffffffffffff89811691861691909117909155603780548a83169516949094179093558515159289169093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fffffffffffffffffffffff00000000000000000000000000000000000000000090931692909217179055611bed612132565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600154600090611c88907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9e565b90506000611c94612215565b90506000816020015160ff16826000015163ffffffff16611cb59190614fe4565b90508215611dec57600154600090611cec908390700100000000000000000000000000000000900467ffffffffffffffff1661504c565b90506000836040015160ff1683611d0391906150c0565b600154611d239084906fffffffffffffffffffffffffffffffff166150c0565b611d2d9190614fe4565b600154909150600090611d7e90611d579084906fffffffffffffffffffffffffffffffff1661517c565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166122db565b90506001861115611dad57611daa611d5782876040015160ff1660018a611da59190614f9e565b6122fa565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e1f908490700100000000000000000000000000000000900467ffffffffffffffff16614f72565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161067f565b600154600090611f2e906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166151f0565b90506000611f4048633b9aca0061234f565b611f4a908361522d565b905060005a611f599088614f9e565b905080821115611f7557611f75611f708284614f9e565b612366565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611fbe949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611fbe979096959101615241565b60008061201786612394565b9050612025818686866123c6565b9695505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561209e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c29190614efa565b6120cc9083615298565b421192915050565b60008060006120e48660006123f6565b90508061211a576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166121c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067f565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260365483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156122b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d691906152d5565b905090565b60006122f06122ea8585612414565b83612424565b90505b9392505050565b6000670de0b6b3a764000061233b6123128583614fe4565b61232490670de0b6b3a764000061504c565b61233685670de0b6b3a76400006150c0565b612433565b61234590866150c0565b6122f09190614fe4565b60008183101561235f57816122f3565b5090919050565b6000805a90505b825a6123799083614f9e565b101561238f5761238882615374565b915061236d565b505050565b606081805190602001206040516020016123b091815260200190565b6040516020818303038152906040529050919050565b60006123ed846123d7878686612464565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561235f57816122f3565b600081831261235f57816122f3565b60006122f3670de0b6b3a76400008361244b86612ee2565b61245591906150c0565b61245f9190614fe4565b613126565b606060008451116124d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161067f565b60006124dc84613365565b905060006124e986613451565b905060008460405160200161250091815260200190565b60405160208183030381529060405290506000805b8451811015612e59576000858281518110612532576125326153ac565b6020026020010151905084518311156125cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161067f565b82600003612686578051805160209182012060405161261b926125f592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067f565b6127dd565b80515160201161273c57805180516020918201206040516126b0926125f592910190815260200190565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161067f565b8051845160208087019190912082519190920120146127dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161067f565b6127e960106001615298565b816020015151036129c5578451830361295d576128238160200151601081518110612816576128166153ac565b60200260200101516134b4565b965060008751116128b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067f565b600186516128c49190614f9e565b8214612952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067f565b5050505050506122f3565b6000858481518110612971576129716153ac565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061299c5761299c6153ac565b602002602001015190506129af81613614565b95506129bc600186615298565b94505050612e46565b600281602001515103612dbe5760006129dd82613639565b90506000816000815181106129f4576129f46153ac565b016020015160f81c90506000612a0b6002836153db565b612a169060026153fd565b90506000612a27848360ff1661365d565b90506000612a358a8961365d565b90506000612a438383613693565b905080835114612ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067f565b60ff851660021480612aea575060ff85166003145b15612cd95780825114612b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067f565b612b998760200151600181518110612816576128166153ac565b9c5060008d5111612c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067f565b60018c51612c3a9190614f9e565b8814612cc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067f565b5050505050505050505050506122f3565b60ff85161580612cec575060ff85166001145b15612d2b57612d188760200151600181518110612d0b57612d0b6153ac565b6020026020010151613614565b9950612d24818a615298565b9850612db3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161067f565b505050505050612e46565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161067f565b5080612e5181615374565b915050612515565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161067f565b6000808213612f4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b60006060612f5a84613747565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361315757506000919050565b680755bf798b4a1bf1e582126131c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161067f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156133835761338361486a565b6040519080825280602002602001820160405280156133c857816020015b60408051808201909152606080825260208201528152602001906001900390816133a15790505b50915060005b8181101561344a5760405180604001604052808583815181106133f3576133f36153ac565b60200260200101518152602001613422868481518110613415576134156153ac565b602002602001015161381d565b815250838281518110613437576134376153ac565b60209081029190910101526001016133ce565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156134a9578060011b82018184015160001a8060041c8253600f81166001830153505060010161347b565b509295945050505050565b606060008060006134c485613830565b9194509250905060008160018111156134df576134df615420565b1461356c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067f565b6135768284615298565b855114613605576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161067f565b6123ed8560200151848461429d565b606060208260000151106136305761362b826134b4565b61105f565b61105f82614331565b606061105f6136588360200151600081518110612816576128166153ac565b613451565b60608251821061367c575060408051602081019091526000815261105f565b6122f3838384865161368e9190614f9e565b614347565b60008082518451106136a65782516136a9565b83515b90505b808210801561373057508282815181106136c8576136c86153ac565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613707576137076153ac565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613740578160010191506136ac565b5092915050565b60008082116137b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061105f61382b8361451f565b614608565b6000806000808460000151116138ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b6020840151805160001a607f8111613913576000600160009450945094505050614296565b60b78111613b21576000613928608083614f9e565b9050808760000151116139e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161067f565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613a5c57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613b0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161067f565b5060019550935060009250614296915050565b60bf8111613e6f576000613b3660b783614f9e565b905080876000015111613bf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161067f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c60378111613d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161067f565b613d9d8184615298565b895111613e52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161067f565b613e5d836001615298565b97509550600094506142969350505050565b60f78111613f50576000613e8460c083614f9e565b905080876000015111613f3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b600195509350849250614296915050565b6000613f5d60f783614f9e565b905080876000015111614018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161067f565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036140f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c603781116141ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161067f565b6141c48184615298565b895111614279576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b614284836001615298565b97509550600194506142969350505050565b9193909250565b60608167ffffffffffffffff8111156142b8576142b861486a565b6040519080825280601f01601f1916602001820160405280156142e2576020820181803683370190505b50905081156122f35760006142f78486615298565b90506020820160005b84811015614318578281015182820152602001614300565b84811115614327576000858301525b5050509392505050565b606061105f82602001516000846000015161429d565b60608182601f0110156143b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b828284011015614422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b8183018451101561448f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161067f565b6060821580156144ae5760405191506000825260208201604052614516565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156144e75780518352602092830192016144cf565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116145ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b50604080518082019091528151815260209182019181019190915290565b6060600080600061461885613830565b91945092509050600181600181111561463357614633615420565b146146c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067f565b84516146cc8385615298565b14614759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161067f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816147705790505093506000835b865181101561485e576000806147e36040518060400160405280858c600001516147c79190614f9e565b8152602001858c602001516147dc9190615298565b9052613830565b5091509150604051806040016040528083836147ff9190615298565b8152602001848b602001516148149190615298565b815250888581518110614829576148296153ac565b602090810291909101015261483f600185615298565b935061484b8183615298565b6148559084615298565b9250505061479d565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156148e0576148e061486a565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461490a57600080fd5b50565b600082601f83011261491e57600080fd5b813567ffffffffffffffff8111156149385761493861486a565b61496960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614899565b81815284602083860101111561497e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156149ad57600080fd5b60405160c0810167ffffffffffffffff82821081831117156149d1576149d161486a565b8160405282935084358352602085013591506149ec826148e8565b81602084015260408501359150614a02826148e8565b816040840152606085013560608401526080850135608084015260a0850135915080821115614a3057600080fd5b50614a3d8582860161490d565b60a0830152505092915050565b600080600080600085870360e0811215614a6357600080fd5b863567ffffffffffffffff80821115614a7b57600080fd5b614a878a838b0161499b565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614ac057600080fd5b60408901955060c0890135925080831115614ada57600080fd5b828901925089601f840112614aee57600080fd5b8235915080821115614aff57600080fd5b508860208260051b8401011115614b1557600080fd5b959894975092955050506020019190565b60005b83811015614b41578181015183820152602001614b29565b83811115614b50576000848401525b50505050565b60008151808452614b6e816020860160208601614b26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122f36020830184614b56565b600060208284031215614bc557600080fd5b5035919050565b600060208284031215614bde57600080fd5b813567ffffffffffffffff811115614bf557600080fd5b614c018482850161499b565b949350505050565b803567ffffffffffffffff81168114614c2157600080fd5b919050565b600060208284031215614c3857600080fd5b6122f382614c09565b80358015158114614c2157600080fd5b600080600080600060a08688031215614c6957600080fd5b8535614c74816148e8565b945060208601359350614c8960408701614c09565b9250614c9760608701614c41565b9150608086013567ffffffffffffffff811115614cb357600080fd5b614cbf8882890161490d565b9150509295509295909350565b60008060008060808587031215614ce257600080fd5b8435614ced816148e8565b93506020850135614cfd816148e8565b92506040850135614d0d816148e8565b9150614d1b60608601614c41565b905092959194509250565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614d7a816049850160208701614b26565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614c2157600080fd5b600060608284031215614dbd57600080fd5b6040516060810181811067ffffffffffffffff82111715614de057614de061486a565b60405282518152614df360208401614d8b565b6020820152614e0460408401614d8b565b60408201529392505050565b600060808284031215614e2257600080fd5b6040516080810181811067ffffffffffffffff82111715614e4557614e4561486a565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e9157614e9161486a565b8360051b6020614ea2818301614899565b868152918501918181019036841115614eba57600080fd5b865b84811015614eee57803586811115614ed45760008081fd5b614ee036828b0161490d565b845250918301918301614ebc565b50979650505050505050565b600060208284031215614f0c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614f6957614f69614f13565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f9557614f95614f13565b01949350505050565b600082821015614fb057614fb0614f13565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff357614ff3614fb5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504757615047614f13565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508657615086614f13565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150ba576150ba614f13565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561510157615101614f13565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513c5761513c614f13565b6000871292508782058712848416161561515857615158614f13565b8785058712818416161561516e5761516e614f13565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b6576151b6614f13565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151ea576151ea614f13565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561522857615228614f13565b500290565b60008261523c5761523c614fb5565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261528c60c0830184614b56565b98975050505050505050565b600082198211156152ab576152ab614f13565b500190565b805163ffffffff81168114614c2157600080fd5b805160ff81168114614c2157600080fd5b600060c082840312156152e757600080fd5b60405160c0810181811067ffffffffffffffff8211171561530a5761530a61486a565b604052615316836152b0565b8152615324602084016152c4565b6020820152615335604084016152c4565b6040820152615346606084016152b0565b6060820152615357608084016152b0565b608082015261536860a08401614d8b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153a5576153a5614f13565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806153ee576153ee614fb5565b8060ff84160691505092915050565b600060ff821660ff84168082101561541757615417614f13565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "GUARDIAN()": {}, - "L2_ORACLE()": {}, - "SYSTEM_CONFIG()": {}, - "depositTransaction(address,uint256,uint64,bool,bytes)": { - "params": { - "_data": "Data to trigger the recipient with.", - "_gasLimit": "Amount of L2 gas to purchase by burning gas on L1.", - "_isCreation": "Whether or not the transaction is a contract creation.", - "_to": "Target address on L2.", - "_value": "ETH value to send to the recipient." - } - }, - "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": { - "params": { - "_tx": "Withdrawal transaction to finalize." - } - }, - "initialize(address,address,address,bool)": { - "params": { - "_guardian": "Address that can pause withdrawals.", - "_l2Oracle": "Address of the L2OutputOracle contract.", - "_paused": "Sets the contract's pausability state.", - "_systemConfig": "Address of the SystemConfig contract." - } - }, - "isOutputFinalized(uint256)": { - "params": { - "_l2OutputIndex": "Index of the L2 output to check." - }, - "returns": { - "_0": "Whether or not the output is finalized." - } - }, - "minimumGasLimit(uint64)": { - "params": { - "_byteCount": "Number of bytes in the calldata." - }, - "returns": { - "_0": "The minimum gas limit for a deposit." - } - }, - "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": { - "params": { - "_l2OutputIndex": "L2 output index to prove against.", - "_outputRootProof": "Inclusion proof of the L2ToL1MessagePasser contract's storage root.", - "_tx": "Withdrawal transaction to finalize.", - "_withdrawalProof": "Inclusion proof of the withdrawal in L2ToL1MessagePasser contract." - } - } - }, - "events": { - "Paused(address)": { - "params": { - "account": "Address of the account triggering the pause." - } - }, - "TransactionDeposited(address,address,uint256,bytes)": { - "params": { - "from": "Address that triggered the deposit transaction.", - "opaqueData": "ABI encoded deposit data to be parsed off-chain.", - "to": "Address that the deposit transaction is directed to.", - "version": "Version of this deposit transaction event." - } - }, - "Unpaused(address)": { - "params": { - "account": "Address of the account triggering the unpause." - } - }, - "WithdrawalFinalized(bytes32,bool)": { - "params": { - "success": "Whether the withdrawal transaction was successful.", - "withdrawalHash": "Hash of the withdrawal transaction." - } - }, - "WithdrawalProven(bytes32,address,address)": { - "params": { - "from": "Address that triggered the withdrawal transaction.", - "to": "Address that the withdrawal transaction is directed to.", - "withdrawalHash": "Hash of the withdrawal transaction." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Paused\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"bytes\",\"name\":\"opaqueData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"TransactionDeposited\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Unpaused\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\",\"indexed\":false}],\"type\":\"event\",\"name\":\"WithdrawalFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"WithdrawalProven\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"GUARDIAN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"SYSTEM_CONFIG\",\"outputs\":[{\"internalType\":\"contract SystemConfig\",\"name\":\"\",\"type\":\"address\"}]},{\"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\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"depositTransaction\"},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"donateETH\"},{\"inputs\":[{\"internalType\":\"struct Types.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeWithdrawalTransaction\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"guardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_guardian\",\"type\":\"address\"},{\"internalType\":\"contract SystemConfig\",\"name\":\"_systemConfig\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"isOutputFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2Oracle\",\"outputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_byteCount\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"pause\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"struct Types.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}]},{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"},{\"internalType\":\"struct Types.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}]},{\"internalType\":\"bytes[]\",\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"proveWithdrawalTransaction\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"provenWithdrawals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2OutputIndex\",\"type\":\"uint128\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"systemConfig\",\"outputs\":[{\"internalType\":\"contract SystemConfig\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"unpause\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"GUARDIAN()\":{\"custom:legacy\":\"\"},\"L2_ORACLE()\":{\"custom:legacy\":\"\"},\"SYSTEM_CONFIG()\":{\"custom:legacy\":\"\"},\"depositTransaction(address,uint256,uint64,bool,bytes)\":{\"params\":{\"_data\":\"Data to trigger the recipient with.\",\"_gasLimit\":\"Amount of L2 gas to purchase by burning gas on L1.\",\"_isCreation\":\"Whether or not the transaction is a contract creation.\",\"_to\":\"Target address on L2.\",\"_value\":\"ETH value to send to the recipient.\"}},\"finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))\":{\"params\":{\"_tx\":\"Withdrawal transaction to finalize.\"}},\"initialize(address,address,address,bool)\":{\"params\":{\"_guardian\":\"Address that can pause withdrawals.\",\"_l2Oracle\":\"Address of the L2OutputOracle contract.\",\"_paused\":\"Sets the contract's pausability state.\",\"_systemConfig\":\"Address of the SystemConfig contract.\"}},\"isOutputFinalized(uint256)\":{\"params\":{\"_l2OutputIndex\":\"Index of the L2 output to check.\"},\"returns\":{\"_0\":\"Whether or not the output is finalized.\"}},\"minimumGasLimit(uint64)\":{\"params\":{\"_byteCount\":\"Number of bytes in the calldata.\"},\"returns\":{\"_0\":\"The minimum gas limit for a deposit.\"}},\"proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])\":{\"params\":{\"_l2OutputIndex\":\"L2 output index to prove against.\",\"_outputRootProof\":\"Inclusion proof of the L2ToL1MessagePasser contract's storage root.\",\"_tx\":\"Withdrawal transaction to finalize.\",\"_withdrawalProof\":\"Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"GUARDIAN()\":{\"notice\":\"Getter for the Guardian\"},\"L2_ORACLE()\":{\"notice\":\"Getter for the L2OutputOracle\"},\"SYSTEM_CONFIG()\":{\"notice\":\"Getter for the SystemConfig\"},\"constructor\":{\"notice\":\"Constructs the OptimismPortal contract.\"},\"depositTransaction(address,uint256,uint64,bool,bytes)\":{\"notice\":\"Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in deriving deposit transactions. Note that if a deposit is made by a contract, its address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider using the CrossDomainMessenger contracts for a simpler developer experience.\"},\"donateETH()\":{\"notice\":\"Accepts ETH value without triggering a deposit to L2. This function mainly exists for the sake of the migration between the legacy Optimism system and Bedrock.\"},\"finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))\":{\"notice\":\"Finalizes a withdrawal transaction.\"},\"finalizedWithdrawals(bytes32)\":{\"notice\":\"A list of withdrawal hashes which have been successfully finalized.\"},\"guardian()\":{\"notice\":\"Address that has the ability to pause and unpause withdrawals.\"},\"initialize(address,address,address,bool)\":{\"notice\":\"Initializer.\"},\"isOutputFinalized(uint256)\":{\"notice\":\"Determine if a given output is finalized. Reverts if the call to L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\"},\"l2Oracle()\":{\"notice\":\"Address of the L2OutputOracle contract.\"},\"l2Sender()\":{\"notice\":\"Address of the L2 account which initiated a withdrawal in this transaction. If the of this variable is the default L2 sender address, then we are NOT inside of a call to finalizeWithdrawalTransaction.\"},\"minimumGasLimit(uint64)\":{\"notice\":\"Computes the minimum gas limit for a deposit. The minimum gas limit linearly increases based on the size of the calldata. This is to prevent users from creating L2 resource usage without paying for it. This function can be used when interacting with the portal to ensure forwards compatibility.\"},\"params()\":{\"notice\":\"EIP-1559 style gas parameters.\"},\"pause()\":{\"notice\":\"Pauses withdrawals.\"},\"paused()\":{\"notice\":\"Determines if cross domain messaging is paused. When set to true, withdrawals are paused. This may be removed in the future.\"},\"proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])\":{\"notice\":\"Proves a withdrawal transaction.\"},\"provenWithdrawals(bytes32)\":{\"notice\":\"A mapping of withdrawal hashes to `ProvenWithdrawal` data.\"},\"systemConfig()\":{\"notice\":\"Address of the SystemConfig contract.\"},\"unpause()\":{\"notice\":\"Unpauses withdrawals.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/OptimismPortal.sol\":\"OptimismPortal\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L2OutputOracle.sol\":{\"keccak256\":\"0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705\",\"urls\":[\"bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc\",\"dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN\"],\"license\":\"MIT\"},\"src/L1/OptimismPortal.sol\":{\"keccak256\":\"0xdca91a921b402d82b455d7f11027514e8a16dca906cf820b3afffe271beb8a13\",\"urls\":[\"bzz-raw://688912b9d6005af8395d5c2eb5c4e3367a8be7b50ea97c34fc6a7ac0e2d8fd6a\",\"dweb:/ipfs/QmNPJDwHpNmJ5VPWAJB8muRpZxYeySZDVoV1TMVN7roijJ\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L1/SystemConfig.sol\":{\"keccak256\":\"0x4bbbc7868e948c44f29285a69383e93251a0c330a67929fb72def01cec060d4e\",\"urls\":[\"bzz-raw://1e7ea2f8b3d49bee9c753f107ede6eda93b2cc0e34d0643fa14ebbb26c19e71b\",\"dweb:/ipfs/QmRP81F8FRVXVZs6u2f2poEPDnbFZhNwNYxHgCVEhGpEmB\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Bytes.sol\":{\"keccak256\":\"0x827f47d123b0fdf3b08816d5b33831811704dbf4e554e53f2269354f6bba8859\",\"urls\":[\"bzz-raw://3137ac7204d30a245a8b0d67aa6da5286f1bd8c90379daab561f84963b6db782\",\"dweb:/ipfs/QmWRhisw3axJK833gUScs23ETh2MLFbVzzqzYVMKSDN3S9\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x9ba74a3b0a11693e622380807d213d5d1250d974e18b2cd768da9cbe719a6778\",\"urls\":[\"bzz-raw://0808d721ed9e05707526ee134faa051d707a95ee6b8bd6e0b1972275da8e5723\",\"dweb:/ipfs/QmcTTPu9xgckfWdbFUAcr2RAgk3J6vzyR4FpV798TjFMeN\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xf8ba770ee6666e73ae43184c700e9c704b2c4ace71f9e3c2227ddc11a8148b4c\",\"urls\":[\"bzz-raw://4702ccee1fe44aea3ee01d59e6152eb755da083f786f00947fec4437c064fe74\",\"dweb:/ipfs/QmQjFj5J7hrEM1dxJjFszzW2Cs7g7eMhYNBXonF2DXBstE\"],\"license\":\"MIT\"},\"src/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0xeaff8315cfd21197bc6bc859c2decf5d4f4838c9c357c502cdf2b1eac863d288\",\"urls\":[\"bzz-raw://79dcdcaa560aea51d138da4f5dc553a1808b6de090b2dc1629f18375edbff681\",\"dweb:/ipfs/QmbE4pUPhf5fLKW4W6cEjhQs55gEDvHmbmoBqkW1yz3bnw\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"],\"license\":\"Apache-2.0\"}},\"version\":1}", - "numDeployments": 2, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 60835, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "params", - "offset": 0, - "slot": "1", - "type": "t_struct(ResourceParams)60818_storage" - }, - { - "astId": 60840, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "__gap", - "offset": 0, - "slot": "2", - "type": "t_array(t_uint256)48_storage" - }, - { - "astId": 59871, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "l2Sender", - "offset": 0, - "slot": "50", - "type": "t_address" - }, - { - "astId": 59876, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "finalizedWithdrawals", - "offset": 0, - "slot": "51", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 59882, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "provenWithdrawals", - "offset": 0, - "slot": "52", - "type": "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)59860_storage)" - }, - { - "astId": 59885, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "paused", - "offset": 0, - "slot": "53", - "type": "t_bool" - }, - { - "astId": 59889, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "l2Oracle", - "offset": 1, - "slot": "53", - "type": "t_contract(L2OutputOracle)59820" - }, - { - "astId": 59893, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "systemConfig", - "offset": 0, - "slot": "54", - "type": "t_contract(SystemConfig)61941" - }, - { - "astId": 59896, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "guardian", - "offset": 0, - "slot": "55", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)48_storage": { - "encoding": "inplace", - "label": "uint256[48]", - "numberOfBytes": "1536", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_contract(L2OutputOracle)59820": { - "encoding": "inplace", - "label": "contract L2OutputOracle", - "numberOfBytes": "20" - }, - "t_contract(SystemConfig)61941": { - "encoding": "inplace", - "label": "contract SystemConfig", - "numberOfBytes": "20" - }, - "t_mapping(t_bytes32,t_bool)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)59860_storage)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal)", - "numberOfBytes": "32", - "value": "t_struct(ProvenWithdrawal)59860_storage" - }, - "t_struct(ProvenWithdrawal)59860_storage": { - "encoding": "inplace", - "label": "struct OptimismPortal.ProvenWithdrawal", - "numberOfBytes": "64", - "members": [ - { - "astId": 59855, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "outputRoot", - "offset": 0, - "slot": "0", - "type": "t_bytes32" - }, - { - "astId": 59857, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "timestamp", - "offset": 0, - "slot": "1", - "type": "t_uint128" - }, - { - "astId": 59859, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "l2OutputIndex", - "offset": 16, - "slot": "1", - "type": "t_uint128" - } - ] - }, - "t_struct(ResourceParams)60818_storage": { - "encoding": "inplace", - "label": "struct ResourceMetering.ResourceParams", - "numberOfBytes": "32", - "members": [ - { - "astId": 60813, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "prevBaseFee", - "offset": 0, - "slot": "0", - "type": "t_uint128" - }, - { - "astId": 60815, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "prevBoughtGas", - "offset": 16, - "slot": "0", - "type": "t_uint64" - }, - { - "astId": 60817, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "prevBlockNum", - "offset": 24, - "slot": "0", - "type": "t_uint64" - } - ] - }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x53b24743fdd00ac90ab5b91a531a7f8ab74d29e8db7a85db5e489fa5d8d08702", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "GUARDIAN()": { - "notice": "Getter for the Guardian" - }, - "L2_ORACLE()": { - "notice": "Getter for the L2OutputOracle" - }, - "SYSTEM_CONFIG()": { - "notice": "Getter for the SystemConfig" - }, - "constructor": { - "notice": "Constructs the OptimismPortal contract." - }, - "depositTransaction(address,uint256,uint64,bool,bytes)": { - "notice": "Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in deriving deposit transactions. Note that if a deposit is made by a contract, its address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider using the CrossDomainMessenger contracts for a simpler developer experience." - }, - "donateETH()": { - "notice": "Accepts ETH value without triggering a deposit to L2. This function mainly exists for the sake of the migration between the legacy Optimism system and Bedrock." - }, - "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": { - "notice": "Finalizes a withdrawal transaction." - }, - "finalizedWithdrawals(bytes32)": { - "notice": "A list of withdrawal hashes which have been successfully finalized." - }, - "guardian()": { - "notice": "Address that has the ability to pause and unpause withdrawals." - }, - "initialize(address,address,address,bool)": { - "notice": "Initializer." - }, - "isOutputFinalized(uint256)": { - "notice": "Determine if a given output is finalized. Reverts if the call to L2_ORACLE.getL2Output reverts. Returns a boolean otherwise." - }, - "l2Oracle()": { - "notice": "Address of the L2OutputOracle contract." - }, - "l2Sender()": { - "notice": "Address of the L2 account which initiated a withdrawal in this transaction. If the of this variable is the default L2 sender address, then we are NOT inside of a call to finalizeWithdrawalTransaction." - }, - "minimumGasLimit(uint64)": { - "notice": "Computes the minimum gas limit for a deposit. The minimum gas limit linearly increases based on the size of the calldata. This is to prevent users from creating L2 resource usage without paying for it. This function can be used when interacting with the portal to ensure forwards compatibility." - }, - "params()": { - "notice": "EIP-1559 style gas parameters." - }, - "pause()": { - "notice": "Pauses withdrawals." - }, - "paused()": { - "notice": "Determines if cross domain messaging is paused. When set to true, withdrawals are paused. This may be removed in the future." - }, - "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": { - "notice": "Proves a withdrawal transaction." - }, - "provenWithdrawals(bytes32)": { - "notice": "A mapping of withdrawal hashes to `ProvenWithdrawal` data." - }, - "systemConfig()": { - "notice": "Address of the SystemConfig contract." - }, - "unpause()": { - "notice": "Unpauses withdrawals." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "Paused(address)": { - "notice": "Emitted when the pause is triggered." - }, - "TransactionDeposited(address,address,uint256,bytes)": { - "notice": "Emitted when a transaction is deposited from L1 to L2. The parameters of this event are read by the rollup node and used to derive deposit transactions on L2." - }, - "Unpaused(address)": { - "notice": "Emitted when the pause is lifted." - }, - "WithdrawalFinalized(bytes32,bool)": { - "notice": "Emitted when a withdrawal transaction is finalized." - }, - "WithdrawalProven(bytes32,address,address)": { - "notice": "Emitted when a withdrawal transaction is proven." - } - }, - "notice": "The OptimismPortal is a low-level contract responsible for passing messages between L1 and L2. Messages sent directly to the OptimismPortal have no form of replayability. Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/OptimismPortalProxy.json b/packages/contracts-bedrock/deployments/mainnet/OptimismPortalProxy.json deleted file mode 100644 index 37b62aa64690..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/OptimismPortalProxy.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x8da60c6cebf2d2c87437952eb159c6be86edb98cf0f98bba058df16b4d8aa943", - "receipt": { - "to": null, - "from": "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960", - "contractAddress": "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", - "transactionIndex": 110, - "gasUsed": "523960", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x46d5b502bf0b4473d984d51e838c2fe8221d19ed75adcab17844d6e746e3643b", - "transactionHash": "0x8da60c6cebf2d2c87437952eb159c6be86edb98cf0f98bba058df16b4d8aa943", - "logs": [ - { - "transactionIndex": 110, - "blockNumber": 17365802, - "transactionHash": "0x8da60c6cebf2d2c87437952eb159c6be86edb98cf0f98bba058df16b4d8aa943", - "address": "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000543ba4aadbab8f9025686bd03993043599c6fb04", - "logIndex": 291, - "blockHash": "0x46d5b502bf0b4473d984d51e838c2fe8221d19ed75adcab17844d6e746e3643b" - } - ], - "blockNumber": 17365802, - "cumulativeGasUsed": "10917526", - "status": 1, - "byzantium": true - }, - "args": [ - "0x543bA4AADBAb8f9025686Bd03993043599c6fB04" - ], - "numDeployments": 1, - "solcInputHash": "13ac93d026822f719ad110af836d1582", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33b903585eb9cfc60a70bcdf4ee44220b173caff16dfb9071cd0668c7a551265\",\"dweb:/ipfs/QmXHUZ9brinN1WS9i63ocRQsQidY96WePDBhBsFRhDmVjr\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/PortalSender.json b/packages/contracts-bedrock/deployments/mainnet/PortalSender.json deleted file mode 100644 index f3111b0c1446..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/PortalSender.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "address": "0x0A893d9576b9cFD9EF78595963dc973238E78210", - "abi": [ - { - "inputs": [ - { - "internalType": "contract OptimismPortal", - "name": "_portal", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "PORTAL", - "outputs": [ - { - "internalType": "contract OptimismPortal", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "donate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0xec487a1d2cd607cad1c88ad2769a694901b268a97e45f662afe6a39266b93d60", - "receipt": { - "to": null, - "from": "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960", - "contractAddress": "0x0A893d9576b9cFD9EF78595963dc973238E78210", - "transactionIndex": 92, - "gasUsed": "118186", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xd88eeaeb10110aa57b00c2e414b1e69979c14d265bc571884450dad5bab60a79", - "transactionHash": "0xec487a1d2cd607cad1c88ad2769a694901b268a97e45f662afe6a39266b93d60", - "logs": [], - "blockNumber": 17365811, - "cumulativeGasUsed": "9259464", - "status": 1, - "byzantium": true - }, - "args": [ - "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" - ], - "numDeployments": 1, - "solcInputHash": "13ac93d026822f719ad110af836d1582", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract OptimismPortal\",\"name\":\"_portal\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"PORTAL\",\"outputs\":[{\"internalType\":\"contract OptimismPortal\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"donate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_portal\":\"Address of the OptimismPortal contract.\"}}},\"title\":\"PortalSender\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"PORTAL()\":{\"notice\":\"Address of the OptimismPortal contract.\"},\"donate()\":{\"notice\":\"Sends balance of this contract to the OptimismPortal.\"}},\"notice\":\"The PortalSender is a simple intermediate contract that will transfer the balance of the L1StandardBridge to the OptimismPortal during the Bedrock migration.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/deployment/PortalSender.sol\":\"PortalSender\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L1/L2OutputOracle.sol\":{\"keccak256\":\"0xba09a5005080e6c7ccc9e0dab17165f20ae0ef9d9c04a13d0b5c158dc1c2a4bb\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fce7e5b5fb4882f05ddcd540f4781225bcf95870b5206e1b423a98ddd3e80df2\",\"dweb:/ipfs/QmQxsgVPaZmkW8SKxKtQEmP5ApeXAxaEEC6Hf4AQ4xL3wC\"]},\"contracts/L1/OptimismPortal.sol\":{\"keccak256\":\"0x3b16493feec098a6d70b98a83e0f7c5f541ac33c5265edee77c2c0229c343fd2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://795b7f9aca7930f9b446d81071ba7d35872f3fbd53faa0e7acb1f51df4edb7f2\",\"dweb:/ipfs/QmTwr3pGnVVN2qfTjPqC5svhM7rLVLgiEj1SthHVz1v4k8\"]},\"contracts/L1/ResourceMetering.sol\":{\"keccak256\":\"0xbd7b9532a70d8c842bfce0ea971be50d02fbbf0227c9ad55c71ac68d438010f4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4969f478dd54e89392cda2ea0c5edcf1be55a5dee43a0e410527b6e3bcb85c88\",\"dweb:/ipfs/QmU2crAojw8DRDsz7PAPrereazjFsKh9wtfTpTDVh6NLfW\"]},\"contracts/L1/SystemConfig.sol\":{\"keccak256\":\"0x2202e03df7b5f70b0cf1cf942afe51cab165bf35864a77d6a77dc82c55653689\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://42ec7d69b192c6199bf28ccf1d19d896f01807039f6bdc3e871b52eb7d9ee645\",\"dweb:/ipfs/QmPmWLf9a9FJ2fYQi9nP73e4QRnAMDbrfNwLS1u8KZgrEs\"]},\"contracts/deployment/PortalSender.sol\":{\"keccak256\":\"0xe60d88036d9aa8f8e80a4108ee30ad987564ad996af87a79ba92f6ca35852881\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a4be187cd3d5926592491f722dfa1b1c41a8f4f1abdc8cf3883964f70acb0a44\",\"dweb:/ipfs/QmYsAK4YcRHmPoex2eX2x1r6N76AMk3rdBHHmp6gUT73Fa\"]},\"contracts/libraries/Arithmetic.sol\":{\"keccak256\":\"0xc8858039f87e48e6f18c1af8bc0b03e57cfef564acddfd06e4d91e3db7ac5ed6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2fc79af1e844aa6dc1c68067bfe1d359df8d4e9a3e8881afb3bcfcbf68071714\",\"dweb:/ipfs/QmcNC4k8zmvwj4kZizSenTiWbx2DJQPbwqXXLF4iMbkRVD\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Bytes.sol\":{\"keccak256\":\"0x7aca6593fadf438ee9cd090d8fdc8f94a5202a2eb7f764c9a86f207712d87a48\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://aac32157885c5a08bd0bc7dcd5511f66db12bb20d0c263dd7be9f58b91538fc1\",\"dweb:/ipfs/Qmb1iG11Z53yt9wNbGsuTvoydJXFosDDpWwRSADKyqiCjw\"]},\"contracts/libraries/Constants.sol\":{\"keccak256\":\"0x8c7be28a175eb732995a7f704560163c30261f9f70d377f865c5060882509f5d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f72aba26553b10ca88708e05461691b36b0d2ec7a87f718022fe119ca9c70852\",\"dweb:/ipfs/QmQtDEB1F3D8RsgG63KSJ9t7ZyFLaXc2Av81vKD9y2TMn7\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/SafeCall.sol\":{\"keccak256\":\"0x3deedbfc0a57228366531a4f09c94d174f0bb4ea49476a92226d471f3abb349b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e8091b178f6710cb7738f07b1706fe18c241b6275b6641b32724d4ecf5a087dd\",\"dweb:/ipfs/Qmd5kchcZhHepJ3boHRTVDJUr9jsuweWEyoUmNmMFJB6vp\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x4fe8ec920798661a828430bd30dc2715eeb40534ec01c0a7bf41cb4ab422e134\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://74c8471869900bd459358cd990bda1c8d234c06b788804c7049cf465ae1e299f\",\"dweb:/ipfs/QmakcfP6NmbVUQsKqH7rEyJsbiqckigLahw9g74oencEJ7\"]},\"contracts/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x50763c897f0fe84cb067985ec4d7c5721ce9004a69cf0327f96f8982ee8ca412\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://603af847b43933b075f9aac3a7b3cd65041ffe6d732826695458ca9575e1a809\",\"dweb:/ipfs/QmfByFEaCxT9y1VtqoLi5EsXZ9ihkPfj6g5x7pcPoQ7q2K\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xd27fc945d6dd2821636d840f3766f817823c8e9fbfdb87c2da7c73e4292d2f7f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://497cec37d09ebcdc8d1cccac608a4a0b9b9d83eac6cc7c9e8b73c4c6644e2209\",\"dweb:/ipfs/QmUYMsCcgU6epspvKV9Y6anHyyMb4hd1xVzUZheBY9mfG7\"]},\"contracts/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0x61b03a03779cb1f75cea3b88af16fdfd10629029b4b2d6be5238e71af8ef1b5f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1212951af291c0e033a7119b42de5cad6b6bf32da26777da7c2419e76fa8f314\",\"dweb:/ipfs/QmYbnifDmL6UkP9D1X9GaNLR1Q8wYwmDNeYqkJ71bycaE5\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"contracts/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"]},\"node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"]},\"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"]},\"node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]}},\"version\":1}", - "bytecode": "0x60a060405234801561001057600080fd5b506040516101b53803806101b583398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b6080516101256100906000396000818160400152609701526101256000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80630ff754ea1461003b578063ed88c68e1461008b575b600080fd5b6100627f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b610093610095565b005b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638b4c40b0476040518263ffffffff1660e01b81526004016000604051808303818588803b1580156100fd57600080fd5b505af1158015610111573d6000803e3d6000fd5b505050505056fea164736f6c634300080f000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80630ff754ea1461003b578063ed88c68e1461008b575b600080fd5b6100627f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b610093610095565b005b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638b4c40b0476040518263ffffffff1660e01b81526004016000604051808303818588803b1580156100fd57600080fd5b505af1158015610111573d6000803e3d6000fd5b505050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_portal": "Address of the OptimismPortal contract." - } - } - }, - "title": "PortalSender" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "PORTAL()": { - "notice": "Address of the OptimismPortal contract." - }, - "donate()": { - "notice": "Sends balance of this contract to the OptimismPortal." - } - }, - "notice": "The PortalSender is a simple intermediate contract that will transfer the balance of the L1StandardBridge to the OptimismPortal during the Bedrock migration." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/ProtocolVersions.json b/packages/contracts-bedrock/deployments/mainnet/ProtocolVersions.json deleted file mode 100644 index ed490ec191c0..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/ProtocolVersions.json +++ /dev/null @@ -1,496 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "version", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "enum ProtocolVersions.UpdateType", - "name": "updateType", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "ConfigUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "RECOMMENDED_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "REQUIRED_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "ProtocolVersion", - "name": "_required", - "type": "uint256" - }, - { - "internalType": "ProtocolVersion", - "name": "_recommended", - "type": "uint256" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "recommended", - "outputs": [ - { - "internalType": "ProtocolVersion", - "name": "out_", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "required", - "outputs": [ - { - "internalType": "ProtocolVersion", - "name": "out_", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "ProtocolVersion", - "name": "_recommended", - "type": "uint256" - } - ], - "name": "setRecommended", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "ProtocolVersion", - "name": "_required", - "type": "uint256" - } - ], - "name": "setRequired", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "args": [], - "bytecode": "0x60806040523480156200001157600080fd5b506200002261dead60008062000028565b620004c9565b600054600390610100900460ff161580156200004b575060005460ff8083169116105b620000b45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620000d26200013a565b620000dd84620001a2565b620000e88362000221565b620000f382620002d1565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b600054610100900460ff16620001965760405162461bcd60e51b815260206004820152602b602482015260008051602062000e9683398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b620001a062000332565b565b620001ac62000399565b6001600160a01b038116620002135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620000ab565b6200021e81620003f5565b50565b620002676200025260017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16200044b565b60001b826200044760201b620004f51760201c565b6000816040516020016200027d91815260200190565b60408051601f19818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051620002c5919062000471565b60405180910390a35050565b620003026200025260017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6200044b565b6000816040516020016200031891815260200190565b60408051601f198184030181529190529050600162000292565b600054610100900460ff166200038e5760405162461bcd60e51b815260206004820152602b602482015260008051602062000e9683398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b620001a033620003f5565b6033546001600160a01b03163314620001a05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000ab565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b9055565b6000828210156200046c57634e487b7160e01b600052601160045260246000fd5b500390565b600060208083528351808285015260005b81811015620004a05785810183015185820160400152820162000482565b81811115620004b3576000604083870101525b50601f01601f1916929092016040019392505050565b6109bd80620004d96000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e736600461085d565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161010091906108e1565b6100ec61016036600461085d565b61021d565b6100ec61022e565b6100ec61017b366004610924565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103ad565b6100f66103e6565b6100ec6101c6366004610957565b610416565b6100f66104ca565b6100f6600081565b6101e36104f9565b6101ec8161057a565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b81565b6102256104f9565b6101ec81610632565b6102366104f9565b61024060006106ac565b565b600054600390610100900460ff16158015610264575060005460ff8083169116105b6102f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561032e610723565b61033784610416565b6103408361057a565b61034982610632565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b60006103e16103dd60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b5490565b905090565b60006103e16103dd60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b61041e6104f9565b73ffffffffffffffffffffffffffffffffffffffff81166104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102ec565b6101ec816106ac565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102ec565b6105ad6105a860017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b829055565b6000816040516020016105c291815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161062691906108e1565b60405180910390a35050565b6106606105a860017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b60008160405160200161067591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060016105f5565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240600054610100900460ff16610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240336106ac565b60006020828403121561086f57600080fd5b5035919050565b6000815180845260005b8181101561089c57602081850181015186830182015201610880565b818111156108ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006108f46020830184610876565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091f57600080fd5b919050565b60008060006060848603121561093957600080fd5b610942846108fb565b95602085013595506040909401359392505050565b60006020828403121561096957600080fd5b6108f4826108fb565b6000828210156109ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e736600461085d565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161010091906108e1565b6100ec61016036600461085d565b61021d565b6100ec61022e565b6100ec61017b366004610924565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103ad565b6100f66103e6565b6100ec6101c6366004610957565b610416565b6100f66104ca565b6100f6600081565b6101e36104f9565b6101ec8161057a565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b81565b6102256104f9565b6101ec81610632565b6102366104f9565b61024060006106ac565b565b600054600390610100900460ff16158015610264575060005460ff8083169116105b6102f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561032e610723565b61033784610416565b6103408361057a565b61034982610632565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b60006103e16103dd60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b5490565b905090565b60006103e16103dd60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b61041e6104f9565b73ffffffffffffffffffffffffffffffffffffffff81166104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102ec565b6101ec816106ac565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102ec565b6105ad6105a860017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b829055565b6000816040516020016105c291815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161062691906108e1565b60405180910390a35050565b6106606105a860017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b60008160405160200161067591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060016105f5565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240600054610100900460ff16610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240336106ac565b60006020828403121561086f57600080fd5b5035919050565b6000815180845260005b8181101561089c57602081850181015186830182015201610880565b818111156108ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006108f46020830184610876565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091f57600080fd5b919050565b60008060006060848603121561093957600080fd5b610942846108fb565b95602085013595506040909401359392505050565b60006020828403121561096957600080fd5b6108f4826108fb565b6000828210156109ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "initialize(address,uint256,uint256)": { - "params": { - "_owner": "Initial owner of the contract.", - "_recommended": "Recommended protocol version to operate on thi chain.", - "_required": "Required protocol version to operate on this chain." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "recommended()": { - "returns": { - "out_": "Recommended protocol version to sync to the head of the chain." - } - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "required()": { - "returns": { - "out_": "Required protocol version to sync to the head of the chain." - } - }, - "setRecommended(uint256)": { - "params": { - "_recommended": "New recommended protocol version." - } - }, - "setRequired(uint256)": { - "params": { - "_required": "New required protocol version." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "params": { - "data": "Encoded update data.", - "updateType": "Type of update.", - "version": "ProtocolVersion version." - } - } - }, - "title": "ProtocolVersions" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"enum ProtocolVersions.UpdateType\",\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ConfigUpdate\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RECOMMENDED_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"REQUIRED_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"ProtocolVersion\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"ProtocolVersion\",\"name\":\"_recommended\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"recommended\",\"outputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"out_\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"renounceOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"required\",\"outputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"out_\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"_recommended\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setRecommended\"},{\"inputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"_required\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setRequired\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address,uint256,uint256)\":{\"params\":{\"_owner\":\"Initial owner of the contract.\",\"_recommended\":\"Recommended protocol version to operate on thi chain.\",\"_required\":\"Required protocol version to operate on this chain.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"recommended()\":{\"returns\":{\"out_\":\"Recommended protocol version to sync to the head of the chain.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"required()\":{\"returns\":{\"out_\":\"Required protocol version to sync to the head of the chain.\"}},\"setRecommended(uint256)\":{\"params\":{\"_recommended\":\"New recommended protocol version.\"}},\"setRequired(uint256)\":{\"params\":{\"_required\":\"New required protocol version.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"RECOMMENDED_SLOT()\":{\"notice\":\"Storage slot that the recommended protocol version is stored at.\"},\"REQUIRED_SLOT()\":{\"notice\":\"Storage slot that the required protocol version is stored at.\"},\"VERSION()\":{\"notice\":\"Version identifier, used for upgrades.\"},\"constructor\":{\"notice\":\"Constructs the ProtocolVersion contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)` A zero version is considered empty and is ignored by nodes.\"},\"initialize(address,uint256,uint256)\":{\"notice\":\"Initializer.\"},\"recommended()\":{\"notice\":\"High level getter for the recommended protocol version.\"},\"required()\":{\"notice\":\"High level getter for the required protocol version.\"},\"setRecommended(uint256)\":{\"notice\":\"Updates the recommended protocol version. Can only be called by the owner.\"},\"setRequired(uint256)\":{\"notice\":\"Updates the required protocol version. Can only be called by the owner.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/ProtocolVersions.sol\":\"ProtocolVersions\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ProtocolVersions.sol\":{\"keccak256\":\"0xa283721c36e2ba3ea1c61faebc364a8884bf3a276f80374cc8017d0e23ea1dfc\",\"urls\":[\"bzz-raw://4ee23cbc9772213c637c767747e5fb1db7c3f0f17d6a1ff576b638f25c6799e8\",\"dweb:/ipfs/QmfKZfFC6fyhQdLk2YrjVBL6eRX1d9CTrPHj7fNPUNXmEq\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 1, - "receipt": { - "transactionHash": "0x34e5f1585a2404da7aa6108fbef8d63a4e9d5b077b17b791dfb3aed69d9486cc", - "transactionIndex": "0x7f", - "blockHash": "0x209f9de05c2399a0abd737a44aa0ec55bf2221c7dfedbfe61724b0a831c8f0c8", - "blockNumber": "0x11842d9", - "from": "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960", - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "cumulativeGasUsed": "0x12caf91", - "gasUsed": "0xa3523", - "contractAddress": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "logs": [ - { - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c" - ], - "data": "0x", - "blockHash": "0x209f9de05c2399a0abd737a44aa0ec55bf2221c7dfedbfe61724b0a831c8f0c8", - "blockNumber": "0x11842d9", - "transactionHash": "0x34e5f1585a2404da7aa6108fbef8d63a4e9d5b077b17b791dfb3aed69d9486cc", - "transactionIndex": "0x7f", - "logIndex": "0x63e", - "removed": false - }, - { - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "0x000000000000000000000000000000000000000000000000000000000000dead" - ], - "data": "0x", - "blockHash": "0x209f9de05c2399a0abd737a44aa0ec55bf2221c7dfedbfe61724b0a831c8f0c8", - "blockNumber": "0x11842d9", - "transactionHash": "0x34e5f1585a2404da7aa6108fbef8d63a4e9d5b077b17b791dfb3aed69d9486cc", - "transactionIndex": "0x7f", - "logIndex": "0x63f", - "removed": false - }, - { - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x209f9de05c2399a0abd737a44aa0ec55bf2221c7dfedbfe61724b0a831c8f0c8", - "blockNumber": "0x11842d9", - "transactionHash": "0x34e5f1585a2404da7aa6108fbef8d63a4e9d5b077b17b791dfb3aed69d9486cc", - "transactionIndex": "0x7f", - "logIndex": "0x640", - "removed": false - }, - { - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000001" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x209f9de05c2399a0abd737a44aa0ec55bf2221c7dfedbfe61724b0a831c8f0c8", - "blockNumber": "0x11842d9", - "transactionHash": "0x34e5f1585a2404da7aa6108fbef8d63a4e9d5b077b17b791dfb3aed69d9486cc", - "transactionIndex": "0x7f", - "logIndex": "0x641", - "removed": false - }, - { - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000003", - "blockHash": "0x209f9de05c2399a0abd737a44aa0ec55bf2221c7dfedbfe61724b0a831c8f0c8", - "blockNumber": "0x11842d9", - "transactionHash": "0x34e5f1585a2404da7aa6108fbef8d63a4e9d5b077b17b791dfb3aed69d9486cc", - "transactionIndex": "0x7f", - "logIndex": "0x642", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000010000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000008000001000000040000000000000000000000000000000000000001000000040000000000000000000000000000020000000000000000000800000000000000000000000800000000400000000000000000000004040000000000000000001080000000000000000000000000000001000000000080000400000000000000000000000000000000000000000400000000000000000000040000000000000000000000000000000060000000000000000000000000000000000080000000000000000000008000000000", - "type": "0x2", - "effectiveGasPrice": "0x200dd2d8d" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 29536, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 29539, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 29964, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 29408, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 29528, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x34e5f1585a2404da7aa6108fbef8d63a4e9d5b077b17b791dfb3aed69d9486cc", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "RECOMMENDED_SLOT()": { - "notice": "Storage slot that the recommended protocol version is stored at." - }, - "REQUIRED_SLOT()": { - "notice": "Storage slot that the required protocol version is stored at." - }, - "VERSION()": { - "notice": "Version identifier, used for upgrades." - }, - "constructor": { - "notice": "Constructs the ProtocolVersion contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)` A zero version is considered empty and is ignored by nodes." - }, - "initialize(address,uint256,uint256)": { - "notice": "Initializer." - }, - "recommended()": { - "notice": "High level getter for the recommended protocol version." - }, - "required()": { - "notice": "High level getter for the required protocol version." - }, - "setRecommended(uint256)": { - "notice": "Updates the recommended protocol version. Can only be called by the owner." - }, - "setRequired(uint256)": { - "notice": "Updates the required protocol version. Can only be called by the owner." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "notice": "Emitted when configuration is updated." - } - }, - "notice": "The ProtocolVersions contract is used to manage superchain protocol version information." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/ProtocolVersionsProxy.json b/packages/contracts-bedrock/deployments/mainnet/ProtocolVersionsProxy.json deleted file mode 100644 index 571d13eef0f5..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/ProtocolVersionsProxy.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0x8062AbC286f5e7D9428a0Ccb9AbD71e50d93b935", - "args": [ - "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960" - ], - "bytecode": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"AdminChanged\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Upgraded\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"changeAdmin\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"upgradeTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/Proxy.sol\":\"Proxy\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/universal/Proxy.sol\":{\"keccak256\":\"0xc56de5e39cd44eaeb93f0f8705dd07f4a89f66d5c186522532cf899a104cdbca\",\"urls\":[\"bzz-raw://cd1b595148fa62a798343a23e3330e79fef7d747f039d664482044be9ec0ccf3\",\"dweb:/ipfs/QmeAft6H9wbc9zZZ3prtRaBGGzcPy9yExKAhZHjp1iZ8UF\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 2, - "receipt": { - "transactionHash": "0x4ab7f052e31b73b021e814069aca71203829101066362541ba8e14113932ea99", - "transactionIndex": "0x9", - "blockHash": "0x0d0787545a87d78f45279d585b9b25c4aeeb8d2110d56f2c5307b80445d45c53", - "blockNumber": "0x1184344", - "from": "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960", - "to": null, - "cumulativeGasUsed": "0x2afbc6", - "gasUsed": "0x80250", - "contractAddress": "0x8062AbC286f5e7D9428a0Ccb9AbD71e50d93b935", - "logs": [ - { - "address": "0x8062AbC286f5e7D9428a0Ccb9AbD71e50d93b935", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000354f3f4ecdca5e0a7ace08d71348cdc1dab48960", - "blockHash": "0x0d0787545a87d78f45279d585b9b25c4aeeb8d2110d56f2c5307b80445d45c53", - "blockNumber": "0x1184344", - "transactionHash": "0x4ab7f052e31b73b021e814069aca71203829101066362541ba8e14113932ea99", - "transactionIndex": "0x9", - "logIndex": "0x31", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000040000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0x22f2c5d4c" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [], - "types": {} - }, - "transactionHash": "0x4ab7f052e31b73b021e814069aca71203829101066362541ba8e14113932ea99", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/ProxyAdmin.json b/packages/contracts-bedrock/deployments/mainnet/ProxyAdmin.json deleted file mode 100644 index 75bbae585653..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/ProxyAdmin.json +++ /dev/null @@ -1,576 +0,0 @@ -{ - "address": "0x543bA4AADBAb8f9025686Bd03993043599c6fB04", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "addressManager", - "outputs": [ - { - "internalType": "contract AddressManager", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "_newAdmin", - "type": "address" - } - ], - "name": "changeProxyAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - } - ], - "name": "getProxyAdmin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_proxy", - "type": "address" - } - ], - "name": "getProxyImplementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "implementationName", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isUpgrading", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "proxyType", - "outputs": [ - { - "internalType": "enum ProxyAdmin.ProxyType", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "address", - "name": "_address", - "type": "address" - } - ], - "name": "setAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract AddressManager", - "name": "_address", - "type": "address" - } - ], - "name": "setAddressManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_address", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "setImplementationName", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_address", - "type": "address" - }, - { - "internalType": "enum ProxyAdmin.ProxyType", - "name": "_type", - "type": "uint8" - } - ], - "name": "setProxyType", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "_upgrading", - "type": "bool" - } - ], - "name": "setUpgrading", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgrade", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - } - ], - "transactionHash": "0x1c5704eb14508af3d2ef1690aae89f3410a891af903103ab344bd789402f97bf", - "receipt": { - "to": null, - "from": "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960", - "contractAddress": "0x543bA4AADBAb8f9025686Bd03993043599c6fB04", - "transactionIndex": 74, - "gasUsed": "1483961", - "logsBloom": "0x00000800000000000000000000000000000000000000000000800000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000020000000000000080000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5767112801dab6286e5971d21c61a4861a61fe193604f117bef04a32144cd230", - "transactionHash": "0x1c5704eb14508af3d2ef1690aae89f3410a891af903103ab344bd789402f97bf", - "logs": [ - { - "transactionIndex": 74, - "blockNumber": 17365800, - "transactionHash": "0x1c5704eb14508af3d2ef1690aae89f3410a891af903103ab344bd789402f97bf", - "address": "0x543bA4AADBAb8f9025686Bd03993043599c6fB04", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000354f3f4ecdca5e0a7ace08d71348cdc1dab48960" - ], - "data": "0x", - "logIndex": 207, - "blockHash": "0x5767112801dab6286e5971d21c61a4861a61fe193604f117bef04a32144cd230" - }, - { - "transactionIndex": 74, - "blockNumber": 17365800, - "transactionHash": "0x1c5704eb14508af3d2ef1690aae89f3410a891af903103ab344bd789402f97bf", - "address": "0x543bA4AADBAb8f9025686Bd03993043599c6fB04", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x000000000000000000000000354f3f4ecdca5e0a7ace08d71348cdc1dab48960", - "0x000000000000000000000000354f3f4ecdca5e0a7ace08d71348cdc1dab48960" - ], - "data": "0x", - "logIndex": 208, - "blockHash": "0x5767112801dab6286e5971d21c61a4861a61fe193604f117bef04a32144cd230" - } - ], - "blockNumber": 17365800, - "cumulativeGasUsed": "7925562", - "status": 1, - "byzantium": true - }, - "args": [ - "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960" - ], - "numDeployments": 1, - "solcInputHash": "13ac93d026822f719ad110af836d1582", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"contract AddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"implementationName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"proxyType\",\"outputs\":[{\"internalType\":\"enum ProxyAdmin.ProxyType\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract AddressManager\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddressManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"setImplementationName\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"enum ProxyAdmin.ProxyType\",\"name\":\"_type\",\"type\":\"uint8\"}],\"name\":\"setProxyType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_upgrading\",\"type\":\"bool\"}],\"name\":\"setUpgrading\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"params\":{\"_newAdmin\":\"Address of the new proxy admin.\",\"_proxy\":\"Address of the proxy to update.\"}},\"constructor\":{\"params\":{\"_owner\":\"Address of the initial owner of this contract.\"}},\"getProxyAdmin(address)\":{\"params\":{\"_proxy\":\"Address of the proxy to get the admin of.\"},\"returns\":{\"_0\":\"Address of the admin of the proxy.\"}},\"getProxyImplementation(address)\":{\"params\":{\"_proxy\":\"Address of the proxy to get the implementation of.\"},\"returns\":{\"_0\":\"Address of the implementation of the proxy.\"}},\"isUpgrading()\":{\"custom:legacy\":\"@notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\",\"returns\":{\"_0\":\"Whether or not there is an upgrade going on. May not actually tell you whether an upgrade is going on, since we don't currently plan to use this variable for anything other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setAddress(string,address)\":{\"custom:legacy\":\"@notice Set an address in the address manager. Since only the owner of the AddressManager can directly modify addresses and the ProxyAdmin will own the AddressManager, this gives the owner of the ProxyAdmin the ability to modify addresses directly.\",\"params\":{\"_address\":\"Address to attach to the given name.\",\"_name\":\"Name to set within the AddressManager.\"}},\"setAddressManager(address)\":{\"params\":{\"_address\":\"Address of the AddressManager.\"}},\"setImplementationName(address,string)\":{\"params\":{\"_address\":\"Address of the ResolvedDelegateProxy.\",\"_name\":\"Name of the implementation for the proxy.\"}},\"setProxyType(address,uint8)\":{\"params\":{\"_address\":\"Address of the proxy.\",\"_type\":\"Type of the proxy.\"}},\"setUpgrading(bool)\":{\"custom:legacy\":\"@notice Set the upgrading status for the Chugsplash proxy type.\",\"params\":{\"_upgrading\":\"Whether or not the system is upgrading.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"params\":{\"_implementation\":\"Address of the new implementation address.\",\"_proxy\":\"Address of the proxy to upgrade.\"}},\"upgradeAndCall(address,address,bytes)\":{\"params\":{\"_data\":\"Data to trigger the new implementation with.\",\"_implementation\":\"Address of the new implementation address.\",\"_proxy\":\"Address of the proxy to upgrade.\"}}},\"title\":\"ProxyAdmin\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addressManager()\":{\"notice\":\"The address of the address manager, this is required to manage the ResolvedDelegateProxy type.\"},\"changeProxyAdmin(address,address)\":{\"notice\":\"Updates the admin of the given proxy address.\"},\"getProxyAdmin(address)\":{\"notice\":\"Returns the admin of the given proxy address.\"},\"getProxyImplementation(address)\":{\"notice\":\"Returns the implementation of the given proxy address.\"},\"implementationName(address)\":{\"notice\":\"A reverse mapping of addresses to names held in the AddressManager. This must be manually kept up to date with changes in the AddressManager for this contract to be able to work as an admin for the ResolvedDelegateProxy type.\"},\"proxyType(address)\":{\"notice\":\"A mapping of proxy types, used for backwards compatibility.\"},\"setAddressManager(address)\":{\"notice\":\"Set the address of the AddressManager. This is required to manage legacy ResolvedDelegateProxy type proxy contracts.\"},\"setImplementationName(address,string)\":{\"notice\":\"Sets the implementation name for a given address. Only required for ResolvedDelegateProxy type proxies that have an implementation name.\"},\"setProxyType(address,uint8)\":{\"notice\":\"Sets the proxy type for a given address. Only required for non-standard (legacy) proxy types.\"},\"upgrade(address,address)\":{\"notice\":\"Changes a proxy's implementation contract.\"},\"upgradeAndCall(address,address,bytes)\":{\"notice\":\"Changes a proxy's implementation contract and delegatecalls the new implementation with some given data. Useful for atomic upgrade-and-initialize calls.\"}},\"notice\":\"This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy, based on the OpenZeppelin implementation. It has backwards compatibility logic to work with the various types of proxies that have been deployed by Optimism in the past.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/legacy/AddressManager.sol\":{\"keccak256\":\"0x7a353d4c92eed32665fd2f0023c55054901293cf7a6e14ca108229d87c047b10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b92ba23601d1951271729a20db931a45639d9376b7c8e2705c23dc360833715a\",\"dweb:/ipfs/QmTKwYLNYYBKZpd31VNBANmguVUwFZifSg7joHSgLZjZCj\"]},\"contracts/legacy/L1ChugSplashProxy.sol\":{\"keccak256\":\"0x6ae7bf6ea9ac0e3511ee4cb15d946589da0dd35098ff762c0b2903d064f24875\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://02028d86c1d38563021d5ead5282271ccdf1c03a24f2eaee056ae2157f0554ee\",\"dweb:/ipfs/QmW9urkBBRTmZ8FjL5Y5zWbdnRhPDruxCCLnpr2CTkozKM\"]},\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33b903585eb9cfc60a70bcdf4ee44220b173caff16dfb9071cd0668c7a551265\",\"dweb:/ipfs/QmXHUZ9brinN1WS9i63ocRQsQidY96WePDBhBsFRhDmVjr\"]},\"contracts/universal/ProxyAdmin.sol\":{\"keccak256\":\"0x7326011ac425cc9ab4760c29ca559342d4832633b5019a9a61b9e63067374e2a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7d3541272c48443f0b339998553e44600b7bcb4f949e5c94acb5a3acfce19399\",\"dweb:/ipfs/QmNSd9jxACWg8bZE8EgxmRdXwLUQixVs4oiugrVegapUe4\"]},\"node_modules/@openzeppelin/contracts/access/Ownable.sol\":{\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://40fb1b5102468f783961d0af743f91b9980cf66b50d1d12009f6bb1869cea4d2\",\"dweb:/ipfs/QmYqEbJML4jB1GHbzD4cUZDtJg5wVwNm3vDJq1GbyDus8y\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"]}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b5060405162001a5f38038062001a5f8339810160408190526200003491620000a1565b6200003f3362000051565b6200004a8162000051565b50620000d3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208284031215620000b457600080fd5b81516001600160a01b0381168114620000cc57600080fd5b9392505050565b61197c80620000e36000396000f3fe60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "changeProxyAdmin(address,address)": { - "params": { - "_newAdmin": "Address of the new proxy admin.", - "_proxy": "Address of the proxy to update." - } - }, - "constructor": { - "params": { - "_owner": "Address of the initial owner of this contract." - } - }, - "getProxyAdmin(address)": { - "params": { - "_proxy": "Address of the proxy to get the admin of." - }, - "returns": { - "_0": "Address of the admin of the proxy." - } - }, - "getProxyImplementation(address)": { - "params": { - "_proxy": "Address of the proxy to get the implementation of." - }, - "returns": { - "_0": "Address of the implementation of the proxy." - } - }, - "isUpgrading()": { - "returns": { - "_0": "Whether or not there is an upgrade going on. May not actually tell you whether an upgrade is going on, since we don't currently plan to use this variable for anything other than a legacy indicator to fix a UX bug in the ChugSplash proxy." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "setAddress(string,address)": { - "params": { - "_address": "Address to attach to the given name.", - "_name": "Name to set within the AddressManager." - } - }, - "setAddressManager(address)": { - "params": { - "_address": "Address of the AddressManager." - } - }, - "setImplementationName(address,string)": { - "params": { - "_address": "Address of the ResolvedDelegateProxy.", - "_name": "Name of the implementation for the proxy." - } - }, - "setProxyType(address,uint8)": { - "params": { - "_address": "Address of the proxy.", - "_type": "Type of the proxy." - } - }, - "setUpgrading(bool)": { - "params": { - "_upgrading": "Whether or not the system is upgrading." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - }, - "upgrade(address,address)": { - "params": { - "_implementation": "Address of the new implementation address.", - "_proxy": "Address of the proxy to upgrade." - } - }, - "upgradeAndCall(address,address,bytes)": { - "params": { - "_data": "Data to trigger the new implementation with.", - "_implementation": "Address of the new implementation address.", - "_proxy": "Address of the proxy to upgrade." - } - } - }, - "title": "ProxyAdmin" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "addressManager()": { - "notice": "The address of the address manager, this is required to manage the ResolvedDelegateProxy type." - }, - "changeProxyAdmin(address,address)": { - "notice": "Updates the admin of the given proxy address." - }, - "getProxyAdmin(address)": { - "notice": "Returns the admin of the given proxy address." - }, - "getProxyImplementation(address)": { - "notice": "Returns the implementation of the given proxy address." - }, - "implementationName(address)": { - "notice": "A reverse mapping of addresses to names held in the AddressManager. This must be manually kept up to date with changes in the AddressManager for this contract to be able to work as an admin for the ResolvedDelegateProxy type." - }, - "proxyType(address)": { - "notice": "A mapping of proxy types, used for backwards compatibility." - }, - "setAddressManager(address)": { - "notice": "Set the address of the AddressManager. This is required to manage legacy ResolvedDelegateProxy type proxy contracts." - }, - "setImplementationName(address,string)": { - "notice": "Sets the implementation name for a given address. Only required for ResolvedDelegateProxy type proxies that have an implementation name." - }, - "setProxyType(address,uint8)": { - "notice": "Sets the proxy type for a given address. Only required for non-standard (legacy) proxy types." - }, - "upgrade(address,address)": { - "notice": "Changes a proxy's implementation contract." - }, - "upgradeAndCall(address,address,bytes)": { - "notice": "Changes a proxy's implementation contract and delegatecalls the new implementation with some given data. Useful for atomic upgrade-and-initialize calls." - } - }, - "notice": "This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy, based on the OpenZeppelin implementation. It has backwards compatibility logic to work with the various types of proxies that have been deployed by Optimism in the past." - }, - "storageLayout": { - "storage": [ - { - "astId": 53108, - "contract": "contracts/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "_owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 51261, - "contract": "contracts/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "proxyType", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_address,t_enum(ProxyType)51255)" - }, - { - "astId": 51266, - "contract": "contracts/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "implementationName", - "offset": 0, - "slot": "2", - "type": "t_mapping(t_address,t_string_storage)" - }, - { - "astId": 51270, - "contract": "contracts/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "addressManager", - "offset": 0, - "slot": "3", - "type": "t_contract(AddressManager)7678" - }, - { - "astId": 51273, - "contract": "contracts/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "upgrading", - "offset": 20, - "slot": "3", - "type": "t_bool" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(AddressManager)7678": { - "encoding": "inplace", - "label": "contract AddressManager", - "numberOfBytes": "20" - }, - "t_enum(ProxyType)51255": { - "encoding": "inplace", - "label": "enum ProxyAdmin.ProxyType", - "numberOfBytes": "1" - }, - "t_mapping(t_address,t_enum(ProxyType)51255)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => enum ProxyAdmin.ProxyType)", - "numberOfBytes": "32", - "value": "t_enum(ProxyType)51255" - }, - "t_mapping(t_address,t_string_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => string)", - "numberOfBytes": "32", - "value": "t_string_storage" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/SystemConfig.json b/packages/contracts-bedrock/deployments/mainnet/SystemConfig.json deleted file mode 100644 index 3f42750565ea..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/SystemConfig.json +++ /dev/null @@ -1,1078 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "version", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "enum SystemConfig.UpdateType", - "name": "updateType", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "ConfigUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "BATCH_INBOX_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_CROSS_DOMAIN_MESSENGER_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_ERC_721_BRIDGE_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_STANDARD_BRIDGE_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_OUTPUT_ORACLE_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMISM_PORTAL_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "UNSAFE_BLOCK_SIGNER_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "batchInbox", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "batcherHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "gasLimit", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_overhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_scalar", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_batcherHash", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - }, - { - "internalType": "address", - "name": "_unsafeBlockSigner", - "type": "address" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "_config", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "_startBlock", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_batchInbox", - "type": "address" - }, - { - "components": [ - { - "internalType": "address", - "name": "l1CrossDomainMessenger", - "type": "address" - }, - { - "internalType": "address", - "name": "l1ERC721Bridge", - "type": "address" - }, - { - "internalType": "address", - "name": "l1StandardBridge", - "type": "address" - }, - { - "internalType": "address", - "name": "l2OutputOracle", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismPortal", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismMintableERC20Factory", - "type": "address" - } - ], - "internalType": "struct SystemConfig.Addresses", - "name": "_addresses", - "type": "tuple" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l1CrossDomainMessenger", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1ERC721Bridge", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1StandardBridge", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l2OutputOracle", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minimumGasLimit", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "optimismMintableERC20Factory", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "optimismPortal", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "overhead", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "resourceConfig", - "outputs": [ - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "scalar", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_batcherHash", - "type": "bytes32" - } - ], - "name": "setBatcherHash", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_overhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_scalar", - "type": "uint256" - } - ], - "name": "setGasConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - } - ], - "name": "setGasLimit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "_config", - "type": "tuple" - } - ], - "name": "setResourceConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_unsafeBlockSigner", - "type": "address" - } - ], - "name": "setUnsafeBlockSigner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "startBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "unsafeBlockSigner", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "args": [], - "bytecode": "0x60806040523480156200001157600080fd5b506040805160c080820183526001808352602080840182905260028486015260006060808601829052608080870183905260a08088018490528851968701895283875293860183905296850182905284018190529483018590528201849052620000909361dead93909283928392909183919060001990839062000096565b62000ccc565b600054600390610100900460ff16158015620000b9575060005460ff8083169116105b620001225760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620001406200043a565b6200014b8b620004a2565b620001568862000521565b620001628a8a62000573565b6200016d87620005d7565b620001788662000674565b620001be620001a960017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59862000ba9565b60001b84620006dc60201b62000d211760201c565b62000208620001ef60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063762000ba9565b60001b8360000151620006dc60201b62000d211760201c565b620002526200023960017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a862000ba9565b60001b8360200151620006dc60201b62000d211760201c565b6200029c6200028360017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637762000ba9565b60001b8360400151620006dc60201b62000d211760201c565b620002e6620002cd60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a687181662000ba9565b60001b8360600151620006dc60201b62000d211760201c565b620003306200031760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad62000ba9565b60001b8360800151620006dc60201b62000d211760201c565b6200037a6200036160017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d62000ba9565b60001b8360a00151620006dc60201b62000d211760201c565b6200038584620006e0565b62000390856200070d565b6200039a62000a51565b6001600160401b0316876001600160401b03161015620003ec5760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b600054610100900460ff16620004965760405162461bcd60e51b815260206004820152602b60248201526000805160206200285f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000119565b620004a062000a7e565b565b620004ac62000ae5565b6001600160a01b038116620005135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000119565b6200051e8162000b41565b50565b60678190556040805160208082018490528251808303909101815290820190915260005b60006000805160206200283f8339815191528360405162000567919062000bc3565b60405180910390a35050565b60658290556066819055604080516020810184905290810182905260009060600160408051601f198184030181529190529050600160006000805160206200283f83398151915283604051620005ca919062000bc3565b60405180910390a3505050565b620005e162000a51565b6001600160401b0316816001600160401b03161015620006335760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b606880546001600160401b0319166001600160401b038316908117909155604080516020808201939093528151808203909301835281019052600262000545565b620006ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0882620006dc60201b62000d211760201c565b604080516001600160a01b03831660208201526000910160408051601f198184030181529190529050600362000545565b9055565b8015801590620006f05750606a54155b15620006fb57606a55565b606a546000036200051e5743606a5550565b8060a001516001600160801b0316816060015163ffffffff1611156200079c5760405162461bcd60e51b815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840162000119565b6001816040015160ff16116200080d5760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201526e65206c6172676572207468616e203160881b606482015260840162000119565b606854608082015182516001600160401b03909216916200082f919062000c1b565b63ffffffff161115620008745760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b6000816020015160ff1611620008e55760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201526e06965722063616e6e6f74206265203608c1b606482015260840162000119565b8051602082015163ffffffff82169160ff909116906200090790829062000c46565b62000913919062000c78565b63ffffffff16146200098e5760405162461bcd60e51b815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840162000119565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff96871664ffffffffff199095169490941764010000000060ff948516021764ffffffffff60281b191665010000000000939092169290920263ffffffff60301b19161766010000000000009185169190910217600160501b600160f01b0319166a01000000000000000000009390941692909202600160701b600160f01b03191692909217600160701b6001600160801b0390921691909102179055565b60695460009062000a799063ffffffff6a010000000000000000000082048116911662000ca7565b905090565b600054610100900460ff1662000ada5760405162461bcd60e51b815260206004820152602b60248201526000805160206200285f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000119565b620004a03362000b41565b6033546001600160a01b03163314620004a05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000119565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052601160045260246000fd5b60008282101562000bbe5762000bbe62000b93565b500390565b600060208083528351808285015260005b8181101562000bf25785810183015185820160400152820162000bd4565b8181111562000c05576000604083870101525b50601f01601f1916929092016040019392505050565b600063ffffffff80831681851680830382111562000c3d5762000c3d62000b93565b01949350505050565b600063ffffffff8084168062000c6c57634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b600063ffffffff8083168185168183048111821515161562000c9e5762000c9e62000b93565b02949350505050565b60006001600160401b0382811684821680830382111562000c3d5762000c3d62000b93565b611b438062000cdc6000396000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c8063935f029e1161012a578063cc731b02116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610575578063fd32aa0f1461057d578063ffa1ad741461058557600080fd5b8063f45e65d814610558578063f68016b71461056157600080fd5b8063cc731b0214610400578063dac6e63a14610534578063e81b2c6d1461053c578063f2fde38b1461054557600080fd5b8063bc49ce5f116100f9578063bc49ce5f146103ca578063c4e8ddfa146103d2578063c71973f6146103da578063c9b26f61146103ed57600080fd5b8063935f029e146103945780639b7d7f0a146103a7578063a7119869146103af578063b40a817c146103b757600080fd5b80634add321d116101bd57806354fd4d501161018c57806361d157681161017157806361d1576814610366578063715018a61461036e5780638da5cb5b1461037657600080fd5b806354fd4d50146103155780635d73369c1461035e57600080fd5b80634add321d146102b25780634d9f1559146102d35780634f16540b146102db5780635228a6ac1461030257600080fd5b806318d13918116101f957806318d139181461028457806319f5cea8146102995780631fd19ee1146102a157806348cd4cb1146102a957600080fd5b806306c926571461022b578063078f29cf146102465780630a49cb03146102735780630c18c1621461027b575b600080fd5b61023361058d565b6040519081526020015b60405180910390f35b61024e6105bb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023d565b61024e6105f4565b61023360655481565b610297610292366004611677565b610624565b005b610233610638565b61024e610663565b610233606a5481565b6102ba61068d565b60405167ffffffffffffffff909116815260200161023d565b61024e6106b3565b6102337f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b610297610310366004611807565b6106e3565b6103516040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b60405161023d91906119aa565b610233610a79565b610233610aa4565b610297610acf565b60335473ffffffffffffffffffffffffffffffffffffffff1661024e565b6102976103a23660046119bd565b610ae3565b61024e610af9565b61024e610b29565b6102976103c53660046119df565b610b59565b610233610b6a565b61024e610b95565b6102976103e83660046119fa565b610bc5565b6102976103fb366004611a16565b610bd6565b6104c46040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b60405161023d9190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61024e610be7565b61023360675481565b610297610553366004611677565b610c17565b61023360665481565b6068546102ba9067ffffffffffffffff1681565b610233610ccb565b610233610cf6565b610233600081565b6105b860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b81565b60006105ef6105eb60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b5490565b905090565b60006105ef6105eb60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b61062c610d25565b61063581610da6565b50565b6105b860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60006105ef7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b6069546000906105ef9063ffffffff6a0100000000000000000000820481169116611a75565b60006105ef6105eb60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b600054600390610100900460ff16158015610705575060005460ff8083169116105b610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556107cf610e63565b6107d88b610c17565b6107e188610f02565b6107eb8a8a610f2a565b6107f487610fbb565b6107fd86610da6565b61083061082b60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b849055565b61086461085e60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b83519055565b61089b61089260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60208401519055565b6108d26108c960017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b60408401519055565b61090961090060017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b60608401519055565b61094061093760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b60808401519055565b61097761096e60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60a08401519055565b61098084611099565b610989856110c3565b61099161068d565b67ffffffffffffffff168767ffffffffffffffff161015610a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b6105b860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b6105b860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b610ad7610d25565b610ae16000611537565b565b610aeb610d25565b610af58282610f2a565b5050565b60006105ef6105eb60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60006105ef6105eb60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b610b61610d25565b61063581610fbb565b6105b860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b60006105ef6105eb60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b610bcd610d25565b610635816110c3565b610bde610d25565b61063581610f02565b60006105ef6105eb60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b610c1f610d25565b73ffffffffffffffffffffffffffffffffffffffff8116610cc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161078d565b61063581611537565b6105b860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b6105b860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161078d565b610dcf7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610e5791906119aa565b60405180910390a35050565b600054610100900460ff16610efa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae16115ae565b6067819055604080516020808201849052825180830390910181529082019091526000610e26565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae91906119aa565b60405180910390a3505050565b610fc361068d565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610e26565b80158015906110a85750606a54155b156110b257606a55565b606a546000036106355743606a5550565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611173576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840161078d565b6001816040015160ff161161120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e20310000000000000000000000000000000000606482015260840161078d565b6068546080820151825167ffffffffffffffff9092169161122b9190611aa1565b63ffffffff161115611299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b6000816020015160ff1611611330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f7420626520300000000000000000000000000000000000606482015260840161078d565b8051602082015163ffffffff82169160ff90911690611350908290611ac0565b61135a9190611b0a565b63ffffffff16146113ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840161078d565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae133611537565b803573ffffffffffffffffffffffffffffffffffffffff8116811461167257600080fd5b919050565b60006020828403121561168957600080fd5b6116928261164e565b9392505050565b803567ffffffffffffffff8116811461167257600080fd5b60405160c0810167ffffffffffffffff811182821017156116fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff8116811461167257600080fd5b803560ff8116811461167257600080fd5b600060c0828403121561173857600080fd5b60405160c0810181811067ffffffffffffffff82111715611782577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061179183611701565b815261179f60208401611715565b60208201526117b060408401611715565b60408201526117c160608401611701565b60608201526117d260808401611701565b608082015260a08301356fffffffffffffffffffffffffffffffff811681146117fa57600080fd5b60a0919091015292915050565b6000806000806000806000806000808a8c0361028081121561182857600080fd5b6118318c61164e565b9a5060208c0135995060408c0135985060608c0135975061185460808d01611699565b965061186260a08d0161164e565b95506118718d60c08e01611726565b94506101808c013593506118886101a08d0161164e565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe40820112156118ba57600080fd5b506118c36116b1565b6118d06101c08d0161164e565b81526118df6101e08d0161164e565b60208201526118f16102008d0161164e565b60408201526119036102208d0161164e565b60608201526119156102408d0161164e565b60808201526119276102608d0161164e565b60a0820152809150509295989b9194979a5092959850565b6000815180845260005b8181101561196557602081850181015186830182015201611949565b81811115611977576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611692602083018461193f565b600080604083850312156119d057600080fd5b50508035926020909101359150565b6000602082840312156119f157600080fd5b61169282611699565b600060c08284031215611a0c57600080fd5b6116928383611726565b600060208284031215611a2857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611a7057611a70611a2f565b500390565b600067ffffffffffffffff808316818516808303821115611a9857611a98611a2f565b01949350505050565b600063ffffffff808316818516808303821115611a9857611a98611a2f565b600063ffffffff80841680611afe577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611b2d57611b2d611a2f565b0294935050505056fea164736f6c634300080f000a53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77001d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102265760003560e01c8063935f029e1161012a578063cc731b02116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610575578063fd32aa0f1461057d578063ffa1ad741461058557600080fd5b8063f45e65d814610558578063f68016b71461056157600080fd5b8063cc731b0214610400578063dac6e63a14610534578063e81b2c6d1461053c578063f2fde38b1461054557600080fd5b8063bc49ce5f116100f9578063bc49ce5f146103ca578063c4e8ddfa146103d2578063c71973f6146103da578063c9b26f61146103ed57600080fd5b8063935f029e146103945780639b7d7f0a146103a7578063a7119869146103af578063b40a817c146103b757600080fd5b80634add321d116101bd57806354fd4d501161018c57806361d157681161017157806361d1576814610366578063715018a61461036e5780638da5cb5b1461037657600080fd5b806354fd4d50146103155780635d73369c1461035e57600080fd5b80634add321d146102b25780634d9f1559146102d35780634f16540b146102db5780635228a6ac1461030257600080fd5b806318d13918116101f957806318d139181461028457806319f5cea8146102995780631fd19ee1146102a157806348cd4cb1146102a957600080fd5b806306c926571461022b578063078f29cf146102465780630a49cb03146102735780630c18c1621461027b575b600080fd5b61023361058d565b6040519081526020015b60405180910390f35b61024e6105bb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023d565b61024e6105f4565b61023360655481565b610297610292366004611677565b610624565b005b610233610638565b61024e610663565b610233606a5481565b6102ba61068d565b60405167ffffffffffffffff909116815260200161023d565b61024e6106b3565b6102337f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b610297610310366004611807565b6106e3565b6103516040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b60405161023d91906119aa565b610233610a79565b610233610aa4565b610297610acf565b60335473ffffffffffffffffffffffffffffffffffffffff1661024e565b6102976103a23660046119bd565b610ae3565b61024e610af9565b61024e610b29565b6102976103c53660046119df565b610b59565b610233610b6a565b61024e610b95565b6102976103e83660046119fa565b610bc5565b6102976103fb366004611a16565b610bd6565b6104c46040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b60405161023d9190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61024e610be7565b61023360675481565b610297610553366004611677565b610c17565b61023360665481565b6068546102ba9067ffffffffffffffff1681565b610233610ccb565b610233610cf6565b610233600081565b6105b860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b81565b60006105ef6105eb60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b5490565b905090565b60006105ef6105eb60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b61062c610d25565b61063581610da6565b50565b6105b860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60006105ef7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b6069546000906105ef9063ffffffff6a0100000000000000000000820481169116611a75565b60006105ef6105eb60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b600054600390610100900460ff16158015610705575060005460ff8083169116105b610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556107cf610e63565b6107d88b610c17565b6107e188610f02565b6107eb8a8a610f2a565b6107f487610fbb565b6107fd86610da6565b61083061082b60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b849055565b61086461085e60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b83519055565b61089b61089260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60208401519055565b6108d26108c960017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b60408401519055565b61090961090060017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b60608401519055565b61094061093760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b60808401519055565b61097761096e60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60a08401519055565b61098084611099565b610989856110c3565b61099161068d565b67ffffffffffffffff168767ffffffffffffffff161015610a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b6105b860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b6105b860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b610ad7610d25565b610ae16000611537565b565b610aeb610d25565b610af58282610f2a565b5050565b60006105ef6105eb60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60006105ef6105eb60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b610b61610d25565b61063581610fbb565b6105b860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b60006105ef6105eb60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b610bcd610d25565b610635816110c3565b610bde610d25565b61063581610f02565b60006105ef6105eb60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b610c1f610d25565b73ffffffffffffffffffffffffffffffffffffffff8116610cc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161078d565b61063581611537565b6105b860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b6105b860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161078d565b610dcf7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610e5791906119aa565b60405180910390a35050565b600054610100900460ff16610efa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae16115ae565b6067819055604080516020808201849052825180830390910181529082019091526000610e26565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae91906119aa565b60405180910390a3505050565b610fc361068d565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610e26565b80158015906110a85750606a54155b156110b257606a55565b606a546000036106355743606a5550565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611173576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840161078d565b6001816040015160ff161161120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e20310000000000000000000000000000000000606482015260840161078d565b6068546080820151825167ffffffffffffffff9092169161122b9190611aa1565b63ffffffff161115611299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b6000816020015160ff1611611330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f7420626520300000000000000000000000000000000000606482015260840161078d565b8051602082015163ffffffff82169160ff90911690611350908290611ac0565b61135a9190611b0a565b63ffffffff16146113ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840161078d565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae133611537565b803573ffffffffffffffffffffffffffffffffffffffff8116811461167257600080fd5b919050565b60006020828403121561168957600080fd5b6116928261164e565b9392505050565b803567ffffffffffffffff8116811461167257600080fd5b60405160c0810167ffffffffffffffff811182821017156116fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff8116811461167257600080fd5b803560ff8116811461167257600080fd5b600060c0828403121561173857600080fd5b60405160c0810181811067ffffffffffffffff82111715611782577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061179183611701565b815261179f60208401611715565b60208201526117b060408401611715565b60408201526117c160608401611701565b60608201526117d260808401611701565b608082015260a08301356fffffffffffffffffffffffffffffffff811681146117fa57600080fd5b60a0919091015292915050565b6000806000806000806000806000808a8c0361028081121561182857600080fd5b6118318c61164e565b9a5060208c0135995060408c0135985060608c0135975061185460808d01611699565b965061186260a08d0161164e565b95506118718d60c08e01611726565b94506101808c013593506118886101a08d0161164e565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe40820112156118ba57600080fd5b506118c36116b1565b6118d06101c08d0161164e565b81526118df6101e08d0161164e565b60208201526118f16102008d0161164e565b60408201526119036102208d0161164e565b60608201526119156102408d0161164e565b60808201526119276102608d0161164e565b60a0820152809150509295989b9194979a5092959850565b6000815180845260005b8181101561196557602081850181015186830182015201611949565b81811115611977576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611692602083018461193f565b600080604083850312156119d057600080fd5b50508035926020909101359150565b6000602082840312156119f157600080fd5b61169282611699565b600060c08284031215611a0c57600080fd5b6116928383611726565b600060208284031215611a2857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611a7057611a70611a2f565b500390565b600067ffffffffffffffff808316818516808303821115611a9857611a98611a2f565b01949350505050565b600063ffffffff808316818516808303821115611a9857611a98611a2f565b600063ffffffff80841680611afe577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611b2d57611b2d611a2f565b0294935050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))": { - "params": { - "_addresses": "Set of L1 contract addresses. These should be the proxies.", - "_batchInbox": "Batch inbox address. An identifier for the op-node to find canonical data.", - "_batcherHash": "Initial batcher hash.", - "_config": "Initial ResourceConfig.", - "_gasLimit": "Initial gas limit.", - "_overhead": "Initial overhead value.", - "_owner": "Initial owner of the contract.", - "_scalar": "Initial scalar value.", - "_startBlock": "Starting block for the op-node to search for logs from. Contracts that were deployed before this field existed need to have this field set manually via an override. Newly deployed contracts should set this value to uint256(0).", - "_unsafeBlockSigner": "Initial unsafe block signer address." - } - }, - "minimumGasLimit()": { - "returns": { - "_0": "uint64 Minimum gas limit." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "resourceConfig()": { - "returns": { - "_0": "ResourceConfig" - } - }, - "setBatcherHash(bytes32)": { - "params": { - "_batcherHash": "New batcher hash." - } - }, - "setGasConfig(uint256,uint256)": { - "params": { - "_overhead": "New overhead value.", - "_scalar": "New scalar value." - } - }, - "setGasLimit(uint64)": { - "params": { - "_gasLimit": "New gas limit." - } - }, - "setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))": { - "params": { - "_config": "The new resource config values." - } - }, - "setUnsafeBlockSigner(address)": { - "params": { - "_unsafeBlockSigner": "New unsafe block signer address." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - }, - "unsafeBlockSigner()": { - "returns": { - "addr_": "Address of the unsafe block signer." - } - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "params": { - "data": "Encoded update data.", - "updateType": "Type of update.", - "version": "SystemConfig version." - } - } - }, - "title": "SystemConfig" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"enum SystemConfig.UpdateType\",\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ConfigUpdate\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"BATCH_INBOX_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L1_CROSS_DOMAIN_MESSENGER_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L1_ERC_721_BRIDGE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L1_STANDARD_BRIDGE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L2_OUTPUT_ORACLE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OPTIMISM_PORTAL_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"UNSAFE_BLOCK_SIGNER_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"batchInbox\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"batcherHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"gasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_scalar\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_batcherHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"_unsafeBlockSigner\",\"type\":\"address\"},{\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"_config\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}]},{\"internalType\":\"uint256\",\"name\":\"_startBlock\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_batchInbox\",\"type\":\"address\"},{\"internalType\":\"struct SystemConfig.Addresses\",\"name\":\"_addresses\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"address\",\"name\":\"l1CrossDomainMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1ERC721Bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1StandardBridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l2OutputOracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismPortal\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismMintableERC20Factory\",\"type\":\"address\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l1CrossDomainMessenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l1ERC721Bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l1StandardBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2OutputOracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"optimismMintableERC20Factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"optimismPortal\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"overhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"renounceOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"resourceConfig\",\"outputs\":[{\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}]}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"scalar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_batcherHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setBatcherHash\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_scalar\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setGasConfig\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setGasLimit\"},{\"inputs\":[{\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"_config\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setResourceConfig\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_unsafeBlockSigner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setUnsafeBlockSigner\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"startBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"unsafeBlockSigner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))\":{\"params\":{\"_addresses\":\"Set of L1 contract addresses. These should be the proxies.\",\"_batchInbox\":\"Batch inbox address. An identifier for the op-node to find canonical data.\",\"_batcherHash\":\"Initial batcher hash.\",\"_config\":\"Initial ResourceConfig.\",\"_gasLimit\":\"Initial gas limit.\",\"_overhead\":\"Initial overhead value.\",\"_owner\":\"Initial owner of the contract.\",\"_scalar\":\"Initial scalar value.\",\"_startBlock\":\"Starting block for the op-node to search for logs from. Contracts that were deployed before this field existed need to have this field set manually via an override. Newly deployed contracts should set this value to uint256(0).\",\"_unsafeBlockSigner\":\"Initial unsafe block signer address.\"}},\"minimumGasLimit()\":{\"returns\":{\"_0\":\"uint64 Minimum gas limit.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"resourceConfig()\":{\"returns\":{\"_0\":\"ResourceConfig\"}},\"setBatcherHash(bytes32)\":{\"params\":{\"_batcherHash\":\"New batcher hash.\"}},\"setGasConfig(uint256,uint256)\":{\"params\":{\"_overhead\":\"New overhead value.\",\"_scalar\":\"New scalar value.\"}},\"setGasLimit(uint64)\":{\"params\":{\"_gasLimit\":\"New gas limit.\"}},\"setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))\":{\"params\":{\"_config\":\"The new resource config values.\"}},\"setUnsafeBlockSigner(address)\":{\"params\":{\"_unsafeBlockSigner\":\"New unsafe block signer address.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unsafeBlockSigner()\":{\"returns\":{\"addr_\":\"Address of the unsafe block signer.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BATCH_INBOX_SLOT()\":{\"notice\":\"Storage slot that the batch inbox address is stored at.\"},\"L1_CROSS_DOMAIN_MESSENGER_SLOT()\":{\"notice\":\"Storage slot that the L1CrossDomainMessenger address is stored at.\"},\"L1_ERC_721_BRIDGE_SLOT()\":{\"notice\":\"Storage slot that the L1ERC721Bridge address is stored at.\"},\"L1_STANDARD_BRIDGE_SLOT()\":{\"notice\":\"Storage slot that the L1StandardBridge address is stored at.\"},\"L2_OUTPUT_ORACLE_SLOT()\":{\"notice\":\"Storage slot that the L2OutputOracle address is stored at.\"},\"OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT()\":{\"notice\":\"Storage slot that the OptimismMintableERC20Factory address is stored at.\"},\"OPTIMISM_PORTAL_SLOT()\":{\"notice\":\"Storage slot that the OptimismPortal address is stored at.\"},\"UNSAFE_BLOCK_SIGNER_SLOT()\":{\"notice\":\"Storage slot that the unsafe block signer is stored at. Storing it at this deterministic storage slot allows for decoupling the storage layout from the way that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value.\"},\"VERSION()\":{\"notice\":\"Version identifier, used for upgrades.\"},\"batchInbox()\":{\"notice\":\"Getter for the BatchInbox address.\"},\"batcherHash()\":{\"notice\":\"Identifier for the batcher. For version 1 of this configuration, this is represented as an address left-padded with zeros to 32 bytes.\"},\"constructor\":{\"notice\":\"Constructs the SystemConfig contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)`\"},\"gasLimit()\":{\"notice\":\"L2 block gas limit.\"},\"initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))\":{\"notice\":\"Initializer. The resource config must be set before the require check.\"},\"l1CrossDomainMessenger()\":{\"notice\":\"Getter for the L1CrossDomainMessenger address.\"},\"l1ERC721Bridge()\":{\"notice\":\"Getter for the L1ERC721Bridge address.\"},\"l1StandardBridge()\":{\"notice\":\"Getter for the L1StandardBridge address.\"},\"l2OutputOracle()\":{\"notice\":\"Getter for the L2OutputOracle address.\"},\"minimumGasLimit()\":{\"notice\":\"Returns the minimum L2 gas limit that can be safely set for the system to operate. The L2 gas limit must be larger than or equal to the amount of gas that is allocated for deposits per block plus the amount of gas that is allocated for the system transaction. This function is used to determine if changes to parameters are safe.\"},\"optimismMintableERC20Factory()\":{\"notice\":\"Getter for the OptimismMintableERC20Factory address.\"},\"optimismPortal()\":{\"notice\":\"Getter for the OptimismPortal address.\"},\"overhead()\":{\"notice\":\"Fixed L2 gas overhead. Used as part of the L2 fee calculation.\"},\"resourceConfig()\":{\"notice\":\"A getter for the resource config. Ensures that the struct is returned instead of a tuple.\"},\"scalar()\":{\"notice\":\"Dynamic L2 gas overhead. Used as part of the L2 fee calculation.\"},\"setBatcherHash(bytes32)\":{\"notice\":\"Updates the batcher hash. Can only be called by the owner.\"},\"setGasConfig(uint256,uint256)\":{\"notice\":\"Updates gas config. Can only be called by the owner.\"},\"setGasLimit(uint64)\":{\"notice\":\"Updates the L2 gas limit. Can only be called by the owner.\"},\"setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))\":{\"notice\":\"An external setter for the resource config. In the future, this method may emit an event that the `op-node` picks up for when the resource config is changed.\"},\"setUnsafeBlockSigner(address)\":{\"notice\":\"Updates the unsafe block signer address. Can only be called by the owner.\"},\"startBlock()\":{\"notice\":\"The block at which the op-node can start searching for logs from.\"},\"unsafeBlockSigner()\":{\"notice\":\"High level getter for the unsafe block signer address. Unsafe blocks can be propagated across the p2p network if they are signed by the key corresponding to this address.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/SystemConfig.sol\":\"SystemConfig\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L1/SystemConfig.sol\":{\"keccak256\":\"0x4bbbc7868e948c44f29285a69383e93251a0c330a67929fb72def01cec060d4e\",\"urls\":[\"bzz-raw://1e7ea2f8b3d49bee9c753f107ede6eda93b2cc0e34d0643fa14ebbb26c19e71b\",\"dweb:/ipfs/QmRP81F8FRVXVZs6u2f2poEPDnbFZhNwNYxHgCVEhGpEmB\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 2, - "receipt": "", - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 29536, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 29539, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 31067, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 29408, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 29528, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 61293, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "overhead", - "offset": 0, - "slot": "101", - "type": "t_uint256" - }, - { - "astId": 61296, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "scalar", - "offset": 0, - "slot": "102", - "type": "t_uint256" - }, - { - "astId": 61299, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "batcherHash", - "offset": 0, - "slot": "103", - "type": "t_bytes32" - }, - { - "astId": 61302, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "gasLimit", - "offset": 0, - "slot": "104", - "type": "t_uint64" - }, - { - "astId": 61306, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_resourceConfig", - "offset": 0, - "slot": "105", - "type": "t_struct(ResourceConfig)60831_storage" - }, - { - "astId": 61319, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "startBlock", - "offset": 0, - "slot": "106", - "type": "t_uint256" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_struct(ResourceConfig)60831_storage": { - "encoding": "inplace", - "label": "struct ResourceMetering.ResourceConfig", - "numberOfBytes": "32", - "members": [ - { - "astId": 60820, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "maxResourceLimit", - "offset": 0, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 60822, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "elasticityMultiplier", - "offset": 4, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 60824, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "baseFeeMaxChangeDenominator", - "offset": 5, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 60826, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "minimumBaseFee", - "offset": 6, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 60828, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "systemTxMaxGas", - "offset": 10, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 60830, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "maximumBaseFee", - "offset": 14, - "slot": "0", - "type": "t_uint128" - } - ] - }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "encoding": "inplace", - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0xc0537bec4365c978607ef4cc2d92b13f50fec84f8f4e7692779c5a473edba743", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "BATCH_INBOX_SLOT()": { - "notice": "Storage slot that the batch inbox address is stored at." - }, - "L1_CROSS_DOMAIN_MESSENGER_SLOT()": { - "notice": "Storage slot that the L1CrossDomainMessenger address is stored at." - }, - "L1_ERC_721_BRIDGE_SLOT()": { - "notice": "Storage slot that the L1ERC721Bridge address is stored at." - }, - "L1_STANDARD_BRIDGE_SLOT()": { - "notice": "Storage slot that the L1StandardBridge address is stored at." - }, - "L2_OUTPUT_ORACLE_SLOT()": { - "notice": "Storage slot that the L2OutputOracle address is stored at." - }, - "OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT()": { - "notice": "Storage slot that the OptimismMintableERC20Factory address is stored at." - }, - "OPTIMISM_PORTAL_SLOT()": { - "notice": "Storage slot that the OptimismPortal address is stored at." - }, - "UNSAFE_BLOCK_SIGNER_SLOT()": { - "notice": "Storage slot that the unsafe block signer is stored at. Storing it at this deterministic storage slot allows for decoupling the storage layout from the way that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value." - }, - "VERSION()": { - "notice": "Version identifier, used for upgrades." - }, - "batchInbox()": { - "notice": "Getter for the BatchInbox address." - }, - "batcherHash()": { - "notice": "Identifier for the batcher. For version 1 of this configuration, this is represented as an address left-padded with zeros to 32 bytes." - }, - "constructor": { - "notice": "Constructs the SystemConfig contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)`" - }, - "gasLimit()": { - "notice": "L2 block gas limit." - }, - "initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))": { - "notice": "Initializer. The resource config must be set before the require check." - }, - "l1CrossDomainMessenger()": { - "notice": "Getter for the L1CrossDomainMessenger address." - }, - "l1ERC721Bridge()": { - "notice": "Getter for the L1ERC721Bridge address." - }, - "l1StandardBridge()": { - "notice": "Getter for the L1StandardBridge address." - }, - "l2OutputOracle()": { - "notice": "Getter for the L2OutputOracle address." - }, - "minimumGasLimit()": { - "notice": "Returns the minimum L2 gas limit that can be safely set for the system to operate. The L2 gas limit must be larger than or equal to the amount of gas that is allocated for deposits per block plus the amount of gas that is allocated for the system transaction. This function is used to determine if changes to parameters are safe." - }, - "optimismMintableERC20Factory()": { - "notice": "Getter for the OptimismMintableERC20Factory address." - }, - "optimismPortal()": { - "notice": "Getter for the OptimismPortal address." - }, - "overhead()": { - "notice": "Fixed L2 gas overhead. Used as part of the L2 fee calculation." - }, - "resourceConfig()": { - "notice": "A getter for the resource config. Ensures that the struct is returned instead of a tuple." - }, - "scalar()": { - "notice": "Dynamic L2 gas overhead. Used as part of the L2 fee calculation." - }, - "setBatcherHash(bytes32)": { - "notice": "Updates the batcher hash. Can only be called by the owner." - }, - "setGasConfig(uint256,uint256)": { - "notice": "Updates gas config. Can only be called by the owner." - }, - "setGasLimit(uint64)": { - "notice": "Updates the L2 gas limit. Can only be called by the owner." - }, - "setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))": { - "notice": "An external setter for the resource config. In the future, this method may emit an event that the `op-node` picks up for when the resource config is changed." - }, - "setUnsafeBlockSigner(address)": { - "notice": "Updates the unsafe block signer address. Can only be called by the owner." - }, - "startBlock()": { - "notice": "The block at which the op-node can start searching for logs from." - }, - "unsafeBlockSigner()": { - "notice": "High level getter for the unsafe block signer address. Unsafe blocks can be propagated across the p2p network if they are signed by the key corresponding to this address." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "notice": "Emitted when configuration is updated." - } - }, - "notice": "The SystemConfig contract is used to manage configuration of an Optimism network. All configuration is stored on L1 and picked up by L2 as part of the derviation of the L2 chain." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/SystemConfigProxy.json b/packages/contracts-bedrock/deployments/mainnet/SystemConfigProxy.json deleted file mode 100644 index 9887fb571564..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/SystemConfigProxy.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0x229047fed2591dbec1eF1118d64F7aF3dB9EB290", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x17a29cb8106fa26e61bd5eff33b448b7ba10864f201d973f1abcfa608af87015", - "receipt": { - "to": null, - "from": "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960", - "contractAddress": "0x229047fed2591dbec1eF1118d64F7aF3dB9EB290", - "transactionIndex": 87, - "gasUsed": "523960", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000800000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000400000000", - "blockHash": "0xb2f954f82f28e496964b136b4d99833bccc1b9f51e53e85170ff4afaffdd7ed2", - "transactionHash": "0x17a29cb8106fa26e61bd5eff33b448b7ba10864f201d973f1abcfa608af87015", - "logs": [ - { - "transactionIndex": 87, - "blockNumber": 17365804, - "transactionHash": "0x17a29cb8106fa26e61bd5eff33b448b7ba10864f201d973f1abcfa608af87015", - "address": "0x229047fed2591dbec1eF1118d64F7aF3dB9EB290", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000543ba4aadbab8f9025686bd03993043599c6fb04", - "logIndex": 226, - "blockHash": "0xb2f954f82f28e496964b136b4d99833bccc1b9f51e53e85170ff4afaffdd7ed2" - } - ], - "blockNumber": 17365804, - "cumulativeGasUsed": "8661026", - "status": 1, - "byzantium": true - }, - "args": [ - "0x543bA4AADBAb8f9025686Bd03993043599c6fB04" - ], - "numDeployments": 1, - "solcInputHash": "13ac93d026822f719ad110af836d1582", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33b903585eb9cfc60a70bcdf4ee44220b173caff16dfb9071cd0668c7a551265\",\"dweb:/ipfs/QmXHUZ9brinN1WS9i63ocRQsQidY96WePDBhBsFRhDmVjr\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/SystemDictator.json b/packages/contracts-bedrock/deployments/mainnet/SystemDictator.json deleted file mode 100644 index d42b0bbd35e5..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/SystemDictator.json +++ /dev/null @@ -1,1418 +0,0 @@ -{ - "address": "0x09E040a72FD3492355C5aEEdbC3154075f83488a", - "abi": [ - { - "inputs": [], - "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": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "EXIT_1_NO_RETURN_STEP", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PROXY_TRANSFER_STEP", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "config", - "outputs": [ - { - "components": [ - { - "internalType": "contract AddressManager", - "name": "addressManager", - "type": "address" - }, - { - "internalType": "contract ProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, - { - "internalType": "address", - "name": "controller", - "type": "address" - }, - { - "internalType": "address", - "name": "finalOwner", - "type": "address" - } - ], - "internalType": "struct SystemDictator.GlobalConfig", - "name": "globalConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "l2OutputOracleProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismPortalProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1CrossDomainMessengerProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1StandardBridgeProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismMintableERC20FactoryProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1ERC721BridgeProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "systemConfigProxy", - "type": "address" - } - ], - "internalType": "struct SystemDictator.ProxyAddressConfig", - "name": "proxyAddressConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "contract L2OutputOracle", - "name": "l2OutputOracleImpl", - "type": "address" - }, - { - "internalType": "contract OptimismPortal", - "name": "optimismPortalImpl", - "type": "address" - }, - { - "internalType": "contract L1CrossDomainMessenger", - "name": "l1CrossDomainMessengerImpl", - "type": "address" - }, - { - "internalType": "contract L1StandardBridge", - "name": "l1StandardBridgeImpl", - "type": "address" - }, - { - "internalType": "contract OptimismMintableERC20Factory", - "name": "optimismMintableERC20FactoryImpl", - "type": "address" - }, - { - "internalType": "contract L1ERC721Bridge", - "name": "l1ERC721BridgeImpl", - "type": "address" - }, - { - "internalType": "contract PortalSender", - "name": "portalSenderImpl", - "type": "address" - }, - { - "internalType": "contract SystemConfig", - "name": "systemConfigImpl", - "type": "address" - } - ], - "internalType": "struct SystemDictator.ImplementationAddressConfig", - "name": "implementationAddressConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "overhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "scalar", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "batcherHash", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "gasLimit", - "type": "uint64" - }, - { - "internalType": "address", - "name": "unsafeBlockSigner", - "type": "address" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "resourceConfig", - "type": "tuple" - } - ], - "internalType": "struct SystemDictator.SystemConfigConfig", - "name": "systemConfigConfig", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentStep", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "dynamicConfigSet", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "exit1", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "exited", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "finalize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "finalized", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "components": [ - { - "internalType": "contract AddressManager", - "name": "addressManager", - "type": "address" - }, - { - "internalType": "contract ProxyAdmin", - "name": "proxyAdmin", - "type": "address" - }, - { - "internalType": "address", - "name": "controller", - "type": "address" - }, - { - "internalType": "address", - "name": "finalOwner", - "type": "address" - } - ], - "internalType": "struct SystemDictator.GlobalConfig", - "name": "globalConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "l2OutputOracleProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismPortalProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1CrossDomainMessengerProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1StandardBridgeProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismMintableERC20FactoryProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "l1ERC721BridgeProxy", - "type": "address" - }, - { - "internalType": "address", - "name": "systemConfigProxy", - "type": "address" - } - ], - "internalType": "struct SystemDictator.ProxyAddressConfig", - "name": "proxyAddressConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "contract L2OutputOracle", - "name": "l2OutputOracleImpl", - "type": "address" - }, - { - "internalType": "contract OptimismPortal", - "name": "optimismPortalImpl", - "type": "address" - }, - { - "internalType": "contract L1CrossDomainMessenger", - "name": "l1CrossDomainMessengerImpl", - "type": "address" - }, - { - "internalType": "contract L1StandardBridge", - "name": "l1StandardBridgeImpl", - "type": "address" - }, - { - "internalType": "contract OptimismMintableERC20Factory", - "name": "optimismMintableERC20FactoryImpl", - "type": "address" - }, - { - "internalType": "contract L1ERC721Bridge", - "name": "l1ERC721BridgeImpl", - "type": "address" - }, - { - "internalType": "contract PortalSender", - "name": "portalSenderImpl", - "type": "address" - }, - { - "internalType": "contract SystemConfig", - "name": "systemConfigImpl", - "type": "address" - } - ], - "internalType": "struct SystemDictator.ImplementationAddressConfig", - "name": "implementationAddressConfig", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "overhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "scalar", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "batcherHash", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "gasLimit", - "type": "uint64" - }, - { - "internalType": "address", - "name": "unsafeBlockSigner", - "type": "address" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "resourceConfig", - "type": "tuple" - } - ], - "internalType": "struct SystemDictator.SystemConfigConfig", - "name": "systemConfigConfig", - "type": "tuple" - } - ], - "internalType": "struct SystemDictator.DeployConfig", - "name": "_config", - "type": "tuple" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l2OutputOracleDynamicConfig", - "outputs": [ - { - "internalType": "uint256", - "name": "l2OutputOracleStartingBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l2OutputOracleStartingTimestamp", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "oldL1CrossDomainMessenger", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "optimismPortalDynamicConfig", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "phase1", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "phase2", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step1", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step2", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step3", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step4", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "step5", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "l2OutputOracleStartingBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l2OutputOracleStartingTimestamp", - "type": "uint256" - } - ], - "internalType": "struct SystemDictator.L2OutputOracleDynamicConfig", - "name": "_l2OutputOracleDynamicConfig", - "type": "tuple" - }, - { - "internalType": "bool", - "name": "_optimismPortalDynamicConfig", - "type": "bool" - } - ], - "name": "updateDynamicConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0xaca6cdc0a101d28f869a0acfb58a6527ffbbee2bb929bd33cc143f8256639dce", - "receipt": { - "to": null, - "from": "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960", - "contractAddress": "0x09E040a72FD3492355C5aEEdbC3154075f83488a", - "transactionIndex": 107, - "gasUsed": "3480736", - "logsBloom": "0x00000800000000000000000000000000000000000000400000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040001000000000000000000000000000000000000020000000000000000000800000000000020000000000000000000400000000000000000000000020000000000000000000080000000000000000000000000010000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x03e7785abc4b15223aad4b7a52b0ece0c5b9c21d4efa3473435697f373d16dd9", - "transactionHash": "0xaca6cdc0a101d28f869a0acfb58a6527ffbbee2bb929bd33cc143f8256639dce", - "logs": [ - { - "transactionIndex": 107, - "blockNumber": 17365813, - "transactionHash": "0xaca6cdc0a101d28f869a0acfb58a6527ffbbee2bb929bd33cc143f8256639dce", - "address": "0x09E040a72FD3492355C5aEEdbC3154075f83488a", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000354f3f4ecdca5e0a7ace08d71348cdc1dab48960" - ], - "data": "0x", - "logIndex": 273, - "blockHash": "0x03e7785abc4b15223aad4b7a52b0ece0c5b9c21d4efa3473435697f373d16dd9" - }, - { - "transactionIndex": 107, - "blockNumber": 17365813, - "transactionHash": "0xaca6cdc0a101d28f869a0acfb58a6527ffbbee2bb929bd33cc143f8256639dce", - "address": "0x09E040a72FD3492355C5aEEdbC3154075f83488a", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x000000000000000000000000354f3f4ecdca5e0a7ace08d71348cdc1dab48960", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ], - "data": "0x", - "logIndex": 274, - "blockHash": "0x03e7785abc4b15223aad4b7a52b0ece0c5b9c21d4efa3473435697f373d16dd9" - }, - { - "transactionIndex": 107, - "blockNumber": 17365813, - "transactionHash": "0xaca6cdc0a101d28f869a0acfb58a6527ffbbee2bb929bd33cc143f8256639dce", - "address": "0x09E040a72FD3492355C5aEEdbC3154075f83488a", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 275, - "blockHash": "0x03e7785abc4b15223aad4b7a52b0ece0c5b9c21d4efa3473435697f373d16dd9" - } - ], - "blockNumber": 17365813, - "cumulativeGasUsed": "12742741", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "13ac93d026822f719ad110af836d1582", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"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\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"EXIT_1_NO_RETURN_STEP\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PROXY_TRANSFER_STEP\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"config\",\"outputs\":[{\"components\":[{\"internalType\":\"contract AddressManager\",\"name\":\"addressManager\",\"type\":\"address\"},{\"internalType\":\"contract ProxyAdmin\",\"name\":\"proxyAdmin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"finalOwner\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.GlobalConfig\",\"name\":\"globalConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"l2OutputOracleProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismPortalProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1CrossDomainMessengerProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1StandardBridgeProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismMintableERC20FactoryProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1ERC721BridgeProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"systemConfigProxy\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.ProxyAddressConfig\",\"name\":\"proxyAddressConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"l2OutputOracleImpl\",\"type\":\"address\"},{\"internalType\":\"contract OptimismPortal\",\"name\":\"optimismPortalImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1CrossDomainMessenger\",\"name\":\"l1CrossDomainMessengerImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1StandardBridge\",\"name\":\"l1StandardBridgeImpl\",\"type\":\"address\"},{\"internalType\":\"contract OptimismMintableERC20Factory\",\"name\":\"optimismMintableERC20FactoryImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1ERC721Bridge\",\"name\":\"l1ERC721BridgeImpl\",\"type\":\"address\"},{\"internalType\":\"contract PortalSender\",\"name\":\"portalSenderImpl\",\"type\":\"address\"},{\"internalType\":\"contract SystemConfig\",\"name\":\"systemConfigImpl\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.ImplementationAddressConfig\",\"name\":\"implementationAddressConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"scalar\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"batcherHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"unsafeBlockSigner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}],\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"resourceConfig\",\"type\":\"tuple\"}],\"internalType\":\"struct SystemDictator.SystemConfigConfig\",\"name\":\"systemConfigConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentStep\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dynamicConfigSet\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"exit1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"exited\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"finalize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"finalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"contract AddressManager\",\"name\":\"addressManager\",\"type\":\"address\"},{\"internalType\":\"contract ProxyAdmin\",\"name\":\"proxyAdmin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"finalOwner\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.GlobalConfig\",\"name\":\"globalConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"l2OutputOracleProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismPortalProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1CrossDomainMessengerProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1StandardBridgeProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismMintableERC20FactoryProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1ERC721BridgeProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"systemConfigProxy\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.ProxyAddressConfig\",\"name\":\"proxyAddressConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"l2OutputOracleImpl\",\"type\":\"address\"},{\"internalType\":\"contract OptimismPortal\",\"name\":\"optimismPortalImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1CrossDomainMessenger\",\"name\":\"l1CrossDomainMessengerImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1StandardBridge\",\"name\":\"l1StandardBridgeImpl\",\"type\":\"address\"},{\"internalType\":\"contract OptimismMintableERC20Factory\",\"name\":\"optimismMintableERC20FactoryImpl\",\"type\":\"address\"},{\"internalType\":\"contract L1ERC721Bridge\",\"name\":\"l1ERC721BridgeImpl\",\"type\":\"address\"},{\"internalType\":\"contract PortalSender\",\"name\":\"portalSenderImpl\",\"type\":\"address\"},{\"internalType\":\"contract SystemConfig\",\"name\":\"systemConfigImpl\",\"type\":\"address\"}],\"internalType\":\"struct SystemDictator.ImplementationAddressConfig\",\"name\":\"implementationAddressConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"scalar\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"batcherHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"unsafeBlockSigner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}],\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"resourceConfig\",\"type\":\"tuple\"}],\"internalType\":\"struct SystemDictator.SystemConfigConfig\",\"name\":\"systemConfigConfig\",\"type\":\"tuple\"}],\"internalType\":\"struct SystemDictator.DeployConfig\",\"name\":\"_config\",\"type\":\"tuple\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2OutputOracleDynamicConfig\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"l2OutputOracleStartingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l2OutputOracleStartingTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldL1CrossDomainMessenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"optimismPortalDynamicConfig\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"phase1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"phase2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step3\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step4\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"step5\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"l2OutputOracleStartingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l2OutputOracleStartingTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"struct SystemDictator.L2OutputOracleDynamicConfig\",\"name\":\"_l2OutputOracleDynamicConfig\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"_optimismPortalDynamicConfig\",\"type\":\"bool\"}],\"name\":\"updateDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(((address,address,address,address),(address,address,address,address,address,address,address),(address,address,address,address,address,address,address,address),(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128))))\":{\"params\":{\"_config\":\"System configuration.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"updateDynamicConfig((uint256,uint256),bool)\":{\"params\":{\"_l2OutputOracleDynamicConfig\":\"Dynamic L2OutputOracle config.\",\"_optimismPortalDynamicConfig\":\"Dynamic OptimismPortal config.\"}}},\"title\":\"SystemDictator\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"EXIT_1_NO_RETURN_STEP()\":{\"notice\":\"Step after which exit 1 can no longer be used.\"},\"PROXY_TRANSFER_STEP()\":{\"notice\":\"Step where proxy ownership is transferred.\"},\"config()\":{\"notice\":\"System configuration.\"},\"constructor\":{\"notice\":\"Constructor required to ensure that the implementation of the SystemDictator is initialized upon deployment.\"},\"currentStep()\":{\"notice\":\"Current step;\"},\"dynamicConfigSet()\":{\"notice\":\"Whether or not dynamic config has been set.\"},\"exit1()\":{\"notice\":\"First exit point, can only be called before step 3 is executed.\"},\"exited()\":{\"notice\":\"Whether or not the deployment has been exited.\"},\"finalize()\":{\"notice\":\"Tranfers admin ownership to the final owner.\"},\"finalized()\":{\"notice\":\"Whether or not the deployment is finalized.\"},\"l2OutputOracleDynamicConfig()\":{\"notice\":\"Dynamic configuration for the L2OutputOracle.\"},\"oldL1CrossDomainMessenger()\":{\"notice\":\"Address of the old L1CrossDomainMessenger implementation.\"},\"optimismPortalDynamicConfig()\":{\"notice\":\"Dynamic configuration for the OptimismPortal. Determines if the system should be paused when initialized.\"},\"phase1()\":{\"notice\":\"Calls the first 2 steps of the migration process.\"},\"phase2()\":{\"notice\":\"Calls the remaining steps of the migration process, and finalizes.\"},\"step1()\":{\"notice\":\"Configures the ProxyAdmin contract.\"},\"step2()\":{\"notice\":\"Pauses the system by shutting down the L1CrossDomainMessenger and setting the deposit halt flag to tell the Sequencer's DTL to stop accepting deposits.\"},\"step3()\":{\"notice\":\"Removes deprecated addresses from the AddressManager.\"},\"step4()\":{\"notice\":\"Transfers system ownership to the ProxyAdmin.\"},\"step5()\":{\"notice\":\"Upgrades and initializes proxy contracts.\"},\"updateDynamicConfig((uint256,uint256),bool)\":{\"notice\":\"Allows the owner to update dynamic config.\"}},\"notice\":\"The SystemDictator is responsible for coordinating the deployment of a full Bedrock system. The SystemDictator is designed to support both fresh network deployments and upgrades to existing pre-Bedrock systems.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/deployment/SystemDictator.sol\":\"SystemDictator\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L1/L1CrossDomainMessenger.sol\":{\"keccak256\":\"0xeaaa55074aa93641ab9423033a25beeee8b93900b556a059338d77c29b1c7e5f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cdce427876bf3cce02395d716a23675990800c4236f1b99f606ea63ae535ca06\",\"dweb:/ipfs/QmT5gBeR4dH5M6KRvtUKfKVMk4b3528vB49Bn9fNEKSPwH\"]},\"contracts/L1/L1ERC721Bridge.sol\":{\"keccak256\":\"0xe1e81e114ab32473e7cbc88a6e686f166e686ae6cc75ecb7cb3f929a30c92458\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e41cf7b7912446293b5b916c0045bfd25b914fdc1fad0b3b0b471479b55812c4\",\"dweb:/ipfs/QmXkQj7f8pFuoW8UqdW3Mj9u4FdKA6b6qXWHpRJywi3Fwk\"]},\"contracts/L1/L1StandardBridge.sol\":{\"keccak256\":\"0xb2c96bbf32c948863e20a4cd27c0813ae72d8694aaa777fcffb36245bdac6fe3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://229bb8837204c9996f0b91b8886af05e97095563b376aa9a6e3094d7b6622ffb\",\"dweb:/ipfs/QmXaqGWCxGVQ8B27kKeStP1mYW9H22tyrxaHsuUogttz7N\"]},\"contracts/L1/L2OutputOracle.sol\":{\"keccak256\":\"0xba09a5005080e6c7ccc9e0dab17165f20ae0ef9d9c04a13d0b5c158dc1c2a4bb\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fce7e5b5fb4882f05ddcd540f4781225bcf95870b5206e1b423a98ddd3e80df2\",\"dweb:/ipfs/QmQxsgVPaZmkW8SKxKtQEmP5ApeXAxaEEC6Hf4AQ4xL3wC\"]},\"contracts/L1/OptimismPortal.sol\":{\"keccak256\":\"0x3b16493feec098a6d70b98a83e0f7c5f541ac33c5265edee77c2c0229c343fd2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://795b7f9aca7930f9b446d81071ba7d35872f3fbd53faa0e7acb1f51df4edb7f2\",\"dweb:/ipfs/QmTwr3pGnVVN2qfTjPqC5svhM7rLVLgiEj1SthHVz1v4k8\"]},\"contracts/L1/ResourceMetering.sol\":{\"keccak256\":\"0xbd7b9532a70d8c842bfce0ea971be50d02fbbf0227c9ad55c71ac68d438010f4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4969f478dd54e89392cda2ea0c5edcf1be55a5dee43a0e410527b6e3bcb85c88\",\"dweb:/ipfs/QmU2crAojw8DRDsz7PAPrereazjFsKh9wtfTpTDVh6NLfW\"]},\"contracts/L1/SystemConfig.sol\":{\"keccak256\":\"0x2202e03df7b5f70b0cf1cf942afe51cab165bf35864a77d6a77dc82c55653689\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://42ec7d69b192c6199bf28ccf1d19d896f01807039f6bdc3e871b52eb7d9ee645\",\"dweb:/ipfs/QmPmWLf9a9FJ2fYQi9nP73e4QRnAMDbrfNwLS1u8KZgrEs\"]},\"contracts/L2/L2ERC721Bridge.sol\":{\"keccak256\":\"0x94d240acff616f7ec4281bb3c2d3cace1c398bfca754fb3ca7bc795c875b4f10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7613d2506fc31214e3e36c8cd9b0845c9bcaaf063be6fc611ce8efe3fce71584\",\"dweb:/ipfs/QmX8eBBgEWvUPXgpQsPQN3ZhZbwMawFQRuqyTF8Rcv1u1S\"]},\"contracts/deployment/PortalSender.sol\":{\"keccak256\":\"0xe60d88036d9aa8f8e80a4108ee30ad987564ad996af87a79ba92f6ca35852881\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a4be187cd3d5926592491f722dfa1b1c41a8f4f1abdc8cf3883964f70acb0a44\",\"dweb:/ipfs/QmYsAK4YcRHmPoex2eX2x1r6N76AMk3rdBHHmp6gUT73Fa\"]},\"contracts/deployment/SystemDictator.sol\":{\"keccak256\":\"0x4539f2205aa2b1f0502d2b58f6f97772768dc4424333a2acae89dd00c6b0901d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3917b358bf76ee85a534406a12e149df92dca5d404f3aab6a0c4f6dc490f3ad0\",\"dweb:/ipfs/QmdvBYGNKR6pdMBgQGjSgy75i4PtYtr6ZWgjRgv9kMqcq1\"]},\"contracts/legacy/AddressManager.sol\":{\"keccak256\":\"0x7a353d4c92eed32665fd2f0023c55054901293cf7a6e14ca108229d87c047b10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b92ba23601d1951271729a20db931a45639d9376b7c8e2705c23dc360833715a\",\"dweb:/ipfs/QmTKwYLNYYBKZpd31VNBANmguVUwFZifSg7joHSgLZjZCj\"]},\"contracts/legacy/L1ChugSplashProxy.sol\":{\"keccak256\":\"0x6ae7bf6ea9ac0e3511ee4cb15d946589da0dd35098ff762c0b2903d064f24875\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://02028d86c1d38563021d5ead5282271ccdf1c03a24f2eaee056ae2157f0554ee\",\"dweb:/ipfs/QmW9urkBBRTmZ8FjL5Y5zWbdnRhPDruxCCLnpr2CTkozKM\"]},\"contracts/libraries/Arithmetic.sol\":{\"keccak256\":\"0xc8858039f87e48e6f18c1af8bc0b03e57cfef564acddfd06e4d91e3db7ac5ed6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2fc79af1e844aa6dc1c68067bfe1d359df8d4e9a3e8881afb3bcfcbf68071714\",\"dweb:/ipfs/QmcNC4k8zmvwj4kZizSenTiWbx2DJQPbwqXXLF4iMbkRVD\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Bytes.sol\":{\"keccak256\":\"0x7aca6593fadf438ee9cd090d8fdc8f94a5202a2eb7f764c9a86f207712d87a48\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://aac32157885c5a08bd0bc7dcd5511f66db12bb20d0c263dd7be9f58b91538fc1\",\"dweb:/ipfs/Qmb1iG11Z53yt9wNbGsuTvoydJXFosDDpWwRSADKyqiCjw\"]},\"contracts/libraries/Constants.sol\":{\"keccak256\":\"0x8c7be28a175eb732995a7f704560163c30261f9f70d377f865c5060882509f5d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f72aba26553b10ca88708e05461691b36b0d2ec7a87f718022fe119ca9c70852\",\"dweb:/ipfs/QmQtDEB1F3D8RsgG63KSJ9t7ZyFLaXc2Av81vKD9y2TMn7\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/Predeploys.sol\":{\"keccak256\":\"0xfc30fb239b5f00284f4b8f578a62f0882597e939335c91ea9bc4aab3070ddc43\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fa132267b3a9d98568b4e02cbb68fe2d2c0ca630826242c1b2293a8fa35bd302\",\"dweb:/ipfs/QmdYvcGbaykP6wyBu5T2obXrWK56xGnfWqbYeeWpTChq3w\"]},\"contracts/libraries/SafeCall.sol\":{\"keccak256\":\"0x3deedbfc0a57228366531a4f09c94d174f0bb4ea49476a92226d471f3abb349b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e8091b178f6710cb7738f07b1706fe18c241b6275b6641b32724d4ecf5a087dd\",\"dweb:/ipfs/Qmd5kchcZhHepJ3boHRTVDJUr9jsuweWEyoUmNmMFJB6vp\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x4fe8ec920798661a828430bd30dc2715eeb40534ec01c0a7bf41cb4ab422e134\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://74c8471869900bd459358cd990bda1c8d234c06b788804c7049cf465ae1e299f\",\"dweb:/ipfs/QmakcfP6NmbVUQsKqH7rEyJsbiqckigLahw9g74oencEJ7\"]},\"contracts/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x50763c897f0fe84cb067985ec4d7c5721ce9004a69cf0327f96f8982ee8ca412\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://603af847b43933b075f9aac3a7b3cd65041ffe6d732826695458ca9575e1a809\",\"dweb:/ipfs/QmfByFEaCxT9y1VtqoLi5EsXZ9ihkPfj6g5x7pcPoQ7q2K\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xd27fc945d6dd2821636d840f3766f817823c8e9fbfdb87c2da7c73e4292d2f7f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://497cec37d09ebcdc8d1cccac608a4a0b9b9d83eac6cc7c9e8b73c4c6644e2209\",\"dweb:/ipfs/QmUYMsCcgU6epspvKV9Y6anHyyMb4hd1xVzUZheBY9mfG7\"]},\"contracts/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0x61b03a03779cb1f75cea3b88af16fdfd10629029b4b2d6be5238e71af8ef1b5f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1212951af291c0e033a7119b42de5cad6b6bf32da26777da7c2419e76fa8f314\",\"dweb:/ipfs/QmYbnifDmL6UkP9D1X9GaNLR1Q8wYwmDNeYqkJ71bycaE5\"]},\"contracts/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x3c99b1e768cc4c1e064ccc137b1b4d5961bf4edf071be84cc216c5b20f1c00da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e36b2a6325c2f804d769271575669b62ab2da2df3c81921ac7487399fe02af07\",\"dweb:/ipfs/QmTCmcEKwvD8Xvjyev268Bkz27FC7TJpUbw1nADcsThnUr\"]},\"contracts/universal/ERC721Bridge.sol\":{\"keccak256\":\"0xb47389fbec63e85b2d04fce538fe1b8e048278d631729458b70e32a31971c092\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7133f38e3d8d1911738057b1d4523989abd7cd029797b1d3b59cda29d42e9704\",\"dweb:/ipfs/QmUN31CLssESHrBwWA3WYP5L2xESo9Q4aq2Exua1e8UtUW\"]},\"contracts/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x2fea0ee05071c9c6b06a34a8e805801e247e861359b376a8918106e1d6f77ebe\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://198c91bda2edf864ddad1f8ab6168155d13d6ba5487418e5531ff040ff250686\",\"dweb:/ipfs/QmQzxfHY4P7zdVFRh2DTdGt1KeMHaGKNRf3KPZ1mRTYEGB\"]},\"contracts/universal/IOptimismMintableERC721.sol\":{\"keccak256\":\"0xf1a3dd4452df8882a65a31c5e2e8de7872b08cf078be7a5a7da51e6f75c53ad3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b09a2560cae35ca4789fe1ff5edb2bae9fa7dcda115a55f7ccdcc974a2e37526\",\"dweb:/ipfs/QmPQeTvrJ4SJpng5VGZNMf1u85NWxrdus4gGn8xYkHddKM\"]},\"contracts/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x302094342a45ebdf7f46f4fb48821960d2a4134f66fd7f458f73fc4ddf34d219\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b0e2b496e966ca6037e1c9be1d44417c0180fda2a27f68114e93b899defb783\",\"dweb:/ipfs/QmXP76ivMLxYxscC7B9E9qtW3u6HJ2MNaRVeo3x24VEAQH\"]},\"contracts/universal/OptimismMintableERC20Factory.sol\":{\"keccak256\":\"0x87fde59e9b0d43c415cb26d0cb13d7b1aab1f725750291dd257276efdf83774b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e76b70b637fd5d4daf121ba201dd3c85e5ca9763adf65f032c49753057d2c9af\",\"dweb:/ipfs/Qmf5SWFCS2TB1VM5BfGfb8EG84H8mdVwXe9A5jipgf4Lgr\"]},\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33b903585eb9cfc60a70bcdf4ee44220b173caff16dfb9071cd0668c7a551265\",\"dweb:/ipfs/QmXHUZ9brinN1WS9i63ocRQsQidY96WePDBhBsFRhDmVjr\"]},\"contracts/universal/ProxyAdmin.sol\":{\"keccak256\":\"0x7326011ac425cc9ab4760c29ca559342d4832633b5019a9a61b9e63067374e2a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7d3541272c48443f0b339998553e44600b7bcb4f949e5c94acb5a3acfce19399\",\"dweb:/ipfs/QmNSd9jxACWg8bZE8EgxmRdXwLUQixVs4oiugrVegapUe4\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"contracts/universal/StandardBridge.sol\":{\"keccak256\":\"0xaa45044774fa70ed322983c3c0138b21d26d75f4b7e8f5324d53c3eef91adec4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c65c95d0cb71f2e32f5ffdea92151a9a46bbd538ba110389a134963fd16a33e9\",\"dweb:/ipfs/QmaPNZokt4j5SCXaWwVtw6qxu5GXWFa3SWBgaSWPPA9KUG\"]},\"contracts/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"]},\"node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"]},\"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"]},\"node_modules/@openzeppelin/contracts/access/Ownable.sol\":{\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://40fb1b5102468f783961d0af743f91b9980cf66b50d1d12009f6bb1869cea4d2\",\"dweb:/ipfs/QmYqEbJML4jB1GHbzD4cUZDtJg5wVwNm3vDJq1GbyDus8y\"]},\"node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://11756f42121f6541a35a8339ea899ee7514cfaa2e6d740625fcc844419296aa6\",\"dweb:/ipfs/QmekMuk6BY4DAjzeXr4MSbKdgoqqsZnA8JPtuyWc6CwXHf\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://20a97f891d06f0fe91560ea1a142aaa26fdd22bed1b51606b7d48f670deeb50f\",\"dweb:/ipfs/QmTbCtZKChpaX5H2iRiTDMcSz29GSLCpTCDgJpcMR4wg8x\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://26fef835622b46a5ba08b3ef6b46a22e94b5f285d0f0fb66b703bd30217d2c34\",\"dweb:/ipfs/QmZ548qdwfL1qF7aXz3xh1GCdTiST81kGGuKRqVUfYmPZR\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b506000620000296200011a60201b62002b551760201c565b6040805161010080820183526000608080840182815260a080860184905260c080870185905260e0808801869052928752875180840189528581526020818101879052818a018790526060808301889052828701889052828501889052828401889052818a019290925289519788018a52868852878101879052878a01879052878201879052878601879052878401879052878301879052878501879052888a0197909752885193840189528584529583018590529682018490528185018490529181018390529081018290529384018590529082019290925291925090620001129062000191565b5050620006d2565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526301312d008152600a6020820152600891810191909152633b9aca006060820152620f424060808201526001600160801b0360a082015290565b600054610100900460ff1615808015620001b25750600054600160ff909116105b80620001e25750620001cf30620005a260201b62002bd51760201c565b158015620001e2575060005460ff166001145b6200024b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156200026f576000805461ff0019166101001790555b81518051606580546001600160a01b03199081166001600160a01b039384161790915560208084015160668054841691851691909117905560408085015160678054851691861691909117905560609485015160688054851691861691909117905581870151805160698054861691871691909117905580830151606a8054861691871691909117905580820151606b8054861691871691909117905580860151606c80548616918716919091179055608080820151606d8054871691881691909117905560a080830151606e8054881691891691909117905560c092830151606f80548816918916919091179055838a01518051607080548916918a1691909117905580860151607180548916918a1691909117905580850151607280548916918a1691909117905580890151607380548916918a1691909117905580830151607480548916918a1691909117905580820151607580548916918a1691909117905580840151607680548916918a1691909117905560e00151607780548816918916919091179055878a0151805160788054909816908916179096558585015160795585840151607a5585880151607b5585820151607c8054888401516001600160401b039093166001600160e01b031990911617680100000000000000009290991691909102979097179096559301518051607d805494830151938301519783015183870151939097015163ffffffff92831664ffffffffff199096169590951764010000000060ff958616021764ffffffffff60281b191665010000000000949098169390930263ffffffff60301b19169690961766010000000000009587169590950294909417600160501b600160f01b0319166a01000000000000000000009590941694909402600160701b600160f01b03191692909217600160701b6001600160801b039093169290920291909117909155805461010061ff001990911617905562000540620005b1565b60675462000557906001600160a01b031662000619565b80156200059e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff166200060d5760405162461bcd60e51b815260206004820152602b60248201526000805160206200428d83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000242565b620006176200066b565b565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16620006c75760405162461bcd60e51b815260206004820152602b60248201526000805160206200428d83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000242565b620006173362000619565b613bab80620006e26000396000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c8063b3f05b97116100e3578063d7efbb301161008c578063f2fde38b11610066578063f2fde38b14610503578063fb5d737614610516578063fe6b1ddf1461051e57600080fd5b8063d7efbb30146104e6578063df4ec249146104f3578063e7c56229146104fb57600080fd5b8063d36ec430116100bd578063d36ec430146104c3578063d40a71fb146104d6578063d4deb3b6146104de57600080fd5b8063b3f05b9714610473578063bc5df61414610487578063cf03c22d1461049a57600080fd5b8063715018a61161014557806389cb73431161011f57806389cb7343146104195780638da5cb5b1461042c5780638f4ed3331461046b57600080fd5b8063715018a61461022857806379502c55146102305780637d1d95a61461041157600080fd5b80634fb4bcec116101765780634fb4bcec146101e95780635bc34f71146101f15780635ce6c3271461020357600080fd5b8063204c881c1461019d578063289c6af7146101c55780634bb278f3146101df575b600080fd5b607e54607f546101ab919082565b604080519283526020830191909152015b60405180910390f35b6101cd600381565b60405160ff90911681526020016101bc565b6101e7610526565b005b6101e7610790565b6080546101cd90610100900460ff1681565b60805461021890640100000000900460ff1681565b60405190151581526020016101bc565b6101e7611148565b604080516080808201835260655473ffffffffffffffffffffffffffffffffffffffff908116835260665481166020808501919091526067548216848601526068548216606080860191909152855160e0808201885260695485168252606a54851682850152606b54851682890152606c54851682840152606d54851682870152606e54851660a080840191909152606f54861660c080850191909152895161010081018b52607054881681526071548816818801526072548816818c01526073548816818701526074548816818a01526075548816818401526076548816818301526077548816818501528a519384018b526078548816845260795484880152607a54848c0152607b5484870152607c5467ffffffffffffffff8116858b01526801000000000000000090049097168383015289518082018b52607d5463ffffffff8082168352640100000000820460ff908116998401999099526501000000000082049098169b82019b909b5266010000000000008b048716958101959095526a01000000000000000000008a04909516968401969096526e0100000000000000000000000000009097046fffffffffffffffffffffffffffffffff1694820194909452908501526104019384565b6040516101bc9493929190612e23565b6101cd600481565b6080546102189062010000900460ff1681565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b6101e761115c565b608054610218906301000000900460ff1681565b6101e761049536600461346e565b6114cb565b6080546104469065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e76104d1366004613533565b611a29565b6101e7611a9c565b6101e7611f7e565b6080546102189060ff1681565b6101e7611fa6565b6101e761256a565b6101e76105113660046135d2565b612582565b6101e7612639565b6101e7612931565b61052e612bf1565b6066546068546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b15801561059d57600080fd5b505af11580156105b1573d6000803e3d6000fd5b5050608054600461010090910460ff161191506107609050576065546068546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b15801561063957600080fd5b505af115801561064d573d6000803e3d6000fd5b5050606c546068546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911692506313af40359150602401600060405180830381600087803b1580156106c057600080fd5b505af11580156106d4573d6000803e3d6000fd5b5050606e546068546040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169250638f2839709150602401600060405180830381600087803b15801561074757600080fd5b505af115801561075b573d6000803e3d6000fd5b505050505b608080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff166301000000179055565b610798612bf1565b6080546005906301000000900460ff161561083a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d4469637461746f723a20616c72656164792066696e616c697a6560448201527f640000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b608054640100000000900460ff16156108af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20616c72656164792065786974656400006044820152606401610831565b60805460ff8281166101009092041614610925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20696e636f7272656374207374657000006044820152606401610831565b60805462010000900460ff166109bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f53797374656d4469637461746f723a2064796e616d6963206f7261636c65206360448201527f6f6e666967206973206e6f742079657420696e697469616c697a6564000000006064820152608401610831565b606654606954607054607e54607f546040516024810192909252604482015273ffffffffffffffffffffffffffffffffffffffff93841693639623609d938116921690606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe4a3011600000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168152610ab293929190600401613670565b600060405180830381600087803b158015610acc57600080fd5b505af1158015610ae0573d6000803e3d6000fd5b5050606654606a5460715460805460405160ff9091161515602482015273ffffffffffffffffffffffffffffffffffffffff9384169550639623609d9450918316921690604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd53a822f00000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168152610bd693929190600401613670565b600060405180830381600087803b158015610bf057600080fd5b505af1158015610c04573d6000803e3d6000fd5b5050606654606b546072546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610c8257600080fd5b505af1158015610c96573d6000803e3d6000fd5b5050606b54604080517f8129fc1c000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169350638129fc1c925060048181019260009290919082900301818387803b158015610d0657600080fd5b505af1925050508015610d17575060015b610e7457610d236136a9565b806308c379a003610dea5750610d376136c5565b80610d425750610dec565b7f7a2a4e26842155ea933fe6eb6e3137eb5a296dcdf55721c552be7b4c3cc2375981604051602001610d74919061376d565b604051602081830303815290604052805190602001201481604051602001610d9c9190613789565b60405160208183030381529060405290610de3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083191906137f4565b5050610e74565b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f53797374656d4469637461746f723a20756e6578706563746564206572726f7260448201527f20696e697469616c697a696e67204c3158444d20286e6f20726561736f6e29006064820152608401610831565b606654606c546076546040805160048082526024820183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fed88c68e0000000000000000000000000000000000000000000000000000000017905291517f9623609d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff95861695639623609d95610f2a95908216949116929101613670565b600060405180830381600087803b158015610f4457600080fd5b505af1158015610f58573d6000803e3d6000fd5b5050606654606c546073546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610fd657600080fd5b505af1158015610fea573d6000803e3d6000fd5b5050606654606d546074546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b15801561106857600080fd5b505af115801561107c573d6000803e3d6000fd5b5050606654606e546075546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec491506044015b600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b505060808054610100900460ff1692509050600161112c83613836565b91906101000a81548160ff021916908360ff1602179055505050565b611150612bf1565b61115a6000612c72565b565b611164612bf1565b6080546002906301000000900460ff1615611201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d4469637461746f723a20616c72656164792066696e616c697a6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610831565b608054640100000000900460ff1615611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20616c72656164792065786974656400006044820152606401610831565b60805460ff82811661010090920416146112ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20696e636f7272656374207374657000006044820152606401610831565b6065546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061134090600401613855565b602060405180830381865afa15801561135d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113819190613898565b608080547fffffffffffffff0000000000000000000000000000000000000000ffffffffff166501000000000073ffffffffffffffffffffffffffffffffffffffff938416021790556065546040517f9b2ea4bd000000000000000000000000000000000000000000000000000000008152911690639b2ea4bd9061140b906000906004016138b5565b600060405180830381600087803b15801561142557600080fd5b505af1158015611439573d6000803e3d6000fd5b5050606554604080517f9b2ea4bd0000000000000000000000000000000000000000000000000000000081526004810191909152601160448201527f44544c5f534855544f46465f424c4f434b000000000000000000000000000000606482015273ffffffffffffffffffffffffffffffffffffffff43811660248301529091169250639b2ea4bd91506084016110e1565b600054610100900460ff16158080156114eb5750600054600160ff909116105b806115055750303b158015611505575060005460ff166001145b611591576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610831565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156115ef57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b81518051606580547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560208084015160668054841691851691909117905560408085015160678054851691861691909117905560609485015160688054851691861691909117905581870151805160698054861691871691909117905580830151606a8054861691871691909117905580820151606b8054861691871691909117905580860151606c80548616918716919091179055608080820151606d8054871691881691909117905560a080830151606e8054881691891691909117905560c092830151606f80548816918916919091179055838a01518051607080548916918a1691909117905580860151607180548916918a1691909117905580850151607280548916918a1691909117905580890151607380548916918a1691909117905580830151607480548916918a1691909117905580820151607580548916918a1691909117905580840151607680548916918a1691909117905560e00151607780548816918916919091179055878a0151805160788054909816908916179096558585015160795585840151607a5585880151607b5585820151607c80548884015167ffffffffffffffff9093167fffffffff0000000000000000000000000000000000000000000000000000000090911617680100000000000000009290991691909102979097179096559301518051607d805494830151938301519783015183870151939097015163ffffffff9283167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009096169590951764010000000060ff95861602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000094909816939093027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1696909617660100000000000095871695909502949094177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000095909416949094027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff909316929092029190911790915580546101007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9091161790556119a0612ce9565b6067546119c29073ffffffffffffffffffffffffffffffffffffffff16612c72565b8015611a2557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b611a31612bf1565b8151607e55602090910151607f55608080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff009092169190911762010000179055565b611aa4612bf1565b6080546001906301000000900460ff1615611b41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d4469637461746f723a20616c72656164792066696e616c697a6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610831565b608054640100000000900460ff1615611bb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20616c72656164792065786974656400006044820152606401610831565b60805460ff8281166101009092041614611c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20696e636f7272656374207374657000006044820152606401610831565b6066546065546040517f0652b57a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911690630652b57a90602401600060405180830381600087803b158015611c9b57600080fd5b505af1158015611caf573d6000803e3d6000fd5b5050606654606b546040517f8d52d4a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450638d52d4a09350611d119290911690600290600401613916565b600060405180830381600087803b158015611d2b57600080fd5b505af1158015611d3f573d6000803e3d6000fd5b5050606654606b546040517f860f7cda00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316945063860f7cda9350611d9e9290911690600401613977565b600060405180830381600087803b158015611db857600080fd5b505af1158015611dcc573d6000803e3d6000fd5b5050606654606c546040517f8d52d4a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450638d52d4a09350611e2e9290911690600190600401613916565b600060405180830381600087803b158015611e4857600080fd5b505af1158015611e5c573d6000803e3d6000fd5b5050606654606f54607754607854607954607a54607b54607c5460405173ffffffffffffffffffffffffffffffffffffffff9889169a50639623609d99509688169795861696611ecf969586169567ffffffffffffffff8316926801000000000000000090041690607d906024016139d0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff975e92500000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526110e193929190600401613670565b611f86612bf1565b611f8e611fa6565b611f96612639565b611f9e610790565b61115a610526565b611fae612bf1565b6080546003906301000000900460ff161561204b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d4469637461746f723a20616c72656164792066696e616c697a6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610831565b608054640100000000900460ff16156120c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20616c72656164792065786974656400006044820152606401610831565b60805460ff8281166101009092041614612136576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20696e636f7272656374207374657000006044820152606401610831565b60006040518061022001604052806040518060400160405280601d81526020017f4f564d5f43616e6f6e6963616c5472616e73616374696f6e436861696e00000081525081526020016040518060400160405280601a81526020017f4f564d5f4c3243726f7373446f6d61696e4d657373656e6765720000000000008152508152602001604051806060016040528060228152602001613b356022913981526020016040518060400160405280600d81526020017f4f564d5f53657175656e6365720000000000000000000000000000000000000081525081526020016040518060400160405280600c81526020017f4f564d5f50726f706f73657200000000000000000000000000000000000000008152508152602001604051806060016040528060258152602001613b57602591398152602001604051806060016040528060238152602001613b7c602391398152604080518082018252601d81527f4f564d5f43616e6f6e6963616c5472616e73616374696f6e436861696e0000006020828101919091528084019190915281518083018352601881527f4f564d5f5374617465436f6d6d69746d656e74436861696e0000000000000000818301528284015281518083018352600f81527f4f564d5f426f6e644d616e61676572000000000000000000000000000000000081830152606084015281518083018352601481527f4f564d5f457865637574696f6e4d616e616765720000000000000000000000008183015260808401528151808301835260118082527f4f564d5f467261756456657269666965720000000000000000000000000000008284015260a085019190915282518084018452601781527f4f564d5f53746174654d616e61676572466163746f72790000000000000000008184015260c085015282518084018452601c81527f4f564d5f53746174655472616e736974696f6e6572466163746f7279000000008184015260e0850152825180840184529081527f4f564d5f536166657479436865636b65720000000000000000000000000000008183015261010084015281518083018352601981527f4f564d5f4c314d756c74694d65737361676552656c6179657200000000000000818301526101208401528151808301909252600b82527f426f6e644d616e616765720000000000000000000000000000000000000000009082015261014090910152905060005b60118110156125505760655473ffffffffffffffffffffffffffffffffffffffff16639b2ea4bd8383601181106124e7576124e7613a95565b602002015160006040518363ffffffff1660e01b815260040161250b929190613ac4565b600060405180830381600087803b15801561252557600080fd5b505af1158015612539573d6000803e3d6000fd5b50505050808061254890613afc565b9150506124ae565b505060808054610100900460ff1690600161112c83613836565b612572612bf1565b61257a611a9c565b61115a61115c565b61258a612bf1565b73ffffffffffffffffffffffffffffffffffffffff811661262d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610831565b61263681612c72565b50565b612641612bf1565b6080546004906301000000900460ff16156126de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d4469637461746f723a20616c72656164792066696e616c697a6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610831565b608054640100000000900460ff1615612753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20616c72656164792065786974656400006044820152606401610831565b60805460ff82811661010090920416146127c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20696e636f7272656374207374657000006044820152606401610831565b6065546066546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b15801561283857600080fd5b505af115801561284c573d6000803e3d6000fd5b5050606c546066546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911692506313af40359150602401600060405180830381600087803b1580156128bf57600080fd5b505af11580156128d3573d6000803e3d6000fd5b5050606e546066546040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169250638f28397091506024016110e1565b612939612bf1565b608054610100900460ff166003146129d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f53797374656d4469637461746f723a2063616e206f6e6c79206578697431206260448201527f65666f72652073746570203320697320657865637574656400000000000000006064820152608401610831565b6065546080546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831692639b2ea4bd92612a389265010000000000909104909116906004016138b5565b600060405180830381600087803b158015612a5257600080fd5b505af1158015612a66573d6000803e3d6000fd5b5050606554604080517f9b2ea4bd0000000000000000000000000000000000000000000000000000000081526004810191909152601160448201527f44544c5f534855544f46465f424c4f434b00000000000000000000000000000060648201526000602482015273ffffffffffffffffffffffffffffffffffffffff9091169250639b2ea4bd9150608401600060405180830381600087803b158015612b0c57600080fd5b505af1158015612b20573d6000803e3d6000fd5b5050608080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790555050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526301312d008152600a6020820152600891810191909152633b9aca006060820152620f424060808201526fffffffffffffffffffffffffffffffff60a082015290565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff16331461115a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610831565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16612d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610831565b61115a600054610100900460ff16612e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610831565b61115a33612c72565b60006103e08201905073ffffffffffffffffffffffffffffffffffffffff8087511683528060208801511660208401528060408801511660408401528060608801511660608401528086511660808401528060208701511660a08401528060408701511660c08401528060608701511660e0840152806080870151166101008401525060a0850151612ece61012084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c08581015173ffffffffffffffffffffffffffffffffffffffff90811661014085015285518116610160850152602080870151821661018086015260408088015183166101a087015260608089015184166101c08801526080808a015185166101e089015260a0808b015186166102008a01528a87015186166102208a015260e08b015186166102408a0152895186166102608a0152898501516102808a0152898401516102a08a0152898301516102c08a01528982015167ffffffffffffffff166102e08a01528981015190951661030089015294880151805163ffffffff9081166103208a01529381015160ff9081166103408a015292810151909216610360880152810151821661038087015292830151166103a085015201516fffffffffffffffffffffffffffffffff166103c08301525b95945050505050565b60e0810181811067ffffffffffffffff82111715613056577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405250565b6080810181811067ffffffffffffffff82111715613056577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff8211171561310e577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040525050565b73ffffffffffffffffffffffffffffffffffffffff8116811461263657600080fd5b803561314281613115565b919050565b600060e0828403121561315957600080fd5b6040516131658161300f565b809150823561317381613115565b8152602083013561318381613115565b6020820152604083013561319681613115565b604082015260608301356131a981613115565b606082015260808301356131bc81613115565b608082015260a08301356131cf81613115565b60a08201526131e060c08401613137565b60c08201525092915050565b600061010080838503121561320057600080fd5b6040519081019067ffffffffffffffff8211818310171561324a577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8160405280925061325a84613137565b815261326860208501613137565b602082015261327960408501613137565b604082015261328a60608501613137565b606082015261329b60808501613137565b60808201526132ac60a08501613137565b60a08201526132bd60c08501613137565b60c08201526132ce60e08501613137565b60e0820152505092915050565b803563ffffffff8116811461314257600080fd5b803560ff8116811461314257600080fd5b600060c0828403121561331257600080fd5b60405160c0810181811067ffffffffffffffff8211171561335c577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061336b836132db565b8152613379602084016132ef565b602082015261338a604084016132ef565b604082015261339b606084016132db565b60608201526133ac608084016132db565b608082015260a08301356fffffffffffffffffffffffffffffffff811681146133d457600080fd5b60a0919091015292915050565b600061018082840312156133f457600080fd5b6040516134008161300f565b809150823561340e81613115565b80825250602083013560208201526040830135604082015260608301356060820152608083013567ffffffffffffffff8116811461344b57600080fd5b608082015261345c60a08401613137565b60a08201526131e08460c08501613300565b60008183036103e081121561348257600080fd5b60405161348e8161305c565b608082121561349c57600080fd5b60405191506134aa8261305c565b83356134b581613115565b825260208401356134c581613115565b602083015260408401356134d881613115565b604083015260608401356134eb81613115565b60608301528181526135008560808601613147565b60208201526135138561016086016131ec565b60408201526135268561026086016133e1565b6060820152949350505050565b600080828403606081121561354757600080fd5b604081121561355557600080fd5b506040516040810181811067ffffffffffffffff821117156135a0577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040908152843582526020808601359083015290925083013580151581146135c757600080fd5b809150509250929050565b6000602082840312156135e457600080fd5b81356135ef81613115565b9392505050565b60005b838110156136115781810151838201526020016135f9565b83811115613620576000848401525b50505050565b6000815180845261363e8160208601602086016135f6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff8086168352808516602084015250606060408301526130066060830184613626565b600060033d11156136c25760046000803e5060005160e01c5b90565b600060443d10156136d35790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff816024840111818411171561372157505050505090565b82850191508151818111156137395750505050505090565b843d87010160208285010111156137535750505050505090565b613762602082860101876130a3565b509095945050505050565b6000825161377f8184602087016135f6565b9190910192915050565b7f53797374656d4469637461746f723a20756e6578706563746564206572726f7281527f20696e697469616c697a696e67204c3158444d3a2000000000000000000000006020820152600082516137e78160358501602087016135f6565b9190910160350192915050565b6020815260006135ef6020830184613626565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff810361384c5761384c613807565b60010192915050565b60208152600061389260208301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b92915050565b6000602082840312156138aa57600080fd5b81516135ef81613115565b6040815260006138f260408301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b905073ffffffffffffffffffffffffffffffffffffffff8316602083015292915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604081016003831061396a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8260208301529392505050565b73ffffffffffffffffffffffffffffffffffffffff821681526040602082015260006135ef60408301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b60006101808201905073ffffffffffffffffffffffffffffffffffffffff808a16835288602084015287604084015286606084015267ffffffffffffffff8616608084015280851660a084015250825463ffffffff80821660c085015260ff8260201c1660e085015260ff8260281c16610100850152808260301c16610120850152613a6a6101408501828460501c1663ffffffff169052565b50607081901c6fffffffffffffffffffffffffffffffff166101608401525098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b604081526000613ad76040830185613626565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613b2d57613b2d613807565b506001019056fe4f564d5f4465636f6d7072657373696f6e507265636f6d70696c65416464726573734f564d5f436861696e53746f72616765436f6e7461696e65722d4354432d626174636865734f564d5f436861696e53746f72616765436f6e7461696e65722d4354432d7175657565a164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101985760003560e01c8063b3f05b97116100e3578063d7efbb301161008c578063f2fde38b11610066578063f2fde38b14610503578063fb5d737614610516578063fe6b1ddf1461051e57600080fd5b8063d7efbb30146104e6578063df4ec249146104f3578063e7c56229146104fb57600080fd5b8063d36ec430116100bd578063d36ec430146104c3578063d40a71fb146104d6578063d4deb3b6146104de57600080fd5b8063b3f05b9714610473578063bc5df61414610487578063cf03c22d1461049a57600080fd5b8063715018a61161014557806389cb73431161011f57806389cb7343146104195780638da5cb5b1461042c5780638f4ed3331461046b57600080fd5b8063715018a61461022857806379502c55146102305780637d1d95a61461041157600080fd5b80634fb4bcec116101765780634fb4bcec146101e95780635bc34f71146101f15780635ce6c3271461020357600080fd5b8063204c881c1461019d578063289c6af7146101c55780634bb278f3146101df575b600080fd5b607e54607f546101ab919082565b604080519283526020830191909152015b60405180910390f35b6101cd600381565b60405160ff90911681526020016101bc565b6101e7610526565b005b6101e7610790565b6080546101cd90610100900460ff1681565b60805461021890640100000000900460ff1681565b60405190151581526020016101bc565b6101e7611148565b604080516080808201835260655473ffffffffffffffffffffffffffffffffffffffff908116835260665481166020808501919091526067548216848601526068548216606080860191909152855160e0808201885260695485168252606a54851682850152606b54851682890152606c54851682840152606d54851682870152606e54851660a080840191909152606f54861660c080850191909152895161010081018b52607054881681526071548816818801526072548816818c01526073548816818701526074548816818a01526075548816818401526076548816818301526077548816818501528a519384018b526078548816845260795484880152607a54848c0152607b5484870152607c5467ffffffffffffffff8116858b01526801000000000000000090049097168383015289518082018b52607d5463ffffffff8082168352640100000000820460ff908116998401999099526501000000000082049098169b82019b909b5266010000000000008b048716958101959095526a01000000000000000000008a04909516968401969096526e0100000000000000000000000000009097046fffffffffffffffffffffffffffffffff1694820194909452908501526104019384565b6040516101bc9493929190612e23565b6101cd600481565b6080546102189062010000900460ff1681565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b6101e761115c565b608054610218906301000000900460ff1681565b6101e761049536600461346e565b6114cb565b6080546104469065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b6101e76104d1366004613533565b611a29565b6101e7611a9c565b6101e7611f7e565b6080546102189060ff1681565b6101e7611fa6565b6101e761256a565b6101e76105113660046135d2565b612582565b6101e7612639565b6101e7612931565b61052e612bf1565b6066546068546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b15801561059d57600080fd5b505af11580156105b1573d6000803e3d6000fd5b5050608054600461010090910460ff161191506107609050576065546068546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b15801561063957600080fd5b505af115801561064d573d6000803e3d6000fd5b5050606c546068546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911692506313af40359150602401600060405180830381600087803b1580156106c057600080fd5b505af11580156106d4573d6000803e3d6000fd5b5050606e546068546040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169250638f2839709150602401600060405180830381600087803b15801561074757600080fd5b505af115801561075b573d6000803e3d6000fd5b505050505b608080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff166301000000179055565b610798612bf1565b6080546005906301000000900460ff161561083a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d4469637461746f723a20616c72656164792066696e616c697a6560448201527f640000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b608054640100000000900460ff16156108af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20616c72656164792065786974656400006044820152606401610831565b60805460ff8281166101009092041614610925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20696e636f7272656374207374657000006044820152606401610831565b60805462010000900460ff166109bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f53797374656d4469637461746f723a2064796e616d6963206f7261636c65206360448201527f6f6e666967206973206e6f742079657420696e697469616c697a6564000000006064820152608401610831565b606654606954607054607e54607f546040516024810192909252604482015273ffffffffffffffffffffffffffffffffffffffff93841693639623609d938116921690606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe4a3011600000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168152610ab293929190600401613670565b600060405180830381600087803b158015610acc57600080fd5b505af1158015610ae0573d6000803e3d6000fd5b5050606654606a5460715460805460405160ff9091161515602482015273ffffffffffffffffffffffffffffffffffffffff9384169550639623609d9450918316921690604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd53a822f00000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b168152610bd693929190600401613670565b600060405180830381600087803b158015610bf057600080fd5b505af1158015610c04573d6000803e3d6000fd5b5050606654606b546072546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610c8257600080fd5b505af1158015610c96573d6000803e3d6000fd5b5050606b54604080517f8129fc1c000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169350638129fc1c925060048181019260009290919082900301818387803b158015610d0657600080fd5b505af1925050508015610d17575060015b610e7457610d236136a9565b806308c379a003610dea5750610d376136c5565b80610d425750610dec565b7f7a2a4e26842155ea933fe6eb6e3137eb5a296dcdf55721c552be7b4c3cc2375981604051602001610d74919061376d565b604051602081830303815290604052805190602001201481604051602001610d9c9190613789565b60405160208183030381529060405290610de3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083191906137f4565b5050610e74565b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f53797374656d4469637461746f723a20756e6578706563746564206572726f7260448201527f20696e697469616c697a696e67204c3158444d20286e6f20726561736f6e29006064820152608401610831565b606654606c546076546040805160048082526024820183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fed88c68e0000000000000000000000000000000000000000000000000000000017905291517f9623609d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff95861695639623609d95610f2a95908216949116929101613670565b600060405180830381600087803b158015610f4457600080fd5b505af1158015610f58573d6000803e3d6000fd5b5050606654606c546073546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b158015610fd657600080fd5b505af1158015610fea573d6000803e3d6000fd5b5050606654606d546074546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec49150604401600060405180830381600087803b15801561106857600080fd5b505af115801561107c573d6000803e3d6000fd5b5050606654606e546075546040517f99a88ec400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201529082166024820152911692506399a88ec491506044015b600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b505060808054610100900460ff1692509050600161112c83613836565b91906101000a81548160ff021916908360ff1602179055505050565b611150612bf1565b61115a6000612c72565b565b611164612bf1565b6080546002906301000000900460ff1615611201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d4469637461746f723a20616c72656164792066696e616c697a6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610831565b608054640100000000900460ff1615611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20616c72656164792065786974656400006044820152606401610831565b60805460ff82811661010090920416146112ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20696e636f7272656374207374657000006044820152606401610831565b6065546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061134090600401613855565b602060405180830381865afa15801561135d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113819190613898565b608080547fffffffffffffff0000000000000000000000000000000000000000ffffffffff166501000000000073ffffffffffffffffffffffffffffffffffffffff938416021790556065546040517f9b2ea4bd000000000000000000000000000000000000000000000000000000008152911690639b2ea4bd9061140b906000906004016138b5565b600060405180830381600087803b15801561142557600080fd5b505af1158015611439573d6000803e3d6000fd5b5050606554604080517f9b2ea4bd0000000000000000000000000000000000000000000000000000000081526004810191909152601160448201527f44544c5f534855544f46465f424c4f434b000000000000000000000000000000606482015273ffffffffffffffffffffffffffffffffffffffff43811660248301529091169250639b2ea4bd91506084016110e1565b600054610100900460ff16158080156114eb5750600054600160ff909116105b806115055750303b158015611505575060005460ff166001145b611591576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610831565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156115ef57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b81518051606580547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560208084015160668054841691851691909117905560408085015160678054851691861691909117905560609485015160688054851691861691909117905581870151805160698054861691871691909117905580830151606a8054861691871691909117905580820151606b8054861691871691909117905580860151606c80548616918716919091179055608080820151606d8054871691881691909117905560a080830151606e8054881691891691909117905560c092830151606f80548816918916919091179055838a01518051607080548916918a1691909117905580860151607180548916918a1691909117905580850151607280548916918a1691909117905580890151607380548916918a1691909117905580830151607480548916918a1691909117905580820151607580548916918a1691909117905580840151607680548916918a1691909117905560e00151607780548816918916919091179055878a0151805160788054909816908916179096558585015160795585840151607a5585880151607b5585820151607c80548884015167ffffffffffffffff9093167fffffffff0000000000000000000000000000000000000000000000000000000090911617680100000000000000009290991691909102979097179096559301518051607d805494830151938301519783015183870151939097015163ffffffff9283167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009096169590951764010000000060ff95861602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000094909816939093027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1696909617660100000000000095871695909502949094177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000095909416949094027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff909316929092029190911790915580546101007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9091161790556119a0612ce9565b6067546119c29073ffffffffffffffffffffffffffffffffffffffff16612c72565b8015611a2557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b611a31612bf1565b8151607e55602090910151607f55608080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff009092169190911762010000179055565b611aa4612bf1565b6080546001906301000000900460ff1615611b41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d4469637461746f723a20616c72656164792066696e616c697a6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610831565b608054640100000000900460ff1615611bb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20616c72656164792065786974656400006044820152606401610831565b60805460ff8281166101009092041614611c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20696e636f7272656374207374657000006044820152606401610831565b6066546065546040517f0652b57a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911690630652b57a90602401600060405180830381600087803b158015611c9b57600080fd5b505af1158015611caf573d6000803e3d6000fd5b5050606654606b546040517f8d52d4a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450638d52d4a09350611d119290911690600290600401613916565b600060405180830381600087803b158015611d2b57600080fd5b505af1158015611d3f573d6000803e3d6000fd5b5050606654606b546040517f860f7cda00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316945063860f7cda9350611d9e9290911690600401613977565b600060405180830381600087803b158015611db857600080fd5b505af1158015611dcc573d6000803e3d6000fd5b5050606654606c546040517f8d52d4a000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450638d52d4a09350611e2e9290911690600190600401613916565b600060405180830381600087803b158015611e4857600080fd5b505af1158015611e5c573d6000803e3d6000fd5b5050606654606f54607754607854607954607a54607b54607c5460405173ffffffffffffffffffffffffffffffffffffffff9889169a50639623609d99509688169795861696611ecf969586169567ffffffffffffffff8316926801000000000000000090041690607d906024016139d0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff975e92500000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526110e193929190600401613670565b611f86612bf1565b611f8e611fa6565b611f96612639565b611f9e610790565b61115a610526565b611fae612bf1565b6080546003906301000000900460ff161561204b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d4469637461746f723a20616c72656164792066696e616c697a6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610831565b608054640100000000900460ff16156120c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20616c72656164792065786974656400006044820152606401610831565b60805460ff8281166101009092041614612136576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20696e636f7272656374207374657000006044820152606401610831565b60006040518061022001604052806040518060400160405280601d81526020017f4f564d5f43616e6f6e6963616c5472616e73616374696f6e436861696e00000081525081526020016040518060400160405280601a81526020017f4f564d5f4c3243726f7373446f6d61696e4d657373656e6765720000000000008152508152602001604051806060016040528060228152602001613b356022913981526020016040518060400160405280600d81526020017f4f564d5f53657175656e6365720000000000000000000000000000000000000081525081526020016040518060400160405280600c81526020017f4f564d5f50726f706f73657200000000000000000000000000000000000000008152508152602001604051806060016040528060258152602001613b57602591398152602001604051806060016040528060238152602001613b7c602391398152604080518082018252601d81527f4f564d5f43616e6f6e6963616c5472616e73616374696f6e436861696e0000006020828101919091528084019190915281518083018352601881527f4f564d5f5374617465436f6d6d69746d656e74436861696e0000000000000000818301528284015281518083018352600f81527f4f564d5f426f6e644d616e61676572000000000000000000000000000000000081830152606084015281518083018352601481527f4f564d5f457865637574696f6e4d616e616765720000000000000000000000008183015260808401528151808301835260118082527f4f564d5f467261756456657269666965720000000000000000000000000000008284015260a085019190915282518084018452601781527f4f564d5f53746174654d616e61676572466163746f72790000000000000000008184015260c085015282518084018452601c81527f4f564d5f53746174655472616e736974696f6e6572466163746f7279000000008184015260e0850152825180840184529081527f4f564d5f536166657479436865636b65720000000000000000000000000000008183015261010084015281518083018352601981527f4f564d5f4c314d756c74694d65737361676552656c6179657200000000000000818301526101208401528151808301909252600b82527f426f6e644d616e616765720000000000000000000000000000000000000000009082015261014090910152905060005b60118110156125505760655473ffffffffffffffffffffffffffffffffffffffff16639b2ea4bd8383601181106124e7576124e7613a95565b602002015160006040518363ffffffff1660e01b815260040161250b929190613ac4565b600060405180830381600087803b15801561252557600080fd5b505af1158015612539573d6000803e3d6000fd5b50505050808061254890613afc565b9150506124ae565b505060808054610100900460ff1690600161112c83613836565b612572612bf1565b61257a611a9c565b61115a61115c565b61258a612bf1565b73ffffffffffffffffffffffffffffffffffffffff811661262d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610831565b61263681612c72565b50565b612641612bf1565b6080546004906301000000900460ff16156126de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d4469637461746f723a20616c72656164792066696e616c697a6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610831565b608054640100000000900460ff1615612753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20616c72656164792065786974656400006044820152606401610831565b60805460ff82811661010090920416146127c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53797374656d4469637461746f723a20696e636f7272656374207374657000006044820152606401610831565b6065546066546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b90602401600060405180830381600087803b15801561283857600080fd5b505af115801561284c573d6000803e3d6000fd5b5050606c546066546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152911692506313af40359150602401600060405180830381600087803b1580156128bf57600080fd5b505af11580156128d3573d6000803e3d6000fd5b5050606e546066546040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169250638f28397091506024016110e1565b612939612bf1565b608054610100900460ff166003146129d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f53797374656d4469637461746f723a2063616e206f6e6c79206578697431206260448201527f65666f72652073746570203320697320657865637574656400000000000000006064820152608401610831565b6065546080546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831692639b2ea4bd92612a389265010000000000909104909116906004016138b5565b600060405180830381600087803b158015612a5257600080fd5b505af1158015612a66573d6000803e3d6000fd5b5050606554604080517f9b2ea4bd0000000000000000000000000000000000000000000000000000000081526004810191909152601160448201527f44544c5f534855544f46465f424c4f434b00000000000000000000000000000060648201526000602482015273ffffffffffffffffffffffffffffffffffffffff9091169250639b2ea4bd9150608401600060405180830381600087803b158015612b0c57600080fd5b505af1158015612b20573d6000803e3d6000fd5b5050608080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790555050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c0810182526301312d008152600a6020820152600891810191909152633b9aca006060820152620f424060808201526fffffffffffffffffffffffffffffffff60a082015290565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff16331461115a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610831565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16612d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610831565b61115a600054610100900460ff16612e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610831565b61115a33612c72565b60006103e08201905073ffffffffffffffffffffffffffffffffffffffff8087511683528060208801511660208401528060408801511660408401528060608801511660608401528086511660808401528060208701511660a08401528060408701511660c08401528060608701511660e0840152806080870151166101008401525060a0850151612ece61012084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c08581015173ffffffffffffffffffffffffffffffffffffffff90811661014085015285518116610160850152602080870151821661018086015260408088015183166101a087015260608089015184166101c08801526080808a015185166101e089015260a0808b015186166102008a01528a87015186166102208a015260e08b015186166102408a0152895186166102608a0152898501516102808a0152898401516102a08a0152898301516102c08a01528982015167ffffffffffffffff166102e08a01528981015190951661030089015294880151805163ffffffff9081166103208a01529381015160ff9081166103408a015292810151909216610360880152810151821661038087015292830151166103a085015201516fffffffffffffffffffffffffffffffff166103c08301525b95945050505050565b60e0810181811067ffffffffffffffff82111715613056577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405250565b6080810181811067ffffffffffffffff82111715613056577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff8211171561310e577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040525050565b73ffffffffffffffffffffffffffffffffffffffff8116811461263657600080fd5b803561314281613115565b919050565b600060e0828403121561315957600080fd5b6040516131658161300f565b809150823561317381613115565b8152602083013561318381613115565b6020820152604083013561319681613115565b604082015260608301356131a981613115565b606082015260808301356131bc81613115565b608082015260a08301356131cf81613115565b60a08201526131e060c08401613137565b60c08201525092915050565b600061010080838503121561320057600080fd5b6040519081019067ffffffffffffffff8211818310171561324a577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8160405280925061325a84613137565b815261326860208501613137565b602082015261327960408501613137565b604082015261328a60608501613137565b606082015261329b60808501613137565b60808201526132ac60a08501613137565b60a08201526132bd60c08501613137565b60c08201526132ce60e08501613137565b60e0820152505092915050565b803563ffffffff8116811461314257600080fd5b803560ff8116811461314257600080fd5b600060c0828403121561331257600080fd5b60405160c0810181811067ffffffffffffffff8211171561335c577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061336b836132db565b8152613379602084016132ef565b602082015261338a604084016132ef565b604082015261339b606084016132db565b60608201526133ac608084016132db565b608082015260a08301356fffffffffffffffffffffffffffffffff811681146133d457600080fd5b60a0919091015292915050565b600061018082840312156133f457600080fd5b6040516134008161300f565b809150823561340e81613115565b80825250602083013560208201526040830135604082015260608301356060820152608083013567ffffffffffffffff8116811461344b57600080fd5b608082015261345c60a08401613137565b60a08201526131e08460c08501613300565b60008183036103e081121561348257600080fd5b60405161348e8161305c565b608082121561349c57600080fd5b60405191506134aa8261305c565b83356134b581613115565b825260208401356134c581613115565b602083015260408401356134d881613115565b604083015260608401356134eb81613115565b60608301528181526135008560808601613147565b60208201526135138561016086016131ec565b60408201526135268561026086016133e1565b6060820152949350505050565b600080828403606081121561354757600080fd5b604081121561355557600080fd5b506040516040810181811067ffffffffffffffff821117156135a0577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040908152843582526020808601359083015290925083013580151581146135c757600080fd5b809150509250929050565b6000602082840312156135e457600080fd5b81356135ef81613115565b9392505050565b60005b838110156136115781810151838201526020016135f9565b83811115613620576000848401525b50505050565b6000815180845261363e8160208601602086016135f6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff8086168352808516602084015250606060408301526130066060830184613626565b600060033d11156136c25760046000803e5060005160e01c5b90565b600060443d10156136d35790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff816024840111818411171561372157505050505090565b82850191508151818111156137395750505050505090565b843d87010160208285010111156137535750505050505090565b613762602082860101876130a3565b509095945050505050565b6000825161377f8184602087016135f6565b9190910192915050565b7f53797374656d4469637461746f723a20756e6578706563746564206572726f7281527f20696e697469616c697a696e67204c3158444d3a2000000000000000000000006020820152600082516137e78160358501602087016135f6565b9190910160350192915050565b6020815260006135ef6020830184613626565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff810361384c5761384c613807565b60010192915050565b60208152600061389260208301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b92915050565b6000602082840312156138aa57600080fd5b81516135ef81613115565b6040815260006138f260408301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b905073ffffffffffffffffffffffffffffffffffffffff8316602083015292915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604081016003831061396a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8260208301529392505050565b73ffffffffffffffffffffffffffffffffffffffff821681526040602082015260006135ef60408301601a81527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000602082015260400190565b60006101808201905073ffffffffffffffffffffffffffffffffffffffff808a16835288602084015287604084015286606084015267ffffffffffffffff8616608084015280851660a084015250825463ffffffff80821660c085015260ff8260201c1660e085015260ff8260281c16610100850152808260301c16610120850152613a6a6101408501828460501c1663ffffffff169052565b50607081901c6fffffffffffffffffffffffffffffffff166101608401525098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b604081526000613ad76040830185613626565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613b2d57613b2d613807565b506001019056fe4f564d5f4465636f6d7072657373696f6e507265636f6d70696c65416464726573734f564d5f436861696e53746f72616765436f6e7461696e65722d4354432d626174636865734f564d5f436861696e53746f72616765436f6e7461696e65722d4354432d7175657565a164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "initialize(((address,address,address,address),(address,address,address,address,address,address,address),(address,address,address,address,address,address,address,address),(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128))))": { - "params": { - "_config": "System configuration." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - }, - "updateDynamicConfig((uint256,uint256),bool)": { - "params": { - "_l2OutputOracleDynamicConfig": "Dynamic L2OutputOracle config.", - "_optimismPortalDynamicConfig": "Dynamic OptimismPortal config." - } - } - }, - "title": "SystemDictator" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "EXIT_1_NO_RETURN_STEP()": { - "notice": "Step after which exit 1 can no longer be used." - }, - "PROXY_TRANSFER_STEP()": { - "notice": "Step where proxy ownership is transferred." - }, - "config()": { - "notice": "System configuration." - }, - "constructor": { - "notice": "Constructor required to ensure that the implementation of the SystemDictator is initialized upon deployment." - }, - "currentStep()": { - "notice": "Current step;" - }, - "dynamicConfigSet()": { - "notice": "Whether or not dynamic config has been set." - }, - "exit1()": { - "notice": "First exit point, can only be called before step 3 is executed." - }, - "exited()": { - "notice": "Whether or not the deployment has been exited." - }, - "finalize()": { - "notice": "Tranfers admin ownership to the final owner." - }, - "finalized()": { - "notice": "Whether or not the deployment is finalized." - }, - "l2OutputOracleDynamicConfig()": { - "notice": "Dynamic configuration for the L2OutputOracle." - }, - "oldL1CrossDomainMessenger()": { - "notice": "Address of the old L1CrossDomainMessenger implementation." - }, - "optimismPortalDynamicConfig()": { - "notice": "Dynamic configuration for the OptimismPortal. Determines if the system should be paused when initialized." - }, - "phase1()": { - "notice": "Calls the first 2 steps of the migration process." - }, - "phase2()": { - "notice": "Calls the remaining steps of the migration process, and finalizes." - }, - "step1()": { - "notice": "Configures the ProxyAdmin contract." - }, - "step2()": { - "notice": "Pauses the system by shutting down the L1CrossDomainMessenger and setting the deposit halt flag to tell the Sequencer's DTL to stop accepting deposits." - }, - "step3()": { - "notice": "Removes deprecated addresses from the AddressManager." - }, - "step4()": { - "notice": "Transfers system ownership to the ProxyAdmin." - }, - "step5()": { - "notice": "Upgrades and initializes proxy contracts." - }, - "updateDynamicConfig((uint256,uint256),bool)": { - "notice": "Allows the owner to update dynamic config." - } - }, - "notice": "The SystemDictator is responsible for coordinating the deployment of a full Bedrock system. The SystemDictator is designed to support both fresh network deployments and upgrades to existing pre-Bedrock systems." - }, - "storageLayout": { - "storage": [ - { - "astId": 52671, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 52674, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 53099, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 52543, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 52663, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 4322, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "config", - "offset": 0, - "slot": "101", - "type": "t_struct(DeployConfig)4310_storage" - }, - { - "astId": 4326, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l2OutputOracleDynamicConfig", - "offset": 0, - "slot": "126", - "type": "t_struct(L2OutputOracleDynamicConfig)4281_storage" - }, - { - "astId": 4329, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "optimismPortalDynamicConfig", - "offset": 0, - "slot": "128", - "type": "t_bool" - }, - { - "astId": 4332, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "currentStep", - "offset": 1, - "slot": "128", - "type": "t_uint8" - }, - { - "astId": 4335, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "dynamicConfigSet", - "offset": 2, - "slot": "128", - "type": "t_bool" - }, - { - "astId": 4338, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "finalized", - "offset": 3, - "slot": "128", - "type": "t_bool" - }, - { - "astId": 4341, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "exited", - "offset": 4, - "slot": "128", - "type": "t_bool" - }, - { - "astId": 4344, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "oldL1CrossDomainMessenger", - "offset": 5, - "slot": "128", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_contract(AddressManager)7678": { - "encoding": "inplace", - "label": "contract AddressManager", - "numberOfBytes": "20" - }, - "t_contract(L1CrossDomainMessenger)125": { - "encoding": "inplace", - "label": "contract L1CrossDomainMessenger", - "numberOfBytes": "20" - }, - "t_contract(L1ERC721Bridge)325": { - "encoding": "inplace", - "label": "contract L1ERC721Bridge", - "numberOfBytes": "20" - }, - "t_contract(L1StandardBridge)772": { - "encoding": "inplace", - "label": "contract L1StandardBridge", - "numberOfBytes": "20" - }, - "t_contract(L2OutputOracle)1233": { - "encoding": "inplace", - "label": "contract L2OutputOracle", - "numberOfBytes": "20" - }, - "t_contract(OptimismMintableERC20Factory)50636": { - "encoding": "inplace", - "label": "contract OptimismMintableERC20Factory", - "numberOfBytes": "20" - }, - "t_contract(OptimismPortal)1912": { - "encoding": "inplace", - "label": "contract OptimismPortal", - "numberOfBytes": "20" - }, - "t_contract(PortalSender)4190": { - "encoding": "inplace", - "label": "contract PortalSender", - "numberOfBytes": "20" - }, - "t_contract(ProxyAdmin)51686": { - "encoding": "inplace", - "label": "contract ProxyAdmin", - "numberOfBytes": "20" - }, - "t_contract(SystemConfig)2672": { - "encoding": "inplace", - "label": "contract SystemConfig", - "numberOfBytes": "20" - }, - "t_struct(DeployConfig)4310_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.DeployConfig", - "numberOfBytes": "800", - "members": [ - { - "astId": 4300, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "globalConfig", - "offset": 0, - "slot": "0", - "type": "t_struct(GlobalConfig)4236_storage" - }, - { - "astId": 4303, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "proxyAddressConfig", - "offset": 0, - "slot": "4", - "type": "t_struct(ProxyAddressConfig)4251_storage" - }, - { - "astId": 4306, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "implementationAddressConfig", - "offset": 0, - "slot": "11", - "type": "t_struct(ImplementationAddressConfig)4276_storage" - }, - { - "astId": 4309, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "systemConfigConfig", - "offset": 0, - "slot": "19", - "type": "t_struct(SystemConfigConfig)4297_storage" - } - ] - }, - "t_struct(GlobalConfig)4236_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.GlobalConfig", - "numberOfBytes": "128", - "members": [ - { - "astId": 4228, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "addressManager", - "offset": 0, - "slot": "0", - "type": "t_contract(AddressManager)7678" - }, - { - "astId": 4231, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "proxyAdmin", - "offset": 0, - "slot": "1", - "type": "t_contract(ProxyAdmin)51686" - }, - { - "astId": 4233, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "controller", - "offset": 0, - "slot": "2", - "type": "t_address" - }, - { - "astId": 4235, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "finalOwner", - "offset": 0, - "slot": "3", - "type": "t_address" - } - ] - }, - "t_struct(ImplementationAddressConfig)4276_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.ImplementationAddressConfig", - "numberOfBytes": "256", - "members": [ - { - "astId": 4254, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l2OutputOracleImpl", - "offset": 0, - "slot": "0", - "type": "t_contract(L2OutputOracle)1233" - }, - { - "astId": 4257, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "optimismPortalImpl", - "offset": 0, - "slot": "1", - "type": "t_contract(OptimismPortal)1912" - }, - { - "astId": 4260, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1CrossDomainMessengerImpl", - "offset": 0, - "slot": "2", - "type": "t_contract(L1CrossDomainMessenger)125" - }, - { - "astId": 4263, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1StandardBridgeImpl", - "offset": 0, - "slot": "3", - "type": "t_contract(L1StandardBridge)772" - }, - { - "astId": 4266, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "optimismMintableERC20FactoryImpl", - "offset": 0, - "slot": "4", - "type": "t_contract(OptimismMintableERC20Factory)50636" - }, - { - "astId": 4269, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1ERC721BridgeImpl", - "offset": 0, - "slot": "5", - "type": "t_contract(L1ERC721Bridge)325" - }, - { - "astId": 4272, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "portalSenderImpl", - "offset": 0, - "slot": "6", - "type": "t_contract(PortalSender)4190" - }, - { - "astId": 4275, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "systemConfigImpl", - "offset": 0, - "slot": "7", - "type": "t_contract(SystemConfig)2672" - } - ] - }, - "t_struct(L2OutputOracleDynamicConfig)4281_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.L2OutputOracleDynamicConfig", - "numberOfBytes": "64", - "members": [ - { - "astId": 4278, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l2OutputOracleStartingBlockNumber", - "offset": 0, - "slot": "0", - "type": "t_uint256" - }, - { - "astId": 4280, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l2OutputOracleStartingTimestamp", - "offset": 0, - "slot": "1", - "type": "t_uint256" - } - ] - }, - "t_struct(ProxyAddressConfig)4251_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.ProxyAddressConfig", - "numberOfBytes": "224", - "members": [ - { - "astId": 4238, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l2OutputOracleProxy", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 4240, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "optimismPortalProxy", - "offset": 0, - "slot": "1", - "type": "t_address" - }, - { - "astId": 4242, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1CrossDomainMessengerProxy", - "offset": 0, - "slot": "2", - "type": "t_address" - }, - { - "astId": 4244, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1StandardBridgeProxy", - "offset": 0, - "slot": "3", - "type": "t_address" - }, - { - "astId": 4246, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "optimismMintableERC20FactoryProxy", - "offset": 0, - "slot": "4", - "type": "t_address" - }, - { - "astId": 4248, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "l1ERC721BridgeProxy", - "offset": 0, - "slot": "5", - "type": "t_address" - }, - { - "astId": 4250, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "systemConfigProxy", - "offset": 0, - "slot": "6", - "type": "t_address" - } - ] - }, - "t_struct(ResourceConfig)1945_storage": { - "encoding": "inplace", - "label": "struct ResourceMetering.ResourceConfig", - "numberOfBytes": "32", - "members": [ - { - "astId": 1934, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "maxResourceLimit", - "offset": 0, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 1936, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "elasticityMultiplier", - "offset": 4, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 1938, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "baseFeeMaxChangeDenominator", - "offset": 5, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 1940, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "minimumBaseFee", - "offset": 6, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 1942, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "systemTxMaxGas", - "offset": 10, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 1944, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "maximumBaseFee", - "offset": 14, - "slot": "0", - "type": "t_uint128" - } - ] - }, - "t_struct(SystemConfigConfig)4297_storage": { - "encoding": "inplace", - "label": "struct SystemDictator.SystemConfigConfig", - "numberOfBytes": "192", - "members": [ - { - "astId": 4283, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 4285, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "overhead", - "offset": 0, - "slot": "1", - "type": "t_uint256" - }, - { - "astId": 4287, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "scalar", - "offset": 0, - "slot": "2", - "type": "t_uint256" - }, - { - "astId": 4289, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "batcherHash", - "offset": 0, - "slot": "3", - "type": "t_bytes32" - }, - { - "astId": 4291, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "gasLimit", - "offset": 0, - "slot": "4", - "type": "t_uint64" - }, - { - "astId": 4293, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "unsafeBlockSigner", - "offset": 8, - "slot": "4", - "type": "t_address" - }, - { - "astId": 4296, - "contract": "contracts/deployment/SystemDictator.sol:SystemDictator", - "label": "resourceConfig", - "offset": 0, - "slot": "5", - "type": "t_struct(ResourceConfig)1945_storage" - } - ] - }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "encoding": "inplace", - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/SystemDictatorProxy.json b/packages/contracts-bedrock/deployments/mainnet/SystemDictatorProxy.json deleted file mode 100644 index e7b927edfa0a..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/SystemDictatorProxy.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x459dd62834451eddd153403a761496e35d35c842ac4c4bcc480fa87573636607", - "receipt": { - "to": null, - "from": "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960", - "contractAddress": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB", - "transactionIndex": 90, - "gasUsed": "523960", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200800000000000000000000000000000000000000000000000008000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x9b2a75b95bdd1b95733c9b104eb82d4be0495755dc2ae9b100f6760e83d2bb5d", - "transactionHash": "0x459dd62834451eddd153403a761496e35d35c842ac4c4bcc480fa87573636607", - "logs": [ - { - "transactionIndex": 90, - "blockNumber": 17365805, - "transactionHash": "0x459dd62834451eddd153403a761496e35d35c842ac4c4bcc480fa87573636607", - "address": "0xB4453CEb33d2e67FA244A24acf2E50CEF31F53cB", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000354f3f4ecdca5e0a7ace08d71348cdc1dab48960", - "logIndex": 267, - "blockHash": "0x9b2a75b95bdd1b95733c9b104eb82d4be0495755dc2ae9b100f6760e83d2bb5d" - } - ], - "blockNumber": 17365805, - "cumulativeGasUsed": "9446906", - "status": 1, - "byzantium": true - }, - "args": [ - "0x354F3f4ECdcA5E0A7acE08d71348cdC1Dab48960" - ], - "numDeployments": 1, - "solcInputHash": "13ac93d026822f719ad110af836d1582", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/Proxy.sol\":{\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33b903585eb9cfc60a70bcdf4ee44220b173caff16dfb9071cd0668c7a551265\",\"dweb:/ipfs/QmXHUZ9brinN1WS9i63ocRQsQidY96WePDBhBsFRhDmVjr\"]}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/TeleportrWithdrawer.json b/packages/contracts-bedrock/deployments/mainnet/TeleportrWithdrawer.json deleted file mode 100644 index 3681aea4c38e..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/TeleportrWithdrawer.json +++ /dev/null @@ -1,655 +0,0 @@ -{ - "address": "0x78A25524D90E3D0596558fb43789bD800a5c3007", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ReceivedETH", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewERC20", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "WithdrewERC721", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewETH", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_gas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "CALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_gas", - "type": "uint256" - } - ], - "name": "DELEGATECALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "data", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "recipient", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "setData", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - } - ], - "name": "setRecipient", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_teleportr", - "type": "address" - } - ], - "name": "setTeleportr", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "teleportr", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC721", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_id", - "type": "uint256" - } - ], - "name": "withdrawERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "withdrawFromTeleportr", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0xe7914c509af8b99ef3421601b487ccdf2c7ef5955ffbd58bbb7d786452df3638", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5", - "contractAddress": null, - "transactionIndex": 249, - "gasUsed": "1233027", - "logsBloom": "0x00000000000000000001000000000000000000000000000000000000000000000000100000000000000000000000080000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000080000000020000000000000000000800000000000080000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000004000000020000000000000000000000000000000000000000000000", - "blockHash": "0xbdb85532b8a9423604350b1254f5b465838c92bffaecd1768cf94b95e58ffa80", - "transactionHash": "0xe7914c509af8b99ef3421601b487ccdf2c7ef5955ffbd58bbb7d786452df3638", - "logs": [ - { - "transactionIndex": 249, - "blockNumber": 14981055, - "transactionHash": "0xe7914c509af8b99ef3421601b487ccdf2c7ef5955ffbd58bbb7d786452df3638", - "address": "0x78A25524D90E3D0596558fb43789bD800a5c3007", - "topics": [ - "0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58" - ], - "data": "0x", - "logIndex": 574, - "blockHash": "0xbdb85532b8a9423604350b1254f5b465838c92bffaecd1768cf94b95e58ffa80" - } - ], - "blockNumber": 14981055, - "cumulativeGasUsed": "26253070", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "b09909e91a3ff9823ceba49a3a845230", - "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ReceivedETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewETH\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"CALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"}],\"name\":\"DELEGATECALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"data\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"setData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"setRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_teleportr\",\"type\":\"address\"}],\"name\":\"setTeleportr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"teleportr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC721\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFromTeleportr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\",\"_value\":\"ETH value to send with the call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"DELEGATECALL(address,bytes,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"constructor\":{\"params\":{\"_owner\":\"Initial owner of the contract.\"}},\"setData(bytes)\":{\"params\":{\"_data\":\"New data to be sent to the recipient address.\"}},\"setRecipient(address)\":{\"params\":{\"_recipient\":\"New recipient address.\"}},\"setTeleportr(address)\":{\"params\":{\"_teleportr\":\"New Teleportr contract address.\"}},\"withdrawERC20(address,address)\":{\"params\":{\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC20(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount of ERC20 to withdraw.\",\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC721(address,address,uint256)\":{\"params\":{\"_asset\":\"ERC721 token to withdraw.\",\"_id\":\"Token ID of the ERC721 token to withdraw.\",\"_to\":\"Address to receive the ERC721 token.\"}},\"withdrawETH(address)\":{\"params\":{\"_to\":\"Address to receive the ETH balance.\"}},\"withdrawETH(address,uint256)\":{\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_to\":\"Address to receive the ETH balance.\"}}},\"title\":\"TeleportrWithdrawer\",\"version\":1},\"userdoc\":{\"events\":{\"ReceivedETH(address,uint256)\":{\"notice\":\"Emitted when ETH is received by this address.\"},\"WithdrewERC20(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewERC721(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC721 tokens are withdrawn from this address.\"},\"WithdrewETH(address,address,uint256)\":{\"notice\":\"Emitted when ETH is withdrawn from this address.\"}},\"kind\":\"user\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"notice\":\"Sends a CALL to a target address.\"},\"DELEGATECALL(address,bytes,uint256)\":{\"notice\":\"Sends a DELEGATECALL to a target address.\"},\"data()\":{\"notice\":\"Data to be sent to the recipient address.\"},\"recipient()\":{\"notice\":\"Address that will receive Teleportr withdrawals.\"},\"setData(bytes)\":{\"notice\":\"Allows the owner to update the data to be sent to the recipient address.\"},\"setRecipient(address)\":{\"notice\":\"Allows the owner to update the recipient address.\"},\"setTeleportr(address)\":{\"notice\":\"Allows the owner to update the Teleportr contract address.\"},\"teleportr()\":{\"notice\":\"Address of the Teleportr contract.\"},\"withdrawERC20(address,address)\":{\"notice\":\"Withdraws full ERC20 balance to the recipient.\"},\"withdrawERC20(address,address,uint256)\":{\"notice\":\"Withdraws partial ERC20 balance to the recipient.\"},\"withdrawERC721(address,address,uint256)\":{\"notice\":\"Withdraws ERC721 token to the recipient.\"},\"withdrawETH(address)\":{\"notice\":\"Withdraws full ETH balance to the recipient.\"},\"withdrawETH(address,uint256)\":{\"notice\":\"Withdraws partial ETH balance to the recipient.\"},\"withdrawFromTeleportr()\":{\"notice\":\"Withdraws the full balance of the Teleportr contract to the recipient address. Anyone is allowed to trigger this function since the recipient address cannot be controlled by the msg.sender.\"}},\"notice\":\"The TeleportrWithdrawer is a simple contract capable of withdrawing funds from the TeleportrContract and sending them to some recipient address.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/TeleportrWithdrawer.sol\":\"TeleportrWithdrawer\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@rari-capital/solmate/src/auth/Owned.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Simple single owner authorization mixin.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\\nabstract contract Owned {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event OwnerUpdated(address indexed user, address indexed newOwner);\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n address public owner;\\n\\n modifier onlyOwner() virtual {\\n require(msg.sender == owner, \\\"UNAUTHORIZED\\\");\\n\\n _;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(address _owner) {\\n owner = _owner;\\n\\n emit OwnerUpdated(address(0), _owner);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function setOwner(address newOwner) public virtual onlyOwner {\\n owner = newOwner;\\n\\n emit OwnerUpdated(msg.sender, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7e91c80b0dd1a14a19cb9e661b99924043adab6d9d893bbfcf3a6a3dc23a6743\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\\nabstract contract ERC20 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n uint8 public immutable decimals;\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) public balanceOf;\\n\\n mapping(address => mapping(address => uint256)) public allowance;\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 internal immutable INITIAL_CHAIN_ID;\\n\\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\\n\\n mapping(address => uint256) public nonces;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n uint8 _decimals\\n ) {\\n name = _name;\\n symbol = _symbol;\\n decimals = _decimals;\\n\\n INITIAL_CHAIN_ID = block.chainid;\\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 amount) public virtual returns (bool) {\\n allowance[msg.sender][spender] = amount;\\n\\n emit Approval(msg.sender, spender, amount);\\n\\n return true;\\n }\\n\\n function transfer(address to, uint256 amount) public virtual returns (bool) {\\n balanceOf[msg.sender] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(msg.sender, to, amount);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual returns (bool) {\\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\\n\\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\\n\\n balanceOf[from] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n return true;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(deadline >= block.timestamp, \\\"PERMIT_DEADLINE_EXPIRED\\\");\\n\\n // Unchecked because the only math done is incrementing\\n // the owner's nonce which cannot realistically overflow.\\n unchecked {\\n address recoveredAddress = ecrecover(\\n keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\",\\n DOMAIN_SEPARATOR(),\\n keccak256(\\n abi.encode(\\n keccak256(\\n \\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\"\\n ),\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n )\\n ),\\n v,\\n r,\\n s\\n );\\n\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"INVALID_SIGNER\\\");\\n\\n allowance[recoveredAddress][spender] = value;\\n }\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\\n }\\n\\n function computeDomainSeparator() internal view virtual returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name)),\\n keccak256(\\\"1\\\"),\\n block.chainid,\\n address(this)\\n )\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 amount) internal virtual {\\n totalSupply += amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(address(0), to, amount);\\n }\\n\\n function _burn(address from, uint256 amount) internal virtual {\\n balanceOf[from] -= amount;\\n\\n // Cannot underflow because a user's balance\\n // will never be larger than the total supply.\\n unchecked {\\n totalSupply -= amount;\\n }\\n\\n emit Transfer(from, address(0), amount);\\n }\\n}\\n\",\"keccak256\":\"0x0240f7703cff32a61ee3e9fbb339e09a944260432a9ef37debf3692b1a6c8049\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\\n\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE/LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n function tokenURI(uint256 id) public view virtual returns (string memory);\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 BALANCE/OWNER STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) internal _ownerOf;\\n\\n mapping(address => uint256) internal _balanceOf;\\n\\n function ownerOf(uint256 id) public view virtual returns (address owner) {\\n require((owner = _ownerOf[id]) != address(0), \\\"NOT_MINTED\\\");\\n }\\n\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n require(owner != address(0), \\\"ZERO_ADDRESS\\\");\\n\\n return _balanceOf[owner];\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 APPROVAL STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) public getApproved;\\n\\n mapping(address => mapping(address => bool)) public isApprovedForAll;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(string memory _name, string memory _symbol) {\\n name = _name;\\n symbol = _symbol;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 id) public virtual {\\n address owner = _ownerOf[id];\\n\\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \\\"NOT_AUTHORIZED\\\");\\n\\n getApproved[id] = spender;\\n\\n emit Approval(owner, spender, id);\\n }\\n\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n isApprovedForAll[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(msg.sender, operator, approved);\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n require(from == _ownerOf[id], \\\"WRONG_FROM\\\");\\n\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(\\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\\n \\\"NOT_AUTHORIZED\\\"\\n );\\n\\n // Underflow of the sender's balance is impossible because we check for\\n // ownership above and the recipient's balance can't realistically overflow.\\n unchecked {\\n _balanceOf[from]--;\\n\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n delete getApproved[id];\\n\\n emit Transfer(from, to, id);\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n bytes calldata data\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC165 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return\\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 id) internal virtual {\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(_ownerOf[id] == address(0), \\\"ALREADY_MINTED\\\");\\n\\n // Counter overflow is incredibly unrealistic.\\n unchecked {\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n emit Transfer(address(0), to, id);\\n }\\n\\n function _burn(uint256 id) internal virtual {\\n address owner = _ownerOf[id];\\n\\n require(owner != address(0), \\\"NOT_MINTED\\\");\\n\\n // Ownership check above ensures no underflow.\\n unchecked {\\n _balanceOf[owner]--;\\n }\\n\\n delete _ownerOf[id];\\n\\n delete getApproved[id];\\n\\n emit Transfer(owner, address(0), id);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL SAFE MINT LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _safeMint(address to, uint256 id) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function _safeMint(\\n address to,\\n uint256 id,\\n bytes memory data\\n ) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n}\\n\\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721TokenReceiver {\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external virtual returns (bytes4) {\\n return ERC721TokenReceiver.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0xb59c7c25eca386f39da4819a9f70f89b73b7583d5f5127a83ffe5339800b1183\",\"license\":\"AGPL-3.0-only\"},\"contracts/universal/AssetReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { ERC20 } from \\\"@rari-capital/solmate/src/tokens/ERC20.sol\\\";\\nimport { ERC721 } from \\\"@rari-capital/solmate/src/tokens/ERC721.sol\\\";\\nimport { Transactor } from \\\"./Transactor.sol\\\";\\n\\n/**\\n * @title AssetReceiver\\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\\n */\\ncontract AssetReceiver is Transactor {\\n /**\\n * Emitted when ETH is received by this address.\\n */\\n event ReceivedETH(address indexed from, uint256 amount);\\n\\n /**\\n * Emitted when ETH is withdrawn from this address.\\n */\\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\\n\\n /**\\n * Emitted when ERC20 tokens are withdrawn from this address.\\n */\\n event WithdrewERC20(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 amount\\n );\\n\\n /**\\n * Emitted when ERC721 tokens are withdrawn from this address.\\n */\\n event WithdrewERC721(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 id\\n );\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Transactor(_owner) {}\\n\\n /**\\n * Make sure we can receive ETH.\\n */\\n receive() external payable {\\n emit ReceivedETH(msg.sender, msg.value);\\n }\\n\\n /**\\n * Withdraws full ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n */\\n function withdrawETH(address payable _to) external onlyOwner {\\n withdrawETH(_to, address(this).balance);\\n }\\n\\n /**\\n * Withdraws partial ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n * @param _amount Amount of ETH to withdraw.\\n */\\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\\n // slither-disable-next-line reentrancy-unlimited-gas\\n _to.transfer(_amount);\\n emit WithdrewETH(msg.sender, _to, _amount);\\n }\\n\\n /**\\n * Withdraws full ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n */\\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\\n }\\n\\n /**\\n * Withdraws partial ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n * @param _amount Amount of ERC20 to withdraw.\\n */\\n function withdrawERC20(\\n ERC20 _asset,\\n address _to,\\n uint256 _amount\\n ) public onlyOwner {\\n // slither-disable-next-line unchecked-transfer\\n _asset.transfer(_to, _amount);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\\n }\\n\\n /**\\n * Withdraws ERC721 token to the recipient.\\n *\\n * @param _asset ERC721 token to withdraw.\\n * @param _to Address to receive the ERC721 token.\\n * @param _id Token ID of the ERC721 token to withdraw.\\n */\\n function withdrawERC721(\\n ERC721 _asset,\\n address _to,\\n uint256 _id\\n ) external onlyOwner {\\n _asset.transferFrom(address(this), _to, _id);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\\n }\\n}\\n\",\"keccak256\":\"0x1f82aff6f4e5a4bebebbfb4a2e0e4378ef9bc5bee8b81f88b27fc0ce73546d5f\",\"license\":\"MIT\"},\"contracts/universal/TeleportrWithdrawer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { AssetReceiver } from \\\"./AssetReceiver.sol\\\";\\n\\n/**\\n * @notice Stub interface for Teleportr.\\n */\\ninterface Teleportr {\\n function withdrawBalance() external;\\n}\\n\\n/**\\n * @title TeleportrWithdrawer\\n * @notice The TeleportrWithdrawer is a simple contract capable of withdrawing funds from the\\n * TeleportrContract and sending them to some recipient address.\\n */\\ncontract TeleportrWithdrawer is AssetReceiver {\\n /**\\n * @notice Address of the Teleportr contract.\\n */\\n address public teleportr;\\n\\n /**\\n * @notice Address that will receive Teleportr withdrawals.\\n */\\n address public recipient;\\n\\n /**\\n * @notice Data to be sent to the recipient address.\\n */\\n bytes public data;\\n\\n /**\\n * @param _owner Initial owner of the contract.\\n */\\n constructor(address _owner) AssetReceiver(_owner) {}\\n\\n /**\\n * @notice Allows the owner to update the recipient address.\\n *\\n * @param _recipient New recipient address.\\n */\\n function setRecipient(address _recipient) external onlyOwner {\\n recipient = _recipient;\\n }\\n\\n /**\\n * @notice Allows the owner to update the Teleportr contract address.\\n *\\n * @param _teleportr New Teleportr contract address.\\n */\\n function setTeleportr(address _teleportr) external onlyOwner {\\n teleportr = _teleportr;\\n }\\n\\n /**\\n * @notice Allows the owner to update the data to be sent to the recipient address.\\n *\\n * @param _data New data to be sent to the recipient address.\\n */\\n function setData(bytes memory _data) external onlyOwner {\\n data = _data;\\n }\\n\\n /**\\n * @notice Withdraws the full balance of the Teleportr contract to the recipient address.\\n * Anyone is allowed to trigger this function since the recipient address cannot be\\n * controlled by the msg.sender.\\n */\\n function withdrawFromTeleportr() external {\\n Teleportr(teleportr).withdrawBalance();\\n (bool success, ) = recipient.call{ value: address(this).balance }(data);\\n require(success, \\\"TeleportrWithdrawer: send failed\\\");\\n }\\n}\\n\",\"keccak256\":\"0x26414ae14c7aee927c18075ee60757383e0202c2a2691f23b86c200c0ac24713\",\"license\":\"MIT\"},\"contracts/universal/Transactor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { Owned } from \\\"@rari-capital/solmate/src/auth/Owned.sol\\\";\\n\\n/**\\n * @title Transactor\\n * @notice Transactor is a minimal contract that can send transactions.\\n */\\ncontract Transactor is Owned {\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Owned(_owner) {}\\n\\n /**\\n * Sends a CALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @param _value ETH value to send with the call.\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function CALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas,\\n uint256 _value\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n return _target.call{ gas: _gas, value: _value }(_data);\\n }\\n\\n /**\\n * Sends a DELEGATECALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function DELEGATECALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n // slither-disable-next-line controlled-delegatecall\\n return _target.delegatecall{ gas: _gas }(_data);\\n }\\n}\\n\",\"keccak256\":\"0xfe0d9c05a423d36775047e3285f76b874f8b887444d412a0d680c302c3b06a50\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506040516115ac3803806115ac83398101604081905261002f91610086565b600080546001600160a01b0319166001600160a01b03831690811782556040518392839283929091907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908290a3505050506100b6565b60006020828403121561009857600080fd5b81516001600160a01b03811681146100af57600080fd5b9392505050565b6114e7806100c56000396000f3fe6080604052600436106100f75760003560e01c8063617d55421161008a5780638da5cb5b116100595780638da5cb5b146102f65780639456fbcc146103235780639e73dbea14610343578063ab62f0e11461035657600080fd5b8063617d55421461026757806366d003ac14610287578063690d8320146102b457806373d4a13a146102d457600080fd5b80634025feb2116100c65780634025feb2146101e657806344004cc1146102065780634782f779146102265780635cef8b4a1461024657600080fd5b806306fa29b21461013857806313af40351461018f5780633afe48c2146101b15780633bbed4a0146101c657600080fd5b366101335760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561014457600080fd5b506001546101659073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561019b57600080fd5b506101af6101aa366004610ff1565b610376565b005b3480156101bd57600080fd5b506101af610452565b3480156101d257600080fd5b506101af6101e1366004610ff1565b61059a565b3480156101f257600080fd5b506101af610201366004611015565b610648565b34801561021257600080fd5b506101af610221366004611015565b6107c0565b34801561023257600080fd5b506101af610241366004611056565b610946565b61025961025436600461115c565b610a42565b60405161018692919061122f565b34801561027357600080fd5b506101af610282366004610ff1565b610b21565b34801561029357600080fd5b506002546101659073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102c057600080fd5b506101af6102cf366004610ff1565b610bcf565b3480156102e057600080fd5b506102e9610c40565b6040516101869190611252565b34801561030257600080fd5b506000546101659073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032f57600080fd5b506101af61033e366004611265565b610cce565b61025961035136600461129e565b610dde565b34801561036257600080fd5b506101af6103713660046112fe565b610ec1565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103e25760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635fd8c7106040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104bc57600080fd5b505af11580156104d0573d6000803e3d6000fd5b50506002546040516000935073ffffffffffffffffffffffffffffffffffffffff9091169150479061050490600390611387565b60006040518083038185875af1925050503d8060008114610541576040519150601f19603f3d011682016040523d82523d6000602084013e610546565b606091505b50509050806105975760405162461bcd60e51b815260206004820181905260248201527f54656c65706f727472576974686472617765723a2073656e64206661696c656460448201526064016103d9565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106015760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106af5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561072557600080fd5b505af1158015610739573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8846040516107b391815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108275760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b15801561089757600080fd5b505af11580156108ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cf919061145a565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa846040516107b391815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109ad5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f193505050501580156109f0573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610aad5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610ad3919061147c565b6000604051808303818686f4925050503d8060008114610b0f576040519150601f19603f3d011682016040523d82523d6000602084013e610b14565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b885760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c365760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6105978147610946565b60038054610c4d90611333565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7990611333565b8015610cc65780601f10610c9b57610100808354040283529160200191610cc6565b820191906000526020600020905b815481529060010190602001808311610ca957829003601f168201915b505050505081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d355760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610dda908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b158015610da257600080fd5b505afa158015610db6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102219190611498565b5050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610e495760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8573ffffffffffffffffffffffffffffffffffffffff16848487604051610e70919061147c565b600060405180830381858888f193505050503d8060008114610eae576040519150601f19603f3d011682016040523d82523d6000602084013e610eb3565b606091505b509150915094509492505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f285760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8051610dda906003906020840190828054610f4290611333565b90600052602060002090601f016020900481019282610f645760008555610faa565b82601f10610f7d57805160ff1916838001178555610faa565b82800160010185558215610faa579182015b82811115610faa578251825591602001919060010190610f8f565b50610fb6929150610fba565b5090565b5b80821115610fb65760008155600101610fbb565b73ffffffffffffffffffffffffffffffffffffffff8116811461059757600080fd5b60006020828403121561100357600080fd5b813561100e81610fcf565b9392505050565b60008060006060848603121561102a57600080fd5b833561103581610fcf565b9250602084013561104581610fcf565b929592945050506040919091013590565b6000806040838503121561106957600080fd5b823561107481610fcf565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126110c257600080fd5b813567ffffffffffffffff808211156110dd576110dd611082565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561112357611123611082565b8160405283815286602085880101111561113c57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561117157600080fd5b833561117c81610fcf565b9250602084013567ffffffffffffffff81111561119857600080fd5b6111a4868287016110b1565b925050604084013590509250925092565b60005b838110156111d05781810151838201526020016111b8565b838111156111df576000848401525b50505050565b600081518084526111fd8160208601602086016111b5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b821515815260406020820152600061124a60408301846111e5565b949350505050565b60208152600061100e60208301846111e5565b6000806040838503121561127857600080fd5b823561128381610fcf565b9150602083013561129381610fcf565b809150509250929050565b600080600080608085870312156112b457600080fd5b84356112bf81610fcf565b9350602085013567ffffffffffffffff8111156112db57600080fd5b6112e7878288016110b1565b949794965050505060408301359260600135919050565b60006020828403121561131057600080fd5b813567ffffffffffffffff81111561132757600080fd5b61124a848285016110b1565b600181811c9082168061134757607f821691505b60208210811415611381577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600080835481600182811c9150808316806113a357607f831692505b60208084108214156113dc577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b8180156113f0576001811461141f5761144c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0086168952848901965061144c565b60008a81526020902060005b868110156114445781548b82015290850190830161142b565b505084890196505b509498975050505050505050565b60006020828403121561146c57600080fd5b8151801515811461100e57600080fd5b6000825161148e8184602087016111b5565b9190910192915050565b6000602082840312156114aa57600080fd5b505191905056fea26469706673582212203903a2f3f310c1942ac6f552df9012c64af2d384894531650c63a359397535f364736f6c63430008090033", - "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063617d55421161008a5780638da5cb5b116100595780638da5cb5b146102f65780639456fbcc146103235780639e73dbea14610343578063ab62f0e11461035657600080fd5b8063617d55421461026757806366d003ac14610287578063690d8320146102b457806373d4a13a146102d457600080fd5b80634025feb2116100c65780634025feb2146101e657806344004cc1146102065780634782f779146102265780635cef8b4a1461024657600080fd5b806306fa29b21461013857806313af40351461018f5780633afe48c2146101b15780633bbed4a0146101c657600080fd5b366101335760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561014457600080fd5b506001546101659073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561019b57600080fd5b506101af6101aa366004610ff1565b610376565b005b3480156101bd57600080fd5b506101af610452565b3480156101d257600080fd5b506101af6101e1366004610ff1565b61059a565b3480156101f257600080fd5b506101af610201366004611015565b610648565b34801561021257600080fd5b506101af610221366004611015565b6107c0565b34801561023257600080fd5b506101af610241366004611056565b610946565b61025961025436600461115c565b610a42565b60405161018692919061122f565b34801561027357600080fd5b506101af610282366004610ff1565b610b21565b34801561029357600080fd5b506002546101659073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102c057600080fd5b506101af6102cf366004610ff1565b610bcf565b3480156102e057600080fd5b506102e9610c40565b6040516101869190611252565b34801561030257600080fd5b506000546101659073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032f57600080fd5b506101af61033e366004611265565b610cce565b61025961035136600461129e565b610dde565b34801561036257600080fd5b506101af6103713660046112fe565b610ec1565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103e25760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635fd8c7106040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104bc57600080fd5b505af11580156104d0573d6000803e3d6000fd5b50506002546040516000935073ffffffffffffffffffffffffffffffffffffffff9091169150479061050490600390611387565b60006040518083038185875af1925050503d8060008114610541576040519150601f19603f3d011682016040523d82523d6000602084013e610546565b606091505b50509050806105975760405162461bcd60e51b815260206004820181905260248201527f54656c65706f727472576974686472617765723a2073656e64206661696c656460448201526064016103d9565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106015760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106af5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561072557600080fd5b505af1158015610739573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8846040516107b391815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108275760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b15801561089757600080fd5b505af11580156108ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cf919061145a565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa846040516107b391815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109ad5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f193505050501580156109f0573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610aad5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610ad3919061147c565b6000604051808303818686f4925050503d8060008114610b0f576040519150601f19603f3d011682016040523d82523d6000602084013e610b14565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b885760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c365760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6105978147610946565b60038054610c4d90611333565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7990611333565b8015610cc65780601f10610c9b57610100808354040283529160200191610cc6565b820191906000526020600020905b815481529060010190602001808311610ca957829003601f168201915b505050505081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d355760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610dda908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b158015610da257600080fd5b505afa158015610db6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102219190611498565b5050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610e495760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8573ffffffffffffffffffffffffffffffffffffffff16848487604051610e70919061147c565b600060405180830381858888f193505050503d8060008114610eae576040519150601f19603f3d011682016040523d82523d6000602084013e610eb3565b606091505b509150915094509492505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f285760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8051610dda906003906020840190828054610f4290611333565b90600052602060002090601f016020900481019282610f645760008555610faa565b82601f10610f7d57805160ff1916838001178555610faa565b82800160010185558215610faa579182015b82811115610faa578251825591602001919060010190610f8f565b50610fb6929150610fba565b5090565b5b80821115610fb65760008155600101610fbb565b73ffffffffffffffffffffffffffffffffffffffff8116811461059757600080fd5b60006020828403121561100357600080fd5b813561100e81610fcf565b9392505050565b60008060006060848603121561102a57600080fd5b833561103581610fcf565b9250602084013561104581610fcf565b929592945050506040919091013590565b6000806040838503121561106957600080fd5b823561107481610fcf565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126110c257600080fd5b813567ffffffffffffffff808211156110dd576110dd611082565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561112357611123611082565b8160405283815286602085880101111561113c57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561117157600080fd5b833561117c81610fcf565b9250602084013567ffffffffffffffff81111561119857600080fd5b6111a4868287016110b1565b925050604084013590509250925092565b60005b838110156111d05781810151838201526020016111b8565b838111156111df576000848401525b50505050565b600081518084526111fd8160208601602086016111b5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b821515815260406020820152600061124a60408301846111e5565b949350505050565b60208152600061100e60208301846111e5565b6000806040838503121561127857600080fd5b823561128381610fcf565b9150602083013561129381610fcf565b809150509250929050565b600080600080608085870312156112b457600080fd5b84356112bf81610fcf565b9350602085013567ffffffffffffffff8111156112db57600080fd5b6112e7878288016110b1565b949794965050505060408301359260600135919050565b60006020828403121561131057600080fd5b813567ffffffffffffffff81111561132757600080fd5b61124a848285016110b1565b600181811c9082168061134757607f821691505b60208210811415611381577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600080835481600182811c9150808316806113a357607f831692505b60208084108214156113dc577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b8180156113f0576001811461141f5761144c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0086168952848901965061144c565b60008a81526020902060005b868110156114445781548b82015290850190830161142b565b505084890196505b509498975050505050505050565b60006020828403121561146c57600080fd5b8151801515811461100e57600080fd5b6000825161148e8184602087016111b5565b9190910192915050565b6000602082840312156114aa57600080fd5b505191905056fea26469706673582212203903a2f3f310c1942ac6f552df9012c64af2d384894531650c63a359397535f364736f6c63430008090033", - "devdoc": { - "kind": "dev", - "methods": { - "CALL(address,bytes,uint256,uint256)": { - "params": { - "_data": "Data to send with the call.", - "_gas": "Amount of gas to send with the call.", - "_target": "Address to call.", - "_value": "ETH value to send with the call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "DELEGATECALL(address,bytes,uint256)": { - "params": { - "_data": "Data to send with the call.", - "_gas": "Amount of gas to send with the call.", - "_target": "Address to call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "constructor": { - "params": { - "_owner": "Initial owner of the contract." - } - }, - "setData(bytes)": { - "params": { - "_data": "New data to be sent to the recipient address." - } - }, - "setRecipient(address)": { - "params": { - "_recipient": "New recipient address." - } - }, - "setTeleportr(address)": { - "params": { - "_teleportr": "New Teleportr contract address." - } - }, - "withdrawERC20(address,address)": { - "params": { - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC20(address,address,uint256)": { - "params": { - "_amount": "Amount of ERC20 to withdraw.", - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC721(address,address,uint256)": { - "params": { - "_asset": "ERC721 token to withdraw.", - "_id": "Token ID of the ERC721 token to withdraw.", - "_to": "Address to receive the ERC721 token." - } - }, - "withdrawETH(address)": { - "params": { - "_to": "Address to receive the ETH balance." - } - }, - "withdrawETH(address,uint256)": { - "params": { - "_amount": "Amount of ETH to withdraw.", - "_to": "Address to receive the ETH balance." - } - } - }, - "title": "TeleportrWithdrawer", - "version": 1 - }, - "userdoc": { - "events": { - "ReceivedETH(address,uint256)": { - "notice": "Emitted when ETH is received by this address." - }, - "WithdrewERC20(address,address,address,uint256)": { - "notice": "Emitted when ERC20 tokens are withdrawn from this address." - }, - "WithdrewERC721(address,address,address,uint256)": { - "notice": "Emitted when ERC721 tokens are withdrawn from this address." - }, - "WithdrewETH(address,address,uint256)": { - "notice": "Emitted when ETH is withdrawn from this address." - } - }, - "kind": "user", - "methods": { - "CALL(address,bytes,uint256,uint256)": { - "notice": "Sends a CALL to a target address." - }, - "DELEGATECALL(address,bytes,uint256)": { - "notice": "Sends a DELEGATECALL to a target address." - }, - "data()": { - "notice": "Data to be sent to the recipient address." - }, - "recipient()": { - "notice": "Address that will receive Teleportr withdrawals." - }, - "setData(bytes)": { - "notice": "Allows the owner to update the data to be sent to the recipient address." - }, - "setRecipient(address)": { - "notice": "Allows the owner to update the recipient address." - }, - "setTeleportr(address)": { - "notice": "Allows the owner to update the Teleportr contract address." - }, - "teleportr()": { - "notice": "Address of the Teleportr contract." - }, - "withdrawERC20(address,address)": { - "notice": "Withdraws full ERC20 balance to the recipient." - }, - "withdrawERC20(address,address,uint256)": { - "notice": "Withdraws partial ERC20 balance to the recipient." - }, - "withdrawERC721(address,address,uint256)": { - "notice": "Withdraws ERC721 token to the recipient." - }, - "withdrawETH(address)": { - "notice": "Withdraws full ETH balance to the recipient." - }, - "withdrawETH(address,uint256)": { - "notice": "Withdraws partial ETH balance to the recipient." - }, - "withdrawFromTeleportr()": { - "notice": "Withdraws the full balance of the Teleportr contract to the recipient address. Anyone is allowed to trigger this function since the recipient address cannot be controlled by the msg.sender." - } - }, - "notice": "The TeleportrWithdrawer is a simple contract capable of withdrawing funds from the TeleportrContract and sending them to some recipient address.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 4371, - "contract": "contracts/universal/TeleportrWithdrawer.sol:TeleportrWithdrawer", - "label": "owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 6314, - "contract": "contracts/universal/TeleportrWithdrawer.sol:TeleportrWithdrawer", - "label": "teleportr", - "offset": 0, - "slot": "1", - "type": "t_address" - }, - { - "astId": 6317, - "contract": "contracts/universal/TeleportrWithdrawer.sol:TeleportrWithdrawer", - "label": "recipient", - "offset": 0, - "slot": "2", - "type": "t_address" - }, - { - "astId": 6320, - "contract": "contracts/universal/TeleportrWithdrawer.sol:TeleportrWithdrawer", - "label": "data", - "offset": 0, - "slot": "3", - "type": "t_bytes_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bytes_storage": { - "encoding": "bytes", - "label": "bytes", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/mainnet/solcInputs/13ac93d026822f719ad110af836d1582.json b/packages/contracts-bedrock/deployments/mainnet/solcInputs/13ac93d026822f719ad110af836d1582.json deleted file mode 100644 index cde6d404005a..000000000000 --- a/packages/contracts-bedrock/deployments/mainnet/solcInputs/13ac93d026822f719ad110af836d1582.json +++ /dev/null @@ -1,596 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/L1/L1CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismPortal } from \"./OptimismPortal.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1CrossDomainMessenger\n * @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible\n * for sending and receiving data on the L1 side. Users are encouraged to use this\n * interface instead of interacting with lower-level contracts directly.\n */\ncontract L1CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @notice Address of the OptimismPortal.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @custom:semver 1.4.0\n *\n * @param _portal Address of the OptimismPortal contract on this network.\n */\n constructor(OptimismPortal _portal)\n Semver(1, 4, 0)\n CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER)\n {\n PORTAL = _portal;\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return msg.sender == address(PORTAL) && PORTAL.l2Sender() == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(PORTAL);\n }\n}\n" - }, - "contracts/L1/L1ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { IERC721 } from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L1ERC721Bridge\n * @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as an escrow for ERC721 tokens deposited into L2.\n */\ncontract L1ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token\n * by ID was deposited for a given L2 token.\n */\n mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;\n\n /**\n * @custom:semver 1.1.1\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 1)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L1ERC721Bridge: local token cannot be self\");\n\n // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.\n require(\n deposits[_localToken][_remoteToken][_tokenId] == true,\n \"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\"\n );\n\n // Mark that the token ID for this L1/L2 token pair is no longer escrowed in the L1\n // Bridge.\n deposits[_localToken][_remoteToken][_tokenId] = false;\n\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the\n // withdrawer.\n IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L1ERC721Bridge: remote token cannot be address(0)\");\n\n // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)\n bytes memory message = abi.encodeWithSelector(\n L2ERC721Bridge.finalizeBridgeERC721.selector,\n _remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Lock token into bridge\n deposits[_localToken][_remoteToken][_tokenId] = true;\n IERC721(_localToken).transferFrom(_from, address(this), _tokenId);\n\n // Send calldata into L2\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L1/L1StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1StandardBridge\n * @notice The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L1, it will be escrowed within this\n * contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was\n * stored within this contract. After Bedrock, ETH is instead stored inside the\n * OptimismPortal contract.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L1StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated.\n *\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of ETH deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ETHDepositInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized.\n *\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of ETH withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 withdrawal is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _messenger Address of the L1CrossDomainMessenger.\n */\n constructor(address payable _messenger)\n Semver(1, 1, 0)\n StandardBridge(_messenger, payable(Predeploys.L2_STANDARD_BRIDGE))\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into the sender's account on L2.\n *\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETH(uint32 _minGasLimit, bytes calldata _extraData) external payable onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into a target account on L2.\n * Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will\n * be locked in the L2StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n *\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable {\n _initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into the sender's account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20(\n address _l1Token,\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual onlyEOA {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into a target account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20To(\n address _l1Token,\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ETH from L2.\n *\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of ETH to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeETHWithdrawal(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ERC20 tokens from L2.\n *\n * @param _l1Token Address of the token on L1.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of the ERC20 to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeERC20Withdrawal(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external {\n finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L2 bridge contract.\n *\n * @return Address of the corresponding L2 bridge contract.\n */\n function l2TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @notice Internal function for initiating an ETH deposit.\n *\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateETHDeposit(\n address _from,\n address _to,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Internal function for initiating an ERC20 deposit.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateERC20Deposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHDepositInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHDepositInitiated(_from, _to, _amount, _extraData);\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHWithdrawalFinalized event followed by the ETHBridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData);\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20DepositInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20DepositInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20WithdrawalFinalized event followed by the ERC20BridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20WithdrawalFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L1/L2OutputOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\n/**\n * @custom:proxied\n * @title L2OutputOracle\n * @notice The L2OutputOracle contains an array of L2 state outputs, where each output is a\n * commitment to the state of the L2 chain. Other contracts like the OptimismPortal use\n * these outputs to verify information about the state of L2.\n */\ncontract L2OutputOracle is Initializable, Semver {\n /**\n * @notice The interval in L2 blocks at which checkpoints must be submitted. Although this is\n * immutable, it can safely be modified by upgrading the implementation contract.\n */\n uint256 public immutable SUBMISSION_INTERVAL;\n\n /**\n * @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified.\n */\n uint256 public immutable L2_BLOCK_TIME;\n\n /**\n * @notice The address of the challenger. Can be updated via upgrade.\n */\n address public immutable CHALLENGER;\n\n /**\n * @notice The address of the proposer. Can be updated via upgrade.\n */\n address public immutable PROPOSER;\n\n /**\n * @notice Minimum time (in seconds) that must elapse before a withdrawal can be finalized.\n */\n uint256 public immutable FINALIZATION_PERIOD_SECONDS;\n\n /**\n * @notice The number of the first L2 block recorded in this contract.\n */\n uint256 public startingBlockNumber;\n\n /**\n * @notice The timestamp of the first L2 block recorded in this contract.\n */\n uint256 public startingTimestamp;\n\n /**\n * @notice Array of L2 output proposals.\n */\n Types.OutputProposal[] internal l2Outputs;\n\n /**\n * @notice Emitted when an output is proposed.\n *\n * @param outputRoot The output root.\n * @param l2OutputIndex The index of the output in the l2Outputs array.\n * @param l2BlockNumber The L2 block number of the output root.\n * @param l1Timestamp The L1 timestamp when proposed.\n */\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n /**\n * @notice Emitted when outputs are deleted.\n *\n * @param prevNextOutputIndex Next L2 output index before the deletion.\n * @param newNextOutputIndex Next L2 output index after the deletion.\n */\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n /**\n * @custom:semver 1.3.0\n *\n * @param _submissionInterval Interval in blocks at which checkpoints must be submitted.\n * @param _l2BlockTime The time per L2 block, in seconds.\n * @param _startingBlockNumber The number of the first L2 block.\n * @param _startingTimestamp The timestamp of the first L2 block.\n * @param _proposer The address of the proposer.\n * @param _challenger The address of the challenger.\n */\n constructor(\n uint256 _submissionInterval,\n uint256 _l2BlockTime,\n uint256 _startingBlockNumber,\n uint256 _startingTimestamp,\n address _proposer,\n address _challenger,\n uint256 _finalizationPeriodSeconds\n ) Semver(1, 3, 0) {\n require(_l2BlockTime > 0, \"L2OutputOracle: L2 block time must be greater than 0\");\n require(\n _submissionInterval > 0,\n \"L2OutputOracle: submission interval must be greater than 0\"\n );\n\n SUBMISSION_INTERVAL = _submissionInterval;\n L2_BLOCK_TIME = _l2BlockTime;\n PROPOSER = _proposer;\n CHALLENGER = _challenger;\n FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;\n\n initialize(_startingBlockNumber, _startingTimestamp);\n }\n\n /**\n * @notice Initializer.\n *\n * @param _startingBlockNumber Block number for the first recoded L2 block.\n * @param _startingTimestamp Timestamp for the first recoded L2 block.\n */\n function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp)\n public\n initializer\n {\n require(\n _startingTimestamp <= block.timestamp,\n \"L2OutputOracle: starting L2 timestamp must be less than current time\"\n );\n\n startingTimestamp = _startingTimestamp;\n startingBlockNumber = _startingBlockNumber;\n }\n\n /**\n * @notice Deletes all output proposals after and including the proposal that corresponds to\n * the given output index. Only the challenger address can delete outputs.\n *\n * @param _l2OutputIndex Index of the first L2 output to be deleted. All outputs after this\n * output will also be deleted.\n */\n // solhint-disable-next-line ordering\n function deleteL2Outputs(uint256 _l2OutputIndex) external {\n require(\n msg.sender == CHALLENGER,\n \"L2OutputOracle: only the challenger address can delete outputs\"\n );\n\n // Make sure we're not *increasing* the length of the array.\n require(\n _l2OutputIndex < l2Outputs.length,\n \"L2OutputOracle: cannot delete outputs after the latest output index\"\n );\n\n // Do not allow deleting any outputs that have already been finalized.\n require(\n block.timestamp - l2Outputs[_l2OutputIndex].timestamp < FINALIZATION_PERIOD_SECONDS,\n \"L2OutputOracle: cannot delete outputs that have already been finalized\"\n );\n\n uint256 prevNextL2OutputIndex = nextOutputIndex();\n\n // Use assembly to delete the array elements because Solidity doesn't allow it.\n assembly {\n sstore(l2Outputs.slot, _l2OutputIndex)\n }\n\n emit OutputsDeleted(prevNextL2OutputIndex, _l2OutputIndex);\n }\n\n /**\n * @notice Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp\n * must be equal to the current value returned by `nextTimestamp()` in order to be\n * accepted. This function may only be called by the Proposer.\n *\n * @param _outputRoot The L2 output of the checkpoint block.\n * @param _l2BlockNumber The L2 block number that resulted in _outputRoot.\n * @param _l1BlockHash A block hash which must be included in the current chain.\n * @param _l1BlockNumber The block number with the specified block hash.\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external payable {\n require(\n msg.sender == PROPOSER,\n \"L2OutputOracle: only the proposer address can propose new outputs\"\n );\n\n require(\n _l2BlockNumber == nextBlockNumber(),\n \"L2OutputOracle: block number must be equal to next expected block number\"\n );\n\n require(\n computeL2Timestamp(_l2BlockNumber) < block.timestamp,\n \"L2OutputOracle: cannot propose L2 output in the future\"\n );\n\n require(\n _outputRoot != bytes32(0),\n \"L2OutputOracle: L2 output proposal cannot be the zero hash\"\n );\n\n if (_l1BlockHash != bytes32(0)) {\n // This check allows the proposer to propose an output based on a given L1 block,\n // without fear that it will be reorged out.\n // It will also revert if the blockheight provided is more than 256 blocks behind the\n // chain tip (as the hash will return as zero). This does open the door to a griefing\n // attack in which the proposer's submission is censored until the block is no longer\n // retrievable, if the proposer is experiencing this attack it can simply leave out the\n // blockhash value, and delay submission until it is confident that the L1 block is\n // finalized.\n require(\n blockhash(_l1BlockNumber) == _l1BlockHash,\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n }\n\n emit OutputProposed(_outputRoot, nextOutputIndex(), _l2BlockNumber, block.timestamp);\n\n l2Outputs.push(\n Types.OutputProposal({\n outputRoot: _outputRoot,\n timestamp: uint128(block.timestamp),\n l2BlockNumber: uint128(_l2BlockNumber)\n })\n );\n }\n\n /**\n * @notice Returns an output by index. Exists because Solidity's array access will return a\n * tuple instead of a struct.\n *\n * @param _l2OutputIndex Index of the output to return.\n *\n * @return The output at the given index.\n */\n function getL2Output(uint256 _l2OutputIndex)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[_l2OutputIndex];\n }\n\n /**\n * @notice Returns the index of the L2 output that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return Index of the first checkpoint that commits to the given L2 block number.\n */\n function getL2OutputIndexAfter(uint256 _l2BlockNumber) public view returns (uint256) {\n // Make sure an output for this block number has actually been proposed.\n require(\n _l2BlockNumber <= latestBlockNumber(),\n \"L2OutputOracle: cannot get output for a block that has not been proposed\"\n );\n\n // Make sure there's at least one output proposed.\n require(\n l2Outputs.length > 0,\n \"L2OutputOracle: cannot get output as no outputs have been proposed yet\"\n );\n\n // Find the output via binary search, guaranteed to exist.\n uint256 lo = 0;\n uint256 hi = l2Outputs.length;\n while (lo < hi) {\n uint256 mid = (lo + hi) / 2;\n if (l2Outputs[mid].l2BlockNumber < _l2BlockNumber) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n return lo;\n }\n\n /**\n * @notice Returns the L2 output proposal that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return First checkpoint that commits to the given L2 block number.\n */\n function getL2OutputAfter(uint256 _l2BlockNumber)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)];\n }\n\n /**\n * @notice Returns the number of outputs that have been proposed. Will revert if no outputs\n * have been proposed yet.\n *\n * @return The number of outputs that have been proposed.\n */\n function latestOutputIndex() external view returns (uint256) {\n return l2Outputs.length - 1;\n }\n\n /**\n * @notice Returns the index of the next output to be proposed.\n *\n * @return The index of the next output to be proposed.\n */\n function nextOutputIndex() public view returns (uint256) {\n return l2Outputs.length;\n }\n\n /**\n * @notice Returns the block number of the latest submitted L2 output proposal. If no proposals\n * been submitted yet then this function will return the starting block number.\n *\n * @return Latest submitted L2 block number.\n */\n function latestBlockNumber() public view returns (uint256) {\n return\n l2Outputs.length == 0\n ? startingBlockNumber\n : l2Outputs[l2Outputs.length - 1].l2BlockNumber;\n }\n\n /**\n * @notice Computes the block number of the next L2 block that needs to be checkpointed.\n *\n * @return Next L2 block number.\n */\n function nextBlockNumber() public view returns (uint256) {\n return latestBlockNumber() + SUBMISSION_INTERVAL;\n }\n\n /**\n * @notice Returns the L2 timestamp corresponding to a given L2 block number.\n *\n * @param _l2BlockNumber The L2 block number of the target block.\n *\n * @return L2 timestamp of the given block.\n */\n function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {\n return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME);\n }\n}\n" - }, - "contracts/L1/OptimismPortal.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { L2OutputOracle } from \"./L2OutputOracle.sol\";\nimport { SystemConfig } from \"./SystemConfig.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { SecureMerkleTrie } from \"../libraries/trie/SecureMerkleTrie.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title OptimismPortal\n * @notice The OptimismPortal is a low-level contract responsible for passing messages between L1\n * and L2. Messages sent directly to the OptimismPortal have no form of replayability.\n * Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface.\n */\ncontract OptimismPortal is Initializable, ResourceMetering, Semver {\n /**\n * @notice Represents a proven withdrawal.\n *\n * @custom:field outputRoot Root of the L2 output this was proven against.\n * @custom:field timestamp Timestamp at whcih the withdrawal was proven.\n * @custom:field l2OutputIndex Index of the output this was proven against.\n */\n struct ProvenWithdrawal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2OutputIndex;\n }\n\n /**\n * @notice Version of the deposit event.\n */\n uint256 internal constant DEPOSIT_VERSION = 0;\n\n /**\n * @notice The L2 gas limit set when eth is deposited using the receive() function.\n */\n uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Address of the L2OutputOracle contract.\n */\n L2OutputOracle public immutable L2_ORACLE;\n\n /**\n * @notice Address of the SystemConfig contract.\n */\n SystemConfig public immutable SYSTEM_CONFIG;\n\n /**\n * @notice Address that has the ability to pause and unpause withdrawals.\n */\n address public immutable GUARDIAN;\n\n /**\n * @notice Address of the L2 account which initiated a withdrawal in this transaction. If the\n * of this variable is the default L2 sender address, then we are NOT inside of a call\n * to finalizeWithdrawalTransaction.\n */\n address public l2Sender;\n\n /**\n * @notice A list of withdrawal hashes which have been successfully finalized.\n */\n mapping(bytes32 => bool) public finalizedWithdrawals;\n\n /**\n * @notice A mapping of withdrawal hashes to `ProvenWithdrawal` data.\n */\n mapping(bytes32 => ProvenWithdrawal) public provenWithdrawals;\n\n /**\n * @notice Determines if cross domain messaging is paused. When set to true,\n * withdrawals are paused. This may be removed in the future.\n */\n bool public paused;\n\n /**\n * @notice Emitted when a transaction is deposited from L1 to L2. The parameters of this event\n * are read by the rollup node and used to derive deposit transactions on L2.\n *\n * @param from Address that triggered the deposit transaction.\n * @param to Address that the deposit transaction is directed to.\n * @param version Version of this deposit transaction event.\n * @param opaqueData ABI encoded deposit data to be parsed off-chain.\n */\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is proven.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n */\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is finalized.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n * @param success Whether the withdrawal transaction was successful.\n */\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n\n /**\n * @notice Emitted when the pause is triggered.\n *\n * @param account Address of the account triggering the pause.\n */\n event Paused(address account);\n\n /**\n * @notice Emitted when the pause is lifted.\n *\n * @param account Address of the account triggering the unpause.\n */\n event Unpaused(address account);\n\n /**\n * @notice Reverts when paused.\n */\n modifier whenNotPaused() {\n require(paused == false, \"OptimismPortal: paused\");\n _;\n }\n\n /**\n * @custom:semver 1.6.0\n *\n * @param _l2Oracle Address of the L2OutputOracle contract.\n * @param _guardian Address that can pause deposits and withdrawals.\n * @param _paused Sets the contract's pausability state.\n * @param _config Address of the SystemConfig contract.\n */\n constructor(\n L2OutputOracle _l2Oracle,\n address _guardian,\n bool _paused,\n SystemConfig _config\n ) Semver(1, 6, 0) {\n L2_ORACLE = _l2Oracle;\n GUARDIAN = _guardian;\n SYSTEM_CONFIG = _config;\n initialize(_paused);\n }\n\n /**\n * @notice Initializer.\n */\n function initialize(bool _paused) public initializer {\n l2Sender = Constants.DEFAULT_L2_SENDER;\n paused = _paused;\n __ResourceMetering_init();\n }\n\n /**\n * @notice Pause deposits and withdrawals.\n */\n function pause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can pause\");\n paused = true;\n emit Paused(msg.sender);\n }\n\n /**\n * @notice Unpause deposits and withdrawals.\n */\n function unpause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can unpause\");\n paused = false;\n emit Unpaused(msg.sender);\n }\n\n /**\n * @notice Computes the minimum gas limit for a deposit. The minimum gas limit\n * linearly increases based on the size of the calldata. This is to prevent\n * users from creating L2 resource usage without paying for it. This function\n * can be used when interacting with the portal to ensure forwards compatibility.\n *\n */\n function minimumGasLimit(uint64 _byteCount) public pure returns (uint64) {\n return _byteCount * 16 + 21000;\n }\n\n /**\n * @notice Accepts value so that users can send ETH directly to this contract and have the\n * funds be deposited to their address on L2. This is intended as a convenience\n * function for EOAs. Contracts should call the depositTransaction() function directly\n * otherwise any deposited funds will be lost due to address aliasing.\n */\n // solhint-disable-next-line ordering\n receive() external payable {\n depositTransaction(msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes(\"\"));\n }\n\n /**\n * @notice Accepts ETH value without triggering a deposit to L2. This function mainly exists\n * for the sake of the migration between the legacy Optimism system and Bedrock.\n */\n function donateETH() external payable {\n // Intentionally empty.\n }\n\n /**\n * @notice Getter for the resource config. Used internally by the ResourceMetering\n * contract. The SystemConfig is the source of truth for the resource config.\n *\n * @return ResourceMetering.ResourceConfig\n */\n function _resourceConfig()\n internal\n view\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return SYSTEM_CONFIG.resourceConfig();\n }\n\n /**\n * @notice Proves a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n * @param _l2OutputIndex L2 output index to prove against.\n * @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root.\n * @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\n */\n function proveWithdrawalTransaction(\n Types.WithdrawalTransaction memory _tx,\n uint256 _l2OutputIndex,\n Types.OutputRootProof calldata _outputRootProof,\n bytes[] calldata _withdrawalProof\n ) external whenNotPaused {\n // Prevent users from creating a deposit transaction where this address is the message\n // sender on L2. Because this is checked here, we do not need to check again in\n // `finalizeWithdrawalTransaction`.\n require(\n _tx.target != address(this),\n \"OptimismPortal: you cannot send messages to the portal contract\"\n );\n\n // Get the output root and load onto the stack to prevent multiple mloads. This will\n // revert if there is no output root for the given block number.\n bytes32 outputRoot = L2_ORACLE.getL2Output(_l2OutputIndex).outputRoot;\n\n // Verify that the output root can be generated with the elements in the proof.\n require(\n outputRoot == Hashing.hashOutputRootProof(_outputRootProof),\n \"OptimismPortal: invalid output root proof\"\n );\n\n // Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // We generally want to prevent users from proving the same withdrawal multiple times\n // because each successive proof will update the timestamp. A malicious user can take\n // advantage of this to prevent other users from finalizing their withdrawal. However,\n // since withdrawals are proven before an output root is finalized, we need to allow users\n // to re-prove their withdrawal only in the case that the output root for their specified\n // output index has been updated.\n require(\n provenWithdrawal.timestamp == 0 ||\n L2_ORACLE.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot !=\n provenWithdrawal.outputRoot,\n \"OptimismPortal: withdrawal hash has already been proven\"\n );\n\n // Compute the storage slot of the withdrawal hash in the L2ToL1MessagePasser contract.\n // Refer to the Solidity documentation for more information on how storage layouts are\n // computed for mappings.\n bytes32 storageKey = keccak256(\n abi.encode(\n withdrawalHash,\n uint256(0) // The withdrawals mapping is at the first slot in the layout.\n )\n );\n\n // Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract\n // on L2. If this is true, under the assumption that the SecureMerkleTrie does not have\n // bugs, then we know that this withdrawal was actually triggered on L2 and can therefore\n // be relayed on L1.\n require(\n SecureMerkleTrie.verifyInclusionProof(\n abi.encode(storageKey),\n hex\"01\",\n _withdrawalProof,\n _outputRootProof.messagePasserStorageRoot\n ),\n \"OptimismPortal: invalid withdrawal inclusion proof\"\n );\n\n // Designate the withdrawalHash as proven by storing the `outputRoot`, `timestamp`, and\n // `l2BlockNumber` in the `provenWithdrawals` mapping. A `withdrawalHash` can only be\n // proven once unless it is submitted again with a different outputRoot.\n provenWithdrawals[withdrawalHash] = ProvenWithdrawal({\n outputRoot: outputRoot,\n timestamp: uint128(block.timestamp),\n l2OutputIndex: uint128(_l2OutputIndex)\n });\n\n // Emit a `WithdrawalProven` event.\n emit WithdrawalProven(withdrawalHash, _tx.sender, _tx.target);\n }\n\n /**\n * @notice Finalizes a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n */\n function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx)\n external\n whenNotPaused\n {\n // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other\n // than the default value when a withdrawal transaction is being finalized. This check is\n // a defacto reentrancy guard.\n require(\n l2Sender == Constants.DEFAULT_L2_SENDER,\n \"OptimismPortal: can only trigger one withdrawal per transaction\"\n );\n\n // Grab the proven withdrawal from the `provenWithdrawals` map.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // A withdrawal can only be finalized if it has been proven. We know that a withdrawal has\n // been proven at least once when its timestamp is non-zero. Unproven withdrawals will have\n // a timestamp of zero.\n require(\n provenWithdrawal.timestamp != 0,\n \"OptimismPortal: withdrawal has not been proven yet\"\n );\n\n // As a sanity check, we make sure that the proven withdrawal's timestamp is greater than\n // starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of\n // safety against weird bugs in the proving step.\n require(\n provenWithdrawal.timestamp >= L2_ORACLE.startingTimestamp(),\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n\n // A proven withdrawal must wait at least the finalization period before it can be\n // finalized. This waiting period can elapse in parallel with the waiting period for the\n // output the withdrawal was proven against. In effect, this means that the minimum\n // withdrawal time is proposal submission time + finalization period.\n require(\n _isFinalizationPeriodElapsed(provenWithdrawal.timestamp),\n \"OptimismPortal: proven withdrawal finalization period has not elapsed\"\n );\n\n // Grab the OutputProposal from the L2OutputOracle, will revert if the output that\n // corresponds to the given index has not been proposed yet.\n Types.OutputProposal memory proposal = L2_ORACLE.getL2Output(\n provenWithdrawal.l2OutputIndex\n );\n\n // Check that the output root that was used to prove the withdrawal is the same as the\n // current output root for the given output index. An output root may change if it is\n // deleted by the challenger address and then re-proposed.\n require(\n proposal.outputRoot == provenWithdrawal.outputRoot,\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n\n // Check that the output proposal has also been finalized.\n require(\n _isFinalizationPeriodElapsed(proposal.timestamp),\n \"OptimismPortal: output proposal finalization period has not elapsed\"\n );\n\n // Check that this withdrawal has not already been finalized, this is replay protection.\n require(\n finalizedWithdrawals[withdrawalHash] == false,\n \"OptimismPortal: withdrawal has already been finalized\"\n );\n\n // Mark the withdrawal as finalized so it can't be replayed.\n finalizedWithdrawals[withdrawalHash] = true;\n\n // Set the l2Sender so contracts know who triggered this withdrawal on L2.\n l2Sender = _tx.sender;\n\n // Trigger the call to the target contract. We use a custom low level method\n // SafeCall.callWithMinGas to ensure two key properties\n // 1. Target contracts cannot force this call to run out of gas by returning a very large\n // amount of data (and this is OK because we don't care about the returndata here).\n // 2. The amount of gas provided to the execution context of the target is at least the\n // gas limit specified by the user. If there is not enough gas in the current context\n // to accomplish this, `callWithMinGas` will revert.\n bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data);\n\n // Reset the l2Sender back to the default value.\n l2Sender = Constants.DEFAULT_L2_SENDER;\n\n // All withdrawals are immediately finalized. Replayability can\n // be achieved through contracts built on top of this contract\n emit WithdrawalFinalized(withdrawalHash, success);\n\n // Reverting here is useful for determining the exact gas cost to successfully execute the\n // sub call to the target contract if the minimum gas limit specified by the user would not\n // be sufficient to execute the sub call.\n if (success == false && tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"OptimismPortal: withdrawal failed\");\n }\n }\n\n /**\n * @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in\n * deriving deposit transactions. Note that if a deposit is made by a contract, its\n * address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider\n * using the CrossDomainMessenger contracts for a simpler developer experience.\n *\n * @param _to Target address on L2.\n * @param _value ETH value to send to the recipient.\n * @param _gasLimit Minimum L2 gas limit (can be greater than or equal to this value).\n * @param _isCreation Whether or not the transaction is a contract creation.\n * @param _data Data to trigger the recipient with.\n */\n function depositTransaction(\n address _to,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable metered(_gasLimit) {\n // Just to be safe, make sure that people specify address(0) as the target when doing\n // contract creations.\n if (_isCreation) {\n require(\n _to == address(0),\n \"OptimismPortal: must send to address(0) when creating a contract\"\n );\n }\n\n // Prevent depositing transactions that have too small of a gas limit. Users should pay\n // more for more resource usage.\n require(\n _gasLimit >= minimumGasLimit(uint64(_data.length)),\n \"OptimismPortal: gas limit too small\"\n );\n\n // Prevent the creation of deposit transactions that have too much calldata. This gives an\n // upper limit on the size of unsafe blocks over the p2p network. 120kb is chosen to ensure\n // that the transaction can fit into the p2p network policy of 128kb even though deposit\n // transactions are not gossipped over the p2p network.\n require(_data.length <= 120_000, \"OptimismPortal: data too large\");\n\n // Transform the from-address to its alias if the caller is a contract.\n address from = msg.sender;\n if (msg.sender != tx.origin) {\n from = AddressAliasHelper.applyL1ToL2Alias(msg.sender);\n }\n\n // Compute the opaque data that will be emitted as part of the TransactionDeposited event.\n // We use opaque data so that we can update the TransactionDeposited event in the future\n // without breaking the current interface.\n bytes memory opaqueData = abi.encodePacked(\n msg.value,\n _value,\n _gasLimit,\n _isCreation,\n _data\n );\n\n // Emit a TransactionDeposited event so that the rollup node can derive a deposit\n // transaction for this deposit.\n emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);\n }\n\n /**\n * @notice Determine if a given output is finalized. Reverts if the call to\n * L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\n *\n * @param _l2OutputIndex Index of the L2 output to check.\n *\n * @return Whether or not the output is finalized.\n */\n function isOutputFinalized(uint256 _l2OutputIndex) external view returns (bool) {\n return _isFinalizationPeriodElapsed(L2_ORACLE.getL2Output(_l2OutputIndex).timestamp);\n }\n\n /**\n * @notice Determines whether the finalization period has elapsed w/r/t a given timestamp.\n *\n * @param _timestamp Timestamp to check.\n *\n * @return Whether or not the finalization period has elapsed.\n */\n function _isFinalizationPeriodElapsed(uint256 _timestamp) internal view returns (bool) {\n return block.timestamp > _timestamp + L2_ORACLE.FINALIZATION_PERIOD_SECONDS();\n }\n}\n" - }, - "contracts/L1/ResourceMetering.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\n\n/**\n * @custom:upgradeable\n * @title ResourceMetering\n * @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing\n * updates automatically based on current demand.\n */\nabstract contract ResourceMetering is Initializable {\n /**\n * @notice Represents the various parameters that control the way in which resources are\n * metered. Corresponds to the EIP-1559 resource metering system.\n *\n * @custom:field prevBaseFee Base fee from the previous block(s).\n * @custom:field prevBoughtGas Amount of gas bought so far in the current block.\n * @custom:field prevBlockNum Last block number that the base fee was updated.\n */\n struct ResourceParams {\n uint128 prevBaseFee;\n uint64 prevBoughtGas;\n uint64 prevBlockNum;\n }\n\n /**\n * @notice Represents the configuration for the EIP-1559 based curve for the deposit gas\n * market. These values should be set with care as it is possible to set them in\n * a way that breaks the deposit gas market. The target resource limit is defined as\n * maxResourceLimit / elasticityMultiplier. This struct was designed to fit within a\n * single word. There is additional space for additions in the future.\n *\n * @custom:field maxResourceLimit Represents the maximum amount of deposit gas that\n * can be purchased per block.\n * @custom:field elasticityMultiplier Determines the target resource limit along with\n * the resource limit.\n * @custom:field baseFeeMaxChangeDenominator Determines max change on fee per block.\n * @custom:field minimumBaseFee The min deposit base fee, it is clamped to this\n * value.\n * @custom:field systemTxMaxGas The amount of gas supplied to the system\n * transaction. This should be set to the same number\n * that the op-node sets as the gas limit for the\n * system transaction.\n * @custom:field maximumBaseFee The max deposit base fee, it is clamped to this\n * value.\n */\n struct ResourceConfig {\n uint32 maxResourceLimit;\n uint8 elasticityMultiplier;\n uint8 baseFeeMaxChangeDenominator;\n uint32 minimumBaseFee;\n uint32 systemTxMaxGas;\n uint128 maximumBaseFee;\n }\n\n /**\n * @notice EIP-1559 style gas parameters.\n */\n ResourceParams public params;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[48] private __gap;\n\n /**\n * @notice Meters access to a function based an amount of a requested resource.\n *\n * @param _amount Amount of the resource requested.\n */\n modifier metered(uint64 _amount) {\n // Record initial gas amount so we can refund for it later.\n uint256 initialGas = gasleft();\n\n // Run the underlying function.\n _;\n\n // Run the metering function.\n _metered(_amount, initialGas);\n }\n\n /**\n * @notice An internal function that holds all of the logic for metering a resource.\n *\n * @param _amount Amount of the resource requested.\n * @param _initialGas The amount of gas before any modifier execution.\n */\n function _metered(uint64 _amount, uint256 _initialGas) internal {\n // Update block number and base fee if necessary.\n uint256 blockDiff = block.number - params.prevBlockNum;\n\n ResourceConfig memory config = _resourceConfig();\n int256 targetResourceLimit = int256(uint256(config.maxResourceLimit)) /\n int256(uint256(config.elasticityMultiplier));\n\n if (blockDiff > 0) {\n // Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate\n // at which deposits can be created and therefore limit the potential for deposits to\n // spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.\n int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit;\n int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) /\n (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));\n\n // Update base fee by adding the base fee delta and clamp the resulting value between\n // min and max.\n int256 newBaseFee = Arithmetic.clamp({\n _value: int256(uint256(params.prevBaseFee)) + baseFeeDelta,\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n\n // If we skipped more than one block, we also need to account for every empty block.\n // Empty block means there was no demand for deposits in that block, so we should\n // reflect this lack of demand in the fee.\n if (blockDiff > 1) {\n // Update the base fee by repeatedly applying the exponent 1-(1/change_denominator)\n // blockDiff - 1 times. Simulates multiple empty blocks. Clamp the resulting value\n // between min and max.\n newBaseFee = Arithmetic.clamp({\n _value: Arithmetic.cdexp({\n _coefficient: newBaseFee,\n _denominator: int256(uint256(config.baseFeeMaxChangeDenominator)),\n _exponent: int256(blockDiff - 1)\n }),\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n }\n\n // Update new base fee, reset bought gas, and update block number.\n params.prevBaseFee = uint128(uint256(newBaseFee));\n params.prevBoughtGas = 0;\n params.prevBlockNum = uint64(block.number);\n }\n\n // Make sure we can actually buy the resource amount requested by the user.\n params.prevBoughtGas += _amount;\n require(\n int256(uint256(params.prevBoughtGas)) <= int256(uint256(config.maxResourceLimit)),\n \"ResourceMetering: cannot buy more gas than available gas limit\"\n );\n\n // Determine the amount of ETH to be paid.\n uint256 resourceCost = uint256(_amount) * uint256(params.prevBaseFee);\n\n // We currently charge for this ETH amount as an L1 gas burn, so we convert the ETH amount\n // into gas by dividing by the L1 base fee. We assume a minimum base fee of 1 gwei to avoid\n // division by zero for L1s that don't support 1559 or to avoid excessive gas burns during\n // periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei\n // during any 1 day period in the last 5 years, so should be fine.\n uint256 gasCost = resourceCost / Math.max(block.basefee, 1 gwei);\n\n // Give the user a refund based on the amount of gas they used to do all of the work up to\n // this point. Since we're at the end of the modifier, this should be pretty accurate. Acts\n // effectively like a dynamic stipend (with a minimum value).\n uint256 usedGas = _initialGas - gasleft();\n if (gasCost > usedGas) {\n Burn.gas(gasCost - usedGas);\n }\n }\n\n /**\n * @notice Virtual function that returns the resource config. Contracts that inherit this\n * contract must implement this function.\n *\n * @return ResourceConfig\n */\n function _resourceConfig() internal virtual returns (ResourceConfig memory);\n\n /**\n * @notice Sets initial resource parameter values. This function must either be called by the\n * initializer function of an upgradeable child contract.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __ResourceMetering_init() internal onlyInitializing {\n params = ResourceParams({\n prevBaseFee: 1 gwei,\n prevBoughtGas: 0,\n prevBlockNum: uint64(block.number)\n });\n }\n}\n" - }, - "contracts/L1/SystemConfig.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\n\n/**\n * @title SystemConfig\n * @notice The SystemConfig contract is used to manage configuration of an Optimism network. All\n * configuration is stored on L1 and picked up by L2 as part of the derviation of the L2\n * chain.\n */\ncontract SystemConfig is OwnableUpgradeable, Semver {\n /**\n * @notice Enum representing different types of updates.\n *\n * @custom:value BATCHER Represents an update to the batcher hash.\n * @custom:value GAS_CONFIG Represents an update to txn fee config on L2.\n * @custom:value GAS_LIMIT Represents an update to gas limit on L2.\n * @custom:value UNSAFE_BLOCK_SIGNER Represents an update to the signer key for unsafe\n * block distrubution.\n */\n enum UpdateType {\n BATCHER,\n GAS_CONFIG,\n GAS_LIMIT,\n UNSAFE_BLOCK_SIGNER\n }\n\n /**\n * @notice Version identifier, used for upgrades.\n */\n uint256 public constant VERSION = 0;\n\n /**\n * @notice Storage slot that the unsafe block signer is stored at. Storing it at this\n * deterministic storage slot allows for decoupling the storage layout from the way\n * that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value.\n */\n bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256(\"systemconfig.unsafeblocksigner\");\n\n /**\n * @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public overhead;\n\n /**\n * @notice Dynamic L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public scalar;\n\n /**\n * @notice Identifier for the batcher. For version 1 of this configuration, this is represented\n * as an address left-padded with zeros to 32 bytes.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice L2 block gas limit.\n */\n uint64 public gasLimit;\n\n /**\n * @notice The configuration for the deposit fee market. Used by the OptimismPortal\n * to meter the cost of buying L2 gas on L1. Set as internal and wrapped with a getter\n * so that the struct is returned instead of a tuple.\n */\n ResourceMetering.ResourceConfig internal _resourceConfig;\n\n /**\n * @notice Emitted when configuration is updated\n *\n * @param version SystemConfig version.\n * @param updateType Type of update.\n * @param data Encoded update data.\n */\n event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);\n\n /**\n * @custom:semver 1.3.0\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial resource config.\n */\n constructor(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) Semver(1, 3, 0) {\n initialize({\n _owner: _owner,\n _overhead: _overhead,\n _scalar: _scalar,\n _batcherHash: _batcherHash,\n _gasLimit: _gasLimit,\n _unsafeBlockSigner: _unsafeBlockSigner,\n _config: _config\n });\n }\n\n /**\n * @notice Initializer. The resource config must be set before the\n * require check.\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial ResourceConfig.\n */\n function initialize(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) public initializer {\n __Ownable_init();\n transferOwnership(_owner);\n overhead = _overhead;\n scalar = _scalar;\n batcherHash = _batcherHash;\n gasLimit = _gasLimit;\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n _setResourceConfig(_config);\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n }\n\n /**\n * @notice Returns the minimum L2 gas limit that can be safely set for the system to\n * operate. The L2 gas limit must be larger than or equal to the amount of\n * gas that is allocated for deposits per block plus the amount of gas that\n * is allocated for the system transaction.\n * This function is used to determine if changes to parameters are safe.\n *\n * @return uint64\n */\n function minimumGasLimit() public view returns (uint64) {\n return uint64(_resourceConfig.maxResourceLimit) + uint64(_resourceConfig.systemTxMaxGas);\n }\n\n /**\n * @notice High level getter for the unsafe block signer address. Unsafe blocks can be\n * propagated across the p2p network if they are signed by the key corresponding to\n * this address.\n *\n * @return Address of the unsafe block signer.\n */\n // solhint-disable-next-line ordering\n function unsafeBlockSigner() external view returns (address) {\n address addr;\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n addr := sload(slot)\n }\n return addr;\n }\n\n /**\n * @notice Updates the unsafe block signer address.\n *\n * @param _unsafeBlockSigner New unsafe block signer address.\n */\n function setUnsafeBlockSigner(address _unsafeBlockSigner) external onlyOwner {\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n\n bytes memory data = abi.encode(_unsafeBlockSigner);\n emit ConfigUpdate(VERSION, UpdateType.UNSAFE_BLOCK_SIGNER, data);\n }\n\n /**\n * @notice Updates the batcher hash.\n *\n * @param _batcherHash New batcher hash.\n */\n function setBatcherHash(bytes32 _batcherHash) external onlyOwner {\n batcherHash = _batcherHash;\n\n bytes memory data = abi.encode(_batcherHash);\n emit ConfigUpdate(VERSION, UpdateType.BATCHER, data);\n }\n\n /**\n * @notice Updates gas config.\n *\n * @param _overhead New overhead value.\n * @param _scalar New scalar value.\n */\n function setGasConfig(uint256 _overhead, uint256 _scalar) external onlyOwner {\n overhead = _overhead;\n scalar = _scalar;\n\n bytes memory data = abi.encode(_overhead, _scalar);\n emit ConfigUpdate(VERSION, UpdateType.GAS_CONFIG, data);\n }\n\n /**\n * @notice Updates the L2 gas limit.\n *\n * @param _gasLimit New gas limit.\n */\n function setGasLimit(uint64 _gasLimit) external onlyOwner {\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n gasLimit = _gasLimit;\n\n bytes memory data = abi.encode(_gasLimit);\n emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data);\n }\n\n /**\n * @notice Low level setter for the unsafe block signer address. This function exists to\n * deduplicate code around storing the unsafeBlockSigner address in storage.\n *\n * @param _unsafeBlockSigner New unsafeBlockSigner value.\n */\n function _setUnsafeBlockSigner(address _unsafeBlockSigner) internal {\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n sstore(slot, _unsafeBlockSigner)\n }\n }\n\n /**\n * @notice A getter for the resource config. Ensures that the struct is\n * returned instead of a tuple.\n *\n * @return ResourceConfig\n */\n function resourceConfig() external view returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig;\n }\n\n /**\n * @notice An external setter for the resource config. In the future, this\n * method may emit an event that the `op-node` picks up for when the\n * resource config is changed.\n *\n * @param _config The new resource config values.\n */\n function setResourceConfig(ResourceMetering.ResourceConfig memory _config) external onlyOwner {\n _setResourceConfig(_config);\n }\n\n /**\n * @notice An internal setter for the resource config. Ensures that the\n * config is sane before storing it by checking for invariants.\n *\n * @param _config The new resource config.\n */\n function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal {\n // Min base fee must be less than or equal to max base fee.\n require(\n _config.minimumBaseFee <= _config.maximumBaseFee,\n \"SystemConfig: min base fee must be less than max base\"\n );\n // Base fee change denominator must be greater than 1.\n require(\n _config.baseFeeMaxChangeDenominator > 1,\n \"SystemConfig: denominator must be larger than 1\"\n );\n // Max resource limit plus system tx gas must be less than or equal to the L2 gas limit.\n // The gas limit must be increased before these values can be increased.\n require(\n _config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit,\n \"SystemConfig: gas limit too low\"\n );\n // Elasticity multiplier must be greater than 0.\n require(\n _config.elasticityMultiplier > 0,\n \"SystemConfig: elasticity multiplier cannot be 0\"\n );\n // No precision loss when computing target resource limit.\n require(\n ((_config.maxResourceLimit / _config.elasticityMultiplier) *\n _config.elasticityMultiplier) == _config.maxResourceLimit,\n \"SystemConfig: precision loss with target resource limit\"\n );\n\n _resourceConfig = _config;\n }\n}\n" - }, - "contracts/L2/BaseFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000019\n * @title BaseFeeVault\n * @notice The BaseFeeVault accumulates the base fee that is paid by transactions.\n */\ncontract BaseFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n}\n" - }, - "contracts/L2/CrossDomainOwnable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\n/**\n * @title CrossDomainOwnable\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is only safe to be used if the\n * CrossDomainMessenger system is bypassed and the caller on L1 is calling the\n * OptimismPortal directly.\n */\nabstract contract CrossDomainOwnable is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `msg.sender` is the owner of the contract.\n */\n function _checkOwner() internal view override {\n require(\n owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender),\n \"CrossDomainOwnable: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable2\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is meant to be used with systems that use\n * the CrossDomainMessenger system. It will not work if the OptimismPortal is used\n * directly.\n */\nabstract contract CrossDomainOwnable2 is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable2: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable2: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable3\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on either L1 or L2. Note that this contract is meant to be used with systems\n * that use the CrossDomainMessenger system. It will not work if the OptimismPortal is\n * used directly.\n */\nabstract contract CrossDomainOwnable3 is Ownable {\n /**\n * @notice If true, the contract uses the cross domain _checkOwner function override. If false\n * it uses the standard Ownable _checkOwner function.\n */\n bool public isLocal = true;\n\n /**\n * @notice Emits when ownership of the contract is transferred. Includes the\n * isLocal field in addition to the standard `Ownable` OwnershipTransferred event.\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n /**\n * @notice Allows for ownership to be transferred with specifying the locality.\n * @param _owner The new owner of the contract.\n * @param _isLocal Configures the locality of the ownership.\n */\n function transferOwnership(address _owner, bool _isLocal) external onlyOwner {\n require(_owner != address(0), \"CrossDomainOwnable3: new owner is the zero address\");\n\n address oldOwner = owner();\n _transferOwnership(_owner);\n isLocal = _isLocal;\n\n emit OwnershipTransferred(oldOwner, _owner, _isLocal);\n }\n\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n if (isLocal) {\n require(owner() == msg.sender, \"CrossDomainOwnable3: caller is not the owner\");\n } else {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable3: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable3: caller is not the owner\"\n );\n }\n }\n}\n" - }, - "contracts/L2/GasPriceOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000000F\n * @title GasPriceOracle\n * @notice This contract maintains the variables responsible for computing the L1 portion of the\n * total fee charged on L2. Before Bedrock, this contract held variables in state that were\n * read during the state transition function to compute the L1 portion of the transaction\n * fee. After Bedrock, this contract now simply proxies the L1Block contract, which has\n * the values used to compute the L1 portion of the fee in its state.\n *\n * The contract exposes an API that is useful for knowing how large the L1 portion of the\n * transaction fee will be. The following events were deprecated with Bedrock:\n * - event OverheadUpdated(uint256 overhead);\n * - event ScalarUpdated(uint256 scalar);\n * - event DecimalsUpdated(uint256 decimals);\n */\ncontract GasPriceOracle is Semver {\n /**\n * @notice Number of decimals used in the scalar.\n */\n uint256 public constant DECIMALS = 6;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Computes the L1 portion of the fee based on the size of the rlp encoded input\n * transaction, the current L1 base fee, and the various dynamic parameters.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.\n *\n * @return L1 fee that should be paid for the tx\n */\n function getL1Fee(bytes memory _data) external view returns (uint256) {\n uint256 l1GasUsed = getL1GasUsed(_data);\n uint256 l1Fee = l1GasUsed * l1BaseFee();\n uint256 divisor = 10**DECIMALS;\n uint256 unscaled = l1Fee * scalar();\n uint256 scaled = unscaled / divisor;\n return scaled;\n }\n\n /**\n * @notice Retrieves the current gas price (base fee).\n *\n * @return Current L2 gas price (base fee).\n */\n function gasPrice() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current base fee.\n *\n * @return Current L2 base fee.\n */\n function baseFee() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current fee overhead.\n *\n * @return Current fee overhead.\n */\n function overhead() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead();\n }\n\n /**\n * @notice Retrieves the current fee scalar.\n *\n * @return Current fee scalar.\n */\n function scalar() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar();\n }\n\n /**\n * @notice Retrieves the latest known L1 base fee.\n *\n * @return Latest known L1 base fee.\n */\n function l1BaseFee() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee();\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the number of decimals used in the scalar.\n *\n * @return Number of decimals used in the scalar.\n */\n function decimals() public pure returns (uint256) {\n return DECIMALS;\n }\n\n /**\n * @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which\n * represents the per-transaction gas overhead of posting the transaction and state\n * roots to L1. Adds 68 bytes of padding to account for the fact that the input does\n * not have a signature.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for.\n *\n * @return Amount of L1 gas used to publish the transaction.\n */\n function getL1GasUsed(bytes memory _data) public view returns (uint256) {\n uint256 total = 0;\n uint256 length = _data.length;\n for (uint256 i = 0; i < length; i++) {\n if (_data[i] == 0) {\n total += 4;\n } else {\n total += 16;\n }\n }\n uint256 unsigned = total + overhead();\n return unsigned + (68 * 16);\n }\n}\n" - }, - "contracts/L2/L1Block.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000015\n * @title L1Block\n * @notice The L1Block predeploy gives users access to information about the last known L1 block.\n * Values within this contract are updated once per epoch (every L1 block) and can only be\n * set by the \"depositor\" account, a special system address. Depositor account transactions\n * are created by the protocol whenever we move to a new epoch.\n */\ncontract L1Block is Semver {\n /**\n * @notice Address of the special depositor account.\n */\n address public constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001;\n\n /**\n * @notice The latest L1 block number known by the L2 system.\n */\n uint64 public number;\n\n /**\n * @notice The latest L1 timestamp known by the L2 system.\n */\n uint64 public timestamp;\n\n /**\n * @notice The latest L1 basefee.\n */\n uint256 public basefee;\n\n /**\n * @notice The latest L1 blockhash.\n */\n bytes32 public hash;\n\n /**\n * @notice The number of L2 blocks in the same epoch.\n */\n uint64 public sequenceNumber;\n\n /**\n * @notice The versioned hash to authenticate the batcher by.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice The overhead value applied to the L1 portion of the transaction\n * fee.\n */\n uint256 public l1FeeOverhead;\n\n /**\n * @notice The scalar value applied to the L1 portion of the transaction fee.\n */\n uint256 public l1FeeScalar;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Updates the L1 block values.\n *\n * @param _number L1 blocknumber.\n * @param _timestamp L1 timestamp.\n * @param _basefee L1 basefee.\n * @param _hash L1 blockhash.\n * @param _sequenceNumber Number of L2 blocks since epoch start.\n * @param _batcherHash Versioned hash to authenticate batcher by.\n * @param _l1FeeOverhead L1 fee overhead.\n * @param _l1FeeScalar L1 fee scalar.\n */\n function setL1BlockValues(\n uint64 _number,\n uint64 _timestamp,\n uint256 _basefee,\n bytes32 _hash,\n uint64 _sequenceNumber,\n bytes32 _batcherHash,\n uint256 _l1FeeOverhead,\n uint256 _l1FeeScalar\n ) external {\n require(\n msg.sender == DEPOSITOR_ACCOUNT,\n \"L1Block: only the depositor account can set L1 block values\"\n );\n\n number = _number;\n timestamp = _timestamp;\n basefee = _basefee;\n hash = _hash;\n sequenceNumber = _sequenceNumber;\n batcherHash = _batcherHash;\n l1FeeOverhead = _l1FeeOverhead;\n l1FeeScalar = _l1FeeScalar;\n }\n}\n" - }, - "contracts/L2/L1FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000001A\n * @title L1FeeVault\n * @notice The L1FeeVault accumulates the L1 portion of the transaction fees.\n */\ncontract L1FeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n}\n" - }, - "contracts/L2/L2CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { L2ToL1MessagePasser } from \"./L2ToL1MessagePasser.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000007\n * @title L2CrossDomainMessenger\n * @notice The L2CrossDomainMessenger is a high-level interface for message passing between L1 and\n * L2 on the L2 side. Users are generally encouraged to use this contract instead of lower\n * level message passing contracts.\n */\ncontract L2CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @custom:semver 1.4.0\n *\n * @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.\n */\n constructor(address _l1CrossDomainMessenger)\n Semver(1, 4, 0)\n CrossDomainMessenger(_l1CrossDomainMessenger)\n {\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote messenger. Use otherMessenger going forward.\n *\n * @return Address of the L1CrossDomainMessenger contract.\n */\n function l1CrossDomainMessenger() public view returns (address) {\n return OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{\n value: _value\n }(_to, _gasLimit, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(Predeploys.L2_TO_L1_MESSAGE_PASSER);\n }\n}\n" - }, - "contracts/L2/L2ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { IOptimismMintableERC721 } from \"../universal/IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L2ERC721Bridge\n * @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.\n * This contract also acts as a burner for tokens being withdrawn.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n */\ncontract L2ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L1. Data supplied here will not be used to\n * execute any code on L1 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L2ERC721Bridge: local token cannot be self\");\n\n // Note that supportsInterface makes a callback to the _localToken address which is user\n // provided.\n require(\n ERC165Checker.supportsInterface(_localToken, type(IOptimismMintableERC721).interfaceId),\n \"L2ERC721Bridge: local token interface is not compliant\"\n );\n\n require(\n _remoteToken == IOptimismMintableERC721(_localToken).remoteToken(),\n \"L2ERC721Bridge: wrong remote token for Optimism Mintable ERC721 local token\"\n );\n\n // When a deposit is finalized, we give the NFT with the same tokenId to the account\n // on L2. Note that safeMint makes a callback to the _to address which is user provided.\n IOptimismMintableERC721(_localToken).safeMint(_to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L2ERC721Bridge: remote token cannot be address(0)\");\n\n // Check that the withdrawal is being initiated by the NFT owner\n require(\n _from == IOptimismMintableERC721(_localToken).ownerOf(_tokenId),\n \"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\"\n );\n\n // Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)\n // slither-disable-next-line reentrancy-events\n address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();\n require(\n remoteToken == _remoteToken,\n \"L2ERC721Bridge: remote token does not match given value\"\n );\n\n // When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2\n // usage\n // slither-disable-next-line reentrancy-events\n IOptimismMintableERC721(_localToken).burn(_from, _tokenId);\n\n bytes memory message = abi.encodeWithSelector(\n L1ERC721Bridge.finalizeBridgeERC721.selector,\n remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Send message to L1 bridge\n // slither-disable-next-line reentrancy-events\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L2/L2StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000010\n * @title L2StandardBridge\n * @notice The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L2, it will be escrowed within this\n * contract. If the ERC20 token is native to L1, it will be burnt.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L2StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal from L2 to L1 is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _otherBridge Address of the L1StandardBridge.\n */\n constructor(address payable _otherBridge)\n Semver(1, 1, 0)\n StandardBridge(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER), _otherBridge)\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateWithdrawal(\n Predeploys.LEGACY_ERC20_ETH,\n msg.sender,\n msg.sender,\n msg.value,\n RECEIVE_DEFAULT_GAS_LIMIT,\n bytes(\"\")\n );\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdraw(\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual onlyEOA {\n _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1 to a target account on L1.\n * Note that if ETH is sent to a contract on L1 and the call fails, then that ETH will\n * be locked in the L1StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20To` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdrawTo(\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual {\n _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a deposit from L1 to L2. To finalize a deposit of ether, use address(0)\n * and the l1Token and the Legacy ERC20 ether predeploy address as the l2Token.\n *\n * @param _l1Token Address of the L1 token to deposit.\n * @param _l2Token Address of the corresponding L2 token.\n * @param _from Address of the depositor.\n * @param _to Address of the recipient.\n * @param _amount Amount of the tokens being deposited.\n * @param _extraData Extra data attached to the deposit.\n */\n function finalizeDeposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable virtual {\n if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n } else {\n finalizeBridgeERC20(_l2Token, _l1Token, _from, _to, _amount, _extraData);\n }\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L1 bridge contract.\n *\n * @return Address of the corresponding L1 bridge contract.\n */\n function l1TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @custom:legacy\n * @notice Internal function to a withdrawal from L2 to L1 to a target account on L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _from Address of the withdrawer.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function _initiateWithdrawal(\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {\n _initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);\n } else {\n address l1Token = OptimismMintableERC20(_l2Token).l1Token();\n _initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ETHBridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ERC20BridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L2/L2ToL1MessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000016\n * @title L2ToL1MessagePasser\n * @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from\n * L2 to L1 can be stored. The storage root of this contract is pulled up to the top level\n * of the L2 output to reduce the cost of proving the existence of sent messages.\n */\ncontract L2ToL1MessagePasser is Semver {\n /**\n * @notice The L1 gas limit set when eth is withdrawn using the receive() function.\n */\n uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Includes the message hashes for all withdrawals\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @notice A unique value hashed with each withdrawal.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Emitted any time a withdrawal is initiated.\n *\n * @param nonce Unique value corresponding to each withdrawal.\n * @param sender The L2 account address which initiated the withdrawal.\n * @param target The L1 account address the call will be send to.\n * @param value The ETH value submitted for withdrawal, to be forwarded to the target.\n * @param gasLimit The minimum amount of gas that must be provided when withdrawing.\n * @param data The data to be forwarded to the target on L1.\n * @param withdrawalHash The hash of the withdrawal.\n */\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n /**\n * @notice Emitted when the balance of this contract is burned.\n *\n * @param amount Amount of ETh that was burned.\n */\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Allows users to withdraw ETH by sending directly to this contract.\n */\n receive() external payable {\n initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @notice Removes all ETH held by this contract from the state. Used to prevent the amount of\n * ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to\n * create a contract and self-destruct it to itself. Anyone can call this function. Not\n * incentivized since this function is very cheap.\n */\n function burn() external {\n uint256 balance = address(this).balance;\n Burn.eth(balance);\n emit WithdrawerBalanceBurnt(balance);\n }\n\n /**\n * @notice Sends a message from L2 to L1.\n *\n * @param _target Address to call on L1 execution.\n * @param _gasLimit Minimum gas limit for executing the message on L1.\n * @param _data Data to forward to L1 target.\n */\n function initiateWithdrawal(\n address _target,\n uint256 _gasLimit,\n bytes memory _data\n ) public payable {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messageNonce(),\n sender: msg.sender,\n target: _target,\n value: msg.value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n sentMessages[withdrawalHash] = true;\n\n emit MessagePassed(\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _gasLimit,\n _data,\n withdrawalHash\n );\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n}\n" - }, - "contracts/L2/SequencerFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000011\n * @title SequencerFeeVault\n * @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during\n * transaction processing and block production.\n */\ncontract SequencerFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the recipient address.\n *\n * @return The recipient address.\n */\n function l1FeeWallet() public view returns (address) {\n return RECIPIENT;\n }\n}\n" - }, - "contracts/deployment/PortalSender.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/**\n * @title PortalSender\n * @notice The PortalSender is a simple intermediate contract that will transfer the balance of the\n * L1StandardBridge to the OptimismPortal during the Bedrock migration.\n */\ncontract PortalSender {\n /**\n * @notice Address of the OptimismPortal contract.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @param _portal Address of the OptimismPortal contract.\n */\n constructor(OptimismPortal _portal) {\n PORTAL = _portal;\n }\n\n /**\n * @notice Sends balance of this contract to the OptimismPortal.\n */\n function donate() public {\n PORTAL.donateETH{ value: address(this).balance }();\n }\n}\n" - }, - "contracts/deployment/SystemDictator.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { PortalSender } from \"./PortalSender.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @title SystemDictator\n * @notice The SystemDictator is responsible for coordinating the deployment of a full Bedrock\n * system. The SystemDictator is designed to support both fresh network deployments and\n * upgrades to existing pre-Bedrock systems.\n */\ncontract SystemDictator is OwnableUpgradeable {\n /**\n * @notice Basic system configuration.\n */\n struct GlobalConfig {\n AddressManager addressManager;\n ProxyAdmin proxyAdmin;\n address controller;\n address finalOwner;\n }\n\n /**\n * @notice Set of proxy addresses.\n */\n struct ProxyAddressConfig {\n address l2OutputOracleProxy;\n address optimismPortalProxy;\n address l1CrossDomainMessengerProxy;\n address l1StandardBridgeProxy;\n address optimismMintableERC20FactoryProxy;\n address l1ERC721BridgeProxy;\n address systemConfigProxy;\n }\n\n /**\n * @notice Set of implementation addresses.\n */\n struct ImplementationAddressConfig {\n L2OutputOracle l2OutputOracleImpl;\n OptimismPortal optimismPortalImpl;\n L1CrossDomainMessenger l1CrossDomainMessengerImpl;\n L1StandardBridge l1StandardBridgeImpl;\n OptimismMintableERC20Factory optimismMintableERC20FactoryImpl;\n L1ERC721Bridge l1ERC721BridgeImpl;\n PortalSender portalSenderImpl;\n SystemConfig systemConfigImpl;\n }\n\n /**\n * @notice Dynamic L2OutputOracle config.\n */\n struct L2OutputOracleDynamicConfig {\n uint256 l2OutputOracleStartingBlockNumber;\n uint256 l2OutputOracleStartingTimestamp;\n }\n\n /**\n * @notice Values for the system config contract.\n */\n struct SystemConfigConfig {\n address owner;\n uint256 overhead;\n uint256 scalar;\n bytes32 batcherHash;\n uint64 gasLimit;\n address unsafeBlockSigner;\n ResourceMetering.ResourceConfig resourceConfig;\n }\n\n /**\n * @notice Combined system configuration.\n */\n struct DeployConfig {\n GlobalConfig globalConfig;\n ProxyAddressConfig proxyAddressConfig;\n ImplementationAddressConfig implementationAddressConfig;\n SystemConfigConfig systemConfigConfig;\n }\n\n /**\n * @notice Step after which exit 1 can no longer be used.\n */\n uint8 public constant EXIT_1_NO_RETURN_STEP = 3;\n\n /**\n * @notice Step where proxy ownership is transferred.\n */\n uint8 public constant PROXY_TRANSFER_STEP = 4;\n\n /**\n * @notice System configuration.\n */\n DeployConfig public config;\n\n /**\n * @notice Dynamic configuration for the L2OutputOracle.\n */\n L2OutputOracleDynamicConfig public l2OutputOracleDynamicConfig;\n\n /**\n * @notice Dynamic configuration for the OptimismPortal. Determines\n * if the system should be paused when initialized.\n */\n bool public optimismPortalDynamicConfig;\n\n /**\n * @notice Current step;\n */\n uint8 public currentStep;\n\n /**\n * @notice Whether or not dynamic config has been set.\n */\n bool public dynamicConfigSet;\n\n /**\n * @notice Whether or not the deployment is finalized.\n */\n bool public finalized;\n\n /**\n * @notice Whether or not the deployment has been exited.\n */\n bool public exited;\n\n /**\n * @notice Address of the old L1CrossDomainMessenger implementation.\n */\n address public oldL1CrossDomainMessenger;\n\n /**\n * @notice Checks that the current step is the expected step, then bumps the current step.\n *\n * @param _step Current step.\n */\n modifier step(uint8 _step) {\n require(!finalized, \"SystemDictator: already finalized\");\n require(!exited, \"SystemDictator: already exited\");\n require(currentStep == _step, \"SystemDictator: incorrect step\");\n _;\n currentStep++;\n }\n\n /**\n * @notice Constructor required to ensure that the implementation of the SystemDictator is\n * initialized upon deployment.\n */\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n // Using this shorter variable as an alias for address(0) just prevents us from having to\n // to use a new line for every single parameter.\n address zero = address(0);\n initialize(\n DeployConfig(\n GlobalConfig(AddressManager(zero), ProxyAdmin(zero), zero, zero),\n ProxyAddressConfig(zero, zero, zero, zero, zero, zero, zero),\n ImplementationAddressConfig(\n L2OutputOracle(zero),\n OptimismPortal(payable(zero)),\n L1CrossDomainMessenger(zero),\n L1StandardBridge(payable(zero)),\n OptimismMintableERC20Factory(zero),\n L1ERC721Bridge(zero),\n PortalSender(zero),\n SystemConfig(zero)\n ),\n SystemConfigConfig(zero, 0, 0, bytes32(0), 0, zero, rcfg)\n )\n );\n }\n\n /**\n * @param _config System configuration.\n */\n function initialize(DeployConfig memory _config) public initializer {\n config = _config;\n currentStep = 1;\n __Ownable_init();\n _transferOwnership(config.globalConfig.controller);\n }\n\n /**\n * @notice Allows the owner to update dynamic config.\n *\n * @param _l2OutputOracleDynamicConfig Dynamic L2OutputOracle config.\n * @param _optimismPortalDynamicConfig Dynamic OptimismPortal config.\n */\n function updateDynamicConfig(\n L2OutputOracleDynamicConfig memory _l2OutputOracleDynamicConfig,\n bool _optimismPortalDynamicConfig\n ) external onlyOwner {\n l2OutputOracleDynamicConfig = _l2OutputOracleDynamicConfig;\n optimismPortalDynamicConfig = _optimismPortalDynamicConfig;\n dynamicConfigSet = true;\n }\n\n /**\n * @notice Configures the ProxyAdmin contract.\n */\n function step1() public onlyOwner step(1) {\n // Set the AddressManager in the ProxyAdmin.\n config.globalConfig.proxyAdmin.setAddressManager(config.globalConfig.addressManager);\n\n // Set the L1CrossDomainMessenger to the RESOLVED proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n ProxyAdmin.ProxyType.RESOLVED\n );\n\n // Set the implementation name for the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.setImplementationName(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Set the L1StandardBridge to the CHUGSPLASH proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1StandardBridgeProxy,\n ProxyAdmin.ProxyType.CHUGSPLASH\n );\n\n // Upgrade and initialize the SystemConfig so the Sequencer can start up.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.systemConfigProxy),\n address(config.implementationAddressConfig.systemConfigImpl),\n abi.encodeCall(\n SystemConfig.initialize,\n (\n config.systemConfigConfig.owner,\n config.systemConfigConfig.overhead,\n config.systemConfigConfig.scalar,\n config.systemConfigConfig.batcherHash,\n config.systemConfigConfig.gasLimit,\n config.systemConfigConfig.unsafeBlockSigner,\n config.systemConfigConfig.resourceConfig\n )\n )\n );\n }\n\n /**\n * @notice Pauses the system by shutting down the L1CrossDomainMessenger and setting the\n * deposit halt flag to tell the Sequencer's DTL to stop accepting deposits.\n */\n function step2() public onlyOwner step(2) {\n // Store the address of the old L1CrossDomainMessenger implementation. We will need this\n // address in the case that we have to exit early.\n oldL1CrossDomainMessenger = config.globalConfig.addressManager.getAddress(\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Temporarily brick the L1CrossDomainMessenger by setting its implementation address to\n // address(0) which will cause the ResolvedDelegateProxy to revert. Better than pausing\n // the L1CrossDomainMessenger via pause() because it can be easily reverted.\n config.globalConfig.addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(0));\n\n // Set the DTL shutoff block, which will tell the DTL to stop syncing new deposits from the\n // CanonicalTransactionChain. We do this by setting an address in the AddressManager\n // because the DTL already has a reference to the AddressManager and this way we don't also\n // need to give it a reference to the SystemDictator.\n config.globalConfig.addressManager.setAddress(\n \"DTL_SHUTOFF_BLOCK\",\n address(uint160(block.number))\n );\n }\n\n /**\n * @notice Removes deprecated addresses from the AddressManager.\n */\n function step3() public onlyOwner step(EXIT_1_NO_RETURN_STEP) {\n // Remove all deprecated addresses from the AddressManager\n string[17] memory deprecated = [\n \"OVM_CanonicalTransactionChain\",\n \"OVM_L2CrossDomainMessenger\",\n \"OVM_DecompressionPrecompileAddress\",\n \"OVM_Sequencer\",\n \"OVM_Proposer\",\n \"OVM_ChainStorageContainer-CTC-batches\",\n \"OVM_ChainStorageContainer-CTC-queue\",\n \"OVM_CanonicalTransactionChain\",\n \"OVM_StateCommitmentChain\",\n \"OVM_BondManager\",\n \"OVM_ExecutionManager\",\n \"OVM_FraudVerifier\",\n \"OVM_StateManagerFactory\",\n \"OVM_StateTransitionerFactory\",\n \"OVM_SafetyChecker\",\n \"OVM_L1MultiMessageRelayer\",\n \"BondManager\"\n ];\n\n for (uint256 i = 0; i < deprecated.length; i++) {\n config.globalConfig.addressManager.setAddress(deprecated[i], address(0));\n }\n }\n\n /**\n * @notice Transfers system ownership to the ProxyAdmin.\n */\n function step4() public onlyOwner step(PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the ProxyAdmin.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1StandardBridge to the ProxyAdmin.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the ProxyAdmin.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.proxyAdmin)\n );\n }\n\n /**\n * @notice Upgrades and initializes proxy contracts.\n */\n function step5() public onlyOwner step(5) {\n // Dynamic config must be set before we can initialize the L2OutputOracle.\n require(dynamicConfigSet, \"SystemDictator: dynamic oracle config is not yet initialized\");\n\n // Upgrade and initialize the L2OutputOracle.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l2OutputOracleProxy),\n address(config.implementationAddressConfig.l2OutputOracleImpl),\n abi.encodeCall(\n L2OutputOracle.initialize,\n (\n l2OutputOracleDynamicConfig.l2OutputOracleStartingBlockNumber,\n l2OutputOracleDynamicConfig.l2OutputOracleStartingTimestamp\n )\n )\n );\n\n // Upgrade and initialize the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.optimismPortalProxy),\n address(config.implementationAddressConfig.optimismPortalImpl),\n abi.encodeCall(OptimismPortal.initialize, (optimismPortalDynamicConfig))\n );\n\n // Upgrade the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1CrossDomainMessengerProxy),\n address(config.implementationAddressConfig.l1CrossDomainMessengerImpl)\n );\n\n // Try to initialize the L1CrossDomainMessenger, only fail if it's already been initialized.\n try\n L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy)\n .initialize()\n {\n // L1CrossDomainMessenger is the one annoying edge case difference between existing\n // networks and fresh networks because in existing networks it'll already be\n // initialized but in fresh networks it won't be. Try/catch is the easiest and most\n // consistent way to handle this because initialized() is not exposed publicly.\n } catch Error(string memory reason) {\n require(\n keccak256(abi.encodePacked(reason)) ==\n keccak256(\"Initializable: contract is already initialized\"),\n string.concat(\"SystemDictator: unexpected error initializing L1XDM: \", reason)\n );\n } catch {\n revert(\"SystemDictator: unexpected error initializing L1XDM (no reason)\");\n }\n\n // Transfer ETH from the L1StandardBridge to the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.portalSenderImpl),\n abi.encodeCall(PortalSender.donate, ())\n );\n\n // Upgrade the L1StandardBridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.l1StandardBridgeImpl)\n );\n\n // Upgrade the OptimismMintableERC20Factory (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.optimismMintableERC20FactoryProxy),\n address(config.implementationAddressConfig.optimismMintableERC20FactoryImpl)\n );\n\n // Upgrade the L1ERC721Bridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1ERC721BridgeProxy),\n address(config.implementationAddressConfig.l1ERC721BridgeImpl)\n );\n }\n\n /**\n * @notice Calls the first 2 steps of the migration process.\n */\n function phase1() external onlyOwner {\n step1();\n step2();\n }\n\n /**\n * @notice Calls the remaining steps of the migration process, and finalizes.\n */\n function phase2() external onlyOwner {\n step3();\n step4();\n step5();\n finalize();\n }\n\n /**\n * @notice Tranfers admin ownership to the final owner.\n */\n function finalize() public onlyOwner {\n // Transfer ownership of the ProxyAdmin to the final owner.\n config.globalConfig.proxyAdmin.transferOwnership(config.globalConfig.finalOwner);\n\n // Optionally also transfer AddressManager and L1StandardBridge if we still own it. Might\n // happen if we're exiting early.\n if (currentStep <= PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the final owner.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1StandardBridge to the final owner.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the final owner.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.finalOwner)\n );\n }\n\n // Mark the deployment as finalized.\n finalized = true;\n }\n\n /**\n * @notice First exit point, can only be called before step 3 is executed.\n */\n function exit1() external onlyOwner {\n require(\n currentStep == EXIT_1_NO_RETURN_STEP,\n \"SystemDictator: can only exit1 before step 3 is executed\"\n );\n\n // Reset the L1CrossDomainMessenger to the old implementation.\n config.globalConfig.addressManager.setAddress(\n \"OVM_L1CrossDomainMessenger\",\n oldL1CrossDomainMessenger\n );\n\n // Unset the DTL shutoff block which will allow the DTL to sync again.\n config.globalConfig.addressManager.setAddress(\"DTL_SHUTOFF_BLOCK\", address(0));\n\n // Mark the deployment as exited.\n exited = true;\n }\n}\n" - }, - "contracts/dispute/BondManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { GameType } from \"../libraries/DisputeTypes.sol\";\nimport { GameStatus } from \"../libraries/DisputeTypes.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\n\nimport { IDisputeGame } from \"./IDisputeGame.sol\";\nimport { IDisputeGameFactory } from \"./IDisputeGameFactory.sol\";\n\n/**\n * @title BondManager\n * @notice The Bond Manager serves as an escrow for permissionless output proposal bonds.\n */\ncontract BondManager {\n /**\n * @notice The Bond Type\n */\n struct Bond {\n address owner;\n uint256 expiration;\n bytes32 id;\n uint256 amount;\n }\n\n /**\n * @notice Mapping from bondId to bond.\n */\n mapping(bytes32 => Bond) public bonds;\n\n /**\n * @notice BondPosted is emitted when a bond is posted.\n * @param bondId is the id of the bond.\n * @param owner is the address that owns the bond.\n * @param expiration is the time at which the bond expires.\n * @param amount is the amount of the bond.\n */\n event BondPosted(bytes32 bondId, address owner, uint256 expiration, uint256 amount);\n\n /**\n * @notice BondSeized is emitted when a bond is seized.\n * @param bondId is the id of the bond.\n * @param owner is the address that owns the bond.\n * @param seizer is the address that seized the bond.\n * @param amount is the amount of the bond.\n */\n event BondSeized(bytes32 bondId, address owner, address seizer, uint256 amount);\n\n /**\n * @notice BondReclaimed is emitted when a bond is reclaimed by the owner.\n * @param bondId is the id of the bond.\n * @param claiment is the address that reclaimed the bond.\n * @param amount is the amount of the bond.\n */\n event BondReclaimed(bytes32 bondId, address claiment, uint256 amount);\n\n /**\n * @notice The permissioned dispute game factory.\n * @dev Used to verify the status of bonds.\n */\n IDisputeGameFactory public immutable DISPUTE_GAME_FACTORY;\n\n /**\n * @notice Amount of gas used to transfer ether when splitting the bond.\n * This is a reasonable amount of gas for a transfer, even to a smart contract.\n * The number of participants is bound of by the block gas limit.\n */\n uint256 private constant TRANSFER_GAS = 30_000;\n\n /**\n * @notice Instantiates the bond maanger with the registered dispute game factory.\n * @param _disputeGameFactory is the dispute game factory.\n */\n constructor(IDisputeGameFactory _disputeGameFactory) {\n DISPUTE_GAME_FACTORY = _disputeGameFactory;\n }\n\n /**\n * @notice Post a bond with a given id and owner.\n * @dev This function will revert if the provided bondId is already in use.\n * @param _bondId is the id of the bond.\n * @param _bondOwner is the address that owns the bond.\n * @param _minClaimHold is the minimum amount of time the owner\n * must wait before reclaiming their bond.\n */\n function post(\n bytes32 _bondId,\n address _bondOwner,\n uint256 _minClaimHold\n ) external payable {\n require(bonds[_bondId].owner == address(0), \"BondManager: BondId already posted.\");\n require(_bondOwner != address(0), \"BondManager: Owner cannot be the zero address.\");\n require(msg.value > 0, \"BondManager: Value must be non-zero.\");\n\n uint256 expiration = _minClaimHold + block.timestamp;\n bonds[_bondId] = Bond({\n owner: _bondOwner,\n expiration: expiration,\n id: _bondId,\n amount: msg.value\n });\n\n emit BondPosted(_bondId, _bondOwner, expiration, msg.value);\n }\n\n /**\n * @notice Seizes the bond with the given id.\n * @dev This function will revert if there is no bond at the given id.\n * @param _bondId is the id of the bond.\n */\n function seize(bytes32 _bondId) external {\n Bond memory b = bonds[_bondId];\n require(b.owner != address(0), \"BondManager: The bond does not exist.\");\n require(b.expiration >= block.timestamp, \"BondManager: Bond expired.\");\n\n IDisputeGame caller = IDisputeGame(msg.sender);\n IDisputeGame game = DISPUTE_GAME_FACTORY.games(\n GameType.ATTESTATION,\n caller.rootClaim(),\n caller.extraData()\n );\n require(msg.sender == address(game), \"BondManager: Unauthorized seizure.\");\n require(game.status() == GameStatus.CHALLENGER_WINS, \"BondManager: Game incomplete.\");\n\n delete bonds[_bondId];\n\n emit BondSeized(_bondId, b.owner, msg.sender, b.amount);\n\n bool success = SafeCall.send(payable(msg.sender), gasleft(), b.amount);\n require(success, \"BondManager: Failed to send Ether.\");\n }\n\n /**\n * @notice Seizes the bond with the given id and distributes it to recipients.\n * @dev This function will revert if there is no bond at the given id.\n * @param _bondId is the id of the bond.\n * @param _claimRecipients is a set of addresses to split the bond amongst.\n */\n function seizeAndSplit(bytes32 _bondId, address[] calldata _claimRecipients) external {\n Bond memory b = bonds[_bondId];\n require(b.owner != address(0), \"BondManager: The bond does not exist.\");\n require(b.expiration >= block.timestamp, \"BondManager: Bond expired.\");\n\n IDisputeGame caller = IDisputeGame(msg.sender);\n IDisputeGame game = DISPUTE_GAME_FACTORY.games(\n GameType.ATTESTATION,\n caller.rootClaim(),\n caller.extraData()\n );\n require(msg.sender == address(game), \"BondManager: Unauthorized seizure.\");\n require(game.status() == GameStatus.CHALLENGER_WINS, \"BondManager: Game incomplete.\");\n\n delete bonds[_bondId];\n\n emit BondSeized(_bondId, b.owner, msg.sender, b.amount);\n\n uint256 len = _claimRecipients.length;\n uint256 proportionalAmount = b.amount / len;\n // Send the proportional amount to each recipient. Do not revert if a send fails as that\n // will prevent other recipients from receiving their share.\n for (uint256 i; i < len; i++) {\n SafeCall.send({\n _target: payable(_claimRecipients[i]),\n _gas: TRANSFER_GAS,\n _value: proportionalAmount\n });\n }\n }\n\n /**\n * @notice Reclaims the bond of the bond owner.\n * @dev This function will revert if there is no bond at the given id.\n * @param _bondId is the id of the bond.\n */\n function reclaim(bytes32 _bondId) external {\n Bond memory b = bonds[_bondId];\n require(b.owner == msg.sender, \"BondManager: Unauthorized claimant.\");\n require(b.expiration <= block.timestamp, \"BondManager: Bond isn't claimable yet.\");\n\n delete bonds[_bondId];\n\n emit BondReclaimed(_bondId, msg.sender, b.amount);\n\n bool success = SafeCall.send(payable(msg.sender), gasleft(), b.amount);\n require(success, \"BondManager: Failed to send Ether.\");\n }\n}\n" - }, - "contracts/dispute/DisputeGameFactory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { ClonesWithImmutableArgs } from \"@cwia/ClonesWithImmutableArgs.sol\";\n\nimport { Claim } from \"../libraries/DisputeTypes.sol\";\nimport { Hash } from \"../libraries/DisputeTypes.sol\";\nimport { GameType } from \"../libraries/DisputeTypes.sol\";\n\nimport { NoImplementation } from \"../libraries/DisputeErrors.sol\";\nimport { GameAlreadyExists } from \"../libraries/DisputeErrors.sol\";\n\nimport { IDisputeGame } from \"./IDisputeGame.sol\";\nimport { IDisputeGameFactory } from \"./IDisputeGameFactory.sol\";\n\n/**\n * @title DisputeGameFactory\n * @notice A factory contract for creating `IDisputeGame` contracts.\n */\ncontract DisputeGameFactory is Ownable, IDisputeGameFactory {\n /**\n * @dev Allows for the creation of clone proxies with immutable arguments.\n */\n using ClonesWithImmutableArgs for address;\n\n /**\n * @notice Mapping of `GameType`s to their respective `IDisputeGame` implementations.\n */\n mapping(GameType => IDisputeGame) public gameImpls;\n\n /**\n * @notice Mapping of a hash of `gameType . rootClaim . extraData` to\n * the deployed `IDisputeGame` clone.\n * @dev Note: `.` denotes concatenation.\n */\n mapping(Hash => IDisputeGame) internal disputeGames;\n\n /**\n * @notice Constructs a new DisputeGameFactory contract.\n * @param _owner The owner of the contract.\n */\n constructor(address _owner) Ownable() {\n transferOwnership(_owner);\n }\n\n /**\n * @notice Retrieves the hash of `gameType . rootClaim . extraData`\n * to the deployed `DisputeGame` clone.\n * @dev Note: `.` denotes concatenation.\n * @param gameType The type of the DisputeGame.\n * Used to decide the implementation to clone.\n * @param rootClaim The root claim of the DisputeGame.\n * @param extraData Any extra data that should be provided to the\n * created dispute game.\n * @return _proxy The clone of the `DisputeGame` created with the\n * given parameters. `address(0)` if nonexistent.\n */\n function games(\n GameType gameType,\n Claim rootClaim,\n bytes calldata extraData\n ) external view returns (IDisputeGame _proxy) {\n return disputeGames[getGameUUID(gameType, rootClaim, extraData)];\n }\n\n /**\n * @notice Creates a new DisputeGame proxy contract.\n * @notice If a dispute game with the given parameters already exists,\n * it will be returned.\n * @param gameType The type of the DisputeGame.\n * Used to decide the proxy implementation.\n * @param rootClaim The root claim of the DisputeGame.\n * @param extraData Any extra data that should be provided\n * to the created dispute game.\n * @return proxy The clone of the `DisputeGame`.\n */\n function create(\n GameType gameType,\n Claim rootClaim,\n bytes calldata extraData\n ) external returns (IDisputeGame proxy) {\n // Grab the implementation contract for the given `GameType`.\n IDisputeGame impl = gameImpls[gameType];\n\n // If there is no implementation to clone for the given `GameType`, revert.\n if (address(impl) == address(0)) {\n revert NoImplementation(gameType);\n }\n\n // Clone the implementation contract and initialize it with the given parameters.\n bytes memory data = abi.encodePacked(rootClaim, extraData);\n proxy = IDisputeGame(address(impl).clone(data));\n proxy.initialize();\n\n // Compute the unique identifier for the dispute game.\n Hash uuid = getGameUUID(gameType, rootClaim, extraData);\n\n // If a dispute game with the same UUID already exists, revert.\n if (address(disputeGames[uuid]) != address(0)) {\n revert GameAlreadyExists(uuid);\n }\n\n // Store the dispute game in the mapping & emit the `DisputeGameCreated` event.\n disputeGames[uuid] = proxy;\n emit DisputeGameCreated(address(proxy), gameType, rootClaim);\n }\n\n /**\n * @notice Sets the implementation contract for a specific `GameType`.\n * @param gameType The type of the DisputeGame.\n * @param impl The implementation contract for the given `GameType`.\n */\n function setImplementation(GameType gameType, IDisputeGame impl) external onlyOwner {\n gameImpls[gameType] = impl;\n emit ImplementationSet(address(impl), gameType);\n }\n\n /**\n * @notice Returns a unique identifier for the given dispute game parameters.\n * @dev Hashes the concatenation of `gameType . rootClaim . extraData`\n * without expanding memory.\n * @param gameType The type of the DisputeGame.\n * @param rootClaim The root claim of the DisputeGame.\n * @param extraData Any extra data that should be provided to the created dispute game.\n * @return _uuid The unique identifier for the given dispute game parameters.\n */\n function getGameUUID(\n GameType gameType,\n Claim rootClaim,\n bytes memory extraData\n ) public pure returns (Hash _uuid) {\n assembly {\n // Grab the offsets of the other memory locations we will need to temporarily overwrite.\n let gameTypeOffset := sub(extraData, 0x60)\n let rootClaimOffset := add(gameTypeOffset, 0x20)\n let pointerOffset := add(rootClaimOffset, 0x20)\n\n // Copy the memory that we will temporarily overwrite onto the stack\n // so we can restore it later\n let tempA := mload(gameTypeOffset)\n let tempB := mload(rootClaimOffset)\n let tempC := mload(pointerOffset)\n\n // Overwrite the memory with the data we want to hash\n mstore(gameTypeOffset, gameType)\n mstore(rootClaimOffset, rootClaim)\n mstore(pointerOffset, 0x60)\n\n // Compute the length of the memory to hash\n // `0x60 + 0x20 + extraData.length` rounded to the *next* multiple of 32.\n let hashLen := and(add(mload(extraData), 0x9F), not(0x1F))\n\n // Hash the memory to produce the UUID digest\n _uuid := keccak256(gameTypeOffset, hashLen)\n\n // Restore the memory prior to `extraData`\n mstore(gameTypeOffset, tempA)\n mstore(rootClaimOffset, tempB)\n mstore(pointerOffset, tempC)\n }\n }\n}\n" - }, - "contracts/dispute/IAttestationDisputeGame.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { IDisputeGame } from \"./IDisputeGame.sol\";\n\n/**\n * @title IAttestationDisputeGame\n * @notice The interface for an attestation-based DisputeGame meant to contest output\n * proposals in Optimism's `L2OutputOracle` contract.\n */\ninterface IAttestationDisputeGame is IDisputeGame {\n /**\n * @notice A mapping of addresses from the `signerSet` to booleans signifying whether\n * or not they have authorized the `rootClaim` to be invalidated.\n * @param challenger The address to check for authorization.\n * @return _challenged Whether or not the `challenger` has challenged the `rootClaim`.\n */\n function challenges(address challenger) external view returns (bool _challenged);\n\n /**\n * @notice The signer set consists of authorized public keys that may challenge\n * the `rootClaim`.\n * @param addr The address to check for authorization.\n * @return _isAuthorized Whether or not the `addr` is part of the signer set.\n */\n function signerSet(address addr) external view returns (bool _isAuthorized);\n\n /**\n * @notice The amount of signatures required to successfully challenge the `rootClaim`\n * output proposal. Once this threshold is met by members of the `signerSet`\n * calling `challenge`, the game will be resolved to `CHALLENGER_WINS`.\n * @custom:invariant The `signatureThreshold` may never be greater than the length\n * of the `signerSet`.\n * @return _signatureThreshold The amount of signatures required to successfully\n * challenge the `rootClaim` output proposal.\n */\n function frozenSignatureThreshold() external view returns (uint256 _signatureThreshold);\n\n /**\n * @notice Returns the L2 Block Number that the `rootClaim` commits to.\n * Exists within the `extraData`.\n * @return _l2BlockNumber The L2 Block Number that the `rootClaim` commits to.\n */\n function l2BlockNumber() external view returns (uint256 _l2BlockNumber);\n\n /**\n * @notice Challenge the `rootClaim`.\n * @dev - If the `ecrecover`ed address that created the signature is not a part of\n * the signer set returned by `signerSet`, this function should revert.\n * - If the `ecrecover`ed address that created the signature is not the\n * msg.sender, this function should revert.\n * - If the signature provided is the signature that breaches the signature\n * threshold, the function should call the `resolve` function to resolve\n * the game as `CHALLENGER_WINS`.\n * - When the game resolves, the bond attached to the root claim should be\n * distributed among the signers who participated in challenging the\n * invalid claim.\n * @param signature An EIP-712 signature committing to the `rootClaim` and\n * `l2BlockNumber` (within the `extraData`) from a key that exists\n * within the `signerSet`.\n */\n function challenge(bytes calldata signature) external;\n}\n" - }, - "contracts/dispute/IBondManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\n/**\n * @title IBondManager\n * @notice The Bond Manager holds ether posted as a bond for a bond id.\n */\ninterface IBondManager {\n /**\n * @notice Post a bond with a given id and owner.\n * @dev This function will revert if the provided bondId is already in use.\n * @param _bondId is the id of the bond.\n * @param _bondOwner is the address that owns the bond.\n * @param _minClaimHold is the minimum amount of time the owner\n * must wait before reclaiming their bond.\n */\n function post(\n bytes32 _bondId,\n address _bondOwner,\n uint256 _minClaimHold\n ) external payable;\n\n /**\n * @notice Seizes the bond with the given id.\n * @dev This function will revert if there is no bond at the given id.\n * @param _bondId is the id of the bond.\n */\n function seize(bytes32 _bondId) external;\n\n /**\n * @notice Seizes the bond with the given id and distributes it to recipients.\n * @dev This function will revert if there is no bond at the given id.\n * @param _bondId is the id of the bond.\n * @param _claimRecipients is a set of addresses to split the bond amongst.\n */\n function seizeAndSplit(bytes32 _bondId, address[] calldata _claimRecipients) external;\n\n /**\n * @notice Reclaims the bond of the bond owner.\n * @dev This function will revert if there is no bond at the given id.\n * @param _bondId is the id of the bond.\n */\n function reclaim(bytes32 _bondId) external;\n}\n" - }, - "contracts/dispute/IDisputeGame.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { Claim } from \"../libraries/DisputeTypes.sol\";\nimport { GameType } from \"../libraries/DisputeTypes.sol\";\nimport { GameStatus } from \"../libraries/DisputeTypes.sol\";\nimport { Timestamp } from \"../libraries/DisputeTypes.sol\";\n\nimport { IVersioned } from \"./IVersioned.sol\";\nimport { IBondManager } from \"./IBondManager.sol\";\nimport { IInitializable } from \"./IInitializable.sol\";\n\n/**\n * @title IDisputeGame\n * @notice The generic interface for a DisputeGame contract.\n */\ninterface IDisputeGame is IInitializable, IVersioned {\n /**\n * @notice Emitted when the game is resolved.\n * @param status The status of the game after resolution.\n */\n event Resolved(GameStatus indexed status);\n\n /// @notice Returns the timestamp that the DisputeGame contract was created at.\n\n /**\n * @notice Returns the timestamp that the DisputeGame contract was created at.\n * @return _createdAt The timestamp that the DisputeGame contract was created at.\n */\n function createdAt() external view returns (Timestamp _createdAt);\n\n /**\n * @notice Returns the current status of the game.\n * @return _status The current status of the game.\n */\n function status() external view returns (GameStatus _status);\n\n /**\n * @notice Getter for the game type.\n * @dev `clones-with-immutable-args` argument #1\n * @dev The reference impl should be entirely different depending on the type (fault, validity)\n * i.e. The game type should indicate the security model.\n * @return _gameType The type of proof system being used.\n */\n function gameType() external view returns (GameType _gameType);\n\n /**\n * @notice Getter for the root claim.\n * @dev `clones-with-immutable-args` argument #2\n * @return _rootClaim The root claim of the DisputeGame.\n */\n function rootClaim() external view returns (Claim _rootClaim);\n\n /**\n * @notice Getter for the extra data.\n * @dev `clones-with-immutable-args` argument #3\n * @return _extraData Any extra data supplied to the dispute game contract by the creator.\n */\n function extraData() external view returns (bytes memory _extraData);\n\n /**\n * @notice Returns the address of the `BondManager` used.\n * @return _bondManager The address of the `BondManager` used.\n */\n function bondManager() external view returns (IBondManager _bondManager);\n\n /**\n * @notice If all necessary information has been gathered, this function should mark the game\n * status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of\n * the resolved game. It is at this stage that the bonds should be awarded to the\n * necessary parties.\n * @dev May only be called if the `status` is `IN_PROGRESS`.\n * @return _status The status of the game after resolution.\n */\n function resolve() external returns (GameStatus _status);\n}\n" - }, - "contracts/dispute/IDisputeGameFactory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { Claim } from \"../libraries/DisputeTypes.sol\";\nimport { GameType } from \"../libraries/DisputeTypes.sol\";\n\nimport { IDisputeGame } from \"./IDisputeGame.sol\";\n\n/**\n * @title IDisputeGameFactory\n * @notice The interface for a DisputeGameFactory contract.\n */\ninterface IDisputeGameFactory {\n /**\n * @notice Emitted when a new dispute game is created\n * @param disputeProxy The address of the dispute game proxy\n * @param gameType The type of the dispute game proxy's implementation\n * @param rootClaim The root claim of the dispute game\n */\n event DisputeGameCreated(\n address indexed disputeProxy,\n GameType indexed gameType,\n Claim indexed rootClaim\n );\n\n /**\n * @notice Emitted when a new game implementation added to the factory\n * @param impl The implementation contract for the given `GameType`.\n * @param gameType The type of the DisputeGame.\n */\n event ImplementationSet(address indexed impl, GameType indexed gameType);\n\n /**\n * @notice `games` queries an internal a mapping that maps the hash of\n * `gameType ++ rootClaim ++ extraData` to the deployed `DisputeGame` clone.\n * @dev `++` equates to concatenation.\n * @param gameType The type of the DisputeGame - used to decide the proxy implementation\n * @param rootClaim The root claim of the DisputeGame.\n * @param extraData Any extra data that should be provided to the created dispute game.\n * @return _proxy The clone of the `DisputeGame` created with the given parameters.\n * Returns `address(0)` if nonexistent.\n */\n function games(\n GameType gameType,\n Claim rootClaim,\n bytes calldata extraData\n ) external view returns (IDisputeGame _proxy);\n\n /**\n * @notice `gameImpls` is a mapping that maps `GameType`s to their respective\n * `IDisputeGame` implementations.\n * @param gameType The type of the dispute game.\n * @return _impl The address of the implementation of the game type.\n * Will be cloned on creation of a new dispute game with the given `gameType`.\n */\n function gameImpls(GameType gameType) external view returns (IDisputeGame _impl);\n\n /**\n * @notice Creates a new DisputeGame proxy contract.\n * @param gameType The type of the DisputeGame - used to decide the proxy implementation\n * @param rootClaim The root claim of the DisputeGame.\n * @param extraData Any extra data that should be provided to the created dispute game.\n * @return proxy The address of the created DisputeGame proxy.\n */\n function create(\n GameType gameType,\n Claim rootClaim,\n bytes calldata extraData\n ) external returns (IDisputeGame proxy);\n\n /**\n * @notice Sets the implementation contract for a specific `GameType`.\n * @dev May only be called by the `owner`.\n * @param gameType The type of the DisputeGame.\n * @param impl The implementation contract for the given `GameType`.\n */\n function setImplementation(GameType gameType, IDisputeGame impl) external;\n}\n" - }, - "contracts/dispute/IFaultDisputeGame.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { Clock } from \"../libraries/DisputeTypes.sol\";\nimport { Claim } from \"../libraries/DisputeTypes.sol\";\nimport { Position } from \"../libraries/DisputeTypes.sol\";\nimport { Timestamp } from \"../libraries/DisputeTypes.sol\";\nimport { ClaimHash } from \"../libraries/DisputeTypes.sol\";\nimport { BondAmount } from \"../libraries/DisputeTypes.sol\";\n\nimport { IDisputeGame } from \"./IDisputeGame.sol\";\n\n/**\n * @title IFaultDisputeGame\n * @notice The interface for a fault proof backed dispute game.\n */\ninterface IFaultDisputeGame is IDisputeGame {\n /**\n * @notice Emitted when a subclaim is disagreed upon by `claimant`\n * @dev Disagreeing with a subclaim is akin to attacking it.\n * @param claimHash The unique ClaimHash that is being disagreed upon\n * @param pivot The claim for the following pivot (disagreement = go left)\n * @param claimant The address of the claimant\n */\n event Attack(ClaimHash indexed claimHash, Claim indexed pivot, address indexed claimant);\n\n /**\n * @notice Emitted when a subclaim is agreed upon by `claimant`\n * @dev Agreeing with a subclaim is akin to defending it.\n * @param claimHash The unique ClaimHash that is being agreed upon\n * @param pivot The claim for the following pivot (agreement = go right)\n * @param claimant The address of the claimant\n */\n event Defend(ClaimHash indexed claimHash, Claim indexed pivot, address indexed claimant);\n\n /**\n * @notice State variable of the starting timestamp of the game, set on deployment.\n * @return The starting timestamp of the game\n */\n function gameStart() external view returns (Timestamp);\n\n /**\n * @notice Maps a unique ClaimHash to a Claim.\n * @param claimHash The unique ClaimHash\n * @return claim The Claim associated with the ClaimHash\n */\n function claims(ClaimHash claimHash) external view returns (Claim claim);\n\n /**\n * @notice Maps a unique ClaimHash to its parent.\n * @param claimHash The unique ClaimHash\n * @return parent The parent ClaimHash of the passed ClaimHash\n */\n function parents(ClaimHash claimHash) external view returns (ClaimHash parent);\n\n /**\n * @notice Maps a unique ClaimHash to its Position.\n * @param claimHash The unique ClaimHash\n * @return position The Position associated with the ClaimHash\n */\n function positions(ClaimHash claimHash) external view returns (Position position);\n\n /**\n * @notice Maps a unique ClaimHash to a Bond.\n * @param claimHash The unique ClaimHash\n * @return bond The Bond associated with the ClaimHash\n */\n function bonds(ClaimHash claimHash) external view returns (BondAmount bond);\n\n /**\n * @notice Maps a unique ClaimHash its chess clock.\n * @param claimHash The unique ClaimHash\n * @return clock The chess clock associated with the ClaimHash\n */\n function clocks(ClaimHash claimHash) external view returns (Clock clock);\n\n /**\n * @notice Maps a unique ClaimHash to its reference counter.\n * @param claimHash The unique ClaimHash\n * @return _rc The reference counter associated with the ClaimHash\n */\n function rc(ClaimHash claimHash) external view returns (uint64 _rc);\n\n /**\n * @notice Maps a unique ClaimHash to a boolean indicating whether or not it has been countered.\n * @param claimHash The unique claimHash\n * @return _countered Whether or not `claimHash` has been countered\n */\n function countered(ClaimHash claimHash) external view returns (bool _countered);\n\n /**\n * @notice Disagree with a subclaim\n * @param disagreement The ClaimHash of the disagreement\n * @param pivot The claimed pivot\n */\n function attack(ClaimHash disagreement, Claim pivot) external;\n\n /**\n * @notice Agree with a subclaim\n * @param agreement The ClaimHash of the agreement\n * @param pivot The claimed pivot\n */\n function defend(ClaimHash agreement, Claim pivot) external;\n\n /**\n * @notice Perform the final step via an on-chain fault proof processor\n * @dev This function should point to a fault proof processor in order to execute\n * a step in the fault proof program on-chain. The interface of the fault proof\n * processor contract should be generic enough such that we can use different\n * fault proof VMs (MIPS, RiscV5, etc.)\n * @param disagreement The ClaimHash of the disagreement\n */\n function step(ClaimHash disagreement) external;\n}\n" - }, - "contracts/dispute/IInitializable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\n/**\n * @title IInitializable\n * @notice An interface for initializable contracts.\n */\ninterface IInitializable {\n /**\n * @notice Initializes the contract.\n * @dev This function may only be called once.\n */\n function initialize() external;\n}\n" - }, - "contracts/dispute/IVersioned.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\n/**\n * @title IVersioned\n * @notice An interface for semantically versioned contracts.\n */\ninterface IVersioned {\n /**\n * @notice Returns the semantic version of the contract\n * @return _version The semantic version of the contract\n */\n function version() external pure returns (string memory _version);\n}\n" - }, - "contracts/echidna/FuzzAddressAliasing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract EchidnaFuzzAddressAliasing {\n bool internal failedRoundtrip;\n\n /**\n * @notice Takes an address to be aliased with AddressAliasHelper and then unaliased\n * and updates the test contract's state indicating if the round trip encoding\n * failed.\n */\n function testRoundTrip(address addr) public {\n // Alias our address\n address aliasedAddr = AddressAliasHelper.applyL1ToL2Alias(addr);\n\n // Unalias our address\n address undoneAliasAddr = AddressAliasHelper.undoL1ToL2Alias(aliasedAddr);\n\n // If our round trip aliasing did not return the original result, set our state.\n if (addr != undoneAliasAddr) {\n failedRoundtrip = true;\n }\n }\n\n /**\n * @custom:invariant Address aliases are always able to be undone.\n *\n * Asserts that an address that has been aliased with `applyL1ToL2Alias` can always\n * be unaliased with `undoL1ToL2Alias`.\n */\n function echidna_round_trip_aliasing() public view returns (bool) {\n // ASSERTION: The round trip aliasing done in testRoundTrip(...) should never fail.\n return !failedRoundtrip;\n }\n}\n" - }, - "contracts/echidna/FuzzBurn.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\n\ncontract EchidnaFuzzBurnEth is StdUtils {\n bool internal failedEthBurn;\n\n /**\n * @notice Takes an integer amount of eth to burn through the Burn library and\n * updates the contract state if an incorrect amount of eth moved from the contract\n */\n function testBurn(uint256 _value) public {\n // cache the contract's eth balance\n uint256 preBurnBalance = address(this).balance;\n uint256 value = bound(_value, 0, preBurnBalance);\n\n // execute a burn of _value eth\n Burn.eth(value);\n\n // check that exactly value eth was transfered from the contract\n unchecked {\n if (address(this).balance != preBurnBalance - value) {\n failedEthBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `eth(uint256)` always burns the exact amount of eth passed.\n *\n * Asserts that when `Burn.eth(uint256)` is called, it always burns the exact amount\n * of ETH passed to the function.\n */\n function echidna_burn_eth() public view returns (bool) {\n // ASSERTION: The amount burned should always match the amount passed exactly\n return !failedEthBurn;\n }\n}\n\ncontract EchidnaFuzzBurnGas is StdUtils {\n bool internal failedGasBurn;\n\n /**\n * @notice Takes an integer amount of gas to burn through the Burn library and\n * updates the contract state if at least that amount of gas was not burned\n * by the library\n */\n function testGas(uint256 _value) public {\n // cap the value to the max resource limit\n uint256 MAX_RESOURCE_LIMIT = 8_000_000;\n uint256 value = bound(_value, 0, MAX_RESOURCE_LIMIT);\n\n // cache the contract's current remaining gas\n uint256 preBurnGas = gasleft();\n\n // execute the gas burn\n Burn.gas(value);\n\n // cache the remaining gas post burn\n uint256 postBurnGas = gasleft();\n\n // check that at least value gas was burnt (and that there was no underflow)\n unchecked {\n if (postBurnGas - preBurnGas > value || preBurnGas - value > preBurnGas) {\n failedGasBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `gas(uint256)` always burns at least the amount of gas passed.\n *\n * Asserts that when `Burn.gas(uint256)` is called, it always burns at least the amount\n * of gas passed to the function.\n */\n function echidna_burn_gas() public view returns (bool) {\n // ASSERTION: The amount of gas burned should be strictly greater than the\n // the amount passed as _value (minimum _value + whatever minor overhead to\n // the value after the call)\n return !failedGasBurn;\n }\n}\n" - }, - "contracts/echidna/FuzzEncoding.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzEncoding {\n bool internal failedRoundtripAToB;\n bool internal failedRoundtripBToA;\n\n /**\n * @notice Takes a pair of integers to be encoded into a versioned nonce with the\n * Encoding library and then decoded and updates the test contract's state\n * indicating if the round trip encoding failed.\n */\n function testRoundTripAToB(uint240 _nonce, uint16 _version) public {\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(encodedVersionedNonce);\n\n // If our round trip encoding did not return the original result, set our state.\n if ((decodedNonce != _nonce) || (decodedVersion != _version)) {\n failedRoundtripAToB = true;\n }\n }\n\n /**\n * @notice Takes an integer representing a packed version and nonce and attempts\n * to decode them using the Encoding library before re-encoding and updates\n * the test contract's state indicating if the round trip encoding failed.\n */\n function testRoundTripBToA(uint256 _versionedNonce) public {\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(_versionedNonce);\n\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(decodedNonce, decodedVersion);\n\n // If our round trip encoding did not return the original result, set our state.\n if (encodedVersionedNonce != _versionedNonce) {\n failedRoundtripBToA = true;\n }\n }\n\n /**\n * @custom:invariant `testRoundTripAToB` never fails.\n *\n * Asserts that a raw versioned nonce can be encoded / decoded to reach the same raw value.\n */\n function echidna_round_trip_encoding_AToB() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripAToB(...)\n return !failedRoundtripAToB;\n }\n\n /**\n * @custom:invariant `testRoundTripBToA` never fails.\n *\n * Asserts that an encoded versioned nonce can always be decoded / re-encoded to reach\n * the same encoded value.\n */\n function echidna_round_trip_encoding_BToA() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripBToA should never\n // fail.\n return !failedRoundtripBToA;\n }\n}\n" - }, - "contracts/echidna/FuzzHashing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzHashing {\n bool internal failedCrossDomainHashHighVersion;\n bool internal failedCrossDomainHashV0;\n bool internal failedCrossDomainHashV1;\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash with a randomly\n * generated version. Only schema versions 0 and 1 are supported and all others should revert.\n */\n function testHashCrossDomainMessageHighVersion(\n uint16 _version,\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // hash the cross domain message. we don't need to store the result since the function\n // validates and should revert if an invalid version (>1) is encoded\n Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);\n\n // check that execution never makes it this far for an invalid version\n if (_version > 1) {\n failedCrossDomainHashHighVersion = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v0 schema\n * and compares the output of a call to the unversioned function to the v0 function directly\n */\n function testHashCrossDomainMessageV0(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 0\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 0);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n encodedNonce\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV0 = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v1 schema\n * and compares the output of a call to the unversioned function to the v1 function directly\n */\n function testHashCrossDomainMessageV1(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 1\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 1);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV1 = true;\n }\n }\n\n /**\n * @custom:invariant `hashCrossDomainMessage` reverts if `version` is > `1`.\n *\n * The `hashCrossDomainMessage` function should always revert if the `version` passed is > `1`.\n */\n function echidna_hash_xdomain_msg_high_version() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage will never succeed for a version > 1\n return !failedCrossDomainHashHighVersion;\n }\n\n /**\n * @custom:invariant `version` = `0`: `hashCrossDomainMessage` and `hashCrossDomainMessageV0`\n * are equivalent.\n *\n * If the version passed is 0, `hashCrossDomainMessage` and `hashCrossDomainMessageV0` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_0() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV0\n // should always match when the version passed is 0\n return !failedCrossDomainHashV0;\n }\n\n /**\n * @custom:invariant `version` = `1`: `hashCrossDomainMessage` and `hashCrossDomainMessageV1`\n * are equivalent.\n *\n * If the version passed is 1, `hashCrossDomainMessage` and `hashCrossDomainMessageV1` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_1() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV1\n // should always match when the version passed is 1\n return !failedCrossDomainHashV1;\n }\n}\n" - }, - "contracts/echidna/FuzzOptimismPortal.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzOptimismPortal {\n OptimismPortal internal portal;\n bool internal failedToComplete;\n\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n SystemConfig systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: rcfg\n });\n\n portal = new OptimismPortal({\n _l2Oracle: L2OutputOracle(address(0)),\n _guardian: address(0),\n _paused: false,\n _config: systemConfig\n });\n }\n\n // A test intended to identify any unexpected halting conditions\n function testDepositTransactionCompletes(\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable {\n failedToComplete = true;\n require(!_isCreation || _to == address(0), \"EchidnaFuzzOptimismPortal: invalid test case.\");\n portal.depositTransaction{ value: _mint }(_to, _value, _gasLimit, _isCreation, _data);\n failedToComplete = false;\n }\n\n /**\n * @custom:invariant Deposits of any value should always succeed unless\n * `_to` = `address(0)` or `_isCreation` = `true`.\n *\n * All deposits, barring creation transactions and transactions sent to `address(0)`,\n * should always succeed.\n */\n function echidna_deposit_completes() public view returns (bool) {\n return !failedToComplete;\n }\n}\n" - }, - "contracts/echidna/FuzzResourceMetering.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzResourceMetering is ResourceMetering, StdUtils {\n bool internal failedMaxGasPerBlock;\n bool internal failedRaiseBaseFee;\n bool internal failedLowerBaseFee;\n bool internal failedNeverBelowMinBaseFee;\n bool internal failedMaxRaiseBaseFeePerBlock;\n bool internal failedMaxLowerBaseFeePerBlock;\n\n // Used as a special flag for the purpose of identifying unchecked math errors specifically\n // in the test contracts, not the target contracts themselves.\n bool internal underflow;\n\n constructor() {\n initialize();\n }\n\n function initialize() internal initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public pure returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n return rcfg;\n }\n\n /**\n * @notice Takes the necessary parameters to allow us to burn arbitrary amounts of gas to test\n * the underlying resource metering/gas market logic\n */\n function testBurn(uint256 _gasToBurn, bool _raiseBaseFee) public {\n // Part 1: we cache the current param values and do some basic checks on them.\n uint256 cachedPrevBaseFee = uint256(params.prevBaseFee);\n uint256 cachedPrevBoughtGas = uint256(params.prevBoughtGas);\n uint256 cachedPrevBlockNum = uint256(params.prevBlockNum);\n\n ResourceMetering.ResourceConfig memory rcfg = resourceConfig();\n uint256 targetResourceLimit = uint256(rcfg.maxResourceLimit) /\n uint256(rcfg.elasticityMultiplier);\n\n // check that the last block's base fee hasn't dropped below the minimum\n if (cachedPrevBaseFee < uint256(rcfg.minimumBaseFee)) {\n failedNeverBelowMinBaseFee = true;\n }\n // check that the last block didn't consume more than the max amount of gas\n if (cachedPrevBoughtGas > uint256(rcfg.maxResourceLimit)) {\n failedMaxGasPerBlock = true;\n }\n\n // Part2: we perform the gas burn\n\n // force the gasToBurn into the correct range based on whether we intend to\n // raise or lower the baseFee after this block, respectively\n uint256 gasToBurn;\n if (_raiseBaseFee) {\n gasToBurn = bound(\n _gasToBurn,\n uint256(targetResourceLimit),\n uint256(rcfg.maxResourceLimit)\n );\n } else {\n gasToBurn = bound(_gasToBurn, 0, targetResourceLimit);\n }\n\n _burnInternal(uint64(gasToBurn));\n\n // Part 3: we run checks and modify our invariant flags based on the updated params values\n\n // Calculate the maximum allowed baseFee change (per block)\n uint256 maxBaseFeeChange = cachedPrevBaseFee / uint256(rcfg.baseFeeMaxChangeDenominator);\n\n // If the last block used more than the target amount of gas (and there were no\n // empty blocks in between), ensure this block's baseFee increased, but not by\n // more than the max amount per block\n if (\n (cachedPrevBoughtGas > uint256(targetResourceLimit)) &&\n (uint256(params.prevBlockNum) - cachedPrevBlockNum == 1)\n ) {\n failedRaiseBaseFee = failedRaiseBaseFee || (params.prevBaseFee <= cachedPrevBaseFee);\n failedMaxRaiseBaseFeePerBlock =\n failedMaxRaiseBaseFeePerBlock ||\n ((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);\n }\n\n // If the last block used less than the target amount of gas, (or was empty),\n // ensure that: this block's baseFee was decreased, but not by more than the max amount\n if (\n (cachedPrevBoughtGas < uint256(targetResourceLimit)) ||\n (uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)\n ) {\n // Invariant: baseFee should decrease\n failedLowerBaseFee =\n failedLowerBaseFee ||\n (uint256(params.prevBaseFee) > cachedPrevBaseFee);\n\n if (params.prevBlockNum - cachedPrevBlockNum == 1) {\n // No empty blocks\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n } else if (params.prevBlockNum - cachedPrevBlockNum > 1) {\n // We have at least one empty block\n // Update the maxBaseFeeChange to account for multiple blocks having passed\n unchecked {\n maxBaseFeeChange = uint256(\n int256(cachedPrevBaseFee) -\n Arithmetic.clamp(\n Arithmetic.cdexp(\n int256(cachedPrevBaseFee),\n int256(uint256(rcfg.baseFeeMaxChangeDenominator)),\n int256(uint256(params.prevBlockNum) - cachedPrevBlockNum)\n ),\n int256(uint256(rcfg.minimumBaseFee)),\n int256(uint256(rcfg.maximumBaseFee))\n )\n );\n }\n\n // Detect an underflow in the previous calculation.\n // Without using unchecked above, and detecting the underflow here, echidna would\n // otherwise ignore the revert.\n underflow = underflow || maxBaseFeeChange > cachedPrevBaseFee;\n\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n }\n }\n }\n\n function _burnInternal(uint64 _gasToBurn) private metered(_gasToBurn) {}\n\n /**\n * @custom:invariant The base fee should increase if the last block used more\n * than the target amount of gas\n *\n * If the last block used more than the target amount of gas (and there were no\n * empty blocks in between), ensure this block's baseFee increased, but not by\n * more than the max amount per block.\n */\n function echidna_high_usage_raise_baseFee() public view returns (bool) {\n return !failedRaiseBaseFee;\n }\n\n /**\n * @custom:invariant The base fee should decrease if the last block used less\n * than the target amount of gas\n *\n * If the previous block used less than the target amount of gas, the base fee should decrease,\n * but not more than the max amount.\n */\n function echidna_low_usage_lower_baseFee() public view returns (bool) {\n return !failedLowerBaseFee;\n }\n\n /**\n * @custom:invariant A block's base fee should never be below `MINIMUM_BASE_FEE`\n *\n * This test asserts that a block's base fee can never drop below the\n * `MINIMUM_BASE_FEE` threshold.\n */\n function echidna_never_below_min_baseFee() public view returns (bool) {\n return !failedNeverBelowMinBaseFee;\n }\n\n /**\n * @custom:invariant A block can never consume more than `MAX_RESOURCE_LIMIT` gas.\n *\n * This test asserts that a block can never consume more than the `MAX_RESOURCE_LIMIT`\n * gas threshold.\n */\n function echidna_never_above_max_gas_limit() public view returns (bool) {\n return !failedMaxGasPerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be raised more than the max base fee change.\n *\n * After a block consumes more gas than the target gas, the base fee cannot be raised\n * more than the maximum amount allowed. The max base fee change (per-block) is derived\n * as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_increase() public view returns (bool) {\n return !failedMaxRaiseBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be lowered more than the max base fee change.\n *\n * After a block consumes less than the target gas, the base fee cannot be lowered more\n * than the maximum amount allowed. The max base fee change (per-block) is derived as\n *follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_decrease() public view returns (bool) {\n return !failedMaxLowerBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The `maxBaseFeeChange` calculation over multiple blocks can never\n * underflow.\n *\n * When calculating the `maxBaseFeeChange` after multiple empty blocks, the calculation\n * should never be allowed to underflow.\n */\n function echidna_underflow() public view returns (bool) {\n return !underflow;\n }\n}\n" - }, - "contracts/governance/GovernanceToken.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:predeploy 0x4200000000000000000000000000000000000042\n * @title GovernanceToken\n * @notice The Optimism token used in governance and supporting voting and delegation. Implements\n * EIP 2612 allowing signed approvals. Contract is \"owned\" by a `MintManager` instance with\n * permission to the `mint` function only, for the purposes of enforcing the token inflation\n * schedule.\n */\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\n constructor() ERC20(\"Optimism\", \"OP\") ERC20Permit(\"Optimism\") {}\n\n /**\n * @notice Allows the owner to mint tokens.\n *\n * @param _account The account receiving minted tokens.\n * @param _amount The amount of tokens to mint.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n /**\n * @notice Callback called after a token transfer.\n *\n * @param from The account sending tokens.\n * @param to The account receiving tokens.\n * @param amount The amount of tokens being transfered.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20, ERC20Votes) {\n super._afterTokenTransfer(from, to, amount);\n }\n\n /**\n * @notice Internal mint function.\n *\n * @param to The account receiving minted tokens.\n * @param amount The amount of tokens to mint.\n */\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._mint(to, amount);\n }\n\n /**\n * @notice Internal burn function.\n *\n * @param account The account that tokens will be burned from.\n * @param amount The amount of tokens that will be burned.\n */\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._burn(account, amount);\n }\n}\n" - }, - "contracts/governance/MintManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./GovernanceToken.sol\";\n\n/**\n * @title MintManager\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\n * Contract acts as the token \"mint manager\" with permission to the `mint` function only.\n * Currently permitted to mint once per year of up to 2% of the total token supply.\n * Upgradable to allow changes in the inflation schedule.\n */\ncontract MintManager is Ownable {\n /**\n * @notice The GovernanceToken that the MintManager can mint tokens\n */\n GovernanceToken public immutable governanceToken;\n\n /**\n * @notice The amount of tokens that can be minted per year. The value is a fixed\n * point number with 4 decimals.\n */\n uint256 public constant MINT_CAP = 20; // 2%\n\n /**\n * @notice The number of decimals for the MINT_CAP.\n */\n uint256 public constant DENOMINATOR = 1000;\n\n /**\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\n * be minted again.\n */\n uint256 public constant MINT_PERIOD = 365 days;\n\n /**\n * @notice Tracks the time of last mint.\n */\n uint256 public mintPermittedAfter;\n\n /**\n * @param _upgrader The owner of this contract\n * @param _governanceToken The governance token this contract can mint\n * tokens of\n */\n constructor(address _upgrader, address _governanceToken) {\n transferOwnership(_upgrader);\n governanceToken = GovernanceToken(_governanceToken);\n }\n\n /**\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\n *\n * @param _account Address to mint new tokens to.\n * @param _amount Amount of tokens to be minted.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n if (mintPermittedAfter > 0) {\n require(\n mintPermittedAfter <= block.timestamp,\n \"MintManager: minting not permitted yet\"\n );\n\n require(\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\n \"MintManager: mint amount exceeds cap\"\n );\n }\n\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\n governanceToken.mint(_account, _amount);\n }\n\n /**\n * @notice Upgrade the owner of the governance token to a new MintManager.\n *\n * @param _newMintManager The MintManager to upgrade to.\n */\n function upgrade(address _newMintManager) public onlyOwner {\n require(\n _newMintManager != address(0),\n \"MintManager: mint manager cannot be the zero address\"\n );\n\n governanceToken.transferOwnership(_newMintManager);\n }\n}\n" - }, - "contracts/legacy/AddressManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:legacy\n * @title AddressManager\n * @notice AddressManager is a legacy contract that was used in the old version of the Optimism\n * system to manage a registry of string names to addresses. We now use a more standard\n * proxy system instead, but this contract is still necessary for backwards compatibility\n * with several older contracts.\n */\ncontract AddressManager is Ownable {\n /**\n * @notice Mapping of the hashes of string names to addresses.\n */\n mapping(bytes32 => address) private addresses;\n\n /**\n * @notice Emitted when an address is modified in the registry.\n *\n * @param name String name being set in the registry.\n * @param newAddress Address set for the given name.\n * @param oldAddress Address that was previously set for the given name.\n */\n event AddressSet(string indexed name, address newAddress, address oldAddress);\n\n /**\n * @notice Changes the address associated with a particular name.\n *\n * @param _name String name to associate an address with.\n * @param _address Address to associate with the name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n bytes32 nameHash = _getNameHash(_name);\n address oldAddress = addresses[nameHash];\n addresses[nameHash] = _address;\n\n emit AddressSet(_name, _address, oldAddress);\n }\n\n /**\n * @notice Retrieves the address associated with a given name.\n *\n * @param _name Name to retrieve an address for.\n *\n * @return Address associated with the given name.\n */\n function getAddress(string memory _name) external view returns (address) {\n return addresses[_getNameHash(_name)];\n }\n\n /**\n * @notice Computes the hash of a name.\n *\n * @param _name Name to compute a hash for.\n *\n * @return Hash of the given name.\n */\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(_name));\n }\n}\n" - }, - "contracts/legacy/DeployerWhitelist.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000002\n * @title DeployerWhitelist\n * @notice DeployerWhitelist is a legacy contract that was originally used to act as a whitelist of\n * addresses allowed to the Optimism network. The DeployerWhitelist has since been\n * disabled, but the code is kept in state for the sake of full backwards compatibility.\n * As of the Bedrock upgrade, the DeployerWhitelist is completely unused by the Optimism\n * system and could, in theory, be removed entirely.\n */\ncontract DeployerWhitelist is Semver {\n /**\n * @notice Address of the owner of this contract. Note that when this address is set to\n * address(0), the whitelist is disabled.\n */\n address public owner;\n\n /**\n * @notice Mapping of deployer addresses to boolean whitelist status.\n */\n mapping(address => bool) public whitelist;\n\n /**\n * @notice Emitted when the owner of this contract changes.\n *\n * @param oldOwner Address of the previous owner.\n * @param newOwner Address of the new owner.\n */\n event OwnerChanged(address oldOwner, address newOwner);\n\n /**\n * @notice Emitted when the whitelist status of a deployer changes.\n *\n * @param deployer Address of the deployer.\n * @param whitelisted Boolean indicating whether the deployer is whitelisted.\n */\n event WhitelistStatusChanged(address deployer, bool whitelisted);\n\n /**\n * @notice Emitted when the whitelist is disabled.\n *\n * @param oldOwner Address of the final owner of the whitelist.\n */\n event WhitelistDisabled(address oldOwner);\n\n /**\n * @notice Blocks functions to anyone except the contract owner.\n */\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"DeployerWhitelist: function can only be called by the owner of this contract\"\n );\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Adds or removes an address from the deployment whitelist.\n *\n * @param _deployer Address to update permissions for.\n * @param _isWhitelisted Whether or not the address is whitelisted.\n */\n function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external onlyOwner {\n whitelist[_deployer] = _isWhitelisted;\n emit WhitelistStatusChanged(_deployer, _isWhitelisted);\n }\n\n /**\n * @notice Updates the owner of this contract.\n *\n * @param _owner Address of the new owner.\n */\n function setOwner(address _owner) external onlyOwner {\n // Prevent users from setting the whitelist owner to address(0) except via\n // enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to\n // any other address that doesn't have a corresponding knowable private key.\n require(\n _owner != address(0),\n \"DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment\"\n );\n\n emit OwnerChanged(owner, _owner);\n owner = _owner;\n }\n\n /**\n * @notice Permanently enables arbitrary contract deployment and deletes the owner.\n */\n function enableArbitraryContractDeployment() external onlyOwner {\n emit WhitelistDisabled(owner);\n owner = address(0);\n }\n\n /**\n * @notice Checks whether an address is allowed to deploy contracts.\n *\n * @param _deployer Address to check.\n *\n * @return Whether or not the address can deploy contracts.\n */\n function isDeployerAllowed(address _deployer) external view returns (bool) {\n return (owner == address(0) || whitelist[_deployer]);\n }\n}\n" - }, - "contracts/legacy/L1BlockNumber.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000013\n * @title L1BlockNumber\n * @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract\n * in the old version of the Optimism system. Only necessary for backwards compatibility.\n * If you want to access the L1 block number going forward, you should use the L1Block\n * contract instead.\n */\ncontract L1BlockNumber is Semver {\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Returns the L1 block number.\n */\n receive() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Returns the L1 block number.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Retrieves the latest L1 block number.\n *\n * @return Latest L1 block number.\n */\n function getL1BlockNumber() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).number();\n }\n}\n" - }, - "contracts/legacy/L1ChugSplashProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title IL1ChugSplashDeployer\n */\ninterface IL1ChugSplashDeployer {\n function isUpgrading() external view returns (bool);\n}\n\n/**\n * @custom:legacy\n * @title L1ChugSplashProxy\n * @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\n * functions `setCode` and `setStorage` for changing the code or storage of the contract.\n *\n * Note for future developers: do NOT make anything in this contract 'public' unless you\n * know what you're doing. Anything public can potentially have a function signature that\n * conflicts with a signature attached to the implementation contract. Public functions\n * SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good\n * reason not to have that modifier. And there almost certainly is not a good reason to not\n * have that modifier. Beware!\n */\ncontract L1ChugSplashProxy {\n /**\n * @notice \"Magic\" prefix. When prepended to some arbitrary bytecode and used to create a\n * contract, the appended bytecode will be deployed as given.\n */\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice Blocks a function from being called when the parent signals that the system should\n * be paused via an isUpgrading function.\n */\n modifier onlyWhenNotPaused() {\n address owner = _getOwner();\n\n // We do a low-level call because there's no guarantee that the owner actually *is* an\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\n // it turns out that it isn't the right type of contract.\n (bool success, bytes memory returndata) = owner.staticcall(\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)\n );\n\n // If the call was unsuccessful then we assume that there's no \"isUpgrading\" method and we\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\n // long. If this isn't the case then we can safely ignore the result.\n if (success && returndata.length == 32) {\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\n // case that the isUpgrading function returned something other than 0 or 1. But we only\n // really care about the case where this value is 0 (= false).\n uint256 ret = abi.decode(returndata, (uint256));\n require(ret == 0, \"L1ChugSplashProxy: system is currently being upgraded\");\n }\n\n _;\n }\n\n /**\n * @notice Makes a proxy call instead of triggering the given function when the caller is\n * either the owner or the zero address. Caller can only ever be the zero address if\n * this function is being called off-chain via eth_call, which is totally fine and can\n * be convenient for client-side tooling. Avoids situations where the proxy and\n * implementation share a sighash and the proxy function ends up being called instead\n * of the implementation one.\n *\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If\n * there's a way for someone to send a transaction with msg.sender == address(0) in any\n * real context then we have much bigger problems. Primary reason to include this\n * additional allowed sender is because the owner address can be changed dynamically\n * and we do not want clients to have to keep track of the current owner in order to\n * make an eth_call that doesn't trigger the proxied contract.\n */\n // slither-disable-next-line incorrect-modifier\n modifier proxyCallIfNotOwner() {\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @param _owner Address of the initial contract owner.\n */\n constructor(address _owner) {\n _setOwner(_owner);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Sets the code that should be running behind this proxy.\n *\n * Note: This scheme is a bit different from the standard proxy scheme where one would\n * typically deploy the code separately and then set the implementation address. We're\n * doing it this way because it gives us a lot more freedom on the client side. Can\n * only be triggered by the contract owner.\n *\n * @param _code New contract code to run inside this contract.\n */\n function setCode(bytes memory _code) external proxyCallIfNotOwner {\n // Get the code hash of the current implementation.\n address implementation = _getImplementation();\n\n // If the code hash matches the new implementation then we return early.\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\n return;\n }\n\n // Create the deploycode by appending the magic prefix.\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\n\n // Deploy the code and set the new implementation address.\n address newImplementation;\n assembly {\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\n }\n\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\n // actually fail this check. Should only happen if the contract creation from above runs\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\n // should be doing this check anyway though.\n require(\n _getAccountCodeHash(newImplementation) == keccak256(_code),\n \"L1ChugSplashProxy: code was not correctly deployed\"\n );\n\n _setImplementation(newImplementation);\n }\n\n /**\n * @notice Modifies some storage slot within the proxy contract. Gives us a lot of power to\n * perform upgrades in a more transparent way. Only callable by the owner.\n *\n * @param _key Storage key to modify.\n * @param _value New value for the storage key.\n */\n function setStorage(bytes32 _key, bytes32 _value) external proxyCallIfNotOwner {\n assembly {\n sstore(_key, _value)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _owner New owner of the proxy contract.\n */\n function setOwner(address _owner) external proxyCallIfNotOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Queries the owner of the proxy contract. Can only be called by the owner OR by\n * making an eth_call and setting the \"from\" address to address(0).\n *\n * @return Owner address.\n */\n function getOwner() external proxyCallIfNotOwner returns (address) {\n return _getOwner();\n }\n\n /**\n * @notice Queries the implementation address. Can only be called by the owner OR by making an\n * eth_call and setting the \"from\" address to address(0).\n *\n * @return Implementation address.\n */\n function getImplementation() external proxyCallIfNotOwner returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _owner New owner of the proxy contract.\n */\n function _setOwner(address _owner) internal {\n assembly {\n sstore(OWNER_KEY, _owner)\n }\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal onlyWhenNotPaused {\n address implementation = _getImplementation();\n\n require(implementation != address(0), \"L1ChugSplashProxy: implementation is not set yet\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address implementation;\n assembly {\n implementation := sload(IMPLEMENTATION_KEY)\n }\n return implementation;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getOwner() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n\n /**\n * @notice Gets the code hash for a given account.\n *\n * @param _account Address of the account to get a code hash for.\n *\n * @return Code hash for the account.\n */\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\n bytes32 codeHash;\n assembly {\n codeHash := extcodehash(_account)\n }\n return codeHash;\n }\n}\n" - }, - "contracts/legacy/LegacyERC20ETH.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000\n * @title LegacyERC20ETH\n * @notice LegacyERC20ETH is a legacy contract that held ETH balances before the Bedrock upgrade.\n * All ETH balances held within this contract were migrated to the state trie as part of\n * the Bedrock upgrade. Functions within this contract that mutate state were already\n * disabled as part of the EVM equivalence upgrade.\n */\ncontract LegacyERC20ETH is OptimismMintableERC20 {\n /**\n * @notice Initializes the contract as an Optimism Mintable ERC20.\n */\n constructor()\n OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), \"Ether\", \"ETH\")\n {}\n\n /**\n * @notice Returns the ETH balance of the target account. Overrides the base behavior of the\n * contract to preserve the invariant that the balance within this contract always\n * matches the balance in the state trie.\n *\n * @param _who Address of the account to query.\n *\n * @return The ETH balance of the target account.\n */\n function balanceOf(address _who) public view virtual override returns (uint256) {\n return address(_who).balance;\n }\n\n /**\n * @custom:blocked\n * @notice Mints some amount of ETH.\n */\n function mint(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: mint is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Burns some amount of ETH.\n */\n function burn(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: burn is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers some amount of ETH.\n */\n function transfer(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transfer is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Approves a spender to spend some amount of ETH.\n */\n function approve(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: approve is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers funds from some sender account.\n */\n function transferFrom(\n address,\n address,\n uint256\n ) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transferFrom is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Increases the allowance of a spender.\n */\n function increaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Decreases the allowance of a spender.\n */\n function decreaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n }\n}\n" - }, - "contracts/legacy/LegacyMessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000000\n * @title LegacyMessagePasser\n * @notice The LegacyMessagePasser was the low-level mechanism used to send messages from L2 to L1\n * before the Bedrock upgrade. It is now deprecated in favor of the new MessagePasser.\n */\ncontract LegacyMessagePasser is Semver {\n /**\n * @notice Mapping of sent message hashes to boolean status.\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Passes a message to L1.\n *\n * @param _message Message to pass to L1.\n */\n function passMessageToL1(bytes memory _message) external {\n sentMessages[keccak256(abi.encodePacked(_message, msg.sender))] = true;\n }\n}\n" - }, - "contracts/legacy/LegacyMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ILegacyMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @title LegacyMintableERC20\n * @notice The legacy implementation of the OptimismMintableERC20. This\n * contract is deprecated and should no longer be used.\n */\ncontract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {\n /**\n * @notice Emitted when the token is minted by the bridge.\n */\n event Mint(address indexed _account, uint256 _amount);\n\n /**\n * @notice Emitted when a token is burned by the bridge.\n */\n event Burn(address indexed _account, uint256 _amount);\n\n /**\n * @notice The token on the remote domain.\n */\n address public l1Token;\n\n /**\n * @notice The local bridge.\n */\n address public l2Bridge;\n\n /**\n * @param _l2Bridge Address of the L2 standard bridge.\n * @param _l1Token Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _l2Bridge,\n address _l1Token,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) {\n l1Token = _l1Token;\n l2Bridge = _l2Bridge;\n }\n\n /**\n * @notice Modifier that requires the contract was called by the bridge.\n */\n modifier onlyL2Bridge() {\n require(msg.sender == l2Bridge, \"Only L2 Bridge can mint and burn\");\n _;\n }\n\n /**\n * @notice EIP165 implementation.\n */\n function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n\n /**\n * @notice Only the bridge can mint tokens.\n * @param _to The account receiving tokens.\n * @param _amount The amount of tokens to receive.\n */\n function mint(address _to, uint256 _amount) public virtual onlyL2Bridge {\n _mint(_to, _amount);\n\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Only the bridge can burn tokens.\n * @param _from The account having tokens burnt.\n * @param _amount The amount of tokens being burnt.\n */\n function burn(address _from, uint256 _amount) public virtual onlyL2Bridge {\n _burn(_from, _amount);\n\n emit Burn(_from, _amount);\n }\n}\n" - }, - "contracts/legacy/ResolvedDelegateProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressManager } from \"./AddressManager.sol\";\n\n/**\n * @custom:legacy\n * @title ResolvedDelegateProxy\n * @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to\n * resolve the implementation address. We're maintaining this contract for backwards\n * compatibility so we can manage all legacy proxies where necessary.\n */\ncontract ResolvedDelegateProxy {\n /**\n * @notice Mapping used to store the implementation name that corresponds to this contract. A\n * mapping was originally used as a way to bypass the same issue normally solved by\n * storing the implementation address in a specific storage slot that does not conflict\n * with any other storage slot. Generally NOT a safe solution but works as long as the\n * implementation does not also keep a mapping in the first storage slot.\n */\n mapping(address => string) private implementationName;\n\n /**\n * @notice Mapping used to store the address of the AddressManager contract where the\n * implementation address will be resolved from. Same concept here as with the above\n * mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping\n * in the second storage slot.\n */\n mapping(address => AddressManager) private addressManager;\n\n /**\n * @param _addressManager Address of the AddressManager.\n * @param _implementationName implementationName of the contract to proxy to.\n */\n constructor(AddressManager _addressManager, string memory _implementationName) {\n addressManager[address(this)] = _addressManager;\n implementationName[address(this)] = _implementationName;\n }\n\n /**\n * @notice Fallback, performs a delegatecall to the resolved implementation address.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n address target = addressManager[address(this)].getAddress(\n (implementationName[address(this)])\n );\n\n require(target != address(0), \"ResolvedDelegateProxy: target address must be initialized\");\n\n // slither-disable-next-line controlled-delegatecall\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\n\n if (success == true) {\n assembly {\n return(add(returndata, 0x20), mload(returndata))\n }\n } else {\n assembly {\n revert(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n" - }, - "contracts/libraries/Arithmetic.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { SignedMath } from \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport { FixedPointMathLib } from \"@rari-capital/solmate/src/utils/FixedPointMathLib.sol\";\n\n/**\n * @title Arithmetic\n * @notice Even more math than before.\n */\nlibrary Arithmetic {\n /**\n * @notice Clamps a value between a minimum and maximum.\n *\n * @param _value The value to clamp.\n * @param _min The minimum value.\n * @param _max The maximum value.\n *\n * @return The clamped value.\n */\n function clamp(\n int256 _value,\n int256 _min,\n int256 _max\n ) internal pure returns (int256) {\n return SignedMath.min(SignedMath.max(_value, _min), _max);\n }\n\n /**\n * @notice (c)oefficient (d)enominator (exp)onentiation function.\n * Returns the result of: c * (1 - 1/d)^exp.\n *\n * @param _coefficient Coefficient of the function.\n * @param _denominator Fractional denominator.\n * @param _exponent Power function exponent.\n *\n * @return Result of c * (1 - 1/d)^exp.\n */\n function cdexp(\n int256 _coefficient,\n int256 _denominator,\n int256 _exponent\n ) internal pure returns (int256) {\n return\n (_coefficient *\n (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;\n }\n}\n" - }, - "contracts/libraries/Burn.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Burn\n * @notice Utilities for burning stuff.\n */\nlibrary Burn {\n /**\n * Burns a given amount of ETH.\n *\n * @param _amount Amount of ETH to burn.\n */\n function eth(uint256 _amount) internal {\n new Burner{ value: _amount }();\n }\n\n /**\n * Burns a given amount of gas.\n *\n * @param _amount Amount of gas to burn.\n */\n function gas(uint256 _amount) internal view {\n uint256 i = 0;\n uint256 initialGas = gasleft();\n while (initialGas - gasleft() < _amount) {\n ++i;\n }\n }\n}\n\n/**\n * @title Burner\n * @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to\n * the contract from the circulating supply. Self-destructing is the only way to remove ETH\n * from the circulating supply.\n */\ncontract Burner {\n constructor() payable {\n selfdestruct(payable(address(this)));\n }\n}\n" - }, - "contracts/libraries/Bytes.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Bytes\n * @notice Bytes is a library for manipulating byte arrays.\n */\nlibrary Bytes {\n /**\n * @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\n * @notice Slices a byte array with a given starting index and length. Returns a new byte array\n * as opposed to a pointer to the original array. Will throw if trying to slice more\n * bytes than exist in the array.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n * @param _length Length of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n ) internal pure returns (bytes memory) {\n unchecked {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_start + _length >= _start, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n }\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n /**\n * @notice Slices a byte array with a given starting index up to the end of the original byte\n * array. Returns a new array rathern than a pointer to the original.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\n if (_start >= _bytes.length) {\n return bytes(\"\");\n }\n return slice(_bytes, _start, _bytes.length - _start);\n }\n\n /**\n * @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.\n * Resulting nibble array will be exactly twice as long as the input byte array.\n *\n * @param _bytes Input byte array to convert.\n *\n * @return Resulting nibble array.\n */\n function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n uint256 bytesLength = _bytes.length;\n bytes memory nibbles = new bytes(bytesLength * 2);\n bytes1 b;\n\n for (uint256 i = 0; i < bytesLength; ) {\n b = _bytes[i];\n nibbles[i * 2] = b >> 4;\n nibbles[i * 2 + 1] = b & 0x0f;\n unchecked {\n ++i;\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Compares two byte arrays by comparing their keccak256 hashes.\n *\n * @param _bytes First byte array to compare.\n * @param _other Second byte array to compare.\n *\n * @return True if the two byte arrays are equal, false otherwise.\n */\n function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n return keccak256(_bytes) == keccak256(_other);\n }\n}\n" - }, - "contracts/libraries/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n/**\n * @title Constants\n * @notice Constants is a library for storing constants. Simple! Don't put everything in here, just\n * the stuff used in multiple contracts. Constants that only apply to a single contract\n * should be defined in that contract instead.\n */\nlibrary Constants {\n /**\n * @notice Special address to be used as the tx origin for gas estimation calls in the\n * OptimismPortal and CrossDomainMessenger calls. You only need to use this address if\n * the minimum gas limit specified by the user is not actually enough to execute the\n * given message and you're attempting to estimate the actual necessary gas limit. We\n * use address(1) because it's the ecrecover precompile and therefore guaranteed to\n * never have any code on any EVM chain.\n */\n address internal constant ESTIMATION_ADDRESS = address(1);\n\n /**\n * @notice Value used for the L2 sender storage slot in both the OptimismPortal and the\n * CrossDomainMessenger contracts before an actual sender is set. This value is\n * non-zero to reduce the gas cost of message passing transactions.\n */\n address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;\n\n /**\n * @notice Returns the default values for the ResourceConfig. These are the recommended values\n * for a production network.\n */\n function DEFAULT_RESOURCE_CONFIG()\n internal\n pure\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n return config;\n }\n}\n" - }, - "contracts/libraries/DisputeErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"./DisputeTypes.sol\";\n\n////////////////////////////////////////////////////////////////\n// `DisputeGameFactory` Errors //\n////////////////////////////////////////////////////////////////\n\n/**\n * @notice Thrown when a dispute game is attempted to be created with an unsupported game type.\n * @param gameType The unsupported game type.\n */\nerror NoImplementation(GameType gameType);\n\n/**\n * @notice Thrown when a dispute game that already exists is attempted to be created.\n * @param uuid The UUID of the dispute game that already exists.\n */\nerror GameAlreadyExists(Hash uuid);\n\n////////////////////////////////////////////////////////////////\n// `DisputeGame_Fault.sol` Errors //\n////////////////////////////////////////////////////////////////\n\n/**\n * @notice Thrown when a supplied bond is too low to cover the\n * cost of the next possible counter claim.\n */\nerror BondTooLow();\n\n/**\n * @notice Thrown when a defense against the root claim is attempted.\n */\nerror CannotDefendRootClaim();\n\n/**\n * @notice Thrown when a claim is attempting to be made that already exists.\n */\nerror ClaimAlreadyExists();\n\n////////////////////////////////////////////////////////////////\n// `AttestationDisputeGame` Errors //\n////////////////////////////////////////////////////////////////\n\n/**\n * @notice Thrown when an invalid signature is submitted to `challenge`.\n */\nerror InvalidSignature();\n\n/**\n * @notice Thrown when a signature that has already been used to support the\n * `rootClaim` is submitted to `challenge`.\n */\nerror AlreadyChallenged();\n\n////////////////////////////////////////////////////////////////\n// `Ownable` Errors //\n////////////////////////////////////////////////////////////////\n\n/**\n * @notice Thrown when a function that is protected by the `onlyOwner` modifier\n * is called from an account other than the owner.\n */\nerror NotOwner();\n" - }, - "contracts/libraries/DisputeTypes.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\n/**\n * @notice A custom type for a generic hash.\n */\ntype Hash is bytes32;\n\n/**\n * @notice A claim represents an MPT root representing the state of the fault proof program.\n */\ntype Claim is bytes32;\n\n/**\n * @notice A claim hash represents a hash of a claim and a position within the game tree.\n * @dev Keccak hash of abi.encodePacked(Claim, Position);\n */\ntype ClaimHash is bytes32;\n\n/**\n * @notice A bondamount represents the amount of collateral that a user has locked up in a claim.\n */\ntype BondAmount is uint256;\n\n/**\n * @notice A dedicated timestamp type.\n */\ntype Timestamp is uint64;\n\n/**\n * @notice A dedicated duration type.\n * @dev Unit: seconds\n */\ntype Duration is uint64;\n\n/**\n * @notice A `Clock` represents a packed `Duration` and `Timestamp`\n * @dev The packed layout of this type is as follows:\n * ┌────────────┬────────────────┐\n * │ Bits │ Value │\n * ├────────────┼────────────────┤\n * │ [0, 128) │ Duration │\n * │ [128, 256) │ Timestamp │\n * └────────────┴────────────────┘\n */\ntype Clock is uint256;\n\n/**\n * @notice A `Position` represents a position of a claim within the game tree.\n * @dev The packed layout of this type is as follows:\n * ┌────────────┬────────────────┐\n * │ Bits │ Value │\n * ├────────────┼────────────────┤\n * │ [0, 128) │ Depth │\n * │ [128, 256) │ Index at depth │\n * └────────────┴────────────────┘\n */\ntype Position is uint256;\n\n/**\n * @notice The current status of the dispute game.\n */\nenum GameStatus {\n // The game is currently in progress, and has not been resolved.\n IN_PROGRESS,\n // The game has concluded, and the `rootClaim` was challenged successfully.\n CHALLENGER_WINS,\n // The game has concluded, and the `rootClaim` could not be contested.\n DEFENDER_WINS\n}\n\n/**\n * @notice The type of proof system being used.\n */\nenum GameType {\n // The game will use a `IDisputeGame` implementation that utilizes fault proofs.\n FAULT,\n // The game will use a `IDisputeGame` implementation that utilizes validity proofs.\n VALIDITY,\n // The game will use a `IDisputeGame` implementation that utilizes attestation proofs.\n ATTESTATION\n}\n" - }, - "contracts/libraries/Encoding.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Hashing } from \"./Hashing.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\n\n/**\n * @title Encoding\n * @notice Encoding handles Optimism's various different encoding schemes.\n */\nlibrary Encoding {\n /**\n * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\n * to the L2 system. Useful for searching for a deposit in the L2 system. The\n * transaction is prefixed with 0x7e to identify its EIP-2718 type.\n *\n * @param _tx User deposit transaction to encode.\n *\n * @return RLP encoded L2 deposit transaction.\n */\n function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes memory)\n {\n bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\n bytes[] memory raw = new bytes[](8);\n raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\n raw[1] = RLPWriter.writeAddress(_tx.from);\n raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\"\") : RLPWriter.writeAddress(_tx.to);\n raw[3] = RLPWriter.writeUint(_tx.mint);\n raw[4] = RLPWriter.writeUint(_tx.value);\n raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\n raw[6] = RLPWriter.writeBool(false);\n raw[7] = RLPWriter.writeBytes(_tx.data);\n return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\n }\n\n /**\n * @notice Encodes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n (, uint16 version) = decodeVersionedNonce(_nonce);\n if (version == 0) {\n return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Encoding: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Encodes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _data,\n _nonce\n );\n }\n\n /**\n * @notice Encodes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(uint256,address,address,uint256,uint256,bytes)\",\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n }\n\n /**\n * @notice Adds a version number into the first two bytes of a message nonce.\n *\n * @param _nonce Message nonce to encode into.\n * @param _version Version number to encode into the message nonce.\n *\n * @return Message nonce with version encoded into the first two bytes.\n */\n function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\n uint256 nonce;\n assembly {\n nonce := or(shl(240, _version), _nonce)\n }\n return nonce;\n }\n\n /**\n * @notice Pulls the version out of a version-encoded nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n *\n * @return Nonce without encoded version.\n * @return Version of the message.\n */\n function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\n uint240 nonce;\n uint16 version;\n assembly {\n nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n version := shr(240, _nonce)\n }\n return (nonce, version);\n }\n}\n" - }, - "contracts/libraries/Hashing.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Encoding } from \"./Encoding.sol\";\n\n/**\n * @title Hashing\n * @notice Hashing handles Optimism's various different hashing schemes.\n */\nlibrary Hashing {\n /**\n * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\n * given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\n * system.\n *\n * @param _tx User deposit transaction to hash.\n *\n * @return Hash of the RLP encoded L2 deposit transaction.\n */\n function hashDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return keccak256(Encoding.encodeDepositTransaction(_tx));\n }\n\n /**\n * @notice Computes the deposit transaction's \"source hash\", a value that guarantees the hash\n * of the L2 transaction that corresponds to a deposit is unique and is\n * deterministically generated from L1 transaction data.\n *\n * @param _l1BlockHash Hash of the L1 block where the deposit was included.\n * @param _logIndex The index of the log that created the deposit transaction.\n *\n * @return Hash of the deposit transaction's \"source hash\".\n */\n function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)\n internal\n pure\n returns (bytes32)\n {\n bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\n return keccak256(abi.encode(bytes32(0), depositId));\n }\n\n /**\n * @notice Hashes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n if (version == 0) {\n return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Hashing: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Hashes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes32) {\n return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));\n }\n\n /**\n * @notice Hashes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n return\n keccak256(\n Encoding.encodeCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n )\n );\n }\n\n /**\n * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\n *\n * @param _tx Withdrawal transaction to hash.\n *\n * @return Hashed withdrawal transaction.\n */\n function hashWithdrawal(Types.WithdrawalTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\n );\n }\n\n /**\n * @notice Hashes the various elements of an output root proof into an output root hash which\n * can be used to check if the proof is valid.\n *\n * @param _outputRootProof Output root proof which should hash to an output root.\n *\n * @return Hashed output root proof.\n */\n function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(\n _outputRootProof.version,\n _outputRootProof.stateRoot,\n _outputRootProof.messagePasserStorageRoot,\n _outputRootProof.latestBlockhash\n )\n );\n }\n}\n" - }, - "contracts/libraries/LegacyCrossDomainUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n// Importing from the legacy contracts package causes issues with the build of the contract bindings\n// so we just copy the library here from\n// /packages/contracts/contracts/libraries/bridge/Lib_CrossDomainUtils.sol at commit\n// 7866168c\n/**\n * @title LegacyCrossDomainUtils\n */\nlibrary LegacyCrossDomainUtils {\n /**\n * Generates the correct cross domain calldata for a message.\n * @param _target Target contract address.\n * @param _sender Message sender address.\n * @param _message Message to send to the target.\n * @param _messageNonce Nonce for the provided message.\n * @return ABI encoded cross domain calldata.\n */\n function encodeXDomainCalldata(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _message,\n _messageNonce\n );\n }\n}\n" - }, - "contracts/libraries/Predeploys.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Predeploys\n * @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.\n */\nlibrary Predeploys {\n /**\n * @notice Address of the L2ToL1MessagePasser predeploy.\n */\n address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;\n\n /**\n * @notice Address of the L2CrossDomainMessenger predeploy.\n */\n address internal constant L2_CROSS_DOMAIN_MESSENGER =\n 0x4200000000000000000000000000000000000007;\n\n /**\n * @notice Address of the L2StandardBridge predeploy.\n */\n address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\n\n /**\n * @notice Address of the L2ERC721Bridge predeploy.\n */\n address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;\n\n /**\n * @notice Address of the SequencerFeeWallet predeploy.\n */\n address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;\n\n /**\n * @notice Address of the OptimismMintableERC20Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY =\n 0x4200000000000000000000000000000000000012;\n\n /**\n * @notice Address of the OptimismMintableERC721Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY =\n 0x4200000000000000000000000000000000000017;\n\n /**\n * @notice Address of the L1Block predeploy.\n */\n address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;\n\n /**\n * @notice Address of the GasPriceOracle predeploy. Includes fee information\n * and helpers for computing the L1 portion of the transaction fee.\n */\n address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;\n\n /**\n * @custom:legacy\n * @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger\n * or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.\n */\n address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\n\n /**\n * @custom:legacy\n * @notice Address of the DeployerWhitelist predeploy. No longer active.\n */\n address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the\n * state trie as of the Bedrock upgrade. Contract has been locked and write functions\n * can no longer be accessed.\n */\n address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;\n\n /**\n * @custom:legacy\n * @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy\n * instead, which exposes more information about the L1 state.\n */\n address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated\n * L2ToL1MessagePasser contract instead.\n */\n address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\n\n /**\n * @notice Address of the ProxyAdmin predeploy.\n */\n address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;\n\n /**\n * @notice Address of the BaseFeeVault predeploy.\n */\n address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;\n\n /**\n * @notice Address of the L1FeeVault predeploy.\n */\n address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;\n\n /**\n * @notice Address of the GovernanceToken predeploy.\n */\n address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042;\n}\n" - }, - "contracts/libraries/SafeCall.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title SafeCall\n * @notice Perform low level safe calls\n */\nlibrary SafeCall {\n /**\n * @notice Performs a low level call without copying any returndata.\n * @dev Passes no calldata to the call context.\n *\n * @param _target Address to call\n * @param _gas Amount of gas to pass to the call\n * @param _value Amount of value to pass to the call\n */\n function send(\n address _target,\n uint256 _gas,\n uint256 _value\n ) internal returns (bool) {\n bool _success;\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n 0, // inloc\n 0, // inlen\n 0, // outloc\n 0 // outlen\n )\n }\n return _success;\n }\n\n /**\n * @notice Perform a low level call without copying any returndata\n *\n * @param _target Address to call\n * @param _gas Amount of gas to pass to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function call(\n address _target,\n uint256 _gas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n }\n return _success;\n }\n\n /**\n * @notice Helper function to determine if there is sufficient gas remaining within the context\n * to guarantee that the minimum gas requirement for a call will be met as well as\n * optionally reserving a specified amount of gas for after the call has concluded.\n * @param _minGas The minimum amount of gas that may be passed to the target context.\n * @param _reservedGas Optional amount of gas to reserve for the caller after the execution\n * of the target context.\n * @return `true` if there is enough gas remaining to safely supply `_minGas` to the target\n * context as well as reserve `_reservedGas` for the caller after the execution of\n * the target context.\n * @dev !!!!! FOOTGUN ALERT !!!!!\n * 1.) The 40_000 base buffer is to account for the worst case of the dynamic cost of the\n * `CALL` opcode's `address_access_cost`, `positive_value_cost`, and\n * `value_to_empty_account_cost` factors with an added buffer of 5,700 gas. It is\n * still possible to self-rekt by initiating a withdrawal with a minimum gas limit\n * that does not account for the `memory_expansion_cost` & `code_execution_cost`\n * factors of the dynamic cost of the `CALL` opcode.\n * 2.) This function should *directly* precede the external call if possible. There is an\n * added buffer to account for gas consumed between this check and the call, but it\n * is only 5,700 gas.\n * 3.) Because EIP-150 ensures that a maximum of 63/64ths of the remaining gas in the call\n * frame may be passed to a subcontext, we need to ensure that the gas will not be\n * truncated.\n * 4.) Use wisely. This function is not a silver bullet.\n */\n function hasMinGas(uint256 _minGas, uint256 _reservedGas) internal view returns (bool) {\n bool _hasMinGas;\n assembly {\n // Equation: gas × 63 ≥ minGas × 64 + 63(40_000 + reservedGas)\n _hasMinGas := iszero(\n lt(mul(gas(), 63), add(mul(_minGas, 64), mul(add(40000, _reservedGas), 63)))\n )\n }\n return _hasMinGas;\n }\n\n /**\n * @notice Perform a low level call without copying any returndata. This function\n * will revert if the call cannot be performed with the specified minimum\n * gas.\n *\n * @param _target Address to call\n * @param _minGas The minimum amount of gas that may be passed to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function callWithMinGas(\n address _target,\n uint256 _minGas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n bool _hasMinGas = hasMinGas(_minGas, 0);\n assembly {\n // Assertion: gasleft() >= (_minGas * 64) / 63 + 40_000\n if iszero(_hasMinGas) {\n // Store the \"Error(string)\" selector in scratch space.\n mstore(0, 0x08c379a0)\n // Store the pointer to the string length in scratch space.\n mstore(32, 32)\n // Store the string.\n //\n // SAFETY:\n // - We pad the beginning of the string with two zero bytes as well as the\n // length (24) to ensure that we override the free memory pointer at offset\n // 0x40. This is necessary because the free memory pointer is likely to\n // be greater than 1 byte when this function is called, but it is incredibly\n // unlikely that it will be greater than 3 bytes. As for the data within\n // 0x60, it is ensured that it is 0 due to 0x60 being the zero offset.\n // - It's fine to clobber the free memory pointer, we're reverting.\n mstore(88, 0x0000185361666543616c6c3a204e6f7420656e6f75676820676173)\n\n // Revert with 'Error(\"SafeCall: Not enough gas\")'\n revert(28, 100)\n }\n\n // The call will be supplied at least ((_minGas * 64) / 63) gas due to the\n // above assertion. This ensures that, in all circumstances (except for when the\n // `_minGas` does not account for the `memory_expansion_cost` and `code_execution_cost`\n // factors of the dynamic cost of the `CALL` opcode), the call will receive at least\n // the minimum amount of gas specified.\n _success := call(\n gas(), // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0x00, // outloc\n 0x00 // outlen\n )\n }\n return _success;\n }\n}\n" - }, - "contracts/libraries/Types.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Types\n * @notice Contains various types used throughout the Optimism contract system.\n */\nlibrary Types {\n /**\n * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\n * timestamp that the output root is posted. This timestamp is used to verify that the\n * finalization period has passed since the output root was submitted.\n *\n * @custom:field outputRoot Hash of the L2 output.\n * @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.\n * @custom:field l2BlockNumber L2 block number that the output corresponds to.\n */\n struct OutputProposal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2BlockNumber;\n }\n\n /**\n * @notice Struct representing the elements that are hashed together to generate an output root\n * which itself represents a snapshot of the L2 state.\n *\n * @custom:field version Version of the output root.\n * @custom:field stateRoot Root of the state trie at the block of this output.\n * @custom:field messagePasserStorageRoot Root of the message passer storage trie.\n * @custom:field latestBlockhash Hash of the block this output was generated from.\n */\n struct OutputRootProof {\n bytes32 version;\n bytes32 stateRoot;\n bytes32 messagePasserStorageRoot;\n bytes32 latestBlockhash;\n }\n\n /**\n * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n * user (as opposed to a system deposit transaction generated by the system).\n *\n * @custom:field from Address of the sender of the transaction.\n * @custom:field to Address of the recipient of the transaction.\n * @custom:field isCreation True if the transaction is a contract creation.\n * @custom:field value Value to send to the recipient.\n * @custom:field mint Amount of ETH to mint.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n * @custom:field l1BlockHash Hash of the block the transaction was submitted in.\n * @custom:field logIndex Index of the log in the block the transaction was submitted in.\n */\n struct UserDepositTransaction {\n address from;\n address to;\n bool isCreation;\n uint256 value;\n uint256 mint;\n uint64 gasLimit;\n bytes data;\n bytes32 l1BlockHash;\n uint256 logIndex;\n }\n\n /**\n * @notice Struct representing a withdrawal transaction.\n *\n * @custom:field nonce Nonce of the withdrawal transaction\n * @custom:field sender Address of the sender of the transaction.\n * @custom:field target Address of the recipient of the transaction.\n * @custom:field value Value to send to the recipient.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n */\n struct WithdrawalTransaction {\n uint256 nonce;\n address sender;\n address target;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPReader.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\n/**\n * @custom:attribution https://github.com/hamdiallam/Solidity-RLP\n * @title RLPReader\n * @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted\n * from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with\n * various tweaks to improve readability.\n */\nlibrary RLPReader {\n /**\n * Custom pointer type to avoid confusion between pointers and uint256s.\n */\n type MemoryPointer is uint256;\n\n /**\n * @notice RLP item types.\n *\n * @custom:value DATA_ITEM Represents an RLP data item (NOT a list).\n * @custom:value LIST_ITEM Represents an RLP list item.\n */\n enum RLPItemType {\n DATA_ITEM,\n LIST_ITEM\n }\n\n /**\n * @notice Struct representing an RLP item.\n *\n * @custom:field length Length of the RLP item.\n * @custom:field ptr Pointer to the RLP item in memory.\n */\n struct RLPItem {\n uint256 length;\n MemoryPointer ptr;\n }\n\n /**\n * @notice Max list length that this library will accept.\n */\n uint256 internal constant MAX_LIST_LENGTH = 32;\n\n /**\n * @notice Converts bytes to a reference to memory position and length.\n *\n * @param _in Input bytes to convert.\n *\n * @return Output memory reference.\n */\n function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n // Empty arrays are not RLP items.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr;\n assembly {\n ptr := add(_in, 32)\n }\n\n return RLPItem({ length: _in.length, ptr: ptr });\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.LIST_ITEM,\n \"RLPReader: decoded item type for list is not a list item\"\n );\n\n require(\n listOffset + listLength == _in.length,\n \"RLPReader: list item has an invalid data remainder\"\n );\n\n // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n // writing to the length. Since we can't know the number of RLP items without looping over\n // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n // simply set a reasonable maximum list length and decrease the size before we finish.\n RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n uint256 itemCount = 0;\n uint256 offset = listOffset;\n while (offset < _in.length) {\n (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n RLPItem({\n length: _in.length - offset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n })\n );\n\n // We don't need to check itemCount < out.length explicitly because Solidity already\n // handles this check on our behalf, we'd just be wasting gas.\n out[itemCount] = RLPItem({\n length: itemLength + itemOffset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n });\n\n itemCount += 1;\n offset += itemOffset + itemLength;\n }\n\n // Decrease the array size to match the actual item count.\n assembly {\n mstore(out, itemCount)\n }\n\n return out;\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n return readList(toRLPItem(_in));\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.DATA_ITEM,\n \"RLPReader: decoded item type for bytes is not a data item\"\n );\n\n require(\n _in.length == itemOffset + itemLength,\n \"RLPReader: bytes value contains an invalid remainder\"\n );\n\n return _copy(_in.ptr, itemOffset, itemLength);\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n return readBytes(toRLPItem(_in));\n }\n\n /**\n * @notice Reads the raw bytes of an RLP item.\n *\n * @param _in RLP item to read.\n *\n * @return Raw RLP bytes.\n */\n function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n return _copy(_in.ptr, 0, _in.length);\n }\n\n /**\n * @notice Decodes the length of an RLP item.\n *\n * @param _in RLP item to decode.\n *\n * @return Offset of the encoded data.\n * @return Length of the encoded data.\n * @return RLP item type (LIST_ITEM or DATA_ITEM).\n */\n function _decodeLength(RLPItem memory _in)\n private\n pure\n returns (\n uint256,\n uint256,\n RLPItemType\n )\n {\n // Short-circuit if there's nothing to decode, note that we perform this check when\n // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass\n // that function and create an RLP item directly. So we need to check this anyway.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr = _in.ptr;\n uint256 prefix;\n assembly {\n prefix := byte(0, mload(ptr))\n }\n\n if (prefix <= 0x7f) {\n // Single byte.\n return (0, 1, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xb7) {\n // Short string.\n\n // slither-disable-next-line variable-scope\n uint256 strLen = prefix - 0x80;\n\n require(\n _in.length > strLen,\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n strLen != 1 || firstByteOfContent >= 0x80,\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n\n return (1, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xbf) {\n // Long string.\n uint256 lenOfStrLen = prefix - 0xb7;\n\n require(\n _in.length > lenOfStrLen,\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n\n uint256 strLen;\n assembly {\n strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))\n }\n\n require(\n strLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long string)\"\n );\n\n require(\n _in.length > lenOfStrLen + strLen,\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n\n return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xf7) {\n // Short list.\n // slither-disable-next-line variable-scope\n uint256 listLen = prefix - 0xc0;\n\n require(\n _in.length > listLen,\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n\n return (1, listLen, RLPItemType.LIST_ITEM);\n } else {\n // Long list.\n uint256 lenOfListLen = prefix - 0xf7;\n\n require(\n _in.length > lenOfListLen,\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long list)\"\n );\n\n uint256 listLen;\n assembly {\n listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))\n }\n\n require(\n listLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long list)\"\n );\n\n require(\n _in.length > lenOfListLen + listLen,\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n\n return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n }\n }\n\n /**\n * @notice Copies the bytes from a memory location.\n *\n * @param _src Pointer to the location to read from.\n * @param _offset Offset to start reading from.\n * @param _length Number of bytes to read.\n *\n * @return Copied bytes.\n */\n function _copy(\n MemoryPointer _src,\n uint256 _offset,\n uint256 _length\n ) private pure returns (bytes memory) {\n bytes memory out = new bytes(_length);\n if (_length == 0) {\n return out;\n }\n\n // Mostly based on Solidity's copy_memory_to_memory:\n // solhint-disable max-line-length\n // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114\n uint256 src = MemoryPointer.unwrap(_src) + _offset;\n assembly {\n let dest := add(out, 32)\n let i := 0\n for {\n\n } lt(i, _length) {\n i := add(i, 32)\n } {\n mstore(add(dest, i), mload(add(src, i)))\n }\n\n if gt(i, _length) {\n mstore(add(dest, _length), 0)\n }\n }\n\n return out;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPWriter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\n * @title RLPWriter\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\n * RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\n * modifications to improve legibility.\n */\nlibrary RLPWriter {\n /**\n * @notice RLP encodes a byte string.\n *\n * @param _in The byte string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_in.length == 1 && uint8(_in[0]) < 128) {\n encoded = _in;\n } else {\n encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n }\n\n return encoded;\n }\n\n /**\n * @notice RLP encodes a list of RLP encoded byte byte strings.\n *\n * @param _in The list of RLP encoded byte strings.\n *\n * @return The RLP encoded list of items in bytes.\n */\n function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n bytes memory list = _flatten(_in);\n return abi.encodePacked(_writeLength(list.length, 192), list);\n }\n\n /**\n * @notice RLP encodes a string.\n *\n * @param _in The string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeString(string memory _in) internal pure returns (bytes memory) {\n return writeBytes(bytes(_in));\n }\n\n /**\n * @notice RLP encodes an address.\n *\n * @param _in The address to encode.\n *\n * @return The RLP encoded address in bytes.\n */\n function writeAddress(address _in) internal pure returns (bytes memory) {\n return writeBytes(abi.encodePacked(_in));\n }\n\n /**\n * @notice RLP encodes a uint.\n *\n * @param _in The uint256 to encode.\n *\n * @return The RLP encoded uint256 in bytes.\n */\n function writeUint(uint256 _in) internal pure returns (bytes memory) {\n return writeBytes(_toBinary(_in));\n }\n\n /**\n * @notice RLP encodes a bool.\n *\n * @param _in The bool to encode.\n *\n * @return The RLP encoded bool in bytes.\n */\n function writeBool(bool _in) internal pure returns (bytes memory) {\n bytes memory encoded = new bytes(1);\n encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n return encoded;\n }\n\n /**\n * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\n *\n * @param _len The length of the string or the payload.\n * @param _offset 128 if item is string, 192 if item is list.\n *\n * @return RLP encoded bytes.\n */\n function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_len < 56) {\n encoded = new bytes(1);\n encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n } else {\n uint256 lenLen;\n uint256 i = 1;\n while (_len / i != 0) {\n lenLen++;\n i *= 256;\n }\n\n encoded = new bytes(lenLen + 1);\n encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n for (i = 1; i <= lenLen; i++) {\n encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n }\n }\n\n return encoded;\n }\n\n /**\n * @notice Encode integer in big endian binary form with no leading zeroes.\n *\n * @param _x The integer to encode.\n *\n * @return RLP encoded bytes.\n */\n function _toBinary(uint256 _x) private pure returns (bytes memory) {\n bytes memory b = abi.encodePacked(_x);\n\n uint256 i = 0;\n for (; i < 32; i++) {\n if (b[i] != 0) {\n break;\n }\n }\n\n bytes memory res = new bytes(32 - i);\n for (uint256 j = 0; j < res.length; j++) {\n res[j] = b[i++];\n }\n\n return res;\n }\n\n /**\n * @custom:attribution https://github.com/Arachnid/solidity-stringutils\n * @notice Copies a piece of memory to another location.\n *\n * @param _dest Destination location.\n * @param _src Source location.\n * @param _len Length of memory to copy.\n */\n function _memcpy(\n uint256 _dest,\n uint256 _src,\n uint256 _len\n ) private pure {\n uint256 dest = _dest;\n uint256 src = _src;\n uint256 len = _len;\n\n for (; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n uint256 mask;\n unchecked {\n mask = 256**(32 - len) - 1;\n }\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /**\n * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\n * @notice Flattens a list of byte strings into one byte string.\n *\n * @param _list List of byte strings to flatten.\n *\n * @return The flattened byte string.\n */\n function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n if (_list.length == 0) {\n return new bytes(0);\n }\n\n uint256 len;\n uint256 i = 0;\n for (; i < _list.length; i++) {\n len += _list[i].length;\n }\n\n bytes memory flattened = new bytes(len);\n uint256 flattenedPtr;\n assembly {\n flattenedPtr := add(flattened, 0x20)\n }\n\n for (i = 0; i < _list.length; i++) {\n bytes memory item = _list[i];\n\n uint256 listPtr;\n assembly {\n listPtr := add(item, 0x20)\n }\n\n _memcpy(flattenedPtr, listPtr, item.length);\n flattenedPtr += _list[i].length;\n }\n\n return flattened;\n }\n}\n" - }, - "contracts/libraries/trie/MerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Bytes } from \"../Bytes.sol\";\nimport { RLPReader } from \"../rlp/RLPReader.sol\";\n\n/**\n * @title MerkleTrie\n * @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie\n * inclusion proofs. By default, this library assumes a hexary trie. One can change the\n * trie radix constant to support other trie radixes.\n */\nlibrary MerkleTrie {\n /**\n * @notice Struct representing a node in the trie.\n *\n * @custom:field encoded The RLP-encoded node.\n * @custom:field decoded The RLP-decoded node.\n */\n struct TrieNode {\n bytes encoded;\n RLPReader.RLPItem[] decoded;\n }\n\n /**\n * @notice Determines the number of elements per branch node.\n */\n uint256 internal constant TREE_RADIX = 16;\n\n /**\n * @notice Branch nodes have TREE_RADIX elements and one value element.\n */\n uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\n\n /**\n * @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.\n */\n uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\n\n /**\n * @notice Prefix for even-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_EVEN = 0;\n\n /**\n * @notice Prefix for odd-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_ODD = 1;\n\n /**\n * @notice Prefix for even-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_EVEN = 2;\n\n /**\n * @notice Prefix for odd-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_ODD = 3;\n\n /**\n * @notice Verifies a proof that a given key/value pair is present in the trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n return Bytes.equal(_value, get(_key, _proof, _root));\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n require(_key.length > 0, \"MerkleTrie: empty key\");\n\n TrieNode[] memory proof = _parseProof(_proof);\n bytes memory key = Bytes.toNibbles(_key);\n bytes memory currentNodeID = abi.encodePacked(_root);\n uint256 currentKeyIndex = 0;\n\n // Proof is top-down, so we start at the first element (root).\n for (uint256 i = 0; i < proof.length; i++) {\n TrieNode memory currentNode = proof[i];\n\n // Key index should never exceed total key length or we'll be out of bounds.\n require(\n currentKeyIndex <= key.length,\n \"MerkleTrie: key index exceeds total key length\"\n );\n\n if (currentKeyIndex == 0) {\n // First proof element is always the root node.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid root hash\"\n );\n } else if (currentNode.encoded.length >= 32) {\n // Nodes 32 bytes or larger are hashed inside branch nodes.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid large internal hash\"\n );\n } else {\n // Nodes smaller than 32 bytes aren't hashed.\n require(\n Bytes.equal(currentNode.encoded, currentNodeID),\n \"MerkleTrie: invalid internal node hash\"\n );\n }\n\n if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\n if (currentKeyIndex == key.length) {\n // Value is the last element of the decoded list (for branch nodes). There's\n // some ambiguity in the Merkle trie specification because bytes(0) is a\n // valid value to place into the trie, but for branch nodes bytes(0) can exist\n // even when the value wasn't explicitly placed there. Geth treats a value of\n // bytes(0) as \"key does not exist\" and so we do the same.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (branch)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (branch)\"\n );\n\n return value;\n } else {\n // We're not at the end of the key yet.\n // Figure out what the next node ID should be and continue.\n uint8 branchKey = uint8(key[currentKeyIndex]);\n RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\n currentNodeID = _getNodeID(nextNode);\n currentKeyIndex += 1;\n }\n } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\n bytes memory path = _getNodePath(currentNode);\n uint8 prefix = uint8(path[0]);\n uint8 offset = 2 - (prefix % 2);\n bytes memory pathRemainder = Bytes.slice(path, offset);\n bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);\n uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\n\n // Whether this is a leaf node or an extension node, the path remainder MUST be a\n // prefix of the key remainder (or be equal to the key remainder) or the proof is\n // considered invalid.\n require(\n pathRemainder.length == sharedNibbleLength,\n \"MerkleTrie: path remainder must share all nibbles with key\"\n );\n\n if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\n // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid,\n // the key remainder must be exactly equal to the path remainder. We already\n // did the necessary byte comparison, so it's more efficient here to check that\n // the key remainder length equals the shared nibble length, which implies\n // equality with the path remainder (since we already did the same check with\n // the path remainder and the shared nibble length).\n require(\n keyRemainder.length == sharedNibbleLength,\n \"MerkleTrie: key remainder must be identical to path remainder\"\n );\n\n // Our Merkle Trie is designed specifically for the purposes of the Ethereum\n // state trie. Empty values are not allowed in the state trie, so we can safely\n // say that if the value is empty, the key should not exist and the proof is\n // invalid.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[1]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (leaf)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (leaf)\"\n );\n\n return value;\n } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\n // Prefix of 0 or 1 means this is an extension node. We move onto the next node\n // in the proof and increment the key index by the length of the path remainder\n // which is equal to the shared nibble length.\n currentNodeID = _getNodeID(currentNode.decoded[1]);\n currentKeyIndex += sharedNibbleLength;\n } else {\n revert(\"MerkleTrie: received a node with an unknown prefix\");\n }\n } else {\n revert(\"MerkleTrie: received an unparseable node\");\n }\n }\n\n revert(\"MerkleTrie: ran out of proof elements\");\n }\n\n /**\n * @notice Parses an array of proof elements into a new array that contains both the original\n * encoded element and the RLP-decoded element.\n *\n * @param _proof Array of proof elements to parse.\n *\n * @return Proof parsed into easily accessible structs.\n */\n function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {\n uint256 length = _proof.length;\n TrieNode[] memory proof = new TrieNode[](length);\n for (uint256 i = 0; i < length; ) {\n proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });\n unchecked {\n ++i;\n }\n }\n return proof;\n }\n\n /**\n * @notice Picks out the ID for a node. Node ID is referred to as the \"hash\" within the\n * specification, but nodes < 32 bytes are not actually hashed.\n *\n * @param _node Node to pull an ID for.\n *\n * @return ID for the node, depending on the size of its contents.\n */\n function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {\n return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);\n }\n\n /**\n * @notice Gets the path for a leaf or extension node.\n *\n * @param _node Node to get a path for.\n *\n * @return Node path, converted to an array of nibbles.\n */\n function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {\n return Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0]));\n }\n\n /**\n * @notice Utility; determines the number of nibbles shared between two nibble arrays.\n *\n * @param _a First nibble array.\n * @param _b Second nibble array.\n *\n * @return Number of shared nibbles.\n */\n function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\n private\n pure\n returns (uint256)\n {\n uint256 shared;\n uint256 max = (_a.length < _b.length) ? _a.length : _b.length;\n for (; shared < max && _a[shared] == _b[shared]; ) {\n unchecked {\n ++shared;\n }\n }\n return shared;\n }\n}\n" - }, - "contracts/libraries/trie/SecureMerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/* Library Imports */\nimport { MerkleTrie } from \"./MerkleTrie.sol\";\n\n/**\n * @title SecureMerkleTrie\n * @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input\n * keys. Ethereum's state trie hashes input keys before storing them.\n */\nlibrary SecureMerkleTrie {\n /**\n * @notice Verifies a proof that a given key/value pair is present in the Merkle trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.get(key, _proof, _root);\n }\n\n /**\n * @notice Computes the hashed version of the input key.\n *\n * @param _key Key to hash.\n *\n * @return Hashed version of the key.\n */\n function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {\n return abi.encodePacked(keccak256(_key));\n }\n}\n" - }, - "contracts/periphery/TransferOnion.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title TransferOnion\n * @notice TransferOnion is a hash onion for distributing tokens. The shell commits\n * to an ordered list of the token transfers and can be permissionlessly\n * unwrapped in order. The SENDER must `approve` this contract as\n * `transferFrom` is used to move the token balances.\n */\ncontract TransferOnion is ReentrancyGuard {\n using SafeERC20 for ERC20;\n\n /**\n * @notice Struct representing a layer of the onion.\n */\n struct Layer {\n address recipient;\n uint256 amount;\n bytes32 shell;\n }\n\n /**\n * @notice Address of the token to distribute.\n */\n ERC20 public immutable TOKEN;\n\n /**\n * @notice Address of the account to distribute tokens from.\n */\n address public immutable SENDER;\n\n /**\n * @notice Current shell hash.\n */\n bytes32 public shell;\n\n /**\n * @param _token Address of the token to distribute.\n * @param _sender Address of the sender to distribute from.\n * @param _shell Initial shell of the onion.\n */\n constructor(\n ERC20 _token,\n address _sender,\n bytes32 _shell\n ) {\n TOKEN = _token;\n SENDER = _sender;\n shell = _shell;\n }\n\n /**\n * @notice Peels layers from the onion and distributes tokens.\n *\n * @param _layers Array of onion layers to peel.\n */\n function peel(Layer[] memory _layers) public nonReentrant {\n bytes32 tempShell = shell;\n uint256 length = _layers.length;\n for (uint256 i = 0; i < length; ) {\n Layer memory layer = _layers[i];\n\n // Confirm that the onion layer is correct.\n require(\n keccak256(abi.encode(layer.recipient, layer.amount, layer.shell)) == tempShell,\n \"TransferOnion: what are you doing in my swamp?\"\n );\n\n // Update the onion layer.\n tempShell = layer.shell;\n\n // Transfer the tokens.\n TOKEN.safeTransferFrom(SENDER, layer.recipient, layer.amount);\n\n // Unchecked increment to save some gas.\n unchecked {\n ++i;\n }\n }\n\n shell = tempShell;\n }\n}\n" - }, - "contracts/test/AddressAliasHelper.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract AddressAliasHelper_applyAndUndo_Test is Test {\n /**\n * @notice Tests that applying and then undoing an alias results in the original address.\n */\n function testFuzz_applyAndUndo_succeeds(address _address) external {\n address aliased = AddressAliasHelper.applyL1ToL2Alias(_address);\n address unaliased = AddressAliasHelper.undoL1ToL2Alias(aliased);\n assertEq(_address, unaliased);\n }\n}\n" - }, - "contracts/test/BenchmarkTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test } from \"forge-std/Test.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport \"./CommonTest.t.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n// Free function for setting the prevBaseFee param in the OptimismPortal.\nfunction setPrevBaseFee(\n Vm _vm,\n address _op,\n uint128 _prevBaseFee\n) {\n _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee));\n}\n\ncontract SetPrevBaseFee_Test is Portal_Initializer {\n function test_setPrevBaseFee_succeeds() external {\n setPrevBaseFee(vm, address(op), 100 gwei);\n (uint128 prevBaseFee, , uint64 prevBlockNum) = op.params();\n assertEq(uint256(prevBaseFee), 100 gwei);\n assertEq(uint256(prevBlockNum), block.number);\n }\n}\n\n// Tests for obtaining pure gas cost estimates for commonly used functions.\n// The objective with these benchmarks is to strip down the actual test functions\n// so that they are nothing more than the call we want measure the gas cost of.\n// In order to achieve this we make no assertions, and handle everything else in the setUp()\n// function.\ncontract GasBenchMark_OptimismPortal is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n bytes32 _outputRoot;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n\n // Get withdrawal proof data we can use for testing.\n bytes32 _storageRoot;\n bytes32 _stateRoot;\n (_stateRoot, _storageRoot, _outputRoot, , _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public virtual override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n function test_depositTransaction_benchmark() external {\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_depositTransaction_benchmark_1() external {\n setPrevBaseFee(vm, address(op), 1 gwei);\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_proveWithdrawalTransaction_benchmark() external {\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n}\n\ncontract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {\n function test_sendMessage_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n\n function test_sendMessage_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), alice, 100000, true);\n vm.startPrank(alice, alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n }\n\n function test_depositETH_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositETH_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositERC20_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n\n function test_depositERC20_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), address(L1Bridge), 100, true);\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.startPrank(address(L1Bridge.messenger()));\n vm.deal(address(L1Bridge.messenger()), 100);\n }\n\n function test_finalizeETHWithdrawal_benchmark() external {\n // TODO: Make this more accurate. It is underestimating the cost because it pranks\n // the call coming from the messenger, which bypasses the portal\n // and oracle.\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer {\n uint256 nextBlockNumber;\n\n function setUp() public override {\n super.setUp();\n nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.startPrank(proposer);\n }\n\n function test_proposeL2Output_benchmark() external {\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n}\n" - }, - "contracts/test/BondManager.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"forge-std/Test.sol\";\n\nimport \"../libraries/DisputeTypes.sol\";\n\nimport { IDisputeGame } from \"../dispute/IDisputeGame.sol\";\nimport { IBondManager } from \"../dispute/IBondManager.sol\";\n\nimport { DisputeGameFactory } from \"../dispute/DisputeGameFactory.sol\";\n\nimport { BondManager } from \"../dispute/BondManager.sol\";\n\ncontract BondManager_Test is Test {\n DisputeGameFactory factory;\n BondManager bm;\n\n // DisputeGameFactory events\n event DisputeGameCreated(\n address indexed disputeProxy,\n GameType indexed gameType,\n Claim indexed rootClaim\n );\n\n // BondManager events\n event BondPosted(bytes32 bondId, address owner, uint256 expiration, uint256 amount);\n event BondSeized(bytes32 bondId, address owner, address seizer, uint256 amount);\n event BondReclaimed(bytes32 bondId, address claiment, uint256 amount);\n\n function setUp() public {\n factory = new DisputeGameFactory(address(this));\n bm = new BondManager(factory);\n }\n\n /**\n * -------------------------------------------\n * Test Bond Posting\n * -------------------------------------------\n */\n\n /**\n * @notice Tests that posting a bond succeeds.\n */\n function testFuzz_post_succeeds(\n bytes32 bondId,\n address owner,\n uint256 minClaimHold,\n uint256 amount\n ) public {\n vm.assume(owner != address(0));\n vm.assume(owner != address(bm));\n vm.assume(owner != address(this));\n // Create2Deployer\n vm.assume(owner != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n vm.assume(amount != 0);\n unchecked {\n vm.assume(block.timestamp + minClaimHold > minClaimHold);\n }\n\n vm.deal(address(this), amount);\n\n vm.expectEmit(true, true, true, true);\n uint256 expiration = block.timestamp + minClaimHold;\n emit BondPosted(bondId, owner, expiration, amount);\n\n bm.post{ value: amount }(bondId, owner, minClaimHold);\n\n // Validate the bond\n (\n address newFetchedOwner,\n uint256 fetchedExpiration,\n bytes32 fetchedBondId,\n uint256 bondAmount\n ) = bm.bonds(bondId);\n assertEq(newFetchedOwner, owner);\n assertEq(fetchedExpiration, block.timestamp + minClaimHold);\n assertEq(fetchedBondId, bondId);\n assertEq(bondAmount, amount);\n }\n\n /**\n * @notice Tests that posting a bond with the same id twice reverts.\n */\n function testFuzz_post_duplicates_reverts(\n bytes32 bondId,\n address owner,\n uint256 minClaimHold,\n uint256 amount\n ) public {\n vm.assume(owner != address(0));\n amount = amount / 2;\n vm.assume(amount != 0);\n unchecked {\n vm.assume(block.timestamp + minClaimHold > minClaimHold);\n }\n\n vm.deal(address(this), amount);\n bm.post{ value: amount }(bondId, owner, minClaimHold);\n\n vm.deal(address(this), amount);\n vm.expectRevert(\"BondManager: BondId already posted.\");\n bm.post{ value: amount }(bondId, owner, minClaimHold);\n }\n\n /**\n * @notice Posting with the zero address as the owner fails.\n */\n function testFuzz_post_zeroAddress_reverts(\n bytes32 bondId,\n uint256 minClaimHold,\n uint256 amount\n ) public {\n address owner = address(0);\n vm.deal(address(this), amount);\n vm.expectRevert(\"BondManager: Owner cannot be the zero address.\");\n bm.post{ value: amount }(bondId, owner, minClaimHold);\n }\n\n /**\n * @notice Posting zero value bonds should revert.\n */\n function testFuzz_post_zeroAddress_reverts(\n bytes32 bondId,\n address owner,\n uint256 minClaimHold\n ) public {\n vm.assume(owner != address(0));\n uint256 amount = 0;\n vm.deal(address(this), amount);\n vm.expectRevert(\"BondManager: Value must be non-zero.\");\n bm.post{ value: amount }(bondId, owner, minClaimHold);\n }\n\n /**\n * -------------------------------------------\n * Test Bond Seizing\n * -------------------------------------------\n */\n\n /**\n * @notice Non-existing bonds shouldn't be seizable.\n */\n function testFuzz_seize_missingBond_reverts(bytes32 bondId) public {\n vm.expectRevert(\"BondManager: The bond does not exist.\");\n bm.seize(bondId);\n }\n\n /**\n * @notice Bonds that expired cannot be seized.\n */\n function testFuzz_seize_expired_reverts(\n bytes32 bondId,\n address owner,\n uint256 minClaimHold,\n uint256 amount\n ) public {\n vm.assume(owner != address(0));\n vm.assume(owner != address(bm));\n vm.assume(owner != address(this));\n vm.assume(amount != 0);\n unchecked {\n vm.assume(block.timestamp + minClaimHold + 1 > minClaimHold);\n }\n vm.deal(address(this), amount);\n bm.post{ value: amount }(bondId, owner, minClaimHold);\n\n vm.warp(block.timestamp + minClaimHold + 1);\n vm.expectRevert(\"BondManager: Bond expired.\");\n bm.seize(bondId);\n }\n\n /**\n * @notice Bonds cannot be seized by unauthorized parties.\n */\n function testFuzz_seize_unauthorized_reverts(\n bytes32 bondId,\n address owner,\n uint256 minClaimHold,\n uint256 amount\n ) public {\n vm.assume(owner != address(0));\n vm.assume(owner != address(bm));\n vm.assume(owner != address(this));\n vm.assume(amount != 0);\n unchecked {\n vm.assume(block.timestamp + minClaimHold > minClaimHold);\n }\n vm.deal(address(this), amount);\n bm.post{ value: amount }(bondId, owner, minClaimHold);\n\n MockAttestationDisputeGame game = new MockAttestationDisputeGame();\n vm.prank(address(game));\n vm.expectRevert(\"BondManager: Unauthorized seizure.\");\n bm.seize(bondId);\n }\n\n /**\n * @notice Seizing a bond should succeed if the game resolves.\n */\n function testFuzz_seize_succeeds(\n bytes32 bondId,\n uint256 minClaimHold,\n bytes calldata extraData\n ) public {\n unchecked {\n vm.assume(block.timestamp + minClaimHold > minClaimHold);\n }\n\n vm.deal(address(this), 1 ether);\n bm.post{ value: 1 ether }(bondId, address(0xba5ed), minClaimHold);\n\n // Create a mock dispute game in the factory\n IDisputeGame proxy;\n Claim rootClaim;\n bytes memory ed = extraData;\n {\n rootClaim = Claim.wrap(bytes32(\"\"));\n MockAttestationDisputeGame implementation = new MockAttestationDisputeGame();\n GameType gt = GameType.ATTESTATION;\n factory.setImplementation(gt, IDisputeGame(address(implementation)));\n vm.expectEmit(false, true, true, false);\n emit DisputeGameCreated(address(0), gt, rootClaim);\n proxy = factory.create(gt, rootClaim, extraData);\n assertEq(address(factory.games(gt, rootClaim, extraData)), address(proxy));\n }\n\n // Update the game fields\n MockAttestationDisputeGame spawned = MockAttestationDisputeGame(payable(address(proxy)));\n spawned.setBondManager(bm);\n spawned.setRootClaim(rootClaim);\n spawned.setGameStatus(GameStatus.CHALLENGER_WINS);\n spawned.setBondId(bondId);\n spawned.setExtraData(ed);\n\n // Seize the bond by calling resolve\n vm.expectEmit(true, true, true, true);\n emit BondSeized(bondId, address(0xba5ed), address(spawned), 1 ether);\n spawned.resolve();\n assertEq(address(spawned).balance, 1 ether);\n\n // Validate that the bond was deleted\n (address newFetchedOwner, , , ) = bm.bonds(bondId);\n assertEq(newFetchedOwner, address(0));\n }\n\n /**\n * -------------------------------------------\n * Test Bond Split and Seizing\n * -------------------------------------------\n */\n\n /**\n * @notice Seizing and splitting a bond should succeed if the game resolves.\n */\n function testFuzz_seizeAndSplit_succeeds(\n bytes32 bondId,\n uint256 minClaimHold,\n bytes calldata extraData\n ) public {\n unchecked {\n vm.assume(block.timestamp + minClaimHold > minClaimHold);\n }\n\n vm.deal(address(this), 1 ether);\n bm.post{ value: 1 ether }(bondId, address(0xba5ed), minClaimHold);\n\n // Create a mock dispute game in the factory\n IDisputeGame proxy;\n Claim rootClaim;\n bytes memory ed = extraData;\n {\n rootClaim = Claim.wrap(bytes32(\"\"));\n MockAttestationDisputeGame implementation = new MockAttestationDisputeGame();\n GameType gt = GameType.ATTESTATION;\n factory.setImplementation(gt, IDisputeGame(address(implementation)));\n vm.expectEmit(false, true, true, false);\n emit DisputeGameCreated(address(0), gt, rootClaim);\n proxy = factory.create(gt, rootClaim, extraData);\n assertEq(address(factory.games(gt, rootClaim, extraData)), address(proxy));\n }\n\n // Update the game fields\n MockAttestationDisputeGame spawned = MockAttestationDisputeGame(payable(address(proxy)));\n spawned.setBondManager(bm);\n spawned.setRootClaim(rootClaim);\n spawned.setGameStatus(GameStatus.CHALLENGER_WINS);\n spawned.setBondId(bondId);\n spawned.setExtraData(ed);\n\n // Seize the bond by calling resolve\n vm.expectEmit(true, true, true, true);\n emit BondSeized(bondId, address(0xba5ed), address(spawned), 1 ether);\n spawned.splitResolve();\n assertEq(address(spawned).balance, 0);\n address[] memory challengers = spawned.getChallengers();\n uint256 proportionalAmount = 1 ether / challengers.length;\n for (uint256 i = 0; i < challengers.length; i++) {\n assertEq(address(challengers[i]).balance, proportionalAmount);\n }\n\n // Validate that the bond was deleted\n (address newFetchedOwner, , , ) = bm.bonds(bondId);\n assertEq(newFetchedOwner, address(0));\n }\n\n /**\n * -------------------------------------------\n * Test Bond Reclaiming\n * -------------------------------------------\n */\n\n /**\n * @notice Bonds can be reclaimed after the specified amount of time.\n */\n function testFuzz_reclaim_succeeds(\n bytes32 bondId,\n address owner,\n uint256 minClaimHold,\n uint256 amount\n ) public {\n vm.assume(owner != address(0));\n vm.assume(owner.code.length == 0);\n vm.assume(amount != 0);\n unchecked {\n vm.assume(block.timestamp + minClaimHold > minClaimHold);\n }\n assumeNoPrecompiles(owner);\n\n // Post the bond\n vm.deal(address(this), amount);\n bm.post{ value: amount }(bondId, owner, minClaimHold);\n\n // We can't claim if the block.timestamp is less than the bond expiration.\n (, uint256 expiration, , ) = bm.bonds(bondId);\n if (expiration > block.timestamp) {\n vm.prank(owner);\n vm.expectRevert(\"BondManager: Bond isn't claimable yet.\");\n bm.reclaim(bondId);\n }\n\n // Past expiration, the owner can reclaim\n vm.warp(expiration);\n vm.prank(owner);\n bm.reclaim(bondId);\n assertEq(owner.balance, amount);\n }\n}\n\n/**\n * @title MockAttestationDisputeGame\n * @dev A mock dispute game for testing bond seizures.\n */\ncontract MockAttestationDisputeGame is IDisputeGame {\n GameStatus internal gameStatus;\n BondManager bm;\n Claim internal rc;\n bytes internal ed;\n bytes32 internal bondId;\n\n address[] internal challengers;\n\n function getChallengers() public view returns (address[] memory) {\n return challengers;\n }\n\n function setBondId(bytes32 bid) external {\n bondId = bid;\n }\n\n function setBondManager(BondManager _bm) external {\n bm = _bm;\n }\n\n function setGameStatus(GameStatus _gs) external {\n gameStatus = _gs;\n }\n\n function setRootClaim(Claim _rc) external {\n rc = _rc;\n }\n\n function setExtraData(bytes memory _ed) external {\n ed = _ed;\n }\n\n receive() external payable {}\n\n fallback() external payable {}\n\n function splitResolve() public {\n challengers = [address(1), address(2)];\n bm.seizeAndSplit(bondId, challengers);\n }\n\n /**\n * -------------------------------------------\n * Initializable Functions\n * -------------------------------------------\n */\n\n function initialize() external {\n /* noop */\n }\n\n /**\n * -------------------------------------------\n * IVersioned Functions\n * -------------------------------------------\n */\n\n function version() external pure returns (string memory _version) {\n return \"0.1.0\";\n }\n\n /**\n * -------------------------------------------\n * IDisputeGame Functions\n * -------------------------------------------\n */\n\n function createdAt() external pure override returns (Timestamp _createdAt) {\n return Timestamp.wrap(uint64(0));\n }\n\n function status() external view override returns (GameStatus _status) {\n return gameStatus;\n }\n\n function gameType() external pure returns (GameType _gameType) {\n return GameType.ATTESTATION;\n }\n\n function rootClaim() external view override returns (Claim _rootClaim) {\n return rc;\n }\n\n function extraData() external view returns (bytes memory _extraData) {\n return ed;\n }\n\n function bondManager() external view override returns (IBondManager _bondManager) {\n return IBondManager(address(bm));\n }\n\n function resolve() external returns (GameStatus _status) {\n bm.seize(bondId);\n return gameStatus;\n }\n}\n" - }, - "contracts/test/Bytes.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Bytes } from \"../libraries/Bytes.sol\";\n\ncontract Bytes_slice_Test is Test {\n /**\n * @notice Tests that the `slice` function works as expected when starting from index 0.\n */\n function test_slice_fromZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check if all possible slices starting from index 0 are correct.\n assertEq(Bytes.slice(input, 0, 0), hex\"\");\n assertEq(Bytes.slice(input, 0, 1), hex\"11\");\n assertEq(Bytes.slice(input, 0, 2), hex\"1122\");\n assertEq(Bytes.slice(input, 0, 3), hex\"112233\");\n assertEq(Bytes.slice(input, 0, 4), hex\"11223344\");\n assertEq(Bytes.slice(input, 0, 5), hex\"1122334455\");\n assertEq(Bytes.slice(input, 0, 6), hex\"112233445566\");\n assertEq(Bytes.slice(input, 0, 7), hex\"11223344556677\");\n assertEq(Bytes.slice(input, 0, 8), hex\"1122334455667788\");\n assertEq(Bytes.slice(input, 0, 9), hex\"112233445566778899\");\n assertEq(Bytes.slice(input, 0, 10), hex\"11223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when starting from indices [1, 9]\n * with lengths [1, 9], in reverse order.\n */\n function test_slice_fromNonZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check correctness of slices starting from indexes [1, 9]\n // and spanning [1, 9] bytes, in reverse order\n assertEq(Bytes.slice(input, 9, 1), hex\"00\");\n assertEq(Bytes.slice(input, 8, 2), hex\"9900\");\n assertEq(Bytes.slice(input, 7, 3), hex\"889900\");\n assertEq(Bytes.slice(input, 6, 4), hex\"77889900\");\n assertEq(Bytes.slice(input, 5, 5), hex\"6677889900\");\n assertEq(Bytes.slice(input, 4, 6), hex\"556677889900\");\n assertEq(Bytes.slice(input, 3, 7), hex\"44556677889900\");\n assertEq(Bytes.slice(input, 2, 8), hex\"3344556677889900\");\n assertEq(Bytes.slice(input, 1, 9), hex\"223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple words\n * in memory. In this case, we test that a 2 byte slice between the 32nd byte of the\n * first word and the 1st byte of the second word is correct.\n */\n function test_slice_acrossWords_works() public {\n bytes\n memory input = hex\"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000\";\n\n assertEq(Bytes.slice(input, 31, 2), hex\"1122\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple\n * words in memory. In this case, we test that a 34 byte slice between 3 separate words\n * returns the correct result.\n */\n function test_slice_acrossMultipleWords_works() public {\n bytes\n memory input = hex\"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000\";\n bytes\n memory expected = hex\"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11\";\n\n assertEq(Bytes.slice(input, 31, 34), expected);\n }\n\n /**\n * @notice Tests that, when given an input bytes array of length `n`, the `slice` function will\n * always revert if `_start + _length > n`.\n */\n function testFuzz_slice_outOfBounds_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // We want a valid start index and a length that will not overflow.\n vm.assume(_start < _input.length && _length < type(uint256).max - 31);\n // But, we want an invalid slice length.\n vm.assume(_start + _length > _input.length);\n\n vm.expectRevert(\"slice_outOfBounds\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,\n * the `slice` function reverts.\n */\n function testFuzz_slice_lengthOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that the `_length` will overflow if a number >= 31 is added to it.\n vm.assume(_length > type(uint256).max - 31);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a start index `n` that is greater than\n * `type(uint256).max - n`, the `slice` function reverts.\n */\n function testFuzz_slice_rangeOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that `_length` is a realistic length of a slice. This is to make sure\n // we revert on the correct require statement.\n vm.assume(_length < _input.length);\n // Ensure that `_start` will overflow if `_length` is added to it.\n vm.assume(_start > type(uint256).max - _length);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that the `slice` function correctly updates the free memory pointer depending\n * on the length of the slice.\n */\n function testFuzz_slice_memorySafety_succeeds(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // The start should never be more than the length of the input bytes array - 1\n vm.assume(_start < _input.length);\n // The length should never be more than the length of the input bytes array - the starting\n // slice index.\n vm.assume(_length <= _input.length - _start);\n\n // Grab the free memory pointer before the slice operation\n uint64 initPtr;\n assembly {\n initPtr := mload(0x40)\n }\n uint64 expectedPtr = uint64(initPtr + 0x20 + ((_length + 0x1f) & ~uint256(0x1f)));\n\n // Ensure that all memory outside of the expected range is safe.\n vm.expectSafeMemory(initPtr, expectedPtr);\n\n // Slice the input bytes array from `_start` to `_start + _length`\n bytes memory slice = Bytes.slice(_input, _start, _length);\n\n // Grab the free memory pointer after the slice operation\n uint64 finalPtr;\n assembly {\n finalPtr := mload(0x40)\n }\n\n // The free memory pointer should have been updated properly\n if (_length == 0) {\n // If the slice length is zero, only 32 bytes of memory should have been allocated.\n assertEq(finalPtr, initPtr + 0x20);\n } else {\n // If the slice length is greater than zero, the memory allocated should be the\n // length of the slice rounded up to the next 32 byte word + 32 bytes for the\n // length of the byte array.\n //\n // Note that we use a slightly less efficient, but equivalent method of rounding\n // up `_length` to the next multiple of 32 than is used in the `slice` function.\n // This is to diff test the method used in `slice`.\n uint64 _expectedPtr = uint64(initPtr + 0x20 + (((_length + 0x1F) >> 5) << 5));\n assertEq(finalPtr, _expectedPtr);\n\n // Sanity check for equivalence of the rounding methods.\n assertEq(_expectedPtr, expectedPtr);\n }\n\n // The slice length should be equal to `_length`\n assertEq(slice.length, _length);\n }\n}\n\ncontract Bytes_toNibbles_Test is Test {\n /**\n * @notice Diffs the test Solidity version of `toNibbles` against the Yul version.\n *\n * @param _bytes The `bytes` array to convert to nibbles.\n *\n * @return Yul version of `toNibbles` applied to `_bytes`.\n */\n function _toNibblesYul(bytes memory _bytes) internal pure returns (bytes memory) {\n // Allocate memory for the `nibbles` array.\n bytes memory nibbles = new bytes(_bytes.length << 1);\n\n assembly {\n // Load the length of the passed bytes array from memory\n let bytesLength := mload(_bytes)\n\n // Store the memory offset of the _bytes array's contents on the stack\n let bytesStart := add(_bytes, 0x20)\n\n // Store the memory offset of the nibbles array's contents on the stack\n let nibblesStart := add(nibbles, 0x20)\n\n // Loop through each byte in the input array\n for {\n let i := 0x00\n } lt(i, bytesLength) {\n i := add(i, 0x01)\n } {\n // Get the starting offset of the next 2 bytes in the nibbles array\n let offset := add(nibblesStart, shl(0x01, i))\n\n // Load the byte at the current index within the `_bytes` array\n let b := byte(0x00, mload(add(bytesStart, i)))\n\n // Pull out the first nibble and store it in the new array\n mstore8(offset, shr(0x04, b))\n // Pull out the second nibble and store it in the new array\n mstore8(add(offset, 0x01), and(b, 0x0F))\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Tests that, given an input of 5 bytes, the `toNibbles` function returns an array of\n * 10 nibbles corresponding to the input data.\n */\n function test_toNibbles_expectedResult5Bytes_works() public {\n bytes memory input = hex\"1234567890\";\n bytes memory expected = hex\"01020304050607080900\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 128 bytes, the `toNibbles` function returns an array\n * of 256 nibbles corresponding to the input data. This test exists to ensure that,\n * given a large input, the `toNibbles` function works as expected.\n */\n function test_toNibbles_expectedResult128Bytes_works() public {\n bytes\n memory input = hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f\";\n bytes\n memory expected = hex\"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 0 bytes, the `toNibbles` function returns a zero\n * length array.\n */\n function test_toNibbles_zeroLengthInput_works() public {\n bytes memory input = hex\"\";\n bytes memory expected = hex\"\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length, 0);\n assertEq(expected.length, 0);\n assertEq(actual.length, 0);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Test that the `toNibbles` function in the `Bytes` library is equivalent to the Yul\n * implementation.\n */\n function testDiff_toNibbles_succeeds(bytes memory _input) public {\n assertEq(Bytes.toNibbles(_input), _toNibblesYul(_input));\n }\n}\n\ncontract Bytes_equal_Test is Test {\n /**\n * @notice Manually checks equality of two dynamic `bytes` arrays in memory.\n *\n * @param _a The first `bytes` array to compare.\n * @param _b The second `bytes` array to compare.\n *\n * @return True if the two `bytes` arrays are equal in memory.\n */\n function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) {\n bool _eq;\n assembly {\n _eq := and(\n // Check if the contents of the two bytes arrays are equal in memory.\n eq(keccak256(add(0x20, _a), mload(_a)), keccak256(add(0x20, _b), mload(_b))),\n // Check if the length of the two bytes arrays are equal in memory.\n // This is redundant given the above check, but included for completeness.\n eq(mload(_a), mload(_b))\n )\n }\n return _eq;\n }\n\n /**\n * @notice Tests that the `equal` function in the `Bytes` library returns `false` if given two\n * non-equal byte arrays.\n */\n function testFuzz_equal_notEqual_works(bytes memory _a, bytes memory _b) public {\n vm.assume(!manualEq(_a, _b));\n assertFalse(Bytes.equal(_a, _b));\n }\n\n /**\n * @notice Test whether or not the `equal` function in the `Bytes` library is equivalent to\n * manually checking equality of the two dynamic `bytes` arrays in memory.\n */\n function testDiff_equal_works(bytes memory _a, bytes memory _b) public {\n assertEq(Bytes.equal(_a, _b), manualEq(_a, _b));\n }\n}\n" - }, - "contracts/test/CommonTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test, StdUtils } from \"forge-std/Test.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { IL1ChugSplashDeployer } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { LegacyMintableERC20 } from \"../legacy/LegacyMintableERC20.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract CommonTest is Test {\n address alice = address(128);\n address bob = address(256);\n address multisig = address(512);\n\n address immutable ZERO_ADDRESS = address(0);\n address immutable NON_ZERO_ADDRESS = address(1);\n uint256 immutable NON_ZERO_VALUE = 100;\n uint256 immutable ZERO_VALUE = 0;\n uint64 immutable NON_ZERO_GASLIMIT = 50000;\n bytes32 nonZeroHash = keccak256(abi.encode(\"NON_ZERO\"));\n bytes NON_ZERO_DATA = hex\"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000\";\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n FFIInterface ffi;\n\n function setUp() public virtual {\n // Give alice and bob some ETH\n vm.deal(alice, 1 << 16);\n vm.deal(bob, 1 << 16);\n vm.deal(multisig, 1 << 16);\n\n vm.label(alice, \"alice\");\n vm.label(bob, \"bob\");\n vm.label(multisig, \"multisig\");\n\n // Make sure we have a non-zero base fee\n vm.fee(1000000000);\n\n ffi = new FFIInterface();\n }\n\n function emitTransactionDeposited(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) internal {\n emit TransactionDeposited(\n _from,\n _to,\n 0,\n abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)\n );\n }\n}\n\ncontract L2OutputOracle_Initializer is CommonTest {\n // Test target\n L2OutputOracle oracle;\n L2OutputOracle oracleImpl;\n\n L2ToL1MessagePasser messagePasser =\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));\n\n // Constructor arguments\n address internal proposer = 0x000000000000000000000000000000000000AbBa;\n address internal owner = 0x000000000000000000000000000000000000ACDC;\n uint256 internal submissionInterval = 1800;\n uint256 internal l2BlockTime = 2;\n uint256 internal startingBlockNumber = 200;\n uint256 internal startingTimestamp = 1000;\n address guardian;\n\n // Test data\n uint256 initL1Time;\n\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n // Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output\n function warpToProposeTime(uint256 _nextBlockNumber) public {\n vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1);\n }\n\n function setUp() public virtual override {\n super.setUp();\n guardian = makeAddr(\"guardian\");\n\n // By default the first block has timestamp and number zero, which will cause underflows in the\n // tests, so we'll move forward to these block values.\n initL1Time = startingTimestamp + 1;\n vm.warp(initL1Time);\n vm.roll(startingBlockNumber);\n // Deploy the L2OutputOracle and transfer owernship to the proposer\n oracleImpl = new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: startingTimestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(oracleImpl),\n abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp))\n );\n oracle = L2OutputOracle(address(proxy));\n vm.label(address(oracle), \"L2OutputOracle\");\n\n // Set the L2ToL1MessagePasser at the correct address\n vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code);\n\n vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, \"L2ToL1MessagePasser\");\n }\n}\n\ncontract Portal_Initializer is L2OutputOracle_Initializer {\n // Test target\n OptimismPortal internal opImpl;\n OptimismPortal internal op;\n SystemConfig systemConfig;\n\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n\n systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: config\n });\n\n opImpl = new OptimismPortal({\n _l2Oracle: oracle,\n _guardian: guardian,\n _paused: true,\n _config: systemConfig\n });\n\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(opImpl),\n abi.encodeWithSelector(OptimismPortal.initialize.selector, false)\n );\n op = OptimismPortal(payable(address(proxy)));\n vm.label(address(op), \"OptimismPortal\");\n }\n}\n\ncontract Messenger_Initializer is Portal_Initializer {\n AddressManager internal addressManager;\n L1CrossDomainMessenger internal L1Messenger;\n L2CrossDomainMessenger internal L2Messenger =\n L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);\n\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event RelayedMessage(bytes32 indexed msgHash);\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 mint,\n uint256 value,\n uint64 gasLimit,\n bool isCreation,\n bytes data\n );\n\n event WhatHappened(bool success, bytes returndata);\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the address manager\n vm.prank(multisig);\n addressManager = new AddressManager();\n\n // Setup implementation\n L1CrossDomainMessenger L1MessengerImpl = new L1CrossDomainMessenger(op);\n\n // Setup the address manager and proxy\n vm.prank(multisig);\n addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(L1MessengerImpl));\n ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(\n addressManager,\n \"OVM_L1CrossDomainMessenger\"\n );\n L1Messenger = L1CrossDomainMessenger(address(proxy));\n L1Messenger.initialize();\n\n vm.etch(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n address(new L2CrossDomainMessenger(address(L1Messenger))).code\n );\n\n L2Messenger.initialize();\n\n // Label addresses\n vm.label(address(addressManager), \"AddressManager\");\n vm.label(address(L1MessengerImpl), \"L1CrossDomainMessenger_Impl\");\n vm.label(address(L1Messenger), \"L1CrossDomainMessenger_Proxy\");\n vm.label(Predeploys.LEGACY_ERC20_ETH, \"LegacyERC20ETH\");\n vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, \"L2CrossDomainMessenger\");\n\n vm.label(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n \"L1CrossDomainMessenger_aliased\"\n );\n }\n}\n\ncontract Bridge_Initializer is Messenger_Initializer {\n L1StandardBridge L1Bridge;\n L2StandardBridge L2Bridge;\n OptimismMintableERC20Factory L2TokenFactory;\n OptimismMintableERC20Factory L1TokenFactory;\n ERC20 L1Token;\n ERC20 BadL1Token;\n OptimismMintableERC20 L2Token;\n LegacyMintableERC20 LegacyL2Token;\n ERC20 NativeL2Token;\n ERC20 BadL2Token;\n OptimismMintableERC20 RemoteL1Token;\n\n event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data\n );\n\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFailed(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.label(Predeploys.L2_STANDARD_BRIDGE, \"L2StandardBridge\");\n vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, \"OptimismMintableERC20Factory\");\n\n // Deploy the L1 bridge and initialize it with the address of the\n // L1CrossDomainMessenger\n L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig);\n vm.mockCall(\n multisig,\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector),\n abi.encode(true)\n );\n vm.startPrank(multisig);\n proxy.setCode(address(new L1StandardBridge(payable(address(L1Messenger)))).code);\n vm.clearMockedCalls();\n address L1Bridge_Impl = proxy.getImplementation();\n vm.stopPrank();\n\n L1Bridge = L1StandardBridge(payable(address(proxy)));\n\n vm.label(address(proxy), \"L1StandardBridge_Proxy\");\n vm.label(address(L1Bridge_Impl), \"L1StandardBridge_Impl\");\n\n // Deploy the L2StandardBridge, move it to the correct predeploy\n // address and then initialize it\n L2StandardBridge l2B = new L2StandardBridge(payable(proxy));\n vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(l2B).code);\n L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));\n\n // Set up the L2 mintable token factory\n OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(\n Predeploys.L2_STANDARD_BRIDGE\n );\n vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code);\n L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);\n\n vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code);\n\n L1Token = new ERC20(\"Native L1 Token\", \"L1T\");\n\n LegacyL2Token = new LegacyMintableERC20({\n _l2Bridge: address(L2Bridge),\n _l1Token: address(L1Token),\n _name: string.concat(\"LegacyL2-\", L1Token.name()),\n _symbol: string.concat(\"LegacyL2-\", L1Token.symbol())\n });\n vm.label(address(LegacyL2Token), \"LegacyMintableERC20\");\n\n // Deploy the L2 ERC20 now\n L2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(L1Token),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n BadL2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n NativeL2Token = new ERC20(\"Native L2 Token\", \"L2T\");\n L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge));\n\n RemoteL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(NativeL2Token),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n\n BadL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n }\n}\n\ncontract ERC721Bridge_Initializer is Messenger_Initializer {\n L1ERC721Bridge L1Bridge;\n L2ERC721Bridge L2Bridge;\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the L1ERC721Bridge.\n L1Bridge = new L1ERC721Bridge(address(L1Messenger), Predeploys.L2_ERC721_BRIDGE);\n\n // Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.\n vm.etch(\n Predeploys.L2_ERC721_BRIDGE,\n address(new L2ERC721Bridge(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(L1Bridge)))\n .code\n );\n\n // Set up a reference to the L2ERC721Bridge.\n L2Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);\n\n // Label the L1 and L2 bridges.\n vm.label(address(L1Bridge), \"L1ERC721Bridge\");\n vm.label(address(L2Bridge), \"L2ERC721Bridge\");\n }\n}\n\ncontract FFIInterface is Test {\n function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx)\n external\n returns (\n bytes32,\n bytes32,\n bytes32,\n bytes32,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"getProveWithdrawalTransactionInputs\";\n cmds[2] = vm.toString(_tx.nonce);\n cmds[3] = vm.toString(_tx.sender);\n cmds[4] = vm.toString(_tx.target);\n cmds[5] = vm.toString(_tx.value);\n cmds[6] = vm.toString(_tx.gasLimit);\n cmds[7] = vm.toString(_tx.data);\n\n bytes memory result = vm.ffi(cmds);\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[]));\n\n return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof);\n }\n\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashWithdrawal(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashWithdrawal\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashOutputRootProof(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external returns (bytes32) {\n string[] memory cmds = new string[](6);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashOutputRootProof\";\n cmds[2] = Strings.toHexString(uint256(_version));\n cmds[3] = Strings.toHexString(uint256(_stateRoot));\n cmds[4] = Strings.toHexString(uint256(_messagePasserStorageRoot));\n cmds[5] = Strings.toHexString(uint256(_latestBlockhash));\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashDepositTransaction(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external returns (bytes32) {\n string[] memory cmds = new string[](10);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashDepositTransaction\";\n cmds[2] = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n cmds[3] = vm.toString(_logIndex);\n cmds[4] = vm.toString(_from);\n cmds[5] = vm.toString(_to);\n cmds[6] = vm.toString(_mint);\n cmds[7] = vm.toString(_value);\n cmds[8] = vm.toString(_gas);\n cmds[9] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function encodeDepositTransaction(Types.UserDepositTransaction calldata txn)\n external\n returns (bytes memory)\n {\n string[] memory cmds = new string[](11);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeDepositTransaction\";\n cmds[2] = vm.toString(txn.from);\n cmds[3] = vm.toString(txn.to);\n cmds[4] = vm.toString(txn.value);\n cmds[5] = vm.toString(txn.mint);\n cmds[6] = vm.toString(txn.gasLimit);\n cmds[7] = vm.toString(txn.isCreation);\n cmds[8] = vm.toString(txn.data);\n cmds[9] = vm.toString(txn.l1BlockHash);\n cmds[10] = vm.toString(txn.logIndex);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes memory) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) {\n string[] memory cmds = new string[](3);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"decodeVersionedNonce\";\n cmds[2] = vm.toString(nonce);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (uint256, uint256));\n }\n\n function getMerkleTrieFuzzCase(string memory variant)\n external\n returns (\n bytes32,\n bytes memory,\n bytes memory,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](5);\n cmds[0] = \"./test-case-generator/fuzz\";\n cmds[1] = \"-m\";\n cmds[2] = \"trie\";\n cmds[3] = \"-v\";\n cmds[4] = variant;\n\n return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[]));\n }\n}\n\n// Used for testing a future upgrade beyond the current implementations.\n// We include some variables so that we can sanity check accessing storage values after an upgrade.\ncontract NextImpl is Initializable {\n // Initializable occupies the zero-th slot.\n bytes32 slot1;\n bytes32[19] __gap;\n bytes32 slot21;\n bytes32 public constant slot21Init = bytes32(hex\"1337\");\n\n function initialize() public reinitializer(2) {\n // Slot21 is unused by an of our upgradeable contracts.\n // This is used to verify that we can access this value after an upgrade.\n slot21 = slot21Init;\n }\n}\n\ncontract Reverter {\n fallback() external {\n revert();\n }\n}\n\n// Useful for testing reentrancy guards\ncontract CallerCaller {\n event WhatHappened(bool success, bytes returndata);\n\n fallback() external {\n (bool success, bytes memory returndata) = msg.sender.call(msg.data);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n\n// Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard.\ncontract ConfigurableCaller {\n bool doRevert = true;\n address target;\n bytes payload;\n\n event WhatHappened(bool success, bytes returndata);\n\n /**\n * @notice Call the configured target with the configured payload OR revert.\n */\n function call() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n } else {\n (bool success, bytes memory returndata) = address(target).call(payload);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n }\n\n /**\n * @notice Set whether or not to have `call` revert.\n */\n function setDoRevert(bool _doRevert) external {\n doRevert = _doRevert;\n }\n\n /**\n * @notice Set the target for the call made in `call`.\n */\n function setTarget(address _target) external {\n target = _target;\n }\n\n /**\n * @notice Set the payload for the call made in `call`.\n */\n function setPayload(bytes calldata _payload) external {\n payload = _payload;\n }\n\n /**\n * @notice Fallback function that reverts if `doRevert` is true.\n * Otherwise, it does nothing.\n */\n fallback() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n }\n }\n}\n" - }, - "contracts/test/CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, CallerCaller, CommonTest } from \"./CommonTest.t.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\n\n// Libraries\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n// CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2\n// CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract.\ncontract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {\n // Ensure that baseGas passes for the max value of _minGasLimit,\n // this is about 4 Billion.\n function test_baseGas_succeeds() external view {\n L1Messenger.baseGas(hex\"ff\", type(uint32).max);\n }\n\n // Fuzz for other values which might cause a revert in baseGas.\n function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view {\n L1Messenger.baseGas(hex\"ff\", _minGasLimit);\n }\n\n /**\n * @notice The baseGas function should always return a value greater than\n * or equal to the minimum gas limit value on the OptimismPortal.\n * This guarantees that the messengers will always pass sufficient\n * gas to the OptimismPortal.\n */\n function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit)\n external\n {\n vm.assume(_data.length <= type(uint64).max);\n uint64 baseGas = L1Messenger.baseGas(_data, _minGasLimit);\n uint64 minGasLimit = op.minimumGasLimit(uint64(_data.length));\n assertTrue(baseGas >= minGasLimit);\n }\n}\n\n/**\n * @title ExternalRelay\n * @notice A mock external contract called via the SafeCall inside\n * the CrossDomainMessenger's `relayMessage` function.\n */\ncontract ExternalRelay is CommonTest {\n address internal op;\n address internal fuzzedSender;\n L1CrossDomainMessenger internal L1Messenger;\n\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n constructor(L1CrossDomainMessenger _l1Messenger, address _op) {\n L1Messenger = _l1Messenger;\n op = _op;\n }\n\n /**\n * @notice Internal helper function to relay a message and perform assertions.\n */\n function _internalRelay(address _innerSender) internal {\n address initialSender = L1Messenger.xDomainMessageSender();\n\n bytes memory callMessage = getCallData();\n\n bytes32 hash = Hashing.hashCrossDomainMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: _innerSender,\n _target: address(this),\n _value: 0,\n _gasLimit: 0,\n _data: callMessage\n });\n\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n vm.prank(address(op));\n L1Messenger.relayMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: _innerSender,\n _target: address(this),\n _value: 0,\n _minGasLimit: 0,\n _message: callMessage\n });\n\n assertTrue(L1Messenger.failedMessages(hash));\n assertFalse(L1Messenger.successfulMessages(hash));\n assertEq(initialSender, L1Messenger.xDomainMessageSender());\n }\n\n /**\n * @notice externalCallWithMinGas is called by the CrossDomainMessenger.\n */\n function externalCallWithMinGas() external payable {\n for (uint256 i = 0; i < 10; i++) {\n address _innerSender;\n unchecked {\n _innerSender = address(uint160(uint256(uint160(fuzzedSender)) + i));\n }\n _internalRelay(_innerSender);\n }\n }\n\n /**\n * @notice Helper function to get the callData for an `externalCallWithMinGas\n */\n function getCallData() public pure returns (bytes memory) {\n return abi.encodeWithSelector(ExternalRelay.externalCallWithMinGas.selector);\n }\n\n /**\n * @notice Helper function to set the fuzzed sender\n */\n function setFuzzedSender(address _fuzzedSender) public {\n fuzzedSender = _fuzzedSender;\n }\n}\n\n/**\n * @title CrossDomainMessenger_RelayMessage_Test\n * @notice Fuzz tests re-entrancy into the CrossDomainMessenger relayMessage function.\n */\ncontract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer {\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n ExternalRelay public er;\n\n function setUp() public override {\n super.setUp();\n er = new ExternalRelay(L1Messenger, address(op));\n }\n\n /**\n * @dev This test mocks an OptimismPortal call to the L1CrossDomainMessenger via\n * the relayMessage function. The relayMessage function will then use SafeCall's\n * callWithMinGas to call the target with call data packed in the callMessage.\n * For this test, the callWithMinGas will call the mock ExternalRelay test contract\n * defined above, executing the externalCallWithMinGas function which will try to\n * re-enter the CrossDomainMessenger's relayMessage function, resulting in that message\n * being recorded as failed.\n */\n function testFuzz_relayMessageReenter_succeeds(address _sender, uint256 _gasLimit) external {\n vm.assume(_sender != Predeploys.L2_CROSS_DOMAIN_MESSENGER);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n er.setFuzzedSender(_sender);\n address target = address(er);\n bytes memory callMessage = er.getCallData();\n\n vm.expectCall(target, callMessage);\n\n uint64 gasLimit = uint64(bound(_gasLimit, 0, 30_000_000));\n\n bytes32 hash = Hashing.hashCrossDomainMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: sender,\n _target: target,\n _value: 0,\n _gasLimit: gasLimit,\n _data: callMessage\n });\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n L1Messenger.relayMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: sender,\n _target: target,\n _value: 0,\n _minGasLimit: gasLimit,\n _message: callMessage\n });\n\n assertTrue(L1Messenger.successfulMessages(hash));\n assertEq(L1Messenger.failedMessages(hash), false);\n\n // Ensures that the `xDomainMsgSender` is set back to `Predeploys.L2_CROSS_DOMAIN_MESSENGER`\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest, Portal_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable } from \"../L2/CrossDomainOwnable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Vm, VmSafe } from \"forge-std/Vm.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract XDomainSetter is CrossDomainOwnable {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable_Test is CommonTest {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n setter = new XDomainSetter();\n }\n\n // Check that the revert message is correct\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable: caller is not the owner\");\n setter.set(1);\n }\n\n // Check that making a call can set the value properly\n function test_onlyOwner_succeeds() external {\n assertEq(setter.value(), 0);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(setter.owner()));\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n\ncontract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n\n vm.prank(alice);\n setter = new XDomainSetter();\n }\n\n function test_depositTransaction_crossDomainOwner_succeeds() external {\n vm.recordLogs();\n\n vm.prank(alice);\n op.depositTransaction({\n _to: address(setter),\n _value: 0,\n _gasLimit: 30_000,\n _isCreation: false,\n _data: abi.encodeWithSelector(XDomainSetter.set.selector, 1)\n });\n\n // Simulate the operation of the `op-node` by parsing data\n // from logs\n VmSafe.Log[] memory logs = vm.getRecordedLogs();\n // Only 1 log emitted\n assertEq(logs.length, 1);\n\n VmSafe.Log memory log = logs[0];\n\n // It is the expected topic\n bytes32 topic = log.topics[0];\n assertEq(topic, keccak256(\"TransactionDeposited(address,address,uint256,bytes)\"));\n\n // from is indexed and the first argument to the event.\n bytes32 _from = log.topics[1];\n address from = Bytes32AddressLib.fromLast20Bytes(_from);\n\n assertEq(AddressAliasHelper.undoL1ToL2Alias(from), alice);\n\n // Make a call from the \"from\" value received from the log.\n // In theory the opaque data could be parsed from the log\n // and passed to a low level call to \"to\", but calling set\n // directly on the setter is good enough.\n vm.prank(from);\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable2.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable2 } from \"../L2/CrossDomainOwnable2.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter2 is CrossDomainOwnable2 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable2_Test is Messenger_Initializer {\n XDomainSetter2 setter;\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter2();\n }\n\n function test_onlyOwner_notMessenger_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice));\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the owner\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner2_reverts() external {\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_onlyOwner_succeeds() external {\n address owner = setter.owner();\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n owner,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter2.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable3.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable3 } from \"../L2/CrossDomainOwnable3.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter3 is CrossDomainOwnable3 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable3_Test is Messenger_Initializer {\n XDomainSetter3 setter;\n\n /**\n * @notice OpenZeppelin Ownable.sol transferOwnership event\n */\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @notice CrossDomainOwnable3.sol transferOwnership event\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter3();\n }\n\n function test_constructor_succeeds() public {\n assertEq(setter.owner(), alice);\n assertEq(setter.isLocal(), true);\n }\n\n function test_localOnlyOwner_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_transferOwnership_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n }\n\n function test_crossDomainOnlyOwner_notOwner_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob);\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_crossDomainOnlyOwner_notOwner2_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter3.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_crossDomainOnlyOwner_notMessenger_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_transferOwnership_zeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"CrossDomainOwnable3: new owner is the zero address\");\n setter.transferOwnership({ _owner: address(0), _isLocal: true });\n }\n\n function test_transferOwnership_noLocalZeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"Ownable: new owner is the zero address\");\n setter.transferOwnership(address(0));\n }\n\n function test_localOnlyOwner_succeeds() public {\n assertEq(setter.isLocal(), true);\n vm.prank(setter.owner());\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n\n function test_localTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, true);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n\n assertEq(setter.isLocal(), true);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n /**\n * @notice The existing transferOwnership(address) method\n * still exists on the contract\n */\n function test_transferOwnershipNoLocal_succeeds() public {\n bool isLocal = setter.isLocal();\n\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n\n vm.prank(setter.owner());\n setter.transferOwnership(bob);\n\n // isLocal has not changed\n assertEq(setter.isLocal(), isLocal);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n function test_crossDomainTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n bob,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter3.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/DeployerWhitelist.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { DeployerWhitelist } from \"../legacy/DeployerWhitelist.sol\";\n\ncontract DeployerWhitelist_Test is CommonTest {\n DeployerWhitelist list;\n\n function setUp() public virtual override {\n list = new DeployerWhitelist();\n }\n\n // The owner should be address(0)\n function test_owner_succeeds() external {\n assertEq(list.owner(), address(0));\n }\n\n // The storage slot for the owner must be the same\n function test_storageSlots_succeeds() external {\n vm.prank(list.owner());\n list.setOwner(address(1));\n\n assertEq(bytes32(uint256(1)), vm.load(address(list), bytes32(uint256(0))));\n }\n}\n" - }, - "contracts/test/DisputeGameFactory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport \"../libraries/DisputeTypes.sol\";\nimport \"../libraries/DisputeErrors.sol\";\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { DisputeGameFactory } from \"../dispute/DisputeGameFactory.sol\";\nimport { IDisputeGame } from \"../dispute/IDisputeGame.sol\";\n\ncontract DisputeGameFactory_Test is Test {\n DisputeGameFactory factory;\n FakeClone fakeClone;\n\n event DisputeGameCreated(\n address indexed disputeProxy,\n GameType indexed gameType,\n Claim indexed rootClaim\n );\n\n event ImplementationSet(address indexed impl, GameType indexed gameType);\n\n function setUp() public {\n factory = new DisputeGameFactory(address(this));\n fakeClone = new FakeClone();\n }\n\n /**\n * @dev Tests that the `create` function succeeds when creating a new dispute game\n * with a `GameType` that has an implementation set.\n */\n function testFuzz_create_succeeds(\n uint8 gameType,\n Claim rootClaim,\n bytes calldata extraData\n ) public {\n // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.\n GameType gt = GameType(uint8(bound(gameType, 0, 2)));\n\n // Set all three implementations to the same `FakeClone` contract.\n for (uint8 i; i < 3; i++) {\n factory.setImplementation(GameType(i), IDisputeGame(address(fakeClone)));\n }\n\n vm.expectEmit(false, true, true, false);\n emit DisputeGameCreated(address(0), gt, rootClaim);\n IDisputeGame proxy = factory.create(gt, rootClaim, extraData);\n\n // Ensure that the dispute game was assigned to the `disputeGames` mapping.\n assertEq(address(factory.games(gt, rootClaim, extraData)), address(proxy));\n }\n\n /**\n * @dev Tests that the `create` function reverts when there is no implementation\n * set for the given `GameType`.\n */\n function testFuzz_create_noImpl_reverts(\n uint8 gameType,\n Claim rootClaim,\n bytes calldata extraData\n ) public {\n // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.\n GameType gt = GameType(uint8(bound(gameType, 0, 2)));\n\n vm.expectRevert(abi.encodeWithSelector(NoImplementation.selector, gt));\n factory.create(gt, rootClaim, extraData);\n }\n\n /**\n * @dev Tests that the `create` function reverts when there exists a dispute game with the same UUID.\n */\n function testFuzz_create_sameUUID_reverts(\n uint8 gameType,\n Claim rootClaim,\n bytes calldata extraData\n ) public {\n // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.\n GameType gt = GameType(uint8(bound(gameType, 0, 2)));\n\n // Set all three implementations to the same `FakeClone` contract.\n for (uint8 i; i < 3; i++) {\n factory.setImplementation(GameType(i), IDisputeGame(address(fakeClone)));\n }\n\n // Create our first dispute game - this should succeed.\n vm.expectEmit(false, true, true, false);\n emit DisputeGameCreated(address(0), gt, rootClaim);\n IDisputeGame proxy = factory.create(gt, rootClaim, extraData);\n\n // Ensure that the dispute game was assigned to the `disputeGames` mapping.\n assertEq(address(factory.games(gt, rootClaim, extraData)), address(proxy));\n\n // Ensure that the `create` function reverts when called with parameters that would result in the same UUID.\n vm.expectRevert(\n abi.encodeWithSelector(\n GameAlreadyExists.selector,\n factory.getGameUUID(gt, rootClaim, extraData)\n )\n );\n factory.create(gt, rootClaim, extraData);\n }\n\n /**\n * @dev Tests that the `setImplementation` function properly sets the implementation for a given `GameType`.\n */\n function test_setImplementation_succeeds() public {\n // There should be no implementation for the `GameType.FAULT` enum value, it has not been set.\n assertEq(address(factory.gameImpls(GameType.FAULT)), address(0));\n\n vm.expectEmit(true, true, true, true, address(factory));\n emit ImplementationSet(address(1), GameType.FAULT);\n\n // Set the implementation for the `GameType.FAULT` enum value.\n factory.setImplementation(GameType.FAULT, IDisputeGame(address(1)));\n\n // Ensure that the implementation for the `GameType.FAULT` enum value is set.\n assertEq(address(factory.gameImpls(GameType.FAULT)), address(1));\n }\n\n /**\n * @dev Tests that the `setImplementation` function reverts when called by a non-owner.\n */\n function test_setImplementation_notOwner_reverts() public {\n // Ensure that the `setImplementation` function reverts when called by a non-owner.\n vm.prank(address(0));\n vm.expectRevert(\"Ownable: caller is not the owner\");\n factory.setImplementation(GameType.FAULT, IDisputeGame(address(1)));\n }\n\n /**\n * @dev Tests that the `getGameUUID` function returns the correct hash when comparing\n * against the keccak256 hash of the abi-encoded parameters.\n */\n function testDiff_getGameUUID_succeeds(\n uint8 gameType,\n Claim rootClaim,\n bytes calldata extraData\n ) public {\n // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.\n GameType gt = GameType(uint8(bound(gameType, 0, 2)));\n\n assertEq(\n Hash.unwrap(factory.getGameUUID(gt, rootClaim, extraData)),\n keccak256(abi.encode(gt, rootClaim, extraData))\n );\n }\n\n /**\n * @dev Tests that the `owner` function returns the correct address after deployment.\n */\n function test_owner_succeeds() public {\n assertEq(factory.owner(), address(this));\n }\n\n /**\n * @dev Tests that the `transferOwnership` function succeeds when called by the owner.\n */\n function test_transferOwnership_succeeds() public {\n factory.transferOwnership(address(1));\n assertEq(factory.owner(), address(1));\n }\n\n /**\n * @dev Tests that the `transferOwnership` function reverts when called by a non-owner.\n */\n function test_transferOwnership_notOwner_reverts() public {\n vm.prank(address(0));\n vm.expectRevert(\"Ownable: caller is not the owner\");\n factory.transferOwnership(address(1));\n }\n}\n\n/**\n * @dev A fake clone used for testing the `DisputeGameFactory` contract's `create` function.\n */\ncontract FakeClone {\n function initialize() external {\n // noop\n }\n}\n" - }, - "contracts/test/Encoding.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Encoding_Test is CommonTest {\n function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external {\n (uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(\n Encoding.encodeVersionedNonce(_nonce, _version)\n );\n assertEq(version, _version);\n assertEq(nonce, _nonce);\n }\n\n function testDiff_decodeVersionedNonce_succeeds(uint240 _nonce, uint16 _version) external {\n uint256 nonce = uint256(Encoding.encodeVersionedNonce(_nonce, _version));\n (uint256 decodedNonce, uint256 decodedVersion) = ffi.decodeVersionedNonce(nonce);\n\n assertEq(_version, uint16(decodedVersion));\n\n assertEq(_nonce, uint240(decodedNonce));\n }\n\n function testDiff_encodeCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint8 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint8 version = _version % 2;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory encoding = Encoding.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n bytes memory _encoding = ffi.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n assertEq(encoding, _encoding);\n }\n\n function testFuzz_encodeCrossDomainMessageV0_matchesLegacy_succeeds(\n uint240 _nonce,\n address _sender,\n address _target,\n bytes memory _data\n ) external {\n uint8 version = 0;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory legacyEncoding = LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _data,\n nonce\n );\n\n bytes memory bedrockEncoding = Encoding.encodeCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n nonce\n );\n\n assertEq(legacyEncoding, bedrockEncoding);\n }\n\n function testDiff_encodeDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bool isCreate,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n Types.UserDepositTransaction memory t = Types.UserDepositTransaction(\n _from,\n _to,\n isCreate,\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n );\n\n bytes memory txn = Encoding.encodeDepositTransaction(t);\n bytes memory _txn = ffi.encodeDepositTransaction(t);\n\n assertEq(txn, _txn);\n }\n}\n" - }, - "contracts/test/FeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { L1FeeVault } from \"../L2/L1FeeVault.sol\";\nimport { BaseFeeVault } from \"../L2/BaseFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n// Test the implementations of the FeeVault\ncontract FeeVault_Test is Bridge_Initializer {\n BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));\n L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT));\n\n address constant recipient = address(0x10000);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.BASE_FEE_VAULT, address(new BaseFeeVault(recipient)).code);\n vm.etch(Predeploys.L1_FEE_VAULT, address(new L1FeeVault(recipient)).code);\n\n vm.label(Predeploys.BASE_FEE_VAULT, \"BaseFeeVault\");\n vm.label(Predeploys.L1_FEE_VAULT, \"L1FeeVault\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(baseFeeVault.RECIPIENT(), recipient);\n assertEq(l1FeeVault.RECIPIENT(), recipient);\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n}\n" - }, - "contracts/test/GasPriceOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GasPriceOracle } from \"../L2/GasPriceOracle.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract GasPriceOracle_Test is CommonTest {\n event OverheadUpdated(uint256);\n event ScalarUpdated(uint256);\n event DecimalsUpdated(uint256);\n\n GasPriceOracle gasOracle;\n L1Block l1Block;\n address depositor;\n\n // set the initial L1 context values\n uint64 constant number = 10;\n uint64 constant timestamp = 11;\n uint256 constant basefee = 100;\n bytes32 constant hash = bytes32(uint256(64));\n uint64 constant sequenceNumber = 0;\n bytes32 constant batcherHash = bytes32(uint256(777));\n uint256 constant l1FeeOverhead = 310;\n uint256 constant l1FeeScalar = 10;\n\n function setUp() public virtual override {\n super.setUp();\n // place the L1Block contract at the predeploy address\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n\n l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n depositor = l1Block.DEPOSITOR_ACCOUNT();\n\n // We are not setting the gas oracle at its predeploy\n // address for simplicity purposes. Nothing in this test\n // requires it to be at a particular address\n gasOracle = new GasPriceOracle();\n\n vm.prank(depositor);\n l1Block.setL1BlockValues({\n _number: number,\n _timestamp: timestamp,\n _basefee: basefee,\n _hash: hash,\n _sequenceNumber: sequenceNumber,\n _batcherHash: batcherHash,\n _l1FeeOverhead: l1FeeOverhead,\n _l1FeeScalar: l1FeeScalar\n });\n }\n\n function test_l1BaseFee_succeeds() external {\n assertEq(gasOracle.l1BaseFee(), basefee);\n }\n\n function test_gasPrice_succeeds() external {\n vm.fee(100);\n uint256 gasPrice = gasOracle.gasPrice();\n assertEq(gasPrice, 100);\n }\n\n function test_baseFee_succeeds() external {\n vm.fee(64);\n uint256 gasPrice = gasOracle.baseFee();\n assertEq(gasPrice, 64);\n }\n\n function test_scalar_succeeds() external {\n assertEq(gasOracle.scalar(), l1FeeScalar);\n }\n\n function test_overhead_succeeds() external {\n assertEq(gasOracle.overhead(), l1FeeOverhead);\n }\n\n function test_decimals_succeeds() external {\n assertEq(gasOracle.decimals(), 6);\n assertEq(gasOracle.DECIMALS(), 6);\n }\n\n // Removed in bedrock\n function test_setGasPrice_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setGasPrice(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n\n // Removed in bedrock\n function test_setL1BaseFee_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setL1BaseFee(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n}\n" - }, - "contracts/test/GovernanceToken.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract GovernanceToken_Test is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n\n function setUp() public virtual override {\n super.setUp();\n vm.prank(owner);\n gov = new GovernanceToken();\n }\n\n function test_constructor_succeeds() external {\n assertEq(gov.owner(), owner);\n assertEq(gov.name(), \"Optimism\");\n assertEq(gov.symbol(), \"OP\");\n assertEq(gov.decimals(), 18);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_mint_fromOwner_succeeds() external {\n // Mint 100 tokens.\n vm.prank(owner);\n gov.mint(owner, 100);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 100);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_mint_fromNotOwner_reverts() external {\n // Mint 100 tokens as rando.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n gov.mint(owner, 100);\n\n // Balance does not update.\n assertEq(gov.balanceOf(owner), 0);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_burn_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando burns their tokens.\n vm.prank(rando);\n gov.burn(50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_burnFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to burn 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner burns 50 tokens from rando.\n vm.prank(owner);\n gov.burnFrom(rando, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_transfer_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando transfers 50 tokens to owner.\n vm.prank(rando);\n gov.transfer(owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_approve_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n\n function test_transferFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner transfers 50 tokens from rando to owner.\n vm.prank(owner);\n gov.transferFrom(rando, owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_increaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Rando increases allowance by 50 tokens.\n vm.prank(rando);\n gov.increaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 100);\n }\n\n function test_decreaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 100 tokens.\n vm.prank(rando);\n gov.approve(owner, 100);\n\n // Rando decreases allowance by 50 tokens.\n vm.prank(rando);\n gov.decreaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n}\n" - }, - "contracts/test/Hashing.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Hashing_hashDepositSource_Test is CommonTest {\n /**\n * @notice Tests that hashDepositSource returns the correct hash in a simple case.\n */\n function test_hashDepositSource_succeeds() external {\n assertEq(\n Hashing.hashDepositSource(\n 0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,\n 0x1\n ),\n 0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc\n );\n }\n}\n\ncontract Hashing_hashCrossDomainMessage_Test is CommonTest {\n /**\n * @notice Tests that hashCrossDomainMessage returns the correct hash in a simple case.\n */\n function testDiff_hashCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint16 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Ensure the version is valid.\n uint16 version = uint16(bound(uint256(_version), 0, 1));\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n assertEq(\n Hashing.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data),\n ffi.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n\n /**\n * @notice Tests that hashCrossDomainMessageV0 matches the hash of the legacy encoding.\n */\n function testFuzz_hashCrossDomainMessageV0_matchesLegacy_succeeds(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) external {\n assertEq(\n keccak256(\n LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _message,\n _messageNonce\n )\n ),\n Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _messageNonce)\n );\n }\n}\n\ncontract Hashing_hashWithdrawal_Test is CommonTest {\n /**\n * @notice Tests that hashWithdrawal returns the correct hash in a simple case.\n */\n function testDiff_hashWithdrawal_succeeds(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n assertEq(\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)\n ),\n ffi.hashWithdrawal(_nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n}\n\ncontract Hashing_hashOutputRootProof_Test is CommonTest {\n /**\n * @notice Tests that hashOutputRootProof returns the correct hash in a simple case.\n */\n function testDiff_hashOutputRootProof_succeeds(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external {\n assertEq(\n Hashing.hashOutputRootProof(\n Types.OutputRootProof({\n version: _version,\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _messagePasserStorageRoot,\n latestBlockhash: _latestBlockhash\n })\n ),\n ffi.hashOutputRootProof(\n _version,\n _stateRoot,\n _messagePasserStorageRoot,\n _latestBlockhash\n )\n );\n }\n}\n\ncontract Hashing_hashDepositTransaction_Test is CommonTest {\n /**\n * @notice Tests that hashDepositTransaction returns the correct hash in a simple case.\n */\n function testDiff_hashDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n assertEq(\n Hashing.hashDepositTransaction(\n Types.UserDepositTransaction(\n _from,\n _to,\n false, // isCreate\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n )\n ),\n ffi.hashDepositTransaction(_from, _to, _mint, _value, _gas, _data, _logIndex)\n );\n }\n}\n" - }, - "contracts/test/L1Block.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\ncontract L1BlockTest is CommonTest {\n L1Block lb;\n address depositor;\n bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));\n\n function setUp() public virtual override {\n super.setUp();\n lb = new L1Block();\n depositor = lb.DEPOSITOR_ACCOUNT();\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: uint64(1),\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: NON_ZERO_HASH,\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(0),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function testFuzz_updatesValues_succeeds(\n uint64 n,\n uint64 t,\n uint256 b,\n bytes32 h,\n uint64 s,\n bytes32 bt,\n uint256 fo,\n uint256 fs\n ) external {\n vm.prank(depositor);\n lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs);\n assertEq(lb.number(), n);\n assertEq(lb.timestamp(), t);\n assertEq(lb.basefee(), b);\n assertEq(lb.hash(), h);\n assertEq(lb.sequenceNumber(), s);\n assertEq(lb.batcherHash(), bt);\n assertEq(lb.l1FeeOverhead(), fo);\n assertEq(lb.l1FeeScalar(), fs);\n }\n\n function test_number_succeeds() external {\n assertEq(lb.number(), uint64(1));\n }\n\n function test_timestamp_succeeds() external {\n assertEq(lb.timestamp(), uint64(2));\n }\n\n function test_basefee_succeeds() external {\n assertEq(lb.basefee(), 3);\n }\n\n function test_hash_succeeds() external {\n assertEq(lb.hash(), NON_ZERO_HASH);\n }\n\n function test_sequenceNumber_succeeds() external {\n assertEq(lb.sequenceNumber(), uint64(4));\n }\n\n function test_updateValues_succeeds() external {\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: type(uint64).max,\n _timestamp: type(uint64).max,\n _basefee: type(uint256).max,\n _hash: keccak256(abi.encode(1)),\n _sequenceNumber: type(uint64).max,\n _batcherHash: bytes32(type(uint256).max),\n _l1FeeOverhead: type(uint256).max,\n _l1FeeScalar: type(uint256).max\n });\n }\n}\n" - }, - "contracts/test/L1BlockNumber.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { L1BlockNumber } from \"../legacy/L1BlockNumber.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract L1BlockNumberTest is Test {\n L1Block lb;\n L1BlockNumber bn;\n\n uint64 constant number = 99;\n\n function setUp() external {\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n lb = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n bn = new L1BlockNumber();\n vm.prank(lb.DEPOSITOR_ACCOUNT());\n\n lb.setL1BlockValues({\n _number: number,\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: bytes32(uint256(10)),\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(uint256(0)),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function test_getL1BlockNumber_succeeds() external {\n assertEq(bn.getL1BlockNumber(), number);\n }\n\n function test_fallback_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n\n function test_receive_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call{ value: 1 }(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n}\n" - }, - "contracts/test/L1CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle_Initializer } from \"./L2OutputOracle.t.sol\";\n\n/* Libraries */\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n/* Target contract dependencies */\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/* Target contract */\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\n\ncontract L1CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n // the version is encoded in the nonce\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce());\n assertEq(version, L1Messenger.MESSAGE_VERSION());\n }\n\n // sendMessage: should be able to send a single message\n // TODO: this same test needs to be done with the legacy message type\n // by setting the message version to 0\n function test_sendMessage_succeeds() external {\n // deposit transaction on the optimism portal should be called\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n )\n );\n\n // TransactionDeposited event\n vm.expectEmit(true, true, true, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n );\n\n // SentMessage event\n vm.expectEmit(true, true, true, true);\n emit SentMessage(recipient, alice, hex\"ff\", L1Messenger.messageNonce(), 100);\n\n // SentMessageExtension1 event\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(alice, 0);\n\n vm.prank(alice);\n L1Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n // sendMessage: should be able to send the same message twice\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L1Messenger.messageNonce());\n }\n\n function test_xDomainSender_notSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(address(op));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n // relayMessage: should send a successful call to the target contract\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.expectCall(target, hex\"1111\");\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n // set the target to be the OptimismPortal\n address target = address(op);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.prank(address(op));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n\n vm.store(address(op), 0, bytes32(abi.encode(sender)));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: should revert if eth is sent from a contract other than the standard bridge\n function test_replayMessage_withValue_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.expectRevert(\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n L1Messenger.relayMessage{ value: 100 }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n vm.expectCall(target, hex\"1111\");\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacy_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyOldReplay_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Mark legacy message as already relayed.\n uint256 successfulMessagesSlot = 203;\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex\"1111\", 0);\n bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot));\n vm.store(address(L1Messenger), slot, bytes32(uint256(1)));\n\n // Expect revert.\n vm.expectRevert(\"CrossDomainMessenger: legacy withdrawal already relayed\");\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was not relayed.\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyRetryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect FailedRelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacyRetryAfterSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message has already been relayed\");\n\n // Retry the message again.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n}\n" - }, - "contracts/test/L1ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L1ERC721Bridge_Test is Messenger_Initializer {\n TestERC721 internal localToken;\n TestERC721 internal remoteToken;\n L1ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L1ERC721Bridge(address(L1Messenger), otherBridge);\n localToken = new TestERC721();\n remoteToken = new TestERC721();\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L1ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L1Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L1Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notEscrowed_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n" - }, - "contracts/test/L1StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\n\ncontract L1StandardBridge_Getter_Test is Bridge_Initializer {\n function test_getters_succeeds() external {\n assert(L1Bridge.l2TokenBridge() == address(L2Bridge));\n assert(L1Bridge.OTHER_BRIDGE() == L2Bridge);\n assert(L1Bridge.messenger() == L1Messenger);\n assert(L1Bridge.MESSENGER() == L1Messenger);\n assertEq(L1Bridge.version(), \"1.1.0\");\n }\n}\n\ncontract L1StandardBridge_Initialize_Test is Bridge_Initializer {\n function test_initialize_succeeds() external {\n assertEq(address(L1Bridge.messenger()), address(L1Messenger));\n\n assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE);\n\n assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE);\n }\n}\n\ncontract L1StandardBridge_Initialize_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_Receive_Test is Bridge_Initializer {\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(op).balance, 0);\n\n // The legacy event must be emitted for backwards compatibility\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n ),\n 200_000\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L1Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(op).balance, 100);\n }\n}\n\ncontract L1StandardBridge_Receive_TestFail {}\n\ncontract PreBridgeETH is Bridge_Initializer {\n function _preBridgeETH(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 500,\n hex\"dead\"\n );\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex\"dead\")\n );\n }\n vm.expectCall(\n address(L1Messenger),\n 500,\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 50000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 500,\n 50000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 50000);\n vm.expectCall(\n address(op),\n 500,\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 500,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(500),\n uint256(500),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 500, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 500, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 50000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 500);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETH_Test is PreBridgeETH {\n // depositETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_depositETH_succeeds() external {\n _preBridgeETH({ isLegacy: true });\n L1Bridge.depositETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_BridgeETH_Test is PreBridgeETH {\n // BridgeETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETH_succeeds() external {\n _preBridgeETH({ isLegacy: false });\n L1Bridge.bridgeETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer {\n function test_depositETH_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, address(L1Token).code);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice);\n L1Bridge.depositETH{ value: 1 }(300, hex\"\");\n }\n}\n\ncontract PreBridgeETHTo is Bridge_Initializer {\n function _preBridgeETHTo(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex\"dead\")\n );\n }\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n bob,\n 600,\n hex\"dead\"\n );\n\n // the L1 bridge should call\n // L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 60000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 600,\n 60000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 60000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 600,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(600),\n uint256(600),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, bob, 600, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, bob, 600, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 60000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 600);\n\n // deposit eth to bob\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo {\n // depositETHTo\n // - emits ETHDepositInitiated\n // - calls optimismPortal.depositTransaction\n // - EOA or contract can call\n // - ETH ends up in the optimismPortal\n function test_depositETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: true });\n L1Bridge.depositETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo {\n // BridgeETHTo\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: false });\n L1Bridge.bridgeETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // depositERC20\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - only callable by EOA\n function test_depositERC20_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Deal Alice's ERC20 State\n deal(address(L1Token), alice, 100000, true);\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n // The L1Bridge should transfer alice's tokens to itself\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)\n );\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n vm.prank(alice);\n L1Bridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex\"\");\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n }\n}\n\ncontract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer {\n function test_depositERC20_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, hex\"ffff\");\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice, alice);\n L1Bridge.depositERC20(address(0), address(0), 100, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {\n // depositERC20To\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - callable by a contract\n function test_depositERC20To_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n bob,\n 1000,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n deal(address(L1Token), alice, 100000, true);\n\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)\n );\n\n vm.prank(alice);\n L1Bridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex\"\");\n\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 1000);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeETHWithdrawal\n // - emits ETHWithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeETHWithdrawal_succeeds() external {\n uint256 aliceBalance = alice.balance;\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHWithdrawalFinalized(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n vm.expectCall(alice, hex\"\");\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n // ensure that the messenger has ETH to call with\n vm.deal(address(L1Bridge.messenger()), 100);\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n\n assertEq(address(L1Bridge.messenger()).balance, 0);\n assertEq(aliceBalance + 100, alice.balance);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeERC20Withdrawal\n // - updates bridge.deposits\n // - emits ERC20WithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeERC20Withdrawal_succeeds() external {\n deal(address(L1Token), address(L1Bridge), 100, true);\n\n uint256 slot = stdstore\n .target(address(L1Bridge))\n .sig(\"deposits(address,address)\")\n .with_key(address(L1Token))\n .with_key(address(L2Token))\n .find();\n\n // Give the L1 bridge some ERC20 tokens\n vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)\n );\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n assertEq(L1Token.balanceOf(address(L1Bridge)), 0);\n assertEq(L1Token.balanceOf(address(alice)), 100);\n }\n}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer {\n function test_finalizeERC20Withdrawal_notMessenger_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(28));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n\n function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(address(0)))\n );\n vm.prank(address(L1Bridge.messenger()));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer {\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L1Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L1Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce());\n assertEq(version, L2Messenger.MESSAGE_VERSION());\n }\n\n function test_sendMessage_succeeds() external {\n bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage(\n L2Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n );\n vm.expectCall(\n address(messagePasser),\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData\n )\n );\n\n // MessagePassed event\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(L2Messenger),\n address(L1Messenger),\n 0,\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData,\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messagePasser.messageNonce(),\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: L2Messenger.baseGas(hex\"ff\", 100),\n data: xDomainCallData\n })\n )\n );\n\n vm.prank(alice);\n L2Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L2Messenger.messageNonce();\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L2Messenger.messageNonce());\n }\n\n function test_xDomainSender_senderNotSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 2), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n vm.expectCall(target, hex\"1111\");\n\n vm.prank(caller);\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L2Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L2Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n address target = address(messagePasser);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory message = hex\"1111\";\n\n vm.prank(caller);\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retry_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n uint256 value = 100;\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(caller), value);\n vm.prank(caller);\n L2Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L2Messenger.successfulMessages(hash), false);\n assertEq(L2Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L2Messenger.successfulMessages(hash), true);\n assertEq(L2Messenger.failedMessages(hash), true);\n }\n}\n" - }, - "contracts/test/L2ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract TestMintableERC721 is OptimismMintableERC721 {\n constructor(address _bridge, address _remoteToken)\n OptimismMintableERC721(_bridge, 1, _remoteToken, \"Test\", \"TST\")\n {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L2ERC721Bridge_Test is Messenger_Initializer {\n TestMintableERC721 internal localToken;\n TestERC721 internal remoteToken;\n L2ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L2ERC721Bridge(address(L2Messenger), otherBridge);\n remoteToken = new TestERC721();\n localToken = new TestMintableERC721(address(bridge), address(remoteToken));\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L2ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L2Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L2Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L1ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_interfaceNotCompliant_reverts() external {\n // Create a non-compliant token\n NonCompliantERC721 nonCompliantToken = new NonCompliantERC721(alice);\n\n // Bridge the non-compliant token.\n vm.prank(alice);\n bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex\"5678\");\n\n // Attempt to finalize the withdrawal. Should revert because the token does not claim\n // to be compliant with the `IOptimismMintableERC721` interface.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token interface is not compliant\");\n bridge.finalizeBridgeERC721(\n address(address(nonCompliantToken)),\n address(address(0x01)),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_alreadyExists_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721: token already minted\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n\n/**\n * @dev A non-compliant ERC721 token that does not implement the full ERC721 interface.\n *\n * This is used to test that the bridge will revert if the token does not claim to support\n * the ERC721 interface.\n */\ncontract NonCompliantERC721 {\n address internal immutable owner;\n\n constructor(address _owner) {\n owner = _owner;\n }\n\n function ownerOf(uint256) external view returns (address) {\n return owner;\n }\n\n function remoteToken() external pure returns (address) {\n return address(0x01);\n }\n\n function burn(address, uint256) external {\n // Do nothing.\n }\n\n function supportsInterface(bytes4) external pure returns (bool) {\n return false;\n }\n}\n" - }, - "contracts/test/L2OutputOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { L2OutputOracle_Initializer, NextImpl } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2OutputOracleTest is L2OutputOracle_Initializer {\n bytes32 proposedOutput1 = keccak256(abi.encode(1));\n\n function test_constructor_succeeds() external {\n assertEq(oracle.PROPOSER(), proposer);\n assertEq(oracle.CHALLENGER(), owner);\n assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);\n assertEq(oracle.latestBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingTimestamp(), startingTimestamp);\n }\n\n function test_constructor_badTimestamp_reverts() external {\n vm.expectRevert(\"L2OutputOracle: starting L2 timestamp must be less than current time\");\n\n // startingTimestamp is in the future\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp + 1,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function test_constructor_l2BlockTimeZero_reverts() external {\n vm.expectRevert(\"L2OutputOracle: L2 block time must be greater than 0\");\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: 0,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function test_constructor_submissionInterval_reverts() external {\n vm.expectRevert(\"L2OutputOracle: submission interval must be greater than 0\");\n new L2OutputOracle({\n _submissionInterval: 0,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n /****************\n * Getter Tests *\n ****************/\n\n // Test: latestBlockNumber() should return the correct value\n function test_latestBlockNumber_succeeds() external {\n uint256 proposedNumber = oracle.nextBlockNumber();\n\n // Roll to after the block number we'll propose\n warpToProposeTime(proposedNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0);\n assertEq(oracle.latestBlockNumber(), proposedNumber);\n }\n\n // Test: getL2Output() should return the correct value\n function test_getL2Output_succeeds() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0);\n\n Types.OutputProposal memory proposal = oracle.getL2Output(nextOutputIndex);\n assertEq(proposal.outputRoot, proposedOutput1);\n assertEq(proposal.timestamp, block.timestamp);\n\n // The block number is larger than the latest proposed output:\n vm.expectRevert(stdError.indexOOBError);\n oracle.getL2Output(nextOutputIndex + 1);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is exact block\n function test_getL2OutputIndexAfter_sameBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with exact same block as proposed returns the proposal.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is previous block\n function test_getL2OutputIndexAfter_previousBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with previous block returns the proposal too.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 - 1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value during binary search\n function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n bytes32 output2 = keccak256(abi.encode(2));\n uint256 nextBlockNumber2 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber2);\n vm.prank(proposer);\n oracle.proposeL2Output(output2, nextBlockNumber2, 0, 0);\n\n bytes32 output3 = keccak256(abi.encode(3));\n uint256 nextBlockNumber3 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber3);\n vm.prank(proposer);\n oracle.proposeL2Output(output3, nextBlockNumber3, 0, 0);\n\n bytes32 output4 = keccak256(abi.encode(4));\n uint256 nextBlockNumber4 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber4);\n vm.prank(proposer);\n oracle.proposeL2Output(output4, nextBlockNumber4, 0, 0);\n\n // Querying with a block number between the first and second proposal\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 + 1);\n assertEq(index1, 1);\n\n // Querying with a block number between the second and third proposal\n uint256 index2 = oracle.getL2OutputIndexAfter(nextBlockNumber2 + 1);\n assertEq(index2, 2);\n\n // Querying with a block number between the third and fourth proposal\n uint256 index3 = oracle.getL2OutputIndexAfter(nextBlockNumber3 + 1);\n assertEq(index3, 3);\n }\n\n // Test: getL2OutputIndexAfter() reverts when no output exists yet\n function test_getL2OutputIndexAfter_noOutputsExis_reverts() external {\n vm.expectRevert(\"L2OutputOracle: cannot get output as no outputs have been proposed yet\");\n oracle.getL2OutputIndexAfter(0);\n }\n\n // Test: nextBlockNumber() should return the correct value\n function test_nextBlockNumber_succeeds() external {\n assertEq(\n oracle.nextBlockNumber(),\n // The return value should match this arithmetic\n oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL()\n );\n }\n\n function test_computeL2Timestamp_succeeds() external {\n // reverts if timestamp is too low\n vm.expectRevert(stdError.arithmeticError);\n oracle.computeL2Timestamp(startingBlockNumber - 1);\n\n // returns the correct value...\n // ... for the very first block\n assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);\n\n // ... for the first block after the starting block\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 1),\n startingTimestamp + l2BlockTime\n );\n\n // ... for some other block number\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 96024),\n startingTimestamp + l2BlockTime * 96024\n );\n }\n\n /*****************************\n * Propose Tests - Happy Path *\n *****************************/\n\n // Test: proposeL2Output succeeds when given valid input, and no block hash and number are\n // specified.\n function test_proposeL2Output_proposeAnotherOutput_succeeds() public {\n bytes32 proposedOutput2 = keccak256(abi.encode());\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n uint256 proposedNumber = oracle.latestBlockNumber();\n\n // Ensure the submissionInterval is enforced\n assertEq(nextBlockNumber, proposedNumber + submissionInterval);\n\n vm.roll(nextBlockNumber + 1);\n\n vm.expectEmit(true, true, true, true);\n emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp);\n\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output succeeds when given valid input, and when a block hash and number are\n // specified for reorg protection.\n function test_proposeWithBlockhashAndHeight_succeeds() external {\n // Get the number and hash of a previous block in the chain\n uint256 prevL1BlockNumber = block.number - 1;\n bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber);\n }\n\n /***************************\n * Propose Tests - Sad Path *\n ***************************/\n\n // Test: proposeL2Output fails if called by a party that is not the proposer.\n function test_proposeL2Output_notProposer_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n\n vm.prank(address(128));\n vm.expectRevert(\"L2OutputOracle: only the proposer address can propose new outputs\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails given a zero blockhash.\n function test_proposeL2Output_emptyOutput_reverts() external {\n bytes32 outputToPropose = bytes32(0);\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: L2 output proposal cannot be the zero hash\");\n oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if the block number doesn't match the next expected number.\n function test_proposeL2Output_unexpectedBlockNumber_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: block number must be equal to next expected block number\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);\n }\n\n // Test: proposeL2Output fails if it would have a timestamp in the future.\n function test_proposeL2Output_futureTimetamp_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber);\n vm.warp(nextTimestamp);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: cannot propose L2 output in the future\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if a non-existent L1 block hash and number are provided for reorg\n // protection.\n function test_proposeL2Output_wrongFork_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(\n nonZeroHash,\n nextBlockNumber,\n bytes32(uint256(0x01)),\n block.number - 1\n );\n }\n\n // Test: proposeL2Output fails when given valid input, but the block hash and number do not\n // match.\n function test_proposeL2Output_unmatchedBlockhash_reverts() external {\n // Move ahead to block 100 so that we can reference historical blocks\n vm.roll(100);\n\n // Get the number and hash of a previous block in the chain\n uint256 l1BlockNumber = block.number - 1;\n bytes32 l1BlockHash = blockhash(l1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n\n // This will fail when foundry no longer returns zerod block hashes\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);\n }\n\n /*****************************\n * Delete Tests - Happy Path *\n *****************************/\n\n function test_deleteOutputs_singleOutput_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 1);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex);\n oracle.deleteL2Outputs(latestOutputIndex);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n function test_deleteOutputs_multipleOutputs_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 3);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n /***************************\n * Delete Tests - Sad Path *\n ***************************/\n\n function test_deleteL2Outputs_ifNotChallenger_reverts() external {\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.expectRevert(\"L2OutputOracle: only the challenger address can delete outputs\");\n oracle.deleteL2Outputs(latestBlockNumber);\n }\n\n function test_deleteL2Outputs_nonExistent_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestBlockNumber + 1);\n }\n\n function test_deleteL2Outputs_afterLatest_reverts() external {\n // Start by proposing three outputs\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Delete the latest two outputs\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n vm.prank(owner);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // Now try to delete the same output again\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n }\n\n function test_deleteL2Outputs_finalized_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Warp past the finalization period + 1 second\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n\n // Try to delete a finalized output\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs that have already been finalized\");\n oracle.deleteL2Outputs(latestOutputIndex);\n }\n}\n\ncontract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {\n Proxy internal proxy;\n\n function setUp() public override {\n super.setUp();\n proxy = Proxy(payable(address(oracle)));\n }\n\n function test_initValuesOnProxy_succeeds() external {\n assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());\n assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());\n assertEq(startingBlockNumber, oracleImpl.startingBlockNumber());\n assertEq(startingTimestamp, oracleImpl.startingTimestamp());\n\n assertEq(proposer, oracleImpl.PROPOSER());\n assertEq(owner, oracleImpl.CHALLENGER());\n }\n\n function test_initializeProxy_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(payable(proxy)).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_initializeImpl_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(oracleImpl).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(oracle), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(oracle), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(oracle)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/L2StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { console } from \"forge-std/console.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\ncontract L2StandardBridge_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n function test_initialize_succeeds() external {\n assertEq(address(L2Bridge.messenger()), address(L2Messenger));\n assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge));\n assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge));\n }\n\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(messagePasser).balance, 0);\n uint256 nonce = L2Messenger.messageNonce();\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 200_000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 100,\n 200_000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 100,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n // L2ToL1MessagePasser will emit a MessagePassed event\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 100,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 200_000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 100);\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L2Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(messagePasser).balance, 100);\n }\n\n // withrdraw\n // - requires amount == msg.value\n function test_withdraw_insufficientValue_reverts() external {\n assertEq(address(messagePasser).balance, 0);\n\n vm.expectRevert(\"StandardBridge: bridging ETH must include sufficient ETH value\");\n vm.prank(alice, alice);\n L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex\"\");\n }\n\n /**\n * @notice Use the legacy `withdraw` interface on the L2StandardBridge to\n * withdraw ether from L2 to L1.\n */\n function test_withdraw_ether_succeeds() external {\n assertTrue(alice.balance >= 100);\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0);\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated({\n l1Token: address(0),\n l2Token: Predeploys.LEGACY_ERC20_ETH,\n from: alice,\n to: alice,\n amount: 100,\n data: hex\"\"\n });\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex\"\" });\n\n vm.prank(alice, alice);\n L2Bridge.withdraw{ value: 100 }({\n _l2Token: Predeploys.LEGACY_ERC20_ETH,\n _amount: 100,\n _minGasLimit: 1000,\n _extraData: hex\"\"\n });\n\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 100);\n }\n}\n\ncontract PreBridgeERC20 is Bridge_Initializer {\n // withdraw and BridgeERC20 should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20(bool _isLegacy, address _l2Token) internal {\n // Alice has 100 L2Token\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(_l2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex\"\")\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20.selector,\n _l2Token,\n address(L1Token),\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n _l2Token,\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {\n // withdraw\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_withdraw_withdrawingERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // BridgeERC20\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdrawLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) });\n L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_bridgeLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) });\n L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdraw_notEOA_reverts() external {\n // This contract has 100 L2Token\n deal(address(L2Token), address(this), 100, true);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n }\n}\n\ncontract PreBridgeERC20To is Bridge_Initializer {\n // withdrawTo and BridgeERC20To should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal {\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(L2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n bob,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.withdrawTo.selector,\n _l2Token,\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20To.selector,\n _l2Token,\n address(L1Token),\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {\n // withdrawTo\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_withdrawTo_withdrawingERC20_succeeds() external {\n _preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // bridgeERC20To\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20To_succeeds() external {\n _preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex\"\");\n assertEq(L2Token.balanceOf(alice), 0);\n }\n}\n\ncontract L2StandardBridge_Bridge_Test is Bridge_Initializer {\n // finalizeDeposit\n // - only callable by l1TokenBridge\n // - supported token pair emits DepositFinalized\n // - invalid deposit calls Withdrawer.initiateWithdrawal\n function test_finalizeDeposit_depositingERC20_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex\"\");\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeDeposit_depositingETH_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(\n address(L2Token), // localToken\n address(L1Token), // remoteToken\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Messenger), 100, hex\"\");\n }\n}\n\ncontract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L2Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true);\n emit DepositFinalized(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2ToL1MessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\n\ncontract L2ToL1MessagePasserTest is CommonTest {\n L2ToL1MessagePasser messagePasser;\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new L2ToL1MessagePasser();\n }\n\n function testFuzz_initiateWithdrawal_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint256 nonce = messagePasser.messageNonce();\n\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: _value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash);\n\n vm.deal(_sender, _value);\n vm.prank(_sender);\n messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);\n\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0)));\n\n assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1)));\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by a contract\n function test_initiateWithdrawal_fromContract_succeeds() external {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\"\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\",\n withdrawalHash\n );\n\n vm.deal(address(this), 2**64);\n messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex\"\");\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by an EOA\n function test_initiateWithdrawal_fromEOA_succeeds() external {\n uint256 gasLimit = 64000;\n address target = address(4);\n uint256 value = 100;\n bytes memory data = hex\"ff\";\n uint256 nonce = messagePasser.messageNonce();\n\n // EOA emulation\n vm.prank(alice, alice);\n vm.deal(alice, 2**64);\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data)\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash);\n\n messagePasser.initiateWithdrawal{ value: value }(target, gasLimit, data);\n\n // the sent messages mapping is filled\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n // the nonce increments\n assertEq(nonce + 1, messagePasser.messageNonce());\n }\n\n // Test: burn should destroy the ETH held in the contract\n function test_burn_succeeds() external {\n messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n NON_ZERO_GASLIMIT,\n NON_ZERO_DATA\n );\n\n assertEq(address(messagePasser).balance, NON_ZERO_VALUE);\n vm.expectEmit(true, false, false, false);\n emit WithdrawerBalanceBurnt(NON_ZERO_VALUE);\n messagePasser.burn();\n\n // The Withdrawer should have no balance\n assertEq(address(messagePasser).balance, 0);\n }\n}\n" - }, - "contracts/test/LegacyERC20ETH.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyERC20ETH_Test is CommonTest {\n LegacyERC20ETH eth;\n\n function setUp() public virtual override {\n super.setUp();\n eth = new LegacyERC20ETH();\n }\n\n function test_metadata_succeeds() external {\n assertEq(eth.name(), \"Ether\");\n assertEq(eth.symbol(), \"ETH\");\n assertEq(eth.decimals(), 18);\n }\n\n function test_crossDomain_succeeds() external {\n assertEq(eth.l2Bridge(), Predeploys.L2_STANDARD_BRIDGE);\n assertEq(eth.l1Token(), address(0));\n }\n\n function test_transfer_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transfer is disabled\");\n eth.transfer(alice, 100);\n }\n\n function test_approve_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: approve is disabled\");\n eth.approve(alice, 100);\n }\n\n function test_transferFrom_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transferFrom is disabled\");\n eth.transferFrom(bob, alice, 100);\n }\n\n function test_increaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n eth.increaseAllowance(alice, 100);\n }\n\n function test_decreaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n eth.decreaseAllowance(alice, 100);\n }\n\n function test_mint_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: mint is disabled\");\n eth.mint(alice, 100);\n }\n\n function test_burn_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: burn is disabled\");\n eth.burn(alice, 100);\n }\n}\n" - }, - "contracts/test/LegacyMessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyMessagePasser } from \"../legacy/LegacyMessagePasser.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyMessagePasser_Test is CommonTest {\n LegacyMessagePasser messagePasser;\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new LegacyMessagePasser();\n }\n\n function test_passMessageToL1_succeeds() external {\n vm.prank(alice);\n messagePasser.passMessageToL1(hex\"ff\");\n assert(messagePasser.sentMessages(keccak256(abi.encodePacked(hex\"ff\", alice))));\n }\n}\n" - }, - "contracts/test/MerkleTrie.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MerkleTrie } from \"../libraries/trie/MerkleTrie.sol\";\n\ncontract MerkleTrie_get_Test is CommonTest {\n function test_get_validProof1_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579326262\";\n bytes memory val = hex\"6176616c32\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof2_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[\n 2\n ] = hex\"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof3_succeeds() external {\n bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof4_succeeds() external {\n bytes32 root = 0x37956bab6bba472308146808d5311ac19cb4a7daae5df7efcc0f32badc97f55e;\n bytes memory key = hex\"6b6579316161\";\n bytes memory val = hex\"3031323334\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"ce87206b6579316161853031323334\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof5_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657931\";\n bytes\n memory val = hex\"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof6_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657932\";\n bytes memory val = hex\"73686f7274\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[2] = hex\"df808080808080c9823262856176616c338080808080808080808573686f7274\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof7_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657933\";\n bytes memory val = hex\"31323334353637383930313233343536373839303132333435363738393031\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof8_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"61\";\n bytes memory val = hex\"61\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22061\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof9_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"62\";\n bytes memory val = hex\"62\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22062\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof10_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"63\";\n bytes memory val = hex\"63\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22063\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_nonexistentKey1_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b657932\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_nonexistentKey2_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"616e7972616e646f6d6b6579\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_wrongKeyProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579316161\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[2] = hex\"d687206e6f746865728d33343938683472697568677765\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_corruptedProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579326262\";\n bytes[] memory proof = new bytes[](5);\n proof[0] = hex\"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[\n 2\n ] = hex\"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 3\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[4] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidDataRemainder_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa000000000000000000000000000000\";\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidInternalNodeHash_reverts() external {\n bytes32 root = 0xa827dff1a657bb9bb9a1c3abe9db173e2f1359f15eb06f1647ea21ac7c95d8fa;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157\";\n proof[\n 1\n ] = hex\"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080\";\n proof[2] = hex\"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroBranchValueLength_reverts() external {\n bytes32 root = 0xe04b3589eef96b237cd49ccb5dcf6e654a47682bfa0961d563ab843f7ad1e035;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](2);\n proof[0] = hex\"dd8200aad98080808080808080808080c43b82aabbc43c82aacc80808080\";\n proof[1] = hex\"d98080808080808080808080c43b82aabbc43c82aacc80808080\";\n\n vm.expectRevert(\"MerkleTrie: value length must be greater than zero (branch)\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroLengthKey_reverts() external {\n bytes32 root = 0x54157fd62cdf2f474e7bfec2d3cd581e807bee38488c9590cb887add98936b73;\n bytes memory key = hex\"\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"c78320f00082b443\";\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey1_reverts() external {\n bytes32 root = 0xa513ba530659356fb7588a2c831944e80fd8aedaa5a4dc36f918152be2be0605;\n bytes memory key = hex\"01\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"db10d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[1] = hex\"d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[2] = hex\"c582202381aa\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey2_reverts() external {\n bytes32 root = 0xa06abffaec4ebe8ccde595f4547b864b4421b21c1fc699973f94710c9bc17979;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905\";\n proof[\n 1\n ] = hex\"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080\";\n proof[2] = hex\"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_extraProofElements_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](4);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa\";\n proof[3] = hex\"c32081aa\";\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_validProofs_succeeds(bytes4) external {\n // Generate a test case with a valid proof of inclusion for the k/v pair in the trie.\n (bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi\n .getMerkleTrieFuzzCase(\"valid\");\n\n // Assert that our expected value is equal to our actual value.\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidRoot_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"valid\"\n );\n\n bytes32 rootHash = keccak256(abi.encodePacked(root));\n vm.expectRevert(\"MerkleTrie: invalid root hash\");\n MerkleTrie.get(key, proof, rootHash);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_extraProofElements_reverts(bytes4) external {\n // Generate an invalid test case with an extra proof element attached to an otherwise\n // valid proof of inclusion for the passed k/v.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"extra_proof_elems\"\n );\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external {\n // Generate an invalid test case where a long proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_large_internal_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid large internal hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external {\n // Generate an invalid test case where a small proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_internal_node_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_corruptedProof_reverts(bytes4) external {\n // Generate an invalid test case where the proof is malformed.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"corrupted_proof\"\n );\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidDataRemainder_reverts(bytes4) external {\n // Generate an invalid test case where a random element of the proof has more bytes than the\n // length designates within the RLP list encoding.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_data_remainder\"\n );\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_prefixedValidKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and a valid key that is prefixed\n // with random bytes\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"prefixed_valid_key\"\n );\n\n // Ambiguous revert check- all that we care is that it *does* fail. This case may\n // fail within different branches.\n vm.expectRevert();\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_emptyKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and an empty key\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"empty_key\"\n );\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_partialProof_reverts(bytes4) external {\n // Get a random test case with a valid trie / partially correct proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"partial_proof\"\n );\n\n vm.expectRevert(\"MerkleTrie: ran out of proof elements\");\n MerkleTrie.get(key, proof, root);\n }\n}\n" - }, - "contracts/test/MintManager.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MintManager } from \"../governance/MintManager.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract MintManager_Initializer is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n MintManager internal manager;\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.prank(owner);\n gov = new GovernanceToken();\n\n vm.prank(owner);\n manager = new MintManager(owner, address(gov));\n\n vm.prank(owner);\n gov.transferOwnership(address(manager));\n }\n}\n\ncontract MintManager_constructor_Test is MintManager_Initializer {\n /**\n * @notice Tests that the constructor properly configures the contract.\n */\n function test_constructor_succeeds() external {\n assertEq(manager.owner(), owner);\n assertEq(address(manager.governanceToken()), address(gov));\n }\n}\n\ncontract MintManager_mint_Test is MintManager_Initializer {\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner.\n */\n function test_mint_fromOwner_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the mint function reverts when called by a non-owner.\n */\n function test_mint_fromNotOwner_reverts() external {\n // Mint from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.mint(owner, 100);\n }\n\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner a second\n * time after the mint period has elapsed.\n */\n function test_mint_afterPeriodElapsed_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again after period elapsed (2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n manager.mint(owner, 2);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 102);\n }\n\n /**\n * @notice Tests that the mint function always reverts when called before the mint period has\n * elapsed, even if the caller is the owner.\n */\n function test_mint_beforePeriodElapsed_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: minting not permitted yet\");\n manager.mint(owner, 100);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the owner cannot mint more than the mint cap.\n */\n function test_mint_moreThanCap_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again (greater than 2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint amount exceeds cap\");\n manager.mint(owner, 3);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n}\n\ncontract MintManager_upgrade_Test is MintManager_Initializer {\n /**\n * @notice Tests that the owner can upgrade the mint manager.\n */\n function test_upgrade_fromOwner_succeeds() external {\n // Upgrade to new manager.\n vm.prank(owner);\n manager.upgrade(rando);\n\n // New manager is rando.\n assertEq(gov.owner(), rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when called by a non-owner.\n */\n function test_upgrade_fromNotOwner_reverts() external {\n // Upgrade from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.upgrade(rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when attempting to update to the zero\n * address, even if the caller is the owner.\n */\n function test_upgrade_toZeroAddress_reverts() external {\n // Upgrade to zero address fails.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint manager cannot be the zero address\");\n manager.upgrade(address(0));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport {\n ILegacyMintableERC20,\n IOptimismMintableERC20\n} from \"../universal/IOptimismMintableERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract OptimismMintableERC20_Test is Bridge_Initializer {\n event Mint(address indexed account, uint256 amount);\n event Burn(address indexed account, uint256 amount);\n\n function test_semver_succeeds() external {\n assertEq(L2Token.version(), \"1.0.0\");\n }\n\n function test_remoteToken_succeeds() external {\n assertEq(L2Token.remoteToken(), address(L1Token));\n }\n\n function test_bridge_succeeds() external {\n assertEq(L2Token.bridge(), address(L2Bridge));\n }\n\n function test_l1Token_succeeds() external {\n assertEq(L2Token.l1Token(), address(L1Token));\n }\n\n function test_l2Bridge_succeeds() external {\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_legacy_succeeds() external {\n // Getters for the remote token\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.l1Token(), address(L1Token));\n // Getters for the bridge\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_mint_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 100);\n }\n\n function test_mint_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.mint(alice, 100);\n }\n\n function test_burn_succeeds() external {\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_burn_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.burn(alice, 100);\n }\n\n function test_erc165_supportsInterface_succeeds() external {\n // The assertEq calls in this test are comparing the manual calculation of the iface,\n // with what is returned by the solidity's type().interfaceId, just to be safe.\n bytes4 iface1 = bytes4(keccak256(\"supportsInterface(bytes4)\"));\n assertEq(iface1, type(IERC165).interfaceId);\n assert(L2Token.supportsInterface(iface1));\n\n bytes4 iface2 = L2Token.l1Token.selector ^ L2Token.mint.selector ^ L2Token.burn.selector;\n assertEq(iface2, type(ILegacyMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface2));\n\n bytes4 iface3 = L2Token.remoteToken.selector ^\n L2Token.bridge.selector ^\n L2Token.mint.selector ^\n L2Token.burn.selector;\n assertEq(iface3, type(IOptimismMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface3));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\n\ncontract OptimismMintableTokenFactory_Test is Bridge_Initializer {\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_bridge_succeeds() external {\n assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge));\n }\n\n function test_createStandardL2Token_succeeds() external {\n address remote = address(4);\n address local = LibRLP.computeAddress(address(L2TokenFactory), 2);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_sameTwice_succeeds() external {\n address remote = address(4);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n\n address local = LibRLP.computeAddress(address(L2TokenFactory), 3);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_remoteIsZero_succeeds() external {\n address remote = address(0);\n vm.expectRevert(\"OptimismMintableERC20Factory: must provide remote token address\");\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721, IERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport {\n OptimismMintableERC721,\n IOptimismMintableERC721\n} from \"../universal/OptimismMintableERC721.sol\";\n\ncontract OptimismMintableERC721_Test is ERC721Bridge_Initializer {\n ERC721 internal L1Token;\n OptimismMintableERC721 internal L2Token;\n\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n event Mint(address indexed account, uint256 tokenId);\n\n event Burn(address indexed account, uint256 tokenId);\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n L1Token = new ERC721(\"L1Token\", \"L1T\");\n L2Token = new OptimismMintableERC721(\n address(L2Bridge),\n 1,\n address(L1Token),\n \"L2Token\",\n \"L2T\"\n );\n\n // Label the addresses for nice traces.\n vm.label(address(L1Token), \"L1ERC721Token\");\n vm.label(address(L2Token), \"L2ERC721Token\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(L2Token.name(), \"L2Token\");\n assertEq(L2Token.symbol(), \"L2T\");\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.remoteChainId(), 1);\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.REMOTE_CHAIN_ID(), 1);\n assertEq(L2Token.version(), \"1.1.0\");\n }\n\n /**\n * @notice Ensure that the contract supports the expected interfaces.\n */\n function test_supportsInterfaces_succeeds() external {\n // Checks if the contract supports the IOptimismMintableERC721 interface.\n assertTrue(L2Token.supportsInterface(type(IOptimismMintableERC721).interfaceId));\n // Checks if the contract supports the IERC721Enumerable interface.\n assertTrue(L2Token.supportsInterface(type(IERC721Enumerable).interfaceId));\n // Checks if the contract supports the IERC721 interface.\n assertTrue(L2Token.supportsInterface(type(IERC721).interfaceId));\n // Checks if the contract supports the IERC165 interface.\n assertTrue(L2Token.supportsInterface(type(IERC165).interfaceId));\n }\n\n function test_safeMint_succeeds() external {\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(address(0), alice, 1);\n\n // Expect a mint event.\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 1);\n\n // Mint the token.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token should be owned by alice.\n assertEq(L2Token.ownerOf(1), alice);\n }\n\n function test_safeMint_notBridge_reverts() external {\n // Try to mint the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.safeMint(alice, 1);\n }\n\n function test_burn_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(alice, address(0), 1);\n\n // Expect a burn event.\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 1);\n\n // Burn the token.\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 1);\n\n // Token should be owned by address(0).\n vm.expectRevert(\"ERC721: invalid token ID\");\n L2Token.ownerOf(1);\n }\n\n function test_burn_notBridge_reverts() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Try to burn the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.burn(alice, 1);\n }\n\n function test_tokenURI_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token URI should be correct.\n assertEq(\n L2Token.tokenURI(1),\n string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(address(L1Token)), 20),\n \"@\",\n Strings.toString(1),\n \"/tokenURI?uint256=\",\n Strings.toString(1)\n )\n )\n );\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\n\ncontract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {\n OptimismMintableERC721Factory internal factory;\n\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n factory = new OptimismMintableERC721Factory(address(L2Bridge), 1);\n\n // Label the addresses for nice traces.\n vm.label(address(factory), \"OptimismMintableERC721Factory\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(factory.BRIDGE(), address(L2Bridge));\n assertEq(factory.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_succeeds() external {\n // Predict the address based on the factory address and nonce.\n address predicted = LibRLP.computeAddress(address(factory), 1);\n\n // Expect a token creation event.\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC721Created(predicted, address(1234), alice);\n\n // Create the token.\n vm.prank(alice);\n OptimismMintableERC721 created = OptimismMintableERC721(\n factory.createOptimismMintableERC721(address(1234), \"L2Token\", \"L2T\")\n );\n\n // Token address should be correct.\n assertEq(address(created), predicted);\n\n // Should be marked as created by the factory.\n assertEq(factory.isOptimismMintableERC721(address(created)), true);\n\n // Token should've been constructed correctly.\n assertEq(created.name(), \"L2Token\");\n assertEq(created.symbol(), \"L2T\");\n assertEq(created.REMOTE_TOKEN(), address(1234));\n assertEq(created.BRIDGE(), address(L2Bridge));\n assertEq(created.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_zeroRemoteToken_reverts() external {\n // Try to create a token with a zero remote token address.\n vm.expectRevert(\"OptimismMintableERC721Factory: L1 token address cannot be address(0)\");\n factory.createOptimismMintableERC721(address(0), \"L2Token\", \"L2T\");\n }\n}\n" - }, - "contracts/test/OptimismPortal.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { Portal_Initializer, CommonTest, NextImpl } from \"./CommonTest.t.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\ncontract OptimismPortal_Test is Portal_Initializer {\n event Paused(address);\n event Unpaused(address);\n\n function test_constructor_succeeds() external {\n assertEq(address(op.L2_ORACLE()), address(oracle));\n assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD);\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be paused by the GUARDIAN\n */\n function test_pause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n assertEq(op.paused(), false);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Paused(guardian);\n\n vm.prank(guardian);\n op.pause();\n\n assertEq(op.paused(), true);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not the\n * GUARDIAN calls `pause()`\n */\n function test_pause_onlyGuardian_reverts() external {\n assertEq(op.paused(), false);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can pause\");\n vm.prank(alice);\n op.pause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be unpaused by the GUARDIAN\n */\n function test_unpause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Unpaused(guardian);\n vm.prank(guardian);\n op.unpause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not\n * the GUARDIAN calls `unpause()`\n */\n function test_unpause_onlyGuardian_reverts() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can unpause\");\n vm.prank(alice);\n op.unpause();\n\n assertEq(op.paused(), true);\n }\n\n function test_receive_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex\"\");\n\n // give alice money and send as an eoa\n vm.deal(alice, 2**64);\n vm.prank(alice, alice);\n (bool s, ) = address(op).call{ value: 100 }(hex\"\");\n\n assert(s);\n assertEq(address(op).balance, 100);\n }\n\n // Test: depositTransaction fails when contract creation has a non-zero destination address\n function test_depositTransaction_contractCreation_reverts() external {\n // contract creation must have a target of address(0)\n vm.expectRevert(\"OptimismPortal: must send to address(0) when creating a contract\");\n op.depositTransaction(address(1), 1, 0, true, hex\"\");\n }\n\n /**\n * @notice Prevent deposits from being too large to have a sane upper bound\n * on unsafe blocks sent over the p2p network.\n */\n function test_depositTransaction_largeData_reverts() external {\n uint256 size = 120_001;\n uint64 gasLimit = op.minimumGasLimit(uint64(size));\n vm.expectRevert(\"OptimismPortal: data too large\");\n op.depositTransaction({\n _to: address(0),\n _value: 0,\n _gasLimit: gasLimit,\n _isCreation: false,\n _data: new bytes(size)\n });\n }\n\n /**\n * @notice Prevent gasless deposits from being force processed in L2 by\n * ensuring that they have a large enough gas limit set.\n */\n function test_depositTransaction_smallGasLimit_reverts() external {\n vm.expectRevert(\"OptimismPortal: gas limit too small\");\n op.depositTransaction({\n _to: address(1),\n _value: 0,\n _gasLimit: 0,\n _isCreation: false,\n _data: hex\"\"\n });\n }\n\n /**\n * @notice Fuzz for too small of gas limits\n */\n function testFuzz_depositTransaction_smallGasLimit_succeeds(\n bytes memory _data,\n bool _shouldFail\n ) external {\n vm.assume(_data.length <= type(uint64).max);\n\n uint64 gasLimit = op.minimumGasLimit(uint64(_data.length));\n if (_shouldFail) {\n gasLimit = uint64(bound(gasLimit, 0, gasLimit - 1));\n vm.expectRevert(\"OptimismPortal: gas limit too small\");\n }\n\n op.depositTransaction({\n _to: address(0x40),\n _value: 0,\n _gasLimit: gasLimit,\n _isCreation: false,\n _data: _data\n });\n }\n\n /**\n * @notice Ensure that the 0 calldata case is covered and there is a linearly\n * increasing gas limit for larger calldata sizes.\n */\n function test_minimumGasLimit_succeeds() external {\n assertEq(op.minimumGasLimit(0), 21_000);\n assertTrue(op.minimumGasLimit(2) > op.minimumGasLimit(1));\n assertTrue(op.minimumGasLimit(3) > op.minimumGasLimit(2));\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a tx with 0 value\n function test_depositTransaction_noValueEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a tx with 0 value\n function test_depositTransaction_noValueContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndContractContractCreation_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n function test_simple_isOutputFinalized_succeeds() external {\n uint256 ts = block.timestamp;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))\n )\n );\n\n // warp to the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS());\n assertEq(op.isOutputFinalized(0), false);\n\n // warp past the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n assertEq(op.isOutputFinalized(0), true);\n }\n\n function test_isOutputFinalized_succeeds() external {\n uint256 checkpoint = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n vm.roll(checkpoint);\n vm.warp(oracle.computeL2Timestamp(checkpoint) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0);\n\n // warp to the final second of the finalization period\n uint256 finalizationHorizon = block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS();\n vm.warp(finalizationHorizon);\n // The checkpointed block should not be finalized until 1 second from now.\n assertEq(op.isOutputFinalized(nextOutputIndex), false);\n // Nor should a block after it\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n\n // warp past the finalization period\n vm.warp(finalizationHorizon + 1);\n // It should now be finalized.\n assertEq(op.isOutputFinalized(nextOutputIndex), true);\n // But not the block after it.\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n }\n}\n\ncontract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n // Utility function used in the subsequent test. This is necessary to assert that the\n // reentrant call will revert.\n function callPortalAndExpectRevert() external payable {\n vm.expectRevert(\"OptimismPortal: can only trigger one withdrawal per transaction\");\n // Arguments here don't matter, as the require check is the first thing that happens.\n // We assume that this has already been proven.\n op.finalizeWithdrawalTransaction(_defaultTx);\n // Assert that the withdrawal was not finalized.\n assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));\n }\n\n /**\n * @notice Proving withdrawal transactions should revert when paused\n */\n function test_proveWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.proveWithdrawalTransaction({\n _tx: _defaultTx,\n _l2OutputIndex: _proposedOutputIndex,\n _outputRootProof: _outputRootProof,\n _withdrawalProof: _withdrawalProof\n });\n }\n\n // Test: proveWithdrawalTransaction cannot prove a withdrawal with itself (the OptimismPortal) as the target.\n function test_proveWithdrawalTransaction_onSelfCall_reverts() external {\n _defaultTx.target = address(op);\n vm.expectRevert(\"OptimismPortal: you cannot send messages to the portal contract\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the outputRootProof does not match the output root\n function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external {\n // Modify the version to invalidate the withdrawal proof.\n _outputRootProof.version = bytes32(uint256(1));\n vm.expectRevert(\"OptimismPortal: invalid output root proof\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the proof is invalid due to non-existence of\n // the withdrawal.\n function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external {\n // modify the default test values to invalidate the proof.\n _defaultTx.data = hex\"abcd\";\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the passed transaction's withdrawalHash has\n // already been proven.\n function test_proveWithdrawalTransaction_replayProve_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: withdrawal hash has already been proven\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root has changed AND the l2BlockNumber stays the same.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in the OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a different output root within the `provenWithdrawals` mapping without\n // touching the l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root + output index + l2BlockNumber changes.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds()\n external\n {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a dummy output root within the `provenWithdrawals` mapping without touching the\n // l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle\n Types.OutputProposal memory proposal = op.L2_ORACLE().getL2Output(_proposedOutputIndex);\n\n // Propose the same output root again, creating the same output at a different index + l2BlockNumber.\n vm.startPrank(op.L2_ORACLE().PROPOSER());\n op.L2_ORACLE().proposeL2Output(\n proposal.outputRoot,\n op.L2_ORACLE().nextBlockNumber(),\n blockhash(block.number),\n block.number\n );\n vm.stopPrank();\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot + a different output index\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex + 1,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds and emits the WithdrawalProven event.\n function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: finalizeWithdrawalTransaction succeeds and emits the WithdrawalFinalized event.\n function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, false, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore + 100);\n }\n\n /**\n * @notice Finalizing withdrawal transactions should revert when paused\n */\n function test_finalizeWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has not been proven.\n function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectRevert(\"OptimismPortal: withdrawal has not been proven yet\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if withdrawal not proven long enough ago.\n function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Mock a call where the resulting output root is anything but the original output root. In\n // this case we just use bytes32(uint256(1)).\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(bytes32(uint256(1)), _proposedBlockNumber)\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the provenWithdrawal's timestamp is less\n // than the L2 output oracle's starting timestamp\n function test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a startingTimestamp change on the L2 Oracle\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSignature(\"startingTimestamp()\"),\n abi.encode(block.timestamp + 1)\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output root proven is not the same as the\n // output root at the time of finalization.\n function test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock an outputRoot change on the output proposal before attempting\n // to finalize the withdrawal.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n bytes32(uint256(0)),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output proposal's timestamp has\n // not passed the finalization period.\n function test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a timestamp change on the output proposal that has not passed the\n // finalization period.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(block.timestamp + 1),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\"OptimismPortal: output proposal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction fails because the target reverts,\n // and emits the WithdrawalFinalized event with success=false.\n function test_finalizeWithdrawalTransaction_targetFails_fails() external {\n uint256 bobBalanceBefore = address(bob).balance;\n vm.etch(bob, hex\"fe\"); // Contract with just the invalid opcode.\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, false);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the finalization period has not yet passed.\n function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external {\n // Setup the Oracle to return an output with a recent timestamp\n uint256 recentTimestamp = block.timestamp - 1000;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(recentTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has already been finalized.\n function test_finalizeWithdrawalTransaction_onReplay_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if insufficient gas is supplied.\n function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external {\n // This number was identified through trial and error.\n uint256 gasLimit = 150_000;\n Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: gasLimit,\n data: hex\"\"\n });\n\n // Get updated proof inputs.\n (bytes32 stateRoot, bytes32 storageRoot, , , bytes[] memory withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(insufficientGasTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n Hashing.hashOutputRootProof(outputRootProof),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n insufficientGasTx,\n _proposedOutputIndex,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectRevert(\"SafeCall: Not enough gas\");\n op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if a sub-call attempts to finalize another\n // withdrawal.\n function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Copy and modify the default test values to attempt a reentrant call by first calling to\n // this contract's callPortalAndExpectRevert() function above.\n Types.WithdrawalTransaction memory _testTx = _defaultTx;\n _testTx.target = address(this);\n _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector);\n\n // Get modified proof inputs.\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_testTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp.\n uint256 finalizedTimestamp = block.timestamp - oracle.FINALIZATION_PERIOD_SECONDS() - 1;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n outputRoot,\n uint128(finalizedTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(withdrawalHash, alice, address(this));\n op.proveWithdrawalTransaction(\n _testTx,\n _proposedBlockNumber,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectCall(address(this), _testTx.data);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_testTx);\n\n // Ensure that bob's balance was not changed by the reentrant call.\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n function testDiff_finalizeWithdrawalTransaction_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n vm.assume(\n _target != address(op) && // Cannot call the optimism portal or a contract\n _target.code.length == 0 && // No accounts with code\n _target != CONSOLE && // The console has no code but behaves like a contract\n uint160(_target) > 9 // No precompiles (or zero address)\n );\n\n // Total ETH supply is currently about 120M ETH.\n uint256 value = bound(_value, 0, 200_000_000 ether);\n vm.deal(address(op), value);\n\n uint256 gasLimit = bound(_gasLimit, 0, 50_000_000);\n uint256 nonce = messagePasser.messageNonce();\n\n // Get a withdrawal transaction and mock proof from the differential testing script.\n Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: value,\n gasLimit: gasLimit,\n data: _data\n });\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_tx);\n\n // Create the output root proof\n Types.OutputRootProof memory proof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n\n // Ensure the values returned from ffi are correct\n assertEq(outputRoot, Hashing.hashOutputRootProof(proof));\n assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx));\n\n // Setup the Oracle to return the outputRoot\n vm.mockCall(\n address(oracle),\n abi.encodeWithSelector(oracle.getL2Output.selector),\n abi.encode(outputRoot, block.timestamp, 100)\n );\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _tx,\n 100, // l2BlockNumber\n proof,\n withdrawalProof\n );\n (bytes32 _root, , ) = op.provenWithdrawals(withdrawalHash);\n assertTrue(_root != bytes32(0));\n\n // Warp past the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Finalize the withdrawal transaction\n vm.expectCallMinGas(_tx.target, _tx.value, uint64(_tx.gasLimit), _tx.data);\n op.finalizeWithdrawalTransaction(_tx);\n assertTrue(op.finalizedWithdrawals(withdrawalHash));\n }\n}\n\ncontract OptimismPortalUpgradeable_Test is Portal_Initializer {\n Proxy internal proxy;\n uint64 initialBlockNum;\n\n function setUp() public override {\n super.setUp();\n initialBlockNum = uint64(block.number);\n proxy = Proxy(payable(address(op)));\n }\n\n function test_params_initValuesOnProxy_succeeds() external {\n OptimismPortal p = OptimismPortal(payable(address(proxy)));\n\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = p.params();\n\n ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig();\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_initialize_cannotInitProxy_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(payable(proxy)).initialize(false);\n }\n\n function test_initialize_cannotInitImpl_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(opImpl).initialize(false);\n }\n\n function test_upgradeToAndCall_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(op), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(op)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n\n/**\n * @title OptimismPortalResourceFuzz_Test\n * @dev Test various values of the resource metering config to ensure that deposits cannot be\n * broken by changing the config.\n */\ncontract OptimismPortalResourceFuzz_Test is Portal_Initializer {\n /**\n * @dev The max gas limit observed throughout this test. Setting this too high can cause\n * the test to take too long to run.\n */\n uint256 constant MAX_GAS_LIMIT = 30_000_000;\n\n /**\n * @dev Test that various values of the resource metering config will not break deposits.\n */\n function testFuzz_systemConfigDeposit_succeeds(\n uint32 _maxResourceLimit,\n uint8 _elasticityMultiplier,\n uint8 _baseFeeMaxChangeDenominator,\n uint32 _minimumBaseFee,\n uint32 _systemTxMaxGas,\n uint128 _maximumBaseFee,\n uint64 _gasLimit,\n uint64 _prevBoughtGas,\n uint128 _prevBaseFee,\n uint8 _blockDiff\n ) external {\n // Get the set system gas limit\n uint64 gasLimit = systemConfig.gasLimit();\n // Bound resource config\n _maxResourceLimit = uint32(bound(_maxResourceLimit, 21000, MAX_GAS_LIMIT / 8));\n _gasLimit = uint64(bound(_gasLimit, 21000, _maxResourceLimit));\n _prevBaseFee = uint128(bound(_prevBaseFee, 0, 3 gwei));\n // Prevent values that would cause reverts\n vm.assume(gasLimit >= _gasLimit);\n vm.assume(_minimumBaseFee < _maximumBaseFee);\n vm.assume(_baseFeeMaxChangeDenominator > 1);\n vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit);\n vm.assume(_elasticityMultiplier > 0);\n vm.assume(\n ((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) ==\n _maxResourceLimit\n );\n _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit));\n _blockDiff = uint8(bound(_blockDiff, 0, 3));\n\n // Create a resource config to mock the call to the system config with\n ResourceMetering.ResourceConfig memory rcfg = ResourceMetering.ResourceConfig({\n maxResourceLimit: _maxResourceLimit,\n elasticityMultiplier: _elasticityMultiplier,\n baseFeeMaxChangeDenominator: _baseFeeMaxChangeDenominator,\n minimumBaseFee: _minimumBaseFee,\n systemTxMaxGas: _systemTxMaxGas,\n maximumBaseFee: _maximumBaseFee\n });\n vm.mockCall(\n address(systemConfig),\n abi.encodeWithSelector(systemConfig.resourceConfig.selector),\n abi.encode(rcfg)\n );\n\n // Set the resource params\n uint256 _prevBlockNum = block.number - _blockDiff;\n vm.store(\n address(op),\n bytes32(uint256(1)),\n bytes32((_prevBlockNum << 192) | (uint256(_prevBoughtGas) << 128) | _prevBaseFee)\n );\n // Ensure that the storage setting is correct\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = op.params();\n assertEq(prevBaseFee, _prevBaseFee);\n assertEq(prevBoughtGas, _prevBoughtGas);\n assertEq(prevBlockNum, _prevBlockNum);\n\n // Do a deposit, should not revert\n op.depositTransaction{ gas: MAX_GAS_LIMIT }({\n _to: address(0x20),\n _value: 0x40,\n _gasLimit: _gasLimit,\n _isCreation: false,\n _data: hex\"\"\n });\n }\n}\n" - }, - "contracts/test/Proxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract SimpleStorage {\n mapping(uint256 => uint256) internal store;\n\n function get(uint256 key) external payable returns (uint256) {\n return store[key];\n }\n\n function set(uint256 key, uint256 value) external payable {\n store[key] = value;\n }\n}\n\ncontract Clasher {\n function upgradeTo(address) external pure {\n revert(\"upgradeTo\");\n }\n}\n\ncontract Proxy_Test is Test {\n event Upgraded(address indexed implementation);\n event AdminChanged(address previousAdmin, address newAdmin);\n\n address alice = address(64);\n\n bytes32 internal constant IMPLEMENTATION_KEY =\n bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1);\n\n bytes32 internal constant OWNER_KEY = bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1);\n\n Proxy proxy;\n SimpleStorage simpleStorage;\n\n function setUp() external {\n // Deploy a proxy and simple storage contract as\n // the implementation\n proxy = new Proxy(alice);\n simpleStorage = new SimpleStorage();\n\n vm.prank(alice);\n proxy.upgradeTo(address(simpleStorage));\n }\n\n function test_implementationKey_succeeds() external {\n // The hardcoded implementation key should be correct\n vm.prank(alice);\n proxy.upgradeTo(address(6));\n\n bytes32 key = vm.load(address(proxy), IMPLEMENTATION_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(6));\n }\n\n function test_ownerKey_succeeds() external {\n // The hardcoded owner key should be correct\n vm.prank(alice);\n proxy.changeAdmin(address(6));\n\n bytes32 key = vm.load(address(proxy), OWNER_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(address(6));\n address owner = proxy.admin();\n assertEq(owner, address(6));\n }\n\n function test_proxyCallToImp_notAdmin_succeeds() external {\n // The implementation does not have a `upgradeTo`\n // method, calling `upgradeTo` not as the owner\n // should revert.\n vm.expectRevert();\n proxy.upgradeTo(address(64));\n\n // Call `upgradeTo` as the owner, it should succeed\n // and emit the `Upgraded` event.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(64));\n vm.prank(alice);\n proxy.upgradeTo(address(64));\n\n // Get the implementation as the owner\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(64));\n }\n\n function test_ownerProxyCall_notAdmin_succeeds() external {\n // Calling `changeAdmin` not as the owner should revert\n // as the implementation does not have a `changeAdmin` method.\n vm.expectRevert();\n proxy.changeAdmin(address(1));\n\n // Call `changeAdmin` as the owner, it should succeed\n // and emit the `AdminChanged` event.\n vm.expectEmit(true, true, true, true);\n emit AdminChanged(alice, address(1));\n vm.prank(alice);\n proxy.changeAdmin(address(1));\n\n // Calling `admin` not as the owner should\n // revert as the implementation does not have\n // a `admin` method.\n vm.expectRevert();\n proxy.admin();\n\n // Calling `admin` as the owner should work.\n vm.prank(address(1));\n address owner = proxy.admin();\n assertEq(owner, address(1));\n }\n\n function test_delegatesToImpl_succeeds() external {\n // Call the storage setter on the proxy\n SimpleStorage(address(proxy)).set(1, 1);\n\n // The key should not be set in the implementation\n uint256 result = simpleStorage.get(1);\n assertEq(result, 0);\n {\n // The key should be set in the proxy\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n\n {\n // The owner should be able to call through the proxy\n // when there is not a function selector crash\n vm.prank(alice);\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n }\n\n function test_upgradeToAndCall_succeeds() external {\n {\n // There should be nothing in the current proxy storage\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 0);\n }\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(simpleStorage));\n vm.prank(alice);\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The call should have impacted the state\n uint256 result = SimpleStorage(address(proxy)).get(1);\n assertEq(result, 1);\n }\n\n function test_upgradeToAndCall_functionDoesNotExist_reverts() external {\n // Get the current implementation address\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call. This reverts because the calldata doesn't\n // match a function on the implementation.\n vm.expectRevert(\"Proxy: delegatecall to new implementation contract failed\");\n vm.prank(alice);\n proxy.upgradeToAndCall(address(simpleStorage), hex\"\");\n\n // The implementation address should have not\n // updated because the call to `upgradeToAndCall`\n // reverted.\n vm.prank(alice);\n address postImpl = proxy.implementation();\n assertEq(impl, postImpl);\n\n // The attempt to `upgradeToAndCall`\n // should revert when it is not called by the owner.\n vm.expectRevert();\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n }\n\n function test_upgradeToAndCall_isPayable_succeeds() external {\n // Give alice some funds\n vm.deal(alice, 1 ether);\n // Set the implementation and call and send\n // value.\n vm.prank(alice);\n proxy.upgradeToAndCall{ value: 1 ether }(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The implementation address should be correct\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // The proxy should have a balance\n assertEq(address(proxy).balance, 1 ether);\n }\n\n function test_upgradeTo_clashingFunctionSignatures_succeeds() external {\n // Clasher has a clashing function with the proxy.\n Clasher clasher = new Clasher();\n\n // Set the clasher as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(clasher));\n\n {\n // Assert that the implementation was set properly.\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(clasher));\n }\n\n // Call the clashing function on the proxy\n // not as the owner so that the call passes through.\n // The implementation will revert so we can be\n // sure that the call passed through.\n vm.expectRevert(bytes(\"upgradeTo\"));\n proxy.upgradeTo(address(0));\n\n {\n // Now call the clashing function as the owner\n // and be sure that it doesn't pass through to\n // the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(0));\n }\n }\n\n // Allow for `eth_call` to call proxy methods\n // by setting \"from\" to `address(0)`.\n function test_implementation_zeroAddressCaller_succeeds() external {\n vm.prank(address(0));\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n }\n\n function test_implementation_isZeroAddress_reverts() external {\n // Set `address(0)` as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n\n (bool success, bytes memory returndata) = address(proxy).call(hex\"\");\n assertEq(success, false);\n\n bytes memory err = abi.encodeWithSignature(\n \"Error(string)\",\n \"Proxy: implementation not initialized\"\n );\n\n assertEq(returndata, err);\n }\n}\n" - }, - "contracts/test/ProxyAdmin.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { SimpleStorage } from \"./Proxy.t.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\n\ncontract ProxyAdmin_Test is Test {\n address alice = address(64);\n\n Proxy proxy;\n L1ChugSplashProxy chugsplash;\n ResolvedDelegateProxy resolved;\n\n AddressManager addressManager;\n\n ProxyAdmin admin;\n\n SimpleStorage implementation;\n\n function setUp() external {\n // Deploy the proxy admin\n admin = new ProxyAdmin(alice);\n // Deploy the standard proxy\n proxy = new Proxy(address(admin));\n\n // Deploy the legacy L1ChugSplashProxy with the admin as the owner\n chugsplash = new L1ChugSplashProxy(address(admin));\n\n // Deploy the legacy AddressManager\n addressManager = new AddressManager();\n // The proxy admin must be the new owner of the address manager\n addressManager.transferOwnership(address(admin));\n // Deploy a legacy ResolvedDelegateProxy with the name `a`.\n // Whatever `a` is set to in AddressManager will be the address\n // that is used for the implementation.\n resolved = new ResolvedDelegateProxy(addressManager, \"a\");\n\n // Impersonate alice for setting up the admin.\n vm.startPrank(alice);\n // Set the address of the address manager in the admin so that it\n // can resolve the implementation address of legacy\n // ResolvedDelegateProxy based proxies.\n admin.setAddressManager(addressManager);\n // Set the reverse lookup of the ResolvedDelegateProxy\n // proxy\n admin.setImplementationName(address(resolved), \"a\");\n\n // Set the proxy types\n admin.setProxyType(address(proxy), ProxyAdmin.ProxyType.ERC1967);\n admin.setProxyType(address(chugsplash), ProxyAdmin.ProxyType.CHUGSPLASH);\n admin.setProxyType(address(resolved), ProxyAdmin.ProxyType.RESOLVED);\n vm.stopPrank();\n\n implementation = new SimpleStorage();\n }\n\n function test_setImplementationName_succeeds() external {\n vm.prank(alice);\n admin.setImplementationName(address(1), \"foo\");\n assertEq(admin.implementationName(address(1)), \"foo\");\n }\n\n function test_setAddressManager_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setAddressManager(AddressManager((address(0))));\n }\n\n function test_setImplementationName_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setImplementationName(address(0), \"foo\");\n }\n\n function test_setProxyType_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setProxyType(address(0), ProxyAdmin.ProxyType.CHUGSPLASH);\n }\n\n function test_owner_succeeds() external {\n assertEq(admin.owner(), alice);\n }\n\n function test_proxyType_succeeds() external {\n assertEq(uint256(admin.proxyType(address(proxy))), uint256(ProxyAdmin.ProxyType.ERC1967));\n assertEq(\n uint256(admin.proxyType(address(chugsplash))),\n uint256(ProxyAdmin.ProxyType.CHUGSPLASH)\n );\n assertEq(\n uint256(admin.proxyType(address(resolved))),\n uint256(ProxyAdmin.ProxyType.RESOLVED)\n );\n }\n\n function test_erc1967GetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(proxy));\n }\n\n function test_chugsplashGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(resolved));\n }\n\n function getProxyImplementation(address payable _proxy) internal {\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(0));\n }\n\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n }\n\n function test_erc1967GetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(resolved));\n }\n\n function getProxyAdmin(address payable _proxy) internal {\n address owner = admin.getProxyAdmin(_proxy);\n assertEq(owner, address(admin));\n }\n\n function test_erc1967ChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(resolved));\n }\n\n function changeProxyAdmin(address payable _proxy) internal {\n ProxyAdmin.ProxyType proxyType = admin.proxyType(address(_proxy));\n\n vm.prank(alice);\n admin.changeProxyAdmin(_proxy, address(128));\n\n // The proxy is no longer the admin and can\n // no longer call the proxy interface except for\n // the ResolvedDelegate type on which anybody can\n // call the admin interface.\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n vm.expectRevert(\"Proxy: implementation not initialized\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n vm.expectRevert(\"L1ChugSplashProxy: implementation is not set yet\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n // Just an empty block to show that all cases are covered\n } else {\n vm.expectRevert(\"ProxyAdmin: unknown proxy type\");\n }\n\n // Call the proxy contract directly to get the admin.\n // Different proxy types have different interfaces.\n vm.prank(address(128));\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n assertEq(Proxy(payable(_proxy)).admin(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n assertEq(L1ChugSplashProxy(payable(_proxy)).getOwner(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n assertEq(addressManager.owner(), address(128));\n } else {\n assert(false);\n }\n }\n\n function test_erc1967Upgrade_succeeds() external {\n upgrade(payable(proxy));\n }\n\n function test_chugsplashUpgrade_succeeds() external {\n upgrade(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgrade_succeeds() external {\n upgrade(payable(resolved));\n }\n\n function upgrade(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n\n function test_erc1967UpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(proxy));\n }\n\n function test_chugsplashUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(resolved));\n }\n\n function upgradeAndCall(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgradeAndCall(\n _proxy,\n address(implementation),\n abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1)\n );\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n\n uint256 got = SimpleStorage(address(_proxy)).get(1);\n assertEq(got, 1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.changeProxyAdmin(payable(proxy), address(0));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgrade(payable(proxy), address(implementation));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgradeAndCall(payable(proxy), address(implementation), hex\"\");\n }\n\n function test_isUpgrading_succeeds() external {\n assertEq(false, admin.isUpgrading());\n\n vm.prank(alice);\n admin.setUpgrading(true);\n assertEq(true, admin.isUpgrading());\n }\n}\n" - }, - "contracts/test/RLP.t.sol": { - "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\n/**\n * @title LibRLP\n * @notice Via https://github.com/Rari-Capital/solmate/issues/207.\n */\nlibrary LibRLP {\n using Bytes32AddressLib for bytes32;\n\n function computeAddress(address deployer, uint256 nonce) internal pure returns (address) {\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))\n .fromLast20Bytes();\n if (nonce <= 0x7f)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))\n .fromLast20Bytes();\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= type(uint8).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd7),\n bytes1(0x94),\n deployer,\n bytes1(0x81),\n uint8(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint16).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd8),\n bytes1(0x94),\n deployer,\n bytes1(0x82),\n uint16(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint24).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd9),\n bytes1(0x94),\n deployer,\n bytes1(0x83),\n uint24(nonce)\n )\n ).fromLast20Bytes();\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return\n keccak256(\n abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))\n ).fromLast20Bytes();\n }\n}\n" - }, - "contracts/test/RLPReader.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { RLPReader } from \"../libraries/rlp/RLPReader.sol\";\n\ncontract RLPReader_readBytes_Test is CommonTest {\n function test_readBytes_bytestring00_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"00\"), hex\"00\");\n }\n\n function test_readBytes_bytestring01_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"01\"), hex\"01\");\n }\n\n function test_readBytes_bytestring7f_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"7f\"), hex\"7f\");\n }\n\n function test_readBytes_revertListItem_reverts() external {\n vm.expectRevert(\"RLPReader: decoded item type for bytes is not a data item\");\n RLPReader.readBytes(hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_readBytes_invalidStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n RLPReader.readBytes(hex\"b9\");\n }\n\n function test_readBytes_invalidListLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n RLPReader.readBytes(hex\"ff\");\n }\n\n function test_readBytes_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: bytes value contains an invalid remainder\");\n RLPReader.readBytes(hex\"800a\");\n }\n\n function test_readBytes_invalidPrefix_reverts() external {\n vm.expectRevert(\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n RLPReader.readBytes(hex\"810a\");\n }\n}\n\ncontract RLPReader_readList_Test is CommonTest {\n function test_readList_empty_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c0\");\n assertEq(list.length, 0);\n }\n\n function test_readList_multiList_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c6827a77c10401\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"827a77\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c104\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"01\");\n }\n\n function test_readList_shortListMax1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n\n assertEq(list.length, 11);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[4]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[5]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[6]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[7]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[8]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[9]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[10]), hex\"8471776572\");\n }\n\n function test_readList_longList1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n\n assertEq(list.length, 4);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"cf84617364668471776572847a786376\");\n }\n\n function test_readList_longList2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n assertEq(list.length, 32);\n\n for (uint256 i = 0; i < 32; i++) {\n assertEq(RLPReader.readRawBytes(list[i]), hex\"cf84617364668471776572847a786376\");\n }\n }\n\n function test_readList_listLongerThan32Elements_reverts() external {\n vm.expectRevert(stdError.indexOOBError);\n RLPReader.readList(\n hex\"e1454545454545454545454545454545454545454545454545454545454545454545\"\n );\n }\n\n function test_readList_listOfLists_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c4c2c0c0c0\");\n assertEq(list.length, 2);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c2c0c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c0\");\n }\n\n function test_readList_listOfLists2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c7c0c1c0c3c0c1c0\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c1c0\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"c3c0c1c0\");\n }\n\n function test_readList_dictTest1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n assertEq(list.length, 4);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"ca846b6579318476616c31\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"ca846b6579328476616c32\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"ca846b6579338476616c33\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"ca846b6579348476616c34\");\n }\n\n function test_readList_invalidShortList_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efdebd\");\n }\n\n function test_readList_longStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efb83600\");\n }\n\n function test_readList_notLongEnough_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(\n hex\"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n );\n }\n\n function test_readList_int32Overflow_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"bf0f000000000000021111\");\n }\n\n function test_readList_int32Overflow2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ff0f000000000000021111\");\n }\n\n function test_readList_incorrectLengthInArray_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(hex\"b800\");\n }\n\n function test_readList_leadingZerosInLongLengthList1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must not have any leading zeros (long list)\");\n RLPReader.readList(\n hex\"fb00000040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_nonOptimalLongLengthArray1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b81000112233445566778899aabbccddeeff\");\n }\n\n function test_readList_nonOptimalLongLengthArray2_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b801ff\");\n }\n\n function test_readList_invalidValue_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n RLPReader.readList(hex\"91\");\n }\n\n function test_readList_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n RLPReader.readList(hex\"c000\");\n }\n\n function test_readList_notEnoughContentForString1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"ba010000aabbccddeeff\");\n }\n\n function test_readList_notEnoughContentForString2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"b840ffeeddccbbaa99887766554433221100\");\n }\n\n function test_readList_notEnoughContentForList1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"f90180\");\n }\n\n function test_readList_notEnoughContentForList2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ffffffffffffffffff0001020304050607\");\n }\n\n function test_readList_longStringLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b80100\");\n }\n\n function test_readList_longListLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long list)\");\n RLPReader.readList(hex\"f80100\");\n }\n}\n" - }, - "contracts/test/RLPWriter.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { RLPWriter } from \"../libraries/rlp/RLPWriter.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\n\ncontract RLPWriter_writeString_Test is CommonTest {\n function test_writeString_empty_succeeds() external {\n assertEq(RLPWriter.writeString(\"\"), hex\"80\");\n }\n\n function test_writeString_bytestring00_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0000\"), hex\"00\");\n }\n\n function test_writeString_bytestring01_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0001\"), hex\"01\");\n }\n\n function test_writeString_bytestring7f_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u007F\"), hex\"7f\");\n }\n\n function test_writeString_shortstring_succeeds() external {\n assertEq(RLPWriter.writeString(\"dog\"), hex\"83646f67\");\n }\n\n function test_writeString_shortstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing eli\"),\n hex\"b74c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69\"\n );\n }\n\n function test_writeString_longstring_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing elit\"),\n hex\"b8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974\"\n );\n }\n\n function test_writeString_longstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\n \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat\"\n ),\n hex\"b904004c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742e20437572616269747572206d6175726973206d61676e612c20737573636970697420736564207665686963756c61206e6f6e2c20696163756c697320666175636962757320746f72746f722e2050726f696e20737573636970697420756c74726963696573206d616c6573756164612e204475697320746f72746f7220656c69742c2064696374756d2071756973207472697374697175652065752c20756c7472696365732061742072697375732e204d6f72626920612065737420696d70657264696574206d6920756c6c616d636f7270657220616c6971756574207375736369706974206e6563206c6f72656d2e2041656e65616e2071756973206c656f206d6f6c6c69732c2076756c70757461746520656c6974207661726975732c20636f6e73657175617420656e696d2e204e756c6c6120756c74726963657320747572706973206a7573746f2c20657420706f73756572652075726e6120636f6e7365637465747572206e65632e2050726f696e206e6f6e20636f6e76616c6c6973206d657475732e20446f6e65632074656d706f7220697073756d20696e206d617572697320636f6e67756520736f6c6c696369747564696e2e20566573746962756c756d20616e746520697073756d207072696d697320696e206661756369627573206f726369206c756374757320657420756c74726963657320706f737565726520637562696c69612043757261653b2053757370656e646973736520636f6e76616c6c69732073656d2076656c206d617373612066617563696275732c2065676574206c6163696e6961206c616375732074656d706f722e204e756c6c61207175697320756c747269636965732070757275732e2050726f696e20617563746f722072686f6e637573206e69626820636f6e64696d656e74756d206d6f6c6c69732e20416c697175616d20636f6e73657175617420656e696d206174206d65747573206c75637475732c206120656c656966656e6420707572757320656765737461732e20437572616269747572206174206e696268206d657475732e204e616d20626962656e64756d2c206e6571756520617420617563746f72207472697374697175652c206c6f72656d206c696265726f20616c697175657420617263752c206e6f6e20696e74657264756d2074656c6c7573206c65637475732073697420616d65742065726f732e20437261732072686f6e6375732c206d65747573206163206f726e617265206375727375732c20646f6c6f72206a7573746f20756c747269636573206d657475732c20617420756c6c616d636f7270657220766f6c7574706174\"\n );\n }\n}\n\ncontract RLPWriter_writeUint_Test is CommonTest {\n function test_writeUint_zero_succeeds() external {\n assertEq(RLPWriter.writeUint(0x0), hex\"80\");\n }\n\n function test_writeUint_smallint_succeeds() external {\n assertEq(RLPWriter.writeUint(1), hex\"01\");\n }\n\n function test_writeUint_smallint2_succeeds() external {\n assertEq(RLPWriter.writeUint(16), hex\"10\");\n }\n\n function test_writeUint_smallint3_succeeds() external {\n assertEq(RLPWriter.writeUint(79), hex\"4f\");\n }\n\n function test_writeUint_smallint4_succeeds() external {\n assertEq(RLPWriter.writeUint(127), hex\"7f\");\n }\n\n function test_writeUint_mediumint_succeeds() external {\n assertEq(RLPWriter.writeUint(128), hex\"8180\");\n }\n\n function test_writeUint_mediumint2_succeeds() external {\n assertEq(RLPWriter.writeUint(1000), hex\"8203e8\");\n }\n\n function test_writeUint_mediumint3_succeeds() external {\n assertEq(RLPWriter.writeUint(100000), hex\"830186a0\");\n }\n}\n\ncontract RLPWriter_writeList_Test is CommonTest {\n function test_writeList_empty_succeeds() external {\n assertEq(RLPWriter.writeList(new bytes[](0)), hex\"c0\");\n }\n\n function test_writeList_stringList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeString(\"dog\");\n list[1] = RLPWriter.writeString(\"god\");\n list[2] = RLPWriter.writeString(\"cat\");\n\n assertEq(RLPWriter.writeList(list), hex\"cc83646f6783676f6483636174\");\n }\n\n function test_writeList_multiList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeUint(4);\n\n list[0] = RLPWriter.writeString(\"zw\");\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeUint(1);\n\n assertEq(RLPWriter.writeList(list), hex\"c6827a77c10401\");\n }\n\n function test_writeList_shortListMax1_succeeds() external {\n bytes[] memory list = new bytes[](11);\n list[0] = RLPWriter.writeString(\"asdf\");\n list[1] = RLPWriter.writeString(\"qwer\");\n list[2] = RLPWriter.writeString(\"zxcv\");\n list[3] = RLPWriter.writeString(\"asdf\");\n list[4] = RLPWriter.writeString(\"qwer\");\n list[5] = RLPWriter.writeString(\"zxcv\");\n list[6] = RLPWriter.writeString(\"asdf\");\n list[7] = RLPWriter.writeString(\"qwer\");\n list[8] = RLPWriter.writeString(\"zxcv\");\n list[9] = RLPWriter.writeString(\"asdf\");\n list[10] = RLPWriter.writeString(\"qwer\");\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n }\n\n function test_writeList_longlist1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list2);\n list[3] = RLPWriter.writeList(list2);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_longlist2_succeeds() external {\n bytes[] memory list = new bytes[](32);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n for (uint256 i = 0; i < 32; i++) {\n list[i] = RLPWriter.writeList(list2);\n }\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_listoflists_succeeds() external {\n // [ [ [], [] ], [] ]\n bytes[] memory list = new bytes[](2);\n bytes[] memory list2 = new bytes[](2);\n\n list2[0] = RLPWriter.writeList(new bytes[](0));\n list2[1] = RLPWriter.writeList(new bytes[](0));\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(new bytes[](0));\n\n assertEq(RLPWriter.writeList(list), hex\"c4c2c0c0c0\");\n }\n\n function test_writeList_listoflists2_succeeds() external {\n // [ [], [[]], [ [], [[]] ] ]\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeList(new bytes[](0));\n\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeList(new bytes[](0));\n\n list[1] = RLPWriter.writeList(list2);\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeList(new bytes[](0));\n list3[1] = RLPWriter.writeList(list2);\n\n list[2] = RLPWriter.writeList(list3);\n\n assertEq(RLPWriter.writeList(list), hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_writeList_dictTest1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n\n bytes[] memory list1 = new bytes[](2);\n list1[0] = RLPWriter.writeString(\"key1\");\n list1[1] = RLPWriter.writeString(\"val1\");\n\n bytes[] memory list2 = new bytes[](2);\n list2[0] = RLPWriter.writeString(\"key2\");\n list2[1] = RLPWriter.writeString(\"val2\");\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeString(\"key3\");\n list3[1] = RLPWriter.writeString(\"val3\");\n\n bytes[] memory list4 = new bytes[](2);\n list4[0] = RLPWriter.writeString(\"key4\");\n list4[1] = RLPWriter.writeString(\"val4\");\n\n list[0] = RLPWriter.writeList(list1);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list3);\n list[3] = RLPWriter.writeList(list4);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n }\n}\n" - }, - "contracts/test/ResolvedDelegateProxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\n\ncontract ResolvedDelegateProxy_Test is Test {\n AddressManager internal addressManager;\n SimpleImplementation internal impl;\n SimpleImplementation internal proxy;\n\n function setUp() public {\n // Set up the address manager.\n addressManager = new AddressManager();\n impl = new SimpleImplementation();\n addressManager.setAddress(\"SimpleImplementation\", address(impl));\n\n // Set up the proxy.\n proxy = SimpleImplementation(\n address(new ResolvedDelegateProxy(addressManager, \"SimpleImplementation\"))\n );\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall succeeds.\n function testFuzz_fallback_delegateCallFoo_succeeds(uint256 x) public {\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.foo.selector, x));\n assertEq(proxy.foo(x), x);\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall reverts.\n function test_fallback_delegateCallBar_reverts() public {\n vm.expectRevert(\"SimpleImplementation: revert\");\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.bar.selector));\n proxy.bar();\n }\n\n // Tests that the proxy fallback reverts as expected if the implementation within the\n // address manager is not set.\n function test_fallback_addressManagerNotSet_reverts() public {\n AddressManager am = new AddressManager();\n SimpleImplementation p = SimpleImplementation(\n address(new ResolvedDelegateProxy(am, \"SimpleImplementation\"))\n );\n\n vm.expectRevert(\"ResolvedDelegateProxy: target address must be initialized\");\n p.foo(0);\n }\n}\n\ncontract SimpleImplementation {\n function foo(uint256 _x) public pure returns (uint256) {\n return _x;\n }\n\n function bar() public pure {\n revert(\"SimpleImplementation: revert\");\n }\n}\n" - }, - "contracts/test/ResourceMetering.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract MeterUser is ResourceMetering {\n ResourceMetering.ResourceConfig public innerConfig;\n\n constructor() {\n initialize();\n innerConfig = Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function initialize() public initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public view returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n view\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return innerConfig;\n }\n\n function use(uint64 _amount) public metered(_amount) {}\n\n function set(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) public {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n\n function setParams(ResourceMetering.ResourceConfig memory newConfig) public {\n innerConfig = newConfig;\n }\n}\n\n/**\n * @title ResourceConfig\n * @notice The tests are based on the default config values. It is expected that\n * the config values used in these tests are ran in production.\n */\ncontract ResourceMetering_Test is Test {\n MeterUser internal meter;\n uint64 initialBlockNum;\n\n function setUp() public {\n meter = new MeterUser();\n initialBlockNum = uint64(block.number);\n }\n\n function test_meter_initialResourceParams_succeeds() external {\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_updateParamsNoChange_succeeds() external {\n meter.use(0); // equivalent to just updating the base fee and block number\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n meter.use(0);\n (uint128 postBaseFee, uint64 postBoughtGas, uint64 postBlockNum) = meter.params();\n\n assertEq(postBaseFee, prevBaseFee);\n assertEq(postBoughtGas, prevBoughtGas);\n assertEq(postBlockNum, prevBlockNum);\n }\n\n function test_meter_updateOneEmptyBlock_succeeds() external {\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 1);\n }\n\n function test_meter_updateTwoEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 2);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 2);\n }\n\n function test_meter_updateTenEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 10);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 10);\n }\n\n function test_meter_updateNoGasDelta_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint256 target = uint256(rcfg.maxResourceLimit) / uint256(rcfg.elasticityMultiplier);\n meter.use(uint64(target));\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1000000000);\n assertEq(prevBoughtGas, target);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_useMax_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n meter.use(target * elasticityMultiplier);\n\n (, uint64 prevBoughtGas, ) = meter.params();\n assertEq(prevBoughtGas, target * elasticityMultiplier);\n\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 postBaseFee, , ) = meter.params();\n assertEq(postBaseFee, 2125000000);\n }\n\n /**\n * @notice This tests that the metered modifier reverts if\n * the ResourceConfig baseFeeMaxChangeDenominator\n * is set to 1.\n * Since the metered modifier internally calls\n * solmate's powWad function, it will revert\n * with the error string \"UNDEFINED\" since the\n * first parameter will be computed as 0.\n */\n function test_meter_denominatorEq1_reverts() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n rcfg.baseFeeMaxChangeDenominator = 1;\n meter.setParams(rcfg);\n meter.use(target * elasticityMultiplier);\n\n (, uint64 prevBoughtGas, ) = meter.params();\n assertEq(prevBoughtGas, target * elasticityMultiplier);\n\n vm.roll(initialBlockNum + 2);\n\n vm.expectRevert(\"UNDEFINED\");\n meter.use(0);\n }\n\n function test_meter_useMoreThanMax_reverts() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.expectRevert(\"ResourceMetering: cannot buy more gas than available gas limit\");\n meter.use(target * elasticityMultiplier + 1);\n }\n\n // Demonstrates that the resource metering arithmetic can tolerate very large gaps between\n // deposits.\n function testFuzz_meter_largeBlockDiff_succeeds(uint64 _amount, uint256 _blockDiff) external {\n // This test fails if the following line is commented out.\n // At 12 seconds per block, this number is effectively unreachable.\n vm.assume(_blockDiff < 433576281058164217753225238677900874458691);\n\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.assume(_amount < target * elasticityMultiplier);\n vm.roll(initialBlockNum + _blockDiff);\n meter.use(_amount);\n }\n}\n\n/**\n * @title CustomMeterUser\n * @notice A simple wrapper around `ResourceMetering` that allows the initial\n * params to be set in the constructor.\n */\ncontract CustomMeterUser is ResourceMetering {\n uint256 public startGas;\n uint256 public endGas;\n\n constructor(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function use(uint64 _amount) public returns (uint256) {\n uint256 initialGas = gasleft();\n _metered(_amount, initialGas);\n return initialGas - gasleft();\n }\n}\n\n/**\n * @title ArtifactResourceMetering_Test\n * @notice A table test that sets the state of the ResourceParams and then requests\n * various amounts of gas. This test ensures that a wide range of values\n * can safely be used with the `ResourceMetering` contract.\n * It also writes a CSV file to disk that includes useful information\n * about how much gas is used and how expensive it is in USD terms to\n * purchase the deposit gas.\n */\ncontract ArtifactResourceMetering_Test is Test {\n uint128 internal minimumBaseFee;\n uint128 internal maximumBaseFee;\n uint64 internal maxResourceLimit;\n uint64 internal targetResourceLimit;\n\n string internal outfile;\n\n // keccak256(abi.encodeWithSignature(\"Error(string)\", \"ResourceMetering: cannot buy more gas than available gas limit\"))\n bytes32 internal cannotBuyMoreGas =\n 0x84edc668cfd5e050b8999f43ff87a1faaa93e5f935b20bc1dd4d3ff157ccf429;\n // keccak256(abi.encodeWithSignature(\"Panic(uint256)\", 0x11))\n bytes32 internal overflowErr =\n 0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;\n // keccak256(hex\"\")\n bytes32 internal emptyReturnData =\n 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n\n /**\n * @notice Sets up the tests by getting constants from the ResourceMetering\n * contract.\n */\n function setUp() public {\n vm.roll(1_000_000);\n\n MeterUser base = new MeterUser();\n ResourceMetering.ResourceConfig memory rcfg = base.resourceConfig();\n minimumBaseFee = uint128(rcfg.minimumBaseFee);\n maximumBaseFee = rcfg.maximumBaseFee;\n maxResourceLimit = uint64(rcfg.maxResourceLimit);\n targetResourceLimit = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n\n outfile = string.concat(vm.projectRoot(), \"/.resource-metering.csv\");\n try vm.removeFile(outfile) {} catch {}\n }\n\n /**\n * @notice Generate a CSV file. The call to `meter` should be called with at\n * most the L1 block gas limit. Without specifying the amount of\n * gas, it can take very long to execute.\n */\n function test_meter_generateArtifact_succeeds() external {\n vm.writeLine(\n outfile,\n \"prevBaseFee,prevBoughtGas,prevBlockNumDiff,l1BaseFee,requestedGas,gasConsumed,ethPrice,usdCost,success\"\n );\n\n // prevBaseFee value in ResourceParams\n uint128[] memory prevBaseFees = new uint128[](5);\n prevBaseFees[0] = minimumBaseFee;\n prevBaseFees[1] = maximumBaseFee;\n prevBaseFees[2] = uint128(50 gwei);\n prevBaseFees[3] = uint128(100 gwei);\n prevBaseFees[4] = uint128(200 gwei);\n\n // prevBoughtGas value in ResourceParams\n uint64[] memory prevBoughtGases = new uint64[](1);\n prevBoughtGases[0] = uint64(0);\n\n // prevBlockNum diff, simulates blocks with no deposits when non zero\n uint64[] memory prevBlockNumDiffs = new uint64[](2);\n prevBlockNumDiffs[0] = 0;\n prevBlockNumDiffs[1] = 1;\n\n // The amount of L2 gas that a user requests\n uint64[] memory requestedGases = new uint64[](3);\n requestedGases[0] = maxResourceLimit;\n requestedGases[1] = targetResourceLimit;\n requestedGases[2] = uint64(100_000);\n\n // The L1 base fee\n uint256[] memory l1BaseFees = new uint256[](4);\n l1BaseFees[0] = 1 gwei;\n l1BaseFees[1] = 50 gwei;\n l1BaseFees[2] = 75 gwei;\n l1BaseFees[3] = 100 gwei;\n\n // USD price of 1 ether\n uint256[] memory ethPrices = new uint256[](2);\n ethPrices[0] = 1600;\n ethPrices[1] = 3200;\n\n // Iterate over all of the test values and run a test\n for (uint256 i; i < prevBaseFees.length; i++) {\n for (uint256 j; j < prevBoughtGases.length; j++) {\n for (uint256 k; k < prevBlockNumDiffs.length; k++) {\n for (uint256 l; l < requestedGases.length; l++) {\n for (uint256 m; m < l1BaseFees.length; m++) {\n for (uint256 n; n < ethPrices.length; n++) {\n uint256 snapshotId = vm.snapshot();\n\n uint128 prevBaseFee = prevBaseFees[i];\n uint64 prevBoughtGas = prevBoughtGases[j];\n uint64 prevBlockNumDiff = prevBlockNumDiffs[k];\n uint64 requestedGas = requestedGases[l];\n uint256 l1BaseFee = l1BaseFees[m];\n uint256 ethPrice = ethPrices[n];\n string memory result = \"success\";\n\n vm.fee(l1BaseFee);\n\n CustomMeterUser meter = new CustomMeterUser({\n _prevBaseFee: prevBaseFee,\n _prevBoughtGas: prevBoughtGas,\n _prevBlockNum: uint64(block.number)\n });\n\n vm.roll(block.number + prevBlockNumDiff);\n\n // Call the metering code and catch the various\n // types of errors.\n uint256 gasConsumed = 0;\n try meter.use{ gas: 30_000_000 }(requestedGas) returns (\n uint256 _gasConsumed\n ) {\n gasConsumed = _gasConsumed;\n } catch (bytes memory err) {\n bytes32 hash = keccak256(err);\n if (hash == cannotBuyMoreGas) {\n result = \"ResourceMetering: cannot buy more gas than available gas limit\";\n } else if (hash == overflowErr) {\n result = \"arithmetic overflow/underflow\";\n } else if (hash == emptyReturnData) {\n result = \"out of gas\";\n } else {\n result = \"UNKNOWN ERROR\";\n }\n }\n\n // Compute the USD cost of the gas used\n uint256 usdCost = (gasConsumed * l1BaseFee * ethPrice) / 1 ether;\n\n vm.writeLine(\n outfile,\n string.concat(\n vm.toString(prevBaseFee),\n \",\",\n vm.toString(prevBoughtGas),\n \",\",\n vm.toString(prevBlockNumDiff),\n \",\",\n vm.toString(l1BaseFee),\n \",\",\n vm.toString(requestedGas),\n \",\",\n vm.toString(gasConsumed),\n \",\",\n \"$\",\n vm.toString(ethPrice),\n \",\",\n \"$\",\n vm.toString(usdCost),\n \",\",\n result\n )\n );\n\n assertTrue(vm.revertTo(snapshotId));\n }\n }\n }\n }\n }\n }\n }\n}\n" - }, - "contracts/test/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\n\ncontract SafeCall_Test is CommonTest {\n function testFuzz_send_succeeds(\n address from,\n address to,\n uint256 gas,\n uint64 value\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n // don't call the ffi interface\n vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCall(to, value, bytes(\"\"));\n vm.prank(from);\n bool success = SafeCall.send(to, gas, value);\n\n assertTrue(success, \"send not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function testFuzz_call_succeeds(\n address from,\n address to,\n uint256 gas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n // don't call the ffi interface\n vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCall(to, value, data);\n vm.prank(from);\n bool success = SafeCall.call(to, gas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function testFuzz_callWithMinGas_hasEnough_succeeds(\n address from,\n address to,\n uint64 minGas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n // don't call the FFIInterface\n vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n // Bound minGas to [0, l1_block_gas_limit]\n minGas = uint64(bound(minGas, 0, 30_000_000));\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCallMinGas(to, value, minGas, data);\n vm.prank(from);\n bool success = SafeCall.callWithMinGas(to, minGas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function test_callWithMinGas_noLeakageLow_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 40_000; i < 100_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 65_907 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 65_907) {\n assertFalse(caller.makeSafeCall(i, 25_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 25_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 25_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n\n function test_callWithMinGas_noLeakageHigh_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 15_200_000; i < 15_300_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 15_278_606 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 15_278_606) {\n assertFalse(caller.makeSafeCall(i, 15_000_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 15_000_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 15_000_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n}\n\ncontract SimpleSafeCaller {\n uint256 public a;\n\n function makeSafeCall(uint64 gas, uint64 minGas) external returns (bool) {\n return\n SafeCall.call(\n address(this),\n gas,\n 0,\n abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas)\n );\n }\n\n function makeSafeCallMinGas(uint64 minGas) external returns (bool) {\n return\n SafeCall.callWithMinGas(\n address(this),\n minGas,\n 0,\n abi.encodeWithSelector(this.setA.selector, 1)\n );\n }\n\n function setA(uint256 _a) external {\n a = _a;\n }\n}\n" - }, - "contracts/test/Semver.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\n\n/**\n * @notice Test the Semver contract that is used for semantic versioning\n * of various contracts.\n */\ncontract Semver_Test is CommonTest {\n /**\n * @notice Global semver contract deployed in setUp. This is used in\n * the test cases.\n */\n Semver semver;\n\n /**\n * @notice Deploy a Semver contract\n */\n function setUp() public virtual override {\n semver = new Semver(7, 8, 0);\n }\n\n /**\n * @notice Test the version getter\n */\n function test_version_succeeds() external {\n assertEq(semver.version(), \"7.8.0\");\n }\n\n /**\n * @notice Since the versions are all immutable, they should\n * be able to be accessed from behind a proxy without needing\n * to initialize the contract.\n */\n function test_behindProxy_succeeds() external {\n Proxy proxy = new Proxy(alice);\n vm.prank(alice);\n proxy.upgradeTo(address(semver));\n\n assertEq(Semver(address(proxy)).version(), \"7.8.0\");\n }\n}\n" - }, - "contracts/test/SequencerFeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { SequencerFeeVault } from \"../L2/SequencerFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract SequencerFeeVault_Test is Bridge_Initializer {\n SequencerFeeVault vault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET));\n address constant recipient = address(256);\n\n event Withdrawal(uint256 value, address to, address from);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.SEQUENCER_FEE_WALLET, address(new SequencerFeeVault(recipient)).code);\n vm.label(Predeploys.SEQUENCER_FEE_WALLET, \"SequencerFeeVault\");\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n\n function test_constructor_succeeds() external {\n assertEq(vault.l1FeeWallet(), recipient);\n }\n\n function test_receive_succeeds() external {\n uint256 balance = address(vault).balance;\n\n vm.prank(alice);\n (bool success, ) = address(vault).call{ value: 100 }(hex\"\");\n\n assertEq(success, true);\n assertEq(address(vault).balance, balance + 100);\n }\n\n function test_withdraw_notEnough_reverts() external {\n assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());\n\n vm.expectRevert(\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n vault.withdraw();\n }\n\n function test_withdraw_succeeds() external {\n uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1;\n vm.deal(address(vault), amount);\n\n // No ether has been withdrawn yet\n assertEq(vault.totalProcessed(), 0);\n\n vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));\n emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));\n\n // The entire vault's balance is withdrawn\n vm.expectCall(\n Predeploys.L2_STANDARD_BRIDGE,\n address(vault).balance,\n abi.encodeWithSelector(\n StandardBridge.bridgeETHTo.selector,\n vault.l1FeeWallet(),\n 35_000,\n bytes(\"\")\n )\n );\n\n vault.withdraw();\n\n // The withdrawal was successful\n assertEq(vault.totalProcessed(), amount);\n }\n}\n" - }, - "contracts/test/StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport {\n OptimismMintableERC20,\n ILegacyMintableERC20\n} from \"../universal/OptimismMintableERC20.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/**\n * @title StandardBridgeTester\n * @notice Simple wrapper around the StandardBridge contract that exposes\n * internal functions so they can be more easily tested directly.\n */\ncontract StandardBridgeTester is StandardBridge {\n constructor(address payable _messenger, address payable _otherBridge)\n StandardBridge(_messenger, _otherBridge)\n {}\n\n function isOptimismMintableERC20(address _token) external view returns (bool) {\n return _isOptimismMintableERC20(_token);\n }\n\n function isCorrectTokenPair(address _mintableToken, address _otherToken)\n external\n view\n returns (bool)\n {\n return _isCorrectTokenPair(_mintableToken, _otherToken);\n }\n\n receive() external payable override {}\n}\n\n/**\n * @title LegacyMintable\n * @notice Simple implementation of the legacy OptimismMintableERC20.\n */\ncontract LegacyMintable is ERC20, ILegacyMintableERC20 {\n constructor(string memory _name, string memory _ticker) ERC20(_name, _ticker) {}\n\n function l1Token() external pure returns (address) {\n return address(0);\n }\n\n function mint(address _to, uint256 _amount) external pure {}\n\n function burn(address _from, uint256 _amount) external pure {}\n\n /**\n * @notice Implements ERC165. This implementation should not be changed as\n * it is how the actual legacy optimism mintable token does the\n * check. Allows for testing against code that is has been deployed,\n * assuming different compiler version is no problem.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n}\n\n/**\n * @title StandardBridge_Stateless_Test\n * @notice Tests internal functions that require no existing state or contract\n * interactions with the messenger.\n */\ncontract StandardBridge_Stateless_Test is CommonTest {\n StandardBridgeTester internal bridge;\n OptimismMintableERC20 internal mintable;\n ERC20 internal erc20;\n LegacyMintable internal legacy;\n\n function setUp() public override {\n super.setUp();\n\n bridge = new StandardBridgeTester({\n _messenger: payable(address(0)),\n _otherBridge: payable(address(0))\n });\n\n mintable = new OptimismMintableERC20({\n _bridge: address(0),\n _remoteToken: address(0),\n _name: \"Stonks\",\n _symbol: \"STONK\"\n });\n\n erc20 = new ERC20(\"Altcoin\", \"ALT\");\n legacy = new LegacyMintable(\"Legacy\", \"LEG\");\n }\n\n /**\n * @notice Test coverage for identifying OptimismMintableERC20 tokens.\n * This function should return true for both modern and legacy\n * OptimismMintableERC20 tokens and false for any accounts that\n * do not implement the interface.\n */\n function test_isOptimismMintableERC20_succeeds() external {\n // Both the modern and legacy mintable tokens should return true\n assertTrue(bridge.isOptimismMintableERC20(address(mintable)));\n assertTrue(bridge.isOptimismMintableERC20(address(legacy)));\n // A regular ERC20 should return false\n assertFalse(bridge.isOptimismMintableERC20(address(erc20)));\n // Non existent contracts should return false and not revert\n assertEq(address(0x20).code.length, 0);\n assertFalse(bridge.isOptimismMintableERC20(address(0x20)));\n }\n\n /**\n * @notice Test coverage of isCorrectTokenPair under different types of\n * tokens.\n */\n function test_isCorrectTokenPair_succeeds() external {\n // Modern + known to be correct remote token\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.remoteToken()));\n // Modern + known to be correct l1Token (legacy interface)\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.l1Token()));\n // Modern + known to be incorrect remote token\n assertTrue(mintable.remoteToken() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(mintable), address(0x20)));\n // Legacy + known to be correct l1Token\n assertTrue(bridge.isCorrectTokenPair(address(legacy), legacy.l1Token()));\n // Legacy + known to be incorrect l1Token\n assertTrue(legacy.l1Token() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(legacy), address(0x20)));\n // A token that doesn't support either modern or legacy interface\n // will revert\n vm.expectRevert();\n bridge.isCorrectTokenPair(address(erc20), address(1));\n }\n}\n" - }, - "contracts/test/SystemConfig.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract SystemConfig_Init is CommonTest {\n SystemConfig sysConf;\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n sysConf = new SystemConfig({\n _owner: alice,\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: config\n });\n }\n}\n\ncontract SystemConfig_Initialize_TestFail is SystemConfig_Init {\n function test_initialize_lowGasLimit_reverts() external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n\n ResourceMetering.ResourceConfig memory cfg = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n new SystemConfig({\n _owner: alice,\n _overhead: 0,\n _scalar: 0,\n _batcherHash: bytes32(hex\"\"),\n _gasLimit: minimumGasLimit - 1,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n }\n}\n\ncontract SystemConfig_Setters_TestFail is SystemConfig_Init {\n function test_setBatcherHash_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setBatcherHash(bytes32(hex\"\"));\n }\n\n function test_setGasConfig_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasConfig(0, 0);\n }\n\n function test_setGasLimit_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasLimit(0);\n }\n\n function test_setUnsafeBlockSigner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setUnsafeBlockSigner(address(0x20));\n }\n\n function test_setResourceConfig_notOwner_reverts() external {\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badMinMax_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 2 gwei,\n maximumBaseFee: 1 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: min base fee must be less than max base\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_zeroDenominator_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 0,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: denominator must be larger than 1\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_lowGasLimit_reverts() external {\n uint64 gasLimit = sysConf.gasLimit();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: uint32(gasLimit),\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: uint32(gasLimit),\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badPrecision_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 11,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: precision loss with target resource limit\");\n sysConf.setResourceConfig(config);\n }\n}\n\ncontract SystemConfig_Setters_Test is SystemConfig_Init {\n event ConfigUpdate(\n uint256 indexed version,\n SystemConfig.UpdateType indexed updateType,\n bytes data\n );\n\n function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash));\n\n vm.prank(sysConf.owner());\n sysConf.setBatcherHash(newBatcherHash);\n assertEq(sysConf.batcherHash(), newBatcherHash);\n }\n\n function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.GAS_CONFIG,\n abi.encode(newOverhead, newScalar)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setGasConfig(newOverhead, newScalar);\n assertEq(sysConf.overhead(), newOverhead);\n assertEq(sysConf.scalar(), newScalar);\n }\n\n function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n newGasLimit = uint64(\n bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))\n );\n\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit));\n\n vm.prank(sysConf.owner());\n sysConf.setGasLimit(newGasLimit);\n assertEq(sysConf.gasLimit(), newGasLimit);\n }\n\n function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER,\n abi.encode(newUnsafeSigner)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setUnsafeBlockSigner(newUnsafeSigner);\n assertEq(sysConf.unsafeBlockSigner(), newUnsafeSigner);\n }\n}\n" - }, - "contracts/test/TransferOnion.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { TransferOnion } from \"../periphery/TransferOnion.sol\";\n\n/**\n * @title TransferOnionTest\n * @notice Test coverage of TransferOnion\n */\ncontract TransferOnionTest is Test {\n /**\n * @notice TransferOnion\n */\n TransferOnion internal onion;\n\n /**\n * @notice token constructor arg\n */\n address internal _token;\n\n /**\n * @notice sender constructor arg\n */\n address internal _sender;\n\n /**\n * @notice Sets up addresses, deploys contracts and funds the owner.\n */\n function setUp() public {\n ERC20 token = new ERC20(\"Token\", \"TKN\");\n _token = address(token);\n _sender = makeAddr(\"sender\");\n }\n\n /**\n * @notice Deploy the TransferOnion with a dummy shell\n */\n function _deploy() public {\n _deploy(bytes32(0));\n }\n\n /**\n * @notice Deploy the TransferOnion with a specific shell\n */\n function _deploy(bytes32 _shell) public {\n onion = new TransferOnion({ _token: ERC20(_token), _sender: _sender, _shell: _shell });\n }\n\n /**\n * @notice Build the onion data\n */\n function _onionize(TransferOnion.Layer[] memory _layers)\n public\n pure\n returns (bytes32, TransferOnion.Layer[] memory)\n {\n uint256 length = _layers.length;\n bytes32 hash = bytes32(0);\n for (uint256 i; i < length; i++) {\n TransferOnion.Layer memory layer = _layers[i];\n _layers[i].shell = hash;\n hash = keccak256(abi.encode(layer.recipient, layer.amount, hash));\n }\n return (hash, _layers);\n }\n\n /**\n * @notice The constructor sets the variables as expected\n */\n function test_constructor_succeeds() external {\n _deploy();\n\n assertEq(address(onion.TOKEN()), _token);\n assertEq(onion.SENDER(), _sender);\n assertEq(onion.shell(), bytes32(0));\n }\n\n /**\n * @notice unwrap\n */\n function test_unwrap_succeeds() external {\n // Commit to transferring tiny amounts of tokens\n TransferOnion.Layer[] memory _layers = new TransferOnion.Layer[](2);\n _layers[0] = TransferOnion.Layer(address(1), 1, bytes32(0));\n _layers[1] = TransferOnion.Layer(address(2), 2, bytes32(0));\n\n // Build the onion shell\n (bytes32 shell, TransferOnion.Layer[] memory layers) = _onionize(_layers);\n _deploy(shell);\n\n assertEq(onion.shell(), shell);\n\n address token = address(onion.TOKEN());\n address sender = onion.SENDER();\n\n // give 3 units of token to sender\n deal(token, onion.SENDER(), 3);\n vm.prank(sender);\n ERC20(token).approve(address(onion), 3);\n\n // To build the inputs, to `peel`, need to reverse the list\n TransferOnion.Layer[] memory inputs = new TransferOnion.Layer[](2);\n int256 length = int256(layers.length);\n for (int256 i = length - 1; i >= 0; i--) {\n uint256 ui = uint256(i);\n uint256 revidx = uint256(length) - ui - 1;\n TransferOnion.Layer memory layer = layers[ui];\n inputs[revidx] = layer;\n }\n\n // The accounts have no balance\n assertEq(ERC20(_token).balanceOf(address(1)), 0);\n assertEq(ERC20(_token).balanceOf(address(2)), 0);\n\n onion.peel(inputs);\n\n // Now the accounts have the expected balance\n assertEq(ERC20(_token).balanceOf(address(1)), 1);\n assertEq(ERC20(_token).balanceOf(address(2)), 2);\n }\n}\n" - }, - "contracts/test/invariants/CrossDomainMessenger.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { OptimismPortal } from \"../../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../../L1/L1CrossDomainMessenger.sol\";\nimport { Messenger_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\nimport { Predeploys } from \"../../libraries/Predeploys.sol\";\nimport { Constants } from \"../../libraries/Constants.sol\";\nimport { Encoding } from \"../../libraries/Encoding.sol\";\nimport { Hashing } from \"../../libraries/Hashing.sol\";\n\ncontract RelayActor is StdUtils {\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n uint256 public numHashes;\n bytes32[] public hashes;\n bool public reverted = false;\n\n OptimismPortal op;\n L1CrossDomainMessenger xdm;\n Vm vm;\n bool doFail;\n\n constructor(\n OptimismPortal _op,\n L1CrossDomainMessenger _xdm,\n Vm _vm,\n bool _doFail\n ) {\n op = _op;\n xdm = _xdm;\n vm = _vm;\n doFail = _doFail;\n }\n\n /**\n * Relays a message to the `L1CrossDomainMessenger` with a random `version`, and `_message`.\n */\n function relay(\n uint8 _version,\n uint8 _value,\n bytes memory _message\n ) external {\n address target = address(0x04); // ID precompile\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Set the minimum gas limit to the cost of the identity precompile's execution for\n // the given message.\n // ID Precompile cost can be determined by calculating: 15 + 3 * data_word_length\n uint32 minGasLimit = uint32(15 + 3 * ((_message.length + 31) / 32));\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Restrict version to the range of [0, 1]\n _version = _version % 2;\n\n // Restrict the value to the range of [0, 1]\n // This is just so we get variance of calls with and without value. The ID precompile\n // will not reject value being sent to it.\n _value = _value % 2;\n\n // If the message should succeed, supply it `baseGas`. If not, supply it an amount of\n // gas that is too low to complete the call.\n uint256 gas = doFail\n ? bound(minGasLimit, 60_000, 80_000)\n : xdm.baseGas(_message, minGasLimit);\n\n // Compute the cross domain message hash and store it in `hashes`.\n // The `relayMessage` function will always encode the message as a version 1\n // message after checking that the V0 hash has not already been relayed.\n bytes32 _hash = Hashing.hashCrossDomainMessageV1(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n _value,\n minGasLimit,\n _message\n );\n hashes.push(_hash);\n numHashes += 1;\n\n // Make sure we've got a fresh message.\n vm.assume(xdm.successfulMessages(_hash) == false && xdm.failedMessages(_hash) == false);\n\n // Act as the optimism portal and call `relayMessage` on the `L1CrossDomainMessenger` with\n // the outer min gas limit.\n vm.startPrank(address(op));\n if (!doFail) {\n vm.expectCallMinGas(address(0x04), _value, minGasLimit, _message);\n }\n try\n xdm.relayMessage{ gas: gas, value: _value }(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n _value,\n minGasLimit,\n _message\n )\n {} catch {\n // If any of these calls revert, set `reverted` to true to fail the invariant test.\n // NOTE: This is to get around forge's invariant fuzzer ignoring reverted calls\n // to this function.\n reverted = true;\n }\n vm.stopPrank();\n }\n}\n\ncontract XDM_MinGasLimits is Messenger_Initializer {\n RelayActor actor;\n\n function init(bool doFail) public virtual {\n // Set up the `L1CrossDomainMessenger` and `OptimismPortal` contracts.\n super.setUp();\n\n // Deploy a relay actor\n actor = new RelayActor(op, L1Messenger, vm, doFail);\n\n // Give the portal some ether to send to `relayMessage`\n vm.deal(address(op), type(uint128).max);\n\n // Target the `RelayActor` contract\n targetContract(address(actor));\n\n // Don't allow the estimation address to be the sender\n excludeSender(Constants.ESTIMATION_ADDRESS);\n\n // Target the actor's `relay` function\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.relay.selector;\n targetSelector(FuzzSelector({ addr: address(actor), selectors: selectors }));\n }\n}\n\ncontract XDM_MinGasLimits_Succeeds is XDM_MinGasLimits {\n function setUp() public override {\n // Don't fail\n super.init(false);\n }\n\n /**\n * @custom:invariant A call to `relayMessage` should succeed if at least the minimum gas limit\n * can be supplied to the target context, there is enough gas to complete\n * execution of `relayMessage` after the target context's execution is\n * finished, and the target context did not revert.\n *\n * There are two minimum gas limits here:\n *\n * - The outer min gas limit is for the call from the `OptimismPortal` to the\n * `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function\n * with the `message` and inner limit.\n *\n * - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target\n * contract.\n */\n function invariant_minGasLimits() external {\n uint256 length = actor.numHashes();\n for (uint256 i = 0; i < length; ++i) {\n bytes32 hash = actor.hashes(i);\n // The message hash is set in the successfulMessages mapping\n assertTrue(L1Messenger.successfulMessages(hash));\n // The message hash is not set in the failedMessages mapping\n assertFalse(L1Messenger.failedMessages(hash));\n }\n assertFalse(actor.reverted());\n }\n}\n\ncontract XDM_MinGasLimits_Reverts is XDM_MinGasLimits {\n function setUp() public override {\n // Do fail\n super.init(true);\n }\n\n /**\n * @custom:invariant A call to `relayMessage` should assign the message hash to the\n * `failedMessages` mapping if not enough gas is supplied to forward\n * `minGasLimit` to the target context or if there is not enough gas to\n * complete execution of `relayMessage` after the target context's execution\n * is finished.\n *\n * There are two minimum gas limits here:\n *\n * - The outer min gas limit is for the call from the `OptimismPortal` to the\n * `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function\n * with the `message` and inner limit.\n *\n * - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target\n * contract.\n */\n function invariant_minGasLimits() external {\n uint256 length = actor.numHashes();\n for (uint256 i = 0; i < length; ++i) {\n bytes32 hash = actor.hashes(i);\n // The message hash is not set in the successfulMessages mapping\n assertFalse(L1Messenger.successfulMessages(hash));\n // The message hash is set in the failedMessages mapping\n assertTrue(L1Messenger.failedMessages(hash));\n }\n assertFalse(actor.reverted());\n }\n}\n" - }, - "contracts/test/invariants/L2OutputOracle.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { L2OutputOracle_Initializer } from \"../CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../../L1/L2OutputOracle.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\n\ncontract L2OutputOracle_Proposer {\n L2OutputOracle internal oracle;\n Vm internal vm;\n\n constructor(L2OutputOracle _oracle, Vm _vm) {\n oracle = _oracle;\n vm = _vm;\n }\n\n /**\n * @dev Allows the actor to propose an L2 output to the `L2OutputOracle`\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external {\n // Act as the proposer and propose a new output.\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _l2BlockNumber, _l1BlockHash, _l1BlockNumber);\n }\n}\n\ncontract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_Initializer {\n L2OutputOracle_Proposer internal actor;\n\n function setUp() public override {\n super.setUp();\n\n // Create a proposer actor.\n actor = new L2OutputOracle_Proposer(oracle, vm);\n\n // Set the target contract to the proposer actor.\n targetContract(address(actor));\n\n // Set the target selector for `proposeL2Output`\n // `proposeL2Output` is the only function we care about, as it is the only function\n // that can modify the `l2Outputs` array in the oracle.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.proposeL2Output.selector;\n FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The block number of the output root proposals should monotonically\n * increase.\n *\n * When a new output is submitted, it should never be allowed to correspond to a block\n * number that is less than the current output.\n */\n function invariant_monotonicBlockNumIncrease() external {\n // Assert that the block number of proposals must monotonically increase.\n assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber());\n }\n}\n" - }, - "contracts/test/invariants/OptimismPortal.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Portal_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\n\ncontract OptimismPortal_Invariant_Harness is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n function setUp() public virtual override {\n super.setUp();\n\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n}\n\ncontract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization\n * period has not elapsed.\n *\n * A withdrawal that has been proven should not be able to be finalized until after\n * the finalization period has elapsed.\n */\n function invariant_cannotFinalizeBeforePeriodHasPassed() external {\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Finalize the withdrawal transaction.\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal\n * has already been finalized.\n *\n * Ensures that there is no chain of calls that can be made that allows a withdrawal\n * to be finalized twice.\n */\n function invariant_cannotFinalizeTwice() external {\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant A withdrawal should **always** be able to be finalized\n * `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.\n *\n * This invariant asserts that there is no chain of calls that can be made that\n * will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS`\n * after it was successfully proven.\n */\n function invariant_canAlwaysFinalize() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value);\n }\n}\n" - }, - "contracts/test/invariants/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { SafeCall } from \"../../libraries/SafeCall.sol\";\n\ncontract SafeCall_Succeeds_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, false);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n\n // Give the actor some ETH to work with\n vm.deal(address(actor), type(uint128).max);\n }\n\n /**\n * @custom:invariant If `callWithMinGas` performs a call, then it must always\n * provide at least the specified minimum gas limit to the subcontext.\n *\n * If the check for remaining gas in `SafeCall.callWithMinGas` passes, the\n * subcontext of the call below it must be provided at least `minGas` gas.\n */\n function invariant_callWithMinGas_alwaysForwardsMinGas_succeeds() public {\n assertEq(actor.numCalls(), 0, \"no failed calls allowed\");\n }\n\n function performSafeCallMinGas(address to, uint64 minGas) external payable {\n SafeCall.callWithMinGas(to, minGas, msg.value, hex\"\");\n }\n}\n\ncontract SafeCall_Fails_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, true);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n\n // Give the actor some ETH to work with\n vm.deal(address(actor), type(uint128).max);\n }\n\n /**\n * @custom:invariant `callWithMinGas` reverts if there is not enough gas to pass\n * to the subcontext.\n *\n * If there is not enough gas in the callframe to ensure that `callWithMinGas`\n * can provide the specified minimum gas limit to the subcontext of the call,\n * then `callWithMinGas` must revert.\n */\n function invariant_callWithMinGas_neverForwardsMinGas_reverts() public {\n assertEq(actor.numCalls(), 0, \"no successful calls allowed\");\n }\n\n function performSafeCallMinGas(address to, uint64 minGas) external payable {\n SafeCall.callWithMinGas(to, minGas, msg.value, hex\"\");\n }\n}\n\ncontract SafeCaller_Actor is StdUtils {\n bool internal immutable FAILS;\n\n Vm internal vm;\n uint256 public numCalls;\n\n constructor(Vm _vm, bool _fails) {\n vm = _vm;\n FAILS = _fails;\n }\n\n function performSafeCallMinGas(\n uint64 gas,\n uint64 minGas,\n address to,\n uint8 value\n ) external {\n // Only send to EOAs - we exclude the console as it has no code but reverts when called\n // with a selector that doesn't exist due to the foundry hook.\n vm.assume(to.code.length == 0 && to != 0x000000000000000000636F6e736F6c652e6c6f67);\n\n // Bound the minimum gas amount to [2500, type(uint48).max]\n minGas = uint64(bound(minGas, 2500, type(uint48).max));\n if (FAILS) {\n // Bound the gas passed to [minGas, ((minGas * 64) / 63)]\n gas = uint64(bound(gas, minGas, (minGas * 64) / 63));\n } else {\n // Bound the gas passed to\n // [((minGas * 64) / 63) + 40_000 + 1000, type(uint64).max]\n // The extra 1000 gas is to account for the gas used by the `SafeCall.call` call\n // itself.\n gas = uint64(bound(gas, ((minGas * 64) / 63) + 40_000 + 1000, type(uint64).max));\n }\n\n vm.expectCallMinGas(to, value, minGas, hex\"\");\n bool success = SafeCall.call(\n msg.sender,\n gas,\n value,\n abi.encodeWithSelector(\n SafeCall_Succeeds_Invariants.performSafeCallMinGas.selector,\n to,\n minGas\n )\n );\n\n if (success && FAILS) numCalls++;\n if (!FAILS && !success) numCalls++;\n }\n}\n" - }, - "contracts/test/invariants/SystemConfig.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { SystemConfig } from \"../../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../../L1/ResourceMetering.sol\";\nimport { Constants } from \"../../libraries/Constants.sol\";\n\ncontract SystemConfig_GasLimitLowerBound_Invariant is Test {\n SystemConfig public config;\n\n function setUp() public {\n ResourceMetering.ResourceConfig memory cfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n config = new SystemConfig({\n _owner: address(0xbeef),\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n\n // Set the target contract to the `config`\n targetContract(address(config));\n // Set the target sender to the `config`'s owner (0xbeef)\n targetSender(address(0xbeef));\n // Set the target selector for `setGasLimit`\n // `setGasLimit` is the only function we care about, as it is the only function\n // that can modify the gas limit within the SystemConfig.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = config.setGasLimit.selector;\n FuzzSelector memory selector = FuzzSelector({\n addr: address(config),\n selectors: selectors\n });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The gas limit of the `SystemConfig` contract can never be lower\n * than the hard-coded lower bound.\n */\n function invariant_gasLimitLowerBound() external {\n assertTrue(config.gasLimit() >= config.minimumGasLimit());\n }\n}\n" - }, - "contracts/universal/CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer0\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * libAddressManager variable used to exist. Must be the first contract in the inheritance\n * tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer0 {\n /**\n * @custom:legacy\n * @custom:spacer libAddressManager\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n}\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer1\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * PausableUpgradable and OwnableUpgradeable variables used to exist. Must be\n * the third contract in the inheritance tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer1 {\n /**\n * @custom:legacy\n * @custom:spacer ContextUpgradable's __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable.\n *\n */\n uint256[50] private spacer_1_0_1600;\n\n /**\n * @custom:legacy\n * @custom:spacer OwnableUpgradeable's _owner\n * @notice Spacer for backwards compatibility.\n * Come from OpenZeppelin OwnableUpgradeable.\n */\n address private spacer_51_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer OwnableUpgradeable's __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * OwnableUpgradeable.\n */\n uint256[49] private spacer_52_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer PausableUpgradable's _paused\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n bool private spacer_101_0_1;\n\n /**\n * @custom:legacy\n * @custom:spacer PausableUpgradable's __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n uint256[49] private spacer_102_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer ReentrancyGuardUpgradeable's `_status` field.\n * @notice Spacer for backwards compatibility.\n */\n uint256 private spacer_151_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer ReentrancyGuardUpgradeable's __gap\n * @notice Spacer for backwards compatibility.\n */\n uint256[49] private spacer_152_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer blockedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_201_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer relayedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_202_0_32;\n}\n\n/**\n * @custom:upgradeable\n * @title CrossDomainMessenger\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\n * cross-chain messenger contracts. It's designed to be a universal interface that only\n * needs to be extended slightly to provide low-level message passing functionality on each\n * chain it's deployed on. Currently only designed for message passing between two paired\n * chains and does not support one-to-many interactions.\n *\n * Any changes to this contract MUST result in a semver bump for contracts that inherit it.\n */\nabstract contract CrossDomainMessenger is\n CrossDomainMessengerLegacySpacer0,\n Initializable,\n CrossDomainMessengerLegacySpacer1\n{\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Constant overhead added to the base gas for a message.\n */\n uint64 public constant RELAY_CONSTANT_OVERHEAD = 200_000;\n\n /**\n * @notice Numerator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 64;\n\n /**\n * @notice Denominator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 63;\n\n /**\n * @notice Extra gas added to base gas for each byte of calldata in a message.\n */\n uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\n\n /**\n * @notice Gas reserved for performing the external call in `relayMessage`.\n */\n uint64 public constant RELAY_CALL_OVERHEAD = 40_000;\n\n /**\n * @notice Gas reserved for finalizing the execution of `relayMessage` after the safe call.\n */\n uint64 public constant RELAY_RESERVED_GAS = 40_000;\n\n /**\n * @notice Gas reserved for the execution between the `hasMinGas` check and the external\n * call in `relayMessage`.\n */\n uint64 public constant RELAY_GAS_CHECK_BUFFER = 5_000;\n\n /**\n * @notice Address of the paired CrossDomainMessenger contract on the other chain.\n */\n address public immutable OTHER_MESSENGER;\n\n /**\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n * be present in this mapping if it has successfully been relayed on this chain, and\n * can therefore not be relayed again.\n */\n mapping(bytes32 => bool) public successfulMessages;\n\n /**\n * @notice Address of the sender of the currently executing message on the other chain. If the\n * value of this variable is the default value (0x00000000...dead) then no message is\n * currently being executed. Use the xDomainMessageSender getter which will throw an\n * error if this is the case.\n */\n address internal xDomainMsgSender;\n\n /**\n * @notice Nonce for the next message to be sent, without the message version applied. Use the\n * messageNonce getter which will insert the message version into the nonce to give you\n * the actual nonce to be used for the message.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Mapping of message hashes to a boolean if and only if the message has failed to be\n * executed at least once. A message will not be present in this mapping if it\n * successfully executed on the first attempt.\n */\n mapping(bytes32 => bool) public failedMessages;\n\n /**\n * @notice Reserve extra slots in the storage layout for future upgrades.\n * A gap size of 41 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[42] private __gap;\n\n /**\n * @notice Emitted whenever a message is sent to the other chain.\n *\n * @param target Address of the recipient of the message.\n * @param sender Address of the sender of the message.\n * @param message Message to trigger the recipient address with.\n * @param messageNonce Unique nonce attached to the message.\n * @param gasLimit Minimum gas limit that the message can be executed with.\n */\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n /**\n * @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the\n * SentMessage event without breaking the ABI of this contract, this is good enough.\n *\n * @param sender Address of the sender of the message.\n * @param value ETH value sent along with the message to the recipient.\n */\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n /**\n * @notice Emitted whenever a message is successfully relayed on this chain.\n *\n * @param msgHash Hash of the message that was relayed.\n */\n event RelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @notice Emitted whenever a message fails to be relayed on this chain.\n *\n * @param msgHash Hash of the message that failed to be relayed.\n */\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @param _otherMessenger Address of the messenger on the paired chain.\n */\n constructor(address _otherMessenger) {\n OTHER_MESSENGER = _otherMessenger;\n }\n\n /**\n * @notice Sends a message to some target address on the other chain. Note that if the call\n * always reverts, then the message will be unrelayable, and any ETH sent will be\n * permanently locked. The same will occur if the target on the other chain is\n * considered unsafe (see the _isUnsafeTarget() function).\n *\n * @param _target Target contract or wallet address.\n * @param _message Message to trigger the target address with.\n * @param _minGasLimit Minimum gas limit that the message can be executed with.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _minGasLimit\n ) external payable {\n // Triggers a message to the other messenger. Note that the amount of gas provided to the\n // message is the amount of gas requested by the user PLUS the base gas value. We want to\n // guarantee the property that the call to the target contract will always have at least\n // the minimum gas limit specified by the user.\n _sendMessage(\n OTHER_MESSENGER,\n baseGas(_message, _minGasLimit),\n msg.value,\n abi.encodeWithSelector(\n this.relayMessage.selector,\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _minGasLimit,\n _message\n )\n );\n\n emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit);\n emit SentMessageExtension1(msg.sender, msg.value);\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\n * be executed via cross-chain call from the other messenger OR if the message was\n * already received once and is currently being replayed.\n *\n * @param _nonce Nonce of the message being relayed.\n * @param _sender Address of the user who sent the message.\n * @param _target Address that the message is targeted at.\n * @param _value ETH value to send with the message.\n * @param _minGasLimit Minimum amount of gas that the message can be executed with.\n * @param _message Message to send to the target.\n */\n function relayMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _minGasLimit,\n bytes calldata _message\n ) external payable {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n require(\n version < 2,\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // If the message is version 0, then it's a migrated legacy withdrawal. We therefore need\n // to check that the legacy version of the message has not already been relayed.\n if (version == 0) {\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce);\n require(\n successfulMessages[oldHash] == false,\n \"CrossDomainMessenger: legacy withdrawal already relayed\"\n );\n }\n\n // We use the v1 message hash as the unique identifier for the message because it commits\n // to the value and minimum gas limit of the message.\n bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _minGasLimit,\n _message\n );\n\n if (_isOtherMessenger()) {\n // These properties should always hold when the message is first submitted (as\n // opposed to being replayed).\n assert(msg.value == _value);\n assert(!failedMessages[versionedHash]);\n } else {\n require(\n msg.value == 0,\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n\n require(\n failedMessages[versionedHash],\n \"CrossDomainMessenger: message cannot be replayed\"\n );\n }\n\n require(\n _isUnsafeTarget(_target) == false,\n \"CrossDomainMessenger: cannot send message to blocked system address\"\n );\n\n require(\n successfulMessages[versionedHash] == false,\n \"CrossDomainMessenger: message has already been relayed\"\n );\n\n // If there is not enough gas left to perform the external call and finish the execution,\n // return early and assign the message to the failedMessages mapping.\n // We are asserting that we have enough gas to:\n // 1. Call the target contract (_minGasLimit + RELAY_CALL_OVERHEAD + RELAY_GAS_CHECK_BUFFER)\n // 1.a. The RELAY_CALL_OVERHEAD is included in `hasMinGas`.\n // 2. Finish the execution after the external call (RELAY_RESERVED_GAS).\n //\n // If `xDomainMsgSender` is not the default L2 sender, this function\n // is being re-entered. This marks the message as failed to allow it to be replayed.\n if (\n !SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER) ||\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER\n ) {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n\n return;\n }\n\n xDomainMsgSender = _sender;\n bool success = SafeCall.call(_target, gasleft() - RELAY_RESERVED_GAS, _value, _message);\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n\n if (success) {\n successfulMessages[versionedHash] = true;\n emit RelayedMessage(versionedHash);\n } else {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n }\n }\n\n /**\n * @notice Retrieves the address of the contract or wallet that initiated the currently\n * executing message on the other chain. Will throw an error if there is no message\n * currently being executed. Allows the recipient of a call to see who triggered it.\n *\n * @return Address of the sender of the currently executing message on the other chain.\n */\n function xDomainMessageSender() external view returns (address) {\n require(\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER,\n \"CrossDomainMessenger: xDomainMessageSender is not set\"\n );\n\n return xDomainMsgSender;\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n\n /**\n * @notice Computes the amount of gas required to guarantee that a given message will be\n * received on the other chain without running out of gas. Guaranteeing that a message\n * will not run out of gas is important because this ensures that a message can always\n * be replayed on the other chain if it fails to execute completely.\n *\n * @param _message Message to compute the amount of required gas for.\n * @param _minGasLimit Minimum desired gas limit when message goes to target.\n *\n * @return Amount of gas required to guarantee message receipt.\n */\n function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {\n return\n // Constant overhead\n RELAY_CONSTANT_OVERHEAD +\n // Calldata overhead\n (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\n // Dynamic overhead (EIP-150)\n ((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\n MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\n // Gas reserved for the worst-case cost of 3/5 of the `CALL` opcode's dynamic gas\n // factors. (Conservative)\n RELAY_CALL_OVERHEAD +\n // Relay reserved gas (to ensure execution of `relayMessage` completes after the\n // subcontext finishes executing) (Conservative)\n RELAY_RESERVED_GAS +\n // Gas reserved for the execution between the `hasMinGas` check and the `CALL`\n // opcode. (Conservative)\n RELAY_GAS_CHECK_BUFFER;\n }\n\n /**\n * @notice Intializer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __CrossDomainMessenger_init() internal onlyInitializing {\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n }\n\n /**\n * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @param _to Recipient of the message on the other chain.\n * @param _gasLimit Minimum gas limit the message can be executed with.\n * @param _value Amount of ETH to send with the message.\n * @param _data Message data.\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal virtual;\n\n /**\n * @notice Checks whether the message is coming from the other messenger. Implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @return Whether the message is coming from the other messenger.\n */\n function _isOtherMessenger() internal view virtual returns (bool);\n\n /**\n * @notice Checks whether a given call target is a system address that could cause the\n * messenger to peform an unsafe action. This is NOT a mechanism for blocking user\n * addresses. This is ONLY used to prevent the execution of messages to specific\n * system addresses that could cause security issues, e.g., having the\n * CrossDomainMessenger send messages to itself.\n *\n * @param _target Address of the contract to check.\n *\n * @return Whether or not the address is an unsafe system address.\n */\n function _isUnsafeTarget(address _target) internal view virtual returns (bool);\n}\n" - }, - "contracts/universal/ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721Bridge\n * @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.\n */\nabstract contract ERC721Bridge {\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Address of the bridge on the other network.\n */\n address public immutable OTHER_BRIDGE;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[49] private __gap;\n\n /**\n * @notice Emitted when an ERC721 bridge to the other network is initiated.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC721 bridge from the other network is finalized.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) && MESSENGER.xDomainMessageSender() == OTHER_BRIDGE,\n \"ERC721Bridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge) {\n require(_messenger != address(0), \"ERC721Bridge: messenger cannot be address(0)\");\n require(_otherBridge != address(0), \"ERC721Bridge: other bridge cannot be address(0)\");\n\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = _otherBridge;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for other bridge address.\n *\n * @return Address of the bridge on the other network.\n */\n function otherBridge() external view returns (address) {\n return OTHER_BRIDGE;\n }\n\n /**\n * @notice Initiates a bridge of an NFT to the caller's account on the other chain. Note that\n * this function can only be called by EOAs. Smart contract wallets should use the\n * `bridgeERC721To` function after ensuring that the recipient address on the remote\n * chain exists. Also note that the current owner of the token on this chain must\n * approve this contract to operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721(\n address _localToken,\n address _remoteToken,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n // Modifier requiring sender to be EOA. This prevents against a user error that would occur\n // if the sender is a smart contract wallet that has a different address on the remote chain\n // (or doesn't have an address on the remote chain at all). The user would fail to receive\n // the NFT if they use this function because it sends the NFT to the same address as the\n // caller. This check could be bypassed by a malicious contract via initcode, but it takes\n // care of the user error we want to avoid.\n require(!Address.isContract(msg.sender), \"ERC721Bridge: account is not externally owned\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note\n * that the current owner of the token on this chain must approve this contract to\n * operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n require(_to != address(0), \"ERC721Bridge: nft recipient cannot be address(0)\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Internal function for initiating a token bridge to the other domain.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _from Address of the sender on this domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other domain. Data supplied here will\n * not be used to execute any code on the other domain and is only emitted\n * as extra data for the convenience of off-chain tooling.\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal virtual;\n}\n" - }, - "contracts/universal/FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n/**\n * @title FeeVault\n * @notice The FeeVault contract contains the basic logic for the various different vault contracts\n * used to hold fee revenue generated by the L2 system.\n */\nabstract contract FeeVault {\n /**\n * @notice Emits each time that a withdrawal occurs.\n *\n * @param value Amount that was withdrawn (in wei).\n * @param to Address that the funds were sent to.\n * @param from Address that triggered the withdrawal.\n */\n event Withdrawal(uint256 value, address to, address from);\n\n /**\n * @notice Minimum balance before a withdrawal can be triggered.\n */\n uint256 public immutable MIN_WITHDRAWAL_AMOUNT;\n\n /**\n * @notice Wallet that will receive the fees on L1.\n */\n address public immutable RECIPIENT;\n\n /**\n * @notice The minimum gas limit for the FeeVault withdrawal transaction.\n */\n uint32 internal constant WITHDRAWAL_MIN_GAS = 35_000;\n\n /**\n * @notice Total amount of wei processed by the contract.\n */\n uint256 public totalProcessed;\n\n /**\n * @param _recipient Wallet that will receive the fees on L1.\n * @param _minWithdrawalAmount Minimum balance before a withdrawal can be triggered.\n */\n constructor(address _recipient, uint256 _minWithdrawalAmount) {\n MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;\n RECIPIENT = _recipient;\n }\n\n /**\n * @notice Allow the contract to receive ETH.\n */\n receive() external payable {}\n\n /**\n * @notice Triggers a withdrawal of funds to the L1 fee wallet.\n */\n function withdraw() external {\n require(\n address(this).balance >= MIN_WITHDRAWAL_AMOUNT,\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n\n uint256 value = address(this).balance;\n totalProcessed += value;\n\n emit Withdrawal(value, RECIPIENT, msg.sender);\n\n L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }(\n RECIPIENT,\n WITHDRAWAL_MIN_GAS,\n bytes(\"\")\n );\n }\n}\n" - }, - "contracts/universal/IOptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @title IOptimismMintableERC20\n * @notice This interface is available on the OptimismMintableERC20 contract. We declare it as a\n * separate interface so that it can be used in custom implementations of\n * OptimismMintableERC20.\n */\ninterface IOptimismMintableERC20 is IERC165 {\n function remoteToken() external view returns (address);\n\n function bridge() external returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n\n/**\n * @custom:legacy\n * @title ILegacyMintableERC20\n * @notice This interface was available on the legacy L2StandardERC20 contract. It remains available\n * on the OptimismMintableERC20 contract for backwards compatibility.\n */\ninterface ILegacyMintableERC20 is IERC165 {\n function l1Token() external view returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n" - }, - "contracts/universal/IOptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\n/**\n * @title IOptimismMintableERC721\n * @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.\n * Tokens that follow this standard can be easily transferred across the ERC721 bridge.\n */\ninterface IOptimismMintableERC721 is IERC721Enumerable {\n /**\n * @notice Emitted when a token is minted.\n *\n * @param account Address of the account the token was minted to.\n * @param tokenId Token ID of the minted token.\n */\n event Mint(address indexed account, uint256 tokenId);\n\n /**\n * @notice Emitted when a token is burned.\n *\n * @param account Address of the account the token was burned from.\n * @param tokenId Token ID of the burned token.\n */\n event Burn(address indexed account, uint256 tokenId);\n\n /**\n * @notice Mints some token ID for a user, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * @param _to Address of the user to mint the token for.\n * @param _tokenId Token ID to mint.\n */\n function safeMint(address _to, uint256 _tokenId) external;\n\n /**\n * @notice Burns a token ID from a user.\n *\n * @param _from Address of the user to burn the token from.\n * @param _tokenId Token ID to burn.\n */\n function burn(address _from, uint256 _tokenId) external;\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function REMOTE_CHAIN_ID() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function REMOTE_TOKEN() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function BRIDGE() external view returns (address);\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function remoteChainId() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function remoteToken() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function bridge() external view returns (address);\n}\n" - }, - "contracts/universal/OptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { ILegacyMintableERC20, IOptimismMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC20\n * @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed\n * to allow the StandardBridge contracts to mint and burn tokens. This makes it possible to\n * use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa.\n * Designed to be backwards compatible with the older StandardL2ERC20 token which was only\n * meant for use on L2.\n */\ncontract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, Semver {\n /**\n * @notice Address of the corresponding version of this token on the remote chain.\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @notice Address of the StandardBridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Emitted whenever tokens are minted for an account.\n *\n * @param account Address of the account tokens are being minted for.\n * @param amount Amount of tokens minted.\n */\n event Mint(address indexed account, uint256 amount);\n\n /**\n * @notice Emitted whenever tokens are burned from an account.\n *\n * @param account Address of the account tokens are being burned from.\n * @param amount Amount of tokens burned.\n */\n event Burn(address indexed account, uint256 amount);\n\n /**\n * @notice A modifier that only allows the bridge to call\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC20: only bridge can mint and burn\");\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the L2 standard bridge.\n * @param _remoteToken Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _bridge,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) Semver(1, 0, 0) {\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n }\n\n /**\n * @notice Allows the StandardBridge on this network to mint tokens.\n *\n * @param _to Address to mint tokens to.\n * @param _amount Amount of tokens to mint.\n */\n function mint(address _to, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _mint(_to, _amount);\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Allows the StandardBridge on this network to burn tokens.\n *\n * @param _from Address to burn tokens from.\n * @param _amount Amount of tokens to burn.\n */\n function burn(address _from, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _burn(_from, _amount);\n emit Burn(_from, _amount);\n }\n\n /**\n * @notice ERC165 interface check function.\n *\n * @param _interfaceId Interface ID to check.\n *\n * @return Whether or not the interface is supported by this contract.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 iface1 = type(IERC165).interfaceId;\n // Interface corresponding to the legacy L2StandardERC20.\n bytes4 iface2 = type(ILegacyMintableERC20).interfaceId;\n // Interface corresponding to the updated OptimismMintableERC20 (this contract).\n bytes4 iface3 = type(IOptimismMintableERC20).interfaceId;\n return _interfaceId == iface1 || _interfaceId == iface2 || _interfaceId == iface3;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote token. Use REMOTE_TOKEN going forward.\n */\n function l1Token() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the bridge. Use BRIDGE going forward.\n */\n function l2Bridge() public view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for REMOTE_TOKEN.\n */\n function remoteToken() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for BRIDGE.\n */\n function bridge() public view returns (address) {\n return BRIDGE;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC20Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Contract Imports */\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000012\n * @title OptimismMintableERC20Factory\n * @notice OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20\n * contracts on the network it's deployed to. Simplifies the deployment process for users\n * who may be less familiar with deploying smart contracts. Designed to be backwards\n * compatible with the older StandardL2ERC20Factory contract.\n */\ncontract OptimismMintableERC20Factory is Semver {\n /**\n * @notice Address of the StandardBridge on this chain.\n */\n address public immutable BRIDGE;\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a new OptimismMintableERC20 is created. Legacy version of the newer\n * OptimismMintableERC20Created event. We recommend relying on that event instead.\n *\n * @param remoteToken Address of the token on the remote chain.\n * @param localToken Address of the created token on the local chain.\n */\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC20 is created.\n *\n * @param localToken Address of the created token on the local chain.\n * @param remoteToken Address of the corresponding token on the remote chain.\n * @param deployer Address of the account that deployed the token.\n */\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC20 token contract since this contract\n * is responsible for deploying OptimismMintableERC20 contracts.\n *\n * @param _bridge Address of the StandardBridge on this chain.\n */\n constructor(address _bridge) Semver(1, 1, 0) {\n BRIDGE = _bridge;\n }\n\n /**\n * @custom:legacy\n * @notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the\n * newer createOptimismMintableERC20 function, which has a more intuitive name.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createStandardL2Token(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n return createOptimismMintableERC20(_remoteToken, _name, _symbol);\n }\n\n /**\n * @notice Creates an instance of the OptimismMintableERC20 contract.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createOptimismMintableERC20(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) public returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC20Factory: must provide remote token address\"\n );\n\n address localToken = address(\n new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol)\n );\n\n // Emit the old event too for legacy support.\n emit StandardL2TokenCreated(_remoteToken, localToken);\n\n // Emit the updated event. The arguments here differ from the legacy event, but\n // are consistent with the ordering used in StandardBridge events.\n emit OptimismMintableERC20Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n ERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { IOptimismMintableERC721 } from \"./IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC721\n * @notice This contract is the remote representation for some token that lives on another network,\n * typically an Optimism representation of an Ethereum-based token. Standard reference\n * implementation that can be extended or modified according to your needs.\n */\ncontract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Semver {\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Base token URI for this token.\n */\n string public baseTokenURI;\n\n /**\n * @notice Modifier that prevents callers other than the bridge from calling the function.\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC721: only bridge can call this function\");\n _;\n }\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _bridge Address of the bridge on this network.\n * @param _remoteChainId Chain ID where the remote token is deployed.\n * @param _remoteToken Address of the corresponding token on the other network.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n constructor(\n address _bridge,\n uint256 _remoteChainId,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) Semver(1, 1, 0) {\n require(_bridge != address(0), \"OptimismMintableERC721: bridge cannot be address(0)\");\n require(_remoteChainId != 0, \"OptimismMintableERC721: remote chain id cannot be zero\");\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721: remote token cannot be address(0)\"\n );\n\n REMOTE_CHAIN_ID = _remoteChainId;\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n\n // Creates a base URI in the format specified by EIP-681:\n // https://eips.ethereum.org/EIPS/eip-681\n baseTokenURI = string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(_remoteToken), 20),\n \"@\",\n Strings.toString(_remoteChainId),\n \"/tokenURI?uint256=\"\n )\n );\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteChainId() external view returns (uint256) {\n return REMOTE_CHAIN_ID;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteToken() external view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function bridge() external view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function safeMint(address _to, uint256 _tokenId) external virtual onlyBridge {\n _safeMint(_to, _tokenId);\n\n emit Mint(_to, _tokenId);\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function burn(address _from, uint256 _tokenId) external virtual onlyBridge {\n _burn(_tokenId);\n\n emit Burn(_from, _tokenId);\n }\n\n /**\n * @notice Checks if a given interface ID is supported by this contract.\n *\n * @param _interfaceId The interface ID to check.\n *\n * @return True if the interface ID is supported, false otherwise.\n */\n function supportsInterface(bytes4 _interfaceId)\n public\n view\n override(ERC721Enumerable, IERC165)\n returns (bool)\n {\n bytes4 iface = type(IOptimismMintableERC721).interfaceId;\n return _interfaceId == iface || super.supportsInterface(_interfaceId);\n }\n\n /**\n * @notice Returns the base token URI.\n *\n * @return Base token URI.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return baseTokenURI;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismMintableERC721 } from \"./OptimismMintableERC721.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @title OptimismMintableERC721Factory\n * @notice Factory contract for creating OptimismMintableERC721 contracts.\n */\ncontract OptimismMintableERC721Factory is Semver {\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Chain ID for the remote network.\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @notice Tracks addresses created by this factory.\n */\n mapping(address => bool) public isOptimismMintableERC721;\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC721 contract is created.\n *\n * @param localToken Address of the token on the this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param deployer Address of the initiator of the deployment\n */\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.2.0\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC721 token contract since this contract\n * is responsible for deploying OptimismMintableERC721 contracts.\n *\n * @param _bridge Address of the ERC721 bridge on this network.\n * @param _remoteChainId Chain ID for the remote network.\n */\n constructor(address _bridge, uint256 _remoteChainId) Semver(1, 2, 0) {\n BRIDGE = _bridge;\n REMOTE_CHAIN_ID = _remoteChainId;\n }\n\n /**\n * @notice Creates an instance of the standard ERC721.\n *\n * @param _remoteToken Address of the corresponding token on the other domain.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n function createOptimismMintableERC721(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721Factory: L1 token address cannot be address(0)\"\n );\n\n address localToken = address(\n new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)\n );\n\n isOptimismMintableERC721[localToken] = true;\n emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/Proxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Proxy\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\n * if the caller is address(0), meaning that the call originated from an off-chain\n * simulation.\n */\ncontract Proxy {\n /**\n * @notice The storage slot that holds the address of the implementation.\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice The storage slot that holds the address of the owner.\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice An event that is emitted each time the implementation is changed. This event is part\n * of the EIP-1967 specification.\n *\n * @param implementation The address of the implementation contract\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\n * EIP-1967 specification.\n *\n * @param previousAdmin The previous owner of the contract\n * @param newAdmin The new owner of the contract\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\n * eth_call to interact with this proxy without needing to use low-level storage\n * inspection. We assume that nobody is able to trigger calls from address(0) during\n * normal EVM execution.\n */\n modifier proxyCallIfNotAdmin() {\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\n * EIP-1967 admin storage slot so that accidental storage collision with the\n * implementation is not possible.\n *\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\n * transparent proxy interface.\n */\n constructor(address _admin) {\n _changeAdmin(_admin);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Set the implementation contract address. The code at the given address will execute\n * when this contract is called.\n *\n * @param _implementation Address of the implementation contract.\n */\n function upgradeTo(address _implementation) public virtual proxyCallIfNotAdmin {\n _setImplementation(_implementation);\n }\n\n /**\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\n * atomic execution of initialization-based upgrades.\n *\n * @param _implementation Address of the implementation contract.\n * @param _data Calldata to delegatecall the new implementation with.\n */\n function upgradeToAndCall(address _implementation, bytes calldata _data)\n public\n payable\n virtual\n proxyCallIfNotAdmin\n returns (bytes memory)\n {\n _setImplementation(_implementation);\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\n require(success, \"Proxy: delegatecall to new implementation contract failed\");\n return returndata;\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _admin New owner of the proxy contract.\n */\n function changeAdmin(address _admin) public virtual proxyCallIfNotAdmin {\n _changeAdmin(_admin);\n }\n\n /**\n * @notice Gets the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function admin() public virtual proxyCallIfNotAdmin returns (address) {\n return _getAdmin();\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function implementation() public virtual proxyCallIfNotAdmin returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n emit Upgraded(_implementation);\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _admin New owner of the proxy contract.\n */\n function _changeAdmin(address _admin) internal {\n address previous = _getAdmin();\n assembly {\n sstore(OWNER_KEY, _admin)\n }\n emit AdminChanged(previous, _admin);\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal {\n address impl = _getImplementation();\n require(impl != address(0), \"Proxy: implementation not initialized\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address impl;\n assembly {\n impl := sload(IMPLEMENTATION_KEY)\n }\n return impl;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getAdmin() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n}\n" - }, - "contracts/universal/ProxyAdmin.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { Proxy } from \"./Proxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\n\n/**\n * @title IStaticERC1967Proxy\n * @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface.\n */\ninterface IStaticERC1967Proxy {\n function implementation() external view returns (address);\n\n function admin() external view returns (address);\n}\n\n/**\n * @title IStaticL1ChugSplashProxy\n * @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface.\n */\ninterface IStaticL1ChugSplashProxy {\n function getImplementation() external view returns (address);\n\n function getOwner() external view returns (address);\n}\n\n/**\n * @title ProxyAdmin\n * @notice This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy,\n * based on the OpenZeppelin implementation. It has backwards compatibility logic to work\n * with the various types of proxies that have been deployed by Optimism in the past.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @notice The proxy types that the ProxyAdmin can manage.\n *\n * @custom:value ERC1967 Represents an ERC1967 compliant transparent proxy interface.\n * @custom:value CHUGSPLASH Represents the Chugsplash proxy interface (legacy).\n * @custom:value RESOLVED Represents the ResolvedDelegate proxy (legacy).\n */\n enum ProxyType {\n ERC1967,\n CHUGSPLASH,\n RESOLVED\n }\n\n /**\n * @notice A mapping of proxy types, used for backwards compatibility.\n */\n mapping(address => ProxyType) public proxyType;\n\n /**\n * @notice A reverse mapping of addresses to names held in the AddressManager. This must be\n * manually kept up to date with changes in the AddressManager for this contract\n * to be able to work as an admin for the ResolvedDelegateProxy type.\n */\n mapping(address => string) public implementationName;\n\n /**\n * @notice The address of the address manager, this is required to manage the\n * ResolvedDelegateProxy type.\n */\n AddressManager public addressManager;\n\n /**\n * @notice A legacy upgrading indicator used by the old Chugsplash Proxy.\n */\n bool internal upgrading;\n\n /**\n * @param _owner Address of the initial owner of this contract.\n */\n constructor(address _owner) Ownable() {\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the proxy type for a given address. Only required for non-standard (legacy)\n * proxy types.\n *\n * @param _address Address of the proxy.\n * @param _type Type of the proxy.\n */\n function setProxyType(address _address, ProxyType _type) external onlyOwner {\n proxyType[_address] = _type;\n }\n\n /**\n * @notice Sets the implementation name for a given address. Only required for\n * ResolvedDelegateProxy type proxies that have an implementation name.\n *\n * @param _address Address of the ResolvedDelegateProxy.\n * @param _name Name of the implementation for the proxy.\n */\n function setImplementationName(address _address, string memory _name) external onlyOwner {\n implementationName[_address] = _name;\n }\n\n /**\n * @notice Set the address of the AddressManager. This is required to manage legacy\n * ResolvedDelegateProxy type proxy contracts.\n *\n * @param _address Address of the AddressManager.\n */\n function setAddressManager(AddressManager _address) external onlyOwner {\n addressManager = _address;\n }\n\n /**\n * @custom:legacy\n * @notice Set an address in the address manager. Since only the owner of the AddressManager\n * can directly modify addresses and the ProxyAdmin will own the AddressManager, this\n * gives the owner of the ProxyAdmin the ability to modify addresses directly.\n *\n * @param _name Name to set within the AddressManager.\n * @param _address Address to attach to the given name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n addressManager.setAddress(_name, _address);\n }\n\n /**\n * @custom:legacy\n * @notice Set the upgrading status for the Chugsplash proxy type.\n *\n * @param _upgrading Whether or not the system is upgrading.\n */\n function setUpgrading(bool _upgrading) external onlyOwner {\n upgrading = _upgrading;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\n *\n * @return Whether or not there is an upgrade going on. May not actually tell you whether an\n * upgrade is going on, since we don't currently plan to use this variable for anything\n * other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\n */\n function isUpgrading() external view returns (bool) {\n return upgrading;\n }\n\n /**\n * @notice Returns the implementation of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the implementation of.\n *\n * @return Address of the implementation of the proxy.\n */\n function getProxyImplementation(address _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).implementation();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getImplementation();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.getAddress(implementationName[_proxy]);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Returns the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the admin of.\n *\n * @return Address of the admin of the proxy.\n */\n function getProxyAdmin(address payable _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).admin();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getOwner();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.owner();\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Updates the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to update.\n * @param _newAdmin Address of the new proxy admin.\n */\n function changeProxyAdmin(address payable _proxy, address _newAdmin) external onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).changeAdmin(_newAdmin);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setOwner(_newAdmin);\n } else if (ptype == ProxyType.RESOLVED) {\n addressManager.transferOwnership(_newAdmin);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n */\n function upgrade(address payable _proxy, address _implementation) public onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeTo(_implementation);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setStorage(\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n bytes32(uint256(uint160(_implementation)))\n );\n } else if (ptype == ProxyType.RESOLVED) {\n string memory name = implementationName[_proxy];\n addressManager.setAddress(name, _implementation);\n } else {\n // It should not be possible to retrieve a ProxyType value which is not matched by\n // one of the previous conditions.\n assert(false);\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract and delegatecalls the new implementation\n * with some given data. Useful for atomic upgrade-and-initialize calls.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n * @param _data Data to trigger the new implementation with.\n */\n function upgradeAndCall(\n address payable _proxy,\n address _implementation,\n bytes memory _data\n ) external payable onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);\n } else {\n // reverts if proxy type is unknown\n upgrade(_proxy, _implementation);\n (bool success, ) = _proxy.call{ value: msg.value }(_data);\n require(success, \"ProxyAdmin: call to proxy after upgrade failed\");\n }\n }\n}\n" - }, - "contracts/universal/Semver.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n" - }, - "contracts/universal/StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { IOptimismMintableERC20, ILegacyMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"./OptimismMintableERC20.sol\";\n\n/**\n * @custom:upgradeable\n * @title StandardBridge\n * @notice StandardBridge is a base contract for the L1 and L2 standard ERC20 bridges. It handles\n * the core bridging logic, including escrowing tokens that are native to the local chain\n * and minting/burning tokens that are native to the remote chain.\n */\nabstract contract StandardBridge {\n using SafeERC20 for IERC20;\n\n /**\n * @notice The L2 gas limit set when eth is depoisited using the receive() function.\n */\n uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000;\n\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Corresponding bridge on the other domain.\n */\n StandardBridge public immutable OTHER_BRIDGE;\n\n /**\n * @custom:legacy\n * @custom:spacer messenger\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer l2TokenBridge\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_1_0_20;\n\n /**\n * @notice Mapping that stores deposits for a given pair of local and remote tokens.\n */\n mapping(address => mapping(address => uint256)) public deposits;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n * A gap size of 47 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[47] private __gap;\n\n /**\n * @notice Emitted when an ETH bridge is initiated to the other chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ETH bridge is finalized on this chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is initiated to the other chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is finalized on this chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Only allow EOAs to call the functions. Note that this is not safe against contracts\n * calling code within their constructors, but also doesn't really matter since we're\n * just trying to prevent users accidentally depositing with smart contract wallets.\n */\n modifier onlyEOA() {\n require(\n !Address.isContract(msg.sender),\n \"StandardBridge: function can only be called from an EOA\"\n );\n _;\n }\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) &&\n MESSENGER.xDomainMessageSender() == address(OTHER_BRIDGE),\n \"StandardBridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of CrossDomainMessenger on this network.\n * @param _otherBridge Address of the other StandardBridge contract.\n */\n constructor(address payable _messenger, address payable _otherBridge) {\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = StandardBridge(_otherBridge);\n }\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n * Must be implemented by contracts that inherit.\n */\n receive() external payable virtual;\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @notice Sends ETH to the sender's address on the other chain.\n *\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETH(uint32 _minGasLimit, bytes calldata _extraData) public payable onlyEOA {\n _initiateBridgeETH(msg.sender, msg.sender, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a\n * smart contract and the call fails, the ETH will be temporarily locked in the\n * StandardBridge on the other chain until the call is replayed. If the call cannot be\n * replayed with any amount of gas (call always reverts), then the ETH will be\n * permanently locked in the StandardBridge on the other chain. ETH will also\n * be locked if the receiver is the other bridge, because finalizeBridgeETH will revert\n * in that case.\n *\n * @param _to Address of the receiver.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public payable {\n _initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ERC20 tokens to the sender's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20(\n address _localToken,\n address _remoteToken,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual onlyEOA {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public payable onlyOtherBridge {\n require(msg.value == _amount, \"StandardBridge: amount sent does not match amount required\");\n require(_to != address(this), \"StandardBridge: cannot send to self\");\n require(_to != address(MESSENGER), \"StandardBridge: cannot send to messenger\");\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n\n bool success = SafeCall.call(_to, gasleft(), _amount, hex\"\");\n require(success, \"StandardBridge: ETH transfer failed\");\n }\n\n /**\n * @notice Finalizes an ERC20 bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public onlyOtherBridge {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).mint(_to, _amount);\n } else {\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] - _amount;\n IERC20(_localToken).safeTransfer(_to, _amount);\n }\n\n // Emit the correct events. By default this will be ERC20BridgeFinalized, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Initiates a bridge of ETH through the CrossDomainMessenger.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n require(\n msg.value == _amount,\n \"StandardBridge: bridging ETH must include sufficient ETH value\"\n );\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage{ value: _amount }(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeETH.selector,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).burn(_from, _amount);\n } else {\n IERC20(_localToken).safeTransferFrom(_from, address(this), _amount);\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] + _amount;\n }\n\n // Emit the correct events. By default this will be ERC20BridgeInitiated, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeERC20.selector,\n // Because this call will be executed on the remote chain, we reverse the order of\n // the remote and local token addresses relative to their order in the\n // finalizeBridgeERC20 function.\n _remoteToken,\n _localToken,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Checks if a given address is an OptimismMintableERC20. Not perfect, but good enough.\n * Just the way we like it.\n *\n * @param _token Address of the token to check.\n *\n * @return True if the token is an OptimismMintableERC20.\n */\n function _isOptimismMintableERC20(address _token) internal view returns (bool) {\n return\n ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId) ||\n ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);\n }\n\n /**\n * @notice Checks if the \"other token\" is the correct pair token for the OptimismMintableERC20.\n * Calls can be saved in the future by combining this logic with\n * `_isOptimismMintableERC20`.\n *\n * @param _mintableToken OptimismMintableERC20 to check against.\n * @param _otherToken Pair token to check.\n *\n * @return True if the other token is the correct pair token for the OptimismMintableERC20.\n */\n function _isCorrectTokenPair(address _mintableToken, address _otherToken)\n internal\n view\n returns (bool)\n {\n if (\n ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)\n ) {\n return _otherToken == ILegacyMintableERC20(_mintableToken).l1Token();\n } else {\n return _otherToken == IOptimismMintableERC20(_mintableToken).remoteToken();\n }\n }\n\n /** @notice Emits the ETHBridgeInitiated event and if necessary the appropriate legacy event\n * when an ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ETHBridgeFinalized and if necessary the appropriate legacy event when an\n * ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeInitiated event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeFinalized event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/vendor/AddressAliasHelper.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.0;\n\nlibrary AddressAliasHelper {\n uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n /// @notice Utility function that converts the address in the L1 that submitted a tx to\n /// the inbox to the msg.sender viewed in the L2\n /// @param l1Address the address in the L1 that triggered the tx to L2\n /// @return l2Address L2 address as viewed in msg.sender\n function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {\n unchecked {\n l2Address = address(uint160(l1Address) + offset);\n }\n }\n\n /// @notice Utility function that converts the msg.sender viewed in the L2 to the\n /// address in the L1 that submitted a tx to the inbox\n /// @param l2Address L2 address as viewed in msg.sender\n /// @return l1Address the address in the L1 that triggered the tx to L2\n function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {\n unchecked {\n l1Address = address(uint160(l2Address) - offset);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/governance/utils/IVotes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20Permit.sol\";\nimport \"../../../utils/math/Math.sol\";\nimport \"../../../governance/utils/IVotes.sol\";\nimport \"../../../utils/math/SafeCast.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20Votes is IVotes, ERC20Permit {\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCast.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = Math.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSA.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"./IERC721Enumerable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n // Mapping from owner to list of owned token IDs\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n // Mapping from token ID to index of the owner tokens list\n mapping(uint256 => uint256) private _ownedTokensIndex;\n\n // Array with all token ids, used for enumeration\n uint256[] private _allTokens;\n\n // Mapping from token id to position in the allTokens array\n mapping(uint256 => uint256) private _allTokensIndex;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n return _ownedTokens[owner][index];\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _allTokens.length;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721Enumerable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n return _allTokens[index];\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n if (from == address(0)) {\n _addTokenToAllTokensEnumeration(tokenId);\n } else if (from != to) {\n _removeTokenFromOwnerEnumeration(from, tokenId);\n }\n if (to == address(0)) {\n _removeTokenFromAllTokensEnumeration(tokenId);\n } else if (to != from) {\n _addTokenToOwnerEnumeration(to, tokenId);\n }\n }\n\n /**\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\n * @param to address representing the new owner of the given token ID\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n */\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n uint256 length = ERC721.balanceOf(to);\n _ownedTokens[to][length] = tokenId;\n _ownedTokensIndex[tokenId] = length;\n }\n\n /**\n * @dev Private function to add a token to this extension's token tracking data structures.\n * @param tokenId uint256 ID of the token to be added to the tokens list\n */\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n _allTokensIndex[tokenId] = _allTokens.length;\n _allTokens.push(tokenId);\n }\n\n /**\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n * @param from address representing the previous owner of the given token ID\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n */\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary\n if (tokenIndex != lastTokenIndex) {\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n }\n\n // This also deletes the contents at the last position of the array\n delete _ownedTokensIndex[tokenId];\n delete _ownedTokens[from][lastTokenIndex];\n }\n\n /**\n * @dev Private function to remove a token from this extension's token tracking data structures.\n * This has O(1) time complexity, but alters the order of the _allTokens array.\n * @param tokenId uint256 ID of the token to be removed from the tokens list\n */\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = _allTokens.length - 1;\n uint256 tokenIndex = _allTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n // This also deletes the contents at the last position of the array\n delete _allTokensIndex[tokenId];\n _allTokens.pop();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Counters.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface,\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n _supportsERC165Interface(account, type(IERC165).interfaceId) &&\n !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)\n internal\n view\n returns (bool[] memory)\n {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in _interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!_supportsERC165Interface(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n * Interface identification is specified in ERC-165.\n */\n function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/Bytes32AddressLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Library for converting between addresses and bytes32 values.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)\nlibrary Bytes32AddressLib {\n function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {\n return bytes32(bytes20(addressValue));\n }\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n /*//////////////////////////////////////////////////////////////\n SIMPLIFIED FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n }\n\n function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n }\n\n function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n }\n\n function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n }\n\n function powWad(int256 x, int256 y) internal pure returns (int256) {\n // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\n return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\n }\n\n function expWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n // When the result is < 0.5 we return zero. This happens when\n // x <= floor(log(0.5e18) * 1e18) ~ -42e18\n if (x <= -42139678854452767551) return 0;\n\n // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\n // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\n if (x >= 135305999368893231589) revert(\"EXP_OVERFLOW\");\n\n // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\n // for more intermediate precision and a binary basis. This base conversion\n // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n x = (x << 78) / 5**18;\n\n // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\n x = x - k * 54916777467707473351141471128;\n\n // k is in the range [-61, 195].\n\n // Evaluate using a (6, 7)-term rational approximation.\n // p is made monic, we'll multiply by a scale factor later.\n int256 y = x + 1346386616545796478920950773328;\n y = ((y * x) >> 96) + 57155421227552351082224309758442;\n int256 p = y + x - 94201549194550492254356042504812;\n p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n p = p * x + (4385272521454847904659076985693276 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n int256 q = x - 2855989394907223263936484059900;\n q = ((q * x) >> 96) + 50020603652535783019961831881945;\n q = ((q * x) >> 96) - 533845033583426703283633433725380;\n q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial won't have zeros in the domain as all its roots are complex.\n // No scaling is necessary because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r should be in the range (0.09, 0.25) * 2**96.\n\n // We now need to multiply r by:\n // * the scale factor s = ~6.031367120.\n // * the 2**k factor from the range reduction.\n // * the 1e18 / 2**96 factor for base conversion.\n // We do this all at once, with an intermediate result in 2**213\n // basis, so the final right shift is always by a positive amount.\n r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\n }\n }\n\n function lnWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n require(x > 0, \"UNDEFINED\");\n\n // We want to convert x from 10**18 fixed point to 2**96 fixed point.\n // We do this by multiplying by 2**96 / 10**18. But since\n // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\n // and add ln(2**96 / 10**18) at the end.\n\n // Reduce range of x to (1, 2) * 2**96\n // ln(2^k * x) = k * ln(2) + ln(x)\n int256 k = int256(log2(uint256(x))) - 96;\n x <<= uint256(159 - k);\n x = int256(uint256(x) >> 159);\n\n // Evaluate using a (8, 8)-term rational approximation.\n // p is made monic, we will multiply by a scale factor later.\n int256 p = x + 3273285459638523848632254066296;\n p = ((p * x) >> 96) + 24828157081833163892658089445524;\n p = ((p * x) >> 96) + 43456485725739037958740375743393;\n p = ((p * x) >> 96) - 11111509109440967052023855526967;\n p = ((p * x) >> 96) - 45023709667254063763336534515857;\n p = ((p * x) >> 96) - 14706773417378608786704636184526;\n p = p * x - (795164235651350426258249787498 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n // q is monic by convention.\n int256 q = x + 5573035233440673466300451813936;\n q = ((q * x) >> 96) + 71694874799317883764090561454958;\n q = ((q * x) >> 96) + 283447036172924575727196451306956;\n q = ((q * x) >> 96) + 401686690394027663651624208769553;\n q = ((q * x) >> 96) + 204048457590392012362485061816622;\n q = ((q * x) >> 96) + 31853899698501571402653359427138;\n q = ((q * x) >> 96) + 909429971244387300277376558375;\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial is known not to have zeros in the domain.\n // No scaling required because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r is in the range (0, 0.125) * 2**96\n\n // Finalization, we need to:\n // * multiply by the scale factor s = 5.549…\n // * add ln(2**96 / 10**18)\n // * add k * ln(2)\n // * multiply by 10**18 / 2**96 = 5**18 >> 78\n\n // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\n r *= 1677202110996718588342820967067443963516166;\n // add ln(2) * k * 5e18 * 2**192\n r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\n // add ln(2**96 / 10**18) * 5e18 * 2**192\n r += 600920179829731861736702779321621459595472258049074101567377883020018308;\n // base conversion: mul 2**18 / 2**192\n r >>= 174;\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n LOW LEVEL FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function mulDivDown(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // Divide z by the denominator.\n z := div(z, denominator)\n }\n }\n\n function mulDivUp(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // First, divide z - 1 by the denominator and add 1.\n // We allow z - 1 to underflow if z is 0, because we multiply the\n // end result by 0 if z is zero, ensuring we return 0 if z is zero.\n z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\n }\n }\n\n function rpow(\n uint256 x,\n uint256 n,\n uint256 scalar\n ) internal pure returns (uint256 z) {\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n // 0 ** 0 = 1\n z := scalar\n }\n default {\n // 0 ** n = 0\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n // If n is even, store scalar in z for now.\n z := scalar\n }\n default {\n // If n is odd, store x in z for now.\n z := x\n }\n\n // Shifting right by 1 is like dividing by 2.\n let half := shr(1, scalar)\n\n for {\n // Shift n right by 1 before looping to halve it.\n n := shr(1, n)\n } n {\n // Shift n right by 1 each iteration to halve it.\n n := shr(1, n)\n } {\n // Revert immediately if x ** 2 would overflow.\n // Equivalent to iszero(eq(div(xx, x), x)) here.\n if shr(128, x) {\n revert(0, 0)\n }\n\n // Store x squared.\n let xx := mul(x, x)\n\n // Round to the nearest number.\n let xxRound := add(xx, half)\n\n // Revert if xx + half overflowed.\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n\n // Set x to scaled xxRound.\n x := div(xxRound, scalar)\n\n // If n is even:\n if mod(n, 2) {\n // Compute z * x.\n let zx := mul(z, x)\n\n // If z * x overflowed:\n if iszero(eq(div(zx, x), z)) {\n // Revert if x is non-zero.\n if iszero(iszero(x)) {\n revert(0, 0)\n }\n }\n\n // Round to the nearest number.\n let zxRound := add(zx, half)\n\n // Revert if zx + half overflowed.\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n\n // Return properly scaled zxRound.\n z := div(zxRound, scalar)\n }\n }\n }\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n GENERAL NUMBER UTILITIES\n //////////////////////////////////////////////////////////////*/\n\n function sqrt(uint256 x) internal pure returns (uint256 z) {\n assembly {\n let y := x // We start y at x, which will help us make our initial estimate.\n\n z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n // We check y >= 2^(k + 8) but shift right by k bits\n // each branch to ensure that if x >= 256, then y >= 256.\n if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n y := shr(128, y)\n z := shl(64, z)\n }\n if iszero(lt(y, 0x1000000000000000000)) {\n y := shr(64, y)\n z := shl(32, z)\n }\n if iszero(lt(y, 0x10000000000)) {\n y := shr(32, y)\n z := shl(16, z)\n }\n if iszero(lt(y, 0x1000000)) {\n y := shr(16, y)\n z := shl(8, z)\n }\n\n // Goal was to get z*z*y within a small factor of x. More iterations could\n // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n // There is no overflow risk here since y < 2^136 after the first branch above.\n z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n\n // If x+1 is a perfect square, the Babylonian method cycles between\n // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n z := sub(z, lt(div(x, z), z))\n }\n }\n\n function log2(uint256 x) internal pure returns (uint256 r) {\n require(x > 0, \"UNDEFINED\");\n\n assembly {\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\n r := or(r, shl(3, lt(0xff, shr(r, x))))\n r := or(r, shl(2, lt(0xf, shr(r, x))))\n r := or(r, shl(1, lt(0x3, shr(r, x))))\n r := or(r, lt(0x1, shr(r, x)))\n }\n }\n}\n" - }, - "node_modules/clones-with-immutable-args/src/ClonesWithImmutableArgs.sol": { - "content": "// SPDX-License-Identifier: BSD\n\npragma solidity ^0.8.4;\n\n/// @title ClonesWithImmutableArgs\n/// @author wighawag, zefram.eth, Saw-mon & Natalie\n/// @notice Enables creating clone contracts with immutable args\nlibrary ClonesWithImmutableArgs {\n uint256 private constant FREE_MEMORY_POINTER_SLOT = 0x40;\n uint256 private constant BOOTSTRAP_LENGTH = 0x3f;\n uint256 private constant ONE_WORD = 0x20;\n uint256 private constant MAX_UINT256 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n bytes32 private constant CREATE_FAIL_ERROR = 0xebfef18800000000000000000000000000000000000000000000000000000000;\n\n /// @notice Creates a clone proxy of the implementation contract, with immutable args\n /// @dev data cannot exceed 65535 bytes, since 2 bytes are used to store the data length\n /// @param implementation The implementation contract to clone\n /// @param data Encoded immutable args\n /// @return instance The address of the created clone\n function clone(address implementation, bytes memory data)\n internal\n returns (address payable instance)\n {\n // unrealistic for memory ptr or data length to exceed 256 bits\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let extraLength := add(mload(data), 2) // +2 bytes for telling how much data there is appended to the call\n let creationSize := add(extraLength, BOOTSTRAP_LENGTH)\n let runSize := sub(creationSize, 0x0a)\n\n // free memory pointer\n let ptr := mload(FREE_MEMORY_POINTER_SLOT)\n \n // -------------------------------------------------------------------------------------------------------------\n // CREATION (10 bytes)\n // -------------------------------------------------------------------------------------------------------------\n\n // 61 runtime | PUSH2 runtime (r) | r | –\n // 3d | RETURNDATASIZE | 0 r | –\n // 81 | DUP2 | r 0 r | –\n // 60 offset | PUSH1 offset (o) | o r 0 r | –\n // 3d | RETURNDATASIZE | 0 o r 0 r | –\n // 39 | CODECOPY | 0 r | [0 - runSize): runtime code\n // f3 | RETURN | | [0 - runSize): runtime code\n\n // -------------------------------------------------------------------------------------------------------------\n // RUNTIME (53 bytes + extraLength)\n // -------------------------------------------------------------------------------------------------------------\n\n // --- copy calldata to memmory ---\n // 36 | CALLDATASIZE | cds | –\n // 3d | RETURNDATASIZE | 0 cds | –\n // 3d | RETURNDATASIZE | 0 0 cds | –\n // 37 | CALLDATACOPY | | [0 - cds): calldata\n\n // --- keep some values in stack ---\n // 3d | RETURNDATASIZE | 0 | [0 - cds): calldata\n // 3d | RETURNDATASIZE | 0 0 | [0 - cds): calldata\n // 3d | RETURNDATASIZE | 0 0 0 | [0 - cds): calldata\n // 3d | RETURNDATASIZE | 0 0 0 0 | [0 - cds): calldata\n // 61 extra | PUSH2 extra (e) | e 0 0 0 0 | [0 - cds): calldata\n\n // --- copy extra data to memory ---\n // 80 | DUP1 | e e 0 0 0 0 | [0 - cds): calldata\n // 60 0x35 | PUSH1 0x35 | 0x35 e e 0 0 0 0 | [0 - cds): calldata\n // 36 | CALLDATASIZE | cds 0x35 e e 0 0 0 0 | [0 - cds): calldata\n // 39 | CODECOPY | e 0 0 0 0 | [0 - cds): calldata, [cds - cds + e): extraData\n\n // --- delegate call to the implementation contract ---\n // 36 | CALLDATASIZE | cds e 0 0 0 0 | [0 - cds): calldata, [cds - cds + e): extraData\n // 01 | ADD | cds+e 0 0 0 0 | [0 - cds): calldata, [cds - cds + e): extraData\n // 3d | RETURNDATASIZE | 0 cds+e 0 0 0 0 | [0 - cds): calldata, [cds - cds + e): extraData\n // 73 addr | PUSH20 addr | addr 0 cds+e 0 0 0 0 | [0 - cds): calldata, [cds - cds + e): extraData\n // 5a | GAS | gas addr 0 cds+e 0 0 0 0| [0 - cds): calldata, [cds - cds + e): extraData\n // f4 | DELEGATECALL | success 0 0 | [0 - cds): calldata, [cds - cds + e): extraData\n\n // --- copy return data to memory ---\n // 3d | RETURNDATASIZE | rds success 0 0 | [0 - cds): calldata, [cds - cds + e): extraData\n // 3d | RETURNDATASIZE | rds rds success 0 0 | [0 - cds): calldata, [cds - cds + e): extraData\n // 93 | SWAP4 | 0 rds success 0 rds | [0 - cds): calldata, [cds - cds + e): extraData\n // 80 | DUP1 | 0 0 rds success 0 rds | [0 - cds): calldata, [cds - cds + e): extraData\n // 3e | RETURNDATACOPY | success 0 rds | [0 - rds): returndata, ... the rest might be dirty\n \n // 60 0x33 | PUSH1 0x33 | 0x33 success 0 rds | [0 - rds): returndata, ... the rest might be dirty\n // 57 | JUMPI | 0 rds | [0 - rds): returndata, ... the rest might be dirty\n\n // --- revert ---\n // fd | REVERT | | [0 - rds): returndata, ... the rest might be dirty\n\n // --- return ---\n // 5b | JUMPDEST | 0 rds | [0 - rds): returndata, ... the rest might be dirty\n // f3 | RETURN | | [0 - rds): returndata, ... the rest might be dirty\n\n mstore(\n ptr,\n or(\n hex\"610000_3d_81_600a_3d_39_f3_36_3d_3d_37_3d_3d_3d_3d_610000_80_6035_36_39_36_01_3d_73\",\n or(\n shl(0xe8, runSize),\n shl(0x58, extraLength)\n )\n )\n )\n \n mstore(\n add(ptr, 0x1e),\n shl(0x60, implementation)\n )\n\n mstore(\n add(ptr, 0x32),\n hex\"5a_f4_3d_3d_93_80_3e_6033_57_fd_5b_f3\"\n )\n\n\n // -------------------------------------------------------------------------------------------------------------\n // APPENDED DATA (Accessible from extcodecopy)\n // (but also send as appended data to the delegatecall)\n // -------------------------------------------------------------------------------------------------------------\n\n let counter := mload(data)\n let copyPtr := add(ptr, BOOTSTRAP_LENGTH)\n let dataPtr := add(data, ONE_WORD)\n\n for {} true {} {\n if lt(counter, ONE_WORD) {\n break\n }\n\n mstore(copyPtr, mload(dataPtr))\n\n copyPtr := add(copyPtr, ONE_WORD)\n dataPtr := add(dataPtr, ONE_WORD)\n\n counter := sub(counter, ONE_WORD)\n }\n \n let mask := shl(\n shl(3, sub(ONE_WORD, counter)), \n MAX_UINT256\n )\n\n mstore(copyPtr, and(mload(dataPtr), mask))\n copyPtr := add(copyPtr, counter)\n mstore(copyPtr, shl(0xf0, extraLength))\n\n instance := create(0, ptr, creationSize)\n\n if iszero(instance) {\n // revert CreateFail()\n mstore(0, CREATE_FAIL_ERROR)\n revert(0, ONE_WORD)\n }\n\n // Update free memory pointer\n mstore(FREE_MEMORY_POINTER_SLOT, add(ptr, creationSize))\n }\n }\n}\n" - }, - "node_modules/ds-test/src/test.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.5.0;\n\ncontract DSTest {\n event log (string);\n event logs (bytes);\n\n event log_address (address);\n event log_bytes32 (bytes32);\n event log_int (int);\n event log_uint (uint);\n event log_bytes (bytes);\n event log_string (string);\n\n event log_named_address (string key, address val);\n event log_named_bytes32 (string key, bytes32 val);\n event log_named_decimal_int (string key, int val, uint decimals);\n event log_named_decimal_uint (string key, uint val, uint decimals);\n event log_named_int (string key, int val);\n event log_named_uint (string key, uint val);\n event log_named_bytes (string key, bytes val);\n event log_named_string (string key, string val);\n\n bool public IS_TEST = true;\n bool private _failed;\n\n address constant HEVM_ADDRESS =\n address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));\n\n modifier mayRevert() { _; }\n modifier testopts(string memory) { _; }\n\n function failed() public returns (bool) {\n if (_failed) {\n return _failed;\n } else {\n bool globalFailed = false;\n if (hasHEVMContext()) {\n (, bytes memory retdata) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"load(address,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"))\n )\n );\n globalFailed = abi.decode(retdata, (bool));\n }\n return globalFailed;\n }\n } \n\n function fail() internal {\n if (hasHEVMContext()) {\n (bool status, ) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"store(address,bytes32,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"), bytes32(uint256(0x01)))\n )\n );\n status; // Silence compiler warnings\n }\n _failed = true;\n }\n\n function hasHEVMContext() internal view returns (bool) {\n uint256 hevmCodeSize = 0;\n assembly {\n hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D)\n }\n return hevmCodeSize > 0;\n }\n\n modifier logs_gas() {\n uint startGas = gasleft();\n _;\n uint endGas = gasleft();\n emit log_named_uint(\"gas\", startGas - endGas);\n }\n\n function assertTrue(bool condition) internal {\n if (!condition) {\n emit log(\"Error: Assertion Failed\");\n fail();\n }\n }\n\n function assertTrue(bool condition, string memory err) internal {\n if (!condition) {\n emit log_named_string(\"Error\", err);\n assertTrue(condition);\n }\n }\n\n function assertEq(address a, address b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [address]\");\n emit log_named_address(\" Expected\", b);\n emit log_named_address(\" Actual\", a);\n fail();\n }\n }\n function assertEq(address a, address b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes32 a, bytes32 b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bytes32]\");\n emit log_named_bytes32(\" Expected\", b);\n emit log_named_bytes32(\" Actual\", a);\n fail();\n }\n }\n function assertEq(bytes32 a, bytes32 b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq32(bytes32 a, bytes32 b) internal {\n assertEq(a, b);\n }\n function assertEq32(bytes32 a, bytes32 b, string memory err) internal {\n assertEq(a, b, err);\n }\n\n function assertEq(int a, int b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [int]\");\n emit log_named_int(\" Expected\", b);\n emit log_named_int(\" Actual\", a);\n fail();\n }\n }\n function assertEq(int a, int b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq(uint a, uint b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [uint]\");\n emit log_named_uint(\" Expected\", b);\n emit log_named_uint(\" Actual\", a);\n fail();\n }\n }\n function assertEq(uint a, uint b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEqDecimal(int a, int b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Expected\", b, decimals);\n emit log_named_decimal_int(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Expected\", b, decimals);\n emit log_named_decimal_uint(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n\n function assertGt(uint a, uint b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGt(uint a, uint b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGt(int a, int b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGt(int a, int b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGtDecimal(int a, int b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n\n function assertGe(uint a, uint b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGe(uint a, uint b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGe(int a, int b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGe(int a, int b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGeDecimal(int a, int b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertLt(uint a, uint b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLt(uint a, uint b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLt(int a, int b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLt(int a, int b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLtDecimal(int a, int b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n\n function assertLe(uint a, uint b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLe(uint a, uint b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLe(int a, int b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLe(int a, int b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLeDecimal(int a, int b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLeDecimal(a, b, decimals);\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertEq(string memory a, string memory b) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log(\"Error: a == b not satisfied [string]\");\n emit log_named_string(\" Expected\", b);\n emit log_named_string(\" Actual\", a);\n fail();\n }\n }\n function assertEq(string memory a, string memory b, string memory err) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {\n ok = true;\n if (a.length == b.length) {\n for (uint i = 0; i < a.length; i++) {\n if (a[i] != b[i]) {\n ok = false;\n }\n }\n } else {\n ok = false;\n }\n }\n function assertEq0(bytes memory a, bytes memory b) internal {\n if (!checkEq0(a, b)) {\n emit log(\"Error: a == b not satisfied [bytes]\");\n emit log_named_bytes(\" Expected\", b);\n emit log_named_bytes(\" Actual\", a);\n fail();\n }\n }\n function assertEq0(bytes memory a, bytes memory b, string memory err) internal {\n if (!checkEq0(a, b)) {\n emit log_named_string(\"Error\", err);\n assertEq0(a, b);\n }\n }\n}\n" - }, - "node_modules/forge-std/src/Base.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {StdStorage} from \"./StdStorage.sol\";\nimport {Vm, VmSafe} from \"./Vm.sol\";\n\nabstract contract CommonBase {\n // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.\n address internal constant VM_ADDRESS = address(uint160(uint256(keccak256(\"hevm cheat code\"))));\n // console.sol and console2.sol work by executing a staticcall to this address.\n address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;\n // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38.\n address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256(\"foundry default caller\"))));\n // Address of the test contract, deployed by the DEFAULT_SENDER.\n address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;\n // Deterministic deployment address of the Multicall3 contract.\n address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11;\n\n uint256 internal constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n Vm internal constant vm = Vm(VM_ADDRESS);\n StdStorage internal stdstore;\n}\n\nabstract contract TestBase is CommonBase {}\n\nabstract contract ScriptBase is CommonBase {\n // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);\n}\n" - }, - "node_modules/forge-std/src/StdAssertions.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {DSTest} from \"ds-test/test.sol\";\nimport {stdMath} from \"./StdMath.sol\";\n\nabstract contract StdAssertions is DSTest {\n event log_array(uint256[] val);\n event log_array(int256[] val);\n event log_array(address[] val);\n event log_named_array(string key, uint256[] val);\n event log_named_array(string key, int256[] val);\n event log_named_array(string key, address[] val);\n\n function fail(string memory err) internal virtual {\n emit log_named_string(\"Error\", err);\n fail();\n }\n\n function assertFalse(bool data) internal virtual {\n assertTrue(!data);\n }\n\n function assertFalse(bool data, string memory err) internal virtual {\n assertTrue(!data, err);\n }\n\n function assertEq(bool a, bool b) internal virtual {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bool]\");\n emit log_named_string(\" Left\", a ? \"true\" : \"false\");\n emit log_named_string(\" Right\", b ? \"true\" : \"false\");\n fail();\n }\n }\n\n function assertEq(bool a, bool b, string memory err) internal virtual {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes memory a, bytes memory b) internal virtual {\n assertEq0(a, b);\n }\n\n function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual {\n assertEq0(a, b, err);\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [uint[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [int[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(address[] memory a, address[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [address[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n // Legacy helper\n function assertEqUint(uint256 a, uint256 b) internal virtual {\n assertEq(uint256(a), uint256(b));\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100%\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals,\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual {\n assertEqCall(target, callDataA, target, callDataB, true);\n }\n\n function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB)\n internal\n virtual\n {\n assertEqCall(targetA, callDataA, targetB, callDataB, true);\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData)\n internal\n virtual\n {\n assertEqCall(target, callDataA, target, callDataB, strictRevertData);\n }\n\n function assertEqCall(\n address targetA,\n bytes memory callDataA,\n address targetB,\n bytes memory callDataB,\n bool strictRevertData\n ) internal virtual {\n (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA);\n (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB);\n\n if (successA && successB) {\n assertEq(returnDataA, returnDataB, \"Call return data does not match\");\n }\n\n if (!successA && !successB && strictRevertData) {\n assertEq(returnDataA, returnDataB, \"Call revert data does not match\");\n }\n\n if (!successA && successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call revert data\", returnDataA);\n emit log_named_bytes(\" Right call return data\", returnDataB);\n fail();\n }\n\n if (successA && !successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call return data\", returnDataA);\n emit log_named_bytes(\" Right call revert data\", returnDataB);\n fail();\n }\n }\n}\n" - }, - "node_modules/forge-std/src/StdChains.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n/**\n * StdChains provides information about EVM compatible chains that can be used in scripts/tests.\n * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are\n * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of\n * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the\n * alias used in this contract, which can be found as the first argument to the\n * `setChainWithDefaultRpcUrl` call in the `initialize` function.\n *\n * There are two main ways to use this contract:\n * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or\n * `setChain(string memory chainAlias, Chain memory chain)`\n * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`.\n *\n * The first time either of those are used, chains are initialized with the default set of RPC URLs.\n * This is done in `initialize`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in\n * `defaultRpcUrls`.\n *\n * The `setChain` function is straightforward, and it simply saves off the given chain data.\n *\n * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say\n * we want to retrieve `mainnet`'s RPC URL:\n * - If you haven't set any mainnet chain info with `setChain`, you haven't specified that\n * chain in `foundry.toml` and no env var is set, the default data and RPC URL will be returned.\n * - If you have set a mainnet RPC URL in `foundry.toml` it will return that, if valid (e.g. if\n * a URL is given or if an environment variable is given and that environment variable exists).\n * Otherwise, the default data is returned.\n * - If you specified data with `setChain` it will return that.\n *\n * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.\n */\nabstract contract StdChains {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private initialized;\n\n struct ChainData {\n string name;\n uint256 chainId;\n string rpcUrl;\n }\n\n struct Chain {\n // The chain name.\n string name;\n // The chain's Chain ID.\n uint256 chainId;\n // The chain's alias. (i.e. what gets specified in `foundry.toml`).\n string chainAlias;\n // A default RPC endpoint for this chain.\n // NOTE: This default RPC URL is included for convenience to facilitate quick tests and\n // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy\n // usage as you will be throttled and this is a disservice to others who need this endpoint.\n string rpcUrl;\n }\n\n // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data.\n mapping(string => Chain) private chains;\n // Maps from the chain's alias to it's default RPC URL.\n mapping(string => string) private defaultRpcUrls;\n // Maps from a chain ID to it's alias.\n mapping(uint256 => string) private idToAlias;\n\n bool private fallbackToDefaultRpcUrls = true;\n\n // The RPC URL will be fetched from config or defaultRpcUrls if possible.\n function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) {\n require(bytes(chainAlias).length != 0, \"StdChains getChain(string): Chain alias cannot be the empty string.\");\n\n initialize();\n chain = chains[chainAlias];\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(string): Chain with alias \\\"\", chainAlias, \"\\\" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n function getChain(uint256 chainId) internal virtual returns (Chain memory chain) {\n require(chainId != 0, \"StdChains getChain(uint256): Chain ID cannot be 0.\");\n initialize();\n string memory chainAlias = idToAlias[chainId];\n\n chain = chains[chainAlias];\n\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(uint256): Chain with ID \", vm.toString(chainId), \" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, ChainData memory chain) internal virtual {\n require(\n bytes(chainAlias).length != 0,\n \"StdChains setChain(string,ChainData): Chain alias cannot be the empty string.\"\n );\n\n require(chain.chainId != 0, \"StdChains setChain(string,ChainData): Chain ID cannot be 0.\");\n\n initialize();\n string memory foundAlias = idToAlias[chain.chainId];\n\n require(\n bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)),\n string(\n abi.encodePacked(\n \"StdChains setChain(string,ChainData): Chain ID \",\n vm.toString(chain.chainId),\n \" already used by \\\"\",\n foundAlias,\n \"\\\".\"\n )\n )\n );\n\n uint256 oldChainId = chains[chainAlias].chainId;\n delete idToAlias[oldChainId];\n\n chains[chainAlias] =\n Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl});\n idToAlias[chain.chainId] = chainAlias;\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, Chain memory chain) internal virtual {\n setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl}));\n }\n\n function _toUpper(string memory str) private pure returns (string memory) {\n bytes memory strb = bytes(str);\n bytes memory copy = new bytes(strb.length);\n for (uint256 i = 0; i < strb.length; i++) {\n bytes1 b = strb[i];\n if (b >= 0x61 && b <= 0x7A) {\n copy[i] = bytes1(uint8(b) - 32);\n } else {\n copy[i] = b;\n }\n }\n return string(copy);\n }\n\n // lookup rpcUrl, in descending order of priority:\n // current -> config (foundry.toml) -> environment variable -> default\n function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) {\n if (bytes(chain.rpcUrl).length == 0) {\n try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) {\n chain.rpcUrl = configRpcUrl;\n } catch (bytes memory err) {\n string memory envName = string(abi.encodePacked(_toUpper(chainAlias), \"_RPC_URL\"));\n if (fallbackToDefaultRpcUrls) {\n chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]);\n } else {\n chain.rpcUrl = vm.envString(envName);\n }\n // distinguish 'not found' from 'cannot read'\n bytes memory notFoundError =\n abi.encodeWithSignature(\"CheatCodeError\", string(abi.encodePacked(\"invalid rpc url \", chainAlias)));\n if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, err), mload(err))\n }\n }\n }\n }\n return chain;\n }\n\n function setFallbackToDefaultRpcUrls(bool useDefault) internal {\n fallbackToDefaultRpcUrls = useDefault;\n }\n\n function initialize() private {\n if (initialized) return;\n\n initialized = true;\n\n // If adding an RPC here, make sure to test the default RPC URL in `testRpcs`\n setChainWithDefaultRpcUrl(\"anvil\", ChainData(\"Anvil\", 31337, \"http://127.0.0.1:8545\"));\n setChainWithDefaultRpcUrl(\n \"mainnet\", ChainData(\"Mainnet\", 1, \"https://mainnet.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"goerli\", ChainData(\"Goerli\", 5, \"https://goerli.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"sepolia\", ChainData(\"Sepolia\", 11155111, \"https://sepolia.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\"optimism\", ChainData(\"Optimism\", 10, \"https://mainnet.optimism.io\"));\n setChainWithDefaultRpcUrl(\"optimism_goerli\", ChainData(\"Optimism Goerli\", 420, \"https://goerli.optimism.io\"));\n setChainWithDefaultRpcUrl(\"arbitrum_one\", ChainData(\"Arbitrum One\", 42161, \"https://arb1.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\n \"arbitrum_one_goerli\", ChainData(\"Arbitrum One Goerli\", 421613, \"https://goerli-rollup.arbitrum.io/rpc\")\n );\n setChainWithDefaultRpcUrl(\"arbitrum_nova\", ChainData(\"Arbitrum Nova\", 42170, \"https://nova.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\"polygon\", ChainData(\"Polygon\", 137, \"https://polygon-rpc.com\"));\n setChainWithDefaultRpcUrl(\n \"polygon_mumbai\", ChainData(\"Polygon Mumbai\", 80001, \"https://rpc-mumbai.maticvigil.com\")\n );\n setChainWithDefaultRpcUrl(\"avalanche\", ChainData(\"Avalanche\", 43114, \"https://api.avax.network/ext/bc/C/rpc\"));\n setChainWithDefaultRpcUrl(\n \"avalanche_fuji\", ChainData(\"Avalanche Fuji\", 43113, \"https://api.avax-test.network/ext/bc/C/rpc\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain\", ChainData(\"BNB Smart Chain\", 56, \"https://bsc-dataseed1.binance.org\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain_testnet\",\n ChainData(\"BNB Smart Chain Testnet\", 97, \"https://rpc.ankr.com/bsc_testnet_chapel\")\n );\n setChainWithDefaultRpcUrl(\"gnosis_chain\", ChainData(\"Gnosis Chain\", 100, \"https://rpc.gnosischain.com\"));\n }\n\n // set chain info, with priority to chainAlias' rpc url in foundry.toml\n function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private {\n string memory rpcUrl = chain.rpcUrl;\n defaultRpcUrls[chainAlias] = rpcUrl;\n chain.rpcUrl = \"\";\n setChain(chainAlias, chain);\n chain.rpcUrl = rpcUrl; // restore argument\n }\n}\n" - }, - "node_modules/forge-std/src/StdCheats.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdCheatsSafe {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private gasMeteringOff;\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawTx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n // json value name = function\n string functionSig;\n bytes32 hash;\n // json value name = tx\n RawTx1559Detail txDetail;\n // json value name = type\n string opcode;\n }\n\n struct RawTx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n bytes gas;\n bytes nonce;\n address to;\n bytes txType;\n bytes value;\n }\n\n struct Tx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n bytes32 hash;\n Tx1559Detail txDetail;\n string opcode;\n }\n\n struct Tx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n uint256 gas;\n uint256 nonce;\n address to;\n uint256 txType;\n uint256 value;\n }\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct TxLegacy {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n string hash;\n string opcode;\n TxDetailLegacy transaction;\n }\n\n struct TxDetailLegacy {\n AccessList[] accessList;\n uint256 chainId;\n bytes data;\n address from;\n uint256 gas;\n uint256 gasPrice;\n bytes32 hash;\n uint256 nonce;\n bytes1 opcode;\n bytes32 r;\n bytes32 s;\n uint256 txType;\n address to;\n uint8 v;\n uint256 value;\n }\n\n struct AccessList {\n address accessAddress;\n bytes32[] storageKeys;\n }\n\n // Data structures to parse Receipt objects from the broadcast artifact.\n // The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawReceipt {\n bytes32 blockHash;\n bytes blockNumber;\n address contractAddress;\n bytes cumulativeGasUsed;\n bytes effectiveGasPrice;\n address from;\n bytes gasUsed;\n RawReceiptLog[] logs;\n bytes logsBloom;\n bytes status;\n address to;\n bytes32 transactionHash;\n bytes transactionIndex;\n }\n\n struct Receipt {\n bytes32 blockHash;\n uint256 blockNumber;\n address contractAddress;\n uint256 cumulativeGasUsed;\n uint256 effectiveGasPrice;\n address from;\n uint256 gasUsed;\n ReceiptLog[] logs;\n bytes logsBloom;\n uint256 status;\n address to;\n bytes32 transactionHash;\n uint256 transactionIndex;\n }\n\n // Data structures to parse the entire broadcast artifact, assuming the\n // transactions conform to EIP1559.\n\n struct EIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n Receipt[] receipts;\n uint256 timestamp;\n Tx1559[] transactions;\n TxReturn[] txReturns;\n }\n\n struct RawEIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n RawReceipt[] receipts;\n TxReturn[] txReturns;\n uint256 timestamp;\n RawTx1559[] transactions;\n }\n\n struct RawReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n bytes blockNumber;\n bytes data;\n bytes logIndex;\n bool removed;\n bytes32[] topics;\n bytes32 transactionHash;\n bytes transactionIndex;\n bytes transactionLogIndex;\n }\n\n struct ReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n uint256 blockNumber;\n bytes data;\n uint256 logIndex;\n bytes32[] topics;\n uint256 transactionIndex;\n uint256 transactionLogIndex;\n bool removed;\n }\n\n struct TxReturn {\n string internalType;\n string value;\n }\n\n function assumeNoPrecompiles(address addr) internal virtual {\n // Assembly required since `block.chainid` was introduced in 0.8.0.\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n assumeNoPrecompiles(addr, chainId);\n }\n\n function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual {\n // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific\n // address), but the same rationale for excluding them applies so we include those too.\n\n // These should be present on all EVM-compatible chains.\n vm.assume(addr < address(0x1) || addr > address(0x9));\n\n // forgefmt: disable-start\n if (chainId == 10 || chainId == 420) {\n // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21\n vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800));\n } else if (chainId == 42161 || chainId == 421613) {\n // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains\n vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068));\n } else if (chainId == 43114 || chainId == 43113) {\n // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59\n vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff));\n vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF));\n vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff));\n }\n // forgefmt: disable-end\n }\n\n function readEIP1559ScriptArtifact(string memory path)\n internal\n view\n virtual\n returns (EIP1559ScriptArtifact memory)\n {\n string memory data = vm.readFile(path);\n bytes memory parsedData = vm.parseJson(data);\n RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact));\n EIP1559ScriptArtifact memory artifact;\n artifact.libraries = rawArtifact.libraries;\n artifact.path = rawArtifact.path;\n artifact.timestamp = rawArtifact.timestamp;\n artifact.pending = rawArtifact.pending;\n artifact.txReturns = rawArtifact.txReturns;\n artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts);\n artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions);\n return artifact;\n }\n\n function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) {\n Tx1559[] memory txs = new Tx1559[](rawTxs.length);\n for (uint256 i; i < rawTxs.length; i++) {\n txs[i] = rawToConvertedEIPTx1559(rawTxs[i]);\n }\n return txs;\n }\n\n function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) {\n Tx1559 memory transaction;\n transaction.arguments = rawTx.arguments;\n transaction.contractName = rawTx.contractName;\n transaction.functionSig = rawTx.functionSig;\n transaction.hash = rawTx.hash;\n transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail);\n transaction.opcode = rawTx.opcode;\n return transaction;\n }\n\n function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail)\n internal\n pure\n virtual\n returns (Tx1559Detail memory)\n {\n Tx1559Detail memory txDetail;\n txDetail.data = rawDetail.data;\n txDetail.from = rawDetail.from;\n txDetail.to = rawDetail.to;\n txDetail.nonce = _bytesToUint(rawDetail.nonce);\n txDetail.txType = _bytesToUint(rawDetail.txType);\n txDetail.value = _bytesToUint(rawDetail.value);\n txDetail.gas = _bytesToUint(rawDetail.gas);\n txDetail.accessList = rawDetail.accessList;\n return txDetail;\n }\n\n function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".transactions\");\n RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[]));\n return rawToConvertedEIPTx1559s(rawTxs);\n }\n\n function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".transactions[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559));\n return rawToConvertedEIPTx1559(rawTx);\n }\n\n // Analogous to readTransactions, but for receipts.\n function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".receipts\");\n RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[]));\n return rawToConvertedReceipts(rawReceipts);\n }\n\n function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".receipts[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt));\n return rawToConvertedReceipt(rawReceipt);\n }\n\n function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) {\n Receipt[] memory receipts = new Receipt[](rawReceipts.length);\n for (uint256 i; i < rawReceipts.length; i++) {\n receipts[i] = rawToConvertedReceipt(rawReceipts[i]);\n }\n return receipts;\n }\n\n function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) {\n Receipt memory receipt;\n receipt.blockHash = rawReceipt.blockHash;\n receipt.to = rawReceipt.to;\n receipt.from = rawReceipt.from;\n receipt.contractAddress = rawReceipt.contractAddress;\n receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice);\n receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed);\n receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed);\n receipt.status = _bytesToUint(rawReceipt.status);\n receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex);\n receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber);\n receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs);\n receipt.logsBloom = rawReceipt.logsBloom;\n receipt.transactionHash = rawReceipt.transactionHash;\n return receipt;\n }\n\n function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs)\n internal\n pure\n virtual\n returns (ReceiptLog[] memory)\n {\n ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length);\n for (uint256 i; i < rawLogs.length; i++) {\n logs[i].logAddress = rawLogs[i].logAddress;\n logs[i].blockHash = rawLogs[i].blockHash;\n logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber);\n logs[i].data = rawLogs[i].data;\n logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex);\n logs[i].topics = rawLogs[i].topics;\n logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex);\n logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex);\n logs[i].removed = rawLogs[i].removed;\n }\n return logs;\n }\n\n // Deploy a contract by fetching the contract bytecode from\n // the artifacts directory\n // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))`\n function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes): Deployment failed.\");\n }\n\n function deployCode(string memory what) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string): Deployment failed.\");\n }\n\n /// @dev deploy contract with value on construction\n function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes,uint256): Deployment failed.\");\n }\n\n function deployCode(string memory what, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,uint256): Deployment failed.\");\n }\n\n // creates a labeled address and the corresponding private key\n function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) {\n privateKey = uint256(keccak256(abi.encodePacked(name)));\n addr = vm.addr(privateKey);\n vm.label(addr, name);\n }\n\n // creates a labeled address\n function makeAddr(string memory name) internal virtual returns (address addr) {\n (addr,) = makeAddrAndKey(name);\n }\n\n function deriveRememberKey(string memory mnemonic, uint32 index)\n internal\n virtual\n returns (address who, uint256 privateKey)\n {\n privateKey = vm.deriveKey(mnemonic, index);\n who = vm.rememberKey(privateKey);\n }\n\n function _bytesToUint(bytes memory b) private pure returns (uint256) {\n require(b.length <= 32, \"StdCheats _bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n function isFork() internal view virtual returns (bool status) {\n try vm.activeFork() {\n status = true;\n } catch (bytes memory) {}\n }\n\n modifier skipWhenForking() {\n if (!isFork()) {\n _;\n }\n }\n\n modifier skipWhenNotForking() {\n if (isFork()) {\n _;\n }\n }\n\n modifier noGasMetering() {\n vm.pauseGasMetering();\n // To prevent turning gas monitoring back on with nested functions that use this modifier,\n // we check if gasMetering started in the off position. If it did, we don't want to turn\n // it back on until we exit the top level function that used the modifier\n //\n // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well.\n // funcA will have `gasStartedOff` as false, funcB will have it as true,\n // so we only turn metering back on at the end of the funcA\n bool gasStartedOff = gasMeteringOff;\n gasMeteringOff = true;\n\n _;\n\n // if gas metering was on when this modifier was called, turn it back on at the end\n if (!gasStartedOff) {\n gasMeteringOff = false;\n vm.resumeGasMetering();\n }\n }\n\n // a cheat for fuzzing addresses that are payable only\n // see https://github.com/foundry-rs/foundry/issues/3631\n function assumePayable(address addr) internal virtual {\n (bool success,) = payable(addr).call{value: 0}(\"\");\n vm.assume(success);\n }\n}\n\n// Wrappers around cheatcodes to avoid footguns\nabstract contract StdCheats is StdCheatsSafe {\n using stdStorage for StdStorage;\n\n StdStorage private stdstore;\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n // Skip forward or rewind time by the specified number of seconds\n function skip(uint256 time) internal virtual {\n vm.warp(block.timestamp + time);\n }\n\n function rewind(uint256 time) internal virtual {\n vm.warp(block.timestamp - time);\n }\n\n // Setup a prank from an address that has some ether\n function hoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender, origin);\n }\n\n function hoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender, origin);\n }\n\n // Start perpetual prank from an address that has some ether\n function startHoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender);\n }\n\n function startHoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender);\n }\n\n // Start perpetual prank from an address that has some ether\n // tx.origin is set to the origin parameter\n function startHoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender, origin);\n }\n\n function startHoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender, origin);\n }\n\n function changePrank(address msgSender) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender);\n }\n\n function changePrank(address msgSender, address txOrigin) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender, txOrigin);\n }\n\n // The same as Vm's `deal`\n // Use the alternative signature for ERC20 tokens\n function deal(address to, uint256 give) internal virtual {\n vm.deal(to, give);\n }\n\n // Set the balance of an account for any ERC20 token\n // Use the alternative signature to update `totalSupply`\n function deal(address token, address to, uint256 give) internal virtual {\n deal(token, to, give, false);\n }\n\n // Set the balance of an account for any ERC1155 token\n // Use the alternative signature to update `totalSupply`\n function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual {\n dealERC1155(token, to, id, give, false);\n }\n\n function deal(address token, address to, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd));\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0x18160ddd).checked_write(totSup);\n }\n }\n\n function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x00fdd58e, to, id));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0xbd85b039, id));\n require(\n totSupData.length != 0,\n \"StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply.\"\n );\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup);\n }\n }\n\n function dealERC721(address token, address to, uint256 id) internal virtual {\n // check if token id is already minted and the actual owner.\n (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id));\n require(successMinted, \"StdCheats deal(address,address,uint,bool): id not minted.\");\n\n // get owner current balance\n (, bytes memory fromBalData) = token.call(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address))));\n uint256 fromPrevBal = abi.decode(fromBalData, (uint256));\n\n // get new user current balance\n (, bytes memory toBalData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 toPrevBal = abi.decode(toBalData, (uint256));\n\n // update balances\n stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal);\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal);\n\n // update owner\n stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to);\n }\n}\n" - }, - "node_modules/forge-std/src/StdError.sol": { - "content": "// SPDX-License-Identifier: MIT\n// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdError {\n bytes public constant assertionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x01);\n bytes public constant arithmeticError = abi.encodeWithSignature(\"Panic(uint256)\", 0x11);\n bytes public constant divisionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x12);\n bytes public constant enumConversionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x21);\n bytes public constant encodeStorageError = abi.encodeWithSignature(\"Panic(uint256)\", 0x22);\n bytes public constant popError = abi.encodeWithSignature(\"Panic(uint256)\", 0x31);\n bytes public constant indexOOBError = abi.encodeWithSignature(\"Panic(uint256)\", 0x32);\n bytes public constant memOverflowError = abi.encodeWithSignature(\"Panic(uint256)\", 0x41);\n bytes public constant zeroVarError = abi.encodeWithSignature(\"Panic(uint256)\", 0x51);\n}\n" - }, - "node_modules/forge-std/src/StdInvariant.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ncontract StdInvariant {\n struct FuzzSelector {\n address addr;\n bytes4[] selectors;\n }\n\n address[] private _excludedContracts;\n address[] private _excludedSenders;\n address[] private _targetedContracts;\n address[] private _targetedSenders;\n\n string[] private _excludedArtifacts;\n string[] private _targetedArtifacts;\n\n FuzzSelector[] private _targetedArtifactSelectors;\n FuzzSelector[] private _targetedSelectors;\n\n // Functions for users:\n // These are intended to be called in tests.\n\n function excludeContract(address newExcludedContract_) internal {\n _excludedContracts.push(newExcludedContract_);\n }\n\n function excludeSender(address newExcludedSender_) internal {\n _excludedSenders.push(newExcludedSender_);\n }\n\n function excludeArtifact(string memory newExcludedArtifact_) internal {\n _excludedArtifacts.push(newExcludedArtifact_);\n }\n\n function targetArtifact(string memory newTargetedArtifact_) internal {\n _targetedArtifacts.push(newTargetedArtifact_);\n }\n\n function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal {\n _targetedArtifactSelectors.push(newTargetedArtifactSelector_);\n }\n\n function targetContract(address newTargetedContract_) internal {\n _targetedContracts.push(newTargetedContract_);\n }\n\n function targetSelector(FuzzSelector memory newTargetedSelector_) internal {\n _targetedSelectors.push(newTargetedSelector_);\n }\n\n function targetSender(address newTargetedSender_) internal {\n _targetedSenders.push(newTargetedSender_);\n }\n\n // Functions for forge:\n // These are called by forge to run invariant tests and don't need to be called in tests.\n\n function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) {\n excludedArtifacts_ = _excludedArtifacts;\n }\n\n function excludeContracts() public view returns (address[] memory excludedContracts_) {\n excludedContracts_ = _excludedContracts;\n }\n\n function excludeSenders() public view returns (address[] memory excludedSenders_) {\n excludedSenders_ = _excludedSenders;\n }\n\n function targetArtifacts() public view returns (string[] memory targetedArtifacts_) {\n targetedArtifacts_ = _targetedArtifacts;\n }\n\n function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) {\n targetedArtifactSelectors_ = _targetedArtifactSelectors;\n }\n\n function targetContracts() public view returns (address[] memory targetedContracts_) {\n targetedContracts_ = _targetedContracts;\n }\n\n function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) {\n targetedSelectors_ = _targetedSelectors;\n }\n\n function targetSenders() public view returns (address[] memory targetedSenders_) {\n targetedSenders_ = _targetedSenders;\n }\n}\n" - }, - "node_modules/forge-std/src/StdJson.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing JSON files\n// To parse:\n// ```\n// using stdJson for string;\n// string memory json = vm.readFile(\"some_peth\");\n// json.parseUint(\"\");\n// ```\n// To write:\n// ```\n// using stdJson for string;\n// string memory json = \"deploymentArtifact\";\n// Contract contract = new Contract();\n// json.serialize(\"contractAddress\", address(contract));\n// json = json.serialize(\"deploymentTimes\", uint(1));\n// // store the stringified JSON to the 'json' variable we have been using as a key\n// // as we won't need it any longer\n// string memory json2 = \"finalArtifact\";\n// string memory final = json2.serialize(\"depArtifact\", json);\n// final.write(\"\");\n// ```\n\nlibrary stdJson {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJson(json, key);\n }\n\n function readUint(string memory json, string memory key) internal returns (uint256) {\n return vm.parseJsonUint(json, key);\n }\n\n function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) {\n return vm.parseJsonUintArray(json, key);\n }\n\n function readInt(string memory json, string memory key) internal returns (int256) {\n return vm.parseJsonInt(json, key);\n }\n\n function readIntArray(string memory json, string memory key) internal returns (int256[] memory) {\n return vm.parseJsonIntArray(json, key);\n }\n\n function readBytes32(string memory json, string memory key) internal returns (bytes32) {\n return vm.parseJsonBytes32(json, key);\n }\n\n function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) {\n return vm.parseJsonBytes32Array(json, key);\n }\n\n function readString(string memory json, string memory key) internal returns (string memory) {\n return vm.parseJsonString(json, key);\n }\n\n function readStringArray(string memory json, string memory key) internal returns (string[] memory) {\n return vm.parseJsonStringArray(json, key);\n }\n\n function readAddress(string memory json, string memory key) internal returns (address) {\n return vm.parseJsonAddress(json, key);\n }\n\n function readAddressArray(string memory json, string memory key) internal returns (address[] memory) {\n return vm.parseJsonAddressArray(json, key);\n }\n\n function readBool(string memory json, string memory key) internal returns (bool) {\n return vm.parseJsonBool(json, key);\n }\n\n function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) {\n return vm.parseJsonBoolArray(json, key);\n }\n\n function readBytes(string memory json, string memory key) internal returns (bytes memory) {\n return vm.parseJsonBytes(json, key);\n }\n\n function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) {\n return vm.parseJsonBytesArray(json, key);\n }\n\n function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bool[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function write(string memory jsonKey, string memory path) internal {\n vm.writeJson(jsonKey, path);\n }\n\n function write(string memory jsonKey, string memory path, string memory valueKey) internal {\n vm.writeJson(jsonKey, path, valueKey);\n }\n}\n" - }, - "node_modules/forge-std/src/StdMath.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdMath {\n int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n function abs(int256 a) internal pure returns (uint256) {\n // Required or it will fail when `a = type(int256).min`\n if (a == INT256_MIN) {\n return 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n }\n\n return uint256(a > 0 ? a : -a);\n }\n\n function delta(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a - b : b - a;\n }\n\n function delta(int256 a, int256 b) internal pure returns (uint256) {\n // a and b are of the same sign\n // this works thanks to two's complement, the left-most bit is the sign bit\n if ((a ^ b) > -1) {\n return delta(abs(a), abs(b));\n }\n\n // a and b are of opposite signs\n return abs(a) + abs(b);\n }\n\n function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n\n return absDelta * 1e18 / b;\n }\n\n function percentDelta(int256 a, int256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n uint256 absB = abs(b);\n\n return absDelta * 1e18 / absB;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nstruct StdStorage {\n mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots;\n mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds;\n bytes32[] _keys;\n bytes4 _sig;\n uint256 _depth;\n address _target;\n bytes32 _set;\n}\n\nlibrary stdStorageSafe {\n event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot);\n event WARNING_UninitedSlot(address who, uint256 slot);\n\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return bytes4(keccak256(bytes(sigStr)));\n }\n\n /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against\n // slot complexity:\n // if flat, will be bytes32(uint256(uint));\n // if map, will be keccak256(abi.encode(key, uint(slot)));\n // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));\n // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);\n function find(StdStorage storage self) internal returns (uint256) {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n // calldata to test against\n if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n vm.record();\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n (bytes32[] memory reads,) = vm.accesses(address(who));\n if (reads.length == 1) {\n bytes32 curr = vm.load(who, reads[0]);\n if (curr == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[0]));\n }\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n } else if (reads.length > 1) {\n for (uint256 i = 0; i < reads.length; i++) {\n bytes32 prev = vm.load(who, reads[i]);\n if (prev == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[i]));\n }\n // store\n vm.store(who, reads[i], bytes32(hex\"1337\"));\n bool success;\n bytes memory rdat;\n {\n (success, rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n if (success && fdat == bytes32(hex\"1337\")) {\n // we found which of the slots is the actual one\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n vm.store(who, reads[i], prev);\n break;\n }\n vm.store(who, reads[i], prev);\n }\n } else {\n revert(\"stdStorage find(StdStorage): No storage use detected for target.\");\n }\n\n require(\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))],\n \"stdStorage find(StdStorage): Slot(s) not found.\"\n );\n\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n self._target = _target;\n return self;\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n self._sig = _sig;\n return self;\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n self._sig = sigs(_sig);\n return self;\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n self._keys.push(bytes32(uint256(uint160(who))));\n return self;\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n self._keys.push(bytes32(amt));\n return self;\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n self._keys.push(key);\n return self;\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n self._depth = _depth;\n return self;\n }\n\n function read(StdStorage storage self) private returns (bytes memory) {\n address t = self._target;\n uint256 s = find(self);\n return abi.encode(vm.load(t, bytes32(s)));\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return abi.decode(read(self), (bytes32));\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n int256 v = read_int(self);\n if (v == 0) return false;\n if (v == 1) return true;\n revert(\"stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool.\");\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return abi.decode(read(self), (address));\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return abi.decode(read(self), (uint256));\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return abi.decode(read(self), (int256));\n }\n\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n\nlibrary stdStorage {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return stdStorageSafe.sigs(sigStr);\n }\n\n function find(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.find(self);\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n return stdStorageSafe.target(self, _target);\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, who);\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, amt);\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, key);\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n return stdStorageSafe.depth(self, _depth);\n }\n\n function checked_write(StdStorage storage self, address who) internal {\n checked_write(self, bytes32(uint256(uint160(who))));\n }\n\n function checked_write(StdStorage storage self, uint256 amt) internal {\n checked_write(self, bytes32(amt));\n }\n\n function checked_write(StdStorage storage self, bool write) internal {\n bytes32 t;\n /// @solidity memory-safe-assembly\n assembly {\n t := write\n }\n checked_write(self, t);\n }\n\n function checked_write(StdStorage storage self, bytes32 set) internal {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n find(self);\n }\n bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]);\n\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n bytes32 curr = vm.load(who, slot);\n\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n vm.store(who, slot, set);\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return stdStorageSafe.read_bytes32(self);\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n return stdStorageSafe.read_bool(self);\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return stdStorageSafe.read_address(self);\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.read_uint(self);\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return stdStorageSafe.read_int(self);\n }\n\n // Private function so needs to be copied over\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n // Private function so needs to be copied over\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStyle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nlibrary StdStyle {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n string constant RED = \"\\u001b[91m\";\n string constant GREEN = \"\\u001b[92m\";\n string constant YELLOW = \"\\u001b[93m\";\n string constant BLUE = \"\\u001b[94m\";\n string constant MAGENTA = \"\\u001b[95m\";\n string constant CYAN = \"\\u001b[96m\";\n string constant BOLD = \"\\u001b[1m\";\n string constant DIM = \"\\u001b[2m\";\n string constant ITALIC = \"\\u001b[3m\";\n string constant UNDERLINE = \"\\u001b[4m\";\n string constant INVERSE = \"\\u001b[7m\";\n string constant RESET = \"\\u001b[0m\";\n\n function styleConcat(string memory style, string memory self) private pure returns (string memory) {\n return string(abi.encodePacked(style, self, RESET));\n }\n\n function red(string memory self) internal pure returns (string memory) {\n return styleConcat(RED, self);\n }\n\n function red(uint256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(int256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(address self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(bool self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes(bytes memory self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes32(bytes32 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function green(string memory self) internal pure returns (string memory) {\n return styleConcat(GREEN, self);\n }\n\n function green(uint256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(int256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(address self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(bool self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes(bytes memory self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes32(bytes32 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function yellow(string memory self) internal pure returns (string memory) {\n return styleConcat(YELLOW, self);\n }\n\n function yellow(uint256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(int256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(address self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(bool self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes(bytes memory self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes32(bytes32 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function blue(string memory self) internal pure returns (string memory) {\n return styleConcat(BLUE, self);\n }\n\n function blue(uint256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(int256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(address self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(bool self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes(bytes memory self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes32(bytes32 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function magenta(string memory self) internal pure returns (string memory) {\n return styleConcat(MAGENTA, self);\n }\n\n function magenta(uint256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(int256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(address self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(bool self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes(bytes memory self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes32(bytes32 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function cyan(string memory self) internal pure returns (string memory) {\n return styleConcat(CYAN, self);\n }\n\n function cyan(uint256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(int256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(address self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(bool self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes(bytes memory self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes32(bytes32 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function bold(string memory self) internal pure returns (string memory) {\n return styleConcat(BOLD, self);\n }\n\n function bold(uint256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(int256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(address self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(bool self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes(bytes memory self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes32(bytes32 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function dim(string memory self) internal pure returns (string memory) {\n return styleConcat(DIM, self);\n }\n\n function dim(uint256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(int256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(address self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(bool self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes(bytes memory self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes32(bytes32 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function italic(string memory self) internal pure returns (string memory) {\n return styleConcat(ITALIC, self);\n }\n\n function italic(uint256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(int256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(address self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(bool self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes(bytes memory self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes32(bytes32 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function underline(string memory self) internal pure returns (string memory) {\n return styleConcat(UNDERLINE, self);\n }\n\n function underline(uint256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(int256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(address self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(bool self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes(bytes memory self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes32(bytes32 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function inverse(string memory self) internal pure returns (string memory) {\n return styleConcat(INVERSE, self);\n }\n\n function inverse(uint256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(int256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(address self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(bool self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes(bytes memory self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes32(bytes32 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n}\n" - }, - "node_modules/forge-std/src/StdUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {IMulticall3} from \"./interfaces/IMulticall3.sol\";\n// TODO Remove import.\nimport {VmSafe} from \"./Vm.sol\";\n\nabstract contract StdUtils {\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n //////////////////////////////////////////////////////////////////////////*/\n\n IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;\n uint256 private constant INT256_MIN_ABS =\n 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n /*//////////////////////////////////////////////////////////////////////////\n INTERNAL FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n require(min <= max, \"StdUtils bound(uint256,uint256,uint256): Max is less than min.\");\n // If x is between min and max, return x directly. This is to ensure that dictionary values\n // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188\n if (x >= min && x <= max) return x;\n\n uint256 size = max - min + 1;\n\n // If the value is 0, 1, 2, 3, warp that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side.\n // This helps ensure coverage of the min/max values.\n if (x <= 3 && size > x) return min + x;\n if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x);\n\n // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.\n if (x > max) {\n uint256 diff = x - max;\n uint256 rem = diff % size;\n if (rem == 0) return max;\n result = min + rem - 1;\n } else if (x < min) {\n uint256 diff = min - x;\n uint256 rem = diff % size;\n if (rem == 0) return min;\n result = max - rem + 1;\n }\n }\n\n function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) {\n result = _bound(x, min, max);\n console2_log(\"Bound Result\", result);\n }\n\n function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) {\n require(min <= max, \"StdUtils bound(int256,int256,int256): Max is less than min.\");\n\n // Shifting all int256 values to uint256 to use _bound function. The range of two types are:\n // int256 : -(2**255) ~ (2**255 - 1)\n // uint256: 0 ~ (2**256 - 1)\n // So, add 2**255, INT256_MIN_ABS to the integer values.\n //\n // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow.\n // So, use `~uint256(x) + 1` instead.\n uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS);\n uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS);\n uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS);\n\n uint256 y = _bound(_x, _min, _max);\n\n // To move it back to int256 value, subtract INT256_MIN_ABS at here.\n result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS);\n console2_log(\"Bound result\", vm.toString(result));\n }\n\n function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {\n require(b.length <= 32, \"StdUtils bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce\n /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol)\n function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) {\n // forgefmt: disable-start\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))));\n if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))));\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce))));\n if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce))));\n if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce))));\n // forgefmt: disable-end\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return addressFromLast20Bytes(\n keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce)))\n );\n }\n\n function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer)\n internal\n pure\n virtual\n returns (address)\n {\n return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash)));\n }\n\n /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer\n function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) {\n return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY);\n }\n\n /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) {\n return hashInitCode(creationCode, \"\");\n }\n\n /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n /// @param args the ABI-encoded arguments to the constructor of C\n function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(creationCode, args));\n }\n\n // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses.\n function getTokenBalances(address token, address[] memory addresses)\n internal\n virtual\n returns (uint256[] memory balances)\n {\n uint256 tokenCodeSize;\n assembly {\n tokenCodeSize := extcodesize(token)\n }\n require(tokenCodeSize > 0, \"StdUtils getTokenBalances(address,address[]): Token address is not a contract.\");\n\n // ABI encode the aggregate call to Multicall3.\n uint256 length = addresses.length;\n IMulticall3.Call[] memory calls = new IMulticall3.Call[](length);\n for (uint256 i = 0; i < length; ++i) {\n // 0x70a08231 = bytes4(\"balanceOf(address)\"))\n calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))});\n }\n\n // Make the aggregate call.\n (, bytes[] memory returnData) = multicall.aggregate(calls);\n\n // ABI decode the return data and return the balances.\n balances = new uint256[](length);\n for (uint256 i = 0; i < length; ++i) {\n balances[i] = abi.decode(returnData[i], (uint256));\n }\n }\n\n /*//////////////////////////////////////////////////////////////////////////\n PRIVATE FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere.\n\n function console2_log(string memory p0, uint256 p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n status;\n }\n\n function console2_log(string memory p0, string memory p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n status;\n }\n}\n" - }, - "node_modules/forge-std/src/Test.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// 💬 ABOUT\n// Standard Library's default Test\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {StdAssertions} from \"./StdAssertions.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheats} from \"./StdCheats.sol\";\nimport {stdError} from \"./StdError.sol\";\nimport {StdInvariant} from \"./StdInvariant.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {Vm} from \"./Vm.sol\";\nimport {StdStyle} from \"./StdStyle.sol\";\n\n// 📦 BOILERPLATE\nimport {TestBase} from \"./Base.sol\";\nimport {DSTest} from \"ds-test/test.sol\";\n\n// ⭐️ TEST\nabstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase {\n// Note: IS_TEST() must return true.\n// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76.\n}\n" - }, - "node_modules/forge-std/src/Vm.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// Cheatcodes are marked as view/pure/none using the following rules:\n// 0. A call's observable behaviour includes its return value, logs, reverts and state writes,\n// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc),\n// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`,\n// 3. Otherwise you're `pure`.\n\ninterface VmSafe {\n struct Log {\n bytes32[] topics;\n bytes data;\n address emitter;\n }\n\n struct Rpc {\n string key;\n string url;\n }\n\n struct FsMetadata {\n bool isDir;\n bool isSymlink;\n uint256 length;\n bool readOnly;\n uint256 modified;\n uint256 accessed;\n uint256 created;\n }\n\n // Loads a storage slot from an address\n function load(address target, bytes32 slot) external view returns (bytes32 data);\n // Signs data\n function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);\n // Gets the address for a given private key\n function addr(uint256 privateKey) external pure returns (address keyAddr);\n // Gets the nonce of an account\n function getNonce(address account) external view returns (uint64 nonce);\n // Performs a foreign function call via the terminal\n function ffi(string[] calldata commandInput) external returns (bytes memory result);\n // Sets environment variables\n function setEnv(string calldata name, string calldata value) external;\n // Reads environment variables, (name) => (value)\n function envBool(string calldata name) external view returns (bool value);\n function envUint(string calldata name) external view returns (uint256 value);\n function envInt(string calldata name) external view returns (int256 value);\n function envAddress(string calldata name) external view returns (address value);\n function envBytes32(string calldata name) external view returns (bytes32 value);\n function envString(string calldata name) external view returns (string memory value);\n function envBytes(string calldata name) external view returns (bytes memory value);\n // Reads environment variables as arrays\n function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value);\n function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value);\n function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value);\n function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);\n function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value);\n function envString(string calldata name, string calldata delim) external view returns (string[] memory value);\n function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value);\n // Read environment variables with default value\n function envOr(string calldata name, bool defaultValue) external returns (bool value);\n function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value);\n function envOr(string calldata name, int256 defaultValue) external returns (int256 value);\n function envOr(string calldata name, address defaultValue) external returns (address value);\n function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value);\n function envOr(string calldata name, string calldata defaultValue) external returns (string memory value);\n function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value);\n // Read environment variables as arrays with default value\n function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue)\n external\n returns (bool[] memory value);\n function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue)\n external\n returns (uint256[] memory value);\n function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue)\n external\n returns (int256[] memory value);\n function envOr(string calldata name, string calldata delim, address[] calldata defaultValue)\n external\n returns (address[] memory value);\n function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue)\n external\n returns (bytes32[] memory value);\n function envOr(string calldata name, string calldata delim, string[] calldata defaultValue)\n external\n returns (string[] memory value);\n function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue)\n external\n returns (bytes[] memory value);\n // Records all storage reads and writes\n function record() external;\n // Gets all accessed reads and write slot from a recording session, for a given address\n function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots);\n // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file\n function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode);\n // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file\n function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode);\n // Labels an address in call traces\n function label(address account, string calldata newLabel) external;\n // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain\n function broadcast() external;\n // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain\n function broadcast(address signer) external;\n // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain\n function broadcast(uint256 privateKey) external;\n // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain\n function startBroadcast() external;\n // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain\n function startBroadcast(address signer) external;\n // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain\n function startBroadcast(uint256 privateKey) external;\n // Stops collecting onchain transactions\n function stopBroadcast() external;\n // Reads the entire content of file to string\n function readFile(string calldata path) external view returns (string memory data);\n // Reads the entire content of file as binary. Path is relative to the project root.\n function readFileBinary(string calldata path) external view returns (bytes memory data);\n // Get the path of the current project root\n function projectRoot() external view returns (string memory path);\n // Get the metadata for a file/directory\n function fsMetadata(string calldata fileOrDir) external returns (FsMetadata memory metadata);\n // Reads next line of file to string\n function readLine(string calldata path) external view returns (string memory line);\n // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does.\n function writeFile(string calldata path, string calldata data) external;\n // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does.\n // Path is relative to the project root.\n function writeFileBinary(string calldata path, bytes calldata data) external;\n // Writes line to file, creating a file if it does not exist.\n function writeLine(string calldata path, string calldata data) external;\n // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine.\n function closeFile(string calldata path) external;\n // Removes file. This cheatcode will revert in the following situations, but is not limited to just these cases:\n // - Path points to a directory.\n // - The file doesn't exist.\n // - The user lacks permissions to remove the file.\n function removeFile(string calldata path) external;\n // Convert values to a string\n function toString(address value) external pure returns (string memory stringifiedValue);\n function toString(bytes calldata value) external pure returns (string memory stringifiedValue);\n function toString(bytes32 value) external pure returns (string memory stringifiedValue);\n function toString(bool value) external pure returns (string memory stringifiedValue);\n function toString(uint256 value) external pure returns (string memory stringifiedValue);\n function toString(int256 value) external pure returns (string memory stringifiedValue);\n // Convert values from a string\n function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue);\n function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue);\n function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue);\n function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue);\n function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue);\n function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue);\n // Record all the transaction logs\n function recordLogs() external;\n // Gets all the recorded logs\n function getRecordedLogs() external returns (Log[] memory logs);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index}\n function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index}\n function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index)\n external\n pure\n returns (uint256 privateKey);\n // Adds a private key to the local forge wallet and returns the address\n function rememberKey(uint256 privateKey) external returns (address keyAddr);\n //\n // parseJson\n //\n // ----\n // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects\n // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in\n // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that\n // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded\n // as tuples, with the attributes in the order in which they are defined.\n // For example: json = { 'a': 1, 'b': 0xa4tb......3xs}\n // a: uint256\n // b: address\n // To decode that json, we need to define a struct or a tuple as follows:\n // struct json = { uint256 a; address b; }\n // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to\n // decode the tuple in that order, and thus fail.\n // ----\n // Given a string of JSON, return it as ABI-encoded\n function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData);\n function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData);\n\n // The following parseJson cheatcodes will do type coercion, for the type that they indicate.\n // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12'\n // and hex numbers '0xEF'.\n // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not\n // a JSON object.\n function parseJsonUint(string calldata, string calldata) external returns (uint256);\n function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory);\n function parseJsonInt(string calldata, string calldata) external returns (int256);\n function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory);\n function parseJsonBool(string calldata, string calldata) external returns (bool);\n function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory);\n function parseJsonAddress(string calldata, string calldata) external returns (address);\n function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory);\n function parseJsonString(string calldata, string calldata) external returns (string memory);\n function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory);\n function parseJsonBytes(string calldata, string calldata) external returns (bytes memory);\n function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory);\n function parseJsonBytes32(string calldata, string calldata) external returns (bytes32);\n function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory);\n\n // Serialize a key and value to a JSON object stored in-memory that can be later written to a file\n // It returns the stringified version of the specific JSON file up to that moment.\n function serializeBool(string calldata objectKey, string calldata valueKey, bool value)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256 value)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address value)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string calldata value)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value)\n external\n returns (string memory json);\n\n function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values)\n external\n returns (string memory json);\n\n //\n // writeJson\n //\n // ----\n // Write a serialized JSON object to a file. If the file exists, it will be overwritten.\n // Let's assume we want to write the following JSON to a file:\n //\n // { \"boolean\": true, \"number\": 342, \"object\": { \"title\": \"finally json serialization\" } }\n //\n // ```\n // string memory json1 = \"some key\";\n // vm.serializeBool(json1, \"boolean\", true);\n // vm.serializeBool(json1, \"number\", uint256(342));\n // json2 = \"some other key\";\n // string memory output = vm.serializeString(json2, \"title\", \"finally json serialization\");\n // string memory finalJson = vm.serialize(json1, \"object\", output);\n // vm.writeJson(finalJson, \"./output/example.json\");\n // ```\n // The critical insight is that every invocation of serialization will return the stringified version of the JSON\n // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version\n // to serialize them as values to another JSON object.\n //\n // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..)\n // will find the object in-memory that is keyed by \"some key\".\n function writeJson(string calldata json, string calldata path) external;\n // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = \n // This is useful to replace a specific value of a JSON file, without having to parse the entire thing\n function writeJson(string calldata json, string calldata path, string calldata valueKey) external;\n // Returns the RPC url for the given alias\n function rpcUrl(string calldata rpcAlias) external view returns (string memory json);\n // Returns all rpc urls and their aliases `[alias, url][]`\n function rpcUrls() external view returns (string[2][] memory urls);\n // Returns all rpc urls and their aliases as structs.\n function rpcUrlStructs() external view returns (Rpc[] memory urls);\n // If the condition is false, discard this run's fuzz inputs and generate new ones.\n function assume(bool condition) external pure;\n // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused.\n function pauseGasMetering() external;\n // Resumes gas metering (i.e. gas usage is counted again). Noop if already on.\n function resumeGasMetering() external;\n}\n\ninterface Vm is VmSafe {\n // Sets block.timestamp\n function warp(uint256 newTimestamp) external;\n // Sets block.height\n function roll(uint256 newHeight) external;\n // Sets block.basefee\n function fee(uint256 newBasefee) external;\n // Sets block.difficulty\n function difficulty(uint256 newDifficulty) external;\n // Sets block.chainid\n function chainId(uint256 newChainId) external;\n // Stores a value to an address' storage slot.\n function store(address target, bytes32 slot, bytes32 value) external;\n // Sets the nonce of an account; must be higher than the current nonce of the account\n function setNonce(address account, uint64 newNonce) external;\n // Sets the *next* call's msg.sender to be the input address\n function prank(address msgSender) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called\n function startPrank(address msgSender) external;\n // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input\n function prank(address msgSender, address txOrigin) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input\n function startPrank(address msgSender, address txOrigin) external;\n // Resets subsequent calls' msg.sender to be `address(this)`\n function stopPrank() external;\n // Sets an address' balance\n function deal(address account, uint256 newBalance) external;\n // Sets an address' code\n function etch(address target, bytes calldata newRuntimeBytecode) external;\n // Expects an error on next call\n function expectRevert(bytes calldata revertData) external;\n function expectRevert(bytes4 revertData) external;\n function expectRevert() external;\n\n // Prepare an expected log with all four checks enabled.\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data.\n // Second form also checks supplied address against emitting contract.\n function expectEmit() external;\n function expectEmit(address emitter) external;\n\n // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData).\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data (as specified by the booleans).\n // Second form also checks supplied address against emitting contract.\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external;\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter)\n external;\n\n // Mocks a call to an address, returning specified data.\n // Calldata can either be strict or a partial match, e.g. if you only\n // pass a Solidity selector to the expected calldata, then the entire Solidity\n // function will be mocked.\n function mockCall(address callee, bytes calldata data, bytes calldata returnData) external;\n // Mocks a call to an address with a specific msg.value, returning specified data.\n // Calldata match takes precedence over msg.value in case of ambiguity.\n function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external;\n // Clears all mocked calls\n function clearMockedCalls() external;\n // Expects a call to an address with the specified calldata.\n // Calldata can either be a strict or a partial match\n function expectCall(address callee, bytes calldata data) external;\n // Expects a call to an address with the specified msg.value and calldata\n function expectCall(address callee, uint256 msgValue, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value, gas, and calldata.\n function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas.\n function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other\n // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set.\n function expectSafeMemory(uint64 min, uint64 max) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext.\n // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges\n // to the set.\n function expectSafeMemoryCall(uint64 min, uint64 max) external;\n // Sets block.coinbase\n function coinbase(address newCoinbase) external;\n // Snapshot the current state of the evm.\n // Returns the id of the snapshot that was created.\n // To revert a snapshot use `revertTo`\n function snapshot() external returns (uint256 snapshotId);\n // Revert the state of the EVM to a previous snapshot\n // Takes the snapshot id to revert to.\n // This deletes the snapshot and all snapshots taken after the given snapshot id.\n function revertTo(uint256 snapshotId) external returns (bool success);\n // Creates a new fork with the given endpoint and block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction,\n // and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before\n // the transaction, returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active.\n function selectFork(uint256 forkId) external;\n /// Returns the identifier of the currently active fork. Reverts if no fork is currently active.\n function activeFork() external view returns (uint256 forkId);\n // Updates the currently active fork to given block number\n // This is similar to `roll` but for the currently active fork\n function rollFork(uint256 blockNumber) external;\n // Updates the currently active fork to given transaction\n // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block\n function rollFork(bytes32 txHash) external;\n // Updates the given fork to given block number\n function rollFork(uint256 forkId, uint256 blockNumber) external;\n // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block\n function rollFork(uint256 forkId, bytes32 txHash) external;\n // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup\n // Meaning, changes made to the state of this account will be kept when switching forks\n function makePersistent(address account) external;\n function makePersistent(address account0, address account1) external;\n function makePersistent(address account0, address account1, address account2) external;\n function makePersistent(address[] calldata accounts) external;\n // Revokes persistent status from the address, previously added via `makePersistent`\n function revokePersistent(address account) external;\n function revokePersistent(address[] calldata accounts) external;\n // Returns true if the account is marked as persistent\n function isPersistent(address account) external view returns (bool persistent);\n // In forking mode, explicitly grant the given address cheatcode access\n function allowCheatcodes(address account) external;\n // Fetches the given transaction from the active fork and executes it on the current state\n function transact(bytes32 txHash) external;\n // Fetches the given transaction from the given fork and executes it on the current state\n function transact(uint256 forkId, bytes32 txHash) external;\n}\n" - }, - "node_modules/forge-std/src/console.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n }\n\n function logUint(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n }\n\n function log(uint p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n }\n\n function log(uint p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n }\n\n function log(uint p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n }\n\n function log(string memory p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/console2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\n/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should\n/// use `int256` and `uint256`. This modified version fixes that. This version is recommended\n/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in\n/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`.\n/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178\nlibrary console2 {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function log(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint256 p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n }\n\n function log(uint256 p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n }\n\n function log(uint256 p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n }\n\n function log(uint256 p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n }\n\n function log(string memory p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n }\n\n function log(string memory p0, int256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,int256)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/interfaces/IMulticall3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ninterface IMulticall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint256 value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n function aggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes[] memory returnData);\n\n function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);\n\n function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData);\n\n function blockAndAggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n\n function getBasefee() external view returns (uint256 basefee);\n\n function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash);\n\n function getBlockNumber() external view returns (uint256 blockNumber);\n\n function getChainId() external view returns (uint256 chainid);\n\n function getCurrentBlockCoinbase() external view returns (address coinbase);\n\n function getCurrentBlockDifficulty() external view returns (uint256 difficulty);\n\n function getCurrentBlockGasLimit() external view returns (uint256 gaslimit);\n\n function getCurrentBlockTimestamp() external view returns (uint256 timestamp);\n\n function getEthBalance(address addr) external view returns (uint256 balance);\n\n function getLastBlockHash() external view returns (bytes32 blockHash);\n\n function tryAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (Result[] memory returnData);\n\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n}\n" - } - }, - "settings": { - "remappings": [ - "@cwia/=node_modules/clones-with-immutable-args/src/", - "@openzeppelin/=node_modules/@openzeppelin/", - "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", - "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", - "@rari-capital/=node_modules/@rari-capital/", - "@rari-capital/solmate/=node_modules/@rari-capital/solmate/", - "clones-with-immutable-args/=node_modules/clones-with-immutable-args/", - "ds-test/=node_modules/ds-test/src/", - "forge-std/=node_modules/forge-std/src/" - ], - "optimizer": { - "enabled": true, - "runs": 999999 - }, - "metadata": { - "bytecodeHash": "none" - }, - "outputSelection": { - "*": { - "": [ - "ast" - ], - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "storageLayout", - "devdoc", - "userdoc" - ] - } - }, - "evmVersion": "london", - "libraries": {} - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/.chainId b/packages/contracts-bedrock/deployments/optimism-goerli/.chainId deleted file mode 100644 index 1e59c84a3a51..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/.chainId +++ /dev/null @@ -1 +0,0 @@ -420 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/AttestationStation.json b/packages/contracts-bedrock/deployments/optimism-goerli/AttestationStation.json deleted file mode 100644 index c2c9d3e8681a..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/AttestationStation.json +++ /dev/null @@ -1,270 +0,0 @@ -{ - "address": "0xbeD744818e96AAD8a51324291a6f6Cb20A0c22be", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "creator", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "about", - "type": "address" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "key", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "val", - "type": "bytes" - } - ], - "name": "AttestationCreated", - "type": "event" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "about", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "key", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "val", - "type": "bytes" - } - ], - "internalType": "struct AttestationStation.AttestationData[]", - "name": "_attestations", - "type": "tuple[]" - } - ], - "name": "attest", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_about", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_key", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "_val", - "type": "bytes" - } - ], - "name": "attest", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "attestations", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x4c0aae61c0030872cb5f8654c36fbc192cfab6f09f93df5c0f80268382d964e9", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078", - "contractAddress": null, - "transactionIndex": 1, - "gasUsed": "666309", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe683044625d767223da2ecd65fd81a34251ffbef27abd3302530be36e99971d0", - "transactionHash": "0x4c0aae61c0030872cb5f8654c36fbc192cfab6f09f93df5c0f80268382d964e9", - "logs": [], - "blockNumber": 4667191, - "cumulativeGasUsed": "666309", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 2, - "solcInputHash": "3aa2ad7d005d9515a1f12df8da17d178", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"name\":\"AttestationCreated\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"internalType\":\"struct AttestationStation.AttestationData[]\",\"name\":\"_attestations\",\"type\":\"tuple[]\"}],\"name\":\"attest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_about\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_val\",\"type\":\"bytes\"}],\"name\":\"attest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"attestations\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Optimism CollectiveGitcoin\",\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"params\":{\"about\":\"Address attestation is about.\",\"creator\":\"Address that made the attestation.\",\"key\":\"Key of the attestation.\",\"val\":\"Value of the attestation.\"}}},\"kind\":\"dev\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"params\":{\"_attestations\":\"An array of attestation data.\"}},\"attest(address,bytes32,bytes)\":{\"params\":{\"_about\":\"Address that the attestation is about.\",\"_key\":\"A key used to namespace the attestation.\",\"_val\":\"An arbitrary value stored as part of the attestation.\"}},\"constructor\":{\"custom:semver\":\"1.1.0\"},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"AttestationStation\",\"version\":1},\"userdoc\":{\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"notice\":\"Emitted when Attestation is created.\"}},\"kind\":\"user\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"notice\":\"Allows anyone to create attestations.\"},\"attest(address,bytes32,bytes)\":{\"notice\":\"Allows anyone to create an attestation.\"},\"attestations(address,address,bytes32)\":{\"notice\":\"Maps addresses to attestations. Creator => About => Key => Value.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Where attestations live.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/AttestationStation.sol\":\"AttestationStation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.15;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x979b13465de4996a1105850abbf48abe7f71d5e18a8d4af318597ee14c165fdf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of attestation data.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x80718fdc09061ea8f8b99a0b846eee46c5a2a1372dbb0cbc3d40953cb3af19e0\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60e060405234801561001057600080fd5b506001608081905260a052600060c05260805160a05160c051610b1c61004f60003960006101ad015260006101840152600061015b0152610b1c6000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806329b42cb51461005157806354fd4d501461007a5780635eb5ea1014610082578063702b9dee14610097575b600080fd5b61006461005f36600461046c565b6100aa565b604051610071919061051e565b60405180910390f35b610064610154565b610095610090366004610538565b6101f7565b005b6100956100a5366004610687565b61025a565b60006020818152938152604080822085529281528281209093528252902080546100d3906106de565b80601f01602080910402602001604051908101604052809291908181526020018280546100ff906106de565b801561014c5780601f106101215761010080835404028352916020019161014c565b820191906000526020600020905b81548152906001019060200180831161012f57829003601f168201915b505050505081565b606061017f7f0000000000000000000000000000000000000000000000000000000000000000610306565b6101a87f0000000000000000000000000000000000000000000000000000000000000000610306565b6101d17f0000000000000000000000000000000000000000000000000000000000000000610306565b6040516020016101e393929190610731565b604051602081830303815290604052905090565b8060005b81811015610254576000848483818110610217576102176107a7565b905060200281019061022991906107d6565b61023290610814565b905061024b81600001518260200151836040015161025a565b506001016101fb565b50505050565b3360009081526020818152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320858452909152902061029a82826108df565b50818373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85846040516102f9919061051e565b60405180910390a4505050565b60608160000361034957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610373578061035d81610a28565b915061036c9050600a83610a8f565b915061034d565b60008167ffffffffffffffff81111561038e5761038e6105ad565b6040519080825280601f01601f1916602001820160405280156103b8576020820181803683370190505b5090505b841561043b576103cd600183610aa3565b91506103da600a86610aba565b6103e5906030610ace565b60f81b8183815181106103fa576103fa6107a7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610434600a86610a8f565b94506103bc565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461046757600080fd5b919050565b60008060006060848603121561048157600080fd5b61048a84610443565b925061049860208501610443565b9150604084013590509250925092565b60005b838110156104c35781810151838201526020016104ab565b838111156102545750506000910152565b600081518084526104ec8160208601602086016104a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061053160208301846104d4565b9392505050565b6000806020838503121561054b57600080fd5b823567ffffffffffffffff8082111561056357600080fd5b818501915085601f83011261057757600080fd5b81358181111561058657600080fd5b8660208260051b850101111561059b57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126105ed57600080fd5b813567ffffffffffffffff80821115610608576106086105ad565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561064e5761064e6105ad565b8160405283815286602085880101111561066757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561069c57600080fd5b6106a584610443565b925060208401359150604084013567ffffffffffffffff8111156106c857600080fd5b6106d4868287016105dc565b9150509250925092565b600181811c908216806106f257607f821691505b60208210810361072b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516107438184602089016104a8565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161077f816001850160208a016104a8565b6001920191820152835161079a8160028401602088016104a8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261080a57600080fd5b9190910192915050565b60006060823603121561082657600080fd5b6040516060810167ffffffffffffffff828210818311171561084a5761084a6105ad565b8160405261085785610443565b835260208501356020840152604085013591508082111561087757600080fd5b50610884368286016105dc565b60408301525092915050565b601f8211156108da57600081815260208120601f850160051c810160208610156108b75750805b601f850160051c820191505b818110156108d6578281556001016108c3565b5050505b505050565b815167ffffffffffffffff8111156108f9576108f96105ad565b61090d8161090784546106de565b84610890565b602080601f831160018114610960576000841561092a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556108d6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156109ad5788860151825594840194600190910190840161098e565b50858210156109e957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a5957610a596109f9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a9e57610a9e610a60565b500490565b600082821015610ab557610ab56109f9565b500390565b600082610ac957610ac9610a60565b500690565b60008219821115610ae157610ae16109f9565b50019056fea2646970667358221220bfd4abacc1c2510682b093eea8745255cdd9f45c5b16c168540522a65ddc1f3264736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806329b42cb51461005157806354fd4d501461007a5780635eb5ea1014610082578063702b9dee14610097575b600080fd5b61006461005f36600461046c565b6100aa565b604051610071919061051e565b60405180910390f35b610064610154565b610095610090366004610538565b6101f7565b005b6100956100a5366004610687565b61025a565b60006020818152938152604080822085529281528281209093528252902080546100d3906106de565b80601f01602080910402602001604051908101604052809291908181526020018280546100ff906106de565b801561014c5780601f106101215761010080835404028352916020019161014c565b820191906000526020600020905b81548152906001019060200180831161012f57829003601f168201915b505050505081565b606061017f7f0000000000000000000000000000000000000000000000000000000000000000610306565b6101a87f0000000000000000000000000000000000000000000000000000000000000000610306565b6101d17f0000000000000000000000000000000000000000000000000000000000000000610306565b6040516020016101e393929190610731565b604051602081830303815290604052905090565b8060005b81811015610254576000848483818110610217576102176107a7565b905060200281019061022991906107d6565b61023290610814565b905061024b81600001518260200151836040015161025a565b506001016101fb565b50505050565b3360009081526020818152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320858452909152902061029a82826108df565b50818373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85846040516102f9919061051e565b60405180910390a4505050565b60608160000361034957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610373578061035d81610a28565b915061036c9050600a83610a8f565b915061034d565b60008167ffffffffffffffff81111561038e5761038e6105ad565b6040519080825280601f01601f1916602001820160405280156103b8576020820181803683370190505b5090505b841561043b576103cd600183610aa3565b91506103da600a86610aba565b6103e5906030610ace565b60f81b8183815181106103fa576103fa6107a7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610434600a86610a8f565b94506103bc565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461046757600080fd5b919050565b60008060006060848603121561048157600080fd5b61048a84610443565b925061049860208501610443565b9150604084013590509250925092565b60005b838110156104c35781810151838201526020016104ab565b838111156102545750506000910152565b600081518084526104ec8160208601602086016104a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061053160208301846104d4565b9392505050565b6000806020838503121561054b57600080fd5b823567ffffffffffffffff8082111561056357600080fd5b818501915085601f83011261057757600080fd5b81358181111561058657600080fd5b8660208260051b850101111561059b57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126105ed57600080fd5b813567ffffffffffffffff80821115610608576106086105ad565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561064e5761064e6105ad565b8160405283815286602085880101111561066757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561069c57600080fd5b6106a584610443565b925060208401359150604084013567ffffffffffffffff8111156106c857600080fd5b6106d4868287016105dc565b9150509250925092565b600181811c908216806106f257607f821691505b60208210810361072b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516107438184602089016104a8565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161077f816001850160208a016104a8565b6001920191820152835161079a8160028401602088016104a8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261080a57600080fd5b9190910192915050565b60006060823603121561082657600080fd5b6040516060810167ffffffffffffffff828210818311171561084a5761084a6105ad565b8160405261085785610443565b835260208501356020840152604085013591508082111561087757600080fd5b50610884368286016105dc565b60408301525092915050565b601f8211156108da57600081815260208120601f850160051c810160208610156108b75750805b601f850160051c820191505b818110156108d6578281556001016108c3565b5050505b505050565b815167ffffffffffffffff8111156108f9576108f96105ad565b61090d8161090784546106de565b84610890565b602080601f831160018114610960576000841561092a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556108d6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156109ad5788860151825594840194600190910190840161098e565b50858210156109e957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a5957610a596109f9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a9e57610a9e610a60565b500490565b600082821015610ab557610ab56109f9565b500390565b600082610ac957610ac9610a60565b500690565b60008219821115610ae157610ae16109f9565b50019056fea2646970667358221220bfd4abacc1c2510682b093eea8745255cdd9f45c5b16c168540522a65ddc1f3264736f6c634300080f0033", - "devdoc": { - "author": "Optimism CollectiveGitcoin", - "events": { - "AttestationCreated(address,address,bytes32,bytes)": { - "params": { - "about": "Address attestation is about.", - "creator": "Address that made the attestation.", - "key": "Key of the attestation.", - "val": "Value of the attestation." - } - } - }, - "kind": "dev", - "methods": { - "attest((address,bytes32,bytes)[])": { - "params": { - "_attestations": "An array of attestation data." - } - }, - "attest(address,bytes32,bytes)": { - "params": { - "_about": "Address that the attestation is about.", - "_key": "A key used to namespace the attestation.", - "_val": "An arbitrary value stored as part of the attestation." - } - }, - "constructor": { - "custom:semver": "1.1.0" - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "AttestationStation", - "version": 1 - }, - "userdoc": { - "events": { - "AttestationCreated(address,address,bytes32,bytes)": { - "notice": "Emitted when Attestation is created." - } - }, - "kind": "user", - "methods": { - "attest((address,bytes32,bytes)[])": { - "notice": "Allows anyone to create attestations." - }, - "attest(address,bytes32,bytes)": { - "notice": "Allows anyone to create an attestation." - }, - "attestations(address,address,bytes32)": { - "notice": "Maps addresses to attestations. Creator => About => Key => Value." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "Where attestations live.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 2135, - "contract": "contracts/universal/op-nft/AttestationStation.sol:AttestationStation", - "label": "attestations", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_address,t_mapping(t_address,t_mapping(t_bytes32,t_bytes_storage)))" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "encoding": "bytes", - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_address,t_mapping(t_bytes32,t_bytes_storage)))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => mapping(bytes32 => bytes)))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_mapping(t_bytes32,t_bytes_storage))" - }, - "t_mapping(t_address,t_mapping(t_bytes32,t_bytes_storage))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(bytes32 => bytes))", - "numberOfBytes": "32", - "value": "t_mapping(t_bytes32,t_bytes_storage)" - }, - "t_mapping(t_bytes32,t_bytes_storage)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bytes)", - "numberOfBytes": "32", - "value": "t_bytes_storage" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/AttestationStationProxy.json b/packages/contracts-bedrock/deployments/optimism-goerli/AttestationStationProxy.json deleted file mode 100644 index bb87ce216cf2..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/AttestationStationProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x784bf644f4af308c768373d6599c71c976fe8977b1b663bdec2025a16f6bff56", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "534190", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000008000000000000000000000000", - "blockHash": "0x7085d08eb9d49fc1ecaa8568a338414983ced83535d8fd2931113b981dea986f", - "transactionHash": "0x784bf644f4af308c768373d6599c71c976fe8977b1b663bdec2025a16f6bff56", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 3451201, - "transactionHash": "0x784bf644f4af308c768373d6599c71c976fe8977b1b663bdec2025a16f6bff56", - "address": "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58", - "logIndex": 0, - "blockHash": "0x7085d08eb9d49fc1ecaa8568a338414983ced83535d8fd2931113b981dea986f" - } - ], - "blockNumber": 3451201, - "cumulativeGasUsed": "534190", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "45837d34ff24b9cb2ae34232b60ea874", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n external\\n payable\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() external proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() external proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/BaseFeeVault.json b/packages/contracts-bedrock/deployments/optimism-goerli/BaseFeeVault.json deleted file mode 100644 index ca4ebf274bcb..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/BaseFeeVault.json +++ /dev/null @@ -1,191 +0,0 @@ -{ - "address": "0x984eBeFb32A5c2862e92ce90EA0C81Ab69F026B5", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - } - ], - "name": "Withdrawal", - "type": "event" - }, - { - "inputs": [], - "name": "MIN_WITHDRAWAL_AMOUNT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RECIPIENT", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalProcessed", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "withdraw", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x8200dcd39f9e6c14017c508bf58527bea3dafd1eb06a5fe006b3345009f107d8", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0x984eBeFb32A5c2862e92ce90EA0C81Ab69F026B5", - "transactionIndex": 1, - "gasUsed": "492913", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x2271d21bc9c675c55be64016d7c610f82108dfc2a31b690ef0cbee4b0efa6709", - "transactionHash": "0x8200dcd39f9e6c14017c508bf58527bea3dafd1eb06a5fe006b3345009f107d8", - "logs": [], - "blockNumber": 8579696, - "cumulativeGasUsed": "539814", - "status": 1, - "byzantium": true - }, - "args": [ - "0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f" - ], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_WITHDRAWAL_AMOUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RECIPIENT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalProcessed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"custom:proxied\":\"@custom:predeploy 0x4200000000000000000000000000000000000019\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.1.0\",\"params\":{\"_recipient\":\"Address that will receive the accumulated fees.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"BaseFeeVault\",\"version\":1},\"userdoc\":{\"events\":{\"Withdrawal(uint256,address,address)\":{\"notice\":\"Emits each time that a withdrawal occurs.\"}},\"kind\":\"user\",\"methods\":{\"MIN_WITHDRAWAL_AMOUNT()\":{\"notice\":\"Minimum balance before a withdrawal can be triggered.\"},\"RECIPIENT()\":{\"notice\":\"Wallet that will receive the fees on L1.\"},\"totalProcessed()\":{\"notice\":\"Total amount of wei processed by the contract.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"},\"withdraw()\":{\"notice\":\"Triggers a withdrawal of funds to the L1 fee wallet.\"}},\"notice\":\"The BaseFeeVault accumulates the base fee that is paid by transactions.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/BaseFeeVault.sol\":\"BaseFeeVault\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L1/ResourceMetering.sol\":{\"keccak256\":\"0xbd7b9532a70d8c842bfce0ea971be50d02fbbf0227c9ad55c71ac68d438010f4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4969f478dd54e89392cda2ea0c5edcf1be55a5dee43a0e410527b6e3bcb85c88\",\"dweb:/ipfs/QmU2crAojw8DRDsz7PAPrereazjFsKh9wtfTpTDVh6NLfW\"]},\"contracts/L2/BaseFeeVault.sol\":{\"keccak256\":\"0xa2d3cb58a2f00b25aea98e0cc532c44ab5c97f28c6f9e3348a31ddc54ffffcb7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://506dbf5211d511db2407d0551e2a5cc2c4754520acad08ee1d9a5d0cffaa71e0\",\"dweb:/ipfs/QmYftWQRoB7CE6huatMncAVUtGYJc42E9heW26snTQqfXn\"]},\"contracts/L2/L2StandardBridge.sol\":{\"keccak256\":\"0xd77e04c57f33cd32c32f326cd06e213d8a27a9fd372cfc4269953a49243c8c41\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f59627bf4c08c85886e819b29b8565b48fa7e9c230732fedfbb0b9c9a0ee04c5\",\"dweb:/ipfs/Qmao1VbQ57h6gdCZTYfipa8LB1wBwAthop5tPd9TgDXES2\"]},\"contracts/libraries/Arithmetic.sol\":{\"keccak256\":\"0xc8858039f87e48e6f18c1af8bc0b03e57cfef564acddfd06e4d91e3db7ac5ed6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2fc79af1e844aa6dc1c68067bfe1d359df8d4e9a3e8881afb3bcfcbf68071714\",\"dweb:/ipfs/QmcNC4k8zmvwj4kZizSenTiWbx2DJQPbwqXXLF4iMbkRVD\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Constants.sol\":{\"keccak256\":\"0x8c7be28a175eb732995a7f704560163c30261f9f70d377f865c5060882509f5d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f72aba26553b10ca88708e05461691b36b0d2ec7a87f718022fe119ca9c70852\",\"dweb:/ipfs/QmQtDEB1F3D8RsgG63KSJ9t7ZyFLaXc2Av81vKD9y2TMn7\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/Predeploys.sol\":{\"keccak256\":\"0xfc30fb239b5f00284f4b8f578a62f0882597e939335c91ea9bc4aab3070ddc43\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fa132267b3a9d98568b4e02cbb68fe2d2c0ca630826242c1b2293a8fa35bd302\",\"dweb:/ipfs/QmdYvcGbaykP6wyBu5T2obXrWK56xGnfWqbYeeWpTChq3w\"]},\"contracts/libraries/SafeCall.sol\":{\"keccak256\":\"0x6e815b62528d452a4f63040d75ff7a08db8ba8096050a53355fc49abaebdf245\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e27e542a11165c82cbb6961f4d8c2a58527fba1ab915afeeded50e96ce929777\",\"dweb:/ipfs/QmRPXdmUAbL1WHZBvENKWkFuHb9bQyrbiJWwDvzEQBLVi8\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x4fe8ec920798661a828430bd30dc2715eeb40534ec01c0a7bf41cb4ab422e134\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://74c8471869900bd459358cd990bda1c8d234c06b788804c7049cf465ae1e299f\",\"dweb:/ipfs/QmakcfP6NmbVUQsKqH7rEyJsbiqckigLahw9g74oencEJ7\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x3c99b1e768cc4c1e064ccc137b1b4d5961bf4edf071be84cc216c5b20f1c00da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e36b2a6325c2f804d769271575669b62ab2da2df3c81921ac7487399fe02af07\",\"dweb:/ipfs/QmTCmcEKwvD8Xvjyev268Bkz27FC7TJpUbw1nADcsThnUr\"]},\"contracts/universal/FeeVault.sol\":{\"keccak256\":\"0x73eb2c835495ec308c69783db55c6cc315ed2a55ee6811ccda4e7dbbde04b2c8\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b5e46201184138d60e339c98276e3b265717a12795270a1d0ef03157e452e9a0\",\"dweb:/ipfs/QmWGLhTcPuF9ZZfrjGj4QGCzEuDwiyRAMpnQvxd2oLFX75\"]},\"contracts/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x2fea0ee05071c9c6b06a34a8e805801e247e861359b376a8918106e1d6f77ebe\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://198c91bda2edf864ddad1f8ab6168155d13d6ba5487418e5531ff040ff250686\",\"dweb:/ipfs/QmQzxfHY4P7zdVFRh2DTdGt1KeMHaGKNRf3KPZ1mRTYEGB\"]},\"contracts/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x302094342a45ebdf7f46f4fb48821960d2a4134f66fd7f458f73fc4ddf34d219\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b0e2b496e966ca6037e1c9be1d44417c0180fda2a27f68114e93b899defb783\",\"dweb:/ipfs/QmXP76ivMLxYxscC7B9E9qtW3u6HJ2MNaRVeo3x24VEAQH\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"contracts/universal/StandardBridge.sol\":{\"keccak256\":\"0xaa45044774fa70ed322983c3c0138b21d26d75f4b7e8f5324d53c3eef91adec4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c65c95d0cb71f2e32f5ffdea92151a9a46bbd538ba110389a134963fd16a33e9\",\"dweb:/ipfs/QmaPNZokt4j5SCXaWwVtw6qxu5GXWFa3SWBgaSWPPA9KUG\"]},\"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://11756f42121f6541a35a8339ea899ee7514cfaa2e6d740625fcc844419296aa6\",\"dweb:/ipfs/QmekMuk6BY4DAjzeXr4MSbKdgoqqsZnA8JPtuyWc6CwXHf\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]}},\"version\":1}", - "bytecode": "0x61012060405234801561001157600080fd5b506040516108e53803806108e58339810160408190526100309161005d565b678ac7230489e800006080526001600160a01b031660a052600160c081905260e05260006101005261008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b60805160a05160c05160e051610100516108006100e560003960006103d3015260006103aa01526000610381015260008181607c015281816102570152610319015260008181610137015261015b01526108006000f3fe60806040526004361061005e5760003560e01c806354fd4d501161004357806354fd4d50146100df57806384411d6514610101578063d3e5792b1461012557600080fd5b80630d9019e11461006a5780633ccfd60b146100c857600080fd5b3661006557005b600080fd5b34801561007657600080fd5b5061009e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100d457600080fd5b506100dd610159565b005b3480156100eb57600080fd5b506100f461037a565b6040516100bf91906105d4565b34801561010d57600080fd5b5061011760005481565b6040519081526020016100bf565b34801561013157600080fd5b506101177f000000000000000000000000000000000000000000000000000000000000000081565b7f0000000000000000000000000000000000000000000000000000000000000000471015610233576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a40160405180910390fd5b600047905080600080828254610249919061061d565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610345917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610635565b6000604051808303818588803b15801561035e57600080fd5b505af1158015610372573d6000803e3d6000fd5b505050505050565b60606103a57f000000000000000000000000000000000000000000000000000000000000000061041d565b6103ce7f000000000000000000000000000000000000000000000000000000000000000061041d565b6103f77f000000000000000000000000000000000000000000000000000000000000000061041d565b60405160200161040993929190610679565b604051602081830303815290604052905090565b60608160000361046057505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561048a5780610474816106ef565b91506104839050600a83610756565b9150610464565b60008167ffffffffffffffff8111156104a5576104a561076a565b6040519080825280601f01601f1916602001820160405280156104cf576020820181803683370190505b5090505b8415610552576104e4600183610799565b91506104f1600a866107b0565b6104fc90603061061d565b60f81b818381518110610511576105116107c4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061054b600a86610756565b94506104d3565b949350505050565b60005b8381101561057557818101518382015260200161055d565b83811115610584576000848401525b50505050565b600081518084526105a281602086016020860161055a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105e7602083018461058a565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610630576106306105ee565b500190565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff83166020820152606060408201526000610670606083018461058a565b95945050505050565b6000845161068b81846020890161055a565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516106c7816001850160208a0161055a565b600192019182015283516106e281600284016020880161055a565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610720576107206105ee565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261076557610765610727565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107ab576107ab6105ee565b500390565b6000826107bf576107bf610727565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c806354fd4d501161004357806354fd4d50146100df57806384411d6514610101578063d3e5792b1461012557600080fd5b80630d9019e11461006a5780633ccfd60b146100c857600080fd5b3661006557005b600080fd5b34801561007657600080fd5b5061009e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100d457600080fd5b506100dd610159565b005b3480156100eb57600080fd5b506100f461037a565b6040516100bf91906105d4565b34801561010d57600080fd5b5061011760005481565b6040519081526020016100bf565b34801561013157600080fd5b506101177f000000000000000000000000000000000000000000000000000000000000000081565b7f0000000000000000000000000000000000000000000000000000000000000000471015610233576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a40160405180910390fd5b600047905080600080828254610249919061061d565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610345917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610635565b6000604051808303818588803b15801561035e57600080fd5b505af1158015610372573d6000803e3d6000fd5b505050505050565b60606103a57f000000000000000000000000000000000000000000000000000000000000000061041d565b6103ce7f000000000000000000000000000000000000000000000000000000000000000061041d565b6103f77f000000000000000000000000000000000000000000000000000000000000000061041d565b60405160200161040993929190610679565b604051602081830303815290604052905090565b60608160000361046057505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561048a5780610474816106ef565b91506104839050600a83610756565b9150610464565b60008167ffffffffffffffff8111156104a5576104a561076a565b6040519080825280601f01601f1916602001820160405280156104cf576020820181803683370190505b5090505b8415610552576104e4600183610799565b91506104f1600a866107b0565b6104fc90603061061d565b60f81b818381518110610511576105116107c4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061054b600a86610756565b94506104d3565b949350505050565b60005b8381101561057557818101518382015260200161055d565b83811115610584576000848401525b50505050565b600081518084526105a281602086016020860161055a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105e7602083018461058a565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610630576106306105ee565b500190565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff83166020820152606060408201526000610670606083018461058a565b95945050505050565b6000845161068b81846020890161055a565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516106c7816001850160208a0161055a565b600192019182015283516106e281600284016020880161055a565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610720576107206105ee565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261076557610765610727565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107ab576107ab6105ee565b500390565b6000826107bf576107bf610727565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_recipient": "Address that will receive the accumulated fees." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "BaseFeeVault" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MIN_WITHDRAWAL_AMOUNT()": { - "notice": "Minimum balance before a withdrawal can be triggered." - }, - "RECIPIENT()": { - "notice": "Wallet that will receive the fees on L1." - }, - "totalProcessed()": { - "notice": "Total amount of wei processed by the contract." - }, - "version()": { - "notice": "Returns the full semver contract version." - }, - "withdraw()": { - "notice": "Triggers a withdrawal of funds to the L1 fee wallet." - } - }, - "events": { - "Withdrawal(uint256,address,address)": { - "notice": "Emits each time that a withdrawal occurs." - } - }, - "notice": "The BaseFeeVault accumulates the base fee that is paid by transactions." - }, - "storageLayout": { - "storage": [ - { - "astId": 46671, - "contract": "contracts/L2/BaseFeeVault.sol:BaseFeeVault", - "label": "totalProcessed", - "offset": 0, - "slot": "0", - "type": "t_uint256" - } - ], - "types": { - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/CheckBalanceHigh.json b/packages/contracts-bedrock/deployments/optimism-goerli/CheckBalanceHigh.json deleted file mode 100644 index 5d65f8d86ea3..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/CheckBalanceHigh.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "address": "0x5d7103853f12109A7d27F118e54BbC654ad847E9", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct CheckBalanceHigh.Params", - "name": "params", - "type": "tuple" - } - ], - "name": "_EventToExposeStructInABI__Params", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x3471e90c7d79ad0c4b5e48740c5c3bbc1dd95df6d6b2b84b2f41f0ec1426c101", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "176628", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x132ca8cc42fb4d0b9a111b739b00c60e504a5242b4303a10a0dd3d1940416b58", - "transactionHash": "0x3471e90c7d79ad0c4b5e48740c5c3bbc1dd95df6d6b2b84b2f41f0ec1426c101", - "logs": [], - "blockNumber": 379105, - "cumulativeGasUsed": "176628", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "cb12280dddcf446d7c90129cbaba29bb", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct CheckBalanceHigh.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"CheckBalanceHigh\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"DripCheck for checking if an account's balance is above a given threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol\":\"CheckBalanceHigh\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbf1b9be6bbcbbbd2268023a169382c9a62a58a343420e4bc4494a9f463f86042\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckBalanceHigh\\n * @notice DripCheck for checking if an account's balance is above a given threshold.\\n */\\ncontract CheckBalanceHigh is IDripCheck {\\n event _EventToExposeStructInABI__Params(Params params);\\n struct Params {\\n address target;\\n uint256 threshold;\\n }\\n\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check target balance is above threshold.\\n return params.target.balance > params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0x413fddb77f3ceb396907ac4caa30070051897867cc914cf34f8abed5d2f19c9f\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610239806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631119392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea26469706673582212202670037ac2f0df3fc2c19f630f10737e037f1732829274c37513beda7d16439864736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631119392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea26469706673582212202670037ac2f0df3fc2c19f630f10737e037f1732829274c37513beda7d16439864736f6c634300080f0033", - "devdoc": { - "kind": "dev", - "methods": {}, - "title": "CheckBalanceHigh", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "notice": "DripCheck for checking if an account's balance is above a given threshold.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/CheckBalanceLow.json b/packages/contracts-bedrock/deployments/optimism-goerli/CheckBalanceLow.json deleted file mode 100644 index 2b1fb5e12233..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/CheckBalanceLow.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "address": "0x7Ce13D154FAEE5C8B3E6b19d4Add16f21d884474", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct CheckBalanceLow.Params", - "name": "params", - "type": "tuple" - } - ], - "name": "_EventToExposeStructInABI__Params", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0xa033cbc354b12f1ce14dd09985d91cdf764a9c9f2c40fd10dff29729579c4b8f", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "176640", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x355bce78cb18977b9744bb3f52d9b6be1a7b9eebeb8ac23b6e5dfab7567cb18b", - "transactionHash": "0xa033cbc354b12f1ce14dd09985d91cdf764a9c9f2c40fd10dff29729579c4b8f", - "logs": [], - "blockNumber": 379110, - "cumulativeGasUsed": "176640", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "cb12280dddcf446d7c90129cbaba29bb", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct CheckBalanceLow.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"CheckBalanceLow\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"DripCheck for checking if an account's balance is below a given threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol\":\"CheckBalanceLow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbf1b9be6bbcbbbd2268023a169382c9a62a58a343420e4bc4494a9f463f86042\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckBalanceLow\\n * @notice DripCheck for checking if an account's balance is below a given threshold.\\n */\\ncontract CheckBalanceLow is IDripCheck {\\n event _EventToExposeStructInABI__Params(Params params);\\n struct Params {\\n address target;\\n uint256 threshold;\\n }\\n\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check target ETH balance is below threshold.\\n return params.target.balance < params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0xb705b39a2a2ba956a75059191b89ccc6a8f398bea09fea6a671fcb8ceaac5e23\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610239806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea2646970667358221220f1fe79edf6cb1b21a2c196070aaf9fd8aa207004c7fd99c5231e1322bc0d04d864736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea2646970667358221220f1fe79edf6cb1b21a2c196070aaf9fd8aa207004c7fd99c5231e1322bc0d04d864736f6c634300080f0033", - "devdoc": { - "kind": "dev", - "methods": {}, - "title": "CheckBalanceLow", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "notice": "DripCheck for checking if an account's balance is below a given threshold.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/CheckGelatoLow.json b/packages/contracts-bedrock/deployments/optimism-goerli/CheckGelatoLow.json deleted file mode 100644 index 4107cb9ea6b7..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/CheckGelatoLow.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "address": "0xF9c8a4Cb4021f57F9f6d69799cA9BefF64524862", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "treasury", - "type": "address" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - } - ], - "indexed": false, - "internalType": "struct CheckGelatoLow.Params", - "name": "params", - "type": "tuple" - } - ], - "name": "_EventToExposeStructInABI__Params", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0xa2c3892e5b792fdb814d5d148fd3b1ff19b06878fe245fb93ad179f403d05b01", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "222032", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xefeb7750cbbb732133ef4060beacd5f4b07c1f1b7a2c41270b1f43a98dd95c77", - "transactionHash": "0xa2c3892e5b792fdb814d5d148fd3b1ff19b06878fe245fb93ad179f403d05b01", - "logs": [], - "blockNumber": 380292, - "cumulativeGasUsed": "222032", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "cb12280dddcf446d7c90129cbaba29bb", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"treasury\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct CheckGelatoLow.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"CheckGelatoLow\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"DripCheck for checking if an account's Gelato ETH balance is below some threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol\":\"CheckGelatoLow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbf1b9be6bbcbbbd2268023a169382c9a62a58a343420e4bc4494a9f463f86042\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\ninterface IGelatoTreasury {\\n function userTokenBalance(address _user, address _token) external view returns (uint256);\\n}\\n\\n/**\\n * @title CheckGelatoLow\\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\\n */\\ncontract CheckGelatoLow is IDripCheck {\\n event _EventToExposeStructInABI__Params(Params params);\\n struct Params {\\n address treasury;\\n uint256 threshold;\\n address recipient;\\n }\\n\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check GelatoTreasury ETH balance is below threshold.\\n return\\n IGelatoTreasury(params.treasury).userTokenBalance(\\n params.recipient,\\n // Gelato represents ETH as 0xeeeee....eeeee\\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\\n ) < params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0x527fc26a3f52e97f22d88859cac0511fc57c8a0f46b0dd9549aa98b248086a9f\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061030c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e366004610160565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610258565b6020810151815160408084015190517fb47064c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6024820152939450919291169063b47064c890604401602060405180830381865afa158015610105573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012991906102bd565b109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561017257600080fd5b813567ffffffffffffffff8082111561018a57600080fd5b818401915084601f83011261019e57600080fd5b8135818111156101b0576101b0610131565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f6576101f6610131565b8160405282815287602084870101111561020f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b805173ffffffffffffffffffffffffffffffffffffffff8116811461025357600080fd5b919050565b60006060828403121561026a57600080fd5b6040516060810181811067ffffffffffffffff8211171561028d5761028d610131565b6040526102998361022f565b8152602083015160208201526102b16040840161022f565b60408201529392505050565b6000602082840312156102cf57600080fd5b505191905056fea2646970667358221220ad6ea11246f072b25bce3394368ffae4870bfffefe4fe262371ac084c9baaca264736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e366004610160565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610258565b6020810151815160408084015190517fb47064c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6024820152939450919291169063b47064c890604401602060405180830381865afa158015610105573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012991906102bd565b109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561017257600080fd5b813567ffffffffffffffff8082111561018a57600080fd5b818401915084601f83011261019e57600080fd5b8135818111156101b0576101b0610131565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f6576101f6610131565b8160405282815287602084870101111561020f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b805173ffffffffffffffffffffffffffffffffffffffff8116811461025357600080fd5b919050565b60006060828403121561026a57600080fd5b6040516060810181811067ffffffffffffffff8211171561028d5761028d610131565b6040526102998361022f565b8152602083015160208201526102b16040840161022f565b60408201529392505050565b6000602082840312156102cf57600080fd5b505191905056fea2646970667358221220ad6ea11246f072b25bce3394368ffae4870bfffefe4fe262371ac084c9baaca264736f6c634300080f0033", - "devdoc": { - "kind": "dev", - "methods": {}, - "title": "CheckGelatoLow", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "notice": "DripCheck for checking if an account's Gelato ETH balance is below some threshold.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/CheckTrue.json b/packages/contracts-bedrock/deployments/optimism-goerli/CheckTrue.json deleted file mode 100644 index 4977fff035bb..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/CheckTrue.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "address": "0x47443D0C184e022F19BD1578F5bca6B8a9F58E32", - "abi": [ - { - "inputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "check", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "pure", - "type": "function" - } - ], - "transactionHash": "0x24cd6437a28b245c14e11cdb849a1c7fa5a4f4e7f7ccb9ddb72c837479167cce", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "139230", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe7bb26ce3802e753a1fde9a8180fd7c56625e649b03571535ef847f74b86e103", - "transactionHash": "0x24cd6437a28b245c14e11cdb849a1c7fa5a4f4e7f7ccb9ddb72c837479167cce", - "logs": [], - "blockNumber": 379170, - "cumulativeGasUsed": "139230", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "cb12280dddcf446d7c90129cbaba29bb", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"CheckTrue\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"DripCheck that always returns true.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckTrue.sol\":\"CheckTrue\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbf1b9be6bbcbbbd2268023a169382c9a62a58a343420e4bc4494a9f463f86042\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckTrue.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckTrue\\n * @notice DripCheck that always returns true.\\n */\\ncontract CheckTrue is IDripCheck {\\n function check(bytes memory) external pure returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x0f3110b218bd0a2fda2dcd6d366d40682a7624e001204b2bda3fcaa043396027\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061018c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004461003e366004610087565b50600190565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561009957600080fd5b813567ffffffffffffffff808211156100b157600080fd5b818401915084601f8301126100c557600080fd5b8135818111156100d7576100d7610058565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561011d5761011d610058565b8160405282815287602084870101111561013657600080fd5b82602086016020830137600092810160200192909252509594505050505056fea2646970667358221220e75519244b9d5ac4ed30ca10eb8a4940711a06bf13b8a7953e0a550561861e0164736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004461003e366004610087565b50600190565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561009957600080fd5b813567ffffffffffffffff808211156100b157600080fd5b818401915084601f8301126100c557600080fd5b8135818111156100d7576100d7610058565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561011d5761011d610058565b8160405282815287602084870101111561013657600080fd5b82602086016020830137600092810160200192909252509594505050505056fea2646970667358221220e75519244b9d5ac4ed30ca10eb8a4940711a06bf13b8a7953e0a550561861e0164736f6c634300080f0033", - "devdoc": { - "kind": "dev", - "methods": {}, - "title": "CheckTrue", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "notice": "DripCheck that always returns true.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/Drippie.json b/packages/contracts-bedrock/deployments/optimism-goerli/Drippie.json deleted file mode 100644 index a4af421c552d..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/Drippie.json +++ /dev/null @@ -1,1038 +0,0 @@ -{ - "address": "0x8D8d533C16D23847EB04EEB0925be8900Dd3af86", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "nameref", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "interval", - "type": "uint256" - }, - { - "internalType": "contract IDripCheck", - "name": "dripcheck", - "type": "address" - }, - { - "internalType": "bytes", - "name": "checkparams", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "address payable", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct Drippie.DripAction[]", - "name": "actions", - "type": "tuple[]" - } - ], - "indexed": false, - "internalType": "struct Drippie.DripConfig", - "name": "config", - "type": "tuple" - } - ], - "name": "DripCreated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "nameref", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "indexed": false, - "internalType": "address", - "name": "executor", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - } - ], - "name": "DripExecuted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "nameref", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "indexed": false, - "internalType": "enum Drippie.DripStatus", - "name": "status", - "type": "uint8" - } - ], - "name": "DripStatusUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ReceivedETH", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewERC20", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "WithdrewERC721", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewETH", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_gas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "CALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_gas", - "type": "uint256" - } - ], - "name": "DELEGATECALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "interval", - "type": "uint256" - }, - { - "internalType": "contract IDripCheck", - "name": "dripcheck", - "type": "address" - }, - { - "internalType": "bytes", - "name": "checkparams", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "address payable", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct Drippie.DripAction[]", - "name": "actions", - "type": "tuple[]" - } - ], - "internalType": "struct Drippie.DripConfig", - "name": "_config", - "type": "tuple" - } - ], - "name": "create", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "drip", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "name": "drips", - "outputs": [ - { - "internalType": "enum Drippie.DripStatus", - "name": "status", - "type": "uint8" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "interval", - "type": "uint256" - }, - { - "internalType": "contract IDripCheck", - "name": "dripcheck", - "type": "address" - }, - { - "internalType": "bytes", - "name": "checkparams", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "address payable", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct Drippie.DripAction[]", - "name": "actions", - "type": "tuple[]" - } - ], - "internalType": "struct Drippie.DripConfig", - "name": "config", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "last", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "count", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "executable", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "enum Drippie.DripStatus", - "name": "_status", - "type": "uint8" - } - ], - "name": "status", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC721", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_id", - "type": "uint256" - } - ], - "name": "withdrawERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0xce71abe3a40dce0243fa31e639995deba791fa6d05de5a0ae33ef3d3b8752764", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "2132643", - "logsBloom": "0x00000000000000000001000000000000000000000000000000000000000000000000100000000000000000000000080000000000000000000000000000000004000080010000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000020000000000000000000000000000000000000000000000", - "blockHash": "0xc752d29e4717f908630803175a62ede18360241f05892f83e2c570e5b6c2fbb2", - "transactionHash": "0xce71abe3a40dce0243fa31e639995deba791fa6d05de5a0ae33ef3d3b8752764", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 379101, - "transactionHash": "0xce71abe3a40dce0243fa31e639995deba791fa6d05de5a0ae33ef3d3b8752764", - "address": "0x8D8d533C16D23847EB04EEB0925be8900Dd3af86", - "topics": [ - "0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58" - ], - "data": "0x", - "logIndex": 0, - "blockHash": "0xc752d29e4717f908630803175a62ede18360241f05892f83e2c570e5b6c2fbb2" - } - ], - "blockNumber": 379101, - "cumulativeGasUsed": "2132643", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "cb12280dddcf446d7c90129cbaba29bb", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"nameref\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"interval\",\"type\":\"uint256\"},{\"internalType\":\"contract IDripCheck\",\"name\":\"dripcheck\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkparams\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address payable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Drippie.DripAction[]\",\"name\":\"actions\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"struct Drippie.DripConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DripCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"nameref\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"DripExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"nameref\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"enum Drippie.DripStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"DripStatusUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ReceivedETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewETH\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"CALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"}],\"name\":\"DELEGATECALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"interval\",\"type\":\"uint256\"},{\"internalType\":\"contract IDripCheck\",\"name\":\"dripcheck\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkparams\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address payable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Drippie.DripAction[]\",\"name\":\"actions\",\"type\":\"tuple[]\"}],\"internalType\":\"struct Drippie.DripConfig\",\"name\":\"_config\",\"type\":\"tuple\"}],\"name\":\"create\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"drip\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"name\":\"drips\",\"outputs\":[{\"internalType\":\"enum Drippie.DripStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"interval\",\"type\":\"uint256\"},{\"internalType\":\"contract IDripCheck\",\"name\":\"dripcheck\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkparams\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address payable\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"struct Drippie.DripAction[]\",\"name\":\"actions\",\"type\":\"tuple[]\"}],\"internalType\":\"struct Drippie.DripConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"last\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"executable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"enum Drippie.DripStatus\",\"name\":\"_status\",\"type\":\"uint8\"}],\"name\":\"status\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC721\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"DripCreated(string,string,(uint256,address,bytes,(address,bytes,uint256)[]))\":{\"params\":{\"config\":\"Config for the created drip.\",\"name\":\"Unindexed name parameter (unhashed).\",\"nameref\":\"Indexed name parameter (hashed).\"}},\"DripExecuted(string,string,address,uint256)\":{\"params\":{\"executor\":\"Address that executed the drip.\",\"name\":\"Unindexed name parameter (unhashed).\",\"nameref\":\"Indexed name parameter (hashed).\",\"timestamp\":\"Time when the drip was executed.\"}},\"DripStatusUpdated(string,string,uint8)\":{\"params\":{\"name\":\"Unindexed name parameter (unhashed).\",\"nameref\":\"Indexed name parameter (hashed).\",\"status\":\"New drip status.\"}}},\"kind\":\"dev\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\",\"_value\":\"ETH value to send with the call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"DELEGATECALL(address,bytes,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"constructor\":{\"params\":{\"_owner\":\"Initial contract owner.\"}},\"create(string,(uint256,address,bytes,(address,bytes,uint256)[]))\":{\"params\":{\"_config\":\"Configuration for the drip.\",\"_name\":\"Name of the drip.\"}},\"drip(string)\":{\"params\":{\"_name\":\"Name of the drip to trigger.\"}},\"executable(string)\":{\"params\":{\"_name\":\"Drip to check.\"},\"returns\":{\"_0\":\"True if the drip is executable, false otherwise.\"}},\"status(string,uint8)\":{\"params\":{\"_name\":\"Name of the drip to update.\",\"_status\":\"New drip status.\"}},\"withdrawERC20(address,address)\":{\"params\":{\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC20(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount of ERC20 to withdraw.\",\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC721(address,address,uint256)\":{\"params\":{\"_asset\":\"ERC721 token to withdraw.\",\"_id\":\"Token ID of the ERC721 token to withdraw.\",\"_to\":\"Address to receive the ERC721 token.\"}},\"withdrawETH(address)\":{\"params\":{\"_to\":\"Address to receive the ETH balance.\"}},\"withdrawETH(address,uint256)\":{\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_to\":\"Address to receive the ETH balance.\"}}},\"title\":\"Drippie\",\"version\":1},\"userdoc\":{\"events\":{\"DripCreated(string,string,(uint256,address,bytes,(address,bytes,uint256)[]))\":{\"notice\":\"Emitted when a new drip is created.\"},\"DripExecuted(string,string,address,uint256)\":{\"notice\":\"Emitted when a drip is executed.\"},\"DripStatusUpdated(string,string,uint8)\":{\"notice\":\"Emitted when a drip status is updated.\"},\"ReceivedETH(address,uint256)\":{\"notice\":\"Emitted when ETH is received by this address.\"},\"WithdrewERC20(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewERC721(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewETH(address,address,uint256)\":{\"notice\":\"Emitted when ETH is withdrawn from this address.\"}},\"kind\":\"user\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"notice\":\"Sends a CALL to a target address.\"},\"DELEGATECALL(address,bytes,uint256)\":{\"notice\":\"Sends a DELEGATECALL to a target address.\"},\"create(string,(uint256,address,bytes,(address,bytes,uint256)[]))\":{\"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.\"},\"drip(string)\":{\"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.\"},\"drips(string)\":{\"notice\":\"Maps from drip names to drip states.\"},\"executable(string)\":{\"notice\":\"Checks if a given drip is executable.\"},\"status(string,uint8)\":{\"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.\"},\"withdrawERC20(address,address)\":{\"notice\":\"Withdraws full ERC20 balance to the recipient.\"},\"withdrawERC20(address,address,uint256)\":{\"notice\":\"Withdraws partial ERC20 balance to the recipient.\"},\"withdrawERC721(address,address,uint256)\":{\"notice\":\"Withdraws ERC721 token to the recipient.\"},\"withdrawETH(address)\":{\"notice\":\"Withdraws full ETH balance to the recipient.\"},\"withdrawETH(address,uint256)\":{\"notice\":\"Withdraws partial ETH balance to the recipient.\"}},\"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.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/Drippie.sol\":\"Drippie\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@rari-capital/solmate/src/auth/Owned.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Simple single owner authorization mixin.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\\nabstract contract Owned {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event OwnerUpdated(address indexed user, address indexed newOwner);\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n address public owner;\\n\\n modifier onlyOwner() virtual {\\n require(msg.sender == owner, \\\"UNAUTHORIZED\\\");\\n\\n _;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(address _owner) {\\n owner = _owner;\\n\\n emit OwnerUpdated(address(0), _owner);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function setOwner(address newOwner) public virtual onlyOwner {\\n owner = newOwner;\\n\\n emit OwnerUpdated(msg.sender, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7e91c80b0dd1a14a19cb9e661b99924043adab6d9d893bbfcf3a6a3dc23a6743\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\\nabstract contract ERC20 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n uint8 public immutable decimals;\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) public balanceOf;\\n\\n mapping(address => mapping(address => uint256)) public allowance;\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 internal immutable INITIAL_CHAIN_ID;\\n\\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\\n\\n mapping(address => uint256) public nonces;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n uint8 _decimals\\n ) {\\n name = _name;\\n symbol = _symbol;\\n decimals = _decimals;\\n\\n INITIAL_CHAIN_ID = block.chainid;\\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 amount) public virtual returns (bool) {\\n allowance[msg.sender][spender] = amount;\\n\\n emit Approval(msg.sender, spender, amount);\\n\\n return true;\\n }\\n\\n function transfer(address to, uint256 amount) public virtual returns (bool) {\\n balanceOf[msg.sender] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(msg.sender, to, amount);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual returns (bool) {\\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\\n\\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\\n\\n balanceOf[from] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n return true;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(deadline >= block.timestamp, \\\"PERMIT_DEADLINE_EXPIRED\\\");\\n\\n // Unchecked because the only math done is incrementing\\n // the owner's nonce which cannot realistically overflow.\\n unchecked {\\n address recoveredAddress = ecrecover(\\n keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\",\\n DOMAIN_SEPARATOR(),\\n keccak256(\\n abi.encode(\\n keccak256(\\n \\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\"\\n ),\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n )\\n ),\\n v,\\n r,\\n s\\n );\\n\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"INVALID_SIGNER\\\");\\n\\n allowance[recoveredAddress][spender] = value;\\n }\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\\n }\\n\\n function computeDomainSeparator() internal view virtual returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name)),\\n keccak256(\\\"1\\\"),\\n block.chainid,\\n address(this)\\n )\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 amount) internal virtual {\\n totalSupply += amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(address(0), to, amount);\\n }\\n\\n function _burn(address from, uint256 amount) internal virtual {\\n balanceOf[from] -= amount;\\n\\n // Cannot underflow because a user's balance\\n // will never be larger than the total supply.\\n unchecked {\\n totalSupply -= amount;\\n }\\n\\n emit Transfer(from, address(0), amount);\\n }\\n}\\n\",\"keccak256\":\"0x0240f7703cff32a61ee3e9fbb339e09a944260432a9ef37debf3692b1a6c8049\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\\n\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE/LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n function tokenURI(uint256 id) public view virtual returns (string memory);\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 BALANCE/OWNER STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) internal _ownerOf;\\n\\n mapping(address => uint256) internal _balanceOf;\\n\\n function ownerOf(uint256 id) public view virtual returns (address owner) {\\n require((owner = _ownerOf[id]) != address(0), \\\"NOT_MINTED\\\");\\n }\\n\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n require(owner != address(0), \\\"ZERO_ADDRESS\\\");\\n\\n return _balanceOf[owner];\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 APPROVAL STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) public getApproved;\\n\\n mapping(address => mapping(address => bool)) public isApprovedForAll;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(string memory _name, string memory _symbol) {\\n name = _name;\\n symbol = _symbol;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 id) public virtual {\\n address owner = _ownerOf[id];\\n\\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \\\"NOT_AUTHORIZED\\\");\\n\\n getApproved[id] = spender;\\n\\n emit Approval(owner, spender, id);\\n }\\n\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n isApprovedForAll[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(msg.sender, operator, approved);\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n require(from == _ownerOf[id], \\\"WRONG_FROM\\\");\\n\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(\\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\\n \\\"NOT_AUTHORIZED\\\"\\n );\\n\\n // Underflow of the sender's balance is impossible because we check for\\n // ownership above and the recipient's balance can't realistically overflow.\\n unchecked {\\n _balanceOf[from]--;\\n\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n delete getApproved[id];\\n\\n emit Transfer(from, to, id);\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n bytes calldata data\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC165 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return\\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 id) internal virtual {\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(_ownerOf[id] == address(0), \\\"ALREADY_MINTED\\\");\\n\\n // Counter overflow is incredibly unrealistic.\\n unchecked {\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n emit Transfer(address(0), to, id);\\n }\\n\\n function _burn(uint256 id) internal virtual {\\n address owner = _ownerOf[id];\\n\\n require(owner != address(0), \\\"NOT_MINTED\\\");\\n\\n // Ownership check above ensures no underflow.\\n unchecked {\\n _balanceOf[owner]--;\\n }\\n\\n delete _ownerOf[id];\\n\\n delete getApproved[id];\\n\\n emit Transfer(owner, address(0), id);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL SAFE MINT LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _safeMint(address to, uint256 id) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function _safeMint(\\n address to,\\n uint256 id,\\n bytes memory data\\n ) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n}\\n\\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721TokenReceiver {\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external virtual returns (bytes4) {\\n return ERC721TokenReceiver.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0xb59c7c25eca386f39da4819a9f70f89b73b7583d5f5127a83ffe5339800b1183\",\"license\":\"AGPL-3.0-only\"},\"contracts/universal/AssetReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { ERC20 } from \\\"@rari-capital/solmate/src/tokens/ERC20.sol\\\";\\nimport { ERC721 } from \\\"@rari-capital/solmate/src/tokens/ERC721.sol\\\";\\nimport { Transactor } from \\\"./Transactor.sol\\\";\\n\\n/**\\n * @title AssetReceiver\\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\\n */\\ncontract AssetReceiver is Transactor {\\n /**\\n * @notice Emitted when ETH is received by this address.\\n *\\n * @param from Address that sent ETH to this contract.\\n */\\n event ReceivedETH(address indexed from, uint256 amount);\\n\\n /**\\n * @notice Emitted when ETH is withdrawn from this address.\\n *\\n * @param withdrawer Address that triggered the withdrawal.\\n * @param recipient Address that received the withdrawal.\\n * @param amount ETH amount withdrawn.\\n */\\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\\n\\n /**\\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\\n *\\n * @param withdrawer Address that triggered the withdrawal.\\n * @param recipient Address that received the withdrawal.\\n * @param asset Address of the token being withdrawn.\\n * @param amount ERC20 amount withdrawn.\\n */\\n event WithdrewERC20(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 amount\\n );\\n\\n /**\\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\\n *\\n * @param withdrawer Address that triggered the withdrawal.\\n * @param recipient Address that received the withdrawal.\\n * @param asset Address of the token being withdrawn.\\n * @param id Token ID being withdrawn.\\n */\\n event WithdrewERC721(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 id\\n );\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Transactor(_owner) {}\\n\\n /**\\n * @notice Make sure we can receive ETH.\\n */\\n receive() external payable {\\n emit ReceivedETH(msg.sender, msg.value);\\n }\\n\\n /**\\n * @notice Withdraws full ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n */\\n function withdrawETH(address payable _to) external onlyOwner {\\n withdrawETH(_to, address(this).balance);\\n }\\n\\n /**\\n * @notice Withdraws partial ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n * @param _amount Amount of ETH to withdraw.\\n */\\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\\n // slither-disable-next-line reentrancy-unlimited-gas\\n _to.transfer(_amount);\\n emit WithdrewETH(msg.sender, _to, _amount);\\n }\\n\\n /**\\n * @notice Withdraws full ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n */\\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\\n }\\n\\n /**\\n * @notice Withdraws partial ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n * @param _amount Amount of ERC20 to withdraw.\\n */\\n function withdrawERC20(\\n ERC20 _asset,\\n address _to,\\n uint256 _amount\\n ) public onlyOwner {\\n // slither-disable-next-line unchecked-transfer\\n _asset.transfer(_to, _amount);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\\n }\\n\\n /**\\n * @notice Withdraws ERC721 token to the recipient.\\n *\\n * @param _asset ERC721 token to withdraw.\\n * @param _to Address to receive the ERC721 token.\\n * @param _id Token ID of the ERC721 token to withdraw.\\n */\\n function withdrawERC721(\\n ERC721 _asset,\\n address _to,\\n uint256 _id\\n ) external onlyOwner {\\n _asset.transferFrom(address(this), _to, _id);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\\n }\\n}\\n\",\"keccak256\":\"0x3330abf055d317df2b99fdb0f51e1105d27d6f2a2819ebec5e0a1a1638203d21\",\"license\":\"MIT\"},\"contracts/universal/Transactor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Owned } from \\\"@rari-capital/solmate/src/auth/Owned.sol\\\";\\n\\n/**\\n * @title Transactor\\n * @notice Transactor is a minimal contract that can send transactions.\\n */\\ncontract Transactor is Owned {\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Owned(_owner) {}\\n\\n /**\\n * Sends a CALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @param _value ETH value to send with the call.\\n *\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function CALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas,\\n uint256 _value\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n return _target.call{ gas: _gas, value: _value }(_data);\\n }\\n\\n /**\\n * Sends a DELEGATECALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n *\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function DELEGATECALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n // slither-disable-next-line controlled-delegatecall\\n return _target.delegatecall{ gas: _gas }(_data);\\n }\\n}\\n\",\"keccak256\":\"0x6f11c33999f7f3183a9c69057040141170218a44ce0e589766a327e44c8f43f1\",\"license\":\"MIT\"},\"contracts/universal/drippie/Drippie.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { AssetReceiver } from \\\"../AssetReceiver.sol\\\";\\nimport { IDripCheck } from \\\"./IDripCheck.sol\\\";\\n\\n/**\\n * @title Drippie\\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\\n * is called a \\\"drip\\\" and can be executed according to some condition (called a dripcheck)\\n * and an execution interval. Drips cannot be executed faster than the execution interval.\\n * Drips can trigger arbitrary contract calls where the calling contract is this contract\\n * address. Drips can also send ETH value, which makes them ideal for keeping addresses\\n * sufficiently funded with ETH. Drippie is designed to be connected with smart contract\\n * automation services so that drips can be executed automatically. However, Drippie is\\n * specifically designed to be separated from these services so that trust assumptions are\\n * better compartmentalized.\\n */\\ncontract Drippie is AssetReceiver {\\n /**\\n * @notice Enum representing different status options for a given drip.\\n *\\n * @custom:value NONE Drip does not exist.\\n * @custom:value ACTIVE Drip is active and can be executed.\\n * @custom:value PAUSED Drip is paused and cannot be executed until reactivated.\\n * @custom:value ARCHIVED Drip is archived and can no longer be executed or reactivated.\\n */\\n enum DripStatus {\\n NONE,\\n ACTIVE,\\n PAUSED,\\n ARCHIVED\\n }\\n\\n /**\\n * @notice Represents a drip action.\\n */\\n struct DripAction {\\n address payable target;\\n bytes data;\\n uint256 value;\\n }\\n\\n /**\\n * @notice Represents the configuration for a given drip.\\n */\\n struct DripConfig {\\n uint256 interval;\\n IDripCheck dripcheck;\\n bytes checkparams;\\n DripAction[] actions;\\n }\\n\\n /**\\n * @notice Represents the state of an active drip.\\n */\\n struct DripState {\\n DripStatus status;\\n DripConfig config;\\n uint256 last;\\n uint256 count;\\n }\\n\\n /**\\n * @notice Emitted when a new drip is created.\\n *\\n * @param nameref Indexed name parameter (hashed).\\n * @param name Unindexed name parameter (unhashed).\\n * @param config Config for the created drip.\\n */\\n event DripCreated(\\n // Emit name twice because indexed version is hashed.\\n string indexed nameref,\\n string name,\\n DripConfig config\\n );\\n\\n /**\\n * @notice Emitted when a drip status is updated.\\n *\\n * @param nameref Indexed name parameter (hashed).\\n * @param name Unindexed name parameter (unhashed).\\n * @param status New drip status.\\n */\\n event DripStatusUpdated(\\n // Emit name twice because indexed version is hashed.\\n string indexed nameref,\\n string name,\\n DripStatus status\\n );\\n\\n /**\\n * @notice Emitted when a drip is executed.\\n *\\n * @param nameref Indexed name parameter (hashed).\\n * @param name Unindexed name parameter (unhashed).\\n * @param executor Address that executed the drip.\\n * @param timestamp Time when the drip was executed.\\n */\\n event DripExecuted(\\n // Emit name twice because indexed version is hashed.\\n string indexed nameref,\\n string name,\\n address executor,\\n uint256 timestamp\\n );\\n\\n /**\\n * @notice Maps from drip names to drip states.\\n */\\n mapping(string => DripState) public drips;\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) AssetReceiver(_owner) {}\\n\\n /**\\n * @notice Creates a new drip with the given name and configuration. Once created, drips cannot\\n * be modified in any way (this is a security measure). If you want to update a drip,\\n * simply pause (and potentially archive) the existing drip and create a new one.\\n *\\n * @param _name Name of the drip.\\n * @param _config Configuration for the drip.\\n */\\n function create(string memory _name, DripConfig memory _config) external onlyOwner {\\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\\n // will ever set the status of a drip back to NONE after it's been created. This is why\\n // archival is a separate status.\\n require(\\n drips[_name].status == DripStatus.NONE,\\n \\\"Drippie: drip with that name already exists\\\"\\n );\\n\\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\\n DripState storage state = drips[_name];\\n state.status = DripStatus.PAUSED;\\n state.config.interval = _config.interval;\\n state.config.dripcheck = _config.dripcheck;\\n state.config.checkparams = _config.checkparams;\\n\\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\\n for (uint256 i = 0; i < _config.actions.length; i++) {\\n state.config.actions.push(_config.actions[i]);\\n }\\n\\n // Tell the world!\\n emit DripCreated(_name, _name, _config);\\n }\\n\\n /**\\n * @notice Sets the status for a given drip. The behavior of this function depends on the\\n * status that the user is trying to set. A drip can always move between ACTIVE and\\n * PAUSED, but it can never move back to NONE and once ARCHIVED, it can never move back\\n * to ACTIVE or PAUSED.\\n *\\n * @param _name Name of the drip to update.\\n * @param _status New drip status.\\n */\\n function status(string memory _name, DripStatus _status) external onlyOwner {\\n // Make sure we can never set drip status back to NONE. A simple security measure to\\n // prevent accidental overwrites if this code is ever updated down the line.\\n require(\\n _status != DripStatus.NONE,\\n \\\"Drippie: drip status can never be set back to NONE after creation\\\"\\n );\\n\\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\\n // seem to be any clear reason why you would want to do this, and it may save some gas in\\n // the case of a front-end bug.\\n require(\\n drips[_name].status != DripStatus.NONE,\\n \\\"Drippie: drip with that name does not exist\\\"\\n );\\n\\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\\n // point of archiving a drip.\\n require(\\n drips[_name].status != DripStatus.ARCHIVED,\\n \\\"Drippie: drip with that name has been archived\\\"\\n );\\n\\n // Although not strictly necessary, we make sure that the status here is actually changing.\\n // This may save the client some gas if there's a front-end bug and the user accidentally\\n // tries to \\\"change\\\" the status to the same value as before.\\n require(\\n drips[_name].status != _status,\\n \\\"Drippie: cannot set drip status to same status as before\\\"\\n );\\n\\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\\n // not allow users to archive active drips so that the effects of this action are more\\n // abundantly clear.\\n if (_status == DripStatus.ARCHIVED) {\\n require(\\n drips[_name].status == DripStatus.PAUSED,\\n \\\"Drippie: drip must be paused to be archived\\\"\\n );\\n }\\n\\n // If we made it here then we can safely update the status.\\n drips[_name].status = _status;\\n emit DripStatusUpdated(_name, _name, drips[_name].status);\\n }\\n\\n /**\\n * @notice Checks if a given drip is executable.\\n *\\n * @param _name Drip to check.\\n *\\n * @return True if the drip is executable, false otherwise.\\n */\\n function executable(string memory _name) public view returns (bool) {\\n DripState storage state = drips[_name];\\n\\n // Only allow active drips to be executed, an obvious security measure.\\n require(\\n state.status == DripStatus.ACTIVE,\\n \\\"Drippie: selected drip does not exist or is not currently active\\\"\\n );\\n\\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\\n // compromised recipient to just a single drip interval, after which the drip can be paused\\n // by the owner address.\\n require(\\n state.last + state.config.interval <= block.timestamp,\\n \\\"Drippie: drip interval has not elapsed since last drip\\\"\\n );\\n\\n // Make sure we're allowed to execute this drip.\\n require(\\n state.config.dripcheck.check(state.config.checkparams),\\n \\\"Drippie: dripcheck failed so drip is not yet ready to be triggered\\\"\\n );\\n\\n // Alright, we're good to execute.\\n return true;\\n }\\n\\n /**\\n * @notice Triggers a drip. This function is deliberately left as a public function because the\\n * assumption being made here is that setting the drip to ACTIVE is an affirmative\\n * signal that the drip should be executable according to the drip parameters, drip\\n * check, and drip interval. Note that drip parameters are read entirely from the state\\n * and are not supplied as user input, so there should not be any way for a\\n * non-authorized user to influence the behavior of the drip.\\n *\\n * @param _name Name of the drip to trigger.\\n */\\n function drip(string memory _name) external {\\n DripState storage state = drips[_name];\\n\\n // Make sure the drip can be executed.\\n require(\\n executable(_name) == true,\\n \\\"Drippie: drip cannot be executed at this time, try again later\\\"\\n );\\n\\n // Update the last execution time for this drip before the call. Note that it's entirely\\n // possible for a drip to be executed multiple times per block or even multiple times\\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\\n // block (since this will then prevent re-entrancy).\\n state.last = block.timestamp;\\n\\n // Execute each action in the drip. We allow drips to have multiple actions because there\\n // are scenarios in which a contract must do multiple things atomically. For example, the\\n // contract may need to withdraw ETH from one account and then deposit that ETH into\\n // another account within the same transaction.\\n uint256 len = state.config.actions.length;\\n for (uint256 i = 0; i < len; i++) {\\n // Must be marked as \\\"storage\\\" because copying structs into memory is not yet supported\\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\\n // read what the rest of this section is doing.\\n DripAction storage action = state.config.actions[i];\\n\\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\\n // returndata.\\n // slither-disable-next-line calls-loop\\n (bool success, ) = action.target.call{ value: action.value }(action.data);\\n\\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\\n // the wrong data to the target contract), the recipient is not payable, or\\n // insufficient gas was supplied to this transaction. We revert so the drip can be\\n // fixed and triggered again later. Means we cannot emit an event to alert of the\\n // failure, but can reasonably be detected by off-chain services even without an event.\\n // Note that this forces the drip executor to supply sufficient gas to the call\\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\\n // not execute).\\n require(\\n success,\\n \\\"Drippie: drip was unsuccessful, please check your configuration for mistakes\\\"\\n );\\n }\\n\\n state.count++;\\n emit DripExecuted(_name, _name, msg.sender, block.timestamp);\\n }\\n}\\n\",\"keccak256\":\"0x6696749e45d49c5724b4d04c59fa32bfae9b2bb687ba9e78fe4cf2a148198cfc\",\"license\":\"MIT\"},\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xbf1b9be6bbcbbbd2268023a169382c9a62a58a343420e4bc4494a9f463f86042\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50604051620026003803806200260083398101604081905262000034916200008c565b600080546001600160a01b0319166001600160a01b03831690811782556040518392839283929091907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908290a350505050620000be565b6000602082840312156200009f57600080fd5b81516001600160a01b0381168114620000b757600080fd5b9392505050565b61253280620000ce6000396000f3fe6080604052600436106100e15760003560e01c8063690d83201161007f5780639456fbcc116100595780639456fbcc146102b05780639bc94d01146102d05780639e73dbea146102f0578063fc3e3eba1461030357600080fd5b8063690d83201461021e5780636f0488131461023e5780638da5cb5b1461025e57600080fd5b80634782f779116100bb5780634782f779146101845780634d7fba6e146101a45780635cef8b4a146101dd57806367148cd2146101fe57600080fd5b806313af4035146101225780634025feb21461014457806344004cc11461016457600080fd5b3661011d5760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561012e57600080fd5b5061014261013d3660046119e8565b610333565b005b34801561015057600080fd5b5061014261015f366004611a0c565b61040f565b34801561017057600080fd5b5061014261017f366004611a0c565b610587565b34801561019057600080fd5b5061014261019f366004611a4d565b6106fe565b3480156101b057600080fd5b506101c46101bf366004611b95565b6107fa565b6040516101d49493929190611d60565b60405180910390f35b6101f06101eb366004611d93565b610a18565b6040516101d4929190611dec565b34801561020a57600080fd5b50610142610219366004611b95565b610af7565b34801561022a57600080fd5b506101426102393660046119e8565b610d6e565b34801561024a57600080fd5b50610142610259366004611e07565b610de2565b34801561026a57600080fd5b5060005461028b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d4565b3480156102bc57600080fd5b506101426102cb366004611fad565b6110b9565b3480156102dc57600080fd5b506101426102eb366004611fe6565b6111ba565b6101f06102fe366004612031565b61166c565b34801561030f57600080fd5b5061032361031e366004611b95565b61174f565b60405190151581526020016101d4565b60005473ffffffffffffffffffffffffffffffffffffffff16331461039f5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104765760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b1580156104ec57600080fd5b505af1158015610500573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a88460405161057a91815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ee5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015610663573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106879190612091565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa8460405161057a91815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107655760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f193505050501580156107a8573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b805160208183018101805160018083529383019483019490942093905282546040805160808101825293850180548552600286015473ffffffffffffffffffffffffffffffffffffffff169385019390935260038501805460ff9093169594939291840191610868906120b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610894906120b3565b80156108e15780601f106108b6576101008083540402835291602001916108e1565b820191906000526020600020905b8154815290600101906020018083116108c457829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015610a00576000848152602090819020604080516060810190915260038502909101805473ffffffffffffffffffffffffffffffffffffffff1682526001810180549293919291840191610965906120b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610991906120b3565b80156109de5780601f106109b3576101008083540402835291602001916109de565b820191906000526020600020905b8154815290600101906020018083116109c157829003601f168201915b505050505081526020016002820154815250508152602001906001019061090f565b50505091525050600582015460069092015490919084565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610a835760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610aa99190612106565b6000604051808303818686f4925050503d8060008114610ae5576040519150601f19603f3d011682016040523d82523d6000602084013e610aea565b606091505b5091509150935093915050565b6000600182604051610b099190612106565b90815260200160405180910390209050610b228261174f565b1515600114610b995760405162461bcd60e51b815260206004820152603e60248201527f447269707069653a20647269702063616e6e6f7420626520657865637574656460448201527f20617420746869732074696d652c2074727920616761696e206c6174657200006064820152608401610396565b426005820155600481015460005b81811015610d00576000836001016003018281548110610bc957610bc9612122565b6000918252602082206003909102018054600282015460405192945073ffffffffffffffffffffffffffffffffffffffff90911691610c0c906001860190612151565b60006040518083038185875af1925050503d8060008114610c49576040519150601f19603f3d011682016040523d82523d6000602084013e610c4e565b606091505b5050905080610ceb5760405162461bcd60e51b815260206004820152604c60248201527f447269707069653a20647269702077617320756e7375636365737366756c2c2060448201527f706c6561736520636865636b20796f757220636f6e66696775726174696f6e2060648201527f666f72206d697374616b65730000000000000000000000000000000000000000608482015260a401610396565b50508080610cf890612214565b915050610ba7565b50600682018054906000610d1383612214565b919050555082604051610d269190612106565b60405180910390207fea21435419aad9c54a9d90e2522b6f60bd566401f36fcef661f5f5a28cc0d2c6843342604051610d619392919061224c565b60405180910390a2505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610dd55760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b610ddf81476106fe565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e495760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6000600183604051610e5b9190612106565b9081526040519081900360200190205460ff166003811115610e7f57610e7f611bd2565b14610ef25760405162461bcd60e51b815260206004820152602b60248201527f447269707069653a206472697020776974682074686174206e616d6520616c7260448201527f65616479206578697374730000000000000000000000000000000000000000006064820152608401610396565b6000600183604051610f049190612106565b908152604080516020928190038301902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600290811782558551600183015592850151928101805473ffffffffffffffffffffffffffffffffffffffff9094167fffffffffffffffffffffffff0000000000000000000000000000000000000000909416939093179092558301519091506003820190610fa890826122d6565b5060005b826060015151811015611071578160010160030183606001518281518110610fd657610fd6612122565b602090810291909101810151825460018082018555600094855293839020825160039092020180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117815591810151909282019061105190826122d6565b50604082015181600201555050808061106990612214565b915050610fac565b50826040516110809190612106565b60405180910390207f49c9c8da28762ffee6f3f2f37f8f4ebcd85afcb02e1bb496dc95cf47c96380368484604051610d619291906123d2565b60005473ffffffffffffffffffffffffffffffffffffffff1633146111205760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526111b6908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611192573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017f9190612400565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146112215760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b600081600381111561123557611235611bd2565b036112ce5760405162461bcd60e51b815260206004820152604160248201527f447269707069653a2064726970207374617475732063616e206e65766572206260448201527f6520736574206261636b20746f204e4f4e45206166746572206372656174696f60648201527f6e00000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b60006001836040516112e09190612106565b9081526040519081900360200190205460ff16600381111561130457611304611bd2565b036113775760405162461bcd60e51b815260206004820152602b60248201527f447269707069653a206472697020776974682074686174206e616d6520646f6560448201527f73206e6f742065786973740000000000000000000000000000000000000000006064820152608401610396565b60036001836040516113899190612106565b9081526040519081900360200190205460ff1660038111156113ad576113ad611bd2565b036114205760405162461bcd60e51b815260206004820152602e60248201527f447269707069653a206472697020776974682074686174206e616d652068617360448201527f206265656e2061726368697665640000000000000000000000000000000000006064820152608401610396565b80600381111561143257611432611bd2565b6001836040516114429190612106565b9081526040519081900360200190205460ff16600381111561146657611466611bd2565b036114d95760405162461bcd60e51b815260206004820152603860248201527f447269707069653a2063616e6e6f74207365742064726970207374617475732060448201527f746f2073616d6520737461747573206173206265666f726500000000000000006064820152608401610396565b60038160038111156114ed576114ed611bd2565b0361159b5760026001836040516115049190612106565b9081526040519081900360200190205460ff16600381111561152857611528611bd2565b1461159b5760405162461bcd60e51b815260206004820152602b60248201527f447269707069653a2064726970206d7573742062652070617573656420746f2060448201527f62652061726368697665640000000000000000000000000000000000000000006064820152608401610396565b806001836040516115ac9190612106565b90815260405190819003602001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156115f3576115f3611bd2565b0217905550816040516116069190612106565b60405180910390207f407cb3ad05e60ec498fb39417c7a4f6b82d5ba80f82fe512a37b02c93181a2a1836001856040516116409190612106565b90815260405190819003602001812054611660929160ff90911690612419565b60405180910390a25050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146116d75760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8573ffffffffffffffffffffffffffffffffffffffff168484876040516116fe9190612106565b600060405180830381858888f193505050503d806000811461173c576040519150601f19603f3d011682016040523d82523d6000602084013e611741565b606091505b509150915094509492505050565b6000806001836040516117629190612106565b90815260405190819003602001902090506001815460ff16600381111561178b5761178b611bd2565b14611800576040805162461bcd60e51b81526020600482015260248101919091527f447269707069653a2073656c6563746564206472697020646f6573206e6f742060448201527f6578697374206f72206973206e6f742063757272656e746c79206163746976656064820152608401610396565b6001810154600582015442916118159161243b565b11156118895760405162461bcd60e51b815260206004820152603660248201527f447269707069653a206472697020696e74657276616c20686173206e6f74206560448201527f6c61707365642073696e6365206c6173742064726970000000000000000000006064820152608401610396565b60028101546040517fc64b3bb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063c64b3bb5906118e4906003850190600401612453565b602060405180830381865afa158015611901573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119259190612091565b6119bd5760405162461bcd60e51b815260206004820152604260248201527f447269707069653a2064726970636865636b206661696c656420736f2064726960448201527f70206973206e6f742079657420726561647920746f206265207472696767657260648201527f6564000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b50600192915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ddf57600080fd5b6000602082840312156119fa57600080fd5b8135611a05816119c6565b9392505050565b600080600060608486031215611a2157600080fd5b8335611a2c816119c6565b92506020840135611a3c816119c6565b929592945050506040919091013590565b60008060408385031215611a6057600080fd5b8235611a6b816119c6565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715611acb57611acb611a79565b60405290565b6040516060810167ffffffffffffffff81118282101715611acb57611acb611a79565b604051601f8201601f1916810167ffffffffffffffff81118282101715611b1d57611b1d611a79565b604052919050565b600082601f830112611b3657600080fd5b813567ffffffffffffffff811115611b5057611b50611a79565b611b636020601f19601f84011601611af4565b818152846020838601011115611b7857600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215611ba757600080fd5b813567ffffffffffffffff811115611bbe57600080fd5b611bca84828501611b25565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110611c38577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60005b83811015611c57578181015183820152602001611c3f565b83811115611c66576000848401525b50505050565b60008151808452611c84816020860160208601611c3c565b601f01601f19169290920160200192915050565b80518252600060208083015173ffffffffffffffffffffffffffffffffffffffff808216838701526040915081850151608083880152611cdb6080880182611c6c565b9050606080870151888303828a01528281518085528785019150878160051b860101888401935060005b82811015611d5057601f1987830301845284518881511683528a810151878c850152611d3388850182611c6c565b918b0151938b0193909352948a0194938a01939150600101611d05565b509b9a5050505050505050505050565b611d6a8186611c01565b608060208201526000611d806080830186611c98565b6040830194909452506060015292915050565b600080600060608486031215611da857600080fd5b8335611db3816119c6565b9250602084013567ffffffffffffffff811115611dcf57600080fd5b611ddb86828701611b25565b925050604084013590509250925092565b8215158152604060208201526000611bca6040830184611c6c565b60008060408385031215611e1a57600080fd5b823567ffffffffffffffff80821115611e3257600080fd5b611e3e86838701611b25565b9350602091508185013581811115611e5557600080fd5b850160808188031215611e6757600080fd5b611e6f611aa8565b8135815283820135611e80816119c6565b81850152604082013583811115611e9657600080fd5b611ea289828501611b25565b604083015250606082013583811115611eba57600080fd5b80830192505087601f830112611ecf57600080fd5b813583811115611ee157611ee1611a79565b8060051b611ef0868201611af4565b918252838101860191868101908b841115611f0a57600080fd5b87860192505b83831015611f9757823587811115611f285760008081fd5b86016060818e03601f19011215611f3f5760008081fd5b611f47611ad1565b89820135611f54816119c6565b8152604082013589811115611f695760008081fd5b611f778f8c83860101611b25565b828c01525060609190910135604082015282529187019190870190611f10565b6060850152509699919850909650505050505050565b60008060408385031215611fc057600080fd5b8235611fcb816119c6565b91506020830135611fdb816119c6565b809150509250929050565b60008060408385031215611ff957600080fd5b823567ffffffffffffffff81111561201057600080fd5b61201c85828601611b25565b925050602083013560048110611fdb57600080fd5b6000806000806080858703121561204757600080fd5b8435612052816119c6565b9350602085013567ffffffffffffffff81111561206e57600080fd5b61207a87828801611b25565b949794965050505060408301359260600135919050565b6000602082840312156120a357600080fd5b81518015158114611a0557600080fd5b600181811c908216806120c757607f821691505b602082108103612100577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008251612118818460208701611c3c565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080835461215f816120b3565b6001828116801561217757600181146121aa576121d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00841687528215158302870194506121d9565b8760005260208060002060005b858110156121d05781548a8201529084019082016121b7565b50505082870194505b50929695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612245576122456121e5565b5060010190565b60608152600061225f6060830186611c6c565b73ffffffffffffffffffffffffffffffffffffffff9490941660208301525060400152919050565b601f8211156122d157600081815260208120601f850160051c810160208610156122ae5750805b601f850160051c820191505b818110156122cd578281556001016122ba565b5050505b505050565b815167ffffffffffffffff8111156122f0576122f0611a79565b612304816122fe84546120b3565b84612287565b602080601f83116001811461235757600084156123215750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556122cd565b600085815260208120601f198616915b8281101561238657888601518255948401946001909101908401612367565b50858210156123c257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b6040815260006123e56040830185611c6c565b82810360208401526123f78185611c98565b95945050505050565b60006020828403121561241257600080fd5b5051919050565b60408152600061242c6040830185611c6c565b9050611a056020830184611c01565b6000821982111561244e5761244e6121e5565b500190565b6000602080835260008454612467816120b3565b8084870152604060018084166000811461248857600181146124c0576124ee565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506124ee565b896000528660002060005b858110156124e65781548b82018601529083019088016124cb565b8a0184019650505b50939897505050505050505056fea26469706673582212209e2c642d826f29e188c7d7b6e9595445cf633c5a5dd84422c15db472d859adff64736f6c634300080f0033", - "deployedBytecode": "0x6080604052600436106100e15760003560e01c8063690d83201161007f5780639456fbcc116100595780639456fbcc146102b05780639bc94d01146102d05780639e73dbea146102f0578063fc3e3eba1461030357600080fd5b8063690d83201461021e5780636f0488131461023e5780638da5cb5b1461025e57600080fd5b80634782f779116100bb5780634782f779146101845780634d7fba6e146101a45780635cef8b4a146101dd57806367148cd2146101fe57600080fd5b806313af4035146101225780634025feb21461014457806344004cc11461016457600080fd5b3661011d5760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561012e57600080fd5b5061014261013d3660046119e8565b610333565b005b34801561015057600080fd5b5061014261015f366004611a0c565b61040f565b34801561017057600080fd5b5061014261017f366004611a0c565b610587565b34801561019057600080fd5b5061014261019f366004611a4d565b6106fe565b3480156101b057600080fd5b506101c46101bf366004611b95565b6107fa565b6040516101d49493929190611d60565b60405180910390f35b6101f06101eb366004611d93565b610a18565b6040516101d4929190611dec565b34801561020a57600080fd5b50610142610219366004611b95565b610af7565b34801561022a57600080fd5b506101426102393660046119e8565b610d6e565b34801561024a57600080fd5b50610142610259366004611e07565b610de2565b34801561026a57600080fd5b5060005461028b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d4565b3480156102bc57600080fd5b506101426102cb366004611fad565b6110b9565b3480156102dc57600080fd5b506101426102eb366004611fe6565b6111ba565b6101f06102fe366004612031565b61166c565b34801561030f57600080fd5b5061032361031e366004611b95565b61174f565b60405190151581526020016101d4565b60005473ffffffffffffffffffffffffffffffffffffffff16331461039f5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104765760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b1580156104ec57600080fd5b505af1158015610500573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a88460405161057a91815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ee5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015610663573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106879190612091565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa8460405161057a91815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107655760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f193505050501580156107a8573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b805160208183018101805160018083529383019483019490942093905282546040805160808101825293850180548552600286015473ffffffffffffffffffffffffffffffffffffffff169385019390935260038501805460ff9093169594939291840191610868906120b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610894906120b3565b80156108e15780601f106108b6576101008083540402835291602001916108e1565b820191906000526020600020905b8154815290600101906020018083116108c457829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015610a00576000848152602090819020604080516060810190915260038502909101805473ffffffffffffffffffffffffffffffffffffffff1682526001810180549293919291840191610965906120b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610991906120b3565b80156109de5780601f106109b3576101008083540402835291602001916109de565b820191906000526020600020905b8154815290600101906020018083116109c157829003601f168201915b505050505081526020016002820154815250508152602001906001019061090f565b50505091525050600582015460069092015490919084565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610a835760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610aa99190612106565b6000604051808303818686f4925050503d8060008114610ae5576040519150601f19603f3d011682016040523d82523d6000602084013e610aea565b606091505b5091509150935093915050565b6000600182604051610b099190612106565b90815260200160405180910390209050610b228261174f565b1515600114610b995760405162461bcd60e51b815260206004820152603e60248201527f447269707069653a20647269702063616e6e6f7420626520657865637574656460448201527f20617420746869732074696d652c2074727920616761696e206c6174657200006064820152608401610396565b426005820155600481015460005b81811015610d00576000836001016003018281548110610bc957610bc9612122565b6000918252602082206003909102018054600282015460405192945073ffffffffffffffffffffffffffffffffffffffff90911691610c0c906001860190612151565b60006040518083038185875af1925050503d8060008114610c49576040519150601f19603f3d011682016040523d82523d6000602084013e610c4e565b606091505b5050905080610ceb5760405162461bcd60e51b815260206004820152604c60248201527f447269707069653a20647269702077617320756e7375636365737366756c2c2060448201527f706c6561736520636865636b20796f757220636f6e66696775726174696f6e2060648201527f666f72206d697374616b65730000000000000000000000000000000000000000608482015260a401610396565b50508080610cf890612214565b915050610ba7565b50600682018054906000610d1383612214565b919050555082604051610d269190612106565b60405180910390207fea21435419aad9c54a9d90e2522b6f60bd566401f36fcef661f5f5a28cc0d2c6843342604051610d619392919061224c565b60405180910390a2505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610dd55760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b610ddf81476106fe565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e495760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6000600183604051610e5b9190612106565b9081526040519081900360200190205460ff166003811115610e7f57610e7f611bd2565b14610ef25760405162461bcd60e51b815260206004820152602b60248201527f447269707069653a206472697020776974682074686174206e616d6520616c7260448201527f65616479206578697374730000000000000000000000000000000000000000006064820152608401610396565b6000600183604051610f049190612106565b908152604080516020928190038301902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600290811782558551600183015592850151928101805473ffffffffffffffffffffffffffffffffffffffff9094167fffffffffffffffffffffffff0000000000000000000000000000000000000000909416939093179092558301519091506003820190610fa890826122d6565b5060005b826060015151811015611071578160010160030183606001518281518110610fd657610fd6612122565b602090810291909101810151825460018082018555600094855293839020825160039092020180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117815591810151909282019061105190826122d6565b50604082015181600201555050808061106990612214565b915050610fac565b50826040516110809190612106565b60405180910390207f49c9c8da28762ffee6f3f2f37f8f4ebcd85afcb02e1bb496dc95cf47c96380368484604051610d619291906123d2565b60005473ffffffffffffffffffffffffffffffffffffffff1633146111205760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526111b6908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611192573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017f9190612400565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146112215760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b600081600381111561123557611235611bd2565b036112ce5760405162461bcd60e51b815260206004820152604160248201527f447269707069653a2064726970207374617475732063616e206e65766572206260448201527f6520736574206261636b20746f204e4f4e45206166746572206372656174696f60648201527f6e00000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b60006001836040516112e09190612106565b9081526040519081900360200190205460ff16600381111561130457611304611bd2565b036113775760405162461bcd60e51b815260206004820152602b60248201527f447269707069653a206472697020776974682074686174206e616d6520646f6560448201527f73206e6f742065786973740000000000000000000000000000000000000000006064820152608401610396565b60036001836040516113899190612106565b9081526040519081900360200190205460ff1660038111156113ad576113ad611bd2565b036114205760405162461bcd60e51b815260206004820152602e60248201527f447269707069653a206472697020776974682074686174206e616d652068617360448201527f206265656e2061726368697665640000000000000000000000000000000000006064820152608401610396565b80600381111561143257611432611bd2565b6001836040516114429190612106565b9081526040519081900360200190205460ff16600381111561146657611466611bd2565b036114d95760405162461bcd60e51b815260206004820152603860248201527f447269707069653a2063616e6e6f74207365742064726970207374617475732060448201527f746f2073616d6520737461747573206173206265666f726500000000000000006064820152608401610396565b60038160038111156114ed576114ed611bd2565b0361159b5760026001836040516115049190612106565b9081526040519081900360200190205460ff16600381111561152857611528611bd2565b1461159b5760405162461bcd60e51b815260206004820152602b60248201527f447269707069653a2064726970206d7573742062652070617573656420746f2060448201527f62652061726368697665640000000000000000000000000000000000000000006064820152608401610396565b806001836040516115ac9190612106565b90815260405190819003602001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156115f3576115f3611bd2565b0217905550816040516116069190612106565b60405180910390207f407cb3ad05e60ec498fb39417c7a4f6b82d5ba80f82fe512a37b02c93181a2a1836001856040516116409190612106565b90815260405190819003602001812054611660929160ff90911690612419565b60405180910390a25050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146116d75760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610396565b8573ffffffffffffffffffffffffffffffffffffffff168484876040516116fe9190612106565b600060405180830381858888f193505050503d806000811461173c576040519150601f19603f3d011682016040523d82523d6000602084013e611741565b606091505b509150915094509492505050565b6000806001836040516117629190612106565b90815260405190819003602001902090506001815460ff16600381111561178b5761178b611bd2565b14611800576040805162461bcd60e51b81526020600482015260248101919091527f447269707069653a2073656c6563746564206472697020646f6573206e6f742060448201527f6578697374206f72206973206e6f742063757272656e746c79206163746976656064820152608401610396565b6001810154600582015442916118159161243b565b11156118895760405162461bcd60e51b815260206004820152603660248201527f447269707069653a206472697020696e74657276616c20686173206e6f74206560448201527f6c61707365642073696e6365206c6173742064726970000000000000000000006064820152608401610396565b60028101546040517fc64b3bb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063c64b3bb5906118e4906003850190600401612453565b602060405180830381865afa158015611901573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119259190612091565b6119bd5760405162461bcd60e51b815260206004820152604260248201527f447269707069653a2064726970636865636b206661696c656420736f2064726960448201527f70206973206e6f742079657420726561647920746f206265207472696767657260648201527f6564000000000000000000000000000000000000000000000000000000000000608482015260a401610396565b50600192915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ddf57600080fd5b6000602082840312156119fa57600080fd5b8135611a05816119c6565b9392505050565b600080600060608486031215611a2157600080fd5b8335611a2c816119c6565b92506020840135611a3c816119c6565b929592945050506040919091013590565b60008060408385031215611a6057600080fd5b8235611a6b816119c6565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715611acb57611acb611a79565b60405290565b6040516060810167ffffffffffffffff81118282101715611acb57611acb611a79565b604051601f8201601f1916810167ffffffffffffffff81118282101715611b1d57611b1d611a79565b604052919050565b600082601f830112611b3657600080fd5b813567ffffffffffffffff811115611b5057611b50611a79565b611b636020601f19601f84011601611af4565b818152846020838601011115611b7857600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215611ba757600080fd5b813567ffffffffffffffff811115611bbe57600080fd5b611bca84828501611b25565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110611c38577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60005b83811015611c57578181015183820152602001611c3f565b83811115611c66576000848401525b50505050565b60008151808452611c84816020860160208601611c3c565b601f01601f19169290920160200192915050565b80518252600060208083015173ffffffffffffffffffffffffffffffffffffffff808216838701526040915081850151608083880152611cdb6080880182611c6c565b9050606080870151888303828a01528281518085528785019150878160051b860101888401935060005b82811015611d5057601f1987830301845284518881511683528a810151878c850152611d3388850182611c6c565b918b0151938b0193909352948a0194938a01939150600101611d05565b509b9a5050505050505050505050565b611d6a8186611c01565b608060208201526000611d806080830186611c98565b6040830194909452506060015292915050565b600080600060608486031215611da857600080fd5b8335611db3816119c6565b9250602084013567ffffffffffffffff811115611dcf57600080fd5b611ddb86828701611b25565b925050604084013590509250925092565b8215158152604060208201526000611bca6040830184611c6c565b60008060408385031215611e1a57600080fd5b823567ffffffffffffffff80821115611e3257600080fd5b611e3e86838701611b25565b9350602091508185013581811115611e5557600080fd5b850160808188031215611e6757600080fd5b611e6f611aa8565b8135815283820135611e80816119c6565b81850152604082013583811115611e9657600080fd5b611ea289828501611b25565b604083015250606082013583811115611eba57600080fd5b80830192505087601f830112611ecf57600080fd5b813583811115611ee157611ee1611a79565b8060051b611ef0868201611af4565b918252838101860191868101908b841115611f0a57600080fd5b87860192505b83831015611f9757823587811115611f285760008081fd5b86016060818e03601f19011215611f3f5760008081fd5b611f47611ad1565b89820135611f54816119c6565b8152604082013589811115611f695760008081fd5b611f778f8c83860101611b25565b828c01525060609190910135604082015282529187019190870190611f10565b6060850152509699919850909650505050505050565b60008060408385031215611fc057600080fd5b8235611fcb816119c6565b91506020830135611fdb816119c6565b809150509250929050565b60008060408385031215611ff957600080fd5b823567ffffffffffffffff81111561201057600080fd5b61201c85828601611b25565b925050602083013560048110611fdb57600080fd5b6000806000806080858703121561204757600080fd5b8435612052816119c6565b9350602085013567ffffffffffffffff81111561206e57600080fd5b61207a87828801611b25565b949794965050505060408301359260600135919050565b6000602082840312156120a357600080fd5b81518015158114611a0557600080fd5b600181811c908216806120c757607f821691505b602082108103612100577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008251612118818460208701611c3c565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080835461215f816120b3565b6001828116801561217757600181146121aa576121d9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00841687528215158302870194506121d9565b8760005260208060002060005b858110156121d05781548a8201529084019082016121b7565b50505082870194505b50929695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612245576122456121e5565b5060010190565b60608152600061225f6060830186611c6c565b73ffffffffffffffffffffffffffffffffffffffff9490941660208301525060400152919050565b601f8211156122d157600081815260208120601f850160051c810160208610156122ae5750805b601f850160051c820191505b818110156122cd578281556001016122ba565b5050505b505050565b815167ffffffffffffffff8111156122f0576122f0611a79565b612304816122fe84546120b3565b84612287565b602080601f83116001811461235757600084156123215750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556122cd565b600085815260208120601f198616915b8281101561238657888601518255948401946001909101908401612367565b50858210156123c257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b6040815260006123e56040830185611c6c565b82810360208401526123f78185611c98565b95945050505050565b60006020828403121561241257600080fd5b5051919050565b60408152600061242c6040830185611c6c565b9050611a056020830184611c01565b6000821982111561244e5761244e6121e5565b500190565b6000602080835260008454612467816120b3565b8084870152604060018084166000811461248857600181146124c0576124ee565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506124ee565b896000528660002060005b858110156124e65781548b82018601529083019088016124cb565b8a0184019650505b50939897505050505050505056fea26469706673582212209e2c642d826f29e188c7d7b6e9595445cf633c5a5dd84422c15db472d859adff64736f6c634300080f0033", - "devdoc": { - "events": { - "DripCreated(string,string,(uint256,address,bytes,(address,bytes,uint256)[]))": { - "params": { - "config": "Config for the created drip.", - "name": "Unindexed name parameter (unhashed).", - "nameref": "Indexed name parameter (hashed)." - } - }, - "DripExecuted(string,string,address,uint256)": { - "params": { - "executor": "Address that executed the drip.", - "name": "Unindexed name parameter (unhashed).", - "nameref": "Indexed name parameter (hashed).", - "timestamp": "Time when the drip was executed." - } - }, - "DripStatusUpdated(string,string,uint8)": { - "params": { - "name": "Unindexed name parameter (unhashed).", - "nameref": "Indexed name parameter (hashed).", - "status": "New drip status." - } - } - }, - "kind": "dev", - "methods": { - "CALL(address,bytes,uint256,uint256)": { - "params": { - "_data": "Data to send with the call.", - "_gas": "Amount of gas to send with the call.", - "_target": "Address to call.", - "_value": "ETH value to send with the call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "DELEGATECALL(address,bytes,uint256)": { - "params": { - "_data": "Data to send with the call.", - "_gas": "Amount of gas to send with the call.", - "_target": "Address to call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "constructor": { - "params": { - "_owner": "Initial contract owner." - } - }, - "create(string,(uint256,address,bytes,(address,bytes,uint256)[]))": { - "params": { - "_config": "Configuration for the drip.", - "_name": "Name of the drip." - } - }, - "drip(string)": { - "params": { - "_name": "Name of the drip to trigger." - } - }, - "executable(string)": { - "params": { - "_name": "Drip to check." - }, - "returns": { - "_0": "True if the drip is executable, false otherwise." - } - }, - "status(string,uint8)": { - "params": { - "_name": "Name of the drip to update.", - "_status": "New drip status." - } - }, - "withdrawERC20(address,address)": { - "params": { - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC20(address,address,uint256)": { - "params": { - "_amount": "Amount of ERC20 to withdraw.", - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC721(address,address,uint256)": { - "params": { - "_asset": "ERC721 token to withdraw.", - "_id": "Token ID of the ERC721 token to withdraw.", - "_to": "Address to receive the ERC721 token." - } - }, - "withdrawETH(address)": { - "params": { - "_to": "Address to receive the ETH balance." - } - }, - "withdrawETH(address,uint256)": { - "params": { - "_amount": "Amount of ETH to withdraw.", - "_to": "Address to receive the ETH balance." - } - } - }, - "title": "Drippie", - "version": 1 - }, - "userdoc": { - "events": { - "DripCreated(string,string,(uint256,address,bytes,(address,bytes,uint256)[]))": { - "notice": "Emitted when a new drip is created." - }, - "DripExecuted(string,string,address,uint256)": { - "notice": "Emitted when a drip is executed." - }, - "DripStatusUpdated(string,string,uint8)": { - "notice": "Emitted when a drip status is updated." - }, - "ReceivedETH(address,uint256)": { - "notice": "Emitted when ETH is received by this address." - }, - "WithdrewERC20(address,address,address,uint256)": { - "notice": "Emitted when ERC20 tokens are withdrawn from this address." - }, - "WithdrewERC721(address,address,address,uint256)": { - "notice": "Emitted when ERC20 tokens are withdrawn from this address." - }, - "WithdrewETH(address,address,uint256)": { - "notice": "Emitted when ETH is withdrawn from this address." - } - }, - "kind": "user", - "methods": { - "CALL(address,bytes,uint256,uint256)": { - "notice": "Sends a CALL to a target address." - }, - "DELEGATECALL(address,bytes,uint256)": { - "notice": "Sends a DELEGATECALL to a target address." - }, - "create(string,(uint256,address,bytes,(address,bytes,uint256)[]))": { - "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." - }, - "drip(string)": { - "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." - }, - "drips(string)": { - "notice": "Maps from drip names to drip states." - }, - "executable(string)": { - "notice": "Checks if a given drip is executable." - }, - "status(string,uint8)": { - "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." - }, - "withdrawERC20(address,address)": { - "notice": "Withdraws full ERC20 balance to the recipient." - }, - "withdrawERC20(address,address,uint256)": { - "notice": "Withdraws partial ERC20 balance to the recipient." - }, - "withdrawERC721(address,address,uint256)": { - "notice": "Withdraws ERC721 token to the recipient." - }, - "withdrawETH(address)": { - "notice": "Withdraws full ETH balance to the recipient." - }, - "withdrawETH(address,uint256)": { - "notice": "Withdraws partial ETH balance to the recipient." - } - }, - "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.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 4096, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 6733, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "drips", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_string_memory_ptr,t_struct(DripState)6696_storage)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_address_payable": { - "encoding": "inplace", - "label": "address payable", - "numberOfBytes": "20" - }, - "t_array(t_struct(DripAction)6673_storage)dyn_storage": { - "base": "t_struct(DripAction)6673_storage", - "encoding": "dynamic_array", - "label": "struct Drippie.DripAction[]", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "encoding": "bytes", - "label": "bytes", - "numberOfBytes": "32" - }, - "t_contract(IDripCheck)7077": { - "encoding": "inplace", - "label": "contract IDripCheck", - "numberOfBytes": "20" - }, - "t_enum(DripStatus)6666": { - "encoding": "inplace", - "label": "enum Drippie.DripStatus", - "numberOfBytes": "1" - }, - "t_mapping(t_string_memory_ptr,t_struct(DripState)6696_storage)": { - "encoding": "mapping", - "key": "t_string_memory_ptr", - "label": "mapping(string => struct Drippie.DripState)", - "numberOfBytes": "32", - "value": "t_struct(DripState)6696_storage" - }, - "t_string_memory_ptr": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(DripAction)6673_storage": { - "encoding": "inplace", - "label": "struct Drippie.DripAction", - "members": [ - { - "astId": 6668, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "target", - "offset": 0, - "slot": "0", - "type": "t_address_payable" - }, - { - "astId": 6670, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "data", - "offset": 0, - "slot": "1", - "type": "t_bytes_storage" - }, - { - "astId": 6672, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "value", - "offset": 0, - "slot": "2", - "type": "t_uint256" - } - ], - "numberOfBytes": "96" - }, - "t_struct(DripConfig)6685_storage": { - "encoding": "inplace", - "label": "struct Drippie.DripConfig", - "members": [ - { - "astId": 6675, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "interval", - "offset": 0, - "slot": "0", - "type": "t_uint256" - }, - { - "astId": 6678, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "dripcheck", - "offset": 0, - "slot": "1", - "type": "t_contract(IDripCheck)7077" - }, - { - "astId": 6680, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "checkparams", - "offset": 0, - "slot": "2", - "type": "t_bytes_storage" - }, - { - "astId": 6684, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "actions", - "offset": 0, - "slot": "3", - "type": "t_array(t_struct(DripAction)6673_storage)dyn_storage" - } - ], - "numberOfBytes": "128" - }, - "t_struct(DripState)6696_storage": { - "encoding": "inplace", - "label": "struct Drippie.DripState", - "members": [ - { - "astId": 6688, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "status", - "offset": 0, - "slot": "0", - "type": "t_enum(DripStatus)6666" - }, - { - "astId": 6691, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "config", - "offset": 0, - "slot": "1", - "type": "t_struct(DripConfig)6685_storage" - }, - { - "astId": 6693, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "last", - "offset": 0, - "slot": "5", - "type": "t_uint256" - }, - { - "astId": 6695, - "contract": "contracts/universal/drippie/Drippie.sol:Drippie", - "label": "count", - "offset": 0, - "slot": "6", - "type": "t_uint256" - } - ], - "numberOfBytes": "224" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/EAS.json b/packages/contracts-bedrock/deployments/optimism-goerli/EAS.json deleted file mode 100644 index a43fa6be5380..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/EAS.json +++ /dev/null @@ -1,1483 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "AccessDenied", - "type": "error" - }, - { - "inputs": [], - "name": "AlreadyRevoked", - "type": "error" - }, - { - "inputs": [], - "name": "AlreadyRevokedOffchain", - "type": "error" - }, - { - "inputs": [], - "name": "AlreadyTimestamped", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientValue", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidAttestation", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidAttestations", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidExpirationTime", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidLength", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidOffset", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRegistry", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRevocation", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRevocations", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidSchema", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidSignature", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidVerifier", - "type": "error" - }, - { - "inputs": [], - "name": "Irrevocable", - "type": "error" - }, - { - "inputs": [], - "name": "NotFound", - "type": "error" - }, - { - "inputs": [], - "name": "NotPayable", - "type": "error" - }, - { - "inputs": [], - "name": "WrongSchema", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "attester", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - } - ], - "name": "Attested", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "attester", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - } - ], - "name": "Revoked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "revoker", - "type": "address" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint64", - "name": "timestamp", - "type": "uint64" - } - ], - "name": "RevokedOffchain", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint64", - "name": "timestamp", - "type": "uint64" - } - ], - "name": "Timestamped", - "type": "event" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint64", - "name": "expirationTime", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "bytes32", - "name": "refUID", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct AttestationRequestData", - "name": "data", - "type": "tuple" - } - ], - "internalType": "struct AttestationRequest", - "name": "request", - "type": "tuple" - } - ], - "name": "attest", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint64", - "name": "expirationTime", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "bytes32", - "name": "refUID", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct AttestationRequestData", - "name": "data", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "internalType": "struct EIP712Signature", - "name": "signature", - "type": "tuple" - }, - { - "internalType": "address", - "name": "attester", - "type": "address" - } - ], - "internalType": "struct DelegatedAttestationRequest", - "name": "delegatedRequest", - "type": "tuple" - } - ], - "name": "attestByDelegation", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "getAttestTypeHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - } - ], - "name": "getAttestation", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "time", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "expirationTime", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "revocationTime", - "type": "uint64" - }, - { - "internalType": "bytes32", - "name": "refUID", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "address", - "name": "attester", - "type": "address" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "internalType": "struct Attestation", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getDomainSeparator", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getName", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "getNonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "revoker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - } - ], - "name": "getRevokeOffchain", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getRevokeTypeHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "getSchemaRegistry", - "outputs": [ - { - "internalType": "contract ISchemaRegistry", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - } - ], - "name": "getTimestamp", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - } - ], - "name": "isAttestationValid", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint64", - "name": "expirationTime", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "bytes32", - "name": "refUID", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct AttestationRequestData[]", - "name": "data", - "type": "tuple[]" - } - ], - "internalType": "struct MultiAttestationRequest[]", - "name": "multiRequests", - "type": "tuple[]" - } - ], - "name": "multiAttest", - "outputs": [ - { - "internalType": "bytes32[]", - "name": "", - "type": "bytes32[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint64", - "name": "expirationTime", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "bytes32", - "name": "refUID", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct AttestationRequestData[]", - "name": "data", - "type": "tuple[]" - }, - { - "components": [ - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "internalType": "struct EIP712Signature[]", - "name": "signatures", - "type": "tuple[]" - }, - { - "internalType": "address", - "name": "attester", - "type": "address" - } - ], - "internalType": "struct MultiDelegatedAttestationRequest[]", - "name": "multiDelegatedRequests", - "type": "tuple[]" - } - ], - "name": "multiAttestByDelegation", - "outputs": [ - { - "internalType": "bytes32[]", - "name": "", - "type": "bytes32[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct RevocationRequestData[]", - "name": "data", - "type": "tuple[]" - } - ], - "internalType": "struct MultiRevocationRequest[]", - "name": "multiRequests", - "type": "tuple[]" - } - ], - "name": "multiRevoke", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct RevocationRequestData[]", - "name": "data", - "type": "tuple[]" - }, - { - "components": [ - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "internalType": "struct EIP712Signature[]", - "name": "signatures", - "type": "tuple[]" - }, - { - "internalType": "address", - "name": "revoker", - "type": "address" - } - ], - "internalType": "struct MultiDelegatedRevocationRequest[]", - "name": "multiDelegatedRequests", - "type": "tuple[]" - } - ], - "name": "multiRevokeByDelegation", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32[]", - "name": "data", - "type": "bytes32[]" - } - ], - "name": "multiRevokeOffchain", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32[]", - "name": "data", - "type": "bytes32[]" - } - ], - "name": "multiTimestamp", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct RevocationRequestData", - "name": "data", - "type": "tuple" - } - ], - "internalType": "struct RevocationRequest", - "name": "request", - "type": "tuple" - } - ], - "name": "revoke", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct RevocationRequestData", - "name": "data", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "internalType": "struct EIP712Signature", - "name": "signature", - "type": "tuple" - }, - { - "internalType": "address", - "name": "revoker", - "type": "address" - } - ], - "internalType": "struct DelegatedRevocationRequest", - "name": "delegatedRequest", - "type": "tuple" - } - ], - "name": "revokeByDelegation", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - } - ], - "name": "revokeOffchain", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - } - ], - "name": "timestamp", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x5A633F1cc84B03F7588486CF2F386c102061E6e1", - "args": [], - "bytecode": "0x6101c06040523480156200001257600080fd5b50604080518082018252600381526245415360e81b6020808301918252835180850190945260058452640312e302e360dc1b9084019081526001608052600060a081905260c052825190912083519091206101408290526101608190524661010052919291839183917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ec8184846040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b60e0523061012052610180525050505060208201516101a052506200010e9050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516144df6200018a60003960006105410152600061265b015260006126aa01526000612685015260006125de0152600061260801526000612632015260006108730152600061084a0152600061082101526144df6000f3fe6080604052600436106101805760003560e01c8063b469318d116100d6578063e45d03f91161007f578063ed24911d11610059578063ed24911d1461049e578063f10b5cc8146104b3578063f17325e7146104e257600080fd5b8063e45d03f914610458578063e57a6b1b1461046b578063e71ff3651461047e57600080fd5b8063d45c4435116100b0578063d45c4435146103cf578063e13458fc14610406578063e30bb5631461041957600080fd5b8063b469318d14610322578063b83010d31461037c578063cf190f34146103af57600080fd5b8063469262671161013857806354fd4d501161011257806354fd4d50146102cd578063831e05a1146102e2578063a3112a64146102f557600080fd5b806346926267146102855780634cb7e9e51461029a5780634d003070146102ad57600080fd5b806317d7de7c1161016957806317d7de7c146102005780632d0335ab1461022257806344adc90e1461026557600080fd5b806312b11a171461018557806313893f61146101c7575b600080fd5b34801561019157600080fd5b507fdbfdf8dc2b135c26253e00d5b6cbe6f20457e003fd526d97cea183883570de615b6040519081526020015b60405180910390f35b3480156101d357600080fd5b506101e76101e23660046133ee565b6104f5565b60405167ffffffffffffffff90911681526020016101be565b34801561020c57600080fd5b5061021561053a565b6040516101be919061349e565b34801561022e57600080fd5b506101b461023d3660046134ea565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6102786102733660046133ee565b61056a565b6040516101be9190613507565b61029861029336600461354b565b6106a1565b005b6102986102a83660046133ee565b610725565b3480156102b957600080fd5b506101e76102c8366004613563565b61080d565b3480156102d957600080fd5b5061021561081a565b6102786102f03660046133ee565b6108bd565b34801561030157600080fd5b50610315610310366004613563565b610b0e565b6040516101be9190613663565b34801561032e57600080fd5b506101e761033d366004613676565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561038857600080fd5b507fa98d02348410c9c76735e0d0bb1396f4015ac2bb9615f9c2611d19d7a8a996506101b4565b3480156103bb57600080fd5b506101e76103ca366004613563565b610cd1565b3480156103db57600080fd5b506101e76103ea366004613563565b60009081526033602052604090205467ffffffffffffffff1690565b6101b46104143660046136a2565b610cdf565b34801561042557600080fd5b50610448610434366004613563565b600090815260326020526040902054151590565b60405190151581526020016101be565b6102986104663660046133ee565b610de2565b6102986104793660046136dd565b610f5d565b34801561048a57600080fd5b506101e76104993660046133ee565b611002565b3480156104aa57600080fd5b506101b461103a565b3480156104bf57600080fd5b5060405173420000000000000000000000000000000000002081526020016101be565b6101b46104f03660046136ef565b611044565b60004282825b8181101561052e57610526338787848181106105195761051961372a565b9050602002013585611102565b6001016104fb565b50909150505b92915050565b60606105657f0000000000000000000000000000000000000000000000000000000000000000611201565b905090565b606060008267ffffffffffffffff81111561058757610587613759565b6040519080825280602002602001820160405280156105ba57816020015b60608152602001906001900390816105a55790505b509050600034815b8581101561068c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86018114368888848181106106025761060261372a565b90506020028101906106149190613788565b9050600061063b823561062a60208501856137c6565b61063391613a3f565b33888761138f565b805190915061064a9086613ae2565b945080602001518785815181106106635761066361372a565b6020026020010181905250806020015151860195505050506106858160010190565b90506105c2565b506106978383611aa1565b9695505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816106b85790505090506106f336839003830160208401613b44565b816000815181106107065761070661372a565b602090810291909101015261072082358233346001611b6e565b505050565b3460005b82811015610807577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83018114368585848181106107695761076961372a565b905060200281019061077b9190613788565b90506107e8813561078f6020840184613b60565b808060200260200160405190810160405280939291908181526020016000905b828210156107db576107cc60408302860136819003810190613b44565b815260200190600101906107af565b5050505050338786611b6e565b6107f29085613ae2565b935050506108008160010190565b9050610729565b50505050565b60004261053483826121a8565b60606108457f000000000000000000000000000000000000000000000000000000000000000061226a565b61086e7f000000000000000000000000000000000000000000000000000000000000000061226a565b6108977f000000000000000000000000000000000000000000000000000000000000000061226a565b6040516020016108a993929190613bc8565b604051602081830303815290604052905090565b606060008267ffffffffffffffff8111156108da576108da613759565b60405190808252806020026020018201604052801561090d57816020015b60608152602001906001900390816108f85790505b509050600034815b8581101561068c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86018114368888848181106109555761095561372a565b90506020028101906109679190613c3e565b905036600061097960208401846137c6565b909250905080158061099957506109936040840184613c72565b82141590505b156109d0576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610a9257610a8a604051806080016040528086600001358152602001858585818110610a0557610a0561372a565b9050602002810190610a179190613cd9565b610a2090613d0d565b8152602001610a326040880188613c72565b85818110610a4257610a4261372a565b905060600201803603810190610a589190613d84565b8152602001610a6d60808801606089016134ea565b73ffffffffffffffffffffffffffffffffffffffff1690526123a7565b6001016109d3565b506000610abb8435610aa48486613a3f565b610ab460808801606089016134ea565b8a8961138f565b8051909150610aca9088613ae2565b96508060200151898781518110610ae357610ae361372a565b6020026020010181905250806020015151880197505050505050610b078160010190565b9050610915565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610c4890613da0565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7490613da0565b8015610cc15780601f10610c9657610100808354040283529160200191610cc1565b820191906000526020600020905b815481529060010190602001808311610ca457829003601f168201915b5050505050815250509050919050565b600042610534338483611102565b6000610cf2610ced83613ded565b6123a7565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610d09579050509050610d776020840184613cd9565b610d8090613d0d565b81600081518110610d9357610d9361372a565b6020908102919091010152610dbc833582610db460c0870160a088016134ea565b34600161138f565b60200151600081518110610dd257610dd261372a565b6020026020010151915050919050565b3460005b82811015610807577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830181146000858584818110610e2757610e2761372a565b9050602002810190610e399190613c3e565b610e4290613ed2565b60208101518051919250901580610e5f5750816040015151815114155b15610e96576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8151811015610f2757610f1f604051806080016040528085600001518152602001848481518110610ecc57610ecc61372a565b6020026020010151815260200185604001518481518110610eef57610eef61372a565b60200260200101518152602001856060015173ffffffffffffffffffffffffffffffffffffffff16815250612536565b600101610e99565b50610f3d82600001518284606001518887611b6e565b610f479086613ae2565b9450505050610f568160010190565b9050610de6565b610f74610f6f36839003830183613fb1565b612536565b604080516001808252818301909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081610f8b579050509050610fc636839003830160208401613b44565b81600081518110610fd957610fd961372a565b6020908102919091010152610720823582610ffa60e0860160c087016134ea565b346001611b6e565b60004282825b8181101561052e576110328686838181106110255761102561372a565b90506020020135846121a8565b600101611008565b60006105656125c4565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161105e5790505090506110cc6020840184613cd9565b6110d590613d0d565b816000815181106110e8576110e861372a565b6020908102919091010152610dbc8335823334600161138f565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611176576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b60208110156112cc5760008582602081106112475761124761372a565b1a60f81b90507fff00000000000000000000000000000000000000000000000000000000000000811660000361127d57506112cc565b808484815181106112905761129061372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350506001918201910161122a565b5060008167ffffffffffffffff8111156112e8576112e8613759565b6040519080825280601f01601f191660200182016040528015611312576020820181803683370190505b50905060005b82811015611386578381815181106113325761133261372a565b602001015160f81c60f81b82828151811061134f5761134f61372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611318565b50949350505050565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff8111156113d4576113d4613759565b6040519080825280602002602001820160405280156113fd578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa15801561146f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526114b5919081019061400d565b80519091506114f0576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff81111561150b5761150b613759565b6040519080825280602002602001820160405280156115aa57816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816115295790505b50905060008467ffffffffffffffff8111156115c8576115c8613759565b6040519080825280602002602001820160405280156115f1578160200160208202803683370190505b50905060005b85811015611a805760008b82815181106116135761161361372a565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff161415801561165e57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15611695576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84604001511580156116a8575080604001515b156116df576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016117034290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6117a583826126f8565b600081815260326020526040902054909250156117c45760010161179b565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906119449082614133565b50505060608401511561199b57606084015160009081526032602052604090205461199b576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828786815181106119ae576119ae61372a565b60200260200101819052508360a001518686815181106119d0576119d061372a565b60200260200101818152505081896020015186815181106119f3576119f361372a565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b3585604051611a6391815260200190565b60405180910390a450505050611a798160010190565b90506115f7565b50611a9083838360008c8c612757565b845250919998505050505050505050565b606060008267ffffffffffffffff811115611abe57611abe613759565b604051908082528060200260200182016040528015611ae7578160200160208202803683370190505b5090506000805b855181101561052e576000868281518110611b0b57611b0b61372a565b6020026020010151905060005b8151811015611b6457818181518110611b3357611b3361372a565b6020026020010151858581518110611b4d57611b4d61372a565b602090810291909101015260019384019301611b18565b5050600101611aee565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611bdc573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611c22919081019061400d565b8051909150611c5d576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff811115611c7a57611c7a613759565b604051908082528060200260200182016040528015611d1957816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611c985790505b50905060008267ffffffffffffffff811115611d3757611d37613759565b604051908082528060200260200182016040528015611d60578160200160208202803683370190505b50905060005b8381101561218a5760008a8281518110611d8257611d8261372a565b6020908102919091018101518051600090815260329092526040909120805491925090611ddb576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c816001015414611e18576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c8116911614611e6e576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff16611ec4576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611f1e576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff161515610100820152600682018054839161012084019161202a90613da0565b80601f016020809104026020016040519081016040528092919081815260200182805461205690613da0565b80156120a35780601f10612078576101008083540402835291602001916120a3565b820191906000526020600020905b81548152906001019060200180831161208657829003601f168201915b5050505050815250508584815181106120be576120be61372a565b602002602001018190525081602001518484815181106120e0576120e061372a565b60200260200101818152505080600101548b73ffffffffffffffffffffffffffffffffffffffff168260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f615856000015160405161217891815260200190565b60405180910390a45050600101611d66565b5061219a84838360018b8b612757565b9a9950505050505050505050565b60008281526033602052604090205467ffffffffffffffff16156121f8576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b6060816000036122ad57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156122d757806122c18161424d565b91506122d09050600a836142b4565b91506122b1565b60008167ffffffffffffffff8111156122f2576122f2613759565b6040519080825280601f01601f19166020018201604052801561231c576020820181803683370190505b5090505b841561239f57612331600183613ae2565b915061233e600a866142c8565b6123499060306142dc565b60f81b81838151811061235e5761235e61372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612398600a866142b4565b9450612320565b949350505050565b60208082015160408084015160608086015173ffffffffffffffffffffffffffffffffffffffff1660009081528086528381208054600181019091558751865187890151878901519589015160808a01518051908c01209851999a9799949895976124ad97612492977fdbfdf8dc2b135c26253e00d5b6cbe6f20457e003fd526d97cea183883570de619791939290918c9101978852602088019690965273ffffffffffffffffffffffffffffffffffffffff94909416604087015267ffffffffffffffff9290921660608601521515608085015260a084015260c083015260e08201526101000190565b60405160208183030381529060405280519060200120612b31565b9050846060015173ffffffffffffffffffffffffffffffffffffffff166124e282856000015186602001518760400151612b44565b73ffffffffffffffffffffffffffffffffffffffff161461252f576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60208181015160408084015160608086015173ffffffffffffffffffffffffffffffffffffffff1660009081528086528381208054600181019091558751865186517fa98d02348410c9c76735e0d0bb1396f4015ac2bb9615f9c2611d19d7a8a99650998101999099529588015291860193909352608085018190529293909291906124ad9060a001612492565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561262a57507f000000000000000000000000000000000000000000000000000000000000000046145b1561265457507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b0151945160009961273999989796918c91016142ef565b60405160208183030381529060405280519060200120905092915050565b845160009060018190036127af576127a7888860008151811061277c5761277c61372a565b6020026020010151886000815181106127975761279761372a565b6020026020010151888888612b6c565b915050610697565b602088015173ffffffffffffffffffffffffffffffffffffffff81166128415760005b82811015612835578781815181106127ec576127ec61372a565b602002602001015160001461282d576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001016127d2565b50600092505050610697565b6000805b8381101561296b5760008982815181106128615761286161372a565b60200260200101519050806000141580156128e857508373ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e691906143cd565b155b1561291f576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87811115612959576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b96879003969190910190600101612845565b508615612a46576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906388e5b2d99083906129c8908d908d906004016143ea565b60206040518083038185885af11580156129e6573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612a0b91906143cd565b612a41576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b15565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906391db0b7e908390612a9c908d908d906004016143ea565b60206040518083038185885af1158015612aba573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612adf91906143cd565b612b15576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415612b2457612b2486612e82565b9998505050505050505050565b6000610534612b3e6125c4565b83612e95565b6000806000612b5587878787612ed7565b91509150612b6281612fef565b5095945050505050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612bd1578515612bc7576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000915050610697565b8515801590612c4c57508073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4a91906143cd565b155b15612c83576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115612cbd576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393508415612d9a576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890612d1c908b90600401613663565b60206040518083038185885af1158015612d3a573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d5f91906143cd565b612d95576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e67565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890612dee908b90600401613663565b60206040518083038185885af1158015612e0c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612e3191906143cd565b612e67576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612e7657612e7684612e82565b50939695505050505050565b8015612e9257612e923382613248565b50565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612739565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f0e5750600090506003612fe6565b8460ff16601b14158015612f2657508460ff16601c14155b15612f375750600090506004612fe6565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612f8b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612fdf57600060019250925050612fe6565b9150600090505b94509492505050565b6000816004811115613003576130036144a3565b0361300b5750565b600181600481111561301f5761301f6144a3565b0361308b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b600281600481111561309f5761309f6144a3565b03613106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401613082565b600381600481111561311a5761311a6144a3565b036131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401613082565b60048160048111156131bb576131bb6144a3565b03612e92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401613082565b804710156132b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401613082565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461330c576040519150601f19603f3d011682016040523d82523d6000602084013e613311565b606091505b5050905080610720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401613082565b60008083601f8401126133b457600080fd5b50813567ffffffffffffffff8111156133cc57600080fd5b6020830191508360208260051b85010111156133e757600080fd5b9250929050565b6000806020838503121561340157600080fd5b823567ffffffffffffffff81111561341857600080fd5b613424858286016133a2565b90969095509350505050565b60005b8381101561344b578181015183820152602001613433565b50506000910152565b6000815180845261346c816020860160208601613430565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006134b16020830184613454565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114612e9257600080fd5b80356134e5816134b8565b919050565b6000602082840312156134fc57600080fd5b81356134b1816134b8565b6020808252825182820181905260009190848201906040850190845b8181101561353f57835183529284019291840191600101613523565b50909695505050505050565b60006060828403121561355d57600080fd5b50919050565b60006020828403121561357557600080fd5b5035919050565b6000610140825184526020830151602085015260408301516135aa604086018267ffffffffffffffff169052565b5060608301516135c6606086018267ffffffffffffffff169052565b5060808301516135e2608086018267ffffffffffffffff169052565b5060a083015160a085015260c083015161361460c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161363c60e086018273ffffffffffffffffffffffffffffffffffffffff169052565b50610100838101511515908501526101208084015181860183905261069783870182613454565b6020815260006134b1602083018461357c565b6000806040838503121561368957600080fd5b8235613694816134b8565b946020939093013593505050565b6000602082840312156136b457600080fd5b813567ffffffffffffffff8111156136cb57600080fd5b820160c081850312156134b157600080fd5b600060e0828403121561355d57600080fd5b60006020828403121561370157600080fd5b813567ffffffffffffffff81111561371857600080fd5b8201604081850312156134b157600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126137bc57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126137fb57600080fd5b83018035915067ffffffffffffffff82111561381657600080fd5b6020019150600581901b36038213156133e757600080fd5b60405160c0810167ffffffffffffffff8111828210171561385157613851613759565b60405290565b6040516080810167ffffffffffffffff8111828210171561385157613851613759565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156138c1576138c1613759565b604052919050565b600067ffffffffffffffff8211156138e3576138e3613759565b5060051b60200190565b8015158114612e9257600080fd5b80356134e5816138ed565b600067ffffffffffffffff82111561392057613920613759565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261395d57600080fd5b813561397061396b82613906565b61387a565b81815284602083860101111561398557600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156139b457600080fd5b6139bc61382e565b905081356139c9816134b8565b8152602082013567ffffffffffffffff80821682146139e757600080fd5b8160208401526139f9604085016138fb565b6040840152606084013560608401526080840135915080821115613a1c57600080fd5b50613a298482850161394c565b60808301525060a082013560a082015292915050565b6000613a4d61396b846138c9565b80848252602080830192508560051b850136811115613a6b57600080fd5b855b81811015613aa757803567ffffffffffffffff811115613a8d5760008081fd5b613a9936828a016139a2565b865250938201938201613a6d565b50919695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561053457610534613ab3565b600060408284031215613b0757600080fd5b6040516040810181811067ffffffffffffffff82111715613b2a57613b2a613759565b604052823581526020928301359281019290925250919050565b600060408284031215613b5657600080fd5b6134b18383613af5565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613b9557600080fd5b83018035915067ffffffffffffffff821115613bb057600080fd5b6020019150600681901b36038213156133e757600080fd5b60008451613bda818460208901613430565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551613c16816001850160208a01613430565b60019201918201528351613c31816002840160208801613430565b0160020195945050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126137bc57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613ca757600080fd5b83018035915067ffffffffffffffff821115613cc257600080fd5b60200191506060810236038213156133e757600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff418336030181126137bc57600080fd5b600061053436836139a2565b600060608284031215613d2b57600080fd5b6040516060810181811067ffffffffffffffff82111715613d4e57613d4e613759565b604052905080823560ff81168114613d6557600080fd5b8082525060208301356020820152604083013560408201525092915050565b600060608284031215613d9657600080fd5b6134b18383613d19565b600181811c90821680613db457607f821691505b60208210810361355d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060c08236031215613dff57600080fd5b613e07613857565b82358152602083013567ffffffffffffffff811115613e2557600080fd5b613e31368286016139a2565b602083015250613e443660408501613d19565b604082015260a0830135613e57816134b8565b606082015292915050565b600082601f830112613e7357600080fd5b81356020613e8361396b836138c9565b82815260609283028501820192828201919087851115613ea257600080fd5b8387015b85811015613ec557613eb88982613d19565b8452928401928101613ea6565b5090979650505050505050565b600060808236031215613ee457600080fd5b613eec613857565b8235815260208084013567ffffffffffffffff80821115613f0c57600080fd5b9085019036601f830112613f1f57600080fd5b8135613f2d61396b826138c9565b81815260069190911b83018401908481019036831115613f4c57600080fd5b938501935b82851015613f7557613f633686613af5565b82528582019150604085019450613f51565b80868801525050506040860135925080831115613f9157600080fd5b5050613f9f36828601613e62565b604083015250613e57606084016134da565b600060e08284031215613fc357600080fd5b613fcb613857565b82358152613fdc8460208501613af5565b6020820152613fee8460608501613d19565b604082015260c0830135614001816134b8565b60608201529392505050565b6000602080838503121561402057600080fd5b825167ffffffffffffffff8082111561403857600080fd5b908401906080828703121561404c57600080fd5b614054613857565b8251815283830151614065816134b8565b818501526040830151614077816138ed565b604082015260608301518281111561408e57600080fd5b80840193505086601f8401126140a357600080fd5b825191506140b361396b83613906565b82815287858486010111156140c757600080fd5b6140d683868301878701613430565b60608201529695505050505050565b601f82111561072057600081815260208120601f850160051c8101602086101561410c5750805b601f850160051c820191505b8181101561412b57828155600101614118565b505050505050565b815167ffffffffffffffff81111561414d5761414d613759565b6141618161415b8454613da0565b846140e5565b602080601f8311600181146141b4576000841561417e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561412b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614201578886015182559484019460019091019084016141e2565b508582101561423d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361427e5761427e613ab3565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826142c3576142c3614285565b500490565b6000826142d7576142d7614285565b500690565b8082018082111561053457610534613ab3565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b60588301528460598301528351614388816079850160208801613430565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a9950505050505050505050565b6000602082840312156143df57600080fd5b81516134b1816138ed565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561445f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261444d86835161357c565b95509382019390820190600101614413565b50508584038187015286518085528782019482019350915060005b828110156144965784518452938101939281019260010161447a565b5091979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000813000a", - "deployedBytecode": "0x6080604052600436106101805760003560e01c8063b469318d116100d6578063e45d03f91161007f578063ed24911d11610059578063ed24911d1461049e578063f10b5cc8146104b3578063f17325e7146104e257600080fd5b8063e45d03f914610458578063e57a6b1b1461046b578063e71ff3651461047e57600080fd5b8063d45c4435116100b0578063d45c4435146103cf578063e13458fc14610406578063e30bb5631461041957600080fd5b8063b469318d14610322578063b83010d31461037c578063cf190f34146103af57600080fd5b8063469262671161013857806354fd4d501161011257806354fd4d50146102cd578063831e05a1146102e2578063a3112a64146102f557600080fd5b806346926267146102855780634cb7e9e51461029a5780634d003070146102ad57600080fd5b806317d7de7c1161016957806317d7de7c146102005780632d0335ab1461022257806344adc90e1461026557600080fd5b806312b11a171461018557806313893f61146101c7575b600080fd5b34801561019157600080fd5b507fdbfdf8dc2b135c26253e00d5b6cbe6f20457e003fd526d97cea183883570de615b6040519081526020015b60405180910390f35b3480156101d357600080fd5b506101e76101e23660046133ee565b6104f5565b60405167ffffffffffffffff90911681526020016101be565b34801561020c57600080fd5b5061021561053a565b6040516101be919061349e565b34801561022e57600080fd5b506101b461023d3660046134ea565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6102786102733660046133ee565b61056a565b6040516101be9190613507565b61029861029336600461354b565b6106a1565b005b6102986102a83660046133ee565b610725565b3480156102b957600080fd5b506101e76102c8366004613563565b61080d565b3480156102d957600080fd5b5061021561081a565b6102786102f03660046133ee565b6108bd565b34801561030157600080fd5b50610315610310366004613563565b610b0e565b6040516101be9190613663565b34801561032e57600080fd5b506101e761033d366004613676565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561038857600080fd5b507fa98d02348410c9c76735e0d0bb1396f4015ac2bb9615f9c2611d19d7a8a996506101b4565b3480156103bb57600080fd5b506101e76103ca366004613563565b610cd1565b3480156103db57600080fd5b506101e76103ea366004613563565b60009081526033602052604090205467ffffffffffffffff1690565b6101b46104143660046136a2565b610cdf565b34801561042557600080fd5b50610448610434366004613563565b600090815260326020526040902054151590565b60405190151581526020016101be565b6102986104663660046133ee565b610de2565b6102986104793660046136dd565b610f5d565b34801561048a57600080fd5b506101e76104993660046133ee565b611002565b3480156104aa57600080fd5b506101b461103a565b3480156104bf57600080fd5b5060405173420000000000000000000000000000000000002081526020016101be565b6101b46104f03660046136ef565b611044565b60004282825b8181101561052e57610526338787848181106105195761051961372a565b9050602002013585611102565b6001016104fb565b50909150505b92915050565b60606105657f0000000000000000000000000000000000000000000000000000000000000000611201565b905090565b606060008267ffffffffffffffff81111561058757610587613759565b6040519080825280602002602001820160405280156105ba57816020015b60608152602001906001900390816105a55790505b509050600034815b8581101561068c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86018114368888848181106106025761060261372a565b90506020028101906106149190613788565b9050600061063b823561062a60208501856137c6565b61063391613a3f565b33888761138f565b805190915061064a9086613ae2565b945080602001518785815181106106635761066361372a565b6020026020010181905250806020015151860195505050506106858160010190565b90506105c2565b506106978383611aa1565b9695505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816106b85790505090506106f336839003830160208401613b44565b816000815181106107065761070661372a565b602090810291909101015261072082358233346001611b6e565b505050565b3460005b82811015610807577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83018114368585848181106107695761076961372a565b905060200281019061077b9190613788565b90506107e8813561078f6020840184613b60565b808060200260200160405190810160405280939291908181526020016000905b828210156107db576107cc60408302860136819003810190613b44565b815260200190600101906107af565b5050505050338786611b6e565b6107f29085613ae2565b935050506108008160010190565b9050610729565b50505050565b60004261053483826121a8565b60606108457f000000000000000000000000000000000000000000000000000000000000000061226a565b61086e7f000000000000000000000000000000000000000000000000000000000000000061226a565b6108977f000000000000000000000000000000000000000000000000000000000000000061226a565b6040516020016108a993929190613bc8565b604051602081830303815290604052905090565b606060008267ffffffffffffffff8111156108da576108da613759565b60405190808252806020026020018201604052801561090d57816020015b60608152602001906001900390816108f85790505b509050600034815b8581101561068c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86018114368888848181106109555761095561372a565b90506020028101906109679190613c3e565b905036600061097960208401846137c6565b909250905080158061099957506109936040840184613c72565b82141590505b156109d0576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610a9257610a8a604051806080016040528086600001358152602001858585818110610a0557610a0561372a565b9050602002810190610a179190613cd9565b610a2090613d0d565b8152602001610a326040880188613c72565b85818110610a4257610a4261372a565b905060600201803603810190610a589190613d84565b8152602001610a6d60808801606089016134ea565b73ffffffffffffffffffffffffffffffffffffffff1690526123a7565b6001016109d3565b506000610abb8435610aa48486613a3f565b610ab460808801606089016134ea565b8a8961138f565b8051909150610aca9088613ae2565b96508060200151898781518110610ae357610ae361372a565b6020026020010181905250806020015151880197505050505050610b078160010190565b9050610915565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610c4890613da0565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7490613da0565b8015610cc15780601f10610c9657610100808354040283529160200191610cc1565b820191906000526020600020905b815481529060010190602001808311610ca457829003601f168201915b5050505050815250509050919050565b600042610534338483611102565b6000610cf2610ced83613ded565b6123a7565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610d09579050509050610d776020840184613cd9565b610d8090613d0d565b81600081518110610d9357610d9361372a565b6020908102919091010152610dbc833582610db460c0870160a088016134ea565b34600161138f565b60200151600081518110610dd257610dd261372a565b6020026020010151915050919050565b3460005b82811015610807577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830181146000858584818110610e2757610e2761372a565b9050602002810190610e399190613c3e565b610e4290613ed2565b60208101518051919250901580610e5f5750816040015151815114155b15610e96576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8151811015610f2757610f1f604051806080016040528085600001518152602001848481518110610ecc57610ecc61372a565b6020026020010151815260200185604001518481518110610eef57610eef61372a565b60200260200101518152602001856060015173ffffffffffffffffffffffffffffffffffffffff16815250612536565b600101610e99565b50610f3d82600001518284606001518887611b6e565b610f479086613ae2565b9450505050610f568160010190565b9050610de6565b610f74610f6f36839003830183613fb1565b612536565b604080516001808252818301909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081610f8b579050509050610fc636839003830160208401613b44565b81600081518110610fd957610fd961372a565b6020908102919091010152610720823582610ffa60e0860160c087016134ea565b346001611b6e565b60004282825b8181101561052e576110328686838181106110255761102561372a565b90506020020135846121a8565b600101611008565b60006105656125c4565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161105e5790505090506110cc6020840184613cd9565b6110d590613d0d565b816000815181106110e8576110e861372a565b6020908102919091010152610dbc8335823334600161138f565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611176576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b60208110156112cc5760008582602081106112475761124761372a565b1a60f81b90507fff00000000000000000000000000000000000000000000000000000000000000811660000361127d57506112cc565b808484815181106112905761129061372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350506001918201910161122a565b5060008167ffffffffffffffff8111156112e8576112e8613759565b6040519080825280601f01601f191660200182016040528015611312576020820181803683370190505b50905060005b82811015611386578381815181106113325761133261372a565b602001015160f81c60f81b82828151811061134f5761134f61372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611318565b50949350505050565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff8111156113d4576113d4613759565b6040519080825280602002602001820160405280156113fd578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa15801561146f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526114b5919081019061400d565b80519091506114f0576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff81111561150b5761150b613759565b6040519080825280602002602001820160405280156115aa57816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816115295790505b50905060008467ffffffffffffffff8111156115c8576115c8613759565b6040519080825280602002602001820160405280156115f1578160200160208202803683370190505b50905060005b85811015611a805760008b82815181106116135761161361372a565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff161415801561165e57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15611695576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84604001511580156116a8575080604001515b156116df576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016117034290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6117a583826126f8565b600081815260326020526040902054909250156117c45760010161179b565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906119449082614133565b50505060608401511561199b57606084015160009081526032602052604090205461199b576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828786815181106119ae576119ae61372a565b60200260200101819052508360a001518686815181106119d0576119d061372a565b60200260200101818152505081896020015186815181106119f3576119f361372a565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b3585604051611a6391815260200190565b60405180910390a450505050611a798160010190565b90506115f7565b50611a9083838360008c8c612757565b845250919998505050505050505050565b606060008267ffffffffffffffff811115611abe57611abe613759565b604051908082528060200260200182016040528015611ae7578160200160208202803683370190505b5090506000805b855181101561052e576000868281518110611b0b57611b0b61372a565b6020026020010151905060005b8151811015611b6457818181518110611b3357611b3361372a565b6020026020010151858581518110611b4d57611b4d61372a565b602090810291909101015260019384019301611b18565b5050600101611aee565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611bdc573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611c22919081019061400d565b8051909150611c5d576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff811115611c7a57611c7a613759565b604051908082528060200260200182016040528015611d1957816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611c985790505b50905060008267ffffffffffffffff811115611d3757611d37613759565b604051908082528060200260200182016040528015611d60578160200160208202803683370190505b50905060005b8381101561218a5760008a8281518110611d8257611d8261372a565b6020908102919091018101518051600090815260329092526040909120805491925090611ddb576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c816001015414611e18576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c8116911614611e6e576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff16611ec4576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611f1e576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff161515610100820152600682018054839161012084019161202a90613da0565b80601f016020809104026020016040519081016040528092919081815260200182805461205690613da0565b80156120a35780601f10612078576101008083540402835291602001916120a3565b820191906000526020600020905b81548152906001019060200180831161208657829003601f168201915b5050505050815250508584815181106120be576120be61372a565b602002602001018190525081602001518484815181106120e0576120e061372a565b60200260200101818152505080600101548b73ffffffffffffffffffffffffffffffffffffffff168260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f615856000015160405161217891815260200190565b60405180910390a45050600101611d66565b5061219a84838360018b8b612757565b9a9950505050505050505050565b60008281526033602052604090205467ffffffffffffffff16156121f8576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b6060816000036122ad57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156122d757806122c18161424d565b91506122d09050600a836142b4565b91506122b1565b60008167ffffffffffffffff8111156122f2576122f2613759565b6040519080825280601f01601f19166020018201604052801561231c576020820181803683370190505b5090505b841561239f57612331600183613ae2565b915061233e600a866142c8565b6123499060306142dc565b60f81b81838151811061235e5761235e61372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612398600a866142b4565b9450612320565b949350505050565b60208082015160408084015160608086015173ffffffffffffffffffffffffffffffffffffffff1660009081528086528381208054600181019091558751865187890151878901519589015160808a01518051908c01209851999a9799949895976124ad97612492977fdbfdf8dc2b135c26253e00d5b6cbe6f20457e003fd526d97cea183883570de619791939290918c9101978852602088019690965273ffffffffffffffffffffffffffffffffffffffff94909416604087015267ffffffffffffffff9290921660608601521515608085015260a084015260c083015260e08201526101000190565b60405160208183030381529060405280519060200120612b31565b9050846060015173ffffffffffffffffffffffffffffffffffffffff166124e282856000015186602001518760400151612b44565b73ffffffffffffffffffffffffffffffffffffffff161461252f576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60208181015160408084015160608086015173ffffffffffffffffffffffffffffffffffffffff1660009081528086528381208054600181019091558751865186517fa98d02348410c9c76735e0d0bb1396f4015ac2bb9615f9c2611d19d7a8a99650998101999099529588015291860193909352608085018190529293909291906124ad9060a001612492565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561262a57507f000000000000000000000000000000000000000000000000000000000000000046145b1561265457507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b0151945160009961273999989796918c91016142ef565b60405160208183030381529060405280519060200120905092915050565b845160009060018190036127af576127a7888860008151811061277c5761277c61372a565b6020026020010151886000815181106127975761279761372a565b6020026020010151888888612b6c565b915050610697565b602088015173ffffffffffffffffffffffffffffffffffffffff81166128415760005b82811015612835578781815181106127ec576127ec61372a565b602002602001015160001461282d576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001016127d2565b50600092505050610697565b6000805b8381101561296b5760008982815181106128615761286161372a565b60200260200101519050806000141580156128e857508373ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e691906143cd565b155b1561291f576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87811115612959576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b96879003969190910190600101612845565b508615612a46576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906388e5b2d99083906129c8908d908d906004016143ea565b60206040518083038185885af11580156129e6573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612a0b91906143cd565b612a41576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b15565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906391db0b7e908390612a9c908d908d906004016143ea565b60206040518083038185885af1158015612aba573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612adf91906143cd565b612b15576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415612b2457612b2486612e82565b9998505050505050505050565b6000610534612b3e6125c4565b83612e95565b6000806000612b5587878787612ed7565b91509150612b6281612fef565b5095945050505050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612bd1578515612bc7576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000915050610697565b8515801590612c4c57508073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4a91906143cd565b155b15612c83576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115612cbd576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393508415612d9a576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890612d1c908b90600401613663565b60206040518083038185885af1158015612d3a573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d5f91906143cd565b612d95576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e67565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890612dee908b90600401613663565b60206040518083038185885af1158015612e0c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612e3191906143cd565b612e67576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612e7657612e7684612e82565b50939695505050505050565b8015612e9257612e923382613248565b50565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612739565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f0e5750600090506003612fe6565b8460ff16601b14158015612f2657508460ff16601c14155b15612f375750600090506004612fe6565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612f8b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612fdf57600060019250925050612fe6565b9150600090505b94509492505050565b6000816004811115613003576130036144a3565b0361300b5750565b600181600481111561301f5761301f6144a3565b0361308b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b600281600481111561309f5761309f6144a3565b03613106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401613082565b600381600481111561311a5761311a6144a3565b036131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401613082565b60048160048111156131bb576131bb6144a3565b03612e92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401613082565b804710156132b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401613082565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461330c576040519150601f19603f3d011682016040523d82523d6000602084013e613311565b606091505b5050905080610720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401613082565b60008083601f8401126133b457600080fd5b50813567ffffffffffffffff8111156133cc57600080fd5b6020830191508360208260051b85010111156133e757600080fd5b9250929050565b6000806020838503121561340157600080fd5b823567ffffffffffffffff81111561341857600080fd5b613424858286016133a2565b90969095509350505050565b60005b8381101561344b578181015183820152602001613433565b50506000910152565b6000815180845261346c816020860160208601613430565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006134b16020830184613454565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114612e9257600080fd5b80356134e5816134b8565b919050565b6000602082840312156134fc57600080fd5b81356134b1816134b8565b6020808252825182820181905260009190848201906040850190845b8181101561353f57835183529284019291840191600101613523565b50909695505050505050565b60006060828403121561355d57600080fd5b50919050565b60006020828403121561357557600080fd5b5035919050565b6000610140825184526020830151602085015260408301516135aa604086018267ffffffffffffffff169052565b5060608301516135c6606086018267ffffffffffffffff169052565b5060808301516135e2608086018267ffffffffffffffff169052565b5060a083015160a085015260c083015161361460c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161363c60e086018273ffffffffffffffffffffffffffffffffffffffff169052565b50610100838101511515908501526101208084015181860183905261069783870182613454565b6020815260006134b1602083018461357c565b6000806040838503121561368957600080fd5b8235613694816134b8565b946020939093013593505050565b6000602082840312156136b457600080fd5b813567ffffffffffffffff8111156136cb57600080fd5b820160c081850312156134b157600080fd5b600060e0828403121561355d57600080fd5b60006020828403121561370157600080fd5b813567ffffffffffffffff81111561371857600080fd5b8201604081850312156134b157600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126137bc57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126137fb57600080fd5b83018035915067ffffffffffffffff82111561381657600080fd5b6020019150600581901b36038213156133e757600080fd5b60405160c0810167ffffffffffffffff8111828210171561385157613851613759565b60405290565b6040516080810167ffffffffffffffff8111828210171561385157613851613759565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156138c1576138c1613759565b604052919050565b600067ffffffffffffffff8211156138e3576138e3613759565b5060051b60200190565b8015158114612e9257600080fd5b80356134e5816138ed565b600067ffffffffffffffff82111561392057613920613759565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261395d57600080fd5b813561397061396b82613906565b61387a565b81815284602083860101111561398557600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156139b457600080fd5b6139bc61382e565b905081356139c9816134b8565b8152602082013567ffffffffffffffff80821682146139e757600080fd5b8160208401526139f9604085016138fb565b6040840152606084013560608401526080840135915080821115613a1c57600080fd5b50613a298482850161394c565b60808301525060a082013560a082015292915050565b6000613a4d61396b846138c9565b80848252602080830192508560051b850136811115613a6b57600080fd5b855b81811015613aa757803567ffffffffffffffff811115613a8d5760008081fd5b613a9936828a016139a2565b865250938201938201613a6d565b50919695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561053457610534613ab3565b600060408284031215613b0757600080fd5b6040516040810181811067ffffffffffffffff82111715613b2a57613b2a613759565b604052823581526020928301359281019290925250919050565b600060408284031215613b5657600080fd5b6134b18383613af5565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613b9557600080fd5b83018035915067ffffffffffffffff821115613bb057600080fd5b6020019150600681901b36038213156133e757600080fd5b60008451613bda818460208901613430565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551613c16816001850160208a01613430565b60019201918201528351613c31816002840160208801613430565b0160020195945050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126137bc57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613ca757600080fd5b83018035915067ffffffffffffffff821115613cc257600080fd5b60200191506060810236038213156133e757600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff418336030181126137bc57600080fd5b600061053436836139a2565b600060608284031215613d2b57600080fd5b6040516060810181811067ffffffffffffffff82111715613d4e57613d4e613759565b604052905080823560ff81168114613d6557600080fd5b8082525060208301356020820152604083013560408201525092915050565b600060608284031215613d9657600080fd5b6134b18383613d19565b600181811c90821680613db457607f821691505b60208210810361355d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060c08236031215613dff57600080fd5b613e07613857565b82358152602083013567ffffffffffffffff811115613e2557600080fd5b613e31368286016139a2565b602083015250613e443660408501613d19565b604082015260a0830135613e57816134b8565b606082015292915050565b600082601f830112613e7357600080fd5b81356020613e8361396b836138c9565b82815260609283028501820192828201919087851115613ea257600080fd5b8387015b85811015613ec557613eb88982613d19565b8452928401928101613ea6565b5090979650505050505050565b600060808236031215613ee457600080fd5b613eec613857565b8235815260208084013567ffffffffffffffff80821115613f0c57600080fd5b9085019036601f830112613f1f57600080fd5b8135613f2d61396b826138c9565b81815260069190911b83018401908481019036831115613f4c57600080fd5b938501935b82851015613f7557613f633686613af5565b82528582019150604085019450613f51565b80868801525050506040860135925080831115613f9157600080fd5b5050613f9f36828601613e62565b604083015250613e57606084016134da565b600060e08284031215613fc357600080fd5b613fcb613857565b82358152613fdc8460208501613af5565b6020820152613fee8460608501613d19565b604082015260c0830135614001816134b8565b60608201529392505050565b6000602080838503121561402057600080fd5b825167ffffffffffffffff8082111561403857600080fd5b908401906080828703121561404c57600080fd5b614054613857565b8251815283830151614065816134b8565b818501526040830151614077816138ed565b604082015260608301518281111561408e57600080fd5b80840193505086601f8401126140a357600080fd5b825191506140b361396b83613906565b82815287858486010111156140c757600080fd5b6140d683868301878701613430565b60608201529695505050505050565b601f82111561072057600081815260208120601f850160051c8101602086101561410c5750805b601f850160051c820191505b8181101561412b57828155600101614118565b505050505050565b815167ffffffffffffffff81111561414d5761414d613759565b6141618161415b8454613da0565b846140e5565b602080601f8311600181146141b4576000841561417e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561412b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614201578886015182559484019460019091019084016141e2565b508582101561423d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361427e5761427e613ab3565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826142c3576142c3614285565b500490565b6000826142d7576142d7614285565b500690565b8082018082111561053457610534613ab3565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b60588301528460598301528351614388816079850160208801613430565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a9950505050505050505050565b6000602082840312156143df57600080fd5b81516134b1816138ed565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561445f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261444d86835161357c565b95509382019390820190600101614413565b50508584038187015286518085528782019482019350915060005b828110156144965784518452938101939281019260010161447a565b5091979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000813000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "attest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)))": { - "details": "Attests to a specific schema.", - "params": { - "request": "The arguments of the attestation request. Example: attest({ schema: \"0facc36681cbe2456019c1b0d1e7bedd6d1d40f6f324bf3dd3a4cef2999200a0\", data: { recipient: \"0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf\", expirationTime: 0, revocable: true, refUID: \"0x0000000000000000000000000000000000000000000000000000000000000000\", data: \"0xF00D\", value: 0 } })" - }, - "returns": { - "_0": "The UID of the new attestation." - } - }, - "attestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256),(uint8,bytes32,bytes32),address))": { - "details": "Attests to a specific schema via the provided EIP712 signature.", - "params": { - "delegatedRequest": "The arguments of the delegated attestation request. Example: attestByDelegation({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 0 }, signature: { v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, attester: '0xc5E8740aD971409492b1A63Db8d83025e0Fc427e' })" - }, - "returns": { - "_0": "The UID of the new attestation." - } - }, - "constructor": { - "details": "Creates a new EAS instance." - }, - "getAttestation(bytes32)": { - "details": "Returns an existing attestation by UID.", - "params": { - "uid": "The UID of the attestation to retrieve." - }, - "returns": { - "_0": "The attestation data members." - } - }, - "getDomainSeparator()": { - "details": "Returns the domain separator used in the encoding of the signatures for attest, and revoke." - }, - "getNonce(address)": { - "details": "Returns the current nonce per-account.", - "params": { - "account": "The requested account." - }, - "returns": { - "_0": "The current nonce." - } - }, - "getRevokeOffchain(address,bytes32)": { - "details": "Returns the timestamp that the specified data was timestamped with.", - "params": { - "data": "The data to query." - }, - "returns": { - "_0": "The timestamp the data was timestamped with." - } - }, - "getSchemaRegistry()": { - "details": "Returns the address of the global schema registry.", - "returns": { - "_0": "The address of the global schema registry." - } - }, - "getTimestamp(bytes32)": { - "details": "Returns the timestamp that the specified data was timestamped with.", - "params": { - "data": "The data to query." - }, - "returns": { - "_0": "The timestamp the data was timestamped with." - } - }, - "isAttestationValid(bytes32)": { - "details": "Checks whether an attestation exists.", - "params": { - "uid": "The UID of the attestation to retrieve." - }, - "returns": { - "_0": "Whether an attestation exists." - } - }, - "multiAttest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[])[])": { - "details": "Attests to multiple schemas.", - "params": { - "multiRequests": "The arguments of the multi attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization. Example: multiAttest([{ schema: '0x33e9094830a5cba5554d1954310e4fbed2ef5f859ec1404619adea4207f391fd', data: [{ recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 1000 }, { recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 0, revocable: false, refUID: '0x480df4a039efc31b11bfdf491b383ca138b6bde160988222a2a3509c02cee174', data: '0x00', value: 0 }], }, { schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', data: [{ recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 0, revocable: true, refUID: '0x75bf2ed8dca25a8190c50c52db136664de25b2449535839008ccfdab469b214f', data: '0x12345678', value: 0 }, }])" - }, - "returns": { - "_0": "The UIDs of the new attestations." - } - }, - "multiAttestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[],(uint8,bytes32,bytes32)[],address)[])": { - "details": "Attests to multiple schemas using via provided EIP712 signatures.", - "params": { - "multiDelegatedRequests": "The arguments of the delegated multi attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization. Example: multiAttestByDelegation([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 0 }, { recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 0, revocable: false, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x00', value: 0 }], signatures: [{ v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, { v: 28, r: '0x487s...67bb', s: '0x12ad...2366' }], attester: '0x1D86495b2A7B524D747d2839b3C645Bed32e8CF4' }])" - }, - "returns": { - "_0": "The UIDs of the new attestations." - } - }, - "multiRevoke((bytes32,(bytes32,uint256)[])[])": { - "details": "Revokes existing attestations to multiple schemas.", - "params": { - "multiRequests": "The arguments of the multi revocation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization. Example: multiRevoke([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', value: 1000 }, { uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', value: 0 }], }, { schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', data: [{ uid: '0x053d42abce1fd7c8fcddfae21845ad34dae287b2c326220b03ba241bc5a8f019', value: 0 }, }])" - } - }, - "multiRevokeByDelegation((bytes32,(bytes32,uint256)[],(uint8,bytes32,bytes32)[],address)[])": { - "details": "Revokes existing attestations to multiple schemas via provided EIP712 signatures.", - "params": { - "multiDelegatedRequests": "The arguments of the delegated multi revocation attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization. Example: multiRevokeByDelegation([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', value: 1000 }, { uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', value: 0 }], signatures: [{ v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, { v: 28, r: '0x487s...67bb', s: '0x12ad...2366' }], revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992' }])" - } - }, - "multiRevokeOffchain(bytes32[])": { - "details": "Revokes the specified multiple bytes32 data.", - "params": { - "data": "The data to timestamp." - }, - "returns": { - "_0": "The timestamp the data was revoked with." - } - }, - "multiTimestamp(bytes32[])": { - "details": "Timestamps the specified multiple bytes32 data.", - "params": { - "data": "The data to timestamp." - }, - "returns": { - "_0": "The timestamp the data was timestamped with." - } - }, - "revoke((bytes32,(bytes32,uint256)))": { - "details": "Revokes an existing attestation to a specific schema. Example: revoke({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { uid: '0x101032e487642ee04ee17049f99a70590c735b8614079fc9275f9dd57c00966d', value: 0 } })", - "params": { - "request": "The arguments of the revocation request." - } - }, - "revokeByDelegation((bytes32,(bytes32,uint256),(uint8,bytes32,bytes32),address))": { - "details": "Revokes an existing attestation to a specific schema via the provided EIP712 signature. Example: revokeByDelegation({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { uid: '0xcbbc12102578c642a0f7b34fe7111e41afa25683b6cd7b5a14caf90fa14d24ba', value: 0 }, signature: { v: 27, r: '0xb593...7142', s: '0x0f5b...2cce' }, revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992' })", - "params": { - "delegatedRequest": "The arguments of the delegated revocation request." - } - }, - "revokeOffchain(bytes32)": { - "details": "Revokes the specified bytes32 data.", - "params": { - "data": "The data to timestamp." - }, - "returns": { - "_0": "The timestamp the data was revoked with." - } - }, - "timestamp(bytes32)": { - "details": "Timestamps the specified bytes32 data.", - "params": { - "data": "The data to timestamp." - }, - "returns": { - "_0": "The timestamp the data was timestamped with." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "events": { - "Attested(address,address,bytes32,bytes32)": { - "details": "Emitted when an attestation has been made.", - "params": { - "attester": "The attesting account.", - "recipient": "The recipient of the attestation.", - "schema": "The UID of the schema.", - "uid": "The UID the revoked attestation." - } - }, - "Revoked(address,address,bytes32,bytes32)": { - "details": "Emitted when an attestation has been revoked.", - "params": { - "attester": "The attesting account.", - "recipient": "The recipient of the attestation.", - "schema": "The UID of the schema.", - "uid": "The UID the revoked attestation." - } - }, - "RevokedOffchain(address,bytes32,uint64)": { - "details": "Emitted when a data has been revoked.", - "params": { - "data": "The data.", - "revoker": "The address of the revoker.", - "timestamp": "The timestamp." - } - }, - "Timestamped(bytes32,uint64)": { - "details": "Emitted when a data has been timestamped.", - "params": { - "data": "The data.", - "timestamp": "The timestamp." - } - } - }, - "title": "EAS" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"AccessDenied\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"AlreadyRevoked\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"AlreadyRevokedOffchain\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"AlreadyTimestamped\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InsufficientValue\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidAttestation\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidAttestations\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidExpirationTime\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidLength\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidOffset\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidRegistry\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidRevocation\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidRevocations\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidSchema\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidSignature\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidVerifier\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"Irrevocable\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"NotFound\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"NotPayable\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"WrongSchema\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\",\"indexed\":false},{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Attested\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\",\"indexed\":false},{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Revoked\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\",\"indexed\":true}],\"type\":\"event\",\"name\":\"RevokedOffchain\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Timestamped\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"struct AttestationRequest\",\"name\":\"request\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct AttestationRequestData\",\"name\":\"data\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"attest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[{\"internalType\":\"struct DelegatedAttestationRequest\",\"name\":\"delegatedRequest\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct AttestationRequestData\",\"name\":\"data\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]},{\"internalType\":\"struct EIP712Signature\",\"name\":\"signature\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}]},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"attestByDelegation\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"getAttestTypeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getAttestation\",\"outputs\":[{\"internalType\":\"struct Attestation\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"time\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"revocationTime\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}]}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getDomainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getRevokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"getRevokeTypeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"getSchemaRegistry\",\"outputs\":[{\"internalType\":\"contract ISchemaRegistry\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getTimestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"isAttestationValid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"struct MultiAttestationRequest[]\",\"name\":\"multiRequests\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct AttestationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"multiAttest\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}]},{\"inputs\":[{\"internalType\":\"struct MultiDelegatedAttestationRequest[]\",\"name\":\"multiDelegatedRequests\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct AttestationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]},{\"internalType\":\"struct EIP712Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}]},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"multiAttestByDelegation\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}]},{\"inputs\":[{\"internalType\":\"struct MultiRevocationRequest[]\",\"name\":\"multiRequests\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct RevocationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"multiRevoke\"},{\"inputs\":[{\"internalType\":\"struct MultiDelegatedRevocationRequest[]\",\"name\":\"multiDelegatedRequests\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct RevocationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]},{\"internalType\":\"struct EIP712Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}]},{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"multiRevokeByDelegation\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"data\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"multiRevokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"data\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"multiTimestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"struct RevocationRequest\",\"name\":\"request\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct RevocationRequestData\",\"name\":\"data\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"revoke\"},{\"inputs\":[{\"internalType\":\"struct DelegatedRevocationRequest\",\"name\":\"delegatedRequest\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct RevocationRequestData\",\"name\":\"data\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]},{\"internalType\":\"struct EIP712Signature\",\"name\":\"signature\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}]},{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"revokeByDelegation\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"revokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"timestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"attest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)))\":{\"details\":\"Attests to a specific schema.\",\"params\":{\"request\":\"The arguments of the attestation request. Example: attest({ schema: \\\"0facc36681cbe2456019c1b0d1e7bedd6d1d40f6f324bf3dd3a4cef2999200a0\\\", data: { recipient: \\\"0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf\\\", expirationTime: 0, revocable: true, refUID: \\\"0x0000000000000000000000000000000000000000000000000000000000000000\\\", data: \\\"0xF00D\\\", value: 0 } })\"},\"returns\":{\"_0\":\"The UID of the new attestation.\"}},\"attestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256),(uint8,bytes32,bytes32),address))\":{\"details\":\"Attests to a specific schema via the provided EIP712 signature.\",\"params\":{\"delegatedRequest\":\"The arguments of the delegated attestation request. Example: attestByDelegation({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 0 }, signature: { v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, attester: '0xc5E8740aD971409492b1A63Db8d83025e0Fc427e' })\"},\"returns\":{\"_0\":\"The UID of the new attestation.\"}},\"constructor\":{\"details\":\"Creates a new EAS instance.\"},\"getAttestation(bytes32)\":{\"details\":\"Returns an existing attestation by UID.\",\"params\":{\"uid\":\"The UID of the attestation to retrieve.\"},\"returns\":{\"_0\":\"The attestation data members.\"}},\"getDomainSeparator()\":{\"details\":\"Returns the domain separator used in the encoding of the signatures for attest, and revoke.\"},\"getNonce(address)\":{\"details\":\"Returns the current nonce per-account.\",\"params\":{\"account\":\"The requested account.\"},\"returns\":{\"_0\":\"The current nonce.\"}},\"getRevokeOffchain(address,bytes32)\":{\"details\":\"Returns the timestamp that the specified data was timestamped with.\",\"params\":{\"data\":\"The data to query.\"},\"returns\":{\"_0\":\"The timestamp the data was timestamped with.\"}},\"getSchemaRegistry()\":{\"details\":\"Returns the address of the global schema registry.\",\"returns\":{\"_0\":\"The address of the global schema registry.\"}},\"getTimestamp(bytes32)\":{\"details\":\"Returns the timestamp that the specified data was timestamped with.\",\"params\":{\"data\":\"The data to query.\"},\"returns\":{\"_0\":\"The timestamp the data was timestamped with.\"}},\"isAttestationValid(bytes32)\":{\"details\":\"Checks whether an attestation exists.\",\"params\":{\"uid\":\"The UID of the attestation to retrieve.\"},\"returns\":{\"_0\":\"Whether an attestation exists.\"}},\"multiAttest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[])[])\":{\"details\":\"Attests to multiple schemas.\",\"params\":{\"multiRequests\":\"The arguments of the multi attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization. Example: multiAttest([{ schema: '0x33e9094830a5cba5554d1954310e4fbed2ef5f859ec1404619adea4207f391fd', data: [{ recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 1000 }, { recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 0, revocable: false, refUID: '0x480df4a039efc31b11bfdf491b383ca138b6bde160988222a2a3509c02cee174', data: '0x00', value: 0 }], }, { schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', data: [{ recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 0, revocable: true, refUID: '0x75bf2ed8dca25a8190c50c52db136664de25b2449535839008ccfdab469b214f', data: '0x12345678', value: 0 }, }])\"},\"returns\":{\"_0\":\"The UIDs of the new attestations.\"}},\"multiAttestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[],(uint8,bytes32,bytes32)[],address)[])\":{\"details\":\"Attests to multiple schemas using via provided EIP712 signatures.\",\"params\":{\"multiDelegatedRequests\":\"The arguments of the delegated multi attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization. Example: multiAttestByDelegation([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 0 }, { recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 0, revocable: false, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x00', value: 0 }], signatures: [{ v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, { v: 28, r: '0x487s...67bb', s: '0x12ad...2366' }], attester: '0x1D86495b2A7B524D747d2839b3C645Bed32e8CF4' }])\"},\"returns\":{\"_0\":\"The UIDs of the new attestations.\"}},\"multiRevoke((bytes32,(bytes32,uint256)[])[])\":{\"details\":\"Revokes existing attestations to multiple schemas.\",\"params\":{\"multiRequests\":\"The arguments of the multi revocation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization. Example: multiRevoke([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', value: 1000 }, { uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', value: 0 }], }, { schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', data: [{ uid: '0x053d42abce1fd7c8fcddfae21845ad34dae287b2c326220b03ba241bc5a8f019', value: 0 }, }])\"}},\"multiRevokeByDelegation((bytes32,(bytes32,uint256)[],(uint8,bytes32,bytes32)[],address)[])\":{\"details\":\"Revokes existing attestations to multiple schemas via provided EIP712 signatures.\",\"params\":{\"multiDelegatedRequests\":\"The arguments of the delegated multi revocation attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization. Example: multiRevokeByDelegation([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', value: 1000 }, { uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', value: 0 }], signatures: [{ v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, { v: 28, r: '0x487s...67bb', s: '0x12ad...2366' }], revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992' }])\"}},\"multiRevokeOffchain(bytes32[])\":{\"details\":\"Revokes the specified multiple bytes32 data.\",\"params\":{\"data\":\"The data to timestamp.\"},\"returns\":{\"_0\":\"The timestamp the data was revoked with.\"}},\"multiTimestamp(bytes32[])\":{\"details\":\"Timestamps the specified multiple bytes32 data.\",\"params\":{\"data\":\"The data to timestamp.\"},\"returns\":{\"_0\":\"The timestamp the data was timestamped with.\"}},\"revoke((bytes32,(bytes32,uint256)))\":{\"details\":\"Revokes an existing attestation to a specific schema. Example: revoke({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { uid: '0x101032e487642ee04ee17049f99a70590c735b8614079fc9275f9dd57c00966d', value: 0 } })\",\"params\":{\"request\":\"The arguments of the revocation request.\"}},\"revokeByDelegation((bytes32,(bytes32,uint256),(uint8,bytes32,bytes32),address))\":{\"details\":\"Revokes an existing attestation to a specific schema via the provided EIP712 signature. Example: revokeByDelegation({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { uid: '0xcbbc12102578c642a0f7b34fe7111e41afa25683b6cd7b5a14caf90fa14d24ba', value: 0 }, signature: { v: 27, r: '0xb593...7142', s: '0x0f5b...2cce' }, revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992' })\",\"params\":{\"delegatedRequest\":\"The arguments of the delegated revocation request.\"}},\"revokeOffchain(bytes32)\":{\"details\":\"Revokes the specified bytes32 data.\",\"params\":{\"data\":\"The data to timestamp.\"},\"returns\":{\"_0\":\"The timestamp the data was revoked with.\"}},\"timestamp(bytes32)\":{\"details\":\"Timestamps the specified bytes32 data.\",\"params\":{\"data\":\"The data to timestamp.\"},\"returns\":{\"_0\":\"The timestamp the data was timestamped with.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getAttestTypeHash()\":{\"notice\":\"Returns the EIP712 type hash for the attest function.\"},\"getName()\":{\"notice\":\"Returns the EIP712 name.\"},\"getRevokeTypeHash()\":{\"notice\":\"Returns the EIP712 type hash for the revoke function.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"contracts/EAS/EAS.sol\":\"EAS\"},\"libraries\":{}},\"sources\":{\"contracts/EAS/Common.sol\":{\"keccak256\":\"0x922fda236f56fa813171ac1ae04d70d58763142ed084e36d29b369160f99acef\",\"urls\":[\"bzz-raw://82c6eb5ce50a0cfa28ad70fcd33fcd7f7704d538666127dc7aca32960423851b\",\"dweb:/ipfs/QmVQXmi9d7R4iks3rKNQKsq9HeuHZwpCg68jFbYGTw3VUs\"],\"license\":\"MIT\"},\"contracts/EAS/EAS.sol\":{\"keccak256\":\"0xc93349cf7bee9e8fe70dceb66dde09b9ad8dc10fe58626b27b17e385a35e454f\",\"urls\":[\"bzz-raw://350da593f44fda2c73b2d41728b40187cb1ae975a88f7f6ea3b7396542ef8ee6\",\"dweb:/ipfs/QmRr5oJa7YSQ2VCdWkwERWWy2oq8jcmVJ51kGmeQjBxgxQ\"],\"license\":\"MIT\"},\"contracts/EAS/IEAS.sol\":{\"keccak256\":\"0x4b8a0893a5184ef6f5025af10362deb802e59a95082b928eeaed6774b44a84c3\",\"urls\":[\"bzz-raw://0470b6ea4e572b0f43167a2d797a9470c5bc11fd95408f2a1c85962f6d83bf8c\",\"dweb:/ipfs/QmWM2nnP6hqXoorx85jsL5oFUaNbyN918F5dqd3kdhf6MD\"],\"license\":\"MIT\"},\"contracts/EAS/ISchemaRegistry.sol\":{\"keccak256\":\"0x456637ee808bb949d3941cd8b11581a7e7e0a92f304dbbf06fba320f27f57664\",\"urls\":[\"bzz-raw://372bc7f2fc72460daa5273200ac0d6b81427a23a65c8f5152a0f0fe2a47567d7\",\"dweb:/ipfs/QmSDDuVvp5nXaNDPzZbDMH1YE2nN4nrK8hEDctWds4wRah\"],\"license\":\"MIT\"},\"contracts/EAS/eip712/EIP712Verifier.sol\":{\"keccak256\":\"0x003d42b51615b5289e4cb3fcb57619be2e658187702ef2a190fb00129a3dfa72\",\"urls\":[\"bzz-raw://3ea08f8aeaf7b0ba98951e6c3815a0fd6cefaee06a521fd52125e1d43fad50fb\",\"dweb:/ipfs/Qmccb3grHDFkavAWkoyPdyTfSXHPcx51Rhoni3DhfQH76S\"],\"license\":\"MIT\"},\"contracts/EAS/resolver/ISchemaResolver.sol\":{\"keccak256\":\"0x222f41e52e73c3edf2adcddd65c1c6911287b701b07413959a2f720778136135\",\"urls\":[\"bzz-raw://5b3fc66b38c358c3aa704aa3c22bfe7d48063f18529dbc6b61666d0609ffd658\",\"dweb:/ipfs/QmcHBVQzH4mTV1afqQrYw83kgknNETQ1brgWryBwN6u3mf\"],\"license\":\"MIT\"},\"contracts/libraries/Predeploys.sol\":{\"keccak256\":\"0xe46f53d83bbc978cebc11cb702e6b9f046cfbafdcbb79bba2837edf28515cbe4\",\"urls\":[\"bzz-raw://c80c47543cad25cc10ddd7ec2a2399ef1dac50bd5c90d8042211ded0692416a8\",\"dweb:/ipfs/QmeKCGE85eJpJzEXSLmQmhWT9aniSqvwNc8XDcSVedh9F8\"],\"license\":\"MIT\"},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0xc455c84bb1f17e994dea0451fd363f81f83965bfa86e81ac6c8b3a327b9a0ff0\",\"urls\":[\"bzz-raw://fab499f3c0d7df8eb763b50621848d5d2147fb9c42a8eb9b65a11093090bb482\",\"dweb:/ipfs/QmUKsG4ztwtUZFjuRYAxgUFTgH5YxWSGF1BFFaB7vdM2K3\"],\"license\":\"MIT\"},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"],\"license\":\"MIT\"},\"node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0xdb7f5c28fc61cda0bd8ab60ce288e206b791643bcd3ba464a70cbec18895a2f5\",\"urls\":[\"bzz-raw://bf52bdf22a33263f5ca6227a35faeac3b81e7d2c692fbcc6a079d488710c5900\",\"dweb:/ipfs/QmcmsjkP4yq3UhiJbvyzwufaY2EKh1zhHaRK8ATag2cpD2\"],\"license\":\"MIT\"},\"node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"keccak256\":\"0x6688fad58b9ec0286d40fa957152e575d5d8bd4c3aa80985efdb11b44f776ae7\",\"urls\":[\"bzz-raw://8bc00ab7f133cdaafd212a5cc6a16c8d37319721105d130c8e5af0c4e8f170ba\",\"dweb:/ipfs/QmVmf6LVMfFiEkvKYLzSv3bGHzymEW93AcUuFrNUdY3NtT\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 1, - "receipt": { - "transactionHash": "0xbb2fc2851a8ecca324ffff4e3918d242feee63421798c0939ee1989c4c74a374", - "transactionIndex": "0x1", - "blockHash": "0x7a30ec8bc826b69ce2cf50106457dc27621dbda6f656856cffd37eb0530a3c16", - "blockNumber": "0xbaad12", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0x3b5b40", - "gasUsed": "0x3aa40b", - "contractAddress": "0x5A633F1cc84B03F7588486CF2F386c102061E6e1", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb2d05e32" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 27260, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "_nonces", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_address,t_uint256)" - }, - { - "astId": 27266, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 24954, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "_db", - "offset": 0, - "slot": "50", - "type": "t_mapping(t_bytes32,t_struct(Attestation)24729_storage)" - }, - { - "astId": 24958, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "_timestamps", - "offset": 0, - "slot": "51", - "type": "t_mapping(t_bytes32,t_uint64)" - }, - { - "astId": 24964, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "_revocationsOffchain", - "offset": 0, - "slot": "52", - "type": "t_mapping(t_address,t_mapping(t_bytes32,t_uint64))" - }, - { - "astId": 24970, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "__gap", - "offset": 0, - "slot": "53", - "type": "t_array(t_uint256)47_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)47_storage": { - "encoding": "inplace", - "label": "uint256[47]", - "numberOfBytes": "1504", - "base": "t_uint256" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "encoding": "bytes", - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_bytes32,t_uint64))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(bytes32 => uint64))", - "numberOfBytes": "32", - "value": "t_mapping(t_bytes32,t_uint64)" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_mapping(t_bytes32,t_struct(Attestation)24729_storage)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => struct Attestation)", - "numberOfBytes": "32", - "value": "t_struct(Attestation)24729_storage" - }, - "t_mapping(t_bytes32,t_uint64)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => uint64)", - "numberOfBytes": "32", - "value": "t_uint64" - }, - "t_struct(Attestation)24729_storage": { - "encoding": "inplace", - "label": "struct Attestation", - "numberOfBytes": "224", - "members": [ - { - "astId": 24710, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "uid", - "offset": 0, - "slot": "0", - "type": "t_bytes32" - }, - { - "astId": 24712, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "schema", - "offset": 0, - "slot": "1", - "type": "t_bytes32" - }, - { - "astId": 24714, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "time", - "offset": 0, - "slot": "2", - "type": "t_uint64" - }, - { - "astId": 24716, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "expirationTime", - "offset": 8, - "slot": "2", - "type": "t_uint64" - }, - { - "astId": 24718, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "revocationTime", - "offset": 16, - "slot": "2", - "type": "t_uint64" - }, - { - "astId": 24720, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "refUID", - "offset": 0, - "slot": "3", - "type": "t_bytes32" - }, - { - "astId": 24722, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "recipient", - "offset": 0, - "slot": "4", - "type": "t_address" - }, - { - "astId": 24724, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "attester", - "offset": 0, - "slot": "5", - "type": "t_address" - }, - { - "astId": 24726, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "revocable", - "offset": 20, - "slot": "5", - "type": "t_bool" - }, - { - "astId": 24728, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "data", - "offset": 0, - "slot": "6", - "type": "t_bytes_storage" - } - ] - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - } - } - }, - "transactionHash": "0xbb2fc2851a8ecca324ffff4e3918d242feee63421798c0939ee1989c4c74a374", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "getAttestTypeHash()": { - "notice": "Returns the EIP712 type hash for the attest function." - }, - "getName()": { - "notice": "Returns the EIP712 name." - }, - "getRevokeTypeHash()": { - "notice": "Returns the EIP712 type hash for the revoke function." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "The Ethereum Attestation Service protocol." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/GasPriceOracle.json b/packages/contracts-bedrock/deployments/optimism-goerli/GasPriceOracle.json deleted file mode 100644 index 5dc77e21e5b6..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/GasPriceOracle.json +++ /dev/null @@ -1,267 +0,0 @@ -{ - "address": "0xb43C412454f5D1e58Fe895B1a832B6700ADB5FA7", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "DECIMALS", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseFee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "gasPrice", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "getL1Fee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "getL1GasUsed", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1BaseFee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "overhead", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "scalar", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x8c489a43a92cc7afceee05a095642087bea53073b1505b269503e0319e666948", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0xb43C412454f5D1e58Fe895B1a832B6700ADB5FA7", - "transactionIndex": 1, - "gasUsed": "610049", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xfb9046eb324ab0aa228b408fcde63bc29ec696fca1bb90e7f0391402b799f518", - "transactionHash": "0x8c489a43a92cc7afceee05a095642087bea53073b1505b269503e0319e666948", - "logs": [], - "blockNumber": 8579685, - "cumulativeGasUsed": "656962", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"DECIMALS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"baseFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gasPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"getL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"getL1GasUsed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1BaseFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"overhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"scalar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"custom:proxied\":\"@custom:predeploy 0x420000000000000000000000000000000000000F\",\"kind\":\"dev\",\"methods\":{\"baseFee()\":{\"returns\":{\"_0\":\"Current L2 base fee.\"}},\"constructor\":{\"custom:semver\":\"1.0.0\"},\"decimals()\":{\"custom:legacy\":\"@notice Retrieves the number of decimals used in the scalar.\",\"returns\":{\"_0\":\"Number of decimals used in the scalar.\"}},\"gasPrice()\":{\"returns\":{\"_0\":\"Current L2 gas price (base fee).\"}},\"getL1Fee(bytes)\":{\"params\":{\"_data\":\"Unsigned fully RLP-encoded transaction to get the L1 fee for.\"},\"returns\":{\"_0\":\"L1 fee that should be paid for the tx\"}},\"getL1GasUsed(bytes)\":{\"params\":{\"_data\":\"Unsigned fully RLP-encoded transaction to get the L1 gas for.\"},\"returns\":{\"_0\":\"Amount of L1 gas used to publish the transaction.\"}},\"l1BaseFee()\":{\"returns\":{\"_0\":\"Latest known L1 base fee.\"}},\"overhead()\":{\"returns\":{\"_0\":\"Current fee overhead.\"}},\"scalar()\":{\"returns\":{\"_0\":\"Current fee scalar.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"GasPriceOracle\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"DECIMALS()\":{\"notice\":\"Number of decimals used in the scalar.\"},\"baseFee()\":{\"notice\":\"Retrieves the current base fee.\"},\"gasPrice()\":{\"notice\":\"Retrieves the current gas price (base fee).\"},\"getL1Fee(bytes)\":{\"notice\":\"Computes the L1 portion of the fee based on the size of the rlp encoded input transaction, the current L1 base fee, and the various dynamic parameters.\"},\"getL1GasUsed(bytes)\":{\"notice\":\"Computes the amount of L1 gas used for a transaction. Adds the overhead which represents the per-transaction gas overhead of posting the transaction and state roots to L1. Adds 68 bytes of padding to account for the fact that the input does not have a signature.\"},\"l1BaseFee()\":{\"notice\":\"Retrieves the latest known L1 base fee.\"},\"overhead()\":{\"notice\":\"Retrieves the current fee overhead.\"},\"scalar()\":{\"notice\":\"Retrieves the current fee scalar.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"This contract maintains the variables responsible for computing the L1 portion of the total fee charged on L2. Before Bedrock, this contract held variables in state that were read during the state transition function to compute the L1 portion of the transaction fee. After Bedrock, this contract now simply proxies the L1Block contract, which has the values used to compute the L1 portion of the fee in its state. The contract exposes an API that is useful for knowing how large the L1 portion of the transaction fee will be. The following events were deprecated with Bedrock: - event OverheadUpdated(uint256 overhead); - event ScalarUpdated(uint256 scalar); - event DecimalsUpdated(uint256 decimals);\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/GasPriceOracle.sol\":\"GasPriceOracle\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L2/GasPriceOracle.sol\":{\"keccak256\":\"0x9b3061d2d5b7841f21ed2ab58096bccbda37ab7416d853c3f83e27bbdbe3ec7c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c86ff50dfd33d81fa9e63ede7e80b3dc57fbe6e53da9cfabae938e6d684dad9d\",\"dweb:/ipfs/Qme2AtXBiNJCmtS2c1BXeaGXUMvvptTD3i2GUncW2EbZ77\"]},\"contracts/L2/L1Block.sol\":{\"keccak256\":\"0xbd2284eeedcdfbb44aeb010c37e109a28a202b6cee62b7091c9a9afb1f461836\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e8afce8fb5023f16e56f9458b3e9ce998740073ef7668d6aade1c0de0512f870\",\"dweb:/ipfs/QmWQ1FNhqJWraS14qq6wYsPngYv6NghHUwgtmvt9PVzhLo\"]},\"contracts/libraries/Predeploys.sol\":{\"keccak256\":\"0xfc30fb239b5f00284f4b8f578a62f0882597e939335c91ea9bc4aab3070ddc43\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fa132267b3a9d98568b4e02cbb68fe2d2c0ca630826242c1b2293a8fa35bd302\",\"dweb:/ipfs/QmdYvcGbaykP6wyBu5T2obXrWK56xGnfWqbYeeWpTChq3w\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]}},\"version\":1}", - "bytecode": "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c081905280610a2361004a823960006102e3015260006102ba015260006102910152610a236000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c806354fd4d5011610076578063de26c4a11161005b578063de26c4a114610123578063f45e65d814610136578063fe173b971461011d57600080fd5b806354fd4d50146101085780636ef25c3a1461011d57600080fd5b8063313ce567116100a7578063313ce567146100e657806349948e0e146100ed578063519b4bd31461010057600080fd5b80630c18c162146100c35780632e0f2625146100de575b600080fd5b6100cb61013e565b6040519081526020015b60405180910390f35b6100cb600681565b60066100cb565b6100cb6100fb3660046105a9565b6101c8565b6100cb610229565b61011061028a565b6040516100d591906106a8565b486100cb565b6100cb6101313660046105a9565b61032d565b6100cb6103dc565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa15801561019f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c391906106f9565b905090565b6000806101d48361032d565b905060006101e0610229565b6101ea9083610741565b905060006101fa6006600a6108a0565b905060006102066103dc565b6102109084610741565b9050600061021e83836108e2565b979650505050505050565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa15801561019f573d6000803e3d6000fd5b60606102b57f000000000000000000000000000000000000000000000000000000000000000061043d565b6102de7f000000000000000000000000000000000000000000000000000000000000000061043d565b6103077f000000000000000000000000000000000000000000000000000000000000000061043d565b604051602001610319939291906108f6565b604051602081830303815290604052905090565b80516000908190815b818110156103b0578481815181106103505761035061096c565b01602001517fff00000000000000000000000000000000000000000000000000000000000000166000036103905761038960048461099b565b925061039e565b61039b60108461099b565b92505b806103a8816109b3565b915050610336565b5060006103bb61013e565b6103c5908461099b565b90506103d38161044061099b565b95945050505050565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa15801561019f573d6000803e3d6000fd5b60608160000361048057505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104aa5780610494816109b3565b91506104a39050600a836108e2565b9150610484565b60008167ffffffffffffffff8111156104c5576104c561057a565b6040519080825280601f01601f1916602001820160405280156104ef576020820181803683370190505b5090505b8415610572576105046001836109eb565b9150610511600a86610a02565b61051c90603061099b565b60f81b8183815181106105315761053161096c565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061056b600a866108e2565b94506104f3565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156105bb57600080fd5b813567ffffffffffffffff808211156105d357600080fd5b818401915084601f8301126105e757600080fd5b8135818111156105f9576105f961057a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561063f5761063f61057a565b8160405282815287602084870101111561065857600080fd5b826020860160208301376000928101602001929092525095945050505050565b60005b8381101561069357818101518382015260200161067b565b838111156106a2576000848401525b50505050565b60208152600082518060208401526106c7816040850160208701610678565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561070b57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561077957610779610712565b500290565b600181815b808511156107d757817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156107bd576107bd610712565b808516156107ca57918102915b93841c9390800290610783565b509250929050565b6000826107ee5750600161089a565b816107fb5750600061089a565b8160018114610811576002811461081b57610837565b600191505061089a565b60ff84111561082c5761082c610712565b50506001821b61089a565b5060208310610133831016604e8410600b841016171561085a575081810a61089a565b610864838361077e565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561089657610896610712565b0290505b92915050565b60006108ac83836107df565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826108f1576108f16108b3565b500490565b60008451610908818460208901610678565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610944816001850160208a01610678565b6001920191820152835161095f816002840160208801610678565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082198211156109ae576109ae610712565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109e4576109e4610712565b5060010190565b6000828210156109fd576109fd610712565b500390565b600082610a1157610a116108b3565b50069056fea164736f6c634300080f000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c806354fd4d5011610076578063de26c4a11161005b578063de26c4a114610123578063f45e65d814610136578063fe173b971461011d57600080fd5b806354fd4d50146101085780636ef25c3a1461011d57600080fd5b8063313ce567116100a7578063313ce567146100e657806349948e0e146100ed578063519b4bd31461010057600080fd5b80630c18c162146100c35780632e0f2625146100de575b600080fd5b6100cb61013e565b6040519081526020015b60405180910390f35b6100cb600681565b60066100cb565b6100cb6100fb3660046105a9565b6101c8565b6100cb610229565b61011061028a565b6040516100d591906106a8565b486100cb565b6100cb6101313660046105a9565b61032d565b6100cb6103dc565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa15801561019f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c391906106f9565b905090565b6000806101d48361032d565b905060006101e0610229565b6101ea9083610741565b905060006101fa6006600a6108a0565b905060006102066103dc565b6102109084610741565b9050600061021e83836108e2565b979650505050505050565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa15801561019f573d6000803e3d6000fd5b60606102b57f000000000000000000000000000000000000000000000000000000000000000061043d565b6102de7f000000000000000000000000000000000000000000000000000000000000000061043d565b6103077f000000000000000000000000000000000000000000000000000000000000000061043d565b604051602001610319939291906108f6565b604051602081830303815290604052905090565b80516000908190815b818110156103b0578481815181106103505761035061096c565b01602001517fff00000000000000000000000000000000000000000000000000000000000000166000036103905761038960048461099b565b925061039e565b61039b60108461099b565b92505b806103a8816109b3565b915050610336565b5060006103bb61013e565b6103c5908461099b565b90506103d38161044061099b565b95945050505050565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa15801561019f573d6000803e3d6000fd5b60608160000361048057505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104aa5780610494816109b3565b91506104a39050600a836108e2565b9150610484565b60008167ffffffffffffffff8111156104c5576104c561057a565b6040519080825280601f01601f1916602001820160405280156104ef576020820181803683370190505b5090505b8415610572576105046001836109eb565b9150610511600a86610a02565b61051c90603061099b565b60f81b8183815181106105315761053161096c565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061056b600a866108e2565b94506104f3565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156105bb57600080fd5b813567ffffffffffffffff808211156105d357600080fd5b818401915084601f8301126105e757600080fd5b8135818111156105f9576105f961057a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561063f5761063f61057a565b8160405282815287602084870101111561065857600080fd5b826020860160208301376000928101602001929092525095945050505050565b60005b8381101561069357818101518382015260200161067b565b838111156106a2576000848401525b50505050565b60208152600082518060208401526106c7816040850160208701610678565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561070b57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561077957610779610712565b500290565b600181815b808511156107d757817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156107bd576107bd610712565b808516156107ca57918102915b93841c9390800290610783565b509250929050565b6000826107ee5750600161089a565b816107fb5750600061089a565b8160018114610811576002811461081b57610837565b600191505061089a565b60ff84111561082c5761082c610712565b50506001821b61089a565b5060208310610133831016604e8410600b841016171561085a575081810a61089a565b610864838361077e565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561089657610896610712565b0290505b92915050565b60006108ac83836107df565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826108f1576108f16108b3565b500490565b60008451610908818460208901610678565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610944816001850160208a01610678565b6001920191820152835161095f816002840160208801610678565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082198211156109ae576109ae610712565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109e4576109e4610712565b5060010190565b6000828210156109fd576109fd610712565b500390565b600082610a1157610a116108b3565b50069056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "baseFee()": { - "returns": { - "_0": "Current L2 base fee." - } - }, - "constructor": {}, - "decimals()": { - "returns": { - "_0": "Number of decimals used in the scalar." - } - }, - "gasPrice()": { - "returns": { - "_0": "Current L2 gas price (base fee)." - } - }, - "getL1Fee(bytes)": { - "params": { - "_data": "Unsigned fully RLP-encoded transaction to get the L1 fee for." - }, - "returns": { - "_0": "L1 fee that should be paid for the tx" - } - }, - "getL1GasUsed(bytes)": { - "params": { - "_data": "Unsigned fully RLP-encoded transaction to get the L1 gas for." - }, - "returns": { - "_0": "Amount of L1 gas used to publish the transaction." - } - }, - "l1BaseFee()": { - "returns": { - "_0": "Latest known L1 base fee." - } - }, - "overhead()": { - "returns": { - "_0": "Current fee overhead." - } - }, - "scalar()": { - "returns": { - "_0": "Current fee scalar." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "GasPriceOracle" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "DECIMALS()": { - "notice": "Number of decimals used in the scalar." - }, - "baseFee()": { - "notice": "Retrieves the current base fee." - }, - "gasPrice()": { - "notice": "Retrieves the current gas price (base fee)." - }, - "getL1Fee(bytes)": { - "notice": "Computes the L1 portion of the fee based on the size of the rlp encoded input transaction, the current L1 base fee, and the various dynamic parameters." - }, - "getL1GasUsed(bytes)": { - "notice": "Computes the amount of L1 gas used for a transaction. Adds the overhead which represents the per-transaction gas overhead of posting the transaction and state roots to L1. Adds 68 bytes of padding to account for the fact that the input does not have a signature." - }, - "l1BaseFee()": { - "notice": "Retrieves the latest known L1 base fee." - }, - "overhead()": { - "notice": "Retrieves the current fee overhead." - }, - "scalar()": { - "notice": "Retrieves the current fee scalar." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "This contract maintains the variables responsible for computing the L1 portion of the total fee charged on L2. Before Bedrock, this contract held variables in state that were read during the state transition function to compute the L1 portion of the transaction fee. After Bedrock, this contract now simply proxies the L1Block contract, which has the values used to compute the L1 portion of the fee in its state. The contract exposes an API that is useful for knowing how large the L1 portion of the transaction fee will be. The following events were deprecated with Bedrock: - event OverheadUpdated(uint256 overhead); - event ScalarUpdated(uint256 scalar); - event DecimalsUpdated(uint256 decimals);" - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/L1Block.json b/packages/contracts-bedrock/deployments/optimism-goerli/L1Block.json deleted file mode 100644 index 6e98dea1b0ac..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/L1Block.json +++ /dev/null @@ -1,360 +0,0 @@ -{ - "address": "0x6dF83A19647A398d48e77a6835F4A28EB7e2f7c0", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "DEPOSITOR_ACCOUNT", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "basefee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "batcherHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "hash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1FeeOverhead", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1FeeScalar", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "number", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "sequenceNumber", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "_number", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "_timestamp", - "type": "uint64" - }, - { - "internalType": "uint256", - "name": "_basefee", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_hash", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "_sequenceNumber", - "type": "uint64" - }, - { - "internalType": "bytes32", - "name": "_batcherHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_l1FeeOverhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_l1FeeScalar", - "type": "uint256" - } - ], - "name": "setL1BlockValues", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "timestamp", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0xea5f379f7e5b1a3e548af70d4f7d0cb8c7fcaa9106fd86403f4617150950f650", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0x6dF83A19647A398d48e77a6835F4A28EB7e2f7c0", - "transactionIndex": 2, - "gasUsed": "483065", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x7ca13a929e32f81a61c5f8b2291bb65331e1224341e40521abfb38ca94387b54", - "transactionHash": "0xea5f379f7e5b1a3e548af70d4f7d0cb8c7fcaa9106fd86403f4617150950f650", - "logs": [], - "blockNumber": 8579658, - "cumulativeGasUsed": "572079", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"DEPOSITOR_ACCOUNT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"basefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batcherHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1FeeOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1FeeScalar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"number\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_number\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"_timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"_basefee\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"_batcherHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1FeeOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l1FeeScalar\",\"type\":\"uint256\"}],\"name\":\"setL1BlockValues\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"custom:proxied\":\"@custom:predeploy 0x4200000000000000000000000000000000000015\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.0.0\"},\"setL1BlockValues(uint64,uint64,uint256,bytes32,uint64,bytes32,uint256,uint256)\":{\"params\":{\"_basefee\":\"L1 basefee.\",\"_batcherHash\":\"Versioned hash to authenticate batcher by.\",\"_hash\":\"L1 blockhash.\",\"_l1FeeOverhead\":\"L1 fee overhead.\",\"_l1FeeScalar\":\"L1 fee scalar.\",\"_number\":\"L1 blocknumber.\",\"_sequenceNumber\":\"Number of L2 blocks since epoch start.\",\"_timestamp\":\"L1 timestamp.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"L1Block\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"DEPOSITOR_ACCOUNT()\":{\"notice\":\"Address of the special depositor account.\"},\"basefee()\":{\"notice\":\"The latest L1 basefee.\"},\"batcherHash()\":{\"notice\":\"The versioned hash to authenticate the batcher by.\"},\"hash()\":{\"notice\":\"The latest L1 blockhash.\"},\"l1FeeOverhead()\":{\"notice\":\"The overhead value applied to the L1 portion of the transaction fee.\"},\"l1FeeScalar()\":{\"notice\":\"The scalar value applied to the L1 portion of the transaction fee.\"},\"number()\":{\"notice\":\"The latest L1 block number known by the L2 system.\"},\"sequenceNumber()\":{\"notice\":\"The number of L2 blocks in the same epoch.\"},\"setL1BlockValues(uint64,uint64,uint256,bytes32,uint64,bytes32,uint256,uint256)\":{\"notice\":\"Updates the L1 block values.\"},\"timestamp()\":{\"notice\":\"The latest L1 timestamp known by the L2 system.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"The L1Block predeploy gives users access to information about the last known L1 block. Values within this contract are updated once per epoch (every L1 block) and can only be set by the \\\"depositor\\\" account, a special system address. Depositor account transactions are created by the protocol whenever we move to a new epoch.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/L1Block.sol\":\"L1Block\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L2/L1Block.sol\":{\"keccak256\":\"0xbd2284eeedcdfbb44aeb010c37e109a28a202b6cee62b7091c9a9afb1f461836\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e8afce8fb5023f16e56f9458b3e9ce998740073ef7668d6aade1c0de0512f870\",\"dweb:/ipfs/QmWQ1FNhqJWraS14qq6wYsPngYv6NghHUwgtmvt9PVzhLo\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]}},\"version\":1}", - "bytecode": "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c0819052806107d661004a82396000610371015260006103480152600061031f01526107d66000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638381f58a11610081578063b80777ea1161005b578063b80777ea14610170578063e591b28214610190578063e81b2c6d146101d057600080fd5b80638381f58a1461014a5780638b239f731461015e5780639e8c49661461016757600080fd5b806354fd4d50116100b257806354fd4d50146100ff5780635cf249691461011457806364ca23ef1461011d57600080fd5b8063015d8eb9146100ce57806309bd5a60146100e3575b600080fd5b6100e16100dc366004610515565b6101d9565b005b6100ec60025481565b6040519081526020015b60405180910390f35b610107610318565b6040516100f691906105b7565b6100ec60015481565b6003546101319067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100f6565b6000546101319067ffffffffffffffff1681565b6100ec60055481565b6100ec60065481565b6000546101319068010000000000000000900467ffffffffffffffff1681565b6101ab73deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60045481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610280576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b60606103437f00000000000000000000000000000000000000000000000000000000000000006103bb565b61036c7f00000000000000000000000000000000000000000000000000000000000000006103bb565b6103957f00000000000000000000000000000000000000000000000000000000000000006103bb565b6040516020016103a793929190610608565b604051602081830303815290604052905090565b6060816000036103fe57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104285780610412816106ad565b91506104219050600a83610714565b9150610402565b60008167ffffffffffffffff81111561044357610443610728565b6040519080825280601f01601f19166020018201604052801561046d576020820181803683370190505b5090505b84156104f057610482600183610757565b915061048f600a8661076e565b61049a906030610782565b60f81b8183815181106104af576104af61079a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104e9600a86610714565b9450610471565b949350505050565b803567ffffffffffffffff8116811461051057600080fd5b919050565b600080600080600080600080610100898b03121561053257600080fd5b61053b896104f8565b975061054960208a016104f8565b9650604089013595506060890135945061056560808a016104f8565b979a969950949793969560a0850135955060c08501359460e001359350915050565b60005b838110156105a257818101518382015260200161058a565b838111156105b1576000848401525b50505050565b60208152600082518060208401526105d6816040850160208701610587565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000845161061a818460208901610587565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610656816001850160208a01610587565b60019201918201528351610671816002840160208801610587565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036106de576106de61067e565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610723576107236106e5565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107695761076961067e565b500390565b60008261077d5761077d6106e5565b500690565b600082198211156107955761079561067e565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100c95760003560e01c80638381f58a11610081578063b80777ea1161005b578063b80777ea14610170578063e591b28214610190578063e81b2c6d146101d057600080fd5b80638381f58a1461014a5780638b239f731461015e5780639e8c49661461016757600080fd5b806354fd4d50116100b257806354fd4d50146100ff5780635cf249691461011457806364ca23ef1461011d57600080fd5b8063015d8eb9146100ce57806309bd5a60146100e3575b600080fd5b6100e16100dc366004610515565b6101d9565b005b6100ec60025481565b6040519081526020015b60405180910390f35b610107610318565b6040516100f691906105b7565b6100ec60015481565b6003546101319067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100f6565b6000546101319067ffffffffffffffff1681565b6100ec60055481565b6100ec60065481565b6000546101319068010000000000000000900467ffffffffffffffff1681565b6101ab73deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60045481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610280576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b60606103437f00000000000000000000000000000000000000000000000000000000000000006103bb565b61036c7f00000000000000000000000000000000000000000000000000000000000000006103bb565b6103957f00000000000000000000000000000000000000000000000000000000000000006103bb565b6040516020016103a793929190610608565b604051602081830303815290604052905090565b6060816000036103fe57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104285780610412816106ad565b91506104219050600a83610714565b9150610402565b60008167ffffffffffffffff81111561044357610443610728565b6040519080825280601f01601f19166020018201604052801561046d576020820181803683370190505b5090505b84156104f057610482600183610757565b915061048f600a8661076e565b61049a906030610782565b60f81b8183815181106104af576104af61079a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104e9600a86610714565b9450610471565b949350505050565b803567ffffffffffffffff8116811461051057600080fd5b919050565b600080600080600080600080610100898b03121561053257600080fd5b61053b896104f8565b975061054960208a016104f8565b9650604089013595506060890135945061056560808a016104f8565b979a969950949793969560a0850135955060c08501359460e001359350915050565b60005b838110156105a257818101518382015260200161058a565b838111156105b1576000848401525b50505050565b60208152600082518060208401526105d6816040850160208701610587565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000845161061a818460208901610587565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610656816001850160208a01610587565b60019201918201528351610671816002840160208801610587565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036106de576106de61067e565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610723576107236106e5565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107695761076961067e565b500390565b60008261077d5761077d6106e5565b500690565b600082198211156107955761079561067e565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": {}, - "setL1BlockValues(uint64,uint64,uint256,bytes32,uint64,bytes32,uint256,uint256)": { - "params": { - "_basefee": "L1 basefee.", - "_batcherHash": "Versioned hash to authenticate batcher by.", - "_hash": "L1 blockhash.", - "_l1FeeOverhead": "L1 fee overhead.", - "_l1FeeScalar": "L1 fee scalar.", - "_number": "L1 blocknumber.", - "_sequenceNumber": "Number of L2 blocks since epoch start.", - "_timestamp": "L1 timestamp." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "L1Block" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "DEPOSITOR_ACCOUNT()": { - "notice": "Address of the special depositor account." - }, - "basefee()": { - "notice": "The latest L1 basefee." - }, - "batcherHash()": { - "notice": "The versioned hash to authenticate the batcher by." - }, - "hash()": { - "notice": "The latest L1 blockhash." - }, - "l1FeeOverhead()": { - "notice": "The overhead value applied to the L1 portion of the transaction fee." - }, - "l1FeeScalar()": { - "notice": "The scalar value applied to the L1 portion of the transaction fee." - }, - "number()": { - "notice": "The latest L1 block number known by the L2 system." - }, - "sequenceNumber()": { - "notice": "The number of L2 blocks in the same epoch." - }, - "setL1BlockValues(uint64,uint64,uint256,bytes32,uint64,bytes32,uint256,uint256)": { - "notice": "Updates the L1 block values." - }, - "timestamp()": { - "notice": "The latest L1 timestamp known by the L2 system." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "The L1Block predeploy gives users access to information about the last known L1 block. Values within this contract are updated once per epoch (every L1 block) and can only be set by the \"depositor\" account, a special system address. Depositor account transactions are created by the protocol whenever we move to a new epoch." - }, - "storageLayout": { - "storage": [ - { - "astId": 3102, - "contract": "contracts/L2/L1Block.sol:L1Block", - "label": "number", - "offset": 0, - "slot": "0", - "type": "t_uint64" - }, - { - "astId": 3105, - "contract": "contracts/L2/L1Block.sol:L1Block", - "label": "timestamp", - "offset": 8, - "slot": "0", - "type": "t_uint64" - }, - { - "astId": 3108, - "contract": "contracts/L2/L1Block.sol:L1Block", - "label": "basefee", - "offset": 0, - "slot": "1", - "type": "t_uint256" - }, - { - "astId": 3111, - "contract": "contracts/L2/L1Block.sol:L1Block", - "label": "hash", - "offset": 0, - "slot": "2", - "type": "t_bytes32" - }, - { - "astId": 3114, - "contract": "contracts/L2/L1Block.sol:L1Block", - "label": "sequenceNumber", - "offset": 0, - "slot": "3", - "type": "t_uint64" - }, - { - "astId": 3117, - "contract": "contracts/L2/L1Block.sol:L1Block", - "label": "batcherHash", - "offset": 0, - "slot": "4", - "type": "t_bytes32" - }, - { - "astId": 3120, - "contract": "contracts/L2/L1Block.sol:L1Block", - "label": "l1FeeOverhead", - "offset": 0, - "slot": "5", - "type": "t_uint256" - }, - { - "astId": 3123, - "contract": "contracts/L2/L1Block.sol:L1Block", - "label": "l1FeeScalar", - "offset": 0, - "slot": "6", - "type": "t_uint256" - } - ], - "types": { - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/L1FeeVault.json b/packages/contracts-bedrock/deployments/optimism-goerli/L1FeeVault.json deleted file mode 100644 index 6a406bb49f71..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/L1FeeVault.json +++ /dev/null @@ -1,191 +0,0 @@ -{ - "address": "0xC7d3389726374B8BFF53116585e20A483415f6f6", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - } - ], - "name": "Withdrawal", - "type": "event" - }, - { - "inputs": [], - "name": "MIN_WITHDRAWAL_AMOUNT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RECIPIENT", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalProcessed", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "withdraw", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x59e591102ee7eb6d0c483d0906df373df211a052397c17f949756c814a138332", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0xC7d3389726374B8BFF53116585e20A483415f6f6", - "transactionIndex": 1, - "gasUsed": "492913", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x3e293acdeeed6687747feb770b99293b7411057574722d2bcf180856fa1f49a8", - "transactionHash": "0x59e591102ee7eb6d0c483d0906df373df211a052397c17f949756c814a138332", - "logs": [], - "blockNumber": 8579702, - "cumulativeGasUsed": "539814", - "status": 1, - "byzantium": true - }, - "args": [ - "0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f" - ], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_WITHDRAWAL_AMOUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RECIPIENT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalProcessed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"custom:proxied\":\"@custom:predeploy 0x420000000000000000000000000000000000001A\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.1.0\",\"params\":{\"_recipient\":\"Address that will receive the accumulated fees.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"L1FeeVault\",\"version\":1},\"userdoc\":{\"events\":{\"Withdrawal(uint256,address,address)\":{\"notice\":\"Emits each time that a withdrawal occurs.\"}},\"kind\":\"user\",\"methods\":{\"MIN_WITHDRAWAL_AMOUNT()\":{\"notice\":\"Minimum balance before a withdrawal can be triggered.\"},\"RECIPIENT()\":{\"notice\":\"Wallet that will receive the fees on L1.\"},\"totalProcessed()\":{\"notice\":\"Total amount of wei processed by the contract.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"},\"withdraw()\":{\"notice\":\"Triggers a withdrawal of funds to the L1 fee wallet.\"}},\"notice\":\"The L1FeeVault accumulates the L1 portion of the transaction fees.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/L1FeeVault.sol\":\"L1FeeVault\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L1/ResourceMetering.sol\":{\"keccak256\":\"0xbd7b9532a70d8c842bfce0ea971be50d02fbbf0227c9ad55c71ac68d438010f4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4969f478dd54e89392cda2ea0c5edcf1be55a5dee43a0e410527b6e3bcb85c88\",\"dweb:/ipfs/QmU2crAojw8DRDsz7PAPrereazjFsKh9wtfTpTDVh6NLfW\"]},\"contracts/L2/L1FeeVault.sol\":{\"keccak256\":\"0x3788c153f2c907f8af0072e9a2d4aa3ec345c91e4c3d0e7bfff002ba518f34c2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c55d8e30118fa0d9c153973931ae24315b9acb168330a6771217c9663fb879e8\",\"dweb:/ipfs/Qmb7JctebXrSVsRAgbEsJd972dVTPSvg9q6taLoZ3DbUBW\"]},\"contracts/L2/L2StandardBridge.sol\":{\"keccak256\":\"0xd77e04c57f33cd32c32f326cd06e213d8a27a9fd372cfc4269953a49243c8c41\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f59627bf4c08c85886e819b29b8565b48fa7e9c230732fedfbb0b9c9a0ee04c5\",\"dweb:/ipfs/Qmao1VbQ57h6gdCZTYfipa8LB1wBwAthop5tPd9TgDXES2\"]},\"contracts/libraries/Arithmetic.sol\":{\"keccak256\":\"0xc8858039f87e48e6f18c1af8bc0b03e57cfef564acddfd06e4d91e3db7ac5ed6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2fc79af1e844aa6dc1c68067bfe1d359df8d4e9a3e8881afb3bcfcbf68071714\",\"dweb:/ipfs/QmcNC4k8zmvwj4kZizSenTiWbx2DJQPbwqXXLF4iMbkRVD\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Constants.sol\":{\"keccak256\":\"0x8c7be28a175eb732995a7f704560163c30261f9f70d377f865c5060882509f5d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f72aba26553b10ca88708e05461691b36b0d2ec7a87f718022fe119ca9c70852\",\"dweb:/ipfs/QmQtDEB1F3D8RsgG63KSJ9t7ZyFLaXc2Av81vKD9y2TMn7\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/Predeploys.sol\":{\"keccak256\":\"0xfc30fb239b5f00284f4b8f578a62f0882597e939335c91ea9bc4aab3070ddc43\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fa132267b3a9d98568b4e02cbb68fe2d2c0ca630826242c1b2293a8fa35bd302\",\"dweb:/ipfs/QmdYvcGbaykP6wyBu5T2obXrWK56xGnfWqbYeeWpTChq3w\"]},\"contracts/libraries/SafeCall.sol\":{\"keccak256\":\"0x6e815b62528d452a4f63040d75ff7a08db8ba8096050a53355fc49abaebdf245\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e27e542a11165c82cbb6961f4d8c2a58527fba1ab915afeeded50e96ce929777\",\"dweb:/ipfs/QmRPXdmUAbL1WHZBvENKWkFuHb9bQyrbiJWwDvzEQBLVi8\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x4fe8ec920798661a828430bd30dc2715eeb40534ec01c0a7bf41cb4ab422e134\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://74c8471869900bd459358cd990bda1c8d234c06b788804c7049cf465ae1e299f\",\"dweb:/ipfs/QmakcfP6NmbVUQsKqH7rEyJsbiqckigLahw9g74oencEJ7\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x3c99b1e768cc4c1e064ccc137b1b4d5961bf4edf071be84cc216c5b20f1c00da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e36b2a6325c2f804d769271575669b62ab2da2df3c81921ac7487399fe02af07\",\"dweb:/ipfs/QmTCmcEKwvD8Xvjyev268Bkz27FC7TJpUbw1nADcsThnUr\"]},\"contracts/universal/FeeVault.sol\":{\"keccak256\":\"0x73eb2c835495ec308c69783db55c6cc315ed2a55ee6811ccda4e7dbbde04b2c8\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b5e46201184138d60e339c98276e3b265717a12795270a1d0ef03157e452e9a0\",\"dweb:/ipfs/QmWGLhTcPuF9ZZfrjGj4QGCzEuDwiyRAMpnQvxd2oLFX75\"]},\"contracts/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x2fea0ee05071c9c6b06a34a8e805801e247e861359b376a8918106e1d6f77ebe\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://198c91bda2edf864ddad1f8ab6168155d13d6ba5487418e5531ff040ff250686\",\"dweb:/ipfs/QmQzxfHY4P7zdVFRh2DTdGt1KeMHaGKNRf3KPZ1mRTYEGB\"]},\"contracts/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x302094342a45ebdf7f46f4fb48821960d2a4134f66fd7f458f73fc4ddf34d219\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b0e2b496e966ca6037e1c9be1d44417c0180fda2a27f68114e93b899defb783\",\"dweb:/ipfs/QmXP76ivMLxYxscC7B9E9qtW3u6HJ2MNaRVeo3x24VEAQH\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"contracts/universal/StandardBridge.sol\":{\"keccak256\":\"0xaa45044774fa70ed322983c3c0138b21d26d75f4b7e8f5324d53c3eef91adec4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c65c95d0cb71f2e32f5ffdea92151a9a46bbd538ba110389a134963fd16a33e9\",\"dweb:/ipfs/QmaPNZokt4j5SCXaWwVtw6qxu5GXWFa3SWBgaSWPPA9KUG\"]},\"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://11756f42121f6541a35a8339ea899ee7514cfaa2e6d740625fcc844419296aa6\",\"dweb:/ipfs/QmekMuk6BY4DAjzeXr4MSbKdgoqqsZnA8JPtuyWc6CwXHf\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]}},\"version\":1}", - "bytecode": "0x61012060405234801561001157600080fd5b506040516108e53803806108e58339810160408190526100309161005d565b678ac7230489e800006080526001600160a01b031660a052600160c081905260e05260006101005261008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b60805160a05160c05160e051610100516108006100e560003960006103d3015260006103aa01526000610381015260008181607c015281816102570152610319015260008181610137015261015b01526108006000f3fe60806040526004361061005e5760003560e01c806354fd4d501161004357806354fd4d50146100df57806384411d6514610101578063d3e5792b1461012557600080fd5b80630d9019e11461006a5780633ccfd60b146100c857600080fd5b3661006557005b600080fd5b34801561007657600080fd5b5061009e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100d457600080fd5b506100dd610159565b005b3480156100eb57600080fd5b506100f461037a565b6040516100bf91906105d4565b34801561010d57600080fd5b5061011760005481565b6040519081526020016100bf565b34801561013157600080fd5b506101177f000000000000000000000000000000000000000000000000000000000000000081565b7f0000000000000000000000000000000000000000000000000000000000000000471015610233576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a40160405180910390fd5b600047905080600080828254610249919061061d565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610345917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610635565b6000604051808303818588803b15801561035e57600080fd5b505af1158015610372573d6000803e3d6000fd5b505050505050565b60606103a57f000000000000000000000000000000000000000000000000000000000000000061041d565b6103ce7f000000000000000000000000000000000000000000000000000000000000000061041d565b6103f77f000000000000000000000000000000000000000000000000000000000000000061041d565b60405160200161040993929190610679565b604051602081830303815290604052905090565b60608160000361046057505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561048a5780610474816106ef565b91506104839050600a83610756565b9150610464565b60008167ffffffffffffffff8111156104a5576104a561076a565b6040519080825280601f01601f1916602001820160405280156104cf576020820181803683370190505b5090505b8415610552576104e4600183610799565b91506104f1600a866107b0565b6104fc90603061061d565b60f81b818381518110610511576105116107c4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061054b600a86610756565b94506104d3565b949350505050565b60005b8381101561057557818101518382015260200161055d565b83811115610584576000848401525b50505050565b600081518084526105a281602086016020860161055a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105e7602083018461058a565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610630576106306105ee565b500190565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff83166020820152606060408201526000610670606083018461058a565b95945050505050565b6000845161068b81846020890161055a565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516106c7816001850160208a0161055a565b600192019182015283516106e281600284016020880161055a565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610720576107206105ee565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261076557610765610727565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107ab576107ab6105ee565b500390565b6000826107bf576107bf610727565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c806354fd4d501161004357806354fd4d50146100df57806384411d6514610101578063d3e5792b1461012557600080fd5b80630d9019e11461006a5780633ccfd60b146100c857600080fd5b3661006557005b600080fd5b34801561007657600080fd5b5061009e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100d457600080fd5b506100dd610159565b005b3480156100eb57600080fd5b506100f461037a565b6040516100bf91906105d4565b34801561010d57600080fd5b5061011760005481565b6040519081526020016100bf565b34801561013157600080fd5b506101177f000000000000000000000000000000000000000000000000000000000000000081565b7f0000000000000000000000000000000000000000000000000000000000000000471015610233576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a40160405180910390fd5b600047905080600080828254610249919061061d565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610345917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610635565b6000604051808303818588803b15801561035e57600080fd5b505af1158015610372573d6000803e3d6000fd5b505050505050565b60606103a57f000000000000000000000000000000000000000000000000000000000000000061041d565b6103ce7f000000000000000000000000000000000000000000000000000000000000000061041d565b6103f77f000000000000000000000000000000000000000000000000000000000000000061041d565b60405160200161040993929190610679565b604051602081830303815290604052905090565b60608160000361046057505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561048a5780610474816106ef565b91506104839050600a83610756565b9150610464565b60008167ffffffffffffffff8111156104a5576104a561076a565b6040519080825280601f01601f1916602001820160405280156104cf576020820181803683370190505b5090505b8415610552576104e4600183610799565b91506104f1600a866107b0565b6104fc90603061061d565b60f81b818381518110610511576105116107c4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061054b600a86610756565b94506104d3565b949350505050565b60005b8381101561057557818101518382015260200161055d565b83811115610584576000848401525b50505050565b600081518084526105a281602086016020860161055a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105e7602083018461058a565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610630576106306105ee565b500190565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff83166020820152606060408201526000610670606083018461058a565b95945050505050565b6000845161068b81846020890161055a565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516106c7816001850160208a0161055a565b600192019182015283516106e281600284016020880161055a565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610720576107206105ee565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261076557610765610727565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107ab576107ab6105ee565b500390565b6000826107bf576107bf610727565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_recipient": "Address that will receive the accumulated fees." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "L1FeeVault" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MIN_WITHDRAWAL_AMOUNT()": { - "notice": "Minimum balance before a withdrawal can be triggered." - }, - "RECIPIENT()": { - "notice": "Wallet that will receive the fees on L1." - }, - "totalProcessed()": { - "notice": "Total amount of wei processed by the contract." - }, - "version()": { - "notice": "Returns the full semver contract version." - }, - "withdraw()": { - "notice": "Triggers a withdrawal of funds to the L1 fee wallet." - } - }, - "events": { - "Withdrawal(uint256,address,address)": { - "notice": "Emits each time that a withdrawal occurs." - } - }, - "notice": "The L1FeeVault accumulates the L1 portion of the transaction fees." - }, - "storageLayout": { - "storage": [ - { - "astId": 46671, - "contract": "contracts/L2/L1FeeVault.sol:L1FeeVault", - "label": "totalProcessed", - "offset": 0, - "slot": "0", - "type": "t_uint256" - } - ], - "types": { - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/L2CrossDomainMessenger.json b/packages/contracts-bedrock/deployments/optimism-goerli/L2CrossDomainMessenger.json deleted file mode 100644 index 5afa1423ff73..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/L2CrossDomainMessenger.json +++ /dev/null @@ -1,777 +0,0 @@ -{ - "address": "0x3305a8110469eB7168870126b26BDAD56067C679", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_l1CrossDomainMessenger", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "msgHash", - "type": "bytes32" - } - ], - "name": "FailedRelayedMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "msgHash", - "type": "bytes32" - } - ], - "name": "RelayedMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "message", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "messageNonce", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - } - ], - "name": "SentMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "SentMessageExtension1", - "type": "event" - }, - { - "inputs": [], - "name": "MESSAGE_VERSION", - "outputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_CALLDATA_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_MESSENGER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_CALL_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_CONSTANT_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_GAS_CHECK_BUFFER", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_RESERVED_GAS", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - } - ], - "name": "baseGas", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "failedMessages", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l1CrossDomainMessenger", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "messageNonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "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": "_minGasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - } - ], - "name": "relayMessage", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - } - ], - "name": "sendMessage", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "successfulMessages", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "xDomainMessageSender", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x106e27edc8fcd438852dfc61d5f0a2ab57a692c34867b840ce82b484c5e5b8c1", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0x3305a8110469eB7168870126b26BDAD56067C679", - "transactionIndex": 1, - "gasUsed": "1797186", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000400000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000001000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc137484cb3fcca86142309e8f0531010de5150858f2f2cec6cb0d656b136f75e", - "transactionHash": "0x106e27edc8fcd438852dfc61d5f0a2ab57a692c34867b840ce82b484c5e5b8c1", - "logs": [ - { - "transactionIndex": 1, - "blockNumber": 8579664, - "transactionHash": "0x106e27edc8fcd438852dfc61d5f0a2ab57a692c34867b840ce82b484c5e5b8c1", - "address": "0x3305a8110469eB7168870126b26BDAD56067C679", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 0, - "blockHash": "0xc137484cb3fcca86142309e8f0531010de5150858f2f2cec6cb0d656b136f75e" - } - ], - "blockNumber": 8579664, - "cumulativeGasUsed": "1861199", - "status": 1, - "byzantium": true - }, - "args": [ - "0x5086d1eEF304eb5284A0f6720f79403b4e9bE294" - ], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1CrossDomainMessenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"FailedRelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"RelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"SentMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SentMessageExtension1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CALL_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RELAY_RESERVED_GAS\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1CrossDomainMessenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"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\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"relayMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"name\":\"sendMessage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"custom:proxied\":\"@custom:predeploy 0x4200000000000000000000000000000000000007\",\"kind\":\"dev\",\"methods\":{\"baseGas(bytes,uint32)\":{\"params\":{\"_message\":\"Message to compute the amount of required gas for.\",\"_minGasLimit\":\"Minimum desired gas limit when message goes to target.\"},\"returns\":{\"_0\":\"Amount of gas required to guarantee message receipt.\"}},\"constructor\":{\"custom:semver\":\"1.4.0\",\"params\":{\"_l1CrossDomainMessenger\":\"Address of the L1CrossDomainMessenger contract.\"}},\"l1CrossDomainMessenger()\":{\"custom:legacy\":\"@notice Legacy getter for the remote messenger. Use otherMessenger going forward.\",\"returns\":{\"_0\":\"Address of the L1CrossDomainMessenger contract.\"}},\"messageNonce()\":{\"returns\":{\"_0\":\"Nonce of the next message to be sent, with added message version.\"}},\"relayMessage(uint256,address,address,uint256,uint256,bytes)\":{\"params\":{\"_message\":\"Message to send to the target.\",\"_minGasLimit\":\"Minimum amount of gas that the message can be executed with.\",\"_nonce\":\"Nonce of the message being relayed.\",\"_sender\":\"Address of the user who sent the message.\",\"_target\":\"Address that the message is targeted at.\",\"_value\":\"ETH value to send with the message.\"}},\"sendMessage(address,bytes,uint32)\":{\"params\":{\"_message\":\"Message to trigger the target address with.\",\"_minGasLimit\":\"Minimum gas limit that the message can be executed with.\",\"_target\":\"Target contract or wallet address.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}},\"xDomainMessageSender()\":{\"returns\":{\"_0\":\"Address of the sender of the currently executing message on the other chain.\"}}},\"title\":\"L2CrossDomainMessenger\",\"version\":1},\"userdoc\":{\"events\":{\"FailedRelayedMessage(bytes32)\":{\"notice\":\"Emitted whenever a message fails to be relayed on this chain.\"},\"RelayedMessage(bytes32)\":{\"notice\":\"Emitted whenever a message is successfully relayed on this chain.\"},\"SentMessage(address,address,bytes,uint256,uint256)\":{\"notice\":\"Emitted whenever a message is sent to the other chain.\"},\"SentMessageExtension1(address,uint256)\":{\"notice\":\"Additional event data to emit, required as of Bedrock. Cannot be merged with the SentMessage event without breaking the ABI of this contract, this is good enough.\"}},\"kind\":\"user\",\"methods\":{\"MESSAGE_VERSION()\":{\"notice\":\"Current message version identifier.\"},\"MIN_GAS_CALLDATA_OVERHEAD()\":{\"notice\":\"Extra gas added to base gas for each byte of calldata in a message.\"},\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()\":{\"notice\":\"Denominator for dynamic overhead added to the base gas for a message.\"},\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR()\":{\"notice\":\"Numerator for dynamic overhead added to the base gas for a message.\"},\"OTHER_MESSENGER()\":{\"notice\":\"Address of the paired CrossDomainMessenger contract on the other chain.\"},\"RELAY_CALL_OVERHEAD()\":{\"notice\":\"Gas reserved for performing the external call in `relayMessage`.\"},\"RELAY_CONSTANT_OVERHEAD()\":{\"notice\":\"Constant overhead added to the base gas for a message.\"},\"RELAY_GAS_CHECK_BUFFER()\":{\"notice\":\"Gas reserved for the execution between the `hasMinGas` check and the external call in `relayMessage`.\"},\"RELAY_RESERVED_GAS()\":{\"notice\":\"Gas reserved for finalizing the execution of `relayMessage` after the safe call.\"},\"baseGas(bytes,uint32)\":{\"notice\":\"Computes the amount of gas required to guarantee that a given message will be received on the other chain without running out of gas. Guaranteeing that a message will not run out of gas is important because this ensures that a message can always be replayed on the other chain if it fails to execute completely.\"},\"failedMessages(bytes32)\":{\"notice\":\"Mapping of message hashes to a boolean if and only if the message has failed to be executed at least once. A message will not be present in this mapping if it successfully executed on the first attempt.\"},\"initialize()\":{\"notice\":\"Initializer.\"},\"messageNonce()\":{\"notice\":\"Retrieves the next message nonce. Message version will be added to the upper two bytes of the message nonce. Message version allows us to treat messages as having different structures.\"},\"relayMessage(uint256,address,address,uint256,uint256,bytes)\":{\"notice\":\"Relays a message that was sent by the other CrossDomainMessenger contract. Can only be executed via cross-chain call from the other messenger OR if the message was already received once and is currently being replayed.\"},\"sendMessage(address,bytes,uint32)\":{\"notice\":\"Sends a message to some target address on the other chain. Note that if the call always reverts, then the message will be unrelayable, and any ETH sent will be permanently locked. The same will occur if the target on the other chain is considered unsafe (see the _isUnsafeTarget() function).\"},\"successfulMessages(bytes32)\":{\"notice\":\"Mapping of message hashes to boolean receipt values. Note that a message will only be present in this mapping if it has successfully been relayed on this chain, and can therefore not be relayed again.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"},\"xDomainMessageSender()\":{\"notice\":\"Retrieves the address of the contract or wallet that initiated the currently executing message on the other chain. Will throw an error if there is no message currently being executed. Allows the recipient of a call to see who triggered it.\"}},\"notice\":\"The L2CrossDomainMessenger is a high-level interface for message passing between L1 and L2 on the L2 side. Users are generally encouraged to use this contract instead of lower level message passing contracts.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/L2CrossDomainMessenger.sol\":\"L2CrossDomainMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L1/ResourceMetering.sol\":{\"keccak256\":\"0xbd7b9532a70d8c842bfce0ea971be50d02fbbf0227c9ad55c71ac68d438010f4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4969f478dd54e89392cda2ea0c5edcf1be55a5dee43a0e410527b6e3bcb85c88\",\"dweb:/ipfs/QmU2crAojw8DRDsz7PAPrereazjFsKh9wtfTpTDVh6NLfW\"]},\"contracts/L2/L2CrossDomainMessenger.sol\":{\"keccak256\":\"0x51c28c22a49e926293de7f06989b656bc2f534ee37a727ee1f67efd557c00826\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c3728945b1f4915e78bb5ecffc58f5e15f5c38f8bccdc646b1773b79346aa2b2\",\"dweb:/ipfs/QmYUgjmX61tJ8oUrZjN2sTYr5YYfGTUQY245v17tyBfU9D\"]},\"contracts/L2/L2ToL1MessagePasser.sol\":{\"keccak256\":\"0xa385bda91d75c44f6d8b0bc5a61e1904ed455d98c07b308910ac1265e6536df1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://dcbaab318b084e163992187aa87f9250782982c10d69be9e11959090e02cc912\",\"dweb:/ipfs/QmY81HgBPp4vcMigSbWQ8mDizXCQFvjN52BF7nGPc6f9Fm\"]},\"contracts/libraries/Arithmetic.sol\":{\"keccak256\":\"0xc8858039f87e48e6f18c1af8bc0b03e57cfef564acddfd06e4d91e3db7ac5ed6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2fc79af1e844aa6dc1c68067bfe1d359df8d4e9a3e8881afb3bcfcbf68071714\",\"dweb:/ipfs/QmcNC4k8zmvwj4kZizSenTiWbx2DJQPbwqXXLF4iMbkRVD\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Constants.sol\":{\"keccak256\":\"0x8c7be28a175eb732995a7f704560163c30261f9f70d377f865c5060882509f5d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f72aba26553b10ca88708e05461691b36b0d2ec7a87f718022fe119ca9c70852\",\"dweb:/ipfs/QmQtDEB1F3D8RsgG63KSJ9t7ZyFLaXc2Av81vKD9y2TMn7\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/Predeploys.sol\":{\"keccak256\":\"0xfc30fb239b5f00284f4b8f578a62f0882597e939335c91ea9bc4aab3070ddc43\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fa132267b3a9d98568b4e02cbb68fe2d2c0ca630826242c1b2293a8fa35bd302\",\"dweb:/ipfs/QmdYvcGbaykP6wyBu5T2obXrWK56xGnfWqbYeeWpTChq3w\"]},\"contracts/libraries/SafeCall.sol\":{\"keccak256\":\"0x6e815b62528d452a4f63040d75ff7a08db8ba8096050a53355fc49abaebdf245\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e27e542a11165c82cbb6961f4d8c2a58527fba1ab915afeeded50e96ce929777\",\"dweb:/ipfs/QmRPXdmUAbL1WHZBvENKWkFuHb9bQyrbiJWwDvzEQBLVi8\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x4fe8ec920798661a828430bd30dc2715eeb40534ec01c0a7bf41cb4ab422e134\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://74c8471869900bd459358cd990bda1c8d234c06b788804c7049cf465ae1e299f\",\"dweb:/ipfs/QmakcfP6NmbVUQsKqH7rEyJsbiqckigLahw9g74oencEJ7\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x3c99b1e768cc4c1e064ccc137b1b4d5961bf4edf071be84cc216c5b20f1c00da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e36b2a6325c2f804d769271575669b62ab2da2df3c81921ac7487399fe02af07\",\"dweb:/ipfs/QmTCmcEKwvD8Xvjyev268Bkz27FC7TJpUbw1nADcsThnUr\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"contracts/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"]},\"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]}},\"version\":1}", - "bytecode": "0x6101006040523480156200001257600080fd5b506040516200219138038062002191833981016040819052620000359162000243565b6001600160a01b038116608052600160a052600460c052600060e0526200005b62000062565b5062000275565b600054600160a81b900460ff16158080156200008b57506000546001600160a01b90910460ff16105b80620000c25750620000a830620001af60201b620013411760201c565b158015620000c25750600054600160a01b900460ff166001145b6200012b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a01b1916600160a01b179055801562000159576000805460ff60a81b1916600160a81b1790555b62000163620001be565b8015620001ac576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6001600160a01b03163b151590565b600054600160a81b900460ff166200022d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000122565b60cc80546001600160a01b03191661dead179055565b6000602082840312156200025657600080fd5b81516001600160a01b03811681146200026e57600080fd5b9392505050565b60805160a05160c05160e051611ecd620002c460003960006106c30152600061069a015260006106710152600081816102a90152818161031a0152818161040b0152610c980152611ecd6000f3fe6080604052600436106101445760003560e01c80638129fc1c116100c0578063a711986911610074578063b28ade2511610059578063b28ade251461036e578063d764ad0b1461038e578063ecc70428146103a157600080fd5b8063a71198691461030b578063b1b1b2091461033e57600080fd5b80638cbeeef2116100a55780638cbeeef2146101e35780639fce812c14610297578063a4e7f8bd146102cb57600080fd5b80638129fc1c1461026b57806383a740741461028057600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146101f95780635644cfdf1461021b5780636e296e451461023157600080fd5b80633f827a5a146101bb5780634c1d6a69146101e357600080fd5b8063028f85f7146101495780630c5684981461017c5780632828d7e8146101915780633dbb202b146101a6575b600080fd5b34801561015557600080fd5b5061015e601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061015e603f81565b34801561019d57600080fd5b5061015e604081565b6101b96101b4366004611886565b610406565b005b3480156101c757600080fd5b506101d0600181565b60405161ffff9091168152602001610173565b3480156101ef57600080fd5b5061015e619c4081565b34801561020557600080fd5b5061020e61066a565b6040516101739190611965565b34801561022757600080fd5b5061015e61138881565b34801561023d57600080fd5b5061024661070d565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b34801561027757600080fd5b506101b96107f9565b34801561028c57600080fd5b5061015e62030d4081565b3480156102a357600080fd5b506102467f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d757600080fd5b506102fb6102e636600461197f565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610173565b34801561031757600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610246565b34801561034a57600080fd5b506102fb61035936600461197f565b60cb6020526000908152604090205460ff1681565b34801561037a57600080fd5b5061015e610389366004611998565b6109f6565b6101b961039c3660046119ec565b610a64565b3480156103ad57600080fd5b506103f860cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610173565b61053f7f00000000000000000000000000000000000000000000000000000000000000006104358585856109f6565b347fd764ad0b000000000000000000000000000000000000000000000000000000006104a160cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104bd9796959493929190611ab7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261135d565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856105c460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516105d6959493929190611b16565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60606106957f00000000000000000000000000000000000000000000000000000000000000006113eb565b6106be7f00000000000000000000000000000000000000000000000000000000000000006113eb565b6106e77f00000000000000000000000000000000000000000000000000000000000000006113eb565b6040516020016106f993929190611b64565b604051602081830303815290604052905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000547501000000000000000000000000000000000000000000900460ff1615808015610844575060005460017401000000000000000000000000000000000000000090910460ff16105b806108765750303b158015610876575060005474010000000000000000000000000000000000000000900460ff166001145b610902576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107d3565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055801561098857600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b610990611520565b80156109f357600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000611388619c4080603f610a12604063ffffffff8816611c09565b610a1c9190611c68565b610a27601088611c09565b610a349062030d40611c8f565b610a3e9190611c8f565b610a489190611c8f565b610a529190611c8f565b610a5c9190611c8f565b949350505050565b60f087901c60028110610b1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107d3565b8061ffff16600003610c14576000610b70878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506115f9915050565b600081815260cb602052604090205490915060ff1615610c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107d3565b505b6000610c5a898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061161892505050565b905073ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330181167f000000000000000000000000000000000000000000000000000000000000000090911603610cf257853414610cce57610cce611cbb565b600081815260ce602052604090205460ff1615610ced57610ced611cbb565b610e44565b3415610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107d3565b600081815260ce602052604090205460ff16610e44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107d3565b610e4d8761163b565b15610f00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107d3565b600081815260cb602052604090205460ff1615610f9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107d3565b610fc085610fb1611388619c40611c8f565b67ffffffffffffffff16611690565b1580610fe6575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b156110ff57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016110f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d3565b5050611338565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061119088619c405a6111539190611cea565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116ae92505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561122757600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a2611334565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611334576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d3565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fc2b3e5ac0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000169063c2b3e5ac9084906113b390889088908790600401611d01565b6000604051808303818588803b1580156113cc57600080fd5b505af11580156113e0573d6000803e3d6000fd5b505050505050505050565b60608160000361142e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611458578061144281611d49565b91506114519050600a83611d81565b9150611432565b60008167ffffffffffffffff81111561147357611473611d95565b6040519080825280601f01601f19166020018201604052801561149d576020820181803683370190505b5090505b8415610a5c576114b2600183611cea565b91506114bf600a86611dc4565b6114ca906030611dd8565b60f81b8183815181106114df576114df611df0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611519600a86611d81565b94506114a1565b6000547501000000000000000000000000000000000000000000900460ff166115cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107d3565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611607858585856116c8565b805190602001209050949350505050565b6000611628878787878787611761565b8051906020012090509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff821630148061168a575073ffffffffffffffffffffffffffffffffffffffff8216734200000000000000000000000000000000000016145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116e19493929190611e1f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161177e96959493929190611e69565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461182457600080fd5b919050565b60008083601f84011261183b57600080fd5b50813567ffffffffffffffff81111561185357600080fd5b60208301915083602082850101111561186b57600080fd5b9250929050565b803563ffffffff8116811461182457600080fd5b6000806000806060858703121561189c57600080fd5b6118a585611800565b9350602085013567ffffffffffffffff8111156118c157600080fd5b6118cd87828801611829565b90945092506118e0905060408601611872565b905092959194509250565b60005b838110156119065781810151838201526020016118ee565b83811115611915576000848401525b50505050565b600081518084526119338160208601602086016118eb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611978602083018461191b565b9392505050565b60006020828403121561199157600080fd5b5035919050565b6000806000604084860312156119ad57600080fd5b833567ffffffffffffffff8111156119c457600080fd5b6119d086828701611829565b90945092506119e3905060208501611872565b90509250925092565b600080600080600080600060c0888a031215611a0757600080fd5b87359650611a1760208901611800565b9550611a2560408901611800565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611a4f57600080fd5b611a5b8a828b01611829565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611b0960c083018486611a6e565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611b46608083018688611a6e565b905083604083015263ffffffff831660608301529695505050505050565b60008451611b768184602089016118eb565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611bb2816001850160208a016118eb565b60019201918201528351611bcd8160028401602088016118eb565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611c3057611c30611bda565b02949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611c8357611c83611c39565b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611cb257611cb2611bda565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611cfc57611cfc611bda565b500390565b73ffffffffffffffffffffffffffffffffffffffff8416815267ffffffffffffffff83166020820152606060408201526000611d40606083018461191b565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d7a57611d7a611bda565b5060010190565b600082611d9057611d90611c39565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082611dd357611dd3611c39565b500690565b60008219821115611deb57611deb611bda565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611e58608083018561191b565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611eb460c083018461191b565b9897505050505050505056fea164736f6c634300080f000a", - "deployedBytecode": "0x6080604052600436106101445760003560e01c80638129fc1c116100c0578063a711986911610074578063b28ade2511610059578063b28ade251461036e578063d764ad0b1461038e578063ecc70428146103a157600080fd5b8063a71198691461030b578063b1b1b2091461033e57600080fd5b80638cbeeef2116100a55780638cbeeef2146101e35780639fce812c14610297578063a4e7f8bd146102cb57600080fd5b80638129fc1c1461026b57806383a740741461028057600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146101f95780635644cfdf1461021b5780636e296e451461023157600080fd5b80633f827a5a146101bb5780634c1d6a69146101e357600080fd5b8063028f85f7146101495780630c5684981461017c5780632828d7e8146101915780633dbb202b146101a6575b600080fd5b34801561015557600080fd5b5061015e601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b34801561018857600080fd5b5061015e603f81565b34801561019d57600080fd5b5061015e604081565b6101b96101b4366004611886565b610406565b005b3480156101c757600080fd5b506101d0600181565b60405161ffff9091168152602001610173565b3480156101ef57600080fd5b5061015e619c4081565b34801561020557600080fd5b5061020e61066a565b6040516101739190611965565b34801561022757600080fd5b5061015e61138881565b34801561023d57600080fd5b5061024661070d565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610173565b34801561027757600080fd5b506101b96107f9565b34801561028c57600080fd5b5061015e62030d4081565b3480156102a357600080fd5b506102467f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d757600080fd5b506102fb6102e636600461197f565b60ce6020526000908152604090205460ff1681565b6040519015158152602001610173565b34801561031757600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610246565b34801561034a57600080fd5b506102fb61035936600461197f565b60cb6020526000908152604090205460ff1681565b34801561037a57600080fd5b5061015e610389366004611998565b6109f6565b6101b961039c3660046119ec565b610a64565b3480156103ad57600080fd5b506103f860cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b604051908152602001610173565b61053f7f00000000000000000000000000000000000000000000000000000000000000006104358585856109f6565b347fd764ad0b000000000000000000000000000000000000000000000000000000006104a160cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016104bd9796959493929190611ab7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261135d565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856105c460cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516105d6959493929190611b16565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60606106957f00000000000000000000000000000000000000000000000000000000000000006113eb565b6106be7f00000000000000000000000000000000000000000000000000000000000000006113eb565b6106e77f00000000000000000000000000000000000000000000000000000000000000006113eb565b6040516020016106f993929190611b64565b604051602081830303815290604052905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000547501000000000000000000000000000000000000000000900460ff1615808015610844575060005460017401000000000000000000000000000000000000000090910460ff16105b806108765750303b158015610876575060005474010000000000000000000000000000000000000000900460ff166001145b610902576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107d3565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055801561098857600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b610990611520565b80156109f357600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000611388619c4080603f610a12604063ffffffff8816611c09565b610a1c9190611c68565b610a27601088611c09565b610a349062030d40611c8f565b610a3e9190611c8f565b610a489190611c8f565b610a529190611c8f565b610a5c9190611c8f565b949350505050565b60f087901c60028110610b1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107d3565b8061ffff16600003610c14576000610b70878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506115f9915050565b600081815260cb602052604090205490915060ff1615610c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107d3565b505b6000610c5a898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061161892505050565b905073ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330181167f000000000000000000000000000000000000000000000000000000000000000090911603610cf257853414610cce57610cce611cbb565b600081815260ce602052604090205460ff1615610ced57610ced611cbb565b610e44565b3415610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107d3565b600081815260ce602052604090205460ff16610e44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107d3565b610e4d8761163b565b15610f00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107d3565b600081815260cb602052604090205460ff1615610f9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107d3565b610fc085610fb1611388619c40611c8f565b67ffffffffffffffff16611690565b1580610fe6575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b156110ff57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016110f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d3565b5050611338565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061119088619c405a6111539190611cea565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116ae92505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801561122757600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a2611334565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611334576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107d3565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6040517fc2b3e5ac0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000169063c2b3e5ac9084906113b390889088908790600401611d01565b6000604051808303818588803b1580156113cc57600080fd5b505af11580156113e0573d6000803e3d6000fd5b505050505050505050565b60608160000361142e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611458578061144281611d49565b91506114519050600a83611d81565b9150611432565b60008167ffffffffffffffff81111561147357611473611d95565b6040519080825280601f01601f19166020018201604052801561149d576020820181803683370190505b5090505b8415610a5c576114b2600183611cea565b91506114bf600a86611dc4565b6114ca906030611dd8565b60f81b8183815181106114df576114df611df0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611519600a86611d81565b94506114a1565b6000547501000000000000000000000000000000000000000000900460ff166115cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107d3565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611607858585856116c8565b805190602001209050949350505050565b6000611628878787878787611761565b8051906020012090509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff821630148061168a575073ffffffffffffffffffffffffffffffffffffffff8216734200000000000000000000000000000000000016145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116e19493929190611e1f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161177e96959493929190611e69565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461182457600080fd5b919050565b60008083601f84011261183b57600080fd5b50813567ffffffffffffffff81111561185357600080fd5b60208301915083602082850101111561186b57600080fd5b9250929050565b803563ffffffff8116811461182457600080fd5b6000806000806060858703121561189c57600080fd5b6118a585611800565b9350602085013567ffffffffffffffff8111156118c157600080fd5b6118cd87828801611829565b90945092506118e0905060408601611872565b905092959194509250565b60005b838110156119065781810151838201526020016118ee565b83811115611915576000848401525b50505050565b600081518084526119338160208601602086016118eb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611978602083018461191b565b9392505050565b60006020828403121561199157600080fd5b5035919050565b6000806000604084860312156119ad57600080fd5b833567ffffffffffffffff8111156119c457600080fd5b6119d086828701611829565b90945092506119e3905060208501611872565b90509250925092565b600080600080600080600060c0888a031215611a0757600080fd5b87359650611a1760208901611800565b9550611a2560408901611800565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611a4f57600080fd5b611a5b8a828b01611829565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611b0960c083018486611a6e565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611b46608083018688611a6e565b905083604083015263ffffffff831660608301529695505050505050565b60008451611b768184602089016118eb565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611bb2816001850160208a016118eb565b60019201918201528351611bcd8160028401602088016118eb565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611c3057611c30611bda565b02949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611c8357611c83611c39565b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611cb257611cb2611bda565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611cfc57611cfc611bda565b500390565b73ffffffffffffffffffffffffffffffffffffffff8416815267ffffffffffffffff83166020820152606060408201526000611d40606083018461191b565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d7a57611d7a611bda565b5060010190565b600082611d9057611d90611c39565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082611dd357611dd3611c39565b500690565b60008219821115611deb57611deb611bda565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611e58608083018561191b565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611eb460c083018461191b565b9897505050505050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "baseGas(bytes,uint32)": { - "params": { - "_message": "Message to compute the amount of required gas for.", - "_minGasLimit": "Minimum desired gas limit when message goes to target." - }, - "returns": { - "_0": "Amount of gas required to guarantee message receipt." - } - }, - "constructor": { - "params": { - "_l1CrossDomainMessenger": "Address of the L1CrossDomainMessenger contract." - } - }, - "l1CrossDomainMessenger()": { - "returns": { - "_0": "Address of the L1CrossDomainMessenger contract." - } - }, - "messageNonce()": { - "returns": { - "_0": "Nonce of the next message to be sent, with added message version." - } - }, - "relayMessage(uint256,address,address,uint256,uint256,bytes)": { - "params": { - "_message": "Message to send to the target.", - "_minGasLimit": "Minimum amount of gas that the message can be executed with.", - "_nonce": "Nonce of the message being relayed.", - "_sender": "Address of the user who sent the message.", - "_target": "Address that the message is targeted at.", - "_value": "ETH value to send with the message." - } - }, - "sendMessage(address,bytes,uint32)": { - "params": { - "_message": "Message to trigger the target address with.", - "_minGasLimit": "Minimum gas limit that the message can be executed with.", - "_target": "Target contract or wallet address." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - }, - "xDomainMessageSender()": { - "returns": { - "_0": "Address of the sender of the currently executing message on the other chain." - } - } - }, - "title": "L2CrossDomainMessenger" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSAGE_VERSION()": { - "notice": "Current message version identifier." - }, - "MIN_GAS_CALLDATA_OVERHEAD()": { - "notice": "Extra gas added to base gas for each byte of calldata in a message." - }, - "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()": { - "notice": "Denominator for dynamic overhead added to the base gas for a message." - }, - "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR()": { - "notice": "Numerator for dynamic overhead added to the base gas for a message." - }, - "OTHER_MESSENGER()": { - "notice": "Address of the paired CrossDomainMessenger contract on the other chain." - }, - "RELAY_CALL_OVERHEAD()": { - "notice": "Gas reserved for performing the external call in `relayMessage`." - }, - "RELAY_CONSTANT_OVERHEAD()": { - "notice": "Constant overhead added to the base gas for a message." - }, - "RELAY_GAS_CHECK_BUFFER()": { - "notice": "Gas reserved for the execution between the `hasMinGas` check and the external call in `relayMessage`." - }, - "RELAY_RESERVED_GAS()": { - "notice": "Gas reserved for finalizing the execution of `relayMessage` after the safe call." - }, - "baseGas(bytes,uint32)": { - "notice": "Computes the amount of gas required to guarantee that a given message will be received on the other chain without running out of gas. Guaranteeing that a message will not run out of gas is important because this ensures that a message can always be replayed on the other chain if it fails to execute completely." - }, - "failedMessages(bytes32)": { - "notice": "Mapping of message hashes to a boolean if and only if the message has failed to be executed at least once. A message will not be present in this mapping if it successfully executed on the first attempt." - }, - "initialize()": { - "notice": "Initializer." - }, - "messageNonce()": { - "notice": "Retrieves the next message nonce. Message version will be added to the upper two bytes of the message nonce. Message version allows us to treat messages as having different structures." - }, - "relayMessage(uint256,address,address,uint256,uint256,bytes)": { - "notice": "Relays a message that was sent by the other CrossDomainMessenger contract. Can only be executed via cross-chain call from the other messenger OR if the message was already received once and is currently being replayed." - }, - "sendMessage(address,bytes,uint32)": { - "notice": "Sends a message to some target address on the other chain. Note that if the call always reverts, then the message will be unrelayable, and any ETH sent will be permanently locked. The same will occur if the target on the other chain is considered unsafe (see the _isUnsafeTarget() function)." - }, - "successfulMessages(bytes32)": { - "notice": "Mapping of message hashes to boolean receipt values. Note that a message will only be present in this mapping if it has successfully been relayed on this chain, and can therefore not be relayed again." - }, - "version()": { - "notice": "Returns the full semver contract version." - }, - "xDomainMessageSender()": { - "notice": "Retrieves the address of the contract or wallet that initiated the currently executing message on the other chain. Will throw an error if there is no message currently being executed. Allows the recipient of a call to see who triggered it." - } - }, - "events": { - "FailedRelayedMessage(bytes32)": { - "notice": "Emitted whenever a message fails to be relayed on this chain." - }, - "RelayedMessage(bytes32)": { - "notice": "Emitted whenever a message is successfully relayed on this chain." - }, - "SentMessage(address,address,bytes,uint256,uint256)": { - "notice": "Emitted whenever a message is sent to the other chain." - }, - "SentMessageExtension1(address,uint256)": { - "notice": "Additional event data to emit, required as of Bedrock. Cannot be merged with the SentMessage event without breaking the ABI of this contract, this is good enough." - } - }, - "notice": "The L2CrossDomainMessenger is a high-level interface for message passing between L1 and L2 on the L2 side. Users are generally encouraged to use this contract instead of lower level message passing contracts." - }, - "storageLayout": { - "storage": [ - { - "astId": 45898, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "spacer_0_0_20", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 49236, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "_initialized", - "offset": 20, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 49239, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "_initializing", - "offset": 21, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 45905, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "spacer_1_0_1600", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 45908, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "spacer_51_0_20", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 45913, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "spacer_52_0_1568", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 45916, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "spacer_101_0_1", - "offset": 0, - "slot": "101", - "type": "t_bool" - }, - { - "astId": 45921, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "spacer_102_0_1568", - "offset": 0, - "slot": "102", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 45924, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "spacer_151_0_32", - "offset": 0, - "slot": "151", - "type": "t_uint256" - }, - { - "astId": 45929, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "spacer_152_0_1568", - "offset": 0, - "slot": "152", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 45934, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "spacer_201_0_32", - "offset": 0, - "slot": "201", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 45939, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "spacer_202_0_32", - "offset": 0, - "slot": "202", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 45987, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "successfulMessages", - "offset": 0, - "slot": "203", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 45990, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "xDomainMsgSender", - "offset": 0, - "slot": "204", - "type": "t_address" - }, - { - "astId": 45993, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "msgNonce", - "offset": 0, - "slot": "205", - "type": "t_uint240" - }, - { - "astId": 45998, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "failedMessages", - "offset": 0, - "slot": "206", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 46003, - "contract": "contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger", - "label": "__gap", - "offset": 0, - "slot": "207", - "type": "t_array(t_uint256)42_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)42_storage": { - "encoding": "inplace", - "label": "uint256[42]", - "numberOfBytes": "1344", - "base": "t_uint256" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes32,t_bool)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_uint240": { - "encoding": "inplace", - "label": "uint240", - "numberOfBytes": "30" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/L2ERC721Bridge.json b/packages/contracts-bedrock/deployments/optimism-goerli/L2ERC721Bridge.json deleted file mode 100644 index 3d734d3beb81..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/L2ERC721Bridge.json +++ /dev/null @@ -1,421 +0,0 @@ -{ - "address": "0x5Eb0EE8d7f29856F50b5c97F9CF1225491404bF1", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_messenger", - "type": "address" - }, - { - "internalType": "address", - "name": "_otherBridge", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC721BridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC721BridgeInitiated", - "type": "event" - }, - { - "inputs": [], - "name": "MESSENGER", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_BRIDGE", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC721To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "messenger", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "otherBridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0xb1558531b8c3a4d2d271b768d63583b8bb189dc945c0881fed0548142fc4927f", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0x5Eb0EE8d7f29856F50b5c97F9CF1225491404bF1", - "transactionIndex": 3, - "gasUsed": "1318890", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa1e924a48dcf7d9bb30b05a140979191dad27527c6f0a7bbd34e4109132a13e1", - "transactionHash": "0xb1558531b8c3a4d2d271b768d63583b8bb189dc945c0881fed0548142fc4927f", - "logs": [], - "blockNumber": 8579680, - "cumulativeGasUsed": "1875901", - "status": 1, - "byzantium": true - }, - "args": [ - "0x4200000000000000000000000000000000000007", - "0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9" - ], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_messenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_otherBridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC721BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC721BridgeInitiated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC721To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bridgeERC721(address,address,uint256,uint32,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.\",\"_localToken\":\"Address of the ERC721 on this domain.\",\"_minGasLimit\":\"Minimum gas limit for the bridge message on the other domain.\",\"_remoteToken\":\"Address of the ERC721 on the remote domain.\",\"_tokenId\":\"Token ID to bridge.\"}},\"bridgeERC721To(address,address,address,uint256,uint32,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.\",\"_localToken\":\"Address of the ERC721 on this domain.\",\"_minGasLimit\":\"Minimum gas limit for the bridge message on the other domain.\",\"_remoteToken\":\"Address of the ERC721 on the remote domain.\",\"_to\":\"Address to receive the token on the other domain.\",\"_tokenId\":\"Token ID to bridge.\"}},\"constructor\":{\"custom:semver\":\"1.1.0\",\"params\":{\"_messenger\":\"Address of the CrossDomainMessenger on this network.\",\"_otherBridge\":\"Address of the ERC721 bridge on the other network.\"}},\"finalizeBridgeERC721(address,address,address,address,uint256,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to L1. Data supplied here will not be used to execute any code on L1 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_from\":\"Address that triggered the bridge on the other domain.\",\"_localToken\":\"Address of the ERC721 token on this domain.\",\"_remoteToken\":\"Address of the ERC721 token on the other domain.\",\"_to\":\"Address to receive the token on this domain.\",\"_tokenId\":\"ID of the token being deposited.\"}},\"messenger()\":{\"custom:legacy\":\"@notice Legacy getter for messenger contract.\",\"returns\":{\"_0\":\"Messenger contract on this domain.\"}},\"otherBridge()\":{\"custom:legacy\":\"@notice Legacy getter for other bridge address.\",\"returns\":{\"_0\":\"Address of the bridge on the other network.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"L2ERC721Bridge\",\"version\":1},\"userdoc\":{\"events\":{\"ERC721BridgeFinalized(address,address,address,address,uint256,bytes)\":{\"notice\":\"Emitted when an ERC721 bridge from the other network is finalized.\"},\"ERC721BridgeInitiated(address,address,address,address,uint256,bytes)\":{\"notice\":\"Emitted when an ERC721 bridge to the other network is initiated.\"}},\"kind\":\"user\",\"methods\":{\"MESSENGER()\":{\"notice\":\"Messenger contract on this domain.\"},\"OTHER_BRIDGE()\":{\"notice\":\"Address of the bridge on the other network.\"},\"bridgeERC721(address,address,uint256,uint32,bytes)\":{\"notice\":\"Initiates a bridge of an NFT to the caller's account on the other chain. Note that this function can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` function after ensuring that the recipient address on the remote chain exists. Also note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\"},\"bridgeERC721To(address,address,address,uint256,uint32,bytes)\":{\"notice\":\"Initiates a bridge of an NFT to some recipient's account on the other chain. Note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\"},\"finalizeBridgeERC721(address,address,address,address,uint256,bytes)\":{\"notice\":\"Completes an ERC721 bridge from the other domain and sends the ERC721 token to the recipient on this domain.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge. This contract also acts as a burner for tokens being withdrawn. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/L2ERC721Bridge.sol\":\"L2ERC721Bridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L1/L1ERC721Bridge.sol\":{\"keccak256\":\"0xf66d53c1bc80c9a204ce8752f26a6fdaa247f6fd80438020b889e0f1c8079b75\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://eab9be6161db4e3e0e598cdaf5e8f9143b4f4bfdbc65e335c5d948b00dc4a1cb\",\"dweb:/ipfs/QmaaLcDguxg1XyCNmbtKMkuTi4ngK8qCUFb1NkurJZGAhZ\"]},\"contracts/L1/ResourceMetering.sol\":{\"keccak256\":\"0xbd7b9532a70d8c842bfce0ea971be50d02fbbf0227c9ad55c71ac68d438010f4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4969f478dd54e89392cda2ea0c5edcf1be55a5dee43a0e410527b6e3bcb85c88\",\"dweb:/ipfs/QmU2crAojw8DRDsz7PAPrereazjFsKh9wtfTpTDVh6NLfW\"]},\"contracts/L2/L2ERC721Bridge.sol\":{\"keccak256\":\"0x94d240acff616f7ec4281bb3c2d3cace1c398bfca754fb3ca7bc795c875b4f10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7613d2506fc31214e3e36c8cd9b0845c9bcaaf063be6fc611ce8efe3fce71584\",\"dweb:/ipfs/QmX8eBBgEWvUPXgpQsPQN3ZhZbwMawFQRuqyTF8Rcv1u1S\"]},\"contracts/libraries/Arithmetic.sol\":{\"keccak256\":\"0xc8858039f87e48e6f18c1af8bc0b03e57cfef564acddfd06e4d91e3db7ac5ed6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2fc79af1e844aa6dc1c68067bfe1d359df8d4e9a3e8881afb3bcfcbf68071714\",\"dweb:/ipfs/QmcNC4k8zmvwj4kZizSenTiWbx2DJQPbwqXXLF4iMbkRVD\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Constants.sol\":{\"keccak256\":\"0x8c7be28a175eb732995a7f704560163c30261f9f70d377f865c5060882509f5d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f72aba26553b10ca88708e05461691b36b0d2ec7a87f718022fe119ca9c70852\",\"dweb:/ipfs/QmQtDEB1F3D8RsgG63KSJ9t7ZyFLaXc2Av81vKD9y2TMn7\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/SafeCall.sol\":{\"keccak256\":\"0x6e815b62528d452a4f63040d75ff7a08db8ba8096050a53355fc49abaebdf245\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e27e542a11165c82cbb6961f4d8c2a58527fba1ab915afeeded50e96ce929777\",\"dweb:/ipfs/QmRPXdmUAbL1WHZBvENKWkFuHb9bQyrbiJWwDvzEQBLVi8\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x4fe8ec920798661a828430bd30dc2715eeb40534ec01c0a7bf41cb4ab422e134\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://74c8471869900bd459358cd990bda1c8d234c06b788804c7049cf465ae1e299f\",\"dweb:/ipfs/QmakcfP6NmbVUQsKqH7rEyJsbiqckigLahw9g74oencEJ7\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x3c99b1e768cc4c1e064ccc137b1b4d5961bf4edf071be84cc216c5b20f1c00da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e36b2a6325c2f804d769271575669b62ab2da2df3c81921ac7487399fe02af07\",\"dweb:/ipfs/QmTCmcEKwvD8Xvjyev268Bkz27FC7TJpUbw1nADcsThnUr\"]},\"contracts/universal/ERC721Bridge.sol\":{\"keccak256\":\"0xb47389fbec63e85b2d04fce538fe1b8e048278d631729458b70e32a31971c092\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7133f38e3d8d1911738057b1d4523989abd7cd029797b1d3b59cda29d42e9704\",\"dweb:/ipfs/QmUN31CLssESHrBwWA3WYP5L2xESo9Q4aq2Exua1e8UtUW\"]},\"contracts/universal/IOptimismMintableERC721.sol\":{\"keccak256\":\"0xf1a3dd4452df8882a65a31c5e2e8de7872b08cf078be7a5a7da51e6f75c53ad3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b09a2560cae35ca4789fe1ff5edb2bae9fa7dcda115a55f7ccdcc974a2e37526\",\"dweb:/ipfs/QmPQeTvrJ4SJpng5VGZNMf1u85NWxrdus4gGn8xYkHddKM\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://20a97f891d06f0fe91560ea1a142aaa26fdd22bed1b51606b7d48f670deeb50f\",\"dweb:/ipfs/QmTbCtZKChpaX5H2iRiTDMcSz29GSLCpTCDgJpcMR4wg8x\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://26fef835622b46a5ba08b3ef6b46a22e94b5f285d0f0fb66b703bd30217d2c34\",\"dweb:/ipfs/QmZ548qdwfL1qF7aXz3xh1GCdTiST81kGGuKRqVUfYmPZR\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]}},\"version\":1}", - "bytecode": "0x6101206040523480156200001257600080fd5b506040516200190c3803806200190c833981016040819052620000359162000162565b600180600084846001600160a01b038216620000ad5760405162461bcd60e51b815260206004820152602c60248201527f4552433732314272696467653a206d657373656e6765722063616e6e6f74206260448201526b65206164647265737328302960a01b60648201526084015b60405180910390fd5b6001600160a01b0381166200011d5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314272696467653a206f74686572206272696467652063616e6e6f60448201526e74206265206164647265737328302960881b6064820152608401620000a4565b6001600160a01b039182166080521660a05260c09290925260e05261010052506200019a9050565b80516001600160a01b03811681146200015d57600080fd5b919050565b600080604083850312156200017657600080fd5b620001818362000145565b9150620001916020840162000145565b90509250929050565b60805160a05160c05160e051610100516116fd6200020f60003960006102a2015260006102790152600061025001526000818161011b015281816101790152818161032e0152610dc101526000818160a40152818161014201528181610304015281816103650152610d9401526116fd6000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80637f46ddb21161005b5780637f46ddb214610116578063927ede2d1461013d578063aa55745214610164578063c89701a21461017757600080fd5b80633687011a1461008d5780633cb747bf146100a257806354fd4d50146100ee578063761f449314610103575b600080fd5b6100a061009b3660046111c8565b61019d565b005b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100f6610249565b6040516100e591906112c5565b6100a06101113660046112d8565b6102ec565b6100c47f000000000000000000000000000000000000000000000000000000000000000081565b6100c47f000000000000000000000000000000000000000000000000000000000000000081565b6100a0610172366004611370565b610853565b7f00000000000000000000000000000000000000000000000000000000000000006100c4565b333b15610231576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b610241868633338888888861090f565b505050505050565b60606102747f0000000000000000000000000000000000000000000000000000000000000000610ead565b61029d7f0000000000000000000000000000000000000000000000000000000000000000610ead565b6102c67f0000000000000000000000000000000000000000000000000000000000000000610ead565b6040516020016102d8939291906113e7565b604051602081830303815290604052905090565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561040a57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103f2919061145d565b73ffffffffffffffffffffffffffffffffffffffff16145b610496576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f7468657220627269646765006064820152608401610228565b3073ffffffffffffffffffffffffffffffffffffffff88160361053b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c66000000000000000000000000000000000000000000006064820152608401610228565b610565877f74259ebf00000000000000000000000000000000000000000000000000000000610fea565b6105f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e20696e746560448201527f7266616365206973206e6f7420636f6d706c69616e74000000000000000000006064820152608401610228565b8673ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561063c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610660919061145d565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610740576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324552433732314272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433732312060648201527f6c6f63616c20746f6b656e000000000000000000000000000000000000000000608482015260a401610228565b6040517fa144819400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301526024820185905288169063a144819490604401600060405180830381600087803b1580156107b057600080fd5b505af11580156107c4573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac8787878760405161084294939291906114c3565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff85166108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f742062652061646472657373283029000000000000000000000000000000006064820152608401610228565b610906878733888888888861090f565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff87166109b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f7420626520616464726573732830290000000000000000000000000000006064820152608401610228565b6040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff891690636352211e90602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a41919061145d565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324552433732314272696467653a205769746864726177616c206973206e6f60448201527f74206265696e6720696e69746961746564206279204e4654206f776e657200006064820152608401610228565b60008873ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6c919061145d565b90508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e20646f6560448201527f73206e6f74206d6174636820676976656e2076616c75650000000000000000006064820152608401610228565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018790528a1690639dc29fac90604401600060405180830381600087803b158015610c9957600080fd5b505af1158015610cad573d6000803e3d6000fd5b50505050600063761f449360e01b828b8a8a8a8989604051602401610cd89796959493929190611503565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f3dbb202b00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690633dbb202b90610ded907f00000000000000000000000000000000000000000000000000000000000000009085908a90600401611560565b600060405180830381600087803b158015610e0757600080fd5b505af1158015610e1b573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a58a8a8989604051610e9994939291906114c3565b60405180910390a450505050505050505050565b606081600003610ef057505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610f1a5780610f04816115d4565b9150610f139050600a8361163b565b9150610ef4565b60008167ffffffffffffffff811115610f3557610f3561164f565b6040519080825280601f01601f191660200182016040528015610f5f576020820181803683370190505b5090505b8415610fe257610f7460018361167e565b9150610f81600a86611695565b610f8c9060306116a9565b60f81b818381518110610fa157610fa16116c1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610fdb600a8661163b565b9450610f63565b949350505050565b6000610ff58361100d565b801561100657506110068383611072565b9392505050565b6000611039827f01ffc9a700000000000000000000000000000000000000000000000000000000611072565b801561106c575061106a827fffffffff00000000000000000000000000000000000000000000000000000000611072565b155b92915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561112a575060208210155b80156111365750600081115b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461116357600080fd5b50565b803563ffffffff8116811461117a57600080fd5b919050565b60008083601f84011261119157600080fd5b50813567ffffffffffffffff8111156111a957600080fd5b6020830191508360208285010111156111c157600080fd5b9250929050565b60008060008060008060a087890312156111e157600080fd5b86356111ec81611141565b955060208701356111fc81611141565b94506040870135935061121160608801611166565b9250608087013567ffffffffffffffff81111561122d57600080fd5b61123989828a0161117f565b979a9699509497509295939492505050565b60005b8381101561126657818101518382015260200161124e565b83811115611275576000848401525b50505050565b6000815180845261129381602086016020860161124b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611006602083018461127b565b600080600080600080600060c0888a0312156112f357600080fd5b87356112fe81611141565b9650602088013561130e81611141565b9550604088013561131e81611141565b9450606088013561132e81611141565b93506080880135925060a088013567ffffffffffffffff81111561135157600080fd5b61135d8a828b0161117f565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561138b57600080fd5b873561139681611141565b965060208801356113a681611141565b955060408801356113b681611141565b9450606088013593506113cb60808901611166565b925060a088013567ffffffffffffffff81111561135157600080fd5b600084516113f981846020890161124b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611435816001850160208a0161124b565b6001920191820152835161145081600284016020880161124b565b0160020195945050505050565b60006020828403121561146f57600080fd5b815161100681611141565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006114f960608301848661147a565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261155360c08301848661147a565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061158f606083018561127b565b905063ffffffff83166040830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611605576116056115a5565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261164a5761164a61160c565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015611690576116906115a5565b500390565b6000826116a4576116a461160c565b500690565b600082198211156116bc576116bc6115a5565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c80637f46ddb21161005b5780637f46ddb214610116578063927ede2d1461013d578063aa55745214610164578063c89701a21461017757600080fd5b80633687011a1461008d5780633cb747bf146100a257806354fd4d50146100ee578063761f449314610103575b600080fd5b6100a061009b3660046111c8565b61019d565b005b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100f6610249565b6040516100e591906112c5565b6100a06101113660046112d8565b6102ec565b6100c47f000000000000000000000000000000000000000000000000000000000000000081565b6100c47f000000000000000000000000000000000000000000000000000000000000000081565b6100a0610172366004611370565b610853565b7f00000000000000000000000000000000000000000000000000000000000000006100c4565b333b15610231576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b610241868633338888888861090f565b505050505050565b60606102747f0000000000000000000000000000000000000000000000000000000000000000610ead565b61029d7f0000000000000000000000000000000000000000000000000000000000000000610ead565b6102c67f0000000000000000000000000000000000000000000000000000000000000000610ead565b6040516020016102d8939291906113e7565b604051602081830303815290604052905090565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561040a57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103f2919061145d565b73ffffffffffffffffffffffffffffffffffffffff16145b610496576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f7468657220627269646765006064820152608401610228565b3073ffffffffffffffffffffffffffffffffffffffff88160361053b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c66000000000000000000000000000000000000000000006064820152608401610228565b610565877f74259ebf00000000000000000000000000000000000000000000000000000000610fea565b6105f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e20696e746560448201527f7266616365206973206e6f7420636f6d706c69616e74000000000000000000006064820152608401610228565b8673ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561063c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610660919061145d565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610740576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324552433732314272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433732312060648201527f6c6f63616c20746f6b656e000000000000000000000000000000000000000000608482015260a401610228565b6040517fa144819400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301526024820185905288169063a144819490604401600060405180830381600087803b1580156107b057600080fd5b505af11580156107c4573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac8787878760405161084294939291906114c3565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff85166108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f742062652061646472657373283029000000000000000000000000000000006064820152608401610228565b610906878733888888888861090f565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff87166109b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f7420626520616464726573732830290000000000000000000000000000006064820152608401610228565b6040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff891690636352211e90602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a41919061145d565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324552433732314272696467653a205769746864726177616c206973206e6f60448201527f74206265696e6720696e69746961746564206279204e4654206f776e657200006064820152608401610228565b60008873ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6c919061145d565b90508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e20646f6560448201527f73206e6f74206d6174636820676976656e2076616c75650000000000000000006064820152608401610228565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018790528a1690639dc29fac90604401600060405180830381600087803b158015610c9957600080fd5b505af1158015610cad573d6000803e3d6000fd5b50505050600063761f449360e01b828b8a8a8a8989604051602401610cd89796959493929190611503565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f3dbb202b00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690633dbb202b90610ded907f00000000000000000000000000000000000000000000000000000000000000009085908a90600401611560565b600060405180830381600087803b158015610e0757600080fd5b505af1158015610e1b573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a58a8a8989604051610e9994939291906114c3565b60405180910390a450505050505050505050565b606081600003610ef057505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610f1a5780610f04816115d4565b9150610f139050600a8361163b565b9150610ef4565b60008167ffffffffffffffff811115610f3557610f3561164f565b6040519080825280601f01601f191660200182016040528015610f5f576020820181803683370190505b5090505b8415610fe257610f7460018361167e565b9150610f81600a86611695565b610f8c9060306116a9565b60f81b818381518110610fa157610fa16116c1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610fdb600a8661163b565b9450610f63565b949350505050565b6000610ff58361100d565b801561100657506110068383611072565b9392505050565b6000611039827f01ffc9a700000000000000000000000000000000000000000000000000000000611072565b801561106c575061106a827fffffffff00000000000000000000000000000000000000000000000000000000611072565b155b92915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561112a575060208210155b80156111365750600081115b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461116357600080fd5b50565b803563ffffffff8116811461117a57600080fd5b919050565b60008083601f84011261119157600080fd5b50813567ffffffffffffffff8111156111a957600080fd5b6020830191508360208285010111156111c157600080fd5b9250929050565b60008060008060008060a087890312156111e157600080fd5b86356111ec81611141565b955060208701356111fc81611141565b94506040870135935061121160608801611166565b9250608087013567ffffffffffffffff81111561122d57600080fd5b61123989828a0161117f565b979a9699509497509295939492505050565b60005b8381101561126657818101518382015260200161124e565b83811115611275576000848401525b50505050565b6000815180845261129381602086016020860161124b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611006602083018461127b565b600080600080600080600060c0888a0312156112f357600080fd5b87356112fe81611141565b9650602088013561130e81611141565b9550604088013561131e81611141565b9450606088013561132e81611141565b93506080880135925060a088013567ffffffffffffffff81111561135157600080fd5b61135d8a828b0161117f565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561138b57600080fd5b873561139681611141565b965060208801356113a681611141565b955060408801356113b681611141565b9450606088013593506113cb60808901611166565b925060a088013567ffffffffffffffff81111561135157600080fd5b600084516113f981846020890161124b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611435816001850160208a0161124b565b6001920191820152835161145081600284016020880161124b565b0160020195945050505050565b60006020828403121561146f57600080fd5b815161100681611141565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006114f960608301848661147a565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261155360c08301848661147a565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061158f606083018561127b565b905063ffffffff83166040830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611605576116056115a5565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261164a5761164a61160c565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015611690576116906115a5565b500390565b6000826116a4576116a461160c565b500690565b600082198211156116bc576116bc6115a5565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "bridgeERC721(address,address,uint256,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.", - "_localToken": "Address of the ERC721 on this domain.", - "_minGasLimit": "Minimum gas limit for the bridge message on the other domain.", - "_remoteToken": "Address of the ERC721 on the remote domain.", - "_tokenId": "Token ID to bridge." - } - }, - "bridgeERC721To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.", - "_localToken": "Address of the ERC721 on this domain.", - "_minGasLimit": "Minimum gas limit for the bridge message on the other domain.", - "_remoteToken": "Address of the ERC721 on the remote domain.", - "_to": "Address to receive the token on the other domain.", - "_tokenId": "Token ID to bridge." - } - }, - "constructor": { - "params": { - "_messenger": "Address of the CrossDomainMessenger on this network.", - "_otherBridge": "Address of the ERC721 bridge on the other network." - } - }, - "finalizeBridgeERC721(address,address,address,address,uint256,bytes)": { - "params": { - "_extraData": "Optional data to forward to L1. Data supplied here will not be used to execute any code on L1 and is only emitted as extra data for the convenience of off-chain tooling.", - "_from": "Address that triggered the bridge on the other domain.", - "_localToken": "Address of the ERC721 token on this domain.", - "_remoteToken": "Address of the ERC721 token on the other domain.", - "_to": "Address to receive the token on this domain.", - "_tokenId": "ID of the token being deposited." - } - }, - "messenger()": { - "returns": { - "_0": "Messenger contract on this domain." - } - }, - "otherBridge()": { - "returns": { - "_0": "Address of the bridge on the other network." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "L2ERC721Bridge" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSENGER()": { - "notice": "Messenger contract on this domain." - }, - "OTHER_BRIDGE()": { - "notice": "Address of the bridge on the other network." - }, - "bridgeERC721(address,address,uint256,uint32,bytes)": { - "notice": "Initiates a bridge of an NFT to the caller's account on the other chain. Note that this function can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` function after ensuring that the recipient address on the remote chain exists. Also note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "bridgeERC721To(address,address,address,uint256,uint32,bytes)": { - "notice": "Initiates a bridge of an NFT to some recipient's account on the other chain. Note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "finalizeBridgeERC721(address,address,address,address,uint256,bytes)": { - "notice": "Completes an ERC721 bridge from the other domain and sends the ERC721 token to the recipient on this domain." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "events": { - "ERC721BridgeFinalized(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC721 bridge from the other network is finalized." - }, - "ERC721BridgeInitiated(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC721 bridge to the other network is initiated." - } - }, - "notice": "The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge. This contract also acts as a burner for tokens being withdrawn. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "storageLayout": { - "storage": [ - { - "astId": 46438, - "contract": "contracts/L2/L2ERC721Bridge.sol:L2ERC721Bridge", - "label": "__gap", - "offset": 0, - "slot": "0", - "type": "t_array(t_uint256)49_storage" - } - ], - "types": { - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/L2ERC721BridgeProxy.json b/packages/contracts-bedrock/deployments/optimism-goerli/L2ERC721BridgeProxy.json deleted file mode 100644 index 7b340b91992b..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/L2ERC721BridgeProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x4200000000000000000000000000000000000014", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x651e799090ad8368e9950399918ebaca75b4c50b030a211d4db139849c628902", - "receipt": { - "to": null, - "from": "0x5c679a57e018F5F146838138d3E032Ef4913D551", - "contractAddress": "0x4200000000000000000000000000000000000014", - "transactionIndex": 0, - "gasUsed": "532674", - "logsBloom": "0x00000000000000000000000000000000000000000000200000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000008000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x93b7b9ef8fb4874e7ca905a3fd375e14c32b863072b7e8cb8c02789f9827122b", - "transactionHash": "0x651e799090ad8368e9950399918ebaca75b4c50b030a211d4db139849c628902", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 1562987, - "transactionHash": "0x651e799090ad8368e9950399918ebaca75b4c50b030a211d4db139849c628902", - "address": "0x4200000000000000000000000000000000000014", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c679a57e018f5f146838138d3e032ef4913d551", - "logIndex": 0, - "blockHash": "0x93b7b9ef8fb4874e7ca905a3fd375e14c32b863072b7e8cb8c02789f9827122b" - } - ], - "blockNumber": 1562987, - "cumulativeGasUsed": "532674", - "status": 1, - "byzantium": true - }, - "args": [ - "0x5c679a57e018F5F146838138d3E032Ef4913D551" - ], - "numDeployments": 1, - "solcInputHash": "ab9b77493f35e63b7a63fb2fa8d618b4", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n external\\n payable\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() external proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() external proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/L2StandardBridge.json b/packages/contracts-bedrock/deployments/optimism-goerli/L2StandardBridge.json deleted file mode 100644 index 3053c165c6a4..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/L2StandardBridge.json +++ /dev/null @@ -1,889 +0,0 @@ -{ - "address": "0x26A77636eD9A97BBDE9740bed362bFCE5CaB8e10", - "abi": [ - { - "inputs": [ - { - "internalType": "address payable", - "name": "_otherBridge", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "DepositFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20BridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20BridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHBridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHBridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "WithdrawalInitiated", - "type": "event" - }, - { - "inputs": [], - "name": "MESSENGER", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_BRIDGE", - "outputs": [ - { - "internalType": "contract StandardBridge", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC20To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeETHTo", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "deposits", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeDeposit", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "l1TokenBridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "messenger", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "withdraw", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "withdrawTo", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x7aa83de19846f2e702d3ff6a51ac9aa273497c3abc49c414c170c43434239265", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0x26A77636eD9A97BBDE9740bed362bFCE5CaB8e10", - "transactionIndex": 1, - "gasUsed": "2401526", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x169e42b58c89087b3b3ab20e52edc28b06e93bc3cd21a9ab044a95149e35d140", - "transactionHash": "0x7aa83de19846f2e702d3ff6a51ac9aa273497c3abc49c414c170c43434239265", - "logs": [], - "blockNumber": 8579669, - "cumulativeGasUsed": "2452027", - "status": 1, - "byzantium": true - }, - "args": [ - "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8" - ], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_otherBridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"DepositFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"WithdrawalInitiated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"contract StandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeDeposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1TokenBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"custom:proxied\":\"@custom:predeploy 0x4200000000000000000000000000000000000010\",\"events\":{\"DepositFinalized(address,address,address,address,uint256,bytes)\":{\"custom:legacy\":\"@notice Emitted whenever an ERC20 deposit is finalized.\",\"params\":{\"amount\":\"Amount of the ERC20 deposited.\",\"extraData\":\"Extra data attached to the deposit.\",\"from\":\"Address of the depositor.\",\"l1Token\":\"Address of the token on L1.\",\"l2Token\":\"Address of the corresponding token on L2.\",\"to\":\"Address of the recipient on L2.\"}},\"WithdrawalInitiated(address,address,address,address,uint256,bytes)\":{\"custom:legacy\":\"@notice Emitted whenever a withdrawal from L2 to L1 is initiated.\",\"params\":{\"amount\":\"Amount of the ERC20 withdrawn.\",\"extraData\":\"Extra data attached to the withdrawal.\",\"from\":\"Address of the withdrawer.\",\"l1Token\":\"Address of the token on L1.\",\"l2Token\":\"Address of the corresponding token on L2.\",\"to\":\"Address of the recipient on L1.\"}}},\"kind\":\"dev\",\"methods\":{\"bridgeERC20(address,address,uint256,uint32,bytes)\":{\"params\":{\"_amount\":\"Amount of local tokens to deposit.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\"}},\"bridgeERC20To(address,address,address,uint256,uint32,bytes)\":{\"params\":{\"_amount\":\"Amount of local tokens to deposit.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\",\"_to\":\"Address of the receiver.\"}},\"bridgeETH(uint32,bytes)\":{\"params\":{\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\"}},\"bridgeETHTo(address,uint32,bytes)\":{\"params\":{\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_to\":\"Address of the receiver.\"}},\"constructor\":{\"custom:semver\":\"1.1.0\",\"params\":{\"_otherBridge\":\"Address of the L1StandardBridge.\"}},\"finalizeBridgeERC20(address,address,address,address,uint256,bytes)\":{\"params\":{\"_amount\":\"Amount of the ERC20 being bridged.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_from\":\"Address of the sender.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\",\"_to\":\"Address of the receiver.\"}},\"finalizeBridgeETH(address,address,uint256,bytes)\":{\"params\":{\"_amount\":\"Amount of ETH being bridged.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_from\":\"Address of the sender.\",\"_to\":\"Address of the receiver.\"}},\"finalizeDeposit(address,address,address,address,uint256,bytes)\":{\"custom:legacy\":\"@notice Finalizes a deposit from L1 to L2. To finalize a deposit of ether, use address(0) and the l1Token and the Legacy ERC20 ether predeploy address as the l2Token.\",\"params\":{\"_amount\":\"Amount of the tokens being deposited.\",\"_extraData\":\"Extra data attached to the deposit.\",\"_from\":\"Address of the depositor.\",\"_l1Token\":\"Address of the L1 token to deposit.\",\"_l2Token\":\"Address of the corresponding L2 token.\",\"_to\":\"Address of the recipient.\"}},\"l1TokenBridge()\":{\"custom:legacy\":\"@notice Retrieves the access of the corresponding L1 bridge contract.\",\"returns\":{\"_0\":\"Address of the corresponding L1 bridge contract.\"}},\"messenger()\":{\"custom:legacy\":\"@notice Legacy getter for messenger contract.\",\"returns\":{\"_0\":\"Messenger contract on this domain.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}},\"withdraw(address,uint256,uint32,bytes)\":{\"custom:legacy\":\"@notice Initiates a withdrawal from L2 to L1. This function only works with OptimismMintableERC20 tokens or ether. Use the `bridgeERC20` function to bridge native L2 tokens to L1.\",\"params\":{\"_amount\":\"Amount of the L2 token to withdraw.\",\"_extraData\":\"Extra data attached to the withdrawal.\",\"_l2Token\":\"Address of the L2 token to withdraw.\",\"_minGasLimit\":\"Minimum gas limit to use for the transaction.\"}},\"withdrawTo(address,address,uint256,uint32,bytes)\":{\"custom:legacy\":\"@notice Initiates a withdrawal from L2 to L1 to a target account on L1. Note that if ETH is sent to a contract on L1 and the call fails, then that ETH will be locked in the L1StandardBridge. ETH may be recoverable if the call can be successfully replayed by increasing the amount of gas supplied to the call. If the call will fail for any amount of gas, then the ETH will be locked permanently. This function only works with OptimismMintableERC20 tokens or ether. Use the `bridgeERC20To` function to bridge native L2 tokens to L1.\",\"params\":{\"_amount\":\"Amount of the L2 token to withdraw.\",\"_extraData\":\"Extra data attached to the withdrawal.\",\"_l2Token\":\"Address of the L2 token to withdraw.\",\"_minGasLimit\":\"Minimum gas limit to use for the transaction.\",\"_to\":\"Recipient account on L1.\"}}},\"title\":\"L2StandardBridge\",\"version\":1},\"userdoc\":{\"events\":{\"ERC20BridgeFinalized(address,address,address,address,uint256,bytes)\":{\"notice\":\"Emitted when an ERC20 bridge is finalized on this chain.\"},\"ERC20BridgeInitiated(address,address,address,address,uint256,bytes)\":{\"notice\":\"Emitted when an ERC20 bridge is initiated to the other chain.\"},\"ETHBridgeFinalized(address,address,uint256,bytes)\":{\"notice\":\"Emitted when an ETH bridge is finalized on this chain.\"},\"ETHBridgeInitiated(address,address,uint256,bytes)\":{\"notice\":\"Emitted when an ETH bridge is initiated to the other chain.\"}},\"kind\":\"user\",\"methods\":{\"MESSENGER()\":{\"notice\":\"Messenger contract on this domain.\"},\"OTHER_BRIDGE()\":{\"notice\":\"Corresponding bridge on the other domain.\"},\"bridgeERC20(address,address,uint256,uint32,bytes)\":{\"notice\":\"Sends ERC20 tokens to the sender's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain.\"},\"bridgeERC20To(address,address,address,uint256,uint32,bytes)\":{\"notice\":\"Sends ERC20 tokens to a receiver's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain.\"},\"bridgeETH(uint32,bytes)\":{\"notice\":\"Sends ETH to the sender's address on the other chain.\"},\"bridgeETHTo(address,uint32,bytes)\":{\"notice\":\"Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a smart contract and the call fails, the ETH will be temporarily locked in the StandardBridge on the other chain until the call is replayed. If the call cannot be replayed with any amount of gas (call always reverts), then the ETH will be permanently locked in the StandardBridge on the other chain. ETH will also be locked if the receiver is the other bridge, because finalizeBridgeETH will revert in that case.\"},\"deposits(address,address)\":{\"notice\":\"Mapping that stores deposits for a given pair of local and remote tokens.\"},\"finalizeBridgeERC20(address,address,address,address,uint256,bytes)\":{\"notice\":\"Finalizes an ERC20 bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain.\"},\"finalizeBridgeETH(address,address,uint256,bytes)\":{\"notice\":\"Finalizes an ETH bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and L2. In the case that an ERC20 token is native to L2, it will be escrowed within this contract. If the ERC20 token is native to L1, it will be burnt. NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples of some token types that may not be properly supported by this contract include, but are not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/L2StandardBridge.sol\":\"L2StandardBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L1/ResourceMetering.sol\":{\"keccak256\":\"0xbd7b9532a70d8c842bfce0ea971be50d02fbbf0227c9ad55c71ac68d438010f4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4969f478dd54e89392cda2ea0c5edcf1be55a5dee43a0e410527b6e3bcb85c88\",\"dweb:/ipfs/QmU2crAojw8DRDsz7PAPrereazjFsKh9wtfTpTDVh6NLfW\"]},\"contracts/L2/L2StandardBridge.sol\":{\"keccak256\":\"0xd77e04c57f33cd32c32f326cd06e213d8a27a9fd372cfc4269953a49243c8c41\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f59627bf4c08c85886e819b29b8565b48fa7e9c230732fedfbb0b9c9a0ee04c5\",\"dweb:/ipfs/Qmao1VbQ57h6gdCZTYfipa8LB1wBwAthop5tPd9TgDXES2\"]},\"contracts/libraries/Arithmetic.sol\":{\"keccak256\":\"0xc8858039f87e48e6f18c1af8bc0b03e57cfef564acddfd06e4d91e3db7ac5ed6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2fc79af1e844aa6dc1c68067bfe1d359df8d4e9a3e8881afb3bcfcbf68071714\",\"dweb:/ipfs/QmcNC4k8zmvwj4kZizSenTiWbx2DJQPbwqXXLF4iMbkRVD\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Constants.sol\":{\"keccak256\":\"0x8c7be28a175eb732995a7f704560163c30261f9f70d377f865c5060882509f5d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f72aba26553b10ca88708e05461691b36b0d2ec7a87f718022fe119ca9c70852\",\"dweb:/ipfs/QmQtDEB1F3D8RsgG63KSJ9t7ZyFLaXc2Av81vKD9y2TMn7\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/Predeploys.sol\":{\"keccak256\":\"0xfc30fb239b5f00284f4b8f578a62f0882597e939335c91ea9bc4aab3070ddc43\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fa132267b3a9d98568b4e02cbb68fe2d2c0ca630826242c1b2293a8fa35bd302\",\"dweb:/ipfs/QmdYvcGbaykP6wyBu5T2obXrWK56xGnfWqbYeeWpTChq3w\"]},\"contracts/libraries/SafeCall.sol\":{\"keccak256\":\"0x6e815b62528d452a4f63040d75ff7a08db8ba8096050a53355fc49abaebdf245\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e27e542a11165c82cbb6961f4d8c2a58527fba1ab915afeeded50e96ce929777\",\"dweb:/ipfs/QmRPXdmUAbL1WHZBvENKWkFuHb9bQyrbiJWwDvzEQBLVi8\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x4fe8ec920798661a828430bd30dc2715eeb40534ec01c0a7bf41cb4ab422e134\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://74c8471869900bd459358cd990bda1c8d234c06b788804c7049cf465ae1e299f\",\"dweb:/ipfs/QmakcfP6NmbVUQsKqH7rEyJsbiqckigLahw9g74oencEJ7\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x3c99b1e768cc4c1e064ccc137b1b4d5961bf4edf071be84cc216c5b20f1c00da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e36b2a6325c2f804d769271575669b62ab2da2df3c81921ac7487399fe02af07\",\"dweb:/ipfs/QmTCmcEKwvD8Xvjyev268Bkz27FC7TJpUbw1nADcsThnUr\"]},\"contracts/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x2fea0ee05071c9c6b06a34a8e805801e247e861359b376a8918106e1d6f77ebe\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://198c91bda2edf864ddad1f8ab6168155d13d6ba5487418e5531ff040ff250686\",\"dweb:/ipfs/QmQzxfHY4P7zdVFRh2DTdGt1KeMHaGKNRf3KPZ1mRTYEGB\"]},\"contracts/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x302094342a45ebdf7f46f4fb48821960d2a4134f66fd7f458f73fc4ddf34d219\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b0e2b496e966ca6037e1c9be1d44417c0180fda2a27f68114e93b899defb783\",\"dweb:/ipfs/QmXP76ivMLxYxscC7B9E9qtW3u6HJ2MNaRVeo3x24VEAQH\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"contracts/universal/StandardBridge.sol\":{\"keccak256\":\"0xaa45044774fa70ed322983c3c0138b21d26d75f4b7e8f5324d53c3eef91adec4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c65c95d0cb71f2e32f5ffdea92151a9a46bbd538ba110389a134963fd16a33e9\",\"dweb:/ipfs/QmaPNZokt4j5SCXaWwVtw6qxu5GXWFa3SWBgaSWPPA9KUG\"]},\"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://11756f42121f6541a35a8339ea899ee7514cfaa2e6d740625fcc844419296aa6\",\"dweb:/ipfs/QmekMuk6BY4DAjzeXr4MSbKdgoqqsZnA8JPtuyWc6CwXHf\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]}},\"version\":1}", - "bytecode": "0x6101206040523480156200001257600080fd5b5060405162002c0638038062002c0683398101604081905262000035916200006f565b7342000000000000000000000000000000000000076080526001600160a01b031660a052600160c081905260e052600061010052620000a1565b6000602082840312156200008257600080fd5b81516001600160a01b03811681146200009a57600080fd5b9392505050565b60805160a05160c05160e05161010051612ac5620001416000396000610fd201526000610fa901526000610f800152600081816102280152818161030c0152818161050b015281816109cf015281816112ca015261160b015260008181610281015281816103a6015281816104e101528181610542015281816109a501528181610a0601528181610c930152818161128d01526115cf0152612ac56000f3fe6080604052600436106100ec5760003560e01c806354fd4d501161008a5780638f601f66116100595780638f601f661461034e578063927ede2d14610394578063a3a79548146103c8578063e11013dd146103db57600080fd5b806354fd4d50146102c5578063662a633a146102e75780637f46ddb2146102fa578063870876231461032e57600080fd5b806332b7006d116100c657806332b7006d1461020657806336c717c1146102195780633cb747bf14610272578063540abf73146102a557600080fd5b80630166a07a146101c057806309fc8843146101e05780631635f5fd146101f357600080fd5b366101bb57333b15610185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101b973deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d40604051806020016040528060008152506103ee565b005b600080fd5b3480156101cc57600080fd5b506101b96101db366004612372565b6104c9565b6101b96101ee366004612423565b6108b6565b6101b9610201366004612476565b61098d565b6101b96102143660046124e9565b610e5a565b34801561022557600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561027e57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610248565b3480156102b157600080fd5b506101b96102c036600461253d565b610f34565b3480156102d157600080fd5b506102da610f79565b604051610269919061262a565b6101b96102f5366004612372565b61101c565b34801561030657600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b34801561033a57600080fd5b506101b961034936600461263d565b61108f565b34801561035a57600080fd5b506103866103693660046126c0565b600260209081526000928352604080842090915290825290205481565b604051908152602001610269565b3480156103a057600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b6101b96103d636600461263d565b611163565b6101b96103e93660046126f9565b6111a7565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff87160161043d5761043885858585856111f0565b6104c1565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ae919061275c565b90506104bf878288888888886113d4565b505b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156105e757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf919061275c565b73ffffffffffffffffffffffffffffffffffffffff16145b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b6106a28761171b565b156107f0576106b1878761177d565b610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107d357600080fd5b505af11580156107e7573d6000803e3d6000fd5b50505050610872565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461082e9084906127a8565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561087290858561189d565b6104bf878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061197192505050565b333b15610945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6109883333348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610aab57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a93919061275c565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b823414610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e74207265717569726564000000000000606482015260840161017c565b3073ffffffffffffffffffffffffffffffffffffffff851603610c91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c660000000000000000000000000000000000000000000000000000000000606482015260840161017c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e676572000000000000000000000000000000000000000000000000606482015260840161017c565b610dae85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119ff92505050565b6000610dcb855a8660405180602001604052806000815250611aa0565b9050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c65640000000000000000000000000000000000000000000000000000000000606482015260840161017c565b333b15610ee9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b610f2d853333878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b5050505050565b6104bf87873388888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6060610fa47f0000000000000000000000000000000000000000000000000000000000000000611aba565b610fcd7f0000000000000000000000000000000000000000000000000000000000000000611aba565b610ff67f0000000000000000000000000000000000000000000000000000000000000000611aba565b604051602001611008939291906127bf565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015611069575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b156110805761107b858585858561098d565b6104bf565b6104bf868887878787876104c9565b333b1561111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6104c186863333888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6104c1863387878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b6111ea3385348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b50505050565b82341461127f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c75650000606482015260840161017c565b61128b85858584611bf7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b898989886040516024016113089493929190612835565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261139b9291889060040161287e565b6000604051808303818588803b1580156113b457600080fd5b505af11580156113c8573d6000803e3d6000fd5b50505050505050505050565b6113dd8761171b565b1561152b576113ec878761177d565b61149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561150e57600080fd5b505af1158015611522573d6000803e3d6000fd5b505050506115bf565b61154d73ffffffffffffffffffffffffffffffffffffffff8816863086611c98565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461158b9084906128c3565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b6115cd878787878786611cf6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b898b8a8a8a8960405160240161164d969594939291906128db565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b90921682526116e09291879060040161287e565b600060405180830381600087803b1580156116fa57600080fd5b505af115801561170e573d6000803e3d6000fd5b5050505050505050505050565b6000611747827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d84565b806117775750611777827fec4fc8e300000000000000000000000000000000000000000000000000000000611d84565b92915050565b60006117a9837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d84565b15611852578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181d919061275c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611777565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f9573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109889084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611da7565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898686866040516119e993929190612936565b60405180910390a46104c1868686868686611eb3565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611a8c93929190612936565b60405180910390a46111ea84848484611f3b565b600080600080845160208601878a8af19695505050505050565b606081600003611afd57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611b275780611b1181612974565b9150611b209050600a836129db565b9150611b01565b60008167ffffffffffffffff811115611b4257611b426129ef565b6040519080825280601f01601f191660200182016040528015611b6c576020820181803683370190505b5090505b8415611bef57611b816001836127a8565b9150611b8e600a86612a1e565b611b999060306128c3565b60f81b818381518110611bae57611bae612a32565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611be8600a866129db565b9450611b70565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611c8493929190612936565b60405180910390a46111ea84848484611fa8565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526111ea9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016118ef565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611d6e93929190612936565b60405180910390a46104c1868686868686612007565b6000611d8f8361207f565b8015611da05750611da083836120e3565b9392505050565b6000611e09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b29092919063ffffffff16565b8051909150156109885780806020019051810190611e279190612a61565b610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161017c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611f2b93929190612936565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f9a929190612a83565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f9a929190612a83565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611f2b93929190612936565b60006120ab827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e3565b801561177757506120dc827fffffffff000000000000000000000000000000000000000000000000000000006120e3565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219b575060208210155b80156121a75750600081115b979650505050505050565b6060611bef84846000858573ffffffffffffffffffffffffffffffffffffffff85163b61223b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161017c565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516122649190612a9c565b60006040518083038185875af1925050503d80600081146122a1576040519150601f19603f3d011682016040523d82523d6000602084013e6122a6565b606091505b50915091506121a7828286606083156122c0575081611da0565b8251156122d05782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017c919061262a565b73ffffffffffffffffffffffffffffffffffffffff8116811461232657600080fd5b50565b60008083601f84011261233b57600080fd5b50813567ffffffffffffffff81111561235357600080fd5b60208301915083602082850101111561236b57600080fd5b9250929050565b600080600080600080600060c0888a03121561238d57600080fd5b873561239881612304565b965060208801356123a881612304565b955060408801356123b881612304565b945060608801356123c881612304565b93506080880135925060a088013567ffffffffffffffff8111156123eb57600080fd5b6123f78a828b01612329565b989b979a50959850939692959293505050565b803563ffffffff8116811461241e57600080fd5b919050565b60008060006040848603121561243857600080fd5b6124418461240a565b9250602084013567ffffffffffffffff81111561245d57600080fd5b61246986828701612329565b9497909650939450505050565b60008060008060006080868803121561248e57600080fd5b853561249981612304565b945060208601356124a981612304565b935060408601359250606086013567ffffffffffffffff8111156124cc57600080fd5b6124d888828901612329565b969995985093965092949392505050565b60008060008060006080868803121561250157600080fd5b853561250c81612304565b9450602086013593506125216040870161240a565b9250606086013567ffffffffffffffff8111156124cc57600080fd5b600080600080600080600060c0888a03121561255857600080fd5b873561256381612304565b9650602088013561257381612304565b9550604088013561258381612304565b9450606088013593506125986080890161240a565b925060a088013567ffffffffffffffff8111156123eb57600080fd5b60005b838110156125cf5781810151838201526020016125b7565b838111156111ea5750506000910152565b600081518084526125f88160208601602086016125b4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611da060208301846125e0565b60008060008060008060a0878903121561265657600080fd5b863561266181612304565b9550602087013561267181612304565b9450604087013593506126866060880161240a565b9250608087013567ffffffffffffffff8111156126a257600080fd5b6126ae89828a01612329565b979a9699509497509295939492505050565b600080604083850312156126d357600080fd5b82356126de81612304565b915060208301356126ee81612304565b809150509250929050565b6000806000806060858703121561270f57600080fd5b843561271a81612304565b93506127286020860161240a565b9250604085013567ffffffffffffffff81111561274457600080fd5b61275087828801612329565b95989497509550505050565b60006020828403121561276e57600080fd5b8151611da081612304565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156127ba576127ba612779565b500390565b600084516127d18184602089016125b4565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161280d816001850160208a016125b4565b600192019182015283516128288160028401602088016125b4565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261287460808301846125e0565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006128ad60608301856125e0565b905063ffffffff83166040830152949350505050565b600082198211156128d6576128d6612779565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261292a60c08301846125e0565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296b60608301846125e0565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036129a5576129a5612779565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826129ea576129ea6129ac565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612a2d57612a2d6129ac565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612a7357600080fd5b81518015158114611da057600080fd5b828152604060208201526000611bef60408301846125e0565b60008251612aae8184602087016125b4565b919091019291505056fea164736f6c634300080f000a", - "deployedBytecode": "0x6080604052600436106100ec5760003560e01c806354fd4d501161008a5780638f601f66116100595780638f601f661461034e578063927ede2d14610394578063a3a79548146103c8578063e11013dd146103db57600080fd5b806354fd4d50146102c5578063662a633a146102e75780637f46ddb2146102fa578063870876231461032e57600080fd5b806332b7006d116100c657806332b7006d1461020657806336c717c1146102195780633cb747bf14610272578063540abf73146102a557600080fd5b80630166a07a146101c057806309fc8843146101e05780631635f5fd146101f357600080fd5b366101bb57333b15610185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101b973deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d40604051806020016040528060008152506103ee565b005b600080fd5b3480156101cc57600080fd5b506101b96101db366004612372565b6104c9565b6101b96101ee366004612423565b6108b6565b6101b9610201366004612476565b61098d565b6101b96102143660046124e9565b610e5a565b34801561022557600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561027e57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610248565b3480156102b157600080fd5b506101b96102c036600461253d565b610f34565b3480156102d157600080fd5b506102da610f79565b604051610269919061262a565b6101b96102f5366004612372565b61101c565b34801561030657600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b34801561033a57600080fd5b506101b961034936600461263d565b61108f565b34801561035a57600080fd5b506103866103693660046126c0565b600260209081526000928352604080842090915290825290205481565b604051908152602001610269565b3480156103a057600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b6101b96103d636600461263d565b611163565b6101b96103e93660046126f9565b6111a7565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff87160161043d5761043885858585856111f0565b6104c1565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ae919061275c565b90506104bf878288888888886113d4565b505b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156105e757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf919061275c565b73ffffffffffffffffffffffffffffffffffffffff16145b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b6106a28761171b565b156107f0576106b1878761177d565b610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107d357600080fd5b505af11580156107e7573d6000803e3d6000fd5b50505050610872565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461082e9084906127a8565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561087290858561189d565b6104bf878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061197192505050565b333b15610945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6109883333348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610aab57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a93919061275c565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b823414610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e74207265717569726564000000000000606482015260840161017c565b3073ffffffffffffffffffffffffffffffffffffffff851603610c91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c660000000000000000000000000000000000000000000000000000000000606482015260840161017c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e676572000000000000000000000000000000000000000000000000606482015260840161017c565b610dae85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119ff92505050565b6000610dcb855a8660405180602001604052806000815250611aa0565b9050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c65640000000000000000000000000000000000000000000000000000000000606482015260840161017c565b333b15610ee9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b610f2d853333878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b5050505050565b6104bf87873388888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6060610fa47f0000000000000000000000000000000000000000000000000000000000000000611aba565b610fcd7f0000000000000000000000000000000000000000000000000000000000000000611aba565b610ff67f0000000000000000000000000000000000000000000000000000000000000000611aba565b604051602001611008939291906127bf565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015611069575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b156110805761107b858585858561098d565b6104bf565b6104bf868887878787876104c9565b333b1561111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6104c186863333888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6104c1863387878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b6111ea3385348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b50505050565b82341461127f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c75650000606482015260840161017c565b61128b85858584611bf7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b898989886040516024016113089493929190612835565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261139b9291889060040161287e565b6000604051808303818588803b1580156113b457600080fd5b505af11580156113c8573d6000803e3d6000fd5b50505050505050505050565b6113dd8761171b565b1561152b576113ec878761177d565b61149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561150e57600080fd5b505af1158015611522573d6000803e3d6000fd5b505050506115bf565b61154d73ffffffffffffffffffffffffffffffffffffffff8816863086611c98565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461158b9084906128c3565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b6115cd878787878786611cf6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b898b8a8a8a8960405160240161164d969594939291906128db565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b90921682526116e09291879060040161287e565b600060405180830381600087803b1580156116fa57600080fd5b505af115801561170e573d6000803e3d6000fd5b5050505050505050505050565b6000611747827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d84565b806117775750611777827fec4fc8e300000000000000000000000000000000000000000000000000000000611d84565b92915050565b60006117a9837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d84565b15611852578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181d919061275c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611777565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f9573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109889084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611da7565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898686866040516119e993929190612936565b60405180910390a46104c1868686868686611eb3565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611a8c93929190612936565b60405180910390a46111ea84848484611f3b565b600080600080845160208601878a8af19695505050505050565b606081600003611afd57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611b275780611b1181612974565b9150611b209050600a836129db565b9150611b01565b60008167ffffffffffffffff811115611b4257611b426129ef565b6040519080825280601f01601f191660200182016040528015611b6c576020820181803683370190505b5090505b8415611bef57611b816001836127a8565b9150611b8e600a86612a1e565b611b999060306128c3565b60f81b818381518110611bae57611bae612a32565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611be8600a866129db565b9450611b70565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611c8493929190612936565b60405180910390a46111ea84848484611fa8565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526111ea9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016118ef565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611d6e93929190612936565b60405180910390a46104c1868686868686612007565b6000611d8f8361207f565b8015611da05750611da083836120e3565b9392505050565b6000611e09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b29092919063ffffffff16565b8051909150156109885780806020019051810190611e279190612a61565b610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161017c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611f2b93929190612936565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f9a929190612a83565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f9a929190612a83565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611f2b93929190612936565b60006120ab827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e3565b801561177757506120dc827fffffffff000000000000000000000000000000000000000000000000000000006120e3565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219b575060208210155b80156121a75750600081115b979650505050505050565b6060611bef84846000858573ffffffffffffffffffffffffffffffffffffffff85163b61223b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161017c565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516122649190612a9c565b60006040518083038185875af1925050503d80600081146122a1576040519150601f19603f3d011682016040523d82523d6000602084013e6122a6565b606091505b50915091506121a7828286606083156122c0575081611da0565b8251156122d05782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017c919061262a565b73ffffffffffffffffffffffffffffffffffffffff8116811461232657600080fd5b50565b60008083601f84011261233b57600080fd5b50813567ffffffffffffffff81111561235357600080fd5b60208301915083602082850101111561236b57600080fd5b9250929050565b600080600080600080600060c0888a03121561238d57600080fd5b873561239881612304565b965060208801356123a881612304565b955060408801356123b881612304565b945060608801356123c881612304565b93506080880135925060a088013567ffffffffffffffff8111156123eb57600080fd5b6123f78a828b01612329565b989b979a50959850939692959293505050565b803563ffffffff8116811461241e57600080fd5b919050565b60008060006040848603121561243857600080fd5b6124418461240a565b9250602084013567ffffffffffffffff81111561245d57600080fd5b61246986828701612329565b9497909650939450505050565b60008060008060006080868803121561248e57600080fd5b853561249981612304565b945060208601356124a981612304565b935060408601359250606086013567ffffffffffffffff8111156124cc57600080fd5b6124d888828901612329565b969995985093965092949392505050565b60008060008060006080868803121561250157600080fd5b853561250c81612304565b9450602086013593506125216040870161240a565b9250606086013567ffffffffffffffff8111156124cc57600080fd5b600080600080600080600060c0888a03121561255857600080fd5b873561256381612304565b9650602088013561257381612304565b9550604088013561258381612304565b9450606088013593506125986080890161240a565b925060a088013567ffffffffffffffff8111156123eb57600080fd5b60005b838110156125cf5781810151838201526020016125b7565b838111156111ea5750506000910152565b600081518084526125f88160208601602086016125b4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611da060208301846125e0565b60008060008060008060a0878903121561265657600080fd5b863561266181612304565b9550602087013561267181612304565b9450604087013593506126866060880161240a565b9250608087013567ffffffffffffffff8111156126a257600080fd5b6126ae89828a01612329565b979a9699509497509295939492505050565b600080604083850312156126d357600080fd5b82356126de81612304565b915060208301356126ee81612304565b809150509250929050565b6000806000806060858703121561270f57600080fd5b843561271a81612304565b93506127286020860161240a565b9250604085013567ffffffffffffffff81111561274457600080fd5b61275087828801612329565b95989497509550505050565b60006020828403121561276e57600080fd5b8151611da081612304565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156127ba576127ba612779565b500390565b600084516127d18184602089016125b4565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161280d816001850160208a016125b4565b600192019182015283516128288160028401602088016125b4565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261287460808301846125e0565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006128ad60608301856125e0565b905063ffffffff83166040830152949350505050565b600082198211156128d6576128d6612779565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261292a60c08301846125e0565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296b60608301846125e0565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036129a5576129a5612779565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826129ea576129ea6129ac565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612a2d57612a2d6129ac565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612a7357600080fd5b81518015158114611da057600080fd5b828152604060208201526000611bef60408301846125e0565b60008251612aae8184602087016125b4565b919091019291505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "bridgeERC20(address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of local tokens to deposit.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_localToken": "Address of the ERC20 on this chain.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_remoteToken": "Address of the corresponding token on the remote chain." - } - }, - "bridgeERC20To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of local tokens to deposit.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_localToken": "Address of the ERC20 on this chain.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_remoteToken": "Address of the corresponding token on the remote chain.", - "_to": "Address of the receiver." - } - }, - "bridgeETH(uint32,bytes)": { - "params": { - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with." - } - }, - "bridgeETHTo(address,uint32,bytes)": { - "params": { - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_to": "Address of the receiver." - } - }, - "constructor": { - "params": { - "_otherBridge": "Address of the L1StandardBridge." - } - }, - "finalizeBridgeERC20(address,address,address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of the ERC20 being bridged.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_from": "Address of the sender.", - "_localToken": "Address of the ERC20 on this chain.", - "_remoteToken": "Address of the corresponding token on the remote chain.", - "_to": "Address of the receiver." - } - }, - "finalizeBridgeETH(address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of ETH being bridged.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_from": "Address of the sender.", - "_to": "Address of the receiver." - } - }, - "finalizeDeposit(address,address,address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of the tokens being deposited.", - "_extraData": "Extra data attached to the deposit.", - "_from": "Address of the depositor.", - "_l1Token": "Address of the L1 token to deposit.", - "_l2Token": "Address of the corresponding L2 token.", - "_to": "Address of the recipient." - } - }, - "l1TokenBridge()": { - "returns": { - "_0": "Address of the corresponding L1 bridge contract." - } - }, - "messenger()": { - "returns": { - "_0": "Messenger contract on this domain." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - }, - "withdraw(address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of the L2 token to withdraw.", - "_extraData": "Extra data attached to the withdrawal.", - "_l2Token": "Address of the L2 token to withdraw.", - "_minGasLimit": "Minimum gas limit to use for the transaction." - } - }, - "withdrawTo(address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of the L2 token to withdraw.", - "_extraData": "Extra data attached to the withdrawal.", - "_l2Token": "Address of the L2 token to withdraw.", - "_minGasLimit": "Minimum gas limit to use for the transaction.", - "_to": "Recipient account on L1." - } - } - }, - "events": { - "DepositFinalized(address,address,address,address,uint256,bytes)": { - "params": { - "amount": "Amount of the ERC20 deposited.", - "extraData": "Extra data attached to the deposit.", - "from": "Address of the depositor.", - "l1Token": "Address of the token on L1.", - "l2Token": "Address of the corresponding token on L2.", - "to": "Address of the recipient on L2." - } - }, - "WithdrawalInitiated(address,address,address,address,uint256,bytes)": { - "params": { - "amount": "Amount of the ERC20 withdrawn.", - "extraData": "Extra data attached to the withdrawal.", - "from": "Address of the withdrawer.", - "l1Token": "Address of the token on L1.", - "l2Token": "Address of the corresponding token on L2.", - "to": "Address of the recipient on L1." - } - } - }, - "title": "L2StandardBridge" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSENGER()": { - "notice": "Messenger contract on this domain." - }, - "OTHER_BRIDGE()": { - "notice": "Corresponding bridge on the other domain." - }, - "bridgeERC20(address,address,uint256,uint32,bytes)": { - "notice": "Sends ERC20 tokens to the sender's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain." - }, - "bridgeERC20To(address,address,address,uint256,uint32,bytes)": { - "notice": "Sends ERC20 tokens to a receiver's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain." - }, - "bridgeETH(uint32,bytes)": { - "notice": "Sends ETH to the sender's address on the other chain." - }, - "bridgeETHTo(address,uint32,bytes)": { - "notice": "Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a smart contract and the call fails, the ETH will be temporarily locked in the StandardBridge on the other chain until the call is replayed. If the call cannot be replayed with any amount of gas (call always reverts), then the ETH will be permanently locked in the StandardBridge on the other chain. ETH will also be locked if the receiver is the other bridge, because finalizeBridgeETH will revert in that case." - }, - "deposits(address,address)": { - "notice": "Mapping that stores deposits for a given pair of local and remote tokens." - }, - "finalizeBridgeERC20(address,address,address,address,uint256,bytes)": { - "notice": "Finalizes an ERC20 bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain." - }, - "finalizeBridgeETH(address,address,uint256,bytes)": { - "notice": "Finalizes an ETH bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "events": { - "ERC20BridgeFinalized(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC20 bridge is finalized on this chain." - }, - "ERC20BridgeInitiated(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC20 bridge is initiated to the other chain." - }, - "ETHBridgeFinalized(address,address,uint256,bytes)": { - "notice": "Emitted when an ETH bridge is finalized on this chain." - }, - "ETHBridgeInitiated(address,address,uint256,bytes)": { - "notice": "Emitted when an ETH bridge is initiated to the other chain." - } - }, - "notice": "The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and L2. In the case that an ERC20 token is native to L2, it will be escrowed within this contract. If the ERC20 token is native to L1, it will be burnt. NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples of some token types that may not be properly supported by this contract include, but are not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists." - }, - "storageLayout": { - "storage": [ - { - "astId": 48356, - "contract": "contracts/L2/L2StandardBridge.sol:L2StandardBridge", - "label": "spacer_0_0_20", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 48359, - "contract": "contracts/L2/L2StandardBridge.sol:L2StandardBridge", - "label": "spacer_1_0_20", - "offset": 0, - "slot": "1", - "type": "t_address" - }, - { - "astId": 48366, - "contract": "contracts/L2/L2StandardBridge.sol:L2StandardBridge", - "label": "deposits", - "offset": 0, - "slot": "2", - "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" - }, - { - "astId": 48371, - "contract": "contracts/L2/L2StandardBridge.sol:L2StandardBridge", - "label": "__gap", - "offset": 0, - "slot": "3", - "type": "t_array(t_uint256)47_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)47_storage": { - "encoding": "inplace", - "label": "uint256[47]", - "numberOfBytes": "1504", - "base": "t_uint256" - }, - "t_mapping(t_address,t_mapping(t_address,t_uint256))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => uint256))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_uint256)" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/L2ToL1MessagePasser.json b/packages/contracts-bedrock/deployments/optimism-goerli/L2ToL1MessagePasser.json deleted file mode 100644 index 5c7c0c2004aa..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/L2ToL1MessagePasser.json +++ /dev/null @@ -1,306 +0,0 @@ -{ - "address": "0x50CcA47c1e06084459dc83c9E964F4a158cB28Ae", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "withdrawalHash", - "type": "bytes32" - } - ], - "name": "MessagePassed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrawerBalanceBurnt", - "type": "event" - }, - { - "inputs": [], - "name": "MESSAGE_VERSION", - "outputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "burn", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_gasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "initiateWithdrawal", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "messageNonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "sentMessages", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x34eb684cb1a7cd53dcbbeac926c389066708b55023662726da724f527151c50a", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0x50CcA47c1e06084459dc83c9E964F4a158cB28Ae", - "transactionIndex": 2, - "gasUsed": "609034", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xfc90bb4a325d363720404e9c49e0d3f1354028f8f6efe8af49b2b4b4cee1028f", - "transactionHash": "0x34eb684cb1a7cd53dcbbeac926c389066708b55023662726da724f527151c50a", - "logs": [], - "blockNumber": 8579675, - "cumulativeGasUsed": "877476", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"}],\"name\":\"MessagePassed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawerBalanceBurnt\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"initiateWithdrawal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"sentMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"custom:proxied\":\"@custom:predeploy 0x4200000000000000000000000000000000000016\",\"events\":{\"MessagePassed(uint256,address,address,uint256,uint256,bytes,bytes32)\":{\"params\":{\"data\":\"The data to be forwarded to the target on L1.\",\"gasLimit\":\"The minimum amount of gas that must be provided when withdrawing.\",\"nonce\":\"Unique value corresponding to each withdrawal.\",\"sender\":\"The L2 account address which initiated the withdrawal.\",\"target\":\"The L1 account address the call will be send to.\",\"value\":\"The ETH value submitted for withdrawal, to be forwarded to the target.\",\"withdrawalHash\":\"The hash of the withdrawal.\"}},\"WithdrawerBalanceBurnt(uint256)\":{\"params\":{\"amount\":\"Amount of ETh that was burned.\"}}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.0.0\"},\"initiateWithdrawal(address,uint256,bytes)\":{\"params\":{\"_data\":\"Data to forward to L1 target.\",\"_gasLimit\":\"Minimum gas limit for executing the message on L1.\",\"_target\":\"Address to call on L1 execution.\"}},\"messageNonce()\":{\"returns\":{\"_0\":\"Nonce of the next message to be sent, with added message version.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"L2ToL1MessagePasser\",\"version\":1},\"userdoc\":{\"events\":{\"MessagePassed(uint256,address,address,uint256,uint256,bytes,bytes32)\":{\"notice\":\"Emitted any time a withdrawal is initiated.\"},\"WithdrawerBalanceBurnt(uint256)\":{\"notice\":\"Emitted when the balance of this contract is burned.\"}},\"kind\":\"user\",\"methods\":{\"MESSAGE_VERSION()\":{\"notice\":\"Current message version identifier.\"},\"burn()\":{\"notice\":\"Removes all ETH held by this contract from the state. Used to prevent the amount of ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to create a contract and self-destruct it to itself. Anyone can call this function. Not incentivized since this function is very cheap.\"},\"initiateWithdrawal(address,uint256,bytes)\":{\"notice\":\"Sends a message from L2 to L1.\"},\"messageNonce()\":{\"notice\":\"Retrieves the next message nonce. Message version will be added to the upper two bytes of the message nonce. Message version allows us to treat messages as having different structures.\"},\"sentMessages(bytes32)\":{\"notice\":\"Includes the message hashes for all withdrawals\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from L2 to L1 can be stored. The storage root of this contract is pulled up to the top level of the L2 output to reduce the cost of proving the existence of sent messages.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/L2ToL1MessagePasser.sol\":\"L2ToL1MessagePasser\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L2/L2ToL1MessagePasser.sol\":{\"keccak256\":\"0xa385bda91d75c44f6d8b0bc5a61e1904ed455d98c07b308910ac1265e6536df1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://dcbaab318b084e163992187aa87f9250782982c10d69be9e11959090e02cc912\",\"dweb:/ipfs/QmY81HgBPp4vcMigSbWQ8mDizXCQFvjN52BF7nGPc6f9Fm\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x4fe8ec920798661a828430bd30dc2715eeb40534ec01c0a7bf41cb4ab422e134\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://74c8471869900bd459358cd990bda1c8d234c06b788804c7049cf465ae1e299f\",\"dweb:/ipfs/QmakcfP6NmbVUQsKqH7rEyJsbiqckigLahw9g74oencEJ7\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]}},\"version\":1}", - "bytecode": "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c081905280610a2061004a82396000610403015260006103da015260006103b10152610a206000f3fe6080604052600436106100695760003560e01c806382e3702d1161004357806382e3702d146100f6578063c2b3e5ac14610136578063ecc704281461014957600080fd5b80633f827a5a1461009257806344df8e70146100bf57806354fd4d50146100d457600080fd5b3661008d5761008b33620186a0604051806020016040528060008152506101ae565b005b600080fd5b34801561009e57600080fd5b506100a7600181565b60405161ffff90911681526020015b60405180910390f35b3480156100cb57600080fd5b5061008b610372565b3480156100e057600080fd5b506100e96103aa565b6040516100b6919061068c565b34801561010257600080fd5b506101266101113660046106a6565b60006020819052908152604090205460ff1681565b60405190151581526020016100b6565b61008b6101443660046106ee565b6101ae565b34801561015557600080fd5b506101a06001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016100b6565b60006102446040518060c001604052806102086001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b815233602082015273ffffffffffffffffffffffffffffffffffffffff871660408201523460608201526080810186905260a00184905261044d565b600081815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055905073ffffffffffffffffffffffffffffffffffffffff8416336102df6001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b7f02a52367d10742d8032712c1bb8e0144ff1ec5ffda1ed7d70bb05a27449550543487878760405161031494939291906107f2565b60405180910390a45050600180547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082168301167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b4761037c8161049a565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b60606103d57f00000000000000000000000000000000000000000000000000000000000000006104c9565b6103fe7f00000000000000000000000000000000000000000000000000000000000000006104c9565b6104277f00000000000000000000000000000000000000000000000000000000000000006104c9565b60405160200161043993929190610822565b604051602081830303815290604052905090565b80516020808301516040808501516060860151608087015160a0880151935160009761047d979096959101610898565b604051602081830303815290604052805190602001209050919050565b806040516104a790610606565b6040518091039082f09050801580156104c4573d6000803e3d6000fd5b505050565b60608160000361050c57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561053657806105208161091e565b915061052f9050600a83610985565b9150610510565b60008167ffffffffffffffff811115610551576105516106bf565b6040519080825280601f01601f19166020018201604052801561057b576020820181803683370190505b5090505b84156105fe57610590600183610999565b915061059d600a866109b0565b6105a89060306109c4565b60f81b8183815181106105bd576105bd6109dc565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506105f7600a86610985565b945061057f565b949350505050565b600880610a0c83390190565b60005b8381101561062d578181015183820152602001610615565b8381111561063c576000848401525b50505050565b6000815180845261065a816020860160208601610612565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061069f6020830184610642565b9392505050565b6000602082840312156106b857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561070357600080fd5b833573ffffffffffffffffffffffffffffffffffffffff8116811461072757600080fd5b925060208401359150604084013567ffffffffffffffff8082111561074b57600080fd5b818601915086601f83011261075f57600080fd5b813581811115610771576107716106bf565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156107b7576107b76106bf565b816040528281528960208487010111156107d057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b8481528360208201526080604082015260006108116080830185610642565b905082606083015295945050505050565b60008451610834818460208901610612565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610870816001850160208a01610612565b6001920191820152835161088b816002840160208801610612565b0160020195945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526108e360c0830184610642565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361094f5761094f6108ef565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261099457610994610956565b500490565b6000828210156109ab576109ab6108ef565b500390565b6000826109bf576109bf610956565b500690565b600082198211156109d7576109d76108ef565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe608060405230fffea164736f6c634300080f000a", - "deployedBytecode": "0x6080604052600436106100695760003560e01c806382e3702d1161004357806382e3702d146100f6578063c2b3e5ac14610136578063ecc704281461014957600080fd5b80633f827a5a1461009257806344df8e70146100bf57806354fd4d50146100d457600080fd5b3661008d5761008b33620186a0604051806020016040528060008152506101ae565b005b600080fd5b34801561009e57600080fd5b506100a7600181565b60405161ffff90911681526020015b60405180910390f35b3480156100cb57600080fd5b5061008b610372565b3480156100e057600080fd5b506100e96103aa565b6040516100b6919061068c565b34801561010257600080fd5b506101266101113660046106a6565b60006020819052908152604090205460ff1681565b60405190151581526020016100b6565b61008b6101443660046106ee565b6101ae565b34801561015557600080fd5b506101a06001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016100b6565b60006102446040518060c001604052806102086001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b815233602082015273ffffffffffffffffffffffffffffffffffffffff871660408201523460608201526080810186905260a00184905261044d565b600081815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055905073ffffffffffffffffffffffffffffffffffffffff8416336102df6001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b7f02a52367d10742d8032712c1bb8e0144ff1ec5ffda1ed7d70bb05a27449550543487878760405161031494939291906107f2565b60405180910390a45050600180547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082168301167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b4761037c8161049a565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b60606103d57f00000000000000000000000000000000000000000000000000000000000000006104c9565b6103fe7f00000000000000000000000000000000000000000000000000000000000000006104c9565b6104277f00000000000000000000000000000000000000000000000000000000000000006104c9565b60405160200161043993929190610822565b604051602081830303815290604052905090565b80516020808301516040808501516060860151608087015160a0880151935160009761047d979096959101610898565b604051602081830303815290604052805190602001209050919050565b806040516104a790610606565b6040518091039082f09050801580156104c4573d6000803e3d6000fd5b505050565b60608160000361050c57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561053657806105208161091e565b915061052f9050600a83610985565b9150610510565b60008167ffffffffffffffff811115610551576105516106bf565b6040519080825280601f01601f19166020018201604052801561057b576020820181803683370190505b5090505b84156105fe57610590600183610999565b915061059d600a866109b0565b6105a89060306109c4565b60f81b8183815181106105bd576105bd6109dc565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506105f7600a86610985565b945061057f565b949350505050565b600880610a0c83390190565b60005b8381101561062d578181015183820152602001610615565b8381111561063c576000848401525b50505050565b6000815180845261065a816020860160208601610612565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061069f6020830184610642565b9392505050565b6000602082840312156106b857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561070357600080fd5b833573ffffffffffffffffffffffffffffffffffffffff8116811461072757600080fd5b925060208401359150604084013567ffffffffffffffff8082111561074b57600080fd5b818601915086601f83011261075f57600080fd5b813581811115610771576107716106bf565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156107b7576107b76106bf565b816040528281528960208487010111156107d057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b8481528360208201526080604082015260006108116080830185610642565b905082606083015295945050505050565b60008451610834818460208901610612565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610870816001850160208a01610612565b6001920191820152835161088b816002840160208801610612565b0160020195945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526108e360c0830184610642565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361094f5761094f6108ef565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261099457610994610956565b500490565b6000828210156109ab576109ab6108ef565b500390565b6000826109bf576109bf610956565b500690565b600082198211156109d7576109d76108ef565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe608060405230fffea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": {}, - "initiateWithdrawal(address,uint256,bytes)": { - "params": { - "_data": "Data to forward to L1 target.", - "_gasLimit": "Minimum gas limit for executing the message on L1.", - "_target": "Address to call on L1 execution." - } - }, - "messageNonce()": { - "returns": { - "_0": "Nonce of the next message to be sent, with added message version." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "events": { - "MessagePassed(uint256,address,address,uint256,uint256,bytes,bytes32)": { - "params": { - "data": "The data to be forwarded to the target on L1.", - "gasLimit": "The minimum amount of gas that must be provided when withdrawing.", - "nonce": "Unique value corresponding to each withdrawal.", - "sender": "The L2 account address which initiated the withdrawal.", - "target": "The L1 account address the call will be send to.", - "value": "The ETH value submitted for withdrawal, to be forwarded to the target.", - "withdrawalHash": "The hash of the withdrawal." - } - }, - "WithdrawerBalanceBurnt(uint256)": { - "params": { - "amount": "Amount of ETh that was burned." - } - } - }, - "title": "L2ToL1MessagePasser" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSAGE_VERSION()": { - "notice": "Current message version identifier." - }, - "burn()": { - "notice": "Removes all ETH held by this contract from the state. Used to prevent the amount of ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to create a contract and self-destruct it to itself. Anyone can call this function. Not incentivized since this function is very cheap." - }, - "initiateWithdrawal(address,uint256,bytes)": { - "notice": "Sends a message from L2 to L1." - }, - "messageNonce()": { - "notice": "Retrieves the next message nonce. Message version will be added to the upper two bytes of the message nonce. Message version allows us to treat messages as having different structures." - }, - "sentMessages(bytes32)": { - "notice": "Includes the message hashes for all withdrawals" - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "events": { - "MessagePassed(uint256,address,address,uint256,uint256,bytes,bytes32)": { - "notice": "Emitted any time a withdrawal is initiated." - }, - "WithdrawerBalanceBurnt(uint256)": { - "notice": "Emitted when the balance of this contract is burned." - } - }, - "notice": "The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from L2 to L1 can be stored. The storage root of this contract is pulled up to the top level of the L2 output to reduce the cost of proving the existence of sent messages." - }, - "storageLayout": { - "storage": [ - { - "astId": 3976, - "contract": "contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser", - "label": "sentMessages", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 3979, - "contract": "contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser", - "label": "msgNonce", - "offset": 0, - "slot": "1", - "type": "t_uint240" - } - ], - "types": { - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes32,t_bool)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_uint240": { - "encoding": "inplace", - "label": "uint240", - "numberOfBytes": "30" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/MintManager.json b/packages/contracts-bedrock/deployments/optimism-goerli/MintManager.json deleted file mode 100644 index d0dccf28d1aa..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/MintManager.json +++ /dev/null @@ -1,316 +0,0 @@ -{ - "address": "0x038a8825A3C3B0c08d52Cc76E5E361953Cf6Dc76", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_upgrader", - "type": "address" - }, - { - "internalType": "address", - "name": "_governanceToken", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "DENOMINATOR", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MINT_CAP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MINT_PERIOD", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "governanceToken", - "outputs": [ - { - "internalType": "contract GovernanceToken", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "mintPermittedAfter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_newMintManager", - "type": "address" - } - ], - "name": "upgrade", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0xef34b41d22d24351e6ff22ffc48345eb42218c6c6403c950724a98ded6427c89", - "receipt": { - "to": null, - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "contractAddress": "0x038a8825A3C3B0c08d52Cc76E5E361953Cf6Dc76", - "transactionIndex": 0, - "gasUsed": "880786", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000140000000000000000000000000100000000000000000000000001001000000000000000000000000000000000020000000000000000000800000000000000000000400000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x32d987eea82dca38607860e322e8e65da279102dd609137782217b7cc447d5cd", - "transactionHash": "0xef34b41d22d24351e6ff22ffc48345eb42218c6c6403c950724a98ded6427c89", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 1777450, - "transactionHash": "0xef34b41d22d24351e6ff22ffc48345eb42218c6c6403c950724a98ded6427c89", - "address": "0x038a8825A3C3B0c08d52Cc76E5E361953Cf6Dc76", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000018394b52d3cb931dfa76f63251919d051953413d" - ], - "data": "0x", - "logIndex": 0, - "blockHash": "0x32d987eea82dca38607860e322e8e65da279102dd609137782217b7cc447d5cd" - }, - { - "transactionIndex": 0, - "blockNumber": 1777450, - "transactionHash": "0xef34b41d22d24351e6ff22ffc48345eb42218c6c6403c950724a98ded6427c89", - "address": "0x038a8825A3C3B0c08d52Cc76E5E361953Cf6Dc76", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x00000000000000000000000018394b52d3cb931dfa76f63251919d051953413d", - "0x000000000000000000000000c30276833798867c1dbc5c468bf51ca900b44e4c" - ], - "data": "0x", - "logIndex": 1, - "blockHash": "0x32d987eea82dca38607860e322e8e65da279102dd609137782217b7cc447d5cd" - } - ], - "blockNumber": 1777450, - "cumulativeGasUsed": "880786", - "status": 1, - "byzantium": true - }, - "args": [ - "0xC30276833798867C1dBC5c468bf51cA900b44E4c", - "0x4200000000000000000000000000000000000042" - ], - "numDeployments": 1, - "solcInputHash": "b1df373a9ed51b3903b61f56faa9a78f", - "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_upgrader\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_governanceToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINT_CAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINT_PERIOD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governanceToken\",\"outputs\":[{\"internalType\":\"contract GovernanceToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mintPermittedAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMintManager\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_governanceToken\":\"The governance token this contract can mint tokens of\",\"_upgrader\":\"The owner of this contract\"}},\"mint(address,uint256)\":{\"params\":{\"_account\":\"Address to mint new tokens to.\",\"_amount\":\"Amount of tokens to be minted.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address)\":{\"params\":{\"_newMintManager\":\"The MintManager to upgrade to\"}}},\"title\":\"MintManager\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"DENOMINATOR()\":{\"notice\":\"The number of decimals for the MINT_CAP.\"},\"MINT_CAP()\":{\"notice\":\"The amount of tokens that can be minted per year. The value is a fixed point number with 4 decimals.\"},\"MINT_PERIOD()\":{\"notice\":\"The amount of time that must pass before the MINT_CAP number of tokens can be minted again.\"},\"governanceToken()\":{\"notice\":\"The GovernanceToken that the MintManager can mint tokens\"},\"mint(address,uint256)\":{\"notice\":\"Only the token owner is allowed to mint a certain amount of OP per year.\"},\"mintPermittedAfter()\":{\"notice\":\"Tracks the time of last mint\"},\"upgrade(address)\":{\"notice\":\"Upgrade the owner of the governance token to a new MintManager.\"}},\"notice\":\"Set as `owner` of the OP token and responsible for the token inflation schedule. Contract acts as the token \\\"mint manager\\\" with permission to the `mint` function only. Currently permitted to mint once per year of up to 2% of the total token supply. Upgradable to allow changes in the inflation schedule.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/MintManager.sol\":\"MintManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x24e0364e503a9bbde94c715d26573a76f14cd2a202d45f96f52134ab806b67b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"keccak256\":\"0xf5324a55ee9c0b4a840ea57c055ac9d046f88986ceef567e1cf68113e46a79c0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, _allowances[owner][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = _allowances[owner][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Spend `amount` form the allowance of `owner` toward `spender`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xdadd41acb749920eccf40aeaa8d291adf9751399a7343561bad13e7a8d99be0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0x0d19410453cda55960a818e02bd7c18952a5c8fe7a3036e81f0d599f34487a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"keccak256\":\"0x7fd2492be0468be4662081ee25cde38a31e4a0ceca0fed10160462389013910f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private immutable _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"keccak256\":\"0x8a763ef5625e97f5287c7ddd5ede434129069e15d83bf0a68ad10a5e56ccb439\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0xf0018c2440fbe238dd3a8732fa8e17a0f9dce84d31451dc8a32f6d62b349c9f1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x32c202bd28995dd20c4347b7c6467a6d3241c74c8ad3edcbb610cd9205916c45\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0x3c07f43e60e099b3b157243b3152722e73b80eeb7985c2cd73712828d7f7da29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"keccak256\":\"0x6688fad58b9ec0286d40fa957152e575d5d8bd4c3aa80985efdb11b44f776ae7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0xc995bddbca1ae19788db9f8b61e63385edd3fddf89693b612d5abd1a275974d2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits.\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits.\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x5c6caab697d302ad7eb59c234a4d2dbc965c1bae87709bd2850060b7695b28c7\",\"license\":\"MIT\"},\"contracts/GovernanceToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @dev The Optimism token used in governance and supporting voting and delegation.\\n * Implements EIP 2612 allowing signed approvals.\\n * Contract is \\\"owned\\\" by a `MintManager` instance with permission to the `mint` function only,\\n * for the purposes of enforcing the token inflation schedule.\\n */\\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\\n /**\\n * @dev Constructor.\\n */\\n constructor() ERC20(\\\"Optimism\\\", \\\"OP\\\") ERC20Permit(\\\"Optimism\\\") {}\\n\\n function mint(address _account, uint256 _amount) public onlyOwner {\\n _mint(_account, _amount);\\n }\\n\\n // The following functions are overrides required by Solidity.\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal override(ERC20, ERC20Votes) {\\n super._afterTokenTransfer(from, to, amount);\\n }\\n\\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\\n super._mint(to, amount);\\n }\\n\\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0x9686248fc10e71c30b05bc86a7b7749f12f74e5701c9d73b15ca9f75b9093839\",\"license\":\"MIT\"},\"contracts/MintManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"./GovernanceToken.sol\\\";\\n\\n/**\\n * @title MintManager\\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\\n * Contract acts as the token \\\"mint manager\\\" with permission to the `mint` function only.\\n * Currently permitted to mint once per year of up to 2% of the total token supply.\\n * Upgradable to allow changes in the inflation schedule.\\n */\\ncontract MintManager is Ownable {\\n /**\\n * @notice The GovernanceToken that the MintManager can mint tokens\\n */\\n GovernanceToken public immutable governanceToken;\\n\\n /**\\n * @notice The amount of tokens that can be minted per year. The value is a fixed\\n * point number with 4 decimals.\\n */\\n uint256 public constant MINT_CAP = 20; // 2%\\n\\n /**\\n * @notice The number of decimals for the MINT_CAP.\\n */\\n uint256 public constant DENOMINATOR = 1000;\\n\\n /**\\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\\n * be minted again.\\n */\\n uint256 public constant MINT_PERIOD = 365 days;\\n\\n /**\\n * @notice Tracks the time of last mint\\n */\\n uint256 public mintPermittedAfter;\\n\\n /**\\n * @param _upgrader The owner of this contract\\n * @param _governanceToken The governance token this contract can mint\\n * tokens of\\n */\\n constructor(address _upgrader, address _governanceToken) {\\n transferOwnership(_upgrader);\\n governanceToken = GovernanceToken(_governanceToken);\\n }\\n\\n /**\\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\\n *\\n * @param _account Address to mint new tokens to.\\n * @param _amount Amount of tokens to be minted.\\n */\\n function mint(address _account, uint256 _amount) public onlyOwner {\\n if (mintPermittedAfter > 0) {\\n require(mintPermittedAfter <= block.timestamp, \\\"OP: minting not permitted yet\\\");\\n\\n require(\\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\\n \\\"OP: mint amount exceeds cap\\\"\\n );\\n }\\n\\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\\n\\n governanceToken.mint(_account, _amount);\\n }\\n\\n /**\\n * @notice Upgrade the owner of the governance token to a new MintManager.\\n *\\n * @param _newMintManager The MintManager to upgrade to\\n */\\n function upgrade(address _newMintManager) public onlyOwner {\\n require(_newMintManager != address(0), \\\"OP: Mint manager cannot be empty\\\");\\n\\n governanceToken.transferOwnership(_newMintManager);\\n }\\n}\\n\",\"keccak256\":\"0x502e1e705839a9840823fe4c2eef2cf7f717b548c2259c6c5cf5e62753fbd940\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b50604051620012f1380380620012f1833981810160405281019062000037919062000319565b620000576200004b620000a460201b60201c565b620000ac60201b60201c565b62000068826200017060201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050506200047b565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b62000180620000a460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620001a66200028660201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614620001ff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001f690620003c1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141562000272576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002699062000459565b60405180910390fd5b6200028381620000ac60201b60201c565b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002e182620002b4565b9050919050565b620002f381620002d4565b8114620002ff57600080fd5b50565b6000815190506200031381620002e8565b92915050565b60008060408385031215620003335762000332620002af565b5b6000620003438582860162000302565b9250506020620003568582860162000302565b9150509250929050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000620003a960208362000360565b9150620003b68262000371565b602082019050919050565b60006020820190508181036000830152620003dc816200039a565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006200044160268362000360565b91506200044e82620003e3565b604082019050919050565b60006020820190508181036000830152620004748162000432565b9050919050565b608051610e45620004ac600039600081816102a8015281816104070152818161050301526107500152610e456000f3fe608060405234801561001057600080fd5b506004361061009d5760003560e01c80638da5cb5b116100665780638da5cb5b14610120578063918f86741461013e57806398f1312e1461015c578063f2fde38b1461017a578063f96dae0a146101965761009d565b8062f8900c146100a25780630900f010146100c057806340c10f19146100dc578063715018a6146100f857806383ea6e9714610102575b600080fd5b6100aa6101b4565b6040516100b79190610857565b60405180910390f35b6100da60048036038101906100d591906108d5565b6101ba565b005b6100f660048036038101906100f1919061092e565b610334565b005b610100610592565b005b61010a61061a565b6040516101179190610857565b60405180910390f35b610128610622565b604051610135919061097d565b60405180910390f35b61014661064b565b6040516101539190610857565b60405180910390f35b610164610651565b6040516101719190610857565b60405180910390f35b610194600480360381019061018f91906108d5565b610656565b005b61019e61074e565b6040516101ab91906109f7565b60405180910390f35b60015481565b6101c2610772565b73ffffffffffffffffffffffffffffffffffffffff166101e0610622565b73ffffffffffffffffffffffffffffffffffffffff1614610236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022d90610a6f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156102a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161029d90610adb565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b826040518263ffffffff1660e01b81526004016102ff919061097d565b600060405180830381600087803b15801561031957600080fd5b505af115801561032d573d6000803e3d6000fd5b5050505050565b61033c610772565b73ffffffffffffffffffffffffffffffffffffffff1661035a610622565b73ffffffffffffffffffffffffffffffffffffffff16146103b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a790610a6f565b60405180910390fd5b600060015411156104eb57426001541115610400576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f790610b47565b60405180910390fd5b6103e860147f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104949190610b7c565b61049e9190610bd8565b6104a89190610c61565b8111156104ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e190610cde565b60405180910390fd5b5b6301e13380426104fb9190610cfe565b6001819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b815260040161055c929190610d54565b600060405180830381600087803b15801561057657600080fd5b505af115801561058a573d6000803e3d6000fd5b505050505050565b61059a610772565b73ffffffffffffffffffffffffffffffffffffffff166105b8610622565b73ffffffffffffffffffffffffffffffffffffffff161461060e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060590610a6f565b60405180910390fd5b610618600061077a565b565b6301e1338081565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6103e881565b601481565b61065e610772565b73ffffffffffffffffffffffffffffffffffffffff1661067c610622565b73ffffffffffffffffffffffffffffffffffffffff16146106d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c990610a6f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610742576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073990610def565b60405180910390fd5b61074b8161077a565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000819050919050565b6108518161083e565b82525050565b600060208201905061086c6000830184610848565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006108a282610877565b9050919050565b6108b281610897565b81146108bd57600080fd5b50565b6000813590506108cf816108a9565b92915050565b6000602082840312156108eb576108ea610872565b5b60006108f9848285016108c0565b91505092915050565b61090b8161083e565b811461091657600080fd5b50565b60008135905061092881610902565b92915050565b6000806040838503121561094557610944610872565b5b6000610953858286016108c0565b925050602061096485828601610919565b9150509250929050565b61097781610897565b82525050565b6000602082019050610992600083018461096e565b92915050565b6000819050919050565b60006109bd6109b86109b384610877565b610998565b610877565b9050919050565b60006109cf826109a2565b9050919050565b60006109e1826109c4565b9050919050565b6109f1816109d6565b82525050565b6000602082019050610a0c60008301846109e8565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610a59602083610a12565b9150610a6482610a23565b602082019050919050565b60006020820190508181036000830152610a8881610a4c565b9050919050565b7f4f503a204d696e74206d616e616765722063616e6e6f7420626520656d707479600082015250565b6000610ac5602083610a12565b9150610ad082610a8f565b602082019050919050565b60006020820190508181036000830152610af481610ab8565b9050919050565b7f4f503a206d696e74696e67206e6f74207065726d697474656420796574000000600082015250565b6000610b31601d83610a12565b9150610b3c82610afb565b602082019050919050565b60006020820190508181036000830152610b6081610b24565b9050919050565b600081519050610b7681610902565b92915050565b600060208284031215610b9257610b91610872565b5b6000610ba084828501610b67565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610be38261083e565b9150610bee8361083e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610c2757610c26610ba9565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610c6c8261083e565b9150610c778361083e565b925082610c8757610c86610c32565b5b828204905092915050565b7f4f503a206d696e7420616d6f756e742065786365656473206361700000000000600082015250565b6000610cc8601b83610a12565b9150610cd382610c92565b602082019050919050565b60006020820190508181036000830152610cf781610cbb565b9050919050565b6000610d098261083e565b9150610d148361083e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610d4957610d48610ba9565b5b828201905092915050565b6000604082019050610d69600083018561096e565b610d766020830184610848565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610dd9602683610a12565b9150610de482610d7d565b604082019050919050565b60006020820190508181036000830152610e0881610dcc565b905091905056fea2646970667358221220d6ef0f15f2581f08c298ff8c67408d75a27f67742459525e88193c029a7a0bcf64736f6c634300080c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061009d5760003560e01c80638da5cb5b116100665780638da5cb5b14610120578063918f86741461013e57806398f1312e1461015c578063f2fde38b1461017a578063f96dae0a146101965761009d565b8062f8900c146100a25780630900f010146100c057806340c10f19146100dc578063715018a6146100f857806383ea6e9714610102575b600080fd5b6100aa6101b4565b6040516100b79190610857565b60405180910390f35b6100da60048036038101906100d591906108d5565b6101ba565b005b6100f660048036038101906100f1919061092e565b610334565b005b610100610592565b005b61010a61061a565b6040516101179190610857565b60405180910390f35b610128610622565b604051610135919061097d565b60405180910390f35b61014661064b565b6040516101539190610857565b60405180910390f35b610164610651565b6040516101719190610857565b60405180910390f35b610194600480360381019061018f91906108d5565b610656565b005b61019e61074e565b6040516101ab91906109f7565b60405180910390f35b60015481565b6101c2610772565b73ffffffffffffffffffffffffffffffffffffffff166101e0610622565b73ffffffffffffffffffffffffffffffffffffffff1614610236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022d90610a6f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156102a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161029d90610adb565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b826040518263ffffffff1660e01b81526004016102ff919061097d565b600060405180830381600087803b15801561031957600080fd5b505af115801561032d573d6000803e3d6000fd5b5050505050565b61033c610772565b73ffffffffffffffffffffffffffffffffffffffff1661035a610622565b73ffffffffffffffffffffffffffffffffffffffff16146103b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a790610a6f565b60405180910390fd5b600060015411156104eb57426001541115610400576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f790610b47565b60405180910390fd5b6103e860147f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104949190610b7c565b61049e9190610bd8565b6104a89190610c61565b8111156104ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e190610cde565b60405180910390fd5b5b6301e13380426104fb9190610cfe565b6001819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b815260040161055c929190610d54565b600060405180830381600087803b15801561057657600080fd5b505af115801561058a573d6000803e3d6000fd5b505050505050565b61059a610772565b73ffffffffffffffffffffffffffffffffffffffff166105b8610622565b73ffffffffffffffffffffffffffffffffffffffff161461060e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060590610a6f565b60405180910390fd5b610618600061077a565b565b6301e1338081565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6103e881565b601481565b61065e610772565b73ffffffffffffffffffffffffffffffffffffffff1661067c610622565b73ffffffffffffffffffffffffffffffffffffffff16146106d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c990610a6f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610742576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073990610def565b60405180910390fd5b61074b8161077a565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000819050919050565b6108518161083e565b82525050565b600060208201905061086c6000830184610848565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006108a282610877565b9050919050565b6108b281610897565b81146108bd57600080fd5b50565b6000813590506108cf816108a9565b92915050565b6000602082840312156108eb576108ea610872565b5b60006108f9848285016108c0565b91505092915050565b61090b8161083e565b811461091657600080fd5b50565b60008135905061092881610902565b92915050565b6000806040838503121561094557610944610872565b5b6000610953858286016108c0565b925050602061096485828601610919565b9150509250929050565b61097781610897565b82525050565b6000602082019050610992600083018461096e565b92915050565b6000819050919050565b60006109bd6109b86109b384610877565b610998565b610877565b9050919050565b60006109cf826109a2565b9050919050565b60006109e1826109c4565b9050919050565b6109f1816109d6565b82525050565b6000602082019050610a0c60008301846109e8565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610a59602083610a12565b9150610a6482610a23565b602082019050919050565b60006020820190508181036000830152610a8881610a4c565b9050919050565b7f4f503a204d696e74206d616e616765722063616e6e6f7420626520656d707479600082015250565b6000610ac5602083610a12565b9150610ad082610a8f565b602082019050919050565b60006020820190508181036000830152610af481610ab8565b9050919050565b7f4f503a206d696e74696e67206e6f74207065726d697474656420796574000000600082015250565b6000610b31601d83610a12565b9150610b3c82610afb565b602082019050919050565b60006020820190508181036000830152610b6081610b24565b9050919050565b600081519050610b7681610902565b92915050565b600060208284031215610b9257610b91610872565b5b6000610ba084828501610b67565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610be38261083e565b9150610bee8361083e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610c2757610c26610ba9565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610c6c8261083e565b9150610c778361083e565b925082610c8757610c86610c32565b5b828204905092915050565b7f4f503a206d696e7420616d6f756e742065786365656473206361700000000000600082015250565b6000610cc8601b83610a12565b9150610cd382610c92565b602082019050919050565b60006020820190508181036000830152610cf781610cbb565b9050919050565b6000610d098261083e565b9150610d148361083e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610d4957610d48610ba9565b5b828201905092915050565b6000604082019050610d69600083018561096e565b610d766020830184610848565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610dd9602683610a12565b9150610de482610d7d565b604082019050919050565b60006020820190508181036000830152610e0881610dcc565b905091905056fea2646970667358221220d6ef0f15f2581f08c298ff8c67408d75a27f67742459525e88193c029a7a0bcf64736f6c634300080c0033", - "devdoc": { - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_governanceToken": "The governance token this contract can mint tokens of", - "_upgrader": "The owner of this contract" - } - }, - "mint(address,uint256)": { - "params": { - "_account": "Address to mint new tokens to.", - "_amount": "Amount of tokens to be minted." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - }, - "upgrade(address)": { - "params": { - "_newMintManager": "The MintManager to upgrade to" - } - } - }, - "title": "MintManager", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "DENOMINATOR()": { - "notice": "The number of decimals for the MINT_CAP." - }, - "MINT_CAP()": { - "notice": "The amount of tokens that can be minted per year. The value is a fixed point number with 4 decimals." - }, - "MINT_PERIOD()": { - "notice": "The amount of time that must pass before the MINT_CAP number of tokens can be minted again." - }, - "governanceToken()": { - "notice": "The GovernanceToken that the MintManager can mint tokens" - }, - "mint(address,uint256)": { - "notice": "Only the token owner is allowed to mint a certain amount of OP per year." - }, - "mintPermittedAfter()": { - "notice": "Tracks the time of last mint" - }, - "upgrade(address)": { - "notice": "Upgrade the owner of the governance token to a new MintManager." - } - }, - "notice": "Set as `owner` of the OP token and responsible for the token inflation schedule. Contract acts as the token \"mint manager\" with permission to the `mint` function only. Currently permitted to mint once per year of up to 2% of the total token supply. Upgradable to allow changes in the inflation schedule.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 7, - "contract": "contracts/MintManager.sol:MintManager", - "label": "_owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 3573, - "contract": "contracts/MintManager.sol:MintManager", - "label": "mintPermittedAfter", - "offset": 0, - "slot": "1", - "type": "t_uint256" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/OptimismMintableERC20Factory.json b/packages/contracts-bedrock/deployments/optimism-goerli/OptimismMintableERC20Factory.json deleted file mode 100644 index 8238c4251e6e..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/OptimismMintableERC20Factory.json +++ /dev/null @@ -1,244 +0,0 @@ -{ - "address": "0x3F94732CFd48eE3597d7cEDfb853cfB2De31219c", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_bridge", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "deployer", - "type": "address" - } - ], - "name": "OptimismMintableERC20Created", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - } - ], - "name": "StandardL2TokenCreated", - "type": "event" - }, - { - "inputs": [], - "name": "BRIDGE", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createOptimismMintableERC20", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createStandardL2Token", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0xa03da13fa2f6f9ea224e2e19b5fb19c644203263f97e9de2f62d0be3796faa7a", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0x3F94732CFd48eE3597d7cEDfb853cfB2De31219c", - "transactionIndex": 1, - "gasUsed": "1995465", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x3763c5bec563a3cecde263b31267f532357d5ac67be40a557705dfe4254c6af6", - "transactionHash": "0xa03da13fa2f6f9ea224e2e19b5fb19c644203263f97e9de2f62d0be3796faa7a", - "logs": [], - "blockNumber": 8579707, - "cumulativeGasUsed": "2042366", - "status": 1, - "byzantium": true - }, - "args": [ - "0x4200000000000000000000000000000000000010" - ], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"}],\"name\":\"OptimismMintableERC20Created\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"StandardL2TokenCreated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createOptimismMintableERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createStandardL2Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"custom:proxied\":\"@custom:predeployed 0x4200000000000000000000000000000000000012\",\"events\":{\"OptimismMintableERC20Created(address,address,address)\":{\"params\":{\"deployer\":\"Address of the account that deployed the token.\",\"localToken\":\"Address of the created token on the local chain.\",\"remoteToken\":\"Address of the corresponding token on the remote chain.\"}},\"StandardL2TokenCreated(address,address)\":{\"custom:legacy\":\"@notice Emitted whenever a new OptimismMintableERC20 is created. Legacy version of the newer OptimismMintableERC20Created event. We recommend relying on that event instead.\",\"params\":{\"localToken\":\"Address of the created token on the local chain.\",\"remoteToken\":\"Address of the token on the remote chain.\"}}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.1.0\",\"params\":{\"_bridge\":\"Address of the StandardBridge on this chain.\"}},\"createOptimismMintableERC20(address,string,string)\":{\"params\":{\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"createStandardL2Token(address,string,string)\":{\"custom:legacy\":\"@notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the newer createOptimismMintableERC20 function, which has a more intuitive name.\",\"params\":{\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"OptimismMintableERC20Factory\",\"version\":1},\"userdoc\":{\"events\":{\"OptimismMintableERC20Created(address,address,address)\":{\"notice\":\"Emitted whenever a new OptimismMintableERC20 is created.\"}},\"kind\":\"user\",\"methods\":{\"BRIDGE()\":{\"notice\":\"Address of the StandardBridge on this chain.\"},\"constructor\":{\"notice\":\"The semver MUST be bumped any time that there is a change in the OptimismMintableERC20 token contract since this contract is responsible for deploying OptimismMintableERC20 contracts.\"},\"createOptimismMintableERC20(address,string,string)\":{\"notice\":\"Creates an instance of the OptimismMintableERC20 contract.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20 contracts on the network it's deployed to. Simplifies the deployment process for users who may be less familiar with deploying smart contracts. Designed to be backwards compatible with the older StandardL2ERC20Factory contract.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/OptimismMintableERC20Factory.sol\":\"OptimismMintableERC20Factory\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x2fea0ee05071c9c6b06a34a8e805801e247e861359b376a8918106e1d6f77ebe\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://198c91bda2edf864ddad1f8ab6168155d13d6ba5487418e5531ff040ff250686\",\"dweb:/ipfs/QmQzxfHY4P7zdVFRh2DTdGt1KeMHaGKNRf3KPZ1mRTYEGB\"]},\"contracts/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x302094342a45ebdf7f46f4fb48821960d2a4134f66fd7f458f73fc4ddf34d219\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b0e2b496e966ca6037e1c9be1d44417c0180fda2a27f68114e93b899defb783\",\"dweb:/ipfs/QmXP76ivMLxYxscC7B9E9qtW3u6HJ2MNaRVeo3x24VEAQH\"]},\"contracts/universal/OptimismMintableERC20Factory.sol\":{\"keccak256\":\"0x87fde59e9b0d43c415cb26d0cb13d7b1aab1f725750291dd257276efdf83774b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e76b70b637fd5d4daf121ba201dd3c85e5ca9763adf65f032c49753057d2c9af\",\"dweb:/ipfs/Qmf5SWFCS2TB1VM5BfGfb8EG84H8mdVwXe9A5jipgf4Lgr\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]}},\"version\":1}", - "bytecode": "0x61010060405234801561001157600080fd5b5060405161243538038061243583398101604081905261003091610050565b6001608081905260a052600060c0526001600160a01b031660e052610080565b60006020828403121561006257600080fd5b81516001600160a01b038116811461007957600080fd5b9392505050565b60805160a05160c05160e0516123776100be6000396000818160d3015261026501526000610153015260006101280152600060fd01526123776000f3fe60806040523480156200001157600080fd5b5060043610620000525760003560e01c806354fd4d501462000057578063896f93d11462000079578063ce5ac90f14620000b6578063ee9a31a214620000cd575b600080fd5b62000061620000f5565b60405162000070919062000550565b60405180910390f35b620000906200008a3660046200064e565b620001a0565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000070565b62000090620000c73660046200064e565b620001b7565b620000907f000000000000000000000000000000000000000000000000000000000000000081565b6060620001227f000000000000000000000000000000000000000000000000000000000000000062000376565b6200014d7f000000000000000000000000000000000000000000000000000000000000000062000376565b620001787f000000000000000000000000000000000000000000000000000000000000000062000376565b6040516020016200018c93929190620006e5565b604051602081830303815290604052905090565b6000620001af848484620001b7565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff841662000261576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e206164647265737300606482015260840160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008585856040516200029590620004c3565b620002a4949392919062000761565b604051809103906000f080158015620002c1573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80871691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a3949350505050565b606081600003620003ba57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115620003ea5780620003d181620007ea565b9150620003e29050600a8362000854565b9150620003be565b60008167ffffffffffffffff8111156200040857620004086200056c565b6040519080825280601f01601f19166020018201604052801562000433576020820181803683370190505b5090505b8415620001af576200044b6001836200086b565b91506200045a600a8662000885565b620004679060306200089c565b60f81b8183815181106200047f576200047f620008b7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350620004bb600a8662000854565b945062000437565b611a8480620008e783390190565b60005b83811015620004ee578181015183820152602001620004d4565b83811115620004fe576000848401525b50505050565b600081518084526200051e816020860160208601620004d1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000565602083018462000504565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112620005ad57600080fd5b813567ffffffffffffffff80821115620005cb57620005cb6200056c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156200061457620006146200056c565b816040528381528660208588010111156200062e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200066457600080fd5b833573ffffffffffffffffffffffffffffffffffffffff811681146200068957600080fd5b9250602084013567ffffffffffffffff80821115620006a757600080fd5b620006b5878388016200059b565b93506040860135915080821115620006cc57600080fd5b50620006db868287016200059b565b9150509250925092565b60008451620006f9818460208901620004d1565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855162000737816001850160208a01620004d1565b6001920191820152835162000754816002840160208801620004d1565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250608060408301526200079c608083018562000504565b8281036060840152620007b0818562000504565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036200081e576200081e620007bb565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008262000866576200086662000825565b500490565b600082821015620008805762000880620007bb565b500390565b60008262000897576200089762000825565b500690565b60008219821115620008b257620008b2620007bb565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe6101206040523480156200001257600080fd5b5060405162001a8438038062001a8483398101604081905262000035916200016d565b6001600080848460036200004a83826200028c565b5060046200005982826200028c565b50505060809290925260a05260c05250506001600160a01b0390811660e052166101005262000358565b80516001600160a01b03811681146200009b57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000c857600080fd5b81516001600160401b0380821115620000e557620000e5620000a0565b604051601f8301601f19908116603f01168101908282118183101715620001105762000110620000a0565b816040528381526020925086838588010111156200012d57600080fd5b600091505b8382101562000151578582018301518183018401529082019062000132565b83821115620001635760008385830101525b9695505050505050565b600080600080608085870312156200018457600080fd5b6200018f8562000083565b93506200019f6020860162000083565b60408601519093506001600160401b0380821115620001bd57600080fd5b620001cb88838901620000b6565b93506060870151915080821115620001e257600080fd5b50620001f187828801620000b6565b91505092959194509250565b600181811c908216806200021257607f821691505b6020821081036200023357634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200028757600081815260208120601f850160051c81016020861015620002625750805b601f850160051c820191505b8181101562000283578281556001016200026e565b5050505b505050565b81516001600160401b03811115620002a857620002a8620000a0565b620002c081620002b98454620001fd565b8462000239565b602080601f831160018114620002f85760008415620002df5750858301515b600019600386901b1c1916600185901b17855562000283565b600085815260208120601f198616915b82811015620003295788860151825594840194600190910190840162000308565b5085821015620003485787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e051610100516116cb620003b9600039600081816102f50152818161038a015281816105cf01526107a90152600081816101a9015261031b015260006107380152600061070f015260006106e601526116cb6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e1461033f578063e78cea92146102f3578063ee9a31a21461038557600080fd5b8063ae1f6aaf146102f3578063c01e1bd614610319578063d6c0b2c41461031957600080fd5b80639dc29fac116100bd5780639dc29fac146102ba578063a457c2d7146102cd578063a9059cbb146102e057600080fd5b806370a082311461027c57806395d89b41146102b257600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461024c57806340c10f191461025f57806354fd4d501461027457600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611307565b6103ac565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f861049d565b60405161019b919061137c565b61018f6102133660046113f6565b61052f565b6002545b60405190815260200161019b565b61018f610238366004611420565b610547565b6040516012815260200161019b565b61018f61025a3660046113f6565b61056b565b61027261026d3660046113f6565b6105b7565b005b6101f86106df565b61021c61028a36600461145c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610782565b6102726102c83660046113f6565b610791565b61018f6102db3660046113f6565b6108a8565b61018f6102ee3660046113f6565b610979565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61034d366004611477565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061046557507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b8061049457507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ac906114aa565b80601f01602080910402602001604051908101604052809291908181526020018280546104d8906114aa565b80156105255780601f106104fa57610100808354040283529160200191610525565b820191906000526020600020905b81548152906001019060200180831161050857829003601f168201915b5050505050905090565b60003361053d818585610987565b5060019392505050565b600033610555858285610b3b565b610560858585610c12565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061053d90829086906105b290879061152c565b610987565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b61068b8282610ec5565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106d391815260200190565b60405180910390a25050565b606061070a7f0000000000000000000000000000000000000000000000000000000000000000610fe5565b6107337f0000000000000000000000000000000000000000000000000000000000000000610fe5565b61075c7f0000000000000000000000000000000000000000000000000000000000000000610fe5565b60405160200161076e93929190611544565b604051602081830303815290604052905090565b6060600480546104ac906114aa565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e0000000000000000000000006064820152608401610678565b6108608282611122565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106d391815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561096c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610678565b6105608286868403610987565b60003361053d818585610c12565b73ffffffffffffffffffffffffffffffffffffffff8316610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff8216610acc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c0c5781811015610bff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610678565b610c0c8484848403610987565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff8216610d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e5290849061152c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eb891815260200190565b60405180910390a3610c0c565b73ffffffffffffffffffffffffffffffffffffffff8216610f42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610678565b8060026000828254610f54919061152c565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f8e90849061152c565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361102857505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611052578061103c816115ba565b915061104b9050600a83611621565b915061102c565b60008167ffffffffffffffff81111561106d5761106d611635565b6040519080825280601f01601f191660200182016040528015611097576020820181803683370190505b5090505b841561111a576110ac600183611664565b91506110b9600a8661167b565b6110c490603061152c565b60f81b8183815181106110d9576110d961168f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611113600a86611621565b945061109b565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561127b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112b7908490611664565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b2e565b60006020828403121561131957600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461134957600080fd5b9392505050565b60005b8381101561136b578181015183820152602001611353565b83811115610c0c5750506000910152565b602081526000825180602084015261139b816040850160208701611350565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146113f157600080fd5b919050565b6000806040838503121561140957600080fd5b611412836113cd565b946020939093013593505050565b60008060006060848603121561143557600080fd5b61143e846113cd565b925061144c602085016113cd565b9150604084013590509250925092565b60006020828403121561146e57600080fd5b611349826113cd565b6000806040838503121561148a57600080fd5b611493836113cd565b91506114a1602084016113cd565b90509250929050565b600181811c908216806114be57607f821691505b6020821081036114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561153f5761153f6114fd565b500190565b60008451611556818460208901611350565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611592816001850160208a01611350565b600192019182015283516115ad816002840160208801611350565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036115eb576115eb6114fd565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611630576116306115f2565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015611676576116766114fd565b500390565b60008261168a5761168a6115f2565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", - "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000525760003560e01c806354fd4d501462000057578063896f93d11462000079578063ce5ac90f14620000b6578063ee9a31a214620000cd575b600080fd5b62000061620000f5565b60405162000070919062000550565b60405180910390f35b620000906200008a3660046200064e565b620001a0565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000070565b62000090620000c73660046200064e565b620001b7565b620000907f000000000000000000000000000000000000000000000000000000000000000081565b6060620001227f000000000000000000000000000000000000000000000000000000000000000062000376565b6200014d7f000000000000000000000000000000000000000000000000000000000000000062000376565b620001787f000000000000000000000000000000000000000000000000000000000000000062000376565b6040516020016200018c93929190620006e5565b604051602081830303815290604052905090565b6000620001af848484620001b7565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff841662000261576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e206164647265737300606482015260840160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008585856040516200029590620004c3565b620002a4949392919062000761565b604051809103906000f080158015620002c1573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80871691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a3949350505050565b606081600003620003ba57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115620003ea5780620003d181620007ea565b9150620003e29050600a8362000854565b9150620003be565b60008167ffffffffffffffff8111156200040857620004086200056c565b6040519080825280601f01601f19166020018201604052801562000433576020820181803683370190505b5090505b8415620001af576200044b6001836200086b565b91506200045a600a8662000885565b620004679060306200089c565b60f81b8183815181106200047f576200047f620008b7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350620004bb600a8662000854565b945062000437565b611a8480620008e783390190565b60005b83811015620004ee578181015183820152602001620004d4565b83811115620004fe576000848401525b50505050565b600081518084526200051e816020860160208601620004d1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000565602083018462000504565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112620005ad57600080fd5b813567ffffffffffffffff80821115620005cb57620005cb6200056c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156200061457620006146200056c565b816040528381528660208588010111156200062e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200066457600080fd5b833573ffffffffffffffffffffffffffffffffffffffff811681146200068957600080fd5b9250602084013567ffffffffffffffff80821115620006a757600080fd5b620006b5878388016200059b565b93506040860135915080821115620006cc57600080fd5b50620006db868287016200059b565b9150509250925092565b60008451620006f9818460208901620004d1565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855162000737816001850160208a01620004d1565b6001920191820152835162000754816002840160208801620004d1565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250608060408301526200079c608083018562000504565b8281036060840152620007b0818562000504565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036200081e576200081e620007bb565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008262000866576200086662000825565b500490565b600082821015620008805762000880620007bb565b500390565b60008262000897576200089762000825565b500690565b60008219821115620008b257620008b2620007bb565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe6101206040523480156200001257600080fd5b5060405162001a8438038062001a8483398101604081905262000035916200016d565b6001600080848460036200004a83826200028c565b5060046200005982826200028c565b50505060809290925260a05260c05250506001600160a01b0390811660e052166101005262000358565b80516001600160a01b03811681146200009b57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000c857600080fd5b81516001600160401b0380821115620000e557620000e5620000a0565b604051601f8301601f19908116603f01168101908282118183101715620001105762000110620000a0565b816040528381526020925086838588010111156200012d57600080fd5b600091505b8382101562000151578582018301518183018401529082019062000132565b83821115620001635760008385830101525b9695505050505050565b600080600080608085870312156200018457600080fd5b6200018f8562000083565b93506200019f6020860162000083565b60408601519093506001600160401b0380821115620001bd57600080fd5b620001cb88838901620000b6565b93506060870151915080821115620001e257600080fd5b50620001f187828801620000b6565b91505092959194509250565b600181811c908216806200021257607f821691505b6020821081036200023357634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200028757600081815260208120601f850160051c81016020861015620002625750805b601f850160051c820191505b8181101562000283578281556001016200026e565b5050505b505050565b81516001600160401b03811115620002a857620002a8620000a0565b620002c081620002b98454620001fd565b8462000239565b602080601f831160018114620002f85760008415620002df5750858301515b600019600386901b1c1916600185901b17855562000283565b600085815260208120601f198616915b82811015620003295788860151825594840194600190910190840162000308565b5085821015620003485787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e051610100516116cb620003b9600039600081816102f50152818161038a015281816105cf01526107a90152600081816101a9015261031b015260006107380152600061070f015260006106e601526116cb6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e1461033f578063e78cea92146102f3578063ee9a31a21461038557600080fd5b8063ae1f6aaf146102f3578063c01e1bd614610319578063d6c0b2c41461031957600080fd5b80639dc29fac116100bd5780639dc29fac146102ba578063a457c2d7146102cd578063a9059cbb146102e057600080fd5b806370a082311461027c57806395d89b41146102b257600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461024c57806340c10f191461025f57806354fd4d501461027457600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611307565b6103ac565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f861049d565b60405161019b919061137c565b61018f6102133660046113f6565b61052f565b6002545b60405190815260200161019b565b61018f610238366004611420565b610547565b6040516012815260200161019b565b61018f61025a3660046113f6565b61056b565b61027261026d3660046113f6565b6105b7565b005b6101f86106df565b61021c61028a36600461145c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610782565b6102726102c83660046113f6565b610791565b61018f6102db3660046113f6565b6108a8565b61018f6102ee3660046113f6565b610979565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61034d366004611477565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061046557507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b8061049457507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ac906114aa565b80601f01602080910402602001604051908101604052809291908181526020018280546104d8906114aa565b80156105255780601f106104fa57610100808354040283529160200191610525565b820191906000526020600020905b81548152906001019060200180831161050857829003601f168201915b5050505050905090565b60003361053d818585610987565b5060019392505050565b600033610555858285610b3b565b610560858585610c12565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061053d90829086906105b290879061152c565b610987565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b61068b8282610ec5565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106d391815260200190565b60405180910390a25050565b606061070a7f0000000000000000000000000000000000000000000000000000000000000000610fe5565b6107337f0000000000000000000000000000000000000000000000000000000000000000610fe5565b61075c7f0000000000000000000000000000000000000000000000000000000000000000610fe5565b60405160200161076e93929190611544565b604051602081830303815290604052905090565b6060600480546104ac906114aa565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e0000000000000000000000006064820152608401610678565b6108608282611122565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106d391815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561096c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610678565b6105608286868403610987565b60003361053d818585610c12565b73ffffffffffffffffffffffffffffffffffffffff8316610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff8216610acc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c0c5781811015610bff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610678565b610c0c8484848403610987565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff8216610d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e5290849061152c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eb891815260200190565b60405180910390a3610c0c565b73ffffffffffffffffffffffffffffffffffffffff8216610f42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610678565b8060026000828254610f54919061152c565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f8e90849061152c565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361102857505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611052578061103c816115ba565b915061104b9050600a83611621565b915061102c565b60008167ffffffffffffffff81111561106d5761106d611635565b6040519080825280601f01601f191660200182016040528015611097576020820181803683370190505b5090505b841561111a576110ac600183611664565b91506110b9600a8661167b565b6110c490603061152c565b60f81b8183815181106110d9576110d961168f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611113600a86611621565b945061109b565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561127b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610678565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112b7908490611664565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b2e565b60006020828403121561131957600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461134957600080fd5b9392505050565b60005b8381101561136b578181015183820152602001611353565b83811115610c0c5750506000910152565b602081526000825180602084015261139b816040850160208701611350565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146113f157600080fd5b919050565b6000806040838503121561140957600080fd5b611412836113cd565b946020939093013593505050565b60008060006060848603121561143557600080fd5b61143e846113cd565b925061144c602085016113cd565b9150604084013590509250925092565b60006020828403121561146e57600080fd5b611349826113cd565b6000806040838503121561148a57600080fd5b611493836113cd565b91506114a1602084016113cd565b90509250929050565b600181811c908216806114be57607f821691505b6020821081036114f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561153f5761153f6114fd565b500190565b60008451611556818460208901611350565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611592816001850160208a01611350565b600192019182015283516115ad816002840160208801611350565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036115eb576115eb6114fd565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611630576116306115f2565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015611676576116766114fd565b500390565b60008261168a5761168a6115f2565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_bridge": "Address of the StandardBridge on this chain." - } - }, - "createOptimismMintableERC20(address,string,string)": { - "params": { - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "createStandardL2Token(address,string,string)": { - "params": { - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "events": { - "OptimismMintableERC20Created(address,address,address)": { - "params": { - "deployer": "Address of the account that deployed the token.", - "localToken": "Address of the created token on the local chain.", - "remoteToken": "Address of the corresponding token on the remote chain." - } - }, - "StandardL2TokenCreated(address,address)": { - "params": { - "localToken": "Address of the created token on the local chain.", - "remoteToken": "Address of the token on the remote chain." - } - } - }, - "title": "OptimismMintableERC20Factory" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "BRIDGE()": { - "notice": "Address of the StandardBridge on this chain." - }, - "constructor": { - "notice": "The semver MUST be bumped any time that there is a change in the OptimismMintableERC20 token contract since this contract is responsible for deploying OptimismMintableERC20 contracts." - }, - "createOptimismMintableERC20(address,string,string)": { - "notice": "Creates an instance of the OptimismMintableERC20 contract." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "events": { - "OptimismMintableERC20Created(address,address,address)": { - "notice": "Emitted whenever a new OptimismMintableERC20 is created." - } - }, - "notice": "OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20 contracts on the network it's deployed to. Simplifies the deployment process for users who may be less familiar with deploying smart contracts. Designed to be backwards compatible with the older StandardL2ERC20Factory contract." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/OptimismMintableERC721Factory.json b/packages/contracts-bedrock/deployments/optimism-goerli/OptimismMintableERC721Factory.json deleted file mode 100644 index db548aa72994..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/OptimismMintableERC721Factory.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "address": "0x13DcfC403eCEF3E8Eab66C00dC64e793dc40Be1d", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_bridge", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_remoteChainId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "deployer", - "type": "address" - } - ], - "name": "OptimismMintableERC721Created", - "type": "event" - }, - { - "inputs": [], - "name": "BRIDGE", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "REMOTE_CHAIN_ID", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createOptimismMintableERC721", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "isOptimismMintableERC721", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x66bd3795a6bef6b6ab0942e832c304d3bea5663d2ede9b5af06bffdc033619a3", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0x13DcfC403eCEF3E8Eab66C00dC64e793dc40Be1d", - "transactionIndex": 1, - "gasUsed": "3372345", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1d0825f07a8ddff70a90349d805448866f966283135060195e3dc0baed203f49", - "transactionHash": "0x66bd3795a6bef6b6ab0942e832c304d3bea5663d2ede9b5af06bffdc033619a3", - "logs": [], - "blockNumber": 8579713, - "cumulativeGasUsed": "3419258", - "status": 1, - "byzantium": true - }, - "args": [ - "0x4200000000000000000000000000000000000010", - "5" - ], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_remoteChainId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"}],\"name\":\"OptimismMintableERC721Created\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REMOTE_CHAIN_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createOptimismMintableERC721\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOptimismMintableERC721\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"OptimismMintableERC721Created(address,address,address)\":{\"params\":{\"deployer\":\"Address of the initiator of the deployment\",\"localToken\":\"Address of the token on the this domain.\",\"remoteToken\":\"Address of the token on the remote domain.\"}}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.2.0\",\"params\":{\"_bridge\":\"Address of the ERC721 bridge on this network.\",\"_remoteChainId\":\"Chain ID for the remote network.\"}},\"createOptimismMintableERC721(address,string,string)\":{\"params\":{\"_name\":\"ERC721 name.\",\"_remoteToken\":\"Address of the corresponding token on the other domain.\",\"_symbol\":\"ERC721 symbol.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"OptimismMintableERC721Factory\",\"version\":1},\"userdoc\":{\"events\":{\"OptimismMintableERC721Created(address,address,address)\":{\"notice\":\"Emitted whenever a new OptimismMintableERC721 contract is created.\"}},\"kind\":\"user\",\"methods\":{\"BRIDGE()\":{\"notice\":\"Address of the ERC721 bridge on this network.\"},\"REMOTE_CHAIN_ID()\":{\"notice\":\"Chain ID for the remote network.\"},\"constructor\":{\"notice\":\"The semver MUST be bumped any time that there is a change in the OptimismMintableERC721 token contract since this contract is responsible for deploying OptimismMintableERC721 contracts.\"},\"createOptimismMintableERC721(address,string,string)\":{\"notice\":\"Creates an instance of the standard ERC721.\"},\"isOptimismMintableERC721(address)\":{\"notice\":\"Tracks addresses created by this factory.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Factory contract for creating OptimismMintableERC721 contracts.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/OptimismMintableERC721Factory.sol\":\"OptimismMintableERC721Factory\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/universal/IOptimismMintableERC721.sol\":{\"keccak256\":\"0xf1a3dd4452df8882a65a31c5e2e8de7872b08cf078be7a5a7da51e6f75c53ad3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b09a2560cae35ca4789fe1ff5edb2bae9fa7dcda115a55f7ccdcc974a2e37526\",\"dweb:/ipfs/QmPQeTvrJ4SJpng5VGZNMf1u85NWxrdus4gGn8xYkHddKM\"]},\"contracts/universal/OptimismMintableERC721.sol\":{\"keccak256\":\"0xfafd77f2c45ef4295478335243b930fd19fffdc820ed424805f37f197915f03e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://05be10c5e73ec56376e90b73dc55a6a5f491a275a8e941a87db5671b40685665\",\"dweb:/ipfs/QmPnc4aFuRCJLVm3GuRfzxMyXxjBnoeRyzMsCz6nxQxrrB\"]},\"contracts/universal/OptimismMintableERC721Factory.sol\":{\"keccak256\":\"0x5dab871aef66fc09336f2f2c6bd0dbea17036bfa6ece27f10cb4a6241f95f561\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f230320a93cc2769fb0f738e367ed4d7b0eb9385d37eb783137e1a56d927ce08\",\"dweb:/ipfs/QmdaVF27BNxV7SFrE1QeVbFJd25tvVdHUVnUAreFoR4E8K\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"keccak256\":\"0x0b606994df12f0ce35f6d2f6dcdde7e55e6899cdef7e00f180980caa81e3844e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4c827c981a552d1c76c96060e92f56b52bc20c6f9b4dbf911fe99ddbfb41f2ea\",\"dweb:/ipfs/QmW8xvJdzHrr8Ry34C7viBsgG2b8T1mL4BQWJ5CdfD9JLB\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://20a97f891d06f0fe91560ea1a142aaa26fdd22bed1b51606b7d48f670deeb50f\",\"dweb:/ipfs/QmTbCtZKChpaX5H2iRiTDMcSz29GSLCpTCDgJpcMR4wg8x\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708\",\"dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"keccak256\":\"0x0a79511df8151b10b0a0004d6a76ad956582d32824af4c0f4886bdbdfe5746e5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://afbedcf17f31db719e6fdc56caa8f458799c5fa2eb94cb1e94ef18f89af85768\",\"dweb:/ipfs/QmVmqRdBfbgYThpZSoAJ5o9mnAMjx8mCHHjv3Rh8cQAAg3\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://26fef835622b46a5ba08b3ef6b46a22e94b5f285d0f0fb66b703bd30217d2c34\",\"dweb:/ipfs/QmZ548qdwfL1qF7aXz3xh1GCdTiST81kGGuKRqVUfYmPZR\"]},\"node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146\",\"dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d\",\"dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]}},\"version\":1}", - "bytecode": "0x61012060405234801561001157600080fd5b50604051613d6c380380613d6c83398101604081905261003091610056565b6001608052600260a052600060c0526001600160a01b0390911660e05261010052610090565b6000806040838503121561006957600080fd5b82516001600160a01b038116811461008057600080fd5b6020939093015192949293505050565b60805160a05160c05160e05161010051613c8b6100e16000396000818160d3015261030a01526000818161014701526102e9015260006101c70152600061019c015260006101710152613c8b6000f3fe60806040523480156200001157600080fd5b50600436106200006f5760003560e01c80637d1d0c5b11620000565780637d1d0c5b14620000cd578063d97df6521462000104578063ee9a31a2146200014157600080fd5b806354fd4d5014620000745780635572acae1462000096575b600080fd5b6200007e62000169565b6040516200008d9190620005dc565b60405180910390f35b620000bc620000a736600462000622565b60006020819052908152604090205460ff1681565b60405190151581526020016200008d565b620000f57f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016200008d565b6200011b6200011536600462000722565b62000214565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016200008d565b6200011b7f000000000000000000000000000000000000000000000000000000000000000081565b6060620001967f0000000000000000000000000000000000000000000000000000000000000000620003fa565b620001c17f0000000000000000000000000000000000000000000000000000000000000000620003fa565b620001ec7f0000000000000000000000000000000000000000000000000000000000000000620003fa565b60405160200162000200939291906200079f565b604051602081830303815290604052905090565b600073ffffffffffffffffffffffffffffffffffffffff8416620002e5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4f7074696d69736d4d696e7461626c65455243373231466163746f72793a204c908201527f3120746f6b656e20616464726573732063616e6e6f742062652061646472657360648201527f7328302900000000000000000000000000000000000000000000000000000000608482015260a40160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008686866040516200033a906200054f565b6200034a9594939291906200081b565b604051809103906000f08015801562000367573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff8181166000818152602081815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590513381529394509188169290917fe72783bb8e0ca31286b85278da59684dd814df9762a52f0837f89edd1483b299910160405180910390a3949350505050565b6060816000036200043e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156200046e57806200045581620008ab565b9150620004669050600a8362000915565b915062000442565b60008167ffffffffffffffff8111156200048c576200048c62000640565b6040519080825280601f01601f191660200182016040528015620004b7576020820181803683370190505b5090505b84156200054757620004cf6001836200092c565b9150620004de600a8662000946565b620004eb9060306200095d565b60f81b81838151811062000503576200050362000978565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506200053f600a8662000915565b9450620004bb565b949350505050565b6132d780620009a883390190565b60005b838110156200057a57818101518382015260200162000560565b838111156200058a576000848401525b50505050565b60008151808452620005aa8160208601602086016200055d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005f1602083018462000590565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061d57600080fd5b919050565b6000602082840312156200063557600080fd5b620005f182620005f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200068157600080fd5b813567ffffffffffffffff808211156200069f576200069f62000640565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006e857620006e862000640565b816040528381528660208588010111156200070257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200073857600080fd5b6200074384620005f8565b9250602084013567ffffffffffffffff808211156200076157600080fd5b6200076f878388016200066f565b935060408601359150808211156200078657600080fd5b5062000795868287016200066f565b9150509250925092565b60008451620007b38184602089016200055d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551620007f1816001850160208a016200055d565b600192019182015283516200080e8160028401602088016200055d565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835286602084015280861660408401525060a060608301526200085c60a083018562000590565b828103608084015262000870818562000590565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620008df57620008df6200087c565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082620009275762000927620008e6565b500490565b6000828210156200094157620009416200087c565b500390565b600082620009585762000958620008e6565b500690565b600082198211156200097357620009736200087c565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe6101406040523480156200001257600080fd5b50604051620032d7380380620032d7833981016040819052620000359162000640565b600180600084848262000049838262000769565b50600162000058828262000769565b50505060809290925260a05260c0526001600160a01b038516620000e95760405162461bcd60e51b815260206004820152603360248201527f4f7074696d69736d4d696e7461626c654552433732313a20627269646765206360448201527f616e6e6f7420626520616464726573732830290000000000000000000000000060648201526084015b60405180910390fd5b83600003620001615760405162461bcd60e51b815260206004820152603660248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465206360448201527f6861696e2069642063616e6e6f74206265207a65726f000000000000000000006064820152608401620000e0565b6001600160a01b038316620001df5760405162461bcd60e51b815260206004820152603960248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465207460448201527f6f6b656e2063616e6e6f742062652061646472657373283029000000000000006064820152608401620000e0565b60e08490526001600160a01b03838116610100819052908616610120526200021590601462000269602090811b62000f5c17901c565b6200022b856200042960201b6200119f1760201c565b6040516020016200023e92919062000835565b604051602081830303815290604052600a90816200025d919062000769565b505050505050620009a6565b606060006200027a836002620008bf565b62000287906002620008e1565b6001600160401b03811115620002a157620002a162000566565b6040519080825280601f01601f191660200182016040528015620002cc576020820181803683370190505b509050600360fc1b81600081518110620002ea57620002ea620008fc565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106200031c576200031c620008fc565b60200101906001600160f81b031916908160001a905350600062000342846002620008bf565b6200034f906001620008e1565b90505b6001811115620003d1576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110620003875762000387620008fc565b1a60f81b828281518110620003a057620003a0620008fc565b60200101906001600160f81b031916908160001a90535060049490941c93620003c98162000912565b905062000352565b508315620004225760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620000e0565b9392505050565b606081600003620004515750506040805180820190915260018152600360fc1b602082015290565b8160005b811562000481578062000468816200092c565b9150620004799050600a836200095e565b915062000455565b6000816001600160401b038111156200049e576200049e62000566565b6040519080825280601f01601f191660200182016040528015620004c9576020820181803683370190505b5090505b84156200054157620004e160018362000975565b9150620004f0600a866200098f565b620004fd906030620008e1565b60f81b818381518110620005155762000515620008fc565b60200101906001600160f81b031916908160001a90535062000539600a866200095e565b9450620004cd565b949350505050565b80516001600160a01b03811681146200056157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620005995781810151838201526020016200057f565b83811115620005a9576000848401525b50505050565b600082601f830112620005c157600080fd5b81516001600160401b0380821115620005de57620005de62000566565b604051601f8301601f19908116603f0116810190828211818310171562000609576200060962000566565b816040528381528660208588010111156200062357600080fd5b620006368460208301602089016200057c565b9695505050505050565b600080600080600060a086880312156200065957600080fd5b620006648662000549565b9450602086015193506200067b6040870162000549565b60608701519093506001600160401b03808211156200069957600080fd5b620006a789838a01620005af565b93506080880151915080821115620006be57600080fd5b50620006cd88828901620005af565b9150509295509295909350565b600181811c90821680620006ef57607f821691505b6020821081036200071057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200076457600081815260208120601f850160051c810160208610156200073f5750805b601f850160051c820191505b8181101562000760578281556001016200074b565b5050505b505050565b81516001600160401b0381111562000785576200078562000566565b6200079d81620007968454620006da565b8462000716565b602080601f831160018114620007d55760008415620007bc5750858301515b600019600386901b1c1916600185901b17855562000760565b600085815260208120601f198616915b828110156200080657888601518255948401946001909101908401620007e5565b5085821015620008255787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6832ba3432b932bab69d60b91b8152600083516200085b8160098501602088016200057c565b600160fe1b60099184019182015283516200087e81600a8401602088016200057c565b712f746f6b656e5552493f75696e743235363d60701b600a9290910191820152601c01949350505050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620008dc57620008dc620008a9565b500290565b60008219821115620008f757620008f7620008a9565b500190565b634e487b7160e01b600052603260045260246000fd5b600081620009245762000924620008a9565b506000190190565b600060018201620009415762000941620008a9565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008262000970576200097062000948565b500490565b6000828210156200098a576200098a620008a9565b500390565b600082620009a157620009a162000948565b500690565b60805160a05160c05160e05161010051610120516128be62000a19600039600081816103ae0152818161044601528181610b900152610cb20152600081816101e001526103880152600081816102f501526103d4015260006109bf015260006109960152600061096d01526128be6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80637d1d0c5b116100ee578063c87b56dd11610097578063e78cea9211610071578063e78cea92146103ac578063e9518196146103d2578063e985e9c5146103f8578063ee9a31a21461044157600080fd5b8063c87b56dd1461036b578063d547cfb71461037e578063d6c0b2c41461038657600080fd5b8063a1448194116100c8578063a144819414610332578063a22cb46514610345578063b88d4fde1461035857600080fd5b80637d1d0c5b146102f057806395d89b41146103175780639dc29fac1461031f57600080fd5b806323b872dd1161015b5780634f6ccce7116101355780634f6ccce7146102af57806354fd4d50146102c25780636352211e146102ca57806370a08231146102dd57600080fd5b806323b872dd146102765780632f745c591461028957806342842e0e1461029c57600080fd5b8063081812fc1161018c578063081812fc1461023c578063095ea7b31461024f57806318160ddd1461026457600080fd5b806301ffc9a7146101b3578063033964be146101db57806306fdde0314610227575b600080fd5b6101c66101c1366004612295565b610468565b60405190151581526020015b60405180910390f35b6102027f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b61022f6104c6565b6040516101d29190612328565b61020261024a36600461233b565b610558565b61026261025d36600461237d565b61058c565b005b6008545b6040519081526020016101d2565b6102626102843660046123a7565b61071d565b61026861029736600461237d565b6107be565b6102626102aa3660046123a7565b61088d565b6102686102bd36600461233b565b6108a8565b61022f610966565b6102026102d836600461233b565b610a09565b6102686102eb3660046123e3565b610a9b565b6102687f000000000000000000000000000000000000000000000000000000000000000081565b61022f610b69565b61026261032d36600461237d565b610b78565b61026261034036600461237d565b610c9a565b6102626103533660046123fe565b610db1565b610262610366366004612469565b610dc0565b61022f61037936600461233b565b610e68565b61022f610ece565b7f0000000000000000000000000000000000000000000000000000000000000000610202565b7f0000000000000000000000000000000000000000000000000000000000000000610202565b7f0000000000000000000000000000000000000000000000000000000000000000610268565b6101c6610406366004612563565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b6102027f000000000000000000000000000000000000000000000000000000000000000081565b60007f74259ebf000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083168114806104bf57506104bf836112dc565b9392505050565b6060600080546104d590612596565b80601f016020809104026020016040519081016040528092919081815260200182805461050190612596565b801561054e5780601f106105235761010080835404028352916020019161054e565b820191906000526020600020905b81548152906001019060200180831161053157829003601f168201915b5050505050905090565b600061056382611332565b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b600061059782610a09565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610659576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff8216148061068257506106828133610406565b61070e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610650565b61071883836113c0565b505050565b6107273382611460565b6107b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610650565b61071883838361151f565b60006107c983610a9b565b8210610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610650565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b61071883838360405180602001604052806000815250610dc0565b60006108b360085490565b8210610941576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610650565b60088281548110610954576109546125e9565b90600052602060002001549050919050565b60606109917f000000000000000000000000000000000000000000000000000000000000000061119f565b6109ba7f000000000000000000000000000000000000000000000000000000000000000061119f565b6109e37f000000000000000000000000000000000000000000000000000000000000000061119f565b6040516020016109f593929190612618565b604051602081830303815290604052905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610a95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610650565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff8216610b40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152608401610650565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b6060600180546104d590612596565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e0000000000006064820152608401610650565b610c4681611791565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca582604051610c8e91815260200190565b60405180910390a25050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e0000000000006064820152608401610650565b610d69828261186a565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610c8e91815260200190565b610dbc338383611884565b5050565b610dca3383611460565b610e56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610650565b610e62848484846119b1565b50505050565b6060610e7382611332565b6000610e7d611a54565b90506000815111610e9d57604051806020016040528060008152506104bf565b80610ea78461119f565b604051602001610eb892919061268e565b6040516020818303038152906040529392505050565b600a8054610edb90612596565b80601f0160208091040260200160405190810160405280929190818152602001828054610f0790612596565b8015610f545780601f10610f2957610100808354040283529160200191610f54565b820191906000526020600020905b815481529060010190602001808311610f3757829003601f168201915b505050505081565b60606000610f6b8360026126ec565b610f76906002612729565b67ffffffffffffffff811115610f8e57610f8e61243a565b6040519080825280601f01601f191660200182016040528015610fb8576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110610fef57610fef6125e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611052576110526125e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061108e8460026126ec565b611099906001612729565b90505b6001811115611136577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106110da576110da6125e9565b1a60f81b8282815181106110f0576110f06125e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361112f81612741565b905061109c565b5083156104bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610650565b6060816000036111e257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561120c57806111f681612776565b91506112059050600a836127dd565b91506111e6565b60008167ffffffffffffffff8111156112275761122761243a565b6040519080825280601f01601f191660200182016040528015611251576020820181803683370190505b5090505b84156112d4576112666001836127f1565b9150611273600a86612808565b61127e906030612729565b60f81b818381518110611293576112936125e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506112cd600a866127dd565b9450611255565b949350505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610a955750610a9582611a63565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff166113bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610650565b50565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061141a82610a09565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061146c83610a09565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806114da575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b806112d457508373ffffffffffffffffffffffffffffffffffffffff1661150084610558565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b8273ffffffffffffffffffffffffffffffffffffffff1661153f82610a09565b73ffffffffffffffffffffffffffffffffffffffff16146115e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610650565b73ffffffffffffffffffffffffffffffffffffffff8216611684576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610650565b61168f838383611b46565b61169a6000826113c0565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054600192906116d09084906127f1565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040812080546001929061170b908490612729565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061179c82610a09565b90506117aa81600084611b46565b6117b56000836113c0565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054600192906117eb9084906127f1565b909155505060008281526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b610dbc828260405180602001604052806000815250611c4c565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610650565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6119bc84848461151f565b6119c884848484611cef565b610e62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610650565b6060600a80546104d590612596565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480611af657507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610a9557507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610a95565b73ffffffffffffffffffffffffffffffffffffffff8316611bae57611ba981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611beb565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611beb57611beb8382611ee2565b73ffffffffffffffffffffffffffffffffffffffff8216611c0f5761071881611f99565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610718576107188282612048565b611c568383612099565b611c636000848484611cef565b610718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610650565b600073ffffffffffffffffffffffffffffffffffffffff84163b15611ed7576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290611d6690339089908890889060040161281c565b6020604051808303816000875af1925050508015611dbf575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611dbc91810190612865565b60015b611e8c573d808015611ded576040519150601f19603f3d011682016040523d82523d6000602084013e611df2565b606091505b508051600003611e84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610650565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506112d4565b506001949350505050565b60006001611eef84610a9b565b611ef991906127f1565b600083815260076020526040902054909150808214611f595773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b600854600090611fab906001906127f1565b60008381526009602052604081205460088054939450909284908110611fd357611fd36125e9565b906000526020600020015490508060088381548110611ff457611ff46125e9565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061202c5761202c612882565b6001900381819060005260206000200160009055905550505050565b600061205383610a9b565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b73ffffffffffffffffffffffffffffffffffffffff8216612116576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610650565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156121a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610650565b6121ae60008383611b46565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906121e4908490612729565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146113bd57600080fd5b6000602082840312156122a757600080fd5b81356104bf81612267565b60005b838110156122cd5781810151838201526020016122b5565b83811115610e625750506000910152565b600081518084526122f68160208601602086016122b2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104bf60208301846122de565b60006020828403121561234d57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461237857600080fd5b919050565b6000806040838503121561239057600080fd5b61239983612354565b946020939093013593505050565b6000806000606084860312156123bc57600080fd5b6123c584612354565b92506123d360208501612354565b9150604084013590509250925092565b6000602082840312156123f557600080fd5b6104bf82612354565b6000806040838503121561241157600080fd5b61241a83612354565b91506020830135801515811461242f57600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561247f57600080fd5b61248885612354565b935061249660208601612354565b925060408501359150606085013567ffffffffffffffff808211156124ba57600080fd5b818701915087601f8301126124ce57600080fd5b8135818111156124e0576124e061243a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156125265761252661243a565b816040528281528a602084870101111561253f57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561257657600080fd5b61257f83612354565b915061258d60208401612354565b90509250929050565b600181811c908216806125aa57607f821691505b6020821081036125e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000845161262a8184602089016122b2565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612666816001850160208a016122b2565b600192019182015283516126818160028401602088016122b2565b0160020195945050505050565b600083516126a08184602088016122b2565b8351908301906126b48183602088016122b2565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612724576127246126bd565b500290565b6000821982111561273c5761273c6126bd565b500190565b600081612750576127506126bd565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036127a7576127a76126bd565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826127ec576127ec6127ae565b500490565b600082821015612803576128036126bd565b500390565b600082612817576128176127ae565b500690565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261285b60808301846122de565b9695505050505050565b60006020828403121561287757600080fd5b81516104bf81612267565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", - "deployedBytecode": "0x60806040523480156200001157600080fd5b50600436106200006f5760003560e01c80637d1d0c5b11620000565780637d1d0c5b14620000cd578063d97df6521462000104578063ee9a31a2146200014157600080fd5b806354fd4d5014620000745780635572acae1462000096575b600080fd5b6200007e62000169565b6040516200008d9190620005dc565b60405180910390f35b620000bc620000a736600462000622565b60006020819052908152604090205460ff1681565b60405190151581526020016200008d565b620000f57f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016200008d565b6200011b6200011536600462000722565b62000214565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016200008d565b6200011b7f000000000000000000000000000000000000000000000000000000000000000081565b6060620001967f0000000000000000000000000000000000000000000000000000000000000000620003fa565b620001c17f0000000000000000000000000000000000000000000000000000000000000000620003fa565b620001ec7f0000000000000000000000000000000000000000000000000000000000000000620003fa565b60405160200162000200939291906200079f565b604051602081830303815290604052905090565b600073ffffffffffffffffffffffffffffffffffffffff8416620002e5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4f7074696d69736d4d696e7461626c65455243373231466163746f72793a204c908201527f3120746f6b656e20616464726573732063616e6e6f742062652061646472657360648201527f7328302900000000000000000000000000000000000000000000000000000000608482015260a40160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008686866040516200033a906200054f565b6200034a9594939291906200081b565b604051809103906000f08015801562000367573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff8181166000818152602081815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590513381529394509188169290917fe72783bb8e0ca31286b85278da59684dd814df9762a52f0837f89edd1483b299910160405180910390a3949350505050565b6060816000036200043e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156200046e57806200045581620008ab565b9150620004669050600a8362000915565b915062000442565b60008167ffffffffffffffff8111156200048c576200048c62000640565b6040519080825280601f01601f191660200182016040528015620004b7576020820181803683370190505b5090505b84156200054757620004cf6001836200092c565b9150620004de600a8662000946565b620004eb9060306200095d565b60f81b81838151811062000503576200050362000978565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506200053f600a8662000915565b9450620004bb565b949350505050565b6132d780620009a883390190565b60005b838110156200057a57818101518382015260200162000560565b838111156200058a576000848401525b50505050565b60008151808452620005aa8160208601602086016200055d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005f1602083018462000590565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061d57600080fd5b919050565b6000602082840312156200063557600080fd5b620005f182620005f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200068157600080fd5b813567ffffffffffffffff808211156200069f576200069f62000640565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006e857620006e862000640565b816040528381528660208588010111156200070257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200073857600080fd5b6200074384620005f8565b9250602084013567ffffffffffffffff808211156200076157600080fd5b6200076f878388016200066f565b935060408601359150808211156200078657600080fd5b5062000795868287016200066f565b9150509250925092565b60008451620007b38184602089016200055d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551620007f1816001850160208a016200055d565b600192019182015283516200080e8160028401602088016200055d565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835286602084015280861660408401525060a060608301526200085c60a083018562000590565b828103608084015262000870818562000590565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620008df57620008df6200087c565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082620009275762000927620008e6565b500490565b6000828210156200094157620009416200087c565b500390565b600082620009585762000958620008e6565b500690565b600082198211156200097357620009736200087c565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe6101406040523480156200001257600080fd5b50604051620032d7380380620032d7833981016040819052620000359162000640565b600180600084848262000049838262000769565b50600162000058828262000769565b50505060809290925260a05260c0526001600160a01b038516620000e95760405162461bcd60e51b815260206004820152603360248201527f4f7074696d69736d4d696e7461626c654552433732313a20627269646765206360448201527f616e6e6f7420626520616464726573732830290000000000000000000000000060648201526084015b60405180910390fd5b83600003620001615760405162461bcd60e51b815260206004820152603660248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465206360448201527f6861696e2069642063616e6e6f74206265207a65726f000000000000000000006064820152608401620000e0565b6001600160a01b038316620001df5760405162461bcd60e51b815260206004820152603960248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465207460448201527f6f6b656e2063616e6e6f742062652061646472657373283029000000000000006064820152608401620000e0565b60e08490526001600160a01b03838116610100819052908616610120526200021590601462000269602090811b62000f5c17901c565b6200022b856200042960201b6200119f1760201c565b6040516020016200023e92919062000835565b604051602081830303815290604052600a90816200025d919062000769565b505050505050620009a6565b606060006200027a836002620008bf565b62000287906002620008e1565b6001600160401b03811115620002a157620002a162000566565b6040519080825280601f01601f191660200182016040528015620002cc576020820181803683370190505b509050600360fc1b81600081518110620002ea57620002ea620008fc565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106200031c576200031c620008fc565b60200101906001600160f81b031916908160001a905350600062000342846002620008bf565b6200034f906001620008e1565b90505b6001811115620003d1576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110620003875762000387620008fc565b1a60f81b828281518110620003a057620003a0620008fc565b60200101906001600160f81b031916908160001a90535060049490941c93620003c98162000912565b905062000352565b508315620004225760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620000e0565b9392505050565b606081600003620004515750506040805180820190915260018152600360fc1b602082015290565b8160005b811562000481578062000468816200092c565b9150620004799050600a836200095e565b915062000455565b6000816001600160401b038111156200049e576200049e62000566565b6040519080825280601f01601f191660200182016040528015620004c9576020820181803683370190505b5090505b84156200054157620004e160018362000975565b9150620004f0600a866200098f565b620004fd906030620008e1565b60f81b818381518110620005155762000515620008fc565b60200101906001600160f81b031916908160001a90535062000539600a866200095e565b9450620004cd565b949350505050565b80516001600160a01b03811681146200056157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620005995781810151838201526020016200057f565b83811115620005a9576000848401525b50505050565b600082601f830112620005c157600080fd5b81516001600160401b0380821115620005de57620005de62000566565b604051601f8301601f19908116603f0116810190828211818310171562000609576200060962000566565b816040528381528660208588010111156200062357600080fd5b620006368460208301602089016200057c565b9695505050505050565b600080600080600060a086880312156200065957600080fd5b620006648662000549565b9450602086015193506200067b6040870162000549565b60608701519093506001600160401b03808211156200069957600080fd5b620006a789838a01620005af565b93506080880151915080821115620006be57600080fd5b50620006cd88828901620005af565b9150509295509295909350565b600181811c90821680620006ef57607f821691505b6020821081036200071057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200076457600081815260208120601f850160051c810160208610156200073f5750805b601f850160051c820191505b8181101562000760578281556001016200074b565b5050505b505050565b81516001600160401b0381111562000785576200078562000566565b6200079d81620007968454620006da565b8462000716565b602080601f831160018114620007d55760008415620007bc5750858301515b600019600386901b1c1916600185901b17855562000760565b600085815260208120601f198616915b828110156200080657888601518255948401946001909101908401620007e5565b5085821015620008255787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6832ba3432b932bab69d60b91b8152600083516200085b8160098501602088016200057c565b600160fe1b60099184019182015283516200087e81600a8401602088016200057c565b712f746f6b656e5552493f75696e743235363d60701b600a9290910191820152601c01949350505050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620008dc57620008dc620008a9565b500290565b60008219821115620008f757620008f7620008a9565b500190565b634e487b7160e01b600052603260045260246000fd5b600081620009245762000924620008a9565b506000190190565b600060018201620009415762000941620008a9565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008262000970576200097062000948565b500490565b6000828210156200098a576200098a620008a9565b500390565b600082620009a157620009a162000948565b500690565b60805160a05160c05160e05161010051610120516128be62000a19600039600081816103ae0152818161044601528181610b900152610cb20152600081816101e001526103880152600081816102f501526103d4015260006109bf015260006109960152600061096d01526128be6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80637d1d0c5b116100ee578063c87b56dd11610097578063e78cea9211610071578063e78cea92146103ac578063e9518196146103d2578063e985e9c5146103f8578063ee9a31a21461044157600080fd5b8063c87b56dd1461036b578063d547cfb71461037e578063d6c0b2c41461038657600080fd5b8063a1448194116100c8578063a144819414610332578063a22cb46514610345578063b88d4fde1461035857600080fd5b80637d1d0c5b146102f057806395d89b41146103175780639dc29fac1461031f57600080fd5b806323b872dd1161015b5780634f6ccce7116101355780634f6ccce7146102af57806354fd4d50146102c25780636352211e146102ca57806370a08231146102dd57600080fd5b806323b872dd146102765780632f745c591461028957806342842e0e1461029c57600080fd5b8063081812fc1161018c578063081812fc1461023c578063095ea7b31461024f57806318160ddd1461026457600080fd5b806301ffc9a7146101b3578063033964be146101db57806306fdde0314610227575b600080fd5b6101c66101c1366004612295565b610468565b60405190151581526020015b60405180910390f35b6102027f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b61022f6104c6565b6040516101d29190612328565b61020261024a36600461233b565b610558565b61026261025d36600461237d565b61058c565b005b6008545b6040519081526020016101d2565b6102626102843660046123a7565b61071d565b61026861029736600461237d565b6107be565b6102626102aa3660046123a7565b61088d565b6102686102bd36600461233b565b6108a8565b61022f610966565b6102026102d836600461233b565b610a09565b6102686102eb3660046123e3565b610a9b565b6102687f000000000000000000000000000000000000000000000000000000000000000081565b61022f610b69565b61026261032d36600461237d565b610b78565b61026261034036600461237d565b610c9a565b6102626103533660046123fe565b610db1565b610262610366366004612469565b610dc0565b61022f61037936600461233b565b610e68565b61022f610ece565b7f0000000000000000000000000000000000000000000000000000000000000000610202565b7f0000000000000000000000000000000000000000000000000000000000000000610202565b7f0000000000000000000000000000000000000000000000000000000000000000610268565b6101c6610406366004612563565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b6102027f000000000000000000000000000000000000000000000000000000000000000081565b60007f74259ebf000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083168114806104bf57506104bf836112dc565b9392505050565b6060600080546104d590612596565b80601f016020809104026020016040519081016040528092919081815260200182805461050190612596565b801561054e5780601f106105235761010080835404028352916020019161054e565b820191906000526020600020905b81548152906001019060200180831161053157829003601f168201915b5050505050905090565b600061056382611332565b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b600061059782610a09565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610659576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff8216148061068257506106828133610406565b61070e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610650565b61071883836113c0565b505050565b6107273382611460565b6107b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610650565b61071883838361151f565b60006107c983610a9b565b8210610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610650565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b61071883838360405180602001604052806000815250610dc0565b60006108b360085490565b8210610941576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610650565b60088281548110610954576109546125e9565b90600052602060002001549050919050565b60606109917f000000000000000000000000000000000000000000000000000000000000000061119f565b6109ba7f000000000000000000000000000000000000000000000000000000000000000061119f565b6109e37f000000000000000000000000000000000000000000000000000000000000000061119f565b6040516020016109f593929190612618565b604051602081830303815290604052905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610a95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610650565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff8216610b40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152608401610650565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b6060600180546104d590612596565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e0000000000006064820152608401610650565b610c4681611791565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca582604051610c8e91815260200190565b60405180910390a25050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e0000000000006064820152608401610650565b610d69828261186a565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610c8e91815260200190565b610dbc338383611884565b5050565b610dca3383611460565b610e56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610650565b610e62848484846119b1565b50505050565b6060610e7382611332565b6000610e7d611a54565b90506000815111610e9d57604051806020016040528060008152506104bf565b80610ea78461119f565b604051602001610eb892919061268e565b6040516020818303038152906040529392505050565b600a8054610edb90612596565b80601f0160208091040260200160405190810160405280929190818152602001828054610f0790612596565b8015610f545780601f10610f2957610100808354040283529160200191610f54565b820191906000526020600020905b815481529060010190602001808311610f3757829003601f168201915b505050505081565b60606000610f6b8360026126ec565b610f76906002612729565b67ffffffffffffffff811115610f8e57610f8e61243a565b6040519080825280601f01601f191660200182016040528015610fb8576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110610fef57610fef6125e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611052576110526125e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061108e8460026126ec565b611099906001612729565b90505b6001811115611136577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106110da576110da6125e9565b1a60f81b8282815181106110f0576110f06125e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361112f81612741565b905061109c565b5083156104bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610650565b6060816000036111e257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561120c57806111f681612776565b91506112059050600a836127dd565b91506111e6565b60008167ffffffffffffffff8111156112275761122761243a565b6040519080825280601f01601f191660200182016040528015611251576020820181803683370190505b5090505b84156112d4576112666001836127f1565b9150611273600a86612808565b61127e906030612729565b60f81b818381518110611293576112936125e9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506112cd600a866127dd565b9450611255565b949350505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610a955750610a9582611a63565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff166113bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610650565b50565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061141a82610a09565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061146c83610a09565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806114da575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b806112d457508373ffffffffffffffffffffffffffffffffffffffff1661150084610558565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b8273ffffffffffffffffffffffffffffffffffffffff1661153f82610a09565b73ffffffffffffffffffffffffffffffffffffffff16146115e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610650565b73ffffffffffffffffffffffffffffffffffffffff8216611684576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610650565b61168f838383611b46565b61169a6000826113c0565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054600192906116d09084906127f1565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040812080546001929061170b908490612729565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061179c82610a09565b90506117aa81600084611b46565b6117b56000836113c0565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604081208054600192906117eb9084906127f1565b909155505060008281526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b610dbc828260405180602001604052806000815250611c4c565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610650565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6119bc84848461151f565b6119c884848484611cef565b610e62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610650565b6060600a80546104d590612596565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480611af657507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610a9557507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610a95565b73ffffffffffffffffffffffffffffffffffffffff8316611bae57611ba981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611beb565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611beb57611beb8382611ee2565b73ffffffffffffffffffffffffffffffffffffffff8216611c0f5761071881611f99565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610718576107188282612048565b611c568383612099565b611c636000848484611cef565b610718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610650565b600073ffffffffffffffffffffffffffffffffffffffff84163b15611ed7576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290611d6690339089908890889060040161281c565b6020604051808303816000875af1925050508015611dbf575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611dbc91810190612865565b60015b611e8c573d808015611ded576040519150601f19603f3d011682016040523d82523d6000602084013e611df2565b606091505b508051600003611e84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610650565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506112d4565b506001949350505050565b60006001611eef84610a9b565b611ef991906127f1565b600083815260076020526040902054909150808214611f595773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b600854600090611fab906001906127f1565b60008381526009602052604081205460088054939450909284908110611fd357611fd36125e9565b906000526020600020015490508060088381548110611ff457611ff46125e9565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061202c5761202c612882565b6001900381819060005260206000200160009055905550505050565b600061205383610a9b565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b73ffffffffffffffffffffffffffffffffffffffff8216612116576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610650565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156121a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610650565b6121ae60008383611b46565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906121e4908490612729565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146113bd57600080fd5b6000602082840312156122a757600080fd5b81356104bf81612267565b60005b838110156122cd5781810151838201526020016122b5565b83811115610e625750506000910152565b600081518084526122f68160208601602086016122b2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104bf60208301846122de565b60006020828403121561234d57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461237857600080fd5b919050565b6000806040838503121561239057600080fd5b61239983612354565b946020939093013593505050565b6000806000606084860312156123bc57600080fd5b6123c584612354565b92506123d360208501612354565b9150604084013590509250925092565b6000602082840312156123f557600080fd5b6104bf82612354565b6000806040838503121561241157600080fd5b61241a83612354565b91506020830135801515811461242f57600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561247f57600080fd5b61248885612354565b935061249660208601612354565b925060408501359150606085013567ffffffffffffffff808211156124ba57600080fd5b818701915087601f8301126124ce57600080fd5b8135818111156124e0576124e061243a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156125265761252661243a565b816040528281528a602084870101111561253f57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561257657600080fd5b61257f83612354565b915061258d60208401612354565b90509250929050565b600181811c908216806125aa57607f821691505b6020821081036125e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000845161262a8184602089016122b2565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612666816001850160208a016122b2565b600192019182015283516126818160028401602088016122b2565b0160020195945050505050565b600083516126a08184602088016122b2565b8351908301906126b48183602088016122b2565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612724576127246126bd565b500290565b6000821982111561273c5761273c6126bd565b500190565b600081612750576127506126bd565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036127a7576127a76126bd565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826127ec576127ec6127ae565b500490565b600082821015612803576128036126bd565b500390565b600082612817576128176127ae565b500690565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261285b60808301846122de565b9695505050505050565b60006020828403121561287757600080fd5b81516104bf81612267565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_bridge": "Address of the ERC721 bridge on this network.", - "_remoteChainId": "Chain ID for the remote network." - } - }, - "createOptimismMintableERC721(address,string,string)": { - "params": { - "_name": "ERC721 name.", - "_remoteToken": "Address of the corresponding token on the other domain.", - "_symbol": "ERC721 symbol." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "events": { - "OptimismMintableERC721Created(address,address,address)": { - "params": { - "deployer": "Address of the initiator of the deployment", - "localToken": "Address of the token on the this domain.", - "remoteToken": "Address of the token on the remote domain." - } - } - }, - "title": "OptimismMintableERC721Factory" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "BRIDGE()": { - "notice": "Address of the ERC721 bridge on this network." - }, - "REMOTE_CHAIN_ID()": { - "notice": "Chain ID for the remote network." - }, - "constructor": { - "notice": "The semver MUST be bumped any time that there is a change in the OptimismMintableERC721 token contract since this contract is responsible for deploying OptimismMintableERC721 contracts." - }, - "createOptimismMintableERC721(address,string,string)": { - "notice": "Creates an instance of the standard ERC721." - }, - "isOptimismMintableERC721(address)": { - "notice": "Tracks addresses created by this factory." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "events": { - "OptimismMintableERC721Created(address,address,address)": { - "notice": "Emitted whenever a new OptimismMintableERC721 contract is created." - } - }, - "notice": "Factory contract for creating OptimismMintableERC721 contracts." - }, - "storageLayout": { - "storage": [ - { - "astId": 47461, - "contract": "contracts/universal/OptimismMintableERC721Factory.sol:OptimismMintableERC721Factory", - "label": "isOptimismMintableERC721", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_address,t_bool)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_mapping(t_address,t_bool)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => bool)", - "numberOfBytes": "32", - "value": "t_bool" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/OptimismMintableERC721FactoryProxy.json b/packages/contracts-bedrock/deployments/optimism-goerli/OptimismMintableERC721FactoryProxy.json deleted file mode 100644 index 69482dda23fb..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/OptimismMintableERC721FactoryProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x83F019dE99dB0cA483A5f2fC7053D3EA57BdE06D", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x12ed035f890442d691aa03f20b5fff5e2e599af0cabb84978efc7af59df050bb", - "receipt": { - "to": null, - "from": "0x5c679a57e018F5F146838138d3E032Ef4913D551", - "contractAddress": "0x83F019dE99dB0cA483A5f2fC7053D3EA57BdE06D", - "transactionIndex": 0, - "gasUsed": "532674", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000080000000000000000000000000000000000000000000040000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc8b5cf8db3d9d3bc1045e53fd6d1e075a720e4aa76b3593e63478baf60d37356", - "transactionHash": "0x12ed035f890442d691aa03f20b5fff5e2e599af0cabb84978efc7af59df050bb", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 1563185, - "transactionHash": "0x12ed035f890442d691aa03f20b5fff5e2e599af0cabb84978efc7af59df050bb", - "address": "0x83F019dE99dB0cA483A5f2fC7053D3EA57BdE06D", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c679a57e018f5f146838138d3e032ef4913d551", - "logIndex": 0, - "blockHash": "0xc8b5cf8db3d9d3bc1045e53fd6d1e075a720e4aa76b3593e63478baf60d37356" - } - ], - "blockNumber": 1563185, - "cumulativeGasUsed": "532674", - "status": 1, - "byzantium": true - }, - "args": [ - "0x5c679a57e018F5F146838138d3E032Ef4913D551" - ], - "numDeployments": 1, - "solcInputHash": "ab9b77493f35e63b7a63fb2fa8d618b4", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n external\\n payable\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() external proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() external proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/Optimist.json b/packages/contracts-bedrock/deployments/optimism-goerli/Optimist.json deleted file mode 100644 index 9bea8e63c0b3..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/Optimist.json +++ /dev/null @@ -1,883 +0,0 @@ -{ - "address": "0x2044D9830067B78c65F9702506798D6035f58745", - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "address", - "name": "_baseURIAttestor", - "type": "address" - }, - { - "internalType": "contract AttestationStation", - "name": "_attestationStation", - "type": "address" - }, - { - "internalType": "contract OptimistAllowlist", - "name": "_optimistAllowlist", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [], - "name": "ATTESTATION_STATION", - "outputs": [ - { - "internalType": "contract AttestationStation", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "BASE_URI_ATTESTATION_KEY", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "BASE_URI_ATTESTOR", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMIST_ALLOWLIST", - "outputs": [ - { - "internalType": "contract OptimistAllowlist", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "burn", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - } - ], - "name": "isOnAllowList", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - } - ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "tokenIdOfAddress", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x43857c8d09ffe81885d69ae0f72d1103e06a81fe2bfe027b170f08de36f26845", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 1, - "gasUsed": "2242451", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000002000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x19b116883b0dc13479692c084cfeaa28a77ef49da9d85cba16eae1a1ec98d064", - "transactionHash": "0x43857c8d09ffe81885d69ae0f72d1103e06a81fe2bfe027b170f08de36f26845", - "logs": [ - { - "transactionIndex": 1, - "blockNumber": 7691711, - "transactionHash": "0x43857c8d09ffe81885d69ae0f72d1103e06a81fe2bfe027b170f08de36f26845", - "address": "0x2044D9830067B78c65F9702506798D6035f58745", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 0, - "blockHash": "0x19b116883b0dc13479692c084cfeaa28a77ef49da9d85cba16eae1a1ec98d064" - } - ], - "blockNumber": 7691711, - "cumulativeGasUsed": "2289352", - "status": 1, - "byzantium": true - }, - "args": [ - "Optimist", - "OPTIMIST", - "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819", - "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77", - "0x482b1945D58f2E9Db0CEbe13c7fcFc6876b41180" - ], - "numDeployments": 2, - "solcInputHash": "d7155764d4bdb814f10e1bb45296292b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_baseURIAttestor\",\"type\":\"address\"},{\"internalType\":\"contract AttestationStation\",\"name\":\"_attestationStation\",\"type\":\"address\"},{\"internalType\":\"contract OptimistAllowlist\",\"name\":\"_optimistAllowlist\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ATTESTATION_STATION\",\"outputs\":[{\"internalType\":\"contract AttestationStation\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BASE_URI_ATTESTATION_KEY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BASE_URI_ATTESTOR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPTIMIST_ALLOWLIST\",\"outputs\":[{\"internalType\":\"contract OptimistAllowlist\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"baseURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"isOnAllowList\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"tokenIdOfAddress\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Optimism CollectiveGitcoin\",\"kind\":\"dev\",\"methods\":{\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"baseURI()\":{\"returns\":{\"_0\":\"BaseURI for all tokens.\"}},\"burn(uint256)\":{\"details\":\"Burns `tokenId`. See {ERC721-_burn}. Requirements: - The caller must own `tokenId` or be an approved operator.\"},\"constructor\":{\"custom:semver\":\"2.0.0\",\"params\":{\"_attestationStation\":\"Address of the AttestationStation contract.\",\"_baseURIAttestor\":\"Address of the baseURI attestor.\",\"_name\":\"Token name.\",\"_optimistAllowlist\":\"Address of the OptimistAllowlist contract\",\"_symbol\":\"Token symbol.\"}},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"initialize(string,string)\":{\"params\":{\"_name\":\"Token name.\",\"_symbol\":\"Token symbol.\"}},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"isOnAllowList(address)\":{\"returns\":{\"_0\":\"Whether or not the address is allowed to mint yet.\"}},\"mint(address)\":{\"params\":{\"_recipient\":\"Address of the token recipient.\"}},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenIdOfAddress(address)\":{\"returns\":{\"_0\":\"Token ID for the token owned by the given address.\"}},\"tokenURI(uint256)\":{\"params\":{\"_tokenId\":\"Token ID to query.\"},\"returns\":{\"_0\":\"Token URI for the given token by ID.\"}},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"Optimist\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"ATTESTATION_STATION()\":{\"notice\":\"Address of the AttestationStation contract.\"},\"BASE_URI_ATTESTATION_KEY()\":{\"notice\":\"Attestation key used by the attestor to attest the baseURI.\"},\"BASE_URI_ATTESTOR()\":{\"notice\":\"Attestor who attests to baseURI.\"},\"OPTIMIST_ALLOWLIST()\":{\"notice\":\"Address of the OptimistAllowlist contract.\"},\"approve(address,uint256)\":{\"notice\":\"Disabled for the Optimist NFT (Soul Bound Token).\"},\"baseURI()\":{\"notice\":\"Returns the baseURI for all tokens.\"},\"initialize(string,string)\":{\"notice\":\"Initializes the Optimist contract.\"},\"isOnAllowList(address)\":{\"notice\":\"Checks OptimistAllowlist to determine whether a given address is allowed to mint the Optimist NFT. Since the Optimist NFT will also be used as part of the Citizens House, mints are currently restricted. Eventually anyone will be able to mint.\"},\"mint(address)\":{\"notice\":\"Allows an address to mint an Optimist NFT. Token ID is the uint256 representation of the recipient's address. Recipients must be permitted to mint, eventually anyone will be able to mint. One token per address.\"},\"setApprovalForAll(address,bool)\":{\"notice\":\"Disabled for the Optimist NFT (Soul Bound Token).\"},\"tokenIdOfAddress(address)\":{\"notice\":\"Returns the token ID for the token owned by a given address. This is the uint256 representation of the given address.\"},\"tokenURI(uint256)\":{\"notice\":\"Returns the token URI for a given token by ID\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"A Soul Bound Token for real humans only(tm).\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/Optimist.sol\":\"Optimist\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721Upgradeable.sol\\\";\\nimport \\\"./IERC721ReceiverUpgradeable.sol\\\";\\nimport \\\"./extensions/IERC721MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../utils/StringsUpgradeable.sol\\\";\\nimport \\\"../../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\\n using AddressUpgradeable for address;\\n using StringsUpgradeable for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC721_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\\n return\\n interfaceId == type(IERC721Upgradeable).interfaceId ||\\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721Upgradeable.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor approved for all\\\"\\n );\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n _requireMinted(tokenId);\\n\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _safeTransfer(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) internal virtual {\\n _transfer(from, to, tokenId);\\n require(_checkOnERC721Received(from, to, tokenId, data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n }\\n\\n /**\\n * @dev Returns whether `tokenId` exists.\\n *\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\n *\\n * Tokens start existing when they are minted (`_mint`),\\n * and stop existing when they are burned (`_burn`).\\n */\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\n return _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721Upgradeable.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) internal virtual {\\n _mint(to, tokenId);\\n require(\\n _checkOnERC721Received(address(0), to, tokenId, data),\\n \\\"ERC721: transfer to non ERC721Receiver implementer\\\"\\n );\\n }\\n\\n /**\\n * @dev Mints `tokenId` and transfers it to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - `to` cannot be the zero address.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _mint(address to, uint256 tokenId) internal virtual {\\n require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n _beforeTokenTransfer(address(0), to, tokenId);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721Upgradeable.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[44] private __gap;\\n}\\n\",\"keccak256\":\"0x5331c8909221d9f9f3851cfadd5959d0873413a2c27e30e0f2fa234158c1c6cf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721ReceiverUpgradeable {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xbb2ed8106d94aeae6858e2551a1e7174df73994b77b13ebd120ccaaef80155f5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165Upgradeable.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721Upgradeable is IERC165Upgradeable {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x016298e66a5810253c6c905e61966bb31c8775c3f3517bf946ff56ee31d6c005\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721Upgradeable.sol\\\";\\nimport \\\"../../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\\n function __ERC721Burnable_init() internal onlyInitializing {\\n }\\n\\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xa7dbff7171ac06a023a5ca52c2138ac711037b2146b9197a52e5de4f9183e04d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721Upgradeable.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x95a471796eb5f030fdc438660bebec121ad5d063763e64d92376ffb4b5ce8b70\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165Upgradeable).interfaceId;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165Upgradeable {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of AttestationData structs.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x421923e04df145353db12cd0352ccf516d9c29ab64b138733b4f7a6a450ce2be\",\"license\":\"MIT\"},\"contracts/universal/op-nft/Optimist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\nimport {\\n ERC721BurnableUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\\\";\\nimport { AttestationStation } from \\\"./AttestationStation.sol\\\";\\nimport { OptimistAllowlist } from \\\"./OptimistAllowlist.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @title Optimist\\n * @notice A Soul Bound Token for real humans only(tm).\\n */\\ncontract Optimist is ERC721BurnableUpgradeable, Semver {\\n /**\\n * @notice Attestation key used by the attestor to attest the baseURI.\\n */\\n bytes32 public constant BASE_URI_ATTESTATION_KEY = bytes32(\\\"optimist.base-uri\\\");\\n\\n /**\\n * @notice Attestor who attests to baseURI.\\n */\\n address public immutable BASE_URI_ATTESTOR;\\n\\n /**\\n * @notice Address of the AttestationStation contract.\\n */\\n AttestationStation public immutable ATTESTATION_STATION;\\n\\n /**\\n * @notice Address of the OptimistAllowlist contract.\\n */\\n OptimistAllowlist public immutable OPTIMIST_ALLOWLIST;\\n\\n /**\\n * @custom:semver 2.0.0\\n * @param _name Token name.\\n * @param _symbol Token symbol.\\n * @param _baseURIAttestor Address of the baseURI attestor.\\n * @param _attestationStation Address of the AttestationStation contract.\\n * @param _optimistAllowlist Address of the OptimistAllowlist contract\\n */\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _baseURIAttestor,\\n AttestationStation _attestationStation,\\n OptimistAllowlist _optimistAllowlist\\n ) Semver(2, 0, 0) {\\n BASE_URI_ATTESTOR = _baseURIAttestor;\\n ATTESTATION_STATION = _attestationStation;\\n OPTIMIST_ALLOWLIST = _optimistAllowlist;\\n initialize(_name, _symbol);\\n }\\n\\n /**\\n * @notice Initializes the Optimist contract.\\n *\\n * @param _name Token name.\\n * @param _symbol Token symbol.\\n */\\n function initialize(string memory _name, string memory _symbol) public initializer {\\n __ERC721_init(_name, _symbol);\\n __ERC721Burnable_init();\\n }\\n\\n /**\\n * @notice Allows an address to mint an Optimist NFT. Token ID is the uint256 representation\\n * of the recipient's address. Recipients must be permitted to mint, eventually anyone\\n * will be able to mint. One token per address.\\n *\\n * @param _recipient Address of the token recipient.\\n */\\n function mint(address _recipient) public {\\n require(isOnAllowList(_recipient), \\\"Optimist: address is not on allowList\\\");\\n _safeMint(_recipient, tokenIdOfAddress(_recipient));\\n }\\n\\n /**\\n * @notice Returns the baseURI for all tokens.\\n *\\n * @return BaseURI for all tokens.\\n */\\n function baseURI() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n ATTESTATION_STATION.attestations(\\n BASE_URI_ATTESTOR,\\n address(this),\\n bytes32(\\\"optimist.base-uri\\\")\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the token URI for a given token by ID\\n *\\n * @param _tokenId Token ID to query.\\n\\n * @return Token URI for the given token by ID.\\n */\\n function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n baseURI(),\\n \\\"/\\\",\\n // Properly format the token ID as a 20 byte hex string (address).\\n Strings.toHexString(_tokenId, 20),\\n \\\".json\\\"\\n )\\n );\\n }\\n\\n /**\\n * @notice Checks OptimistAllowlist to determine whether a given address is allowed to mint\\n * the Optimist NFT. Since the Optimist NFT will also be used as part of the\\n * Citizens House, mints are currently restricted. Eventually anyone will be able\\n * to mint.\\n *\\n * @return Whether or not the address is allowed to mint yet.\\n */\\n function isOnAllowList(address _recipient) public view returns (bool) {\\n return OPTIMIST_ALLOWLIST.isAllowedToMint(_recipient);\\n }\\n\\n /**\\n * @notice Returns the token ID for the token owned by a given address. This is the uint256\\n * representation of the given address.\\n *\\n * @return Token ID for the token owned by the given address.\\n */\\n function tokenIdOfAddress(address _owner) public pure returns (uint256) {\\n return uint256(uint160(_owner));\\n }\\n\\n /**\\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\\n */\\n function approve(address, uint256) public pure override {\\n revert(\\\"Optimist: soul bound token\\\");\\n }\\n\\n /**\\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\\n */\\n function setApprovalForAll(address, bool) public virtual override {\\n revert(\\\"Optimist: soul bound token\\\");\\n }\\n\\n /**\\n * @notice Prevents transfers of the Optimist NFT (Soul Bound Token).\\n *\\n * @param _from Address of the token sender.\\n * @param _to Address of the token recipient.\\n */\\n function _beforeTokenTransfer(\\n address _from,\\n address _to,\\n uint256\\n ) internal virtual override {\\n require(_from == address(0) || _to == address(0), \\\"Optimist: soul bound token\\\");\\n }\\n}\\n\",\"keccak256\":\"0xf9c7973102666d1dc1b8a1918d6df82fa8fb470e1774aea840b300afb9699cac\",\"license\":\"MIT\"},\"contracts/universal/op-nft/OptimistAllowlist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\nimport { AttestationStation } from \\\"./AttestationStation.sol\\\";\\nimport { OptimistConstants } from \\\"./libraries/OptimistConstants.sol\\\";\\n\\n/**\\n * @title OptimistAllowlist\\n * @notice Source of truth for whether an address is able to mint an Optimist NFT.\\n isAllowedToMint function checks various signals to return boolean value for whether an\\n address is eligible or not.\\n */\\ncontract OptimistAllowlist is Semver {\\n /**\\n * @notice Attestation key used by the AllowlistAttestor to manually add addresses to the\\n * allowlist.\\n */\\n bytes32 public constant OPTIMIST_CAN_MINT_ATTESTATION_KEY = bytes32(\\\"optimist.can-mint\\\");\\n\\n /**\\n * @notice Attestation key used by Coinbase to issue attestations for Quest participants.\\n */\\n bytes32 public constant COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY =\\n bytes32(\\\"coinbase.quest-eligible\\\");\\n\\n /**\\n * @notice Address of the AttestationStation contract.\\n */\\n AttestationStation public immutable ATTESTATION_STATION;\\n\\n /**\\n * @notice Attestor that issues 'optimist.can-mint' attestations.\\n */\\n address public immutable ALLOWLIST_ATTESTOR;\\n\\n /**\\n * @notice Attestor that issues 'coinbase.quest-eligible' attestations.\\n */\\n address public immutable COINBASE_QUEST_ATTESTOR;\\n\\n /**\\n * @notice Address of OptimistInviter contract that issues 'optimist.can-mint-from-invite'\\n * attestations.\\n */\\n address public immutable OPTIMIST_INVITER;\\n\\n /**\\n * @custom:semver 1.0.0\\n *\\n * @param _attestationStation Address of the AttestationStation contract.\\n * @param _allowlistAttestor Address of the allowlist attestor.\\n * @param _coinbaseQuestAttestor Address of the Coinbase Quest attestor.\\n * @param _optimistInviter Address of the OptimistInviter contract.\\n */\\n constructor(\\n AttestationStation _attestationStation,\\n address _allowlistAttestor,\\n address _coinbaseQuestAttestor,\\n address _optimistInviter\\n ) Semver(1, 0, 0) {\\n ATTESTATION_STATION = _attestationStation;\\n ALLOWLIST_ATTESTOR = _allowlistAttestor;\\n COINBASE_QUEST_ATTESTOR = _coinbaseQuestAttestor;\\n OPTIMIST_INVITER = _optimistInviter;\\n }\\n\\n /**\\n * @notice Checks whether a given address is allowed to mint the Optimist NFT yet. Since the\\n * Optimist NFT will also be used as part of the Citizens House, mints are currently\\n * restricted. Eventually anyone will be able to mint.\\n *\\n * Currently, address is allowed to mint if it satisfies any of the following:\\n * 1) Has a valid 'optimist.can-mint' attestation from the allowlist attestor.\\n * 2) Has a valid 'coinbase.quest-eligible' attestation from Coinbase Quest attestor\\n * 3) Has a valid 'optimist.can-mint-from-invite' attestation from the OptimistInviter\\n * contract.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address is allowed to mint yet.\\n */\\n function isAllowedToMint(address _claimer) public view returns (bool) {\\n return\\n _hasAttestationFromAllowlistAttestor(_claimer) ||\\n _hasAttestationFromCoinbaseQuestAttestor(_claimer) ||\\n _hasAttestationFromOptimistInviter(_claimer);\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid 'optimist.can-mint' attestation from the\\n * allowlist attestor.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromAllowlistAttestor(address _claimer) internal view returns (bool) {\\n // Expected attestation value is bytes32(\\\"true\\\")\\n return\\n _hasValidAttestation(ALLOWLIST_ATTESTOR, _claimer, OPTIMIST_CAN_MINT_ATTESTATION_KEY);\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid attestation from the Coinbase attestor.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromCoinbaseQuestAttestor(address _claimer)\\n internal\\n view\\n returns (bool)\\n {\\n // Expected attestation value is bytes32(\\\"true\\\")\\n return\\n _hasValidAttestation(\\n COINBASE_QUEST_ATTESTOR,\\n _claimer,\\n COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY\\n );\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid attestation from the OptimistInviter contract.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromOptimistInviter(address _claimer) internal view returns (bool) {\\n // Expected attestation value is the inviter's address\\n return\\n _hasValidAttestation(\\n OPTIMIST_INVITER,\\n _claimer,\\n OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY\\n );\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid truthy attestation.\\n * Any attestation val other than bytes32(\\\"\\\") is considered truthy.\\n *\\n * @param _creator Address that made the attestation.\\n * @param _about Address attestation is about.\\n * @param _key Key of the attestation.\\n *\\n * @return Whether or not the address has a valid truthy attestation.\\n */\\n function _hasValidAttestation(\\n address _creator,\\n address _about,\\n bytes32 _key\\n ) internal view returns (bool) {\\n return ATTESTATION_STATION.attestations(_creator, _about, _key).length > 0;\\n }\\n}\\n\",\"keccak256\":\"0xd36a677571450d2d9be832beb80e5c37481fcdfc355e6a9b929ac9c8d4966ca0\",\"license\":\"MIT\"},\"contracts/universal/op-nft/libraries/OptimistConstants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title OptimistConstants\\n * @notice Library for storing Optimist related constants that are shared in multiple contracts.\\n */\\n\\nlibrary OptimistConstants {\\n /**\\n * @notice Attestation key issued by OptimistInviter allowing the attested account to mint.\\n */\\n bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY =\\n bytes32(\\\"optimist.can-mint-from-invite\\\");\\n}\\n\",\"keccak256\":\"0x6eebe1db87f8a5de79bf8af9120e5b0cc6a9b51d8d86e6461cdb6bc52a1dde21\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6101406040523480156200001257600080fd5b5060405162002c7f38038062002c7f8339810160408190526200003591620003ee565b6002608052600060a081905260c0526001600160a01b0380841660e052828116610100528116610120526200006b858562000076565b5050505050620005f4565b600054610100900460ff1615808015620000975750600054600160ff909116105b80620000c75750620000b430620001b660201b62000dd61760201c565b158015620000c7575060005460ff166001145b620001305760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000154576000805461ff0019166101001790555b620001608383620001c5565b6200016a62000231565b8015620001b1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002215760405162461bcd60e51b815260206004820152602b602482015260008051602062002c5f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000127565b6200022d82826200028f565b5050565b600054610100900460ff166200028d5760405162461bcd60e51b815260206004820152602b602482015260008051602062002c5f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000127565b565b600054610100900460ff16620002eb5760405162461bcd60e51b815260206004820152602b602482015260008051602062002c5f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000127565b6065620002f9838262000528565b506066620001b1828262000528565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200033057600080fd5b81516001600160401b03808211156200034d576200034d62000308565b604051601f8301601f19908116603f0116810190828211818310171562000378576200037862000308565b816040528381526020925086838588010111156200039557600080fd5b600091505b83821015620003b957858201830151818301840152908201906200039a565b83821115620003cb5760008385830101525b9695505050505050565b6001600160a01b0381168114620003eb57600080fd5b50565b600080600080600060a086880312156200040757600080fd5b85516001600160401b03808211156200041f57600080fd5b6200042d89838a016200031e565b965060208801519150808211156200044457600080fd5b5062000453888289016200031e565b94505060408601516200046681620003d5565b60608701519093506200047981620003d5565b60808701519092506200048c81620003d5565b809150509295509295909350565b600181811c90821680620004af57607f821691505b602082108103620004d057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620001b157600081815260208120601f850160051c81016020861015620004ff5750805b601f850160051c820191505b8181101562000520578281556001016200050b565b505050505050565b81516001600160401b0381111562000544576200054462000308565b6200055c816200055584546200049a565b84620004d6565b602080601f8311600181146200059457600084156200057b5750858301515b600019600386901b1c1916600185901b17855562000520565b600085815260208120601f198616915b82811015620005c557888601518255948401946001909101908401620005a4565b5085821015620005e45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e051610100516101205161260662000659600039600081816103930152610c900152600081816103ba0152610b1301526000818161022c0152610abc01526000610928015260006108ff015260006108d601526126066000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c80636a627842116100e3578063a22cb4651161008c578063ce5dd1b511610066578063ce5dd1b51461038e578063db083d71146103b5578063e985e9c5146103dc57600080fd5b8063a22cb4651461035a578063b88d4fde14610368578063c87b56dd1461037b57600080fd5b80637c08652f116100bd5780637c08652f146103185780638f328a1f1461033f57806395d89b411461035257600080fd5b80636a627842146102ea5780636c0360eb146102fd57806370a082311461030557600080fd5b806323b872dd116101455780634cd88b761161011f5780634cd88b76146102bc57806354fd4d50146102cf5780636352211e146102d757600080fd5b806323b872dd1461028357806342842e0e1461029657806342966c68146102a957600080fd5b8063095ea7b311610176578063095ea7b31461021257806319f463f21461022757806321d3d5cf1461024e57600080fd5b806301ffc9a71461019d57806306fdde03146101c5578063081812fc146101da575b600080fd5b6101b06101ab366004611d0e565b610425565b60405190151581526020015b60405180910390f35b6101cd61050a565b6040516101bc9190611d83565b6101ed6101e8366004611d96565b61059c565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b610225610220366004611dd8565b6105d0565b005b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6102757f6f7074696d6973742e626173652d75726900000000000000000000000000000081565b6040519081526020016101bc565b610225610291366004611e02565b61061d565b6102256102a4366004611e02565b6106aa565b6102256102b7366004611d96565b6106c5565b6102256102ca366004611f24565b61074c565b6101cd6108cf565b6101ed6102e5366004611d96565b610972565b6102256102f8366004611f88565b6109e4565b6101cd610a7f565b610275610313366004611f88565b610b94565b610275610326366004611f88565b73ffffffffffffffffffffffffffffffffffffffff1690565b6101b061034d366004611f88565b610c48565b6101cd610cfd565b610225610220366004611fb1565b610225610376366004611fe8565b610d0c565b6101cd610389366004611d96565b610d9a565b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6101b06103ea366004612064565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152606a6020908152604080832093909416825291909152205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806104b857507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061050457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606065805461051990612097565b80601f016020809104026020016040519081016040528092919081815260200182805461054590612097565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b60006105a782610df2565b5060009081526069602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405162461bcd60e51b815260206004820152601a60248201527f4f7074696d6973743a20736f756c20626f756e6420746f6b656e00000000000060448201526064015b60405180910390fd5b610628335b82610e63565b61069a5760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b6106a5838383610f23565b505050565b6106a583838360405180602001604052806000815250610d0c565b6106ce33610622565b6107405760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b61074981611161565b50565b600054610100900460ff161580801561076c5750600054600160ff909116105b806107865750303b158015610786575060005460ff166001145b6107f85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610614565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561085657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610860838361123b565b6108686112c2565b80156106a557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60606108fa7f0000000000000000000000000000000000000000000000000000000000000000611341565b6109237f0000000000000000000000000000000000000000000000000000000000000000611341565b61094c7f0000000000000000000000000000000000000000000000000000000000000000611341565b60405160200161095e939291906120ea565b604051602081830303815290604052905090565b60008181526067602052604081205473ffffffffffffffffffffffffffffffffffffffff16806105045760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610614565b6109ed81610c48565b610a5f5760405162461bcd60e51b815260206004820152602560248201527f4f7074696d6973743a2061646472657373206973206e6f74206f6e20616c6c6f60448201527f774c6973740000000000000000000000000000000000000000000000000000006064820152608401610614565b6107498173ffffffffffffffffffffffffffffffffffffffff8116611476565b6040517f29b42cb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301527f6f7074696d6973742e626173652d75726900000000000000000000000000000060448301526060917f0000000000000000000000000000000000000000000000000000000000000000909116906329b42cb590606401600060405180830381865afa158015610b5c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b849190810190612160565b60405160200161095e91906121d7565b600073ffffffffffffffffffffffffffffffffffffffff8216610c1f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152608401610614565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526068602052604090205490565b6040517f4813d8a600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690634813d8a690602401602060405180830381865afa158015610cd9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050491906121f3565b60606066805461051990612097565b610d163383610e63565b610d885760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b610d9484848484611490565b50505050565b6060610da4610a7f565b610daf836014611519565b604051602001610dc0929190612210565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60008181526067602052604090205473ffffffffffffffffffffffffffffffffffffffff166107495760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610614565b600080610e6f83610972565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610edd575073ffffffffffffffffffffffffffffffffffffffff8082166000908152606a602090815260408083209388168352929052205460ff165b80610f1b57508373ffffffffffffffffffffffffffffffffffffffff16610f038461059c565b73ffffffffffffffffffffffffffffffffffffffff16145b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16610f4382610972565b73ffffffffffffffffffffffffffffffffffffffff1614610fcc5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610614565b73ffffffffffffffffffffffffffffffffffffffff82166110545760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610614565b61105f838383611749565b61106a6000826117cc565b73ffffffffffffffffffffffffffffffffffffffff831660009081526068602052604081208054600192906110a09084906122c1565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526068602052604081208054600192906110db9084906122d8565b909155505060008181526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061116c82610972565b905061117a81600084611749565b6111856000836117cc565b73ffffffffffffffffffffffffffffffffffffffff811660009081526068602052604081208054600192906111bb9084906122c1565b909155505060008281526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45b5050565b600054610100900460ff166112b85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b611237828261186c565b600054610100900460ff1661133f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b565b60608160000361138457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156113ae5780611398816122f0565b91506113a79050600a83612357565b9150611388565b60008167ffffffffffffffff8111156113c9576113c9611e3e565b6040519080825280601f01601f1916602001820160405280156113f3576020820181803683370190505b5090505b8415610f1b576114086001836122c1565b9150611415600a8661236b565b6114209060306122d8565b60f81b8183815181106114355761143561237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061146f600a86612357565b94506113f7565b611237828260405180602001604052806000815250611902565b61149b848484610f23565b6114a78484848461198b565b610d945760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b606060006115288360026123ae565b6115339060026122d8565b67ffffffffffffffff81111561154b5761154b611e3e565b6040519080825280601f01601f191660200182016040528015611575576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106115ac576115ac61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061160f5761160f61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061164b8460026123ae565b6116569060016122d8565b90505b60018111156116f3577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106116975761169761237f565b1a60f81b8282815181106116ad576116ad61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936116ec816123eb565b9050611659565b5083156117425760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610614565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff83161580611780575073ffffffffffffffffffffffffffffffffffffffff8216155b6106a55760405162461bcd60e51b815260206004820152601a60248201527f4f7074696d6973743a20736f756c20626f756e6420746f6b656e0000000000006044820152606401610614565b600081815260696020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061182682610972565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600054610100900460ff166118e95760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b60656118f5838261246e565b5060666106a5828261246e565b61190c8383611b46565b611919600084848461198b565b6106a55760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b600073ffffffffffffffffffffffffffffffffffffffff84163b15611b3b576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290611a0290339089908890889060040161256a565b6020604051808303816000875af1925050508015611a3d575060408051601f3d908101601f19168201909252611a3a918101906125b3565b60015b611af0573d808015611a6b576040519150601f19603f3d011682016040523d82523d6000602084013e611a70565b606091505b508051600003611ae85760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050610f1b565b506001949350505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ba95760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610614565b60008181526067602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611c1b5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610614565b611c2760008383611749565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606860205260408120805460019290611c5d9084906122d8565b909155505060008181526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461074957600080fd5b600060208284031215611d2057600080fd5b813561174281611ce0565b60005b83811015611d46578181015183820152602001611d2e565b83811115610d945750506000910152565b60008151808452611d6f816020860160208601611d2b565b601f01601f19169290920160200192915050565b6020815260006117426020830184611d57565b600060208284031215611da857600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611dd357600080fd5b919050565b60008060408385031215611deb57600080fd5b611df483611daf565b946020939093013593505050565b600080600060608486031215611e1757600080fd5b611e2084611daf565b9250611e2e60208501611daf565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e9657611e96611e3e565b604052919050565b600067ffffffffffffffff821115611eb857611eb8611e3e565b50601f01601f191660200190565b6000611ed9611ed484611e9e565b611e6d565b9050828152838383011115611eed57600080fd5b828260208301376000602084830101529392505050565b600082601f830112611f1557600080fd5b61174283833560208501611ec6565b60008060408385031215611f3757600080fd5b823567ffffffffffffffff80821115611f4f57600080fd5b611f5b86838701611f04565b93506020850135915080821115611f7157600080fd5b50611f7e85828601611f04565b9150509250929050565b600060208284031215611f9a57600080fd5b61174282611daf565b801515811461074957600080fd5b60008060408385031215611fc457600080fd5b611fcd83611daf565b91506020830135611fdd81611fa3565b809150509250929050565b60008060008060808587031215611ffe57600080fd5b61200785611daf565b935061201560208601611daf565b925060408501359150606085013567ffffffffffffffff81111561203857600080fd5b8501601f8101871361204957600080fd5b61205887823560208401611ec6565b91505092959194509250565b6000806040838503121561207757600080fd5b61208083611daf565b915061208e60208401611daf565b90509250929050565b600181811c908216806120ab57607f821691505b6020821081036120e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516120fc818460208901611d2b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612138816001850160208a01611d2b565b60019201918201528351612153816002840160208801611d2b565b0160020195945050505050565b60006020828403121561217257600080fd5b815167ffffffffffffffff81111561218957600080fd5b8201601f8101841361219a57600080fd5b80516121a8611ed482611e9e565b8181528560208385010111156121bd57600080fd5b6121ce826020830160208601611d2b565b95945050505050565b600082516121e9818460208701611d2b565b9190910192915050565b60006020828403121561220557600080fd5b815161174281611fa3565b60008351612222818460208801611d2b565b7f2f00000000000000000000000000000000000000000000000000000000000000908301908152835161225c816001840160208801611d2b565b7f2e6a736f6e00000000000000000000000000000000000000000000000000000060019290910191820152600601949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156122d3576122d3612292565b500390565b600082198211156122eb576122eb612292565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361232157612321612292565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261236657612366612328565b500490565b60008261237a5761237a612328565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156123e6576123e6612292565b500290565b6000816123fa576123fa612292565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b601f8211156106a557600081815260208120601f850160051c810160208610156124475750805b601f850160051c820191505b8181101561246657828155600101612453565b505050505050565b815167ffffffffffffffff81111561248857612488611e3e565b61249c816124968454612097565b84612420565b602080601f8311600181146124ef57600084156124b95750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612466565b600085815260208120601f198616915b8281101561251e578886015182559484019460019091019084016124ff565b508582101561255a57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526125a96080830184611d57565b9695505050505050565b6000602082840312156125c557600080fd5b815161174281611ce056fea264697066735822122068519f9cbd8d80e9e293c6c977994da4f38aba3722422b6bfce53b68916efab964736f6c634300080f0033496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101985760003560e01c80636a627842116100e3578063a22cb4651161008c578063ce5dd1b511610066578063ce5dd1b51461038e578063db083d71146103b5578063e985e9c5146103dc57600080fd5b8063a22cb4651461035a578063b88d4fde14610368578063c87b56dd1461037b57600080fd5b80637c08652f116100bd5780637c08652f146103185780638f328a1f1461033f57806395d89b411461035257600080fd5b80636a627842146102ea5780636c0360eb146102fd57806370a082311461030557600080fd5b806323b872dd116101455780634cd88b761161011f5780634cd88b76146102bc57806354fd4d50146102cf5780636352211e146102d757600080fd5b806323b872dd1461028357806342842e0e1461029657806342966c68146102a957600080fd5b8063095ea7b311610176578063095ea7b31461021257806319f463f21461022757806321d3d5cf1461024e57600080fd5b806301ffc9a71461019d57806306fdde03146101c5578063081812fc146101da575b600080fd5b6101b06101ab366004611d0e565b610425565b60405190151581526020015b60405180910390f35b6101cd61050a565b6040516101bc9190611d83565b6101ed6101e8366004611d96565b61059c565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b610225610220366004611dd8565b6105d0565b005b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6102757f6f7074696d6973742e626173652d75726900000000000000000000000000000081565b6040519081526020016101bc565b610225610291366004611e02565b61061d565b6102256102a4366004611e02565b6106aa565b6102256102b7366004611d96565b6106c5565b6102256102ca366004611f24565b61074c565b6101cd6108cf565b6101ed6102e5366004611d96565b610972565b6102256102f8366004611f88565b6109e4565b6101cd610a7f565b610275610313366004611f88565b610b94565b610275610326366004611f88565b73ffffffffffffffffffffffffffffffffffffffff1690565b6101b061034d366004611f88565b610c48565b6101cd610cfd565b610225610220366004611fb1565b610225610376366004611fe8565b610d0c565b6101cd610389366004611d96565b610d9a565b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6101b06103ea366004612064565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152606a6020908152604080832093909416825291909152205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806104b857507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061050457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606065805461051990612097565b80601f016020809104026020016040519081016040528092919081815260200182805461054590612097565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b60006105a782610df2565b5060009081526069602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405162461bcd60e51b815260206004820152601a60248201527f4f7074696d6973743a20736f756c20626f756e6420746f6b656e00000000000060448201526064015b60405180910390fd5b610628335b82610e63565b61069a5760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b6106a5838383610f23565b505050565b6106a583838360405180602001604052806000815250610d0c565b6106ce33610622565b6107405760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b61074981611161565b50565b600054610100900460ff161580801561076c5750600054600160ff909116105b806107865750303b158015610786575060005460ff166001145b6107f85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610614565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561085657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610860838361123b565b6108686112c2565b80156106a557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60606108fa7f0000000000000000000000000000000000000000000000000000000000000000611341565b6109237f0000000000000000000000000000000000000000000000000000000000000000611341565b61094c7f0000000000000000000000000000000000000000000000000000000000000000611341565b60405160200161095e939291906120ea565b604051602081830303815290604052905090565b60008181526067602052604081205473ffffffffffffffffffffffffffffffffffffffff16806105045760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610614565b6109ed81610c48565b610a5f5760405162461bcd60e51b815260206004820152602560248201527f4f7074696d6973743a2061646472657373206973206e6f74206f6e20616c6c6f60448201527f774c6973740000000000000000000000000000000000000000000000000000006064820152608401610614565b6107498173ffffffffffffffffffffffffffffffffffffffff8116611476565b6040517f29b42cb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301527f6f7074696d6973742e626173652d75726900000000000000000000000000000060448301526060917f0000000000000000000000000000000000000000000000000000000000000000909116906329b42cb590606401600060405180830381865afa158015610b5c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b849190810190612160565b60405160200161095e91906121d7565b600073ffffffffffffffffffffffffffffffffffffffff8216610c1f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152608401610614565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526068602052604090205490565b6040517f4813d8a600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690634813d8a690602401602060405180830381865afa158015610cd9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050491906121f3565b60606066805461051990612097565b610d163383610e63565b610d885760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b610d9484848484611490565b50505050565b6060610da4610a7f565b610daf836014611519565b604051602001610dc0929190612210565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60008181526067602052604090205473ffffffffffffffffffffffffffffffffffffffff166107495760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610614565b600080610e6f83610972565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610edd575073ffffffffffffffffffffffffffffffffffffffff8082166000908152606a602090815260408083209388168352929052205460ff165b80610f1b57508373ffffffffffffffffffffffffffffffffffffffff16610f038461059c565b73ffffffffffffffffffffffffffffffffffffffff16145b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16610f4382610972565b73ffffffffffffffffffffffffffffffffffffffff1614610fcc5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610614565b73ffffffffffffffffffffffffffffffffffffffff82166110545760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610614565b61105f838383611749565b61106a6000826117cc565b73ffffffffffffffffffffffffffffffffffffffff831660009081526068602052604081208054600192906110a09084906122c1565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526068602052604081208054600192906110db9084906122d8565b909155505060008181526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061116c82610972565b905061117a81600084611749565b6111856000836117cc565b73ffffffffffffffffffffffffffffffffffffffff811660009081526068602052604081208054600192906111bb9084906122c1565b909155505060008281526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45b5050565b600054610100900460ff166112b85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b611237828261186c565b600054610100900460ff1661133f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b565b60608160000361138457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156113ae5780611398816122f0565b91506113a79050600a83612357565b9150611388565b60008167ffffffffffffffff8111156113c9576113c9611e3e565b6040519080825280601f01601f1916602001820160405280156113f3576020820181803683370190505b5090505b8415610f1b576114086001836122c1565b9150611415600a8661236b565b6114209060306122d8565b60f81b8183815181106114355761143561237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061146f600a86612357565b94506113f7565b611237828260405180602001604052806000815250611902565b61149b848484610f23565b6114a78484848461198b565b610d945760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b606060006115288360026123ae565b6115339060026122d8565b67ffffffffffffffff81111561154b5761154b611e3e565b6040519080825280601f01601f191660200182016040528015611575576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106115ac576115ac61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061160f5761160f61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061164b8460026123ae565b6116569060016122d8565b90505b60018111156116f3577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106116975761169761237f565b1a60f81b8282815181106116ad576116ad61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936116ec816123eb565b9050611659565b5083156117425760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610614565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff83161580611780575073ffffffffffffffffffffffffffffffffffffffff8216155b6106a55760405162461bcd60e51b815260206004820152601a60248201527f4f7074696d6973743a20736f756c20626f756e6420746f6b656e0000000000006044820152606401610614565b600081815260696020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061182682610972565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600054610100900460ff166118e95760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b60656118f5838261246e565b5060666106a5828261246e565b61190c8383611b46565b611919600084848461198b565b6106a55760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b600073ffffffffffffffffffffffffffffffffffffffff84163b15611b3b576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290611a0290339089908890889060040161256a565b6020604051808303816000875af1925050508015611a3d575060408051601f3d908101601f19168201909252611a3a918101906125b3565b60015b611af0573d808015611a6b576040519150601f19603f3d011682016040523d82523d6000602084013e611a70565b606091505b508051600003611ae85760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050610f1b565b506001949350505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ba95760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610614565b60008181526067602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611c1b5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610614565b611c2760008383611749565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606860205260408120805460019290611c5d9084906122d8565b909155505060008181526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461074957600080fd5b600060208284031215611d2057600080fd5b813561174281611ce0565b60005b83811015611d46578181015183820152602001611d2e565b83811115610d945750506000910152565b60008151808452611d6f816020860160208601611d2b565b601f01601f19169290920160200192915050565b6020815260006117426020830184611d57565b600060208284031215611da857600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611dd357600080fd5b919050565b60008060408385031215611deb57600080fd5b611df483611daf565b946020939093013593505050565b600080600060608486031215611e1757600080fd5b611e2084611daf565b9250611e2e60208501611daf565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e9657611e96611e3e565b604052919050565b600067ffffffffffffffff821115611eb857611eb8611e3e565b50601f01601f191660200190565b6000611ed9611ed484611e9e565b611e6d565b9050828152838383011115611eed57600080fd5b828260208301376000602084830101529392505050565b600082601f830112611f1557600080fd5b61174283833560208501611ec6565b60008060408385031215611f3757600080fd5b823567ffffffffffffffff80821115611f4f57600080fd5b611f5b86838701611f04565b93506020850135915080821115611f7157600080fd5b50611f7e85828601611f04565b9150509250929050565b600060208284031215611f9a57600080fd5b61174282611daf565b801515811461074957600080fd5b60008060408385031215611fc457600080fd5b611fcd83611daf565b91506020830135611fdd81611fa3565b809150509250929050565b60008060008060808587031215611ffe57600080fd5b61200785611daf565b935061201560208601611daf565b925060408501359150606085013567ffffffffffffffff81111561203857600080fd5b8501601f8101871361204957600080fd5b61205887823560208401611ec6565b91505092959194509250565b6000806040838503121561207757600080fd5b61208083611daf565b915061208e60208401611daf565b90509250929050565b600181811c908216806120ab57607f821691505b6020821081036120e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516120fc818460208901611d2b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612138816001850160208a01611d2b565b60019201918201528351612153816002840160208801611d2b565b0160020195945050505050565b60006020828403121561217257600080fd5b815167ffffffffffffffff81111561218957600080fd5b8201601f8101841361219a57600080fd5b80516121a8611ed482611e9e565b8181528560208385010111156121bd57600080fd5b6121ce826020830160208601611d2b565b95945050505050565b600082516121e9818460208701611d2b565b9190910192915050565b60006020828403121561220557600080fd5b815161174281611fa3565b60008351612222818460208801611d2b565b7f2f00000000000000000000000000000000000000000000000000000000000000908301908152835161225c816001840160208801611d2b565b7f2e6a736f6e00000000000000000000000000000000000000000000000000000060019290910191820152600601949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156122d3576122d3612292565b500390565b600082198211156122eb576122eb612292565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361232157612321612292565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261236657612366612328565b500490565b60008261237a5761237a612328565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156123e6576123e6612292565b500290565b6000816123fa576123fa612292565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b601f8211156106a557600081815260208120601f850160051c810160208610156124475750805b601f850160051c820191505b8181101561246657828155600101612453565b505050505050565b815167ffffffffffffffff81111561248857612488611e3e565b61249c816124968454612097565b84612420565b602080601f8311600181146124ef57600084156124b95750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612466565b600085815260208120601f198616915b8281101561251e578886015182559484019460019091019084016124ff565b508582101561255a57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526125a96080830184611d57565b9695505050505050565b6000602082840312156125c557600080fd5b815161174281611ce056fea264697066735822122068519f9cbd8d80e9e293c6c977994da4f38aba3722422b6bfce53b68916efab964736f6c634300080f0033", - "devdoc": { - "author": "Optimism CollectiveGitcoin", - "kind": "dev", - "methods": { - "balanceOf(address)": { - "details": "See {IERC721-balanceOf}." - }, - "baseURI()": { - "returns": { - "_0": "BaseURI for all tokens." - } - }, - "burn(uint256)": { - "details": "Burns `tokenId`. See {ERC721-_burn}. Requirements: - The caller must own `tokenId` or be an approved operator." - }, - "constructor": { - "custom:semver": "2.0.0", - "params": { - "_attestationStation": "Address of the AttestationStation contract.", - "_baseURIAttestor": "Address of the baseURI attestor.", - "_name": "Token name.", - "_optimistAllowlist": "Address of the OptimistAllowlist contract", - "_symbol": "Token symbol." - } - }, - "getApproved(uint256)": { - "details": "See {IERC721-getApproved}." - }, - "initialize(string,string)": { - "params": { - "_name": "Token name.", - "_symbol": "Token symbol." - } - }, - "isApprovedForAll(address,address)": { - "details": "See {IERC721-isApprovedForAll}." - }, - "isOnAllowList(address)": { - "returns": { - "_0": "Whether or not the address is allowed to mint yet." - } - }, - "mint(address)": { - "params": { - "_recipient": "Address of the token recipient." - } - }, - "name()": { - "details": "See {IERC721Metadata-name}." - }, - "ownerOf(uint256)": { - "details": "See {IERC721-ownerOf}." - }, - "safeTransferFrom(address,address,uint256)": { - "details": "See {IERC721-safeTransferFrom}." - }, - "safeTransferFrom(address,address,uint256,bytes)": { - "details": "See {IERC721-safeTransferFrom}." - }, - "supportsInterface(bytes4)": { - "details": "See {IERC165-supportsInterface}." - }, - "symbol()": { - "details": "See {IERC721Metadata-symbol}." - }, - "tokenIdOfAddress(address)": { - "returns": { - "_0": "Token ID for the token owned by the given address." - } - }, - "tokenURI(uint256)": { - "params": { - "_tokenId": "Token ID to query." - }, - "returns": { - "_0": "Token URI for the given token by ID." - } - }, - "transferFrom(address,address,uint256)": { - "details": "See {IERC721-transferFrom}." - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "Optimist", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "ATTESTATION_STATION()": { - "notice": "Address of the AttestationStation contract." - }, - "BASE_URI_ATTESTATION_KEY()": { - "notice": "Attestation key used by the attestor to attest the baseURI." - }, - "BASE_URI_ATTESTOR()": { - "notice": "Attestor who attests to baseURI." - }, - "OPTIMIST_ALLOWLIST()": { - "notice": "Address of the OptimistAllowlist contract." - }, - "approve(address,uint256)": { - "notice": "Disabled for the Optimist NFT (Soul Bound Token)." - }, - "baseURI()": { - "notice": "Returns the baseURI for all tokens." - }, - "initialize(string,string)": { - "notice": "Initializes the Optimist contract." - }, - "isOnAllowList(address)": { - "notice": "Checks OptimistAllowlist to determine whether a given address is allowed to mint the Optimist NFT. Since the Optimist NFT will also be used as part of the Citizens House, mints are currently restricted. Eventually anyone will be able to mint." - }, - "mint(address)": { - "notice": "Allows an address to mint an Optimist NFT. Token ID is the uint256 representation of the recipient's address. Recipients must be permitted to mint, eventually anyone will be able to mint. One token per address." - }, - "setApprovalForAll(address,bool)": { - "notice": "Disabled for the Optimist NFT (Soul Bound Token)." - }, - "tokenIdOfAddress(address)": { - "notice": "Returns the token ID for the token owned by a given address. This is the uint256 representation of the given address." - }, - "tokenURI(uint256)": { - "notice": "Returns the token URI for a given token by ID" - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "A Soul Bound Token for real humans only(tm).", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 1166, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 1169, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 2697, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 3505, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "__gap", - "offset": 0, - "slot": "51", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 1339, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_name", - "offset": 0, - "slot": "101", - "type": "t_string_storage" - }, - { - "astId": 1341, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_symbol", - "offset": 0, - "slot": "102", - "type": "t_string_storage" - }, - { - "astId": 1345, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_owners", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_address)" - }, - { - "astId": 1349, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_balances", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_address,t_uint256)" - }, - { - "astId": 1353, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_tokenApprovals", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_uint256,t_address)" - }, - { - "astId": 1359, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_operatorApprovals", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" - }, - { - "astId": 2201, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "__gap", - "offset": 0, - "slot": "107", - "type": "t_array(t_uint256)44_storage" - }, - { - "astId": 2385, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "__gap", - "offset": 0, - "slot": "151", - "type": "t_array(t_uint256)50_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)44_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[44]", - "numberOfBytes": "1408" - }, - "t_array(t_uint256)50_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_mapping(t_address,t_bool)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_mapping(t_address,t_mapping(t_address,t_bool))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => bool))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_bool)" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_mapping(t_uint256,t_address)": { - "encoding": "mapping", - "key": "t_uint256", - "label": "mapping(uint256 => address)", - "numberOfBytes": "32", - "value": "t_address" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/OptimistAllowlist.json b/packages/contracts-bedrock/deployments/optimism-goerli/OptimistAllowlist.json deleted file mode 100644 index 20736b2dfdd4..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/OptimistAllowlist.json +++ /dev/null @@ -1,232 +0,0 @@ -{ - "address": "0x1EC6A94aee0Ff4BB21d4852da2D07b8Fd25914a0", - "abi": [ - { - "inputs": [ - { - "internalType": "contract AttestationStation", - "name": "_attestationStation", - "type": "address" - }, - { - "internalType": "address", - "name": "_allowlistAttestor", - "type": "address" - }, - { - "internalType": "address", - "name": "_coinbaseQuestAttestor", - "type": "address" - }, - { - "internalType": "address", - "name": "_optimistInviter", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "ALLOWLIST_ATTESTOR", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "ATTESTATION_STATION", - "outputs": [ - { - "internalType": "contract AttestationStation", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COINBASE_QUEST_ATTESTOR", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMIST_CAN_MINT_ATTESTATION_KEY", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMIST_INVITER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_claimer", - "type": "address" - } - ], - "name": "isAllowedToMint", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x5673e56b5a4f86f06bac8ed41f0f67ab12d1aaee313770d23d173f3736493be0", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819", - "contractAddress": null, - "transactionIndex": 3, - "gasUsed": "568770", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x6badea5d408ed78fae97b6620d71146646ab68889ad2a3cac3813af7cc9e6280", - "transactionHash": "0x5673e56b5a4f86f06bac8ed41f0f67ab12d1aaee313770d23d173f3736493be0", - "logs": [], - "blockNumber": 8253248, - "cumulativeGasUsed": "878505", - "status": 1, - "byzantium": true - }, - "args": [ - "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77", - "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819", - "0x9A75024c09b48B78205dfCf9D9FC5E026CD9A416", - "0x073031A1E1b8F5458Ed41Ce56331F5fd7e1de929" - ], - "numDeployments": 2, - "solcInputHash": "d7155764d4bdb814f10e1bb45296292b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract AttestationStation\",\"name\":\"_attestationStation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowlistAttestor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_coinbaseQuestAttestor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_optimistInviter\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ALLOWLIST_ATTESTOR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ATTESTATION_STATION\",\"outputs\":[{\"internalType\":\"contract AttestationStation\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COINBASE_QUEST_ATTESTOR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPTIMIST_CAN_MINT_ATTESTATION_KEY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPTIMIST_INVITER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_claimer\",\"type\":\"address\"}],\"name\":\"isAllowedToMint\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.0.0\",\"params\":{\"_allowlistAttestor\":\"Address of the allowlist attestor.\",\"_attestationStation\":\"Address of the AttestationStation contract.\",\"_coinbaseQuestAttestor\":\"Address of the Coinbase Quest attestor.\",\"_optimistInviter\":\"Address of the OptimistInviter contract.\"}},\"isAllowedToMint(address)\":{\"params\":{\"_claimer\":\"Address to check.\"},\"returns\":{\"_0\":\"Whether or not the address is allowed to mint yet.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"OptimistAllowlist\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"ALLOWLIST_ATTESTOR()\":{\"notice\":\"Attestor that issues 'optimist.can-mint' attestations.\"},\"ATTESTATION_STATION()\":{\"notice\":\"Address of the AttestationStation contract.\"},\"COINBASE_QUEST_ATTESTOR()\":{\"notice\":\"Attestor that issues 'coinbase.quest-eligible' attestations.\"},\"COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY()\":{\"notice\":\"Attestation key used by Coinbase to issue attestations for Quest participants.\"},\"OPTIMIST_CAN_MINT_ATTESTATION_KEY()\":{\"notice\":\"Attestation key used by the AllowlistAttestor to manually add addresses to the allowlist.\"},\"OPTIMIST_INVITER()\":{\"notice\":\"Address of OptimistInviter contract that issues 'optimist.can-mint-from-invite' attestations.\"},\"isAllowedToMint(address)\":{\"notice\":\"Checks whether a given address is allowed to mint the Optimist NFT yet. Since the Optimist NFT will also be used as part of the Citizens House, mints are currently restricted. Eventually anyone will be able to mint. Currently, address is allowed to mint if it satisfies any of the following: 1) Has a valid 'optimist.can-mint' attestation from the allowlist attestor. 2) Has a valid 'coinbase.quest-eligible' attestation from Coinbase Quest attestor 3) Has a valid 'optimist.can-mint-from-invite' attestation from the OptimistInviter contract.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Source of truth for whether an address is able to mint an Optimist NFT. isAllowedToMint function checks various signals to return boolean value for whether an address is eligible or not.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/OptimistAllowlist.sol\":\"OptimistAllowlist\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of AttestationData structs.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x421923e04df145353db12cd0352ccf516d9c29ab64b138733b4f7a6a450ce2be\",\"license\":\"MIT\"},\"contracts/universal/op-nft/OptimistAllowlist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\nimport { AttestationStation } from \\\"./AttestationStation.sol\\\";\\nimport { OptimistConstants } from \\\"./libraries/OptimistConstants.sol\\\";\\n\\n/**\\n * @title OptimistAllowlist\\n * @notice Source of truth for whether an address is able to mint an Optimist NFT.\\n isAllowedToMint function checks various signals to return boolean value for whether an\\n address is eligible or not.\\n */\\ncontract OptimistAllowlist is Semver {\\n /**\\n * @notice Attestation key used by the AllowlistAttestor to manually add addresses to the\\n * allowlist.\\n */\\n bytes32 public constant OPTIMIST_CAN_MINT_ATTESTATION_KEY = bytes32(\\\"optimist.can-mint\\\");\\n\\n /**\\n * @notice Attestation key used by Coinbase to issue attestations for Quest participants.\\n */\\n bytes32 public constant COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY =\\n bytes32(\\\"coinbase.quest-eligible\\\");\\n\\n /**\\n * @notice Address of the AttestationStation contract.\\n */\\n AttestationStation public immutable ATTESTATION_STATION;\\n\\n /**\\n * @notice Attestor that issues 'optimist.can-mint' attestations.\\n */\\n address public immutable ALLOWLIST_ATTESTOR;\\n\\n /**\\n * @notice Attestor that issues 'coinbase.quest-eligible' attestations.\\n */\\n address public immutable COINBASE_QUEST_ATTESTOR;\\n\\n /**\\n * @notice Address of OptimistInviter contract that issues 'optimist.can-mint-from-invite'\\n * attestations.\\n */\\n address public immutable OPTIMIST_INVITER;\\n\\n /**\\n * @custom:semver 1.0.0\\n *\\n * @param _attestationStation Address of the AttestationStation contract.\\n * @param _allowlistAttestor Address of the allowlist attestor.\\n * @param _coinbaseQuestAttestor Address of the Coinbase Quest attestor.\\n * @param _optimistInviter Address of the OptimistInviter contract.\\n */\\n constructor(\\n AttestationStation _attestationStation,\\n address _allowlistAttestor,\\n address _coinbaseQuestAttestor,\\n address _optimistInviter\\n ) Semver(1, 0, 0) {\\n ATTESTATION_STATION = _attestationStation;\\n ALLOWLIST_ATTESTOR = _allowlistAttestor;\\n COINBASE_QUEST_ATTESTOR = _coinbaseQuestAttestor;\\n OPTIMIST_INVITER = _optimistInviter;\\n }\\n\\n /**\\n * @notice Checks whether a given address is allowed to mint the Optimist NFT yet. Since the\\n * Optimist NFT will also be used as part of the Citizens House, mints are currently\\n * restricted. Eventually anyone will be able to mint.\\n *\\n * Currently, address is allowed to mint if it satisfies any of the following:\\n * 1) Has a valid 'optimist.can-mint' attestation from the allowlist attestor.\\n * 2) Has a valid 'coinbase.quest-eligible' attestation from Coinbase Quest attestor\\n * 3) Has a valid 'optimist.can-mint-from-invite' attestation from the OptimistInviter\\n * contract.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address is allowed to mint yet.\\n */\\n function isAllowedToMint(address _claimer) public view returns (bool) {\\n return\\n _hasAttestationFromAllowlistAttestor(_claimer) ||\\n _hasAttestationFromCoinbaseQuestAttestor(_claimer) ||\\n _hasAttestationFromOptimistInviter(_claimer);\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid 'optimist.can-mint' attestation from the\\n * allowlist attestor.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromAllowlistAttestor(address _claimer) internal view returns (bool) {\\n // Expected attestation value is bytes32(\\\"true\\\")\\n return\\n _hasValidAttestation(ALLOWLIST_ATTESTOR, _claimer, OPTIMIST_CAN_MINT_ATTESTATION_KEY);\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid attestation from the Coinbase attestor.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromCoinbaseQuestAttestor(address _claimer)\\n internal\\n view\\n returns (bool)\\n {\\n // Expected attestation value is bytes32(\\\"true\\\")\\n return\\n _hasValidAttestation(\\n COINBASE_QUEST_ATTESTOR,\\n _claimer,\\n COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY\\n );\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid attestation from the OptimistInviter contract.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromOptimistInviter(address _claimer) internal view returns (bool) {\\n // Expected attestation value is the inviter's address\\n return\\n _hasValidAttestation(\\n OPTIMIST_INVITER,\\n _claimer,\\n OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY\\n );\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid truthy attestation.\\n * Any attestation val other than bytes32(\\\"\\\") is considered truthy.\\n *\\n * @param _creator Address that made the attestation.\\n * @param _about Address attestation is about.\\n * @param _key Key of the attestation.\\n *\\n * @return Whether or not the address has a valid truthy attestation.\\n */\\n function _hasValidAttestation(\\n address _creator,\\n address _about,\\n bytes32 _key\\n ) internal view returns (bool) {\\n return ATTESTATION_STATION.attestations(_creator, _about, _key).length > 0;\\n }\\n}\\n\",\"keccak256\":\"0xd36a677571450d2d9be832beb80e5c37481fcdfc355e6a9b929ac9c8d4966ca0\",\"license\":\"MIT\"},\"contracts/universal/op-nft/libraries/OptimistConstants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title OptimistConstants\\n * @notice Library for storing Optimist related constants that are shared in multiple contracts.\\n */\\n\\nlibrary OptimistConstants {\\n /**\\n * @notice Attestation key issued by OptimistInviter allowing the attested account to mint.\\n */\\n bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY =\\n bytes32(\\\"optimist.can-mint-from-invite\\\");\\n}\\n\",\"keccak256\":\"0x6eebe1db87f8a5de79bf8af9120e5b0cc6a9b51d8d86e6461cdb6bc52a1dde21\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x61016060405234801561001157600080fd5b50604051610a9d380380610a9d8339810160408190526100309161007c565b6001608052600060a081905260c0526001600160a01b0393841660e0529183166101005282166101205216610140526100db565b6001600160a01b038116811461007957600080fd5b50565b6000806000806080858703121561009257600080fd5b845161009d81610064565b60208601519094506100ae81610064565b60408601519093506100bf81610064565b60608601519092506100d081610064565b939692955090935050565b60805160a05160c05160e05161010051610120516101405161094d6101506000396000818161011b015261035a0152600081816092015261030d01526000818161019e01526102c001526000818161017701526105360152600061026f015260006102460152600061021d015261094d6000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063819f7e841161005b578063819f7e841461013d578063db083d7114610172578063db3c316314610199578063e7bd804e146101c057600080fd5b80633ac52df71461008d5780634813d8a6146100de57806354fd4d50146101015780635e4f489a14610116575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100f16100ec3660046105cd565b6101e7565b60405190151581526020016100d5565b610109610216565b6040516100d5919061063a565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101647f636f696e626173652e71756573742d656c696769626c6500000000000000000081565b6040519081526020016100d5565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101647f6f7074696d6973742e63616e2d6d696e7400000000000000000000000000000081565b60006101f2826102b9565b80610201575061020182610306565b80610210575061021082610353565b92915050565b60606102417f00000000000000000000000000000000000000000000000000000000000000006103a0565b61026a7f00000000000000000000000000000000000000000000000000000000000000006103a0565b6102937f00000000000000000000000000000000000000000000000000000000000000006103a0565b6040516020016102a59392919061068b565b604051602081830303815290604052905090565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f6f7074696d6973742e63616e2d6d696e740000000000000000000000000000006104dd565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f636f696e626173652e71756573742d656c696769626c650000000000000000006104dd565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f6f7074696d6973742e63616e2d6d696e742d66726f6d2d696e766974650000006104dd565b6060816000036103e357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561040d57806103f781610730565b91506104069050600a83610797565b91506103e7565b60008167ffffffffffffffff811115610428576104286107ab565b6040519080825280601f01601f191660200182016040528015610452576020820181803683370190505b5090505b84156104d5576104676001836107da565b9150610474600a866107f1565b61047f906030610805565b60f81b8183815181106104945761049461081d565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104ce600a86610797565b9450610456565b949350505050565b6040517f29b42cb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283811660248301526044820183905260009182917f000000000000000000000000000000000000000000000000000000000000000016906329b42cb590606401600060405180830381865afa15801561057d573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105c3919081019061084c565b5111949350505050565b6000602082840312156105df57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461060357600080fd5b9392505050565b60005b8381101561062557818101518382015260200161060d565b83811115610634576000848401525b50505050565b602081526000825180602084015261065981604085016020870161060a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000845161069d81846020890161060a565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516106d9816001850160208a0161060a565b600192019182015283516106f481600284016020880161060a565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361076157610761610701565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826107a6576107a6610768565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107ec576107ec610701565b500390565b60008261080057610800610768565b500690565b6000821982111561081857610818610701565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561085e57600080fd5b815167ffffffffffffffff8082111561087657600080fd5b818401915084601f83011261088a57600080fd5b81518181111561089c5761089c6107ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e2576108e26107ab565b816040528281528760208487010111156108fb57600080fd5b61090c83602083016020880161060a565b97965050505050505056fea2646970667358221220f7c9eee125b4662acd39871c7f71fd0d6635d58d3d0d2d059a8c8bb16ba6d74564736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063819f7e841161005b578063819f7e841461013d578063db083d7114610172578063db3c316314610199578063e7bd804e146101c057600080fd5b80633ac52df71461008d5780634813d8a6146100de57806354fd4d50146101015780635e4f489a14610116575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100f16100ec3660046105cd565b6101e7565b60405190151581526020016100d5565b610109610216565b6040516100d5919061063a565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101647f636f696e626173652e71756573742d656c696769626c6500000000000000000081565b6040519081526020016100d5565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101647f6f7074696d6973742e63616e2d6d696e7400000000000000000000000000000081565b60006101f2826102b9565b80610201575061020182610306565b80610210575061021082610353565b92915050565b60606102417f00000000000000000000000000000000000000000000000000000000000000006103a0565b61026a7f00000000000000000000000000000000000000000000000000000000000000006103a0565b6102937f00000000000000000000000000000000000000000000000000000000000000006103a0565b6040516020016102a59392919061068b565b604051602081830303815290604052905090565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f6f7074696d6973742e63616e2d6d696e740000000000000000000000000000006104dd565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f636f696e626173652e71756573742d656c696769626c650000000000000000006104dd565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f6f7074696d6973742e63616e2d6d696e742d66726f6d2d696e766974650000006104dd565b6060816000036103e357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561040d57806103f781610730565b91506104069050600a83610797565b91506103e7565b60008167ffffffffffffffff811115610428576104286107ab565b6040519080825280601f01601f191660200182016040528015610452576020820181803683370190505b5090505b84156104d5576104676001836107da565b9150610474600a866107f1565b61047f906030610805565b60f81b8183815181106104945761049461081d565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104ce600a86610797565b9450610456565b949350505050565b6040517f29b42cb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283811660248301526044820183905260009182917f000000000000000000000000000000000000000000000000000000000000000016906329b42cb590606401600060405180830381865afa15801561057d573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105c3919081019061084c565b5111949350505050565b6000602082840312156105df57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461060357600080fd5b9392505050565b60005b8381101561062557818101518382015260200161060d565b83811115610634576000848401525b50505050565b602081526000825180602084015261065981604085016020870161060a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000845161069d81846020890161060a565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516106d9816001850160208a0161060a565b600192019182015283516106f481600284016020880161060a565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361076157610761610701565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826107a6576107a6610768565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107ec576107ec610701565b500390565b60008261080057610800610768565b500690565b6000821982111561081857610818610701565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561085e57600080fd5b815167ffffffffffffffff8082111561087657600080fd5b818401915084601f83011261088a57600080fd5b81518181111561089c5761089c6107ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e2576108e26107ab565b816040528281528760208487010111156108fb57600080fd5b61090c83602083016020880161060a565b97965050505050505056fea2646970667358221220f7c9eee125b4662acd39871c7f71fd0d6635d58d3d0d2d059a8c8bb16ba6d74564736f6c634300080f0033", - "devdoc": { - "kind": "dev", - "methods": { - "constructor": { - "custom:semver": "1.0.0", - "params": { - "_allowlistAttestor": "Address of the allowlist attestor.", - "_attestationStation": "Address of the AttestationStation contract.", - "_coinbaseQuestAttestor": "Address of the Coinbase Quest attestor.", - "_optimistInviter": "Address of the OptimistInviter contract." - } - }, - "isAllowedToMint(address)": { - "params": { - "_claimer": "Address to check." - }, - "returns": { - "_0": "Whether or not the address is allowed to mint yet." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "OptimistAllowlist", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "ALLOWLIST_ATTESTOR()": { - "notice": "Attestor that issues 'optimist.can-mint' attestations." - }, - "ATTESTATION_STATION()": { - "notice": "Address of the AttestationStation contract." - }, - "COINBASE_QUEST_ATTESTOR()": { - "notice": "Attestor that issues 'coinbase.quest-eligible' attestations." - }, - "COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY()": { - "notice": "Attestation key used by Coinbase to issue attestations for Quest participants." - }, - "OPTIMIST_CAN_MINT_ATTESTATION_KEY()": { - "notice": "Attestation key used by the AllowlistAttestor to manually add addresses to the allowlist." - }, - "OPTIMIST_INVITER()": { - "notice": "Address of OptimistInviter contract that issues 'optimist.can-mint-from-invite' attestations." - }, - "isAllowedToMint(address)": { - "notice": "Checks whether a given address is allowed to mint the Optimist NFT yet. Since the Optimist NFT will also be used as part of the Citizens House, mints are currently restricted. Eventually anyone will be able to mint. Currently, address is allowed to mint if it satisfies any of the following: 1) Has a valid 'optimist.can-mint' attestation from the allowlist attestor. 2) Has a valid 'coinbase.quest-eligible' attestation from Coinbase Quest attestor 3) Has a valid 'optimist.can-mint-from-invite' attestation from the OptimistInviter contract." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "Source of truth for whether an address is able to mint an Optimist NFT. isAllowedToMint function checks various signals to return boolean value for whether an address is eligible or not.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/OptimistAllowlistProxy.json b/packages/contracts-bedrock/deployments/optimism-goerli/OptimistAllowlistProxy.json deleted file mode 100644 index 4e821b79b1a8..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/OptimistAllowlistProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x482b1945D58f2E9Db0CEbe13c7fcFc6876b41180", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x1ad6d371fc1567fe96ef97bf4d1b0446a0df8bca5b4bbe36391a8b8039982f21", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 1, - "gasUsed": "534190", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000400000000000000000000000000000000000000000000", - "blockHash": "0x76d8f7991f381ae9eabc900e5684fbb8e1d29b4b22e539ec5369d3f15ae4372d", - "transactionHash": "0x1ad6d371fc1567fe96ef97bf4d1b0446a0df8bca5b4bbe36391a8b8039982f21", - "logs": [ - { - "transactionIndex": 1, - "blockNumber": 7691644, - "transactionHash": "0x1ad6d371fc1567fe96ef97bf4d1b0446a0df8bca5b4bbe36391a8b8039982f21", - "address": "0x482b1945D58f2E9Db0CEbe13c7fcFc6876b41180", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58", - "logIndex": 0, - "blockHash": "0x76d8f7991f381ae9eabc900e5684fbb8e1d29b4b22e539ec5369d3f15ae4372d" - } - ], - "blockNumber": 7691644, - "cumulativeGasUsed": "598191", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "d7155764d4bdb814f10e1bb45296292b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) public virtual proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n public\\n payable\\n virtual\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) public virtual proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() public virtual proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() public virtual proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea26469706673582212200496188e743eb5556ea8662e234845601d39477882517acc1cf9061fcc51284c64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea26469706673582212200496188e743eb5556ea8662e234845601d39477882517acc1cf9061fcc51284c64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/OptimistInviter.json b/packages/contracts-bedrock/deployments/optimism-goerli/OptimistInviter.json deleted file mode 100644 index 899002bc91c1..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/OptimistInviter.json +++ /dev/null @@ -1,543 +0,0 @@ -{ - "address": "0xe256605bE52B0758fd70E07953dD36fABF9beFd2", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_inviteGranter", - "type": "address" - }, - { - "internalType": "contract AttestationStation", - "name": "_attestationStation", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "issuer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "claimer", - "type": "address" - } - ], - "name": "InviteClaimed", - "type": "event" - }, - { - "inputs": [], - "name": "ATTESTATION_STATION", - "outputs": [ - { - "internalType": "contract AttestationStation", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "CAN_INVITE_ATTESTATION_KEY", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "CLAIMABLE_INVITE_TYPEHASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "EIP712_VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INVITE_GRANTER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_COMMITMENT_PERIOD", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_claimer", - "type": "address" - }, - { - "components": [ - { - "internalType": "address", - "name": "issuer", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "nonce", - "type": "bytes32" - } - ], - "internalType": "struct OptimistInviter.ClaimableInvite", - "name": "_claimableInvite", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "_signature", - "type": "bytes" - } - ], - "name": "claimInvite", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_commitment", - "type": "bytes32" - } - ], - "name": "commitInvite", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "commitmentTimestamps", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "inviteCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "_accounts", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "_inviteCount", - "type": "uint256" - } - ], - "name": "setInviteCounts", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "usedNonces", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x142dcc7b21e97d2199e3c086e0dd94e3293549aea1373c3a856fdf1065a27101", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 3, - "gasUsed": "1650064", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1f493311ad79e9a938942359c85bf059eac56d3b52289012b283a4c9ebb5ec61", - "transactionHash": "0x142dcc7b21e97d2199e3c086e0dd94e3293549aea1373c3a856fdf1065a27101", - "logs": [], - "blockNumber": 7690225, - "cumulativeGasUsed": "2093837", - "status": 1, - "byzantium": true - }, - "args": [ - "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819", - "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77" - ], - "numDeployments": 1, - "solcInputHash": "d7155764d4bdb814f10e1bb45296292b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_inviteGranter\",\"type\":\"address\"},{\"internalType\":\"contract AttestationStation\",\"name\":\"_attestationStation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"issuer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"claimer\",\"type\":\"address\"}],\"name\":\"InviteClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ATTESTATION_STATION\",\"outputs\":[{\"internalType\":\"contract AttestationStation\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"CAN_INVITE_ATTESTATION_KEY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"CLAIMABLE_INVITE_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"EIP712_VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INVITE_GRANTER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_COMMITMENT_PERIOD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_claimer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"issuer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OptimistInviter.ClaimableInvite\",\"name\":\"_claimableInvite\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"claimInvite\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_commitment\",\"type\":\"bytes32\"}],\"name\":\"commitInvite\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"commitmentTimestamps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"inviteCounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_accounts\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_inviteCount\",\"type\":\"uint256\"}],\"name\":\"setInviteCounts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"usedNonces\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"custom:upgradeable\":\"@title OptimistInviter\",\"events\":{\"InviteClaimed(address,address)\":{\"params\":{\"claimer\":\"Address that claimed the invite.\",\"issuer\":\"Address that issued the signature.\"}}},\"kind\":\"dev\",\"methods\":{\"claimInvite(address,(address,bytes32),bytes)\":{\"params\":{\"_claimableInvite\":\"ClaimableInvite struct containing the issuer and nonce.\",\"_claimer\":\"Address that will be granted the invite.\",\"_signature\":\"Signature signed over the claimable invite.\"}},\"commitInvite(bytes32)\":{\"params\":{\"_commitment\":\"A hash of the claimer and signature concatenated. keccak256(abi.encode(_claimer, _signature))\"}},\"constructor\":{\"custom:semver\":\"1.0.0\",\"params\":{\"_attestationStation\":\"Address of the AttestationStation contract.\",\"_inviteGranter\":\"Address of the invite granter.\"}},\"initialize(string)\":{\"params\":{\"_name\":\"Contract name.\"}},\"setInviteCounts(address[],uint256)\":{\"params\":{\"_accounts\":\"An array of accounts to update the invite counts of.\",\"_inviteCount\":\"Number of invites to set to.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"version\":1},\"userdoc\":{\"events\":{\"InviteClaimed(address,address)\":{\"notice\":\"Emitted when an invite is claimed.\"}},\"kind\":\"user\",\"methods\":{\"ATTESTATION_STATION()\":{\"notice\":\"Address of the AttestationStation contract.\"},\"CAN_INVITE_ATTESTATION_KEY()\":{\"notice\":\"Attestation key for that signals that an account was allowed to issue invites\"},\"CLAIMABLE_INVITE_TYPEHASH()\":{\"notice\":\"EIP712 typehash for the ClaimableInvite type.\"},\"EIP712_VERSION()\":{\"notice\":\"Version used for the EIP712 domain separator. This version is separated from the contract semver because the EIP712 domain separator is used to sign messages, and changing the domain separator invalidates all existing signatures. We should only bump this version if we make a major change to the signature scheme.\"},\"INVITE_GRANTER()\":{\"notice\":\"Granter who can set accounts' invite counts.\"},\"MIN_COMMITMENT_PERIOD()\":{\"notice\":\"Minimum age of a commitment (in seconds) before it can be revealed using claimInvite. Currently set to 60 seconds. Prevents an attacker from front-running a commitment by taking the signature in the claimInvite call and quickly committing and claiming it before the the claimer's transaction succeeds. With this, frontrunning a commitment requires that an attacker be able to prevent the honest claimer's claimInvite transaction from being included for this long.\"},\"claimInvite(address,(address,bytes32),bytes)\":{\"notice\":\"Allows anyone to reveal a commitment and claim an invite. The hash, keccak256(abi.encode(_claimer, _signature)), should have been already committed using commitInvite. Before issuing the \\\"optimist.can-mint-from-invite\\\" attestation, this function checks that 1) the hash corresponding to the _claimer and the _signature was committed 2) MIN_COMMITMENT_PERIOD has passed since the commitment was made. 3) the _signature is signed correctly by the issuer 4) the _signature hasn't already been used to claim an invite before 5) the _signature issuer has not used up all of their invites This function doesn't require that the _claimer is calling this function.\"},\"commitInvite(bytes32)\":{\"notice\":\"Allows anyone (but likely the claimer) to commit a received signature along with the address to claim to. Before calling this function, the claimer should have received a signature from the issuer off-chain. The claimer then calls this function with the hash of the claimer's address and the received signature. This is necessary to prevent front-running when the invitee is claiming the invite. Without a commit and reveal scheme, anyone who is watching the mempool can take the signature being submitted and front run the transaction to claim the invite to their own address. The same commitment can only be made once, and the function reverts if the commitment has already been made. This prevents griefing where a malicious party can prevent the original claimer from being able to claimInvite.\"},\"commitmentTimestamps(bytes32)\":{\"notice\":\"Maps from hashes to the timestamp when they were committed.\"},\"initialize(string)\":{\"notice\":\"Initializes this contract, setting the EIP712 context. Only update the EIP712_VERSION when there is a change to the signature scheme. After the EIP712 version is changed, any signatures issued off-chain but not claimed yet will no longer be accepted by the claimInvite function. Please make sure to notify the issuers that they must re-issue their invite signatures.\"},\"inviteCounts(address)\":{\"notice\":\"Maps from addresses to number of invites they have.\"},\"setInviteCounts(address[],uint256)\":{\"notice\":\"Allows invite granter to set the number of invites an address has.\"},\"usedNonces(address,bytes32)\":{\"notice\":\"Maps from addresses to nonces to whether or not they have been used.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"OptimistInviter issues \\\"optimist.can-invite\\\" and \\\"optimist.can-mint-from-invite\\\" attestations. Accounts that have invites can issue signatures that allow other accounts to claim an invite. The invitee uses a claim and reveal flow to claim the invite to an address of their choosing. Parties involved: 1) INVITE_GRANTER: trusted account that can allow accounts to issue invites 2) issuer: account that is allowed to issue invites 3) claimer: account that receives the invites Flow: 1) INVITE_GRANTER calls _setInviteCount to allow an issuer to issue a certain number of invites, and also creates a \\\"optimist.can-invite\\\" attestation for the issuer 2) Off-chain, the issuer signs (EIP-712) a ClaimableInvite to produce a signature 3) Off-chain, invite issuer sends the plaintext ClaimableInvite and the signature to the recipient 4) claimer chooses an address they want to receive the invite on 5) claimer commits the hash of the address they want to receive the invite on and the received signature keccak256(abi.encode(addressToReceiveTo, receivedSignature)) using the commitInvite function 6) claimer waits for the MIN_COMMITMENT_PERIOD to pass. 7) claimer reveals the plaintext ClaimableInvite and the signature using the claimInvite function, receiving the \\\"optimist.can-mint-from-invite\\\" attestation\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/OptimistInviter.sol\":\"OptimistInviter\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xbf5daf926894541a40a64b43c3746aa1940c5a1b3b8d14a06465eea72a9b90cc\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb7f5c28fc61cda0bd8ab60ce288e206b791643bcd3ba464a70cbec18895a2f5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.1) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../Address.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n if (error == ECDSA.RecoverError.NoError && recovered == signer) {\\n return true;\\n }\\n\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length == 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0xbb5c92a62f2a917ec08667ebc024d5f4172ae3594cd5f4eaa997485ed0440d81\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of AttestationData structs.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x421923e04df145353db12cd0352ccf516d9c29ab64b138733b4f7a6a450ce2be\",\"license\":\"MIT\"},\"contracts/universal/op-nft/OptimistInviter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { OptimistConstants } from \\\"./libraries/OptimistConstants.sol\\\";\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\nimport { AttestationStation } from \\\"./AttestationStation.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {\\n EIP712Upgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\n\\n/**\\n * @custom:upgradeable\\n * @title OptimistInviter\\n * @notice OptimistInviter issues \\\"optimist.can-invite\\\" and \\\"optimist.can-mint-from-invite\\\"\\n * attestations. Accounts that have invites can issue signatures that allow other\\n * accounts to claim an invite. The invitee uses a claim and reveal flow to claim the\\n * invite to an address of their choosing.\\n *\\n * Parties involved:\\n * 1) INVITE_GRANTER: trusted account that can allow accounts to issue invites\\n * 2) issuer: account that is allowed to issue invites\\n * 3) claimer: account that receives the invites\\n *\\n * Flow:\\n * 1) INVITE_GRANTER calls _setInviteCount to allow an issuer to issue a certain number\\n * of invites, and also creates a \\\"optimist.can-invite\\\" attestation for the issuer\\n * 2) Off-chain, the issuer signs (EIP-712) a ClaimableInvite to produce a signature\\n * 3) Off-chain, invite issuer sends the plaintext ClaimableInvite and the signature\\n * to the recipient\\n * 4) claimer chooses an address they want to receive the invite on\\n * 5) claimer commits the hash of the address they want to receive the invite on and the\\n * received signature keccak256(abi.encode(addressToReceiveTo, receivedSignature))\\n * using the commitInvite function\\n * 6) claimer waits for the MIN_COMMITMENT_PERIOD to pass.\\n * 7) claimer reveals the plaintext ClaimableInvite and the signature using the\\n * claimInvite function, receiving the \\\"optimist.can-mint-from-invite\\\" attestation\\n */\\ncontract OptimistInviter is Semver, EIP712Upgradeable {\\n /**\\n * @notice Emitted when an invite is claimed.\\n *\\n * @param issuer Address that issued the signature.\\n * @param claimer Address that claimed the invite.\\n */\\n event InviteClaimed(address indexed issuer, address indexed claimer);\\n\\n /**\\n * @notice Version used for the EIP712 domain separator. This version is separated from the\\n * contract semver because the EIP712 domain separator is used to sign messages, and\\n * changing the domain separator invalidates all existing signatures. We should only\\n * bump this version if we make a major change to the signature scheme.\\n */\\n string public constant EIP712_VERSION = \\\"1.0.0\\\";\\n\\n /**\\n * @notice EIP712 typehash for the ClaimableInvite type.\\n */\\n bytes32 public constant CLAIMABLE_INVITE_TYPEHASH =\\n keccak256(\\\"ClaimableInvite(address issuer,bytes32 nonce)\\\");\\n\\n /**\\n * @notice Attestation key for that signals that an account was allowed to issue invites\\n */\\n bytes32 public constant CAN_INVITE_ATTESTATION_KEY = bytes32(\\\"optimist.can-invite\\\");\\n\\n /**\\n * @notice Granter who can set accounts' invite counts.\\n */\\n address public immutable INVITE_GRANTER;\\n\\n /**\\n * @notice Address of the AttestationStation contract.\\n */\\n AttestationStation public immutable ATTESTATION_STATION;\\n\\n /**\\n * @notice Minimum age of a commitment (in seconds) before it can be revealed using claimInvite.\\n * Currently set to 60 seconds.\\n *\\n * Prevents an attacker from front-running a commitment by taking the signature in the\\n * claimInvite call and quickly committing and claiming it before the the claimer's\\n * transaction succeeds. With this, frontrunning a commitment requires that an attacker\\n * be able to prevent the honest claimer's claimInvite transaction from being included\\n * for this long.\\n */\\n uint256 public constant MIN_COMMITMENT_PERIOD = 60;\\n\\n /**\\n * @notice Struct that represents a claimable invite that will be signed by the issuer.\\n *\\n * @custom:field issuer Address that issued the signature. Reason this is explicitly included,\\n * and not implicitly assumed to be the recovered address from the\\n * signature is that the issuer may be using a ERC-1271 compatible\\n * contract wallet, where the recovered address is not the same as the\\n * issuer, or the signature is not an ECDSA signature at all.\\n * @custom:field nonce Pseudorandom nonce to prevent replay attacks.\\n */\\n struct ClaimableInvite {\\n address issuer;\\n bytes32 nonce;\\n }\\n\\n /**\\n * @notice Maps from hashes to the timestamp when they were committed.\\n */\\n mapping(bytes32 => uint256) public commitmentTimestamps;\\n\\n /**\\n * @notice Maps from addresses to nonces to whether or not they have been used.\\n */\\n mapping(address => mapping(bytes32 => bool)) public usedNonces;\\n\\n /**\\n * @notice Maps from addresses to number of invites they have.\\n */\\n mapping(address => uint256) public inviteCounts;\\n\\n /**\\n * @custom:semver 1.0.0\\n *\\n * @param _inviteGranter Address of the invite granter.\\n * @param _attestationStation Address of the AttestationStation contract.\\n */\\n constructor(address _inviteGranter, AttestationStation _attestationStation) Semver(1, 0, 0) {\\n INVITE_GRANTER = _inviteGranter;\\n ATTESTATION_STATION = _attestationStation;\\n }\\n\\n /**\\n * @notice Initializes this contract, setting the EIP712 context.\\n *\\n * Only update the EIP712_VERSION when there is a change to the signature scheme.\\n * After the EIP712 version is changed, any signatures issued off-chain but not\\n * claimed yet will no longer be accepted by the claimInvite function. Please make\\n * sure to notify the issuers that they must re-issue their invite signatures.\\n *\\n * @param _name Contract name.\\n */\\n function initialize(string memory _name) public initializer {\\n __EIP712_init(_name, EIP712_VERSION);\\n }\\n\\n /**\\n * @notice Allows invite granter to set the number of invites an address has.\\n *\\n * @param _accounts An array of accounts to update the invite counts of.\\n * @param _inviteCount Number of invites to set to.\\n */\\n function setInviteCounts(address[] calldata _accounts, uint256 _inviteCount) public {\\n // Only invite granter can grant invites\\n require(\\n msg.sender == INVITE_GRANTER,\\n \\\"OptimistInviter: only invite granter can grant invites\\\"\\n );\\n\\n uint256 length = _accounts.length;\\n\\n AttestationStation.AttestationData[]\\n memory attestations = new AttestationStation.AttestationData[](length);\\n\\n for (uint256 i; i < length; ) {\\n // Set invite count for account to _inviteCount\\n inviteCounts[_accounts[i]] = _inviteCount;\\n\\n // Create an attestation for posterity that the account is allowed to create invites\\n attestations[i] = AttestationStation.AttestationData({\\n about: _accounts[i],\\n key: CAN_INVITE_ATTESTATION_KEY,\\n val: bytes(\\\"true\\\")\\n });\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n ATTESTATION_STATION.attest(attestations);\\n }\\n\\n /**\\n * @notice Allows anyone (but likely the claimer) to commit a received signature along with the\\n * address to claim to.\\n *\\n * Before calling this function, the claimer should have received a signature from the\\n * issuer off-chain. The claimer then calls this function with the hash of the\\n * claimer's address and the received signature. This is necessary to prevent\\n * front-running when the invitee is claiming the invite. Without a commit and reveal\\n * scheme, anyone who is watching the mempool can take the signature being submitted\\n * and front run the transaction to claim the invite to their own address.\\n *\\n * The same commitment can only be made once, and the function reverts if the\\n * commitment has already been made. This prevents griefing where a malicious party can\\n * prevent the original claimer from being able to claimInvite.\\n *\\n *\\n * @param _commitment A hash of the claimer and signature concatenated.\\n * keccak256(abi.encode(_claimer, _signature))\\n */\\n function commitInvite(bytes32 _commitment) public {\\n // Check that the commitment hasn't already been made. This prevents griefing where\\n // a malicious party continuously re-submits the same commitment, preventing the original\\n // claimer from claiming their invite by resetting the minimum commitment period.\\n require(commitmentTimestamps[_commitment] == 0, \\\"OptimistInviter: commitment already made\\\");\\n\\n commitmentTimestamps[_commitment] = block.timestamp;\\n }\\n\\n /**\\n * @notice Allows anyone to reveal a commitment and claim an invite.\\n *\\n * The hash, keccak256(abi.encode(_claimer, _signature)), should have been already\\n * committed using commitInvite. Before issuing the \\\"optimist.can-mint-from-invite\\\"\\n * attestation, this function checks that\\n * 1) the hash corresponding to the _claimer and the _signature was committed\\n * 2) MIN_COMMITMENT_PERIOD has passed since the commitment was made.\\n * 3) the _signature is signed correctly by the issuer\\n * 4) the _signature hasn't already been used to claim an invite before\\n * 5) the _signature issuer has not used up all of their invites\\n * This function doesn't require that the _claimer is calling this function.\\n *\\n * @param _claimer Address that will be granted the invite.\\n * @param _claimableInvite ClaimableInvite struct containing the issuer and nonce.\\n * @param _signature Signature signed over the claimable invite.\\n */\\n function claimInvite(\\n address _claimer,\\n ClaimableInvite calldata _claimableInvite,\\n bytes memory _signature\\n ) public {\\n uint256 commitmentTimestamp = commitmentTimestamps[\\n keccak256(abi.encode(_claimer, _signature))\\n ];\\n\\n // Make sure the claimer and signature have been committed.\\n require(\\n commitmentTimestamp > 0,\\n \\\"OptimistInviter: claimer and signature have not been committed yet\\\"\\n );\\n\\n // Check that MIN_COMMITMENT_PERIOD has passed since the commitment was made.\\n require(\\n commitmentTimestamp + MIN_COMMITMENT_PERIOD <= block.timestamp,\\n \\\"OptimistInviter: minimum commitment period has not elapsed yet\\\"\\n );\\n\\n // Generate a EIP712 typed data hash to compare against the signature.\\n bytes32 digest = _hashTypedDataV4(\\n keccak256(\\n abi.encode(\\n CLAIMABLE_INVITE_TYPEHASH,\\n _claimableInvite.issuer,\\n _claimableInvite.nonce\\n )\\n )\\n );\\n\\n // Uses SignatureChecker, which supports both regular ECDSA signatures from EOAs as well as\\n // ERC-1271 signatures from contract wallets or multi-sigs. This means that if the issuer\\n // wants to revoke a signature, they can use a smart contract wallet to issue the signature,\\n // then invalidate the signature after issuing it.\\n require(\\n SignatureChecker.isValidSignatureNow(_claimableInvite.issuer, digest, _signature),\\n \\\"OptimistInviter: invalid signature\\\"\\n );\\n\\n // The issuer's signature commits to a nonce to prevent replay attacks.\\n // This checks that the nonce has not been used for this issuer before. The nonces are\\n // scoped to the issuer address, so the same nonce can be used by different issuers without\\n // clashing.\\n require(\\n usedNonces[_claimableInvite.issuer][_claimableInvite.nonce] == false,\\n \\\"OptimistInviter: nonce has already been used\\\"\\n );\\n\\n // Set the nonce as used for the issuer so that it cannot be replayed.\\n usedNonces[_claimableInvite.issuer][_claimableInvite.nonce] = true;\\n\\n // Failing this check means that the issuer has used up all of their existing invites.\\n require(\\n inviteCounts[_claimableInvite.issuer] > 0,\\n \\\"OptimistInviter: issuer has no invites\\\"\\n );\\n\\n // Reduce the issuer's invite count by 1. Can be unchecked because we check above that\\n // count is > 0.\\n unchecked {\\n --inviteCounts[_claimableInvite.issuer];\\n }\\n\\n // Create the attestation that the claimer can mint from the issuer's invite.\\n // The invite issuer is included in the data of the attestation.\\n ATTESTATION_STATION.attest(\\n _claimer,\\n OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY,\\n abi.encode(_claimableInvite.issuer)\\n );\\n\\n emit InviteClaimed(_claimableInvite.issuer, _claimer);\\n }\\n}\\n\",\"keccak256\":\"0xd7b006570c7e0c66ed0a8001c7e57848062913639e65f5bb6f4d8120e2a00c32\",\"license\":\"MIT\"},\"contracts/universal/op-nft/libraries/OptimistConstants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title OptimistConstants\\n * @notice Library for storing Optimist related constants that are shared in multiple contracts.\\n */\\n\\nlibrary OptimistConstants {\\n /**\\n * @notice Attestation key issued by OptimistInviter allowing the attested account to mint.\\n */\\n bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY =\\n bytes32(\\\"optimist.can-mint-from-invite\\\");\\n}\\n\",\"keccak256\":\"0x6eebe1db87f8a5de79bf8af9120e5b0cc6a9b51d8d86e6461cdb6bc52a1dde21\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6101206040523480156200001257600080fd5b5060405162001e0938038062001e09833981016040819052620000359162000076565b6001608052600060a081905260c0526001600160a01b0391821660e0521661010052620000b5565b6001600160a01b03811681146200007357600080fd5b50565b600080604083850312156200008a57600080fd5b825162000097816200005d565b6020840151909250620000aa816200005d565b809150509250929050565b60805160a05160c05160e05161010051611cfb6200010e60003960008181610257015281816106510152610c0201526000818160f401526103b401526000610da101526000610d7801526000610d4f0152611cfb6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063916db22f1161008c578063db083d7111610066578063db083d7114610252578063de2dd22114610279578063eccec5a814610299578063f62d1888146102d557600080fd5b8063916db22f146101e4578063b4245d731461020b578063c4fc453d1461022b57600080fd5b806350b414e6116100c857806350b414e61461016857806350eedbc21461017e57806354fd4d50146101915780635fda04c7146101a657600080fd5b806314b47241146100ef578063187e3cd11461014057806325b27a3d14610155575b600080fd5b6101167f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61015361014e36600461165f565b6102e8565b005b610153610163366004611678565b61039c565b610170603c81565b604051908152602001610137565b61015361018c3660046117df565b6106bf565b610199610d48565b60405161013791906118f5565b6101d46101b4366004611908565b603660209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610137565b6101707f6f7074696d6973742e63616e2d696e766974650000000000000000000000000081565b61017061021936600461165f565b60356020526000908152604090205481565b6101707f6529fd129351e725d7bcbc468b0b0b4675477e56b58514e69ab7e66ddfd20fce81565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b610170610287366004611932565b60376020526000908152604090205481565b6101996040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6101536102e336600461194d565b610deb565b60008181526035602052604090205415610389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4f7074696d697374496e76697465723a20636f6d6d69746d656e7420616c726560448201527f616479206d61646500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000908152603560205260409020429055565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4f7074696d697374496e76697465723a206f6e6c7920696e766974652067726160448201527f6e7465722063616e206772616e7420696e7669746573000000000000000000006064820152608401610380565b8160008167ffffffffffffffff81111561047d5761047d61171c565b6040519080825280602002602001820160405280156104ca57816020015b6040805160608082018352600080835260208301529181019190915281526020019060019003908161049b5790505b50905060005b828110156106135783603760008888858181106104ef576104ef611996565b90506020020160208101906105049190611932565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550604051806060016040528087878481811061055f5761055f611996565b90506020020160208101906105749190611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020017f6f7074696d6973742e63616e2d696e766974650000000000000000000000000081526020016040518060400160405280600481526020017f747275650000000000000000000000000000000000000000000000000000000081525081525082828151811061060057610600611996565b60209081029190910101526001016104d0565b506040517f5eb5ea1000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690635eb5ea10906106869084906004016119c5565b600060405180830381600087803b1580156106a057600080fd5b505af11580156106b4573d6000803e3d6000fd5b505050505050505050565b60006035600085846040516020016106d8929190611a78565b604051602081830303815290604052805190602001208152602001908152602001600020549050600081116107b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f4f7074696d697374496e76697465723a20636c61696d657220616e642073696760448201527f6e61747572652068617665206e6f74206265656e20636f6d6d6974746564207960648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a401610380565b426107c1603c83611ad6565b111561084f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f7074696d697374496e76697465723a206d696e696d756d20636f6d6d69746d60448201527f656e7420706572696f6420686173206e6f7420656c61707365642079657400006064820152608401610380565b60006108d27f6529fd129351e725d7bcbc468b0b0b4675477e56b58514e69ab7e66ddfd20fce6108826020870187611932565b6040805160208181019490945273ffffffffffffffffffffffffffffffffffffffff9092169082015290860135606082015260800160405160208183030381529060405280519060200120610fb5565b90506108eb6108e46020860186611932565b8285611024565b610977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4f7074696d697374496e76697465723a20696e76616c6964207369676e61747560448201527f72650000000000000000000000000000000000000000000000000000000000006064820152608401610380565b603660006109886020870187611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020808201929092526040908101600090812087840135825290925290205460ff1615610a4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4f7074696d697374496e76697465723a206e6f6e63652068617320616c72656160448201527f6479206265656e207573656400000000000000000000000000000000000000006064820152608401610380565b600160366000610a626020880188611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020808201929092526040908101600090812088840180358352935290812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016931515939093179092556037908290610ad69088611932565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411610b9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f7074696d697374496e76697465723a2069737375657220686173206e6f206960448201527f6e766974657300000000000000000000000000000000000000000000000000006064820152608401610380565b60376000610baf6020870187611932565b73ffffffffffffffffffffffffffffffffffffffff9081168252602080830193909352604090910160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190557f0000000000000000000000000000000000000000000000000000000000000000169063702b9dee9087907f6f7074696d6973742e63616e2d6d696e742d66726f6d2d696e7669746500000090610c5990890189611932565b6040805173ffffffffffffffffffffffffffffffffffffffff9092166020830152016040516020818303038152906040526040518463ffffffff1660e01b8152600401610ca893929190611aee565b600060405180830381600087803b158015610cc257600080fd5b505af1158015610cd6573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff86169050610cff6020860186611932565b73ffffffffffffffffffffffffffffffffffffffff167f745d3c5bc92ab40b418069bf8f8e2030807effceb88bbaa07ee01574f16be47560405160405180910390a35050505050565b6060610d737f00000000000000000000000000000000000000000000000000000000000000006111f3565b610d9c7f00000000000000000000000000000000000000000000000000000000000000006111f3565b610dc57f00000000000000000000000000000000000000000000000000000000000000006111f3565b604051602001610dd793929190611b2c565b604051602081830303815290604052905090565b600054610100900460ff1615808015610e0b5750600054600160ff909116105b80610e255750303b158015610e25575060005460ff166001145b610eb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610380565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610f0f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610f4e826040518060400160405280600581526020017f312e302e30000000000000000000000000000000000000000000000000000000815250611330565b8015610fb157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600061101e610fc26113d1565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b92915050565b60008060006110338585611451565b9092509050600081600481111561104c5761104c611ba2565b14801561108457508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15611094576001925050506111ec565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016110c9929190611bd1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516111529190611bea565b600060405180830381855afa9150503d806000811461118d576040519150601f19603f3d011682016040523d82523d6000602084013e611192565b606091505b50915091508180156111a5575080516020145b80156111e5575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906111e39083016020908101908401611c06565b145b9450505050505b9392505050565b60608160000361123657505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611260578061124a81611c1f565b91506112599050600a83611c86565b915061123a565b60008167ffffffffffffffff81111561127b5761127b61171c565b6040519080825280601f01601f1916602001820160405280156112a5576020820181803683370190505b5090505b8415611328576112ba600183611c9a565b91506112c7600a86611cb1565b6112d2906030611ad6565b60f81b8183815181106112e7576112e7611996565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611321600a86611c86565b94506112a9565b949350505050565b600054610100900460ff166113c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610380565b610fb18282611496565b600061144c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61140060015490565b6002546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b905090565b60008082516041036114875760208301516040840151606085015160001a61147b87828585611547565b9450945050505061148f565b506000905060025b9250929050565b600054610100900460ff1661152d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610380565b815160209283012081519190920120600191909155600255565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561157e5750600090506003611656565b8460ff16601b1415801561159657508460ff16601c14155b156115a75750600090506004611656565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156115fb573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661164f57600060019250925050611656565b9150600090505b94509492505050565b60006020828403121561167157600080fd5b5035919050565b60008060006040848603121561168d57600080fd5b833567ffffffffffffffff808211156116a557600080fd5b818601915086601f8301126116b957600080fd5b8135818111156116c857600080fd5b8760208260051b85010111156116dd57600080fd5b6020928301989097509590910135949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461171757600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff808411156117665761176661171c565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156117ac576117ac61171c565b816040528093508581528686860111156117c557600080fd5b858560208301376000602087830101525050509392505050565b600080600083850360808112156117f557600080fd5b6117fe856116f3565b935060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561183057600080fd5b50602084019150606084013567ffffffffffffffff81111561185157600080fd5b8401601f8101861361186257600080fd5b6118718682356020840161174b565b9150509250925092565b60005b8381101561189657818101518382015260200161187e565b838111156118a5576000848401525b50505050565b600081518084526118c381602086016020860161187b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111ec60208301846118ab565b6000806040838503121561191b57600080fd5b611924836116f3565b946020939093013593505050565b60006020828403121561194457600080fd5b6111ec826116f3565b60006020828403121561195f57600080fd5b813567ffffffffffffffff81111561197657600080fd5b8201601f8101841361198757600080fd5b6113288482356020840161174b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611a6a578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287810151888501528601516060878501819052611a56818601836118ab565b9689019694505050908601906001016119ec565b509098975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061132860408301846118ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115611ae957611ae9611aa7565b500190565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611b2360608301846118ab565b95945050505050565b60008451611b3e81846020890161187b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611b7a816001850160208a0161187b565b60019201918201528351611b9581600284016020880161187b565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061132860408301846118ab565b60008251611bfc81846020870161187b565b9190910192915050565b600060208284031215611c1857600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c5057611c50611aa7565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611c9557611c95611c57565b500490565b600082821015611cac57611cac611aa7565b500390565b600082611cc057611cc0611c57565b50069056fea264697066735822122097f93936c2ea57902b86c424cff790fa55dccd81b007b045479cd5575c81c5d564736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063916db22f1161008c578063db083d7111610066578063db083d7114610252578063de2dd22114610279578063eccec5a814610299578063f62d1888146102d557600080fd5b8063916db22f146101e4578063b4245d731461020b578063c4fc453d1461022b57600080fd5b806350b414e6116100c857806350b414e61461016857806350eedbc21461017e57806354fd4d50146101915780635fda04c7146101a657600080fd5b806314b47241146100ef578063187e3cd11461014057806325b27a3d14610155575b600080fd5b6101167f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61015361014e36600461165f565b6102e8565b005b610153610163366004611678565b61039c565b610170603c81565b604051908152602001610137565b61015361018c3660046117df565b6106bf565b610199610d48565b60405161013791906118f5565b6101d46101b4366004611908565b603660209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610137565b6101707f6f7074696d6973742e63616e2d696e766974650000000000000000000000000081565b61017061021936600461165f565b60356020526000908152604090205481565b6101707f6529fd129351e725d7bcbc468b0b0b4675477e56b58514e69ab7e66ddfd20fce81565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b610170610287366004611932565b60376020526000908152604090205481565b6101996040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6101536102e336600461194d565b610deb565b60008181526035602052604090205415610389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4f7074696d697374496e76697465723a20636f6d6d69746d656e7420616c726560448201527f616479206d61646500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000908152603560205260409020429055565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4f7074696d697374496e76697465723a206f6e6c7920696e766974652067726160448201527f6e7465722063616e206772616e7420696e7669746573000000000000000000006064820152608401610380565b8160008167ffffffffffffffff81111561047d5761047d61171c565b6040519080825280602002602001820160405280156104ca57816020015b6040805160608082018352600080835260208301529181019190915281526020019060019003908161049b5790505b50905060005b828110156106135783603760008888858181106104ef576104ef611996565b90506020020160208101906105049190611932565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550604051806060016040528087878481811061055f5761055f611996565b90506020020160208101906105749190611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020017f6f7074696d6973742e63616e2d696e766974650000000000000000000000000081526020016040518060400160405280600481526020017f747275650000000000000000000000000000000000000000000000000000000081525081525082828151811061060057610600611996565b60209081029190910101526001016104d0565b506040517f5eb5ea1000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690635eb5ea10906106869084906004016119c5565b600060405180830381600087803b1580156106a057600080fd5b505af11580156106b4573d6000803e3d6000fd5b505050505050505050565b60006035600085846040516020016106d8929190611a78565b604051602081830303815290604052805190602001208152602001908152602001600020549050600081116107b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f4f7074696d697374496e76697465723a20636c61696d657220616e642073696760448201527f6e61747572652068617665206e6f74206265656e20636f6d6d6974746564207960648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a401610380565b426107c1603c83611ad6565b111561084f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f7074696d697374496e76697465723a206d696e696d756d20636f6d6d69746d60448201527f656e7420706572696f6420686173206e6f7420656c61707365642079657400006064820152608401610380565b60006108d27f6529fd129351e725d7bcbc468b0b0b4675477e56b58514e69ab7e66ddfd20fce6108826020870187611932565b6040805160208181019490945273ffffffffffffffffffffffffffffffffffffffff9092169082015290860135606082015260800160405160208183030381529060405280519060200120610fb5565b90506108eb6108e46020860186611932565b8285611024565b610977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4f7074696d697374496e76697465723a20696e76616c6964207369676e61747560448201527f72650000000000000000000000000000000000000000000000000000000000006064820152608401610380565b603660006109886020870187611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020808201929092526040908101600090812087840135825290925290205460ff1615610a4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4f7074696d697374496e76697465723a206e6f6e63652068617320616c72656160448201527f6479206265656e207573656400000000000000000000000000000000000000006064820152608401610380565b600160366000610a626020880188611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020808201929092526040908101600090812088840180358352935290812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016931515939093179092556037908290610ad69088611932565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411610b9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f7074696d697374496e76697465723a2069737375657220686173206e6f206960448201527f6e766974657300000000000000000000000000000000000000000000000000006064820152608401610380565b60376000610baf6020870187611932565b73ffffffffffffffffffffffffffffffffffffffff9081168252602080830193909352604090910160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190557f0000000000000000000000000000000000000000000000000000000000000000169063702b9dee9087907f6f7074696d6973742e63616e2d6d696e742d66726f6d2d696e7669746500000090610c5990890189611932565b6040805173ffffffffffffffffffffffffffffffffffffffff9092166020830152016040516020818303038152906040526040518463ffffffff1660e01b8152600401610ca893929190611aee565b600060405180830381600087803b158015610cc257600080fd5b505af1158015610cd6573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff86169050610cff6020860186611932565b73ffffffffffffffffffffffffffffffffffffffff167f745d3c5bc92ab40b418069bf8f8e2030807effceb88bbaa07ee01574f16be47560405160405180910390a35050505050565b6060610d737f00000000000000000000000000000000000000000000000000000000000000006111f3565b610d9c7f00000000000000000000000000000000000000000000000000000000000000006111f3565b610dc57f00000000000000000000000000000000000000000000000000000000000000006111f3565b604051602001610dd793929190611b2c565b604051602081830303815290604052905090565b600054610100900460ff1615808015610e0b5750600054600160ff909116105b80610e255750303b158015610e25575060005460ff166001145b610eb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610380565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610f0f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610f4e826040518060400160405280600581526020017f312e302e30000000000000000000000000000000000000000000000000000000815250611330565b8015610fb157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600061101e610fc26113d1565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b92915050565b60008060006110338585611451565b9092509050600081600481111561104c5761104c611ba2565b14801561108457508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15611094576001925050506111ec565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016110c9929190611bd1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516111529190611bea565b600060405180830381855afa9150503d806000811461118d576040519150601f19603f3d011682016040523d82523d6000602084013e611192565b606091505b50915091508180156111a5575080516020145b80156111e5575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906111e39083016020908101908401611c06565b145b9450505050505b9392505050565b60608160000361123657505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611260578061124a81611c1f565b91506112599050600a83611c86565b915061123a565b60008167ffffffffffffffff81111561127b5761127b61171c565b6040519080825280601f01601f1916602001820160405280156112a5576020820181803683370190505b5090505b8415611328576112ba600183611c9a565b91506112c7600a86611cb1565b6112d2906030611ad6565b60f81b8183815181106112e7576112e7611996565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611321600a86611c86565b94506112a9565b949350505050565b600054610100900460ff166113c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610380565b610fb18282611496565b600061144c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61140060015490565b6002546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b905090565b60008082516041036114875760208301516040840151606085015160001a61147b87828585611547565b9450945050505061148f565b506000905060025b9250929050565b600054610100900460ff1661152d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610380565b815160209283012081519190920120600191909155600255565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561157e5750600090506003611656565b8460ff16601b1415801561159657508460ff16601c14155b156115a75750600090506004611656565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156115fb573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661164f57600060019250925050611656565b9150600090505b94509492505050565b60006020828403121561167157600080fd5b5035919050565b60008060006040848603121561168d57600080fd5b833567ffffffffffffffff808211156116a557600080fd5b818601915086601f8301126116b957600080fd5b8135818111156116c857600080fd5b8760208260051b85010111156116dd57600080fd5b6020928301989097509590910135949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461171757600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff808411156117665761176661171c565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156117ac576117ac61171c565b816040528093508581528686860111156117c557600080fd5b858560208301376000602087830101525050509392505050565b600080600083850360808112156117f557600080fd5b6117fe856116f3565b935060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561183057600080fd5b50602084019150606084013567ffffffffffffffff81111561185157600080fd5b8401601f8101861361186257600080fd5b6118718682356020840161174b565b9150509250925092565b60005b8381101561189657818101518382015260200161187e565b838111156118a5576000848401525b50505050565b600081518084526118c381602086016020860161187b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111ec60208301846118ab565b6000806040838503121561191b57600080fd5b611924836116f3565b946020939093013593505050565b60006020828403121561194457600080fd5b6111ec826116f3565b60006020828403121561195f57600080fd5b813567ffffffffffffffff81111561197657600080fd5b8201601f8101841361198757600080fd5b6113288482356020840161174b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611a6a578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287810151888501528601516060878501819052611a56818601836118ab565b9689019694505050908601906001016119ec565b509098975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061132860408301846118ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115611ae957611ae9611aa7565b500190565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611b2360608301846118ab565b95945050505050565b60008451611b3e81846020890161187b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611b7a816001850160208a0161187b565b60019201918201528351611b9581600284016020880161187b565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061132860408301846118ab565b60008251611bfc81846020870161187b565b9190910192915050565b600060208284031215611c1857600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c5057611c50611aa7565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611c9557611c95611c57565b500490565b600082821015611cac57611cac611aa7565b500390565b600082611cc057611cc0611c57565b50069056fea264697066735822122097f93936c2ea57902b86c424cff790fa55dccd81b007b045479cd5575c81c5d564736f6c634300080f0033", - "devdoc": { - "custom:upgradeable": "@title OptimistInviter", - "events": { - "InviteClaimed(address,address)": { - "params": { - "claimer": "Address that claimed the invite.", - "issuer": "Address that issued the signature." - } - } - }, - "kind": "dev", - "methods": { - "claimInvite(address,(address,bytes32),bytes)": { - "params": { - "_claimableInvite": "ClaimableInvite struct containing the issuer and nonce.", - "_claimer": "Address that will be granted the invite.", - "_signature": "Signature signed over the claimable invite." - } - }, - "commitInvite(bytes32)": { - "params": { - "_commitment": "A hash of the claimer and signature concatenated. keccak256(abi.encode(_claimer, _signature))" - } - }, - "constructor": { - "custom:semver": "1.0.0", - "params": { - "_attestationStation": "Address of the AttestationStation contract.", - "_inviteGranter": "Address of the invite granter." - } - }, - "initialize(string)": { - "params": { - "_name": "Contract name." - } - }, - "setInviteCounts(address[],uint256)": { - "params": { - "_accounts": "An array of accounts to update the invite counts of.", - "_inviteCount": "Number of invites to set to." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "version": 1 - }, - "userdoc": { - "events": { - "InviteClaimed(address,address)": { - "notice": "Emitted when an invite is claimed." - } - }, - "kind": "user", - "methods": { - "ATTESTATION_STATION()": { - "notice": "Address of the AttestationStation contract." - }, - "CAN_INVITE_ATTESTATION_KEY()": { - "notice": "Attestation key for that signals that an account was allowed to issue invites" - }, - "CLAIMABLE_INVITE_TYPEHASH()": { - "notice": "EIP712 typehash for the ClaimableInvite type." - }, - "EIP712_VERSION()": { - "notice": "Version used for the EIP712 domain separator. This version is separated from the contract semver because the EIP712 domain separator is used to sign messages, and changing the domain separator invalidates all existing signatures. We should only bump this version if we make a major change to the signature scheme." - }, - "INVITE_GRANTER()": { - "notice": "Granter who can set accounts' invite counts." - }, - "MIN_COMMITMENT_PERIOD()": { - "notice": "Minimum age of a commitment (in seconds) before it can be revealed using claimInvite. Currently set to 60 seconds. Prevents an attacker from front-running a commitment by taking the signature in the claimInvite call and quickly committing and claiming it before the the claimer's transaction succeeds. With this, frontrunning a commitment requires that an attacker be able to prevent the honest claimer's claimInvite transaction from being included for this long." - }, - "claimInvite(address,(address,bytes32),bytes)": { - "notice": "Allows anyone to reveal a commitment and claim an invite. The hash, keccak256(abi.encode(_claimer, _signature)), should have been already committed using commitInvite. Before issuing the \"optimist.can-mint-from-invite\" attestation, this function checks that 1) the hash corresponding to the _claimer and the _signature was committed 2) MIN_COMMITMENT_PERIOD has passed since the commitment was made. 3) the _signature is signed correctly by the issuer 4) the _signature hasn't already been used to claim an invite before 5) the _signature issuer has not used up all of their invites This function doesn't require that the _claimer is calling this function." - }, - "commitInvite(bytes32)": { - "notice": "Allows anyone (but likely the claimer) to commit a received signature along with the address to claim to. Before calling this function, the claimer should have received a signature from the issuer off-chain. The claimer then calls this function with the hash of the claimer's address and the received signature. This is necessary to prevent front-running when the invitee is claiming the invite. Without a commit and reveal scheme, anyone who is watching the mempool can take the signature being submitted and front run the transaction to claim the invite to their own address. The same commitment can only be made once, and the function reverts if the commitment has already been made. This prevents griefing where a malicious party can prevent the original claimer from being able to claimInvite." - }, - "commitmentTimestamps(bytes32)": { - "notice": "Maps from hashes to the timestamp when they were committed." - }, - "initialize(string)": { - "notice": "Initializes this contract, setting the EIP712 context. Only update the EIP712_VERSION when there is a change to the signature scheme. After the EIP712 version is changed, any signatures issued off-chain but not claimed yet will no longer be accepted by the claimInvite function. Please make sure to notify the issuers that they must re-issue their invite signatures." - }, - "inviteCounts(address)": { - "notice": "Maps from addresses to number of invites they have." - }, - "setInviteCounts(address[],uint256)": { - "notice": "Allows invite granter to set the number of invites an address has." - }, - "usedNonces(address,bytes32)": { - "notice": "Maps from addresses to nonces to whether or not they have been used." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "OptimistInviter issues \"optimist.can-invite\" and \"optimist.can-mint-from-invite\" attestations. Accounts that have invites can issue signatures that allow other accounts to claim an invite. The invitee uses a claim and reveal flow to claim the invite to an address of their choosing. Parties involved: 1) INVITE_GRANTER: trusted account that can allow accounts to issue invites 2) issuer: account that is allowed to issue invites 3) claimer: account that receives the invites Flow: 1) INVITE_GRANTER calls _setInviteCount to allow an issuer to issue a certain number of invites, and also creates a \"optimist.can-invite\" attestation for the issuer 2) Off-chain, the issuer signs (EIP-712) a ClaimableInvite to produce a signature 3) Off-chain, invite issuer sends the plaintext ClaimableInvite and the signature to the recipient 4) claimer chooses an address they want to receive the invite on 5) claimer commits the hash of the address they want to receive the invite on and the received signature keccak256(abi.encode(addressToReceiveTo, receivedSignature)) using the commitInvite function 6) claimer waits for the MIN_COMMITMENT_PERIOD to pass. 7) claimer reveals the plaintext ClaimableInvite and the signature using the claimInvite function, receiving the \"optimist.can-mint-from-invite\" attestation", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 1166, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 1169, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 3321, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "_HASHED_NAME", - "offset": 0, - "slot": "1", - "type": "t_bytes32" - }, - { - "astId": 3323, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "_HASHED_VERSION", - "offset": 0, - "slot": "2", - "type": "t_bytes32" - }, - { - "astId": 3461, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "__gap", - "offset": 0, - "slot": "3", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 5494, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "commitmentTimestamps", - "offset": 0, - "slot": "53", - "type": "t_mapping(t_bytes32,t_uint256)" - }, - { - "astId": 5501, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "usedNonces", - "offset": 0, - "slot": "54", - "type": "t_mapping(t_address,t_mapping(t_bytes32,t_bool))" - }, - { - "astId": 5506, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "inviteCounts", - "offset": 0, - "slot": "55", - "type": "t_mapping(t_address,t_uint256)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)50_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_bytes32,t_bool))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(bytes32 => bool))", - "numberOfBytes": "32", - "value": "t_mapping(t_bytes32,t_bool)" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_mapping(t_bytes32,t_bool)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_mapping(t_bytes32,t_uint256)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/OptimistInviterProxy.json b/packages/contracts-bedrock/deployments/optimism-goerli/OptimistInviterProxy.json deleted file mode 100644 index cd73860c7799..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/OptimistInviterProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x073031A1E1b8F5458Ed41Ce56331F5fd7e1de929", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x49b84cb498f5e256c0bcc616fd1c1d262c5cd01b67339f8eb9c9cd4ff26f5b90", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 1, - "gasUsed": "534190", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080010000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x711ca7182301afd7a0be34c2ba3e6d693b22723d4609944a77dca738911aa336", - "transactionHash": "0x49b84cb498f5e256c0bcc616fd1c1d262c5cd01b67339f8eb9c9cd4ff26f5b90", - "logs": [ - { - "transactionIndex": 1, - "blockNumber": 7690255, - "transactionHash": "0x49b84cb498f5e256c0bcc616fd1c1d262c5cd01b67339f8eb9c9cd4ff26f5b90", - "address": "0x073031A1E1b8F5458Ed41Ce56331F5fd7e1de929", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58", - "logIndex": 0, - "blockHash": "0x711ca7182301afd7a0be34c2ba3e6d693b22723d4609944a77dca738911aa336" - } - ], - "blockNumber": 7690255, - "cumulativeGasUsed": "581103", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "d7155764d4bdb814f10e1bb45296292b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) public virtual proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n public\\n payable\\n virtual\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) public virtual proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() public virtual proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() public virtual proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea26469706673582212200496188e743eb5556ea8662e234845601d39477882517acc1cf9061fcc51284c64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea26469706673582212200496188e743eb5556ea8662e234845601d39477882517acc1cf9061fcc51284c64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/OptimistProxy.json b/packages/contracts-bedrock/deployments/optimism-goerli/OptimistProxy.json deleted file mode 100644 index 099c6d45c790..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/OptimistProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x890d2852461118f7847e5d9d1d5cf04714dc2aba8e279a5a06fd32e6415c3d1c", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "534190", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000020000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x82b49133e92eddff1adca6bd3d902c0a54ccc681bf917ed8116c03133b1c32e7", - "transactionHash": "0x890d2852461118f7847e5d9d1d5cf04714dc2aba8e279a5a06fd32e6415c3d1c", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 3451420, - "transactionHash": "0x890d2852461118f7847e5d9d1d5cf04714dc2aba8e279a5a06fd32e6415c3d1c", - "address": "0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58", - "logIndex": 0, - "blockHash": "0x82b49133e92eddff1adca6bd3d902c0a54ccc681bf917ed8116c03133b1c32e7" - } - ], - "blockNumber": 3451420, - "cumulativeGasUsed": "534190", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "45837d34ff24b9cb2ae34232b60ea874", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n external\\n payable\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() external proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() external proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/SchemaRegistry.json b/packages/contracts-bedrock/deployments/optimism-goerli/SchemaRegistry.json deleted file mode 100644 index 24af8ddc658c..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/SchemaRegistry.json +++ /dev/null @@ -1,293 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "AlreadyExists", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "registerer", - "type": "address" - } - ], - "name": "Registered", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - } - ], - "name": "getSchema", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "contract ISchemaResolver", - "name": "resolver", - "type": "address" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "string", - "name": "schema", - "type": "string" - } - ], - "internalType": "struct SchemaRecord", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "schema", - "type": "string" - }, - { - "internalType": "contract ISchemaResolver", - "name": "resolver", - "type": "address" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - } - ], - "name": "register", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x2545fa928d5d278cA75Fd47306e4a89096ff6403", - "args": [], - "bytecode": "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c081905280610b166100478239600060fe0152600060d50152600060ac0152610b166000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806360d7a27814610064578063a2ea7c6e14610085575b600080fd5b61004e6100a5565b60405161005b9190610604565b60405180910390f35b61007761007236600461061e565b610148565b60405190815260200161005b565b6100986100933660046106d0565b6102f1565b60405161005b91906106e9565b60606100d07f0000000000000000000000000000000000000000000000000000000000000000610419565b6100f97f0000000000000000000000000000000000000000000000000000000000000000610419565b6101227f0000000000000000000000000000000000000000000000000000000000000000610419565b6040516020016101349392919061073a565b604051602081830303815290604052905090565b60008060405180608001604052806000801b81526020018573ffffffffffffffffffffffffffffffffffffffff168152602001841515815260200187878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939094525092935091506101ca905082610556565b60008181526020819052604090205490915015610213576040517f23369fa600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80825260008181526020818152604091829020845181559084015160018201805493860151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00000000000000000000000000000000000000000090941673ffffffffffffffffffffffffffffffffffffffff9092169190911792909217909155606083015183919060028201906102af9082610881565b50506040513381528291507f7d917fcbc9a29a9705ff9936ffa599500e4fd902e4486bae317414fe967b307c9060200160405180910390a29695505050505050565b604080516080810182526000808252602082018190529181019190915260608082015260008281526020818152604091829020825160808101845281548152600182015473ffffffffffffffffffffffffffffffffffffffff8116938201939093527401000000000000000000000000000000000000000090920460ff16151592820192909252600282018054919291606084019190610390906107df565b80601f01602080910402602001604051908101604052809291908181526020018280546103bc906107df565b80156104095780601f106103de57610100808354040283529160200191610409565b820191906000526020600020905b8154815290600101906020018083116103ec57829003601f168201915b5050505050815250509050919050565b60608160000361045c57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104865780610470816109ca565b915061047f9050600a83610a31565b9150610460565b60008167ffffffffffffffff8111156104a1576104a16107b0565b6040519080825280601f01601f1916602001820160405280156104cb576020820181803683370190505b5090505b841561054e576104e0600183610a45565b91506104ed600a86610a5e565b6104f8906030610a72565b60f81b81838151811061050d5761050d610a85565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610547600a86610a31565b94506104cf565b949350505050565b600081606001518260200151836040015160405160200161057993929190610ab4565b604051602081830303815290604052805190602001209050919050565b60005b838110156105b1578181015183820152602001610599565b50506000910152565b600081518084526105d2816020860160208601610596565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061061760208301846105ba565b9392505050565b6000806000806060858703121561063457600080fd5b843567ffffffffffffffff8082111561064c57600080fd5b818701915087601f83011261066057600080fd5b81358181111561066f57600080fd5b88602082850101111561068157600080fd5b6020928301965094505085013573ffffffffffffffffffffffffffffffffffffffff811681146106b057600080fd5b9150604085013580151581146106c557600080fd5b939692955090935050565b6000602082840312156106e257600080fd5b5035919050565b602081528151602082015273ffffffffffffffffffffffffffffffffffffffff60208301511660408201526040820151151560608201526000606083015160808084015261054e60a08401826105ba565b6000845161074c818460208901610596565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610788816001850160208a01610596565b600192019182015283516107a3816002840160208801610596565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600181811c908216806107f357607f821691505b60208210810361082c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561087c57600081815260208120601f850160051c810160208610156108595750805b601f850160051c820191505b8181101561087857828155600101610865565b5050505b505050565b815167ffffffffffffffff81111561089b5761089b6107b0565b6108af816108a984546107df565b84610832565b602080601f83116001811461090257600084156108cc5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610878565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561094f57888601518255948401946001909101908401610930565b508582101561098b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109fb576109fb61099b565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a4057610a40610a02565b500490565b81810381811115610a5857610a5861099b565b92915050565b600082610a6d57610a6d610a02565b500690565b80820180821115610a5857610a5861099b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008451610ac6818460208901610596565b60609490941b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190930190815290151560f81b60148201526015019291505056fea164736f6c6343000813000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806360d7a27814610064578063a2ea7c6e14610085575b600080fd5b61004e6100a5565b60405161005b9190610604565b60405180910390f35b61007761007236600461061e565b610148565b60405190815260200161005b565b6100986100933660046106d0565b6102f1565b60405161005b91906106e9565b60606100d07f0000000000000000000000000000000000000000000000000000000000000000610419565b6100f97f0000000000000000000000000000000000000000000000000000000000000000610419565b6101227f0000000000000000000000000000000000000000000000000000000000000000610419565b6040516020016101349392919061073a565b604051602081830303815290604052905090565b60008060405180608001604052806000801b81526020018573ffffffffffffffffffffffffffffffffffffffff168152602001841515815260200187878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939094525092935091506101ca905082610556565b60008181526020819052604090205490915015610213576040517f23369fa600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80825260008181526020818152604091829020845181559084015160018201805493860151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00000000000000000000000000000000000000000090941673ffffffffffffffffffffffffffffffffffffffff9092169190911792909217909155606083015183919060028201906102af9082610881565b50506040513381528291507f7d917fcbc9a29a9705ff9936ffa599500e4fd902e4486bae317414fe967b307c9060200160405180910390a29695505050505050565b604080516080810182526000808252602082018190529181019190915260608082015260008281526020818152604091829020825160808101845281548152600182015473ffffffffffffffffffffffffffffffffffffffff8116938201939093527401000000000000000000000000000000000000000090920460ff16151592820192909252600282018054919291606084019190610390906107df565b80601f01602080910402602001604051908101604052809291908181526020018280546103bc906107df565b80156104095780601f106103de57610100808354040283529160200191610409565b820191906000526020600020905b8154815290600101906020018083116103ec57829003601f168201915b5050505050815250509050919050565b60608160000361045c57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104865780610470816109ca565b915061047f9050600a83610a31565b9150610460565b60008167ffffffffffffffff8111156104a1576104a16107b0565b6040519080825280601f01601f1916602001820160405280156104cb576020820181803683370190505b5090505b841561054e576104e0600183610a45565b91506104ed600a86610a5e565b6104f8906030610a72565b60f81b81838151811061050d5761050d610a85565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610547600a86610a31565b94506104cf565b949350505050565b600081606001518260200151836040015160405160200161057993929190610ab4565b604051602081830303815290604052805190602001209050919050565b60005b838110156105b1578181015183820152602001610599565b50506000910152565b600081518084526105d2816020860160208601610596565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061061760208301846105ba565b9392505050565b6000806000806060858703121561063457600080fd5b843567ffffffffffffffff8082111561064c57600080fd5b818701915087601f83011261066057600080fd5b81358181111561066f57600080fd5b88602082850101111561068157600080fd5b6020928301965094505085013573ffffffffffffffffffffffffffffffffffffffff811681146106b057600080fd5b9150604085013580151581146106c557600080fd5b939692955090935050565b6000602082840312156106e257600080fd5b5035919050565b602081528151602082015273ffffffffffffffffffffffffffffffffffffffff60208301511660408201526040820151151560608201526000606083015160808084015261054e60a08401826105ba565b6000845161074c818460208901610596565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610788816001850160208a01610596565b600192019182015283516107a3816002840160208801610596565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600181811c908216806107f357607f821691505b60208210810361082c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561087c57600081815260208120601f850160051c810160208610156108595750805b601f850160051c820191505b8181101561087857828155600101610865565b5050505b505050565b815167ffffffffffffffff81111561089b5761089b6107b0565b6108af816108a984546107df565b84610832565b602080601f83116001811461090257600084156108cc5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610878565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561094f57888601518255948401946001909101908401610930565b508582101561098b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109fb576109fb61099b565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a4057610a40610a02565b500490565b81810381811115610a5857610a5861099b565b92915050565b600082610a6d57610a6d610a02565b500690565b80820180821115610a5857610a5861099b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008451610ac6818460208901610596565b60609490941b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190930190815290151560f81b60148201526015019291505056fea164736f6c6343000813000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "details": "Creates a new SchemaRegistry instance." - }, - "getSchema(bytes32)": { - "details": "Returns an existing schema by UID", - "params": { - "uid": "The UID of the schema to retrieve." - }, - "returns": { - "_0": "The schema data members." - } - }, - "register(string,address,bool)": { - "details": "Submits and reserves a new schema", - "params": { - "resolver": "An optional schema resolver.", - "revocable": "Whether the schema allows revocations explicitly.", - "schema": "The schema data schema." - }, - "returns": { - "_0": "The UID of the new schema." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "events": { - "Registered(bytes32,address)": { - "details": "Emitted when a new schema has been registered", - "params": { - "registerer": "The address of the account used to register the schema.", - "uid": "The schema UID." - } - } - }, - "title": "SchemaRegistry" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"AlreadyExists\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"registerer\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Registered\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getSchema\",\"outputs\":[{\"internalType\":\"struct SchemaRecord\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"contract ISchemaResolver\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"schema\",\"type\":\"string\"}]}]},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"schema\",\"type\":\"string\"},{\"internalType\":\"contract ISchemaResolver\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"register\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Creates a new SchemaRegistry instance.\"},\"getSchema(bytes32)\":{\"details\":\"Returns an existing schema by UID\",\"params\":{\"uid\":\"The UID of the schema to retrieve.\"},\"returns\":{\"_0\":\"The schema data members.\"}},\"register(string,address,bool)\":{\"details\":\"Submits and reserves a new schema\",\"params\":{\"resolver\":\"An optional schema resolver.\",\"revocable\":\"Whether the schema allows revocations explicitly.\",\"schema\":\"The schema data schema.\"},\"returns\":{\"_0\":\"The UID of the new schema.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"contracts/EAS/SchemaRegistry.sol\":\"SchemaRegistry\"},\"libraries\":{}},\"sources\":{\"contracts/EAS/Common.sol\":{\"keccak256\":\"0x922fda236f56fa813171ac1ae04d70d58763142ed084e36d29b369160f99acef\",\"urls\":[\"bzz-raw://82c6eb5ce50a0cfa28ad70fcd33fcd7f7704d538666127dc7aca32960423851b\",\"dweb:/ipfs/QmVQXmi9d7R4iks3rKNQKsq9HeuHZwpCg68jFbYGTw3VUs\"],\"license\":\"MIT\"},\"contracts/EAS/ISchemaRegistry.sol\":{\"keccak256\":\"0x456637ee808bb949d3941cd8b11581a7e7e0a92f304dbbf06fba320f27f57664\",\"urls\":[\"bzz-raw://372bc7f2fc72460daa5273200ac0d6b81427a23a65c8f5152a0f0fe2a47567d7\",\"dweb:/ipfs/QmSDDuVvp5nXaNDPzZbDMH1YE2nN4nrK8hEDctWds4wRah\"],\"license\":\"MIT\"},\"contracts/EAS/SchemaRegistry.sol\":{\"keccak256\":\"0x0cba1207d8986681585b65863a7cefd5cfc23e9e414d02baef027fca5cc8113d\",\"urls\":[\"bzz-raw://a5f62f15f3e977d1416af1cc4742e312d6f7c75a5ab533180695e02eb603d172\",\"dweb:/ipfs/QmPsyWTzKet3v4bfM7H8Eyz2uRRafz25Jxeqg9c6rKUDPH\"],\"license\":\"MIT\"},\"contracts/EAS/resolver/ISchemaResolver.sol\":{\"keccak256\":\"0x222f41e52e73c3edf2adcddd65c1c6911287b701b07413959a2f720778136135\",\"urls\":[\"bzz-raw://5b3fc66b38c358c3aa704aa3c22bfe7d48063f18529dbc6b61666d0609ffd658\",\"dweb:/ipfs/QmcHBVQzH4mTV1afqQrYw83kgknNETQ1brgWryBwN6u3mf\"],\"license\":\"MIT\"},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0xc455c84bb1f17e994dea0451fd363f81f83965bfa86e81ac6c8b3a327b9a0ff0\",\"urls\":[\"bzz-raw://fab499f3c0d7df8eb763b50621848d5d2147fb9c42a8eb9b65a11093090bb482\",\"dweb:/ipfs/QmUKsG4ztwtUZFjuRYAxgUFTgH5YxWSGF1BFFaB7vdM2K3\"],\"license\":\"MIT\"},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 1, - "receipt": { - "transactionHash": "0xfcee65e070a73f09d30aeae275abb7ff11f0e6d7a950c6032b0fb7e0950a382c", - "transactionIndex": "0x1", - "blockHash": "0x9c59cce84fd9fdd418fa3b99cc22fc52b775eed30b3671ab644dbec7630ce162", - "blockNumber": "0xbaabdb", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0xad18a", - "gasUsed": "0xa1a55", - "contractAddress": "0x2545fa928d5d278cA75Fd47306e4a89096ff6403", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb2d05e32" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 27112, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "_registry", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_bytes32,t_struct(SchemaRecord)27057_storage)" - }, - { - "astId": 27118, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)49_storage" - } - ], - "types": { - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_contract(ISchemaResolver)27536": { - "encoding": "inplace", - "label": "contract ISchemaResolver", - "numberOfBytes": "20" - }, - "t_mapping(t_bytes32,t_struct(SchemaRecord)27057_storage)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => struct SchemaRecord)", - "numberOfBytes": "32", - "value": "t_struct(SchemaRecord)27057_storage" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(SchemaRecord)27057_storage": { - "encoding": "inplace", - "label": "struct SchemaRecord", - "numberOfBytes": "96", - "members": [ - { - "astId": 27049, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "uid", - "offset": 0, - "slot": "0", - "type": "t_bytes32" - }, - { - "astId": 27052, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "resolver", - "offset": 0, - "slot": "1", - "type": "t_contract(ISchemaResolver)27536" - }, - { - "astId": 27054, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "revocable", - "offset": 20, - "slot": "1", - "type": "t_bool" - }, - { - "astId": 27056, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "schema", - "offset": 0, - "slot": "2", - "type": "t_string_storage" - } - ] - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - }, - "transactionHash": "0xfcee65e070a73f09d30aeae275abb7ff11f0e6d7a950c6032b0fb7e0950a382c", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "The global attestation schemas for the Ethereum Attestation Service protocol." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/SequencerFeeVault.json b/packages/contracts-bedrock/deployments/optimism-goerli/SequencerFeeVault.json deleted file mode 100644 index 51b16c18c3fc..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/SequencerFeeVault.json +++ /dev/null @@ -1,209 +0,0 @@ -{ - "address": "0x9eE472aB07Aa92bAe20a9d3E2d29beD3248b9075", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - } - ], - "name": "Withdrawal", - "type": "event" - }, - { - "inputs": [], - "name": "MIN_WITHDRAWAL_AMOUNT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RECIPIENT", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1FeeWallet", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalProcessed", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "withdraw", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0xe48c7bbac5aae994f898f87b9bf8e0bb466d84d8bd454f81990dcfbe9838caac", - "receipt": { - "to": null, - "from": "0xf80267194936da1E98dB10bcE06F3147D580a62e", - "contractAddress": "0x9eE472aB07Aa92bAe20a9d3E2d29beD3248b9075", - "transactionIndex": 2, - "gasUsed": "506060", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x52f53f362a23142d90f2abdffb2addca84a67c854a4fc67274d671f3265432d2", - "transactionHash": "0xe48c7bbac5aae994f898f87b9bf8e0bb466d84d8bd454f81990dcfbe9838caac", - "logs": [], - "blockNumber": 8579691, - "cumulativeGasUsed": "987372", - "status": 1, - "byzantium": true - }, - "args": [ - "0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f" - ], - "numDeployments": 1, - "solcInputHash": "2d538e296d12ca6101a896ac2e894043", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_WITHDRAWAL_AMOUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RECIPIENT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1FeeWallet\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalProcessed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"custom:proxied\":\"@custom:predeploy 0x4200000000000000000000000000000000000011\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.1.0\",\"params\":{\"_recipient\":\"Address that will receive the accumulated fees.\"}},\"l1FeeWallet()\":{\"custom:legacy\":\"@notice Legacy getter for the recipient address.\",\"returns\":{\"_0\":\"The recipient address.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"SequencerFeeVault\",\"version\":1},\"userdoc\":{\"events\":{\"Withdrawal(uint256,address,address)\":{\"notice\":\"Emits each time that a withdrawal occurs.\"}},\"kind\":\"user\",\"methods\":{\"MIN_WITHDRAWAL_AMOUNT()\":{\"notice\":\"Minimum balance before a withdrawal can be triggered.\"},\"RECIPIENT()\":{\"notice\":\"Wallet that will receive the fees on L1.\"},\"totalProcessed()\":{\"notice\":\"Total amount of wei processed by the contract.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"},\"withdraw()\":{\"notice\":\"Triggers a withdrawal of funds to the L1 fee wallet.\"}},\"notice\":\"The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during transaction processing and block production.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/SequencerFeeVault.sol\":\"SequencerFeeVault\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"]},\"sources\":{\"contracts/L1/ResourceMetering.sol\":{\"keccak256\":\"0xbd7b9532a70d8c842bfce0ea971be50d02fbbf0227c9ad55c71ac68d438010f4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4969f478dd54e89392cda2ea0c5edcf1be55a5dee43a0e410527b6e3bcb85c88\",\"dweb:/ipfs/QmU2crAojw8DRDsz7PAPrereazjFsKh9wtfTpTDVh6NLfW\"]},\"contracts/L2/L2StandardBridge.sol\":{\"keccak256\":\"0xd77e04c57f33cd32c32f326cd06e213d8a27a9fd372cfc4269953a49243c8c41\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f59627bf4c08c85886e819b29b8565b48fa7e9c230732fedfbb0b9c9a0ee04c5\",\"dweb:/ipfs/Qmao1VbQ57h6gdCZTYfipa8LB1wBwAthop5tPd9TgDXES2\"]},\"contracts/L2/SequencerFeeVault.sol\":{\"keccak256\":\"0xf4b01c9026a2208866ab0099f0ebd3df6f8a8c7f995fef99688243558c30e212\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9f6ec0c7f5fa9b75d4686cf18224bdb43b344420c37585eda565c1ff74a1bd71\",\"dweb:/ipfs/QmX3dDrAkZ6ahf9F4Md1PN7LUBRyAV61rL17on6KAV15Fm\"]},\"contracts/libraries/Arithmetic.sol\":{\"keccak256\":\"0xc8858039f87e48e6f18c1af8bc0b03e57cfef564acddfd06e4d91e3db7ac5ed6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2fc79af1e844aa6dc1c68067bfe1d359df8d4e9a3e8881afb3bcfcbf68071714\",\"dweb:/ipfs/QmcNC4k8zmvwj4kZizSenTiWbx2DJQPbwqXXLF4iMbkRVD\"]},\"contracts/libraries/Burn.sol\":{\"keccak256\":\"0x54233b226ba6919dc46d438bc790108d8f855001002a1b9c3c37aed7a83e5f3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4051a4baca357a9191a6c9e3aa1593a17b69dd7915966e23e4cb269e9c1d9ed4\",\"dweb:/ipfs/QmadKjGKvxm53abVHQdsxrXBc8e9jXywu6vvhkAgjsx59J\"]},\"contracts/libraries/Constants.sol\":{\"keccak256\":\"0x8c7be28a175eb732995a7f704560163c30261f9f70d377f865c5060882509f5d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f72aba26553b10ca88708e05461691b36b0d2ec7a87f718022fe119ca9c70852\",\"dweb:/ipfs/QmQtDEB1F3D8RsgG63KSJ9t7ZyFLaXc2Av81vKD9y2TMn7\"]},\"contracts/libraries/Encoding.sol\":{\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f18156216c1f9457c2e032a812ad70f2babbc5b89997554ff014d64c483fb2ff\",\"dweb:/ipfs/Qmc5rjMaBFn3jV7XqDrEvRbmatQvJxeVJYA5B5rdcKPkcJ\"]},\"contracts/libraries/Hashing.sol\":{\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6746ed0d26d603568818cc52a29d0209effd69f7e55bd0017a6b91bd6cf319fe\",\"dweb:/ipfs/QmPebCmCELMBRtDDxt5ziEPfRXUh6tfm2qJdwz3iyrDdWN\"]},\"contracts/libraries/Predeploys.sol\":{\"keccak256\":\"0xfc30fb239b5f00284f4b8f578a62f0882597e939335c91ea9bc4aab3070ddc43\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fa132267b3a9d98568b4e02cbb68fe2d2c0ca630826242c1b2293a8fa35bd302\",\"dweb:/ipfs/QmdYvcGbaykP6wyBu5T2obXrWK56xGnfWqbYeeWpTChq3w\"]},\"contracts/libraries/SafeCall.sol\":{\"keccak256\":\"0x6e815b62528d452a4f63040d75ff7a08db8ba8096050a53355fc49abaebdf245\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e27e542a11165c82cbb6961f4d8c2a58527fba1ab915afeeded50e96ce929777\",\"dweb:/ipfs/QmRPXdmUAbL1WHZBvENKWkFuHb9bQyrbiJWwDvzEQBLVi8\"]},\"contracts/libraries/Types.sol\":{\"keccak256\":\"0x4fe8ec920798661a828430bd30dc2715eeb40534ec01c0a7bf41cb4ab422e134\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://74c8471869900bd459358cd990bda1c8d234c06b788804c7049cf465ae1e299f\",\"dweb:/ipfs/QmakcfP6NmbVUQsKqH7rEyJsbiqckigLahw9g74oencEJ7\"]},\"contracts/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://921c44e6a0982b9a4011900fda1bda2c06b7a85894967de98b407a83fe9f90c0\",\"dweb:/ipfs/QmSsHLKDUQ82kpKdqB6VntVGKuPDb4W9VdotsubuqWBzio\"]},\"contracts/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x3c99b1e768cc4c1e064ccc137b1b4d5961bf4edf071be84cc216c5b20f1c00da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e36b2a6325c2f804d769271575669b62ab2da2df3c81921ac7487399fe02af07\",\"dweb:/ipfs/QmTCmcEKwvD8Xvjyev268Bkz27FC7TJpUbw1nADcsThnUr\"]},\"contracts/universal/FeeVault.sol\":{\"keccak256\":\"0x73eb2c835495ec308c69783db55c6cc315ed2a55ee6811ccda4e7dbbde04b2c8\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b5e46201184138d60e339c98276e3b265717a12795270a1d0ef03157e452e9a0\",\"dweb:/ipfs/QmWGLhTcPuF9ZZfrjGj4QGCzEuDwiyRAMpnQvxd2oLFX75\"]},\"contracts/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x2fea0ee05071c9c6b06a34a8e805801e247e861359b376a8918106e1d6f77ebe\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://198c91bda2edf864ddad1f8ab6168155d13d6ba5487418e5531ff040ff250686\",\"dweb:/ipfs/QmQzxfHY4P7zdVFRh2DTdGt1KeMHaGKNRf3KPZ1mRTYEGB\"]},\"contracts/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x302094342a45ebdf7f46f4fb48821960d2a4134f66fd7f458f73fc4ddf34d219\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b0e2b496e966ca6037e1c9be1d44417c0180fda2a27f68114e93b899defb783\",\"dweb:/ipfs/QmXP76ivMLxYxscC7B9E9qtW3u6HJ2MNaRVeo3x24VEAQH\"]},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9baf7797439c0ae6512f4639dfc6a1934dbd4e4d7cbb8e63e99264ff47682c9e\",\"dweb:/ipfs/QmawAuhppPyeoZH3rC1uh87xDELa9Lyfw5pYsBqE8myE1m\"]},\"contracts/universal/StandardBridge.sol\":{\"keccak256\":\"0xaa45044774fa70ed322983c3c0138b21d26d75f4b7e8f5324d53c3eef91adec4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c65c95d0cb71f2e32f5ffdea92151a9a46bbd538ba110389a134963fd16a33e9\",\"dweb:/ipfs/QmaPNZokt4j5SCXaWwVtw6qxu5GXWFa3SWBgaSWPPA9KUG\"]},\"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://11756f42121f6541a35a8339ea899ee7514cfaa2e6d740625fcc844419296aa6\",\"dweb:/ipfs/QmekMuk6BY4DAjzeXr4MSbKdgoqqsZnA8JPtuyWc6CwXHf\"]},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"node_modules/@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"]},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"]},\"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"node_modules/@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"]},\"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"]},\"node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"]}},\"version\":1}", - "bytecode": "0x61012060405234801561001157600080fd5b5060405161092a38038061092a8339810160408190526100309161005d565b678ac7230489e800006080526001600160a01b031660a052600160c081905260e05260006101005261008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b60805160a05160c05160e0516101005161083e6100ec6000396000610411015260006103e8015260006103bf0152600081816087015281816101730152818161029501526103570152600081816101420152610199015261083e6000f3fe6080604052600436106100695760003560e01c806384411d651161004357806384411d651461010c578063d3e5792b14610130578063d4ff92181461016457600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e8610197565b005b3480156100f657600080fd5b506100ff6103b8565b6040516100ca9190610612565b34801561011857600080fd5b5061012260005481565b6040519081526020016100ca565b34801561013c57600080fd5b506101227f000000000000000000000000000000000000000000000000000000000000000081565b34801561017057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006100a9565b7f0000000000000000000000000000000000000000000000000000000000000000471015610271576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a40160405180910390fd5b600047905080600080828254610287919061065b565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610383917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610673565b6000604051808303818588803b15801561039c57600080fd5b505af11580156103b0573d6000803e3d6000fd5b505050505050565b60606103e37f000000000000000000000000000000000000000000000000000000000000000061045b565b61040c7f000000000000000000000000000000000000000000000000000000000000000061045b565b6104357f000000000000000000000000000000000000000000000000000000000000000061045b565b604051602001610447939291906106b7565b604051602081830303815290604052905090565b60608160000361049e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104c857806104b28161072d565b91506104c19050600a83610794565b91506104a2565b60008167ffffffffffffffff8111156104e3576104e36107a8565b6040519080825280601f01601f19166020018201604052801561050d576020820181803683370190505b5090505b8415610590576105226001836107d7565b915061052f600a866107ee565b61053a90603061065b565b60f81b81838151811061054f5761054f610802565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610589600a86610794565b9450610511565b949350505050565b60005b838110156105b357818101518382015260200161059b565b838111156105c2576000848401525b50505050565b600081518084526105e0816020860160208601610598565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061062560208301846105c8565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561066e5761066e61062c565b500190565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff831660208201526060604082015260006106ae60608301846105c8565b95945050505050565b600084516106c9818460208901610598565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610705816001850160208a01610598565b60019201918201528351610720816002840160208801610598565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361075e5761075e61062c565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826107a3576107a3610765565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107e9576107e961062c565b500390565b6000826107fd576107fd610765565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x6080604052600436106100695760003560e01c806384411d651161004357806384411d651461010c578063d3e5792b14610130578063d4ff92181461016457600080fd5b80630d9019e1146100755780633ccfd60b146100d357806354fd4d50146100ea57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156100df57600080fd5b506100e8610197565b005b3480156100f657600080fd5b506100ff6103b8565b6040516100ca9190610612565b34801561011857600080fd5b5061012260005481565b6040519081526020016100ca565b34801561013c57600080fd5b506101227f000000000000000000000000000000000000000000000000000000000000000081565b34801561017057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006100a9565b7f0000000000000000000000000000000000000000000000000000000000000000471015610271576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a40160405180910390fd5b600047905080600080828254610287919061065b565b9091555050604080518281527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166020820152338183015290517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1604080516020810182526000815290517fe11013dd0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109163e11013dd918491610383917f0000000000000000000000000000000000000000000000000000000000000000916188b891600401610673565b6000604051808303818588803b15801561039c57600080fd5b505af11580156103b0573d6000803e3d6000fd5b505050505050565b60606103e37f000000000000000000000000000000000000000000000000000000000000000061045b565b61040c7f000000000000000000000000000000000000000000000000000000000000000061045b565b6104357f000000000000000000000000000000000000000000000000000000000000000061045b565b604051602001610447939291906106b7565b604051602081830303815290604052905090565b60608160000361049e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104c857806104b28161072d565b91506104c19050600a83610794565b91506104a2565b60008167ffffffffffffffff8111156104e3576104e36107a8565b6040519080825280601f01601f19166020018201604052801561050d576020820181803683370190505b5090505b8415610590576105226001836107d7565b915061052f600a866107ee565b61053a90603061065b565b60f81b81838151811061054f5761054f610802565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610589600a86610794565b9450610511565b949350505050565b60005b838110156105b357818101518382015260200161059b565b838111156105c2576000848401525b50505050565b600081518084526105e0816020860160208601610598565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061062560208301846105c8565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561066e5761066e61062c565b500190565b73ffffffffffffffffffffffffffffffffffffffff8416815263ffffffff831660208201526060604082015260006106ae60608301846105c8565b95945050505050565b600084516106c9818460208901610598565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610705816001850160208a01610598565b60019201918201528351610720816002840160208801610598565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361075e5761075e61062c565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826107a3576107a3610765565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107e9576107e961062c565b500390565b6000826107fd576107fd610765565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_recipient": "Address that will receive the accumulated fees." - } - }, - "l1FeeWallet()": { - "returns": { - "_0": "The recipient address." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "SequencerFeeVault" - }, - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MIN_WITHDRAWAL_AMOUNT()": { - "notice": "Minimum balance before a withdrawal can be triggered." - }, - "RECIPIENT()": { - "notice": "Wallet that will receive the fees on L1." - }, - "totalProcessed()": { - "notice": "Total amount of wei processed by the contract." - }, - "version()": { - "notice": "Returns the full semver contract version." - }, - "withdraw()": { - "notice": "Triggers a withdrawal of funds to the L1 fee wallet." - } - }, - "events": { - "Withdrawal(uint256,address,address)": { - "notice": "Emits each time that a withdrawal occurs." - } - }, - "notice": "The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during transaction processing and block production." - }, - "storageLayout": { - "storage": [ - { - "astId": 46671, - "contract": "contracts/L2/SequencerFeeVault.sol:SequencerFeeVault", - "label": "totalProcessed", - "offset": 0, - "slot": "0", - "type": "t_uint256" - } - ], - "types": { - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/2d538e296d12ca6101a896ac2e894043.json b/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/2d538e296d12ca6101a896ac2e894043.json deleted file mode 100644 index 89915af4d92c..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/2d538e296d12ca6101a896ac2e894043.json +++ /dev/null @@ -1,552 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/L1/L1CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismPortal } from \"./OptimismPortal.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1CrossDomainMessenger\n * @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible\n * for sending and receiving data on the L1 side. Users are encouraged to use this\n * interface instead of interacting with lower-level contracts directly.\n */\ncontract L1CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @notice Address of the OptimismPortal.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @custom:semver 1.4.0\n *\n * @param _portal Address of the OptimismPortal contract on this network.\n */\n constructor(OptimismPortal _portal)\n Semver(1, 4, 0)\n CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER)\n {\n PORTAL = _portal;\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return msg.sender == address(PORTAL) && PORTAL.l2Sender() == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(PORTAL);\n }\n}\n" - }, - "contracts/L1/L1ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { IERC721 } from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L1ERC721Bridge\n * @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as an escrow for ERC721 tokens deposited into L2.\n */\ncontract L1ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token\n * by ID was deposited for a given L2 token.\n */\n mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L1ERC721Bridge: local token cannot be self\");\n\n // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.\n require(\n deposits[_localToken][_remoteToken][_tokenId] == true,\n \"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\"\n );\n\n // Mark that the token ID for this L1/L2 token pair is no longer escrowed in the L1\n // Bridge.\n deposits[_localToken][_remoteToken][_tokenId] = false;\n\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the\n // withdrawer.\n IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L1ERC721Bridge: remote token cannot be address(0)\");\n\n // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)\n bytes memory message = abi.encodeWithSelector(\n L2ERC721Bridge.finalizeBridgeERC721.selector,\n _remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Lock token into bridge\n deposits[_localToken][_remoteToken][_tokenId] = true;\n IERC721(_localToken).transferFrom(_from, address(this), _tokenId);\n\n // Send calldata into L2\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L1/L1StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1StandardBridge\n * @notice The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L1, it will be escrowed within this\n * contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was\n * stored within this contract. After Bedrock, ETH is instead stored inside the\n * OptimismPortal contract.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L1StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated.\n *\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of ETH deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ETHDepositInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized.\n *\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of ETH withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 withdrawal is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _messenger Address of the L1CrossDomainMessenger.\n */\n constructor(address payable _messenger)\n Semver(1, 1, 0)\n StandardBridge(_messenger, payable(Predeploys.L2_STANDARD_BRIDGE))\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into the sender's account on L2.\n *\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETH(uint32 _minGasLimit, bytes calldata _extraData) external payable onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into a target account on L2.\n * Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will\n * be locked in the L2StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n *\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable {\n _initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into the sender's account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20(\n address _l1Token,\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual onlyEOA {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into a target account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20To(\n address _l1Token,\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ETH from L2.\n *\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of ETH to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeETHWithdrawal(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ERC20 tokens from L2.\n *\n * @param _l1Token Address of the token on L1.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of the ERC20 to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeERC20Withdrawal(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external {\n finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L2 bridge contract.\n *\n * @return Address of the corresponding L2 bridge contract.\n */\n function l2TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @notice Internal function for initiating an ETH deposit.\n *\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateETHDeposit(\n address _from,\n address _to,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Internal function for initiating an ERC20 deposit.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateERC20Deposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHDepositInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHDepositInitiated(_from, _to, _amount, _extraData);\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHWithdrawalFinalized event followed by the ETHBridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData);\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20DepositInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20DepositInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20WithdrawalFinalized event followed by the ERC20BridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20WithdrawalFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L1/L2OutputOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\n/**\n * @custom:proxied\n * @title L2OutputOracle\n * @notice The L2OutputOracle contains an array of L2 state outputs, where each output is a\n * commitment to the state of the L2 chain. Other contracts like the OptimismPortal use\n * these outputs to verify information about the state of L2.\n */\ncontract L2OutputOracle is Initializable, Semver {\n /**\n * @notice The interval in L2 blocks at which checkpoints must be submitted. Although this is\n * immutable, it can safely be modified by upgrading the implementation contract.\n */\n uint256 public immutable SUBMISSION_INTERVAL;\n\n /**\n * @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified.\n */\n uint256 public immutable L2_BLOCK_TIME;\n\n /**\n * @notice The address of the challenger. Can be updated via upgrade.\n */\n address public immutable CHALLENGER;\n\n /**\n * @notice The address of the proposer. Can be updated via upgrade.\n */\n address public immutable PROPOSER;\n\n /**\n * @notice Minimum time (in seconds) that must elapse before a withdrawal can be finalized.\n */\n uint256 public immutable FINALIZATION_PERIOD_SECONDS;\n\n /**\n * @notice The number of the first L2 block recorded in this contract.\n */\n uint256 public startingBlockNumber;\n\n /**\n * @notice The timestamp of the first L2 block recorded in this contract.\n */\n uint256 public startingTimestamp;\n\n /**\n * @notice Array of L2 output proposals.\n */\n Types.OutputProposal[] internal l2Outputs;\n\n /**\n * @notice Emitted when an output is proposed.\n *\n * @param outputRoot The output root.\n * @param l2OutputIndex The index of the output in the l2Outputs array.\n * @param l2BlockNumber The L2 block number of the output root.\n * @param l1Timestamp The L1 timestamp when proposed.\n */\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n /**\n * @notice Emitted when outputs are deleted.\n *\n * @param prevNextOutputIndex Next L2 output index before the deletion.\n * @param newNextOutputIndex Next L2 output index after the deletion.\n */\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n /**\n * @custom:semver 1.3.0\n *\n * @param _submissionInterval Interval in blocks at which checkpoints must be submitted.\n * @param _l2BlockTime The time per L2 block, in seconds.\n * @param _startingBlockNumber The number of the first L2 block.\n * @param _startingTimestamp The timestamp of the first L2 block.\n * @param _proposer The address of the proposer.\n * @param _challenger The address of the challenger.\n */\n constructor(\n uint256 _submissionInterval,\n uint256 _l2BlockTime,\n uint256 _startingBlockNumber,\n uint256 _startingTimestamp,\n address _proposer,\n address _challenger,\n uint256 _finalizationPeriodSeconds\n ) Semver(1, 3, 0) {\n require(_l2BlockTime > 0, \"L2OutputOracle: L2 block time must be greater than 0\");\n require(\n _submissionInterval > 0,\n \"L2OutputOracle: submission interval must be greater than 0\"\n );\n\n SUBMISSION_INTERVAL = _submissionInterval;\n L2_BLOCK_TIME = _l2BlockTime;\n PROPOSER = _proposer;\n CHALLENGER = _challenger;\n FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;\n\n initialize(_startingBlockNumber, _startingTimestamp);\n }\n\n /**\n * @notice Initializer.\n *\n * @param _startingBlockNumber Block number for the first recoded L2 block.\n * @param _startingTimestamp Timestamp for the first recoded L2 block.\n */\n function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp)\n public\n initializer\n {\n require(\n _startingTimestamp <= block.timestamp,\n \"L2OutputOracle: starting L2 timestamp must be less than current time\"\n );\n\n startingTimestamp = _startingTimestamp;\n startingBlockNumber = _startingBlockNumber;\n }\n\n /**\n * @notice Deletes all output proposals after and including the proposal that corresponds to\n * the given output index. Only the challenger address can delete outputs.\n *\n * @param _l2OutputIndex Index of the first L2 output to be deleted. All outputs after this\n * output will also be deleted.\n */\n // solhint-disable-next-line ordering\n function deleteL2Outputs(uint256 _l2OutputIndex) external {\n require(\n msg.sender == CHALLENGER,\n \"L2OutputOracle: only the challenger address can delete outputs\"\n );\n\n // Make sure we're not *increasing* the length of the array.\n require(\n _l2OutputIndex < l2Outputs.length,\n \"L2OutputOracle: cannot delete outputs after the latest output index\"\n );\n\n // Do not allow deleting any outputs that have already been finalized.\n require(\n block.timestamp - l2Outputs[_l2OutputIndex].timestamp < FINALIZATION_PERIOD_SECONDS,\n \"L2OutputOracle: cannot delete outputs that have already been finalized\"\n );\n\n uint256 prevNextL2OutputIndex = nextOutputIndex();\n\n // Use assembly to delete the array elements because Solidity doesn't allow it.\n assembly {\n sstore(l2Outputs.slot, _l2OutputIndex)\n }\n\n emit OutputsDeleted(prevNextL2OutputIndex, _l2OutputIndex);\n }\n\n /**\n * @notice Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp\n * must be equal to the current value returned by `nextTimestamp()` in order to be\n * accepted. This function may only be called by the Proposer.\n *\n * @param _outputRoot The L2 output of the checkpoint block.\n * @param _l2BlockNumber The L2 block number that resulted in _outputRoot.\n * @param _l1BlockHash A block hash which must be included in the current chain.\n * @param _l1BlockNumber The block number with the specified block hash.\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external payable {\n require(\n msg.sender == PROPOSER,\n \"L2OutputOracle: only the proposer address can propose new outputs\"\n );\n\n require(\n _l2BlockNumber == nextBlockNumber(),\n \"L2OutputOracle: block number must be equal to next expected block number\"\n );\n\n require(\n computeL2Timestamp(_l2BlockNumber) < block.timestamp,\n \"L2OutputOracle: cannot propose L2 output in the future\"\n );\n\n require(\n _outputRoot != bytes32(0),\n \"L2OutputOracle: L2 output proposal cannot be the zero hash\"\n );\n\n if (_l1BlockHash != bytes32(0)) {\n // This check allows the proposer to propose an output based on a given L1 block,\n // without fear that it will be reorged out.\n // It will also revert if the blockheight provided is more than 256 blocks behind the\n // chain tip (as the hash will return as zero). This does open the door to a griefing\n // attack in which the proposer's submission is censored until the block is no longer\n // retrievable, if the proposer is experiencing this attack it can simply leave out the\n // blockhash value, and delay submission until it is confident that the L1 block is\n // finalized.\n require(\n blockhash(_l1BlockNumber) == _l1BlockHash,\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n }\n\n emit OutputProposed(_outputRoot, nextOutputIndex(), _l2BlockNumber, block.timestamp);\n\n l2Outputs.push(\n Types.OutputProposal({\n outputRoot: _outputRoot,\n timestamp: uint128(block.timestamp),\n l2BlockNumber: uint128(_l2BlockNumber)\n })\n );\n }\n\n /**\n * @notice Returns an output by index. Exists because Solidity's array access will return a\n * tuple instead of a struct.\n *\n * @param _l2OutputIndex Index of the output to return.\n *\n * @return The output at the given index.\n */\n function getL2Output(uint256 _l2OutputIndex)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[_l2OutputIndex];\n }\n\n /**\n * @notice Returns the index of the L2 output that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return Index of the first checkpoint that commits to the given L2 block number.\n */\n function getL2OutputIndexAfter(uint256 _l2BlockNumber) public view returns (uint256) {\n // Make sure an output for this block number has actually been proposed.\n require(\n _l2BlockNumber <= latestBlockNumber(),\n \"L2OutputOracle: cannot get output for a block that has not been proposed\"\n );\n\n // Make sure there's at least one output proposed.\n require(\n l2Outputs.length > 0,\n \"L2OutputOracle: cannot get output as no outputs have been proposed yet\"\n );\n\n // Find the output via binary search, guaranteed to exist.\n uint256 lo = 0;\n uint256 hi = l2Outputs.length;\n while (lo < hi) {\n uint256 mid = (lo + hi) / 2;\n if (l2Outputs[mid].l2BlockNumber < _l2BlockNumber) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n return lo;\n }\n\n /**\n * @notice Returns the L2 output proposal that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return First checkpoint that commits to the given L2 block number.\n */\n function getL2OutputAfter(uint256 _l2BlockNumber)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)];\n }\n\n /**\n * @notice Returns the number of outputs that have been proposed. Will revert if no outputs\n * have been proposed yet.\n *\n * @return The number of outputs that have been proposed.\n */\n function latestOutputIndex() external view returns (uint256) {\n return l2Outputs.length - 1;\n }\n\n /**\n * @notice Returns the index of the next output to be proposed.\n *\n * @return The index of the next output to be proposed.\n */\n function nextOutputIndex() public view returns (uint256) {\n return l2Outputs.length;\n }\n\n /**\n * @notice Returns the block number of the latest submitted L2 output proposal. If no proposals\n * been submitted yet then this function will return the starting block number.\n *\n * @return Latest submitted L2 block number.\n */\n function latestBlockNumber() public view returns (uint256) {\n return\n l2Outputs.length == 0\n ? startingBlockNumber\n : l2Outputs[l2Outputs.length - 1].l2BlockNumber;\n }\n\n /**\n * @notice Computes the block number of the next L2 block that needs to be checkpointed.\n *\n * @return Next L2 block number.\n */\n function nextBlockNumber() public view returns (uint256) {\n return latestBlockNumber() + SUBMISSION_INTERVAL;\n }\n\n /**\n * @notice Returns the L2 timestamp corresponding to a given L2 block number.\n *\n * @param _l2BlockNumber The L2 block number of the target block.\n *\n * @return L2 timestamp of the given block.\n */\n function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {\n return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME);\n }\n}\n" - }, - "contracts/L1/OptimismPortal.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { L2OutputOracle } from \"./L2OutputOracle.sol\";\nimport { SystemConfig } from \"./SystemConfig.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { SecureMerkleTrie } from \"../libraries/trie/SecureMerkleTrie.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title OptimismPortal\n * @notice The OptimismPortal is a low-level contract responsible for passing messages between L1\n * and L2. Messages sent directly to the OptimismPortal have no form of replayability.\n * Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface.\n */\ncontract OptimismPortal is Initializable, ResourceMetering, Semver {\n /**\n * @notice Represents a proven withdrawal.\n *\n * @custom:field outputRoot Root of the L2 output this was proven against.\n * @custom:field timestamp Timestamp at whcih the withdrawal was proven.\n * @custom:field l2OutputIndex Index of the output this was proven against.\n */\n struct ProvenWithdrawal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2OutputIndex;\n }\n\n /**\n * @notice Version of the deposit event.\n */\n uint256 internal constant DEPOSIT_VERSION = 0;\n\n /**\n * @notice The L2 gas limit set when eth is deposited using the receive() function.\n */\n uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Address of the L2OutputOracle contract.\n */\n L2OutputOracle public immutable L2_ORACLE;\n\n /**\n * @notice Address of the SystemConfig contract.\n */\n SystemConfig public immutable SYSTEM_CONFIG;\n\n /**\n * @notice Address that has the ability to pause and unpause withdrawals.\n */\n address public immutable GUARDIAN;\n\n /**\n * @notice Address of the L2 account which initiated a withdrawal in this transaction. If the\n * of this variable is the default L2 sender address, then we are NOT inside of a call\n * to finalizeWithdrawalTransaction.\n */\n address public l2Sender;\n\n /**\n * @notice A list of withdrawal hashes which have been successfully finalized.\n */\n mapping(bytes32 => bool) public finalizedWithdrawals;\n\n /**\n * @notice A mapping of withdrawal hashes to `ProvenWithdrawal` data.\n */\n mapping(bytes32 => ProvenWithdrawal) public provenWithdrawals;\n\n /**\n * @notice Determines if cross domain messaging is paused. When set to true,\n * withdrawals are paused. This may be removed in the future.\n */\n bool public paused;\n\n /**\n * @notice Emitted when a transaction is deposited from L1 to L2. The parameters of this event\n * are read by the rollup node and used to derive deposit transactions on L2.\n *\n * @param from Address that triggered the deposit transaction.\n * @param to Address that the deposit transaction is directed to.\n * @param version Version of this deposit transaction event.\n * @param opaqueData ABI encoded deposit data to be parsed off-chain.\n */\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is proven.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n */\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is finalized.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n * @param success Whether the withdrawal transaction was successful.\n */\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n\n /**\n * @notice Emitted when the pause is triggered.\n *\n * @param account Address of the account triggering the pause.\n */\n event Paused(address account);\n\n /**\n * @notice Emitted when the pause is lifted.\n *\n * @param account Address of the account triggering the unpause.\n */\n event Unpaused(address account);\n\n /**\n * @notice Reverts when paused.\n */\n modifier whenNotPaused() {\n require(paused == false, \"OptimismPortal: paused\");\n _;\n }\n\n /**\n * @custom:semver 1.6.0\n *\n * @param _l2Oracle Address of the L2OutputOracle contract.\n * @param _guardian Address that can pause deposits and withdrawals.\n * @param _paused Sets the contract's pausability state.\n * @param _config Address of the SystemConfig contract.\n */\n constructor(\n L2OutputOracle _l2Oracle,\n address _guardian,\n bool _paused,\n SystemConfig _config\n ) Semver(1, 6, 0) {\n L2_ORACLE = _l2Oracle;\n GUARDIAN = _guardian;\n SYSTEM_CONFIG = _config;\n initialize(_paused);\n }\n\n /**\n * @notice Initializer.\n */\n function initialize(bool _paused) public initializer {\n l2Sender = Constants.DEFAULT_L2_SENDER;\n paused = _paused;\n __ResourceMetering_init();\n }\n\n /**\n * @notice Pause deposits and withdrawals.\n */\n function pause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can pause\");\n paused = true;\n emit Paused(msg.sender);\n }\n\n /**\n * @notice Unpause deposits and withdrawals.\n */\n function unpause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can unpause\");\n paused = false;\n emit Unpaused(msg.sender);\n }\n\n /**\n * @notice Computes the minimum gas limit for a deposit. The minimum gas limit\n * linearly increases based on the size of the calldata. This is to prevent\n * users from creating L2 resource usage without paying for it. This function\n * can be used when interacting with the portal to ensure forwards compatibility.\n *\n */\n function minimumGasLimit(uint64 _byteCount) public pure returns (uint64) {\n return _byteCount * 16 + 21000;\n }\n\n /**\n * @notice Accepts value so that users can send ETH directly to this contract and have the\n * funds be deposited to their address on L2. This is intended as a convenience\n * function for EOAs. Contracts should call the depositTransaction() function directly\n * otherwise any deposited funds will be lost due to address aliasing.\n */\n // solhint-disable-next-line ordering\n receive() external payable {\n depositTransaction(msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes(\"\"));\n }\n\n /**\n * @notice Accepts ETH value without triggering a deposit to L2. This function mainly exists\n * for the sake of the migration between the legacy Optimism system and Bedrock.\n */\n function donateETH() external payable {\n // Intentionally empty.\n }\n\n /**\n * @notice Getter for the resource config. Used internally by the ResourceMetering\n * contract. The SystemConfig is the source of truth for the resource config.\n *\n * @return ResourceMetering.ResourceConfig\n */\n function _resourceConfig()\n internal\n view\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return SYSTEM_CONFIG.resourceConfig();\n }\n\n /**\n * @notice Proves a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n * @param _l2OutputIndex L2 output index to prove against.\n * @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root.\n * @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\n */\n function proveWithdrawalTransaction(\n Types.WithdrawalTransaction memory _tx,\n uint256 _l2OutputIndex,\n Types.OutputRootProof calldata _outputRootProof,\n bytes[] calldata _withdrawalProof\n ) external whenNotPaused {\n // Prevent users from creating a deposit transaction where this address is the message\n // sender on L2. Because this is checked here, we do not need to check again in\n // `finalizeWithdrawalTransaction`.\n require(\n _tx.target != address(this),\n \"OptimismPortal: you cannot send messages to the portal contract\"\n );\n\n // Get the output root and load onto the stack to prevent multiple mloads. This will\n // revert if there is no output root for the given block number.\n bytes32 outputRoot = L2_ORACLE.getL2Output(_l2OutputIndex).outputRoot;\n\n // Verify that the output root can be generated with the elements in the proof.\n require(\n outputRoot == Hashing.hashOutputRootProof(_outputRootProof),\n \"OptimismPortal: invalid output root proof\"\n );\n\n // Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // We generally want to prevent users from proving the same withdrawal multiple times\n // because each successive proof will update the timestamp. A malicious user can take\n // advantage of this to prevent other users from finalizing their withdrawal. However,\n // since withdrawals are proven before an output root is finalized, we need to allow users\n // to re-prove their withdrawal only in the case that the output root for their specified\n // output index has been updated.\n require(\n provenWithdrawal.timestamp == 0 ||\n L2_ORACLE.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot !=\n provenWithdrawal.outputRoot,\n \"OptimismPortal: withdrawal hash has already been proven\"\n );\n\n // Compute the storage slot of the withdrawal hash in the L2ToL1MessagePasser contract.\n // Refer to the Solidity documentation for more information on how storage layouts are\n // computed for mappings.\n bytes32 storageKey = keccak256(\n abi.encode(\n withdrawalHash,\n uint256(0) // The withdrawals mapping is at the first slot in the layout.\n )\n );\n\n // Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract\n // on L2. If this is true, under the assumption that the SecureMerkleTrie does not have\n // bugs, then we know that this withdrawal was actually triggered on L2 and can therefore\n // be relayed on L1.\n require(\n SecureMerkleTrie.verifyInclusionProof(\n abi.encode(storageKey),\n hex\"01\",\n _withdrawalProof,\n _outputRootProof.messagePasserStorageRoot\n ),\n \"OptimismPortal: invalid withdrawal inclusion proof\"\n );\n\n // Designate the withdrawalHash as proven by storing the `outputRoot`, `timestamp`, and\n // `l2BlockNumber` in the `provenWithdrawals` mapping. A `withdrawalHash` can only be\n // proven once unless it is submitted again with a different outputRoot.\n provenWithdrawals[withdrawalHash] = ProvenWithdrawal({\n outputRoot: outputRoot,\n timestamp: uint128(block.timestamp),\n l2OutputIndex: uint128(_l2OutputIndex)\n });\n\n // Emit a `WithdrawalProven` event.\n emit WithdrawalProven(withdrawalHash, _tx.sender, _tx.target);\n }\n\n /**\n * @notice Finalizes a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n */\n function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx)\n external\n whenNotPaused\n {\n // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other\n // than the default value when a withdrawal transaction is being finalized. This check is\n // a defacto reentrancy guard.\n require(\n l2Sender == Constants.DEFAULT_L2_SENDER,\n \"OptimismPortal: can only trigger one withdrawal per transaction\"\n );\n\n // Grab the proven withdrawal from the `provenWithdrawals` map.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // A withdrawal can only be finalized if it has been proven. We know that a withdrawal has\n // been proven at least once when its timestamp is non-zero. Unproven withdrawals will have\n // a timestamp of zero.\n require(\n provenWithdrawal.timestamp != 0,\n \"OptimismPortal: withdrawal has not been proven yet\"\n );\n\n // As a sanity check, we make sure that the proven withdrawal's timestamp is greater than\n // starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of\n // safety against weird bugs in the proving step.\n require(\n provenWithdrawal.timestamp >= L2_ORACLE.startingTimestamp(),\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n\n // A proven withdrawal must wait at least the finalization period before it can be\n // finalized. This waiting period can elapse in parallel with the waiting period for the\n // output the withdrawal was proven against. In effect, this means that the minimum\n // withdrawal time is proposal submission time + finalization period.\n require(\n _isFinalizationPeriodElapsed(provenWithdrawal.timestamp),\n \"OptimismPortal: proven withdrawal finalization period has not elapsed\"\n );\n\n // Grab the OutputProposal from the L2OutputOracle, will revert if the output that\n // corresponds to the given index has not been proposed yet.\n Types.OutputProposal memory proposal = L2_ORACLE.getL2Output(\n provenWithdrawal.l2OutputIndex\n );\n\n // Check that the output root that was used to prove the withdrawal is the same as the\n // current output root for the given output index. An output root may change if it is\n // deleted by the challenger address and then re-proposed.\n require(\n proposal.outputRoot == provenWithdrawal.outputRoot,\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n\n // Check that the output proposal has also been finalized.\n require(\n _isFinalizationPeriodElapsed(proposal.timestamp),\n \"OptimismPortal: output proposal finalization period has not elapsed\"\n );\n\n // Check that this withdrawal has not already been finalized, this is replay protection.\n require(\n finalizedWithdrawals[withdrawalHash] == false,\n \"OptimismPortal: withdrawal has already been finalized\"\n );\n\n // Mark the withdrawal as finalized so it can't be replayed.\n finalizedWithdrawals[withdrawalHash] = true;\n\n // Set the l2Sender so contracts know who triggered this withdrawal on L2.\n l2Sender = _tx.sender;\n\n // Trigger the call to the target contract. We use a custom low level method\n // SafeCall.callWithMinGas to ensure two key properties\n // 1. Target contracts cannot force this call to run out of gas by returning a very large\n // amount of data (and this is OK because we don't care about the returndata here).\n // 2. The amount of gas provided to the execution context of the target is at least the\n // gas limit specified by the user. If there is not enough gas in the current context\n // to accomplish this, `callWithMinGas` will revert.\n bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data);\n\n // Reset the l2Sender back to the default value.\n l2Sender = Constants.DEFAULT_L2_SENDER;\n\n // All withdrawals are immediately finalized. Replayability can\n // be achieved through contracts built on top of this contract\n emit WithdrawalFinalized(withdrawalHash, success);\n\n // Reverting here is useful for determining the exact gas cost to successfully execute the\n // sub call to the target contract if the minimum gas limit specified by the user would not\n // be sufficient to execute the sub call.\n if (success == false && tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"OptimismPortal: withdrawal failed\");\n }\n }\n\n /**\n * @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in\n * deriving deposit transactions. Note that if a deposit is made by a contract, its\n * address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider\n * using the CrossDomainMessenger contracts for a simpler developer experience.\n *\n * @param _to Target address on L2.\n * @param _value ETH value to send to the recipient.\n * @param _gasLimit Minimum L2 gas limit (can be greater than or equal to this value).\n * @param _isCreation Whether or not the transaction is a contract creation.\n * @param _data Data to trigger the recipient with.\n */\n function depositTransaction(\n address _to,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable metered(_gasLimit) {\n // Just to be safe, make sure that people specify address(0) as the target when doing\n // contract creations.\n if (_isCreation) {\n require(\n _to == address(0),\n \"OptimismPortal: must send to address(0) when creating a contract\"\n );\n }\n\n // Prevent depositing transactions that have too small of a gas limit. Users should pay\n // more for more resource usage.\n require(\n _gasLimit >= minimumGasLimit(uint64(_data.length)),\n \"OptimismPortal: gas limit too small\"\n );\n\n // Prevent the creation of deposit transactions that have too much calldata. This gives an\n // upper limit on the size of unsafe blocks over the p2p network. 120kb is chosen to ensure\n // that the transaction can fit into the p2p network policy of 128kb even though deposit\n // transactions are not gossipped over the p2p network.\n require(_data.length <= 120_000, \"OptimismPortal: data too large\");\n\n // Transform the from-address to its alias if the caller is a contract.\n address from = msg.sender;\n if (msg.sender != tx.origin) {\n from = AddressAliasHelper.applyL1ToL2Alias(msg.sender);\n }\n\n // Compute the opaque data that will be emitted as part of the TransactionDeposited event.\n // We use opaque data so that we can update the TransactionDeposited event in the future\n // without breaking the current interface.\n bytes memory opaqueData = abi.encodePacked(\n msg.value,\n _value,\n _gasLimit,\n _isCreation,\n _data\n );\n\n // Emit a TransactionDeposited event so that the rollup node can derive a deposit\n // transaction for this deposit.\n emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);\n }\n\n /**\n * @notice Determine if a given output is finalized. Reverts if the call to\n * L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\n *\n * @param _l2OutputIndex Index of the L2 output to check.\n *\n * @return Whether or not the output is finalized.\n */\n function isOutputFinalized(uint256 _l2OutputIndex) external view returns (bool) {\n return _isFinalizationPeriodElapsed(L2_ORACLE.getL2Output(_l2OutputIndex).timestamp);\n }\n\n /**\n * @notice Determines whether the finalization period has elapsed w/r/t a given timestamp.\n *\n * @param _timestamp Timestamp to check.\n *\n * @return Whether or not the finalization period has elapsed.\n */\n function _isFinalizationPeriodElapsed(uint256 _timestamp) internal view returns (bool) {\n return block.timestamp > _timestamp + L2_ORACLE.FINALIZATION_PERIOD_SECONDS();\n }\n}\n" - }, - "contracts/L1/ResourceMetering.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\n\n/**\n * @custom:upgradeable\n * @title ResourceMetering\n * @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing\n * updates automatically based on current demand.\n */\nabstract contract ResourceMetering is Initializable {\n /**\n * @notice Represents the various parameters that control the way in which resources are\n * metered. Corresponds to the EIP-1559 resource metering system.\n *\n * @custom:field prevBaseFee Base fee from the previous block(s).\n * @custom:field prevBoughtGas Amount of gas bought so far in the current block.\n * @custom:field prevBlockNum Last block number that the base fee was updated.\n */\n struct ResourceParams {\n uint128 prevBaseFee;\n uint64 prevBoughtGas;\n uint64 prevBlockNum;\n }\n\n /**\n * @notice Represents the configuration for the EIP-1559 based curve for the deposit gas\n * market. These values should be set with care as it is possible to set them in\n * a way that breaks the deposit gas market. The target resource limit is defined as\n * maxResourceLimit / elasticityMultiplier. This struct was designed to fit within a\n * single word. There is additional space for additions in the future.\n *\n * @custom:field maxResourceLimit Represents the maximum amount of deposit gas that\n * can be purchased per block.\n * @custom:field elasticityMultiplier Determines the target resource limit along with\n * the resource limit.\n * @custom:field baseFeeMaxChangeDenominator Determines max change on fee per block.\n * @custom:field minimumBaseFee The min deposit base fee, it is clamped to this\n * value.\n * @custom:field systemTxMaxGas The amount of gas supplied to the system\n * transaction. This should be set to the same number\n * that the op-node sets as the gas limit for the\n * system transaction.\n * @custom:field maximumBaseFee The max deposit base fee, it is clamped to this\n * value.\n */\n struct ResourceConfig {\n uint32 maxResourceLimit;\n uint8 elasticityMultiplier;\n uint8 baseFeeMaxChangeDenominator;\n uint32 minimumBaseFee;\n uint32 systemTxMaxGas;\n uint128 maximumBaseFee;\n }\n\n /**\n * @notice EIP-1559 style gas parameters.\n */\n ResourceParams public params;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[48] private __gap;\n\n /**\n * @notice Meters access to a function based an amount of a requested resource.\n *\n * @param _amount Amount of the resource requested.\n */\n modifier metered(uint64 _amount) {\n // Record initial gas amount so we can refund for it later.\n uint256 initialGas = gasleft();\n\n // Run the underlying function.\n _;\n\n // Run the metering function.\n _metered(_amount, initialGas);\n }\n\n /**\n * @notice An internal function that holds all of the logic for metering a resource.\n *\n * @param _amount Amount of the resource requested.\n * @param _initialGas The amount of gas before any modifier execution.\n */\n function _metered(uint64 _amount, uint256 _initialGas) internal {\n // Update block number and base fee if necessary.\n uint256 blockDiff = block.number - params.prevBlockNum;\n\n ResourceConfig memory config = _resourceConfig();\n int256 targetResourceLimit = int256(uint256(config.maxResourceLimit)) /\n int256(uint256(config.elasticityMultiplier));\n\n if (blockDiff > 0) {\n // Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate\n // at which deposits can be created and therefore limit the potential for deposits to\n // spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.\n int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit;\n int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) /\n (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));\n\n // Update base fee by adding the base fee delta and clamp the resulting value between\n // min and max.\n int256 newBaseFee = Arithmetic.clamp({\n _value: int256(uint256(params.prevBaseFee)) + baseFeeDelta,\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n\n // If we skipped more than one block, we also need to account for every empty block.\n // Empty block means there was no demand for deposits in that block, so we should\n // reflect this lack of demand in the fee.\n if (blockDiff > 1) {\n // Update the base fee by repeatedly applying the exponent 1-(1/change_denominator)\n // blockDiff - 1 times. Simulates multiple empty blocks. Clamp the resulting value\n // between min and max.\n newBaseFee = Arithmetic.clamp({\n _value: Arithmetic.cdexp({\n _coefficient: newBaseFee,\n _denominator: int256(uint256(config.baseFeeMaxChangeDenominator)),\n _exponent: int256(blockDiff - 1)\n }),\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n }\n\n // Update new base fee, reset bought gas, and update block number.\n params.prevBaseFee = uint128(uint256(newBaseFee));\n params.prevBoughtGas = 0;\n params.prevBlockNum = uint64(block.number);\n }\n\n // Make sure we can actually buy the resource amount requested by the user.\n params.prevBoughtGas += _amount;\n require(\n int256(uint256(params.prevBoughtGas)) <= int256(uint256(config.maxResourceLimit)),\n \"ResourceMetering: cannot buy more gas than available gas limit\"\n );\n\n // Determine the amount of ETH to be paid.\n uint256 resourceCost = uint256(_amount) * uint256(params.prevBaseFee);\n\n // We currently charge for this ETH amount as an L1 gas burn, so we convert the ETH amount\n // into gas by dividing by the L1 base fee. We assume a minimum base fee of 1 gwei to avoid\n // division by zero for L1s that don't support 1559 or to avoid excessive gas burns during\n // periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei\n // during any 1 day period in the last 5 years, so should be fine.\n uint256 gasCost = resourceCost / Math.max(block.basefee, 1 gwei);\n\n // Give the user a refund based on the amount of gas they used to do all of the work up to\n // this point. Since we're at the end of the modifier, this should be pretty accurate. Acts\n // effectively like a dynamic stipend (with a minimum value).\n uint256 usedGas = _initialGas - gasleft();\n if (gasCost > usedGas) {\n Burn.gas(gasCost - usedGas);\n }\n }\n\n /**\n * @notice Virtual function that returns the resource config. Contracts that inherit this\n * contract must implement this function.\n *\n * @return ResourceConfig\n */\n function _resourceConfig() internal virtual returns (ResourceConfig memory);\n\n /**\n * @notice Sets initial resource parameter values. This function must either be called by the\n * initializer function of an upgradeable child contract.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __ResourceMetering_init() internal onlyInitializing {\n params = ResourceParams({\n prevBaseFee: 1 gwei,\n prevBoughtGas: 0,\n prevBlockNum: uint64(block.number)\n });\n }\n}\n" - }, - "contracts/L1/SystemConfig.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\n\n/**\n * @title SystemConfig\n * @notice The SystemConfig contract is used to manage configuration of an Optimism network. All\n * configuration is stored on L1 and picked up by L2 as part of the derviation of the L2\n * chain.\n */\ncontract SystemConfig is OwnableUpgradeable, Semver {\n /**\n * @notice Enum representing different types of updates.\n *\n * @custom:value BATCHER Represents an update to the batcher hash.\n * @custom:value GAS_CONFIG Represents an update to txn fee config on L2.\n * @custom:value GAS_LIMIT Represents an update to gas limit on L2.\n * @custom:value UNSAFE_BLOCK_SIGNER Represents an update to the signer key for unsafe\n * block distrubution.\n */\n enum UpdateType {\n BATCHER,\n GAS_CONFIG,\n GAS_LIMIT,\n UNSAFE_BLOCK_SIGNER\n }\n\n /**\n * @notice Version identifier, used for upgrades.\n */\n uint256 public constant VERSION = 0;\n\n /**\n * @notice Storage slot that the unsafe block signer is stored at. Storing it at this\n * deterministic storage slot allows for decoupling the storage layout from the way\n * that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value.\n */\n bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256(\"systemconfig.unsafeblocksigner\");\n\n /**\n * @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public overhead;\n\n /**\n * @notice Dynamic L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public scalar;\n\n /**\n * @notice Identifier for the batcher. For version 1 of this configuration, this is represented\n * as an address left-padded with zeros to 32 bytes.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice L2 block gas limit.\n */\n uint64 public gasLimit;\n\n /**\n * @notice The configuration for the deposit fee market. Used by the OptimismPortal\n * to meter the cost of buying L2 gas on L1. Set as internal and wrapped with a getter\n * so that the struct is returned instead of a tuple.\n */\n ResourceMetering.ResourceConfig internal _resourceConfig;\n\n /**\n * @notice Emitted when configuration is updated\n *\n * @param version SystemConfig version.\n * @param updateType Type of update.\n * @param data Encoded update data.\n */\n event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);\n\n /**\n * @custom:semver 1.3.0\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial resource config.\n */\n constructor(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) Semver(1, 3, 0) {\n initialize({\n _owner: _owner,\n _overhead: _overhead,\n _scalar: _scalar,\n _batcherHash: _batcherHash,\n _gasLimit: _gasLimit,\n _unsafeBlockSigner: _unsafeBlockSigner,\n _config: _config\n });\n }\n\n /**\n * @notice Initializer. The resource config must be set before the\n * require check.\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial ResourceConfig.\n */\n function initialize(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) public initializer {\n __Ownable_init();\n transferOwnership(_owner);\n overhead = _overhead;\n scalar = _scalar;\n batcherHash = _batcherHash;\n gasLimit = _gasLimit;\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n _setResourceConfig(_config);\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n }\n\n /**\n * @notice Returns the minimum L2 gas limit that can be safely set for the system to\n * operate. The L2 gas limit must be larger than or equal to the amount of\n * gas that is allocated for deposits per block plus the amount of gas that\n * is allocated for the system transaction.\n * This function is used to determine if changes to parameters are safe.\n *\n * @return uint64\n */\n function minimumGasLimit() public view returns (uint64) {\n return uint64(_resourceConfig.maxResourceLimit) + uint64(_resourceConfig.systemTxMaxGas);\n }\n\n /**\n * @notice High level getter for the unsafe block signer address. Unsafe blocks can be\n * propagated across the p2p network if they are signed by the key corresponding to\n * this address.\n *\n * @return Address of the unsafe block signer.\n */\n // solhint-disable-next-line ordering\n function unsafeBlockSigner() external view returns (address) {\n address addr;\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n addr := sload(slot)\n }\n return addr;\n }\n\n /**\n * @notice Updates the unsafe block signer address.\n *\n * @param _unsafeBlockSigner New unsafe block signer address.\n */\n function setUnsafeBlockSigner(address _unsafeBlockSigner) external onlyOwner {\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n\n bytes memory data = abi.encode(_unsafeBlockSigner);\n emit ConfigUpdate(VERSION, UpdateType.UNSAFE_BLOCK_SIGNER, data);\n }\n\n /**\n * @notice Updates the batcher hash.\n *\n * @param _batcherHash New batcher hash.\n */\n function setBatcherHash(bytes32 _batcherHash) external onlyOwner {\n batcherHash = _batcherHash;\n\n bytes memory data = abi.encode(_batcherHash);\n emit ConfigUpdate(VERSION, UpdateType.BATCHER, data);\n }\n\n /**\n * @notice Updates gas config.\n *\n * @param _overhead New overhead value.\n * @param _scalar New scalar value.\n */\n function setGasConfig(uint256 _overhead, uint256 _scalar) external onlyOwner {\n overhead = _overhead;\n scalar = _scalar;\n\n bytes memory data = abi.encode(_overhead, _scalar);\n emit ConfigUpdate(VERSION, UpdateType.GAS_CONFIG, data);\n }\n\n /**\n * @notice Updates the L2 gas limit.\n *\n * @param _gasLimit New gas limit.\n */\n function setGasLimit(uint64 _gasLimit) external onlyOwner {\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n gasLimit = _gasLimit;\n\n bytes memory data = abi.encode(_gasLimit);\n emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data);\n }\n\n /**\n * @notice Low level setter for the unsafe block signer address. This function exists to\n * deduplicate code around storing the unsafeBlockSigner address in storage.\n *\n * @param _unsafeBlockSigner New unsafeBlockSigner value.\n */\n function _setUnsafeBlockSigner(address _unsafeBlockSigner) internal {\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n sstore(slot, _unsafeBlockSigner)\n }\n }\n\n /**\n * @notice A getter for the resource config. Ensures that the struct is\n * returned instead of a tuple.\n *\n * @return ResourceConfig\n */\n function resourceConfig() external view returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig;\n }\n\n /**\n * @notice An external setter for the resource config. In the future, this\n * method may emit an event that the `op-node` picks up for when the\n * resource config is changed.\n *\n * @param _config The new resource config values.\n */\n function setResourceConfig(ResourceMetering.ResourceConfig memory _config) external onlyOwner {\n _setResourceConfig(_config);\n }\n\n /**\n * @notice An internal setter for the resource config. Ensures that the\n * config is sane before storing it by checking for invariants.\n *\n * @param _config The new resource config.\n */\n function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal {\n // Min base fee must be less than or equal to max base fee.\n require(\n _config.minimumBaseFee <= _config.maximumBaseFee,\n \"SystemConfig: min base fee must be less than max base\"\n );\n // Base fee change denominator must be greater than 1.\n require(\n _config.baseFeeMaxChangeDenominator > 1,\n \"SystemConfig: denominator must be larger than 1\"\n );\n // Max resource limit plus system tx gas must be less than or equal to the L2 gas limit.\n // The gas limit must be increased before these values can be increased.\n require(\n _config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit,\n \"SystemConfig: gas limit too low\"\n );\n // Elasticity multiplier must be greater than 0.\n require(\n _config.elasticityMultiplier > 0,\n \"SystemConfig: elasticity multiplier cannot be 0\"\n );\n // No precision loss when computing target resource limit.\n require(\n ((_config.maxResourceLimit / _config.elasticityMultiplier) *\n _config.elasticityMultiplier) == _config.maxResourceLimit,\n \"SystemConfig: precision loss with target resource limit\"\n );\n\n _resourceConfig = _config;\n }\n}\n" - }, - "contracts/L2/BaseFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000019\n * @title BaseFeeVault\n * @notice The BaseFeeVault accumulates the base fee that is paid by transactions.\n */\ncontract BaseFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n}\n" - }, - "contracts/L2/CrossDomainOwnable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\n/**\n * @title CrossDomainOwnable\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is only safe to be used if the\n * CrossDomainMessenger system is bypassed and the caller on L1 is calling the\n * OptimismPortal directly.\n */\nabstract contract CrossDomainOwnable is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `msg.sender` is the owner of the contract.\n */\n function _checkOwner() internal view override {\n require(\n owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender),\n \"CrossDomainOwnable: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable2\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is meant to be used with systems that use\n * the CrossDomainMessenger system. It will not work if the OptimismPortal is used\n * directly.\n */\nabstract contract CrossDomainOwnable2 is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable2: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable2: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable3\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on either L1 or L2. Note that this contract is meant to be used with systems\n * that use the CrossDomainMessenger system. It will not work if the OptimismPortal is\n * used directly.\n */\nabstract contract CrossDomainOwnable3 is Ownable {\n /**\n * @notice If true, the contract uses the cross domain _checkOwner function override. If false\n * it uses the standard Ownable _checkOwner function.\n */\n bool public isLocal = true;\n\n /**\n * @notice Emits when ownership of the contract is transferred. Includes the\n * isLocal field in addition to the standard `Ownable` OwnershipTransferred event.\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n /**\n * @notice Allows for ownership to be transferred with specifying the locality.\n * @param _owner The new owner of the contract.\n * @param _isLocal Configures the locality of the ownership.\n */\n function transferOwnership(address _owner, bool _isLocal) external onlyOwner {\n require(_owner != address(0), \"CrossDomainOwnable3: new owner is the zero address\");\n\n address oldOwner = owner();\n _transferOwnership(_owner);\n isLocal = _isLocal;\n\n emit OwnershipTransferred(oldOwner, _owner, _isLocal);\n }\n\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n if (isLocal) {\n require(owner() == msg.sender, \"CrossDomainOwnable3: caller is not the owner\");\n } else {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable3: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable3: caller is not the owner\"\n );\n }\n }\n}\n" - }, - "contracts/L2/GasPriceOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000000F\n * @title GasPriceOracle\n * @notice This contract maintains the variables responsible for computing the L1 portion of the\n * total fee charged on L2. Before Bedrock, this contract held variables in state that were\n * read during the state transition function to compute the L1 portion of the transaction\n * fee. After Bedrock, this contract now simply proxies the L1Block contract, which has\n * the values used to compute the L1 portion of the fee in its state.\n *\n * The contract exposes an API that is useful for knowing how large the L1 portion of the\n * transaction fee will be. The following events were deprecated with Bedrock:\n * - event OverheadUpdated(uint256 overhead);\n * - event ScalarUpdated(uint256 scalar);\n * - event DecimalsUpdated(uint256 decimals);\n */\ncontract GasPriceOracle is Semver {\n /**\n * @notice Number of decimals used in the scalar.\n */\n uint256 public constant DECIMALS = 6;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Computes the L1 portion of the fee based on the size of the rlp encoded input\n * transaction, the current L1 base fee, and the various dynamic parameters.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.\n *\n * @return L1 fee that should be paid for the tx\n */\n function getL1Fee(bytes memory _data) external view returns (uint256) {\n uint256 l1GasUsed = getL1GasUsed(_data);\n uint256 l1Fee = l1GasUsed * l1BaseFee();\n uint256 divisor = 10**DECIMALS;\n uint256 unscaled = l1Fee * scalar();\n uint256 scaled = unscaled / divisor;\n return scaled;\n }\n\n /**\n * @notice Retrieves the current gas price (base fee).\n *\n * @return Current L2 gas price (base fee).\n */\n function gasPrice() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current base fee.\n *\n * @return Current L2 base fee.\n */\n function baseFee() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current fee overhead.\n *\n * @return Current fee overhead.\n */\n function overhead() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead();\n }\n\n /**\n * @notice Retrieves the current fee scalar.\n *\n * @return Current fee scalar.\n */\n function scalar() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar();\n }\n\n /**\n * @notice Retrieves the latest known L1 base fee.\n *\n * @return Latest known L1 base fee.\n */\n function l1BaseFee() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee();\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the number of decimals used in the scalar.\n *\n * @return Number of decimals used in the scalar.\n */\n function decimals() public pure returns (uint256) {\n return DECIMALS;\n }\n\n /**\n * @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which\n * represents the per-transaction gas overhead of posting the transaction and state\n * roots to L1. Adds 68 bytes of padding to account for the fact that the input does\n * not have a signature.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for.\n *\n * @return Amount of L1 gas used to publish the transaction.\n */\n function getL1GasUsed(bytes memory _data) public view returns (uint256) {\n uint256 total = 0;\n uint256 length = _data.length;\n for (uint256 i = 0; i < length; i++) {\n if (_data[i] == 0) {\n total += 4;\n } else {\n total += 16;\n }\n }\n uint256 unsigned = total + overhead();\n return unsigned + (68 * 16);\n }\n}\n" - }, - "contracts/L2/L1Block.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000015\n * @title L1Block\n * @notice The L1Block predeploy gives users access to information about the last known L1 block.\n * Values within this contract are updated once per epoch (every L1 block) and can only be\n * set by the \"depositor\" account, a special system address. Depositor account transactions\n * are created by the protocol whenever we move to a new epoch.\n */\ncontract L1Block is Semver {\n /**\n * @notice Address of the special depositor account.\n */\n address public constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001;\n\n /**\n * @notice The latest L1 block number known by the L2 system.\n */\n uint64 public number;\n\n /**\n * @notice The latest L1 timestamp known by the L2 system.\n */\n uint64 public timestamp;\n\n /**\n * @notice The latest L1 basefee.\n */\n uint256 public basefee;\n\n /**\n * @notice The latest L1 blockhash.\n */\n bytes32 public hash;\n\n /**\n * @notice The number of L2 blocks in the same epoch.\n */\n uint64 public sequenceNumber;\n\n /**\n * @notice The versioned hash to authenticate the batcher by.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice The overhead value applied to the L1 portion of the transaction\n * fee.\n */\n uint256 public l1FeeOverhead;\n\n /**\n * @notice The scalar value applied to the L1 portion of the transaction fee.\n */\n uint256 public l1FeeScalar;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Updates the L1 block values.\n *\n * @param _number L1 blocknumber.\n * @param _timestamp L1 timestamp.\n * @param _basefee L1 basefee.\n * @param _hash L1 blockhash.\n * @param _sequenceNumber Number of L2 blocks since epoch start.\n * @param _batcherHash Versioned hash to authenticate batcher by.\n * @param _l1FeeOverhead L1 fee overhead.\n * @param _l1FeeScalar L1 fee scalar.\n */\n function setL1BlockValues(\n uint64 _number,\n uint64 _timestamp,\n uint256 _basefee,\n bytes32 _hash,\n uint64 _sequenceNumber,\n bytes32 _batcherHash,\n uint256 _l1FeeOverhead,\n uint256 _l1FeeScalar\n ) external {\n require(\n msg.sender == DEPOSITOR_ACCOUNT,\n \"L1Block: only the depositor account can set L1 block values\"\n );\n\n number = _number;\n timestamp = _timestamp;\n basefee = _basefee;\n hash = _hash;\n sequenceNumber = _sequenceNumber;\n batcherHash = _batcherHash;\n l1FeeOverhead = _l1FeeOverhead;\n l1FeeScalar = _l1FeeScalar;\n }\n}\n" - }, - "contracts/L2/L1FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000001A\n * @title L1FeeVault\n * @notice The L1FeeVault accumulates the L1 portion of the transaction fees.\n */\ncontract L1FeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n}\n" - }, - "contracts/L2/L2CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { L2ToL1MessagePasser } from \"./L2ToL1MessagePasser.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000007\n * @title L2CrossDomainMessenger\n * @notice The L2CrossDomainMessenger is a high-level interface for message passing between L1 and\n * L2 on the L2 side. Users are generally encouraged to use this contract instead of lower\n * level message passing contracts.\n */\ncontract L2CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @custom:semver 1.4.0\n *\n * @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.\n */\n constructor(address _l1CrossDomainMessenger)\n Semver(1, 4, 0)\n CrossDomainMessenger(_l1CrossDomainMessenger)\n {\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote messenger. Use otherMessenger going forward.\n *\n * @return Address of the L1CrossDomainMessenger contract.\n */\n function l1CrossDomainMessenger() public view returns (address) {\n return OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{\n value: _value\n }(_to, _gasLimit, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(Predeploys.L2_TO_L1_MESSAGE_PASSER);\n }\n}\n" - }, - "contracts/L2/L2ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { IOptimismMintableERC721 } from \"../universal/IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L2ERC721Bridge\n * @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.\n * This contract also acts as a burner for tokens being withdrawn.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n */\ncontract L2ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L1. Data supplied here will not be used to\n * execute any code on L1 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L2ERC721Bridge: local token cannot be self\");\n\n // Note that supportsInterface makes a callback to the _localToken address which is user\n // provided.\n require(\n ERC165Checker.supportsInterface(_localToken, type(IOptimismMintableERC721).interfaceId),\n \"L2ERC721Bridge: local token interface is not compliant\"\n );\n\n require(\n _remoteToken == IOptimismMintableERC721(_localToken).remoteToken(),\n \"L2ERC721Bridge: wrong remote token for Optimism Mintable ERC721 local token\"\n );\n\n // When a deposit is finalized, we give the NFT with the same tokenId to the account\n // on L2. Note that safeMint makes a callback to the _to address which is user provided.\n IOptimismMintableERC721(_localToken).safeMint(_to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L2ERC721Bridge: remote token cannot be address(0)\");\n\n // Check that the withdrawal is being initiated by the NFT owner\n require(\n _from == IOptimismMintableERC721(_localToken).ownerOf(_tokenId),\n \"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\"\n );\n\n // Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)\n // slither-disable-next-line reentrancy-events\n address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();\n require(\n remoteToken == _remoteToken,\n \"L2ERC721Bridge: remote token does not match given value\"\n );\n\n // When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2\n // usage\n // slither-disable-next-line reentrancy-events\n IOptimismMintableERC721(_localToken).burn(_from, _tokenId);\n\n bytes memory message = abi.encodeWithSelector(\n L1ERC721Bridge.finalizeBridgeERC721.selector,\n remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Send message to L1 bridge\n // slither-disable-next-line reentrancy-events\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L2/L2StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000010\n * @title L2StandardBridge\n * @notice The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L2, it will be escrowed within this\n * contract. If the ERC20 token is native to L1, it will be burnt.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L2StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal from L2 to L1 is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _otherBridge Address of the L1StandardBridge.\n */\n constructor(address payable _otherBridge)\n Semver(1, 1, 0)\n StandardBridge(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER), _otherBridge)\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateWithdrawal(\n Predeploys.LEGACY_ERC20_ETH,\n msg.sender,\n msg.sender,\n msg.value,\n RECEIVE_DEFAULT_GAS_LIMIT,\n bytes(\"\")\n );\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdraw(\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual onlyEOA {\n _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1 to a target account on L1.\n * Note that if ETH is sent to a contract on L1 and the call fails, then that ETH will\n * be locked in the L1StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20To` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdrawTo(\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual {\n _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a deposit from L1 to L2. To finalize a deposit of ether, use address(0)\n * and the l1Token and the Legacy ERC20 ether predeploy address as the l2Token.\n *\n * @param _l1Token Address of the L1 token to deposit.\n * @param _l2Token Address of the corresponding L2 token.\n * @param _from Address of the depositor.\n * @param _to Address of the recipient.\n * @param _amount Amount of the tokens being deposited.\n * @param _extraData Extra data attached to the deposit.\n */\n function finalizeDeposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable virtual {\n if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n } else {\n finalizeBridgeERC20(_l2Token, _l1Token, _from, _to, _amount, _extraData);\n }\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L1 bridge contract.\n *\n * @return Address of the corresponding L1 bridge contract.\n */\n function l1TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @custom:legacy\n * @notice Internal function to a withdrawal from L2 to L1 to a target account on L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _from Address of the withdrawer.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function _initiateWithdrawal(\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {\n _initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);\n } else {\n address l1Token = OptimismMintableERC20(_l2Token).l1Token();\n _initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ETHBridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ERC20BridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L2/L2ToL1MessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000016\n * @title L2ToL1MessagePasser\n * @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from\n * L2 to L1 can be stored. The storage root of this contract is pulled up to the top level\n * of the L2 output to reduce the cost of proving the existence of sent messages.\n */\ncontract L2ToL1MessagePasser is Semver {\n /**\n * @notice The L1 gas limit set when eth is withdrawn using the receive() function.\n */\n uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Includes the message hashes for all withdrawals\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @notice A unique value hashed with each withdrawal.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Emitted any time a withdrawal is initiated.\n *\n * @param nonce Unique value corresponding to each withdrawal.\n * @param sender The L2 account address which initiated the withdrawal.\n * @param target The L1 account address the call will be send to.\n * @param value The ETH value submitted for withdrawal, to be forwarded to the target.\n * @param gasLimit The minimum amount of gas that must be provided when withdrawing.\n * @param data The data to be forwarded to the target on L1.\n * @param withdrawalHash The hash of the withdrawal.\n */\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n /**\n * @notice Emitted when the balance of this contract is burned.\n *\n * @param amount Amount of ETh that was burned.\n */\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Allows users to withdraw ETH by sending directly to this contract.\n */\n receive() external payable {\n initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @notice Removes all ETH held by this contract from the state. Used to prevent the amount of\n * ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to\n * create a contract and self-destruct it to itself. Anyone can call this function. Not\n * incentivized since this function is very cheap.\n */\n function burn() external {\n uint256 balance = address(this).balance;\n Burn.eth(balance);\n emit WithdrawerBalanceBurnt(balance);\n }\n\n /**\n * @notice Sends a message from L2 to L1.\n *\n * @param _target Address to call on L1 execution.\n * @param _gasLimit Minimum gas limit for executing the message on L1.\n * @param _data Data to forward to L1 target.\n */\n function initiateWithdrawal(\n address _target,\n uint256 _gasLimit,\n bytes memory _data\n ) public payable {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messageNonce(),\n sender: msg.sender,\n target: _target,\n value: msg.value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n sentMessages[withdrawalHash] = true;\n\n emit MessagePassed(\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _gasLimit,\n _data,\n withdrawalHash\n );\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n}\n" - }, - "contracts/L2/SequencerFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000011\n * @title SequencerFeeVault\n * @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during\n * transaction processing and block production.\n */\ncontract SequencerFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the recipient address.\n *\n * @return The recipient address.\n */\n function l1FeeWallet() public view returns (address) {\n return RECIPIENT;\n }\n}\n" - }, - "contracts/deployment/PortalSender.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/**\n * @title PortalSender\n * @notice The PortalSender is a simple intermediate contract that will transfer the balance of the\n * L1StandardBridge to the OptimismPortal during the Bedrock migration.\n */\ncontract PortalSender {\n /**\n * @notice Address of the OptimismPortal contract.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @param _portal Address of the OptimismPortal contract.\n */\n constructor(OptimismPortal _portal) {\n PORTAL = _portal;\n }\n\n /**\n * @notice Sends balance of this contract to the OptimismPortal.\n */\n function donate() public {\n PORTAL.donateETH{ value: address(this).balance }();\n }\n}\n" - }, - "contracts/deployment/SystemDictator.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { PortalSender } from \"./PortalSender.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @title SystemDictator\n * @notice The SystemDictator is responsible for coordinating the deployment of a full Bedrock\n * system. The SystemDictator is designed to support both fresh network deployments and\n * upgrades to existing pre-Bedrock systems.\n */\ncontract SystemDictator is OwnableUpgradeable {\n /**\n * @notice Basic system configuration.\n */\n struct GlobalConfig {\n AddressManager addressManager;\n ProxyAdmin proxyAdmin;\n address controller;\n address finalOwner;\n }\n\n /**\n * @notice Set of proxy addresses.\n */\n struct ProxyAddressConfig {\n address l2OutputOracleProxy;\n address optimismPortalProxy;\n address l1CrossDomainMessengerProxy;\n address l1StandardBridgeProxy;\n address optimismMintableERC20FactoryProxy;\n address l1ERC721BridgeProxy;\n address systemConfigProxy;\n }\n\n /**\n * @notice Set of implementation addresses.\n */\n struct ImplementationAddressConfig {\n L2OutputOracle l2OutputOracleImpl;\n OptimismPortal optimismPortalImpl;\n L1CrossDomainMessenger l1CrossDomainMessengerImpl;\n L1StandardBridge l1StandardBridgeImpl;\n OptimismMintableERC20Factory optimismMintableERC20FactoryImpl;\n L1ERC721Bridge l1ERC721BridgeImpl;\n PortalSender portalSenderImpl;\n SystemConfig systemConfigImpl;\n }\n\n /**\n * @notice Dynamic L2OutputOracle config.\n */\n struct L2OutputOracleDynamicConfig {\n uint256 l2OutputOracleStartingBlockNumber;\n uint256 l2OutputOracleStartingTimestamp;\n }\n\n /**\n * @notice Values for the system config contract.\n */\n struct SystemConfigConfig {\n address owner;\n uint256 overhead;\n uint256 scalar;\n bytes32 batcherHash;\n uint64 gasLimit;\n address unsafeBlockSigner;\n ResourceMetering.ResourceConfig resourceConfig;\n }\n\n /**\n * @notice Combined system configuration.\n */\n struct DeployConfig {\n GlobalConfig globalConfig;\n ProxyAddressConfig proxyAddressConfig;\n ImplementationAddressConfig implementationAddressConfig;\n SystemConfigConfig systemConfigConfig;\n }\n\n /**\n * @notice Step after which exit 1 can no longer be used.\n */\n uint8 public constant EXIT_1_NO_RETURN_STEP = 3;\n\n /**\n * @notice Step where proxy ownership is transferred.\n */\n uint8 public constant PROXY_TRANSFER_STEP = 4;\n\n /**\n * @notice System configuration.\n */\n DeployConfig public config;\n\n /**\n * @notice Dynamic configuration for the L2OutputOracle.\n */\n L2OutputOracleDynamicConfig public l2OutputOracleDynamicConfig;\n\n /**\n * @notice Dynamic configuration for the OptimismPortal. Determines\n * if the system should be paused when initialized.\n */\n bool public optimismPortalDynamicConfig;\n\n /**\n * @notice Current step;\n */\n uint8 public currentStep;\n\n /**\n * @notice Whether or not dynamic config has been set.\n */\n bool public dynamicConfigSet;\n\n /**\n * @notice Whether or not the deployment is finalized.\n */\n bool public finalized;\n\n /**\n * @notice Whether or not the deployment has been exited.\n */\n bool public exited;\n\n /**\n * @notice Address of the old L1CrossDomainMessenger implementation.\n */\n address public oldL1CrossDomainMessenger;\n\n /**\n * @notice Checks that the current step is the expected step, then bumps the current step.\n *\n * @param _step Current step.\n */\n modifier step(uint8 _step) {\n require(!finalized, \"SystemDictator: already finalized\");\n require(!exited, \"SystemDictator: already exited\");\n require(currentStep == _step, \"SystemDictator: incorrect step\");\n _;\n currentStep++;\n }\n\n /**\n * @notice Constructor required to ensure that the implementation of the SystemDictator is\n * initialized upon deployment.\n */\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n // Using this shorter variable as an alias for address(0) just prevents us from having to\n // to use a new line for every single parameter.\n address zero = address(0);\n initialize(\n DeployConfig(\n GlobalConfig(AddressManager(zero), ProxyAdmin(zero), zero, zero),\n ProxyAddressConfig(zero, zero, zero, zero, zero, zero, zero),\n ImplementationAddressConfig(\n L2OutputOracle(zero),\n OptimismPortal(payable(zero)),\n L1CrossDomainMessenger(zero),\n L1StandardBridge(payable(zero)),\n OptimismMintableERC20Factory(zero),\n L1ERC721Bridge(zero),\n PortalSender(zero),\n SystemConfig(zero)\n ),\n SystemConfigConfig(zero, 0, 0, bytes32(0), 0, zero, rcfg)\n )\n );\n }\n\n /**\n * @param _config System configuration.\n */\n function initialize(DeployConfig memory _config) public initializer {\n config = _config;\n currentStep = 1;\n __Ownable_init();\n _transferOwnership(config.globalConfig.controller);\n }\n\n /**\n * @notice Allows the owner to update dynamic config.\n *\n * @param _l2OutputOracleDynamicConfig Dynamic L2OutputOracle config.\n * @param _optimismPortalDynamicConfig Dynamic OptimismPortal config.\n */\n function updateDynamicConfig(\n L2OutputOracleDynamicConfig memory _l2OutputOracleDynamicConfig,\n bool _optimismPortalDynamicConfig\n ) external onlyOwner {\n l2OutputOracleDynamicConfig = _l2OutputOracleDynamicConfig;\n optimismPortalDynamicConfig = _optimismPortalDynamicConfig;\n dynamicConfigSet = true;\n }\n\n /**\n * @notice Configures the ProxyAdmin contract.\n */\n function step1() public onlyOwner step(1) {\n // Set the AddressManager in the ProxyAdmin.\n config.globalConfig.proxyAdmin.setAddressManager(config.globalConfig.addressManager);\n\n // Set the L1CrossDomainMessenger to the RESOLVED proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n ProxyAdmin.ProxyType.RESOLVED\n );\n\n // Set the implementation name for the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.setImplementationName(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Set the L1StandardBridge to the CHUGSPLASH proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1StandardBridgeProxy,\n ProxyAdmin.ProxyType.CHUGSPLASH\n );\n\n // Upgrade and initialize the SystemConfig so the Sequencer can start up.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.systemConfigProxy),\n address(config.implementationAddressConfig.systemConfigImpl),\n abi.encodeCall(\n SystemConfig.initialize,\n (\n config.systemConfigConfig.owner,\n config.systemConfigConfig.overhead,\n config.systemConfigConfig.scalar,\n config.systemConfigConfig.batcherHash,\n config.systemConfigConfig.gasLimit,\n config.systemConfigConfig.unsafeBlockSigner,\n config.systemConfigConfig.resourceConfig\n )\n )\n );\n }\n\n /**\n * @notice Pauses the system by shutting down the L1CrossDomainMessenger and setting the\n * deposit halt flag to tell the Sequencer's DTL to stop accepting deposits.\n */\n function step2() public onlyOwner step(2) {\n // Store the address of the old L1CrossDomainMessenger implementation. We will need this\n // address in the case that we have to exit early.\n oldL1CrossDomainMessenger = config.globalConfig.addressManager.getAddress(\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Temporarily brick the L1CrossDomainMessenger by setting its implementation address to\n // address(0) which will cause the ResolvedDelegateProxy to revert. Better than pausing\n // the L1CrossDomainMessenger via pause() because it can be easily reverted.\n config.globalConfig.addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(0));\n\n // Set the DTL shutoff block, which will tell the DTL to stop syncing new deposits from the\n // CanonicalTransactionChain. We do this by setting an address in the AddressManager\n // because the DTL already has a reference to the AddressManager and this way we don't also\n // need to give it a reference to the SystemDictator.\n config.globalConfig.addressManager.setAddress(\n \"DTL_SHUTOFF_BLOCK\",\n address(uint160(block.number))\n );\n }\n\n /**\n * @notice Removes deprecated addresses from the AddressManager.\n */\n function step3() external onlyOwner step(EXIT_1_NO_RETURN_STEP) {\n // Remove all deprecated addresses from the AddressManager\n string[17] memory deprecated = [\n \"OVM_CanonicalTransactionChain\",\n \"OVM_L2CrossDomainMessenger\",\n \"OVM_DecompressionPrecompileAddress\",\n \"OVM_Sequencer\",\n \"OVM_Proposer\",\n \"OVM_ChainStorageContainer-CTC-batches\",\n \"OVM_ChainStorageContainer-CTC-queue\",\n \"OVM_CanonicalTransactionChain\",\n \"OVM_StateCommitmentChain\",\n \"OVM_BondManager\",\n \"OVM_ExecutionManager\",\n \"OVM_FraudVerifier\",\n \"OVM_StateManagerFactory\",\n \"OVM_StateTransitionerFactory\",\n \"OVM_SafetyChecker\",\n \"OVM_L1MultiMessageRelayer\",\n \"BondManager\"\n ];\n\n for (uint256 i = 0; i < deprecated.length; i++) {\n config.globalConfig.addressManager.setAddress(deprecated[i], address(0));\n }\n }\n\n /**\n * @notice Transfers system ownership to the ProxyAdmin.\n */\n function step4() external onlyOwner step(PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the ProxyAdmin.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1StandardBridge to the ProxyAdmin.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the ProxyAdmin.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.proxyAdmin)\n );\n }\n\n /**\n * @notice Upgrades and initializes proxy contracts.\n */\n function step5() external onlyOwner step(5) {\n // Dynamic config must be set before we can initialize the L2OutputOracle.\n require(dynamicConfigSet, \"SystemDictator: dynamic oracle config is not yet initialized\");\n\n // Upgrade and initialize the L2OutputOracle.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l2OutputOracleProxy),\n address(config.implementationAddressConfig.l2OutputOracleImpl),\n abi.encodeCall(\n L2OutputOracle.initialize,\n (\n l2OutputOracleDynamicConfig.l2OutputOracleStartingBlockNumber,\n l2OutputOracleDynamicConfig.l2OutputOracleStartingTimestamp\n )\n )\n );\n\n // Upgrade and initialize the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.optimismPortalProxy),\n address(config.implementationAddressConfig.optimismPortalImpl),\n abi.encodeCall(OptimismPortal.initialize, (optimismPortalDynamicConfig))\n );\n\n // Upgrade the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1CrossDomainMessengerProxy),\n address(config.implementationAddressConfig.l1CrossDomainMessengerImpl)\n );\n\n // Try to initialize the L1CrossDomainMessenger, only fail if it's already been initialized.\n try\n L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy)\n .initialize()\n {\n // L1CrossDomainMessenger is the one annoying edge case difference between existing\n // networks and fresh networks because in existing networks it'll already be\n // initialized but in fresh networks it won't be. Try/catch is the easiest and most\n // consistent way to handle this because initialized() is not exposed publicly.\n } catch Error(string memory reason) {\n require(\n keccak256(abi.encodePacked(reason)) ==\n keccak256(\"Initializable: contract is already initialized\"),\n string.concat(\"SystemDictator: unexpected error initializing L1XDM: \", reason)\n );\n } catch {\n revert(\"SystemDictator: unexpected error initializing L1XDM (no reason)\");\n }\n\n // Transfer ETH from the L1StandardBridge to the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.portalSenderImpl),\n abi.encodeCall(PortalSender.donate, ())\n );\n\n // Upgrade the L1StandardBridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.l1StandardBridgeImpl)\n );\n\n // Upgrade the OptimismMintableERC20Factory (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.optimismMintableERC20FactoryProxy),\n address(config.implementationAddressConfig.optimismMintableERC20FactoryImpl)\n );\n\n // Upgrade the L1ERC721Bridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1ERC721BridgeProxy),\n address(config.implementationAddressConfig.l1ERC721BridgeImpl)\n );\n }\n\n /**\n * @notice Calls the first 2 steps of the migration process.\n */\n function phase1() external onlyOwner {\n step1();\n step2();\n }\n\n /**\n * @notice Tranfers admin ownership to the final owner.\n */\n function finalize() external onlyOwner {\n // Transfer ownership of the ProxyAdmin to the final owner.\n config.globalConfig.proxyAdmin.transferOwnership(config.globalConfig.finalOwner);\n\n // Optionally also transfer AddressManager and L1StandardBridge if we still own it. Might\n // happen if we're exiting early.\n if (currentStep <= PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the final owner.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1StandardBridge to the final owner.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the final owner.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.finalOwner)\n );\n }\n\n // Mark the deployment as finalized.\n finalized = true;\n }\n\n /**\n * @notice First exit point, can only be called before step 3 is executed.\n */\n function exit1() external onlyOwner {\n require(\n currentStep == EXIT_1_NO_RETURN_STEP,\n \"SystemDictator: can only exit1 before step 3 is executed\"\n );\n\n // Reset the L1CrossDomainMessenger to the old implementation.\n config.globalConfig.addressManager.setAddress(\n \"OVM_L1CrossDomainMessenger\",\n oldL1CrossDomainMessenger\n );\n\n // Unset the DTL shutoff block which will allow the DTL to sync again.\n config.globalConfig.addressManager.setAddress(\"DTL_SHUTOFF_BLOCK\", address(0));\n\n // Mark the deployment as exited.\n exited = true;\n }\n}\n" - }, - "contracts/echidna/FuzzAddressAliasing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract EchidnaFuzzAddressAliasing {\n bool internal failedRoundtrip;\n\n /**\n * @notice Takes an address to be aliased with AddressAliasHelper and then unaliased\n * and updates the test contract's state indicating if the round trip encoding\n * failed.\n */\n function testRoundTrip(address addr) public {\n // Alias our address\n address aliasedAddr = AddressAliasHelper.applyL1ToL2Alias(addr);\n\n // Unalias our address\n address undoneAliasAddr = AddressAliasHelper.undoL1ToL2Alias(aliasedAddr);\n\n // If our round trip aliasing did not return the original result, set our state.\n if (addr != undoneAliasAddr) {\n failedRoundtrip = true;\n }\n }\n\n /**\n * @custom:invariant Address aliases are always able to be undone.\n *\n * Asserts that an address that has been aliased with `applyL1ToL2Alias` can always\n * be unaliased with `undoL1ToL2Alias`.\n */\n function echidna_round_trip_aliasing() public view returns (bool) {\n // ASSERTION: The round trip aliasing done in testRoundTrip(...) should never fail.\n return !failedRoundtrip;\n }\n}\n" - }, - "contracts/echidna/FuzzBurn.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\n\ncontract EchidnaFuzzBurnEth is StdUtils {\n bool internal failedEthBurn;\n\n /**\n * @notice Takes an integer amount of eth to burn through the Burn library and\n * updates the contract state if an incorrect amount of eth moved from the contract\n */\n function testBurn(uint256 _value) public {\n // cache the contract's eth balance\n uint256 preBurnBalance = address(this).balance;\n uint256 value = bound(_value, 0, preBurnBalance);\n\n // execute a burn of _value eth\n Burn.eth(value);\n\n // check that exactly value eth was transfered from the contract\n unchecked {\n if (address(this).balance != preBurnBalance - value) {\n failedEthBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `eth(uint256)` always burns the exact amount of eth passed.\n *\n * Asserts that when `Burn.eth(uint256)` is called, it always burns the exact amount\n * of ETH passed to the function.\n */\n function echidna_burn_eth() public view returns (bool) {\n // ASSERTION: The amount burned should always match the amount passed exactly\n return !failedEthBurn;\n }\n}\n\ncontract EchidnaFuzzBurnGas is StdUtils {\n bool internal failedGasBurn;\n\n /**\n * @notice Takes an integer amount of gas to burn through the Burn library and\n * updates the contract state if at least that amount of gas was not burned\n * by the library\n */\n function testGas(uint256 _value) public {\n // cap the value to the max resource limit\n uint256 MAX_RESOURCE_LIMIT = 8_000_000;\n uint256 value = bound(_value, 0, MAX_RESOURCE_LIMIT);\n\n // cache the contract's current remaining gas\n uint256 preBurnGas = gasleft();\n\n // execute the gas burn\n Burn.gas(value);\n\n // cache the remaining gas post burn\n uint256 postBurnGas = gasleft();\n\n // check that at least value gas was burnt (and that there was no underflow)\n unchecked {\n if (postBurnGas - preBurnGas > value || preBurnGas - value > preBurnGas) {\n failedGasBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `gas(uint256)` always burns at least the amount of gas passed.\n *\n * Asserts that when `Burn.gas(uint256)` is called, it always burns at least the amount\n * of gas passed to the function.\n */\n function echidna_burn_gas() public view returns (bool) {\n // ASSERTION: The amount of gas burned should be strictly greater than the\n // the amount passed as _value (minimum _value + whatever minor overhead to\n // the value after the call)\n return !failedGasBurn;\n }\n}\n" - }, - "contracts/echidna/FuzzEncoding.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzEncoding {\n bool internal failedRoundtripAToB;\n bool internal failedRoundtripBToA;\n\n /**\n * @notice Takes a pair of integers to be encoded into a versioned nonce with the\n * Encoding library and then decoded and updates the test contract's state\n * indicating if the round trip encoding failed.\n */\n function testRoundTripAToB(uint240 _nonce, uint16 _version) public {\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(encodedVersionedNonce);\n\n // If our round trip encoding did not return the original result, set our state.\n if ((decodedNonce != _nonce) || (decodedVersion != _version)) {\n failedRoundtripAToB = true;\n }\n }\n\n /**\n * @notice Takes an integer representing a packed version and nonce and attempts\n * to decode them using the Encoding library before re-encoding and updates\n * the test contract's state indicating if the round trip encoding failed.\n */\n function testRoundTripBToA(uint256 _versionedNonce) public {\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(_versionedNonce);\n\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(decodedNonce, decodedVersion);\n\n // If our round trip encoding did not return the original result, set our state.\n if (encodedVersionedNonce != _versionedNonce) {\n failedRoundtripBToA = true;\n }\n }\n\n /**\n * @custom:invariant `testRoundTripAToB` never fails.\n *\n * Asserts that a raw versioned nonce can be encoded / decoded to reach the same raw value.\n */\n function echidna_round_trip_encoding_AToB() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripAToB(...)\n return !failedRoundtripAToB;\n }\n\n /**\n * @custom:invariant `testRoundTripBToA` never fails.\n *\n * Asserts that an encoded versioned nonce can always be decoded / re-encoded to reach\n * the same encoded value.\n */\n function echidna_round_trip_encoding_BToA() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripBToA should never\n // fail.\n return !failedRoundtripBToA;\n }\n}\n" - }, - "contracts/echidna/FuzzHashing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzHashing {\n bool internal failedCrossDomainHashHighVersion;\n bool internal failedCrossDomainHashV0;\n bool internal failedCrossDomainHashV1;\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash with a randomly\n * generated version. Only schema versions 0 and 1 are supported and all others should revert.\n */\n function testHashCrossDomainMessageHighVersion(\n uint16 _version,\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // hash the cross domain message. we don't need to store the result since the function\n // validates and should revert if an invalid version (>1) is encoded\n Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);\n\n // check that execution never makes it this far for an invalid version\n if (_version > 1) {\n failedCrossDomainHashHighVersion = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v0 schema\n * and compares the output of a call to the unversioned function to the v0 function directly\n */\n function testHashCrossDomainMessageV0(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 0\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 0);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n encodedNonce\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV0 = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v1 schema\n * and compares the output of a call to the unversioned function to the v1 function directly\n */\n function testHashCrossDomainMessageV1(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 1\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 1);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV1 = true;\n }\n }\n\n /**\n * @custom:invariant `hashCrossDomainMessage` reverts if `version` is > `1`.\n *\n * The `hashCrossDomainMessage` function should always revert if the `version` passed is > `1`.\n */\n function echidna_hash_xdomain_msg_high_version() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage will never succeed for a version > 1\n return !failedCrossDomainHashHighVersion;\n }\n\n /**\n * @custom:invariant `version` = `0`: `hashCrossDomainMessage` and `hashCrossDomainMessageV0`\n * are equivalent.\n *\n * If the version passed is 0, `hashCrossDomainMessage` and `hashCrossDomainMessageV0` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_0() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV0\n // should always match when the version passed is 0\n return !failedCrossDomainHashV0;\n }\n\n /**\n * @custom:invariant `version` = `1`: `hashCrossDomainMessage` and `hashCrossDomainMessageV1`\n * are equivalent.\n *\n * If the version passed is 1, `hashCrossDomainMessage` and `hashCrossDomainMessageV1` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_1() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV1\n // should always match when the version passed is 1\n return !failedCrossDomainHashV1;\n }\n}\n" - }, - "contracts/echidna/FuzzOptimismPortal.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzOptimismPortal {\n OptimismPortal internal portal;\n bool internal failedToComplete;\n\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n SystemConfig systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: rcfg\n });\n\n portal = new OptimismPortal({\n _l2Oracle: L2OutputOracle(address(0)),\n _guardian: address(0),\n _paused: false,\n _config: systemConfig\n });\n }\n\n // A test intended to identify any unexpected halting conditions\n function testDepositTransactionCompletes(\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable {\n failedToComplete = true;\n require(!_isCreation || _to == address(0), \"EchidnaFuzzOptimismPortal: invalid test case.\");\n portal.depositTransaction{ value: _mint }(_to, _value, _gasLimit, _isCreation, _data);\n failedToComplete = false;\n }\n\n /**\n * @custom:invariant Deposits of any value should always succeed unless\n * `_to` = `address(0)` or `_isCreation` = `true`.\n *\n * All deposits, barring creation transactions and transactions sent to `address(0)`,\n * should always succeed.\n */\n function echidna_deposit_completes() public view returns (bool) {\n return !failedToComplete;\n }\n}\n" - }, - "contracts/echidna/FuzzResourceMetering.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzResourceMetering is ResourceMetering, StdUtils {\n bool internal failedMaxGasPerBlock;\n bool internal failedRaiseBaseFee;\n bool internal failedLowerBaseFee;\n bool internal failedNeverBelowMinBaseFee;\n bool internal failedMaxRaiseBaseFeePerBlock;\n bool internal failedMaxLowerBaseFeePerBlock;\n\n // Used as a special flag for the purpose of identifying unchecked math errors specifically\n // in the test contracts, not the target contracts themselves.\n bool internal underflow;\n\n constructor() {\n initialize();\n }\n\n function initialize() internal initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public pure returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n return rcfg;\n }\n\n /**\n * @notice Takes the necessary parameters to allow us to burn arbitrary amounts of gas to test\n * the underlying resource metering/gas market logic\n */\n function testBurn(uint256 _gasToBurn, bool _raiseBaseFee) public {\n // Part 1: we cache the current param values and do some basic checks on them.\n uint256 cachedPrevBaseFee = uint256(params.prevBaseFee);\n uint256 cachedPrevBoughtGas = uint256(params.prevBoughtGas);\n uint256 cachedPrevBlockNum = uint256(params.prevBlockNum);\n\n ResourceMetering.ResourceConfig memory rcfg = resourceConfig();\n uint256 targetResourceLimit = uint256(rcfg.maxResourceLimit) /\n uint256(rcfg.elasticityMultiplier);\n\n // check that the last block's base fee hasn't dropped below the minimum\n if (cachedPrevBaseFee < uint256(rcfg.minimumBaseFee)) {\n failedNeverBelowMinBaseFee = true;\n }\n // check that the last block didn't consume more than the max amount of gas\n if (cachedPrevBoughtGas > uint256(rcfg.maxResourceLimit)) {\n failedMaxGasPerBlock = true;\n }\n\n // Part2: we perform the gas burn\n\n // force the gasToBurn into the correct range based on whether we intend to\n // raise or lower the baseFee after this block, respectively\n uint256 gasToBurn;\n if (_raiseBaseFee) {\n gasToBurn = bound(\n _gasToBurn,\n uint256(targetResourceLimit),\n uint256(rcfg.maxResourceLimit)\n );\n } else {\n gasToBurn = bound(_gasToBurn, 0, targetResourceLimit);\n }\n\n _burnInternal(uint64(gasToBurn));\n\n // Part 3: we run checks and modify our invariant flags based on the updated params values\n\n // Calculate the maximum allowed baseFee change (per block)\n uint256 maxBaseFeeChange = cachedPrevBaseFee / uint256(rcfg.baseFeeMaxChangeDenominator);\n\n // If the last block used more than the target amount of gas (and there were no\n // empty blocks in between), ensure this block's baseFee increased, but not by\n // more than the max amount per block\n if (\n (cachedPrevBoughtGas > uint256(targetResourceLimit)) &&\n (uint256(params.prevBlockNum) - cachedPrevBlockNum == 1)\n ) {\n failedRaiseBaseFee = failedRaiseBaseFee || (params.prevBaseFee <= cachedPrevBaseFee);\n failedMaxRaiseBaseFeePerBlock =\n failedMaxRaiseBaseFeePerBlock ||\n ((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);\n }\n\n // If the last block used less than the target amount of gas, (or was empty),\n // ensure that: this block's baseFee was decreased, but not by more than the max amount\n if (\n (cachedPrevBoughtGas < uint256(targetResourceLimit)) ||\n (uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)\n ) {\n // Invariant: baseFee should decrease\n failedLowerBaseFee =\n failedLowerBaseFee ||\n (uint256(params.prevBaseFee) > cachedPrevBaseFee);\n\n if (params.prevBlockNum - cachedPrevBlockNum == 1) {\n // No empty blocks\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n } else if (params.prevBlockNum - cachedPrevBlockNum > 1) {\n // We have at least one empty block\n // Update the maxBaseFeeChange to account for multiple blocks having passed\n unchecked {\n maxBaseFeeChange = uint256(\n int256(cachedPrevBaseFee) -\n Arithmetic.clamp(\n Arithmetic.cdexp(\n int256(cachedPrevBaseFee),\n int256(uint256(rcfg.baseFeeMaxChangeDenominator)),\n int256(uint256(params.prevBlockNum) - cachedPrevBlockNum)\n ),\n int256(uint256(rcfg.minimumBaseFee)),\n int256(uint256(rcfg.maximumBaseFee))\n )\n );\n }\n\n // Detect an underflow in the previous calculation.\n // Without using unchecked above, and detecting the underflow here, echidna would\n // otherwise ignore the revert.\n underflow = underflow || maxBaseFeeChange > cachedPrevBaseFee;\n\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n }\n }\n }\n\n function _burnInternal(uint64 _gasToBurn) private metered(_gasToBurn) {}\n\n /**\n * @custom:invariant The base fee should increase if the last block used more\n * than the target amount of gas\n *\n * If the last block used more than the target amount of gas (and there were no\n * empty blocks in between), ensure this block's baseFee increased, but not by\n * more than the max amount per block.\n */\n function echidna_high_usage_raise_baseFee() public view returns (bool) {\n return !failedRaiseBaseFee;\n }\n\n /**\n * @custom:invariant The base fee should decrease if the last block used less\n * than the target amount of gas\n *\n * If the previous block used less than the target amount of gas, the base fee should decrease,\n * but not more than the max amount.\n */\n function echidna_low_usage_lower_baseFee() public view returns (bool) {\n return !failedLowerBaseFee;\n }\n\n /**\n * @custom:invariant A block's base fee should never be below `MINIMUM_BASE_FEE`\n *\n * This test asserts that a block's base fee can never drop below the\n * `MINIMUM_BASE_FEE` threshold.\n */\n function echidna_never_below_min_baseFee() public view returns (bool) {\n return !failedNeverBelowMinBaseFee;\n }\n\n /**\n * @custom:invariant A block can never consume more than `MAX_RESOURCE_LIMIT` gas.\n *\n * This test asserts that a block can never consume more than the `MAX_RESOURCE_LIMIT`\n * gas threshold.\n */\n function echidna_never_above_max_gas_limit() public view returns (bool) {\n return !failedMaxGasPerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be raised more than the max base fee change.\n *\n * After a block consumes more gas than the target gas, the base fee cannot be raised\n * more than the maximum amount allowed. The max base fee change (per-block) is derived\n * as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_increase() public view returns (bool) {\n return !failedMaxRaiseBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be lowered more than the max base fee change.\n *\n * After a block consumes less than the target gas, the base fee cannot be lowered more\n * than the maximum amount allowed. The max base fee change (per-block) is derived as\n *follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_decrease() public view returns (bool) {\n return !failedMaxLowerBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The `maxBaseFeeChange` calculation over multiple blocks can never\n * underflow.\n *\n * When calculating the `maxBaseFeeChange` after multiple empty blocks, the calculation\n * should never be allowed to underflow.\n */\n function echidna_underflow() public view returns (bool) {\n return !underflow;\n }\n}\n" - }, - "contracts/governance/GovernanceToken.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:predeploy 0x4200000000000000000000000000000000000042\n * @title GovernanceToken\n * @notice The Optimism token used in governance and supporting voting and delegation. Implements\n * EIP 2612 allowing signed approvals. Contract is \"owned\" by a `MintManager` instance with\n * permission to the `mint` function only, for the purposes of enforcing the token inflation\n * schedule.\n */\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\n constructor() ERC20(\"Optimism\", \"OP\") ERC20Permit(\"Optimism\") {}\n\n /**\n * @notice Allows the owner to mint tokens.\n *\n * @param _account The account receiving minted tokens.\n * @param _amount The amount of tokens to mint.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n /**\n * @notice Callback called after a token transfer.\n *\n * @param from The account sending tokens.\n * @param to The account receiving tokens.\n * @param amount The amount of tokens being transfered.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20, ERC20Votes) {\n super._afterTokenTransfer(from, to, amount);\n }\n\n /**\n * @notice Internal mint function.\n *\n * @param to The account receiving minted tokens.\n * @param amount The amount of tokens to mint.\n */\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._mint(to, amount);\n }\n\n /**\n * @notice Internal burn function.\n *\n * @param account The account that tokens will be burned from.\n * @param amount The amount of tokens that will be burned.\n */\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._burn(account, amount);\n }\n}\n" - }, - "contracts/governance/MintManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./GovernanceToken.sol\";\n\n/**\n * @title MintManager\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\n * Contract acts as the token \"mint manager\" with permission to the `mint` function only.\n * Currently permitted to mint once per year of up to 2% of the total token supply.\n * Upgradable to allow changes in the inflation schedule.\n */\ncontract MintManager is Ownable {\n /**\n * @notice The GovernanceToken that the MintManager can mint tokens\n */\n GovernanceToken public immutable governanceToken;\n\n /**\n * @notice The amount of tokens that can be minted per year. The value is a fixed\n * point number with 4 decimals.\n */\n uint256 public constant MINT_CAP = 20; // 2%\n\n /**\n * @notice The number of decimals for the MINT_CAP.\n */\n uint256 public constant DENOMINATOR = 1000;\n\n /**\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\n * be minted again.\n */\n uint256 public constant MINT_PERIOD = 365 days;\n\n /**\n * @notice Tracks the time of last mint.\n */\n uint256 public mintPermittedAfter;\n\n /**\n * @param _upgrader The owner of this contract\n * @param _governanceToken The governance token this contract can mint\n * tokens of\n */\n constructor(address _upgrader, address _governanceToken) {\n transferOwnership(_upgrader);\n governanceToken = GovernanceToken(_governanceToken);\n }\n\n /**\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\n *\n * @param _account Address to mint new tokens to.\n * @param _amount Amount of tokens to be minted.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n if (mintPermittedAfter > 0) {\n require(\n mintPermittedAfter <= block.timestamp,\n \"MintManager: minting not permitted yet\"\n );\n\n require(\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\n \"MintManager: mint amount exceeds cap\"\n );\n }\n\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\n governanceToken.mint(_account, _amount);\n }\n\n /**\n * @notice Upgrade the owner of the governance token to a new MintManager.\n *\n * @param _newMintManager The MintManager to upgrade to.\n */\n function upgrade(address _newMintManager) public onlyOwner {\n require(\n _newMintManager != address(0),\n \"MintManager: mint manager cannot be the zero address\"\n );\n\n governanceToken.transferOwnership(_newMintManager);\n }\n}\n" - }, - "contracts/legacy/AddressManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:legacy\n * @title AddressManager\n * @notice AddressManager is a legacy contract that was used in the old version of the Optimism\n * system to manage a registry of string names to addresses. We now use a more standard\n * proxy system instead, but this contract is still necessary for backwards compatibility\n * with several older contracts.\n */\ncontract AddressManager is Ownable {\n /**\n * @notice Mapping of the hashes of string names to addresses.\n */\n mapping(bytes32 => address) private addresses;\n\n /**\n * @notice Emitted when an address is modified in the registry.\n *\n * @param name String name being set in the registry.\n * @param newAddress Address set for the given name.\n * @param oldAddress Address that was previously set for the given name.\n */\n event AddressSet(string indexed name, address newAddress, address oldAddress);\n\n /**\n * @notice Changes the address associated with a particular name.\n *\n * @param _name String name to associate an address with.\n * @param _address Address to associate with the name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n bytes32 nameHash = _getNameHash(_name);\n address oldAddress = addresses[nameHash];\n addresses[nameHash] = _address;\n\n emit AddressSet(_name, _address, oldAddress);\n }\n\n /**\n * @notice Retrieves the address associated with a given name.\n *\n * @param _name Name to retrieve an address for.\n *\n * @return Address associated with the given name.\n */\n function getAddress(string memory _name) external view returns (address) {\n return addresses[_getNameHash(_name)];\n }\n\n /**\n * @notice Computes the hash of a name.\n *\n * @param _name Name to compute a hash for.\n *\n * @return Hash of the given name.\n */\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(_name));\n }\n}\n" - }, - "contracts/legacy/DeployerWhitelist.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000002\n * @title DeployerWhitelist\n * @notice DeployerWhitelist is a legacy contract that was originally used to act as a whitelist of\n * addresses allowed to the Optimism network. The DeployerWhitelist has since been\n * disabled, but the code is kept in state for the sake of full backwards compatibility.\n * As of the Bedrock upgrade, the DeployerWhitelist is completely unused by the Optimism\n * system and could, in theory, be removed entirely.\n */\ncontract DeployerWhitelist is Semver {\n /**\n * @notice Address of the owner of this contract. Note that when this address is set to\n * address(0), the whitelist is disabled.\n */\n address public owner;\n\n /**\n * @notice Mapping of deployer addresses to boolean whitelist status.\n */\n mapping(address => bool) public whitelist;\n\n /**\n * @notice Emitted when the owner of this contract changes.\n *\n * @param oldOwner Address of the previous owner.\n * @param newOwner Address of the new owner.\n */\n event OwnerChanged(address oldOwner, address newOwner);\n\n /**\n * @notice Emitted when the whitelist status of a deployer changes.\n *\n * @param deployer Address of the deployer.\n * @param whitelisted Boolean indicating whether the deployer is whitelisted.\n */\n event WhitelistStatusChanged(address deployer, bool whitelisted);\n\n /**\n * @notice Emitted when the whitelist is disabled.\n *\n * @param oldOwner Address of the final owner of the whitelist.\n */\n event WhitelistDisabled(address oldOwner);\n\n /**\n * @notice Blocks functions to anyone except the contract owner.\n */\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"DeployerWhitelist: function can only be called by the owner of this contract\"\n );\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Adds or removes an address from the deployment whitelist.\n *\n * @param _deployer Address to update permissions for.\n * @param _isWhitelisted Whether or not the address is whitelisted.\n */\n function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external onlyOwner {\n whitelist[_deployer] = _isWhitelisted;\n emit WhitelistStatusChanged(_deployer, _isWhitelisted);\n }\n\n /**\n * @notice Updates the owner of this contract.\n *\n * @param _owner Address of the new owner.\n */\n function setOwner(address _owner) external onlyOwner {\n // Prevent users from setting the whitelist owner to address(0) except via\n // enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to\n // any other address that doesn't have a corresponding knowable private key.\n require(\n _owner != address(0),\n \"DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment\"\n );\n\n emit OwnerChanged(owner, _owner);\n owner = _owner;\n }\n\n /**\n * @notice Permanently enables arbitrary contract deployment and deletes the owner.\n */\n function enableArbitraryContractDeployment() external onlyOwner {\n emit WhitelistDisabled(owner);\n owner = address(0);\n }\n\n /**\n * @notice Checks whether an address is allowed to deploy contracts.\n *\n * @param _deployer Address to check.\n *\n * @return Whether or not the address can deploy contracts.\n */\n function isDeployerAllowed(address _deployer) external view returns (bool) {\n return (owner == address(0) || whitelist[_deployer]);\n }\n}\n" - }, - "contracts/legacy/L1BlockNumber.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000013\n * @title L1BlockNumber\n * @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract\n * in the old version of the Optimism system. Only necessary for backwards compatibility.\n * If you want to access the L1 block number going forward, you should use the L1Block\n * contract instead.\n */\ncontract L1BlockNumber is Semver {\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Returns the L1 block number.\n */\n receive() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Returns the L1 block number.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Retrieves the latest L1 block number.\n *\n * @return Latest L1 block number.\n */\n function getL1BlockNumber() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).number();\n }\n}\n" - }, - "contracts/legacy/L1ChugSplashProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title IL1ChugSplashDeployer\n */\ninterface IL1ChugSplashDeployer {\n function isUpgrading() external view returns (bool);\n}\n\n/**\n * @custom:legacy\n * @title L1ChugSplashProxy\n * @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\n * functions `setCode` and `setStorage` for changing the code or storage of the contract.\n *\n * Note for future developers: do NOT make anything in this contract 'public' unless you\n * know what you're doing. Anything public can potentially have a function signature that\n * conflicts with a signature attached to the implementation contract. Public functions\n * SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good\n * reason not to have that modifier. And there almost certainly is not a good reason to not\n * have that modifier. Beware!\n */\ncontract L1ChugSplashProxy {\n /**\n * @notice \"Magic\" prefix. When prepended to some arbitrary bytecode and used to create a\n * contract, the appended bytecode will be deployed as given.\n */\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice Blocks a function from being called when the parent signals that the system should\n * be paused via an isUpgrading function.\n */\n modifier onlyWhenNotPaused() {\n address owner = _getOwner();\n\n // We do a low-level call because there's no guarantee that the owner actually *is* an\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\n // it turns out that it isn't the right type of contract.\n (bool success, bytes memory returndata) = owner.staticcall(\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)\n );\n\n // If the call was unsuccessful then we assume that there's no \"isUpgrading\" method and we\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\n // long. If this isn't the case then we can safely ignore the result.\n if (success && returndata.length == 32) {\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\n // case that the isUpgrading function returned something other than 0 or 1. But we only\n // really care about the case where this value is 0 (= false).\n uint256 ret = abi.decode(returndata, (uint256));\n require(ret == 0, \"L1ChugSplashProxy: system is currently being upgraded\");\n }\n\n _;\n }\n\n /**\n * @notice Makes a proxy call instead of triggering the given function when the caller is\n * either the owner or the zero address. Caller can only ever be the zero address if\n * this function is being called off-chain via eth_call, which is totally fine and can\n * be convenient for client-side tooling. Avoids situations where the proxy and\n * implementation share a sighash and the proxy function ends up being called instead\n * of the implementation one.\n *\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If\n * there's a way for someone to send a transaction with msg.sender == address(0) in any\n * real context then we have much bigger problems. Primary reason to include this\n * additional allowed sender is because the owner address can be changed dynamically\n * and we do not want clients to have to keep track of the current owner in order to\n * make an eth_call that doesn't trigger the proxied contract.\n */\n // slither-disable-next-line incorrect-modifier\n modifier proxyCallIfNotOwner() {\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @param _owner Address of the initial contract owner.\n */\n constructor(address _owner) {\n _setOwner(_owner);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Sets the code that should be running behind this proxy.\n *\n * Note: This scheme is a bit different from the standard proxy scheme where one would\n * typically deploy the code separately and then set the implementation address. We're\n * doing it this way because it gives us a lot more freedom on the client side. Can\n * only be triggered by the contract owner.\n *\n * @param _code New contract code to run inside this contract.\n */\n function setCode(bytes memory _code) external proxyCallIfNotOwner {\n // Get the code hash of the current implementation.\n address implementation = _getImplementation();\n\n // If the code hash matches the new implementation then we return early.\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\n return;\n }\n\n // Create the deploycode by appending the magic prefix.\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\n\n // Deploy the code and set the new implementation address.\n address newImplementation;\n assembly {\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\n }\n\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\n // actually fail this check. Should only happen if the contract creation from above runs\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\n // should be doing this check anyway though.\n require(\n _getAccountCodeHash(newImplementation) == keccak256(_code),\n \"L1ChugSplashProxy: code was not correctly deployed\"\n );\n\n _setImplementation(newImplementation);\n }\n\n /**\n * @notice Modifies some storage slot within the proxy contract. Gives us a lot of power to\n * perform upgrades in a more transparent way. Only callable by the owner.\n *\n * @param _key Storage key to modify.\n * @param _value New value for the storage key.\n */\n function setStorage(bytes32 _key, bytes32 _value) external proxyCallIfNotOwner {\n assembly {\n sstore(_key, _value)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _owner New owner of the proxy contract.\n */\n function setOwner(address _owner) external proxyCallIfNotOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Queries the owner of the proxy contract. Can only be called by the owner OR by\n * making an eth_call and setting the \"from\" address to address(0).\n *\n * @return Owner address.\n */\n function getOwner() external proxyCallIfNotOwner returns (address) {\n return _getOwner();\n }\n\n /**\n * @notice Queries the implementation address. Can only be called by the owner OR by making an\n * eth_call and setting the \"from\" address to address(0).\n *\n * @return Implementation address.\n */\n function getImplementation() external proxyCallIfNotOwner returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _owner New owner of the proxy contract.\n */\n function _setOwner(address _owner) internal {\n assembly {\n sstore(OWNER_KEY, _owner)\n }\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal onlyWhenNotPaused {\n address implementation = _getImplementation();\n\n require(implementation != address(0), \"L1ChugSplashProxy: implementation is not set yet\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address implementation;\n assembly {\n implementation := sload(IMPLEMENTATION_KEY)\n }\n return implementation;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getOwner() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n\n /**\n * @notice Gets the code hash for a given account.\n *\n * @param _account Address of the account to get a code hash for.\n *\n * @return Code hash for the account.\n */\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\n bytes32 codeHash;\n assembly {\n codeHash := extcodehash(_account)\n }\n return codeHash;\n }\n}\n" - }, - "contracts/legacy/LegacyERC20ETH.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000\n * @title LegacyERC20ETH\n * @notice LegacyERC20ETH is a legacy contract that held ETH balances before the Bedrock upgrade.\n * All ETH balances held within this contract were migrated to the state trie as part of\n * the Bedrock upgrade. Functions within this contract that mutate state were already\n * disabled as part of the EVM equivalence upgrade.\n */\ncontract LegacyERC20ETH is OptimismMintableERC20 {\n /**\n * @notice Initializes the contract as an Optimism Mintable ERC20.\n */\n constructor()\n OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), \"Ether\", \"ETH\")\n {}\n\n /**\n * @notice Returns the ETH balance of the target account. Overrides the base behavior of the\n * contract to preserve the invariant that the balance within this contract always\n * matches the balance in the state trie.\n *\n * @param _who Address of the account to query.\n *\n * @return The ETH balance of the target account.\n */\n function balanceOf(address _who) public view virtual override returns (uint256) {\n return address(_who).balance;\n }\n\n /**\n * @custom:blocked\n * @notice Mints some amount of ETH.\n */\n function mint(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: mint is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Burns some amount of ETH.\n */\n function burn(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: burn is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers some amount of ETH.\n */\n function transfer(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transfer is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Approves a spender to spend some amount of ETH.\n */\n function approve(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: approve is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers funds from some sender account.\n */\n function transferFrom(\n address,\n address,\n uint256\n ) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transferFrom is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Increases the allowance of a spender.\n */\n function increaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Decreases the allowance of a spender.\n */\n function decreaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n }\n}\n" - }, - "contracts/legacy/LegacyMessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000000\n * @title LegacyMessagePasser\n * @notice The LegacyMessagePasser was the low-level mechanism used to send messages from L2 to L1\n * before the Bedrock upgrade. It is now deprecated in favor of the new MessagePasser.\n */\ncontract LegacyMessagePasser is Semver {\n /**\n * @notice Mapping of sent message hashes to boolean status.\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Passes a message to L1.\n *\n * @param _message Message to pass to L1.\n */\n function passMessageToL1(bytes memory _message) external {\n sentMessages[keccak256(abi.encodePacked(_message, msg.sender))] = true;\n }\n}\n" - }, - "contracts/legacy/LegacyMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ILegacyMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @title LegacyMintableERC20\n * @notice The legacy implementation of the OptimismMintableERC20. This\n * contract is deprecated and should no longer be used.\n */\ncontract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {\n /**\n * @notice Emitted when the token is minted by the bridge.\n */\n event Mint(address indexed _account, uint256 _amount);\n\n /**\n * @notice Emitted when a token is burned by the bridge.\n */\n event Burn(address indexed _account, uint256 _amount);\n\n /**\n * @notice The token on the remote domain.\n */\n address public l1Token;\n\n /**\n * @notice The local bridge.\n */\n address public l2Bridge;\n\n /**\n * @param _l2Bridge Address of the L2 standard bridge.\n * @param _l1Token Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _l2Bridge,\n address _l1Token,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) {\n l1Token = _l1Token;\n l2Bridge = _l2Bridge;\n }\n\n /**\n * @notice Modifier that requires the contract was called by the bridge.\n */\n modifier onlyL2Bridge() {\n require(msg.sender == l2Bridge, \"Only L2 Bridge can mint and burn\");\n _;\n }\n\n /**\n * @notice EIP165 implementation.\n */\n function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n\n /**\n * @notice Only the bridge can mint tokens.\n * @param _to The account receiving tokens.\n * @param _amount The amount of tokens to receive.\n */\n function mint(address _to, uint256 _amount) public virtual onlyL2Bridge {\n _mint(_to, _amount);\n\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Only the bridge can burn tokens.\n * @param _from The account having tokens burnt.\n * @param _amount The amount of tokens being burnt.\n */\n function burn(address _from, uint256 _amount) public virtual onlyL2Bridge {\n _burn(_from, _amount);\n\n emit Burn(_from, _amount);\n }\n}\n" - }, - "contracts/legacy/ResolvedDelegateProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressManager } from \"./AddressManager.sol\";\n\n/**\n * @custom:legacy\n * @title ResolvedDelegateProxy\n * @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to\n * resolve the implementation address. We're maintaining this contract for backwards\n * compatibility so we can manage all legacy proxies where necessary.\n */\ncontract ResolvedDelegateProxy {\n /**\n * @notice Mapping used to store the implementation name that corresponds to this contract. A\n * mapping was originally used as a way to bypass the same issue normally solved by\n * storing the implementation address in a specific storage slot that does not conflict\n * with any other storage slot. Generally NOT a safe solution but works as long as the\n * implementation does not also keep a mapping in the first storage slot.\n */\n mapping(address => string) private implementationName;\n\n /**\n * @notice Mapping used to store the address of the AddressManager contract where the\n * implementation address will be resolved from. Same concept here as with the above\n * mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping\n * in the second storage slot.\n */\n mapping(address => AddressManager) private addressManager;\n\n /**\n * @param _addressManager Address of the AddressManager.\n * @param _implementationName implementationName of the contract to proxy to.\n */\n constructor(AddressManager _addressManager, string memory _implementationName) {\n addressManager[address(this)] = _addressManager;\n implementationName[address(this)] = _implementationName;\n }\n\n /**\n * @notice Fallback, performs a delegatecall to the resolved implementation address.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n address target = addressManager[address(this)].getAddress(\n (implementationName[address(this)])\n );\n\n require(target != address(0), \"ResolvedDelegateProxy: target address must be initialized\");\n\n // slither-disable-next-line controlled-delegatecall\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\n\n if (success == true) {\n assembly {\n return(add(returndata, 0x20), mload(returndata))\n }\n } else {\n assembly {\n revert(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n" - }, - "contracts/libraries/Arithmetic.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { SignedMath } from \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport { FixedPointMathLib } from \"@rari-capital/solmate/src/utils/FixedPointMathLib.sol\";\n\n/**\n * @title Arithmetic\n * @notice Even more math than before.\n */\nlibrary Arithmetic {\n /**\n * @notice Clamps a value between a minimum and maximum.\n *\n * @param _value The value to clamp.\n * @param _min The minimum value.\n * @param _max The maximum value.\n *\n * @return The clamped value.\n */\n function clamp(\n int256 _value,\n int256 _min,\n int256 _max\n ) internal pure returns (int256) {\n return SignedMath.min(SignedMath.max(_value, _min), _max);\n }\n\n /**\n * @notice (c)oefficient (d)enominator (exp)onentiation function.\n * Returns the result of: c * (1 - 1/d)^exp.\n *\n * @param _coefficient Coefficient of the function.\n * @param _denominator Fractional denominator.\n * @param _exponent Power function exponent.\n *\n * @return Result of c * (1 - 1/d)^exp.\n */\n function cdexp(\n int256 _coefficient,\n int256 _denominator,\n int256 _exponent\n ) internal pure returns (int256) {\n return\n (_coefficient *\n (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;\n }\n}\n" - }, - "contracts/libraries/Burn.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Burn\n * @notice Utilities for burning stuff.\n */\nlibrary Burn {\n /**\n * Burns a given amount of ETH.\n *\n * @param _amount Amount of ETH to burn.\n */\n function eth(uint256 _amount) internal {\n new Burner{ value: _amount }();\n }\n\n /**\n * Burns a given amount of gas.\n *\n * @param _amount Amount of gas to burn.\n */\n function gas(uint256 _amount) internal view {\n uint256 i = 0;\n uint256 initialGas = gasleft();\n while (initialGas - gasleft() < _amount) {\n ++i;\n }\n }\n}\n\n/**\n * @title Burner\n * @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to\n * the contract from the circulating supply. Self-destructing is the only way to remove ETH\n * from the circulating supply.\n */\ncontract Burner {\n constructor() payable {\n selfdestruct(payable(address(this)));\n }\n}\n" - }, - "contracts/libraries/Bytes.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Bytes\n * @notice Bytes is a library for manipulating byte arrays.\n */\nlibrary Bytes {\n /**\n * @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\n * @notice Slices a byte array with a given starting index and length. Returns a new byte array\n * as opposed to a pointer to the original array. Will throw if trying to slice more\n * bytes than exist in the array.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n * @param _length Length of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n ) internal pure returns (bytes memory) {\n unchecked {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_start + _length >= _start, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n }\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n /**\n * @notice Slices a byte array with a given starting index up to the end of the original byte\n * array. Returns a new array rathern than a pointer to the original.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\n if (_start >= _bytes.length) {\n return bytes(\"\");\n }\n return slice(_bytes, _start, _bytes.length - _start);\n }\n\n /**\n * @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.\n * Resulting nibble array will be exactly twice as long as the input byte array.\n *\n * @param _bytes Input byte array to convert.\n *\n * @return Resulting nibble array.\n */\n function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n uint256 bytesLength = _bytes.length;\n bytes memory nibbles = new bytes(bytesLength * 2);\n bytes1 b;\n\n for (uint256 i = 0; i < bytesLength; ) {\n b = _bytes[i];\n nibbles[i * 2] = b >> 4;\n nibbles[i * 2 + 1] = b & 0x0f;\n unchecked {\n ++i;\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Compares two byte arrays by comparing their keccak256 hashes.\n *\n * @param _bytes First byte array to compare.\n * @param _other Second byte array to compare.\n *\n * @return True if the two byte arrays are equal, false otherwise.\n */\n function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n return keccak256(_bytes) == keccak256(_other);\n }\n}\n" - }, - "contracts/libraries/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n/**\n * @title Constants\n * @notice Constants is a library for storing constants. Simple! Don't put everything in here, just\n * the stuff used in multiple contracts. Constants that only apply to a single contract\n * should be defined in that contract instead.\n */\nlibrary Constants {\n /**\n * @notice Special address to be used as the tx origin for gas estimation calls in the\n * OptimismPortal and CrossDomainMessenger calls. You only need to use this address if\n * the minimum gas limit specified by the user is not actually enough to execute the\n * given message and you're attempting to estimate the actual necessary gas limit. We\n * use address(1) because it's the ecrecover precompile and therefore guaranteed to\n * never have any code on any EVM chain.\n */\n address internal constant ESTIMATION_ADDRESS = address(1);\n\n /**\n * @notice Value used for the L2 sender storage slot in both the OptimismPortal and the\n * CrossDomainMessenger contracts before an actual sender is set. This value is\n * non-zero to reduce the gas cost of message passing transactions.\n */\n address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;\n\n /**\n * @notice Returns the default values for the ResourceConfig. These are the recommended values\n * for a production network.\n */\n function DEFAULT_RESOURCE_CONFIG()\n internal\n pure\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n return config;\n }\n}\n" - }, - "contracts/libraries/Encoding.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Hashing } from \"./Hashing.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\n\n/**\n * @title Encoding\n * @notice Encoding handles Optimism's various different encoding schemes.\n */\nlibrary Encoding {\n /**\n * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\n * to the L2 system. Useful for searching for a deposit in the L2 system. The\n * transaction is prefixed with 0x7e to identify its EIP-2718 type.\n *\n * @param _tx User deposit transaction to encode.\n *\n * @return RLP encoded L2 deposit transaction.\n */\n function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes memory)\n {\n bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\n bytes[] memory raw = new bytes[](8);\n raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\n raw[1] = RLPWriter.writeAddress(_tx.from);\n raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\"\") : RLPWriter.writeAddress(_tx.to);\n raw[3] = RLPWriter.writeUint(_tx.mint);\n raw[4] = RLPWriter.writeUint(_tx.value);\n raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\n raw[6] = RLPWriter.writeBool(false);\n raw[7] = RLPWriter.writeBytes(_tx.data);\n return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\n }\n\n /**\n * @notice Encodes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n (, uint16 version) = decodeVersionedNonce(_nonce);\n if (version == 0) {\n return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Encoding: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Encodes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _data,\n _nonce\n );\n }\n\n /**\n * @notice Encodes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(uint256,address,address,uint256,uint256,bytes)\",\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n }\n\n /**\n * @notice Adds a version number into the first two bytes of a message nonce.\n *\n * @param _nonce Message nonce to encode into.\n * @param _version Version number to encode into the message nonce.\n *\n * @return Message nonce with version encoded into the first two bytes.\n */\n function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\n uint256 nonce;\n assembly {\n nonce := or(shl(240, _version), _nonce)\n }\n return nonce;\n }\n\n /**\n * @notice Pulls the version out of a version-encoded nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n *\n * @return Nonce without encoded version.\n * @return Version of the message.\n */\n function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\n uint240 nonce;\n uint16 version;\n assembly {\n nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n version := shr(240, _nonce)\n }\n return (nonce, version);\n }\n}\n" - }, - "contracts/libraries/Hashing.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Encoding } from \"./Encoding.sol\";\n\n/**\n * @title Hashing\n * @notice Hashing handles Optimism's various different hashing schemes.\n */\nlibrary Hashing {\n /**\n * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\n * given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\n * system.\n *\n * @param _tx User deposit transaction to hash.\n *\n * @return Hash of the RLP encoded L2 deposit transaction.\n */\n function hashDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return keccak256(Encoding.encodeDepositTransaction(_tx));\n }\n\n /**\n * @notice Computes the deposit transaction's \"source hash\", a value that guarantees the hash\n * of the L2 transaction that corresponds to a deposit is unique and is\n * deterministically generated from L1 transaction data.\n *\n * @param _l1BlockHash Hash of the L1 block where the deposit was included.\n * @param _logIndex The index of the log that created the deposit transaction.\n *\n * @return Hash of the deposit transaction's \"source hash\".\n */\n function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)\n internal\n pure\n returns (bytes32)\n {\n bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\n return keccak256(abi.encode(bytes32(0), depositId));\n }\n\n /**\n * @notice Hashes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n if (version == 0) {\n return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Hashing: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Hashes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes32) {\n return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));\n }\n\n /**\n * @notice Hashes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n return\n keccak256(\n Encoding.encodeCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n )\n );\n }\n\n /**\n * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\n *\n * @param _tx Withdrawal transaction to hash.\n *\n * @return Hashed withdrawal transaction.\n */\n function hashWithdrawal(Types.WithdrawalTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\n );\n }\n\n /**\n * @notice Hashes the various elements of an output root proof into an output root hash which\n * can be used to check if the proof is valid.\n *\n * @param _outputRootProof Output root proof which should hash to an output root.\n *\n * @return Hashed output root proof.\n */\n function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(\n _outputRootProof.version,\n _outputRootProof.stateRoot,\n _outputRootProof.messagePasserStorageRoot,\n _outputRootProof.latestBlockhash\n )\n );\n }\n}\n" - }, - "contracts/libraries/LegacyCrossDomainUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n// Importing from the legacy contracts package causes issues with the build of the contract bindings\n// so we just copy the library here from\n// /packages/contracts/contracts/libraries/bridge/Lib_CrossDomainUtils.sol at commit\n// 7866168c\n/**\n * @title LegacyCrossDomainUtils\n */\nlibrary LegacyCrossDomainUtils {\n /**\n * Generates the correct cross domain calldata for a message.\n * @param _target Target contract address.\n * @param _sender Message sender address.\n * @param _message Message to send to the target.\n * @param _messageNonce Nonce for the provided message.\n * @return ABI encoded cross domain calldata.\n */\n function encodeXDomainCalldata(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _message,\n _messageNonce\n );\n }\n}\n" - }, - "contracts/libraries/Predeploys.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Predeploys\n * @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.\n */\nlibrary Predeploys {\n /**\n * @notice Address of the L2ToL1MessagePasser predeploy.\n */\n address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;\n\n /**\n * @notice Address of the L2CrossDomainMessenger predeploy.\n */\n address internal constant L2_CROSS_DOMAIN_MESSENGER =\n 0x4200000000000000000000000000000000000007;\n\n /**\n * @notice Address of the L2StandardBridge predeploy.\n */\n address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\n\n /**\n * @notice Address of the L2ERC721Bridge predeploy.\n */\n address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;\n\n /**\n * @notice Address of the SequencerFeeWallet predeploy.\n */\n address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;\n\n /**\n * @notice Address of the OptimismMintableERC20Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY =\n 0x4200000000000000000000000000000000000012;\n\n /**\n * @notice Address of the OptimismMintableERC721Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY =\n 0x4200000000000000000000000000000000000017;\n\n /**\n * @notice Address of the L1Block predeploy.\n */\n address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;\n\n /**\n * @notice Address of the GasPriceOracle predeploy. Includes fee information\n * and helpers for computing the L1 portion of the transaction fee.\n */\n address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;\n\n /**\n * @custom:legacy\n * @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger\n * or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.\n */\n address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\n\n /**\n * @custom:legacy\n * @notice Address of the DeployerWhitelist predeploy. No longer active.\n */\n address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the\n * state trie as of the Bedrock upgrade. Contract has been locked and write functions\n * can no longer be accessed.\n */\n address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;\n\n /**\n * @custom:legacy\n * @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy\n * instead, which exposes more information about the L1 state.\n */\n address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated\n * L2ToL1MessagePasser contract instead.\n */\n address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\n\n /**\n * @notice Address of the ProxyAdmin predeploy.\n */\n address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;\n\n /**\n * @notice Address of the BaseFeeVault predeploy.\n */\n address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;\n\n /**\n * @notice Address of the L1FeeVault predeploy.\n */\n address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;\n\n /**\n * @notice Address of the GovernanceToken predeploy.\n */\n address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042;\n}\n" - }, - "contracts/libraries/SafeCall.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title SafeCall\n * @notice Perform low level safe calls\n */\nlibrary SafeCall {\n /**\n * @notice Perform a low level call without copying any returndata\n *\n * @param _target Address to call\n * @param _gas Amount of gas to pass to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function call(\n address _target,\n uint256 _gas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n }\n return _success;\n }\n\n /**\n * @notice Helper function to determine if there is sufficient gas remaining within the context\n * to guarantee that the minimum gas requirement for a call will be met as well as\n * optionally reserving a specified amount of gas for after the call has concluded.\n * @param _minGas The minimum amount of gas that may be passed to the target context.\n * @param _reservedGas Optional amount of gas to reserve for the caller after the execution\n * of the target context.\n * @return `true` if there is enough gas remaining to safely supply `_minGas` to the target\n * context as well as reserve `_reservedGas` for the caller after the execution of\n * the target context.\n * @dev !!!!! FOOTGUN ALERT !!!!!\n * 1.) The 40_000 base buffer is to account for the worst case of the dynamic cost of the\n * `CALL` opcode's `address_access_cost`, `positive_value_cost`, and\n * `value_to_empty_account_cost` factors with an added buffer of 5,700 gas. It is\n * still possible to self-rekt by initiating a withdrawal with a minimum gas limit\n * that does not account for the `memory_expansion_cost` & `code_execution_cost`\n * factors of the dynamic cost of the `CALL` opcode.\n * 2.) This function should *directly* precede the external call if possible. There is an\n * added buffer to account for gas consumed between this check and the call, but it\n * is only 5,700 gas.\n * 3.) Because EIP-150 ensures that a maximum of 63/64ths of the remaining gas in the call\n * frame may be passed to a subcontext, we need to ensure that the gas will not be\n * truncated.\n * 4.) Use wisely. This function is not a silver bullet.\n */\n function hasMinGas(uint256 _minGas, uint256 _reservedGas) internal view returns (bool) {\n bool _hasMinGas;\n assembly {\n // Equation: gas × 63 ≥ minGas × 64 + 63(40_000 + reservedGas)\n _hasMinGas := iszero(\n lt(mul(gas(), 63), add(mul(_minGas, 64), mul(add(40000, _reservedGas), 63)))\n )\n }\n return _hasMinGas;\n }\n\n /**\n * @notice Perform a low level call without copying any returndata. This function\n * will revert if the call cannot be performed with the specified minimum\n * gas.\n *\n * @param _target Address to call\n * @param _minGas The minimum amount of gas that may be passed to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function callWithMinGas(\n address _target,\n uint256 _minGas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n bool _hasMinGas = hasMinGas(_minGas, 0);\n assembly {\n // Assertion: gasleft() >= (_minGas * 64) / 63 + 40_000\n if iszero(_hasMinGas) {\n // Store the \"Error(string)\" selector in scratch space.\n mstore(0, 0x08c379a0)\n // Store the pointer to the string length in scratch space.\n mstore(32, 32)\n // Store the string.\n //\n // SAFETY:\n // - We pad the beginning of the string with two zero bytes as well as the\n // length (24) to ensure that we override the free memory pointer at offset\n // 0x40. This is necessary because the free memory pointer is likely to\n // be greater than 1 byte when this function is called, but it is incredibly\n // unlikely that it will be greater than 3 bytes. As for the data within\n // 0x60, it is ensured that it is 0 due to 0x60 being the zero offset.\n // - It's fine to clobber the free memory pointer, we're reverting.\n mstore(88, 0x0000185361666543616c6c3a204e6f7420656e6f75676820676173)\n\n // Revert with 'Error(\"SafeCall: Not enough gas\")'\n revert(28, 100)\n }\n\n // The call will be supplied at least ((_minGas * 64) / 63) gas due to the\n // above assertion. This ensures that, in all circumstances (except for when the\n // `_minGas` does not account for the `memory_expansion_cost` and `code_execution_cost`\n // factors of the dynamic cost of the `CALL` opcode), the call will receive at least\n // the minimum amount of gas specified.\n _success := call(\n gas(), // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0x00, // outloc\n 0x00 // outlen\n )\n }\n return _success;\n }\n}\n" - }, - "contracts/libraries/Types.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Types\n * @notice Contains various types used throughout the Optimism contract system.\n */\nlibrary Types {\n /**\n * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\n * timestamp that the output root is posted. This timestamp is used to verify that the\n * finalization period has passed since the output root was submitted.\n *\n * @custom:field outputRoot Hash of the L2 output.\n * @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.\n * @custom:field l2BlockNumber L2 block number that the output corresponds to.\n */\n struct OutputProposal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2BlockNumber;\n }\n\n /**\n * @notice Struct representing the elements that are hashed together to generate an output root\n * which itself represents a snapshot of the L2 state.\n *\n * @custom:field version Version of the output root.\n * @custom:field stateRoot Root of the state trie at the block of this output.\n * @custom:field messagePasserStorageRoot Root of the message passer storage trie.\n * @custom:field latestBlockhash Hash of the block this output was generated from.\n */\n struct OutputRootProof {\n bytes32 version;\n bytes32 stateRoot;\n bytes32 messagePasserStorageRoot;\n bytes32 latestBlockhash;\n }\n\n /**\n * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n * user (as opposed to a system deposit transaction generated by the system).\n *\n * @custom:field from Address of the sender of the transaction.\n * @custom:field to Address of the recipient of the transaction.\n * @custom:field isCreation True if the transaction is a contract creation.\n * @custom:field value Value to send to the recipient.\n * @custom:field mint Amount of ETH to mint.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n * @custom:field l1BlockHash Hash of the block the transaction was submitted in.\n * @custom:field logIndex Index of the log in the block the transaction was submitted in.\n */\n struct UserDepositTransaction {\n address from;\n address to;\n bool isCreation;\n uint256 value;\n uint256 mint;\n uint64 gasLimit;\n bytes data;\n bytes32 l1BlockHash;\n uint256 logIndex;\n }\n\n /**\n * @notice Struct representing a withdrawal transaction.\n *\n * @custom:field nonce Nonce of the withdrawal transaction\n * @custom:field sender Address of the sender of the transaction.\n * @custom:field target Address of the recipient of the transaction.\n * @custom:field value Value to send to the recipient.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n */\n struct WithdrawalTransaction {\n uint256 nonce;\n address sender;\n address target;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPReader.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\n/**\n * @custom:attribution https://github.com/hamdiallam/Solidity-RLP\n * @title RLPReader\n * @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted\n * from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with\n * various tweaks to improve readability.\n */\nlibrary RLPReader {\n /**\n * Custom pointer type to avoid confusion between pointers and uint256s.\n */\n type MemoryPointer is uint256;\n\n /**\n * @notice RLP item types.\n *\n * @custom:value DATA_ITEM Represents an RLP data item (NOT a list).\n * @custom:value LIST_ITEM Represents an RLP list item.\n */\n enum RLPItemType {\n DATA_ITEM,\n LIST_ITEM\n }\n\n /**\n * @notice Struct representing an RLP item.\n *\n * @custom:field length Length of the RLP item.\n * @custom:field ptr Pointer to the RLP item in memory.\n */\n struct RLPItem {\n uint256 length;\n MemoryPointer ptr;\n }\n\n /**\n * @notice Max list length that this library will accept.\n */\n uint256 internal constant MAX_LIST_LENGTH = 32;\n\n /**\n * @notice Converts bytes to a reference to memory position and length.\n *\n * @param _in Input bytes to convert.\n *\n * @return Output memory reference.\n */\n function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n // Empty arrays are not RLP items.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr;\n assembly {\n ptr := add(_in, 32)\n }\n\n return RLPItem({ length: _in.length, ptr: ptr });\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.LIST_ITEM,\n \"RLPReader: decoded item type for list is not a list item\"\n );\n\n require(\n listOffset + listLength == _in.length,\n \"RLPReader: list item has an invalid data remainder\"\n );\n\n // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n // writing to the length. Since we can't know the number of RLP items without looping over\n // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n // simply set a reasonable maximum list length and decrease the size before we finish.\n RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n uint256 itemCount = 0;\n uint256 offset = listOffset;\n while (offset < _in.length) {\n (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n RLPItem({\n length: _in.length - offset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n })\n );\n\n // We don't need to check itemCount < out.length explicitly because Solidity already\n // handles this check on our behalf, we'd just be wasting gas.\n out[itemCount] = RLPItem({\n length: itemLength + itemOffset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n });\n\n itemCount += 1;\n offset += itemOffset + itemLength;\n }\n\n // Decrease the array size to match the actual item count.\n assembly {\n mstore(out, itemCount)\n }\n\n return out;\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n return readList(toRLPItem(_in));\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.DATA_ITEM,\n \"RLPReader: decoded item type for bytes is not a data item\"\n );\n\n require(\n _in.length == itemOffset + itemLength,\n \"RLPReader: bytes value contains an invalid remainder\"\n );\n\n return _copy(_in.ptr, itemOffset, itemLength);\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n return readBytes(toRLPItem(_in));\n }\n\n /**\n * @notice Reads the raw bytes of an RLP item.\n *\n * @param _in RLP item to read.\n *\n * @return Raw RLP bytes.\n */\n function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n return _copy(_in.ptr, 0, _in.length);\n }\n\n /**\n * @notice Decodes the length of an RLP item.\n *\n * @param _in RLP item to decode.\n *\n * @return Offset of the encoded data.\n * @return Length of the encoded data.\n * @return RLP item type (LIST_ITEM or DATA_ITEM).\n */\n function _decodeLength(RLPItem memory _in)\n private\n pure\n returns (\n uint256,\n uint256,\n RLPItemType\n )\n {\n // Short-circuit if there's nothing to decode, note that we perform this check when\n // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass\n // that function and create an RLP item directly. So we need to check this anyway.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr = _in.ptr;\n uint256 prefix;\n assembly {\n prefix := byte(0, mload(ptr))\n }\n\n if (prefix <= 0x7f) {\n // Single byte.\n return (0, 1, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xb7) {\n // Short string.\n\n // slither-disable-next-line variable-scope\n uint256 strLen = prefix - 0x80;\n\n require(\n _in.length > strLen,\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n strLen != 1 || firstByteOfContent >= 0x80,\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n\n return (1, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xbf) {\n // Long string.\n uint256 lenOfStrLen = prefix - 0xb7;\n\n require(\n _in.length > lenOfStrLen,\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n\n uint256 strLen;\n assembly {\n strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))\n }\n\n require(\n strLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long string)\"\n );\n\n require(\n _in.length > lenOfStrLen + strLen,\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n\n return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xf7) {\n // Short list.\n // slither-disable-next-line variable-scope\n uint256 listLen = prefix - 0xc0;\n\n require(\n _in.length > listLen,\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n\n return (1, listLen, RLPItemType.LIST_ITEM);\n } else {\n // Long list.\n uint256 lenOfListLen = prefix - 0xf7;\n\n require(\n _in.length > lenOfListLen,\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long list)\"\n );\n\n uint256 listLen;\n assembly {\n listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))\n }\n\n require(\n listLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long list)\"\n );\n\n require(\n _in.length > lenOfListLen + listLen,\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n\n return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n }\n }\n\n /**\n * @notice Copies the bytes from a memory location.\n *\n * @param _src Pointer to the location to read from.\n * @param _offset Offset to start reading from.\n * @param _length Number of bytes to read.\n *\n * @return Copied bytes.\n */\n function _copy(\n MemoryPointer _src,\n uint256 _offset,\n uint256 _length\n ) private pure returns (bytes memory) {\n bytes memory out = new bytes(_length);\n if (_length == 0) {\n return out;\n }\n\n // Mostly based on Solidity's copy_memory_to_memory:\n // solhint-disable max-line-length\n // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114\n uint256 src = MemoryPointer.unwrap(_src) + _offset;\n assembly {\n let dest := add(out, 32)\n let i := 0\n for {\n\n } lt(i, _length) {\n i := add(i, 32)\n } {\n mstore(add(dest, i), mload(add(src, i)))\n }\n\n if gt(i, _length) {\n mstore(add(dest, _length), 0)\n }\n }\n\n return out;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPWriter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\n * @title RLPWriter\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\n * RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\n * modifications to improve legibility.\n */\nlibrary RLPWriter {\n /**\n * @notice RLP encodes a byte string.\n *\n * @param _in The byte string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_in.length == 1 && uint8(_in[0]) < 128) {\n encoded = _in;\n } else {\n encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n }\n\n return encoded;\n }\n\n /**\n * @notice RLP encodes a list of RLP encoded byte byte strings.\n *\n * @param _in The list of RLP encoded byte strings.\n *\n * @return The RLP encoded list of items in bytes.\n */\n function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n bytes memory list = _flatten(_in);\n return abi.encodePacked(_writeLength(list.length, 192), list);\n }\n\n /**\n * @notice RLP encodes a string.\n *\n * @param _in The string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeString(string memory _in) internal pure returns (bytes memory) {\n return writeBytes(bytes(_in));\n }\n\n /**\n * @notice RLP encodes an address.\n *\n * @param _in The address to encode.\n *\n * @return The RLP encoded address in bytes.\n */\n function writeAddress(address _in) internal pure returns (bytes memory) {\n return writeBytes(abi.encodePacked(_in));\n }\n\n /**\n * @notice RLP encodes a uint.\n *\n * @param _in The uint256 to encode.\n *\n * @return The RLP encoded uint256 in bytes.\n */\n function writeUint(uint256 _in) internal pure returns (bytes memory) {\n return writeBytes(_toBinary(_in));\n }\n\n /**\n * @notice RLP encodes a bool.\n *\n * @param _in The bool to encode.\n *\n * @return The RLP encoded bool in bytes.\n */\n function writeBool(bool _in) internal pure returns (bytes memory) {\n bytes memory encoded = new bytes(1);\n encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n return encoded;\n }\n\n /**\n * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\n *\n * @param _len The length of the string or the payload.\n * @param _offset 128 if item is string, 192 if item is list.\n *\n * @return RLP encoded bytes.\n */\n function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_len < 56) {\n encoded = new bytes(1);\n encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n } else {\n uint256 lenLen;\n uint256 i = 1;\n while (_len / i != 0) {\n lenLen++;\n i *= 256;\n }\n\n encoded = new bytes(lenLen + 1);\n encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n for (i = 1; i <= lenLen; i++) {\n encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n }\n }\n\n return encoded;\n }\n\n /**\n * @notice Encode integer in big endian binary form with no leading zeroes.\n *\n * @param _x The integer to encode.\n *\n * @return RLP encoded bytes.\n */\n function _toBinary(uint256 _x) private pure returns (bytes memory) {\n bytes memory b = abi.encodePacked(_x);\n\n uint256 i = 0;\n for (; i < 32; i++) {\n if (b[i] != 0) {\n break;\n }\n }\n\n bytes memory res = new bytes(32 - i);\n for (uint256 j = 0; j < res.length; j++) {\n res[j] = b[i++];\n }\n\n return res;\n }\n\n /**\n * @custom:attribution https://github.com/Arachnid/solidity-stringutils\n * @notice Copies a piece of memory to another location.\n *\n * @param _dest Destination location.\n * @param _src Source location.\n * @param _len Length of memory to copy.\n */\n function _memcpy(\n uint256 _dest,\n uint256 _src,\n uint256 _len\n ) private pure {\n uint256 dest = _dest;\n uint256 src = _src;\n uint256 len = _len;\n\n for (; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n uint256 mask;\n unchecked {\n mask = 256**(32 - len) - 1;\n }\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /**\n * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\n * @notice Flattens a list of byte strings into one byte string.\n *\n * @param _list List of byte strings to flatten.\n *\n * @return The flattened byte string.\n */\n function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n if (_list.length == 0) {\n return new bytes(0);\n }\n\n uint256 len;\n uint256 i = 0;\n for (; i < _list.length; i++) {\n len += _list[i].length;\n }\n\n bytes memory flattened = new bytes(len);\n uint256 flattenedPtr;\n assembly {\n flattenedPtr := add(flattened, 0x20)\n }\n\n for (i = 0; i < _list.length; i++) {\n bytes memory item = _list[i];\n\n uint256 listPtr;\n assembly {\n listPtr := add(item, 0x20)\n }\n\n _memcpy(flattenedPtr, listPtr, item.length);\n flattenedPtr += _list[i].length;\n }\n\n return flattened;\n }\n}\n" - }, - "contracts/libraries/trie/MerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Bytes } from \"../Bytes.sol\";\nimport { RLPReader } from \"../rlp/RLPReader.sol\";\n\n/**\n * @title MerkleTrie\n * @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie\n * inclusion proofs. By default, this library assumes a hexary trie. One can change the\n * trie radix constant to support other trie radixes.\n */\nlibrary MerkleTrie {\n /**\n * @notice Struct representing a node in the trie.\n *\n * @custom:field encoded The RLP-encoded node.\n * @custom:field decoded The RLP-decoded node.\n */\n struct TrieNode {\n bytes encoded;\n RLPReader.RLPItem[] decoded;\n }\n\n /**\n * @notice Determines the number of elements per branch node.\n */\n uint256 internal constant TREE_RADIX = 16;\n\n /**\n * @notice Branch nodes have TREE_RADIX elements and one value element.\n */\n uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\n\n /**\n * @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.\n */\n uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\n\n /**\n * @notice Prefix for even-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_EVEN = 0;\n\n /**\n * @notice Prefix for odd-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_ODD = 1;\n\n /**\n * @notice Prefix for even-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_EVEN = 2;\n\n /**\n * @notice Prefix for odd-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_ODD = 3;\n\n /**\n * @notice Verifies a proof that a given key/value pair is present in the trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n return Bytes.equal(_value, get(_key, _proof, _root));\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n require(_key.length > 0, \"MerkleTrie: empty key\");\n\n TrieNode[] memory proof = _parseProof(_proof);\n bytes memory key = Bytes.toNibbles(_key);\n bytes memory currentNodeID = abi.encodePacked(_root);\n uint256 currentKeyIndex = 0;\n\n // Proof is top-down, so we start at the first element (root).\n for (uint256 i = 0; i < proof.length; i++) {\n TrieNode memory currentNode = proof[i];\n\n // Key index should never exceed total key length or we'll be out of bounds.\n require(\n currentKeyIndex <= key.length,\n \"MerkleTrie: key index exceeds total key length\"\n );\n\n if (currentKeyIndex == 0) {\n // First proof element is always the root node.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid root hash\"\n );\n } else if (currentNode.encoded.length >= 32) {\n // Nodes 32 bytes or larger are hashed inside branch nodes.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid large internal hash\"\n );\n } else {\n // Nodes smaller than 32 bytes aren't hashed.\n require(\n Bytes.equal(currentNode.encoded, currentNodeID),\n \"MerkleTrie: invalid internal node hash\"\n );\n }\n\n if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\n if (currentKeyIndex == key.length) {\n // Value is the last element of the decoded list (for branch nodes). There's\n // some ambiguity in the Merkle trie specification because bytes(0) is a\n // valid value to place into the trie, but for branch nodes bytes(0) can exist\n // even when the value wasn't explicitly placed there. Geth treats a value of\n // bytes(0) as \"key does not exist\" and so we do the same.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (branch)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (branch)\"\n );\n\n return value;\n } else {\n // We're not at the end of the key yet.\n // Figure out what the next node ID should be and continue.\n uint8 branchKey = uint8(key[currentKeyIndex]);\n RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\n currentNodeID = _getNodeID(nextNode);\n currentKeyIndex += 1;\n }\n } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\n bytes memory path = _getNodePath(currentNode);\n uint8 prefix = uint8(path[0]);\n uint8 offset = 2 - (prefix % 2);\n bytes memory pathRemainder = Bytes.slice(path, offset);\n bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);\n uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\n\n // Whether this is a leaf node or an extension node, the path remainder MUST be a\n // prefix of the key remainder (or be equal to the key remainder) or the proof is\n // considered invalid.\n require(\n pathRemainder.length == sharedNibbleLength,\n \"MerkleTrie: path remainder must share all nibbles with key\"\n );\n\n if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\n // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid,\n // the key remainder must be exactly equal to the path remainder. We already\n // did the necessary byte comparison, so it's more efficient here to check that\n // the key remainder length equals the shared nibble length, which implies\n // equality with the path remainder (since we already did the same check with\n // the path remainder and the shared nibble length).\n require(\n keyRemainder.length == sharedNibbleLength,\n \"MerkleTrie: key remainder must be identical to path remainder\"\n );\n\n // Our Merkle Trie is designed specifically for the purposes of the Ethereum\n // state trie. Empty values are not allowed in the state trie, so we can safely\n // say that if the value is empty, the key should not exist and the proof is\n // invalid.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[1]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (leaf)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (leaf)\"\n );\n\n return value;\n } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\n // Prefix of 0 or 1 means this is an extension node. We move onto the next node\n // in the proof and increment the key index by the length of the path remainder\n // which is equal to the shared nibble length.\n currentNodeID = _getNodeID(currentNode.decoded[1]);\n currentKeyIndex += sharedNibbleLength;\n } else {\n revert(\"MerkleTrie: received a node with an unknown prefix\");\n }\n } else {\n revert(\"MerkleTrie: received an unparseable node\");\n }\n }\n\n revert(\"MerkleTrie: ran out of proof elements\");\n }\n\n /**\n * @notice Parses an array of proof elements into a new array that contains both the original\n * encoded element and the RLP-decoded element.\n *\n * @param _proof Array of proof elements to parse.\n *\n * @return Proof parsed into easily accessible structs.\n */\n function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {\n uint256 length = _proof.length;\n TrieNode[] memory proof = new TrieNode[](length);\n for (uint256 i = 0; i < length; ) {\n proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });\n unchecked {\n ++i;\n }\n }\n return proof;\n }\n\n /**\n * @notice Picks out the ID for a node. Node ID is referred to as the \"hash\" within the\n * specification, but nodes < 32 bytes are not actually hashed.\n *\n * @param _node Node to pull an ID for.\n *\n * @return ID for the node, depending on the size of its contents.\n */\n function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {\n return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);\n }\n\n /**\n * @notice Gets the path for a leaf or extension node.\n *\n * @param _node Node to get a path for.\n *\n * @return Node path, converted to an array of nibbles.\n */\n function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {\n return Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0]));\n }\n\n /**\n * @notice Utility; determines the number of nibbles shared between two nibble arrays.\n *\n * @param _a First nibble array.\n * @param _b Second nibble array.\n *\n * @return Number of shared nibbles.\n */\n function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\n private\n pure\n returns (uint256)\n {\n uint256 shared;\n uint256 max = (_a.length < _b.length) ? _a.length : _b.length;\n for (; shared < max && _a[shared] == _b[shared]; ) {\n unchecked {\n ++shared;\n }\n }\n return shared;\n }\n}\n" - }, - "contracts/libraries/trie/SecureMerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/* Library Imports */\nimport { MerkleTrie } from \"./MerkleTrie.sol\";\n\n/**\n * @title SecureMerkleTrie\n * @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input\n * keys. Ethereum's state trie hashes input keys before storing them.\n */\nlibrary SecureMerkleTrie {\n /**\n * @notice Verifies a proof that a given key/value pair is present in the Merkle trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.get(key, _proof, _root);\n }\n\n /**\n * @notice Computes the hashed version of the input key.\n *\n * @param _key Key to hash.\n *\n * @return Hashed version of the key.\n */\n function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {\n return abi.encodePacked(keccak256(_key));\n }\n}\n" - }, - "contracts/periphery/TransferOnion.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title TransferOnion\n * @notice TransferOnion is a hash onion for distributing tokens. The shell commits\n * to an ordered list of the token transfers and can be permissionlessly\n * unwrapped in order. The SENDER must `approve` this contract as\n * `transferFrom` is used to move the token balances.\n */\ncontract TransferOnion is ReentrancyGuard {\n using SafeERC20 for ERC20;\n\n /**\n * @notice Struct representing a layer of the onion.\n */\n struct Layer {\n address recipient;\n uint256 amount;\n bytes32 shell;\n }\n\n /**\n * @notice Address of the token to distribute.\n */\n ERC20 public immutable TOKEN;\n\n /**\n * @notice Address of the account to distribute tokens from.\n */\n address public immutable SENDER;\n\n /**\n * @notice Current shell hash.\n */\n bytes32 public shell;\n\n /**\n * @param _token Address of the token to distribute.\n * @param _sender Address of the sender to distribute from.\n * @param _shell Initial shell of the onion.\n */\n constructor(\n ERC20 _token,\n address _sender,\n bytes32 _shell\n ) {\n TOKEN = _token;\n SENDER = _sender;\n shell = _shell;\n }\n\n /**\n * @notice Peels layers from the onion and distributes tokens.\n *\n * @param _layers Array of onion layers to peel.\n */\n function peel(Layer[] memory _layers) public nonReentrant {\n bytes32 tempShell = shell;\n uint256 length = _layers.length;\n for (uint256 i = 0; i < length; ) {\n Layer memory layer = _layers[i];\n\n // Confirm that the onion layer is correct.\n require(\n keccak256(abi.encode(layer.recipient, layer.amount, layer.shell)) == tempShell,\n \"TransferOnion: what are you doing in my swamp?\"\n );\n\n // Update the onion layer.\n tempShell = layer.shell;\n\n // Transfer the tokens.\n TOKEN.safeTransferFrom(SENDER, layer.recipient, layer.amount);\n\n // Unchecked increment to save some gas.\n unchecked {\n ++i;\n }\n }\n\n shell = tempShell;\n }\n}\n" - }, - "contracts/test/AddressAliasHelper.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract AddressAliasHelper_applyAndUndo_Test is Test {\n /**\n * @notice Tests that applying and then undoing an alias results in the original address.\n */\n function testFuzz_applyAndUndo_succeeds(address _address) external {\n address aliased = AddressAliasHelper.applyL1ToL2Alias(_address);\n address unaliased = AddressAliasHelper.undoL1ToL2Alias(aliased);\n assertEq(_address, unaliased);\n }\n}\n" - }, - "contracts/test/BenchmarkTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test } from \"forge-std/Test.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport \"./CommonTest.t.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n// Free function for setting the prevBaseFee param in the OptimismPortal.\nfunction setPrevBaseFee(\n Vm _vm,\n address _op,\n uint128 _prevBaseFee\n) {\n _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee));\n}\n\ncontract SetPrevBaseFee_Test is Portal_Initializer {\n function test_setPrevBaseFee_succeeds() external {\n setPrevBaseFee(vm, address(op), 100 gwei);\n (uint128 prevBaseFee, , uint64 prevBlockNum) = op.params();\n assertEq(uint256(prevBaseFee), 100 gwei);\n assertEq(uint256(prevBlockNum), block.number);\n }\n}\n\n// Tests for obtaining pure gas cost estimates for commonly used functions.\n// The objective with these benchmarks is to strip down the actual test functions\n// so that they are nothing more than the call we want measure the gas cost of.\n// In order to achieve this we make no assertions, and handle everything else in the setUp()\n// function.\ncontract GasBenchMark_OptimismPortal is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n bytes32 _outputRoot;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n\n // Get withdrawal proof data we can use for testing.\n bytes32 _storageRoot;\n bytes32 _stateRoot;\n (_stateRoot, _storageRoot, _outputRoot, , _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public virtual override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n function test_depositTransaction_benchmark() external {\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_depositTransaction_benchmark_1() external {\n setPrevBaseFee(vm, address(op), 1 gwei);\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_proveWithdrawalTransaction_benchmark() external {\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n}\n\ncontract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {\n function test_sendMessage_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n\n function test_sendMessage_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), alice, 100000, true);\n vm.startPrank(alice, alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n }\n\n function test_depositETH_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositETH_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositERC20_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n\n function test_depositERC20_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), address(L1Bridge), 100, true);\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.startPrank(address(L1Bridge.messenger()));\n vm.deal(address(L1Bridge.messenger()), 100);\n }\n\n function test_finalizeETHWithdrawal_benchmark() external {\n // TODO: Make this more accurate. It is underestimating the cost because it pranks\n // the call coming from the messenger, which bypasses the portal\n // and oracle.\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer {\n uint256 nextBlockNumber;\n\n function setUp() public override {\n super.setUp();\n nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.startPrank(proposer);\n }\n\n function test_proposeL2Output_benchmark() external {\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n}\n" - }, - "contracts/test/Bytes.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Bytes } from \"../libraries/Bytes.sol\";\n\ncontract Bytes_slice_Test is Test {\n /**\n * @notice Tests that the `slice` function works as expected when starting from index 0.\n */\n function test_slice_fromZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check if all possible slices starting from index 0 are correct.\n assertEq(Bytes.slice(input, 0, 0), hex\"\");\n assertEq(Bytes.slice(input, 0, 1), hex\"11\");\n assertEq(Bytes.slice(input, 0, 2), hex\"1122\");\n assertEq(Bytes.slice(input, 0, 3), hex\"112233\");\n assertEq(Bytes.slice(input, 0, 4), hex\"11223344\");\n assertEq(Bytes.slice(input, 0, 5), hex\"1122334455\");\n assertEq(Bytes.slice(input, 0, 6), hex\"112233445566\");\n assertEq(Bytes.slice(input, 0, 7), hex\"11223344556677\");\n assertEq(Bytes.slice(input, 0, 8), hex\"1122334455667788\");\n assertEq(Bytes.slice(input, 0, 9), hex\"112233445566778899\");\n assertEq(Bytes.slice(input, 0, 10), hex\"11223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when starting from indices [1, 9]\n * with lengths [1, 9], in reverse order.\n */\n function test_slice_fromNonZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check correctness of slices starting from indexes [1, 9]\n // and spanning [1, 9] bytes, in reverse order\n assertEq(Bytes.slice(input, 9, 1), hex\"00\");\n assertEq(Bytes.slice(input, 8, 2), hex\"9900\");\n assertEq(Bytes.slice(input, 7, 3), hex\"889900\");\n assertEq(Bytes.slice(input, 6, 4), hex\"77889900\");\n assertEq(Bytes.slice(input, 5, 5), hex\"6677889900\");\n assertEq(Bytes.slice(input, 4, 6), hex\"556677889900\");\n assertEq(Bytes.slice(input, 3, 7), hex\"44556677889900\");\n assertEq(Bytes.slice(input, 2, 8), hex\"3344556677889900\");\n assertEq(Bytes.slice(input, 1, 9), hex\"223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple words\n * in memory. In this case, we test that a 2 byte slice between the 32nd byte of the\n * first word and the 1st byte of the second word is correct.\n */\n function test_slice_acrossWords_works() public {\n bytes\n memory input = hex\"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000\";\n\n assertEq(Bytes.slice(input, 31, 2), hex\"1122\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple\n * words in memory. In this case, we test that a 34 byte slice between 3 separate words\n * returns the correct result.\n */\n function test_slice_acrossMultipleWords_works() public {\n bytes\n memory input = hex\"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000\";\n bytes\n memory expected = hex\"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11\";\n\n assertEq(Bytes.slice(input, 31, 34), expected);\n }\n\n /**\n * @notice Tests that, when given an input bytes array of length `n`, the `slice` function will\n * always revert if `_start + _length > n`.\n */\n function testFuzz_slice_outOfBounds_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // We want a valid start index and a length that will not overflow.\n vm.assume(_start < _input.length && _length < type(uint256).max - 31);\n // But, we want an invalid slice length.\n vm.assume(_start + _length > _input.length);\n\n vm.expectRevert(\"slice_outOfBounds\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,\n * the `slice` function reverts.\n */\n function testFuzz_slice_lengthOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that the `_length` will overflow if a number >= 31 is added to it.\n vm.assume(_length > type(uint256).max - 31);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a start index `n` that is greater than\n * `type(uint256).max - n`, the `slice` function reverts.\n */\n function testFuzz_slice_rangeOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that `_length` is a realistic length of a slice. This is to make sure\n // we revert on the correct require statement.\n vm.assume(_length < _input.length);\n // Ensure that `_start` will overflow if `_length` is added to it.\n vm.assume(_start > type(uint256).max - _length);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that the `slice` function correctly updates the free memory pointer depending\n * on the length of the slice.\n */\n function testFuzz_slice_memorySafety_succeeds(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // The start should never be more than the length of the input bytes array - 1\n vm.assume(_start < _input.length);\n // The length should never be more than the length of the input bytes array - the starting\n // slice index.\n vm.assume(_length <= _input.length - _start);\n\n // Grab the free memory pointer before the slice operation\n uint64 initPtr;\n assembly {\n initPtr := mload(0x40)\n }\n uint64 expectedPtr = uint64(initPtr + 0x20 + ((_length + 0x1f) & ~uint256(0x1f)));\n\n // Ensure that all memory outside of the expected range is safe.\n vm.expectSafeMemory(initPtr, expectedPtr);\n\n // Slice the input bytes array from `_start` to `_start + _length`\n bytes memory slice = Bytes.slice(_input, _start, _length);\n\n // Grab the free memory pointer after the slice operation\n uint64 finalPtr;\n assembly {\n finalPtr := mload(0x40)\n }\n\n // The free memory pointer should have been updated properly\n if (_length == 0) {\n // If the slice length is zero, only 32 bytes of memory should have been allocated.\n assertEq(finalPtr, initPtr + 0x20);\n } else {\n // If the slice length is greater than zero, the memory allocated should be the\n // length of the slice rounded up to the next 32 byte word + 32 bytes for the\n // length of the byte array.\n //\n // Note that we use a slightly less efficient, but equivalent method of rounding\n // up `_length` to the next multiple of 32 than is used in the `slice` function.\n // This is to diff test the method used in `slice`.\n uint64 _expectedPtr = uint64(initPtr + 0x20 + (((_length + 0x1F) >> 5) << 5));\n assertEq(finalPtr, _expectedPtr);\n\n // Sanity check for equivalence of the rounding methods.\n assertEq(_expectedPtr, expectedPtr);\n }\n\n // The slice length should be equal to `_length`\n assertEq(slice.length, _length);\n }\n}\n\ncontract Bytes_toNibbles_Test is Test {\n /**\n * @notice Diffs the test Solidity version of `toNibbles` against the Yul version.\n *\n * @param _bytes The `bytes` array to convert to nibbles.\n *\n * @return Yul version of `toNibbles` applied to `_bytes`.\n */\n function _toNibblesYul(bytes memory _bytes) internal pure returns (bytes memory) {\n // Allocate memory for the `nibbles` array.\n bytes memory nibbles = new bytes(_bytes.length << 1);\n\n assembly {\n // Load the length of the passed bytes array from memory\n let bytesLength := mload(_bytes)\n\n // Store the memory offset of the _bytes array's contents on the stack\n let bytesStart := add(_bytes, 0x20)\n\n // Store the memory offset of the nibbles array's contents on the stack\n let nibblesStart := add(nibbles, 0x20)\n\n // Loop through each byte in the input array\n for {\n let i := 0x00\n } lt(i, bytesLength) {\n i := add(i, 0x01)\n } {\n // Get the starting offset of the next 2 bytes in the nibbles array\n let offset := add(nibblesStart, shl(0x01, i))\n\n // Load the byte at the current index within the `_bytes` array\n let b := byte(0x00, mload(add(bytesStart, i)))\n\n // Pull out the first nibble and store it in the new array\n mstore8(offset, shr(0x04, b))\n // Pull out the second nibble and store it in the new array\n mstore8(add(offset, 0x01), and(b, 0x0F))\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Tests that, given an input of 5 bytes, the `toNibbles` function returns an array of\n * 10 nibbles corresponding to the input data.\n */\n function test_toNibbles_expectedResult5Bytes_works() public {\n bytes memory input = hex\"1234567890\";\n bytes memory expected = hex\"01020304050607080900\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 128 bytes, the `toNibbles` function returns an array\n * of 256 nibbles corresponding to the input data. This test exists to ensure that,\n * given a large input, the `toNibbles` function works as expected.\n */\n function test_toNibbles_expectedResult128Bytes_works() public {\n bytes\n memory input = hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f\";\n bytes\n memory expected = hex\"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 0 bytes, the `toNibbles` function returns a zero\n * length array.\n */\n function test_toNibbles_zeroLengthInput_works() public {\n bytes memory input = hex\"\";\n bytes memory expected = hex\"\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length, 0);\n assertEq(expected.length, 0);\n assertEq(actual.length, 0);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Test that the `toNibbles` function in the `Bytes` library is equivalent to the Yul\n * implementation.\n */\n function testDiff_toNibbles_succeeds(bytes memory _input) public {\n assertEq(Bytes.toNibbles(_input), _toNibblesYul(_input));\n }\n}\n\ncontract Bytes_equal_Test is Test {\n /**\n * @notice Manually checks equality of two dynamic `bytes` arrays in memory.\n *\n * @param _a The first `bytes` array to compare.\n * @param _b The second `bytes` array to compare.\n *\n * @return True if the two `bytes` arrays are equal in memory.\n */\n function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) {\n bool _eq;\n assembly {\n _eq := and(\n // Check if the contents of the two bytes arrays are equal in memory.\n eq(keccak256(add(0x20, _a), mload(_a)), keccak256(add(0x20, _b), mload(_b))),\n // Check if the length of the two bytes arrays are equal in memory.\n // This is redundant given the above check, but included for completeness.\n eq(mload(_a), mload(_b))\n )\n }\n return _eq;\n }\n\n /**\n * @notice Tests that the `equal` function in the `Bytes` library returns `false` if given two\n * non-equal byte arrays.\n */\n function testFuzz_equal_notEqual_works(bytes memory _a, bytes memory _b) public {\n vm.assume(!manualEq(_a, _b));\n assertFalse(Bytes.equal(_a, _b));\n }\n\n /**\n * @notice Test whether or not the `equal` function in the `Bytes` library is equivalent to\n * manually checking equality of the two dynamic `bytes` arrays in memory.\n */\n function testDiff_equal_works(bytes memory _a, bytes memory _b) public {\n assertEq(Bytes.equal(_a, _b), manualEq(_a, _b));\n }\n}\n" - }, - "contracts/test/CommonTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test, StdUtils } from \"forge-std/Test.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { IL1ChugSplashDeployer } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { LegacyMintableERC20 } from \"../legacy/LegacyMintableERC20.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract CommonTest is Test {\n address alice = address(128);\n address bob = address(256);\n address multisig = address(512);\n\n address immutable ZERO_ADDRESS = address(0);\n address immutable NON_ZERO_ADDRESS = address(1);\n uint256 immutable NON_ZERO_VALUE = 100;\n uint256 immutable ZERO_VALUE = 0;\n uint64 immutable NON_ZERO_GASLIMIT = 50000;\n bytes32 nonZeroHash = keccak256(abi.encode(\"NON_ZERO\"));\n bytes NON_ZERO_DATA = hex\"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000\";\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n FFIInterface ffi;\n\n function setUp() public virtual {\n // Give alice and bob some ETH\n vm.deal(alice, 1 << 16);\n vm.deal(bob, 1 << 16);\n vm.deal(multisig, 1 << 16);\n\n vm.label(alice, \"alice\");\n vm.label(bob, \"bob\");\n vm.label(multisig, \"multisig\");\n\n // Make sure we have a non-zero base fee\n vm.fee(1000000000);\n\n ffi = new FFIInterface();\n }\n\n function emitTransactionDeposited(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) internal {\n emit TransactionDeposited(\n _from,\n _to,\n 0,\n abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)\n );\n }\n}\n\ncontract L2OutputOracle_Initializer is CommonTest {\n // Test target\n L2OutputOracle oracle;\n L2OutputOracle oracleImpl;\n\n L2ToL1MessagePasser messagePasser =\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));\n\n // Constructor arguments\n address internal proposer = 0x000000000000000000000000000000000000AbBa;\n address internal owner = 0x000000000000000000000000000000000000ACDC;\n uint256 internal submissionInterval = 1800;\n uint256 internal l2BlockTime = 2;\n uint256 internal startingBlockNumber = 200;\n uint256 internal startingTimestamp = 1000;\n address guardian;\n\n // Test data\n uint256 initL1Time;\n\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n // Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output\n function warpToProposeTime(uint256 _nextBlockNumber) public {\n vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1);\n }\n\n function setUp() public virtual override {\n super.setUp();\n guardian = makeAddr(\"guardian\");\n\n // By default the first block has timestamp and number zero, which will cause underflows in the\n // tests, so we'll move forward to these block values.\n initL1Time = startingTimestamp + 1;\n vm.warp(initL1Time);\n vm.roll(startingBlockNumber);\n // Deploy the L2OutputOracle and transfer owernship to the proposer\n oracleImpl = new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: startingTimestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(oracleImpl),\n abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp))\n );\n oracle = L2OutputOracle(address(proxy));\n vm.label(address(oracle), \"L2OutputOracle\");\n\n // Set the L2ToL1MessagePasser at the correct address\n vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code);\n\n vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, \"L2ToL1MessagePasser\");\n }\n}\n\ncontract Portal_Initializer is L2OutputOracle_Initializer {\n // Test target\n OptimismPortal internal opImpl;\n OptimismPortal internal op;\n SystemConfig systemConfig;\n\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n\n systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: config\n });\n\n opImpl = new OptimismPortal({\n _l2Oracle: oracle,\n _guardian: guardian,\n _paused: true,\n _config: systemConfig\n });\n\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(opImpl),\n abi.encodeWithSelector(OptimismPortal.initialize.selector, false)\n );\n op = OptimismPortal(payable(address(proxy)));\n vm.label(address(op), \"OptimismPortal\");\n }\n}\n\ncontract Messenger_Initializer is Portal_Initializer {\n AddressManager internal addressManager;\n L1CrossDomainMessenger internal L1Messenger;\n L2CrossDomainMessenger internal L2Messenger =\n L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);\n\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event RelayedMessage(bytes32 indexed msgHash);\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 mint,\n uint256 value,\n uint64 gasLimit,\n bool isCreation,\n bytes data\n );\n\n event WhatHappened(bool success, bytes returndata);\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the address manager\n vm.prank(multisig);\n addressManager = new AddressManager();\n\n // Setup implementation\n L1CrossDomainMessenger L1MessengerImpl = new L1CrossDomainMessenger(op);\n\n // Setup the address manager and proxy\n vm.prank(multisig);\n addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(L1MessengerImpl));\n ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(\n addressManager,\n \"OVM_L1CrossDomainMessenger\"\n );\n L1Messenger = L1CrossDomainMessenger(address(proxy));\n L1Messenger.initialize();\n\n vm.etch(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n address(new L2CrossDomainMessenger(address(L1Messenger))).code\n );\n\n L2Messenger.initialize();\n\n // Label addresses\n vm.label(address(addressManager), \"AddressManager\");\n vm.label(address(L1MessengerImpl), \"L1CrossDomainMessenger_Impl\");\n vm.label(address(L1Messenger), \"L1CrossDomainMessenger_Proxy\");\n vm.label(Predeploys.LEGACY_ERC20_ETH, \"LegacyERC20ETH\");\n vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, \"L2CrossDomainMessenger\");\n\n vm.label(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n \"L1CrossDomainMessenger_aliased\"\n );\n }\n}\n\ncontract Bridge_Initializer is Messenger_Initializer {\n L1StandardBridge L1Bridge;\n L2StandardBridge L2Bridge;\n OptimismMintableERC20Factory L2TokenFactory;\n OptimismMintableERC20Factory L1TokenFactory;\n ERC20 L1Token;\n ERC20 BadL1Token;\n OptimismMintableERC20 L2Token;\n LegacyMintableERC20 LegacyL2Token;\n ERC20 NativeL2Token;\n ERC20 BadL2Token;\n OptimismMintableERC20 RemoteL1Token;\n\n event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data\n );\n\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFailed(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.label(Predeploys.L2_STANDARD_BRIDGE, \"L2StandardBridge\");\n vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, \"OptimismMintableERC20Factory\");\n\n // Deploy the L1 bridge and initialize it with the address of the\n // L1CrossDomainMessenger\n L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig);\n vm.mockCall(\n multisig,\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector),\n abi.encode(true)\n );\n vm.startPrank(multisig);\n proxy.setCode(address(new L1StandardBridge(payable(address(L1Messenger)))).code);\n vm.clearMockedCalls();\n address L1Bridge_Impl = proxy.getImplementation();\n vm.stopPrank();\n\n L1Bridge = L1StandardBridge(payable(address(proxy)));\n\n vm.label(address(proxy), \"L1StandardBridge_Proxy\");\n vm.label(address(L1Bridge_Impl), \"L1StandardBridge_Impl\");\n\n // Deploy the L2StandardBridge, move it to the correct predeploy\n // address and then initialize it\n L2StandardBridge l2B = new L2StandardBridge(payable(proxy));\n vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(l2B).code);\n L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));\n\n // Set up the L2 mintable token factory\n OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(\n Predeploys.L2_STANDARD_BRIDGE\n );\n vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code);\n L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);\n\n vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code);\n\n L1Token = new ERC20(\"Native L1 Token\", \"L1T\");\n\n LegacyL2Token = new LegacyMintableERC20({\n _l2Bridge: address(L2Bridge),\n _l1Token: address(L1Token),\n _name: string.concat(\"LegacyL2-\", L1Token.name()),\n _symbol: string.concat(\"LegacyL2-\", L1Token.symbol())\n });\n vm.label(address(LegacyL2Token), \"LegacyMintableERC20\");\n\n // Deploy the L2 ERC20 now\n L2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(L1Token),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n BadL2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n NativeL2Token = new ERC20(\"Native L2 Token\", \"L2T\");\n L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge));\n\n RemoteL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(NativeL2Token),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n\n BadL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n }\n}\n\ncontract ERC721Bridge_Initializer is Messenger_Initializer {\n L1ERC721Bridge L1Bridge;\n L2ERC721Bridge L2Bridge;\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the L1ERC721Bridge.\n L1Bridge = new L1ERC721Bridge(address(L1Messenger), Predeploys.L2_ERC721_BRIDGE);\n\n // Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.\n vm.etch(\n Predeploys.L2_ERC721_BRIDGE,\n address(new L2ERC721Bridge(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(L1Bridge)))\n .code\n );\n\n // Set up a reference to the L2ERC721Bridge.\n L2Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);\n\n // Label the L1 and L2 bridges.\n vm.label(address(L1Bridge), \"L1ERC721Bridge\");\n vm.label(address(L2Bridge), \"L2ERC721Bridge\");\n }\n}\n\ncontract FFIInterface is Test {\n function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx)\n external\n returns (\n bytes32,\n bytes32,\n bytes32,\n bytes32,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"getProveWithdrawalTransactionInputs\";\n cmds[2] = vm.toString(_tx.nonce);\n cmds[3] = vm.toString(_tx.sender);\n cmds[4] = vm.toString(_tx.target);\n cmds[5] = vm.toString(_tx.value);\n cmds[6] = vm.toString(_tx.gasLimit);\n cmds[7] = vm.toString(_tx.data);\n\n bytes memory result = vm.ffi(cmds);\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[]));\n\n return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof);\n }\n\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashWithdrawal(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashWithdrawal\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashOutputRootProof(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external returns (bytes32) {\n string[] memory cmds = new string[](6);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashOutputRootProof\";\n cmds[2] = Strings.toHexString(uint256(_version));\n cmds[3] = Strings.toHexString(uint256(_stateRoot));\n cmds[4] = Strings.toHexString(uint256(_messagePasserStorageRoot));\n cmds[5] = Strings.toHexString(uint256(_latestBlockhash));\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashDepositTransaction(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external returns (bytes32) {\n string[] memory cmds = new string[](10);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashDepositTransaction\";\n cmds[2] = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n cmds[3] = vm.toString(_logIndex);\n cmds[4] = vm.toString(_from);\n cmds[5] = vm.toString(_to);\n cmds[6] = vm.toString(_mint);\n cmds[7] = vm.toString(_value);\n cmds[8] = vm.toString(_gas);\n cmds[9] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function encodeDepositTransaction(Types.UserDepositTransaction calldata txn)\n external\n returns (bytes memory)\n {\n string[] memory cmds = new string[](11);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeDepositTransaction\";\n cmds[2] = vm.toString(txn.from);\n cmds[3] = vm.toString(txn.to);\n cmds[4] = vm.toString(txn.value);\n cmds[5] = vm.toString(txn.mint);\n cmds[6] = vm.toString(txn.gasLimit);\n cmds[7] = vm.toString(txn.isCreation);\n cmds[8] = vm.toString(txn.data);\n cmds[9] = vm.toString(txn.l1BlockHash);\n cmds[10] = vm.toString(txn.logIndex);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes memory) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) {\n string[] memory cmds = new string[](3);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"decodeVersionedNonce\";\n cmds[2] = vm.toString(nonce);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (uint256, uint256));\n }\n\n function getMerkleTrieFuzzCase(string memory variant)\n external\n returns (\n bytes32,\n bytes memory,\n bytes memory,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](5);\n cmds[0] = \"./test-case-generator/fuzz\";\n cmds[1] = \"-m\";\n cmds[2] = \"trie\";\n cmds[3] = \"-v\";\n cmds[4] = variant;\n\n return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[]));\n }\n}\n\n// Used for testing a future upgrade beyond the current implementations.\n// We include some variables so that we can sanity check accessing storage values after an upgrade.\ncontract NextImpl is Initializable {\n // Initializable occupies the zero-th slot.\n bytes32 slot1;\n bytes32[19] __gap;\n bytes32 slot21;\n bytes32 public constant slot21Init = bytes32(hex\"1337\");\n\n function initialize() public reinitializer(2) {\n // Slot21 is unused by an of our upgradeable contracts.\n // This is used to verify that we can access this value after an upgrade.\n slot21 = slot21Init;\n }\n}\n\ncontract Reverter {\n fallback() external {\n revert();\n }\n}\n\n// Useful for testing reentrancy guards\ncontract CallerCaller {\n event WhatHappened(bool success, bytes returndata);\n\n fallback() external {\n (bool success, bytes memory returndata) = msg.sender.call(msg.data);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n\n// Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard.\ncontract ConfigurableCaller {\n bool doRevert = true;\n address target;\n bytes payload;\n\n event WhatHappened(bool success, bytes returndata);\n\n /**\n * @notice Call the configured target with the configured payload OR revert.\n */\n function call() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n } else {\n (bool success, bytes memory returndata) = address(target).call(payload);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n }\n\n /**\n * @notice Set whether or not to have `call` revert.\n */\n function setDoRevert(bool _doRevert) external {\n doRevert = _doRevert;\n }\n\n /**\n * @notice Set the target for the call made in `call`.\n */\n function setTarget(address _target) external {\n target = _target;\n }\n\n /**\n * @notice Set the payload for the call made in `call`.\n */\n function setPayload(bytes calldata _payload) external {\n payload = _payload;\n }\n\n /**\n * @notice Fallback function that reverts if `doRevert` is true.\n * Otherwise, it does nothing.\n */\n fallback() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n }\n }\n}\n" - }, - "contracts/test/CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, CallerCaller, CommonTest } from \"./CommonTest.t.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\n\n// Libraries\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n// CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2\n// CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract.\ncontract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {\n // Ensure that baseGas passes for the max value of _minGasLimit,\n // this is about 4 Billion.\n function test_baseGas_succeeds() external view {\n L1Messenger.baseGas(hex\"ff\", type(uint32).max);\n }\n\n // Fuzz for other values which might cause a revert in baseGas.\n function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view {\n L1Messenger.baseGas(hex\"ff\", _minGasLimit);\n }\n\n /**\n * @notice The baseGas function should always return a value greater than\n * or equal to the minimum gas limit value on the OptimismPortal.\n * This guarantees that the messengers will always pass sufficient\n * gas to the OptimismPortal.\n */\n function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit)\n external\n {\n vm.assume(_data.length <= type(uint64).max);\n uint64 baseGas = L1Messenger.baseGas(_data, _minGasLimit);\n uint64 minGasLimit = op.minimumGasLimit(uint64(_data.length));\n assertTrue(baseGas >= minGasLimit);\n }\n}\n\n/**\n * @title ExternalRelay\n * @notice A mock external contract called via the SafeCall inside\n * the CrossDomainMessenger's `relayMessage` function.\n */\ncontract ExternalRelay is CommonTest {\n address internal op;\n address internal fuzzedSender;\n L1CrossDomainMessenger internal L1Messenger;\n\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n constructor(L1CrossDomainMessenger _l1Messenger, address _op) {\n L1Messenger = _l1Messenger;\n op = _op;\n }\n\n /**\n * @notice Internal helper function to relay a message and perform assertions.\n */\n function _internalRelay(address _innerSender) internal {\n address initialSender = L1Messenger.xDomainMessageSender();\n\n bytes memory callMessage = getCallData();\n\n bytes32 hash = Hashing.hashCrossDomainMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: _innerSender,\n _target: address(this),\n _value: 0,\n _gasLimit: 0,\n _data: callMessage\n });\n\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n vm.prank(address(op));\n L1Messenger.relayMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: _innerSender,\n _target: address(this),\n _value: 0,\n _minGasLimit: 0,\n _message: callMessage\n });\n\n assertTrue(L1Messenger.failedMessages(hash));\n assertFalse(L1Messenger.successfulMessages(hash));\n assertEq(initialSender, L1Messenger.xDomainMessageSender());\n }\n\n /**\n * @notice externalCallWithMinGas is called by the CrossDomainMessenger.\n */\n function externalCallWithMinGas() external payable {\n for (uint256 i = 0; i < 10; i++) {\n address _innerSender;\n unchecked {\n _innerSender = address(uint160(uint256(uint160(fuzzedSender)) + i));\n }\n _internalRelay(_innerSender);\n }\n }\n\n /**\n * @notice Helper function to get the callData for an `externalCallWithMinGas\n */\n function getCallData() public pure returns (bytes memory) {\n return abi.encodeWithSelector(ExternalRelay.externalCallWithMinGas.selector);\n }\n\n /**\n * @notice Helper function to set the fuzzed sender\n */\n function setFuzzedSender(address _fuzzedSender) public {\n fuzzedSender = _fuzzedSender;\n }\n}\n\n/**\n * @title CrossDomainMessenger_RelayMessage_Test\n * @notice Fuzz tests re-entrancy into the CrossDomainMessenger relayMessage function.\n */\ncontract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer {\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n ExternalRelay public er;\n\n function setUp() public override {\n super.setUp();\n er = new ExternalRelay(L1Messenger, address(op));\n }\n\n /**\n * @dev This test mocks an OptimismPortal call to the L1CrossDomainMessenger via\n * the relayMessage function. The relayMessage function will then use SafeCall's\n * callWithMinGas to call the target with call data packed in the callMessage.\n * For this test, the callWithMinGas will call the mock ExternalRelay test contract\n * defined above, executing the externalCallWithMinGas function which will try to\n * re-enter the CrossDomainMessenger's relayMessage function, resulting in that message\n * being recorded as failed.\n */\n function testFuzz_relayMessageReenter_succeeds(address _sender, uint256 _gasLimit) external {\n vm.assume(_sender != Predeploys.L2_CROSS_DOMAIN_MESSENGER);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n er.setFuzzedSender(_sender);\n address target = address(er);\n bytes memory callMessage = er.getCallData();\n\n vm.expectCall(target, callMessage);\n\n uint64 gasLimit = uint64(bound(_gasLimit, 0, 30_000_000));\n\n bytes32 hash = Hashing.hashCrossDomainMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: sender,\n _target: target,\n _value: 0,\n _gasLimit: gasLimit,\n _data: callMessage\n });\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n L1Messenger.relayMessage({\n _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n _sender: sender,\n _target: target,\n _value: 0,\n _minGasLimit: gasLimit,\n _message: callMessage\n });\n\n assertTrue(L1Messenger.successfulMessages(hash));\n assertEq(L1Messenger.failedMessages(hash), false);\n\n // Ensures that the `xDomainMsgSender` is set back to `Predeploys.L2_CROSS_DOMAIN_MESSENGER`\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest, Portal_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable } from \"../L2/CrossDomainOwnable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Vm, VmSafe } from \"forge-std/Vm.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract XDomainSetter is CrossDomainOwnable {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable_Test is CommonTest {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n setter = new XDomainSetter();\n }\n\n // Check that the revert message is correct\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable: caller is not the owner\");\n setter.set(1);\n }\n\n // Check that making a call can set the value properly\n function test_onlyOwner_succeeds() external {\n assertEq(setter.value(), 0);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(setter.owner()));\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n\ncontract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n\n vm.prank(alice);\n setter = new XDomainSetter();\n }\n\n function test_depositTransaction_crossDomainOwner_succeeds() external {\n vm.recordLogs();\n\n vm.prank(alice);\n op.depositTransaction({\n _to: address(setter),\n _value: 0,\n _gasLimit: 30_000,\n _isCreation: false,\n _data: abi.encodeWithSelector(XDomainSetter.set.selector, 1)\n });\n\n // Simulate the operation of the `op-node` by parsing data\n // from logs\n VmSafe.Log[] memory logs = vm.getRecordedLogs();\n // Only 1 log emitted\n assertEq(logs.length, 1);\n\n VmSafe.Log memory log = logs[0];\n\n // It is the expected topic\n bytes32 topic = log.topics[0];\n assertEq(topic, keccak256(\"TransactionDeposited(address,address,uint256,bytes)\"));\n\n // from is indexed and the first argument to the event.\n bytes32 _from = log.topics[1];\n address from = Bytes32AddressLib.fromLast20Bytes(_from);\n\n assertEq(AddressAliasHelper.undoL1ToL2Alias(from), alice);\n\n // Make a call from the \"from\" value received from the log.\n // In theory the opaque data could be parsed from the log\n // and passed to a low level call to \"to\", but calling set\n // directly on the setter is good enough.\n vm.prank(from);\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable2.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable2 } from \"../L2/CrossDomainOwnable2.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter2 is CrossDomainOwnable2 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable2_Test is Messenger_Initializer {\n XDomainSetter2 setter;\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter2();\n }\n\n function test_onlyOwner_notMessenger_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice));\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the owner\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner2_reverts() external {\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_onlyOwner_succeeds() external {\n address owner = setter.owner();\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n owner,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter2.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable3.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable3 } from \"../L2/CrossDomainOwnable3.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter3 is CrossDomainOwnable3 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable3_Test is Messenger_Initializer {\n XDomainSetter3 setter;\n\n /**\n * @notice OpenZeppelin Ownable.sol transferOwnership event\n */\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @notice CrossDomainOwnable3.sol transferOwnership event\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter3();\n }\n\n function test_constructor_succeeds() public {\n assertEq(setter.owner(), alice);\n assertEq(setter.isLocal(), true);\n }\n\n function test_localOnlyOwner_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_transferOwnership_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n }\n\n function test_crossDomainOnlyOwner_notOwner_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob);\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_crossDomainOnlyOwner_notOwner2_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter3.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_crossDomainOnlyOwner_notMessenger_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_transferOwnership_zeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"CrossDomainOwnable3: new owner is the zero address\");\n setter.transferOwnership({ _owner: address(0), _isLocal: true });\n }\n\n function test_transferOwnership_noLocalZeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"Ownable: new owner is the zero address\");\n setter.transferOwnership(address(0));\n }\n\n function test_localOnlyOwner_succeeds() public {\n assertEq(setter.isLocal(), true);\n vm.prank(setter.owner());\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n\n function test_localTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, true);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n\n assertEq(setter.isLocal(), true);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n /**\n * @notice The existing transferOwnership(address) method\n * still exists on the contract\n */\n function test_transferOwnershipNoLocal_succeeds() public {\n bool isLocal = setter.isLocal();\n\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n\n vm.prank(setter.owner());\n setter.transferOwnership(bob);\n\n // isLocal has not changed\n assertEq(setter.isLocal(), isLocal);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n function test_crossDomainTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n bob,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter3.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/DeployerWhitelist.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { DeployerWhitelist } from \"../legacy/DeployerWhitelist.sol\";\n\ncontract DeployerWhitelist_Test is CommonTest {\n DeployerWhitelist list;\n\n function setUp() public virtual override {\n list = new DeployerWhitelist();\n }\n\n // The owner should be address(0)\n function test_owner_succeeds() external {\n assertEq(list.owner(), address(0));\n }\n\n // The storage slot for the owner must be the same\n function test_storageSlots_succeeds() external {\n vm.prank(list.owner());\n list.setOwner(address(1));\n\n assertEq(bytes32(uint256(1)), vm.load(address(list), bytes32(uint256(0))));\n }\n}\n" - }, - "contracts/test/Encoding.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Encoding_Test is CommonTest {\n function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external {\n (uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(\n Encoding.encodeVersionedNonce(_nonce, _version)\n );\n assertEq(version, _version);\n assertEq(nonce, _nonce);\n }\n\n function testDiff_decodeVersionedNonce_succeeds(uint240 _nonce, uint16 _version) external {\n uint256 nonce = uint256(Encoding.encodeVersionedNonce(_nonce, _version));\n (uint256 decodedNonce, uint256 decodedVersion) = ffi.decodeVersionedNonce(nonce);\n\n assertEq(_version, uint16(decodedVersion));\n\n assertEq(_nonce, uint240(decodedNonce));\n }\n\n function testDiff_encodeCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint8 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint8 version = _version % 2;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory encoding = Encoding.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n bytes memory _encoding = ffi.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n assertEq(encoding, _encoding);\n }\n\n function testFuzz_encodeCrossDomainMessageV0_matchesLegacy_succeeds(\n uint240 _nonce,\n address _sender,\n address _target,\n bytes memory _data\n ) external {\n uint8 version = 0;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory legacyEncoding = LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _data,\n nonce\n );\n\n bytes memory bedrockEncoding = Encoding.encodeCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n nonce\n );\n\n assertEq(legacyEncoding, bedrockEncoding);\n }\n\n function testDiff_encodeDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bool isCreate,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n Types.UserDepositTransaction memory t = Types.UserDepositTransaction(\n _from,\n _to,\n isCreate,\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n );\n\n bytes memory txn = Encoding.encodeDepositTransaction(t);\n bytes memory _txn = ffi.encodeDepositTransaction(t);\n\n assertEq(txn, _txn);\n }\n}\n" - }, - "contracts/test/FeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { L1FeeVault } from \"../L2/L1FeeVault.sol\";\nimport { BaseFeeVault } from \"../L2/BaseFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n// Test the implementations of the FeeVault\ncontract FeeVault_Test is Bridge_Initializer {\n BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));\n L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT));\n\n address constant recipient = address(0x10000);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.BASE_FEE_VAULT, address(new BaseFeeVault(recipient)).code);\n vm.etch(Predeploys.L1_FEE_VAULT, address(new L1FeeVault(recipient)).code);\n\n vm.label(Predeploys.BASE_FEE_VAULT, \"BaseFeeVault\");\n vm.label(Predeploys.L1_FEE_VAULT, \"L1FeeVault\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(baseFeeVault.RECIPIENT(), recipient);\n assertEq(l1FeeVault.RECIPIENT(), recipient);\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n}\n" - }, - "contracts/test/GasPriceOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GasPriceOracle } from \"../L2/GasPriceOracle.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract GasPriceOracle_Test is CommonTest {\n event OverheadUpdated(uint256);\n event ScalarUpdated(uint256);\n event DecimalsUpdated(uint256);\n\n GasPriceOracle gasOracle;\n L1Block l1Block;\n address depositor;\n\n // set the initial L1 context values\n uint64 constant number = 10;\n uint64 constant timestamp = 11;\n uint256 constant basefee = 100;\n bytes32 constant hash = bytes32(uint256(64));\n uint64 constant sequenceNumber = 0;\n bytes32 constant batcherHash = bytes32(uint256(777));\n uint256 constant l1FeeOverhead = 310;\n uint256 constant l1FeeScalar = 10;\n\n function setUp() public virtual override {\n super.setUp();\n // place the L1Block contract at the predeploy address\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n\n l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n depositor = l1Block.DEPOSITOR_ACCOUNT();\n\n // We are not setting the gas oracle at its predeploy\n // address for simplicity purposes. Nothing in this test\n // requires it to be at a particular address\n gasOracle = new GasPriceOracle();\n\n vm.prank(depositor);\n l1Block.setL1BlockValues({\n _number: number,\n _timestamp: timestamp,\n _basefee: basefee,\n _hash: hash,\n _sequenceNumber: sequenceNumber,\n _batcherHash: batcherHash,\n _l1FeeOverhead: l1FeeOverhead,\n _l1FeeScalar: l1FeeScalar\n });\n }\n\n function test_l1BaseFee_succeeds() external {\n assertEq(gasOracle.l1BaseFee(), basefee);\n }\n\n function test_gasPrice_succeeds() external {\n vm.fee(100);\n uint256 gasPrice = gasOracle.gasPrice();\n assertEq(gasPrice, 100);\n }\n\n function test_baseFee_succeeds() external {\n vm.fee(64);\n uint256 gasPrice = gasOracle.baseFee();\n assertEq(gasPrice, 64);\n }\n\n function test_scalar_succeeds() external {\n assertEq(gasOracle.scalar(), l1FeeScalar);\n }\n\n function test_overhead_succeeds() external {\n assertEq(gasOracle.overhead(), l1FeeOverhead);\n }\n\n function test_decimals_succeeds() external {\n assertEq(gasOracle.decimals(), 6);\n assertEq(gasOracle.DECIMALS(), 6);\n }\n\n // Removed in bedrock\n function test_setGasPrice_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setGasPrice(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n\n // Removed in bedrock\n function test_setL1BaseFee_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setL1BaseFee(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n}\n" - }, - "contracts/test/GovernanceToken.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract GovernanceToken_Test is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n\n function setUp() public virtual override {\n super.setUp();\n vm.prank(owner);\n gov = new GovernanceToken();\n }\n\n function test_constructor_succeeds() external {\n assertEq(gov.owner(), owner);\n assertEq(gov.name(), \"Optimism\");\n assertEq(gov.symbol(), \"OP\");\n assertEq(gov.decimals(), 18);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_mint_fromOwner_succeeds() external {\n // Mint 100 tokens.\n vm.prank(owner);\n gov.mint(owner, 100);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 100);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_mint_fromNotOwner_reverts() external {\n // Mint 100 tokens as rando.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n gov.mint(owner, 100);\n\n // Balance does not update.\n assertEq(gov.balanceOf(owner), 0);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_burn_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando burns their tokens.\n vm.prank(rando);\n gov.burn(50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_burnFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to burn 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner burns 50 tokens from rando.\n vm.prank(owner);\n gov.burnFrom(rando, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_transfer_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando transfers 50 tokens to owner.\n vm.prank(rando);\n gov.transfer(owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_approve_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n\n function test_transferFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner transfers 50 tokens from rando to owner.\n vm.prank(owner);\n gov.transferFrom(rando, owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_increaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Rando increases allowance by 50 tokens.\n vm.prank(rando);\n gov.increaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 100);\n }\n\n function test_decreaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 100 tokens.\n vm.prank(rando);\n gov.approve(owner, 100);\n\n // Rando decreases allowance by 50 tokens.\n vm.prank(rando);\n gov.decreaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n}\n" - }, - "contracts/test/Hashing.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Hashing_hashDepositSource_Test is CommonTest {\n /**\n * @notice Tests that hashDepositSource returns the correct hash in a simple case.\n */\n function test_hashDepositSource_succeeds() external {\n assertEq(\n Hashing.hashDepositSource(\n 0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,\n 0x1\n ),\n 0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc\n );\n }\n}\n\ncontract Hashing_hashCrossDomainMessage_Test is CommonTest {\n /**\n * @notice Tests that hashCrossDomainMessage returns the correct hash in a simple case.\n */\n function testDiff_hashCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint16 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Ensure the version is valid.\n uint16 version = uint16(bound(uint256(_version), 0, 1));\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n assertEq(\n Hashing.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data),\n ffi.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n\n /**\n * @notice Tests that hashCrossDomainMessageV0 matches the hash of the legacy encoding.\n */\n function testFuzz_hashCrossDomainMessageV0_matchesLegacy_succeeds(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) external {\n assertEq(\n keccak256(\n LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _message,\n _messageNonce\n )\n ),\n Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _messageNonce)\n );\n }\n}\n\ncontract Hashing_hashWithdrawal_Test is CommonTest {\n /**\n * @notice Tests that hashWithdrawal returns the correct hash in a simple case.\n */\n function testDiff_hashWithdrawal_succeeds(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n assertEq(\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)\n ),\n ffi.hashWithdrawal(_nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n}\n\ncontract Hashing_hashOutputRootProof_Test is CommonTest {\n /**\n * @notice Tests that hashOutputRootProof returns the correct hash in a simple case.\n */\n function testDiff_hashOutputRootProof_succeeds(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external {\n assertEq(\n Hashing.hashOutputRootProof(\n Types.OutputRootProof({\n version: _version,\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _messagePasserStorageRoot,\n latestBlockhash: _latestBlockhash\n })\n ),\n ffi.hashOutputRootProof(\n _version,\n _stateRoot,\n _messagePasserStorageRoot,\n _latestBlockhash\n )\n );\n }\n}\n\ncontract Hashing_hashDepositTransaction_Test is CommonTest {\n /**\n * @notice Tests that hashDepositTransaction returns the correct hash in a simple case.\n */\n function testDiff_hashDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n assertEq(\n Hashing.hashDepositTransaction(\n Types.UserDepositTransaction(\n _from,\n _to,\n false, // isCreate\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n )\n ),\n ffi.hashDepositTransaction(_from, _to, _mint, _value, _gas, _data, _logIndex)\n );\n }\n}\n" - }, - "contracts/test/L1Block.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\ncontract L1BlockTest is CommonTest {\n L1Block lb;\n address depositor;\n bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));\n\n function setUp() public virtual override {\n super.setUp();\n lb = new L1Block();\n depositor = lb.DEPOSITOR_ACCOUNT();\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: uint64(1),\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: NON_ZERO_HASH,\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(0),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function testFuzz_updatesValues_succeeds(\n uint64 n,\n uint64 t,\n uint256 b,\n bytes32 h,\n uint64 s,\n bytes32 bt,\n uint256 fo,\n uint256 fs\n ) external {\n vm.prank(depositor);\n lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs);\n assertEq(lb.number(), n);\n assertEq(lb.timestamp(), t);\n assertEq(lb.basefee(), b);\n assertEq(lb.hash(), h);\n assertEq(lb.sequenceNumber(), s);\n assertEq(lb.batcherHash(), bt);\n assertEq(lb.l1FeeOverhead(), fo);\n assertEq(lb.l1FeeScalar(), fs);\n }\n\n function test_number_succeeds() external {\n assertEq(lb.number(), uint64(1));\n }\n\n function test_timestamp_succeeds() external {\n assertEq(lb.timestamp(), uint64(2));\n }\n\n function test_basefee_succeeds() external {\n assertEq(lb.basefee(), 3);\n }\n\n function test_hash_succeeds() external {\n assertEq(lb.hash(), NON_ZERO_HASH);\n }\n\n function test_sequenceNumber_succeeds() external {\n assertEq(lb.sequenceNumber(), uint64(4));\n }\n\n function test_updateValues_succeeds() external {\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: type(uint64).max,\n _timestamp: type(uint64).max,\n _basefee: type(uint256).max,\n _hash: keccak256(abi.encode(1)),\n _sequenceNumber: type(uint64).max,\n _batcherHash: bytes32(type(uint256).max),\n _l1FeeOverhead: type(uint256).max,\n _l1FeeScalar: type(uint256).max\n });\n }\n}\n" - }, - "contracts/test/L1BlockNumber.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { L1BlockNumber } from \"../legacy/L1BlockNumber.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract L1BlockNumberTest is Test {\n L1Block lb;\n L1BlockNumber bn;\n\n uint64 constant number = 99;\n\n function setUp() external {\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n lb = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n bn = new L1BlockNumber();\n vm.prank(lb.DEPOSITOR_ACCOUNT());\n\n lb.setL1BlockValues({\n _number: number,\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: bytes32(uint256(10)),\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(uint256(0)),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function test_getL1BlockNumber_succeeds() external {\n assertEq(bn.getL1BlockNumber(), number);\n }\n\n function test_fallback_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n\n function test_receive_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call{ value: 1 }(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n}\n" - }, - "contracts/test/L1CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle_Initializer } from \"./L2OutputOracle.t.sol\";\n\n/* Libraries */\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n/* Target contract dependencies */\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/* Target contract */\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\n\ncontract L1CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n // the version is encoded in the nonce\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce());\n assertEq(version, L1Messenger.MESSAGE_VERSION());\n }\n\n // sendMessage: should be able to send a single message\n // TODO: this same test needs to be done with the legacy message type\n // by setting the message version to 0\n function test_sendMessage_succeeds() external {\n // deposit transaction on the optimism portal should be called\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n )\n );\n\n // TransactionDeposited event\n vm.expectEmit(true, true, true, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n );\n\n // SentMessage event\n vm.expectEmit(true, true, true, true);\n emit SentMessage(recipient, alice, hex\"ff\", L1Messenger.messageNonce(), 100);\n\n // SentMessageExtension1 event\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(alice, 0);\n\n vm.prank(alice);\n L1Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n // sendMessage: should be able to send the same message twice\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L1Messenger.messageNonce());\n }\n\n function test_xDomainSender_notSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(address(op));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n // relayMessage: should send a successful call to the target contract\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.expectCall(target, hex\"1111\");\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n // set the target to be the OptimismPortal\n address target = address(op);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.prank(address(op));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n\n vm.store(address(op), 0, bytes32(abi.encode(sender)));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: should revert if eth is sent from a contract other than the standard bridge\n function test_replayMessage_withValue_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.expectRevert(\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n L1Messenger.relayMessage{ value: 100 }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n vm.expectCall(target, hex\"1111\");\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacy_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyOldReplay_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Mark legacy message as already relayed.\n uint256 successfulMessagesSlot = 203;\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex\"1111\", 0);\n bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot));\n vm.store(address(L1Messenger), slot, bytes32(uint256(1)));\n\n // Expect revert.\n vm.expectRevert(\"CrossDomainMessenger: legacy withdrawal already relayed\");\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was not relayed.\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyRetryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect FailedRelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacyRetryAfterSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message has already been relayed\");\n\n // Retry the message again.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n}\n" - }, - "contracts/test/L1ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L1ERC721Bridge_Test is Messenger_Initializer {\n TestERC721 internal localToken;\n TestERC721 internal remoteToken;\n L1ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L1ERC721Bridge(address(L1Messenger), otherBridge);\n localToken = new TestERC721();\n remoteToken = new TestERC721();\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L1ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L1Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L1Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notEscrowed_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n" - }, - "contracts/test/L1StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\n\ncontract L1StandardBridge_Getter_Test is Bridge_Initializer {\n function test_getters_succeeds() external {\n assert(L1Bridge.l2TokenBridge() == address(L2Bridge));\n assert(L1Bridge.OTHER_BRIDGE() == L2Bridge);\n assert(L1Bridge.messenger() == L1Messenger);\n assert(L1Bridge.MESSENGER() == L1Messenger);\n assertEq(L1Bridge.version(), \"1.1.0\");\n }\n}\n\ncontract L1StandardBridge_Initialize_Test is Bridge_Initializer {\n function test_initialize_succeeds() external {\n assertEq(address(L1Bridge.messenger()), address(L1Messenger));\n\n assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE);\n\n assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE);\n }\n}\n\ncontract L1StandardBridge_Initialize_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_Receive_Test is Bridge_Initializer {\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(op).balance, 0);\n\n // The legacy event must be emitted for backwards compatibility\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n ),\n 200_000\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L1Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(op).balance, 100);\n }\n}\n\ncontract L1StandardBridge_Receive_TestFail {}\n\ncontract PreBridgeETH is Bridge_Initializer {\n function _preBridgeETH(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 500,\n hex\"dead\"\n );\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex\"dead\")\n );\n }\n vm.expectCall(\n address(L1Messenger),\n 500,\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 50000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 500,\n 50000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 50000);\n vm.expectCall(\n address(op),\n 500,\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 500,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(500),\n uint256(500),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 500, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 500, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 50000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 500);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETH_Test is PreBridgeETH {\n // depositETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_depositETH_succeeds() external {\n _preBridgeETH({ isLegacy: true });\n L1Bridge.depositETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_BridgeETH_Test is PreBridgeETH {\n // BridgeETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETH_succeeds() external {\n _preBridgeETH({ isLegacy: false });\n L1Bridge.bridgeETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer {\n function test_depositETH_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, address(L1Token).code);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice);\n L1Bridge.depositETH{ value: 1 }(300, hex\"\");\n }\n}\n\ncontract PreBridgeETHTo is Bridge_Initializer {\n function _preBridgeETHTo(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex\"dead\")\n );\n }\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n bob,\n 600,\n hex\"dead\"\n );\n\n // the L1 bridge should call\n // L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 60000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 600,\n 60000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 60000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 600,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(600),\n uint256(600),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, bob, 600, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, bob, 600, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 60000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 600);\n\n // deposit eth to bob\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo {\n // depositETHTo\n // - emits ETHDepositInitiated\n // - calls optimismPortal.depositTransaction\n // - EOA or contract can call\n // - ETH ends up in the optimismPortal\n function test_depositETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: true });\n L1Bridge.depositETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo {\n // BridgeETHTo\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: false });\n L1Bridge.bridgeETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // depositERC20\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - only callable by EOA\n function test_depositERC20_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Deal Alice's ERC20 State\n deal(address(L1Token), alice, 100000, true);\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n // The L1Bridge should transfer alice's tokens to itself\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)\n );\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n vm.prank(alice);\n L1Bridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex\"\");\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n }\n}\n\ncontract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer {\n function test_depositERC20_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, hex\"ffff\");\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice, alice);\n L1Bridge.depositERC20(address(0), address(0), 100, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {\n // depositERC20To\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - callable by a contract\n function test_depositERC20To_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n bob,\n 1000,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n deal(address(L1Token), alice, 100000, true);\n\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)\n );\n\n vm.prank(alice);\n L1Bridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex\"\");\n\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 1000);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeETHWithdrawal\n // - emits ETHWithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeETHWithdrawal_succeeds() external {\n uint256 aliceBalance = alice.balance;\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHWithdrawalFinalized(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n vm.expectCall(alice, hex\"\");\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n // ensure that the messenger has ETH to call with\n vm.deal(address(L1Bridge.messenger()), 100);\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n\n assertEq(address(L1Bridge.messenger()).balance, 0);\n assertEq(aliceBalance + 100, alice.balance);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeERC20Withdrawal\n // - updates bridge.deposits\n // - emits ERC20WithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeERC20Withdrawal_succeeds() external {\n deal(address(L1Token), address(L1Bridge), 100, true);\n\n uint256 slot = stdstore\n .target(address(L1Bridge))\n .sig(\"deposits(address,address)\")\n .with_key(address(L1Token))\n .with_key(address(L2Token))\n .find();\n\n // Give the L1 bridge some ERC20 tokens\n vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)\n );\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n assertEq(L1Token.balanceOf(address(L1Bridge)), 0);\n assertEq(L1Token.balanceOf(address(alice)), 100);\n }\n}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer {\n function test_finalizeERC20Withdrawal_notMessenger_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(28));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n\n function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(address(0)))\n );\n vm.prank(address(L1Bridge.messenger()));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer {\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L1Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L1Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce());\n assertEq(version, L2Messenger.MESSAGE_VERSION());\n }\n\n function test_sendMessage_succeeds() external {\n bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage(\n L2Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n );\n vm.expectCall(\n address(messagePasser),\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData\n )\n );\n\n // MessagePassed event\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(L2Messenger),\n address(L1Messenger),\n 0,\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData,\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messagePasser.messageNonce(),\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: L2Messenger.baseGas(hex\"ff\", 100),\n data: xDomainCallData\n })\n )\n );\n\n vm.prank(alice);\n L2Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L2Messenger.messageNonce();\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L2Messenger.messageNonce());\n }\n\n function test_xDomainSender_senderNotSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 2), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n vm.expectCall(target, hex\"1111\");\n\n vm.prank(caller);\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L2Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L2Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n address target = address(messagePasser);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory message = hex\"1111\";\n\n vm.prank(caller);\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retry_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n uint256 value = 100;\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(caller), value);\n vm.prank(caller);\n L2Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L2Messenger.successfulMessages(hash), false);\n assertEq(L2Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L2Messenger.successfulMessages(hash), true);\n assertEq(L2Messenger.failedMessages(hash), true);\n }\n}\n" - }, - "contracts/test/L2ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract TestMintableERC721 is OptimismMintableERC721 {\n constructor(address _bridge, address _remoteToken)\n OptimismMintableERC721(_bridge, 1, _remoteToken, \"Test\", \"TST\")\n {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L2ERC721Bridge_Test is Messenger_Initializer {\n TestMintableERC721 internal localToken;\n TestERC721 internal remoteToken;\n L2ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L2ERC721Bridge(address(L2Messenger), otherBridge);\n remoteToken = new TestERC721();\n localToken = new TestMintableERC721(address(bridge), address(remoteToken));\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L2ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L2Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L2Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L1ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_interfaceNotCompliant_reverts() external {\n // Create a non-compliant token\n NonCompliantERC721 nonCompliantToken = new NonCompliantERC721(alice);\n\n // Bridge the non-compliant token.\n vm.prank(alice);\n bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex\"5678\");\n\n // Attempt to finalize the withdrawal. Should revert because the token does not claim\n // to be compliant with the `IOptimismMintableERC721` interface.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token interface is not compliant\");\n bridge.finalizeBridgeERC721(\n address(address(nonCompliantToken)),\n address(address(0x01)),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_alreadyExists_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721: token already minted\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n\n/**\n * @dev A non-compliant ERC721 token that does not implement the full ERC721 interface.\n *\n * This is used to test that the bridge will revert if the token does not claim to support\n * the ERC721 interface.\n */\ncontract NonCompliantERC721 {\n address internal immutable owner;\n\n constructor(address _owner) {\n owner = _owner;\n }\n\n function ownerOf(uint256) external view returns (address) {\n return owner;\n }\n\n function remoteToken() external pure returns (address) {\n return address(0x01);\n }\n\n function burn(address, uint256) external {\n // Do nothing.\n }\n\n function supportsInterface(bytes4) external pure returns (bool) {\n return false;\n }\n}\n" - }, - "contracts/test/L2OutputOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { L2OutputOracle_Initializer, NextImpl } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2OutputOracleTest is L2OutputOracle_Initializer {\n bytes32 proposedOutput1 = keccak256(abi.encode(1));\n\n function test_constructor_succeeds() external {\n assertEq(oracle.PROPOSER(), proposer);\n assertEq(oracle.CHALLENGER(), owner);\n assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);\n assertEq(oracle.latestBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingTimestamp(), startingTimestamp);\n }\n\n function test_constructor_badTimestamp_reverts() external {\n vm.expectRevert(\"L2OutputOracle: starting L2 timestamp must be less than current time\");\n\n // startingTimestamp is in the future\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp + 1,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function test_constructor_l2BlockTimeZero_reverts() external {\n vm.expectRevert(\"L2OutputOracle: L2 block time must be greater than 0\");\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: 0,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function test_constructor_submissionInterval_reverts() external {\n vm.expectRevert(\"L2OutputOracle: submission interval must be greater than 0\");\n new L2OutputOracle({\n _submissionInterval: 0,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n /****************\n * Getter Tests *\n ****************/\n\n // Test: latestBlockNumber() should return the correct value\n function test_latestBlockNumber_succeeds() external {\n uint256 proposedNumber = oracle.nextBlockNumber();\n\n // Roll to after the block number we'll propose\n warpToProposeTime(proposedNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0);\n assertEq(oracle.latestBlockNumber(), proposedNumber);\n }\n\n // Test: getL2Output() should return the correct value\n function test_getL2Output_succeeds() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0);\n\n Types.OutputProposal memory proposal = oracle.getL2Output(nextOutputIndex);\n assertEq(proposal.outputRoot, proposedOutput1);\n assertEq(proposal.timestamp, block.timestamp);\n\n // The block number is larger than the latest proposed output:\n vm.expectRevert(stdError.indexOOBError);\n oracle.getL2Output(nextOutputIndex + 1);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is exact block\n function test_getL2OutputIndexAfter_sameBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with exact same block as proposed returns the proposal.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is previous block\n function test_getL2OutputIndexAfter_previousBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with previous block returns the proposal too.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 - 1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value during binary search\n function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n bytes32 output2 = keccak256(abi.encode(2));\n uint256 nextBlockNumber2 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber2);\n vm.prank(proposer);\n oracle.proposeL2Output(output2, nextBlockNumber2, 0, 0);\n\n bytes32 output3 = keccak256(abi.encode(3));\n uint256 nextBlockNumber3 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber3);\n vm.prank(proposer);\n oracle.proposeL2Output(output3, nextBlockNumber3, 0, 0);\n\n bytes32 output4 = keccak256(abi.encode(4));\n uint256 nextBlockNumber4 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber4);\n vm.prank(proposer);\n oracle.proposeL2Output(output4, nextBlockNumber4, 0, 0);\n\n // Querying with a block number between the first and second proposal\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 + 1);\n assertEq(index1, 1);\n\n // Querying with a block number between the second and third proposal\n uint256 index2 = oracle.getL2OutputIndexAfter(nextBlockNumber2 + 1);\n assertEq(index2, 2);\n\n // Querying with a block number between the third and fourth proposal\n uint256 index3 = oracle.getL2OutputIndexAfter(nextBlockNumber3 + 1);\n assertEq(index3, 3);\n }\n\n // Test: getL2OutputIndexAfter() reverts when no output exists yet\n function test_getL2OutputIndexAfter_noOutputsExis_reverts() external {\n vm.expectRevert(\"L2OutputOracle: cannot get output as no outputs have been proposed yet\");\n oracle.getL2OutputIndexAfter(0);\n }\n\n // Test: nextBlockNumber() should return the correct value\n function test_nextBlockNumber_succeeds() external {\n assertEq(\n oracle.nextBlockNumber(),\n // The return value should match this arithmetic\n oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL()\n );\n }\n\n function test_computeL2Timestamp_succeeds() external {\n // reverts if timestamp is too low\n vm.expectRevert(stdError.arithmeticError);\n oracle.computeL2Timestamp(startingBlockNumber - 1);\n\n // returns the correct value...\n // ... for the very first block\n assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);\n\n // ... for the first block after the starting block\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 1),\n startingTimestamp + l2BlockTime\n );\n\n // ... for some other block number\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 96024),\n startingTimestamp + l2BlockTime * 96024\n );\n }\n\n /*****************************\n * Propose Tests - Happy Path *\n *****************************/\n\n // Test: proposeL2Output succeeds when given valid input, and no block hash and number are\n // specified.\n function test_proposeL2Output_proposeAnotherOutput_succeeds() public {\n bytes32 proposedOutput2 = keccak256(abi.encode());\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n uint256 proposedNumber = oracle.latestBlockNumber();\n\n // Ensure the submissionInterval is enforced\n assertEq(nextBlockNumber, proposedNumber + submissionInterval);\n\n vm.roll(nextBlockNumber + 1);\n\n vm.expectEmit(true, true, true, true);\n emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp);\n\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output succeeds when given valid input, and when a block hash and number are\n // specified for reorg protection.\n function test_proposeWithBlockhashAndHeight_succeeds() external {\n // Get the number and hash of a previous block in the chain\n uint256 prevL1BlockNumber = block.number - 1;\n bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber);\n }\n\n /***************************\n * Propose Tests - Sad Path *\n ***************************/\n\n // Test: proposeL2Output fails if called by a party that is not the proposer.\n function test_proposeL2Output_notProposer_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n\n vm.prank(address(128));\n vm.expectRevert(\"L2OutputOracle: only the proposer address can propose new outputs\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails given a zero blockhash.\n function test_proposeL2Output_emptyOutput_reverts() external {\n bytes32 outputToPropose = bytes32(0);\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: L2 output proposal cannot be the zero hash\");\n oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if the block number doesn't match the next expected number.\n function test_proposeL2Output_unexpectedBlockNumber_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: block number must be equal to next expected block number\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);\n }\n\n // Test: proposeL2Output fails if it would have a timestamp in the future.\n function test_proposeL2Output_futureTimetamp_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber);\n vm.warp(nextTimestamp);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: cannot propose L2 output in the future\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if a non-existent L1 block hash and number are provided for reorg\n // protection.\n function test_proposeL2Output_wrongFork_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(\n nonZeroHash,\n nextBlockNumber,\n bytes32(uint256(0x01)),\n block.number - 1\n );\n }\n\n // Test: proposeL2Output fails when given valid input, but the block hash and number do not\n // match.\n function test_proposeL2Output_unmatchedBlockhash_reverts() external {\n // Move ahead to block 100 so that we can reference historical blocks\n vm.roll(100);\n\n // Get the number and hash of a previous block in the chain\n uint256 l1BlockNumber = block.number - 1;\n bytes32 l1BlockHash = blockhash(l1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n\n // This will fail when foundry no longer returns zerod block hashes\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);\n }\n\n /*****************************\n * Delete Tests - Happy Path *\n *****************************/\n\n function test_deleteOutputs_singleOutput_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 1);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex);\n oracle.deleteL2Outputs(latestOutputIndex);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n function test_deleteOutputs_multipleOutputs_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 3);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n /***************************\n * Delete Tests - Sad Path *\n ***************************/\n\n function test_deleteL2Outputs_ifNotChallenger_reverts() external {\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.expectRevert(\"L2OutputOracle: only the challenger address can delete outputs\");\n oracle.deleteL2Outputs(latestBlockNumber);\n }\n\n function test_deleteL2Outputs_nonExistent_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestBlockNumber + 1);\n }\n\n function test_deleteL2Outputs_afterLatest_reverts() external {\n // Start by proposing three outputs\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Delete the latest two outputs\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n vm.prank(owner);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // Now try to delete the same output again\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n }\n\n function test_deleteL2Outputs_finalized_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Warp past the finalization period + 1 second\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n\n // Try to delete a finalized output\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs that have already been finalized\");\n oracle.deleteL2Outputs(latestOutputIndex);\n }\n}\n\ncontract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {\n Proxy internal proxy;\n\n function setUp() public override {\n super.setUp();\n proxy = Proxy(payable(address(oracle)));\n }\n\n function test_initValuesOnProxy_succeeds() external {\n assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());\n assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());\n assertEq(startingBlockNumber, oracleImpl.startingBlockNumber());\n assertEq(startingTimestamp, oracleImpl.startingTimestamp());\n\n assertEq(proposer, oracleImpl.PROPOSER());\n assertEq(owner, oracleImpl.CHALLENGER());\n }\n\n function test_initializeProxy_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(payable(proxy)).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_initializeImpl_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(oracleImpl).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(oracle), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(oracle), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(oracle)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/L2StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { console } from \"forge-std/console.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\ncontract L2StandardBridge_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n function test_initialize_succeeds() external {\n assertEq(address(L2Bridge.messenger()), address(L2Messenger));\n assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge));\n assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge));\n }\n\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(messagePasser).balance, 0);\n uint256 nonce = L2Messenger.messageNonce();\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 200_000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 100,\n 200_000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 100,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n // L2ToL1MessagePasser will emit a MessagePassed event\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 100,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 200_000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 100);\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L2Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(messagePasser).balance, 100);\n }\n\n // withrdraw\n // - requires amount == msg.value\n function test_withdraw_insufficientValue_reverts() external {\n assertEq(address(messagePasser).balance, 0);\n\n vm.expectRevert(\"StandardBridge: bridging ETH must include sufficient ETH value\");\n vm.prank(alice, alice);\n L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex\"\");\n }\n\n /**\n * @notice Use the legacy `withdraw` interface on the L2StandardBridge to\n * withdraw ether from L2 to L1.\n */\n function test_withdraw_ether_succeeds() external {\n assertTrue(alice.balance >= 100);\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0);\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated({\n l1Token: address(0),\n l2Token: Predeploys.LEGACY_ERC20_ETH,\n from: alice,\n to: alice,\n amount: 100,\n data: hex\"\"\n });\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex\"\" });\n\n vm.prank(alice, alice);\n L2Bridge.withdraw{ value: 100 }({\n _l2Token: Predeploys.LEGACY_ERC20_ETH,\n _amount: 100,\n _minGasLimit: 1000,\n _extraData: hex\"\"\n });\n\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 100);\n }\n}\n\ncontract PreBridgeERC20 is Bridge_Initializer {\n // withdraw and BridgeERC20 should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20(bool _isLegacy, address _l2Token) internal {\n // Alice has 100 L2Token\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(_l2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex\"\")\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20.selector,\n _l2Token,\n address(L1Token),\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n _l2Token,\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {\n // withdraw\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_withdraw_withdrawingERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // BridgeERC20\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdrawLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) });\n L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_bridgeLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) });\n L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdraw_notEOA_reverts() external {\n // This contract has 100 L2Token\n deal(address(L2Token), address(this), 100, true);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n }\n}\n\ncontract PreBridgeERC20To is Bridge_Initializer {\n // withdrawTo and BridgeERC20To should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal {\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(L2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n bob,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.withdrawTo.selector,\n _l2Token,\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20To.selector,\n _l2Token,\n address(L1Token),\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {\n // withdrawTo\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_withdrawTo_withdrawingERC20_succeeds() external {\n _preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // bridgeERC20To\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20To_succeeds() external {\n _preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex\"\");\n assertEq(L2Token.balanceOf(alice), 0);\n }\n}\n\ncontract L2StandardBridge_Bridge_Test is Bridge_Initializer {\n // finalizeDeposit\n // - only callable by l1TokenBridge\n // - supported token pair emits DepositFinalized\n // - invalid deposit calls Withdrawer.initiateWithdrawal\n function test_finalizeDeposit_depositingERC20_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex\"\");\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeDeposit_depositingETH_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(\n address(L2Token), // localToken\n address(L1Token), // remoteToken\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Messenger), 100, hex\"\");\n }\n}\n\ncontract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L2Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true);\n emit DepositFinalized(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2ToL1MessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\n\ncontract L2ToL1MessagePasserTest is CommonTest {\n L2ToL1MessagePasser messagePasser;\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new L2ToL1MessagePasser();\n }\n\n function testFuzz_initiateWithdrawal_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint256 nonce = messagePasser.messageNonce();\n\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: _value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash);\n\n vm.deal(_sender, _value);\n vm.prank(_sender);\n messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);\n\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0)));\n\n assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1)));\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by a contract\n function test_initiateWithdrawal_fromContract_succeeds() external {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\"\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\",\n withdrawalHash\n );\n\n vm.deal(address(this), 2**64);\n messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex\"\");\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by an EOA\n function test_initiateWithdrawal_fromEOA_succeeds() external {\n uint256 gasLimit = 64000;\n address target = address(4);\n uint256 value = 100;\n bytes memory data = hex\"ff\";\n uint256 nonce = messagePasser.messageNonce();\n\n // EOA emulation\n vm.prank(alice, alice);\n vm.deal(alice, 2**64);\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data)\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash);\n\n messagePasser.initiateWithdrawal{ value: value }(target, gasLimit, data);\n\n // the sent messages mapping is filled\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n // the nonce increments\n assertEq(nonce + 1, messagePasser.messageNonce());\n }\n\n // Test: burn should destroy the ETH held in the contract\n function test_burn_succeeds() external {\n messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n NON_ZERO_GASLIMIT,\n NON_ZERO_DATA\n );\n\n assertEq(address(messagePasser).balance, NON_ZERO_VALUE);\n vm.expectEmit(true, false, false, false);\n emit WithdrawerBalanceBurnt(NON_ZERO_VALUE);\n messagePasser.burn();\n\n // The Withdrawer should have no balance\n assertEq(address(messagePasser).balance, 0);\n }\n}\n" - }, - "contracts/test/LegacyERC20ETH.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyERC20ETH_Test is CommonTest {\n LegacyERC20ETH eth;\n\n function setUp() public virtual override {\n super.setUp();\n eth = new LegacyERC20ETH();\n }\n\n function test_metadata_succeeds() external {\n assertEq(eth.name(), \"Ether\");\n assertEq(eth.symbol(), \"ETH\");\n assertEq(eth.decimals(), 18);\n }\n\n function test_crossDomain_succeeds() external {\n assertEq(eth.l2Bridge(), Predeploys.L2_STANDARD_BRIDGE);\n assertEq(eth.l1Token(), address(0));\n }\n\n function test_transfer_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transfer is disabled\");\n eth.transfer(alice, 100);\n }\n\n function test_approve_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: approve is disabled\");\n eth.approve(alice, 100);\n }\n\n function test_transferFrom_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transferFrom is disabled\");\n eth.transferFrom(bob, alice, 100);\n }\n\n function test_increaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n eth.increaseAllowance(alice, 100);\n }\n\n function test_decreaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n eth.decreaseAllowance(alice, 100);\n }\n\n function test_mint_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: mint is disabled\");\n eth.mint(alice, 100);\n }\n\n function test_burn_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: burn is disabled\");\n eth.burn(alice, 100);\n }\n}\n" - }, - "contracts/test/LegacyMessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyMessagePasser } from \"../legacy/LegacyMessagePasser.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyMessagePasser_Test is CommonTest {\n LegacyMessagePasser messagePasser;\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new LegacyMessagePasser();\n }\n\n function test_passMessageToL1_succeeds() external {\n vm.prank(alice);\n messagePasser.passMessageToL1(hex\"ff\");\n assert(messagePasser.sentMessages(keccak256(abi.encodePacked(hex\"ff\", alice))));\n }\n}\n" - }, - "contracts/test/MerkleTrie.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MerkleTrie } from \"../libraries/trie/MerkleTrie.sol\";\n\ncontract MerkleTrie_get_Test is CommonTest {\n function test_get_validProof1_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579326262\";\n bytes memory val = hex\"6176616c32\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof2_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[\n 2\n ] = hex\"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof3_succeeds() external {\n bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof4_succeeds() external {\n bytes32 root = 0x37956bab6bba472308146808d5311ac19cb4a7daae5df7efcc0f32badc97f55e;\n bytes memory key = hex\"6b6579316161\";\n bytes memory val = hex\"3031323334\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"ce87206b6579316161853031323334\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof5_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657931\";\n bytes\n memory val = hex\"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof6_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657932\";\n bytes memory val = hex\"73686f7274\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[2] = hex\"df808080808080c9823262856176616c338080808080808080808573686f7274\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof7_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657933\";\n bytes memory val = hex\"31323334353637383930313233343536373839303132333435363738393031\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof8_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"61\";\n bytes memory val = hex\"61\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22061\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof9_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"62\";\n bytes memory val = hex\"62\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22062\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof10_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"63\";\n bytes memory val = hex\"63\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22063\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_nonexistentKey1_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b657932\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_nonexistentKey2_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"616e7972616e646f6d6b6579\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_wrongKeyProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579316161\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[2] = hex\"d687206e6f746865728d33343938683472697568677765\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_corruptedProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579326262\";\n bytes[] memory proof = new bytes[](5);\n proof[0] = hex\"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[\n 2\n ] = hex\"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 3\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[4] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidDataRemainder_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa000000000000000000000000000000\";\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidInternalNodeHash_reverts() external {\n bytes32 root = 0xa827dff1a657bb9bb9a1c3abe9db173e2f1359f15eb06f1647ea21ac7c95d8fa;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157\";\n proof[\n 1\n ] = hex\"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080\";\n proof[2] = hex\"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroBranchValueLength_reverts() external {\n bytes32 root = 0xe04b3589eef96b237cd49ccb5dcf6e654a47682bfa0961d563ab843f7ad1e035;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](2);\n proof[0] = hex\"dd8200aad98080808080808080808080c43b82aabbc43c82aacc80808080\";\n proof[1] = hex\"d98080808080808080808080c43b82aabbc43c82aacc80808080\";\n\n vm.expectRevert(\"MerkleTrie: value length must be greater than zero (branch)\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroLengthKey_reverts() external {\n bytes32 root = 0x54157fd62cdf2f474e7bfec2d3cd581e807bee38488c9590cb887add98936b73;\n bytes memory key = hex\"\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"c78320f00082b443\";\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey1_reverts() external {\n bytes32 root = 0xa513ba530659356fb7588a2c831944e80fd8aedaa5a4dc36f918152be2be0605;\n bytes memory key = hex\"01\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"db10d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[1] = hex\"d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[2] = hex\"c582202381aa\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey2_reverts() external {\n bytes32 root = 0xa06abffaec4ebe8ccde595f4547b864b4421b21c1fc699973f94710c9bc17979;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905\";\n proof[\n 1\n ] = hex\"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080\";\n proof[2] = hex\"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_extraProofElements_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](4);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa\";\n proof[3] = hex\"c32081aa\";\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_validProofs_succeeds(bytes4) external {\n // Generate a test case with a valid proof of inclusion for the k/v pair in the trie.\n (bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi\n .getMerkleTrieFuzzCase(\"valid\");\n\n // Assert that our expected value is equal to our actual value.\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidRoot_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"valid\"\n );\n\n bytes32 rootHash = keccak256(abi.encodePacked(root));\n vm.expectRevert(\"MerkleTrie: invalid root hash\");\n MerkleTrie.get(key, proof, rootHash);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_extraProofElements_reverts(bytes4) external {\n // Generate an invalid test case with an extra proof element attached to an otherwise\n // valid proof of inclusion for the passed k/v.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"extra_proof_elems\"\n );\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external {\n // Generate an invalid test case where a long proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_large_internal_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid large internal hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external {\n // Generate an invalid test case where a small proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_internal_node_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_corruptedProof_reverts(bytes4) external {\n // Generate an invalid test case where the proof is malformed.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"corrupted_proof\"\n );\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidDataRemainder_reverts(bytes4) external {\n // Generate an invalid test case where a random element of the proof has more bytes than the\n // length designates within the RLP list encoding.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_data_remainder\"\n );\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_prefixedValidKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and a valid key that is prefixed\n // with random bytes\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"prefixed_valid_key\"\n );\n\n // Ambiguous revert check- all that we care is that it *does* fail. This case may\n // fail within different branches.\n vm.expectRevert();\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_emptyKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and an empty key\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"empty_key\"\n );\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_partialProof_reverts(bytes4) external {\n // Get a random test case with a valid trie / partially correct proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"partial_proof\"\n );\n\n vm.expectRevert(\"MerkleTrie: ran out of proof elements\");\n MerkleTrie.get(key, proof, root);\n }\n}\n" - }, - "contracts/test/MintManager.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MintManager } from \"../governance/MintManager.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract MintManager_Initializer is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n MintManager internal manager;\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.prank(owner);\n gov = new GovernanceToken();\n\n vm.prank(owner);\n manager = new MintManager(owner, address(gov));\n\n vm.prank(owner);\n gov.transferOwnership(address(manager));\n }\n}\n\ncontract MintManager_constructor_Test is MintManager_Initializer {\n /**\n * @notice Tests that the constructor properly configures the contract.\n */\n function test_constructor_succeeds() external {\n assertEq(manager.owner(), owner);\n assertEq(address(manager.governanceToken()), address(gov));\n }\n}\n\ncontract MintManager_mint_Test is MintManager_Initializer {\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner.\n */\n function test_mint_fromOwner_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the mint function reverts when called by a non-owner.\n */\n function test_mint_fromNotOwner_reverts() external {\n // Mint from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.mint(owner, 100);\n }\n\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner a second\n * time after the mint period has elapsed.\n */\n function test_mint_afterPeriodElapsed_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again after period elapsed (2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n manager.mint(owner, 2);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 102);\n }\n\n /**\n * @notice Tests that the mint function always reverts when called before the mint period has\n * elapsed, even if the caller is the owner.\n */\n function test_mint_beforePeriodElapsed_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: minting not permitted yet\");\n manager.mint(owner, 100);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the owner cannot mint more than the mint cap.\n */\n function test_mint_moreThanCap_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again (greater than 2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint amount exceeds cap\");\n manager.mint(owner, 3);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n}\n\ncontract MintManager_upgrade_Test is MintManager_Initializer {\n /**\n * @notice Tests that the owner can upgrade the mint manager.\n */\n function test_upgrade_fromOwner_succeeds() external {\n // Upgrade to new manager.\n vm.prank(owner);\n manager.upgrade(rando);\n\n // New manager is rando.\n assertEq(gov.owner(), rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when called by a non-owner.\n */\n function test_upgrade_fromNotOwner_reverts() external {\n // Upgrade from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.upgrade(rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when attempting to update to the zero\n * address, even if the caller is the owner.\n */\n function test_upgrade_toZeroAddress_reverts() external {\n // Upgrade to zero address fails.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint manager cannot be the zero address\");\n manager.upgrade(address(0));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport {\n ILegacyMintableERC20,\n IOptimismMintableERC20\n} from \"../universal/IOptimismMintableERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract OptimismMintableERC20_Test is Bridge_Initializer {\n event Mint(address indexed account, uint256 amount);\n event Burn(address indexed account, uint256 amount);\n\n function test_semver_succeeds() external {\n assertEq(L2Token.version(), \"1.0.0\");\n }\n\n function test_remoteToken_succeeds() external {\n assertEq(L2Token.remoteToken(), address(L1Token));\n }\n\n function test_bridge_succeeds() external {\n assertEq(L2Token.bridge(), address(L2Bridge));\n }\n\n function test_l1Token_succeeds() external {\n assertEq(L2Token.l1Token(), address(L1Token));\n }\n\n function test_l2Bridge_succeeds() external {\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_legacy_succeeds() external {\n // Getters for the remote token\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.l1Token(), address(L1Token));\n // Getters for the bridge\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_mint_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 100);\n }\n\n function test_mint_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.mint(alice, 100);\n }\n\n function test_burn_succeeds() external {\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_burn_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.burn(alice, 100);\n }\n\n function test_erc165_supportsInterface_succeeds() external {\n // The assertEq calls in this test are comparing the manual calculation of the iface,\n // with what is returned by the solidity's type().interfaceId, just to be safe.\n bytes4 iface1 = bytes4(keccak256(\"supportsInterface(bytes4)\"));\n assertEq(iface1, type(IERC165).interfaceId);\n assert(L2Token.supportsInterface(iface1));\n\n bytes4 iface2 = L2Token.l1Token.selector ^ L2Token.mint.selector ^ L2Token.burn.selector;\n assertEq(iface2, type(ILegacyMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface2));\n\n bytes4 iface3 = L2Token.remoteToken.selector ^\n L2Token.bridge.selector ^\n L2Token.mint.selector ^\n L2Token.burn.selector;\n assertEq(iface3, type(IOptimismMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface3));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\n\ncontract OptimismMintableTokenFactory_Test is Bridge_Initializer {\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_bridge_succeeds() external {\n assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge));\n }\n\n function test_createStandardL2Token_succeeds() external {\n address remote = address(4);\n address local = LibRLP.computeAddress(address(L2TokenFactory), 2);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_sameTwice_succeeds() external {\n address remote = address(4);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n\n address local = LibRLP.computeAddress(address(L2TokenFactory), 3);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_remoteIsZero_succeeds() external {\n address remote = address(0);\n vm.expectRevert(\"OptimismMintableERC20Factory: must provide remote token address\");\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721, IERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport {\n OptimismMintableERC721,\n IOptimismMintableERC721\n} from \"../universal/OptimismMintableERC721.sol\";\n\ncontract OptimismMintableERC721_Test is ERC721Bridge_Initializer {\n ERC721 internal L1Token;\n OptimismMintableERC721 internal L2Token;\n\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n event Mint(address indexed account, uint256 tokenId);\n\n event Burn(address indexed account, uint256 tokenId);\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n L1Token = new ERC721(\"L1Token\", \"L1T\");\n L2Token = new OptimismMintableERC721(\n address(L2Bridge),\n 1,\n address(L1Token),\n \"L2Token\",\n \"L2T\"\n );\n\n // Label the addresses for nice traces.\n vm.label(address(L1Token), \"L1ERC721Token\");\n vm.label(address(L2Token), \"L2ERC721Token\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(L2Token.name(), \"L2Token\");\n assertEq(L2Token.symbol(), \"L2T\");\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.remoteChainId(), 1);\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.REMOTE_CHAIN_ID(), 1);\n assertEq(L2Token.version(), \"1.1.0\");\n }\n\n /**\n * @notice Ensure that the contract supports the expected interfaces.\n */\n function test_supportsInterfaces_succeeds() external {\n // Checks if the contract supports the IOptimismMintableERC721 interface.\n assertTrue(L2Token.supportsInterface(type(IOptimismMintableERC721).interfaceId));\n // Checks if the contract supports the IERC721Enumerable interface.\n assertTrue(L2Token.supportsInterface(type(IERC721Enumerable).interfaceId));\n // Checks if the contract supports the IERC721 interface.\n assertTrue(L2Token.supportsInterface(type(IERC721).interfaceId));\n // Checks if the contract supports the IERC165 interface.\n assertTrue(L2Token.supportsInterface(type(IERC165).interfaceId));\n }\n\n function test_safeMint_succeeds() external {\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(address(0), alice, 1);\n\n // Expect a mint event.\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 1);\n\n // Mint the token.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token should be owned by alice.\n assertEq(L2Token.ownerOf(1), alice);\n }\n\n function test_safeMint_notBridge_reverts() external {\n // Try to mint the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.safeMint(alice, 1);\n }\n\n function test_burn_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(alice, address(0), 1);\n\n // Expect a burn event.\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 1);\n\n // Burn the token.\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 1);\n\n // Token should be owned by address(0).\n vm.expectRevert(\"ERC721: invalid token ID\");\n L2Token.ownerOf(1);\n }\n\n function test_burn_notBridge_reverts() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Try to burn the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.burn(alice, 1);\n }\n\n function test_tokenURI_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token URI should be correct.\n assertEq(\n L2Token.tokenURI(1),\n string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(address(L1Token)), 20),\n \"@\",\n Strings.toString(1),\n \"/tokenURI?uint256=\",\n Strings.toString(1)\n )\n )\n );\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\n\ncontract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {\n OptimismMintableERC721Factory internal factory;\n\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n factory = new OptimismMintableERC721Factory(address(L2Bridge), 1);\n\n // Label the addresses for nice traces.\n vm.label(address(factory), \"OptimismMintableERC721Factory\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(factory.BRIDGE(), address(L2Bridge));\n assertEq(factory.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_succeeds() external {\n // Predict the address based on the factory address and nonce.\n address predicted = LibRLP.computeAddress(address(factory), 1);\n\n // Expect a token creation event.\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC721Created(predicted, address(1234), alice);\n\n // Create the token.\n vm.prank(alice);\n OptimismMintableERC721 created = OptimismMintableERC721(\n factory.createOptimismMintableERC721(address(1234), \"L2Token\", \"L2T\")\n );\n\n // Token address should be correct.\n assertEq(address(created), predicted);\n\n // Should be marked as created by the factory.\n assertEq(factory.isOptimismMintableERC721(address(created)), true);\n\n // Token should've been constructed correctly.\n assertEq(created.name(), \"L2Token\");\n assertEq(created.symbol(), \"L2T\");\n assertEq(created.REMOTE_TOKEN(), address(1234));\n assertEq(created.BRIDGE(), address(L2Bridge));\n assertEq(created.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_zeroRemoteToken_reverts() external {\n // Try to create a token with a zero remote token address.\n vm.expectRevert(\"OptimismMintableERC721Factory: L1 token address cannot be address(0)\");\n factory.createOptimismMintableERC721(address(0), \"L2Token\", \"L2T\");\n }\n}\n" - }, - "contracts/test/OptimismPortal.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { Portal_Initializer, CommonTest, NextImpl } from \"./CommonTest.t.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\ncontract OptimismPortal_Test is Portal_Initializer {\n event Paused(address);\n event Unpaused(address);\n\n function test_constructor_succeeds() external {\n assertEq(address(op.L2_ORACLE()), address(oracle));\n assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD);\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be paused by the GUARDIAN\n */\n function test_pause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n assertEq(op.paused(), false);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Paused(guardian);\n\n vm.prank(guardian);\n op.pause();\n\n assertEq(op.paused(), true);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not the\n * GUARDIAN calls `pause()`\n */\n function test_pause_onlyGuardian_reverts() external {\n assertEq(op.paused(), false);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can pause\");\n vm.prank(alice);\n op.pause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be unpaused by the GUARDIAN\n */\n function test_unpause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Unpaused(guardian);\n vm.prank(guardian);\n op.unpause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not\n * the GUARDIAN calls `unpause()`\n */\n function test_unpause_onlyGuardian_reverts() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can unpause\");\n vm.prank(alice);\n op.unpause();\n\n assertEq(op.paused(), true);\n }\n\n function test_receive_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex\"\");\n\n // give alice money and send as an eoa\n vm.deal(alice, 2**64);\n vm.prank(alice, alice);\n (bool s, ) = address(op).call{ value: 100 }(hex\"\");\n\n assert(s);\n assertEq(address(op).balance, 100);\n }\n\n // Test: depositTransaction fails when contract creation has a non-zero destination address\n function test_depositTransaction_contractCreation_reverts() external {\n // contract creation must have a target of address(0)\n vm.expectRevert(\"OptimismPortal: must send to address(0) when creating a contract\");\n op.depositTransaction(address(1), 1, 0, true, hex\"\");\n }\n\n /**\n * @notice Prevent deposits from being too large to have a sane upper bound\n * on unsafe blocks sent over the p2p network.\n */\n function test_depositTransaction_largeData_reverts() external {\n uint256 size = 120_001;\n uint64 gasLimit = op.minimumGasLimit(uint64(size));\n vm.expectRevert(\"OptimismPortal: data too large\");\n op.depositTransaction({\n _to: address(0),\n _value: 0,\n _gasLimit: gasLimit,\n _isCreation: false,\n _data: new bytes(size)\n });\n }\n\n /**\n * @notice Prevent gasless deposits from being force processed in L2 by\n * ensuring that they have a large enough gas limit set.\n */\n function test_depositTransaction_smallGasLimit_reverts() external {\n vm.expectRevert(\"OptimismPortal: gas limit too small\");\n op.depositTransaction({\n _to: address(1),\n _value: 0,\n _gasLimit: 0,\n _isCreation: false,\n _data: hex\"\"\n });\n }\n\n /**\n * @notice Fuzz for too small of gas limits\n */\n function testFuzz_depositTransaction_smallGasLimit_succeeds(\n bytes memory _data,\n bool _shouldFail\n ) external {\n vm.assume(_data.length <= type(uint64).max);\n\n uint64 gasLimit = op.minimumGasLimit(uint64(_data.length));\n if (_shouldFail) {\n gasLimit = uint64(bound(gasLimit, 0, gasLimit - 1));\n vm.expectRevert(\"OptimismPortal: gas limit too small\");\n }\n\n op.depositTransaction({\n _to: address(0x40),\n _value: 0,\n _gasLimit: gasLimit,\n _isCreation: false,\n _data: _data\n });\n }\n\n /**\n * @notice Ensure that the 0 calldata case is covered and there is a linearly\n * increasing gas limit for larger calldata sizes.\n */\n function test_minimumGasLimit_succeeds() external {\n assertEq(op.minimumGasLimit(0), 21_000);\n assertTrue(op.minimumGasLimit(2) > op.minimumGasLimit(1));\n assertTrue(op.minimumGasLimit(3) > op.minimumGasLimit(2));\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a tx with 0 value\n function test_depositTransaction_noValueEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a tx with 0 value\n function test_depositTransaction_noValueContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndContractContractCreation_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n function test_simple_isOutputFinalized_succeeds() external {\n uint256 ts = block.timestamp;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))\n )\n );\n\n // warp to the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS());\n assertEq(op.isOutputFinalized(0), false);\n\n // warp past the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n assertEq(op.isOutputFinalized(0), true);\n }\n\n function test_isOutputFinalized_succeeds() external {\n uint256 checkpoint = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n vm.roll(checkpoint);\n vm.warp(oracle.computeL2Timestamp(checkpoint) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0);\n\n // warp to the final second of the finalization period\n uint256 finalizationHorizon = block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS();\n vm.warp(finalizationHorizon);\n // The checkpointed block should not be finalized until 1 second from now.\n assertEq(op.isOutputFinalized(nextOutputIndex), false);\n // Nor should a block after it\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n\n // warp past the finalization period\n vm.warp(finalizationHorizon + 1);\n // It should now be finalized.\n assertEq(op.isOutputFinalized(nextOutputIndex), true);\n // But not the block after it.\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n }\n}\n\ncontract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n // Utility function used in the subsequent test. This is necessary to assert that the\n // reentrant call will revert.\n function callPortalAndExpectRevert() external payable {\n vm.expectRevert(\"OptimismPortal: can only trigger one withdrawal per transaction\");\n // Arguments here don't matter, as the require check is the first thing that happens.\n // We assume that this has already been proven.\n op.finalizeWithdrawalTransaction(_defaultTx);\n // Assert that the withdrawal was not finalized.\n assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));\n }\n\n /**\n * @notice Proving withdrawal transactions should revert when paused\n */\n function test_proveWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.proveWithdrawalTransaction({\n _tx: _defaultTx,\n _l2OutputIndex: _proposedOutputIndex,\n _outputRootProof: _outputRootProof,\n _withdrawalProof: _withdrawalProof\n });\n }\n\n // Test: proveWithdrawalTransaction cannot prove a withdrawal with itself (the OptimismPortal) as the target.\n function test_proveWithdrawalTransaction_onSelfCall_reverts() external {\n _defaultTx.target = address(op);\n vm.expectRevert(\"OptimismPortal: you cannot send messages to the portal contract\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the outputRootProof does not match the output root\n function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external {\n // Modify the version to invalidate the withdrawal proof.\n _outputRootProof.version = bytes32(uint256(1));\n vm.expectRevert(\"OptimismPortal: invalid output root proof\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the proof is invalid due to non-existence of\n // the withdrawal.\n function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external {\n // modify the default test values to invalidate the proof.\n _defaultTx.data = hex\"abcd\";\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the passed transaction's withdrawalHash has\n // already been proven.\n function test_proveWithdrawalTransaction_replayProve_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: withdrawal hash has already been proven\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root has changed AND the l2BlockNumber stays the same.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in the OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a different output root within the `provenWithdrawals` mapping without\n // touching the l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root + output index + l2BlockNumber changes.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds()\n external\n {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a dummy output root within the `provenWithdrawals` mapping without touching the\n // l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle\n Types.OutputProposal memory proposal = op.L2_ORACLE().getL2Output(_proposedOutputIndex);\n\n // Propose the same output root again, creating the same output at a different index + l2BlockNumber.\n vm.startPrank(op.L2_ORACLE().PROPOSER());\n op.L2_ORACLE().proposeL2Output(\n proposal.outputRoot,\n op.L2_ORACLE().nextBlockNumber(),\n blockhash(block.number),\n block.number\n );\n vm.stopPrank();\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot + a different output index\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex + 1,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds and emits the WithdrawalProven event.\n function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: finalizeWithdrawalTransaction succeeds and emits the WithdrawalFinalized event.\n function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, false, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore + 100);\n }\n\n /**\n * @notice Finalizing withdrawal transactions should revert when paused\n */\n function test_finalizeWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has not been proven.\n function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectRevert(\"OptimismPortal: withdrawal has not been proven yet\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if withdrawal not proven long enough ago.\n function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Mock a call where the resulting output root is anything but the original output root. In\n // this case we just use bytes32(uint256(1)).\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(bytes32(uint256(1)), _proposedBlockNumber)\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the provenWithdrawal's timestamp is less\n // than the L2 output oracle's starting timestamp\n function test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a startingTimestamp change on the L2 Oracle\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSignature(\"startingTimestamp()\"),\n abi.encode(block.timestamp + 1)\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output root proven is not the same as the\n // output root at the time of finalization.\n function test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock an outputRoot change on the output proposal before attempting\n // to finalize the withdrawal.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n bytes32(uint256(0)),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output proposal's timestamp has\n // not passed the finalization period.\n function test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a timestamp change on the output proposal that has not passed the\n // finalization period.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(block.timestamp + 1),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\"OptimismPortal: output proposal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction fails because the target reverts,\n // and emits the WithdrawalFinalized event with success=false.\n function test_finalizeWithdrawalTransaction_targetFails_fails() external {\n uint256 bobBalanceBefore = address(bob).balance;\n vm.etch(bob, hex\"fe\"); // Contract with just the invalid opcode.\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, false);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the finalization period has not yet passed.\n function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external {\n // Setup the Oracle to return an output with a recent timestamp\n uint256 recentTimestamp = block.timestamp - 1000;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(recentTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has already been finalized.\n function test_finalizeWithdrawalTransaction_onReplay_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if insufficient gas is supplied.\n function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external {\n // This number was identified through trial and error.\n uint256 gasLimit = 150_000;\n Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: gasLimit,\n data: hex\"\"\n });\n\n // Get updated proof inputs.\n (bytes32 stateRoot, bytes32 storageRoot, , , bytes[] memory withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(insufficientGasTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n Hashing.hashOutputRootProof(outputRootProof),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n insufficientGasTx,\n _proposedOutputIndex,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectRevert(\"SafeCall: Not enough gas\");\n op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if a sub-call attempts to finalize another\n // withdrawal.\n function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Copy and modify the default test values to attempt a reentrant call by first calling to\n // this contract's callPortalAndExpectRevert() function above.\n Types.WithdrawalTransaction memory _testTx = _defaultTx;\n _testTx.target = address(this);\n _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector);\n\n // Get modified proof inputs.\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_testTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp.\n uint256 finalizedTimestamp = block.timestamp - oracle.FINALIZATION_PERIOD_SECONDS() - 1;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n outputRoot,\n uint128(finalizedTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(withdrawalHash, alice, address(this));\n op.proveWithdrawalTransaction(\n _testTx,\n _proposedBlockNumber,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectCall(address(this), _testTx.data);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_testTx);\n\n // Ensure that bob's balance was not changed by the reentrant call.\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n function testDiff_finalizeWithdrawalTransaction_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n vm.assume(\n _target != address(op) && // Cannot call the optimism portal or a contract\n _target.code.length == 0 && // No accounts with code\n _target != CONSOLE && // The console has no code but behaves like a contract\n uint160(_target) > 9 // No precompiles (or zero address)\n );\n\n // Total ETH supply is currently about 120M ETH.\n uint256 value = bound(_value, 0, 200_000_000 ether);\n vm.deal(address(op), value);\n\n uint256 gasLimit = bound(_gasLimit, 0, 50_000_000);\n uint256 nonce = messagePasser.messageNonce();\n\n // Get a withdrawal transaction and mock proof from the differential testing script.\n Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: value,\n gasLimit: gasLimit,\n data: _data\n });\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_tx);\n\n // Create the output root proof\n Types.OutputRootProof memory proof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n\n // Ensure the values returned from ffi are correct\n assertEq(outputRoot, Hashing.hashOutputRootProof(proof));\n assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx));\n\n // Setup the Oracle to return the outputRoot\n vm.mockCall(\n address(oracle),\n abi.encodeWithSelector(oracle.getL2Output.selector),\n abi.encode(outputRoot, block.timestamp, 100)\n );\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _tx,\n 100, // l2BlockNumber\n proof,\n withdrawalProof\n );\n (bytes32 _root, , ) = op.provenWithdrawals(withdrawalHash);\n assertTrue(_root != bytes32(0));\n\n // Warp past the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Finalize the withdrawal transaction\n vm.expectCallMinGas(_tx.target, _tx.value, uint64(_tx.gasLimit), _tx.data);\n op.finalizeWithdrawalTransaction(_tx);\n assertTrue(op.finalizedWithdrawals(withdrawalHash));\n }\n}\n\ncontract OptimismPortalUpgradeable_Test is Portal_Initializer {\n Proxy internal proxy;\n uint64 initialBlockNum;\n\n function setUp() public override {\n super.setUp();\n initialBlockNum = uint64(block.number);\n proxy = Proxy(payable(address(op)));\n }\n\n function test_params_initValuesOnProxy_succeeds() external {\n OptimismPortal p = OptimismPortal(payable(address(proxy)));\n\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = p.params();\n\n ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig();\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_initialize_cannotInitProxy_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(payable(proxy)).initialize(false);\n }\n\n function test_initialize_cannotInitImpl_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(opImpl).initialize(false);\n }\n\n function test_upgradeToAndCall_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(op), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(op)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n\n/**\n * @title OptimismPortalResourceFuzz_Test\n * @dev Test various values of the resource metering config to ensure that deposits cannot be\n * broken by changing the config.\n */\ncontract OptimismPortalResourceFuzz_Test is Portal_Initializer {\n /**\n * @dev The max gas limit observed throughout this test. Setting this too high can cause\n * the test to take too long to run.\n */\n uint256 constant MAX_GAS_LIMIT = 30_000_000;\n\n /**\n * @dev Test that various values of the resource metering config will not break deposits.\n */\n function testFuzz_systemConfigDeposit_succeeds(\n uint32 _maxResourceLimit,\n uint8 _elasticityMultiplier,\n uint8 _baseFeeMaxChangeDenominator,\n uint32 _minimumBaseFee,\n uint32 _systemTxMaxGas,\n uint128 _maximumBaseFee,\n uint64 _gasLimit,\n uint64 _prevBoughtGas,\n uint128 _prevBaseFee,\n uint8 _blockDiff\n ) external {\n // Get the set system gas limit\n uint64 gasLimit = systemConfig.gasLimit();\n // Bound resource config\n _maxResourceLimit = uint32(bound(_maxResourceLimit, 21000, MAX_GAS_LIMIT / 8));\n _gasLimit = uint64(bound(_gasLimit, 21000, _maxResourceLimit));\n _prevBaseFee = uint128(bound(_prevBaseFee, 0, 3 gwei));\n // Prevent values that would cause reverts\n vm.assume(gasLimit >= _gasLimit);\n vm.assume(_minimumBaseFee < _maximumBaseFee);\n vm.assume(_baseFeeMaxChangeDenominator > 1);\n vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit);\n vm.assume(_elasticityMultiplier > 0);\n vm.assume(\n ((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) ==\n _maxResourceLimit\n );\n _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit));\n _blockDiff = uint8(bound(_blockDiff, 0, 3));\n\n // Create a resource config to mock the call to the system config with\n ResourceMetering.ResourceConfig memory rcfg = ResourceMetering.ResourceConfig({\n maxResourceLimit: _maxResourceLimit,\n elasticityMultiplier: _elasticityMultiplier,\n baseFeeMaxChangeDenominator: _baseFeeMaxChangeDenominator,\n minimumBaseFee: _minimumBaseFee,\n systemTxMaxGas: _systemTxMaxGas,\n maximumBaseFee: _maximumBaseFee\n });\n vm.mockCall(\n address(systemConfig),\n abi.encodeWithSelector(systemConfig.resourceConfig.selector),\n abi.encode(rcfg)\n );\n\n // Set the resource params\n uint256 _prevBlockNum = block.number - _blockDiff;\n vm.store(\n address(op),\n bytes32(uint256(1)),\n bytes32((_prevBlockNum << 192) | (uint256(_prevBoughtGas) << 128) | _prevBaseFee)\n );\n // Ensure that the storage setting is correct\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = op.params();\n assertEq(prevBaseFee, _prevBaseFee);\n assertEq(prevBoughtGas, _prevBoughtGas);\n assertEq(prevBlockNum, _prevBlockNum);\n\n // Do a deposit, should not revert\n op.depositTransaction{ gas: MAX_GAS_LIMIT }({\n _to: address(0x20),\n _value: 0x40,\n _gasLimit: _gasLimit,\n _isCreation: false,\n _data: hex\"\"\n });\n }\n}\n" - }, - "contracts/test/Proxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract SimpleStorage {\n mapping(uint256 => uint256) internal store;\n\n function get(uint256 key) external payable returns (uint256) {\n return store[key];\n }\n\n function set(uint256 key, uint256 value) external payable {\n store[key] = value;\n }\n}\n\ncontract Clasher {\n function upgradeTo(address) external pure {\n revert(\"upgradeTo\");\n }\n}\n\ncontract Proxy_Test is Test {\n event Upgraded(address indexed implementation);\n event AdminChanged(address previousAdmin, address newAdmin);\n\n address alice = address(64);\n\n bytes32 internal constant IMPLEMENTATION_KEY =\n bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1);\n\n bytes32 internal constant OWNER_KEY = bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1);\n\n Proxy proxy;\n SimpleStorage simpleStorage;\n\n function setUp() external {\n // Deploy a proxy and simple storage contract as\n // the implementation\n proxy = new Proxy(alice);\n simpleStorage = new SimpleStorage();\n\n vm.prank(alice);\n proxy.upgradeTo(address(simpleStorage));\n }\n\n function test_implementationKey_succeeds() external {\n // The hardcoded implementation key should be correct\n vm.prank(alice);\n proxy.upgradeTo(address(6));\n\n bytes32 key = vm.load(address(proxy), IMPLEMENTATION_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(6));\n }\n\n function test_ownerKey_succeeds() external {\n // The hardcoded owner key should be correct\n vm.prank(alice);\n proxy.changeAdmin(address(6));\n\n bytes32 key = vm.load(address(proxy), OWNER_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(address(6));\n address owner = proxy.admin();\n assertEq(owner, address(6));\n }\n\n function test_proxyCallToImp_notAdmin_succeeds() external {\n // The implementation does not have a `upgradeTo`\n // method, calling `upgradeTo` not as the owner\n // should revert.\n vm.expectRevert();\n proxy.upgradeTo(address(64));\n\n // Call `upgradeTo` as the owner, it should succeed\n // and emit the `Upgraded` event.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(64));\n vm.prank(alice);\n proxy.upgradeTo(address(64));\n\n // Get the implementation as the owner\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(64));\n }\n\n function test_ownerProxyCall_notAdmin_succeeds() external {\n // Calling `changeAdmin` not as the owner should revert\n // as the implementation does not have a `changeAdmin` method.\n vm.expectRevert();\n proxy.changeAdmin(address(1));\n\n // Call `changeAdmin` as the owner, it should succeed\n // and emit the `AdminChanged` event.\n vm.expectEmit(true, true, true, true);\n emit AdminChanged(alice, address(1));\n vm.prank(alice);\n proxy.changeAdmin(address(1));\n\n // Calling `admin` not as the owner should\n // revert as the implementation does not have\n // a `admin` method.\n vm.expectRevert();\n proxy.admin();\n\n // Calling `admin` as the owner should work.\n vm.prank(address(1));\n address owner = proxy.admin();\n assertEq(owner, address(1));\n }\n\n function test_delegatesToImpl_succeeds() external {\n // Call the storage setter on the proxy\n SimpleStorage(address(proxy)).set(1, 1);\n\n // The key should not be set in the implementation\n uint256 result = simpleStorage.get(1);\n assertEq(result, 0);\n {\n // The key should be set in the proxy\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n\n {\n // The owner should be able to call through the proxy\n // when there is not a function selector crash\n vm.prank(alice);\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n }\n\n function test_upgradeToAndCall_succeeds() external {\n {\n // There should be nothing in the current proxy storage\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 0);\n }\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(simpleStorage));\n vm.prank(alice);\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The call should have impacted the state\n uint256 result = SimpleStorage(address(proxy)).get(1);\n assertEq(result, 1);\n }\n\n function test_upgradeToAndCall_functionDoesNotExist_reverts() external {\n // Get the current implementation address\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call. This reverts because the calldata doesn't\n // match a function on the implementation.\n vm.expectRevert(\"Proxy: delegatecall to new implementation contract failed\");\n vm.prank(alice);\n proxy.upgradeToAndCall(address(simpleStorage), hex\"\");\n\n // The implementation address should have not\n // updated because the call to `upgradeToAndCall`\n // reverted.\n vm.prank(alice);\n address postImpl = proxy.implementation();\n assertEq(impl, postImpl);\n\n // The attempt to `upgradeToAndCall`\n // should revert when it is not called by the owner.\n vm.expectRevert();\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n }\n\n function test_upgradeToAndCall_isPayable_succeeds() external {\n // Give alice some funds\n vm.deal(alice, 1 ether);\n // Set the implementation and call and send\n // value.\n vm.prank(alice);\n proxy.upgradeToAndCall{ value: 1 ether }(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The implementation address should be correct\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // The proxy should have a balance\n assertEq(address(proxy).balance, 1 ether);\n }\n\n function test_upgradeTo_clashingFunctionSignatures_succeeds() external {\n // Clasher has a clashing function with the proxy.\n Clasher clasher = new Clasher();\n\n // Set the clasher as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(clasher));\n\n {\n // Assert that the implementation was set properly.\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(clasher));\n }\n\n // Call the clashing function on the proxy\n // not as the owner so that the call passes through.\n // The implementation will revert so we can be\n // sure that the call passed through.\n vm.expectRevert(bytes(\"upgradeTo\"));\n proxy.upgradeTo(address(0));\n\n {\n // Now call the clashing function as the owner\n // and be sure that it doesn't pass through to\n // the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(0));\n }\n }\n\n // Allow for `eth_call` to call proxy methods\n // by setting \"from\" to `address(0)`.\n function test_implementation_zeroAddressCaller_succeeds() external {\n vm.prank(address(0));\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n }\n\n function test_implementation_isZeroAddress_reverts() external {\n // Set `address(0)` as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n\n (bool success, bytes memory returndata) = address(proxy).call(hex\"\");\n assertEq(success, false);\n\n bytes memory err = abi.encodeWithSignature(\n \"Error(string)\",\n \"Proxy: implementation not initialized\"\n );\n\n assertEq(returndata, err);\n }\n}\n" - }, - "contracts/test/ProxyAdmin.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { SimpleStorage } from \"./Proxy.t.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\n\ncontract ProxyAdmin_Test is Test {\n address alice = address(64);\n\n Proxy proxy;\n L1ChugSplashProxy chugsplash;\n ResolvedDelegateProxy resolved;\n\n AddressManager addressManager;\n\n ProxyAdmin admin;\n\n SimpleStorage implementation;\n\n function setUp() external {\n // Deploy the proxy admin\n admin = new ProxyAdmin(alice);\n // Deploy the standard proxy\n proxy = new Proxy(address(admin));\n\n // Deploy the legacy L1ChugSplashProxy with the admin as the owner\n chugsplash = new L1ChugSplashProxy(address(admin));\n\n // Deploy the legacy AddressManager\n addressManager = new AddressManager();\n // The proxy admin must be the new owner of the address manager\n addressManager.transferOwnership(address(admin));\n // Deploy a legacy ResolvedDelegateProxy with the name `a`.\n // Whatever `a` is set to in AddressManager will be the address\n // that is used for the implementation.\n resolved = new ResolvedDelegateProxy(addressManager, \"a\");\n\n // Impersonate alice for setting up the admin.\n vm.startPrank(alice);\n // Set the address of the address manager in the admin so that it\n // can resolve the implementation address of legacy\n // ResolvedDelegateProxy based proxies.\n admin.setAddressManager(addressManager);\n // Set the reverse lookup of the ResolvedDelegateProxy\n // proxy\n admin.setImplementationName(address(resolved), \"a\");\n\n // Set the proxy types\n admin.setProxyType(address(proxy), ProxyAdmin.ProxyType.ERC1967);\n admin.setProxyType(address(chugsplash), ProxyAdmin.ProxyType.CHUGSPLASH);\n admin.setProxyType(address(resolved), ProxyAdmin.ProxyType.RESOLVED);\n vm.stopPrank();\n\n implementation = new SimpleStorage();\n }\n\n function test_setImplementationName_succeeds() external {\n vm.prank(alice);\n admin.setImplementationName(address(1), \"foo\");\n assertEq(admin.implementationName(address(1)), \"foo\");\n }\n\n function test_setAddressManager_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setAddressManager(AddressManager((address(0))));\n }\n\n function test_setImplementationName_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setImplementationName(address(0), \"foo\");\n }\n\n function test_setProxyType_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setProxyType(address(0), ProxyAdmin.ProxyType.CHUGSPLASH);\n }\n\n function test_owner_succeeds() external {\n assertEq(admin.owner(), alice);\n }\n\n function test_proxyType_succeeds() external {\n assertEq(uint256(admin.proxyType(address(proxy))), uint256(ProxyAdmin.ProxyType.ERC1967));\n assertEq(\n uint256(admin.proxyType(address(chugsplash))),\n uint256(ProxyAdmin.ProxyType.CHUGSPLASH)\n );\n assertEq(\n uint256(admin.proxyType(address(resolved))),\n uint256(ProxyAdmin.ProxyType.RESOLVED)\n );\n }\n\n function test_erc1967GetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(proxy));\n }\n\n function test_chugsplashGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(resolved));\n }\n\n function getProxyImplementation(address payable _proxy) internal {\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(0));\n }\n\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n }\n\n function test_erc1967GetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(resolved));\n }\n\n function getProxyAdmin(address payable _proxy) internal {\n address owner = admin.getProxyAdmin(_proxy);\n assertEq(owner, address(admin));\n }\n\n function test_erc1967ChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(resolved));\n }\n\n function changeProxyAdmin(address payable _proxy) internal {\n ProxyAdmin.ProxyType proxyType = admin.proxyType(address(_proxy));\n\n vm.prank(alice);\n admin.changeProxyAdmin(_proxy, address(128));\n\n // The proxy is no longer the admin and can\n // no longer call the proxy interface except for\n // the ResolvedDelegate type on which anybody can\n // call the admin interface.\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n vm.expectRevert(\"Proxy: implementation not initialized\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n vm.expectRevert(\"L1ChugSplashProxy: implementation is not set yet\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n // Just an empty block to show that all cases are covered\n } else {\n vm.expectRevert(\"ProxyAdmin: unknown proxy type\");\n }\n\n // Call the proxy contract directly to get the admin.\n // Different proxy types have different interfaces.\n vm.prank(address(128));\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n assertEq(Proxy(payable(_proxy)).admin(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n assertEq(L1ChugSplashProxy(payable(_proxy)).getOwner(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n assertEq(addressManager.owner(), address(128));\n } else {\n assert(false);\n }\n }\n\n function test_erc1967Upgrade_succeeds() external {\n upgrade(payable(proxy));\n }\n\n function test_chugsplashUpgrade_succeeds() external {\n upgrade(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgrade_succeeds() external {\n upgrade(payable(resolved));\n }\n\n function upgrade(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n\n function test_erc1967UpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(proxy));\n }\n\n function test_chugsplashUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(resolved));\n }\n\n function upgradeAndCall(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgradeAndCall(\n _proxy,\n address(implementation),\n abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1)\n );\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n\n uint256 got = SimpleStorage(address(_proxy)).get(1);\n assertEq(got, 1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.changeProxyAdmin(payable(proxy), address(0));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgrade(payable(proxy), address(implementation));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgradeAndCall(payable(proxy), address(implementation), hex\"\");\n }\n\n function test_isUpgrading_succeeds() external {\n assertEq(false, admin.isUpgrading());\n\n vm.prank(alice);\n admin.setUpgrading(true);\n assertEq(true, admin.isUpgrading());\n }\n}\n" - }, - "contracts/test/RLP.t.sol": { - "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\n/**\n * @title LibRLP\n * @notice Via https://github.com/Rari-Capital/solmate/issues/207.\n */\nlibrary LibRLP {\n using Bytes32AddressLib for bytes32;\n\n function computeAddress(address deployer, uint256 nonce) internal pure returns (address) {\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))\n .fromLast20Bytes();\n if (nonce <= 0x7f)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))\n .fromLast20Bytes();\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= type(uint8).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd7),\n bytes1(0x94),\n deployer,\n bytes1(0x81),\n uint8(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint16).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd8),\n bytes1(0x94),\n deployer,\n bytes1(0x82),\n uint16(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint24).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd9),\n bytes1(0x94),\n deployer,\n bytes1(0x83),\n uint24(nonce)\n )\n ).fromLast20Bytes();\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return\n keccak256(\n abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))\n ).fromLast20Bytes();\n }\n}\n" - }, - "contracts/test/RLPReader.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { RLPReader } from \"../libraries/rlp/RLPReader.sol\";\n\ncontract RLPReader_readBytes_Test is CommonTest {\n function test_readBytes_bytestring00_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"00\"), hex\"00\");\n }\n\n function test_readBytes_bytestring01_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"01\"), hex\"01\");\n }\n\n function test_readBytes_bytestring7f_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"7f\"), hex\"7f\");\n }\n\n function test_readBytes_revertListItem_reverts() external {\n vm.expectRevert(\"RLPReader: decoded item type for bytes is not a data item\");\n RLPReader.readBytes(hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_readBytes_invalidStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n RLPReader.readBytes(hex\"b9\");\n }\n\n function test_readBytes_invalidListLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n RLPReader.readBytes(hex\"ff\");\n }\n\n function test_readBytes_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: bytes value contains an invalid remainder\");\n RLPReader.readBytes(hex\"800a\");\n }\n\n function test_readBytes_invalidPrefix_reverts() external {\n vm.expectRevert(\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n RLPReader.readBytes(hex\"810a\");\n }\n}\n\ncontract RLPReader_readList_Test is CommonTest {\n function test_readList_empty_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c0\");\n assertEq(list.length, 0);\n }\n\n function test_readList_multiList_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c6827a77c10401\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"827a77\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c104\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"01\");\n }\n\n function test_readList_shortListMax1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n\n assertEq(list.length, 11);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[4]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[5]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[6]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[7]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[8]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[9]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[10]), hex\"8471776572\");\n }\n\n function test_readList_longList1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n\n assertEq(list.length, 4);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"cf84617364668471776572847a786376\");\n }\n\n function test_readList_longList2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n assertEq(list.length, 32);\n\n for (uint256 i = 0; i < 32; i++) {\n assertEq(RLPReader.readRawBytes(list[i]), hex\"cf84617364668471776572847a786376\");\n }\n }\n\n function test_readList_listLongerThan32Elements_reverts() external {\n vm.expectRevert(stdError.indexOOBError);\n RLPReader.readList(\n hex\"e1454545454545454545454545454545454545454545454545454545454545454545\"\n );\n }\n\n function test_readList_listOfLists_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c4c2c0c0c0\");\n assertEq(list.length, 2);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c2c0c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c0\");\n }\n\n function test_readList_listOfLists2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c7c0c1c0c3c0c1c0\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c1c0\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"c3c0c1c0\");\n }\n\n function test_readList_dictTest1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n assertEq(list.length, 4);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"ca846b6579318476616c31\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"ca846b6579328476616c32\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"ca846b6579338476616c33\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"ca846b6579348476616c34\");\n }\n\n function test_readList_invalidShortList_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efdebd\");\n }\n\n function test_readList_longStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efb83600\");\n }\n\n function test_readList_notLongEnough_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(\n hex\"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n );\n }\n\n function test_readList_int32Overflow_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"bf0f000000000000021111\");\n }\n\n function test_readList_int32Overflow2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ff0f000000000000021111\");\n }\n\n function test_readList_incorrectLengthInArray_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(hex\"b800\");\n }\n\n function test_readList_leadingZerosInLongLengthList1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must not have any leading zeros (long list)\");\n RLPReader.readList(\n hex\"fb00000040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_nonOptimalLongLengthArray1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b81000112233445566778899aabbccddeeff\");\n }\n\n function test_readList_nonOptimalLongLengthArray2_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b801ff\");\n }\n\n function test_readList_invalidValue_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n RLPReader.readList(hex\"91\");\n }\n\n function test_readList_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n RLPReader.readList(hex\"c000\");\n }\n\n function test_readList_notEnoughContentForString1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"ba010000aabbccddeeff\");\n }\n\n function test_readList_notEnoughContentForString2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"b840ffeeddccbbaa99887766554433221100\");\n }\n\n function test_readList_notEnoughContentForList1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"f90180\");\n }\n\n function test_readList_notEnoughContentForList2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ffffffffffffffffff0001020304050607\");\n }\n\n function test_readList_longStringLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b80100\");\n }\n\n function test_readList_longListLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long list)\");\n RLPReader.readList(hex\"f80100\");\n }\n}\n" - }, - "contracts/test/RLPWriter.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { RLPWriter } from \"../libraries/rlp/RLPWriter.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\n\ncontract RLPWriter_writeString_Test is CommonTest {\n function test_writeString_empty_succeeds() external {\n assertEq(RLPWriter.writeString(\"\"), hex\"80\");\n }\n\n function test_writeString_bytestring00_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0000\"), hex\"00\");\n }\n\n function test_writeString_bytestring01_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0001\"), hex\"01\");\n }\n\n function test_writeString_bytestring7f_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u007F\"), hex\"7f\");\n }\n\n function test_writeString_shortstring_succeeds() external {\n assertEq(RLPWriter.writeString(\"dog\"), hex\"83646f67\");\n }\n\n function test_writeString_shortstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing eli\"),\n hex\"b74c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69\"\n );\n }\n\n function test_writeString_longstring_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing elit\"),\n hex\"b8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974\"\n );\n }\n\n function test_writeString_longstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\n \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat\"\n ),\n hex\"b904004c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742e20437572616269747572206d6175726973206d61676e612c20737573636970697420736564207665686963756c61206e6f6e2c20696163756c697320666175636962757320746f72746f722e2050726f696e20737573636970697420756c74726963696573206d616c6573756164612e204475697320746f72746f7220656c69742c2064696374756d2071756973207472697374697175652065752c20756c7472696365732061742072697375732e204d6f72626920612065737420696d70657264696574206d6920756c6c616d636f7270657220616c6971756574207375736369706974206e6563206c6f72656d2e2041656e65616e2071756973206c656f206d6f6c6c69732c2076756c70757461746520656c6974207661726975732c20636f6e73657175617420656e696d2e204e756c6c6120756c74726963657320747572706973206a7573746f2c20657420706f73756572652075726e6120636f6e7365637465747572206e65632e2050726f696e206e6f6e20636f6e76616c6c6973206d657475732e20446f6e65632074656d706f7220697073756d20696e206d617572697320636f6e67756520736f6c6c696369747564696e2e20566573746962756c756d20616e746520697073756d207072696d697320696e206661756369627573206f726369206c756374757320657420756c74726963657320706f737565726520637562696c69612043757261653b2053757370656e646973736520636f6e76616c6c69732073656d2076656c206d617373612066617563696275732c2065676574206c6163696e6961206c616375732074656d706f722e204e756c6c61207175697320756c747269636965732070757275732e2050726f696e20617563746f722072686f6e637573206e69626820636f6e64696d656e74756d206d6f6c6c69732e20416c697175616d20636f6e73657175617420656e696d206174206d65747573206c75637475732c206120656c656966656e6420707572757320656765737461732e20437572616269747572206174206e696268206d657475732e204e616d20626962656e64756d2c206e6571756520617420617563746f72207472697374697175652c206c6f72656d206c696265726f20616c697175657420617263752c206e6f6e20696e74657264756d2074656c6c7573206c65637475732073697420616d65742065726f732e20437261732072686f6e6375732c206d65747573206163206f726e617265206375727375732c20646f6c6f72206a7573746f20756c747269636573206d657475732c20617420756c6c616d636f7270657220766f6c7574706174\"\n );\n }\n}\n\ncontract RLPWriter_writeUint_Test is CommonTest {\n function test_writeUint_zero_succeeds() external {\n assertEq(RLPWriter.writeUint(0x0), hex\"80\");\n }\n\n function test_writeUint_smallint_succeeds() external {\n assertEq(RLPWriter.writeUint(1), hex\"01\");\n }\n\n function test_writeUint_smallint2_succeeds() external {\n assertEq(RLPWriter.writeUint(16), hex\"10\");\n }\n\n function test_writeUint_smallint3_succeeds() external {\n assertEq(RLPWriter.writeUint(79), hex\"4f\");\n }\n\n function test_writeUint_smallint4_succeeds() external {\n assertEq(RLPWriter.writeUint(127), hex\"7f\");\n }\n\n function test_writeUint_mediumint_succeeds() external {\n assertEq(RLPWriter.writeUint(128), hex\"8180\");\n }\n\n function test_writeUint_mediumint2_succeeds() external {\n assertEq(RLPWriter.writeUint(1000), hex\"8203e8\");\n }\n\n function test_writeUint_mediumint3_succeeds() external {\n assertEq(RLPWriter.writeUint(100000), hex\"830186a0\");\n }\n}\n\ncontract RLPWriter_writeList_Test is CommonTest {\n function test_writeList_empty_succeeds() external {\n assertEq(RLPWriter.writeList(new bytes[](0)), hex\"c0\");\n }\n\n function test_writeList_stringList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeString(\"dog\");\n list[1] = RLPWriter.writeString(\"god\");\n list[2] = RLPWriter.writeString(\"cat\");\n\n assertEq(RLPWriter.writeList(list), hex\"cc83646f6783676f6483636174\");\n }\n\n function test_writeList_multiList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeUint(4);\n\n list[0] = RLPWriter.writeString(\"zw\");\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeUint(1);\n\n assertEq(RLPWriter.writeList(list), hex\"c6827a77c10401\");\n }\n\n function test_writeList_shortListMax1_succeeds() external {\n bytes[] memory list = new bytes[](11);\n list[0] = RLPWriter.writeString(\"asdf\");\n list[1] = RLPWriter.writeString(\"qwer\");\n list[2] = RLPWriter.writeString(\"zxcv\");\n list[3] = RLPWriter.writeString(\"asdf\");\n list[4] = RLPWriter.writeString(\"qwer\");\n list[5] = RLPWriter.writeString(\"zxcv\");\n list[6] = RLPWriter.writeString(\"asdf\");\n list[7] = RLPWriter.writeString(\"qwer\");\n list[8] = RLPWriter.writeString(\"zxcv\");\n list[9] = RLPWriter.writeString(\"asdf\");\n list[10] = RLPWriter.writeString(\"qwer\");\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n }\n\n function test_writeList_longlist1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list2);\n list[3] = RLPWriter.writeList(list2);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_longlist2_succeeds() external {\n bytes[] memory list = new bytes[](32);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n for (uint256 i = 0; i < 32; i++) {\n list[i] = RLPWriter.writeList(list2);\n }\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_listoflists_succeeds() external {\n // [ [ [], [] ], [] ]\n bytes[] memory list = new bytes[](2);\n bytes[] memory list2 = new bytes[](2);\n\n list2[0] = RLPWriter.writeList(new bytes[](0));\n list2[1] = RLPWriter.writeList(new bytes[](0));\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(new bytes[](0));\n\n assertEq(RLPWriter.writeList(list), hex\"c4c2c0c0c0\");\n }\n\n function test_writeList_listoflists2_succeeds() external {\n // [ [], [[]], [ [], [[]] ] ]\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeList(new bytes[](0));\n\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeList(new bytes[](0));\n\n list[1] = RLPWriter.writeList(list2);\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeList(new bytes[](0));\n list3[1] = RLPWriter.writeList(list2);\n\n list[2] = RLPWriter.writeList(list3);\n\n assertEq(RLPWriter.writeList(list), hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_writeList_dictTest1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n\n bytes[] memory list1 = new bytes[](2);\n list1[0] = RLPWriter.writeString(\"key1\");\n list1[1] = RLPWriter.writeString(\"val1\");\n\n bytes[] memory list2 = new bytes[](2);\n list2[0] = RLPWriter.writeString(\"key2\");\n list2[1] = RLPWriter.writeString(\"val2\");\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeString(\"key3\");\n list3[1] = RLPWriter.writeString(\"val3\");\n\n bytes[] memory list4 = new bytes[](2);\n list4[0] = RLPWriter.writeString(\"key4\");\n list4[1] = RLPWriter.writeString(\"val4\");\n\n list[0] = RLPWriter.writeList(list1);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list3);\n list[3] = RLPWriter.writeList(list4);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n }\n}\n" - }, - "contracts/test/ResolvedDelegateProxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\n\ncontract ResolvedDelegateProxy_Test is Test {\n AddressManager internal addressManager;\n SimpleImplementation internal impl;\n SimpleImplementation internal proxy;\n\n function setUp() public {\n // Set up the address manager.\n addressManager = new AddressManager();\n impl = new SimpleImplementation();\n addressManager.setAddress(\"SimpleImplementation\", address(impl));\n\n // Set up the proxy.\n proxy = SimpleImplementation(\n address(new ResolvedDelegateProxy(addressManager, \"SimpleImplementation\"))\n );\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall succeeds.\n function testFuzz_fallback_delegateCallFoo_succeeds(uint256 x) public {\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.foo.selector, x));\n assertEq(proxy.foo(x), x);\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall reverts.\n function test_fallback_delegateCallBar_reverts() public {\n vm.expectRevert(\"SimpleImplementation: revert\");\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.bar.selector));\n proxy.bar();\n }\n\n // Tests that the proxy fallback reverts as expected if the implementation within the\n // address manager is not set.\n function test_fallback_addressManagerNotSet_reverts() public {\n AddressManager am = new AddressManager();\n SimpleImplementation p = SimpleImplementation(\n address(new ResolvedDelegateProxy(am, \"SimpleImplementation\"))\n );\n\n vm.expectRevert(\"ResolvedDelegateProxy: target address must be initialized\");\n p.foo(0);\n }\n}\n\ncontract SimpleImplementation {\n function foo(uint256 _x) public pure returns (uint256) {\n return _x;\n }\n\n function bar() public pure {\n revert(\"SimpleImplementation: revert\");\n }\n}\n" - }, - "contracts/test/ResourceMetering.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract MeterUser is ResourceMetering {\n ResourceMetering.ResourceConfig public innerConfig;\n\n constructor() {\n initialize();\n innerConfig = Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function initialize() public initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public view returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n view\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return innerConfig;\n }\n\n function use(uint64 _amount) public metered(_amount) {}\n\n function set(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) public {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n\n function setParams(ResourceMetering.ResourceConfig memory newConfig) public {\n innerConfig = newConfig;\n }\n}\n\n/**\n * @title ResourceConfig\n * @notice The tests are based on the default config values. It is expected that\n * the config values used in these tests are ran in production.\n */\ncontract ResourceMetering_Test is Test {\n MeterUser internal meter;\n uint64 initialBlockNum;\n\n function setUp() public {\n meter = new MeterUser();\n initialBlockNum = uint64(block.number);\n }\n\n function test_meter_initialResourceParams_succeeds() external {\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_updateParamsNoChange_succeeds() external {\n meter.use(0); // equivalent to just updating the base fee and block number\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n meter.use(0);\n (uint128 postBaseFee, uint64 postBoughtGas, uint64 postBlockNum) = meter.params();\n\n assertEq(postBaseFee, prevBaseFee);\n assertEq(postBoughtGas, prevBoughtGas);\n assertEq(postBlockNum, prevBlockNum);\n }\n\n function test_meter_updateOneEmptyBlock_succeeds() external {\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 1);\n }\n\n function test_meter_updateTwoEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 2);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 2);\n }\n\n function test_meter_updateTenEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 10);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 10);\n }\n\n function test_meter_updateNoGasDelta_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint256 target = uint256(rcfg.maxResourceLimit) / uint256(rcfg.elasticityMultiplier);\n meter.use(uint64(target));\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1000000000);\n assertEq(prevBoughtGas, target);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_useMax_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n meter.use(target * elasticityMultiplier);\n\n (, uint64 prevBoughtGas, ) = meter.params();\n assertEq(prevBoughtGas, target * elasticityMultiplier);\n\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 postBaseFee, , ) = meter.params();\n assertEq(postBaseFee, 2125000000);\n }\n\n /**\n * @notice This tests that the metered modifier reverts if\n * the ResourceConfig baseFeeMaxChangeDenominator\n * is set to 1.\n * Since the metered modifier internally calls\n * solmate's powWad function, it will revert\n * with the error string \"UNDEFINED\" since the\n * first parameter will be computed as 0.\n */\n function test_meter_denominatorEq1_reverts() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n rcfg.baseFeeMaxChangeDenominator = 1;\n meter.setParams(rcfg);\n meter.use(target * elasticityMultiplier);\n\n (, uint64 prevBoughtGas, ) = meter.params();\n assertEq(prevBoughtGas, target * elasticityMultiplier);\n\n vm.roll(initialBlockNum + 2);\n\n vm.expectRevert(\"UNDEFINED\");\n meter.use(0);\n }\n\n function test_meter_useMoreThanMax_reverts() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.expectRevert(\"ResourceMetering: cannot buy more gas than available gas limit\");\n meter.use(target * elasticityMultiplier + 1);\n }\n\n // Demonstrates that the resource metering arithmetic can tolerate very large gaps between\n // deposits.\n function testFuzz_meter_largeBlockDiff_succeeds(uint64 _amount, uint256 _blockDiff) external {\n // This test fails if the following line is commented out.\n // At 12 seconds per block, this number is effectively unreachable.\n vm.assume(_blockDiff < 433576281058164217753225238677900874458691);\n\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.assume(_amount < target * elasticityMultiplier);\n vm.roll(initialBlockNum + _blockDiff);\n meter.use(_amount);\n }\n}\n\n/**\n * @title CustomMeterUser\n * @notice A simple wrapper around `ResourceMetering` that allows the initial\n * params to be set in the constructor.\n */\ncontract CustomMeterUser is ResourceMetering {\n uint256 public startGas;\n uint256 public endGas;\n\n constructor(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function use(uint64 _amount) public returns (uint256) {\n uint256 initialGas = gasleft();\n _metered(_amount, initialGas);\n return initialGas - gasleft();\n }\n}\n\n/**\n * @title ArtifactResourceMetering_Test\n * @notice A table test that sets the state of the ResourceParams and then requests\n * various amounts of gas. This test ensures that a wide range of values\n * can safely be used with the `ResourceMetering` contract.\n * It also writes a CSV file to disk that includes useful information\n * about how much gas is used and how expensive it is in USD terms to\n * purchase the deposit gas.\n */\ncontract ArtifactResourceMetering_Test is Test {\n uint128 internal minimumBaseFee;\n uint128 internal maximumBaseFee;\n uint64 internal maxResourceLimit;\n uint64 internal targetResourceLimit;\n\n string internal outfile;\n\n // keccak256(abi.encodeWithSignature(\"Error(string)\", \"ResourceMetering: cannot buy more gas than available gas limit\"))\n bytes32 internal cannotBuyMoreGas =\n 0x84edc668cfd5e050b8999f43ff87a1faaa93e5f935b20bc1dd4d3ff157ccf429;\n // keccak256(abi.encodeWithSignature(\"Panic(uint256)\", 0x11))\n bytes32 internal overflowErr =\n 0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;\n // keccak256(hex\"\")\n bytes32 internal emptyReturnData =\n 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n\n /**\n * @notice Sets up the tests by getting constants from the ResourceMetering\n * contract.\n */\n function setUp() public {\n vm.roll(1_000_000);\n\n MeterUser base = new MeterUser();\n ResourceMetering.ResourceConfig memory rcfg = base.resourceConfig();\n minimumBaseFee = uint128(rcfg.minimumBaseFee);\n maximumBaseFee = rcfg.maximumBaseFee;\n maxResourceLimit = uint64(rcfg.maxResourceLimit);\n targetResourceLimit = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n\n outfile = string.concat(vm.projectRoot(), \"/.resource-metering.csv\");\n try vm.removeFile(outfile) {} catch {}\n }\n\n /**\n * @notice Generate a CSV file. The call to `meter` should be called with at\n * most the L1 block gas limit. Without specifying the amount of\n * gas, it can take very long to execute.\n */\n function test_meter_generateArtifact_succeeds() external {\n vm.writeLine(\n outfile,\n \"prevBaseFee,prevBoughtGas,prevBlockNumDiff,l1BaseFee,requestedGas,gasConsumed,ethPrice,usdCost,success\"\n );\n\n // prevBaseFee value in ResourceParams\n uint128[] memory prevBaseFees = new uint128[](5);\n prevBaseFees[0] = minimumBaseFee;\n prevBaseFees[1] = maximumBaseFee;\n prevBaseFees[2] = uint128(50 gwei);\n prevBaseFees[3] = uint128(100 gwei);\n prevBaseFees[4] = uint128(200 gwei);\n\n // prevBoughtGas value in ResourceParams\n uint64[] memory prevBoughtGases = new uint64[](1);\n prevBoughtGases[0] = uint64(0);\n\n // prevBlockNum diff, simulates blocks with no deposits when non zero\n uint64[] memory prevBlockNumDiffs = new uint64[](2);\n prevBlockNumDiffs[0] = 0;\n prevBlockNumDiffs[1] = 1;\n\n // The amount of L2 gas that a user requests\n uint64[] memory requestedGases = new uint64[](3);\n requestedGases[0] = maxResourceLimit;\n requestedGases[1] = targetResourceLimit;\n requestedGases[2] = uint64(100_000);\n\n // The L1 base fee\n uint256[] memory l1BaseFees = new uint256[](4);\n l1BaseFees[0] = 1 gwei;\n l1BaseFees[1] = 50 gwei;\n l1BaseFees[2] = 75 gwei;\n l1BaseFees[3] = 100 gwei;\n\n // USD price of 1 ether\n uint256[] memory ethPrices = new uint256[](2);\n ethPrices[0] = 1600;\n ethPrices[1] = 3200;\n\n // Iterate over all of the test values and run a test\n for (uint256 i; i < prevBaseFees.length; i++) {\n for (uint256 j; j < prevBoughtGases.length; j++) {\n for (uint256 k; k < prevBlockNumDiffs.length; k++) {\n for (uint256 l; l < requestedGases.length; l++) {\n for (uint256 m; m < l1BaseFees.length; m++) {\n for (uint256 n; n < ethPrices.length; n++) {\n uint256 snapshotId = vm.snapshot();\n\n uint128 prevBaseFee = prevBaseFees[i];\n uint64 prevBoughtGas = prevBoughtGases[j];\n uint64 prevBlockNumDiff = prevBlockNumDiffs[k];\n uint64 requestedGas = requestedGases[l];\n uint256 l1BaseFee = l1BaseFees[m];\n uint256 ethPrice = ethPrices[n];\n string memory result = \"success\";\n\n vm.fee(l1BaseFee);\n\n CustomMeterUser meter = new CustomMeterUser({\n _prevBaseFee: prevBaseFee,\n _prevBoughtGas: prevBoughtGas,\n _prevBlockNum: uint64(block.number)\n });\n\n vm.roll(block.number + prevBlockNumDiff);\n\n // Call the metering code and catch the various\n // types of errors.\n uint256 gasConsumed = 0;\n try meter.use{ gas: 30_000_000 }(requestedGas) returns (\n uint256 _gasConsumed\n ) {\n gasConsumed = _gasConsumed;\n } catch (bytes memory err) {\n bytes32 hash = keccak256(err);\n if (hash == cannotBuyMoreGas) {\n result = \"ResourceMetering: cannot buy more gas than available gas limit\";\n } else if (hash == overflowErr) {\n result = \"arithmetic overflow/underflow\";\n } else if (hash == emptyReturnData) {\n result = \"out of gas\";\n } else {\n result = \"UNKNOWN ERROR\";\n }\n }\n\n // Compute the USD cost of the gas used\n uint256 usdCost = (gasConsumed * l1BaseFee * ethPrice) / 1 ether;\n\n vm.writeLine(\n outfile,\n string.concat(\n vm.toString(prevBaseFee),\n \",\",\n vm.toString(prevBoughtGas),\n \",\",\n vm.toString(prevBlockNumDiff),\n \",\",\n vm.toString(l1BaseFee),\n \",\",\n vm.toString(requestedGas),\n \",\",\n vm.toString(gasConsumed),\n \",\",\n \"$\",\n vm.toString(ethPrice),\n \",\",\n \"$\",\n vm.toString(usdCost),\n \",\",\n result\n )\n );\n\n assertTrue(vm.revertTo(snapshotId));\n }\n }\n }\n }\n }\n }\n }\n}\n" - }, - "contracts/test/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\n\ncontract SafeCall_Test is CommonTest {\n function testFuzz_call_succeeds(\n address from,\n address to,\n uint256 gas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n // don't call the ffi interface\n vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCall(to, value, data);\n vm.prank(from);\n bool success = SafeCall.call(to, gas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function testFuzz_callWithMinGas_hasEnough_succeeds(\n address from,\n address to,\n uint64 minGas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n // don't call the FFIInterface\n vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n // Bound minGas to [0, l1_block_gas_limit]\n minGas = uint64(bound(minGas, 0, 30_000_000));\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCallMinGas(to, value, minGas, data);\n vm.prank(from);\n bool success = SafeCall.callWithMinGas(to, minGas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function test_callWithMinGas_noLeakageLow_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 40_000; i < 100_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 65_907 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 65_907) {\n assertFalse(caller.makeSafeCall(i, 25_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 25_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 25_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n\n function test_callWithMinGas_noLeakageHigh_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 15_200_000; i < 15_300_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 15_278_606 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 15_278_606) {\n assertFalse(caller.makeSafeCall(i, 15_000_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 15_000_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 15_000_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n}\n\ncontract SimpleSafeCaller {\n uint256 public a;\n\n function makeSafeCall(uint64 gas, uint64 minGas) external returns (bool) {\n return\n SafeCall.call(\n address(this),\n gas,\n 0,\n abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas)\n );\n }\n\n function makeSafeCallMinGas(uint64 minGas) external returns (bool) {\n return\n SafeCall.callWithMinGas(\n address(this),\n minGas,\n 0,\n abi.encodeWithSelector(this.setA.selector, 1)\n );\n }\n\n function setA(uint256 _a) external {\n a = _a;\n }\n}\n" - }, - "contracts/test/Semver.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\n\n/**\n * @notice Test the Semver contract that is used for semantic versioning\n * of various contracts.\n */\ncontract Semver_Test is CommonTest {\n /**\n * @notice Global semver contract deployed in setUp. This is used in\n * the test cases.\n */\n Semver semver;\n\n /**\n * @notice Deploy a Semver contract\n */\n function setUp() public virtual override {\n semver = new Semver(7, 8, 0);\n }\n\n /**\n * @notice Test the version getter\n */\n function test_version_succeeds() external {\n assertEq(semver.version(), \"7.8.0\");\n }\n\n /**\n * @notice Since the versions are all immutable, they should\n * be able to be accessed from behind a proxy without needing\n * to initialize the contract.\n */\n function test_behindProxy_succeeds() external {\n Proxy proxy = new Proxy(alice);\n vm.prank(alice);\n proxy.upgradeTo(address(semver));\n\n assertEq(Semver(address(proxy)).version(), \"7.8.0\");\n }\n}\n" - }, - "contracts/test/SequencerFeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { SequencerFeeVault } from \"../L2/SequencerFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract SequencerFeeVault_Test is Bridge_Initializer {\n SequencerFeeVault vault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET));\n address constant recipient = address(256);\n\n event Withdrawal(uint256 value, address to, address from);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.SEQUENCER_FEE_WALLET, address(new SequencerFeeVault(recipient)).code);\n vm.label(Predeploys.SEQUENCER_FEE_WALLET, \"SequencerFeeVault\");\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n\n function test_constructor_succeeds() external {\n assertEq(vault.l1FeeWallet(), recipient);\n }\n\n function test_receive_succeeds() external {\n uint256 balance = address(vault).balance;\n\n vm.prank(alice);\n (bool success, ) = address(vault).call{ value: 100 }(hex\"\");\n\n assertEq(success, true);\n assertEq(address(vault).balance, balance + 100);\n }\n\n function test_withdraw_notEnough_reverts() external {\n assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());\n\n vm.expectRevert(\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n vault.withdraw();\n }\n\n function test_withdraw_succeeds() external {\n uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1;\n vm.deal(address(vault), amount);\n\n // No ether has been withdrawn yet\n assertEq(vault.totalProcessed(), 0);\n\n vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));\n emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));\n\n // The entire vault's balance is withdrawn\n vm.expectCall(\n Predeploys.L2_STANDARD_BRIDGE,\n address(vault).balance,\n abi.encodeWithSelector(\n StandardBridge.bridgeETHTo.selector,\n vault.l1FeeWallet(),\n 35_000,\n bytes(\"\")\n )\n );\n\n vault.withdraw();\n\n // The withdrawal was successful\n assertEq(vault.totalProcessed(), amount);\n }\n}\n" - }, - "contracts/test/StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport {\n OptimismMintableERC20,\n ILegacyMintableERC20\n} from \"../universal/OptimismMintableERC20.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/**\n * @title StandardBridgeTester\n * @notice Simple wrapper around the StandardBridge contract that exposes\n * internal functions so they can be more easily tested directly.\n */\ncontract StandardBridgeTester is StandardBridge {\n constructor(address payable _messenger, address payable _otherBridge)\n StandardBridge(_messenger, _otherBridge)\n {}\n\n function isOptimismMintableERC20(address _token) external view returns (bool) {\n return _isOptimismMintableERC20(_token);\n }\n\n function isCorrectTokenPair(address _mintableToken, address _otherToken)\n external\n view\n returns (bool)\n {\n return _isCorrectTokenPair(_mintableToken, _otherToken);\n }\n\n receive() external payable override {}\n}\n\n/**\n * @title LegacyMintable\n * @notice Simple implementation of the legacy OptimismMintableERC20.\n */\ncontract LegacyMintable is ERC20, ILegacyMintableERC20 {\n constructor(string memory _name, string memory _ticker) ERC20(_name, _ticker) {}\n\n function l1Token() external pure returns (address) {\n return address(0);\n }\n\n function mint(address _to, uint256 _amount) external pure {}\n\n function burn(address _from, uint256 _amount) external pure {}\n\n /**\n * @notice Implements ERC165. This implementation should not be changed as\n * it is how the actual legacy optimism mintable token does the\n * check. Allows for testing against code that is has been deployed,\n * assuming different compiler version is no problem.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n}\n\n/**\n * @title StandardBridge_Stateless_Test\n * @notice Tests internal functions that require no existing state or contract\n * interactions with the messenger.\n */\ncontract StandardBridge_Stateless_Test is CommonTest {\n StandardBridgeTester internal bridge;\n OptimismMintableERC20 internal mintable;\n ERC20 internal erc20;\n LegacyMintable internal legacy;\n\n function setUp() public override {\n super.setUp();\n\n bridge = new StandardBridgeTester({\n _messenger: payable(address(0)),\n _otherBridge: payable(address(0))\n });\n\n mintable = new OptimismMintableERC20({\n _bridge: address(0),\n _remoteToken: address(0),\n _name: \"Stonks\",\n _symbol: \"STONK\"\n });\n\n erc20 = new ERC20(\"Altcoin\", \"ALT\");\n legacy = new LegacyMintable(\"Legacy\", \"LEG\");\n }\n\n /**\n * @notice Test coverage for identifying OptimismMintableERC20 tokens.\n * This function should return true for both modern and legacy\n * OptimismMintableERC20 tokens and false for any accounts that\n * do not implement the interface.\n */\n function test_isOptimismMintableERC20_succeeds() external {\n // Both the modern and legacy mintable tokens should return true\n assertTrue(bridge.isOptimismMintableERC20(address(mintable)));\n assertTrue(bridge.isOptimismMintableERC20(address(legacy)));\n // A regular ERC20 should return false\n assertFalse(bridge.isOptimismMintableERC20(address(erc20)));\n // Non existent contracts should return false and not revert\n assertEq(address(0x20).code.length, 0);\n assertFalse(bridge.isOptimismMintableERC20(address(0x20)));\n }\n\n /**\n * @notice Test coverage of isCorrectTokenPair under different types of\n * tokens.\n */\n function test_isCorrectTokenPair_succeeds() external {\n // Modern + known to be correct remote token\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.remoteToken()));\n // Modern + known to be correct l1Token (legacy interface)\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.l1Token()));\n // Modern + known to be incorrect remote token\n assertTrue(mintable.remoteToken() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(mintable), address(0x20)));\n // Legacy + known to be correct l1Token\n assertTrue(bridge.isCorrectTokenPair(address(legacy), legacy.l1Token()));\n // Legacy + known to be incorrect l1Token\n assertTrue(legacy.l1Token() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(legacy), address(0x20)));\n // A token that doesn't support either modern or legacy interface\n // will revert\n vm.expectRevert();\n bridge.isCorrectTokenPair(address(erc20), address(1));\n }\n}\n" - }, - "contracts/test/SystemConfig.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract SystemConfig_Init is CommonTest {\n SystemConfig sysConf;\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n sysConf = new SystemConfig({\n _owner: alice,\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: config\n });\n }\n}\n\ncontract SystemConfig_Initialize_TestFail is SystemConfig_Init {\n function test_initialize_lowGasLimit_reverts() external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n\n ResourceMetering.ResourceConfig memory cfg = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n new SystemConfig({\n _owner: alice,\n _overhead: 0,\n _scalar: 0,\n _batcherHash: bytes32(hex\"\"),\n _gasLimit: minimumGasLimit - 1,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n }\n}\n\ncontract SystemConfig_Setters_TestFail is SystemConfig_Init {\n function test_setBatcherHash_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setBatcherHash(bytes32(hex\"\"));\n }\n\n function test_setGasConfig_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasConfig(0, 0);\n }\n\n function test_setGasLimit_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasLimit(0);\n }\n\n function test_setUnsafeBlockSigner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setUnsafeBlockSigner(address(0x20));\n }\n\n function test_setResourceConfig_notOwner_reverts() external {\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badMinMax_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 2 gwei,\n maximumBaseFee: 1 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: min base fee must be less than max base\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_zeroDenominator_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 0,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: denominator must be larger than 1\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_lowGasLimit_reverts() external {\n uint64 gasLimit = sysConf.gasLimit();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: uint32(gasLimit),\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: uint32(gasLimit),\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badPrecision_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 11,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: precision loss with target resource limit\");\n sysConf.setResourceConfig(config);\n }\n}\n\ncontract SystemConfig_Setters_Test is SystemConfig_Init {\n event ConfigUpdate(\n uint256 indexed version,\n SystemConfig.UpdateType indexed updateType,\n bytes data\n );\n\n function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash));\n\n vm.prank(sysConf.owner());\n sysConf.setBatcherHash(newBatcherHash);\n assertEq(sysConf.batcherHash(), newBatcherHash);\n }\n\n function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.GAS_CONFIG,\n abi.encode(newOverhead, newScalar)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setGasConfig(newOverhead, newScalar);\n assertEq(sysConf.overhead(), newOverhead);\n assertEq(sysConf.scalar(), newScalar);\n }\n\n function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n newGasLimit = uint64(\n bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))\n );\n\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit));\n\n vm.prank(sysConf.owner());\n sysConf.setGasLimit(newGasLimit);\n assertEq(sysConf.gasLimit(), newGasLimit);\n }\n\n function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER,\n abi.encode(newUnsafeSigner)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setUnsafeBlockSigner(newUnsafeSigner);\n assertEq(sysConf.unsafeBlockSigner(), newUnsafeSigner);\n }\n}\n" - }, - "contracts/test/TransferOnion.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { TransferOnion } from \"../periphery/TransferOnion.sol\";\n\n/**\n * @title TransferOnionTest\n * @notice Test coverage of TransferOnion\n */\ncontract TransferOnionTest is Test {\n /**\n * @notice TransferOnion\n */\n TransferOnion internal onion;\n\n /**\n * @notice token constructor arg\n */\n address internal _token;\n\n /**\n * @notice sender constructor arg\n */\n address internal _sender;\n\n /**\n * @notice Sets up addresses, deploys contracts and funds the owner.\n */\n function setUp() public {\n ERC20 token = new ERC20(\"Token\", \"TKN\");\n _token = address(token);\n _sender = makeAddr(\"sender\");\n }\n\n /**\n * @notice Deploy the TransferOnion with a dummy shell\n */\n function _deploy() public {\n _deploy(bytes32(0));\n }\n\n /**\n * @notice Deploy the TransferOnion with a specific shell\n */\n function _deploy(bytes32 _shell) public {\n onion = new TransferOnion({ _token: ERC20(_token), _sender: _sender, _shell: _shell });\n }\n\n /**\n * @notice Build the onion data\n */\n function _onionize(TransferOnion.Layer[] memory _layers)\n public\n pure\n returns (bytes32, TransferOnion.Layer[] memory)\n {\n uint256 length = _layers.length;\n bytes32 hash = bytes32(0);\n for (uint256 i; i < length; i++) {\n TransferOnion.Layer memory layer = _layers[i];\n _layers[i].shell = hash;\n hash = keccak256(abi.encode(layer.recipient, layer.amount, hash));\n }\n return (hash, _layers);\n }\n\n /**\n * @notice The constructor sets the variables as expected\n */\n function test_constructor_succeeds() external {\n _deploy();\n\n assertEq(address(onion.TOKEN()), _token);\n assertEq(onion.SENDER(), _sender);\n assertEq(onion.shell(), bytes32(0));\n }\n\n /**\n * @notice unwrap\n */\n function test_unwrap_succeeds() external {\n // Commit to transferring tiny amounts of tokens\n TransferOnion.Layer[] memory _layers = new TransferOnion.Layer[](2);\n _layers[0] = TransferOnion.Layer(address(1), 1, bytes32(0));\n _layers[1] = TransferOnion.Layer(address(2), 2, bytes32(0));\n\n // Build the onion shell\n (bytes32 shell, TransferOnion.Layer[] memory layers) = _onionize(_layers);\n _deploy(shell);\n\n assertEq(onion.shell(), shell);\n\n address token = address(onion.TOKEN());\n address sender = onion.SENDER();\n\n // give 3 units of token to sender\n deal(token, onion.SENDER(), 3);\n vm.prank(sender);\n ERC20(token).approve(address(onion), 3);\n\n // To build the inputs, to `peel`, need to reverse the list\n TransferOnion.Layer[] memory inputs = new TransferOnion.Layer[](2);\n int256 length = int256(layers.length);\n for (int256 i = length - 1; i >= 0; i--) {\n uint256 ui = uint256(i);\n uint256 revidx = uint256(length) - ui - 1;\n TransferOnion.Layer memory layer = layers[ui];\n inputs[revidx] = layer;\n }\n\n // The accounts have no balance\n assertEq(ERC20(_token).balanceOf(address(1)), 0);\n assertEq(ERC20(_token).balanceOf(address(2)), 0);\n\n onion.peel(inputs);\n\n // Now the accounts have the expected balance\n assertEq(ERC20(_token).balanceOf(address(1)), 1);\n assertEq(ERC20(_token).balanceOf(address(2)), 2);\n }\n}\n" - }, - "contracts/test/invariants/CrossDomainMessenger.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { OptimismPortal } from \"../../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../../L1/L1CrossDomainMessenger.sol\";\nimport { Messenger_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\nimport { Predeploys } from \"../../libraries/Predeploys.sol\";\nimport { Constants } from \"../../libraries/Constants.sol\";\nimport { Encoding } from \"../../libraries/Encoding.sol\";\nimport { Hashing } from \"../../libraries/Hashing.sol\";\n\ncontract RelayActor is StdUtils {\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n uint256 public numHashes;\n bytes32[] public hashes;\n bool public reverted = false;\n\n OptimismPortal op;\n L1CrossDomainMessenger xdm;\n Vm vm;\n bool doFail;\n\n constructor(\n OptimismPortal _op,\n L1CrossDomainMessenger _xdm,\n Vm _vm,\n bool _doFail\n ) {\n op = _op;\n xdm = _xdm;\n vm = _vm;\n doFail = _doFail;\n }\n\n /**\n * Relays a message to the `L1CrossDomainMessenger` with a random `version`, and `_message`.\n */\n function relay(\n uint8 _version,\n uint8 _value,\n bytes memory _message\n ) external {\n address target = address(0x04); // ID precompile\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Set the minimum gas limit to the cost of the identity precompile's execution for\n // the given message.\n // ID Precompile cost can be determined by calculating: 15 + 3 * data_word_length\n uint32 minGasLimit = uint32(15 + 3 * ((_message.length + 31) / 32));\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Restrict version to the range of [0, 1]\n _version = _version % 2;\n\n // Restrict the value to the range of [0, 1]\n // This is just so we get variance of calls with and without value. The ID precompile\n // will not reject value being sent to it.\n _value = _value % 2;\n\n // If the message should succeed, supply it `baseGas`. If not, supply it an amount of\n // gas that is too low to complete the call.\n uint256 gas = doFail\n ? bound(minGasLimit, 60_000, 80_000)\n : xdm.baseGas(_message, minGasLimit);\n\n // Compute the cross domain message hash and store it in `hashes`.\n // The `relayMessage` function will always encode the message as a version 1\n // message after checking that the V0 hash has not already been relayed.\n bytes32 _hash = Hashing.hashCrossDomainMessageV1(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n _value,\n minGasLimit,\n _message\n );\n hashes.push(_hash);\n numHashes += 1;\n\n // Make sure we've got a fresh message.\n vm.assume(xdm.successfulMessages(_hash) == false && xdm.failedMessages(_hash) == false);\n\n // Act as the optimism portal and call `relayMessage` on the `L1CrossDomainMessenger` with\n // the outer min gas limit.\n vm.startPrank(address(op));\n if (!doFail) {\n vm.expectCallMinGas(address(0x04), _value, minGasLimit, _message);\n }\n try\n xdm.relayMessage{ gas: gas, value: _value }(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n _value,\n minGasLimit,\n _message\n )\n {} catch {\n // If any of these calls revert, set `reverted` to true to fail the invariant test.\n // NOTE: This is to get around forge's invariant fuzzer ignoring reverted calls\n // to this function.\n reverted = true;\n }\n vm.stopPrank();\n }\n}\n\ncontract XDM_MinGasLimits is Messenger_Initializer {\n RelayActor actor;\n\n function init(bool doFail) public virtual {\n // Set up the `L1CrossDomainMessenger` and `OptimismPortal` contracts.\n super.setUp();\n\n // Deploy a relay actor\n actor = new RelayActor(op, L1Messenger, vm, doFail);\n\n // Give the portal some ether to send to `relayMessage`\n vm.deal(address(op), type(uint128).max);\n\n // Target the `RelayActor` contract\n targetContract(address(actor));\n\n // Don't allow the estimation address to be the sender\n excludeSender(Constants.ESTIMATION_ADDRESS);\n\n // Target the actor's `relay` function\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.relay.selector;\n targetSelector(FuzzSelector({ addr: address(actor), selectors: selectors }));\n }\n}\n\ncontract XDM_MinGasLimits_Succeeds is XDM_MinGasLimits {\n function setUp() public override {\n // Don't fail\n super.init(false);\n }\n\n /**\n * @custom:invariant A call to `relayMessage` should succeed if at least the minimum gas limit\n * can be supplied to the target context, there is enough gas to complete\n * execution of `relayMessage` after the target context's execution is\n * finished, and the target context did not revert.\n *\n * There are two minimum gas limits here:\n *\n * - The outer min gas limit is for the call from the `OptimismPortal` to the\n * `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function\n * with the `message` and inner limit.\n *\n * - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target\n * contract.\n */\n function invariant_minGasLimits() external {\n uint256 length = actor.numHashes();\n for (uint256 i = 0; i < length; ++i) {\n bytes32 hash = actor.hashes(i);\n // The message hash is set in the successfulMessages mapping\n assertTrue(L1Messenger.successfulMessages(hash));\n // The message hash is not set in the failedMessages mapping\n assertFalse(L1Messenger.failedMessages(hash));\n }\n assertFalse(actor.reverted());\n }\n}\n\ncontract XDM_MinGasLimits_Reverts is XDM_MinGasLimits {\n function setUp() public override {\n // Do fail\n super.init(true);\n }\n\n /**\n * @custom:invariant A call to `relayMessage` should assign the message hash to the\n * `failedMessages` mapping if not enough gas is supplied to forward\n * `minGasLimit` to the target context or if there is not enough gas to\n * complete execution of `relayMessage` after the target context's execution\n * is finished.\n *\n * There are two minimum gas limits here:\n *\n * - The outer min gas limit is for the call from the `OptimismPortal` to the\n * `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function\n * with the `message` and inner limit.\n *\n * - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target\n * contract.\n */\n function invariant_minGasLimits() external {\n uint256 length = actor.numHashes();\n for (uint256 i = 0; i < length; ++i) {\n bytes32 hash = actor.hashes(i);\n // The message hash is not set in the successfulMessages mapping\n assertFalse(L1Messenger.successfulMessages(hash));\n // The message hash is set in the failedMessages mapping\n assertTrue(L1Messenger.failedMessages(hash));\n }\n assertFalse(actor.reverted());\n }\n}\n" - }, - "contracts/test/invariants/L2OutputOracle.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { L2OutputOracle_Initializer } from \"../CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../../L1/L2OutputOracle.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\n\ncontract L2OutputOracle_Proposer {\n L2OutputOracle internal oracle;\n Vm internal vm;\n\n constructor(L2OutputOracle _oracle, Vm _vm) {\n oracle = _oracle;\n vm = _vm;\n }\n\n /**\n * @dev Allows the actor to propose an L2 output to the `L2OutputOracle`\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external {\n // Act as the proposer and propose a new output.\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _l2BlockNumber, _l1BlockHash, _l1BlockNumber);\n }\n}\n\ncontract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_Initializer {\n L2OutputOracle_Proposer internal actor;\n\n function setUp() public override {\n super.setUp();\n\n // Create a proposer actor.\n actor = new L2OutputOracle_Proposer(oracle, vm);\n\n // Set the target contract to the proposer actor.\n targetContract(address(actor));\n\n // Set the target selector for `proposeL2Output`\n // `proposeL2Output` is the only function we care about, as it is the only function\n // that can modify the `l2Outputs` array in the oracle.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.proposeL2Output.selector;\n FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The block number of the output root proposals should monotonically\n * increase.\n *\n * When a new output is submitted, it should never be allowed to correspond to a block\n * number that is less than the current output.\n */\n function invariant_monotonicBlockNumIncrease() external {\n // Assert that the block number of proposals must monotonically increase.\n assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber());\n }\n}\n" - }, - "contracts/test/invariants/OptimismPortal.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Portal_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\n\ncontract OptimismPortal_Invariant_Harness is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n function setUp() public virtual override {\n super.setUp();\n\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n}\n\ncontract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization\n * period has not elapsed.\n *\n * A withdrawal that has been proven should not be able to be finalized until after\n * the finalization period has elapsed.\n */\n function invariant_cannotFinalizeBeforePeriodHasPassed() external {\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Finalize the withdrawal transaction.\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal\n * has already been finalized.\n *\n * Ensures that there is no chain of calls that can be made that allows a withdrawal\n * to be finalized twice.\n */\n function invariant_cannotFinalizeTwice() external {\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant A withdrawal should **always** be able to be finalized\n * `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.\n *\n * This invariant asserts that there is no chain of calls that can be made that\n * will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS`\n * after it was successfully proven.\n */\n function invariant_canAlwaysFinalize() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value);\n }\n}\n" - }, - "contracts/test/invariants/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { SafeCall } from \"../../libraries/SafeCall.sol\";\n\ncontract SafeCall_Succeeds_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, false);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n\n // Give the actor some ETH to work with\n vm.deal(address(actor), type(uint128).max);\n }\n\n /**\n * @custom:invariant If `callWithMinGas` performs a call, then it must always\n * provide at least the specified minimum gas limit to the subcontext.\n *\n * If the check for remaining gas in `SafeCall.callWithMinGas` passes, the\n * subcontext of the call below it must be provided at least `minGas` gas.\n */\n function invariant_callWithMinGas_alwaysForwardsMinGas_succeeds() public {\n assertEq(actor.numCalls(), 0, \"no failed calls allowed\");\n }\n\n function performSafeCallMinGas(address to, uint64 minGas) external payable {\n SafeCall.callWithMinGas(to, minGas, msg.value, hex\"\");\n }\n}\n\ncontract SafeCall_Fails_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, true);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n\n // Give the actor some ETH to work with\n vm.deal(address(actor), type(uint128).max);\n }\n\n /**\n * @custom:invariant `callWithMinGas` reverts if there is not enough gas to pass\n * to the subcontext.\n *\n * If there is not enough gas in the callframe to ensure that `callWithMinGas`\n * can provide the specified minimum gas limit to the subcontext of the call,\n * then `callWithMinGas` must revert.\n */\n function invariant_callWithMinGas_neverForwardsMinGas_reverts() public {\n assertEq(actor.numCalls(), 0, \"no successful calls allowed\");\n }\n\n function performSafeCallMinGas(address to, uint64 minGas) external payable {\n SafeCall.callWithMinGas(to, minGas, msg.value, hex\"\");\n }\n}\n\ncontract SafeCaller_Actor is StdUtils {\n bool internal immutable FAILS;\n\n Vm internal vm;\n uint256 public numCalls;\n\n constructor(Vm _vm, bool _fails) {\n vm = _vm;\n FAILS = _fails;\n }\n\n function performSafeCallMinGas(\n uint64 gas,\n uint64 minGas,\n address to,\n uint8 value\n ) external {\n // Only send to EOAs - we exclude the console as it has no code but reverts when called\n // with a selector that doesn't exist due to the foundry hook.\n vm.assume(to.code.length == 0 && to != 0x000000000000000000636F6e736F6c652e6c6f67);\n\n // Bound the minimum gas amount to [2500, type(uint48).max]\n minGas = uint64(bound(minGas, 2500, type(uint48).max));\n if (FAILS) {\n // Bound the gas passed to [minGas, ((minGas * 64) / 63)]\n gas = uint64(bound(gas, minGas, (minGas * 64) / 63));\n } else {\n // Bound the gas passed to\n // [((minGas * 64) / 63) + 40_000 + 1000, type(uint64).max]\n // The extra 1000 gas is to account for the gas used by the `SafeCall.call` call\n // itself.\n gas = uint64(bound(gas, ((minGas * 64) / 63) + 40_000 + 1000, type(uint64).max));\n }\n\n vm.expectCallMinGas(to, value, minGas, hex\"\");\n bool success = SafeCall.call(\n msg.sender,\n gas,\n value,\n abi.encodeWithSelector(\n SafeCall_Succeeds_Invariants.performSafeCallMinGas.selector,\n to,\n minGas\n )\n );\n\n if (success && FAILS) numCalls++;\n if (!FAILS && !success) numCalls++;\n }\n}\n" - }, - "contracts/test/invariants/SystemConfig.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { SystemConfig } from \"../../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../../L1/ResourceMetering.sol\";\nimport { Constants } from \"../../libraries/Constants.sol\";\n\ncontract SystemConfig_GasLimitLowerBound_Invariant is Test {\n SystemConfig public config;\n\n function setUp() public {\n ResourceMetering.ResourceConfig memory cfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n config = new SystemConfig({\n _owner: address(0xbeef),\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n\n // Set the target contract to the `config`\n targetContract(address(config));\n // Set the target sender to the `config`'s owner (0xbeef)\n targetSender(address(0xbeef));\n // Set the target selector for `setGasLimit`\n // `setGasLimit` is the only function we care about, as it is the only function\n // that can modify the gas limit within the SystemConfig.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = config.setGasLimit.selector;\n FuzzSelector memory selector = FuzzSelector({\n addr: address(config),\n selectors: selectors\n });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The gas limit of the `SystemConfig` contract can never be lower\n * than the hard-coded lower bound.\n */\n function invariant_gasLimitLowerBound() external {\n assertTrue(config.gasLimit() >= config.minimumGasLimit());\n }\n}\n" - }, - "contracts/universal/CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer0\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * libAddressManager variable used to exist. Must be the first contract in the inheritance\n * tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer0 {\n /**\n * @custom:legacy\n * @custom:spacer libAddressManager\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n}\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer1\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * PausableUpgradable and OwnableUpgradeable variables used to exist. Must be\n * the third contract in the inheritance tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer1 {\n /**\n * @custom:legacy\n * @custom:spacer ContextUpgradable's __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable.\n *\n */\n uint256[50] private spacer_1_0_1600;\n\n /**\n * @custom:legacy\n * @custom:spacer OwnableUpgradeable's _owner\n * @notice Spacer for backwards compatibility.\n * Come from OpenZeppelin OwnableUpgradeable.\n */\n address private spacer_51_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer OwnableUpgradeable's __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * OwnableUpgradeable.\n */\n uint256[49] private spacer_52_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer PausableUpgradable's _paused\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n bool private spacer_101_0_1;\n\n /**\n * @custom:legacy\n * @custom:spacer PausableUpgradable's __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n uint256[49] private spacer_102_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer ReentrancyGuardUpgradeable's `_status` field.\n * @notice Spacer for backwards compatibility.\n */\n uint256 private spacer_151_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer ReentrancyGuardUpgradeable's __gap\n * @notice Spacer for backwards compatibility.\n */\n uint256[49] private spacer_152_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer blockedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_201_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer relayedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_202_0_32;\n}\n\n/**\n * @custom:upgradeable\n * @title CrossDomainMessenger\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\n * cross-chain messenger contracts. It's designed to be a universal interface that only\n * needs to be extended slightly to provide low-level message passing functionality on each\n * chain it's deployed on. Currently only designed for message passing between two paired\n * chains and does not support one-to-many interactions.\n *\n * Any changes to this contract MUST result in a semver bump for contracts that inherit it.\n */\nabstract contract CrossDomainMessenger is\n CrossDomainMessengerLegacySpacer0,\n Initializable,\n CrossDomainMessengerLegacySpacer1\n{\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Constant overhead added to the base gas for a message.\n */\n uint64 public constant RELAY_CONSTANT_OVERHEAD = 200_000;\n\n /**\n * @notice Numerator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 64;\n\n /**\n * @notice Denominator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 63;\n\n /**\n * @notice Extra gas added to base gas for each byte of calldata in a message.\n */\n uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\n\n /**\n * @notice Gas reserved for performing the external call in `relayMessage`.\n */\n uint64 public constant RELAY_CALL_OVERHEAD = 40_000;\n\n /**\n * @notice Gas reserved for finalizing the execution of `relayMessage` after the safe call.\n */\n uint64 public constant RELAY_RESERVED_GAS = 40_000;\n\n /**\n * @notice Gas reserved for the execution between the `hasMinGas` check and the external\n * call in `relayMessage`.\n */\n uint64 public constant RELAY_GAS_CHECK_BUFFER = 5_000;\n\n /**\n * @notice Address of the paired CrossDomainMessenger contract on the other chain.\n */\n address public immutable OTHER_MESSENGER;\n\n /**\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n * be present in this mapping if it has successfully been relayed on this chain, and\n * can therefore not be relayed again.\n */\n mapping(bytes32 => bool) public successfulMessages;\n\n /**\n * @notice Address of the sender of the currently executing message on the other chain. If the\n * value of this variable is the default value (0x00000000...dead) then no message is\n * currently being executed. Use the xDomainMessageSender getter which will throw an\n * error if this is the case.\n */\n address internal xDomainMsgSender;\n\n /**\n * @notice Nonce for the next message to be sent, without the message version applied. Use the\n * messageNonce getter which will insert the message version into the nonce to give you\n * the actual nonce to be used for the message.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Mapping of message hashes to a boolean if and only if the message has failed to be\n * executed at least once. A message will not be present in this mapping if it\n * successfully executed on the first attempt.\n */\n mapping(bytes32 => bool) public failedMessages;\n\n /**\n * @notice Reserve extra slots in the storage layout for future upgrades.\n * A gap size of 41 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[42] private __gap;\n\n /**\n * @notice Emitted whenever a message is sent to the other chain.\n *\n * @param target Address of the recipient of the message.\n * @param sender Address of the sender of the message.\n * @param message Message to trigger the recipient address with.\n * @param messageNonce Unique nonce attached to the message.\n * @param gasLimit Minimum gas limit that the message can be executed with.\n */\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n /**\n * @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the\n * SentMessage event without breaking the ABI of this contract, this is good enough.\n *\n * @param sender Address of the sender of the message.\n * @param value ETH value sent along with the message to the recipient.\n */\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n /**\n * @notice Emitted whenever a message is successfully relayed on this chain.\n *\n * @param msgHash Hash of the message that was relayed.\n */\n event RelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @notice Emitted whenever a message fails to be relayed on this chain.\n *\n * @param msgHash Hash of the message that failed to be relayed.\n */\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @param _otherMessenger Address of the messenger on the paired chain.\n */\n constructor(address _otherMessenger) {\n OTHER_MESSENGER = _otherMessenger;\n }\n\n /**\n * @notice Sends a message to some target address on the other chain. Note that if the call\n * always reverts, then the message will be unrelayable, and any ETH sent will be\n * permanently locked. The same will occur if the target on the other chain is\n * considered unsafe (see the _isUnsafeTarget() function).\n *\n * @param _target Target contract or wallet address.\n * @param _message Message to trigger the target address with.\n * @param _minGasLimit Minimum gas limit that the message can be executed with.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _minGasLimit\n ) external payable {\n // Triggers a message to the other messenger. Note that the amount of gas provided to the\n // message is the amount of gas requested by the user PLUS the base gas value. We want to\n // guarantee the property that the call to the target contract will always have at least\n // the minimum gas limit specified by the user.\n _sendMessage(\n OTHER_MESSENGER,\n baseGas(_message, _minGasLimit),\n msg.value,\n abi.encodeWithSelector(\n this.relayMessage.selector,\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _minGasLimit,\n _message\n )\n );\n\n emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit);\n emit SentMessageExtension1(msg.sender, msg.value);\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\n * be executed via cross-chain call from the other messenger OR if the message was\n * already received once and is currently being replayed.\n *\n * @param _nonce Nonce of the message being relayed.\n * @param _sender Address of the user who sent the message.\n * @param _target Address that the message is targeted at.\n * @param _value ETH value to send with the message.\n * @param _minGasLimit Minimum amount of gas that the message can be executed with.\n * @param _message Message to send to the target.\n */\n function relayMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _minGasLimit,\n bytes calldata _message\n ) external payable {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n require(\n version < 2,\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // If the message is version 0, then it's a migrated legacy withdrawal. We therefore need\n // to check that the legacy version of the message has not already been relayed.\n if (version == 0) {\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce);\n require(\n successfulMessages[oldHash] == false,\n \"CrossDomainMessenger: legacy withdrawal already relayed\"\n );\n }\n\n // We use the v1 message hash as the unique identifier for the message because it commits\n // to the value and minimum gas limit of the message.\n bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _minGasLimit,\n _message\n );\n\n if (_isOtherMessenger()) {\n // These properties should always hold when the message is first submitted (as\n // opposed to being replayed).\n assert(msg.value == _value);\n assert(!failedMessages[versionedHash]);\n } else {\n require(\n msg.value == 0,\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n\n require(\n failedMessages[versionedHash],\n \"CrossDomainMessenger: message cannot be replayed\"\n );\n }\n\n require(\n _isUnsafeTarget(_target) == false,\n \"CrossDomainMessenger: cannot send message to blocked system address\"\n );\n\n require(\n successfulMessages[versionedHash] == false,\n \"CrossDomainMessenger: message has already been relayed\"\n );\n\n // If there is not enough gas left to perform the external call and finish the execution,\n // return early and assign the message to the failedMessages mapping.\n // We are asserting that we have enough gas to:\n // 1. Call the target contract (_minGasLimit + RELAY_CALL_OVERHEAD + RELAY_GAS_CHECK_BUFFER)\n // 1.a. The RELAY_CALL_OVERHEAD is included in `hasMinGas`.\n // 2. Finish the execution after the external call (RELAY_RESERVED_GAS).\n //\n // If `xDomainMsgSender` is not the default L2 sender, this function\n // is being re-entered. This marks the message as failed to allow it to be replayed.\n if (\n !SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER) ||\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER\n ) {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n\n return;\n }\n\n xDomainMsgSender = _sender;\n bool success = SafeCall.call(_target, gasleft() - RELAY_RESERVED_GAS, _value, _message);\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n\n if (success) {\n successfulMessages[versionedHash] = true;\n emit RelayedMessage(versionedHash);\n } else {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n }\n }\n\n /**\n * @notice Retrieves the address of the contract or wallet that initiated the currently\n * executing message on the other chain. Will throw an error if there is no message\n * currently being executed. Allows the recipient of a call to see who triggered it.\n *\n * @return Address of the sender of the currently executing message on the other chain.\n */\n function xDomainMessageSender() external view returns (address) {\n require(\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER,\n \"CrossDomainMessenger: xDomainMessageSender is not set\"\n );\n\n return xDomainMsgSender;\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n\n /**\n * @notice Computes the amount of gas required to guarantee that a given message will be\n * received on the other chain without running out of gas. Guaranteeing that a message\n * will not run out of gas is important because this ensures that a message can always\n * be replayed on the other chain if it fails to execute completely.\n *\n * @param _message Message to compute the amount of required gas for.\n * @param _minGasLimit Minimum desired gas limit when message goes to target.\n *\n * @return Amount of gas required to guarantee message receipt.\n */\n function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {\n return\n // Constant overhead\n RELAY_CONSTANT_OVERHEAD +\n // Calldata overhead\n (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\n // Dynamic overhead (EIP-150)\n ((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\n MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\n // Gas reserved for the worst-case cost of 3/5 of the `CALL` opcode's dynamic gas\n // factors. (Conservative)\n RELAY_CALL_OVERHEAD +\n // Relay reserved gas (to ensure execution of `relayMessage` completes after the\n // subcontext finishes executing) (Conservative)\n RELAY_RESERVED_GAS +\n // Gas reserved for the execution between the `hasMinGas` check and the `CALL`\n // opcode. (Conservative)\n RELAY_GAS_CHECK_BUFFER;\n }\n\n /**\n * @notice Intializer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __CrossDomainMessenger_init() internal onlyInitializing {\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n }\n\n /**\n * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @param _to Recipient of the message on the other chain.\n * @param _gasLimit Minimum gas limit the message can be executed with.\n * @param _value Amount of ETH to send with the message.\n * @param _data Message data.\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal virtual;\n\n /**\n * @notice Checks whether the message is coming from the other messenger. Implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @return Whether the message is coming from the other messenger.\n */\n function _isOtherMessenger() internal view virtual returns (bool);\n\n /**\n * @notice Checks whether a given call target is a system address that could cause the\n * messenger to peform an unsafe action. This is NOT a mechanism for blocking user\n * addresses. This is ONLY used to prevent the execution of messages to specific\n * system addresses that could cause security issues, e.g., having the\n * CrossDomainMessenger send messages to itself.\n *\n * @param _target Address of the contract to check.\n *\n * @return Whether or not the address is an unsafe system address.\n */\n function _isUnsafeTarget(address _target) internal view virtual returns (bool);\n}\n" - }, - "contracts/universal/ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721Bridge\n * @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.\n */\nabstract contract ERC721Bridge {\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Address of the bridge on the other network.\n */\n address public immutable OTHER_BRIDGE;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[49] private __gap;\n\n /**\n * @notice Emitted when an ERC721 bridge to the other network is initiated.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC721 bridge from the other network is finalized.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) && MESSENGER.xDomainMessageSender() == OTHER_BRIDGE,\n \"ERC721Bridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge) {\n require(_messenger != address(0), \"ERC721Bridge: messenger cannot be address(0)\");\n require(_otherBridge != address(0), \"ERC721Bridge: other bridge cannot be address(0)\");\n\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = _otherBridge;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for other bridge address.\n *\n * @return Address of the bridge on the other network.\n */\n function otherBridge() external view returns (address) {\n return OTHER_BRIDGE;\n }\n\n /**\n * @notice Initiates a bridge of an NFT to the caller's account on the other chain. Note that\n * this function can only be called by EOAs. Smart contract wallets should use the\n * `bridgeERC721To` function after ensuring that the recipient address on the remote\n * chain exists. Also note that the current owner of the token on this chain must\n * approve this contract to operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721(\n address _localToken,\n address _remoteToken,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n // Modifier requiring sender to be EOA. This prevents against a user error that would occur\n // if the sender is a smart contract wallet that has a different address on the remote chain\n // (or doesn't have an address on the remote chain at all). The user would fail to receive\n // the NFT if they use this function because it sends the NFT to the same address as the\n // caller. This check could be bypassed by a malicious contract via initcode, but it takes\n // care of the user error we want to avoid.\n require(!Address.isContract(msg.sender), \"ERC721Bridge: account is not externally owned\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note\n * that the current owner of the token on this chain must approve this contract to\n * operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n require(_to != address(0), \"ERC721Bridge: nft recipient cannot be address(0)\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Internal function for initiating a token bridge to the other domain.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _from Address of the sender on this domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other domain. Data supplied here will\n * not be used to execute any code on the other domain and is only emitted\n * as extra data for the convenience of off-chain tooling.\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal virtual;\n}\n" - }, - "contracts/universal/FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n/**\n * @title FeeVault\n * @notice The FeeVault contract contains the basic logic for the various different vault contracts\n * used to hold fee revenue generated by the L2 system.\n */\nabstract contract FeeVault {\n /**\n * @notice Emits each time that a withdrawal occurs.\n *\n * @param value Amount that was withdrawn (in wei).\n * @param to Address that the funds were sent to.\n * @param from Address that triggered the withdrawal.\n */\n event Withdrawal(uint256 value, address to, address from);\n\n /**\n * @notice Minimum balance before a withdrawal can be triggered.\n */\n uint256 public immutable MIN_WITHDRAWAL_AMOUNT;\n\n /**\n * @notice Wallet that will receive the fees on L1.\n */\n address public immutable RECIPIENT;\n\n /**\n * @notice The minimum gas limit for the FeeVault withdrawal transaction.\n */\n uint32 internal constant WITHDRAWAL_MIN_GAS = 35_000;\n\n /**\n * @notice Total amount of wei processed by the contract.\n */\n uint256 public totalProcessed;\n\n /**\n * @param _recipient Wallet that will receive the fees on L1.\n * @param _minWithdrawalAmount Minimum balance before a withdrawal can be triggered.\n */\n constructor(address _recipient, uint256 _minWithdrawalAmount) {\n MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;\n RECIPIENT = _recipient;\n }\n\n /**\n * @notice Allow the contract to receive ETH.\n */\n receive() external payable {}\n\n /**\n * @notice Triggers a withdrawal of funds to the L1 fee wallet.\n */\n function withdraw() external {\n require(\n address(this).balance >= MIN_WITHDRAWAL_AMOUNT,\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n\n uint256 value = address(this).balance;\n totalProcessed += value;\n\n emit Withdrawal(value, RECIPIENT, msg.sender);\n\n L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }(\n RECIPIENT,\n WITHDRAWAL_MIN_GAS,\n bytes(\"\")\n );\n }\n}\n" - }, - "contracts/universal/IOptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @title IOptimismMintableERC20\n * @notice This interface is available on the OptimismMintableERC20 contract. We declare it as a\n * separate interface so that it can be used in custom implementations of\n * OptimismMintableERC20.\n */\ninterface IOptimismMintableERC20 is IERC165 {\n function remoteToken() external view returns (address);\n\n function bridge() external returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n\n/**\n * @custom:legacy\n * @title ILegacyMintableERC20\n * @notice This interface was available on the legacy L2StandardERC20 contract. It remains available\n * on the OptimismMintableERC20 contract for backwards compatibility.\n */\ninterface ILegacyMintableERC20 is IERC165 {\n function l1Token() external view returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n" - }, - "contracts/universal/IOptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\n/**\n * @title IOptimismMintableERC721\n * @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.\n * Tokens that follow this standard can be easily transferred across the ERC721 bridge.\n */\ninterface IOptimismMintableERC721 is IERC721Enumerable {\n /**\n * @notice Emitted when a token is minted.\n *\n * @param account Address of the account the token was minted to.\n * @param tokenId Token ID of the minted token.\n */\n event Mint(address indexed account, uint256 tokenId);\n\n /**\n * @notice Emitted when a token is burned.\n *\n * @param account Address of the account the token was burned from.\n * @param tokenId Token ID of the burned token.\n */\n event Burn(address indexed account, uint256 tokenId);\n\n /**\n * @notice Mints some token ID for a user, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * @param _to Address of the user to mint the token for.\n * @param _tokenId Token ID to mint.\n */\n function safeMint(address _to, uint256 _tokenId) external;\n\n /**\n * @notice Burns a token ID from a user.\n *\n * @param _from Address of the user to burn the token from.\n * @param _tokenId Token ID to burn.\n */\n function burn(address _from, uint256 _tokenId) external;\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function REMOTE_CHAIN_ID() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function REMOTE_TOKEN() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function BRIDGE() external view returns (address);\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function remoteChainId() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function remoteToken() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function bridge() external view returns (address);\n}\n" - }, - "contracts/universal/OptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { ILegacyMintableERC20, IOptimismMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC20\n * @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed\n * to allow the StandardBridge contracts to mint and burn tokens. This makes it possible to\n * use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa.\n * Designed to be backwards compatible with the older StandardL2ERC20 token which was only\n * meant for use on L2.\n */\ncontract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, Semver {\n /**\n * @notice Address of the corresponding version of this token on the remote chain.\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @notice Address of the StandardBridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Emitted whenever tokens are minted for an account.\n *\n * @param account Address of the account tokens are being minted for.\n * @param amount Amount of tokens minted.\n */\n event Mint(address indexed account, uint256 amount);\n\n /**\n * @notice Emitted whenever tokens are burned from an account.\n *\n * @param account Address of the account tokens are being burned from.\n * @param amount Amount of tokens burned.\n */\n event Burn(address indexed account, uint256 amount);\n\n /**\n * @notice A modifier that only allows the bridge to call\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC20: only bridge can mint and burn\");\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the L2 standard bridge.\n * @param _remoteToken Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _bridge,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) Semver(1, 0, 0) {\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n }\n\n /**\n * @notice Allows the StandardBridge on this network to mint tokens.\n *\n * @param _to Address to mint tokens to.\n * @param _amount Amount of tokens to mint.\n */\n function mint(address _to, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _mint(_to, _amount);\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Allows the StandardBridge on this network to burn tokens.\n *\n * @param _from Address to burn tokens from.\n * @param _amount Amount of tokens to burn.\n */\n function burn(address _from, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _burn(_from, _amount);\n emit Burn(_from, _amount);\n }\n\n /**\n * @notice ERC165 interface check function.\n *\n * @param _interfaceId Interface ID to check.\n *\n * @return Whether or not the interface is supported by this contract.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 iface1 = type(IERC165).interfaceId;\n // Interface corresponding to the legacy L2StandardERC20.\n bytes4 iface2 = type(ILegacyMintableERC20).interfaceId;\n // Interface corresponding to the updated OptimismMintableERC20 (this contract).\n bytes4 iface3 = type(IOptimismMintableERC20).interfaceId;\n return _interfaceId == iface1 || _interfaceId == iface2 || _interfaceId == iface3;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote token. Use REMOTE_TOKEN going forward.\n */\n function l1Token() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the bridge. Use BRIDGE going forward.\n */\n function l2Bridge() public view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for REMOTE_TOKEN.\n */\n function remoteToken() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for BRIDGE.\n */\n function bridge() public view returns (address) {\n return BRIDGE;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC20Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Contract Imports */\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000012\n * @title OptimismMintableERC20Factory\n * @notice OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20\n * contracts on the network it's deployed to. Simplifies the deployment process for users\n * who may be less familiar with deploying smart contracts. Designed to be backwards\n * compatible with the older StandardL2ERC20Factory contract.\n */\ncontract OptimismMintableERC20Factory is Semver {\n /**\n * @notice Address of the StandardBridge on this chain.\n */\n address public immutable BRIDGE;\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a new OptimismMintableERC20 is created. Legacy version of the newer\n * OptimismMintableERC20Created event. We recommend relying on that event instead.\n *\n * @param remoteToken Address of the token on the remote chain.\n * @param localToken Address of the created token on the local chain.\n */\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC20 is created.\n *\n * @param localToken Address of the created token on the local chain.\n * @param remoteToken Address of the corresponding token on the remote chain.\n * @param deployer Address of the account that deployed the token.\n */\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC20 token contract since this contract\n * is responsible for deploying OptimismMintableERC20 contracts.\n *\n * @param _bridge Address of the StandardBridge on this chain.\n */\n constructor(address _bridge) Semver(1, 1, 0) {\n BRIDGE = _bridge;\n }\n\n /**\n * @custom:legacy\n * @notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the\n * newer createOptimismMintableERC20 function, which has a more intuitive name.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createStandardL2Token(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n return createOptimismMintableERC20(_remoteToken, _name, _symbol);\n }\n\n /**\n * @notice Creates an instance of the OptimismMintableERC20 contract.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createOptimismMintableERC20(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) public returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC20Factory: must provide remote token address\"\n );\n\n address localToken = address(\n new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol)\n );\n\n // Emit the old event too for legacy support.\n emit StandardL2TokenCreated(_remoteToken, localToken);\n\n // Emit the updated event. The arguments here differ from the legacy event, but\n // are consistent with the ordering used in StandardBridge events.\n emit OptimismMintableERC20Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n ERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { IOptimismMintableERC721 } from \"./IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC721\n * @notice This contract is the remote representation for some token that lives on another network,\n * typically an Optimism representation of an Ethereum-based token. Standard reference\n * implementation that can be extended or modified according to your needs.\n */\ncontract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Semver {\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Base token URI for this token.\n */\n string public baseTokenURI;\n\n /**\n * @notice Modifier that prevents callers other than the bridge from calling the function.\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC721: only bridge can call this function\");\n _;\n }\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _bridge Address of the bridge on this network.\n * @param _remoteChainId Chain ID where the remote token is deployed.\n * @param _remoteToken Address of the corresponding token on the other network.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n constructor(\n address _bridge,\n uint256 _remoteChainId,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) Semver(1, 1, 0) {\n require(_bridge != address(0), \"OptimismMintableERC721: bridge cannot be address(0)\");\n require(_remoteChainId != 0, \"OptimismMintableERC721: remote chain id cannot be zero\");\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721: remote token cannot be address(0)\"\n );\n\n REMOTE_CHAIN_ID = _remoteChainId;\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n\n // Creates a base URI in the format specified by EIP-681:\n // https://eips.ethereum.org/EIPS/eip-681\n baseTokenURI = string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(_remoteToken), 20),\n \"@\",\n Strings.toString(_remoteChainId),\n \"/tokenURI?uint256=\"\n )\n );\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteChainId() external view returns (uint256) {\n return REMOTE_CHAIN_ID;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteToken() external view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function bridge() external view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function safeMint(address _to, uint256 _tokenId) external virtual onlyBridge {\n _safeMint(_to, _tokenId);\n\n emit Mint(_to, _tokenId);\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function burn(address _from, uint256 _tokenId) external virtual onlyBridge {\n _burn(_tokenId);\n\n emit Burn(_from, _tokenId);\n }\n\n /**\n * @notice Checks if a given interface ID is supported by this contract.\n *\n * @param _interfaceId The interface ID to check.\n *\n * @return True if the interface ID is supported, false otherwise.\n */\n function supportsInterface(bytes4 _interfaceId)\n public\n view\n override(ERC721Enumerable, IERC165)\n returns (bool)\n {\n bytes4 iface = type(IOptimismMintableERC721).interfaceId;\n return _interfaceId == iface || super.supportsInterface(_interfaceId);\n }\n\n /**\n * @notice Returns the base token URI.\n *\n * @return Base token URI.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return baseTokenURI;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismMintableERC721 } from \"./OptimismMintableERC721.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @title OptimismMintableERC721Factory\n * @notice Factory contract for creating OptimismMintableERC721 contracts.\n */\ncontract OptimismMintableERC721Factory is Semver {\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Chain ID for the remote network.\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @notice Tracks addresses created by this factory.\n */\n mapping(address => bool) public isOptimismMintableERC721;\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC721 contract is created.\n *\n * @param localToken Address of the token on the this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param deployer Address of the initiator of the deployment\n */\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.2.0\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC721 token contract since this contract\n * is responsible for deploying OptimismMintableERC721 contracts.\n *\n * @param _bridge Address of the ERC721 bridge on this network.\n * @param _remoteChainId Chain ID for the remote network.\n */\n constructor(address _bridge, uint256 _remoteChainId) Semver(1, 2, 0) {\n BRIDGE = _bridge;\n REMOTE_CHAIN_ID = _remoteChainId;\n }\n\n /**\n * @notice Creates an instance of the standard ERC721.\n *\n * @param _remoteToken Address of the corresponding token on the other domain.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n function createOptimismMintableERC721(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721Factory: L1 token address cannot be address(0)\"\n );\n\n address localToken = address(\n new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)\n );\n\n isOptimismMintableERC721[localToken] = true;\n emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/Proxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Proxy\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\n * if the caller is address(0), meaning that the call originated from an off-chain\n * simulation.\n */\ncontract Proxy {\n /**\n * @notice The storage slot that holds the address of the implementation.\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice The storage slot that holds the address of the owner.\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice An event that is emitted each time the implementation is changed. This event is part\n * of the EIP-1967 specification.\n *\n * @param implementation The address of the implementation contract\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\n * EIP-1967 specification.\n *\n * @param previousAdmin The previous owner of the contract\n * @param newAdmin The new owner of the contract\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\n * eth_call to interact with this proxy without needing to use low-level storage\n * inspection. We assume that nobody is able to trigger calls from address(0) during\n * normal EVM execution.\n */\n modifier proxyCallIfNotAdmin() {\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\n * EIP-1967 admin storage slot so that accidental storage collision with the\n * implementation is not possible.\n *\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\n * transparent proxy interface.\n */\n constructor(address _admin) {\n _changeAdmin(_admin);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Set the implementation contract address. The code at the given address will execute\n * when this contract is called.\n *\n * @param _implementation Address of the implementation contract.\n */\n function upgradeTo(address _implementation) public virtual proxyCallIfNotAdmin {\n _setImplementation(_implementation);\n }\n\n /**\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\n * atomic execution of initialization-based upgrades.\n *\n * @param _implementation Address of the implementation contract.\n * @param _data Calldata to delegatecall the new implementation with.\n */\n function upgradeToAndCall(address _implementation, bytes calldata _data)\n public\n payable\n virtual\n proxyCallIfNotAdmin\n returns (bytes memory)\n {\n _setImplementation(_implementation);\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\n require(success, \"Proxy: delegatecall to new implementation contract failed\");\n return returndata;\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _admin New owner of the proxy contract.\n */\n function changeAdmin(address _admin) public virtual proxyCallIfNotAdmin {\n _changeAdmin(_admin);\n }\n\n /**\n * @notice Gets the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function admin() public virtual proxyCallIfNotAdmin returns (address) {\n return _getAdmin();\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function implementation() public virtual proxyCallIfNotAdmin returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n emit Upgraded(_implementation);\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _admin New owner of the proxy contract.\n */\n function _changeAdmin(address _admin) internal {\n address previous = _getAdmin();\n assembly {\n sstore(OWNER_KEY, _admin)\n }\n emit AdminChanged(previous, _admin);\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal {\n address impl = _getImplementation();\n require(impl != address(0), \"Proxy: implementation not initialized\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address impl;\n assembly {\n impl := sload(IMPLEMENTATION_KEY)\n }\n return impl;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getAdmin() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n}\n" - }, - "contracts/universal/ProxyAdmin.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { Proxy } from \"./Proxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\n\n/**\n * @title IStaticERC1967Proxy\n * @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface.\n */\ninterface IStaticERC1967Proxy {\n function implementation() external view returns (address);\n\n function admin() external view returns (address);\n}\n\n/**\n * @title IStaticL1ChugSplashProxy\n * @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface.\n */\ninterface IStaticL1ChugSplashProxy {\n function getImplementation() external view returns (address);\n\n function getOwner() external view returns (address);\n}\n\n/**\n * @title ProxyAdmin\n * @notice This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy,\n * based on the OpenZeppelin implementation. It has backwards compatibility logic to work\n * with the various types of proxies that have been deployed by Optimism in the past.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @notice The proxy types that the ProxyAdmin can manage.\n *\n * @custom:value ERC1967 Represents an ERC1967 compliant transparent proxy interface.\n * @custom:value CHUGSPLASH Represents the Chugsplash proxy interface (legacy).\n * @custom:value RESOLVED Represents the ResolvedDelegate proxy (legacy).\n */\n enum ProxyType {\n ERC1967,\n CHUGSPLASH,\n RESOLVED\n }\n\n /**\n * @notice A mapping of proxy types, used for backwards compatibility.\n */\n mapping(address => ProxyType) public proxyType;\n\n /**\n * @notice A reverse mapping of addresses to names held in the AddressManager. This must be\n * manually kept up to date with changes in the AddressManager for this contract\n * to be able to work as an admin for the ResolvedDelegateProxy type.\n */\n mapping(address => string) public implementationName;\n\n /**\n * @notice The address of the address manager, this is required to manage the\n * ResolvedDelegateProxy type.\n */\n AddressManager public addressManager;\n\n /**\n * @notice A legacy upgrading indicator used by the old Chugsplash Proxy.\n */\n bool internal upgrading;\n\n /**\n * @param _owner Address of the initial owner of this contract.\n */\n constructor(address _owner) Ownable() {\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the proxy type for a given address. Only required for non-standard (legacy)\n * proxy types.\n *\n * @param _address Address of the proxy.\n * @param _type Type of the proxy.\n */\n function setProxyType(address _address, ProxyType _type) external onlyOwner {\n proxyType[_address] = _type;\n }\n\n /**\n * @notice Sets the implementation name for a given address. Only required for\n * ResolvedDelegateProxy type proxies that have an implementation name.\n *\n * @param _address Address of the ResolvedDelegateProxy.\n * @param _name Name of the implementation for the proxy.\n */\n function setImplementationName(address _address, string memory _name) external onlyOwner {\n implementationName[_address] = _name;\n }\n\n /**\n * @notice Set the address of the AddressManager. This is required to manage legacy\n * ResolvedDelegateProxy type proxy contracts.\n *\n * @param _address Address of the AddressManager.\n */\n function setAddressManager(AddressManager _address) external onlyOwner {\n addressManager = _address;\n }\n\n /**\n * @custom:legacy\n * @notice Set an address in the address manager. Since only the owner of the AddressManager\n * can directly modify addresses and the ProxyAdmin will own the AddressManager, this\n * gives the owner of the ProxyAdmin the ability to modify addresses directly.\n *\n * @param _name Name to set within the AddressManager.\n * @param _address Address to attach to the given name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n addressManager.setAddress(_name, _address);\n }\n\n /**\n * @custom:legacy\n * @notice Set the upgrading status for the Chugsplash proxy type.\n *\n * @param _upgrading Whether or not the system is upgrading.\n */\n function setUpgrading(bool _upgrading) external onlyOwner {\n upgrading = _upgrading;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\n *\n * @return Whether or not there is an upgrade going on. May not actually tell you whether an\n * upgrade is going on, since we don't currently plan to use this variable for anything\n * other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\n */\n function isUpgrading() external view returns (bool) {\n return upgrading;\n }\n\n /**\n * @notice Returns the implementation of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the implementation of.\n *\n * @return Address of the implementation of the proxy.\n */\n function getProxyImplementation(address _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).implementation();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getImplementation();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.getAddress(implementationName[_proxy]);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Returns the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the admin of.\n *\n * @return Address of the admin of the proxy.\n */\n function getProxyAdmin(address payable _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).admin();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getOwner();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.owner();\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Updates the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to update.\n * @param _newAdmin Address of the new proxy admin.\n */\n function changeProxyAdmin(address payable _proxy, address _newAdmin) external onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).changeAdmin(_newAdmin);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setOwner(_newAdmin);\n } else if (ptype == ProxyType.RESOLVED) {\n addressManager.transferOwnership(_newAdmin);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n */\n function upgrade(address payable _proxy, address _implementation) public onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeTo(_implementation);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setStorage(\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n bytes32(uint256(uint160(_implementation)))\n );\n } else if (ptype == ProxyType.RESOLVED) {\n string memory name = implementationName[_proxy];\n addressManager.setAddress(name, _implementation);\n } else {\n // It should not be possible to retrieve a ProxyType value which is not matched by\n // one of the previous conditions.\n assert(false);\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract and delegatecalls the new implementation\n * with some given data. Useful for atomic upgrade-and-initialize calls.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n * @param _data Data to trigger the new implementation with.\n */\n function upgradeAndCall(\n address payable _proxy,\n address _implementation,\n bytes memory _data\n ) external payable onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);\n } else {\n // reverts if proxy type is unknown\n upgrade(_proxy, _implementation);\n (bool success, ) = _proxy.call{ value: msg.value }(_data);\n require(success, \"ProxyAdmin: call to proxy after upgrade failed\");\n }\n }\n}\n" - }, - "contracts/universal/Semver.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n" - }, - "contracts/universal/StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { IOptimismMintableERC20, ILegacyMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"./OptimismMintableERC20.sol\";\n\n/**\n * @custom:upgradeable\n * @title StandardBridge\n * @notice StandardBridge is a base contract for the L1 and L2 standard ERC20 bridges. It handles\n * the core bridging logic, including escrowing tokens that are native to the local chain\n * and minting/burning tokens that are native to the remote chain.\n */\nabstract contract StandardBridge {\n using SafeERC20 for IERC20;\n\n /**\n * @notice The L2 gas limit set when eth is depoisited using the receive() function.\n */\n uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000;\n\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Corresponding bridge on the other domain.\n */\n StandardBridge public immutable OTHER_BRIDGE;\n\n /**\n * @custom:legacy\n * @custom:spacer messenger\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer l2TokenBridge\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_1_0_20;\n\n /**\n * @notice Mapping that stores deposits for a given pair of local and remote tokens.\n */\n mapping(address => mapping(address => uint256)) public deposits;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n * A gap size of 47 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[47] private __gap;\n\n /**\n * @notice Emitted when an ETH bridge is initiated to the other chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ETH bridge is finalized on this chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is initiated to the other chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is finalized on this chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Only allow EOAs to call the functions. Note that this is not safe against contracts\n * calling code within their constructors, but also doesn't really matter since we're\n * just trying to prevent users accidentally depositing with smart contract wallets.\n */\n modifier onlyEOA() {\n require(\n !Address.isContract(msg.sender),\n \"StandardBridge: function can only be called from an EOA\"\n );\n _;\n }\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) &&\n MESSENGER.xDomainMessageSender() == address(OTHER_BRIDGE),\n \"StandardBridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of CrossDomainMessenger on this network.\n * @param _otherBridge Address of the other StandardBridge contract.\n */\n constructor(address payable _messenger, address payable _otherBridge) {\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = StandardBridge(_otherBridge);\n }\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n * Must be implemented by contracts that inherit.\n */\n receive() external payable virtual;\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @notice Sends ETH to the sender's address on the other chain.\n *\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETH(uint32 _minGasLimit, bytes calldata _extraData) public payable onlyEOA {\n _initiateBridgeETH(msg.sender, msg.sender, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a\n * smart contract and the call fails, the ETH will be temporarily locked in the\n * StandardBridge on the other chain until the call is replayed. If the call cannot be\n * replayed with any amount of gas (call always reverts), then the ETH will be\n * permanently locked in the StandardBridge on the other chain. ETH will also\n * be locked if the receiver is the other bridge, because finalizeBridgeETH will revert\n * in that case.\n *\n * @param _to Address of the receiver.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public payable {\n _initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ERC20 tokens to the sender's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20(\n address _localToken,\n address _remoteToken,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual onlyEOA {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public payable onlyOtherBridge {\n require(msg.value == _amount, \"StandardBridge: amount sent does not match amount required\");\n require(_to != address(this), \"StandardBridge: cannot send to self\");\n require(_to != address(MESSENGER), \"StandardBridge: cannot send to messenger\");\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n\n bool success = SafeCall.call(_to, gasleft(), _amount, hex\"\");\n require(success, \"StandardBridge: ETH transfer failed\");\n }\n\n /**\n * @notice Finalizes an ERC20 bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public onlyOtherBridge {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).mint(_to, _amount);\n } else {\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] - _amount;\n IERC20(_localToken).safeTransfer(_to, _amount);\n }\n\n // Emit the correct events. By default this will be ERC20BridgeFinalized, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Initiates a bridge of ETH through the CrossDomainMessenger.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n require(\n msg.value == _amount,\n \"StandardBridge: bridging ETH must include sufficient ETH value\"\n );\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage{ value: _amount }(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeETH.selector,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).burn(_from, _amount);\n } else {\n IERC20(_localToken).safeTransferFrom(_from, address(this), _amount);\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] + _amount;\n }\n\n // Emit the correct events. By default this will be ERC20BridgeInitiated, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeERC20.selector,\n // Because this call will be executed on the remote chain, we reverse the order of\n // the remote and local token addresses relative to their order in the\n // finalizeBridgeERC20 function.\n _remoteToken,\n _localToken,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Checks if a given address is an OptimismMintableERC20. Not perfect, but good enough.\n * Just the way we like it.\n *\n * @param _token Address of the token to check.\n *\n * @return True if the token is an OptimismMintableERC20.\n */\n function _isOptimismMintableERC20(address _token) internal view returns (bool) {\n return\n ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId) ||\n ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);\n }\n\n /**\n * @notice Checks if the \"other token\" is the correct pair token for the OptimismMintableERC20.\n * Calls can be saved in the future by combining this logic with\n * `_isOptimismMintableERC20`.\n *\n * @param _mintableToken OptimismMintableERC20 to check against.\n * @param _otherToken Pair token to check.\n *\n * @return True if the other token is the correct pair token for the OptimismMintableERC20.\n */\n function _isCorrectTokenPair(address _mintableToken, address _otherToken)\n internal\n view\n returns (bool)\n {\n if (\n ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)\n ) {\n return _otherToken == ILegacyMintableERC20(_mintableToken).l1Token();\n } else {\n return _otherToken == IOptimismMintableERC20(_mintableToken).remoteToken();\n }\n }\n\n /** @notice Emits the ETHBridgeInitiated event and if necessary the appropriate legacy event\n * when an ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ETHBridgeFinalized and if necessary the appropriate legacy event when an\n * ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeInitiated event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeFinalized event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/vendor/AddressAliasHelper.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.0;\n\nlibrary AddressAliasHelper {\n uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n /// @notice Utility function that converts the address in the L1 that submitted a tx to\n /// the inbox to the msg.sender viewed in the L2\n /// @param l1Address the address in the L1 that triggered the tx to L2\n /// @return l2Address L2 address as viewed in msg.sender\n function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {\n unchecked {\n l2Address = address(uint160(l1Address) + offset);\n }\n }\n\n /// @notice Utility function that converts the msg.sender viewed in the L2 to the\n /// address in the L1 that submitted a tx to the inbox\n /// @param l2Address L2 address as viewed in msg.sender\n /// @return l1Address the address in the L1 that triggered the tx to L2\n function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {\n unchecked {\n l1Address = address(uint160(l2Address) - offset);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/governance/utils/IVotes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20Permit.sol\";\nimport \"../../../utils/math/Math.sol\";\nimport \"../../../governance/utils/IVotes.sol\";\nimport \"../../../utils/math/SafeCast.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20Votes is IVotes, ERC20Permit {\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCast.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = Math.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSA.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"./IERC721Enumerable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n // Mapping from owner to list of owned token IDs\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n // Mapping from token ID to index of the owner tokens list\n mapping(uint256 => uint256) private _ownedTokensIndex;\n\n // Array with all token ids, used for enumeration\n uint256[] private _allTokens;\n\n // Mapping from token id to position in the allTokens array\n mapping(uint256 => uint256) private _allTokensIndex;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n return _ownedTokens[owner][index];\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _allTokens.length;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721Enumerable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n return _allTokens[index];\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n if (from == address(0)) {\n _addTokenToAllTokensEnumeration(tokenId);\n } else if (from != to) {\n _removeTokenFromOwnerEnumeration(from, tokenId);\n }\n if (to == address(0)) {\n _removeTokenFromAllTokensEnumeration(tokenId);\n } else if (to != from) {\n _addTokenToOwnerEnumeration(to, tokenId);\n }\n }\n\n /**\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\n * @param to address representing the new owner of the given token ID\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n */\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n uint256 length = ERC721.balanceOf(to);\n _ownedTokens[to][length] = tokenId;\n _ownedTokensIndex[tokenId] = length;\n }\n\n /**\n * @dev Private function to add a token to this extension's token tracking data structures.\n * @param tokenId uint256 ID of the token to be added to the tokens list\n */\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n _allTokensIndex[tokenId] = _allTokens.length;\n _allTokens.push(tokenId);\n }\n\n /**\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n * @param from address representing the previous owner of the given token ID\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n */\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary\n if (tokenIndex != lastTokenIndex) {\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n }\n\n // This also deletes the contents at the last position of the array\n delete _ownedTokensIndex[tokenId];\n delete _ownedTokens[from][lastTokenIndex];\n }\n\n /**\n * @dev Private function to remove a token from this extension's token tracking data structures.\n * This has O(1) time complexity, but alters the order of the _allTokens array.\n * @param tokenId uint256 ID of the token to be removed from the tokens list\n */\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = _allTokens.length - 1;\n uint256 tokenIndex = _allTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n // This also deletes the contents at the last position of the array\n delete _allTokensIndex[tokenId];\n _allTokens.pop();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Counters.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface,\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n _supportsERC165Interface(account, type(IERC165).interfaceId) &&\n !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)\n internal\n view\n returns (bool[] memory)\n {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in _interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!_supportsERC165Interface(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n * Interface identification is specified in ERC-165.\n */\n function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/Bytes32AddressLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Library for converting between addresses and bytes32 values.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)\nlibrary Bytes32AddressLib {\n function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {\n return bytes32(bytes20(addressValue));\n }\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n /*//////////////////////////////////////////////////////////////\n SIMPLIFIED FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n }\n\n function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n }\n\n function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n }\n\n function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n }\n\n function powWad(int256 x, int256 y) internal pure returns (int256) {\n // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\n return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\n }\n\n function expWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n // When the result is < 0.5 we return zero. This happens when\n // x <= floor(log(0.5e18) * 1e18) ~ -42e18\n if (x <= -42139678854452767551) return 0;\n\n // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\n // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\n if (x >= 135305999368893231589) revert(\"EXP_OVERFLOW\");\n\n // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\n // for more intermediate precision and a binary basis. This base conversion\n // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n x = (x << 78) / 5**18;\n\n // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\n x = x - k * 54916777467707473351141471128;\n\n // k is in the range [-61, 195].\n\n // Evaluate using a (6, 7)-term rational approximation.\n // p is made monic, we'll multiply by a scale factor later.\n int256 y = x + 1346386616545796478920950773328;\n y = ((y * x) >> 96) + 57155421227552351082224309758442;\n int256 p = y + x - 94201549194550492254356042504812;\n p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n p = p * x + (4385272521454847904659076985693276 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n int256 q = x - 2855989394907223263936484059900;\n q = ((q * x) >> 96) + 50020603652535783019961831881945;\n q = ((q * x) >> 96) - 533845033583426703283633433725380;\n q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial won't have zeros in the domain as all its roots are complex.\n // No scaling is necessary because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r should be in the range (0.09, 0.25) * 2**96.\n\n // We now need to multiply r by:\n // * the scale factor s = ~6.031367120.\n // * the 2**k factor from the range reduction.\n // * the 1e18 / 2**96 factor for base conversion.\n // We do this all at once, with an intermediate result in 2**213\n // basis, so the final right shift is always by a positive amount.\n r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\n }\n }\n\n function lnWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n require(x > 0, \"UNDEFINED\");\n\n // We want to convert x from 10**18 fixed point to 2**96 fixed point.\n // We do this by multiplying by 2**96 / 10**18. But since\n // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\n // and add ln(2**96 / 10**18) at the end.\n\n // Reduce range of x to (1, 2) * 2**96\n // ln(2^k * x) = k * ln(2) + ln(x)\n int256 k = int256(log2(uint256(x))) - 96;\n x <<= uint256(159 - k);\n x = int256(uint256(x) >> 159);\n\n // Evaluate using a (8, 8)-term rational approximation.\n // p is made monic, we will multiply by a scale factor later.\n int256 p = x + 3273285459638523848632254066296;\n p = ((p * x) >> 96) + 24828157081833163892658089445524;\n p = ((p * x) >> 96) + 43456485725739037958740375743393;\n p = ((p * x) >> 96) - 11111509109440967052023855526967;\n p = ((p * x) >> 96) - 45023709667254063763336534515857;\n p = ((p * x) >> 96) - 14706773417378608786704636184526;\n p = p * x - (795164235651350426258249787498 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n // q is monic by convention.\n int256 q = x + 5573035233440673466300451813936;\n q = ((q * x) >> 96) + 71694874799317883764090561454958;\n q = ((q * x) >> 96) + 283447036172924575727196451306956;\n q = ((q * x) >> 96) + 401686690394027663651624208769553;\n q = ((q * x) >> 96) + 204048457590392012362485061816622;\n q = ((q * x) >> 96) + 31853899698501571402653359427138;\n q = ((q * x) >> 96) + 909429971244387300277376558375;\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial is known not to have zeros in the domain.\n // No scaling required because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r is in the range (0, 0.125) * 2**96\n\n // Finalization, we need to:\n // * multiply by the scale factor s = 5.549…\n // * add ln(2**96 / 10**18)\n // * add k * ln(2)\n // * multiply by 10**18 / 2**96 = 5**18 >> 78\n\n // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\n r *= 1677202110996718588342820967067443963516166;\n // add ln(2) * k * 5e18 * 2**192\n r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\n // add ln(2**96 / 10**18) * 5e18 * 2**192\n r += 600920179829731861736702779321621459595472258049074101567377883020018308;\n // base conversion: mul 2**18 / 2**192\n r >>= 174;\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n LOW LEVEL FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function mulDivDown(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // Divide z by the denominator.\n z := div(z, denominator)\n }\n }\n\n function mulDivUp(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // First, divide z - 1 by the denominator and add 1.\n // We allow z - 1 to underflow if z is 0, because we multiply the\n // end result by 0 if z is zero, ensuring we return 0 if z is zero.\n z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\n }\n }\n\n function rpow(\n uint256 x,\n uint256 n,\n uint256 scalar\n ) internal pure returns (uint256 z) {\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n // 0 ** 0 = 1\n z := scalar\n }\n default {\n // 0 ** n = 0\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n // If n is even, store scalar in z for now.\n z := scalar\n }\n default {\n // If n is odd, store x in z for now.\n z := x\n }\n\n // Shifting right by 1 is like dividing by 2.\n let half := shr(1, scalar)\n\n for {\n // Shift n right by 1 before looping to halve it.\n n := shr(1, n)\n } n {\n // Shift n right by 1 each iteration to halve it.\n n := shr(1, n)\n } {\n // Revert immediately if x ** 2 would overflow.\n // Equivalent to iszero(eq(div(xx, x), x)) here.\n if shr(128, x) {\n revert(0, 0)\n }\n\n // Store x squared.\n let xx := mul(x, x)\n\n // Round to the nearest number.\n let xxRound := add(xx, half)\n\n // Revert if xx + half overflowed.\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n\n // Set x to scaled xxRound.\n x := div(xxRound, scalar)\n\n // If n is even:\n if mod(n, 2) {\n // Compute z * x.\n let zx := mul(z, x)\n\n // If z * x overflowed:\n if iszero(eq(div(zx, x), z)) {\n // Revert if x is non-zero.\n if iszero(iszero(x)) {\n revert(0, 0)\n }\n }\n\n // Round to the nearest number.\n let zxRound := add(zx, half)\n\n // Revert if zx + half overflowed.\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n\n // Return properly scaled zxRound.\n z := div(zxRound, scalar)\n }\n }\n }\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n GENERAL NUMBER UTILITIES\n //////////////////////////////////////////////////////////////*/\n\n function sqrt(uint256 x) internal pure returns (uint256 z) {\n assembly {\n let y := x // We start y at x, which will help us make our initial estimate.\n\n z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n // We check y >= 2^(k + 8) but shift right by k bits\n // each branch to ensure that if x >= 256, then y >= 256.\n if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n y := shr(128, y)\n z := shl(64, z)\n }\n if iszero(lt(y, 0x1000000000000000000)) {\n y := shr(64, y)\n z := shl(32, z)\n }\n if iszero(lt(y, 0x10000000000)) {\n y := shr(32, y)\n z := shl(16, z)\n }\n if iszero(lt(y, 0x1000000)) {\n y := shr(16, y)\n z := shl(8, z)\n }\n\n // Goal was to get z*z*y within a small factor of x. More iterations could\n // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n // There is no overflow risk here since y < 2^136 after the first branch above.\n z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n\n // If x+1 is a perfect square, the Babylonian method cycles between\n // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n z := sub(z, lt(div(x, z), z))\n }\n }\n\n function log2(uint256 x) internal pure returns (uint256 r) {\n require(x > 0, \"UNDEFINED\");\n\n assembly {\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\n r := or(r, shl(3, lt(0xff, shr(r, x))))\n r := or(r, shl(2, lt(0xf, shr(r, x))))\n r := or(r, shl(1, lt(0x3, shr(r, x))))\n r := or(r, lt(0x1, shr(r, x)))\n }\n }\n}\n" - }, - "node_modules/ds-test/src/test.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.5.0;\n\ncontract DSTest {\n event log (string);\n event logs (bytes);\n\n event log_address (address);\n event log_bytes32 (bytes32);\n event log_int (int);\n event log_uint (uint);\n event log_bytes (bytes);\n event log_string (string);\n\n event log_named_address (string key, address val);\n event log_named_bytes32 (string key, bytes32 val);\n event log_named_decimal_int (string key, int val, uint decimals);\n event log_named_decimal_uint (string key, uint val, uint decimals);\n event log_named_int (string key, int val);\n event log_named_uint (string key, uint val);\n event log_named_bytes (string key, bytes val);\n event log_named_string (string key, string val);\n\n bool public IS_TEST = true;\n bool private _failed;\n\n address constant HEVM_ADDRESS =\n address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));\n\n modifier mayRevert() { _; }\n modifier testopts(string memory) { _; }\n\n function failed() public returns (bool) {\n if (_failed) {\n return _failed;\n } else {\n bool globalFailed = false;\n if (hasHEVMContext()) {\n (, bytes memory retdata) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"load(address,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"))\n )\n );\n globalFailed = abi.decode(retdata, (bool));\n }\n return globalFailed;\n }\n } \n\n function fail() internal {\n if (hasHEVMContext()) {\n (bool status, ) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"store(address,bytes32,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"), bytes32(uint256(0x01)))\n )\n );\n status; // Silence compiler warnings\n }\n _failed = true;\n }\n\n function hasHEVMContext() internal view returns (bool) {\n uint256 hevmCodeSize = 0;\n assembly {\n hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D)\n }\n return hevmCodeSize > 0;\n }\n\n modifier logs_gas() {\n uint startGas = gasleft();\n _;\n uint endGas = gasleft();\n emit log_named_uint(\"gas\", startGas - endGas);\n }\n\n function assertTrue(bool condition) internal {\n if (!condition) {\n emit log(\"Error: Assertion Failed\");\n fail();\n }\n }\n\n function assertTrue(bool condition, string memory err) internal {\n if (!condition) {\n emit log_named_string(\"Error\", err);\n assertTrue(condition);\n }\n }\n\n function assertEq(address a, address b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [address]\");\n emit log_named_address(\" Expected\", b);\n emit log_named_address(\" Actual\", a);\n fail();\n }\n }\n function assertEq(address a, address b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes32 a, bytes32 b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bytes32]\");\n emit log_named_bytes32(\" Expected\", b);\n emit log_named_bytes32(\" Actual\", a);\n fail();\n }\n }\n function assertEq(bytes32 a, bytes32 b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq32(bytes32 a, bytes32 b) internal {\n assertEq(a, b);\n }\n function assertEq32(bytes32 a, bytes32 b, string memory err) internal {\n assertEq(a, b, err);\n }\n\n function assertEq(int a, int b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [int]\");\n emit log_named_int(\" Expected\", b);\n emit log_named_int(\" Actual\", a);\n fail();\n }\n }\n function assertEq(int a, int b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq(uint a, uint b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [uint]\");\n emit log_named_uint(\" Expected\", b);\n emit log_named_uint(\" Actual\", a);\n fail();\n }\n }\n function assertEq(uint a, uint b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEqDecimal(int a, int b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Expected\", b, decimals);\n emit log_named_decimal_int(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Expected\", b, decimals);\n emit log_named_decimal_uint(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n\n function assertGt(uint a, uint b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGt(uint a, uint b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGt(int a, int b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGt(int a, int b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGtDecimal(int a, int b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n\n function assertGe(uint a, uint b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGe(uint a, uint b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGe(int a, int b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGe(int a, int b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGeDecimal(int a, int b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertLt(uint a, uint b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLt(uint a, uint b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLt(int a, int b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLt(int a, int b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLtDecimal(int a, int b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n\n function assertLe(uint a, uint b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLe(uint a, uint b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLe(int a, int b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLe(int a, int b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLeDecimal(int a, int b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLeDecimal(a, b, decimals);\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertEq(string memory a, string memory b) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log(\"Error: a == b not satisfied [string]\");\n emit log_named_string(\" Expected\", b);\n emit log_named_string(\" Actual\", a);\n fail();\n }\n }\n function assertEq(string memory a, string memory b, string memory err) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {\n ok = true;\n if (a.length == b.length) {\n for (uint i = 0; i < a.length; i++) {\n if (a[i] != b[i]) {\n ok = false;\n }\n }\n } else {\n ok = false;\n }\n }\n function assertEq0(bytes memory a, bytes memory b) internal {\n if (!checkEq0(a, b)) {\n emit log(\"Error: a == b not satisfied [bytes]\");\n emit log_named_bytes(\" Expected\", b);\n emit log_named_bytes(\" Actual\", a);\n fail();\n }\n }\n function assertEq0(bytes memory a, bytes memory b, string memory err) internal {\n if (!checkEq0(a, b)) {\n emit log_named_string(\"Error\", err);\n assertEq0(a, b);\n }\n }\n}\n" - }, - "node_modules/forge-std/src/Base.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {StdStorage} from \"./StdStorage.sol\";\nimport {Vm, VmSafe} from \"./Vm.sol\";\n\nabstract contract CommonBase {\n // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.\n address internal constant VM_ADDRESS = address(uint160(uint256(keccak256(\"hevm cheat code\"))));\n // console.sol and console2.sol work by executing a staticcall to this address.\n address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;\n // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38.\n address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256(\"foundry default caller\"))));\n // Address of the test contract, deployed by the DEFAULT_SENDER.\n address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;\n // Deterministic deployment address of the Multicall3 contract.\n address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11;\n\n uint256 internal constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n Vm internal constant vm = Vm(VM_ADDRESS);\n StdStorage internal stdstore;\n}\n\nabstract contract TestBase is CommonBase {}\n\nabstract contract ScriptBase is CommonBase {\n // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);\n}\n" - }, - "node_modules/forge-std/src/StdAssertions.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {DSTest} from \"ds-test/test.sol\";\nimport {stdMath} from \"./StdMath.sol\";\n\nabstract contract StdAssertions is DSTest {\n event log_array(uint256[] val);\n event log_array(int256[] val);\n event log_array(address[] val);\n event log_named_array(string key, uint256[] val);\n event log_named_array(string key, int256[] val);\n event log_named_array(string key, address[] val);\n\n function fail(string memory err) internal virtual {\n emit log_named_string(\"Error\", err);\n fail();\n }\n\n function assertFalse(bool data) internal virtual {\n assertTrue(!data);\n }\n\n function assertFalse(bool data, string memory err) internal virtual {\n assertTrue(!data, err);\n }\n\n function assertEq(bool a, bool b) internal virtual {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bool]\");\n emit log_named_string(\" Left\", a ? \"true\" : \"false\");\n emit log_named_string(\" Right\", b ? \"true\" : \"false\");\n fail();\n }\n }\n\n function assertEq(bool a, bool b, string memory err) internal virtual {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes memory a, bytes memory b) internal virtual {\n assertEq0(a, b);\n }\n\n function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual {\n assertEq0(a, b, err);\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [uint[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [int[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(address[] memory a, address[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [address[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n // Legacy helper\n function assertEqUint(uint256 a, uint256 b) internal virtual {\n assertEq(uint256(a), uint256(b));\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100%\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals,\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual {\n assertEqCall(target, callDataA, target, callDataB, true);\n }\n\n function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB)\n internal\n virtual\n {\n assertEqCall(targetA, callDataA, targetB, callDataB, true);\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData)\n internal\n virtual\n {\n assertEqCall(target, callDataA, target, callDataB, strictRevertData);\n }\n\n function assertEqCall(\n address targetA,\n bytes memory callDataA,\n address targetB,\n bytes memory callDataB,\n bool strictRevertData\n ) internal virtual {\n (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA);\n (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB);\n\n if (successA && successB) {\n assertEq(returnDataA, returnDataB, \"Call return data does not match\");\n }\n\n if (!successA && !successB && strictRevertData) {\n assertEq(returnDataA, returnDataB, \"Call revert data does not match\");\n }\n\n if (!successA && successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call revert data\", returnDataA);\n emit log_named_bytes(\" Right call return data\", returnDataB);\n fail();\n }\n\n if (successA && !successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call return data\", returnDataA);\n emit log_named_bytes(\" Right call revert data\", returnDataB);\n fail();\n }\n }\n}\n" - }, - "node_modules/forge-std/src/StdChains.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n/**\n * StdChains provides information about EVM compatible chains that can be used in scripts/tests.\n * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are\n * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of\n * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the\n * alias used in this contract, which can be found as the first argument to the\n * `setChainWithDefaultRpcUrl` call in the `initialize` function.\n *\n * There are two main ways to use this contract:\n * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or\n * `setChain(string memory chainAlias, Chain memory chain)`\n * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`.\n *\n * The first time either of those are used, chains are initialized with the default set of RPC URLs.\n * This is done in `initialize`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in\n * `defaultRpcUrls`.\n *\n * The `setChain` function is straightforward, and it simply saves off the given chain data.\n *\n * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say\n * we want to retrieve `mainnet`'s RPC URL:\n * - If you haven't set any mainnet chain info with `setChain`, you haven't specified that\n * chain in `foundry.toml` and no env var is set, the default data and RPC URL will be returned.\n * - If you have set a mainnet RPC URL in `foundry.toml` it will return that, if valid (e.g. if\n * a URL is given or if an environment variable is given and that environment variable exists).\n * Otherwise, the default data is returned.\n * - If you specified data with `setChain` it will return that.\n *\n * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.\n */\nabstract contract StdChains {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private initialized;\n\n struct ChainData {\n string name;\n uint256 chainId;\n string rpcUrl;\n }\n\n struct Chain {\n // The chain name.\n string name;\n // The chain's Chain ID.\n uint256 chainId;\n // The chain's alias. (i.e. what gets specified in `foundry.toml`).\n string chainAlias;\n // A default RPC endpoint for this chain.\n // NOTE: This default RPC URL is included for convenience to facilitate quick tests and\n // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy\n // usage as you will be throttled and this is a disservice to others who need this endpoint.\n string rpcUrl;\n }\n\n // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data.\n mapping(string => Chain) private chains;\n // Maps from the chain's alias to it's default RPC URL.\n mapping(string => string) private defaultRpcUrls;\n // Maps from a chain ID to it's alias.\n mapping(uint256 => string) private idToAlias;\n\n bool private fallbackToDefaultRpcUrls = true;\n\n // The RPC URL will be fetched from config or defaultRpcUrls if possible.\n function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) {\n require(bytes(chainAlias).length != 0, \"StdChains getChain(string): Chain alias cannot be the empty string.\");\n\n initialize();\n chain = chains[chainAlias];\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(string): Chain with alias \\\"\", chainAlias, \"\\\" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n function getChain(uint256 chainId) internal virtual returns (Chain memory chain) {\n require(chainId != 0, \"StdChains getChain(uint256): Chain ID cannot be 0.\");\n initialize();\n string memory chainAlias = idToAlias[chainId];\n\n chain = chains[chainAlias];\n\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(uint256): Chain with ID \", vm.toString(chainId), \" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, ChainData memory chain) internal virtual {\n require(\n bytes(chainAlias).length != 0,\n \"StdChains setChain(string,ChainData): Chain alias cannot be the empty string.\"\n );\n\n require(chain.chainId != 0, \"StdChains setChain(string,ChainData): Chain ID cannot be 0.\");\n\n initialize();\n string memory foundAlias = idToAlias[chain.chainId];\n\n require(\n bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)),\n string(\n abi.encodePacked(\n \"StdChains setChain(string,ChainData): Chain ID \",\n vm.toString(chain.chainId),\n \" already used by \\\"\",\n foundAlias,\n \"\\\".\"\n )\n )\n );\n\n uint256 oldChainId = chains[chainAlias].chainId;\n delete idToAlias[oldChainId];\n\n chains[chainAlias] =\n Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl});\n idToAlias[chain.chainId] = chainAlias;\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, Chain memory chain) internal virtual {\n setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl}));\n }\n\n function _toUpper(string memory str) private pure returns (string memory) {\n bytes memory strb = bytes(str);\n bytes memory copy = new bytes(strb.length);\n for (uint256 i = 0; i < strb.length; i++) {\n bytes1 b = strb[i];\n if (b >= 0x61 && b <= 0x7A) {\n copy[i] = bytes1(uint8(b) - 32);\n } else {\n copy[i] = b;\n }\n }\n return string(copy);\n }\n\n // lookup rpcUrl, in descending order of priority:\n // current -> config (foundry.toml) -> environment variable -> default\n function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) {\n if (bytes(chain.rpcUrl).length == 0) {\n try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) {\n chain.rpcUrl = configRpcUrl;\n } catch (bytes memory err) {\n string memory envName = string(abi.encodePacked(_toUpper(chainAlias), \"_RPC_URL\"));\n if (fallbackToDefaultRpcUrls) {\n chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]);\n } else {\n chain.rpcUrl = vm.envString(envName);\n }\n // distinguish 'not found' from 'cannot read'\n bytes memory notFoundError =\n abi.encodeWithSignature(\"CheatCodeError\", string(abi.encodePacked(\"invalid rpc url \", chainAlias)));\n if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, err), mload(err))\n }\n }\n }\n }\n return chain;\n }\n\n function setFallbackToDefaultRpcUrls(bool useDefault) internal {\n fallbackToDefaultRpcUrls = useDefault;\n }\n\n function initialize() private {\n if (initialized) return;\n\n initialized = true;\n\n // If adding an RPC here, make sure to test the default RPC URL in `testRpcs`\n setChainWithDefaultRpcUrl(\"anvil\", ChainData(\"Anvil\", 31337, \"http://127.0.0.1:8545\"));\n setChainWithDefaultRpcUrl(\n \"mainnet\", ChainData(\"Mainnet\", 1, \"https://mainnet.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"goerli\", ChainData(\"Goerli\", 5, \"https://goerli.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"sepolia\", ChainData(\"Sepolia\", 11155111, \"https://sepolia.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\"optimism\", ChainData(\"Optimism\", 10, \"https://mainnet.optimism.io\"));\n setChainWithDefaultRpcUrl(\"optimism_goerli\", ChainData(\"Optimism Goerli\", 420, \"https://goerli.optimism.io\"));\n setChainWithDefaultRpcUrl(\"arbitrum_one\", ChainData(\"Arbitrum One\", 42161, \"https://arb1.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\n \"arbitrum_one_goerli\", ChainData(\"Arbitrum One Goerli\", 421613, \"https://goerli-rollup.arbitrum.io/rpc\")\n );\n setChainWithDefaultRpcUrl(\"arbitrum_nova\", ChainData(\"Arbitrum Nova\", 42170, \"https://nova.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\"polygon\", ChainData(\"Polygon\", 137, \"https://polygon-rpc.com\"));\n setChainWithDefaultRpcUrl(\n \"polygon_mumbai\", ChainData(\"Polygon Mumbai\", 80001, \"https://rpc-mumbai.maticvigil.com\")\n );\n setChainWithDefaultRpcUrl(\"avalanche\", ChainData(\"Avalanche\", 43114, \"https://api.avax.network/ext/bc/C/rpc\"));\n setChainWithDefaultRpcUrl(\n \"avalanche_fuji\", ChainData(\"Avalanche Fuji\", 43113, \"https://api.avax-test.network/ext/bc/C/rpc\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain\", ChainData(\"BNB Smart Chain\", 56, \"https://bsc-dataseed1.binance.org\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain_testnet\",\n ChainData(\"BNB Smart Chain Testnet\", 97, \"https://rpc.ankr.com/bsc_testnet_chapel\")\n );\n setChainWithDefaultRpcUrl(\"gnosis_chain\", ChainData(\"Gnosis Chain\", 100, \"https://rpc.gnosischain.com\"));\n }\n\n // set chain info, with priority to chainAlias' rpc url in foundry.toml\n function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private {\n string memory rpcUrl = chain.rpcUrl;\n defaultRpcUrls[chainAlias] = rpcUrl;\n chain.rpcUrl = \"\";\n setChain(chainAlias, chain);\n chain.rpcUrl = rpcUrl; // restore argument\n }\n}\n" - }, - "node_modules/forge-std/src/StdCheats.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdCheatsSafe {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private gasMeteringOff;\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawTx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n // json value name = function\n string functionSig;\n bytes32 hash;\n // json value name = tx\n RawTx1559Detail txDetail;\n // json value name = type\n string opcode;\n }\n\n struct RawTx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n bytes gas;\n bytes nonce;\n address to;\n bytes txType;\n bytes value;\n }\n\n struct Tx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n bytes32 hash;\n Tx1559Detail txDetail;\n string opcode;\n }\n\n struct Tx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n uint256 gas;\n uint256 nonce;\n address to;\n uint256 txType;\n uint256 value;\n }\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct TxLegacy {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n string hash;\n string opcode;\n TxDetailLegacy transaction;\n }\n\n struct TxDetailLegacy {\n AccessList[] accessList;\n uint256 chainId;\n bytes data;\n address from;\n uint256 gas;\n uint256 gasPrice;\n bytes32 hash;\n uint256 nonce;\n bytes1 opcode;\n bytes32 r;\n bytes32 s;\n uint256 txType;\n address to;\n uint8 v;\n uint256 value;\n }\n\n struct AccessList {\n address accessAddress;\n bytes32[] storageKeys;\n }\n\n // Data structures to parse Receipt objects from the broadcast artifact.\n // The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawReceipt {\n bytes32 blockHash;\n bytes blockNumber;\n address contractAddress;\n bytes cumulativeGasUsed;\n bytes effectiveGasPrice;\n address from;\n bytes gasUsed;\n RawReceiptLog[] logs;\n bytes logsBloom;\n bytes status;\n address to;\n bytes32 transactionHash;\n bytes transactionIndex;\n }\n\n struct Receipt {\n bytes32 blockHash;\n uint256 blockNumber;\n address contractAddress;\n uint256 cumulativeGasUsed;\n uint256 effectiveGasPrice;\n address from;\n uint256 gasUsed;\n ReceiptLog[] logs;\n bytes logsBloom;\n uint256 status;\n address to;\n bytes32 transactionHash;\n uint256 transactionIndex;\n }\n\n // Data structures to parse the entire broadcast artifact, assuming the\n // transactions conform to EIP1559.\n\n struct EIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n Receipt[] receipts;\n uint256 timestamp;\n Tx1559[] transactions;\n TxReturn[] txReturns;\n }\n\n struct RawEIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n RawReceipt[] receipts;\n TxReturn[] txReturns;\n uint256 timestamp;\n RawTx1559[] transactions;\n }\n\n struct RawReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n bytes blockNumber;\n bytes data;\n bytes logIndex;\n bool removed;\n bytes32[] topics;\n bytes32 transactionHash;\n bytes transactionIndex;\n bytes transactionLogIndex;\n }\n\n struct ReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n uint256 blockNumber;\n bytes data;\n uint256 logIndex;\n bytes32[] topics;\n uint256 transactionIndex;\n uint256 transactionLogIndex;\n bool removed;\n }\n\n struct TxReturn {\n string internalType;\n string value;\n }\n\n function assumeNoPrecompiles(address addr) internal virtual {\n // Assembly required since `block.chainid` was introduced in 0.8.0.\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n assumeNoPrecompiles(addr, chainId);\n }\n\n function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual {\n // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific\n // address), but the same rationale for excluding them applies so we include those too.\n\n // These should be present on all EVM-compatible chains.\n vm.assume(addr < address(0x1) || addr > address(0x9));\n\n // forgefmt: disable-start\n if (chainId == 10 || chainId == 420) {\n // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21\n vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800));\n } else if (chainId == 42161 || chainId == 421613) {\n // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains\n vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068));\n } else if (chainId == 43114 || chainId == 43113) {\n // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59\n vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff));\n vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF));\n vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff));\n }\n // forgefmt: disable-end\n }\n\n function readEIP1559ScriptArtifact(string memory path)\n internal\n view\n virtual\n returns (EIP1559ScriptArtifact memory)\n {\n string memory data = vm.readFile(path);\n bytes memory parsedData = vm.parseJson(data);\n RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact));\n EIP1559ScriptArtifact memory artifact;\n artifact.libraries = rawArtifact.libraries;\n artifact.path = rawArtifact.path;\n artifact.timestamp = rawArtifact.timestamp;\n artifact.pending = rawArtifact.pending;\n artifact.txReturns = rawArtifact.txReturns;\n artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts);\n artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions);\n return artifact;\n }\n\n function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) {\n Tx1559[] memory txs = new Tx1559[](rawTxs.length);\n for (uint256 i; i < rawTxs.length; i++) {\n txs[i] = rawToConvertedEIPTx1559(rawTxs[i]);\n }\n return txs;\n }\n\n function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) {\n Tx1559 memory transaction;\n transaction.arguments = rawTx.arguments;\n transaction.contractName = rawTx.contractName;\n transaction.functionSig = rawTx.functionSig;\n transaction.hash = rawTx.hash;\n transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail);\n transaction.opcode = rawTx.opcode;\n return transaction;\n }\n\n function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail)\n internal\n pure\n virtual\n returns (Tx1559Detail memory)\n {\n Tx1559Detail memory txDetail;\n txDetail.data = rawDetail.data;\n txDetail.from = rawDetail.from;\n txDetail.to = rawDetail.to;\n txDetail.nonce = _bytesToUint(rawDetail.nonce);\n txDetail.txType = _bytesToUint(rawDetail.txType);\n txDetail.value = _bytesToUint(rawDetail.value);\n txDetail.gas = _bytesToUint(rawDetail.gas);\n txDetail.accessList = rawDetail.accessList;\n return txDetail;\n }\n\n function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".transactions\");\n RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[]));\n return rawToConvertedEIPTx1559s(rawTxs);\n }\n\n function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".transactions[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559));\n return rawToConvertedEIPTx1559(rawTx);\n }\n\n // Analogous to readTransactions, but for receipts.\n function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".receipts\");\n RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[]));\n return rawToConvertedReceipts(rawReceipts);\n }\n\n function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".receipts[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt));\n return rawToConvertedReceipt(rawReceipt);\n }\n\n function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) {\n Receipt[] memory receipts = new Receipt[](rawReceipts.length);\n for (uint256 i; i < rawReceipts.length; i++) {\n receipts[i] = rawToConvertedReceipt(rawReceipts[i]);\n }\n return receipts;\n }\n\n function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) {\n Receipt memory receipt;\n receipt.blockHash = rawReceipt.blockHash;\n receipt.to = rawReceipt.to;\n receipt.from = rawReceipt.from;\n receipt.contractAddress = rawReceipt.contractAddress;\n receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice);\n receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed);\n receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed);\n receipt.status = _bytesToUint(rawReceipt.status);\n receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex);\n receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber);\n receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs);\n receipt.logsBloom = rawReceipt.logsBloom;\n receipt.transactionHash = rawReceipt.transactionHash;\n return receipt;\n }\n\n function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs)\n internal\n pure\n virtual\n returns (ReceiptLog[] memory)\n {\n ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length);\n for (uint256 i; i < rawLogs.length; i++) {\n logs[i].logAddress = rawLogs[i].logAddress;\n logs[i].blockHash = rawLogs[i].blockHash;\n logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber);\n logs[i].data = rawLogs[i].data;\n logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex);\n logs[i].topics = rawLogs[i].topics;\n logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex);\n logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex);\n logs[i].removed = rawLogs[i].removed;\n }\n return logs;\n }\n\n // Deploy a contract by fetching the contract bytecode from\n // the artifacts directory\n // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))`\n function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes): Deployment failed.\");\n }\n\n function deployCode(string memory what) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string): Deployment failed.\");\n }\n\n /// @dev deploy contract with value on construction\n function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes,uint256): Deployment failed.\");\n }\n\n function deployCode(string memory what, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,uint256): Deployment failed.\");\n }\n\n // creates a labeled address and the corresponding private key\n function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) {\n privateKey = uint256(keccak256(abi.encodePacked(name)));\n addr = vm.addr(privateKey);\n vm.label(addr, name);\n }\n\n // creates a labeled address\n function makeAddr(string memory name) internal virtual returns (address addr) {\n (addr,) = makeAddrAndKey(name);\n }\n\n function deriveRememberKey(string memory mnemonic, uint32 index)\n internal\n virtual\n returns (address who, uint256 privateKey)\n {\n privateKey = vm.deriveKey(mnemonic, index);\n who = vm.rememberKey(privateKey);\n }\n\n function _bytesToUint(bytes memory b) private pure returns (uint256) {\n require(b.length <= 32, \"StdCheats _bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n function isFork() internal view virtual returns (bool status) {\n try vm.activeFork() {\n status = true;\n } catch (bytes memory) {}\n }\n\n modifier skipWhenForking() {\n if (!isFork()) {\n _;\n }\n }\n\n modifier skipWhenNotForking() {\n if (isFork()) {\n _;\n }\n }\n\n modifier noGasMetering() {\n vm.pauseGasMetering();\n // To prevent turning gas monitoring back on with nested functions that use this modifier,\n // we check if gasMetering started in the off position. If it did, we don't want to turn\n // it back on until we exit the top level function that used the modifier\n //\n // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well.\n // funcA will have `gasStartedOff` as false, funcB will have it as true,\n // so we only turn metering back on at the end of the funcA\n bool gasStartedOff = gasMeteringOff;\n gasMeteringOff = true;\n\n _;\n\n // if gas metering was on when this modifier was called, turn it back on at the end\n if (!gasStartedOff) {\n gasMeteringOff = false;\n vm.resumeGasMetering();\n }\n }\n\n // a cheat for fuzzing addresses that are payable only\n // see https://github.com/foundry-rs/foundry/issues/3631\n function assumePayable(address addr) internal virtual {\n (bool success,) = payable(addr).call{value: 0}(\"\");\n vm.assume(success);\n }\n}\n\n// Wrappers around cheatcodes to avoid footguns\nabstract contract StdCheats is StdCheatsSafe {\n using stdStorage for StdStorage;\n\n StdStorage private stdstore;\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n // Skip forward or rewind time by the specified number of seconds\n function skip(uint256 time) internal virtual {\n vm.warp(block.timestamp + time);\n }\n\n function rewind(uint256 time) internal virtual {\n vm.warp(block.timestamp - time);\n }\n\n // Setup a prank from an address that has some ether\n function hoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender, origin);\n }\n\n function hoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender, origin);\n }\n\n // Start perpetual prank from an address that has some ether\n function startHoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender);\n }\n\n function startHoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender);\n }\n\n // Start perpetual prank from an address that has some ether\n // tx.origin is set to the origin parameter\n function startHoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender, origin);\n }\n\n function startHoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender, origin);\n }\n\n function changePrank(address msgSender) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender);\n }\n\n function changePrank(address msgSender, address txOrigin) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender, txOrigin);\n }\n\n // The same as Vm's `deal`\n // Use the alternative signature for ERC20 tokens\n function deal(address to, uint256 give) internal virtual {\n vm.deal(to, give);\n }\n\n // Set the balance of an account for any ERC20 token\n // Use the alternative signature to update `totalSupply`\n function deal(address token, address to, uint256 give) internal virtual {\n deal(token, to, give, false);\n }\n\n // Set the balance of an account for any ERC1155 token\n // Use the alternative signature to update `totalSupply`\n function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual {\n dealERC1155(token, to, id, give, false);\n }\n\n function deal(address token, address to, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd));\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0x18160ddd).checked_write(totSup);\n }\n }\n\n function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x00fdd58e, to, id));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0xbd85b039, id));\n require(\n totSupData.length != 0,\n \"StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply.\"\n );\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup);\n }\n }\n\n function dealERC721(address token, address to, uint256 id) internal virtual {\n // check if token id is already minted and the actual owner.\n (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id));\n require(successMinted, \"StdCheats deal(address,address,uint,bool): id not minted.\");\n\n // get owner current balance\n (, bytes memory fromBalData) = token.call(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address))));\n uint256 fromPrevBal = abi.decode(fromBalData, (uint256));\n\n // get new user current balance\n (, bytes memory toBalData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 toPrevBal = abi.decode(toBalData, (uint256));\n\n // update balances\n stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal);\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal);\n\n // update owner\n stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to);\n }\n}\n" - }, - "node_modules/forge-std/src/StdError.sol": { - "content": "// SPDX-License-Identifier: MIT\n// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdError {\n bytes public constant assertionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x01);\n bytes public constant arithmeticError = abi.encodeWithSignature(\"Panic(uint256)\", 0x11);\n bytes public constant divisionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x12);\n bytes public constant enumConversionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x21);\n bytes public constant encodeStorageError = abi.encodeWithSignature(\"Panic(uint256)\", 0x22);\n bytes public constant popError = abi.encodeWithSignature(\"Panic(uint256)\", 0x31);\n bytes public constant indexOOBError = abi.encodeWithSignature(\"Panic(uint256)\", 0x32);\n bytes public constant memOverflowError = abi.encodeWithSignature(\"Panic(uint256)\", 0x41);\n bytes public constant zeroVarError = abi.encodeWithSignature(\"Panic(uint256)\", 0x51);\n}\n" - }, - "node_modules/forge-std/src/StdInvariant.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ncontract StdInvariant {\n struct FuzzSelector {\n address addr;\n bytes4[] selectors;\n }\n\n address[] private _excludedContracts;\n address[] private _excludedSenders;\n address[] private _targetedContracts;\n address[] private _targetedSenders;\n\n string[] private _excludedArtifacts;\n string[] private _targetedArtifacts;\n\n FuzzSelector[] private _targetedArtifactSelectors;\n FuzzSelector[] private _targetedSelectors;\n\n // Functions for users:\n // These are intended to be called in tests.\n\n function excludeContract(address newExcludedContract_) internal {\n _excludedContracts.push(newExcludedContract_);\n }\n\n function excludeSender(address newExcludedSender_) internal {\n _excludedSenders.push(newExcludedSender_);\n }\n\n function excludeArtifact(string memory newExcludedArtifact_) internal {\n _excludedArtifacts.push(newExcludedArtifact_);\n }\n\n function targetArtifact(string memory newTargetedArtifact_) internal {\n _targetedArtifacts.push(newTargetedArtifact_);\n }\n\n function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal {\n _targetedArtifactSelectors.push(newTargetedArtifactSelector_);\n }\n\n function targetContract(address newTargetedContract_) internal {\n _targetedContracts.push(newTargetedContract_);\n }\n\n function targetSelector(FuzzSelector memory newTargetedSelector_) internal {\n _targetedSelectors.push(newTargetedSelector_);\n }\n\n function targetSender(address newTargetedSender_) internal {\n _targetedSenders.push(newTargetedSender_);\n }\n\n // Functions for forge:\n // These are called by forge to run invariant tests and don't need to be called in tests.\n\n function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) {\n excludedArtifacts_ = _excludedArtifacts;\n }\n\n function excludeContracts() public view returns (address[] memory excludedContracts_) {\n excludedContracts_ = _excludedContracts;\n }\n\n function excludeSenders() public view returns (address[] memory excludedSenders_) {\n excludedSenders_ = _excludedSenders;\n }\n\n function targetArtifacts() public view returns (string[] memory targetedArtifacts_) {\n targetedArtifacts_ = _targetedArtifacts;\n }\n\n function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) {\n targetedArtifactSelectors_ = _targetedArtifactSelectors;\n }\n\n function targetContracts() public view returns (address[] memory targetedContracts_) {\n targetedContracts_ = _targetedContracts;\n }\n\n function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) {\n targetedSelectors_ = _targetedSelectors;\n }\n\n function targetSenders() public view returns (address[] memory targetedSenders_) {\n targetedSenders_ = _targetedSenders;\n }\n}\n" - }, - "node_modules/forge-std/src/StdJson.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing JSON files\n// To parse:\n// ```\n// using stdJson for string;\n// string memory json = vm.readFile(\"some_peth\");\n// json.parseUint(\"\");\n// ```\n// To write:\n// ```\n// using stdJson for string;\n// string memory json = \"deploymentArtifact\";\n// Contract contract = new Contract();\n// json.serialize(\"contractAddress\", address(contract));\n// json = json.serialize(\"deploymentTimes\", uint(1));\n// // store the stringified JSON to the 'json' variable we have been using as a key\n// // as we won't need it any longer\n// string memory json2 = \"finalArtifact\";\n// string memory final = json2.serialize(\"depArtifact\", json);\n// final.write(\"\");\n// ```\n\nlibrary stdJson {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJson(json, key);\n }\n\n function readUint(string memory json, string memory key) internal returns (uint256) {\n return vm.parseJsonUint(json, key);\n }\n\n function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) {\n return vm.parseJsonUintArray(json, key);\n }\n\n function readInt(string memory json, string memory key) internal returns (int256) {\n return vm.parseJsonInt(json, key);\n }\n\n function readIntArray(string memory json, string memory key) internal returns (int256[] memory) {\n return vm.parseJsonIntArray(json, key);\n }\n\n function readBytes32(string memory json, string memory key) internal returns (bytes32) {\n return vm.parseJsonBytes32(json, key);\n }\n\n function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) {\n return vm.parseJsonBytes32Array(json, key);\n }\n\n function readString(string memory json, string memory key) internal returns (string memory) {\n return vm.parseJsonString(json, key);\n }\n\n function readStringArray(string memory json, string memory key) internal returns (string[] memory) {\n return vm.parseJsonStringArray(json, key);\n }\n\n function readAddress(string memory json, string memory key) internal returns (address) {\n return vm.parseJsonAddress(json, key);\n }\n\n function readAddressArray(string memory json, string memory key) internal returns (address[] memory) {\n return vm.parseJsonAddressArray(json, key);\n }\n\n function readBool(string memory json, string memory key) internal returns (bool) {\n return vm.parseJsonBool(json, key);\n }\n\n function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) {\n return vm.parseJsonBoolArray(json, key);\n }\n\n function readBytes(string memory json, string memory key) internal returns (bytes memory) {\n return vm.parseJsonBytes(json, key);\n }\n\n function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) {\n return vm.parseJsonBytesArray(json, key);\n }\n\n function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bool[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function write(string memory jsonKey, string memory path) internal {\n vm.writeJson(jsonKey, path);\n }\n\n function write(string memory jsonKey, string memory path, string memory valueKey) internal {\n vm.writeJson(jsonKey, path, valueKey);\n }\n}\n" - }, - "node_modules/forge-std/src/StdMath.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdMath {\n int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n function abs(int256 a) internal pure returns (uint256) {\n // Required or it will fail when `a = type(int256).min`\n if (a == INT256_MIN) {\n return 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n }\n\n return uint256(a > 0 ? a : -a);\n }\n\n function delta(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a - b : b - a;\n }\n\n function delta(int256 a, int256 b) internal pure returns (uint256) {\n // a and b are of the same sign\n // this works thanks to two's complement, the left-most bit is the sign bit\n if ((a ^ b) > -1) {\n return delta(abs(a), abs(b));\n }\n\n // a and b are of opposite signs\n return abs(a) + abs(b);\n }\n\n function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n\n return absDelta * 1e18 / b;\n }\n\n function percentDelta(int256 a, int256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n uint256 absB = abs(b);\n\n return absDelta * 1e18 / absB;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nstruct StdStorage {\n mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots;\n mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds;\n bytes32[] _keys;\n bytes4 _sig;\n uint256 _depth;\n address _target;\n bytes32 _set;\n}\n\nlibrary stdStorageSafe {\n event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot);\n event WARNING_UninitedSlot(address who, uint256 slot);\n\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return bytes4(keccak256(bytes(sigStr)));\n }\n\n /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against\n // slot complexity:\n // if flat, will be bytes32(uint256(uint));\n // if map, will be keccak256(abi.encode(key, uint(slot)));\n // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));\n // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);\n function find(StdStorage storage self) internal returns (uint256) {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n // calldata to test against\n if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n vm.record();\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n (bytes32[] memory reads,) = vm.accesses(address(who));\n if (reads.length == 1) {\n bytes32 curr = vm.load(who, reads[0]);\n if (curr == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[0]));\n }\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n } else if (reads.length > 1) {\n for (uint256 i = 0; i < reads.length; i++) {\n bytes32 prev = vm.load(who, reads[i]);\n if (prev == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[i]));\n }\n // store\n vm.store(who, reads[i], bytes32(hex\"1337\"));\n bool success;\n bytes memory rdat;\n {\n (success, rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n if (success && fdat == bytes32(hex\"1337\")) {\n // we found which of the slots is the actual one\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n vm.store(who, reads[i], prev);\n break;\n }\n vm.store(who, reads[i], prev);\n }\n } else {\n revert(\"stdStorage find(StdStorage): No storage use detected for target.\");\n }\n\n require(\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))],\n \"stdStorage find(StdStorage): Slot(s) not found.\"\n );\n\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n self._target = _target;\n return self;\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n self._sig = _sig;\n return self;\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n self._sig = sigs(_sig);\n return self;\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n self._keys.push(bytes32(uint256(uint160(who))));\n return self;\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n self._keys.push(bytes32(amt));\n return self;\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n self._keys.push(key);\n return self;\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n self._depth = _depth;\n return self;\n }\n\n function read(StdStorage storage self) private returns (bytes memory) {\n address t = self._target;\n uint256 s = find(self);\n return abi.encode(vm.load(t, bytes32(s)));\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return abi.decode(read(self), (bytes32));\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n int256 v = read_int(self);\n if (v == 0) return false;\n if (v == 1) return true;\n revert(\"stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool.\");\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return abi.decode(read(self), (address));\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return abi.decode(read(self), (uint256));\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return abi.decode(read(self), (int256));\n }\n\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n\nlibrary stdStorage {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return stdStorageSafe.sigs(sigStr);\n }\n\n function find(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.find(self);\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n return stdStorageSafe.target(self, _target);\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, who);\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, amt);\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, key);\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n return stdStorageSafe.depth(self, _depth);\n }\n\n function checked_write(StdStorage storage self, address who) internal {\n checked_write(self, bytes32(uint256(uint160(who))));\n }\n\n function checked_write(StdStorage storage self, uint256 amt) internal {\n checked_write(self, bytes32(amt));\n }\n\n function checked_write(StdStorage storage self, bool write) internal {\n bytes32 t;\n /// @solidity memory-safe-assembly\n assembly {\n t := write\n }\n checked_write(self, t);\n }\n\n function checked_write(StdStorage storage self, bytes32 set) internal {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n find(self);\n }\n bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]);\n\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n bytes32 curr = vm.load(who, slot);\n\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n vm.store(who, slot, set);\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return stdStorageSafe.read_bytes32(self);\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n return stdStorageSafe.read_bool(self);\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return stdStorageSafe.read_address(self);\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.read_uint(self);\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return stdStorageSafe.read_int(self);\n }\n\n // Private function so needs to be copied over\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n // Private function so needs to be copied over\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStyle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nlibrary StdStyle {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n string constant RED = \"\\u001b[91m\";\n string constant GREEN = \"\\u001b[92m\";\n string constant YELLOW = \"\\u001b[93m\";\n string constant BLUE = \"\\u001b[94m\";\n string constant MAGENTA = \"\\u001b[95m\";\n string constant CYAN = \"\\u001b[96m\";\n string constant BOLD = \"\\u001b[1m\";\n string constant DIM = \"\\u001b[2m\";\n string constant ITALIC = \"\\u001b[3m\";\n string constant UNDERLINE = \"\\u001b[4m\";\n string constant INVERSE = \"\\u001b[7m\";\n string constant RESET = \"\\u001b[0m\";\n\n function styleConcat(string memory style, string memory self) private pure returns (string memory) {\n return string(abi.encodePacked(style, self, RESET));\n }\n\n function red(string memory self) internal pure returns (string memory) {\n return styleConcat(RED, self);\n }\n\n function red(uint256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(int256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(address self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(bool self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes(bytes memory self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes32(bytes32 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function green(string memory self) internal pure returns (string memory) {\n return styleConcat(GREEN, self);\n }\n\n function green(uint256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(int256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(address self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(bool self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes(bytes memory self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes32(bytes32 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function yellow(string memory self) internal pure returns (string memory) {\n return styleConcat(YELLOW, self);\n }\n\n function yellow(uint256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(int256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(address self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(bool self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes(bytes memory self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes32(bytes32 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function blue(string memory self) internal pure returns (string memory) {\n return styleConcat(BLUE, self);\n }\n\n function blue(uint256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(int256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(address self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(bool self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes(bytes memory self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes32(bytes32 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function magenta(string memory self) internal pure returns (string memory) {\n return styleConcat(MAGENTA, self);\n }\n\n function magenta(uint256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(int256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(address self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(bool self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes(bytes memory self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes32(bytes32 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function cyan(string memory self) internal pure returns (string memory) {\n return styleConcat(CYAN, self);\n }\n\n function cyan(uint256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(int256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(address self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(bool self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes(bytes memory self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes32(bytes32 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function bold(string memory self) internal pure returns (string memory) {\n return styleConcat(BOLD, self);\n }\n\n function bold(uint256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(int256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(address self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(bool self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes(bytes memory self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes32(bytes32 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function dim(string memory self) internal pure returns (string memory) {\n return styleConcat(DIM, self);\n }\n\n function dim(uint256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(int256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(address self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(bool self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes(bytes memory self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes32(bytes32 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function italic(string memory self) internal pure returns (string memory) {\n return styleConcat(ITALIC, self);\n }\n\n function italic(uint256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(int256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(address self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(bool self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes(bytes memory self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes32(bytes32 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function underline(string memory self) internal pure returns (string memory) {\n return styleConcat(UNDERLINE, self);\n }\n\n function underline(uint256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(int256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(address self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(bool self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes(bytes memory self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes32(bytes32 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function inverse(string memory self) internal pure returns (string memory) {\n return styleConcat(INVERSE, self);\n }\n\n function inverse(uint256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(int256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(address self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(bool self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes(bytes memory self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes32(bytes32 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n}\n" - }, - "node_modules/forge-std/src/StdUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {IMulticall3} from \"./interfaces/IMulticall3.sol\";\n// TODO Remove import.\nimport {VmSafe} from \"./Vm.sol\";\n\nabstract contract StdUtils {\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n //////////////////////////////////////////////////////////////////////////*/\n\n IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;\n uint256 private constant INT256_MIN_ABS =\n 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n /*//////////////////////////////////////////////////////////////////////////\n INTERNAL FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n require(min <= max, \"StdUtils bound(uint256,uint256,uint256): Max is less than min.\");\n // If x is between min and max, return x directly. This is to ensure that dictionary values\n // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188\n if (x >= min && x <= max) return x;\n\n uint256 size = max - min + 1;\n\n // If the value is 0, 1, 2, 3, warp that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side.\n // This helps ensure coverage of the min/max values.\n if (x <= 3 && size > x) return min + x;\n if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x);\n\n // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.\n if (x > max) {\n uint256 diff = x - max;\n uint256 rem = diff % size;\n if (rem == 0) return max;\n result = min + rem - 1;\n } else if (x < min) {\n uint256 diff = min - x;\n uint256 rem = diff % size;\n if (rem == 0) return min;\n result = max - rem + 1;\n }\n }\n\n function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) {\n result = _bound(x, min, max);\n console2_log(\"Bound Result\", result);\n }\n\n function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) {\n require(min <= max, \"StdUtils bound(int256,int256,int256): Max is less than min.\");\n\n // Shifting all int256 values to uint256 to use _bound function. The range of two types are:\n // int256 : -(2**255) ~ (2**255 - 1)\n // uint256: 0 ~ (2**256 - 1)\n // So, add 2**255, INT256_MIN_ABS to the integer values.\n //\n // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow.\n // So, use `~uint256(x) + 1` instead.\n uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS);\n uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS);\n uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS);\n\n uint256 y = _bound(_x, _min, _max);\n\n // To move it back to int256 value, subtract INT256_MIN_ABS at here.\n result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS);\n console2_log(\"Bound result\", vm.toString(result));\n }\n\n function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {\n require(b.length <= 32, \"StdUtils bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce\n /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol)\n function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) {\n // forgefmt: disable-start\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))));\n if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))));\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce))));\n if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce))));\n if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce))));\n // forgefmt: disable-end\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return addressFromLast20Bytes(\n keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce)))\n );\n }\n\n function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer)\n internal\n pure\n virtual\n returns (address)\n {\n return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash)));\n }\n\n /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer\n function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) {\n return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY);\n }\n\n /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) {\n return hashInitCode(creationCode, \"\");\n }\n\n /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n /// @param args the ABI-encoded arguments to the constructor of C\n function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(creationCode, args));\n }\n\n // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses.\n function getTokenBalances(address token, address[] memory addresses)\n internal\n virtual\n returns (uint256[] memory balances)\n {\n uint256 tokenCodeSize;\n assembly {\n tokenCodeSize := extcodesize(token)\n }\n require(tokenCodeSize > 0, \"StdUtils getTokenBalances(address,address[]): Token address is not a contract.\");\n\n // ABI encode the aggregate call to Multicall3.\n uint256 length = addresses.length;\n IMulticall3.Call[] memory calls = new IMulticall3.Call[](length);\n for (uint256 i = 0; i < length; ++i) {\n // 0x70a08231 = bytes4(\"balanceOf(address)\"))\n calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))});\n }\n\n // Make the aggregate call.\n (, bytes[] memory returnData) = multicall.aggregate(calls);\n\n // ABI decode the return data and return the balances.\n balances = new uint256[](length);\n for (uint256 i = 0; i < length; ++i) {\n balances[i] = abi.decode(returnData[i], (uint256));\n }\n }\n\n /*//////////////////////////////////////////////////////////////////////////\n PRIVATE FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere.\n\n function console2_log(string memory p0, uint256 p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n status;\n }\n\n function console2_log(string memory p0, string memory p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n status;\n }\n}\n" - }, - "node_modules/forge-std/src/Test.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// 💬 ABOUT\n// Standard Library's default Test\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {StdAssertions} from \"./StdAssertions.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheats} from \"./StdCheats.sol\";\nimport {stdError} from \"./StdError.sol\";\nimport {StdInvariant} from \"./StdInvariant.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {Vm} from \"./Vm.sol\";\nimport {StdStyle} from \"./StdStyle.sol\";\n\n// 📦 BOILERPLATE\nimport {TestBase} from \"./Base.sol\";\nimport {DSTest} from \"ds-test/test.sol\";\n\n// ⭐️ TEST\nabstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase {\n// Note: IS_TEST() must return true.\n// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76.\n}\n" - }, - "node_modules/forge-std/src/Vm.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// Cheatcodes are marked as view/pure/none using the following rules:\n// 0. A call's observable behaviour includes its return value, logs, reverts and state writes,\n// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc),\n// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`,\n// 3. Otherwise you're `pure`.\n\ninterface VmSafe {\n struct Log {\n bytes32[] topics;\n bytes data;\n address emitter;\n }\n\n struct Rpc {\n string key;\n string url;\n }\n\n struct FsMetadata {\n bool isDir;\n bool isSymlink;\n uint256 length;\n bool readOnly;\n uint256 modified;\n uint256 accessed;\n uint256 created;\n }\n\n // Loads a storage slot from an address\n function load(address target, bytes32 slot) external view returns (bytes32 data);\n // Signs data\n function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);\n // Gets the address for a given private key\n function addr(uint256 privateKey) external pure returns (address keyAddr);\n // Gets the nonce of an account\n function getNonce(address account) external view returns (uint64 nonce);\n // Performs a foreign function call via the terminal\n function ffi(string[] calldata commandInput) external returns (bytes memory result);\n // Sets environment variables\n function setEnv(string calldata name, string calldata value) external;\n // Reads environment variables, (name) => (value)\n function envBool(string calldata name) external view returns (bool value);\n function envUint(string calldata name) external view returns (uint256 value);\n function envInt(string calldata name) external view returns (int256 value);\n function envAddress(string calldata name) external view returns (address value);\n function envBytes32(string calldata name) external view returns (bytes32 value);\n function envString(string calldata name) external view returns (string memory value);\n function envBytes(string calldata name) external view returns (bytes memory value);\n // Reads environment variables as arrays\n function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value);\n function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value);\n function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value);\n function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);\n function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value);\n function envString(string calldata name, string calldata delim) external view returns (string[] memory value);\n function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value);\n // Read environment variables with default value\n function envOr(string calldata name, bool defaultValue) external returns (bool value);\n function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value);\n function envOr(string calldata name, int256 defaultValue) external returns (int256 value);\n function envOr(string calldata name, address defaultValue) external returns (address value);\n function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value);\n function envOr(string calldata name, string calldata defaultValue) external returns (string memory value);\n function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value);\n // Read environment variables as arrays with default value\n function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue)\n external\n returns (bool[] memory value);\n function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue)\n external\n returns (uint256[] memory value);\n function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue)\n external\n returns (int256[] memory value);\n function envOr(string calldata name, string calldata delim, address[] calldata defaultValue)\n external\n returns (address[] memory value);\n function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue)\n external\n returns (bytes32[] memory value);\n function envOr(string calldata name, string calldata delim, string[] calldata defaultValue)\n external\n returns (string[] memory value);\n function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue)\n external\n returns (bytes[] memory value);\n // Records all storage reads and writes\n function record() external;\n // Gets all accessed reads and write slot from a recording session, for a given address\n function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots);\n // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file\n function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode);\n // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file\n function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode);\n // Labels an address in call traces\n function label(address account, string calldata newLabel) external;\n // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain\n function broadcast() external;\n // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain\n function broadcast(address signer) external;\n // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain\n function broadcast(uint256 privateKey) external;\n // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain\n function startBroadcast() external;\n // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain\n function startBroadcast(address signer) external;\n // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain\n function startBroadcast(uint256 privateKey) external;\n // Stops collecting onchain transactions\n function stopBroadcast() external;\n // Reads the entire content of file to string\n function readFile(string calldata path) external view returns (string memory data);\n // Reads the entire content of file as binary. Path is relative to the project root.\n function readFileBinary(string calldata path) external view returns (bytes memory data);\n // Get the path of the current project root\n function projectRoot() external view returns (string memory path);\n // Get the metadata for a file/directory\n function fsMetadata(string calldata fileOrDir) external returns (FsMetadata memory metadata);\n // Reads next line of file to string\n function readLine(string calldata path) external view returns (string memory line);\n // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does.\n function writeFile(string calldata path, string calldata data) external;\n // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does.\n // Path is relative to the project root.\n function writeFileBinary(string calldata path, bytes calldata data) external;\n // Writes line to file, creating a file if it does not exist.\n function writeLine(string calldata path, string calldata data) external;\n // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine.\n function closeFile(string calldata path) external;\n // Removes file. This cheatcode will revert in the following situations, but is not limited to just these cases:\n // - Path points to a directory.\n // - The file doesn't exist.\n // - The user lacks permissions to remove the file.\n function removeFile(string calldata path) external;\n // Convert values to a string\n function toString(address value) external pure returns (string memory stringifiedValue);\n function toString(bytes calldata value) external pure returns (string memory stringifiedValue);\n function toString(bytes32 value) external pure returns (string memory stringifiedValue);\n function toString(bool value) external pure returns (string memory stringifiedValue);\n function toString(uint256 value) external pure returns (string memory stringifiedValue);\n function toString(int256 value) external pure returns (string memory stringifiedValue);\n // Convert values from a string\n function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue);\n function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue);\n function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue);\n function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue);\n function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue);\n function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue);\n // Record all the transaction logs\n function recordLogs() external;\n // Gets all the recorded logs\n function getRecordedLogs() external returns (Log[] memory logs);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index}\n function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index}\n function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index)\n external\n pure\n returns (uint256 privateKey);\n // Adds a private key to the local forge wallet and returns the address\n function rememberKey(uint256 privateKey) external returns (address keyAddr);\n //\n // parseJson\n //\n // ----\n // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects\n // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in\n // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that\n // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded\n // as tuples, with the attributes in the order in which they are defined.\n // For example: json = { 'a': 1, 'b': 0xa4tb......3xs}\n // a: uint256\n // b: address\n // To decode that json, we need to define a struct or a tuple as follows:\n // struct json = { uint256 a; address b; }\n // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to\n // decode the tuple in that order, and thus fail.\n // ----\n // Given a string of JSON, return it as ABI-encoded\n function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData);\n function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData);\n\n // The following parseJson cheatcodes will do type coercion, for the type that they indicate.\n // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12'\n // and hex numbers '0xEF'.\n // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not\n // a JSON object.\n function parseJsonUint(string calldata, string calldata) external returns (uint256);\n function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory);\n function parseJsonInt(string calldata, string calldata) external returns (int256);\n function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory);\n function parseJsonBool(string calldata, string calldata) external returns (bool);\n function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory);\n function parseJsonAddress(string calldata, string calldata) external returns (address);\n function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory);\n function parseJsonString(string calldata, string calldata) external returns (string memory);\n function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory);\n function parseJsonBytes(string calldata, string calldata) external returns (bytes memory);\n function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory);\n function parseJsonBytes32(string calldata, string calldata) external returns (bytes32);\n function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory);\n\n // Serialize a key and value to a JSON object stored in-memory that can be later written to a file\n // It returns the stringified version of the specific JSON file up to that moment.\n function serializeBool(string calldata objectKey, string calldata valueKey, bool value)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256 value)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address value)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string calldata value)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value)\n external\n returns (string memory json);\n\n function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values)\n external\n returns (string memory json);\n\n //\n // writeJson\n //\n // ----\n // Write a serialized JSON object to a file. If the file exists, it will be overwritten.\n // Let's assume we want to write the following JSON to a file:\n //\n // { \"boolean\": true, \"number\": 342, \"object\": { \"title\": \"finally json serialization\" } }\n //\n // ```\n // string memory json1 = \"some key\";\n // vm.serializeBool(json1, \"boolean\", true);\n // vm.serializeBool(json1, \"number\", uint256(342));\n // json2 = \"some other key\";\n // string memory output = vm.serializeString(json2, \"title\", \"finally json serialization\");\n // string memory finalJson = vm.serialize(json1, \"object\", output);\n // vm.writeJson(finalJson, \"./output/example.json\");\n // ```\n // The critical insight is that every invocation of serialization will return the stringified version of the JSON\n // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version\n // to serialize them as values to another JSON object.\n //\n // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..)\n // will find the object in-memory that is keyed by \"some key\".\n function writeJson(string calldata json, string calldata path) external;\n // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = \n // This is useful to replace a specific value of a JSON file, without having to parse the entire thing\n function writeJson(string calldata json, string calldata path, string calldata valueKey) external;\n // Returns the RPC url for the given alias\n function rpcUrl(string calldata rpcAlias) external view returns (string memory json);\n // Returns all rpc urls and their aliases `[alias, url][]`\n function rpcUrls() external view returns (string[2][] memory urls);\n // Returns all rpc urls and their aliases as structs.\n function rpcUrlStructs() external view returns (Rpc[] memory urls);\n // If the condition is false, discard this run's fuzz inputs and generate new ones.\n function assume(bool condition) external pure;\n // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused.\n function pauseGasMetering() external;\n // Resumes gas metering (i.e. gas usage is counted again). Noop if already on.\n function resumeGasMetering() external;\n}\n\ninterface Vm is VmSafe {\n // Sets block.timestamp\n function warp(uint256 newTimestamp) external;\n // Sets block.height\n function roll(uint256 newHeight) external;\n // Sets block.basefee\n function fee(uint256 newBasefee) external;\n // Sets block.difficulty\n function difficulty(uint256 newDifficulty) external;\n // Sets block.chainid\n function chainId(uint256 newChainId) external;\n // Stores a value to an address' storage slot.\n function store(address target, bytes32 slot, bytes32 value) external;\n // Sets the nonce of an account; must be higher than the current nonce of the account\n function setNonce(address account, uint64 newNonce) external;\n // Sets the *next* call's msg.sender to be the input address\n function prank(address msgSender) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called\n function startPrank(address msgSender) external;\n // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input\n function prank(address msgSender, address txOrigin) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input\n function startPrank(address msgSender, address txOrigin) external;\n // Resets subsequent calls' msg.sender to be `address(this)`\n function stopPrank() external;\n // Sets an address' balance\n function deal(address account, uint256 newBalance) external;\n // Sets an address' code\n function etch(address target, bytes calldata newRuntimeBytecode) external;\n // Expects an error on next call\n function expectRevert(bytes calldata revertData) external;\n function expectRevert(bytes4 revertData) external;\n function expectRevert() external;\n\n // Prepare an expected log with all four checks enabled.\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data.\n // Second form also checks supplied address against emitting contract.\n function expectEmit() external;\n function expectEmit(address emitter) external;\n\n // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData).\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data (as specified by the booleans).\n // Second form also checks supplied address against emitting contract.\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external;\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter)\n external;\n\n // Mocks a call to an address, returning specified data.\n // Calldata can either be strict or a partial match, e.g. if you only\n // pass a Solidity selector to the expected calldata, then the entire Solidity\n // function will be mocked.\n function mockCall(address callee, bytes calldata data, bytes calldata returnData) external;\n // Mocks a call to an address with a specific msg.value, returning specified data.\n // Calldata match takes precedence over msg.value in case of ambiguity.\n function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external;\n // Clears all mocked calls\n function clearMockedCalls() external;\n // Expects a call to an address with the specified calldata.\n // Calldata can either be a strict or a partial match\n function expectCall(address callee, bytes calldata data) external;\n // Expects a call to an address with the specified msg.value and calldata\n function expectCall(address callee, uint256 msgValue, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value, gas, and calldata.\n function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas.\n function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other\n // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set.\n function expectSafeMemory(uint64 min, uint64 max) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext.\n // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges\n // to the set.\n function expectSafeMemoryCall(uint64 min, uint64 max) external;\n // Sets block.coinbase\n function coinbase(address newCoinbase) external;\n // Snapshot the current state of the evm.\n // Returns the id of the snapshot that was created.\n // To revert a snapshot use `revertTo`\n function snapshot() external returns (uint256 snapshotId);\n // Revert the state of the EVM to a previous snapshot\n // Takes the snapshot id to revert to.\n // This deletes the snapshot and all snapshots taken after the given snapshot id.\n function revertTo(uint256 snapshotId) external returns (bool success);\n // Creates a new fork with the given endpoint and block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction,\n // and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before\n // the transaction, returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active.\n function selectFork(uint256 forkId) external;\n /// Returns the identifier of the currently active fork. Reverts if no fork is currently active.\n function activeFork() external view returns (uint256 forkId);\n // Updates the currently active fork to given block number\n // This is similar to `roll` but for the currently active fork\n function rollFork(uint256 blockNumber) external;\n // Updates the currently active fork to given transaction\n // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block\n function rollFork(bytes32 txHash) external;\n // Updates the given fork to given block number\n function rollFork(uint256 forkId, uint256 blockNumber) external;\n // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block\n function rollFork(uint256 forkId, bytes32 txHash) external;\n // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup\n // Meaning, changes made to the state of this account will be kept when switching forks\n function makePersistent(address account) external;\n function makePersistent(address account0, address account1) external;\n function makePersistent(address account0, address account1, address account2) external;\n function makePersistent(address[] calldata accounts) external;\n // Revokes persistent status from the address, previously added via `makePersistent`\n function revokePersistent(address account) external;\n function revokePersistent(address[] calldata accounts) external;\n // Returns true if the account is marked as persistent\n function isPersistent(address account) external view returns (bool persistent);\n // In forking mode, explicitly grant the given address cheatcode access\n function allowCheatcodes(address account) external;\n // Fetches the given transaction from the active fork and executes it on the current state\n function transact(bytes32 txHash) external;\n // Fetches the given transaction from the given fork and executes it on the current state\n function transact(uint256 forkId, bytes32 txHash) external;\n}\n" - }, - "node_modules/forge-std/src/console.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n }\n\n function logUint(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n }\n\n function log(uint p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n }\n\n function log(uint p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n }\n\n function log(uint p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n }\n\n function log(string memory p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/console2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\n/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should\n/// use `int256` and `uint256`. This modified version fixes that. This version is recommended\n/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in\n/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`.\n/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178\nlibrary console2 {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function log(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint256 p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n }\n\n function log(uint256 p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n }\n\n function log(uint256 p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n }\n\n function log(uint256 p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n }\n\n function log(string memory p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n }\n\n function log(string memory p0, int256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,int256)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/interfaces/IMulticall3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ninterface IMulticall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint256 value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n function aggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes[] memory returnData);\n\n function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);\n\n function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData);\n\n function blockAndAggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n\n function getBasefee() external view returns (uint256 basefee);\n\n function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash);\n\n function getBlockNumber() external view returns (uint256 blockNumber);\n\n function getChainId() external view returns (uint256 chainid);\n\n function getCurrentBlockCoinbase() external view returns (address coinbase);\n\n function getCurrentBlockDifficulty() external view returns (uint256 difficulty);\n\n function getCurrentBlockGasLimit() external view returns (uint256 gaslimit);\n\n function getCurrentBlockTimestamp() external view returns (uint256 timestamp);\n\n function getEthBalance(address addr) external view returns (uint256 balance);\n\n function getLastBlockHash() external view returns (bytes32 blockHash);\n\n function tryAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (Result[] memory returnData);\n\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n}\n" - } - }, - "settings": { - "remappings": [ - "@openzeppelin/=node_modules/@openzeppelin/", - "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", - "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", - "@rari-capital/=node_modules/@rari-capital/", - "@rari-capital/solmate/=node_modules/@rari-capital/solmate/", - "ds-test/=node_modules/ds-test/src/", - "forge-std/=node_modules/forge-std/src/" - ], - "optimizer": { - "enabled": true, - "runs": 999999 - }, - "metadata": { - "bytecodeHash": "none" - }, - "outputSelection": { - "*": { - "": [ - "ast" - ], - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "storageLayout", - "devdoc", - "userdoc" - ] - } - }, - "evmVersion": "london", - "libraries": {} - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/4eff12bc9de58190fbafded200df8851.json b/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/4eff12bc9de58190fbafded200df8851.json deleted file mode 100644 index fd16bdebc2a1..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/4eff12bc9de58190fbafded200df8851.json +++ /dev/null @@ -1,554 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/L1/L1CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismPortal } from \"./OptimismPortal.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1CrossDomainMessenger\n * @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible\n * for sending and receiving data on the L1 side. Users are encouraged to use this\n * interface instead of interacting with lower-level contracts directly.\n */\ncontract L1CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @notice Address of the OptimismPortal.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _portal Address of the OptimismPortal contract on this network.\n */\n constructor(OptimismPortal _portal)\n Semver(1, 1, 0)\n CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER)\n {\n PORTAL = _portal;\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return msg.sender == address(PORTAL) && PORTAL.l2Sender() == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(PORTAL);\n }\n}\n" - }, - "contracts/L1/L1ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { IERC721 } from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L1ERC721Bridge\n * @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as an escrow for ERC721 tokens deposited into L2.\n */\ncontract L1ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token\n * by ID was deposited for a given L2 token.\n */\n mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L1ERC721Bridge: local token cannot be self\");\n\n // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.\n require(\n deposits[_localToken][_remoteToken][_tokenId] == true,\n \"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\"\n );\n\n // Mark that the token ID for this L1/L2 token pair is no longer escrowed in the L1\n // Bridge.\n deposits[_localToken][_remoteToken][_tokenId] = false;\n\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the\n // withdrawer.\n IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L1ERC721Bridge: remote token cannot be address(0)\");\n\n // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)\n bytes memory message = abi.encodeWithSelector(\n L2ERC721Bridge.finalizeBridgeERC721.selector,\n _remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Lock token into bridge\n deposits[_localToken][_remoteToken][_tokenId] = true;\n IERC721(_localToken).transferFrom(_from, address(this), _tokenId);\n\n // Send calldata into L2\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L1/L1StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title L1StandardBridge\n * @notice The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L1, it will be escrowed within this\n * contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was\n * stored within this contract. After Bedrock, ETH is instead stored inside the\n * OptimismPortal contract.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L1StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated.\n *\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of ETH deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ETHDepositInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized.\n *\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of ETH withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 withdrawal is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _messenger Address of the L1CrossDomainMessenger.\n */\n constructor(address payable _messenger)\n Semver(1, 1, 0)\n StandardBridge(_messenger, payable(Predeploys.L2_STANDARD_BRIDGE))\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into the sender's account on L2.\n *\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETH(uint32 _minGasLimit, bytes calldata _extraData) external payable onlyEOA {\n _initiateETHDeposit(msg.sender, msg.sender, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ETH into a target account on L2.\n * Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will\n * be locked in the L2StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n *\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable {\n _initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into the sender's account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20(\n address _l1Token,\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual onlyEOA {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Deposits some amount of ERC20 tokens into a target account on L2.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function depositERC20To(\n address _l1Token,\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external virtual {\n _initiateERC20Deposit(\n _l1Token,\n _l2Token,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ETH from L2.\n *\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of ETH to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeETHWithdrawal(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a withdrawal of ERC20 tokens from L2.\n *\n * @param _l1Token Address of the token on L1.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the withdrawer on L2.\n * @param _to Address of the recipient on L1.\n * @param _amount Amount of the ERC20 to withdraw.\n * @param _extraData Optional data forwarded from L2.\n */\n function finalizeERC20Withdrawal(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external {\n finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L2 bridge contract.\n *\n * @return Address of the corresponding L2 bridge contract.\n */\n function l2TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @notice Internal function for initiating an ETH deposit.\n *\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateETHDeposit(\n address _from,\n address _to,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Internal function for initiating an ERC20 deposit.\n *\n * @param _l1Token Address of the L1 token being deposited.\n * @param _l2Token Address of the corresponding token on L2.\n * @param _from Address of the sender on L1.\n * @param _to Address of the recipient on L2.\n * @param _amount Amount of the ERC20 to deposit.\n * @param _minGasLimit Minimum gas limit for the deposit message on L2.\n * @param _extraData Optional data to forward to L2.\n */\n function _initiateERC20Deposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n _initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHDepositInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHDepositInitiated(_from, _to, _amount, _extraData);\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ETHWithdrawalFinalized event followed by the ETHBridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData);\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20DepositInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20DepositInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy ERC20WithdrawalFinalized event followed by the ERC20BridgeFinalized\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit ERC20WithdrawalFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L1/L2OutputOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\n/**\n * @custom:proxied\n * @title L2OutputOracle\n * @notice The L2OutputOracle contains an array of L2 state outputs, where each output is a\n * commitment to the state of the L2 chain. Other contracts like the OptimismPortal use\n * these outputs to verify information about the state of L2.\n */\ncontract L2OutputOracle is Initializable, Semver {\n /**\n * @notice The interval in L2 blocks at which checkpoints must be submitted. Although this is\n * immutable, it can safely be modified by upgrading the implementation contract.\n */\n uint256 public immutable SUBMISSION_INTERVAL;\n\n /**\n * @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified.\n */\n uint256 public immutable L2_BLOCK_TIME;\n\n /**\n * @notice The address of the challenger. Can be updated via upgrade.\n */\n address public immutable CHALLENGER;\n\n /**\n * @notice The address of the proposer. Can be updated via upgrade.\n */\n address public immutable PROPOSER;\n\n /**\n * @notice Minimum time (in seconds) that must elapse before a withdrawal can be finalized.\n */\n uint256 public immutable FINALIZATION_PERIOD_SECONDS;\n\n /**\n * @notice The number of the first L2 block recorded in this contract.\n */\n uint256 public startingBlockNumber;\n\n /**\n * @notice The timestamp of the first L2 block recorded in this contract.\n */\n uint256 public startingTimestamp;\n\n /**\n * @notice Array of L2 output proposals.\n */\n Types.OutputProposal[] internal l2Outputs;\n\n /**\n * @notice Emitted when an output is proposed.\n *\n * @param outputRoot The output root.\n * @param l2OutputIndex The index of the output in the l2Outputs array.\n * @param l2BlockNumber The L2 block number of the output root.\n * @param l1Timestamp The L1 timestamp when proposed.\n */\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n /**\n * @notice Emitted when outputs are deleted.\n *\n * @param prevNextOutputIndex Next L2 output index before the deletion.\n * @param newNextOutputIndex Next L2 output index after the deletion.\n */\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n /**\n * @custom:semver 1.2.0\n *\n * @param _submissionInterval Interval in blocks at which checkpoints must be submitted.\n * @param _l2BlockTime The time per L2 block, in seconds.\n * @param _startingBlockNumber The number of the first L2 block.\n * @param _startingTimestamp The timestamp of the first L2 block.\n * @param _proposer The address of the proposer.\n * @param _challenger The address of the challenger.\n */\n constructor(\n uint256 _submissionInterval,\n uint256 _l2BlockTime,\n uint256 _startingBlockNumber,\n uint256 _startingTimestamp,\n address _proposer,\n address _challenger,\n uint256 _finalizationPeriodSeconds\n ) Semver(1, 2, 0) {\n require(_l2BlockTime > 0, \"L2OutputOracle: L2 block time must be greater than 0\");\n require(\n _submissionInterval > _l2BlockTime,\n \"L2OutputOracle: submission interval must be greater than L2 block time\"\n );\n\n SUBMISSION_INTERVAL = _submissionInterval;\n L2_BLOCK_TIME = _l2BlockTime;\n PROPOSER = _proposer;\n CHALLENGER = _challenger;\n FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;\n\n initialize(_startingBlockNumber, _startingTimestamp);\n }\n\n /**\n * @notice Initializer.\n *\n * @param _startingBlockNumber Block number for the first recoded L2 block.\n * @param _startingTimestamp Timestamp for the first recoded L2 block.\n */\n function initialize(uint256 _startingBlockNumber, uint256 _startingTimestamp)\n public\n initializer\n {\n require(\n _startingTimestamp <= block.timestamp,\n \"L2OutputOracle: starting L2 timestamp must be less than current time\"\n );\n\n startingTimestamp = _startingTimestamp;\n startingBlockNumber = _startingBlockNumber;\n }\n\n /**\n * @notice Deletes all output proposals after and including the proposal that corresponds to\n * the given output index. Only the challenger address can delete outputs.\n *\n * @param _l2OutputIndex Index of the first L2 output to be deleted. All outputs after this\n * output will also be deleted.\n */\n // solhint-disable-next-line ordering\n function deleteL2Outputs(uint256 _l2OutputIndex) external {\n require(\n msg.sender == CHALLENGER,\n \"L2OutputOracle: only the challenger address can delete outputs\"\n );\n\n // Make sure we're not *increasing* the length of the array.\n require(\n _l2OutputIndex < l2Outputs.length,\n \"L2OutputOracle: cannot delete outputs after the latest output index\"\n );\n\n // Do not allow deleting any outputs that have already been finalized.\n require(\n block.timestamp - l2Outputs[_l2OutputIndex].timestamp < FINALIZATION_PERIOD_SECONDS,\n \"L2OutputOracle: cannot delete outputs that have already been finalized\"\n );\n\n uint256 prevNextL2OutputIndex = nextOutputIndex();\n\n // Use assembly to delete the array elements because Solidity doesn't allow it.\n assembly {\n sstore(l2Outputs.slot, _l2OutputIndex)\n }\n\n emit OutputsDeleted(prevNextL2OutputIndex, _l2OutputIndex);\n }\n\n /**\n * @notice Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp\n * must be equal to the current value returned by `nextTimestamp()` in order to be\n * accepted. This function may only be called by the Proposer.\n *\n * @param _outputRoot The L2 output of the checkpoint block.\n * @param _l2BlockNumber The L2 block number that resulted in _outputRoot.\n * @param _l1BlockHash A block hash which must be included in the current chain.\n * @param _l1BlockNumber The block number with the specified block hash.\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external payable {\n require(\n msg.sender == PROPOSER,\n \"L2OutputOracle: only the proposer address can propose new outputs\"\n );\n\n require(\n _l2BlockNumber == nextBlockNumber(),\n \"L2OutputOracle: block number must be equal to next expected block number\"\n );\n\n require(\n computeL2Timestamp(_l2BlockNumber) < block.timestamp,\n \"L2OutputOracle: cannot propose L2 output in the future\"\n );\n\n require(\n _outputRoot != bytes32(0),\n \"L2OutputOracle: L2 output proposal cannot be the zero hash\"\n );\n\n if (_l1BlockHash != bytes32(0)) {\n // This check allows the proposer to propose an output based on a given L1 block,\n // without fear that it will be reorged out.\n // It will also revert if the blockheight provided is more than 256 blocks behind the\n // chain tip (as the hash will return as zero). This does open the door to a griefing\n // attack in which the proposer's submission is censored until the block is no longer\n // retrievable, if the proposer is experiencing this attack it can simply leave out the\n // blockhash value, and delay submission until it is confident that the L1 block is\n // finalized.\n require(\n blockhash(_l1BlockNumber) == _l1BlockHash,\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n }\n\n emit OutputProposed(_outputRoot, nextOutputIndex(), _l2BlockNumber, block.timestamp);\n\n l2Outputs.push(\n Types.OutputProposal({\n outputRoot: _outputRoot,\n timestamp: uint128(block.timestamp),\n l2BlockNumber: uint128(_l2BlockNumber)\n })\n );\n }\n\n /**\n * @notice Returns an output by index. Exists because Solidity's array access will return a\n * tuple instead of a struct.\n *\n * @param _l2OutputIndex Index of the output to return.\n *\n * @return The output at the given index.\n */\n function getL2Output(uint256 _l2OutputIndex)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[_l2OutputIndex];\n }\n\n /**\n * @notice Returns the index of the L2 output that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return Index of the first checkpoint that commits to the given L2 block number.\n */\n function getL2OutputIndexAfter(uint256 _l2BlockNumber) public view returns (uint256) {\n // Make sure an output for this block number has actually been proposed.\n require(\n _l2BlockNumber <= latestBlockNumber(),\n \"L2OutputOracle: cannot get output for a block that has not been proposed\"\n );\n\n // Make sure there's at least one output proposed.\n require(\n l2Outputs.length > 0,\n \"L2OutputOracle: cannot get output as no outputs have been proposed yet\"\n );\n\n // Find the output via binary search, guaranteed to exist.\n uint256 lo = 0;\n uint256 hi = l2Outputs.length;\n while (lo < hi) {\n uint256 mid = (lo + hi) / 2;\n if (l2Outputs[mid].l2BlockNumber < _l2BlockNumber) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n return lo;\n }\n\n /**\n * @notice Returns the L2 output proposal that checkpoints a given L2 block number. Uses a\n * binary search to find the first output greater than or equal to the given block.\n *\n * @param _l2BlockNumber L2 block number to find a checkpoint for.\n *\n * @return First checkpoint that commits to the given L2 block number.\n */\n function getL2OutputAfter(uint256 _l2BlockNumber)\n external\n view\n returns (Types.OutputProposal memory)\n {\n return l2Outputs[getL2OutputIndexAfter(_l2BlockNumber)];\n }\n\n /**\n * @notice Returns the number of outputs that have been proposed. Will revert if no outputs\n * have been proposed yet.\n *\n * @return The number of outputs that have been proposed.\n */\n function latestOutputIndex() external view returns (uint256) {\n return l2Outputs.length - 1;\n }\n\n /**\n * @notice Returns the index of the next output to be proposed.\n *\n * @return The index of the next output to be proposed.\n */\n function nextOutputIndex() public view returns (uint256) {\n return l2Outputs.length;\n }\n\n /**\n * @notice Returns the block number of the latest submitted L2 output proposal. If no proposals\n * been submitted yet then this function will return the starting block number.\n *\n * @return Latest submitted L2 block number.\n */\n function latestBlockNumber() public view returns (uint256) {\n return\n l2Outputs.length == 0\n ? startingBlockNumber\n : l2Outputs[l2Outputs.length - 1].l2BlockNumber;\n }\n\n /**\n * @notice Computes the block number of the next L2 block that needs to be checkpointed.\n *\n * @return Next L2 block number.\n */\n function nextBlockNumber() public view returns (uint256) {\n return latestBlockNumber() + SUBMISSION_INTERVAL;\n }\n\n /**\n * @notice Returns the L2 timestamp corresponding to a given L2 block number.\n *\n * @param _l2BlockNumber The L2 block number of the target block.\n *\n * @return L2 timestamp of the given block.\n */\n function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {\n return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME);\n }\n}\n" - }, - "contracts/L1/OptimismPortal.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { L2OutputOracle } from \"./L2OutputOracle.sol\";\nimport { SystemConfig } from \"./SystemConfig.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { SecureMerkleTrie } from \"../libraries/trie/SecureMerkleTrie.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @title OptimismPortal\n * @notice The OptimismPortal is a low-level contract responsible for passing messages between L1\n * and L2. Messages sent directly to the OptimismPortal have no form of replayability.\n * Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface.\n */\ncontract OptimismPortal is Initializable, ResourceMetering, Semver {\n /**\n * @notice Represents a proven withdrawal.\n *\n * @custom:field outputRoot Root of the L2 output this was proven against.\n * @custom:field timestamp Timestamp at whcih the withdrawal was proven.\n * @custom:field l2OutputIndex Index of the output this was proven against.\n */\n struct ProvenWithdrawal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2OutputIndex;\n }\n\n /**\n * @notice Version of the deposit event.\n */\n uint256 internal constant DEPOSIT_VERSION = 0;\n\n /**\n * @notice The L2 gas limit set when eth is deposited using the receive() function.\n */\n uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Address of the L2OutputOracle contract.\n */\n L2OutputOracle public immutable L2_ORACLE;\n\n /**\n * @notice Address of the SystemConfig contract.\n */\n SystemConfig public immutable SYSTEM_CONFIG;\n\n /**\n * @notice Address that has the ability to pause and unpause withdrawals.\n */\n address public immutable GUARDIAN;\n\n /**\n * @notice Address of the L2 account which initiated a withdrawal in this transaction. If the\n * of this variable is the default L2 sender address, then we are NOT inside of a call\n * to finalizeWithdrawalTransaction.\n */\n address public l2Sender;\n\n /**\n * @notice A list of withdrawal hashes which have been successfully finalized.\n */\n mapping(bytes32 => bool) public finalizedWithdrawals;\n\n /**\n * @notice A mapping of withdrawal hashes to `ProvenWithdrawal` data.\n */\n mapping(bytes32 => ProvenWithdrawal) public provenWithdrawals;\n\n /**\n * @notice Determines if cross domain messaging is paused. When set to true,\n * deposits and withdrawals are paused. This may be removed in the\n * future.\n */\n bool public paused;\n\n /**\n * @notice Emitted when a transaction is deposited from L1 to L2. The parameters of this event\n * are read by the rollup node and used to derive deposit transactions on L2.\n *\n * @param from Address that triggered the deposit transaction.\n * @param to Address that the deposit transaction is directed to.\n * @param version Version of this deposit transaction event.\n * @param opaqueData ABI encoded deposit data to be parsed off-chain.\n */\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is proven.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n */\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n /**\n * @notice Emitted when a withdrawal transaction is finalized.\n *\n * @param withdrawalHash Hash of the withdrawal transaction.\n * @param success Whether the withdrawal transaction was successful.\n */\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n\n /**\n * @notice Emitted when the pause is triggered.\n *\n * @param account Address of the account triggering the pause.\n */\n event Paused(address account);\n\n /**\n * @notice Emitted when the pause is lifted.\n *\n * @param account Address of the account triggering the unpause.\n */\n event Unpaused(address account);\n\n /**\n * @notice Reverts when paused.\n */\n modifier whenNotPaused() {\n require(paused == false, \"OptimismPortal: paused\");\n _;\n }\n\n /**\n * @custom:semver 1.3.0\n *\n * @param _l2Oracle Address of the L2OutputOracle contract.\n * @param _guardian Address that can pause deposits and withdrawals.\n * @param _paused Sets the contract's pausability state.\n * @param _config Address of the SystemConfig contract.\n */\n constructor(\n L2OutputOracle _l2Oracle,\n address _guardian,\n bool _paused,\n SystemConfig _config\n ) Semver(1, 3, 0) {\n L2_ORACLE = _l2Oracle;\n GUARDIAN = _guardian;\n SYSTEM_CONFIG = _config;\n initialize(_paused);\n }\n\n /**\n * @notice Initializer.\n */\n function initialize(bool _paused) public initializer {\n l2Sender = Constants.DEFAULT_L2_SENDER;\n paused = _paused;\n __ResourceMetering_init();\n }\n\n /**\n * @notice Pause deposits and withdrawals.\n */\n function pause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can pause\");\n paused = true;\n emit Paused(msg.sender);\n }\n\n /**\n * @notice Unpause deposits and withdrawals.\n */\n function unpause() external {\n require(msg.sender == GUARDIAN, \"OptimismPortal: only guardian can unpause\");\n paused = false;\n emit Unpaused(msg.sender);\n }\n\n /**\n * @notice Accepts value so that users can send ETH directly to this contract and have the\n * funds be deposited to their address on L2. This is intended as a convenience\n * function for EOAs. Contracts should call the depositTransaction() function directly\n * otherwise any deposited funds will be lost due to address aliasing.\n */\n // solhint-disable-next-line ordering\n receive() external payable {\n depositTransaction(msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes(\"\"));\n }\n\n /**\n * @notice Accepts ETH value without triggering a deposit to L2. This function mainly exists\n * for the sake of the migration between the legacy Optimism system and Bedrock.\n */\n function donateETH() external payable {\n // Intentionally empty.\n }\n\n /**\n * @notice Getter for the resource config. Used internally by the ResourceMetering\n * contract. The SystemConfig is the source of truth for the resource config.\n *\n * @return ResourceMetering.ResourceConfig\n */\n function _resourceConfig()\n internal\n view\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return SYSTEM_CONFIG.resourceConfig();\n }\n\n /**\n * @notice Proves a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n * @param _l2OutputIndex L2 output index to prove against.\n * @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root.\n * @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\n */\n function proveWithdrawalTransaction(\n Types.WithdrawalTransaction memory _tx,\n uint256 _l2OutputIndex,\n Types.OutputRootProof calldata _outputRootProof,\n bytes[] calldata _withdrawalProof\n ) external whenNotPaused {\n // Prevent users from creating a deposit transaction where this address is the message\n // sender on L2. Because this is checked here, we do not need to check again in\n // `finalizeWithdrawalTransaction`.\n require(\n _tx.target != address(this),\n \"OptimismPortal: you cannot send messages to the portal contract\"\n );\n\n // Get the output root and load onto the stack to prevent multiple mloads. This will\n // revert if there is no output root for the given block number.\n bytes32 outputRoot = L2_ORACLE.getL2Output(_l2OutputIndex).outputRoot;\n\n // Verify that the output root can be generated with the elements in the proof.\n require(\n outputRoot == Hashing.hashOutputRootProof(_outputRootProof),\n \"OptimismPortal: invalid output root proof\"\n );\n\n // Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // We generally want to prevent users from proving the same withdrawal multiple times\n // because each successive proof will update the timestamp. A malicious user can take\n // advantage of this to prevent other users from finalizing their withdrawal. However,\n // since withdrawals are proven before an output root is finalized, we need to allow users\n // to re-prove their withdrawal only in the case that the output root for their specified\n // output index has been updated.\n require(\n provenWithdrawal.timestamp == 0 ||\n L2_ORACLE.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot !=\n provenWithdrawal.outputRoot,\n \"OptimismPortal: withdrawal hash has already been proven\"\n );\n\n // Compute the storage slot of the withdrawal hash in the L2ToL1MessagePasser contract.\n // Refer to the Solidity documentation for more information on how storage layouts are\n // computed for mappings.\n bytes32 storageKey = keccak256(\n abi.encode(\n withdrawalHash,\n uint256(0) // The withdrawals mapping is at the first slot in the layout.\n )\n );\n\n // Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract\n // on L2. If this is true, under the assumption that the SecureMerkleTrie does not have\n // bugs, then we know that this withdrawal was actually triggered on L2 and can therefore\n // be relayed on L1.\n require(\n SecureMerkleTrie.verifyInclusionProof(\n abi.encode(storageKey),\n hex\"01\",\n _withdrawalProof,\n _outputRootProof.messagePasserStorageRoot\n ),\n \"OptimismPortal: invalid withdrawal inclusion proof\"\n );\n\n // Designate the withdrawalHash as proven by storing the `outputRoot`, `timestamp`, and\n // `l2BlockNumber` in the `provenWithdrawals` mapping. A `withdrawalHash` can only be\n // proven once unless it is submitted again with a different outputRoot.\n provenWithdrawals[withdrawalHash] = ProvenWithdrawal({\n outputRoot: outputRoot,\n timestamp: uint128(block.timestamp),\n l2OutputIndex: uint128(_l2OutputIndex)\n });\n\n // Emit a `WithdrawalProven` event.\n emit WithdrawalProven(withdrawalHash, _tx.sender, _tx.target);\n }\n\n /**\n * @notice Finalizes a withdrawal transaction.\n *\n * @param _tx Withdrawal transaction to finalize.\n */\n function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx)\n external\n whenNotPaused\n {\n // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other\n // than the default value when a withdrawal transaction is being finalized. This check is\n // a defacto reentrancy guard.\n require(\n l2Sender == Constants.DEFAULT_L2_SENDER,\n \"OptimismPortal: can only trigger one withdrawal per transaction\"\n );\n\n // Grab the proven withdrawal from the `provenWithdrawals` map.\n bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx);\n ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash];\n\n // A withdrawal can only be finalized if it has been proven. We know that a withdrawal has\n // been proven at least once when its timestamp is non-zero. Unproven withdrawals will have\n // a timestamp of zero.\n require(\n provenWithdrawal.timestamp != 0,\n \"OptimismPortal: withdrawal has not been proven yet\"\n );\n\n // As a sanity check, we make sure that the proven withdrawal's timestamp is greater than\n // starting timestamp inside the L2OutputOracle. Not strictly necessary but extra layer of\n // safety against weird bugs in the proving step.\n require(\n provenWithdrawal.timestamp >= L2_ORACLE.startingTimestamp(),\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n\n // A proven withdrawal must wait at least the finalization period before it can be\n // finalized. This waiting period can elapse in parallel with the waiting period for the\n // output the withdrawal was proven against. In effect, this means that the minimum\n // withdrawal time is proposal submission time + finalization period.\n require(\n _isFinalizationPeriodElapsed(provenWithdrawal.timestamp),\n \"OptimismPortal: proven withdrawal finalization period has not elapsed\"\n );\n\n // Grab the OutputProposal from the L2OutputOracle, will revert if the output that\n // corresponds to the given index has not been proposed yet.\n Types.OutputProposal memory proposal = L2_ORACLE.getL2Output(\n provenWithdrawal.l2OutputIndex\n );\n\n // Check that the output root that was used to prove the withdrawal is the same as the\n // current output root for the given output index. An output root may change if it is\n // deleted by the challenger address and then re-proposed.\n require(\n proposal.outputRoot == provenWithdrawal.outputRoot,\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n\n // Check that the output proposal has also been finalized.\n require(\n _isFinalizationPeriodElapsed(proposal.timestamp),\n \"OptimismPortal: output proposal finalization period has not elapsed\"\n );\n\n // Check that this withdrawal has not already been finalized, this is replay protection.\n require(\n finalizedWithdrawals[withdrawalHash] == false,\n \"OptimismPortal: withdrawal has already been finalized\"\n );\n\n // Mark the withdrawal as finalized so it can't be replayed.\n finalizedWithdrawals[withdrawalHash] = true;\n\n // Set the l2Sender so contracts know who triggered this withdrawal on L2.\n l2Sender = _tx.sender;\n\n // Trigger the call to the target contract. We use a custom low level method\n // SafeCall.callWithMinGas to ensure two key properties\n // 1. Target contracts cannot force this call to run out of gas by returning a very large\n // amount of data (and this is OK because we don't care about the returndata here).\n // 2. The amount of gas provided to the call to the target contract is at least the gas\n // limit specified by the user. If there is not enough gas in the callframe to\n // accomplish this, `callWithMinGas` will revert.\n // Additionally, if there is not enough gas remaining to complete the execution after the\n // call returns, this function will revert.\n bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data);\n\n // Reset the l2Sender back to the default value.\n l2Sender = Constants.DEFAULT_L2_SENDER;\n\n // All withdrawals are immediately finalized. Replayability can\n // be achieved through contracts built on top of this contract\n emit WithdrawalFinalized(withdrawalHash, success);\n\n // Reverting here is useful for determining the exact gas cost to successfully execute the\n // sub call to the target contract if the minimum gas limit specified by the user would not\n // be sufficient to execute the sub call.\n if (success == false && tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"OptimismPortal: withdrawal failed\");\n }\n }\n\n /**\n * @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in\n * deriving deposit transactions. Note that if a deposit is made by a contract, its\n * address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider\n * using the CrossDomainMessenger contracts for a simpler developer experience.\n *\n * @param _to Target address on L2.\n * @param _value ETH value to send to the recipient.\n * @param _gasLimit Minimum L2 gas limit (can be greater than or equal to this value).\n * @param _isCreation Whether or not the transaction is a contract creation.\n * @param _data Data to trigger the recipient with.\n */\n function depositTransaction(\n address _to,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable metered(_gasLimit) {\n // Just to be safe, make sure that people specify address(0) as the target when doing\n // contract creations.\n if (_isCreation) {\n require(\n _to == address(0),\n \"OptimismPortal: must send to address(0) when creating a contract\"\n );\n }\n\n // Prevent depositing transactions that have too small of a gas limit.\n require(_gasLimit >= 21_000, \"OptimismPortal: gas limit must cover instrinsic gas cost\");\n\n // Transform the from-address to its alias if the caller is a contract.\n address from = msg.sender;\n if (msg.sender != tx.origin) {\n from = AddressAliasHelper.applyL1ToL2Alias(msg.sender);\n }\n\n // Compute the opaque data that will be emitted as part of the TransactionDeposited event.\n // We use opaque data so that we can update the TransactionDeposited event in the future\n // without breaking the current interface.\n bytes memory opaqueData = abi.encodePacked(\n msg.value,\n _value,\n _gasLimit,\n _isCreation,\n _data\n );\n\n // Emit a TransactionDeposited event so that the rollup node can derive a deposit\n // transaction for this deposit.\n emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);\n }\n\n /**\n * @notice Determine if a given output is finalized. Reverts if the call to\n * L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\n *\n * @param _l2OutputIndex Index of the L2 output to check.\n *\n * @return Whether or not the output is finalized.\n */\n function isOutputFinalized(uint256 _l2OutputIndex) external view returns (bool) {\n return _isFinalizationPeriodElapsed(L2_ORACLE.getL2Output(_l2OutputIndex).timestamp);\n }\n\n /**\n * @notice Determines whether the finalization period has elapsed w/r/t a given timestamp.\n *\n * @param _timestamp Timestamp to check.\n *\n * @return Whether or not the finalization period has elapsed.\n */\n function _isFinalizationPeriodElapsed(uint256 _timestamp) internal view returns (bool) {\n return block.timestamp > _timestamp + L2_ORACLE.FINALIZATION_PERIOD_SECONDS();\n }\n}\n" - }, - "contracts/L1/ResourceMetering.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\n\n/**\n * @custom:upgradeable\n * @title ResourceMetering\n * @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing\n * updates automatically based on current demand.\n */\nabstract contract ResourceMetering is Initializable {\n /**\n * @notice Represents the various parameters that control the way in which resources are\n * metered. Corresponds to the EIP-1559 resource metering system.\n *\n * @custom:field prevBaseFee Base fee from the previous block(s).\n * @custom:field prevBoughtGas Amount of gas bought so far in the current block.\n * @custom:field prevBlockNum Last block number that the base fee was updated.\n */\n struct ResourceParams {\n uint128 prevBaseFee;\n uint64 prevBoughtGas;\n uint64 prevBlockNum;\n }\n\n /**\n * @notice Represents the configuration for the EIP-1559 based curve for the deposit gas\n * market. These values should be set with care as it is possible to set them in\n * a way that breaks the deposit gas market. The target resource limit is defined as\n * maxResourceLimit / elasticityMultiplier. This struct was designed to fit within a\n * single word. There is additional space for additions in the future.\n *\n * @custom:field maxResourceLimit Represents the maximum amount of deposit gas that\n * can be purchased per block.\n * @custom:field elasticityMultiplier Determines the target resource limit along with\n * the resource limit.\n * @custom:field baseFeeMaxChangeDenominator Determines max change on fee per block.\n * @custom:field minimumBaseFee The min deposit base fee, it is clamped to this\n * value.\n * @custom:field systemTxMaxGas The amount of gas supplied to the system\n * transaction. This should be set to the same number\n * that the op-node sets as the gas limit for the\n * system transaction.\n * @custom:field maximumBaseFee The max deposit base fee, it is clamped to this\n * value.\n */\n struct ResourceConfig {\n uint32 maxResourceLimit;\n uint8 elasticityMultiplier;\n uint8 baseFeeMaxChangeDenominator;\n uint32 minimumBaseFee;\n uint32 systemTxMaxGas;\n uint128 maximumBaseFee;\n }\n\n /**\n * @notice EIP-1559 style gas parameters.\n */\n ResourceParams public params;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[48] private __gap;\n\n /**\n * @notice Meters access to a function based an amount of a requested resource.\n *\n * @param _amount Amount of the resource requested.\n */\n modifier metered(uint64 _amount) {\n // Record initial gas amount so we can refund for it later.\n uint256 initialGas = gasleft();\n\n // Run the underlying function.\n _;\n\n // Run the metering function.\n _metered(_amount, initialGas);\n }\n\n /**\n * @notice An internal function that holds all of the logic for metering a resource.\n *\n * @param _amount Amount of the resource requested.\n * @param _initialGas The amount of gas before any modifier execution.\n */\n function _metered(uint64 _amount, uint256 _initialGas) internal {\n // Update block number and base fee if necessary.\n uint256 blockDiff = block.number - params.prevBlockNum;\n\n ResourceConfig memory config = _resourceConfig();\n int256 targetResourceLimit = int256(uint256(config.maxResourceLimit)) /\n int256(uint256(config.elasticityMultiplier));\n\n if (blockDiff > 0) {\n // Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate\n // at which deposits can be created and therefore limit the potential for deposits to\n // spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.\n int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit;\n int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) /\n (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));\n\n // Update base fee by adding the base fee delta and clamp the resulting value between\n // min and max.\n int256 newBaseFee = Arithmetic.clamp({\n _value: int256(uint256(params.prevBaseFee)) + baseFeeDelta,\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n\n // If we skipped more than one block, we also need to account for every empty block.\n // Empty block means there was no demand for deposits in that block, so we should\n // reflect this lack of demand in the fee.\n if (blockDiff > 1) {\n // Update the base fee by repeatedly applying the exponent 1-(1/change_denominator)\n // blockDiff - 1 times. Simulates multiple empty blocks. Clamp the resulting value\n // between min and max.\n newBaseFee = Arithmetic.clamp({\n _value: Arithmetic.cdexp({\n _coefficient: newBaseFee,\n _denominator: int256(uint256(config.baseFeeMaxChangeDenominator)),\n _exponent: int256(blockDiff - 1)\n }),\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n }\n\n // Update new base fee, reset bought gas, and update block number.\n params.prevBaseFee = uint128(uint256(newBaseFee));\n params.prevBoughtGas = 0;\n params.prevBlockNum = uint64(block.number);\n }\n\n // Make sure we can actually buy the resource amount requested by the user.\n params.prevBoughtGas += _amount;\n require(\n int256(uint256(params.prevBoughtGas)) <= int256(uint256(config.maxResourceLimit)),\n \"ResourceMetering: cannot buy more gas than available gas limit\"\n );\n\n // Determine the amount of ETH to be paid.\n uint256 resourceCost = uint256(_amount) * uint256(params.prevBaseFee);\n\n // We currently charge for this ETH amount as an L1 gas burn, so we convert the ETH amount\n // into gas by dividing by the L1 base fee. We assume a minimum base fee of 1 gwei to avoid\n // division by zero for L1s that don't support 1559 or to avoid excessive gas burns during\n // periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei\n // during any 1 day period in the last 5 years, so should be fine.\n uint256 gasCost = resourceCost / Math.max(block.basefee, 1 gwei);\n\n // Give the user a refund based on the amount of gas they used to do all of the work up to\n // this point. Since we're at the end of the modifier, this should be pretty accurate. Acts\n // effectively like a dynamic stipend (with a minimum value).\n uint256 usedGas = _initialGas - gasleft();\n if (gasCost > usedGas) {\n Burn.gas(gasCost - usedGas);\n }\n }\n\n /**\n * @notice Virtual function that returns the resource config. Contracts that inherit this\n * contract must implement this function.\n *\n * @return ResourceConfig\n */\n function _resourceConfig() internal virtual returns (ResourceConfig memory);\n\n /**\n * @notice Sets initial resource parameter values. This function must either be called by the\n * initializer function of an upgradeable child contract.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __ResourceMetering_init() internal onlyInitializing {\n params = ResourceParams({\n prevBaseFee: 1 gwei,\n prevBoughtGas: 0,\n prevBlockNum: uint64(block.number)\n });\n }\n}\n" - }, - "contracts/L1/SystemConfig.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { ResourceMetering } from \"./ResourceMetering.sol\";\n\n/**\n * @title SystemConfig\n * @notice The SystemConfig contract is used to manage configuration of an Optimism network. All\n * configuration is stored on L1 and picked up by L2 as part of the derviation of the L2\n * chain.\n */\ncontract SystemConfig is OwnableUpgradeable, Semver {\n /**\n * @notice Enum representing different types of updates.\n *\n * @custom:value BATCHER Represents an update to the batcher hash.\n * @custom:value GAS_CONFIG Represents an update to txn fee config on L2.\n * @custom:value GAS_LIMIT Represents an update to gas limit on L2.\n * @custom:value UNSAFE_BLOCK_SIGNER Represents an update to the signer key for unsafe\n * block distrubution.\n */\n enum UpdateType {\n BATCHER,\n GAS_CONFIG,\n GAS_LIMIT,\n UNSAFE_BLOCK_SIGNER\n }\n\n /**\n * @notice Version identifier, used for upgrades.\n */\n uint256 public constant VERSION = 0;\n\n /**\n * @notice Storage slot that the unsafe block signer is stored at. Storing it at this\n * deterministic storage slot allows for decoupling the storage layout from the way\n * that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value.\n */\n bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256(\"systemconfig.unsafeblocksigner\");\n\n /**\n * @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public overhead;\n\n /**\n * @notice Dynamic L2 gas overhead. Used as part of the L2 fee calculation.\n */\n uint256 public scalar;\n\n /**\n * @notice Identifier for the batcher. For version 1 of this configuration, this is represented\n * as an address left-padded with zeros to 32 bytes.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice L2 block gas limit.\n */\n uint64 public gasLimit;\n\n /**\n * @notice The configuration for the deposit fee market. Used by the OptimismPortal\n * to meter the cost of buying L2 gas on L1. Set as internal and wrapped with a getter\n * so that the struct is returned instead of a tuple.\n */\n ResourceMetering.ResourceConfig internal _resourceConfig;\n\n /**\n * @notice Emitted when configuration is updated\n *\n * @param version SystemConfig version.\n * @param updateType Type of update.\n * @param data Encoded update data.\n */\n event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);\n\n /**\n * @custom:semver 1.2.0\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial resource config.\n */\n constructor(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) Semver(1, 2, 0) {\n initialize({\n _owner: _owner,\n _overhead: _overhead,\n _scalar: _scalar,\n _batcherHash: _batcherHash,\n _gasLimit: _gasLimit,\n _unsafeBlockSigner: _unsafeBlockSigner,\n _config: _config\n });\n }\n\n /**\n * @notice Initializer. The resource config must be set before the\n * require check.\n *\n * @param _owner Initial owner of the contract.\n * @param _overhead Initial overhead value.\n * @param _scalar Initial scalar value.\n * @param _batcherHash Initial batcher hash.\n * @param _gasLimit Initial gas limit.\n * @param _unsafeBlockSigner Initial unsafe block signer address.\n * @param _config Initial ResourceConfig.\n */\n function initialize(\n address _owner,\n uint256 _overhead,\n uint256 _scalar,\n bytes32 _batcherHash,\n uint64 _gasLimit,\n address _unsafeBlockSigner,\n ResourceMetering.ResourceConfig memory _config\n ) public initializer {\n __Ownable_init();\n transferOwnership(_owner);\n overhead = _overhead;\n scalar = _scalar;\n batcherHash = _batcherHash;\n gasLimit = _gasLimit;\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n _setResourceConfig(_config);\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n }\n\n /**\n * @notice Returns the minimum L2 gas limit that can be safely set for the system to\n * operate. The L2 gas limit must be larger than or equal to the amount of\n * gas that is allocated for deposits per block plus the amount of gas that\n * is allocated for the system transaction.\n * This function is used to determine if changes to parameters are safe.\n *\n * @return uint64\n */\n function minimumGasLimit() public view returns (uint64) {\n return uint64(_resourceConfig.maxResourceLimit) + uint64(_resourceConfig.systemTxMaxGas);\n }\n\n /**\n * @notice High level getter for the unsafe block signer address. Unsafe blocks can be\n * propagated across the p2p network if they are signed by the key corresponding to\n * this address.\n *\n * @return Address of the unsafe block signer.\n */\n // solhint-disable-next-line ordering\n function unsafeBlockSigner() external view returns (address) {\n address addr;\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n addr := sload(slot)\n }\n return addr;\n }\n\n /**\n * @notice Updates the unsafe block signer address.\n *\n * @param _unsafeBlockSigner New unsafe block signer address.\n */\n function setUnsafeBlockSigner(address _unsafeBlockSigner) external onlyOwner {\n _setUnsafeBlockSigner(_unsafeBlockSigner);\n\n bytes memory data = abi.encode(_unsafeBlockSigner);\n emit ConfigUpdate(VERSION, UpdateType.UNSAFE_BLOCK_SIGNER, data);\n }\n\n /**\n * @notice Updates the batcher hash.\n *\n * @param _batcherHash New batcher hash.\n */\n function setBatcherHash(bytes32 _batcherHash) external onlyOwner {\n batcherHash = _batcherHash;\n\n bytes memory data = abi.encode(_batcherHash);\n emit ConfigUpdate(VERSION, UpdateType.BATCHER, data);\n }\n\n /**\n * @notice Updates gas config.\n *\n * @param _overhead New overhead value.\n * @param _scalar New scalar value.\n */\n function setGasConfig(uint256 _overhead, uint256 _scalar) external onlyOwner {\n overhead = _overhead;\n scalar = _scalar;\n\n bytes memory data = abi.encode(_overhead, _scalar);\n emit ConfigUpdate(VERSION, UpdateType.GAS_CONFIG, data);\n }\n\n /**\n * @notice Updates the L2 gas limit.\n *\n * @param _gasLimit New gas limit.\n */\n function setGasLimit(uint64 _gasLimit) external onlyOwner {\n require(_gasLimit >= minimumGasLimit(), \"SystemConfig: gas limit too low\");\n gasLimit = _gasLimit;\n\n bytes memory data = abi.encode(_gasLimit);\n emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data);\n }\n\n /**\n * @notice Low level setter for the unsafe block signer address. This function exists to\n * deduplicate code around storing the unsafeBlockSigner address in storage.\n *\n * @param _unsafeBlockSigner New unsafeBlockSigner value.\n */\n function _setUnsafeBlockSigner(address _unsafeBlockSigner) internal {\n bytes32 slot = UNSAFE_BLOCK_SIGNER_SLOT;\n assembly {\n sstore(slot, _unsafeBlockSigner)\n }\n }\n\n /**\n * @notice A getter for the resource config. Ensures that the struct is\n * returned instead of a tuple.\n *\n * @return ResourceConfig\n */\n function resourceConfig() external view returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig;\n }\n\n /**\n * @notice An external setter for the resource config. In the future, this\n * method may emit an event that the `op-node` picks up for when the\n * resource config is changed.\n *\n * @param _config The new resource config values.\n */\n function setResourceConfig(ResourceMetering.ResourceConfig memory _config) external onlyOwner {\n _setResourceConfig(_config);\n }\n\n /**\n * @notice An internal setter for the resource config. Ensures that the\n * config is sane before storing it by checking for invariants.\n *\n * @param _config The new resource config.\n */\n function _setResourceConfig(ResourceMetering.ResourceConfig memory _config) internal {\n // Min base fee must be less than or equal to max base fee.\n require(\n _config.minimumBaseFee <= _config.maximumBaseFee,\n \"SystemConfig: min base fee must be less than max base\"\n );\n // Base fee change denominator must be greater than 0.\n require(_config.baseFeeMaxChangeDenominator > 0, \"SystemConfig: denominator cannot be 0\");\n // Max resource limit plus system tx gas must be less than or equal to the L2 gas limit.\n // The gas limit must be increased before these values can be increased.\n require(\n _config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit,\n \"SystemConfig: gas limit too low\"\n );\n // Elasticity multiplier must be greater than 0.\n require(\n _config.elasticityMultiplier > 0,\n \"SystemConfig: elasticity multiplier cannot be 0\"\n );\n // No precision loss when computing target resource limit.\n require(\n ((_config.maxResourceLimit / _config.elasticityMultiplier) *\n _config.elasticityMultiplier) == _config.maxResourceLimit,\n \"SystemConfig: precision loss with target resource limit\"\n );\n\n _resourceConfig = _config;\n }\n}\n" - }, - "contracts/L2/BaseFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000019\n * @title BaseFeeVault\n * @notice The BaseFeeVault accumulates the base fee that is paid by transactions.\n */\ncontract BaseFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n}\n" - }, - "contracts/L2/CrossDomainOwnable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\n/**\n * @title CrossDomainOwnable\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is only safe to be used if the\n * CrossDomainMessenger system is bypassed and the caller on L1 is calling the\n * OptimismPortal directly.\n */\nabstract contract CrossDomainOwnable is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `msg.sender` is the owner of the contract.\n */\n function _checkOwner() internal view override {\n require(\n owner() == AddressAliasHelper.undoL1ToL2Alias(msg.sender),\n \"CrossDomainOwnable: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable2\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on L1. Note that this contract is meant to be used with systems that use\n * the CrossDomainMessenger system. It will not work if the OptimismPortal is used\n * directly.\n */\nabstract contract CrossDomainOwnable2 is Ownable {\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable2: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable2: caller is not the owner\"\n );\n }\n}\n" - }, - "contracts/L2/CrossDomainOwnable3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L2CrossDomainMessenger } from \"./L2CrossDomainMessenger.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title CrossDomainOwnable3\n * @notice This contract extends the OpenZeppelin `Ownable` contract for L2 contracts to be owned\n * by contracts on either L1 or L2. Note that this contract is meant to be used with systems\n * that use the CrossDomainMessenger system. It will not work if the OptimismPortal is\n * used directly.\n */\nabstract contract CrossDomainOwnable3 is Ownable {\n /**\n * @notice If true, the contract uses the cross domain _checkOwner function override. If false\n * it uses the standard Ownable _checkOwner function.\n */\n bool public isLocal = true;\n\n /**\n * @notice Emits when ownership of the contract is transferred. Includes the\n * isLocal field in addition to the standard `Ownable` OwnershipTransferred event.\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n /**\n * @notice Allows for ownership to be transferred with specifying the locality.\n * @param _owner The new owner of the contract.\n * @param _isLocal Configures the locality of the ownership.\n */\n function transferOwnership(address _owner, bool _isLocal) external onlyOwner {\n require(_owner != address(0), \"CrossDomainOwnable3: new owner is the zero address\");\n\n address oldOwner = owner();\n _transferOwnership(_owner);\n isLocal = _isLocal;\n\n emit OwnershipTransferred(oldOwner, _owner, _isLocal);\n }\n\n /**\n * @notice Overrides the implementation of the `onlyOwner` modifier to check that the unaliased\n * `xDomainMessageSender` is the owner of the contract. This value is set to the caller\n * of the L1CrossDomainMessenger.\n */\n function _checkOwner() internal view override {\n if (isLocal) {\n require(owner() == msg.sender, \"CrossDomainOwnable3: caller is not the owner\");\n } else {\n L2CrossDomainMessenger messenger = L2CrossDomainMessenger(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER\n );\n\n require(\n msg.sender == address(messenger),\n \"CrossDomainOwnable3: caller is not the messenger\"\n );\n\n require(\n owner() == messenger.xDomainMessageSender(),\n \"CrossDomainOwnable3: caller is not the owner\"\n );\n }\n }\n}\n" - }, - "contracts/L2/GasPriceOracle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000000F\n * @title GasPriceOracle\n * @notice This contract maintains the variables responsible for computing the L1 portion of the\n * total fee charged on L2. Before Bedrock, this contract held variables in state that were\n * read during the state transition function to compute the L1 portion of the transaction\n * fee. After Bedrock, this contract now simply proxies the L1Block contract, which has\n * the values used to compute the L1 portion of the fee in its state.\n *\n * The contract exposes an API that is useful for knowing how large the L1 portion of the\n * transaction fee will be. The following events were deprecated with Bedrock:\n * - event OverheadUpdated(uint256 overhead);\n * - event ScalarUpdated(uint256 scalar);\n * - event DecimalsUpdated(uint256 decimals);\n */\ncontract GasPriceOracle is Semver {\n /**\n * @notice Number of decimals used in the scalar.\n */\n uint256 public constant DECIMALS = 6;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Computes the L1 portion of the fee based on the size of the rlp encoded input\n * transaction, the current L1 base fee, and the various dynamic parameters.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.\n *\n * @return L1 fee that should be paid for the tx\n */\n function getL1Fee(bytes memory _data) external view returns (uint256) {\n uint256 l1GasUsed = getL1GasUsed(_data);\n uint256 l1Fee = l1GasUsed * l1BaseFee();\n uint256 divisor = 10**DECIMALS;\n uint256 unscaled = l1Fee * scalar();\n uint256 scaled = unscaled / divisor;\n return scaled;\n }\n\n /**\n * @notice Retrieves the current gas price (base fee).\n *\n * @return Current L2 gas price (base fee).\n */\n function gasPrice() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current base fee.\n *\n * @return Current L2 base fee.\n */\n function baseFee() public view returns (uint256) {\n return block.basefee;\n }\n\n /**\n * @notice Retrieves the current fee overhead.\n *\n * @return Current fee overhead.\n */\n function overhead() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead();\n }\n\n /**\n * @notice Retrieves the current fee scalar.\n *\n * @return Current fee scalar.\n */\n function scalar() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar();\n }\n\n /**\n * @notice Retrieves the latest known L1 base fee.\n *\n * @return Latest known L1 base fee.\n */\n function l1BaseFee() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee();\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the number of decimals used in the scalar.\n *\n * @return Number of decimals used in the scalar.\n */\n function decimals() public pure returns (uint256) {\n return DECIMALS;\n }\n\n /**\n * @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which\n * represents the per-transaction gas overhead of posting the transaction and state\n * roots to L1. Adds 68 bytes of padding to account for the fact that the input does\n * not have a signature.\n *\n * @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for.\n *\n * @return Amount of L1 gas used to publish the transaction.\n */\n function getL1GasUsed(bytes memory _data) public view returns (uint256) {\n uint256 total = 0;\n uint256 length = _data.length;\n for (uint256 i = 0; i < length; i++) {\n if (_data[i] == 0) {\n total += 4;\n } else {\n total += 16;\n }\n }\n uint256 unsigned = total + overhead();\n return unsigned + (68 * 16);\n }\n}\n" - }, - "contracts/L2/L1Block.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000015\n * @title L1Block\n * @notice The L1Block predeploy gives users access to information about the last known L1 block.\n * Values within this contract are updated once per epoch (every L1 block) and can only be\n * set by the \"depositor\" account, a special system address. Depositor account transactions\n * are created by the protocol whenever we move to a new epoch.\n */\ncontract L1Block is Semver {\n /**\n * @notice Address of the special depositor account.\n */\n address public constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001;\n\n /**\n * @notice The latest L1 block number known by the L2 system.\n */\n uint64 public number;\n\n /**\n * @notice The latest L1 timestamp known by the L2 system.\n */\n uint64 public timestamp;\n\n /**\n * @notice The latest L1 basefee.\n */\n uint256 public basefee;\n\n /**\n * @notice The latest L1 blockhash.\n */\n bytes32 public hash;\n\n /**\n * @notice The number of L2 blocks in the same epoch.\n */\n uint64 public sequenceNumber;\n\n /**\n * @notice The versioned hash to authenticate the batcher by.\n */\n bytes32 public batcherHash;\n\n /**\n * @notice The overhead value applied to the L1 portion of the transaction\n * fee.\n */\n uint256 public l1FeeOverhead;\n\n /**\n * @notice The scalar value applied to the L1 portion of the transaction fee.\n */\n uint256 public l1FeeScalar;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Updates the L1 block values.\n *\n * @param _number L1 blocknumber.\n * @param _timestamp L1 timestamp.\n * @param _basefee L1 basefee.\n * @param _hash L1 blockhash.\n * @param _sequenceNumber Number of L2 blocks since epoch start.\n * @param _batcherHash Versioned hash to authenticate batcher by.\n * @param _l1FeeOverhead L1 fee overhead.\n * @param _l1FeeScalar L1 fee scalar.\n */\n function setL1BlockValues(\n uint64 _number,\n uint64 _timestamp,\n uint256 _basefee,\n bytes32 _hash,\n uint64 _sequenceNumber,\n bytes32 _batcherHash,\n uint256 _l1FeeOverhead,\n uint256 _l1FeeScalar\n ) external {\n require(\n msg.sender == DEPOSITOR_ACCOUNT,\n \"L1Block: only the depositor account can set L1 block values\"\n );\n\n number = _number;\n timestamp = _timestamp;\n basefee = _basefee;\n hash = _hash;\n sequenceNumber = _sequenceNumber;\n batcherHash = _batcherHash;\n l1FeeOverhead = _l1FeeOverhead;\n l1FeeScalar = _l1FeeScalar;\n }\n}\n" - }, - "contracts/L2/L1FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x420000000000000000000000000000000000001A\n * @title L1FeeVault\n * @notice The L1FeeVault accumulates the L1 portion of the transaction fees.\n */\ncontract L1FeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n}\n" - }, - "contracts/L2/L2CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { L2ToL1MessagePasser } from \"./L2ToL1MessagePasser.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000007\n * @title L2CrossDomainMessenger\n * @notice The L2CrossDomainMessenger is a high-level interface for message passing between L1 and\n * L2 on the L2 side. Users are generally encouraged to use this contract instead of lower\n * level message passing contracts.\n */\ncontract L2CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.\n */\n constructor(address _l1CrossDomainMessenger)\n Semver(1, 1, 0)\n CrossDomainMessenger(_l1CrossDomainMessenger)\n {\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote messenger. Use otherMessenger going forward.\n *\n * @return Address of the L1CrossDomainMessenger contract.\n */\n function l1CrossDomainMessenger() public view returns (address) {\n return OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{\n value: _value\n }(_to, _gasLimit, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(Predeploys.L2_TO_L1_MESSAGE_PASSER);\n }\n}\n" - }, - "contracts/L2/L2ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/ERC721Bridge.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { IOptimismMintableERC721 } from \"../universal/IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title L2ERC721Bridge\n * @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.\n * This contract also acts as a burner for tokens being withdrawn.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n */\ncontract L2ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 1, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L1. Data supplied here will not be used to\n * execute any code on L1 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L2ERC721Bridge: local token cannot be self\");\n\n // Note that supportsInterface makes a callback to the _localToken address which is user\n // provided.\n require(\n ERC165Checker.supportsInterface(_localToken, type(IOptimismMintableERC721).interfaceId),\n \"L2ERC721Bridge: local token interface is not compliant\"\n );\n\n require(\n _remoteToken == IOptimismMintableERC721(_localToken).remoteToken(),\n \"L2ERC721Bridge: wrong remote token for Optimism Mintable ERC721 local token\"\n );\n\n // When a deposit is finalized, we give the NFT with the same tokenId to the account\n // on L2. Note that safeMint makes a callback to the _to address which is user provided.\n IOptimismMintableERC721(_localToken).safeMint(_to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"L2ERC721Bridge: remote token cannot be address(0)\");\n\n // Check that the withdrawal is being initiated by the NFT owner\n require(\n _from == IOptimismMintableERC721(_localToken).ownerOf(_tokenId),\n \"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\"\n );\n\n // Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)\n // slither-disable-next-line reentrancy-events\n address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();\n require(\n remoteToken == _remoteToken,\n \"L2ERC721Bridge: remote token does not match given value\"\n );\n\n // When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2\n // usage\n // slither-disable-next-line reentrancy-events\n IOptimismMintableERC721(_localToken).burn(_from, _tokenId);\n\n bytes memory message = abi.encodeWithSelector(\n L1ERC721Bridge.finalizeBridgeERC721.selector,\n remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Send message to L1 bridge\n // slither-disable-next-line reentrancy-events\n MESSENGER.sendMessage(OTHER_BRIDGE, message, _minGasLimit);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n" - }, - "contracts/L2/L2StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000010\n * @title L2StandardBridge\n * @notice The L2StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and\n * L2. In the case that an ERC20 token is native to L2, it will be escrowed within this\n * contract. If the ERC20 token is native to L1, it will be burnt.\n * NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples\n * of some token types that may not be properly supported by this contract include, but are\n * not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.\n */\ncontract L2StandardBridge is StandardBridge, Semver {\n /**\n * @custom:legacy\n * @notice Emitted whenever a withdrawal from L2 to L1 is initiated.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the withdrawer.\n * @param to Address of the recipient on L1.\n * @param amount Amount of the ERC20 withdrawn.\n * @param extraData Extra data attached to the withdrawal.\n */\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:legacy\n * @notice Emitted whenever an ERC20 deposit is finalized.\n *\n * @param l1Token Address of the token on L1.\n * @param l2Token Address of the corresponding token on L2.\n * @param from Address of the depositor.\n * @param to Address of the recipient on L2.\n * @param amount Amount of the ERC20 deposited.\n * @param extraData Extra data attached to the deposit.\n */\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @param _otherBridge Address of the L1StandardBridge.\n */\n constructor(address payable _otherBridge)\n Semver(1, 1, 0)\n StandardBridge(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER), _otherBridge)\n {}\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n */\n receive() external payable override onlyEOA {\n _initiateWithdrawal(\n Predeploys.LEGACY_ERC20_ETH,\n msg.sender,\n msg.sender,\n msg.value,\n RECEIVE_DEFAULT_GAS_LIMIT,\n bytes(\"\")\n );\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdraw(\n address _l2Token,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual onlyEOA {\n _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Initiates a withdrawal from L2 to L1 to a target account on L1.\n * Note that if ETH is sent to a contract on L1 and the call fails, then that ETH will\n * be locked in the L1StandardBridge. ETH may be recoverable if the call can be\n * successfully replayed by increasing the amount of gas supplied to the call. If the\n * call will fail for any amount of gas, then the ETH will be locked permanently.\n * This function only works with OptimismMintableERC20 tokens or ether. Use the\n * `bridgeERC20To` function to bridge native L2 tokens to L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function withdrawTo(\n address _l2Token,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external payable virtual {\n _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);\n }\n\n /**\n * @custom:legacy\n * @notice Finalizes a deposit from L1 to L2. To finalize a deposit of ether, use address(0)\n * and the l1Token and the Legacy ERC20 ether predeploy address as the l2Token.\n *\n * @param _l1Token Address of the L1 token to deposit.\n * @param _l2Token Address of the corresponding L2 token.\n * @param _from Address of the depositor.\n * @param _to Address of the recipient.\n * @param _amount Amount of the tokens being deposited.\n * @param _extraData Extra data attached to the deposit.\n */\n function finalizeDeposit(\n address _l1Token,\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) external payable virtual {\n if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) {\n finalizeBridgeETH(_from, _to, _amount, _extraData);\n } else {\n finalizeBridgeERC20(_l2Token, _l1Token, _from, _to, _amount, _extraData);\n }\n }\n\n /**\n * @custom:legacy\n * @notice Retrieves the access of the corresponding L1 bridge contract.\n *\n * @return Address of the corresponding L1 bridge contract.\n */\n function l1TokenBridge() external view returns (address) {\n return address(OTHER_BRIDGE);\n }\n\n /**\n * @custom:legacy\n * @notice Internal function to a withdrawal from L2 to L1 to a target account on L1.\n *\n * @param _l2Token Address of the L2 token to withdraw.\n * @param _from Address of the withdrawer.\n * @param _to Recipient account on L1.\n * @param _amount Amount of the L2 token to withdraw.\n * @param _minGasLimit Minimum gas limit to use for the transaction.\n * @param _extraData Extra data attached to the withdrawal.\n */\n function _initiateWithdrawal(\n address _l2Token,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {\n _initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);\n } else {\n address l1Token = OptimismMintableERC20(_l2Token).l1Token();\n _initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData);\n }\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ETHBridgeInitiated event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ETHBridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(\n address(0),\n Predeploys.LEGACY_ERC20_ETH,\n _from,\n _to,\n _amount,\n _extraData\n );\n super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy WithdrawalInitiated event followed by the ERC20BridgeInitiated\n * event. This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit WithdrawalInitiated(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the legacy DepositFinalized event followed by the ERC20BridgeFinalized event.\n * This is necessary for backwards compatibility with the legacy bridge.\n *\n * @inheritdoc StandardBridge\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal override {\n emit DepositFinalized(_remoteToken, _localToken, _from, _to, _amount, _extraData);\n super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/L2/L2ToL1MessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000016\n * @title L2ToL1MessagePasser\n * @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from\n * L2 to L1 can be stored. The storage root of this contract is pulled up to the top level\n * of the L2 output to reduce the cost of proving the existence of sent messages.\n */\ncontract L2ToL1MessagePasser is Semver {\n /**\n * @notice The L1 gas limit set when eth is withdrawn using the receive() function.\n */\n uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Includes the message hashes for all withdrawals\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @notice A unique value hashed with each withdrawal.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Emitted any time a withdrawal is initiated.\n *\n * @param nonce Unique value corresponding to each withdrawal.\n * @param sender The L2 account address which initiated the withdrawal.\n * @param target The L1 account address the call will be send to.\n * @param value The ETH value submitted for withdrawal, to be forwarded to the target.\n * @param gasLimit The minimum amount of gas that must be provided when withdrawing.\n * @param data The data to be forwarded to the target on L1.\n * @param withdrawalHash The hash of the withdrawal.\n */\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n /**\n * @notice Emitted when the balance of this contract is burned.\n *\n * @param amount Amount of ETh that was burned.\n */\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Allows users to withdraw ETH by sending directly to this contract.\n */\n receive() external payable {\n initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @notice Removes all ETH held by this contract from the state. Used to prevent the amount of\n * ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to\n * create a contract and self-destruct it to itself. Anyone can call this function. Not\n * incentivized since this function is very cheap.\n */\n function burn() external {\n uint256 balance = address(this).balance;\n Burn.eth(balance);\n emit WithdrawerBalanceBurnt(balance);\n }\n\n /**\n * @notice Sends a message from L2 to L1.\n *\n * @param _target Address to call on L1 execution.\n * @param _gasLimit Minimum gas limit for executing the message on L1.\n * @param _data Data to forward to L1 target.\n */\n function initiateWithdrawal(\n address _target,\n uint256 _gasLimit,\n bytes memory _data\n ) public payable {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messageNonce(),\n sender: msg.sender,\n target: _target,\n value: msg.value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n sentMessages[withdrawalHash] = true;\n\n emit MessagePassed(\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _gasLimit,\n _data,\n withdrawalHash\n );\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n}\n" - }, - "contracts/L2/SequencerFeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\nimport { FeeVault } from \"../universal/FeeVault.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000011\n * @title SequencerFeeVault\n * @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during\n * transaction processing and block production.\n */\ncontract SequencerFeeVault is FeeVault, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _recipient Address that will receive the accumulated fees.\n */\n constructor(address _recipient) FeeVault(_recipient, 10 ether) Semver(1, 1, 0) {}\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the recipient address.\n *\n * @return The recipient address.\n */\n function l1FeeWallet() public view returns (address) {\n return RECIPIENT;\n }\n}\n" - }, - "contracts/deployment/PortalSender.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/**\n * @title PortalSender\n * @notice The PortalSender is a simple intermediate contract that will transfer the balance of the\n * L1StandardBridge to the OptimismPortal during the Bedrock migration.\n */\ncontract PortalSender {\n /**\n * @notice Address of the OptimismPortal contract.\n */\n OptimismPortal public immutable PORTAL;\n\n /**\n * @param _portal Address of the OptimismPortal contract.\n */\n constructor(OptimismPortal _portal) {\n PORTAL = _portal;\n }\n\n /**\n * @notice Sends balance of this contract to the OptimismPortal.\n */\n function donate() public {\n PORTAL.donateETH{ value: address(this).balance }();\n }\n}\n" - }, - "contracts/deployment/SystemDictator.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { PortalSender } from \"./PortalSender.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @title SystemDictator\n * @notice The SystemDictator is responsible for coordinating the deployment of a full Bedrock\n * system. The SystemDictator is designed to support both fresh network deployments and\n * upgrades to existing pre-Bedrock systems.\n */\ncontract SystemDictator is OwnableUpgradeable {\n /**\n * @notice Basic system configuration.\n */\n struct GlobalConfig {\n AddressManager addressManager;\n ProxyAdmin proxyAdmin;\n address controller;\n address finalOwner;\n }\n\n /**\n * @notice Set of proxy addresses.\n */\n struct ProxyAddressConfig {\n address l2OutputOracleProxy;\n address optimismPortalProxy;\n address l1CrossDomainMessengerProxy;\n address l1StandardBridgeProxy;\n address optimismMintableERC20FactoryProxy;\n address l1ERC721BridgeProxy;\n address systemConfigProxy;\n }\n\n /**\n * @notice Set of implementation addresses.\n */\n struct ImplementationAddressConfig {\n L2OutputOracle l2OutputOracleImpl;\n OptimismPortal optimismPortalImpl;\n L1CrossDomainMessenger l1CrossDomainMessengerImpl;\n L1StandardBridge l1StandardBridgeImpl;\n OptimismMintableERC20Factory optimismMintableERC20FactoryImpl;\n L1ERC721Bridge l1ERC721BridgeImpl;\n PortalSender portalSenderImpl;\n SystemConfig systemConfigImpl;\n }\n\n /**\n * @notice Dynamic L2OutputOracle config.\n */\n struct L2OutputOracleDynamicConfig {\n uint256 l2OutputOracleStartingBlockNumber;\n uint256 l2OutputOracleStartingTimestamp;\n }\n\n /**\n * @notice Values for the system config contract.\n */\n struct SystemConfigConfig {\n address owner;\n uint256 overhead;\n uint256 scalar;\n bytes32 batcherHash;\n uint64 gasLimit;\n address unsafeBlockSigner;\n ResourceMetering.ResourceConfig resourceConfig;\n }\n\n /**\n * @notice Combined system configuration.\n */\n struct DeployConfig {\n GlobalConfig globalConfig;\n ProxyAddressConfig proxyAddressConfig;\n ImplementationAddressConfig implementationAddressConfig;\n SystemConfigConfig systemConfigConfig;\n }\n\n /**\n * @notice Step after which exit 1 can no longer be used.\n */\n uint8 public constant EXIT_1_NO_RETURN_STEP = 3;\n\n /**\n * @notice Step where proxy ownership is transferred.\n */\n uint8 public constant PROXY_TRANSFER_STEP = 4;\n\n /**\n * @notice System configuration.\n */\n DeployConfig public config;\n\n /**\n * @notice Dynamic configuration for the L2OutputOracle.\n */\n L2OutputOracleDynamicConfig public l2OutputOracleDynamicConfig;\n\n /**\n * @notice Dynamic configuration for the OptimismPortal. Determines\n * if the system should be paused when initialized.\n */\n bool public optimismPortalDynamicConfig;\n\n /**\n * @notice Current step;\n */\n uint8 public currentStep;\n\n /**\n * @notice Whether or not dynamic config has been set.\n */\n bool public dynamicConfigSet;\n\n /**\n * @notice Whether or not the deployment is finalized.\n */\n bool public finalized;\n\n /**\n * @notice Whether or not the deployment has been exited.\n */\n bool public exited;\n\n /**\n * @notice Address of the old L1CrossDomainMessenger implementation.\n */\n address public oldL1CrossDomainMessenger;\n\n /**\n * @notice Checks that the current step is the expected step, then bumps the current step.\n *\n * @param _step Current step.\n */\n modifier step(uint8 _step) {\n require(!finalized, \"SystemDictator: already finalized\");\n require(!exited, \"SystemDictator: already exited\");\n require(currentStep == _step, \"SystemDictator: incorrect step\");\n _;\n currentStep++;\n }\n\n /**\n * @notice Constructor required to ensure that the implementation of the SystemDictator is\n * initialized upon deployment.\n */\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n // Using this shorter variable as an alias for address(0) just prevents us from having to\n // to use a new line for every single parameter.\n address zero = address(0);\n initialize(\n DeployConfig(\n GlobalConfig(AddressManager(zero), ProxyAdmin(zero), zero, zero),\n ProxyAddressConfig(zero, zero, zero, zero, zero, zero, zero),\n ImplementationAddressConfig(\n L2OutputOracle(zero),\n OptimismPortal(payable(zero)),\n L1CrossDomainMessenger(zero),\n L1StandardBridge(payable(zero)),\n OptimismMintableERC20Factory(zero),\n L1ERC721Bridge(zero),\n PortalSender(zero),\n SystemConfig(zero)\n ),\n SystemConfigConfig(zero, 0, 0, bytes32(0), 0, zero, rcfg)\n )\n );\n }\n\n /**\n * @param _config System configuration.\n */\n function initialize(DeployConfig memory _config) public initializer {\n config = _config;\n currentStep = 1;\n __Ownable_init();\n _transferOwnership(config.globalConfig.controller);\n }\n\n /**\n * @notice Allows the owner to update dynamic config.\n *\n * @param _l2OutputOracleDynamicConfig Dynamic L2OutputOracle config.\n * @param _optimismPortalDynamicConfig Dynamic OptimismPortal config.\n */\n function updateDynamicConfig(\n L2OutputOracleDynamicConfig memory _l2OutputOracleDynamicConfig,\n bool _optimismPortalDynamicConfig\n ) external onlyOwner {\n l2OutputOracleDynamicConfig = _l2OutputOracleDynamicConfig;\n optimismPortalDynamicConfig = _optimismPortalDynamicConfig;\n dynamicConfigSet = true;\n }\n\n /**\n * @notice Configures the ProxyAdmin contract.\n */\n function step1() external onlyOwner step(1) {\n // Set the AddressManager in the ProxyAdmin.\n config.globalConfig.proxyAdmin.setAddressManager(config.globalConfig.addressManager);\n\n // Set the L1CrossDomainMessenger to the RESOLVED proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n ProxyAdmin.ProxyType.RESOLVED\n );\n\n // Set the implementation name for the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.setImplementationName(\n config.proxyAddressConfig.l1CrossDomainMessengerProxy,\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Set the L1StandardBridge to the CHUGSPLASH proxy type.\n config.globalConfig.proxyAdmin.setProxyType(\n config.proxyAddressConfig.l1StandardBridgeProxy,\n ProxyAdmin.ProxyType.CHUGSPLASH\n );\n\n // Upgrade and initialize the SystemConfig so the Sequencer can start up.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.systemConfigProxy),\n address(config.implementationAddressConfig.systemConfigImpl),\n abi.encodeCall(\n SystemConfig.initialize,\n (\n config.systemConfigConfig.owner,\n config.systemConfigConfig.overhead,\n config.systemConfigConfig.scalar,\n config.systemConfigConfig.batcherHash,\n config.systemConfigConfig.gasLimit,\n config.systemConfigConfig.unsafeBlockSigner,\n config.systemConfigConfig.resourceConfig\n )\n )\n );\n }\n\n /**\n * @notice Pauses the system by shutting down the L1CrossDomainMessenger and setting the\n * deposit halt flag to tell the Sequencer's DTL to stop accepting deposits.\n */\n function step2() external onlyOwner step(2) {\n // Store the address of the old L1CrossDomainMessenger implementation. We will need this\n // address in the case that we have to exit early.\n oldL1CrossDomainMessenger = config.globalConfig.addressManager.getAddress(\n \"OVM_L1CrossDomainMessenger\"\n );\n\n // Temporarily brick the L1CrossDomainMessenger by setting its implementation address to\n // address(0) which will cause the ResolvedDelegateProxy to revert. Better than pausing\n // the L1CrossDomainMessenger via pause() because it can be easily reverted.\n config.globalConfig.addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(0));\n\n // Set the DTL shutoff block, which will tell the DTL to stop syncing new deposits from the\n // CanonicalTransactionChain. We do this by setting an address in the AddressManager\n // because the DTL already has a reference to the AddressManager and this way we don't also\n // need to give it a reference to the SystemDictator.\n config.globalConfig.addressManager.setAddress(\n \"DTL_SHUTOFF_BLOCK\",\n address(uint160(block.number))\n );\n }\n\n /**\n * @notice Removes deprecated addresses from the AddressManager.\n */\n function step3() external onlyOwner step(EXIT_1_NO_RETURN_STEP) {\n // Remove all deprecated addresses from the AddressManager\n string[17] memory deprecated = [\n \"OVM_CanonicalTransactionChain\",\n \"OVM_L2CrossDomainMessenger\",\n \"OVM_DecompressionPrecompileAddress\",\n \"OVM_Sequencer\",\n \"OVM_Proposer\",\n \"OVM_ChainStorageContainer-CTC-batches\",\n \"OVM_ChainStorageContainer-CTC-queue\",\n \"OVM_CanonicalTransactionChain\",\n \"OVM_StateCommitmentChain\",\n \"OVM_BondManager\",\n \"OVM_ExecutionManager\",\n \"OVM_FraudVerifier\",\n \"OVM_StateManagerFactory\",\n \"OVM_StateTransitionerFactory\",\n \"OVM_SafetyChecker\",\n \"OVM_L1MultiMessageRelayer\",\n \"BondManager\"\n ];\n\n for (uint256 i = 0; i < deprecated.length; i++) {\n config.globalConfig.addressManager.setAddress(deprecated[i], address(0));\n }\n }\n\n /**\n * @notice Transfers system ownership to the ProxyAdmin.\n */\n function step4() external onlyOwner step(PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the ProxyAdmin.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1StandardBridge to the ProxyAdmin.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.proxyAdmin)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the ProxyAdmin.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.proxyAdmin)\n );\n }\n\n /**\n * @notice Upgrades and initializes proxy contracts.\n */\n function step5() external onlyOwner step(5) {\n // Dynamic config must be set before we can initialize the L2OutputOracle.\n require(dynamicConfigSet, \"SystemDictator: dynamic oracle config is not yet initialized\");\n\n // Upgrade and initialize the L2OutputOracle.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l2OutputOracleProxy),\n address(config.implementationAddressConfig.l2OutputOracleImpl),\n abi.encodeCall(\n L2OutputOracle.initialize,\n (\n l2OutputOracleDynamicConfig.l2OutputOracleStartingBlockNumber,\n l2OutputOracleDynamicConfig.l2OutputOracleStartingTimestamp\n )\n )\n );\n\n // Upgrade and initialize the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.optimismPortalProxy),\n address(config.implementationAddressConfig.optimismPortalImpl),\n abi.encodeCall(OptimismPortal.initialize, (optimismPortalDynamicConfig))\n );\n\n // Upgrade the L1CrossDomainMessenger.\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1CrossDomainMessengerProxy),\n address(config.implementationAddressConfig.l1CrossDomainMessengerImpl)\n );\n\n // Try to initialize the L1CrossDomainMessenger, only fail if it's already been initialized.\n try\n L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy)\n .initialize()\n {\n // L1CrossDomainMessenger is the one annoying edge case difference between existing\n // networks and fresh networks because in existing networks it'll already be\n // initialized but in fresh networks it won't be. Try/catch is the easiest and most\n // consistent way to handle this because initialized() is not exposed publicly.\n } catch Error(string memory reason) {\n require(\n keccak256(abi.encodePacked(reason)) ==\n keccak256(\"Initializable: contract is already initialized\"),\n string.concat(\"SystemDictator: unexpected error initializing L1XDM: \", reason)\n );\n } catch {\n revert(\"SystemDictator: unexpected error initializing L1XDM (no reason)\");\n }\n\n // Transfer ETH from the L1StandardBridge to the OptimismPortal.\n config.globalConfig.proxyAdmin.upgradeAndCall(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.portalSenderImpl),\n abi.encodeCall(PortalSender.donate, ())\n );\n\n // Upgrade the L1StandardBridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1StandardBridgeProxy),\n address(config.implementationAddressConfig.l1StandardBridgeImpl)\n );\n\n // Upgrade the OptimismMintableERC20Factory (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.optimismMintableERC20FactoryProxy),\n address(config.implementationAddressConfig.optimismMintableERC20FactoryImpl)\n );\n\n // Upgrade the L1ERC721Bridge (no initializer).\n config.globalConfig.proxyAdmin.upgrade(\n payable(config.proxyAddressConfig.l1ERC721BridgeProxy),\n address(config.implementationAddressConfig.l1ERC721BridgeImpl)\n );\n }\n\n /**\n * @notice Tranfers admin ownership to the final owner.\n */\n function finalize() external onlyOwner {\n // Transfer ownership of the ProxyAdmin to the final owner.\n config.globalConfig.proxyAdmin.transferOwnership(config.globalConfig.finalOwner);\n\n // Optionally also transfer AddressManager and L1StandardBridge if we still own it. Might\n // happen if we're exiting early.\n if (currentStep <= PROXY_TRANSFER_STEP) {\n // Transfer ownership of the AddressManager to the final owner.\n config.globalConfig.addressManager.transferOwnership(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1StandardBridge to the final owner.\n L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(\n address(config.globalConfig.finalOwner)\n );\n\n // Transfer ownership of the L1ERC721Bridge to the final owner.\n Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(\n address(config.globalConfig.finalOwner)\n );\n }\n\n // Mark the deployment as finalized.\n finalized = true;\n }\n\n /**\n * @notice First exit point, can only be called before step 3 is executed.\n */\n function exit1() external onlyOwner {\n require(\n currentStep == EXIT_1_NO_RETURN_STEP,\n \"SystemDictator: can only exit1 before step 3 is executed\"\n );\n\n // Reset the L1CrossDomainMessenger to the old implementation.\n config.globalConfig.addressManager.setAddress(\n \"OVM_L1CrossDomainMessenger\",\n oldL1CrossDomainMessenger\n );\n\n // Unset the DTL shutoff block which will allow the DTL to sync again.\n config.globalConfig.addressManager.setAddress(\"DTL_SHUTOFF_BLOCK\", address(0));\n\n // Mark the deployment as exited.\n exited = true;\n }\n}\n" - }, - "contracts/echidna/FuzzAddressAliasing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract EchidnaFuzzAddressAliasing {\n bool internal failedRoundtrip;\n\n /**\n * @notice Takes an address to be aliased with AddressAliasHelper and then unaliased\n * and updates the test contract's state indicating if the round trip encoding\n * failed.\n */\n function testRoundTrip(address addr) public {\n // Alias our address\n address aliasedAddr = AddressAliasHelper.applyL1ToL2Alias(addr);\n\n // Unalias our address\n address undoneAliasAddr = AddressAliasHelper.undoL1ToL2Alias(aliasedAddr);\n\n // If our round trip aliasing did not return the original result, set our state.\n if (addr != undoneAliasAddr) {\n failedRoundtrip = true;\n }\n }\n\n /**\n * @custom:invariant Address aliases are always able to be undone.\n *\n * Asserts that an address that has been aliased with `applyL1ToL2Alias` can always\n * be unaliased with `undoL1ToL2Alias`.\n */\n function echidna_round_trip_aliasing() public view returns (bool) {\n // ASSERTION: The round trip aliasing done in testRoundTrip(...) should never fail.\n return !failedRoundtrip;\n }\n}\n" - }, - "contracts/echidna/FuzzBurn.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\n\ncontract EchidnaFuzzBurnEth is StdUtils {\n bool internal failedEthBurn;\n\n /**\n * @notice Takes an integer amount of eth to burn through the Burn library and\n * updates the contract state if an incorrect amount of eth moved from the contract\n */\n function testBurn(uint256 _value) public {\n // cache the contract's eth balance\n uint256 preBurnBalance = address(this).balance;\n uint256 value = bound(_value, 0, preBurnBalance);\n\n // execute a burn of _value eth\n Burn.eth(value);\n\n // check that exactly value eth was transfered from the contract\n unchecked {\n if (address(this).balance != preBurnBalance - value) {\n failedEthBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `eth(uint256)` always burns the exact amount of eth passed.\n *\n * Asserts that when `Burn.eth(uint256)` is called, it always burns the exact amount\n * of ETH passed to the function.\n */\n function echidna_burn_eth() public view returns (bool) {\n // ASSERTION: The amount burned should always match the amount passed exactly\n return !failedEthBurn;\n }\n}\n\ncontract EchidnaFuzzBurnGas is StdUtils {\n bool internal failedGasBurn;\n\n /**\n * @notice Takes an integer amount of gas to burn through the Burn library and\n * updates the contract state if at least that amount of gas was not burned\n * by the library\n */\n function testGas(uint256 _value) public {\n // cap the value to the max resource limit\n uint256 MAX_RESOURCE_LIMIT = 8_000_000;\n uint256 value = bound(_value, 0, MAX_RESOURCE_LIMIT);\n\n // cache the contract's current remaining gas\n uint256 preBurnGas = gasleft();\n\n // execute the gas burn\n Burn.gas(value);\n\n // cache the remaining gas post burn\n uint256 postBurnGas = gasleft();\n\n // check that at least value gas was burnt (and that there was no underflow)\n unchecked {\n if (postBurnGas - preBurnGas > value || preBurnGas - value > preBurnGas) {\n failedGasBurn = true;\n }\n }\n }\n\n /**\n * @custom:invariant `gas(uint256)` always burns at least the amount of gas passed.\n *\n * Asserts that when `Burn.gas(uint256)` is called, it always burns at least the amount\n * of gas passed to the function.\n */\n function echidna_burn_gas() public view returns (bool) {\n // ASSERTION: The amount of gas burned should be strictly greater than the\n // the amount passed as _value (minimum _value + whatever minor overhead to\n // the value after the call)\n return !failedGasBurn;\n }\n}\n" - }, - "contracts/echidna/FuzzEncoding.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzEncoding {\n bool internal failedRoundtripAToB;\n bool internal failedRoundtripBToA;\n\n /**\n * @notice Takes a pair of integers to be encoded into a versioned nonce with the\n * Encoding library and then decoded and updates the test contract's state\n * indicating if the round trip encoding failed.\n */\n function testRoundTripAToB(uint240 _nonce, uint16 _version) public {\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(encodedVersionedNonce);\n\n // If our round trip encoding did not return the original result, set our state.\n if ((decodedNonce != _nonce) || (decodedVersion != _version)) {\n failedRoundtripAToB = true;\n }\n }\n\n /**\n * @notice Takes an integer representing a packed version and nonce and attempts\n * to decode them using the Encoding library before re-encoding and updates\n * the test contract's state indicating if the round trip encoding failed.\n */\n function testRoundTripBToA(uint256 _versionedNonce) public {\n // Decode the nonce and version\n uint240 decodedNonce;\n uint16 decodedVersion;\n\n (decodedNonce, decodedVersion) = Encoding.decodeVersionedNonce(_versionedNonce);\n\n // Encode the nonce and version\n uint256 encodedVersionedNonce = Encoding.encodeVersionedNonce(decodedNonce, decodedVersion);\n\n // If our round trip encoding did not return the original result, set our state.\n if (encodedVersionedNonce != _versionedNonce) {\n failedRoundtripBToA = true;\n }\n }\n\n /**\n * @custom:invariant `testRoundTripAToB` never fails.\n *\n * Asserts that a raw versioned nonce can be encoded / decoded to reach the same raw value.\n */\n function echidna_round_trip_encoding_AToB() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripAToB(...)\n return !failedRoundtripAToB;\n }\n\n /**\n * @custom:invariant `testRoundTripBToA` never fails.\n *\n * Asserts that an encoded versioned nonce can always be decoded / re-encoded to reach\n * the same encoded value.\n */\n function echidna_round_trip_encoding_BToA() public view returns (bool) {\n // ASSERTION: The round trip encoding done in testRoundTripBToA should never\n // fail.\n return !failedRoundtripBToA;\n }\n}\n" - }, - "contracts/echidna/FuzzHashing.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract EchidnaFuzzHashing {\n bool internal failedCrossDomainHashHighVersion;\n bool internal failedCrossDomainHashV0;\n bool internal failedCrossDomainHashV1;\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash with a randomly\n * generated version. Only schema versions 0 and 1 are supported and all others should revert.\n */\n function testHashCrossDomainMessageHighVersion(\n uint16 _version,\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, _version);\n\n // hash the cross domain message. we don't need to store the result since the function\n // validates and should revert if an invalid version (>1) is encoded\n Hashing.hashCrossDomainMessage(encodedNonce, _sender, _target, _value, _gasLimit, _data);\n\n // check that execution never makes it this far for an invalid version\n if (_version > 1) {\n failedCrossDomainHashHighVersion = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v0 schema\n * and compares the output of a call to the unversioned function to the v0 function directly\n */\n function testHashCrossDomainMessageV0(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 0\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 0);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n encodedNonce\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV0 = true;\n }\n }\n\n /**\n * @notice Takes the necessary parameters to perform a cross domain hash using the v1 schema\n * and compares the output of a call to the unversioned function to the v1 function directly\n */\n function testHashCrossDomainMessageV1(\n uint240 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) public {\n // generate the versioned nonce with the version set to 1\n uint256 encodedNonce = Encoding.encodeVersionedNonce(_nonce, 1);\n\n // hash the cross domain message using the unversioned and versioned functions for\n // comparison\n bytes32 sampleHash1 = Hashing.hashCrossDomainMessage(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n bytes32 sampleHash2 = Hashing.hashCrossDomainMessageV1(\n encodedNonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n // check that the output of both functions matches\n if (sampleHash1 != sampleHash2) {\n failedCrossDomainHashV1 = true;\n }\n }\n\n /**\n * @custom:invariant `hashCrossDomainMessage` reverts if `version` is > `1`.\n *\n * The `hashCrossDomainMessage` function should always revert if the `version` passed is > `1`.\n */\n function echidna_hash_xdomain_msg_high_version() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage will never succeed for a version > 1\n return !failedCrossDomainHashHighVersion;\n }\n\n /**\n * @custom:invariant `version` = `0`: `hashCrossDomainMessage` and `hashCrossDomainMessageV0`\n * are equivalent.\n *\n * If the version passed is 0, `hashCrossDomainMessage` and `hashCrossDomainMessageV0` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_0() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV0\n // should always match when the version passed is 0\n return !failedCrossDomainHashV0;\n }\n\n /**\n * @custom:invariant `version` = `1`: `hashCrossDomainMessage` and `hashCrossDomainMessageV1`\n * are equivalent.\n *\n * If the version passed is 1, `hashCrossDomainMessage` and `hashCrossDomainMessageV1` should be\n * equivalent.\n */\n function echidna_hash_xdomain_msg_1() public view returns (bool) {\n // ASSERTION: A call to hashCrossDomainMessage and hashCrossDomainMessageV1\n // should always match when the version passed is 1\n return !failedCrossDomainHashV1;\n }\n}\n" - }, - "contracts/echidna/FuzzOptimismPortal.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzOptimismPortal {\n OptimismPortal internal portal;\n bool internal failedToComplete;\n\n constructor() {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n SystemConfig systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: rcfg\n });\n\n portal = new OptimismPortal({\n _l2Oracle: L2OutputOracle(address(0)),\n _guardian: address(0),\n _paused: false,\n _config: systemConfig\n });\n }\n\n // A test intended to identify any unexpected halting conditions\n function testDepositTransactionCompletes(\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) public payable {\n failedToComplete = true;\n require(!_isCreation || _to == address(0), \"EchidnaFuzzOptimismPortal: invalid test case.\");\n portal.depositTransaction{ value: _mint }(_to, _value, _gasLimit, _isCreation, _data);\n failedToComplete = false;\n }\n\n /**\n * @custom:invariant Deposits of any value should always succeed unless\n * `_to` = `address(0)` or `_isCreation` = `true`.\n *\n * All deposits, barring creation transactions and transactions sent to `address(0)`,\n * should always succeed.\n */\n function echidna_deposit_completes() public view returns (bool) {\n return !failedToComplete;\n }\n}\n" - }, - "contracts/echidna/FuzzResourceMetering.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\nimport { StdUtils } from \"forge-std/Test.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract EchidnaFuzzResourceMetering is ResourceMetering, StdUtils {\n bool internal failedMaxGasPerBlock;\n bool internal failedRaiseBaseFee;\n bool internal failedLowerBaseFee;\n bool internal failedNeverBelowMinBaseFee;\n bool internal failedMaxRaiseBaseFeePerBlock;\n bool internal failedMaxLowerBaseFeePerBlock;\n\n // Used as a special flag for the purpose of identifying unchecked math errors specifically\n // in the test contracts, not the target contracts themselves.\n bool internal underflow;\n\n constructor() {\n initialize();\n }\n\n function initialize() internal initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public pure returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();\n return rcfg;\n }\n\n /**\n * @notice Takes the necessary parameters to allow us to burn arbitrary amounts of gas to test\n * the underlying resource metering/gas market logic\n */\n function testBurn(uint256 _gasToBurn, bool _raiseBaseFee) public {\n // Part 1: we cache the current param values and do some basic checks on them.\n uint256 cachedPrevBaseFee = uint256(params.prevBaseFee);\n uint256 cachedPrevBoughtGas = uint256(params.prevBoughtGas);\n uint256 cachedPrevBlockNum = uint256(params.prevBlockNum);\n\n ResourceMetering.ResourceConfig memory rcfg = resourceConfig();\n uint256 targetResourceLimit = uint256(rcfg.maxResourceLimit) /\n uint256(rcfg.elasticityMultiplier);\n\n // check that the last block's base fee hasn't dropped below the minimum\n if (cachedPrevBaseFee < uint256(rcfg.minimumBaseFee)) {\n failedNeverBelowMinBaseFee = true;\n }\n // check that the last block didn't consume more than the max amount of gas\n if (cachedPrevBoughtGas > uint256(rcfg.maxResourceLimit)) {\n failedMaxGasPerBlock = true;\n }\n\n // Part2: we perform the gas burn\n\n // force the gasToBurn into the correct range based on whether we intend to\n // raise or lower the baseFee after this block, respectively\n uint256 gasToBurn;\n if (_raiseBaseFee) {\n gasToBurn = bound(\n _gasToBurn,\n uint256(targetResourceLimit),\n uint256(rcfg.maxResourceLimit)\n );\n } else {\n gasToBurn = bound(_gasToBurn, 0, targetResourceLimit);\n }\n\n _burnInternal(uint64(gasToBurn));\n\n // Part 3: we run checks and modify our invariant flags based on the updated params values\n\n // Calculate the maximum allowed baseFee change (per block)\n uint256 maxBaseFeeChange = cachedPrevBaseFee / uint256(rcfg.baseFeeMaxChangeDenominator);\n\n // If the last block used more than the target amount of gas (and there were no\n // empty blocks in between), ensure this block's baseFee increased, but not by\n // more than the max amount per block\n if (\n (cachedPrevBoughtGas > uint256(targetResourceLimit)) &&\n (uint256(params.prevBlockNum) - cachedPrevBlockNum == 1)\n ) {\n failedRaiseBaseFee = failedRaiseBaseFee || (params.prevBaseFee <= cachedPrevBaseFee);\n failedMaxRaiseBaseFeePerBlock =\n failedMaxRaiseBaseFeePerBlock ||\n ((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBaseFeeChange);\n }\n\n // If the last block used less than the target amount of gas, (or was empty),\n // ensure that: this block's baseFee was decreased, but not by more than the max amount\n if (\n (cachedPrevBoughtGas < uint256(targetResourceLimit)) ||\n (uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)\n ) {\n // Invariant: baseFee should decrease\n failedLowerBaseFee =\n failedLowerBaseFee ||\n (uint256(params.prevBaseFee) > cachedPrevBaseFee);\n\n if (params.prevBlockNum - cachedPrevBlockNum == 1) {\n // No empty blocks\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n } else if (params.prevBlockNum - cachedPrevBlockNum > 1) {\n // We have at least one empty block\n // Update the maxBaseFeeChange to account for multiple blocks having passed\n unchecked {\n maxBaseFeeChange = uint256(\n int256(cachedPrevBaseFee) -\n Arithmetic.clamp(\n Arithmetic.cdexp(\n int256(cachedPrevBaseFee),\n int256(uint256(rcfg.baseFeeMaxChangeDenominator)),\n int256(uint256(params.prevBlockNum) - cachedPrevBlockNum)\n ),\n int256(uint256(rcfg.minimumBaseFee)),\n int256(uint256(rcfg.maximumBaseFee))\n )\n );\n }\n\n // Detect an underflow in the previous calculation.\n // Without using unchecked above, and detecting the underflow here, echidna would\n // otherwise ignore the revert.\n underflow = underflow || maxBaseFeeChange > cachedPrevBaseFee;\n\n // Invariant: baseFee should not have decreased by more than the maximum amount\n failedMaxLowerBaseFeePerBlock =\n failedMaxLowerBaseFeePerBlock ||\n ((cachedPrevBaseFee - uint256(params.prevBaseFee)) <= maxBaseFeeChange);\n }\n }\n }\n\n function _burnInternal(uint64 _gasToBurn) private metered(_gasToBurn) {}\n\n /**\n * @custom:invariant The base fee should increase if the last block used more\n * than the target amount of gas\n *\n * If the last block used more than the target amount of gas (and there were no\n * empty blocks in between), ensure this block's baseFee increased, but not by\n * more than the max amount per block.\n */\n function echidna_high_usage_raise_baseFee() public view returns (bool) {\n return !failedRaiseBaseFee;\n }\n\n /**\n * @custom:invariant The base fee should decrease if the last block used less\n * than the target amount of gas\n *\n * If the previous block used less than the target amount of gas, the base fee should decrease,\n * but not more than the max amount.\n */\n function echidna_low_usage_lower_baseFee() public view returns (bool) {\n return !failedLowerBaseFee;\n }\n\n /**\n * @custom:invariant A block's base fee should never be below `MINIMUM_BASE_FEE`\n *\n * This test asserts that a block's base fee can never drop below the\n * `MINIMUM_BASE_FEE` threshold.\n */\n function echidna_never_below_min_baseFee() public view returns (bool) {\n return !failedNeverBelowMinBaseFee;\n }\n\n /**\n * @custom:invariant A block can never consume more than `MAX_RESOURCE_LIMIT` gas.\n *\n * This test asserts that a block can never consume more than the `MAX_RESOURCE_LIMIT`\n * gas threshold.\n */\n function echidna_never_above_max_gas_limit() public view returns (bool) {\n return !failedMaxGasPerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be raised more than the max base fee change.\n *\n * After a block consumes more gas than the target gas, the base fee cannot be raised\n * more than the maximum amount allowed. The max base fee change (per-block) is derived\n * as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_increase() public view returns (bool) {\n return !failedMaxRaiseBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The base fee can never be lowered more than the max base fee change.\n *\n * After a block consumes less than the target gas, the base fee cannot be lowered more\n * than the maximum amount allowed. The max base fee change (per-block) is derived as\n *follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR`\n */\n function echidna_never_exceed_max_decrease() public view returns (bool) {\n return !failedMaxLowerBaseFeePerBlock;\n }\n\n /**\n * @custom:invariant The `maxBaseFeeChange` calculation over multiple blocks can never\n * underflow.\n *\n * When calculating the `maxBaseFeeChange` after multiple empty blocks, the calculation\n * should never be allowed to underflow.\n */\n function echidna_underflow() public view returns (bool) {\n return !underflow;\n }\n}\n" - }, - "contracts/governance/GovernanceToken.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:predeploy 0x4200000000000000000000000000000000000042\n * @title GovernanceToken\n * @notice The Optimism token used in governance and supporting voting and delegation. Implements\n * EIP 2612 allowing signed approvals. Contract is \"owned\" by a `MintManager` instance with\n * permission to the `mint` function only, for the purposes of enforcing the token inflation\n * schedule.\n */\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\n constructor() ERC20(\"Optimism\", \"OP\") ERC20Permit(\"Optimism\") {}\n\n /**\n * @notice Allows the owner to mint tokens.\n *\n * @param _account The account receiving minted tokens.\n * @param _amount The amount of tokens to mint.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n /**\n * @notice Callback called after a token transfer.\n *\n * @param from The account sending tokens.\n * @param to The account receiving tokens.\n * @param amount The amount of tokens being transfered.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20, ERC20Votes) {\n super._afterTokenTransfer(from, to, amount);\n }\n\n /**\n * @notice Internal mint function.\n *\n * @param to The account receiving minted tokens.\n * @param amount The amount of tokens to mint.\n */\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._mint(to, amount);\n }\n\n /**\n * @notice Internal burn function.\n *\n * @param account The account that tokens will be burned from.\n * @param amount The amount of tokens that will be burned.\n */\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._burn(account, amount);\n }\n}\n" - }, - "contracts/governance/MintManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./GovernanceToken.sol\";\n\n/**\n * @title MintManager\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\n * Contract acts as the token \"mint manager\" with permission to the `mint` function only.\n * Currently permitted to mint once per year of up to 2% of the total token supply.\n * Upgradable to allow changes in the inflation schedule.\n */\ncontract MintManager is Ownable {\n /**\n * @notice The GovernanceToken that the MintManager can mint tokens\n */\n GovernanceToken public immutable governanceToken;\n\n /**\n * @notice The amount of tokens that can be minted per year. The value is a fixed\n * point number with 4 decimals.\n */\n uint256 public constant MINT_CAP = 20; // 2%\n\n /**\n * @notice The number of decimals for the MINT_CAP.\n */\n uint256 public constant DENOMINATOR = 1000;\n\n /**\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\n * be minted again.\n */\n uint256 public constant MINT_PERIOD = 365 days;\n\n /**\n * @notice Tracks the time of last mint.\n */\n uint256 public mintPermittedAfter;\n\n /**\n * @param _upgrader The owner of this contract\n * @param _governanceToken The governance token this contract can mint\n * tokens of\n */\n constructor(address _upgrader, address _governanceToken) {\n transferOwnership(_upgrader);\n governanceToken = GovernanceToken(_governanceToken);\n }\n\n /**\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\n *\n * @param _account Address to mint new tokens to.\n * @param _amount Amount of tokens to be minted.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n if (mintPermittedAfter > 0) {\n require(\n mintPermittedAfter <= block.timestamp,\n \"MintManager: minting not permitted yet\"\n );\n\n require(\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\n \"MintManager: mint amount exceeds cap\"\n );\n }\n\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\n governanceToken.mint(_account, _amount);\n }\n\n /**\n * @notice Upgrade the owner of the governance token to a new MintManager.\n *\n * @param _newMintManager The MintManager to upgrade to.\n */\n function upgrade(address _newMintManager) public onlyOwner {\n require(\n _newMintManager != address(0),\n \"MintManager: mint manager cannot be the zero address\"\n );\n\n governanceToken.transferOwnership(_newMintManager);\n }\n}\n" - }, - "contracts/legacy/AddressManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:legacy\n * @title AddressManager\n * @notice AddressManager is a legacy contract that was used in the old version of the Optimism\n * system to manage a registry of string names to addresses. We now use a more standard\n * proxy system instead, but this contract is still necessary for backwards compatibility\n * with several older contracts.\n */\ncontract AddressManager is Ownable {\n /**\n * @notice Mapping of the hashes of string names to addresses.\n */\n mapping(bytes32 => address) private addresses;\n\n /**\n * @notice Emitted when an address is modified in the registry.\n *\n * @param name String name being set in the registry.\n * @param newAddress Address set for the given name.\n * @param oldAddress Address that was previously set for the given name.\n */\n event AddressSet(string indexed name, address newAddress, address oldAddress);\n\n /**\n * @notice Changes the address associated with a particular name.\n *\n * @param _name String name to associate an address with.\n * @param _address Address to associate with the name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n bytes32 nameHash = _getNameHash(_name);\n address oldAddress = addresses[nameHash];\n addresses[nameHash] = _address;\n\n emit AddressSet(_name, _address, oldAddress);\n }\n\n /**\n * @notice Retrieves the address associated with a given name.\n *\n * @param _name Name to retrieve an address for.\n *\n * @return Address associated with the given name.\n */\n function getAddress(string memory _name) external view returns (address) {\n return addresses[_getNameHash(_name)];\n }\n\n /**\n * @notice Computes the hash of a name.\n *\n * @param _name Name to compute a hash for.\n *\n * @return Hash of the given name.\n */\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(_name));\n }\n}\n" - }, - "contracts/legacy/DeployerWhitelist.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000002\n * @title DeployerWhitelist\n * @notice DeployerWhitelist is a legacy contract that was originally used to act as a whitelist of\n * addresses allowed to the Optimism network. The DeployerWhitelist has since been\n * disabled, but the code is kept in state for the sake of full backwards compatibility.\n * As of the Bedrock upgrade, the DeployerWhitelist is completely unused by the Optimism\n * system and could, in theory, be removed entirely.\n */\ncontract DeployerWhitelist is Semver {\n /**\n * @notice Address of the owner of this contract. Note that when this address is set to\n * address(0), the whitelist is disabled.\n */\n address public owner;\n\n /**\n * @notice Mapping of deployer addresses to boolean whitelist status.\n */\n mapping(address => bool) public whitelist;\n\n /**\n * @notice Emitted when the owner of this contract changes.\n *\n * @param oldOwner Address of the previous owner.\n * @param newOwner Address of the new owner.\n */\n event OwnerChanged(address oldOwner, address newOwner);\n\n /**\n * @notice Emitted when the whitelist status of a deployer changes.\n *\n * @param deployer Address of the deployer.\n * @param whitelisted Boolean indicating whether the deployer is whitelisted.\n */\n event WhitelistStatusChanged(address deployer, bool whitelisted);\n\n /**\n * @notice Emitted when the whitelist is disabled.\n *\n * @param oldOwner Address of the final owner of the whitelist.\n */\n event WhitelistDisabled(address oldOwner);\n\n /**\n * @notice Blocks functions to anyone except the contract owner.\n */\n modifier onlyOwner() {\n require(\n msg.sender == owner,\n \"DeployerWhitelist: function can only be called by the owner of this contract\"\n );\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Adds or removes an address from the deployment whitelist.\n *\n * @param _deployer Address to update permissions for.\n * @param _isWhitelisted Whether or not the address is whitelisted.\n */\n function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external onlyOwner {\n whitelist[_deployer] = _isWhitelisted;\n emit WhitelistStatusChanged(_deployer, _isWhitelisted);\n }\n\n /**\n * @notice Updates the owner of this contract.\n *\n * @param _owner Address of the new owner.\n */\n function setOwner(address _owner) external onlyOwner {\n // Prevent users from setting the whitelist owner to address(0) except via\n // enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to\n // any other address that doesn't have a corresponding knowable private key.\n require(\n _owner != address(0),\n \"DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment\"\n );\n\n emit OwnerChanged(owner, _owner);\n owner = _owner;\n }\n\n /**\n * @notice Permanently enables arbitrary contract deployment and deletes the owner.\n */\n function enableArbitraryContractDeployment() external onlyOwner {\n emit WhitelistDisabled(owner);\n owner = address(0);\n }\n\n /**\n * @notice Checks whether an address is allowed to deploy contracts.\n *\n * @param _deployer Address to check.\n *\n * @return Whether or not the address can deploy contracts.\n */\n function isDeployerAllowed(address _deployer) external view returns (bool) {\n return (owner == address(0) || whitelist[_deployer]);\n }\n}\n" - }, - "contracts/legacy/L1BlockNumber.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000013\n * @title L1BlockNumber\n * @notice L1BlockNumber is a legacy contract that fills the roll of the OVM_L1BlockNumber contract\n * in the old version of the Optimism system. Only necessary for backwards compatibility.\n * If you want to access the L1 block number going forward, you should use the L1Block\n * contract instead.\n */\ncontract L1BlockNumber is Semver {\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Returns the L1 block number.\n */\n receive() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Returns the L1 block number.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n uint256 l1BlockNumber = getL1BlockNumber();\n assembly {\n mstore(0, l1BlockNumber)\n return(0, 32)\n }\n }\n\n /**\n * @notice Retrieves the latest L1 block number.\n *\n * @return Latest L1 block number.\n */\n function getL1BlockNumber() public view returns (uint256) {\n return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).number();\n }\n}\n" - }, - "contracts/legacy/L1ChugSplashProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title IL1ChugSplashDeployer\n */\ninterface IL1ChugSplashDeployer {\n function isUpgrading() external view returns (bool);\n}\n\n/**\n * @custom:legacy\n * @title L1ChugSplashProxy\n * @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\n * functions `setCode` and `setStorage` for changing the code or storage of the contract.\n *\n * Note for future developers: do NOT make anything in this contract 'public' unless you\n * know what you're doing. Anything public can potentially have a function signature that\n * conflicts with a signature attached to the implementation contract. Public functions\n * SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good\n * reason not to have that modifier. And there almost certainly is not a good reason to not\n * have that modifier. Beware!\n */\ncontract L1ChugSplashProxy {\n /**\n * @notice \"Magic\" prefix. When prepended to some arbitrary bytecode and used to create a\n * contract, the appended bytecode will be deployed as given.\n */\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice Blocks a function from being called when the parent signals that the system should\n * be paused via an isUpgrading function.\n */\n modifier onlyWhenNotPaused() {\n address owner = _getOwner();\n\n // We do a low-level call because there's no guarantee that the owner actually *is* an\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\n // it turns out that it isn't the right type of contract.\n (bool success, bytes memory returndata) = owner.staticcall(\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)\n );\n\n // If the call was unsuccessful then we assume that there's no \"isUpgrading\" method and we\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\n // long. If this isn't the case then we can safely ignore the result.\n if (success && returndata.length == 32) {\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\n // case that the isUpgrading function returned something other than 0 or 1. But we only\n // really care about the case where this value is 0 (= false).\n uint256 ret = abi.decode(returndata, (uint256));\n require(ret == 0, \"L1ChugSplashProxy: system is currently being upgraded\");\n }\n\n _;\n }\n\n /**\n * @notice Makes a proxy call instead of triggering the given function when the caller is\n * either the owner or the zero address. Caller can only ever be the zero address if\n * this function is being called off-chain via eth_call, which is totally fine and can\n * be convenient for client-side tooling. Avoids situations where the proxy and\n * implementation share a sighash and the proxy function ends up being called instead\n * of the implementation one.\n *\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If\n * there's a way for someone to send a transaction with msg.sender == address(0) in any\n * real context then we have much bigger problems. Primary reason to include this\n * additional allowed sender is because the owner address can be changed dynamically\n * and we do not want clients to have to keep track of the current owner in order to\n * make an eth_call that doesn't trigger the proxied contract.\n */\n // slither-disable-next-line incorrect-modifier\n modifier proxyCallIfNotOwner() {\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @param _owner Address of the initial contract owner.\n */\n constructor(address _owner) {\n _setOwner(_owner);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Sets the code that should be running behind this proxy.\n *\n * Note: This scheme is a bit different from the standard proxy scheme where one would\n * typically deploy the code separately and then set the implementation address. We're\n * doing it this way because it gives us a lot more freedom on the client side. Can\n * only be triggered by the contract owner.\n *\n * @param _code New contract code to run inside this contract.\n */\n function setCode(bytes memory _code) external proxyCallIfNotOwner {\n // Get the code hash of the current implementation.\n address implementation = _getImplementation();\n\n // If the code hash matches the new implementation then we return early.\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\n return;\n }\n\n // Create the deploycode by appending the magic prefix.\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\n\n // Deploy the code and set the new implementation address.\n address newImplementation;\n assembly {\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\n }\n\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\n // actually fail this check. Should only happen if the contract creation from above runs\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\n // should be doing this check anyway though.\n require(\n _getAccountCodeHash(newImplementation) == keccak256(_code),\n \"L1ChugSplashProxy: code was not correctly deployed\"\n );\n\n _setImplementation(newImplementation);\n }\n\n /**\n * @notice Modifies some storage slot within the proxy contract. Gives us a lot of power to\n * perform upgrades in a more transparent way. Only callable by the owner.\n *\n * @param _key Storage key to modify.\n * @param _value New value for the storage key.\n */\n function setStorage(bytes32 _key, bytes32 _value) external proxyCallIfNotOwner {\n assembly {\n sstore(_key, _value)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _owner New owner of the proxy contract.\n */\n function setOwner(address _owner) external proxyCallIfNotOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Queries the owner of the proxy contract. Can only be called by the owner OR by\n * making an eth_call and setting the \"from\" address to address(0).\n *\n * @return Owner address.\n */\n function getOwner() external proxyCallIfNotOwner returns (address) {\n return _getOwner();\n }\n\n /**\n * @notice Queries the implementation address. Can only be called by the owner OR by making an\n * eth_call and setting the \"from\" address to address(0).\n *\n * @return Implementation address.\n */\n function getImplementation() external proxyCallIfNotOwner returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _owner New owner of the proxy contract.\n */\n function _setOwner(address _owner) internal {\n assembly {\n sstore(OWNER_KEY, _owner)\n }\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal onlyWhenNotPaused {\n address implementation = _getImplementation();\n\n require(implementation != address(0), \"L1ChugSplashProxy: implementation is not set yet\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address implementation;\n assembly {\n implementation := sload(IMPLEMENTATION_KEY)\n }\n return implementation;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getOwner() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n\n /**\n * @notice Gets the code hash for a given account.\n *\n * @param _account Address of the account to get a code hash for.\n *\n * @return Code hash for the account.\n */\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\n bytes32 codeHash;\n assembly {\n codeHash := extcodehash(_account)\n }\n return codeHash;\n }\n}\n" - }, - "contracts/legacy/LegacyERC20ETH.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000\n * @title LegacyERC20ETH\n * @notice LegacyERC20ETH is a legacy contract that held ETH balances before the Bedrock upgrade.\n * All ETH balances held within this contract were migrated to the state trie as part of\n * the Bedrock upgrade. Functions within this contract that mutate state were already\n * disabled as part of the EVM equivalence upgrade.\n */\ncontract LegacyERC20ETH is OptimismMintableERC20 {\n /**\n * @notice Initializes the contract as an Optimism Mintable ERC20.\n */\n constructor()\n OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), \"Ether\", \"ETH\")\n {}\n\n /**\n * @notice Returns the ETH balance of the target account. Overrides the base behavior of the\n * contract to preserve the invariant that the balance within this contract always\n * matches the balance in the state trie.\n *\n * @param _who Address of the account to query.\n *\n * @return The ETH balance of the target account.\n */\n function balanceOf(address _who) public view virtual override returns (uint256) {\n return address(_who).balance;\n }\n\n /**\n * @custom:blocked\n * @notice Mints some amount of ETH.\n */\n function mint(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: mint is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Burns some amount of ETH.\n */\n function burn(address, uint256) public virtual override {\n revert(\"LegacyERC20ETH: burn is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers some amount of ETH.\n */\n function transfer(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transfer is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Approves a spender to spend some amount of ETH.\n */\n function approve(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: approve is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Transfers funds from some sender account.\n */\n function transferFrom(\n address,\n address,\n uint256\n ) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: transferFrom is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Increases the allowance of a spender.\n */\n function increaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n }\n\n /**\n * @custom:blocked\n * @notice Decreases the allowance of a spender.\n */\n function decreaseAllowance(address, uint256) public virtual override returns (bool) {\n revert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n }\n}\n" - }, - "contracts/legacy/LegacyMessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:legacy\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000000\n * @title LegacyMessagePasser\n * @notice The LegacyMessagePasser was the low-level mechanism used to send messages from L2 to L1\n * before the Bedrock upgrade. It is now deprecated in favor of the new MessagePasser.\n */\ncontract LegacyMessagePasser is Semver {\n /**\n * @notice Mapping of sent message hashes to boolean status.\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Passes a message to L1.\n *\n * @param _message Message to pass to L1.\n */\n function passMessageToL1(bytes memory _message) external {\n sentMessages[keccak256(abi.encodePacked(_message, msg.sender))] = true;\n }\n}\n" - }, - "contracts/legacy/LegacyMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ILegacyMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\n/**\n * @title LegacyMintableERC20\n * @notice The legacy implementation of the OptimismMintableERC20. This\n * contract is deprecated and should no longer be used.\n */\ncontract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {\n /**\n * @notice Emitted when the token is minted by the bridge.\n */\n event Mint(address indexed _account, uint256 _amount);\n\n /**\n * @notice Emitted when a token is burned by the bridge.\n */\n event Burn(address indexed _account, uint256 _amount);\n\n /**\n * @notice The token on the remote domain.\n */\n address public l1Token;\n\n /**\n * @notice The local bridge.\n */\n address public l2Bridge;\n\n /**\n * @param _l2Bridge Address of the L2 standard bridge.\n * @param _l1Token Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _l2Bridge,\n address _l1Token,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) {\n l1Token = _l1Token;\n l2Bridge = _l2Bridge;\n }\n\n /**\n * @notice Modifier that requires the contract was called by the bridge.\n */\n modifier onlyL2Bridge() {\n require(msg.sender == l2Bridge, \"Only L2 Bridge can mint and burn\");\n _;\n }\n\n /**\n * @notice EIP165 implementation.\n */\n function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n\n /**\n * @notice Only the bridge can mint tokens.\n * @param _to The account receiving tokens.\n * @param _amount The amount of tokens to receive.\n */\n function mint(address _to, uint256 _amount) public virtual onlyL2Bridge {\n _mint(_to, _amount);\n\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Only the bridge can burn tokens.\n * @param _from The account having tokens burnt.\n * @param _amount The amount of tokens being burnt.\n */\n function burn(address _from, uint256 _amount) public virtual onlyL2Bridge {\n _burn(_from, _amount);\n\n emit Burn(_from, _amount);\n }\n}\n" - }, - "contracts/legacy/ResolvedDelegateProxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressManager } from \"./AddressManager.sol\";\n\n/**\n * @custom:legacy\n * @title ResolvedDelegateProxy\n * @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to\n * resolve the implementation address. We're maintaining this contract for backwards\n * compatibility so we can manage all legacy proxies where necessary.\n */\ncontract ResolvedDelegateProxy {\n /**\n * @notice Mapping used to store the implementation name that corresponds to this contract. A\n * mapping was originally used as a way to bypass the same issue normally solved by\n * storing the implementation address in a specific storage slot that does not conflict\n * with any other storage slot. Generally NOT a safe solution but works as long as the\n * implementation does not also keep a mapping in the first storage slot.\n */\n mapping(address => string) private implementationName;\n\n /**\n * @notice Mapping used to store the address of the AddressManager contract where the\n * implementation address will be resolved from. Same concept here as with the above\n * mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping\n * in the second storage slot.\n */\n mapping(address => AddressManager) private addressManager;\n\n /**\n * @param _addressManager Address of the AddressManager.\n * @param _implementationName implementationName of the contract to proxy to.\n */\n constructor(AddressManager _addressManager, string memory _implementationName) {\n addressManager[address(this)] = _addressManager;\n implementationName[address(this)] = _implementationName;\n }\n\n /**\n * @notice Fallback, performs a delegatecall to the resolved implementation address.\n */\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n address target = addressManager[address(this)].getAddress(\n (implementationName[address(this)])\n );\n\n require(target != address(0), \"ResolvedDelegateProxy: target address must be initialized\");\n\n // slither-disable-next-line controlled-delegatecall\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\n\n if (success == true) {\n assembly {\n return(add(returndata, 0x20), mload(returndata))\n }\n } else {\n assembly {\n revert(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n" - }, - "contracts/libraries/Arithmetic.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { SignedMath } from \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport { FixedPointMathLib } from \"@rari-capital/solmate/src/utils/FixedPointMathLib.sol\";\n\n/**\n * @title Arithmetic\n * @notice Even more math than before.\n */\nlibrary Arithmetic {\n /**\n * @notice Clamps a value between a minimum and maximum.\n *\n * @param _value The value to clamp.\n * @param _min The minimum value.\n * @param _max The maximum value.\n *\n * @return The clamped value.\n */\n function clamp(\n int256 _value,\n int256 _min,\n int256 _max\n ) internal pure returns (int256) {\n return SignedMath.min(SignedMath.max(_value, _min), _max);\n }\n\n /**\n * @notice (c)oefficient (d)enominator (exp)onentiation function.\n * Returns the result of: c * (1 - 1/d)^exp.\n *\n * @param _coefficient Coefficient of the function.\n * @param _denominator Fractional denominator.\n * @param _exponent Power function exponent.\n *\n * @return Result of c * (1 - 1/d)^exp.\n */\n function cdexp(\n int256 _coefficient,\n int256 _denominator,\n int256 _exponent\n ) internal pure returns (int256) {\n return\n (_coefficient *\n (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;\n }\n}\n" - }, - "contracts/libraries/Burn.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Burn\n * @notice Utilities for burning stuff.\n */\nlibrary Burn {\n /**\n * Burns a given amount of ETH.\n *\n * @param _amount Amount of ETH to burn.\n */\n function eth(uint256 _amount) internal {\n new Burner{ value: _amount }();\n }\n\n /**\n * Burns a given amount of gas.\n *\n * @param _amount Amount of gas to burn.\n */\n function gas(uint256 _amount) internal view {\n uint256 i = 0;\n uint256 initialGas = gasleft();\n while (initialGas - gasleft() < _amount) {\n ++i;\n }\n }\n}\n\n/**\n * @title Burner\n * @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to\n * the contract from the circulating supply. Self-destructing is the only way to remove ETH\n * from the circulating supply.\n */\ncontract Burner {\n constructor() payable {\n selfdestruct(payable(address(this)));\n }\n}\n" - }, - "contracts/libraries/Bytes.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Bytes\n * @notice Bytes is a library for manipulating byte arrays.\n */\nlibrary Bytes {\n /**\n * @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\n * @notice Slices a byte array with a given starting index and length. Returns a new byte array\n * as opposed to a pointer to the original array. Will throw if trying to slice more\n * bytes than exist in the array.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n * @param _length Length of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n ) internal pure returns (bytes memory) {\n unchecked {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_start + _length >= _start, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n }\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n /**\n * @notice Slices a byte array with a given starting index up to the end of the original byte\n * array. Returns a new array rathern than a pointer to the original.\n *\n * @param _bytes Byte array to slice.\n * @param _start Starting index of the slice.\n *\n * @return Slice of the input byte array.\n */\n function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\n if (_start >= _bytes.length) {\n return bytes(\"\");\n }\n return slice(_bytes, _start, _bytes.length - _start);\n }\n\n /**\n * @notice Converts a byte array into a nibble array by splitting each byte into two nibbles.\n * Resulting nibble array will be exactly twice as long as the input byte array.\n *\n * @param _bytes Input byte array to convert.\n *\n * @return Resulting nibble array.\n */\n function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n uint256 bytesLength = _bytes.length;\n bytes memory nibbles = new bytes(bytesLength * 2);\n bytes1 b;\n\n for (uint256 i = 0; i < bytesLength; ) {\n b = _bytes[i];\n nibbles[i * 2] = b >> 4;\n nibbles[i * 2 + 1] = b & 0x0f;\n unchecked {\n ++i;\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Compares two byte arrays by comparing their keccak256 hashes.\n *\n * @param _bytes First byte array to compare.\n * @param _other Second byte array to compare.\n *\n * @return True if the two byte arrays are equal, false otherwise.\n */\n function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n return keccak256(_bytes) == keccak256(_other);\n }\n}\n" - }, - "contracts/libraries/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n/**\n * @title Constants\n * @notice Constants is a library for storing constants. Simple! Don't put everything in here, just\n * the stuff used in multiple contracts. Constants that only apply to a single contract\n * should be defined in that contract instead.\n */\nlibrary Constants {\n /**\n * @notice Special address to be used as the tx origin for gas estimation calls in the\n * OptimismPortal and CrossDomainMessenger calls. You only need to use this address if\n * the minimum gas limit specified by the user is not actually enough to execute the\n * given message and you're attempting to estimate the actual necessary gas limit. We\n * use address(1) because it's the ecrecover precompile and therefore guaranteed to\n * never have any code on any EVM chain.\n */\n address internal constant ESTIMATION_ADDRESS = address(1);\n\n /**\n * @notice Value used for the L2 sender storage slot in both the OptimismPortal and the\n * CrossDomainMessenger contracts before an actual sender is set. This value is\n * non-zero to reduce the gas cost of message passing transactions.\n */\n address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;\n\n /**\n * @notice Returns the default values for the ResourceConfig. These are the recommended values\n * for a production network.\n */\n function DEFAULT_RESOURCE_CONFIG()\n internal\n pure\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n return config;\n }\n}\n" - }, - "contracts/libraries/Encoding.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Hashing } from \"./Hashing.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\n\n/**\n * @title Encoding\n * @notice Encoding handles Optimism's various different encoding schemes.\n */\nlibrary Encoding {\n /**\n * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\n * to the L2 system. Useful for searching for a deposit in the L2 system. The\n * transaction is prefixed with 0x7e to identify its EIP-2718 type.\n *\n * @param _tx User deposit transaction to encode.\n *\n * @return RLP encoded L2 deposit transaction.\n */\n function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes memory)\n {\n bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\n bytes[] memory raw = new bytes[](8);\n raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\n raw[1] = RLPWriter.writeAddress(_tx.from);\n raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\"\") : RLPWriter.writeAddress(_tx.to);\n raw[3] = RLPWriter.writeUint(_tx.mint);\n raw[4] = RLPWriter.writeUint(_tx.value);\n raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\n raw[6] = RLPWriter.writeBool(false);\n raw[7] = RLPWriter.writeBytes(_tx.data);\n return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\n }\n\n /**\n * @notice Encodes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n (, uint16 version) = decodeVersionedNonce(_nonce);\n if (version == 0) {\n return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Encoding: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Encodes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _data,\n _nonce\n );\n }\n\n /**\n * @notice Encodes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(uint256,address,address,uint256,uint256,bytes)\",\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n }\n\n /**\n * @notice Adds a version number into the first two bytes of a message nonce.\n *\n * @param _nonce Message nonce to encode into.\n * @param _version Version number to encode into the message nonce.\n *\n * @return Message nonce with version encoded into the first two bytes.\n */\n function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\n uint256 nonce;\n assembly {\n nonce := or(shl(240, _version), _nonce)\n }\n return nonce;\n }\n\n /**\n * @notice Pulls the version out of a version-encoded nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n *\n * @return Nonce without encoded version.\n * @return Version of the message.\n */\n function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\n uint240 nonce;\n uint16 version;\n assembly {\n nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n version := shr(240, _nonce)\n }\n return (nonce, version);\n }\n}\n" - }, - "contracts/libraries/Hashing.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Encoding } from \"./Encoding.sol\";\n\n/**\n * @title Hashing\n * @notice Hashing handles Optimism's various different hashing schemes.\n */\nlibrary Hashing {\n /**\n * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\n * given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\n * system.\n *\n * @param _tx User deposit transaction to hash.\n *\n * @return Hash of the RLP encoded L2 deposit transaction.\n */\n function hashDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return keccak256(Encoding.encodeDepositTransaction(_tx));\n }\n\n /**\n * @notice Computes the deposit transaction's \"source hash\", a value that guarantees the hash\n * of the L2 transaction that corresponds to a deposit is unique and is\n * deterministically generated from L1 transaction data.\n *\n * @param _l1BlockHash Hash of the L1 block where the deposit was included.\n * @param _logIndex The index of the log that created the deposit transaction.\n *\n * @return Hash of the deposit transaction's \"source hash\".\n */\n function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)\n internal\n pure\n returns (bytes32)\n {\n bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\n return keccak256(abi.encode(bytes32(0), depositId));\n }\n\n /**\n * @notice Hashes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n if (version == 0) {\n return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Hashing: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Hashes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes32) {\n return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));\n }\n\n /**\n * @notice Hashes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n return\n keccak256(\n Encoding.encodeCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n )\n );\n }\n\n /**\n * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\n *\n * @param _tx Withdrawal transaction to hash.\n *\n * @return Hashed withdrawal transaction.\n */\n function hashWithdrawal(Types.WithdrawalTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\n );\n }\n\n /**\n * @notice Hashes the various elements of an output root proof into an output root hash which\n * can be used to check if the proof is valid.\n *\n * @param _outputRootProof Output root proof which should hash to an output root.\n *\n * @return Hashed output root proof.\n */\n function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(\n _outputRootProof.version,\n _outputRootProof.stateRoot,\n _outputRootProof.messagePasserStorageRoot,\n _outputRootProof.latestBlockhash\n )\n );\n }\n}\n" - }, - "contracts/libraries/LegacyCrossDomainUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n// Importing from the legacy contracts package causes issues with the build of the contract bindings\n// so we just copy the library here from\n// /packages/contracts/contracts/libraries/bridge/Lib_CrossDomainUtils.sol at commit\n// 7866168c\n/**\n * @title LegacyCrossDomainUtils\n */\nlibrary LegacyCrossDomainUtils {\n /**\n * Generates the correct cross domain calldata for a message.\n * @param _target Target contract address.\n * @param _sender Message sender address.\n * @param _message Message to send to the target.\n * @param _messageNonce Nonce for the provided message.\n * @return ABI encoded cross domain calldata.\n */\n function encodeXDomainCalldata(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _message,\n _messageNonce\n );\n }\n}\n" - }, - "contracts/libraries/Predeploys.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Predeploys\n * @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.\n */\nlibrary Predeploys {\n /**\n * @notice Address of the L2ToL1MessagePasser predeploy.\n */\n address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;\n\n /**\n * @notice Address of the L2CrossDomainMessenger predeploy.\n */\n address internal constant L2_CROSS_DOMAIN_MESSENGER =\n 0x4200000000000000000000000000000000000007;\n\n /**\n * @notice Address of the L2StandardBridge predeploy.\n */\n address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\n\n /**\n * @notice Address of the L2ERC721Bridge predeploy.\n */\n address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;\n\n /**\n * @notice Address of the SequencerFeeWallet predeploy.\n */\n address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;\n\n /**\n * @notice Address of the OptimismMintableERC20Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY =\n 0x4200000000000000000000000000000000000012;\n\n /**\n * @notice Address of the OptimismMintableERC721Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY =\n 0x4200000000000000000000000000000000000017;\n\n /**\n * @notice Address of the L1Block predeploy.\n */\n address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;\n\n /**\n * @notice Address of the GasPriceOracle predeploy. Includes fee information\n * and helpers for computing the L1 portion of the transaction fee.\n */\n address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;\n\n /**\n * @custom:legacy\n * @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger\n * or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.\n */\n address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\n\n /**\n * @custom:legacy\n * @notice Address of the DeployerWhitelist predeploy. No longer active.\n */\n address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the\n * state trie as of the Bedrock upgrade. Contract has been locked and write functions\n * can no longer be accessed.\n */\n address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;\n\n /**\n * @custom:legacy\n * @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy\n * instead, which exposes more information about the L1 state.\n */\n address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated\n * L2ToL1MessagePasser contract instead.\n */\n address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\n\n /**\n * @notice Address of the ProxyAdmin predeploy.\n */\n address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;\n\n /**\n * @notice Address of the BaseFeeVault predeploy.\n */\n address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;\n\n /**\n * @notice Address of the L1FeeVault predeploy.\n */\n address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;\n\n /**\n * @notice Address of the GovernanceToken predeploy.\n */\n address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042;\n}\n" - }, - "contracts/libraries/SafeCall.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title SafeCall\n * @notice Perform low level safe calls\n */\nlibrary SafeCall {\n /**\n * @notice Perform a low level call without copying any returndata\n *\n * @param _target Address to call\n * @param _gas Amount of gas to pass to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function call(\n address _target,\n uint256 _gas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n }\n return _success;\n }\n\n /**\n * @notice Perform a low level call without copying any returndata. This function\n * will revert if the call cannot be performed with the specified minimum\n * gas.\n *\n * @param _target Address to call\n * @param _minGas The minimum amount of gas that may be passed to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function callWithMinGas(\n address _target,\n uint256 _minGas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n // Assertion: gasleft() >= ((_minGas + 200) * 64) / 63\n //\n // Because EIP-150 ensures that, a maximum of 63/64ths of the remaining gas in the call\n // frame may be passed to a subcontext, we need to ensure that the gas will not be\n // truncated to hold this function's invariant: \"If a call is performed by\n // `callWithMinGas`, it must receive at least the specified minimum gas limit.\" In\n // addition, exactly 51 gas is consumed between the below `GAS` opcode and the `CALL`\n // opcode, so it is factored in with some extra room for error.\n if lt(gas(), div(mul(64, add(_minGas, 200)), 63)) {\n // Store the \"Error(string)\" selector in scratch space.\n mstore(0, 0x08c379a0)\n // Store the pointer to the string length in scratch space.\n mstore(32, 32)\n // Store the string.\n //\n // SAFETY:\n // - We pad the beginning of the string with two zero bytes as well as the\n // length (24) to ensure that we override the free memory pointer at offset\n // 0x40. This is necessary because the free memory pointer is likely to\n // be greater than 1 byte when this function is called, but it is incredibly\n // unlikely that it will be greater than 3 bytes. As for the data within\n // 0x60, it is ensured that it is 0 due to 0x60 being the zero offset.\n // - It's fine to clobber the free memory pointer, we're reverting.\n mstore(88, 0x0000185361666543616c6c3a204e6f7420656e6f75676820676173)\n\n // Revert with 'Error(\"SafeCall: Not enough gas\")'\n revert(28, 100)\n }\n\n // The call will be supplied at least (((_minGas + 200) * 64) / 63) - 49 gas due to the\n // above assertion. This ensures that, in all circumstances, the call will\n // receive at least the minimum amount of gas specified.\n // We can prove this property by solving the inequalities:\n // ((((_minGas + 200) * 64) / 63) - 49) >= _minGas\n // ((((_minGas + 200) * 64) / 63) - 51) * (63 / 64) >= _minGas\n // Both inequalities hold true for all possible values of `_minGas`.\n _success := call(\n gas(), // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0x00, // outloc\n 0x00 // outlen\n )\n }\n return _success;\n }\n}\n" - }, - "contracts/libraries/Types.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Types\n * @notice Contains various types used throughout the Optimism contract system.\n */\nlibrary Types {\n /**\n * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\n * timestamp that the output root is posted. This timestamp is used to verify that the\n * finalization period has passed since the output root was submitted.\n *\n * @custom:field outputRoot Hash of the L2 output.\n * @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.\n * @custom:field l2BlockNumber L2 block number that the output corresponds to.\n */\n struct OutputProposal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2BlockNumber;\n }\n\n /**\n * @notice Struct representing the elements that are hashed together to generate an output root\n * which itself represents a snapshot of the L2 state.\n *\n * @custom:field version Version of the output root.\n * @custom:field stateRoot Root of the state trie at the block of this output.\n * @custom:field messagePasserStorageRoot Root of the message passer storage trie.\n * @custom:field latestBlockhash Hash of the block this output was generated from.\n */\n struct OutputRootProof {\n bytes32 version;\n bytes32 stateRoot;\n bytes32 messagePasserStorageRoot;\n bytes32 latestBlockhash;\n }\n\n /**\n * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n * user (as opposed to a system deposit transaction generated by the system).\n *\n * @custom:field from Address of the sender of the transaction.\n * @custom:field to Address of the recipient of the transaction.\n * @custom:field isCreation True if the transaction is a contract creation.\n * @custom:field value Value to send to the recipient.\n * @custom:field mint Amount of ETH to mint.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n * @custom:field l1BlockHash Hash of the block the transaction was submitted in.\n * @custom:field logIndex Index of the log in the block the transaction was submitted in.\n */\n struct UserDepositTransaction {\n address from;\n address to;\n bool isCreation;\n uint256 value;\n uint256 mint;\n uint64 gasLimit;\n bytes data;\n bytes32 l1BlockHash;\n uint256 logIndex;\n }\n\n /**\n * @notice Struct representing a withdrawal transaction.\n *\n * @custom:field nonce Nonce of the withdrawal transaction\n * @custom:field sender Address of the sender of the transaction.\n * @custom:field target Address of the recipient of the transaction.\n * @custom:field value Value to send to the recipient.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n */\n struct WithdrawalTransaction {\n uint256 nonce;\n address sender;\n address target;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPReader.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\n/**\n * @custom:attribution https://github.com/hamdiallam/Solidity-RLP\n * @title RLPReader\n * @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted\n * from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with\n * various tweaks to improve readability.\n */\nlibrary RLPReader {\n /**\n * Custom pointer type to avoid confusion between pointers and uint256s.\n */\n type MemoryPointer is uint256;\n\n /**\n * @notice RLP item types.\n *\n * @custom:value DATA_ITEM Represents an RLP data item (NOT a list).\n * @custom:value LIST_ITEM Represents an RLP list item.\n */\n enum RLPItemType {\n DATA_ITEM,\n LIST_ITEM\n }\n\n /**\n * @notice Struct representing an RLP item.\n *\n * @custom:field length Length of the RLP item.\n * @custom:field ptr Pointer to the RLP item in memory.\n */\n struct RLPItem {\n uint256 length;\n MemoryPointer ptr;\n }\n\n /**\n * @notice Max list length that this library will accept.\n */\n uint256 internal constant MAX_LIST_LENGTH = 32;\n\n /**\n * @notice Converts bytes to a reference to memory position and length.\n *\n * @param _in Input bytes to convert.\n *\n * @return Output memory reference.\n */\n function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n // Empty arrays are not RLP items.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr;\n assembly {\n ptr := add(_in, 32)\n }\n\n return RLPItem({ length: _in.length, ptr: ptr });\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n (uint256 listOffset, uint256 listLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.LIST_ITEM,\n \"RLPReader: decoded item type for list is not a list item\"\n );\n\n require(\n listOffset + listLength == _in.length,\n \"RLPReader: list item has an invalid data remainder\"\n );\n\n // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n // writing to the length. Since we can't know the number of RLP items without looping over\n // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n // simply set a reasonable maximum list length and decrease the size before we finish.\n RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n uint256 itemCount = 0;\n uint256 offset = listOffset;\n while (offset < _in.length) {\n (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n RLPItem({\n length: _in.length - offset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n })\n );\n\n // We don't need to check itemCount < out.length explicitly because Solidity already\n // handles this check on our behalf, we'd just be wasting gas.\n out[itemCount] = RLPItem({\n length: itemLength + itemOffset,\n ptr: MemoryPointer.wrap(MemoryPointer.unwrap(_in.ptr) + offset)\n });\n\n itemCount += 1;\n offset += itemOffset + itemLength;\n }\n\n // Decrease the array size to match the actual item count.\n assembly {\n mstore(out, itemCount)\n }\n\n return out;\n }\n\n /**\n * @notice Reads an RLP list value into a list of RLP items.\n *\n * @param _in RLP list value.\n *\n * @return Decoded RLP list items.\n */\n function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n return readList(toRLPItem(_in));\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n require(\n itemType == RLPItemType.DATA_ITEM,\n \"RLPReader: decoded item type for bytes is not a data item\"\n );\n\n require(\n _in.length == itemOffset + itemLength,\n \"RLPReader: bytes value contains an invalid remainder\"\n );\n\n return _copy(_in.ptr, itemOffset, itemLength);\n }\n\n /**\n * @notice Reads an RLP bytes value into bytes.\n *\n * @param _in RLP bytes value.\n *\n * @return Decoded bytes.\n */\n function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n return readBytes(toRLPItem(_in));\n }\n\n /**\n * @notice Reads the raw bytes of an RLP item.\n *\n * @param _in RLP item to read.\n *\n * @return Raw RLP bytes.\n */\n function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n return _copy(_in.ptr, 0, _in.length);\n }\n\n /**\n * @notice Decodes the length of an RLP item.\n *\n * @param _in RLP item to decode.\n *\n * @return Offset of the encoded data.\n * @return Length of the encoded data.\n * @return RLP item type (LIST_ITEM or DATA_ITEM).\n */\n function _decodeLength(RLPItem memory _in)\n private\n pure\n returns (\n uint256,\n uint256,\n RLPItemType\n )\n {\n // Short-circuit if there's nothing to decode, note that we perform this check when\n // the user creates an RLP item via toRLPItem, but it's always possible for them to bypass\n // that function and create an RLP item directly. So we need to check this anyway.\n require(\n _in.length > 0,\n \"RLPReader: length of an RLP item must be greater than zero to be decodable\"\n );\n\n MemoryPointer ptr = _in.ptr;\n uint256 prefix;\n assembly {\n prefix := byte(0, mload(ptr))\n }\n\n if (prefix <= 0x7f) {\n // Single byte.\n return (0, 1, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xb7) {\n // Short string.\n\n // slither-disable-next-line variable-scope\n uint256 strLen = prefix - 0x80;\n\n require(\n _in.length > strLen,\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n strLen != 1 || firstByteOfContent >= 0x80,\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n\n return (1, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xbf) {\n // Long string.\n uint256 lenOfStrLen = prefix - 0xb7;\n\n require(\n _in.length > lenOfStrLen,\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n\n uint256 strLen;\n assembly {\n strLen := shr(sub(256, mul(8, lenOfStrLen)), mload(add(ptr, 1)))\n }\n\n require(\n strLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long string)\"\n );\n\n require(\n _in.length > lenOfStrLen + strLen,\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n\n return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n } else if (prefix <= 0xf7) {\n // Short list.\n // slither-disable-next-line variable-scope\n uint256 listLen = prefix - 0xc0;\n\n require(\n _in.length > listLen,\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n\n return (1, listLen, RLPItemType.LIST_ITEM);\n } else {\n // Long list.\n uint256 lenOfListLen = prefix - 0xf7;\n\n require(\n _in.length > lenOfListLen,\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n\n bytes1 firstByteOfContent;\n assembly {\n firstByteOfContent := and(mload(add(ptr, 1)), shl(248, 0xff))\n }\n\n require(\n firstByteOfContent != 0x00,\n \"RLPReader: length of content must not have any leading zeros (long list)\"\n );\n\n uint256 listLen;\n assembly {\n listLen := shr(sub(256, mul(8, lenOfListLen)), mload(add(ptr, 1)))\n }\n\n require(\n listLen > 55,\n \"RLPReader: length of content must be greater than 55 bytes (long list)\"\n );\n\n require(\n _in.length > lenOfListLen + listLen,\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n\n return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n }\n }\n\n /**\n * @notice Copies the bytes from a memory location.\n *\n * @param _src Pointer to the location to read from.\n * @param _offset Offset to start reading from.\n * @param _length Number of bytes to read.\n *\n * @return Copied bytes.\n */\n function _copy(\n MemoryPointer _src,\n uint256 _offset,\n uint256 _length\n ) private pure returns (bytes memory) {\n bytes memory out = new bytes(_length);\n if (_length == 0) {\n return out;\n }\n\n // Mostly based on Solidity's copy_memory_to_memory:\n // solhint-disable max-line-length\n // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114\n uint256 src = MemoryPointer.unwrap(_src) + _offset;\n assembly {\n let dest := add(out, 32)\n let i := 0\n for {\n\n } lt(i, _length) {\n i := add(i, 32)\n } {\n mstore(add(dest, i), mload(add(src, i)))\n }\n\n if gt(i, _length) {\n mstore(add(dest, _length), 0)\n }\n }\n\n return out;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPWriter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\n * @title RLPWriter\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\n * RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\n * modifications to improve legibility.\n */\nlibrary RLPWriter {\n /**\n * @notice RLP encodes a byte string.\n *\n * @param _in The byte string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_in.length == 1 && uint8(_in[0]) < 128) {\n encoded = _in;\n } else {\n encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n }\n\n return encoded;\n }\n\n /**\n * @notice RLP encodes a list of RLP encoded byte byte strings.\n *\n * @param _in The list of RLP encoded byte strings.\n *\n * @return The RLP encoded list of items in bytes.\n */\n function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n bytes memory list = _flatten(_in);\n return abi.encodePacked(_writeLength(list.length, 192), list);\n }\n\n /**\n * @notice RLP encodes a string.\n *\n * @param _in The string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeString(string memory _in) internal pure returns (bytes memory) {\n return writeBytes(bytes(_in));\n }\n\n /**\n * @notice RLP encodes an address.\n *\n * @param _in The address to encode.\n *\n * @return The RLP encoded address in bytes.\n */\n function writeAddress(address _in) internal pure returns (bytes memory) {\n return writeBytes(abi.encodePacked(_in));\n }\n\n /**\n * @notice RLP encodes a uint.\n *\n * @param _in The uint256 to encode.\n *\n * @return The RLP encoded uint256 in bytes.\n */\n function writeUint(uint256 _in) internal pure returns (bytes memory) {\n return writeBytes(_toBinary(_in));\n }\n\n /**\n * @notice RLP encodes a bool.\n *\n * @param _in The bool to encode.\n *\n * @return The RLP encoded bool in bytes.\n */\n function writeBool(bool _in) internal pure returns (bytes memory) {\n bytes memory encoded = new bytes(1);\n encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n return encoded;\n }\n\n /**\n * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\n *\n * @param _len The length of the string or the payload.\n * @param _offset 128 if item is string, 192 if item is list.\n *\n * @return RLP encoded bytes.\n */\n function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_len < 56) {\n encoded = new bytes(1);\n encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n } else {\n uint256 lenLen;\n uint256 i = 1;\n while (_len / i != 0) {\n lenLen++;\n i *= 256;\n }\n\n encoded = new bytes(lenLen + 1);\n encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n for (i = 1; i <= lenLen; i++) {\n encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n }\n }\n\n return encoded;\n }\n\n /**\n * @notice Encode integer in big endian binary form with no leading zeroes.\n *\n * @param _x The integer to encode.\n *\n * @return RLP encoded bytes.\n */\n function _toBinary(uint256 _x) private pure returns (bytes memory) {\n bytes memory b = abi.encodePacked(_x);\n\n uint256 i = 0;\n for (; i < 32; i++) {\n if (b[i] != 0) {\n break;\n }\n }\n\n bytes memory res = new bytes(32 - i);\n for (uint256 j = 0; j < res.length; j++) {\n res[j] = b[i++];\n }\n\n return res;\n }\n\n /**\n * @custom:attribution https://github.com/Arachnid/solidity-stringutils\n * @notice Copies a piece of memory to another location.\n *\n * @param _dest Destination location.\n * @param _src Source location.\n * @param _len Length of memory to copy.\n */\n function _memcpy(\n uint256 _dest,\n uint256 _src,\n uint256 _len\n ) private pure {\n uint256 dest = _dest;\n uint256 src = _src;\n uint256 len = _len;\n\n for (; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n uint256 mask;\n unchecked {\n mask = 256**(32 - len) - 1;\n }\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /**\n * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\n * @notice Flattens a list of byte strings into one byte string.\n *\n * @param _list List of byte strings to flatten.\n *\n * @return The flattened byte string.\n */\n function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n if (_list.length == 0) {\n return new bytes(0);\n }\n\n uint256 len;\n uint256 i = 0;\n for (; i < _list.length; i++) {\n len += _list[i].length;\n }\n\n bytes memory flattened = new bytes(len);\n uint256 flattenedPtr;\n assembly {\n flattenedPtr := add(flattened, 0x20)\n }\n\n for (i = 0; i < _list.length; i++) {\n bytes memory item = _list[i];\n\n uint256 listPtr;\n assembly {\n listPtr := add(item, 0x20)\n }\n\n _memcpy(flattenedPtr, listPtr, item.length);\n flattenedPtr += _list[i].length;\n }\n\n return flattened;\n }\n}\n" - }, - "contracts/libraries/trie/MerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Bytes } from \"../Bytes.sol\";\nimport { RLPReader } from \"../rlp/RLPReader.sol\";\n\n/**\n * @title MerkleTrie\n * @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie\n * inclusion proofs. By default, this library assumes a hexary trie. One can change the\n * trie radix constant to support other trie radixes.\n */\nlibrary MerkleTrie {\n /**\n * @notice Struct representing a node in the trie.\n *\n * @custom:field encoded The RLP-encoded node.\n * @custom:field decoded The RLP-decoded node.\n */\n struct TrieNode {\n bytes encoded;\n RLPReader.RLPItem[] decoded;\n }\n\n /**\n * @notice Determines the number of elements per branch node.\n */\n uint256 internal constant TREE_RADIX = 16;\n\n /**\n * @notice Branch nodes have TREE_RADIX elements and one value element.\n */\n uint256 internal constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\n\n /**\n * @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.\n */\n uint256 internal constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\n\n /**\n * @notice Prefix for even-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_EVEN = 0;\n\n /**\n * @notice Prefix for odd-nibbled extension node paths.\n */\n uint8 internal constant PREFIX_EXTENSION_ODD = 1;\n\n /**\n * @notice Prefix for even-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_EVEN = 2;\n\n /**\n * @notice Prefix for odd-nibbled leaf node paths.\n */\n uint8 internal constant PREFIX_LEAF_ODD = 3;\n\n /**\n * @notice Verifies a proof that a given key/value pair is present in the trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n return Bytes.equal(_value, get(_key, _proof, _root));\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n require(_key.length > 0, \"MerkleTrie: empty key\");\n\n TrieNode[] memory proof = _parseProof(_proof);\n bytes memory key = Bytes.toNibbles(_key);\n bytes memory currentNodeID = abi.encodePacked(_root);\n uint256 currentKeyIndex = 0;\n\n // Proof is top-down, so we start at the first element (root).\n for (uint256 i = 0; i < proof.length; i++) {\n TrieNode memory currentNode = proof[i];\n\n // Key index should never exceed total key length or we'll be out of bounds.\n require(\n currentKeyIndex <= key.length,\n \"MerkleTrie: key index exceeds total key length\"\n );\n\n if (currentKeyIndex == 0) {\n // First proof element is always the root node.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid root hash\"\n );\n } else if (currentNode.encoded.length >= 32) {\n // Nodes 32 bytes or larger are hashed inside branch nodes.\n require(\n Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),\n \"MerkleTrie: invalid large internal hash\"\n );\n } else {\n // Nodes smaller than 32 bytes aren't hashed.\n require(\n Bytes.equal(currentNode.encoded, currentNodeID),\n \"MerkleTrie: invalid internal node hash\"\n );\n }\n\n if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\n if (currentKeyIndex == key.length) {\n // Value is the last element of the decoded list (for branch nodes). There's\n // some ambiguity in the Merkle trie specification because bytes(0) is a\n // valid value to place into the trie, but for branch nodes bytes(0) can exist\n // even when the value wasn't explicitly placed there. Geth treats a value of\n // bytes(0) as \"key does not exist\" and so we do the same.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[TREE_RADIX]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (branch)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (branch)\"\n );\n\n return value;\n } else {\n // We're not at the end of the key yet.\n // Figure out what the next node ID should be and continue.\n uint8 branchKey = uint8(key[currentKeyIndex]);\n RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\n currentNodeID = _getNodeID(nextNode);\n currentKeyIndex += 1;\n }\n } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\n bytes memory path = _getNodePath(currentNode);\n uint8 prefix = uint8(path[0]);\n uint8 offset = 2 - (prefix % 2);\n bytes memory pathRemainder = Bytes.slice(path, offset);\n bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);\n uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\n\n // Whether this is a leaf node or an extension node, the path remainder MUST be a\n // prefix of the key remainder (or be equal to the key remainder) or the proof is\n // considered invalid.\n require(\n pathRemainder.length == sharedNibbleLength,\n \"MerkleTrie: path remainder must share all nibbles with key\"\n );\n\n if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\n // Prefix of 2 or 3 means this is a leaf node. For the leaf node to be valid,\n // the key remainder must be exactly equal to the path remainder. We already\n // did the necessary byte comparison, so it's more efficient here to check that\n // the key remainder length equals the shared nibble length, which implies\n // equality with the path remainder (since we already did the same check with\n // the path remainder and the shared nibble length).\n require(\n keyRemainder.length == sharedNibbleLength,\n \"MerkleTrie: key remainder must be identical to path remainder\"\n );\n\n // Our Merkle Trie is designed specifically for the purposes of the Ethereum\n // state trie. Empty values are not allowed in the state trie, so we can safely\n // say that if the value is empty, the key should not exist and the proof is\n // invalid.\n bytes memory value = RLPReader.readBytes(currentNode.decoded[1]);\n require(\n value.length > 0,\n \"MerkleTrie: value length must be greater than zero (leaf)\"\n );\n\n // Extra proof elements are not allowed.\n require(\n i == proof.length - 1,\n \"MerkleTrie: value node must be last node in proof (leaf)\"\n );\n\n return value;\n } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\n // Prefix of 0 or 1 means this is an extension node. We move onto the next node\n // in the proof and increment the key index by the length of the path remainder\n // which is equal to the shared nibble length.\n currentNodeID = _getNodeID(currentNode.decoded[1]);\n currentKeyIndex += sharedNibbleLength;\n } else {\n revert(\"MerkleTrie: received a node with an unknown prefix\");\n }\n } else {\n revert(\"MerkleTrie: received an unparseable node\");\n }\n }\n\n revert(\"MerkleTrie: ran out of proof elements\");\n }\n\n /**\n * @notice Parses an array of proof elements into a new array that contains both the original\n * encoded element and the RLP-decoded element.\n *\n * @param _proof Array of proof elements to parse.\n *\n * @return Proof parsed into easily accessible structs.\n */\n function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {\n uint256 length = _proof.length;\n TrieNode[] memory proof = new TrieNode[](length);\n for (uint256 i = 0; i < length; ) {\n proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });\n unchecked {\n ++i;\n }\n }\n return proof;\n }\n\n /**\n * @notice Picks out the ID for a node. Node ID is referred to as the \"hash\" within the\n * specification, but nodes < 32 bytes are not actually hashed.\n *\n * @param _node Node to pull an ID for.\n *\n * @return ID for the node, depending on the size of its contents.\n */\n function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {\n return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);\n }\n\n /**\n * @notice Gets the path for a leaf or extension node.\n *\n * @param _node Node to get a path for.\n *\n * @return Node path, converted to an array of nibbles.\n */\n function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {\n return Bytes.toNibbles(RLPReader.readBytes(_node.decoded[0]));\n }\n\n /**\n * @notice Utility; determines the number of nibbles shared between two nibble arrays.\n *\n * @param _a First nibble array.\n * @param _b Second nibble array.\n *\n * @return Number of shared nibbles.\n */\n function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\n private\n pure\n returns (uint256)\n {\n uint256 shared;\n uint256 max = (_a.length < _b.length) ? _a.length : _b.length;\n for (; shared < max && _a[shared] == _b[shared]; ) {\n unchecked {\n ++shared;\n }\n }\n return shared;\n }\n}\n" - }, - "contracts/libraries/trie/SecureMerkleTrie.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/* Library Imports */\nimport { MerkleTrie } from \"./MerkleTrie.sol\";\n\n/**\n * @title SecureMerkleTrie\n * @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input\n * keys. Ethereum's state trie hashes input keys before storing them.\n */\nlibrary SecureMerkleTrie {\n /**\n * @notice Verifies a proof that a given key/value pair is present in the Merkle trie.\n *\n * @param _key Key of the node to search for, as a hex string.\n * @param _value Value of the node to search for, as a hex string.\n * @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle\n * trees, this proof is executed top-down and consists of a list of RLP-encoded\n * nodes that make a path down to the target node.\n * @param _root Known root of the Merkle trie. Used to verify that the included proof is\n * correctly constructed.\n *\n * @return Whether or not the proof is valid.\n */\n function verifyInclusionProof(\n bytes memory _key,\n bytes memory _value,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bool) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\n }\n\n /**\n * @notice Retrieves the value associated with a given key.\n *\n * @param _key Key to search for, as hex bytes.\n * @param _proof Merkle trie inclusion proof for the key.\n * @param _root Known root of the Merkle trie.\n *\n * @return Value of the key if it exists.\n */\n function get(\n bytes memory _key,\n bytes[] memory _proof,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n bytes memory key = _getSecureKey(_key);\n return MerkleTrie.get(key, _proof, _root);\n }\n\n /**\n * @notice Computes the hashed version of the input key.\n *\n * @param _key Key to hash.\n *\n * @return Hashed version of the key.\n */\n function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {\n return abi.encodePacked(keccak256(_key));\n }\n}\n" - }, - "contracts/periphery/TransferOnion.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title TransferOnion\n * @notice TransferOnion is a hash onion for distributing tokens. The shell commits\n * to an ordered list of the token transfers and can be permissionlessly\n * unwrapped in order. The SENDER must `approve` this contract as\n * `transferFrom` is used to move the token balances.\n */\ncontract TransferOnion is ReentrancyGuard {\n using SafeERC20 for ERC20;\n\n /**\n * @notice Struct representing a layer of the onion.\n */\n struct Layer {\n address recipient;\n uint256 amount;\n bytes32 shell;\n }\n\n /**\n * @notice Address of the token to distribute.\n */\n ERC20 public immutable TOKEN;\n\n /**\n * @notice Address of the account to distribute tokens from.\n */\n address public immutable SENDER;\n\n /**\n * @notice Current shell hash.\n */\n bytes32 public shell;\n\n /**\n * @param _token Address of the token to distribute.\n * @param _sender Address of the sender to distribute from.\n * @param _shell Initial shell of the onion.\n */\n constructor(\n ERC20 _token,\n address _sender,\n bytes32 _shell\n ) {\n TOKEN = _token;\n SENDER = _sender;\n shell = _shell;\n }\n\n /**\n * @notice Peels layers from the onion and distributes tokens.\n *\n * @param _layers Array of onion layers to peel.\n */\n function peel(Layer[] memory _layers) public nonReentrant {\n bytes32 tempShell = shell;\n uint256 length = _layers.length;\n for (uint256 i = 0; i < length; ) {\n Layer memory layer = _layers[i];\n\n // Confirm that the onion layer is correct.\n require(\n keccak256(abi.encode(layer.recipient, layer.amount, layer.shell)) == tempShell,\n \"TransferOnion: what are you doing in my swamp?\"\n );\n\n // Update the onion layer.\n tempShell = layer.shell;\n\n // Transfer the tokens.\n TOKEN.safeTransferFrom(SENDER, layer.recipient, layer.amount);\n\n // Unchecked increment to save some gas.\n unchecked {\n ++i;\n }\n }\n\n shell = tempShell;\n }\n}\n" - }, - "contracts/test/AddressAliasHelper.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\n\ncontract AddressAliasHelper_applyAndUndo_Test is Test {\n /**\n * @notice Tests that applying and then undoing an alias results in the original address.\n */\n function testFuzz_applyAndUndo_succeeds(address _address) external {\n address aliased = AddressAliasHelper.applyL1ToL2Alias(_address);\n address unaliased = AddressAliasHelper.undoL1ToL2Alias(aliased);\n assertEq(_address, unaliased);\n }\n}\n" - }, - "contracts/test/BenchmarkTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test } from \"forge-std/Test.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport \"./CommonTest.t.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n// Free function for setting the prevBaseFee param in the OptimismPortal.\nfunction setPrevBaseFee(\n Vm _vm,\n address _op,\n uint128 _prevBaseFee\n) {\n _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee));\n}\n\ncontract SetPrevBaseFee_Test is Portal_Initializer {\n function test_setPrevBaseFee_succeeds() external {\n setPrevBaseFee(vm, address(op), 100 gwei);\n (uint128 prevBaseFee, , uint64 prevBlockNum) = op.params();\n assertEq(uint256(prevBaseFee), 100 gwei);\n assertEq(uint256(prevBlockNum), block.number);\n }\n}\n\n// Tests for obtaining pure gas cost estimates for commonly used functions.\n// The objective with these benchmarks is to strip down the actual test functions\n// so that they are nothing more than the call we want measure the gas cost of.\n// In order to achieve this we make no assertions, and handle everything else in the setUp()\n// function.\ncontract GasBenchMark_OptimismPortal is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n bytes32 _outputRoot;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n\n // Get withdrawal proof data we can use for testing.\n bytes32 _storageRoot;\n bytes32 _stateRoot;\n (_stateRoot, _storageRoot, _outputRoot, , _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public virtual override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n function test_depositTransaction_benchmark() external {\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_depositTransaction_benchmark_1() external {\n setPrevBaseFee(vm, address(op), 1 gwei);\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n function test_proveWithdrawalTransaction_benchmark() external {\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n}\n\ncontract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer {\n function test_sendMessage_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n\n function test_sendMessage_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n // The amount of data typically sent during a bridge deposit.\n bytes\n memory data = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n vm.resumeGasMetering();\n L1Messenger.sendMessage(bob, data, uint32(100));\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), alice, 100000, true);\n vm.startPrank(alice, alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n }\n\n function test_depositETH_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositETH_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.depositETH{ value: 500 }(50000, hex\"\");\n }\n\n function test_depositERC20_benchmark_0() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 1 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n\n function test_depositERC20_benchmark_1() external {\n vm.pauseGasMetering();\n setPrevBaseFee(vm, address(op), 10 gwei);\n vm.resumeGasMetering();\n L1Bridge.bridgeERC20({\n _localToken: address(L1Token),\n _remoteToken: address(L2Token),\n _amount: 100,\n _minGasLimit: 100_000,\n _extraData: hex\"\"\n });\n }\n}\n\ncontract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer {\n function setUp() public virtual override {\n super.setUp();\n deal(address(L1Token), address(L1Bridge), 100, true);\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.startPrank(address(L1Bridge.messenger()));\n vm.deal(address(L1Bridge.messenger()), 100);\n }\n\n function test_finalizeETHWithdrawal_benchmark() external {\n // TODO: Make this more accurate. It is underestimating the cost because it pranks\n // the call coming from the messenger, which bypasses the portal\n // and oracle.\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer {\n uint256 nextBlockNumber;\n\n function setUp() public override {\n super.setUp();\n nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.startPrank(proposer);\n }\n\n function test_proposeL2Output_benchmark() external {\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n}\n" - }, - "contracts/test/Bytes.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Bytes } from \"../libraries/Bytes.sol\";\n\ncontract Bytes_slice_Test is Test {\n /**\n * @notice Tests that the `slice` function works as expected when starting from index 0.\n */\n function test_slice_fromZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check if all possible slices starting from index 0 are correct.\n assertEq(Bytes.slice(input, 0, 0), hex\"\");\n assertEq(Bytes.slice(input, 0, 1), hex\"11\");\n assertEq(Bytes.slice(input, 0, 2), hex\"1122\");\n assertEq(Bytes.slice(input, 0, 3), hex\"112233\");\n assertEq(Bytes.slice(input, 0, 4), hex\"11223344\");\n assertEq(Bytes.slice(input, 0, 5), hex\"1122334455\");\n assertEq(Bytes.slice(input, 0, 6), hex\"112233445566\");\n assertEq(Bytes.slice(input, 0, 7), hex\"11223344556677\");\n assertEq(Bytes.slice(input, 0, 8), hex\"1122334455667788\");\n assertEq(Bytes.slice(input, 0, 9), hex\"112233445566778899\");\n assertEq(Bytes.slice(input, 0, 10), hex\"11223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when starting from indices [1, 9]\n * with lengths [1, 9], in reverse order.\n */\n function test_slice_fromNonZeroIdx_works() public {\n bytes memory input = hex\"11223344556677889900\";\n\n // Exhaustively check correctness of slices starting from indexes [1, 9]\n // and spanning [1, 9] bytes, in reverse order\n assertEq(Bytes.slice(input, 9, 1), hex\"00\");\n assertEq(Bytes.slice(input, 8, 2), hex\"9900\");\n assertEq(Bytes.slice(input, 7, 3), hex\"889900\");\n assertEq(Bytes.slice(input, 6, 4), hex\"77889900\");\n assertEq(Bytes.slice(input, 5, 5), hex\"6677889900\");\n assertEq(Bytes.slice(input, 4, 6), hex\"556677889900\");\n assertEq(Bytes.slice(input, 3, 7), hex\"44556677889900\");\n assertEq(Bytes.slice(input, 2, 8), hex\"3344556677889900\");\n assertEq(Bytes.slice(input, 1, 9), hex\"223344556677889900\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple words\n * in memory. In this case, we test that a 2 byte slice between the 32nd byte of the\n * first word and the 1st byte of the second word is correct.\n */\n function test_slice_acrossWords_works() public {\n bytes\n memory input = hex\"00000000000000000000000000000000000000000000000000000000000000112200000000000000000000000000000000000000000000000000000000000000\";\n\n assertEq(Bytes.slice(input, 31, 2), hex\"1122\");\n }\n\n /**\n * @notice Tests that the `slice` function works as expected when slicing between multiple\n * words in memory. In this case, we test that a 34 byte slice between 3 separate words\n * returns the correct result.\n */\n function test_slice_acrossMultipleWords_works() public {\n bytes\n memory input = hex\"000000000000000000000000000000000000000000000000000000000000001122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1100000000000000000000000000000000000000000000000000000000000000\";\n bytes\n memory expected = hex\"1122FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11\";\n\n assertEq(Bytes.slice(input, 31, 34), expected);\n }\n\n /**\n * @notice Tests that, when given an input bytes array of length `n`, the `slice` function will\n * always revert if `_start + _length > n`.\n */\n function testFuzz_slice_outOfBounds_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // We want a valid start index and a length that will not overflow.\n vm.assume(_start < _input.length && _length < type(uint256).max - 31);\n // But, we want an invalid slice length.\n vm.assume(_start + _length > _input.length);\n\n vm.expectRevert(\"slice_outOfBounds\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a length `n` that is greater than `type(uint256).max - 31`,\n * the `slice` function reverts.\n */\n function testFuzz_slice_lengthOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that the `_length` will overflow if a number >= 31 is added to it.\n vm.assume(_length > type(uint256).max - 31);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that, when given a start index `n` that is greater than\n * `type(uint256).max - n`, the `slice` function reverts.\n */\n function testFuzz_slice_rangeOverflows_reverts(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // Ensure that `_length` is a realistic length of a slice. This is to make sure\n // we revert on the correct require statement.\n vm.assume(_length < _input.length);\n // Ensure that `_start` will overflow if `_length` is added to it.\n vm.assume(_start > type(uint256).max - _length);\n\n vm.expectRevert(\"slice_overflow\");\n Bytes.slice(_input, _start, _length);\n }\n\n /**\n * @notice Tests that the `slice` function correctly updates the free memory pointer depending\n * on the length of the slice.\n */\n function testFuzz_slice_memorySafety_succeeds(\n bytes memory _input,\n uint256 _start,\n uint256 _length\n ) public {\n // The start should never be more than the length of the input bytes array - 1\n vm.assume(_start < _input.length);\n // The length should never be more than the length of the input bytes array - the starting\n // slice index.\n vm.assume(_length <= _input.length - _start);\n\n // Grab the free memory pointer before the slice operation\n uint64 initPtr;\n assembly {\n initPtr := mload(0x40)\n }\n uint64 expectedPtr = uint64(initPtr + 0x20 + ((_length + 0x1f) & ~uint256(0x1f)));\n\n // Ensure that all memory outside of the expected range is safe.\n vm.expectSafeMemory(initPtr, expectedPtr);\n\n // Slice the input bytes array from `_start` to `_start + _length`\n bytes memory slice = Bytes.slice(_input, _start, _length);\n\n // Grab the free memory pointer after the slice operation\n uint64 finalPtr;\n assembly {\n finalPtr := mload(0x40)\n }\n\n // The free memory pointer should have been updated properly\n if (_length == 0) {\n // If the slice length is zero, only 32 bytes of memory should have been allocated.\n assertEq(finalPtr, initPtr + 0x20);\n } else {\n // If the slice length is greater than zero, the memory allocated should be the\n // length of the slice rounded up to the next 32 byte word + 32 bytes for the\n // length of the byte array.\n //\n // Note that we use a slightly less efficient, but equivalent method of rounding\n // up `_length` to the next multiple of 32 than is used in the `slice` function.\n // This is to diff test the method used in `slice`.\n uint64 _expectedPtr = uint64(initPtr + 0x20 + (((_length + 0x1F) >> 5) << 5));\n assertEq(finalPtr, _expectedPtr);\n\n // Sanity check for equivalence of the rounding methods.\n assertEq(_expectedPtr, expectedPtr);\n }\n\n // The slice length should be equal to `_length`\n assertEq(slice.length, _length);\n }\n}\n\ncontract Bytes_toNibbles_Test is Test {\n /**\n * @notice Diffs the test Solidity version of `toNibbles` against the Yul version.\n *\n * @param _bytes The `bytes` array to convert to nibbles.\n *\n * @return Yul version of `toNibbles` applied to `_bytes`.\n */\n function _toNibblesYul(bytes memory _bytes) internal pure returns (bytes memory) {\n // Allocate memory for the `nibbles` array.\n bytes memory nibbles = new bytes(_bytes.length << 1);\n\n assembly {\n // Load the length of the passed bytes array from memory\n let bytesLength := mload(_bytes)\n\n // Store the memory offset of the _bytes array's contents on the stack\n let bytesStart := add(_bytes, 0x20)\n\n // Store the memory offset of the nibbles array's contents on the stack\n let nibblesStart := add(nibbles, 0x20)\n\n // Loop through each byte in the input array\n for {\n let i := 0x00\n } lt(i, bytesLength) {\n i := add(i, 0x01)\n } {\n // Get the starting offset of the next 2 bytes in the nibbles array\n let offset := add(nibblesStart, shl(0x01, i))\n\n // Load the byte at the current index within the `_bytes` array\n let b := byte(0x00, mload(add(bytesStart, i)))\n\n // Pull out the first nibble and store it in the new array\n mstore8(offset, shr(0x04, b))\n // Pull out the second nibble and store it in the new array\n mstore8(add(offset, 0x01), and(b, 0x0F))\n }\n }\n\n return nibbles;\n }\n\n /**\n * @notice Tests that, given an input of 5 bytes, the `toNibbles` function returns an array of\n * 10 nibbles corresponding to the input data.\n */\n function test_toNibbles_expectedResult5Bytes_works() public {\n bytes memory input = hex\"1234567890\";\n bytes memory expected = hex\"01020304050607080900\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 128 bytes, the `toNibbles` function returns an array\n * of 256 nibbles corresponding to the input data. This test exists to ensure that,\n * given a large input, the `toNibbles` function works as expected.\n */\n function test_toNibbles_expectedResult128Bytes_works() public {\n bytes\n memory input = hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f\";\n bytes\n memory expected = hex\"0000000100020003000400050006000700080009000a000b000c000d000e000f0100010101020103010401050106010701080109010a010b010c010d010e010f0200020102020203020402050206020702080209020a020b020c020d020e020f0300030103020303030403050306030703080309030a030b030c030d030e030f0400040104020403040404050406040704080409040a040b040c040d040e040f0500050105020503050405050506050705080509050a050b050c050d050e050f0600060106020603060406050606060706080609060a060b060c060d060e060f0700070107020703070407050706070707080709070a070b070c070d070e070f\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length * 2, actual.length);\n assertEq(expected.length, actual.length);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Tests that, given an input of 0 bytes, the `toNibbles` function returns a zero\n * length array.\n */\n function test_toNibbles_zeroLengthInput_works() public {\n bytes memory input = hex\"\";\n bytes memory expected = hex\"\";\n bytes memory actual = Bytes.toNibbles(input);\n\n assertEq(input.length, 0);\n assertEq(expected.length, 0);\n assertEq(actual.length, 0);\n assertEq(actual, expected);\n }\n\n /**\n * @notice Test that the `toNibbles` function in the `Bytes` library is equivalent to the Yul\n * implementation.\n */\n function testDiff_toNibbles_succeeds(bytes memory _input) public {\n assertEq(Bytes.toNibbles(_input), _toNibblesYul(_input));\n }\n}\n\ncontract Bytes_equal_Test is Test {\n /**\n * @notice Manually checks equality of two dynamic `bytes` arrays in memory.\n *\n * @param _a The first `bytes` array to compare.\n * @param _b The second `bytes` array to compare.\n *\n * @return True if the two `bytes` arrays are equal in memory.\n */\n function manualEq(bytes memory _a, bytes memory _b) internal pure returns (bool) {\n bool _eq;\n assembly {\n _eq := and(\n // Check if the contents of the two bytes arrays are equal in memory.\n eq(keccak256(add(0x20, _a), mload(_a)), keccak256(add(0x20, _b), mload(_b))),\n // Check if the length of the two bytes arrays are equal in memory.\n // This is redundant given the above check, but included for completeness.\n eq(mload(_a), mload(_b))\n )\n }\n return _eq;\n }\n\n /**\n * @notice Tests that the `equal` function in the `Bytes` library returns `false` if given two\n * non-equal byte arrays.\n */\n function testFuzz_equal_notEqual_works(bytes memory _a, bytes memory _b) public {\n vm.assume(!manualEq(_a, _b));\n assertFalse(Bytes.equal(_a, _b));\n }\n\n /**\n * @notice Test whether or not the `equal` function in the `Bytes` library is equivalent to\n * manually checking equality of the two dynamic `bytes` arrays in memory.\n */\n function testDiff_equal_works(bytes memory _a, bytes memory _b) public {\n assertEq(Bytes.equal(_a, _b), manualEq(_a, _b));\n }\n}\n" - }, - "contracts/test/CommonTest.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Test, StdUtils } from \"forge-std/Test.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L1StandardBridge } from \"../L1/L1StandardBridge.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC20Factory } from \"../universal/OptimismMintableERC20Factory.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { IL1ChugSplashDeployer } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { LegacyMintableERC20 } from \"../legacy/LegacyMintableERC20.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract CommonTest is Test {\n address alice = address(128);\n address bob = address(256);\n address multisig = address(512);\n\n address immutable ZERO_ADDRESS = address(0);\n address immutable NON_ZERO_ADDRESS = address(1);\n uint256 immutable NON_ZERO_VALUE = 100;\n uint256 immutable ZERO_VALUE = 0;\n uint64 immutable NON_ZERO_GASLIMIT = 50000;\n bytes32 nonZeroHash = keccak256(abi.encode(\"NON_ZERO\"));\n bytes NON_ZERO_DATA = hex\"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000\";\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 indexed version,\n bytes opaqueData\n );\n\n FFIInterface ffi;\n\n function setUp() public virtual {\n // Give alice and bob some ETH\n vm.deal(alice, 1 << 16);\n vm.deal(bob, 1 << 16);\n vm.deal(multisig, 1 << 16);\n\n vm.label(alice, \"alice\");\n vm.label(bob, \"bob\");\n vm.label(multisig, \"multisig\");\n\n // Make sure we have a non-zero base fee\n vm.fee(1000000000);\n\n ffi = new FFIInterface();\n }\n\n function emitTransactionDeposited(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gasLimit,\n bool _isCreation,\n bytes memory _data\n ) internal {\n emit TransactionDeposited(\n _from,\n _to,\n 0,\n abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)\n );\n }\n}\n\ncontract L2OutputOracle_Initializer is CommonTest {\n // Test target\n L2OutputOracle oracle;\n L2OutputOracle oracleImpl;\n\n L2ToL1MessagePasser messagePasser =\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));\n\n // Constructor arguments\n address internal proposer = 0x000000000000000000000000000000000000AbBa;\n address internal owner = 0x000000000000000000000000000000000000ACDC;\n uint256 internal submissionInterval = 1800;\n uint256 internal l2BlockTime = 2;\n uint256 internal startingBlockNumber = 200;\n uint256 internal startingTimestamp = 1000;\n address guardian;\n\n // Test data\n uint256 initL1Time;\n\n event OutputProposed(\n bytes32 indexed outputRoot,\n uint256 indexed l2OutputIndex,\n uint256 indexed l2BlockNumber,\n uint256 l1Timestamp\n );\n\n event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);\n\n // Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output\n function warpToProposeTime(uint256 _nextBlockNumber) public {\n vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1);\n }\n\n function setUp() public virtual override {\n super.setUp();\n guardian = makeAddr(\"guardian\");\n\n // By default the first block has timestamp and number zero, which will cause underflows in the\n // tests, so we'll move forward to these block values.\n initL1Time = startingTimestamp + 1;\n vm.warp(initL1Time);\n vm.roll(startingBlockNumber);\n // Deploy the L2OutputOracle and transfer owernship to the proposer\n oracleImpl = new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: startingTimestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(oracleImpl),\n abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp))\n );\n oracle = L2OutputOracle(address(proxy));\n vm.label(address(oracle), \"L2OutputOracle\");\n\n // Set the L2ToL1MessagePasser at the correct address\n vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code);\n\n vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, \"L2ToL1MessagePasser\");\n }\n}\n\ncontract Portal_Initializer is L2OutputOracle_Initializer {\n // Test target\n OptimismPortal internal opImpl;\n OptimismPortal internal op;\n SystemConfig systemConfig;\n\n event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);\n event WithdrawalProven(\n bytes32 indexed withdrawalHash,\n address indexed from,\n address indexed to\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n\n systemConfig = new SystemConfig({\n _owner: address(1),\n _overhead: 0,\n _scalar: 10000,\n _batcherHash: bytes32(0),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(0),\n _config: config\n });\n\n opImpl = new OptimismPortal({\n _l2Oracle: oracle,\n _guardian: guardian,\n _paused: true,\n _config: systemConfig\n });\n\n Proxy proxy = new Proxy(multisig);\n vm.prank(multisig);\n proxy.upgradeToAndCall(\n address(opImpl),\n abi.encodeWithSelector(OptimismPortal.initialize.selector, false)\n );\n op = OptimismPortal(payable(address(proxy)));\n vm.label(address(op), \"OptimismPortal\");\n }\n}\n\ncontract Messenger_Initializer is Portal_Initializer {\n AddressManager internal addressManager;\n L1CrossDomainMessenger internal L1Messenger;\n L2CrossDomainMessenger internal L2Messenger =\n L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);\n\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event RelayedMessage(bytes32 indexed msgHash);\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n event TransactionDeposited(\n address indexed from,\n address indexed to,\n uint256 mint,\n uint256 value,\n uint64 gasLimit,\n bool isCreation,\n bytes data\n );\n\n event WhatHappened(bool success, bytes returndata);\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the address manager\n vm.prank(multisig);\n addressManager = new AddressManager();\n\n // Setup implementation\n L1CrossDomainMessenger L1MessengerImpl = new L1CrossDomainMessenger(op);\n\n // Setup the address manager and proxy\n vm.prank(multisig);\n addressManager.setAddress(\"OVM_L1CrossDomainMessenger\", address(L1MessengerImpl));\n ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(\n addressManager,\n \"OVM_L1CrossDomainMessenger\"\n );\n L1Messenger = L1CrossDomainMessenger(address(proxy));\n L1Messenger.initialize();\n\n vm.etch(\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n address(new L2CrossDomainMessenger(address(L1Messenger))).code\n );\n\n L2Messenger.initialize();\n\n // Label addresses\n vm.label(address(addressManager), \"AddressManager\");\n vm.label(address(L1MessengerImpl), \"L1CrossDomainMessenger_Impl\");\n vm.label(address(L1Messenger), \"L1CrossDomainMessenger_Proxy\");\n vm.label(Predeploys.LEGACY_ERC20_ETH, \"LegacyERC20ETH\");\n vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, \"L2CrossDomainMessenger\");\n\n vm.label(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n \"L1CrossDomainMessenger_aliased\"\n );\n }\n}\n\ncontract Bridge_Initializer is Messenger_Initializer {\n L1StandardBridge L1Bridge;\n L2StandardBridge L2Bridge;\n OptimismMintableERC20Factory L2TokenFactory;\n OptimismMintableERC20Factory L1TokenFactory;\n ERC20 L1Token;\n ERC20 BadL1Token;\n OptimismMintableERC20 L2Token;\n LegacyMintableERC20 LegacyL2Token;\n ERC20 NativeL2Token;\n ERC20 BadL2Token;\n OptimismMintableERC20 RemoteL1Token;\n\n event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHWithdrawalFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data\n );\n\n event ERC20DepositInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20WithdrawalFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event WithdrawalInitiated(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFinalized(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event DepositFailed(\n address indexed l1Token,\n address indexed l2Token,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data);\n\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes data\n );\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.label(Predeploys.L2_STANDARD_BRIDGE, \"L2StandardBridge\");\n vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, \"OptimismMintableERC20Factory\");\n\n // Deploy the L1 bridge and initialize it with the address of the\n // L1CrossDomainMessenger\n L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig);\n vm.mockCall(\n multisig,\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector),\n abi.encode(true)\n );\n vm.startPrank(multisig);\n proxy.setCode(address(new L1StandardBridge(payable(address(L1Messenger)))).code);\n vm.clearMockedCalls();\n address L1Bridge_Impl = proxy.getImplementation();\n vm.stopPrank();\n\n L1Bridge = L1StandardBridge(payable(address(proxy)));\n\n vm.label(address(proxy), \"L1StandardBridge_Proxy\");\n vm.label(address(L1Bridge_Impl), \"L1StandardBridge_Impl\");\n\n // Deploy the L2StandardBridge, move it to the correct predeploy\n // address and then initialize it\n L2StandardBridge l2B = new L2StandardBridge(payable(proxy));\n vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(l2B).code);\n L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));\n\n // Set up the L2 mintable token factory\n OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(\n Predeploys.L2_STANDARD_BRIDGE\n );\n vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code);\n L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);\n\n vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code);\n\n L1Token = new ERC20(\"Native L1 Token\", \"L1T\");\n\n LegacyL2Token = new LegacyMintableERC20({\n _l2Bridge: address(L2Bridge),\n _l1Token: address(L1Token),\n _name: string.concat(\"LegacyL2-\", L1Token.name()),\n _symbol: string.concat(\"LegacyL2-\", L1Token.symbol())\n });\n vm.label(address(LegacyL2Token), \"LegacyMintableERC20\");\n\n // Deploy the L2 ERC20 now\n L2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(L1Token),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n BadL2Token = OptimismMintableERC20(\n L2TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L2-\", L1Token.name())),\n string(abi.encodePacked(\"L2-\", L1Token.symbol()))\n )\n );\n\n NativeL2Token = new ERC20(\"Native L2 Token\", \"L2T\");\n L1TokenFactory = new OptimismMintableERC20Factory(address(L1Bridge));\n\n RemoteL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(NativeL2Token),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n\n BadL1Token = OptimismMintableERC20(\n L1TokenFactory.createStandardL2Token(\n address(1),\n string(abi.encodePacked(\"L1-\", NativeL2Token.name())),\n string(abi.encodePacked(\"L1-\", NativeL2Token.symbol()))\n )\n );\n }\n}\n\ncontract ERC721Bridge_Initializer is Messenger_Initializer {\n L1ERC721Bridge L1Bridge;\n L2ERC721Bridge L2Bridge;\n\n function setUp() public virtual override {\n super.setUp();\n\n // Deploy the L1ERC721Bridge.\n L1Bridge = new L1ERC721Bridge(address(L1Messenger), Predeploys.L2_ERC721_BRIDGE);\n\n // Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.\n vm.etch(\n Predeploys.L2_ERC721_BRIDGE,\n address(new L2ERC721Bridge(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(L1Bridge)))\n .code\n );\n\n // Set up a reference to the L2ERC721Bridge.\n L2Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);\n\n // Label the L1 and L2 bridges.\n vm.label(address(L1Bridge), \"L1ERC721Bridge\");\n vm.label(address(L2Bridge), \"L2ERC721Bridge\");\n }\n}\n\ncontract FFIInterface is Test {\n function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx)\n external\n returns (\n bytes32,\n bytes32,\n bytes32,\n bytes32,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"getProveWithdrawalTransactionInputs\";\n cmds[2] = vm.toString(_tx.nonce);\n cmds[3] = vm.toString(_tx.sender);\n cmds[4] = vm.toString(_tx.target);\n cmds[5] = vm.toString(_tx.value);\n cmds[6] = vm.toString(_tx.gasLimit);\n cmds[7] = vm.toString(_tx.data);\n\n bytes memory result = vm.ffi(cmds);\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[]));\n\n return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof);\n }\n\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashWithdrawal(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes32) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashWithdrawal\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashOutputRootProof(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external returns (bytes32) {\n string[] memory cmds = new string[](6);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashOutputRootProof\";\n cmds[2] = Strings.toHexString(uint256(_version));\n cmds[3] = Strings.toHexString(uint256(_stateRoot));\n cmds[4] = Strings.toHexString(uint256(_messagePasserStorageRoot));\n cmds[5] = Strings.toHexString(uint256(_latestBlockhash));\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function hashDepositTransaction(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external returns (bytes32) {\n string[] memory cmds = new string[](10);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"hashDepositTransaction\";\n cmds[2] = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n cmds[3] = vm.toString(_logIndex);\n cmds[4] = vm.toString(_from);\n cmds[5] = vm.toString(_to);\n cmds[6] = vm.toString(_mint);\n cmds[7] = vm.toString(_value);\n cmds[8] = vm.toString(_gas);\n cmds[9] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes32));\n }\n\n function encodeDepositTransaction(Types.UserDepositTransaction calldata txn)\n external\n returns (bytes memory)\n {\n string[] memory cmds = new string[](11);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeDepositTransaction\";\n cmds[2] = vm.toString(txn.from);\n cmds[3] = vm.toString(txn.to);\n cmds[4] = vm.toString(txn.value);\n cmds[5] = vm.toString(txn.mint);\n cmds[6] = vm.toString(txn.gasLimit);\n cmds[7] = vm.toString(txn.isCreation);\n cmds[8] = vm.toString(txn.data);\n cmds[9] = vm.toString(txn.l1BlockHash);\n cmds[10] = vm.toString(txn.logIndex);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external returns (bytes memory) {\n string[] memory cmds = new string[](8);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"encodeCrossDomainMessage\";\n cmds[2] = vm.toString(_nonce);\n cmds[3] = vm.toString(_sender);\n cmds[4] = vm.toString(_target);\n cmds[5] = vm.toString(_value);\n cmds[6] = vm.toString(_gasLimit);\n cmds[7] = vm.toString(_data);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (bytes));\n }\n\n function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) {\n string[] memory cmds = new string[](3);\n cmds[0] = \"scripts/differential-testing/differential-testing\";\n cmds[1] = \"decodeVersionedNonce\";\n cmds[2] = vm.toString(nonce);\n\n bytes memory result = vm.ffi(cmds);\n return abi.decode(result, (uint256, uint256));\n }\n\n function getMerkleTrieFuzzCase(string memory variant)\n external\n returns (\n bytes32,\n bytes memory,\n bytes memory,\n bytes[] memory\n )\n {\n string[] memory cmds = new string[](5);\n cmds[0] = \"./test-case-generator/fuzz\";\n cmds[1] = \"-m\";\n cmds[2] = \"trie\";\n cmds[3] = \"-v\";\n cmds[4] = variant;\n\n return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[]));\n }\n}\n\n// Used for testing a future upgrade beyond the current implementations.\n// We include some variables so that we can sanity check accessing storage values after an upgrade.\ncontract NextImpl is Initializable {\n // Initializable occupies the zero-th slot.\n bytes32 slot1;\n bytes32[19] __gap;\n bytes32 slot21;\n bytes32 public constant slot21Init = bytes32(hex\"1337\");\n\n function initialize() public reinitializer(2) {\n // Slot21 is unused by an of our upgradeable contracts.\n // This is used to verify that we can access this value after an upgrade.\n slot21 = slot21Init;\n }\n}\n\ncontract Reverter {\n fallback() external {\n revert();\n }\n}\n\n// Useful for testing reentrancy guards\ncontract CallerCaller {\n event WhatHappened(bool success, bytes returndata);\n\n fallback() external {\n (bool success, bytes memory returndata) = msg.sender.call(msg.data);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n}\n\n// Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard.\ncontract ConfigurableCaller {\n bool doRevert = true;\n address target;\n bytes payload;\n\n event WhatHappened(bool success, bytes returndata);\n\n /**\n * @notice Call the configured target with the configured payload OR revert.\n */\n function call() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n } else {\n (bool success, bytes memory returndata) = address(target).call(payload);\n emit WhatHappened(success, returndata);\n assembly {\n switch success\n case 0 {\n revert(add(returndata, 0x20), mload(returndata))\n }\n default {\n return(add(returndata, 0x20), mload(returndata))\n }\n }\n }\n }\n\n /**\n * @notice Set whether or not to have `call` revert.\n */\n function setDoRevert(bool _doRevert) external {\n doRevert = _doRevert;\n }\n\n /**\n * @notice Set the target for the call made in `call`.\n */\n function setTarget(address _target) external {\n target = _target;\n }\n\n /**\n * @notice Set the payload for the call made in `call`.\n */\n function setPayload(bytes calldata _payload) external {\n payload = _payload;\n }\n\n /**\n * @notice Fallback function that reverts if `doRevert` is true.\n * Otherwise, it does nothing.\n */\n fallback() external {\n if (doRevert) {\n revert(\"ConfigurableCaller: revert\");\n }\n }\n}\n" - }, - "contracts/test/CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, CallerCaller } from \"./CommonTest.t.sol\";\n\n// CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2\n// CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract.\ncontract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {\n // Ensure that baseGas passes for the max value of _minGasLimit,\n // this is about 4 Billion.\n function test_baseGas_succeeds() external view {\n L1Messenger.baseGas(hex\"ff\", type(uint32).max);\n }\n\n // Fuzz for other values which might cause a revert in baseGas.\n function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view {\n L1Messenger.baseGas(hex\"ff\", _minGasLimit);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest, Portal_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable } from \"../L2/CrossDomainOwnable.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Vm, VmSafe } from \"forge-std/Vm.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract XDomainSetter is CrossDomainOwnable {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable_Test is CommonTest {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n setter = new XDomainSetter();\n }\n\n // Check that the revert message is correct\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable: caller is not the owner\");\n setter.set(1);\n }\n\n // Check that making a call can set the value properly\n function test_onlyOwner_succeeds() external {\n assertEq(setter.value(), 0);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(setter.owner()));\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n\ncontract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {\n XDomainSetter setter;\n\n function setUp() public override {\n super.setUp();\n\n vm.prank(alice);\n setter = new XDomainSetter();\n }\n\n function test_depositTransaction_crossDomainOwner_succeeds() external {\n vm.recordLogs();\n\n vm.prank(alice);\n op.depositTransaction({\n _to: address(setter),\n _value: 0,\n _gasLimit: 21_000,\n _isCreation: false,\n _data: abi.encodeWithSelector(XDomainSetter.set.selector, 1)\n });\n\n // Simulate the operation of the `op-node` by parsing data\n // from logs\n VmSafe.Log[] memory logs = vm.getRecordedLogs();\n // Only 1 log emitted\n assertEq(logs.length, 1);\n\n VmSafe.Log memory log = logs[0];\n\n // It is the expected topic\n bytes32 topic = log.topics[0];\n assertEq(topic, keccak256(\"TransactionDeposited(address,address,uint256,bytes)\"));\n\n // from is indexed and the first argument to the event.\n bytes32 _from = log.topics[1];\n address from = Bytes32AddressLib.fromLast20Bytes(_from);\n\n assertEq(AddressAliasHelper.undoL1ToL2Alias(from), alice);\n\n // Make a call from the \"from\" value received from the log.\n // In theory the opaque data could be parsed from the log\n // and passed to a low level call to \"to\", but calling set\n // directly on the setter is good enough.\n vm.prank(from);\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable2.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable2 } from \"../L2/CrossDomainOwnable2.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter2 is CrossDomainOwnable2 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable2_Test is Messenger_Initializer {\n XDomainSetter2 setter;\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter2();\n }\n\n function test_onlyOwner_notMessenger_reverts() external {\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice));\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable2: caller is not the owner\");\n setter.set(1);\n }\n\n function test_onlyOwner_notOwner2_reverts() external {\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter2.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_onlyOwner_succeeds() external {\n address owner = setter.owner();\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n owner,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter2.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/CrossDomainOwnable3.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\nimport { CommonTest, Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { CrossDomainOwnable3 } from \"../L2/CrossDomainOwnable3.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\ncontract XDomainSetter3 is CrossDomainOwnable3 {\n uint256 public value;\n\n function set(uint256 _value) external onlyOwner {\n value = _value;\n }\n}\n\ncontract CrossDomainOwnable3_Test is Messenger_Initializer {\n XDomainSetter3 setter;\n\n /**\n * @notice OpenZeppelin Ownable.sol transferOwnership event\n */\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @notice CrossDomainOwnable3.sol transferOwnership event\n */\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner,\n bool isLocal\n );\n\n function setUp() public override {\n super.setUp();\n vm.prank(alice);\n setter = new XDomainSetter3();\n }\n\n function test_constructor_succeeds() public {\n assertEq(setter.owner(), alice);\n assertEq(setter.isLocal(), true);\n }\n\n function test_localOnlyOwner_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_transferOwnership_notOwner_reverts() public {\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n }\n\n function test_crossDomainOnlyOwner_notOwner_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n // set the xDomainMsgSender storage slot\n bytes32 key = bytes32(uint256(204));\n bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob);\n vm.store(address(L2Messenger), key, value);\n\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the owner\");\n setter.set(1);\n }\n\n function test_crossDomainOnlyOwner_notOwner2_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n uint240 nonce = 0;\n address sender = bob;\n address target = address(setter);\n uint256 value = 0;\n uint256 minGasLimit = 0;\n bytes memory message = abi.encodeWithSelector(XDomainSetter3.set.selector, 1);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n // It should be a failed message. The revert is caught,\n // so we cannot expectRevert here.\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit FailedRelayedMessage(hash);\n\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(nonce, 1),\n sender,\n target,\n value,\n minGasLimit,\n message\n );\n\n assertEq(setter.value(), 0);\n }\n\n function test_crossDomainOnlyOwner_notMessenger_reverts() public {\n vm.expectEmit(true, true, true, true);\n\n // OpenZeppelin Ownable.sol transferOwnership event\n emit OwnershipTransferred(alice, alice);\n\n // CrossDomainOwnable3.sol transferOwnership event\n emit OwnershipTransferred(alice, alice, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: alice, _isLocal: false });\n\n vm.prank(bob);\n vm.expectRevert(\"CrossDomainOwnable3: caller is not the messenger\");\n setter.set(1);\n }\n\n function test_transferOwnership_zeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"CrossDomainOwnable3: new owner is the zero address\");\n setter.transferOwnership({ _owner: address(0), _isLocal: true });\n }\n\n function test_transferOwnership_noLocalZeroAddress_reverts() public {\n vm.prank(setter.owner());\n vm.expectRevert(\"Ownable: new owner is the zero address\");\n setter.transferOwnership(address(0));\n }\n\n function test_localOnlyOwner_succeeds() public {\n assertEq(setter.isLocal(), true);\n vm.prank(setter.owner());\n setter.set(1);\n assertEq(setter.value(), 1);\n }\n\n function test_localTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, true);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: true });\n\n assertEq(setter.isLocal(), true);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n /**\n * @notice The existing transferOwnership(address) method\n * still exists on the contract\n */\n function test_transferOwnershipNoLocal_succeeds() public {\n bool isLocal = setter.isLocal();\n\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n\n vm.prank(setter.owner());\n setter.transferOwnership(bob);\n\n // isLocal has not changed\n assertEq(setter.isLocal(), isLocal);\n\n vm.prank(bob);\n setter.set(2);\n assertEq(setter.value(), 2);\n }\n\n function test_crossDomainTransferOwnership_succeeds() public {\n vm.expectEmit(true, true, true, true, address(setter));\n emit OwnershipTransferred(alice, bob);\n emit OwnershipTransferred(alice, bob, false);\n\n vm.prank(setter.owner());\n setter.transferOwnership({ _owner: bob, _isLocal: false });\n\n assertEq(setter.isLocal(), false);\n\n // Simulate the L2 execution where the call is coming from\n // the L1CrossDomainMessenger\n vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(1, 1),\n bob,\n address(setter),\n 0,\n 0,\n abi.encodeWithSelector(XDomainSetter3.set.selector, 2)\n );\n\n assertEq(setter.value(), 2);\n }\n}\n" - }, - "contracts/test/DeployerWhitelist.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { DeployerWhitelist } from \"../legacy/DeployerWhitelist.sol\";\n\ncontract DeployerWhitelist_Test is CommonTest {\n DeployerWhitelist list;\n\n function setUp() public virtual override {\n list = new DeployerWhitelist();\n }\n\n // The owner should be address(0)\n function test_owner_succeeds() external {\n assertEq(list.owner(), address(0));\n }\n\n // The storage slot for the owner must be the same\n function test_storageSlots_succeeds() external {\n vm.prank(list.owner());\n list.setOwner(address(1));\n\n assertEq(bytes32(uint256(1)), vm.load(address(list), bytes32(uint256(0))));\n }\n}\n" - }, - "contracts/test/Encoding.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Encoding_Test is CommonTest {\n function testFuzz_nonceVersioning_succeeds(uint240 _nonce, uint16 _version) external {\n (uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(\n Encoding.encodeVersionedNonce(_nonce, _version)\n );\n assertEq(version, _version);\n assertEq(nonce, _nonce);\n }\n\n function testDiff_decodeVersionedNonce_succeeds(uint240 _nonce, uint16 _version) external {\n uint256 nonce = uint256(Encoding.encodeVersionedNonce(_nonce, _version));\n (uint256 decodedNonce, uint256 decodedVersion) = ffi.decodeVersionedNonce(nonce);\n\n assertEq(_version, uint16(decodedVersion));\n\n assertEq(_nonce, uint240(decodedNonce));\n }\n\n function testDiff_encodeCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint8 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint8 version = _version % 2;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory encoding = Encoding.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n bytes memory _encoding = ffi.encodeCrossDomainMessage(\n nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n\n assertEq(encoding, _encoding);\n }\n\n function testFuzz_encodeCrossDomainMessageV0_matchesLegacy_succeeds(\n uint240 _nonce,\n address _sender,\n address _target,\n bytes memory _data\n ) external {\n uint8 version = 0;\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n bytes memory legacyEncoding = LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _data,\n nonce\n );\n\n bytes memory bedrockEncoding = Encoding.encodeCrossDomainMessageV0(\n _target,\n _sender,\n _data,\n nonce\n );\n\n assertEq(legacyEncoding, bedrockEncoding);\n }\n\n function testDiff_encodeDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bool isCreate,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n Types.UserDepositTransaction memory t = Types.UserDepositTransaction(\n _from,\n _to,\n isCreate,\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n );\n\n bytes memory txn = Encoding.encodeDepositTransaction(t);\n bytes memory _txn = ffi.encodeDepositTransaction(t);\n\n assertEq(txn, _txn);\n }\n}\n" - }, - "contracts/test/FeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { L1FeeVault } from \"../L2/L1FeeVault.sol\";\nimport { BaseFeeVault } from \"../L2/BaseFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n// Test the implementations of the FeeVault\ncontract FeeVault_Test is Bridge_Initializer {\n BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));\n L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT));\n\n address constant recipient = address(0x10000);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.BASE_FEE_VAULT, address(new BaseFeeVault(recipient)).code);\n vm.etch(Predeploys.L1_FEE_VAULT, address(new L1FeeVault(recipient)).code);\n\n vm.label(Predeploys.BASE_FEE_VAULT, \"BaseFeeVault\");\n vm.label(Predeploys.L1_FEE_VAULT, \"L1FeeVault\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(baseFeeVault.RECIPIENT(), recipient);\n assertEq(l1FeeVault.RECIPIENT(), recipient);\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n}\n" - }, - "contracts/test/GasPriceOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GasPriceOracle } from \"../L2/GasPriceOracle.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract GasPriceOracle_Test is CommonTest {\n event OverheadUpdated(uint256);\n event ScalarUpdated(uint256);\n event DecimalsUpdated(uint256);\n\n GasPriceOracle gasOracle;\n L1Block l1Block;\n address depositor;\n\n // set the initial L1 context values\n uint64 constant number = 10;\n uint64 constant timestamp = 11;\n uint256 constant basefee = 100;\n bytes32 constant hash = bytes32(uint256(64));\n uint64 constant sequenceNumber = 0;\n bytes32 constant batcherHash = bytes32(uint256(777));\n uint256 constant l1FeeOverhead = 310;\n uint256 constant l1FeeScalar = 10;\n\n function setUp() public virtual override {\n super.setUp();\n // place the L1Block contract at the predeploy address\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n\n l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n depositor = l1Block.DEPOSITOR_ACCOUNT();\n\n // We are not setting the gas oracle at its predeploy\n // address for simplicity purposes. Nothing in this test\n // requires it to be at a particular address\n gasOracle = new GasPriceOracle();\n\n vm.prank(depositor);\n l1Block.setL1BlockValues({\n _number: number,\n _timestamp: timestamp,\n _basefee: basefee,\n _hash: hash,\n _sequenceNumber: sequenceNumber,\n _batcherHash: batcherHash,\n _l1FeeOverhead: l1FeeOverhead,\n _l1FeeScalar: l1FeeScalar\n });\n }\n\n function test_l1BaseFee_succeeds() external {\n assertEq(gasOracle.l1BaseFee(), basefee);\n }\n\n function test_gasPrice_succeeds() external {\n vm.fee(100);\n uint256 gasPrice = gasOracle.gasPrice();\n assertEq(gasPrice, 100);\n }\n\n function test_baseFee_succeeds() external {\n vm.fee(64);\n uint256 gasPrice = gasOracle.baseFee();\n assertEq(gasPrice, 64);\n }\n\n function test_scalar_succeeds() external {\n assertEq(gasOracle.scalar(), l1FeeScalar);\n }\n\n function test_overhead_succeeds() external {\n assertEq(gasOracle.overhead(), l1FeeOverhead);\n }\n\n function test_decimals_succeeds() external {\n assertEq(gasOracle.decimals(), 6);\n assertEq(gasOracle.DECIMALS(), 6);\n }\n\n // Removed in bedrock\n function test_setGasPrice_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setGasPrice(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n\n // Removed in bedrock\n function test_setL1BaseFee_doesNotExist_reverts() external {\n (bool success, bytes memory returndata) = address(gasOracle).call(\n abi.encodeWithSignature(\"setL1BaseFee(uint256)\", 1)\n );\n\n assertEq(success, false);\n assertEq(returndata, hex\"\");\n }\n}\n" - }, - "contracts/test/GovernanceToken.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract GovernanceToken_Test is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n\n function setUp() public virtual override {\n super.setUp();\n vm.prank(owner);\n gov = new GovernanceToken();\n }\n\n function test_constructor_succeeds() external {\n assertEq(gov.owner(), owner);\n assertEq(gov.name(), \"Optimism\");\n assertEq(gov.symbol(), \"OP\");\n assertEq(gov.decimals(), 18);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_mint_fromOwner_succeeds() external {\n // Mint 100 tokens.\n vm.prank(owner);\n gov.mint(owner, 100);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 100);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_mint_fromNotOwner_reverts() external {\n // Mint 100 tokens as rando.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n gov.mint(owner, 100);\n\n // Balance does not update.\n assertEq(gov.balanceOf(owner), 0);\n assertEq(gov.totalSupply(), 0);\n }\n\n function test_burn_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando burns their tokens.\n vm.prank(rando);\n gov.burn(50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_burnFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to burn 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner burns 50 tokens from rando.\n vm.prank(owner);\n gov.burnFrom(rando, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 50);\n }\n\n function test_transfer_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando transfers 50 tokens to owner.\n vm.prank(rando);\n gov.transfer(owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_approve_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n\n function test_transferFrom_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Owner transfers 50 tokens from rando to owner.\n vm.prank(owner);\n gov.transferFrom(rando, owner, 50);\n\n // Balances have updated correctly.\n assertEq(gov.balanceOf(owner), 50);\n assertEq(gov.balanceOf(rando), 50);\n assertEq(gov.totalSupply(), 100);\n }\n\n function test_increaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 50 tokens.\n vm.prank(rando);\n gov.approve(owner, 50);\n\n // Rando increases allowance by 50 tokens.\n vm.prank(rando);\n gov.increaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 100);\n }\n\n function test_decreaseAllowance_succeeds() external {\n // Mint 100 tokens to rando.\n vm.prank(owner);\n gov.mint(rando, 100);\n\n // Rando approves owner to spend 100 tokens.\n vm.prank(rando);\n gov.approve(owner, 100);\n\n // Rando decreases allowance by 50 tokens.\n vm.prank(rando);\n gov.decreaseAllowance(owner, 50);\n\n // Allowances have updated.\n assertEq(gov.allowance(rando, owner), 50);\n }\n}\n" - }, - "contracts/test/Hashing.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { LegacyCrossDomainUtils } from \"../libraries/LegacyCrossDomainUtils.sol\";\n\ncontract Hashing_hashDepositSource_Test is CommonTest {\n /**\n * @notice Tests that hashDepositSource returns the correct hash in a simple case.\n */\n function test_hashDepositSource_succeeds() external {\n assertEq(\n Hashing.hashDepositSource(\n 0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,\n 0x1\n ),\n 0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc\n );\n }\n}\n\ncontract Hashing_hashCrossDomainMessage_Test is CommonTest {\n /**\n * @notice Tests that hashCrossDomainMessage returns the correct hash in a simple case.\n */\n function testDiff_hashCrossDomainMessage_succeeds(\n uint240 _nonce,\n uint16 _version,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Ensure the version is valid.\n uint16 version = uint16(bound(uint256(_version), 0, 1));\n uint256 nonce = Encoding.encodeVersionedNonce(_nonce, version);\n\n assertEq(\n Hashing.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data),\n ffi.hashCrossDomainMessage(nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n\n /**\n * @notice Tests that hashCrossDomainMessageV0 matches the hash of the legacy encoding.\n */\n function testFuzz_hashCrossDomainMessageV0_matchesLegacy_succeeds(\n address _target,\n address _sender,\n bytes memory _message,\n uint256 _messageNonce\n ) external {\n assertEq(\n keccak256(\n LegacyCrossDomainUtils.encodeXDomainCalldata(\n _target,\n _sender,\n _message,\n _messageNonce\n )\n ),\n Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _messageNonce)\n );\n }\n}\n\ncontract Hashing_hashWithdrawal_Test is CommonTest {\n /**\n * @notice Tests that hashWithdrawal returns the correct hash in a simple case.\n */\n function testDiff_hashWithdrawal_succeeds(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n assertEq(\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(_nonce, _sender, _target, _value, _gasLimit, _data)\n ),\n ffi.hashWithdrawal(_nonce, _sender, _target, _value, _gasLimit, _data)\n );\n }\n}\n\ncontract Hashing_hashOutputRootProof_Test is CommonTest {\n /**\n * @notice Tests that hashOutputRootProof returns the correct hash in a simple case.\n */\n function testDiff_hashOutputRootProof_succeeds(\n bytes32 _version,\n bytes32 _stateRoot,\n bytes32 _messagePasserStorageRoot,\n bytes32 _latestBlockhash\n ) external {\n assertEq(\n Hashing.hashOutputRootProof(\n Types.OutputRootProof({\n version: _version,\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _messagePasserStorageRoot,\n latestBlockhash: _latestBlockhash\n })\n ),\n ffi.hashOutputRootProof(\n _version,\n _stateRoot,\n _messagePasserStorageRoot,\n _latestBlockhash\n )\n );\n }\n}\n\ncontract Hashing_hashDepositTransaction_Test is CommonTest {\n /**\n * @notice Tests that hashDepositTransaction returns the correct hash in a simple case.\n */\n function testDiff_hashDepositTransaction_succeeds(\n address _from,\n address _to,\n uint256 _mint,\n uint256 _value,\n uint64 _gas,\n bytes memory _data,\n uint64 _logIndex\n ) external {\n assertEq(\n Hashing.hashDepositTransaction(\n Types.UserDepositTransaction(\n _from,\n _to,\n false, // isCreate\n _value,\n _mint,\n _gas,\n _data,\n bytes32(uint256(0)),\n _logIndex\n )\n ),\n ffi.hashDepositTransaction(_from, _to, _mint, _value, _gas, _data, _logIndex)\n );\n }\n}\n" - }, - "contracts/test/L1Block.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\n\ncontract L1BlockTest is CommonTest {\n L1Block lb;\n address depositor;\n bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));\n\n function setUp() public virtual override {\n super.setUp();\n lb = new L1Block();\n depositor = lb.DEPOSITOR_ACCOUNT();\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: uint64(1),\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: NON_ZERO_HASH,\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(0),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function testFuzz_updatesValues_succeeds(\n uint64 n,\n uint64 t,\n uint256 b,\n bytes32 h,\n uint64 s,\n bytes32 bt,\n uint256 fo,\n uint256 fs\n ) external {\n vm.prank(depositor);\n lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs);\n assertEq(lb.number(), n);\n assertEq(lb.timestamp(), t);\n assertEq(lb.basefee(), b);\n assertEq(lb.hash(), h);\n assertEq(lb.sequenceNumber(), s);\n assertEq(lb.batcherHash(), bt);\n assertEq(lb.l1FeeOverhead(), fo);\n assertEq(lb.l1FeeScalar(), fs);\n }\n\n function test_number_succeeds() external {\n assertEq(lb.number(), uint64(1));\n }\n\n function test_timestamp_succeeds() external {\n assertEq(lb.timestamp(), uint64(2));\n }\n\n function test_basefee_succeeds() external {\n assertEq(lb.basefee(), 3);\n }\n\n function test_hash_succeeds() external {\n assertEq(lb.hash(), NON_ZERO_HASH);\n }\n\n function test_sequenceNumber_succeeds() external {\n assertEq(lb.sequenceNumber(), uint64(4));\n }\n\n function test_updateValues_succeeds() external {\n vm.prank(depositor);\n lb.setL1BlockValues({\n _number: type(uint64).max,\n _timestamp: type(uint64).max,\n _basefee: type(uint256).max,\n _hash: keccak256(abi.encode(1)),\n _sequenceNumber: type(uint64).max,\n _batcherHash: bytes32(type(uint256).max),\n _l1FeeOverhead: type(uint256).max,\n _l1FeeScalar: type(uint256).max\n });\n }\n}\n" - }, - "contracts/test/L1BlockNumber.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { L1Block } from \"../L2/L1Block.sol\";\nimport { L1BlockNumber } from \"../legacy/L1BlockNumber.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract L1BlockNumberTest is Test {\n L1Block lb;\n L1BlockNumber bn;\n\n uint64 constant number = 99;\n\n function setUp() external {\n vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);\n lb = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);\n bn = new L1BlockNumber();\n vm.prank(lb.DEPOSITOR_ACCOUNT());\n\n lb.setL1BlockValues({\n _number: number,\n _timestamp: uint64(2),\n _basefee: 3,\n _hash: bytes32(uint256(10)),\n _sequenceNumber: uint64(4),\n _batcherHash: bytes32(uint256(0)),\n _l1FeeOverhead: 2,\n _l1FeeScalar: 3\n });\n }\n\n function test_getL1BlockNumber_succeeds() external {\n assertEq(bn.getL1BlockNumber(), number);\n }\n\n function test_fallback_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n\n function test_receive_succeeds() external {\n (bool success, bytes memory ret) = address(bn).call{ value: 1 }(hex\"\");\n assertEq(success, true);\n assertEq(ret, abi.encode(number));\n }\n}\n" - }, - "contracts/test/L1CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Testing utilities */\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle_Initializer } from \"./L2OutputOracle.t.sol\";\n\n/* Libraries */\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n/* Target contract dependencies */\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\n\n/* Target contract */\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\n\ncontract L1CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n // the version is encoded in the nonce\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce());\n assertEq(version, L1Messenger.MESSAGE_VERSION());\n }\n\n // sendMessage: should be able to send a single message\n // TODO: this same test needs to be done with the legacy message type\n // by setting the message version to 0\n function test_sendMessage_succeeds() external {\n // deposit transaction on the optimism portal should be called\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n )\n );\n\n // TransactionDeposited event\n vm.expectEmit(true, true, true, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),\n Predeploys.L2_CROSS_DOMAIN_MESSENGER,\n 0,\n 0,\n L1Messenger.baseGas(hex\"ff\", 100),\n false,\n Encoding.encodeCrossDomainMessage(\n L1Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n )\n );\n\n // SentMessage event\n vm.expectEmit(true, true, true, true);\n emit SentMessage(recipient, alice, hex\"ff\", L1Messenger.messageNonce(), 100);\n\n // SentMessageExtension1 event\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(alice, 0);\n\n vm.prank(alice);\n L1Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n // sendMessage: should be able to send the same message twice\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L1Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L1Messenger.messageNonce());\n }\n\n function test_xDomainSender_notSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // xDomainMessageSender: should return the xDomainMsgSender address\n // TODO: might need a test contract\n // function test_xDomainSenderSetCorrectly() external {}\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(address(op));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n // relayMessage: should send a successful call to the target contract\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.expectCall(target, hex\"1111\");\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n // set the target to be the OptimismPortal\n address target = address(op);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.prank(address(op));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n\n vm.store(address(op), 0, bytes32(abi.encode(sender)));\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: should revert if eth is sent from a contract other than the standard bridge\n function test_replayMessage_withValue_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory message = hex\"1111\";\n\n vm.expectRevert(\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n L1Messenger.relayMessage{ value: 100 }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L1Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n vm.expectCall(target, hex\"1111\");\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n // relayMessage: Should revert if the recipient is trying to reenter with the\n // same message.\n function test_relayMessage_reentrancySameMessage_reverts() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory callMessage = abi.encodeWithSelector(caller.call.selector);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Set the portal's `l2Sender` to the `sender`.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(uint256(uint160(sender))));\n\n // Act as the portal and call the `relayMessage` function with the `innerMessage`.\n vm.prank(address(op));\n vm.expectCall(target, callMessage);\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message failed to be relayed\n assertFalse(L1Messenger.successfulMessages(hash));\n assertTrue(L1Messenger.failedMessages(hash));\n\n // Set the configurable caller's target to `L1Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L1Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L1Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n callMessage\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with the same message hash. The reentrancy attempt should\n // revert.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(\n false,\n abi.encodeWithSignature(\"Error(string)\", \"ReentrancyGuard: reentrant call\")\n );\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message still failed to be relayed.\n assertFalse(L1Messenger.successfulMessages(hash));\n assertTrue(L1Messenger.failedMessages(hash));\n }\n\n // relayMessage: should not revert if the recipient reenters `relayMessage` with a different\n // message hash.\n function test_relayMessage_reentrancyDiffMessage_succeeds() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n bytes memory messageA = abi.encodeWithSelector(caller.call.selector);\n bytes memory messageB = hex\"\";\n\n bytes32 hashA = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n bytes32 hashB = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Set the portal's `l2Sender` to the `sender`.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(uint256(uint160(sender))));\n\n // Act as the portal and call the `relayMessage` function with both `messageA` and `messageB`.\n vm.startPrank(address(op));\n\n vm.expectCall(target, messageA);\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n vm.expectCall(target, messageB);\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Stop acting as the portal\n vm.stopPrank();\n\n // Assert that both messages failed to be relayed\n assertFalse(L1Messenger.successfulMessages(hashA));\n assertFalse(L1Messenger.successfulMessages(hashB));\n assertTrue(L1Messenger.failedMessages(hashA));\n assertTrue(L1Messenger.failedMessages(hashB));\n\n // Set the configurable caller's target to `L1Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L1Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L1Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageB\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with messageB. The reentrancy attempt should succeed\n // because the message hashes are different.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(true, hex\"\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n\n // Assert that both messages are now in the `successfulMessages` mapping.\n assertTrue(L1Messenger.successfulMessages(hashA));\n assertTrue(L1Messenger.successfulMessages(hashB));\n }\n\n function test_relayMessage_legacy_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyOldReplay_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Mark legacy message as already relayed.\n uint256 successfulMessagesSlot = 203;\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex\"1111\", 0);\n bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot));\n vm.store(address(L1Messenger), slot, bytes32(uint256(1)));\n\n // Expect revert.\n vm.expectRevert(\"CrossDomainMessenger: legacy withdrawal already relayed\");\n\n // Relay the message.\n vm.prank(address(op));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // Message was not relayed.\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), false);\n }\n\n function test_relayMessage_legacyRetryAfterFailure_succeeds() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect FailedRelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit FailedRelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n }\n\n function test_relayMessage_legacyRetryAfterSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), false);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n\n // Retry the message.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external {\n address target = address(0xabcd);\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n uint256 value = 100;\n\n // Compute the message hash.\n bytes32 hash = Hashing.hashCrossDomainMessageV1(\n // Using a legacy nonce with version 0.\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Turn the target into a Reverter.\n vm.etch(target, address(new Reverter()).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Relay the message.\n vm.deal(address(op), value);\n vm.prank(address(op));\n L1Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message failed.\n assertEq(address(L1Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L1Messenger.successfulMessages(hash), false);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Make the target not revert anymore.\n vm.etch(target, address(0).code);\n\n // Target should be called with expected data.\n vm.expectCall(target, hex\"1111\");\n\n // Expect RelayedMessage event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit RelayedMessage(hash);\n\n // Retry the message\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n // Message was successfully relayed.\n assertEq(address(L1Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L1Messenger.successfulMessages(hash), true);\n assertEq(L1Messenger.failedMessages(hash), true);\n\n // Expect a revert.\n vm.expectRevert(\"CrossDomainMessenger: message has already been relayed\");\n\n // Retry the message again.\n vm.prank(address(sender));\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n }\n}\n" - }, - "contracts/test/L1ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L1ERC721Bridge_Test is Messenger_Initializer {\n TestERC721 internal localToken;\n TestERC721 internal remoteToken;\n L1ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L1ERC721Bridge(address(L1Messenger), otherBridge);\n localToken = new TestERC721();\n remoteToken = new TestERC721();\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L1ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L1Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L1Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L1Messenger),\n abi.encodeCall(\n L1Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), true);\n assertEq(localToken.ownerOf(tokenId), address(bridge));\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L1ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"ERC721: transfer from incorrect owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(bridge.deposits(address(localToken), address(remoteToken), tokenId), false);\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notEscrowed_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L1Messenger),\n abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L1Messenger));\n vm.expectRevert(\"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n" - }, - "contracts/test/L1StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\n\ncontract L1StandardBridge_Getter_Test is Bridge_Initializer {\n function test_getters_succeeds() external {\n assert(L1Bridge.l2TokenBridge() == address(L2Bridge));\n assert(L1Bridge.OTHER_BRIDGE() == L2Bridge);\n assert(L1Bridge.messenger() == L1Messenger);\n assert(L1Bridge.MESSENGER() == L1Messenger);\n assertEq(L1Bridge.version(), \"1.1.0\");\n }\n}\n\ncontract L1StandardBridge_Initialize_Test is Bridge_Initializer {\n function test_initialize_succeeds() external {\n assertEq(address(L1Bridge.messenger()), address(L1Messenger));\n\n assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE);\n\n assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE);\n }\n}\n\ncontract L1StandardBridge_Initialize_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_Receive_Test is Bridge_Initializer {\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(op).balance, 0);\n\n // The legacy event must be emitted for backwards compatibility\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n ),\n 200_000\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L1Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(op).balance, 100);\n }\n}\n\ncontract L1StandardBridge_Receive_TestFail {}\n\ncontract PreBridgeETH is Bridge_Initializer {\n function _preBridgeETH(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 500,\n hex\"dead\"\n );\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 500,\n abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex\"dead\")\n );\n }\n vm.expectCall(\n address(L1Messenger),\n 500,\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 50000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 500,\n 50000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 50000);\n vm.expectCall(\n address(op),\n 500,\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 500,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(500),\n uint256(500),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, alice, 500, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, alice, 500, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 50000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 500);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETH_Test is PreBridgeETH {\n // depositETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_depositETH_succeeds() external {\n _preBridgeETH({ isLegacy: true });\n L1Bridge.depositETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_BridgeETH_Test is PreBridgeETH {\n // BridgeETH\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETH_succeeds() external {\n _preBridgeETH({ isLegacy: false });\n L1Bridge.bridgeETH{ value: 500 }(50000, hex\"dead\");\n assertEq(address(op).balance, 500);\n }\n}\n\ncontract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer {\n function test_depositETH_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, address(L1Token).code);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice);\n L1Bridge.depositETH{ value: 1 }(300, hex\"\");\n }\n}\n\ncontract PreBridgeETHTo is Bridge_Initializer {\n function _preBridgeETHTo(bool isLegacy) internal {\n assertEq(address(op).balance, 0);\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n if (isLegacy) {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex\"dead\")\n );\n } else {\n vm.expectCall(\n address(L1Bridge),\n 600,\n abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex\"dead\")\n );\n }\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n bob,\n 600,\n hex\"dead\"\n );\n\n // the L1 bridge should call\n // L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 60000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 600,\n 60000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 60000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 600,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(600),\n uint256(600),\n baseGas,\n false,\n innerMessage\n );\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHDepositInitiated(alice, bob, 600, hex\"dead\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeInitiated(alice, bob, 600, hex\"dead\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 60000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 600);\n\n // deposit eth to bob\n vm.prank(alice, alice);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo {\n // depositETHTo\n // - emits ETHDepositInitiated\n // - calls optimismPortal.depositTransaction\n // - EOA or contract can call\n // - ETH ends up in the optimismPortal\n function test_depositETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: true });\n L1Bridge.depositETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo {\n // BridgeETHTo\n // - emits ETHDepositInitiated\n // - emits ETHBridgeInitiated\n // - calls optimismPortal.depositTransaction\n // - only EOA\n // - ETH ends up in the optimismPortal\n function test_bridgeETHTo_succeeds() external {\n _preBridgeETHTo({ isLegacy: false });\n L1Bridge.bridgeETHTo{ value: 600 }(bob, 60000, hex\"dead\");\n assertEq(address(op).balance, 600);\n }\n}\n\ncontract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // depositERC20\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - only callable by EOA\n function test_depositERC20_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Deal Alice's ERC20 State\n deal(address(L1Token), alice, 100000, true);\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n // The L1Bridge should transfer alice's tokens to itself\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100)\n );\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n vm.prank(alice);\n L1Bridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex\"\");\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n }\n}\n\ncontract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer {\n function test_depositERC20_notEoa_reverts() external {\n // turn alice into a contract\n vm.etch(alice, hex\"ffff\");\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n vm.prank(alice, alice);\n L1Bridge.depositERC20(address(0), address(0), 100, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {\n // depositERC20To\n // - updates bridge.deposits\n // - emits ERC20DepositInitiated\n // - calls optimismPortal.depositTransaction\n // - callable by a contract\n function test_depositERC20To_succeeds() external {\n uint256 nonce = L1Messenger.messageNonce();\n uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION\n address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L2Token),\n address(L1Token),\n alice,\n bob,\n 1000,\n hex\"\"\n );\n\n // the L1 bridge should call L1CrossDomainMessenger.sendMessage\n vm.expectCall(\n address(L1Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L2Bridge),\n message,\n 10000\n )\n );\n\n bytes memory innerMessage = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L1Bridge),\n address(L2Bridge),\n 0,\n 10000,\n message\n );\n\n uint64 baseGas = L1Messenger.baseGas(message, 10000);\n vm.expectCall(\n address(op),\n abi.encodeWithSelector(\n OptimismPortal.depositTransaction.selector,\n address(L2Messenger),\n 0,\n baseGas,\n false,\n innerMessage\n )\n );\n\n bytes memory opaqueData = abi.encodePacked(\n uint256(0),\n uint256(0),\n baseGas,\n false,\n innerMessage\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex\"\");\n\n // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call\n vm.expectEmit(true, true, true, true, address(op));\n emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData);\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L1Messenger));\n emit SentMessageExtension1(address(L1Bridge), 0);\n\n deal(address(L1Token), alice, 100000, true);\n\n vm.prank(alice);\n L1Token.approve(address(L1Bridge), type(uint256).max);\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000)\n );\n\n vm.prank(alice);\n L1Bridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex\"\");\n\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 1000);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeETHWithdrawal\n // - emits ETHWithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeETHWithdrawal_succeeds() external {\n uint256 aliceBalance = alice.balance;\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHWithdrawalFinalized(alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n vm.expectCall(alice, hex\"\");\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n // ensure that the messenger has ETH to call with\n vm.deal(address(L1Bridge.messenger()), 100);\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex\"\");\n\n assertEq(address(L1Bridge.messenger()).balance, 0);\n assertEq(aliceBalance + 100, alice.balance);\n }\n}\n\ncontract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer {}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n // finalizeERC20Withdrawal\n // - updates bridge.deposits\n // - emits ERC20WithdrawalFinalized\n // - only callable by L2 bridge\n function test_finalizeERC20Withdrawal_succeeds() external {\n deal(address(L1Token), address(L1Bridge), 100, true);\n\n uint256 slot = stdstore\n .target(address(L1Bridge))\n .sig(\"deposits(address,address)\")\n .with_key(address(L1Token))\n .with_key(address(L2Token))\n .find();\n\n // Give the L1 bridge some ERC20 tokens\n vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));\n assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectCall(\n address(L1Token),\n abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)\n );\n\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(L1Bridge.messenger()));\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n assertEq(L1Token.balanceOf(address(L1Bridge)), 0);\n assertEq(L1Token.balanceOf(address(alice)), 100);\n }\n}\n\ncontract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer {\n function test_finalizeERC20Withdrawal_notMessenger_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.prank(address(28));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n\n function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external {\n vm.mockCall(\n address(L1Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(address(0)))\n );\n vm.prank(address(L1Bridge.messenger()));\n vm.expectRevert(\"StandardBridge: function can only be called from the other bridge\");\n L1Bridge.finalizeERC20Withdrawal(\n address(L1Token),\n address(L2Token),\n alice,\n alice,\n 100,\n hex\"\"\n );\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true, address(L1Bridge));\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n\ncontract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer {\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L1Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L1Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n address messenger = address(L1Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L1Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L1Bridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2CrossDomainMessenger.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Messenger_Initializer, Reverter, ConfigurableCaller } from \"./CommonTest.t.sol\";\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { L2CrossDomainMessenger } from \"../L2/L2CrossDomainMessenger.sol\";\nimport { L1CrossDomainMessenger } from \"../L1/L1CrossDomainMessenger.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2CrossDomainMessenger_Test is Messenger_Initializer {\n // Receiver address for testing\n address recipient = address(0xabbaacdc);\n\n function test_messageVersion_succeeds() external {\n (, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce());\n assertEq(version, L2Messenger.MESSAGE_VERSION());\n }\n\n function test_sendMessage_succeeds() external {\n bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage(\n L2Messenger.messageNonce(),\n alice,\n recipient,\n 0,\n 100,\n hex\"ff\"\n );\n vm.expectCall(\n address(messagePasser),\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData\n )\n );\n\n // MessagePassed event\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(L2Messenger),\n address(L1Messenger),\n 0,\n L2Messenger.baseGas(hex\"ff\", 100),\n xDomainCallData,\n Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messagePasser.messageNonce(),\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: L2Messenger.baseGas(hex\"ff\", 100),\n data: xDomainCallData\n })\n )\n );\n\n vm.prank(alice);\n L2Messenger.sendMessage(recipient, hex\"ff\", uint32(100));\n }\n\n function test_sendMessage_twice_succeeds() external {\n uint256 nonce = L2Messenger.messageNonce();\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n L2Messenger.sendMessage(recipient, hex\"aa\", uint32(500_000));\n // the nonce increments for each message sent\n assertEq(nonce + 2, L2Messenger.messageNonce());\n }\n\n function test_xDomainSender_senderNotSet_reverts() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n function test_relayMessage_v2_reverts() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n // Expect a revert.\n vm.expectRevert(\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // Try to relay a v2 message.\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 2), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n }\n\n function test_relayMessage_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n vm.expectCall(target, hex\"1111\");\n\n vm.prank(caller);\n\n vm.expectEmit(true, true, true, true);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n hex\"1111\"\n );\n\n emit RelayedMessage(hash);\n\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n 0, // value\n 0,\n hex\"1111\"\n );\n\n // the message hash is in the successfulMessages mapping\n assert(L2Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertEq(L2Messenger.failedMessages(hash), false);\n }\n\n // relayMessage: should revert if attempting to relay a message sent to an L1 system contract\n function test_relayMessage_toSystemContract_reverts() external {\n address target = address(messagePasser);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory message = hex\"1111\";\n\n vm.prank(caller);\n vm.expectRevert(\"CrossDomainMessenger: message cannot be replayed\");\n L1Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n message\n );\n }\n\n // relayMessage: the xDomainMessageSender is reset to the original value\n function test_xDomainMessageSender_reset_succeeds() external {\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n vm.prank(caller);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n address(0),\n address(0),\n 0,\n 0,\n hex\"\"\n );\n\n vm.expectRevert(\"CrossDomainMessenger: xDomainMessageSender is not set\");\n L2Messenger.xDomainMessageSender();\n }\n\n // relayMessage: should send a successful call to the target contract after the first message\n // fails and ETH gets stuck, but the second message succeeds\n function test_relayMessage_retry_succeeds() external {\n address target = address(0xabcd);\n address sender = address(L1Messenger);\n address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n uint256 value = 100;\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n vm.etch(target, address(new Reverter()).code);\n vm.deal(address(caller), value);\n vm.prank(caller);\n L2Messenger.relayMessage{ value: value }(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, value);\n assertEq(address(target).balance, 0);\n assertEq(L2Messenger.successfulMessages(hash), false);\n assertEq(L2Messenger.failedMessages(hash), true);\n\n vm.expectEmit(true, true, true, true);\n\n emit RelayedMessage(hash);\n\n vm.etch(target, address(0).code);\n vm.prank(address(sender));\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1), // nonce\n sender,\n target,\n value,\n 0,\n hex\"1111\"\n );\n\n assertEq(address(L2Messenger).balance, 0);\n assertEq(address(target).balance, value);\n assertEq(L2Messenger.successfulMessages(hash), true);\n assertEq(L2Messenger.failedMessages(hash), true);\n }\n\n // relayMessage: Should revert if the recipient is trying to reenter with the\n // same message.\n function test_relayMessage_reentrancySameMessage_reverts() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = address(L1Messenger);\n address l1XDMAlias = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n bytes memory callMessage = abi.encodeWithSelector(caller.call.selector);\n\n bytes32 hash = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Act as the L1XDM and call the `relayMessage` function with the `innerMessage`.\n vm.prank(l1XDMAlias);\n vm.expectCall(target, callMessage);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message failed to be relayed\n assertFalse(L2Messenger.successfulMessages(hash));\n assertTrue(L2Messenger.failedMessages(hash));\n\n // Set the configurable caller's target to `L2Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L2Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L2Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with the same message hash. The reentrancy attempt should\n // revert.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(\n false,\n abi.encodeWithSignature(\"Error(string)\", \"ReentrancyGuard: reentrant call\")\n );\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n callMessage\n );\n\n // Assert that the message still failed to be relayed.\n assertFalse(L2Messenger.successfulMessages(hash));\n assertTrue(L2Messenger.failedMessages(hash));\n }\n\n // relayMessage: should not revert if the recipient reenters `relayMessage` with a different\n // message hash.\n function test_relayMessage_reentrancyDiffMessage_succeeds() external {\n ConfigurableCaller caller = new ConfigurableCaller();\n address target = address(caller);\n address sender = address(L1Messenger);\n address l1XDMAlias = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));\n\n bytes memory messageA = abi.encodeWithSelector(caller.call.selector);\n bytes memory messageB = hex\"\";\n\n bytes32 hashA = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n bytes32 hashB = Hashing.hashCrossDomainMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Act as the L1XDM and call the `relayMessage` function with both `messageA` and `messageB`.\n vm.startPrank(l1XDMAlias);\n\n vm.expectCall(target, messageA);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n vm.expectCall(target, messageB);\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageB\n );\n\n // Stop acting as the L1XDM\n vm.stopPrank();\n\n // Assert that both messages failed to be relayed\n assertFalse(L2Messenger.successfulMessages(hashA));\n assertFalse(L2Messenger.successfulMessages(hashB));\n assertTrue(L2Messenger.failedMessages(hashA));\n assertTrue(L2Messenger.failedMessages(hashB));\n\n // Set the configurable caller's target to `L2Messenger` and set the payload to `relayMessage(...)`.\n caller.setDoRevert(false);\n caller.setTarget(address(L2Messenger));\n caller.setPayload(\n abi.encodeWithSelector(\n L2Messenger.relayMessage.selector,\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageB\n )\n );\n\n // Attempt to replay the failed message, which will *not* immediately revert this time around,\n // but attempt to reenter `relayMessage` with messageB. The reentrancy attempt should succeed\n // because the message hashes are different.\n vm.expectEmit(true, true, true, true, target);\n emit WhatHappened(true, hex\"\");\n L2Messenger.relayMessage(\n Encoding.encodeVersionedNonce(0, 1),\n sender,\n target,\n 0,\n 0,\n messageA\n );\n\n // Assert that both messages are now in the `successfulMessages` mapping.\n assertTrue(L2Messenger.successfulMessages(hashA));\n assertTrue(L2Messenger.successfulMessages(hashB));\n }\n}\n" - }, - "contracts/test/L2ERC721Bridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { Messenger_Initializer } from \"./CommonTest.t.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"Test\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract TestMintableERC721 is OptimismMintableERC721 {\n constructor(address _bridge, address _remoteToken)\n OptimismMintableERC721(_bridge, 1, _remoteToken, \"Test\", \"TST\")\n {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n}\n\ncontract L2ERC721Bridge_Test is Messenger_Initializer {\n TestMintableERC721 internal localToken;\n TestERC721 internal remoteToken;\n L2ERC721Bridge internal bridge;\n address internal constant otherBridge = address(0x3456);\n uint256 internal constant tokenId = 1;\n\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n function setUp() public override {\n super.setUp();\n\n // Create necessary contracts.\n bridge = new L2ERC721Bridge(address(L2Messenger), otherBridge);\n remoteToken = new TestERC721();\n localToken = new TestMintableERC721(address(bridge), address(remoteToken));\n\n // Label the bridge so we get nice traces.\n vm.label(address(bridge), \"L2ERC721Bridge\");\n\n // Mint alice a token.\n localToken.mint(alice, tokenId);\n\n // Approve the bridge to transfer the token.\n vm.prank(alice);\n localToken.approve(address(bridge), tokenId);\n }\n\n function test_constructor_succeeds() public {\n assertEq(address(bridge.MESSENGER()), address(L2Messenger));\n assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);\n assertEq(address(bridge.messenger()), address(L2Messenger));\n assertEq(address(bridge.otherBridge()), otherBridge);\n }\n\n function test_bridgeERC721_succeeds() public {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L2ERC721Bridge.finalizeBridgeERC721,\n (\n address(remoteToken),\n address(localToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n )\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721_fromContract_reverts() external {\n // Bridge the token.\n vm.etch(alice, hex\"01\");\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: account is not externally owned\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_succeeds() external {\n // Expect a call to the messenger.\n vm.expectCall(\n address(L2Messenger),\n abi.encodeCall(\n L2Messenger.sendMessage,\n (\n address(otherBridge),\n abi.encodeCall(\n L1ERC721Bridge.finalizeBridgeERC721,\n (address(remoteToken), address(localToken), alice, bob, tokenId, hex\"5678\")\n ),\n 1234\n )\n )\n );\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeInitiated(\n address(localToken),\n address(remoteToken),\n alice,\n bob,\n tokenId,\n hex\"5678\"\n );\n\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is burned.\n vm.expectRevert(\"ERC721: invalid token ID\");\n localToken.ownerOf(tokenId);\n }\n\n function test_bridgeERC721To_localTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert();\n bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {\n // Bridge the token.\n vm.prank(alice);\n vm.expectRevert(\"L2ERC721Bridge: remote token cannot be address(0)\");\n bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex\"5678\");\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_bridgeERC721To_wrongOwner_reverts() external {\n // Bridge the token.\n vm.prank(bob);\n vm.expectRevert(\"L2ERC721Bridge: Withdrawal is not being initiated by NFT owner\");\n bridge.bridgeERC721To(\n address(localToken),\n address(remoteToken),\n bob,\n tokenId,\n 1234,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_succeeds() external {\n // Bridge the token.\n vm.prank(alice);\n bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex\"5678\");\n\n // Expect an event to be emitted.\n vm.expectEmit(true, true, true, true);\n emit ERC721BridgeFinalized(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n\n // Token is not locked in the bridge.\n assertEq(localToken.ownerOf(tokenId), alice);\n }\n\n function test_finalizeBridgeERC721_interfaceNotCompliant_reverts() external {\n // Create a non-compliant token\n NonCompliantERC721 nonCompliantToken = new NonCompliantERC721(alice);\n\n // Bridge the non-compliant token.\n vm.prank(alice);\n bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex\"5678\");\n\n // Attempt to finalize the withdrawal. Should revert because the token does not claim\n // to be compliant with the `IOptimismMintableERC721` interface.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token interface is not compliant\");\n bridge.finalizeBridgeERC721(\n address(address(nonCompliantToken)),\n address(address(0x01)),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.prank(alice);\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(alice)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721Bridge: function can only be called from the other bridge\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_selfToken_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"L2ERC721Bridge: local token cannot be self\");\n bridge.finalizeBridgeERC721(\n address(bridge),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n\n function test_finalizeBridgeERC721_alreadyExists_reverts() external {\n // Finalize a withdrawal.\n vm.mockCall(\n address(L2Messenger),\n abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),\n abi.encode(otherBridge)\n );\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"ERC721: token already minted\");\n bridge.finalizeBridgeERC721(\n address(localToken),\n address(remoteToken),\n alice,\n alice,\n tokenId,\n hex\"5678\"\n );\n }\n}\n\n/**\n * @dev A non-compliant ERC721 token that does not implement the full ERC721 interface.\n *\n * This is used to test that the bridge will revert if the token does not claim to support\n * the ERC721 interface.\n */\ncontract NonCompliantERC721 {\n address internal immutable owner;\n\n constructor(address _owner) {\n owner = _owner;\n }\n\n function ownerOf(uint256) external view returns (address) {\n return owner;\n }\n\n function remoteToken() external pure returns (address) {\n return address(0x01);\n }\n\n function burn(address, uint256) external {\n // Do nothing.\n }\n\n function supportsInterface(bytes4) external pure returns (bool) {\n return false;\n }\n}\n" - }, - "contracts/test/L2OutputOracle.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { L2OutputOracle_Initializer, NextImpl } from \"./CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Types } from \"../libraries/Types.sol\";\n\ncontract L2OutputOracleTest is L2OutputOracle_Initializer {\n bytes32 proposedOutput1 = keccak256(abi.encode(1));\n\n function test_constructor_succeeds() external {\n assertEq(oracle.PROPOSER(), proposer);\n assertEq(oracle.CHALLENGER(), owner);\n assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);\n assertEq(oracle.latestBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingBlockNumber(), startingBlockNumber);\n assertEq(oracle.startingTimestamp(), startingTimestamp);\n }\n\n function test_constructor_badTimestamp_reverts() external {\n vm.expectRevert(\"L2OutputOracle: starting L2 timestamp must be less than current time\");\n\n // startingTimestamp is in the future\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp + 1,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function test_constructor_l2BlockTimeZero_reverts() external {\n vm.expectRevert(\"L2OutputOracle: L2 block time must be greater than 0\");\n new L2OutputOracle({\n _submissionInterval: submissionInterval,\n _l2BlockTime: 0,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n function testFuzz_constructor_submissionIntervalLteL2BlockTime_reverts(\n uint256 _submissionInterval,\n uint256 _l2BlockTime\n ) external {\n // Bound the _l2blockTime to be in the range of [1, type(uint256).max]\n _l2BlockTime = bound(_l2BlockTime, 1, type(uint256).max);\n // Roll the block number to _l2blockTime (the starting L2 timestamp must be less than or equal to the current time)\n vm.roll(_l2BlockTime);\n // Bound _submissionInterval to be less than or equal to _l2BlockTime\n _submissionInterval = bound(_submissionInterval, 0, _l2BlockTime);\n\n vm.expectRevert(\"L2OutputOracle: submission interval must be greater than L2 block time\");\n new L2OutputOracle({\n _submissionInterval: _submissionInterval,\n _l2BlockTime: _l2BlockTime,\n _startingBlockNumber: startingBlockNumber,\n _startingTimestamp: block.timestamp,\n _proposer: proposer,\n _challenger: owner,\n _finalizationPeriodSeconds: 7 days\n });\n }\n\n /****************\n * Getter Tests *\n ****************/\n\n // Test: latestBlockNumber() should return the correct value\n function test_latestBlockNumber_succeeds() external {\n uint256 proposedNumber = oracle.nextBlockNumber();\n\n // Roll to after the block number we'll propose\n warpToProposeTime(proposedNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0);\n assertEq(oracle.latestBlockNumber(), proposedNumber);\n }\n\n // Test: getL2Output() should return the correct value\n function test_getL2Output_succeeds() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0);\n\n Types.OutputProposal memory proposal = oracle.getL2Output(nextOutputIndex);\n assertEq(proposal.outputRoot, proposedOutput1);\n assertEq(proposal.timestamp, block.timestamp);\n\n // The block number is larger than the latest proposed output:\n vm.expectRevert(stdError.indexOOBError);\n oracle.getL2Output(nextOutputIndex + 1);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is exact block\n function test_getL2OutputIndexAfter_sameBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with exact same block as proposed returns the proposal.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value when input is previous block\n function test_getL2OutputIndexAfter_previousBlock_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n // Querying with previous block returns the proposal too.\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 - 1);\n assertEq(index1, 0);\n }\n\n // Test: getL2OutputIndexAfter() returns correct value during binary search\n function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external {\n bytes32 output1 = keccak256(abi.encode(1));\n uint256 nextBlockNumber1 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber1);\n vm.prank(proposer);\n oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);\n\n bytes32 output2 = keccak256(abi.encode(2));\n uint256 nextBlockNumber2 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber2);\n vm.prank(proposer);\n oracle.proposeL2Output(output2, nextBlockNumber2, 0, 0);\n\n bytes32 output3 = keccak256(abi.encode(3));\n uint256 nextBlockNumber3 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber3);\n vm.prank(proposer);\n oracle.proposeL2Output(output3, nextBlockNumber3, 0, 0);\n\n bytes32 output4 = keccak256(abi.encode(4));\n uint256 nextBlockNumber4 = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber4);\n vm.prank(proposer);\n oracle.proposeL2Output(output4, nextBlockNumber4, 0, 0);\n\n // Querying with a block number between the first and second proposal\n uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 + 1);\n assertEq(index1, 1);\n\n // Querying with a block number between the second and third proposal\n uint256 index2 = oracle.getL2OutputIndexAfter(nextBlockNumber2 + 1);\n assertEq(index2, 2);\n\n // Querying with a block number between the third and fourth proposal\n uint256 index3 = oracle.getL2OutputIndexAfter(nextBlockNumber3 + 1);\n assertEq(index3, 3);\n }\n\n // Test: getL2OutputIndexAfter() reverts when no output exists yet\n function test_getL2OutputIndexAfter_noOutputsExis_reverts() external {\n vm.expectRevert(\"L2OutputOracle: cannot get output as no outputs have been proposed yet\");\n oracle.getL2OutputIndexAfter(0);\n }\n\n // Test: nextBlockNumber() should return the correct value\n function test_nextBlockNumber_succeeds() external {\n assertEq(\n oracle.nextBlockNumber(),\n // The return value should match this arithmetic\n oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL()\n );\n }\n\n function test_computeL2Timestamp_succeeds() external {\n // reverts if timestamp is too low\n vm.expectRevert(stdError.arithmeticError);\n oracle.computeL2Timestamp(startingBlockNumber - 1);\n\n // returns the correct value...\n // ... for the very first block\n assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);\n\n // ... for the first block after the starting block\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 1),\n startingTimestamp + l2BlockTime\n );\n\n // ... for some other block number\n assertEq(\n oracle.computeL2Timestamp(startingBlockNumber + 96024),\n startingTimestamp + l2BlockTime * 96024\n );\n }\n\n /*****************************\n * Propose Tests - Happy Path *\n *****************************/\n\n // Test: proposeL2Output succeeds when given valid input, and no block hash and number are\n // specified.\n function test_proposeL2Output_proposeAnotherOutput_succeeds() public {\n bytes32 proposedOutput2 = keccak256(abi.encode());\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n warpToProposeTime(nextBlockNumber);\n uint256 proposedNumber = oracle.latestBlockNumber();\n\n // Ensure the submissionInterval is enforced\n assertEq(nextBlockNumber, proposedNumber + submissionInterval);\n\n vm.roll(nextBlockNumber + 1);\n\n vm.expectEmit(true, true, true, true);\n emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp);\n\n vm.prank(proposer);\n oracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output succeeds when given valid input, and when a block hash and number are\n // specified for reorg protection.\n function test_proposeWithBlockhashAndHeight_succeeds() external {\n // Get the number and hash of a previous block in the chain\n uint256 prevL1BlockNumber = block.number - 1;\n bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber);\n }\n\n /***************************\n * Propose Tests - Sad Path *\n ***************************/\n\n // Test: proposeL2Output fails if called by a party that is not the proposer.\n function test_proposeL2Output_notProposer_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n\n vm.prank(address(128));\n vm.expectRevert(\"L2OutputOracle: only the proposer address can propose new outputs\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails given a zero blockhash.\n function test_proposeL2Output_emptyOutput_reverts() external {\n bytes32 outputToPropose = bytes32(0);\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: L2 output proposal cannot be the zero hash\");\n oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if the block number doesn't match the next expected number.\n function test_proposeL2Output_unexpectedBlockNumber_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: block number must be equal to next expected block number\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);\n }\n\n // Test: proposeL2Output fails if it would have a timestamp in the future.\n function test_proposeL2Output_futureTimetamp_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber);\n vm.warp(nextTimestamp);\n vm.prank(proposer);\n vm.expectRevert(\"L2OutputOracle: cannot propose L2 output in the future\");\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);\n }\n\n // Test: proposeL2Output fails if a non-existent L1 block hash and number are provided for reorg\n // protection.\n function test_proposeL2Output_wrongFork_reverts() external {\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(\n nonZeroHash,\n nextBlockNumber,\n bytes32(uint256(0x01)),\n block.number - 1\n );\n }\n\n // Test: proposeL2Output fails when given valid input, but the block hash and number do not\n // match.\n function test_proposeL2Output_unmatchedBlockhash_reverts() external {\n // Move ahead to block 100 so that we can reference historical blocks\n vm.roll(100);\n\n // Get the number and hash of a previous block in the chain\n uint256 l1BlockNumber = block.number - 1;\n bytes32 l1BlockHash = blockhash(l1BlockNumber);\n\n uint256 nextBlockNumber = oracle.nextBlockNumber();\n warpToProposeTime(nextBlockNumber);\n vm.prank(proposer);\n\n // This will fail when foundry no longer returns zerod block hashes\n vm.expectRevert(\n \"L2OutputOracle: block hash does not match the hash at the expected height\"\n );\n oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);\n }\n\n /*****************************\n * Delete Tests - Happy Path *\n *****************************/\n\n function test_deleteOutputs_singleOutput_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 1);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex);\n oracle.deleteL2Outputs(latestOutputIndex);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n function test_deleteOutputs_multipleOutputs_succeeds() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 3);\n\n vm.prank(owner);\n vm.expectEmit(true, true, false, false);\n emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // validate latestBlockNumber has been reduced\n uint256 latestBlockNumberAfter = oracle.latestBlockNumber();\n uint256 latestOutputIndexAfter = oracle.latestOutputIndex();\n assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter);\n\n // validate that the new latest output is as expected.\n Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter);\n assertEq(newLatestOutput.outputRoot, proposal.outputRoot);\n assertEq(newLatestOutput.timestamp, proposal.timestamp);\n }\n\n /***************************\n * Delete Tests - Sad Path *\n ***************************/\n\n function test_deleteL2Outputs_ifNotChallenger_reverts() external {\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.expectRevert(\"L2OutputOracle: only the challenger address can delete outputs\");\n oracle.deleteL2Outputs(latestBlockNumber);\n }\n\n function test_deleteL2Outputs_nonExistent_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n uint256 latestBlockNumber = oracle.latestBlockNumber();\n\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestBlockNumber + 1);\n }\n\n function test_deleteL2Outputs_afterLatest_reverts() external {\n // Start by proposing three outputs\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Delete the latest two outputs\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n vm.prank(owner);\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n\n // Now try to delete the same output again\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs after the latest output index\");\n oracle.deleteL2Outputs(latestOutputIndex - 2);\n }\n\n function test_deleteL2Outputs_finalized_reverts() external {\n test_proposeL2Output_proposeAnotherOutput_succeeds();\n\n // Warp past the finalization period + 1 second\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n uint256 latestOutputIndex = oracle.latestOutputIndex();\n\n // Try to delete a finalized output\n vm.prank(owner);\n vm.expectRevert(\"L2OutputOracle: cannot delete outputs that have already been finalized\");\n oracle.deleteL2Outputs(latestOutputIndex);\n }\n}\n\ncontract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {\n Proxy internal proxy;\n\n function setUp() public override {\n super.setUp();\n proxy = Proxy(payable(address(oracle)));\n }\n\n function test_initValuesOnProxy_succeeds() external {\n assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());\n assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());\n assertEq(startingBlockNumber, oracleImpl.startingBlockNumber());\n assertEq(startingTimestamp, oracleImpl.startingTimestamp());\n\n assertEq(proposer, oracleImpl.PROPOSER());\n assertEq(owner, oracleImpl.CHALLENGER());\n }\n\n function test_initializeProxy_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(payable(proxy)).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_initializeImpl_alreadyInitialized_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n L2OutputOracle(oracleImpl).initialize(startingBlockNumber, startingTimestamp);\n }\n\n function test_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(oracle), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(oracle), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(oracle)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/L2StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { stdStorage, StdStorage } from \"forge-std/Test.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { console } from \"forge-std/console.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\n\ncontract L2StandardBridge_Test is Bridge_Initializer {\n using stdStorage for StdStorage;\n\n function test_initialize_succeeds() external {\n assertEq(address(L2Bridge.messenger()), address(L2Messenger));\n assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge));\n assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge));\n }\n\n // receive\n // - can accept ETH\n function test_receive_succeeds() external {\n assertEq(address(messagePasser).balance, 0);\n uint256 nonce = L2Messenger.messageNonce();\n\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeETH.selector,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 200_000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 100,\n 200_000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 100,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeInitiated(alice, alice, 100, hex\"\");\n\n // L2ToL1MessagePasser will emit a MessagePassed event\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 100,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 200_000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 100);\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n vm.prank(alice, alice);\n (bool success, ) = address(L2Bridge).call{ value: 100 }(hex\"\");\n assertEq(success, true);\n assertEq(address(messagePasser).balance, 100);\n }\n\n // withrdraw\n // - requires amount == msg.value\n function test_withdraw_insufficientValue_reverts() external {\n assertEq(address(messagePasser).balance, 0);\n\n vm.expectRevert(\"StandardBridge: bridging ETH must include sufficient ETH value\");\n vm.prank(alice, alice);\n L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex\"\");\n }\n\n /**\n * @notice Use the legacy `withdraw` interface on the L2StandardBridge to\n * withdraw ether from L2 to L1.\n */\n function test_withdraw_ether_succeeds() external {\n assertTrue(alice.balance >= 100);\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0);\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated({\n l1Token: address(0),\n l2Token: Predeploys.LEGACY_ERC20_ETH,\n from: alice,\n to: alice,\n amount: 100,\n data: hex\"\"\n });\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex\"\" });\n\n vm.prank(alice, alice);\n L2Bridge.withdraw{ value: 100 }({\n _l2Token: Predeploys.LEGACY_ERC20_ETH,\n _amount: 100,\n _minGasLimit: 1000,\n _extraData: hex\"\"\n });\n\n assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 100);\n }\n}\n\ncontract PreBridgeERC20 is Bridge_Initializer {\n // withdraw and BridgeERC20 should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20(bool _isLegacy, address _l2Token) internal {\n // Alice has 100 L2Token\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(_l2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n alice,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex\"\")\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20.selector,\n _l2Token,\n address(L1Token),\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n _l2Token,\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true);\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {\n // withdraw\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_withdraw_withdrawingERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // BridgeERC20\n // - token is burned\n // - emits WithdrawalInitiated\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdrawLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) });\n L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_bridgeLegacyERC20_succeeds() external {\n _preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) });\n L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_withdraw_notEOA_reverts() external {\n // This contract has 100 L2Token\n deal(address(L2Token), address(this), 100, true);\n\n vm.expectRevert(\"StandardBridge: function can only be called from an EOA\");\n L2Bridge.withdraw(address(L2Token), 100, 1000, hex\"\");\n }\n}\n\ncontract PreBridgeERC20To is Bridge_Initializer {\n // withdrawTo and BridgeERC20To should behave the same when transferring ERC20 tokens\n // so they should share the same setup and expectEmit calls\n function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal {\n deal(_l2Token, alice, 100, true);\n assertEq(ERC20(L2Token).balanceOf(alice), 100);\n uint256 nonce = L2Messenger.messageNonce();\n bytes memory message = abi.encodeWithSelector(\n StandardBridge.finalizeBridgeERC20.selector,\n address(L1Token),\n _l2Token,\n alice,\n bob,\n 100,\n hex\"\"\n );\n uint64 baseGas = L2Messenger.baseGas(message, 1000);\n bytes memory withdrawalData = abi.encodeWithSelector(\n CrossDomainMessenger.relayMessage.selector,\n nonce,\n address(L2Bridge),\n address(L1Bridge),\n 0,\n 1000,\n message\n );\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: address(L2Messenger),\n target: address(L1Messenger),\n value: 0,\n gasLimit: baseGas,\n data: withdrawalData\n })\n );\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(messagePasser));\n emit MessagePassed(\n nonce,\n address(L2Messenger),\n address(L1Messenger),\n 0,\n baseGas,\n withdrawalData,\n withdrawalHash\n );\n\n // SentMessage event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000);\n\n // SentMessageExtension1 event emitted by the CrossDomainMessenger\n vm.expectEmit(true, true, true, true, address(L2Messenger));\n emit SentMessageExtension1(address(L2Bridge), 0);\n\n if (_isLegacy) {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.withdrawTo.selector,\n _l2Token,\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n } else {\n vm.expectCall(\n address(L2Bridge),\n abi.encodeWithSelector(\n L2Bridge.bridgeERC20To.selector,\n _l2Token,\n address(L1Token),\n bob,\n 100,\n 1000,\n hex\"\"\n )\n );\n }\n\n vm.expectCall(\n address(L2Messenger),\n abi.encodeWithSelector(\n CrossDomainMessenger.sendMessage.selector,\n address(L1Bridge),\n message,\n 1000\n )\n );\n\n vm.expectCall(\n Predeploys.L2_TO_L1_MESSAGE_PASSER,\n abi.encodeWithSelector(\n L2ToL1MessagePasser.initiateWithdrawal.selector,\n address(L1Messenger),\n baseGas,\n withdrawalData\n )\n );\n\n // The L2Bridge should burn the tokens\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)\n );\n\n vm.prank(alice, alice);\n }\n}\n\ncontract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {\n // withdrawTo\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_withdrawTo_withdrawingERC20_succeeds() external {\n _preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) });\n L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex\"\");\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n // bridgeERC20To\n // - token is burned\n // - emits WithdrawalInitiated w/ correct recipient\n // - calls Withdrawer.initiateWithdrawal\n function test_bridgeERC20To_succeeds() external {\n _preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) });\n L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex\"\");\n assertEq(L2Token.balanceOf(alice), 0);\n }\n}\n\ncontract L2StandardBridge_Bridge_Test is Bridge_Initializer {\n // finalizeDeposit\n // - only callable by l1TokenBridge\n // - supported token pair emits DepositFinalized\n // - invalid deposit calls Withdrawer.initiateWithdrawal\n function test_finalizeDeposit_depositingERC20_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n vm.expectCall(\n address(L2Token),\n abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex\"\");\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeDeposit_depositingETH_succeeds() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n\n // Should emit both the bedrock and legacy events\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true, address(L2Bridge));\n emit ERC20BridgeFinalized(\n address(L2Token), // localToken\n address(L1Token), // remoteToken\n alice,\n alice,\n 100,\n hex\"\"\n );\n\n vm.prank(address(L2Messenger));\n L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_incorrectValue_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: amount sent does not match amount required\");\n L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToSelf_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to self\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex\"\");\n }\n\n function test_finalizeBridgeETH_sendToMessenger_reverts() external {\n vm.mockCall(\n address(L2Bridge.messenger()),\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(address(L2Messenger), 100);\n vm.prank(address(L2Messenger));\n vm.expectRevert(\"StandardBridge: cannot send to messenger\");\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Messenger), 100, hex\"\");\n }\n}\n\ncontract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {\n function test_finalizeBridgeETH_succeeds() external {\n address messenger = address(L2Bridge.messenger());\n vm.mockCall(\n messenger,\n abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),\n abi.encode(address(L2Bridge.OTHER_BRIDGE()))\n );\n vm.deal(messenger, 100);\n vm.prank(messenger);\n\n vm.expectEmit(true, true, true, true);\n emit DepositFinalized(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex\"\");\n\n vm.expectEmit(true, true, true, true);\n emit ETHBridgeFinalized(alice, alice, 100, hex\"\");\n\n L2Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex\"\");\n }\n}\n" - }, - "contracts/test/L2ToL1MessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { L2ToL1MessagePasser } from \"../L2/L2ToL1MessagePasser.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\n\ncontract L2ToL1MessagePasserTest is CommonTest {\n L2ToL1MessagePasser messagePasser;\n\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new L2ToL1MessagePasser();\n }\n\n function testFuzz_initiateWithdrawal_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n uint256 nonce = messagePasser.messageNonce();\n\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: _value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash);\n\n vm.deal(_sender, _value);\n vm.prank(_sender);\n messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);\n\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0)));\n\n assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1)));\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by a contract\n function test_initiateWithdrawal_fromContract_succeeds() external {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\"\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(\n messagePasser.messageNonce(),\n address(this),\n address(4),\n 100,\n 64000,\n hex\"\",\n withdrawalHash\n );\n\n vm.deal(address(this), 2**64);\n messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex\"\");\n }\n\n // Test: initiateWithdrawal should emit the correct log when called by an EOA\n function test_initiateWithdrawal_fromEOA_succeeds() external {\n uint256 gasLimit = 64000;\n address target = address(4);\n uint256 value = 100;\n bytes memory data = hex\"ff\";\n uint256 nonce = messagePasser.messageNonce();\n\n // EOA emulation\n vm.prank(alice, alice);\n vm.deal(alice, 2**64);\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data)\n );\n\n vm.expectEmit(true, true, true, true);\n emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash);\n\n messagePasser.initiateWithdrawal{ value: value }(target, gasLimit, data);\n\n // the sent messages mapping is filled\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n // the nonce increments\n assertEq(nonce + 1, messagePasser.messageNonce());\n }\n\n // Test: burn should destroy the ETH held in the contract\n function test_burn_succeeds() external {\n messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n NON_ZERO_GASLIMIT,\n NON_ZERO_DATA\n );\n\n assertEq(address(messagePasser).balance, NON_ZERO_VALUE);\n vm.expectEmit(true, false, false, false);\n emit WithdrawerBalanceBurnt(NON_ZERO_VALUE);\n messagePasser.burn();\n\n // The Withdrawer should have no balance\n assertEq(address(messagePasser).balance, 0);\n }\n}\n" - }, - "contracts/test/LegacyERC20ETH.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyERC20ETH } from \"../legacy/LegacyERC20ETH.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyERC20ETH_Test is CommonTest {\n LegacyERC20ETH eth;\n\n function setUp() public virtual override {\n super.setUp();\n eth = new LegacyERC20ETH();\n }\n\n function test_metadata_succeeds() external {\n assertEq(eth.name(), \"Ether\");\n assertEq(eth.symbol(), \"ETH\");\n assertEq(eth.decimals(), 18);\n }\n\n function test_crossDomain_succeeds() external {\n assertEq(eth.l2Bridge(), Predeploys.L2_STANDARD_BRIDGE);\n assertEq(eth.l1Token(), address(0));\n }\n\n function test_transfer_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transfer is disabled\");\n eth.transfer(alice, 100);\n }\n\n function test_approve_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: approve is disabled\");\n eth.approve(alice, 100);\n }\n\n function test_transferFrom_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: transferFrom is disabled\");\n eth.transferFrom(bob, alice, 100);\n }\n\n function test_increaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: increaseAllowance is disabled\");\n eth.increaseAllowance(alice, 100);\n }\n\n function test_decreaseAllowance_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: decreaseAllowance is disabled\");\n eth.decreaseAllowance(alice, 100);\n }\n\n function test_mint_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: mint is disabled\");\n eth.mint(alice, 100);\n }\n\n function test_burn_doesNotExist_reverts() external {\n vm.expectRevert(\"LegacyERC20ETH: burn is disabled\");\n eth.burn(alice, 100);\n }\n}\n" - }, - "contracts/test/LegacyMessagePasser.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { LegacyMessagePasser } from \"../legacy/LegacyMessagePasser.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract LegacyMessagePasser_Test is CommonTest {\n LegacyMessagePasser messagePasser;\n\n function setUp() public virtual override {\n super.setUp();\n messagePasser = new LegacyMessagePasser();\n }\n\n function test_passMessageToL1_succeeds() external {\n vm.prank(alice);\n messagePasser.passMessageToL1(hex\"ff\");\n assert(messagePasser.sentMessages(keccak256(abi.encodePacked(hex\"ff\", alice))));\n }\n}\n" - }, - "contracts/test/MerkleTrie.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MerkleTrie } from \"../libraries/trie/MerkleTrie.sol\";\n\ncontract MerkleTrie_get_Test is CommonTest {\n function test_get_validProof1_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579326262\";\n bytes memory val = hex\"6176616c32\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof2_succeeds() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[\n 2\n ] = hex\"ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof3_succeeds() external {\n bytes32 root = 0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed;\n bytes memory key = hex\"6b6579316161\";\n bytes\n memory val = hex\"303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof4_succeeds() external {\n bytes32 root = 0x37956bab6bba472308146808d5311ac19cb4a7daae5df7efcc0f32badc97f55e;\n bytes memory key = hex\"6b6579316161\";\n bytes memory val = hex\"3031323334\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"ce87206b6579316161853031323334\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof5_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657931\";\n bytes\n memory val = hex\"30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof6_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657932\";\n bytes memory val = hex\"73686f7274\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[2] = hex\"df808080808080c9823262856176616c338080808080808080808573686f7274\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof7_succeeds() external {\n bytes32 root = 0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89;\n bytes memory key = hex\"6b657933\";\n bytes memory val = hex\"31323334353637383930313233343536373839303132333435363738393031\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779\";\n proof[\n 1\n ] = hex\"f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080\";\n proof[\n 2\n ] = hex\"f839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof8_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"61\";\n bytes memory val = hex\"61\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22061\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof9_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"62\";\n bytes memory val = hex\"62\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22062\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_validProof10_succeeds() external {\n bytes32 root = 0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978;\n bytes memory key = hex\"63\";\n bytes memory val = hex\"63\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d916d780c22061c22062c2206380808080808080808080808080\";\n proof[1] = hex\"d780c22061c22062c2206380808080808080808080808080\";\n proof[2] = hex\"c22063\";\n\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n function test_get_nonexistentKey1_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"6b657932\";\n bytes[] memory proof = new bytes[](3);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 1\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[2] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_nonexistentKey2_reverts() external {\n bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f;\n bytes memory key = hex\"616e7972616e646f6d6b6579\";\n bytes[] memory proof = new bytes[](1);\n proof[\n 0\n ] = hex\"e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_wrongKeyProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579316161\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e216a04892c039d654f1be9af20e88ae53e9ab5fa5520190e0fb2f805823e45ebad22f\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[2] = hex\"d687206e6f746865728d33343938683472697568677765\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_corruptedProof_reverts() external {\n bytes32 root = 0x2858eebfa9d96c8a9e6a0cae9d86ec9189127110f132d63f07d3544c2a75a696;\n bytes memory key = hex\"6b6579326262\";\n bytes[] memory proof = new bytes[](5);\n proof[0] = hex\"2fd2ba5ee42358802ffbe0900152a55fabe953ae880ef29abef154d639c09248a016e2\";\n proof[\n 1\n ] = hex\"f84780d687206e6f746865728d33343938683472697568677765808080808080808080a0854405b57aa6dc458bc41899a761cbbb1f66a4998af6dd0e8601c1b845395ae38080808080\";\n proof[\n 2\n ] = hex\"e583165793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386\";\n proof[\n 3\n ] = hex\"f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080\";\n proof[4] = hex\"ca83206262856176616c32\";\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidDataRemainder_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa000000000000000000000000000000\";\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_invalidInternalNodeHash_reverts() external {\n bytes32 root = 0xa827dff1a657bb9bb9a1c3abe9db173e2f1359f15eb06f1647ea21ac7c95d8fa;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa09862c6b113008c4204c13755693cbb868acc25ebaa98db11df8c89a0c0dd3157\";\n proof[\n 1\n ] = hex\"f380808080808080808080a0de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f00c220118080808080\";\n proof[2] = hex\"de2a9c6a46b6ea71ab9e881c8420570cf19e833c85df6026b04f085016e78f\";\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroBranchValueLength_reverts() external {\n bytes32 root = 0xe04b3589eef96b237cd49ccb5dcf6e654a47682bfa0961d563ab843f7ad1e035;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](2);\n proof[0] = hex\"dd8200aad98080808080808080808080c43b82aabbc43c82aacc80808080\";\n proof[1] = hex\"d98080808080808080808080c43b82aabbc43c82aacc80808080\";\n\n vm.expectRevert(\"MerkleTrie: value length must be greater than zero (branch)\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_zeroLengthKey_reverts() external {\n bytes32 root = 0x54157fd62cdf2f474e7bfec2d3cd581e807bee38488c9590cb887add98936b73;\n bytes memory key = hex\"\";\n bytes[] memory proof = new bytes[](1);\n proof[0] = hex\"c78320f00082b443\";\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey1_reverts() external {\n bytes32 root = 0xa513ba530659356fb7588a2c831944e80fd8aedaa5a4dc36f918152be2be0605;\n bytes memory key = hex\"01\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"db10d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[1] = hex\"d9c32081bbc582202381aa808080808080808080808080808080\";\n proof[2] = hex\"c582202381aa\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_smallerPathThanKey2_reverts() external {\n bytes32 root = 0xa06abffaec4ebe8ccde595f4547b864b4421b21c1fc699973f94710c9bc17979;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](3);\n proof[0] = hex\"e21aa07ea462226a3dc0a46afb4ded39306d7a84d311ada3557dfc75a909fd25530905\";\n proof[\n 1\n ] = hex\"f380808080808080808080a027f11bd3af96d137b9287632f44dd00fea1ca1bd70386c30985ede8cc287476e808080c220338080\";\n proof[2] = hex\"e48200bba0a6911545ed01c2d3f4e15b8b27c7bfba97738bd5e6dd674dd07033428a4c53af\";\n\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n MerkleTrie.get(key, proof, root);\n }\n\n function test_get_extraProofElements_reverts() external {\n bytes32 root = 0x278c88eb59beba4f8b94f940c41614bb0dd80c305859ebffcd6ce07c93ca3749;\n bytes memory key = hex\"aa\";\n bytes[] memory proof = new bytes[](4);\n proof[0] = hex\"d91ad780808080808080808080c32081aac32081ab8080808080\";\n proof[1] = hex\"d780808080808080808080c32081aac32081ab8080808080\";\n proof[2] = hex\"c32081aa\";\n proof[3] = hex\"c32081aa\";\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_validProofs_succeeds(bytes4) external {\n // Generate a test case with a valid proof of inclusion for the k/v pair in the trie.\n (bytes32 root, bytes memory key, bytes memory val, bytes[] memory proof) = ffi\n .getMerkleTrieFuzzCase(\"valid\");\n\n // Assert that our expected value is equal to our actual value.\n assertEq(val, MerkleTrie.get(key, proof, root));\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidRoot_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"valid\"\n );\n\n bytes32 rootHash = keccak256(abi.encodePacked(root));\n vm.expectRevert(\"MerkleTrie: invalid root hash\");\n MerkleTrie.get(key, proof, rootHash);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_extraProofElements_reverts(bytes4) external {\n // Generate an invalid test case with an extra proof element attached to an otherwise\n // valid proof of inclusion for the passed k/v.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"extra_proof_elems\"\n );\n\n vm.expectRevert(\"MerkleTrie: value node must be last node in proof (leaf)\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidLargeInternalHash_reverts(bytes4) external {\n // Generate an invalid test case where a long proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_large_internal_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid large internal hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidInternalNodeHash_reverts(bytes4) external {\n // Generate an invalid test case where a small proof element is incorrect for the root.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_internal_node_hash\"\n );\n\n vm.expectRevert(\"MerkleTrie: invalid internal node hash\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_corruptedProof_reverts(bytes4) external {\n // Generate an invalid test case where the proof is malformed.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"corrupted_proof\"\n );\n\n vm.expectRevert(\"RLPReader: decoded item type for list is not a list item\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_invalidDataRemainder_reverts(bytes4) external {\n // Generate an invalid test case where a random element of the proof has more bytes than the\n // length designates within the RLP list encoding.\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"invalid_data_remainder\"\n );\n\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_prefixedValidKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and a valid key that is prefixed\n // with random bytes\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"prefixed_valid_key\"\n );\n\n // Ambiguous revert check- all that we care is that it *does* fail. This case may\n // fail within different branches.\n vm.expectRevert();\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_emptyKey_reverts(bytes4) external {\n // Get a random test case with a valid trie / proof and an empty key\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"empty_key\"\n );\n\n vm.expectRevert(\"MerkleTrie: empty key\");\n MerkleTrie.get(key, proof, root);\n }\n\n /// @notice The `bytes4` parameter is to enable parallel fuzz runs; it is ignored.\n function testFuzz_get_partialProof_reverts(bytes4) external {\n // Get a random test case with a valid trie / partially correct proof\n (bytes32 root, bytes memory key, , bytes[] memory proof) = ffi.getMerkleTrieFuzzCase(\n \"partial_proof\"\n );\n\n vm.expectRevert(\"MerkleTrie: ran out of proof elements\");\n MerkleTrie.get(key, proof, root);\n }\n}\n" - }, - "contracts/test/MintManager.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { MintManager } from \"../governance/MintManager.sol\";\nimport { GovernanceToken } from \"../governance/GovernanceToken.sol\";\n\ncontract MintManager_Initializer is CommonTest {\n address constant owner = address(0x1234);\n address constant rando = address(0x5678);\n GovernanceToken internal gov;\n MintManager internal manager;\n\n function setUp() public virtual override {\n super.setUp();\n\n vm.prank(owner);\n gov = new GovernanceToken();\n\n vm.prank(owner);\n manager = new MintManager(owner, address(gov));\n\n vm.prank(owner);\n gov.transferOwnership(address(manager));\n }\n}\n\ncontract MintManager_constructor_Test is MintManager_Initializer {\n /**\n * @notice Tests that the constructor properly configures the contract.\n */\n function test_constructor_succeeds() external {\n assertEq(manager.owner(), owner);\n assertEq(address(manager.governanceToken()), address(gov));\n }\n}\n\ncontract MintManager_mint_Test is MintManager_Initializer {\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner.\n */\n function test_mint_fromOwner_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the mint function reverts when called by a non-owner.\n */\n function test_mint_fromNotOwner_reverts() external {\n // Mint from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.mint(owner, 100);\n }\n\n /**\n * @notice Tests that the mint function properly mints tokens when called by the owner a second\n * time after the mint period has elapsed.\n */\n function test_mint_afterPeriodElapsed_succeeds() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again after period elapsed (2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n manager.mint(owner, 2);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 102);\n }\n\n /**\n * @notice Tests that the mint function always reverts when called before the mint period has\n * elapsed, even if the caller is the owner.\n */\n function test_mint_beforePeriodElapsed_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: minting not permitted yet\");\n manager.mint(owner, 100);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n\n /**\n * @notice Tests that the owner cannot mint more than the mint cap.\n */\n function test_mint_moreThanCap_reverts() external {\n // Mint once.\n vm.prank(owner);\n manager.mint(owner, 100);\n\n // Token balance increases.\n assertEq(gov.balanceOf(owner), 100);\n\n // Mint again (greater than 2% max).\n vm.warp(block.timestamp + manager.MINT_PERIOD() + 1);\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint amount exceeds cap\");\n manager.mint(owner, 3);\n\n // Token balance does not increase.\n assertEq(gov.balanceOf(owner), 100);\n }\n}\n\ncontract MintManager_upgrade_Test is MintManager_Initializer {\n /**\n * @notice Tests that the owner can upgrade the mint manager.\n */\n function test_upgrade_fromOwner_succeeds() external {\n // Upgrade to new manager.\n vm.prank(owner);\n manager.upgrade(rando);\n\n // New manager is rando.\n assertEq(gov.owner(), rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when called by a non-owner.\n */\n function test_upgrade_fromNotOwner_reverts() external {\n // Upgrade from rando fails.\n vm.prank(rando);\n vm.expectRevert(\"Ownable: caller is not the owner\");\n manager.upgrade(rando);\n }\n\n /**\n * @notice Tests that the upgrade function reverts when attempting to update to the zero\n * address, even if the caller is the owner.\n */\n function test_upgrade_toZeroAddress_reverts() external {\n // Upgrade to zero address fails.\n vm.prank(owner);\n vm.expectRevert(\"MintManager: mint manager cannot be the zero address\");\n manager.upgrade(address(0));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport {\n ILegacyMintableERC20,\n IOptimismMintableERC20\n} from \"../universal/IOptimismMintableERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract OptimismMintableERC20_Test is Bridge_Initializer {\n event Mint(address indexed account, uint256 amount);\n event Burn(address indexed account, uint256 amount);\n\n function test_semver_succeeds() external {\n assertEq(L2Token.version(), \"1.0.0\");\n }\n\n function test_remoteToken_succeeds() external {\n assertEq(L2Token.remoteToken(), address(L1Token));\n }\n\n function test_bridge_succeeds() external {\n assertEq(L2Token.bridge(), address(L2Bridge));\n }\n\n function test_l1Token_succeeds() external {\n assertEq(L2Token.l1Token(), address(L1Token));\n }\n\n function test_l2Bridge_succeeds() external {\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_legacy_succeeds() external {\n // Getters for the remote token\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.l1Token(), address(L1Token));\n // Getters for the bridge\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.l2Bridge(), address(L2Bridge));\n }\n\n function test_mint_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 100);\n }\n\n function test_mint_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.mint(alice, 100);\n }\n\n function test_burn_succeeds() external {\n vm.prank(address(L2Bridge));\n L2Token.mint(alice, 100);\n\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 100);\n\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 100);\n\n assertEq(L2Token.balanceOf(alice), 0);\n }\n\n function test_burn_notBridge_reverts() external {\n // NOT the bridge\n vm.expectRevert(\"OptimismMintableERC20: only bridge can mint and burn\");\n vm.prank(address(alice));\n L2Token.burn(alice, 100);\n }\n\n function test_erc165_supportsInterface_succeeds() external {\n // The assertEq calls in this test are comparing the manual calculation of the iface,\n // with what is returned by the solidity's type().interfaceId, just to be safe.\n bytes4 iface1 = bytes4(keccak256(\"supportsInterface(bytes4)\"));\n assertEq(iface1, type(IERC165).interfaceId);\n assert(L2Token.supportsInterface(iface1));\n\n bytes4 iface2 = L2Token.l1Token.selector ^ L2Token.mint.selector ^ L2Token.burn.selector;\n assertEq(iface2, type(ILegacyMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface2));\n\n bytes4 iface3 = L2Token.remoteToken.selector ^\n L2Token.bridge.selector ^\n L2Token.mint.selector ^\n L2Token.burn.selector;\n assertEq(iface3, type(IOptimismMintableERC20).interfaceId);\n assert(L2Token.supportsInterface(iface3));\n }\n}\n" - }, - "contracts/test/OptimismMintableERC20Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\n\ncontract OptimismMintableTokenFactory_Test is Bridge_Initializer {\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n }\n\n function test_bridge_succeeds() external {\n assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge));\n }\n\n function test_createStandardL2Token_succeeds() external {\n address remote = address(4);\n address local = LibRLP.computeAddress(address(L2TokenFactory), 2);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_sameTwice_succeeds() external {\n address remote = address(4);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n\n address local = LibRLP.computeAddress(address(L2TokenFactory), 3);\n\n vm.expectEmit(true, true, true, true);\n emit StandardL2TokenCreated(remote, local);\n\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC20Created(local, remote, alice);\n\n vm.prank(alice);\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n\n function test_createStandardL2Token_remoteIsZero_succeeds() external {\n address remote = address(0);\n vm.expectRevert(\"OptimismMintableERC20Factory: must provide remote token address\");\n L2TokenFactory.createStandardL2Token(remote, \"Beep\", \"BOOP\");\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\n\ncontract OptimismMintableERC721_Test is ERC721Bridge_Initializer {\n ERC721 internal L1Token;\n OptimismMintableERC721 internal L2Token;\n\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n event Mint(address indexed account, uint256 tokenId);\n\n event Burn(address indexed account, uint256 tokenId);\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n L1Token = new ERC721(\"L1Token\", \"L1T\");\n L2Token = new OptimismMintableERC721(\n address(L2Bridge),\n 1,\n address(L1Token),\n \"L2Token\",\n \"L2T\"\n );\n\n // Label the addresses for nice traces.\n vm.label(address(L1Token), \"L1ERC721Token\");\n vm.label(address(L2Token), \"L2ERC721Token\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(L2Token.name(), \"L2Token\");\n assertEq(L2Token.symbol(), \"L2T\");\n assertEq(L2Token.remoteToken(), address(L1Token));\n assertEq(L2Token.bridge(), address(L2Bridge));\n assertEq(L2Token.remoteChainId(), 1);\n assertEq(L2Token.REMOTE_TOKEN(), address(L1Token));\n assertEq(L2Token.BRIDGE(), address(L2Bridge));\n assertEq(L2Token.REMOTE_CHAIN_ID(), 1);\n assertEq(L2Token.version(), \"1.0.0\");\n }\n\n function test_safeMint_succeeds() external {\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(address(0), alice, 1);\n\n // Expect a mint event.\n vm.expectEmit(true, true, true, true);\n emit Mint(alice, 1);\n\n // Mint the token.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token should be owned by alice.\n assertEq(L2Token.ownerOf(1), alice);\n }\n\n function test_safeMint_notBridge_reverts() external {\n // Try to mint the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.safeMint(alice, 1);\n }\n\n function test_burn_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Expect a transfer event.\n vm.expectEmit(true, true, true, true);\n emit Transfer(alice, address(0), 1);\n\n // Expect a burn event.\n vm.expectEmit(true, true, true, true);\n emit Burn(alice, 1);\n\n // Burn the token.\n vm.prank(address(L2Bridge));\n L2Token.burn(alice, 1);\n\n // Token should be owned by address(0).\n vm.expectRevert(\"ERC721: invalid token ID\");\n L2Token.ownerOf(1);\n }\n\n function test_burn_notBridge_reverts() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Try to burn the token.\n vm.expectRevert(\"OptimismMintableERC721: only bridge can call this function\");\n vm.prank(address(alice));\n L2Token.burn(alice, 1);\n }\n\n function test_tokenURI_succeeds() external {\n // Mint the token first.\n vm.prank(address(L2Bridge));\n L2Token.safeMint(alice, 1);\n\n // Token URI should be correct.\n assertEq(\n L2Token.tokenURI(1),\n string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(address(L1Token)), 20),\n \"@\",\n Strings.toString(1),\n \"/tokenURI?uint256=\",\n Strings.toString(1)\n )\n )\n );\n }\n}\n" - }, - "contracts/test/OptimismMintableERC721Factory.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { ERC721Bridge_Initializer } from \"./CommonTest.t.sol\";\nimport { LibRLP } from \"./RLP.t.sol\";\nimport { OptimismMintableERC721 } from \"../universal/OptimismMintableERC721.sol\";\nimport { OptimismMintableERC721Factory } from \"../universal/OptimismMintableERC721Factory.sol\";\n\ncontract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {\n OptimismMintableERC721Factory internal factory;\n\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n function setUp() public override {\n super.setUp();\n\n // Set up the token pair.\n factory = new OptimismMintableERC721Factory(address(L2Bridge), 1);\n\n // Label the addresses for nice traces.\n vm.label(address(factory), \"OptimismMintableERC721Factory\");\n }\n\n function test_constructor_succeeds() external {\n assertEq(factory.BRIDGE(), address(L2Bridge));\n assertEq(factory.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_succeeds() external {\n // Predict the address based on the factory address and nonce.\n address predicted = LibRLP.computeAddress(address(factory), 1);\n\n // Expect a token creation event.\n vm.expectEmit(true, true, true, true);\n emit OptimismMintableERC721Created(predicted, address(1234), alice);\n\n // Create the token.\n vm.prank(alice);\n OptimismMintableERC721 created = OptimismMintableERC721(\n factory.createOptimismMintableERC721(address(1234), \"L2Token\", \"L2T\")\n );\n\n // Token address should be correct.\n assertEq(address(created), predicted);\n\n // Should be marked as created by the factory.\n assertEq(factory.isOptimismMintableERC721(address(created)), true);\n\n // Token should've been constructed correctly.\n assertEq(created.name(), \"L2Token\");\n assertEq(created.symbol(), \"L2T\");\n assertEq(created.REMOTE_TOKEN(), address(1234));\n assertEq(created.BRIDGE(), address(L2Bridge));\n assertEq(created.REMOTE_CHAIN_ID(), 1);\n }\n\n function test_createOptimismMintableERC721_zeroRemoteToken_reverts() external {\n // Try to create a token with a zero remote token address.\n vm.expectRevert(\"OptimismMintableERC721Factory: L1 token address cannot be address(0)\");\n factory.createOptimismMintableERC721(address(0), \"L2Token\", \"L2T\");\n }\n}\n" - }, - "contracts/test/OptimismPortal.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { Portal_Initializer, CommonTest, NextImpl } from \"./CommonTest.t.sol\";\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { L2OutputOracle } from \"../L1/L2OutputOracle.sol\";\nimport { OptimismPortal } from \"../L1/OptimismPortal.sol\";\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\ncontract OptimismPortal_Test is Portal_Initializer {\n event Paused(address);\n event Unpaused(address);\n\n function test_constructor_succeeds() external {\n assertEq(address(op.L2_ORACLE()), address(oracle));\n assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD);\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be paused by the GUARDIAN\n */\n function test_pause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n assertEq(op.paused(), false);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Paused(guardian);\n\n vm.prank(guardian);\n op.pause();\n\n assertEq(op.paused(), true);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not the\n * GUARDIAN calls `pause()`\n */\n function test_pause_onlyGuardian_reverts() external {\n assertEq(op.paused(), false);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can pause\");\n vm.prank(alice);\n op.pause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal can be unpaused by the GUARDIAN\n */\n function test_unpause_succeeds() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n vm.expectEmit(true, true, true, true, address(op));\n emit Unpaused(guardian);\n vm.prank(guardian);\n op.unpause();\n\n assertEq(op.paused(), false);\n }\n\n /**\n * @notice The OptimismPortal reverts when an account that is not\n * the GUARDIAN calls `unpause()`\n */\n function test_unpause_onlyGuardian_reverts() external {\n address guardian = op.GUARDIAN();\n\n vm.prank(guardian);\n op.pause();\n assertEq(op.paused(), true);\n\n assertTrue(op.GUARDIAN() != alice);\n vm.expectRevert(\"OptimismPortal: only guardian can unpause\");\n vm.prank(alice);\n op.unpause();\n\n assertEq(op.paused(), true);\n }\n\n function test_receive_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex\"\");\n\n // give alice money and send as an eoa\n vm.deal(alice, 2**64);\n vm.prank(alice, alice);\n (bool s, ) = address(op).call{ value: 100 }(hex\"\");\n\n assert(s);\n assertEq(address(op).balance, 100);\n }\n\n // Test: depositTransaction fails when contract creation has a non-zero destination address\n function test_depositTransaction_contractCreation_reverts() external {\n // contract creation must have a target of address(0)\n vm.expectRevert(\"OptimismPortal: must send to address(0) when creating a contract\");\n op.depositTransaction(address(1), 1, 0, true, hex\"\");\n }\n\n /**\n * @notice Prevent gasless deposits from being force processed in L2 by\n * ensuring that they have a large enough gas limit set.\n */\n function test_depositTransaction_smallGasLimit_reverts() external {\n vm.expectRevert(\"OptimismPortal: gas limit must cover instrinsic gas cost\");\n op.depositTransaction({\n _to: address(1),\n _value: 0,\n _gasLimit: 0,\n _isCreation: false,\n _data: hex\"\"\n });\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a tx with 0 value\n function test_depositTransaction_noValueEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a tx with 0 value\n function test_depositTransaction_noValueContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should emit the correct log when an EOA deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should emit the correct log when a contract deposits a contract creation with 0 value\n function test_depositTransaction_createWithZeroValueForContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA);\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromEOA_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a transaction with ETH\n function test_depositTransaction_withEthValueFromContract_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n NON_ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n NON_ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n false,\n NON_ZERO_DATA\n );\n }\n\n // Test: depositTransaction should increase its eth balance when an EOA deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() external {\n // EOA emulation\n vm.prank(address(this), address(this));\n\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n address(this),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n hex\"\"\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n // Test: depositTransaction should increase its eth balance when a contract deposits a contract creation with ETH\n function test_depositTransaction_withEthValueAndContractContractCreation_succeeds() external {\n vm.expectEmit(true, true, false, true);\n emitTransactionDeposited(\n AddressAliasHelper.applyL1ToL2Alias(address(this)),\n ZERO_ADDRESS,\n NON_ZERO_VALUE,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n\n op.depositTransaction{ value: NON_ZERO_VALUE }(\n ZERO_ADDRESS,\n ZERO_VALUE,\n NON_ZERO_GASLIMIT,\n true,\n NON_ZERO_DATA\n );\n assertEq(address(op).balance, NON_ZERO_VALUE);\n }\n\n function test_simple_isOutputFinalized_succeeds() external {\n uint256 ts = block.timestamp;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))\n )\n );\n\n // warp to the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS());\n assertEq(op.isOutputFinalized(0), false);\n\n // warp past the finalization period\n vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n assertEq(op.isOutputFinalized(0), true);\n }\n\n function test_isOutputFinalized_succeeds() external {\n uint256 checkpoint = oracle.nextBlockNumber();\n uint256 nextOutputIndex = oracle.nextOutputIndex();\n vm.roll(checkpoint);\n vm.warp(oracle.computeL2Timestamp(checkpoint) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0);\n\n // warp to the final second of the finalization period\n uint256 finalizationHorizon = block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS();\n vm.warp(finalizationHorizon);\n // The checkpointed block should not be finalized until 1 second from now.\n assertEq(op.isOutputFinalized(nextOutputIndex), false);\n // Nor should a block after it\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n\n // warp past the finalization period\n vm.warp(finalizationHorizon + 1);\n // It should now be finalized.\n assertEq(op.isOutputFinalized(nextOutputIndex), true);\n // But not the block after it.\n vm.expectRevert(stdError.indexOOBError);\n assertEq(op.isOutputFinalized(nextOutputIndex + 1), false);\n }\n}\n\ncontract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.\n constructor() {\n super.setUp();\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n }\n\n // Get the system into a nice ready-to-use state.\n function setUp() public override {\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n\n // Utility function used in the subsequent test. This is necessary to assert that the\n // reentrant call will revert.\n function callPortalAndExpectRevert() external payable {\n vm.expectRevert(\"OptimismPortal: can only trigger one withdrawal per transaction\");\n // Arguments here don't matter, as the require check is the first thing that happens.\n // We assume that this has already been proven.\n op.finalizeWithdrawalTransaction(_defaultTx);\n // Assert that the withdrawal was not finalized.\n assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));\n }\n\n /**\n * @notice Proving withdrawal transactions should revert when paused\n */\n function test_proveWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.proveWithdrawalTransaction({\n _tx: _defaultTx,\n _l2OutputIndex: _proposedOutputIndex,\n _outputRootProof: _outputRootProof,\n _withdrawalProof: _withdrawalProof\n });\n }\n\n // Test: proveWithdrawalTransaction cannot prove a withdrawal with itself (the OptimismPortal) as the target.\n function test_proveWithdrawalTransaction_onSelfCall_reverts() external {\n _defaultTx.target = address(op);\n vm.expectRevert(\"OptimismPortal: you cannot send messages to the portal contract\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the outputRootProof does not match the output root\n function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external {\n // Modify the version to invalidate the withdrawal proof.\n _outputRootProof.version = bytes32(uint256(1));\n vm.expectRevert(\"OptimismPortal: invalid output root proof\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the proof is invalid due to non-existence of\n // the withdrawal.\n function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external {\n // modify the default test values to invalidate the proof.\n _defaultTx.data = hex\"abcd\";\n vm.expectRevert(\"MerkleTrie: path remainder must share all nibbles with key\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction reverts if the passed transaction's withdrawalHash has\n // already been proven.\n function test_proveWithdrawalTransaction_replayProve_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: withdrawal hash has already been proven\");\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root has changed AND the l2BlockNumber stays the same.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in the OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a different output root within the `provenWithdrawals` mapping without\n // touching the l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds if the passed transaction's withdrawalHash has\n // already been proven AND the output root + output index + l2BlockNumber changes.\n function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds()\n external\n {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`\n // inside of the `provenWithdrawal`s mapping.\n bytes32 slot;\n assembly {\n mstore(0x00, sload(_withdrawalHash.slot))\n mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in OptimismPortal\n slot := keccak256(0x00, 0x40)\n }\n\n // Store a dummy output root within the `provenWithdrawals` mapping without touching the\n // l2BlockNumber or timestamp.\n vm.store(address(op), slot, bytes32(0));\n\n // Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle\n Types.OutputProposal memory proposal = op.L2_ORACLE().getL2Output(_proposedOutputIndex);\n\n // Propose the same output root again, creating the same output at a different index + l2BlockNumber.\n vm.startPrank(op.L2_ORACLE().PROPOSER());\n op.L2_ORACLE().proposeL2Output(\n proposal.outputRoot,\n op.L2_ORACLE().nextBlockNumber(),\n blockhash(block.number),\n block.number\n );\n vm.stopPrank();\n\n // Warp ahead 1 second\n vm.warp(block.timestamp + 1);\n\n // Even though we have already proven this withdrawalHash, we should be allowed to re-submit\n // our proof with a changed outputRoot + a different output index\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex + 1,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Ensure that the withdrawal was updated within the mapping\n (, uint128 timestamp, ) = op.provenWithdrawals(_withdrawalHash);\n assertEq(timestamp, block.timestamp);\n }\n\n // Test: proveWithdrawalTransaction succeeds and emits the WithdrawalProven event.\n function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n }\n\n // Test: finalizeWithdrawalTransaction succeeds and emits the WithdrawalFinalized event.\n function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, false, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore + 100);\n }\n\n /**\n * @notice Finalizing withdrawal transactions should revert when paused\n */\n function test_finalizeWithdrawalTransaction_paused_reverts() external {\n vm.prank(op.GUARDIAN());\n op.pause();\n\n vm.expectRevert(\"OptimismPortal: paused\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has not been proven.\n function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectRevert(\"OptimismPortal: withdrawal has not been proven yet\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if withdrawal not proven long enough ago.\n function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Mock a call where the resulting output root is anything but the original output root. In\n // this case we just use bytes32(uint256(1)).\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(bytes32(uint256(1)), _proposedBlockNumber)\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the provenWithdrawal's timestamp is less\n // than the L2 output oracle's starting timestamp\n function test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a startingTimestamp change on the L2 Oracle\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSignature(\"startingTimestamp()\"),\n abi.encode(block.timestamp + 1)\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output root proven is not the same as the\n // output root at the time of finalization.\n function test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock an outputRoot change on the output proposal before attempting\n // to finalize the withdrawal.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n bytes32(uint256(0)),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\n \"OptimismPortal: output root proven is not the same as current output root\"\n );\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the output proposal's timestamp has\n // not passed the finalization period.\n function test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Prove our withdrawal\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp to after the finalization period\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Mock a timestamp change on the output proposal that has not passed the\n // finalization period.\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(block.timestamp + 1),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n // Attempt to finalize the withdrawal\n vm.expectRevert(\"OptimismPortal: output proposal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Ensure that bob's balance has remained the same\n assertEq(bobBalanceBefore, address(bob).balance);\n }\n\n // Test: finalizeWithdrawalTransaction fails because the target reverts,\n // and emits the WithdrawalFinalized event with success=false.\n function test_finalizeWithdrawalTransaction_targetFails_fails() external {\n uint256 bobBalanceBefore = address(bob).balance;\n vm.etch(bob, hex\"fe\"); // Contract with just the invalid opcode.\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, false);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the finalization period has not yet passed.\n function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external {\n // Setup the Oracle to return an output with a recent timestamp\n uint256 recentTimestamp = block.timestamp - 1000;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n _outputRoot,\n uint128(recentTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if the withdrawal has already been finalized.\n function test_finalizeWithdrawalTransaction_onReplay_reverts() external {\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(_withdrawalHash, alice, bob);\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(_withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if insufficient gas is supplied.\n function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external {\n // This number was identified through trial and error.\n uint256 gasLimit = 150_000;\n Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: gasLimit,\n data: hex\"\"\n });\n\n // Get updated proof inputs.\n (bytes32 stateRoot, bytes32 storageRoot, , , bytes[] memory withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(insufficientGasTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n Hashing.hashOutputRootProof(outputRootProof),\n uint128(block.timestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n op.proveWithdrawalTransaction(\n insufficientGasTx,\n _proposedOutputIndex,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectRevert(\"SafeCall: Not enough gas\");\n op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);\n }\n\n // Test: finalizeWithdrawalTransaction reverts if a sub-call attempts to finalize another\n // withdrawal.\n function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n // Copy and modify the default test values to attempt a reentrant call by first calling to\n // this contract's callPortalAndExpectRevert() function above.\n Types.WithdrawalTransaction memory _testTx = _defaultTx;\n _testTx.target = address(this);\n _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector);\n\n // Get modified proof inputs.\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_testTx);\n Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({\n version: bytes32(0),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(0)\n });\n\n // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp.\n uint256 finalizedTimestamp = block.timestamp - oracle.FINALIZATION_PERIOD_SECONDS() - 1;\n vm.mockCall(\n address(op.L2_ORACLE()),\n abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),\n abi.encode(\n Types.OutputProposal(\n outputRoot,\n uint128(finalizedTimestamp),\n uint128(_proposedBlockNumber)\n )\n )\n );\n\n vm.expectEmit(true, true, true, true);\n emit WithdrawalProven(withdrawalHash, alice, address(this));\n op.proveWithdrawalTransaction(\n _testTx,\n _proposedBlockNumber,\n outputRootProof,\n withdrawalProof\n );\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n vm.expectCall(address(this), _testTx.data);\n vm.expectEmit(true, true, true, true);\n emit WithdrawalFinalized(withdrawalHash, true);\n op.finalizeWithdrawalTransaction(_testTx);\n\n // Ensure that bob's balance was not changed by the reentrant call.\n assert(address(bob).balance == bobBalanceBefore);\n }\n\n function testDiff_finalizeWithdrawalTransaction_succeeds(\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) external {\n // Cannot call the optimism portal\n vm.assume(_target != address(op));\n // Total ETH supply is currently about 120M ETH.\n uint256 value = bound(_value, 0, 200_000_000 ether);\n uint256 gasLimit = bound(_gasLimit, 0, 50_000_000);\n uint256 nonce = messagePasser.messageNonce();\n Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({\n nonce: nonce,\n sender: _sender,\n target: _target,\n value: value,\n gasLimit: gasLimit,\n data: _data\n });\n (\n bytes32 stateRoot,\n bytes32 storageRoot,\n bytes32 outputRoot,\n bytes32 withdrawalHash,\n bytes[] memory withdrawalProof\n ) = ffi.getProveWithdrawalTransactionInputs(_tx);\n\n Types.OutputRootProof memory proof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: stateRoot,\n messagePasserStorageRoot: storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n\n // Ensure the values returned from ffi are correct\n assertEq(outputRoot, Hashing.hashOutputRootProof(proof));\n assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx));\n\n // Mock the call to the oracle\n vm.mockCall(\n address(oracle),\n abi.encodeWithSelector(oracle.getL2Output.selector),\n abi.encode(outputRoot, 0)\n );\n\n // Start the withdrawal, it must be initiated by the _sender and the\n // correct value must be passed along\n vm.deal(_tx.sender, _tx.value);\n vm.prank(_tx.sender);\n messagePasser.initiateWithdrawal{ value: _tx.value }(_tx.target, _tx.gasLimit, _tx.data);\n\n // Ensure that the sentMessages is correct\n assertEq(messagePasser.sentMessages(withdrawalHash), true);\n\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n op.proveWithdrawalTransaction(\n _tx,\n 100, // l2BlockNumber\n proof,\n withdrawalProof\n );\n }\n}\n\ncontract OptimismPortalUpgradeable_Test is Portal_Initializer {\n Proxy internal proxy;\n uint64 initialBlockNum;\n\n function setUp() public override {\n super.setUp();\n initialBlockNum = uint64(block.number);\n proxy = Proxy(payable(address(op)));\n }\n\n function test_params_initValuesOnProxy_succeeds() external {\n OptimismPortal p = OptimismPortal(payable(address(proxy)));\n\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = p.params();\n\n ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig();\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_initialize_cannotInitProxy_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(payable(proxy)).initialize(false);\n }\n\n function test_initialize_cannotInitImpl_reverts() external {\n vm.expectRevert(\"Initializable: contract is already initialized\");\n OptimismPortal(opImpl).initialize(false);\n }\n\n function test_upgradeToAndCall_upgrading_succeeds() external {\n // Check an unused slot before upgrading.\n bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21)));\n assertEq(bytes32(0), slot21Before);\n\n NextImpl nextImpl = new NextImpl();\n vm.startPrank(multisig);\n proxy.upgradeToAndCall(\n address(nextImpl),\n abi.encodeWithSelector(NextImpl.initialize.selector)\n );\n assertEq(proxy.implementation(), address(nextImpl));\n\n // Verify that the NextImpl contract initialized its values according as expected\n bytes32 slot21After = vm.load(address(op), bytes32(uint256(21)));\n bytes32 slot21Expected = NextImpl(address(op)).slot21Init();\n assertEq(slot21Expected, slot21After);\n }\n}\n" - }, - "contracts/test/Proxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\ncontract SimpleStorage {\n mapping(uint256 => uint256) internal store;\n\n function get(uint256 key) external payable returns (uint256) {\n return store[key];\n }\n\n function set(uint256 key, uint256 value) external payable {\n store[key] = value;\n }\n}\n\ncontract Clasher {\n function upgradeTo(address) external pure {\n revert(\"upgradeTo\");\n }\n}\n\ncontract Proxy_Test is Test {\n event Upgraded(address indexed implementation);\n event AdminChanged(address previousAdmin, address newAdmin);\n\n address alice = address(64);\n\n bytes32 internal constant IMPLEMENTATION_KEY =\n bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1);\n\n bytes32 internal constant OWNER_KEY = bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1);\n\n Proxy proxy;\n SimpleStorage simpleStorage;\n\n function setUp() external {\n // Deploy a proxy and simple storage contract as\n // the implementation\n proxy = new Proxy(alice);\n simpleStorage = new SimpleStorage();\n\n vm.prank(alice);\n proxy.upgradeTo(address(simpleStorage));\n }\n\n function test_implementationKey_succeeds() external {\n // The hardcoded implementation key should be correct\n vm.prank(alice);\n proxy.upgradeTo(address(6));\n\n bytes32 key = vm.load(address(proxy), IMPLEMENTATION_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(6));\n }\n\n function test_ownerKey_succeeds() external {\n // The hardcoded owner key should be correct\n vm.prank(alice);\n proxy.changeAdmin(address(6));\n\n bytes32 key = vm.load(address(proxy), OWNER_KEY);\n assertEq(address(6), Bytes32AddressLib.fromLast20Bytes(key));\n\n vm.prank(address(6));\n address owner = proxy.admin();\n assertEq(owner, address(6));\n }\n\n function test_proxyCallToImp_notAdmin_succeeds() external {\n // The implementation does not have a `upgradeTo`\n // method, calling `upgradeTo` not as the owner\n // should revert.\n vm.expectRevert();\n proxy.upgradeTo(address(64));\n\n // Call `upgradeTo` as the owner, it should succeed\n // and emit the `Upgraded` event.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(64));\n vm.prank(alice);\n proxy.upgradeTo(address(64));\n\n // Get the implementation as the owner\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(64));\n }\n\n function test_ownerProxyCall_notAdmin_succeeds() external {\n // Calling `changeAdmin` not as the owner should revert\n // as the implementation does not have a `changeAdmin` method.\n vm.expectRevert();\n proxy.changeAdmin(address(1));\n\n // Call `changeAdmin` as the owner, it should succeed\n // and emit the `AdminChanged` event.\n vm.expectEmit(true, true, true, true);\n emit AdminChanged(alice, address(1));\n vm.prank(alice);\n proxy.changeAdmin(address(1));\n\n // Calling `admin` not as the owner should\n // revert as the implementation does not have\n // a `admin` method.\n vm.expectRevert();\n proxy.admin();\n\n // Calling `admin` as the owner should work.\n vm.prank(address(1));\n address owner = proxy.admin();\n assertEq(owner, address(1));\n }\n\n function test_delegatesToImpl_succeeds() external {\n // Call the storage setter on the proxy\n SimpleStorage(address(proxy)).set(1, 1);\n\n // The key should not be set in the implementation\n uint256 result = simpleStorage.get(1);\n assertEq(result, 0);\n {\n // The key should be set in the proxy\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n\n {\n // The owner should be able to call through the proxy\n // when there is not a function selector crash\n vm.prank(alice);\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 1);\n }\n }\n\n function test_upgradeToAndCall_succeeds() external {\n {\n // There should be nothing in the current proxy storage\n uint256 expect = SimpleStorage(address(proxy)).get(1);\n assertEq(expect, 0);\n }\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call.\n vm.expectEmit(true, true, true, true);\n emit Upgraded(address(simpleStorage));\n vm.prank(alice);\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The call should have impacted the state\n uint256 result = SimpleStorage(address(proxy)).get(1);\n assertEq(result, 1);\n }\n\n function test_upgradeToAndCall_functionDoesNotExist_reverts() external {\n // Get the current implementation address\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // Deploy a new SimpleStorage\n simpleStorage = new SimpleStorage();\n\n // Set the new SimpleStorage as the implementation\n // and call. This reverts because the calldata doesn't\n // match a function on the implementation.\n vm.expectRevert(\"Proxy: delegatecall to new implementation contract failed\");\n vm.prank(alice);\n proxy.upgradeToAndCall(address(simpleStorage), hex\"\");\n\n // The implementation address should have not\n // updated because the call to `upgradeToAndCall`\n // reverted.\n vm.prank(alice);\n address postImpl = proxy.implementation();\n assertEq(impl, postImpl);\n\n // The attempt to `upgradeToAndCall`\n // should revert when it is not called by the owner.\n vm.expectRevert();\n proxy.upgradeToAndCall(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n }\n\n function test_upgradeToAndCall_isPayable_succeeds() external {\n // Give alice some funds\n vm.deal(alice, 1 ether);\n // Set the implementation and call and send\n // value.\n vm.prank(alice);\n proxy.upgradeToAndCall{ value: 1 ether }(\n address(simpleStorage),\n abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)\n );\n\n // The implementation address should be correct\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n\n // The proxy should have a balance\n assertEq(address(proxy).balance, 1 ether);\n }\n\n function test_upgradeTo_clashingFunctionSignatures_succeeds() external {\n // Clasher has a clashing function with the proxy.\n Clasher clasher = new Clasher();\n\n // Set the clasher as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(clasher));\n\n {\n // Assert that the implementation was set properly.\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(clasher));\n }\n\n // Call the clashing function on the proxy\n // not as the owner so that the call passes through.\n // The implementation will revert so we can be\n // sure that the call passed through.\n vm.expectRevert(bytes(\"upgradeTo\"));\n proxy.upgradeTo(address(0));\n\n {\n // Now call the clashing function as the owner\n // and be sure that it doesn't pass through to\n // the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n vm.prank(alice);\n address impl = proxy.implementation();\n assertEq(impl, address(0));\n }\n }\n\n // Allow for `eth_call` to call proxy methods\n // by setting \"from\" to `address(0)`.\n function test_implementation_zeroAddressCaller_succeeds() external {\n vm.prank(address(0));\n address impl = proxy.implementation();\n assertEq(impl, address(simpleStorage));\n }\n\n function test_implementation_isZeroAddress_reverts() external {\n // Set `address(0)` as the implementation.\n vm.prank(alice);\n proxy.upgradeTo(address(0));\n\n (bool success, bytes memory returndata) = address(proxy).call(hex\"\");\n assertEq(success, false);\n\n bytes memory err = abi.encodeWithSignature(\n \"Error(string)\",\n \"Proxy: implementation not initialized\"\n );\n\n assertEq(returndata, err);\n }\n}\n" - }, - "contracts/test/ProxyAdmin.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { ProxyAdmin } from \"../universal/ProxyAdmin.sol\";\nimport { SimpleStorage } from \"./Proxy.t.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\n\ncontract ProxyAdmin_Test is Test {\n address alice = address(64);\n\n Proxy proxy;\n L1ChugSplashProxy chugsplash;\n ResolvedDelegateProxy resolved;\n\n AddressManager addressManager;\n\n ProxyAdmin admin;\n\n SimpleStorage implementation;\n\n function setUp() external {\n // Deploy the proxy admin\n admin = new ProxyAdmin(alice);\n // Deploy the standard proxy\n proxy = new Proxy(address(admin));\n\n // Deploy the legacy L1ChugSplashProxy with the admin as the owner\n chugsplash = new L1ChugSplashProxy(address(admin));\n\n // Deploy the legacy AddressManager\n addressManager = new AddressManager();\n // The proxy admin must be the new owner of the address manager\n addressManager.transferOwnership(address(admin));\n // Deploy a legacy ResolvedDelegateProxy with the name `a`.\n // Whatever `a` is set to in AddressManager will be the address\n // that is used for the implementation.\n resolved = new ResolvedDelegateProxy(addressManager, \"a\");\n\n // Impersonate alice for setting up the admin.\n vm.startPrank(alice);\n // Set the address of the address manager in the admin so that it\n // can resolve the implementation address of legacy\n // ResolvedDelegateProxy based proxies.\n admin.setAddressManager(addressManager);\n // Set the reverse lookup of the ResolvedDelegateProxy\n // proxy\n admin.setImplementationName(address(resolved), \"a\");\n\n // Set the proxy types\n admin.setProxyType(address(proxy), ProxyAdmin.ProxyType.ERC1967);\n admin.setProxyType(address(chugsplash), ProxyAdmin.ProxyType.CHUGSPLASH);\n admin.setProxyType(address(resolved), ProxyAdmin.ProxyType.RESOLVED);\n vm.stopPrank();\n\n implementation = new SimpleStorage();\n }\n\n function test_setImplementationName_succeeds() external {\n vm.prank(alice);\n admin.setImplementationName(address(1), \"foo\");\n assertEq(admin.implementationName(address(1)), \"foo\");\n }\n\n function test_setAddressManager_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setAddressManager(AddressManager((address(0))));\n }\n\n function test_setImplementationName_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setImplementationName(address(0), \"foo\");\n }\n\n function test_setProxyType_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.setProxyType(address(0), ProxyAdmin.ProxyType.CHUGSPLASH);\n }\n\n function test_owner_succeeds() external {\n assertEq(admin.owner(), alice);\n }\n\n function test_proxyType_succeeds() external {\n assertEq(uint256(admin.proxyType(address(proxy))), uint256(ProxyAdmin.ProxyType.ERC1967));\n assertEq(\n uint256(admin.proxyType(address(chugsplash))),\n uint256(ProxyAdmin.ProxyType.CHUGSPLASH)\n );\n assertEq(\n uint256(admin.proxyType(address(resolved))),\n uint256(ProxyAdmin.ProxyType.RESOLVED)\n );\n }\n\n function test_erc1967GetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(proxy));\n }\n\n function test_chugsplashGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyImplementation_succeeds() external {\n getProxyImplementation(payable(resolved));\n }\n\n function getProxyImplementation(address payable _proxy) internal {\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(0));\n }\n\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n {\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n }\n\n function test_erc1967GetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedGetProxyAdmin_succeeds() external {\n getProxyAdmin(payable(resolved));\n }\n\n function getProxyAdmin(address payable _proxy) internal {\n address owner = admin.getProxyAdmin(_proxy);\n assertEq(owner, address(admin));\n }\n\n function test_erc1967ChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(proxy));\n }\n\n function test_chugsplashChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(chugsplash));\n }\n\n function test_delegateResolvedChangeProxyAdmin_succeeds() external {\n changeProxyAdmin(payable(resolved));\n }\n\n function changeProxyAdmin(address payable _proxy) internal {\n ProxyAdmin.ProxyType proxyType = admin.proxyType(address(_proxy));\n\n vm.prank(alice);\n admin.changeProxyAdmin(_proxy, address(128));\n\n // The proxy is no longer the admin and can\n // no longer call the proxy interface except for\n // the ResolvedDelegate type on which anybody can\n // call the admin interface.\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n vm.expectRevert(\"Proxy: implementation not initialized\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n vm.expectRevert(\"L1ChugSplashProxy: implementation is not set yet\");\n admin.getProxyAdmin(_proxy);\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n // Just an empty block to show that all cases are covered\n } else {\n vm.expectRevert(\"ProxyAdmin: unknown proxy type\");\n }\n\n // Call the proxy contract directly to get the admin.\n // Different proxy types have different interfaces.\n vm.prank(address(128));\n if (proxyType == ProxyAdmin.ProxyType.ERC1967) {\n assertEq(Proxy(payable(_proxy)).admin(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.CHUGSPLASH) {\n assertEq(L1ChugSplashProxy(payable(_proxy)).getOwner(), address(128));\n } else if (proxyType == ProxyAdmin.ProxyType.RESOLVED) {\n assertEq(addressManager.owner(), address(128));\n } else {\n assert(false);\n }\n }\n\n function test_erc1967Upgrade_succeeds() external {\n upgrade(payable(proxy));\n }\n\n function test_chugsplashUpgrade_succeeds() external {\n upgrade(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgrade_succeeds() external {\n upgrade(payable(resolved));\n }\n\n function upgrade(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgrade(_proxy, address(implementation));\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n }\n\n function test_erc1967UpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(proxy));\n }\n\n function test_chugsplashUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(chugsplash));\n }\n\n function test_delegateResolvedUpgradeAndCall_succeeds() external {\n upgradeAndCall(payable(resolved));\n }\n\n function upgradeAndCall(address payable _proxy) internal {\n vm.prank(alice);\n admin.upgradeAndCall(\n _proxy,\n address(implementation),\n abi.encodeWithSelector(SimpleStorage.set.selector, 1, 1)\n );\n\n address impl = admin.getProxyImplementation(_proxy);\n assertEq(impl, address(implementation));\n\n uint256 got = SimpleStorage(address(_proxy)).get(1);\n assertEq(got, 1);\n }\n\n function test_onlyOwner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.changeProxyAdmin(payable(proxy), address(0));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgrade(payable(proxy), address(implementation));\n\n vm.expectRevert(\"Ownable: caller is not the owner\");\n admin.upgradeAndCall(payable(proxy), address(implementation), hex\"\");\n }\n\n function test_isUpgrading_succeeds() external {\n assertEq(false, admin.isUpgrading());\n\n vm.prank(alice);\n admin.setUpgrading(true);\n assertEq(true, admin.isUpgrading());\n }\n}\n" - }, - "contracts/test/RLP.t.sol": { - "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\nimport { Bytes32AddressLib } from \"@rari-capital/solmate/src/utils/Bytes32AddressLib.sol\";\n\n/**\n * @title LibRLP\n * @notice Via https://github.com/Rari-Capital/solmate/issues/207.\n */\nlibrary LibRLP {\n using Bytes32AddressLib for bytes32;\n\n function computeAddress(address deployer, uint256 nonce) internal pure returns (address) {\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))\n .fromLast20Bytes();\n if (nonce <= 0x7f)\n return\n keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))\n .fromLast20Bytes();\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= type(uint8).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd7),\n bytes1(0x94),\n deployer,\n bytes1(0x81),\n uint8(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint16).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd8),\n bytes1(0x94),\n deployer,\n bytes1(0x82),\n uint16(nonce)\n )\n ).fromLast20Bytes();\n if (nonce <= type(uint24).max)\n return\n keccak256(\n abi.encodePacked(\n bytes1(0xd9),\n bytes1(0x94),\n deployer,\n bytes1(0x83),\n uint24(nonce)\n )\n ).fromLast20Bytes();\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return\n keccak256(\n abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))\n ).fromLast20Bytes();\n }\n}\n" - }, - "contracts/test/RLPReader.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { stdError } from \"forge-std/Test.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { RLPReader } from \"../libraries/rlp/RLPReader.sol\";\n\ncontract RLPReader_readBytes_Test is CommonTest {\n function test_readBytes_bytestring00_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"00\"), hex\"00\");\n }\n\n function test_readBytes_bytestring01_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"01\"), hex\"01\");\n }\n\n function test_readBytes_bytestring7f_succeeds() external {\n assertEq(RLPReader.readBytes(hex\"7f\"), hex\"7f\");\n }\n\n function test_readBytes_revertListItem_reverts() external {\n vm.expectRevert(\"RLPReader: decoded item type for bytes is not a data item\");\n RLPReader.readBytes(hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_readBytes_invalidStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of string length (long string)\"\n );\n RLPReader.readBytes(hex\"b9\");\n }\n\n function test_readBytes_invalidListLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be > than length of list length (long list)\"\n );\n RLPReader.readBytes(hex\"ff\");\n }\n\n function test_readBytes_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: bytes value contains an invalid remainder\");\n RLPReader.readBytes(hex\"800a\");\n }\n\n function test_readBytes_invalidPrefix_reverts() external {\n vm.expectRevert(\n \"RLPReader: invalid prefix, single byte < 0x80 are not prefixed (short string)\"\n );\n RLPReader.readBytes(hex\"810a\");\n }\n}\n\ncontract RLPReader_readList_Test is CommonTest {\n function test_readList_empty_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c0\");\n assertEq(list.length, 0);\n }\n\n function test_readList_multiList_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c6827a77c10401\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"827a77\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c104\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"01\");\n }\n\n function test_readList_shortListMax1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n\n assertEq(list.length, 11);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[4]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[5]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[6]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[7]), hex\"8471776572\");\n assertEq(RLPReader.readRawBytes(list[8]), hex\"847a786376\");\n assertEq(RLPReader.readRawBytes(list[9]), hex\"8461736466\");\n assertEq(RLPReader.readRawBytes(list[10]), hex\"8471776572\");\n }\n\n function test_readList_longList1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n\n assertEq(list.length, 4);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"cf84617364668471776572847a786376\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"cf84617364668471776572847a786376\");\n }\n\n function test_readList_longList2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n assertEq(list.length, 32);\n\n for (uint256 i = 0; i < 32; i++) {\n assertEq(RLPReader.readRawBytes(list[i]), hex\"cf84617364668471776572847a786376\");\n }\n }\n\n function test_readList_listLongerThan32Elements_reverts() external {\n vm.expectRevert(stdError.indexOOBError);\n RLPReader.readList(\n hex\"e1454545454545454545454545454545454545454545454545454545454545454545\"\n );\n }\n\n function test_readList_listOfLists_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c4c2c0c0c0\");\n assertEq(list.length, 2);\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c2c0c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c0\");\n }\n\n function test_readList_listOfLists2_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(hex\"c7c0c1c0c3c0c1c0\");\n assertEq(list.length, 3);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"c0\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"c1c0\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"c3c0c1c0\");\n }\n\n function test_readList_dictTest1_succeeds() external {\n RLPReader.RLPItem[] memory list = RLPReader.readList(\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n assertEq(list.length, 4);\n\n assertEq(RLPReader.readRawBytes(list[0]), hex\"ca846b6579318476616c31\");\n assertEq(RLPReader.readRawBytes(list[1]), hex\"ca846b6579328476616c32\");\n assertEq(RLPReader.readRawBytes(list[2]), hex\"ca846b6579338476616c33\");\n assertEq(RLPReader.readRawBytes(list[3]), hex\"ca846b6579348476616c34\");\n }\n\n function test_readList_invalidShortList_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efdebd\");\n }\n\n function test_readList_longStringLength_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(hex\"efb83600\");\n }\n\n function test_readList_notLongEnough_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than list length (short list)\"\n );\n RLPReader.readList(\n hex\"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n );\n }\n\n function test_readList_int32Overflow_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"bf0f000000000000021111\");\n }\n\n function test_readList_int32Overflow2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ff0f000000000000021111\");\n }\n\n function test_readList_incorrectLengthInArray_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(\n hex\"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_leadingZerosInLongLengthArray2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must not have any leading zeros (long string)\"\n );\n RLPReader.readList(hex\"b800\");\n }\n\n function test_readList_leadingZerosInLongLengthList1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must not have any leading zeros (long list)\");\n RLPReader.readList(\n hex\"fb00000040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\"\n );\n }\n\n function test_readList_nonOptimalLongLengthArray1_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b81000112233445566778899aabbccddeeff\");\n }\n\n function test_readList_nonOptimalLongLengthArray2_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b801ff\");\n }\n\n function test_readList_invalidValue_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than string length (short string)\"\n );\n RLPReader.readList(hex\"91\");\n }\n\n function test_readList_invalidRemainder_reverts() external {\n vm.expectRevert(\"RLPReader: list item has an invalid data remainder\");\n RLPReader.readList(hex\"c000\");\n }\n\n function test_readList_notEnoughContentForString1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"ba010000aabbccddeeff\");\n }\n\n function test_readList_notEnoughContentForString2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long string)\"\n );\n RLPReader.readList(hex\"b840ffeeddccbbaa99887766554433221100\");\n }\n\n function test_readList_notEnoughContentForList1_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"f90180\");\n }\n\n function test_readList_notEnoughContentForList2_reverts() external {\n vm.expectRevert(\n \"RLPReader: length of content must be greater than total length (long list)\"\n );\n RLPReader.readList(hex\"ffffffffffffffffff0001020304050607\");\n }\n\n function test_readList_longStringLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long string)\");\n RLPReader.readList(hex\"b80100\");\n }\n\n function test_readList_longListLessThan56Bytes_reverts() external {\n vm.expectRevert(\"RLPReader: length of content must be greater than 55 bytes (long list)\");\n RLPReader.readList(hex\"f80100\");\n }\n}\n" - }, - "contracts/test/RLPWriter.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { RLPWriter } from \"../libraries/rlp/RLPWriter.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\n\ncontract RLPWriter_writeString_Test is CommonTest {\n function test_writeString_empty_succeeds() external {\n assertEq(RLPWriter.writeString(\"\"), hex\"80\");\n }\n\n function test_writeString_bytestring00_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0000\"), hex\"00\");\n }\n\n function test_writeString_bytestring01_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u0001\"), hex\"01\");\n }\n\n function test_writeString_bytestring7f_succeeds() external {\n assertEq(RLPWriter.writeString(\"\\u007F\"), hex\"7f\");\n }\n\n function test_writeString_shortstring_succeeds() external {\n assertEq(RLPWriter.writeString(\"dog\"), hex\"83646f67\");\n }\n\n function test_writeString_shortstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing eli\"),\n hex\"b74c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69\"\n );\n }\n\n function test_writeString_longstring_succeeds() external {\n assertEq(\n RLPWriter.writeString(\"Lorem ipsum dolor sit amet, consectetur adipisicing elit\"),\n hex\"b8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974\"\n );\n }\n\n function test_writeString_longstring2_succeeds() external {\n assertEq(\n RLPWriter.writeString(\n \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat\"\n ),\n hex\"b904004c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742e20437572616269747572206d6175726973206d61676e612c20737573636970697420736564207665686963756c61206e6f6e2c20696163756c697320666175636962757320746f72746f722e2050726f696e20737573636970697420756c74726963696573206d616c6573756164612e204475697320746f72746f7220656c69742c2064696374756d2071756973207472697374697175652065752c20756c7472696365732061742072697375732e204d6f72626920612065737420696d70657264696574206d6920756c6c616d636f7270657220616c6971756574207375736369706974206e6563206c6f72656d2e2041656e65616e2071756973206c656f206d6f6c6c69732c2076756c70757461746520656c6974207661726975732c20636f6e73657175617420656e696d2e204e756c6c6120756c74726963657320747572706973206a7573746f2c20657420706f73756572652075726e6120636f6e7365637465747572206e65632e2050726f696e206e6f6e20636f6e76616c6c6973206d657475732e20446f6e65632074656d706f7220697073756d20696e206d617572697320636f6e67756520736f6c6c696369747564696e2e20566573746962756c756d20616e746520697073756d207072696d697320696e206661756369627573206f726369206c756374757320657420756c74726963657320706f737565726520637562696c69612043757261653b2053757370656e646973736520636f6e76616c6c69732073656d2076656c206d617373612066617563696275732c2065676574206c6163696e6961206c616375732074656d706f722e204e756c6c61207175697320756c747269636965732070757275732e2050726f696e20617563746f722072686f6e637573206e69626820636f6e64696d656e74756d206d6f6c6c69732e20416c697175616d20636f6e73657175617420656e696d206174206d65747573206c75637475732c206120656c656966656e6420707572757320656765737461732e20437572616269747572206174206e696268206d657475732e204e616d20626962656e64756d2c206e6571756520617420617563746f72207472697374697175652c206c6f72656d206c696265726f20616c697175657420617263752c206e6f6e20696e74657264756d2074656c6c7573206c65637475732073697420616d65742065726f732e20437261732072686f6e6375732c206d65747573206163206f726e617265206375727375732c20646f6c6f72206a7573746f20756c747269636573206d657475732c20617420756c6c616d636f7270657220766f6c7574706174\"\n );\n }\n}\n\ncontract RLPWriter_writeUint_Test is CommonTest {\n function test_writeUint_zero_succeeds() external {\n assertEq(RLPWriter.writeUint(0x0), hex\"80\");\n }\n\n function test_writeUint_smallint_succeeds() external {\n assertEq(RLPWriter.writeUint(1), hex\"01\");\n }\n\n function test_writeUint_smallint2_succeeds() external {\n assertEq(RLPWriter.writeUint(16), hex\"10\");\n }\n\n function test_writeUint_smallint3_succeeds() external {\n assertEq(RLPWriter.writeUint(79), hex\"4f\");\n }\n\n function test_writeUint_smallint4_succeeds() external {\n assertEq(RLPWriter.writeUint(127), hex\"7f\");\n }\n\n function test_writeUint_mediumint_succeeds() external {\n assertEq(RLPWriter.writeUint(128), hex\"8180\");\n }\n\n function test_writeUint_mediumint2_succeeds() external {\n assertEq(RLPWriter.writeUint(1000), hex\"8203e8\");\n }\n\n function test_writeUint_mediumint3_succeeds() external {\n assertEq(RLPWriter.writeUint(100000), hex\"830186a0\");\n }\n}\n\ncontract RLPWriter_writeList_Test is CommonTest {\n function test_writeList_empty_succeeds() external {\n assertEq(RLPWriter.writeList(new bytes[](0)), hex\"c0\");\n }\n\n function test_writeList_stringList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeString(\"dog\");\n list[1] = RLPWriter.writeString(\"god\");\n list[2] = RLPWriter.writeString(\"cat\");\n\n assertEq(RLPWriter.writeList(list), hex\"cc83646f6783676f6483636174\");\n }\n\n function test_writeList_multiList_succeeds() external {\n bytes[] memory list = new bytes[](3);\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeUint(4);\n\n list[0] = RLPWriter.writeString(\"zw\");\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeUint(1);\n\n assertEq(RLPWriter.writeList(list), hex\"c6827a77c10401\");\n }\n\n function test_writeList_shortListMax1_succeeds() external {\n bytes[] memory list = new bytes[](11);\n list[0] = RLPWriter.writeString(\"asdf\");\n list[1] = RLPWriter.writeString(\"qwer\");\n list[2] = RLPWriter.writeString(\"zxcv\");\n list[3] = RLPWriter.writeString(\"asdf\");\n list[4] = RLPWriter.writeString(\"qwer\");\n list[5] = RLPWriter.writeString(\"zxcv\");\n list[6] = RLPWriter.writeString(\"asdf\");\n list[7] = RLPWriter.writeString(\"qwer\");\n list[8] = RLPWriter.writeString(\"zxcv\");\n list[9] = RLPWriter.writeString(\"asdf\");\n list[10] = RLPWriter.writeString(\"qwer\");\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572\"\n );\n }\n\n function test_writeList_longlist1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list2);\n list[3] = RLPWriter.writeList(list2);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_longlist2_succeeds() external {\n bytes[] memory list = new bytes[](32);\n bytes[] memory list2 = new bytes[](3);\n\n list2[0] = RLPWriter.writeString(\"asdf\");\n list2[1] = RLPWriter.writeString(\"qwer\");\n list2[2] = RLPWriter.writeString(\"zxcv\");\n\n for (uint256 i = 0; i < 32; i++) {\n list[i] = RLPWriter.writeList(list2);\n }\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"f90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376\"\n );\n }\n\n function test_writeList_listoflists_succeeds() external {\n // [ [ [], [] ], [] ]\n bytes[] memory list = new bytes[](2);\n bytes[] memory list2 = new bytes[](2);\n\n list2[0] = RLPWriter.writeList(new bytes[](0));\n list2[1] = RLPWriter.writeList(new bytes[](0));\n\n list[0] = RLPWriter.writeList(list2);\n list[1] = RLPWriter.writeList(new bytes[](0));\n\n assertEq(RLPWriter.writeList(list), hex\"c4c2c0c0c0\");\n }\n\n function test_writeList_listoflists2_succeeds() external {\n // [ [], [[]], [ [], [[]] ] ]\n bytes[] memory list = new bytes[](3);\n list[0] = RLPWriter.writeList(new bytes[](0));\n\n bytes[] memory list2 = new bytes[](1);\n list2[0] = RLPWriter.writeList(new bytes[](0));\n\n list[1] = RLPWriter.writeList(list2);\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeList(new bytes[](0));\n list3[1] = RLPWriter.writeList(list2);\n\n list[2] = RLPWriter.writeList(list3);\n\n assertEq(RLPWriter.writeList(list), hex\"c7c0c1c0c3c0c1c0\");\n }\n\n function test_writeList_dictTest1_succeeds() external {\n bytes[] memory list = new bytes[](4);\n\n bytes[] memory list1 = new bytes[](2);\n list1[0] = RLPWriter.writeString(\"key1\");\n list1[1] = RLPWriter.writeString(\"val1\");\n\n bytes[] memory list2 = new bytes[](2);\n list2[0] = RLPWriter.writeString(\"key2\");\n list2[1] = RLPWriter.writeString(\"val2\");\n\n bytes[] memory list3 = new bytes[](2);\n list3[0] = RLPWriter.writeString(\"key3\");\n list3[1] = RLPWriter.writeString(\"val3\");\n\n bytes[] memory list4 = new bytes[](2);\n list4[0] = RLPWriter.writeString(\"key4\");\n list4[1] = RLPWriter.writeString(\"val4\");\n\n list[0] = RLPWriter.writeList(list1);\n list[1] = RLPWriter.writeList(list2);\n list[2] = RLPWriter.writeList(list3);\n list[3] = RLPWriter.writeList(list4);\n\n assertEq(\n RLPWriter.writeList(list),\n hex\"ecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34\"\n );\n }\n}\n" - }, - "contracts/test/ResolvedDelegateProxy.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { ResolvedDelegateProxy } from \"../legacy/ResolvedDelegateProxy.sol\";\n\ncontract ResolvedDelegateProxy_Test is Test {\n AddressManager internal addressManager;\n SimpleImplementation internal impl;\n SimpleImplementation internal proxy;\n\n function setUp() public {\n // Set up the address manager.\n addressManager = new AddressManager();\n impl = new SimpleImplementation();\n addressManager.setAddress(\"SimpleImplementation\", address(impl));\n\n // Set up the proxy.\n proxy = SimpleImplementation(\n address(new ResolvedDelegateProxy(addressManager, \"SimpleImplementation\"))\n );\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall succeeds.\n function testFuzz_fallback_delegateCallFoo_succeeds(uint256 x) public {\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.foo.selector, x));\n assertEq(proxy.foo(x), x);\n }\n\n // Tests that the proxy properly bubbles up returndata when the delegatecall reverts.\n function test_fallback_delegateCallBar_reverts() public {\n vm.expectRevert(\"SimpleImplementation: revert\");\n vm.expectCall(address(impl), abi.encodeWithSelector(impl.bar.selector));\n proxy.bar();\n }\n\n // Tests that the proxy fallback reverts as expected if the implementation within the\n // address manager is not set.\n function test_fallback_addressManagerNotSet_reverts() public {\n AddressManager am = new AddressManager();\n SimpleImplementation p = SimpleImplementation(\n address(new ResolvedDelegateProxy(am, \"SimpleImplementation\"))\n );\n\n vm.expectRevert(\"ResolvedDelegateProxy: target address must be initialized\");\n p.foo(0);\n }\n}\n\ncontract SimpleImplementation {\n function foo(uint256 _x) public pure returns (uint256) {\n return _x;\n }\n\n function bar() public pure {\n revert(\"SimpleImplementation: revert\");\n }\n}\n" - }, - "contracts/test/ResourceMetering.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract MeterUser is ResourceMetering {\n constructor() {\n initialize();\n }\n\n function initialize() public initializer {\n __ResourceMetering_init();\n }\n\n function resourceConfig() public pure returns (ResourceMetering.ResourceConfig memory) {\n return _resourceConfig();\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function use(uint64 _amount) public metered(_amount) {}\n\n function set(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) public {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n}\n\n/**\n * @title ResourceConfig\n * @notice The tests are based on the default config values. It is expected that\n * the config values used in these tests are ran in production.\n */\ncontract ResourceMetering_Test is Test {\n MeterUser internal meter;\n uint64 initialBlockNum;\n\n function setUp() public {\n meter = new MeterUser();\n initialBlockNum = uint64(block.number);\n }\n\n function test_meter_initialResourceParams_succeeds() external {\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n\n assertEq(prevBaseFee, rcfg.minimumBaseFee);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_updateParamsNoChange_succeeds() external {\n meter.use(0); // equivalent to just updating the base fee and block number\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n meter.use(0);\n (uint128 postBaseFee, uint64 postBoughtGas, uint64 postBlockNum) = meter.params();\n\n assertEq(postBaseFee, prevBaseFee);\n assertEq(postBoughtGas, prevBoughtGas);\n assertEq(postBlockNum, prevBlockNum);\n }\n\n function test_meter_updateOneEmptyBlock_succeeds() external {\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 1);\n }\n\n function test_meter_updateTwoEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 2);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 2);\n }\n\n function test_meter_updateTenEmptyBlocks_succeeds() external {\n vm.roll(initialBlockNum + 10);\n meter.use(0);\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1 gwei);\n assertEq(prevBoughtGas, 0);\n assertEq(prevBlockNum, initialBlockNum + 10);\n }\n\n function test_meter_updateNoGasDelta_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint256 target = uint256(rcfg.maxResourceLimit) / uint256(rcfg.elasticityMultiplier);\n meter.use(uint64(target));\n (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params();\n\n assertEq(prevBaseFee, 1000000000);\n assertEq(prevBoughtGas, target);\n assertEq(prevBlockNum, initialBlockNum);\n }\n\n function test_meter_useMax_succeeds() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n meter.use(target * elasticityMultiplier);\n\n (, uint64 prevBoughtGas, ) = meter.params();\n assertEq(prevBoughtGas, target * elasticityMultiplier);\n\n vm.roll(initialBlockNum + 1);\n meter.use(0);\n (uint128 postBaseFee, , ) = meter.params();\n assertEq(postBaseFee, 2125000000);\n }\n\n function test_meter_useMoreThanMax_reverts() external {\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.expectRevert(\"ResourceMetering: cannot buy more gas than available gas limit\");\n meter.use(target * elasticityMultiplier + 1);\n }\n\n // Demonstrates that the resource metering arithmetic can tolerate very large gaps between\n // deposits.\n function testFuzz_meter_largeBlockDiff_succeeds(uint64 _amount, uint256 _blockDiff) external {\n // This test fails if the following line is commented out.\n // At 12 seconds per block, this number is effectively unreachable.\n vm.assume(_blockDiff < 433576281058164217753225238677900874458691);\n\n ResourceMetering.ResourceConfig memory rcfg = meter.resourceConfig();\n uint64 target = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n uint64 elasticityMultiplier = uint64(rcfg.elasticityMultiplier);\n\n vm.assume(_amount < target * elasticityMultiplier);\n vm.roll(initialBlockNum + _blockDiff);\n meter.use(_amount);\n }\n}\n\n/**\n * @title CustomMeterUser\n * @notice A simple wrapper around `ResourceMetering` that allows the initial\n * params to be set in the constructor.\n */\ncontract CustomMeterUser is ResourceMetering {\n uint256 public startGas;\n uint256 public endGas;\n\n constructor(\n uint128 _prevBaseFee,\n uint64 _prevBoughtGas,\n uint64 _prevBlockNum\n ) {\n params = ResourceMetering.ResourceParams({\n prevBaseFee: _prevBaseFee,\n prevBoughtGas: _prevBoughtGas,\n prevBlockNum: _prevBlockNum\n });\n }\n\n function _resourceConfig()\n internal\n pure\n override\n returns (ResourceMetering.ResourceConfig memory)\n {\n return Constants.DEFAULT_RESOURCE_CONFIG();\n }\n\n function use(uint64 _amount) public returns (uint256) {\n uint256 initialGas = gasleft();\n _metered(_amount, initialGas);\n return initialGas - gasleft();\n }\n}\n\n/**\n * @title ArtifactResourceMetering_Test\n * @notice A table test that sets the state of the ResourceParams and then requests\n * various amounts of gas. This test ensures that a wide range of values\n * can safely be used with the `ResourceMetering` contract.\n * It also writes a CSV file to disk that includes useful information\n * about how much gas is used and how expensive it is in USD terms to\n * purchase the deposit gas.\n */\ncontract ArtifactResourceMetering_Test is Test {\n uint128 internal minimumBaseFee;\n uint128 internal maximumBaseFee;\n uint64 internal maxResourceLimit;\n uint64 internal targetResourceLimit;\n\n string internal outfile;\n\n // keccak256(abi.encodeWithSignature(\"Error(string)\", \"ResourceMetering: cannot buy more gas than available gas limit\"))\n bytes32 internal cannotBuyMoreGas =\n 0x84edc668cfd5e050b8999f43ff87a1faaa93e5f935b20bc1dd4d3ff157ccf429;\n // keccak256(abi.encodeWithSignature(\"Panic(uint256)\", 0x11))\n bytes32 internal overflowErr =\n 0x1ca389f2c8264faa4377de9ce8e14d6263ef29c68044a9272d405761bab2db27;\n // keccak256(hex\"\")\n bytes32 internal emptyReturnData =\n 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n\n /**\n * @notice Sets up the tests by getting constants from the ResourceMetering\n * contract.\n */\n function setUp() public {\n vm.roll(1_000_000);\n\n MeterUser base = new MeterUser();\n ResourceMetering.ResourceConfig memory rcfg = base.resourceConfig();\n minimumBaseFee = uint128(rcfg.minimumBaseFee);\n maximumBaseFee = rcfg.maximumBaseFee;\n maxResourceLimit = uint64(rcfg.maxResourceLimit);\n targetResourceLimit = uint64(rcfg.maxResourceLimit) / uint64(rcfg.elasticityMultiplier);\n\n outfile = string.concat(vm.projectRoot(), \"/.resource-metering.csv\");\n try vm.removeFile(outfile) {} catch {}\n }\n\n /**\n * @notice Generate a CSV file. The call to `meter` should be called with at\n * most the L1 block gas limit. Without specifying the amount of\n * gas, it can take very long to execute.\n */\n function test_meter_generateArtifact_succeeds() external {\n vm.writeLine(\n outfile,\n \"prevBaseFee,prevBoughtGas,prevBlockNumDiff,l1BaseFee,requestedGas,gasConsumed,ethPrice,usdCost,success\"\n );\n\n // prevBaseFee value in ResourceParams\n uint128[] memory prevBaseFees = new uint128[](5);\n prevBaseFees[0] = minimumBaseFee;\n prevBaseFees[1] = maximumBaseFee;\n prevBaseFees[2] = uint128(50 gwei);\n prevBaseFees[3] = uint128(100 gwei);\n prevBaseFees[4] = uint128(200 gwei);\n\n // prevBoughtGas value in ResourceParams\n uint64[] memory prevBoughtGases = new uint64[](1);\n prevBoughtGases[0] = uint64(0);\n\n // prevBlockNum diff, simulates blocks with no deposits when non zero\n uint64[] memory prevBlockNumDiffs = new uint64[](2);\n prevBlockNumDiffs[0] = 0;\n prevBlockNumDiffs[1] = 1;\n\n // The amount of L2 gas that a user requests\n uint64[] memory requestedGases = new uint64[](3);\n requestedGases[0] = maxResourceLimit;\n requestedGases[1] = targetResourceLimit;\n requestedGases[2] = uint64(100_000);\n\n // The L1 base fee\n uint256[] memory l1BaseFees = new uint256[](4);\n l1BaseFees[0] = 1 gwei;\n l1BaseFees[1] = 50 gwei;\n l1BaseFees[2] = 75 gwei;\n l1BaseFees[3] = 100 gwei;\n\n // USD price of 1 ether\n uint256[] memory ethPrices = new uint256[](2);\n ethPrices[0] = 1600;\n ethPrices[1] = 3200;\n\n // Iterate over all of the test values and run a test\n for (uint256 i; i < prevBaseFees.length; i++) {\n for (uint256 j; j < prevBoughtGases.length; j++) {\n for (uint256 k; k < prevBlockNumDiffs.length; k++) {\n for (uint256 l; l < requestedGases.length; l++) {\n for (uint256 m; m < l1BaseFees.length; m++) {\n for (uint256 n; n < ethPrices.length; n++) {\n uint256 snapshotId = vm.snapshot();\n\n uint128 prevBaseFee = prevBaseFees[i];\n uint64 prevBoughtGas = prevBoughtGases[j];\n uint64 prevBlockNumDiff = prevBlockNumDiffs[k];\n uint64 requestedGas = requestedGases[l];\n uint256 l1BaseFee = l1BaseFees[m];\n uint256 ethPrice = ethPrices[n];\n string memory result = \"success\";\n\n vm.fee(l1BaseFee);\n\n CustomMeterUser meter = new CustomMeterUser({\n _prevBaseFee: prevBaseFee,\n _prevBoughtGas: prevBoughtGas,\n _prevBlockNum: uint64(block.number)\n });\n\n vm.roll(block.number + prevBlockNumDiff);\n\n // Call the metering code and catch the various\n // types of errors.\n uint256 gasConsumed = 0;\n try meter.use{ gas: 30_000_000 }(requestedGas) returns (\n uint256 _gasConsumed\n ) {\n gasConsumed = _gasConsumed;\n } catch (bytes memory err) {\n bytes32 hash = keccak256(err);\n if (hash == cannotBuyMoreGas) {\n result = \"ResourceMetering: cannot buy more gas than available gas limit\";\n } else if (hash == overflowErr) {\n result = \"arithmetic overflow/underflow\";\n } else if (hash == emptyReturnData) {\n result = \"out of gas\";\n } else {\n result = \"UNKNOWN ERROR\";\n }\n }\n\n // Compute the USD cost of the gas used\n uint256 usdCost = (gasConsumed * l1BaseFee * ethPrice) / 1 ether;\n\n vm.writeLine(\n outfile,\n string.concat(\n vm.toString(prevBaseFee),\n \",\",\n vm.toString(prevBoughtGas),\n \",\",\n vm.toString(prevBlockNumDiff),\n \",\",\n vm.toString(l1BaseFee),\n \",\",\n vm.toString(requestedGas),\n \",\",\n vm.toString(gasConsumed),\n \",\",\n \"$\",\n vm.toString(ethPrice),\n \",\",\n \"$\",\n vm.toString(usdCost),\n \",\",\n result\n )\n );\n\n assertTrue(vm.revertTo(snapshotId));\n }\n }\n }\n }\n }\n }\n }\n}\n" - }, - "contracts/test/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\n\ncontract SafeCall_call_Test is CommonTest {\n function testFuzz_call_succeeds(\n address from,\n address to,\n uint256 gas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCall(to, value, data);\n vm.prank(from);\n bool success = SafeCall.call(to, gas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function testFuzz_callWithMinGas_hasEnough_succeeds(\n address from,\n address to,\n uint64 minGas,\n uint64 value,\n bytes memory data\n ) external {\n vm.assume(from.balance == 0);\n vm.assume(to.balance == 0);\n // no precompiles (mainnet)\n assumeNoPrecompiles(to, 1);\n // don't call the vm\n vm.assume(to != address(vm));\n vm.assume(from != address(vm));\n // don't call the console\n vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));\n // don't call the create2 deployer\n vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));\n\n assertEq(from.balance, 0, \"from balance is 0\");\n vm.deal(from, value);\n assertEq(from.balance, value, \"from balance not dealt\");\n\n // Bound minGas to [0, l1_block_gas_limit]\n minGas = uint64(bound(minGas, 0, 30_000_000));\n\n uint256[2] memory balancesBefore = [from.balance, to.balance];\n\n vm.expectCallMinGas(to, value, minGas, data);\n vm.prank(from);\n bool success = SafeCall.callWithMinGas(to, minGas, value, data);\n\n assertTrue(success, \"call not successful\");\n if (from == to) {\n assertEq(from.balance, balancesBefore[0], \"Self-send did not change balance\");\n } else {\n assertEq(from.balance, balancesBefore[0] - value, \"from balance not drained\");\n assertEq(to.balance, balancesBefore[1] + value, \"to balance received\");\n }\n }\n\n function test_callWithMinGas_noLeakageLow_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 5000; i < 50_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 26,071 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 26_071) {\n assertFalse(caller.makeSafeCall(i, 25_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 25_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 25_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n\n function test_callWithMinGas_noLeakageHigh_succeeds() external {\n SimpleSafeCaller caller = new SimpleSafeCaller();\n\n for (uint64 i = 15_200_000; i < 15_300_000; i++) {\n uint256 snapshot = vm.snapshot();\n\n // 15,238,769 is the exact amount of gas required to make the safe call\n // successfully.\n if (i < 15_238_769) {\n assertFalse(caller.makeSafeCall(i, 15_000_000));\n } else {\n vm.expectCallMinGas(\n address(caller),\n 0,\n 15_000_000,\n abi.encodeWithSelector(caller.setA.selector, 1)\n );\n assertTrue(caller.makeSafeCall(i, 15_000_000));\n }\n\n assertTrue(vm.revertTo(snapshot));\n }\n }\n}\n\ncontract SimpleSafeCaller {\n uint256 public a;\n\n function makeSafeCall(uint64 gas, uint64 minGas) external returns (bool) {\n return\n SafeCall.call(\n address(this),\n gas,\n 0,\n abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas)\n );\n }\n\n function makeSafeCallMinGas(uint64 minGas) external returns (bool) {\n return\n SafeCall.callWithMinGas(\n address(this),\n minGas,\n 0,\n abi.encodeWithSelector(this.setA.selector, 1)\n );\n }\n\n function setA(uint256 _a) external {\n a = _a;\n }\n}\n" - }, - "contracts/test/Semver.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { Proxy } from \"../universal/Proxy.sol\";\n\n/**\n * @notice Test the Semver contract that is used for semantic versioning\n * of various contracts.\n */\ncontract Semver_Test is CommonTest {\n /**\n * @notice Global semver contract deployed in setUp. This is used in\n * the test cases.\n */\n Semver semver;\n\n /**\n * @notice Deploy a Semver contract\n */\n function setUp() public virtual override {\n semver = new Semver(7, 8, 0);\n }\n\n /**\n * @notice Test the version getter\n */\n function test_version_succeeds() external {\n assertEq(semver.version(), \"7.8.0\");\n }\n\n /**\n * @notice Since the versions are all immutable, they should\n * be able to be accessed from behind a proxy without needing\n * to initialize the contract.\n */\n function test_behindProxy_succeeds() external {\n Proxy proxy = new Proxy(alice);\n vm.prank(alice);\n proxy.upgradeTo(address(semver));\n\n assertEq(Semver(address(proxy)).version(), \"7.8.0\");\n }\n}\n" - }, - "contracts/test/SequencerFeeVault.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Bridge_Initializer } from \"./CommonTest.t.sol\";\n\nimport { SequencerFeeVault } from \"../L2/SequencerFeeVault.sol\";\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\ncontract SequencerFeeVault_Test is Bridge_Initializer {\n SequencerFeeVault vault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET));\n address constant recipient = address(256);\n\n event Withdrawal(uint256 value, address to, address from);\n\n function setUp() public override {\n super.setUp();\n vm.etch(Predeploys.SEQUENCER_FEE_WALLET, address(new SequencerFeeVault(recipient)).code);\n vm.label(Predeploys.SEQUENCER_FEE_WALLET, \"SequencerFeeVault\");\n }\n\n function test_minWithdrawalAmount_succeeds() external {\n assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), 10 ether);\n }\n\n function test_constructor_succeeds() external {\n assertEq(vault.l1FeeWallet(), recipient);\n }\n\n function test_receive_succeeds() external {\n uint256 balance = address(vault).balance;\n\n vm.prank(alice);\n (bool success, ) = address(vault).call{ value: 100 }(hex\"\");\n\n assertEq(success, true);\n assertEq(address(vault).balance, balance + 100);\n }\n\n function test_withdraw_notEnough_reverts() external {\n assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());\n\n vm.expectRevert(\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n vault.withdraw();\n }\n\n function test_withdraw_succeeds() external {\n uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1;\n vm.deal(address(vault), amount);\n\n // No ether has been withdrawn yet\n assertEq(vault.totalProcessed(), 0);\n\n vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));\n emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this));\n\n // The entire vault's balance is withdrawn\n vm.expectCall(\n Predeploys.L2_STANDARD_BRIDGE,\n address(vault).balance,\n abi.encodeWithSelector(\n StandardBridge.bridgeETHTo.selector,\n vault.l1FeeWallet(),\n 35_000,\n bytes(\"\")\n )\n );\n\n vault.withdraw();\n\n // The withdrawal was successful\n assertEq(vault.totalProcessed(), amount);\n }\n}\n" - }, - "contracts/test/StandardBridge.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { StandardBridge } from \"../universal/StandardBridge.sol\";\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport {\n OptimismMintableERC20,\n ILegacyMintableERC20\n} from \"../universal/OptimismMintableERC20.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/**\n * @title StandardBridgeTester\n * @notice Simple wrapper around the StandardBridge contract that exposes\n * internal functions so they can be more easily tested directly.\n */\ncontract StandardBridgeTester is StandardBridge {\n constructor(address payable _messenger, address payable _otherBridge)\n StandardBridge(_messenger, _otherBridge)\n {}\n\n function isOptimismMintableERC20(address _token) external view returns (bool) {\n return _isOptimismMintableERC20(_token);\n }\n\n function isCorrectTokenPair(address _mintableToken, address _otherToken)\n external\n view\n returns (bool)\n {\n return _isCorrectTokenPair(_mintableToken, _otherToken);\n }\n\n receive() external payable override {}\n}\n\n/**\n * @title LegacyMintable\n * @notice Simple implementation of the legacy OptimismMintableERC20.\n */\ncontract LegacyMintable is ERC20, ILegacyMintableERC20 {\n constructor(string memory _name, string memory _ticker) ERC20(_name, _ticker) {}\n\n function l1Token() external pure returns (address) {\n return address(0);\n }\n\n function mint(address _to, uint256 _amount) external pure {}\n\n function burn(address _from, uint256 _amount) external pure {}\n\n /**\n * @notice Implements ERC165. This implementation should not be changed as\n * it is how the actual legacy optimism mintable token does the\n * check. Allows for testing against code that is has been deployed,\n * assuming different compiler version is no problem.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 firstSupportedInterface = bytes4(keccak256(\"supportsInterface(bytes4)\")); // ERC165\n bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^\n ILegacyMintableERC20.mint.selector ^\n ILegacyMintableERC20.burn.selector;\n return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;\n }\n}\n\n/**\n * @title StandardBridge_Stateless_Test\n * @notice Tests internal functions that require no existing state or contract\n * interactions with the messenger.\n */\ncontract StandardBridge_Stateless_Test is CommonTest {\n StandardBridgeTester internal bridge;\n OptimismMintableERC20 internal mintable;\n ERC20 internal erc20;\n LegacyMintable internal legacy;\n\n function setUp() public override {\n super.setUp();\n\n bridge = new StandardBridgeTester({\n _messenger: payable(address(0)),\n _otherBridge: payable(address(0))\n });\n\n mintable = new OptimismMintableERC20({\n _bridge: address(0),\n _remoteToken: address(0),\n _name: \"Stonks\",\n _symbol: \"STONK\"\n });\n\n erc20 = new ERC20(\"Altcoin\", \"ALT\");\n legacy = new LegacyMintable(\"Legacy\", \"LEG\");\n }\n\n /**\n * @notice Test coverage for identifying OptimismMintableERC20 tokens.\n * This function should return true for both modern and legacy\n * OptimismMintableERC20 tokens and false for any accounts that\n * do not implement the interface.\n */\n function test_isOptimismMintableERC20_succeeds() external {\n // Both the modern and legacy mintable tokens should return true\n assertTrue(bridge.isOptimismMintableERC20(address(mintable)));\n assertTrue(bridge.isOptimismMintableERC20(address(legacy)));\n // A regular ERC20 should return false\n assertFalse(bridge.isOptimismMintableERC20(address(erc20)));\n // Non existent contracts should return false and not revert\n assertEq(address(0x20).code.length, 0);\n assertFalse(bridge.isOptimismMintableERC20(address(0x20)));\n }\n\n /**\n * @notice Test coverage of isCorrectTokenPair under different types of\n * tokens.\n */\n function test_isCorrectTokenPair_succeeds() external {\n // Modern + known to be correct remote token\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.remoteToken()));\n // Modern + known to be correct l1Token (legacy interface)\n assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.l1Token()));\n // Modern + known to be incorrect remote token\n assertTrue(mintable.remoteToken() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(mintable), address(0x20)));\n // Legacy + known to be correct l1Token\n assertTrue(bridge.isCorrectTokenPair(address(legacy), legacy.l1Token()));\n // Legacy + known to be incorrect l1Token\n assertTrue(legacy.l1Token() != address(0x20));\n assertFalse(bridge.isCorrectTokenPair(address(legacy), address(0x20)));\n // A token that doesn't support either modern or legacy interface\n // will revert\n vm.expectRevert();\n bridge.isCorrectTokenPair(address(erc20), address(1));\n }\n}\n" - }, - "contracts/test/SystemConfig.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CommonTest } from \"./CommonTest.t.sol\";\nimport { SystemConfig } from \"../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\ncontract SystemConfig_Init is CommonTest {\n SystemConfig sysConf;\n\n function setUp() public virtual override {\n super.setUp();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n sysConf = new SystemConfig({\n _owner: alice,\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: config\n });\n }\n}\n\ncontract SystemConfig_Initialize_TestFail is SystemConfig_Init {\n function test_initialize_lowGasLimit_reverts() external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n\n ResourceMetering.ResourceConfig memory cfg = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n new SystemConfig({\n _owner: alice,\n _overhead: 0,\n _scalar: 0,\n _batcherHash: bytes32(hex\"\"),\n _gasLimit: minimumGasLimit - 1,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n }\n}\n\ncontract SystemConfig_Setters_TestFail is SystemConfig_Init {\n function test_setBatcherHash_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setBatcherHash(bytes32(hex\"\"));\n }\n\n function test_setGasConfig_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasConfig(0, 0);\n }\n\n function test_setGasLimit_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setGasLimit(0);\n }\n\n function test_setUnsafeBlockSigner_notOwner_reverts() external {\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setUnsafeBlockSigner(address(0x20));\n }\n\n function test_setResourceConfig_notOwner_reverts() external {\n ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();\n vm.expectRevert(\"Ownable: caller is not the owner\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badMinMax_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 2 gwei,\n maximumBaseFee: 1 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: min base fee must be less than max base\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_zeroDenominator_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 0,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: denominator cannot be 0\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_lowGasLimit_reverts() external {\n uint64 gasLimit = sysConf.gasLimit();\n\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: uint32(gasLimit),\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: uint32(gasLimit),\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: gas limit too low\");\n sysConf.setResourceConfig(config);\n }\n\n function test_setResourceConfig_badPrecision_reverts() external {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 11,\n baseFeeMaxChangeDenominator: 8,\n systemTxMaxGas: 1_000_000,\n minimumBaseFee: 1 gwei,\n maximumBaseFee: 2 gwei\n });\n vm.prank(sysConf.owner());\n vm.expectRevert(\"SystemConfig: precision loss with target resource limit\");\n sysConf.setResourceConfig(config);\n }\n}\n\ncontract SystemConfig_Setters_Test is SystemConfig_Init {\n event ConfigUpdate(\n uint256 indexed version,\n SystemConfig.UpdateType indexed updateType,\n bytes data\n );\n\n function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash));\n\n vm.prank(sysConf.owner());\n sysConf.setBatcherHash(newBatcherHash);\n assertEq(sysConf.batcherHash(), newBatcherHash);\n }\n\n function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.GAS_CONFIG,\n abi.encode(newOverhead, newScalar)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setGasConfig(newOverhead, newScalar);\n assertEq(sysConf.overhead(), newOverhead);\n assertEq(sysConf.scalar(), newScalar);\n }\n\n function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {\n uint64 minimumGasLimit = sysConf.minimumGasLimit();\n newGasLimit = uint64(\n bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))\n );\n\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit));\n\n vm.prank(sysConf.owner());\n sysConf.setGasLimit(newGasLimit);\n assertEq(sysConf.gasLimit(), newGasLimit);\n }\n\n function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external {\n vm.expectEmit(true, true, true, true);\n emit ConfigUpdate(\n 0,\n SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER,\n abi.encode(newUnsafeSigner)\n );\n\n vm.prank(sysConf.owner());\n sysConf.setUnsafeBlockSigner(newUnsafeSigner);\n assertEq(sysConf.unsafeBlockSigner(), newUnsafeSigner);\n }\n}\n" - }, - "contracts/test/TransferOnion.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { TransferOnion } from \"../periphery/TransferOnion.sol\";\n\n/**\n * @title TransferOnionTest\n * @notice Test coverage of TransferOnion\n */\ncontract TransferOnionTest is Test {\n /**\n * @notice TransferOnion\n */\n TransferOnion internal onion;\n\n /**\n * @notice token constructor arg\n */\n address internal _token;\n\n /**\n * @notice sender constructor arg\n */\n address internal _sender;\n\n /**\n * @notice Sets up addresses, deploys contracts and funds the owner.\n */\n function setUp() public {\n ERC20 token = new ERC20(\"Token\", \"TKN\");\n _token = address(token);\n _sender = makeAddr(\"sender\");\n }\n\n /**\n * @notice Deploy the TransferOnion with a dummy shell\n */\n function _deploy() public {\n _deploy(bytes32(0));\n }\n\n /**\n * @notice Deploy the TransferOnion with a specific shell\n */\n function _deploy(bytes32 _shell) public {\n onion = new TransferOnion({ _token: ERC20(_token), _sender: _sender, _shell: _shell });\n }\n\n /**\n * @notice Build the onion data\n */\n function _onionize(TransferOnion.Layer[] memory _layers)\n public\n pure\n returns (bytes32, TransferOnion.Layer[] memory)\n {\n uint256 length = _layers.length;\n bytes32 hash = bytes32(0);\n for (uint256 i; i < length; i++) {\n TransferOnion.Layer memory layer = _layers[i];\n _layers[i].shell = hash;\n hash = keccak256(abi.encode(layer.recipient, layer.amount, hash));\n }\n return (hash, _layers);\n }\n\n /**\n * @notice The constructor sets the variables as expected\n */\n function test_constructor_succeeds() external {\n _deploy();\n\n assertEq(address(onion.TOKEN()), _token);\n assertEq(onion.SENDER(), _sender);\n assertEq(onion.shell(), bytes32(0));\n }\n\n /**\n * @notice unwrap\n */\n function test_unwrap_succeeds() external {\n // Commit to transferring tiny amounts of tokens\n TransferOnion.Layer[] memory _layers = new TransferOnion.Layer[](2);\n _layers[0] = TransferOnion.Layer(address(1), 1, bytes32(0));\n _layers[1] = TransferOnion.Layer(address(2), 2, bytes32(0));\n\n // Build the onion shell\n (bytes32 shell, TransferOnion.Layer[] memory layers) = _onionize(_layers);\n _deploy(shell);\n\n assertEq(onion.shell(), shell);\n\n address token = address(onion.TOKEN());\n address sender = onion.SENDER();\n\n // give 3 units of token to sender\n deal(token, onion.SENDER(), 3);\n vm.prank(sender);\n ERC20(token).approve(address(onion), 3);\n\n // To build the inputs, to `peel`, need to reverse the list\n TransferOnion.Layer[] memory inputs = new TransferOnion.Layer[](2);\n int256 length = int256(layers.length);\n for (int256 i = length - 1; i >= 0; i--) {\n uint256 ui = uint256(i);\n uint256 revidx = uint256(length) - ui - 1;\n TransferOnion.Layer memory layer = layers[ui];\n inputs[revidx] = layer;\n }\n\n // The accounts have no balance\n assertEq(ERC20(_token).balanceOf(address(1)), 0);\n assertEq(ERC20(_token).balanceOf(address(2)), 0);\n\n onion.peel(inputs);\n\n // Now the accounts have the expected balance\n assertEq(ERC20(_token).balanceOf(address(1)), 1);\n assertEq(ERC20(_token).balanceOf(address(2)), 2);\n }\n}\n" - }, - "contracts/test/invariants/CrossDomainMessenger.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { OptimismPortal } from \"../../L1/OptimismPortal.sol\";\nimport { L1CrossDomainMessenger } from \"../../L1/L1CrossDomainMessenger.sol\";\nimport { Messenger_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\nimport { Predeploys } from \"../../libraries/Predeploys.sol\";\nimport { Encoding } from \"../../libraries/Encoding.sol\";\nimport { Hashing } from \"../../libraries/Hashing.sol\";\n\ncontract RelayActor is StdUtils {\n // Storage slot of the l2Sender\n uint256 constant senderSlotIndex = 50;\n\n uint256 public numHashes;\n bytes32[] public hashes;\n bool public reverted = false;\n\n OptimismPortal op;\n L1CrossDomainMessenger xdm;\n Vm vm;\n\n constructor(\n OptimismPortal _op,\n L1CrossDomainMessenger _xdm,\n Vm _vm\n ) {\n op = _op;\n xdm = _xdm;\n vm = _vm;\n }\n\n /**\n * Relays a message to the `L1CrossDomainMessenger` with a random `version`, `_minGasLimit`\n * and `_message`.\n */\n function relay(\n uint16 _version,\n uint32 _minGasLimit,\n bytes memory _message\n ) external {\n address target = address(0x04); // ID precompile\n address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;\n\n // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.\n vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));\n\n // Restrict `_minGasLimit` to a number in the range of the block gas limit.\n _minGasLimit = uint32(bound(_minGasLimit, 0, block.gaslimit));\n\n // Restrict version to the range of [0, 1]\n _version = _version % 2;\n\n // Compute the cross domain message hash and store it in `hashes`.\n // The `relayMessage` function will always encode the message as a version 1\n // message after checking that the V0 hash has not already been relayed.\n bytes32 _hash = Hashing.hashCrossDomainMessageV1(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n 0, // value\n _minGasLimit,\n _message\n );\n\n // Act as the optimism portal and call `relayMessage` on the `L1CrossDomainMessenger` with\n // the outer min gas limit.\n vm.startPrank(address(op));\n vm.expectCall(target, _message);\n try\n xdm.relayMessage{ gas: xdm.baseGas(_message, _minGasLimit) }(\n Encoding.encodeVersionedNonce(0, _version),\n sender,\n target,\n 0, // value\n _minGasLimit,\n _message\n )\n {} catch {\n // If any of these calls revert, set `reverted` to true to fail the invariant test.\n // NOTE: This is to get around forge's invariant fuzzer ignoring reverted calls\n // to this function.\n reverted = true;\n }\n vm.stopPrank();\n\n hashes.push(_hash);\n numHashes += 1;\n }\n}\n\ncontract XDM_MinGasLimits is Messenger_Initializer {\n RelayActor actor;\n\n function setUp() public virtual override {\n // Set up the `L1CrossDomainMessenger` and `OptimismPortal` contracts.\n super.setUp();\n\n // Deploy a relay actor\n actor = new RelayActor(op, L1Messenger, vm);\n\n // Target the `RelayActor` contract\n targetContract(address(actor));\n\n // Target the actor's `relay` function\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.relay.selector;\n targetSelector(FuzzSelector({ addr: address(actor), selectors: selectors }));\n }\n\n /**\n * @custom:invariant A call to `relayMessage` should never revert if at least the proper minimum\n * gas limits are supplied.\n *\n * There are two minimum gas limits here:\n *\n * - The outer min gas limit is for the call from the `OptimismPortal` to the\n * `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function\n * with the `message` and inner limit.\n *\n * - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target\n * contract.\n */\n function invariant_minGasLimits() public {\n uint256 length = actor.numHashes();\n for (uint256 i = 0; i < length; ++i) {\n bytes32 hash = actor.hashes(i);\n // the message hash is in the successfulMessages mapping\n assertTrue(L1Messenger.successfulMessages(hash));\n // it is not in the received messages mapping\n assertFalse(L1Messenger.failedMessages(hash));\n }\n assertFalse(actor.reverted());\n }\n}\n" - }, - "contracts/test/invariants/L2OutputOracle.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { L2OutputOracle_Initializer } from \"../CommonTest.t.sol\";\nimport { L2OutputOracle } from \"../../L1/L2OutputOracle.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\n\ncontract L2OutputOracle_Proposer {\n L2OutputOracle internal oracle;\n Vm internal vm;\n\n constructor(L2OutputOracle _oracle, Vm _vm) {\n oracle = _oracle;\n vm = _vm;\n }\n\n /**\n * @dev Allows the actor to propose an L2 output to the `L2OutputOracle`\n */\n function proposeL2Output(\n bytes32 _outputRoot,\n uint256 _l2BlockNumber,\n bytes32 _l1BlockHash,\n uint256 _l1BlockNumber\n ) external {\n // Act as the proposer and propose a new output.\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _l2BlockNumber, _l1BlockHash, _l1BlockNumber);\n }\n}\n\ncontract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_Initializer {\n L2OutputOracle_Proposer internal actor;\n\n function setUp() public override {\n super.setUp();\n\n // Create a proposer actor.\n actor = new L2OutputOracle_Proposer(oracle, vm);\n\n // Set the target contract to the proposer actor.\n targetContract(address(actor));\n\n // Set the target selector for `proposeL2Output`\n // `proposeL2Output` is the only function we care about, as it is the only function\n // that can modify the `l2Outputs` array in the oracle.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = actor.proposeL2Output.selector;\n FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The block number of the output root proposals should monotonically\n * increase.\n *\n * When a new output is submitted, it should never be allowed to correspond to a block\n * number that is less than the current output.\n */\n function invariant_monotonicBlockNumIncrease() external {\n // Assert that the block number of proposals must monotonically increase.\n assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber());\n }\n}\n" - }, - "contracts/test/invariants/OptimismPortal.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Portal_Initializer } from \"../CommonTest.t.sol\";\nimport { Types } from \"../../libraries/Types.sol\";\n\ncontract OptimismPortal_Invariant_Harness is Portal_Initializer {\n // Reusable default values for a test withdrawal\n Types.WithdrawalTransaction _defaultTx;\n\n uint256 _proposedOutputIndex;\n uint256 _proposedBlockNumber;\n bytes32 _stateRoot;\n bytes32 _storageRoot;\n bytes32 _outputRoot;\n bytes32 _withdrawalHash;\n bytes[] _withdrawalProof;\n Types.OutputRootProof internal _outputRootProof;\n\n function setUp() public virtual override {\n super.setUp();\n\n _defaultTx = Types.WithdrawalTransaction({\n nonce: 0,\n sender: alice,\n target: bob,\n value: 100,\n gasLimit: 100_000,\n data: hex\"\"\n });\n // Get withdrawal proof data we can use for testing.\n (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi\n .getProveWithdrawalTransactionInputs(_defaultTx);\n\n // Setup a dummy output root proof for reuse.\n _outputRootProof = Types.OutputRootProof({\n version: bytes32(uint256(0)),\n stateRoot: _stateRoot,\n messagePasserStorageRoot: _storageRoot,\n latestBlockhash: bytes32(uint256(0))\n });\n _proposedBlockNumber = oracle.nextBlockNumber();\n _proposedOutputIndex = oracle.nextOutputIndex();\n\n // Configure the oracle to return the output root we've prepared.\n vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);\n vm.prank(oracle.PROPOSER());\n oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);\n\n // Warp beyond the finalization period for the block we've proposed.\n vm.warp(\n oracle.getL2Output(_proposedOutputIndex).timestamp +\n oracle.FINALIZATION_PERIOD_SECONDS() +\n 1\n );\n // Fund the portal so that we can withdraw ETH.\n vm.deal(address(op), 0xFFFFFFFF);\n }\n}\n\ncontract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization\n * period has not elapsed.\n *\n * A withdrawal that has been proven should not be able to be finalized until after\n * the finalization period has elapsed.\n */\n function invariant_cannotFinalizeBeforePeriodHasPassed() external {\n vm.expectRevert(\"OptimismPortal: proven withdrawal finalization period has not elapsed\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Finalize the withdrawal transaction.\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal\n * has already been finalized.\n *\n * Ensures that there is no chain of calls that can be made that allows a withdrawal\n * to be finalized twice.\n */\n function invariant_cannotFinalizeTwice() external {\n vm.expectRevert(\"OptimismPortal: withdrawal has already been finalized\");\n op.finalizeWithdrawalTransaction(_defaultTx);\n }\n}\n\ncontract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant_Harness {\n function setUp() public override {\n super.setUp();\n\n // Prove the withdrawal transaction\n op.proveWithdrawalTransaction(\n _defaultTx,\n _proposedOutputIndex,\n _outputRootProof,\n _withdrawalProof\n );\n\n // Warp past the finalization period.\n vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);\n\n // Set the target contract to the portal proxy\n targetContract(address(op));\n // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded\n excludeSender(address(multisig));\n }\n\n /**\n * @custom:invariant A withdrawal should **always** be able to be finalized\n * `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.\n *\n * This invariant asserts that there is no chain of calls that can be made that\n * will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS`\n * after it was successfully proven.\n */\n function invariant_canAlwaysFinalize() external {\n uint256 bobBalanceBefore = address(bob).balance;\n\n op.finalizeWithdrawalTransaction(_defaultTx);\n\n assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value);\n }\n}\n" - }, - "contracts/test/invariants/SafeCall.t.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { StdUtils } from \"forge-std/StdUtils.sol\";\nimport { Vm } from \"forge-std/Vm.sol\";\nimport { SafeCall } from \"../../libraries/SafeCall.sol\";\n\ncontract SafeCall_Succeeds_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, false);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n }\n\n /**\n * @custom:invariant If `callWithMinGas` performs a call, then it must always\n * provide at least the specified minimum gas limit to the subcontext.\n *\n * If the check for remaining gas in `SafeCall.callWithMinGas` passes, the\n * subcontext of the call below it must be provided at least `minGas` gas.\n */\n function invariant_callWithMinGas_alwaysForwardsMinGas_succeeds() public {\n assertEq(actor.numCalls(), 0, \"no failed calls allowed\");\n }\n\n function performSafeCallMinGas(uint64 minGas) external {\n SafeCall.callWithMinGas(address(0), minGas, 0, hex\"\");\n }\n}\n\ncontract SafeCall_Fails_Invariants is Test {\n SafeCaller_Actor actor;\n\n function setUp() public {\n // Create a new safe caller actor.\n actor = new SafeCaller_Actor(vm, true);\n\n // Set the caller to this contract\n targetSender(address(this));\n\n // Target the safe caller actor.\n targetContract(address(actor));\n }\n\n /**\n * @custom:invariant `callWithMinGas` reverts if there is not enough gas to pass\n * to the subcontext.\n *\n * If there is not enough gas in the callframe to ensure that `callWithMinGas`\n * can provide the specified minimum gas limit to the subcontext of the call,\n * then `callWithMinGas` must revert.\n */\n function invariant_callWithMinGas_neverForwardsMinGas_reverts() public {\n assertEq(actor.numCalls(), 0, \"no successful calls allowed\");\n }\n\n function performSafeCallMinGas(uint64 minGas) external {\n SafeCall.callWithMinGas(address(0), minGas, 0, hex\"\");\n }\n}\n\ncontract SafeCaller_Actor is StdUtils {\n bool internal immutable FAILS;\n\n Vm internal vm;\n uint256 public numCalls;\n\n constructor(Vm _vm, bool _fails) {\n vm = _vm;\n FAILS = _fails;\n }\n\n function performSafeCallMinGas(uint64 gas, uint64 minGas) external {\n if (FAILS) {\n // Bound the minimum gas amount to [2500, type(uint48).max]\n minGas = uint64(bound(minGas, 2500, type(uint48).max));\n // Bound the gas passed to [minGas, (((minGas + 200) * 64) / 63)]\n gas = uint64(bound(gas, minGas, (((minGas + 200) * 64) / 63)));\n } else {\n // Bound the minimum gas amount to [2500, type(uint48).max]\n minGas = uint64(bound(minGas, 2500, type(uint48).max));\n // Bound the gas passed to [(((minGas + 200) * 64) / 63) + 500, type(uint64).max]\n gas = uint64(bound(gas, (((minGas + 200) * 64) / 63) + 500, type(uint64).max));\n }\n\n vm.expectCallMinGas(address(0x00), 0, minGas, hex\"\");\n bool success = SafeCall.call(\n msg.sender,\n gas,\n 0,\n abi.encodeWithSelector(0x2ae57a41, minGas)\n );\n\n if (success && FAILS) numCalls++;\n if (!FAILS && !success) numCalls++;\n }\n}\n" - }, - "contracts/test/invariants/SystemConfig.t.sol": { - "content": "pragma solidity 0.8.15;\n\nimport { Test } from \"forge-std/Test.sol\";\nimport { SystemConfig } from \"../../L1/SystemConfig.sol\";\nimport { ResourceMetering } from \"../../L1/ResourceMetering.sol\";\nimport { Constants } from \"../../libraries/Constants.sol\";\n\ncontract SystemConfig_GasLimitLowerBound_Invariant is Test {\n SystemConfig public config;\n\n function setUp() public {\n ResourceMetering.ResourceConfig memory cfg = Constants.DEFAULT_RESOURCE_CONFIG();\n\n config = new SystemConfig({\n _owner: address(0xbeef),\n _overhead: 2100,\n _scalar: 1000000,\n _batcherHash: bytes32(hex\"abcd\"),\n _gasLimit: 30_000_000,\n _unsafeBlockSigner: address(1),\n _config: cfg\n });\n\n // Set the target contract to the `config`\n targetContract(address(config));\n // Set the target sender to the `config`'s owner (0xbeef)\n targetSender(address(0xbeef));\n // Set the target selector for `setGasLimit`\n // `setGasLimit` is the only function we care about, as it is the only function\n // that can modify the gas limit within the SystemConfig.\n bytes4[] memory selectors = new bytes4[](1);\n selectors[0] = config.setGasLimit.selector;\n FuzzSelector memory selector = FuzzSelector({\n addr: address(config),\n selectors: selectors\n });\n targetSelector(selector);\n }\n\n /**\n * @custom:invariant The gas limit of the `SystemConfig` contract can never be lower\n * than the hard-coded lower bound.\n */\n function invariant_gasLimitLowerBound() external {\n assertTrue(config.gasLimit() >= config.minimumGasLimit());\n }\n}\n" - }, - "contracts/universal/CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer0\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * libAddressManager variable used to exist. Must be the first contract in the inheritance\n * tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer0 {\n /**\n * @custom:legacy\n * @custom:spacer libAddressManager\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n}\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer1\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * PausableUpgradable and OwnableUpgradeable variables used to exist. Must be\n * the third contract in the inheritance tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer1 {\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable via OwnableUpgradeable.\n *\n */\n uint256[50] private spacer_1_0_1600;\n\n /**\n * @custom:legacy\n * @custom:spacer _owner\n * @notice Spacer for backwards compatibility.\n * Come from OpenZeppelin OwnableUpgradeable.\n */\n address private spacer_51_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable via PausableUpgradable.\n */\n uint256[49] private spacer_52_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer _paused\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n bool private spacer_101_0_1;\n\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n uint256[49] private spacer_102_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer ReentrancyGuardUpgradeable's `_status` field.\n * @notice Spacer for backwards compatibility\n */\n uint256 private spacer_151_0_32;\n\n /**\n * @custom:spacer ReentrancyGuardUpgradeable\n * @notice Spacer for backwards compatibility\n */\n uint256[49] private __gap_reentrancy_guard;\n\n /**\n * @custom:legacy\n * @custom:spacer blockedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_201_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer relayedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_202_0_32;\n}\n\n/**\n * @custom:upgradeable\n * @title CrossDomainMessenger\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\n * cross-chain messenger contracts. It's designed to be a universal interface that only\n * needs to be extended slightly to provide low-level message passing functionality on each\n * chain it's deployed on. Currently only designed for message passing between two paired\n * chains and does not support one-to-many interactions.\n *\n * Any changes to this contract MUST result in a semver bump for contracts that inherit it.\n */\nabstract contract CrossDomainMessenger is\n CrossDomainMessengerLegacySpacer0,\n Initializable,\n CrossDomainMessengerLegacySpacer1\n{\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Constant overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_CONSTANT_OVERHEAD = 200_000;\n\n /**\n * @notice Numerator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 1016;\n\n /**\n * @notice Denominator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 1000;\n\n /**\n * @notice Extra gas added to base gas for each byte of calldata in a message.\n */\n uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\n\n /**\n * @notice Address of the paired CrossDomainMessenger contract on the other chain.\n */\n address public immutable OTHER_MESSENGER;\n\n /**\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n * be present in this mapping if it has successfully been relayed on this chain, and\n * can therefore not be relayed again.\n */\n mapping(bytes32 => bool) public successfulMessages;\n\n /**\n * @notice Address of the sender of the currently executing message on the other chain. If the\n * value of this variable is the default value (0x00000000...dead) then no message is\n * currently being executed. Use the xDomainMessageSender getter which will throw an\n * error if this is the case.\n */\n address internal xDomainMsgSender;\n\n /**\n * @notice Nonce for the next message to be sent, without the message version applied. Use the\n * messageNonce getter which will insert the message version into the nonce to give you\n * the actual nonce to be used for the message.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Mapping of message hashes to a boolean if and only if the message has failed to be\n * executed at least once. A message will not be present in this mapping if it\n * successfully executed on the first attempt.\n */\n mapping(bytes32 => bool) public failedMessages;\n\n /**\n * @notice A mapping of hashes to reentrancy locks.\n */\n mapping(bytes32 => bool) internal reentrancyLocks;\n\n /**\n * @notice Reserve extra slots in the storage layout for future upgrades.\n * A gap size of 41 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[41] private __gap;\n\n /**\n * @notice Emitted whenever a message is sent to the other chain.\n *\n * @param target Address of the recipient of the message.\n * @param sender Address of the sender of the message.\n * @param message Message to trigger the recipient address with.\n * @param messageNonce Unique nonce attached to the message.\n * @param gasLimit Minimum gas limit that the message can be executed with.\n */\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n /**\n * @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the\n * SentMessage event without breaking the ABI of this contract, this is good enough.\n *\n * @param sender Address of the sender of the message.\n * @param value ETH value sent along with the message to the recipient.\n */\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n /**\n * @notice Emitted whenever a message is successfully relayed on this chain.\n *\n * @param msgHash Hash of the message that was relayed.\n */\n event RelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @notice Emitted whenever a message fails to be relayed on this chain.\n *\n * @param msgHash Hash of the message that failed to be relayed.\n */\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @param _otherMessenger Address of the messenger on the paired chain.\n */\n constructor(address _otherMessenger) {\n OTHER_MESSENGER = _otherMessenger;\n }\n\n /**\n * @notice Sends a message to some target address on the other chain. Note that if the call\n * always reverts, then the message will be unrelayable, and any ETH sent will be\n * permanently locked. The same will occur if the target on the other chain is\n * considered unsafe (see the _isUnsafeTarget() function).\n *\n * @param _target Target contract or wallet address.\n * @param _message Message to trigger the target address with.\n * @param _minGasLimit Minimum gas limit that the message can be executed with.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _minGasLimit\n ) external payable {\n // Triggers a message to the other messenger. Note that the amount of gas provided to the\n // message is the amount of gas requested by the user PLUS the base gas value. We want to\n // guarantee the property that the call to the target contract will always have at least\n // the minimum gas limit specified by the user.\n _sendMessage(\n OTHER_MESSENGER,\n baseGas(_message, _minGasLimit),\n msg.value,\n abi.encodeWithSelector(\n this.relayMessage.selector,\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _minGasLimit,\n _message\n )\n );\n\n emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit);\n emit SentMessageExtension1(msg.sender, msg.value);\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\n * be executed via cross-chain call from the other messenger OR if the message was\n * already received once and is currently being replayed.\n *\n * @param _nonce Nonce of the message being relayed.\n * @param _sender Address of the user who sent the message.\n * @param _target Address that the message is targeted at.\n * @param _value ETH value to send with the message.\n * @param _minGasLimit Minimum amount of gas that the message can be executed with.\n * @param _message Message to send to the target.\n */\n function relayMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _minGasLimit,\n bytes calldata _message\n ) external payable {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n require(\n version < 2,\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // If the message is version 0, then it's a migrated legacy withdrawal. We therefore need\n // to check that the legacy version of the message has not already been relayed.\n if (version == 0) {\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce);\n require(\n successfulMessages[oldHash] == false,\n \"CrossDomainMessenger: legacy withdrawal already relayed\"\n );\n }\n\n // We use the v1 message hash as the unique identifier for the message because it commits\n // to the value and minimum gas limit of the message.\n bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _minGasLimit,\n _message\n );\n\n // Check if the reentrancy lock for the `versionedHash` is already set.\n if (reentrancyLocks[versionedHash]) {\n revert(\"ReentrancyGuard: reentrant call\");\n }\n // Trigger the reentrancy lock for `versionedHash`\n reentrancyLocks[versionedHash] = true;\n\n if (_isOtherMessenger()) {\n // These properties should always hold when the message is first submitted (as\n // opposed to being replayed).\n assert(msg.value == _value);\n assert(!failedMessages[versionedHash]);\n } else {\n require(\n msg.value == 0,\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n\n require(\n failedMessages[versionedHash],\n \"CrossDomainMessenger: message cannot be replayed\"\n );\n }\n\n require(\n _isUnsafeTarget(_target) == false,\n \"CrossDomainMessenger: cannot send message to blocked system address\"\n );\n\n require(\n successfulMessages[versionedHash] == false,\n \"CrossDomainMessenger: message has already been relayed\"\n );\n\n xDomainMsgSender = _sender;\n bool success = SafeCall.callWithMinGas(_target, _minGasLimit, _value, _message);\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n\n if (success) {\n successfulMessages[versionedHash] = true;\n emit RelayedMessage(versionedHash);\n } else {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n }\n\n // Clear the reentrancy lock for `versionedHash`\n reentrancyLocks[versionedHash] = false;\n }\n\n /**\n * @notice Retrieves the address of the contract or wallet that initiated the currently\n * executing message on the other chain. Will throw an error if there is no message\n * currently being executed. Allows the recipient of a call to see who triggered it.\n *\n * @return Address of the sender of the currently executing message on the other chain.\n */\n function xDomainMessageSender() external view returns (address) {\n require(\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER,\n \"CrossDomainMessenger: xDomainMessageSender is not set\"\n );\n\n return xDomainMsgSender;\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n\n /**\n * @notice Computes the amount of gas required to guarantee that a given message will be\n * received on the other chain without running out of gas. Guaranteeing that a message\n * will not run out of gas is important because this ensures that a message can always\n * be replayed on the other chain if it fails to execute completely.\n *\n * @param _message Message to compute the amount of required gas for.\n * @param _minGasLimit Minimum desired gas limit when message goes to target.\n *\n * @return Amount of gas required to guarantee message receipt.\n */\n function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {\n // We peform the following math on uint64s to avoid overflow errors. Multiplying the\n // by MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR would otherwise limit the _minGasLimit to\n // type(uint32).max / MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR ~= 4.2m.\n return\n // Dynamic overhead\n ((uint64(_minGasLimit) * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\n MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\n // Calldata overhead\n (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\n // Constant overhead\n MIN_GAS_CONSTANT_OVERHEAD;\n }\n\n /**\n * @notice Intializer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __CrossDomainMessenger_init() internal onlyInitializing {\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n }\n\n /**\n * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @param _to Recipient of the message on the other chain.\n * @param _gasLimit Minimum gas limit the message can be executed with.\n * @param _value Amount of ETH to send with the message.\n * @param _data Message data.\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal virtual;\n\n /**\n * @notice Checks whether the message is coming from the other messenger. Implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @return Whether the message is coming from the other messenger.\n */\n function _isOtherMessenger() internal view virtual returns (bool);\n\n /**\n * @notice Checks whether a given call target is a system address that could cause the\n * messenger to peform an unsafe action. This is NOT a mechanism for blocking user\n * addresses. This is ONLY used to prevent the execution of messages to specific\n * system addresses that could cause security issues, e.g., having the\n * CrossDomainMessenger send messages to itself.\n *\n * @param _target Address of the contract to check.\n *\n * @return Whether or not the address is an unsafe system address.\n */\n function _isUnsafeTarget(address _target) internal view virtual returns (bool);\n}\n" - }, - "contracts/universal/ERC721Bridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721Bridge\n * @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.\n */\nabstract contract ERC721Bridge {\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Address of the bridge on the other network.\n */\n address public immutable OTHER_BRIDGE;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[49] private __gap;\n\n /**\n * @notice Emitted when an ERC721 bridge to the other network is initiated.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC721 bridge from the other network is finalized.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) && MESSENGER.xDomainMessageSender() == OTHER_BRIDGE,\n \"ERC721Bridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge) {\n require(_messenger != address(0), \"ERC721Bridge: messenger cannot be address(0)\");\n require(_otherBridge != address(0), \"ERC721Bridge: other bridge cannot be address(0)\");\n\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = _otherBridge;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for other bridge address.\n *\n * @return Address of the bridge on the other network.\n */\n function otherBridge() external view returns (address) {\n return OTHER_BRIDGE;\n }\n\n /**\n * @notice Initiates a bridge of an NFT to the caller's account on the other chain. Note that\n * this function can only be called by EOAs. Smart contract wallets should use the\n * `bridgeERC721To` function after ensuring that the recipient address on the remote\n * chain exists. Also note that the current owner of the token on this chain must\n * approve this contract to operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721(\n address _localToken,\n address _remoteToken,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n // Modifier requiring sender to be EOA. This prevents against a user error that would occur\n // if the sender is a smart contract wallet that has a different address on the remote chain\n // (or doesn't have an address on the remote chain at all). The user would fail to receive\n // the NFT if they use this function because it sends the NFT to the same address as the\n // caller. This check could be bypassed by a malicious contract via initcode, but it takes\n // care of the user error we want to avoid.\n require(!Address.isContract(msg.sender), \"ERC721Bridge: account is not externally owned\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note\n * that the current owner of the token on this chain must approve this contract to\n * operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n require(_to != address(0), \"ERC721Bridge: nft recipient cannot be address(0)\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Internal function for initiating a token bridge to the other domain.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _from Address of the sender on this domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other domain. Data supplied here will\n * not be used to execute any code on the other domain and is only emitted\n * as extra data for the convenience of off-chain tooling.\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal virtual;\n}\n" - }, - "contracts/universal/FeeVault.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { L2StandardBridge } from \"../L2/L2StandardBridge.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\n\n/**\n * @title FeeVault\n * @notice The FeeVault contract contains the basic logic for the various different vault contracts\n * used to hold fee revenue generated by the L2 system.\n */\nabstract contract FeeVault {\n /**\n * @notice Emits each time that a withdrawal occurs.\n *\n * @param value Amount that was withdrawn (in wei).\n * @param to Address that the funds were sent to.\n * @param from Address that triggered the withdrawal.\n */\n event Withdrawal(uint256 value, address to, address from);\n\n /**\n * @notice Minimum balance before a withdrawal can be triggered.\n */\n uint256 public immutable MIN_WITHDRAWAL_AMOUNT;\n\n /**\n * @notice Wallet that will receive the fees on L1.\n */\n address public immutable RECIPIENT;\n\n /**\n * @notice The minimum gas limit for the FeeVault withdrawal transaction.\n */\n uint32 internal constant WITHDRAWAL_MIN_GAS = 35_000;\n\n /**\n * @notice Total amount of wei processed by the contract.\n */\n uint256 public totalProcessed;\n\n /**\n * @param _recipient Wallet that will receive the fees on L1.\n * @param _minWithdrawalAmount Minimum balance before a withdrawal can be triggered.\n */\n constructor(address _recipient, uint256 _minWithdrawalAmount) {\n MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;\n RECIPIENT = _recipient;\n }\n\n /**\n * @notice Allow the contract to receive ETH.\n */\n receive() external payable {}\n\n /**\n * @notice Triggers a withdrawal of funds to the L1 fee wallet.\n */\n function withdraw() external {\n require(\n address(this).balance >= MIN_WITHDRAWAL_AMOUNT,\n \"FeeVault: withdrawal amount must be greater than minimum withdrawal amount\"\n );\n\n uint256 value = address(this).balance;\n totalProcessed += value;\n\n emit Withdrawal(value, RECIPIENT, msg.sender);\n\n L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).bridgeETHTo{ value: value }(\n RECIPIENT,\n WITHDRAWAL_MIN_GAS,\n bytes(\"\")\n );\n }\n}\n" - }, - "contracts/universal/IOptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @title IOptimismMintableERC20\n * @notice This interface is available on the OptimismMintableERC20 contract. We declare it as a\n * separate interface so that it can be used in custom implementations of\n * OptimismMintableERC20.\n */\ninterface IOptimismMintableERC20 is IERC165 {\n function remoteToken() external view returns (address);\n\n function bridge() external returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n\n/**\n * @custom:legacy\n * @title ILegacyMintableERC20\n * @notice This interface was available on the legacy L2StandardERC20 contract. It remains available\n * on the OptimismMintableERC20 contract for backwards compatibility.\n */\ninterface ILegacyMintableERC20 is IERC165 {\n function l1Token() external view returns (address);\n\n function mint(address _to, uint256 _amount) external;\n\n function burn(address _from, uint256 _amount) external;\n}\n" - }, - "contracts/universal/IOptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\n/**\n * @title IOptimismMintableERC721\n * @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.\n * Tokens that follow this standard can be easily transferred across the ERC721 bridge.\n */\ninterface IOptimismMintableERC721 is IERC721Enumerable {\n /**\n * @notice Emitted when a token is minted.\n *\n * @param account Address of the account the token was minted to.\n * @param tokenId Token ID of the minted token.\n */\n event Mint(address indexed account, uint256 tokenId);\n\n /**\n * @notice Emitted when a token is burned.\n *\n * @param account Address of the account the token was burned from.\n * @param tokenId Token ID of the burned token.\n */\n event Burn(address indexed account, uint256 tokenId);\n\n /**\n * @notice Mints some token ID for a user, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * @param _to Address of the user to mint the token for.\n * @param _tokenId Token ID to mint.\n */\n function safeMint(address _to, uint256 _tokenId) external;\n\n /**\n * @notice Burns a token ID from a user.\n *\n * @param _from Address of the user to burn the token from.\n * @param _tokenId Token ID to burn.\n */\n function burn(address _from, uint256 _tokenId) external;\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function REMOTE_CHAIN_ID() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function REMOTE_TOKEN() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function BRIDGE() external view returns (address);\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function remoteChainId() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function remoteToken() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function bridge() external view returns (address);\n}\n" - }, - "contracts/universal/OptimismMintableERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { ILegacyMintableERC20, IOptimismMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC20\n * @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed\n * to allow the StandardBridge contracts to mint and burn tokens. This makes it possible to\n * use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa.\n * Designed to be backwards compatible with the older StandardL2ERC20 token which was only\n * meant for use on L2.\n */\ncontract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, Semver {\n /**\n * @notice Address of the corresponding version of this token on the remote chain.\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @notice Address of the StandardBridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Emitted whenever tokens are minted for an account.\n *\n * @param account Address of the account tokens are being minted for.\n * @param amount Amount of tokens minted.\n */\n event Mint(address indexed account, uint256 amount);\n\n /**\n * @notice Emitted whenever tokens are burned from an account.\n *\n * @param account Address of the account tokens are being burned from.\n * @param amount Amount of tokens burned.\n */\n event Burn(address indexed account, uint256 amount);\n\n /**\n * @notice A modifier that only allows the bridge to call\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC20: only bridge can mint and burn\");\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the L2 standard bridge.\n * @param _remoteToken Address of the corresponding L1 token.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n */\n constructor(\n address _bridge,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC20(_name, _symbol) Semver(1, 0, 0) {\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n }\n\n /**\n * @notice Allows the StandardBridge on this network to mint tokens.\n *\n * @param _to Address to mint tokens to.\n * @param _amount Amount of tokens to mint.\n */\n function mint(address _to, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _mint(_to, _amount);\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Allows the StandardBridge on this network to burn tokens.\n *\n * @param _from Address to burn tokens from.\n * @param _amount Amount of tokens to burn.\n */\n function burn(address _from, uint256 _amount)\n external\n virtual\n override(IOptimismMintableERC20, ILegacyMintableERC20)\n onlyBridge\n {\n _burn(_from, _amount);\n emit Burn(_from, _amount);\n }\n\n /**\n * @notice ERC165 interface check function.\n *\n * @param _interfaceId Interface ID to check.\n *\n * @return Whether or not the interface is supported by this contract.\n */\n function supportsInterface(bytes4 _interfaceId) external pure returns (bool) {\n bytes4 iface1 = type(IERC165).interfaceId;\n // Interface corresponding to the legacy L2StandardERC20.\n bytes4 iface2 = type(ILegacyMintableERC20).interfaceId;\n // Interface corresponding to the updated OptimismMintableERC20 (this contract).\n bytes4 iface3 = type(IOptimismMintableERC20).interfaceId;\n return _interfaceId == iface1 || _interfaceId == iface2 || _interfaceId == iface3;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote token. Use REMOTE_TOKEN going forward.\n */\n function l1Token() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the bridge. Use BRIDGE going forward.\n */\n function l2Bridge() public view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for REMOTE_TOKEN.\n */\n function remoteToken() public view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for BRIDGE.\n */\n function bridge() public view returns (address) {\n return BRIDGE;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC20Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/* Contract Imports */\nimport { OptimismMintableERC20 } from \"../universal/OptimismMintableERC20.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeployed 0x4200000000000000000000000000000000000012\n * @title OptimismMintableERC20Factory\n * @notice OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20\n * contracts on the network it's deployed to. Simplifies the deployment process for users\n * who may be less familiar with deploying smart contracts. Designed to be backwards\n * compatible with the older StandardL2ERC20Factory contract.\n */\ncontract OptimismMintableERC20Factory is Semver {\n /**\n * @notice Address of the StandardBridge on this chain.\n */\n address public immutable BRIDGE;\n\n /**\n * @custom:legacy\n * @notice Emitted whenever a new OptimismMintableERC20 is created. Legacy version of the newer\n * OptimismMintableERC20Created event. We recommend relying on that event instead.\n *\n * @param remoteToken Address of the token on the remote chain.\n * @param localToken Address of the created token on the local chain.\n */\n event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC20 is created.\n *\n * @param localToken Address of the created token on the local chain.\n * @param remoteToken Address of the corresponding token on the remote chain.\n * @param deployer Address of the account that deployed the token.\n */\n event OptimismMintableERC20Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.1.0\n *\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC20 token contract since this contract\n * is responsible for deploying OptimismMintableERC20 contracts.\n *\n * @param _bridge Address of the StandardBridge on this chain.\n */\n constructor(address _bridge) Semver(1, 1, 0) {\n BRIDGE = _bridge;\n }\n\n /**\n * @custom:legacy\n * @notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the\n * newer createOptimismMintableERC20 function, which has a more intuitive name.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createStandardL2Token(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n return createOptimismMintableERC20(_remoteToken, _name, _symbol);\n }\n\n /**\n * @notice Creates an instance of the OptimismMintableERC20 contract.\n *\n * @param _remoteToken Address of the token on the remote chain.\n * @param _name ERC20 name.\n * @param _symbol ERC20 symbol.\n *\n * @return Address of the newly created token.\n */\n function createOptimismMintableERC20(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) public returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC20Factory: must provide remote token address\"\n );\n\n address localToken = address(\n new OptimismMintableERC20(BRIDGE, _remoteToken, _name, _symbol)\n );\n\n // Emit the old event too for legacy support.\n emit StandardL2TokenCreated(_remoteToken, localToken);\n\n // Emit the updated event. The arguments here differ from the legacy event, but\n // are consistent with the ordering used in StandardBridge events.\n emit OptimismMintableERC20Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n ERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { IOptimismMintableERC721 } from \"./IOptimismMintableERC721.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC721\n * @notice This contract is the remote representation for some token that lives on another network,\n * typically an Optimism representation of an Ethereum-based token. Standard reference\n * implementation that can be extended or modified according to your needs.\n */\ncontract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721, Semver {\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable REMOTE_TOKEN;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Base token URI for this token.\n */\n string public baseTokenURI;\n\n /**\n * @notice Modifier that prevents callers other than the bridge from calling the function.\n */\n modifier onlyBridge() {\n require(msg.sender == BRIDGE, \"OptimismMintableERC721: only bridge can call this function\");\n _;\n }\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the bridge on this network.\n * @param _remoteChainId Chain ID where the remote token is deployed.\n * @param _remoteToken Address of the corresponding token on the other network.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n constructor(\n address _bridge,\n uint256 _remoteChainId,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) Semver(1, 0, 0) {\n require(_bridge != address(0), \"OptimismMintableERC721: bridge cannot be address(0)\");\n require(_remoteChainId != 0, \"OptimismMintableERC721: remote chain id cannot be zero\");\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721: remote token cannot be address(0)\"\n );\n\n REMOTE_CHAIN_ID = _remoteChainId;\n REMOTE_TOKEN = _remoteToken;\n BRIDGE = _bridge;\n\n // Creates a base URI in the format specified by EIP-681:\n // https://eips.ethereum.org/EIPS/eip-681\n baseTokenURI = string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(_remoteToken), 20),\n \"@\",\n Strings.toString(_remoteChainId),\n \"/tokenURI?uint256=\"\n )\n );\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteChainId() external view returns (uint256) {\n return REMOTE_CHAIN_ID;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function remoteToken() external view returns (address) {\n return REMOTE_TOKEN;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function bridge() external view returns (address) {\n return BRIDGE;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function safeMint(address _to, uint256 _tokenId) external virtual onlyBridge {\n _safeMint(_to, _tokenId);\n\n emit Mint(_to, _tokenId);\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function burn(address _from, uint256 _tokenId) external virtual onlyBridge {\n _burn(_tokenId);\n\n emit Burn(_from, _tokenId);\n }\n\n /**\n * @notice Checks if a given interface ID is supported by this contract.\n *\n * @param _interfaceId The interface ID to check.\n *\n * @return True if the interface ID is supported, false otherwise.\n */\n function supportsInterface(bytes4 _interfaceId)\n public\n view\n override(ERC721Enumerable, IERC165)\n returns (bool)\n {\n bytes4 iface1 = type(IERC165).interfaceId;\n bytes4 iface2 = type(IOptimismMintableERC721).interfaceId;\n return\n _interfaceId == iface1 ||\n _interfaceId == iface2 ||\n super.supportsInterface(_interfaceId);\n }\n\n /**\n * @notice Returns the base token URI.\n *\n * @return Base token URI.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return baseTokenURI;\n }\n}\n" - }, - "contracts/universal/OptimismMintableERC721Factory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismMintableERC721 } from \"./OptimismMintableERC721.sol\";\nimport { Semver } from \"./Semver.sol\";\n\n/**\n * @title OptimismMintableERC721Factory\n * @notice Factory contract for creating OptimismMintableERC721 contracts.\n */\ncontract OptimismMintableERC721Factory is Semver {\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n address public immutable BRIDGE;\n\n /**\n * @notice Chain ID for the remote network.\n */\n uint256 public immutable REMOTE_CHAIN_ID;\n\n /**\n * @notice Tracks addresses created by this factory.\n */\n mapping(address => bool) public isOptimismMintableERC721;\n\n /**\n * @notice Emitted whenever a new OptimismMintableERC721 contract is created.\n *\n * @param localToken Address of the token on the this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param deployer Address of the initiator of the deployment\n */\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @custom:semver 1.1.0\n * @notice The semver MUST be bumped any time that there is a change in\n * the OptimismMintableERC721 token contract since this contract\n * is responsible for deploying OptimismMintableERC721 contracts.\n *\n * @param _bridge Address of the ERC721 bridge on this network.\n * @param _remoteChainId Chain ID for the remote network.\n */\n constructor(address _bridge, uint256 _remoteChainId) Semver(1, 1, 0) {\n BRIDGE = _bridge;\n REMOTE_CHAIN_ID = _remoteChainId;\n }\n\n /**\n * @notice Creates an instance of the standard ERC721.\n *\n * @param _remoteToken Address of the corresponding token on the other domain.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n function createOptimismMintableERC721(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721Factory: L1 token address cannot be address(0)\"\n );\n\n address localToken = address(\n new OptimismMintableERC721(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)\n );\n\n isOptimismMintableERC721[localToken] = true;\n emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n" - }, - "contracts/universal/Proxy.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Proxy\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\n * if the caller is address(0), meaning that the call originated from an off-chain\n * simulation.\n */\ncontract Proxy {\n /**\n * @notice The storage slot that holds the address of the implementation.\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice The storage slot that holds the address of the owner.\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice An event that is emitted each time the implementation is changed. This event is part\n * of the EIP-1967 specification.\n *\n * @param implementation The address of the implementation contract\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\n * EIP-1967 specification.\n *\n * @param previousAdmin The previous owner of the contract\n * @param newAdmin The new owner of the contract\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\n * eth_call to interact with this proxy without needing to use low-level storage\n * inspection. We assume that nobody is able to trigger calls from address(0) during\n * normal EVM execution.\n */\n modifier proxyCallIfNotAdmin() {\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\n * EIP-1967 admin storage slot so that accidental storage collision with the\n * implementation is not possible.\n *\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\n * transparent proxy interface.\n */\n constructor(address _admin) {\n _changeAdmin(_admin);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Set the implementation contract address. The code at the given address will execute\n * when this contract is called.\n *\n * @param _implementation Address of the implementation contract.\n */\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\n _setImplementation(_implementation);\n }\n\n /**\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\n * atomic execution of initialization-based upgrades.\n *\n * @param _implementation Address of the implementation contract.\n * @param _data Calldata to delegatecall the new implementation with.\n */\n function upgradeToAndCall(address _implementation, bytes calldata _data)\n external\n payable\n proxyCallIfNotAdmin\n returns (bytes memory)\n {\n _setImplementation(_implementation);\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\n require(success, \"Proxy: delegatecall to new implementation contract failed\");\n return returndata;\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _admin New owner of the proxy contract.\n */\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\n _changeAdmin(_admin);\n }\n\n /**\n * @notice Gets the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function admin() external proxyCallIfNotAdmin returns (address) {\n return _getAdmin();\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function implementation() external proxyCallIfNotAdmin returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n emit Upgraded(_implementation);\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _admin New owner of the proxy contract.\n */\n function _changeAdmin(address _admin) internal {\n address previous = _getAdmin();\n assembly {\n sstore(OWNER_KEY, _admin)\n }\n emit AdminChanged(previous, _admin);\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal {\n address impl = _getImplementation();\n require(impl != address(0), \"Proxy: implementation not initialized\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address impl;\n assembly {\n impl := sload(IMPLEMENTATION_KEY)\n }\n return impl;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getAdmin() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n}\n" - }, - "contracts/universal/ProxyAdmin.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { Proxy } from \"./Proxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\n\n/**\n * @title IStaticERC1967Proxy\n * @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface.\n */\ninterface IStaticERC1967Proxy {\n function implementation() external view returns (address);\n\n function admin() external view returns (address);\n}\n\n/**\n * @title IStaticL1ChugSplashProxy\n * @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface.\n */\ninterface IStaticL1ChugSplashProxy {\n function getImplementation() external view returns (address);\n\n function getOwner() external view returns (address);\n}\n\n/**\n * @title ProxyAdmin\n * @notice This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy,\n * based on the OpenZeppelin implementation. It has backwards compatibility logic to work\n * with the various types of proxies that have been deployed by Optimism in the past.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @notice The proxy types that the ProxyAdmin can manage.\n *\n * @custom:value ERC1967 Represents an ERC1967 compliant transparent proxy interface.\n * @custom:value CHUGSPLASH Represents the Chugsplash proxy interface (legacy).\n * @custom:value RESOLVED Represents the ResolvedDelegate proxy (legacy).\n */\n enum ProxyType {\n ERC1967,\n CHUGSPLASH,\n RESOLVED\n }\n\n /**\n * @notice A mapping of proxy types, used for backwards compatibility.\n */\n mapping(address => ProxyType) public proxyType;\n\n /**\n * @notice A reverse mapping of addresses to names held in the AddressManager. This must be\n * manually kept up to date with changes in the AddressManager for this contract\n * to be able to work as an admin for the ResolvedDelegateProxy type.\n */\n mapping(address => string) public implementationName;\n\n /**\n * @notice The address of the address manager, this is required to manage the\n * ResolvedDelegateProxy type.\n */\n AddressManager public addressManager;\n\n /**\n * @notice A legacy upgrading indicator used by the old Chugsplash Proxy.\n */\n bool internal upgrading;\n\n /**\n * @param _owner Address of the initial owner of this contract.\n */\n constructor(address _owner) Ownable() {\n _transferOwnership(_owner);\n }\n\n /**\n * @notice Sets the proxy type for a given address. Only required for non-standard (legacy)\n * proxy types.\n *\n * @param _address Address of the proxy.\n * @param _type Type of the proxy.\n */\n function setProxyType(address _address, ProxyType _type) external onlyOwner {\n proxyType[_address] = _type;\n }\n\n /**\n * @notice Sets the implementation name for a given address. Only required for\n * ResolvedDelegateProxy type proxies that have an implementation name.\n *\n * @param _address Address of the ResolvedDelegateProxy.\n * @param _name Name of the implementation for the proxy.\n */\n function setImplementationName(address _address, string memory _name) external onlyOwner {\n implementationName[_address] = _name;\n }\n\n /**\n * @notice Set the address of the AddressManager. This is required to manage legacy\n * ResolvedDelegateProxy type proxy contracts.\n *\n * @param _address Address of the AddressManager.\n */\n function setAddressManager(AddressManager _address) external onlyOwner {\n addressManager = _address;\n }\n\n /**\n * @custom:legacy\n * @notice Set an address in the address manager. Since only the owner of the AddressManager\n * can directly modify addresses and the ProxyAdmin will own the AddressManager, this\n * gives the owner of the ProxyAdmin the ability to modify addresses directly.\n *\n * @param _name Name to set within the AddressManager.\n * @param _address Address to attach to the given name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n addressManager.setAddress(_name, _address);\n }\n\n /**\n * @custom:legacy\n * @notice Set the upgrading status for the Chugsplash proxy type.\n *\n * @param _upgrading Whether or not the system is upgrading.\n */\n function setUpgrading(bool _upgrading) external onlyOwner {\n upgrading = _upgrading;\n }\n\n /**\n * @custom:legacy\n * @notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\n *\n * @return Whether or not there is an upgrade going on. May not actually tell you whether an\n * upgrade is going on, since we don't currently plan to use this variable for anything\n * other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\n */\n function isUpgrading() external view returns (bool) {\n return upgrading;\n }\n\n /**\n * @notice Returns the implementation of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the implementation of.\n *\n * @return Address of the implementation of the proxy.\n */\n function getProxyImplementation(address _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).implementation();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getImplementation();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.getAddress(implementationName[_proxy]);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Returns the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the admin of.\n *\n * @return Address of the admin of the proxy.\n */\n function getProxyAdmin(address payable _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).admin();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getOwner();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.owner();\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Updates the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to update.\n * @param _newAdmin Address of the new proxy admin.\n */\n function changeProxyAdmin(address payable _proxy, address _newAdmin) external onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).changeAdmin(_newAdmin);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setOwner(_newAdmin);\n } else if (ptype == ProxyType.RESOLVED) {\n addressManager.transferOwnership(_newAdmin);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n */\n function upgrade(address payable _proxy, address _implementation) public onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeTo(_implementation);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setStorage(\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n bytes32(uint256(uint160(_implementation)))\n );\n } else if (ptype == ProxyType.RESOLVED) {\n string memory name = implementationName[_proxy];\n addressManager.setAddress(name, _implementation);\n } else {\n // It should not be possible to retrieve a ProxyType value which is not matched by\n // one of the previous conditions.\n assert(false);\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract and delegatecalls the new implementation\n * with some given data. Useful for atomic upgrade-and-initialize calls.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n * @param _data Data to trigger the new implementation with.\n */\n function upgradeAndCall(\n address payable _proxy,\n address _implementation,\n bytes memory _data\n ) external payable onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);\n } else {\n // reverts if proxy type is unknown\n upgrade(_proxy, _implementation);\n (bool success, ) = _proxy.call{ value: msg.value }(_data);\n require(success, \"ProxyAdmin: call to proxy after upgrade failed\");\n }\n }\n}\n" - }, - "contracts/universal/Semver.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n" - }, - "contracts/universal/StandardBridge.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { IOptimismMintableERC20, ILegacyMintableERC20 } from \"./IOptimismMintableERC20.sol\";\nimport { CrossDomainMessenger } from \"./CrossDomainMessenger.sol\";\nimport { OptimismMintableERC20 } from \"./OptimismMintableERC20.sol\";\n\n/**\n * @custom:upgradeable\n * @title StandardBridge\n * @notice StandardBridge is a base contract for the L1 and L2 standard ERC20 bridges. It handles\n * the core bridging logic, including escrowing tokens that are native to the local chain\n * and minting/burning tokens that are native to the remote chain.\n */\nabstract contract StandardBridge {\n using SafeERC20 for IERC20;\n\n /**\n * @notice The L2 gas limit set when eth is depoisited using the receive() function.\n */\n uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000;\n\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable MESSENGER;\n\n /**\n * @notice Corresponding bridge on the other domain.\n */\n StandardBridge public immutable OTHER_BRIDGE;\n\n /**\n * @custom:legacy\n * @custom:spacer messenger\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer l2TokenBridge\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_1_0_20;\n\n /**\n * @notice Mapping that stores deposits for a given pair of local and remote tokens.\n */\n mapping(address => mapping(address => uint256)) public deposits;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n * A gap size of 47 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[47] private __gap;\n\n /**\n * @notice Emitted when an ETH bridge is initiated to the other chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeInitiated(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ETH bridge is finalized on this chain.\n *\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of ETH sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ETHBridgeFinalized(\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is initiated to the other chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC20 bridge is finalized on this chain.\n *\n * @param localToken Address of the ERC20 on this chain.\n * @param remoteToken Address of the ERC20 on the remote chain.\n * @param from Address of the sender.\n * @param to Address of the receiver.\n * @param amount Amount of the ERC20 sent.\n * @param extraData Extra data sent with the transaction.\n */\n event ERC20BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 amount,\n bytes extraData\n );\n\n /**\n * @notice Only allow EOAs to call the functions. Note that this is not safe against contracts\n * calling code within their constructors, but also doesn't really matter since we're\n * just trying to prevent users accidentally depositing with smart contract wallets.\n */\n modifier onlyEOA() {\n require(\n !Address.isContract(msg.sender),\n \"StandardBridge: function can only be called from an EOA\"\n );\n _;\n }\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(MESSENGER) &&\n MESSENGER.xDomainMessageSender() == address(OTHER_BRIDGE),\n \"StandardBridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of CrossDomainMessenger on this network.\n * @param _otherBridge Address of the other StandardBridge contract.\n */\n constructor(address payable _messenger, address payable _otherBridge) {\n MESSENGER = CrossDomainMessenger(_messenger);\n OTHER_BRIDGE = StandardBridge(_otherBridge);\n }\n\n /**\n * @notice Allows EOAs to bridge ETH by sending directly to the bridge.\n * Must be implemented by contracts that inherit.\n */\n receive() external payable virtual;\n\n /**\n * @custom:legacy\n * @notice Legacy getter for messenger contract.\n *\n * @return Messenger contract on this domain.\n */\n function messenger() external view returns (CrossDomainMessenger) {\n return MESSENGER;\n }\n\n /**\n * @notice Sends ETH to the sender's address on the other chain.\n *\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETH(uint32 _minGasLimit, bytes calldata _extraData) public payable onlyEOA {\n _initiateBridgeETH(msg.sender, msg.sender, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a\n * smart contract and the call fails, the ETH will be temporarily locked in the\n * StandardBridge on the other chain until the call is replayed. If the call cannot be\n * replayed with any amount of gas (call always reverts), then the ETH will be\n * permanently locked in the StandardBridge on the other chain. ETH will also\n * be locked if the receiver is the other bridge, because finalizeBridgeETH will revert\n * in that case.\n *\n * @param _to Address of the receiver.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeETHTo(\n address _to,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public payable {\n _initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData);\n }\n\n /**\n * @notice Sends ERC20 tokens to the sender's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20(\n address _localToken,\n address _remoteToken,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual onlyEOA {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the\n * ERC20 token on the other chain does not recognize the local token as the correct\n * pair token, the ERC20 bridge will fail and the tokens will be returned to sender on\n * this chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function bridgeERC20To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) public virtual {\n _initiateBridgeERC20(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _amount,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Finalizes an ETH bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public payable onlyOtherBridge {\n require(msg.value == _amount, \"StandardBridge: amount sent does not match amount required\");\n require(_to != address(this), \"StandardBridge: cannot send to self\");\n require(_to != address(MESSENGER), \"StandardBridge: cannot send to messenger\");\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeFinalized(_from, _to, _amount, _extraData);\n\n bool success = SafeCall.call(_to, gasleft(), _amount, hex\"\");\n require(success, \"StandardBridge: ETH transfer failed\");\n }\n\n /**\n * @notice Finalizes an ERC20 bridge on this chain. Can only be triggered by the other\n * StandardBridge contract on the remote chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 being bridged.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function finalizeBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes calldata _extraData\n ) public onlyOtherBridge {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).mint(_to, _amount);\n } else {\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] - _amount;\n IERC20(_localToken).safeTransfer(_to, _amount);\n }\n\n // Emit the correct events. By default this will be ERC20BridgeFinalized, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Initiates a bridge of ETH through the CrossDomainMessenger.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH being bridged.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeETH(\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n require(\n msg.value == _amount,\n \"StandardBridge: bridging ETH must include sufficient ETH value\"\n );\n\n // Emit the correct events. By default this will be _amount, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitETHBridgeInitiated(_from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage{ value: _amount }(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeETH.selector,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Sends ERC20 tokens to a receiver's address on the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the corresponding token on the remote chain.\n * @param _to Address of the receiver.\n * @param _amount Amount of local tokens to deposit.\n * @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.\n * @param _extraData Extra data to be sent with the transaction. Note that the recipient will\n * not be triggered with this data, but it will be emitted and can be used\n * to identify the transaction.\n */\n function _initiateBridgeERC20(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n uint32 _minGasLimit,\n bytes memory _extraData\n ) internal {\n if (_isOptimismMintableERC20(_localToken)) {\n require(\n _isCorrectTokenPair(_localToken, _remoteToken),\n \"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token\"\n );\n\n OptimismMintableERC20(_localToken).burn(_from, _amount);\n } else {\n IERC20(_localToken).safeTransferFrom(_from, address(this), _amount);\n deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] + _amount;\n }\n\n // Emit the correct events. By default this will be ERC20BridgeInitiated, but child\n // contracts may override this function in order to emit legacy events as well.\n _emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n\n MESSENGER.sendMessage(\n address(OTHER_BRIDGE),\n abi.encodeWithSelector(\n this.finalizeBridgeERC20.selector,\n // Because this call will be executed on the remote chain, we reverse the order of\n // the remote and local token addresses relative to their order in the\n // finalizeBridgeERC20 function.\n _remoteToken,\n _localToken,\n _from,\n _to,\n _amount,\n _extraData\n ),\n _minGasLimit\n );\n }\n\n /**\n * @notice Checks if a given address is an OptimismMintableERC20. Not perfect, but good enough.\n * Just the way we like it.\n *\n * @param _token Address of the token to check.\n *\n * @return True if the token is an OptimismMintableERC20.\n */\n function _isOptimismMintableERC20(address _token) internal view returns (bool) {\n return\n ERC165Checker.supportsInterface(_token, type(ILegacyMintableERC20).interfaceId) ||\n ERC165Checker.supportsInterface(_token, type(IOptimismMintableERC20).interfaceId);\n }\n\n /**\n * @notice Checks if the \"other token\" is the correct pair token for the OptimismMintableERC20.\n * Calls can be saved in the future by combining this logic with\n * `_isOptimismMintableERC20`.\n *\n * @param _mintableToken OptimismMintableERC20 to check against.\n * @param _otherToken Pair token to check.\n *\n * @return True if the other token is the correct pair token for the OptimismMintableERC20.\n */\n function _isCorrectTokenPair(address _mintableToken, address _otherToken)\n internal\n view\n returns (bool)\n {\n if (\n ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)\n ) {\n return _otherToken == ILegacyMintableERC20(_mintableToken).l1Token();\n } else {\n return _otherToken == IOptimismMintableERC20(_mintableToken).remoteToken();\n }\n }\n\n /** @notice Emits the ETHBridgeInitiated event and if necessary the appropriate legacy event\n * when an ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeInitiated(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeInitiated(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ETHBridgeFinalized and if necessary the appropriate legacy event when an\n * ETH bridge is finalized on this chain.\n *\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of ETH sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitETHBridgeFinalized(\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ETHBridgeFinalized(_from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeInitiated event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeInitiated(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n\n /**\n * @notice Emits the ERC20BridgeFinalized event and if necessary the appropriate legacy\n * event when an ERC20 bridge is initiated to the other chain.\n *\n * @param _localToken Address of the ERC20 on this chain.\n * @param _remoteToken Address of the ERC20 on the remote chain.\n * @param _from Address of the sender.\n * @param _to Address of the receiver.\n * @param _amount Amount of the ERC20 sent.\n * @param _extraData Extra data sent with the transaction.\n */\n function _emitERC20BridgeFinalized(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _amount,\n bytes memory _extraData\n ) internal virtual {\n emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);\n }\n}\n" - }, - "contracts/vendor/AddressAliasHelper.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.0;\n\nlibrary AddressAliasHelper {\n uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n /// @notice Utility function that converts the address in the L1 that submitted a tx to\n /// the inbox to the msg.sender viewed in the L2\n /// @param l1Address the address in the L1 that triggered the tx to L2\n /// @return l2Address L2 address as viewed in msg.sender\n function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {\n unchecked {\n l2Address = address(uint160(l1Address) + offset);\n }\n }\n\n /// @notice Utility function that converts the msg.sender viewed in the L2 to the\n /// address in the L1 that submitted a tx to the inbox\n /// @param l2Address L2 address as viewed in msg.sender\n /// @return l1Address the address in the L1 that triggered the tx to L2\n function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {\n unchecked {\n l1Address = address(uint160(l2Address) - offset);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/governance/utils/IVotes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20Permit.sol\";\nimport \"../../../utils/math/Math.sol\";\nimport \"../../../governance/utils/IVotes.sol\";\nimport \"../../../utils/math/SafeCast.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20Votes is IVotes, ERC20Permit {\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCast.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = Math.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSA.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"./IERC721Enumerable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n // Mapping from owner to list of owned token IDs\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n // Mapping from token ID to index of the owner tokens list\n mapping(uint256 => uint256) private _ownedTokensIndex;\n\n // Array with all token ids, used for enumeration\n uint256[] private _allTokens;\n\n // Mapping from token id to position in the allTokens array\n mapping(uint256 => uint256) private _allTokensIndex;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n return _ownedTokens[owner][index];\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _allTokens.length;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721Enumerable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n return _allTokens[index];\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n if (from == address(0)) {\n _addTokenToAllTokensEnumeration(tokenId);\n } else if (from != to) {\n _removeTokenFromOwnerEnumeration(from, tokenId);\n }\n if (to == address(0)) {\n _removeTokenFromAllTokensEnumeration(tokenId);\n } else if (to != from) {\n _addTokenToOwnerEnumeration(to, tokenId);\n }\n }\n\n /**\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\n * @param to address representing the new owner of the given token ID\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n */\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n uint256 length = ERC721.balanceOf(to);\n _ownedTokens[to][length] = tokenId;\n _ownedTokensIndex[tokenId] = length;\n }\n\n /**\n * @dev Private function to add a token to this extension's token tracking data structures.\n * @param tokenId uint256 ID of the token to be added to the tokens list\n */\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n _allTokensIndex[tokenId] = _allTokens.length;\n _allTokens.push(tokenId);\n }\n\n /**\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n * @param from address representing the previous owner of the given token ID\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n */\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary\n if (tokenIndex != lastTokenIndex) {\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n }\n\n // This also deletes the contents at the last position of the array\n delete _ownedTokensIndex[tokenId];\n delete _ownedTokens[from][lastTokenIndex];\n }\n\n /**\n * @dev Private function to remove a token from this extension's token tracking data structures.\n * This has O(1) time complexity, but alters the order of the _allTokens array.\n * @param tokenId uint256 ID of the token to be removed from the tokens list\n */\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = _allTokens.length - 1;\n uint256 tokenIndex = _allTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n // This also deletes the contents at the last position of the array\n delete _allTokensIndex[tokenId];\n _allTokens.pop();\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n" - }, - "node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Counters.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface,\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n _supportsERC165Interface(account, type(IERC165).interfaceId) &&\n !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)\n internal\n view\n returns (bool[] memory)\n {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in _interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!_supportsERC165Interface(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n * Interface identification is specified in ERC-165.\n */\n function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/Bytes32AddressLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Library for converting between addresses and bytes32 values.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)\nlibrary Bytes32AddressLib {\n function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {\n return bytes32(bytes20(addressValue));\n }\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n /*//////////////////////////////////////////////////////////////\n SIMPLIFIED FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n }\n\n function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n }\n\n function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n }\n\n function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n }\n\n function powWad(int256 x, int256 y) internal pure returns (int256) {\n // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\n return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\n }\n\n function expWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n // When the result is < 0.5 we return zero. This happens when\n // x <= floor(log(0.5e18) * 1e18) ~ -42e18\n if (x <= -42139678854452767551) return 0;\n\n // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\n // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\n if (x >= 135305999368893231589) revert(\"EXP_OVERFLOW\");\n\n // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\n // for more intermediate precision and a binary basis. This base conversion\n // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n x = (x << 78) / 5**18;\n\n // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\n x = x - k * 54916777467707473351141471128;\n\n // k is in the range [-61, 195].\n\n // Evaluate using a (6, 7)-term rational approximation.\n // p is made monic, we'll multiply by a scale factor later.\n int256 y = x + 1346386616545796478920950773328;\n y = ((y * x) >> 96) + 57155421227552351082224309758442;\n int256 p = y + x - 94201549194550492254356042504812;\n p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n p = p * x + (4385272521454847904659076985693276 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n int256 q = x - 2855989394907223263936484059900;\n q = ((q * x) >> 96) + 50020603652535783019961831881945;\n q = ((q * x) >> 96) - 533845033583426703283633433725380;\n q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial won't have zeros in the domain as all its roots are complex.\n // No scaling is necessary because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r should be in the range (0.09, 0.25) * 2**96.\n\n // We now need to multiply r by:\n // * the scale factor s = ~6.031367120.\n // * the 2**k factor from the range reduction.\n // * the 1e18 / 2**96 factor for base conversion.\n // We do this all at once, with an intermediate result in 2**213\n // basis, so the final right shift is always by a positive amount.\n r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\n }\n }\n\n function lnWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n require(x > 0, \"UNDEFINED\");\n\n // We want to convert x from 10**18 fixed point to 2**96 fixed point.\n // We do this by multiplying by 2**96 / 10**18. But since\n // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\n // and add ln(2**96 / 10**18) at the end.\n\n // Reduce range of x to (1, 2) * 2**96\n // ln(2^k * x) = k * ln(2) + ln(x)\n int256 k = int256(log2(uint256(x))) - 96;\n x <<= uint256(159 - k);\n x = int256(uint256(x) >> 159);\n\n // Evaluate using a (8, 8)-term rational approximation.\n // p is made monic, we will multiply by a scale factor later.\n int256 p = x + 3273285459638523848632254066296;\n p = ((p * x) >> 96) + 24828157081833163892658089445524;\n p = ((p * x) >> 96) + 43456485725739037958740375743393;\n p = ((p * x) >> 96) - 11111509109440967052023855526967;\n p = ((p * x) >> 96) - 45023709667254063763336534515857;\n p = ((p * x) >> 96) - 14706773417378608786704636184526;\n p = p * x - (795164235651350426258249787498 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n // q is monic by convention.\n int256 q = x + 5573035233440673466300451813936;\n q = ((q * x) >> 96) + 71694874799317883764090561454958;\n q = ((q * x) >> 96) + 283447036172924575727196451306956;\n q = ((q * x) >> 96) + 401686690394027663651624208769553;\n q = ((q * x) >> 96) + 204048457590392012362485061816622;\n q = ((q * x) >> 96) + 31853899698501571402653359427138;\n q = ((q * x) >> 96) + 909429971244387300277376558375;\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial is known not to have zeros in the domain.\n // No scaling required because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r is in the range (0, 0.125) * 2**96\n\n // Finalization, we need to:\n // * multiply by the scale factor s = 5.549…\n // * add ln(2**96 / 10**18)\n // * add k * ln(2)\n // * multiply by 10**18 / 2**96 = 5**18 >> 78\n\n // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\n r *= 1677202110996718588342820967067443963516166;\n // add ln(2) * k * 5e18 * 2**192\n r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\n // add ln(2**96 / 10**18) * 5e18 * 2**192\n r += 600920179829731861736702779321621459595472258049074101567377883020018308;\n // base conversion: mul 2**18 / 2**192\n r >>= 174;\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n LOW LEVEL FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function mulDivDown(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // Divide z by the denominator.\n z := div(z, denominator)\n }\n }\n\n function mulDivUp(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // First, divide z - 1 by the denominator and add 1.\n // We allow z - 1 to underflow if z is 0, because we multiply the\n // end result by 0 if z is zero, ensuring we return 0 if z is zero.\n z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\n }\n }\n\n function rpow(\n uint256 x,\n uint256 n,\n uint256 scalar\n ) internal pure returns (uint256 z) {\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n // 0 ** 0 = 1\n z := scalar\n }\n default {\n // 0 ** n = 0\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n // If n is even, store scalar in z for now.\n z := scalar\n }\n default {\n // If n is odd, store x in z for now.\n z := x\n }\n\n // Shifting right by 1 is like dividing by 2.\n let half := shr(1, scalar)\n\n for {\n // Shift n right by 1 before looping to halve it.\n n := shr(1, n)\n } n {\n // Shift n right by 1 each iteration to halve it.\n n := shr(1, n)\n } {\n // Revert immediately if x ** 2 would overflow.\n // Equivalent to iszero(eq(div(xx, x), x)) here.\n if shr(128, x) {\n revert(0, 0)\n }\n\n // Store x squared.\n let xx := mul(x, x)\n\n // Round to the nearest number.\n let xxRound := add(xx, half)\n\n // Revert if xx + half overflowed.\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n\n // Set x to scaled xxRound.\n x := div(xxRound, scalar)\n\n // If n is even:\n if mod(n, 2) {\n // Compute z * x.\n let zx := mul(z, x)\n\n // If z * x overflowed:\n if iszero(eq(div(zx, x), z)) {\n // Revert if x is non-zero.\n if iszero(iszero(x)) {\n revert(0, 0)\n }\n }\n\n // Round to the nearest number.\n let zxRound := add(zx, half)\n\n // Revert if zx + half overflowed.\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n\n // Return properly scaled zxRound.\n z := div(zxRound, scalar)\n }\n }\n }\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n GENERAL NUMBER UTILITIES\n //////////////////////////////////////////////////////////////*/\n\n function sqrt(uint256 x) internal pure returns (uint256 z) {\n assembly {\n let y := x // We start y at x, which will help us make our initial estimate.\n\n z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n // We check y >= 2^(k + 8) but shift right by k bits\n // each branch to ensure that if x >= 256, then y >= 256.\n if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n y := shr(128, y)\n z := shl(64, z)\n }\n if iszero(lt(y, 0x1000000000000000000)) {\n y := shr(64, y)\n z := shl(32, z)\n }\n if iszero(lt(y, 0x10000000000)) {\n y := shr(32, y)\n z := shl(16, z)\n }\n if iszero(lt(y, 0x1000000)) {\n y := shr(16, y)\n z := shl(8, z)\n }\n\n // Goal was to get z*z*y within a small factor of x. More iterations could\n // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n // There is no overflow risk here since y < 2^136 after the first branch above.\n z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n\n // If x+1 is a perfect square, the Babylonian method cycles between\n // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n z := sub(z, lt(div(x, z), z))\n }\n }\n\n function log2(uint256 x) internal pure returns (uint256 r) {\n require(x > 0, \"UNDEFINED\");\n\n assembly {\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\n r := or(r, shl(3, lt(0xff, shr(r, x))))\n r := or(r, shl(2, lt(0xf, shr(r, x))))\n r := or(r, shl(1, lt(0x3, shr(r, x))))\n r := or(r, lt(0x1, shr(r, x)))\n }\n }\n}\n" - }, - "node_modules/ds-test/src/test.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.5.0;\n\ncontract DSTest {\n event log (string);\n event logs (bytes);\n\n event log_address (address);\n event log_bytes32 (bytes32);\n event log_int (int);\n event log_uint (uint);\n event log_bytes (bytes);\n event log_string (string);\n\n event log_named_address (string key, address val);\n event log_named_bytes32 (string key, bytes32 val);\n event log_named_decimal_int (string key, int val, uint decimals);\n event log_named_decimal_uint (string key, uint val, uint decimals);\n event log_named_int (string key, int val);\n event log_named_uint (string key, uint val);\n event log_named_bytes (string key, bytes val);\n event log_named_string (string key, string val);\n\n bool public IS_TEST = true;\n bool private _failed;\n\n address constant HEVM_ADDRESS =\n address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));\n\n modifier mayRevert() { _; }\n modifier testopts(string memory) { _; }\n\n function failed() public returns (bool) {\n if (_failed) {\n return _failed;\n } else {\n bool globalFailed = false;\n if (hasHEVMContext()) {\n (, bytes memory retdata) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"load(address,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"))\n )\n );\n globalFailed = abi.decode(retdata, (bool));\n }\n return globalFailed;\n }\n } \n\n function fail() internal {\n if (hasHEVMContext()) {\n (bool status, ) = HEVM_ADDRESS.call(\n abi.encodePacked(\n bytes4(keccak256(\"store(address,bytes32,bytes32)\")),\n abi.encode(HEVM_ADDRESS, bytes32(\"failed\"), bytes32(uint256(0x01)))\n )\n );\n status; // Silence compiler warnings\n }\n _failed = true;\n }\n\n function hasHEVMContext() internal view returns (bool) {\n uint256 hevmCodeSize = 0;\n assembly {\n hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D)\n }\n return hevmCodeSize > 0;\n }\n\n modifier logs_gas() {\n uint startGas = gasleft();\n _;\n uint endGas = gasleft();\n emit log_named_uint(\"gas\", startGas - endGas);\n }\n\n function assertTrue(bool condition) internal {\n if (!condition) {\n emit log(\"Error: Assertion Failed\");\n fail();\n }\n }\n\n function assertTrue(bool condition, string memory err) internal {\n if (!condition) {\n emit log_named_string(\"Error\", err);\n assertTrue(condition);\n }\n }\n\n function assertEq(address a, address b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [address]\");\n emit log_named_address(\" Expected\", b);\n emit log_named_address(\" Actual\", a);\n fail();\n }\n }\n function assertEq(address a, address b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes32 a, bytes32 b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bytes32]\");\n emit log_named_bytes32(\" Expected\", b);\n emit log_named_bytes32(\" Actual\", a);\n fail();\n }\n }\n function assertEq(bytes32 a, bytes32 b, string memory err) internal {\n if (a != b) {\n emit log_named_string (\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq32(bytes32 a, bytes32 b) internal {\n assertEq(a, b);\n }\n function assertEq32(bytes32 a, bytes32 b, string memory err) internal {\n assertEq(a, b, err);\n }\n\n function assertEq(int a, int b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [int]\");\n emit log_named_int(\" Expected\", b);\n emit log_named_int(\" Actual\", a);\n fail();\n }\n }\n function assertEq(int a, int b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEq(uint a, uint b) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [uint]\");\n emit log_named_uint(\" Expected\", b);\n emit log_named_uint(\" Actual\", a);\n fail();\n }\n }\n function assertEq(uint a, uint b, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n function assertEqDecimal(int a, int b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Expected\", b, decimals);\n emit log_named_decimal_int(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals) internal {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Expected\", b, decimals);\n emit log_named_decimal_uint(\" Actual\", a, decimals);\n fail();\n }\n }\n function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEqDecimal(a, b, decimals);\n }\n }\n\n function assertGt(uint a, uint b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGt(uint a, uint b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGt(int a, int b) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGt(int a, int b, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGt(a, b);\n }\n }\n function assertGtDecimal(int a, int b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals) internal {\n if (a <= b) {\n emit log(\"Error: a > b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a <= b) {\n emit log_named_string(\"Error\", err);\n assertGtDecimal(a, b, decimals);\n }\n }\n\n function assertGe(uint a, uint b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertGe(uint a, uint b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGe(int a, int b) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertGe(int a, int b, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGe(a, b);\n }\n }\n function assertGeDecimal(int a, int b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals) internal {\n if (a < b) {\n emit log(\"Error: a >= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a < b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertLt(uint a, uint b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLt(uint a, uint b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLt(int a, int b) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLt(int a, int b, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLt(a, b);\n }\n }\n function assertLtDecimal(int a, int b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals) internal {\n if (a >= b) {\n emit log(\"Error: a < b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a >= b) {\n emit log_named_string(\"Error\", err);\n assertLtDecimal(a, b, decimals);\n }\n }\n\n function assertLe(uint a, uint b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [uint]\");\n emit log_named_uint(\" Value a\", a);\n emit log_named_uint(\" Value b\", b);\n fail();\n }\n }\n function assertLe(uint a, uint b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLe(int a, int b) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [int]\");\n emit log_named_int(\" Value a\", a);\n emit log_named_int(\" Value b\", b);\n fail();\n }\n }\n function assertLe(int a, int b, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLe(a, b);\n }\n }\n function assertLeDecimal(int a, int b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal int]\");\n emit log_named_decimal_int(\" Value a\", a, decimals);\n emit log_named_decimal_int(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertLeDecimal(a, b, decimals);\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals) internal {\n if (a > b) {\n emit log(\"Error: a <= b not satisfied [decimal uint]\");\n emit log_named_decimal_uint(\" Value a\", a, decimals);\n emit log_named_decimal_uint(\" Value b\", b, decimals);\n fail();\n }\n }\n function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {\n if (a > b) {\n emit log_named_string(\"Error\", err);\n assertGeDecimal(a, b, decimals);\n }\n }\n\n function assertEq(string memory a, string memory b) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log(\"Error: a == b not satisfied [string]\");\n emit log_named_string(\" Expected\", b);\n emit log_named_string(\" Actual\", a);\n fail();\n }\n }\n function assertEq(string memory a, string memory b, string memory err) internal {\n if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {\n ok = true;\n if (a.length == b.length) {\n for (uint i = 0; i < a.length; i++) {\n if (a[i] != b[i]) {\n ok = false;\n }\n }\n } else {\n ok = false;\n }\n }\n function assertEq0(bytes memory a, bytes memory b) internal {\n if (!checkEq0(a, b)) {\n emit log(\"Error: a == b not satisfied [bytes]\");\n emit log_named_bytes(\" Expected\", b);\n emit log_named_bytes(\" Actual\", a);\n fail();\n }\n }\n function assertEq0(bytes memory a, bytes memory b, string memory err) internal {\n if (!checkEq0(a, b)) {\n emit log_named_string(\"Error\", err);\n assertEq0(a, b);\n }\n }\n}\n" - }, - "node_modules/forge-std/src/Base.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {StdStorage} from \"./StdStorage.sol\";\nimport {Vm, VmSafe} from \"./Vm.sol\";\n\nabstract contract CommonBase {\n // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.\n address internal constant VM_ADDRESS = address(uint160(uint256(keccak256(\"hevm cheat code\"))));\n // console.sol and console2.sol work by executing a staticcall to this address.\n address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;\n // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38.\n address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256(\"foundry default caller\"))));\n // Address of the test contract, deployed by the DEFAULT_SENDER.\n address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;\n // Deterministic deployment address of the Multicall3 contract.\n address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11;\n\n uint256 internal constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n Vm internal constant vm = Vm(VM_ADDRESS);\n StdStorage internal stdstore;\n}\n\nabstract contract TestBase is CommonBase {}\n\nabstract contract ScriptBase is CommonBase {\n // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);\n}\n" - }, - "node_modules/forge-std/src/StdAssertions.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {DSTest} from \"ds-test/test.sol\";\nimport {stdMath} from \"./StdMath.sol\";\n\nabstract contract StdAssertions is DSTest {\n event log_array(uint256[] val);\n event log_array(int256[] val);\n event log_array(address[] val);\n event log_named_array(string key, uint256[] val);\n event log_named_array(string key, int256[] val);\n event log_named_array(string key, address[] val);\n\n function fail(string memory err) internal virtual {\n emit log_named_string(\"Error\", err);\n fail();\n }\n\n function assertFalse(bool data) internal virtual {\n assertTrue(!data);\n }\n\n function assertFalse(bool data, string memory err) internal virtual {\n assertTrue(!data, err);\n }\n\n function assertEq(bool a, bool b) internal virtual {\n if (a != b) {\n emit log(\"Error: a == b not satisfied [bool]\");\n emit log_named_string(\" Left\", a ? \"true\" : \"false\");\n emit log_named_string(\" Right\", b ? \"true\" : \"false\");\n fail();\n }\n }\n\n function assertEq(bool a, bool b, string memory err) internal virtual {\n if (a != b) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(bytes memory a, bytes memory b) internal virtual {\n assertEq0(a, b);\n }\n\n function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual {\n assertEq0(a, b, err);\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [uint[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [int[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(address[] memory a, address[] memory b) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log(\"Error: a == b not satisfied [address[]]\");\n emit log_named_array(\" Left\", a);\n emit log_named_array(\" Right\", b);\n fail();\n }\n }\n\n function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual {\n if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {\n emit log_named_string(\"Error\", err);\n assertEq(a, b);\n }\n }\n\n // Legacy helper\n function assertEqUint(uint256 a, uint256 b) internal virtual {\n assertEq(uint256(a), uint256(b));\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_uint(\" Max Delta\", maxDelta);\n emit log_named_uint(\" Delta\", delta);\n fail();\n }\n }\n\n function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbs(a, b, maxDelta);\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max Delta\", maxDelta, decimals);\n emit log_named_decimal_uint(\" Delta\", delta, decimals);\n fail();\n }\n }\n\n function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n uint256 delta = stdMath.delta(a, b);\n\n if (delta > maxDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqAbsDecimal(a, b, maxDelta, decimals);\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100%\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_uint(\" Left\", a);\n emit log_named_uint(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals\n ) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [uint]\");\n emit log_named_decimal_uint(\" Left\", a, decimals);\n emit log_named_decimal_uint(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(\n uint256 a,\n uint256 b,\n uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%\n uint256 decimals,\n string memory err\n ) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_int(\" Left\", a);\n emit log_named_int(\" Right\", b);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRel(a, b, maxPercentDelta);\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual {\n if (b == 0) return assertEq(a, b); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log(\"Error: a ~= b not satisfied [int]\");\n emit log_named_decimal_int(\" Left\", a, decimals);\n emit log_named_decimal_int(\" Right\", b, decimals);\n emit log_named_decimal_uint(\" Max % Delta\", maxPercentDelta, 18);\n emit log_named_decimal_uint(\" % Delta\", percentDelta, 18);\n fail();\n }\n }\n\n function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err)\n internal\n virtual\n {\n if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too.\n\n uint256 percentDelta = stdMath.percentDelta(a, b);\n\n if (percentDelta > maxPercentDelta) {\n emit log_named_string(\"Error\", err);\n assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals);\n }\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual {\n assertEqCall(target, callDataA, target, callDataB, true);\n }\n\n function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB)\n internal\n virtual\n {\n assertEqCall(targetA, callDataA, targetB, callDataB, true);\n }\n\n function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData)\n internal\n virtual\n {\n assertEqCall(target, callDataA, target, callDataB, strictRevertData);\n }\n\n function assertEqCall(\n address targetA,\n bytes memory callDataA,\n address targetB,\n bytes memory callDataB,\n bool strictRevertData\n ) internal virtual {\n (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA);\n (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB);\n\n if (successA && successB) {\n assertEq(returnDataA, returnDataB, \"Call return data does not match\");\n }\n\n if (!successA && !successB && strictRevertData) {\n assertEq(returnDataA, returnDataB, \"Call revert data does not match\");\n }\n\n if (!successA && successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call revert data\", returnDataA);\n emit log_named_bytes(\" Right call return data\", returnDataB);\n fail();\n }\n\n if (successA && !successB) {\n emit log(\"Error: Calls were not equal\");\n emit log_named_bytes(\" Left call return data\", returnDataA);\n emit log_named_bytes(\" Right call revert data\", returnDataB);\n fail();\n }\n }\n}\n" - }, - "node_modules/forge-std/src/StdChains.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n/**\n * StdChains provides information about EVM compatible chains that can be used in scripts/tests.\n * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are\n * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of\n * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the\n * alias used in this contract, which can be found as the first argument to the\n * `setChainWithDefaultRpcUrl` call in the `initialize` function.\n *\n * There are two main ways to use this contract:\n * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or\n * `setChain(string memory chainAlias, Chain memory chain)`\n * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`.\n *\n * The first time either of those are used, chains are initialized with the default set of RPC URLs.\n * This is done in `initialize`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in\n * `defaultRpcUrls`.\n *\n * The `setChain` function is straightforward, and it simply saves off the given chain data.\n *\n * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say\n * we want to retrieve `mainnet`'s RPC URL:\n * - If you haven't set any mainnet chain info with `setChain`, you haven't specified that\n * chain in `foundry.toml` and no env var is set, the default data and RPC URL will be returned.\n * - If you have set a mainnet RPC URL in `foundry.toml` it will return that, if valid (e.g. if\n * a URL is given or if an environment variable is given and that environment variable exists).\n * Otherwise, the default data is returned.\n * - If you specified data with `setChain` it will return that.\n *\n * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.\n */\nabstract contract StdChains {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private initialized;\n\n struct ChainData {\n string name;\n uint256 chainId;\n string rpcUrl;\n }\n\n struct Chain {\n // The chain name.\n string name;\n // The chain's Chain ID.\n uint256 chainId;\n // The chain's alias. (i.e. what gets specified in `foundry.toml`).\n string chainAlias;\n // A default RPC endpoint for this chain.\n // NOTE: This default RPC URL is included for convenience to facilitate quick tests and\n // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy\n // usage as you will be throttled and this is a disservice to others who need this endpoint.\n string rpcUrl;\n }\n\n // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data.\n mapping(string => Chain) private chains;\n // Maps from the chain's alias to it's default RPC URL.\n mapping(string => string) private defaultRpcUrls;\n // Maps from a chain ID to it's alias.\n mapping(uint256 => string) private idToAlias;\n\n bool private fallbackToDefaultRpcUrls = true;\n\n // The RPC URL will be fetched from config or defaultRpcUrls if possible.\n function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) {\n require(bytes(chainAlias).length != 0, \"StdChains getChain(string): Chain alias cannot be the empty string.\");\n\n initialize();\n chain = chains[chainAlias];\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(string): Chain with alias \\\"\", chainAlias, \"\\\" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n function getChain(uint256 chainId) internal virtual returns (Chain memory chain) {\n require(chainId != 0, \"StdChains getChain(uint256): Chain ID cannot be 0.\");\n initialize();\n string memory chainAlias = idToAlias[chainId];\n\n chain = chains[chainAlias];\n\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(uint256): Chain with ID \", vm.toString(chainId), \" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, ChainData memory chain) internal virtual {\n require(\n bytes(chainAlias).length != 0,\n \"StdChains setChain(string,ChainData): Chain alias cannot be the empty string.\"\n );\n\n require(chain.chainId != 0, \"StdChains setChain(string,ChainData): Chain ID cannot be 0.\");\n\n initialize();\n string memory foundAlias = idToAlias[chain.chainId];\n\n require(\n bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)),\n string(\n abi.encodePacked(\n \"StdChains setChain(string,ChainData): Chain ID \",\n vm.toString(chain.chainId),\n \" already used by \\\"\",\n foundAlias,\n \"\\\".\"\n )\n )\n );\n\n uint256 oldChainId = chains[chainAlias].chainId;\n delete idToAlias[oldChainId];\n\n chains[chainAlias] =\n Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl});\n idToAlias[chain.chainId] = chainAlias;\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, Chain memory chain) internal virtual {\n setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl}));\n }\n\n function _toUpper(string memory str) private pure returns (string memory) {\n bytes memory strb = bytes(str);\n bytes memory copy = new bytes(strb.length);\n for (uint256 i = 0; i < strb.length; i++) {\n bytes1 b = strb[i];\n if (b >= 0x61 && b <= 0x7A) {\n copy[i] = bytes1(uint8(b) - 32);\n } else {\n copy[i] = b;\n }\n }\n return string(copy);\n }\n\n // lookup rpcUrl, in descending order of priority:\n // current -> config (foundry.toml) -> environment variable -> default\n function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) {\n if (bytes(chain.rpcUrl).length == 0) {\n try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) {\n chain.rpcUrl = configRpcUrl;\n } catch (bytes memory err) {\n string memory envName = string(abi.encodePacked(_toUpper(chainAlias), \"_RPC_URL\"));\n if (fallbackToDefaultRpcUrls) {\n chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]);\n } else {\n chain.rpcUrl = vm.envString(envName);\n }\n // distinguish 'not found' from 'cannot read'\n bytes memory notFoundError =\n abi.encodeWithSignature(\"CheatCodeError\", string(abi.encodePacked(\"invalid rpc url \", chainAlias)));\n if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, err), mload(err))\n }\n }\n }\n }\n return chain;\n }\n\n function setFallbackToDefaultRpcUrls(bool useDefault) internal {\n fallbackToDefaultRpcUrls = useDefault;\n }\n\n function initialize() private {\n if (initialized) return;\n\n initialized = true;\n\n // If adding an RPC here, make sure to test the default RPC URL in `testRpcs`\n setChainWithDefaultRpcUrl(\"anvil\", ChainData(\"Anvil\", 31337, \"http://127.0.0.1:8545\"));\n setChainWithDefaultRpcUrl(\n \"mainnet\", ChainData(\"Mainnet\", 1, \"https://mainnet.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"goerli\", ChainData(\"Goerli\", 5, \"https://goerli.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\n \"sepolia\", ChainData(\"Sepolia\", 11155111, \"https://sepolia.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b\")\n );\n setChainWithDefaultRpcUrl(\"optimism\", ChainData(\"Optimism\", 10, \"https://mainnet.optimism.io\"));\n setChainWithDefaultRpcUrl(\"optimism_goerli\", ChainData(\"Optimism Goerli\", 420, \"https://goerli.optimism.io\"));\n setChainWithDefaultRpcUrl(\"arbitrum_one\", ChainData(\"Arbitrum One\", 42161, \"https://arb1.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\n \"arbitrum_one_goerli\", ChainData(\"Arbitrum One Goerli\", 421613, \"https://goerli-rollup.arbitrum.io/rpc\")\n );\n setChainWithDefaultRpcUrl(\"arbitrum_nova\", ChainData(\"Arbitrum Nova\", 42170, \"https://nova.arbitrum.io/rpc\"));\n setChainWithDefaultRpcUrl(\"polygon\", ChainData(\"Polygon\", 137, \"https://polygon-rpc.com\"));\n setChainWithDefaultRpcUrl(\n \"polygon_mumbai\", ChainData(\"Polygon Mumbai\", 80001, \"https://rpc-mumbai.maticvigil.com\")\n );\n setChainWithDefaultRpcUrl(\"avalanche\", ChainData(\"Avalanche\", 43114, \"https://api.avax.network/ext/bc/C/rpc\"));\n setChainWithDefaultRpcUrl(\n \"avalanche_fuji\", ChainData(\"Avalanche Fuji\", 43113, \"https://api.avax-test.network/ext/bc/C/rpc\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain\", ChainData(\"BNB Smart Chain\", 56, \"https://bsc-dataseed1.binance.org\")\n );\n setChainWithDefaultRpcUrl(\n \"bnb_smart_chain_testnet\",\n ChainData(\"BNB Smart Chain Testnet\", 97, \"https://rpc.ankr.com/bsc_testnet_chapel\")\n );\n setChainWithDefaultRpcUrl(\"gnosis_chain\", ChainData(\"Gnosis Chain\", 100, \"https://rpc.gnosischain.com\"));\n }\n\n // set chain info, with priority to chainAlias' rpc url in foundry.toml\n function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private {\n string memory rpcUrl = chain.rpcUrl;\n defaultRpcUrls[chainAlias] = rpcUrl;\n chain.rpcUrl = \"\";\n setChain(chainAlias, chain);\n chain.rpcUrl = rpcUrl; // restore argument\n }\n}\n" - }, - "node_modules/forge-std/src/StdCheats.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdCheatsSafe {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private gasMeteringOff;\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawTx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n // json value name = function\n string functionSig;\n bytes32 hash;\n // json value name = tx\n RawTx1559Detail txDetail;\n // json value name = type\n string opcode;\n }\n\n struct RawTx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n bytes gas;\n bytes nonce;\n address to;\n bytes txType;\n bytes value;\n }\n\n struct Tx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n bytes32 hash;\n Tx1559Detail txDetail;\n string opcode;\n }\n\n struct Tx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n uint256 gas;\n uint256 nonce;\n address to;\n uint256 txType;\n uint256 value;\n }\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct TxLegacy {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n string hash;\n string opcode;\n TxDetailLegacy transaction;\n }\n\n struct TxDetailLegacy {\n AccessList[] accessList;\n uint256 chainId;\n bytes data;\n address from;\n uint256 gas;\n uint256 gasPrice;\n bytes32 hash;\n uint256 nonce;\n bytes1 opcode;\n bytes32 r;\n bytes32 s;\n uint256 txType;\n address to;\n uint8 v;\n uint256 value;\n }\n\n struct AccessList {\n address accessAddress;\n bytes32[] storageKeys;\n }\n\n // Data structures to parse Receipt objects from the broadcast artifact.\n // The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawReceipt {\n bytes32 blockHash;\n bytes blockNumber;\n address contractAddress;\n bytes cumulativeGasUsed;\n bytes effectiveGasPrice;\n address from;\n bytes gasUsed;\n RawReceiptLog[] logs;\n bytes logsBloom;\n bytes status;\n address to;\n bytes32 transactionHash;\n bytes transactionIndex;\n }\n\n struct Receipt {\n bytes32 blockHash;\n uint256 blockNumber;\n address contractAddress;\n uint256 cumulativeGasUsed;\n uint256 effectiveGasPrice;\n address from;\n uint256 gasUsed;\n ReceiptLog[] logs;\n bytes logsBloom;\n uint256 status;\n address to;\n bytes32 transactionHash;\n uint256 transactionIndex;\n }\n\n // Data structures to parse the entire broadcast artifact, assuming the\n // transactions conform to EIP1559.\n\n struct EIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n Receipt[] receipts;\n uint256 timestamp;\n Tx1559[] transactions;\n TxReturn[] txReturns;\n }\n\n struct RawEIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n RawReceipt[] receipts;\n TxReturn[] txReturns;\n uint256 timestamp;\n RawTx1559[] transactions;\n }\n\n struct RawReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n bytes blockNumber;\n bytes data;\n bytes logIndex;\n bool removed;\n bytes32[] topics;\n bytes32 transactionHash;\n bytes transactionIndex;\n bytes transactionLogIndex;\n }\n\n struct ReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n uint256 blockNumber;\n bytes data;\n uint256 logIndex;\n bytes32[] topics;\n uint256 transactionIndex;\n uint256 transactionLogIndex;\n bool removed;\n }\n\n struct TxReturn {\n string internalType;\n string value;\n }\n\n function assumeNoPrecompiles(address addr) internal virtual {\n // Assembly required since `block.chainid` was introduced in 0.8.0.\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n assumeNoPrecompiles(addr, chainId);\n }\n\n function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual {\n // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific\n // address), but the same rationale for excluding them applies so we include those too.\n\n // These should be present on all EVM-compatible chains.\n vm.assume(addr < address(0x1) || addr > address(0x9));\n\n // forgefmt: disable-start\n if (chainId == 10 || chainId == 420) {\n // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21\n vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800));\n } else if (chainId == 42161 || chainId == 421613) {\n // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains\n vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068));\n } else if (chainId == 43114 || chainId == 43113) {\n // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59\n vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff));\n vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF));\n vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff));\n }\n // forgefmt: disable-end\n }\n\n function readEIP1559ScriptArtifact(string memory path)\n internal\n view\n virtual\n returns (EIP1559ScriptArtifact memory)\n {\n string memory data = vm.readFile(path);\n bytes memory parsedData = vm.parseJson(data);\n RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact));\n EIP1559ScriptArtifact memory artifact;\n artifact.libraries = rawArtifact.libraries;\n artifact.path = rawArtifact.path;\n artifact.timestamp = rawArtifact.timestamp;\n artifact.pending = rawArtifact.pending;\n artifact.txReturns = rawArtifact.txReturns;\n artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts);\n artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions);\n return artifact;\n }\n\n function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) {\n Tx1559[] memory txs = new Tx1559[](rawTxs.length);\n for (uint256 i; i < rawTxs.length; i++) {\n txs[i] = rawToConvertedEIPTx1559(rawTxs[i]);\n }\n return txs;\n }\n\n function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) {\n Tx1559 memory transaction;\n transaction.arguments = rawTx.arguments;\n transaction.contractName = rawTx.contractName;\n transaction.functionSig = rawTx.functionSig;\n transaction.hash = rawTx.hash;\n transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail);\n transaction.opcode = rawTx.opcode;\n return transaction;\n }\n\n function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail)\n internal\n pure\n virtual\n returns (Tx1559Detail memory)\n {\n Tx1559Detail memory txDetail;\n txDetail.data = rawDetail.data;\n txDetail.from = rawDetail.from;\n txDetail.to = rawDetail.to;\n txDetail.nonce = _bytesToUint(rawDetail.nonce);\n txDetail.txType = _bytesToUint(rawDetail.txType);\n txDetail.value = _bytesToUint(rawDetail.value);\n txDetail.gas = _bytesToUint(rawDetail.gas);\n txDetail.accessList = rawDetail.accessList;\n return txDetail;\n }\n\n function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".transactions\");\n RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[]));\n return rawToConvertedEIPTx1559s(rawTxs);\n }\n\n function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".transactions[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559));\n return rawToConvertedEIPTx1559(rawTx);\n }\n\n // Analogous to readTransactions, but for receipts.\n function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) {\n string memory deployData = vm.readFile(path);\n bytes memory parsedDeployData = vm.parseJson(deployData, \".receipts\");\n RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[]));\n return rawToConvertedReceipts(rawReceipts);\n }\n\n function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) {\n string memory deployData = vm.readFile(path);\n string memory key = string(abi.encodePacked(\".receipts[\", vm.toString(index), \"]\"));\n bytes memory parsedDeployData = vm.parseJson(deployData, key);\n RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt));\n return rawToConvertedReceipt(rawReceipt);\n }\n\n function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) {\n Receipt[] memory receipts = new Receipt[](rawReceipts.length);\n for (uint256 i; i < rawReceipts.length; i++) {\n receipts[i] = rawToConvertedReceipt(rawReceipts[i]);\n }\n return receipts;\n }\n\n function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) {\n Receipt memory receipt;\n receipt.blockHash = rawReceipt.blockHash;\n receipt.to = rawReceipt.to;\n receipt.from = rawReceipt.from;\n receipt.contractAddress = rawReceipt.contractAddress;\n receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice);\n receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed);\n receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed);\n receipt.status = _bytesToUint(rawReceipt.status);\n receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex);\n receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber);\n receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs);\n receipt.logsBloom = rawReceipt.logsBloom;\n receipt.transactionHash = rawReceipt.transactionHash;\n return receipt;\n }\n\n function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs)\n internal\n pure\n virtual\n returns (ReceiptLog[] memory)\n {\n ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length);\n for (uint256 i; i < rawLogs.length; i++) {\n logs[i].logAddress = rawLogs[i].logAddress;\n logs[i].blockHash = rawLogs[i].blockHash;\n logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber);\n logs[i].data = rawLogs[i].data;\n logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex);\n logs[i].topics = rawLogs[i].topics;\n logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex);\n logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex);\n logs[i].removed = rawLogs[i].removed;\n }\n return logs;\n }\n\n // Deploy a contract by fetching the contract bytecode from\n // the artifacts directory\n // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))`\n function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes): Deployment failed.\");\n }\n\n function deployCode(string memory what) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(0, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string): Deployment failed.\");\n }\n\n /// @dev deploy contract with value on construction\n function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,bytes,uint256): Deployment failed.\");\n }\n\n function deployCode(string memory what, uint256 val) internal virtual returns (address addr) {\n bytes memory bytecode = vm.getCode(what);\n /// @solidity memory-safe-assembly\n assembly {\n addr := create(val, add(bytecode, 0x20), mload(bytecode))\n }\n\n require(addr != address(0), \"StdCheats deployCode(string,uint256): Deployment failed.\");\n }\n\n // creates a labeled address and the corresponding private key\n function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) {\n privateKey = uint256(keccak256(abi.encodePacked(name)));\n addr = vm.addr(privateKey);\n vm.label(addr, name);\n }\n\n // creates a labeled address\n function makeAddr(string memory name) internal virtual returns (address addr) {\n (addr,) = makeAddrAndKey(name);\n }\n\n function deriveRememberKey(string memory mnemonic, uint32 index)\n internal\n virtual\n returns (address who, uint256 privateKey)\n {\n privateKey = vm.deriveKey(mnemonic, index);\n who = vm.rememberKey(privateKey);\n }\n\n function _bytesToUint(bytes memory b) private pure returns (uint256) {\n require(b.length <= 32, \"StdCheats _bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n function isFork() internal view virtual returns (bool status) {\n try vm.activeFork() {\n status = true;\n } catch (bytes memory) {}\n }\n\n modifier skipWhenForking() {\n if (!isFork()) {\n _;\n }\n }\n\n modifier skipWhenNotForking() {\n if (isFork()) {\n _;\n }\n }\n\n modifier noGasMetering() {\n vm.pauseGasMetering();\n // To prevent turning gas monitoring back on with nested functions that use this modifier,\n // we check if gasMetering started in the off position. If it did, we don't want to turn\n // it back on until we exit the top level function that used the modifier\n //\n // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well.\n // funcA will have `gasStartedOff` as false, funcB will have it as true,\n // so we only turn metering back on at the end of the funcA\n bool gasStartedOff = gasMeteringOff;\n gasMeteringOff = true;\n\n _;\n\n // if gas metering was on when this modifier was called, turn it back on at the end\n if (!gasStartedOff) {\n gasMeteringOff = false;\n vm.resumeGasMetering();\n }\n }\n\n // a cheat for fuzzing addresses that are payable only\n // see https://github.com/foundry-rs/foundry/issues/3631\n function assumePayable(address addr) internal virtual {\n (bool success,) = payable(addr).call{value: 0}(\"\");\n vm.assume(success);\n }\n}\n\n// Wrappers around cheatcodes to avoid footguns\nabstract contract StdCheats is StdCheatsSafe {\n using stdStorage for StdStorage;\n\n StdStorage private stdstore;\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n // Skip forward or rewind time by the specified number of seconds\n function skip(uint256 time) internal virtual {\n vm.warp(block.timestamp + time);\n }\n\n function rewind(uint256 time) internal virtual {\n vm.warp(block.timestamp - time);\n }\n\n // Setup a prank from an address that has some ether\n function hoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender);\n }\n\n function hoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.prank(msgSender, origin);\n }\n\n function hoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.prank(msgSender, origin);\n }\n\n // Start perpetual prank from an address that has some ether\n function startHoax(address msgSender) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender);\n }\n\n function startHoax(address msgSender, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender);\n }\n\n // Start perpetual prank from an address that has some ether\n // tx.origin is set to the origin parameter\n function startHoax(address msgSender, address origin) internal virtual {\n vm.deal(msgSender, 1 << 128);\n vm.startPrank(msgSender, origin);\n }\n\n function startHoax(address msgSender, address origin, uint256 give) internal virtual {\n vm.deal(msgSender, give);\n vm.startPrank(msgSender, origin);\n }\n\n function changePrank(address msgSender) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender);\n }\n\n function changePrank(address msgSender, address txOrigin) internal virtual {\n vm.stopPrank();\n vm.startPrank(msgSender, txOrigin);\n }\n\n // The same as Vm's `deal`\n // Use the alternative signature for ERC20 tokens\n function deal(address to, uint256 give) internal virtual {\n vm.deal(to, give);\n }\n\n // Set the balance of an account for any ERC20 token\n // Use the alternative signature to update `totalSupply`\n function deal(address token, address to, uint256 give) internal virtual {\n deal(token, to, give, false);\n }\n\n // Set the balance of an account for any ERC1155 token\n // Use the alternative signature to update `totalSupply`\n function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual {\n dealERC1155(token, to, id, give, false);\n }\n\n function deal(address token, address to, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd));\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0x18160ddd).checked_write(totSup);\n }\n }\n\n function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual {\n // get current balance\n (, bytes memory balData) = token.call(abi.encodeWithSelector(0x00fdd58e, to, id));\n uint256 prevBal = abi.decode(balData, (uint256));\n\n // update balance\n stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give);\n\n // update total supply\n if (adjust) {\n (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0xbd85b039, id));\n require(\n totSupData.length != 0,\n \"StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply.\"\n );\n uint256 totSup = abi.decode(totSupData, (uint256));\n if (give < prevBal) {\n totSup -= (prevBal - give);\n } else {\n totSup += (give - prevBal);\n }\n stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup);\n }\n }\n\n function dealERC721(address token, address to, uint256 id) internal virtual {\n // check if token id is already minted and the actual owner.\n (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id));\n require(successMinted, \"StdCheats deal(address,address,uint,bool): id not minted.\");\n\n // get owner current balance\n (, bytes memory fromBalData) = token.call(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address))));\n uint256 fromPrevBal = abi.decode(fromBalData, (uint256));\n\n // get new user current balance\n (, bytes memory toBalData) = token.call(abi.encodeWithSelector(0x70a08231, to));\n uint256 toPrevBal = abi.decode(toBalData, (uint256));\n\n // update balances\n stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal);\n stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal);\n\n // update owner\n stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to);\n }\n}\n" - }, - "node_modules/forge-std/src/StdError.sol": { - "content": "// SPDX-License-Identifier: MIT\n// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdError {\n bytes public constant assertionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x01);\n bytes public constant arithmeticError = abi.encodeWithSignature(\"Panic(uint256)\", 0x11);\n bytes public constant divisionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x12);\n bytes public constant enumConversionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x21);\n bytes public constant encodeStorageError = abi.encodeWithSignature(\"Panic(uint256)\", 0x22);\n bytes public constant popError = abi.encodeWithSignature(\"Panic(uint256)\", 0x31);\n bytes public constant indexOOBError = abi.encodeWithSignature(\"Panic(uint256)\", 0x32);\n bytes public constant memOverflowError = abi.encodeWithSignature(\"Panic(uint256)\", 0x41);\n bytes public constant zeroVarError = abi.encodeWithSignature(\"Panic(uint256)\", 0x51);\n}\n" - }, - "node_modules/forge-std/src/StdInvariant.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ncontract StdInvariant {\n struct FuzzSelector {\n address addr;\n bytes4[] selectors;\n }\n\n address[] private _excludedContracts;\n address[] private _excludedSenders;\n address[] private _targetedContracts;\n address[] private _targetedSenders;\n\n string[] private _excludedArtifacts;\n string[] private _targetedArtifacts;\n\n FuzzSelector[] private _targetedArtifactSelectors;\n FuzzSelector[] private _targetedSelectors;\n\n // Functions for users:\n // These are intended to be called in tests.\n\n function excludeContract(address newExcludedContract_) internal {\n _excludedContracts.push(newExcludedContract_);\n }\n\n function excludeSender(address newExcludedSender_) internal {\n _excludedSenders.push(newExcludedSender_);\n }\n\n function excludeArtifact(string memory newExcludedArtifact_) internal {\n _excludedArtifacts.push(newExcludedArtifact_);\n }\n\n function targetArtifact(string memory newTargetedArtifact_) internal {\n _targetedArtifacts.push(newTargetedArtifact_);\n }\n\n function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal {\n _targetedArtifactSelectors.push(newTargetedArtifactSelector_);\n }\n\n function targetContract(address newTargetedContract_) internal {\n _targetedContracts.push(newTargetedContract_);\n }\n\n function targetSelector(FuzzSelector memory newTargetedSelector_) internal {\n _targetedSelectors.push(newTargetedSelector_);\n }\n\n function targetSender(address newTargetedSender_) internal {\n _targetedSenders.push(newTargetedSender_);\n }\n\n // Functions for forge:\n // These are called by forge to run invariant tests and don't need to be called in tests.\n\n function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) {\n excludedArtifacts_ = _excludedArtifacts;\n }\n\n function excludeContracts() public view returns (address[] memory excludedContracts_) {\n excludedContracts_ = _excludedContracts;\n }\n\n function excludeSenders() public view returns (address[] memory excludedSenders_) {\n excludedSenders_ = _excludedSenders;\n }\n\n function targetArtifacts() public view returns (string[] memory targetedArtifacts_) {\n targetedArtifacts_ = _targetedArtifacts;\n }\n\n function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) {\n targetedArtifactSelectors_ = _targetedArtifactSelectors;\n }\n\n function targetContracts() public view returns (address[] memory targetedContracts_) {\n targetedContracts_ = _targetedContracts;\n }\n\n function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) {\n targetedSelectors_ = _targetedSelectors;\n }\n\n function targetSenders() public view returns (address[] memory targetedSenders_) {\n targetedSenders_ = _targetedSenders;\n }\n}\n" - }, - "node_modules/forge-std/src/StdJson.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing JSON files\n// To parse:\n// ```\n// using stdJson for string;\n// string memory json = vm.readFile(\"some_peth\");\n// json.parseUint(\"\");\n// ```\n// To write:\n// ```\n// using stdJson for string;\n// string memory json = \"deploymentArtifact\";\n// Contract contract = new Contract();\n// json.serialize(\"contractAddress\", address(contract));\n// json = json.serialize(\"deploymentTimes\", uint(1));\n// // store the stringified JSON to the 'json' variable we have been using as a key\n// // as we won't need it any longer\n// string memory json2 = \"finalArtifact\";\n// string memory final = json2.serialize(\"depArtifact\", json);\n// final.write(\"\");\n// ```\n\nlibrary stdJson {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJson(json, key);\n }\n\n function readUint(string memory json, string memory key) internal returns (uint256) {\n return vm.parseJsonUint(json, key);\n }\n\n function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) {\n return vm.parseJsonUintArray(json, key);\n }\n\n function readInt(string memory json, string memory key) internal returns (int256) {\n return vm.parseJsonInt(json, key);\n }\n\n function readIntArray(string memory json, string memory key) internal returns (int256[] memory) {\n return vm.parseJsonIntArray(json, key);\n }\n\n function readBytes32(string memory json, string memory key) internal returns (bytes32) {\n return vm.parseJsonBytes32(json, key);\n }\n\n function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) {\n return vm.parseJsonBytes32Array(json, key);\n }\n\n function readString(string memory json, string memory key) internal returns (string memory) {\n return vm.parseJsonString(json, key);\n }\n\n function readStringArray(string memory json, string memory key) internal returns (string[] memory) {\n return vm.parseJsonStringArray(json, key);\n }\n\n function readAddress(string memory json, string memory key) internal returns (address) {\n return vm.parseJsonAddress(json, key);\n }\n\n function readAddressArray(string memory json, string memory key) internal returns (address[] memory) {\n return vm.parseJsonAddressArray(json, key);\n }\n\n function readBool(string memory json, string memory key) internal returns (bool) {\n return vm.parseJsonBool(json, key);\n }\n\n function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) {\n return vm.parseJsonBoolArray(json, key);\n }\n\n function readBytes(string memory json, string memory key) internal returns (bytes memory) {\n return vm.parseJsonBytes(json, key);\n }\n\n function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) {\n return vm.parseJsonBytesArray(json, key);\n }\n\n function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bool[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBool(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, uint256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeUint(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, int256[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeInt(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, address[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeAddress(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes32[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes32(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, bytes[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeBytes(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function serialize(string memory jsonKey, string memory key, string[] memory value)\n internal\n returns (string memory)\n {\n return vm.serializeString(jsonKey, key, value);\n }\n\n function write(string memory jsonKey, string memory path) internal {\n vm.writeJson(jsonKey, path);\n }\n\n function write(string memory jsonKey, string memory path, string memory valueKey) internal {\n vm.writeJson(jsonKey, path, valueKey);\n }\n}\n" - }, - "node_modules/forge-std/src/StdMath.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdMath {\n int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n function abs(int256 a) internal pure returns (uint256) {\n // Required or it will fail when `a = type(int256).min`\n if (a == INT256_MIN) {\n return 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n }\n\n return uint256(a > 0 ? a : -a);\n }\n\n function delta(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a - b : b - a;\n }\n\n function delta(int256 a, int256 b) internal pure returns (uint256) {\n // a and b are of the same sign\n // this works thanks to two's complement, the left-most bit is the sign bit\n if ((a ^ b) > -1) {\n return delta(abs(a), abs(b));\n }\n\n // a and b are of opposite signs\n return abs(a) + abs(b);\n }\n\n function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n\n return absDelta * 1e18 / b;\n }\n\n function percentDelta(int256 a, int256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n uint256 absB = abs(b);\n\n return absDelta * 1e18 / absB;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStorage.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nstruct StdStorage {\n mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots;\n mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds;\n bytes32[] _keys;\n bytes4 _sig;\n uint256 _depth;\n address _target;\n bytes32 _set;\n}\n\nlibrary stdStorageSafe {\n event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot);\n event WARNING_UninitedSlot(address who, uint256 slot);\n\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return bytes4(keccak256(bytes(sigStr)));\n }\n\n /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against\n // slot complexity:\n // if flat, will be bytes32(uint256(uint));\n // if map, will be keccak256(abi.encode(key, uint(slot)));\n // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));\n // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);\n function find(StdStorage storage self) internal returns (uint256) {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n // calldata to test against\n if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n vm.record();\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n (bytes32[] memory reads,) = vm.accesses(address(who));\n if (reads.length == 1) {\n bytes32 curr = vm.load(who, reads[0]);\n if (curr == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[0]));\n }\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n } else if (reads.length > 1) {\n for (uint256 i = 0; i < reads.length; i++) {\n bytes32 prev = vm.load(who, reads[i]);\n if (prev == bytes32(0)) {\n emit WARNING_UninitedSlot(who, uint256(reads[i]));\n }\n // store\n vm.store(who, reads[i], bytes32(hex\"1337\"));\n bool success;\n bytes memory rdat;\n {\n (success, rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n\n if (success && fdat == bytes32(hex\"1337\")) {\n // we found which of the slots is the actual one\n emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i]));\n self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]);\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;\n vm.store(who, reads[i], prev);\n break;\n }\n vm.store(who, reads[i], prev);\n }\n } else {\n revert(\"stdStorage find(StdStorage): No storage use detected for target.\");\n }\n\n require(\n self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))],\n \"stdStorage find(StdStorage): Slot(s) not found.\"\n );\n\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n\n return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n self._target = _target;\n return self;\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n self._sig = _sig;\n return self;\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n self._sig = sigs(_sig);\n return self;\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n self._keys.push(bytes32(uint256(uint160(who))));\n return self;\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n self._keys.push(bytes32(amt));\n return self;\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n self._keys.push(key);\n return self;\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n self._depth = _depth;\n return self;\n }\n\n function read(StdStorage storage self) private returns (bytes memory) {\n address t = self._target;\n uint256 s = find(self);\n return abi.encode(vm.load(t, bytes32(s)));\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return abi.decode(read(self), (bytes32));\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n int256 v = read_int(self);\n if (v == 0) return false;\n if (v == 1) return true;\n revert(\"stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool.\");\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return abi.decode(read(self), (address));\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return abi.decode(read(self), (uint256));\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return abi.decode(read(self), (int256));\n }\n\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n\nlibrary stdStorage {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return stdStorageSafe.sigs(sigStr);\n }\n\n function find(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.find(self);\n }\n\n function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {\n return stdStorageSafe.target(self, _target);\n }\n\n function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {\n return stdStorageSafe.sig(self, _sig);\n }\n\n function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, who);\n }\n\n function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, amt);\n }\n\n function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {\n return stdStorageSafe.with_key(self, key);\n }\n\n function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {\n return stdStorageSafe.depth(self, _depth);\n }\n\n function checked_write(StdStorage storage self, address who) internal {\n checked_write(self, bytes32(uint256(uint160(who))));\n }\n\n function checked_write(StdStorage storage self, uint256 amt) internal {\n checked_write(self, bytes32(amt));\n }\n\n function checked_write(StdStorage storage self, bool write) internal {\n bytes32 t;\n /// @solidity memory-safe-assembly\n assembly {\n t := write\n }\n checked_write(self, t);\n }\n\n function checked_write(StdStorage storage self, bytes32 set) internal {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes32[] memory ins = self._keys;\n\n bytes memory cald = abi.encodePacked(fsig, flatten(ins));\n if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {\n find(self);\n }\n bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]);\n\n bytes32 fdat;\n {\n (, bytes memory rdat) = who.staticcall(cald);\n fdat = bytesToBytes32(rdat, 32 * field_depth);\n }\n bytes32 curr = vm.load(who, slot);\n\n if (fdat != curr) {\n require(\n false,\n \"stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.\"\n );\n }\n vm.store(who, slot, set);\n delete self._target;\n delete self._sig;\n delete self._keys;\n delete self._depth;\n }\n\n function read_bytes32(StdStorage storage self) internal returns (bytes32) {\n return stdStorageSafe.read_bytes32(self);\n }\n\n function read_bool(StdStorage storage self) internal returns (bool) {\n return stdStorageSafe.read_bool(self);\n }\n\n function read_address(StdStorage storage self) internal returns (address) {\n return stdStorageSafe.read_address(self);\n }\n\n function read_uint(StdStorage storage self) internal returns (uint256) {\n return stdStorageSafe.read_uint(self);\n }\n\n function read_int(StdStorage storage self) internal returns (int256) {\n return stdStorageSafe.read_int(self);\n }\n\n // Private function so needs to be copied over\n function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) {\n bytes32 out;\n\n uint256 max = b.length > 32 ? 32 : b.length;\n for (uint256 i = 0; i < max; i++) {\n out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);\n }\n return out;\n }\n\n // Private function so needs to be copied over\n function flatten(bytes32[] memory b) private pure returns (bytes memory) {\n bytes memory result = new bytes(b.length * 32);\n for (uint256 i = 0; i < b.length; i++) {\n bytes32 k = b[i];\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(result, add(32, mul(32, i))), k)\n }\n }\n\n return result;\n }\n}\n" - }, - "node_modules/forge-std/src/StdStyle.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nlibrary StdStyle {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n string constant RED = \"\\u001b[91m\";\n string constant GREEN = \"\\u001b[92m\";\n string constant YELLOW = \"\\u001b[93m\";\n string constant BLUE = \"\\u001b[94m\";\n string constant MAGENTA = \"\\u001b[95m\";\n string constant CYAN = \"\\u001b[96m\";\n string constant BOLD = \"\\u001b[1m\";\n string constant DIM = \"\\u001b[2m\";\n string constant ITALIC = \"\\u001b[3m\";\n string constant UNDERLINE = \"\\u001b[4m\";\n string constant INVERSE = \"\\u001b[7m\";\n string constant RESET = \"\\u001b[0m\";\n\n function styleConcat(string memory style, string memory self) private pure returns (string memory) {\n return string(abi.encodePacked(style, self, RESET));\n }\n\n function red(string memory self) internal pure returns (string memory) {\n return styleConcat(RED, self);\n }\n\n function red(uint256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(int256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(address self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(bool self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes(bytes memory self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes32(bytes32 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function green(string memory self) internal pure returns (string memory) {\n return styleConcat(GREEN, self);\n }\n\n function green(uint256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(int256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(address self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(bool self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes(bytes memory self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes32(bytes32 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function yellow(string memory self) internal pure returns (string memory) {\n return styleConcat(YELLOW, self);\n }\n\n function yellow(uint256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(int256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(address self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(bool self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes(bytes memory self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes32(bytes32 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function blue(string memory self) internal pure returns (string memory) {\n return styleConcat(BLUE, self);\n }\n\n function blue(uint256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(int256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(address self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(bool self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes(bytes memory self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes32(bytes32 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function magenta(string memory self) internal pure returns (string memory) {\n return styleConcat(MAGENTA, self);\n }\n\n function magenta(uint256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(int256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(address self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(bool self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes(bytes memory self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magentaBytes32(bytes32 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function cyan(string memory self) internal pure returns (string memory) {\n return styleConcat(CYAN, self);\n }\n\n function cyan(uint256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(int256 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(address self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyan(bool self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes(bytes memory self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function cyanBytes32(bytes32 self) internal pure returns (string memory) {\n return cyan(vm.toString(self));\n }\n\n function bold(string memory self) internal pure returns (string memory) {\n return styleConcat(BOLD, self);\n }\n\n function bold(uint256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(int256 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(address self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function bold(bool self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes(bytes memory self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function boldBytes32(bytes32 self) internal pure returns (string memory) {\n return bold(vm.toString(self));\n }\n\n function dim(string memory self) internal pure returns (string memory) {\n return styleConcat(DIM, self);\n }\n\n function dim(uint256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(int256 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(address self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dim(bool self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes(bytes memory self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function dimBytes32(bytes32 self) internal pure returns (string memory) {\n return dim(vm.toString(self));\n }\n\n function italic(string memory self) internal pure returns (string memory) {\n return styleConcat(ITALIC, self);\n }\n\n function italic(uint256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(int256 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(address self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italic(bool self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes(bytes memory self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function italicBytes32(bytes32 self) internal pure returns (string memory) {\n return italic(vm.toString(self));\n }\n\n function underline(string memory self) internal pure returns (string memory) {\n return styleConcat(UNDERLINE, self);\n }\n\n function underline(uint256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(int256 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(address self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underline(bool self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes(bytes memory self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function underlineBytes32(bytes32 self) internal pure returns (string memory) {\n return underline(vm.toString(self));\n }\n\n function inverse(string memory self) internal pure returns (string memory) {\n return styleConcat(INVERSE, self);\n }\n\n function inverse(uint256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(int256 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(address self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverse(bool self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes(bytes memory self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n\n function inverseBytes32(bytes32 self) internal pure returns (string memory) {\n return inverse(vm.toString(self));\n }\n}\n" - }, - "node_modules/forge-std/src/StdUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {IMulticall3} from \"./interfaces/IMulticall3.sol\";\n// TODO Remove import.\nimport {VmSafe} from \"./Vm.sol\";\n\nabstract contract StdUtils {\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n //////////////////////////////////////////////////////////////////////////*/\n\n IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;\n uint256 private constant INT256_MIN_ABS =\n 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n /*//////////////////////////////////////////////////////////////////////////\n INTERNAL FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n require(min <= max, \"StdUtils bound(uint256,uint256,uint256): Max is less than min.\");\n // If x is between min and max, return x directly. This is to ensure that dictionary values\n // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188\n if (x >= min && x <= max) return x;\n\n uint256 size = max - min + 1;\n\n // If the value is 0, 1, 2, 3, warp that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side.\n // This helps ensure coverage of the min/max values.\n if (x <= 3 && size > x) return min + x;\n if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x);\n\n // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.\n if (x > max) {\n uint256 diff = x - max;\n uint256 rem = diff % size;\n if (rem == 0) return max;\n result = min + rem - 1;\n } else if (x < min) {\n uint256 diff = min - x;\n uint256 rem = diff % size;\n if (rem == 0) return min;\n result = max - rem + 1;\n }\n }\n\n function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) {\n result = _bound(x, min, max);\n console2_log(\"Bound Result\", result);\n }\n\n function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) {\n require(min <= max, \"StdUtils bound(int256,int256,int256): Max is less than min.\");\n\n // Shifting all int256 values to uint256 to use _bound function. The range of two types are:\n // int256 : -(2**255) ~ (2**255 - 1)\n // uint256: 0 ~ (2**256 - 1)\n // So, add 2**255, INT256_MIN_ABS to the integer values.\n //\n // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow.\n // So, use `~uint256(x) + 1` instead.\n uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS);\n uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS);\n uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS);\n\n uint256 y = _bound(_x, _min, _max);\n\n // To move it back to int256 value, subtract INT256_MIN_ABS at here.\n result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS);\n console2_log(\"Bound result\", vm.toString(result));\n }\n\n function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {\n require(b.length <= 32, \"StdUtils bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));\n }\n\n /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce\n /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol)\n function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) {\n // forgefmt: disable-start\n // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.\n // A one byte integer uses its own value as its length prefix, there is no additional \"0x80 + length\" prefix that comes before it.\n if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))));\n if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))));\n\n // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.\n if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce))));\n if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce))));\n if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce))));\n // forgefmt: disable-end\n\n // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp\n // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)\n // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)\n // We assume nobody can have a nonce large enough to require more than 32 bytes.\n return addressFromLast20Bytes(\n keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce)))\n );\n }\n\n function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer)\n internal\n pure\n virtual\n returns (address)\n {\n return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash)));\n }\n\n /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer\n function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) {\n return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY);\n }\n\n /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) {\n return hashInitCode(creationCode, \"\");\n }\n\n /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2\n /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode\n /// @param args the ABI-encoded arguments to the constructor of C\n function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(creationCode, args));\n }\n\n // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses.\n function getTokenBalances(address token, address[] memory addresses)\n internal\n virtual\n returns (uint256[] memory balances)\n {\n uint256 tokenCodeSize;\n assembly {\n tokenCodeSize := extcodesize(token)\n }\n require(tokenCodeSize > 0, \"StdUtils getTokenBalances(address,address[]): Token address is not a contract.\");\n\n // ABI encode the aggregate call to Multicall3.\n uint256 length = addresses.length;\n IMulticall3.Call[] memory calls = new IMulticall3.Call[](length);\n for (uint256 i = 0; i < length; ++i) {\n // 0x70a08231 = bytes4(\"balanceOf(address)\"))\n calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))});\n }\n\n // Make the aggregate call.\n (, bytes[] memory returnData) = multicall.aggregate(calls);\n\n // ABI decode the return data and return the balances.\n balances = new uint256[](length);\n for (uint256 i = 0; i < length; ++i) {\n balances[i] = abi.decode(returnData[i], (uint256));\n }\n }\n\n /*//////////////////////////////////////////////////////////////////////////\n PRIVATE FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere.\n\n function console2_log(string memory p0, uint256 p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n status;\n }\n\n function console2_log(string memory p0, string memory p1) private view {\n (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n status;\n }\n}\n" - }, - "node_modules/forge-std/src/Test.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// 💬 ABOUT\n// Standard Library's default Test\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {StdAssertions} from \"./StdAssertions.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheats} from \"./StdCheats.sol\";\nimport {stdError} from \"./StdError.sol\";\nimport {StdInvariant} from \"./StdInvariant.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {Vm} from \"./Vm.sol\";\nimport {StdStyle} from \"./StdStyle.sol\";\n\n// 📦 BOILERPLATE\nimport {TestBase} from \"./Base.sol\";\nimport {DSTest} from \"ds-test/test.sol\";\n\n// ⭐️ TEST\nabstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase {\n// Note: IS_TEST() must return true.\n// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76.\n}\n" - }, - "node_modules/forge-std/src/Vm.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// Cheatcodes are marked as view/pure/none using the following rules:\n// 0. A call's observable behaviour includes its return value, logs, reverts and state writes,\n// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc),\n// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`,\n// 3. Otherwise you're `pure`.\n\ninterface VmSafe {\n struct Log {\n bytes32[] topics;\n bytes data;\n address emitter;\n }\n\n struct Rpc {\n string key;\n string url;\n }\n\n struct FsMetadata {\n bool isDir;\n bool isSymlink;\n uint256 length;\n bool readOnly;\n uint256 modified;\n uint256 accessed;\n uint256 created;\n }\n\n // Loads a storage slot from an address\n function load(address target, bytes32 slot) external view returns (bytes32 data);\n // Signs data\n function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s);\n // Gets the address for a given private key\n function addr(uint256 privateKey) external pure returns (address keyAddr);\n // Gets the nonce of an account\n function getNonce(address account) external view returns (uint64 nonce);\n // Performs a foreign function call via the terminal\n function ffi(string[] calldata commandInput) external returns (bytes memory result);\n // Sets environment variables\n function setEnv(string calldata name, string calldata value) external;\n // Reads environment variables, (name) => (value)\n function envBool(string calldata name) external view returns (bool value);\n function envUint(string calldata name) external view returns (uint256 value);\n function envInt(string calldata name) external view returns (int256 value);\n function envAddress(string calldata name) external view returns (address value);\n function envBytes32(string calldata name) external view returns (bytes32 value);\n function envString(string calldata name) external view returns (string memory value);\n function envBytes(string calldata name) external view returns (bytes memory value);\n // Reads environment variables as arrays\n function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value);\n function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value);\n function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value);\n function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);\n function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value);\n function envString(string calldata name, string calldata delim) external view returns (string[] memory value);\n function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value);\n // Read environment variables with default value\n function envOr(string calldata name, bool defaultValue) external returns (bool value);\n function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value);\n function envOr(string calldata name, int256 defaultValue) external returns (int256 value);\n function envOr(string calldata name, address defaultValue) external returns (address value);\n function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value);\n function envOr(string calldata name, string calldata defaultValue) external returns (string memory value);\n function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value);\n // Read environment variables as arrays with default value\n function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue)\n external\n returns (bool[] memory value);\n function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue)\n external\n returns (uint256[] memory value);\n function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue)\n external\n returns (int256[] memory value);\n function envOr(string calldata name, string calldata delim, address[] calldata defaultValue)\n external\n returns (address[] memory value);\n function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue)\n external\n returns (bytes32[] memory value);\n function envOr(string calldata name, string calldata delim, string[] calldata defaultValue)\n external\n returns (string[] memory value);\n function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue)\n external\n returns (bytes[] memory value);\n // Records all storage reads and writes\n function record() external;\n // Gets all accessed reads and write slot from a recording session, for a given address\n function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots);\n // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file\n function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode);\n // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file\n function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode);\n // Labels an address in call traces\n function label(address account, string calldata newLabel) external;\n // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain\n function broadcast() external;\n // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain\n function broadcast(address signer) external;\n // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain\n function broadcast(uint256 privateKey) external;\n // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain\n function startBroadcast() external;\n // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain\n function startBroadcast(address signer) external;\n // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain\n function startBroadcast(uint256 privateKey) external;\n // Stops collecting onchain transactions\n function stopBroadcast() external;\n // Reads the entire content of file to string\n function readFile(string calldata path) external view returns (string memory data);\n // Reads the entire content of file as binary. Path is relative to the project root.\n function readFileBinary(string calldata path) external view returns (bytes memory data);\n // Get the path of the current project root\n function projectRoot() external view returns (string memory path);\n // Get the metadata for a file/directory\n function fsMetadata(string calldata fileOrDir) external returns (FsMetadata memory metadata);\n // Reads next line of file to string\n function readLine(string calldata path) external view returns (string memory line);\n // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does.\n function writeFile(string calldata path, string calldata data) external;\n // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does.\n // Path is relative to the project root.\n function writeFileBinary(string calldata path, bytes calldata data) external;\n // Writes line to file, creating a file if it does not exist.\n function writeLine(string calldata path, string calldata data) external;\n // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine.\n function closeFile(string calldata path) external;\n // Removes file. This cheatcode will revert in the following situations, but is not limited to just these cases:\n // - Path points to a directory.\n // - The file doesn't exist.\n // - The user lacks permissions to remove the file.\n function removeFile(string calldata path) external;\n // Convert values to a string\n function toString(address value) external pure returns (string memory stringifiedValue);\n function toString(bytes calldata value) external pure returns (string memory stringifiedValue);\n function toString(bytes32 value) external pure returns (string memory stringifiedValue);\n function toString(bool value) external pure returns (string memory stringifiedValue);\n function toString(uint256 value) external pure returns (string memory stringifiedValue);\n function toString(int256 value) external pure returns (string memory stringifiedValue);\n // Convert values from a string\n function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue);\n function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue);\n function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue);\n function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue);\n function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue);\n function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue);\n // Record all the transaction logs\n function recordLogs() external;\n // Gets all the recorded logs\n function getRecordedLogs() external returns (Log[] memory logs);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index}\n function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey);\n // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index}\n function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index)\n external\n pure\n returns (uint256 privateKey);\n // Adds a private key to the local forge wallet and returns the address\n function rememberKey(uint256 privateKey) external returns (address keyAddr);\n //\n // parseJson\n //\n // ----\n // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects\n // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in\n // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that\n // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded\n // as tuples, with the attributes in the order in which they are defined.\n // For example: json = { 'a': 1, 'b': 0xa4tb......3xs}\n // a: uint256\n // b: address\n // To decode that json, we need to define a struct or a tuple as follows:\n // struct json = { uint256 a; address b; }\n // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to\n // decode the tuple in that order, and thus fail.\n // ----\n // Given a string of JSON, return it as ABI-encoded\n function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData);\n function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData);\n\n // The following parseJson cheatcodes will do type coercion, for the type that they indicate.\n // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12'\n // and hex numbers '0xEF'.\n // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not\n // a JSON object.\n function parseJsonUint(string calldata, string calldata) external returns (uint256);\n function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory);\n function parseJsonInt(string calldata, string calldata) external returns (int256);\n function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory);\n function parseJsonBool(string calldata, string calldata) external returns (bool);\n function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory);\n function parseJsonAddress(string calldata, string calldata) external returns (address);\n function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory);\n function parseJsonString(string calldata, string calldata) external returns (string memory);\n function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory);\n function parseJsonBytes(string calldata, string calldata) external returns (bytes memory);\n function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory);\n function parseJsonBytes32(string calldata, string calldata) external returns (bytes32);\n function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory);\n\n // Serialize a key and value to a JSON object stored in-memory that can be later written to a file\n // It returns the stringified version of the specific JSON file up to that moment.\n function serializeBool(string calldata objectKey, string calldata valueKey, bool value)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256 value)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address value)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string calldata value)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value)\n external\n returns (string memory json);\n\n function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values)\n external\n returns (string memory json);\n function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values)\n external\n returns (string memory json);\n function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values)\n external\n returns (string memory json);\n function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values)\n external\n returns (string memory json);\n function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values)\n external\n returns (string memory json);\n function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values)\n external\n returns (string memory json);\n function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values)\n external\n returns (string memory json);\n\n //\n // writeJson\n //\n // ----\n // Write a serialized JSON object to a file. If the file exists, it will be overwritten.\n // Let's assume we want to write the following JSON to a file:\n //\n // { \"boolean\": true, \"number\": 342, \"object\": { \"title\": \"finally json serialization\" } }\n //\n // ```\n // string memory json1 = \"some key\";\n // vm.serializeBool(json1, \"boolean\", true);\n // vm.serializeBool(json1, \"number\", uint256(342));\n // json2 = \"some other key\";\n // string memory output = vm.serializeString(json2, \"title\", \"finally json serialization\");\n // string memory finalJson = vm.serialize(json1, \"object\", output);\n // vm.writeJson(finalJson, \"./output/example.json\");\n // ```\n // The critical insight is that every invocation of serialization will return the stringified version of the JSON\n // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version\n // to serialize them as values to another JSON object.\n //\n // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..)\n // will find the object in-memory that is keyed by \"some key\".\n function writeJson(string calldata json, string calldata path) external;\n // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = \n // This is useful to replace a specific value of a JSON file, without having to parse the entire thing\n function writeJson(string calldata json, string calldata path, string calldata valueKey) external;\n // Returns the RPC url for the given alias\n function rpcUrl(string calldata rpcAlias) external view returns (string memory json);\n // Returns all rpc urls and their aliases `[alias, url][]`\n function rpcUrls() external view returns (string[2][] memory urls);\n // Returns all rpc urls and their aliases as structs.\n function rpcUrlStructs() external view returns (Rpc[] memory urls);\n // If the condition is false, discard this run's fuzz inputs and generate new ones.\n function assume(bool condition) external pure;\n // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused.\n function pauseGasMetering() external;\n // Resumes gas metering (i.e. gas usage is counted again). Noop if already on.\n function resumeGasMetering() external;\n}\n\ninterface Vm is VmSafe {\n // Sets block.timestamp\n function warp(uint256 newTimestamp) external;\n // Sets block.height\n function roll(uint256 newHeight) external;\n // Sets block.basefee\n function fee(uint256 newBasefee) external;\n // Sets block.difficulty\n function difficulty(uint256 newDifficulty) external;\n // Sets block.chainid\n function chainId(uint256 newChainId) external;\n // Stores a value to an address' storage slot.\n function store(address target, bytes32 slot, bytes32 value) external;\n // Sets the nonce of an account; must be higher than the current nonce of the account\n function setNonce(address account, uint64 newNonce) external;\n // Sets the *next* call's msg.sender to be the input address\n function prank(address msgSender) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called\n function startPrank(address msgSender) external;\n // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input\n function prank(address msgSender, address txOrigin) external;\n // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input\n function startPrank(address msgSender, address txOrigin) external;\n // Resets subsequent calls' msg.sender to be `address(this)`\n function stopPrank() external;\n // Sets an address' balance\n function deal(address account, uint256 newBalance) external;\n // Sets an address' code\n function etch(address target, bytes calldata newRuntimeBytecode) external;\n // Expects an error on next call\n function expectRevert(bytes calldata revertData) external;\n function expectRevert(bytes4 revertData) external;\n function expectRevert() external;\n\n // Prepare an expected log with all four checks enabled.\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data.\n // Second form also checks supplied address against emitting contract.\n function expectEmit() external;\n function expectEmit(address emitter) external;\n\n // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData).\n // Call this function, then emit an event, then call a function. Internally after the call, we check if\n // logs were emitted in the expected order with the expected topics and data (as specified by the booleans).\n // Second form also checks supplied address against emitting contract.\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external;\n function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter)\n external;\n\n // Mocks a call to an address, returning specified data.\n // Calldata can either be strict or a partial match, e.g. if you only\n // pass a Solidity selector to the expected calldata, then the entire Solidity\n // function will be mocked.\n function mockCall(address callee, bytes calldata data, bytes calldata returnData) external;\n // Mocks a call to an address with a specific msg.value, returning specified data.\n // Calldata match takes precedence over msg.value in case of ambiguity.\n function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external;\n // Clears all mocked calls\n function clearMockedCalls() external;\n // Expects a call to an address with the specified calldata.\n // Calldata can either be a strict or a partial match\n function expectCall(address callee, bytes calldata data) external;\n // Expects a call to an address with the specified msg.value and calldata\n function expectCall(address callee, uint256 msgValue, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value, gas, and calldata.\n function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external;\n // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas.\n function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other\n // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set.\n function expectSafeMemory(uint64 min, uint64 max) external;\n // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext.\n // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges\n // to the set.\n function expectSafeMemoryCall(uint64 min, uint64 max) external;\n // Sets block.coinbase\n function coinbase(address newCoinbase) external;\n // Snapshot the current state of the evm.\n // Returns the id of the snapshot that was created.\n // To revert a snapshot use `revertTo`\n function snapshot() external returns (uint256 snapshotId);\n // Revert the state of the EVM to a previous snapshot\n // Takes the snapshot id to revert to.\n // This deletes the snapshot and all snapshots taken after the given snapshot id.\n function revertTo(uint256 snapshotId) external returns (bool success);\n // Creates a new fork with the given endpoint and block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork\n function createFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction,\n // and returns the identifier of the fork\n function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId);\n // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before\n // the transaction, returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId);\n // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork\n function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId);\n // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active.\n function selectFork(uint256 forkId) external;\n /// Returns the identifier of the currently active fork. Reverts if no fork is currently active.\n function activeFork() external view returns (uint256 forkId);\n // Updates the currently active fork to given block number\n // This is similar to `roll` but for the currently active fork\n function rollFork(uint256 blockNumber) external;\n // Updates the currently active fork to given transaction\n // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block\n function rollFork(bytes32 txHash) external;\n // Updates the given fork to given block number\n function rollFork(uint256 forkId, uint256 blockNumber) external;\n // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block\n function rollFork(uint256 forkId, bytes32 txHash) external;\n // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup\n // Meaning, changes made to the state of this account will be kept when switching forks\n function makePersistent(address account) external;\n function makePersistent(address account0, address account1) external;\n function makePersistent(address account0, address account1, address account2) external;\n function makePersistent(address[] calldata accounts) external;\n // Revokes persistent status from the address, previously added via `makePersistent`\n function revokePersistent(address account) external;\n function revokePersistent(address[] calldata accounts) external;\n // Returns true if the account is marked as persistent\n function isPersistent(address account) external view returns (bool persistent);\n // In forking mode, explicitly grant the given address cheatcode access\n function allowCheatcodes(address account) external;\n // Fetches the given transaction from the active fork and executes it on the current state\n function transact(bytes32 txHash) external;\n // Fetches the given transaction from the given fork and executes it on the current state\n function transact(uint256 forkId, bytes32 txHash) external;\n}\n" - }, - "node_modules/forge-std/src/console.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n }\n\n function logUint(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n }\n\n function log(uint p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n }\n\n function log(uint p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n }\n\n function log(uint p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n }\n\n function log(string memory p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n }\n\n function log(uint p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/console2.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\n/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should\n/// use `int256` and `uint256`. This modified version fixes that. This version is recommended\n/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in\n/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`.\n/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178\nlibrary console2 {\n address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n function _sendLogPayload(bytes memory payload) private view {\n uint256 payloadLength = payload.length;\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n let payloadStart := add(payload, 32)\n let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n }\n }\n\n function log() internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function log(int256 p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function log(string memory p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint256 p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n }\n\n function log(uint256 p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n }\n\n function log(uint256 p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n }\n\n function log(uint256 p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n }\n\n function log(string memory p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n }\n\n function log(string memory p0, int256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,int256)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint256 p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint256 p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint256 p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal view {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}" - }, - "node_modules/forge-std/src/interfaces/IMulticall3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ninterface IMulticall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint256 value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n function aggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes[] memory returnData);\n\n function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);\n\n function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData);\n\n function blockAndAggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n\n function getBasefee() external view returns (uint256 basefee);\n\n function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash);\n\n function getBlockNumber() external view returns (uint256 blockNumber);\n\n function getChainId() external view returns (uint256 chainid);\n\n function getCurrentBlockCoinbase() external view returns (address coinbase);\n\n function getCurrentBlockDifficulty() external view returns (uint256 difficulty);\n\n function getCurrentBlockGasLimit() external view returns (uint256 gaslimit);\n\n function getCurrentBlockTimestamp() external view returns (uint256 timestamp);\n\n function getEthBalance(address addr) external view returns (uint256 balance);\n\n function getLastBlockHash() external view returns (bytes32 blockHash);\n\n function tryAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (Result[] memory returnData);\n\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n}\n" - } - }, - "settings": { - "remappings": [ - "@openzeppelin/=node_modules/@openzeppelin/", - "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", - "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", - "@rari-capital/=node_modules/@rari-capital/", - "@rari-capital/solmate/=node_modules/@rari-capital/solmate/", - "@safe-global/safe-contracts/=node_modules/@safe-global/safe-contracts/", - "ds-test/=node_modules/ds-test/src/", - "forge-std/=node_modules/forge-std/src/", - "solady/=node_modules/solady/src/" - ], - "optimizer": { - "enabled": true, - "runs": 999999 - }, - "metadata": { - "bytecodeHash": "none" - }, - "outputSelection": { - "*": { - "": [ - "ast" - ], - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "storageLayout", - "devdoc", - "userdoc" - ] - } - }, - "evmVersion": "london", - "libraries": {} - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/b1df373a9ed51b3903b61f56faa9a78f.json b/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/b1df373a9ed51b3903b61f56faa9a78f.json deleted file mode 100644 index b0bf9b8a4dfb..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/b1df373a9ed51b3903b61f56faa9a78f.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/GovernanceToken.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev The Optimism token used in governance and supporting voting and delegation.\n * Implements EIP 2612 allowing signed approvals.\n * Contract is \"owned\" by a `MintManager` instance with permission to the `mint` function only,\n * for the purposes of enforcing the token inflation schedule.\n */\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\n /**\n * @dev Constructor.\n */\n constructor() ERC20(\"Optimism\", \"OP\") ERC20Permit(\"Optimism\") {}\n\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n // The following functions are overrides required by Solidity.\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20, ERC20Votes) {\n super._afterTokenTransfer(from, to, amount);\n }\n\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._mint(to, amount);\n }\n\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._burn(account, amount);\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, _allowances[owner][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = _allowances[owner][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Spend `amount` form the allowance of `owner` toward `spender`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20Permit.sol\";\nimport \"../../../utils/math/Math.sol\";\nimport \"../../../governance/utils/IVotes.sol\";\nimport \"../../../utils/math/SafeCast.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20Votes is IVotes, ERC20Permit {\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCast.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = Math.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSA.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n}\n" - }, - "@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private immutable _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" - }, - "@openzeppelin/contracts/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" - }, - "@openzeppelin/contracts/governance/utils/IVotes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "@openzeppelin/contracts/utils/math/SafeCast.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" - }, - "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" - }, - "@openzeppelin/contracts/utils/Counters.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" - }, - "@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n" - }, - "contracts/MintManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./GovernanceToken.sol\";\n\n/**\n * @title MintManager\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\n * Contract acts as the token \"mint manager\" with permission to the `mint` function only.\n * Currently permitted to mint once per year of up to 2% of the total token supply.\n * Upgradable to allow changes in the inflation schedule.\n */\ncontract MintManager is Ownable {\n /**\n * @notice The GovernanceToken that the MintManager can mint tokens\n */\n GovernanceToken public immutable governanceToken;\n\n /**\n * @notice The amount of tokens that can be minted per year. The value is a fixed\n * point number with 4 decimals.\n */\n uint256 public constant MINT_CAP = 20; // 2%\n\n /**\n * @notice The number of decimals for the MINT_CAP.\n */\n uint256 public constant DENOMINATOR = 1000;\n\n /**\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\n * be minted again.\n */\n uint256 public constant MINT_PERIOD = 365 days;\n\n /**\n * @notice Tracks the time of last mint\n */\n uint256 public mintPermittedAfter;\n\n /**\n * @param _upgrader The owner of this contract\n * @param _governanceToken The governance token this contract can mint\n * tokens of\n */\n constructor(address _upgrader, address _governanceToken) {\n transferOwnership(_upgrader);\n governanceToken = GovernanceToken(_governanceToken);\n }\n\n /**\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\n *\n * @param _account Address to mint new tokens to.\n * @param _amount Amount of tokens to be minted.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n if (mintPermittedAfter > 0) {\n require(mintPermittedAfter <= block.timestamp, \"OP: minting not permitted yet\");\n\n require(\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\n \"OP: mint amount exceeds cap\"\n );\n }\n\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\n\n governanceToken.mint(_account, _amount);\n }\n\n /**\n * @notice Upgrade the owner of the governance token to a new MintManager.\n *\n * @param _newMintManager The MintManager to upgrade to\n */\n function upgrade(address _newMintManager) public onlyOwner {\n require(_newMintManager != address(0), \"OP: Mint manager cannot be empty\");\n\n governanceToken.transferOwnership(_newMintManager);\n }\n}\n" - }, - "contracts/test/TestERC20.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity =0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestERC20 is ERC20 {\n constructor(\n string memory name_,\n string memory symbol_,\n uint256 amountToMint\n ) ERC20(name_, symbol_) {\n setBalance(msg.sender, amountToMint);\n }\n\n // sets the balance of the address\n // this mints/burns the amount depending on the current balance\n function setBalance(address to, uint256 amount) public {\n uint256 old = balanceOf(to);\n if (old < amount) {\n _mint(to, amount - old);\n } else if (old > amount) {\n _burn(to, old - amount);\n }\n }\n}\n" - }, - "contracts/MerkleDistributor.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity =0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\";\nimport \"./interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n uint256 public constant ONE_YEAR_IN_SECONDS = 31_536_000;\n uint256 public immutable activationTimestamp;\n address public immutable airdropTreasury;\n bool public isActive;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n event Finalised(address indexed calledBy, uint256 timestamp, uint256 unclaimedAmount);\n\n constructor(\n address token_,\n bytes32 merkleRoot_,\n address _treasury\n ) {\n token = token_;\n merkleRoot = merkleRoot_;\n\n activationTimestamp = block.timestamp;\n isActive = true;\n airdropTreasury = _treasury;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(\n uint256 index,\n address account,\n uint256 amount,\n bytes32[] calldata merkleProof\n ) external override {\n require(!isClaimed(index), \"MerkleDistributor: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(\n MerkleProof.verify(merkleProof, merkleRoot, node),\n \"MerkleDistributor: Invalid proof.\"\n );\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n /**\n * @dev Finalises the airdrop and sweeps unclaimed tokens into the Optimism multisig\n */\n function clawBack() external {\n // Airdrop can only be finalised once\n require(isActive, \"Airdrop: Already finalised\");\n // Airdrop will remain open for one year\n require(\n block.timestamp >= activationTimestamp + ONE_YEAR_IN_SECONDS,\n \"Airdrop: Drop should remain open for one year\"\n );\n // Deactivate airdrop\n isActive = false;\n\n // Sweep unclaimed tokens\n uint256 amount = IERC20(token).balanceOf(address(this));\n require(\n IERC20(token).transfer(airdropTreasury, amount),\n \"Airdrop: Finalise transfer failed\"\n );\n\n emit Finalised(msg.sender, block.timestamp, amount);\n }\n}\n" - }, - "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/MerkleProof.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev These functions deal with verification of Merkle Trees proofs.\n *\n * The proofs can be generated using the JavaScript library\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\n *\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\n */\nlibrary MerkleProof {\n /**\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n * defined by `root`. For this, a `proof` must be provided, containing\n * sibling hashes on the branch from the leaf to the root of the tree. Each\n * pair of leaves and each pair of pre-images are assumed to be sorted.\n */\n function verify(\n bytes32[] memory proof,\n bytes32 root,\n bytes32 leaf\n ) internal pure returns (bool) {\n return processProof(proof, leaf) == root;\n }\n\n /**\n * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n * hash matches the root of the tree. When processing the proof, the pairs\n * of leafs & pre-images are assumed to be sorted.\n *\n * _Available since v4.4._\n */\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\n bytes32 computedHash = leaf;\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n if (computedHash <= proofElement) {\n // Hash(current computed hash + current element of the proof)\n computedHash = _efficientHash(computedHash, proofElement);\n } else {\n // Hash(current element of the proof + current computed hash)\n computedHash = _efficientHash(proofElement, computedHash);\n }\n }\n return computedHash;\n }\n\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\n assembly {\n mstore(0x00, a)\n mstore(0x20, b)\n value := keccak256(0x00, 0x40)\n }\n }\n}\n" - }, - "contracts/interfaces/IMerkleDistributor.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.12;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(\n uint256 index,\n address account,\n uint256 amount,\n bytes32[] calldata merkleProof\n ) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}\n" - } - }, - "settings": { - "outputSelection": { - "*": { - "*": [ - "metadata", - "storageLayout", - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "devdoc", - "userdoc", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "optimizer": { - "enabled": false, - "runs": 200 - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/cf9f12504fd2a3f54e63ce13e7c60cdc.json b/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/cf9f12504fd2a3f54e63ce13e7c60cdc.json deleted file mode 100644 index cd674e3e437d..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-goerli/solcInputs/cf9f12504fd2a3f54e63ce13e7c60cdc.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/L1/ResourceMetering.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { Math } from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Arithmetic } from \"../libraries/Arithmetic.sol\";\n\n/**\n * @custom:upgradeable\n * @title ResourceMetering\n * @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing\n * updates automatically based on current demand.\n */\nabstract contract ResourceMetering is Initializable {\n /**\n * @notice Represents the various parameters that control the way in which resources are\n * metered. Corresponds to the EIP-1559 resource metering system.\n *\n * @custom:field prevBaseFee Base fee from the previous block(s).\n * @custom:field prevBoughtGas Amount of gas bought so far in the current block.\n * @custom:field prevBlockNum Last block number that the base fee was updated.\n */\n struct ResourceParams {\n uint128 prevBaseFee;\n uint64 prevBoughtGas;\n uint64 prevBlockNum;\n }\n\n /**\n * @notice Represents the configuration for the EIP-1559 based curve for the deposit gas\n * market. These values should be set with care as it is possible to set them in\n * a way that breaks the deposit gas market. The target resource limit is defined as\n * maxResourceLimit / elasticityMultiplier. This struct was designed to fit within a\n * single word. There is additional space for additions in the future.\n *\n * @custom:field maxResourceLimit Represents the maximum amount of deposit gas that\n * can be purchased per block.\n * @custom:field elasticityMultiplier Determines the target resource limit along with\n * the resource limit.\n * @custom:field baseFeeMaxChangeDenominator Determines max change on fee per block.\n * @custom:field minimumBaseFee The min deposit base fee, it is clamped to this\n * value.\n * @custom:field systemTxMaxGas The amount of gas supplied to the system\n * transaction. This should be set to the same number\n * that the op-node sets as the gas limit for the\n * system transaction.\n * @custom:field maximumBaseFee The max deposit base fee, it is clamped to this\n * value.\n */\n struct ResourceConfig {\n uint32 maxResourceLimit;\n uint8 elasticityMultiplier;\n uint8 baseFeeMaxChangeDenominator;\n uint32 minimumBaseFee;\n uint32 systemTxMaxGas;\n uint128 maximumBaseFee;\n }\n\n /**\n * @notice EIP-1559 style gas parameters.\n */\n ResourceParams public params;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[48] private __gap;\n\n /**\n * @notice Meters access to a function based an amount of a requested resource.\n *\n * @param _amount Amount of the resource requested.\n */\n modifier metered(uint64 _amount) {\n // Record initial gas amount so we can refund for it later.\n uint256 initialGas = gasleft();\n\n // Run the underlying function.\n _;\n\n // Run the metering function.\n _metered(_amount, initialGas);\n }\n\n /**\n * @notice An internal function that holds all of the logic for metering a resource.\n *\n * @param _amount Amount of the resource requested.\n * @param _initialGas The amount of gas before any modifier execution.\n */\n function _metered(uint64 _amount, uint256 _initialGas) internal {\n // Update block number and base fee if necessary.\n uint256 blockDiff = block.number - params.prevBlockNum;\n\n ResourceConfig memory config = _resourceConfig();\n int256 targetResourceLimit = int256(uint256(config.maxResourceLimit)) /\n int256(uint256(config.elasticityMultiplier));\n\n if (blockDiff > 0) {\n // Handle updating EIP-1559 style gas parameters. We use EIP-1559 to restrict the rate\n // at which deposits can be created and therefore limit the potential for deposits to\n // spam the L2 system. Fee scheme is very similar to EIP-1559 with minor changes.\n int256 gasUsedDelta = int256(uint256(params.prevBoughtGas)) - targetResourceLimit;\n int256 baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) /\n (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)));\n\n // Update base fee by adding the base fee delta and clamp the resulting value between\n // min and max.\n int256 newBaseFee = Arithmetic.clamp({\n _value: int256(uint256(params.prevBaseFee)) + baseFeeDelta,\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n\n // If we skipped more than one block, we also need to account for every empty block.\n // Empty block means there was no demand for deposits in that block, so we should\n // reflect this lack of demand in the fee.\n if (blockDiff > 1) {\n // Update the base fee by repeatedly applying the exponent 1-(1/change_denominator)\n // blockDiff - 1 times. Simulates multiple empty blocks. Clamp the resulting value\n // between min and max.\n newBaseFee = Arithmetic.clamp({\n _value: Arithmetic.cdexp({\n _coefficient: newBaseFee,\n _denominator: int256(uint256(config.baseFeeMaxChangeDenominator)),\n _exponent: int256(blockDiff - 1)\n }),\n _min: int256(uint256(config.minimumBaseFee)),\n _max: int256(uint256(config.maximumBaseFee))\n });\n }\n\n // Update new base fee, reset bought gas, and update block number.\n params.prevBaseFee = uint128(uint256(newBaseFee));\n params.prevBoughtGas = 0;\n params.prevBlockNum = uint64(block.number);\n }\n\n // Make sure we can actually buy the resource amount requested by the user.\n params.prevBoughtGas += _amount;\n require(\n int256(uint256(params.prevBoughtGas)) <= int256(uint256(config.maxResourceLimit)),\n \"ResourceMetering: cannot buy more gas than available gas limit\"\n );\n\n // Determine the amount of ETH to be paid.\n uint256 resourceCost = uint256(_amount) * uint256(params.prevBaseFee);\n\n // We currently charge for this ETH amount as an L1 gas burn, so we convert the ETH amount\n // into gas by dividing by the L1 base fee. We assume a minimum base fee of 1 gwei to avoid\n // division by zero for L1s that don't support 1559 or to avoid excessive gas burns during\n // periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei\n // during any 1 day period in the last 5 years, so should be fine.\n uint256 gasCost = resourceCost / Math.max(block.basefee, 1 gwei);\n\n // Give the user a refund based on the amount of gas they used to do all of the work up to\n // this point. Since we're at the end of the modifier, this should be pretty accurate. Acts\n // effectively like a dynamic stipend (with a minimum value).\n uint256 usedGas = _initialGas - gasleft();\n if (gasCost > usedGas) {\n Burn.gas(gasCost - usedGas);\n }\n }\n\n /**\n * @notice Virtual function that returns the resource config. Contracts that inherit this\n * contract must implement this function.\n *\n * @return ResourceConfig\n */\n function _resourceConfig() internal virtual returns (ResourceConfig memory);\n\n /**\n * @notice Sets initial resource parameter values. This function must either be called by the\n * initializer function of an upgradeable child contract.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __ResourceMetering_init() internal onlyInitializing {\n params = ResourceParams({\n prevBaseFee: 1 gwei,\n prevBoughtGas: 0,\n prevBlockNum: uint64(block.number)\n });\n }\n}\n" - }, - "contracts/L2/L2CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AddressAliasHelper } from \"../vendor/AddressAliasHelper.sol\";\nimport { Predeploys } from \"../libraries/Predeploys.sol\";\nimport { CrossDomainMessenger } from \"../universal/CrossDomainMessenger.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\nimport { L2ToL1MessagePasser } from \"./L2ToL1MessagePasser.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000007\n * @title L2CrossDomainMessenger\n * @notice The L2CrossDomainMessenger is a high-level interface for message passing between L1 and\n * L2 on the L2 side. Users are generally encouraged to use this contract instead of lower\n * level message passing contracts.\n */\ncontract L2CrossDomainMessenger is CrossDomainMessenger, Semver {\n /**\n * @custom:semver 1.1.0\n *\n * @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.\n */\n constructor(address _l1CrossDomainMessenger)\n Semver(1, 1, 0)\n CrossDomainMessenger(_l1CrossDomainMessenger)\n {\n initialize();\n }\n\n /**\n * @notice Initializer.\n */\n function initialize() public initializer {\n __CrossDomainMessenger_init();\n }\n\n /**\n * @custom:legacy\n * @notice Legacy getter for the remote messenger. Use otherMessenger going forward.\n *\n * @return Address of the L1CrossDomainMessenger contract.\n */\n function l1CrossDomainMessenger() public view returns (address) {\n return OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal override {\n L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{\n value: _value\n }(_to, _gasLimit, _data);\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isOtherMessenger() internal view override returns (bool) {\n return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == OTHER_MESSENGER;\n }\n\n /**\n * @inheritdoc CrossDomainMessenger\n */\n function _isUnsafeTarget(address _target) internal view override returns (bool) {\n return _target == address(this) || _target == address(Predeploys.L2_TO_L1_MESSAGE_PASSER);\n }\n}\n" - }, - "contracts/L2/L2ToL1MessagePasser.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Types } from \"../libraries/Types.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Burn } from \"../libraries/Burn.sol\";\nimport { Semver } from \"../universal/Semver.sol\";\n\n/**\n * @custom:proxied\n * @custom:predeploy 0x4200000000000000000000000000000000000016\n * @title L2ToL1MessagePasser\n * @notice The L2ToL1MessagePasser is a dedicated contract where messages that are being sent from\n * L2 to L1 can be stored. The storage root of this contract is pulled up to the top level\n * of the L2 output to reduce the cost of proving the existence of sent messages.\n */\ncontract L2ToL1MessagePasser is Semver {\n /**\n * @notice The L1 gas limit set when eth is withdrawn using the receive() function.\n */\n uint256 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;\n\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Includes the message hashes for all withdrawals\n */\n mapping(bytes32 => bool) public sentMessages;\n\n /**\n * @notice A unique value hashed with each withdrawal.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Emitted any time a withdrawal is initiated.\n *\n * @param nonce Unique value corresponding to each withdrawal.\n * @param sender The L2 account address which initiated the withdrawal.\n * @param target The L1 account address the call will be send to.\n * @param value The ETH value submitted for withdrawal, to be forwarded to the target.\n * @param gasLimit The minimum amount of gas that must be provided when withdrawing.\n * @param data The data to be forwarded to the target on L1.\n * @param withdrawalHash The hash of the withdrawal.\n */\n event MessagePassed(\n uint256 indexed nonce,\n address indexed sender,\n address indexed target,\n uint256 value,\n uint256 gasLimit,\n bytes data,\n bytes32 withdrawalHash\n );\n\n /**\n * @notice Emitted when the balance of this contract is burned.\n *\n * @param amount Amount of ETh that was burned.\n */\n event WithdrawerBalanceBurnt(uint256 indexed amount);\n\n /**\n * @custom:semver 1.0.0\n */\n constructor() Semver(1, 0, 0) {}\n\n /**\n * @notice Allows users to withdraw ETH by sending directly to this contract.\n */\n receive() external payable {\n initiateWithdrawal(msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(\"\"));\n }\n\n /**\n * @notice Removes all ETH held by this contract from the state. Used to prevent the amount of\n * ETH on L2 inflating when ETH is withdrawn. Currently only way to do this is to\n * create a contract and self-destruct it to itself. Anyone can call this function. Not\n * incentivized since this function is very cheap.\n */\n function burn() external {\n uint256 balance = address(this).balance;\n Burn.eth(balance);\n emit WithdrawerBalanceBurnt(balance);\n }\n\n /**\n * @notice Sends a message from L2 to L1.\n *\n * @param _target Address to call on L1 execution.\n * @param _gasLimit Minimum gas limit for executing the message on L1.\n * @param _data Data to forward to L1 target.\n */\n function initiateWithdrawal(\n address _target,\n uint256 _gasLimit,\n bytes memory _data\n ) public payable {\n bytes32 withdrawalHash = Hashing.hashWithdrawal(\n Types.WithdrawalTransaction({\n nonce: messageNonce(),\n sender: msg.sender,\n target: _target,\n value: msg.value,\n gasLimit: _gasLimit,\n data: _data\n })\n );\n\n sentMessages[withdrawalHash] = true;\n\n emit MessagePassed(\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _gasLimit,\n _data,\n withdrawalHash\n );\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n}\n" - }, - "contracts/libraries/Arithmetic.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { SignedMath } from \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport { FixedPointMathLib } from \"@rari-capital/solmate/src/utils/FixedPointMathLib.sol\";\n\n/**\n * @title Arithmetic\n * @notice Even more math than before.\n */\nlibrary Arithmetic {\n /**\n * @notice Clamps a value between a minimum and maximum.\n *\n * @param _value The value to clamp.\n * @param _min The minimum value.\n * @param _max The maximum value.\n *\n * @return The clamped value.\n */\n function clamp(\n int256 _value,\n int256 _min,\n int256 _max\n ) internal pure returns (int256) {\n return SignedMath.min(SignedMath.max(_value, _min), _max);\n }\n\n /**\n * @notice (c)oefficient (d)enominator (exp)onentiation function.\n * Returns the result of: c * (1 - 1/d)^exp.\n *\n * @param _coefficient Coefficient of the function.\n * @param _denominator Fractional denominator.\n * @param _exponent Power function exponent.\n *\n * @return Result of c * (1 - 1/d)^exp.\n */\n function cdexp(\n int256 _coefficient,\n int256 _denominator,\n int256 _exponent\n ) internal pure returns (int256) {\n return\n (_coefficient *\n (FixedPointMathLib.powWad(1e18 - (1e18 / _denominator), _exponent * 1e18))) / 1e18;\n }\n}\n" - }, - "contracts/libraries/Burn.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Burn\n * @notice Utilities for burning stuff.\n */\nlibrary Burn {\n /**\n * Burns a given amount of ETH.\n *\n * @param _amount Amount of ETH to burn.\n */\n function eth(uint256 _amount) internal {\n new Burner{ value: _amount }();\n }\n\n /**\n * Burns a given amount of gas.\n *\n * @param _amount Amount of gas to burn.\n */\n function gas(uint256 _amount) internal view {\n uint256 i = 0;\n uint256 initialGas = gasleft();\n while (initialGas - gasleft() < _amount) {\n ++i;\n }\n }\n}\n\n/**\n * @title Burner\n * @notice Burner self-destructs on creation and sends all ETH to itself, removing all ETH given to\n * the contract from the circulating supply. Self-destructing is the only way to remove ETH\n * from the circulating supply.\n */\ncontract Burner {\n constructor() payable {\n selfdestruct(payable(address(this)));\n }\n}\n" - }, - "contracts/libraries/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ResourceMetering } from \"../L1/ResourceMetering.sol\";\n\n/**\n * @title Constants\n * @notice Constants is a library for storing constants. Simple! Don't put everything in here, just\n * the stuff used in multiple contracts. Constants that only apply to a single contract\n * should be defined in that contract instead.\n */\nlibrary Constants {\n /**\n * @notice Special address to be used as the tx origin for gas estimation calls in the\n * OptimismPortal and CrossDomainMessenger calls. You only need to use this address if\n * the minimum gas limit specified by the user is not actually enough to execute the\n * given message and you're attempting to estimate the actual necessary gas limit. We\n * use address(1) because it's the ecrecover precompile and therefore guaranteed to\n * never have any code on any EVM chain.\n */\n address internal constant ESTIMATION_ADDRESS = address(1);\n\n /**\n * @notice Value used for the L2 sender storage slot in both the OptimismPortal and the\n * CrossDomainMessenger contracts before an actual sender is set. This value is\n * non-zero to reduce the gas cost of message passing transactions.\n */\n address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;\n\n /**\n * @notice Returns the default values for the ResourceConfig. These are the recommended values\n * for a production network.\n */\n function DEFAULT_RESOURCE_CONFIG()\n internal\n pure\n returns (ResourceMetering.ResourceConfig memory)\n {\n ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({\n maxResourceLimit: 20_000_000,\n elasticityMultiplier: 10,\n baseFeeMaxChangeDenominator: 8,\n minimumBaseFee: 1 gwei,\n systemTxMaxGas: 1_000_000,\n maximumBaseFee: type(uint128).max\n });\n return config;\n }\n}\n" - }, - "contracts/libraries/Encoding.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Hashing } from \"./Hashing.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\n\n/**\n * @title Encoding\n * @notice Encoding handles Optimism's various different encoding schemes.\n */\nlibrary Encoding {\n /**\n * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\n * to the L2 system. Useful for searching for a deposit in the L2 system. The\n * transaction is prefixed with 0x7e to identify its EIP-2718 type.\n *\n * @param _tx User deposit transaction to encode.\n *\n * @return RLP encoded L2 deposit transaction.\n */\n function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes memory)\n {\n bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\n bytes[] memory raw = new bytes[](8);\n raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\n raw[1] = RLPWriter.writeAddress(_tx.from);\n raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\"\") : RLPWriter.writeAddress(_tx.to);\n raw[3] = RLPWriter.writeUint(_tx.mint);\n raw[4] = RLPWriter.writeUint(_tx.value);\n raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\n raw[6] = RLPWriter.writeBool(false);\n raw[7] = RLPWriter.writeBytes(_tx.data);\n return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\n }\n\n /**\n * @notice Encodes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n (, uint16 version) = decodeVersionedNonce(_nonce);\n if (version == 0) {\n return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Encoding: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Encodes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _data,\n _nonce\n );\n }\n\n /**\n * @notice Encodes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(uint256,address,address,uint256,uint256,bytes)\",\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n }\n\n /**\n * @notice Adds a version number into the first two bytes of a message nonce.\n *\n * @param _nonce Message nonce to encode into.\n * @param _version Version number to encode into the message nonce.\n *\n * @return Message nonce with version encoded into the first two bytes.\n */\n function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\n uint256 nonce;\n assembly {\n nonce := or(shl(240, _version), _nonce)\n }\n return nonce;\n }\n\n /**\n * @notice Pulls the version out of a version-encoded nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n *\n * @return Nonce without encoded version.\n * @return Version of the message.\n */\n function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\n uint240 nonce;\n uint16 version;\n assembly {\n nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n version := shr(240, _nonce)\n }\n return (nonce, version);\n }\n}\n" - }, - "contracts/libraries/Hashing.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Encoding } from \"./Encoding.sol\";\n\n/**\n * @title Hashing\n * @notice Hashing handles Optimism's various different hashing schemes.\n */\nlibrary Hashing {\n /**\n * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\n * given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\n * system.\n *\n * @param _tx User deposit transaction to hash.\n *\n * @return Hash of the RLP encoded L2 deposit transaction.\n */\n function hashDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return keccak256(Encoding.encodeDepositTransaction(_tx));\n }\n\n /**\n * @notice Computes the deposit transaction's \"source hash\", a value that guarantees the hash\n * of the L2 transaction that corresponds to a deposit is unique and is\n * deterministically generated from L1 transaction data.\n *\n * @param _l1BlockHash Hash of the L1 block where the deposit was included.\n * @param _logIndex The index of the log that created the deposit transaction.\n *\n * @return Hash of the deposit transaction's \"source hash\".\n */\n function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)\n internal\n pure\n returns (bytes32)\n {\n bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\n return keccak256(abi.encode(bytes32(0), depositId));\n }\n\n /**\n * @notice Hashes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n if (version == 0) {\n return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Hashing: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Hashes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes32) {\n return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));\n }\n\n /**\n * @notice Hashes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n return\n keccak256(\n Encoding.encodeCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n )\n );\n }\n\n /**\n * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\n *\n * @param _tx Withdrawal transaction to hash.\n *\n * @return Hashed withdrawal transaction.\n */\n function hashWithdrawal(Types.WithdrawalTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\n );\n }\n\n /**\n * @notice Hashes the various elements of an output root proof into an output root hash which\n * can be used to check if the proof is valid.\n *\n * @param _outputRootProof Output root proof which should hash to an output root.\n *\n * @return Hashed output root proof.\n */\n function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(\n _outputRootProof.version,\n _outputRootProof.stateRoot,\n _outputRootProof.messagePasserStorageRoot,\n _outputRootProof.latestBlockhash\n )\n );\n }\n}\n" - }, - "contracts/libraries/Predeploys.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Predeploys\n * @notice Contains constant addresses for contracts that are pre-deployed to the L2 system.\n */\nlibrary Predeploys {\n /**\n * @notice Address of the L2ToL1MessagePasser predeploy.\n */\n address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;\n\n /**\n * @notice Address of the L2CrossDomainMessenger predeploy.\n */\n address internal constant L2_CROSS_DOMAIN_MESSENGER =\n 0x4200000000000000000000000000000000000007;\n\n /**\n * @notice Address of the L2StandardBridge predeploy.\n */\n address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\n\n /**\n * @notice Address of the L2ERC721Bridge predeploy.\n */\n address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;\n\n /**\n * @notice Address of the SequencerFeeWallet predeploy.\n */\n address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;\n\n /**\n * @notice Address of the OptimismMintableERC20Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY =\n 0x4200000000000000000000000000000000000012;\n\n /**\n * @notice Address of the OptimismMintableERC721Factory predeploy.\n */\n address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY =\n 0x4200000000000000000000000000000000000017;\n\n /**\n * @notice Address of the L1Block predeploy.\n */\n address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;\n\n /**\n * @notice Address of the GasPriceOracle predeploy. Includes fee information\n * and helpers for computing the L1 portion of the transaction fee.\n */\n address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;\n\n /**\n * @custom:legacy\n * @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger\n * or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.\n */\n address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\n\n /**\n * @custom:legacy\n * @notice Address of the DeployerWhitelist predeploy. No longer active.\n */\n address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the\n * state trie as of the Bedrock upgrade. Contract has been locked and write functions\n * can no longer be accessed.\n */\n address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;\n\n /**\n * @custom:legacy\n * @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy\n * instead, which exposes more information about the L1 state.\n */\n address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\n\n /**\n * @custom:legacy\n * @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated\n * L2ToL1MessagePasser contract instead.\n */\n address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\n\n /**\n * @notice Address of the ProxyAdmin predeploy.\n */\n address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;\n\n /**\n * @notice Address of the BaseFeeVault predeploy.\n */\n address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;\n\n /**\n * @notice Address of the L1FeeVault predeploy.\n */\n address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;\n\n /**\n * @notice Address of the GovernanceToken predeploy.\n */\n address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042;\n}\n" - }, - "contracts/libraries/SafeCall.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title SafeCall\n * @notice Perform low level safe calls\n */\nlibrary SafeCall {\n /**\n * @notice Perform a low level call without copying any returndata\n *\n * @param _target Address to call\n * @param _gas Amount of gas to pass to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function call(\n address _target,\n uint256 _gas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n }\n return _success;\n }\n\n /**\n * @notice Perform a low level call without copying any returndata. This function\n * will revert if the call cannot be performed with the specified minimum\n * gas.\n *\n * @param _target Address to call\n * @param _minGas The minimum amount of gas that may be passed to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function callWithMinGas(\n address _target,\n uint256 _minGas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n // Assertion: gasleft() >= ((_minGas + 200) * 64) / 63\n //\n // Because EIP-150 ensures that, a maximum of 63/64ths of the remaining gas in the call\n // frame may be passed to a subcontext, we need to ensure that the gas will not be\n // truncated to hold this function's invariant: \"If a call is performed by\n // `callWithMinGas`, it must receive at least the specified minimum gas limit.\" In\n // addition, exactly 51 gas is consumed between the below `GAS` opcode and the `CALL`\n // opcode, so it is factored in with some extra room for error.\n if lt(gas(), div(mul(64, add(_minGas, 200)), 63)) {\n // Store the \"Error(string)\" selector in scratch space.\n mstore(0, 0x08c379a0)\n // Store the pointer to the string length in scratch space.\n mstore(32, 32)\n // Store the string.\n //\n // SAFETY:\n // - We pad the beginning of the string with two zero bytes as well as the\n // length (24) to ensure that we override the free memory pointer at offset\n // 0x40. This is necessary because the free memory pointer is likely to\n // be greater than 1 byte when this function is called, but it is incredibly\n // unlikely that it will be greater than 3 bytes. As for the data within\n // 0x60, it is ensured that it is 0 due to 0x60 being the zero offset.\n // - It's fine to clobber the free memory pointer, we're reverting.\n mstore(88, 0x0000185361666543616c6c3a204e6f7420656e6f75676820676173)\n\n // Revert with 'Error(\"SafeCall: Not enough gas\")'\n revert(28, 100)\n }\n\n // The call will be supplied at least (((_minGas + 200) * 64) / 63) - 49 gas due to the\n // above assertion. This ensures that, in all circumstances, the call will\n // receive at least the minimum amount of gas specified.\n // We can prove this property by solving the inequalities:\n // ((((_minGas + 200) * 64) / 63) - 49) >= _minGas\n // ((((_minGas + 200) * 64) / 63) - 51) * (63 / 64) >= _minGas\n // Both inequalities hold true for all possible values of `_minGas`.\n _success := call(\n gas(), // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 32), // inloc\n mload(_calldata), // inlen\n 0x00, // outloc\n 0x00 // outlen\n )\n }\n return _success;\n }\n}\n" - }, - "contracts/libraries/Types.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Types\n * @notice Contains various types used throughout the Optimism contract system.\n */\nlibrary Types {\n /**\n * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\n * timestamp that the output root is posted. This timestamp is used to verify that the\n * finalization period has passed since the output root was submitted.\n *\n * @custom:field outputRoot Hash of the L2 output.\n * @custom:field timestamp Timestamp of the L1 block that the output root was submitted in.\n * @custom:field l2BlockNumber L2 block number that the output corresponds to.\n */\n struct OutputProposal {\n bytes32 outputRoot;\n uint128 timestamp;\n uint128 l2BlockNumber;\n }\n\n /**\n * @notice Struct representing the elements that are hashed together to generate an output root\n * which itself represents a snapshot of the L2 state.\n *\n * @custom:field version Version of the output root.\n * @custom:field stateRoot Root of the state trie at the block of this output.\n * @custom:field messagePasserStorageRoot Root of the message passer storage trie.\n * @custom:field latestBlockhash Hash of the block this output was generated from.\n */\n struct OutputRootProof {\n bytes32 version;\n bytes32 stateRoot;\n bytes32 messagePasserStorageRoot;\n bytes32 latestBlockhash;\n }\n\n /**\n * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n * user (as opposed to a system deposit transaction generated by the system).\n *\n * @custom:field from Address of the sender of the transaction.\n * @custom:field to Address of the recipient of the transaction.\n * @custom:field isCreation True if the transaction is a contract creation.\n * @custom:field value Value to send to the recipient.\n * @custom:field mint Amount of ETH to mint.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n * @custom:field l1BlockHash Hash of the block the transaction was submitted in.\n * @custom:field logIndex Index of the log in the block the transaction was submitted in.\n */\n struct UserDepositTransaction {\n address from;\n address to;\n bool isCreation;\n uint256 value;\n uint256 mint;\n uint64 gasLimit;\n bytes data;\n bytes32 l1BlockHash;\n uint256 logIndex;\n }\n\n /**\n * @notice Struct representing a withdrawal transaction.\n *\n * @custom:field nonce Nonce of the withdrawal transaction\n * @custom:field sender Address of the sender of the transaction.\n * @custom:field target Address of the recipient of the transaction.\n * @custom:field value Value to send to the recipient.\n * @custom:field gasLimit Gas limit of the transaction.\n * @custom:field data Data of the transaction.\n */\n struct WithdrawalTransaction {\n uint256 nonce;\n address sender;\n address target;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n}\n" - }, - "contracts/libraries/rlp/RLPWriter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\n * @title RLPWriter\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\n * RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\n * modifications to improve legibility.\n */\nlibrary RLPWriter {\n /**\n * @notice RLP encodes a byte string.\n *\n * @param _in The byte string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_in.length == 1 && uint8(_in[0]) < 128) {\n encoded = _in;\n } else {\n encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n }\n\n return encoded;\n }\n\n /**\n * @notice RLP encodes a list of RLP encoded byte byte strings.\n *\n * @param _in The list of RLP encoded byte strings.\n *\n * @return The RLP encoded list of items in bytes.\n */\n function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n bytes memory list = _flatten(_in);\n return abi.encodePacked(_writeLength(list.length, 192), list);\n }\n\n /**\n * @notice RLP encodes a string.\n *\n * @param _in The string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeString(string memory _in) internal pure returns (bytes memory) {\n return writeBytes(bytes(_in));\n }\n\n /**\n * @notice RLP encodes an address.\n *\n * @param _in The address to encode.\n *\n * @return The RLP encoded address in bytes.\n */\n function writeAddress(address _in) internal pure returns (bytes memory) {\n return writeBytes(abi.encodePacked(_in));\n }\n\n /**\n * @notice RLP encodes a uint.\n *\n * @param _in The uint256 to encode.\n *\n * @return The RLP encoded uint256 in bytes.\n */\n function writeUint(uint256 _in) internal pure returns (bytes memory) {\n return writeBytes(_toBinary(_in));\n }\n\n /**\n * @notice RLP encodes a bool.\n *\n * @param _in The bool to encode.\n *\n * @return The RLP encoded bool in bytes.\n */\n function writeBool(bool _in) internal pure returns (bytes memory) {\n bytes memory encoded = new bytes(1);\n encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n return encoded;\n }\n\n /**\n * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\n *\n * @param _len The length of the string or the payload.\n * @param _offset 128 if item is string, 192 if item is list.\n *\n * @return RLP encoded bytes.\n */\n function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_len < 56) {\n encoded = new bytes(1);\n encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n } else {\n uint256 lenLen;\n uint256 i = 1;\n while (_len / i != 0) {\n lenLen++;\n i *= 256;\n }\n\n encoded = new bytes(lenLen + 1);\n encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n for (i = 1; i <= lenLen; i++) {\n encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n }\n }\n\n return encoded;\n }\n\n /**\n * @notice Encode integer in big endian binary form with no leading zeroes.\n *\n * @param _x The integer to encode.\n *\n * @return RLP encoded bytes.\n */\n function _toBinary(uint256 _x) private pure returns (bytes memory) {\n bytes memory b = abi.encodePacked(_x);\n\n uint256 i = 0;\n for (; i < 32; i++) {\n if (b[i] != 0) {\n break;\n }\n }\n\n bytes memory res = new bytes(32 - i);\n for (uint256 j = 0; j < res.length; j++) {\n res[j] = b[i++];\n }\n\n return res;\n }\n\n /**\n * @custom:attribution https://github.com/Arachnid/solidity-stringutils\n * @notice Copies a piece of memory to another location.\n *\n * @param _dest Destination location.\n * @param _src Source location.\n * @param _len Length of memory to copy.\n */\n function _memcpy(\n uint256 _dest,\n uint256 _src,\n uint256 _len\n ) private pure {\n uint256 dest = _dest;\n uint256 src = _src;\n uint256 len = _len;\n\n for (; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n uint256 mask;\n unchecked {\n mask = 256**(32 - len) - 1;\n }\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /**\n * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\n * @notice Flattens a list of byte strings into one byte string.\n *\n * @param _list List of byte strings to flatten.\n *\n * @return The flattened byte string.\n */\n function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n if (_list.length == 0) {\n return new bytes(0);\n }\n\n uint256 len;\n uint256 i = 0;\n for (; i < _list.length; i++) {\n len += _list[i].length;\n }\n\n bytes memory flattened = new bytes(len);\n uint256 flattenedPtr;\n assembly {\n flattenedPtr := add(flattened, 0x20)\n }\n\n for (i = 0; i < _list.length; i++) {\n bytes memory item = _list[i];\n\n uint256 listPtr;\n assembly {\n listPtr := add(item, 0x20)\n }\n\n _memcpy(flattenedPtr, listPtr, item.length);\n flattenedPtr += _list[i].length;\n }\n\n return flattened;\n }\n}\n" - }, - "contracts/universal/CrossDomainMessenger.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\nimport { Constants } from \"../libraries/Constants.sol\";\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer0\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * libAddressManager variable used to exist. Must be the first contract in the inheritance\n * tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer0 {\n /**\n * @custom:legacy\n * @custom:spacer libAddressManager\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n}\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer1\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * PausableUpgradable and OwnableUpgradeable variables used to exist. Must be\n * the third contract in the inheritance tree of the CrossDomainMessenger.\n */\ncontract CrossDomainMessengerLegacySpacer1 {\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable via OwnableUpgradeable.\n *\n */\n uint256[50] private spacer_1_0_1600;\n\n /**\n * @custom:legacy\n * @custom:spacer _owner\n * @notice Spacer for backwards compatibility.\n * Come from OpenZeppelin OwnableUpgradeable.\n */\n address private spacer_51_0_20;\n\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * ContextUpgradable via PausableUpgradable.\n */\n uint256[49] private spacer_52_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer _paused\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n bool private spacer_101_0_1;\n\n /**\n * @custom:legacy\n * @custom:spacer __gap\n * @notice Spacer for backwards compatibility. Comes from OpenZeppelin\n * PausableUpgradable.\n */\n uint256[49] private spacer_102_0_1568;\n\n /**\n * @custom:legacy\n * @custom:spacer ReentrancyGuardUpgradeable's `_status` field.\n * @notice Spacer for backwards compatibility\n */\n uint256 private spacer_151_0_32;\n\n /**\n * @custom:spacer ReentrancyGuardUpgradeable\n * @notice Spacer for backwards compatibility\n */\n uint256[49] private __gap_reentrancy_guard;\n\n /**\n * @custom:legacy\n * @custom:spacer blockedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_201_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer relayedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_202_0_32;\n}\n\n/**\n * @custom:upgradeable\n * @title CrossDomainMessenger\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\n * cross-chain messenger contracts. It's designed to be a universal interface that only\n * needs to be extended slightly to provide low-level message passing functionality on each\n * chain it's deployed on. Currently only designed for message passing between two paired\n * chains and does not support one-to-many interactions.\n *\n * Any changes to this contract MUST result in a semver bump for contracts that inherit it.\n */\nabstract contract CrossDomainMessenger is\n CrossDomainMessengerLegacySpacer0,\n Initializable,\n CrossDomainMessengerLegacySpacer1\n{\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Constant overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_CONSTANT_OVERHEAD = 200_000;\n\n /**\n * @notice Numerator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 1016;\n\n /**\n * @notice Denominator for dynamic overhead added to the base gas for a message.\n */\n uint64 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 1000;\n\n /**\n * @notice Extra gas added to base gas for each byte of calldata in a message.\n */\n uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\n\n /**\n * @notice Address of the paired CrossDomainMessenger contract on the other chain.\n */\n address public immutable OTHER_MESSENGER;\n\n /**\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n * be present in this mapping if it has successfully been relayed on this chain, and\n * can therefore not be relayed again.\n */\n mapping(bytes32 => bool) public successfulMessages;\n\n /**\n * @notice Address of the sender of the currently executing message on the other chain. If the\n * value of this variable is the default value (0x00000000...dead) then no message is\n * currently being executed. Use the xDomainMessageSender getter which will throw an\n * error if this is the case.\n */\n address internal xDomainMsgSender;\n\n /**\n * @notice Nonce for the next message to be sent, without the message version applied. Use the\n * messageNonce getter which will insert the message version into the nonce to give you\n * the actual nonce to be used for the message.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Mapping of message hashes to a boolean if and only if the message has failed to be\n * executed at least once. A message will not be present in this mapping if it\n * successfully executed on the first attempt.\n */\n mapping(bytes32 => bool) public failedMessages;\n\n /**\n * @notice A mapping of hashes to reentrancy locks.\n */\n mapping(bytes32 => bool) internal reentrancyLocks;\n\n /**\n * @notice Reserve extra slots in the storage layout for future upgrades.\n * A gap size of 41 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[41] private __gap;\n\n /**\n * @notice Emitted whenever a message is sent to the other chain.\n *\n * @param target Address of the recipient of the message.\n * @param sender Address of the sender of the message.\n * @param message Message to trigger the recipient address with.\n * @param messageNonce Unique nonce attached to the message.\n * @param gasLimit Minimum gas limit that the message can be executed with.\n */\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n /**\n * @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the\n * SentMessage event without breaking the ABI of this contract, this is good enough.\n *\n * @param sender Address of the sender of the message.\n * @param value ETH value sent along with the message to the recipient.\n */\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n /**\n * @notice Emitted whenever a message is successfully relayed on this chain.\n *\n * @param msgHash Hash of the message that was relayed.\n */\n event RelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @notice Emitted whenever a message fails to be relayed on this chain.\n *\n * @param msgHash Hash of the message that failed to be relayed.\n */\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @param _otherMessenger Address of the messenger on the paired chain.\n */\n constructor(address _otherMessenger) {\n OTHER_MESSENGER = _otherMessenger;\n }\n\n /**\n * @notice Sends a message to some target address on the other chain. Note that if the call\n * always reverts, then the message will be unrelayable, and any ETH sent will be\n * permanently locked. The same will occur if the target on the other chain is\n * considered unsafe (see the _isUnsafeTarget() function).\n *\n * @param _target Target contract or wallet address.\n * @param _message Message to trigger the target address with.\n * @param _minGasLimit Minimum gas limit that the message can be executed with.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _minGasLimit\n ) external payable {\n // Triggers a message to the other messenger. Note that the amount of gas provided to the\n // message is the amount of gas requested by the user PLUS the base gas value. We want to\n // guarantee the property that the call to the target contract will always have at least\n // the minimum gas limit specified by the user.\n _sendMessage(\n OTHER_MESSENGER,\n baseGas(_message, _minGasLimit),\n msg.value,\n abi.encodeWithSelector(\n this.relayMessage.selector,\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _minGasLimit,\n _message\n )\n );\n\n emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit);\n emit SentMessageExtension1(msg.sender, msg.value);\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\n * be executed via cross-chain call from the other messenger OR if the message was\n * already received once and is currently being replayed.\n *\n * @param _nonce Nonce of the message being relayed.\n * @param _sender Address of the user who sent the message.\n * @param _target Address that the message is targeted at.\n * @param _value ETH value to send with the message.\n * @param _minGasLimit Minimum amount of gas that the message can be executed with.\n * @param _message Message to send to the target.\n */\n function relayMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _minGasLimit,\n bytes calldata _message\n ) external payable {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n require(\n version < 2,\n \"CrossDomainMessenger: only version 0 or 1 messages are supported at this time\"\n );\n\n // If the message is version 0, then it's a migrated legacy withdrawal. We therefore need\n // to check that the legacy version of the message has not already been relayed.\n if (version == 0) {\n bytes32 oldHash = Hashing.hashCrossDomainMessageV0(_target, _sender, _message, _nonce);\n require(\n successfulMessages[oldHash] == false,\n \"CrossDomainMessenger: legacy withdrawal already relayed\"\n );\n }\n\n // We use the v1 message hash as the unique identifier for the message because it commits\n // to the value and minimum gas limit of the message.\n bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _minGasLimit,\n _message\n );\n\n // Check if the reentrancy lock for the `versionedHash` is already set.\n if (reentrancyLocks[versionedHash]) {\n revert(\"ReentrancyGuard: reentrant call\");\n }\n // Trigger the reentrancy lock for `versionedHash`\n reentrancyLocks[versionedHash] = true;\n\n if (_isOtherMessenger()) {\n // These properties should always hold when the message is first submitted (as\n // opposed to being replayed).\n assert(msg.value == _value);\n assert(!failedMessages[versionedHash]);\n } else {\n require(\n msg.value == 0,\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n\n require(\n failedMessages[versionedHash],\n \"CrossDomainMessenger: message cannot be replayed\"\n );\n }\n\n require(\n _isUnsafeTarget(_target) == false,\n \"CrossDomainMessenger: cannot send message to blocked system address\"\n );\n\n require(\n successfulMessages[versionedHash] == false,\n \"CrossDomainMessenger: message has already been relayed\"\n );\n\n xDomainMsgSender = _sender;\n bool success = SafeCall.callWithMinGas(_target, _minGasLimit, _value, _message);\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n\n if (success) {\n successfulMessages[versionedHash] = true;\n emit RelayedMessage(versionedHash);\n } else {\n failedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n\n // Revert in this case if the transaction was triggered by the estimation address. This\n // should only be possible during gas estimation or we have bigger problems. Reverting\n // here will make the behavior of gas estimation change such that the gas limit\n // computed will be the amount required to relay the message, even if that amount is\n // greater than the minimum gas limit specified by the user.\n if (tx.origin == Constants.ESTIMATION_ADDRESS) {\n revert(\"CrossDomainMessenger: failed to relay message\");\n }\n }\n\n // Clear the reentrancy lock for `versionedHash`\n reentrancyLocks[versionedHash] = false;\n }\n\n /**\n * @notice Retrieves the address of the contract or wallet that initiated the currently\n * executing message on the other chain. Will throw an error if there is no message\n * currently being executed. Allows the recipient of a call to see who triggered it.\n *\n * @return Address of the sender of the currently executing message on the other chain.\n */\n function xDomainMessageSender() external view returns (address) {\n require(\n xDomainMsgSender != Constants.DEFAULT_L2_SENDER,\n \"CrossDomainMessenger: xDomainMessageSender is not set\"\n );\n\n return xDomainMsgSender;\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n\n /**\n * @notice Computes the amount of gas required to guarantee that a given message will be\n * received on the other chain without running out of gas. Guaranteeing that a message\n * will not run out of gas is important because this ensures that a message can always\n * be replayed on the other chain if it fails to execute completely.\n *\n * @param _message Message to compute the amount of required gas for.\n * @param _minGasLimit Minimum desired gas limit when message goes to target.\n *\n * @return Amount of gas required to guarantee message receipt.\n */\n function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint64) {\n // We peform the following math on uint64s to avoid overflow errors. Multiplying the\n // by MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR would otherwise limit the _minGasLimit to\n // type(uint32).max / MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR ~= 4.2m.\n return\n // Dynamic overhead\n ((uint64(_minGasLimit) * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\n MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\n // Calldata overhead\n (uint64(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\n // Constant overhead\n MIN_GAS_CONSTANT_OVERHEAD;\n }\n\n /**\n * @notice Intializer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __CrossDomainMessenger_init() internal onlyInitializing {\n xDomainMsgSender = Constants.DEFAULT_L2_SENDER;\n }\n\n /**\n * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @param _to Recipient of the message on the other chain.\n * @param _gasLimit Minimum gas limit the message can be executed with.\n * @param _value Amount of ETH to send with the message.\n * @param _data Message data.\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal virtual;\n\n /**\n * @notice Checks whether the message is coming from the other messenger. Implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @return Whether the message is coming from the other messenger.\n */\n function _isOtherMessenger() internal view virtual returns (bool);\n\n /**\n * @notice Checks whether a given call target is a system address that could cause the\n * messenger to peform an unsafe action. This is NOT a mechanism for blocking user\n * addresses. This is ONLY used to prevent the execution of messages to specific\n * system addresses that could cause security issues, e.g., having the\n * CrossDomainMessenger send messages to itself.\n *\n * @param _target Address of the contract to check.\n *\n * @return Whether or not the address is an unsafe system address.\n */\n function _isUnsafeTarget(address _target) internal view virtual returns (bool);\n}\n" - }, - "contracts/universal/Semver.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n" - }, - "contracts/vendor/AddressAliasHelper.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.0;\n\nlibrary AddressAliasHelper {\n uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n /// @notice Utility function that converts the address in the L1 that submitted a tx to\n /// the inbox to the msg.sender viewed in the L2\n /// @param l1Address the address in the L1 that triggered the tx to L2\n /// @return l2Address L2 address as viewed in msg.sender\n function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {\n unchecked {\n l2Address = address(uint160(l1Address) + offset);\n }\n }\n\n /// @notice Utility function that converts the msg.sender viewed in the L2 to the\n /// address in the L1 that submitted a tx to the inbox\n /// @param l2Address L2 address as viewed in msg.sender\n /// @return l1Address the address in the L1 that triggered the tx to L2\n function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {\n unchecked {\n l1Address = address(uint160(l2Address) - offset);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "node_modules/@rari-capital/solmate/src/utils/FixedPointMathLib.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n /*//////////////////////////////////////////////////////////////\n SIMPLIFIED FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n }\n\n function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n }\n\n function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n }\n\n function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n }\n\n function powWad(int256 x, int256 y) internal pure returns (int256) {\n // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)\n return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0.\n }\n\n function expWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n // When the result is < 0.5 we return zero. This happens when\n // x <= floor(log(0.5e18) * 1e18) ~ -42e18\n if (x <= -42139678854452767551) return 0;\n\n // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\n // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\n if (x >= 135305999368893231589) revert(\"EXP_OVERFLOW\");\n\n // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\n // for more intermediate precision and a binary basis. This base conversion\n // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n x = (x << 78) / 5**18;\n\n // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;\n x = x - k * 54916777467707473351141471128;\n\n // k is in the range [-61, 195].\n\n // Evaluate using a (6, 7)-term rational approximation.\n // p is made monic, we'll multiply by a scale factor later.\n int256 y = x + 1346386616545796478920950773328;\n y = ((y * x) >> 96) + 57155421227552351082224309758442;\n int256 p = y + x - 94201549194550492254356042504812;\n p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n p = p * x + (4385272521454847904659076985693276 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n int256 q = x - 2855989394907223263936484059900;\n q = ((q * x) >> 96) + 50020603652535783019961831881945;\n q = ((q * x) >> 96) - 533845033583426703283633433725380;\n q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial won't have zeros in the domain as all its roots are complex.\n // No scaling is necessary because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r should be in the range (0.09, 0.25) * 2**96.\n\n // We now need to multiply r by:\n // * the scale factor s = ~6.031367120.\n // * the 2**k factor from the range reduction.\n // * the 1e18 / 2**96 factor for base conversion.\n // We do this all at once, with an intermediate result in 2**213\n // basis, so the final right shift is always by a positive amount.\n r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));\n }\n }\n\n function lnWad(int256 x) internal pure returns (int256 r) {\n unchecked {\n require(x > 0, \"UNDEFINED\");\n\n // We want to convert x from 10**18 fixed point to 2**96 fixed point.\n // We do this by multiplying by 2**96 / 10**18. But since\n // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\n // and add ln(2**96 / 10**18) at the end.\n\n // Reduce range of x to (1, 2) * 2**96\n // ln(2^k * x) = k * ln(2) + ln(x)\n int256 k = int256(log2(uint256(x))) - 96;\n x <<= uint256(159 - k);\n x = int256(uint256(x) >> 159);\n\n // Evaluate using a (8, 8)-term rational approximation.\n // p is made monic, we will multiply by a scale factor later.\n int256 p = x + 3273285459638523848632254066296;\n p = ((p * x) >> 96) + 24828157081833163892658089445524;\n p = ((p * x) >> 96) + 43456485725739037958740375743393;\n p = ((p * x) >> 96) - 11111509109440967052023855526967;\n p = ((p * x) >> 96) - 45023709667254063763336534515857;\n p = ((p * x) >> 96) - 14706773417378608786704636184526;\n p = p * x - (795164235651350426258249787498 << 96);\n\n // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n // q is monic by convention.\n int256 q = x + 5573035233440673466300451813936;\n q = ((q * x) >> 96) + 71694874799317883764090561454958;\n q = ((q * x) >> 96) + 283447036172924575727196451306956;\n q = ((q * x) >> 96) + 401686690394027663651624208769553;\n q = ((q * x) >> 96) + 204048457590392012362485061816622;\n q = ((q * x) >> 96) + 31853899698501571402653359427138;\n q = ((q * x) >> 96) + 909429971244387300277376558375;\n assembly {\n // Div in assembly because solidity adds a zero check despite the unchecked.\n // The q polynomial is known not to have zeros in the domain.\n // No scaling required because p is already 2**96 too large.\n r := sdiv(p, q)\n }\n\n // r is in the range (0, 0.125) * 2**96\n\n // Finalization, we need to:\n // * multiply by the scale factor s = 5.549…\n // * add ln(2**96 / 10**18)\n // * add k * ln(2)\n // * multiply by 10**18 / 2**96 = 5**18 >> 78\n\n // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\n r *= 1677202110996718588342820967067443963516166;\n // add ln(2) * k * 5e18 * 2**192\n r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;\n // add ln(2**96 / 10**18) * 5e18 * 2**192\n r += 600920179829731861736702779321621459595472258049074101567377883020018308;\n // base conversion: mul 2**18 / 2**192\n r >>= 174;\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n LOW LEVEL FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function mulDivDown(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // Divide z by the denominator.\n z := div(z, denominator)\n }\n }\n\n function mulDivUp(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n assembly {\n // Store x * y in z for now.\n z := mul(x, y)\n\n // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\n if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\n revert(0, 0)\n }\n\n // First, divide z - 1 by the denominator and add 1.\n // We allow z - 1 to underflow if z is 0, because we multiply the\n // end result by 0 if z is zero, ensuring we return 0 if z is zero.\n z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))\n }\n }\n\n function rpow(\n uint256 x,\n uint256 n,\n uint256 scalar\n ) internal pure returns (uint256 z) {\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n // 0 ** 0 = 1\n z := scalar\n }\n default {\n // 0 ** n = 0\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n // If n is even, store scalar in z for now.\n z := scalar\n }\n default {\n // If n is odd, store x in z for now.\n z := x\n }\n\n // Shifting right by 1 is like dividing by 2.\n let half := shr(1, scalar)\n\n for {\n // Shift n right by 1 before looping to halve it.\n n := shr(1, n)\n } n {\n // Shift n right by 1 each iteration to halve it.\n n := shr(1, n)\n } {\n // Revert immediately if x ** 2 would overflow.\n // Equivalent to iszero(eq(div(xx, x), x)) here.\n if shr(128, x) {\n revert(0, 0)\n }\n\n // Store x squared.\n let xx := mul(x, x)\n\n // Round to the nearest number.\n let xxRound := add(xx, half)\n\n // Revert if xx + half overflowed.\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n\n // Set x to scaled xxRound.\n x := div(xxRound, scalar)\n\n // If n is even:\n if mod(n, 2) {\n // Compute z * x.\n let zx := mul(z, x)\n\n // If z * x overflowed:\n if iszero(eq(div(zx, x), z)) {\n // Revert if x is non-zero.\n if iszero(iszero(x)) {\n revert(0, 0)\n }\n }\n\n // Round to the nearest number.\n let zxRound := add(zx, half)\n\n // Revert if zx + half overflowed.\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n\n // Return properly scaled zxRound.\n z := div(zxRound, scalar)\n }\n }\n }\n }\n }\n\n /*//////////////////////////////////////////////////////////////\n GENERAL NUMBER UTILITIES\n //////////////////////////////////////////////////////////////*/\n\n function sqrt(uint256 x) internal pure returns (uint256 z) {\n assembly {\n let y := x // We start y at x, which will help us make our initial estimate.\n\n z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n // We check y >= 2^(k + 8) but shift right by k bits\n // each branch to ensure that if x >= 256, then y >= 256.\n if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n y := shr(128, y)\n z := shl(64, z)\n }\n if iszero(lt(y, 0x1000000000000000000)) {\n y := shr(64, y)\n z := shl(32, z)\n }\n if iszero(lt(y, 0x10000000000)) {\n y := shr(32, y)\n z := shl(16, z)\n }\n if iszero(lt(y, 0x1000000)) {\n y := shr(16, y)\n z := shl(8, z)\n }\n\n // Goal was to get z*z*y within a small factor of x. More iterations could\n // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n // There is no overflow risk here since y < 2^136 after the first branch above.\n z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n z := shr(1, add(z, div(x, z)))\n\n // If x+1 is a perfect square, the Babylonian method cycles between\n // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n z := sub(z, lt(div(x, z), z))\n }\n }\n\n function log2(uint256 x) internal pure returns (uint256 r) {\n require(x > 0, \"UNDEFINED\");\n\n assembly {\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\n r := or(r, shl(3, lt(0xff, shr(r, x))))\n r := or(r, shl(2, lt(0xf, shr(r, x))))\n r := or(r, shl(1, lt(0x3, shr(r, x))))\n r := or(r, lt(0x1, shr(r, x)))\n }\n }\n}\n" - } - }, - "settings": { - "remappings": [ - "@openzeppelin/=node_modules/@openzeppelin/", - "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", - "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", - "@rari-capital/=node_modules/@rari-capital/", - "@rari-capital/solmate/=node_modules/@rari-capital/solmate/", - "@safe-global/safe-contracts/=node_modules/@safe-global/safe-contracts/", - "ds-test/=node_modules/ds-test/src/", - "forge-std/=node_modules/forge-std/src/", - "solady/=node_modules/solady/src/" - ], - "optimizer": { - "enabled": true, - "runs": 999999 - }, - "metadata": { - "bytecodeHash": "none" - }, - "outputSelection": { - "*": { - "": [ - "ast" - ], - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "storageLayout", - "devdoc", - "userdoc" - ] - } - }, - "evmVersion": "london", - "libraries": {} - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/.chainId b/packages/contracts-bedrock/deployments/optimism-mainnet/.chainId deleted file mode 100644 index 9a037142aa3c..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/.chainId +++ /dev/null @@ -1 +0,0 @@ -10 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/AssetReceiver.json b/packages/contracts-bedrock/deployments/optimism-mainnet/AssetReceiver.json deleted file mode 100644 index 90bda4e9e155..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/AssetReceiver.json +++ /dev/null @@ -1,505 +0,0 @@ -{ - "address": "0x15DdA60616Ffca20371ED1659dBB78E888f65556", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ReceivedETH", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewERC20", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "WithdrewERC721", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "withdrawer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrewETH", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_gas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "CALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_gas", - "type": "uint256" - } - ], - "name": "DELEGATECALL", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC20", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ERC721", - "name": "_asset", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_id", - "type": "uint256" - } - ], - "name": "withdrawERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0xc478761265f900cc77738ebe913f9894e4e31f5eb9571521d2c82eedcde263aa", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "887432", - "logsBloom": "0x00100000000000000001000000000000000000000000000000000000000000000000100000000000000000100000080000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000020000000000000000000000000000000000000000000000", - "blockHash": "0xba4660a5466eba797503a88256c703f1c0019eec12d403db1a6f998d285281c5", - "transactionHash": "0xc478761265f900cc77738ebe913f9894e4e31f5eb9571521d2c82eedcde263aa", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 10573944, - "transactionHash": "0xc478761265f900cc77738ebe913f9894e4e31f5eb9571521d2c82eedcde263aa", - "address": "0x15DdA60616Ffca20371ED1659dBB78E888f65556", - "topics": [ - "0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58" - ], - "data": "0x", - "logIndex": 0, - "blockHash": "0xba4660a5466eba797503a88256c703f1c0019eec12d403db1a6f998d285281c5" - } - ], - "blockNumber": 10573944, - "cumulativeGasUsed": "887432", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 2, - "solcInputHash": "66d28de48de020e62747d42ffe3118e7", - "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ReceivedETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewETH\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"CALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"}],\"name\":\"DELEGATECALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC721\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\",\"_value\":\"ETH value to send with the call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"DELEGATECALL(address,bytes,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"constructor\":{\"params\":{\"_owner\":\"Initial contract owner.\"}},\"withdrawERC20(address,address)\":{\"params\":{\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC20(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount of ERC20 to withdraw.\",\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC721(address,address,uint256)\":{\"params\":{\"_asset\":\"ERC721 token to withdraw.\",\"_id\":\"Token ID of the ERC721 token to withdraw.\",\"_to\":\"Address to receive the ERC721 token.\"}},\"withdrawETH(address)\":{\"params\":{\"_to\":\"Address to receive the ETH balance.\"}},\"withdrawETH(address,uint256)\":{\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_to\":\"Address to receive the ETH balance.\"}}},\"title\":\"AssetReceiver\",\"version\":1},\"userdoc\":{\"events\":{\"ReceivedETH(address,uint256)\":{\"notice\":\"Emitted when ETH is received by this address.\"},\"WithdrewERC20(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewERC721(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC721 tokens are withdrawn from this address.\"},\"WithdrewETH(address,address,uint256)\":{\"notice\":\"Emitted when ETH is withdrawn from this address.\"}},\"kind\":\"user\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"notice\":\"Sends a CALL to a target address.\"},\"DELEGATECALL(address,bytes,uint256)\":{\"notice\":\"Sends a DELEGATECALL to a target address.\"},\"withdrawERC20(address,address)\":{\"notice\":\"Withdraws full ERC20 balance to the recipient.\"},\"withdrawERC20(address,address,uint256)\":{\"notice\":\"Withdraws partial ERC20 balance to the recipient.\"},\"withdrawERC721(address,address,uint256)\":{\"notice\":\"Withdraws ERC721 token to the recipient.\"},\"withdrawETH(address)\":{\"notice\":\"Withdraws full ETH balance to the recipient.\"},\"withdrawETH(address,uint256)\":{\"notice\":\"Withdraws partial ETH balance to the recipient.\"}},\"notice\":\"AssetReceiver is a minimal contract for receiving funds assets in the form of either ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/AssetReceiver.sol\":\"AssetReceiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@rari-capital/solmate/src/auth/Owned.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Simple single owner authorization mixin.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\\nabstract contract Owned {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event OwnerUpdated(address indexed user, address indexed newOwner);\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n address public owner;\\n\\n modifier onlyOwner() virtual {\\n require(msg.sender == owner, \\\"UNAUTHORIZED\\\");\\n\\n _;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(address _owner) {\\n owner = _owner;\\n\\n emit OwnerUpdated(address(0), _owner);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function setOwner(address newOwner) public virtual onlyOwner {\\n owner = newOwner;\\n\\n emit OwnerUpdated(msg.sender, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7e91c80b0dd1a14a19cb9e661b99924043adab6d9d893bbfcf3a6a3dc23a6743\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\\nabstract contract ERC20 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n uint8 public immutable decimals;\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) public balanceOf;\\n\\n mapping(address => mapping(address => uint256)) public allowance;\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 internal immutable INITIAL_CHAIN_ID;\\n\\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\\n\\n mapping(address => uint256) public nonces;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n uint8 _decimals\\n ) {\\n name = _name;\\n symbol = _symbol;\\n decimals = _decimals;\\n\\n INITIAL_CHAIN_ID = block.chainid;\\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 amount) public virtual returns (bool) {\\n allowance[msg.sender][spender] = amount;\\n\\n emit Approval(msg.sender, spender, amount);\\n\\n return true;\\n }\\n\\n function transfer(address to, uint256 amount) public virtual returns (bool) {\\n balanceOf[msg.sender] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(msg.sender, to, amount);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual returns (bool) {\\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\\n\\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\\n\\n balanceOf[from] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n return true;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(deadline >= block.timestamp, \\\"PERMIT_DEADLINE_EXPIRED\\\");\\n\\n // Unchecked because the only math done is incrementing\\n // the owner's nonce which cannot realistically overflow.\\n unchecked {\\n address recoveredAddress = ecrecover(\\n keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\",\\n DOMAIN_SEPARATOR(),\\n keccak256(\\n abi.encode(\\n keccak256(\\n \\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\"\\n ),\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n )\\n ),\\n v,\\n r,\\n s\\n );\\n\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"INVALID_SIGNER\\\");\\n\\n allowance[recoveredAddress][spender] = value;\\n }\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\\n }\\n\\n function computeDomainSeparator() internal view virtual returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name)),\\n keccak256(\\\"1\\\"),\\n block.chainid,\\n address(this)\\n )\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 amount) internal virtual {\\n totalSupply += amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(address(0), to, amount);\\n }\\n\\n function _burn(address from, uint256 amount) internal virtual {\\n balanceOf[from] -= amount;\\n\\n // Cannot underflow because a user's balance\\n // will never be larger than the total supply.\\n unchecked {\\n totalSupply -= amount;\\n }\\n\\n emit Transfer(from, address(0), amount);\\n }\\n}\\n\",\"keccak256\":\"0x0240f7703cff32a61ee3e9fbb339e09a944260432a9ef37debf3692b1a6c8049\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\\n\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE/LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n function tokenURI(uint256 id) public view virtual returns (string memory);\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 BALANCE/OWNER STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) internal _ownerOf;\\n\\n mapping(address => uint256) internal _balanceOf;\\n\\n function ownerOf(uint256 id) public view virtual returns (address owner) {\\n require((owner = _ownerOf[id]) != address(0), \\\"NOT_MINTED\\\");\\n }\\n\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n require(owner != address(0), \\\"ZERO_ADDRESS\\\");\\n\\n return _balanceOf[owner];\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 APPROVAL STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) public getApproved;\\n\\n mapping(address => mapping(address => bool)) public isApprovedForAll;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(string memory _name, string memory _symbol) {\\n name = _name;\\n symbol = _symbol;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 id) public virtual {\\n address owner = _ownerOf[id];\\n\\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \\\"NOT_AUTHORIZED\\\");\\n\\n getApproved[id] = spender;\\n\\n emit Approval(owner, spender, id);\\n }\\n\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n isApprovedForAll[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(msg.sender, operator, approved);\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n require(from == _ownerOf[id], \\\"WRONG_FROM\\\");\\n\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(\\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\\n \\\"NOT_AUTHORIZED\\\"\\n );\\n\\n // Underflow of the sender's balance is impossible because we check for\\n // ownership above and the recipient's balance can't realistically overflow.\\n unchecked {\\n _balanceOf[from]--;\\n\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n delete getApproved[id];\\n\\n emit Transfer(from, to, id);\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n bytes calldata data\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC165 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return\\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 id) internal virtual {\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(_ownerOf[id] == address(0), \\\"ALREADY_MINTED\\\");\\n\\n // Counter overflow is incredibly unrealistic.\\n unchecked {\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n emit Transfer(address(0), to, id);\\n }\\n\\n function _burn(uint256 id) internal virtual {\\n address owner = _ownerOf[id];\\n\\n require(owner != address(0), \\\"NOT_MINTED\\\");\\n\\n // Ownership check above ensures no underflow.\\n unchecked {\\n _balanceOf[owner]--;\\n }\\n\\n delete _ownerOf[id];\\n\\n delete getApproved[id];\\n\\n emit Transfer(owner, address(0), id);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL SAFE MINT LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _safeMint(address to, uint256 id) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function _safeMint(\\n address to,\\n uint256 id,\\n bytes memory data\\n ) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n}\\n\\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721TokenReceiver {\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external virtual returns (bytes4) {\\n return ERC721TokenReceiver.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0xb59c7c25eca386f39da4819a9f70f89b73b7583d5f5127a83ffe5339800b1183\",\"license\":\"AGPL-3.0-only\"},\"contracts/universal/AssetReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { ERC20 } from \\\"@rari-capital/solmate/src/tokens/ERC20.sol\\\";\\nimport { ERC721 } from \\\"@rari-capital/solmate/src/tokens/ERC721.sol\\\";\\nimport { Transactor } from \\\"./Transactor.sol\\\";\\n\\n/**\\n * @title AssetReceiver\\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\\n */\\ncontract AssetReceiver is Transactor {\\n /**\\n * Emitted when ETH is received by this address.\\n */\\n event ReceivedETH(address indexed from, uint256 amount);\\n\\n /**\\n * Emitted when ETH is withdrawn from this address.\\n */\\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\\n\\n /**\\n * Emitted when ERC20 tokens are withdrawn from this address.\\n */\\n event WithdrewERC20(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 amount\\n );\\n\\n /**\\n * Emitted when ERC721 tokens are withdrawn from this address.\\n */\\n event WithdrewERC721(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 id\\n );\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Transactor(_owner) {}\\n\\n /**\\n * Make sure we can receive ETH.\\n */\\n receive() external payable {\\n emit ReceivedETH(msg.sender, msg.value);\\n }\\n\\n /**\\n * Withdraws full ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n */\\n function withdrawETH(address payable _to) external onlyOwner {\\n withdrawETH(_to, address(this).balance);\\n }\\n\\n /**\\n * Withdraws partial ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n * @param _amount Amount of ETH to withdraw.\\n */\\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\\n // slither-disable-next-line reentrancy-unlimited-gas\\n _to.transfer(_amount);\\n emit WithdrewETH(msg.sender, _to, _amount);\\n }\\n\\n /**\\n * Withdraws full ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n */\\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\\n }\\n\\n /**\\n * Withdraws partial ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n * @param _amount Amount of ERC20 to withdraw.\\n */\\n function withdrawERC20(\\n ERC20 _asset,\\n address _to,\\n uint256 _amount\\n ) public onlyOwner {\\n // slither-disable-next-line unchecked-transfer\\n _asset.transfer(_to, _amount);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\\n }\\n\\n /**\\n * Withdraws ERC721 token to the recipient.\\n *\\n * @param _asset ERC721 token to withdraw.\\n * @param _to Address to receive the ERC721 token.\\n * @param _id Token ID of the ERC721 token to withdraw.\\n */\\n function withdrawERC721(\\n ERC721 _asset,\\n address _to,\\n uint256 _id\\n ) external onlyOwner {\\n _asset.transferFrom(address(this), _to, _id);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\\n }\\n}\\n\",\"keccak256\":\"0x1f82aff6f4e5a4bebebbfb4a2e0e4378ef9bc5bee8b81f88b27fc0ce73546d5f\",\"license\":\"MIT\"},\"contracts/universal/Transactor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { Owned } from \\\"@rari-capital/solmate/src/auth/Owned.sol\\\";\\n\\n/**\\n * @title Transactor\\n * @notice Transactor is a minimal contract that can send transactions.\\n */\\ncontract Transactor is Owned {\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Owned(_owner) {}\\n\\n /**\\n * Sends a CALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @param _value ETH value to send with the call.\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function CALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas,\\n uint256 _value\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n return _target.call{ gas: _gas, value: _value }(_data);\\n }\\n\\n /**\\n * Sends a DELEGATECALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function DELEGATECALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n // slither-disable-next-line controlled-delegatecall\\n return _target.delegatecall{ gas: _gas }(_data);\\n }\\n}\\n\",\"keccak256\":\"0xfe0d9c05a423d36775047e3285f76b874f8b887444d412a0d680c302c3b06a50\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50604051610f6e380380610f6e83398101604081905261002f91610081565b600080546001600160a01b0319166001600160a01b038316908117825560405183928392917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908290a35050506100b1565b60006020828403121561009357600080fd5b81516001600160a01b03811681146100aa57600080fd5b9392505050565b610eae806100c06000396000f3fe60806040526004361061009a5760003560e01c80635cef8b4a116100695780638da5cb5b1161004e5780638da5cb5b146101a75780639456fbcc146101f95780639e73dbea1461021957600080fd5b80635cef8b4a1461015d578063690d83201461018757600080fd5b806313af4035146100db5780634025feb2146100fd57806344004cc11461011d5780634782f7791461013d57600080fd5b366100d65760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b3480156100e757600080fd5b506100fb6100f6366004610b3a565b61022c565b005b34801561010957600080fd5b506100fb610118366004610b5e565b610322565b34801561012957600080fd5b506100fb610138366004610b5e565b6104b4565b34801561014957600080fd5b506100fb610158366004610b9f565b610654565b61017061016b366004610ca5565b61076a565b60405161017e929190610d2e565b60405180910390f35b34801561019357600080fd5b506100fb6101a2366004610b3a565b610863565b3480156101b357600080fd5b506000546101d49073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161017e565b34801561020557600080fd5b506100fb610214366004610d88565b6108f1565b610170610227366004610dc1565b610a1b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561041957600080fd5b505af115801561042d573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8846040516104a791815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b1580156105a557600080fd5b505af11580156105b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105dd9190610e21565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa846040516104a791815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610718573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8473ffffffffffffffffffffffffffffffffffffffff1683856040516108159190610e43565b6000604051808303818686f4925050503d8060008114610851576040519150601f19603f3d011682016040523d82523d6000602084013e610856565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6108ee8147610654565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610a17908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101389190610e5f565b5050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610aa0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8573ffffffffffffffffffffffffffffffffffffffff16848487604051610ac79190610e43565b600060405180830381858888f193505050503d8060008114610b05576040519150601f19603f3d011682016040523d82523d6000602084013e610b0a565b606091505b509150915094509492505050565b73ffffffffffffffffffffffffffffffffffffffff811681146108ee57600080fd5b600060208284031215610b4c57600080fd5b8135610b5781610b18565b9392505050565b600080600060608486031215610b7357600080fd5b8335610b7e81610b18565b92506020840135610b8e81610b18565b929592945050506040919091013590565b60008060408385031215610bb257600080fd5b8235610bbd81610b18565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610c0b57600080fd5b813567ffffffffffffffff80821115610c2657610c26610bcb565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610c6c57610c6c610bcb565b81604052838152866020858801011115610c8557600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215610cba57600080fd5b8335610cc581610b18565b9250602084013567ffffffffffffffff811115610ce157600080fd5b610ced86828701610bfa565b925050604084013590509250925092565b60005b83811015610d19578181015183820152602001610d01565b83811115610d28576000848401525b50505050565b82151581526040602082015260008251806040840152610d55816060850160208701610cfe565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b60008060408385031215610d9b57600080fd5b8235610da681610b18565b91506020830135610db681610b18565b809150509250929050565b60008060008060808587031215610dd757600080fd5b8435610de281610b18565b9350602085013567ffffffffffffffff811115610dfe57600080fd5b610e0a87828801610bfa565b949794965050505060408301359260600135919050565b600060208284031215610e3357600080fd5b81518015158114610b5757600080fd5b60008251610e55818460208701610cfe565b9190910192915050565b600060208284031215610e7157600080fd5b505191905056fea2646970667358221220a79fda18860baa011a378f2e4963a1c9eb8fa5184c5fd3130308ce3c35ba96da64736f6c63430008090033", - "deployedBytecode": "0x60806040526004361061009a5760003560e01c80635cef8b4a116100695780638da5cb5b1161004e5780638da5cb5b146101a75780639456fbcc146101f95780639e73dbea1461021957600080fd5b80635cef8b4a1461015d578063690d83201461018757600080fd5b806313af4035146100db5780634025feb2146100fd57806344004cc11461011d5780634782f7791461013d57600080fd5b366100d65760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b3480156100e757600080fd5b506100fb6100f6366004610b3a565b61022c565b005b34801561010957600080fd5b506100fb610118366004610b5e565b610322565b34801561012957600080fd5b506100fb610138366004610b5e565b6104b4565b34801561014957600080fd5b506100fb610158366004610b9f565b610654565b61017061016b366004610ca5565b61076a565b60405161017e929190610d2e565b60405180910390f35b34801561019357600080fd5b506100fb6101a2366004610b3a565b610863565b3480156101b357600080fd5b506000546101d49073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161017e565b34801561020557600080fd5b506100fb610214366004610d88565b6108f1565b610170610227366004610dc1565b610a1b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561041957600080fd5b505af115801561042d573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8846040516104a791815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b1580156105a557600080fd5b505af11580156105b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105dd9190610e21565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa846040516104a791815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610718573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8473ffffffffffffffffffffffffffffffffffffffff1683856040516108159190610e43565b6000604051808303818686f4925050503d8060008114610851576040519150601f19603f3d011682016040523d82523d6000602084013e610856565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6108ee8147610654565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610a17908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101389190610e5f565b5050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610aa0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8573ffffffffffffffffffffffffffffffffffffffff16848487604051610ac79190610e43565b600060405180830381858888f193505050503d8060008114610b05576040519150601f19603f3d011682016040523d82523d6000602084013e610b0a565b606091505b509150915094509492505050565b73ffffffffffffffffffffffffffffffffffffffff811681146108ee57600080fd5b600060208284031215610b4c57600080fd5b8135610b5781610b18565b9392505050565b600080600060608486031215610b7357600080fd5b8335610b7e81610b18565b92506020840135610b8e81610b18565b929592945050506040919091013590565b60008060408385031215610bb257600080fd5b8235610bbd81610b18565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610c0b57600080fd5b813567ffffffffffffffff80821115610c2657610c26610bcb565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610c6c57610c6c610bcb565b81604052838152866020858801011115610c8557600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215610cba57600080fd5b8335610cc581610b18565b9250602084013567ffffffffffffffff811115610ce157600080fd5b610ced86828701610bfa565b925050604084013590509250925092565b60005b83811015610d19578181015183820152602001610d01565b83811115610d28576000848401525b50505050565b82151581526040602082015260008251806040840152610d55816060850160208701610cfe565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b60008060408385031215610d9b57600080fd5b8235610da681610b18565b91506020830135610db681610b18565b809150509250929050565b60008060008060808587031215610dd757600080fd5b8435610de281610b18565b9350602085013567ffffffffffffffff811115610dfe57600080fd5b610e0a87828801610bfa565b949794965050505060408301359260600135919050565b600060208284031215610e3357600080fd5b81518015158114610b5757600080fd5b60008251610e55818460208701610cfe565b9190910192915050565b600060208284031215610e7157600080fd5b505191905056fea2646970667358221220a79fda18860baa011a378f2e4963a1c9eb8fa5184c5fd3130308ce3c35ba96da64736f6c63430008090033", - "devdoc": { - "kind": "dev", - "methods": { - "CALL(address,bytes,uint256,uint256)": { - "params": { - "_data": "Data to send with the call.", - "_gas": "Amount of gas to send with the call.", - "_target": "Address to call.", - "_value": "ETH value to send with the call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "DELEGATECALL(address,bytes,uint256)": { - "params": { - "_data": "Data to send with the call.", - "_gas": "Amount of gas to send with the call.", - "_target": "Address to call." - }, - "returns": { - "_0": "Boolean success value.", - "_1": "Bytes data returned by the call." - } - }, - "constructor": { - "params": { - "_owner": "Initial contract owner." - } - }, - "withdrawERC20(address,address)": { - "params": { - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC20(address,address,uint256)": { - "params": { - "_amount": "Amount of ERC20 to withdraw.", - "_asset": "ERC20 token to withdraw.", - "_to": "Address to receive the ERC20 balance." - } - }, - "withdrawERC721(address,address,uint256)": { - "params": { - "_asset": "ERC721 token to withdraw.", - "_id": "Token ID of the ERC721 token to withdraw.", - "_to": "Address to receive the ERC721 token." - } - }, - "withdrawETH(address)": { - "params": { - "_to": "Address to receive the ETH balance." - } - }, - "withdrawETH(address,uint256)": { - "params": { - "_amount": "Amount of ETH to withdraw.", - "_to": "Address to receive the ETH balance." - } - } - }, - "title": "AssetReceiver", - "version": 1 - }, - "userdoc": { - "events": { - "ReceivedETH(address,uint256)": { - "notice": "Emitted when ETH is received by this address." - }, - "WithdrewERC20(address,address,address,uint256)": { - "notice": "Emitted when ERC20 tokens are withdrawn from this address." - }, - "WithdrewERC721(address,address,address,uint256)": { - "notice": "Emitted when ERC721 tokens are withdrawn from this address." - }, - "WithdrewETH(address,address,uint256)": { - "notice": "Emitted when ETH is withdrawn from this address." - } - }, - "kind": "user", - "methods": { - "CALL(address,bytes,uint256,uint256)": { - "notice": "Sends a CALL to a target address." - }, - "DELEGATECALL(address,bytes,uint256)": { - "notice": "Sends a DELEGATECALL to a target address." - }, - "withdrawERC20(address,address)": { - "notice": "Withdraws full ERC20 balance to the recipient." - }, - "withdrawERC20(address,address,uint256)": { - "notice": "Withdraws partial ERC20 balance to the recipient." - }, - "withdrawERC721(address,address,uint256)": { - "notice": "Withdraws ERC721 token to the recipient." - }, - "withdrawETH(address)": { - "notice": "Withdraws full ETH balance to the recipient." - }, - "withdrawETH(address,uint256)": { - "notice": "Withdraws partial ETH balance to the recipient." - } - }, - "notice": "AssetReceiver is a minimal contract for receiving funds assets in the form of either ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 10, - "contract": "contracts/universal/AssetReceiver.sol:AssetReceiver", - "label": "owner", - "offset": 0, - "slot": "0", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/AttestationStation.json b/packages/contracts-bedrock/deployments/optimism-mainnet/AttestationStation.json deleted file mode 100644 index 550f3107c92a..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/AttestationStation.json +++ /dev/null @@ -1,270 +0,0 @@ -{ - "address": "0xbeD744818e96AAD8a51324291a6f6Cb20A0c22be", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "creator", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "about", - "type": "address" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "key", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "val", - "type": "bytes" - } - ], - "name": "AttestationCreated", - "type": "event" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "about", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "key", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "val", - "type": "bytes" - } - ], - "internalType": "struct AttestationStation.AttestationData[]", - "name": "_attestations", - "type": "tuple[]" - } - ], - "name": "attest", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_about", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_key", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "_val", - "type": "bytes" - } - ], - "name": "attest", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "attestations", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x0272013b1d20b4b8e2b8153867389c1c75cbbd5c50e564ee71a62dbfcc35f062", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x956a5152D0f498dBA0c5966577bb44262F8F7078", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "666309", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x6d539badaadce9732f2f79e1ceaee94499dd0003d42862324ff334bd7e7e6e68", - "transactionHash": "0x0272013b1d20b4b8e2b8153867389c1c75cbbd5c50e564ee71a62dbfcc35f062", - "logs": [], - "blockNumber": 70643992, - "cumulativeGasUsed": "666309", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 2, - "solcInputHash": "3aa2ad7d005d9515a1f12df8da17d178", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"name\":\"AttestationCreated\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"about\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"val\",\"type\":\"bytes\"}],\"internalType\":\"struct AttestationStation.AttestationData[]\",\"name\":\"_attestations\",\"type\":\"tuple[]\"}],\"name\":\"attest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_about\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_val\",\"type\":\"bytes\"}],\"name\":\"attest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"attestations\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Optimism CollectiveGitcoin\",\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"params\":{\"about\":\"Address attestation is about.\",\"creator\":\"Address that made the attestation.\",\"key\":\"Key of the attestation.\",\"val\":\"Value of the attestation.\"}}},\"kind\":\"dev\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"params\":{\"_attestations\":\"An array of attestation data.\"}},\"attest(address,bytes32,bytes)\":{\"params\":{\"_about\":\"Address that the attestation is about.\",\"_key\":\"A key used to namespace the attestation.\",\"_val\":\"An arbitrary value stored as part of the attestation.\"}},\"constructor\":{\"custom:semver\":\"1.1.0\"},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"AttestationStation\",\"version\":1},\"userdoc\":{\"events\":{\"AttestationCreated(address,address,bytes32,bytes)\":{\"notice\":\"Emitted when Attestation is created.\"}},\"kind\":\"user\",\"methods\":{\"attest((address,bytes32,bytes)[])\":{\"notice\":\"Allows anyone to create attestations.\"},\"attest(address,bytes32,bytes)\":{\"notice\":\"Allows anyone to create an attestation.\"},\"attestations(address,address,bytes32)\":{\"notice\":\"Maps addresses to attestations. Creator => About => Key => Value.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Where attestations live.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/AttestationStation.sol\":\"AttestationStation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.15;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x979b13465de4996a1105850abbf48abe7f71d5e18a8d4af318597ee14c165fdf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of attestation data.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x80718fdc09061ea8f8b99a0b846eee46c5a2a1372dbb0cbc3d40953cb3af19e0\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60e060405234801561001057600080fd5b506001608081905260a052600060c05260805160a05160c051610b1c61004f60003960006101ad015260006101840152600061015b0152610b1c6000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806329b42cb51461005157806354fd4d501461007a5780635eb5ea1014610082578063702b9dee14610097575b600080fd5b61006461005f36600461046c565b6100aa565b604051610071919061051e565b60405180910390f35b610064610154565b610095610090366004610538565b6101f7565b005b6100956100a5366004610687565b61025a565b60006020818152938152604080822085529281528281209093528252902080546100d3906106de565b80601f01602080910402602001604051908101604052809291908181526020018280546100ff906106de565b801561014c5780601f106101215761010080835404028352916020019161014c565b820191906000526020600020905b81548152906001019060200180831161012f57829003601f168201915b505050505081565b606061017f7f0000000000000000000000000000000000000000000000000000000000000000610306565b6101a87f0000000000000000000000000000000000000000000000000000000000000000610306565b6101d17f0000000000000000000000000000000000000000000000000000000000000000610306565b6040516020016101e393929190610731565b604051602081830303815290604052905090565b8060005b81811015610254576000848483818110610217576102176107a7565b905060200281019061022991906107d6565b61023290610814565b905061024b81600001518260200151836040015161025a565b506001016101fb565b50505050565b3360009081526020818152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320858452909152902061029a82826108df565b50818373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85846040516102f9919061051e565b60405180910390a4505050565b60608160000361034957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610373578061035d81610a28565b915061036c9050600a83610a8f565b915061034d565b60008167ffffffffffffffff81111561038e5761038e6105ad565b6040519080825280601f01601f1916602001820160405280156103b8576020820181803683370190505b5090505b841561043b576103cd600183610aa3565b91506103da600a86610aba565b6103e5906030610ace565b60f81b8183815181106103fa576103fa6107a7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610434600a86610a8f565b94506103bc565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461046757600080fd5b919050565b60008060006060848603121561048157600080fd5b61048a84610443565b925061049860208501610443565b9150604084013590509250925092565b60005b838110156104c35781810151838201526020016104ab565b838111156102545750506000910152565b600081518084526104ec8160208601602086016104a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061053160208301846104d4565b9392505050565b6000806020838503121561054b57600080fd5b823567ffffffffffffffff8082111561056357600080fd5b818501915085601f83011261057757600080fd5b81358181111561058657600080fd5b8660208260051b850101111561059b57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126105ed57600080fd5b813567ffffffffffffffff80821115610608576106086105ad565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561064e5761064e6105ad565b8160405283815286602085880101111561066757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561069c57600080fd5b6106a584610443565b925060208401359150604084013567ffffffffffffffff8111156106c857600080fd5b6106d4868287016105dc565b9150509250925092565b600181811c908216806106f257607f821691505b60208210810361072b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516107438184602089016104a8565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161077f816001850160208a016104a8565b6001920191820152835161079a8160028401602088016104a8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261080a57600080fd5b9190910192915050565b60006060823603121561082657600080fd5b6040516060810167ffffffffffffffff828210818311171561084a5761084a6105ad565b8160405261085785610443565b835260208501356020840152604085013591508082111561087757600080fd5b50610884368286016105dc565b60408301525092915050565b601f8211156108da57600081815260208120601f850160051c810160208610156108b75750805b601f850160051c820191505b818110156108d6578281556001016108c3565b5050505b505050565b815167ffffffffffffffff8111156108f9576108f96105ad565b61090d8161090784546106de565b84610890565b602080601f831160018114610960576000841561092a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556108d6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156109ad5788860151825594840194600190910190840161098e565b50858210156109e957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a5957610a596109f9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a9e57610a9e610a60565b500490565b600082821015610ab557610ab56109f9565b500390565b600082610ac957610ac9610a60565b500690565b60008219821115610ae157610ae16109f9565b50019056fea2646970667358221220bfd4abacc1c2510682b093eea8745255cdd9f45c5b16c168540522a65ddc1f3264736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806329b42cb51461005157806354fd4d501461007a5780635eb5ea1014610082578063702b9dee14610097575b600080fd5b61006461005f36600461046c565b6100aa565b604051610071919061051e565b60405180910390f35b610064610154565b610095610090366004610538565b6101f7565b005b6100956100a5366004610687565b61025a565b60006020818152938152604080822085529281528281209093528252902080546100d3906106de565b80601f01602080910402602001604051908101604052809291908181526020018280546100ff906106de565b801561014c5780601f106101215761010080835404028352916020019161014c565b820191906000526020600020905b81548152906001019060200180831161012f57829003601f168201915b505050505081565b606061017f7f0000000000000000000000000000000000000000000000000000000000000000610306565b6101a87f0000000000000000000000000000000000000000000000000000000000000000610306565b6101d17f0000000000000000000000000000000000000000000000000000000000000000610306565b6040516020016101e393929190610731565b604051602081830303815290604052905090565b8060005b81811015610254576000848483818110610217576102176107a7565b905060200281019061022991906107d6565b61023290610814565b905061024b81600001518260200151836040015161025a565b506001016101fb565b50505050565b3360009081526020818152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320858452909152902061029a82826108df565b50818373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85846040516102f9919061051e565b60405180910390a4505050565b60608160000361034957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610373578061035d81610a28565b915061036c9050600a83610a8f565b915061034d565b60008167ffffffffffffffff81111561038e5761038e6105ad565b6040519080825280601f01601f1916602001820160405280156103b8576020820181803683370190505b5090505b841561043b576103cd600183610aa3565b91506103da600a86610aba565b6103e5906030610ace565b60f81b8183815181106103fa576103fa6107a7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610434600a86610a8f565b94506103bc565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461046757600080fd5b919050565b60008060006060848603121561048157600080fd5b61048a84610443565b925061049860208501610443565b9150604084013590509250925092565b60005b838110156104c35781810151838201526020016104ab565b838111156102545750506000910152565b600081518084526104ec8160208601602086016104a8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061053160208301846104d4565b9392505050565b6000806020838503121561054b57600080fd5b823567ffffffffffffffff8082111561056357600080fd5b818501915085601f83011261057757600080fd5b81358181111561058657600080fd5b8660208260051b850101111561059b57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126105ed57600080fd5b813567ffffffffffffffff80821115610608576106086105ad565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561064e5761064e6105ad565b8160405283815286602085880101111561066757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561069c57600080fd5b6106a584610443565b925060208401359150604084013567ffffffffffffffff8111156106c857600080fd5b6106d4868287016105dc565b9150509250925092565b600181811c908216806106f257607f821691505b60208210810361072b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516107438184602089016104a8565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161077f816001850160208a016104a8565b6001920191820152835161079a8160028401602088016104a8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261080a57600080fd5b9190910192915050565b60006060823603121561082657600080fd5b6040516060810167ffffffffffffffff828210818311171561084a5761084a6105ad565b8160405261085785610443565b835260208501356020840152604085013591508082111561087757600080fd5b50610884368286016105dc565b60408301525092915050565b601f8211156108da57600081815260208120601f850160051c810160208610156108b75750805b601f850160051c820191505b818110156108d6578281556001016108c3565b5050505b505050565b815167ffffffffffffffff8111156108f9576108f96105ad565b61090d8161090784546106de565b84610890565b602080601f831160018114610960576000841561092a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556108d6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156109ad5788860151825594840194600190910190840161098e565b50858210156109e957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a5957610a596109f9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a9e57610a9e610a60565b500490565b600082821015610ab557610ab56109f9565b500390565b600082610ac957610ac9610a60565b500690565b60008219821115610ae157610ae16109f9565b50019056fea2646970667358221220bfd4abacc1c2510682b093eea8745255cdd9f45c5b16c168540522a65ddc1f3264736f6c634300080f0033", - "devdoc": { - "author": "Optimism CollectiveGitcoin", - "events": { - "AttestationCreated(address,address,bytes32,bytes)": { - "params": { - "about": "Address attestation is about.", - "creator": "Address that made the attestation.", - "key": "Key of the attestation.", - "val": "Value of the attestation." - } - } - }, - "kind": "dev", - "methods": { - "attest((address,bytes32,bytes)[])": { - "params": { - "_attestations": "An array of attestation data." - } - }, - "attest(address,bytes32,bytes)": { - "params": { - "_about": "Address that the attestation is about.", - "_key": "A key used to namespace the attestation.", - "_val": "An arbitrary value stored as part of the attestation." - } - }, - "constructor": { - "custom:semver": "1.1.0" - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "AttestationStation", - "version": 1 - }, - "userdoc": { - "events": { - "AttestationCreated(address,address,bytes32,bytes)": { - "notice": "Emitted when Attestation is created." - } - }, - "kind": "user", - "methods": { - "attest((address,bytes32,bytes)[])": { - "notice": "Allows anyone to create attestations." - }, - "attest(address,bytes32,bytes)": { - "notice": "Allows anyone to create an attestation." - }, - "attestations(address,address,bytes32)": { - "notice": "Maps addresses to attestations. Creator => About => Key => Value." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "Where attestations live.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 2135, - "contract": "contracts/universal/op-nft/AttestationStation.sol:AttestationStation", - "label": "attestations", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_address,t_mapping(t_address,t_mapping(t_bytes32,t_bytes_storage)))" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "encoding": "bytes", - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_address,t_mapping(t_bytes32,t_bytes_storage)))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => mapping(bytes32 => bytes)))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_mapping(t_bytes32,t_bytes_storage))" - }, - "t_mapping(t_address,t_mapping(t_bytes32,t_bytes_storage))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(bytes32 => bytes))", - "numberOfBytes": "32", - "value": "t_mapping(t_bytes32,t_bytes_storage)" - }, - "t_mapping(t_bytes32,t_bytes_storage)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bytes)", - "numberOfBytes": "32", - "value": "t_bytes_storage" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/AttestationStationProxy.json b/packages/contracts-bedrock/deployments/optimism-mainnet/AttestationStationProxy.json deleted file mode 100644 index b9b59ffc2858..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/AttestationStationProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0xddf8785bc33a64924409c4588a7664b210c469c6a658ae36ef106a4ed6c324ca", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "534190", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000008000000000000000000000000", - "blockHash": "0x59216851b5a511cd84c75a7b796ca0f23331bc52c92085d4a5921061428b82f6", - "transactionHash": "0xddf8785bc33a64924409c4588a7664b210c469c6a658ae36ef106a4ed6c324ca", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 49669971, - "transactionHash": "0xddf8785bc33a64924409c4588a7664b210c469c6a658ae36ef106a4ed6c324ca", - "address": "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58", - "logIndex": 0, - "blockHash": "0x59216851b5a511cd84c75a7b796ca0f23331bc52c92085d4a5921061428b82f6" - } - ], - "blockNumber": 49669971, - "cumulativeGasUsed": "534190", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "45837d34ff24b9cb2ae34232b60ea874", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n external\\n payable\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() external proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() external proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/EAS.json b/packages/contracts-bedrock/deployments/optimism-mainnet/EAS.json deleted file mode 100644 index 0964371988a0..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/EAS.json +++ /dev/null @@ -1,1534 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "AccessDenied", - "type": "error" - }, - { - "inputs": [], - "name": "AlreadyRevoked", - "type": "error" - }, - { - "inputs": [], - "name": "AlreadyRevokedOffchain", - "type": "error" - }, - { - "inputs": [], - "name": "AlreadyTimestamped", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientValue", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidAttestation", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidAttestations", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidExpirationTime", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidLength", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidOffset", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRegistry", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRevocation", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRevocations", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidSchema", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidSignature", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidVerifier", - "type": "error" - }, - { - "inputs": [], - "name": "Irrevocable", - "type": "error" - }, - { - "inputs": [], - "name": "NotFound", - "type": "error" - }, - { - "inputs": [], - "name": "NotPayable", - "type": "error" - }, - { - "inputs": [], - "name": "WrongSchema", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "attester", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - } - ], - "name": "Attested", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "attester", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - } - ], - "name": "Revoked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "revoker", - "type": "address" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint64", - "name": "timestamp", - "type": "uint64" - } - ], - "name": "RevokedOffchain", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint64", - "name": "timestamp", - "type": "uint64" - } - ], - "name": "Timestamped", - "type": "event" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint64", - "name": "expirationTime", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "bytes32", - "name": "refUID", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct AttestationRequestData", - "name": "data", - "type": "tuple" - } - ], - "internalType": "struct AttestationRequest", - "name": "request", - "type": "tuple" - } - ], - "name": "attest", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint64", - "name": "expirationTime", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "bytes32", - "name": "refUID", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct AttestationRequestData", - "name": "data", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "internalType": "struct EIP712Signature", - "name": "signature", - "type": "tuple" - }, - { - "internalType": "address", - "name": "attester", - "type": "address" - } - ], - "internalType": "struct DelegatedAttestationRequest", - "name": "delegatedRequest", - "type": "tuple" - } - ], - "name": "attestByDelegation", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "getAttestTypeHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - } - ], - "name": "getAttestation", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "time", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "expirationTime", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "revocationTime", - "type": "uint64" - }, - { - "internalType": "bytes32", - "name": "refUID", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "address", - "name": "attester", - "type": "address" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "internalType": "struct Attestation", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getDomainSeparator", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getName", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "getNonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "revoker", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - } - ], - "name": "getRevokeOffchain", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getRevokeTypeHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "getSchemaRegistry", - "outputs": [ - { - "internalType": "contract ISchemaRegistry", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - } - ], - "name": "getTimestamp", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - } - ], - "name": "isAttestationValid", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint64", - "name": "expirationTime", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "bytes32", - "name": "refUID", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct AttestationRequestData[]", - "name": "data", - "type": "tuple[]" - } - ], - "internalType": "struct MultiAttestationRequest[]", - "name": "multiRequests", - "type": "tuple[]" - } - ], - "name": "multiAttest", - "outputs": [ - { - "internalType": "bytes32[]", - "name": "", - "type": "bytes32[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint64", - "name": "expirationTime", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "bytes32", - "name": "refUID", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct AttestationRequestData[]", - "name": "data", - "type": "tuple[]" - }, - { - "components": [ - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "internalType": "struct EIP712Signature[]", - "name": "signatures", - "type": "tuple[]" - }, - { - "internalType": "address", - "name": "attester", - "type": "address" - } - ], - "internalType": "struct MultiDelegatedAttestationRequest[]", - "name": "multiDelegatedRequests", - "type": "tuple[]" - } - ], - "name": "multiAttestByDelegation", - "outputs": [ - { - "internalType": "bytes32[]", - "name": "", - "type": "bytes32[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct RevocationRequestData[]", - "name": "data", - "type": "tuple[]" - } - ], - "internalType": "struct MultiRevocationRequest[]", - "name": "multiRequests", - "type": "tuple[]" - } - ], - "name": "multiRevoke", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct RevocationRequestData[]", - "name": "data", - "type": "tuple[]" - }, - { - "components": [ - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "internalType": "struct EIP712Signature[]", - "name": "signatures", - "type": "tuple[]" - }, - { - "internalType": "address", - "name": "revoker", - "type": "address" - } - ], - "internalType": "struct MultiDelegatedRevocationRequest[]", - "name": "multiDelegatedRequests", - "type": "tuple[]" - } - ], - "name": "multiRevokeByDelegation", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32[]", - "name": "data", - "type": "bytes32[]" - } - ], - "name": "multiRevokeOffchain", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32[]", - "name": "data", - "type": "bytes32[]" - } - ], - "name": "multiTimestamp", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct RevocationRequestData", - "name": "data", - "type": "tuple" - } - ], - "internalType": "struct RevocationRequest", - "name": "request", - "type": "tuple" - } - ], - "name": "revoke", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "schema", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "internalType": "struct RevocationRequestData", - "name": "data", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "internalType": "struct EIP712Signature", - "name": "signature", - "type": "tuple" - }, - { - "internalType": "address", - "name": "revoker", - "type": "address" - } - ], - "internalType": "struct DelegatedRevocationRequest", - "name": "delegatedRequest", - "type": "tuple" - } - ], - "name": "revokeByDelegation", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - } - ], - "name": "revokeOffchain", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "data", - "type": "bytes32" - } - ], - "name": "timestamp", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x4E0275Ea5a89e7a3c1B58411379D1a0eDdc5b088", - "args": [], - "bytecode": "0x6101c06040523480156200001257600080fd5b50604080518082018252600381526245415360e81b602080830191825283518085019094526005845264312e302e3160d81b90840190815260016080819052600060a05260c052825190912083519091206101408290526101608190524661010052919291839183917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ec8184846040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b60e0523061012052610180525050505060208201516101a052506200010e9050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516144df6200018a60003960006105410152600061265b015260006126aa01526000612685015260006125de0152600061260801526000612632015260006108730152600061084a0152600061082101526144df6000f3fe6080604052600436106101805760003560e01c8063b469318d116100d6578063e45d03f91161007f578063ed24911d11610059578063ed24911d1461049e578063f10b5cc8146104b3578063f17325e7146104e257600080fd5b8063e45d03f914610458578063e57a6b1b1461046b578063e71ff3651461047e57600080fd5b8063d45c4435116100b0578063d45c4435146103cf578063e13458fc14610406578063e30bb5631461041957600080fd5b8063b469318d14610322578063b83010d31461037c578063cf190f34146103af57600080fd5b8063469262671161013857806354fd4d501161011257806354fd4d50146102cd578063831e05a1146102e2578063a3112a64146102f557600080fd5b806346926267146102855780634cb7e9e51461029a5780634d003070146102ad57600080fd5b806317d7de7c1161016957806317d7de7c146102005780632d0335ab1461022257806344adc90e1461026557600080fd5b806312b11a171461018557806313893f61146101c7575b600080fd5b34801561019157600080fd5b507fdbfdf8dc2b135c26253e00d5b6cbe6f20457e003fd526d97cea183883570de615b6040519081526020015b60405180910390f35b3480156101d357600080fd5b506101e76101e23660046133ee565b6104f5565b60405167ffffffffffffffff90911681526020016101be565b34801561020c57600080fd5b5061021561053a565b6040516101be919061349e565b34801561022e57600080fd5b506101b461023d3660046134ea565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6102786102733660046133ee565b61056a565b6040516101be9190613507565b61029861029336600461354b565b6106a1565b005b6102986102a83660046133ee565b610725565b3480156102b957600080fd5b506101e76102c8366004613563565b61080d565b3480156102d957600080fd5b5061021561081a565b6102786102f03660046133ee565b6108bd565b34801561030157600080fd5b50610315610310366004613563565b610b0e565b6040516101be9190613663565b34801561032e57600080fd5b506101e761033d366004613676565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561038857600080fd5b507fa98d02348410c9c76735e0d0bb1396f4015ac2bb9615f9c2611d19d7a8a996506101b4565b3480156103bb57600080fd5b506101e76103ca366004613563565b610cd1565b3480156103db57600080fd5b506101e76103ea366004613563565b60009081526033602052604090205467ffffffffffffffff1690565b6101b46104143660046136a2565b610cdf565b34801561042557600080fd5b50610448610434366004613563565b600090815260326020526040902054151590565b60405190151581526020016101be565b6102986104663660046133ee565b610de2565b6102986104793660046136dd565b610f5d565b34801561048a57600080fd5b506101e76104993660046133ee565b611002565b3480156104aa57600080fd5b506101b461103a565b3480156104bf57600080fd5b5060405173420000000000000000000000000000000000002081526020016101be565b6101b46104f03660046136ef565b611044565b60004282825b8181101561052e57610526338787848181106105195761051961372a565b9050602002013585611102565b6001016104fb565b50909150505b92915050565b60606105657f0000000000000000000000000000000000000000000000000000000000000000611201565b905090565b606060008267ffffffffffffffff81111561058757610587613759565b6040519080825280602002602001820160405280156105ba57816020015b60608152602001906001900390816105a55790505b509050600034815b8581101561068c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86018114368888848181106106025761060261372a565b90506020028101906106149190613788565b9050600061063b823561062a60208501856137c6565b61063391613a3f565b33888761138f565b805190915061064a9086613ae2565b945080602001518785815181106106635761066361372a565b6020026020010181905250806020015151860195505050506106858160010190565b90506105c2565b506106978383611aa1565b9695505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816106b85790505090506106f336839003830160208401613b44565b816000815181106107065761070661372a565b602090810291909101015261072082358233346001611b6e565b505050565b3460005b82811015610807577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83018114368585848181106107695761076961372a565b905060200281019061077b9190613788565b90506107e8813561078f6020840184613b60565b808060200260200160405190810160405280939291908181526020016000905b828210156107db576107cc60408302860136819003810190613b44565b815260200190600101906107af565b5050505050338786611b6e565b6107f29085613ae2565b935050506108008160010190565b9050610729565b50505050565b60004261053483826121a8565b60606108457f000000000000000000000000000000000000000000000000000000000000000061226a565b61086e7f000000000000000000000000000000000000000000000000000000000000000061226a565b6108977f000000000000000000000000000000000000000000000000000000000000000061226a565b6040516020016108a993929190613bc8565b604051602081830303815290604052905090565b606060008267ffffffffffffffff8111156108da576108da613759565b60405190808252806020026020018201604052801561090d57816020015b60608152602001906001900390816108f85790505b509050600034815b8581101561068c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86018114368888848181106109555761095561372a565b90506020028101906109679190613c3e565b905036600061097960208401846137c6565b909250905080158061099957506109936040840184613c72565b82141590505b156109d0576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610a9257610a8a604051806080016040528086600001358152602001858585818110610a0557610a0561372a565b9050602002810190610a179190613cd9565b610a2090613d0d565b8152602001610a326040880188613c72565b85818110610a4257610a4261372a565b905060600201803603810190610a589190613d84565b8152602001610a6d60808801606089016134ea565b73ffffffffffffffffffffffffffffffffffffffff1690526123a7565b6001016109d3565b506000610abb8435610aa48486613a3f565b610ab460808801606089016134ea565b8a8961138f565b8051909150610aca9088613ae2565b96508060200151898781518110610ae357610ae361372a565b6020026020010181905250806020015151880197505050505050610b078160010190565b9050610915565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610c4890613da0565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7490613da0565b8015610cc15780601f10610c9657610100808354040283529160200191610cc1565b820191906000526020600020905b815481529060010190602001808311610ca457829003601f168201915b5050505050815250509050919050565b600042610534338483611102565b6000610cf2610ced83613ded565b6123a7565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610d09579050509050610d776020840184613cd9565b610d8090613d0d565b81600081518110610d9357610d9361372a565b6020908102919091010152610dbc833582610db460c0870160a088016134ea565b34600161138f565b60200151600081518110610dd257610dd261372a565b6020026020010151915050919050565b3460005b82811015610807577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830181146000858584818110610e2757610e2761372a565b9050602002810190610e399190613c3e565b610e4290613ed2565b60208101518051919250901580610e5f5750816040015151815114155b15610e96576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8151811015610f2757610f1f604051806080016040528085600001518152602001848481518110610ecc57610ecc61372a565b6020026020010151815260200185604001518481518110610eef57610eef61372a565b60200260200101518152602001856060015173ffffffffffffffffffffffffffffffffffffffff16815250612536565b600101610e99565b50610f3d82600001518284606001518887611b6e565b610f479086613ae2565b9450505050610f568160010190565b9050610de6565b610f74610f6f36839003830183613fb1565b612536565b604080516001808252818301909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081610f8b579050509050610fc636839003830160208401613b44565b81600081518110610fd957610fd961372a565b6020908102919091010152610720823582610ffa60e0860160c087016134ea565b346001611b6e565b60004282825b8181101561052e576110328686838181106110255761102561372a565b90506020020135846121a8565b600101611008565b60006105656125c4565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161105e5790505090506110cc6020840184613cd9565b6110d590613d0d565b816000815181106110e8576110e861372a565b6020908102919091010152610dbc8335823334600161138f565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611176576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b60208110156112cc5760008582602081106112475761124761372a565b1a60f81b90507fff00000000000000000000000000000000000000000000000000000000000000811660000361127d57506112cc565b808484815181106112905761129061372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350506001918201910161122a565b5060008167ffffffffffffffff8111156112e8576112e8613759565b6040519080825280601f01601f191660200182016040528015611312576020820181803683370190505b50905060005b82811015611386578381815181106113325761133261372a565b602001015160f81c60f81b82828151811061134f5761134f61372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611318565b50949350505050565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff8111156113d4576113d4613759565b6040519080825280602002602001820160405280156113fd578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa15801561146f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526114b5919081019061400d565b80519091506114f0576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff81111561150b5761150b613759565b6040519080825280602002602001820160405280156115aa57816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816115295790505b50905060008467ffffffffffffffff8111156115c8576115c8613759565b6040519080825280602002602001820160405280156115f1578160200160208202803683370190505b50905060005b85811015611a805760008b82815181106116135761161361372a565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff161415801561165e57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15611695576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84604001511580156116a8575080604001515b156116df576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016117034290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6117a583826126f8565b600081815260326020526040902054909250156117c45760010161179b565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906119449082614133565b50505060608401511561199b57606084015160009081526032602052604090205461199b576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828786815181106119ae576119ae61372a565b60200260200101819052508360a001518686815181106119d0576119d061372a565b60200260200101818152505081896020015186815181106119f3576119f361372a565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b3585604051611a6391815260200190565b60405180910390a450505050611a798160010190565b90506115f7565b50611a9083838360008c8c612757565b845250919998505050505050505050565b606060008267ffffffffffffffff811115611abe57611abe613759565b604051908082528060200260200182016040528015611ae7578160200160208202803683370190505b5090506000805b855181101561052e576000868281518110611b0b57611b0b61372a565b6020026020010151905060005b8151811015611b6457818181518110611b3357611b3361372a565b6020026020010151858581518110611b4d57611b4d61372a565b602090810291909101015260019384019301611b18565b5050600101611aee565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611bdc573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611c22919081019061400d565b8051909150611c5d576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff811115611c7a57611c7a613759565b604051908082528060200260200182016040528015611d1957816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611c985790505b50905060008267ffffffffffffffff811115611d3757611d37613759565b604051908082528060200260200182016040528015611d60578160200160208202803683370190505b50905060005b8381101561218a5760008a8281518110611d8257611d8261372a565b6020908102919091018101518051600090815260329092526040909120805491925090611ddb576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c816001015414611e18576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c8116911614611e6e576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff16611ec4576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611f1e576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff161515610100820152600682018054839161012084019161202a90613da0565b80601f016020809104026020016040519081016040528092919081815260200182805461205690613da0565b80156120a35780601f10612078576101008083540402835291602001916120a3565b820191906000526020600020905b81548152906001019060200180831161208657829003601f168201915b5050505050815250508584815181106120be576120be61372a565b602002602001018190525081602001518484815181106120e0576120e061372a565b60200260200101818152505080600101548b73ffffffffffffffffffffffffffffffffffffffff168260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f615856000015160405161217891815260200190565b60405180910390a45050600101611d66565b5061219a84838360018b8b612757565b9a9950505050505050505050565b60008281526033602052604090205467ffffffffffffffff16156121f8576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b6060816000036122ad57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156122d757806122c18161424d565b91506122d09050600a836142b4565b91506122b1565b60008167ffffffffffffffff8111156122f2576122f2613759565b6040519080825280601f01601f19166020018201604052801561231c576020820181803683370190505b5090505b841561239f57612331600183613ae2565b915061233e600a866142c8565b6123499060306142dc565b60f81b81838151811061235e5761235e61372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612398600a866142b4565b9450612320565b949350505050565b60208082015160408084015160608086015173ffffffffffffffffffffffffffffffffffffffff1660009081528086528381208054600181019091558751865187890151878901519589015160808a01518051908c01209851999a9799949895976124ad97612492977fdbfdf8dc2b135c26253e00d5b6cbe6f20457e003fd526d97cea183883570de619791939290918c9101978852602088019690965273ffffffffffffffffffffffffffffffffffffffff94909416604087015267ffffffffffffffff9290921660608601521515608085015260a084015260c083015260e08201526101000190565b60405160208183030381529060405280519060200120612b31565b9050846060015173ffffffffffffffffffffffffffffffffffffffff166124e282856000015186602001518760400151612b44565b73ffffffffffffffffffffffffffffffffffffffff161461252f576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60208181015160408084015160608086015173ffffffffffffffffffffffffffffffffffffffff1660009081528086528381208054600181019091558751865186517fa98d02348410c9c76735e0d0bb1396f4015ac2bb9615f9c2611d19d7a8a99650998101999099529588015291860193909352608085018190529293909291906124ad9060a001612492565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561262a57507f000000000000000000000000000000000000000000000000000000000000000046145b1561265457507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b0151945160009961273999989796918c91016142ef565b60405160208183030381529060405280519060200120905092915050565b845160009060018190036127af576127a7888860008151811061277c5761277c61372a565b6020026020010151886000815181106127975761279761372a565b6020026020010151888888612b6c565b915050610697565b602088015173ffffffffffffffffffffffffffffffffffffffff81166128415760005b82811015612835578781815181106127ec576127ec61372a565b602002602001015160001461282d576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001016127d2565b50600092505050610697565b6000805b8381101561296b5760008982815181106128615761286161372a565b60200260200101519050806000141580156128e857508373ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e691906143cd565b155b1561291f576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87811115612959576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b96879003969190910190600101612845565b508615612a46576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906388e5b2d99083906129c8908d908d906004016143ea565b60206040518083038185885af11580156129e6573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612a0b91906143cd565b612a41576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b15565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906391db0b7e908390612a9c908d908d906004016143ea565b60206040518083038185885af1158015612aba573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612adf91906143cd565b612b15576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415612b2457612b2486612e82565b9998505050505050505050565b6000610534612b3e6125c4565b83612e95565b6000806000612b5587878787612ed7565b91509150612b6281612fef565b5095945050505050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612bd1578515612bc7576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000915050610697565b8515801590612c4c57508073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4a91906143cd565b155b15612c83576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115612cbd576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393508415612d9a576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890612d1c908b90600401613663565b60206040518083038185885af1158015612d3a573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d5f91906143cd565b612d95576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e67565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890612dee908b90600401613663565b60206040518083038185885af1158015612e0c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612e3191906143cd565b612e67576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612e7657612e7684612e82565b50939695505050505050565b8015612e9257612e923382613248565b50565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612739565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f0e5750600090506003612fe6565b8460ff16601b14158015612f2657508460ff16601c14155b15612f375750600090506004612fe6565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612f8b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612fdf57600060019250925050612fe6565b9150600090505b94509492505050565b6000816004811115613003576130036144a3565b0361300b5750565b600181600481111561301f5761301f6144a3565b0361308b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b600281600481111561309f5761309f6144a3565b03613106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401613082565b600381600481111561311a5761311a6144a3565b036131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401613082565b60048160048111156131bb576131bb6144a3565b03612e92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401613082565b804710156132b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401613082565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461330c576040519150601f19603f3d011682016040523d82523d6000602084013e613311565b606091505b5050905080610720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401613082565b60008083601f8401126133b457600080fd5b50813567ffffffffffffffff8111156133cc57600080fd5b6020830191508360208260051b85010111156133e757600080fd5b9250929050565b6000806020838503121561340157600080fd5b823567ffffffffffffffff81111561341857600080fd5b613424858286016133a2565b90969095509350505050565b60005b8381101561344b578181015183820152602001613433565b50506000910152565b6000815180845261346c816020860160208601613430565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006134b16020830184613454565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114612e9257600080fd5b80356134e5816134b8565b919050565b6000602082840312156134fc57600080fd5b81356134b1816134b8565b6020808252825182820181905260009190848201906040850190845b8181101561353f57835183529284019291840191600101613523565b50909695505050505050565b60006060828403121561355d57600080fd5b50919050565b60006020828403121561357557600080fd5b5035919050565b6000610140825184526020830151602085015260408301516135aa604086018267ffffffffffffffff169052565b5060608301516135c6606086018267ffffffffffffffff169052565b5060808301516135e2608086018267ffffffffffffffff169052565b5060a083015160a085015260c083015161361460c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161363c60e086018273ffffffffffffffffffffffffffffffffffffffff169052565b50610100838101511515908501526101208084015181860183905261069783870182613454565b6020815260006134b1602083018461357c565b6000806040838503121561368957600080fd5b8235613694816134b8565b946020939093013593505050565b6000602082840312156136b457600080fd5b813567ffffffffffffffff8111156136cb57600080fd5b820160c081850312156134b157600080fd5b600060e0828403121561355d57600080fd5b60006020828403121561370157600080fd5b813567ffffffffffffffff81111561371857600080fd5b8201604081850312156134b157600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126137bc57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126137fb57600080fd5b83018035915067ffffffffffffffff82111561381657600080fd5b6020019150600581901b36038213156133e757600080fd5b60405160c0810167ffffffffffffffff8111828210171561385157613851613759565b60405290565b6040516080810167ffffffffffffffff8111828210171561385157613851613759565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156138c1576138c1613759565b604052919050565b600067ffffffffffffffff8211156138e3576138e3613759565b5060051b60200190565b8015158114612e9257600080fd5b80356134e5816138ed565b600067ffffffffffffffff82111561392057613920613759565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261395d57600080fd5b813561397061396b82613906565b61387a565b81815284602083860101111561398557600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156139b457600080fd5b6139bc61382e565b905081356139c9816134b8565b8152602082013567ffffffffffffffff80821682146139e757600080fd5b8160208401526139f9604085016138fb565b6040840152606084013560608401526080840135915080821115613a1c57600080fd5b50613a298482850161394c565b60808301525060a082013560a082015292915050565b6000613a4d61396b846138c9565b80848252602080830192508560051b850136811115613a6b57600080fd5b855b81811015613aa757803567ffffffffffffffff811115613a8d5760008081fd5b613a9936828a016139a2565b865250938201938201613a6d565b50919695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561053457610534613ab3565b600060408284031215613b0757600080fd5b6040516040810181811067ffffffffffffffff82111715613b2a57613b2a613759565b604052823581526020928301359281019290925250919050565b600060408284031215613b5657600080fd5b6134b18383613af5565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613b9557600080fd5b83018035915067ffffffffffffffff821115613bb057600080fd5b6020019150600681901b36038213156133e757600080fd5b60008451613bda818460208901613430565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551613c16816001850160208a01613430565b60019201918201528351613c31816002840160208801613430565b0160020195945050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126137bc57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613ca757600080fd5b83018035915067ffffffffffffffff821115613cc257600080fd5b60200191506060810236038213156133e757600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff418336030181126137bc57600080fd5b600061053436836139a2565b600060608284031215613d2b57600080fd5b6040516060810181811067ffffffffffffffff82111715613d4e57613d4e613759565b604052905080823560ff81168114613d6557600080fd5b8082525060208301356020820152604083013560408201525092915050565b600060608284031215613d9657600080fd5b6134b18383613d19565b600181811c90821680613db457607f821691505b60208210810361355d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060c08236031215613dff57600080fd5b613e07613857565b82358152602083013567ffffffffffffffff811115613e2557600080fd5b613e31368286016139a2565b602083015250613e443660408501613d19565b604082015260a0830135613e57816134b8565b606082015292915050565b600082601f830112613e7357600080fd5b81356020613e8361396b836138c9565b82815260609283028501820192828201919087851115613ea257600080fd5b8387015b85811015613ec557613eb88982613d19565b8452928401928101613ea6565b5090979650505050505050565b600060808236031215613ee457600080fd5b613eec613857565b8235815260208084013567ffffffffffffffff80821115613f0c57600080fd5b9085019036601f830112613f1f57600080fd5b8135613f2d61396b826138c9565b81815260069190911b83018401908481019036831115613f4c57600080fd5b938501935b82851015613f7557613f633686613af5565b82528582019150604085019450613f51565b80868801525050506040860135925080831115613f9157600080fd5b5050613f9f36828601613e62565b604083015250613e57606084016134da565b600060e08284031215613fc357600080fd5b613fcb613857565b82358152613fdc8460208501613af5565b6020820152613fee8460608501613d19565b604082015260c0830135614001816134b8565b60608201529392505050565b6000602080838503121561402057600080fd5b825167ffffffffffffffff8082111561403857600080fd5b908401906080828703121561404c57600080fd5b614054613857565b8251815283830151614065816134b8565b818501526040830151614077816138ed565b604082015260608301518281111561408e57600080fd5b80840193505086601f8401126140a357600080fd5b825191506140b361396b83613906565b82815287858486010111156140c757600080fd5b6140d683868301878701613430565b60608201529695505050505050565b601f82111561072057600081815260208120601f850160051c8101602086101561410c5750805b601f850160051c820191505b8181101561412b57828155600101614118565b505050505050565b815167ffffffffffffffff81111561414d5761414d613759565b6141618161415b8454613da0565b846140e5565b602080601f8311600181146141b4576000841561417e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561412b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614201578886015182559484019460019091019084016141e2565b508582101561423d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361427e5761427e613ab3565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826142c3576142c3614285565b500490565b6000826142d7576142d7614285565b500690565b8082018082111561053457610534613ab3565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b60588301528460598301528351614388816079850160208801613430565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a9950505050505050505050565b6000602082840312156143df57600080fd5b81516134b1816138ed565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561445f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261444d86835161357c565b95509382019390820190600101614413565b50508584038187015286518085528782019482019350915060005b828110156144965784518452938101939281019260010161447a565b5091979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000813000a", - "deployedBytecode": "0x6080604052600436106101805760003560e01c8063b469318d116100d6578063e45d03f91161007f578063ed24911d11610059578063ed24911d1461049e578063f10b5cc8146104b3578063f17325e7146104e257600080fd5b8063e45d03f914610458578063e57a6b1b1461046b578063e71ff3651461047e57600080fd5b8063d45c4435116100b0578063d45c4435146103cf578063e13458fc14610406578063e30bb5631461041957600080fd5b8063b469318d14610322578063b83010d31461037c578063cf190f34146103af57600080fd5b8063469262671161013857806354fd4d501161011257806354fd4d50146102cd578063831e05a1146102e2578063a3112a64146102f557600080fd5b806346926267146102855780634cb7e9e51461029a5780634d003070146102ad57600080fd5b806317d7de7c1161016957806317d7de7c146102005780632d0335ab1461022257806344adc90e1461026557600080fd5b806312b11a171461018557806313893f61146101c7575b600080fd5b34801561019157600080fd5b507fdbfdf8dc2b135c26253e00d5b6cbe6f20457e003fd526d97cea183883570de615b6040519081526020015b60405180910390f35b3480156101d357600080fd5b506101e76101e23660046133ee565b6104f5565b60405167ffffffffffffffff90911681526020016101be565b34801561020c57600080fd5b5061021561053a565b6040516101be919061349e565b34801561022e57600080fd5b506101b461023d3660046134ea565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6102786102733660046133ee565b61056a565b6040516101be9190613507565b61029861029336600461354b565b6106a1565b005b6102986102a83660046133ee565b610725565b3480156102b957600080fd5b506101e76102c8366004613563565b61080d565b3480156102d957600080fd5b5061021561081a565b6102786102f03660046133ee565b6108bd565b34801561030157600080fd5b50610315610310366004613563565b610b0e565b6040516101be9190613663565b34801561032e57600080fd5b506101e761033d366004613676565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561038857600080fd5b507fa98d02348410c9c76735e0d0bb1396f4015ac2bb9615f9c2611d19d7a8a996506101b4565b3480156103bb57600080fd5b506101e76103ca366004613563565b610cd1565b3480156103db57600080fd5b506101e76103ea366004613563565b60009081526033602052604090205467ffffffffffffffff1690565b6101b46104143660046136a2565b610cdf565b34801561042557600080fd5b50610448610434366004613563565b600090815260326020526040902054151590565b60405190151581526020016101be565b6102986104663660046133ee565b610de2565b6102986104793660046136dd565b610f5d565b34801561048a57600080fd5b506101e76104993660046133ee565b611002565b3480156104aa57600080fd5b506101b461103a565b3480156104bf57600080fd5b5060405173420000000000000000000000000000000000002081526020016101be565b6101b46104f03660046136ef565b611044565b60004282825b8181101561052e57610526338787848181106105195761051961372a565b9050602002013585611102565b6001016104fb565b50909150505b92915050565b60606105657f0000000000000000000000000000000000000000000000000000000000000000611201565b905090565b606060008267ffffffffffffffff81111561058757610587613759565b6040519080825280602002602001820160405280156105ba57816020015b60608152602001906001900390816105a55790505b509050600034815b8581101561068c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86018114368888848181106106025761060261372a565b90506020028101906106149190613788565b9050600061063b823561062a60208501856137c6565b61063391613a3f565b33888761138f565b805190915061064a9086613ae2565b945080602001518785815181106106635761066361372a565b6020026020010181905250806020015151860195505050506106858160010190565b90506105c2565b506106978383611aa1565b9695505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816106b85790505090506106f336839003830160208401613b44565b816000815181106107065761070661372a565b602090810291909101015261072082358233346001611b6e565b505050565b3460005b82811015610807577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83018114368585848181106107695761076961372a565b905060200281019061077b9190613788565b90506107e8813561078f6020840184613b60565b808060200260200160405190810160405280939291908181526020016000905b828210156107db576107cc60408302860136819003810190613b44565b815260200190600101906107af565b5050505050338786611b6e565b6107f29085613ae2565b935050506108008160010190565b9050610729565b50505050565b60004261053483826121a8565b60606108457f000000000000000000000000000000000000000000000000000000000000000061226a565b61086e7f000000000000000000000000000000000000000000000000000000000000000061226a565b6108977f000000000000000000000000000000000000000000000000000000000000000061226a565b6040516020016108a993929190613bc8565b604051602081830303815290604052905090565b606060008267ffffffffffffffff8111156108da576108da613759565b60405190808252806020026020018201604052801561090d57816020015b60608152602001906001900390816108f85790505b509050600034815b8581101561068c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86018114368888848181106109555761095561372a565b90506020028101906109679190613c3e565b905036600061097960208401846137c6565b909250905080158061099957506109936040840184613c72565b82141590505b156109d0576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610a9257610a8a604051806080016040528086600001358152602001858585818110610a0557610a0561372a565b9050602002810190610a179190613cd9565b610a2090613d0d565b8152602001610a326040880188613c72565b85818110610a4257610a4261372a565b905060600201803603810190610a589190613d84565b8152602001610a6d60808801606089016134ea565b73ffffffffffffffffffffffffffffffffffffffff1690526123a7565b6001016109d3565b506000610abb8435610aa48486613a3f565b610ab460808801606089016134ea565b8a8961138f565b8051909150610aca9088613ae2565b96508060200151898781518110610ae357610ae361372a565b6020026020010181905250806020015151880197505050505050610b078160010190565b9050610915565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610c4890613da0565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7490613da0565b8015610cc15780601f10610c9657610100808354040283529160200191610cc1565b820191906000526020600020905b815481529060010190602001808311610ca457829003601f168201915b5050505050815250509050919050565b600042610534338483611102565b6000610cf2610ced83613ded565b6123a7565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610d09579050509050610d776020840184613cd9565b610d8090613d0d565b81600081518110610d9357610d9361372a565b6020908102919091010152610dbc833582610db460c0870160a088016134ea565b34600161138f565b60200151600081518110610dd257610dd261372a565b6020026020010151915050919050565b3460005b82811015610807577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830181146000858584818110610e2757610e2761372a565b9050602002810190610e399190613c3e565b610e4290613ed2565b60208101518051919250901580610e5f5750816040015151815114155b15610e96576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8151811015610f2757610f1f604051806080016040528085600001518152602001848481518110610ecc57610ecc61372a565b6020026020010151815260200185604001518481518110610eef57610eef61372a565b60200260200101518152602001856060015173ffffffffffffffffffffffffffffffffffffffff16815250612536565b600101610e99565b50610f3d82600001518284606001518887611b6e565b610f479086613ae2565b9450505050610f568160010190565b9050610de6565b610f74610f6f36839003830183613fb1565b612536565b604080516001808252818301909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081610f8b579050509050610fc636839003830160208401613b44565b81600081518110610fd957610fd961372a565b6020908102919091010152610720823582610ffa60e0860160c087016134ea565b346001611b6e565b60004282825b8181101561052e576110328686838181106110255761102561372a565b90506020020135846121a8565b600101611008565b60006105656125c4565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161105e5790505090506110cc6020840184613cd9565b6110d590613d0d565b816000815181106110e8576110e861372a565b6020908102919091010152610dbc8335823334600161138f565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611176576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b60208110156112cc5760008582602081106112475761124761372a565b1a60f81b90507fff00000000000000000000000000000000000000000000000000000000000000811660000361127d57506112cc565b808484815181106112905761129061372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350506001918201910161122a565b5060008167ffffffffffffffff8111156112e8576112e8613759565b6040519080825280601f01601f191660200182016040528015611312576020820181803683370190505b50905060005b82811015611386578381815181106113325761133261372a565b602001015160f81c60f81b82828151811061134f5761134f61372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611318565b50949350505050565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff8111156113d4576113d4613759565b6040519080825280602002602001820160405280156113fd578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa15801561146f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526114b5919081019061400d565b80519091506114f0576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff81111561150b5761150b613759565b6040519080825280602002602001820160405280156115aa57816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816115295790505b50905060008467ffffffffffffffff8111156115c8576115c8613759565b6040519080825280602002602001820160405280156115f1578160200160208202803683370190505b50905060005b85811015611a805760008b82815181106116135761161361372a565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff161415801561165e57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15611695576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84604001511580156116a8575080604001515b156116df576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016117034290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6117a583826126f8565b600081815260326020526040902054909250156117c45760010161179b565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906119449082614133565b50505060608401511561199b57606084015160009081526032602052604090205461199b576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828786815181106119ae576119ae61372a565b60200260200101819052508360a001518686815181106119d0576119d061372a565b60200260200101818152505081896020015186815181106119f3576119f361372a565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b3585604051611a6391815260200190565b60405180910390a450505050611a798160010190565b90506115f7565b50611a9083838360008c8c612757565b845250919998505050505050505050565b606060008267ffffffffffffffff811115611abe57611abe613759565b604051908082528060200260200182016040528015611ae7578160200160208202803683370190505b5090506000805b855181101561052e576000868281518110611b0b57611b0b61372a565b6020026020010151905060005b8151811015611b6457818181518110611b3357611b3361372a565b6020026020010151858581518110611b4d57611b4d61372a565b602090810291909101015260019384019301611b18565b5050600101611aee565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611bdc573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611c22919081019061400d565b8051909150611c5d576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff811115611c7a57611c7a613759565b604051908082528060200260200182016040528015611d1957816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611c985790505b50905060008267ffffffffffffffff811115611d3757611d37613759565b604051908082528060200260200182016040528015611d60578160200160208202803683370190505b50905060005b8381101561218a5760008a8281518110611d8257611d8261372a565b6020908102919091018101518051600090815260329092526040909120805491925090611ddb576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c816001015414611e18576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c8116911614611e6e576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff16611ec4576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611f1e576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff161515610100820152600682018054839161012084019161202a90613da0565b80601f016020809104026020016040519081016040528092919081815260200182805461205690613da0565b80156120a35780601f10612078576101008083540402835291602001916120a3565b820191906000526020600020905b81548152906001019060200180831161208657829003601f168201915b5050505050815250508584815181106120be576120be61372a565b602002602001018190525081602001518484815181106120e0576120e061372a565b60200260200101818152505080600101548b73ffffffffffffffffffffffffffffffffffffffff168260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f615856000015160405161217891815260200190565b60405180910390a45050600101611d66565b5061219a84838360018b8b612757565b9a9950505050505050505050565b60008281526033602052604090205467ffffffffffffffff16156121f8576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b6060816000036122ad57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156122d757806122c18161424d565b91506122d09050600a836142b4565b91506122b1565b60008167ffffffffffffffff8111156122f2576122f2613759565b6040519080825280601f01601f19166020018201604052801561231c576020820181803683370190505b5090505b841561239f57612331600183613ae2565b915061233e600a866142c8565b6123499060306142dc565b60f81b81838151811061235e5761235e61372a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612398600a866142b4565b9450612320565b949350505050565b60208082015160408084015160608086015173ffffffffffffffffffffffffffffffffffffffff1660009081528086528381208054600181019091558751865187890151878901519589015160808a01518051908c01209851999a9799949895976124ad97612492977fdbfdf8dc2b135c26253e00d5b6cbe6f20457e003fd526d97cea183883570de619791939290918c9101978852602088019690965273ffffffffffffffffffffffffffffffffffffffff94909416604087015267ffffffffffffffff9290921660608601521515608085015260a084015260c083015260e08201526101000190565b60405160208183030381529060405280519060200120612b31565b9050846060015173ffffffffffffffffffffffffffffffffffffffff166124e282856000015186602001518760400151612b44565b73ffffffffffffffffffffffffffffffffffffffff161461252f576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60208181015160408084015160608086015173ffffffffffffffffffffffffffffffffffffffff1660009081528086528381208054600181019091558751865186517fa98d02348410c9c76735e0d0bb1396f4015ac2bb9615f9c2611d19d7a8a99650998101999099529588015291860193909352608085018190529293909291906124ad9060a001612492565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561262a57507f000000000000000000000000000000000000000000000000000000000000000046145b1561265457507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b0151945160009961273999989796918c91016142ef565b60405160208183030381529060405280519060200120905092915050565b845160009060018190036127af576127a7888860008151811061277c5761277c61372a565b6020026020010151886000815181106127975761279761372a565b6020026020010151888888612b6c565b915050610697565b602088015173ffffffffffffffffffffffffffffffffffffffff81166128415760005b82811015612835578781815181106127ec576127ec61372a565b602002602001015160001461282d576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001016127d2565b50600092505050610697565b6000805b8381101561296b5760008982815181106128615761286161372a565b60200260200101519050806000141580156128e857508373ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e691906143cd565b155b1561291f576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87811115612959576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b96879003969190910190600101612845565b508615612a46576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906388e5b2d99083906129c8908d908d906004016143ea565b60206040518083038185885af11580156129e6573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612a0b91906143cd565b612a41576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b15565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906391db0b7e908390612a9c908d908d906004016143ea565b60206040518083038185885af1158015612aba573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612adf91906143cd565b612b15576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415612b2457612b2486612e82565b9998505050505050505050565b6000610534612b3e6125c4565b83612e95565b6000806000612b5587878787612ed7565b91509150612b6281612fef565b5095945050505050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612bd1578515612bc7576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000915050610697565b8515801590612c4c57508073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4a91906143cd565b155b15612c83576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115612cbd576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393508415612d9a576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890612d1c908b90600401613663565b60206040518083038185885af1158015612d3a573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d5f91906143cd565b612d95576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e67565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890612dee908b90600401613663565b60206040518083038185885af1158015612e0c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612e3191906143cd565b612e67576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612e7657612e7684612e82565b50939695505050505050565b8015612e9257612e923382613248565b50565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612739565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f0e5750600090506003612fe6565b8460ff16601b14158015612f2657508460ff16601c14155b15612f375750600090506004612fe6565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612f8b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612fdf57600060019250925050612fe6565b9150600090505b94509492505050565b6000816004811115613003576130036144a3565b0361300b5750565b600181600481111561301f5761301f6144a3565b0361308b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064015b60405180910390fd5b600281600481111561309f5761309f6144a3565b03613106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401613082565b600381600481111561311a5761311a6144a3565b036131a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401613082565b60048160048111156131bb576131bb6144a3565b03612e92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401613082565b804710156132b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401613082565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461330c576040519150601f19603f3d011682016040523d82523d6000602084013e613311565b606091505b5050905080610720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401613082565b60008083601f8401126133b457600080fd5b50813567ffffffffffffffff8111156133cc57600080fd5b6020830191508360208260051b85010111156133e757600080fd5b9250929050565b6000806020838503121561340157600080fd5b823567ffffffffffffffff81111561341857600080fd5b613424858286016133a2565b90969095509350505050565b60005b8381101561344b578181015183820152602001613433565b50506000910152565b6000815180845261346c816020860160208601613430565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006134b16020830184613454565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114612e9257600080fd5b80356134e5816134b8565b919050565b6000602082840312156134fc57600080fd5b81356134b1816134b8565b6020808252825182820181905260009190848201906040850190845b8181101561353f57835183529284019291840191600101613523565b50909695505050505050565b60006060828403121561355d57600080fd5b50919050565b60006020828403121561357557600080fd5b5035919050565b6000610140825184526020830151602085015260408301516135aa604086018267ffffffffffffffff169052565b5060608301516135c6606086018267ffffffffffffffff169052565b5060808301516135e2608086018267ffffffffffffffff169052565b5060a083015160a085015260c083015161361460c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161363c60e086018273ffffffffffffffffffffffffffffffffffffffff169052565b50610100838101511515908501526101208084015181860183905261069783870182613454565b6020815260006134b1602083018461357c565b6000806040838503121561368957600080fd5b8235613694816134b8565b946020939093013593505050565b6000602082840312156136b457600080fd5b813567ffffffffffffffff8111156136cb57600080fd5b820160c081850312156134b157600080fd5b600060e0828403121561355d57600080fd5b60006020828403121561370157600080fd5b813567ffffffffffffffff81111561371857600080fd5b8201604081850312156134b157600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126137bc57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126137fb57600080fd5b83018035915067ffffffffffffffff82111561381657600080fd5b6020019150600581901b36038213156133e757600080fd5b60405160c0810167ffffffffffffffff8111828210171561385157613851613759565b60405290565b6040516080810167ffffffffffffffff8111828210171561385157613851613759565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156138c1576138c1613759565b604052919050565b600067ffffffffffffffff8211156138e3576138e3613759565b5060051b60200190565b8015158114612e9257600080fd5b80356134e5816138ed565b600067ffffffffffffffff82111561392057613920613759565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261395d57600080fd5b813561397061396b82613906565b61387a565b81815284602083860101111561398557600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156139b457600080fd5b6139bc61382e565b905081356139c9816134b8565b8152602082013567ffffffffffffffff80821682146139e757600080fd5b8160208401526139f9604085016138fb565b6040840152606084013560608401526080840135915080821115613a1c57600080fd5b50613a298482850161394c565b60808301525060a082013560a082015292915050565b6000613a4d61396b846138c9565b80848252602080830192508560051b850136811115613a6b57600080fd5b855b81811015613aa757803567ffffffffffffffff811115613a8d5760008081fd5b613a9936828a016139a2565b865250938201938201613a6d565b50919695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561053457610534613ab3565b600060408284031215613b0757600080fd5b6040516040810181811067ffffffffffffffff82111715613b2a57613b2a613759565b604052823581526020928301359281019290925250919050565b600060408284031215613b5657600080fd5b6134b18383613af5565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613b9557600080fd5b83018035915067ffffffffffffffff821115613bb057600080fd5b6020019150600681901b36038213156133e757600080fd5b60008451613bda818460208901613430565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551613c16816001850160208a01613430565b60019201918201528351613c31816002840160208801613430565b0160020195945050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126137bc57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613ca757600080fd5b83018035915067ffffffffffffffff821115613cc257600080fd5b60200191506060810236038213156133e757600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff418336030181126137bc57600080fd5b600061053436836139a2565b600060608284031215613d2b57600080fd5b6040516060810181811067ffffffffffffffff82111715613d4e57613d4e613759565b604052905080823560ff81168114613d6557600080fd5b8082525060208301356020820152604083013560408201525092915050565b600060608284031215613d9657600080fd5b6134b18383613d19565b600181811c90821680613db457607f821691505b60208210810361355d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060c08236031215613dff57600080fd5b613e07613857565b82358152602083013567ffffffffffffffff811115613e2557600080fd5b613e31368286016139a2565b602083015250613e443660408501613d19565b604082015260a0830135613e57816134b8565b606082015292915050565b600082601f830112613e7357600080fd5b81356020613e8361396b836138c9565b82815260609283028501820192828201919087851115613ea257600080fd5b8387015b85811015613ec557613eb88982613d19565b8452928401928101613ea6565b5090979650505050505050565b600060808236031215613ee457600080fd5b613eec613857565b8235815260208084013567ffffffffffffffff80821115613f0c57600080fd5b9085019036601f830112613f1f57600080fd5b8135613f2d61396b826138c9565b81815260069190911b83018401908481019036831115613f4c57600080fd5b938501935b82851015613f7557613f633686613af5565b82528582019150604085019450613f51565b80868801525050506040860135925080831115613f9157600080fd5b5050613f9f36828601613e62565b604083015250613e57606084016134da565b600060e08284031215613fc357600080fd5b613fcb613857565b82358152613fdc8460208501613af5565b6020820152613fee8460608501613d19565b604082015260c0830135614001816134b8565b60608201529392505050565b6000602080838503121561402057600080fd5b825167ffffffffffffffff8082111561403857600080fd5b908401906080828703121561404c57600080fd5b614054613857565b8251815283830151614065816134b8565b818501526040830151614077816138ed565b604082015260608301518281111561408e57600080fd5b80840193505086601f8401126140a357600080fd5b825191506140b361396b83613906565b82815287858486010111156140c757600080fd5b6140d683868301878701613430565b60608201529695505050505050565b601f82111561072057600081815260208120601f850160051c8101602086101561410c5750805b601f850160051c820191505b8181101561412b57828155600101614118565b505050505050565b815167ffffffffffffffff81111561414d5761414d613759565b6141618161415b8454613da0565b846140e5565b602080601f8311600181146141b4576000841561417e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561412b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614201578886015182559484019460019091019084016141e2565b508582101561423d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361427e5761427e613ab3565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826142c3576142c3614285565b500490565b6000826142d7576142d7614285565b500690565b8082018082111561053457610534613ab3565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b60588301528460598301528351614388816079850160208801613430565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a9950505050505050505050565b6000602082840312156143df57600080fd5b81516134b1816138ed565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561445f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261444d86835161357c565b95509382019390820190600101614413565b50508584038187015286518085528782019482019350915060005b828110156144965784518452938101939281019260010161447a565b5091979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000813000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "attest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)))": { - "params": { - "request": "The arguments of the attestation request." - }, - "returns": { - "_0": "The UID of the new attestation." - } - }, - "attestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256),(uint8,bytes32,bytes32),address))": { - "params": { - "delegatedRequest": "The arguments of the delegated attestation request." - }, - "returns": { - "_0": "The UID of the new attestation." - } - }, - "constructor": { - "details": "Creates a new EAS instance." - }, - "getAttestTypeHash()": { - "returns": { - "_0": "The EIP712 attest function type hash." - } - }, - "getAttestation(bytes32)": { - "params": { - "uid": "The UID of the attestation to retrieve." - }, - "returns": { - "_0": "The attestation data members." - } - }, - "getName()": { - "returns": { - "_0": "The EIP712 name." - } - }, - "getNonce(address)": { - "params": { - "account": "The requested account." - }, - "returns": { - "_0": "The current nonce." - } - }, - "getRevokeOffchain(address,bytes32)": { - "params": { - "data": "The data to query." - }, - "returns": { - "_0": "The timestamp the data was timestamped with." - } - }, - "getRevokeTypeHash()": { - "returns": { - "_0": "hash_ The EIP712 revoke function type hash." - } - }, - "getSchemaRegistry()": { - "returns": { - "_0": "The address of the global schema registry." - } - }, - "getTimestamp(bytes32)": { - "params": { - "data": "The data to query." - }, - "returns": { - "_0": "The timestamp the data was timestamped with." - } - }, - "isAttestationValid(bytes32)": { - "params": { - "uid": "The UID of the attestation to retrieve." - }, - "returns": { - "_0": "Whether an attestation exists." - } - }, - "multiAttest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[])[])": { - "params": { - "multiRequests": "The arguments of the multi attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization." - }, - "returns": { - "_0": "The UIDs of the new attestations." - } - }, - "multiAttestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[],(uint8,bytes32,bytes32)[],address)[])": { - "params": { - "multiDelegatedRequests": "The arguments of the delegated multi attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization." - }, - "returns": { - "_0": "The UIDs of the new attestations." - } - }, - "multiRevoke((bytes32,(bytes32,uint256)[])[])": { - "params": { - "multiRequests": "The arguments of the multi revocation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization." - } - }, - "multiRevokeByDelegation((bytes32,(bytes32,uint256)[],(uint8,bytes32,bytes32)[],address)[])": { - "params": { - "multiDelegatedRequests": "The arguments of the delegated multi revocation attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization." - } - }, - "multiRevokeOffchain(bytes32[])": { - "params": { - "data": "The data to timestamp." - }, - "returns": { - "_0": "The timestamp the data was revoked with." - } - }, - "multiTimestamp(bytes32[])": { - "params": { - "data": "The data to timestamp." - }, - "returns": { - "_0": "The timestamp the data was timestamped with." - } - }, - "revoke((bytes32,(bytes32,uint256)))": { - "params": { - "request": "The arguments of the revocation request." - } - }, - "revokeByDelegation((bytes32,(bytes32,uint256),(uint8,bytes32,bytes32),address))": { - "params": { - "delegatedRequest": "The arguments of the delegated revocation request." - } - }, - "revokeOffchain(bytes32)": { - "params": { - "data": "The data to timestamp." - }, - "returns": { - "_0": "The timestamp the data was revoked with." - } - }, - "timestamp(bytes32)": { - "params": { - "data": "The data to timestamp." - }, - "returns": { - "_0": "The timestamp the data was timestamped with." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "events": { - "Attested(address,address,bytes32,bytes32)": { - "details": "Emitted when an attestation has been made.", - "params": { - "attester": "The attesting account.", - "recipient": "The recipient of the attestation.", - "schema": "The UID of the schema.", - "uid": "The UID the revoked attestation." - } - }, - "Revoked(address,address,bytes32,bytes32)": { - "details": "Emitted when an attestation has been revoked.", - "params": { - "attester": "The attesting account.", - "recipient": "The recipient of the attestation.", - "schema": "The UID of the schema.", - "uid": "The UID the revoked attestation." - } - }, - "RevokedOffchain(address,bytes32,uint64)": { - "details": "Emitted when a data has been revoked.", - "params": { - "data": "The data.", - "revoker": "The address of the revoker.", - "timestamp": "The timestamp." - } - }, - "Timestamped(bytes32,uint64)": { - "details": "Emitted when a data has been timestamped.", - "params": { - "data": "The data.", - "timestamp": "The timestamp." - } - } - }, - "title": "EAS" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"AccessDenied\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"AlreadyRevoked\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"AlreadyRevokedOffchain\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"AlreadyTimestamped\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InsufficientValue\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidAttestation\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidAttestations\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidExpirationTime\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidLength\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidOffset\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidRegistry\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidRevocation\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidRevocations\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidSchema\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidSignature\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"InvalidVerifier\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"Irrevocable\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"NotFound\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"NotPayable\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"WrongSchema\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\",\"indexed\":false},{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Attested\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\",\"indexed\":false},{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Revoked\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\",\"indexed\":true}],\"type\":\"event\",\"name\":\"RevokedOffchain\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Timestamped\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"struct AttestationRequest\",\"name\":\"request\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct AttestationRequestData\",\"name\":\"data\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"attest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[{\"internalType\":\"struct DelegatedAttestationRequest\",\"name\":\"delegatedRequest\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct AttestationRequestData\",\"name\":\"data\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]},{\"internalType\":\"struct EIP712Signature\",\"name\":\"signature\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}]},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"attestByDelegation\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"getAttestTypeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getAttestation\",\"outputs\":[{\"internalType\":\"struct Attestation\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"time\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"revocationTime\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}]}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getDomainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getRevokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"getRevokeTypeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"getSchemaRegistry\",\"outputs\":[{\"internalType\":\"contract ISchemaRegistry\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getTimestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"isAttestationValid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"struct MultiAttestationRequest[]\",\"name\":\"multiRequests\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct AttestationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"multiAttest\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}]},{\"inputs\":[{\"internalType\":\"struct MultiDelegatedAttestationRequest[]\",\"name\":\"multiDelegatedRequests\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct AttestationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]},{\"internalType\":\"struct EIP712Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}]},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"multiAttestByDelegation\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}]},{\"inputs\":[{\"internalType\":\"struct MultiRevocationRequest[]\",\"name\":\"multiRequests\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct RevocationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"multiRevoke\"},{\"inputs\":[{\"internalType\":\"struct MultiDelegatedRevocationRequest[]\",\"name\":\"multiDelegatedRequests\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct RevocationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]},{\"internalType\":\"struct EIP712Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}]},{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"multiRevokeByDelegation\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"data\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"multiRevokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"data\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"multiTimestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"struct RevocationRequest\",\"name\":\"request\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct RevocationRequestData\",\"name\":\"data\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"revoke\"},{\"inputs\":[{\"internalType\":\"struct DelegatedRevocationRequest\",\"name\":\"delegatedRequest\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"struct RevocationRequestData\",\"name\":\"data\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}]},{\"internalType\":\"struct EIP712Signature\",\"name\":\"signature\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}]},{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"}]}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"revokeByDelegation\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"revokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"timestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"attest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)))\":{\"params\":{\"request\":\"The arguments of the attestation request.\"},\"returns\":{\"_0\":\"The UID of the new attestation.\"}},\"attestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256),(uint8,bytes32,bytes32),address))\":{\"params\":{\"delegatedRequest\":\"The arguments of the delegated attestation request.\"},\"returns\":{\"_0\":\"The UID of the new attestation.\"}},\"constructor\":{\"details\":\"Creates a new EAS instance.\"},\"getAttestTypeHash()\":{\"returns\":{\"_0\":\"The EIP712 attest function type hash.\"}},\"getAttestation(bytes32)\":{\"params\":{\"uid\":\"The UID of the attestation to retrieve.\"},\"returns\":{\"_0\":\"The attestation data members.\"}},\"getName()\":{\"returns\":{\"_0\":\"The EIP712 name.\"}},\"getNonce(address)\":{\"params\":{\"account\":\"The requested account.\"},\"returns\":{\"_0\":\"The current nonce.\"}},\"getRevokeOffchain(address,bytes32)\":{\"params\":{\"data\":\"The data to query.\"},\"returns\":{\"_0\":\"The timestamp the data was timestamped with.\"}},\"getRevokeTypeHash()\":{\"returns\":{\"_0\":\"hash_ The EIP712 revoke function type hash.\"}},\"getSchemaRegistry()\":{\"returns\":{\"_0\":\"The address of the global schema registry.\"}},\"getTimestamp(bytes32)\":{\"params\":{\"data\":\"The data to query.\"},\"returns\":{\"_0\":\"The timestamp the data was timestamped with.\"}},\"isAttestationValid(bytes32)\":{\"params\":{\"uid\":\"The UID of the attestation to retrieve.\"},\"returns\":{\"_0\":\"Whether an attestation exists.\"}},\"multiAttest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[])[])\":{\"params\":{\"multiRequests\":\"The arguments of the multi attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization.\"},\"returns\":{\"_0\":\"The UIDs of the new attestations.\"}},\"multiAttestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[],(uint8,bytes32,bytes32)[],address)[])\":{\"params\":{\"multiDelegatedRequests\":\"The arguments of the delegated multi attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization.\"},\"returns\":{\"_0\":\"The UIDs of the new attestations.\"}},\"multiRevoke((bytes32,(bytes32,uint256)[])[])\":{\"params\":{\"multiRequests\":\"The arguments of the multi revocation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization.\"}},\"multiRevokeByDelegation((bytes32,(bytes32,uint256)[],(uint8,bytes32,bytes32)[],address)[])\":{\"params\":{\"multiDelegatedRequests\":\"The arguments of the delegated multi revocation attestation requests. The requests should be grouped by distinct schema ids to benefit from the best batching optimization.\"}},\"multiRevokeOffchain(bytes32[])\":{\"params\":{\"data\":\"The data to timestamp.\"},\"returns\":{\"_0\":\"The timestamp the data was revoked with.\"}},\"multiTimestamp(bytes32[])\":{\"params\":{\"data\":\"The data to timestamp.\"},\"returns\":{\"_0\":\"The timestamp the data was timestamped with.\"}},\"revoke((bytes32,(bytes32,uint256)))\":{\"params\":{\"request\":\"The arguments of the revocation request.\"}},\"revokeByDelegation((bytes32,(bytes32,uint256),(uint8,bytes32,bytes32),address))\":{\"params\":{\"delegatedRequest\":\"The arguments of the delegated revocation request.\"}},\"revokeOffchain(bytes32)\":{\"params\":{\"data\":\"The data to timestamp.\"},\"returns\":{\"_0\":\"The timestamp the data was revoked with.\"}},\"timestamp(bytes32)\":{\"params\":{\"data\":\"The data to timestamp.\"},\"returns\":{\"_0\":\"The timestamp the data was timestamped with.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"attest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)))\":{\"notice\":\"Attests to a specific schema. Example: attest({ schema: \\\"0facc36681cbe2456019c1b0d1e7bedd6d1d40f6f324bf3dd3a4cef2999200a0\\\", data: { recipient: \\\"0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf\\\", expirationTime: 0, revocable: true, refUID: \\\"0x0000000000000000000000000000000000000000000000000000000000000000\\\", data: \\\"0xF00D\\\", value: 0 } })\"},\"attestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256),(uint8,bytes32,bytes32),address))\":{\"notice\":\"Attests to a specific schema via the provided EIP712 signature. Example: attestByDelegation({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 0 }, signature: { v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, attester: '0xc5E8740aD971409492b1A63Db8d83025e0Fc427e' })\"},\"getAttestTypeHash()\":{\"notice\":\"Returns the EIP712 type hash for the attest function.\"},\"getAttestation(bytes32)\":{\"notice\":\"Returns an existing attestation by UID.\"},\"getDomainSeparator()\":{\"notice\":\"Returns the domain separator used in the encoding of the signatures for attest, and revoke.\"},\"getName()\":{\"notice\":\"Returns the EIP712 name.\"},\"getNonce(address)\":{\"notice\":\"Returns the current nonce per-account.\"},\"getRevokeOffchain(address,bytes32)\":{\"notice\":\"Returns the timestamp that the specified data was timestamped with.\"},\"getRevokeTypeHash()\":{\"notice\":\"Returns the EIP712 type hash for the revoke function.\"},\"getSchemaRegistry()\":{\"notice\":\"Returns the address of the global schema registry.\"},\"getTimestamp(bytes32)\":{\"notice\":\"Returns the timestamp that the specified data was timestamped with.\"},\"isAttestationValid(bytes32)\":{\"notice\":\"Checks whether an attestation exists.\"},\"multiAttest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[])[])\":{\"notice\":\"Attests to multiple schemas. Example: multiAttest([{ schema: '0x33e9094830a5cba5554d1954310e4fbed2ef5f859ec1404619adea4207f391fd', data: [{ recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 1000 }, { recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 0, revocable: false, refUID: '0x480df4a039efc31b11bfdf491b383ca138b6bde160988222a2a3509c02cee174', data: '0x00', value: 0 }], }, { schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', data: [{ recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 0, revocable: true, refUID: '0x75bf2ed8dca25a8190c50c52db136664de25b2449535839008ccfdab469b214f', data: '0x12345678', value: 0 }, }])\"},\"multiAttestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[],(uint8,bytes32,bytes32)[],address)[])\":{\"notice\":\"Attests to multiple schemas using via provided EIP712 signatures. Example: multiAttestByDelegation([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 0 }, { recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 0, revocable: false, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x00', value: 0 }], signatures: [{ v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, { v: 28, r: '0x487s...67bb', s: '0x12ad...2366' }], attester: '0x1D86495b2A7B524D747d2839b3C645Bed32e8CF4' }])\"},\"multiRevoke((bytes32,(bytes32,uint256)[])[])\":{\"notice\":\"Revokes existing attestations to multiple schemas. Example: multiRevoke([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', value: 1000 }, { uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', value: 0 }], }, { schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', data: [{ uid: '0x053d42abce1fd7c8fcddfae21845ad34dae287b2c326220b03ba241bc5a8f019', value: 0 }, }])\"},\"multiRevokeByDelegation((bytes32,(bytes32,uint256)[],(uint8,bytes32,bytes32)[],address)[])\":{\"notice\":\"Revokes existing attestations to multiple schemas via provided EIP712 signatures. Example: multiRevokeByDelegation([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', value: 1000 }, { uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', value: 0 }], signatures: [{ v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, { v: 28, r: '0x487s...67bb', s: '0x12ad...2366' }], revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992' }])\"},\"multiRevokeOffchain(bytes32[])\":{\"notice\":\"Revokes the specified multiple bytes32 data.\"},\"multiTimestamp(bytes32[])\":{\"notice\":\"Timestamps the specified multiple bytes32 data.\"},\"revoke((bytes32,(bytes32,uint256)))\":{\"notice\":\"Revokes an existing attestation to a specific schema. Example: revoke({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { uid: '0x101032e487642ee04ee17049f99a70590c735b8614079fc9275f9dd57c00966d', value: 0 } })\"},\"revokeByDelegation((bytes32,(bytes32,uint256),(uint8,bytes32,bytes32),address))\":{\"notice\":\"Revokes an existing attestation to a specific schema via the provided EIP712 signature. Example: revokeByDelegation({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { uid: '0xcbbc12102578c642a0f7b34fe7111e41afa25683b6cd7b5a14caf90fa14d24ba', value: 0 }, signature: { v: 27, r: '0xb593...7142', s: '0x0f5b...2cce' }, revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992' })\"},\"revokeOffchain(bytes32)\":{\"notice\":\"Revokes the specified bytes32 data.\"},\"timestamp(bytes32)\":{\"notice\":\"Timestamps the specified bytes32 data.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"contracts/EAS/EAS.sol\":\"EAS\"},\"libraries\":{}},\"sources\":{\"contracts/EAS/Common.sol\":{\"keccak256\":\"0x880e8262ee6682eeca6140e5a0b71f98e0c4024720c777da161e05a7715ed09a\",\"urls\":[\"bzz-raw://56ed7dc6b538070a66b851275a6a9721275da9e5e83631d94e93620cd679c3f6\",\"dweb:/ipfs/QmVjKgNr3jbnYerjDyFGLky8wXCUR8SuzxrsypBVVSW3tk\"],\"license\":\"MIT\"},\"contracts/EAS/EAS.sol\":{\"keccak256\":\"0x6b2cb86e523e76ab186c84ec7e9ee3451e993ddeea97c0c775d7e716b3379423\",\"urls\":[\"bzz-raw://3d05621ec6e9f83b4b6a77cf934d042d06bf6edb16e200245d9ac6620fabf7c0\",\"dweb:/ipfs/QmZWSECRBQMg4fduaYCrUhgmbmxK5cqaPSUAYHGWp4az5g\"],\"license\":\"MIT\"},\"contracts/EAS/IEAS.sol\":{\"keccak256\":\"0x8370442f2f2a19eef31653d46860ddcaa1c10bd5ec70113ce93fc43e672378c6\",\"urls\":[\"bzz-raw://37968de66d77a84bf03876d2ec6363f155dfccf87f00df9876d154ac8a6a87d6\",\"dweb:/ipfs/Qmb82nUieu66cfTLVdRcGwGGs2yYqmut4hDJ5vUVqtnXFe\"],\"license\":\"MIT\"},\"contracts/EAS/ISchemaRegistry.sol\":{\"keccak256\":\"0x4e988bea43a70e8ed156c7ee74dd3667872a68f65fa10dc4f07ddd4d89b929f1\",\"urls\":[\"bzz-raw://046977484b8089aad16f2064099b3f7604bcbddd61334e046838c3c448b5ebb5\",\"dweb:/ipfs/QmXdorYunKEbiosCGL4teYCd1W2njCqujvMWQjYonAxU6w\"],\"license\":\"MIT\"},\"contracts/EAS/eip712/EIP712Verifier.sol\":{\"keccak256\":\"0x048e65ebd0d8a0e3195affa57e7f7b904b3195fe28b160169244fc89c0eb55f2\",\"urls\":[\"bzz-raw://7c8760a59d43cf81c43f2945283f0f0e5f6f205136064d4e48ee2abe67fe687b\",\"dweb:/ipfs/QmaGXYY8g17CTMYyVCZK42P8MM3ntcQye1KK1ytc6sbbVb\"],\"license\":\"MIT\"},\"contracts/EAS/resolver/ISchemaResolver.sol\":{\"keccak256\":\"0xe537341e3d8d9c8e0eada21b4278beef510781fb1745892312c286a3c8287c2d\",\"urls\":[\"bzz-raw://5ab80b1fd7b6ad0ca94ff14358c5ba942614e25632d8a07c8e364d3f45c08453\",\"dweb:/ipfs/QmY6WToUtVo1HpDq7z7Tb17othZnJwpz4m26GuzKAsGTeM\"],\"license\":\"MIT\"},\"contracts/libraries/Predeploys.sol\":{\"keccak256\":\"0xe46f53d83bbc978cebc11cb702e6b9f046cfbafdcbb79bba2837edf28515cbe4\",\"urls\":[\"bzz-raw://c80c47543cad25cc10ddd7ec2a2399ef1dac50bd5c90d8042211ded0692416a8\",\"dweb:/ipfs/QmeKCGE85eJpJzEXSLmQmhWT9aniSqvwNc8XDcSVedh9F8\"],\"license\":\"MIT\"},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0xc455c84bb1f17e994dea0451fd363f81f83965bfa86e81ac6c8b3a327b9a0ff0\",\"urls\":[\"bzz-raw://fab499f3c0d7df8eb763b50621848d5d2147fb9c42a8eb9b65a11093090bb482\",\"dweb:/ipfs/QmUKsG4ztwtUZFjuRYAxgUFTgH5YxWSGF1BFFaB7vdM2K3\"],\"license\":\"MIT\"},\"node_modules/@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"],\"license\":\"MIT\"},\"node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0xdb7f5c28fc61cda0bd8ab60ce288e206b791643bcd3ba464a70cbec18895a2f5\",\"urls\":[\"bzz-raw://bf52bdf22a33263f5ca6227a35faeac3b81e7d2c692fbcc6a079d488710c5900\",\"dweb:/ipfs/QmcmsjkP4yq3UhiJbvyzwufaY2EKh1zhHaRK8ATag2cpD2\"],\"license\":\"MIT\"},\"node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"keccak256\":\"0x6688fad58b9ec0286d40fa957152e575d5d8bd4c3aa80985efdb11b44f776ae7\",\"urls\":[\"bzz-raw://8bc00ab7f133cdaafd212a5cc6a16c8d37319721105d130c8e5af0c4e8f170ba\",\"dweb:/ipfs/QmVmf6LVMfFiEkvKYLzSv3bGHzymEW93AcUuFrNUdY3NtT\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 1, - "receipt": { - "transactionHash": "0xb17f2eb6e221002683f7427bd2481ce78b0f82094c4eeb0e701442cba4904db5", - "transactionIndex": "0x2", - "blockHash": "0xfcbb8967e5e2d9c6547cd7ae13b0f7973cc2bbd01fbf506e64ef0959ae345f19", - "blockNumber": "0x6645706", - "from": "0x9bbFB9919062C29a5eE15aCD93c9D7c3b14d31aa", - "to": null, - "cumulativeGasUsed": "0x3bf2b8", - "gasUsed": "0x3aa40b", - "contractAddress": "0x4E0275Ea5a89e7a3c1B58411379D1a0eDdc5b088", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb2d05e44" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 27260, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "_nonces", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_address,t_uint256)" - }, - { - "astId": 27266, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 24954, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "_db", - "offset": 0, - "slot": "50", - "type": "t_mapping(t_bytes32,t_struct(Attestation)24729_storage)" - }, - { - "astId": 24958, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "_timestamps", - "offset": 0, - "slot": "51", - "type": "t_mapping(t_bytes32,t_uint64)" - }, - { - "astId": 24964, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "_revocationsOffchain", - "offset": 0, - "slot": "52", - "type": "t_mapping(t_address,t_mapping(t_bytes32,t_uint64))" - }, - { - "astId": 24970, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "__gap", - "offset": 0, - "slot": "53", - "type": "t_array(t_uint256)47_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)47_storage": { - "encoding": "inplace", - "label": "uint256[47]", - "numberOfBytes": "1504", - "base": "t_uint256" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "encoding": "bytes", - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_bytes32,t_uint64))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(bytes32 => uint64))", - "numberOfBytes": "32", - "value": "t_mapping(t_bytes32,t_uint64)" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_mapping(t_bytes32,t_struct(Attestation)24729_storage)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => struct Attestation)", - "numberOfBytes": "32", - "value": "t_struct(Attestation)24729_storage" - }, - "t_mapping(t_bytes32,t_uint64)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => uint64)", - "numberOfBytes": "32", - "value": "t_uint64" - }, - "t_struct(Attestation)24729_storage": { - "encoding": "inplace", - "label": "struct Attestation", - "numberOfBytes": "224", - "members": [ - { - "astId": 24710, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "uid", - "offset": 0, - "slot": "0", - "type": "t_bytes32" - }, - { - "astId": 24712, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "schema", - "offset": 0, - "slot": "1", - "type": "t_bytes32" - }, - { - "astId": 24714, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "time", - "offset": 0, - "slot": "2", - "type": "t_uint64" - }, - { - "astId": 24716, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "expirationTime", - "offset": 8, - "slot": "2", - "type": "t_uint64" - }, - { - "astId": 24718, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "revocationTime", - "offset": 16, - "slot": "2", - "type": "t_uint64" - }, - { - "astId": 24720, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "refUID", - "offset": 0, - "slot": "3", - "type": "t_bytes32" - }, - { - "astId": 24722, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "recipient", - "offset": 0, - "slot": "4", - "type": "t_address" - }, - { - "astId": 24724, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "attester", - "offset": 0, - "slot": "5", - "type": "t_address" - }, - { - "astId": 24726, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "revocable", - "offset": 20, - "slot": "5", - "type": "t_bool" - }, - { - "astId": 24728, - "contract": "contracts/EAS/EAS.sol:EAS", - "label": "data", - "offset": 0, - "slot": "6", - "type": "t_bytes_storage" - } - ] - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - } - } - }, - "transactionHash": "0xb17f2eb6e221002683f7427bd2481ce78b0f82094c4eeb0e701442cba4904db5", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "attest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)))": { - "notice": "Attests to a specific schema. Example: attest({ schema: \"0facc36681cbe2456019c1b0d1e7bedd6d1d40f6f324bf3dd3a4cef2999200a0\", data: { recipient: \"0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf\", expirationTime: 0, revocable: true, refUID: \"0x0000000000000000000000000000000000000000000000000000000000000000\", data: \"0xF00D\", value: 0 } })" - }, - "attestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256),(uint8,bytes32,bytes32),address))": { - "notice": "Attests to a specific schema via the provided EIP712 signature. Example: attestByDelegation({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 0 }, signature: { v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, attester: '0xc5E8740aD971409492b1A63Db8d83025e0Fc427e' })" - }, - "getAttestTypeHash()": { - "notice": "Returns the EIP712 type hash for the attest function." - }, - "getAttestation(bytes32)": { - "notice": "Returns an existing attestation by UID." - }, - "getDomainSeparator()": { - "notice": "Returns the domain separator used in the encoding of the signatures for attest, and revoke." - }, - "getName()": { - "notice": "Returns the EIP712 name." - }, - "getNonce(address)": { - "notice": "Returns the current nonce per-account." - }, - "getRevokeOffchain(address,bytes32)": { - "notice": "Returns the timestamp that the specified data was timestamped with." - }, - "getRevokeTypeHash()": { - "notice": "Returns the EIP712 type hash for the revoke function." - }, - "getSchemaRegistry()": { - "notice": "Returns the address of the global schema registry." - }, - "getTimestamp(bytes32)": { - "notice": "Returns the timestamp that the specified data was timestamped with." - }, - "isAttestationValid(bytes32)": { - "notice": "Checks whether an attestation exists." - }, - "multiAttest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[])[])": { - "notice": "Attests to multiple schemas. Example: multiAttest([{ schema: '0x33e9094830a5cba5554d1954310e4fbed2ef5f859ec1404619adea4207f391fd', data: [{ recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 1000 }, { recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 0, revocable: false, refUID: '0x480df4a039efc31b11bfdf491b383ca138b6bde160988222a2a3509c02cee174', data: '0x00', value: 0 }], }, { schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', data: [{ recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 0, revocable: true, refUID: '0x75bf2ed8dca25a8190c50c52db136664de25b2449535839008ccfdab469b214f', data: '0x12345678', value: 0 }, }])" - }, - "multiAttestByDelegation((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[],(uint8,bytes32,bytes32)[],address)[])": { - "notice": "Attests to multiple schemas using via provided EIP712 signatures. Example: multiAttestByDelegation([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', expirationTime: 1673891048, revocable: true, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x1234', value: 0 }, { recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf', expirationTime: 0, revocable: false, refUID: '0x0000000000000000000000000000000000000000000000000000000000000000', data: '0x00', value: 0 }], signatures: [{ v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, { v: 28, r: '0x487s...67bb', s: '0x12ad...2366' }], attester: '0x1D86495b2A7B524D747d2839b3C645Bed32e8CF4' }])" - }, - "multiRevoke((bytes32,(bytes32,uint256)[])[])": { - "notice": "Revokes existing attestations to multiple schemas. Example: multiRevoke([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', value: 1000 }, { uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', value: 0 }], }, { schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425', data: [{ uid: '0x053d42abce1fd7c8fcddfae21845ad34dae287b2c326220b03ba241bc5a8f019', value: 0 }, }])" - }, - "multiRevokeByDelegation((bytes32,(bytes32,uint256)[],(uint8,bytes32,bytes32)[],address)[])": { - "notice": "Revokes existing attestations to multiple schemas via provided EIP712 signatures. Example: multiRevokeByDelegation([{ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: [{ uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25', value: 1000 }, { uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade', value: 0 }], signatures: [{ v: 28, r: '0x148c...b25b', s: '0x5a72...be22' }, { v: 28, r: '0x487s...67bb', s: '0x12ad...2366' }], revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992' }])" - }, - "multiRevokeOffchain(bytes32[])": { - "notice": "Revokes the specified multiple bytes32 data." - }, - "multiTimestamp(bytes32[])": { - "notice": "Timestamps the specified multiple bytes32 data." - }, - "revoke((bytes32,(bytes32,uint256)))": { - "notice": "Revokes an existing attestation to a specific schema. Example: revoke({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { uid: '0x101032e487642ee04ee17049f99a70590c735b8614079fc9275f9dd57c00966d', value: 0 } })" - }, - "revokeByDelegation((bytes32,(bytes32,uint256),(uint8,bytes32,bytes32),address))": { - "notice": "Revokes an existing attestation to a specific schema via the provided EIP712 signature. Example: revokeByDelegation({ schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc', data: { uid: '0xcbbc12102578c642a0f7b34fe7111e41afa25683b6cd7b5a14caf90fa14d24ba', value: 0 }, signature: { v: 27, r: '0xb593...7142', s: '0x0f5b...2cce' }, revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992' })" - }, - "revokeOffchain(bytes32)": { - "notice": "Revokes the specified bytes32 data." - }, - "timestamp(bytes32)": { - "notice": "Timestamps the specified bytes32 data." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "The Ethereum Attestation Service protocol." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/L2ERC721Bridge.json b/packages/contracts-bedrock/deployments/optimism-mainnet/L2ERC721Bridge.json deleted file mode 100644 index fe0939d45919..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/L2ERC721Bridge.json +++ /dev/null @@ -1,386 +0,0 @@ -{ - "address": "0x5a7749f83b81B301cAb5f48EB8516B986DAef23D", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_messenger", - "type": "address" - }, - { - "internalType": "address", - "name": "_otherBridge", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC721BridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC721BridgeInitiated", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC721To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "messenger", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "otherBridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x4455387bbc834a39d85d9c6d5547960d447932e163ca4f31346751845bde2d2f", - "receipt": { - "to": null, - "from": "0x53A6eecC2dD4795Fcc68940ddc6B4d53Bd88Bd9E", - "contractAddress": "0x5a7749f83b81B301cAb5f48EB8516B986DAef23D", - "transactionIndex": 0, - "gasUsed": "1344187", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x31bd7880fdc5835a924663f5f4f768fc7dde8edebab62d98d6cd9c7385f63430", - "transactionHash": "0x4455387bbc834a39d85d9c6d5547960d447932e163ca4f31346751845bde2d2f", - "logs": [], - "blockNumber": 27392732, - "cumulativeGasUsed": "1344187", - "status": 1, - "byzantium": true - }, - "args": [ - "0x4200000000000000000000000000000000000007", - "0x5a7749f83b81B301cAb5f48EB8516B986DAef23D" - ], - "numDeployments": 1, - "solcInputHash": "ab9b77493f35e63b7a63fb2fa8d618b4", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_messenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_otherBridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC721BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC721BridgeInitiated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC721To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bridgeERC721(address,address,uint256,uint32,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.\",\"_localToken\":\"Address of the ERC721 on this domain.\",\"_minGasLimit\":\"Minimum gas limit for the bridge message on the other domain.\",\"_remoteToken\":\"Address of the ERC721 on the remote domain.\",\"_tokenId\":\"Token ID to bridge.\"}},\"bridgeERC721To(address,address,address,uint256,uint32,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.\",\"_localToken\":\"Address of the ERC721 on this domain.\",\"_minGasLimit\":\"Minimum gas limit for the bridge message on the other domain.\",\"_remoteToken\":\"Address of the ERC721 on the remote domain.\",\"_to\":\"Address to receive the token on the other domain.\",\"_tokenId\":\"Token ID to bridge.\"}},\"constructor\":{\"custom:semver\":\"1.0.0\",\"params\":{\"_messenger\":\"Address of the CrossDomainMessenger on this network.\",\"_otherBridge\":\"Address of the ERC721 bridge on the other network.\"}},\"finalizeBridgeERC721(address,address,address,address,uint256,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to L1. Data supplied here will not be used to execute any code on L1 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_from\":\"Address that triggered the bridge on the other domain.\",\"_localToken\":\"Address of the ERC721 token on this domain.\",\"_remoteToken\":\"Address of the ERC721 token on the other domain.\",\"_to\":\"Address to receive the token on this domain.\",\"_tokenId\":\"ID of the token being deposited.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"L2ERC721Bridge\",\"version\":1},\"userdoc\":{\"events\":{\"ERC721BridgeFinalized(address,address,address,address,uint256,bytes)\":{\"notice\":\"Emitted when an ERC721 bridge from the other network is finalized.\"},\"ERC721BridgeInitiated(address,address,address,address,uint256,bytes)\":{\"notice\":\"Emitted when an ERC721 bridge to the other network is initiated.\"}},\"kind\":\"user\",\"methods\":{\"bridgeERC721(address,address,uint256,uint32,bytes)\":{\"notice\":\"Initiates a bridge of an NFT to the caller's account on the other chain. Note that this function can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` function after ensuring that the recipient address on the remote chain exists. Also note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\"},\"bridgeERC721To(address,address,address,uint256,uint32,bytes)\":{\"notice\":\"Initiates a bridge of an NFT to some recipient's account on the other chain. Note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\"},\"finalizeBridgeERC721(address,address,address,address,uint256,bytes)\":{\"notice\":\"Completes an ERC721 bridge from the other domain and sends the ERC721 token to the recipient on this domain.\"},\"messenger()\":{\"notice\":\"Messenger contract on this domain.\"},\"otherBridge()\":{\"notice\":\"Address of the bridge on the other network.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge. This contract also acts as a burner for tokens being withdrawn. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L2/L2ERC721Bridge.sol\":\"L2ERC721Bridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/libraries/Encoding.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Types } from \\\"./Types.sol\\\";\\nimport { Hashing } from \\\"./Hashing.sol\\\";\\nimport { RLPWriter } from \\\"./rlp/RLPWriter.sol\\\";\\n\\n/**\\n * @title Encoding\\n * @notice Encoding handles Optimism's various different encoding schemes.\\n */\\nlibrary Encoding {\\n /**\\n * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\\n * to the L2 system. Useful for searching for a deposit in the L2 system. The\\n * transaction is prefixed with 0x7e to identify its EIP-2718 type.\\n *\\n * @param _tx User deposit transaction to encode.\\n *\\n * @return RLP encoded L2 deposit transaction.\\n */\\n function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\\n internal\\n pure\\n returns (bytes memory)\\n {\\n bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\\n bytes[] memory raw = new bytes[](8);\\n raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\\n raw[1] = RLPWriter.writeAddress(_tx.from);\\n raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\\\"\\\") : RLPWriter.writeAddress(_tx.to);\\n raw[3] = RLPWriter.writeUint(_tx.mint);\\n raw[4] = RLPWriter.writeUint(_tx.value);\\n raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\\n raw[6] = RLPWriter.writeBool(false);\\n raw[7] = RLPWriter.writeBytes(_tx.data);\\n return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\\n }\\n\\n /**\\n * @notice Encodes the cross domain message based on the version that is encoded into the\\n * message nonce.\\n *\\n * @param _nonce Message nonce with version encoded into the first two bytes.\\n * @param _sender Address of the sender of the message.\\n * @param _target Address of the target of the message.\\n * @param _value ETH value to send to the target.\\n * @param _gasLimit Gas limit to use for the message.\\n * @param _data Data to send with the message.\\n *\\n * @return Encoded cross domain message.\\n */\\n function encodeCrossDomainMessage(\\n uint256 _nonce,\\n address _sender,\\n address _target,\\n uint256 _value,\\n uint256 _gasLimit,\\n bytes memory _data\\n ) internal pure returns (bytes memory) {\\n (, uint16 version) = decodeVersionedNonce(_nonce);\\n if (version == 0) {\\n return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);\\n } else if (version == 1) {\\n return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\\n } else {\\n revert(\\\"Encoding: unknown cross domain message version\\\");\\n }\\n }\\n\\n /**\\n * @notice Encodes a cross domain message based on the V0 (legacy) encoding.\\n *\\n * @param _target Address of the target of the message.\\n * @param _sender Address of the sender of the message.\\n * @param _data Data to send with the message.\\n * @param _nonce Message nonce.\\n *\\n * @return Encoded cross domain message.\\n */\\n function encodeCrossDomainMessageV0(\\n address _target,\\n address _sender,\\n bytes memory _data,\\n uint256 _nonce\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodeWithSignature(\\n \\\"relayMessage(address,address,bytes,uint256)\\\",\\n _target,\\n _sender,\\n _data,\\n _nonce\\n );\\n }\\n\\n /**\\n * @notice Encodes a cross domain message based on the V1 (current) encoding.\\n *\\n * @param _nonce Message nonce.\\n * @param _sender Address of the sender of the message.\\n * @param _target Address of the target of the message.\\n * @param _value ETH value to send to the target.\\n * @param _gasLimit Gas limit to use for the message.\\n * @param _data Data to send with the message.\\n *\\n * @return Encoded cross domain message.\\n */\\n function encodeCrossDomainMessageV1(\\n uint256 _nonce,\\n address _sender,\\n address _target,\\n uint256 _value,\\n uint256 _gasLimit,\\n bytes memory _data\\n ) internal pure returns (bytes memory) {\\n return\\n abi.encodeWithSignature(\\n \\\"relayMessage(uint256,address,address,uint256,uint256,bytes)\\\",\\n _nonce,\\n _sender,\\n _target,\\n _value,\\n _gasLimit,\\n _data\\n );\\n }\\n\\n /**\\n * @notice Adds a version number into the first two bytes of a message nonce.\\n *\\n * @param _nonce Message nonce to encode into.\\n * @param _version Version number to encode into the message nonce.\\n *\\n * @return Message nonce with version encoded into the first two bytes.\\n */\\n function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\\n uint256 nonce;\\n assembly {\\n nonce := or(shl(240, _version), _nonce)\\n }\\n return nonce;\\n }\\n\\n /**\\n * @notice Pulls the version out of a version-encoded nonce.\\n *\\n * @param _nonce Message nonce with version encoded into the first two bytes.\\n *\\n * @return Nonce without encoded version.\\n * @return Version of the message.\\n */\\n function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\\n uint240 nonce;\\n uint16 version;\\n assembly {\\n nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n version := shr(240, _nonce)\\n }\\n return (nonce, version);\\n }\\n}\\n\",\"keccak256\":\"0x170cd0821cec37976a6391da20f1dcdcb1ea9ffada96ccd3c57ff2e357589418\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/libraries/Hashing.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Types } from \\\"./Types.sol\\\";\\nimport { Encoding } from \\\"./Encoding.sol\\\";\\n\\n/**\\n * @title Hashing\\n * @notice Hashing handles Optimism's various different hashing schemes.\\n */\\nlibrary Hashing {\\n /**\\n * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\\n * given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\\n * system.\\n *\\n * @param _tx User deposit transaction to hash.\\n *\\n * @return Hash of the RLP encoded L2 deposit transaction.\\n */\\n function hashDepositTransaction(Types.UserDepositTransaction memory _tx)\\n internal\\n pure\\n returns (bytes32)\\n {\\n return keccak256(Encoding.encodeDepositTransaction(_tx));\\n }\\n\\n /**\\n * @notice Computes the deposit transaction's \\\"source hash\\\", a value that guarantees the hash\\n * of the L2 transaction that corresponds to a deposit is unique and is\\n * deterministically generated from L1 transaction data.\\n *\\n * @param _l1BlockHash Hash of the L1 block where the deposit was included.\\n * @param _logIndex The index of the log that created the deposit transaction.\\n *\\n * @return Hash of the deposit transaction's \\\"source hash\\\".\\n */\\n function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)\\n internal\\n pure\\n returns (bytes32)\\n {\\n bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\\n return keccak256(abi.encode(bytes32(0), depositId));\\n }\\n\\n /**\\n * @notice Hashes the cross domain message based on the version that is encoded into the\\n * message nonce.\\n *\\n * @param _nonce Message nonce with version encoded into the first two bytes.\\n * @param _sender Address of the sender of the message.\\n * @param _target Address of the target of the message.\\n * @param _value ETH value to send to the target.\\n * @param _gasLimit Gas limit to use for the message.\\n * @param _data Data to send with the message.\\n *\\n * @return Hashed cross domain message.\\n */\\n function hashCrossDomainMessage(\\n uint256 _nonce,\\n address _sender,\\n address _target,\\n uint256 _value,\\n uint256 _gasLimit,\\n bytes memory _data\\n ) internal pure returns (bytes32) {\\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\\n if (version == 0) {\\n return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);\\n } else if (version == 1) {\\n return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\\n } else {\\n revert(\\\"Hashing: unknown cross domain message version\\\");\\n }\\n }\\n\\n /**\\n * @notice Hashes a cross domain message based on the V0 (legacy) encoding.\\n *\\n * @param _target Address of the target of the message.\\n * @param _sender Address of the sender of the message.\\n * @param _data Data to send with the message.\\n * @param _nonce Message nonce.\\n *\\n * @return Hashed cross domain message.\\n */\\n function hashCrossDomainMessageV0(\\n address _target,\\n address _sender,\\n bytes memory _data,\\n uint256 _nonce\\n ) internal pure returns (bytes32) {\\n return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));\\n }\\n\\n /**\\n * @notice Hashes a cross domain message based on the V1 (current) encoding.\\n *\\n * @param _nonce Message nonce.\\n * @param _sender Address of the sender of the message.\\n * @param _target Address of the target of the message.\\n * @param _value ETH value to send to the target.\\n * @param _gasLimit Gas limit to use for the message.\\n * @param _data Data to send with the message.\\n *\\n * @return Hashed cross domain message.\\n */\\n function hashCrossDomainMessageV1(\\n uint256 _nonce,\\n address _sender,\\n address _target,\\n uint256 _value,\\n uint256 _gasLimit,\\n bytes memory _data\\n ) internal pure returns (bytes32) {\\n return\\n keccak256(\\n Encoding.encodeCrossDomainMessageV1(\\n _nonce,\\n _sender,\\n _target,\\n _value,\\n _gasLimit,\\n _data\\n )\\n );\\n }\\n\\n /**\\n * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\\n *\\n * @param _tx Withdrawal transaction to hash.\\n *\\n * @return Hashed withdrawal transaction.\\n */\\n function hashWithdrawal(Types.WithdrawalTransaction memory _tx)\\n internal\\n pure\\n returns (bytes32)\\n {\\n return\\n keccak256(\\n abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\\n );\\n }\\n\\n /**\\n * @notice Hashes the various elements of an output root proof into an output root hash which\\n * can be used to check if the proof is valid.\\n *\\n * @param _outputRootProof Output root proof which should hash to an output root.\\n *\\n * @return Hashed output root proof.\\n */\\n function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)\\n internal\\n pure\\n returns (bytes32)\\n {\\n return\\n keccak256(\\n abi.encode(\\n _outputRootProof.version,\\n _outputRootProof.stateRoot,\\n _outputRootProof.messagePasserStorageRoot,\\n _outputRootProof.latestBlockhash\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x5d4988987899306d2785b3de068194a39f8e829a7864762a07a0016db5189f5e\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/libraries/SafeCall.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title SafeCall\\n * @notice Perform low level safe calls\\n */\\nlibrary SafeCall {\\n /**\\n * @notice Perform a low level call without copying any returndata\\n *\\n * @param _target Address to call\\n * @param _gas Amount of gas to pass to the call\\n * @param _value Amount of value to pass to the call\\n * @param _calldata Calldata to pass to the call\\n */\\n function call(\\n address _target,\\n uint256 _gas,\\n uint256 _value,\\n bytes memory _calldata\\n ) internal returns (bool) {\\n bool _success;\\n assembly {\\n _success := call(\\n _gas, // gas\\n _target, // recipient\\n _value, // ether value\\n add(_calldata, 0x20), // inloc\\n mload(_calldata), // inlen\\n 0, // outloc\\n 0 // outlen\\n )\\n }\\n return _success;\\n }\\n}\\n\",\"keccak256\":\"0xbb0621c028c18e9d5a54cf1a8136cf2e77f161de48aeb8d911e230f6b280c9ed\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/libraries/Types.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title Types\\n * @notice Contains various types used throughout the Optimism contract system.\\n */\\nlibrary Types {\\n /**\\n * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\\n * timestamp that the output root is posted. This timestamp is used to verify that the\\n * finalization period has passed since the output root was submitted.\\n */\\n struct OutputProposal {\\n bytes32 outputRoot;\\n uint256 timestamp;\\n }\\n\\n /**\\n * @notice Struct representing the elements that are hashed together to generate an output root\\n * which itself represents a snapshot of the L2 state.\\n */\\n struct OutputRootProof {\\n bytes32 version;\\n bytes32 stateRoot;\\n bytes32 messagePasserStorageRoot;\\n bytes32 latestBlockhash;\\n }\\n\\n /**\\n * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\\n * user (as opposed to a system deposit transaction generated by the system).\\n */\\n struct UserDepositTransaction {\\n address from;\\n address to;\\n bool isCreation;\\n uint256 value;\\n uint256 mint;\\n uint64 gasLimit;\\n bytes data;\\n bytes32 l1BlockHash;\\n uint256 logIndex;\\n }\\n\\n /**\\n * @notice Struct representing a withdrawal transaction.\\n */\\n struct WithdrawalTransaction {\\n uint256 nonce;\\n address sender;\\n address target;\\n uint256 value;\\n uint256 gasLimit;\\n bytes data;\\n }\\n}\\n\",\"keccak256\":\"0x69ca98e57a7cbe60cffeb0f76f6f9279010941b1931581e9a35478f30e2546d1\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/libraries/rlp/RLPWriter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\\n * @title RLPWriter\\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\\n * RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\\n * modifications to improve legibility.\\n */\\nlibrary RLPWriter {\\n /**\\n * @notice RLP encodes a byte string.\\n *\\n * @param _in The byte string to encode.\\n *\\n * @return The RLP encoded string in bytes.\\n */\\n function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\\n bytes memory encoded;\\n\\n if (_in.length == 1 && uint8(_in[0]) < 128) {\\n encoded = _in;\\n } else {\\n encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\\n }\\n\\n return encoded;\\n }\\n\\n /**\\n * @notice RLP encodes a list of RLP encoded byte byte strings.\\n *\\n * @param _in The list of RLP encoded byte strings.\\n *\\n * @return The RLP encoded list of items in bytes.\\n */\\n function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\\n bytes memory list = _flatten(_in);\\n return abi.encodePacked(_writeLength(list.length, 192), list);\\n }\\n\\n /**\\n * @notice RLP encodes a string.\\n *\\n * @param _in The string to encode.\\n *\\n * @return The RLP encoded string in bytes.\\n */\\n function writeString(string memory _in) internal pure returns (bytes memory) {\\n return writeBytes(bytes(_in));\\n }\\n\\n /**\\n * @notice RLP encodes an address.\\n *\\n * @param _in The address to encode.\\n *\\n * @return The RLP encoded address in bytes.\\n */\\n function writeAddress(address _in) internal pure returns (bytes memory) {\\n return writeBytes(abi.encodePacked(_in));\\n }\\n\\n /**\\n * @notice RLP encodes a uint.\\n *\\n * @param _in The uint256 to encode.\\n *\\n * @return The RLP encoded uint256 in bytes.\\n */\\n function writeUint(uint256 _in) internal pure returns (bytes memory) {\\n return writeBytes(_toBinary(_in));\\n }\\n\\n /**\\n * @notice RLP encodes a bool.\\n *\\n * @param _in The bool to encode.\\n *\\n * @return The RLP encoded bool in bytes.\\n */\\n function writeBool(bool _in) internal pure returns (bytes memory) {\\n bytes memory encoded = new bytes(1);\\n encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\\n return encoded;\\n }\\n\\n /**\\n * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\\n *\\n * @param _len The length of the string or the payload.\\n * @param _offset 128 if item is string, 192 if item is list.\\n *\\n * @return RLP encoded bytes.\\n */\\n function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\\n bytes memory encoded;\\n\\n if (_len < 56) {\\n encoded = new bytes(1);\\n encoded[0] = bytes1(uint8(_len) + uint8(_offset));\\n } else {\\n uint256 lenLen;\\n uint256 i = 1;\\n while (_len / i != 0) {\\n lenLen++;\\n i *= 256;\\n }\\n\\n encoded = new bytes(lenLen + 1);\\n encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\\n for (i = 1; i <= lenLen; i++) {\\n encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\\n }\\n }\\n\\n return encoded;\\n }\\n\\n /**\\n * @notice Encode integer in big endian binary form with no leading zeroes.\\n *\\n * @param _x The integer to encode.\\n *\\n * @return RLP encoded bytes.\\n */\\n function _toBinary(uint256 _x) private pure returns (bytes memory) {\\n bytes memory b = abi.encodePacked(_x);\\n\\n uint256 i = 0;\\n for (; i < 32; i++) {\\n if (b[i] != 0) {\\n break;\\n }\\n }\\n\\n bytes memory res = new bytes(32 - i);\\n for (uint256 j = 0; j < res.length; j++) {\\n res[j] = b[i++];\\n }\\n\\n return res;\\n }\\n\\n /**\\n * @custom:attribution https://github.com/Arachnid/solidity-stringutils\\n * @notice Copies a piece of memory to another location.\\n *\\n * @param _dest Destination location.\\n * @param _src Source location.\\n * @param _len Length of memory to copy.\\n */\\n function _memcpy(\\n uint256 _dest,\\n uint256 _src,\\n uint256 _len\\n ) private pure {\\n uint256 dest = _dest;\\n uint256 src = _src;\\n uint256 len = _len;\\n\\n for (; len >= 32; len -= 32) {\\n assembly {\\n mstore(dest, mload(src))\\n }\\n dest += 32;\\n src += 32;\\n }\\n\\n uint256 mask;\\n unchecked {\\n mask = 256**(32 - len) - 1;\\n }\\n assembly {\\n let srcpart := and(mload(src), not(mask))\\n let destpart := and(mload(dest), mask)\\n mstore(dest, or(destpart, srcpart))\\n }\\n }\\n\\n /**\\n * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\\n * @notice Flattens a list of byte strings into one byte string.\\n *\\n * @param _list List of byte strings to flatten.\\n *\\n * @return The flattened byte string.\\n */\\n function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\\n if (_list.length == 0) {\\n return new bytes(0);\\n }\\n\\n uint256 len;\\n uint256 i = 0;\\n for (; i < _list.length; i++) {\\n len += _list[i].length;\\n }\\n\\n bytes memory flattened = new bytes(len);\\n uint256 flattenedPtr;\\n assembly {\\n flattenedPtr := add(flattened, 0x20)\\n }\\n\\n for (i = 0; i < _list.length; i++) {\\n bytes memory item = _list[i];\\n\\n uint256 listPtr;\\n assembly {\\n listPtr := add(item, 0x20)\\n }\\n\\n _memcpy(flattenedPtr, listPtr, item.length);\\n flattenedPtr += _list[i].length;\\n }\\n\\n return flattened;\\n }\\n}\\n\",\"keccak256\":\"0x5aa9d21c5b41c9786f23153f819d561ae809a1d55c7b0d423dfeafdfbacedc78\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/universal/CrossDomainMessenger.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport {\\n OwnableUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {\\n PausableUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport { SafeCall } from \\\"../libraries/SafeCall.sol\\\";\\nimport { Hashing } from \\\"../libraries/Hashing.sol\\\";\\nimport { Encoding } from \\\"../libraries/Encoding.sol\\\";\\n\\n/**\\n * @custom:legacy\\n * @title CrossDomainMessengerLegacySpacer\\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\\n * libAddressManager variable used to exist. Must be the first contract in the inheritance\\n * tree of the CrossDomainMessenger\\n */\\ncontract CrossDomainMessengerLegacySpacer {\\n /**\\n * @custom:legacy\\n * @custom:spacer libAddressManager\\n * @notice Spacer for backwards compatibility.\\n */\\n address private spacer_0_0_20;\\n}\\n\\n/**\\n * @custom:upgradeable\\n * @title CrossDomainMessenger\\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\\n * cross-chain messenger contracts. It's designed to be a universal interface that only\\n * needs to be extended slightly to provide low-level message passing functionality on each\\n * chain it's deployed on. Currently only designed for message passing between two paired\\n * chains and does not support one-to-many interactions.\\n */\\nabstract contract CrossDomainMessenger is\\n CrossDomainMessengerLegacySpacer,\\n OwnableUpgradeable,\\n PausableUpgradeable,\\n ReentrancyGuardUpgradeable\\n{\\n /**\\n * @notice Current message version identifier.\\n */\\n uint16 public constant MESSAGE_VERSION = 1;\\n\\n /**\\n * @notice Constant overhead added to the base gas for a message.\\n */\\n uint32 public constant MIN_GAS_CONSTANT_OVERHEAD = 200_000;\\n\\n /**\\n * @notice Numerator for dynamic overhead added to the base gas for a message.\\n */\\n uint32 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 1016;\\n\\n /**\\n * @notice Denominator for dynamic overhead added to the base gas for a message.\\n */\\n uint32 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 1000;\\n\\n /**\\n * @notice Extra gas added to base gas for each byte of calldata in a message.\\n */\\n uint32 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\\n\\n /**\\n * @notice Minimum amount of gas required to relay a message.\\n */\\n uint256 internal constant RELAY_GAS_REQUIRED = 45_000;\\n\\n /**\\n * @notice Amount of gas held in reserve to guarantee that relay execution completes.\\n */\\n uint256 internal constant RELAY_GAS_BUFFER = RELAY_GAS_REQUIRED - 5000;\\n\\n /**\\n * @notice Initial value for the xDomainMsgSender variable. We set this to a non-zero value\\n * because performing an SSTORE on a non-zero value is significantly cheaper than on a\\n * zero value.\\n */\\n address internal constant DEFAULT_XDOMAIN_SENDER = 0x000000000000000000000000000000000000dEaD;\\n\\n /**\\n * @notice Address of the paired CrossDomainMessenger contract on the other chain.\\n */\\n address public immutable otherMessenger;\\n\\n /**\\n * @custom:legacy\\n * @custom:spacer blockedMessages\\n * @notice Spacer for backwards compatibility.\\n */\\n mapping(bytes32 => bool) private spacer_201_0_32;\\n\\n /**\\n * @custom:legacy\\n * @custom:spacer relayedMessages\\n * @notice Spacer for backwards compatibility.\\n */\\n mapping(bytes32 => bool) private spacer_202_0_32;\\n\\n /**\\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\\n * be present in this mapping if it has successfully been relayed on this chain, and\\n * can therefore not be relayed again.\\n */\\n mapping(bytes32 => bool) public successfulMessages;\\n\\n /**\\n * @notice Address of the sender of the currently executing message on the other chain. If the\\n * value of this variable is the default value (0x00000000...dead) then no message is\\n * currently being executed. Use the xDomainMessageSender getter which will throw an\\n * error if this is the case.\\n */\\n address internal xDomainMsgSender;\\n\\n /**\\n * @notice Nonce for the next message to be sent, without the message version applied. Use the\\n * messageNonce getter which will insert the message version into the nonce to give you\\n * the actual nonce to be used for the message.\\n */\\n uint240 internal msgNonce;\\n\\n /**\\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\\n * be present in this mapping if it failed to be relayed on this chain at least once.\\n * If a message is successfully relayed on the first attempt, then it will only be\\n * present within the successfulMessages mapping.\\n */\\n mapping(bytes32 => bool) public receivedMessages;\\n\\n /**\\n * @notice Reserve extra slots in the storage layout for future upgrades.\\n * A gap size of 41 was chosen here, so that the first slot used in a child contract\\n * would be a multiple of 50.\\n */\\n uint256[42] private __gap;\\n\\n /**\\n * @notice Emitted whenever a message is sent to the other chain.\\n *\\n * @param target Address of the recipient of the message.\\n * @param sender Address of the sender of the message.\\n * @param message Message to trigger the recipient address with.\\n * @param messageNonce Unique nonce attached to the message.\\n * @param gasLimit Minimum gas limit that the message can be executed with.\\n */\\n event SentMessage(\\n address indexed target,\\n address sender,\\n bytes message,\\n uint256 messageNonce,\\n uint256 gasLimit\\n );\\n\\n /**\\n * @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the\\n * SentMessage event without breaking the ABI of this contract, this is good enough.\\n *\\n * @param sender Address of the sender of the message.\\n * @param value ETH value sent along with the message to the recipient.\\n */\\n event SentMessageExtension1(address indexed sender, uint256 value);\\n\\n /**\\n * @notice Emitted whenever a message is successfully relayed on this chain.\\n *\\n * @param msgHash Hash of the message that was relayed.\\n */\\n event RelayedMessage(bytes32 indexed msgHash);\\n\\n /**\\n * @notice Emitted whenever a message fails to be relayed on this chain.\\n *\\n * @param msgHash Hash of the message that failed to be relayed.\\n */\\n event FailedRelayedMessage(bytes32 indexed msgHash);\\n\\n /**\\n * @param _otherMessenger Address of the messenger on the paired chain.\\n */\\n constructor(address _otherMessenger) {\\n otherMessenger = _otherMessenger;\\n }\\n\\n /**\\n * @notice Allows the owner of this contract to temporarily pause message relaying. Backup\\n * security mechanism just in case. Owner should be the same as the upgrade wallet to\\n * maintain the security model of the system as a whole.\\n */\\n function pause() external onlyOwner {\\n _pause();\\n }\\n\\n /**\\n * @notice Allows the owner of this contract to resume message relaying once paused.\\n */\\n function unpause() external onlyOwner {\\n _unpause();\\n }\\n\\n /**\\n * @notice Sends a message to some target address on the other chain. Note that if the call\\n * always reverts, then the message will be unrelayable, and any ETH sent will be\\n * permanently locked. The same will occur if the target on the other chain is\\n * considered unsafe (see the _isUnsafeTarget() function).\\n *\\n * @param _target Target contract or wallet address.\\n * @param _message Message to trigger the target address with.\\n * @param _minGasLimit Minimum gas limit that the message can be executed with.\\n */\\n function sendMessage(\\n address _target,\\n bytes calldata _message,\\n uint32 _minGasLimit\\n ) external payable {\\n // Triggers a message to the other messenger. Note that the amount of gas provided to the\\n // message is the amount of gas requested by the user PLUS the base gas value. We want to\\n // guarantee the property that the call to the target contract will always have at least\\n // the minimum gas limit specified by the user.\\n _sendMessage(\\n otherMessenger,\\n baseGas(_message, _minGasLimit),\\n msg.value,\\n abi.encodeWithSelector(\\n this.relayMessage.selector,\\n messageNonce(),\\n msg.sender,\\n _target,\\n msg.value,\\n _minGasLimit,\\n _message\\n )\\n );\\n\\n emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit);\\n emit SentMessageExtension1(msg.sender, msg.value);\\n\\n unchecked {\\n ++msgNonce;\\n }\\n }\\n\\n /**\\n * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\\n * be executed via cross-chain call from the other messenger OR if the message was\\n * already received once and is currently being replayed.\\n *\\n * @param _nonce Nonce of the message being relayed.\\n * @param _sender Address of the user who sent the message.\\n * @param _target Address that the message is targeted at.\\n * @param _value ETH value to send with the message.\\n * @param _minGasLimit Minimum amount of gas that the message can be executed with.\\n * @param _message Message to send to the target.\\n */\\n function relayMessage(\\n uint256 _nonce,\\n address _sender,\\n address _target,\\n uint256 _value,\\n uint256 _minGasLimit,\\n bytes calldata _message\\n ) external payable nonReentrant whenNotPaused {\\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\\n\\n // Block any messages that aren't version 1. All version 0 messages have been guaranteed to\\n // be relayed OR have been migrated to version 1 messages. Version 0 messages do not commit\\n // to the value or minGasLimit fields, which can create unexpected issues for end-users.\\n require(\\n version == 1,\\n \\\"CrossDomainMessenger: only version 1 messages are supported after the Bedrock upgrade\\\"\\n );\\n\\n bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(\\n _nonce,\\n _sender,\\n _target,\\n _value,\\n _minGasLimit,\\n _message\\n );\\n\\n if (_isOtherMessenger()) {\\n // This property should always hold when the message is first submitted (as opposed to\\n // being replayed).\\n assert(msg.value == _value);\\n } else {\\n require(\\n msg.value == 0,\\n \\\"CrossDomainMessenger: value must be zero unless message is from a system address\\\"\\n );\\n\\n require(\\n receivedMessages[versionedHash],\\n \\\"CrossDomainMessenger: message cannot be replayed\\\"\\n );\\n }\\n\\n require(\\n _isUnsafeTarget(_target) == false,\\n \\\"CrossDomainMessenger: cannot send message to blocked system address\\\"\\n );\\n\\n require(\\n successfulMessages[versionedHash] == false,\\n \\\"CrossDomainMessenger: message has already been relayed\\\"\\n );\\n\\n require(\\n gasleft() >= _minGasLimit + RELAY_GAS_REQUIRED,\\n \\\"CrossDomainMessenger: insufficient gas to relay message\\\"\\n );\\n\\n xDomainMsgSender = _sender;\\n bool success = SafeCall.call(_target, gasleft() - RELAY_GAS_BUFFER, _value, _message);\\n xDomainMsgSender = DEFAULT_XDOMAIN_SENDER;\\n\\n if (success == true) {\\n successfulMessages[versionedHash] = true;\\n emit RelayedMessage(versionedHash);\\n } else {\\n receivedMessages[versionedHash] = true;\\n emit FailedRelayedMessage(versionedHash);\\n }\\n }\\n\\n /**\\n * @notice Retrieves the address of the contract or wallet that initiated the currently\\n * executing message on the other chain. Will throw an error if there is no message\\n * currently being executed. Allows the recipient of a call to see who triggered it.\\n *\\n * @return Address of the sender of the currently executing message on the other chain.\\n */\\n function xDomainMessageSender() external view returns (address) {\\n require(\\n xDomainMsgSender != DEFAULT_XDOMAIN_SENDER,\\n \\\"CrossDomainMessenger: xDomainMessageSender is not set\\\"\\n );\\n\\n return xDomainMsgSender;\\n }\\n\\n /**\\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\\n * bytes of the message nonce. Message version allows us to treat messages as having\\n * different structures.\\n *\\n * @return Nonce of the next message to be sent, with added message version.\\n */\\n function messageNonce() public view returns (uint256) {\\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\\n }\\n\\n /**\\n * @notice Computes the amount of gas required to guarantee that a given message will be\\n * received on the other chain without running out of gas. Guaranteeing that a message\\n * will not run out of gas is important because this ensures that a message can always\\n * be replayed on the other chain if it fails to execute completely.\\n *\\n * @param _message Message to compute the amount of required gas for.\\n * @param _minGasLimit Minimum desired gas limit when message goes to target.\\n *\\n * @return Amount of gas required to guarantee message receipt.\\n */\\n function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint32) {\\n return\\n // Dynamic overhead\\n ((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\\n MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\\n // Calldata overhead\\n (uint32(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\\n // Constant overhead\\n MIN_GAS_CONSTANT_OVERHEAD;\\n }\\n\\n /**\\n * @notice Intializer.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function __CrossDomainMessenger_init() internal onlyInitializing {\\n xDomainMsgSender = DEFAULT_XDOMAIN_SENDER;\\n __Context_init_unchained();\\n __Ownable_init_unchained();\\n __Pausable_init_unchained();\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n /**\\n * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\\n * contracts because the logic for this depends on the network where the messenger is\\n * being deployed.\\n *\\n * @param _to Recipient of the message on the other chain.\\n * @param _gasLimit Minimum gas limit the message can be executed with.\\n * @param _value Amount of ETH to send with the message.\\n * @param _data Message data.\\n */\\n function _sendMessage(\\n address _to,\\n uint64 _gasLimit,\\n uint256 _value,\\n bytes memory _data\\n ) internal virtual;\\n\\n /**\\n * @notice Checks whether the message is coming from the other messenger. Implemented by child\\n * contracts because the logic for this depends on the network where the messenger is\\n * being deployed.\\n *\\n * @return Whether the message is coming from the other messenger.\\n */\\n function _isOtherMessenger() internal view virtual returns (bool);\\n\\n /**\\n * @notice Checks whether a given call target is a system address that could cause the\\n * messenger to peform an unsafe action. This is NOT a mechanism for blocking user\\n * addresses. This is ONLY used to prevent the execution of messages to specific\\n * system addresses that could cause security issues, e.g., having the\\n * CrossDomainMessenger send messages to itself.\\n *\\n * @param _target Address of the contract to check.\\n *\\n * @return Whether or not the address is an unsafe system address.\\n */\\n function _isUnsafeTarget(address _target) internal view virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xead7d44e99f3749f1f45e3f70496c27c2d56e532835c13d02b43ee0d8ff1d593\",\"license\":\"MIT\"},\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.15;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x8215e8fbaace5e06fdf0be26cd8ec224847cf03e89bd78dc8ba3ec2cb429d4fe\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n function __Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __Pausable_init_unchained() internal onlyInitializing {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n require(!paused(), \\\"Pausable: paused\\\");\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n require(paused(), \\\"Pausable: not paused\\\");\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x40c636b4572ff5f1dc50cf22097e93c0723ee14eff87e99ac2b02636eeca1250\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x8cc03c5ac17e8a7396e487cda41fc1f1dfdb91db7d528e6da84bee3b6dd7e167\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x0d4de01fe5360c38b4ad2b0822a12722958428f5138a7ff47c1720eb6fa52bba\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x32c202bd28995dd20c4347b7c6467a6d3241c74c8ad3edcbb610cd9205916c45\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Checker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Library used to query support of an interface declared via {IERC165}.\\n *\\n * Note that these functions return the actual result of the query: they do not\\n * `revert` if an interface is not supported. It is up to the caller to decide\\n * what to do in these cases.\\n */\\nlibrary ERC165Checker {\\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\\n\\n /**\\n * @dev Returns true if `account` supports the {IERC165} interface,\\n */\\n function supportsERC165(address account) internal view returns (bool) {\\n // Any contract that implements ERC165 must explicitly indicate support of\\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\\n return\\n _supportsERC165Interface(account, type(IERC165).interfaceId) &&\\n !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);\\n }\\n\\n /**\\n * @dev Returns true if `account` supports the interface defined by\\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\\n *\\n * See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\\n // query support of both ERC165 as per the spec and support of _interfaceId\\n return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);\\n }\\n\\n /**\\n * @dev Returns a boolean array where each value corresponds to the\\n * interfaces passed in and whether they're supported or not. This allows\\n * you to batch check interfaces for a contract where your expectation\\n * is that some interfaces may not be supported.\\n *\\n * See {IERC165-supportsInterface}.\\n *\\n * _Available since v3.4._\\n */\\n function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)\\n internal\\n view\\n returns (bool[] memory)\\n {\\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\\n\\n // query support of ERC165 itself\\n if (supportsERC165(account)) {\\n // query support of each interface in interfaceIds\\n for (uint256 i = 0; i < interfaceIds.length; i++) {\\n interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);\\n }\\n }\\n\\n return interfaceIdsSupported;\\n }\\n\\n /**\\n * @dev Returns true if `account` supports all the interfaces defined in\\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\\n *\\n * Batch-querying can lead to gas savings by skipping repeated checks for\\n * {IERC165} support.\\n *\\n * See {IERC165-supportsInterface}.\\n */\\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\\n // query support of ERC165 itself\\n if (!supportsERC165(account)) {\\n return false;\\n }\\n\\n // query support of each interface in _interfaceIds\\n for (uint256 i = 0; i < interfaceIds.length; i++) {\\n if (!_supportsERC165Interface(account, interfaceIds[i])) {\\n return false;\\n }\\n }\\n\\n // all interfaces supported\\n return true;\\n }\\n\\n /**\\n * @notice Query if a contract implements an interface, does not check ERC165 support\\n * @param account The address of the contract to query for support of an interface\\n * @param interfaceId The interface identifier, as specified in ERC-165\\n * @return true if the contract at account indicates support of the interface with\\n * identifier interfaceId, false otherwise\\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\\n * the behavior of this method is undefined. This precondition can be checked\\n * with {supportsERC165}.\\n * Interface identification is specified in ERC-165.\\n */\\n function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {\\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\\n (bool success, bytes memory result) = account.staticcall{gas: 30000}(encodedParams);\\n if (result.length < 32) return false;\\n return success && abi.decode(result, (bool));\\n }\\n}\\n\",\"keccak256\":\"0xf7291d7213336b00ee7edbf7cd5034778dd7b0bda2a7489e664f1e5cacc6c24e\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/L1/L1ERC721Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { ERC721Bridge } from \\\"../universal/op-erc721/ERC721Bridge.sol\\\";\\nimport { IERC721 } from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport { L2ERC721Bridge } from \\\"../L2/L2ERC721Bridge.sol\\\";\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title L1ERC721Bridge\\n * @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to\\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\\n * acts as an escrow for ERC721 tokens deposited into L2.\\n */\\ncontract L1ERC721Bridge is ERC721Bridge, Semver {\\n /**\\n * @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token\\n * by ID was deposited for a given L2 token.\\n */\\n mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;\\n\\n /**\\n * @custom:semver 1.0.0\\n *\\n * @param _messenger Address of the CrossDomainMessenger on this network.\\n * @param _otherBridge Address of the ERC721 bridge on the other network.\\n */\\n constructor(address _messenger, address _otherBridge)\\n Semver(1, 0, 0)\\n ERC721Bridge(_messenger, _otherBridge)\\n {}\\n\\n /*************************\\n * Cross-chain Functions *\\n *************************/\\n\\n /**\\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\\n * recipient on this domain.\\n *\\n * @param _localToken Address of the ERC721 token on this domain.\\n * @param _remoteToken Address of the ERC721 token on the other domain.\\n * @param _from Address that triggered the bridge on the other domain.\\n * @param _to Address to receive the token on this domain.\\n * @param _tokenId ID of the token being deposited.\\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\\n * execute any code on L2 and is only emitted as extra data for the\\n * convenience of off-chain tooling.\\n */\\n function finalizeBridgeERC721(\\n address _localToken,\\n address _remoteToken,\\n address _from,\\n address _to,\\n uint256 _tokenId,\\n bytes calldata _extraData\\n ) external onlyOtherBridge {\\n require(_localToken != address(this), \\\"L1ERC721Bridge: local token cannot be self\\\");\\n\\n // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.\\n require(\\n deposits[_localToken][_remoteToken][_tokenId] == true,\\n \\\"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\\\"\\n );\\n\\n // Mark that the token ID for this L1/L2 token pair is no longer escrowed in the L1\\n // Bridge.\\n deposits[_localToken][_remoteToken][_tokenId] = false;\\n\\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the\\n // withdrawer.\\n IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId);\\n\\n // slither-disable-next-line reentrancy-events\\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\\n }\\n\\n /**\\n * @inheritdoc ERC721Bridge\\n */\\n function _initiateBridgeERC721(\\n address _localToken,\\n address _remoteToken,\\n address _from,\\n address _to,\\n uint256 _tokenId,\\n uint32 _minGasLimit,\\n bytes calldata _extraData\\n ) internal override {\\n require(_remoteToken != address(0), \\\"ERC721Bridge: remote token cannot be address(0)\\\");\\n\\n // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)\\n bytes memory message = abi.encodeWithSelector(\\n L2ERC721Bridge.finalizeBridgeERC721.selector,\\n _remoteToken,\\n _localToken,\\n _from,\\n _to,\\n _tokenId,\\n _extraData\\n );\\n\\n // Lock token into bridge\\n deposits[_localToken][_remoteToken][_tokenId] = true;\\n IERC721(_localToken).transferFrom(_from, address(this), _tokenId);\\n\\n // Send calldata into L2\\n messenger.sendMessage(otherBridge, message, _minGasLimit);\\n emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\\n }\\n}\\n\",\"keccak256\":\"0x966ae750603761f5636063e4d1441759bd7e140ba933303d31c62220e75c8869\",\"license\":\"MIT\"},\"contracts/L2/L2ERC721Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { ERC721Bridge } from \\\"../universal/op-erc721/ERC721Bridge.sol\\\";\\nimport { ERC165Checker } from \\\"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\\\";\\nimport { L1ERC721Bridge } from \\\"../L1/L1ERC721Bridge.sol\\\";\\nimport { IOptimismMintableERC721 } from \\\"../universal/op-erc721/IOptimismMintableERC721.sol\\\";\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title L2ERC721Bridge\\n * @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to\\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\\n * acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.\\n * This contract also acts as a burner for tokens being withdrawn.\\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\\n * bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to\\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\\n * can be refunded on L2.\\n */\\ncontract L2ERC721Bridge is ERC721Bridge, Semver {\\n /**\\n * @custom:semver 1.0.0\\n *\\n * @param _messenger Address of the CrossDomainMessenger on this network.\\n * @param _otherBridge Address of the ERC721 bridge on the other network.\\n */\\n constructor(address _messenger, address _otherBridge)\\n Semver(1, 0, 0)\\n ERC721Bridge(_messenger, _otherBridge)\\n {}\\n\\n /**\\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\\n * recipient on this domain.\\n *\\n * @param _localToken Address of the ERC721 token on this domain.\\n * @param _remoteToken Address of the ERC721 token on the other domain.\\n * @param _from Address that triggered the bridge on the other domain.\\n * @param _to Address to receive the token on this domain.\\n * @param _tokenId ID of the token being deposited.\\n * @param _extraData Optional data to forward to L1. Data supplied here will not be used to\\n * execute any code on L1 and is only emitted as extra data for the\\n * convenience of off-chain tooling.\\n */\\n function finalizeBridgeERC721(\\n address _localToken,\\n address _remoteToken,\\n address _from,\\n address _to,\\n uint256 _tokenId,\\n bytes calldata _extraData\\n ) external onlyOtherBridge {\\n require(_localToken != address(this), \\\"L2ERC721Bridge: local token cannot be self\\\");\\n\\n // Note that supportsInterface makes a callback to the _localToken address which is user\\n // provided.\\n require(\\n ERC165Checker.supportsInterface(_localToken, type(IOptimismMintableERC721).interfaceId),\\n \\\"L2ERC721Bridge: local token interface is not compliant\\\"\\n );\\n\\n require(\\n _remoteToken == IOptimismMintableERC721(_localToken).remoteToken(),\\n \\\"L2ERC721Bridge: wrong remote token for Optimism Mintable ERC721 local token\\\"\\n );\\n\\n // When a deposit is finalized, we give the NFT with the same tokenId to the account\\n // on L2. Note that safeMint makes a callback to the _to address which is user provided.\\n IOptimismMintableERC721(_localToken).safeMint(_to, _tokenId);\\n\\n // slither-disable-next-line reentrancy-events\\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\\n }\\n\\n /**\\n * @inheritdoc ERC721Bridge\\n */\\n function _initiateBridgeERC721(\\n address _localToken,\\n address _remoteToken,\\n address _from,\\n address _to,\\n uint256 _tokenId,\\n uint32 _minGasLimit,\\n bytes calldata _extraData\\n ) internal override {\\n require(_remoteToken != address(0), \\\"ERC721Bridge: remote token cannot be address(0)\\\");\\n\\n // Check that the withdrawal is being initiated by the NFT owner\\n require(\\n _from == IOptimismMintableERC721(_localToken).ownerOf(_tokenId),\\n \\\"Withdrawal is not being initiated by NFT owner\\\"\\n );\\n\\n // Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)\\n // slither-disable-next-line reentrancy-events\\n address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();\\n require(\\n remoteToken == _remoteToken,\\n \\\"L2ERC721Bridge: remote token does not match given value\\\"\\n );\\n\\n // When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2\\n // usage\\n // slither-disable-next-line reentrancy-events\\n IOptimismMintableERC721(_localToken).burn(_from, _tokenId);\\n\\n bytes memory message = abi.encodeWithSelector(\\n L1ERC721Bridge.finalizeBridgeERC721.selector,\\n remoteToken,\\n _localToken,\\n _from,\\n _to,\\n _tokenId,\\n _extraData\\n );\\n\\n // Send message to L1 bridge\\n // slither-disable-next-line reentrancy-events\\n messenger.sendMessage(otherBridge, message, _minGasLimit);\\n\\n // slither-disable-next-line reentrancy-events\\n emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData);\\n }\\n}\\n\",\"keccak256\":\"0xedcf2403f87c8c72790c053b44ccd762e99f5cdf0f362123288d6893b4c856b5\",\"license\":\"MIT\"},\"contracts/universal/op-erc721/ERC721Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport {\\n CrossDomainMessenger\\n} from \\\"@eth-optimism/contracts-bedrock/contracts/universal/CrossDomainMessenger.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\n/**\\n * @title ERC721Bridge\\n * @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.\\n */\\nabstract contract ERC721Bridge {\\n /**\\n * @notice Emitted when an ERC721 bridge to the other network is initiated.\\n *\\n * @param localToken Address of the token on this domain.\\n * @param remoteToken Address of the token on the remote domain.\\n * @param from Address that initiated bridging action.\\n * @param to Address to receive the token.\\n * @param tokenId ID of the specific token deposited.\\n * @param extraData Extra data for use on the client-side.\\n */\\n event ERC721BridgeInitiated(\\n address indexed localToken,\\n address indexed remoteToken,\\n address indexed from,\\n address to,\\n uint256 tokenId,\\n bytes extraData\\n );\\n\\n /**\\n * @notice Emitted when an ERC721 bridge from the other network is finalized.\\n *\\n * @param localToken Address of the token on this domain.\\n * @param remoteToken Address of the token on the remote domain.\\n * @param from Address that initiated bridging action.\\n * @param to Address to receive the token.\\n * @param tokenId ID of the specific token deposited.\\n * @param extraData Extra data for use on the client-side.\\n */\\n event ERC721BridgeFinalized(\\n address indexed localToken,\\n address indexed remoteToken,\\n address indexed from,\\n address to,\\n uint256 tokenId,\\n bytes extraData\\n );\\n\\n /**\\n * @notice Messenger contract on this domain.\\n */\\n CrossDomainMessenger public immutable messenger;\\n\\n /**\\n * @notice Address of the bridge on the other network.\\n */\\n address public immutable otherBridge;\\n\\n /**\\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\\n */\\n uint256[49] private __gap;\\n\\n /**\\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\\n */\\n modifier onlyOtherBridge() {\\n require(\\n msg.sender == address(messenger) && messenger.xDomainMessageSender() == otherBridge,\\n \\\"ERC721Bridge: function can only be called from the other bridge\\\"\\n );\\n _;\\n }\\n\\n /**\\n * @param _messenger Address of the CrossDomainMessenger on this network.\\n * @param _otherBridge Address of the ERC721 bridge on the other network.\\n */\\n constructor(address _messenger, address _otherBridge) {\\n require(_messenger != address(0), \\\"ERC721Bridge: messenger cannot be address(0)\\\");\\n require(_otherBridge != address(0), \\\"ERC721Bridge: other bridge cannot be address(0)\\\");\\n\\n messenger = CrossDomainMessenger(_messenger);\\n otherBridge = _otherBridge;\\n }\\n\\n /**\\n * @notice Initiates a bridge of an NFT to the caller's account on the other chain. Note that\\n * this function can only be called by EOAs. Smart contract wallets should use the\\n * `bridgeERC721To` function after ensuring that the recipient address on the remote\\n * chain exists. Also note that the current owner of the token on this chain must\\n * approve this contract to operate the NFT before it can be bridged.\\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\\n * can be refunded on L2.\\n *\\n * @param _localToken Address of the ERC721 on this domain.\\n * @param _remoteToken Address of the ERC721 on the remote domain.\\n * @param _tokenId Token ID to bridge.\\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\\n * be used to execute any code on the other chain and is only emitted as\\n * extra data for the convenience of off-chain tooling.\\n */\\n function bridgeERC721(\\n address _localToken,\\n address _remoteToken,\\n uint256 _tokenId,\\n uint32 _minGasLimit,\\n bytes calldata _extraData\\n ) external {\\n // Modifier requiring sender to be EOA. This prevents against a user error that would occur\\n // if the sender is a smart contract wallet that has a different address on the remote chain\\n // (or doesn't have an address on the remote chain at all). The user would fail to receive\\n // the NFT if they use this function because it sends the NFT to the same address as the\\n // caller. This check could be bypassed by a malicious contract via initcode, but it takes\\n // care of the user error we want to avoid.\\n require(!Address.isContract(msg.sender), \\\"ERC721Bridge: account is not externally owned\\\");\\n\\n _initiateBridgeERC721(\\n _localToken,\\n _remoteToken,\\n msg.sender,\\n msg.sender,\\n _tokenId,\\n _minGasLimit,\\n _extraData\\n );\\n }\\n\\n /**\\n * @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note\\n * that the current owner of the token on this chain must approve this contract to\\n * operate the NFT before it can be bridged.\\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\\n * can be refunded on L2.\\n *\\n * @param _localToken Address of the ERC721 on this domain.\\n * @param _remoteToken Address of the ERC721 on the remote domain.\\n * @param _to Address to receive the token on the other domain.\\n * @param _tokenId Token ID to bridge.\\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\\n * be used to execute any code on the other chain and is only emitted as\\n * extra data for the convenience of off-chain tooling.\\n */\\n function bridgeERC721To(\\n address _localToken,\\n address _remoteToken,\\n address _to,\\n uint256 _tokenId,\\n uint32 _minGasLimit,\\n bytes calldata _extraData\\n ) external {\\n require(_to != address(0), \\\"ERC721Bridge: nft recipient cannot be address(0)\\\");\\n\\n _initiateBridgeERC721(\\n _localToken,\\n _remoteToken,\\n msg.sender,\\n _to,\\n _tokenId,\\n _minGasLimit,\\n _extraData\\n );\\n }\\n\\n /**\\n * @notice Internal function for initiating a token bridge to the other domain.\\n *\\n * @param _localToken Address of the ERC721 on this domain.\\n * @param _remoteToken Address of the ERC721 on the remote domain.\\n * @param _from Address of the sender on this domain.\\n * @param _to Address to receive the token on the other domain.\\n * @param _tokenId Token ID to bridge.\\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\\n * @param _extraData Optional data to forward to the other domain. Data supplied here will\\n * not be used to execute any code on the other domain and is only emitted\\n * as extra data for the convenience of off-chain tooling.\\n */\\n function _initiateBridgeERC721(\\n address _localToken,\\n address _remoteToken,\\n address _from,\\n address _to,\\n uint256 _tokenId,\\n uint32 _minGasLimit,\\n bytes calldata _extraData\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x24898e2e75865a4e35cde2d62518cb4c15a30b7cdae8a1a37624a82ae2a26eb7\",\"license\":\"MIT\"},\"contracts/universal/op-erc721/IOptimismMintableERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {\\n IERC721Enumerable\\n} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\n\\n/**\\n * @title IOptimismMintableERC721\\n * @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.\\n * Tokens that follow this standard can be easily transferred across the ERC721 bridge.\\n */\\ninterface IOptimismMintableERC721 is IERC721Enumerable {\\n /**\\n * @notice Emitted when a token is minted.\\n *\\n * @param account Address of the account the token was minted to.\\n * @param tokenId Token ID of the minted token.\\n */\\n event Mint(address indexed account, uint256 tokenId);\\n\\n /**\\n * @notice Emitted when a token is burned.\\n *\\n * @param account Address of the account the token was burned from.\\n * @param tokenId Token ID of the burned token.\\n */\\n event Burn(address indexed account, uint256 tokenId);\\n\\n /**\\n * @notice Chain ID of the chain where the remote token is deployed.\\n */\\n function remoteChainId() external view returns (uint256);\\n\\n /**\\n * @notice Address of the token on the remote domain.\\n */\\n function remoteToken() external view returns (address);\\n\\n /**\\n * @notice Address of the ERC721 bridge on this network.\\n */\\n function bridge() external view returns (address);\\n\\n /**\\n * @notice Mints some token ID for a user, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * @param _to Address of the user to mint the token for.\\n * @param _tokenId Token ID to mint.\\n */\\n function safeMint(address _to, uint256 _tokenId) external;\\n\\n /**\\n * @notice Burns a token ID from a user.\\n *\\n * @param _from Address of the user to burn the token from.\\n * @param _tokenId Token ID to burn.\\n */\\n function burn(address _from, uint256 _tokenId) external;\\n}\\n\",\"keccak256\":\"0xc3703030d0093d65839b02296e3152681fa1c8d717e66ab3f5a7c32ba3fd0a54\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6101206040523480156200001257600080fd5b506040516200197238038062001972833981016040819052620000359162000162565b600160008084846001600160a01b038216620000ad5760405162461bcd60e51b815260206004820152602c60248201527f4552433732314272696467653a206d657373656e6765722063616e6e6f74206260448201526b65206164647265737328302960a01b60648201526084015b60405180910390fd5b6001600160a01b0381166200011d5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314272696467653a206f74686572206272696467652063616e6e6f60448201526e74206265206164647265737328302960881b6064820152608401620000a4565b6001600160a01b039182166080521660a05260c09290925260e05261010052506200019a9050565b80516001600160a01b03811681146200015d57600080fd5b919050565b600080604083850312156200017657600080fd5b620001818362000145565b9150620001916020840162000145565b90509250929050565b60805160a05160c05160e051610100516117716200020160003960006102440152600061021b015260006101f201526000818161011d015281816102d00152610d630152600081816091015281816102a6015281816103070152610d3601526117716000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063761f449311610050578063761f4493146100f2578063aa55745214610105578063c89701a21461011857600080fd5b80633687011a146100775780633cb747bf1461008c57806354fd4d50146100dd575b600080fd5b61008a6100853660046111d8565b61013f565b005b6100b37f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100e56101eb565b6040516100d491906112d5565b61008a6101003660046112e8565b61028e565b61008a610113366004611380565b6107f5565b6100b37f000000000000000000000000000000000000000000000000000000000000000081565b333b156101d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6101e386863333888888886108b1565b505050505050565b60606102167f0000000000000000000000000000000000000000000000000000000000000000610e4f565b61023f7f0000000000000000000000000000000000000000000000000000000000000000610e4f565b6102687f0000000000000000000000000000000000000000000000000000000000000000610e4f565b60405160200161027a939291906113f7565b604051602081830303815290604052905090565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156103ac57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610370573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610394919061146d565b73ffffffffffffffffffffffffffffffffffffffff16145b610438576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f74686572206272696467650060648201526084016101ca565b3073ffffffffffffffffffffffffffffffffffffffff8816036104dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016101ca565b610507877fe49bc7f800000000000000000000000000000000000000000000000000000000610f8c565b610593576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e20696e746560448201527f7266616365206973206e6f7420636f6d706c69616e740000000000000000000060648201526084016101ca565b8673ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610602919061146d565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146106e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324552433732314272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433732312060648201527f6c6f63616c20746f6b656e000000000000000000000000000000000000000000608482015260a4016101ca565b6040517fa144819400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301526024820185905288169063a144819490604401600060405180830381600087803b15801561075257600080fd5b505af1158015610766573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107e494939291906114da565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610898576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f7420626520616464726573732830290000000000000000000000000000000060648201526084016101ca565b6108a887873388888888886108b1565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff8716610954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4552433732314272696467653a2072656d6f746520746f6b656e2063616e6e6f60448201527f742062652061646472657373283029000000000000000000000000000000000060648201526084016101ca565b6040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff891690636352211e90602401602060405180830381865afa1580156109bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e3919061146d565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f5769746864726177616c206973206e6f74206265696e6720696e69746961746560448201527f64206279204e4654206f776e657200000000000000000000000000000000000060648201526084016101ca565b60008873ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0e919061146d565b90508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e20646f6560448201527f73206e6f74206d6174636820676976656e2076616c756500000000000000000060648201526084016101ca565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018790528a1690639dc29fac90604401600060405180830381600087803b158015610c3b57600080fd5b505af1158015610c4f573d6000803e3d6000fd5b50505050600063761f449360e01b828b8a8a8a8989604051602401610c7a9796959493929190611510565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f3dbb202b00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690633dbb202b90610d8f907f00000000000000000000000000000000000000000000000000000000000000009085908a9060040161156d565b600060405180830381600087803b158015610da957600080fd5b505af1158015610dbd573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a58a8a8989604051610e3b94939291906114da565b60405180910390a450505050505050505050565b606081600003610e9257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610ebc5780610ea6816115e1565b9150610eb59050600a83611648565b9150610e96565b60008167ffffffffffffffff811115610ed757610ed761165c565b6040519080825280601f01601f191660200182016040528015610f01576020820181803683370190505b5090505b8415610f8457610f1660018361168b565b9150610f23600a866116a2565b610f2e9060306116b6565b60f81b818381518110610f4357610f436116ce565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610f7d600a86611648565b9450610f05565b949350505050565b6000610f9783610fb1565b8015610fa85750610fa88383611015565b90505b92915050565b6000610fdd827f01ffc9a700000000000000000000000000000000000000000000000000000000611015565b8015610fab575061100e827fffffffff00000000000000000000000000000000000000000000000000000000611015565b1592915050565b604080517fffffffff00000000000000000000000000000000000000000000000000000000831660248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a7000000000000000000000000000000000000000000000000000000001790529051600091908290819073ffffffffffffffffffffffffffffffffffffffff871690617530906110cf9086906116fd565b6000604051808303818686fa925050503d806000811461110b576040519150601f19603f3d011682016040523d82523d6000602084013e611110565b606091505b509150915060208151101561112b5760009350505050610fab565b8180156111475750808060200190518101906111479190611719565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461117357600080fd5b50565b803563ffffffff8116811461118a57600080fd5b919050565b60008083601f8401126111a157600080fd5b50813567ffffffffffffffff8111156111b957600080fd5b6020830191508360208285010111156111d157600080fd5b9250929050565b60008060008060008060a087890312156111f157600080fd5b86356111fc81611151565b9550602087013561120c81611151565b94506040870135935061122160608801611176565b9250608087013567ffffffffffffffff81111561123d57600080fd5b61124989828a0161118f565b979a9699509497509295939492505050565b60005b8381101561127657818101518382015260200161125e565b83811115611285576000848401525b50505050565b600081518084526112a381602086016020860161125b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610fa8602083018461128b565b600080600080600080600060c0888a03121561130357600080fd5b873561130e81611151565b9650602088013561131e81611151565b9550604088013561132e81611151565b9450606088013561133e81611151565b93506080880135925060a088013567ffffffffffffffff81111561136157600080fd5b61136d8a828b0161118f565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561139b57600080fd5b87356113a681611151565b965060208801356113b681611151565b955060408801356113c681611151565b9450606088013593506113db60808901611176565b925060a088013567ffffffffffffffff81111561136157600080fd5b6000845161140981846020890161125b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611445816001850160208a0161125b565b6001920191820152835161146081600284016020880161125b565b0160020195945050505050565b60006020828403121561147f57600080fd5b815161148a81611151565b9392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000611147606083018486611491565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261156060c083018486611491565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061159c606083018561128b565b905063ffffffff83166040830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611612576116126115b2565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165757611657611619565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008282101561169d5761169d6115b2565b500390565b6000826116b1576116b1611619565b500690565b600082198211156116c9576116c96115b2565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000825161170f81846020870161125b565b9190910192915050565b60006020828403121561172b57600080fd5b8151801515811461148a57600080fdfea264697066735822122038ebf17853e671ca85694dc6b63a39fe1ec7d19a5f56e16bf6790e2e0b0569e764736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063761f449311610050578063761f4493146100f2578063aa55745214610105578063c89701a21461011857600080fd5b80633687011a146100775780633cb747bf1461008c57806354fd4d50146100dd575b600080fd5b61008a6100853660046111d8565b61013f565b005b6100b37f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100e56101eb565b6040516100d491906112d5565b61008a6101003660046112e8565b61028e565b61008a610113366004611380565b6107f5565b6100b37f000000000000000000000000000000000000000000000000000000000000000081565b333b156101d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6101e386863333888888886108b1565b505050505050565b60606102167f0000000000000000000000000000000000000000000000000000000000000000610e4f565b61023f7f0000000000000000000000000000000000000000000000000000000000000000610e4f565b6102687f0000000000000000000000000000000000000000000000000000000000000000610e4f565b60405160200161027a939291906113f7565b604051602081830303815290604052905090565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156103ac57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610370573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610394919061146d565b73ffffffffffffffffffffffffffffffffffffffff16145b610438576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f74686572206272696467650060648201526084016101ca565b3073ffffffffffffffffffffffffffffffffffffffff8816036104dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016101ca565b610507877fe49bc7f800000000000000000000000000000000000000000000000000000000610f8c565b610593576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324552433732314272696467653a206c6f63616c20746f6b656e20696e746560448201527f7266616365206973206e6f7420636f6d706c69616e740000000000000000000060648201526084016101ca565b8673ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610602919061146d565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146106e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324552433732314272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433732312060648201527f6c6f63616c20746f6b656e000000000000000000000000000000000000000000608482015260a4016101ca565b6040517fa144819400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301526024820185905288169063a144819490604401600060405180830381600087803b15801561075257600080fd5b505af1158015610766573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107e494939291906114da565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610898576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f7420626520616464726573732830290000000000000000000000000000000060648201526084016101ca565b6108a887873388888888886108b1565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff8716610954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4552433732314272696467653a2072656d6f746520746f6b656e2063616e6e6f60448201527f742062652061646472657373283029000000000000000000000000000000000060648201526084016101ca565b6040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff891690636352211e90602401602060405180830381865afa1580156109bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e3919061146d565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f5769746864726177616c206973206e6f74206265696e6720696e69746961746560448201527f64206279204e4654206f776e657200000000000000000000000000000000000060648201526084016101ca565b60008873ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0e919061146d565b90508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324552433732314272696467653a2072656d6f746520746f6b656e20646f6560448201527f73206e6f74206d6174636820676976656e2076616c756500000000000000000060648201526084016101ca565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018790528a1690639dc29fac90604401600060405180830381600087803b158015610c3b57600080fd5b505af1158015610c4f573d6000803e3d6000fd5b50505050600063761f449360e01b828b8a8a8a8989604051602401610c7a9796959493929190611510565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f3dbb202b00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690633dbb202b90610d8f907f00000000000000000000000000000000000000000000000000000000000000009085908a9060040161156d565b600060405180830381600087803b158015610da957600080fd5b505af1158015610dbd573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a58a8a8989604051610e3b94939291906114da565b60405180910390a450505050505050505050565b606081600003610e9257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610ebc5780610ea6816115e1565b9150610eb59050600a83611648565b9150610e96565b60008167ffffffffffffffff811115610ed757610ed761165c565b6040519080825280601f01601f191660200182016040528015610f01576020820181803683370190505b5090505b8415610f8457610f1660018361168b565b9150610f23600a866116a2565b610f2e9060306116b6565b60f81b818381518110610f4357610f436116ce565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610f7d600a86611648565b9450610f05565b949350505050565b6000610f9783610fb1565b8015610fa85750610fa88383611015565b90505b92915050565b6000610fdd827f01ffc9a700000000000000000000000000000000000000000000000000000000611015565b8015610fab575061100e827fffffffff00000000000000000000000000000000000000000000000000000000611015565b1592915050565b604080517fffffffff00000000000000000000000000000000000000000000000000000000831660248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a7000000000000000000000000000000000000000000000000000000001790529051600091908290819073ffffffffffffffffffffffffffffffffffffffff871690617530906110cf9086906116fd565b6000604051808303818686fa925050503d806000811461110b576040519150601f19603f3d011682016040523d82523d6000602084013e611110565b606091505b509150915060208151101561112b5760009350505050610fab565b8180156111475750808060200190518101906111479190611719565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461117357600080fd5b50565b803563ffffffff8116811461118a57600080fd5b919050565b60008083601f8401126111a157600080fd5b50813567ffffffffffffffff8111156111b957600080fd5b6020830191508360208285010111156111d157600080fd5b9250929050565b60008060008060008060a087890312156111f157600080fd5b86356111fc81611151565b9550602087013561120c81611151565b94506040870135935061122160608801611176565b9250608087013567ffffffffffffffff81111561123d57600080fd5b61124989828a0161118f565b979a9699509497509295939492505050565b60005b8381101561127657818101518382015260200161125e565b83811115611285576000848401525b50505050565b600081518084526112a381602086016020860161125b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610fa8602083018461128b565b600080600080600080600060c0888a03121561130357600080fd5b873561130e81611151565b9650602088013561131e81611151565b9550604088013561132e81611151565b9450606088013561133e81611151565b93506080880135925060a088013567ffffffffffffffff81111561136157600080fd5b61136d8a828b0161118f565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561139b57600080fd5b87356113a681611151565b965060208801356113b681611151565b955060408801356113c681611151565b9450606088013593506113db60808901611176565b925060a088013567ffffffffffffffff81111561136157600080fd5b6000845161140981846020890161125b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611445816001850160208a0161125b565b6001920191820152835161146081600284016020880161125b565b0160020195945050505050565b60006020828403121561147f57600080fd5b815161148a81611151565b9392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000611147606083018486611491565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261156060c083018486611491565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061159c606083018561128b565b905063ffffffff83166040830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611612576116126115b2565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165757611657611619565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008282101561169d5761169d6115b2565b500390565b6000826116b1576116b1611619565b500690565b600082198211156116c9576116c96115b2565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000825161170f81846020870161125b565b9190910192915050565b60006020828403121561172b57600080fd5b8151801515811461148a57600080fdfea264697066735822122038ebf17853e671ca85694dc6b63a39fe1ec7d19a5f56e16bf6790e2e0b0569e764736f6c634300080f0033", - "devdoc": { - "kind": "dev", - "methods": { - "bridgeERC721(address,address,uint256,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.", - "_localToken": "Address of the ERC721 on this domain.", - "_minGasLimit": "Minimum gas limit for the bridge message on the other domain.", - "_remoteToken": "Address of the ERC721 on the remote domain.", - "_tokenId": "Token ID to bridge." - } - }, - "bridgeERC721To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.", - "_localToken": "Address of the ERC721 on this domain.", - "_minGasLimit": "Minimum gas limit for the bridge message on the other domain.", - "_remoteToken": "Address of the ERC721 on the remote domain.", - "_to": "Address to receive the token on the other domain.", - "_tokenId": "Token ID to bridge." - } - }, - "constructor": { - "custom:semver": "1.0.0", - "params": { - "_messenger": "Address of the CrossDomainMessenger on this network.", - "_otherBridge": "Address of the ERC721 bridge on the other network." - } - }, - "finalizeBridgeERC721(address,address,address,address,uint256,bytes)": { - "params": { - "_extraData": "Optional data to forward to L1. Data supplied here will not be used to execute any code on L1 and is only emitted as extra data for the convenience of off-chain tooling.", - "_from": "Address that triggered the bridge on the other domain.", - "_localToken": "Address of the ERC721 token on this domain.", - "_remoteToken": "Address of the ERC721 token on the other domain.", - "_to": "Address to receive the token on this domain.", - "_tokenId": "ID of the token being deposited." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "L2ERC721Bridge", - "version": 1 - }, - "userdoc": { - "events": { - "ERC721BridgeFinalized(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC721 bridge from the other network is finalized." - }, - "ERC721BridgeInitiated(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC721 bridge to the other network is initiated." - } - }, - "kind": "user", - "methods": { - "bridgeERC721(address,address,uint256,uint32,bytes)": { - "notice": "Initiates a bridge of an NFT to the caller's account on the other chain. Note that this function can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` function after ensuring that the recipient address on the remote chain exists. Also note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "bridgeERC721To(address,address,address,uint256,uint32,bytes)": { - "notice": "Initiates a bridge of an NFT to some recipient's account on the other chain. Note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "finalizeBridgeERC721(address,address,address,address,uint256,bytes)": { - "notice": "Completes an ERC721 bridge from the other domain and sends the ERC721 token to the recipient on this domain." - }, - "messenger()": { - "notice": "Messenger contract on this domain." - }, - "otherBridge()": { - "notice": "Address of the bridge on the other network." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge. This contract also acts as a burner for tokens being withdrawn. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 8088, - "contract": "contracts/L2/L2ERC721Bridge.sol:L2ERC721Bridge", - "label": "__gap", - "offset": 0, - "slot": "0", - "type": "t_array(t_uint256)49_storage" - } - ], - "types": { - "t_array(t_uint256)49_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/MintManager.json b/packages/contracts-bedrock/deployments/optimism-mainnet/MintManager.json deleted file mode 100644 index f71c767af618..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/MintManager.json +++ /dev/null @@ -1,316 +0,0 @@ -{ - "address": "0x5C4e7Ba1E219E47948e6e3F55019A647bA501005", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_upgrader", - "type": "address" - }, - { - "internalType": "address", - "name": "_governanceToken", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "DENOMINATOR", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MINT_CAP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MINT_PERIOD", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "governanceToken", - "outputs": [ - { - "internalType": "contract GovernanceToken", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "mintPermittedAfter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_newMintManager", - "type": "address" - } - ], - "name": "upgrade", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0x87f4ef2d91434e18615cabd129752c1f50600a7152f036828e8667b32c10bb1a", - "receipt": { - "to": null, - "from": "0x4D014f3c5F33Aa9Cd1Dc29ce29618d07Ae666d15", - "contractAddress": "0x5C4e7Ba1E219E47948e6e3F55019A647bA501005", - "transactionIndex": 0, - "gasUsed": "880798", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000200020000000000000000000000000000000000000000000000000000000000000000000000000000004000001000000000000000000000000000140000000020000000000000020000800000000000000000000000000000000400000000000000000000000000000000010000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x87432e6b30f06243ca328c59d522b3a361bb863726e1e8e171e607d49bb7df66", - "transactionHash": "0x87f4ef2d91434e18615cabd129752c1f50600a7152f036828e8667b32c10bb1a", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 28103702, - "transactionHash": "0x87f4ef2d91434e18615cabd129752c1f50600a7152f036828e8667b32c10bb1a", - "address": "0x5C4e7Ba1E219E47948e6e3F55019A647bA501005", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000004d014f3c5f33aa9cd1dc29ce29618d07ae666d15" - ], - "data": "0x", - "logIndex": 0, - "blockHash": "0x87432e6b30f06243ca328c59d522b3a361bb863726e1e8e171e607d49bb7df66" - }, - { - "transactionIndex": 0, - "blockNumber": 28103702, - "transactionHash": "0x87f4ef2d91434e18615cabd129752c1f50600a7152f036828e8667b32c10bb1a", - "address": "0x5C4e7Ba1E219E47948e6e3F55019A647bA501005", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000004d014f3c5f33aa9cd1dc29ce29618d07ae666d15", - "0x0000000000000000000000002a82ae142b2e62cb7d10b55e323acb1cab663a26" - ], - "data": "0x", - "logIndex": 1, - "blockHash": "0x87432e6b30f06243ca328c59d522b3a361bb863726e1e8e171e607d49bb7df66" - } - ], - "blockNumber": 28103702, - "cumulativeGasUsed": "880798", - "status": 1, - "byzantium": true - }, - "args": [ - "0x2A82Ae142b2e62Cb7D10b55E323ACB1Cab663a26", - "0x4200000000000000000000000000000000000042" - ], - "numDeployments": 1, - "solcInputHash": "b1df373a9ed51b3903b61f56faa9a78f", - "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_upgrader\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_governanceToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINT_CAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINT_PERIOD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governanceToken\",\"outputs\":[{\"internalType\":\"contract GovernanceToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mintPermittedAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newMintManager\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_governanceToken\":\"The governance token this contract can mint tokens of\",\"_upgrader\":\"The owner of this contract\"}},\"mint(address,uint256)\":{\"params\":{\"_account\":\"Address to mint new tokens to.\",\"_amount\":\"Amount of tokens to be minted.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address)\":{\"params\":{\"_newMintManager\":\"The MintManager to upgrade to\"}}},\"title\":\"MintManager\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"DENOMINATOR()\":{\"notice\":\"The number of decimals for the MINT_CAP.\"},\"MINT_CAP()\":{\"notice\":\"The amount of tokens that can be minted per year. The value is a fixed point number with 4 decimals.\"},\"MINT_PERIOD()\":{\"notice\":\"The amount of time that must pass before the MINT_CAP number of tokens can be minted again.\"},\"governanceToken()\":{\"notice\":\"The GovernanceToken that the MintManager can mint tokens\"},\"mint(address,uint256)\":{\"notice\":\"Only the token owner is allowed to mint a certain amount of OP per year.\"},\"mintPermittedAfter()\":{\"notice\":\"Tracks the time of last mint\"},\"upgrade(address)\":{\"notice\":\"Upgrade the owner of the governance token to a new MintManager.\"}},\"notice\":\"Set as `owner` of the OP token and responsible for the token inflation schedule. Contract acts as the token \\\"mint manager\\\" with permission to the `mint` function only. Currently permitted to mint once per year of up to 2% of the total token supply. Upgradable to allow changes in the inflation schedule.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/MintManager.sol\":\"MintManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x24e0364e503a9bbde94c715d26573a76f14cd2a202d45f96f52134ab806b67b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n *\\n * _Available since v4.5._\\n */\\ninterface IVotes {\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\\n */\\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"keccak256\":\"0xf5324a55ee9c0b4a840ea57c055ac9d046f88986ceef567e1cf68113e46a79c0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, _allowances[owner][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = _allowances[owner][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Spend `amount` form the allowance of `owner` toward `spender`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xdadd41acb749920eccf40aeaa8d291adf9751399a7343561bad13e7a8d99be0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0x0d19410453cda55960a818e02bd7c18952a5c8fe7a3036e81f0d599f34487a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../governance/utils/IVotes.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is IVotes, ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual override returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view virtual override returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual override {\\n _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"keccak256\":\"0x7fd2492be0468be4662081ee25cde38a31e4a0ceca0fed10160462389013910f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private immutable _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"keccak256\":\"0x8a763ef5625e97f5287c7ddd5ede434129069e15d83bf0a68ad10a5e56ccb439\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0xf0018c2440fbe238dd3a8732fa8e17a0f9dce84d31451dc8a32f6d62b349c9f1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x32c202bd28995dd20c4347b7c6467a6d3241c74c8ad3edcbb610cd9205916c45\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0x3c07f43e60e099b3b157243b3152722e73b80eeb7985c2cd73712828d7f7da29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n address private immutable _CACHED_THIS;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _CACHED_THIS = address(this);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"keccak256\":\"0x6688fad58b9ec0286d40fa957152e575d5d8bd4c3aa80985efdb11b44f776ae7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0xc995bddbca1ae19788db9f8b61e63385edd3fddf89693b612d5abd1a275974d2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits.\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt128(int256 value) internal pure returns (int128) {\\n require(value >= type(int128).min && value <= type(int128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return int128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt64(int256 value) internal pure returns (int64) {\\n require(value >= type(int64).min && value <= type(int64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return int64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt32(int256 value) internal pure returns (int32) {\\n require(value >= type(int32).min && value <= type(int32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n return int32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n *\\n * _Available since v3.1._\\n */\\n function toInt16(int256 value) internal pure returns (int16) {\\n require(value >= type(int16).min && value <= type(int16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n return int16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits.\\n *\\n * _Available since v3.1._\\n */\\n function toInt8(int256 value) internal pure returns (int8) {\\n require(value >= type(int8).min && value <= type(int8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n return int8(value);\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x5c6caab697d302ad7eb59c234a4d2dbc965c1bae87709bd2850060b7695b28c7\",\"license\":\"MIT\"},\"contracts/GovernanceToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @dev The Optimism token used in governance and supporting voting and delegation.\\n * Implements EIP 2612 allowing signed approvals.\\n * Contract is \\\"owned\\\" by a `MintManager` instance with permission to the `mint` function only,\\n * for the purposes of enforcing the token inflation schedule.\\n */\\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\\n /**\\n * @dev Constructor.\\n */\\n constructor() ERC20(\\\"Optimism\\\", \\\"OP\\\") ERC20Permit(\\\"Optimism\\\") {}\\n\\n function mint(address _account, uint256 _amount) public onlyOwner {\\n _mint(_account, _amount);\\n }\\n\\n // The following functions are overrides required by Solidity.\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal override(ERC20, ERC20Votes) {\\n super._afterTokenTransfer(from, to, amount);\\n }\\n\\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\\n super._mint(to, amount);\\n }\\n\\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\\n super._burn(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0x9686248fc10e71c30b05bc86a7b7749f12f74e5701c9d73b15ca9f75b9093839\",\"license\":\"MIT\"},\"contracts/MintManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"./GovernanceToken.sol\\\";\\n\\n/**\\n * @title MintManager\\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\\n * Contract acts as the token \\\"mint manager\\\" with permission to the `mint` function only.\\n * Currently permitted to mint once per year of up to 2% of the total token supply.\\n * Upgradable to allow changes in the inflation schedule.\\n */\\ncontract MintManager is Ownable {\\n /**\\n * @notice The GovernanceToken that the MintManager can mint tokens\\n */\\n GovernanceToken public immutable governanceToken;\\n\\n /**\\n * @notice The amount of tokens that can be minted per year. The value is a fixed\\n * point number with 4 decimals.\\n */\\n uint256 public constant MINT_CAP = 20; // 2%\\n\\n /**\\n * @notice The number of decimals for the MINT_CAP.\\n */\\n uint256 public constant DENOMINATOR = 1000;\\n\\n /**\\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\\n * be minted again.\\n */\\n uint256 public constant MINT_PERIOD = 365 days;\\n\\n /**\\n * @notice Tracks the time of last mint\\n */\\n uint256 public mintPermittedAfter;\\n\\n /**\\n * @param _upgrader The owner of this contract\\n * @param _governanceToken The governance token this contract can mint\\n * tokens of\\n */\\n constructor(address _upgrader, address _governanceToken) {\\n transferOwnership(_upgrader);\\n governanceToken = GovernanceToken(_governanceToken);\\n }\\n\\n /**\\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\\n *\\n * @param _account Address to mint new tokens to.\\n * @param _amount Amount of tokens to be minted.\\n */\\n function mint(address _account, uint256 _amount) public onlyOwner {\\n if (mintPermittedAfter > 0) {\\n require(mintPermittedAfter <= block.timestamp, \\\"OP: minting not permitted yet\\\");\\n\\n require(\\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\\n \\\"OP: mint amount exceeds cap\\\"\\n );\\n }\\n\\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\\n\\n governanceToken.mint(_account, _amount);\\n }\\n\\n /**\\n * @notice Upgrade the owner of the governance token to a new MintManager.\\n *\\n * @param _newMintManager The MintManager to upgrade to\\n */\\n function upgrade(address _newMintManager) public onlyOwner {\\n require(_newMintManager != address(0), \\\"OP: Mint manager cannot be empty\\\");\\n\\n governanceToken.transferOwnership(_newMintManager);\\n }\\n}\\n\",\"keccak256\":\"0x502e1e705839a9840823fe4c2eef2cf7f717b548c2259c6c5cf5e62753fbd940\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b50604051620012f1380380620012f1833981810160405281019062000037919062000319565b620000576200004b620000a460201b60201c565b620000ac60201b60201c565b62000068826200017060201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050506200047b565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b62000180620000a460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620001a66200028660201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614620001ff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001f690620003c1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141562000272576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002699062000459565b60405180910390fd5b6200028381620000ac60201b60201c565b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002e182620002b4565b9050919050565b620002f381620002d4565b8114620002ff57600080fd5b50565b6000815190506200031381620002e8565b92915050565b60008060408385031215620003335762000332620002af565b5b6000620003438582860162000302565b9250506020620003568582860162000302565b9150509250929050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000620003a960208362000360565b9150620003b68262000371565b602082019050919050565b60006020820190508181036000830152620003dc816200039a565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006200044160268362000360565b91506200044e82620003e3565b604082019050919050565b60006020820190508181036000830152620004748162000432565b9050919050565b608051610e45620004ac600039600081816102a8015281816104070152818161050301526107500152610e456000f3fe608060405234801561001057600080fd5b506004361061009d5760003560e01c80638da5cb5b116100665780638da5cb5b14610120578063918f86741461013e57806398f1312e1461015c578063f2fde38b1461017a578063f96dae0a146101965761009d565b8062f8900c146100a25780630900f010146100c057806340c10f19146100dc578063715018a6146100f857806383ea6e9714610102575b600080fd5b6100aa6101b4565b6040516100b79190610857565b60405180910390f35b6100da60048036038101906100d591906108d5565b6101ba565b005b6100f660048036038101906100f1919061092e565b610334565b005b610100610592565b005b61010a61061a565b6040516101179190610857565b60405180910390f35b610128610622565b604051610135919061097d565b60405180910390f35b61014661064b565b6040516101539190610857565b60405180910390f35b610164610651565b6040516101719190610857565b60405180910390f35b610194600480360381019061018f91906108d5565b610656565b005b61019e61074e565b6040516101ab91906109f7565b60405180910390f35b60015481565b6101c2610772565b73ffffffffffffffffffffffffffffffffffffffff166101e0610622565b73ffffffffffffffffffffffffffffffffffffffff1614610236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022d90610a6f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156102a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161029d90610adb565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b826040518263ffffffff1660e01b81526004016102ff919061097d565b600060405180830381600087803b15801561031957600080fd5b505af115801561032d573d6000803e3d6000fd5b5050505050565b61033c610772565b73ffffffffffffffffffffffffffffffffffffffff1661035a610622565b73ffffffffffffffffffffffffffffffffffffffff16146103b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a790610a6f565b60405180910390fd5b600060015411156104eb57426001541115610400576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f790610b47565b60405180910390fd5b6103e860147f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104949190610b7c565b61049e9190610bd8565b6104a89190610c61565b8111156104ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e190610cde565b60405180910390fd5b5b6301e13380426104fb9190610cfe565b6001819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b815260040161055c929190610d54565b600060405180830381600087803b15801561057657600080fd5b505af115801561058a573d6000803e3d6000fd5b505050505050565b61059a610772565b73ffffffffffffffffffffffffffffffffffffffff166105b8610622565b73ffffffffffffffffffffffffffffffffffffffff161461060e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060590610a6f565b60405180910390fd5b610618600061077a565b565b6301e1338081565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6103e881565b601481565b61065e610772565b73ffffffffffffffffffffffffffffffffffffffff1661067c610622565b73ffffffffffffffffffffffffffffffffffffffff16146106d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c990610a6f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610742576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073990610def565b60405180910390fd5b61074b8161077a565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000819050919050565b6108518161083e565b82525050565b600060208201905061086c6000830184610848565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006108a282610877565b9050919050565b6108b281610897565b81146108bd57600080fd5b50565b6000813590506108cf816108a9565b92915050565b6000602082840312156108eb576108ea610872565b5b60006108f9848285016108c0565b91505092915050565b61090b8161083e565b811461091657600080fd5b50565b60008135905061092881610902565b92915050565b6000806040838503121561094557610944610872565b5b6000610953858286016108c0565b925050602061096485828601610919565b9150509250929050565b61097781610897565b82525050565b6000602082019050610992600083018461096e565b92915050565b6000819050919050565b60006109bd6109b86109b384610877565b610998565b610877565b9050919050565b60006109cf826109a2565b9050919050565b60006109e1826109c4565b9050919050565b6109f1816109d6565b82525050565b6000602082019050610a0c60008301846109e8565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610a59602083610a12565b9150610a6482610a23565b602082019050919050565b60006020820190508181036000830152610a8881610a4c565b9050919050565b7f4f503a204d696e74206d616e616765722063616e6e6f7420626520656d707479600082015250565b6000610ac5602083610a12565b9150610ad082610a8f565b602082019050919050565b60006020820190508181036000830152610af481610ab8565b9050919050565b7f4f503a206d696e74696e67206e6f74207065726d697474656420796574000000600082015250565b6000610b31601d83610a12565b9150610b3c82610afb565b602082019050919050565b60006020820190508181036000830152610b6081610b24565b9050919050565b600081519050610b7681610902565b92915050565b600060208284031215610b9257610b91610872565b5b6000610ba084828501610b67565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610be38261083e565b9150610bee8361083e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610c2757610c26610ba9565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610c6c8261083e565b9150610c778361083e565b925082610c8757610c86610c32565b5b828204905092915050565b7f4f503a206d696e7420616d6f756e742065786365656473206361700000000000600082015250565b6000610cc8601b83610a12565b9150610cd382610c92565b602082019050919050565b60006020820190508181036000830152610cf781610cbb565b9050919050565b6000610d098261083e565b9150610d148361083e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610d4957610d48610ba9565b5b828201905092915050565b6000604082019050610d69600083018561096e565b610d766020830184610848565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610dd9602683610a12565b9150610de482610d7d565b604082019050919050565b60006020820190508181036000830152610e0881610dcc565b905091905056fea2646970667358221220d6ef0f15f2581f08c298ff8c67408d75a27f67742459525e88193c029a7a0bcf64736f6c634300080c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061009d5760003560e01c80638da5cb5b116100665780638da5cb5b14610120578063918f86741461013e57806398f1312e1461015c578063f2fde38b1461017a578063f96dae0a146101965761009d565b8062f8900c146100a25780630900f010146100c057806340c10f19146100dc578063715018a6146100f857806383ea6e9714610102575b600080fd5b6100aa6101b4565b6040516100b79190610857565b60405180910390f35b6100da60048036038101906100d591906108d5565b6101ba565b005b6100f660048036038101906100f1919061092e565b610334565b005b610100610592565b005b61010a61061a565b6040516101179190610857565b60405180910390f35b610128610622565b604051610135919061097d565b60405180910390f35b61014661064b565b6040516101539190610857565b60405180910390f35b610164610651565b6040516101719190610857565b60405180910390f35b610194600480360381019061018f91906108d5565b610656565b005b61019e61074e565b6040516101ab91906109f7565b60405180910390f35b60015481565b6101c2610772565b73ffffffffffffffffffffffffffffffffffffffff166101e0610622565b73ffffffffffffffffffffffffffffffffffffffff1614610236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161022d90610a6f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156102a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161029d90610adb565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b826040518263ffffffff1660e01b81526004016102ff919061097d565b600060405180830381600087803b15801561031957600080fd5b505af115801561032d573d6000803e3d6000fd5b5050505050565b61033c610772565b73ffffffffffffffffffffffffffffffffffffffff1661035a610622565b73ffffffffffffffffffffffffffffffffffffffff16146103b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a790610a6f565b60405180910390fd5b600060015411156104eb57426001541115610400576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f790610b47565b60405180910390fd5b6103e860147f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104949190610b7c565b61049e9190610bd8565b6104a89190610c61565b8111156104ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e190610cde565b60405180910390fd5b5b6301e13380426104fb9190610cfe565b6001819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b815260040161055c929190610d54565b600060405180830381600087803b15801561057657600080fd5b505af115801561058a573d6000803e3d6000fd5b505050505050565b61059a610772565b73ffffffffffffffffffffffffffffffffffffffff166105b8610622565b73ffffffffffffffffffffffffffffffffffffffff161461060e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060590610a6f565b60405180910390fd5b610618600061077a565b565b6301e1338081565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6103e881565b601481565b61065e610772565b73ffffffffffffffffffffffffffffffffffffffff1661067c610622565b73ffffffffffffffffffffffffffffffffffffffff16146106d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c990610a6f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610742576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073990610def565b60405180910390fd5b61074b8161077a565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000819050919050565b6108518161083e565b82525050565b600060208201905061086c6000830184610848565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006108a282610877565b9050919050565b6108b281610897565b81146108bd57600080fd5b50565b6000813590506108cf816108a9565b92915050565b6000602082840312156108eb576108ea610872565b5b60006108f9848285016108c0565b91505092915050565b61090b8161083e565b811461091657600080fd5b50565b60008135905061092881610902565b92915050565b6000806040838503121561094557610944610872565b5b6000610953858286016108c0565b925050602061096485828601610919565b9150509250929050565b61097781610897565b82525050565b6000602082019050610992600083018461096e565b92915050565b6000819050919050565b60006109bd6109b86109b384610877565b610998565b610877565b9050919050565b60006109cf826109a2565b9050919050565b60006109e1826109c4565b9050919050565b6109f1816109d6565b82525050565b6000602082019050610a0c60008301846109e8565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000610a59602083610a12565b9150610a6482610a23565b602082019050919050565b60006020820190508181036000830152610a8881610a4c565b9050919050565b7f4f503a204d696e74206d616e616765722063616e6e6f7420626520656d707479600082015250565b6000610ac5602083610a12565b9150610ad082610a8f565b602082019050919050565b60006020820190508181036000830152610af481610ab8565b9050919050565b7f4f503a206d696e74696e67206e6f74207065726d697474656420796574000000600082015250565b6000610b31601d83610a12565b9150610b3c82610afb565b602082019050919050565b60006020820190508181036000830152610b6081610b24565b9050919050565b600081519050610b7681610902565b92915050565b600060208284031215610b9257610b91610872565b5b6000610ba084828501610b67565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610be38261083e565b9150610bee8361083e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610c2757610c26610ba9565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610c6c8261083e565b9150610c778361083e565b925082610c8757610c86610c32565b5b828204905092915050565b7f4f503a206d696e7420616d6f756e742065786365656473206361700000000000600082015250565b6000610cc8601b83610a12565b9150610cd382610c92565b602082019050919050565b60006020820190508181036000830152610cf781610cbb565b9050919050565b6000610d098261083e565b9150610d148361083e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610d4957610d48610ba9565b5b828201905092915050565b6000604082019050610d69600083018561096e565b610d766020830184610848565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610dd9602683610a12565b9150610de482610d7d565b604082019050919050565b60006020820190508181036000830152610e0881610dcc565b905091905056fea2646970667358221220d6ef0f15f2581f08c298ff8c67408d75a27f67742459525e88193c029a7a0bcf64736f6c634300080c0033", - "devdoc": { - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_governanceToken": "The governance token this contract can mint tokens of", - "_upgrader": "The owner of this contract" - } - }, - "mint(address,uint256)": { - "params": { - "_account": "Address to mint new tokens to.", - "_amount": "Amount of tokens to be minted." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - }, - "upgrade(address)": { - "params": { - "_newMintManager": "The MintManager to upgrade to" - } - } - }, - "title": "MintManager", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "DENOMINATOR()": { - "notice": "The number of decimals for the MINT_CAP." - }, - "MINT_CAP()": { - "notice": "The amount of tokens that can be minted per year. The value is a fixed point number with 4 decimals." - }, - "MINT_PERIOD()": { - "notice": "The amount of time that must pass before the MINT_CAP number of tokens can be minted again." - }, - "governanceToken()": { - "notice": "The GovernanceToken that the MintManager can mint tokens" - }, - "mint(address,uint256)": { - "notice": "Only the token owner is allowed to mint a certain amount of OP per year." - }, - "mintPermittedAfter()": { - "notice": "Tracks the time of last mint" - }, - "upgrade(address)": { - "notice": "Upgrade the owner of the governance token to a new MintManager." - } - }, - "notice": "Set as `owner` of the OP token and responsible for the token inflation schedule. Contract acts as the token \"mint manager\" with permission to the `mint` function only. Currently permitted to mint once per year of up to 2% of the total token supply. Upgradable to allow changes in the inflation schedule.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 7, - "contract": "contracts/MintManager.sol:MintManager", - "label": "_owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 3573, - "contract": "contracts/MintManager.sol:MintManager", - "label": "mintPermittedAfter", - "offset": 0, - "slot": "1", - "type": "t_uint256" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimismMintableERC721Factory.json b/packages/contracts-bedrock/deployments/optimism-mainnet/OptimismMintableERC721Factory.json deleted file mode 100644 index 0052dac91020..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimismMintableERC721Factory.json +++ /dev/null @@ -1,250 +0,0 @@ -{ - "address": "0x69D67c1caa8D0717DffA6d2e5B1f7F19926e5EF0", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_bridge", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_remoteChainId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "deployer", - "type": "address" - } - ], - "name": "OptimismMintableERC721Created", - "type": "event" - }, - { - "inputs": [], - "name": "bridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createOptimismMintableERC721", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "isOptimismMintableERC721", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "remoteChainId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0xffa94dd9f5a43e9dd4c20f1f9335e6a392fcd6066fa70738808432d926b31a68", - "receipt": { - "to": null, - "from": "0x53A6eecC2dD4795Fcc68940ddc6B4d53Bd88Bd9E", - "contractAddress": "0x69D67c1caa8D0717DffA6d2e5B1f7F19926e5EF0", - "transactionIndex": 0, - "gasUsed": "3124569", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcd388f3b7f032bd0ef8b65aab748193683f5ae671a627a4eee81707bb980bc2a", - "transactionHash": "0xffa94dd9f5a43e9dd4c20f1f9335e6a392fcd6066fa70738808432d926b31a68", - "logs": [], - "blockNumber": 27396228, - "cumulativeGasUsed": "3124569", - "status": 1, - "byzantium": true - }, - "args": [ - "0x4200000000000000000000000000000000000014", - 1 - ], - "numDeployments": 1, - "solcInputHash": "ab9b77493f35e63b7a63fb2fa8d618b4", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_remoteChainId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"}],\"name\":\"OptimismMintableERC721Created\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createOptimismMintableERC721\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOptimismMintableERC721\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"remoteChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"OptimismMintableERC721Created(address,address,address)\":{\"params\":{\"deployer\":\"Address of the initiator of the deployment\",\"localToken\":\"Address of the token on the this domain.\",\"remoteToken\":\"Address of the token on the remote domain.\"}}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.0.0\",\"params\":{\"_bridge\":\"Address of the ERC721 bridge on this network.\"}},\"createOptimismMintableERC721(address,string,string)\":{\"params\":{\"_name\":\"ERC721 name.\",\"_remoteToken\":\"Address of the corresponding token on the other domain.\",\"_symbol\":\"ERC721 symbol.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"OptimismMintableERC721Factory\",\"version\":1},\"userdoc\":{\"events\":{\"OptimismMintableERC721Created(address,address,address)\":{\"notice\":\"Emitted whenever a new OptimismMintableERC721 contract is created.\"}},\"kind\":\"user\",\"methods\":{\"bridge()\":{\"notice\":\"Address of the ERC721 bridge on this network.\"},\"createOptimismMintableERC721(address,string,string)\":{\"notice\":\"Creates an instance of the standard ERC721.\"},\"isOptimismMintableERC721(address)\":{\"notice\":\"Tracks addresses created by this factory.\"},\"remoteChainId()\":{\"notice\":\"Chain ID for the remote network.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Factory contract for creating OptimismMintableERC721 contracts.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-erc721/OptimismMintableERC721Factory.sol\":\"OptimismMintableERC721Factory\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.15;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x8215e8fbaace5e06fdf0be26cd8ec224847cf03e89bd78dc8ba3ec2cb429d4fe\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n using Address for address;\\n using Strings for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: balance query for the zero address\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: owner query for nonexistent token\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n require(_exists(tokenId), \\\"ERC721Metadata: URI query for nonexistent token\\\");\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not owner nor approved for all\\\"\\n );\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n require(_exists(tokenId), \\\"ERC721: approved query for nonexistent token\\\");\\n\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory _data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\n _safeTransfer(from, to, tokenId, _data);\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory _data\\n ) internal virtual {\\n _transfer(from, to, tokenId);\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n }\\n\\n /**\\n * @dev Returns whether `tokenId` exists.\\n *\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\n *\\n * Tokens start existing when they are minted (`_mint`),\\n * and stop existing when they are burned (`_burn`).\\n */\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\n return _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n require(_exists(tokenId), \\\"ERC721: operator query for nonexistent token\\\");\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory _data\\n ) internal virtual {\\n _mint(to, tokenId);\\n require(\\n _checkOnERC721Received(address(0), to, tokenId, _data),\\n \\\"ERC721: transfer to non ERC721Receiver implementer\\\"\\n );\\n }\\n\\n /**\\n * @dev Mints `tokenId` and transfers it to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - `to` cannot be the zero address.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _mint(address to, uint256 tokenId) internal virtual {\\n require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n _beforeTokenTransfer(address(0), to, tokenId);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits a {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits a {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param _data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory _data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {\\n return retval == IERC721Receiver.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0x921f012325281f7d81e29c53a13824cf6c2c5d77232065d0d4f3f912e97af6ea\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x0d4de01fe5360c38b4ad2b0822a12722958428f5138a7ff47c1720eb6fa52bba\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721.sol\\\";\\nimport \\\"./IERC721Enumerable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\\n * enumerability of all the token ids in the contract as well as all token ids owned by each\\n * account.\\n */\\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\\n // Mapping from owner to list of owned token IDs\\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\\n\\n // Mapping from token ID to index of the owner tokens list\\n mapping(uint256 => uint256) private _ownedTokensIndex;\\n\\n // Array with all token ids, used for enumeration\\n uint256[] private _allTokens;\\n\\n // Mapping from token id to position in the allTokens array\\n mapping(uint256 => uint256) private _allTokensIndex;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721.balanceOf(owner), \\\"ERC721Enumerable: owner index out of bounds\\\");\\n return _ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\\n require(index < ERC721Enumerable.totalSupply(), \\\"ERC721Enumerable: global index out of bounds\\\");\\n return _allTokens[index];\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual override {\\n super._beforeTokenTransfer(from, to, tokenId);\\n\\n if (from == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (from != to) {\\n _removeTokenFromOwnerEnumeration(from, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (to != from) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n uint256 length = ERC721.balanceOf(to);\\n _ownedTokens[to][length] = tokenId;\\n _ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n _allTokensIndex[tokenId] = _allTokens.length;\\n _allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\\n\\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete _ownedTokensIndex[tokenId];\\n delete _ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = _allTokens.length - 1;\\n uint256 tokenIndex = _allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = _allTokens[lastTokenIndex];\\n\\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete _allTokensIndex[tokenId];\\n _allTokens.pop();\\n }\\n}\\n\",\"keccak256\":\"0x0a79511df8151b10b0a0004d6a76ad956582d32824af4c0f4886bdbdfe5746e5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x32c202bd28995dd20c4347b7c6467a6d3241c74c8ad3edcbb610cd9205916c45\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/universal/op-erc721/IOptimismMintableERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {\\n IERC721Enumerable\\n} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\n\\n/**\\n * @title IOptimismMintableERC721\\n * @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.\\n * Tokens that follow this standard can be easily transferred across the ERC721 bridge.\\n */\\ninterface IOptimismMintableERC721 is IERC721Enumerable {\\n /**\\n * @notice Emitted when a token is minted.\\n *\\n * @param account Address of the account the token was minted to.\\n * @param tokenId Token ID of the minted token.\\n */\\n event Mint(address indexed account, uint256 tokenId);\\n\\n /**\\n * @notice Emitted when a token is burned.\\n *\\n * @param account Address of the account the token was burned from.\\n * @param tokenId Token ID of the burned token.\\n */\\n event Burn(address indexed account, uint256 tokenId);\\n\\n /**\\n * @notice Chain ID of the chain where the remote token is deployed.\\n */\\n function remoteChainId() external view returns (uint256);\\n\\n /**\\n * @notice Address of the token on the remote domain.\\n */\\n function remoteToken() external view returns (address);\\n\\n /**\\n * @notice Address of the ERC721 bridge on this network.\\n */\\n function bridge() external view returns (address);\\n\\n /**\\n * @notice Mints some token ID for a user, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * @param _to Address of the user to mint the token for.\\n * @param _tokenId Token ID to mint.\\n */\\n function safeMint(address _to, uint256 _tokenId) external;\\n\\n /**\\n * @notice Burns a token ID from a user.\\n *\\n * @param _from Address of the user to burn the token from.\\n * @param _tokenId Token ID to burn.\\n */\\n function burn(address _from, uint256 _tokenId) external;\\n}\\n\",\"keccak256\":\"0xc3703030d0093d65839b02296e3152681fa1c8d717e66ab3f5a7c32ba3fd0a54\",\"license\":\"MIT\"},\"contracts/universal/op-erc721/OptimismMintableERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {\\n ERC721Enumerable\\n} from \\\"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\\\";\\nimport { ERC721 } from \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport { IERC165 } from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport { IOptimismMintableERC721 } from \\\"./IOptimismMintableERC721.sol\\\";\\n\\n/**\\n * @title OptimismMintableERC721\\n * @notice This contract is the remote representation for some token that lives on another network,\\n * typically an Optimism representation of an Ethereum-based token. Standard reference\\n * implementation that can be extended or modified according to your needs.\\n */\\ncontract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721 {\\n /**\\n * @inheritdoc IOptimismMintableERC721\\n */\\n uint256 public immutable remoteChainId;\\n\\n /**\\n * @inheritdoc IOptimismMintableERC721\\n */\\n address public immutable remoteToken;\\n\\n /**\\n * @inheritdoc IOptimismMintableERC721\\n */\\n address public immutable bridge;\\n\\n /**\\n * @notice Base token URI for this token.\\n */\\n string public baseTokenURI;\\n\\n /**\\n * @param _bridge Address of the bridge on this network.\\n * @param _remoteChainId Chain ID where the remote token is deployed.\\n * @param _remoteToken Address of the corresponding token on the other network.\\n * @param _name ERC721 name.\\n * @param _symbol ERC721 symbol.\\n */\\n constructor(\\n address _bridge,\\n uint256 _remoteChainId,\\n address _remoteToken,\\n string memory _name,\\n string memory _symbol\\n ) ERC721(_name, _symbol) {\\n require(_bridge != address(0), \\\"OptimismMintableERC721: bridge cannot be address(0)\\\");\\n require(_remoteChainId != 0, \\\"OptimismMintableERC721: remote chain id cannot be zero\\\");\\n require(\\n _remoteToken != address(0),\\n \\\"OptimismMintableERC721: remote token cannot be address(0)\\\"\\n );\\n\\n remoteChainId = _remoteChainId;\\n remoteToken = _remoteToken;\\n bridge = _bridge;\\n\\n // Creates a base URI in the format specified by EIP-681:\\n // https://eips.ethereum.org/EIPS/eip-681\\n baseTokenURI = string(\\n abi.encodePacked(\\n \\\"ethereum:\\\",\\n Strings.toHexString(uint160(_remoteToken), 20),\\n \\\"@\\\",\\n Strings.toString(_remoteChainId),\\n \\\"/tokenURI?uint256=\\\"\\n )\\n );\\n }\\n\\n /**\\n * @notice Modifier that prevents callers other than the bridge from calling the function.\\n */\\n modifier onlyBridge() {\\n require(msg.sender == bridge, \\\"OptimismMintableERC721: only bridge can call this function\\\");\\n _;\\n }\\n\\n /**\\n * @inheritdoc IOptimismMintableERC721\\n */\\n function safeMint(address _to, uint256 _tokenId) external virtual onlyBridge {\\n _safeMint(_to, _tokenId);\\n\\n emit Mint(_to, _tokenId);\\n }\\n\\n /**\\n * @inheritdoc IOptimismMintableERC721\\n */\\n function burn(address _from, uint256 _tokenId) external virtual onlyBridge {\\n _burn(_tokenId);\\n\\n emit Burn(_from, _tokenId);\\n }\\n\\n /**\\n * @notice Checks if a given interface ID is supported by this contract.\\n *\\n * @param _interfaceId The interface ID to check.\\n *\\n * @return True if the interface ID is supported, false otherwise.\\n */\\n function supportsInterface(bytes4 _interfaceId)\\n public\\n view\\n override(ERC721Enumerable, IERC165)\\n returns (bool)\\n {\\n bytes4 iface1 = type(IERC165).interfaceId;\\n bytes4 iface2 = type(IOptimismMintableERC721).interfaceId;\\n return\\n _interfaceId == iface1 ||\\n _interfaceId == iface2 ||\\n super.supportsInterface(_interfaceId);\\n }\\n\\n /**\\n * @notice Returns the base token URI.\\n *\\n * @return Base token URI.\\n */\\n function _baseURI() internal view virtual override returns (string memory) {\\n return baseTokenURI;\\n }\\n}\\n\",\"keccak256\":\"0x5ab0e15ecf5617db181396e9c95087fb403e3276527b6426ae3845ec50514d36\",\"license\":\"MIT\"},\"contracts/universal/op-erc721/OptimismMintableERC721Factory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { OptimismMintableERC721 } from \\\"./OptimismMintableERC721.sol\\\";\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title OptimismMintableERC721Factory\\n * @notice Factory contract for creating OptimismMintableERC721 contracts.\\n */\\ncontract OptimismMintableERC721Factory is Semver {\\n /**\\n * @notice Emitted whenever a new OptimismMintableERC721 contract is created.\\n *\\n * @param localToken Address of the token on the this domain.\\n * @param remoteToken Address of the token on the remote domain.\\n * @param deployer Address of the initiator of the deployment\\n */\\n event OptimismMintableERC721Created(\\n address indexed localToken,\\n address indexed remoteToken,\\n address deployer\\n );\\n\\n /**\\n * @notice Address of the ERC721 bridge on this network.\\n */\\n address public immutable bridge;\\n\\n /**\\n * @notice Chain ID for the remote network.\\n */\\n uint256 public immutable remoteChainId;\\n\\n /**\\n * @notice Tracks addresses created by this factory.\\n */\\n mapping(address => bool) public isOptimismMintableERC721;\\n\\n /**\\n * @custom:semver 1.0.0\\n *\\n * @param _bridge Address of the ERC721 bridge on this network.\\n */\\n constructor(address _bridge, uint256 _remoteChainId) Semver(1, 0, 0) {\\n require(\\n _bridge != address(0),\\n \\\"OptimismMintableERC721Factory: bridge cannot be address(0)\\\"\\n );\\n require(\\n _remoteChainId != 0,\\n \\\"OptimismMintableERC721Factory: remote chain id cannot be zero\\\"\\n );\\n\\n bridge = _bridge;\\n remoteChainId = _remoteChainId;\\n }\\n\\n /**\\n * @notice Creates an instance of the standard ERC721.\\n *\\n * @param _remoteToken Address of the corresponding token on the other domain.\\n * @param _name ERC721 name.\\n * @param _symbol ERC721 symbol.\\n */\\n function createOptimismMintableERC721(\\n address _remoteToken,\\n string memory _name,\\n string memory _symbol\\n ) external returns (address) {\\n require(\\n _remoteToken != address(0),\\n \\\"OptimismMintableERC721Factory: L1 token address cannot be address(0)\\\"\\n );\\n\\n address localToken = address(\\n new OptimismMintableERC721(bridge, remoteChainId, _remoteToken, _name, _symbol)\\n );\\n\\n isOptimismMintableERC721[localToken] = true;\\n emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);\\n\\n return localToken;\\n }\\n}\\n\",\"keccak256\":\"0xf53ee39e9ca7baa5d1c234e58068f9195be1d4c5180a4862356de86294563ba5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x61012060405234801561001157600080fd5b506040516139b33803806139b38339810160408190526100309161014d565b6001608052600060a081905260c0526001600160a01b0382166100c05760405162461bcd60e51b815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c65455243373231466163746f72793a206260448201527f72696467652063616e6e6f74206265206164647265737328302900000000000060648201526084015b60405180910390fd5b806000036101365760405162461bcd60e51b815260206004820152603d60248201527f4f7074696d69736d4d696e7461626c65455243373231466163746f72793a207260448201527f656d6f746520636861696e2069642063616e6e6f74206265207a65726f00000060648201526084016100b7565b6001600160a01b0390911660e05261010052610187565b6000806040838503121561016057600080fd5b82516001600160a01b038116811461017757600080fd5b6020939093015192949293505050565b60805160a05160c05160e051610100516137da6101d960003960008181610138015261030a01526000818161011001526102e9015260006101c70152600061019c0152600061017101526137da6000f3fe60806040523480156200001157600080fd5b50600436106200006f5760003560e01c8063d97df6521162000056578063d97df65214620000cd578063e78cea92146200010a578063e9518196146200013257600080fd5b806354fd4d5014620000745780635572acae1462000096575b600080fd5b6200007e62000169565b6040516200008d9190620005dc565b60405180910390f35b620000bc620000a736600462000622565b60006020819052908152604090205460ff1681565b60405190151581526020016200008d565b620000e4620000de36600462000722565b62000214565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016200008d565b620000e47f000000000000000000000000000000000000000000000000000000000000000081565b6200015a7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016200008d565b6060620001967f0000000000000000000000000000000000000000000000000000000000000000620003fa565b620001c17f0000000000000000000000000000000000000000000000000000000000000000620003fa565b620001ec7f0000000000000000000000000000000000000000000000000000000000000000620003fa565b60405160200162000200939291906200079f565b604051602081830303815290604052905090565b600073ffffffffffffffffffffffffffffffffffffffff8416620002e5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4f7074696d69736d4d696e7461626c65455243373231466163746f72793a204c908201527f3120746f6b656e20616464726573732063616e6e6f742062652061646472657360648201527f7328302900000000000000000000000000000000000000000000000000000000608482015260a40160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008686866040516200033a906200054f565b6200034a9594939291906200081b565b604051809103906000f08015801562000367573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff8181166000818152602081815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590513381529394509188169290917fe72783bb8e0ca31286b85278da59684dd814df9762a52f0837f89edd1483b299910160405180910390a3949350505050565b6060816000036200043e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156200046e57806200045581620008ab565b9150620004669050600a8362000915565b915062000442565b60008167ffffffffffffffff8111156200048c576200048c62000640565b6040519080825280601f01601f191660200182016040528015620004b7576020820181803683370190505b5090505b84156200054757620004cf6001836200092c565b9150620004de600a8662000946565b620004eb9060306200095d565b60f81b81838151811062000503576200050362000978565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506200053f600a8662000915565b9450620004bb565b949350505050565b612dfd80620009a883390190565b60005b838110156200057a57818101518382015260200162000560565b838111156200058a576000848401525b50505050565b60008151808452620005aa8160208601602086016200055d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005f1602083018462000590565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061d57600080fd5b919050565b6000602082840312156200063557600080fd5b620005f182620005f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200068157600080fd5b813567ffffffffffffffff808211156200069f576200069f62000640565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006e857620006e862000640565b816040528381528660208588010111156200070257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200073857600080fd5b6200074384620005f8565b9250602084013567ffffffffffffffff808211156200076157600080fd5b6200076f878388016200066f565b935060408601359150808211156200078657600080fd5b5062000795868287016200066f565b9150509250925092565b60008451620007b38184602089016200055d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551620007f1816001850160208a016200055d565b600192019182015283516200080e8160028401602088016200055d565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835286602084015280861660408401525060a060608301526200085c60a083018562000590565b828103608084015262000870818562000590565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620008df57620008df6200087c565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082620009275762000927620008e6565b500490565b6000828210156200094157620009416200087c565b500390565b600082620009585762000958620008e6565b500690565b600082198211156200097357620009736200087c565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe60e06040523480156200001157600080fd5b5060405162002dfd38038062002dfd83398101604081905262000034916200062d565b8181600062000044838262000756565b50600162000053828262000756565b5050506001600160a01b038516620000d85760405162461bcd60e51b815260206004820152603360248201527f4f7074696d69736d4d696e7461626c654552433732313a20627269646765206360448201527f616e6e6f7420626520616464726573732830290000000000000000000000000060648201526084015b60405180910390fd5b83600003620001505760405162461bcd60e51b815260206004820152603660248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465206360448201527f6861696e2069642063616e6e6f74206265207a65726f000000000000000000006064820152608401620000cf565b6001600160a01b038316620001ce5760405162461bcd60e51b815260206004820152603960248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465207460448201527f6f6b656e2063616e6e6f742062652061646472657373283029000000000000006064820152608401620000cf565b60808490526001600160a01b0383811660a081905290861660c0526200020290601462000256602090811b62000dd217901c565b62000218856200041660201b62000ffb1760201c565b6040516020016200022b92919062000822565b604051602081830303815290604052600a90816200024a919062000756565b50505050505062000993565b6060600062000267836002620008ac565b62000274906002620008ce565b6001600160401b038111156200028e576200028e62000553565b6040519080825280601f01601f191660200182016040528015620002b9576020820181803683370190505b509050600360fc1b81600081518110620002d757620002d7620008e9565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110620003095762000309620008e9565b60200101906001600160f81b031916908160001a90535060006200032f846002620008ac565b6200033c906001620008ce565b90505b6001811115620003be576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110620003745762000374620008e9565b1a60f81b8282815181106200038d576200038d620008e9565b60200101906001600160f81b031916908160001a90535060049490941c93620003b681620008ff565b90506200033f565b5083156200040f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620000cf565b9392505050565b6060816000036200043e5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156200046e5780620004558162000919565b9150620004669050600a836200094b565b915062000442565b6000816001600160401b038111156200048b576200048b62000553565b6040519080825280601f01601f191660200182016040528015620004b6576020820181803683370190505b5090505b84156200052e57620004ce60018362000962565b9150620004dd600a866200097c565b620004ea906030620008ce565b60f81b818381518110620005025762000502620008e9565b60200101906001600160f81b031916908160001a90535062000526600a866200094b565b9450620004ba565b949350505050565b80516001600160a01b03811681146200054e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620005865781810151838201526020016200056c565b8381111562000596576000848401525b50505050565b600082601f830112620005ae57600080fd5b81516001600160401b0380821115620005cb57620005cb62000553565b604051601f8301601f19908116603f01168101908282118183101715620005f657620005f662000553565b816040528381528660208588010111156200061057600080fd5b6200062384602083016020890162000569565b9695505050505050565b600080600080600060a086880312156200064657600080fd5b620006518662000536565b945060208601519350620006686040870162000536565b60608701519093506001600160401b03808211156200068657600080fd5b6200069489838a016200059c565b93506080880151915080821115620006ab57600080fd5b50620006ba888289016200059c565b9150509295509295909350565b600181811c90821680620006dc57607f821691505b602082108103620006fd57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200075157600081815260208120601f850160051c810160208610156200072c5750805b601f850160051c820191505b818110156200074d5782815560010162000738565b5050505b505050565b81516001600160401b0381111562000772576200077262000553565b6200078a81620007838454620006c7565b8462000703565b602080601f831160018114620007c25760008415620007a95750858301515b600019600386901b1c1916600185901b1785556200074d565b600085815260208120601f198616915b82811015620007f357888601518255948401946001909101908401620007d2565b5085821015620008125787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6832ba3432b932bab69d60b91b8152600083516200084881600985016020880162000569565b600160fe1b60099184019182015283516200086b81600a84016020880162000569565b712f746f6b656e5552493f75696e743235363d60701b600a9290910191820152601c01949350505050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620008c957620008c962000896565b500290565b60008219821115620008e457620008e462000896565b500190565b634e487b7160e01b600052603260045260246000fd5b60008162000911576200091162000896565b506000190190565b6000600182016200092e576200092e62000896565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826200095d576200095d62000935565b500490565b60008282101562000977576200097762000896565b500390565b6000826200098e576200098e62000935565b500690565b60805160a05160c05161242c620009d160003960008181610323015281816109f80152610ae6015260006102fc0152600061034a015261242c6000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806395d89b41116100d8578063c87b56dd1161008c578063e78cea9211610066578063e78cea921461031e578063e951819614610345578063e985e9c51461036c57600080fd5b8063c87b56dd146102dc578063d547cfb7146102ef578063d6c0b2c4146102f757600080fd5b8063a1448194116100bd578063a1448194146102a3578063a22cb465146102b6578063b88d4fde146102c957600080fd5b806395d89b41146102885780639dc29fac1461029057600080fd5b806323b872dd1161013a5780634f6ccce7116101145780634f6ccce71461024f5780636352211e1461026257806370a082311461027557600080fd5b806323b872dd146102165780632f745c591461022957806342842e0e1461023c57600080fd5b8063081812fc1161016b578063081812fc146101c4578063095ea7b3146101ef57806318160ddd1461020457600080fd5b806301ffc9a71461018757806306fdde03146101af575b600080fd5b61019a610195366004611e6a565b6103a8565b60405190151581526020015b60405180910390f35b6101b7610457565b6040516101a69190611efd565b6101d76101d2366004611f10565b6104e9565b6040516001600160a01b0390911681526020016101a6565b6102026101fd366004611f45565b610594565b005b6008545b6040519081526020016101a6565b610202610224366004611f6f565b6106c5565b610208610237366004611f45565b61074c565b61020261024a366004611f6f565b6107f4565b61020861025d366004611f10565b61080f565b6101d7610270366004611f10565b6108b3565b610208610283366004611fab565b610944565b6101b76109de565b61020261029e366004611f45565b6109ed565b6102026102b1366004611f45565b610adb565b6102026102c4366004611fc6565b610bbe565b6102026102d7366004612031565b610bcd565b6101b76102ea366004611f10565b610c5b565b6101b7610d44565b6101d77f000000000000000000000000000000000000000000000000000000000000000081565b6101d77f000000000000000000000000000000000000000000000000000000000000000081565b6102087f000000000000000000000000000000000000000000000000000000000000000081565b61019a61037a36600461212b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fe49bc7f8000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000841682148061044057507fffffffff00000000000000000000000000000000000000000000000000000000848116908216145b8061044f575061044f84611130565b949350505050565b6060600080546104669061215e565b80601f01602080910402602001604051908101604052809291908181526020018280546104929061215e565b80156104df5780601f106104b4576101008083540402835291602001916104df565b820191906000526020600020905b8154815290600101906020018083116104c257829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166105785760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061059f826108b3565b9050806001600160a01b0316836001600160a01b0316036106285760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f7200000000000000000000000000000000000000000000000000000000000000606482015260840161056f565b336001600160a01b03821614806106445750610644813361037a565b6106b65760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161056f565b6106c08383611186565b505050565b6106cf338261120c565b6107415760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f766564000000000000000000000000000000606482015260840161056f565b6106c0838383611313565b600061075783610944565b82106107cb5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e6473000000000000000000000000000000000000000000606482015260840161056f565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6106c083838360405180602001604052806000815250610bcd565b600061081a60085490565b821061088e5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e64730000000000000000000000000000000000000000606482015260840161056f565b600882815481106108a1576108a16121b1565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b03168061093e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e0000000000000000000000000000000000000000000000606482015260840161056f565b92915050565b60006001600160a01b0382166109c25760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f206164647265737300000000000000000000000000000000000000000000606482015260840161056f565b506001600160a01b031660009081526003602052604090205490565b6060600180546104669061215e565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a8b5760405162461bcd60e51b815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e000000000000606482015260840161056f565b610a9481611503565b816001600160a01b03167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca582604051610acf91815260200190565b60405180910390a25050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b795760405162461bcd60e51b815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e000000000000606482015260840161056f565b610b8382826115c2565b816001600160a01b03167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610acf91815260200190565b610bc93383836115dc565b5050565b610bd7338361120c565b610c495760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f766564000000000000000000000000000000606482015260840161056f565b610c55848484846116c8565b50505050565b6000818152600260205260409020546060906001600160a01b0316610ce85760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000606482015260840161056f565b6000610cf2611751565b90506000815111610d125760405180602001604052806000815250610d3d565b80610d1c84610ffb565b604051602001610d2d9291906121e0565b6040516020818303038152906040525b9392505050565b600a8054610d519061215e565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7d9061215e565b8015610dca5780601f10610d9f57610100808354040283529160200191610dca565b820191906000526020600020905b815481529060010190602001808311610dad57829003601f168201915b505050505081565b60606000610de183600261223e565b610dec90600261227b565b67ffffffffffffffff811115610e0457610e04612002565b6040519080825280601f01601f191660200182016040528015610e2e576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110610e6557610e656121b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110610ec857610ec86121b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000610f0484600261223e565b610f0f90600161227b565b90505b6001811115610fac577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110610f5057610f506121b1565b1a60f81b828281518110610f6657610f666121b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93610fa581612293565b9050610f12565b508315610d3d5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161056f565b60608160000361103e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156110685780611052816122c8565b91506110619050600a8361232f565b9150611042565b60008167ffffffffffffffff81111561108357611083612002565b6040519080825280601f01601f1916602001820160405280156110ad576020820181803683370190505b5090505b841561044f576110c2600183612343565b91506110cf600a8661235a565b6110da90603061227b565b60f81b8183815181106110ef576110ef6121b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611129600a8661232f565b94506110b1565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d6300000000000000000000000000000000000000000000000000000000148061093e575061093e82611760565b600081815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03841690811790915581906111d3826108b3565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b03166112965760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e0000000000000000000000000000000000000000606482015260840161056f565b60006112a1836108b3565b9050806001600160a01b0316846001600160a01b031614806112e857506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b8061044f5750836001600160a01b0316611301846104e9565b6001600160a01b031614949350505050565b826001600160a01b0316611326826108b3565b6001600160a01b0316146113a25760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e6572000000000000000000000000000000000000000000000000000000606482015260840161056f565b6001600160a01b03821661141d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161056f565b611428838383611843565b611433600082611186565b6001600160a01b038316600090815260036020526040812080546001929061145c908490612343565b90915550506001600160a01b038216600090815260036020526040812080546001929061148a90849061227b565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061150e826108b3565b905061151c81600084611843565b611527600083611186565b6001600160a01b0381166000908152600360205260408120805460019290611550908490612343565b909155505060008281526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b610bc98282604051806020016040528060008152506118fb565b816001600160a01b0316836001600160a01b03160361163d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161056f565b6001600160a01b0383811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6116d3848484611313565b6116df84848484611984565b610c555760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161056f565b6060600a80546104669061215e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806117f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061093e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161461093e565b6001600160a01b03831661189e5761189981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6118c1565b816001600160a01b0316836001600160a01b0316146118c1576118c18382611b43565b6001600160a01b0382166118d8576106c081611be0565b826001600160a01b0316826001600160a01b0316146106c0576106c08282611c8f565b6119058383611cd3565b6119126000848484611984565b6106c05760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161056f565b60006001600160a01b0384163b15611b38576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a02906119e190339089908890889060040161236e565b6020604051808303816000875af1925050508015611a3a575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611a37918101906123aa565b60015b611aed573d808015611a68576040519150601f19603f3d011682016040523d82523d6000602084013e611a6d565b606091505b508051600003611ae55760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161056f565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a020000000000000000000000000000000000000000000000000000000014905061044f565b506001949350505050565b60006001611b5084610944565b611b5a9190612343565b600083815260076020526040902054909150808214611bad576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090611bf290600190612343565b60008381526009602052604081205460088054939450909284908110611c1a57611c1a6121b1565b906000526020600020015490508060088381548110611c3b57611c3b6121b1565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480611c7357611c736123c7565b6001900381819060005260206000200160009055905550505050565b6000611c9a83610944565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216611d295760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161056f565b6000818152600260205260409020546001600160a01b031615611d8e5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161056f565b611d9a60008383611843565b6001600160a01b0382166000908152600360205260408120805460019290611dc390849061227b565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e6757600080fd5b50565b600060208284031215611e7c57600080fd5b8135610d3d81611e39565b60005b83811015611ea2578181015183820152602001611e8a565b83811115610c555750506000910152565b60008151808452611ecb816020860160208601611e87565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610d3d6020830184611eb3565b600060208284031215611f2257600080fd5b5035919050565b80356001600160a01b0381168114611f4057600080fd5b919050565b60008060408385031215611f5857600080fd5b611f6183611f29565b946020939093013593505050565b600080600060608486031215611f8457600080fd5b611f8d84611f29565b9250611f9b60208501611f29565b9150604084013590509250925092565b600060208284031215611fbd57600080fd5b610d3d82611f29565b60008060408385031215611fd957600080fd5b611fe283611f29565b915060208301358015158114611ff757600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561204757600080fd5b61205085611f29565b935061205e60208601611f29565b925060408501359150606085013567ffffffffffffffff8082111561208257600080fd5b818701915087601f83011261209657600080fd5b8135818111156120a8576120a8612002565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156120ee576120ee612002565b816040528281528a602084870101111561210757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561213e57600080fd5b61214783611f29565b915061215560208401611f29565b90509250929050565b600181811c9082168061217257607f821691505b6020821081036121ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600083516121f2818460208801611e87565b835190830190612206818360208801611e87565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156122765761227661220f565b500290565b6000821982111561228e5761228e61220f565b500190565b6000816122a2576122a261220f565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036122f9576122f961220f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261233e5761233e612300565b500490565b6000828210156123555761235561220f565b500390565b60008261236957612369612300565b500690565b60006001600160a01b038087168352808616602084015250836040830152608060608301526123a06080830184611eb3565b9695505050505050565b6000602082840312156123bc57600080fd5b8151610d3d81611e39565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220091cfc6e67938e5e9e61881af7ded22673b926104a9d05247aaec2f673e28e7364736f6c634300080f0033a2646970667358221220e0ec23cedfe5d74b2d927547b5882cd7e2b775e04cdebb66d2280c7da8786df664736f6c634300080f0033", - "deployedBytecode": "0x60806040523480156200001157600080fd5b50600436106200006f5760003560e01c8063d97df6521162000056578063d97df65214620000cd578063e78cea92146200010a578063e9518196146200013257600080fd5b806354fd4d5014620000745780635572acae1462000096575b600080fd5b6200007e62000169565b6040516200008d9190620005dc565b60405180910390f35b620000bc620000a736600462000622565b60006020819052908152604090205460ff1681565b60405190151581526020016200008d565b620000e4620000de36600462000722565b62000214565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016200008d565b620000e47f000000000000000000000000000000000000000000000000000000000000000081565b6200015a7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016200008d565b6060620001967f0000000000000000000000000000000000000000000000000000000000000000620003fa565b620001c17f0000000000000000000000000000000000000000000000000000000000000000620003fa565b620001ec7f0000000000000000000000000000000000000000000000000000000000000000620003fa565b60405160200162000200939291906200079f565b604051602081830303815290604052905090565b600073ffffffffffffffffffffffffffffffffffffffff8416620002e5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4f7074696d69736d4d696e7461626c65455243373231466163746f72793a204c908201527f3120746f6b656e20616464726573732063616e6e6f742062652061646472657360648201527f7328302900000000000000000000000000000000000000000000000000000000608482015260a40160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008686866040516200033a906200054f565b6200034a9594939291906200081b565b604051809103906000f08015801562000367573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff8181166000818152602081815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590513381529394509188169290917fe72783bb8e0ca31286b85278da59684dd814df9762a52f0837f89edd1483b299910160405180910390a3949350505050565b6060816000036200043e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156200046e57806200045581620008ab565b9150620004669050600a8362000915565b915062000442565b60008167ffffffffffffffff8111156200048c576200048c62000640565b6040519080825280601f01601f191660200182016040528015620004b7576020820181803683370190505b5090505b84156200054757620004cf6001836200092c565b9150620004de600a8662000946565b620004eb9060306200095d565b60f81b81838151811062000503576200050362000978565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506200053f600a8662000915565b9450620004bb565b949350505050565b612dfd80620009a883390190565b60005b838110156200057a57818101518382015260200162000560565b838111156200058a576000848401525b50505050565b60008151808452620005aa8160208601602086016200055d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005f1602083018462000590565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061d57600080fd5b919050565b6000602082840312156200063557600080fd5b620005f182620005f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200068157600080fd5b813567ffffffffffffffff808211156200069f576200069f62000640565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006e857620006e862000640565b816040528381528660208588010111156200070257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200073857600080fd5b6200074384620005f8565b9250602084013567ffffffffffffffff808211156200076157600080fd5b6200076f878388016200066f565b935060408601359150808211156200078657600080fd5b5062000795868287016200066f565b9150509250925092565b60008451620007b38184602089016200055d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551620007f1816001850160208a016200055d565b600192019182015283516200080e8160028401602088016200055d565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835286602084015280861660408401525060a060608301526200085c60a083018562000590565b828103608084015262000870818562000590565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620008df57620008df6200087c565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082620009275762000927620008e6565b500490565b6000828210156200094157620009416200087c565b500390565b600082620009585762000958620008e6565b500690565b600082198211156200097357620009736200087c565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe60e06040523480156200001157600080fd5b5060405162002dfd38038062002dfd83398101604081905262000034916200062d565b8181600062000044838262000756565b50600162000053828262000756565b5050506001600160a01b038516620000d85760405162461bcd60e51b815260206004820152603360248201527f4f7074696d69736d4d696e7461626c654552433732313a20627269646765206360448201527f616e6e6f7420626520616464726573732830290000000000000000000000000060648201526084015b60405180910390fd5b83600003620001505760405162461bcd60e51b815260206004820152603660248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465206360448201527f6861696e2069642063616e6e6f74206265207a65726f000000000000000000006064820152608401620000cf565b6001600160a01b038316620001ce5760405162461bcd60e51b815260206004820152603960248201527f4f7074696d69736d4d696e7461626c654552433732313a2072656d6f7465207460448201527f6f6b656e2063616e6e6f742062652061646472657373283029000000000000006064820152608401620000cf565b60808490526001600160a01b0383811660a081905290861660c0526200020290601462000256602090811b62000dd217901c565b62000218856200041660201b62000ffb1760201c565b6040516020016200022b92919062000822565b604051602081830303815290604052600a90816200024a919062000756565b50505050505062000993565b6060600062000267836002620008ac565b62000274906002620008ce565b6001600160401b038111156200028e576200028e62000553565b6040519080825280601f01601f191660200182016040528015620002b9576020820181803683370190505b509050600360fc1b81600081518110620002d757620002d7620008e9565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110620003095762000309620008e9565b60200101906001600160f81b031916908160001a90535060006200032f846002620008ac565b6200033c906001620008ce565b90505b6001811115620003be576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110620003745762000374620008e9565b1a60f81b8282815181106200038d576200038d620008e9565b60200101906001600160f81b031916908160001a90535060049490941c93620003b681620008ff565b90506200033f565b5083156200040f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620000cf565b9392505050565b6060816000036200043e5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156200046e5780620004558162000919565b9150620004669050600a836200094b565b915062000442565b6000816001600160401b038111156200048b576200048b62000553565b6040519080825280601f01601f191660200182016040528015620004b6576020820181803683370190505b5090505b84156200052e57620004ce60018362000962565b9150620004dd600a866200097c565b620004ea906030620008ce565b60f81b818381518110620005025762000502620008e9565b60200101906001600160f81b031916908160001a90535062000526600a866200094b565b9450620004ba565b949350505050565b80516001600160a01b03811681146200054e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620005865781810151838201526020016200056c565b8381111562000596576000848401525b50505050565b600082601f830112620005ae57600080fd5b81516001600160401b0380821115620005cb57620005cb62000553565b604051601f8301601f19908116603f01168101908282118183101715620005f657620005f662000553565b816040528381528660208588010111156200061057600080fd5b6200062384602083016020890162000569565b9695505050505050565b600080600080600060a086880312156200064657600080fd5b620006518662000536565b945060208601519350620006686040870162000536565b60608701519093506001600160401b03808211156200068657600080fd5b6200069489838a016200059c565b93506080880151915080821115620006ab57600080fd5b50620006ba888289016200059c565b9150509295509295909350565b600181811c90821680620006dc57607f821691505b602082108103620006fd57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200075157600081815260208120601f850160051c810160208610156200072c5750805b601f850160051c820191505b818110156200074d5782815560010162000738565b5050505b505050565b81516001600160401b0381111562000772576200077262000553565b6200078a81620007838454620006c7565b8462000703565b602080601f831160018114620007c25760008415620007a95750858301515b600019600386901b1c1916600185901b1785556200074d565b600085815260208120601f198616915b82811015620007f357888601518255948401946001909101908401620007d2565b5085821015620008125787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6832ba3432b932bab69d60b91b8152600083516200084881600985016020880162000569565b600160fe1b60099184019182015283516200086b81600a84016020880162000569565b712f746f6b656e5552493f75696e743235363d60701b600a9290910191820152601c01949350505050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620008c957620008c962000896565b500290565b60008219821115620008e457620008e462000896565b500190565b634e487b7160e01b600052603260045260246000fd5b60008162000911576200091162000896565b506000190190565b6000600182016200092e576200092e62000896565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826200095d576200095d62000935565b500490565b60008282101562000977576200097762000896565b500390565b6000826200098e576200098e62000935565b500690565b60805160a05160c05161242c620009d160003960008181610323015281816109f80152610ae6015260006102fc0152600061034a015261242c6000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806395d89b41116100d8578063c87b56dd1161008c578063e78cea9211610066578063e78cea921461031e578063e951819614610345578063e985e9c51461036c57600080fd5b8063c87b56dd146102dc578063d547cfb7146102ef578063d6c0b2c4146102f757600080fd5b8063a1448194116100bd578063a1448194146102a3578063a22cb465146102b6578063b88d4fde146102c957600080fd5b806395d89b41146102885780639dc29fac1461029057600080fd5b806323b872dd1161013a5780634f6ccce7116101145780634f6ccce71461024f5780636352211e1461026257806370a082311461027557600080fd5b806323b872dd146102165780632f745c591461022957806342842e0e1461023c57600080fd5b8063081812fc1161016b578063081812fc146101c4578063095ea7b3146101ef57806318160ddd1461020457600080fd5b806301ffc9a71461018757806306fdde03146101af575b600080fd5b61019a610195366004611e6a565b6103a8565b60405190151581526020015b60405180910390f35b6101b7610457565b6040516101a69190611efd565b6101d76101d2366004611f10565b6104e9565b6040516001600160a01b0390911681526020016101a6565b6102026101fd366004611f45565b610594565b005b6008545b6040519081526020016101a6565b610202610224366004611f6f565b6106c5565b610208610237366004611f45565b61074c565b61020261024a366004611f6f565b6107f4565b61020861025d366004611f10565b61080f565b6101d7610270366004611f10565b6108b3565b610208610283366004611fab565b610944565b6101b76109de565b61020261029e366004611f45565b6109ed565b6102026102b1366004611f45565b610adb565b6102026102c4366004611fc6565b610bbe565b6102026102d7366004612031565b610bcd565b6101b76102ea366004611f10565b610c5b565b6101b7610d44565b6101d77f000000000000000000000000000000000000000000000000000000000000000081565b6101d77f000000000000000000000000000000000000000000000000000000000000000081565b6102087f000000000000000000000000000000000000000000000000000000000000000081565b61019a61037a36600461212b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fe49bc7f8000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000841682148061044057507fffffffff00000000000000000000000000000000000000000000000000000000848116908216145b8061044f575061044f84611130565b949350505050565b6060600080546104669061215e565b80601f01602080910402602001604051908101604052809291908181526020018280546104929061215e565b80156104df5780601f106104b4576101008083540402835291602001916104df565b820191906000526020600020905b8154815290600101906020018083116104c257829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166105785760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061059f826108b3565b9050806001600160a01b0316836001600160a01b0316036106285760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f7200000000000000000000000000000000000000000000000000000000000000606482015260840161056f565b336001600160a01b03821614806106445750610644813361037a565b6106b65760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161056f565b6106c08383611186565b505050565b6106cf338261120c565b6107415760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f766564000000000000000000000000000000606482015260840161056f565b6106c0838383611313565b600061075783610944565b82106107cb5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e6473000000000000000000000000000000000000000000606482015260840161056f565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6106c083838360405180602001604052806000815250610bcd565b600061081a60085490565b821061088e5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e64730000000000000000000000000000000000000000606482015260840161056f565b600882815481106108a1576108a16121b1565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b03168061093e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e0000000000000000000000000000000000000000000000606482015260840161056f565b92915050565b60006001600160a01b0382166109c25760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f206164647265737300000000000000000000000000000000000000000000606482015260840161056f565b506001600160a01b031660009081526003602052604090205490565b6060600180546104669061215e565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a8b5760405162461bcd60e51b815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e000000000000606482015260840161056f565b610a9481611503565b816001600160a01b03167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca582604051610acf91815260200190565b60405180910390a25050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b795760405162461bcd60e51b815260206004820152603a60248201527f4f7074696d69736d4d696e7461626c654552433732313a206f6e6c792062726960448201527f6467652063616e2063616c6c20746869732066756e6374696f6e000000000000606482015260840161056f565b610b8382826115c2565b816001600160a01b03167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610acf91815260200190565b610bc93383836115dc565b5050565b610bd7338361120c565b610c495760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f766564000000000000000000000000000000606482015260840161056f565b610c55848484846116c8565b50505050565b6000818152600260205260409020546060906001600160a01b0316610ce85760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000606482015260840161056f565b6000610cf2611751565b90506000815111610d125760405180602001604052806000815250610d3d565b80610d1c84610ffb565b604051602001610d2d9291906121e0565b6040516020818303038152906040525b9392505050565b600a8054610d519061215e565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7d9061215e565b8015610dca5780601f10610d9f57610100808354040283529160200191610dca565b820191906000526020600020905b815481529060010190602001808311610dad57829003601f168201915b505050505081565b60606000610de183600261223e565b610dec90600261227b565b67ffffffffffffffff811115610e0457610e04612002565b6040519080825280601f01601f191660200182016040528015610e2e576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110610e6557610e656121b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110610ec857610ec86121b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000610f0484600261223e565b610f0f90600161227b565b90505b6001811115610fac577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110610f5057610f506121b1565b1a60f81b828281518110610f6657610f666121b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93610fa581612293565b9050610f12565b508315610d3d5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161056f565b60608160000361103e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156110685780611052816122c8565b91506110619050600a8361232f565b9150611042565b60008167ffffffffffffffff81111561108357611083612002565b6040519080825280601f01601f1916602001820160405280156110ad576020820181803683370190505b5090505b841561044f576110c2600183612343565b91506110cf600a8661235a565b6110da90603061227b565b60f81b8183815181106110ef576110ef6121b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611129600a8661232f565b94506110b1565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d6300000000000000000000000000000000000000000000000000000000148061093e575061093e82611760565b600081815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03841690811790915581906111d3826108b3565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b03166112965760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e0000000000000000000000000000000000000000606482015260840161056f565b60006112a1836108b3565b9050806001600160a01b0316846001600160a01b031614806112e857506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b8061044f5750836001600160a01b0316611301846104e9565b6001600160a01b031614949350505050565b826001600160a01b0316611326826108b3565b6001600160a01b0316146113a25760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e6572000000000000000000000000000000000000000000000000000000606482015260840161056f565b6001600160a01b03821661141d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161056f565b611428838383611843565b611433600082611186565b6001600160a01b038316600090815260036020526040812080546001929061145c908490612343565b90915550506001600160a01b038216600090815260036020526040812080546001929061148a90849061227b565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061150e826108b3565b905061151c81600084611843565b611527600083611186565b6001600160a01b0381166000908152600360205260408120805460019290611550908490612343565b909155505060008281526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b610bc98282604051806020016040528060008152506118fb565b816001600160a01b0316836001600160a01b03160361163d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161056f565b6001600160a01b0383811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6116d3848484611313565b6116df84848484611984565b610c555760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161056f565b6060600a80546104669061215e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806117f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061093e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161461093e565b6001600160a01b03831661189e5761189981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6118c1565b816001600160a01b0316836001600160a01b0316146118c1576118c18382611b43565b6001600160a01b0382166118d8576106c081611be0565b826001600160a01b0316826001600160a01b0316146106c0576106c08282611c8f565b6119058383611cd3565b6119126000848484611984565b6106c05760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161056f565b60006001600160a01b0384163b15611b38576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a02906119e190339089908890889060040161236e565b6020604051808303816000875af1925050508015611a3a575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611a37918101906123aa565b60015b611aed573d808015611a68576040519150601f19603f3d011682016040523d82523d6000602084013e611a6d565b606091505b508051600003611ae55760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161056f565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a020000000000000000000000000000000000000000000000000000000014905061044f565b506001949350505050565b60006001611b5084610944565b611b5a9190612343565b600083815260076020526040902054909150808214611bad576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090611bf290600190612343565b60008381526009602052604081205460088054939450909284908110611c1a57611c1a6121b1565b906000526020600020015490508060088381548110611c3b57611c3b6121b1565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480611c7357611c736123c7565b6001900381819060005260206000200160009055905550505050565b6000611c9a83610944565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216611d295760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161056f565b6000818152600260205260409020546001600160a01b031615611d8e5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161056f565b611d9a60008383611843565b6001600160a01b0382166000908152600360205260408120805460019290611dc390849061227b565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611e6757600080fd5b50565b600060208284031215611e7c57600080fd5b8135610d3d81611e39565b60005b83811015611ea2578181015183820152602001611e8a565b83811115610c555750506000910152565b60008151808452611ecb816020860160208601611e87565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610d3d6020830184611eb3565b600060208284031215611f2257600080fd5b5035919050565b80356001600160a01b0381168114611f4057600080fd5b919050565b60008060408385031215611f5857600080fd5b611f6183611f29565b946020939093013593505050565b600080600060608486031215611f8457600080fd5b611f8d84611f29565b9250611f9b60208501611f29565b9150604084013590509250925092565b600060208284031215611fbd57600080fd5b610d3d82611f29565b60008060408385031215611fd957600080fd5b611fe283611f29565b915060208301358015158114611ff757600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561204757600080fd5b61205085611f29565b935061205e60208601611f29565b925060408501359150606085013567ffffffffffffffff8082111561208257600080fd5b818701915087601f83011261209657600080fd5b8135818111156120a8576120a8612002565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156120ee576120ee612002565b816040528281528a602084870101111561210757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561213e57600080fd5b61214783611f29565b915061215560208401611f29565b90509250929050565b600181811c9082168061217257607f821691505b6020821081036121ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600083516121f2818460208801611e87565b835190830190612206818360208801611e87565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156122765761227661220f565b500290565b6000821982111561228e5761228e61220f565b500190565b6000816122a2576122a261220f565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036122f9576122f961220f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261233e5761233e612300565b500490565b6000828210156123555761235561220f565b500390565b60008261236957612369612300565b500690565b60006001600160a01b038087168352808616602084015250836040830152608060608301526123a06080830184611eb3565b9695505050505050565b6000602082840312156123bc57600080fd5b8151610d3d81611e39565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220091cfc6e67938e5e9e61881af7ded22673b926104a9d05247aaec2f673e28e7364736f6c634300080f0033a2646970667358221220e0ec23cedfe5d74b2d927547b5882cd7e2b775e04cdebb66d2280c7da8786df664736f6c634300080f0033", - "devdoc": { - "events": { - "OptimismMintableERC721Created(address,address,address)": { - "params": { - "deployer": "Address of the initiator of the deployment", - "localToken": "Address of the token on the this domain.", - "remoteToken": "Address of the token on the remote domain." - } - } - }, - "kind": "dev", - "methods": { - "constructor": { - "custom:semver": "1.0.0", - "params": { - "_bridge": "Address of the ERC721 bridge on this network." - } - }, - "createOptimismMintableERC721(address,string,string)": { - "params": { - "_name": "ERC721 name.", - "_remoteToken": "Address of the corresponding token on the other domain.", - "_symbol": "ERC721 symbol." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "OptimismMintableERC721Factory", - "version": 1 - }, - "userdoc": { - "events": { - "OptimismMintableERC721Created(address,address,address)": { - "notice": "Emitted whenever a new OptimismMintableERC721 contract is created." - } - }, - "kind": "user", - "methods": { - "bridge()": { - "notice": "Address of the ERC721 bridge on this network." - }, - "createOptimismMintableERC721(address,string,string)": { - "notice": "Creates an instance of the standard ERC721." - }, - "isOptimismMintableERC721(address)": { - "notice": "Tracks addresses created by this factory." - }, - "remoteChainId()": { - "notice": "Chain ID for the remote network." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "Factory contract for creating OptimismMintableERC721 contracts.", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 8543, - "contract": "contracts/universal/op-erc721/OptimismMintableERC721Factory.sol:OptimismMintableERC721Factory", - "label": "isOptimismMintableERC721", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_address,t_bool)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_mapping(t_address,t_bool)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => bool)", - "numberOfBytes": "32", - "value": "t_bool" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimismMintableERC721FactoryProxy.json b/packages/contracts-bedrock/deployments/optimism-mainnet/OptimismMintableERC721FactoryProxy.json deleted file mode 100644 index 4c0e4160aa01..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimismMintableERC721FactoryProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x4482B6510dF4C723Bdf80c4441dBDbc855AB29AC", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0xe730ca7b4123d14a445606ce0cf449b3c73c12da907c765c63df04d68f3427bb", - "receipt": { - "to": null, - "from": "0x53A6eecC2dD4795Fcc68940ddc6B4d53Bd88Bd9E", - "contractAddress": "0x4482B6510dF4C723Bdf80c4441dBDbc855AB29AC", - "transactionIndex": 0, - "gasUsed": "532674", - "logsBloom": "0x00000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000008000000020000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc8610148d3e013d22ad9c3d52f6f96c01c9ba33a71bcc2e58dbe058ab5766f82", - "transactionHash": "0xe730ca7b4123d14a445606ce0cf449b3c73c12da907c765c63df04d68f3427bb", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 27396072, - "transactionHash": "0xe730ca7b4123d14a445606ce0cf449b3c73c12da907c765c63df04d68f3427bb", - "address": "0x4482B6510dF4C723Bdf80c4441dBDbc855AB29AC", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053a6eecc2dd4795fcc68940ddc6b4d53bd88bd9e", - "logIndex": 0, - "blockHash": "0xc8610148d3e013d22ad9c3d52f6f96c01c9ba33a71bcc2e58dbe058ab5766f82" - } - ], - "blockNumber": 27396072, - "cumulativeGasUsed": "532674", - "status": 1, - "byzantium": true - }, - "args": [ - "0x53A6eecC2dD4795Fcc68940ddc6B4d53Bd88Bd9E" - ], - "numDeployments": 1, - "solcInputHash": "ab9b77493f35e63b7a63fb2fa8d618b4", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n external\\n payable\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() external proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() external proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/Optimist.json b/packages/contracts-bedrock/deployments/optimism-mainnet/Optimist.json deleted file mode 100644 index abc6e6a12a1a..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/Optimist.json +++ /dev/null @@ -1,883 +0,0 @@ -{ - "address": "0x7c3B29661317a18Ea2bFfc8b5081dBFf60404E52", - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "address", - "name": "_baseURIAttestor", - "type": "address" - }, - { - "internalType": "contract AttestationStation", - "name": "_attestationStation", - "type": "address" - }, - { - "internalType": "contract OptimistAllowlist", - "name": "_optimistAllowlist", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [], - "name": "ATTESTATION_STATION", - "outputs": [ - { - "internalType": "contract AttestationStation", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "BASE_URI_ATTESTATION_KEY", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "BASE_URI_ATTESTOR", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMIST_ALLOWLIST", - "outputs": [ - { - "internalType": "contract OptimistAllowlist", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "burn", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - } - ], - "name": "isOnAllowList", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_recipient", - "type": "address" - } - ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "tokenIdOfAddress", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x3dc847b45e050bf6f3732330d8ac94bf736a1a6fd8a143b6c0dbe0e850009dbb", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "2242451", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000080000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5c2528f97cb45423c2ae91620b75cdf554e3c866e8616bd2b8b47fabbe2b99d3", - "transactionHash": "0x3dc847b45e050bf6f3732330d8ac94bf736a1a6fd8a143b6c0dbe0e850009dbb", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 87032414, - "transactionHash": "0x3dc847b45e050bf6f3732330d8ac94bf736a1a6fd8a143b6c0dbe0e850009dbb", - "address": "0x7c3B29661317a18Ea2bFfc8b5081dBFf60404E52", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 0, - "blockHash": "0x5c2528f97cb45423c2ae91620b75cdf554e3c866e8616bd2b8b47fabbe2b99d3" - } - ], - "blockNumber": 87032414, - "cumulativeGasUsed": "2242451", - "status": 1, - "byzantium": true - }, - "args": [ - "Optimist", - "OPTIMIST", - "0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3", - "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77", - "0x482b1945D58f2E9Db0CEbe13c7fcFc6876b41180" - ], - "numDeployments": 1, - "solcInputHash": "d7155764d4bdb814f10e1bb45296292b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_baseURIAttestor\",\"type\":\"address\"},{\"internalType\":\"contract AttestationStation\",\"name\":\"_attestationStation\",\"type\":\"address\"},{\"internalType\":\"contract OptimistAllowlist\",\"name\":\"_optimistAllowlist\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ATTESTATION_STATION\",\"outputs\":[{\"internalType\":\"contract AttestationStation\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BASE_URI_ATTESTATION_KEY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BASE_URI_ATTESTOR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPTIMIST_ALLOWLIST\",\"outputs\":[{\"internalType\":\"contract OptimistAllowlist\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"baseURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"isOnAllowList\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"tokenIdOfAddress\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Optimism CollectiveGitcoin\",\"kind\":\"dev\",\"methods\":{\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"baseURI()\":{\"returns\":{\"_0\":\"BaseURI for all tokens.\"}},\"burn(uint256)\":{\"details\":\"Burns `tokenId`. See {ERC721-_burn}. Requirements: - The caller must own `tokenId` or be an approved operator.\"},\"constructor\":{\"custom:semver\":\"2.0.0\",\"params\":{\"_attestationStation\":\"Address of the AttestationStation contract.\",\"_baseURIAttestor\":\"Address of the baseURI attestor.\",\"_name\":\"Token name.\",\"_optimistAllowlist\":\"Address of the OptimistAllowlist contract\",\"_symbol\":\"Token symbol.\"}},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"initialize(string,string)\":{\"params\":{\"_name\":\"Token name.\",\"_symbol\":\"Token symbol.\"}},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"isOnAllowList(address)\":{\"returns\":{\"_0\":\"Whether or not the address is allowed to mint yet.\"}},\"mint(address)\":{\"params\":{\"_recipient\":\"Address of the token recipient.\"}},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenIdOfAddress(address)\":{\"returns\":{\"_0\":\"Token ID for the token owned by the given address.\"}},\"tokenURI(uint256)\":{\"params\":{\"_tokenId\":\"Token ID to query.\"},\"returns\":{\"_0\":\"Token URI for the given token by ID.\"}},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"Optimist\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"ATTESTATION_STATION()\":{\"notice\":\"Address of the AttestationStation contract.\"},\"BASE_URI_ATTESTATION_KEY()\":{\"notice\":\"Attestation key used by the attestor to attest the baseURI.\"},\"BASE_URI_ATTESTOR()\":{\"notice\":\"Attestor who attests to baseURI.\"},\"OPTIMIST_ALLOWLIST()\":{\"notice\":\"Address of the OptimistAllowlist contract.\"},\"approve(address,uint256)\":{\"notice\":\"Disabled for the Optimist NFT (Soul Bound Token).\"},\"baseURI()\":{\"notice\":\"Returns the baseURI for all tokens.\"},\"initialize(string,string)\":{\"notice\":\"Initializes the Optimist contract.\"},\"isOnAllowList(address)\":{\"notice\":\"Checks OptimistAllowlist to determine whether a given address is allowed to mint the Optimist NFT. Since the Optimist NFT will also be used as part of the Citizens House, mints are currently restricted. Eventually anyone will be able to mint.\"},\"mint(address)\":{\"notice\":\"Allows an address to mint an Optimist NFT. Token ID is the uint256 representation of the recipient's address. Recipients must be permitted to mint, eventually anyone will be able to mint. One token per address.\"},\"setApprovalForAll(address,bool)\":{\"notice\":\"Disabled for the Optimist NFT (Soul Bound Token).\"},\"tokenIdOfAddress(address)\":{\"notice\":\"Returns the token ID for the token owned by a given address. This is the uint256 representation of the given address.\"},\"tokenURI(uint256)\":{\"notice\":\"Returns the token URI for a given token by ID\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"A Soul Bound Token for real humans only(tm).\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/Optimist.sol\":\"Optimist\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721Upgradeable.sol\\\";\\nimport \\\"./IERC721ReceiverUpgradeable.sol\\\";\\nimport \\\"./extensions/IERC721MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../utils/StringsUpgradeable.sol\\\";\\nimport \\\"../../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\\n using AddressUpgradeable for address;\\n using StringsUpgradeable for uint256;\\n\\n // Token name\\n string private _name;\\n\\n // Token symbol\\n string private _symbol;\\n\\n // Mapping from token ID to owner address\\n mapping(uint256 => address) private _owners;\\n\\n // Mapping owner address to token count\\n mapping(address => uint256) private _balances;\\n\\n // Mapping from token ID to approved address\\n mapping(uint256 => address) private _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC721_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\\n return\\n interfaceId == type(IERC721Upgradeable).interfaceId ||\\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual override returns (uint256) {\\n require(owner != address(0), \\\"ERC721: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _owners[tokenId];\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ERC721Upgradeable.ownerOf(tokenId);\\n require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n require(\\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n \\\"ERC721: approve caller is not token owner nor approved for all\\\"\\n );\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n _requireMinted(tokenId);\\n\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _safeTransfer(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) internal virtual {\\n _transfer(from, to, tokenId);\\n require(_checkOnERC721Received(from, to, tokenId, data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n }\\n\\n /**\\n * @dev Returns whether `tokenId` exists.\\n *\\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\n *\\n * Tokens start existing when they are minted (`_mint`),\\n * and stop existing when they are burned (`_burn`).\\n */\\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\\n return _owners[tokenId] != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721Upgradeable.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) internal virtual {\\n _mint(to, tokenId);\\n require(\\n _checkOnERC721Received(address(0), to, tokenId, data),\\n \\\"ERC721: transfer to non ERC721Receiver implementer\\\"\\n );\\n }\\n\\n /**\\n * @dev Mints `tokenId` and transfers it to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - `to` cannot be the zero address.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _mint(address to, uint256 tokenId) internal virtual {\\n require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n _beforeTokenTransfer(address(0), to, tokenId);\\n\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal virtual {\\n address owner = ERC721Upgradeable.ownerOf(tokenId);\\n\\n _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n // Clear approvals\\n _approve(address(0), tokenId);\\n\\n _balances[owner] -= 1;\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId);\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {\\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId);\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(\\n address owner,\\n address operator,\\n bool approved\\n ) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting\\n * and burning.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n * transferred to `to`.\\n * - When `from` is zero, `tokenId` will be minted for `to`.\\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 tokenId\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[44] private __gap;\\n}\\n\",\"keccak256\":\"0x5331c8909221d9f9f3851cfadd5959d0873413a2c27e30e0f2fa234158c1c6cf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721ReceiverUpgradeable {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xbb2ed8106d94aeae6858e2551a1e7174df73994b77b13ebd120ccaaef80155f5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165Upgradeable.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721Upgradeable is IERC165Upgradeable {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x016298e66a5810253c6c905e61966bb31c8775c3f3517bf946ff56ee31d6c005\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC721Upgradeable.sol\\\";\\nimport \\\"../../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @title ERC721 Burnable Token\\n * @dev ERC721 Token that can be burned (destroyed).\\n */\\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\\n function __ERC721Burnable_init() internal onlyInitializing {\\n }\\n\\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Burns `tokenId`. See {ERC721-_burn}.\\n *\\n * Requirements:\\n *\\n * - The caller must own `tokenId` or be an approved operator.\\n */\\n function burn(uint256 tokenId) public virtual {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner nor approved\\\");\\n _burn(tokenId);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xa7dbff7171ac06a023a5ca52c2138ac711037b2146b9197a52e5de4f9183e04d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721Upgradeable.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x95a471796eb5f030fdc438660bebec121ad5d063763e64d92376ffb4b5ce8b70\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165Upgradeable).interfaceId;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165Upgradeable {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of AttestationData structs.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x421923e04df145353db12cd0352ccf516d9c29ab64b138733b4f7a6a450ce2be\",\"license\":\"MIT\"},\"contracts/universal/op-nft/Optimist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\nimport {\\n ERC721BurnableUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\\\";\\nimport { AttestationStation } from \\\"./AttestationStation.sol\\\";\\nimport { OptimistAllowlist } from \\\"./OptimistAllowlist.sol\\\";\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @title Optimist\\n * @notice A Soul Bound Token for real humans only(tm).\\n */\\ncontract Optimist is ERC721BurnableUpgradeable, Semver {\\n /**\\n * @notice Attestation key used by the attestor to attest the baseURI.\\n */\\n bytes32 public constant BASE_URI_ATTESTATION_KEY = bytes32(\\\"optimist.base-uri\\\");\\n\\n /**\\n * @notice Attestor who attests to baseURI.\\n */\\n address public immutable BASE_URI_ATTESTOR;\\n\\n /**\\n * @notice Address of the AttestationStation contract.\\n */\\n AttestationStation public immutable ATTESTATION_STATION;\\n\\n /**\\n * @notice Address of the OptimistAllowlist contract.\\n */\\n OptimistAllowlist public immutable OPTIMIST_ALLOWLIST;\\n\\n /**\\n * @custom:semver 2.0.0\\n * @param _name Token name.\\n * @param _symbol Token symbol.\\n * @param _baseURIAttestor Address of the baseURI attestor.\\n * @param _attestationStation Address of the AttestationStation contract.\\n * @param _optimistAllowlist Address of the OptimistAllowlist contract\\n */\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _baseURIAttestor,\\n AttestationStation _attestationStation,\\n OptimistAllowlist _optimistAllowlist\\n ) Semver(2, 0, 0) {\\n BASE_URI_ATTESTOR = _baseURIAttestor;\\n ATTESTATION_STATION = _attestationStation;\\n OPTIMIST_ALLOWLIST = _optimistAllowlist;\\n initialize(_name, _symbol);\\n }\\n\\n /**\\n * @notice Initializes the Optimist contract.\\n *\\n * @param _name Token name.\\n * @param _symbol Token symbol.\\n */\\n function initialize(string memory _name, string memory _symbol) public initializer {\\n __ERC721_init(_name, _symbol);\\n __ERC721Burnable_init();\\n }\\n\\n /**\\n * @notice Allows an address to mint an Optimist NFT. Token ID is the uint256 representation\\n * of the recipient's address. Recipients must be permitted to mint, eventually anyone\\n * will be able to mint. One token per address.\\n *\\n * @param _recipient Address of the token recipient.\\n */\\n function mint(address _recipient) public {\\n require(isOnAllowList(_recipient), \\\"Optimist: address is not on allowList\\\");\\n _safeMint(_recipient, tokenIdOfAddress(_recipient));\\n }\\n\\n /**\\n * @notice Returns the baseURI for all tokens.\\n *\\n * @return BaseURI for all tokens.\\n */\\n function baseURI() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n ATTESTATION_STATION.attestations(\\n BASE_URI_ATTESTOR,\\n address(this),\\n bytes32(\\\"optimist.base-uri\\\")\\n )\\n )\\n );\\n }\\n\\n /**\\n * @notice Returns the token URI for a given token by ID\\n *\\n * @param _tokenId Token ID to query.\\n\\n * @return Token URI for the given token by ID.\\n */\\n function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n baseURI(),\\n \\\"/\\\",\\n // Properly format the token ID as a 20 byte hex string (address).\\n Strings.toHexString(_tokenId, 20),\\n \\\".json\\\"\\n )\\n );\\n }\\n\\n /**\\n * @notice Checks OptimistAllowlist to determine whether a given address is allowed to mint\\n * the Optimist NFT. Since the Optimist NFT will also be used as part of the\\n * Citizens House, mints are currently restricted. Eventually anyone will be able\\n * to mint.\\n *\\n * @return Whether or not the address is allowed to mint yet.\\n */\\n function isOnAllowList(address _recipient) public view returns (bool) {\\n return OPTIMIST_ALLOWLIST.isAllowedToMint(_recipient);\\n }\\n\\n /**\\n * @notice Returns the token ID for the token owned by a given address. This is the uint256\\n * representation of the given address.\\n *\\n * @return Token ID for the token owned by the given address.\\n */\\n function tokenIdOfAddress(address _owner) public pure returns (uint256) {\\n return uint256(uint160(_owner));\\n }\\n\\n /**\\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\\n */\\n function approve(address, uint256) public pure override {\\n revert(\\\"Optimist: soul bound token\\\");\\n }\\n\\n /**\\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\\n */\\n function setApprovalForAll(address, bool) public virtual override {\\n revert(\\\"Optimist: soul bound token\\\");\\n }\\n\\n /**\\n * @notice Prevents transfers of the Optimist NFT (Soul Bound Token).\\n *\\n * @param _from Address of the token sender.\\n * @param _to Address of the token recipient.\\n */\\n function _beforeTokenTransfer(\\n address _from,\\n address _to,\\n uint256\\n ) internal virtual override {\\n require(_from == address(0) || _to == address(0), \\\"Optimist: soul bound token\\\");\\n }\\n}\\n\",\"keccak256\":\"0xf9c7973102666d1dc1b8a1918d6df82fa8fb470e1774aea840b300afb9699cac\",\"license\":\"MIT\"},\"contracts/universal/op-nft/OptimistAllowlist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\nimport { AttestationStation } from \\\"./AttestationStation.sol\\\";\\nimport { OptimistConstants } from \\\"./libraries/OptimistConstants.sol\\\";\\n\\n/**\\n * @title OptimistAllowlist\\n * @notice Source of truth for whether an address is able to mint an Optimist NFT.\\n isAllowedToMint function checks various signals to return boolean value for whether an\\n address is eligible or not.\\n */\\ncontract OptimistAllowlist is Semver {\\n /**\\n * @notice Attestation key used by the AllowlistAttestor to manually add addresses to the\\n * allowlist.\\n */\\n bytes32 public constant OPTIMIST_CAN_MINT_ATTESTATION_KEY = bytes32(\\\"optimist.can-mint\\\");\\n\\n /**\\n * @notice Attestation key used by Coinbase to issue attestations for Quest participants.\\n */\\n bytes32 public constant COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY =\\n bytes32(\\\"coinbase.quest-eligible\\\");\\n\\n /**\\n * @notice Address of the AttestationStation contract.\\n */\\n AttestationStation public immutable ATTESTATION_STATION;\\n\\n /**\\n * @notice Attestor that issues 'optimist.can-mint' attestations.\\n */\\n address public immutable ALLOWLIST_ATTESTOR;\\n\\n /**\\n * @notice Attestor that issues 'coinbase.quest-eligible' attestations.\\n */\\n address public immutable COINBASE_QUEST_ATTESTOR;\\n\\n /**\\n * @notice Address of OptimistInviter contract that issues 'optimist.can-mint-from-invite'\\n * attestations.\\n */\\n address public immutable OPTIMIST_INVITER;\\n\\n /**\\n * @custom:semver 1.0.0\\n *\\n * @param _attestationStation Address of the AttestationStation contract.\\n * @param _allowlistAttestor Address of the allowlist attestor.\\n * @param _coinbaseQuestAttestor Address of the Coinbase Quest attestor.\\n * @param _optimistInviter Address of the OptimistInviter contract.\\n */\\n constructor(\\n AttestationStation _attestationStation,\\n address _allowlistAttestor,\\n address _coinbaseQuestAttestor,\\n address _optimistInviter\\n ) Semver(1, 0, 0) {\\n ATTESTATION_STATION = _attestationStation;\\n ALLOWLIST_ATTESTOR = _allowlistAttestor;\\n COINBASE_QUEST_ATTESTOR = _coinbaseQuestAttestor;\\n OPTIMIST_INVITER = _optimistInviter;\\n }\\n\\n /**\\n * @notice Checks whether a given address is allowed to mint the Optimist NFT yet. Since the\\n * Optimist NFT will also be used as part of the Citizens House, mints are currently\\n * restricted. Eventually anyone will be able to mint.\\n *\\n * Currently, address is allowed to mint if it satisfies any of the following:\\n * 1) Has a valid 'optimist.can-mint' attestation from the allowlist attestor.\\n * 2) Has a valid 'coinbase.quest-eligible' attestation from Coinbase Quest attestor\\n * 3) Has a valid 'optimist.can-mint-from-invite' attestation from the OptimistInviter\\n * contract.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address is allowed to mint yet.\\n */\\n function isAllowedToMint(address _claimer) public view returns (bool) {\\n return\\n _hasAttestationFromAllowlistAttestor(_claimer) ||\\n _hasAttestationFromCoinbaseQuestAttestor(_claimer) ||\\n _hasAttestationFromOptimistInviter(_claimer);\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid 'optimist.can-mint' attestation from the\\n * allowlist attestor.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromAllowlistAttestor(address _claimer) internal view returns (bool) {\\n // Expected attestation value is bytes32(\\\"true\\\")\\n return\\n _hasValidAttestation(ALLOWLIST_ATTESTOR, _claimer, OPTIMIST_CAN_MINT_ATTESTATION_KEY);\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid attestation from the Coinbase attestor.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromCoinbaseQuestAttestor(address _claimer)\\n internal\\n view\\n returns (bool)\\n {\\n // Expected attestation value is bytes32(\\\"true\\\")\\n return\\n _hasValidAttestation(\\n COINBASE_QUEST_ATTESTOR,\\n _claimer,\\n COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY\\n );\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid attestation from the OptimistInviter contract.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromOptimistInviter(address _claimer) internal view returns (bool) {\\n // Expected attestation value is the inviter's address\\n return\\n _hasValidAttestation(\\n OPTIMIST_INVITER,\\n _claimer,\\n OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY\\n );\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid truthy attestation.\\n * Any attestation val other than bytes32(\\\"\\\") is considered truthy.\\n *\\n * @param _creator Address that made the attestation.\\n * @param _about Address attestation is about.\\n * @param _key Key of the attestation.\\n *\\n * @return Whether or not the address has a valid truthy attestation.\\n */\\n function _hasValidAttestation(\\n address _creator,\\n address _about,\\n bytes32 _key\\n ) internal view returns (bool) {\\n return ATTESTATION_STATION.attestations(_creator, _about, _key).length > 0;\\n }\\n}\\n\",\"keccak256\":\"0xd36a677571450d2d9be832beb80e5c37481fcdfc355e6a9b929ac9c8d4966ca0\",\"license\":\"MIT\"},\"contracts/universal/op-nft/libraries/OptimistConstants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title OptimistConstants\\n * @notice Library for storing Optimist related constants that are shared in multiple contracts.\\n */\\n\\nlibrary OptimistConstants {\\n /**\\n * @notice Attestation key issued by OptimistInviter allowing the attested account to mint.\\n */\\n bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY =\\n bytes32(\\\"optimist.can-mint-from-invite\\\");\\n}\\n\",\"keccak256\":\"0x6eebe1db87f8a5de79bf8af9120e5b0cc6a9b51d8d86e6461cdb6bc52a1dde21\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6101406040523480156200001257600080fd5b5060405162002c7f38038062002c7f8339810160408190526200003591620003ee565b6002608052600060a081905260c0526001600160a01b0380841660e052828116610100528116610120526200006b858562000076565b5050505050620005f4565b600054610100900460ff1615808015620000975750600054600160ff909116105b80620000c75750620000b430620001b660201b62000dd61760201c565b158015620000c7575060005460ff166001145b620001305760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000154576000805461ff0019166101001790555b620001608383620001c5565b6200016a62000231565b8015620001b1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002215760405162461bcd60e51b815260206004820152602b602482015260008051602062002c5f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000127565b6200022d82826200028f565b5050565b600054610100900460ff166200028d5760405162461bcd60e51b815260206004820152602b602482015260008051602062002c5f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000127565b565b600054610100900460ff16620002eb5760405162461bcd60e51b815260206004820152602b602482015260008051602062002c5f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000127565b6065620002f9838262000528565b506066620001b1828262000528565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200033057600080fd5b81516001600160401b03808211156200034d576200034d62000308565b604051601f8301601f19908116603f0116810190828211818310171562000378576200037862000308565b816040528381526020925086838588010111156200039557600080fd5b600091505b83821015620003b957858201830151818301840152908201906200039a565b83821115620003cb5760008385830101525b9695505050505050565b6001600160a01b0381168114620003eb57600080fd5b50565b600080600080600060a086880312156200040757600080fd5b85516001600160401b03808211156200041f57600080fd5b6200042d89838a016200031e565b965060208801519150808211156200044457600080fd5b5062000453888289016200031e565b94505060408601516200046681620003d5565b60608701519093506200047981620003d5565b60808701519092506200048c81620003d5565b809150509295509295909350565b600181811c90821680620004af57607f821691505b602082108103620004d057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620001b157600081815260208120601f850160051c81016020861015620004ff5750805b601f850160051c820191505b8181101562000520578281556001016200050b565b505050505050565b81516001600160401b0381111562000544576200054462000308565b6200055c816200055584546200049a565b84620004d6565b602080601f8311600181146200059457600084156200057b5750858301515b600019600386901b1c1916600185901b17855562000520565b600085815260208120601f198616915b82811015620005c557888601518255948401946001909101908401620005a4565b5085821015620005e45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e051610100516101205161260662000659600039600081816103930152610c900152600081816103ba0152610b1301526000818161022c0152610abc01526000610928015260006108ff015260006108d601526126066000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c80636a627842116100e3578063a22cb4651161008c578063ce5dd1b511610066578063ce5dd1b51461038e578063db083d71146103b5578063e985e9c5146103dc57600080fd5b8063a22cb4651461035a578063b88d4fde14610368578063c87b56dd1461037b57600080fd5b80637c08652f116100bd5780637c08652f146103185780638f328a1f1461033f57806395d89b411461035257600080fd5b80636a627842146102ea5780636c0360eb146102fd57806370a082311461030557600080fd5b806323b872dd116101455780634cd88b761161011f5780634cd88b76146102bc57806354fd4d50146102cf5780636352211e146102d757600080fd5b806323b872dd1461028357806342842e0e1461029657806342966c68146102a957600080fd5b8063095ea7b311610176578063095ea7b31461021257806319f463f21461022757806321d3d5cf1461024e57600080fd5b806301ffc9a71461019d57806306fdde03146101c5578063081812fc146101da575b600080fd5b6101b06101ab366004611d0e565b610425565b60405190151581526020015b60405180910390f35b6101cd61050a565b6040516101bc9190611d83565b6101ed6101e8366004611d96565b61059c565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b610225610220366004611dd8565b6105d0565b005b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6102757f6f7074696d6973742e626173652d75726900000000000000000000000000000081565b6040519081526020016101bc565b610225610291366004611e02565b61061d565b6102256102a4366004611e02565b6106aa565b6102256102b7366004611d96565b6106c5565b6102256102ca366004611f24565b61074c565b6101cd6108cf565b6101ed6102e5366004611d96565b610972565b6102256102f8366004611f88565b6109e4565b6101cd610a7f565b610275610313366004611f88565b610b94565b610275610326366004611f88565b73ffffffffffffffffffffffffffffffffffffffff1690565b6101b061034d366004611f88565b610c48565b6101cd610cfd565b610225610220366004611fb1565b610225610376366004611fe8565b610d0c565b6101cd610389366004611d96565b610d9a565b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6101b06103ea366004612064565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152606a6020908152604080832093909416825291909152205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806104b857507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061050457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606065805461051990612097565b80601f016020809104026020016040519081016040528092919081815260200182805461054590612097565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b60006105a782610df2565b5060009081526069602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405162461bcd60e51b815260206004820152601a60248201527f4f7074696d6973743a20736f756c20626f756e6420746f6b656e00000000000060448201526064015b60405180910390fd5b610628335b82610e63565b61069a5760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b6106a5838383610f23565b505050565b6106a583838360405180602001604052806000815250610d0c565b6106ce33610622565b6107405760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b61074981611161565b50565b600054610100900460ff161580801561076c5750600054600160ff909116105b806107865750303b158015610786575060005460ff166001145b6107f85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610614565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561085657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610860838361123b565b6108686112c2565b80156106a557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60606108fa7f0000000000000000000000000000000000000000000000000000000000000000611341565b6109237f0000000000000000000000000000000000000000000000000000000000000000611341565b61094c7f0000000000000000000000000000000000000000000000000000000000000000611341565b60405160200161095e939291906120ea565b604051602081830303815290604052905090565b60008181526067602052604081205473ffffffffffffffffffffffffffffffffffffffff16806105045760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610614565b6109ed81610c48565b610a5f5760405162461bcd60e51b815260206004820152602560248201527f4f7074696d6973743a2061646472657373206973206e6f74206f6e20616c6c6f60448201527f774c6973740000000000000000000000000000000000000000000000000000006064820152608401610614565b6107498173ffffffffffffffffffffffffffffffffffffffff8116611476565b6040517f29b42cb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301527f6f7074696d6973742e626173652d75726900000000000000000000000000000060448301526060917f0000000000000000000000000000000000000000000000000000000000000000909116906329b42cb590606401600060405180830381865afa158015610b5c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b849190810190612160565b60405160200161095e91906121d7565b600073ffffffffffffffffffffffffffffffffffffffff8216610c1f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152608401610614565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526068602052604090205490565b6040517f4813d8a600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690634813d8a690602401602060405180830381865afa158015610cd9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050491906121f3565b60606066805461051990612097565b610d163383610e63565b610d885760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b610d9484848484611490565b50505050565b6060610da4610a7f565b610daf836014611519565b604051602001610dc0929190612210565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60008181526067602052604090205473ffffffffffffffffffffffffffffffffffffffff166107495760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610614565b600080610e6f83610972565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610edd575073ffffffffffffffffffffffffffffffffffffffff8082166000908152606a602090815260408083209388168352929052205460ff165b80610f1b57508373ffffffffffffffffffffffffffffffffffffffff16610f038461059c565b73ffffffffffffffffffffffffffffffffffffffff16145b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16610f4382610972565b73ffffffffffffffffffffffffffffffffffffffff1614610fcc5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610614565b73ffffffffffffffffffffffffffffffffffffffff82166110545760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610614565b61105f838383611749565b61106a6000826117cc565b73ffffffffffffffffffffffffffffffffffffffff831660009081526068602052604081208054600192906110a09084906122c1565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526068602052604081208054600192906110db9084906122d8565b909155505060008181526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061116c82610972565b905061117a81600084611749565b6111856000836117cc565b73ffffffffffffffffffffffffffffffffffffffff811660009081526068602052604081208054600192906111bb9084906122c1565b909155505060008281526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45b5050565b600054610100900460ff166112b85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b611237828261186c565b600054610100900460ff1661133f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b565b60608160000361138457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156113ae5780611398816122f0565b91506113a79050600a83612357565b9150611388565b60008167ffffffffffffffff8111156113c9576113c9611e3e565b6040519080825280601f01601f1916602001820160405280156113f3576020820181803683370190505b5090505b8415610f1b576114086001836122c1565b9150611415600a8661236b565b6114209060306122d8565b60f81b8183815181106114355761143561237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061146f600a86612357565b94506113f7565b611237828260405180602001604052806000815250611902565b61149b848484610f23565b6114a78484848461198b565b610d945760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b606060006115288360026123ae565b6115339060026122d8565b67ffffffffffffffff81111561154b5761154b611e3e565b6040519080825280601f01601f191660200182016040528015611575576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106115ac576115ac61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061160f5761160f61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061164b8460026123ae565b6116569060016122d8565b90505b60018111156116f3577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106116975761169761237f565b1a60f81b8282815181106116ad576116ad61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936116ec816123eb565b9050611659565b5083156117425760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610614565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff83161580611780575073ffffffffffffffffffffffffffffffffffffffff8216155b6106a55760405162461bcd60e51b815260206004820152601a60248201527f4f7074696d6973743a20736f756c20626f756e6420746f6b656e0000000000006044820152606401610614565b600081815260696020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061182682610972565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600054610100900460ff166118e95760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b60656118f5838261246e565b5060666106a5828261246e565b61190c8383611b46565b611919600084848461198b565b6106a55760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b600073ffffffffffffffffffffffffffffffffffffffff84163b15611b3b576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290611a0290339089908890889060040161256a565b6020604051808303816000875af1925050508015611a3d575060408051601f3d908101601f19168201909252611a3a918101906125b3565b60015b611af0573d808015611a6b576040519150601f19603f3d011682016040523d82523d6000602084013e611a70565b606091505b508051600003611ae85760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050610f1b565b506001949350505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ba95760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610614565b60008181526067602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611c1b5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610614565b611c2760008383611749565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606860205260408120805460019290611c5d9084906122d8565b909155505060008181526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461074957600080fd5b600060208284031215611d2057600080fd5b813561174281611ce0565b60005b83811015611d46578181015183820152602001611d2e565b83811115610d945750506000910152565b60008151808452611d6f816020860160208601611d2b565b601f01601f19169290920160200192915050565b6020815260006117426020830184611d57565b600060208284031215611da857600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611dd357600080fd5b919050565b60008060408385031215611deb57600080fd5b611df483611daf565b946020939093013593505050565b600080600060608486031215611e1757600080fd5b611e2084611daf565b9250611e2e60208501611daf565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e9657611e96611e3e565b604052919050565b600067ffffffffffffffff821115611eb857611eb8611e3e565b50601f01601f191660200190565b6000611ed9611ed484611e9e565b611e6d565b9050828152838383011115611eed57600080fd5b828260208301376000602084830101529392505050565b600082601f830112611f1557600080fd5b61174283833560208501611ec6565b60008060408385031215611f3757600080fd5b823567ffffffffffffffff80821115611f4f57600080fd5b611f5b86838701611f04565b93506020850135915080821115611f7157600080fd5b50611f7e85828601611f04565b9150509250929050565b600060208284031215611f9a57600080fd5b61174282611daf565b801515811461074957600080fd5b60008060408385031215611fc457600080fd5b611fcd83611daf565b91506020830135611fdd81611fa3565b809150509250929050565b60008060008060808587031215611ffe57600080fd5b61200785611daf565b935061201560208601611daf565b925060408501359150606085013567ffffffffffffffff81111561203857600080fd5b8501601f8101871361204957600080fd5b61205887823560208401611ec6565b91505092959194509250565b6000806040838503121561207757600080fd5b61208083611daf565b915061208e60208401611daf565b90509250929050565b600181811c908216806120ab57607f821691505b6020821081036120e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516120fc818460208901611d2b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612138816001850160208a01611d2b565b60019201918201528351612153816002840160208801611d2b565b0160020195945050505050565b60006020828403121561217257600080fd5b815167ffffffffffffffff81111561218957600080fd5b8201601f8101841361219a57600080fd5b80516121a8611ed482611e9e565b8181528560208385010111156121bd57600080fd5b6121ce826020830160208601611d2b565b95945050505050565b600082516121e9818460208701611d2b565b9190910192915050565b60006020828403121561220557600080fd5b815161174281611fa3565b60008351612222818460208801611d2b565b7f2f00000000000000000000000000000000000000000000000000000000000000908301908152835161225c816001840160208801611d2b565b7f2e6a736f6e00000000000000000000000000000000000000000000000000000060019290910191820152600601949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156122d3576122d3612292565b500390565b600082198211156122eb576122eb612292565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361232157612321612292565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261236657612366612328565b500490565b60008261237a5761237a612328565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156123e6576123e6612292565b500290565b6000816123fa576123fa612292565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b601f8211156106a557600081815260208120601f850160051c810160208610156124475750805b601f850160051c820191505b8181101561246657828155600101612453565b505050505050565b815167ffffffffffffffff81111561248857612488611e3e565b61249c816124968454612097565b84612420565b602080601f8311600181146124ef57600084156124b95750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612466565b600085815260208120601f198616915b8281101561251e578886015182559484019460019091019084016124ff565b508582101561255a57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526125a96080830184611d57565b9695505050505050565b6000602082840312156125c557600080fd5b815161174281611ce056fea264697066735822122068519f9cbd8d80e9e293c6c977994da4f38aba3722422b6bfce53b68916efab964736f6c634300080f0033496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101985760003560e01c80636a627842116100e3578063a22cb4651161008c578063ce5dd1b511610066578063ce5dd1b51461038e578063db083d71146103b5578063e985e9c5146103dc57600080fd5b8063a22cb4651461035a578063b88d4fde14610368578063c87b56dd1461037b57600080fd5b80637c08652f116100bd5780637c08652f146103185780638f328a1f1461033f57806395d89b411461035257600080fd5b80636a627842146102ea5780636c0360eb146102fd57806370a082311461030557600080fd5b806323b872dd116101455780634cd88b761161011f5780634cd88b76146102bc57806354fd4d50146102cf5780636352211e146102d757600080fd5b806323b872dd1461028357806342842e0e1461029657806342966c68146102a957600080fd5b8063095ea7b311610176578063095ea7b31461021257806319f463f21461022757806321d3d5cf1461024e57600080fd5b806301ffc9a71461019d57806306fdde03146101c5578063081812fc146101da575b600080fd5b6101b06101ab366004611d0e565b610425565b60405190151581526020015b60405180910390f35b6101cd61050a565b6040516101bc9190611d83565b6101ed6101e8366004611d96565b61059c565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b610225610220366004611dd8565b6105d0565b005b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6102757f6f7074696d6973742e626173652d75726900000000000000000000000000000081565b6040519081526020016101bc565b610225610291366004611e02565b61061d565b6102256102a4366004611e02565b6106aa565b6102256102b7366004611d96565b6106c5565b6102256102ca366004611f24565b61074c565b6101cd6108cf565b6101ed6102e5366004611d96565b610972565b6102256102f8366004611f88565b6109e4565b6101cd610a7f565b610275610313366004611f88565b610b94565b610275610326366004611f88565b73ffffffffffffffffffffffffffffffffffffffff1690565b6101b061034d366004611f88565b610c48565b6101cd610cfd565b610225610220366004611fb1565b610225610376366004611fe8565b610d0c565b6101cd610389366004611d96565b610d9a565b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6101ed7f000000000000000000000000000000000000000000000000000000000000000081565b6101b06103ea366004612064565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152606a6020908152604080832093909416825291909152205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806104b857507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061050457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606065805461051990612097565b80601f016020809104026020016040519081016040528092919081815260200182805461054590612097565b80156105925780601f1061056757610100808354040283529160200191610592565b820191906000526020600020905b81548152906001019060200180831161057557829003601f168201915b5050505050905090565b60006105a782610df2565b5060009081526069602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405162461bcd60e51b815260206004820152601a60248201527f4f7074696d6973743a20736f756c20626f756e6420746f6b656e00000000000060448201526064015b60405180910390fd5b610628335b82610e63565b61069a5760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b6106a5838383610f23565b505050565b6106a583838360405180602001604052806000815250610d0c565b6106ce33610622565b6107405760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b61074981611161565b50565b600054610100900460ff161580801561076c5750600054600160ff909116105b806107865750303b158015610786575060005460ff166001145b6107f85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610614565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561085657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610860838361123b565b6108686112c2565b80156106a557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60606108fa7f0000000000000000000000000000000000000000000000000000000000000000611341565b6109237f0000000000000000000000000000000000000000000000000000000000000000611341565b61094c7f0000000000000000000000000000000000000000000000000000000000000000611341565b60405160200161095e939291906120ea565b604051602081830303815290604052905090565b60008181526067602052604081205473ffffffffffffffffffffffffffffffffffffffff16806105045760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610614565b6109ed81610c48565b610a5f5760405162461bcd60e51b815260206004820152602560248201527f4f7074696d6973743a2061646472657373206973206e6f74206f6e20616c6c6f60448201527f774c6973740000000000000000000000000000000000000000000000000000006064820152608401610614565b6107498173ffffffffffffffffffffffffffffffffffffffff8116611476565b6040517f29b42cb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301527f6f7074696d6973742e626173652d75726900000000000000000000000000000060448301526060917f0000000000000000000000000000000000000000000000000000000000000000909116906329b42cb590606401600060405180830381865afa158015610b5c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b849190810190612160565b60405160200161095e91906121d7565b600073ffffffffffffffffffffffffffffffffffffffff8216610c1f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152608401610614565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526068602052604090205490565b6040517f4813d8a600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690634813d8a690602401602060405180830381865afa158015610cd9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050491906121f3565b60606066805461051990612097565b610d163383610e63565b610d885760405162461bcd60e51b815260206004820152602e60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206e6f7220617070726f7665640000000000000000000000000000000000006064820152608401610614565b610d9484848484611490565b50505050565b6060610da4610a7f565b610daf836014611519565b604051602001610dc0929190612210565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60008181526067602052604090205473ffffffffffffffffffffffffffffffffffffffff166107495760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610614565b600080610e6f83610972565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610edd575073ffffffffffffffffffffffffffffffffffffffff8082166000908152606a602090815260408083209388168352929052205460ff165b80610f1b57508373ffffffffffffffffffffffffffffffffffffffff16610f038461059c565b73ffffffffffffffffffffffffffffffffffffffff16145b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16610f4382610972565b73ffffffffffffffffffffffffffffffffffffffff1614610fcc5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610614565b73ffffffffffffffffffffffffffffffffffffffff82166110545760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610614565b61105f838383611749565b61106a6000826117cc565b73ffffffffffffffffffffffffffffffffffffffff831660009081526068602052604081208054600192906110a09084906122c1565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526068602052604081208054600192906110db9084906122d8565b909155505060008181526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061116c82610972565b905061117a81600084611749565b6111856000836117cc565b73ffffffffffffffffffffffffffffffffffffffff811660009081526068602052604081208054600192906111bb9084906122c1565b909155505060008281526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45b5050565b600054610100900460ff166112b85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b611237828261186c565b600054610100900460ff1661133f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b565b60608160000361138457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156113ae5780611398816122f0565b91506113a79050600a83612357565b9150611388565b60008167ffffffffffffffff8111156113c9576113c9611e3e565b6040519080825280601f01601f1916602001820160405280156113f3576020820181803683370190505b5090505b8415610f1b576114086001836122c1565b9150611415600a8661236b565b6114209060306122d8565b60f81b8183815181106114355761143561237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061146f600a86612357565b94506113f7565b611237828260405180602001604052806000815250611902565b61149b848484610f23565b6114a78484848461198b565b610d945760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b606060006115288360026123ae565b6115339060026122d8565b67ffffffffffffffff81111561154b5761154b611e3e565b6040519080825280601f01601f191660200182016040528015611575576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106115ac576115ac61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061160f5761160f61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061164b8460026123ae565b6116569060016122d8565b90505b60018111156116f3577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106116975761169761237f565b1a60f81b8282815181106116ad576116ad61237f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936116ec816123eb565b9050611659565b5083156117425760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610614565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff83161580611780575073ffffffffffffffffffffffffffffffffffffffff8216155b6106a55760405162461bcd60e51b815260206004820152601a60248201527f4f7074696d6973743a20736f756c20626f756e6420746f6b656e0000000000006044820152606401610614565b600081815260696020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061182682610972565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600054610100900460ff166118e95760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610614565b60656118f5838261246e565b5060666106a5828261246e565b61190c8383611b46565b611919600084848461198b565b6106a55760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b600073ffffffffffffffffffffffffffffffffffffffff84163b15611b3b576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290611a0290339089908890889060040161256a565b6020604051808303816000875af1925050508015611a3d575060408051601f3d908101601f19168201909252611a3a918101906125b3565b60015b611af0573d808015611a6b576040519150601f19603f3d011682016040523d82523d6000602084013e611a70565b606091505b508051600003611ae85760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610614565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050610f1b565b506001949350505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ba95760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610614565b60008181526067602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611c1b5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610614565b611c2760008383611749565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606860205260408120805460019290611c5d9084906122d8565b909155505060008181526067602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461074957600080fd5b600060208284031215611d2057600080fd5b813561174281611ce0565b60005b83811015611d46578181015183820152602001611d2e565b83811115610d945750506000910152565b60008151808452611d6f816020860160208601611d2b565b601f01601f19169290920160200192915050565b6020815260006117426020830184611d57565b600060208284031215611da857600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611dd357600080fd5b919050565b60008060408385031215611deb57600080fd5b611df483611daf565b946020939093013593505050565b600080600060608486031215611e1757600080fd5b611e2084611daf565b9250611e2e60208501611daf565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e9657611e96611e3e565b604052919050565b600067ffffffffffffffff821115611eb857611eb8611e3e565b50601f01601f191660200190565b6000611ed9611ed484611e9e565b611e6d565b9050828152838383011115611eed57600080fd5b828260208301376000602084830101529392505050565b600082601f830112611f1557600080fd5b61174283833560208501611ec6565b60008060408385031215611f3757600080fd5b823567ffffffffffffffff80821115611f4f57600080fd5b611f5b86838701611f04565b93506020850135915080821115611f7157600080fd5b50611f7e85828601611f04565b9150509250929050565b600060208284031215611f9a57600080fd5b61174282611daf565b801515811461074957600080fd5b60008060408385031215611fc457600080fd5b611fcd83611daf565b91506020830135611fdd81611fa3565b809150509250929050565b60008060008060808587031215611ffe57600080fd5b61200785611daf565b935061201560208601611daf565b925060408501359150606085013567ffffffffffffffff81111561203857600080fd5b8501601f8101871361204957600080fd5b61205887823560208401611ec6565b91505092959194509250565b6000806040838503121561207757600080fd5b61208083611daf565b915061208e60208401611daf565b90509250929050565b600181811c908216806120ab57607f821691505b6020821081036120e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600084516120fc818460208901611d2b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612138816001850160208a01611d2b565b60019201918201528351612153816002840160208801611d2b565b0160020195945050505050565b60006020828403121561217257600080fd5b815167ffffffffffffffff81111561218957600080fd5b8201601f8101841361219a57600080fd5b80516121a8611ed482611e9e565b8181528560208385010111156121bd57600080fd5b6121ce826020830160208601611d2b565b95945050505050565b600082516121e9818460208701611d2b565b9190910192915050565b60006020828403121561220557600080fd5b815161174281611fa3565b60008351612222818460208801611d2b565b7f2f00000000000000000000000000000000000000000000000000000000000000908301908152835161225c816001840160208801611d2b565b7f2e6a736f6e00000000000000000000000000000000000000000000000000000060019290910191820152600601949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156122d3576122d3612292565b500390565b600082198211156122eb576122eb612292565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361232157612321612292565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261236657612366612328565b500490565b60008261237a5761237a612328565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156123e6576123e6612292565b500290565b6000816123fa576123fa612292565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b601f8211156106a557600081815260208120601f850160051c810160208610156124475750805b601f850160051c820191505b8181101561246657828155600101612453565b505050505050565b815167ffffffffffffffff81111561248857612488611e3e565b61249c816124968454612097565b84612420565b602080601f8311600181146124ef57600084156124b95750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612466565b600085815260208120601f198616915b8281101561251e578886015182559484019460019091019084016124ff565b508582101561255a57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526125a96080830184611d57565b9695505050505050565b6000602082840312156125c557600080fd5b815161174281611ce056fea264697066735822122068519f9cbd8d80e9e293c6c977994da4f38aba3722422b6bfce53b68916efab964736f6c634300080f0033", - "devdoc": { - "author": "Optimism CollectiveGitcoin", - "kind": "dev", - "methods": { - "balanceOf(address)": { - "details": "See {IERC721-balanceOf}." - }, - "baseURI()": { - "returns": { - "_0": "BaseURI for all tokens." - } - }, - "burn(uint256)": { - "details": "Burns `tokenId`. See {ERC721-_burn}. Requirements: - The caller must own `tokenId` or be an approved operator." - }, - "constructor": { - "custom:semver": "2.0.0", - "params": { - "_attestationStation": "Address of the AttestationStation contract.", - "_baseURIAttestor": "Address of the baseURI attestor.", - "_name": "Token name.", - "_optimistAllowlist": "Address of the OptimistAllowlist contract", - "_symbol": "Token symbol." - } - }, - "getApproved(uint256)": { - "details": "See {IERC721-getApproved}." - }, - "initialize(string,string)": { - "params": { - "_name": "Token name.", - "_symbol": "Token symbol." - } - }, - "isApprovedForAll(address,address)": { - "details": "See {IERC721-isApprovedForAll}." - }, - "isOnAllowList(address)": { - "returns": { - "_0": "Whether or not the address is allowed to mint yet." - } - }, - "mint(address)": { - "params": { - "_recipient": "Address of the token recipient." - } - }, - "name()": { - "details": "See {IERC721Metadata-name}." - }, - "ownerOf(uint256)": { - "details": "See {IERC721-ownerOf}." - }, - "safeTransferFrom(address,address,uint256)": { - "details": "See {IERC721-safeTransferFrom}." - }, - "safeTransferFrom(address,address,uint256,bytes)": { - "details": "See {IERC721-safeTransferFrom}." - }, - "supportsInterface(bytes4)": { - "details": "See {IERC165-supportsInterface}." - }, - "symbol()": { - "details": "See {IERC721Metadata-symbol}." - }, - "tokenIdOfAddress(address)": { - "returns": { - "_0": "Token ID for the token owned by the given address." - } - }, - "tokenURI(uint256)": { - "params": { - "_tokenId": "Token ID to query." - }, - "returns": { - "_0": "Token URI for the given token by ID." - } - }, - "transferFrom(address,address,uint256)": { - "details": "See {IERC721-transferFrom}." - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "Optimist", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "ATTESTATION_STATION()": { - "notice": "Address of the AttestationStation contract." - }, - "BASE_URI_ATTESTATION_KEY()": { - "notice": "Attestation key used by the attestor to attest the baseURI." - }, - "BASE_URI_ATTESTOR()": { - "notice": "Attestor who attests to baseURI." - }, - "OPTIMIST_ALLOWLIST()": { - "notice": "Address of the OptimistAllowlist contract." - }, - "approve(address,uint256)": { - "notice": "Disabled for the Optimist NFT (Soul Bound Token)." - }, - "baseURI()": { - "notice": "Returns the baseURI for all tokens." - }, - "initialize(string,string)": { - "notice": "Initializes the Optimist contract." - }, - "isOnAllowList(address)": { - "notice": "Checks OptimistAllowlist to determine whether a given address is allowed to mint the Optimist NFT. Since the Optimist NFT will also be used as part of the Citizens House, mints are currently restricted. Eventually anyone will be able to mint." - }, - "mint(address)": { - "notice": "Allows an address to mint an Optimist NFT. Token ID is the uint256 representation of the recipient's address. Recipients must be permitted to mint, eventually anyone will be able to mint. One token per address." - }, - "setApprovalForAll(address,bool)": { - "notice": "Disabled for the Optimist NFT (Soul Bound Token)." - }, - "tokenIdOfAddress(address)": { - "notice": "Returns the token ID for the token owned by a given address. This is the uint256 representation of the given address." - }, - "tokenURI(uint256)": { - "notice": "Returns the token URI for a given token by ID" - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "A Soul Bound Token for real humans only(tm).", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 1166, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 1169, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 2697, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 3505, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "__gap", - "offset": 0, - "slot": "51", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 1339, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_name", - "offset": 0, - "slot": "101", - "type": "t_string_storage" - }, - { - "astId": 1341, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_symbol", - "offset": 0, - "slot": "102", - "type": "t_string_storage" - }, - { - "astId": 1345, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_owners", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_address)" - }, - { - "astId": 1349, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_balances", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_address,t_uint256)" - }, - { - "astId": 1353, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_tokenApprovals", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_uint256,t_address)" - }, - { - "astId": 1359, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "_operatorApprovals", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" - }, - { - "astId": 2201, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "__gap", - "offset": 0, - "slot": "107", - "type": "t_array(t_uint256)44_storage" - }, - { - "astId": 2385, - "contract": "contracts/universal/op-nft/Optimist.sol:Optimist", - "label": "__gap", - "offset": 0, - "slot": "151", - "type": "t_array(t_uint256)50_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)44_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[44]", - "numberOfBytes": "1408" - }, - "t_array(t_uint256)50_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_mapping(t_address,t_bool)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_mapping(t_address,t_mapping(t_address,t_bool))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => bool))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_bool)" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_mapping(t_uint256,t_address)": { - "encoding": "mapping", - "key": "t_uint256", - "label": "mapping(uint256 => address)", - "numberOfBytes": "32", - "value": "t_address" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistAllowlist.json b/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistAllowlist.json deleted file mode 100644 index 295667f8c81e..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistAllowlist.json +++ /dev/null @@ -1,232 +0,0 @@ -{ - "address": "0x7688895Ad581637e0e50605189AC15c3B1CF0014", - "abi": [ - { - "inputs": [ - { - "internalType": "contract AttestationStation", - "name": "_attestationStation", - "type": "address" - }, - { - "internalType": "address", - "name": "_allowlistAttestor", - "type": "address" - }, - { - "internalType": "address", - "name": "_coinbaseQuestAttestor", - "type": "address" - }, - { - "internalType": "address", - "name": "_optimistInviter", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "ALLOWLIST_ATTESTOR", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "ATTESTATION_STATION", - "outputs": [ - { - "internalType": "contract AttestationStation", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COINBASE_QUEST_ATTESTOR", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMIST_CAN_MINT_ATTESTATION_KEY", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMIST_INVITER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_claimer", - "type": "address" - } - ], - "name": "isAllowedToMint", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0xa4fdbc20288ff71bcf2ae03124cfdb99231db7643509e5e09de7e637e17e925a", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "568758", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb669a73c250c84f232a25032e1da2a777b0fc5a39d0d8ee38742decff4873794", - "transactionHash": "0xa4fdbc20288ff71bcf2ae03124cfdb99231db7643509e5e09de7e637e17e925a", - "logs": [], - "blockNumber": 87031619, - "cumulativeGasUsed": "568758", - "status": 1, - "byzantium": true - }, - "args": [ - "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77", - "0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3", - "0x661B7Acca8ebd93AFd349a088e9a9A00053DB1BF", - "0x073031A1E1b8F5458Ed41Ce56331F5fd7e1de929" - ], - "numDeployments": 1, - "solcInputHash": "d7155764d4bdb814f10e1bb45296292b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract AttestationStation\",\"name\":\"_attestationStation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_allowlistAttestor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_coinbaseQuestAttestor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_optimistInviter\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ALLOWLIST_ATTESTOR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ATTESTATION_STATION\",\"outputs\":[{\"internalType\":\"contract AttestationStation\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COINBASE_QUEST_ATTESTOR\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPTIMIST_CAN_MINT_ATTESTATION_KEY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPTIMIST_INVITER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_claimer\",\"type\":\"address\"}],\"name\":\"isAllowedToMint\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:semver\":\"1.0.0\",\"params\":{\"_allowlistAttestor\":\"Address of the allowlist attestor.\",\"_attestationStation\":\"Address of the AttestationStation contract.\",\"_coinbaseQuestAttestor\":\"Address of the Coinbase Quest attestor.\",\"_optimistInviter\":\"Address of the OptimistInviter contract.\"}},\"isAllowedToMint(address)\":{\"params\":{\"_claimer\":\"Address to check.\"},\"returns\":{\"_0\":\"Whether or not the address is allowed to mint yet.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"title\":\"OptimistAllowlist\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"ALLOWLIST_ATTESTOR()\":{\"notice\":\"Attestor that issues 'optimist.can-mint' attestations.\"},\"ATTESTATION_STATION()\":{\"notice\":\"Address of the AttestationStation contract.\"},\"COINBASE_QUEST_ATTESTOR()\":{\"notice\":\"Attestor that issues 'coinbase.quest-eligible' attestations.\"},\"COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY()\":{\"notice\":\"Attestation key used by Coinbase to issue attestations for Quest participants.\"},\"OPTIMIST_CAN_MINT_ATTESTATION_KEY()\":{\"notice\":\"Attestation key used by the AllowlistAttestor to manually add addresses to the allowlist.\"},\"OPTIMIST_INVITER()\":{\"notice\":\"Address of OptimistInviter contract that issues 'optimist.can-mint-from-invite' attestations.\"},\"isAllowedToMint(address)\":{\"notice\":\"Checks whether a given address is allowed to mint the Optimist NFT yet. Since the Optimist NFT will also be used as part of the Citizens House, mints are currently restricted. Eventually anyone will be able to mint. Currently, address is allowed to mint if it satisfies any of the following: 1) Has a valid 'optimist.can-mint' attestation from the allowlist attestor. 2) Has a valid 'coinbase.quest-eligible' attestation from Coinbase Quest attestor 3) Has a valid 'optimist.can-mint-from-invite' attestation from the OptimistInviter contract.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"Source of truth for whether an address is able to mint an Optimist NFT. isAllowedToMint function checks various signals to return boolean value for whether an address is eligible or not.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/OptimistAllowlist.sol\":\"OptimistAllowlist\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of AttestationData structs.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x421923e04df145353db12cd0352ccf516d9c29ab64b138733b4f7a6a450ce2be\",\"license\":\"MIT\"},\"contracts/universal/op-nft/OptimistAllowlist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\nimport { AttestationStation } from \\\"./AttestationStation.sol\\\";\\nimport { OptimistConstants } from \\\"./libraries/OptimistConstants.sol\\\";\\n\\n/**\\n * @title OptimistAllowlist\\n * @notice Source of truth for whether an address is able to mint an Optimist NFT.\\n isAllowedToMint function checks various signals to return boolean value for whether an\\n address is eligible or not.\\n */\\ncontract OptimistAllowlist is Semver {\\n /**\\n * @notice Attestation key used by the AllowlistAttestor to manually add addresses to the\\n * allowlist.\\n */\\n bytes32 public constant OPTIMIST_CAN_MINT_ATTESTATION_KEY = bytes32(\\\"optimist.can-mint\\\");\\n\\n /**\\n * @notice Attestation key used by Coinbase to issue attestations for Quest participants.\\n */\\n bytes32 public constant COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY =\\n bytes32(\\\"coinbase.quest-eligible\\\");\\n\\n /**\\n * @notice Address of the AttestationStation contract.\\n */\\n AttestationStation public immutable ATTESTATION_STATION;\\n\\n /**\\n * @notice Attestor that issues 'optimist.can-mint' attestations.\\n */\\n address public immutable ALLOWLIST_ATTESTOR;\\n\\n /**\\n * @notice Attestor that issues 'coinbase.quest-eligible' attestations.\\n */\\n address public immutable COINBASE_QUEST_ATTESTOR;\\n\\n /**\\n * @notice Address of OptimistInviter contract that issues 'optimist.can-mint-from-invite'\\n * attestations.\\n */\\n address public immutable OPTIMIST_INVITER;\\n\\n /**\\n * @custom:semver 1.0.0\\n *\\n * @param _attestationStation Address of the AttestationStation contract.\\n * @param _allowlistAttestor Address of the allowlist attestor.\\n * @param _coinbaseQuestAttestor Address of the Coinbase Quest attestor.\\n * @param _optimistInviter Address of the OptimistInviter contract.\\n */\\n constructor(\\n AttestationStation _attestationStation,\\n address _allowlistAttestor,\\n address _coinbaseQuestAttestor,\\n address _optimistInviter\\n ) Semver(1, 0, 0) {\\n ATTESTATION_STATION = _attestationStation;\\n ALLOWLIST_ATTESTOR = _allowlistAttestor;\\n COINBASE_QUEST_ATTESTOR = _coinbaseQuestAttestor;\\n OPTIMIST_INVITER = _optimistInviter;\\n }\\n\\n /**\\n * @notice Checks whether a given address is allowed to mint the Optimist NFT yet. Since the\\n * Optimist NFT will also be used as part of the Citizens House, mints are currently\\n * restricted. Eventually anyone will be able to mint.\\n *\\n * Currently, address is allowed to mint if it satisfies any of the following:\\n * 1) Has a valid 'optimist.can-mint' attestation from the allowlist attestor.\\n * 2) Has a valid 'coinbase.quest-eligible' attestation from Coinbase Quest attestor\\n * 3) Has a valid 'optimist.can-mint-from-invite' attestation from the OptimistInviter\\n * contract.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address is allowed to mint yet.\\n */\\n function isAllowedToMint(address _claimer) public view returns (bool) {\\n return\\n _hasAttestationFromAllowlistAttestor(_claimer) ||\\n _hasAttestationFromCoinbaseQuestAttestor(_claimer) ||\\n _hasAttestationFromOptimistInviter(_claimer);\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid 'optimist.can-mint' attestation from the\\n * allowlist attestor.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromAllowlistAttestor(address _claimer) internal view returns (bool) {\\n // Expected attestation value is bytes32(\\\"true\\\")\\n return\\n _hasValidAttestation(ALLOWLIST_ATTESTOR, _claimer, OPTIMIST_CAN_MINT_ATTESTATION_KEY);\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid attestation from the Coinbase attestor.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromCoinbaseQuestAttestor(address _claimer)\\n internal\\n view\\n returns (bool)\\n {\\n // Expected attestation value is bytes32(\\\"true\\\")\\n return\\n _hasValidAttestation(\\n COINBASE_QUEST_ATTESTOR,\\n _claimer,\\n COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY\\n );\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid attestation from the OptimistInviter contract.\\n *\\n * @param _claimer Address to check.\\n *\\n * @return Whether or not the address has a valid attestation.\\n */\\n function _hasAttestationFromOptimistInviter(address _claimer) internal view returns (bool) {\\n // Expected attestation value is the inviter's address\\n return\\n _hasValidAttestation(\\n OPTIMIST_INVITER,\\n _claimer,\\n OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY\\n );\\n }\\n\\n /**\\n * @notice Checks whether an address has a valid truthy attestation.\\n * Any attestation val other than bytes32(\\\"\\\") is considered truthy.\\n *\\n * @param _creator Address that made the attestation.\\n * @param _about Address attestation is about.\\n * @param _key Key of the attestation.\\n *\\n * @return Whether or not the address has a valid truthy attestation.\\n */\\n function _hasValidAttestation(\\n address _creator,\\n address _about,\\n bytes32 _key\\n ) internal view returns (bool) {\\n return ATTESTATION_STATION.attestations(_creator, _about, _key).length > 0;\\n }\\n}\\n\",\"keccak256\":\"0xd36a677571450d2d9be832beb80e5c37481fcdfc355e6a9b929ac9c8d4966ca0\",\"license\":\"MIT\"},\"contracts/universal/op-nft/libraries/OptimistConstants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title OptimistConstants\\n * @notice Library for storing Optimist related constants that are shared in multiple contracts.\\n */\\n\\nlibrary OptimistConstants {\\n /**\\n * @notice Attestation key issued by OptimistInviter allowing the attested account to mint.\\n */\\n bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY =\\n bytes32(\\\"optimist.can-mint-from-invite\\\");\\n}\\n\",\"keccak256\":\"0x6eebe1db87f8a5de79bf8af9120e5b0cc6a9b51d8d86e6461cdb6bc52a1dde21\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x61016060405234801561001157600080fd5b50604051610a9d380380610a9d8339810160408190526100309161007c565b6001608052600060a081905260c0526001600160a01b0393841660e0529183166101005282166101205216610140526100db565b6001600160a01b038116811461007957600080fd5b50565b6000806000806080858703121561009257600080fd5b845161009d81610064565b60208601519094506100ae81610064565b60408601519093506100bf81610064565b60608601519092506100d081610064565b939692955090935050565b60805160a05160c05160e05161010051610120516101405161094d6101506000396000818161011b015261035a0152600081816092015261030d01526000818161019e01526102c001526000818161017701526105360152600061026f015260006102460152600061021d015261094d6000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063819f7e841161005b578063819f7e841461013d578063db083d7114610172578063db3c316314610199578063e7bd804e146101c057600080fd5b80633ac52df71461008d5780634813d8a6146100de57806354fd4d50146101015780635e4f489a14610116575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100f16100ec3660046105cd565b6101e7565b60405190151581526020016100d5565b610109610216565b6040516100d5919061063a565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101647f636f696e626173652e71756573742d656c696769626c6500000000000000000081565b6040519081526020016100d5565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101647f6f7074696d6973742e63616e2d6d696e7400000000000000000000000000000081565b60006101f2826102b9565b80610201575061020182610306565b80610210575061021082610353565b92915050565b60606102417f00000000000000000000000000000000000000000000000000000000000000006103a0565b61026a7f00000000000000000000000000000000000000000000000000000000000000006103a0565b6102937f00000000000000000000000000000000000000000000000000000000000000006103a0565b6040516020016102a59392919061068b565b604051602081830303815290604052905090565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f6f7074696d6973742e63616e2d6d696e740000000000000000000000000000006104dd565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f636f696e626173652e71756573742d656c696769626c650000000000000000006104dd565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f6f7074696d6973742e63616e2d6d696e742d66726f6d2d696e766974650000006104dd565b6060816000036103e357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561040d57806103f781610730565b91506104069050600a83610797565b91506103e7565b60008167ffffffffffffffff811115610428576104286107ab565b6040519080825280601f01601f191660200182016040528015610452576020820181803683370190505b5090505b84156104d5576104676001836107da565b9150610474600a866107f1565b61047f906030610805565b60f81b8183815181106104945761049461081d565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104ce600a86610797565b9450610456565b949350505050565b6040517f29b42cb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283811660248301526044820183905260009182917f000000000000000000000000000000000000000000000000000000000000000016906329b42cb590606401600060405180830381865afa15801561057d573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105c3919081019061084c565b5111949350505050565b6000602082840312156105df57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461060357600080fd5b9392505050565b60005b8381101561062557818101518382015260200161060d565b83811115610634576000848401525b50505050565b602081526000825180602084015261065981604085016020870161060a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000845161069d81846020890161060a565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516106d9816001850160208a0161060a565b600192019182015283516106f481600284016020880161060a565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361076157610761610701565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826107a6576107a6610768565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107ec576107ec610701565b500390565b60008261080057610800610768565b500690565b6000821982111561081857610818610701565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561085e57600080fd5b815167ffffffffffffffff8082111561087657600080fd5b818401915084601f83011261088a57600080fd5b81518181111561089c5761089c6107ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e2576108e26107ab565b816040528281528760208487010111156108fb57600080fd5b61090c83602083016020880161060a565b97965050505050505056fea2646970667358221220f7c9eee125b4662acd39871c7f71fd0d6635d58d3d0d2d059a8c8bb16ba6d74564736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063819f7e841161005b578063819f7e841461013d578063db083d7114610172578063db3c316314610199578063e7bd804e146101c057600080fd5b80633ac52df71461008d5780634813d8a6146100de57806354fd4d50146101015780635e4f489a14610116575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100f16100ec3660046105cd565b6101e7565b60405190151581526020016100d5565b610109610216565b6040516100d5919061063a565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101647f636f696e626173652e71756573742d656c696769626c6500000000000000000081565b6040519081526020016100d5565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101647f6f7074696d6973742e63616e2d6d696e7400000000000000000000000000000081565b60006101f2826102b9565b80610201575061020182610306565b80610210575061021082610353565b92915050565b60606102417f00000000000000000000000000000000000000000000000000000000000000006103a0565b61026a7f00000000000000000000000000000000000000000000000000000000000000006103a0565b6102937f00000000000000000000000000000000000000000000000000000000000000006103a0565b6040516020016102a59392919061068b565b604051602081830303815290604052905090565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f6f7074696d6973742e63616e2d6d696e740000000000000000000000000000006104dd565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f636f696e626173652e71756573742d656c696769626c650000000000000000006104dd565b60006102107f0000000000000000000000000000000000000000000000000000000000000000837f6f7074696d6973742e63616e2d6d696e742d66726f6d2d696e766974650000006104dd565b6060816000036103e357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561040d57806103f781610730565b91506104069050600a83610797565b91506103e7565b60008167ffffffffffffffff811115610428576104286107ab565b6040519080825280601f01601f191660200182016040528015610452576020820181803683370190505b5090505b84156104d5576104676001836107da565b9150610474600a866107f1565b61047f906030610805565b60f81b8183815181106104945761049461081d565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104ce600a86610797565b9450610456565b949350505050565b6040517f29b42cb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015283811660248301526044820183905260009182917f000000000000000000000000000000000000000000000000000000000000000016906329b42cb590606401600060405180830381865afa15801561057d573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105c3919081019061084c565b5111949350505050565b6000602082840312156105df57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461060357600080fd5b9392505050565b60005b8381101561062557818101518382015260200161060d565b83811115610634576000848401525b50505050565b602081526000825180602084015261065981604085016020870161060a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000845161069d81846020890161060a565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516106d9816001850160208a0161060a565b600192019182015283516106f481600284016020880161060a565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361076157610761610701565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826107a6576107a6610768565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156107ec576107ec610701565b500390565b60008261080057610800610768565b500690565b6000821982111561081857610818610701565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561085e57600080fd5b815167ffffffffffffffff8082111561087657600080fd5b818401915084601f83011261088a57600080fd5b81518181111561089c5761089c6107ab565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e2576108e26107ab565b816040528281528760208487010111156108fb57600080fd5b61090c83602083016020880161060a565b97965050505050505056fea2646970667358221220f7c9eee125b4662acd39871c7f71fd0d6635d58d3d0d2d059a8c8bb16ba6d74564736f6c634300080f0033", - "devdoc": { - "kind": "dev", - "methods": { - "constructor": { - "custom:semver": "1.0.0", - "params": { - "_allowlistAttestor": "Address of the allowlist attestor.", - "_attestationStation": "Address of the AttestationStation contract.", - "_coinbaseQuestAttestor": "Address of the Coinbase Quest attestor.", - "_optimistInviter": "Address of the OptimistInviter contract." - } - }, - "isAllowedToMint(address)": { - "params": { - "_claimer": "Address to check." - }, - "returns": { - "_0": "Whether or not the address is allowed to mint yet." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "title": "OptimistAllowlist", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "ALLOWLIST_ATTESTOR()": { - "notice": "Attestor that issues 'optimist.can-mint' attestations." - }, - "ATTESTATION_STATION()": { - "notice": "Address of the AttestationStation contract." - }, - "COINBASE_QUEST_ATTESTOR()": { - "notice": "Attestor that issues 'coinbase.quest-eligible' attestations." - }, - "COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY()": { - "notice": "Attestation key used by Coinbase to issue attestations for Quest participants." - }, - "OPTIMIST_CAN_MINT_ATTESTATION_KEY()": { - "notice": "Attestation key used by the AllowlistAttestor to manually add addresses to the allowlist." - }, - "OPTIMIST_INVITER()": { - "notice": "Address of OptimistInviter contract that issues 'optimist.can-mint-from-invite' attestations." - }, - "isAllowedToMint(address)": { - "notice": "Checks whether a given address is allowed to mint the Optimist NFT yet. Since the Optimist NFT will also be used as part of the Citizens House, mints are currently restricted. Eventually anyone will be able to mint. Currently, address is allowed to mint if it satisfies any of the following: 1) Has a valid 'optimist.can-mint' attestation from the allowlist attestor. 2) Has a valid 'coinbase.quest-eligible' attestation from Coinbase Quest attestor 3) Has a valid 'optimist.can-mint-from-invite' attestation from the OptimistInviter contract." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "Source of truth for whether an address is able to mint an Optimist NFT. isAllowedToMint function checks various signals to return boolean value for whether an address is eligible or not.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistAllowlistProxy.json b/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistAllowlistProxy.json deleted file mode 100644 index d26cc3cb23fa..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistAllowlistProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x482b1945D58f2E9Db0CEbe13c7fcFc6876b41180", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x8a5be8c67f602b334fedc18faaa58de68861d619be084d90310f93015c2c0b7c", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "534190", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000400000000000000000000000000000000000000000000", - "blockHash": "0x54e0ce11f60f1f0c01aad2bf677a4550669f7ca408a4ee7c5bddf0b25fe11e85", - "transactionHash": "0x8a5be8c67f602b334fedc18faaa58de68861d619be084d90310f93015c2c0b7c", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 87031806, - "transactionHash": "0x8a5be8c67f602b334fedc18faaa58de68861d619be084d90310f93015c2c0b7c", - "address": "0x482b1945D58f2E9Db0CEbe13c7fcFc6876b41180", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58", - "logIndex": 0, - "blockHash": "0x54e0ce11f60f1f0c01aad2bf677a4550669f7ca408a4ee7c5bddf0b25fe11e85" - } - ], - "blockNumber": 87031806, - "cumulativeGasUsed": "534190", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "d7155764d4bdb814f10e1bb45296292b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) public virtual proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n public\\n payable\\n virtual\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) public virtual proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() public virtual proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() public virtual proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea26469706673582212200496188e743eb5556ea8662e234845601d39477882517acc1cf9061fcc51284c64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea26469706673582212200496188e743eb5556ea8662e234845601d39477882517acc1cf9061fcc51284c64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistInviter.json b/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistInviter.json deleted file mode 100644 index b7059136a651..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistInviter.json +++ /dev/null @@ -1,543 +0,0 @@ -{ - "address": "0xD1A342EB71F5e032770dc0Fb11dE3F75a23C7ca9", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_inviteGranter", - "type": "address" - }, - { - "internalType": "contract AttestationStation", - "name": "_attestationStation", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "issuer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "claimer", - "type": "address" - } - ], - "name": "InviteClaimed", - "type": "event" - }, - { - "inputs": [], - "name": "ATTESTATION_STATION", - "outputs": [ - { - "internalType": "contract AttestationStation", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "CAN_INVITE_ATTESTATION_KEY", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "CLAIMABLE_INVITE_TYPEHASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "EIP712_VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INVITE_GRANTER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_COMMITMENT_PERIOD", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_claimer", - "type": "address" - }, - { - "components": [ - { - "internalType": "address", - "name": "issuer", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "nonce", - "type": "bytes32" - } - ], - "internalType": "struct OptimistInviter.ClaimableInvite", - "name": "_claimableInvite", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "_signature", - "type": "bytes" - } - ], - "name": "claimInvite", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_commitment", - "type": "bytes32" - } - ], - "name": "commitInvite", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "commitmentTimestamps", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "inviteCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "_accounts", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "_inviteCount", - "type": "uint256" - } - ], - "name": "setInviteCounts", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "usedNonces", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0xe8b8a4c7cb6f074690f00e79e0a13d16f3ed16e4afb56d02afe74825a86f0d00", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "1650064", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xbc41ee7fc08d560ed6791a304433afbb424415cfa189376192b63eb6a85d8a55", - "transactionHash": "0xe8b8a4c7cb6f074690f00e79e0a13d16f3ed16e4afb56d02afe74825a86f0d00", - "logs": [], - "blockNumber": 87030949, - "cumulativeGasUsed": "1650064", - "status": 1, - "byzantium": true - }, - "args": [ - "0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3", - "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77" - ], - "numDeployments": 1, - "solcInputHash": "d7155764d4bdb814f10e1bb45296292b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_inviteGranter\",\"type\":\"address\"},{\"internalType\":\"contract AttestationStation\",\"name\":\"_attestationStation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"issuer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"claimer\",\"type\":\"address\"}],\"name\":\"InviteClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ATTESTATION_STATION\",\"outputs\":[{\"internalType\":\"contract AttestationStation\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"CAN_INVITE_ATTESTATION_KEY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"CLAIMABLE_INVITE_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"EIP712_VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INVITE_GRANTER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_COMMITMENT_PERIOD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_claimer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"issuer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OptimistInviter.ClaimableInvite\",\"name\":\"_claimableInvite\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"claimInvite\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_commitment\",\"type\":\"bytes32\"}],\"name\":\"commitInvite\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"commitmentTimestamps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"inviteCounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_accounts\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_inviteCount\",\"type\":\"uint256\"}],\"name\":\"setInviteCounts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"usedNonces\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"custom:upgradeable\":\"@title OptimistInviter\",\"events\":{\"InviteClaimed(address,address)\":{\"params\":{\"claimer\":\"Address that claimed the invite.\",\"issuer\":\"Address that issued the signature.\"}}},\"kind\":\"dev\",\"methods\":{\"claimInvite(address,(address,bytes32),bytes)\":{\"params\":{\"_claimableInvite\":\"ClaimableInvite struct containing the issuer and nonce.\",\"_claimer\":\"Address that will be granted the invite.\",\"_signature\":\"Signature signed over the claimable invite.\"}},\"commitInvite(bytes32)\":{\"params\":{\"_commitment\":\"A hash of the claimer and signature concatenated. keccak256(abi.encode(_claimer, _signature))\"}},\"constructor\":{\"custom:semver\":\"1.0.0\",\"params\":{\"_attestationStation\":\"Address of the AttestationStation contract.\",\"_inviteGranter\":\"Address of the invite granter.\"}},\"initialize(string)\":{\"params\":{\"_name\":\"Contract name.\"}},\"setInviteCounts(address[],uint256)\":{\"params\":{\"_accounts\":\"An array of accounts to update the invite counts of.\",\"_inviteCount\":\"Number of invites to set to.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"version\":1},\"userdoc\":{\"events\":{\"InviteClaimed(address,address)\":{\"notice\":\"Emitted when an invite is claimed.\"}},\"kind\":\"user\",\"methods\":{\"ATTESTATION_STATION()\":{\"notice\":\"Address of the AttestationStation contract.\"},\"CAN_INVITE_ATTESTATION_KEY()\":{\"notice\":\"Attestation key for that signals that an account was allowed to issue invites\"},\"CLAIMABLE_INVITE_TYPEHASH()\":{\"notice\":\"EIP712 typehash for the ClaimableInvite type.\"},\"EIP712_VERSION()\":{\"notice\":\"Version used for the EIP712 domain separator. This version is separated from the contract semver because the EIP712 domain separator is used to sign messages, and changing the domain separator invalidates all existing signatures. We should only bump this version if we make a major change to the signature scheme.\"},\"INVITE_GRANTER()\":{\"notice\":\"Granter who can set accounts' invite counts.\"},\"MIN_COMMITMENT_PERIOD()\":{\"notice\":\"Minimum age of a commitment (in seconds) before it can be revealed using claimInvite. Currently set to 60 seconds. Prevents an attacker from front-running a commitment by taking the signature in the claimInvite call and quickly committing and claiming it before the the claimer's transaction succeeds. With this, frontrunning a commitment requires that an attacker be able to prevent the honest claimer's claimInvite transaction from being included for this long.\"},\"claimInvite(address,(address,bytes32),bytes)\":{\"notice\":\"Allows anyone to reveal a commitment and claim an invite. The hash, keccak256(abi.encode(_claimer, _signature)), should have been already committed using commitInvite. Before issuing the \\\"optimist.can-mint-from-invite\\\" attestation, this function checks that 1) the hash corresponding to the _claimer and the _signature was committed 2) MIN_COMMITMENT_PERIOD has passed since the commitment was made. 3) the _signature is signed correctly by the issuer 4) the _signature hasn't already been used to claim an invite before 5) the _signature issuer has not used up all of their invites This function doesn't require that the _claimer is calling this function.\"},\"commitInvite(bytes32)\":{\"notice\":\"Allows anyone (but likely the claimer) to commit a received signature along with the address to claim to. Before calling this function, the claimer should have received a signature from the issuer off-chain. The claimer then calls this function with the hash of the claimer's address and the received signature. This is necessary to prevent front-running when the invitee is claiming the invite. Without a commit and reveal scheme, anyone who is watching the mempool can take the signature being submitted and front run the transaction to claim the invite to their own address. The same commitment can only be made once, and the function reverts if the commitment has already been made. This prevents griefing where a malicious party can prevent the original claimer from being able to claimInvite.\"},\"commitmentTimestamps(bytes32)\":{\"notice\":\"Maps from hashes to the timestamp when they were committed.\"},\"initialize(string)\":{\"notice\":\"Initializes this contract, setting the EIP712 context. Only update the EIP712_VERSION when there is a change to the signature scheme. After the EIP712 version is changed, any signatures issued off-chain but not claimed yet will no longer be accepted by the claimInvite function. Please make sure to notify the issuers that they must re-issue their invite signatures.\"},\"inviteCounts(address)\":{\"notice\":\"Maps from addresses to number of invites they have.\"},\"setInviteCounts(address[],uint256)\":{\"notice\":\"Allows invite granter to set the number of invites an address has.\"},\"usedNonces(address,bytes32)\":{\"notice\":\"Maps from addresses to nonces to whether or not they have been used.\"},\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"notice\":\"OptimistInviter issues \\\"optimist.can-invite\\\" and \\\"optimist.can-mint-from-invite\\\" attestations. Accounts that have invites can issue signatures that allow other accounts to claim an invite. The invitee uses a claim and reveal flow to claim the invite to an address of their choosing. Parties involved: 1) INVITE_GRANTER: trusted account that can allow accounts to issue invites 2) issuer: account that is allowed to issue invites 3) claimer: account that receives the invites Flow: 1) INVITE_GRANTER calls _setInviteCount to allow an issuer to issue a certain number of invites, and also creates a \\\"optimist.can-invite\\\" attestation for the issuer 2) Off-chain, the issuer signs (EIP-712) a ClaimableInvite to produce a signature 3) Off-chain, invite issuer sends the plaintext ClaimableInvite and the signature to the recipient 4) claimer chooses an address they want to receive the invite on 5) claimer commits the hash of the address they want to receive the invite on and the received signature keccak256(abi.encode(addressToReceiveTo, receivedSignature)) using the commitInvite function 6) claimer waits for the MIN_COMMITMENT_PERIOD to pass. 7) claimer reveals the plaintext ClaimableInvite and the signature using the claimInvite function, receiving the \\\"optimist.can-mint-from-invite\\\" attestation\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/op-nft/OptimistInviter.sol\":\"OptimistInviter\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { Strings } from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\n\\n/**\\n * @title Semver\\n * @notice Semver is a simple contract for managing contract versions.\\n */\\ncontract Semver {\\n /**\\n * @notice Contract version number (major).\\n */\\n uint256 private immutable MAJOR_VERSION;\\n\\n /**\\n * @notice Contract version number (minor).\\n */\\n uint256 private immutable MINOR_VERSION;\\n\\n /**\\n * @notice Contract version number (patch).\\n */\\n uint256 private immutable PATCH_VERSION;\\n\\n /**\\n * @param _major Version number (major).\\n * @param _minor Version number (minor).\\n * @param _patch Version number (patch).\\n */\\n constructor(\\n uint256 _major,\\n uint256 _minor,\\n uint256 _patch\\n ) {\\n MAJOR_VERSION = _major;\\n MINOR_VERSION = _minor;\\n PATCH_VERSION = _patch;\\n }\\n\\n /**\\n * @notice Returns the full semver contract version.\\n *\\n * @return Semver contract version as a string.\\n */\\n function version() public view returns (string memory) {\\n return\\n string(\\n abi.encodePacked(\\n Strings.toString(MAJOR_VERSION),\\n \\\".\\\",\\n Strings.toString(MINOR_VERSION),\\n \\\".\\\",\\n Strings.toString(PATCH_VERSION)\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x400059d3edb9efc9c23e6fbc18de6710f9235a4ffba4ab23bdb9f825273f093b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xbf5daf926894541a40a64b43c3746aa1940c5a1b3b8d14a06465eea72a9b90cc\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xdb7f5c28fc61cda0bd8ab60ce288e206b791643bcd3ba464a70cbec18895a2f5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.1) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../Address.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n if (error == ECDSA.RecoverError.NoError && recovered == signer) {\\n return true;\\n }\\n\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length == 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0xbb5c92a62f2a917ec08667ebc024d5f4172ae3594cd5f4eaa997485ed0440d81\",\"license\":\"MIT\"},\"contracts/universal/op-nft/AttestationStation.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\n\\n/**\\n * @title AttestationStation\\n * @author Optimism Collective\\n * @author Gitcoin\\n * @notice Where attestations live.\\n */\\ncontract AttestationStation is Semver {\\n /**\\n * @notice Struct representing data that is being attested.\\n *\\n * @custom:field about Address for which the attestation is about.\\n * @custom:field key A bytes32 key for the attestation.\\n * @custom:field val The attestation as arbitrary bytes.\\n */\\n struct AttestationData {\\n address about;\\n bytes32 key;\\n bytes val;\\n }\\n\\n /**\\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\\n */\\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\\n\\n /**\\n * @notice Emitted when Attestation is created.\\n *\\n * @param creator Address that made the attestation.\\n * @param about Address attestation is about.\\n * @param key Key of the attestation.\\n * @param val Value of the attestation.\\n */\\n event AttestationCreated(\\n address indexed creator,\\n address indexed about,\\n bytes32 indexed key,\\n bytes val\\n );\\n\\n /**\\n * @custom:semver 1.1.0\\n */\\n constructor() Semver(1, 1, 0) {}\\n\\n /**\\n * @notice Allows anyone to create an attestation.\\n *\\n * @param _about Address that the attestation is about.\\n * @param _key A key used to namespace the attestation.\\n * @param _val An arbitrary value stored as part of the attestation.\\n */\\n function attest(\\n address _about,\\n bytes32 _key,\\n bytes memory _val\\n ) public {\\n attestations[msg.sender][_about][_key] = _val;\\n\\n emit AttestationCreated(msg.sender, _about, _key, _val);\\n }\\n\\n /**\\n * @notice Allows anyone to create attestations.\\n *\\n * @param _attestations An array of AttestationData structs.\\n */\\n function attest(AttestationData[] calldata _attestations) external {\\n uint256 length = _attestations.length;\\n for (uint256 i = 0; i < length; ) {\\n AttestationData memory attestation = _attestations[i];\\n\\n attest(attestation.about, attestation.key, attestation.val);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x421923e04df145353db12cd0352ccf516d9c29ab64b138733b4f7a6a450ce2be\",\"license\":\"MIT\"},\"contracts/universal/op-nft/OptimistInviter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport { OptimistConstants } from \\\"./libraries/OptimistConstants.sol\\\";\\nimport { Semver } from \\\"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\\\";\\nimport { AttestationStation } from \\\"./AttestationStation.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\nimport {\\n EIP712Upgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\n\\n/**\\n * @custom:upgradeable\\n * @title OptimistInviter\\n * @notice OptimistInviter issues \\\"optimist.can-invite\\\" and \\\"optimist.can-mint-from-invite\\\"\\n * attestations. Accounts that have invites can issue signatures that allow other\\n * accounts to claim an invite. The invitee uses a claim and reveal flow to claim the\\n * invite to an address of their choosing.\\n *\\n * Parties involved:\\n * 1) INVITE_GRANTER: trusted account that can allow accounts to issue invites\\n * 2) issuer: account that is allowed to issue invites\\n * 3) claimer: account that receives the invites\\n *\\n * Flow:\\n * 1) INVITE_GRANTER calls _setInviteCount to allow an issuer to issue a certain number\\n * of invites, and also creates a \\\"optimist.can-invite\\\" attestation for the issuer\\n * 2) Off-chain, the issuer signs (EIP-712) a ClaimableInvite to produce a signature\\n * 3) Off-chain, invite issuer sends the plaintext ClaimableInvite and the signature\\n * to the recipient\\n * 4) claimer chooses an address they want to receive the invite on\\n * 5) claimer commits the hash of the address they want to receive the invite on and the\\n * received signature keccak256(abi.encode(addressToReceiveTo, receivedSignature))\\n * using the commitInvite function\\n * 6) claimer waits for the MIN_COMMITMENT_PERIOD to pass.\\n * 7) claimer reveals the plaintext ClaimableInvite and the signature using the\\n * claimInvite function, receiving the \\\"optimist.can-mint-from-invite\\\" attestation\\n */\\ncontract OptimistInviter is Semver, EIP712Upgradeable {\\n /**\\n * @notice Emitted when an invite is claimed.\\n *\\n * @param issuer Address that issued the signature.\\n * @param claimer Address that claimed the invite.\\n */\\n event InviteClaimed(address indexed issuer, address indexed claimer);\\n\\n /**\\n * @notice Version used for the EIP712 domain separator. This version is separated from the\\n * contract semver because the EIP712 domain separator is used to sign messages, and\\n * changing the domain separator invalidates all existing signatures. We should only\\n * bump this version if we make a major change to the signature scheme.\\n */\\n string public constant EIP712_VERSION = \\\"1.0.0\\\";\\n\\n /**\\n * @notice EIP712 typehash for the ClaimableInvite type.\\n */\\n bytes32 public constant CLAIMABLE_INVITE_TYPEHASH =\\n keccak256(\\\"ClaimableInvite(address issuer,bytes32 nonce)\\\");\\n\\n /**\\n * @notice Attestation key for that signals that an account was allowed to issue invites\\n */\\n bytes32 public constant CAN_INVITE_ATTESTATION_KEY = bytes32(\\\"optimist.can-invite\\\");\\n\\n /**\\n * @notice Granter who can set accounts' invite counts.\\n */\\n address public immutable INVITE_GRANTER;\\n\\n /**\\n * @notice Address of the AttestationStation contract.\\n */\\n AttestationStation public immutable ATTESTATION_STATION;\\n\\n /**\\n * @notice Minimum age of a commitment (in seconds) before it can be revealed using claimInvite.\\n * Currently set to 60 seconds.\\n *\\n * Prevents an attacker from front-running a commitment by taking the signature in the\\n * claimInvite call and quickly committing and claiming it before the the claimer's\\n * transaction succeeds. With this, frontrunning a commitment requires that an attacker\\n * be able to prevent the honest claimer's claimInvite transaction from being included\\n * for this long.\\n */\\n uint256 public constant MIN_COMMITMENT_PERIOD = 60;\\n\\n /**\\n * @notice Struct that represents a claimable invite that will be signed by the issuer.\\n *\\n * @custom:field issuer Address that issued the signature. Reason this is explicitly included,\\n * and not implicitly assumed to be the recovered address from the\\n * signature is that the issuer may be using a ERC-1271 compatible\\n * contract wallet, where the recovered address is not the same as the\\n * issuer, or the signature is not an ECDSA signature at all.\\n * @custom:field nonce Pseudorandom nonce to prevent replay attacks.\\n */\\n struct ClaimableInvite {\\n address issuer;\\n bytes32 nonce;\\n }\\n\\n /**\\n * @notice Maps from hashes to the timestamp when they were committed.\\n */\\n mapping(bytes32 => uint256) public commitmentTimestamps;\\n\\n /**\\n * @notice Maps from addresses to nonces to whether or not they have been used.\\n */\\n mapping(address => mapping(bytes32 => bool)) public usedNonces;\\n\\n /**\\n * @notice Maps from addresses to number of invites they have.\\n */\\n mapping(address => uint256) public inviteCounts;\\n\\n /**\\n * @custom:semver 1.0.0\\n *\\n * @param _inviteGranter Address of the invite granter.\\n * @param _attestationStation Address of the AttestationStation contract.\\n */\\n constructor(address _inviteGranter, AttestationStation _attestationStation) Semver(1, 0, 0) {\\n INVITE_GRANTER = _inviteGranter;\\n ATTESTATION_STATION = _attestationStation;\\n }\\n\\n /**\\n * @notice Initializes this contract, setting the EIP712 context.\\n *\\n * Only update the EIP712_VERSION when there is a change to the signature scheme.\\n * After the EIP712 version is changed, any signatures issued off-chain but not\\n * claimed yet will no longer be accepted by the claimInvite function. Please make\\n * sure to notify the issuers that they must re-issue their invite signatures.\\n *\\n * @param _name Contract name.\\n */\\n function initialize(string memory _name) public initializer {\\n __EIP712_init(_name, EIP712_VERSION);\\n }\\n\\n /**\\n * @notice Allows invite granter to set the number of invites an address has.\\n *\\n * @param _accounts An array of accounts to update the invite counts of.\\n * @param _inviteCount Number of invites to set to.\\n */\\n function setInviteCounts(address[] calldata _accounts, uint256 _inviteCount) public {\\n // Only invite granter can grant invites\\n require(\\n msg.sender == INVITE_GRANTER,\\n \\\"OptimistInviter: only invite granter can grant invites\\\"\\n );\\n\\n uint256 length = _accounts.length;\\n\\n AttestationStation.AttestationData[]\\n memory attestations = new AttestationStation.AttestationData[](length);\\n\\n for (uint256 i; i < length; ) {\\n // Set invite count for account to _inviteCount\\n inviteCounts[_accounts[i]] = _inviteCount;\\n\\n // Create an attestation for posterity that the account is allowed to create invites\\n attestations[i] = AttestationStation.AttestationData({\\n about: _accounts[i],\\n key: CAN_INVITE_ATTESTATION_KEY,\\n val: bytes(\\\"true\\\")\\n });\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n ATTESTATION_STATION.attest(attestations);\\n }\\n\\n /**\\n * @notice Allows anyone (but likely the claimer) to commit a received signature along with the\\n * address to claim to.\\n *\\n * Before calling this function, the claimer should have received a signature from the\\n * issuer off-chain. The claimer then calls this function with the hash of the\\n * claimer's address and the received signature. This is necessary to prevent\\n * front-running when the invitee is claiming the invite. Without a commit and reveal\\n * scheme, anyone who is watching the mempool can take the signature being submitted\\n * and front run the transaction to claim the invite to their own address.\\n *\\n * The same commitment can only be made once, and the function reverts if the\\n * commitment has already been made. This prevents griefing where a malicious party can\\n * prevent the original claimer from being able to claimInvite.\\n *\\n *\\n * @param _commitment A hash of the claimer and signature concatenated.\\n * keccak256(abi.encode(_claimer, _signature))\\n */\\n function commitInvite(bytes32 _commitment) public {\\n // Check that the commitment hasn't already been made. This prevents griefing where\\n // a malicious party continuously re-submits the same commitment, preventing the original\\n // claimer from claiming their invite by resetting the minimum commitment period.\\n require(commitmentTimestamps[_commitment] == 0, \\\"OptimistInviter: commitment already made\\\");\\n\\n commitmentTimestamps[_commitment] = block.timestamp;\\n }\\n\\n /**\\n * @notice Allows anyone to reveal a commitment and claim an invite.\\n *\\n * The hash, keccak256(abi.encode(_claimer, _signature)), should have been already\\n * committed using commitInvite. Before issuing the \\\"optimist.can-mint-from-invite\\\"\\n * attestation, this function checks that\\n * 1) the hash corresponding to the _claimer and the _signature was committed\\n * 2) MIN_COMMITMENT_PERIOD has passed since the commitment was made.\\n * 3) the _signature is signed correctly by the issuer\\n * 4) the _signature hasn't already been used to claim an invite before\\n * 5) the _signature issuer has not used up all of their invites\\n * This function doesn't require that the _claimer is calling this function.\\n *\\n * @param _claimer Address that will be granted the invite.\\n * @param _claimableInvite ClaimableInvite struct containing the issuer and nonce.\\n * @param _signature Signature signed over the claimable invite.\\n */\\n function claimInvite(\\n address _claimer,\\n ClaimableInvite calldata _claimableInvite,\\n bytes memory _signature\\n ) public {\\n uint256 commitmentTimestamp = commitmentTimestamps[\\n keccak256(abi.encode(_claimer, _signature))\\n ];\\n\\n // Make sure the claimer and signature have been committed.\\n require(\\n commitmentTimestamp > 0,\\n \\\"OptimistInviter: claimer and signature have not been committed yet\\\"\\n );\\n\\n // Check that MIN_COMMITMENT_PERIOD has passed since the commitment was made.\\n require(\\n commitmentTimestamp + MIN_COMMITMENT_PERIOD <= block.timestamp,\\n \\\"OptimistInviter: minimum commitment period has not elapsed yet\\\"\\n );\\n\\n // Generate a EIP712 typed data hash to compare against the signature.\\n bytes32 digest = _hashTypedDataV4(\\n keccak256(\\n abi.encode(\\n CLAIMABLE_INVITE_TYPEHASH,\\n _claimableInvite.issuer,\\n _claimableInvite.nonce\\n )\\n )\\n );\\n\\n // Uses SignatureChecker, which supports both regular ECDSA signatures from EOAs as well as\\n // ERC-1271 signatures from contract wallets or multi-sigs. This means that if the issuer\\n // wants to revoke a signature, they can use a smart contract wallet to issue the signature,\\n // then invalidate the signature after issuing it.\\n require(\\n SignatureChecker.isValidSignatureNow(_claimableInvite.issuer, digest, _signature),\\n \\\"OptimistInviter: invalid signature\\\"\\n );\\n\\n // The issuer's signature commits to a nonce to prevent replay attacks.\\n // This checks that the nonce has not been used for this issuer before. The nonces are\\n // scoped to the issuer address, so the same nonce can be used by different issuers without\\n // clashing.\\n require(\\n usedNonces[_claimableInvite.issuer][_claimableInvite.nonce] == false,\\n \\\"OptimistInviter: nonce has already been used\\\"\\n );\\n\\n // Set the nonce as used for the issuer so that it cannot be replayed.\\n usedNonces[_claimableInvite.issuer][_claimableInvite.nonce] = true;\\n\\n // Failing this check means that the issuer has used up all of their existing invites.\\n require(\\n inviteCounts[_claimableInvite.issuer] > 0,\\n \\\"OptimistInviter: issuer has no invites\\\"\\n );\\n\\n // Reduce the issuer's invite count by 1. Can be unchecked because we check above that\\n // count is > 0.\\n unchecked {\\n --inviteCounts[_claimableInvite.issuer];\\n }\\n\\n // Create the attestation that the claimer can mint from the issuer's invite.\\n // The invite issuer is included in the data of the attestation.\\n ATTESTATION_STATION.attest(\\n _claimer,\\n OptimistConstants.OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY,\\n abi.encode(_claimableInvite.issuer)\\n );\\n\\n emit InviteClaimed(_claimableInvite.issuer, _claimer);\\n }\\n}\\n\",\"keccak256\":\"0xd7b006570c7e0c66ed0a8001c7e57848062913639e65f5bb6f4d8120e2a00c32\",\"license\":\"MIT\"},\"contracts/universal/op-nft/libraries/OptimistConstants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title OptimistConstants\\n * @notice Library for storing Optimist related constants that are shared in multiple contracts.\\n */\\n\\nlibrary OptimistConstants {\\n /**\\n * @notice Attestation key issued by OptimistInviter allowing the attested account to mint.\\n */\\n bytes32 internal constant OPTIMIST_CAN_MINT_FROM_INVITE_ATTESTATION_KEY =\\n bytes32(\\\"optimist.can-mint-from-invite\\\");\\n}\\n\",\"keccak256\":\"0x6eebe1db87f8a5de79bf8af9120e5b0cc6a9b51d8d86e6461cdb6bc52a1dde21\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6101206040523480156200001257600080fd5b5060405162001e0938038062001e09833981016040819052620000359162000076565b6001608052600060a081905260c0526001600160a01b0391821660e0521661010052620000b5565b6001600160a01b03811681146200007357600080fd5b50565b600080604083850312156200008a57600080fd5b825162000097816200005d565b6020840151909250620000aa816200005d565b809150509250929050565b60805160a05160c05160e05161010051611cfb6200010e60003960008181610257015281816106510152610c0201526000818160f401526103b401526000610da101526000610d7801526000610d4f0152611cfb6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063916db22f1161008c578063db083d7111610066578063db083d7114610252578063de2dd22114610279578063eccec5a814610299578063f62d1888146102d557600080fd5b8063916db22f146101e4578063b4245d731461020b578063c4fc453d1461022b57600080fd5b806350b414e6116100c857806350b414e61461016857806350eedbc21461017e57806354fd4d50146101915780635fda04c7146101a657600080fd5b806314b47241146100ef578063187e3cd11461014057806325b27a3d14610155575b600080fd5b6101167f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61015361014e36600461165f565b6102e8565b005b610153610163366004611678565b61039c565b610170603c81565b604051908152602001610137565b61015361018c3660046117df565b6106bf565b610199610d48565b60405161013791906118f5565b6101d46101b4366004611908565b603660209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610137565b6101707f6f7074696d6973742e63616e2d696e766974650000000000000000000000000081565b61017061021936600461165f565b60356020526000908152604090205481565b6101707f6529fd129351e725d7bcbc468b0b0b4675477e56b58514e69ab7e66ddfd20fce81565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b610170610287366004611932565b60376020526000908152604090205481565b6101996040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6101536102e336600461194d565b610deb565b60008181526035602052604090205415610389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4f7074696d697374496e76697465723a20636f6d6d69746d656e7420616c726560448201527f616479206d61646500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000908152603560205260409020429055565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4f7074696d697374496e76697465723a206f6e6c7920696e766974652067726160448201527f6e7465722063616e206772616e7420696e7669746573000000000000000000006064820152608401610380565b8160008167ffffffffffffffff81111561047d5761047d61171c565b6040519080825280602002602001820160405280156104ca57816020015b6040805160608082018352600080835260208301529181019190915281526020019060019003908161049b5790505b50905060005b828110156106135783603760008888858181106104ef576104ef611996565b90506020020160208101906105049190611932565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550604051806060016040528087878481811061055f5761055f611996565b90506020020160208101906105749190611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020017f6f7074696d6973742e63616e2d696e766974650000000000000000000000000081526020016040518060400160405280600481526020017f747275650000000000000000000000000000000000000000000000000000000081525081525082828151811061060057610600611996565b60209081029190910101526001016104d0565b506040517f5eb5ea1000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690635eb5ea10906106869084906004016119c5565b600060405180830381600087803b1580156106a057600080fd5b505af11580156106b4573d6000803e3d6000fd5b505050505050505050565b60006035600085846040516020016106d8929190611a78565b604051602081830303815290604052805190602001208152602001908152602001600020549050600081116107b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f4f7074696d697374496e76697465723a20636c61696d657220616e642073696760448201527f6e61747572652068617665206e6f74206265656e20636f6d6d6974746564207960648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a401610380565b426107c1603c83611ad6565b111561084f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f7074696d697374496e76697465723a206d696e696d756d20636f6d6d69746d60448201527f656e7420706572696f6420686173206e6f7420656c61707365642079657400006064820152608401610380565b60006108d27f6529fd129351e725d7bcbc468b0b0b4675477e56b58514e69ab7e66ddfd20fce6108826020870187611932565b6040805160208181019490945273ffffffffffffffffffffffffffffffffffffffff9092169082015290860135606082015260800160405160208183030381529060405280519060200120610fb5565b90506108eb6108e46020860186611932565b8285611024565b610977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4f7074696d697374496e76697465723a20696e76616c6964207369676e61747560448201527f72650000000000000000000000000000000000000000000000000000000000006064820152608401610380565b603660006109886020870187611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020808201929092526040908101600090812087840135825290925290205460ff1615610a4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4f7074696d697374496e76697465723a206e6f6e63652068617320616c72656160448201527f6479206265656e207573656400000000000000000000000000000000000000006064820152608401610380565b600160366000610a626020880188611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020808201929092526040908101600090812088840180358352935290812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016931515939093179092556037908290610ad69088611932565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411610b9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f7074696d697374496e76697465723a2069737375657220686173206e6f206960448201527f6e766974657300000000000000000000000000000000000000000000000000006064820152608401610380565b60376000610baf6020870187611932565b73ffffffffffffffffffffffffffffffffffffffff9081168252602080830193909352604090910160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190557f0000000000000000000000000000000000000000000000000000000000000000169063702b9dee9087907f6f7074696d6973742e63616e2d6d696e742d66726f6d2d696e7669746500000090610c5990890189611932565b6040805173ffffffffffffffffffffffffffffffffffffffff9092166020830152016040516020818303038152906040526040518463ffffffff1660e01b8152600401610ca893929190611aee565b600060405180830381600087803b158015610cc257600080fd5b505af1158015610cd6573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff86169050610cff6020860186611932565b73ffffffffffffffffffffffffffffffffffffffff167f745d3c5bc92ab40b418069bf8f8e2030807effceb88bbaa07ee01574f16be47560405160405180910390a35050505050565b6060610d737f00000000000000000000000000000000000000000000000000000000000000006111f3565b610d9c7f00000000000000000000000000000000000000000000000000000000000000006111f3565b610dc57f00000000000000000000000000000000000000000000000000000000000000006111f3565b604051602001610dd793929190611b2c565b604051602081830303815290604052905090565b600054610100900460ff1615808015610e0b5750600054600160ff909116105b80610e255750303b158015610e25575060005460ff166001145b610eb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610380565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610f0f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610f4e826040518060400160405280600581526020017f312e302e30000000000000000000000000000000000000000000000000000000815250611330565b8015610fb157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600061101e610fc26113d1565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b92915050565b60008060006110338585611451565b9092509050600081600481111561104c5761104c611ba2565b14801561108457508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15611094576001925050506111ec565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016110c9929190611bd1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516111529190611bea565b600060405180830381855afa9150503d806000811461118d576040519150601f19603f3d011682016040523d82523d6000602084013e611192565b606091505b50915091508180156111a5575080516020145b80156111e5575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906111e39083016020908101908401611c06565b145b9450505050505b9392505050565b60608160000361123657505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611260578061124a81611c1f565b91506112599050600a83611c86565b915061123a565b60008167ffffffffffffffff81111561127b5761127b61171c565b6040519080825280601f01601f1916602001820160405280156112a5576020820181803683370190505b5090505b8415611328576112ba600183611c9a565b91506112c7600a86611cb1565b6112d2906030611ad6565b60f81b8183815181106112e7576112e7611996565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611321600a86611c86565b94506112a9565b949350505050565b600054610100900460ff166113c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610380565b610fb18282611496565b600061144c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61140060015490565b6002546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b905090565b60008082516041036114875760208301516040840151606085015160001a61147b87828585611547565b9450945050505061148f565b506000905060025b9250929050565b600054610100900460ff1661152d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610380565b815160209283012081519190920120600191909155600255565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561157e5750600090506003611656565b8460ff16601b1415801561159657508460ff16601c14155b156115a75750600090506004611656565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156115fb573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661164f57600060019250925050611656565b9150600090505b94509492505050565b60006020828403121561167157600080fd5b5035919050565b60008060006040848603121561168d57600080fd5b833567ffffffffffffffff808211156116a557600080fd5b818601915086601f8301126116b957600080fd5b8135818111156116c857600080fd5b8760208260051b85010111156116dd57600080fd5b6020928301989097509590910135949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461171757600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff808411156117665761176661171c565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156117ac576117ac61171c565b816040528093508581528686860111156117c557600080fd5b858560208301376000602087830101525050509392505050565b600080600083850360808112156117f557600080fd5b6117fe856116f3565b935060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561183057600080fd5b50602084019150606084013567ffffffffffffffff81111561185157600080fd5b8401601f8101861361186257600080fd5b6118718682356020840161174b565b9150509250925092565b60005b8381101561189657818101518382015260200161187e565b838111156118a5576000848401525b50505050565b600081518084526118c381602086016020860161187b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111ec60208301846118ab565b6000806040838503121561191b57600080fd5b611924836116f3565b946020939093013593505050565b60006020828403121561194457600080fd5b6111ec826116f3565b60006020828403121561195f57600080fd5b813567ffffffffffffffff81111561197657600080fd5b8201601f8101841361198757600080fd5b6113288482356020840161174b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611a6a578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287810151888501528601516060878501819052611a56818601836118ab565b9689019694505050908601906001016119ec565b509098975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061132860408301846118ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115611ae957611ae9611aa7565b500190565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611b2360608301846118ab565b95945050505050565b60008451611b3e81846020890161187b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611b7a816001850160208a0161187b565b60019201918201528351611b9581600284016020880161187b565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061132860408301846118ab565b60008251611bfc81846020870161187b565b9190910192915050565b600060208284031215611c1857600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c5057611c50611aa7565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611c9557611c95611c57565b500490565b600082821015611cac57611cac611aa7565b500390565b600082611cc057611cc0611c57565b50069056fea264697066735822122097f93936c2ea57902b86c424cff790fa55dccd81b007b045479cd5575c81c5d564736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063916db22f1161008c578063db083d7111610066578063db083d7114610252578063de2dd22114610279578063eccec5a814610299578063f62d1888146102d557600080fd5b8063916db22f146101e4578063b4245d731461020b578063c4fc453d1461022b57600080fd5b806350b414e6116100c857806350b414e61461016857806350eedbc21461017e57806354fd4d50146101915780635fda04c7146101a657600080fd5b806314b47241146100ef578063187e3cd11461014057806325b27a3d14610155575b600080fd5b6101167f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61015361014e36600461165f565b6102e8565b005b610153610163366004611678565b61039c565b610170603c81565b604051908152602001610137565b61015361018c3660046117df565b6106bf565b610199610d48565b60405161013791906118f5565b6101d46101b4366004611908565b603660209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610137565b6101707f6f7074696d6973742e63616e2d696e766974650000000000000000000000000081565b61017061021936600461165f565b60356020526000908152604090205481565b6101707f6529fd129351e725d7bcbc468b0b0b4675477e56b58514e69ab7e66ddfd20fce81565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b610170610287366004611932565b60376020526000908152604090205481565b6101996040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6101536102e336600461194d565b610deb565b60008181526035602052604090205415610389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4f7074696d697374496e76697465723a20636f6d6d69746d656e7420616c726560448201527f616479206d61646500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000908152603560205260409020429055565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4f7074696d697374496e76697465723a206f6e6c7920696e766974652067726160448201527f6e7465722063616e206772616e7420696e7669746573000000000000000000006064820152608401610380565b8160008167ffffffffffffffff81111561047d5761047d61171c565b6040519080825280602002602001820160405280156104ca57816020015b6040805160608082018352600080835260208301529181019190915281526020019060019003908161049b5790505b50905060005b828110156106135783603760008888858181106104ef576104ef611996565b90506020020160208101906105049190611932565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550604051806060016040528087878481811061055f5761055f611996565b90506020020160208101906105749190611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020017f6f7074696d6973742e63616e2d696e766974650000000000000000000000000081526020016040518060400160405280600481526020017f747275650000000000000000000000000000000000000000000000000000000081525081525082828151811061060057610600611996565b60209081029190910101526001016104d0565b506040517f5eb5ea1000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690635eb5ea10906106869084906004016119c5565b600060405180830381600087803b1580156106a057600080fd5b505af11580156106b4573d6000803e3d6000fd5b505050505050505050565b60006035600085846040516020016106d8929190611a78565b604051602081830303815290604052805190602001208152602001908152602001600020549050600081116107b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f4f7074696d697374496e76697465723a20636c61696d657220616e642073696760448201527f6e61747572652068617665206e6f74206265656e20636f6d6d6974746564207960648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a401610380565b426107c1603c83611ad6565b111561084f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f7074696d697374496e76697465723a206d696e696d756d20636f6d6d69746d60448201527f656e7420706572696f6420686173206e6f7420656c61707365642079657400006064820152608401610380565b60006108d27f6529fd129351e725d7bcbc468b0b0b4675477e56b58514e69ab7e66ddfd20fce6108826020870187611932565b6040805160208181019490945273ffffffffffffffffffffffffffffffffffffffff9092169082015290860135606082015260800160405160208183030381529060405280519060200120610fb5565b90506108eb6108e46020860186611932565b8285611024565b610977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4f7074696d697374496e76697465723a20696e76616c6964207369676e61747560448201527f72650000000000000000000000000000000000000000000000000000000000006064820152608401610380565b603660006109886020870187611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020808201929092526040908101600090812087840135825290925290205460ff1615610a4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4f7074696d697374496e76697465723a206e6f6e63652068617320616c72656160448201527f6479206265656e207573656400000000000000000000000000000000000000006064820152608401610380565b600160366000610a626020880188611932565b73ffffffffffffffffffffffffffffffffffffffff1681526020808201929092526040908101600090812088840180358352935290812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016931515939093179092556037908290610ad69088611932565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411610b9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f7074696d697374496e76697465723a2069737375657220686173206e6f206960448201527f6e766974657300000000000000000000000000000000000000000000000000006064820152608401610380565b60376000610baf6020870187611932565b73ffffffffffffffffffffffffffffffffffffffff9081168252602080830193909352604090910160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190557f0000000000000000000000000000000000000000000000000000000000000000169063702b9dee9087907f6f7074696d6973742e63616e2d6d696e742d66726f6d2d696e7669746500000090610c5990890189611932565b6040805173ffffffffffffffffffffffffffffffffffffffff9092166020830152016040516020818303038152906040526040518463ffffffff1660e01b8152600401610ca893929190611aee565b600060405180830381600087803b158015610cc257600080fd5b505af1158015610cd6573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff86169050610cff6020860186611932565b73ffffffffffffffffffffffffffffffffffffffff167f745d3c5bc92ab40b418069bf8f8e2030807effceb88bbaa07ee01574f16be47560405160405180910390a35050505050565b6060610d737f00000000000000000000000000000000000000000000000000000000000000006111f3565b610d9c7f00000000000000000000000000000000000000000000000000000000000000006111f3565b610dc57f00000000000000000000000000000000000000000000000000000000000000006111f3565b604051602001610dd793929190611b2c565b604051602081830303815290604052905090565b600054610100900460ff1615808015610e0b5750600054600160ff909116105b80610e255750303b158015610e25575060005460ff166001145b610eb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610380565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610f0f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610f4e826040518060400160405280600581526020017f312e302e30000000000000000000000000000000000000000000000000000000815250611330565b8015610fb157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600061101e610fc26113d1565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b92915050565b60008060006110338585611451565b9092509050600081600481111561104c5761104c611ba2565b14801561108457508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15611094576001925050506111ec565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016110c9929190611bd1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516111529190611bea565b600060405180830381855afa9150503d806000811461118d576040519150601f19603f3d011682016040523d82523d6000602084013e611192565b606091505b50915091508180156111a5575080516020145b80156111e5575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906111e39083016020908101908401611c06565b145b9450505050505b9392505050565b60608160000361123657505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611260578061124a81611c1f565b91506112599050600a83611c86565b915061123a565b60008167ffffffffffffffff81111561127b5761127b61171c565b6040519080825280601f01601f1916602001820160405280156112a5576020820181803683370190505b5090505b8415611328576112ba600183611c9a565b91506112c7600a86611cb1565b6112d2906030611ad6565b60f81b8183815181106112e7576112e7611996565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611321600a86611c86565b94506112a9565b949350505050565b600054610100900460ff166113c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610380565b610fb18282611496565b600061144c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61140060015490565b6002546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b905090565b60008082516041036114875760208301516040840151606085015160001a61147b87828585611547565b9450945050505061148f565b506000905060025b9250929050565b600054610100900460ff1661152d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610380565b815160209283012081519190920120600191909155600255565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561157e5750600090506003611656565b8460ff16601b1415801561159657508460ff16601c14155b156115a75750600090506004611656565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156115fb573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661164f57600060019250925050611656565b9150600090505b94509492505050565b60006020828403121561167157600080fd5b5035919050565b60008060006040848603121561168d57600080fd5b833567ffffffffffffffff808211156116a557600080fd5b818601915086601f8301126116b957600080fd5b8135818111156116c857600080fd5b8760208260051b85010111156116dd57600080fd5b6020928301989097509590910135949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461171757600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff808411156117665761176661171c565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156117ac576117ac61171c565b816040528093508581528686860111156117c557600080fd5b858560208301376000602087830101525050509392505050565b600080600083850360808112156117f557600080fd5b6117fe856116f3565b935060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561183057600080fd5b50602084019150606084013567ffffffffffffffff81111561185157600080fd5b8401601f8101861361186257600080fd5b6118718682356020840161174b565b9150509250925092565b60005b8381101561189657818101518382015260200161187e565b838111156118a5576000848401525b50505050565b600081518084526118c381602086016020860161187b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111ec60208301846118ab565b6000806040838503121561191b57600080fd5b611924836116f3565b946020939093013593505050565b60006020828403121561194457600080fd5b6111ec826116f3565b60006020828403121561195f57600080fd5b813567ffffffffffffffff81111561197657600080fd5b8201601f8101841361198757600080fd5b6113288482356020840161174b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611a6a578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287810151888501528601516060878501819052611a56818601836118ab565b9689019694505050908601906001016119ec565b509098975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061132860408301846118ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115611ae957611ae9611aa7565b500190565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611b2360608301846118ab565b95945050505050565b60008451611b3e81846020890161187b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611b7a816001850160208a0161187b565b60019201918201528351611b9581600284016020880161187b565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061132860408301846118ab565b60008251611bfc81846020870161187b565b9190910192915050565b600060208284031215611c1857600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c5057611c50611aa7565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611c9557611c95611c57565b500490565b600082821015611cac57611cac611aa7565b500390565b600082611cc057611cc0611c57565b50069056fea264697066735822122097f93936c2ea57902b86c424cff790fa55dccd81b007b045479cd5575c81c5d564736f6c634300080f0033", - "devdoc": { - "custom:upgradeable": "@title OptimistInviter", - "events": { - "InviteClaimed(address,address)": { - "params": { - "claimer": "Address that claimed the invite.", - "issuer": "Address that issued the signature." - } - } - }, - "kind": "dev", - "methods": { - "claimInvite(address,(address,bytes32),bytes)": { - "params": { - "_claimableInvite": "ClaimableInvite struct containing the issuer and nonce.", - "_claimer": "Address that will be granted the invite.", - "_signature": "Signature signed over the claimable invite." - } - }, - "commitInvite(bytes32)": { - "params": { - "_commitment": "A hash of the claimer and signature concatenated. keccak256(abi.encode(_claimer, _signature))" - } - }, - "constructor": { - "custom:semver": "1.0.0", - "params": { - "_attestationStation": "Address of the AttestationStation contract.", - "_inviteGranter": "Address of the invite granter." - } - }, - "initialize(string)": { - "params": { - "_name": "Contract name." - } - }, - "setInviteCounts(address[],uint256)": { - "params": { - "_accounts": "An array of accounts to update the invite counts of.", - "_inviteCount": "Number of invites to set to." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "version": 1 - }, - "userdoc": { - "events": { - "InviteClaimed(address,address)": { - "notice": "Emitted when an invite is claimed." - } - }, - "kind": "user", - "methods": { - "ATTESTATION_STATION()": { - "notice": "Address of the AttestationStation contract." - }, - "CAN_INVITE_ATTESTATION_KEY()": { - "notice": "Attestation key for that signals that an account was allowed to issue invites" - }, - "CLAIMABLE_INVITE_TYPEHASH()": { - "notice": "EIP712 typehash for the ClaimableInvite type." - }, - "EIP712_VERSION()": { - "notice": "Version used for the EIP712 domain separator. This version is separated from the contract semver because the EIP712 domain separator is used to sign messages, and changing the domain separator invalidates all existing signatures. We should only bump this version if we make a major change to the signature scheme." - }, - "INVITE_GRANTER()": { - "notice": "Granter who can set accounts' invite counts." - }, - "MIN_COMMITMENT_PERIOD()": { - "notice": "Minimum age of a commitment (in seconds) before it can be revealed using claimInvite. Currently set to 60 seconds. Prevents an attacker from front-running a commitment by taking the signature in the claimInvite call and quickly committing and claiming it before the the claimer's transaction succeeds. With this, frontrunning a commitment requires that an attacker be able to prevent the honest claimer's claimInvite transaction from being included for this long." - }, - "claimInvite(address,(address,bytes32),bytes)": { - "notice": "Allows anyone to reveal a commitment and claim an invite. The hash, keccak256(abi.encode(_claimer, _signature)), should have been already committed using commitInvite. Before issuing the \"optimist.can-mint-from-invite\" attestation, this function checks that 1) the hash corresponding to the _claimer and the _signature was committed 2) MIN_COMMITMENT_PERIOD has passed since the commitment was made. 3) the _signature is signed correctly by the issuer 4) the _signature hasn't already been used to claim an invite before 5) the _signature issuer has not used up all of their invites This function doesn't require that the _claimer is calling this function." - }, - "commitInvite(bytes32)": { - "notice": "Allows anyone (but likely the claimer) to commit a received signature along with the address to claim to. Before calling this function, the claimer should have received a signature from the issuer off-chain. The claimer then calls this function with the hash of the claimer's address and the received signature. This is necessary to prevent front-running when the invitee is claiming the invite. Without a commit and reveal scheme, anyone who is watching the mempool can take the signature being submitted and front run the transaction to claim the invite to their own address. The same commitment can only be made once, and the function reverts if the commitment has already been made. This prevents griefing where a malicious party can prevent the original claimer from being able to claimInvite." - }, - "commitmentTimestamps(bytes32)": { - "notice": "Maps from hashes to the timestamp when they were committed." - }, - "initialize(string)": { - "notice": "Initializes this contract, setting the EIP712 context. Only update the EIP712_VERSION when there is a change to the signature scheme. After the EIP712 version is changed, any signatures issued off-chain but not claimed yet will no longer be accepted by the claimInvite function. Please make sure to notify the issuers that they must re-issue their invite signatures." - }, - "inviteCounts(address)": { - "notice": "Maps from addresses to number of invites they have." - }, - "setInviteCounts(address[],uint256)": { - "notice": "Allows invite granter to set the number of invites an address has." - }, - "usedNonces(address,bytes32)": { - "notice": "Maps from addresses to nonces to whether or not they have been used." - }, - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "OptimistInviter issues \"optimist.can-invite\" and \"optimist.can-mint-from-invite\" attestations. Accounts that have invites can issue signatures that allow other accounts to claim an invite. The invitee uses a claim and reveal flow to claim the invite to an address of their choosing. Parties involved: 1) INVITE_GRANTER: trusted account that can allow accounts to issue invites 2) issuer: account that is allowed to issue invites 3) claimer: account that receives the invites Flow: 1) INVITE_GRANTER calls _setInviteCount to allow an issuer to issue a certain number of invites, and also creates a \"optimist.can-invite\" attestation for the issuer 2) Off-chain, the issuer signs (EIP-712) a ClaimableInvite to produce a signature 3) Off-chain, invite issuer sends the plaintext ClaimableInvite and the signature to the recipient 4) claimer chooses an address they want to receive the invite on 5) claimer commits the hash of the address they want to receive the invite on and the received signature keccak256(abi.encode(addressToReceiveTo, receivedSignature)) using the commitInvite function 6) claimer waits for the MIN_COMMITMENT_PERIOD to pass. 7) claimer reveals the plaintext ClaimableInvite and the signature using the claimInvite function, receiving the \"optimist.can-mint-from-invite\" attestation", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 1166, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 1169, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 3321, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "_HASHED_NAME", - "offset": 0, - "slot": "1", - "type": "t_bytes32" - }, - { - "astId": 3323, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "_HASHED_VERSION", - "offset": 0, - "slot": "2", - "type": "t_bytes32" - }, - { - "astId": 3461, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "__gap", - "offset": 0, - "slot": "3", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 5494, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "commitmentTimestamps", - "offset": 0, - "slot": "53", - "type": "t_mapping(t_bytes32,t_uint256)" - }, - { - "astId": 5501, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "usedNonces", - "offset": 0, - "slot": "54", - "type": "t_mapping(t_address,t_mapping(t_bytes32,t_bool))" - }, - { - "astId": 5506, - "contract": "contracts/universal/op-nft/OptimistInviter.sol:OptimistInviter", - "label": "inviteCounts", - "offset": 0, - "slot": "55", - "type": "t_mapping(t_address,t_uint256)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)50_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_bytes32,t_bool))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(bytes32 => bool))", - "numberOfBytes": "32", - "value": "t_mapping(t_bytes32,t_bool)" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_mapping(t_bytes32,t_bool)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_mapping(t_bytes32,t_uint256)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistInviterProxy.json b/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistInviterProxy.json deleted file mode 100644 index 24a4368dad49..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistInviterProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x073031A1E1b8F5458Ed41Ce56331F5fd7e1de929", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x0103162552bf1ea529a5b39fa6b29efe7439475be4bed49cda640f2a3b91b3e3", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "534190", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080010000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xde6a4af6b6df5b8bcc01857505fbab84445c5441f2a76c2f62e3c1a942f2265b", - "transactionHash": "0x0103162552bf1ea529a5b39fa6b29efe7439475be4bed49cda640f2a3b91b3e3", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 87031037, - "transactionHash": "0x0103162552bf1ea529a5b39fa6b29efe7439475be4bed49cda640f2a3b91b3e3", - "address": "0x073031A1E1b8F5458Ed41Ce56331F5fd7e1de929", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58", - "logIndex": 0, - "blockHash": "0xde6a4af6b6df5b8bcc01857505fbab84445c5441f2a76c2f62e3c1a942f2265b" - } - ], - "blockNumber": 87031037, - "cumulativeGasUsed": "534190", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "d7155764d4bdb814f10e1bb45296292b", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) public virtual proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n public\\n payable\\n virtual\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) public virtual proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() public virtual proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() public virtual proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0x64d67f1936d97c87a2e42317eb162744ad5cefdc9bc8b1138ee4afe2886eb885\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea26469706673582212200496188e743eb5556ea8662e234845601d39477882517acc1cf9061fcc51284c64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea26469706673582212200496188e743eb5556ea8662e234845601d39477882517acc1cf9061fcc51284c64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistProxy.json b/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistProxy.json deleted file mode 100644 index 904016e921b2..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/OptimistProxy.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "address": "0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "transactionHash": "0x3a663cc47f695bade6e93cbd5803bdd8e3419a689fd4682a2e12a37f9a6dd3ef", - "receipt": { - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58", - "contractAddress": null, - "transactionIndex": 0, - "gasUsed": "534190", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000020000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x8edb9af706a1eaa6dcff60412414c56e2b55528e997bd9f079d9eca72aa745fc", - "transactionHash": "0x3a663cc47f695bade6e93cbd5803bdd8e3419a689fd4682a2e12a37f9a6dd3ef", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 49670714, - "transactionHash": "0x3a663cc47f695bade6e93cbd5803bdd8e3419a689fd4682a2e12a37f9a6dd3ef", - "address": "0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58", - "logIndex": 0, - "blockHash": "0x8edb9af706a1eaa6dcff60412414c56e2b55528e997bd9f079d9eca72aa745fc" - } - ], - "blockNumber": 49670714, - "cumulativeGasUsed": "534190", - "status": 1, - "byzantium": true - }, - "args": [ - "0x9C6373dE60c2D3297b18A8f964618ac46E011B58" - ], - "numDeployments": 1, - "solcInputHash": "45837d34ff24b9cb2ae34232b60ea874", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n external\\n payable\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() external proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() external proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033", - "devdoc": { - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "title": "Proxy", - "version": 1 - }, - "userdoc": { - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "implementation()": { - "notice": "Queries the implementation address." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/SchemaRegistry.json b/packages/contracts-bedrock/deployments/optimism-mainnet/SchemaRegistry.json deleted file mode 100644 index 458dd59f0d96..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/SchemaRegistry.json +++ /dev/null @@ -1,293 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "AlreadyExists", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "registerer", - "type": "address" - } - ], - "name": "Registered", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - } - ], - "name": "getSchema", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "uid", - "type": "bytes32" - }, - { - "internalType": "contract ISchemaResolver", - "name": "resolver", - "type": "address" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - }, - { - "internalType": "string", - "name": "schema", - "type": "string" - } - ], - "internalType": "struct SchemaRecord", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "schema", - "type": "string" - }, - { - "internalType": "contract ISchemaResolver", - "name": "resolver", - "type": "address" - }, - { - "internalType": "bool", - "name": "revocable", - "type": "bool" - } - ], - "name": "register", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x6232208d66bAc2305b46b4Cb6BCB3857B298DF13", - "args": [], - "bytecode": "0x60e060405234801561001057600080fd5b5060016080819052600060a081905260c082905281610b166100478339600060fe0152600060d50152600060ac0152610b166000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806360d7a27814610064578063a2ea7c6e14610085575b600080fd5b61004e6100a5565b60405161005b9190610604565b60405180910390f35b61007761007236600461061e565b610148565b60405190815260200161005b565b6100986100933660046106d0565b6102f1565b60405161005b91906106e9565b60606100d07f0000000000000000000000000000000000000000000000000000000000000000610419565b6100f97f0000000000000000000000000000000000000000000000000000000000000000610419565b6101227f0000000000000000000000000000000000000000000000000000000000000000610419565b6040516020016101349392919061073a565b604051602081830303815290604052905090565b60008060405180608001604052806000801b81526020018573ffffffffffffffffffffffffffffffffffffffff168152602001841515815260200187878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939094525092935091506101ca905082610556565b60008181526020819052604090205490915015610213576040517f23369fa600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80825260008181526020818152604091829020845181559084015160018201805493860151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00000000000000000000000000000000000000000090941673ffffffffffffffffffffffffffffffffffffffff9092169190911792909217909155606083015183919060028201906102af9082610881565b50506040513381528291507f7d917fcbc9a29a9705ff9936ffa599500e4fd902e4486bae317414fe967b307c9060200160405180910390a29695505050505050565b604080516080810182526000808252602082018190529181019190915260608082015260008281526020818152604091829020825160808101845281548152600182015473ffffffffffffffffffffffffffffffffffffffff8116938201939093527401000000000000000000000000000000000000000090920460ff16151592820192909252600282018054919291606084019190610390906107df565b80601f01602080910402602001604051908101604052809291908181526020018280546103bc906107df565b80156104095780601f106103de57610100808354040283529160200191610409565b820191906000526020600020905b8154815290600101906020018083116103ec57829003601f168201915b5050505050815250509050919050565b60608160000361045c57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104865780610470816109ca565b915061047f9050600a83610a31565b9150610460565b60008167ffffffffffffffff8111156104a1576104a16107b0565b6040519080825280601f01601f1916602001820160405280156104cb576020820181803683370190505b5090505b841561054e576104e0600183610a45565b91506104ed600a86610a5e565b6104f8906030610a72565b60f81b81838151811061050d5761050d610a85565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610547600a86610a31565b94506104cf565b949350505050565b600081606001518260200151836040015160405160200161057993929190610ab4565b604051602081830303815290604052805190602001209050919050565b60005b838110156105b1578181015183820152602001610599565b50506000910152565b600081518084526105d2816020860160208601610596565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061061760208301846105ba565b9392505050565b6000806000806060858703121561063457600080fd5b843567ffffffffffffffff8082111561064c57600080fd5b818701915087601f83011261066057600080fd5b81358181111561066f57600080fd5b88602082850101111561068157600080fd5b6020928301965094505085013573ffffffffffffffffffffffffffffffffffffffff811681146106b057600080fd5b9150604085013580151581146106c557600080fd5b939692955090935050565b6000602082840312156106e257600080fd5b5035919050565b602081528151602082015273ffffffffffffffffffffffffffffffffffffffff60208301511660408201526040820151151560608201526000606083015160808084015261054e60a08401826105ba565b6000845161074c818460208901610596565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610788816001850160208a01610596565b600192019182015283516107a3816002840160208801610596565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600181811c908216806107f357607f821691505b60208210810361082c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561087c57600081815260208120601f850160051c810160208610156108595750805b601f850160051c820191505b8181101561087857828155600101610865565b5050505b505050565b815167ffffffffffffffff81111561089b5761089b6107b0565b6108af816108a984546107df565b84610832565b602080601f83116001811461090257600084156108cc5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610878565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561094f57888601518255948401946001909101908401610930565b508582101561098b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109fb576109fb61099b565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a4057610a40610a02565b500490565b81810381811115610a5857610a5861099b565b92915050565b600082610a6d57610a6d610a02565b500690565b80820180821115610a5857610a5861099b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008451610ac6818460208901610596565b60609490941b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190930190815290151560f81b60148201526015019291505056fea164736f6c6343000813000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806354fd4d501461004657806360d7a27814610064578063a2ea7c6e14610085575b600080fd5b61004e6100a5565b60405161005b9190610604565b60405180910390f35b61007761007236600461061e565b610148565b60405190815260200161005b565b6100986100933660046106d0565b6102f1565b60405161005b91906106e9565b60606100d07f0000000000000000000000000000000000000000000000000000000000000000610419565b6100f97f0000000000000000000000000000000000000000000000000000000000000000610419565b6101227f0000000000000000000000000000000000000000000000000000000000000000610419565b6040516020016101349392919061073a565b604051602081830303815290604052905090565b60008060405180608001604052806000801b81526020018573ffffffffffffffffffffffffffffffffffffffff168152602001841515815260200187878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939094525092935091506101ca905082610556565b60008181526020819052604090205490915015610213576040517f23369fa600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80825260008181526020818152604091829020845181559084015160018201805493860151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00000000000000000000000000000000000000000090941673ffffffffffffffffffffffffffffffffffffffff9092169190911792909217909155606083015183919060028201906102af9082610881565b50506040513381528291507f7d917fcbc9a29a9705ff9936ffa599500e4fd902e4486bae317414fe967b307c9060200160405180910390a29695505050505050565b604080516080810182526000808252602082018190529181019190915260608082015260008281526020818152604091829020825160808101845281548152600182015473ffffffffffffffffffffffffffffffffffffffff8116938201939093527401000000000000000000000000000000000000000090920460ff16151592820192909252600282018054919291606084019190610390906107df565b80601f01602080910402602001604051908101604052809291908181526020018280546103bc906107df565b80156104095780601f106103de57610100808354040283529160200191610409565b820191906000526020600020905b8154815290600101906020018083116103ec57829003601f168201915b5050505050815250509050919050565b60608160000361045c57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156104865780610470816109ca565b915061047f9050600a83610a31565b9150610460565b60008167ffffffffffffffff8111156104a1576104a16107b0565b6040519080825280601f01601f1916602001820160405280156104cb576020820181803683370190505b5090505b841561054e576104e0600183610a45565b91506104ed600a86610a5e565b6104f8906030610a72565b60f81b81838151811061050d5761050d610a85565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610547600a86610a31565b94506104cf565b949350505050565b600081606001518260200151836040015160405160200161057993929190610ab4565b604051602081830303815290604052805190602001209050919050565b60005b838110156105b1578181015183820152602001610599565b50506000910152565b600081518084526105d2816020860160208601610596565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061061760208301846105ba565b9392505050565b6000806000806060858703121561063457600080fd5b843567ffffffffffffffff8082111561064c57600080fd5b818701915087601f83011261066057600080fd5b81358181111561066f57600080fd5b88602082850101111561068157600080fd5b6020928301965094505085013573ffffffffffffffffffffffffffffffffffffffff811681146106b057600080fd5b9150604085013580151581146106c557600080fd5b939692955090935050565b6000602082840312156106e257600080fd5b5035919050565b602081528151602082015273ffffffffffffffffffffffffffffffffffffffff60208301511660408201526040820151151560608201526000606083015160808084015261054e60a08401826105ba565b6000845161074c818460208901610596565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610788816001850160208a01610596565b600192019182015283516107a3816002840160208801610596565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600181811c908216806107f357607f821691505b60208210810361082c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561087c57600081815260208120601f850160051c810160208610156108595750805b601f850160051c820191505b8181101561087857828155600101610865565b5050505b505050565b815167ffffffffffffffff81111561089b5761089b6107b0565b6108af816108a984546107df565b84610832565b602080601f83116001811461090257600084156108cc5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610878565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561094f57888601518255948401946001909101908401610930565b508582101561098b57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036109fb576109fb61099b565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a4057610a40610a02565b500490565b81810381811115610a5857610a5861099b565b92915050565b600082610a6d57610a6d610a02565b500690565b80820180821115610a5857610a5861099b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008451610ac6818460208901610596565b60609490941b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190930190815290151560f81b60148201526015019291505056fea164736f6c6343000813000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "details": "Creates a new SchemaRegistry instance." - }, - "getSchema(bytes32)": { - "details": "Returns an existing schema by UID", - "params": { - "uid": "The UID of the schema to retrieve." - }, - "returns": { - "_0": "The schema data members." - } - }, - "register(string,address,bool)": { - "details": "Submits and reserves a new schema", - "params": { - "resolver": "An optional schema resolver.", - "revocable": "Whether the schema allows revocations explicitly.", - "schema": "The schema data schema." - }, - "returns": { - "_0": "The UID of the new schema." - } - }, - "version()": { - "returns": { - "_0": "Semver contract version as a string." - } - } - }, - "events": { - "Registered(bytes32,address)": { - "details": "Emitted when a new schema has been registered", - "params": { - "registerer": "The address of the account used to register the schema.", - "uid": "The schema UID." - } - } - }, - "title": "SchemaRegistry" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"type\":\"error\",\"name\":\"AlreadyExists\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"registerer\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Registered\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getSchema\",\"outputs\":[{\"internalType\":\"struct SchemaRecord\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"contract ISchemaResolver\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"schema\",\"type\":\"string\"}]}]},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"schema\",\"type\":\"string\"},{\"internalType\":\"contract ISchemaResolver\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"register\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Creates a new SchemaRegistry instance.\"},\"getSchema(bytes32)\":{\"details\":\"Returns an existing schema by UID\",\"params\":{\"uid\":\"The UID of the schema to retrieve.\"},\"returns\":{\"_0\":\"The schema data members.\"}},\"register(string,address,bool)\":{\"details\":\"Submits and reserves a new schema\",\"params\":{\"resolver\":\"An optional schema resolver.\",\"revocable\":\"Whether the schema allows revocations explicitly.\",\"schema\":\"The schema data schema.\"},\"returns\":{\"_0\":\"The UID of the new schema.\"}},\"version()\":{\"returns\":{\"_0\":\"Semver contract version as a string.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"version()\":{\"notice\":\"Returns the full semver contract version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=node_modules/clones-with-immutable-args/src/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@rari-capital/=node_modules/@rari-capital/\",\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\",\":clones-with-immutable-args/=node_modules/clones-with-immutable-args/\",\":ds-test/=node_modules/ds-test/src/\",\":forge-std/=node_modules/forge-std/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"contracts/EAS/SchemaRegistry.sol\":\"SchemaRegistry\"},\"libraries\":{}},\"sources\":{\"contracts/EAS/Common.sol\":{\"keccak256\":\"0x880e8262ee6682eeca6140e5a0b71f98e0c4024720c777da161e05a7715ed09a\",\"urls\":[\"bzz-raw://56ed7dc6b538070a66b851275a6a9721275da9e5e83631d94e93620cd679c3f6\",\"dweb:/ipfs/QmVjKgNr3jbnYerjDyFGLky8wXCUR8SuzxrsypBVVSW3tk\"],\"license\":\"MIT\"},\"contracts/EAS/ISchemaRegistry.sol\":{\"keccak256\":\"0x4e988bea43a70e8ed156c7ee74dd3667872a68f65fa10dc4f07ddd4d89b929f1\",\"urls\":[\"bzz-raw://046977484b8089aad16f2064099b3f7604bcbddd61334e046838c3c448b5ebb5\",\"dweb:/ipfs/QmXdorYunKEbiosCGL4teYCd1W2njCqujvMWQjYonAxU6w\"],\"license\":\"MIT\"},\"contracts/EAS/SchemaRegistry.sol\":{\"keccak256\":\"0x41f61bef4ebc0c20d0ed6bbab7623f26e0ff13f68e969211a8882a9610f935b6\",\"urls\":[\"bzz-raw://cccadbdd3bf6546ed9d7280119b6d0c7d4de6f92de9469cbab62c01d59b84c8b\",\"dweb:/ipfs/Qmf7vycRfckwYCUYN7e6bce4QuMj35hjR1AqqtoYm4gNxu\"],\"license\":\"MIT\"},\"contracts/EAS/resolver/ISchemaResolver.sol\":{\"keccak256\":\"0xe537341e3d8d9c8e0eada21b4278beef510781fb1745892312c286a3c8287c2d\",\"urls\":[\"bzz-raw://5ab80b1fd7b6ad0ca94ff14358c5ba942614e25632d8a07c8e364d3f45c08453\",\"dweb:/ipfs/QmY6WToUtVo1HpDq7z7Tb17othZnJwpz4m26GuzKAsGTeM\"],\"license\":\"MIT\"},\"contracts/universal/Semver.sol\":{\"keccak256\":\"0xc455c84bb1f17e994dea0451fd363f81f83965bfa86e81ac6c8b3a327b9a0ff0\",\"urls\":[\"bzz-raw://fab499f3c0d7df8eb763b50621848d5d2147fb9c42a8eb9b65a11093090bb482\",\"dweb:/ipfs/QmUKsG4ztwtUZFjuRYAxgUFTgH5YxWSGF1BFFaB7vdM2K3\"],\"license\":\"MIT\"},\"node_modules/@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 1, - "receipt": { - "transactionHash": "0xef2a1eb6082e0ce53a239b80272f9ac5e0734901f0e2b7dc851d6f4d3ab04e8e", - "transactionIndex": "0x1", - "blockHash": "0x3d832e9dc651b4667640a6a685b55f4548663e0e936adf45c2336dc44f029b68", - "blockNumber": "0x6645730", - "from": "0x9bbFB9919062C29a5eE15aCD93c9D7c3b14d31aa", - "to": null, - "cumulativeGasUsed": "0xadf9a", - "gasUsed": "0xa1a55", - "contractAddress": "0x6232208d66bAc2305b46b4Cb6BCB3857B298DF13", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb2d05e40" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 27112, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "_registry", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_bytes32,t_struct(SchemaRecord)27057_storage)" - }, - { - "astId": 27118, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)49_storage" - } - ], - "types": { - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_contract(ISchemaResolver)27536": { - "encoding": "inplace", - "label": "contract ISchemaResolver", - "numberOfBytes": "20" - }, - "t_mapping(t_bytes32,t_struct(SchemaRecord)27057_storage)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => struct SchemaRecord)", - "numberOfBytes": "32", - "value": "t_struct(SchemaRecord)27057_storage" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(SchemaRecord)27057_storage": { - "encoding": "inplace", - "label": "struct SchemaRecord", - "numberOfBytes": "96", - "members": [ - { - "astId": 27049, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "uid", - "offset": 0, - "slot": "0", - "type": "t_bytes32" - }, - { - "astId": 27052, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "resolver", - "offset": 0, - "slot": "1", - "type": "t_contract(ISchemaResolver)27536" - }, - { - "astId": 27054, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "revocable", - "offset": 20, - "slot": "1", - "type": "t_bool" - }, - { - "astId": 27056, - "contract": "contracts/EAS/SchemaRegistry.sol:SchemaRegistry", - "label": "schema", - "offset": 0, - "slot": "2", - "type": "t_string_storage" - } - ] - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - } - } - }, - "transactionHash": "0xef2a1eb6082e0ce53a239b80272f9ac5e0734901f0e2b7dc851d6f4d3ab04e8e", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "version()": { - "notice": "Returns the full semver contract version." - } - }, - "notice": "The global attestation schemas for the Ethereum Attestation Service protocol." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-mainnet/solcInputs/b1df373a9ed51b3903b61f56faa9a78f.json b/packages/contracts-bedrock/deployments/optimism-mainnet/solcInputs/b1df373a9ed51b3903b61f56faa9a78f.json deleted file mode 100644 index b0bf9b8a4dfb..000000000000 --- a/packages/contracts-bedrock/deployments/optimism-mainnet/solcInputs/b1df373a9ed51b3903b61f56faa9a78f.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/GovernanceToken.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev The Optimism token used in governance and supporting voting and delegation.\n * Implements EIP 2612 allowing signed approvals.\n * Contract is \"owned\" by a `MintManager` instance with permission to the `mint` function only,\n * for the purposes of enforcing the token inflation schedule.\n */\ncontract GovernanceToken is ERC20Burnable, ERC20Votes, Ownable {\n /**\n * @dev Constructor.\n */\n constructor() ERC20(\"Optimism\", \"OP\") ERC20Permit(\"Optimism\") {}\n\n function mint(address _account, uint256 _amount) public onlyOwner {\n _mint(_account, _amount);\n }\n\n // The following functions are overrides required by Solidity.\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20, ERC20Votes) {\n super._afterTokenTransfer(from, to, amount);\n }\n\n function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._mint(to, amount);\n }\n\n function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) {\n super._burn(account, amount);\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, _allowances[owner][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = _allowances[owner][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Spend `amount` form the allowance of `owner` toward `spender`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20Permit.sol\";\nimport \"../../../utils/math/Math.sol\";\nimport \"../../../governance/utils/IVotes.sol\";\nimport \"../../../utils/math/SafeCast.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20Votes is IVotes, ERC20Permit {\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCast.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = Math.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSA.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n}\n" - }, - "@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private immutable _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" - }, - "@openzeppelin/contracts/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" - }, - "@openzeppelin/contracts/governance/utils/IVotes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "@openzeppelin/contracts/utils/math/SafeCast.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" - }, - "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" - }, - "@openzeppelin/contracts/utils/Counters.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" - }, - "@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n" - }, - "contracts/MintManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./GovernanceToken.sol\";\n\n/**\n * @title MintManager\n * @notice Set as `owner` of the OP token and responsible for the token inflation schedule.\n * Contract acts as the token \"mint manager\" with permission to the `mint` function only.\n * Currently permitted to mint once per year of up to 2% of the total token supply.\n * Upgradable to allow changes in the inflation schedule.\n */\ncontract MintManager is Ownable {\n /**\n * @notice The GovernanceToken that the MintManager can mint tokens\n */\n GovernanceToken public immutable governanceToken;\n\n /**\n * @notice The amount of tokens that can be minted per year. The value is a fixed\n * point number with 4 decimals.\n */\n uint256 public constant MINT_CAP = 20; // 2%\n\n /**\n * @notice The number of decimals for the MINT_CAP.\n */\n uint256 public constant DENOMINATOR = 1000;\n\n /**\n * @notice The amount of time that must pass before the MINT_CAP number of tokens can\n * be minted again.\n */\n uint256 public constant MINT_PERIOD = 365 days;\n\n /**\n * @notice Tracks the time of last mint\n */\n uint256 public mintPermittedAfter;\n\n /**\n * @param _upgrader The owner of this contract\n * @param _governanceToken The governance token this contract can mint\n * tokens of\n */\n constructor(address _upgrader, address _governanceToken) {\n transferOwnership(_upgrader);\n governanceToken = GovernanceToken(_governanceToken);\n }\n\n /**\n * @notice Only the token owner is allowed to mint a certain amount of OP per year.\n *\n * @param _account Address to mint new tokens to.\n * @param _amount Amount of tokens to be minted.\n */\n function mint(address _account, uint256 _amount) public onlyOwner {\n if (mintPermittedAfter > 0) {\n require(mintPermittedAfter <= block.timestamp, \"OP: minting not permitted yet\");\n\n require(\n _amount <= (governanceToken.totalSupply() * MINT_CAP) / DENOMINATOR,\n \"OP: mint amount exceeds cap\"\n );\n }\n\n mintPermittedAfter = block.timestamp + MINT_PERIOD;\n\n governanceToken.mint(_account, _amount);\n }\n\n /**\n * @notice Upgrade the owner of the governance token to a new MintManager.\n *\n * @param _newMintManager The MintManager to upgrade to\n */\n function upgrade(address _newMintManager) public onlyOwner {\n require(_newMintManager != address(0), \"OP: Mint manager cannot be empty\");\n\n governanceToken.transferOwnership(_newMintManager);\n }\n}\n" - }, - "contracts/test/TestERC20.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity =0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestERC20 is ERC20 {\n constructor(\n string memory name_,\n string memory symbol_,\n uint256 amountToMint\n ) ERC20(name_, symbol_) {\n setBalance(msg.sender, amountToMint);\n }\n\n // sets the balance of the address\n // this mints/burns the amount depending on the current balance\n function setBalance(address to, uint256 amount) public {\n uint256 old = balanceOf(to);\n if (old < amount) {\n _mint(to, amount - old);\n } else if (old > amount) {\n _burn(to, old - amount);\n }\n }\n}\n" - }, - "contracts/MerkleDistributor.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity =0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\";\nimport \"./interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n uint256 public constant ONE_YEAR_IN_SECONDS = 31_536_000;\n uint256 public immutable activationTimestamp;\n address public immutable airdropTreasury;\n bool public isActive;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n event Finalised(address indexed calledBy, uint256 timestamp, uint256 unclaimedAmount);\n\n constructor(\n address token_,\n bytes32 merkleRoot_,\n address _treasury\n ) {\n token = token_;\n merkleRoot = merkleRoot_;\n\n activationTimestamp = block.timestamp;\n isActive = true;\n airdropTreasury = _treasury;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(\n uint256 index,\n address account,\n uint256 amount,\n bytes32[] calldata merkleProof\n ) external override {\n require(!isClaimed(index), \"MerkleDistributor: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(\n MerkleProof.verify(merkleProof, merkleRoot, node),\n \"MerkleDistributor: Invalid proof.\"\n );\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n /**\n * @dev Finalises the airdrop and sweeps unclaimed tokens into the Optimism multisig\n */\n function clawBack() external {\n // Airdrop can only be finalised once\n require(isActive, \"Airdrop: Already finalised\");\n // Airdrop will remain open for one year\n require(\n block.timestamp >= activationTimestamp + ONE_YEAR_IN_SECONDS,\n \"Airdrop: Drop should remain open for one year\"\n );\n // Deactivate airdrop\n isActive = false;\n\n // Sweep unclaimed tokens\n uint256 amount = IERC20(token).balanceOf(address(this));\n require(\n IERC20(token).transfer(airdropTreasury, amount),\n \"Airdrop: Finalise transfer failed\"\n );\n\n emit Finalised(msg.sender, block.timestamp, amount);\n }\n}\n" - }, - "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/MerkleProof.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev These functions deal with verification of Merkle Trees proofs.\n *\n * The proofs can be generated using the JavaScript library\n * https://github.com/miguelmota/merkletreejs[merkletreejs].\n * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.\n *\n * See `test/utils/cryptography/MerkleProof.test.js` for some examples.\n */\nlibrary MerkleProof {\n /**\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n * defined by `root`. For this, a `proof` must be provided, containing\n * sibling hashes on the branch from the leaf to the root of the tree. Each\n * pair of leaves and each pair of pre-images are assumed to be sorted.\n */\n function verify(\n bytes32[] memory proof,\n bytes32 root,\n bytes32 leaf\n ) internal pure returns (bool) {\n return processProof(proof, leaf) == root;\n }\n\n /**\n * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up\n * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n * hash matches the root of the tree. When processing the proof, the pairs\n * of leafs & pre-images are assumed to be sorted.\n *\n * _Available since v4.4._\n */\n function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\n bytes32 computedHash = leaf;\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n if (computedHash <= proofElement) {\n // Hash(current computed hash + current element of the proof)\n computedHash = _efficientHash(computedHash, proofElement);\n } else {\n // Hash(current element of the proof + current computed hash)\n computedHash = _efficientHash(proofElement, computedHash);\n }\n }\n return computedHash;\n }\n\n function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\n assembly {\n mstore(0x00, a)\n mstore(0x20, b)\n value := keccak256(0x00, 0x40)\n }\n }\n}\n" - }, - "contracts/interfaces/IMerkleDistributor.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.12;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(\n uint256 index,\n address account,\n uint256 amount,\n bytes32[] calldata merkleProof\n ) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}\n" - } - }, - "settings": { - "outputSelection": { - "*": { - "*": [ - "metadata", - "storageLayout", - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "devdoc", - "userdoc", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "optimizer": { - "enabled": false, - "runs": 200 - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/.chainId b/packages/contracts-bedrock/deployments/sepolia/.chainId deleted file mode 100644 index bd8d1cd44c96..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/.chainId +++ /dev/null @@ -1 +0,0 @@ -11155111 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/AddressManager.json b/packages/contracts-bedrock/deployments/sepolia/AddressManager.json deleted file mode 100644 index 0204a3620d88..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/AddressManager.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "oldAddress", - "type": "address" - } - ], - "name": "AddressSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "getAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "address", - "name": "_address", - "type": "address" - } - ], - "name": "setAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "address": "0x9bFE9c5609311DF1c011c47642253B78a4f33F4B", - "args": [], - "bytecode": "0x608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6105ef8061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046104fa565b610106565b6100906100da366004610548565b6101d9565b6100746100ed366004610585565b610215565b6100fa6102d1565b6101046000610352565b565b61010e6102d1565b6000610119836103c7565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff00000000000000000000000000000000000000008316179092559151929350169061017c9085906105a7565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006101e8846103c7565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b61021d6102d1565b73ffffffffffffffffffffffffffffffffffffffff81166102c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ce81610352565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bc565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016103da91906105a7565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261043757600080fd5b813567ffffffffffffffff80821115610452576104526103f7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610498576104986103f7565b816040528381528660208588010111156104b157600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b919050565b6000806040838503121561050d57600080fd5b823567ffffffffffffffff81111561052457600080fd5b61053085828601610426565b92505061053f602084016104d1565b90509250929050565b60006020828403121561055a57600080fd5b813567ffffffffffffffff81111561057157600080fd5b61057d84828501610426565b949350505050565b60006020828403121561059757600080fd5b6105a0826104d1565b9392505050565b6000825160005b818110156105c857602081860181015185830152016105ae565b818111156105d7576000828501525b50919091019291505056fea164736f6c634300080f000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046104fa565b610106565b6100906100da366004610548565b6101d9565b6100746100ed366004610585565b610215565b6100fa6102d1565b6101046000610352565b565b61010e6102d1565b6000610119836103c7565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff00000000000000000000000000000000000000008316179092559151929350169061017c9085906105a7565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006101e8846103c7565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b61021d6102d1565b73ffffffffffffffffffffffffffffffffffffffff81166102c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ce81610352565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bc565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016103da91906105a7565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261043757600080fd5b813567ffffffffffffffff80821115610452576104526103f7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610498576104986103f7565b816040528381528660208588010111156104b157600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b919050565b6000806040838503121561050d57600080fd5b823567ffffffffffffffff81111561052457600080fd5b61053085828601610426565b92505061053f602084016104d1565b90509250929050565b60006020828403121561055a57600080fd5b813567ffffffffffffffff81111561057157600080fd5b61057d84828501610426565b949350505050565b60006020828403121561059757600080fd5b6105a0826104d1565b9392505050565b6000825160005b818110156105c857602081860181015185830152016105ae565b818111156105d7576000828501525b50919091019291505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "getAddress(string)": { - "params": { - "_name": "Name to retrieve an address for." - }, - "returns": { - "_0": "Address associated with the given name." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "setAddress(string,address)": { - "params": { - "_address": "Address to associate with the name.", - "_name": "String name to associate an address with." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - } - }, - "events": { - "AddressSet(string,address,address)": { - "params": { - "name": "String name being set in the registry.", - "newAddress": "Address set for the given name.", - "oldAddress": "Address that was previously set for the given name." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"newAddress\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"address\",\"name\":\"oldAddress\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"AddressSet\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"renounceOwnership\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setAddress\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferOwnership\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getAddress(string)\":{\"params\":{\"_name\":\"Name to retrieve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setAddress(string,address)\":{\"params\":{\"_address\":\"Address to associate with the name.\",\"_name\":\"String name to associate an address with.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getAddress(string)\":{\"notice\":\"Retrieves the address associated with a given name.\"},\"setAddress(string,address)\":{\"notice\":\"Changes the address associated with a particular name.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/legacy/AddressManager.sol\":\"AddressManager\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"urls\":[\"bzz-raw://40fb1b5102468f783961d0af743f91b9980cf66b50d1d12009f6bb1869cea4d2\",\"dweb:/ipfs/QmYqEbJML4jB1GHbzD4cUZDtJg5wVwNm3vDJq1GbyDus8y\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"],\"license\":\"MIT\"},\"src/legacy/AddressManager.sol\":{\"keccak256\":\"0x1fcb990df6473f7fa360d5924d62d39ce2ca97d45668e3901e5405cfbe598b19\",\"urls\":[\"bzz-raw://9d08358b60dea54dbc32e988a1bb7ea909488063eaae3c5ae28a322f125c9b34\",\"dweb:/ipfs/QmZPQwdjLh9gaamNAoTUmWwwbRKj3yHovBYfnTPnfuKvUt\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": { - "transactionHash": "0xe6d395de5325c383fda316d820c8086e2fba23f26d3ae72a20778a7ca0edccdb", - "transactionIndex": "0x2", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0x223cf5", - "gasUsed": "0x62d28", - "contractAddress": "0x9bFE9c5609311DF1c011c47642253B78a4f33F4B", - "logs": [ - { - "address": "0x9bFE9c5609311DF1c011c47642253B78a4f33F4B", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000018394b52d3cb931dfa76f63251919d051953413d" - ], - "data": "0x", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "transactionHash": "0xe6d395de5325c383fda316d820c8086e2fba23f26d3ae72a20778a7ca0edccdb", - "transactionIndex": "0x2", - "logIndex": "0x2", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000200000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000001000000000004000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000040000000000000000008000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xbec78df7" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 31896, - "contract": "src/legacy/AddressManager.sol:AddressManager", - "label": "_owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 62378, - "contract": "src/legacy/AddressManager.sol:AddressManager", - "label": "addresses", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_bytes32,t_address)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes32,t_address)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => address)", - "numberOfBytes": "32", - "value": "t_address" - } - } - }, - "transactionHash": "0xe6d395de5325c383fda316d820c8086e2fba23f26d3ae72a20778a7ca0edccdb", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "getAddress(string)": { - "notice": "Retrieves the address associated with a given name." - }, - "setAddress(string,address)": { - "notice": "Changes the address associated with a particular name." - } - }, - "events": { - "AddressSet(string,address,address)": { - "notice": "Emitted when an address is modified in the registry." - } - }, - "notice": "AddressManager is a legacy contract that was used in the old version of the Optimism system to manage a registry of string names to addresses. We now use a more standard proxy system instead, but this contract is still necessary for backwards compatibility with several older contracts." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/L1CrossDomainMessenger.json b/packages/contracts-bedrock/deployments/sepolia/L1CrossDomainMessenger.json deleted file mode 100644 index 7dab1a754d85..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/L1CrossDomainMessenger.json +++ /dev/null @@ -1,801 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "msgHash", - "type": "bytes32" - } - ], - "name": "FailedRelayedMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "msgHash", - "type": "bytes32" - } - ], - "name": "RelayedMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "message", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "messageNonce", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - } - ], - "name": "SentMessage", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "SentMessageExtension1", - "type": "event" - }, - { - "inputs": [], - "name": "MESSAGE_VERSION", - "outputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_CALLDATA_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_MESSENGER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PORTAL", - "outputs": [ - { - "internalType": "contract OptimismPortal", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_CALL_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_CONSTANT_OVERHEAD", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_GAS_CHECK_BUFFER", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RELAY_RESERVED_GAS", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - } - ], - "name": "baseGas", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "failedMessages", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract OptimismPortal", - "name": "_portal", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "messageNonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "portal", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "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": "_minGasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - } - ], - "name": "relayMessage", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_message", - "type": "bytes" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - } - ], - "name": "sendMessage", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "successfulMessages", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "xDomainMessageSender", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0xDa2332D0a7608919Cd331B1304Cd179129a90495", - "args": [], - "bytecode": "0x60a06040523480156200001157600080fd5b507342000000000000000000000000000000000000076080526200003660006200003c565b620001ea565b600054600390600160a81b900460ff1615801562000068575060005460ff808316600160a01b90920416105b620000d15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b60008054600160a81b61ffff60a01b19909116600160a01b60ff85160260ff60a81b19161717905560f980546001600160a01b0319166001600160a01b0384161790556200011e62000165565b6000805460ff60a81b1916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054600160a81b900460ff16620001d45760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000c8565b60cc80546001600160a01b03191661dead179055565b608051611cee620002146000396000818161033b0152818161048a01526114ef0152611cee6000f3fe60806040526004361061015f5760003560e01c80636e296e45116100c0578063b1b1b20911610074578063c4d66de811610059578063c4d66de8146103ed578063d764ad0b1461040d578063ecc704281461042057600080fd5b8063b1b1b2091461039d578063b28ade25146103cd57600080fd5b80638cbeeef2116100a55780638cbeeef2146102505780639fce812c14610329578063a4e7f8bd1461035d57600080fd5b80636e296e45146102fd57806383a740741461031257600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146102665780635644cfdf146102bc5780636425666b146102d257600080fd5b80633f827a5a146102285780634c1d6a691461025057600080fd5b80630ff754ea116101485780630ff754ea146101ac5780632828d7e8146101fe5780633dbb202b1461021357600080fd5b8063028f85f7146101645780630c56849814610197575b600080fd5b34801561017057600080fd5b50610179601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101a357600080fd5b50610179603f81565b3480156101b857600080fd5b5060f9546101d99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018e565b34801561020a57600080fd5b50610179604081565b6102266102213660046117ba565b610485565b005b34801561023457600080fd5b5061023d600181565b60405161ffff909116815260200161018e565b34801561025c57600080fd5b50610179619c4081565b34801561027257600080fd5b506102af6040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b60405161018e919061188c565b3480156102c857600080fd5b5061017961138881565b3480156102de57600080fd5b5060f95473ffffffffffffffffffffffffffffffffffffffff166101d9565b34801561030957600080fd5b506101d96106e9565b34801561031e57600080fd5b5061017962030d4081565b34801561033557600080fd5b506101d97f000000000000000000000000000000000000000000000000000000000000000081565b34801561036957600080fd5b5061038d6103783660046118a6565b60ce6020526000908152604090205460ff1681565b604051901515815260200161018e565b3480156103a957600080fd5b5061038d6103b83660046118a6565b60cb6020526000908152604090205460ff1681565b3480156103d957600080fd5b506101796103e83660046118bf565b6107d5565b3480156103f957600080fd5b50610226610408366004611913565b610843565b61022661041b366004611930565b610a47565b34801561042c57600080fd5b5061047760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b60405190815260200161018e565b6105be7f00000000000000000000000000000000000000000000000000000000000000006104b48585856107d5565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061052060cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c60405160240161053c97969594939291906119ff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526112d3565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561064360cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b86604051610655959493929190611a5e565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6107f1604063ffffffff8816611adb565b6107fb9190611b0b565b610806601088611adb565b6108139062030d40611b59565b61081d9190611b59565b6108279190611b59565b6108319190611b59565b61083b9190611b59565b949350505050565b6000546003907501000000000000000000000000000000000000000000900460ff16158015610891575060005460ff8083167401000000000000000000000000000000000000000090920416105b61091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107af565b6000805475010000000000000000000000000000000000000000007fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000060ff8516027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff161717905560f980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556109e561136c565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60f087901c60028110610b02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107af565b8061ffff16600003610bf7576000610b53878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250611445915050565b600081815260cb602052604090205490915060ff1615610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107af565b505b6000610c3d898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146492505050565b9050610c47611487565b15610c7f57853414610c5b57610c5b611b85565b600081815260ce602052604090205460ff1615610c7a57610c7a611b85565b610dd1565b3415610d33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107af565b600081815260ce602052604090205460ff16610dd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107af565b610dda8761157d565b15610e8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107af565b600081815260cb602052604090205460ff1615610f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107af565b610f4d85610f3e611388619c40611b59565b67ffffffffffffffff166115c3565b1580610f73575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561108c57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b50506112c5565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061111d88619c405a6110e09190611bb4565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115e192505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111b457600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112c1565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b5050505b50505050505050565b905090565b60f9546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611334908890839089906000908990600401611bcb565b6000604051808303818588803b15801561134d57600080fd5b505af1158015611361573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107af565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611453858585856115fb565b805190602001209050949350505050565b6000611474878787878787611694565b8051906020012090509695505050505050565b60f95460009073ffffffffffffffffffffffffffffffffffffffff16331480156112ce575060f954604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691639bf62d829160048083019260209291908290030181865afa15801561153d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115619190611c23565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff82163014806115bd575060f95473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116149493929190611c40565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60608686868686866040516024016116b196959493929190611c8a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461175557600080fd5b50565b60008083601f84011261176a57600080fd5b50813567ffffffffffffffff81111561178257600080fd5b60208301915083602082850101111561179a57600080fd5b9250929050565b803563ffffffff811681146117b557600080fd5b919050565b600080600080606085870312156117d057600080fd5b84356117db81611733565b9350602085013567ffffffffffffffff8111156117f757600080fd5b61180387828801611758565b90945092506118169050604086016117a1565b905092959194509250565b6000815180845260005b818110156118475760208185018101518683018201520161182b565b81811115611859576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061189f6020830184611821565b9392505050565b6000602082840312156118b857600080fd5b5035919050565b6000806000604084860312156118d457600080fd5b833567ffffffffffffffff8111156118eb57600080fd5b6118f786828701611758565b909450925061190a9050602085016117a1565b90509250925092565b60006020828403121561192557600080fd5b813561189f81611733565b600080600080600080600060c0888a03121561194b57600080fd5b87359650602088013561195d81611733565b9550604088013561196d81611733565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561199757600080fd5b6119a38a828b01611758565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611a5160c0830184866119b6565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611a8e6080830186886119b6565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611b0257611b02611aac565b02949350505050565b600067ffffffffffffffff80841680611b4d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b7c57611b7c611aac565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611bc657611bc6611aac565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611c1860a0830184611821565b979650505050505050565b600060208284031215611c3557600080fd5b815161189f81611733565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611c796080830185611821565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611cd560c0830184611821565b9897505050505050505056fea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061015f5760003560e01c80636e296e45116100c0578063b1b1b20911610074578063c4d66de811610059578063c4d66de8146103ed578063d764ad0b1461040d578063ecc704281461042057600080fd5b8063b1b1b2091461039d578063b28ade25146103cd57600080fd5b80638cbeeef2116100a55780638cbeeef2146102505780639fce812c14610329578063a4e7f8bd1461035d57600080fd5b80636e296e45146102fd57806383a740741461031257600080fd5b80633f827a5a1161011757806354fd4d50116100fc57806354fd4d50146102665780635644cfdf146102bc5780636425666b146102d257600080fd5b80633f827a5a146102285780634c1d6a691461025057600080fd5b80630ff754ea116101485780630ff754ea146101ac5780632828d7e8146101fe5780633dbb202b1461021357600080fd5b8063028f85f7146101645780630c56849814610197575b600080fd5b34801561017057600080fd5b50610179601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101a357600080fd5b50610179603f81565b3480156101b857600080fd5b5060f9546101d99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018e565b34801561020a57600080fd5b50610179604081565b6102266102213660046117ba565b610485565b005b34801561023457600080fd5b5061023d600181565b60405161ffff909116815260200161018e565b34801561025c57600080fd5b50610179619c4081565b34801561027257600080fd5b506102af6040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b60405161018e919061188c565b3480156102c857600080fd5b5061017961138881565b3480156102de57600080fd5b5060f95473ffffffffffffffffffffffffffffffffffffffff166101d9565b34801561030957600080fd5b506101d96106e9565b34801561031e57600080fd5b5061017962030d4081565b34801561033557600080fd5b506101d97f000000000000000000000000000000000000000000000000000000000000000081565b34801561036957600080fd5b5061038d6103783660046118a6565b60ce6020526000908152604090205460ff1681565b604051901515815260200161018e565b3480156103a957600080fd5b5061038d6103b83660046118a6565b60cb6020526000908152604090205460ff1681565b3480156103d957600080fd5b506101796103e83660046118bf565b6107d5565b3480156103f957600080fd5b50610226610408366004611913565b610843565b61022661041b366004611930565b610a47565b34801561042c57600080fd5b5061047760cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b60405190815260200161018e565b6105be7f00000000000000000000000000000000000000000000000000000000000000006104b48585856107d5565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061052060cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c60405160240161053c97969594939291906119ff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526112d3565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a33858561064360cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b86604051610655959493929190611a5e565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2153016107b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f7420736574000000000000000000000060648201526084015b60405180910390fd5b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f6107f1604063ffffffff8816611adb565b6107fb9190611b0b565b610806601088611adb565b6108139062030d40611b59565b61081d9190611b59565b6108279190611b59565b6108319190611b59565b61083b9190611b59565b949350505050565b6000546003907501000000000000000000000000000000000000000000900460ff16158015610891575060005460ff8083167401000000000000000000000000000000000000000090920416105b61091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016107af565b6000805475010000000000000000000000000000000000000000007fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000060ff8516027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff161717905560f980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556109e561136c565b600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60f087901c60028110610b02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a4016107af565b8061ffff16600003610bf7576000610b53878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250611445915050565b600081815260cb602052604090205490915060ff1615610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c6179656400000000000000000060648201526084016107af565b505b6000610c3d898989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061146492505050565b9050610c47611487565b15610c7f57853414610c5b57610c5b611b85565b600081815260ce602052604090205460ff1615610c7a57610c7a611b85565b610dd1565b3415610d33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a4016107af565b600081815260ce602052604090205460ff16610dd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c617965640000000000000000000000000000000060648201526084016107af565b610dda8761157d565b15610e8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a4016107af565b600081815260cb602052604090205460ff1615610f2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c617965640000000000000000000060648201526084016107af565b610f4d85610f3e611388619c40611b59565b67ffffffffffffffff166115c3565b1580610f73575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561108c57600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3201611085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b50506112c5565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061111d88619c405a6110e09190611bb4565b8988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115e192505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156111b457600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26112c1565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016112c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d6573736167650000000000000000000000000000000000000060648201526084016107af565b5050505b50505050505050565b905090565b60f9546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611334908890839089906000908990600401611bcb565b6000604051808303818588803b15801561134d57600080fd5b505af1158015611361573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016107af565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055565b6000611453858585856115fb565b805190602001209050949350505050565b6000611474878787878787611694565b8051906020012090509695505050505050565b60f95460009073ffffffffffffffffffffffffffffffffffffffff16331480156112ce575060f954604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691639bf62d829160048083019260209291908290030181865afa15801561153d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115619190611c23565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff82163014806115bd575060f95473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b6060848484846040516024016116149493929190611c40565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60608686868686866040516024016116b196959493929190611c8a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461175557600080fd5b50565b60008083601f84011261176a57600080fd5b50813567ffffffffffffffff81111561178257600080fd5b60208301915083602082850101111561179a57600080fd5b9250929050565b803563ffffffff811681146117b557600080fd5b919050565b600080600080606085870312156117d057600080fd5b84356117db81611733565b9350602085013567ffffffffffffffff8111156117f757600080fd5b61180387828801611758565b90945092506118169050604086016117a1565b905092959194509250565b6000815180845260005b818110156118475760208185018101518683018201520161182b565b81811115611859576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061189f6020830184611821565b9392505050565b6000602082840312156118b857600080fd5b5035919050565b6000806000604084860312156118d457600080fd5b833567ffffffffffffffff8111156118eb57600080fd5b6118f786828701611758565b909450925061190a9050602085016117a1565b90509250925092565b60006020828403121561192557600080fd5b813561189f81611733565b600080600080600080600060c0888a03121561194b57600080fd5b87359650602088013561195d81611733565b9550604088013561196d81611733565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561199757600080fd5b6119a38a828b01611758565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611a5160c0830184866119b6565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611a8e6080830186886119b6565b905083604083015263ffffffff831660608301529695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611b0257611b02611aac565b02949350505050565b600067ffffffffffffffff80841680611b4d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611b7c57611b7c611aac565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611bc657611bc6611aac565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611c1860a0830184611821565b979650505050505050565b600060208284031215611c3557600080fd5b815161189f81611733565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611c796080830185611821565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611cd560c0830184611821565b9897505050505050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "baseGas(bytes,uint32)": { - "params": { - "_message": "Message to compute the amount of required gas for.", - "_minGasLimit": "Minimum desired gas limit when message goes to target." - }, - "returns": { - "_0": "Amount of gas required to guarantee message receipt." - } - }, - "initialize(address)": { - "params": { - "_portal": "Address of the OptimismPortal contract on this network." - } - }, - "messageNonce()": { - "returns": { - "_0": "Nonce of the next message to be sent, with added message version." - } - }, - "relayMessage(uint256,address,address,uint256,uint256,bytes)": { - "params": { - "_message": "Message to send to the target.", - "_minGasLimit": "Minimum amount of gas that the message can be executed with.", - "_nonce": "Nonce of the message being relayed.", - "_sender": "Address of the user who sent the message.", - "_target": "Address that the message is targeted at.", - "_value": "ETH value to send with the message." - } - }, - "sendMessage(address,bytes,uint32)": { - "params": { - "_message": "Message to trigger the target address with.", - "_minGasLimit": "Minimum gas limit that the message can be executed with.", - "_target": "Target contract or wallet address." - } - }, - "xDomainMessageSender()": { - "returns": { - "_0": "Address of the sender of the currently executing message on the other chain." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true}],\"type\":\"event\",\"name\":\"FailedRelayedMessage\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true}],\"type\":\"event\",\"name\":\"RelayedMessage\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\",\"indexed\":false}],\"type\":\"event\",\"name\":\"SentMessage\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false}],\"type\":\"event\",\"name\":\"SentMessageExtension1\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MESSAGE_VERSION\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MIN_GAS_CALLDATA_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OTHER_MESSENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"PORTAL\",\"outputs\":[{\"internalType\":\"contract OptimismPortal\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_CALL_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_CONSTANT_OVERHEAD\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_GAS_CHECK_BUFFER\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RELAY_RESERVED_GAS\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"baseGas\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"failedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"contract OptimismPortal\",\"name\":\"_portal\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"portal\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"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\":\"_minGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"relayMessage\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"sendMessage\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"baseGas(bytes,uint32)\":{\"params\":{\"_message\":\"Message to compute the amount of required gas for.\",\"_minGasLimit\":\"Minimum desired gas limit when message goes to target.\"},\"returns\":{\"_0\":\"Amount of gas required to guarantee message receipt.\"}},\"initialize(address)\":{\"params\":{\"_portal\":\"Address of the OptimismPortal contract on this network.\"}},\"messageNonce()\":{\"returns\":{\"_0\":\"Nonce of the next message to be sent, with added message version.\"}},\"relayMessage(uint256,address,address,uint256,uint256,bytes)\":{\"params\":{\"_message\":\"Message to send to the target.\",\"_minGasLimit\":\"Minimum amount of gas that the message can be executed with.\",\"_nonce\":\"Nonce of the message being relayed.\",\"_sender\":\"Address of the user who sent the message.\",\"_target\":\"Address that the message is targeted at.\",\"_value\":\"ETH value to send with the message.\"}},\"sendMessage(address,bytes,uint32)\":{\"params\":{\"_message\":\"Message to trigger the target address with.\",\"_minGasLimit\":\"Minimum gas limit that the message can be executed with.\",\"_target\":\"Target contract or wallet address.\"}},\"xDomainMessageSender()\":{\"returns\":{\"_0\":\"Address of the sender of the currently executing message on the other chain.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"MESSAGE_VERSION()\":{\"notice\":\"Current message version identifier.\"},\"MIN_GAS_CALLDATA_OVERHEAD()\":{\"notice\":\"Extra gas added to base gas for each byte of calldata in a message.\"},\"MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()\":{\"notice\":\"Denominator for dynamic overhead added to the base gas for a message.\"},\"MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR()\":{\"notice\":\"Numerator for dynamic overhead added to the base gas for a message.\"},\"OTHER_MESSENGER()\":{\"notice\":\"Address of the paired CrossDomainMessenger contract on the other chain.\"},\"PORTAL()\":{\"notice\":\"Address of the OptimismPortal. The public getter for this is legacy and will be removed in the future. Use `portal()` instead.\"},\"RELAY_CALL_OVERHEAD()\":{\"notice\":\"Gas reserved for performing the external call in `relayMessage`.\"},\"RELAY_CONSTANT_OVERHEAD()\":{\"notice\":\"Constant overhead added to the base gas for a message.\"},\"RELAY_GAS_CHECK_BUFFER()\":{\"notice\":\"Gas reserved for the execution between the `hasMinGas` check and the external call in `relayMessage`.\"},\"RELAY_RESERVED_GAS()\":{\"notice\":\"Gas reserved for finalizing the execution of `relayMessage` after the safe call.\"},\"baseGas(bytes,uint32)\":{\"notice\":\"Computes the amount of gas required to guarantee that a given message will be received on the other chain without running out of gas. Guaranteeing that a message will not run out of gas is important because this ensures that a message can always be replayed on the other chain if it fails to execute completely.\"},\"constructor\":{\"notice\":\"Constructs the L1CrossDomainMessenger contract.\"},\"failedMessages(bytes32)\":{\"notice\":\"Mapping of message hashes to a boolean if and only if the message has failed to be executed at least once. A message will not be present in this mapping if it successfully executed on the first attempt.\"},\"initialize(address)\":{\"notice\":\"Initializes the contract.\"},\"messageNonce()\":{\"notice\":\"Retrieves the next message nonce. Message version will be added to the upper two bytes of the message nonce. Message version allows us to treat messages as having different structures.\"},\"portal()\":{\"notice\":\"Getter for the OptimismPortal address.\"},\"relayMessage(uint256,address,address,uint256,uint256,bytes)\":{\"notice\":\"Relays a message that was sent by the other CrossDomainMessenger contract. Can only be executed via cross-chain call from the other messenger OR if the message was already received once and is currently being replayed.\"},\"sendMessage(address,bytes,uint32)\":{\"notice\":\"Sends a message to some target address on the other chain. Note that if the call always reverts, then the message will be unrelayable, and any ETH sent will be permanently locked. The same will occur if the target on the other chain is considered unsafe (see the _isUnsafeTarget() function).\"},\"successfulMessages(bytes32)\":{\"notice\":\"Mapping of message hashes to boolean receipt values. Note that a message will only be present in this mapping if it has successfully been relayed on this chain, and can therefore not be relayed again.\"},\"version()\":{\"notice\":\"Semantic version.\"},\"xDomainMessageSender()\":{\"notice\":\"Retrieves the address of the contract or wallet that initiated the currently executing message on the other chain. Will throw an error if there is no message currently being executed. Allows the recipient of a call to see who triggered it.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L1CrossDomainMessenger.sol\":\"L1CrossDomainMessenger\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L1CrossDomainMessenger.sol\":{\"keccak256\":\"0xe3fdf4102a94b9383f1ca917499ffeb8dd9be6317ef4ed9626a5ff44daf54461\",\"urls\":[\"bzz-raw://1c1a5f8612f0b170350e2436a64695c3e7fffd04ea1a617a64eacd4d2342a07c\",\"dweb:/ipfs/QmdoehaP6a9kyWR73LqRdqSCShiXKePwM7WJedwikvYR1w\"],\"license\":\"MIT\"},\"src/L1/L2OutputOracle.sol\":{\"keccak256\":\"0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705\",\"urls\":[\"bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc\",\"dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN\"],\"license\":\"MIT\"},\"src/L1/OptimismPortal.sol\":{\"keccak256\":\"0xdca91a921b402d82b455d7f11027514e8a16dca906cf820b3afffe271beb8a13\",\"urls\":[\"bzz-raw://688912b9d6005af8395d5c2eb5c4e3367a8be7b50ea97c34fc6a7ac0e2d8fd6a\",\"dweb:/ipfs/QmNPJDwHpNmJ5VPWAJB8muRpZxYeySZDVoV1TMVN7roijJ\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L1/SystemConfig.sol\":{\"keccak256\":\"0x2b4005c512ab947da105305e3db913b0d7884a954d0aa602f90f7b02188dcda6\",\"urls\":[\"bzz-raw://cc68c9ec4e1aebdd9dba39c7516d38e40a4472b708dfaca1fb9a4742d346db47\",\"dweb:/ipfs/QmX8moXk9cb47tRefi6q15oQAAt18MHEdQojWhrXxz5ykK\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Bytes.sol\":{\"keccak256\":\"0x827f47d123b0fdf3b08816d5b33831811704dbf4e554e53f2269354f6bba8859\",\"urls\":[\"bzz-raw://3137ac7204d30a245a8b0d67aa6da5286f1bd8c90379daab561f84963b6db782\",\"dweb:/ipfs/QmWRhisw3axJK833gUScs23ETh2MLFbVzzqzYVMKSDN3S9\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/Predeploys.sol\":{\"keccak256\":\"0x5af3a849f68f7c9108858ebac5c769da8f1c0309b5c0cb42eb5cbb15e3fe6058\",\"urls\":[\"bzz-raw://6ffe76429a96d274577be66627eddad5cd05ad36d0cb6b9b3c3f9fa8a609dd7e\",\"dweb:/ipfs/QmVhWnB7Avg684TEQ9BExWqSN1YfLehUTWoqpjymeQEQHm\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x9ba74a3b0a11693e622380807d213d5d1250d974e18b2cd768da9cbe719a6778\",\"urls\":[\"bzz-raw://0808d721ed9e05707526ee134faa051d707a95ee6b8bd6e0b1972275da8e5723\",\"dweb:/ipfs/QmcTTPu9xgckfWdbFUAcr2RAgk3J6vzyR4FpV798TjFMeN\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xf8ba770ee6666e73ae43184c700e9c704b2c4ace71f9e3c2227ddc11a8148b4c\",\"urls\":[\"bzz-raw://4702ccee1fe44aea3ee01d59e6152eb755da083f786f00947fec4437c064fe74\",\"dweb:/ipfs/QmQjFj5J7hrEM1dxJjFszzW2Cs7g7eMhYNBXonF2DXBstE\"],\"license\":\"MIT\"},\"src/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0xeaff8315cfd21197bc6bc859c2decf5d4f4838c9c357c502cdf2b1eac863d288\",\"urls\":[\"bzz-raw://79dcdcaa560aea51d138da4f5dc553a1808b6de090b2dc1629f18375edbff681\",\"dweb:/ipfs/QmbE4pUPhf5fLKW4W6cEjhQs55gEDvHmbmoBqkW1yz3bnw\"],\"license\":\"MIT\"},\"src/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x4302ae78bcafde2737d4048bbf8fdb3dd4cd7254c015b91dfa14fdaafd412f4a\",\"urls\":[\"bzz-raw://78d3d1823ad4e1fba15921a0a361b452c85d111e2d53cbbed11a8632782ea8f3\",\"dweb:/ipfs/QmVc2rTRpn7g7WAUxDShSuy6dY5zmtbJ7hHC6sT9PcD3Gj\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"],\"license\":\"Apache-2.0\"}},\"version\":1}", - "numDeployments": 6, - "receipt": { - "transactionHash": "0x9fad9708327ba5a4d7daa0eabeeca7b72a2553fd3b6914eb09ff3d3dc1bd9c4a", - "transactionIndex": "0x5", - "blockHash": "0x30eaba364ea372999e21c65eeb06db7a6200a8de6b3bebf9d88175bdbe963346", - "blockNumber": "0x438a04", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "cumulativeGasUsed": "0x6fab3b", - "gasUsed": "0x19edc6", - "contractAddress": "0xDa2332D0a7608919Cd331B1304Cd179129a90495", - "logs": [ - { - "address": "0xDa2332D0a7608919Cd331B1304Cd179129a90495", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000003", - "blockHash": "0x30eaba364ea372999e21c65eeb06db7a6200a8de6b3bebf9d88175bdbe963346", - "blockNumber": "0x438a04", - "transactionHash": "0x9fad9708327ba5a4d7daa0eabeeca7b72a2553fd3b6914eb09ff3d3dc1bd9c4a", - "transactionIndex": "0x5", - "logIndex": "0xd", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000200080000000000000000000000000000000000000000000000400000000000000000020000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb3c41425" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 75492, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_0_0_20", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 29536, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "_initialized", - "offset": 20, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 29539, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "_initializing", - "offset": 21, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 75499, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_1_0_1600", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 75502, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_51_0_20", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 75507, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_52_0_1568", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 75510, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_101_0_1", - "offset": 0, - "slot": "101", - "type": "t_bool" - }, - { - "astId": 75515, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_102_0_1568", - "offset": 0, - "slot": "102", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 75518, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_151_0_32", - "offset": 0, - "slot": "151", - "type": "t_uint256" - }, - { - "astId": 75523, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_152_0_1568", - "offset": 0, - "slot": "152", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 75528, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_201_0_32", - "offset": 0, - "slot": "201", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75533, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "spacer_202_0_32", - "offset": 0, - "slot": "202", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75581, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "successfulMessages", - "offset": 0, - "slot": "203", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75584, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "xDomainMsgSender", - "offset": 0, - "slot": "204", - "type": "t_address" - }, - { - "astId": 75587, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "msgNonce", - "offset": 0, - "slot": "205", - "type": "t_uint240" - }, - { - "astId": 75592, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "failedMessages", - "offset": 0, - "slot": "206", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 75597, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "__gap", - "offset": 0, - "slot": "207", - "type": "t_array(t_uint256)42_storage" - }, - { - "astId": 58828, - "contract": "src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger", - "label": "PORTAL", - "offset": 0, - "slot": "249", - "type": "t_contract(OptimismPortal)60892" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)42_storage": { - "encoding": "inplace", - "label": "uint256[42]", - "numberOfBytes": "1344", - "base": "t_uint256" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_contract(OptimismPortal)60892": { - "encoding": "inplace", - "label": "contract OptimismPortal", - "numberOfBytes": "20" - }, - "t_mapping(t_bytes32,t_bool)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_uint240": { - "encoding": "inplace", - "label": "uint240", - "numberOfBytes": "30" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x9fad9708327ba5a4d7daa0eabeeca7b72a2553fd3b6914eb09ff3d3dc1bd9c4a", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSAGE_VERSION()": { - "notice": "Current message version identifier." - }, - "MIN_GAS_CALLDATA_OVERHEAD()": { - "notice": "Extra gas added to base gas for each byte of calldata in a message." - }, - "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()": { - "notice": "Denominator for dynamic overhead added to the base gas for a message." - }, - "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR()": { - "notice": "Numerator for dynamic overhead added to the base gas for a message." - }, - "OTHER_MESSENGER()": { - "notice": "Address of the paired CrossDomainMessenger contract on the other chain." - }, - "PORTAL()": { - "notice": "Address of the OptimismPortal. The public getter for this is legacy and will be removed in the future. Use `portal()` instead." - }, - "RELAY_CALL_OVERHEAD()": { - "notice": "Gas reserved for performing the external call in `relayMessage`." - }, - "RELAY_CONSTANT_OVERHEAD()": { - "notice": "Constant overhead added to the base gas for a message." - }, - "RELAY_GAS_CHECK_BUFFER()": { - "notice": "Gas reserved for the execution between the `hasMinGas` check and the external call in `relayMessage`." - }, - "RELAY_RESERVED_GAS()": { - "notice": "Gas reserved for finalizing the execution of `relayMessage` after the safe call." - }, - "baseGas(bytes,uint32)": { - "notice": "Computes the amount of gas required to guarantee that a given message will be received on the other chain without running out of gas. Guaranteeing that a message will not run out of gas is important because this ensures that a message can always be replayed on the other chain if it fails to execute completely." - }, - "constructor": { - "notice": "Constructs the L1CrossDomainMessenger contract." - }, - "failedMessages(bytes32)": { - "notice": "Mapping of message hashes to a boolean if and only if the message has failed to be executed at least once. A message will not be present in this mapping if it successfully executed on the first attempt." - }, - "initialize(address)": { - "notice": "Initializes the contract." - }, - "messageNonce()": { - "notice": "Retrieves the next message nonce. Message version will be added to the upper two bytes of the message nonce. Message version allows us to treat messages as having different structures." - }, - "portal()": { - "notice": "Getter for the OptimismPortal address." - }, - "relayMessage(uint256,address,address,uint256,uint256,bytes)": { - "notice": "Relays a message that was sent by the other CrossDomainMessenger contract. Can only be executed via cross-chain call from the other messenger OR if the message was already received once and is currently being replayed." - }, - "sendMessage(address,bytes,uint32)": { - "notice": "Sends a message to some target address on the other chain. Note that if the call always reverts, then the message will be unrelayable, and any ETH sent will be permanently locked. The same will occur if the target on the other chain is considered unsafe (see the _isUnsafeTarget() function)." - }, - "successfulMessages(bytes32)": { - "notice": "Mapping of message hashes to boolean receipt values. Note that a message will only be present in this mapping if it has successfully been relayed on this chain, and can therefore not be relayed again." - }, - "version()": { - "notice": "Semantic version." - }, - "xDomainMessageSender()": { - "notice": "Retrieves the address of the contract or wallet that initiated the currently executing message on the other chain. Will throw an error if there is no message currently being executed. Allows the recipient of a call to see who triggered it." - } - }, - "events": { - "FailedRelayedMessage(bytes32)": { - "notice": "Emitted whenever a message fails to be relayed on this chain." - }, - "RelayedMessage(bytes32)": { - "notice": "Emitted whenever a message is successfully relayed on this chain." - }, - "SentMessage(address,address,bytes,uint256,uint256)": { - "notice": "Emitted whenever a message is sent to the other chain." - }, - "SentMessageExtension1(address,uint256)": { - "notice": "Additional event data to emit, required as of Bedrock. Cannot be merged with the SentMessage event without breaking the ABI of this contract, this is good enough." - } - }, - "notice": "The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible for sending and receiving data on the L1 side. Users are encouraged to use this interface instead of interacting with lower-level contracts directly." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/L1CrossDomainMessengerProxy.json b/packages/contracts-bedrock/deployments/sepolia/L1CrossDomainMessengerProxy.json deleted file mode 100644 index 88097abff1ce..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/L1CrossDomainMessengerProxy.json +++ /dev/null @@ -1,119 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "contract AddressManager", - "name": "_addressManager", - "type": "address" - }, - { - "internalType": "string", - "name": "_implementationName", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "stateMutability": "payable", - "type": "fallback" - } - ], - "address": "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef", - "args": [ - "0x9bFE9c5609311DF1c011c47642253B78a4f33F4B", - "OVM_L1CrossDomainMessenger" - ], - "bytecode": "0x608060405234801561001057600080fd5b506040516105f03803806105f083398101604081905261002f91610088565b30600090815260016020908152604080832080546001600160a01b0319166001600160a01b03871617905590829052902061006a8282610203565b5050506102c2565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561009b57600080fd5b82516001600160a01b03811681146100b257600080fd5b602084810151919350906001600160401b03808211156100d157600080fd5b818601915086601f8301126100e557600080fd5b8151818111156100f7576100f7610072565b604051601f8201601f19908116603f0116810190838211818310171561011f5761011f610072565b81604052828152898684870101111561013757600080fd5b600093505b82841015610159578484018601518185018701529285019261013c565b8284111561016a5760008684830101525b8096505050505050509250929050565b600181811c9082168061018e57607f821691505b6020821081036101ae57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156101fe57600081815260208120601f850160051c810160208610156101db5750805b601f850160051c820191505b818110156101fa578281556001016101e7565b5050505b505050565b81516001600160401b0381111561021c5761021c610072565b6102308161022a845461017a565b846101b4565b602080601f831160018114610265576000841561024d5750858301515b600019600386901b1c1916600185901b1785556101fa565b600085815260208120601f198616915b8281101561029457888601518255948401946001909101908401610275565b50858210156102b25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61031f806102d16000396000f3fe608060408181523060009081526001602090815282822054908290529181207fbf40fac1000000000000000000000000000000000000000000000000000000009093529173ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061006d9060846101e2565b602060405180830381865afa15801561008a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ae91906102c5565b905073ffffffffffffffffffffffffffffffffffffffff8116610157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f5265736f6c76656444656c656761746550726f78793a2074617267657420616460448201527f6472657373206d75737420626520696e697469616c697a656400000000000000606482015260840160405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff16600036604051610182929190610302565b600060405180830381855af49150503d80600081146101bd576040519150601f19603f3d011682016040523d82523d6000602084013e6101c2565b606091505b5090925090508115156001036101da57805160208201f35b805160208201fd5b600060208083526000845481600182811c91508083168061020457607f831692505b858310810361023a577f4e487b710000000000000000000000000000000000000000000000000000000085526022600452602485fd5b878601838152602001818015610257576001811461028b576102b6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616825284151560051b820196506102b6565b60008b81526020902060005b868110156102b057815484820152908501908901610297565b83019750505b50949998505050505050505050565b6000602082840312156102d757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146102fb57600080fd5b9392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "deployedBytecode": "0x608060408181523060009081526001602090815282822054908290529181207fbf40fac1000000000000000000000000000000000000000000000000000000009093529173ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061006d9060846101e2565b602060405180830381865afa15801561008a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ae91906102c5565b905073ffffffffffffffffffffffffffffffffffffffff8116610157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f5265736f6c76656444656c656761746550726f78793a2074617267657420616460448201527f6472657373206d75737420626520696e697469616c697a656400000000000000606482015260840160405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff16600036604051610182929190610302565b600060405180830381855af49150503d80600081146101bd576040519150601f19603f3d011682016040523d82523d6000602084013e6101c2565b606091505b5090925090508115156001036101da57805160208201f35b805160208201fd5b600060208083526000845481600182811c91508083168061020457607f831692505b858310810361023a577f4e487b710000000000000000000000000000000000000000000000000000000085526022600452602485fd5b878601838152602001818015610257576001811461028b576102b6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616825284151560051b820196506102b6565b60008b81526020902060005b868110156102b057815484820152908501908901610297565b83019750505b50949998505050505050505050565b6000602082840312156102d757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146102fb57600080fd5b9392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_addressManager": "Address of the AddressManager.", - "_implementationName": "implementationName of the contract to proxy to." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract AddressManager\",\"name\":\"_addressManager\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_implementationName\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"fallback\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_addressManager\":\"Address of the AddressManager.\",\"_implementationName\":\"implementationName of the contract to proxy to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/legacy/ResolvedDelegateProxy.sol\":\"ResolvedDelegateProxy\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"urls\":[\"bzz-raw://40fb1b5102468f783961d0af743f91b9980cf66b50d1d12009f6bb1869cea4d2\",\"dweb:/ipfs/QmYqEbJML4jB1GHbzD4cUZDtJg5wVwNm3vDJq1GbyDus8y\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"],\"license\":\"MIT\"},\"src/legacy/AddressManager.sol\":{\"keccak256\":\"0x1fcb990df6473f7fa360d5924d62d39ce2ca97d45668e3901e5405cfbe598b19\",\"urls\":[\"bzz-raw://9d08358b60dea54dbc32e988a1bb7ea909488063eaae3c5ae28a322f125c9b34\",\"dweb:/ipfs/QmZPQwdjLh9gaamNAoTUmWwwbRKj3yHovBYfnTPnfuKvUt\"],\"license\":\"MIT\"},\"src/legacy/ResolvedDelegateProxy.sol\":{\"keccak256\":\"0xe4ac1ddcf33df096f54db4e02d0b128704facdbd918645888d2d0431e4bb11fb\",\"urls\":[\"bzz-raw://61eeaea537ab98eb27b65afaf3665dc16338bd81f48f01b8477c6176328b3033\",\"dweb:/ipfs/QmSGYe6ZB8BrC7u28NTGeAtpqs9CcfkneuCngEUS1tyujS\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": { - "transactionHash": "0xf6dcfce79f0b87a325b4f42d397a4a02c0143e1a2aafd931eed9190f13336808", - "transactionIndex": "0x9", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0x5f2b88", - "gasUsed": "0x44e5e", - "contractAddress": "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xbec78df7" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 63316, - "contract": "src/legacy/ResolvedDelegateProxy.sol:ResolvedDelegateProxy", - "label": "implementationName", - "offset": 0, - "slot": "0", - "type": "t_mapping(t_address,t_string_storage)" - }, - { - "astId": 63322, - "contract": "src/legacy/ResolvedDelegateProxy.sol:ResolvedDelegateProxy", - "label": "addressManager", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_address,t_contract(AddressManager)62454)" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_contract(AddressManager)62454": { - "encoding": "inplace", - "label": "contract AddressManager", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_contract(AddressManager)62454)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => contract AddressManager)", - "numberOfBytes": "32", - "value": "t_contract(AddressManager)62454" - }, - "t_mapping(t_address,t_string_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => string)", - "numberOfBytes": "32", - "value": "t_string_storage" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - } - } - }, - "transactionHash": "0xf6dcfce79f0b87a325b4f42d397a4a02c0143e1a2aafd931eed9190f13336808", - "userdoc": { - "version": 1, - "kind": "user", - "notice": "ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to resolve the implementation address. We're maintaining this contract for backwards compatibility so we can manage all legacy proxies where necessary." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/L1ERC721Bridge.json b/packages/contracts-bedrock/deployments/sepolia/L1ERC721Bridge.json deleted file mode 100644 index 241f422df07a..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/L1ERC721Bridge.json +++ /dev/null @@ -1,554 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC721BridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC721BridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "inputs": [], - "name": "MESSENGER", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_BRIDGE", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC721To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "deposits", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "_messenger", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "messenger", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "otherBridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x806C2d0d2BDDFf9279CB2A8722F9117f0b0aDE73", - "args": [], - "bytecode": "0x60a060405234801561001057600080fd5b50734200000000000000000000000000000000000014610034565b60405180910390fd5b6001600160a01b031660805261004a600061004f565b6101cb565b600054600390610100900460ff16158015610071575060005460ff8083169116105b6100d45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161002b565b6000805461ffff191660ff8316176101001790556100f182610136565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054610100900460ff166101a15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161002b565b600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6080516112116101fb600039600081816101cd0152818161023b015281816103350152610bf101526112116000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80637f46ddb211610076578063aa5574521161005b578063aa55745214610213578063c4d66de814610226578063c89701a21461023957600080fd5b80637f46ddb2146101c8578063927ede2d146101ef57600080fd5b806354fd4d50116100a757806354fd4d50146101285780635d93a3fc14610171578063761f4493146101b557600080fd5b80633687011a146100c35780633cb747bf146100d8575b600080fd5b6100d66100d1366004610e47565b61025f565b005b6000546100fe9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101646040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b60405161011f9190610f35565b6101a561017f366004610f4f565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b604051901515815260200161011f565b6100d66101c3366004610f90565b61030b565b6100fe7f000000000000000000000000000000000000000000000000000000000000000081565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166100fe565b6100d6610221366004611028565b610776565b6100d661023436600461109f565b610832565b7f00000000000000000000000000000000000000000000000000000000000000006100fe565b333b156102f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b610303868633338888888861097c565b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314801561041357507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fb91906110bc565b73ffffffffffffffffffffffffffffffffffffffff16145b61049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f74686572206272696467650060648201526084016102ea565b3073ffffffffffffffffffffffffffffffffffffffff881603610544576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff161515600114610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c31204272696467650000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156106d357600080fd5b505af11580156106e7573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107659493929190611122565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f7420626520616464726573732830290000000000000000000000000000000060648201526084016102ea565b610829878733888888888861097c565b50505050505050565b600054600390610100900460ff16158015610854575060005460ff8083169116105b6108e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016102ea565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561091a82610cdc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b73ffffffffffffffffffffffffffffffffffffffff8716610a1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f74206265206164647265737328302900000000000000000000000000000060648201526084016102ea565b600063761f449360e01b888a8989898888604051602401610a469796959493929190611162565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610b8657600080fd5b505af1158015610b9a573d6000803e3d6000fd5b50506000546040517f3dbb202b0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169250633dbb202b9150610c1d907f000000000000000000000000000000000000000000000000000000000000000090859089906004016111bf565b600060405180830381600087803b158015610c3757600080fd5b505af1158015610c4b573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610cc99493929190611122565b60405180910390a4505050505050505050565b600054610100900460ff16610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ea565b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610de257600080fd5b50565b803563ffffffff81168114610df957600080fd5b919050565b60008083601f840112610e1057600080fd5b50813567ffffffffffffffff811115610e2857600080fd5b602083019150836020828501011115610e4057600080fd5b9250929050565b60008060008060008060a08789031215610e6057600080fd5b8635610e6b81610dc0565b95506020870135610e7b81610dc0565b945060408701359350610e9060608801610de5565b9250608087013567ffffffffffffffff811115610eac57600080fd5b610eb889828a01610dfe565b979a9699509497509295939492505050565b6000815180845260005b81811015610ef057602081850181015186830182015201610ed4565b81811115610f02576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f486020830184610eca565b9392505050565b600080600060608486031215610f6457600080fd5b8335610f6f81610dc0565b92506020840135610f7f81610dc0565b929592945050506040919091013590565b600080600080600080600060c0888a031215610fab57600080fd5b8735610fb681610dc0565b96506020880135610fc681610dc0565b95506040880135610fd681610dc0565b94506060880135610fe681610dc0565b93506080880135925060a088013567ffffffffffffffff81111561100957600080fd5b6110158a828b01610dfe565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561104357600080fd5b873561104e81610dc0565b9650602088013561105e81610dc0565b9550604088013561106e81610dc0565b94506060880135935061108360808901610de5565b925060a088013567ffffffffffffffff81111561100957600080fd5b6000602082840312156110b157600080fd5b8135610f4881610dc0565b6000602082840312156110ce57600080fd5b8151610f4881610dc0565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006111586060830184866110d9565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a08301526111b260c0830184866110d9565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006111ee6060830185610eca565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c80637f46ddb211610076578063aa5574521161005b578063aa55745214610213578063c4d66de814610226578063c89701a21461023957600080fd5b80637f46ddb2146101c8578063927ede2d146101ef57600080fd5b806354fd4d50116100a757806354fd4d50146101285780635d93a3fc14610171578063761f4493146101b557600080fd5b80633687011a146100c35780633cb747bf146100d8575b600080fd5b6100d66100d1366004610e47565b61025f565b005b6000546100fe9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101646040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b60405161011f9190610f35565b6101a561017f366004610f4f565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b604051901515815260200161011f565b6100d66101c3366004610f90565b61030b565b6100fe7f000000000000000000000000000000000000000000000000000000000000000081565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166100fe565b6100d6610221366004611028565b610776565b6100d661023436600461109f565b610832565b7f00000000000000000000000000000000000000000000000000000000000000006100fe565b333b156102f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b610303868633338888888861097c565b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314801561041357507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fb91906110bc565b73ffffffffffffffffffffffffffffffffffffffff16145b61049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f74686572206272696467650060648201526084016102ea565b3073ffffffffffffffffffffffffffffffffffffffff881603610544576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff161515600114610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c31204272696467650000000000000060648201526084016102ea565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156106d357600080fd5b505af11580156106e7573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac878787876040516107659493929190611122565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f7420626520616464726573732830290000000000000000000000000000000060648201526084016102ea565b610829878733888888888861097c565b50505050505050565b600054600390610100900460ff16158015610854575060005460ff8083169116105b6108e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016102ea565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561091a82610cdc565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b73ffffffffffffffffffffffffffffffffffffffff8716610a1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f74206265206164647265737328302900000000000000000000000000000060648201526084016102ea565b600063761f449360e01b888a8989898888604051602401610a469796959493929190611162565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610b8657600080fd5b505af1158015610b9a573d6000803e3d6000fd5b50506000546040517f3dbb202b0000000000000000000000000000000000000000000000000000000081526201000090910473ffffffffffffffffffffffffffffffffffffffff169250633dbb202b9150610c1d907f000000000000000000000000000000000000000000000000000000000000000090859089906004016111bf565b600060405180830381600087803b158015610c3757600080fd5b505af1158015610c4b573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610cc99493929190611122565b60405180910390a4505050505050505050565b600054610100900460ff16610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ea565b6000805473ffffffffffffffffffffffffffffffffffffffff90921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610de257600080fd5b50565b803563ffffffff81168114610df957600080fd5b919050565b60008083601f840112610e1057600080fd5b50813567ffffffffffffffff811115610e2857600080fd5b602083019150836020828501011115610e4057600080fd5b9250929050565b60008060008060008060a08789031215610e6057600080fd5b8635610e6b81610dc0565b95506020870135610e7b81610dc0565b945060408701359350610e9060608801610de5565b9250608087013567ffffffffffffffff811115610eac57600080fd5b610eb889828a01610dfe565b979a9699509497509295939492505050565b6000815180845260005b81811015610ef057602081850181015186830182015201610ed4565b81811115610f02576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f486020830184610eca565b9392505050565b600080600060608486031215610f6457600080fd5b8335610f6f81610dc0565b92506020840135610f7f81610dc0565b929592945050506040919091013590565b600080600080600080600060c0888a031215610fab57600080fd5b8735610fb681610dc0565b96506020880135610fc681610dc0565b95506040880135610fd681610dc0565b94506060880135610fe681610dc0565b93506080880135925060a088013567ffffffffffffffff81111561100957600080fd5b6110158a828b01610dfe565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561104357600080fd5b873561104e81610dc0565b9650602088013561105e81610dc0565b9550604088013561106e81610dc0565b94506060880135935061108360808901610de5565b925060a088013567ffffffffffffffff81111561100957600080fd5b6000602082840312156110b157600080fd5b8135610f4881610dc0565b6000602082840312156110ce57600080fd5b8151610f4881610dc0565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006111586060830184866110d9565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a08301526111b260c0830184866110d9565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006111ee6060830185610eca565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "bridgeERC721(address,address,uint256,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.", - "_localToken": "Address of the ERC721 on this domain.", - "_minGasLimit": "Minimum gas limit for the bridge message on the other domain.", - "_remoteToken": "Address of the ERC721 on the remote domain.", - "_tokenId": "Token ID to bridge." - } - }, - "bridgeERC721To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.", - "_localToken": "Address of the ERC721 on this domain.", - "_minGasLimit": "Minimum gas limit for the bridge message on the other domain.", - "_remoteToken": "Address of the ERC721 on the remote domain.", - "_to": "Address to receive the token on the other domain.", - "_tokenId": "Token ID to bridge." - } - }, - "finalizeBridgeERC721(address,address,address,address,uint256,bytes)": { - "params": { - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_from": "Address that triggered the bridge on the other domain.", - "_localToken": "Address of the ERC721 token on this domain.", - "_remoteToken": "Address of the ERC721 token on the other domain.", - "_to": "Address to receive the token on this domain.", - "_tokenId": "ID of the token being deposited." - } - }, - "initialize(address)": { - "params": { - "_messenger": "Address of the CrossDomainMessenger on this network." - } - }, - "otherBridge()": { - "returns": { - "_0": "Address of the bridge on the other network." - } - } - }, - "title": "L1ERC721Bridge" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC721BridgeFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC721BridgeInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC721\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC721To\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeBridgeERC721\"},{\"inputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"_messenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"bridgeERC721(address,address,uint256,uint32,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.\",\"_localToken\":\"Address of the ERC721 on this domain.\",\"_minGasLimit\":\"Minimum gas limit for the bridge message on the other domain.\",\"_remoteToken\":\"Address of the ERC721 on the remote domain.\",\"_tokenId\":\"Token ID to bridge.\"}},\"bridgeERC721To(address,address,address,uint256,uint32,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to the other chain. Data supplied here will not be used to execute any code on the other chain and is only emitted as extra data for the convenience of off-chain tooling.\",\"_localToken\":\"Address of the ERC721 on this domain.\",\"_minGasLimit\":\"Minimum gas limit for the bridge message on the other domain.\",\"_remoteToken\":\"Address of the ERC721 on the remote domain.\",\"_to\":\"Address to receive the token on the other domain.\",\"_tokenId\":\"Token ID to bridge.\"}},\"finalizeBridgeERC721(address,address,address,address,uint256,bytes)\":{\"params\":{\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_from\":\"Address that triggered the bridge on the other domain.\",\"_localToken\":\"Address of the ERC721 token on this domain.\",\"_remoteToken\":\"Address of the ERC721 token on the other domain.\",\"_to\":\"Address to receive the token on this domain.\",\"_tokenId\":\"ID of the token being deposited.\"}},\"initialize(address)\":{\"params\":{\"_messenger\":\"Address of the CrossDomainMessenger on this network.\"}},\"otherBridge()\":{\"returns\":{\"_0\":\"Address of the bridge on the other network.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"MESSENGER()\":{\"notice\":\"Getter for messenger contract.\"},\"OTHER_BRIDGE()\":{\"notice\":\"Address of the bridge on the other network.\"},\"bridgeERC721(address,address,uint256,uint32,bytes)\":{\"notice\":\"Initiates a bridge of an NFT to the caller's account on the other chain. Note that this function can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` function after ensuring that the recipient address on the remote chain exists. Also note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\"},\"bridgeERC721To(address,address,address,uint256,uint32,bytes)\":{\"notice\":\"Initiates a bridge of an NFT to some recipient's account on the other chain. Note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2.\"},\"constructor\":{\"notice\":\"Constructs the contract.\"},\"deposits(address,address,uint256)\":{\"notice\":\"Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token by ID was deposited for a given L2 token.\"},\"finalizeBridgeERC721(address,address,address,address,uint256,bytes)\":{\"notice\":\"Completes an ERC721 bridge from the other domain and sends the ERC721 token to the recipient on this domain.\"},\"initialize(address)\":{\"notice\":\"Initializes the contract.\"},\"messenger()\":{\"notice\":\"Messenger contract on this domain.\"},\"otherBridge()\":{\"notice\":\"Getter for other bridge address.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L1ERC721Bridge.sol\":\"L1ERC721Bridge\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"urls\":[\"bzz-raw://20a97f891d06f0fe91560ea1a142aaa26fdd22bed1b51606b7d48f670deeb50f\",\"dweb:/ipfs/QmTbCtZKChpaX5H2iRiTDMcSz29GSLCpTCDgJpcMR4wg8x\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"keccak256\":\"0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf\",\"urls\":[\"bzz-raw://26fef835622b46a5ba08b3ef6b46a22e94b5f285d0f0fb66b703bd30217d2c34\",\"dweb:/ipfs/QmZ548qdwfL1qF7aXz3xh1GCdTiST81kGGuKRqVUfYmPZR\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L1ERC721Bridge.sol\":{\"keccak256\":\"0xfcbde0f08cd5601aac88a40ee9224f59af9c7f5c404d67f37cbb0abd5f298b1f\",\"urls\":[\"bzz-raw://f1d26441cb269c4e1d45b2739342c016d8ec461dcb99c30da6e649e58d3b376d\",\"dweb:/ipfs/QmU4sYC5ZBGWtgwV2isLp8pXhvNum34d6Fsdsj7UNLEcUw\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L2/L2ERC721Bridge.sol\":{\"keccak256\":\"0xcc0de3ee4e726fe4a0a52a0684fc30454a49190d600c7cbeade798ae020d70f6\",\"urls\":[\"bzz-raw://bfa81e6c23f59237794bce97ad55cca091980c3db50bb295f836ab20cb58e4c8\",\"dweb:/ipfs/QmSpfckbZeoCEAASqxWdFm7t8q6Rqkqwk2jQFSCKEBXEVs\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/Predeploys.sol\":{\"keccak256\":\"0x5af3a849f68f7c9108858ebac5c769da8f1c0309b5c0cb42eb5cbb15e3fe6058\",\"urls\":[\"bzz-raw://6ffe76429a96d274577be66627eddad5cd05ad36d0cb6b9b3c3f9fa8a609dd7e\",\"dweb:/ipfs/QmVhWnB7Avg684TEQ9BExWqSN1YfLehUTWoqpjymeQEQHm\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x4302ae78bcafde2737d4048bbf8fdb3dd4cd7254c015b91dfa14fdaafd412f4a\",\"urls\":[\"bzz-raw://78d3d1823ad4e1fba15921a0a361b452c85d111e2d53cbbed11a8632782ea8f3\",\"dweb:/ipfs/QmVc2rTRpn7g7WAUxDShSuy6dY5zmtbJ7hHC6sT9PcD3Gj\"],\"license\":\"MIT\"},\"src/universal/ERC721Bridge.sol\":{\"keccak256\":\"0x1aba1c039fa759d7d081e0d60c5d742e8d3147f0eda19af5c17cf291b4f53213\",\"urls\":[\"bzz-raw://a3581c48036bf901da4dd823f4b2fc65870414a116b32ed042d89778a2027e3f\",\"dweb:/ipfs/QmVqTCMR6NroWCQzjc1vkznHp1XbNFSYXNDgrvXUDEuZoA\"],\"license\":\"MIT\"},\"src/universal/IOptimismMintableERC721.sol\":{\"keccak256\":\"0xb3a65b067e67a9e1fa0493401c8d247970377c6725eba4e7b02ce8099c4f4f52\",\"urls\":[\"bzz-raw://86bb6864027560ade2f4ced6a6e34213cbff8002977dc365377e5a0b473cf17b\",\"dweb:/ipfs/QmQvjtodTK27as1g1PzsYk9NyJJ3X6a6251o1vrBwx7DPT\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 6, - "receipt": { - "transactionHash": "0x4a50da124051e8611e6ef87230e73f487647ae6882c43442fdebbd58bcc20a60", - "transactionIndex": "0x6", - "blockHash": "0x1757e9d553875bd033f03f68b1e4494db5258e626f0853156717dd64b6cdb98a", - "blockNumber": "0x438a06", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "cumulativeGasUsed": "0x3f3e27", - "gasUsed": "0x1075e1", - "contractAddress": "0x806C2d0d2BDDFf9279CB2A8722F9117f0b0aDE73", - "logs": [ - { - "address": "0x806C2d0d2BDDFf9279CB2A8722F9117f0b0aDE73", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000003", - "blockHash": "0x1757e9d553875bd033f03f68b1e4494db5258e626f0853156717dd64b6cdb98a", - "blockNumber": "0x438a06", - "transactionHash": "0x4a50da124051e8611e6ef87230e73f487647ae6882c43442fdebbd58bcc20a60", - "transactionIndex": "0x6", - "logIndex": "0x1b", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000080000000000000000000000000000000400000000000000000000010000000000000000000000000000000000000000040000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb3abbc06" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 76028, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "messenger", - "offset": 2, - "slot": "0", - "type": "t_contract(CrossDomainMessenger)76013" - }, - { - "astId": 76036, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)48_storage" - }, - { - "astId": 58984, - "contract": "src/L1/L1ERC721Bridge.sol:L1ERC721Bridge", - "label": "deposits", - "offset": 0, - "slot": "49", - "type": "t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint256,t_bool)))" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)48_storage": { - "encoding": "inplace", - "label": "uint256[48]", - "numberOfBytes": "1536", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(CrossDomainMessenger)76013": { - "encoding": "inplace", - "label": "contract CrossDomainMessenger", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint256,t_bool)))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => mapping(uint256 => bool)))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_mapping(t_uint256,t_bool))" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_bool))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(uint256 => bool))", - "numberOfBytes": "32", - "value": "t_mapping(t_uint256,t_bool)" - }, - "t_mapping(t_uint256,t_bool)": { - "encoding": "mapping", - "key": "t_uint256", - "label": "mapping(uint256 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x4a50da124051e8611e6ef87230e73f487647ae6882c43442fdebbd58bcc20a60", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSENGER()": { - "notice": "Getter for messenger contract." - }, - "OTHER_BRIDGE()": { - "notice": "Address of the bridge on the other network." - }, - "bridgeERC721(address,address,uint256,uint32,bytes)": { - "notice": "Initiates a bridge of an NFT to the caller's account on the other chain. Note that this function can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` function after ensuring that the recipient address on the remote chain exists. Also note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "bridgeERC721To(address,address,address,uint256,uint32,bytes)": { - "notice": "Initiates a bridge of an NFT to some recipient's account on the other chain. Note that the current owner of the token on this chain must approve this contract to operate the NFT before it can be bridged. **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This bridge only supports ERC721s originally deployed on Ethereum. Users will need to wait for the one-week challenge period to elapse before their Optimism-native NFT can be refunded on L2." - }, - "constructor": { - "notice": "Constructs the contract." - }, - "deposits(address,address,uint256)": { - "notice": "Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token by ID was deposited for a given L2 token." - }, - "finalizeBridgeERC721(address,address,address,address,uint256,bytes)": { - "notice": "Completes an ERC721 bridge from the other domain and sends the ERC721 token to the recipient on this domain." - }, - "initialize(address)": { - "notice": "Initializes the contract." - }, - "messenger()": { - "notice": "Messenger contract on this domain." - }, - "otherBridge()": { - "notice": "Getter for other bridge address." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ERC721BridgeFinalized(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC721 bridge from the other network is finalized." - }, - "ERC721BridgeInitiated(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC721 bridge to the other network is initiated." - } - }, - "notice": "The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract acts as an escrow for ERC721 tokens deposited into L2." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/L1ERC721BridgeProxy.json b/packages/contracts-bedrock/deployments/sepolia/L1ERC721BridgeProxy.json deleted file mode 100644 index 449f83f9b234..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/L1ERC721BridgeProxy.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0xd83e03D576d23C9AEab8cC44Fa98d058D2176D1f", - "args": [ - "0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc" - ], - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"AdminChanged\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Upgraded\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"changeAdmin\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"upgradeTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/Proxy.sol\":\"Proxy\"},\"libraries\":{}},\"sources\":{\"src/universal/Proxy.sol\":{\"keccak256\":\"0x783aed9ff90b38a9898be5fb18699b3b249f012bc2c33f6537e1ab9f6444478f\",\"urls\":[\"bzz-raw://b119b1b68874f4d92a89cc05a4f0d25da73a959747a81e26739739a52895b844\",\"dweb:/ipfs/QmbKZqMd6CsM7annE7bCXcCi72syJAX3qtuFNPEGMCp13W\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": { - "transactionHash": "0x0cc2efb428b8fcd337337e6c04d1af53ffa295345244c448617ab9156a624d69", - "transactionIndex": "0xc", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0x6fea85", - "gasUsed": "0x7feb8", - "contractAddress": "0xd83e03D576d23C9AEab8cC44Fa98d058D2176D1f", - "logs": [ - { - "address": "0xd83e03D576d23C9AEab8cC44Fa98d058D2176D1f", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000189abaaaa82dfc015a588a7dbad6f13b1d3485bc", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "transactionHash": "0x0cc2efb428b8fcd337337e6c04d1af53ffa295345244c448617ab9156a624d69", - "transactionIndex": "0xc", - "logIndex": "0xa", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xbec78df7" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [], - "types": {} - }, - "transactionHash": "0x0cc2efb428b8fcd337337e6c04d1af53ffa295345244c448617ab9156a624d69", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/L1StandardBridge.json b/packages/contracts-bedrock/deployments/sepolia/L1StandardBridge.json deleted file mode 100644 index aeb12096b07b..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/L1StandardBridge.json +++ /dev/null @@ -1,1151 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20BridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20BridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20DepositInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "l1Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "l2Token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ERC20WithdrawalFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHBridgeFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHBridgeInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHDepositInitiated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "ETHWithdrawalFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "inputs": [], - "name": "MESSENGER", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OTHER_BRIDGE", - "outputs": [ - { - "internalType": "contract StandardBridge", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeERC20To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "bridgeETHTo", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositERC20To", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint32", - "name": "_minGasLimit", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "depositETHTo", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "deposits", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_localToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeBridgeETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_l1Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_l2Token", - "type": "address" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeERC20Withdrawal", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_extraData", - "type": "bytes" - } - ], - "name": "finalizeETHWithdrawal", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "_messenger", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l2TokenBridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "messenger", - "outputs": [ - { - "internalType": "contract CrossDomainMessenger", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "otherBridge", - "outputs": [ - { - "internalType": "contract StandardBridge", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0xcfBCbA6d9E84A3c4FaE0eda9684cE39a09aa2c8A", - "args": [], - "bytecode": "0x60a06040523480156200001157600080fd5b507342000000000000000000000000000000000000106080526200003660006200003c565b620001bb565b600054600390610100900460ff161580156200005f575060005460ff8083169116105b620000c85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620000e7826200012c565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b600054610100900460ff16620001995760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000bf565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b608051612a44620001fa60003960008181610379015281816104300152818161057001528181610a22015281816113d80152611a8b0152612a446000f3fe6080604052600436106101635760003560e01c806387087623116100c0578063a9f9e67511610074578063c4d66de811610059578063c4d66de8146104c5578063c89701a214610421578063e11013dd146104e557600080fd5b8063a9f9e67514610492578063b1a1a882146104b257600080fd5b806391c49bf8116100a557806391c49bf814610421578063927ede2d146104545780639a2ac6d51461047f57600080fd5b806387087623146103bb5780638f601f66146103db57600080fd5b8063540abf731161011757806358a997f6116100fc57806358a997f6146103475780637f46ddb214610367578063838b25201461039b57600080fd5b8063540abf73146102d157806354fd4d50146102f157600080fd5b80631532ec34116101485780631532ec34146102545780631635f5fd146102675780633cb747bf1461027a57600080fd5b80630166a07a1461022157806309fc88431461024157600080fd5b3661021c57333b156101fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61021a333362030d40604051806020016040528060008152506104f8565b005b600080fd5b34801561022d57600080fd5b5061021a61023c36600461248b565b61050b565b61021a61024f36600461253c565b6108d2565b61021a61026236600461258f565b6109a9565b61021a61027536600461258f565b6109bd565b34801561028657600080fd5b506003546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102dd57600080fd5b5061021a6102ec366004612602565b610e33565b3480156102fd57600080fd5b5061033a6040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516102c891906126ef565b34801561035357600080fd5b5061021a610362366004612702565b610e78565b34801561037357600080fd5b506102a77f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a757600080fd5b5061021a6103b6366004612602565b610f4c565b3480156103c757600080fd5b5061021a6103d6366004612702565b610f91565b3480156103e757600080fd5b506104136103f6366004612785565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102c8565b34801561042d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102a7565b34801561046057600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102a7565b61021a61048d3660046127be565b611065565b34801561049e57600080fd5b5061021a6104ad36600461248b565b6110a7565b61021a6104c036600461253c565b6110b6565b3480156104d157600080fd5b5061021a6104e0366004612821565b611187565b61021a6104f33660046127be565b6112d1565b6105058484348585611314565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff16331480156105fa5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e2919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b6106ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b6106b5876114fa565b15610803576106c4878761155c565b610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107e657600080fd5b505af11580156107fa573d6000803e3d6000fd5b50505050610885565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461084190849061288a565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561088590858561167c565b6108c9878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175092505050565b50505050505050565b333b15610961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b505050565b6109b685858585856109bd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610aac5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b823414610bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101f3565b3073ffffffffffffffffffffffffffffffffffffffff851603610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101f3565b610d7f85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117de92505050565b6000610d9c855a8660405180602001604052806000815250611851565b905080610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b505050505050565b6108c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b333b15610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b6108c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b333b15611020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b61050533858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b6108c98787878787878761050b565b333b15611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b600054600390610100900460ff161580156111a9575060005460ff8083169116105b611235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101f3565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561126f82611bc2565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6105053385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b8234146113a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101f3565b6113af85858584611ca0565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b9085907f0000000000000000000000000000000000000000000000000000000000000000907f1635f5fd000000000000000000000000000000000000000000000000000000009061142e908b908b9086908a906024016128a1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526114c1929188906004016128ea565b6000604051808303818588803b1580156114da57600080fd5b505af11580156114ee573d6000803e3d6000fd5b50505050505050505050565b6000611526827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b806115565750611556827fec4fc8e300000000000000000000000000000000000000000000000000000000611d13565b92915050565b6000611588837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b15611631578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fc919061283e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611556565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109a49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611d36565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516117c89392919061292f565b60405180910390a4610e2b868686868686611e42565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631848460405161183d92919061296d565b60405180910390a361050584848484611eca565b600080600080845160208601878a8af19695505050505050565b611874876114fa565b156119c257611883878761155c565b611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b50505050611a56565b6119e473ffffffffffffffffffffffffffffffffffffffff8816863086611f37565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611a22908490612986565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611a64878787878786611f95565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b907f0000000000000000000000000000000000000000000000000000000000000000907f0166a07a0000000000000000000000000000000000000000000000000000000090611ae5908b908d908c908c908c908b9060240161299e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611b78929187906004016128ea565b600060405180830381600087803b158015611b9257600080fd5b505af1158015611ba6573d6000803e3d6000fd5b5050505050505050505050565b6108c98787878787878761186b565b600054610100900460ff16611c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101f3565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611cff92919061296d565b60405180910390a361050584848484612023565b6000611d1e83612082565b8015611d2f5750611d2f83836120e6565b9392505050565b6000611d98826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b59092919063ffffffff16565b8051909150156109a45780806020019051810190611db691906129f9565b6109a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101f3565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611eba9392919061292f565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f2992919061296d565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105059085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116ce565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161200d9392919061292f565b60405180910390a4610e2b8686868686866121cc565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f2992919061296d565b60006120ae827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e6565b801561155657506120df827fffffffff000000000000000000000000000000000000000000000000000000006120e6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219e575060208210155b80156121aa5750600081115b979650505050505050565b60606121c48484600085612244565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611eba9392919061292f565b6060824710156122d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101f3565b73ffffffffffffffffffffffffffffffffffffffff85163b612354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161237d9190612a1b565b60006040518083038185875af1925050503d80600081146123ba576040519150601f19603f3d011682016040523d82523d6000602084013e6123bf565b606091505b50915091506121aa828286606083156123d9575081611d2f565b8251156123e95782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f391906126ef565b73ffffffffffffffffffffffffffffffffffffffff8116811461243f57600080fd5b50565b60008083601f84011261245457600080fd5b50813567ffffffffffffffff81111561246c57600080fd5b60208301915083602082850101111561248457600080fd5b9250929050565b600080600080600080600060c0888a0312156124a657600080fd5b87356124b18161241d565b965060208801356124c18161241d565b955060408801356124d18161241d565b945060608801356124e18161241d565b93506080880135925060a088013567ffffffffffffffff81111561250457600080fd5b6125108a828b01612442565b989b979a50959850939692959293505050565b803563ffffffff8116811461253757600080fd5b919050565b60008060006040848603121561255157600080fd5b61255a84612523565b9250602084013567ffffffffffffffff81111561257657600080fd5b61258286828701612442565b9497909650939450505050565b6000806000806000608086880312156125a757600080fd5b85356125b28161241d565b945060208601356125c28161241d565b935060408601359250606086013567ffffffffffffffff8111156125e557600080fd5b6125f188828901612442565b969995985093965092949392505050565b600080600080600080600060c0888a03121561261d57600080fd5b87356126288161241d565b965060208801356126388161241d565b955060408801356126488161241d565b94506060880135935061265d60808901612523565b925060a088013567ffffffffffffffff81111561250457600080fd5b60005b8381101561269457818101518382015260200161267c565b838111156105055750506000910152565b600081518084526126bd816020860160208601612679565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d2f60208301846126a5565b60008060008060008060a0878903121561271b57600080fd5b86356127268161241d565b955060208701356127368161241d565b94506040870135935061274b60608801612523565b9250608087013567ffffffffffffffff81111561276757600080fd5b61277389828a01612442565b979a9699509497509295939492505050565b6000806040838503121561279857600080fd5b82356127a38161241d565b915060208301356127b38161241d565b809150509250929050565b600080600080606085870312156127d457600080fd5b84356127df8161241d565b93506127ed60208601612523565b9250604085013567ffffffffffffffff81111561280957600080fd5b61281587828801612442565b95989497509550505050565b60006020828403121561283357600080fd5b8135611d2f8161241d565b60006020828403121561285057600080fd5b8151611d2f8161241d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561289c5761289c61285b565b500390565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128e060808301846126a5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061291960608301856126a5565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296460608301846126a5565b95945050505050565b8281526040602082015260006121c460408301846126a5565b600082198211156129995761299961285b565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526129ed60c08301846126a5565b98975050505050505050565b600060208284031215612a0b57600080fd5b81518015158114611d2f57600080fd5b60008251612a2d818460208701612679565b919091019291505056fea164736f6c634300080f000a", - "deployedBytecode": "0x6080604052600436106101635760003560e01c806387087623116100c0578063a9f9e67511610074578063c4d66de811610059578063c4d66de8146104c5578063c89701a214610421578063e11013dd146104e557600080fd5b8063a9f9e67514610492578063b1a1a882146104b257600080fd5b806391c49bf8116100a557806391c49bf814610421578063927ede2d146104545780639a2ac6d51461047f57600080fd5b806387087623146103bb5780638f601f66146103db57600080fd5b8063540abf731161011757806358a997f6116100fc57806358a997f6146103475780637f46ddb214610367578063838b25201461039b57600080fd5b8063540abf73146102d157806354fd4d50146102f157600080fd5b80631532ec34116101485780631532ec34146102545780631635f5fd146102675780633cb747bf1461027a57600080fd5b80630166a07a1461022157806309fc88431461024157600080fd5b3661021c57333b156101fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61021a333362030d40604051806020016040528060008152506104f8565b005b600080fd5b34801561022d57600080fd5b5061021a61023c36600461248b565b61050b565b61021a61024f36600461253c565b6108d2565b61021a61026236600461258f565b6109a9565b61021a61027536600461258f565b6109bd565b34801561028657600080fd5b506003546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102dd57600080fd5b5061021a6102ec366004612602565b610e33565b3480156102fd57600080fd5b5061033a6040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6040516102c891906126ef565b34801561035357600080fd5b5061021a610362366004612702565b610e78565b34801561037357600080fd5b506102a77f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a757600080fd5b5061021a6103b6366004612602565b610f4c565b3480156103c757600080fd5b5061021a6103d6366004612702565b610f91565b3480156103e757600080fd5b506104136103f6366004612785565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102c8565b34801561042d57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102a7565b34801561046057600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102a7565b61021a61048d3660046127be565b611065565b34801561049e57600080fd5b5061021a6104ad36600461248b565b6110a7565b61021a6104c036600461253c565b6110b6565b3480156104d157600080fd5b5061021a6104e0366004612821565b611187565b61021a6104f33660046127be565b6112d1565b6105058484348585611314565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff16331480156105fa5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e2919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b6106ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b6106b5876114fa565b15610803576106c4878761155c565b610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107e657600080fd5b505af11580156107fa573d6000803e3d6000fd5b50505050610885565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461084190849061288a565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561088590858561167c565b6108c9878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175092505050565b50505050505050565b333b15610961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a43333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b505050565b6109b685858585856109bd565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610aac5750600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116931691636e296e459160048083019260209291908290030181865afa158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061283e565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101f3565b823414610bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101f3565b3073ffffffffffffffffffffffffffffffffffffffff851603610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610d3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101f3565b610d7f85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117de92505050565b6000610d9c855a8660405180602001604052806000815250611851565b905080610e2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101f3565b505050505050565b6108c987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b333b15610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b6108c987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb392505050565b333b15611020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b610e2b86863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061186b92505050565b61050533858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b6108c98787878787878761050b565b333b15611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101f3565b6109a433338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104f892505050565b600054600390610100900460ff161580156111a9575060005460ff8083169116105b611235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016101f3565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561126f82611bc2565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6105053385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061131492505050565b8234146113a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101f3565b6113af85858584611ca0565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b9085907f0000000000000000000000000000000000000000000000000000000000000000907f1635f5fd000000000000000000000000000000000000000000000000000000009061142e908b908b9086908a906024016128a1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526114c1929188906004016128ea565b6000604051808303818588803b1580156114da57600080fd5b505af11580156114ee573d6000803e3d6000fd5b50505050505050505050565b6000611526827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b806115565750611556827fec4fc8e300000000000000000000000000000000000000000000000000000000611d13565b92915050565b6000611588837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d13565b15611631578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fc919061283e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611556565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d8573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109a49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611d36565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516117c89392919061292f565b60405180910390a4610e2b868686868686611e42565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631848460405161183d92919061296d565b60405180910390a361050584848484611eca565b600080600080845160208601878a8af19695505050505050565b611874876114fa565b156119c257611883878761155c565b611935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101f3565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b1580156119a557600080fd5b505af11580156119b9573d6000803e3d6000fd5b50505050611a56565b6119e473ffffffffffffffffffffffffffffffffffffffff8816863086611f37565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611a22908490612986565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611a64878787878786611f95565b60035460405173ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b907f0000000000000000000000000000000000000000000000000000000000000000907f0166a07a0000000000000000000000000000000000000000000000000000000090611ae5908b908d908c908c908c908b9060240161299e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611b78929187906004016128ea565b600060405180830381600087803b158015611b9257600080fd5b505af1158015611ba6573d6000803e3d6000fd5b5050505050505050505050565b6108c98787878787878761186b565b600054610100900460ff16611c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016101f3565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611cff92919061296d565b60405180910390a361050584848484612023565b6000611d1e83612082565b8015611d2f5750611d2f83836120e6565b9392505050565b6000611d98826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b59092919063ffffffff16565b8051909150156109a45780806020019051810190611db691906129f9565b6109a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101f3565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611eba9392919061292f565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f2992919061296d565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105059085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116ce565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161200d9392919061292f565b60405180910390a4610e2b8686868686866121cc565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f2992919061296d565b60006120ae827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e6565b801561155657506120df827fffffffff000000000000000000000000000000000000000000000000000000006120e6565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219e575060208210155b80156121aa5750600081115b979650505050505050565b60606121c48484600085612244565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611eba9392919061292f565b6060824710156122d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101f3565b73ffffffffffffffffffffffffffffffffffffffff85163b612354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161237d9190612a1b565b60006040518083038185875af1925050503d80600081146123ba576040519150601f19603f3d011682016040523d82523d6000602084013e6123bf565b606091505b50915091506121aa828286606083156123d9575081611d2f565b8251156123e95782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f391906126ef565b73ffffffffffffffffffffffffffffffffffffffff8116811461243f57600080fd5b50565b60008083601f84011261245457600080fd5b50813567ffffffffffffffff81111561246c57600080fd5b60208301915083602082850101111561248457600080fd5b9250929050565b600080600080600080600060c0888a0312156124a657600080fd5b87356124b18161241d565b965060208801356124c18161241d565b955060408801356124d18161241d565b945060608801356124e18161241d565b93506080880135925060a088013567ffffffffffffffff81111561250457600080fd5b6125108a828b01612442565b989b979a50959850939692959293505050565b803563ffffffff8116811461253757600080fd5b919050565b60008060006040848603121561255157600080fd5b61255a84612523565b9250602084013567ffffffffffffffff81111561257657600080fd5b61258286828701612442565b9497909650939450505050565b6000806000806000608086880312156125a757600080fd5b85356125b28161241d565b945060208601356125c28161241d565b935060408601359250606086013567ffffffffffffffff8111156125e557600080fd5b6125f188828901612442565b969995985093965092949392505050565b600080600080600080600060c0888a03121561261d57600080fd5b87356126288161241d565b965060208801356126388161241d565b955060408801356126488161241d565b94506060880135935061265d60808901612523565b925060a088013567ffffffffffffffff81111561250457600080fd5b60005b8381101561269457818101518382015260200161267c565b838111156105055750506000910152565b600081518084526126bd816020860160208601612679565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d2f60208301846126a5565b60008060008060008060a0878903121561271b57600080fd5b86356127268161241d565b955060208701356127368161241d565b94506040870135935061274b60608801612523565b9250608087013567ffffffffffffffff81111561276757600080fd5b61277389828a01612442565b979a9699509497509295939492505050565b6000806040838503121561279857600080fd5b82356127a38161241d565b915060208301356127b38161241d565b809150509250929050565b600080600080606085870312156127d457600080fd5b84356127df8161241d565b93506127ed60208601612523565b9250604085013567ffffffffffffffff81111561280957600080fd5b61281587828801612442565b95989497509550505050565b60006020828403121561283357600080fd5b8135611d2f8161241d565b60006020828403121561285057600080fd5b8151611d2f8161241d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561289c5761289c61285b565b500390565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128e060808301846126a5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061291960608301856126a5565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296460608301846126a5565b95945050505050565b8281526040602082015260006121c460408301846126a5565b600082198211156129995761299961285b565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526129ed60c08301846126a5565b98975050505050505050565b600060208284031215612a0b57600080fd5b81518015158114611d2f57600080fd5b60008251612a2d818460208701612679565b919091019291505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "MESSENGER()": {}, - "bridgeERC20(address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of local tokens to deposit.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_localToken": "Address of the ERC20 on this chain.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_remoteToken": "Address of the corresponding token on the remote chain." - } - }, - "bridgeERC20To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of local tokens to deposit.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_localToken": "Address of the ERC20 on this chain.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_remoteToken": "Address of the corresponding token on the remote chain.", - "_to": "Address of the receiver." - } - }, - "bridgeETH(uint32,bytes)": { - "params": { - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with." - } - }, - "bridgeETHTo(address,uint32,bytes)": { - "params": { - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_minGasLimit": "Minimum amount of gas that the bridge can be relayed with.", - "_to": "Address of the receiver." - } - }, - "depositERC20(address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of the ERC20 to deposit.", - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_l1Token": "Address of the L1 token being deposited.", - "_l2Token": "Address of the corresponding token on L2.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2." - } - }, - "depositERC20To(address,address,address,uint256,uint32,bytes)": { - "params": { - "_amount": "Amount of the ERC20 to deposit.", - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_l1Token": "Address of the L1 token being deposited.", - "_l2Token": "Address of the corresponding token on L2.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2.", - "_to": "Address of the recipient on L2." - } - }, - "depositETH(uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2." - } - }, - "depositETHTo(address,uint32,bytes)": { - "params": { - "_extraData": "Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.", - "_minGasLimit": "Minimum gas limit for the deposit message on L2.", - "_to": "Address of the recipient on L2." - } - }, - "finalizeBridgeERC20(address,address,address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of the ERC20 being bridged.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_from": "Address of the sender.", - "_localToken": "Address of the ERC20 on this chain.", - "_remoteToken": "Address of the corresponding token on the remote chain.", - "_to": "Address of the receiver." - } - }, - "finalizeBridgeETH(address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of ETH being bridged.", - "_extraData": "Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.", - "_from": "Address of the sender.", - "_to": "Address of the receiver." - } - }, - "finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of the ERC20 to withdraw.", - "_extraData": "Optional data forwarded from L2.", - "_from": "Address of the withdrawer on L2.", - "_l1Token": "Address of the token on L1.", - "_l2Token": "Address of the corresponding token on L2.", - "_to": "Address of the recipient on L1." - } - }, - "finalizeETHWithdrawal(address,address,uint256,bytes)": { - "params": { - "_amount": "Amount of ETH to withdraw.", - "_extraData": "Optional data forwarded from L2.", - "_from": "Address of the withdrawer on L2.", - "_to": "Address of the recipient on L1." - } - }, - "l2TokenBridge()": { - "returns": { - "_0": "Address of the corresponding L2 bridge contract." - } - } - }, - "events": { - "ERC20DepositInitiated(address,address,address,address,uint256,bytes)": { - "params": { - "amount": "Amount of the ERC20 deposited.", - "extraData": "Extra data attached to the deposit.", - "from": "Address of the depositor.", - "l1Token": "Address of the token on L1.", - "l2Token": "Address of the corresponding token on L2.", - "to": "Address of the recipient on L2." - } - }, - "ERC20WithdrawalFinalized(address,address,address,address,uint256,bytes)": { - "params": { - "amount": "Amount of the ERC20 withdrawn.", - "extraData": "Extra data attached to the withdrawal.", - "from": "Address of the withdrawer.", - "l1Token": "Address of the token on L1.", - "l2Token": "Address of the corresponding token on L2.", - "to": "Address of the recipient on L1." - } - }, - "ETHDepositInitiated(address,address,uint256,bytes)": { - "params": { - "amount": "Amount of ETH deposited.", - "extraData": "Extra data attached to the deposit.", - "from": "Address of the depositor.", - "to": "Address of the recipient on L2." - } - }, - "ETHWithdrawalFinalized(address,address,uint256,bytes)": { - "params": { - "amount": "Amount of ETH withdrawn.", - "extraData": "Extra data attached to the withdrawal.", - "from": "Address of the withdrawer.", - "to": "Address of the recipient on L1." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20BridgeFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20BridgeInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20DepositInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ERC20WithdrawalFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHBridgeFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHBridgeInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHDepositInitiated\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ETHWithdrawalFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"contract StandardBridge\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC20\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"bridgeERC20To\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"bridgeETH\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"bridgeETHTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"depositERC20\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"depositERC20To\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"depositETH\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"depositETHTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeBridgeERC20\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"finalizeBridgeETH\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeERC20Withdrawal\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"finalizeETHWithdrawal\"},{\"inputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"_messenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2TokenBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contract CrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"contract StandardBridge\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"MESSENGER()\":{\"custom:legacy\":\"@return Messenger contract on this domain.\"},\"bridgeERC20(address,address,uint256,uint32,bytes)\":{\"params\":{\"_amount\":\"Amount of local tokens to deposit.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\"}},\"bridgeERC20To(address,address,address,uint256,uint32,bytes)\":{\"params\":{\"_amount\":\"Amount of local tokens to deposit.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\",\"_to\":\"Address of the receiver.\"}},\"bridgeETH(uint32,bytes)\":{\"params\":{\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\"}},\"bridgeETHTo(address,uint32,bytes)\":{\"params\":{\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_minGasLimit\":\"Minimum amount of gas that the bridge can be relayed with.\",\"_to\":\"Address of the receiver.\"}},\"depositERC20(address,address,uint256,uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ERC20 tokens into the sender's account on L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_l1Token\":\"Address of the L1 token being deposited.\",\"_l2Token\":\"Address of the corresponding token on L2.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\"}},\"depositERC20To(address,address,address,uint256,uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ERC20 tokens into a target account on L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_l1Token\":\"Address of the L1 token being deposited.\",\"_l2Token\":\"Address of the corresponding token on L2.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\",\"_to\":\"Address of the recipient on L2.\"}},\"depositETH(uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ETH into the sender's account on L2.\",\"params\":{\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\"}},\"depositETHTo(address,uint32,bytes)\":{\"custom:legacy\":\"@notice Deposits some amount of ETH into a target account on L2. Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will be locked in the L2StandardBridge. ETH may be recoverable if the call can be successfully replayed by increasing the amount of gas supplied to the call. If the call will fail for any amount of gas, then the ETH will be locked permanently.\",\"params\":{\"_extraData\":\"Optional data to forward to L2. Data supplied here will not be used to execute any code on L2 and is only emitted as extra data for the convenience of off-chain tooling.\",\"_minGasLimit\":\"Minimum gas limit for the deposit message on L2.\",\"_to\":\"Address of the recipient on L2.\"}},\"finalizeBridgeERC20(address,address,address,address,uint256,bytes)\":{\"params\":{\"_amount\":\"Amount of the ERC20 being bridged.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_from\":\"Address of the sender.\",\"_localToken\":\"Address of the ERC20 on this chain.\",\"_remoteToken\":\"Address of the corresponding token on the remote chain.\",\"_to\":\"Address of the receiver.\"}},\"finalizeBridgeETH(address,address,uint256,bytes)\":{\"params\":{\"_amount\":\"Amount of ETH being bridged.\",\"_extraData\":\"Extra data to be sent with the transaction. Note that the recipient will not be triggered with this data, but it will be emitted and can be used to identify the transaction.\",\"_from\":\"Address of the sender.\",\"_to\":\"Address of the receiver.\"}},\"finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)\":{\"custom:legacy\":\"@notice Finalizes a withdrawal of ERC20 tokens from L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to withdraw.\",\"_extraData\":\"Optional data forwarded from L2.\",\"_from\":\"Address of the withdrawer on L2.\",\"_l1Token\":\"Address of the token on L1.\",\"_l2Token\":\"Address of the corresponding token on L2.\",\"_to\":\"Address of the recipient on L1.\"}},\"finalizeETHWithdrawal(address,address,uint256,bytes)\":{\"custom:legacy\":\"@notice Finalizes a withdrawal of ETH from L2.\",\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_extraData\":\"Optional data forwarded from L2.\",\"_from\":\"Address of the withdrawer on L2.\",\"_to\":\"Address of the recipient on L1.\"}},\"l2TokenBridge()\":{\"custom:legacy\":\"@notice Retrieves the access of the corresponding L2 bridge contract.\",\"returns\":{\"_0\":\"Address of the corresponding L2 bridge contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"MESSENGER()\":{\"notice\":\"Getter for messenger contract.\"},\"OTHER_BRIDGE()\":{\"notice\":\"Corresponding bridge on the other domain. This public getter is deprecated and will be removed in the future. Please use `otherBridge` instead. This can safely be an immutable because for the L1StandardBridge, it will be set to the L2StandardBridge address, which is the same for all OP Stack chains. For the L2StandardBridge, there are not multiple proxies using the same implementation.\"},\"bridgeERC20(address,address,uint256,uint32,bytes)\":{\"notice\":\"Sends ERC20 tokens to the sender's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain.\"},\"bridgeERC20To(address,address,address,uint256,uint32,bytes)\":{\"notice\":\"Sends ERC20 tokens to a receiver's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain.\"},\"bridgeETH(uint32,bytes)\":{\"notice\":\"Sends ETH to the sender's address on the other chain.\"},\"bridgeETHTo(address,uint32,bytes)\":{\"notice\":\"Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a smart contract and the call fails, the ETH will be temporarily locked in the StandardBridge on the other chain until the call is replayed. If the call cannot be replayed with any amount of gas (call always reverts), then the ETH will be permanently locked in the StandardBridge on the other chain. ETH will also be locked if the receiver is the other bridge, because finalizeBridgeETH will revert in that case.\"},\"constructor\":{\"notice\":\"Constructs the L1StandardBridge contract.\"},\"deposits(address,address)\":{\"notice\":\"Mapping that stores deposits for a given pair of local and remote tokens.\"},\"finalizeBridgeERC20(address,address,address,address,uint256,bytes)\":{\"notice\":\"Finalizes an ERC20 bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain.\"},\"finalizeBridgeETH(address,address,uint256,bytes)\":{\"notice\":\"Finalizes an ETH bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain.\"},\"initialize(address)\":{\"notice\":\"Initializer\"},\"messenger()\":{\"notice\":\"Messenger contract on this domain. This public getter is deprecated and will be removed in the future. Please use `messenger` instead.\"},\"otherBridge()\":{\"notice\":\"Getter for the remote domain bridge contract.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L1StandardBridge.sol\":\"L1StandardBridge\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"urls\":[\"bzz-raw://11756f42121f6541a35a8339ea899ee7514cfaa2e6d740625fcc844419296aa6\",\"dweb:/ipfs/QmekMuk6BY4DAjzeXr4MSbKdgoqqsZnA8JPtuyWc6CwXHf\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol\":{\"keccak256\":\"0xc65c83c1039508fa7a42a09a3c6a32babd1c438ba4dbb23581255e784b5d5eed\",\"urls\":[\"bzz-raw://a1b3b38db0f76429db899909025e534c366415e9ea8b5ddc4c8901e6a7fc1461\",\"dweb:/ipfs/QmYv1KxyHjLEky9JWNSsSfpGJbiCxFyzVFgTwQKpiqYGUg\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L1StandardBridge.sol\":{\"keccak256\":\"0x6838bb9b120c2c55e5f86591180053fd213141310c59a7856c55289079e26818\",\"urls\":[\"bzz-raw://193330432139af7aa03e97e0bb451c8204cc0f63452edc2312fe9465f36cf48c\",\"dweb:/ipfs/Qmchazs1JtQ84dCjVUFFHFQxpL8Byh4RCEWVGVfXqZbPNi\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/Predeploys.sol\":{\"keccak256\":\"0x5af3a849f68f7c9108858ebac5c769da8f1c0309b5c0cb42eb5cbb15e3fe6058\",\"urls\":[\"bzz-raw://6ffe76429a96d274577be66627eddad5cd05ad36d0cb6b9b3c3f9fa8a609dd7e\",\"dweb:/ipfs/QmVhWnB7Avg684TEQ9BExWqSN1YfLehUTWoqpjymeQEQHm\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/universal/CrossDomainMessenger.sol\":{\"keccak256\":\"0x4302ae78bcafde2737d4048bbf8fdb3dd4cd7254c015b91dfa14fdaafd412f4a\",\"urls\":[\"bzz-raw://78d3d1823ad4e1fba15921a0a361b452c85d111e2d53cbbed11a8632782ea8f3\",\"dweb:/ipfs/QmVc2rTRpn7g7WAUxDShSuy6dY5zmtbJ7hHC6sT9PcD3Gj\"],\"license\":\"MIT\"},\"src/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x6f8133b39efcbcbd5088f195dfacf1bedc3146508429c3865443909af735a04c\",\"urls\":[\"bzz-raw://adc36971e2e120458769f050428d9d2b0504516660345020c2521ee46e6d8abf\",\"dweb:/ipfs/QmPbFusQkZgGKpU8Fv5JoqL4oVeJtM3yqnhRGLY9eZT5zZ\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x39af021e492020fbeb5401371010d4a2fb69debe9596dbbead7bcd7fae248b0b\",\"urls\":[\"bzz-raw://dbeea52e586d2d7de55491a660ca76f75167ba6b43b65d29564864ee9c34a174\",\"dweb:/ipfs/QmS23vFqQxyUXhGuV1nSowZZS93CUkSnsb41uuyRtSeAED\"],\"license\":\"MIT\"},\"src/universal/Semver.sol\":{\"keccak256\":\"0x9de68ce536aee1aa616b4bf88d7ccc335460e6edd0e7170bdbf94c4fe3d41c60\",\"urls\":[\"bzz-raw://d5909c0b049b03a2bc24816ecf15b0aaf18c04a963174e1eba7624321bef330d\",\"dweb:/ipfs/QmeqdutwZWHqQMXauNR6WY8PrUpfsTiWTQyanbnGM9QqzT\"],\"license\":\"MIT\"},\"src/universal/StandardBridge.sol\":{\"keccak256\":\"0xc6ab09f73ee243757df19b3304b6ca289af84c2ce3ea4bf370a89c39c6ae5b04\",\"urls\":[\"bzz-raw://f5a3a6a7240ddb7c78b446e0647b7f5e7a8948b368a59d433efd70e927ea5c32\",\"dweb:/ipfs/QmVjEgX5LtCKz7HauTag8ukFgt5edPCVAsve6Mb3mKnXJN\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 6, - "receipt": { - "transactionHash": "0x72a6b58c6177e96088d47729d5d71bd13513ad5c923d45999a928dc8dc2c8c51", - "transactionIndex": "0x5", - "blockHash": "0x1757e9d553875bd033f03f68b1e4494db5258e626f0853156717dd64b6cdb98a", - "blockNumber": "0x438a06", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "cumulativeGasUsed": "0x2ec846", - "gasUsed": "0x24c685", - "contractAddress": "0xcfBCbA6d9E84A3c4FaE0eda9684cE39a09aa2c8A", - "logs": [ - { - "address": "0xcfBCbA6d9E84A3c4FaE0eda9684cE39a09aa2c8A", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000003", - "blockHash": "0x1757e9d553875bd033f03f68b1e4494db5258e626f0853156717dd64b6cdb98a", - "blockNumber": "0x438a06", - "transactionHash": "0x72a6b58c6177e96088d47729d5d71bd13513ad5c923d45999a928dc8dc2c8c51", - "transactionIndex": "0x5", - "logIndex": "0x1a", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb3abbc06" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 78131, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "spacer_0_2_20", - "offset": 2, - "slot": "0", - "type": "t_address" - }, - { - "astId": 78134, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "spacer_1_0_20", - "offset": 0, - "slot": "1", - "type": "t_address" - }, - { - "astId": 78141, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "deposits", - "offset": 0, - "slot": "2", - "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" - }, - { - "astId": 78145, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "messenger", - "offset": 0, - "slot": "3", - "type": "t_contract(CrossDomainMessenger)76013" - }, - { - "astId": 78150, - "contract": "src/L1/L1StandardBridge.sol:L1StandardBridge", - "label": "__gap", - "offset": 0, - "slot": "4", - "type": "t_array(t_uint256)46_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)46_storage": { - "encoding": "inplace", - "label": "uint256[46]", - "numberOfBytes": "1472", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(CrossDomainMessenger)76013": { - "encoding": "inplace", - "label": "contract CrossDomainMessenger", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_mapping(t_address,t_uint256))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => uint256))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_uint256)" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x72a6b58c6177e96088d47729d5d71bd13513ad5c923d45999a928dc8dc2c8c51", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "MESSENGER()": { - "notice": "Getter for messenger contract." - }, - "OTHER_BRIDGE()": { - "notice": "Corresponding bridge on the other domain. This public getter is deprecated and will be removed in the future. Please use `otherBridge` instead. This can safely be an immutable because for the L1StandardBridge, it will be set to the L2StandardBridge address, which is the same for all OP Stack chains. For the L2StandardBridge, there are not multiple proxies using the same implementation." - }, - "bridgeERC20(address,address,uint256,uint32,bytes)": { - "notice": "Sends ERC20 tokens to the sender's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain." - }, - "bridgeERC20To(address,address,address,uint256,uint32,bytes)": { - "notice": "Sends ERC20 tokens to a receiver's address on the other chain. Note that if the ERC20 token on the other chain does not recognize the local token as the correct pair token, the ERC20 bridge will fail and the tokens will be returned to sender on this chain." - }, - "bridgeETH(uint32,bytes)": { - "notice": "Sends ETH to the sender's address on the other chain." - }, - "bridgeETHTo(address,uint32,bytes)": { - "notice": "Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a smart contract and the call fails, the ETH will be temporarily locked in the StandardBridge on the other chain until the call is replayed. If the call cannot be replayed with any amount of gas (call always reverts), then the ETH will be permanently locked in the StandardBridge on the other chain. ETH will also be locked if the receiver is the other bridge, because finalizeBridgeETH will revert in that case." - }, - "constructor": { - "notice": "Constructs the L1StandardBridge contract." - }, - "deposits(address,address)": { - "notice": "Mapping that stores deposits for a given pair of local and remote tokens." - }, - "finalizeBridgeERC20(address,address,address,address,uint256,bytes)": { - "notice": "Finalizes an ERC20 bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain." - }, - "finalizeBridgeETH(address,address,uint256,bytes)": { - "notice": "Finalizes an ETH bridge on this chain. Can only be triggered by the other StandardBridge contract on the remote chain." - }, - "initialize(address)": { - "notice": "Initializer" - }, - "messenger()": { - "notice": "Messenger contract on this domain. This public getter is deprecated and will be removed in the future. Please use `messenger` instead." - }, - "otherBridge()": { - "notice": "Getter for the remote domain bridge contract." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ERC20BridgeFinalized(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC20 bridge is finalized on this chain." - }, - "ERC20BridgeInitiated(address,address,address,address,uint256,bytes)": { - "notice": "Emitted when an ERC20 bridge is initiated to the other chain." - }, - "ETHBridgeFinalized(address,address,uint256,bytes)": { - "notice": "Emitted when an ETH bridge is finalized on this chain." - }, - "ETHBridgeInitiated(address,address,uint256,bytes)": { - "notice": "Emitted when an ETH bridge is initiated to the other chain." - } - }, - "notice": "The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and L2. In the case that an ERC20 token is native to L1, it will be escrowed within this contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was stored within this contract. After Bedrock, ETH is instead stored inside the OptimismPortal contract. NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples of some token types that may not be properly supported by this contract include, but are not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/L1StandardBridgeProxy.json b/packages/contracts-bedrock/deployments/sepolia/L1StandardBridgeProxy.json deleted file mode 100644 index a1911106523e..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/L1StandardBridgeProxy.json +++ /dev/null @@ -1,182 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_code", - "type": "bytes" - } - ], - "name": "setCode", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_key", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_value", - "type": "bytes32" - } - ], - "name": "setStorage", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", - "args": [ - "0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc" - ], - "bytecode": "0x608060405234801561001057600080fd5b50604051610a44380380610a4483398101604081905261002f9161005d565b610057817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b5061008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b6109a88061009c6000396000f3fe60806040526004361061005e5760003560e01c8063893d20e811610043578063893d20e8146100b55780639b0b0fda146100f3578063aaf10f42146101135761006d565b806313af4035146100755780636c5d4ad0146100955761006d565b3661006d5761006b610128565b005b61006b610128565b34801561008157600080fd5b5061006b6100903660046107a2565b6103cb565b3480156100a157600080fd5b5061006b6100b036600461080e565b61045c565b3480156100c157600080fd5b506100ca610611565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ff57600080fd5b5061006b61010e3660046108dd565b6106a8565b34801561011f57600080fd5b506100ca610716565b60006101527fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb7947262000000000000000000000000000000000000000000000000000000001790529051919250600091829173ffffffffffffffffffffffffffffffffffffffff8516916101d4919061093a565b600060405180830381855afa9150503d806000811461020f576040519150601f19603f3d011682016040523d82523d6000602084013e610214565b606091505b5091509150818015610227575080516020145b156102d9576000818060200190518101906102429190610946565b905080156102d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d2069732063757260448201527f72656e746c79206265696e67207570677261646564000000000000000000000060648201526084015b60405180910390fd5b505b60006103037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166103a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201527f6e206973206e6f7420736574207965740000000000000000000000000000000060648201526084016102ce565b3660008037600080366000845af43d6000803e806103c5573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610424575033155b1561045457610451817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b50565b610451610128565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104b5575033155b156104545760006104e47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b9050803f82516020840120036104f8575050565b60405160009061052e907f600d380380600d6000396000f30000000000000000000000000000000000000090859060200161095f565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146105e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527f636f72726563746c79206465706c6f796564000000000000000000000000000060648201526084016102ce565b61060b817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50505050565b600061063b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610672575033155b1561069d57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6106a5610128565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610701575033155b1561070a579055565b610712610128565b5050565b60006107407fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610777575033155b1561069d57507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000602082840312156107b457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146107d857600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561082057600080fd5b813567ffffffffffffffff8082111561083857600080fd5b818401915084601f83011261084c57600080fd5b81358181111561085e5761085e6107df565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108a4576108a46107df565b816040528281528760208487010111156108bd57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156108f057600080fd5b50508035926020909101359150565b6000815160005b818110156109205760208185018101518683015201610906565b8181111561092f576000828601525b509290920192915050565b60006107d882846108ff565b60006020828403121561095857600080fd5b5051919050565b7fffffffffffffffffffffffffff00000000000000000000000000000000000000831681526000610993600d8301846108ff565b94935050505056fea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c8063893d20e811610043578063893d20e8146100b55780639b0b0fda146100f3578063aaf10f42146101135761006d565b806313af4035146100755780636c5d4ad0146100955761006d565b3661006d5761006b610128565b005b61006b610128565b34801561008157600080fd5b5061006b6100903660046107a2565b6103cb565b3480156100a157600080fd5b5061006b6100b036600461080e565b61045c565b3480156100c157600080fd5b506100ca610611565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ff57600080fd5b5061006b61010e3660046108dd565b6106a8565b34801561011f57600080fd5b506100ca610716565b60006101527fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb7947262000000000000000000000000000000000000000000000000000000001790529051919250600091829173ffffffffffffffffffffffffffffffffffffffff8516916101d4919061093a565b600060405180830381855afa9150503d806000811461020f576040519150601f19603f3d011682016040523d82523d6000602084013e610214565b606091505b5091509150818015610227575080516020145b156102d9576000818060200190518101906102429190610946565b905080156102d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d2069732063757260448201527f72656e746c79206265696e67207570677261646564000000000000000000000060648201526084015b60405180910390fd5b505b60006103037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166103a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201527f6e206973206e6f7420736574207965740000000000000000000000000000000060648201526084016102ce565b3660008037600080366000845af43d6000803e806103c5573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610424575033155b1561045457610451817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b50565b610451610128565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104b5575033155b156104545760006104e47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b9050803f82516020840120036104f8575050565b60405160009061052e907f600d380380600d6000396000f30000000000000000000000000000000000000090859060200161095f565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146105e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527f636f72726563746c79206465706c6f796564000000000000000000000000000060648201526084016102ce565b61060b817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50505050565b600061063b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610672575033155b1561069d57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6106a5610128565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610701575033155b1561070a579055565b610712610128565b5050565b60006107407fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610777575033155b1561069d57507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000602082840312156107b457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146107d857600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561082057600080fd5b813567ffffffffffffffff8082111561083857600080fd5b818401915084601f83011261084c57600080fd5b81358181111561085e5761085e6107df565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108a4576108a46107df565b816040528281528760208487010111156108bd57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156108f057600080fd5b50508035926020909101359150565b6000815160005b818110156109205760208185018101518683015201610906565b8181111561092f576000828601525b509290920192915050565b60006107d882846108ff565b60006020828403121561095857600080fd5b5051919050565b7fffffffffffffffffffffffffff00000000000000000000000000000000000000831681526000610993600d8301846108ff565b94935050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "constructor": { - "params": { - "_owner": "Address of the initial contract owner." - } - }, - "getImplementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "getOwner()": { - "returns": { - "_0": "Owner address." - } - }, - "setCode(bytes)": { - "params": { - "_code": "New contract code to run inside this contract." - } - }, - "setOwner(address)": { - "params": { - "_owner": "New owner of the proxy contract." - } - }, - "setStorage(bytes32,bytes32)": { - "params": { - "_key": "Storage key to modify.", - "_value": "New value for the storage key." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"getImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setCode\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setOwner\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_value\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setStorage\"},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_owner\":\"Address of the initial contract owner.\"}},\"getImplementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"getOwner()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"setCode(bytes)\":{\"params\":{\"_code\":\"New contract code to run inside this contract.\"}},\"setOwner(address)\":{\"params\":{\"_owner\":\"New owner of the proxy contract.\"}},\"setStorage(bytes32,bytes32)\":{\"params\":{\"_key\":\"Storage key to modify.\",\"_value\":\"New value for the storage key.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getImplementation()\":{\"notice\":\"Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"getOwner()\":{\"notice\":\"Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"setCode(bytes)\":{\"notice\":\"Sets the code that should be running behind this proxy. Note: This scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner.\"},\"setOwner(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"setStorage(bytes32,bytes32)\":{\"notice\":\"Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/legacy/L1ChugSplashProxy.sol\":\"L1ChugSplashProxy\"},\"libraries\":{}},\"sources\":{\"src/legacy/L1ChugSplashProxy.sol\":{\"keccak256\":\"0x102ea9c1eac2bbc071e38fdcc8d92deda3e7f32dc72d57fa3fe315cef354a5fe\",\"urls\":[\"bzz-raw://42efc6f277dd5f9ed874dbc6e214d481a26cc71751d505a75b44d86ecf8e4815\",\"dweb:/ipfs/QmUZLYii4uBr5JrWz8NTaaYkX56VvygKSqziKqGHuzM2Wr\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": { - "transactionHash": "0x736c5d873360bd726f70311303b34d4beb022b23bd87b2684723d14067e6e143", - "transactionIndex": "0x8", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0x5add2a", - "gasUsed": "0x94b82", - "contractAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xbec78df7" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [], - "types": {} - }, - "transactionHash": "0x736c5d873360bd726f70311303b34d4beb022b23bd87b2684723d14067e6e143", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "getImplementation()": { - "notice": "Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)." - }, - "getOwner()": { - "notice": "Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)." - }, - "setCode(bytes)": { - "notice": "Sets the code that should be running behind this proxy. Note: This scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner." - }, - "setOwner(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "setStorage(bytes32,bytes32)": { - "notice": "Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner." - } - }, - "notice": "Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!" - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/L2OutputOracle.json b/packages/contracts-bedrock/deployments/sepolia/L2OutputOracle.json deleted file mode 100644 index bcc14146d2a1..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/L2OutputOracle.json +++ /dev/null @@ -1,846 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "uint256", - "name": "_submissionInterval", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_l2BlockTime", - "type": "uint256" - }, - { - "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": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "l2OutputIndex", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "l2BlockNumber", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "l1Timestamp", - "type": "uint256" - } - ], - "name": "OutputProposed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "prevNextOutputIndex", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "newNextOutputIndex", - "type": "uint256" - } - ], - "name": "OutputsDeleted", - "type": "event" - }, - { - "inputs": [], - "name": "CHALLENGER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "FINALIZATION_PERIOD_SECONDS", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_BLOCK_TIME", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PROPOSER", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SUBMISSION_INTERVAL", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "challenger", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - } - ], - "name": "computeL2Timestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - } - ], - "name": "deleteL2Outputs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "finalizationPeriodSeconds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - } - ], - "name": "getL2Output", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint128", - "name": "timestamp", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "l2BlockNumber", - "type": "uint128" - } - ], - "internalType": "struct Types.OutputProposal", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - } - ], - "name": "getL2OutputAfter", - "outputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint128", - "name": "timestamp", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "l2BlockNumber", - "type": "uint128" - } - ], - "internalType": "struct Types.OutputProposal", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - } - ], - "name": "getL2OutputIndexAfter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_startingBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_startingTimestamp", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_proposer", - "type": "address" - }, - { - "internalType": "address", - "name": "_challenger", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l2BlockTime", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "latestBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "latestOutputIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nextBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nextOutputIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_l2BlockNumber", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_l1BlockHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_l1BlockNumber", - "type": "uint256" - } - ], - "name": "proposeL2Output", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "proposer", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "startingBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "startingTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "submissionInterval", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0xdb515F91fAA93d894586bA45FEe58d511FDAEC32", - "args": [], - "bytecode": "0x60e06040523480156200001157600080fd5b50604051620018ae380380620018ae8339810160408190526200003491620002f3565b60008211620000b05760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e203000000000000000000000000060648201526084015b60405180910390fd5b60008311620001285760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e20300000000000006064820152608401620000a7565b608083905260a082905260c08190526200014660008080806200014f565b50505062000322565b600054600390610100900460ff1615801562000172575060005460ff8083169116105b620001d75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000a7565b6000805461ffff191660ff83161761010017905542841115620002715760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401620000a7565b60028490556001859055600580546001600160a01b038581166001600160a01b03199283161790925560048054928516929091169190911790556000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6000806000606084860312156200030957600080fd5b8351925060208401519150604084015190509250925092565b60805160a05160c0516115326200037c600039600081816104b3015281816105710152610beb0152600081816101a1015281816103b9015261127401526000818161021f0152818161053b01526112c201526115326000f3fe60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec334814610517578063e1a41bcf1461052c578063f4daa2911461055f57600080fd5b8063ce5db8d6146104a4578063cf8e5cf0146104d7578063d1de856c146104f757600080fd5b8063a25ae557116100b0578063a25ae557146103f0578063a8e4fb901461044c578063bffa7f0f1461047957600080fd5b806389c44cbb1461038a57806393991af3146103aa5780639aaab648146103dd57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa51461033e5780637f00642014610354578063887862721461037457600080fd5b806369f16eec146102e95780636abcf563146102fe5780636b4d98dd1461031357600080fd5b8063529933df11610169578063529933df1461020d578063534db0e21461024157806354fd4d501461029357600080fd5b80622134cc1461018f578063019e2729146101d65780634599c788146101f8575b600080fd5b34801561019b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101e257600080fd5b506101f66101f136600461131c565b610593565b005b34801561020457600080fd5b506101c36107f2565b34801561021957600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561024d57600080fd5b5060045461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cd565b34801561029f57600080fd5b506102dc6040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101cd9190611362565b3480156102f557600080fd5b506101c3610865565b34801561030a57600080fd5b506003546101c3565b34801561031f57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1661026e565b34801561034a57600080fd5b506101c360015481565b34801561036057600080fd5b506101c361036f3660046113d5565b610877565b34801561038057600080fd5b506101c360025481565b34801561039657600080fd5b506101f66103a53660046113d5565b610a8b565b3480156103b657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b6101f66103eb3660046113ee565b610d43565b3480156103fc57600080fd5b5061041061040b3660046113d5565b6111a4565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101cd565b34801561045857600080fd5b5060055461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561048557600080fd5b5060055473ffffffffffffffffffffffffffffffffffffffff1661026e565b3480156104b057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b3480156104e357600080fd5b506104106104f23660046113d5565b611238565b34801561050357600080fd5b506101c36105123660046113d5565b611270565b34801561052357600080fd5b506101c36112be565b34801561053857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b34801561056b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b600054600390610100900460ff161580156105b5575060005460ff8083169116105b610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790554284111561072e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161063d565b600284905560018590556005805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556004805492851692909116919091179055600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6003546000901561085c576003805461080d9060019061144f565b8154811061081d5761081d611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b6003546000906108609060019061144f565b60006108816107f2565b821115610936576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546109eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546000905b80821015610a845760006002610a088385611495565b610a1291906114ad565b90508460038281548110610a2857610a28611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610a7a57610a73816001611495565b9250610a7e565b8091505b506109f2565b5092915050565b60045473ffffffffffffffffffffffffffffffffffffffff163314610b32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161063d565b6003548110610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b7f000000000000000000000000000000000000000000000000000000000000000060038281548110610c1d57610c1d611466565b6000918252602090912060016002909202010154610c4d906fffffffffffffffffffffffffffffffff164261144f565b10610d00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161063d565b6000610d0b60035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60055473ffffffffffffffffffffffffffffffffffffffff163314610e10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b610e186112be565b8314610ecc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161063d565b42610ed684611270565b10610f63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161063d565b83610ff0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161063d565b81156110ac57818140146110ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161063d565b826110b660035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2426040516110e891815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b6040805160608101825260008082526020820181905291810191909152600382815481106111d4576111d4611466565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b6040805160608101825260008082526020820181905291810191909152600361126083610877565b815481106111d4576111d4611466565b60007f0000000000000000000000000000000000000000000000000000000000000000600154836112a1919061144f565b6112ab91906114e8565b6002546112b89190611495565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006112e96107f2565b6108609190611495565b803573ffffffffffffffffffffffffffffffffffffffff8116811461131757600080fd5b919050565b6000806000806080858703121561133257600080fd5b8435935060208501359250611349604086016112f3565b9150611357606086016112f3565b905092959194509250565b600060208083528351808285015260005b8181101561138f57858101830151858201604001528201611373565b818111156113a1576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156113e757600080fd5b5035919050565b6000806000806080858703121561140457600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561146157611461611420565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082198211156114a8576114a8611420565b500190565b6000826114e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561152057611520611420565b50029056fea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec334814610517578063e1a41bcf1461052c578063f4daa2911461055f57600080fd5b8063ce5db8d6146104a4578063cf8e5cf0146104d7578063d1de856c146104f757600080fd5b8063a25ae557116100b0578063a25ae557146103f0578063a8e4fb901461044c578063bffa7f0f1461047957600080fd5b806389c44cbb1461038a57806393991af3146103aa5780639aaab648146103dd57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa51461033e5780637f00642014610354578063887862721461037457600080fd5b806369f16eec146102e95780636abcf563146102fe5780636b4d98dd1461031357600080fd5b8063529933df11610169578063529933df1461020d578063534db0e21461024157806354fd4d501461029357600080fd5b80622134cc1461018f578063019e2729146101d65780634599c788146101f8575b600080fd5b34801561019b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101e257600080fd5b506101f66101f136600461131c565b610593565b005b34801561020457600080fd5b506101c36107f2565b34801561021957600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561024d57600080fd5b5060045461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cd565b34801561029f57600080fd5b506102dc6040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101cd9190611362565b3480156102f557600080fd5b506101c3610865565b34801561030a57600080fd5b506003546101c3565b34801561031f57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1661026e565b34801561034a57600080fd5b506101c360015481565b34801561036057600080fd5b506101c361036f3660046113d5565b610877565b34801561038057600080fd5b506101c360025481565b34801561039657600080fd5b506101f66103a53660046113d5565b610a8b565b3480156103b657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b6101f66103eb3660046113ee565b610d43565b3480156103fc57600080fd5b5061041061040b3660046113d5565b6111a4565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101cd565b34801561045857600080fd5b5060055461026e9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561048557600080fd5b5060055473ffffffffffffffffffffffffffffffffffffffff1661026e565b3480156104b057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b3480156104e357600080fd5b506104106104f23660046113d5565b611238565b34801561050357600080fd5b506101c36105123660046113d5565b611270565b34801561052357600080fd5b506101c36112be565b34801561053857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101c3565b34801561056b57600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b600054600390610100900460ff161580156105b5575060005460ff8083169116105b610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790554284111561072e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161063d565b600284905560018590556005805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556004805492851692909116919091179055600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6003546000901561085c576003805461080d9060019061144f565b8154811061081d5761081d611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b6003546000906108609060019061144f565b60006108816107f2565b821115610936576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546109eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161063d565b6003546000905b80821015610a845760006002610a088385611495565b610a1291906114ad565b90508460038281548110610a2857610a28611466565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610a7a57610a73816001611495565b9250610a7e565b8091505b506109f2565b5092915050565b60045473ffffffffffffffffffffffffffffffffffffffff163314610b32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161063d565b6003548110610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b7f000000000000000000000000000000000000000000000000000000000000000060038281548110610c1d57610c1d611466565b6000918252602090912060016002909202010154610c4d906fffffffffffffffffffffffffffffffff164261144f565b10610d00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161063d565b6000610d0b60035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60055473ffffffffffffffffffffffffffffffffffffffff163314610e10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161063d565b610e186112be565b8314610ecc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161063d565b42610ed684611270565b10610f63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161063d565b83610ff0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161063d565b81156110ac57818140146110ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161063d565b826110b660035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e2426040516110e891815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b6040805160608101825260008082526020820181905291810191909152600382815481106111d4576111d4611466565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b6040805160608101825260008082526020820181905291810191909152600361126083610877565b815481106111d4576111d4611466565b60007f0000000000000000000000000000000000000000000000000000000000000000600154836112a1919061144f565b6112ab91906114e8565b6002546112b89190611495565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006112e96107f2565b6108609190611495565b803573ffffffffffffffffffffffffffffffffffffffff8116811461131757600080fd5b919050565b6000806000806080858703121561133257600080fd5b8435935060208501359250611349604086016112f3565b9150611357606086016112f3565b905092959194509250565b600060208083528351808285015260005b8181101561138f57858101830151858201604001528201611373565b818111156113a1576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156113e757600080fd5b5035919050565b6000806000806080858703121561140457600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561146157611461611420565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082198211156114a8576114a8611420565b500190565b6000826114e3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561152057611520611420565b50029056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "CHALLENGER()": {}, - "PROPOSER()": {}, - "computeL2Timestamp(uint256)": { - "params": { - "_l2BlockNumber": "The L2 block number of the target block." - }, - "returns": { - "_0": "L2 timestamp of the given block." - } - }, - "constructor": { - "params": { - "_finalizationPeriodSeconds": "The amount of time that must pass for an output proposal", - "_l2BlockTime": "The time per L2 block, in seconds.", - "_submissionInterval": "Interval in blocks at which checkpoints must be submitted." - } - }, - "deleteL2Outputs(uint256)": { - "params": { - "_l2OutputIndex": "Index of the first L2 output to be deleted. All outputs after this output will also be deleted." - } - }, - "getL2Output(uint256)": { - "params": { - "_l2OutputIndex": "Index of the output to return." - }, - "returns": { - "_0": "The output at the given index." - } - }, - "getL2OutputAfter(uint256)": { - "params": { - "_l2BlockNumber": "L2 block number to find a checkpoint for." - }, - "returns": { - "_0": "First checkpoint that commits to the given L2 block number." - } - }, - "getL2OutputIndexAfter(uint256)": { - "params": { - "_l2BlockNumber": "L2 block number to find a checkpoint for." - }, - "returns": { - "_0": "Index of the first checkpoint that commits to the given L2 block number." - } - }, - "initialize(uint256,uint256,address,address)": { - "params": { - "_challenger": "The address of the challenger.", - "_proposer": "The address of the proposer.", - "_startingBlockNumber": "Block number for the first recoded L2 block.", - "_startingTimestamp": "Timestamp for the first recoded L2 block." - } - }, - "latestBlockNumber()": { - "returns": { - "_0": "Latest submitted L2 block number." - } - }, - "latestOutputIndex()": { - "returns": { - "_0": "The number of outputs that have been proposed." - } - }, - "nextBlockNumber()": { - "returns": { - "_0": "Next L2 block number." - } - }, - "nextOutputIndex()": { - "returns": { - "_0": "The index of the next output to be proposed." - } - }, - "proposeL2Output(bytes32,uint256,bytes32,uint256)": { - "params": { - "_l1BlockHash": "A block hash which must be included in the current chain.", - "_l1BlockNumber": "The block number with the specified block hash.", - "_l2BlockNumber": "The L2 block number that resulted in _outputRoot.", - "_outputRoot": "The L2 output of the checkpoint block." - } - } - }, - "events": { - "OutputProposed(bytes32,uint256,uint256,uint256)": { - "params": { - "l1Timestamp": "The L1 timestamp when proposed.", - "l2BlockNumber": "The L2 block number of the output root.", - "l2OutputIndex": "The index of the output in the l2Outputs array.", - "outputRoot": "The output root." - } - }, - "OutputsDeleted(uint256,uint256)": { - "params": { - "newNextOutputIndex": "Next L2 output index after the deletion.", - "prevNextOutputIndex": "Next L2 output index before the deletion." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_submissionInterval\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_finalizationPeriodSeconds\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"l2OutputIndex\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"l2BlockNumber\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"l1Timestamp\",\"type\":\"uint256\",\"indexed\":false}],\"type\":\"event\",\"name\":\"OutputProposed\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"prevNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"newNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OutputsDeleted\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"CHALLENGER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L2_BLOCK_TIME\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"PROPOSER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"challenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"computeL2Timestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"deleteL2Outputs\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"finalizationPeriodSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getL2Output\",\"outputs\":[{\"internalType\":\"struct Types.OutputProposal\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}]}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getL2OutputAfter\",\"outputs\":[{\"internalType\":\"struct Types.OutputProposal\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2BlockNumber\",\"type\":\"uint128\"}]}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getL2OutputIndexAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_proposer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_challenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2BlockTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"latestBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"latestOutputIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"nextBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"nextOutputIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1BlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1BlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"proposeL2Output\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"proposer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"startingBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"startingTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"submissionInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"CHALLENGER()\":{\"custom:legacy\":\"\"},\"PROPOSER()\":{\"custom:legacy\":\"\"},\"computeL2Timestamp(uint256)\":{\"params\":{\"_l2BlockNumber\":\"The L2 block number of the target block.\"},\"returns\":{\"_0\":\"L2 timestamp of the given block.\"}},\"constructor\":{\"params\":{\"_finalizationPeriodSeconds\":\"The amount of time that must pass for an output proposal\",\"_l2BlockTime\":\"The time per L2 block, in seconds.\",\"_submissionInterval\":\"Interval in blocks at which checkpoints must be submitted.\"}},\"deleteL2Outputs(uint256)\":{\"params\":{\"_l2OutputIndex\":\"Index of the first L2 output to be deleted. All outputs after this output will also be deleted.\"}},\"getL2Output(uint256)\":{\"params\":{\"_l2OutputIndex\":\"Index of the output to return.\"},\"returns\":{\"_0\":\"The output at the given index.\"}},\"getL2OutputAfter(uint256)\":{\"params\":{\"_l2BlockNumber\":\"L2 block number to find a checkpoint for.\"},\"returns\":{\"_0\":\"First checkpoint that commits to the given L2 block number.\"}},\"getL2OutputIndexAfter(uint256)\":{\"params\":{\"_l2BlockNumber\":\"L2 block number to find a checkpoint for.\"},\"returns\":{\"_0\":\"Index of the first checkpoint that commits to the given L2 block number.\"}},\"initialize(uint256,uint256,address,address)\":{\"params\":{\"_challenger\":\"The address of the challenger.\",\"_proposer\":\"The address of the proposer.\",\"_startingBlockNumber\":\"Block number for the first recoded L2 block.\",\"_startingTimestamp\":\"Timestamp for the first recoded L2 block.\"}},\"latestBlockNumber()\":{\"returns\":{\"_0\":\"Latest submitted L2 block number.\"}},\"latestOutputIndex()\":{\"returns\":{\"_0\":\"The number of outputs that have been proposed.\"}},\"nextBlockNumber()\":{\"returns\":{\"_0\":\"Next L2 block number.\"}},\"nextOutputIndex()\":{\"returns\":{\"_0\":\"The index of the next output to be proposed.\"}},\"proposeL2Output(bytes32,uint256,bytes32,uint256)\":{\"params\":{\"_l1BlockHash\":\"A block hash which must be included in the current chain.\",\"_l1BlockNumber\":\"The block number with the specified block hash.\",\"_l2BlockNumber\":\"The L2 block number that resulted in _outputRoot.\",\"_outputRoot\":\"The L2 output of the checkpoint block.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"CHALLENGER()\":{\"notice\":\"Getter for the challenger address. This will be removed in the future, use `challenger` instead.\"},\"L2_BLOCK_TIME()\":{\"notice\":\"The time between L2 blocks in seconds. Once set, this value MUST NOT be modified. Public getter is legacy and will be removed in the future. Use `l2BlockTime` instead.\"},\"PROPOSER()\":{\"notice\":\"Getter for the proposer address. This will be removed in the future, use `proposer` instead.\"},\"SUBMISSION_INTERVAL()\":{\"notice\":\"The interval in L2 blocks at which checkpoints must be submitted. Although this is immutable, it can safely be modified by upgrading the implementation contract. Public getter is legacy and will be removed in the future. Use `submissionInterval` instead.\"},\"challenger()\":{\"notice\":\"The address of the challenger. Can be updated via reinitialize.\"},\"computeL2Timestamp(uint256)\":{\"notice\":\"Returns the L2 timestamp corresponding to a given L2 block number.\"},\"constructor\":{\"notice\":\"Constructs the L2OutputOracle contract.\"},\"deleteL2Outputs(uint256)\":{\"notice\":\"Deletes all output proposals after and including the proposal that corresponds to the given output index. Only the challenger address can delete outputs.\"},\"finalizationPeriodSeconds()\":{\"notice\":\"Getter for the finalization period.\"},\"getL2Output(uint256)\":{\"notice\":\"Returns an output by index. Needed to return a struct instead of a tuple.\"},\"getL2OutputAfter(uint256)\":{\"notice\":\"Returns the L2 output proposal that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block.\"},\"getL2OutputIndexAfter(uint256)\":{\"notice\":\"Returns the index of the L2 output that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block.\"},\"initialize(uint256,uint256,address,address)\":{\"notice\":\"Initializer.\"},\"l2BlockTime()\":{\"notice\":\"Getter for the L2 block time.\"},\"latestBlockNumber()\":{\"notice\":\"Returns the block number of the latest submitted L2 output proposal. If no proposals been submitted yet then this function will return the starting block number.\"},\"latestOutputIndex()\":{\"notice\":\"Returns the number of outputs that have been proposed. Will revert if no outputs have been proposed yet.\"},\"nextBlockNumber()\":{\"notice\":\"Computes the block number of the next L2 block that needs to be checkpointed.\"},\"nextOutputIndex()\":{\"notice\":\"Returns the index of the next output to be proposed.\"},\"proposeL2Output(bytes32,uint256,bytes32,uint256)\":{\"notice\":\"Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp must be equal to the current value returned by `nextTimestamp()` in order to be accepted. This function may only be called by the Proposer.\"},\"proposer()\":{\"notice\":\"The address of the proposer. Can be updated via reinitialize.\"},\"startingBlockNumber()\":{\"notice\":\"The number of the first L2 block recorded in this contract.\"},\"startingTimestamp()\":{\"notice\":\"The timestamp of the first L2 block recorded in this contract.\"},\"submissionInterval()\":{\"notice\":\"Getter for the output proposal submission interval.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/L2OutputOracle.sol\":\"L2OutputOracle\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L2OutputOracle.sol\":{\"keccak256\":\"0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705\",\"urls\":[\"bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc\",\"dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 6, - "receipt": { - "transactionHash": "0xc494caec7817d47e185549da36cfc2f66bddd139d1bb87af651b20eb94f9e2ac", - "transactionIndex": "0x6", - "blockHash": "0x30eaba364ea372999e21c65eeb06db7a6200a8de6b3bebf9d88175bdbe963346", - "blockNumber": "0x438a04", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "cumulativeGasUsed": "0x82f03b", - "gasUsed": "0x134500", - "contractAddress": "0xdb515F91fAA93d894586bA45FEe58d511FDAEC32", - "logs": [ - { - "address": "0xdb515F91fAA93d894586bA45FEe58d511FDAEC32", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000003", - "blockHash": "0x30eaba364ea372999e21c65eeb06db7a6200a8de6b3bebf9d88175bdbe963346", - "blockNumber": "0x438a04", - "transactionHash": "0xc494caec7817d47e185549da36cfc2f66bddd139d1bb87af651b20eb94f9e2ac", - "transactionIndex": "0x6", - "logIndex": "0xe", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000004000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb3c41425" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 59681, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "startingBlockNumber", - "offset": 0, - "slot": "1", - "type": "t_uint256" - }, - { - "astId": 59684, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "startingTimestamp", - "offset": 0, - "slot": "2", - "type": "t_uint256" - }, - { - "astId": 59689, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "l2Outputs", - "offset": 0, - "slot": "3", - "type": "t_array(t_struct(OutputProposal)71419_storage)dyn_storage" - }, - { - "astId": 59692, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "challenger", - "offset": 0, - "slot": "4", - "type": "t_address" - }, - { - "astId": 59695, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "proposer", - "offset": 0, - "slot": "5", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_struct(OutputProposal)71419_storage)dyn_storage": { - "encoding": "dynamic_array", - "label": "struct Types.OutputProposal[]", - "numberOfBytes": "32", - "base": "t_struct(OutputProposal)71419_storage" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_struct(OutputProposal)71419_storage": { - "encoding": "inplace", - "label": "struct Types.OutputProposal", - "numberOfBytes": "64", - "members": [ - { - "astId": 71414, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "outputRoot", - "offset": 0, - "slot": "0", - "type": "t_bytes32" - }, - { - "astId": 71416, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "timestamp", - "offset": 0, - "slot": "1", - "type": "t_uint128" - }, - { - "astId": 71418, - "contract": "src/L1/L2OutputOracle.sol:L2OutputOracle", - "label": "l2BlockNumber", - "offset": 16, - "slot": "1", - "type": "t_uint128" - } - ] - }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0xc494caec7817d47e185549da36cfc2f66bddd139d1bb87af651b20eb94f9e2ac", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "CHALLENGER()": { - "notice": "Getter for the challenger address. This will be removed in the future, use `challenger` instead." - }, - "L2_BLOCK_TIME()": { - "notice": "The time between L2 blocks in seconds. Once set, this value MUST NOT be modified. Public getter is legacy and will be removed in the future. Use `l2BlockTime` instead." - }, - "PROPOSER()": { - "notice": "Getter for the proposer address. This will be removed in the future, use `proposer` instead." - }, - "SUBMISSION_INTERVAL()": { - "notice": "The interval in L2 blocks at which checkpoints must be submitted. Although this is immutable, it can safely be modified by upgrading the implementation contract. Public getter is legacy and will be removed in the future. Use `submissionInterval` instead." - }, - "challenger()": { - "notice": "The address of the challenger. Can be updated via reinitialize." - }, - "computeL2Timestamp(uint256)": { - "notice": "Returns the L2 timestamp corresponding to a given L2 block number." - }, - "constructor": { - "notice": "Constructs the L2OutputOracle contract." - }, - "deleteL2Outputs(uint256)": { - "notice": "Deletes all output proposals after and including the proposal that corresponds to the given output index. Only the challenger address can delete outputs." - }, - "finalizationPeriodSeconds()": { - "notice": "Getter for the finalization period." - }, - "getL2Output(uint256)": { - "notice": "Returns an output by index. Needed to return a struct instead of a tuple." - }, - "getL2OutputAfter(uint256)": { - "notice": "Returns the L2 output proposal that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block." - }, - "getL2OutputIndexAfter(uint256)": { - "notice": "Returns the index of the L2 output that checkpoints a given L2 block number. Uses a binary search to find the first output greater than or equal to the given block." - }, - "initialize(uint256,uint256,address,address)": { - "notice": "Initializer." - }, - "l2BlockTime()": { - "notice": "Getter for the L2 block time." - }, - "latestBlockNumber()": { - "notice": "Returns the block number of the latest submitted L2 output proposal. If no proposals been submitted yet then this function will return the starting block number." - }, - "latestOutputIndex()": { - "notice": "Returns the number of outputs that have been proposed. Will revert if no outputs have been proposed yet." - }, - "nextBlockNumber()": { - "notice": "Computes the block number of the next L2 block that needs to be checkpointed." - }, - "nextOutputIndex()": { - "notice": "Returns the index of the next output to be proposed." - }, - "proposeL2Output(bytes32,uint256,bytes32,uint256)": { - "notice": "Accepts an outputRoot and the timestamp of the corresponding L2 block. The timestamp must be equal to the current value returned by `nextTimestamp()` in order to be accepted. This function may only be called by the Proposer." - }, - "proposer()": { - "notice": "The address of the proposer. Can be updated via reinitialize." - }, - "startingBlockNumber()": { - "notice": "The number of the first L2 block recorded in this contract." - }, - "startingTimestamp()": { - "notice": "The timestamp of the first L2 block recorded in this contract." - }, - "submissionInterval()": { - "notice": "Getter for the output proposal submission interval." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "OutputProposed(bytes32,uint256,uint256,uint256)": { - "notice": "Emitted when an output is proposed." - }, - "OutputsDeleted(uint256,uint256)": { - "notice": "Emitted when outputs are deleted." - } - }, - "notice": "The L2OutputOracle contains an array of L2 state outputs, where each output is a commitment to the state of the L2 chain. Other contracts like the OptimismPortal use these outputs to verify information about the state of L2." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/L2OutputOracleProxy.json b/packages/contracts-bedrock/deployments/sepolia/L2OutputOracleProxy.json deleted file mode 100644 index 3e73e4375384..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/L2OutputOracleProxy.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", - "args": [ - "0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc" - ], - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"AdminChanged\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Upgraded\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"changeAdmin\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"upgradeTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/Proxy.sol\":\"Proxy\"},\"libraries\":{}},\"sources\":{\"src/universal/Proxy.sol\":{\"keccak256\":\"0x783aed9ff90b38a9898be5fb18699b3b249f012bc2c33f6537e1ab9f6444478f\",\"urls\":[\"bzz-raw://b119b1b68874f4d92a89cc05a4f0d25da73a959747a81e26739739a52895b844\",\"dweb:/ipfs/QmbKZqMd6CsM7annE7bCXcCi72syJAX3qtuFNPEGMCp13W\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": { - "transactionHash": "0x5c4860af998f0dca2420d76b161bd5f0e051b1f78c2bce5a42fbfb3a755350a6", - "transactionIndex": "0x6", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0x4992f0", - "gasUsed": "0x7feb8", - "contractAddress": "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", - "logs": [ - { - "address": "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000189abaaaa82dfc015a588a7dbad6f13b1d3485bc", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "transactionHash": "0x5c4860af998f0dca2420d76b161bd5f0e051b1f78c2bce5a42fbfb3a755350a6", - "transactionIndex": "0x6", - "logIndex": "0x6", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xbec78df7" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [], - "types": {} - }, - "transactionHash": "0x5c4860af998f0dca2420d76b161bd5f0e051b1f78c2bce5a42fbfb3a755350a6", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/OptimismMintableERC20Factory.json b/packages/contracts-bedrock/deployments/sepolia/OptimismMintableERC20Factory.json deleted file mode 100644 index 766ba557a906..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/OptimismMintableERC20Factory.json +++ /dev/null @@ -1,385 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "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": "localToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "deployer", - "type": "address" - } - ], - "name": "OptimismMintableERC20Created", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "remoteToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "localToken", - "type": "address" - } - ], - "name": "StandardL2TokenCreated", - "type": "event" - }, - { - "inputs": [], - "name": "BRIDGE", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "bridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createOptimismMintableERC20", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "uint8", - "name": "_decimals", - "type": "uint8" - } - ], - "name": "createOptimismMintableERC20WithDecimals", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_remoteToken", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createStandardL2Token", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_bridge", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x373B66bd178cb2716D5A9596B1a42Ed39b87A535", - "args": [], - "bytecode": "0x608060405234801561001057600080fd5b5061001b6000610020565b610118565b600054600390610100900460ff16158015610042575060005460ff8083169116105b6100a95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805461010060ff841661ffff19909216821717610100600160b01b03191661ff0019620100006001600160a01b0387160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6123cf806101276000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b611ad880620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe6101406040523480156200001257600080fd5b5060405162001ad838038062001ad8833981016040819052620000359162000178565b600160026000858560036200004b8382620002b3565b5060046200005a8282620002b3565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037f565b80516001600160a01b0381168114620000a657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d357600080fd5b81516001600160401b0380821115620000f057620000f0620000ab565b604051601f8301601f19908116603f011681019082821181831017156200011b576200011b620000ab565b816040528381526020925086838588010111156200013857600080fd5b600091505b838210156200015c57858201830151818301840152908201906200013d565b838211156200016e5760008385830101525b9695505050505050565b600080600080600060a086880312156200019157600080fd5b6200019c866200008e565b9450620001ac602087016200008e565b60408701519094506001600160401b0380821115620001ca57600080fd5b620001d889838a01620000c1565b94506060880151915080821115620001ef57600080fd5b50620001fe88828901620000c1565b925050608086015160ff811681146200021657600080fd5b809150509295509295909350565b600181811c908216806200023957607f821691505b6020821081036200025a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ae57600081815260208120601f850160051c81016020861015620002895750805b601f850160051c820191505b81811015620002aa5782815560010162000295565b5050505b505050565b81516001600160401b03811115620002cf57620002cf620000ab565b620002e781620002e0845462000224565b8462000260565b602080601f8311600181146200031f5760008415620003065750858301515b600019600386901b1c1916600185901b178555620002aa565b600085815260208120601f198616915b8281101562000350578886015182559484019460019091019084016200032f565b50858210156200036f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003eb6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", - "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b611ad880620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe6101406040523480156200001257600080fd5b5060405162001ad838038062001ad8833981016040819052620000359162000178565b600160026000858560036200004b8382620002b3565b5060046200005a8282620002b3565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037f565b80516001600160a01b0381168114620000a657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d357600080fd5b81516001600160401b0380821115620000f057620000f0620000ab565b604051601f8301601f19908116603f011681019082821181831017156200011b576200011b620000ab565b816040528381526020925086838588010111156200013857600080fd5b600091505b838210156200015c57858201830151818301840152908201906200013d565b838211156200016e5760008385830101525b9695505050505050565b600080600080600060a086880312156200019157600080fd5b6200019c866200008e565b9450620001ac602087016200008e565b60408701519094506001600160401b0380821115620001ca57600080fd5b620001d889838a01620000c1565b94506060880151915080821115620001ef57600080fd5b50620001fe88828901620000c1565b925050608086015160ff811681146200021657600080fd5b809150509295509295909350565b600181811c908216806200023957607f821691505b6020821081036200025a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ae57600081815260208120601f850160051c81016020861015620002895750805b601f850160051c820191505b81811015620002aa5782815560010162000295565b5050505b505050565b81516001600160401b03811115620002cf57620002cf620000ab565b620002e781620002e0845462000224565b8462000260565b602080601f8311600181146200031f5760008415620003065750858301515b600019600386901b1c1916600185901b178555620002aa565b600085815260208120601f198616915b8281101562000350578886015182559484019460019091019084016200032f565b50858210156200036f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003eb6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "BRIDGE()": {}, - "createOptimismMintableERC20(address,string,string)": { - "params": { - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "createOptimismMintableERC20WithDecimals(address,string,string,uint8)": { - "params": { - "_decimals": "ERC20 decimals", - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "createStandardL2Token(address,string,string)": { - "params": { - "_name": "ERC20 name.", - "_remoteToken": "Address of the token on the remote chain.", - "_symbol": "ERC20 symbol." - }, - "returns": { - "_0": "Address of the newly created token." - } - }, - "initialize(address)": { - "params": { - "_bridge": "Address of the StandardBridge on this chain." - } - } - }, - "events": { - "OptimismMintableERC20Created(address,address,address)": { - "params": { - "deployer": "Address of the account that deployed the token.", - "localToken": "Address of the created token on the local chain.", - "remoteToken": "Address of the corresponding token on the remote chain." - } - }, - "StandardL2TokenCreated(address,address)": { - "params": { - "localToken": "Address of the created token on the local chain.", - "remoteToken": "Address of the token on the remote chain." - } - } - }, - "title": "OptimismMintableERC20Factory" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"OptimismMintableERC20Created\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"StandardL2TokenCreated\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"createOptimismMintableERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"_decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"createOptimismMintableERC20WithDecimals\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"createStandardL2Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"BRIDGE()\":{\"custom:legacy\":\"\"},\"createOptimismMintableERC20(address,string,string)\":{\"params\":{\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"createOptimismMintableERC20WithDecimals(address,string,string,uint8)\":{\"params\":{\"_decimals\":\"ERC20 decimals\",\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"createStandardL2Token(address,string,string)\":{\"custom:legacy\":\"@notice Creates an instance of the OptimismMintableERC20 contract. Legacy version of the newer createOptimismMintableERC20 function, which has a more intuitive name.\",\"params\":{\"_name\":\"ERC20 name.\",\"_remoteToken\":\"Address of the token on the remote chain.\",\"_symbol\":\"ERC20 symbol.\"},\"returns\":{\"_0\":\"Address of the newly created token.\"}},\"initialize(address)\":{\"params\":{\"_bridge\":\"Address of the StandardBridge on this chain.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BRIDGE()\":{\"notice\":\"Returns the address of the StandardBridge on this chain. This is a legacy getter, use `bridge` instead.\"},\"bridge()\":{\"notice\":\"Address of the StandardBridge on this chain.\"},\"constructor\":{\"notice\":\"The semver MUST be bumped any time that there is a change in the OptimismMintableERC20 token contract since this contract is responsible for deploying OptimismMintableERC20 contracts.\"},\"createOptimismMintableERC20(address,string,string)\":{\"notice\":\"Creates an instance of the OptimismMintableERC20 contract.\"},\"createOptimismMintableERC20WithDecimals(address,string,string,uint8)\":{\"notice\":\"Creates an instance of the OptimismMintableERC20 contract, with specified decimals.\"},\"initialize(address)\":{\"notice\":\"Initializer.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/OptimismMintableERC20Factory.sol\":\"OptimismMintableERC20Factory\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"urls\":[\"bzz-raw://43e46da9d9f49741ecd876a269e71bc7494058d7a8e9478429998adb5bc3eaa0\",\"dweb:/ipfs/QmUtp4cqzf22C5rJ76AabKADquGWcjsc33yjYXxXC4sDvy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"urls\":[\"bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638\",\"dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/universal/IOptimismMintableERC20.sol\":{\"keccak256\":\"0x6f8133b39efcbcbd5088f195dfacf1bedc3146508429c3865443909af735a04c\",\"urls\":[\"bzz-raw://adc36971e2e120458769f050428d9d2b0504516660345020c2521ee46e6d8abf\",\"dweb:/ipfs/QmPbFusQkZgGKpU8Fv5JoqL4oVeJtM3yqnhRGLY9eZT5zZ\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/universal/OptimismMintableERC20.sol\":{\"keccak256\":\"0x39af021e492020fbeb5401371010d4a2fb69debe9596dbbead7bcd7fae248b0b\",\"urls\":[\"bzz-raw://dbeea52e586d2d7de55491a660ca76f75167ba6b43b65d29564864ee9c34a174\",\"dweb:/ipfs/QmS23vFqQxyUXhGuV1nSowZZS93CUkSnsb41uuyRtSeAED\"],\"license\":\"MIT\"},\"src/universal/OptimismMintableERC20Factory.sol\":{\"keccak256\":\"0x60862069899142dc4803d5f5754fd22339980bf74cfc4e2573bb59ff88a99c69\",\"urls\":[\"bzz-raw://8018f9fb11105ab80d4d6fb0bceabf8435d20d0883efa95070ae9e9983e3895c\",\"dweb:/ipfs/Qmf2ghxThySJA1pRvZfj3Q9yJwAZHSxwXAV9GDEqXxEWY9\"],\"license\":\"MIT\"},\"src/universal/Semver.sol\":{\"keccak256\":\"0x9de68ce536aee1aa616b4bf88d7ccc335460e6edd0e7170bdbf94c4fe3d41c60\",\"urls\":[\"bzz-raw://d5909c0b049b03a2bc24816ecf15b0aaf18c04a963174e1eba7624321bef330d\",\"dweb:/ipfs/QmeqdutwZWHqQMXauNR6WY8PrUpfsTiWTQyanbnGM9QqzT\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 6, - "receipt": { - "transactionHash": "0x0185a08905c55ab2fd276ef7a9bae9365d5eeadaed0890326e73e6bb6c50cdd1", - "transactionIndex": "0x7", - "blockHash": "0x30eaba364ea372999e21c65eeb06db7a6200a8de6b3bebf9d88175bdbe963346", - "blockNumber": "0x438a04", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "cumulativeGasUsed": "0xa229d5", - "gasUsed": "0x1f399a", - "contractAddress": "0x373B66bd178cb2716D5A9596B1a42Ed39b87A535", - "logs": [ - { - "address": "0x373B66bd178cb2716D5A9596B1a42Ed39b87A535", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000003", - "blockHash": "0x30eaba364ea372999e21c65eeb06db7a6200a8de6b3bebf9d88175bdbe963346", - "blockNumber": "0x438a04", - "transactionHash": "0x0185a08905c55ab2fd276ef7a9bae9365d5eeadaed0890326e73e6bb6c50cdd1", - "transactionIndex": "0x7", - "logIndex": "0xf", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000800000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb3c41425" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 76782, - "contract": "src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory", - "label": "bridge", - "offset": 2, - "slot": "0", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x0185a08905c55ab2fd276ef7a9bae9365d5eeadaed0890326e73e6bb6c50cdd1", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "BRIDGE()": { - "notice": "Returns the address of the StandardBridge on this chain. This is a legacy getter, use `bridge` instead." - }, - "bridge()": { - "notice": "Address of the StandardBridge on this chain." - }, - "constructor": { - "notice": "The semver MUST be bumped any time that there is a change in the OptimismMintableERC20 token contract since this contract is responsible for deploying OptimismMintableERC20 contracts." - }, - "createOptimismMintableERC20(address,string,string)": { - "notice": "Creates an instance of the OptimismMintableERC20 contract." - }, - "createOptimismMintableERC20WithDecimals(address,string,string,uint8)": { - "notice": "Creates an instance of the OptimismMintableERC20 contract, with specified decimals." - }, - "initialize(address)": { - "notice": "Initializer." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "OptimismMintableERC20Created(address,address,address)": { - "notice": "Emitted whenever a new OptimismMintableERC20 is created." - } - }, - "notice": "OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20 contracts on the network it's deployed to. Simplifies the deployment process for users who may be less familiar with deploying smart contracts. Designed to be backwards compatible with the older StandardL2ERC20Factory contract." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/OptimismMintableERC20FactoryProxy.json b/packages/contracts-bedrock/deployments/sepolia/OptimismMintableERC20FactoryProxy.json deleted file mode 100644 index e9218419ef2f..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/OptimismMintableERC20FactoryProxy.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0x868D59fF9710159C2B330Cc0fBDF57144dD7A13b", - "args": [ - "0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc" - ], - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"AdminChanged\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Upgraded\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"changeAdmin\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"upgradeTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/Proxy.sol\":\"Proxy\"},\"libraries\":{}},\"sources\":{\"src/universal/Proxy.sol\":{\"keccak256\":\"0x783aed9ff90b38a9898be5fb18699b3b249f012bc2c33f6537e1ab9f6444478f\",\"urls\":[\"bzz-raw://b119b1b68874f4d92a89cc05a4f0d25da73a959747a81e26739739a52895b844\",\"dweb:/ipfs/QmbKZqMd6CsM7annE7bCXcCi72syJAX3qtuFNPEGMCp13W\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": { - "transactionHash": "0xb5cf29ab2fd0d1831f27e7be89ed597111a4662cf6c4a0ca86462e304f38c431", - "transactionIndex": "0xb", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0x67ebcd", - "gasUsed": "0x7feb8", - "contractAddress": "0x868D59fF9710159C2B330Cc0fBDF57144dD7A13b", - "logs": [ - { - "address": "0x868D59fF9710159C2B330Cc0fBDF57144dD7A13b", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000189abaaaa82dfc015a588a7dbad6f13b1d3485bc", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "transactionHash": "0xb5cf29ab2fd0d1831f27e7be89ed597111a4662cf6c4a0ca86462e304f38c431", - "transactionIndex": "0xb", - "logIndex": "0x9", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400800000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xbec78df7" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [], - "types": {} - }, - "transactionHash": "0xb5cf29ab2fd0d1831f27e7be89ed597111a4662cf6c4a0ca86462e304f38c431", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/OptimismPortal.json b/packages/contracts-bedrock/deployments/sepolia/OptimismPortal.json deleted file mode 100644 index 6077ca63f752..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/OptimismPortal.json +++ /dev/null @@ -1,999 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Paused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "version", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "opaqueData", - "type": "bytes" - } - ], - "name": "TransactionDeposited", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Unpaused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "withdrawalHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "name": "WithdrawalFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "withdrawalHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "WithdrawalProven", - "type": "event" - }, - { - "inputs": [], - "name": "GUARDIAN", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_ORACLE", - "outputs": [ - { - "internalType": "contract L2OutputOracle", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SYSTEM_CONFIG", - "outputs": [ - { - "internalType": "contract SystemConfig", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "_isCreation", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "depositTransaction", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "donateETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "internalType": "struct Types.WithdrawalTransaction", - "name": "_tx", - "type": "tuple" - } - ], - "name": "finalizeWithdrawalTransaction", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "finalizedWithdrawals", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "guardian", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract L2OutputOracle", - "name": "_l2Oracle", - "type": "address" - }, - { - "internalType": "address", - "name": "_guardian", - "type": "address" - }, - { - "internalType": "contract SystemConfig", - "name": "_systemConfig", - "type": "address" - }, - { - "internalType": "bool", - "name": "_paused", - "type": "bool" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - } - ], - "name": "isOutputFinalized", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l2Oracle", - "outputs": [ - { - "internalType": "contract L2OutputOracle", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l2Sender", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "_byteCount", - "type": "uint64" - } - ], - "name": "minimumGasLimit", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "params", - "outputs": [ - { - "internalType": "uint128", - "name": "prevBaseFee", - "type": "uint128" - }, - { - "internalType": "uint64", - "name": "prevBoughtGas", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "prevBlockNum", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "paused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasLimit", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "internalType": "struct Types.WithdrawalTransaction", - "name": "_tx", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "_l2OutputIndex", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "version", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "stateRoot", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "messagePasserStorageRoot", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "latestBlockhash", - "type": "bytes32" - } - ], - "internalType": "struct Types.OutputRootProof", - "name": "_outputRootProof", - "type": "tuple" - }, - { - "internalType": "bytes[]", - "name": "_withdrawalProof", - "type": "bytes[]" - } - ], - "name": "proveWithdrawalTransaction", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "provenWithdrawals", - "outputs": [ - { - "internalType": "bytes32", - "name": "outputRoot", - "type": "bytes32" - }, - { - "internalType": "uint128", - "name": "timestamp", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "l2OutputIndex", - "type": "uint128" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "systemConfig", - "outputs": [ - { - "internalType": "contract SystemConfig", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "unpause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0xD14AA6C7B6D92803F3910Ec1DADCCd0757341862", - "args": [], - "bytecode": "0x60806040523480156200001157600080fd5b506200002260008080600162000028565b62000224565b600054600390610100900460ff161580156200004b575060005460ff8083169116105b620000b45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100908117909155603280546001600160a01b031990811661dead1790915560358054603680546001600160a01b0389811691861691909117909155603780548a831695169490941790935585151592891690930260ff19166001600160a81b0319909316929092171790556200013962000181565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600054610100900460ff16620001ee5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b61545c80620002346000396000f3fe60806040526004361061016d5760003560e01c80638b4c40b0116100cb578063a35d99df1161007f578063e9e05c4211610059578063e9e05c4214610573578063f049875014610586578063fecf9734146105b157600080fd5b8063a35d99df1461040d578063cff0ab9614610446578063e965084c146104e757600080fd5b80639b5f694a116100b05780639b5f694a1461037e5780639bf62d82146103b0578063a14238e7146103dd57600080fd5b80638b4c40b0146101925780638c3152e91461035e57600080fd5b806354fd4d50116101225780636dbffb78116101075780636dbffb78146102fe578063724c184c1461031e5780638456cb591461034957600080fd5b806354fd4d501461027e5780635c975abb146102d457600080fd5b80633f4ba83a116101535780633f4ba83a1461021c578063452a9320146102315780634870496f1461025e57600080fd5b80621c2ff61461019957806333d7e2bd146101ef57600080fd5b36610194576101923334620186a06000604051806020016040528060008152506105d1565b005b600080fd5b3480156101a557600080fd5b50603554610100900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101fb57600080fd5b506036546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022857600080fd5b5061019261086c565b34801561023d57600080fd5b506037546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026a57600080fd5b50610192610279366004614a4a565b610971565b34801561028a57600080fd5b506102c76040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b6040516101e69190614ba0565b3480156102e057600080fd5b506035546102ee9060ff1681565b60405190151581526020016101e6565b34801561030a57600080fd5b506102ee610319366004614bb3565b610fa6565b34801561032a57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101c5565b34801561035557600080fd5b50610192611065565b34801561036a57600080fd5b50610192610379366004614bcc565b611167565b34801561038a57600080fd5b506035546101c590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103bc57600080fd5b506032546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e957600080fd5b506102ee6103f8366004614bb3565b60336020526000908152604090205460ff1681565b34801561041957600080fd5b5061042d610428366004614c26565b611a2b565b60405167ffffffffffffffff90911681526020016101e6565b34801561045257600080fd5b506001546104ae906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101e6565b3480156104f357600080fd5b50610545610502366004614bb3565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101e6565b610192610581366004614c51565b6105d1565b34801561059257600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff166101c5565b3480156105bd57600080fd5b506101926105cc366004614ccc565b611a44565b8260005a905083156106885773ffffffffffffffffffffffffffffffffffffffff87161561068857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6106928351611a2b565b67ffffffffffffffff168567ffffffffffffffff161015610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161067f565b6201d4c0835111156107a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161067f565b333281146107c4575033731111000000000000000000000000000000001111015b600034888888886040516020016107df959493929190614d26565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161084f9190614ba0565b60405180910390a450506108638282611c52565b50505050505050565b60375473ffffffffffffffffffffffffffffffffffffffff163314610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e70617573650000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff16156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161067f565b6035546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101869052600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190614dab565b519050610b50610b4b36869003860186614e10565b611f7f565b8114610bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161067f565b6000610be987611fdb565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d035750805160355460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190614dab565b5114155b610d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161067f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610e589101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610e4e888a614e76565b8a6040013561200b565b610ee4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161067f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6035546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161105f9161010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190614dab565b602001516fffffffffffffffffffffffffffffffff1661202f565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff16331461110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20706175736500000000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610967565b60355460ff16156111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161067f565b600061128882611fdb565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161067f565b603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190614efa565b81602001516fffffffffffffffffffffffffffffffff1610156114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161067f565b6114ee81602001516fffffffffffffffffffffffffffffffff1661202f565b6115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60355460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff9091166004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561162c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116509190614dab565b825181519192501461170a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161067f565b61172981602001516fffffffffffffffffffffffffffffffff1661202f565b6117db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60008381526033602052604090205460ff161561187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161067f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161191c939291906120d4565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061198190841515815260200190565b60405180910390a2801580156119975750326001145b15611a24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161067f565b5050505050565b6000611a38826010614f42565b61105f90615208614f72565b600054600390610100900460ff16158015611a66575060005460ff8083169116105b611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100908117909155603280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811661dead17909155603580546036805473ffffffffffffffffffffffffffffffffffffffff89811691861691909117909155603780548a83169516949094179093558515159289169093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fffffffffffffffffffffff00000000000000000000000000000000000000000090931692909217179055611bed612132565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600154600090611c88907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9e565b90506000611c94612215565b90506000816020015160ff16826000015163ffffffff16611cb59190614fe4565b90508215611dec57600154600090611cec908390700100000000000000000000000000000000900467ffffffffffffffff1661504c565b90506000836040015160ff1683611d0391906150c0565b600154611d239084906fffffffffffffffffffffffffffffffff166150c0565b611d2d9190614fe4565b600154909150600090611d7e90611d579084906fffffffffffffffffffffffffffffffff1661517c565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166122db565b90506001861115611dad57611daa611d5782876040015160ff1660018a611da59190614f9e565b6122fa565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e1f908490700100000000000000000000000000000000900467ffffffffffffffff16614f72565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161067f565b600154600090611f2e906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166151f0565b90506000611f4048633b9aca0061234f565b611f4a908361522d565b905060005a611f599088614f9e565b905080821115611f7557611f75611f708284614f9e565b612366565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611fbe949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611fbe979096959101615241565b60008061201786612394565b9050612025818686866123c6565b9695505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561209e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c29190614efa565b6120cc9083615298565b421192915050565b60008060006120e48660006123f6565b90508061211a576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166121c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067f565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260365483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156122b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d691906152d5565b905090565b60006122f06122ea8585612414565b83612424565b90505b9392505050565b6000670de0b6b3a764000061233b6123128583614fe4565b61232490670de0b6b3a764000061504c565b61233685670de0b6b3a76400006150c0565b612433565b61234590866150c0565b6122f09190614fe4565b60008183101561235f57816122f3565b5090919050565b6000805a90505b825a6123799083614f9e565b101561238f5761238882615374565b915061236d565b505050565b606081805190602001206040516020016123b091815260200190565b6040516020818303038152906040529050919050565b60006123ed846123d7878686612464565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561235f57816122f3565b600081831261235f57816122f3565b60006122f3670de0b6b3a76400008361244b86612ee2565b61245591906150c0565b61245f9190614fe4565b613126565b606060008451116124d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161067f565b60006124dc84613365565b905060006124e986613451565b905060008460405160200161250091815260200190565b60405160208183030381529060405290506000805b8451811015612e59576000858281518110612532576125326153ac565b6020026020010151905084518311156125cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161067f565b82600003612686578051805160209182012060405161261b926125f592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067f565b6127dd565b80515160201161273c57805180516020918201206040516126b0926125f592910190815260200190565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161067f565b8051845160208087019190912082519190920120146127dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161067f565b6127e960106001615298565b816020015151036129c5578451830361295d576128238160200151601081518110612816576128166153ac565b60200260200101516134b4565b965060008751116128b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067f565b600186516128c49190614f9e565b8214612952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067f565b5050505050506122f3565b6000858481518110612971576129716153ac565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061299c5761299c6153ac565b602002602001015190506129af81613614565b95506129bc600186615298565b94505050612e46565b600281602001515103612dbe5760006129dd82613639565b90506000816000815181106129f4576129f46153ac565b016020015160f81c90506000612a0b6002836153db565b612a169060026153fd565b90506000612a27848360ff1661365d565b90506000612a358a8961365d565b90506000612a438383613693565b905080835114612ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067f565b60ff851660021480612aea575060ff85166003145b15612cd95780825114612b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067f565b612b998760200151600181518110612816576128166153ac565b9c5060008d5111612c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067f565b60018c51612c3a9190614f9e565b8814612cc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067f565b5050505050505050505050506122f3565b60ff85161580612cec575060ff85166001145b15612d2b57612d188760200151600181518110612d0b57612d0b6153ac565b6020026020010151613614565b9950612d24818a615298565b9850612db3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161067f565b505050505050612e46565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161067f565b5080612e5181615374565b915050612515565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161067f565b6000808213612f4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b60006060612f5a84613747565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361315757506000919050565b680755bf798b4a1bf1e582126131c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161067f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156133835761338361486a565b6040519080825280602002602001820160405280156133c857816020015b60408051808201909152606080825260208201528152602001906001900390816133a15790505b50915060005b8181101561344a5760405180604001604052808583815181106133f3576133f36153ac565b60200260200101518152602001613422868481518110613415576134156153ac565b602002602001015161381d565b815250838281518110613437576134376153ac565b60209081029190910101526001016133ce565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156134a9578060011b82018184015160001a8060041c8253600f81166001830153505060010161347b565b509295945050505050565b606060008060006134c485613830565b9194509250905060008160018111156134df576134df615420565b1461356c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067f565b6135768284615298565b855114613605576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161067f565b6123ed8560200151848461429d565b606060208260000151106136305761362b826134b4565b61105f565b61105f82614331565b606061105f6136588360200151600081518110612816576128166153ac565b613451565b60608251821061367c575060408051602081019091526000815261105f565b6122f3838384865161368e9190614f9e565b614347565b60008082518451106136a65782516136a9565b83515b90505b808210801561373057508282815181106136c8576136c86153ac565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613707576137076153ac565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613740578160010191506136ac565b5092915050565b60008082116137b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061105f61382b8361451f565b614608565b6000806000808460000151116138ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b6020840151805160001a607f8111613913576000600160009450945094505050614296565b60b78111613b21576000613928608083614f9e565b9050808760000151116139e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161067f565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613a5c57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613b0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161067f565b5060019550935060009250614296915050565b60bf8111613e6f576000613b3660b783614f9e565b905080876000015111613bf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161067f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c60378111613d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161067f565b613d9d8184615298565b895111613e52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161067f565b613e5d836001615298565b97509550600094506142969350505050565b60f78111613f50576000613e8460c083614f9e565b905080876000015111613f3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b600195509350849250614296915050565b6000613f5d60f783614f9e565b905080876000015111614018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161067f565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036140f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c603781116141ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161067f565b6141c48184615298565b895111614279576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b614284836001615298565b97509550600194506142969350505050565b9193909250565b60608167ffffffffffffffff8111156142b8576142b861486a565b6040519080825280601f01601f1916602001820160405280156142e2576020820181803683370190505b50905081156122f35760006142f78486615298565b90506020820160005b84811015614318578281015182820152602001614300565b84811115614327576000858301525b5050509392505050565b606061105f82602001516000846000015161429d565b60608182601f0110156143b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b828284011015614422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b8183018451101561448f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161067f565b6060821580156144ae5760405191506000825260208201604052614516565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156144e75780518352602092830192016144cf565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116145ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b50604080518082019091528151815260209182019181019190915290565b6060600080600061461885613830565b91945092509050600181600181111561463357614633615420565b146146c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067f565b84516146cc8385615298565b14614759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161067f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816147705790505093506000835b865181101561485e576000806147e36040518060400160405280858c600001516147c79190614f9e565b8152602001858c602001516147dc9190615298565b9052613830565b5091509150604051806040016040528083836147ff9190615298565b8152602001848b602001516148149190615298565b815250888581518110614829576148296153ac565b602090810291909101015261483f600185615298565b935061484b8183615298565b6148559084615298565b9250505061479d565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156148e0576148e061486a565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461490a57600080fd5b50565b600082601f83011261491e57600080fd5b813567ffffffffffffffff8111156149385761493861486a565b61496960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614899565b81815284602083860101111561497e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156149ad57600080fd5b60405160c0810167ffffffffffffffff82821081831117156149d1576149d161486a565b8160405282935084358352602085013591506149ec826148e8565b81602084015260408501359150614a02826148e8565b816040840152606085013560608401526080850135608084015260a0850135915080821115614a3057600080fd5b50614a3d8582860161490d565b60a0830152505092915050565b600080600080600085870360e0811215614a6357600080fd5b863567ffffffffffffffff80821115614a7b57600080fd5b614a878a838b0161499b565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614ac057600080fd5b60408901955060c0890135925080831115614ada57600080fd5b828901925089601f840112614aee57600080fd5b8235915080821115614aff57600080fd5b508860208260051b8401011115614b1557600080fd5b959894975092955050506020019190565b60005b83811015614b41578181015183820152602001614b29565b83811115614b50576000848401525b50505050565b60008151808452614b6e816020860160208601614b26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122f36020830184614b56565b600060208284031215614bc557600080fd5b5035919050565b600060208284031215614bde57600080fd5b813567ffffffffffffffff811115614bf557600080fd5b614c018482850161499b565b949350505050565b803567ffffffffffffffff81168114614c2157600080fd5b919050565b600060208284031215614c3857600080fd5b6122f382614c09565b80358015158114614c2157600080fd5b600080600080600060a08688031215614c6957600080fd5b8535614c74816148e8565b945060208601359350614c8960408701614c09565b9250614c9760608701614c41565b9150608086013567ffffffffffffffff811115614cb357600080fd5b614cbf8882890161490d565b9150509295509295909350565b60008060008060808587031215614ce257600080fd5b8435614ced816148e8565b93506020850135614cfd816148e8565b92506040850135614d0d816148e8565b9150614d1b60608601614c41565b905092959194509250565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614d7a816049850160208701614b26565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614c2157600080fd5b600060608284031215614dbd57600080fd5b6040516060810181811067ffffffffffffffff82111715614de057614de061486a565b60405282518152614df360208401614d8b565b6020820152614e0460408401614d8b565b60408201529392505050565b600060808284031215614e2257600080fd5b6040516080810181811067ffffffffffffffff82111715614e4557614e4561486a565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e9157614e9161486a565b8360051b6020614ea2818301614899565b868152918501918181019036841115614eba57600080fd5b865b84811015614eee57803586811115614ed45760008081fd5b614ee036828b0161490d565b845250918301918301614ebc565b50979650505050505050565b600060208284031215614f0c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614f6957614f69614f13565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f9557614f95614f13565b01949350505050565b600082821015614fb057614fb0614f13565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff357614ff3614fb5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504757615047614f13565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508657615086614f13565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150ba576150ba614f13565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561510157615101614f13565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513c5761513c614f13565b6000871292508782058712848416161561515857615158614f13565b8785058712818416161561516e5761516e614f13565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b6576151b6614f13565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151ea576151ea614f13565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561522857615228614f13565b500290565b60008261523c5761523c614fb5565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261528c60c0830184614b56565b98975050505050505050565b600082198211156152ab576152ab614f13565b500190565b805163ffffffff81168114614c2157600080fd5b805160ff81168114614c2157600080fd5b600060c082840312156152e757600080fd5b60405160c0810181811067ffffffffffffffff8211171561530a5761530a61486a565b604052615316836152b0565b8152615324602084016152c4565b6020820152615335604084016152c4565b6040820152615346606084016152b0565b6060820152615357608084016152b0565b608082015261536860a08401614d8b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153a5576153a5614f13565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806153ee576153ee614fb5565b8060ff84160691505092915050565b600060ff821660ff84168082101561541757615417614f13565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061016d5760003560e01c80638b4c40b0116100cb578063a35d99df1161007f578063e9e05c4211610059578063e9e05c4214610573578063f049875014610586578063fecf9734146105b157600080fd5b8063a35d99df1461040d578063cff0ab9614610446578063e965084c146104e757600080fd5b80639b5f694a116100b05780639b5f694a1461037e5780639bf62d82146103b0578063a14238e7146103dd57600080fd5b80638b4c40b0146101925780638c3152e91461035e57600080fd5b806354fd4d50116101225780636dbffb78116101075780636dbffb78146102fe578063724c184c1461031e5780638456cb591461034957600080fd5b806354fd4d501461027e5780635c975abb146102d457600080fd5b80633f4ba83a116101535780633f4ba83a1461021c578063452a9320146102315780634870496f1461025e57600080fd5b80621c2ff61461019957806333d7e2bd146101ef57600080fd5b36610194576101923334620186a06000604051806020016040528060008152506105d1565b005b600080fd5b3480156101a557600080fd5b50603554610100900473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101fb57600080fd5b506036546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561022857600080fd5b5061019261086c565b34801561023d57600080fd5b506037546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026a57600080fd5b50610192610279366004614a4a565b610971565b34801561028a57600080fd5b506102c76040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b6040516101e69190614ba0565b3480156102e057600080fd5b506035546102ee9060ff1681565b60405190151581526020016101e6565b34801561030a57600080fd5b506102ee610319366004614bb3565b610fa6565b34801561032a57600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101c5565b34801561035557600080fd5b50610192611065565b34801561036a57600080fd5b50610192610379366004614bcc565b611167565b34801561038a57600080fd5b506035546101c590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103bc57600080fd5b506032546101c59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e957600080fd5b506102ee6103f8366004614bb3565b60336020526000908152604090205460ff1681565b34801561041957600080fd5b5061042d610428366004614c26565b611a2b565b60405167ffffffffffffffff90911681526020016101e6565b34801561045257600080fd5b506001546104ae906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101e6565b3480156104f357600080fd5b50610545610502366004614bb3565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101e6565b610192610581366004614c51565b6105d1565b34801561059257600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff166101c5565b3480156105bd57600080fd5b506101926105cc366004614ccc565b611a44565b8260005a905083156106885773ffffffffffffffffffffffffffffffffffffffff87161561068857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6106928351611a2b565b67ffffffffffffffff168567ffffffffffffffff161015610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161067f565b6201d4c0835111156107a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161067f565b333281146107c4575033731111000000000000000000000000000000001111015b600034888888886040516020016107df959493929190614d26565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161084f9190614ba0565b60405180910390a450506108638282611c52565b50505050505050565b60375473ffffffffffffffffffffffffffffffffffffffff163314610913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e70617573650000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff16156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161067f565b6035546040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101869052600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b369190614dab565b519050610b50610b4b36869003860186614e10565b611f7f565b8114610bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161067f565b6000610be987611fdb565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d035750805160355460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015261010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cff9190614dab565b5114155b610d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161067f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610e589101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610e4e888a614e76565b8a6040013561200b565b610ee4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161067f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6035546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161105f9161010090910473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190614dab565b602001516fffffffffffffffffffffffffffffffff1661202f565b92915050565b60375473ffffffffffffffffffffffffffffffffffffffff16331461110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20706175736500000000000000000000000000000000000000000000000000606482015260840161067f565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610967565b60355460ff16156111d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161067f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead1461127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161067f565b600061128882611fdb565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff80821694830185905270010000000000000000000000000000000090910416918101919091529293509003611373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161067f565b603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190614efa565b81602001516fffffffffffffffffffffffffffffffff1610156114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161067f565b6114ee81602001516fffffffffffffffffffffffffffffffff1661202f565b6115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60355460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff9091166004820152600091610100900473ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561162c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116509190614dab565b825181519192501461170a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161067f565b61172981602001516fffffffffffffffffffffffffffffffff1661202f565b6117db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161067f565b60008381526033602052604090205460ff161561187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161067f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161191c939291906120d4565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061198190841515815260200190565b60405180910390a2801580156119975750326001145b15611a24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161067f565b5050505050565b6000611a38826010614f42565b61105f90615208614f72565b600054600390610100900460ff16158015611a66575060005460ff8083169116105b611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100908117909155603280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811661dead17909155603580546036805473ffffffffffffffffffffffffffffffffffffffff89811691861691909117909155603780548a83169516949094179093558515159289169093027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fffffffffffffffffffffff00000000000000000000000000000000000000000090931692909217179055611bed612132565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600154600090611c88907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9e565b90506000611c94612215565b90506000816020015160ff16826000015163ffffffff16611cb59190614fe4565b90508215611dec57600154600090611cec908390700100000000000000000000000000000000900467ffffffffffffffff1661504c565b90506000836040015160ff1683611d0391906150c0565b600154611d239084906fffffffffffffffffffffffffffffffff166150c0565b611d2d9190614fe4565b600154909150600090611d7e90611d579084906fffffffffffffffffffffffffffffffff1661517c565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff166122db565b90506001861115611dad57611daa611d5782876040015160ff1660018a611da59190614f9e565b6122fa565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e1f908490700100000000000000000000000000000000900467ffffffffffffffff16614f72565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161067f565b600154600090611f2e906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166151f0565b90506000611f4048633b9aca0061234f565b611f4a908361522d565b905060005a611f599088614f9e565b905080821115611f7557611f75611f708284614f9e565b612366565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611fbe949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611fbe979096959101615241565b60008061201786612394565b9050612025818686866123c6565b9695505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561209e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c29190614efa565b6120cc9083615298565b421192915050565b60008060006120e48660006123f6565b90508061211a576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff166121c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067f565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260365483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa1580156122b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d691906152d5565b905090565b60006122f06122ea8585612414565b83612424565b90505b9392505050565b6000670de0b6b3a764000061233b6123128583614fe4565b61232490670de0b6b3a764000061504c565b61233685670de0b6b3a76400006150c0565b612433565b61234590866150c0565b6122f09190614fe4565b60008183101561235f57816122f3565b5090919050565b6000805a90505b825a6123799083614f9e565b101561238f5761238882615374565b915061236d565b505050565b606081805190602001206040516020016123b091815260200190565b6040516020818303038152906040529050919050565b60006123ed846123d7878686612464565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561235f57816122f3565b600081831261235f57816122f3565b60006122f3670de0b6b3a76400008361244b86612ee2565b61245591906150c0565b61245f9190614fe4565b613126565b606060008451116124d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161067f565b60006124dc84613365565b905060006124e986613451565b905060008460405160200161250091815260200190565b60405160208183030381529060405290506000805b8451811015612e59576000858281518110612532576125326153ac565b6020026020010151905084518311156125cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161067f565b82600003612686578051805160209182012060405161261b926125f592910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161067f565b6127dd565b80515160201161273c57805180516020918201206040516126b0926125f592910190815260200190565b612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161067f565b8051845160208087019190912082519190920120146127dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161067f565b6127e960106001615298565b816020015151036129c5578451830361295d576128238160200151601081518110612816576128166153ac565b60200260200101516134b4565b965060008751116128b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161067f565b600186516128c49190614f9e565b8214612952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161067f565b5050505050506122f3565b6000858481518110612971576129716153ac565b602001015160f81c60f81b60f81c9050600082602001518260ff168151811061299c5761299c6153ac565b602002602001015190506129af81613614565b95506129bc600186615298565b94505050612e46565b600281602001515103612dbe5760006129dd82613639565b90506000816000815181106129f4576129f46153ac565b016020015160f81c90506000612a0b6002836153db565b612a169060026153fd565b90506000612a27848360ff1661365d565b90506000612a358a8961365d565b90506000612a438383613693565b905080835114612ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161067f565b60ff851660021480612aea575060ff85166003145b15612cd95780825114612b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161067f565b612b998760200151600181518110612816576128166153ac565b9c5060008d5111612c2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161067f565b60018c51612c3a9190614f9e565b8814612cc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161067f565b5050505050505050505050506122f3565b60ff85161580612cec575060ff85166001145b15612d2b57612d188760200151600181518110612d0b57612d0b6153ac565b6020026020010151613614565b9950612d24818a615298565b9850612db3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161067f565b505050505050612e46565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161067f565b5080612e5181615374565b915050612515565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161067f565b6000808213612f4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b60006060612f5a84613747565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361315757506000919050565b680755bf798b4a1bf1e582126131c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161067f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156133835761338361486a565b6040519080825280602002602001820160405280156133c857816020015b60408051808201909152606080825260208201528152602001906001900390816133a15790505b50915060005b8181101561344a5760405180604001604052808583815181106133f3576133f36153ac565b60200260200101518152602001613422868481518110613415576134156153ac565b602002602001015161381d565b815250838281518110613437576134376153ac565b60209081029190910101526001016133ce565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b838110156134a9578060011b82018184015160001a8060041c8253600f81166001830153505060010161347b565b509295945050505050565b606060008060006134c485613830565b9194509250905060008160018111156134df576134df615420565b1461356c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161067f565b6135768284615298565b855114613605576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161067f565b6123ed8560200151848461429d565b606060208260000151106136305761362b826134b4565b61105f565b61105f82614331565b606061105f6136588360200151600081518110612816576128166153ac565b613451565b60608251821061367c575060408051602081019091526000815261105f565b6122f3838384865161368e9190614f9e565b614347565b60008082518451106136a65782516136a9565b83515b90505b808210801561373057508282815181106136c8576136c86153ac565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916848381518110613707576137076153ac565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b15613740578160010191506136ac565b5092915050565b60008082116137b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161067f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061105f61382b8361451f565b614608565b6000806000808460000151116138ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b6020840151805160001a607f8111613913576000600160009450945094505050614296565b60b78111613b21576000613928608083614f9e565b9050808760000151116139e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161067f565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613a5c57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613b0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161067f565b5060019550935060009250614296915050565b60bf8111613e6f576000613b3660b783614f9e565b905080876000015111613bf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161067f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c60378111613d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161067f565b613d9d8184615298565b895111613e52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161067f565b613e5d836001615298565b97509550600094506142969350505050565b60f78111613f50576000613e8460c083614f9e565b905080876000015111613f3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b600195509350849250614296915050565b6000613f5d60f783614f9e565b905080876000015111614018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161067f565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036140f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161067f565b600184015160088302610100031c603781116141ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161067f565b6141c48184615298565b895111614279576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161067f565b614284836001615298565b97509550600194506142969350505050565b9193909250565b60608167ffffffffffffffff8111156142b8576142b861486a565b6040519080825280601f01601f1916602001820160405280156142e2576020820181803683370190505b50905081156122f35760006142f78486615298565b90506020820160005b84811015614318578281015182820152602001614300565b84811115614327576000858301525b5050509392505050565b606061105f82602001516000846000015161429d565b60608182601f0110156143b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b828284011015614422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161067f565b8183018451101561448f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161067f565b6060821580156144ae5760405191506000825260208201604052614516565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156144e75780518352602092830192016144cf565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116145ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161067f565b50604080518082019091528151815260209182019181019190915290565b6060600080600061461885613830565b91945092509050600181600181111561463357614633615420565b146146c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161067f565b84516146cc8385615298565b14614759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161067f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816147705790505093506000835b865181101561485e576000806147e36040518060400160405280858c600001516147c79190614f9e565b8152602001858c602001516147dc9190615298565b9052613830565b5091509150604051806040016040528083836147ff9190615298565b8152602001848b602001516148149190615298565b815250888581518110614829576148296153ac565b602090810291909101015261483f600185615298565b935061484b8183615298565b6148559084615298565b9250505061479d565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156148e0576148e061486a565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461490a57600080fd5b50565b600082601f83011261491e57600080fd5b813567ffffffffffffffff8111156149385761493861486a565b61496960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614899565b81815284602083860101111561497e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156149ad57600080fd5b60405160c0810167ffffffffffffffff82821081831117156149d1576149d161486a565b8160405282935084358352602085013591506149ec826148e8565b81602084015260408501359150614a02826148e8565b816040840152606085013560608401526080850135608084015260a0850135915080821115614a3057600080fd5b50614a3d8582860161490d565b60a0830152505092915050565b600080600080600085870360e0811215614a6357600080fd5b863567ffffffffffffffff80821115614a7b57600080fd5b614a878a838b0161499b565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614ac057600080fd5b60408901955060c0890135925080831115614ada57600080fd5b828901925089601f840112614aee57600080fd5b8235915080821115614aff57600080fd5b508860208260051b8401011115614b1557600080fd5b959894975092955050506020019190565b60005b83811015614b41578181015183820152602001614b29565b83811115614b50576000848401525b50505050565b60008151808452614b6e816020860160208601614b26565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122f36020830184614b56565b600060208284031215614bc557600080fd5b5035919050565b600060208284031215614bde57600080fd5b813567ffffffffffffffff811115614bf557600080fd5b614c018482850161499b565b949350505050565b803567ffffffffffffffff81168114614c2157600080fd5b919050565b600060208284031215614c3857600080fd5b6122f382614c09565b80358015158114614c2157600080fd5b600080600080600060a08688031215614c6957600080fd5b8535614c74816148e8565b945060208601359350614c8960408701614c09565b9250614c9760608701614c41565b9150608086013567ffffffffffffffff811115614cb357600080fd5b614cbf8882890161490d565b9150509295509295909350565b60008060008060808587031215614ce257600080fd5b8435614ced816148e8565b93506020850135614cfd816148e8565b92506040850135614d0d816148e8565b9150614d1b60608601614c41565b905092959194509250565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614d7a816049850160208701614b26565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614c2157600080fd5b600060608284031215614dbd57600080fd5b6040516060810181811067ffffffffffffffff82111715614de057614de061486a565b60405282518152614df360208401614d8b565b6020820152614e0460408401614d8b565b60408201529392505050565b600060808284031215614e2257600080fd5b6040516080810181811067ffffffffffffffff82111715614e4557614e4561486a565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e9157614e9161486a565b8360051b6020614ea2818301614899565b868152918501918181019036841115614eba57600080fd5b865b84811015614eee57803586811115614ed45760008081fd5b614ee036828b0161490d565b845250918301918301614ebc565b50979650505050505050565b600060208284031215614f0c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614f6957614f69614f13565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f9557614f95614f13565b01949350505050565b600082821015614fb057614fb0614f13565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff357614ff3614fb5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504757615047614f13565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508657615086614f13565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150ba576150ba614f13565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561510157615101614f13565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513c5761513c614f13565b6000871292508782058712848416161561515857615158614f13565b8785058712818416161561516e5761516e614f13565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b6576151b6614f13565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151ea576151ea614f13565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561522857615228614f13565b500290565b60008261523c5761523c614fb5565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261528c60c0830184614b56565b98975050505050505050565b600082198211156152ab576152ab614f13565b500190565b805163ffffffff81168114614c2157600080fd5b805160ff81168114614c2157600080fd5b600060c082840312156152e757600080fd5b60405160c0810181811067ffffffffffffffff8211171561530a5761530a61486a565b604052615316836152b0565b8152615324602084016152c4565b6020820152615335604084016152c4565b6040820152615346606084016152b0565b6060820152615357608084016152b0565b608082015261536860a08401614d8b565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153a5576153a5614f13565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806153ee576153ee614fb5565b8060ff84160691505092915050565b600060ff821660ff84168082101561541757615417614f13565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "GUARDIAN()": {}, - "L2_ORACLE()": {}, - "SYSTEM_CONFIG()": {}, - "depositTransaction(address,uint256,uint64,bool,bytes)": { - "params": { - "_data": "Data to trigger the recipient with.", - "_gasLimit": "Amount of L2 gas to purchase by burning gas on L1.", - "_isCreation": "Whether or not the transaction is a contract creation.", - "_to": "Target address on L2.", - "_value": "ETH value to send to the recipient." - } - }, - "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": { - "params": { - "_tx": "Withdrawal transaction to finalize." - } - }, - "initialize(address,address,address,bool)": { - "params": { - "_guardian": "Address that can pause withdrawals.", - "_l2Oracle": "Address of the L2OutputOracle contract.", - "_paused": "Sets the contract's pausability state.", - "_systemConfig": "Address of the SystemConfig contract." - } - }, - "isOutputFinalized(uint256)": { - "params": { - "_l2OutputIndex": "Index of the L2 output to check." - }, - "returns": { - "_0": "Whether or not the output is finalized." - } - }, - "minimumGasLimit(uint64)": { - "params": { - "_byteCount": "Number of bytes in the calldata." - }, - "returns": { - "_0": "The minimum gas limit for a deposit." - } - }, - "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": { - "params": { - "_l2OutputIndex": "L2 output index to prove against.", - "_outputRootProof": "Inclusion proof of the L2ToL1MessagePasser contract's storage root.", - "_tx": "Withdrawal transaction to finalize.", - "_withdrawalProof": "Inclusion proof of the withdrawal in L2ToL1MessagePasser contract." - } - } - }, - "events": { - "Paused(address)": { - "params": { - "account": "Address of the account triggering the pause." - } - }, - "TransactionDeposited(address,address,uint256,bytes)": { - "params": { - "from": "Address that triggered the deposit transaction.", - "opaqueData": "ABI encoded deposit data to be parsed off-chain.", - "to": "Address that the deposit transaction is directed to.", - "version": "Version of this deposit transaction event." - } - }, - "Unpaused(address)": { - "params": { - "account": "Address of the account triggering the unpause." - } - }, - "WithdrawalFinalized(bytes32,bool)": { - "params": { - "success": "Whether the withdrawal transaction was successful.", - "withdrawalHash": "Hash of the withdrawal transaction." - } - }, - "WithdrawalProven(bytes32,address,address)": { - "params": { - "from": "Address that triggered the withdrawal transaction.", - "to": "Address that the withdrawal transaction is directed to.", - "withdrawalHash": "Hash of the withdrawal transaction." - } - } - } - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Paused\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"bytes\",\"name\":\"opaqueData\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"TransactionDeposited\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Unpaused\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\",\"indexed\":false}],\"type\":\"event\",\"name\":\"WithdrawalFinalized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"WithdrawalProven\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"GUARDIAN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"SYSTEM_CONFIG\",\"outputs\":[{\"internalType\":\"contract SystemConfig\",\"name\":\"\",\"type\":\"address\"}]},{\"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\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"depositTransaction\"},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"donateETH\"},{\"inputs\":[{\"internalType\":\"struct Types.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"finalizeWithdrawalTransaction\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"guardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_guardian\",\"type\":\"address\"},{\"internalType\":\"contract SystemConfig\",\"name\":\"_systemConfig\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"isOutputFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2Oracle\",\"outputs\":[{\"internalType\":\"contract L2OutputOracle\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_byteCount\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"pause\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[{\"internalType\":\"struct Types.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}]},{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"},{\"internalType\":\"struct Types.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}]},{\"internalType\":\"bytes[]\",\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"proveWithdrawalTransaction\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"provenWithdrawals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2OutputIndex\",\"type\":\"uint128\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"systemConfig\",\"outputs\":[{\"internalType\":\"contract SystemConfig\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"unpause\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"GUARDIAN()\":{\"custom:legacy\":\"\"},\"L2_ORACLE()\":{\"custom:legacy\":\"\"},\"SYSTEM_CONFIG()\":{\"custom:legacy\":\"\"},\"depositTransaction(address,uint256,uint64,bool,bytes)\":{\"params\":{\"_data\":\"Data to trigger the recipient with.\",\"_gasLimit\":\"Amount of L2 gas to purchase by burning gas on L1.\",\"_isCreation\":\"Whether or not the transaction is a contract creation.\",\"_to\":\"Target address on L2.\",\"_value\":\"ETH value to send to the recipient.\"}},\"finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))\":{\"params\":{\"_tx\":\"Withdrawal transaction to finalize.\"}},\"initialize(address,address,address,bool)\":{\"params\":{\"_guardian\":\"Address that can pause withdrawals.\",\"_l2Oracle\":\"Address of the L2OutputOracle contract.\",\"_paused\":\"Sets the contract's pausability state.\",\"_systemConfig\":\"Address of the SystemConfig contract.\"}},\"isOutputFinalized(uint256)\":{\"params\":{\"_l2OutputIndex\":\"Index of the L2 output to check.\"},\"returns\":{\"_0\":\"Whether or not the output is finalized.\"}},\"minimumGasLimit(uint64)\":{\"params\":{\"_byteCount\":\"Number of bytes in the calldata.\"},\"returns\":{\"_0\":\"The minimum gas limit for a deposit.\"}},\"proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])\":{\"params\":{\"_l2OutputIndex\":\"L2 output index to prove against.\",\"_outputRootProof\":\"Inclusion proof of the L2ToL1MessagePasser contract's storage root.\",\"_tx\":\"Withdrawal transaction to finalize.\",\"_withdrawalProof\":\"Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"GUARDIAN()\":{\"notice\":\"Getter for the Guardian\"},\"L2_ORACLE()\":{\"notice\":\"Getter for the L2OutputOracle\"},\"SYSTEM_CONFIG()\":{\"notice\":\"Getter for the SystemConfig\"},\"constructor\":{\"notice\":\"Constructs the OptimismPortal contract.\"},\"depositTransaction(address,uint256,uint64,bool,bytes)\":{\"notice\":\"Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in deriving deposit transactions. Note that if a deposit is made by a contract, its address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider using the CrossDomainMessenger contracts for a simpler developer experience.\"},\"donateETH()\":{\"notice\":\"Accepts ETH value without triggering a deposit to L2. This function mainly exists for the sake of the migration between the legacy Optimism system and Bedrock.\"},\"finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))\":{\"notice\":\"Finalizes a withdrawal transaction.\"},\"finalizedWithdrawals(bytes32)\":{\"notice\":\"A list of withdrawal hashes which have been successfully finalized.\"},\"guardian()\":{\"notice\":\"Address that has the ability to pause and unpause withdrawals.\"},\"initialize(address,address,address,bool)\":{\"notice\":\"Initializer.\"},\"isOutputFinalized(uint256)\":{\"notice\":\"Determine if a given output is finalized. Reverts if the call to L2_ORACLE.getL2Output reverts. Returns a boolean otherwise.\"},\"l2Oracle()\":{\"notice\":\"Address of the L2OutputOracle contract.\"},\"l2Sender()\":{\"notice\":\"Address of the L2 account which initiated a withdrawal in this transaction. If the of this variable is the default L2 sender address, then we are NOT inside of a call to finalizeWithdrawalTransaction.\"},\"minimumGasLimit(uint64)\":{\"notice\":\"Computes the minimum gas limit for a deposit. The minimum gas limit linearly increases based on the size of the calldata. This is to prevent users from creating L2 resource usage without paying for it. This function can be used when interacting with the portal to ensure forwards compatibility.\"},\"params()\":{\"notice\":\"EIP-1559 style gas parameters.\"},\"pause()\":{\"notice\":\"Pauses withdrawals.\"},\"paused()\":{\"notice\":\"Determines if cross domain messaging is paused. When set to true, withdrawals are paused. This may be removed in the future.\"},\"proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])\":{\"notice\":\"Proves a withdrawal transaction.\"},\"provenWithdrawals(bytes32)\":{\"notice\":\"A mapping of withdrawal hashes to `ProvenWithdrawal` data.\"},\"systemConfig()\":{\"notice\":\"Address of the SystemConfig contract.\"},\"unpause()\":{\"notice\":\"Unpauses withdrawals.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/OptimismPortal.sol\":\"OptimismPortal\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/L2OutputOracle.sol\":{\"keccak256\":\"0x60042eb3e619518cab9a8f2480b62871c2d813716e2e60d9a5e0c5f271c58705\",\"urls\":[\"bzz-raw://08538ef2aa99c508b56a8bb9b3c7b93476cba9dbf0b47783141e5e50a02156cc\",\"dweb:/ipfs/QmdvFZ1fUaTkNdmtB66rNAo73RxY7kccsgR6Uqz7psoXGN\"],\"license\":\"MIT\"},\"src/L1/OptimismPortal.sol\":{\"keccak256\":\"0xdca91a921b402d82b455d7f11027514e8a16dca906cf820b3afffe271beb8a13\",\"urls\":[\"bzz-raw://688912b9d6005af8395d5c2eb5c4e3367a8be7b50ea97c34fc6a7ac0e2d8fd6a\",\"dweb:/ipfs/QmNPJDwHpNmJ5VPWAJB8muRpZxYeySZDVoV1TMVN7roijJ\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L1/SystemConfig.sol\":{\"keccak256\":\"0x2b4005c512ab947da105305e3db913b0d7884a954d0aa602f90f7b02188dcda6\",\"urls\":[\"bzz-raw://cc68c9ec4e1aebdd9dba39c7516d38e40a4472b708dfaca1fb9a4742d346db47\",\"dweb:/ipfs/QmX8moXk9cb47tRefi6q15oQAAt18MHEdQojWhrXxz5ykK\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Bytes.sol\":{\"keccak256\":\"0x827f47d123b0fdf3b08816d5b33831811704dbf4e554e53f2269354f6bba8859\",\"urls\":[\"bzz-raw://3137ac7204d30a245a8b0d67aa6da5286f1bd8c90379daab561f84963b6db782\",\"dweb:/ipfs/QmWRhisw3axJK833gUScs23ETh2MLFbVzzqzYVMKSDN3S9\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Encoding.sol\":{\"keccak256\":\"0xd5bbcb7da113e69562498d9543765e03912558ad66348682c2049c31e19f9d9b\",\"urls\":[\"bzz-raw://afc6656ea10062c0c9d0817bb8683636caebf9222c9c102f29ea54fff74a2f93\",\"dweb:/ipfs/QmTNWtMgrTRHM6XtdUmA8bMZcuFpXoFCXgXR5vRihZWLuW\"],\"license\":\"MIT\"},\"src/libraries/Hashing.sol\":{\"keccak256\":\"0x44e2b2dcfffc39c0fc95ccd3c2118c7e7585fadf3dca327877d5756c7d4b21c3\",\"urls\":[\"bzz-raw://6c89e0d9cfcb08a0d3c46c85367a32bbd9703468ba4c0c5bb6e124c1d173b26b\",\"dweb:/ipfs/QmaY3nQHBBhHK1wrurVXiEeNL8hfZ1pRmhpqW44tFDJnDf\"],\"license\":\"MIT\"},\"src/libraries/SafeCall.sol\":{\"keccak256\":\"0x0636a7abb242bb5d6f5606967c8929e6aa7e63468c1e2ce40ad4780d4c4bf94f\",\"urls\":[\"bzz-raw://a4daec2ac8f9907bbf84ef0a1c48f03bae8657619bc6f42b3a672f25c516f17a\",\"dweb:/ipfs/Qmf8gfRxBv8gEmCkP8YMPb2GGfj9QUnoNUyKE7UR2SWGnq\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/libraries/Types.sol\":{\"keccak256\":\"0x75900d651301940d24c00d14f0b3b6cbd6dcf379173ceaa31d9bf5be934a9aa4\",\"urls\":[\"bzz-raw://99c2632c5bf4fa3982391c32110eec9fa07917b483b2442cbaf18bdde5bdb24e\",\"dweb:/ipfs/QmSUs6Amkeootf5gKGbKi4mJpvhN2U8i1ED6ef2dskV5xc\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPReader.sol\":{\"keccak256\":\"0x9ba74a3b0a11693e622380807d213d5d1250d974e18b2cd768da9cbe719a6778\",\"urls\":[\"bzz-raw://0808d721ed9e05707526ee134faa051d707a95ee6b8bd6e0b1972275da8e5723\",\"dweb:/ipfs/QmcTTPu9xgckfWdbFUAcr2RAgk3J6vzyR4FpV798TjFMeN\"],\"license\":\"MIT\"},\"src/libraries/rlp/RLPWriter.sol\":{\"keccak256\":\"0x60ac401490f321c9c55e996a2c65151cd5e60de5f8f297e7c94d541c29820bb6\",\"urls\":[\"bzz-raw://070f5814db07e4a89173d44a36d90e4261ce530f7336034c01635347f2c2d88b\",\"dweb:/ipfs/QmXqr9yW5Kc8MYgr5wSehU5AiqS9pZ4FKxv7vwiwpZCcyV\"],\"license\":\"MIT\"},\"src/libraries/trie/MerkleTrie.sol\":{\"keccak256\":\"0xf8ba770ee6666e73ae43184c700e9c704b2c4ace71f9e3c2227ddc11a8148b4c\",\"urls\":[\"bzz-raw://4702ccee1fe44aea3ee01d59e6152eb755da083f786f00947fec4437c064fe74\",\"dweb:/ipfs/QmQjFj5J7hrEM1dxJjFszzW2Cs7g7eMhYNBXonF2DXBstE\"],\"license\":\"MIT\"},\"src/libraries/trie/SecureMerkleTrie.sol\":{\"keccak256\":\"0xeaff8315cfd21197bc6bc859c2decf5d4f4838c9c357c502cdf2b1eac863d288\",\"urls\":[\"bzz-raw://79dcdcaa560aea51d138da4f5dc553a1808b6de090b2dc1629f18375edbff681\",\"dweb:/ipfs/QmbE4pUPhf5fLKW4W6cEjhQs55gEDvHmbmoBqkW1yz3bnw\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"},\"src/vendor/AddressAliasHelper.sol\":{\"keccak256\":\"0x6ecb83b4ec80fbe49c22f4f95d90482de64660ef5d422a19f4d4b04df31c1237\",\"urls\":[\"bzz-raw://1d0885be6e473962f9a0622176a22300165ac0cc1a1d7f2e22b11c3d656ace88\",\"dweb:/ipfs/QmPRa3KmRpXW5P9ykveKRDgYN5zYo4cYLAYSnoqHX3KnXR\"],\"license\":\"Apache-2.0\"}},\"version\":1}", - "numDeployments": 6, - "receipt": { - "transactionHash": "0x3d49c0d52b00bf8397ae0328e45e8de051db0b2cb2ae8c4d666009bbd493bfee", - "transactionIndex": "0x4", - "blockHash": "0x30eaba364ea372999e21c65eeb06db7a6200a8de6b3bebf9d88175bdbe963346", - "blockNumber": "0x438a04", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "cumulativeGasUsed": "0x55bd75", - "gasUsed": "0x491939", - "contractAddress": "0xD14AA6C7B6D92803F3910Ec1DADCCd0757341862", - "logs": [ - { - "address": "0xD14AA6C7B6D92803F3910Ec1DADCCd0757341862", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000003", - "blockHash": "0x30eaba364ea372999e21c65eeb06db7a6200a8de6b3bebf9d88175bdbe963346", - "blockNumber": "0x438a04", - "transactionHash": "0x3d49c0d52b00bf8397ae0328e45e8de051db0b2cb2ae8c4d666009bbd493bfee", - "transactionIndex": "0x4", - "logIndex": "0xc", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000010400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb3c41425" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 32100, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 32103, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 61182, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "params", - "offset": 0, - "slot": "1", - "type": "t_struct(ResourceParams)61165_storage" - }, - { - "astId": 61187, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "__gap", - "offset": 0, - "slot": "2", - "type": "t_array(t_uint256)48_storage" - }, - { - "astId": 60218, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "l2Sender", - "offset": 0, - "slot": "50", - "type": "t_address" - }, - { - "astId": 60223, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "finalizedWithdrawals", - "offset": 0, - "slot": "51", - "type": "t_mapping(t_bytes32,t_bool)" - }, - { - "astId": 60229, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "provenWithdrawals", - "offset": 0, - "slot": "52", - "type": "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)60207_storage)" - }, - { - "astId": 60232, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "paused", - "offset": 0, - "slot": "53", - "type": "t_bool" - }, - { - "astId": 60236, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "l2Oracle", - "offset": 1, - "slot": "53", - "type": "t_contract(L2OutputOracle)60167" - }, - { - "astId": 60240, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "systemConfig", - "offset": 0, - "slot": "54", - "type": "t_contract(SystemConfig)62287" - }, - { - "astId": 60243, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "guardian", - "offset": 0, - "slot": "55", - "type": "t_address" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)48_storage": { - "encoding": "inplace", - "label": "uint256[48]", - "numberOfBytes": "1536", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_contract(L2OutputOracle)60167": { - "encoding": "inplace", - "label": "contract L2OutputOracle", - "numberOfBytes": "20" - }, - "t_contract(SystemConfig)62287": { - "encoding": "inplace", - "label": "contract SystemConfig", - "numberOfBytes": "20" - }, - "t_mapping(t_bytes32,t_bool)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => bool)", - "numberOfBytes": "32", - "value": "t_bool" - }, - "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)60207_storage)": { - "encoding": "mapping", - "key": "t_bytes32", - "label": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal)", - "numberOfBytes": "32", - "value": "t_struct(ProvenWithdrawal)60207_storage" - }, - "t_struct(ProvenWithdrawal)60207_storage": { - "encoding": "inplace", - "label": "struct OptimismPortal.ProvenWithdrawal", - "numberOfBytes": "64", - "members": [ - { - "astId": 60202, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "outputRoot", - "offset": 0, - "slot": "0", - "type": "t_bytes32" - }, - { - "astId": 60204, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "timestamp", - "offset": 0, - "slot": "1", - "type": "t_uint128" - }, - { - "astId": 60206, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "l2OutputIndex", - "offset": 16, - "slot": "1", - "type": "t_uint128" - } - ] - }, - "t_struct(ResourceParams)61165_storage": { - "encoding": "inplace", - "label": "struct ResourceMetering.ResourceParams", - "numberOfBytes": "32", - "members": [ - { - "astId": 61160, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "prevBaseFee", - "offset": 0, - "slot": "0", - "type": "t_uint128" - }, - { - "astId": 61162, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "prevBoughtGas", - "offset": 16, - "slot": "0", - "type": "t_uint64" - }, - { - "astId": 61164, - "contract": "src/L1/OptimismPortal.sol:OptimismPortal", - "label": "prevBlockNum", - "offset": 24, - "slot": "0", - "type": "t_uint64" - } - ] - }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x3d49c0d52b00bf8397ae0328e45e8de051db0b2cb2ae8c4d666009bbd493bfee", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "GUARDIAN()": { - "notice": "Getter for the Guardian" - }, - "L2_ORACLE()": { - "notice": "Getter for the L2OutputOracle" - }, - "SYSTEM_CONFIG()": { - "notice": "Getter for the SystemConfig" - }, - "constructor": { - "notice": "Constructs the OptimismPortal contract." - }, - "depositTransaction(address,uint256,uint64,bool,bytes)": { - "notice": "Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in deriving deposit transactions. Note that if a deposit is made by a contract, its address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider using the CrossDomainMessenger contracts for a simpler developer experience." - }, - "donateETH()": { - "notice": "Accepts ETH value without triggering a deposit to L2. This function mainly exists for the sake of the migration between the legacy Optimism system and Bedrock." - }, - "finalizeWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes))": { - "notice": "Finalizes a withdrawal transaction." - }, - "finalizedWithdrawals(bytes32)": { - "notice": "A list of withdrawal hashes which have been successfully finalized." - }, - "guardian()": { - "notice": "Address that has the ability to pause and unpause withdrawals." - }, - "initialize(address,address,address,bool)": { - "notice": "Initializer." - }, - "isOutputFinalized(uint256)": { - "notice": "Determine if a given output is finalized. Reverts if the call to L2_ORACLE.getL2Output reverts. Returns a boolean otherwise." - }, - "l2Oracle()": { - "notice": "Address of the L2OutputOracle contract." - }, - "l2Sender()": { - "notice": "Address of the L2 account which initiated a withdrawal in this transaction. If the of this variable is the default L2 sender address, then we are NOT inside of a call to finalizeWithdrawalTransaction." - }, - "minimumGasLimit(uint64)": { - "notice": "Computes the minimum gas limit for a deposit. The minimum gas limit linearly increases based on the size of the calldata. This is to prevent users from creating L2 resource usage without paying for it. This function can be used when interacting with the portal to ensure forwards compatibility." - }, - "params()": { - "notice": "EIP-1559 style gas parameters." - }, - "pause()": { - "notice": "Pauses withdrawals." - }, - "paused()": { - "notice": "Determines if cross domain messaging is paused. When set to true, withdrawals are paused. This may be removed in the future." - }, - "proveWithdrawalTransaction((uint256,address,address,uint256,uint256,bytes),uint256,(bytes32,bytes32,bytes32,bytes32),bytes[])": { - "notice": "Proves a withdrawal transaction." - }, - "provenWithdrawals(bytes32)": { - "notice": "A mapping of withdrawal hashes to `ProvenWithdrawal` data." - }, - "systemConfig()": { - "notice": "Address of the SystemConfig contract." - }, - "unpause()": { - "notice": "Unpauses withdrawals." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "Paused(address)": { - "notice": "Emitted when the pause is triggered." - }, - "TransactionDeposited(address,address,uint256,bytes)": { - "notice": "Emitted when a transaction is deposited from L1 to L2. The parameters of this event are read by the rollup node and used to derive deposit transactions on L2." - }, - "Unpaused(address)": { - "notice": "Emitted when the pause is lifted." - }, - "WithdrawalFinalized(bytes32,bool)": { - "notice": "Emitted when a withdrawal transaction is finalized." - }, - "WithdrawalProven(bytes32,address,address)": { - "notice": "Emitted when a withdrawal transaction is proven." - } - }, - "notice": "The OptimismPortal is a low-level contract responsible for passing messages between L1 and L2. Messages sent directly to the OptimismPortal have no form of replayability. Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/OptimismPortalProxy.json b/packages/contracts-bedrock/deployments/sepolia/OptimismPortalProxy.json deleted file mode 100644 index 745066c478fe..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/OptimismPortalProxy.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0x16Fc5058F25648194471939df75CF27A2fdC48BC", - "args": [ - "0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc" - ], - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"AdminChanged\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Upgraded\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"changeAdmin\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"upgradeTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/Proxy.sol\":\"Proxy\"},\"libraries\":{}},\"sources\":{\"src/universal/Proxy.sol\":{\"keccak256\":\"0x783aed9ff90b38a9898be5fb18699b3b249f012bc2c33f6537e1ab9f6444478f\",\"urls\":[\"bzz-raw://b119b1b68874f4d92a89cc05a4f0d25da73a959747a81e26739739a52895b844\",\"dweb:/ipfs/QmbKZqMd6CsM7annE7bCXcCi72syJAX3qtuFNPEGMCp13W\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": { - "transactionHash": "0xbc4e72f21589ed2f7b018fd442dff1804ba03d678731700e3d14bfea95179ddd", - "transactionIndex": "0x5", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0x419438", - "gasUsed": "0x7feb8", - "contractAddress": "0x16Fc5058F25648194471939df75CF27A2fdC48BC", - "logs": [ - { - "address": "0x16Fc5058F25648194471939df75CF27A2fdC48BC", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000189abaaaa82dfc015a588a7dbad6f13b1d3485bc", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "transactionHash": "0xbc4e72f21589ed2f7b018fd442dff1804ba03d678731700e3d14bfea95179ddd", - "transactionIndex": "0x5", - "logIndex": "0x5", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000010000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xbec78df7" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [], - "types": {} - }, - "transactionHash": "0xbc4e72f21589ed2f7b018fd442dff1804ba03d678731700e3d14bfea95179ddd", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/ProtocolVersions.json b/packages/contracts-bedrock/deployments/sepolia/ProtocolVersions.json deleted file mode 100644 index b34ca4bc7b31..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/ProtocolVersions.json +++ /dev/null @@ -1,496 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "version", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "enum ProtocolVersions.UpdateType", - "name": "updateType", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "ConfigUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "RECOMMENDED_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "REQUIRED_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "ProtocolVersion", - "name": "_required", - "type": "uint256" - }, - { - "internalType": "ProtocolVersion", - "name": "_recommended", - "type": "uint256" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "recommended", - "outputs": [ - { - "internalType": "ProtocolVersion", - "name": "out_", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "required", - "outputs": [ - { - "internalType": "ProtocolVersion", - "name": "out_", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "ProtocolVersion", - "name": "_recommended", - "type": "uint256" - } - ], - "name": "setRecommended", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "ProtocolVersion", - "name": "_required", - "type": "uint256" - } - ], - "name": "setRequired", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "args": [], - "bytecode": "0x60806040523480156200001157600080fd5b506200002261dead60008062000028565b620004c9565b600054600390610100900460ff161580156200004b575060005460ff8083169116105b620000b45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620000d26200013a565b620000dd84620001a2565b620000e88362000221565b620000f382620002d1565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b600054610100900460ff16620001965760405162461bcd60e51b815260206004820152602b602482015260008051602062000e9683398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b620001a062000332565b565b620001ac62000399565b6001600160a01b038116620002135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620000ab565b6200021e81620003f5565b50565b620002676200025260017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16200044b565b60001b826200044760201b620004f51760201c565b6000816040516020016200027d91815260200190565b60408051601f19818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051620002c5919062000471565b60405180910390a35050565b620003026200025260017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6200044b565b6000816040516020016200031891815260200190565b60408051601f198184030181529190529050600162000292565b600054610100900460ff166200038e5760405162461bcd60e51b815260206004820152602b602482015260008051602062000e9683398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000ab565b620001a033620003f5565b6033546001600160a01b03163314620001a05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000ab565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b9055565b6000828210156200046c57634e487b7160e01b600052601160045260246000fd5b500390565b600060208083528351808285015260005b81811015620004a05785810183015185820160400152820162000482565b81811115620004b3576000604083870101525b50601f01601f1916929092016040019392505050565b6109bd80620004d96000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e736600461085d565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161010091906108e1565b6100ec61016036600461085d565b61021d565b6100ec61022e565b6100ec61017b366004610924565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103ad565b6100f66103e6565b6100ec6101c6366004610957565b610416565b6100f66104ca565b6100f6600081565b6101e36104f9565b6101ec8161057a565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b81565b6102256104f9565b6101ec81610632565b6102366104f9565b61024060006106ac565b565b600054600390610100900460ff16158015610264575060005460ff8083169116105b6102f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561032e610723565b61033784610416565b6103408361057a565b61034982610632565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b60006103e16103dd60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b5490565b905090565b60006103e16103dd60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b61041e6104f9565b73ffffffffffffffffffffffffffffffffffffffff81166104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102ec565b6101ec816106ac565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102ec565b6105ad6105a860017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b829055565b6000816040516020016105c291815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161062691906108e1565b60405180910390a35050565b6106606105a860017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b60008160405160200161067591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060016105f5565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240600054610100900460ff16610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240336106ac565b60006020828403121561086f57600080fd5b5035919050565b6000815180845260005b8181101561089c57602081850181015186830182015201610880565b818111156108ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006108f46020830184610876565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091f57600080fd5b919050565b60008060006060848603121561093957600080fd5b610942846108fb565b95602085013595506040909401359392505050565b60006020828403121561096957600080fd5b6108f4826108fb565b6000828210156109ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e736600461085d565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161010091906108e1565b6100ec61016036600461085d565b61021d565b6100ec61022e565b6100ec61017b366004610924565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103ad565b6100f66103e6565b6100ec6101c6366004610957565b610416565b6100f66104ca565b6100f6600081565b6101e36104f9565b6101ec8161057a565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b81565b6102256104f9565b6101ec81610632565b6102366104f9565b61024060006106ac565b565b600054600390610100900460ff16158015610264575060005460ff8083169116105b6102f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561032e610723565b61033784610416565b6103408361057a565b61034982610632565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b60006103e16103dd60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b5490565b905090565b60006103e16103dd60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b61041e6104f9565b73ffffffffffffffffffffffffffffffffffffffff81166104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102ec565b6101ec816106ac565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102ec565b6105ad6105a860017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace1610972565b829055565b6000816040516020016105c291815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161062691906108e1565b60405180910390a35050565b6106606105a860017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b610972565b60008160405160200161067591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060016105f5565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240600054610100900460ff16610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240336106ac565b60006020828403121561086f57600080fd5b5035919050565b6000815180845260005b8181101561089c57602081850181015186830182015201610880565b818111156108ae576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006108f46020830184610876565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091f57600080fd5b919050565b60008060006060848603121561093957600080fd5b610942846108fb565b95602085013595506040909401359392505050565b60006020828403121561096957600080fd5b6108f4826108fb565b6000828210156109ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "initialize(address,uint256,uint256)": { - "params": { - "_owner": "Initial owner of the contract.", - "_recommended": "Recommended protocol version to operate on thi chain.", - "_required": "Required protocol version to operate on this chain." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "recommended()": { - "returns": { - "out_": "Recommended protocol version to sync to the head of the chain." - } - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "required()": { - "returns": { - "out_": "Required protocol version to sync to the head of the chain." - } - }, - "setRecommended(uint256)": { - "params": { - "_recommended": "New recommended protocol version." - } - }, - "setRequired(uint256)": { - "params": { - "_required": "New required protocol version." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "params": { - "data": "Encoded update data.", - "updateType": "Type of update.", - "version": "ProtocolVersion version." - } - } - }, - "title": "ProtocolVersions" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"enum ProtocolVersions.UpdateType\",\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ConfigUpdate\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"RECOMMENDED_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"REQUIRED_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"ProtocolVersion\",\"name\":\"_required\",\"type\":\"uint256\"},{\"internalType\":\"ProtocolVersion\",\"name\":\"_recommended\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"recommended\",\"outputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"out_\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"renounceOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"required\",\"outputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"out_\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"_recommended\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setRecommended\"},{\"inputs\":[{\"internalType\":\"ProtocolVersion\",\"name\":\"_required\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setRequired\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address,uint256,uint256)\":{\"params\":{\"_owner\":\"Initial owner of the contract.\",\"_recommended\":\"Recommended protocol version to operate on thi chain.\",\"_required\":\"Required protocol version to operate on this chain.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"recommended()\":{\"returns\":{\"out_\":\"Recommended protocol version to sync to the head of the chain.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"required()\":{\"returns\":{\"out_\":\"Required protocol version to sync to the head of the chain.\"}},\"setRecommended(uint256)\":{\"params\":{\"_recommended\":\"New recommended protocol version.\"}},\"setRequired(uint256)\":{\"params\":{\"_required\":\"New required protocol version.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"RECOMMENDED_SLOT()\":{\"notice\":\"Storage slot that the recommended protocol version is stored at.\"},\"REQUIRED_SLOT()\":{\"notice\":\"Storage slot that the required protocol version is stored at.\"},\"VERSION()\":{\"notice\":\"Version identifier, used for upgrades.\"},\"constructor\":{\"notice\":\"Constructs the ProtocolVersion contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)` A zero version is considered empty and is ignored by nodes.\"},\"initialize(address,uint256,uint256)\":{\"notice\":\"Initializer.\"},\"recommended()\":{\"notice\":\"High level getter for the recommended protocol version.\"},\"required()\":{\"notice\":\"High level getter for the required protocol version.\"},\"setRecommended(uint256)\":{\"notice\":\"Updates the recommended protocol version. Can only be called by the owner.\"},\"setRequired(uint256)\":{\"notice\":\"Updates the required protocol version. Can only be called by the owner.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/ProtocolVersions.sol\":\"ProtocolVersions\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ProtocolVersions.sol\":{\"keccak256\":\"0xa283721c36e2ba3ea1c61faebc364a8884bf3a276f80374cc8017d0e23ea1dfc\",\"urls\":[\"bzz-raw://4ee23cbc9772213c637c767747e5fb1db7c3f0f17d6a1ff576b638f25c6799e8\",\"dweb:/ipfs/QmfKZfFC6fyhQdLk2YrjVBL6eRX1d9CTrPHj7fNPUNXmEq\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 2, - "receipt": { - "transactionHash": "0x3e058627192fd891a3d6660f21a874e78bac77643013ef46505962d9c7e68477", - "transactionIndex": "0x7", - "blockHash": "0x1757e9d553875bd033f03f68b1e4494db5258e626f0853156717dd64b6cdb98a", - "blockNumber": "0x438a06", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "cumulativeGasUsed": "0x49734a", - "gasUsed": "0xa3523", - "contractAddress": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "logs": [ - { - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c" - ], - "data": "0x", - "blockHash": "0x1757e9d553875bd033f03f68b1e4494db5258e626f0853156717dd64b6cdb98a", - "blockNumber": "0x438a06", - "transactionHash": "0x3e058627192fd891a3d6660f21a874e78bac77643013ef46505962d9c7e68477", - "transactionIndex": "0x7", - "logIndex": "0x1c", - "removed": false - }, - { - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "0x000000000000000000000000000000000000000000000000000000000000dead" - ], - "data": "0x", - "blockHash": "0x1757e9d553875bd033f03f68b1e4494db5258e626f0853156717dd64b6cdb98a", - "blockNumber": "0x438a06", - "transactionHash": "0x3e058627192fd891a3d6660f21a874e78bac77643013ef46505962d9c7e68477", - "transactionIndex": "0x7", - "logIndex": "0x1d", - "removed": false - }, - { - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1757e9d553875bd033f03f68b1e4494db5258e626f0853156717dd64b6cdb98a", - "blockNumber": "0x438a06", - "transactionHash": "0x3e058627192fd891a3d6660f21a874e78bac77643013ef46505962d9c7e68477", - "transactionIndex": "0x7", - "logIndex": "0x1e", - "removed": false - }, - { - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000001" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1757e9d553875bd033f03f68b1e4494db5258e626f0853156717dd64b6cdb98a", - "blockNumber": "0x438a06", - "transactionHash": "0x3e058627192fd891a3d6660f21a874e78bac77643013ef46505962d9c7e68477", - "transactionIndex": "0x7", - "logIndex": "0x1f", - "removed": false - }, - { - "address": "0x42F0bD8313ad456A38061308857b2383fe2c72a0", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000003", - "blockHash": "0x1757e9d553875bd033f03f68b1e4494db5258e626f0853156717dd64b6cdb98a", - "blockNumber": "0x438a06", - "transactionHash": "0x3e058627192fd891a3d6660f21a874e78bac77643013ef46505962d9c7e68477", - "transactionIndex": "0x7", - "logIndex": "0x20", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000010000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000008000001000000040000000000000000000000000000000000000001000000040000000000000000000000000000020000000000000000000800000000000000000000000800000000400000000000000000000004040000000000000000001080000000000000000000000000000001000000000080000400000000000000000000000000000000000000000400000000000000000000040000000000000000000000000000000060000000000000000000000000000000000080000000000000000000008000000000", - "type": "0x2", - "effectiveGasPrice": "0xb3abbc06" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 29536, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 29539, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 31067, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 29408, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 29528, - "contract": "src/L1/ProtocolVersions.sol:ProtocolVersions", - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x3e058627192fd891a3d6660f21a874e78bac77643013ef46505962d9c7e68477", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "RECOMMENDED_SLOT()": { - "notice": "Storage slot that the recommended protocol version is stored at." - }, - "REQUIRED_SLOT()": { - "notice": "Storage slot that the required protocol version is stored at." - }, - "VERSION()": { - "notice": "Version identifier, used for upgrades." - }, - "constructor": { - "notice": "Constructs the ProtocolVersion contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)` A zero version is considered empty and is ignored by nodes." - }, - "initialize(address,uint256,uint256)": { - "notice": "Initializer." - }, - "recommended()": { - "notice": "High level getter for the recommended protocol version." - }, - "required()": { - "notice": "High level getter for the required protocol version." - }, - "setRecommended(uint256)": { - "notice": "Updates the recommended protocol version. Can only be called by the owner." - }, - "setRequired(uint256)": { - "notice": "Updates the required protocol version. Can only be called by the owner." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "notice": "Emitted when configuration is updated." - } - }, - "notice": "The ProtocolVersions contract is used to manage superchain protocol version information." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/ProtocolVersionsProxy.json b/packages/contracts-bedrock/deployments/sepolia/ProtocolVersionsProxy.json deleted file mode 100644 index 740dae175468..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/ProtocolVersionsProxy.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0x79ADD5713B383DAa0a138d3C4780C7A1804a8090", - "args": [ - "0x0a08E04c73f22C65D6dBFF20f87171240df6E519" - ], - "bytecode": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"AdminChanged\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Upgraded\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"changeAdmin\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"upgradeTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/Proxy.sol\":\"Proxy\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/universal/Proxy.sol\":{\"keccak256\":\"0xc56de5e39cd44eaeb93f0f8705dd07f4a89f66d5c186522532cf899a104cdbca\",\"urls\":[\"bzz-raw://cd1b595148fa62a798343a23e3330e79fef7d747f039d664482044be9ec0ccf3\",\"dweb:/ipfs/QmeAft6H9wbc9zZZ3prtRaBGGzcPy9yExKAhZHjp1iZ8UF\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 1, - "receipt": { - "transactionHash": "0xb38d6a449755fc90b9b4a96879c896aa21e156b0363aabec9959d71b554c1060", - "transactionIndex": "0x1", - "blockHash": "0x294120db9ff8f22f5d95b4bcc5dffb23af2cc6f7b02ce2726de0de377f10e03a", - "blockNumber": "0x44bb94", - "from": "0x0a08E04c73f22C65D6dBFF20f87171240df6E519", - "to": null, - "cumulativeGasUsed": "0x135be4", - "gasUsed": "0x80250", - "contractAddress": "0x79ADD5713B383DAa0a138d3C4780C7A1804a8090", - "logs": [ - { - "address": "0x79ADD5713B383DAa0a138d3C4780C7A1804a8090", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a08e04c73f22c65d6dbff20f87171240df6e519", - "blockHash": "0x294120db9ff8f22f5d95b4bcc5dffb23af2cc6f7b02ce2726de0de377f10e03a", - "blockNumber": "0x44bb94", - "transactionHash": "0xb38d6a449755fc90b9b4a96879c896aa21e156b0363aabec9959d71b554c1060", - "transactionIndex": "0x1", - "logIndex": "0x4", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000800000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xb2d05e10" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [], - "types": {} - }, - "transactionHash": "0xb38d6a449755fc90b9b4a96879c896aa21e156b0363aabec9959d71b554c1060", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/ProxyAdmin.json b/packages/contracts-bedrock/deployments/sepolia/ProxyAdmin.json deleted file mode 100644 index 670cdc4a4504..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/ProxyAdmin.json +++ /dev/null @@ -1,579 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "addressManager", - "outputs": [ - { - "internalType": "contract AddressManager", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "_newAdmin", - "type": "address" - } - ], - "name": "changeProxyAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - } - ], - "name": "getProxyAdmin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_proxy", - "type": "address" - } - ], - "name": "getProxyImplementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "implementationName", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isUpgrading", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "proxyType", - "outputs": [ - { - "internalType": "enum ProxyAdmin.ProxyType", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "address", - "name": "_address", - "type": "address" - } - ], - "name": "setAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract AddressManager", - "name": "_address", - "type": "address" - } - ], - "name": "setAddressManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_address", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "setImplementationName", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_address", - "type": "address" - }, - { - "internalType": "enum ProxyAdmin.ProxyType", - "name": "_type", - "type": "uint8" - } - ], - "name": "setProxyType", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "_upgrading", - "type": "bool" - } - ], - "name": "setUpgrading", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgrade", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address payable", - "name": "_proxy", - "type": "address" - }, - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - } - ], - "address": "0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc", - "args": [ - "0x18394B52d3Cb931dfA76F63251919D051953413d" - ], - "bytecode": "0x60806040523480156200001157600080fd5b5060405162001a5f38038062001a5f8339810160408190526200003491620000a1565b6200003f3362000051565b6200004a8162000051565b50620000d3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208284031215620000b457600080fd5b81516001600160a01b0381168114620000cc57600080fd5b9392505050565b61197c80620000e36000396000f3fe60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a", - "deployedBytecode": "0x60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "changeProxyAdmin(address,address)": { - "params": { - "_newAdmin": "Address of the new proxy admin.", - "_proxy": "Address of the proxy to update." - } - }, - "constructor": { - "params": { - "_owner": "Address of the initial owner of this contract." - } - }, - "getProxyAdmin(address)": { - "params": { - "_proxy": "Address of the proxy to get the admin of." - }, - "returns": { - "_0": "Address of the admin of the proxy." - } - }, - "getProxyImplementation(address)": { - "params": { - "_proxy": "Address of the proxy to get the implementation of." - }, - "returns": { - "_0": "Address of the implementation of the proxy." - } - }, - "isUpgrading()": { - "returns": { - "_0": "Whether or not there is an upgrade going on. May not actually tell you whether an upgrade is going on, since we don't currently plan to use this variable for anything other than a legacy indicator to fix a UX bug in the ChugSplash proxy." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "setAddress(string,address)": { - "params": { - "_address": "Address to attach to the given name.", - "_name": "Name to set within the AddressManager." - } - }, - "setAddressManager(address)": { - "params": { - "_address": "Address of the AddressManager." - } - }, - "setImplementationName(address,string)": { - "params": { - "_address": "Address of the ResolvedDelegateProxy.", - "_name": "Name of the implementation for the proxy." - } - }, - "setProxyType(address,uint8)": { - "params": { - "_address": "Address of the proxy.", - "_type": "Type of the proxy." - } - }, - "setUpgrading(bool)": { - "params": { - "_upgrading": "Whether or not the system is upgrading." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - }, - "upgrade(address,address)": { - "params": { - "_implementation": "Address of the new implementation address.", - "_proxy": "Address of the proxy to upgrade." - } - }, - "upgradeAndCall(address,address,bytes)": { - "params": { - "_data": "Data to trigger the new implementation with.", - "_implementation": "Address of the new implementation address.", - "_proxy": "Address of the proxy to upgrade." - } - } - }, - "title": "ProxyAdmin" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"contract AddressManager\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_newAdmin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"changeProxyAdmin\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_proxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"implementationName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"proxyType\",\"outputs\":[{\"internalType\":\"enum ProxyAdmin.ProxyType\",\"name\":\"\",\"type\":\"uint8\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"renounceOwnership\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setAddress\"},{\"inputs\":[{\"internalType\":\"contract AddressManager\",\"name\":\"_address\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setAddressManager\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setImplementationName\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"enum ProxyAdmin.ProxyType\",\"name\":\"_type\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setProxyType\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_upgrading\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setUpgrading\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferOwnership\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"upgrade\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"upgradeAndCall\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"params\":{\"_newAdmin\":\"Address of the new proxy admin.\",\"_proxy\":\"Address of the proxy to update.\"}},\"constructor\":{\"params\":{\"_owner\":\"Address of the initial owner of this contract.\"}},\"getProxyAdmin(address)\":{\"params\":{\"_proxy\":\"Address of the proxy to get the admin of.\"},\"returns\":{\"_0\":\"Address of the admin of the proxy.\"}},\"getProxyImplementation(address)\":{\"params\":{\"_proxy\":\"Address of the proxy to get the implementation of.\"},\"returns\":{\"_0\":\"Address of the implementation of the proxy.\"}},\"isUpgrading()\":{\"custom:legacy\":\"@notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\",\"returns\":{\"_0\":\"Whether or not there is an upgrade going on. May not actually tell you whether an upgrade is going on, since we don't currently plan to use this variable for anything other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setAddress(string,address)\":{\"custom:legacy\":\"@notice Set an address in the address manager. Since only the owner of the AddressManager can directly modify addresses and the ProxyAdmin will own the AddressManager, this gives the owner of the ProxyAdmin the ability to modify addresses directly.\",\"params\":{\"_address\":\"Address to attach to the given name.\",\"_name\":\"Name to set within the AddressManager.\"}},\"setAddressManager(address)\":{\"params\":{\"_address\":\"Address of the AddressManager.\"}},\"setImplementationName(address,string)\":{\"params\":{\"_address\":\"Address of the ResolvedDelegateProxy.\",\"_name\":\"Name of the implementation for the proxy.\"}},\"setProxyType(address,uint8)\":{\"params\":{\"_address\":\"Address of the proxy.\",\"_type\":\"Type of the proxy.\"}},\"setUpgrading(bool)\":{\"custom:legacy\":\"@notice Set the upgrading status for the Chugsplash proxy type.\",\"params\":{\"_upgrading\":\"Whether or not the system is upgrading.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"params\":{\"_implementation\":\"Address of the new implementation address.\",\"_proxy\":\"Address of the proxy to upgrade.\"}},\"upgradeAndCall(address,address,bytes)\":{\"params\":{\"_data\":\"Data to trigger the new implementation with.\",\"_implementation\":\"Address of the new implementation address.\",\"_proxy\":\"Address of the proxy to upgrade.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addressManager()\":{\"notice\":\"The address of the address manager, this is required to manage the ResolvedDelegateProxy type.\"},\"changeProxyAdmin(address,address)\":{\"notice\":\"Updates the admin of the given proxy address.\"},\"getProxyAdmin(address)\":{\"notice\":\"Returns the admin of the given proxy address.\"},\"getProxyImplementation(address)\":{\"notice\":\"Returns the implementation of the given proxy address.\"},\"implementationName(address)\":{\"notice\":\"A reverse mapping of addresses to names held in the AddressManager. This must be manually kept up to date with changes in the AddressManager for this contract to be able to work as an admin for the ResolvedDelegateProxy type.\"},\"proxyType(address)\":{\"notice\":\"A mapping of proxy types, used for backwards compatibility.\"},\"setAddressManager(address)\":{\"notice\":\"Set the address of the AddressManager. This is required to manage legacy ResolvedDelegateProxy type proxy contracts.\"},\"setImplementationName(address,string)\":{\"notice\":\"Sets the implementation name for a given address. Only required for ResolvedDelegateProxy type proxies that have an implementation name.\"},\"setProxyType(address,uint8)\":{\"notice\":\"Sets the proxy type for a given address. Only required for non-standard (legacy) proxy types.\"},\"upgrade(address,address)\":{\"notice\":\"Changes a proxy's implementation contract.\"},\"upgradeAndCall(address,address,bytes)\":{\"notice\":\"Changes a proxy's implementation contract and delegatecalls the new implementation with some given data. Useful for atomic upgrade-and-initialize calls.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/ProxyAdmin.sol\":\"ProxyAdmin\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"urls\":[\"bzz-raw://40fb1b5102468f783961d0af743f91b9980cf66b50d1d12009f6bb1869cea4d2\",\"dweb:/ipfs/QmYqEbJML4jB1GHbzD4cUZDtJg5wVwNm3vDJq1GbyDus8y\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"urls\":[\"bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92\",\"dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3\"],\"license\":\"MIT\"},\"src/legacy/AddressManager.sol\":{\"keccak256\":\"0x1fcb990df6473f7fa360d5924d62d39ce2ca97d45668e3901e5405cfbe598b19\",\"urls\":[\"bzz-raw://9d08358b60dea54dbc32e988a1bb7ea909488063eaae3c5ae28a322f125c9b34\",\"dweb:/ipfs/QmZPQwdjLh9gaamNAoTUmWwwbRKj3yHovBYfnTPnfuKvUt\"],\"license\":\"MIT\"},\"src/legacy/L1ChugSplashProxy.sol\":{\"keccak256\":\"0x102ea9c1eac2bbc071e38fdcc8d92deda3e7f32dc72d57fa3fe315cef354a5fe\",\"urls\":[\"bzz-raw://42efc6f277dd5f9ed874dbc6e214d481a26cc71751d505a75b44d86ecf8e4815\",\"dweb:/ipfs/QmUZLYii4uBr5JrWz8NTaaYkX56VvygKSqziKqGHuzM2Wr\"],\"license\":\"MIT\"},\"src/universal/Proxy.sol\":{\"keccak256\":\"0x783aed9ff90b38a9898be5fb18699b3b249f012bc2c33f6537e1ab9f6444478f\",\"urls\":[\"bzz-raw://b119b1b68874f4d92a89cc05a4f0d25da73a959747a81e26739739a52895b844\",\"dweb:/ipfs/QmbKZqMd6CsM7annE7bCXcCi72syJAX3qtuFNPEGMCp13W\"],\"license\":\"MIT\"},\"src/universal/ProxyAdmin.sol\":{\"keccak256\":\"0xacc43c5531cdb4ab39a66f7cadce5237fe50524d09ec9a247556501832e95b39\",\"urls\":[\"bzz-raw://ddfbac05eb0a63ae377e50e1fdb477558f68eed2bc38ccbd6faae866b0cdebfa\",\"dweb:/ipfs/QmcRkpxA5cGKboA2dFCqBUBLZy1U911arKBnPygcp2xXFi\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": { - "transactionHash": "0x33d37db3eb5f0dae04a7654e3d6028af3270ca60e9904ff61a5d3b84178d1231", - "transactionIndex": "0x3", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0x38e1ae", - "gasUsed": "0x16a4b9", - "contractAddress": "0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc", - "logs": [ - { - "address": "0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000018394b52d3cb931dfa76f63251919d051953413d" - ], - "data": "0x", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "transactionHash": "0x33d37db3eb5f0dae04a7654e3d6028af3270ca60e9904ff61a5d3b84178d1231", - "transactionIndex": "0x3", - "logIndex": "0x3", - "removed": false - }, - { - "address": "0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x00000000000000000000000018394b52d3cb931dfa76f63251919d051953413d", - "0x00000000000000000000000018394b52d3cb931dfa76f63251919d051953413d" - ], - "data": "0x", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "transactionHash": "0x33d37db3eb5f0dae04a7654e3d6028af3270ca60e9904ff61a5d3b84178d1231", - "transactionIndex": "0x3", - "logIndex": "0x4", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000100000000000000000000000000000000000000000000800000000000000000000000000000000000010000000000000000000000040000000000000000000000000000000000000000000000000001000000008000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xbec78df7" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 31896, - "contract": "src/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "_owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 70723, - "contract": "src/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "proxyType", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_address,t_enum(ProxyType)70717)" - }, - { - "astId": 70728, - "contract": "src/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "implementationName", - "offset": 0, - "slot": "2", - "type": "t_mapping(t_address,t_string_storage)" - }, - { - "astId": 70732, - "contract": "src/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "addressManager", - "offset": 0, - "slot": "3", - "type": "t_contract(AddressManager)62454" - }, - { - "astId": 70735, - "contract": "src/universal/ProxyAdmin.sol:ProxyAdmin", - "label": "upgrading", - "offset": 20, - "slot": "3", - "type": "t_bool" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(AddressManager)62454": { - "encoding": "inplace", - "label": "contract AddressManager", - "numberOfBytes": "20" - }, - "t_enum(ProxyType)70717": { - "encoding": "inplace", - "label": "enum ProxyAdmin.ProxyType", - "numberOfBytes": "1" - }, - "t_mapping(t_address,t_enum(ProxyType)70717)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => enum ProxyAdmin.ProxyType)", - "numberOfBytes": "32", - "value": "t_enum(ProxyType)70717" - }, - "t_mapping(t_address,t_string_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => string)", - "numberOfBytes": "32", - "value": "t_string_storage" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - } - } - }, - "transactionHash": "0x33d37db3eb5f0dae04a7654e3d6028af3270ca60e9904ff61a5d3b84178d1231", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "addressManager()": { - "notice": "The address of the address manager, this is required to manage the ResolvedDelegateProxy type." - }, - "changeProxyAdmin(address,address)": { - "notice": "Updates the admin of the given proxy address." - }, - "getProxyAdmin(address)": { - "notice": "Returns the admin of the given proxy address." - }, - "getProxyImplementation(address)": { - "notice": "Returns the implementation of the given proxy address." - }, - "implementationName(address)": { - "notice": "A reverse mapping of addresses to names held in the AddressManager. This must be manually kept up to date with changes in the AddressManager for this contract to be able to work as an admin for the ResolvedDelegateProxy type." - }, - "proxyType(address)": { - "notice": "A mapping of proxy types, used for backwards compatibility." - }, - "setAddressManager(address)": { - "notice": "Set the address of the AddressManager. This is required to manage legacy ResolvedDelegateProxy type proxy contracts." - }, - "setImplementationName(address,string)": { - "notice": "Sets the implementation name for a given address. Only required for ResolvedDelegateProxy type proxies that have an implementation name." - }, - "setProxyType(address,uint8)": { - "notice": "Sets the proxy type for a given address. Only required for non-standard (legacy) proxy types." - }, - "upgrade(address,address)": { - "notice": "Changes a proxy's implementation contract." - }, - "upgradeAndCall(address,address,bytes)": { - "notice": "Changes a proxy's implementation contract and delegatecalls the new implementation with some given data. Useful for atomic upgrade-and-initialize calls." - } - }, - "notice": "This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy, based on the OpenZeppelin implementation. It has backwards compatibility logic to work with the various types of proxies that have been deployed by Optimism in the past." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/SystemConfig.json b/packages/contracts-bedrock/deployments/sepolia/SystemConfig.json deleted file mode 100644 index 7368d84711e7..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/SystemConfig.json +++ /dev/null @@ -1,1197 +0,0 @@ -{ - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "version", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "enum SystemConfig.UpdateType", - "name": "updateType", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "ConfigUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "BATCH_INBOX_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_CROSS_DOMAIN_MESSENGER_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_ERC_721_BRIDGE_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_STANDARD_BRIDGE_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_OUTPUT_ORACLE_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPTIMISM_PORTAL_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "UNSAFE_BLOCK_SIGNER_SLOT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "batchInbox", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "batcherHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "gasLimit", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_overhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_scalar", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_batcherHash", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - }, - { - "internalType": "address", - "name": "_unsafeBlockSigner", - "type": "address" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "_config", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "_startBlock", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_batchInbox", - "type": "address" - }, - { - "components": [ - { - "internalType": "address", - "name": "l1CrossDomainMessenger", - "type": "address" - }, - { - "internalType": "address", - "name": "l1ERC721Bridge", - "type": "address" - }, - { - "internalType": "address", - "name": "l1StandardBridge", - "type": "address" - }, - { - "internalType": "address", - "name": "l2OutputOracle", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismPortal", - "type": "address" - }, - { - "internalType": "address", - "name": "optimismMintableERC20Factory", - "type": "address" - } - ], - "internalType": "struct SystemConfig.Addresses", - "name": "_addresses", - "type": "tuple" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "l1CrossDomainMessenger", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1ERC721Bridge", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l1StandardBridge", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "l2OutputOracle", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minimumGasLimit", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "optimismMintableERC20Factory", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "optimismPortal", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "overhead", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "resourceConfig", - "outputs": [ - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "scalar", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_batcherHash", - "type": "bytes32" - } - ], - "name": "setBatcherHash", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_overhead", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_scalar", - "type": "uint256" - } - ], - "name": "setGasConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - } - ], - "name": "setGasLimit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint32", - "name": "maxResourceLimit", - "type": "uint32" - }, - { - "internalType": "uint8", - "name": "elasticityMultiplier", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "baseFeeMaxChangeDenominator", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "minimumBaseFee", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "systemTxMaxGas", - "type": "uint32" - }, - { - "internalType": "uint128", - "name": "maximumBaseFee", - "type": "uint128" - } - ], - "internalType": "struct ResourceMetering.ResourceConfig", - "name": "_config", - "type": "tuple" - } - ], - "name": "setResourceConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_unsafeBlockSigner", - "type": "address" - } - ], - "name": "setUnsafeBlockSigner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "startBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "unsafeBlockSigner", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "args": [], - "bytecode": "0x60806040523480156200001157600080fd5b506040805160c080820183526001808352602080840182905260028486015260006060808601829052608080870183905260a08088018490528851968701895283875293860183905296850182905284018190529483018590528201849052620000909361dead93909283928392909183919060001990839062000096565b62000ccc565b600054600390610100900460ff16158015620000b9575060005460ff8083169116105b620001225760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055620001406200043a565b6200014b8b620004a2565b620001568862000521565b620001628a8a62000573565b6200016d87620005d7565b620001788662000674565b620001be620001a960017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59862000ba9565b60001b84620006dc60201b62000d211760201c565b62000208620001ef60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063762000ba9565b60001b8360000151620006dc60201b62000d211760201c565b620002526200023960017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a862000ba9565b60001b8360200151620006dc60201b62000d211760201c565b6200029c6200028360017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637762000ba9565b60001b8360400151620006dc60201b62000d211760201c565b620002e6620002cd60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a687181662000ba9565b60001b8360600151620006dc60201b62000d211760201c565b620003306200031760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad62000ba9565b60001b8360800151620006dc60201b62000d211760201c565b6200037a6200036160017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d62000ba9565b60001b8360a00151620006dc60201b62000d211760201c565b6200038584620006e0565b62000390856200070d565b6200039a62000a51565b6001600160401b0316876001600160401b03161015620003ec5760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b600054610100900460ff16620004965760405162461bcd60e51b815260206004820152602b60248201526000805160206200285f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000119565b620004a062000a7e565b565b620004ac62000ae5565b6001600160a01b038116620005135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000119565b6200051e8162000b41565b50565b60678190556040805160208082018490528251808303909101815290820190915260005b60006000805160206200283f8339815191528360405162000567919062000bc3565b60405180910390a35050565b60658290556066819055604080516020810184905290810182905260009060600160408051601f198184030181529190529050600160006000805160206200283f83398151915283604051620005ca919062000bc3565b60405180910390a3505050565b620005e162000a51565b6001600160401b0316816001600160401b03161015620006335760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b606880546001600160401b0319166001600160401b038316908117909155604080516020808201939093528151808203909301835281019052600262000545565b620006ab7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0882620006dc60201b62000d211760201c565b604080516001600160a01b03831660208201526000910160408051601f198184030181529190529050600362000545565b9055565b8015801590620006f05750606a54155b15620006fb57606a55565b606a546000036200051e5743606a5550565b8060a001516001600160801b0316816060015163ffffffff1611156200079c5760405162461bcd60e51b815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840162000119565b6001816040015160ff16116200080d5760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201526e65206c6172676572207468616e203160881b606482015260840162000119565b606854608082015182516001600160401b03909216916200082f919062000c1b565b63ffffffff161115620008745760405162461bcd60e51b815260206004820152601f60248201526000805160206200281f833981519152604482015260640162000119565b6000816020015160ff1611620008e55760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201526e06965722063616e6e6f74206265203608c1b606482015260840162000119565b8051602082015163ffffffff82169160ff909116906200090790829062000c46565b62000913919062000c78565b63ffffffff16146200098e5760405162461bcd60e51b815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840162000119565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff96871664ffffffffff199095169490941764010000000060ff948516021764ffffffffff60281b191665010000000000939092169290920263ffffffff60301b19161766010000000000009185169190910217600160501b600160f01b0319166a01000000000000000000009390941692909202600160701b600160f01b03191692909217600160701b6001600160801b0390921691909102179055565b60695460009062000a799063ffffffff6a010000000000000000000082048116911662000ca7565b905090565b600054610100900460ff1662000ada5760405162461bcd60e51b815260206004820152602b60248201526000805160206200285f83398151915260448201526a6e697469616c697a696e6760a81b606482015260840162000119565b620004a03362000b41565b6033546001600160a01b03163314620004a05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000119565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052601160045260246000fd5b60008282101562000bbe5762000bbe62000b93565b500390565b600060208083528351808285015260005b8181101562000bf25785810183015185820160400152820162000bd4565b8181111562000c05576000604083870101525b50601f01601f1916929092016040019392505050565b600063ffffffff80831681851680830382111562000c3d5762000c3d62000b93565b01949350505050565b600063ffffffff8084168062000c6c57634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b600063ffffffff8083168185168183048111821515161562000c9e5762000c9e62000b93565b02949350505050565b60006001600160401b0382811684821680830382111562000c3d5762000c3d62000b93565b611b438062000cdc6000396000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c8063935f029e1161012a578063cc731b02116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610575578063fd32aa0f1461057d578063ffa1ad741461058557600080fd5b8063f45e65d814610558578063f68016b71461056157600080fd5b8063cc731b0214610400578063dac6e63a14610534578063e81b2c6d1461053c578063f2fde38b1461054557600080fd5b8063bc49ce5f116100f9578063bc49ce5f146103ca578063c4e8ddfa146103d2578063c71973f6146103da578063c9b26f61146103ed57600080fd5b8063935f029e146103945780639b7d7f0a146103a7578063a7119869146103af578063b40a817c146103b757600080fd5b80634add321d116101bd57806354fd4d501161018c57806361d157681161017157806361d1576814610366578063715018a61461036e5780638da5cb5b1461037657600080fd5b806354fd4d50146103155780635d73369c1461035e57600080fd5b80634add321d146102b25780634d9f1559146102d35780634f16540b146102db5780635228a6ac1461030257600080fd5b806318d13918116101f957806318d139181461028457806319f5cea8146102995780631fd19ee1146102a157806348cd4cb1146102a957600080fd5b806306c926571461022b578063078f29cf146102465780630a49cb03146102735780630c18c1621461027b575b600080fd5b61023361058d565b6040519081526020015b60405180910390f35b61024e6105bb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023d565b61024e6105f4565b61023360655481565b610297610292366004611677565b610624565b005b610233610638565b61024e610663565b610233606a5481565b6102ba61068d565b60405167ffffffffffffffff909116815260200161023d565b61024e6106b3565b6102337f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b610297610310366004611807565b6106e3565b6103516040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b60405161023d91906119aa565b610233610a79565b610233610aa4565b610297610acf565b60335473ffffffffffffffffffffffffffffffffffffffff1661024e565b6102976103a23660046119bd565b610ae3565b61024e610af9565b61024e610b29565b6102976103c53660046119df565b610b59565b610233610b6a565b61024e610b95565b6102976103e83660046119fa565b610bc5565b6102976103fb366004611a16565b610bd6565b6104c46040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b60405161023d9190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61024e610be7565b61023360675481565b610297610553366004611677565b610c17565b61023360665481565b6068546102ba9067ffffffffffffffff1681565b610233610ccb565b610233610cf6565b610233600081565b6105b860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b81565b60006105ef6105eb60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b5490565b905090565b60006105ef6105eb60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b61062c610d25565b61063581610da6565b50565b6105b860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60006105ef7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b6069546000906105ef9063ffffffff6a0100000000000000000000820481169116611a75565b60006105ef6105eb60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b600054600390610100900460ff16158015610705575060005460ff8083169116105b610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556107cf610e63565b6107d88b610c17565b6107e188610f02565b6107eb8a8a610f2a565b6107f487610fbb565b6107fd86610da6565b61083061082b60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b849055565b61086461085e60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b83519055565b61089b61089260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60208401519055565b6108d26108c960017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b60408401519055565b61090961090060017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b60608401519055565b61094061093760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b60808401519055565b61097761096e60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60a08401519055565b61098084611099565b610989856110c3565b61099161068d565b67ffffffffffffffff168767ffffffffffffffff161015610a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b6105b860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b6105b860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b610ad7610d25565b610ae16000611537565b565b610aeb610d25565b610af58282610f2a565b5050565b60006105ef6105eb60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60006105ef6105eb60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b610b61610d25565b61063581610fbb565b6105b860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b60006105ef6105eb60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b610bcd610d25565b610635816110c3565b610bde610d25565b61063581610f02565b60006105ef6105eb60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b610c1f610d25565b73ffffffffffffffffffffffffffffffffffffffff8116610cc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161078d565b61063581611537565b6105b860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b6105b860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161078d565b610dcf7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610e5791906119aa565b60405180910390a35050565b600054610100900460ff16610efa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae16115ae565b6067819055604080516020808201849052825180830390910181529082019091526000610e26565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae91906119aa565b60405180910390a3505050565b610fc361068d565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610e26565b80158015906110a85750606a54155b156110b257606a55565b606a546000036106355743606a5550565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611173576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840161078d565b6001816040015160ff161161120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e20310000000000000000000000000000000000606482015260840161078d565b6068546080820151825167ffffffffffffffff9092169161122b9190611aa1565b63ffffffff161115611299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b6000816020015160ff1611611330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f7420626520300000000000000000000000000000000000606482015260840161078d565b8051602082015163ffffffff82169160ff90911690611350908290611ac0565b61135a9190611b0a565b63ffffffff16146113ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840161078d565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae133611537565b803573ffffffffffffffffffffffffffffffffffffffff8116811461167257600080fd5b919050565b60006020828403121561168957600080fd5b6116928261164e565b9392505050565b803567ffffffffffffffff8116811461167257600080fd5b60405160c0810167ffffffffffffffff811182821017156116fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff8116811461167257600080fd5b803560ff8116811461167257600080fd5b600060c0828403121561173857600080fd5b60405160c0810181811067ffffffffffffffff82111715611782577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061179183611701565b815261179f60208401611715565b60208201526117b060408401611715565b60408201526117c160608401611701565b60608201526117d260808401611701565b608082015260a08301356fffffffffffffffffffffffffffffffff811681146117fa57600080fd5b60a0919091015292915050565b6000806000806000806000806000808a8c0361028081121561182857600080fd5b6118318c61164e565b9a5060208c0135995060408c0135985060608c0135975061185460808d01611699565b965061186260a08d0161164e565b95506118718d60c08e01611726565b94506101808c013593506118886101a08d0161164e565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe40820112156118ba57600080fd5b506118c36116b1565b6118d06101c08d0161164e565b81526118df6101e08d0161164e565b60208201526118f16102008d0161164e565b60408201526119036102208d0161164e565b60608201526119156102408d0161164e565b60808201526119276102608d0161164e565b60a0820152809150509295989b9194979a5092959850565b6000815180845260005b8181101561196557602081850181015186830182015201611949565b81811115611977576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611692602083018461193f565b600080604083850312156119d057600080fd5b50508035926020909101359150565b6000602082840312156119f157600080fd5b61169282611699565b600060c08284031215611a0c57600080fd5b6116928383611726565b600060208284031215611a2857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611a7057611a70611a2f565b500390565b600067ffffffffffffffff808316818516808303821115611a9857611a98611a2f565b01949350505050565b600063ffffffff808316818516808303821115611a9857611a98611a2f565b600063ffffffff80841680611afe577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611b2d57611b2d611a2f565b0294935050505056fea164736f6c634300080f000a53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77001d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102265760003560e01c8063935f029e1161012a578063cc731b02116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610575578063fd32aa0f1461057d578063ffa1ad741461058557600080fd5b8063f45e65d814610558578063f68016b71461056157600080fd5b8063cc731b0214610400578063dac6e63a14610534578063e81b2c6d1461053c578063f2fde38b1461054557600080fd5b8063bc49ce5f116100f9578063bc49ce5f146103ca578063c4e8ddfa146103d2578063c71973f6146103da578063c9b26f61146103ed57600080fd5b8063935f029e146103945780639b7d7f0a146103a7578063a7119869146103af578063b40a817c146103b757600080fd5b80634add321d116101bd57806354fd4d501161018c57806361d157681161017157806361d1576814610366578063715018a61461036e5780638da5cb5b1461037657600080fd5b806354fd4d50146103155780635d73369c1461035e57600080fd5b80634add321d146102b25780634d9f1559146102d35780634f16540b146102db5780635228a6ac1461030257600080fd5b806318d13918116101f957806318d139181461028457806319f5cea8146102995780631fd19ee1146102a157806348cd4cb1146102a957600080fd5b806306c926571461022b578063078f29cf146102465780630a49cb03146102735780630c18c1621461027b575b600080fd5b61023361058d565b6040519081526020015b60405180910390f35b61024e6105bb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023d565b61024e6105f4565b61023360655481565b610297610292366004611677565b610624565b005b610233610638565b61024e610663565b610233606a5481565b6102ba61068d565b60405167ffffffffffffffff909116815260200161023d565b61024e6106b3565b6102337f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b610297610310366004611807565b6106e3565b6103516040518060400160405280600681526020017f312e31302e30000000000000000000000000000000000000000000000000000081525081565b60405161023d91906119aa565b610233610a79565b610233610aa4565b610297610acf565b60335473ffffffffffffffffffffffffffffffffffffffff1661024e565b6102976103a23660046119bd565b610ae3565b61024e610af9565b61024e610b29565b6102976103c53660046119df565b610b59565b610233610b6a565b61024e610b95565b6102976103e83660046119fa565b610bc5565b6102976103fb366004611a16565b610bd6565b6104c46040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b60405161023d9190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b61024e610be7565b61023360675481565b610297610553366004611677565b610c17565b61023360665481565b6068546102ba9067ffffffffffffffff1681565b610233610ccb565b610233610cf6565b610233600081565b6105b860017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b81565b60006105ef6105eb60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b5490565b905090565b60006105ef6105eb60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b61062c610d25565b61063581610da6565b50565b6105b860017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60006105ef7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b6069546000906105ef9063ffffffff6a0100000000000000000000820481169116611a75565b60006105ef6105eb60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b600054600390610100900460ff16158015610705575060005460ff8083169116105b610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556107cf610e63565b6107d88b610c17565b6107e188610f02565b6107eb8a8a610f2a565b6107f487610fbb565b6107fd86610da6565b61083061082b60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b849055565b61086461085e60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b83519055565b61089b61089260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b60208401519055565b6108d26108c960017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b60408401519055565b61090961090060017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b60608401519055565b61094061093760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b60808401519055565b61097761096e60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60a08401519055565b61098084611099565b610989856110c3565b61099161068d565b67ffffffffffffffff168767ffffffffffffffff161015610a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050505050565b6105b860017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b6105b860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611a5e565b610ad7610d25565b610ae16000611537565b565b610aeb610d25565b610af58282610f2a565b5050565b60006105ef6105eb60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611a5e565b60006105ef6105eb60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611a5e565b610b61610d25565b61063581610fbb565b6105b860017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b60006105ef6105eb60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611a5e565b610bcd610d25565b610635816110c3565b610bde610d25565b61063581610f02565b60006105ef6105eb60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611a5e565b610c1f610d25565b73ffffffffffffffffffffffffffffffffffffffff8116610cc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161078d565b61063581611537565b6105b860017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611a5e565b6105b860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611a5e565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161078d565b610dcf7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610e5791906119aa565b60405180910390a35050565b600054610100900460ff16610efa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae16115ae565b6067819055604080516020808201849052825180830390910181529082019091526000610e26565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae91906119aa565b60405180910390a3505050565b610fc361068d565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610e26565b80158015906110a85750606a54155b156110b257606a55565b606a546000036106355743606a5550565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611173576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840161078d565b6001816040015160ff161161120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e20310000000000000000000000000000000000606482015260840161078d565b6068546080820151825167ffffffffffffffff9092169161122b9190611aa1565b63ffffffff161115611299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161078d565b6000816020015160ff1611611330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f7420626520300000000000000000000000000000000000606482015260840161078d565b8051602082015163ffffffff82169160ff90911690611350908290611ac0565b61135a9190611b0a565b63ffffffff16146113ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840161078d565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161078d565b610ae133611537565b803573ffffffffffffffffffffffffffffffffffffffff8116811461167257600080fd5b919050565b60006020828403121561168957600080fd5b6116928261164e565b9392505050565b803567ffffffffffffffff8116811461167257600080fd5b60405160c0810167ffffffffffffffff811182821017156116fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff8116811461167257600080fd5b803560ff8116811461167257600080fd5b600060c0828403121561173857600080fd5b60405160c0810181811067ffffffffffffffff82111715611782577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290508061179183611701565b815261179f60208401611715565b60208201526117b060408401611715565b60408201526117c160608401611701565b60608201526117d260808401611701565b608082015260a08301356fffffffffffffffffffffffffffffffff811681146117fa57600080fd5b60a0919091015292915050565b6000806000806000806000806000808a8c0361028081121561182857600080fd5b6118318c61164e565b9a5060208c0135995060408c0135985060608c0135975061185460808d01611699565b965061186260a08d0161164e565b95506118718d60c08e01611726565b94506101808c013593506118886101a08d0161164e565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe40820112156118ba57600080fd5b506118c36116b1565b6118d06101c08d0161164e565b81526118df6101e08d0161164e565b60208201526118f16102008d0161164e565b60408201526119036102208d0161164e565b60608201526119156102408d0161164e565b60808201526119276102608d0161164e565b60a0820152809150509295989b9194979a5092959850565b6000815180845260005b8181101561196557602081850181015186830182015201611949565b81811115611977576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611692602083018461193f565b600080604083850312156119d057600080fd5b50508035926020909101359150565b6000602082840312156119f157600080fd5b61169282611699565b600060c08284031215611a0c57600080fd5b6116928383611726565b600060208284031215611a2857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611a7057611a70611a2f565b500390565b600067ffffffffffffffff808316818516808303821115611a9857611a98611a2f565b01949350505050565b600063ffffffff808316818516808303821115611a9857611a98611a2f565b600063ffffffff80841680611afe577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611b2d57611b2d611a2f565b0294935050505056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))": { - "params": { - "_addresses": "Set of L1 contract addresses. These should be the proxies.", - "_batchInbox": "Batch inbox address. An identifier for the op-node to find canonical data.", - "_batcherHash": "Initial batcher hash.", - "_config": "Initial ResourceConfig.", - "_gasLimit": "Initial gas limit.", - "_overhead": "Initial overhead value.", - "_owner": "Initial owner of the contract.", - "_scalar": "Initial scalar value.", - "_startBlock": "Starting block for the op-node to search for logs from. Contracts that were deployed before this field existed need to have this field set manually via an override. Newly deployed contracts should set this value to uint256(0).", - "_unsafeBlockSigner": "Initial unsafe block signer address." - } - }, - "minimumGasLimit()": { - "returns": { - "_0": "uint64 Minimum gas limit." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "resourceConfig()": { - "returns": { - "_0": "ResourceConfig" - } - }, - "setBatcherHash(bytes32)": { - "params": { - "_batcherHash": "New batcher hash." - } - }, - "setGasConfig(uint256,uint256)": { - "params": { - "_overhead": "New overhead value.", - "_scalar": "New scalar value." - } - }, - "setGasLimit(uint64)": { - "params": { - "_gasLimit": "New gas limit." - } - }, - "setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))": { - "params": { - "_config": "The new resource config values." - } - }, - "setUnsafeBlockSigner(address)": { - "params": { - "_unsafeBlockSigner": "New unsafe block signer address." - } - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - }, - "unsafeBlockSigner()": { - "returns": { - "addr_": "Address of the unsafe block signer." - } - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "params": { - "data": "Encoded update data.", - "updateType": "Type of update.", - "version": "SystemConfig version." - } - } - }, - "title": "SystemConfig" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true},{\"internalType\":\"enum SystemConfig.UpdateType\",\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ConfigUpdate\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false}],\"type\":\"event\",\"name\":\"Initialized\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"BATCH_INBOX_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L1_CROSS_DOMAIN_MESSENGER_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L1_ERC_721_BRIDGE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L1_STANDARD_BRIDGE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"L2_OUTPUT_ORACLE_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"OPTIMISM_PORTAL_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"UNSAFE_BLOCK_SIGNER_SLOT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"batchInbox\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"batcherHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"gasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_scalar\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_batcherHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"_unsafeBlockSigner\",\"type\":\"address\"},{\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"_config\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}]},{\"internalType\":\"uint256\",\"name\":\"_startBlock\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_batchInbox\",\"type\":\"address\"},{\"internalType\":\"struct SystemConfig.Addresses\",\"name\":\"_addresses\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"address\",\"name\":\"l1CrossDomainMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1ERC721Bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1StandardBridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l2OutputOracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismPortal\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"optimismMintableERC20Factory\",\"type\":\"address\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"initialize\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l1CrossDomainMessenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l1ERC721Bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l1StandardBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"l2OutputOracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"optimismMintableERC20Factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"optimismPortal\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"overhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"renounceOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"resourceConfig\",\"outputs\":[{\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}]}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"scalar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_batcherHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setBatcherHash\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_overhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_scalar\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setGasConfig\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setGasLimit\"},{\"inputs\":[{\"internalType\":\"struct ResourceMetering.ResourceConfig\",\"name\":\"_config\",\"type\":\"tuple\",\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxResourceLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"elasticityMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"minimumBaseFee\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"systemTxMaxGas\",\"type\":\"uint32\"},{\"internalType\":\"uint128\",\"name\":\"maximumBaseFee\",\"type\":\"uint128\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setResourceConfig\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_unsafeBlockSigner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setUnsafeBlockSigner\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"startBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferOwnership\"},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"unsafeBlockSigner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr_\",\"type\":\"address\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))\":{\"params\":{\"_addresses\":\"Set of L1 contract addresses. These should be the proxies.\",\"_batchInbox\":\"Batch inbox address. An identifier for the op-node to find canonical data.\",\"_batcherHash\":\"Initial batcher hash.\",\"_config\":\"Initial ResourceConfig.\",\"_gasLimit\":\"Initial gas limit.\",\"_overhead\":\"Initial overhead value.\",\"_owner\":\"Initial owner of the contract.\",\"_scalar\":\"Initial scalar value.\",\"_startBlock\":\"Starting block for the op-node to search for logs from. Contracts that were deployed before this field existed need to have this field set manually via an override. Newly deployed contracts should set this value to uint256(0).\",\"_unsafeBlockSigner\":\"Initial unsafe block signer address.\"}},\"minimumGasLimit()\":{\"returns\":{\"_0\":\"uint64 Minimum gas limit.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"resourceConfig()\":{\"returns\":{\"_0\":\"ResourceConfig\"}},\"setBatcherHash(bytes32)\":{\"params\":{\"_batcherHash\":\"New batcher hash.\"}},\"setGasConfig(uint256,uint256)\":{\"params\":{\"_overhead\":\"New overhead value.\",\"_scalar\":\"New scalar value.\"}},\"setGasLimit(uint64)\":{\"params\":{\"_gasLimit\":\"New gas limit.\"}},\"setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))\":{\"params\":{\"_config\":\"The new resource config values.\"}},\"setUnsafeBlockSigner(address)\":{\"params\":{\"_unsafeBlockSigner\":\"New unsafe block signer address.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unsafeBlockSigner()\":{\"returns\":{\"addr_\":\"Address of the unsafe block signer.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BATCH_INBOX_SLOT()\":{\"notice\":\"Storage slot that the batch inbox address is stored at.\"},\"L1_CROSS_DOMAIN_MESSENGER_SLOT()\":{\"notice\":\"Storage slot that the L1CrossDomainMessenger address is stored at.\"},\"L1_ERC_721_BRIDGE_SLOT()\":{\"notice\":\"Storage slot that the L1ERC721Bridge address is stored at.\"},\"L1_STANDARD_BRIDGE_SLOT()\":{\"notice\":\"Storage slot that the L1StandardBridge address is stored at.\"},\"L2_OUTPUT_ORACLE_SLOT()\":{\"notice\":\"Storage slot that the L2OutputOracle address is stored at.\"},\"OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT()\":{\"notice\":\"Storage slot that the OptimismMintableERC20Factory address is stored at.\"},\"OPTIMISM_PORTAL_SLOT()\":{\"notice\":\"Storage slot that the OptimismPortal address is stored at.\"},\"UNSAFE_BLOCK_SIGNER_SLOT()\":{\"notice\":\"Storage slot that the unsafe block signer is stored at. Storing it at this deterministic storage slot allows for decoupling the storage layout from the way that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value.\"},\"VERSION()\":{\"notice\":\"Version identifier, used for upgrades.\"},\"batchInbox()\":{\"notice\":\"Getter for the BatchInbox address.\"},\"batcherHash()\":{\"notice\":\"Identifier for the batcher. For version 1 of this configuration, this is represented as an address left-padded with zeros to 32 bytes.\"},\"constructor\":{\"notice\":\"Constructs the SystemConfig contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)`\"},\"gasLimit()\":{\"notice\":\"L2 block gas limit.\"},\"initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))\":{\"notice\":\"Initializer. The resource config must be set before the require check.\"},\"l1CrossDomainMessenger()\":{\"notice\":\"Getter for the L1CrossDomainMessenger address.\"},\"l1ERC721Bridge()\":{\"notice\":\"Getter for the L1ERC721Bridge address.\"},\"l1StandardBridge()\":{\"notice\":\"Getter for the L1StandardBridge address.\"},\"l2OutputOracle()\":{\"notice\":\"Getter for the L2OutputOracle address.\"},\"minimumGasLimit()\":{\"notice\":\"Returns the minimum L2 gas limit that can be safely set for the system to operate. The L2 gas limit must be larger than or equal to the amount of gas that is allocated for deposits per block plus the amount of gas that is allocated for the system transaction. This function is used to determine if changes to parameters are safe.\"},\"optimismMintableERC20Factory()\":{\"notice\":\"Getter for the OptimismMintableERC20Factory address.\"},\"optimismPortal()\":{\"notice\":\"Getter for the OptimismPortal address.\"},\"overhead()\":{\"notice\":\"Fixed L2 gas overhead. Used as part of the L2 fee calculation.\"},\"resourceConfig()\":{\"notice\":\"A getter for the resource config. Ensures that the struct is returned instead of a tuple.\"},\"scalar()\":{\"notice\":\"Dynamic L2 gas overhead. Used as part of the L2 fee calculation.\"},\"setBatcherHash(bytes32)\":{\"notice\":\"Updates the batcher hash. Can only be called by the owner.\"},\"setGasConfig(uint256,uint256)\":{\"notice\":\"Updates gas config. Can only be called by the owner.\"},\"setGasLimit(uint64)\":{\"notice\":\"Updates the L2 gas limit. Can only be called by the owner.\"},\"setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))\":{\"notice\":\"An external setter for the resource config. In the future, this method may emit an event that the `op-node` picks up for when the resource config is changed.\"},\"setUnsafeBlockSigner(address)\":{\"notice\":\"Updates the unsafe block signer address. Can only be called by the owner.\"},\"startBlock()\":{\"notice\":\"The block at which the op-node can start searching for logs from.\"},\"unsafeBlockSigner()\":{\"notice\":\"High level getter for the unsafe block signer address. Unsafe blocks can be propagated across the p2p network if they are signed by the key corresponding to this address.\"},\"version()\":{\"notice\":\"Semantic version.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":safe-contracts/=lib/safe-contracts/contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/L1/SystemConfig.sol\":\"SystemConfig\"},\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"urls\":[\"bzz-raw://d7fc8396619de513c96b6e00301b88dd790e83542aab918425633a5f7297a15a\",\"dweb:/ipfs/QmXbP4kiZyp7guuS7xe8KaybnwkRPGrBc2Kbi3vhcTfpxb\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x2a21b14ff90012878752f230d3ffd5c3405e5938d06c97a7d89c0a64561d0d66\",\"urls\":[\"bzz-raw://3313a8f9bb1f9476857c9050067b31982bf2140b83d84f3bc0cec1f62bbe947f\",\"dweb:/ipfs/Qma17Pk8NRe7aB4UD3jjVxk7nSFaov3eQyv86hcyqkwJRV\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"urls\":[\"bzz-raw://b600b852e0597aa69989cc263111f02097e2827edc1bdc70306303e3af5e9929\",\"dweb:/ipfs/QmU4WfM28A1nDqghuuGeFmN3CnVrk6opWtiF65K4vhFPeC\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"urls\":[\"bzz-raw://a709421c4f5d4677db8216055d2d4dac96a613efdb08178a9f7041f0c5cef689\",\"dweb:/ipfs/QmYs2rStvVLDnSJs8HgaMD1ABwoKKWdiVbQyNfLfFWTjTy\"],\"license\":\"MIT\"},\"lib/solmate/src/utils/FixedPointMathLib.sol\":{\"keccak256\":\"0x622fcd8a49e132df5ec7651cc6ae3aaf0cf59bdcd67a9a804a1b9e2485113b7d\",\"urls\":[\"bzz-raw://af77088eb606427d4c55e578984a615779c86bc30646a20f7bb27299ba390f7c\",\"dweb:/ipfs/QmZGQdhdQDtHc7gZXWrKXgA3govc74X8U63BiWhPQK3mK8\"],\"license\":\"MIT\"},\"src/L1/ResourceMetering.sol\":{\"keccak256\":\"0xa4d524f2a5e91a0b63a62603e712001c51c77e8371b93cbb576bcb7d074b7588\",\"urls\":[\"bzz-raw://d6d8141b6c6dc72d2e684c1ae388c005fd78c9ca7fc9c15dddebd227ca4fd730\",\"dweb:/ipfs/QmPfJrR4qssu769TDWJnxdTozqKtZUxiY8fs95bhfECTvG\"],\"license\":\"MIT\"},\"src/L1/SystemConfig.sol\":{\"keccak256\":\"0x4bbbc7868e948c44f29285a69383e93251a0c330a67929fb72def01cec060d4e\",\"urls\":[\"bzz-raw://1e7ea2f8b3d49bee9c753f107ede6eda93b2cc0e34d0643fa14ebbb26c19e71b\",\"dweb:/ipfs/QmRP81F8FRVXVZs6u2f2poEPDnbFZhNwNYxHgCVEhGpEmB\"],\"license\":\"MIT\"},\"src/libraries/Arithmetic.sol\":{\"keccak256\":\"0x06a5a8b00527843f0cfc1bb3c0661316966a6cc432f88be31f23cde78cd07560\",\"urls\":[\"bzz-raw://d5209e78e5415c0bf8b350362a825cc56152811abd6fcf2df3d4fa47766d3dee\",\"dweb:/ipfs/Qmf43xyc4Um32NmccayDfhm8kSnS2mhHXpPZnwABJS7cWm\"],\"license\":\"MIT\"},\"src/libraries/Burn.sol\":{\"keccak256\":\"0x90a795bcea3ef06d6d5011256c4bd63d1a4271f519246dbf1ee3e8f1c0e21010\",\"urls\":[\"bzz-raw://9f60c3aa77cf0c484ddda4754157cff4dc0e2eace4bea67990daff4c0612ab5f\",\"dweb:/ipfs/QmSYGanMFve9uBC17X7hFneSFnwnJxz86Jgh6MX9BRMweb\"],\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"keccak256\":\"0xe12e392f05f80d3837c9392d016471181ae1ee6b84ea91b4e125e6523e5f18a2\",\"urls\":[\"bzz-raw://a3509231c228b7a4352573cd422cf0260dcbb94cfd915e5b664643db5475a5b7\",\"dweb:/ipfs/QmU2QERY4mHxqWFqSE5Exsy6Ftc5MTjTtYHC11fahLJWDC\"],\"license\":\"MIT\"},\"src/libraries/Storage.sol\":{\"keccak256\":\"0x902a0a815272a5b76c647d9e82101aca765e9835a6624d0857088b9da0f58afd\",\"urls\":[\"bzz-raw://9c39a697aacb0a2eac0bf1fbd7790d835a685c61006f6d3464e19cbc96a24480\",\"dweb:/ipfs/QmV3T8ZTRWPB5CNuZjxwWQNoENd7W4SoBMnFG6Y6g6xYV4\"],\"license\":\"MIT\"},\"src/universal/ISemver.sol\":{\"keccak256\":\"0xba34562a8026f59886d2e07d1d58d90b9691d00e0788c6263cef6c22740cab44\",\"urls\":[\"bzz-raw://0826f998632f83c103c3085bf2e872db79a69022b6d2e0444c83a64ca5283c2a\",\"dweb:/ipfs/QmcJ7PNqkAfKqbjFGRordtAg1v9DvcBSKvdTkVvciLyvQR\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 7, - "receipt": { - "transactionHash": "0x902cc51315451ee5623755d0e77385538b42f94c3e9c2095ced649026f91808d", - "transactionIndex": "0xb", - "blockHash": "0xcaca71b1f3b45150e6a90f2bb3053eeb04011c6873c74e53ab796ad7cbb74f0d", - "blockNumber": "0x438ae0", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", - "cumulativeGasUsed": "0x4ad0bc", - "gasUsed": "0x1ae55a", - "contractAddress": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "logs": [ - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c" - ], - "data": "0x", - "blockHash": "0xcaca71b1f3b45150e6a90f2bb3053eeb04011c6873c74e53ab796ad7cbb74f0d", - "blockNumber": "0x438ae0", - "transactionHash": "0x902cc51315451ee5623755d0e77385538b42f94c3e9c2095ced649026f91808d", - "transactionIndex": "0xb", - "logIndex": "0x26", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", - "0x000000000000000000000000000000000000000000000000000000000000dead" - ], - "data": "0x", - "blockHash": "0xcaca71b1f3b45150e6a90f2bb3053eeb04011c6873c74e53ab796ad7cbb74f0d", - "blockNumber": "0x438ae0", - "transactionHash": "0x902cc51315451ee5623755d0e77385538b42f94c3e9c2095ced649026f91808d", - "transactionIndex": "0xb", - "logIndex": "0x27", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcaca71b1f3b45150e6a90f2bb3053eeb04011c6873c74e53ab796ad7cbb74f0d", - "blockNumber": "0x438ae0", - "transactionHash": "0x902cc51315451ee5623755d0e77385538b42f94c3e9c2095ced649026f91808d", - "transactionIndex": "0xb", - "logIndex": "0x28", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000001" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcaca71b1f3b45150e6a90f2bb3053eeb04011c6873c74e53ab796ad7cbb74f0d", - "blockNumber": "0x438ae0", - "transactionHash": "0x902cc51315451ee5623755d0e77385538b42f94c3e9c2095ced649026f91808d", - "transactionIndex": "0xb", - "logIndex": "0x29", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001", - "blockHash": "0xcaca71b1f3b45150e6a90f2bb3053eeb04011c6873c74e53ab796ad7cbb74f0d", - "blockNumber": "0x438ae0", - "transactionHash": "0x902cc51315451ee5623755d0e77385538b42f94c3e9c2095ced649026f91808d", - "transactionIndex": "0xb", - "logIndex": "0x2a", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000003" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcaca71b1f3b45150e6a90f2bb3053eeb04011c6873c74e53ab796ad7cbb74f0d", - "blockNumber": "0x438ae0", - "transactionHash": "0x902cc51315451ee5623755d0e77385538b42f94c3e9c2095ced649026f91808d", - "transactionIndex": "0xb", - "logIndex": "0x2b", - "removed": false - }, - { - "address": "0x3b6090d4ba84B94C20a789436B9010F340AaaC70", - "topics": [ - "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000003", - "blockHash": "0xcaca71b1f3b45150e6a90f2bb3053eeb04011c6873c74e53ab796ad7cbb74f0d", - "blockNumber": "0x438ae0", - "transactionHash": "0x902cc51315451ee5623755d0e77385538b42f94c3e9c2095ced649026f91808d", - "transactionIndex": "0xb", - "logIndex": "0x2c", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x04000000000010000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000020008000000000000040000000000000000000000100000000000000001000000040000000000000000000000000000020000000000000000000800000000000000002000000000000000400000000000000000000004040000000000000000001080000000000000000000000000000001000000000100000400000000000000800000000000000000400000000400000000000000000000040000000000000000000000000000000060000000000000000008000000000000000080000000008000000000008000000000", - "type": "0x2", - "effectiveGasPrice": "0x11242e21a" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [ - { - "astId": 29536, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 29539, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 31067, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 29408, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 29528, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 61640, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "overhead", - "offset": 0, - "slot": "101", - "type": "t_uint256" - }, - { - "astId": 61643, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "scalar", - "offset": 0, - "slot": "102", - "type": "t_uint256" - }, - { - "astId": 61646, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "batcherHash", - "offset": 0, - "slot": "103", - "type": "t_bytes32" - }, - { - "astId": 61649, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "gasLimit", - "offset": 0, - "slot": "104", - "type": "t_uint64" - }, - { - "astId": 61653, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "_resourceConfig", - "offset": 0, - "slot": "105", - "type": "t_struct(ResourceConfig)61178_storage" - }, - { - "astId": 61666, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "startBlock", - "offset": 0, - "slot": "106", - "type": "t_uint256" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_uint256)49_storage": { - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568", - "base": "t_uint256" - }, - "t_array(t_uint256)50_storage": { - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600", - "base": "t_uint256" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes32": { - "encoding": "inplace", - "label": "bytes32", - "numberOfBytes": "32" - }, - "t_struct(ResourceConfig)61178_storage": { - "encoding": "inplace", - "label": "struct ResourceMetering.ResourceConfig", - "numberOfBytes": "32", - "members": [ - { - "astId": 61167, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "maxResourceLimit", - "offset": 0, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 61169, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "elasticityMultiplier", - "offset": 4, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 61171, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "baseFeeMaxChangeDenominator", - "offset": 5, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 61173, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "minimumBaseFee", - "offset": 6, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 61175, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "systemTxMaxGas", - "offset": 10, - "slot": "0", - "type": "t_uint32" - }, - { - "astId": 61177, - "contract": "src/L1/SystemConfig.sol:SystemConfig", - "label": "maximumBaseFee", - "offset": 14, - "slot": "0", - "type": "t_uint128" - } - ] - }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "encoding": "inplace", - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint64": { - "encoding": "inplace", - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - }, - "transactionHash": "0x902cc51315451ee5623755d0e77385538b42f94c3e9c2095ced649026f91808d", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "BATCH_INBOX_SLOT()": { - "notice": "Storage slot that the batch inbox address is stored at." - }, - "L1_CROSS_DOMAIN_MESSENGER_SLOT()": { - "notice": "Storage slot that the L1CrossDomainMessenger address is stored at." - }, - "L1_ERC_721_BRIDGE_SLOT()": { - "notice": "Storage slot that the L1ERC721Bridge address is stored at." - }, - "L1_STANDARD_BRIDGE_SLOT()": { - "notice": "Storage slot that the L1StandardBridge address is stored at." - }, - "L2_OUTPUT_ORACLE_SLOT()": { - "notice": "Storage slot that the L2OutputOracle address is stored at." - }, - "OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT()": { - "notice": "Storage slot that the OptimismMintableERC20Factory address is stored at." - }, - "OPTIMISM_PORTAL_SLOT()": { - "notice": "Storage slot that the OptimismPortal address is stored at." - }, - "UNSAFE_BLOCK_SIGNER_SLOT()": { - "notice": "Storage slot that the unsafe block signer is stored at. Storing it at this deterministic storage slot allows for decoupling the storage layout from the way that `solc` lays out storage. The `op-node` uses a storage proof to fetch this value." - }, - "VERSION()": { - "notice": "Version identifier, used for upgrades." - }, - "batchInbox()": { - "notice": "Getter for the BatchInbox address." - }, - "batcherHash()": { - "notice": "Identifier for the batcher. For version 1 of this configuration, this is represented as an address left-padded with zeros to 32 bytes." - }, - "constructor": { - "notice": "Constructs the SystemConfig contract. Cannot set the owner to `address(0)` due to the Ownable contract's implementation, so set it to `address(0xdEaD)`" - }, - "gasLimit()": { - "notice": "L2 block gas limit." - }, - "initialize(address,uint256,uint256,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),uint256,address,(address,address,address,address,address,address))": { - "notice": "Initializer. The resource config must be set before the require check." - }, - "l1CrossDomainMessenger()": { - "notice": "Getter for the L1CrossDomainMessenger address." - }, - "l1ERC721Bridge()": { - "notice": "Getter for the L1ERC721Bridge address." - }, - "l1StandardBridge()": { - "notice": "Getter for the L1StandardBridge address." - }, - "l2OutputOracle()": { - "notice": "Getter for the L2OutputOracle address." - }, - "minimumGasLimit()": { - "notice": "Returns the minimum L2 gas limit that can be safely set for the system to operate. The L2 gas limit must be larger than or equal to the amount of gas that is allocated for deposits per block plus the amount of gas that is allocated for the system transaction. This function is used to determine if changes to parameters are safe." - }, - "optimismMintableERC20Factory()": { - "notice": "Getter for the OptimismMintableERC20Factory address." - }, - "optimismPortal()": { - "notice": "Getter for the OptimismPortal address." - }, - "overhead()": { - "notice": "Fixed L2 gas overhead. Used as part of the L2 fee calculation." - }, - "resourceConfig()": { - "notice": "A getter for the resource config. Ensures that the struct is returned instead of a tuple." - }, - "scalar()": { - "notice": "Dynamic L2 gas overhead. Used as part of the L2 fee calculation." - }, - "setBatcherHash(bytes32)": { - "notice": "Updates the batcher hash. Can only be called by the owner." - }, - "setGasConfig(uint256,uint256)": { - "notice": "Updates gas config. Can only be called by the owner." - }, - "setGasLimit(uint64)": { - "notice": "Updates the L2 gas limit. Can only be called by the owner." - }, - "setResourceConfig((uint32,uint8,uint8,uint32,uint32,uint128))": { - "notice": "An external setter for the resource config. In the future, this method may emit an event that the `op-node` picks up for when the resource config is changed." - }, - "setUnsafeBlockSigner(address)": { - "notice": "Updates the unsafe block signer address. Can only be called by the owner." - }, - "startBlock()": { - "notice": "The block at which the op-node can start searching for logs from." - }, - "unsafeBlockSigner()": { - "notice": "High level getter for the unsafe block signer address. Unsafe blocks can be propagated across the p2p network if they are signed by the key corresponding to this address." - }, - "version()": { - "notice": "Semantic version." - } - }, - "events": { - "ConfigUpdate(uint256,uint8,bytes)": { - "notice": "Emitted when configuration is updated." - } - }, - "notice": "The SystemConfig contract is used to manage configuration of an Optimism network. All configuration is stored on L1 and picked up by L2 as part of the derviation of the L2 chain." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/sepolia/SystemConfigProxy.json b/packages/contracts-bedrock/deployments/sepolia/SystemConfigProxy.json deleted file mode 100644 index 8016b8fe9dda..000000000000 --- a/packages/contracts-bedrock/deployments/sepolia/SystemConfigProxy.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - } - ], - "name": "changeAdmin", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "address": "0x034edD2A225f7f429A63E0f1D2084B9E0A93b538", - "args": [ - "0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc" - ], - "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", - "devdoc": { - "version": 1, - "kind": "dev", - "methods": { - "admin()": { - "returns": { - "_0": "Owner address." - } - }, - "changeAdmin(address)": { - "params": { - "_admin": "New owner of the proxy contract." - } - }, - "constructor": { - "params": { - "_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface." - } - }, - "implementation()": { - "returns": { - "_0": "Implementation address." - } - }, - "upgradeTo(address)": { - "params": { - "_implementation": "Address of the implementation contract." - } - }, - "upgradeToAndCall(address,bytes)": { - "params": { - "_data": "Calldata to delegatecall the new implementation with.", - "_implementation": "Address of the implementation contract." - } - } - }, - "events": { - "AdminChanged(address,address)": { - "params": { - "newAdmin": "The new owner of the contract", - "previousAdmin": "The previous owner of the contract" - } - }, - "Upgraded(address)": { - "params": { - "implementation": "The address of the implementation contract" - } - } - }, - "title": "Proxy" - }, - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false}],\"type\":\"event\",\"name\":\"AdminChanged\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Upgraded\",\"anonymous\":false},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"changeAdmin\"},{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"upgradeTo\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}]},{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"version\":1}},\"settings\":{\"remappings\":[\":.ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/\",\":.ignored_forge-std/=node_modules/.ignored_forge-std/src/\",\":@cwia/=lib/clones-with-immutable-args/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":@rari-capital/solmate/=lib/solmate/\",\":clones-with-immutable-args/=lib/clones-with-immutable-args/src/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\",\":solmate/=lib/solmate/src/\"],\"optimizer\":{\"enabled\":true,\"runs\":999999},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/universal/Proxy.sol\":\"Proxy\"},\"libraries\":{}},\"sources\":{\"src/universal/Proxy.sol\":{\"keccak256\":\"0x783aed9ff90b38a9898be5fb18699b3b249f012bc2c33f6537e1ab9f6444478f\",\"urls\":[\"bzz-raw://b119b1b68874f4d92a89cc05a4f0d25da73a959747a81e26739739a52895b844\",\"dweb:/ipfs/QmbKZqMd6CsM7annE7bCXcCi72syJAX3qtuFNPEGMCp13W\"],\"license\":\"MIT\"}},\"version\":1}", - "numDeployments": 4, - "receipt": { - "transactionHash": "0x951deaff679124ded80e96135b9b44c726e2d831eb1ab792e5673225aa778c9a", - "transactionIndex": "0x7", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "from": "0x18394B52d3Cb931dfA76F63251919D051953413d", - "to": null, - "cumulativeGasUsed": "0x5191a8", - "gasUsed": "0x7feb8", - "contractAddress": "0x034edD2A225f7f429A63E0f1D2084B9E0A93b538", - "logs": [ - { - "address": "0x034edD2A225f7f429A63E0f1D2084B9E0A93b538", - "topics": [ - "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000189abaaaa82dfc015a588a7dbad6f13b1d3485bc", - "blockHash": "0xa6d331f0f1bd46d1aa2c3575c353e2b981d69bb858e6c58c4d24d75115986a68", - "blockNumber": "0x3e1f50", - "transactionHash": "0x951deaff679124ded80e96135b9b44c726e2d831eb1ab792e5673225aa778c9a", - "transactionIndex": "0x7", - "logIndex": "0x7", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000004000000000000000000000000000000000000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xbec78df7" - }, - "solcInputHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "storageLayout": { - "storage": [], - "types": {} - }, - "transactionHash": "0x951deaff679124ded80e96135b9b44c726e2d831eb1ab792e5673225aa778c9a", - "userdoc": { - "version": 1, - "kind": "user", - "methods": { - "admin()": { - "notice": "Gets the owner of the proxy contract." - }, - "changeAdmin(address)": { - "notice": "Changes the owner of the proxy contract. Only callable by the owner." - }, - "constructor": { - "notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible." - }, - "upgradeTo(address)": { - "notice": "Set the implementation contract address. The code at the given address will execute when this contract is called." - }, - "upgradeToAndCall(address,bytes)": { - "notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades." - } - }, - "events": { - "AdminChanged(address,address)": { - "notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification." - }, - "Upgraded(address)": { - "notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification." - } - }, - "notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation." - } -} \ No newline at end of file diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml index 8c1cc245b681..51f9db270ffe 100644 --- a/packages/contracts-bedrock/foundry.toml +++ b/packages/contracts-bedrock/foundry.toml @@ -15,26 +15,32 @@ remappings = [ '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts', '@rari-capital/solmate/=lib/solmate', '@cwia/=lib/clones-with-immutable-args/src', + '@lib-keccak/=lib/lib-keccak/contracts/lib', 'forge-std/=lib/forge-std/src', 'ds-test/=lib/forge-std/lib/ds-test/src', - 'safe-contracts/=lib/safe-contracts/contracts' + 'safe-contracts/=lib/safe-contracts/contracts', + 'kontrol-cheatcodes/=lib/kontrol-cheatcodes/src', + 'solady/=lib/solady/src', ] extra_output = ['devdoc', 'userdoc', 'metadata', 'storageLayout'] bytecode_hash = 'none' -build_info = true build_info_path = 'artifacts/build-info' # Test / Script Runner Settings ffi = true fs_permissions = [ { access='read-write', path='./.resource-metering.csv' }, + { access='read-write', path='./snapshots/' }, { access='read-write', path='./deployments/' }, { access='read', path='./deploy-config/' }, { access='read', path='./periphery-deploy-config/' }, { access='read', path='./broadcast/' }, { access='read', path = './forge-artifacts/' }, { access='write', path='./semver-lock.json' }, + { access='read-write', path='./.testdata/' }, + { access='read', path='./kout-deployment' } ] +libs = ["node_modules", "lib"] [fuzz] runs = 64 @@ -50,5 +56,35 @@ ignore = ['src/vendor/WETH9.sol'] # PROFILE: CI # ################################################################ -[profile.ci.fuzz] -runs = 512 +[profile.ci] +deny_warnings = true +fuzz = { runs = 512 } + +[profile.ci.invariant] +runs = 256 +depth = 32 + +################################################################ +# PROFILE: LITE # +################################################################ + +[profile.lite] +optimizer = false + +################################################################ +# PROFILE: KONTROL # +################################################################ +# See test/kontrol/README.md for an explanation of how the profiles are configured + +[profile.kdeploy] +src = 'src/L1' +out = 'kout-deployment' +test = 'test/kontrol' +script = 'scripts-kontrol' + +[profile.kprove] +src = 'test/kontrol/proofs' +out = 'kout-proofs' +test = 'test/kontrol/proofs' +script = 'test/kontrol/proofs' +ast = true diff --git a/packages/contracts-bedrock/invariant-docs/AddressAliasHelper.md b/packages/contracts-bedrock/invariant-docs/AddressAliasHelper.md index 36251fcfad0c..f7787a436122 100644 --- a/packages/contracts-bedrock/invariant-docs/AddressAliasHelper.md +++ b/packages/contracts-bedrock/invariant-docs/AddressAliasHelper.md @@ -1,6 +1,6 @@ # `AddressAliasHelper` Invariants ## Address aliases are always able to be undone. -**Test:** [`AddressAliasHelper.t.sol#L46`](../test/invariants/AddressAliasHelper.t.sol#L46) +**Test:** [`AddressAliasHelper.t.sol#L48`](../test/invariants/AddressAliasHelper.t.sol#L48) Asserts that an address that has been aliased with `applyL1ToL2Alias` can always be unaliased with `undoL1ToL2Alias`. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/Burn.Eth.md b/packages/contracts-bedrock/invariant-docs/Burn.Eth.md index b19d3de5475a..eb11cba92315 100644 --- a/packages/contracts-bedrock/invariant-docs/Burn.Eth.md +++ b/packages/contracts-bedrock/invariant-docs/Burn.Eth.md @@ -1,6 +1,6 @@ # `Burn.Eth` Invariants ## `eth(uint256)` always burns the exact amount of eth passed. -**Test:** [`Burn.Eth.t.sol#L64`](../test/invariants/Burn.Eth.t.sol#L64) +**Test:** [`Burn.Eth.t.sol#L66`](../test/invariants/Burn.Eth.t.sol#L66) Asserts that when `Burn.eth(uint256)` is called, it always burns the exact amount of ETH passed to the function. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/Burn.Gas.md b/packages/contracts-bedrock/invariant-docs/Burn.Gas.md index 24f6a0f2df5e..5c343bca23fd 100644 --- a/packages/contracts-bedrock/invariant-docs/Burn.Gas.md +++ b/packages/contracts-bedrock/invariant-docs/Burn.Gas.md @@ -1,6 +1,6 @@ # `Burn.Gas` Invariants ## `gas(uint256)` always burns at least the amount of gas passed. -**Test:** [`Burn.Gas.t.sol#L64`](../test/invariants/Burn.Gas.t.sol#L64) +**Test:** [`Burn.Gas.t.sol#L66`](../test/invariants/Burn.Gas.t.sol#L66) Asserts that when `Burn.gas(uint256)` is called, it always burns at least the amount of gas passed to the function. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md b/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md index 3fae2cddfa87..4329859f24a3 100644 --- a/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md +++ b/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md @@ -1,14 +1,14 @@ # `CrossDomainMessenger` Invariants ## A call to `relayMessage` should succeed if at least the minimum gas limit can be supplied to the target context, there is enough gas to complete execution of `relayMessage` after the target context's execution is finished, and the target context did not revert. -**Test:** [`CrossDomainMessenger.t.sol#L136`](../test/invariants/CrossDomainMessenger.t.sol#L136) +**Test:** [`CrossDomainMessenger.t.sol#L143`](../test/invariants/CrossDomainMessenger.t.sol#L143) There are two minimum gas limits here: - The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit. - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target contract. ## A call to `relayMessage` should assign the message hash to the `failedMessages` mapping if not enough gas is supplied to forward `minGasLimit` to the target context or if there is not enough gas to complete execution of `relayMessage` after the target context's execution is finished. -**Test:** [`CrossDomainMessenger.t.sol#L169`](../test/invariants/CrossDomainMessenger.t.sol#L169) +**Test:** [`CrossDomainMessenger.t.sol#L176`](../test/invariants/CrossDomainMessenger.t.sol#L176) There are two minimum gas limits here: - The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit. diff --git a/packages/contracts-bedrock/invariant-docs/Encoding.md b/packages/contracts-bedrock/invariant-docs/Encoding.md index ab67a91160e1..460eff43df77 100644 --- a/packages/contracts-bedrock/invariant-docs/Encoding.md +++ b/packages/contracts-bedrock/invariant-docs/Encoding.md @@ -1,11 +1,11 @@ # `Encoding` Invariants ## `convertRoundTripAToB` never fails. -**Test:** [`Encoding.t.sol#L71`](../test/invariants/Encoding.t.sol#L71) +**Test:** [`Encoding.t.sol#L73`](../test/invariants/Encoding.t.sol#L73) Asserts that a raw versioned nonce can be encoded / decoded to reach the same raw value. ## `convertRoundTripBToA` never fails. -**Test:** [`Encoding.t.sol#L80`](../test/invariants/Encoding.t.sol#L80) +**Test:** [`Encoding.t.sol#L82`](../test/invariants/Encoding.t.sol#L82) Asserts that an encoded versioned nonce can always be decoded / re-encoded to reach the same encoded value. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/FaultDisputeGame.md b/packages/contracts-bedrock/invariant-docs/FaultDisputeGame.md new file mode 100644 index 000000000000..c54eb974cff7 --- /dev/null +++ b/packages/contracts-bedrock/invariant-docs/FaultDisputeGame.md @@ -0,0 +1,6 @@ +# `FaultDisputeGame` Invariants + +## FaultDisputeGame always returns all ETH on total resolution +**Test:** [`FaultDisputeGame.t.sol#L33`](../test/invariants/FaultDisputeGame.t.sol#L33) + +The FaultDisputeGame contract should always return all ETH in the contract to the correct recipients upon resolution of all outstanding claims. There may never be any ETH left in the contract after a full resolution. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/Hashing.md b/packages/contracts-bedrock/invariant-docs/Hashing.md index 0501ed342d25..acf407876d3c 100644 --- a/packages/contracts-bedrock/invariant-docs/Hashing.md +++ b/packages/contracts-bedrock/invariant-docs/Hashing.md @@ -1,16 +1,16 @@ # `Hashing` Invariants ## `hashCrossDomainMessage` reverts if `version` is > `1`. -**Test:** [`Hashing.t.sol#L117`](../test/invariants/Hashing.t.sol#L117) +**Test:** [`Hashing.t.sol#L119`](../test/invariants/Hashing.t.sol#L119) The `hashCrossDomainMessage` function should always revert if the `version` passed is > `1`. ## `version` = `0`: `hashCrossDomainMessage` and `hashCrossDomainMessageV0` are equivalent. -**Test:** [`Hashing.t.sol#L127`](../test/invariants/Hashing.t.sol#L127) +**Test:** [`Hashing.t.sol#L129`](../test/invariants/Hashing.t.sol#L129) If the version passed is 0, `hashCrossDomainMessage` and `hashCrossDomainMessageV0` should be equivalent. ## `version` = `1`: `hashCrossDomainMessage` and `hashCrossDomainMessageV1` are equivalent. -**Test:** [`Hashing.t.sol#L138`](../test/invariants/Hashing.t.sol#L138) +**Test:** [`Hashing.t.sol#L140`](../test/invariants/Hashing.t.sol#L140) If the version passed is 1, `hashCrossDomainMessage` and `hashCrossDomainMessageV1` should be equivalent. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/InvariantTest.sol.md b/packages/contracts-bedrock/invariant-docs/InvariantTest.sol.md new file mode 100644 index 000000000000..bd27f490f563 --- /dev/null +++ b/packages/contracts-bedrock/invariant-docs/InvariantTest.sol.md @@ -0,0 +1,2 @@ +# `InvariantTest.sol` Invariants + diff --git a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md index c13d0212128d..07347e58bd77 100644 --- a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md +++ b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md @@ -1,21 +1,21 @@ # `OptimismPortal` Invariants ## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. -**Test:** [`OptimismPortal.t.sol#L148`](../test/invariants/OptimismPortal.t.sol#L148) +**Test:** [`OptimismPortal.t.sol#L149`](../test/invariants/OptimismPortal.t.sol#L149) All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. ## `finalizeWithdrawalTransaction` should revert if the finalization period has not elapsed. -**Test:** [`OptimismPortal.t.sol#L171`](../test/invariants/OptimismPortal.t.sol#L171) +**Test:** [`OptimismPortal.t.sol#L172`](../test/invariants/OptimismPortal.t.sol#L172) A withdrawal that has been proven should not be able to be finalized until after the finalization period has elapsed. ## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. -**Test:** [`OptimismPortal.t.sol#L201`](../test/invariants/OptimismPortal.t.sol#L201) +**Test:** [`OptimismPortal.t.sol#L202`](../test/invariants/OptimismPortal.t.sol#L202) Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice. ## A withdrawal should **always** be able to be finalized `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. -**Test:** [`OptimismPortal.t.sol#L230`](../test/invariants/OptimismPortal.t.sol#L230) +**Test:** [`OptimismPortal.t.sol#L231`](../test/invariants/OptimismPortal.t.sol#L231) This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/OptimismPortal2.md b/packages/contracts-bedrock/invariant-docs/OptimismPortal2.md new file mode 100644 index 000000000000..03630c5cd9a0 --- /dev/null +++ b/packages/contracts-bedrock/invariant-docs/OptimismPortal2.md @@ -0,0 +1,21 @@ +# `OptimismPortal2` Invariants + +## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. +**Test:** [`OptimismPortal2.t.sol#L160`](../test/invariants/OptimismPortal2.t.sol#L160) + +All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. + +## `finalizeWithdrawalTransaction` should revert if the proof maturity period has not elapsed. +**Test:** [`OptimismPortal2.t.sol#L182`](../test/invariants/OptimismPortal2.t.sol#L182) + +A withdrawal that has been proven should not be able to be finalized until after the proof maturity period has elapsed. + +## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. +**Test:** [`OptimismPortal2.t.sol#L211`](../test/invariants/OptimismPortal2.t.sol#L211) + +Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice. + +## A withdrawal should **always** be able to be finalized `PROOF_MATURITY_DELAY_SECONDS` after it was successfully proven, if the game has resolved and passed the air-gap. +**Test:** [`OptimismPortal2.t.sol#L239`](../test/invariants/OptimismPortal2.t.sol#L239) + +This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `PROOF_MATURITY_DELAY_SECONDS` after it was successfully proven and the game has resolved and passed the air-gap. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/README.md b/packages/contracts-bedrock/invariant-docs/README.md index ec4fce3c0497..eae292a89cc2 100644 --- a/packages/contracts-bedrock/invariant-docs/README.md +++ b/packages/contracts-bedrock/invariant-docs/README.md @@ -11,9 +11,12 @@ This directory contains documentation for all defined invariant tests within `co - [Burn.Gas](./Burn.Gas.md) - [CrossDomainMessenger](./CrossDomainMessenger.md) - [Encoding](./Encoding.md) +- [FaultDisputeGame](./FaultDisputeGame.md) - [Hashing](./Hashing.md) +- [InvariantTest.sol](./InvariantTest.sol.md) - [L2OutputOracle](./L2OutputOracle.md) - [OptimismPortal](./OptimismPortal.md) +- [OptimismPortal2](./OptimismPortal2.md) - [ResourceMetering](./ResourceMetering.md) - [SafeCall](./SafeCall.md) - [SystemConfig](./SystemConfig.md) @@ -25,7 +28,7 @@ To auto-generate documentation for invariant tests, run `pnpm autogen:invariant- ## Documentation Standard -In order for an invariant test file to be picked up by the [docgen script](../scripts/invariant-doc-gen.ts), it must +In order for an invariant test file to be picked up by the [docgen script](../scripts/autogen/generate-invariant-docs.ts), it must adhere to the following conventions: ### Forge Invariants diff --git a/packages/contracts-bedrock/invariant-docs/ResourceMetering.md b/packages/contracts-bedrock/invariant-docs/ResourceMetering.md index 5330108400b8..967c24bf886f 100644 --- a/packages/contracts-bedrock/invariant-docs/ResourceMetering.md +++ b/packages/contracts-bedrock/invariant-docs/ResourceMetering.md @@ -1,36 +1,36 @@ # `ResourceMetering` Invariants ## The base fee should increase if the last block used more than the target amount of gas. -**Test:** [`ResourceMetering.t.sol#L162`](../test/invariants/ResourceMetering.t.sol#L162) +**Test:** [`ResourceMetering.t.sol#L163`](../test/invariants/ResourceMetering.t.sol#L163) If the last block used more than the target amount of gas (and there were no empty blocks in between), ensure this block's baseFee increased, but not by more than the max amount per block. ## The base fee should decrease if the last block used less than the target amount of gas. -**Test:** [`ResourceMetering.t.sol#L171`](../test/invariants/ResourceMetering.t.sol#L171) +**Test:** [`ResourceMetering.t.sol#L172`](../test/invariants/ResourceMetering.t.sol#L172) If the previous block used less than the target amount of gas, the base fee should decrease, but not more than the max amount. ## A block's base fee should never be below `MINIMUM_BASE_FEE`. -**Test:** [`ResourceMetering.t.sol#L179`](../test/invariants/ResourceMetering.t.sol#L179) +**Test:** [`ResourceMetering.t.sol#L180`](../test/invariants/ResourceMetering.t.sol#L180) This test asserts that a block's base fee can never drop below the `MINIMUM_BASE_FEE` threshold. ## A block can never consume more than `MAX_RESOURCE_LIMIT` gas. -**Test:** [`ResourceMetering.t.sol#L187`](../test/invariants/ResourceMetering.t.sol#L187) +**Test:** [`ResourceMetering.t.sol#L188`](../test/invariants/ResourceMetering.t.sol#L188) This test asserts that a block can never consume more than the `MAX_RESOURCE_LIMIT` gas threshold. ## The base fee can never be raised more than the max base fee change. -**Test:** [`ResourceMetering.t.sol#L197`](../test/invariants/ResourceMetering.t.sol#L197) +**Test:** [`ResourceMetering.t.sol#L198`](../test/invariants/ResourceMetering.t.sol#L198) After a block consumes more gas than the target gas, the base fee cannot be raised more than the maximum amount allowed. The max base fee change (per-block) is derived as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR` ## The base fee can never be lowered more than the max base fee change. -**Test:** [`ResourceMetering.t.sol#L207`](../test/invariants/ResourceMetering.t.sol#L207) +**Test:** [`ResourceMetering.t.sol#L208`](../test/invariants/ResourceMetering.t.sol#L208) After a block consumes less than the target gas, the base fee cannot be lowered more than the maximum amount allowed. The max base fee change (per-block) is derived as follows: `prevBaseFee / BASE_FEE_MAX_CHANGE_DENOMINATOR` ## The `maxBaseFeeChange` calculation over multiple blocks can never underflow. -**Test:** [`ResourceMetering.t.sol#L216`](../test/invariants/ResourceMetering.t.sol#L216) +**Test:** [`ResourceMetering.t.sol#L217`](../test/invariants/ResourceMetering.t.sol#L217) When calculating the `maxBaseFeeChange` after multiple empty blocks, the calculation should never be allowed to underflow. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/SafeCall.md b/packages/contracts-bedrock/invariant-docs/SafeCall.md index 5f0563810a22..19ac6d851030 100644 --- a/packages/contracts-bedrock/invariant-docs/SafeCall.md +++ b/packages/contracts-bedrock/invariant-docs/SafeCall.md @@ -1,11 +1,11 @@ # `SafeCall` Invariants ## If `callWithMinGas` performs a call, then it must always provide at least the specified minimum gas limit to the subcontext. -**Test:** [`SafeCall.t.sol#L31`](../test/invariants/SafeCall.t.sol#L31) +**Test:** [`SafeCall.t.sol#L33`](../test/invariants/SafeCall.t.sol#L33) If the check for remaining gas in `SafeCall.callWithMinGas` passes, the subcontext of the call below it must be provided at least `minGas` gas. ## `callWithMinGas` reverts if there is not enough gas to pass to the subcontext. -**Test:** [`SafeCall.t.sol#L63`](../test/invariants/SafeCall.t.sol#L63) +**Test:** [`SafeCall.t.sol#L66`](../test/invariants/SafeCall.t.sol#L66) If there is not enough gas in the callframe to ensure that `callWithMinGas` can provide the specified minimum gas limit to the subcontext of the call, then `callWithMinGas` must revert. \ No newline at end of file diff --git a/packages/contracts-bedrock/invariant-docs/SystemConfig.md b/packages/contracts-bedrock/invariant-docs/SystemConfig.md index ed225cd63529..382bb3d539df 100644 --- a/packages/contracts-bedrock/invariant-docs/SystemConfig.md +++ b/packages/contracts-bedrock/invariant-docs/SystemConfig.md @@ -1,5 +1,5 @@ # `SystemConfig` Invariants ## The gas limit of the `SystemConfig` contract can never be lower than the hard-coded lower bound. -**Test:** [`SystemConfig.t.sol#L80`](../test/invariants/SystemConfig.t.sol#L80) +**Test:** [`SystemConfig.t.sol#L68`](../test/invariants/SystemConfig.t.sol#L68) diff --git a/packages/contracts-bedrock/layout-lock.json b/packages/contracts-bedrock/layout-lock.json deleted file mode 100644 index d181e170a241..000000000000 --- a/packages/contracts-bedrock/layout-lock.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "L1CrossDomainMessenger": { - "spacer_0_0_20": { - "slot": 0, - "offset": 0, - "length": 20 - }, - "spacer_1_0_1600": { - "slot": 1, - "offset": 0, - "length": 1600 - }, - "spacer_51_0_20": { - "slot": 51, - "offset": 0, - "length": 20 - }, - "spacer_52_0_1568": { - "slot": 52, - "offset": 0, - "length": 1568 - }, - "spacer_101_0_1": { - "slot": 101, - "offset": 0, - "length": 1 - }, - "spacer_102_0_1568": { - "slot": 102, - "offset": 0, - "length": 1568 - }, - "spacer_151_0_32": { - "slot": 151, - "offset": 0, - "length": 32 - }, - "spacer_201_0_32": { - "slot": 201, - "offset": 0, - "length": 32 - }, - "spacer_202_0_32": { - "slot": 202, - "offset": 0, - "length": 32 - } - }, - "L2CrossDomainMessenger": { - "spacer_0_0_20": { - "slot": 0, - "offset": 0, - "length": 20 - }, - "spacer_1_0_1600": { - "slot": 1, - "offset": 0, - "length": 1600 - }, - "spacer_51_0_20": { - "slot": 51, - "offset": 0, - "length": 20 - }, - "spacer_52_0_1568": { - "slot": 52, - "offset": 0, - "length": 1568 - }, - "spacer_101_0_1": { - "slot": 101, - "offset": 0, - "length": 1 - }, - "spacer_102_0_1568": { - "slot": 102, - "offset": 0, - "length": 1568 - }, - "spacer_151_0_32": { - "slot": 151, - "offset": 0, - "length": 32 - }, - "spacer_201_0_32": { - "slot": 201, - "offset": 0, - "length": 32 - }, - "spacer_202_0_32": { - "slot": 202, - "offset": 0, - "length": 32 - } - }, - "L1StandardBridge": { - "spacer_0_2_20": { - "slot": 0, - "offset": 2, - "length": 20 - }, - "spacer_1_0_20": { - "slot": 1, - "offset": 0, - "length": 20 - } - } -} diff --git a/packages/contracts-bedrock/lib/forge-std b/packages/contracts-bedrock/lib/forge-std index e8a047e3f40f..1fd874f0efdb 160000 --- a/packages/contracts-bedrock/lib/forge-std +++ b/packages/contracts-bedrock/lib/forge-std @@ -1 +1 @@ -Subproject commit e8a047e3f40f13fa37af6fe14e6e06283d9a060e +Subproject commit 1fd874f0efdb711cb6807c4f4a000ed2805dc809 diff --git a/packages/contracts-bedrock/lib/kontrol-cheatcodes b/packages/contracts-bedrock/lib/kontrol-cheatcodes new file mode 160000 index 000000000000..2c48ae1ab442 --- /dev/null +++ b/packages/contracts-bedrock/lib/kontrol-cheatcodes @@ -0,0 +1 @@ +Subproject commit 2c48ae1ab44228c199dca29414c0b4b18a3434e6 diff --git a/packages/contracts-bedrock/lib/lib-keccak b/packages/contracts-bedrock/lib/lib-keccak new file mode 160000 index 000000000000..0115edbbc60b --- /dev/null +++ b/packages/contracts-bedrock/lib/lib-keccak @@ -0,0 +1 @@ +Subproject commit 0115edbbc60b5f702392caafc3a142061e6142fa diff --git a/packages/contracts-bedrock/lib/solady b/packages/contracts-bedrock/lib/solady new file mode 160000 index 000000000000..502cc1ea718e --- /dev/null +++ b/packages/contracts-bedrock/lib/solady @@ -0,0 +1 @@ +Subproject commit 502cc1ea718e6fa73b380635ee0868b0740595f0 diff --git a/packages/contracts-bedrock/package.json b/packages/contracts-bedrock/package.json index 88f7e05e4700..9004a872e7cd 100644 --- a/packages/contracts-bedrock/package.json +++ b/packages/contracts-bedrock/package.json @@ -1,10 +1,11 @@ { "name": "@eth-optimism/contracts-bedrock", - "version": "0.16.2", + "version": "0.17.1", "description": "Contracts for Optimism Specs", "license": "MIT", "files": [ "forge-artifacts/**/*.json", + "!forge-artifacts/**/*.t.sol/*.json", "deployments/**/*.json", "src/**/*.sol" ], @@ -13,29 +14,31 @@ "bindings:ts": "nx generate @eth-optimism/contracts-ts", "bindings:go:no-build": "cd ../../op-bindings && make bindings-build", "bindings:go": "pnpm clean && pnpm build && pnpm bindings:go:no-build", - "prebuild": "./scripts/verify-foundry-install.sh", + "prebuild": "./scripts/checks/check-foundry-install.sh", "build": "forge build", "build:go-ffi": "(cd scripts/go-ffi && go build)", - "autogen:invariant-docs": "npx tsx scripts/invariant-doc-gen.ts", + "autogen:invariant-docs": "npx tsx scripts/autogen/generate-invariant-docs.ts", "test": "pnpm build:go-ffi && forge test", + "test:kontrol": "./test/kontrol/scripts/run-kontrol.sh script", + "genesis": "./scripts/generate-l2-genesis.sh", "coverage": "pnpm build:go-ffi && forge coverage", "coverage:lcov": "pnpm build:go-ffi && forge coverage --report lcov", - "gas-snapshot:no-build": "forge snapshot --no-match-test 'testDiff|testFuzz|invariant|generateArtifact'", + "deploy": "./scripts/deploy.sh", + "gas-snapshot:no-build": "forge snapshot --match-contract GasBenchMark", + "statediff": "./scripts/statediff.sh && git diff --exit-code", "gas-snapshot": "pnpm build:go-ffi && pnpm gas-snapshot:no-build", - "storage-snapshot": "./scripts/storage-snapshot.sh", + "snapshots": "npx tsx scripts/autogen/generate-snapshots.ts && ./test/kontrol/scripts/make-summary-deployment.sh", + "snapshots:check": "./scripts/checks/check-snapshots.sh", "semver-lock": "forge script scripts/SemverLock.s.sol", - "validate-deploy-configs": "./scripts/check-deploy-configs.sh", - "validate-spacers:no-build": "npx tsx scripts/validate-spacers.ts", + "validate-deploy-configs": "./scripts/checks/check-deploy-configs.sh", + "validate-spacers:no-build": "npx tsx scripts/checks/check-spacers.ts", "validate-spacers": "pnpm build && pnpm validate-spacers:no-build", - "slither": "./scripts/slither.sh", - "slither:triage": "TRIAGE_MODE=1 ./scripts/slither.sh", - "clean": "rm -rf ./artifacts ./forge-artifacts ./cache ./tsconfig.tsbuildinfo ./tsconfig.build.tsbuildinfo ./scripts/go-ffi/go-ffi", - "preinstall": "npx only-allow pnpm", - "pre-pr:no-build": "pnpm gas-snapshot:no-build && pnpm storage-snapshot && pnpm semver-lock && pnpm autogen:invariant-docs && pnpm lint && pnpm bindings:go", + "clean": "rm -rf ./artifacts ./forge-artifacts ./cache ./tsconfig.tsbuildinfo ./tsconfig.build.tsbuildinfo ./scripts/go-ffi/go-ffi ./.testdata ./deployments/hardhat/*", + "pre-pr:no-build": "pnpm gas-snapshot:no-build && pnpm snapshots && pnpm semver-lock && pnpm autogen:invariant-docs && pnpm lint && pnpm bindings:go:no-build", "pre-pr": "pnpm clean && pnpm build:go-ffi && pnpm build && pnpm pre-pr:no-build", - "pre-pr:full": "pnpm test && pnpm slither && pnpm validate-deploy-configs && pnpm validate-spacers && pnpm pre-pr", + "pre-pr:full": "pnpm test && pnpm validate-deploy-configs && pnpm validate-spacers && pnpm pre-pr", "lint:ts:check": "eslint . --max-warnings=0", - "lint:forge-tests:check": "npx tsx scripts/forge-test-names.ts", + "lint:forge-tests:check": "npx tsx scripts/checks/check-test-names.ts", "lint:contracts:check": "pnpm lint:fix && git diff --exit-code", "lint:check": "pnpm lint:contracts:check && pnpm lint:ts:check", "lint:ts:fix": "eslint --fix .", @@ -44,9 +47,9 @@ "lint": "pnpm lint:fix && pnpm lint:check" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^6.9.0", - "@typescript-eslint/parser": "^6.9.0", - "tsx": "^3.14.0", - "typescript": "^5.2.2" + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "tsx": "^4.7.0", + "typescript": "^5.3.3" } } diff --git a/packages/contracts-bedrock/periphery-deploy-config/4202.json b/packages/contracts-bedrock/periphery-deploy-config/4202.json new file mode 100644 index 000000000000..2e298c7f0585 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/4202.json @@ -0,0 +1,42 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", + "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 3, + "previousDripVersion": 2, + "smallOpChainFaucetDripValue": 34000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/4460.json b/packages/contracts-bedrock/periphery-deploy-config/4460.json new file mode 100644 index 000000000000..5e86522dbe56 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/4460.json @@ -0,0 +1,42 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", + "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 1, + "previousDripVersion": 0, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/58008.json b/packages/contracts-bedrock/periphery-deploy-config/58008.json new file mode 100644 index 000000000000..5e86522dbe56 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/58008.json @@ -0,0 +1,42 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", + "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 1, + "previousDripVersion": 0, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/84532.json b/packages/contracts-bedrock/periphery-deploy-config/84532.json new file mode 100644 index 000000000000..5e86522dbe56 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/84532.json @@ -0,0 +1,42 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", + "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 1, + "previousDripVersion": 0, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/901.json b/packages/contracts-bedrock/periphery-deploy-config/901.json new file mode 100644 index 000000000000..5e86522dbe56 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/901.json @@ -0,0 +1,42 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", + "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 1, + "previousDripVersion": 0, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/919.json b/packages/contracts-bedrock/periphery-deploy-config/919.json new file mode 100644 index 000000000000..5e86522dbe56 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/919.json @@ -0,0 +1,42 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", + "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 1, + "previousDripVersion": 0, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/999999999.json b/packages/contracts-bedrock/periphery-deploy-config/999999999.json new file mode 100644 index 000000000000..5e86522dbe56 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/999999999.json @@ -0,0 +1,42 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", + "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 1, + "previousDripVersion": 0, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json b/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json index ecc0e38255af..0a9e4f938c8f 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json +++ b/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json @@ -1,6 +1,6 @@ { - "faucetAdmin": "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819", - "faucetDrippieOwner": "0xEa193Fd9565284E7534dDDA15b07B119e7792644", + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", "faucetDripV1Value": 20000000000000000000, "faucetDripV1Interval": 3600, "faucetDripV1Threshold": 100000000000000000000, @@ -11,14 +11,32 @@ "faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Value": 1000000000000000000, "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", - "faucetGelatoRecipient": "0x789e58a4B08A23a7f60141959C6ABbdC0D0C4Aba", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", "faucetGelatoBalanceV1DripInterval": 86400, "faucetGelatoBalanceV1Value": 1000000000000000000, "faucetGelatoThreshold": 100000000000000000, - "faucetOnchainAuthModuleAdmin": "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819", + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleAmount": 1000000000000000000, - "faucetOffchainAuthModuleAdmin": "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819", + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleTtl": 86400, - "faucetOffchainAuthModuleAmount": 50000000000000000 + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", + "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 1, + "previousDripVersion": 0, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 } diff --git a/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json b/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json new file mode 100644 index 000000000000..5e86522dbe56 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json @@ -0,0 +1,42 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", + "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 1, + "previousDripVersion": 0, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/sepolia.json b/packages/contracts-bedrock/periphery-deploy-config/sepolia.json new file mode 100644 index 000000000000..c6f7945deeb0 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/sepolia.json @@ -0,0 +1,42 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", + "installOpChainFaucetsDrips": true, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 3, + "previousDripVersion": 2, + "smallOpChainFaucetDripValue": 34000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 +} diff --git a/packages/contracts-bedrock/scripts/Artifacts.s.sol b/packages/contracts-bedrock/scripts/Artifacts.s.sol new file mode 100644 index 000000000000..4042c72043eb --- /dev/null +++ b/packages/contracts-bedrock/scripts/Artifacts.s.sol @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { console2 as console } from "forge-std/console2.sol"; +import { stdJson } from "forge-std/StdJson.sol"; +import { Vm } from "forge-std/Vm.sol"; +import { Executables } from "scripts/Executables.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Config } from "scripts/Config.sol"; +import { StorageSlot } from "scripts/ForgeArtifacts.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +import { LibString } from "solady/utils/LibString.sol"; +import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol"; +import { IAddressManager } from "scripts/interfaces/IAddressManager.sol"; + +/// @notice Represents a deployment. Is serialized to JSON as a key/value +/// pair. Can be accessed from within scripts. +struct Deployment { + string name; + address payable addr; +} + +/// @title Artifacts +/// @notice Useful for accessing deployment artifacts from within scripts. +/// When a contract is deployed, call the `save` function to write its name and +/// contract address to disk. Inspired by `forge-deploy`. +abstract contract Artifacts { + /// @notice Foundry cheatcode VM. + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + /// @notice Error for when attempting to fetch a deployment and it does not exist + + error DeploymentDoesNotExist(string); + /// @notice Error for when trying to save an invalid deployment + error InvalidDeployment(string); + /// @notice The set of deployments that have been done during execution. + + mapping(string => Deployment) internal _namedDeployments; + /// @notice The same as `_namedDeployments` but as an array. + Deployment[] internal _newDeployments; + /// @notice Path to the directory containing the hh deploy style artifacts + string internal deploymentsDir; + /// @notice The path to the deployment artifact that is being written to. + string internal deploymentOutfile; + /// @notice The namespace for the deployment. Can be set with the env var DEPLOYMENT_CONTEXT. + string internal deploymentContext; + + /// @notice Setup function. The arguments here + function setUp() public virtual { + deploymentOutfile = Config.deploymentOutfile(); + console.log("Writing artifact to %s", deploymentOutfile); + ForgeArtifacts.ensurePath(deploymentOutfile); + + uint256 chainId = Config.chainID(); + console.log("Connected to network with chainid %s", chainId); + + // Load addresses from a JSON file if the CONTRACT_ADDRESSES_PATH environment variable + // is set. Great for loading addresses from `superchain-registry`. + string memory addresses = Config.contractAddressesPath(); + if (bytes(addresses).length > 0) { + console.log("Loading addresses from %s", addresses); + _loadAddresses(addresses); + } + } + + /// @notice Populates the addresses to be used in a script based on a JSON file. + /// The format of the JSON file is the same that it output by this script + /// as well as the JSON files that contain addresses in the `superchain-registry` + /// repo. The JSON key is the name of the contract and the value is an address. + function _loadAddresses(string memory _path) internal { + string[] memory commands = new string[](3); + commands[0] = "bash"; + commands[1] = "-c"; + commands[2] = string.concat("jq -cr < ", _path); + string memory json = string(vm.ffi(commands)); + string[] memory keys = vm.parseJsonKeys(json, ""); + for (uint256 i; i < keys.length; i++) { + string memory key = keys[i]; + address addr = stdJson.readAddress(json, string.concat("$.", key)); + save(key, addr); + } + } + + /// @notice Returns all of the deployments done in the current context. + function newDeployments() external view returns (Deployment[] memory) { + return _newDeployments; + } + + /// @notice Returns whether or not a particular deployment exists. + /// @param _name The name of the deployment. + /// @return Whether the deployment exists or not. + function has(string memory _name) public view returns (bool) { + Deployment memory existing = _namedDeployments[_name]; + return bytes(existing.name).length > 0; + } + + /// @notice Returns the address of a deployment. Also handles the predeploys. + /// @param _name The name of the deployment. + /// @return The address of the deployment. May be `address(0)` if the deployment does not + /// exist. + function getAddress(string memory _name) public view returns (address payable) { + Deployment memory existing = _namedDeployments[_name]; + if (existing.addr != address(0)) { + if (bytes(existing.name).length == 0) { + return payable(address(0)); + } + return existing.addr; + } + + bytes32 digest = keccak256(bytes(_name)); + if (digest == keccak256(bytes("L2CrossDomainMessenger"))) { + return payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER); + } else if (digest == keccak256(bytes("L2ToL1MessagePasser"))) { + return payable(Predeploys.L2_TO_L1_MESSAGE_PASSER); + } else if (digest == keccak256(bytes("L2StandardBridge"))) { + return payable(Predeploys.L2_STANDARD_BRIDGE); + } else if (digest == keccak256(bytes("L2ERC721Bridge"))) { + return payable(Predeploys.L2_ERC721_BRIDGE); + } else if (digest == keccak256(bytes("SequencerFeeWallet"))) { + return payable(Predeploys.SEQUENCER_FEE_WALLET); + } else if (digest == keccak256(bytes("OptimismMintableERC20Factory"))) { + return payable(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); + } else if (digest == keccak256(bytes("OptimismMintableERC721Factory"))) { + return payable(Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY); + } else if (digest == keccak256(bytes("L1Block"))) { + return payable(Predeploys.L1_BLOCK_ATTRIBUTES); + } else if (digest == keccak256(bytes("GasPriceOracle"))) { + return payable(Predeploys.GAS_PRICE_ORACLE); + } else if (digest == keccak256(bytes("L1MessageSender"))) { + return payable(Predeploys.L1_MESSAGE_SENDER); + } else if (digest == keccak256(bytes("DeployerWhitelist"))) { + return payable(Predeploys.DEPLOYER_WHITELIST); + } else if (digest == keccak256(bytes("WETH9"))) { + return payable(Predeploys.WETH9); + } else if (digest == keccak256(bytes("LegacyERC20ETH"))) { + return payable(Predeploys.LEGACY_ERC20_ETH); + } else if (digest == keccak256(bytes("L1BlockNumber"))) { + return payable(Predeploys.L1_BLOCK_NUMBER); + } else if (digest == keccak256(bytes("LegacyMessagePasser"))) { + return payable(Predeploys.LEGACY_MESSAGE_PASSER); + } else if (digest == keccak256(bytes("ProxyAdmin"))) { + return payable(Predeploys.PROXY_ADMIN); + } else if (digest == keccak256(bytes("BaseFeeVault"))) { + return payable(Predeploys.BASE_FEE_VAULT); + } else if (digest == keccak256(bytes("L1FeeVault"))) { + return payable(Predeploys.L1_FEE_VAULT); + } else if (digest == keccak256(bytes("GovernanceToken"))) { + return payable(Predeploys.GOVERNANCE_TOKEN); + } else if (digest == keccak256(bytes("SchemaRegistry"))) { + return payable(Predeploys.SCHEMA_REGISTRY); + } else if (digest == keccak256(bytes("EAS"))) { + return payable(Predeploys.EAS); + } + return payable(address(0)); + } + + /// @notice Returns the address of a deployment and reverts if the deployment + /// does not exist. + /// @return The address of the deployment. + function mustGetAddress(string memory _name) public view returns (address payable) { + address addr = getAddress(_name); + if (addr == address(0)) { + revert DeploymentDoesNotExist(_name); + } + return payable(addr); + } + + /// @notice Returns a deployment that is suitable to be used to interact with contracts. + /// @param _name The name of the deployment. + /// @return The deployment. + function get(string memory _name) public view returns (Deployment memory) { + return _namedDeployments[_name]; + } + + /// @notice Appends a deployment to disk as a JSON deploy artifact. + /// @param _name The name of the deployment. + /// @param _deployed The address of the deployment. + function save(string memory _name, address _deployed) public { + if (bytes(_name).length == 0) { + revert InvalidDeployment("EmptyName"); + } + if (bytes(_namedDeployments[_name].name).length > 0) { + revert InvalidDeployment("AlreadyExists"); + } + + console.log("Saving %s: %s", _name, _deployed); + Deployment memory deployment = Deployment({ name: _name, addr: payable(_deployed) }); + _namedDeployments[_name] = deployment; + _newDeployments.push(deployment); + _appendDeployment(_name, _deployed); + } + + /// @notice Reads the deployment artifact from disk that were generated + /// by the deploy script. + /// @return An array of deployments. + function _getDeployments() internal returns (Deployment[] memory) { + string memory json = vm.readFile(deploymentOutfile); + string[] memory cmd = new string[](3); + cmd[0] = Executables.bash; + cmd[1] = "-c"; + cmd[2] = string.concat(Executables.jq, " 'keys' <<< '", json, "'"); + bytes memory res = vm.ffi(cmd); + string[] memory names = stdJson.readStringArray(string(res), ""); + + Deployment[] memory deployments = new Deployment[](names.length); + for (uint256 i; i < names.length; i++) { + string memory contractName = names[i]; + address addr = stdJson.readAddress(json, string.concat("$.", contractName)); + deployments[i] = Deployment({ name: contractName, addr: payable(addr) }); + } + return deployments; + } + + /// @notice Adds a deployment to the temp deployments file + function _appendDeployment(string memory _name, address _deployed) internal { + vm.writeJson({ json: stdJson.serialize("", _name, _deployed), path: deploymentOutfile }); + } + + /// @notice Stubs a deployment retrieved through `get`. + /// @param _name The name of the deployment. + /// @param _addr The mock address of the deployment. + function prankDeployment(string memory _name, address _addr) public { + if (bytes(_name).length == 0) { + revert InvalidDeployment("EmptyName"); + } + + Deployment memory deployment = Deployment({ name: _name, addr: payable(_addr) }); + _namedDeployments[_name] = deployment; + } + + /// @notice Returns the value of the internal `_initialized` storage slot for a given contract. + function loadInitializedSlot(string memory _contractName) public returns (uint8 initialized_) { + address contractAddress; + // Check if the contract name ends with `Proxy` and, if so, get the implementation address + if (LibString.endsWith(_contractName, "Proxy")) { + contractAddress = EIP1967Helper.getImplementation(getAddress(_contractName)); + _contractName = LibString.slice(_contractName, 0, bytes(_contractName).length - 5); + // If the EIP1967 implementation address is 0, we try to get the implementation address from legacy + // AddressManager, which would work if the proxy is ResolvedDelegateProxy like L1CrossDomainMessengerProxy. + if (contractAddress == address(0)) { + contractAddress = + IAddressManager(mustGetAddress("AddressManager")).getAddress(string.concat("OVM_", _contractName)); + } + } else { + contractAddress = mustGetAddress(_contractName); + } + StorageSlot memory slot = ForgeArtifacts.getInitializedSlot(_contractName); + bytes32 slotVal = vm.load(contractAddress, bytes32(vm.parseUint(slot.slot))); + initialized_ = uint8((uint256(slotVal) >> (slot.offset * 8)) & 0xFF); + } +} diff --git a/packages/contracts-bedrock/scripts/ChainAssertions.sol b/packages/contracts-bedrock/scripts/ChainAssertions.sol new file mode 100644 index 000000000000..7afdceb62cb3 --- /dev/null +++ b/packages/contracts-bedrock/scripts/ChainAssertions.sol @@ -0,0 +1,418 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { DeployConfig } from "scripts/DeployConfig.s.sol"; +import { Deployer } from "scripts/Deployer.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { Constants } from "src/libraries/Constants.sol"; +import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { ProtocolVersion, ProtocolVersions } from "src/L1/ProtocolVersions.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Types } from "scripts/Types.sol"; +import { Vm } from "forge-std/Vm.sol"; +import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol"; +import { console2 as console } from "forge-std/console2.sol"; + +library ChainAssertions { + Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + /// @notice Asserts the correctness of an L1 deployment. This function expects that all contracts + /// within the `prox` ContractSet are proxies that have been setup and initialized. + function postDeployAssertions( + Types.ContractSet memory _prox, + DeployConfig _cfg, + uint256 _l2OutputOracleStartingTimestamp, + Vm _vm + ) + internal + view + { + console.log("Running post-deploy assertions"); + ResourceMetering.ResourceConfig memory rcfg = SystemConfig(_prox.SystemConfig).resourceConfig(); + ResourceMetering.ResourceConfig memory dflt = Constants.DEFAULT_RESOURCE_CONFIG(); + require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt))); + + checkSystemConfig({ _contracts: _prox, _cfg: _cfg, _isProxy: true }); + checkL1CrossDomainMessenger({ _contracts: _prox, _vm: _vm, _isProxy: true }); + checkL1StandardBridge({ _contracts: _prox, _isProxy: true }); + checkL2OutputOracle({ + _contracts: _prox, + _cfg: _cfg, + _l2OutputOracleStartingTimestamp: _l2OutputOracleStartingTimestamp, + _isProxy: true + }); + checkOptimismMintableERC20Factory({ _contracts: _prox, _isProxy: true }); + checkL1ERC721Bridge({ _contracts: _prox, _isProxy: true }); + checkOptimismPortal({ _contracts: _prox, _cfg: _cfg, _isProxy: true }); + checkOptimismPortal2({ _contracts: _prox, _cfg: _cfg, _isProxy: true }); + checkProtocolVersions({ _contracts: _prox, _cfg: _cfg, _isProxy: true }); + } + + /// @notice Asserts that the SystemConfig is setup correctly + function checkSystemConfig(Types.ContractSet memory _contracts, DeployConfig _cfg, bool _isProxy) internal view { + console.log("Running chain assertions on the SystemConfig"); + SystemConfig config = SystemConfig(_contracts.SystemConfig); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(config), _slot: 0, _offset: 0 }); + + ResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig(); + + if (_isProxy) { + require(config.owner() == _cfg.finalSystemOwner()); + require(config.overhead() == _cfg.gasPriceOracleOverhead()); + require(config.scalar() == _cfg.gasPriceOracleScalar()); + require(config.batcherHash() == bytes32(uint256(uint160(_cfg.batchSenderAddress())))); + require(config.gasLimit() == uint64(_cfg.l2GenesisBlockGasLimit())); + require(config.unsafeBlockSigner() == _cfg.p2pSequencerAddress()); + // Check _config + ResourceMetering.ResourceConfig memory rconfig = Constants.DEFAULT_RESOURCE_CONFIG(); + require(resourceConfig.maxResourceLimit == rconfig.maxResourceLimit); + require(resourceConfig.elasticityMultiplier == rconfig.elasticityMultiplier); + require(resourceConfig.baseFeeMaxChangeDenominator == rconfig.baseFeeMaxChangeDenominator); + require(resourceConfig.systemTxMaxGas == rconfig.systemTxMaxGas); + require(resourceConfig.minimumBaseFee == rconfig.minimumBaseFee); + require(resourceConfig.maximumBaseFee == rconfig.maximumBaseFee); + // Depends on start block being set to 0 in `initialize` + uint256 cfgStartBlock = _cfg.systemConfigStartBlock(); + require(config.startBlock() == (cfgStartBlock == 0 ? block.number : cfgStartBlock)); + require(config.batchInbox() == _cfg.batchInboxAddress()); + // Check _addresses + require(config.l1CrossDomainMessenger() == _contracts.L1CrossDomainMessenger); + require(config.l1ERC721Bridge() == _contracts.L1ERC721Bridge); + require(config.l1StandardBridge() == _contracts.L1StandardBridge); + require(config.l2OutputOracle() == _contracts.L2OutputOracle); + require(config.optimismPortal() == _contracts.OptimismPortal); + require(config.optimismMintableERC20Factory() == _contracts.OptimismMintableERC20Factory); + } else { + require(config.owner() == address(0xdead)); + require(config.overhead() == 0); + require(config.scalar() == 0); + require(config.batcherHash() == bytes32(0)); + require(config.gasLimit() == 1); + require(config.unsafeBlockSigner() == address(0)); + // Check _config + require(resourceConfig.maxResourceLimit == 1); + require(resourceConfig.elasticityMultiplier == 1); + require(resourceConfig.baseFeeMaxChangeDenominator == 2); + require(resourceConfig.systemTxMaxGas == 0); + require(resourceConfig.minimumBaseFee == 0); + require(resourceConfig.maximumBaseFee == 0); + // Check _addresses + require(config.startBlock() == type(uint256).max); + require(config.batchInbox() == address(0)); + require(config.l1CrossDomainMessenger() == address(0)); + require(config.l1ERC721Bridge() == address(0)); + require(config.l1StandardBridge() == address(0)); + require(config.l2OutputOracle() == address(0)); + require(config.optimismPortal() == address(0)); + require(config.optimismMintableERC20Factory() == address(0)); + } + } + + /// @notice Asserts that the L1CrossDomainMessenger is setup correctly + function checkL1CrossDomainMessenger(Types.ContractSet memory _contracts, Vm _vm, bool _isProxy) internal view { + console.log("Running chain assertions on the L1CrossDomainMessenger"); + L1CrossDomainMessenger messenger = L1CrossDomainMessenger(_contracts.L1CrossDomainMessenger); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(messenger), _slot: 0, _offset: 20 }); + + require(address(messenger.OTHER_MESSENGER()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER); + require(address(messenger.otherMessenger()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER); + + if (_isProxy) { + require(address(messenger.PORTAL()) == _contracts.OptimismPortal); + require(address(messenger.portal()) == _contracts.OptimismPortal); + require(address(messenger.superchainConfig()) == _contracts.SuperchainConfig); + bytes32 xdmSenderSlot = _vm.load(address(messenger), bytes32(uint256(204))); + require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER); + } else { + require(address(messenger.PORTAL()) == address(0)); + require(address(messenger.portal()) == address(0)); + require(address(messenger.superchainConfig()) == address(0)); + } + } + + /// @notice Asserts that the L1StandardBridge is setup correctly + function checkL1StandardBridge(Types.ContractSet memory _contracts, bool _isProxy) internal view { + console.log("Running chain assertions on the L1StandardBridge"); + L1StandardBridge bridge = L1StandardBridge(payable(_contracts.L1StandardBridge)); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); + + if (_isProxy) { + require(address(bridge.MESSENGER()) == _contracts.L1CrossDomainMessenger); + require(address(bridge.messenger()) == _contracts.L1CrossDomainMessenger); + require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE); + require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE); + require(address(bridge.superchainConfig()) == _contracts.SuperchainConfig); + } else { + require(address(bridge.MESSENGER()) == address(0)); + require(address(bridge.messenger()) == address(0)); + require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE); + require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE); + require(address(bridge.superchainConfig()) == address(0)); + } + } + + /// @notice Asserts that the DisputeGameFactory is setup correctly + function checkDisputeGameFactory(Types.ContractSet memory _contracts, address _expectedOwner) internal view { + console.log("Running chain assertions on the DisputeGameFactory"); + DisputeGameFactory factory = DisputeGameFactory(_contracts.DisputeGameFactory); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); + + require(factory.owner() == _expectedOwner); + } + + /// @notice Asserts that the DelayedWETH is setup correctly + function checkDelayedWETH( + Types.ContractSet memory _contracts, + DeployConfig _cfg, + bool _isProxy, + address _expectedOwner + ) + internal + view + { + console.log("Running chain assertions on the DelayedWETH"); + DelayedWETH weth = DelayedWETH(payable(_contracts.DelayedWETH)); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(weth), _slot: 0, _offset: 0 }); + + if (_isProxy) { + require(weth.owner() == _expectedOwner); + require(weth.delay() == _cfg.faultGameWithdrawalDelay()); + require(weth.config() == SuperchainConfig(_contracts.SuperchainConfig)); + } else { + require(weth.owner() == _expectedOwner); + require(weth.delay() == _cfg.faultGameWithdrawalDelay()); + } + } + + /// @notice Asserts that the L2OutputOracle is setup correctly + function checkL2OutputOracle( + Types.ContractSet memory _contracts, + DeployConfig _cfg, + uint256 _l2OutputOracleStartingTimestamp, + bool _isProxy + ) + internal + view + { + console.log("Running chain assertions on the L2OutputOracle"); + L2OutputOracle oracle = L2OutputOracle(_contracts.L2OutputOracle); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(oracle), _slot: 0, _offset: 0 }); + + if (_isProxy) { + require(oracle.SUBMISSION_INTERVAL() == _cfg.l2OutputOracleSubmissionInterval()); + require(oracle.submissionInterval() == _cfg.l2OutputOracleSubmissionInterval()); + require(oracle.L2_BLOCK_TIME() == _cfg.l2BlockTime()); + require(oracle.l2BlockTime() == _cfg.l2BlockTime()); + require(oracle.PROPOSER() == _cfg.l2OutputOracleProposer()); + require(oracle.proposer() == _cfg.l2OutputOracleProposer()); + require(oracle.CHALLENGER() == _cfg.l2OutputOracleChallenger()); + require(oracle.challenger() == _cfg.l2OutputOracleChallenger()); + require(oracle.FINALIZATION_PERIOD_SECONDS() == _cfg.finalizationPeriodSeconds()); + require(oracle.finalizationPeriodSeconds() == _cfg.finalizationPeriodSeconds()); + require(oracle.startingBlockNumber() == _cfg.l2OutputOracleStartingBlockNumber()); + require(oracle.startingTimestamp() == _l2OutputOracleStartingTimestamp); + } else { + require(oracle.SUBMISSION_INTERVAL() == 1); + require(oracle.submissionInterval() == 1); + require(oracle.L2_BLOCK_TIME() == 1); + require(oracle.l2BlockTime() == 1); + require(oracle.PROPOSER() == address(0)); + require(oracle.proposer() == address(0)); + require(oracle.CHALLENGER() == address(0)); + require(oracle.challenger() == address(0)); + require(oracle.FINALIZATION_PERIOD_SECONDS() == 0); + require(oracle.finalizationPeriodSeconds() == 0); + require(oracle.startingBlockNumber() == 0); + require(oracle.startingTimestamp() == 0); + } + } + + /// @notice Asserts that the OptimismMintableERC20Factory is setup correctly + function checkOptimismMintableERC20Factory(Types.ContractSet memory _contracts, bool _isProxy) internal view { + console.log("Running chain assertions on the OptimismMintableERC20Factory"); + OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(_contracts.OptimismMintableERC20Factory); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); + + if (_isProxy) { + require(factory.BRIDGE() == _contracts.L1StandardBridge); + require(factory.bridge() == _contracts.L1StandardBridge); + } else { + require(factory.BRIDGE() == address(0)); + require(factory.bridge() == address(0)); + } + } + + /// @notice Asserts that the L1ERC721Bridge is setup correctly + function checkL1ERC721Bridge(Types.ContractSet memory _contracts, bool _isProxy) internal view { + console.log("Running chain assertions on the L1ERC721Bridge"); + L1ERC721Bridge bridge = L1ERC721Bridge(_contracts.L1ERC721Bridge); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(bridge), _slot: 0, _offset: 0 }); + + require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE); + require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE); + + if (_isProxy) { + require(address(bridge.MESSENGER()) == _contracts.L1CrossDomainMessenger); + require(address(bridge.messenger()) == _contracts.L1CrossDomainMessenger); + require(address(bridge.superchainConfig()) == _contracts.SuperchainConfig); + } else { + require(address(bridge.MESSENGER()) == address(0)); + require(address(bridge.messenger()) == address(0)); + require(address(bridge.superchainConfig()) == address(0)); + } + } + + /// @notice Asserts the OptimismPortal is setup correctly + function checkOptimismPortal(Types.ContractSet memory _contracts, DeployConfig _cfg, bool _isProxy) internal view { + console.log("Running chain assertions on the OptimismPortal"); + + OptimismPortal portal = OptimismPortal(payable(_contracts.OptimismPortal)); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(portal), _slot: 0, _offset: 0 }); + + address guardian = _cfg.superchainConfigGuardian(); + if (guardian.code.length == 0) { + console.log("Guardian has no code: %s", guardian); + } + + if (_isProxy) { + require(address(portal.L2_ORACLE()) == _contracts.L2OutputOracle); + require(address(portal.l2Oracle()) == _contracts.L2OutputOracle); + require(address(portal.SYSTEM_CONFIG()) == _contracts.SystemConfig); + require(address(portal.systemConfig()) == _contracts.SystemConfig); + require(portal.GUARDIAN() == guardian); + require(portal.guardian() == guardian); + require(address(portal.superchainConfig()) == address(_contracts.SuperchainConfig)); + require(portal.paused() == SuperchainConfig(_contracts.SuperchainConfig).paused()); + require(portal.l2Sender() == Constants.DEFAULT_L2_SENDER); + } else { + require(address(portal.L2_ORACLE()) == address(0)); + require(address(portal.l2Oracle()) == address(0)); + require(address(portal.SYSTEM_CONFIG()) == address(0)); + require(address(portal.systemConfig()) == address(0)); + require(address(portal.superchainConfig()) == address(0)); + require(portal.l2Sender() == Constants.DEFAULT_L2_SENDER); + } + } + + /// @notice Asserts the OptimismPortal2 is setup correctly + function checkOptimismPortal2( + Types.ContractSet memory _contracts, + DeployConfig _cfg, + bool _isProxy + ) + internal + view + { + console.log("Running chain assertions on the OptimismPortal2"); + + OptimismPortal2 portal = OptimismPortal2(payable(_contracts.OptimismPortal2)); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(portal), _slot: 0, _offset: 0 }); + + address guardian = _cfg.superchainConfigGuardian(); + if (guardian.code.length == 0) { + console.log("Guardian has no code: %s", guardian); + } + + if (_isProxy) { + require(address(portal.disputeGameFactory()) == _contracts.DisputeGameFactory); + require(address(portal.SYSTEM_CONFIG()) == _contracts.SystemConfig); + require(address(portal.systemConfig()) == _contracts.SystemConfig); + require(portal.GUARDIAN() == guardian); + require(portal.guardian() == guardian); + require(address(portal.superchainConfig()) == address(_contracts.SuperchainConfig)); + require(portal.paused() == SuperchainConfig(_contracts.SuperchainConfig).paused()); + require(portal.l2Sender() == Constants.DEFAULT_L2_SENDER); + } else { + require(address(portal.disputeGameFactory()) == address(0)); + require(address(portal.SYSTEM_CONFIG()) == address(0)); + require(address(portal.systemConfig()) == address(0)); + require(address(portal.superchainConfig()) == address(0)); + require(portal.l2Sender() == Constants.DEFAULT_L2_SENDER); + } + } + + /// @notice Asserts that the ProtocolVersions is setup correctly + function checkProtocolVersions( + Types.ContractSet memory _contracts, + DeployConfig _cfg, + bool _isProxy + ) + internal + view + { + console.log("Running chain assertions on the ProtocolVersions"); + ProtocolVersions versions = ProtocolVersions(_contracts.ProtocolVersions); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(versions), _slot: 0, _offset: 0 }); + + if (_isProxy) { + require(versions.owner() == _cfg.finalSystemOwner()); + require(ProtocolVersion.unwrap(versions.required()) == _cfg.requiredProtocolVersion()); + require(ProtocolVersion.unwrap(versions.recommended()) == _cfg.recommendedProtocolVersion()); + } else { + require(versions.owner() == address(0xdead)); + require(ProtocolVersion.unwrap(versions.required()) == 0); + require(ProtocolVersion.unwrap(versions.recommended()) == 0); + } + } + + /// @notice Asserts that the SuperchainConfig is setup correctly + function checkSuperchainConfig( + Types.ContractSet memory _contracts, + DeployConfig _cfg, + bool _isPaused + ) + internal + view + { + console.log("Running chain assertions on the SuperchainConfig"); + SuperchainConfig superchainConfig = SuperchainConfig(_contracts.SuperchainConfig); + + // Check that the contract is initialized + assertSlotValueIsOne({ _contractAddress: address(superchainConfig), _slot: 0, _offset: 0 }); + + require(superchainConfig.guardian() == _cfg.superchainConfigGuardian()); + require(superchainConfig.paused() == _isPaused); + } + + /// @dev Asserts that for a given contract the value of a storage slot at an offset is 1. + function assertSlotValueIsOne(address _contractAddress, uint256 _slot, uint256 _offset) internal view { + bytes32 slotVal = vm.load(_contractAddress, bytes32(_slot)); + require( + uint8((uint256(slotVal) >> (_offset * 8)) & 0xFF) == uint8(1), + "Storage value is not 1 at the given slot and offset" + ); + } +} diff --git a/packages/contracts-bedrock/scripts/Config.sol b/packages/contracts-bedrock/scripts/Config.sol new file mode 100644 index 000000000000..eafb8bfe983b --- /dev/null +++ b/packages/contracts-bedrock/scripts/Config.sol @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Vm } from "forge-std/Vm.sol"; +import { Chains } from "scripts/Chains.sol"; + +/// @title Config +/// @notice Contains all env var based config. Add any new env var parsing to this file +/// to ensure that all config is in a single place. +library Config { + /// @notice Foundry cheatcode VM. + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + /// @notice Returns the path on the local filesystem where the deployment artifact is + /// written to disk after doing a deployment. + function deploymentOutfile() internal view returns (string memory _env) { + _env = vm.envOr( + "DEPLOYMENT_OUTFILE", string.concat(vm.projectRoot(), "/deployments/", _getDeploymentContext(), "/.deploy") + ); + } + + /// @notice Returns the path on the local filesystem where the deploy config is + function deployConfigPath() internal view returns (string memory _env) { + _env = vm.envOr( + "DEPLOY_CONFIG_PATH", string.concat(vm.projectRoot(), "/deploy-config/", _getDeploymentContext(), ".json") + ); + } + + /// @notice Returns the chainid from the EVM context or the value of the CHAIN_ID env var as + /// an override. + function chainID() internal view returns (uint256 _env) { + _env = vm.envOr("CHAIN_ID", block.chainid); + } + + /// @notice Returns the value of the env var CONTRACT_ADDRESSES_PATH which is a JSON key/value + /// pair of contract names and their addresses. Each key/value pair is passed to `save` + /// which then backs the `getAddress` function. + function contractAddressesPath() internal view returns (string memory _env) { + _env = vm.envOr("CONTRACT_ADDRESSES_PATH", string("")); + } + + /// @notice Returns the deployment context which was only useful in the hardhat deploy style + /// of deployments. It is now DEPRECATED and will be removed in the future. + function deploymentContext() internal view returns (string memory _env) { + _env = vm.envOr("DEPLOYMENT_CONTEXT", string("")); + } + + /// @notice The CREATE2 salt to be used when deploying the implementations. + function implSalt() internal view returns (string memory _env) { + _env = vm.envOr("IMPL_SALT", string("ethers phoenix")); + } + + /// @notice Returns the path that the state dump file should be written to or read from + /// on the local filesystem. + function stateDumpPath(string memory _name) internal view returns (string memory _env) { + _env = vm.envOr( + "STATE_DUMP_PATH", string.concat(vm.projectRoot(), "/", _name, "-", vm.toString(block.chainid), ".json") + ); + } + + /// @notice Returns the sig of the entrypoint to the deploy script. By default, it is `run`. + /// This was useful for creating hardhat deploy style artifacts and will be removed in a future release. + function sig() internal view returns (string memory _env) { + _env = vm.envOr("SIG", string("run")); + } + + /// @notice Returns the name of the file that the forge deployment artifact is written to on the local + /// filesystem. By default, it is the name of the deploy script with the suffix `-latest.json`. + /// This was useful for creating hardhat deploy style artifacts and will be removed in a future release. + function deployFile(string memory _sig) internal view returns (string memory _env) { + _env = vm.envOr("DEPLOY_FILE", string.concat(_sig, "-latest.json")); + } + + /// @notice Returns the private key that is used to configure drippie. + function drippieOwnerPrivateKey() internal view returns (uint256 _env) { + _env = vm.envUint("DRIPPIE_OWNER_PRIVATE_KEY"); + } + + /// @notice The context of the deployment is used to namespace the artifacts. + /// An unknown context will use the chainid as the context name. + /// This is legacy code and should be removed in the future. + function _getDeploymentContext() private view returns (string memory) { + string memory context = deploymentContext(); + if (bytes(context).length > 0) { + return context; + } + + uint256 chainid = Config.chainID(); + if (chainid == Chains.Mainnet) { + return "mainnet"; + } else if (chainid == Chains.Goerli) { + return "goerli"; + } else if (chainid == Chains.OPGoerli) { + return "optimism-goerli"; + } else if (chainid == Chains.OPMainnet) { + return "optimism-mainnet"; + } else if (chainid == Chains.LocalDevnet || chainid == Chains.GethDevnet) { + return "devnetL1"; + } else if (chainid == Chains.Hardhat) { + return "hardhat"; + } else if (chainid == Chains.Sepolia) { + return "sepolia"; + } else if (chainid == Chains.OPSepolia) { + return "optimism-sepolia"; + } else { + return vm.toString(chainid); + } + } +} diff --git a/packages/contracts-bedrock/scripts/Deploy.s.sol b/packages/contracts-bedrock/scripts/Deploy.s.sol index a9d7e1a3fcdb..ca56c9e5dcc2 100644 --- a/packages/contracts-bedrock/scripts/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/Deploy.s.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import { VmSafe } from "forge-std/Vm.sol"; import { Script } from "forge-std/Script.sol"; import { console2 as console } from "forge-std/console2.sol"; @@ -11,99 +12,79 @@ import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; import { Enum as SafeOps } from "safe-contracts/common/Enum.sol"; import { Deployer } from "scripts/Deployer.sol"; -import { DeployConfig } from "scripts/DeployConfig.s.sol"; -import { Safe } from "safe-contracts/Safe.sol"; -import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { DataAvailabilityChallenge } from "src/L1/DataAvailabilityChallenge.sol"; import { Constants } from "src/libraries/Constants.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; +import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { MIPS } from "src/cannon/MIPS.sol"; -import { BlockOracle } from "src/dispute/BlockOracle.sol"; import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; import { StorageSetter } from "src/universal/StorageSetter.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { Chains } from "scripts/Chains.sol"; +import { Config } from "scripts/Config.sol"; import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; -import { AlphabetVM } from "../test/FaultDisputeGame.t.sol"; +import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; import "src/libraries/DisputeTypes.sol"; +import { ChainAssertions } from "scripts/ChainAssertions.sol"; +import { Types } from "scripts/Types.sol"; +import { LibStateDiff } from "scripts/libraries/LibStateDiff.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol"; /// @title Deploy /// @notice Script used to deploy a bedrock system. The entire system is deployed within the `run` function. /// To add a new contract to the system, add a public function that deploys that individual contract. /// Then add a call to that function inside of `run`. Be sure to call the `save` function after each /// deployment so that hardhat-deploy style artifacts can be generated using a call to `sync()`. +/// The `CONTRACT_ADDRESSES_PATH` environment variable can be set to a path that contains a JSON file full of +/// contract name to address pairs. That enables this script to be much more flexible in the way it is used. +/// This contract must not have constructor logic because it is set into state using `etch`. contract Deploy is Deployer { - DeployConfig cfg; - - /// @notice The name of the script, used to ensure the right deploy artifacts - /// are used. - function name() public pure override returns (string memory name_) { - name_ = "Deploy"; - } - - function setUp() public override { - super.setUp(); - - string memory path = string.concat(vm.projectRoot(), "/deploy-config/", deploymentContext, ".json"); - cfg = new DeployConfig(path); - - console.log("Deploying from %s", deployScript); - console.log("Deployment context: %s", deploymentContext); - } - - /// @notice Deploy all of the L1 contracts - function run() public { - console.log("Deploying L1 system"); - - deployProxies(); - deployImplementations(); - - deploySafe(); - transferProxyAdminOwnership(); // to the Safe - - initializeDisputeGameFactory(); - initializeSystemConfig(); - initializeL1StandardBridge(); - initializeL1ERC721Bridge(); - initializeOptimismMintableERC20Factory(); - initializeL1CrossDomainMessenger(); - initializeL2OutputOracle(); - initializeOptimismPortal(); - initializeProtocolVersions(); - -// setAlphabetFaultGameImplementation(); -// setCannonFaultGameImplementation(); - - transferDisputeGameFactoryOwnership(); + using stdJson for string; + + /// @notice FaultDisputeGameParams is a struct that contains the parameters necessary to call + /// the function _setFaultGameImplementation. This struct exists because the EVM needs + /// to finally adopt PUSHN and get rid of stack too deep once and for all. + /// Someday we will look back and laugh about stack too deep, today is not that day. + struct FaultDisputeGameParams { + AnchorStateRegistry anchorStateRegistry; + DelayedWETH weth; + GameType gameType; + Claim absolutePrestate; + IBigStepper faultVm; + uint256 maxGameDepth; } - /// @notice The create2 salt used for deployment of the contract implementations. - /// Using this helps to reduce config across networks as the implementation - /// addresses will be the same across networks when deployed with create2. - function implSalt() public returns (bytes32) { - return keccak256(bytes(vm.envOr("IMPL_SALT", string("ethers phoenix")))); - } + //////////////////////////////////////////////////////////////// + // Modifiers // + //////////////////////////////////////////////////////////////// /// @notice Modifier that wraps a function in broadcasting. modifier broadcast() { - vm.startBroadcast(); + vm.startBroadcast(msg.sender); _; vm.stopBroadcast(); } @@ -128,59 +109,310 @@ contract Deploy is Deployer { } } - /// @notice Deploy all of the proxies - function deployProxies() public { + /// @notice Modifier that wraps a function with statediff recording. + /// The returned AccountAccess[] array is then written to + /// the `snapshots/state-diff/.json` output file. + modifier stateDiff() { + vm.startStateDiffRecording(); + _; + VmSafe.AccountAccess[] memory accesses = vm.stopAndReturnStateDiff(); + console.log("Writing %d state diff account accesses to snapshots/state-diff/%s.json", accesses.length, name()); + string memory json = LibStateDiff.encodeAccountAccesses(accesses); + string memory statediffPath = string.concat(vm.projectRoot(), "/snapshots/state-diff/", name(), ".json"); + vm.writeJson({ json: json, path: statediffPath }); + } + + //////////////////////////////////////////////////////////////// + // Accessors // + //////////////////////////////////////////////////////////////// + + /// @inheritdoc Deployer + function name() public pure override returns (string memory name_) { + name_ = "Deploy"; + } + + /// @notice The create2 salt used for deployment of the contract implementations. + /// Using this helps to reduce config across networks as the implementation + /// addresses will be the same across networks when deployed with create2. + function _implSalt() internal view returns (bytes32) { + return keccak256(bytes(Config.implSalt())); + } + + /// @notice Returns the proxy addresses. If a proxy is not found, it will have address(0). + function _proxies() internal view returns (Types.ContractSet memory proxies_) { + proxies_ = Types.ContractSet({ + L1CrossDomainMessenger: mustGetAddress("L1CrossDomainMessengerProxy"), + L1StandardBridge: mustGetAddress("L1StandardBridgeProxy"), + L2OutputOracle: mustGetAddress("L2OutputOracleProxy"), + DisputeGameFactory: mustGetAddress("DisputeGameFactoryProxy"), + DelayedWETH: mustGetAddress("DelayedWETHProxy"), + AnchorStateRegistry: mustGetAddress("AnchorStateRegistryProxy"), + OptimismMintableERC20Factory: mustGetAddress("OptimismMintableERC20FactoryProxy"), + OptimismPortal: mustGetAddress("OptimismPortalProxy"), + OptimismPortal2: mustGetAddress("OptimismPortalProxy"), + SystemConfig: mustGetAddress("SystemConfigProxy"), + L1ERC721Bridge: mustGetAddress("L1ERC721BridgeProxy"), + ProtocolVersions: mustGetAddress("ProtocolVersionsProxy"), + SuperchainConfig: mustGetAddress("SuperchainConfigProxy") + }); + } + + /// @notice Returns the proxy addresses, not reverting if any are unset. + function _proxiesUnstrict() internal view returns (Types.ContractSet memory proxies_) { + proxies_ = Types.ContractSet({ + L1CrossDomainMessenger: getAddress("L1CrossDomainMessengerProxy"), + L1StandardBridge: getAddress("L1StandardBridgeProxy"), + L2OutputOracle: getAddress("L2OutputOracleProxy"), + DisputeGameFactory: getAddress("DisputeGameFactoryProxy"), + DelayedWETH: getAddress("DelayedWETHProxy"), + AnchorStateRegistry: getAddress("AnchorStateRegistryProxy"), + OptimismMintableERC20Factory: getAddress("OptimismMintableERC20FactoryProxy"), + OptimismPortal: getAddress("OptimismPortalProxy"), + OptimismPortal2: getAddress("OptimismPortalProxy"), + SystemConfig: getAddress("SystemConfigProxy"), + L1ERC721Bridge: getAddress("L1ERC721BridgeProxy"), + ProtocolVersions: getAddress("ProtocolVersionsProxy"), + SuperchainConfig: getAddress("SuperchainConfigProxy") + }); + } + + //////////////////////////////////////////////////////////////// + // State Changing Helper Functions // + //////////////////////////////////////////////////////////////// + + /// @notice Gets the address of the SafeProxyFactory and Safe singleton for use in deploying a new GnosisSafe. + function _getSafeFactory() internal returns (SafeProxyFactory safeProxyFactory_, Safe safeSingleton_) { + // These are the standard create2 deployed contracts. First we'll check if they are deployed, + // if not we'll deploy new ones, though not at these addresses. + address safeProxyFactory = 0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2; + address safeSingleton = 0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552; + + safeProxyFactory.code.length == 0 + ? safeProxyFactory_ = new SafeProxyFactory() + : safeProxyFactory_ = SafeProxyFactory(safeProxyFactory); + + safeSingleton.code.length == 0 ? safeSingleton_ = new Safe() : safeSingleton_ = Safe(payable(safeSingleton)); + + save("SafeProxyFactory", address(safeProxyFactory_)); + save("SafeSingleton", address(safeSingleton_)); + } + + /// @notice Make a call from the Safe contract to an arbitrary address with arbitrary data + function _callViaSafe(address _target, bytes memory _data) internal { + Safe safe = Safe(mustGetAddress("SystemOwnerSafe")); + + // This is the signature format used the caller is also the signer. + bytes memory signature = abi.encodePacked(uint256(uint160(msg.sender)), bytes32(0), uint8(1)); + + safe.execTransaction({ + to: _target, + value: 0, + data: _data, + operation: SafeOps.Operation.Call, + safeTxGas: 0, + baseGas: 0, + gasPrice: 0, + gasToken: address(0), + refundReceiver: payable(address(0)), + signatures: signature + }); + } + + /// @notice Call from the Safe contract to the Proxy Admin's upgrade and call method + function _upgradeAndCallViaSafe(address _proxy, address _implementation, bytes memory _innerCallData) internal { + address proxyAdmin = mustGetAddress("ProxyAdmin"); + + bytes memory data = + abi.encodeCall(ProxyAdmin.upgradeAndCall, (payable(_proxy), _implementation, _innerCallData)); + + _callViaSafe({ _target: proxyAdmin, _data: data }); + } + + /// @notice Transfer ownership of the ProxyAdmin contract to the final system owner + function transferProxyAdminOwnership() public broadcast { + ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); + address owner = proxyAdmin.owner(); + address safe = mustGetAddress("SystemOwnerSafe"); + if (owner != safe) { + proxyAdmin.transferOwnership(safe); + console.log("ProxyAdmin ownership transferred to Safe at: %s", safe); + } + } + + /// @notice Transfer ownership of a Proxy to the ProxyAdmin contract + /// This is expected to be used in conjusting with deployERC1967ProxyWithOwner after setup actions + /// have been performed on the proxy. + /// @param _name The name of the proxy to transfer ownership of. + function transferProxyToProxyAdmin(string memory _name) public broadcast { + Proxy proxy = Proxy(mustGetAddress(_name)); + address proxyAdmin = mustGetAddress("ProxyAdmin"); + proxy.changeAdmin(proxyAdmin); + console.log("Proxy %s ownership transferred to ProxyAdmin at: %s", _name, proxyAdmin); + } + + //////////////////////////////////////////////////////////////// + // SetUp and Run // + //////////////////////////////////////////////////////////////// + + /// @notice Deploy all of the L1 contracts necessary for a full Superchain with a single Op Chain. + function run() public { + console.log("Deploying a fresh OP Stack including SuperchainConfig"); + _run(); + } + + function runWithStateDump() public { + _run(); + + vm.dumpState(Config.stateDumpPath(name())); + } + + /// @notice Deploy all L1 contracts and write the state diff to a file. + function runWithStateDiff() public stateDiff { + _run(); + } + + /// @notice Internal function containing the deploy logic. + function _run() internal { + deploySafe(); + setupSuperchain(); + if (cfg.usePlasma()) { + setupOpPlasma(); + } + setupOpChain(); + } + + //////////////////////////////////////////////////////////////// + // High Level Deployment Functions // + //////////////////////////////////////////////////////////////// + + /// @notice Deploy a full system with a new SuperchainConfig + /// The Superchain system has 2 singleton contracts which lie outside of an OP Chain: + /// 1. The SuperchainConfig contract + /// 2. The ProtocolVersions contract + function setupSuperchain() public { + console.log("Setting up Superchain"); + + // Deploy a new ProxyAdmin and AddressManager + // This proxy will be used on the SuperchainConfig and ProtocolVersions contracts, as well as the contracts + // in the OP Chain system. deployAddressManager(); deployProxyAdmin(); + transferProxyAdminOwnership(); + + // Deploy the SuperchainConfigProxy + deployERC1967Proxy("SuperchainConfigProxy"); + deploySuperchainConfig(); + initializeSuperchainConfig(); + + // Deploy the ProtocolVersionsProxy + deployERC1967Proxy("ProtocolVersionsProxy"); + deployProtocolVersions(); + initializeProtocolVersions(); + } + + /// @notice Deploy a new OP Chain, with an existing SuperchainConfig provided + function setupOpChain() public { + console.log("Deploying OP Chain"); - deployOptimismPortalProxy(); - deployL2OutputOracleProxy(); - deploySystemConfigProxy(); + // Ensure that the requisite contracts are deployed + mustGetAddress("SuperchainConfigProxy"); + mustGetAddress("SystemOwnerSafe"); + mustGetAddress("AddressManager"); + mustGetAddress("ProxyAdmin"); + + deployProxies(); + deployImplementations(); + initializeImplementations(); + + // setAlphabetFaultGameImplementation({ _allowUpgrade: false }); + // setCannonFaultGameImplementation({ _allowUpgrade: false }); + // setPermissionedCannonFaultGameImplementation({ _allowUpgrade: false }); + + transferDisputeGameFactoryOwnership(); + transferDelayedWETHOwnership(); + } + + /// @notice Deploy all of the proxies + function deployProxies() public { + console.log("Deploying proxies"); + + deployERC1967Proxy("OptimismPortalProxy"); + deployERC1967Proxy("SystemConfigProxy"); deployL1StandardBridgeProxy(); deployL1CrossDomainMessengerProxy(); - deployOptimismMintableERC20FactoryProxy(); - deployL1ERC721BridgeProxy(); - deployDisputeGameFactoryProxy(); - deployProtocolVersionsProxy(); + deployERC1967Proxy("OptimismMintableERC20FactoryProxy"); + deployERC1967Proxy("L1ERC721BridgeProxy"); + + // Both the DisputeGameFactory and L2OutputOracle proxies are deployed regardles of whether FPAC is enabled + // to prevent a nastier refactor to the deploy scripts. In the future, the L2OutputOracle will be removed. If + // fault proofs are not enabled, the DisputeGameFactory proxy will be unused. + deployERC1967Proxy("DisputeGameFactoryProxy"); + deployERC1967Proxy("L2OutputOracleProxy"); + deployERC1967Proxy("DelayedWETHProxy"); + deployERC1967Proxy("AnchorStateRegistryProxy"); transferAddressManagerOwnership(); // to the ProxyAdmin } /// @notice Deploy all of the implementations function deployImplementations() public { - deployOptimismPortal(); + console.log("Deploying implementations"); deployL1CrossDomainMessenger(); - deployL2OutputOracle(); deployOptimismMintableERC20Factory(); deploySystemConfig(); deployL1StandardBridge(); deployL1ERC721Bridge(); + deployOptimismPortal(); + deployL2OutputOracle(); + + // Fault proofs + deployOptimismPortal2(); deployDisputeGameFactory(); - deployBlockOracle(); + deployDelayedWETH(); deployPreimageOracle(); deployMips(); - deployProtocolVersions(); + deployAnchorStateRegistry(); } - // @notice Gets the address of the SafeProxyFactory and Safe singleton for use in deploying a new GnosisSafe. - function _getSafeFactory() internal returns (SafeProxyFactory safeProxyFactory_, Safe safeSingleton_) { - // These are they standard create2 deployed contracts. First we'll check if they are deployed, - // if not we'll deploy new ones, though not at these addresses. - address safeProxyFactory = 0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2; - address safeSingleton = 0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552; - - safeProxyFactory.code.length == 0 - ? safeProxyFactory_ = new SafeProxyFactory() - : safeProxyFactory_ = SafeProxyFactory(safeProxyFactory); - - safeSingleton.code.length == 0 ? safeSingleton_ = new Safe() : safeSingleton_ = Safe(payable(safeSingleton)); + /// @notice Initialize all of the implementations + function initializeImplementations() public { + console.log("Initializing implementations"); + initializeSystemConfig(); + initializeL1StandardBridge(); + initializeL1ERC721Bridge(); + initializeOptimismMintableERC20Factory(); + initializeL1CrossDomainMessenger(); + initializeL2OutputOracle(); + initializeDisputeGameFactory(); + initializeDelayedWETH(); + initializeAnchorStateRegistry(); + + // Selectively initialize either the original OptimismPortal or the new OptimismPortal2. Since this will upgrade + // the proxy, we cannot initialize both. FPAC warning can be removed once we're done with the old OptimismPortal + // contract. + if (cfg.useFaultProofs()) { + console.log("WARNING: FPAC is enabled. Initializing the OptimismPortal proxy with the OptimismPortal2."); + initializeOptimismPortal2(); + } else { + initializeOptimismPortal(); + } + } - save("SafeProxyFactory", address(safeProxyFactory_)); - save("SafeSingleton", address(safeSingleton_)); + /// @notice Add Plasma setup to the OP chain + function setupOpPlasma() public { + console.log("Deploying OP Plasma"); + deployDataAvailabilityChallengeProxy(); + deployDataAvailabilityChallenge(); + initializeDataAvailabilityChallenge(); } + //////////////////////////////////////////////////////////////// + // Non-Proxied Deployment Functions // + //////////////////////////////////////////////////////////////// + /// @notice Deploy the Safe function deploySafe() public broadcast returns (address addr_) { + console.log("Deploying Safe"); (SafeProxyFactory safeProxyFactory, Safe safeSingleton) = _getSafeFactory(); address[] memory signers = new address[](1); @@ -198,6 +430,7 @@ contract Deploy is Deployer { /// @notice Deploy the AddressManager function deployAddressManager() public broadcast returns (address addr_) { + console.log("Deploying AddressManager"); AddressManager manager = new AddressManager(); require(manager.owner() == msg.sender); @@ -208,9 +441,8 @@ contract Deploy is Deployer { /// @notice Deploy the ProxyAdmin function deployProxyAdmin() public broadcast returns (address addr_) { - ProxyAdmin admin = new ProxyAdmin({ - _owner: msg.sender - }); + console.log("Deploying ProxyAdmin"); + ProxyAdmin admin = new ProxyAdmin({ _owner: msg.sender }); require(admin.owner() == msg.sender); AddressManager addressManager = AddressManager(mustGetAddress("AddressManager")); @@ -225,250 +457,271 @@ contract Deploy is Deployer { addr_ = address(admin); } - /// @notice Deploy the L1StandardBridgeProxy + /// @notice Deploy the StorageSetter contract, used for upgrades. + function deployStorageSetter() public broadcast returns (address addr_) { + console.log("Deploying StorageSetter"); + StorageSetter setter = new StorageSetter{ salt: _implSalt() }(); + console.log("StorageSetter deployed at: %s", address(setter)); + string memory version = setter.version(); + console.log("StorageSetter version: %s", version); + addr_ = address(setter); + } + + //////////////////////////////////////////////////////////////// + // Proxy Deployment Functions // + //////////////////////////////////////////////////////////////// + + /// @notice Deploy the L1StandardBridgeProxy using a ChugSplashProxy function deployL1StandardBridgeProxy() public broadcast returns (address addr_) { + console.log("Deploying proxy for L1StandardBridge"); address proxyAdmin = mustGetAddress("ProxyAdmin"); L1ChugSplashProxy proxy = new L1ChugSplashProxy(proxyAdmin); - address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY)))); - require(admin == proxyAdmin); + require(EIP1967Helper.getAdmin(address(proxy)) == proxyAdmin); save("L1StandardBridgeProxy", address(proxy)); console.log("L1StandardBridgeProxy deployed at %s", address(proxy)); addr_ = address(proxy); } - /// @notice Deploy the L2OutputOracleProxy - function deployL2OutputOracleProxy() public broadcast returns (address addr_) { - address proxyAdmin = mustGetAddress("ProxyAdmin"); - Proxy proxy = new Proxy({ - _admin: proxyAdmin - }); - - address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY)))); - require(admin == proxyAdmin); - - save("L2OutputOracleProxy", address(proxy)); - console.log("L2OutputOracleProxy deployed at %s", address(proxy)); - addr_ = address(proxy); - } - - /// @notice Deploy the L1CrossDomainMessengerProxy + /// @notice Deploy the L1CrossDomainMessengerProxy using a ResolvedDelegateProxy function deployL1CrossDomainMessengerProxy() public broadcast returns (address addr_) { + console.log("Deploying proxy for L1CrossDomainMessenger"); AddressManager addressManager = AddressManager(mustGetAddress("AddressManager")); - string memory contractName = "OVM_L1CrossDomainMessenger"; - ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(addressManager, contractName); + ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(addressManager, "OVM_L1CrossDomainMessenger"); save("L1CrossDomainMessengerProxy", address(proxy)); console.log("L1CrossDomainMessengerProxy deployed at %s", address(proxy)); - address contractAddr = addressManager.getAddress(contractName); - if (contractAddr != address(proxy)) { - addressManager.setAddress(contractName, address(proxy)); - } - - require(addressManager.getAddress(contractName) == address(proxy)); - addr_ = address(proxy); } - /// @notice Deploy the OptimismPortalProxy - function deployOptimismPortalProxy() public broadcast returns (address addr_) { - address proxyAdmin = mustGetAddress("ProxyAdmin"); - Proxy proxy = new Proxy({ - _admin: proxyAdmin - }); - - address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY)))); - require(admin == proxyAdmin); - - save("OptimismPortalProxy", address(proxy)); - console.log("OptimismPortalProxy deployed at %s", address(proxy)); - - addr_ = address(proxy); + /// @notice Deploys an ERC1967Proxy contract with the ProxyAdmin as the owner. + /// @param _name The name of the proxy contract to be deployed. + /// @return addr_ The address of the deployed proxy contract. + function deployERC1967Proxy(string memory _name) public returns (address addr_) { + addr_ = deployERC1967ProxyWithOwner(_name, mustGetAddress("ProxyAdmin")); } - /// @notice Deploy the OptimismMintableERC20FactoryProxy - function deployOptimismMintableERC20FactoryProxy() public broadcast returns (address addr_) { - address proxyAdmin = mustGetAddress("ProxyAdmin"); - Proxy proxy = new Proxy({ - _admin: proxyAdmin - }); - - address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY)))); - require(admin == proxyAdmin); - - save("OptimismMintableERC20FactoryProxy", address(proxy)); - console.log("OptimismMintableERC20FactoryProxy deployed at %s", address(proxy)); - - addr_ = address(proxy); - } - - /// @notice Deploy the L1ERC721BridgeProxy - function deployL1ERC721BridgeProxy() public broadcast returns (address addr_) { - address proxyAdmin = mustGetAddress("ProxyAdmin"); - Proxy proxy = new Proxy({ - _admin: proxyAdmin - }); - - address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY)))); - require(admin == proxyAdmin); - - save("L1ERC721BridgeProxy", address(proxy)); - console.log("L1ERC721BridgeProxy deployed at %s", address(proxy)); - - addr_ = address(proxy); - } - - /// @notice Deploy the SystemConfigProxy - function deploySystemConfigProxy() public broadcast returns (address addr_) { - address proxyAdmin = mustGetAddress("ProxyAdmin"); - Proxy proxy = new Proxy({ - _admin: proxyAdmin - }); - - address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY)))); - require(admin == proxyAdmin); + /// @notice Deploys an ERC1967Proxy contract with a specified owner. + /// @param _name The name of the proxy contract to be deployed. + /// @param _proxyOwner The address of the owner of the proxy contract. + /// @return addr_ The address of the deployed proxy contract. + function deployERC1967ProxyWithOwner( + string memory _name, + address _proxyOwner + ) + public + broadcast + returns (address addr_) + { + console.log(string.concat("Deploying ERC1967 proxy for ", _name)); + Proxy proxy = new Proxy({ _admin: _proxyOwner }); - save("SystemConfigProxy", address(proxy)); - console.log("SystemConfigProxy deployed at %s", address(proxy)); + require(EIP1967Helper.getAdmin(address(proxy)) == _proxyOwner); + save(_name, address(proxy)); + console.log(" at %s", address(proxy)); addr_ = address(proxy); } - /// @notice Deploy the DisputeGameFactoryProxy - function deployDisputeGameFactoryProxy() public onlyDevnet broadcast returns (address addr_) { + /// @notice Deploy the DataAvailabilityChallengeProxy + function deployDataAvailabilityChallengeProxy() public broadcast returns (address addr_) { + console.log("Deploying proxy for DataAvailabilityChallenge"); address proxyAdmin = mustGetAddress("ProxyAdmin"); - Proxy proxy = new Proxy({ - _admin: proxyAdmin - }); + Proxy proxy = new Proxy({ _admin: proxyAdmin }); - address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY)))); - require(admin == proxyAdmin); + require(EIP1967Helper.getAdmin(address(proxy)) == proxyAdmin); - save("DisputeGameFactoryProxy", address(proxy)); - console.log("DisputeGameFactoryProxy deployed at %s", address(proxy)); + save("DataAvailabilityChallengeProxy", address(proxy)); + console.log("DataAvailabilityChallengeProxy deployed at %s", address(proxy)); addr_ = address(proxy); } - /// @notice Deploy the ProtocolVersionsProxy - function deployProtocolVersionsProxy() public broadcast returns (address addr_) { - address proxyAdmin = mustGetAddress("ProxyAdmin"); - Proxy proxy = new Proxy({ - _admin: proxyAdmin - }); + //////////////////////////////////////////////////////////////// + // Implementation Deployment Functions // + //////////////////////////////////////////////////////////////// - address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY)))); - require(admin == proxyAdmin); + /// @notice Deploy the SuperchainConfig contract + function deploySuperchainConfig() public broadcast { + SuperchainConfig superchainConfig = new SuperchainConfig{ salt: _implSalt() }(); - save("ProtocolVersionsProxy", address(proxy)); - console.log("ProtocolVersionsProxy deployed at %s", address(proxy)); + require(superchainConfig.guardian() == address(0)); + bytes32 initialized = vm.load(address(superchainConfig), bytes32(0)); + require(initialized != 0); - addr_ = address(proxy); + save("SuperchainConfig", address(superchainConfig)); + console.log("SuperchainConfig deployed at %s", address(superchainConfig)); } /// @notice Deploy the L1CrossDomainMessenger function deployL1CrossDomainMessenger() public broadcast returns (address addr_) { - L1CrossDomainMessenger messenger = new L1CrossDomainMessenger{ salt: implSalt() }(); - - require(address(messenger.PORTAL()) == address(0)); - require(address(messenger.portal()) == address(0)); - - bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204))); - require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER); + console.log("Deploying L1CrossDomainMessenger implementation"); + L1CrossDomainMessenger messenger = new L1CrossDomainMessenger{ salt: _implSalt() }(); save("L1CrossDomainMessenger", address(messenger)); console.log("L1CrossDomainMessenger deployed at %s", address(messenger)); + // Override the `L1CrossDomainMessenger` contract to the deployed implementation. This is necessary + // to check the `L1CrossDomainMessenger` implementation alongside dependent contracts, which + // are always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.L1CrossDomainMessenger = address(messenger); + ChainAssertions.checkL1CrossDomainMessenger({ _contracts: contracts, _vm: vm, _isProxy: false }); + addr_ = address(messenger); } /// @notice Deploy the OptimismPortal function deployOptimismPortal() public broadcast returns (address addr_) { - OptimismPortal portal = new OptimismPortal{ salt: implSalt() }(); + console.log("Deploying OptimismPortal implementation"); - require(address(portal.L2_ORACLE()) == address(0)); - require(portal.GUARDIAN() == address(0)); - require(address(portal.SYSTEM_CONFIG()) == address(0)); - require(portal.paused() == true); + OptimismPortal portal = new OptimismPortal{ salt: _implSalt() }(); save("OptimismPortal", address(portal)); console.log("OptimismPortal deployed at %s", address(portal)); + // Override the `OptimismPortal` contract to the deployed implementation. This is necessary + // to check the `OptimismPortal` implementation alongside dependent contracts, which + // are always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.OptimismPortal = address(portal); + ChainAssertions.checkOptimismPortal({ _contracts: contracts, _cfg: cfg, _isProxy: false }); + addr_ = address(portal); } - /// @notice Deploy the L2OutputOracle - function deployL2OutputOracle() public broadcast returns (address addr_) { - L2OutputOracle oracle = new L2OutputOracle{ salt: implSalt() }({ - _submissionInterval: cfg.l2OutputOracleSubmissionInterval(), - _l2BlockTime: cfg.l2BlockTime(), - _finalizationPeriodSeconds: cfg.finalizationPeriodSeconds() + /// @notice Deploy the OptimismPortal2 + function deployOptimismPortal2() public broadcast returns (address addr_) { + console.log("Deploying OptimismPortal2 implementation"); + + // Could also verify this inside DeployConfig but doing it here is a bit more reliable. + require( + uint32(cfg.respectedGameType()) == cfg.respectedGameType(), "Deploy: respectedGameType must fit into uint32" + ); + + OptimismPortal2 portal = new OptimismPortal2{ salt: _implSalt() }({ + _proofMaturityDelaySeconds: cfg.proofMaturityDelaySeconds(), + _disputeGameFinalityDelaySeconds: cfg.disputeGameFinalityDelaySeconds(), + _initialRespectedGameType: GameType.wrap(uint32(cfg.respectedGameType())) }); - require(oracle.SUBMISSION_INTERVAL() == cfg.l2OutputOracleSubmissionInterval()); - require(oracle.submissionInterval() == cfg.l2OutputOracleSubmissionInterval()); - require(oracle.L2_BLOCK_TIME() == cfg.l2BlockTime()); - require(oracle.l2BlockTime() == cfg.l2BlockTime()); - require(oracle.PROPOSER() == address(0)); - require(oracle.proposer() == address(0)); - require(oracle.CHALLENGER() == address(0)); - require(oracle.challenger() == address(0)); - require(oracle.FINALIZATION_PERIOD_SECONDS() == cfg.finalizationPeriodSeconds()); - require(oracle.finalizationPeriodSeconds() == cfg.finalizationPeriodSeconds()); - require(oracle.startingBlockNumber() == 0); - require(oracle.startingTimestamp() == 0); + save("OptimismPortal2", address(portal)); + console.log("OptimismPortal2 deployed at %s", address(portal)); + + // Override the `OptimismPortal2` contract to the deployed implementation. This is necessary + // to check the `OptimismPortal2` implementation alongside dependent contracts, which + // are always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.OptimismPortal2 = address(portal); + ChainAssertions.checkOptimismPortal2({ _contracts: contracts, _cfg: cfg, _isProxy: false }); + + addr_ = address(portal); + } + + /// @notice Deploy the L2OutputOracle + function deployL2OutputOracle() public broadcast returns (address addr_) { + console.log("Deploying L2OutputOracle implementation"); + L2OutputOracle oracle = new L2OutputOracle{ salt: _implSalt() }(); save("L2OutputOracle", address(oracle)); console.log("L2OutputOracle deployed at %s", address(oracle)); + // Override the `L2OutputOracle` contract to the deployed implementation. This is necessary + // to check the `L2OutputOracle` implementation alongside dependent contracts, which + // are always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.L2OutputOracle = address(oracle); + ChainAssertions.checkL2OutputOracle({ + _contracts: contracts, + _cfg: cfg, + _l2OutputOracleStartingTimestamp: 0, + _isProxy: false + }); + addr_ = address(oracle); } /// @notice Deploy the OptimismMintableERC20Factory function deployOptimismMintableERC20Factory() public broadcast returns (address addr_) { - OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory{ salt: implSalt() }(); - - require(factory.BRIDGE() == address(0)); - require(factory.bridge() == address(0)); + console.log("Deploying OptimismMintableERC20Factory implementation"); + OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory{ salt: _implSalt() }(); save("OptimismMintableERC20Factory", address(factory)); console.log("OptimismMintableERC20Factory deployed at %s", address(factory)); + // Override the `OptimismMintableERC20Factory` contract to the deployed implementation. This is necessary + // to check the `OptimismMintableERC20Factory` implementation alongside dependent contracts, which + // are always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.OptimismMintableERC20Factory = address(factory); + ChainAssertions.checkOptimismMintableERC20Factory({ _contracts: contracts, _isProxy: false }); + addr_ = address(factory); } /// @notice Deploy the DisputeGameFactory - function deployDisputeGameFactory() public onlyDevnet broadcast returns (address addr_) { - DisputeGameFactory factory = new DisputeGameFactory{ salt: implSalt() }(); + function deployDisputeGameFactory() public broadcast returns (address addr_) { + console.log("Deploying DisputeGameFactory implementation"); + DisputeGameFactory factory = new DisputeGameFactory{ salt: _implSalt() }(); save("DisputeGameFactory", address(factory)); console.log("DisputeGameFactory deployed at %s", address(factory)); + // Override the `DisputeGameFactory` contract to the deployed implementation. This is necessary to check the + // `DisputeGameFactory` implementation alongside dependent contracts, which are always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.DisputeGameFactory = address(factory); + ChainAssertions.checkDisputeGameFactory({ _contracts: contracts, _expectedOwner: address(0) }); + addr_ = address(factory); } - /// @notice Deploy the BlockOracle - function deployBlockOracle() public onlyDevnet broadcast returns (address addr_) { - BlockOracle oracle = new BlockOracle{ salt: implSalt() }(); - save("BlockOracle", address(oracle)); - console.log("BlockOracle deployed at %s", address(oracle)); + function deployDelayedWETH() public broadcast returns (address addr_) { + console.log("Deploying DelayedWETH implementation"); + DelayedWETH weth = new DelayedWETH{ salt: _implSalt() }(cfg.faultGameWithdrawalDelay()); + save("DelayedWETH", address(weth)); + console.log("DelayedWETH deployed at %s", address(weth)); + + // Override the `DelayedWETH` contract to the deployed implementation. This is necessary + // to check the `DelayedWETH` implementation alongside dependent contracts, which are + // always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.DelayedWETH = address(weth); + ChainAssertions.checkDelayedWETH({ + _contracts: contracts, + _cfg: cfg, + _isProxy: false, + _expectedOwner: address(0) + }); - addr_ = address(oracle); + addr_ = address(weth); } /// @notice Deploy the ProtocolVersions function deployProtocolVersions() public broadcast returns (address addr_) { - ProtocolVersions versions = new ProtocolVersions{ salt: implSalt() }(); + console.log("Deploying ProtocolVersions implementation"); + ProtocolVersions versions = new ProtocolVersions{ salt: _implSalt() }(); save("ProtocolVersions", address(versions)); console.log("ProtocolVersions deployed at %s", address(versions)); + // Override the `ProtocolVersions` contract to the deployed implementation. This is necessary + // to check the `ProtocolVersions` implementation alongside dependent contracts, which + // are always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.ProtocolVersions = address(versions); + ChainAssertions.checkProtocolVersions({ _contracts: contracts, _cfg: cfg, _isProxy: false }); + addr_ = address(versions); } /// @notice Deploy the PreimageOracle - function deployPreimageOracle() public onlyDevnet broadcast returns (address addr_) { - PreimageOracle preimageOracle = new PreimageOracle{ salt: implSalt() }(); + function deployPreimageOracle() public broadcast returns (address addr_) { + console.log("Deploying PreimageOracle implementation"); + PreimageOracle preimageOracle = new PreimageOracle{ salt: _implSalt() }({ + _minProposalSize: cfg.preimageOracleMinProposalSize(), + _challengePeriod: cfg.preimageOracleChallengePeriod() + }); save("PreimageOracle", address(preimageOracle)); console.log("PreimageOracle deployed at %s", address(preimageOracle)); @@ -476,77 +729,85 @@ contract Deploy is Deployer { } /// @notice Deploy Mips - function deployMips() public onlyDevnet broadcast returns (address addr_) { - MIPS mips = new MIPS{ salt: implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle"))); + function deployMips() public broadcast returns (address addr_) { + console.log("Deploying Mips implementation"); + MIPS mips = new MIPS{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle"))); save("Mips", address(mips)); console.log("MIPS deployed at %s", address(mips)); addr_ = address(mips); } + /// @notice Deploy the AnchorStateRegistry + function deployAnchorStateRegistry() public broadcast returns (address addr_) { + console.log("Deploying AnchorStateRegistry implementation"); + AnchorStateRegistry anchorStateRegistry = + new AnchorStateRegistry{ salt: _implSalt() }(DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"))); + save("AnchorStateRegistry", address(anchorStateRegistry)); + console.log("AnchorStateRegistry deployed at %s", address(anchorStateRegistry)); + + addr_ = address(anchorStateRegistry); + } + /// @notice Deploy the SystemConfig function deploySystemConfig() public broadcast returns (address addr_) { - SystemConfig config = new SystemConfig{ salt: implSalt() }(); - - require(config.owner() == address(0xdEaD)); - require(config.overhead() == 0); - require(config.scalar() == 0); - require(config.unsafeBlockSigner() == address(0)); - require(config.batcherHash() == bytes32(0)); - require(config.gasLimit() == 1); - - ResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig(); - require(resourceConfig.maxResourceLimit == 1); - require(resourceConfig.elasticityMultiplier == 1); - require(resourceConfig.baseFeeMaxChangeDenominator == 2); - require(resourceConfig.systemTxMaxGas == 0); - require(resourceConfig.minimumBaseFee == 0); - require(resourceConfig.maximumBaseFee == 0); - - require(config.l1ERC721Bridge() == address(0)); - require(config.l1StandardBridge() == address(0)); - require(config.l2OutputOracle() == address(0)); - require(config.optimismPortal() == address(0)); - require(config.l1CrossDomainMessenger() == address(0)); - require(config.optimismMintableERC20Factory() == address(0)); - require(config.startBlock() == type(uint256).max); + console.log("Deploying SystemConfig implementation"); + SystemConfig config = new SystemConfig{ salt: _implSalt() }(); save("SystemConfig", address(config)); console.log("SystemConfig deployed at %s", address(config)); + // Override the `SystemConfig` contract to the deployed implementation. This is necessary + // to check the `SystemConfig` implementation alongside dependent contracts, which + // are always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.SystemConfig = address(config); + ChainAssertions.checkSystemConfig({ _contracts: contracts, _cfg: cfg, _isProxy: false }); + addr_ = address(config); } /// @notice Deploy the L1StandardBridge function deployL1StandardBridge() public broadcast returns (address addr_) { - L1StandardBridge bridge = new L1StandardBridge{ salt: implSalt() }(); + console.log("Deploying L1StandardBridge implementation"); - require(address(bridge.MESSENGER()) == address(0)); - require(address(bridge.messenger()) == address(0)); - require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE); - require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE); + L1StandardBridge bridge = new L1StandardBridge{ salt: _implSalt() }(); save("L1StandardBridge", address(bridge)); console.log("L1StandardBridge deployed at %s", address(bridge)); + // Override the `L1StandardBridge` contract to the deployed implementation. This is necessary + // to check the `L1StandardBridge` implementation alongside dependent contracts, which + // are always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.L1StandardBridge = address(bridge); + ChainAssertions.checkL1StandardBridge({ _contracts: contracts, _isProxy: false }); + addr_ = address(bridge); } /// @notice Deploy the L1ERC721Bridge function deployL1ERC721Bridge() public broadcast returns (address addr_) { - L1ERC721Bridge bridge = new L1ERC721Bridge{ salt: implSalt() }(); - - require(address(bridge.MESSENGER()) == address(0)); - require(bridge.OTHER_BRIDGE() == Predeploys.L2_ERC721_BRIDGE); + console.log("Deploying L1ERC721Bridge implementation"); + L1ERC721Bridge bridge = new L1ERC721Bridge{ salt: _implSalt() }(); save("L1ERC721Bridge", address(bridge)); console.log("L1ERC721Bridge deployed at %s", address(bridge)); + // Override the `L1ERC721Bridge` contract to the deployed implementation. This is necessary + // to check the `L1ERC721Bridge` implementation alongside dependent contracts, which + // are always proxies. + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.L1ERC721Bridge = address(bridge); + + ChainAssertions.checkL1ERC721Bridge({ _contracts: contracts, _isProxy: false }); + addr_ = address(bridge); } /// @notice Transfer ownership of the address manager to the ProxyAdmin function transferAddressManagerOwnership() public broadcast { + console.log("Transferring AddressManager ownership to ProxyAdmin"); AddressManager addressManager = AddressManager(mustGetAddress("AddressManager")); address owner = addressManager.owner(); address proxyAdmin = mustGetAddress("ProxyAdmin"); @@ -558,39 +819,36 @@ contract Deploy is Deployer { require(addressManager.owner() == proxyAdmin); } - /// @notice Make a call from the Safe contract to an arbitrary address with arbitrary data - function _callViaSafe(address _target, bytes memory _data) internal { - Safe safe = Safe(mustGetAddress("SystemOwnerSafe")); - - // This is the signature format used the caller is also the signer. - bytes memory signature = abi.encodePacked(uint256(uint160(msg.sender)), bytes32(0), uint8(1)); + /// @notice Deploy the DataAvailabilityChallenge + function deployDataAvailabilityChallenge() public broadcast returns (address addr_) { + console.log("Deploying DataAvailabilityChallenge implementation"); + DataAvailabilityChallenge dac = new DataAvailabilityChallenge(); + save("DataAvailabilityChallenge", address(dac)); + console.log("DataAvailabilityChallenge deployed at %s", address(dac)); - safe.execTransaction({ - to: _target, - value: 0, - data: _data, - operation: SafeOps.Operation.Call, - safeTxGas: 0, - baseGas: 0, - gasPrice: 0, - gasToken: address(0), - refundReceiver: payable(address(0)), - signatures: signature - }); + addr_ = address(dac); } - /// @notice Call from the Safe contract to the Proxy Admin's upgrade and call method - function _upgradeAndCallViaSafe(address _proxy, address _implementation, bytes memory _innerCallData) internal { - address proxyAdmin = mustGetAddress("ProxyAdmin"); + //////////////////////////////////////////////////////////////// + // Initialize Functions // + //////////////////////////////////////////////////////////////// - bytes memory data = - abi.encodeCall(ProxyAdmin.upgradeAndCall, (payable(_proxy), _implementation, _innerCallData)); + /// @notice Initialize the SuperchainConfig + function initializeSuperchainConfig() public broadcast { + address payable superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); + address payable superchainConfig = mustGetAddress("SuperchainConfig"); + _upgradeAndCallViaSafe({ + _proxy: superchainConfigProxy, + _implementation: superchainConfig, + _innerCallData: abi.encodeCall(SuperchainConfig.initialize, (cfg.superchainConfigGuardian(), false)) + }); - _callViaSafe({ _target: proxyAdmin, _data: data }); + ChainAssertions.checkSuperchainConfig({ _contracts: _proxiesUnstrict(), _cfg: cfg, _isPaused: false }); } /// @notice Initialize the DisputeGameFactory - function initializeDisputeGameFactory() public onlyDevnet broadcast { + function initializeDisputeGameFactory() public broadcast { + console.log("Upgrading and initializing DisputeGameFactory proxy"); address disputeGameFactoryProxy = mustGetAddress("DisputeGameFactoryProxy"); address disputeGameFactory = mustGetAddress("DisputeGameFactory"); @@ -602,15 +860,78 @@ contract Deploy is Deployer { string memory version = DisputeGameFactory(disputeGameFactoryProxy).version(); console.log("DisputeGameFactory version: %s", version); + + ChainAssertions.checkDisputeGameFactory({ _contracts: _proxiesUnstrict(), _expectedOwner: msg.sender }); + } + + function initializeDelayedWETH() public broadcast { + console.log("Upgrading and initializing DelayedWETH proxy"); + address delayedWETHProxy = mustGetAddress("DelayedWETHProxy"); + address delayedWETH = mustGetAddress("DelayedWETH"); + address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); + + _upgradeAndCallViaSafe({ + _proxy: payable(delayedWETHProxy), + _implementation: delayedWETH, + _innerCallData: abi.encodeCall(DelayedWETH.initialize, (msg.sender, SuperchainConfig(superchainConfigProxy))) + }); + + string memory version = DelayedWETH(payable(delayedWETHProxy)).version(); + console.log("DelayedWETH version: %s", version); + + ChainAssertions.checkDelayedWETH({ + _contracts: _proxiesUnstrict(), + _cfg: cfg, + _isProxy: true, + _expectedOwner: msg.sender + }); + } + + function initializeAnchorStateRegistry() public broadcast { + console.log("Upgrading and initializing AnchorStateRegistry proxy"); + address anchorStateRegistryProxy = mustGetAddress("AnchorStateRegistryProxy"); + address anchorStateRegistry = mustGetAddress("AnchorStateRegistry"); + + AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](3); + roots[0] = AnchorStateRegistry.StartingAnchorRoot({ + gameType: GameTypes.CANNON, + outputRoot: OutputRoot({ + root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), + l2BlockNumber: cfg.faultGameGenesisBlock() + }) + }); + roots[1] = AnchorStateRegistry.StartingAnchorRoot({ + gameType: GameTypes.PERMISSIONED_CANNON, + outputRoot: OutputRoot({ + root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), + l2BlockNumber: cfg.faultGameGenesisBlock() + }) + }); + roots[2] = AnchorStateRegistry.StartingAnchorRoot({ + gameType: GameTypes.ALPHABET, + outputRoot: OutputRoot({ + root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), + l2BlockNumber: cfg.faultGameGenesisBlock() + }) + }); + + _upgradeAndCallViaSafe({ + _proxy: payable(anchorStateRegistryProxy), + _implementation: anchorStateRegistry, + _innerCallData: abi.encodeCall(AnchorStateRegistry.initialize, (roots)) + }); + + string memory version = AnchorStateRegistry(payable(anchorStateRegistryProxy)).version(); + console.log("AnchorStateRegistry version: %s", version); } /// @notice Initialize the SystemConfig function initializeSystemConfig() public broadcast { + console.log("Upgrading and initializing SystemConfig proxy"); address systemConfigProxy = mustGetAddress("SystemConfigProxy"); address systemConfig = mustGetAddress("SystemConfig"); bytes32 batcherHash = bytes32(uint256(uint160(cfg.batchSenderAddress()))); - uint256 startBlock = cfg.systemConfigStartBlock(); _upgradeAndCallViaSafe({ _proxy: payable(systemConfigProxy), @@ -625,7 +946,6 @@ contract Deploy is Deployer { uint64(cfg.l2GenesisBlockGasLimit()), cfg.p2pSequencerAddress(), Constants.DEFAULT_RESOURCE_CONFIG(), - startBlock, cfg.batchInboxAddress(), SystemConfig.Addresses({ l1CrossDomainMessenger: mustGetAddress("L1CrossDomainMessengerProxy"), @@ -643,41 +963,17 @@ contract Deploy is Deployer { string memory version = config.version(); console.log("SystemConfig version: %s", version); - require(config.owner() == cfg.finalSystemOwner()); - require(config.overhead() == cfg.gasPriceOracleOverhead()); - require(config.scalar() == cfg.gasPriceOracleScalar()); - require(config.unsafeBlockSigner() == cfg.p2pSequencerAddress()); - require(config.batcherHash() == batcherHash); - - ResourceMetering.ResourceConfig memory rconfig = Constants.DEFAULT_RESOURCE_CONFIG(); - ResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig(); - require(resourceConfig.maxResourceLimit == rconfig.maxResourceLimit); - require(resourceConfig.elasticityMultiplier == rconfig.elasticityMultiplier); - require(resourceConfig.baseFeeMaxChangeDenominator == rconfig.baseFeeMaxChangeDenominator); - require(resourceConfig.systemTxMaxGas == rconfig.systemTxMaxGas); - require(resourceConfig.minimumBaseFee == rconfig.minimumBaseFee); - require(resourceConfig.maximumBaseFee == rconfig.maximumBaseFee); - - require(config.l1ERC721Bridge() == mustGetAddress("L1ERC721BridgeProxy")); - require(config.l1StandardBridge() == mustGetAddress("L1StandardBridgeProxy")); - require(config.l2OutputOracle() == mustGetAddress("L2OutputOracleProxy")); - require(config.optimismPortal() == mustGetAddress("OptimismPortalProxy")); - require(config.l1CrossDomainMessenger() == mustGetAddress("L1CrossDomainMessengerProxy")); - - // A non zero start block is an override - if (startBlock != 0) { - require(config.startBlock() == startBlock); - } else { - require(config.startBlock() == block.number); - } + ChainAssertions.checkSystemConfig({ _contracts: _proxies(), _cfg: cfg, _isProxy: true }); } /// @notice Initialize the L1StandardBridge function initializeL1StandardBridge() public broadcast { + console.log("Upgrading and initializing L1StandardBridge proxy"); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy"); address l1StandardBridge = mustGetAddress("L1StandardBridge"); address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy"); + address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); uint256 proxyType = uint256(proxyAdmin.proxyType(l1StandardBridgeProxy)); if (proxyType != uint256(ProxyAdmin.ProxyType.CHUGSPLASH)) { @@ -692,42 +988,44 @@ contract Deploy is Deployer { _proxy: payable(l1StandardBridgeProxy), _implementation: l1StandardBridge, _innerCallData: abi.encodeCall( - L1StandardBridge.initialize, (L1CrossDomainMessenger(l1CrossDomainMessengerProxy)) + L1StandardBridge.initialize, + (L1CrossDomainMessenger(l1CrossDomainMessengerProxy), SuperchainConfig(superchainConfigProxy)) ) }); string memory version = L1StandardBridge(payable(l1StandardBridgeProxy)).version(); console.log("L1StandardBridge version: %s", version); - L1StandardBridge bridge = L1StandardBridge(payable(l1StandardBridgeProxy)); - require(address(bridge.MESSENGER()) == l1CrossDomainMessengerProxy); - require(address(bridge.messenger()) == l1CrossDomainMessengerProxy); - require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE); - require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE); + ChainAssertions.checkL1StandardBridge({ _contracts: _proxies(), _isProxy: true }); } /// @notice Initialize the L1ERC721Bridge function initializeL1ERC721Bridge() public broadcast { + console.log("Upgrading and initializing L1ERC721Bridge proxy"); address l1ERC721BridgeProxy = mustGetAddress("L1ERC721BridgeProxy"); address l1ERC721Bridge = mustGetAddress("L1ERC721Bridge"); address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy"); + address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); _upgradeAndCallViaSafe({ _proxy: payable(l1ERC721BridgeProxy), _implementation: l1ERC721Bridge, - _innerCallData: abi.encodeCall(L1ERC721Bridge.initialize, (L1CrossDomainMessenger(l1CrossDomainMessengerProxy))) + _innerCallData: abi.encodeCall( + L1ERC721Bridge.initialize, + (L1CrossDomainMessenger(payable(l1CrossDomainMessengerProxy)), SuperchainConfig(superchainConfigProxy)) + ) }); L1ERC721Bridge bridge = L1ERC721Bridge(l1ERC721BridgeProxy); string memory version = bridge.version(); console.log("L1ERC721Bridge version: %s", version); - require(address(bridge.MESSENGER()) == l1CrossDomainMessengerProxy); - require(bridge.OTHER_BRIDGE() == Predeploys.L2_ERC721_BRIDGE); + ChainAssertions.checkL1ERC721Bridge({ _contracts: _proxies(), _isProxy: true }); } /// @notice Ininitialize the OptimismMintableERC20Factory function initializeOptimismMintableERC20Factory() public broadcast { + console.log("Upgrading and initializing OptimismMintableERC20Factory proxy"); address optimismMintableERC20FactoryProxy = mustGetAddress("OptimismMintableERC20FactoryProxy"); address optimismMintableERC20Factory = mustGetAddress("OptimismMintableERC20Factory"); address l1StandardBridgeProxy = mustGetAddress("L1StandardBridgeProxy"); @@ -742,15 +1040,16 @@ contract Deploy is Deployer { string memory version = factory.version(); console.log("OptimismMintableERC20Factory version: %s", version); - require(factory.BRIDGE() == l1StandardBridgeProxy); - require(factory.bridge() == l1StandardBridgeProxy); + ChainAssertions.checkOptimismMintableERC20Factory({ _contracts: _proxies(), _isProxy: true }); } /// @notice initializeL1CrossDomainMessenger function initializeL1CrossDomainMessenger() public broadcast { + console.log("Upgrading and initializing L1CrossDomainMessenger proxy"); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy"); address l1CrossDomainMessenger = mustGetAddress("L1CrossDomainMessenger"); + address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); address optimismPortalProxy = mustGetAddress("OptimismPortalProxy"); uint256 proxyType = uint256(proxyAdmin.proxyType(l1CrossDomainMessengerProxy)); @@ -779,7 +1078,8 @@ contract Deploy is Deployer { _proxy: payable(l1CrossDomainMessengerProxy), _implementation: l1CrossDomainMessenger, _innerCallData: abi.encodeCall( - L1CrossDomainMessenger.initialize, (OptimismPortal(payable(optimismPortalProxy))) + L1CrossDomainMessenger.initialize, + (SuperchainConfig(superchainConfigProxy), OptimismPortal(payable(optimismPortalProxy))) ) }); @@ -787,14 +1087,12 @@ contract Deploy is Deployer { string memory version = messenger.version(); console.log("L1CrossDomainMessenger version: %s", version); - require(address(messenger.PORTAL()) == optimismPortalProxy); - require(address(messenger.portal()) == optimismPortalProxy); - bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204))); - require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER); + ChainAssertions.checkL1CrossDomainMessenger({ _contracts: _proxies(), _vm: vm, _isProxy: true }); } /// @notice Initialize the L2OutputOracle function initializeL2OutputOracle() public broadcast { + console.log("Upgrading and initializing L2OutputOracle proxy"); address l2OutputOracleProxy = mustGetAddress("L2OutputOracleProxy"); address l2OutputOracle = mustGetAddress("L2OutputOracle"); @@ -804,10 +1102,13 @@ contract Deploy is Deployer { _innerCallData: abi.encodeCall( L2OutputOracle.initialize, ( + cfg.l2OutputOracleSubmissionInterval(), + cfg.l2BlockTime(), cfg.l2OutputOracleStartingBlockNumber(), cfg.l2OutputOracleStartingTimestamp(), cfg.l2OutputOracleProposer(), - cfg.l2OutputOracleChallenger() + cfg.l2OutputOracleChallenger(), + cfg.finalizationPeriodSeconds() ) ) }); @@ -816,38 +1117,33 @@ contract Deploy is Deployer { string memory version = oracle.version(); console.log("L2OutputOracle version: %s", version); - require(oracle.SUBMISSION_INTERVAL() == cfg.l2OutputOracleSubmissionInterval()); - require(oracle.submissionInterval() == cfg.l2OutputOracleSubmissionInterval()); - require(oracle.L2_BLOCK_TIME() == cfg.l2BlockTime()); - require(oracle.l2BlockTime() == cfg.l2BlockTime()); - require(oracle.PROPOSER() == cfg.l2OutputOracleProposer()); - require(oracle.proposer() == cfg.l2OutputOracleProposer()); - require(oracle.CHALLENGER() == cfg.l2OutputOracleChallenger()); - require(oracle.challenger() == cfg.l2OutputOracleChallenger()); - require(oracle.FINALIZATION_PERIOD_SECONDS() == cfg.finalizationPeriodSeconds()); - require(oracle.finalizationPeriodSeconds() == cfg.finalizationPeriodSeconds()); - require(oracle.startingBlockNumber() == cfg.l2OutputOracleStartingBlockNumber()); - require(oracle.startingTimestamp() == cfg.l2OutputOracleStartingTimestamp()); + ChainAssertions.checkL2OutputOracle({ + _contracts: _proxies(), + _cfg: cfg, + _l2OutputOracleStartingTimestamp: cfg.l2OutputOracleStartingTimestamp(), + _isProxy: true + }); } /// @notice Initialize the OptimismPortal function initializeOptimismPortal() public broadcast { + console.log("Upgrading and initializing OptimismPortal proxy"); address optimismPortalProxy = mustGetAddress("OptimismPortalProxy"); address optimismPortal = mustGetAddress("OptimismPortal"); address l2OutputOracleProxy = mustGetAddress("L2OutputOracleProxy"); address systemConfigProxy = mustGetAddress("SystemConfigProxy"); - - address guardian = cfg.portalGuardian(); - if (guardian.code.length == 0) { - console.log("Portal guardian has no code: %s", guardian); - } + address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); _upgradeAndCallViaSafe({ _proxy: payable(optimismPortalProxy), _implementation: optimismPortal, _innerCallData: abi.encodeCall( OptimismPortal.initialize, - (L2OutputOracle(l2OutputOracleProxy), guardian, SystemConfig(systemConfigProxy), false) + ( + L2OutputOracle(l2OutputOracleProxy), + SystemConfig(systemConfigProxy), + SuperchainConfig(superchainConfigProxy) + ) ) }); @@ -855,13 +1151,40 @@ contract Deploy is Deployer { string memory version = portal.version(); console.log("OptimismPortal version: %s", version); - require(address(portal.L2_ORACLE()) == l2OutputOracleProxy); - require(portal.GUARDIAN() == cfg.portalGuardian()); - require(address(portal.SYSTEM_CONFIG()) == systemConfigProxy); - require(portal.paused() == false); + ChainAssertions.checkOptimismPortal({ _contracts: _proxies(), _cfg: cfg, _isProxy: true }); + } + + /// @notice Initialize the OptimismPortal2 + function initializeOptimismPortal2() public broadcast { + console.log("Upgrading and initializing OptimismPortal2 proxy"); + address optimismPortalProxy = mustGetAddress("OptimismPortalProxy"); + address optimismPortal2 = mustGetAddress("OptimismPortal2"); + address disputeGameFactoryProxy = mustGetAddress("DisputeGameFactoryProxy"); + address systemConfigProxy = mustGetAddress("SystemConfigProxy"); + address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); + + _upgradeAndCallViaSafe({ + _proxy: payable(optimismPortalProxy), + _implementation: optimismPortal2, + _innerCallData: abi.encodeCall( + OptimismPortal2.initialize, + ( + DisputeGameFactory(disputeGameFactoryProxy), + SystemConfig(systemConfigProxy), + SuperchainConfig(superchainConfigProxy) + ) + ) + }); + + OptimismPortal2 portal = OptimismPortal2(payable(optimismPortalProxy)); + string memory version = portal.version(); + console.log("OptimismPortal2 version: %s", version); + + ChainAssertions.checkOptimismPortal2({ _contracts: _proxies(), _cfg: cfg, _isProxy: true }); } function initializeProtocolVersions() public broadcast { + console.log("Upgrading and initializing ProtocolVersions proxy"); address protocolVersionsProxy = mustGetAddress("ProtocolVersionsProxy"); address protocolVersions = mustGetAddress("ProtocolVersions"); @@ -886,24 +1209,12 @@ contract Deploy is Deployer { string memory version = versions.version(); console.log("ProtocolVersions version: %s", version); - require(versions.owner() == finalSystemOwner); - require(ProtocolVersion.unwrap(versions.required()) == requiredProtocolVersion); - require(ProtocolVersion.unwrap(versions.recommended()) == recommendedProtocolVersion); - } - - /// @notice Transfer ownership of the ProxyAdmin contract to the final system owner - function transferProxyAdminOwnership() public broadcast { - ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); - address owner = proxyAdmin.owner(); - address safe = mustGetAddress("SystemOwnerSafe"); - if (owner != safe) { - proxyAdmin.transferOwnership(safe); - console.log("ProxyAdmin ownership transferred to Safe at: %s", safe); - } + ChainAssertions.checkProtocolVersions({ _contracts: _proxiesUnstrict(), _cfg: cfg, _isProxy: true }); } /// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner - function transferDisputeGameFactoryOwnership() public onlyDevnet broadcast { + function transferDisputeGameFactoryOwnership() public broadcast { + console.log("Transferring DisputeGameFactory ownership to Safe"); DisputeGameFactory disputeGameFactory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); address owner = disputeGameFactory.owner(); @@ -912,13 +1223,26 @@ contract Deploy is Deployer { disputeGameFactory.transferOwnership(safe); console.log("DisputeGameFactory ownership transferred to Safe at: %s", safe); } + ChainAssertions.checkDisputeGameFactory({ _contracts: _proxies(), _expectedOwner: safe }); } - /// @notice Sets the implementation for the `FAULT` game type in the `DisputeGameFactory` - function setCannonFaultGameImplementation() public onlyDevnet broadcast { - DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + /// @notice Transfer ownership of the DelayedWETH contract to the final system owner + function transferDelayedWETHOwnership() public broadcast { + console.log("Transferring DelayedWETH ownership to Safe"); + DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); + address owner = weth.owner(); + + address safe = mustGetAddress("SystemOwnerSafe"); + if (owner != safe) { + weth.transferOwnership(safe); + console.log("DelayedWETH ownership transferred to Safe at: %s", safe); + } + ChainAssertions.checkDelayedWETH({ _contracts: _proxies(), _cfg: cfg, _isProxy: true, _expectedOwner: safe }); + } - Claim mipsAbsolutePrestate; + /// @notice Loads the mips absolute prestate from the prestate-proof for devnets otherwise + /// from the config. + function loadMipsAbsolutePrestate() internal returns (Claim mipsAbsolutePrestate_) { if (block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet) { // Fetch the absolute prestate dump string memory filePath = string.concat(vm.projectRoot(), "/../../op-program/bin/prestate-proof.json"); @@ -930,83 +1254,181 @@ contract Deploy is Deployer { revert("Cannon prestate dump not found, generate it with `make cannon-prestate` in the monorepo root."); } commands[2] = string.concat("cat ", filePath, " | jq -r .pre"); - mipsAbsolutePrestate = Claim.wrap(abi.decode(vm.ffi(commands), (bytes32))); + mipsAbsolutePrestate_ = Claim.wrap(abi.decode(vm.ffi(commands), (bytes32))); console.log( "[Cannon Dispute Game] Using devnet MIPS Absolute prestate: %s", - vm.toString(Claim.unwrap(mipsAbsolutePrestate)) + vm.toString(Claim.unwrap(mipsAbsolutePrestate_)) ); } else { console.log( - "[Cannon Dispute Game] Using absolute prestate from config: %s", cfg.faultGameAbsolutePrestate() + "[Cannon Dispute Game] Using absolute prestate from config: %x", cfg.faultGameAbsolutePrestate() ); - mipsAbsolutePrestate = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate())); + mipsAbsolutePrestate_ = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate())); } + } + + /// @notice Sets the implementation for the `CANNON` game type in the `DisputeGameFactory` + function setCannonFaultGameImplementation(bool _allowUpgrade) public broadcast { + console.log("Setting Cannon FaultDisputeGame implementation"); + DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); // Set the Cannon FaultDisputeGame implementation in the factory. - _setFaultGameImplementation( - factory, GameTypes.FAULT, mipsAbsolutePrestate, IBigStepper(mustGetAddress("Mips")), cfg.faultGameMaxDepth() - ); + _setFaultGameImplementation({ + _factory: factory, + _allowUpgrade: _allowUpgrade, + _params: FaultDisputeGameParams({ + anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), + weth: weth, + gameType: GameTypes.CANNON, + absolutePrestate: loadMipsAbsolutePrestate(), + faultVm: IBigStepper(mustGetAddress("Mips")), + maxGameDepth: cfg.faultGameMaxDepth() + }) + }); } - /// @notice Sets the implementation for the alphabet game type in the `DisputeGameFactory` - function setAlphabetFaultGameImplementation() public onlyDevnet broadcast { + /// @notice Sets the implementation for the `PERMISSIONED_CANNON` game type in the `DisputeGameFactory` + function setPermissionedCannonFaultGameImplementation(bool _allowUpgrade) public broadcast { + console.log("Setting Cannon PermissionedDisputeGame implementation"); DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); - // Set the Alphabet FaultDisputeGame implementation in the factory. - Claim alphabetAbsolutePrestate = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate())); - _setFaultGameImplementation( - factory, - GameType.wrap(255), - alphabetAbsolutePrestate, - IBigStepper(new AlphabetVM(alphabetAbsolutePrestate)), - 4 // The max game depth of the alphabet game is always 4. - ); + // Set the Cannon FaultDisputeGame implementation in the factory. + _setFaultGameImplementation({ + _factory: factory, + _allowUpgrade: _allowUpgrade, + _params: FaultDisputeGameParams({ + anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), + weth: weth, + gameType: GameTypes.PERMISSIONED_CANNON, + absolutePrestate: loadMipsAbsolutePrestate(), + faultVm: IBigStepper(mustGetAddress("Mips")), + maxGameDepth: cfg.faultGameMaxDepth() + }) + }); + } + + /// @notice Sets the implementation for the `ALPHABET` game type in the `DisputeGameFactory` + function setAlphabetFaultGameImplementation(bool _allowUpgrade) public onlyDevnet broadcast { + console.log("Setting Alphabet FaultDisputeGame implementation"); + DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); + + Claim outputAbsolutePrestate = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate())); + _setFaultGameImplementation({ + _factory: factory, + _allowUpgrade: _allowUpgrade, + _params: FaultDisputeGameParams({ + anchorStateRegistry: AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")), + weth: weth, + gameType: GameTypes.ALPHABET, + absolutePrestate: outputAbsolutePrestate, + faultVm: IBigStepper(new AlphabetVM(outputAbsolutePrestate, PreimageOracle(mustGetAddress("PreimageOracle")))), + // The max depth for the alphabet trace is always 3. Add 1 because split depth is fully inclusive. + maxGameDepth: cfg.faultGameSplitDepth() + 3 + 1 + }) + }); } /// @notice Sets the implementation for the given fault game type in the `DisputeGameFactory`. function _setFaultGameImplementation( DisputeGameFactory _factory, - GameType _gameType, - Claim _absolutePrestate, - IBigStepper _faultVm, - uint256 _maxGameDepth + bool _allowUpgrade, + FaultDisputeGameParams memory _params ) internal { - if (address(_factory.gameImpls(_gameType)) == address(0)) { + if (address(_factory.gameImpls(_params.gameType)) != address(0) && !_allowUpgrade) { + console.log( + "[WARN] DisputeGameFactoryProxy: `FaultDisputeGame` implementation already set for game type: %s", + vm.toString(GameType.unwrap(_params.gameType)) + ); + return; + } + + uint32 rawGameType = GameType.unwrap(_params.gameType); + if (rawGameType != GameTypes.PERMISSIONED_CANNON.raw()) { _factory.setImplementation( - _gameType, + _params.gameType, new FaultDisputeGame({ - _gameType: _gameType, - _absolutePrestate: _absolutePrestate, - _maxGameDepth: _maxGameDepth, + _gameType: _params.gameType, + _absolutePrestate: _params.absolutePrestate, + _maxGameDepth: _params.maxGameDepth, + _splitDepth: cfg.faultGameSplitDepth(), _gameDuration: Duration.wrap(uint64(cfg.faultGameMaxDuration())), - _vm: _faultVm, - _l2oo: L2OutputOracle(mustGetAddress("L2OutputOracleProxy")), - _blockOracle: BlockOracle(mustGetAddress("BlockOracle")) + _vm: _params.faultVm, + _weth: _params.weth, + _anchorStateRegistry: _params.anchorStateRegistry, + _l2ChainId: cfg.l2ChainID() }) ); - - uint8 rawGameType = GameType.unwrap(_gameType); - console.log( - "DisputeGameFactoryProxy: set `FaultDisputeGame` implementation (Backend: %s | GameType: %s)", - rawGameType == 0 ? "Cannon" : "Alphabet", - vm.toString(rawGameType) - ); } else { - console.log( - "[WARN] DisputeGameFactoryProxy: `FaultDisputeGame` implementation already set for game type: %s", - vm.toString(GameType.unwrap(_gameType)) + _factory.setImplementation( + _params.gameType, + new PermissionedDisputeGame({ + _gameType: _params.gameType, + _absolutePrestate: _params.absolutePrestate, + _maxGameDepth: _params.maxGameDepth, + _splitDepth: cfg.faultGameSplitDepth(), + _gameDuration: Duration.wrap(uint64(cfg.faultGameMaxDuration())), + _vm: _params.faultVm, + _weth: _params.weth, + _anchorStateRegistry: _params.anchorStateRegistry, + _l2ChainId: cfg.l2ChainID(), + _proposer: cfg.l2OutputOracleProposer(), + _challenger: cfg.l2OutputOracleChallenger() + }) ); } + + string memory gameTypeString; + if (rawGameType == GameTypes.CANNON.raw()) { + gameTypeString = "Cannon"; + } else if (rawGameType == GameTypes.PERMISSIONED_CANNON.raw()) { + gameTypeString = "PermissionedCannon"; + } else if (rawGameType == GameTypes.ALPHABET.raw()) { + gameTypeString = "Alphabet"; + } else { + gameTypeString = "Unknown"; + } + + console.log( + "DisputeGameFactoryProxy: set `FaultDisputeGame` implementation (Backend: %s | GameType: %s)", + gameTypeString, + vm.toString(rawGameType) + ); } - /// @notice Deploy the StorageSetter contract, used for upgrades. - function deployStorageSetter() public broadcast returns (address addr_) { - StorageSetter setter = new StorageSetter{ salt: implSalt() }(); - console.log("StorageSetter deployed at: %s", address(setter)); - string memory version = setter.version(); - console.log("StorageSetter version: %s", version); - addr_ = address(setter); + /// @notice Initialize the DataAvailabilityChallenge + function initializeDataAvailabilityChallenge() public broadcast { + console.log("Upgrading and initializing DataAvailabilityChallenge proxy"); + address dataAvailabilityChallengeProxy = mustGetAddress("DataAvailabilityChallengeProxy"); + address dataAvailabilityChallenge = mustGetAddress("DataAvailabilityChallenge"); + + address finalSystemOwner = cfg.finalSystemOwner(); + uint256 daChallengeWindow = cfg.daChallengeWindow(); + uint256 daResolveWindow = cfg.daResolveWindow(); + uint256 daBondSize = cfg.daBondSize(); + uint256 daResolverRefundPercentage = cfg.daResolverRefundPercentage(); + + _upgradeAndCallViaSafe({ + _proxy: payable(dataAvailabilityChallengeProxy), + _implementation: dataAvailabilityChallenge, + _innerCallData: abi.encodeCall( + DataAvailabilityChallenge.initialize, + (finalSystemOwner, daChallengeWindow, daResolveWindow, daBondSize, daResolverRefundPercentage) + ) + }); + + DataAvailabilityChallenge dac = DataAvailabilityChallenge(payable(dataAvailabilityChallengeProxy)); + string memory version = dac.version(); + console.log("DataAvailabilityChallenge version: %s", version); + + require(dac.owner() == finalSystemOwner); + require(dac.challengeWindow() == daChallengeWindow); + require(dac.resolveWindow() == daResolveWindow); + require(dac.bondSize() == daBondSize); + require(dac.resolverRefundPercentage() == daResolverRefundPercentage); } } diff --git a/packages/contracts-bedrock/scripts/DeployConfig.s.sol b/packages/contracts-bedrock/scripts/DeployConfig.s.sol index 89157e04a545..097ffbf4b9e4 100644 --- a/packages/contracts-bedrock/scripts/DeployConfig.s.sol +++ b/packages/contracts-bedrock/scripts/DeployConfig.s.sol @@ -1,11 +1,15 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; import { console2 as console } from "forge-std/console2.sol"; import { stdJson } from "forge-std/StdJson.sol"; -import { Executables } from "./Executables.sol"; -import { Chains } from "./Chains.sol"; +import { Executables } from "scripts/Executables.sol"; +import { Chains } from "scripts/Chains.sol"; + +// Global constant for the `useFaultProofs` slot in the DeployConfig contract, which can be overridden in the testing +// environment. +bytes32 constant USE_FAULT_PROOFS_SLOT = bytes32(uint256(63)); /// @title DeployConfig /// @notice Represents the configuration required to deploy the system. It is expected @@ -15,7 +19,7 @@ contract DeployConfig is Script { string internal _json; address public finalSystemOwner; - address public portalGuardian; + address public superchainConfigGuardian; uint256 public l1ChainID; uint256 public l2ChainID; uint256 public l2BlockTime; @@ -31,10 +35,15 @@ contract DeployConfig is Script { address public l2OutputOracleProposer; address public l2OutputOracleChallenger; uint256 public finalizationPeriodSeconds; + bool public fundDevAccounts; address public proxyAdminOwner; address public baseFeeVaultRecipient; + uint256 public baseFeeVaultMinimumWithdrawalAmount; address public l1FeeVaultRecipient; + uint256 public l1FeeVaultMinimumWithdrawalAmount; address public sequencerFeeVaultRecipient; + uint256 public sequencerFeeVaultMinimumWithdrawalAmount; + uint256 public sequencerFeeVaultWithdrawalNetwork; string public governanceTokenName; string public governanceTokenSymbol; address public governanceTokenOwner; @@ -42,26 +51,41 @@ contract DeployConfig is Script { uint256 public l2GenesisBlockBaseFeePerGas; uint256 public gasPriceOracleOverhead; uint256 public gasPriceOracleScalar; + bool public enableGovernance; uint256 public eip1559Denominator; uint256 public eip1559Elasticity; uint256 public faultGameAbsolutePrestate; + uint256 public faultGameGenesisBlock; + bytes32 public faultGameGenesisOutputRoot; uint256 public faultGameMaxDepth; + uint256 public faultGameSplitDepth; uint256 public faultGameMaxDuration; + uint256 public faultGameWithdrawalDelay; + uint256 public preimageOracleMinProposalSize; + uint256 public preimageOracleChallengePeriod; uint256 public systemConfigStartBlock; uint256 public requiredProtocolVersion; uint256 public recommendedProtocolVersion; + uint256 public proofMaturityDelaySeconds; + uint256 public disputeGameFinalityDelaySeconds; + uint256 public respectedGameType; + bool public useFaultProofs; + bool public usePlasma; + uint256 public daChallengeWindow; + uint256 public daResolveWindow; + uint256 public daBondSize; + uint256 public daResolverRefundPercentage; - constructor(string memory _path) { + function read(string memory _path) public { console.log("DeployConfig: reading file %s", _path); try vm.readFile(_path) returns (string memory data) { _json = data; } catch { - console.log("Warning: unable to read config. Do not deploy unless you are not using config."); - return; + require(false, string.concat("Cannot find deploy config file at ", _path)); } finalSystemOwner = stdJson.readAddress(_json, "$.finalSystemOwner"); - portalGuardian = stdJson.readAddress(_json, "$.portalGuardian"); + superchainConfigGuardian = stdJson.readAddress(_json, "$.superchainConfigGuardian"); l1ChainID = stdJson.readUint(_json, "$.l1ChainID"); l2ChainID = stdJson.readUint(_json, "$.l2ChainID"); l2BlockTime = stdJson.readUint(_json, "$.l2BlockTime"); @@ -77,10 +101,15 @@ contract DeployConfig is Script { l2OutputOracleProposer = stdJson.readAddress(_json, "$.l2OutputOracleProposer"); l2OutputOracleChallenger = stdJson.readAddress(_json, "$.l2OutputOracleChallenger"); finalizationPeriodSeconds = stdJson.readUint(_json, "$.finalizationPeriodSeconds"); + fundDevAccounts = stdJson.readBool(_json, "$.fundDevAccounts"); proxyAdminOwner = stdJson.readAddress(_json, "$.proxyAdminOwner"); baseFeeVaultRecipient = stdJson.readAddress(_json, "$.baseFeeVaultRecipient"); + baseFeeVaultMinimumWithdrawalAmount = stdJson.readUint(_json, "$.baseFeeVaultMinimumWithdrawalAmount"); l1FeeVaultRecipient = stdJson.readAddress(_json, "$.l1FeeVaultRecipient"); + l1FeeVaultMinimumWithdrawalAmount = stdJson.readUint(_json, "$.l1FeeVaultMinimumWithdrawalAmount"); sequencerFeeVaultRecipient = stdJson.readAddress(_json, "$.sequencerFeeVaultRecipient"); + sequencerFeeVaultMinimumWithdrawalAmount = stdJson.readUint(_json, "$.sequencerFeeVaultMinimumWithdrawalAmount"); + sequencerFeeVaultWithdrawalNetwork = stdJson.readUint(_json, "$.sequencerFeeVaultWithdrawalNetwork"); governanceTokenName = stdJson.readString(_json, "$.governanceTokenName"); governanceTokenSymbol = stdJson.readString(_json, "$.governanceTokenSymbol"); governanceTokenOwner = stdJson.readAddress(_json, "$.governanceTokenOwner"); @@ -88,17 +117,34 @@ contract DeployConfig is Script { l2GenesisBlockBaseFeePerGas = stdJson.readUint(_json, "$.l2GenesisBlockBaseFeePerGas"); gasPriceOracleOverhead = stdJson.readUint(_json, "$.gasPriceOracleOverhead"); gasPriceOracleScalar = stdJson.readUint(_json, "$.gasPriceOracleScalar"); + enableGovernance = stdJson.readBool(_json, "$.enableGovernance"); eip1559Denominator = stdJson.readUint(_json, "$.eip1559Denominator"); eip1559Elasticity = stdJson.readUint(_json, "$.eip1559Elasticity"); systemConfigStartBlock = stdJson.readUint(_json, "$.systemConfigStartBlock"); requiredProtocolVersion = stdJson.readUint(_json, "$.requiredProtocolVersion"); recommendedProtocolVersion = stdJson.readUint(_json, "$.recommendedProtocolVersion"); - if (block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet) { - faultGameAbsolutePrestate = stdJson.readUint(_json, "$.faultGameAbsolutePrestate"); - faultGameMaxDepth = stdJson.readUint(_json, "$.faultGameMaxDepth"); - faultGameMaxDuration = stdJson.readUint(_json, "$.faultGameMaxDuration"); - } + useFaultProofs = stdJson.readBool(_json, "$.useFaultProofs"); + proofMaturityDelaySeconds = stdJson.readUint(_json, "$.proofMaturityDelaySeconds"); + disputeGameFinalityDelaySeconds = stdJson.readUint(_json, "$.disputeGameFinalityDelaySeconds"); + respectedGameType = stdJson.readUint(_json, "$.respectedGameType"); + + faultGameAbsolutePrestate = stdJson.readUint(_json, "$.faultGameAbsolutePrestate"); + faultGameMaxDepth = stdJson.readUint(_json, "$.faultGameMaxDepth"); + faultGameSplitDepth = stdJson.readUint(_json, "$.faultGameSplitDepth"); + faultGameMaxDuration = stdJson.readUint(_json, "$.faultGameMaxDuration"); + faultGameGenesisBlock = stdJson.readUint(_json, "$.faultGameGenesisBlock"); + faultGameGenesisOutputRoot = stdJson.readBytes32(_json, "$.faultGameGenesisOutputRoot"); + faultGameWithdrawalDelay = stdJson.readUint(_json, "$.faultGameWithdrawalDelay"); + + preimageOracleMinProposalSize = stdJson.readUint(_json, "$.preimageOracleMinProposalSize"); + preimageOracleChallengePeriod = stdJson.readUint(_json, "$.preimageOracleChallengePeriod"); + + usePlasma = _readOr(_json, "$.usePlasma", false); + daChallengeWindow = _readOr(_json, "$.daChallengeWindow", 1000); + daResolveWindow = _readOr(_json, "$.daResolveWindow", 1000); + daBondSize = _readOr(_json, "$.daBondSize", 1000000000); + daResolverRefundPercentage = _readOr(_json, "$.daResolverRefundPercentage", 0); } function l1StartingBlockTag() public returns (bytes32) { @@ -129,6 +175,11 @@ contract DeployConfig is Script { return uint256(_l2OutputOracleStartingTimestamp); } + /// @notice Allow the `usePlasma` config to be overridden in testing environments + function setUsePlasma(bool _usePlasma) public { + usePlasma = _usePlasma; + } + function _getBlockByTag(string memory _tag) internal returns (bytes32) { string[] memory cmd = new string[](3); cmd[0] = Executables.bash; @@ -137,4 +188,12 @@ contract DeployConfig is Script { bytes memory res = vm.ffi(cmd); return abi.decode(res, (bytes32)); } + + function _readOr(string memory json, string memory key, bool defaultValue) internal view returns (bool) { + return vm.keyExists(json, key) ? stdJson.readBool(json, key) : defaultValue; + } + + function _readOr(string memory json, string memory key, uint256 defaultValue) internal view returns (uint256) { + return vm.keyExists(json, key) ? stdJson.readUint(json, key) : defaultValue; + } } diff --git a/packages/contracts-bedrock/scripts/DeployL2.s.sol b/packages/contracts-bedrock/scripts/DeployL2.s.sol deleted file mode 100644 index 7762f9fb6c22..000000000000 --- a/packages/contracts-bedrock/scripts/DeployL2.s.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import { Deployer } from "./Deployer.sol"; -import { DeployConfig } from "./DeployConfig.s.sol"; -import { console2 as console } from "forge-std/console2.sol"; - -import { EAS } from "../src/EAS/EAS.sol"; -import { SchemaRegistry } from "../src/EAS/SchemaRegistry.sol"; -import { ISchemaRegistry } from "../src/EAS/ISchemaRegistry.sol"; -import { Predeploys } from "../src/libraries/Predeploys.sol"; - -/// @title DeployL2 -/// @notice Script used to deploy predeploy implementations to L2. -contract DeployL2 is Deployer { - DeployConfig cfg; - - /// @notice The name of the script, used to ensure the right deploy artifacts - /// are used. - function name() public pure override returns (string memory) { - return "DeployL2"; - } - - function setUp() public override { - super.setUp(); - - string memory path = string.concat(vm.projectRoot(), "/deploy-config/", deploymentContext, ".json"); - cfg = new DeployConfig(path); - - console.log("Deploying from %s", deployScript); - console.log("Deployment context: %s", deploymentContext); - } - - /// @notice Modifier that wraps a function in broadcasting. - modifier broadcast() { - vm.startBroadcast(); - _; - vm.stopBroadcast(); - } - - /// @notice Deploy the EAS implementation. - function deployEAS() public broadcast returns (address) { - EAS eas = new EAS(); - - ISchemaRegistry registry = eas.getSchemaRegistry(); - require(address(registry) == Predeploys.SCHEMA_REGISTRY, "EAS: invalid SchemaRegistry address"); - - save("EAS", address(eas)); - console.log("EAS deployed at %s", address(eas)); - - string memory version = eas.version(); - console.log("EAS version: %s", version); - - return address(eas); - } - - /// @notice Deploy the SchemaManager implementation. - function deploySchemaRegistry() public broadcast returns (address) { - SchemaRegistry registry = new SchemaRegistry(); - - save("SchemaRegistry", address(registry)); - console.log("SchemaRegistry deployed at %s", address(registry)); - - string memory version = registry.version(); - console.log("SchemaRegistry version: %s", version); - - return address(registry); - } -} diff --git a/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol b/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol index 3cb7519832d5..8efb11228334 100644 --- a/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol +++ b/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol @@ -3,8 +3,9 @@ pragma solidity ^0.8.0; import { console2 as console } from "forge-std/console2.sol"; -import { Deployer } from "./Deployer.sol"; -import { PeripheryDeployConfig } from "./PeripheryDeployConfig.s.sol"; +import { Script } from "forge-std/Script.sol"; +import { Artifacts } from "scripts/Artifacts.s.sol"; +import { PeripheryDeployConfig } from "scripts/PeripheryDeployConfig.s.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { Proxy } from "src/universal/Proxy.sol"; @@ -12,29 +13,29 @@ import { Proxy } from "src/universal/Proxy.sol"; import { Faucet } from "src/periphery/faucet/Faucet.sol"; import { Drippie } from "src/periphery/drippie/Drippie.sol"; import { CheckGelatoLow } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol"; -import { CheckBalanceHigh } from "src/periphery/drippie/dripchecks/CheckBalanceHigh.sol"; import { CheckBalanceLow } from "src/periphery/drippie/dripchecks/CheckBalanceLow.sol"; import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol"; import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +import { Config } from "scripts/Config.sol"; /// @title DeployPeriphery /// @notice Script used to deploy periphery contracts. -contract DeployPeriphery is Deployer { +contract DeployPeriphery is Script, Artifacts { PeripheryDeployConfig cfg; /// @notice The name of the script, used to ensure the right deploy artifacts /// are used. - function name() public pure override returns (string memory) { - return "DeployPeriphery"; + function name() public pure returns (string memory name_) { + name_ = "DeployPeriphery"; } function setUp() public override { - super.setUp(); + Artifacts.setUp(); string memory path = string.concat(vm.projectRoot(), "/periphery-deploy-config/", deploymentContext, ".json"); cfg = new PeripheryDeployConfig(path); - console.log("Deploying from %s", deployScript); console.log("Deployment context: %s", deploymentContext); } @@ -47,6 +48,14 @@ contract DeployPeriphery is Deployer { initializeFaucet(); installFaucetAuthModulesConfigs(); + + if (cfg.installOpChainFaucetsDrips()) { + installOpChainFaucetsDrippieConfigs(); + } + + if (cfg.archivePreviousOpChainFaucetsDrips()) { + archivePreviousOpChainFaucetsDrippieConfigs(); + } } /// @notice Deploy all of the proxies @@ -62,7 +71,6 @@ contract DeployPeriphery is Deployer { deployFaucetDrippie(); deployCheckTrue(); deployCheckBalanceLow(); - deployCheckBalanceHigh(); deployCheckGelatoLow(); deployOnChainAuthModule(); deployOffChainAuthModule(); @@ -85,9 +93,7 @@ contract DeployPeriphery is Deployer { save("ProxyAdmin", preComputedAddress); addr_ = preComputedAddress; } else { - ProxyAdmin admin = new ProxyAdmin{ salt: salt }({ - _owner: msg.sender - }); + ProxyAdmin admin = new ProxyAdmin{ salt: salt }({ _owner: msg.sender }); require(admin.owner() == msg.sender); save("ProxyAdmin", address(admin)); @@ -108,11 +114,8 @@ contract DeployPeriphery is Deployer { save("FaucetProxy", preComputedAddress); addr_ = preComputedAddress; } else { - Proxy proxy = new Proxy{ salt: salt }({ - _admin: proxyAdmin - }); - address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY)))); - require(admin == proxyAdmin); + Proxy proxy = new Proxy{ salt: salt }({ _admin: proxyAdmin }); + require(EIP1967Helper.getAdmin(address(proxy)) == proxyAdmin); save("FaucetProxy", address(proxy)); console.log("FaucetProxy deployed at %s", address(proxy)); @@ -199,25 +202,6 @@ contract DeployPeriphery is Deployer { } } - /// @notice Deploy CheckBalanceHigh contract. - function deployCheckBalanceHigh() public broadcast returns (address addr_) { - bytes32 salt = keccak256(bytes("CheckBalanceHigh")); - bytes32 initCodeHash = keccak256(abi.encodePacked(type(CheckBalanceHigh).creationCode)); - address preComputedAddress = computeCreate2Address(salt, initCodeHash); - if (preComputedAddress.code.length > 0) { - console.log("CheckBalanceHigh already deployed at %s", preComputedAddress); - save("CheckBalanceHigh", preComputedAddress); - addr_ = preComputedAddress; - } else { - CheckBalanceHigh checkBalanceHigh = new CheckBalanceHigh{ salt: salt }(); - - save("CheckBalanceHigh", address(checkBalanceHigh)); - console.log("CheckBalanceHigh deployed at %s", address(checkBalanceHigh)); - - addr_ = address(checkBalanceHigh); - } - } - /// @notice Deploy CheckGelatoLow contract. function deployCheckGelatoLow() public broadcast returns (address addr_) { bytes32 salt = keccak256(bytes("CheckGelatoLow")); @@ -264,6 +248,113 @@ contract DeployPeriphery is Deployer { console.log("Faucet drip configs successfully installed"); } + /// @notice installs drip configs that deposit funds to all OP Chain faucets. This function + /// should only be called on an L1 testnet. + function installOpChainFaucetsDrippieConfigs() public { + uint256 drippieOwnerPrivateKey = Config.drippieOwnerPrivateKey(); + vm.startBroadcast(drippieOwnerPrivateKey); + + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + console.log("Installing OP Chain faucet drips at %s", address(drippie)); + installSmallOpChainFaucetsDrips(); + installLargeOpChainFaucetsDrips(); + installSmallOpChainAdminWalletDrips(); + installLargeOpChainAdminWalletDrips(); + + vm.stopBroadcast(); + + console.log("OP chain faucet drip configs successfully installed"); + } + + /// @notice archives the previous OP Chain drip configs. + function archivePreviousOpChainFaucetsDrippieConfigs() public { + uint256 drippieOwnerPrivateKey = Config.drippieOwnerPrivateKey(); + vm.startBroadcast(drippieOwnerPrivateKey); + + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + console.log("Archiving OP Chain faucet drips at %s", address(drippie)); + archivePreviousSmallOpChainFaucetsDrips(); + archivePreviousLargeOpChainFaucetsDrips(); + + vm.stopBroadcast(); + + console.log("OP chain faucet drip configs successfully installed"); + } + + /// @notice installs drips that send funds to small OP chain faucets on the scheduled interval. + function installSmallOpChainFaucetsDrips() public { + address faucetProxy = mustGetAddress("FaucetProxy"); + uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i); + _installDepositEthToDrip( + faucetProxy, + l1BridgeAddress, + cfg.smallOpChainFaucetDripValue(), + cfg.smallOpChainFaucetDripInterval(), + _faucetDripName(l1BridgeAddress, cfg.dripVersion()) + ); + } + } + + /// @notice installs drips that send funds to the admin wallets for small OP chain faucets + /// on the scheduled interval. + function installSmallOpChainAdminWalletDrips() public { + require( + cfg.faucetOnchainAuthModuleAdmin() == cfg.faucetOffchainAuthModuleAdmin(), + "installSmallOpChainAdminWalletDrips: Only handles identical admin wallet addresses" + ); + address adminWallet = cfg.faucetOnchainAuthModuleAdmin(); + uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i); + _installDepositEthToDrip( + adminWallet, + l1BridgeAddress, + cfg.opChainAdminWalletDripValue(), + cfg.opChainAdminWalletDripInterval(), + _adminWalletDripName(l1BridgeAddress, cfg.dripVersion()) + ); + } + } + + /// @notice installs drips that send funds to the admin wallets for large OP chain faucets + /// on the scheduled interval. + function installLargeOpChainAdminWalletDrips() public { + require( + cfg.faucetOnchainAuthModuleAdmin() == cfg.faucetOffchainAuthModuleAdmin(), + "installLargeOpChainAdminWalletDrips: Only handles identical admin wallet addresses" + ); + address adminWallet = cfg.faucetOnchainAuthModuleAdmin(); + uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i); + _installDepositEthToDrip( + adminWallet, + l1BridgeAddress, + cfg.opChainAdminWalletDripValue(), + cfg.opChainAdminWalletDripInterval(), + _adminWalletDripName(l1BridgeAddress, cfg.dripVersion()) + ); + } + } + + /// @notice installs drips that send funds to large OP chain faucets on the scheduled interval. + function installLargeOpChainFaucetsDrips() public { + address faucetProxy = mustGetAddress("FaucetProxy"); + uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i); + _installDepositEthToDrip( + faucetProxy, + l1BridgeAddress, + cfg.largeOpChainFaucetDripValue(), + cfg.largeOpChainFaucetDripInterval(), + _faucetDripName(l1BridgeAddress, cfg.dripVersion()) + ); + } + } + /// @notice installs the FaucetDripV1 drip on the faucet drippie contract. function installFaucetDripV1() public broadcast { Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); @@ -399,12 +490,75 @@ contract DeployPeriphery is Deployer { _activateIfPausedDrip(drippie, dripName); } + function archivePreviousSmallOpChainFaucetsDrips() public { + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i); + _pauseIfActivatedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion())); + _pauseIfActivatedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion())); + _archiveIfPausedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion())); + _archiveIfPausedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion())); + } + } + + function archivePreviousLargeOpChainFaucetsDrips() public { + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i); + _pauseIfActivatedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion())); + _pauseIfActivatedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion())); + _archiveIfPausedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion())); + _archiveIfPausedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion())); + } + } + function _activateIfPausedDrip(Drippie drippie, string memory dripName) internal { + require( + drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE + || drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED, + "attempting to activate a drip that is not currently paused or activated" + ); if (drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED) { console.log("%s is paused, activating", dripName); drippie.status(dripName, Drippie.DripStatus.ACTIVE); console.log("%s activated", dripName); require(drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE); + } else { + console.log("%s already activated", dripName); + } + } + + function _pauseIfActivatedDrip(Drippie drippie, string memory dripName) internal { + require( + drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE + || drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED, + "attempting to pause a drip that is not currently paused or activated" + ); + if (drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE) { + console.log("%s is active, pausing", dripName); + drippie.status(dripName, Drippie.DripStatus.PAUSED); + console.log("%s paused", dripName); + require(drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED); + } else { + console.log("%s already paused", dripName); + } + } + + function _archiveIfPausedDrip(Drippie drippie, string memory dripName) internal { + require( + drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED + || drippie.getDripStatus(dripName) == Drippie.DripStatus.ARCHIVED, + "attempting to archive a drip that is not currently paused or archived" + ); + if (drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED) { + console.log("%s is paused, archiving", dripName); + drippie.status(dripName, Drippie.DripStatus.ARCHIVED); + console.log("%s archived", dripName); + require(drippie.getDripStatus(dripName) == Drippie.DripStatus.ARCHIVED); + } else { + console.log("%s already archived", dripName); } } @@ -468,7 +622,7 @@ contract DeployPeriphery is Deployer { /// @notice installs the OnChain AuthModule on the Faucet contract. function installOnChainAuthModule() public broadcast { string memory moduleName = "OnChainAuthModule"; - Faucet faucet = Faucet(mustGetAddress("Faucet")); + Faucet faucet = Faucet(mustGetAddress("FaucetProxy")); AdminFaucetAuthModule onChainAuthModule = AdminFaucetAuthModule(mustGetAddress(moduleName)); if (faucet.isModuleEnabled(onChainAuthModule)) { console.log("%s already installed.", moduleName); @@ -488,7 +642,7 @@ contract DeployPeriphery is Deployer { /// @notice installs the OffChain AuthModule on the Faucet contract. function installOffChainAuthModule() public broadcast { string memory moduleName = "OffChainAuthModule"; - Faucet faucet = Faucet(mustGetAddress("Faucet")); + Faucet faucet = Faucet(mustGetAddress("FaucetProxy")); AdminFaucetAuthModule offChainAuthModule = AdminFaucetAuthModule(mustGetAddress(moduleName)); if (faucet.isModuleEnabled(offChainAuthModule)) { console.log("%s already installed.", moduleName); @@ -507,11 +661,59 @@ contract DeployPeriphery is Deployer { /// @notice installs all of the auth module in the faucet contract. function installFaucetAuthModulesConfigs() public { - Faucet faucet = Faucet(mustGetAddress("Faucet")); + Faucet faucet = Faucet(mustGetAddress("FaucetProxy")); console.log("Installing auth modules at %s", address(faucet)); installOnChainAuthModule(); installOffChainAuthModule(); console.log("Faucet Auth Module configs successfully installed"); } + + function _faucetDripName(address _l1Bridge, uint256 version) internal pure returns (string memory) { + string memory dripNamePrefixWithBridgeAddress = string.concat("faucet-drip-", vm.toString(_l1Bridge)); + string memory versionSuffix = string.concat("-", vm.toString(version)); + return string.concat(dripNamePrefixWithBridgeAddress, versionSuffix); + } + + function _adminWalletDripName(address _l1Bridge, uint256 version) internal pure returns (string memory) { + string memory dripNamePrefixWithBridgeAddress = string.concat("faucet-admin-drip-", vm.toString(_l1Bridge)); + string memory versionSuffix = string.concat("-", vm.toString(version)); + return string.concat(dripNamePrefixWithBridgeAddress, versionSuffix); + } + + function _installDepositEthToDrip( + address _depositTo, + address _l1Bridge, + uint256 _dripValue, + uint256 _dripInterval, + string memory dripName + ) + internal + { + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) { + console.log("installing %s", dripName); + Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); + actions[0] = Drippie.DripAction({ + target: payable(_l1Bridge), + data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", _depositTo, 200000, ""), + value: _dripValue + }); + drippie.create({ + _name: dripName, + _config: Drippie.DripConfig({ + reentrant: false, + interval: _dripInterval, + dripcheck: CheckTrue(mustGetAddress("CheckTrue")), + checkparams: abi.encode(""), + actions: actions + }) + }); + console.log("%s installed successfully", dripName); + } else { + console.log("%s already installed.", dripName); + } + + _activateIfPausedDrip(drippie, dripName); + } } diff --git a/packages/contracts-bedrock/scripts/Deployer.sol b/packages/contracts-bedrock/scripts/Deployer.sol index 3ba040a29f7c..6ab4fa8c19a9 100644 --- a/packages/contracts-bedrock/scripts/Deployer.sol +++ b/packages/contracts-bedrock/scripts/Deployer.sol @@ -2,499 +2,39 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; -import { stdJson } from "forge-std/StdJson.sol"; -import { console2 as console } from "forge-std/console2.sol"; -import { Executables } from "./Executables.sol"; -import { Chains } from "./Chains.sol"; - -/// @notice store the new deployment to be saved -struct Deployment { - string name; - address payable addr; -} - -/// @notice A `hardhat-deploy` style artifact -struct Artifact { - string abi; - address addr; - string[] args; - bytes bytecode; - bytes deployedBytecode; - string devdoc; - string metadata; - uint256 numDeployments; - string receipt; - bytes32 solcInputHash; - string storageLayout; - bytes32 transactionHash; - string userdoc; -} +import { Artifacts } from "scripts/Artifacts.s.sol"; +import { Config } from "scripts/Config.sol"; +import { DeployConfig } from "scripts/DeployConfig.s.sol"; +import { USE_FAULT_PROOFS_SLOT } from "scripts/DeployConfig.s.sol"; /// @title Deployer /// @author tynes /// @notice A contract that can make deploying and interacting with deployments easy. -/// When a contract is deployed, call the `save` function to write its name and -/// contract address to disk. Then the `sync` function can be called to generate -/// hardhat deploy style artifacts. Forked from `forge-deploy`. -abstract contract Deployer is Script { - /// @notice The set of deployments that have been done during execution. - mapping(string => Deployment) internal _namedDeployments; - /// @notice The same as `_namedDeployments` but as an array. - Deployment[] internal _newDeployments; - /// @notice The namespace for the deployment. Can be set with the env var DEPLOYMENT_CONTEXT. - string internal deploymentContext; - /// @notice Path to the deploy artifact generated by foundry - string internal deployPath; - /// @notice Path to the directory containing the hh deploy style artifacts - string internal deploymentsDir; - /// @notice The name of the deploy script that sends the transactions. - /// Can be modified with the env var DEPLOY_SCRIPT - string internal deployScript; - /// @notice The path to the temp deployments file - string internal tempDeploymentsPath; - /// @notice Error for when attempting to fetch a deployment and it does not exist - - error DeploymentDoesNotExist(string); - /// @notice Error for when trying to save an invalid deployment - error InvalidDeployment(string); - /// @notice The storage slot that holds the address of the implementation. - /// bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) - - bytes32 internal constant IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - /// @notice The storage slot that holds the address of the owner. - /// bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1) - bytes32 internal constant OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; +abstract contract Deployer is Script, Artifacts { + DeployConfig public constant cfg = + DeployConfig(address(uint160(uint256(keccak256(abi.encode("optimism.deployconfig")))))); - /// @notice Create the global variables and set up the filesystem. - /// Forge script will create a file where the prefix is the - /// name of the function that runs with the suffix `-latest.json`. - /// By default, `run()` is called. Allow the user to use the SIG - /// env var to specify what function signature was called so that - /// the `sync()` method can be used to create hardhat deploy style - /// artifacts. - function setUp() public virtual { - string memory root = vm.projectRoot(); - deployScript = vm.envOr("DEPLOY_SCRIPT", name()); + /// @notice Sets up the artifacts contract. + function setUp() public virtual override { + Artifacts.setUp(); - deploymentContext = _getDeploymentContext(); - string memory sig = vm.envOr("SIG", string("run")); - string memory deployFile = vm.envOr("DEPLOY_FILE", string.concat(sig, "-latest.json")); - uint256 chainId = vm.envOr("CHAIN_ID", block.chainid); - deployPath = string.concat(root, "/broadcast/", deployScript, ".s.sol/", vm.toString(chainId), "/", deployFile); + // Load the `useFaultProofs` slot value prior to etching the DeployConfig's bytecode and reading the deploy + // config file. If this slot has already been set, it will override the preference in the deploy config. + bytes32 useFaultProofsOverride = vm.load(address(cfg), USE_FAULT_PROOFS_SLOT); - deploymentsDir = string.concat(root, "/deployments/", deploymentContext); - try vm.createDir(deploymentsDir, true) { } catch (bytes memory) { } + vm.etch(address(cfg), vm.getDeployedCode("DeployConfig.s.sol:DeployConfig")); + vm.label(address(cfg), "DeployConfig"); + vm.allowCheatcodes(address(cfg)); + cfg.read(Config.deployConfigPath()); - string memory chainIdPath = string.concat(deploymentsDir, "/.chainId"); - try vm.readFile(chainIdPath) returns (string memory localChainId) { - if (vm.envOr("STRICT_DEPLOYMENT", true)) { - require(vm.parseUint(localChainId) == chainId, "Misconfigured networks"); - } - } catch { - vm.writeFile(chainIdPath, vm.toString(chainId)); + if (useFaultProofsOverride != 0) { + vm.store(address(cfg), USE_FAULT_PROOFS_SLOT, useFaultProofsOverride); } - console.log("Connected to network with chainid %s", chainId); - - tempDeploymentsPath = string.concat(deploymentsDir, "/.deploy"); - try vm.readFile(tempDeploymentsPath) returns (string memory) { } - catch { - vm.writeJson("{}", tempDeploymentsPath); - } - console.log("Storing temp deployment data in %s", tempDeploymentsPath); - } - - /// @notice Call this function to sync the deployment artifacts such that - /// hardhat deploy style artifacts are created. - function sync() public { - Deployment[] memory deployments = _getTempDeployments(); - console.log("Syncing %s deployments", deployments.length); - console.log("Using deployment artifact %s", deployPath); - - for (uint256 i; i < deployments.length; i++) { - address addr = deployments[i].addr; - string memory deploymentName = deployments[i].name; - - string memory deployTx = _getDeployTransactionByContractAddress(addr); - if (bytes(deployTx).length == 0) { - console.log("Deploy Tx not found for %s skipping deployment artifact generation", deploymentName); - continue; - } - string memory contractName = _getContractNameFromDeployTransaction(deployTx); - console.log("Syncing deployment %s: contract %s", deploymentName, contractName); - - string[] memory args = getDeployTransactionConstructorArguments(deployTx); - bytes memory code = _getCode(contractName); - bytes memory deployedCode = _getDeployedCode(contractName); - string memory receipt = _getDeployReceiptByContractAddress(addr); - - string memory artifactPath = string.concat(deploymentsDir, "/", deploymentName, ".json"); - - uint256 numDeployments = 0; - try vm.readFile(artifactPath) returns (string memory res) { - numDeployments = stdJson.readUint(string(res), "$.numDeployments"); - vm.removeFile(artifactPath); - } catch { } - numDeployments++; - - Artifact memory artifact = Artifact({ - abi: getAbi(contractName), - addr: addr, - args: args, - bytecode: code, - deployedBytecode: deployedCode, - devdoc: getDevDoc(contractName), - metadata: getMetadata(contractName), - numDeployments: numDeployments, - receipt: receipt, - solcInputHash: bytes32(0), - storageLayout: getStorageLayout(contractName), - transactionHash: stdJson.readBytes32(deployTx, "$.hash"), - userdoc: getUserDoc(contractName) - }); - - string memory json = _serializeArtifact(artifact); - - vm.writeJson({ json: json, path: artifactPath }); - } - - console.log("Synced temp deploy files, deleting %s", tempDeploymentsPath); - vm.removeFile(tempDeploymentsPath); } /// @notice Returns the name of the deployment script. Children contracts /// must implement this to ensure that the deploy artifacts can be found. + /// This should be the same as the name of the script and is used as the file + /// name inside of the `broadcast` directory when looking up deployment artifacts. function name() public pure virtual returns (string memory); - - /// @notice Returns all of the deployments done in the current context. - function newDeployments() external view returns (Deployment[] memory) { - return _newDeployments; - } - - /// @notice Returns whether or not a particular deployment exists. - /// @param _name The name of the deployment. - /// @return Whether the deployment exists or not. - function has(string memory _name) public view returns (bool) { - Deployment memory existing = _namedDeployments[_name]; - if (existing.addr != address(0)) { - return bytes(existing.name).length > 0; - } - return _getExistingDeploymentAddress(_name) != address(0); - } - - /// @notice Returns the address of a deployment. - /// @param _name The name of the deployment. - /// @return The address of the deployment. May be `address(0)` if the deployment does not - /// exist. - function getAddress(string memory _name) public view returns (address payable) { - Deployment memory existing = _namedDeployments[_name]; - if (existing.addr != address(0)) { - if (bytes(existing.name).length == 0) { - return payable(address(0)); - } - return existing.addr; - } - return _getExistingDeploymentAddress(_name); - } - - /// @notice Returns the address of a deployment and reverts if the deployment - /// does not exist. - /// @return The address of the deployment. - function mustGetAddress(string memory _name) public view returns (address payable) { - address addr = getAddress(_name); - if (addr == address(0)) { - revert DeploymentDoesNotExist(_name); - } - return payable(addr); - } - - /// @notice Returns a deployment that is suitable to be used to interact with contracts. - /// @param _name The name of the deployment. - /// @return The deployment. - function get(string memory _name) public view returns (Deployment memory) { - Deployment memory deployment = _namedDeployments[_name]; - if (deployment.addr != address(0)) { - return deployment; - } else { - return _getExistingDeployment(_name); - } - } - - /// @notice Writes a deployment to disk as a temp deployment so that the - /// hardhat deploy artifact can be generated afterwards. - /// @param _name The name of the deployment. - /// @param _deployed The address of the deployment. - function save(string memory _name, address _deployed) public { - if (bytes(_name).length == 0) { - revert InvalidDeployment("EmptyName"); - } - if (bytes(_namedDeployments[_name].name).length > 0) { - revert InvalidDeployment("AlreadyExists"); - } - - Deployment memory deployment = Deployment({ name: _name, addr: payable(_deployed) }); - _namedDeployments[_name] = deployment; - _newDeployments.push(deployment); - _writeTemp(_name, _deployed); - } - - /// @notice Reads the temp deployments from disk that were generated - /// by the deploy script. - /// @return An array of deployments. - function _getTempDeployments() internal returns (Deployment[] memory) { - string memory json = vm.readFile(tempDeploymentsPath); - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat(Executables.jq, " 'keys' <<< '", json, "'"); - bytes memory res = vm.ffi(cmd); - string[] memory names = stdJson.readStringArray(string(res), ""); - - Deployment[] memory deployments = new Deployment[](names.length); - for (uint256 i; i < names.length; i++) { - string memory contractName = names[i]; - address addr = stdJson.readAddress(json, string.concat("$.", contractName)); - deployments[i] = Deployment({ name: contractName, addr: payable(addr) }); - } - return deployments; - } - - /// @notice Returns the json of the deployment transaction given a contract address. - function _getDeployTransactionByContractAddress(address _addr) internal returns (string memory) { - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat( - Executables.jq, - " -r '.transactions[] | select(.contractAddress == ", - '"', - vm.toString(_addr), - '"', - ') | select(.transactionType == "CREATE"', - ' or .transactionType == "CREATE2"', - ")' < ", - deployPath - ); - bytes memory res = vm.ffi(cmd); - return string(res); - } - - /// @notice Returns the contract name from a deploy transaction. - function _getContractNameFromDeployTransaction(string memory _deployTx) internal returns (string memory) { - return stdJson.readString(_deployTx, ".contractName"); - } - - /// @notice Wrapper for vm.getCode that handles semver in the name. - function _getCode(string memory _name) internal returns (bytes memory) { - string memory fqn = _getFullyQualifiedName(_name); - bytes memory code = vm.getCode(fqn); - return code; - } - - /// @notice Wrapper for vm.getDeployedCode that handles semver in the name. - function _getDeployedCode(string memory _name) internal returns (bytes memory) { - string memory fqn = _getFullyQualifiedName(_name); - bytes memory code = vm.getDeployedCode(fqn); - return code; - } - - /// @notice Removes the semantic versioning from a contract name. The semver will exist if the contract is compiled - /// more than once with different versions of the compiler. - function _stripSemver(string memory _name) internal returns (string memory) { - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat( - Executables.echo, " ", _name, " | ", Executables.sed, " -E 's/[.][0-9]+\\.[0-9]+\\.[0-9]+//g'" - ); - bytes memory res = vm.ffi(cmd); - return string(res); - } - - /// @notice Returns the constructor arguent of a deployment transaction given a transaction json. - function getDeployTransactionConstructorArguments(string memory _transaction) internal returns (string[] memory) { - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat(Executables.jq, " -r '.arguments' <<< '", _transaction, "'"); - bytes memory res = vm.ffi(cmd); - - string[] memory args = new string[](0); - if (keccak256(bytes("null")) != keccak256(res)) { - args = stdJson.readStringArray(string(res), ""); - } - return args; - } - - /// @notice Builds the fully qualified name of a contract. Assumes that the - /// file name is the same as the contract name but strips semver for the file name. - function _getFullyQualifiedName(string memory _name) internal returns (string memory) { - string memory sanitized = _stripSemver(_name); - return string.concat(sanitized, ".sol:", _name); - } - - /// @notice Returns the filesystem path to the artifact path. Assumes that the name of the - /// file matches the name of the contract. - function _getForgeArtifactPath(string memory _name) internal returns (string memory) { - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat(Executables.forge, " config --json | ", Executables.jq, " -r .out"); - bytes memory res = vm.ffi(cmd); - string memory contractName = _stripSemver(_name); - string memory forgeArtifactPath = - string.concat(vm.projectRoot(), "/", string(res), "/", contractName, ".sol/", _name, ".json"); - return forgeArtifactPath; - } - - /// @notice Returns the forge artifact given a contract name. - function _getForgeArtifact(string memory _name) internal returns (string memory) { - string memory forgeArtifactPath = _getForgeArtifactPath(_name); - string memory forgeArtifact = vm.readFile(forgeArtifactPath); - return forgeArtifact; - } - - /// @notice Returns the receipt of a deployment transaction. - function _getDeployReceiptByContractAddress(address addr) internal returns (string memory) { - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat( - Executables.jq, - " -r '.receipts[] | select(.contractAddress == ", - '"', - vm.toString(addr), - '"', - ")' < ", - deployPath - ); - bytes memory res = vm.ffi(cmd); - string memory receipt = string(res); - return receipt; - } - - /// @notice Returns the devdoc for a deployed contract. - function getDevDoc(string memory _name) internal returns (string memory) { - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat(Executables.jq, " -r '.devdoc' < ", _getForgeArtifactPath(_name)); - bytes memory res = vm.ffi(cmd); - return string(res); - } - - /// @notice Returns the storage layout for a deployed contract. - function getStorageLayout(string memory _name) internal returns (string memory) { - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat(Executables.jq, " -r '.storageLayout' < ", _getForgeArtifactPath(_name)); - bytes memory res = vm.ffi(cmd); - return string(res); - } - - /// @notice Returns the abi for a deployed contract. - function getAbi(string memory _name) internal returns (string memory) { - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat(Executables.jq, " -r '.abi' < ", _getForgeArtifactPath(_name)); - bytes memory res = vm.ffi(cmd); - return string(res); - } - - /// @notice Returns the userdoc for a deployed contract. - function getUserDoc(string memory _name) internal returns (string memory) { - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat(Executables.jq, " -r '.userdoc' < ", _getForgeArtifactPath(_name)); - bytes memory res = vm.ffi(cmd); - return string(res); - } - - /// @notice - function getMetadata(string memory _name) internal returns (string memory) { - string[] memory cmd = new string[](3); - cmd[0] = Executables.bash; - cmd[1] = "-c"; - cmd[2] = string.concat(Executables.jq, " '.metadata | tostring' < ", _getForgeArtifactPath(_name)); - bytes memory res = vm.ffi(cmd); - return string(res); - } - - /// @notice Adds a deployment to the temp deployments file - function _writeTemp(string memory _name, address _deployed) internal { - vm.writeJson({ json: stdJson.serialize("", _name, _deployed), path: tempDeploymentsPath }); - } - - /// @notice Turns an Artifact into a json serialized string - /// @param _artifact The artifact to serialize - /// @return The json serialized string - function _serializeArtifact(Artifact memory _artifact) internal returns (string memory) { - string memory json = ""; - json = stdJson.serialize("", "address", _artifact.addr); - json = stdJson.serialize("", "abi", _artifact.abi); - json = stdJson.serialize("", "args", _artifact.args); - json = stdJson.serialize("", "bytecode", _artifact.bytecode); - json = stdJson.serialize("", "deployedBytecode", _artifact.deployedBytecode); - json = stdJson.serialize("", "devdoc", _artifact.devdoc); - json = stdJson.serialize("", "metadata", _artifact.metadata); - json = stdJson.serialize("", "numDeployments", _artifact.numDeployments); - json = stdJson.serialize("", "receipt", _artifact.receipt); - json = stdJson.serialize("", "solcInputHash", _artifact.solcInputHash); - json = stdJson.serialize("", "storageLayout", _artifact.storageLayout); - json = stdJson.serialize("", "transactionHash", _artifact.transactionHash); - json = stdJson.serialize("", "userdoc", _artifact.userdoc); - return json; - } - - /// @notice The context of the deployment is used to namespace the artifacts. - /// An unknown context will use the chainid as the context name. - function _getDeploymentContext() private returns (string memory) { - string memory context = vm.envOr("DEPLOYMENT_CONTEXT", string("")); - if (bytes(context).length > 0) { - return context; - } - - uint256 chainid = vm.envOr("CHAIN_ID", block.chainid); - if (chainid == Chains.Mainnet) { - return "mainnet"; - } else if (chainid == Chains.Goerli) { - return "goerli"; - } else if (chainid == Chains.OPGoerli) { - return "optimism-goerli"; - } else if (chainid == Chains.OPMainnet) { - return "optimism-mainnet"; - } else if (chainid == Chains.LocalDevnet || chainid == Chains.GethDevnet || chainid == Chains.BscDevnet) { - return "devnetL1"; - } else if (chainid == Chains.Hardhat) { - return "hardhat"; - } else if (chainid == Chains.Sepolia) { - return "sepolia"; - } else if (chainid == Chains.OPSepolia) { - return "optimism-sepolia"; - } else { - return vm.toString(chainid); - } - } - - /// @notice Reads the artifact from the filesystem by name and returns the address. - /// @param _name The name of the artifact to read. - /// @return The address of the artifact. - function _getExistingDeploymentAddress(string memory _name) internal view returns (address payable) { - return _getExistingDeployment(_name).addr; - } - - /// @notice Reads the artifact from the filesystem by name and returns the Deployment. - /// @param _name The name of the artifact to read. - /// @return The deployment corresponding to the name. - function _getExistingDeployment(string memory _name) internal view returns (Deployment memory) { - string memory path = string.concat(deploymentsDir, "/", _name, ".json"); - try vm.readFile(path) returns (string memory json) { - bytes memory addr = stdJson.parseRaw(json, "$.address"); - return Deployment({ addr: abi.decode(addr, (address)), name: _name }); - } catch { - return Deployment({ addr: payable(address(0)), name: "" }); - } - } } diff --git a/packages/contracts-bedrock/scripts/Executables.sol b/packages/contracts-bedrock/scripts/Executables.sol index 4ba5bf98ada3..8eab92078b9b 100644 --- a/packages/contracts-bedrock/scripts/Executables.sol +++ b/packages/contracts-bedrock/scripts/Executables.sol @@ -10,4 +10,6 @@ library Executables { string internal constant forge = "forge"; string internal constant echo = "echo"; string internal constant sed = "sed"; + string internal constant find = "find"; + string internal constant ls = "ls"; } diff --git a/packages/contracts-bedrock/scripts/FaultDisputeGameViz.s.sol b/packages/contracts-bedrock/scripts/FaultDisputeGameViz.s.sol index 56b753846255..1d9ba743a56b 100644 --- a/packages/contracts-bedrock/scripts/FaultDisputeGameViz.s.sol +++ b/packages/contracts-bedrock/scripts/FaultDisputeGameViz.s.sol @@ -1,17 +1,17 @@ +// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; import { Script } from "forge-std/Script.sol"; import { console2 as console } from "forge-std/console2.sol"; -import { FaultDisputeGame_Init } from "../test/FaultDisputeGame.t.sol"; -import { DisputeGameFactory } from "../src/dispute/DisputeGameFactory.sol"; -import { FaultDisputeGame } from "../src/dispute/FaultDisputeGame.sol"; -import { IFaultDisputeGame } from "../src/dispute/interfaces/IFaultDisputeGame.sol"; +import { FaultDisputeGame_Init } from "test/dispute/FaultDisputeGame.t.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; -import "../src/libraries/DisputeTypes.sol"; -import "../src/libraries/DisputeErrors.sol"; -import { LibClock } from "../src/dispute/lib/LibClock.sol"; -import { LibPosition } from "../src/dispute/lib/LibPosition.sol"; +import "src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeErrors.sol"; +import { LibPosition } from "src/dispute/lib/LibPosition.sol"; /** * @title FaultDisputeGameViz @@ -19,12 +19,13 @@ import { LibPosition } from "../src/dispute/lib/LibPosition.sol"; */ contract FaultDisputeGameViz is Script, FaultDisputeGame_Init { /// @dev The root claim of the game. - Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32(uint256(10))); + Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32(uint256(1))); /// @dev The absolute prestate of the trace. - Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32(uint256(0))); + Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32((uint256(3) << 248) | uint256(0))); function setUp() public override { - super.init(ROOT_CLAIM, ABSOLUTE_PRESTATE); + super.setUp(); + super.init({ rootClaim: ROOT_CLAIM, absolutePrestate: ABSOLUTE_PRESTATE, l2BlockNumber: 0x10 }); } /** @@ -42,7 +43,7 @@ contract FaultDisputeGameViz is Script, FaultDisputeGame_Init { * @dev Entry point */ function remote(address _addr) public { - gameProxy = FaultDisputeGame(_addr); + gameProxy = FaultDisputeGame(payable(_addr)); buildGraph(); console.log("Saved graph to `./dispute_game.svg"); } @@ -54,11 +55,21 @@ contract FaultDisputeGameViz is Script, FaultDisputeGame_Init { uint256 numClaims = uint256(vm.load(address(gameProxy), bytes32(uint256(1)))); IFaultDisputeGame.ClaimData[] memory gameData = new IFaultDisputeGame.ClaimData[](numClaims); for (uint256 i = 0; i < numClaims; i++) { - (uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(i); + ( + uint32 parentIndex, + address countered, + address claimant, + uint128 bond, + Claim claim, + Position position, + Clock clock + ) = gameProxy.claimData(i); gameData[i] = IFaultDisputeGame.ClaimData({ parentIndex: parentIndex, - countered: countered, + counteredBy: countered, + claimant: claimant, + bond: bond, claim: claim, position: position, clock: clock diff --git a/packages/contracts-bedrock/scripts/ForgeArtifacts.sol b/packages/contracts-bedrock/scripts/ForgeArtifacts.sol new file mode 100644 index 000000000000..c95254c8e044 --- /dev/null +++ b/packages/contracts-bedrock/scripts/ForgeArtifacts.sol @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Vm } from "forge-std/Vm.sol"; +import { Executables } from "scripts/Executables.sol"; +import { stdJson } from "forge-std/StdJson.sol"; + +/// @notice Contains information about a storage slot. Mirrors the layout of the storage +/// slot object in Forge artifacts so that we can deserialize JSON into this struct. +struct StorageSlot { + uint256 astId; + string _contract; + string label; + uint256 offset; + string slot; + string _type; +} + +/// @title ForgeArtifacts +/// @notice Library for interacting with the forge artifacts. +library ForgeArtifacts { + /// @notice Foundry cheatcode VM. + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + /// @notice Removes the semantic versioning from a contract name. The semver will exist if the contract is compiled + /// more than once with different versions of the compiler. + function _stripSemver(string memory _name) internal returns (string memory out_) { + string[] memory cmd = new string[](3); + cmd[0] = Executables.bash; + cmd[1] = "-c"; + cmd[2] = string.concat( + Executables.echo, " ", _name, " | ", Executables.sed, " -E 's/[.][0-9]+\\.[0-9]+\\.[0-9]+//g'" + ); + bytes memory res = vm.ffi(cmd); + out_ = string(res); + } + + /// @notice Builds the fully qualified name of a contract. Assumes that the + /// file name is the same as the contract name but strips semver for the file name. + function _getFullyQualifiedName(string memory _name) internal returns (string memory out_) { + string memory sanitized = _stripSemver(_name); + out_ = string.concat(sanitized, ".sol:", _name); + } + + /// @notice Returns the storage layout for a deployed contract. + function getStorageLayout(string memory _name) public returns (string memory layout_) { + string[] memory cmd = new string[](3); + cmd[0] = Executables.bash; + cmd[1] = "-c"; + cmd[2] = string.concat(Executables.jq, " -r '.storageLayout' < ", _getForgeArtifactPath(_name)); + bytes memory res = vm.ffi(cmd); + layout_ = string(res); + } + + /// @notice Returns the abi from a the forge artifact + function getAbi(string memory _name) public returns (string memory abi_) { + string[] memory cmd = new string[](3); + cmd[0] = Executables.bash; + cmd[1] = "-c"; + cmd[2] = string.concat(Executables.jq, " -r '.abi' < ", _getForgeArtifactPath(_name)); + bytes memory res = vm.ffi(cmd); + abi_ = string(res); + } + + /// @notice Returns the methodIdentifiers from the forge artifact + function getMethodIdentifiers(string memory _name) internal returns (string[] memory ids_) { + string[] memory cmd = new string[](3); + cmd[0] = Executables.bash; + cmd[1] = "-c"; + cmd[2] = string.concat(Executables.jq, " '.methodIdentifiers | keys' < ", _getForgeArtifactPath(_name)); + bytes memory res = vm.ffi(cmd); + ids_ = stdJson.readStringArray(string(res), ""); + } + + function _getForgeArtifactDirectory(string memory _name) internal returns (string memory dir_) { + string[] memory cmd = new string[](3); + cmd[0] = Executables.bash; + cmd[1] = "-c"; + cmd[2] = string.concat(Executables.forge, " config --json | ", Executables.jq, " -r .out"); + bytes memory res = vm.ffi(cmd); + string memory contractName = _stripSemver(_name); + dir_ = string.concat(vm.projectRoot(), "/", string(res), "/", contractName, ".sol"); + } + + /// @notice Returns the filesystem path to the artifact path. If the contract was compiled + /// with multiple solidity versions then return the first one based on the result of `ls`. + function _getForgeArtifactPath(string memory _name) internal returns (string memory out_) { + string memory directory = _getForgeArtifactDirectory(_name); + string memory path = string.concat(directory, "/", _name, ".json"); + if (vm.exists(path)) { + return path; + } + + string[] memory cmd = new string[](3); + cmd[0] = Executables.bash; + cmd[1] = "-c"; + cmd[2] = string.concat( + Executables.ls, + " -1 --color=never ", + directory, + " | ", + Executables.jq, + " -R -s -c 'split(\"\n\") | map(select(length > 0))'" + ); + bytes memory res = vm.ffi(cmd); + string[] memory files = stdJson.readStringArray(string(res), ""); + out_ = string.concat(directory, "/", files[0]); + } + + /// @notice Returns the forge artifact given a contract name. + function _getForgeArtifact(string memory _name) internal returns (string memory out_) { + string memory forgeArtifactPath = _getForgeArtifactPath(_name); + out_ = vm.readFile(forgeArtifactPath); + } + + /// @notice Pulls the `_initialized` storage slot information from the Forge artifacts for a given contract. + function getInitializedSlot(string memory _contractName) internal returns (StorageSlot memory slot_) { + string memory storageLayout = getStorageLayout(_contractName); + + string[] memory command = new string[](3); + command[0] = Executables.bash; + command[1] = "-c"; + command[2] = string.concat( + Executables.echo, + " '", + storageLayout, + "'", + " | ", + Executables.jq, + " '.storage[] | select(.label == \"_initialized\" and .type == \"t_uint8\")'" + ); + bytes memory rawSlot = vm.parseJson(string(vm.ffi(command))); + slot_ = abi.decode(rawSlot, (StorageSlot)); + } + + /// @notice Accepts a filepath and then ensures that the directory + /// exists for the file to live in. + function ensurePath(string memory _path) internal { + (, bytes memory returndata) = + address(vm).call(abi.encodeWithSignature("split(string,string)", _path, string("/"))); + string[] memory outputs = abi.decode(returndata, (string[])); + + string memory path = ""; + for (uint256 i = 0; i < outputs.length - 1; i++) { + path = string.concat(path, outputs[i], "/"); + } + vm.createDir(path, true); + } +} diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol new file mode 100644 index 000000000000..5f5f8a198bb9 --- /dev/null +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -0,0 +1,429 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Script } from "forge-std/Script.sol"; +import { console2 as console } from "forge-std/console2.sol"; + +import { Artifacts } from "scripts/Artifacts.s.sol"; +import { DeployConfig } from "scripts/DeployConfig.s.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; +import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; +import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; +import { FeeVault } from "src/universal/FeeVault.sol"; +import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +import { L1Block } from "src/L2/L1Block.sol"; +import { GovernanceToken } from "src/governance/GovernanceToken.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +interface IInitializable { + function initialize(address _addr) external; +} + +/// @dev The general flow of adding a predeploy is: +/// 1. _setPredeployProxies uses vm.etch to set the Proxy.sol deployed bytecode for proxy address `0x420...000` to +/// `0x420...000 + PROXY_COUNT - 1`. +/// Additionally, the PROXY_ADMIN_ADDRESS and PROXY_IMPLEMENTATION_ADDRESS storage slots are set for the proxy +/// address. +/// 2. `vm.etch` sets the deployed bytecode for each predeploy at the implementation address (i.e. `0xc0d3` +/// namespace). +/// 3. The `initialize` method is called at the implementation address with zero/dummy vaules if the method exists. +/// 4. The `initialize` method is called at the proxy address with actual vaules if the method exists. +/// 5. A `require` check to verify the expected implementation address is set for the proxy. +/// @notice The following safety invariants are used when setting state: +/// 1. `vm.getDeployedBytecode` can only be used with `vm.etch` when there are no side +/// effects in the constructor and no immutables in the bytecode. +/// 2. A contract must be deployed using the `new` syntax if there are immutables in the code. +/// Any other side effects from the init code besides setting the immutables must be cleaned up afterwards. +/// 3. A contract is deployed using the `new` syntax, however it's not proxied and is still expected to exist at +/// a +/// specific implementation address (i.e. `0xc0d3` namespace). In this case we deploy an instance of the +/// contract +/// using `new` syntax, use `contract.code` to retrieve it's deployed bytecode, `vm.etch` the bytecode at the +/// expected implementation address, and `vm.store` to set any storage slots that are +/// expected to be set after a new deployment. Lastly, we reset the account code and storage slots the contract +/// was initially deployed to so it's not included in the `vm.dumpState`. +contract L2Genesis is Script, Artifacts { + uint256 constant PROXY_COUNT = 2048; + uint256 constant PRECOMPILE_COUNT = 256; + DeployConfig public constant cfg = + DeployConfig(address(uint160(uint256(keccak256(abi.encode("optimism.deployconfig")))))); + + /// @notice The storage slot that holds the address of a proxy implementation. + /// @dev `bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)` + bytes32 internal constant PROXY_IMPLEMENTATION_ADDRESS = + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + + /// @notice The storage slot that holds the address of the owner. + /// @dev `bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)` + bytes32 internal constant PROXY_ADMIN_ADDRESS = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + uint80 internal constant DEV_ACCOUNT_FUND_AMT = 10_000 ether; + /// @notice Default Anvil dev accounts. Only funded if `cfg.fundDevAccounts == true`. + address[10] internal devAccounts = [ + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8, + 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC, + 0x90F79bf6EB2c4f870365E785982E1f101E93b906, + 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65, + 0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc, + 0x976EA74026E726554dB657fA54763abd0C3a0aa9, + 0x14dC79964da2C08b23698B3D3cc7Ca32193d9955, + 0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f, + 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 + ]; + + string internal outfile; + + /// @dev Reads the deploy config, sets `outfile` which is where the `vm.dumpState` will be saved to, and + /// loads in the addresses for the L1 contract deployments. + function setUp() public override { + Artifacts.setUp(); + + string memory path = string.concat(vm.projectRoot(), "/deploy-config/", deploymentContext, ".json"); + vm.etch(address(cfg), vm.getDeployedCode("DeployConfig.s.sol:DeployConfig")); + vm.label(address(cfg), "DeployConfig"); + vm.allowCheatcodes(address(cfg)); + cfg.read(path); + + outfile = string.concat(vm.projectRoot(), "/deployments/", deploymentContext, "/genesis-l2.json"); + + _loadAddresses(string.concat(vm.projectRoot(), "/deployments/", deploymentContext, "/.deploy")); + } + + /// @dev Sets the precompiles, proxies, and the implementation accounts to be `vm.dumpState` + /// to generate a L2 genesis alloc. + /// @notice The alloc object is sorted numerically by address. + function run() public { + _dealEthToPrecompiles(); + _setPredeployProxies(); + _setPredeployImplementations(); + + if (cfg.fundDevAccounts()) { + _fundDevAccounts(); + } + + /// Reset so its not included state dump + vm.etch(address(cfg), ""); + + vm.dumpState(outfile); + _sortJsonByKeys(outfile); + } + + /// @notice Give all of the precompiles 1 wei so that they are + /// not considered empty accounts. + function _dealEthToPrecompiles() internal { + for (uint256 i; i < PRECOMPILE_COUNT; i++) { + vm.deal(address(uint160(i)), 1); + } + } + + /// @dev Set up the accounts that correspond to the predeploys. + /// The Proxy bytecode should be set. All proxied predeploys should have + /// the 1967 admin slot set to the ProxyAdmin predeploy. All defined predeploys + /// should have their implementations set. + function _setPredeployProxies() internal { + bytes memory code = vm.getDeployedCode("Proxy.sol:Proxy"); + uint160 prefix = uint160(0x420) << 148; + + console.log( + "Setting proxy deployed bytecode for addresses in range %s through %s", + address(prefix | uint160(0)), + address(prefix | uint160(PROXY_COUNT - 1)) + ); + for (uint256 i = 0; i < PROXY_COUNT; i++) { + address addr = address(prefix | uint160(i)); + if (_notProxied(addr)) { + continue; + } + + vm.etch(addr, code); + vm.store(addr, PROXY_ADMIN_ADDRESS, bytes32(uint256(uint160(Predeploys.PROXY_ADMIN)))); + + if (_isDefinedPredeploy(addr)) { + address implementation = _predeployToCodeNamespace(addr); + console.log("Setting proxy %s implementation: %s", addr, implementation); + vm.store(addr, PROXY_IMPLEMENTATION_ADDRESS, bytes32(uint256(uint160(implementation)))); + } + } + } + + /// @notice LEGACY_ERC20_ETH is not being predeployed since it's been deprecated. + /// @dev Sets all the implementations for the predeploy proxies. For contracts without proxies, + /// sets the deployed bytecode at their expected predeploy address. + function _setPredeployImplementations() internal { + _setLegacyMessagePasser(); + _setDeployerWhitelist(); + _setWETH9(); + _setL2StandardBridge(); + _setL2CrossDomainMessenger(); + _setSequencerFeeVault(); + _setOptimismMintableERC20Factory(); + _setL1BlockNumber(); + _setGasPriceOracle(); + _setGovernanceToken(); + _setL1Block(); + } + + /// @notice This predeploy is following the saftey invariant #1. + function _setLegacyMessagePasser() internal { + _setImplementationCode(Predeploys.LEGACY_MESSAGE_PASSER, "LegacyMessagePasser"); + } + + /// @notice This predeploy is following the saftey invariant #1. + function _setDeployerWhitelist() internal { + _setImplementationCode(Predeploys.DEPLOYER_WHITELIST, "DeployerWhitelist"); + } + + /// @notice This predeploy is following the saftey invariant #1. + /// Contract metadata hash appended to deployed bytecode will differ + /// from previous L2 genesis output. + /// This contract is NOT proxied. + /// @dev We're manually setting storage slots because we need to deployment to be at + /// the address `Predeploys.WETH9`, so we can't just deploy a new instance of `WETH9`. + function _setWETH9() internal { + console.log("Setting %s implementation at: %s", "WETH9", Predeploys.WETH9); + vm.etch(Predeploys.WETH9, vm.getDeployedCode("WETH9.sol:WETH9")); + + vm.store( + Predeploys.WETH9, + /// string public name + hex"0000000000000000000000000000000000000000000000000000000000000000", + /// "Wrapped Ether" + hex"577261707065642045746865720000000000000000000000000000000000001a" + ); + vm.store( + Predeploys.WETH9, + /// string public symbol + hex"0000000000000000000000000000000000000000000000000000000000000001", + /// "WETH" + hex"5745544800000000000000000000000000000000000000000000000000000008" + ); + vm.store( + Predeploys.WETH9, + // uint8 public decimals + hex"0000000000000000000000000000000000000000000000000000000000000002", + /// 18 + hex"0000000000000000000000000000000000000000000000000000000000000012" + ); + } + + /// @notice This predeploy is following the saftey invariant #1. + /// We're initializing the implementation with `address(0)` so + /// it's not left uninitialized. After `initialize` is called on the + /// proxy to set the storage slot with the expected value. + function _setL2StandardBridge() internal { + address impl = _setImplementationCode(Predeploys.L2_STANDARD_BRIDGE, "L2StandardBridge"); + + L2StandardBridge(payable(impl)).initialize(L1StandardBridge(payable(address(0)))); + + L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).initialize( + L1StandardBridge(mustGetAddress("L1StandardBridgeProxy")) + ); + + _checkL2StandardBridge(impl); + } + + /// @notice This predeploy is following the saftey invariant #1. + /// We're initializing the implementation with `address(0)` so + /// it's not left uninitialized. After `initialize` is called on the + /// proxy to set the storage slot with the expected value. + function _setL2CrossDomainMessenger() internal { + address impl = _setImplementationCode(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger"); + + L2CrossDomainMessenger(impl).initialize(L1CrossDomainMessenger(address(0))); + + L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER).initialize( + L1CrossDomainMessenger(mustGetAddress("L1CrossDomainMessengerProxy")) + ); + + _checkL2CrossDomainMessenger(impl); + } + + /// @notice This predeploy is following the saftey invariant #2, + /// because the constructor args are non-static L1 contract + /// addresses that are being read from the deploy config + /// that are set as immutables. + /// @dev Because the constructor args are stored as immutables, + /// we don't have to worry about setting storage slots. + function _setSequencerFeeVault() internal { + SequencerFeeVault vault = new SequencerFeeVault({ + _recipient: cfg.sequencerFeeVaultRecipient(), + _minWithdrawalAmount: cfg.sequencerFeeVaultMinimumWithdrawalAmount(), + _withdrawalNetwork: FeeVault.WithdrawalNetwork(cfg.sequencerFeeVaultWithdrawalNetwork()) + }); + + address impl = _predeployToCodeNamespace(Predeploys.SEQUENCER_FEE_WALLET); + console.log("Setting %s implementation at: %s", "SequencerFeeVault", impl); + vm.etch(impl, address(vault).code); + + /// Reset so its not included state dump + vm.etch(address(vault), ""); + vm.resetNonce(address(vault)); + + _checkSequencerFeeVault(impl); + } + + /// @notice This predeploy is following the saftey invariant #1. + /// We're initializing the implementation with `address(0)` so + /// it's not left uninitialized. After `initialize` is called on the + /// proxy to set the storage slot with the expected value. + function _setOptimismMintableERC20Factory() internal { + address impl = + _setImplementationCode(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, "OptimismMintableERC20Factory"); + + OptimismMintableERC20Factory(impl).initialize(address(0)); + + OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).initialize( + Predeploys.L2_STANDARD_BRIDGE + ); + + _checkOptimismMintableERC20Factory(impl); + } + + /// @notice This predeploy is following the saftey invariant #1. + /// This contract has no initializer. + function _setL1BlockNumber() internal { + _setImplementationCode(Predeploys.L1_BLOCK_NUMBER, "L1BlockNumber"); + } + + /// @notice This predeploy is following the saftey invariant #1. + /// This contract has no initializer. + function _setGasPriceOracle() internal { + _setImplementationCode(Predeploys.GAS_PRICE_ORACLE, "GasPriceOracle"); + } + + /// @notice This predeploy is following the saftey invariant #3. + function _setGovernanceToken() internal { + if (!cfg.enableGovernance()) { + console.log("Governance not enabled, skipping setting governanace token"); + return; + } + + GovernanceToken token = new GovernanceToken(); + console.log("Setting %s implementation at: %s", "GovernanceToken", Predeploys.GOVERNANCE_TOKEN); + vm.etch(Predeploys.GOVERNANCE_TOKEN, address(token).code); + + bytes32 _nameSlot = hex"0000000000000000000000000000000000000000000000000000000000000003"; + bytes32 _symbolSlot = hex"0000000000000000000000000000000000000000000000000000000000000004"; + bytes32 _ownerSlot = hex"000000000000000000000000000000000000000000000000000000000000000a"; + + vm.store(Predeploys.GOVERNANCE_TOKEN, _nameSlot, vm.load(address(token), _nameSlot)); + vm.store(Predeploys.GOVERNANCE_TOKEN, _symbolSlot, vm.load(address(token), _symbolSlot)); + vm.store(Predeploys.GOVERNANCE_TOKEN, _ownerSlot, bytes32(uint256(uint160(cfg.governanceTokenOwner())))); + + /// Reset so its not included state dump + vm.etch(address(token), ""); + vm.resetNonce(address(token)); + } + + /// @notice This predeploy is following the saftey invariant #1. + /// This contract has no initializer. + /// @dev Previously the initial L1 attributes was set at genesis, to simplify, + /// they no longer are so the resulting storage slots are no longer set. + function _setL1Block() internal { + _setImplementationCode(Predeploys.L1_BLOCK_ATTRIBUTES, "L1Block"); + } + + /// @dev Returns true if the address is not proxied. + function _notProxied(address _addr) internal pure returns (bool) { + return _addr == Predeploys.GOVERNANCE_TOKEN || _addr == Predeploys.WETH9; + } + + /// @dev Returns true if the address is a predeploy. + function _isDefinedPredeploy(address _addr) internal pure returns (bool) { + return _addr == Predeploys.L2_TO_L1_MESSAGE_PASSER || _addr == Predeploys.L2_CROSS_DOMAIN_MESSENGER + || _addr == Predeploys.L2_STANDARD_BRIDGE || _addr == Predeploys.L2_ERC721_BRIDGE + || _addr == Predeploys.SEQUENCER_FEE_WALLET || _addr == Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY + || _addr == Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY || _addr == Predeploys.L1_BLOCK_ATTRIBUTES + || _addr == Predeploys.GAS_PRICE_ORACLE || _addr == Predeploys.DEPLOYER_WHITELIST || _addr == Predeploys.WETH9 + || _addr == Predeploys.L1_BLOCK_NUMBER || _addr == Predeploys.LEGACY_MESSAGE_PASSER + || _addr == Predeploys.PROXY_ADMIN || _addr == Predeploys.BASE_FEE_VAULT || _addr == Predeploys.L1_FEE_VAULT + || _addr == Predeploys.GOVERNANCE_TOKEN || _addr == Predeploys.SCHEMA_REGISTRY || _addr == Predeploys.EAS; + } + + /// @dev Function to compute the expected address of the predeploy implementation + /// in the genesis state. + function _predeployToCodeNamespace(address _addr) internal pure returns (address) { + return address( + uint160(uint256(uint160(_addr)) & 0xffff | uint256(uint160(0xc0D3C0d3C0d3C0D3c0d3C0d3c0D3C0d3c0d30000))) + ); + } + + function _setImplementationCode(address _addr, string memory _name) internal returns (address) { + address impl = _predeployToCodeNamespace(_addr); + console.log("Setting %s implementation at: %s", _name, impl); + vm.etch(impl, vm.getDeployedCode(string.concat(_name, ".sol:", _name))); + + _verifyProxyImplementationAddress(_addr, impl); + + return impl; + } + + /// @dev Function to verify the expected implementation address is set for the respective proxy. + function _verifyProxyImplementationAddress(address _proxy, address _impl) internal view { + require( + EIP1967Helper.getImplementation(_proxy) == _impl, + "Expected different address at Proxys PROXY_IMPLEMENTATION_ADDRESS storage slot" + ); + } + + /// @dev Function to verify that a contract was initialized, and can't be reinitialized. + /// @notice There isn't a good way to know if the resulting revering is due to abi mismatch + /// or because it's already been initialized + function _verifyCantReinitialize(address _contract, address _arg) internal { + vm.expectRevert("Initializable: contract is already initialized"); + IInitializable(_contract).initialize(_arg); + } + + /// @dev Helper function to sort the genesis alloc numerically by address. + function _sortJsonByKeys(string memory _path) internal { + string[] memory commands = new string[](3); + commands[0] = "bash"; + commands[1] = "-c"; + commands[2] = string.concat("cat <<< $(jq -S '.' ", _path, ") > ", _path); + vm.ffi(commands); + } + + function _fundDevAccounts() internal { + for (uint256 i; i < devAccounts.length; i++) { + console.log("Funding dev account %s with %s ETH", devAccounts[i], DEV_ACCOUNT_FUND_AMT / 1e18); + vm.deal(devAccounts[i], DEV_ACCOUNT_FUND_AMT); + } + + _checkDevAccountsFunded(); + } + + ////////////////////////////////////////////////////// + /// Post Checks + ////////////////////////////////////////////////////// + function _checkL2StandardBridge(address _impl) internal { + _verifyCantReinitialize(_impl, address(0)); + _verifyCantReinitialize(Predeploys.L2_STANDARD_BRIDGE, mustGetAddress("L1StandardBridgeProxy")); + } + + function _checkL2CrossDomainMessenger(address _impl) internal { + _verifyCantReinitialize(_impl, address(0)); + _verifyCantReinitialize(Predeploys.L2_CROSS_DOMAIN_MESSENGER, mustGetAddress("L1CrossDomainMessengerProxy")); + } + + function _checkSequencerFeeVault(address _impl) internal view { + _verifyProxyImplementationAddress(Predeploys.SEQUENCER_FEE_WALLET, _impl); + } + + function _checkOptimismMintableERC20Factory(address _impl) internal { + _verifyCantReinitialize(_impl, address(0)); + _verifyCantReinitialize(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, Predeploys.L2_STANDARD_BRIDGE); + } + + function _checkDevAccountsFunded() internal view { + for (uint256 i; i < devAccounts.length; i++) { + if (devAccounts[i].balance != DEV_ACCOUNT_FUND_AMT) { + revert( + string.concat("Dev account not funded with expected amount of ETH: ", vm.toString(devAccounts[i])) + ); + } + } + } +} diff --git a/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol b/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol index 900d6b898950..adf2e88fe3ae 100644 --- a/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol +++ b/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol @@ -34,6 +34,26 @@ contract PeripheryDeployConfig is Script { address public faucetOffchainAuthModuleAdmin; uint256 public faucetOffchainAuthModuleTtl; uint256 public faucetOffchainAuthModuleAmount; + bool public installOpChainFaucetsDrips; + bool public archivePreviousOpChainFaucetsDrips; + uint256 public smallOpChainFaucetDripValue; + uint256 public smallOpChainFaucetDripInterval; + uint256 public largeOpChainFaucetDripValue; + uint256 public largeOpChainFaucetDripInterval; + uint256 public opChainAdminWalletDripValue; + uint256 public opChainAdminWalletDripInterval; + address public opL1BridgeAddress; + address public baseL1BridgeAddress; + address public zoraL1BridgeAddress; + address public pgnL1BridgeAddress; + address public orderlyL1BridgeAddress; + address public modeL1BridgeAddress; + address public lyraL1BridgeAddress; + address public liskL1BridgeAddress; + address[6] public smallFaucetsL1BridgeAddresses; + address[2] public largeFaucetsL1BridgeAddresses; + uint256 public dripVersion; + uint256 public previousDripVersion; constructor(string memory _path) { console.log("PeripheryDeployConfig: reading file %s", _path); @@ -66,5 +86,39 @@ contract PeripheryDeployConfig is Script { faucetOffchainAuthModuleAdmin = stdJson.readAddress(_json, "$.faucetOffchainAuthModuleAdmin"); faucetOffchainAuthModuleTtl = stdJson.readUint(_json, "$.faucetOffchainAuthModuleTtl"); faucetOffchainAuthModuleAmount = stdJson.readUint(_json, "$.faucetOffchainAuthModuleAmount"); + installOpChainFaucetsDrips = stdJson.readBool(_json, "$.installOpChainFaucetsDrips"); + archivePreviousOpChainFaucetsDrips = stdJson.readBool(_json, "$.archivePreviousOpChainFaucetsDrips"); + opL1BridgeAddress = stdJson.readAddress(_json, "$.opL1BridgeAddress"); + baseL1BridgeAddress = stdJson.readAddress(_json, "$.baseL1BridgeAddress"); + zoraL1BridgeAddress = stdJson.readAddress(_json, "$.zoraL1BridgeAddress"); + pgnL1BridgeAddress = stdJson.readAddress(_json, "$.pgnL1BridgeAddress"); + orderlyL1BridgeAddress = stdJson.readAddress(_json, "$.orderlyL1BridgeAddress"); + liskL1BridgeAddress = stdJson.readAddress(_json, "$.liskL1BridgeAddress"); + modeL1BridgeAddress = stdJson.readAddress(_json, "$.modeL1BridgeAddress"); + lyraL1BridgeAddress = stdJson.readAddress(_json, "$.lyraL1BridgeAddress"); + dripVersion = stdJson.readUint(_json, "$.dripVersion"); + previousDripVersion = stdJson.readUint(_json, "$.previousDripVersion"); + smallOpChainFaucetDripValue = stdJson.readUint(_json, "$.smallOpChainFaucetDripValue"); + smallOpChainFaucetDripInterval = stdJson.readUint(_json, "$.smallOpChainFaucetDripInterval"); + largeOpChainFaucetDripValue = stdJson.readUint(_json, "$.largeOpChainFaucetDripValue"); + largeOpChainFaucetDripInterval = stdJson.readUint(_json, "$.largeOpChainFaucetDripInterval"); + opChainAdminWalletDripValue = stdJson.readUint(_json, "$.opChainAdminWalletDripValue"); + opChainAdminWalletDripInterval = stdJson.readUint(_json, "$.opChainAdminWalletDripInterval"); + largeFaucetsL1BridgeAddresses[0] = opL1BridgeAddress; + largeFaucetsL1BridgeAddresses[1] = baseL1BridgeAddress; + smallFaucetsL1BridgeAddresses[0] = zoraL1BridgeAddress; + smallFaucetsL1BridgeAddresses[1] = pgnL1BridgeAddress; + smallFaucetsL1BridgeAddresses[2] = orderlyL1BridgeAddress; + smallFaucetsL1BridgeAddresses[3] = modeL1BridgeAddress; + smallFaucetsL1BridgeAddresses[4] = lyraL1BridgeAddress; + smallFaucetsL1BridgeAddresses[5] = liskL1BridgeAddress; + } + + function getSmallFaucetsL1BridgeAddressesCount() public view returns (uint256 count) { + return smallFaucetsL1BridgeAddresses.length; + } + + function getLargeFaucetsL1BridgeAddressesCount() public view returns (uint256 count) { + return largeFaucetsL1BridgeAddresses.length; } } diff --git a/packages/contracts-bedrock/scripts/SemverLock.s.sol b/packages/contracts-bedrock/scripts/SemverLock.s.sol index 451283c9ab88..e940431b091d 100644 --- a/packages/contracts-bedrock/scripts/SemverLock.s.sol +++ b/packages/contracts-bedrock/scripts/SemverLock.s.sol @@ -53,13 +53,12 @@ contract SemverLock is Script { // Parse the artifact to get the contract's initcode hash. bytes memory initCode = vm.getCode(string.concat(artifactsDir, "/", contractName, ".sol/", fileName)); - // Serialize the source hash in JSON. - string memory j = vm.serializeBytes32(out, _files[i], keccak256(abi.encodePacked(fileContents, initCode))); + // Serialize the initcode hash + sourcecode hash in JSON. + vm.serializeBytes32(_files[i], "initCodeHash", keccak256(initCode)); + string memory obj = vm.serializeBytes32(_files[i], "sourceCodeHash", keccak256(bytes(fileContents))); - // If this is the last file, set the output. - if (i == _files.length - 1) { - out = j; - } + // Serialize the map from the file name -> initcode hash + sourcecode hash in JSON. + out = vm.serializeString("", _files[i], obj); } // Write the semver lockfile. diff --git a/packages/contracts-bedrock/scripts/Types.sol b/packages/contracts-bedrock/scripts/Types.sol new file mode 100644 index 000000000000..c8b48dc1e704 --- /dev/null +++ b/packages/contracts-bedrock/scripts/Types.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +library Types { + /// @notice Represents a set of L1 contracts. Used to represent a set of proxies. + struct ContractSet { + address L1CrossDomainMessenger; + address L1StandardBridge; + address L2OutputOracle; + address DisputeGameFactory; + address DelayedWETH; + address AnchorStateRegistry; + address OptimismMintableERC20Factory; + address OptimismPortal; + address OptimismPortal2; + address SystemConfig; + address L1ERC721Bridge; + address ProtocolVersions; + address SuperchainConfig; + } +} diff --git a/packages/contracts-bedrock/scripts/autogen/generate-invariant-docs.ts b/packages/contracts-bedrock/scripts/autogen/generate-invariant-docs.ts new file mode 100644 index 000000000000..2c01e2617ef4 --- /dev/null +++ b/packages/contracts-bedrock/scripts/autogen/generate-invariant-docs.ts @@ -0,0 +1,170 @@ +import fs from 'fs' +import path from 'path' + +const ROOT_DIR = path.join(__dirname, '..', '..') +const BASE_INVARIANTS_DIR = path.join(ROOT_DIR, 'test', 'invariants') +const BASE_DOCS_DIR = path.join(ROOT_DIR, 'invariant-docs') +const BASE_INVARIANT_GH_URL = '../test/invariants/' +const NATSPEC_INV = '@custom:invariant' + +// Represents an invariant test contract +type Contract = { + name: string + fileName: string + docs: InvariantDoc[] +} + +// Represents the documentation of an invariant +type InvariantDoc = { + header?: string + desc?: string + lineNo?: number +} + +const writtenFiles = [] + +// Lazy-parses all test files in the `test/invariants` directory +// to generate documentation on all invariant tests. +const docGen = (dir: string): void => { + // Grab all files within the invariants test dir + const files = fs.readdirSync(dir) + + // Array to store all found invariant documentation comments. + const docs: Contract[] = [] + + for (const fileName of files) { + // Read the contents of the invariant test file. + const fileContents = fs.readFileSync(path.join(dir, fileName)).toString() + + // Split the file into individual lines and trim whitespace. + const lines = fileContents.split('\n').map((line: string) => line.trim()) + + // Create an object to store all invariant test docs for the current contract + const name = fileName.replace('.t.sol', '') + const contract: Contract = { name, fileName, docs: [] } + + let currentDoc: InvariantDoc + + // Loop through all lines to find comments. + for (let i = 0; i < lines.length; i++) { + let line = lines[i] + + // We have an invariant doc + if (line.startsWith(`/// ${NATSPEC_INV}`)) { + // Assign the header of the invariant doc. + // TODO: Handle ambiguous case for `INVARIANT: ` prefix. + currentDoc = { + header: line.replace(`/// ${NATSPEC_INV}`, '').trim(), + desc: '', + } + + // If the header is multi-line, continue appending to the `currentDoc`'s header. + line = lines[++i] + while (line.startsWith(`///`) && line.trim() !== '///') { + currentDoc.header += ` ${line.replace(`///`, '').trim()}` + line = lines[++i] + } + + // Process the description + while ((line = lines[++i]).startsWith('///')) { + line = line.replace('///', '').trim() + + // If the line has any contents, insert it into the desc. + // Otherwise, consider it a linebreak. + currentDoc.desc += line.length > 0 ? `${line} ` : '\n' + } + + // Set the line number of the test + currentDoc.lineNo = i + 1 + + // Add the doc to the contract + contract.docs.push(currentDoc) + } + } + + // Add the contract to the array of docs + docs.push(contract) + } + + for (const contract of docs) { + const fileName = path.join(BASE_DOCS_DIR, `${contract.name}.md`) + const alreadyWritten = writtenFiles.includes(fileName) + + // If the file has already been written, append the extra docs to the end. + // Otherwise, write the file from scratch. + fs.writeFileSync( + fileName, + alreadyWritten + ? `${fs.readFileSync(fileName)}\n${renderContractDoc(contract, false)}` + : renderContractDoc(contract, true) + ) + + // If the file was just written for the first time, add it to the list of written files. + if (!alreadyWritten) { + writtenFiles.push(fileName) + } + } + + console.log( + `Generated invariant test documentation for:\n - ${ + docs.length + } contracts\n - ${docs.reduce( + (acc: number, contract: Contract) => acc + contract.docs.length, + 0 + )} invariant tests\nsuccessfully!` + ) +} + +// Generate a table of contents for all invariant docs and place it in the README. +const tocGen = (): void => { + const autoTOCPrefix = '\n' + const autoTOCPostfix = '\n' + + // Grab the name of all markdown files in `BASE_DOCS_DIR` except for `README.md`. + const files = fs + .readdirSync(BASE_DOCS_DIR) + .filter((fileName: string) => fileName !== 'README.md') + + // Generate a table of contents section. + const tocList = files + .map( + (fileName: string) => `- [${fileName.replace('.md', '')}](./${fileName})` + ) + .join('\n') + const toc = `${autoTOCPrefix}\n## Table of Contents\n${tocList}\n${autoTOCPostfix}` + + // Write the table of contents to the README. + const readmeContents = fs + .readFileSync(path.join(BASE_DOCS_DIR, 'README.md')) + .toString() + const above = readmeContents.split(autoTOCPrefix)[0] + const below = readmeContents.split(autoTOCPostfix)[1] + fs.writeFileSync( + path.join(BASE_DOCS_DIR, 'README.md'), + `${above}${toc}${below}` + ) +} + +// Render a `Contract` object into valid markdown. +const renderContractDoc = (contract: Contract, header: boolean): string => { + const _header = header ? `# \`${contract.name}\` Invariants\n` : '' + const docs = contract.docs + .map((doc: InvariantDoc) => { + const line = `${contract.fileName}#L${doc.lineNo}` + return `## ${doc.header}\n**Test:** [\`${line}\`](${BASE_INVARIANT_GH_URL}${line})\n\n${doc.desc}` + }) + .join('\n\n') + return `${_header}\n${docs}` +} + +// Generate the docs + +// Forge +console.log('Generating docs for forge invariants...') +docGen(BASE_INVARIANTS_DIR) + +// New line +console.log() + +// Generate an updated table of contents +tocGen() diff --git a/packages/contracts-bedrock/scripts/autogen/generate-snapshots.ts b/packages/contracts-bedrock/scripts/autogen/generate-snapshots.ts new file mode 100644 index 000000000000..19c5e18740a9 --- /dev/null +++ b/packages/contracts-bedrock/scripts/autogen/generate-snapshots.ts @@ -0,0 +1,156 @@ +import fs from 'fs' +import path from 'path' + +const root = path.join(__dirname, '..', '..') +const outdir = process.argv[2] || path.join(root, 'snapshots') +const forgeArtifactsDir = path.join(root, 'forge-artifacts') + +const getAllContractsSources = (): Array => { + const paths = [] + const readFilesRecursively = (dir: string) => { + const files = fs.readdirSync(dir) + + for (const file of files) { + const filePath = path.join(dir, file) + const fileStat = fs.statSync(filePath) + + if (fileStat.isDirectory()) { + readFilesRecursively(filePath) + } else { + paths.push(filePath) + } + } + } + readFilesRecursively(path.join(root, 'src')) + + return paths + .filter((x) => x.endsWith('.sol')) + .map((p: string) => path.basename(p)) + .sort() +} + +type ForgeArtifact = { + abi: object + ast: { + nodeType: string + nodes: any[] + } + storageLayout: { + storage: [{ type: string; label: string; offset: number; slot: number }] + types: { [key: string]: { label: string; numberOfBytes: number } } + } + bytecode: { + object: string + } +} + +type AbiSpecStorageLayoutEntry = { + label: string + slot: number + offset: number + bytes: number + type: string +} +const sortKeys = (obj: any) => { + if (typeof obj !== 'object' || obj === null) { + return obj + } + return Object.keys(obj) + .sort() + .reduce( + (acc, key) => { + acc[key] = sortKeys(obj[key]) + return acc + }, + Array.isArray(obj) ? [] : {} + ) +} + +// ContractName.0.9.8.json -> ContractName.sol +// ContractName.json -> ContractName.sol +const parseArtifactName = (artifactVersionFile: string): string => { + const match = artifactVersionFile.match(/(.*?)\.([0-9]+\.[0-9]+\.[0-9]+)?/) + if (!match) { + throw new Error(`Invalid artifact file name: ${artifactVersionFile}`) + } + return match[1] +} + +const main = async () => { + console.log(`writing abi and storage layout snapshots to ${outdir}`) + + const storageLayoutDir = path.join(outdir, 'storageLayout') + const abiDir = path.join(outdir, 'abi') + fs.mkdirSync(storageLayoutDir, { recursive: true }) + fs.mkdirSync(abiDir, { recursive: true }) + + const contractSources = getAllContractsSources() + const knownAbis = {} + + for (const contractFile of contractSources) { + const contractArtifacts = path.join(forgeArtifactsDir, contractFile) + for (const name of fs.readdirSync(contractArtifacts)) { + const data = fs.readFileSync(path.join(contractArtifacts, name)) + const artifact: ForgeArtifact = JSON.parse(data.toString()) + + const contractName = parseArtifactName(name) + + // HACK: This is a hack to ignore libraries and abstract contracts. Not robust against changes to solc's internal ast repr + const isContract = artifact.ast.nodes.some((node: any) => { + return ( + node.nodeType === 'ContractDefinition' && + node.name === contractName && + node.contractKind === 'contract' && + (node.abstract === undefined || // solc < 0.6 doesn't have explicit abstract contracts + node.abstract === false) + ) + }) + if (!isContract) { + console.log(`ignoring library/interface ${contractName}`) + continue + } + + const storageLayout: AbiSpecStorageLayoutEntry[] = [] + for (const storageEntry of artifact.storageLayout.storage) { + // convert ast-based type to solidity type + const typ = artifact.storageLayout.types[storageEntry.type] + if (typ === undefined) { + throw new Error( + `undefined type for ${contractName}:${storageEntry.label}` + ) + } + storageLayout.push({ + label: storageEntry.label, + bytes: typ.numberOfBytes, + offset: storageEntry.offset, + slot: storageEntry.slot, + type: typ.label, + }) + } + + if (knownAbis[contractName] === undefined) { + knownAbis[contractName] = artifact.abi + } else if ( + JSON.stringify(knownAbis[contractName]) !== JSON.stringify(artifact.abi) + ) { + throw Error( + `detected multiple artifact versions with different ABIs for ${contractFile}` + ) + } else { + console.log(`detected multiple artifacts for ${contractName}`) + } + + // Sort snapshots for easier manual inspection + fs.writeFileSync( + `${abiDir}/${contractName}.json`, + JSON.stringify(sortKeys(artifact.abi), null, 2) + ) + fs.writeFileSync( + `${storageLayoutDir}/${contractName}.json`, + JSON.stringify(sortKeys(storageLayout), null, 2) + ) + } + } +} + +main() diff --git a/packages/contracts-bedrock/scripts/check-deploy-configs.sh b/packages/contracts-bedrock/scripts/check-deploy-configs.sh deleted file mode 100755 index 36c5dce1aa10..000000000000 --- a/packages/contracts-bedrock/scripts/check-deploy-configs.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -# This script is used to check for valid deploy configs. -# It should check all configs and return a non-zero exit code if any of them are invalid. -# getting-started.json isn't valid JSON so its skipped. - -code=$? - -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -CONTRACTS_BASE=$(dirname $SCRIPT_DIR) -MONOREPO_BASE=$(dirname $(dirname $CONTRACTS_BASE)) - -for config in $CONTRACTS_BASE/deploy-config/*.json; do - if grep -q "getting-started" <<< "$config"; then - echo "Skipping getting-started.json" - continue - fi - - go run $MONOREPO_BASE/op-chain-ops/cmd/check-deploy-config/main.go --path $config - [ $? -eq 0 ] || code=$? -done - -exit $code diff --git a/packages/contracts-bedrock/scripts/checks/check-deploy-configs.sh b/packages/contracts-bedrock/scripts/checks/check-deploy-configs.sh new file mode 100755 index 000000000000..0c6071fcaca9 --- /dev/null +++ b/packages/contracts-bedrock/scripts/checks/check-deploy-configs.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# This script is used to check for valid deploy configs. +# It should check all configs and return a non-zero exit code if any of them are invalid. +# getting-started.json isn't valid JSON so its skipped. + +code=0 + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +CONTRACTS_BASE=$(dirname "$(dirname "$SCRIPT_DIR")") +MONOREPO_BASE=$(dirname "$(dirname "$CONTRACTS_BASE")") + +for config in "$CONTRACTS_BASE"/deploy-config/*.json; do + # shellcheck disable=SC2086 + if ! go run "$MONOREPO_BASE/op-chain-ops/cmd/check-deploy-config/main.go" --path "$config"; then + code=1 + fi +done + +exit $code diff --git a/packages/contracts-bedrock/scripts/checks/check-foundry-install.sh b/packages/contracts-bedrock/scripts/checks/check-foundry-install.sh new file mode 100755 index 000000000000..e7edc7db270e --- /dev/null +++ b/packages/contracts-bedrock/scripts/checks/check-foundry-install.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +CONTRACTS_BASE=$(dirname "$(dirname "$SCRIPT_DIR")") +MONOREPO_BASE=$(dirname "$(dirname "$CONTRACTS_BASE")") +VERSIONS_FILE="${MONOREPO_BASE}/versions.json" + +if ! command -v forge &> /dev/null +then + # shellcheck disable=SC2006 + echo "Is Foundry not installed? Consider installing via pnpm install:foundry" >&2 + exit 1 +fi + +# Check VERSIONS_FILE has expected foundry property +if ! jq -e '.foundry' "$VERSIONS_FILE" &> /dev/null; then + echo "'foundry' is missing from $VERSIONS_FILE" >&2 + exit 1 +fi + +# Extract the expected foundry version from versions.json +EXPECTED_VERSION=$(jq -r '.foundry' "$VERSIONS_FILE" | cut -c 1-7) +if [ -z "$EXPECTED_VERSION" ]; then + echo "Unable to extract Foundry version from $VERSIONS_FILE" >&2 + exit 1 +fi + +# Extract the installed forge version +INSTALLED_VERSION=$(forge --version | grep -o '[a-f0-9]\{7\}' | head -n 1) + +# Compare the installed timestamp with the expected timestamp +if [ "$INSTALLED_VERSION" = "$EXPECTED_VERSION" ]; then + echo "Foundry version matches the expected version." +else + echo "Mismatch between installed Foundry version ($INSTALLED_VERSION) and expected version ($EXPECTED_VERSION)." + echo "Your version of Foundry may either not be up to date, or it could be a later version." + echo "Running pnpm update:foundry will install the expected version." +fi diff --git a/packages/contracts-bedrock/scripts/checks/check-snapshots.sh b/packages/contracts-bedrock/scripts/checks/check-snapshots.sh new file mode 100755 index 000000000000..1aedf049fabf --- /dev/null +++ b/packages/contracts-bedrock/scripts/checks/check-snapshots.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# Generate the snapshots +pnpm snapshots + +# Check if the generated snapshots are different from the committed snapshots +if git diff --exit-code snapshots > /dev/null; then + [ -z "$(git ls-files --others --exclude-standard snapshots)" ] || exit 1 +else + exit 1 +fi diff --git a/packages/contracts-bedrock/scripts/checks/check-spacers.ts b/packages/contracts-bedrock/scripts/checks/check-spacers.ts new file mode 100644 index 000000000000..8967618131d3 --- /dev/null +++ b/packages/contracts-bedrock/scripts/checks/check-spacers.ts @@ -0,0 +1,152 @@ +import fs from 'fs' +import path from 'path' + +/** + * Directory path to the artifacts. + * Can be configured as the first argument to the script or + * defaults to the forge-artifacts directory. + */ +const directoryPath = + process.argv[2] || path.join(__dirname, '..', '..', 'forge-artifacts') + +/** + * Returns true if the contract should be skipped when inspecting its storage layout. + * This is useful for abstract contracts that are meant to be inherited. + * The two particular targets are: + * - CrossDomainMessengerLegacySpacer0 + * - CrossDomainMessengerLegacySpacer1 + */ +const skipped = (contractName: string): boolean => { + return contractName.includes('CrossDomainMessengerLegacySpacer') +} + +/** + * Parses out variable info from the variable structure in standard compiler json output. + * + * @param variable Variable structure from standard compiler json output. + * @returns Parsed variable info. + */ +const parseVariableInfo = ( + variable: any +): { + name: string + slot: number + offset: number + length: number +} => { + // Figure out the length of the variable. + let variableLength: number + if (variable.type.startsWith('t_mapping')) { + variableLength = 32 + } else if (variable.type.startsWith('t_uint')) { + variableLength = variable.type.match(/uint([0-9]+)/)?.[1] / 8 + } else if (variable.type.startsWith('t_bytes_')) { + variableLength = 32 + } else if (variable.type.startsWith('t_bytes')) { + variableLength = parseInt(variable.type.match(/bytes([0-9]+)/)?.[1], 10) + } else if (variable.type.startsWith('t_address')) { + variableLength = 20 + } else if (variable.type.startsWith('t_bool')) { + variableLength = 1 + } else if (variable.type.startsWith('t_array')) { + // Figure out the size of the type inside of the array + // and then multiply that by the length of the array. + // This does not support recursion multiple times for simplicity + const type = variable.type.match(/^t_array\((\w+)\)/)?.[1] + const info = parseVariableInfo({ + label: variable.label, + offset: variable.offset, + slot: variable.slot, + type, + }) + const size = variable.type.match(/^t_array\(\w+\)([0-9]+)/)?.[1] + variableLength = info.length * parseInt(size, 10) + } else { + throw new Error( + `${variable.label}: unsupported type ${variable.type}, add it to the script` + ) + } + + return { + name: variable.label, + slot: parseInt(variable.slot, 10), + offset: variable.offset, + length: variableLength, + } +} + +/** + * Main logic of the script + * - Ensures that all of the spacer variables are named correctly + */ +const main = async () => { + const paths = [] + + const readFilesRecursively = (dir: string) => { + const files = fs.readdirSync(dir) + + for (const file of files) { + const filePath = path.join(dir, file) + const fileStat = fs.statSync(filePath) + + if (fileStat.isDirectory()) { + readFilesRecursively(filePath) + } else { + paths.push(filePath) + } + } + } + + readFilesRecursively(directoryPath) + + for (const filePath of paths) { + if (filePath.includes('t.sol')) { + continue + } + const raw = fs.readFileSync(filePath, 'utf8').toString() + const artifact = JSON.parse(raw) + + // Handle contracts without storage + const storageLayout = artifact.storageLayout || {} + if (storageLayout.storage) { + for (const variable of storageLayout.storage) { + const fqn = variable.contract + // Skip some abstract contracts + if (skipped(fqn)) { + continue + } + + // Check that the spacers are all named correctly + if (variable.label.startsWith('spacer_')) { + const [, slot, offset, length] = variable.label.split('_') + const variableInfo = parseVariableInfo(variable) + + // Check that the slot is correct. + if (parseInt(slot, 10) !== variableInfo.slot) { + throw new Error( + `${fqn} ${variable.label} is in slot ${variable.slot} but should be in ${slot}` + ) + } + + // Check that the offset is correct. + if (parseInt(offset, 10) !== variableInfo.offset) { + throw new Error( + `${fqn} ${variable.label} is at offset ${variable.offset} but should be at ${offset}` + ) + } + + // Check that the length is correct. + if (parseInt(length, 10) !== variableInfo.length) { + throw new Error( + `${fqn} ${variable.label} is ${variableInfo.length} bytes long but should be ${length}` + ) + } + + console.log(`${fqn}.${variable.label} is valid`) + } + } + } + } +} + +main() diff --git a/packages/contracts-bedrock/scripts/forge-test-names.ts b/packages/contracts-bedrock/scripts/checks/check-test-names.ts similarity index 100% rename from packages/contracts-bedrock/scripts/forge-test-names.ts rename to packages/contracts-bedrock/scripts/checks/check-test-names.ts diff --git a/packages/contracts-bedrock/scripts/deploy.sh b/packages/contracts-bedrock/scripts/deploy.sh new file mode 100755 index 000000000000..bfbd436eb5fa --- /dev/null +++ b/packages/contracts-bedrock/scripts/deploy.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -euo pipefail + +verify_flag="" +if [ -n "${DEPLOY_VERIFY:-}" ]; then + verify_flag="--verify" +fi + +echo "> Deploying contracts" +forge script -vvv scripts/Deploy.s.sol:Deploy --rpc-url "$DEPLOY_ETH_RPC_URL" --broadcast --private-key "$DEPLOY_PRIVATE_KEY" $verify_flag + +if [ -n "${DEPLOY_GENERATE_HARDHAT_ARTIFACTS:-}" ]; then + echo "> Generating hardhat artifacts" + forge script -vvv scripts/Deploy.s.sol:Deploy --sig 'sync()' --rpc-url "$DEPLOY_ETH_RPC_URL" --broadcast --private-key "$DEPLOY_PRIVATE_KEY" +fi diff --git a/packages/contracts-bedrock/scripts/fpac/.gitignore b/packages/contracts-bedrock/scripts/fpac/.gitignore new file mode 100644 index 000000000000..551c08caf2fb --- /dev/null +++ b/packages/contracts-bedrock/scripts/fpac/.gitignore @@ -0,0 +1,2 @@ +prestate-artifacts/ +prestate-artifacts.tar.gz diff --git a/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol b/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol new file mode 100644 index 000000000000..8911c7de1ae0 --- /dev/null +++ b/packages/contracts-bedrock/scripts/fpac/FPACOPS.s.sol @@ -0,0 +1,221 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Proxy } from "src/universal/Proxy.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { AnchorStateRegistry, IAnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { StdAssertions } from "forge-std/StdAssertions.sol"; +import "src/libraries/DisputeTypes.sol"; +import "scripts/Deploy.s.sol"; + +/// @notice Deploys the Fault Proof Alpha Chad contracts. +contract FPACOPS is Deploy, StdAssertions { + //////////////////////////////////////////////////////////////// + // ENTRYPOINTS // + //////////////////////////////////////////////////////////////// + + function deployFPAC(address _proxyAdmin, address _systemOwnerSafe, address _superchainConfigProxy) public { + console.log("Deploying a fresh FPAC system and OptimismPortal2 implementation."); + + prankDeployment("ProxyAdmin", msg.sender); + prankDeployment("SystemOwnerSafe", msg.sender); + prankDeployment("SuperchainConfigProxy", _superchainConfigProxy); + + // Deploy the proxies. + deployERC1967Proxy("DisputeGameFactoryProxy"); + deployERC1967Proxy("DelayedWETHProxy"); + deployERC1967Proxy("AnchorStateRegistryProxy"); + + // Deploy implementations. + deployDisputeGameFactory(); + deployDelayedWETH(); + deployAnchorStateRegistry(); + deployPreimageOracle(); + deployMips(); + + // Deploy the new `OptimismPortal` implementation. + deployOptimismPortal2(); + + // Initialize the proxies. + initializeDisputeGameFactoryProxy(); + initializeDelayedWETHProxy(); + initializeAnchorStateRegistryProxy(); + + // Deploy the Cannon Fault game implementation and set it as game ID = 0. + setCannonFaultGameImplementation({ _allowUpgrade: false }); + // Deploy the Permissioned Cannon Fault game implementation and set it as game ID = 1. + setPermissionedCannonFaultGameImplementation({ _allowUpgrade: false }); + + // Transfer ownership of the DisputeGameFactory to the SystemOwnerSafe, and transfer the administrative rights + // of the DisputeGameFactoryProxy to the ProxyAdmin. + transferDGFOwnershipFinal({ _proxyAdmin: _proxyAdmin, _systemOwnerSafe: _systemOwnerSafe }); + transferWethOwnershipFinal({ _proxyAdmin: _proxyAdmin, _systemOwnerSafe: _systemOwnerSafe }); + transferAnchorStateOwnershipFinal({ _proxyAdmin: _proxyAdmin }); + + // Run post-deployment assertions. + postDeployAssertions({ _proxyAdmin: _proxyAdmin, _systemOwnerSafe: _systemOwnerSafe }); + + // Print overview + printConfigReview(); + } + + //////////////////////////////////////////////////////////////// + // HELPERS // + //////////////////////////////////////////////////////////////// + + /// @notice Initializes the DisputeGameFactoryProxy with the DisputeGameFactory. + function initializeDisputeGameFactoryProxy() internal broadcast { + console.log("Initializing DisputeGameFactoryProxy with DisputeGameFactory."); + + address dgfProxy = mustGetAddress("DisputeGameFactoryProxy"); + Proxy(payable(dgfProxy)).upgradeToAndCall( + mustGetAddress("DisputeGameFactory"), abi.encodeCall(DisputeGameFactory.initialize, msg.sender) + ); + + // Set the initialization bonds for the FaultDisputeGame and PermissionedDisputeGame. + DisputeGameFactory dgf = DisputeGameFactory(dgfProxy); + dgf.setInitBond(GameTypes.CANNON, 0.08 ether); + dgf.setInitBond(GameTypes.PERMISSIONED_CANNON, 0.08 ether); + } + + function initializeDelayedWETHProxy() internal broadcast { + console.log("Initializing DelayedWETHProxy with DelayedWETH."); + + address wethProxy = mustGetAddress("DelayedWETHProxy"); + address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); + Proxy(payable(wethProxy)).upgradeToAndCall( + mustGetAddress("DelayedWETH"), + abi.encodeCall(DelayedWETH.initialize, (msg.sender, SuperchainConfig(superchainConfigProxy))) + ); + } + + function initializeAnchorStateRegistryProxy() internal broadcast { + console.log("Initializing AnchorStateRegistryProxy with AnchorStateRegistry."); + + AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](2); + roots[0] = AnchorStateRegistry.StartingAnchorRoot({ + gameType: GameTypes.CANNON, + outputRoot: OutputRoot({ + root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), + l2BlockNumber: cfg.faultGameGenesisBlock() + }) + }); + roots[1] = AnchorStateRegistry.StartingAnchorRoot({ + gameType: GameTypes.PERMISSIONED_CANNON, + outputRoot: OutputRoot({ + root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), + l2BlockNumber: cfg.faultGameGenesisBlock() + }) + }); + + address asrProxy = mustGetAddress("AnchorStateRegistryProxy"); + Proxy(payable(asrProxy)).upgradeToAndCall( + mustGetAddress("AnchorStateRegistry"), abi.encodeCall(AnchorStateRegistry.initialize, (roots)) + ); + } + + /// @notice Transfers admin rights of the `DisputeGameFactoryProxy` to the `ProxyAdmin` and sets the + /// `DisputeGameFactory` owner to the `SystemOwnerSafe`. + function transferDGFOwnershipFinal(address _proxyAdmin, address _systemOwnerSafe) internal broadcast { + DisputeGameFactory dgf = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); + + // Transfer the ownership of the DisputeGameFactory to the SystemOwnerSafe. + dgf.transferOwnership(_systemOwnerSafe); + + // Transfer the admin rights of the DisputeGameFactoryProxy to the ProxyAdmin. + Proxy prox = Proxy(payable(address(dgf))); + prox.changeAdmin(_proxyAdmin); + } + + /// @notice Transfers admin rights of the `DelayedWETHProxy` to the `ProxyAdmin` and sets the + /// `DelayedWETH` owner to the `SystemOwnerSafe`. + function transferWethOwnershipFinal(address _proxyAdmin, address _systemOwnerSafe) internal broadcast { + DelayedWETH weth = DelayedWETH(mustGetAddress("DelayedWETHProxy")); + + // Transfer the ownership of the DelayedWETH to the SystemOwnerSafe. + weth.transferOwnership(_systemOwnerSafe); + + // Transfer the admin rights of the DelayedWETHProxy to the ProxyAdmin. + Proxy prox = Proxy(payable(address(weth))); + prox.changeAdmin(_proxyAdmin); + } + + /// @notice Transfers admin rights of the `AnchorStateRegistryProxy` to the `ProxyAdmin`. + function transferAnchorStateOwnershipFinal(address _proxyAdmin) internal broadcast { + AnchorStateRegistry asr = AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")); + + // Transfer the admin rights of the AnchorStateRegistryProxy to the ProxyAdmin. + Proxy prox = Proxy(payable(address(asr))); + prox.changeAdmin(_proxyAdmin); + } + + /// @notice Checks that the deployed system is configured correctly. + function postDeployAssertions(address _proxyAdmin, address _systemOwnerSafe) internal { + Types.ContractSet memory contracts = _proxiesUnstrict(); + contracts.OptimismPortal2 = mustGetAddress("OptimismPortal2"); + + // Ensure that `useFaultProofs` is set to `true`. + assertTrue(cfg.useFaultProofs()); + + // Ensure the contracts are owned by the correct entities. + address dgfProxyAddr = mustGetAddress("DisputeGameFactoryProxy"); + DisputeGameFactory dgfProxy = DisputeGameFactory(dgfProxyAddr); + assertEq(address(uint160(uint256(vm.load(dgfProxyAddr, Constants.PROXY_OWNER_ADDRESS)))), _proxyAdmin); + ChainAssertions.checkDisputeGameFactory(contracts, _systemOwnerSafe); + address wethProxyAddr = mustGetAddress("DelayedWETHProxy"); + assertEq(address(uint160(uint256(vm.load(wethProxyAddr, Constants.PROXY_OWNER_ADDRESS)))), _proxyAdmin); + ChainAssertions.checkDelayedWETH(contracts, cfg, true, _systemOwnerSafe); + + // Check the config elements in the deployed contracts. + ChainAssertions.checkOptimismPortal2(contracts, cfg, false); + + PreimageOracle oracle = PreimageOracle(mustGetAddress("PreimageOracle")); + assertEq(oracle.minProposalSize(), cfg.preimageOracleMinProposalSize()); + assertEq(oracle.challengePeriod(), cfg.preimageOracleChallengePeriod()); + + MIPS mips = MIPS(mustGetAddress("Mips")); + assertEq(address(mips.oracle()), address(oracle)); + + // Check the FaultDisputeGame configuration. + FaultDisputeGame gameImpl = FaultDisputeGame(payable(address(dgfProxy.gameImpls(GameTypes.CANNON)))); + assertEq(gameImpl.maxGameDepth(), cfg.faultGameMaxDepth()); + assertEq(gameImpl.splitDepth(), cfg.faultGameSplitDepth()); + assertEq(gameImpl.gameDuration().raw(), cfg.faultGameMaxDuration()); + assertEq(gameImpl.absolutePrestate().raw(), bytes32(cfg.faultGameAbsolutePrestate())); + + // Check the security override yoke configuration. + PermissionedDisputeGame soyGameImpl = + PermissionedDisputeGame(payable(address(dgfProxy.gameImpls(GameTypes.PERMISSIONED_CANNON)))); + assertEq(soyGameImpl.maxGameDepth(), cfg.faultGameMaxDepth()); + assertEq(soyGameImpl.splitDepth(), cfg.faultGameSplitDepth()); + assertEq(soyGameImpl.gameDuration().raw(), cfg.faultGameMaxDuration()); + assertEq(soyGameImpl.absolutePrestate().raw(), bytes32(cfg.faultGameAbsolutePrestate())); + + // Check the AnchorStateRegistry configuration. + AnchorStateRegistry asr = AnchorStateRegistry(mustGetAddress("AnchorStateRegistryProxy")); + (Hash root1, uint256 l2BlockNumber1) = asr.anchors(GameTypes.CANNON); + (Hash root2, uint256 l2BlockNumber2) = asr.anchors(GameTypes.PERMISSIONED_CANNON); + assertEq(root1.raw(), cfg.faultGameGenesisOutputRoot()); + assertEq(root2.raw(), cfg.faultGameGenesisOutputRoot()); + assertEq(l2BlockNumber1, cfg.faultGameGenesisBlock()); + assertEq(l2BlockNumber2, cfg.faultGameGenesisBlock()); + } + + /// @notice Prints a review of the fault proof configuration section of the deploy config. + function printConfigReview() internal view { + console.log(unicode"📖 FaultDisputeGame Config Overview (chainid: %d)", block.chainid); + console.log(" 0. Use Fault Proofs: %s", cfg.useFaultProofs() ? "true" : "false"); + console.log(" 1. Absolute Prestate: %x", cfg.faultGameAbsolutePrestate()); + console.log(" 2. Max Depth: %d", cfg.faultGameMaxDepth()); + console.log(" 3. Output / Execution split Depth: %d", cfg.faultGameSplitDepth()); + console.log(" 4. Game Duration (seconds): %d", cfg.faultGameMaxDuration()); + console.log(" 5. L2 Genesis block number: %d", cfg.faultGameGenesisBlock()); + console.log(" 6. L2 Genesis output root: %x", uint256(cfg.faultGameGenesisOutputRoot())); + console.log(" 7. Proof Maturity Delay (seconds): ", cfg.proofMaturityDelaySeconds()); + console.log(" 8. Dispute Game Finality Delay (seconds): ", cfg.disputeGameFinalityDelaySeconds()); + console.log(" 9. Respected Game Type: ", cfg.respectedGameType()); + console.log(" 10. Preimage Oracle Min Proposal Size (bytes): ", cfg.preimageOracleMinProposalSize()); + console.log(" 11. Preimage Oracle Challenge Period (seconds): ", cfg.preimageOracleChallengePeriod()); + } +} diff --git a/packages/contracts-bedrock/scripts/fpac/Makefile b/packages/contracts-bedrock/scripts/fpac/Makefile new file mode 100644 index 000000000000..64db2979b943 --- /dev/null +++ b/packages/contracts-bedrock/scripts/fpac/Makefile @@ -0,0 +1,26 @@ +# ENV +monorepo_root := "../../../.." +deploy_config_path := "../../deploy-config" +tmp := $(shell mktemp) + +# Help menu +.PHONY: help +help: # Show help for each of the Makefile recipes. + @grep -E '^[a-zA-Z0-9 -]+:.*#' Makefile | sort | while read -r l; do printf "\033[1;32m$$(echo $$l | cut -f 1 -d':')\033[00m:$$(echo $$l | cut -f 2- -d'#')\n"; done + +.PHONY: cannon-prestate +cannon-prestate: # Generate the cannon prestate, and tar the `op-program` + `cannon` binaries + prestate data used to generate it. + cd $(monorepo_root) && make reproducible-prestate + @mkdir -p prestate-artifacts + @cp -r $(monorepo_root)/cannon/bin/** prestate-artifacts/ + @cp -r $(monorepo_root)/op-program/bin/** prestate-artifacts/ + tar -czvf prestate-artifacts.tar.gz prestate-artifacts + @jq ".faultGameAbsolutePrestate = $$(cat prestate-artifacts/prestate-proof.json | jq .pre)" "$(deploy_config_path)/$(chain).json" > $(tmp) && mv $(tmp) "$(deploy_config_path)/$(chain).json" + @echo "-------------------------------------------------------------------------------------------------------------" + @echo "-> Archive of prestate artifacts available at prestate-artifacts.tar.gz" + @echo "-> Set the absolute prestate to $$(cat prestate-artifacts/prestate-proof.json | jq .pre) in the $(chain) deploy config." + @rm -rf prestate-artifacts + +.PHONY: deploy-fresh +deploy-fresh: cannon-prestate # Deploy a fresh version of the FPAC contracts. Pass `--broadcast` to send to the network. + forge script FPACOPS.sol --sig "deployFPAC(address,address)" $(proxy-admin) $(system-owner-safe) --chain $(chain) -vvv $(args) diff --git a/packages/contracts-bedrock/scripts/fpac/README.md b/packages/contracts-bedrock/scripts/fpac/README.md new file mode 100644 index 000000000000..f03b755e0fbc --- /dev/null +++ b/packages/contracts-bedrock/scripts/fpac/README.md @@ -0,0 +1,21 @@ +# `fpac-deploy` + +Chain-ops scripts for the Fault Proof Alpha Chad contracts. + +## Usage + +### Generating the Cannon prestate and artifacts + +_Description_: Generates the cannon prestate, tars the relavent artifacts, and sets the absolute prestate field in the network's deploy config. + +```sh +make cannon-prestate chain= +``` + +### Deploying a fresh system + +_Description_: Deploys a fully fresh FPAC system to the passed chain. All args after the `args=` are forwarded to `forge script`. + +```sh +make deploy-fresh chain= proxy-admin= system-owner-safe= [args=] +``` diff --git a/packages/contracts-bedrock/scripts/fpac/SubmitLPP.sol b/packages/contracts-bedrock/scripts/fpac/SubmitLPP.sol new file mode 100644 index 000000000000..0a34e2d475fb --- /dev/null +++ b/packages/contracts-bedrock/scripts/fpac/SubmitLPP.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; +import { Script } from "forge-std/Script.sol"; +import { StdAssertions } from "forge-std/StdAssertions.sol"; +import "src/cannon/libraries/CannonTypes.sol"; + +contract SubmitLPP is Script, StdAssertions { + /// @notice Test UUID + uint256 private constant TEST_UUID = uint256(keccak256("TEST_UUID")); + /// @notice Number of bytes to submit to the preimage oracle. + uint256 private constant BYTES_TO_SUBMIT = 4_012_000; + /// @notice Chunk size to submit to the preimage oracle. + uint256 private constant CHUNK_SIZE = 500 * 136; + + PreimageOracle private oracle; + + function post(address _po) external { + // Bootstrap + oracle = PreimageOracle(_po); + + // Allocate chunk - worst case w/ all bits set. + bytes memory chunk = new bytes(CHUNK_SIZE); + for (uint256 i; i < chunk.length; i++) { + chunk[i] = 0xFF; + } + + // Mock state commitments. Worst case w/ all bits set. + bytes32[] memory mockStateCommitments = new bytes32[](CHUNK_SIZE / 136); + bytes32[] memory mockStateCommitmentsLast = new bytes32[](CHUNK_SIZE / 136 + 1); + for (uint256 i; i < mockStateCommitments.length; i++) { + mockStateCommitments[i] = bytes32(type(uint256).max); + mockStateCommitmentsLast[i] = bytes32(type(uint256).max); + } + // Assign last mock state commitment to all bits set. + mockStateCommitmentsLast[mockStateCommitmentsLast.length - 1] = bytes32(type(uint256).max); + + vm.broadcast(); + oracle.initLPP({ _uuid: TEST_UUID, _partOffset: 0, _claimedSize: uint32(BYTES_TO_SUBMIT) }); + + // Submit LPP in 500 * 136 byte chunks. + for (uint256 i = 0; i < BYTES_TO_SUBMIT; i += CHUNK_SIZE) { + bool finalize = i + CHUNK_SIZE >= BYTES_TO_SUBMIT; + + vm.broadcast(); + oracle.addLeavesLPP({ + _uuid: TEST_UUID, + _inputStartBlock: i / 136, + _input: chunk, + _stateCommitments: finalize ? mockStateCommitmentsLast : mockStateCommitments, + _finalize: finalize + }); + } + + // Assert that all bytes were submitted. + LPPMetaData metaData = oracle.proposalMetadata(msg.sender, TEST_UUID); + assertEq(metaData.bytesProcessed(), BYTES_TO_SUBMIT); + assertEq(metaData.blocksProcessed(), (BYTES_TO_SUBMIT / 136) + 1); + } +} diff --git a/packages/contracts-bedrock/scripts/fpac/lpp-estimation.sh b/packages/contracts-bedrock/scripts/fpac/lpp-estimation.sh new file mode 100755 index 000000000000..a120cccf3dee --- /dev/null +++ b/packages/contracts-bedrock/scripts/fpac/lpp-estimation.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Default Anvil private key +PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" +PUB_KEY="$(cast wallet addr $PRIVATE_KEY)" + +# 40 gwei base fee +BASE_FEE=40000000000 + +# Anvil RPC +export ETH_RPC_URL="http://localhost:8545" + +# Start anvil in the background +anvil --base-fee $BASE_FEE & +# Capture the process ID +ANVIL_PID=$! + +# Deploy the `PreimageOracle` contract to anvil. +PO_MIN_PROPOSAL_SIZE=10000 +PO_CHALLENGE_PERIOD=120 +PO_ADDR=$(forge create PreimageOracle --private-key $PRIVATE_KEY --rpc-url $ETH_RPC_URL --json --constructor-args "${PO_MIN_PROPOSAL_SIZE}" "${PO_CHALLENGE_PERIOD}" 0 | jq -r '.deployedTo') + +# Capture the balance of the submitter prior to submitting all leaves. +BALANCE_BEFORE=$(cast balance --rpc-url http://localhost:8545 "$PUB_KEY") +BASE_FEE_BEFORE=$(cast 2d "$(cast rpc 'eth_gasPrice' | jq -r)") + +# Run the `SubmitLPP` script to submit the LPP to the `PreimageOracle` contract. +forge script scripts/fpac/SubmitLPP.sol \ + --sig "post(address)" "$PO_ADDR" \ + --private-key $PRIVATE_KEY \ + --rpc-url $ETH_RPC_URL \ + --broadcast + +BALANCE_AFTER=$(cast balance "$PUB_KEY") +BASE_FEE_AFTER=$(cast 2d "$(cast rpc 'eth_gasPrice' | jq -r)") + +echo "Base Fee Before: $BASE_FEE_BEFORE" +echo "Base Fee After: $BASE_FEE_AFTER" +echo "Balance before: $BALANCE_BEFORE" +echo "Balance after: $BALANCE_AFTER" +echo "Cost: $(cast from-wei $((BALANCE_BEFORE - BALANCE_AFTER))) ETH" + +# Kill anvil +kill $ANVIL_PID diff --git a/packages/contracts-bedrock/scripts/generate-l2-genesis.sh b/packages/contracts-bedrock/scripts/generate-l2-genesis.sh new file mode 100755 index 000000000000..39d162b9151b --- /dev/null +++ b/packages/contracts-bedrock/scripts/generate-l2-genesis.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# Create a L2 genesis.json suitable for the solidity tests to +# ingest using `vm.loadAllocs(string)`. +# This script depends on the relative path to the op-node from +# contracts-bedrock + +SCRIPTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null && pwd)" +CONTRACTS_DIR="$(realpath "$SCRIPTS_DIR/..")" +MONOREPO_BASE="$(realpath "$CONTRACTS_DIR/../..")" + +DEPLOY_ARTIFACT="$CONTRACTS_DIR/deployments/hardhat/.deploy" +OP_NODE="$MONOREPO_BASE/op-node/cmd/main.go" +L1_STARTING_BLOCK_PATH="$CONTRACTS_DIR/test/mocks/block.json" +TESTDATA_DIR="$CONTRACTS_DIR/.testdata" + +OUTFILE_L2="$TESTDATA_DIR/genesis.json" +OUTFILE_ROLLUP="$TESTDATA_DIR/rollup.json" + +LOCKDIR="/tmp/lock-generate-l2-genesis" + +cleanup() { + rm -rf -- "$LOCKDIR" +} + +# Wait for the L2 outfile to be over 8M for up to $2 iterations +# of $1 seconds. This is a hack to ensure that the outfile is fully +# written before the solidity tests try to read it +wait_l2_outfile() { + i=1 + while [ $i -le "$2" ]; do + i=$((i + 1)) + + if [ ! -f "$OUTFILE_L2" ]; then + sleep "$1" + continue + fi + + if [ "$(du -m "$OUTFILE_L2" | cut -f1)" -lt 8 ]; then + sleep "$1" + continue + fi + + exit 0 + done + + echo "L2 genesis file not generated in time. Exiting." + exit 1 +} + +# Directory creations are atomic, so we can use mkdir to +# create a lockfile that prevents subsequent invocations +# of the script from running concurrently. +if mkdir -- "$LOCKDIR" > /dev/null 2>&1; then + trap 'cleanup' EXIT + + mkdir -p "$TESTDATA_DIR" + + if [ ! -f "$DEPLOY_ARTIFACT" ]; then + forge script "$CONTRACTS_DIR"/scripts/Deploy.s.sol:Deploy > /dev/null 2>&1 + fi + + if [ ! -f "$OUTFILE_L2" ]; then + tempfile=$(mktemp) + if ! go run "$OP_NODE" genesis l2 \ + --deploy-config "$CONTRACTS_DIR/deploy-config/hardhat.json" \ + --l1-deployments "$DEPLOY_ARTIFACT" \ + --l1-starting-block "$L1_STARTING_BLOCK_PATH" \ + --outfile.l2 "$OUTFILE_L2" \ + --outfile.rollup "$OUTFILE_ROLLUP" 2>"$tempfile"; then + cat "$tempfile" >&2 + fi + rm "$tempfile" + fi +else + # Wait up to 5 minutes for the lock to be released + wait_l2_outfile 0.25 1200 +fi diff --git a/packages/contracts-bedrock/scripts/getting-started/config.sh b/packages/contracts-bedrock/scripts/getting-started/config.sh new file mode 100755 index 000000000000..95ab527d603d --- /dev/null +++ b/packages/contracts-bedrock/scripts/getting-started/config.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash + +# This script is used to generate the getting-started.json configuration file +# used in the Getting Started quickstart guide on the docs site. Avoids the +# need to have the getting-started.json committed to the repo since it's an +# invalid JSON file when not filled in, which is annoying. + +reqenv() { + if [ -z "${!1}" ]; then + echo "Error: environment variable '$1' is undefined" + exit 1 + fi +} + +# Check required environment variables +reqenv "GS_ADMIN_ADDRESS" +reqenv "GS_BATCHER_ADDRESS" +reqenv "GS_PROPOSER_ADDRESS" +reqenv "GS_SEQUENCER_ADDRESS" +reqenv "L1_RPC_URL" + +# Get the finalized block timestamp and hash +block=$(cast block finalized --rpc-url "$L1_RPC_URL") +timestamp=$(echo "$block" | awk '/timestamp/ { print $2 }') +blockhash=$(echo "$block" | awk '/hash/ { print $2 }') + +# Generate the config file +config=$(cat << EOL +{ + "l1StartingBlockTag": "$blockhash", + + "l1ChainID": 11155111, + "l2ChainID": 42069, + "l2BlockTime": 2, + "l1BlockTime": 12, + + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + + "p2pSequencerAddress": "$GS_SEQUENCER_ADDRESS", + "batchInboxAddress": "0xff00000000000000000000000000000000042069", + "batchSenderAddress": "$GS_BATCHER_ADDRESS", + + "l2OutputOracleSubmissionInterval": 120, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleStartingTimestamp": $timestamp, + + "l2OutputOracleProposer": "$GS_PROPOSER_ADDRESS", + "l2OutputOracleChallenger": "$GS_ADMIN_ADDRESS", + + "finalizationPeriodSeconds": 12, + + "proxyAdminOwner": "$GS_ADMIN_ADDRESS", + "baseFeeVaultRecipient": "$GS_ADMIN_ADDRESS", + "l1FeeVaultRecipient": "$GS_ADMIN_ADDRESS", + "sequencerFeeVaultRecipient": "$GS_ADMIN_ADDRESS", + "finalSystemOwner": "$GS_ADMIN_ADDRESS", + "superchainConfigGuardian": "$GS_ADMIN_ADDRESS", + + "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "sequencerFeeVaultWithdrawalNetwork": 0, + + "gasPriceOracleOverhead": 2100, + "gasPriceOracleScalar": 1000000, + + "enableGovernance": true, + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "governanceTokenOwner": "$GS_ADMIN_ADDRESS", + + "l2GenesisBlockGasLimit": "0x1c9c380", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "l2GenesisRegolithTimeOffset": "0x0", + + "eip1559Denominator": 50, + "eip1559DenominatorCanyon": 250, + "eip1559Elasticity": 6, + + "l2GenesisDeltaTimeOffset": null, + "l2GenesisCanyonTimeOffset": "0x0", + + "systemConfigStartBlock": 0, + + "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + + "faultGameAbsolutePrestate": "0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98", + "faultGameMaxDepth": 44, + "faultGameMaxDuration": 1200, + "faultGameGenesisBlock": 0, + "faultGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameSplitDepth": 14, + + "preimageOracleMinProposalSize": 1800000, + "preimageOracleChallengePeriod": 86400, +} +EOL +) + +# Write the config file +echo "$config" > deploy-config/getting-started.json diff --git a/packages/contracts-bedrock/scripts/getting-started/versions.sh b/packages/contracts-bedrock/scripts/getting-started/versions.sh new file mode 100755 index 000000000000..79dc55a7e9c5 --- /dev/null +++ b/packages/contracts-bedrock/scripts/getting-started/versions.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# This script prints out the versions of the various tools used in the Getting +# Started quickstart guide on the docs site. Simplifies things for users so +# they can easily see if they're using the right versions of everything. + +version() { + local string=$1 + local version_regex='([0-9]+(\.[0-9]+)+)' + if [[ $string =~ $version_regex ]]; then + echo "${BASH_REMATCH[1]}" + else + echo "No version found." + fi +} + +versionFoundry() { + local string="$1" + local version_regex='forge ([0-9]+\.[0-9]+\.[0-9]+)' + local commit_hash_regex='\(([a-fA-F0-9]+)' + local full_regex="${version_regex} ${commit_hash_regex}" + + if [[ $string =~ $full_regex ]]; then + echo "${BASH_REMATCH[1]} (${BASH_REMATCH[2]})" + else + echo "No version, commit hash, and timestamp found." + fi +} + + +# Grab versions +ver_git=$(version "$(git --version)") +ver_go=$(version "$(go version)") +ver_node=$(version "$(node --version)") +ver_pnpm=$(version "$(pnpm --version)") +ver_foundry=$(versionFoundry "$(forge --version)") +ver_make=$(version "$(make --version)") +ver_jq=$(version "$(jq --version)") +ver_direnv=$(version "$(direnv --version)") + +# Print versions +echo "Dependency | Minimum | Actual" +echo "git 2 $ver_git" +echo "go 1.21 $ver_go" +echo "node 20 $ver_node" +echo "pnpm 8 $ver_pnpm" +echo "foundry 0.2.0 (a5efe4f) $ver_foundry" +echo "make 3 $ver_make" +echo "jq 1.6 $ver_jq" +echo "direnv 2 $ver_direnv" diff --git a/packages/contracts-bedrock/scripts/getting-started/wallets.sh b/packages/contracts-bedrock/scripts/getting-started/wallets.sh new file mode 100755 index 000000000000..4d1426d8db5b --- /dev/null +++ b/packages/contracts-bedrock/scripts/getting-started/wallets.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# This script is used to generate the four wallets that are used in the Getting +# Started quickstart guide on the docs site. Simplifies things for users +# slightly while also avoiding the need for users to manually copy/paste a +# bunch of stuff over to the environment file. + +# Generate wallets +wallet1=$(cast wallet new) +wallet2=$(cast wallet new) +wallet3=$(cast wallet new) +wallet4=$(cast wallet new) + +# Grab wallet addresses +address1=$(echo "$wallet1" | awk '/Address/ { print $2 }') +address2=$(echo "$wallet2" | awk '/Address/ { print $2 }') +address3=$(echo "$wallet3" | awk '/Address/ { print $2 }') +address4=$(echo "$wallet4" | awk '/Address/ { print $2 }') + +# Grab wallet private keys +key1=$(echo "$wallet1" | awk '/Private key/ { print $3 }') +key2=$(echo "$wallet2" | awk '/Private key/ { print $3 }') +key3=$(echo "$wallet3" | awk '/Private key/ { print $3 }') +key4=$(echo "$wallet4" | awk '/Private key/ { print $3 }') + +# Print out the environment variables to copy +echo "Copy the following into your .envrc file:" +echo +echo "# Admin account" +echo "export GS_ADMIN_ADDRESS=$address1" +echo "export GS_ADMIN_PRIVATE_KEY=$key1" +echo +echo "# Batcher account" +echo "export GS_BATCHER_ADDRESS=$address2" +echo "export GS_BATCHER_PRIVATE_KEY=$key2" +echo +echo "# Proposer account" +echo "export GS_PROPOSER_ADDRESS=$address3" +echo "export GS_PROPOSER_PRIVATE_KEY=$key3" +echo +echo "# Sequencer account" +echo "export GS_SEQUENCER_ADDRESS=$address4" +echo "export GS_SEQUENCER_PRIVATE_KEY=$key4" diff --git a/packages/contracts-bedrock/scripts/go-ffi/bin.go b/packages/contracts-bedrock/scripts/go-ffi/bin.go index da7475392623..3610b7a140b1 100644 --- a/packages/contracts-bedrock/scripts/go-ffi/bin.go +++ b/packages/contracts-bedrock/scripts/go-ffi/bin.go @@ -11,6 +11,8 @@ func main() { DiffTestUtils() case "trie": FuzzTrie() + case "merkle": + DiffMerkle() default: log.Fatal("Must pass a subcommand") } diff --git a/packages/contracts-bedrock/scripts/go-ffi/merkle.go b/packages/contracts-bedrock/scripts/go-ffi/merkle.go new file mode 100644 index 000000000000..3fdad8ca734c --- /dev/null +++ b/packages/contracts-bedrock/scripts/go-ffi/merkle.go @@ -0,0 +1,98 @@ +package main + +import ( + "fmt" + "log" + "os" + "strconv" + + "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/merkle" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" +) + +// VerifyMerkleProof verifies a merkle proof against the root hash and the leaf hash. +// Reference: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#is_valid_merkle_branch +func VerifyMerkleProof(root, leaf common.Hash, index uint64, proof [merkle.BinaryMerkleTreeDepth]common.Hash) bool { + value := leaf + for i := 0; i < merkle.BinaryMerkleTreeDepth; i++ { + if ((index >> i) & 1) == 1 { + value = crypto.Keccak256Hash(proof[i][:], value[:]) + } else { + value = crypto.Keccak256Hash(value[:], proof[i][:]) + } + } + return value == root +} + +const ( + // GenProof generates a merkle proof for a given leaf index by reconstructing the merkle tree from the passed + // leaves. + genProof = "gen_proof" +) + +var ( + rootAndProof, _ = abi.NewType("tuple", "", []abi.ArgumentMarshaling{ + {Name: "root", Type: "bytes32"}, + {Name: "proof", Type: "bytes32[]"}, + }) + + merkleEncoder = abi.Arguments{ + {Type: rootAndProof}, + } +) + +// DiffMerkle generates an abi-encoded `merkleTestCase` of a specified variant. +func DiffMerkle() { + variant := os.Args[2] + if len(variant) == 0 { + log.Fatal("Must pass a variant to the merkle diff tester!") + } + + switch variant { + case genProof: + if len(os.Args) < 5 { + log.Fatal("Invalid arguments to `gen_proof` variant.") + } + + rawLeaves, err := hexutil.Decode(os.Args[3]) + if err != nil { + log.Fatal("Failed to decode leaves: ", err) + } + index, err := strconv.ParseInt(os.Args[4], 10, 64) + if err != nil { + log.Fatal("Failed to parse leaf index: ", err) + } + merkleTree := merkle.NewBinaryMerkleTree() + + // Append all leaves to the merkle tree. + for i := 0; i < len(rawLeaves)/32; i++ { + leaf := common.BytesToHash(rawLeaves[i<<5 : (i+1)<<5]) + merkleTree.AddLeaf(leaf) + } + + // Generate the proof for the given index. + proof := merkleTree.ProofAtIndex(uint64(index)) + + // Generate the merkle root. + root := merkleTree.RootHash() + + // Return "abi.encode(root, proof)" + packed, err := merkleEncoder.Pack(struct { + Root common.Hash + Proof [merkle.BinaryMerkleTreeDepth]common.Hash + }{ + Root: root, + Proof: proof, + }) + if err != nil { + log.Fatal("Failed to ABI encode root and proof: ", err) + } + fmt.Print(hexutil.Encode(packed[32:])) + default: + log.Fatal("Invalid variant passed to merkle diff tester!") + } +} diff --git a/packages/contracts-bedrock/scripts/interfaces/IAddressManager.sol b/packages/contracts-bedrock/scripts/interfaces/IAddressManager.sol new file mode 100644 index 000000000000..f7e87cdc8702 --- /dev/null +++ b/packages/contracts-bedrock/scripts/interfaces/IAddressManager.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +/// @title IAddressManager +/// @notice Minimal interface of the Legacy AddressManager. +interface IAddressManager { + /// @notice Emitted when an address is modified in the registry. + /// @param name String name being set in the registry. + /// @param newAddress Address set for the given name. + /// @param oldAddress Address that was previously set for the given name. + event AddressSet(string indexed name, address newAddress, address oldAddress); + + /// @notice Changes the address associated with a particular name. + /// @param _name String name to associate an address with. + /// @param _address Address to associate with the name. + function setAddress(string memory _name, address _address) external; + + /// @notice Retrieves the address associated with a given name. + /// @param _name Name to retrieve an address for. + /// @return Address associated with the given name. + function getAddress(string memory _name) external view returns (address); +} diff --git a/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol b/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol new file mode 100644 index 000000000000..2871d76b8238 --- /dev/null +++ b/packages/contracts-bedrock/scripts/interfaces/ISystemConfigV0.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; + +/// @title ISystemConfigV0 +/// @notice Minimal interface of the Legacy SystemConfig containing only getters. +/// Based on +/// https://github.com/ethereum-optimism/optimism/blob/f54a2234f2f350795552011f35f704a3feb56a08/packages/contracts-bedrock/src/L1/SystemConfig.sol +interface ISystemConfigV0 { + function owner() external view returns (address); + function VERSION() external view returns (uint256); + function overhead() external view returns (uint256); + function scalar() external view returns (uint256); + function batcherHash() external view returns (bytes32); + function gasLimit() external view returns (uint64); + function resourceConfig() external view returns (ResourceMetering.ResourceConfig memory); + function unsafeBlockSigner() external view returns (address); +} diff --git a/packages/contracts-bedrock/scripts/invariant-doc-gen.ts b/packages/contracts-bedrock/scripts/invariant-doc-gen.ts deleted file mode 100644 index a4ec3e7c295a..000000000000 --- a/packages/contracts-bedrock/scripts/invariant-doc-gen.ts +++ /dev/null @@ -1,169 +0,0 @@ -import fs from 'fs' -import path from 'path' - -const BASE_INVARIANTS_DIR = path.join(__dirname, '..', 'test', 'invariants') -const BASE_DOCS_DIR = path.join(__dirname, '..', 'invariant-docs') -const BASE_INVARIANT_GH_URL = '../test/invariants/' -const NATSPEC_INV = '@custom:invariant' - -// Represents an invariant test contract -type Contract = { - name: string - fileName: string - docs: InvariantDoc[] -} - -// Represents the documentation of an invariant -type InvariantDoc = { - header?: string - desc?: string - lineNo?: number -} - -const writtenFiles = [] - -// Lazy-parses all test files in the `test/invariants` directory -// to generate documentation on all invariant tests. -const docGen = (dir: string): void => { - // Grab all files within the invariants test dir - const files = fs.readdirSync(dir) - - // Array to store all found invariant documentation comments. - const docs: Contract[] = [] - - for (const fileName of files) { - // Read the contents of the invariant test file. - const fileContents = fs.readFileSync(path.join(dir, fileName)).toString() - - // Split the file into individual lines and trim whitespace. - const lines = fileContents.split('\n').map((line: string) => line.trim()) - - // Create an object to store all invariant test docs for the current contract - const name = fileName.replace('.t.sol', '') - const contract: Contract = { name, fileName, docs: [] } - - let currentDoc: InvariantDoc - - // Loop through all lines to find comments. - for (let i = 0; i < lines.length; i++) { - let line = lines[i] - - // We have an invariant doc - if (line.startsWith(`/// ${NATSPEC_INV}`)) { - // Assign the header of the invariant doc. - // TODO: Handle ambiguous case for `INVARIANT: ` prefix. - currentDoc = { - header: line.replace(`/// ${NATSPEC_INV}`, '').trim(), - desc: '', - } - - // If the header is multi-line, continue appending to the `currentDoc`'s header. - line = lines[++i] - while (line.startsWith(`///`) && line.trim() !== '///') { - currentDoc.header += ` ${line.replace(`///`, '').trim()}` - line = lines[++i] - } - - // Process the description - while ((line = lines[++i]).startsWith('///')) { - line = line.replace('///', '').trim() - - // If the line has any contents, insert it into the desc. - // Otherwise, consider it a linebreak. - currentDoc.desc += line.length > 0 ? `${line} ` : '\n' - } - - // Set the line number of the test - currentDoc.lineNo = i + 1 - - // Add the doc to the contract - contract.docs.push(currentDoc) - } - } - - // Add the contract to the array of docs - docs.push(contract) - } - - for (const contract of docs) { - const fileName = path.join(BASE_DOCS_DIR, `${contract.name}.md`) - const alreadyWritten = writtenFiles.includes(fileName) - - // If the file has already been written, append the extra docs to the end. - // Otherwise, write the file from scratch. - fs.writeFileSync( - fileName, - alreadyWritten - ? `${fs.readFileSync(fileName)}\n${renderContractDoc(contract, false)}` - : renderContractDoc(contract, true) - ) - - // If the file was just written for the first time, add it to the list of written files. - if (!alreadyWritten) { - writtenFiles.push(fileName) - } - } - - console.log( - `Generated invariant test documentation for:\n - ${ - docs.length - } contracts\n - ${docs.reduce( - (acc: number, contract: Contract) => acc + contract.docs.length, - 0 - )} invariant tests\nsuccessfully!` - ) -} - -// Generate a table of contents for all invariant docs and place it in the README. -const tocGen = (): void => { - const autoTOCPrefix = '\n' - const autoTOCPostfix = '\n' - - // Grab the name of all markdown files in `BASE_DOCS_DIR` except for `README.md`. - const files = fs - .readdirSync(BASE_DOCS_DIR) - .filter((fileName: string) => fileName !== 'README.md') - - // Generate a table of contents section. - const tocList = files - .map( - (fileName: string) => `- [${fileName.replace('.md', '')}](./${fileName})` - ) - .join('\n') - const toc = `${autoTOCPrefix}\n## Table of Contents\n${tocList}\n${autoTOCPostfix}` - - // Write the table of contents to the README. - const readmeContents = fs - .readFileSync(path.join(BASE_DOCS_DIR, 'README.md')) - .toString() - const above = readmeContents.split(autoTOCPrefix)[0] - const below = readmeContents.split(autoTOCPostfix)[1] - fs.writeFileSync( - path.join(BASE_DOCS_DIR, 'README.md'), - `${above}${toc}${below}` - ) -} - -// Render a `Contract` object into valid markdown. -const renderContractDoc = (contract: Contract, header: boolean): string => { - const _header = header ? `# \`${contract.name}\` Invariants\n` : '' - const docs = contract.docs - .map((doc: InvariantDoc) => { - const line = `${contract.fileName}#L${doc.lineNo}` - return `## ${doc.header}\n**Test:** [\`${line}\`](${BASE_INVARIANT_GH_URL}${line})\n\n${doc.desc}` - }) - .join('\n\n') - return `${_header}\n${docs}` -} - -// Generate the docs - -// Forge -console.log('Generating docs for forge invariants...') -docGen(BASE_INVARIANTS_DIR) - -// New line -console.log() - -// Generate an updated table of contents -tocGen() diff --git a/packages/contracts-bedrock/scripts/libraries/LibSort.sol b/packages/contracts-bedrock/scripts/libraries/LibSort.sol deleted file mode 100644 index 2f08d4761638..000000000000 --- a/packages/contracts-bedrock/scripts/libraries/LibSort.sol +++ /dev/null @@ -1,668 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Optimized sorts and operations for sorted arrays. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Sort.sol) -library LibSort { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INSERTION SORT */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // - Faster on small arrays (32 or lesser elements). - // - Faster on almost sorted arrays. - // - Smaller bytecode. - // - May be suitable for view functions intended for off-chain querying. - - /// @dev Sorts the array in-place with insertion sort. - function insertionSort(uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) // Length of `a`. - mstore(a, 0) // For insertion sort's inner loop to terminate. - let h := add(a, shl(5, n)) // High slot. - let s := 0x20 - let w := not(31) - for { let i := add(a, s) } 1 { } { - i := add(i, s) - if gt(i, h) { break } - let k := mload(i) // Key. - let j := add(i, w) // The slot before the current slot. - let v := mload(j) // The value of `j`. - if iszero(gt(v, k)) { continue } - for { } 1 { } { - mstore(add(j, s), v) - j := add(j, w) // `sub(j, 0x20)`. - v := mload(j) - if iszero(gt(v, k)) { break } - } - mstore(add(j, s), k) - } - mstore(a, n) // Restore the length of `a`. - } - } - - /// @dev Sorts the array in-place with insertion sort. - function insertionSort(int256[] memory a) internal pure { - _convertTwosComplement(a); - insertionSort(_toUints(a)); - _convertTwosComplement(a); - } - - /// @dev Sorts the array in-place with insertion sort. - function insertionSort(address[] memory a) internal pure { - insertionSort(_toUints(a)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTRO-QUICKSORT */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // - Faster on larger arrays (more than 32 elements). - // - Robust performance. - // - Larger bytecode. - - /// @dev Sorts the array in-place with intro-quicksort. - function sort(uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let w := not(31) - let s := 0x20 - let n := mload(a) // Length of `a`. - mstore(a, 0) // For insertion sort's inner loop to terminate. - - // Let the stack be the start of the free memory. - let stack := mload(0x40) - - for { } iszero(lt(n, 2)) { } { - // Push `l` and `h` to the stack. - // The `shl` by 5 is equivalent to multiplying by `0x20`. - let l := add(a, s) - let h := add(a, shl(5, n)) - - let j := l - // forgefmt: disable-next-item - for {} iszero(or(eq(j, h), gt(mload(j), mload(add(j, s))))) {} { - j := add(j, s) - } - // If the array is already sorted. - if eq(j, h) { break } - - j := h - // forgefmt: disable-next-item - for {} iszero(gt(mload(j), mload(add(j, w)))) {} { - j := add(j, w) // `sub(j, 0x20)`. - } - // If the array is reversed sorted. - if eq(j, l) { - for { } 1 { } { - let t := mload(l) - mstore(l, mload(h)) - mstore(h, t) - h := add(h, w) // `sub(h, 0x20)`. - l := add(l, s) - if iszero(lt(l, h)) { break } - } - break - } - - // Push `l` and `h` onto the stack. - mstore(stack, l) - mstore(add(stack, s), h) - stack := add(stack, 0x40) - break - } - - for { let stackBottom := mload(0x40) } iszero(eq(stack, stackBottom)) { } { - // Pop `l` and `h` from the stack. - stack := sub(stack, 0x40) - let l := mload(stack) - let h := mload(add(stack, s)) - - // Do insertion sort if `h - l <= 0x20 * 12`. - // Threshold is fine-tuned via trial and error. - if iszero(gt(sub(h, l), 0x180)) { - // Hardcode sort the first 2 elements. - let i := add(l, s) - if iszero(lt(mload(l), mload(i))) { - let t := mload(i) - mstore(i, mload(l)) - mstore(l, t) - } - for { } 1 { } { - i := add(i, s) - if gt(i, h) { break } - let k := mload(i) // Key. - let j := add(i, w) // The slot before the current slot. - let v := mload(j) // The value of `j`. - if iszero(gt(v, k)) { continue } - for { } 1 { } { - mstore(add(j, s), v) - j := add(j, w) - v := mload(j) - if iszero(gt(v, k)) { break } - } - mstore(add(j, s), k) - } - continue - } - // Pivot slot is the average of `l` and `h`. - let p := add(shl(5, shr(6, add(l, h))), and(31, l)) - // Median of 3 with sorting. - { - let e0 := mload(l) - let e2 := mload(h) - let e1 := mload(p) - if iszero(lt(e0, e1)) { - let t := e0 - e0 := e1 - e1 := t - } - if iszero(lt(e0, e2)) { - let t := e0 - e0 := e2 - e2 := t - } - if iszero(lt(e1, e2)) { - let t := e1 - e1 := e2 - e2 := t - } - mstore(p, e1) - mstore(h, e2) - mstore(l, e0) - } - // Hoare's partition. - { - // The value of the pivot slot. - let x := mload(p) - p := h - for { let i := l } 1 { } { - for { } 1 { } { - i := add(i, s) - if iszero(gt(x, mload(i))) { break } - } - let j := p - for { } 1 { } { - j := add(j, w) - if iszero(lt(x, mload(j))) { break } - } - p := j - if iszero(lt(i, p)) { break } - // Swap slots `i` and `p`. - let t := mload(i) - mstore(i, mload(p)) - mstore(p, t) - } - } - // If slice on right of pivot is non-empty, push onto stack. - { - mstore(stack, add(p, s)) - // Skip `mstore(add(stack, 0x20), h)`, as it is already on the stack. - stack := add(stack, shl(6, lt(add(p, s), h))) - } - // If slice on left of pivot is non-empty, push onto stack. - { - mstore(stack, l) - mstore(add(stack, s), p) - stack := add(stack, shl(6, gt(p, l))) - } - } - mstore(a, n) // Restore the length of `a`. - } - } - - /// @dev Sorts the array in-place with intro-quicksort. - function sort(int256[] memory a) internal pure { - _convertTwosComplement(a); - sort(_toUints(a)); - _convertTwosComplement(a); - } - - /// @dev Sorts the array in-place with intro-quicksort. - function sort(address[] memory a) internal pure { - sort(_toUints(a)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OTHER USEFUL OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // For performance, the `uniquifySorted` methods will not revert if the - // array is not sorted -- it will simply remove consecutive duplicate elements. - - /// @dev Removes duplicate elements from a ascendingly sorted memory array. - function uniquifySorted(uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - // If the length of `a` is greater than 1. - if iszero(lt(mload(a), 2)) { - let x := add(a, 0x20) - let y := add(a, 0x40) - let end := add(a, shl(5, add(mload(a), 1))) - for { } 1 { } { - if iszero(eq(mload(x), mload(y))) { - x := add(x, 0x20) - mstore(x, mload(y)) - } - y := add(y, 0x20) - if eq(y, end) { break } - } - mstore(a, shr(5, sub(x, a))) - } - } - } - - /// @dev Removes duplicate elements from a ascendingly sorted memory array. - function uniquifySorted(int256[] memory a) internal pure { - uniquifySorted(_toUints(a)); - } - - /// @dev Removes duplicate elements from a ascendingly sorted memory array. - function uniquifySorted(address[] memory a) internal pure { - uniquifySorted(_toUints(a)); - } - - /// @dev Returns whether `a` contains `needle`, - /// and the index of the nearest element less than or equal to `needle`. - function searchSorted(uint256[] memory a, uint256 needle) internal pure returns (bool found, uint256 index) { - (found, index) = _searchSorted(a, needle, 0); - } - - /// @dev Returns whether `a` contains `needle`, - /// and the index of the nearest element less than or equal to `needle`. - function searchSorted(int256[] memory a, int256 needle) internal pure returns (bool found, uint256 index) { - (found, index) = _searchSorted(_toUints(a), uint256(needle), 1 << 255); - } - - /// @dev Returns whether `a` contains `needle`, - /// and the index of the nearest element less than or equal to `needle`. - function searchSorted(address[] memory a, address needle) internal pure returns (bool found, uint256 index) { - (found, index) = _searchSorted(_toUints(a), uint256(uint160(needle)), 0); - } - - /// @dev Reverses the array in-place. - function reverse(uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(mload(a), 2)) { - let s := 0x20 - let w := not(31) - let h := add(a, shl(5, mload(a))) - for { a := add(a, s) } 1 { } { - let t := mload(a) - mstore(a, mload(h)) - mstore(h, t) - h := add(h, w) - a := add(a, s) - if iszero(lt(a, h)) { break } - } - } - } - } - - /// @dev Reverses the array in-place. - function reverse(int256[] memory a) internal pure { - reverse(_toUints(a)); - } - - /// @dev Reverses the array in-place. - function reverse(address[] memory a) internal pure { - reverse(_toUints(a)); - } - - /// @dev Returns whether the array is sorted in ascending order. - function isSorted(uint256[] memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - if iszero(lt(mload(a), 2)) { - let end := add(a, shl(5, mload(a))) - for { a := add(a, 0x20) } 1 { } { - let p := mload(a) - a := add(a, 0x20) - result := iszero(gt(p, mload(a))) - if iszero(mul(result, xor(a, end))) { break } - } - } - } - } - - /// @dev Returns whether the array is sorted in ascending order. - function isSorted(int256[] memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - if iszero(lt(mload(a), 2)) { - let end := add(a, shl(5, mload(a))) - for { a := add(a, 0x20) } 1 { } { - let p := mload(a) - a := add(a, 0x20) - result := iszero(sgt(p, mload(a))) - if iszero(mul(result, xor(a, end))) { break } - } - } - } - } - - /// @dev Returns whether the array is sorted in ascending order. - function isSorted(address[] memory a) internal pure returns (bool result) { - result = isSorted(_toUints(a)); - } - - /// @dev Returns whether the array is strictly ascending (sorted and uniquified). - function isSortedAndUniquified(uint256[] memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - if iszero(lt(mload(a), 2)) { - let end := add(a, shl(5, mload(a))) - for { a := add(a, 0x20) } 1 { } { - let p := mload(a) - a := add(a, 0x20) - result := lt(p, mload(a)) - if iszero(mul(result, xor(a, end))) { break } - } - } - } - } - - /// @dev Returns whether the array is strictly ascending (sorted and uniquified). - function isSortedAndUniquified(int256[] memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - if iszero(lt(mload(a), 2)) { - let end := add(a, shl(5, mload(a))) - for { a := add(a, 0x20) } 1 { } { - let p := mload(a) - a := add(a, 0x20) - result := slt(p, mload(a)) - if iszero(mul(result, xor(a, end))) { break } - } - } - } - } - - /// @dev Returns whether the array is strictly ascending (sorted and uniquified). - function isSortedAndUniquified(address[] memory a) internal pure returns (bool result) { - result = isSortedAndUniquified(_toUints(a)); - } - - /// @dev Returns the sorted set difference of `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function difference(uint256[] memory a, uint256[] memory b) internal pure returns (uint256[] memory c) { - c = _difference(a, b, 0); - } - - /// @dev Returns the sorted set difference between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function difference(int256[] memory a, int256[] memory b) internal pure returns (int256[] memory c) { - c = _toInts(_difference(_toUints(a), _toUints(b), 1 << 255)); - } - - /// @dev Returns the sorted set difference between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function difference(address[] memory a, address[] memory b) internal pure returns (address[] memory c) { - c = _toAddresses(_difference(_toUints(a), _toUints(b), 0)); - } - - /// @dev Returns the sorted set intersection between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function intersection(uint256[] memory a, uint256[] memory b) internal pure returns (uint256[] memory c) { - c = _intersection(a, b, 0); - } - - /// @dev Returns the sorted set intersection between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function intersection(int256[] memory a, int256[] memory b) internal pure returns (int256[] memory c) { - c = _toInts(_intersection(_toUints(a), _toUints(b), 1 << 255)); - } - - /// @dev Returns the sorted set intersection between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function intersection(address[] memory a, address[] memory b) internal pure returns (address[] memory c) { - c = _toAddresses(_intersection(_toUints(a), _toUints(b), 0)); - } - - /// @dev Returns the sorted set union of `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function union(uint256[] memory a, uint256[] memory b) internal pure returns (uint256[] memory c) { - c = _union(a, b, 0); - } - - /// @dev Returns the sorted set union of `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function union(int256[] memory a, int256[] memory b) internal pure returns (int256[] memory c) { - c = _toInts(_union(_toUints(a), _toUints(b), 1 << 255)); - } - - /// @dev Returns the sorted set union between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function union(address[] memory a, address[] memory b) internal pure returns (address[] memory c) { - c = _toAddresses(_union(_toUints(a), _toUints(b), 0)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Reinterpret cast to an uint256 array. - function _toUints(int256[] memory a) private pure returns (uint256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - casted := a - } - } - - /// @dev Reinterpret cast to an uint256 array. - function _toUints(address[] memory a) private pure returns (uint256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - // As any address written to memory will have the upper 96 bits - // of the word zeroized (as per Solidity spec), we can directly - // compare these addresses as if they are whole uint256 words. - casted := a - } - } - - /// @dev Reinterpret cast to an int array. - function _toInts(uint256[] memory a) private pure returns (int256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - casted := a - } - } - - /// @dev Reinterpret cast to an address array. - function _toAddresses(uint256[] memory a) private pure returns (address[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - casted := a - } - } - - /// @dev Converts an array of signed two-complement integers - /// to unsigned integers suitable for sorting. - function _convertTwosComplement(int256[] memory a) private pure { - /// @solidity memory-safe-assembly - assembly { - let w := shl(255, 1) - for { let end := add(a, shl(5, mload(a))) } iszero(eq(a, end)) { } { - a := add(a, 0x20) - mstore(a, add(mload(a), w)) - } - } - } - - /// @dev Returns whether `a` contains `needle`, - /// and the index of the nearest element less than or equal to `needle`. - function _searchSorted( - uint256[] memory a, - uint256 needle, - uint256 signed - ) - private - pure - returns (bool found, uint256 index) - { - /// @solidity memory-safe-assembly - assembly { - let m := 0 // Middle slot. - let s := 0x20 - let l := add(a, s) // Slot of the start of search. - let h := add(a, shl(5, mload(a))) // Slot of the end of search. - for { needle := add(signed, needle) } 1 { } { - // Average of `l` and `h`. - m := add(shl(5, shr(6, add(l, h))), and(31, l)) - let t := add(signed, mload(m)) - found := eq(t, needle) - if or(gt(l, h), found) { break } - // Decide whether to search the left or right half. - if iszero(gt(needle, t)) { - h := sub(m, s) - continue - } - l := add(m, s) - } - // `m` will be less than `add(a, 0x20)` in the case of an empty array, - // or when the value is less than the smallest value in the array. - let t := iszero(lt(m, add(a, s))) - index := shr(5, mul(sub(m, add(a, s)), t)) - found := and(found, t) - } - } - - /// @dev Returns the sorted set difference of `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function _difference( - uint256[] memory a, - uint256[] memory b, - uint256 signed - ) - private - pure - returns (uint256[] memory c) - { - /// @solidity memory-safe-assembly - assembly { - let s := 0x20 - let aEnd := add(a, shl(5, mload(a))) - let bEnd := add(b, shl(5, mload(b))) - c := mload(0x40) // Set `c` to the free memory pointer. - a := add(a, s) - b := add(b, s) - let k := c - for { } iszero(or(gt(a, aEnd), gt(b, bEnd))) { } { - let u := mload(a) - let v := mload(b) - if iszero(xor(u, v)) { - a := add(a, s) - b := add(b, s) - continue - } - if iszero(lt(add(u, signed), add(v, signed))) { - b := add(b, s) - continue - } - k := add(k, s) - mstore(k, u) - a := add(a, s) - } - for { } iszero(gt(a, aEnd)) { } { - k := add(k, s) - mstore(k, mload(a)) - a := add(a, s) - } - mstore(c, shr(5, sub(k, c))) // Store the length of `c`. - mstore(0x40, add(k, s)) // Allocate the memory for `c`. - } - } - - /// @dev Returns the sorted set intersection between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function _intersection( - uint256[] memory a, - uint256[] memory b, - uint256 signed - ) - private - pure - returns (uint256[] memory c) - { - /// @solidity memory-safe-assembly - assembly { - let s := 0x20 - let aEnd := add(a, shl(5, mload(a))) - let bEnd := add(b, shl(5, mload(b))) - c := mload(0x40) // Set `c` to the free memory pointer. - a := add(a, s) - b := add(b, s) - let k := c - for { } iszero(or(gt(a, aEnd), gt(b, bEnd))) { } { - let u := mload(a) - let v := mload(b) - if iszero(xor(u, v)) { - k := add(k, s) - mstore(k, u) - a := add(a, s) - b := add(b, s) - continue - } - if iszero(lt(add(u, signed), add(v, signed))) { - b := add(b, s) - continue - } - a := add(a, s) - } - mstore(c, shr(5, sub(k, c))) // Store the length of `c`. - mstore(0x40, add(k, s)) // Allocate the memory for `c`. - } - } - - /// @dev Returns the sorted set union of `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function _union(uint256[] memory a, uint256[] memory b, uint256 signed) private pure returns (uint256[] memory c) { - /// @solidity memory-safe-assembly - assembly { - let s := 0x20 - let aEnd := add(a, shl(5, mload(a))) - let bEnd := add(b, shl(5, mload(b))) - c := mload(0x40) // Set `c` to the free memory pointer. - a := add(a, s) - b := add(b, s) - let k := c - for { } iszero(or(gt(a, aEnd), gt(b, bEnd))) { } { - let u := mload(a) - let v := mload(b) - if iszero(xor(u, v)) { - k := add(k, s) - mstore(k, u) - a := add(a, s) - b := add(b, s) - continue - } - if iszero(lt(add(u, signed), add(v, signed))) { - k := add(k, s) - mstore(k, v) - b := add(b, s) - continue - } - k := add(k, s) - mstore(k, u) - a := add(a, s) - } - for { } iszero(gt(a, aEnd)) { } { - k := add(k, s) - mstore(k, mload(a)) - a := add(a, s) - } - for { } iszero(gt(b, bEnd)) { } { - k := add(k, s) - mstore(k, mload(b)) - b := add(b, s) - } - mstore(c, shr(5, sub(k, c))) // Store the length of `c`. - mstore(0x40, add(k, s)) // Allocate the memory for `c`. - } - } -} diff --git a/packages/contracts-bedrock/scripts/libraries/LibStateDiff.sol b/packages/contracts-bedrock/scripts/libraries/LibStateDiff.sol new file mode 100644 index 000000000000..2b6f38a9afa7 --- /dev/null +++ b/packages/contracts-bedrock/scripts/libraries/LibStateDiff.sol @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { stdJson } from "forge-std/StdJson.sol"; +import { VmSafe } from "forge-std/Vm.sol"; + +/// @title LibStateDiff +/// @author refcell +/// @notice Library to write StateDiff output to json. +library LibStateDiff { + /// @notice Accepts an array of AccountAccess structs from the Vm and encodes them as a json string. + /// @param _accountAccesses Array of AccountAccess structs. + /// @return serialized_ string + function encodeAccountAccesses(VmSafe.AccountAccess[] memory _accountAccesses) + internal + returns (string memory serialized_) + { + string[] memory accountAccesses = new string[](_accountAccesses.length); + for (uint256 i = 0; i < _accountAccesses.length; i++) { + accountAccesses[i] = serializeAccountAccess(_accountAccesses[i]); + } + serialized_ = stdJson.serialize("accountAccessElem", "accountAccesses", accountAccesses); + } + + /// @notice Turns an AccountAccess into a json serialized string + /// @param _accountAccess The AccountAccess to serialize + /// @return serialized_ The json serialized string + function serializeAccountAccess(VmSafe.AccountAccess memory _accountAccess) + internal + returns (string memory serialized_) + { + string memory json = ""; + json = stdJson.serialize("accountAccess", "chainInfo", serializeChainInfo(_accountAccess.chainInfo)); + json = stdJson.serialize("accountAccess", "kind", serializeAccountAccessKind(_accountAccess.kind)); + json = stdJson.serialize("accountAccess", "account", _accountAccess.account); + json = stdJson.serialize("accountAccess", "accessor", _accountAccess.accessor); + json = stdJson.serialize("accountAccess", "initialized", _accountAccess.initialized); + json = stdJson.serialize("accountAccess", "oldBalance", _accountAccess.oldBalance); + json = stdJson.serialize("accountAccess", "newBalance", _accountAccess.newBalance); + json = stdJson.serialize("accountAccess", "deployedCode", _accountAccess.deployedCode); + json = stdJson.serialize("accountAccess", "value", _accountAccess.value); + json = stdJson.serialize("accountAccess", "data", _accountAccess.data); + json = stdJson.serialize("accountAccess", "reverted", _accountAccess.reverted); + json = stdJson.serialize( + "accountAccess", "storageAccesses", serializeStorageAccesses(_accountAccess.storageAccesses) + ); + serialized_ = json; + } + + /// @notice Accepts a VmSafe.ChainInfo struct and encodes it as a json string. + /// @param _chainInfo The ChainInfo struct to serialize + /// @return serialized_ string + function serializeChainInfo(VmSafe.ChainInfo memory _chainInfo) internal returns (string memory serialized_) { + string memory json = ""; + json = stdJson.serialize("chainInfo", "forkId", _chainInfo.forkId); + json = stdJson.serialize("chainInfo", "chainId", _chainInfo.chainId); + serialized_ = json; + } + + /// @notice Turns an AccountAccessKind into a string. + /// @param _kind The AccountAccessKind to serialize + /// @return serialized_ The string representation of the AccountAccessKind + function serializeAccountAccessKind(VmSafe.AccountAccessKind _kind) + internal + pure + returns (string memory serialized_) + { + if (_kind == VmSafe.AccountAccessKind.Call) { + serialized_ = "Call"; + } else if (_kind == VmSafe.AccountAccessKind.DelegateCall) { + serialized_ = "DelegateCall"; + } else if (_kind == VmSafe.AccountAccessKind.CallCode) { + serialized_ = "CallCode"; + } else if (_kind == VmSafe.AccountAccessKind.StaticCall) { + serialized_ = "StaticCall"; + } else if (_kind == VmSafe.AccountAccessKind.Create) { + serialized_ = "Create"; + } else if (_kind == VmSafe.AccountAccessKind.SelfDestruct) { + serialized_ = "SelfDestruct"; + } else { + serialized_ = "Resume"; + } + } + + /// @notice Accepts an array of StorageAccess structs from the Vm and encodes each as a json string. + /// @param _storageAccesses Array of StorageAccess structs. + /// @return serialized_ The list of json serialized StorageAccess structs. + function serializeStorageAccesses(VmSafe.StorageAccess[] memory _storageAccesses) + internal + returns (string[] memory serialized_) + { + serialized_ = new string[](_storageAccesses.length); + for (uint256 i = 0; i < _storageAccesses.length; i++) { + serialized_[i] = serializeStorageAccess(_storageAccesses[i]); + } + } + + /// @notice Turns a StorageAccess into a json serialized string + /// @param _storageAccess The StorageAccess to serialize + /// @return serialized_ The json serialized string + function serializeStorageAccess(VmSafe.StorageAccess memory _storageAccess) + internal + returns (string memory serialized_) + { + string memory json = ""; + json = stdJson.serialize("storageAccess", "account", _storageAccess.account); + json = stdJson.serialize("storageAccess", "slot", _storageAccess.slot); + json = stdJson.serialize("storageAccess", "isWrite", _storageAccess.isWrite); + json = stdJson.serialize("storageAccess", "previousValue", _storageAccess.previousValue); + json = stdJson.serialize("storageAccess", "newValue", _storageAccess.newValue); + json = stdJson.serialize("storageAccess", "reverted", _storageAccess.reverted); + serialized_ = json; + } +} diff --git a/packages/contracts-bedrock/scripts/print-addresses.sh b/packages/contracts-bedrock/scripts/print-addresses.sh new file mode 100755 index 000000000000..7a4a7465a862 --- /dev/null +++ b/packages/contracts-bedrock/scripts/print-addresses.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# Get the directory of the script itself +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +# Check if the first argument is provided +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +# Check if jq is installed +if ! command -v jq &> /dev/null; then + echo "jq is not installed. Please install it to run this script." + exit 1 +fi + +# Directory name from the argument +DIR_NAME=$1 + +# Check for the --sdk flag +SDK_MODE=false +if [[ "$2" == "--sdk" ]]; then + SDK_MODE=true +fi + +# Full directory path, relative from the script's location +DIR="$SCRIPT_DIR/../deployments/$DIR_NAME" + +# Check if the directory exists +if [ ! -d "$DIR" ]; then + echo "Directory does not exist: $DIR" + exit 1 +fi + +# Declare an array of filenames to check when in SDK mode +declare -a SDK_FILES=("AddressManager" "L1CrossDomainMessengerProxy" "L1StandardBridgeProxy" "OptimismPortalProxy" "L2OutputOracleProxy") + +# Loop through each .json file in the directory +for file in "$DIR"/*.json; do + # Extract the filename without the directory and the .json extension + filename=$(basename "$file" .json) + + # If SDK mode is on and the filename is not in the list, skip it + # shellcheck disable=SC2199,SC2076 + if $SDK_MODE && [[ ! " ${SDK_FILES[@]} " =~ " ${filename} " ]]; then + continue + fi + + # Extract the 'address' field from the JSON file + address=$(jq -r '.address' "$file") + + # Print the filename and the address + echo "${filename}: ${address}" +done diff --git a/packages/contracts-bedrock/scripts/restructure_tests.py b/packages/contracts-bedrock/scripts/restructure_tests.py new file mode 100644 index 000000000000..711753f3a3d1 --- /dev/null +++ b/packages/contracts-bedrock/scripts/restructure_tests.py @@ -0,0 +1,57 @@ +import os +import shutil + + +def mimic_directory_structure(src_folder: str, test_folder: str) -> None: + """ + This function takes a source folder and a test folder as input, and restructures + the test folder to match the directory structure of the source folder. + + Only moves test files (".t.sol") at the root level of the `test` folder. + """ + + # Walk through the src folder and collect a list of all .sol files + sol_files = [] + for root, _, files in os.walk(src_folder): + for file in files: + if file.endswith(".sol"): + sol_files.append(os.path.join(root, file)) + + # Iterate through each .t.sol file in the test folder + for test_file in os.listdir(test_folder): + if test_file.endswith(".t.sol"): + # Construct the corresponding .sol file name + sol_file = test_file.replace(".t.sol", ".sol") + + # Find the full path of the corresponding .sol file in the src folder + src_path = None + for sol_path in sol_files: + if sol_path.endswith(os.path.sep + sol_file): + src_path = sol_path + break + + if src_path: + # Calculate the relative path from the src folder to the .sol file + rel_path = os.path.relpath(src_path, src_folder) + + # Construct the destination path within the test folder + dest_path = os.path.join( + test_folder, rel_path).replace(".sol", ".t.sol") + + # Create the directory structure if it doesn't exist + dest_dir = os.path.dirname(dest_path) + os.makedirs(dest_dir, exist_ok=True) + + # Copy the .t.sol file to the destination folder + shutil.move(os.path.join(test_folder, test_file), dest_path) + print(f"Moved {test_file} to {dest_path}") + else: + print(f"No corresponding .sol file found for {test_file}") + + +# Specify the source and test folder paths +src_folder = "src" +test_folder = "test" + +# Call the mimic_directory_structure function +mimic_directory_structure(src_folder, test_folder) diff --git a/packages/contracts-bedrock/scripts/slither.sh b/packages/contracts-bedrock/scripts/slither.sh deleted file mode 100755 index a191bf139285..000000000000 --- a/packages/contracts-bedrock/scripts/slither.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -rm -rf artifacts forge-artifacts - -# See slither.config.json for slither settings -if [[ -z "$TRIAGE_MODE" ]]; then - echo "Building contracts" - forge build --build-info --force - echo "Running slither" - slither --ignore-compile . -else - echo "Running slither in triage mode" - # Slither's triage mode will run an 'interview' in the terminal, allowing you to review each of - # its findings, and specify which should be ignored in future runs of slither. This will update - # (or create) the slither.db.json file. This DB is a cleaner alternative to adding slither-disable - # comments throughout the codebase. - # Triage mode should only be run manually, and can be used to update the db when new findings are - # causing a CI failure. - slither . --triage-mode - - # For whatever reason the slither db contains a filename_absolute property which includes the full - # local path to source code on the machine where it was generated. This property does not - # seem to be required for slither to run, so we remove it. - DB=slither.db.json - TEMP_DB=temp-slither.db.json - mv $DB $TEMP_DB - jq 'walk(if type == "object" then del(.filename_absolute) else . end)' $TEMP_DB > $DB - rm -f $TEMP_DB -fi diff --git a/packages/contracts-bedrock/scripts/statediff.sh b/packages/contracts-bedrock/scripts/statediff.sh new file mode 100755 index 000000000000..fa1aef11c884 --- /dev/null +++ b/packages/contracts-bedrock/scripts/statediff.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -euo pipefail + +echo "> Deploying contracts to generate state diff (non-broadcast)" +forge script -vvv scripts/Deploy.s.sol:Deploy --sig 'runWithStateDiff()' diff --git a/packages/contracts-bedrock/scripts/storage-snapshot.sh b/packages/contracts-bedrock/scripts/storage-snapshot.sh deleted file mode 100755 index 0395c4aaf69b..000000000000 --- a/packages/contracts-bedrock/scripts/storage-snapshot.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -set -e - -if ! command -v forge &> /dev/null -then - echo "forge could not be found. Please install forge by running:" - echo "curl -L https://foundry.paradigm.xyz | bash" - exit -fi - -contracts=( - src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger - src/L1/L1StandardBridge.sol:L1StandardBridge - src/L1/L2OutputOracle.sol:L2OutputOracle - src/L1/OptimismPortal.sol:OptimismPortal - src/L1/SystemConfig.sol:SystemConfig - src/L1/L1ERC721Bridge.sol:L1ERC721Bridge - src/legacy/DeployerWhitelist.sol:DeployerWhitelist - src/L2/L1Block.sol:L1Block - src/legacy/L1BlockNumber.sol:L1BlockNumber - src/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger - src/L2/L2StandardBridge.sol:L2StandardBridge - src/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser - src/legacy/LegacyERC20ETH.sol:LegacyERC20ETH - src/L2/SequencerFeeVault.sol:SequencerFeeVault - src/L2/BaseFeeVault.sol:BaseFeeVault - src/L2/L1FeeVault.sol:L1FeeVault - src/L2/L2ERC721Bridge.sol:L2ERC721Bridge - src/vendor/WETH9.sol:WETH9 - src/universal/ProxyAdmin.sol:ProxyAdmin - src/universal/Proxy.sol:Proxy - src/legacy/L1ChugSplashProxy.sol:L1ChugSplashProxy - src/universal/OptimismMintableERC20.sol:OptimismMintableERC20 - src/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory - src/dispute/DisputeGameFactory.sol:DisputeGameFactory -) - -dir=$(dirname "$0") - -echo "Creating storage layout diagrams.." - -echo "=======================" > $dir/../.storage-layout -echo "👁👁 STORAGE LAYOUT snapshot 👁👁" >> $dir/../.storage-layout -echo "=======================" >> $dir/../.storage-layout - -for contract in ${contracts[@]} -do - echo -e "\n=======================" >> $dir/../.storage-layout - echo "➡ $contract">> $dir/../.storage-layout - echo -e "=======================\n" >> $dir/../.storage-layout - forge inspect --pretty $contract storage-layout >> $dir/../.storage-layout -done -echo "Storage layout snapshot stored at $dir/../.storage-layout" diff --git a/packages/contracts-bedrock/scripts/universal/EnhancedScript.sol b/packages/contracts-bedrock/scripts/universal/EnhancedScript.sol deleted file mode 100644 index fea9521ef733..000000000000 --- a/packages/contracts-bedrock/scripts/universal/EnhancedScript.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { console } from "forge-std/console.sol"; -import { Script } from "forge-std/Script.sol"; -import { Semver } from "../../src/universal/Semver.sol"; - -/// @title EnhancedScript -/// @notice Enhances forge-std' Script.sol with some additional application-specific functionality. -/// Logs simulation links using Tenderly. -abstract contract EnhancedScript is Script { - /// @notice Helper function used to compute the hash of Semver's version string to be used in a - /// comparison. - function _versionHash(address _addr) internal view returns (bytes32) { - return keccak256(bytes(Semver(_addr).version())); - } - - /// @notice Log a tenderly simulation link. The TENDERLY_USERNAME and TENDERLY_PROJECT - /// environment variables will be used if they are present. The vm is staticcall'ed - /// because of a compiler issue with the higher level ABI. - function logSimulationLink(address _to, bytes memory _data, address _from) public view { - (, bytes memory projData) = VM_ADDRESS.staticcall( - abi.encodeWithSignature("envOr(string,string)", "TENDERLY_PROJECT", "TENDERLY_PROJECT") - ); - string memory proj = abi.decode(projData, (string)); - - (, bytes memory userData) = VM_ADDRESS.staticcall( - abi.encodeWithSignature("envOr(string,string)", "TENDERLY_USERNAME", "TENDERLY_USERNAME") - ); - string memory username = abi.decode(userData, (string)); - - string memory str = string.concat( - "https://dashboard.tenderly.co/", - username, - "/", - proj, - "/simulator/new?network=", - vm.toString(block.chainid), - "&contractAddress=", - vm.toString(_to), - "&rawFunctionInput=", - vm.toString(_data), - "&from=", - vm.toString(_from) - ); - console.log(str); - } -} diff --git a/packages/contracts-bedrock/scripts/universal/GlobalConstants.sol b/packages/contracts-bedrock/scripts/universal/GlobalConstants.sol deleted file mode 100644 index b81eea6159b5..000000000000 --- a/packages/contracts-bedrock/scripts/universal/GlobalConstants.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -/// @title GlobalConstants -/// @notice A set of constants. -contract GlobalConstants { - /// @notice Mainnet chain id. - uint256 constant MAINNET = 1; - - /// @notice Goerli chain id. - uint256 constant GOERLI = 5; - - /// @notice Optimism Goerli chain id. - uint256 constant OP_GOERLI = 420; -} diff --git a/packages/contracts-bedrock/scripts/universal/SafeBuilder.sol b/packages/contracts-bedrock/scripts/universal/SafeBuilder.sol deleted file mode 100644 index cc3519d4af6c..000000000000 --- a/packages/contracts-bedrock/scripts/universal/SafeBuilder.sol +++ /dev/null @@ -1,206 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { console } from "forge-std/console.sol"; -import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol"; - -import { LibSort } from "../libraries/LibSort.sol"; -import { IGnosisSafe, Enum } from "../interfaces/IGnosisSafe.sol"; -import { EnhancedScript } from "../universal/EnhancedScript.sol"; -import { GlobalConstants } from "../universal/GlobalConstants.sol"; -import { ProxyAdmin } from "../../src/universal/ProxyAdmin.sol"; - -/// @title SafeBuilder -/// @notice Builds SafeTransactions -/// Assumes that a gnosis safe is used as the privileged account and the same -/// gnosis safe is the owner the proxy admin. -/// This could be optimized by checking for the number of approvals up front -/// and not submitting the final approval as `execTransaction` can be called when -/// there are `threshold - 1` approvals. -/// Uses the "approved hashes" method of interacting with the gnosis safe. Allows -/// for the most simple user experience when using automation and no indexer. -/// Run the command without the `--broadcast` flag and it will print a tenderly URL. -abstract contract SafeBuilder is EnhancedScript, GlobalConstants { - //////////////////////////////////////////////////////////////// - // State // - //////////////////////////////////////////////////////////////// - - /// @notice Interface for multicall3. - IMulticall3 internal constant multicall = IMulticall3(MULTICALL3_ADDRESS); - - /// @notice An array of approvals, used to generate the execution transaction. - address[] internal approvals; - - //////////////////////////////////////////////////////////////// - // Virtual Functions // - //////////////////////////////////////////////////////////////// - - /// @notice Follow up assertions to ensure that the script ran to completion. - function _postCheck() internal view virtual; - - /// @notice Creates the calldata - function buildCalldata(address _proxyAdmin) internal view virtual returns (bytes memory); - - /// @notice Internal helper function to compute the safe transaction hash. - function computeSafeTransactionHash(address _safe, address _proxyAdmin) public virtual returns (bytes32) { - return _getTransactionHash(_safe, _proxyAdmin); - } - - //////////////////////////////////////////////////////////////// - // Core Logic // - //////////////////////////////////////////////////////////////// - - function run() public returns (bool) { - address safe; - address proxyAdmin; - if (block.chainid == OP_GOERLI) { - safe = 0xE534ccA2753aCFbcDBCeB2291F596fc60495257e; - proxyAdmin = 0x4200000000000000000000000000000000000018; - } else if (block.chainid == GOERLI) { - safe = 0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f; - proxyAdmin = 0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d; - } - console.log("ChainID: %s", block.chainid); - return run(safe, proxyAdmin); - } - - /// @notice The entrypoint to this script. - function run(address _safe, address _proxyAdmin) public returns (bool) { - require(_safe != address(0), "Safe address undefined"); - require(_proxyAdmin != address(0), "ProxyAdminAddress undefined"); - - console.log("Using Safe: %s", _safe); - console.log("Using ProxyAdmin: %s", _proxyAdmin); - - vm.startBroadcast(); - bool success = _run(_safe, _proxyAdmin); - if (success) _postCheck(); - return success; - } - - /// @notice Computes the safe transaction hash for the provided safe and proxy admin. - function _getTransactionHash(address _safe, address _proxyAdmin) internal view returns (bytes32) { - // Ensure that the required contracts exist - require(address(multicall).code.length > 0, "multicall3 not deployed"); - require(_safe.code.length > 0, "no code at safe address"); - require(_proxyAdmin.code.length > 0, "no code at proxy admin address"); - - IGnosisSafe safe = IGnosisSafe(payable(_safe)); - uint256 nonce = safe.nonce(); - - bytes memory data = buildCalldata(_proxyAdmin); - - // Compute the safe transaction hash - bytes32 hash = safe.getTransactionHash({ - to: address(multicall), - value: 0, - data: data, - operation: Enum.Operation.DelegateCall, - safeTxGas: 0, - baseGas: 0, - gasPrice: 0, - gasToken: address(0), - refundReceiver: address(0), - _nonce: nonce - }); - - return hash; - } - - /// @notice The implementation of the upgrade. Split into its own function - /// to allow for testability. This is subject to a race condition if - /// the nonce changes by a different transaction finalizing while not - /// all of the signers have used this script. - function _run(address _safe, address _proxyAdmin) public returns (bool) { - IGnosisSafe safe = IGnosisSafe(payable(_safe)); - bytes memory data = buildCalldata(_proxyAdmin); - - // Compute the safe transaction hash - bytes32 hash = _getTransactionHash(_safe, _proxyAdmin); - - // Send a transaction to approve the hash - safe.approveHash(hash); - - logSimulationLink({ _to: address(safe), _from: msg.sender, _data: abi.encodeCall(safe.approveHash, (hash)) }); - - uint256 threshold = safe.getThreshold(); - address[] memory owners = safe.getOwners(); - - for (uint256 i; i < owners.length; i++) { - address owner = owners[i]; - uint256 approved = safe.approvedHashes(owner, hash); - if (approved == 1) { - approvals.push(owner); - } - } - - if (approvals.length >= threshold) { - bytes memory signatures = buildSignatures(); - - bool success = safe.execTransaction({ - to: address(multicall), - value: 0, - data: data, - operation: Enum.Operation.DelegateCall, - safeTxGas: 0, - baseGas: 0, - gasPrice: 0, - gasToken: address(0), - refundReceiver: payable(address(0)), - signatures: signatures - }); - - logSimulationLink({ - _to: address(safe), - _from: msg.sender, - _data: abi.encodeCall( - safe.execTransaction, - ( - address(multicall), - 0, - data, - Enum.Operation.DelegateCall, - 0, - 0, - 0, - address(0), - payable(address(0)), - signatures - ) - ) - }); - - require(success, "call not successful"); - return true; - } else { - console.log("not enough approvals"); - } - - // Reset the approvals because they are only used transiently. - assembly { - sstore(approvals.slot, 0) - } - - return false; - } - - /// @notice Builds the signatures by tightly packing them together. - /// Ensures that they are sorted. - function buildSignatures() internal view returns (bytes memory) { - address[] memory addrs = new address[](approvals.length); - for (uint256 i; i < approvals.length; i++) { - addrs[i] = approvals[i]; - } - - LibSort.sort(addrs); - - bytes memory signatures; - uint8 v = 1; - bytes32 s = bytes32(0); - for (uint256 i; i < addrs.length; i++) { - bytes32 r = bytes32(uint256(uint160(addrs[i]))); - signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); - } - return signatures; - } -} diff --git a/packages/contracts-bedrock/scripts/upgrades/Multichain.s.sol b/packages/contracts-bedrock/scripts/upgrades/Multichain.s.sol deleted file mode 100644 index 1afb79f4c9de..000000000000 --- a/packages/contracts-bedrock/scripts/upgrades/Multichain.s.sol +++ /dev/null @@ -1,492 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { console } from "forge-std/console.sol"; -import { SafeBuilder } from "../universal/SafeBuilder.sol"; -import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol"; -import { IGnosisSafe, Enum } from "../interfaces/IGnosisSafe.sol"; -import { LibSort } from "../libraries/LibSort.sol"; -import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; -import { Constants } from "src/libraries/Constants.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { Semver } from "src/universal/Semver.sol"; - -import { DeployConfig } from "scripts/DeployConfig.s.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; - -/// @title Multichain -/// @notice Upgrade script for upgrading the L1 contracts after the multichain upgrade. -/// This upgrade involves all of the contracts having the same implementations. -/// The implementation addresses are known ahead of time. -/// Configure the network using the `NETWORK` env var, the options are: -/// `goerli-prod`, `chaosnet` and `devnet`. -contract Multichain is SafeBuilder { - /// @notice Address of the ProxyAdmin, passed in via constructor of `run`. - ProxyAdmin internal PROXY_ADMIN; - - /// @notice An instance of the deployconfig contract, the NETWORK env var determines - /// which file is read from disk to populate this contract. - DeployConfig internal cfg; - - /// @notice Represents a set of L1 contracts. Used to represent a set of proxies. - struct ContractSet { - address L1CrossDomainMessenger; - address L1StandardBridge; - address L2OutputOracle; - address OptimismMintableERC20Factory; - address OptimismPortal; - address SystemConfig; - address L1ERC721Bridge; - } - - /// @notice Possible value of NETWORK env var, for goerli - string internal constant GOERLI_PROD = "goerli-prod"; - /// @notice Possible value of NETWORK env var, for chaosnet - string internal constant CHAOSNET = "chaosnet"; - /// @notice Possible value of NETWORK env var, for devnet - string internal constant DEVNET = "devnet"; - /// @notice Digest of goerli-prod for comparison purposes - bytes32 internal goerli = keccak256(bytes(GOERLI_PROD)); - /// @notice Digest of chaosnet for comparison purposes - bytes32 internal chaosnet = keccak256(bytes(CHAOSNET)); - /// @notice Digest of devnet for comparison purposes - bytes32 internal devnet = keccak256(bytes(DEVNET)); - - /// @notice L1CrossDomainMessenger implementation to upgrade to - address internal constant L1CrossDomainMessengerImplementation = 0xb5df97bB67f5AA7254d40E1B7034bBFF7F183a38; - /// @notice L1StandardBridge implementation to upgrade to - address internal constant L1StandardBridgeImplementation = 0xd9aA10f75a2a93Bfc73AaDD41ae777e900CEdBc9; - /// @notice L2OutputOracle implementation to upgrade to - address internal constant L2OutputOracleImplementation = 0xaBd96C062c6B640d5670455E9d1cD98383Dd23CA; - /// @notice OptimismMintableERC20Factory to upgrade to - address internal constant OptimismMintableERC20FactoryImplementation = 0xdfe97868233d1aa22e815a266982f2cf17685a27; - /// @notice OptimismPortal implementation to upgrade to - address internal constant OptimismPortalImplementation = 0x345D27c7B6C90fef5beA9631037C36119f4bF93e; - /// @notice SystemConfig implementation to upgrade to - address internal constant SystemConfigImplementation = 0x543bA4AADBAb8f9025686Bd03993043599c6fB04; - /// @notice L1ERC721Bridge implementation to upgrade to - address internal constant L1ERC721BridgeImplementation = 0x53C115eD8D9902f4999fDBd8B93Ea79BF37cb588; - - /// @notice A mapping of deployment name to ContractSet of proxy addresses. - ContractSet internal proxies; - - /// @notice The expected versions for the contracts to be upgraded to. - string internal constant L1CrossDomainMessengerVersion = "1.5.1"; - string internal constant L1StandardBridgeVersion = "1.2.1"; - string internal constant L2OutputOracleVersion = "1.4.1"; - string internal constant OptimismMintableERC20FactoryVersion = "1.3.0"; - string internal constant OptimismPortalVersion = "1.8.1"; - string internal constant SystemConfigVersion = "1.6.0"; - string internal constant L1ERC721BridgeVersion = "1.2.1"; - - /// @notice The value of the NETWORK env var - string internal NETWORK; - // @notice Cache a non view function call to the SystemConfig contract - uint256 internal l2OutputOracleStartingTimestamp; - - /// @notice Place the contract addresses in storage so they can be used when building calldata. - function setUp() external { - // Set the network in storage - NETWORK = vm.envOr("NETWORK", GOERLI_PROD); - - // TODO: hack - PROXY_ADMIN = ProxyAdmin(vm.envOr("PROXY_ADMIN", 0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d)); - - // For simple comparisons of dynamic types - bytes32 network = keccak256(bytes(NETWORK)); - - string memory deployConfigPath; - if (network == goerli) { - console.log("Using goerli-prod"); - deployConfigPath = string.concat(vm.projectRoot(), "/deploy-config/goerli.json"); - proxies = ContractSet({ - L1CrossDomainMessenger: 0x5086d1eEF304eb5284A0f6720f79403b4e9bE294, - L1StandardBridge: 0x636Af16bf2f682dD3109e60102b8E1A089FedAa8, - L2OutputOracle: 0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0, - OptimismMintableERC20Factory: 0x883dcF8B05364083D849D8bD226bC8Cb4c42F9C5, - OptimismPortal: 0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383, - SystemConfig: 0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60, - L1ERC721Bridge: 0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9 - }); - } else if (network == chaosnet) { - console.log("Using chaosnet"); - deployConfigPath = string.concat(vm.projectRoot(), "/deploy-config/chaosnet.json"); - proxies = ContractSet({ - L1CrossDomainMessenger: 0xfc428D28D197fFf99A5EbAc6be8B761FEd8718Da, - L1StandardBridge: 0x60859421Ed85C0B11071230cf61dcEeEf54630Ff, - L2OutputOracle: 0x7D00A03f180d8C07B88d8c1384a15326c38FF9Ff, - OptimismMintableERC20Factory: 0x526920419b61153c1F80fD306B5Ab52b69110A6C, - OptimismPortal: 0x1566c8Eea4A255C07Ef58edF91431c8A73ae0B62, - SystemConfig: 0xf2Fa3621cAa534a2AE9Eb36667da57890E5C9E6a, - L1ERC721Bridge: 0x058BBf091232afE99BC2481F809254cD15e64Df5 - }); - } else if (network == devnet) { - console.log("Using devnet"); - deployConfigPath = string.concat(vm.projectRoot(), "/deploy-config/internal-devnet.json"); - proxies = ContractSet({ - L1CrossDomainMessenger: 0x71A046D793C71af209960DCb8bD5388d2c5D2a78, - L1StandardBridge: 0x791590936abB3531c9d54CD10CEC4B14415B0Ba7, - L2OutputOracle: 0xA57B9f15AA204b9D68DF58849b02Df16c80C0999, - OptimismMintableERC20Factory: 0x2998dDaF6AaA00Fa8A7104214688d29Bc749B78F, - OptimismPortal: 0x83a242F8481D4F8a605Aa82BA9D42BA574054258, - SystemConfig: 0x9673B370b773D9FFc4C282B3aF315ab05f17E20C, - L1ERC721Bridge: 0x60e0f047FfA2Fad2AF197c9CDb404bDF47277Ed4 - }); - } else { - revert("Invalid network"); - } - - cfg = new DeployConfig(deployConfigPath); - // cache the starting timestamp here as to not break the view functions below - l2OutputOracleStartingTimestamp = cfg.l2OutputOracleStartingTimestamp(); - } - - /// @notice Follow up assertions to ensure that the script ran to completion. - function _postCheck() internal view override { - ContractSet memory prox = getProxies(); - require( - _versionHash(prox.L1CrossDomainMessenger) == keccak256(bytes(L1CrossDomainMessengerVersion)), - "L1CrossDomainMessenger" - ); - require(_versionHash(prox.L1StandardBridge) == keccak256(bytes(L1StandardBridgeVersion)), "L1StandardBridge"); - require(_versionHash(prox.L2OutputOracle) == keccak256(bytes(L2OutputOracleVersion)), "L2OutputOracle"); - require( - _versionHash(prox.OptimismMintableERC20Factory) == keccak256(bytes(OptimismMintableERC20FactoryVersion)), - "OptimismMintableERC20Factory" - ); - require(_versionHash(prox.OptimismPortal) == keccak256(bytes(OptimismPortalVersion)), "OptimismPortal"); - require(_versionHash(prox.SystemConfig) == keccak256(bytes(SystemConfigVersion)), "SystemConfig"); - require(_versionHash(prox.L1ERC721Bridge) == keccak256(bytes(L1ERC721BridgeVersion)), "L1ERC721Bridge"); - - ResourceMetering.ResourceConfig memory rcfg = SystemConfig(prox.SystemConfig).resourceConfig(); - ResourceMetering.ResourceConfig memory dflt = Constants.DEFAULT_RESOURCE_CONFIG(); - require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt))); - - // Check that the codehashes of all implementations match the proxies set implementations. - require( - PROXY_ADMIN.getProxyImplementation(prox.L1CrossDomainMessenger).codehash - == L1CrossDomainMessengerImplementation.codehash, - "L1CrossDomainMessenger codehash" - ); - require( - PROXY_ADMIN.getProxyImplementation(prox.L1StandardBridge).codehash - == L1StandardBridgeImplementation.codehash, - "L1StandardBridge codehash" - ); - require( - PROXY_ADMIN.getProxyImplementation(prox.L2OutputOracle).codehash == L2OutputOracleImplementation.codehash, - "L2OutputOracle codehash" - ); - require( - PROXY_ADMIN.getProxyImplementation(prox.OptimismMintableERC20Factory).codehash - == OptimismMintableERC20FactoryImplementation.codehash, - "OptimismMintableERC20Factory codehash" - ); - require( - PROXY_ADMIN.getProxyImplementation(prox.OptimismPortal).codehash == OptimismPortalImplementation.codehash, - "OptimismPortal codehash" - ); - require( - PROXY_ADMIN.getProxyImplementation(prox.SystemConfig).codehash == SystemConfigImplementation.codehash, - "SystemConfig codehash" - ); - require( - PROXY_ADMIN.getProxyImplementation(prox.L1ERC721Bridge).codehash == L1ERC721BridgeImplementation.codehash, - "L1ERC721Bridge codehash" - ); - - _postCheckSystemConfig(); - _postCheckL1CrossDomainMessenger(); - _postCheckL1StandardBridge(); - _postCheckL2OutputOracle(); - _postCheckOptimismMintableERC20Factory(); - _postCheckL1ERC721Bridge(); - _postCheckOptimismPortal(); - } - - /// @notice Post check hook for the system config - function _postCheckSystemConfig() internal view { - SystemConfig config = SystemConfig(proxies.SystemConfig); - - require(config.owner() == cfg.finalSystemOwner()); - require(config.overhead() == cfg.gasPriceOracleOverhead()); - require(config.scalar() == cfg.gasPriceOracleScalar()); - require(config.unsafeBlockSigner() == cfg.p2pSequencerAddress()); - require(config.batcherHash() == bytes32(uint256(uint160(cfg.batchSenderAddress())))); - - ResourceMetering.ResourceConfig memory rconfig = Constants.DEFAULT_RESOURCE_CONFIG(); - ResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig(); - require(resourceConfig.maxResourceLimit == rconfig.maxResourceLimit); - require(resourceConfig.elasticityMultiplier == rconfig.elasticityMultiplier); - require(resourceConfig.baseFeeMaxChangeDenominator == rconfig.baseFeeMaxChangeDenominator); - require(resourceConfig.systemTxMaxGas == rconfig.systemTxMaxGas); - require(resourceConfig.minimumBaseFee == rconfig.minimumBaseFee); - require(resourceConfig.maximumBaseFee == rconfig.maximumBaseFee); - - require(config.l1ERC721Bridge() == proxies.L1ERC721Bridge); - require(config.l1StandardBridge() == proxies.L1StandardBridge); - require(config.l2OutputOracle() == proxies.L2OutputOracle); - require(config.optimismPortal() == proxies.OptimismPortal); - require(config.l1CrossDomainMessenger() == proxies.L1CrossDomainMessenger); - - // A non zero start block is an override - uint256 startBlock = cfg.systemConfigStartBlock(); - if (startBlock != 0) { - require(config.startBlock() == startBlock); - } else { - require(config.startBlock() == block.number); - } - } - - /// @notice Post check hook for the L1CrossDomainMessenger - function _postCheckL1CrossDomainMessenger() internal view { - L1CrossDomainMessenger messenger = L1CrossDomainMessenger(proxies.L1CrossDomainMessenger); - require(address(messenger.portal()) == proxies.OptimismPortal); - } - - /// @notice Post check hook for the L1StandardBridge - function _postCheckL1StandardBridge() internal view { - L1StandardBridge bridge = L1StandardBridge(payable(proxies.L1StandardBridge)); - require(address(bridge.MESSENGER()) == proxies.L1CrossDomainMessenger); - require(address(bridge.messenger()) == proxies.L1CrossDomainMessenger); - require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE); - require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE); - // Ensures that the legacy slot is modified correctly. This will fail - // during predeployment simulation on OP Mainnet if there is a bug. - bytes32 slot0 = vm.load(address(bridge), bytes32(uint256(0))); - require(slot0 == bytes32(uint256(2))); - } - - /// @notice Post check hook for the L2OutputOracle - function _postCheckL2OutputOracle() internal view { - L2OutputOracle oracle = L2OutputOracle(proxies.L2OutputOracle); - require(oracle.SUBMISSION_INTERVAL() == cfg.l2OutputOracleSubmissionInterval()); - require(oracle.submissionInterval() == cfg.l2OutputOracleSubmissionInterval()); - require(oracle.L2_BLOCK_TIME() == cfg.l2BlockTime()); - require(oracle.l2BlockTime() == cfg.l2BlockTime()); - require(oracle.PROPOSER() == cfg.l2OutputOracleProposer()); - require(oracle.proposer() == cfg.l2OutputOracleProposer()); - require(oracle.CHALLENGER() == cfg.l2OutputOracleChallenger()); - require(oracle.challenger() == cfg.l2OutputOracleChallenger()); - require(oracle.FINALIZATION_PERIOD_SECONDS() == cfg.finalizationPeriodSeconds()); - require(oracle.finalizationPeriodSeconds() == cfg.finalizationPeriodSeconds()); - require(oracle.startingBlockNumber() == cfg.l2OutputOracleStartingBlockNumber()); - require(oracle.startingTimestamp() == l2OutputOracleStartingTimestamp); - } - - /// @notice Post check hook for the OptimismMintableERC20Factory - function _postCheckOptimismMintableERC20Factory() internal view { - OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(proxies.OptimismMintableERC20Factory); - require(factory.BRIDGE() == proxies.L1StandardBridge); - } - - /// @notice Post check hook for the L1ERC721Bridge - function _postCheckL1ERC721Bridge() internal view { - L1ERC721Bridge bridge = L1ERC721Bridge(proxies.L1ERC721Bridge); - require(address(bridge.MESSENGER()) == proxies.L1CrossDomainMessenger); - require(bridge.OTHER_BRIDGE() == Predeploys.L2_ERC721_BRIDGE); - } - - /// @notice Post check hook for the OptimismPortal - function _postCheckOptimismPortal() internal view { - OptimismPortal portal = OptimismPortal(payable(proxies.OptimismPortal)); - require(address(portal.L2_ORACLE()) == proxies.L2OutputOracle); - require(portal.GUARDIAN() == cfg.portalGuardian()); - require(address(portal.SYSTEM_CONFIG()) == proxies.SystemConfig); - require(portal.paused() == false); - } - - /// @notice Test coverage of the logic. Should only run on goerli but other chains - /// could be added. - function test_script_succeeds() external skipWhenNotForking { - address _safe; - address _proxyAdmin; - - if (block.chainid == GOERLI) { - _safe = 0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f; - _proxyAdmin = 0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d; - // Set the proxy admin for the `_postCheck` function - PROXY_ADMIN = ProxyAdmin(_proxyAdmin); - } - - require(_safe != address(0) && _proxyAdmin != address(0)); - - address[] memory owners = IGnosisSafe(payable(_safe)).getOwners(); - for (uint256 i; i < owners.length; i++) { - address owner = owners[i]; - vm.startBroadcast(owner); - bool success = _run(_safe, _proxyAdmin); - vm.stopBroadcast(); - - if (success) { - console.log("tx success"); - break; - } - } - - _postCheck(); - } - - /// @notice Builds the calldata that the multisig needs to make for the upgrade to happen. - /// A total of 8 calls are made, 7 upgrade implementations and 1 sets the resource - /// config to the default value in the SystemConfig contract. - function buildCalldata(address _proxyAdmin) internal view override returns (bytes memory) { - IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](7); - - ContractSet memory prox = getProxies(); - - // Upgrade the L1CrossDomainMessenger - calls[0] = IMulticall3.Call3({ - target: _proxyAdmin, - allowFailure: false, - callData: abi.encodeCall( - ProxyAdmin.upgradeAndCall, - ( - payable(prox.L1CrossDomainMessenger), // proxy - L1CrossDomainMessengerImplementation, // implementation - abi.encodeCall( // data - L1CrossDomainMessenger.initialize, (OptimismPortal(payable(prox.OptimismPortal)))) - ) - ) - }); - - // Upgrade the L1StandardBridge - calls[1] = IMulticall3.Call3({ - target: _proxyAdmin, - allowFailure: false, - callData: abi.encodeCall( - ProxyAdmin.upgradeAndCall, - ( - payable(prox.L1StandardBridge), // proxy - L1StandardBridgeImplementation, // implementation - abi.encodeCall(L1StandardBridge.initialize, (L1CrossDomainMessenger(prox.L1CrossDomainMessenger))) // data - ) - ) - }); - - // Upgrade the L2OutputOracle - calls[2] = IMulticall3.Call3({ - target: _proxyAdmin, - allowFailure: false, - callData: abi.encodeCall( - ProxyAdmin.upgradeAndCall, - ( - payable(prox.L2OutputOracle), // proxy - L2OutputOracleImplementation, // implementation - abi.encodeCall( // data - L2OutputOracle.initialize, - ( - cfg.l2OutputOracleStartingBlockNumber(), - l2OutputOracleStartingTimestamp, - cfg.l2OutputOracleProposer(), - cfg.l2OutputOracleChallenger() - ) - ) - ) - ) - }); - - // Upgrade the OptimismMintableERC20Factory. No initialize function. - calls[3] = IMulticall3.Call3({ - target: _proxyAdmin, - allowFailure: false, - callData: abi.encodeCall( - ProxyAdmin.upgradeAndCall, - ( - payable(prox.OptimismMintableERC20Factory), // proxy - OptimismMintableERC20FactoryImplementation, // implementation - abi.encodeCall( // data - OptimismMintableERC20Factory.initialize, (prox.L1StandardBridge)) - ) - ) - }); - - // Upgrade the OptimismPortal - calls[4] = IMulticall3.Call3({ - target: _proxyAdmin, - allowFailure: false, - callData: abi.encodeCall( - ProxyAdmin.upgradeAndCall, - ( - payable(prox.OptimismPortal), // proxy - OptimismPortalImplementation, // implementation - abi.encodeCall( // data - OptimismPortal.initialize, - ( - L2OutputOracle(prox.L2OutputOracle), - cfg.portalGuardian(), - SystemConfig(prox.SystemConfig), - false - ) - ) - ) - ) - }); - - // Upgrade the SystemConfig - calls[5] = IMulticall3.Call3({ - target: _proxyAdmin, - allowFailure: false, - callData: abi.encodeCall( - ProxyAdmin.upgradeAndCall, - ( - payable(prox.SystemConfig), // proxy - SystemConfigImplementation, // implementation - abi.encodeCall( // data - SystemConfig.initialize, - ( - cfg.finalSystemOwner(), - cfg.gasPriceOracleOverhead(), - cfg.gasPriceOracleScalar(), - bytes32(uint256(uint160(cfg.batchSenderAddress()))), - uint64(cfg.l2GenesisBlockGasLimit()), - cfg.p2pSequencerAddress(), - Constants.DEFAULT_RESOURCE_CONFIG(), - cfg.systemConfigStartBlock(), - cfg.batchInboxAddress(), - SystemConfig.Addresses({ - l1CrossDomainMessenger: prox.L1CrossDomainMessenger, - l1ERC721Bridge: prox.L1ERC721Bridge, - l1StandardBridge: prox.L1StandardBridge, - l2OutputOracle: prox.L2OutputOracle, - optimismPortal: prox.OptimismPortal, - optimismMintableERC20Factory: prox.OptimismMintableERC20Factory - }) - ) - ) - ) - ) - }); - - // Upgrade the L1ERC721Bridge - calls[6] = IMulticall3.Call3({ - target: _proxyAdmin, - allowFailure: false, - callData: abi.encodeCall( - ProxyAdmin.upgradeAndCall, - ( - payable(prox.L1ERC721Bridge), - L1ERC721BridgeImplementation, - abi.encodeCall(L1ERC721Bridge.initialize, (L1CrossDomainMessenger(prox.L1CrossDomainMessenger))) - ) - ) - }); - - return abi.encodeCall(IMulticall3.aggregate3, (calls)); - } - - /// @notice Returns the ContractSet that represents the proxies for a given network. - /// Configure the network with the NETWORK env var. - function getProxies() internal view returns (ContractSet memory) { - require(proxies.L1CrossDomainMessenger != address(0), "no proxies for this network"); - return proxies; - } -} diff --git a/packages/contracts-bedrock/scripts/validate-spacers.ts b/packages/contracts-bedrock/scripts/validate-spacers.ts deleted file mode 100644 index 493bc77da0ea..000000000000 --- a/packages/contracts-bedrock/scripts/validate-spacers.ts +++ /dev/null @@ -1,182 +0,0 @@ -import fs from 'fs' -import path from 'path' - -import layoutLock from '../layout-lock.json' - -/** - * Directory path to the artifacts. - * Can be configured as the first argument to the script or - * defaults to the forge-artifacts directory. - */ -const directoryPath = - process.argv[2] || path.join(__dirname, '..', 'forge-artifacts') - -/** - * Returns true if the contract should be skipped when inspecting its storage layout. - * This is useful for abstract contracts that are meant to be inherited. - * The two particular targets are: - * - CrossDomainMessengerLegacySpacer0 - * - CrossDomainMessengerLegacySpacer1 - */ -const skipped = (contractName: string): boolean => { - return contractName.includes('CrossDomainMessengerLegacySpacer') -} - -/** - * Parses the fully qualified name of a contract into the name of the contract. - * For example `contracts/Foo.sol:Foo` becomes `Foo`. - */ -const parseFqn = (name: string): string => { - const parts = name.split(':') - return parts[parts.length - 1] -} - -/** - * Parses out variable info from the variable structure in standard compiler json output. - * - * @param variable Variable structure from standard compiler json output. - * @returns Parsed variable info. - */ -const parseVariableInfo = ( - variable: any -): { - name: string - slot: number - offset: number - length: number -} => { - // Figure out the length of the variable. - let variableLength: number - if (variable.type.startsWith('t_mapping')) { - variableLength = 32 - } else if (variable.type.startsWith('t_uint')) { - variableLength = variable.type.match(/uint([0-9]+)/)?.[1] / 8 - } else if (variable.type.startsWith('t_bytes_')) { - variableLength = 32 - } else if (variable.type.startsWith('t_bytes')) { - variableLength = variable.type.match(/uint([0-9]+)/)?.[1] - } else if (variable.type.startsWith('t_address')) { - variableLength = 20 - } else if (variable.type.startsWith('t_bool')) { - variableLength = 1 - } else if (variable.type.startsWith('t_array')) { - // Figure out the size of the type inside of the array - // and then multiply that by the length of the array. - // This does not support recursion multiple times for simplicity - const type = variable.type.match(/^t_array\((\w+)\)/)?.[1] - const info = parseVariableInfo({ - label: variable.label, - offset: variable.offset, - slot: variable.slot, - type, - }) - const size = variable.type.match(/^t_array\(\w+\)([0-9]+)/)?.[1] - variableLength = info.length * parseInt(size, 10) - } else { - throw new Error( - `${variable.label}: unsupported type ${variable.type}, add it to the script` - ) - } - - return { - name: variable.label, - slot: parseInt(variable.slot, 10), - offset: variable.offset, - length: variableLength, - } -} - -/** - * Main logic of the script - * - Ensures that all of the spacer variables are named correctly - * - Ensures that storage slots in the layout lock file do not change - */ -const main = async () => { - const paths = [] - - const readFilesRecursively = (dir: string) => { - const files = fs.readdirSync(dir) - - for (const file of files) { - const filePath = path.join(dir, file) - const fileStat = fs.statSync(filePath) - - if (fileStat.isDirectory()) { - readFilesRecursively(filePath) - } else { - paths.push(filePath) - } - } - } - - readFilesRecursively(directoryPath) - - for (const filePath of paths) { - if (filePath.includes('t.sol')) { - continue - } - const raw = fs.readFileSync(filePath, 'utf8').toString() - const artifact = JSON.parse(raw) - - // Handle contracts without storage - const storageLayout = artifact.storageLayout || {} - if (storageLayout.storage) { - for (const variable of storageLayout.storage) { - const fqn = variable.contract - // Skip some abstract contracts - if (skipped(fqn)) { - continue - } - - const contractName = parseFqn(fqn) - - // Check that the layout lock has not changed - const lock = layoutLock[contractName] || {} - if (lock[variable.label]) { - const variableInfo = parseVariableInfo(variable) - const expectedInfo = lock[variable.label] - if (variableInfo.slot !== expectedInfo.slot) { - throw new Error(`${fqn}.${variable.label} slot has changed`) - } - if (variableInfo.offset !== expectedInfo.offset) { - throw new Error(`${fqn}.${variable.label} offset has changed`) - } - if (variableInfo.length !== expectedInfo.length) { - throw new Error(`${fqn}.${variable.label} length has changed`) - } - } - - // Check that the spacers are all named correctly - if (variable.label.startsWith('spacer_')) { - const [, slot, offset, length] = variable.label.split('_') - const variableInfo = parseVariableInfo(variable) - - // Check that the slot is correct. - if (parseInt(slot, 10) !== variableInfo.slot) { - throw new Error( - `${fqn} ${variable.label} is in slot ${variable.slot} but should be in ${slot}` - ) - } - - // Check that the offset is correct. - if (parseInt(offset, 10) !== variableInfo.offset) { - throw new Error( - `${fqn} ${variable.label} is at offset ${variable.offset} but should be at ${offset}` - ) - } - - // Check that the length is correct. - if (parseInt(length, 10) !== variableInfo.length) { - throw new Error( - `${fqn} ${variable.label} is ${variableInfo.length} bytes long but should be ${length}` - ) - } - - console.log(`${fqn}.${variable.label} is valid`) - } - } - } - } -} - -main() diff --git a/packages/contracts-bedrock/scripts/verify-foundry-install.sh b/packages/contracts-bedrock/scripts/verify-foundry-install.sh deleted file mode 100755 index 2c21ded65830..000000000000 --- a/packages/contracts-bedrock/scripts/verify-foundry-install.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -if ! command -v forge &> /dev/null -then - echo "Is Foundry not installed? Consider installing via `curl -L https://foundry.paradigm.xyz | bash` and then running `foundryup` on a new terminal. For more context, check the installation instructions in the book: https://book.getfoundry.sh/getting-started/installation.html." - exit 1 -fi - -VERSION=$(forge --version) -echo "Using foundry version: $VERSION" diff --git a/packages/contracts-bedrock/scripts/visualize.sh b/packages/contracts-bedrock/scripts/visualize.sh new file mode 100644 index 000000000000..4fb3078ebe70 --- /dev/null +++ b/packages/contracts-bedrock/scripts/visualize.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +RPC="${1:?Must specify RPC address}" +FAULT_GAME_ADDRESS="${2:?Must specify game address}" + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DIR="${DIR%/*}" +cd "$DIR" + +forge script scripts/FaultDisputeGameViz.s.sol \ + --sig "remote(address)" "$FAULT_GAME_ADDRESS" \ + --fork-url "$RPC" diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index baf78554fc45..1b5507af099b 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -1,38 +1,170 @@ { - "src/EAS/EAS.sol": "0xea04b7a9ec170ce9cbd466ede87650f9e9ffe3d725d7951cef5777a98a840173", - "src/EAS/SchemaRegistry.sol": "0x5ee1a0c3b2bf1eb5edb53fb0967cf13856be546f0f16fe7acdc3e4f286db6831", - "src/L1/DelayedVetoable.sol": "0x276c6276292095e6aa37a70008cf4e0d1cbcc020dbc9107459bbc72ab5ed744f", - "src/L1/L1CrossDomainMessenger.sol": "0x2aa4e06827bc48484212eb2bdc30fd604ffd23b37e401b78ef428c12fa9b8385", - "src/L1/L1ERC721Bridge.sol": "0x18219b763fcff3caf54c9fc590ada9e1e2ead50bce1f68f232d444b27ad0fb23", - "src/L1/L1StandardBridge.sol": "0xdf268cf35ddb89c4c820bd19e13eb43e91c837e0d10fea704cb4d5676baa6e8f", - "src/L1/L2OutputOracle.sol": "0x1cfa6e41f3449896d2b0f5fba85d759acefe7012d6bffbcdf0bba883a78b50ee", - "src/L1/OptimismPortal.sol": "0xc4753409d6aca7f7b8a48b9a8ac9542a5c5e0b7e7cb71ca3b6b35dd714806c73", - "src/L1/ProtocolVersions.sol": "0xfc92dfc0e4518470c48c74fa9c5b15347da2a791273afd1968ac3eada7c45dd6", - "src/L1/SystemConfig.sol": "0x9b1c9225283d4944ad722d11d5650a0d84809156cfb1bcab8a7288bc3e5f247f", - "src/L2/BaseFeeVault.sol": "0xe36f9be65c910694e60a14f266f9b6569f01b4ddd74fa0557305eb83e7e9d112", - "src/L2/GasPriceOracle.sol": "0x88efffbd40f8d012d700a5d7fde0d92266f65e9d7006cd8f034bacaa036d0eb2", - "src/L2/L1Block.sol": "0x1ed9aa36036ded00a0383692eca81a22f668d64e22af973559d2ccefc86825c0", - "src/L2/L1FeeVault.sol": "0x6a7a9a262c0a4c9781d812ea343f984944a8dd2b45bc1967dfcc3805c0053518", - "src/L2/L2CrossDomainMessenger.sol": "0x8fe4a79b3e8dd4d53dcd437c1731503beec744836273c114960f1a60ff38a930", - "src/L2/L2ERC721Bridge.sol": "0xdbe75ee8c8163ed5164cc6b293e422c718303b46a8df91e832fa9e5c6a023fb6", - "src/L2/L2StandardBridge.sol": "0x284ebf5569c75d98f2d1920a276d1116524399355708c4a60ea5892283c56719", - "src/L2/L2ToL1MessagePasser.sol": "0xafc710b4d320ef450586d96a61cbd58cac814cb3b0c4fdc280eace3efdcdf321", - "src/L2/SequencerFeeVault.sol": "0x883e434a69b4789997a4a9a32060dbbd2e12db6f1970927f1310820336119575", - "src/Safe/LivenessGuard.sol": "0xa08460138c22a337f8f5d3a17e02beffe8136c4dba58935cc5c9c2d7ffe1222c", - "src/Safe/LivenessModule.sol": "0x45621d74ea464c75064f9194261d29d47552cf4a9c4f4b3a733f5df5803fc0dd", - "src/dispute/BlockOracle.sol": "0x7e724b1ee0116dfd744f556e6237af449c2f40c6426d6f1462ae2a47589283bb", - "src/dispute/DisputeGameFactory.sol": "0xfdfa141408d7f8de7e230ff4bef088e30d0e4d569ca743d60d292abdd21ff270", - "src/dispute/FaultDisputeGame.sol": "0x0766707ab32338a6586c2340ddfbfd4e9023eeb9dfa3ef87e4b404fb0260479f", - "src/legacy/DeployerWhitelist.sol": "0x0a6840074734c9d167321d3299be18ef911a415e4c471fa92af7d6cfaa8336d4", - "src/legacy/L1BlockNumber.sol": "0x20d83a636c5e2067fca8c0ed505b295174e6eddb25960d8705e6b6fea8e77fa6", - "src/legacy/LegacyMessagePasser.sol": "0x80f355c9710af586f58cf6a86d1925e0073d1e504d0b3d814284af1bafe4dece", - "src/periphery/op-nft/AttestationStation.sol": "0x9cf6f2fd909f9bcff229a137198186749a839cfa3d11ddbb3021fe71c30a2fa9", - "src/periphery/op-nft/Optimist.sol": "0x38407f766aa9d394403e9da388dd0265b48901789f3e8a28af50014f9f5251d9", - "src/periphery/op-nft/OptimistAllowlist.sol": "0x53e9a9dfecbae036fd468e8f34c80c7d9c35bd8908c8a6483db44dbc5128ad69", - "src/periphery/op-nft/OptimistInviter.sol": "0xfdd5b9d45205ef9372ba37f7a6394724695e676d27a47cb154ee6e4148490013", - "src/universal/OptimismMintableERC20.sol": "0x716db294648fce1bb41c5f95a20f92445f165a568886f21edd922d5c9b2cb0b5", - "src/universal/OptimismMintableERC20Factory.sol": "0xfcf2eb56777478f47f3bf2f1111aa2e3769d5ed28a6f5fceff4517683447131a", - "src/universal/OptimismMintableERC721.sol": "0x4c73bf8474fa7eb091796a4db7e57bc5f26d50a3d1cfcb78d5efa47ced5ced2b", - "src/universal/OptimismMintableERC721Factory.sol": "0x935fd97018b6ef10fa813d9d43ab7a77c80885f7a8d7feb430097645cb2abd2c", - "src/universal/StorageSetter.sol": "0x6372647d8a67d243bc2fb40d2c4bf5807022d94d52d9423cfed27a7d57918635" + "src/EAS/EAS.sol": { + "initCodeHash": "0x1a097f352425b503a28c795dbfd390f2bc330e9c1f8a27bd26cf243b6c703499", + "sourceCodeHash": "0x23287e96b00c31ab57b05090525afdebf8e45ca09253a21b95052cf7d94e071b" + }, + "src/EAS/SchemaRegistry.sol": { + "initCodeHash": "0xf4c3155413be4a4ebaaba66b9f9daaf12db7b090afdea739dfb8a543df357289", + "sourceCodeHash": "0x2ed7a2d6d66839fb3d207952f44b001bce349334adc40ce66d0503ce64e48548" + }, + "src/L1/DataAvailabilityChallenge.sol": { + "initCodeHash": "0x39d938938b13abb2455959960c2ee96d48149fd16a7fb69f1f6699460d5019be", + "sourceCodeHash": "0xf6c72a2cca24cfa7c9274d720e93b05d665a2751cca3d747105e6c511ccffc73" + }, + "src/L1/DelayedVetoable.sol": { + "initCodeHash": "0x84f78e56211500a768b2c5bbafde8e7b411bd64c237297370d7d22326b68357c", + "sourceCodeHash": "0xc59b8574531162e016d7342aeb6e79d05574e90dbea6c0e5ede35b65010ad894" + }, + "src/L1/L1CrossDomainMessenger.sol": { + "initCodeHash": "0xb0b3273999191e4ff616509e3a368a9d89f7967c20ba73c1bc5bd72bd13acb16", + "sourceCodeHash": "0x6c86ba9f20f54ac834ad846e6302f892b7576dd407db595ebaba017971471eb4" + }, + "src/L1/L1ERC721Bridge.sol": { + "initCodeHash": "0xec73b46e68ea29298707f7b9709e7948afe303907b6c4e8b161e2ded2c85ee9c", + "sourceCodeHash": "0xd57acdbd001941e75cf4326ba7c1bdad809912f10b1e44ffaebe073917cdd296" + }, + "src/L1/L1StandardBridge.sol": { + "initCodeHash": "0xb0166b741e0b6938c004c19de78f347171e2656056a0363434ebd0f34a6a32ca", + "sourceCodeHash": "0x654f9490dd2d0bc9e92dc31781e62f106f6b7d8b6fca0cfe718cd2a599c1b18b" + }, + "src/L1/L2OutputOracle.sol": { + "initCodeHash": "0x14c3a582ca46ef2a6abad5590323f4de26ff4de54415c927c62e131ccbf8d9ba", + "sourceCodeHash": "0xf5fcf570721e25459fadbb37e02f9efe349e1c8afcbf1e3b5fdb09c9f612cdc0" + }, + "src/L1/OptimismPortal.sol": { + "initCodeHash": "0x54658799b54481f56acb6481db4f37ad830a8238a8fd592c96e8b1a2b60e0627", + "sourceCodeHash": "0xf549ae16033b63e7cb3e032898a6495e1a13090dc8dd1422f7f650076ae973f8" + }, + "src/L1/OptimismPortal2.sol": { + "initCodeHash": "0xd2947b6ce4c5976d550c84d72f14ead2c92f27449edc98ca8ef92b3e9c02b367", + "sourceCodeHash": "0x477df849308119f516e21e3c44e72422c1afa919fad5351be5046d3ec9f0e11f" + }, + "src/L1/ProtocolVersions.sol": { + "initCodeHash": "0x72cd467e8bcf019c02675d72ab762e088bcc9cc0f1a4e9f587fa4589f7fdd1b8", + "sourceCodeHash": "0xbd56a23cd3221cb9d25029e80cd9f2afe2c615ae9c0b3956bf6ed373b8b805b6" + }, + "src/L1/SuperchainConfig.sol": { + "initCodeHash": "0xa71c67640d6a25c750fef910a5fe85776ebb7bb18c677bb1b9b95c2f3f561b0c", + "sourceCodeHash": "0xd6a894e371c2c7182b5960c507491f81c3775dda0efedd29475f7c30ca07b004" + }, + "src/L1/SystemConfig.sol": { + "initCodeHash": "0xa14bfe090e923acbacb361d9aa60e0d56fc1dff158ddbd1dc221a5380679f37f", + "sourceCodeHash": "0x58d078f2f352ccb9001afe8245f4655b47ed0227189ede9ef56523b2193059bd" + }, + "src/L2/BaseFeeVault.sol": { + "initCodeHash": "0x2744d34573be83206d1b75d049d18a7bb37f9058e68c0803e5008c46b0dc2474", + "sourceCodeHash": "0xd787bd2a192ba5025fa0a8de2363af66a8de20de226e411bdb576adb64636cd0" + }, + "src/L2/GasPriceOracle.sol": { + "initCodeHash": "0xfd456e91d8c9714590a4f0a2c1046ba70e102f1c629ead886c4eebc3f921c3c3", + "sourceCodeHash": "0xde06becce9514f46ba78b4cb0732c7a714d49ba8f131258d56a5f5b22b51be7e" + }, + "src/L2/L1Block.sol": { + "initCodeHash": "0xda6828a2a6e02d9fde7d5d9947f51b207f31abf5dbb538dd968cd491164e2115", + "sourceCodeHash": "0x775c399d93a729e1d3fe9a67c015f529f0c17a5986f93cd8d0f7806414fc5cdc" + }, + "src/L2/L1FeeVault.sol": { + "initCodeHash": "0x2744d34573be83206d1b75d049d18a7bb37f9058e68c0803e5008c46b0dc2474", + "sourceCodeHash": "0x3a94f273937d8908fb37dd2c495a6a0b9c3941fe68ccea51723f84eb343ba225" + }, + "src/L2/L2CrossDomainMessenger.sol": { + "initCodeHash": "0xfeedd51cc3159f814f6aee9e54cbba1c9a2fa4079fa40c00871889bc1c98c902", + "sourceCodeHash": "0x9993c85445b4a00153d7bbfb8259d920d0b1b6c9fd557c65ad8df47119e55275" + }, + "src/L2/L2ERC721Bridge.sol": { + "initCodeHash": "0xcafa012b2d8f1bb05c11cbbff9749c0fe6f995c9afb1d26d2d71f03384e34a22", + "sourceCodeHash": "0xa7646a588275046f92525ef121e5a0fe149e7752ea51fe62f7e0686a21153542" + }, + "src/L2/L2StandardBridge.sol": { + "initCodeHash": "0xe16aed4fc021c768d0ebcb8bb83db7cfe6b062663d034df9f351cdc6af2e5077", + "sourceCodeHash": "0xc86e370a8cd1277b203d18df154a50aed16b27156b755e6bd6672d068d44b9f2" + }, + "src/L2/L2ToL1MessagePasser.sol": { + "initCodeHash": "0x08bbede75cd6dfd076903b8f04d24f82fa7881576c135825098778632e37eebc", + "sourceCodeHash": "0x8388b9b8075f31d580fed815b66b45394e40fb1a63cd8cda2272d2c390fc908c" + }, + "src/L2/SequencerFeeVault.sol": { + "initCodeHash": "0xd62e193d89b1661d34031227a45ce1eade9c2a89b0bd7f362f511d03cceef294", + "sourceCodeHash": "0xa304b4b556162323d69662b4dd9a1d073d55ec661494465489bb67f1e465e7b3" + }, + "src/Safe/LivenessGuard.sol": { + "initCodeHash": "0x16ec47f0888391638814047a1735dbac849b48e256b2e20182bbb3186d950a3c", + "sourceCodeHash": "0x9633cea9b66077e222f470439fe3e9a31f3e33b4f7a5618374c44310fd234b24" + }, + "src/Safe/LivenessModule.sol": { + "initCodeHash": "0x0da844fb4dd22f252ff631524f01f45edf43bca7558fe45f71d711b79af01742", + "sourceCodeHash": "0x1afb1d392e8f6a58ff86ea7f648e0d1756d4ba8d0d964279d58a390deaa53b7e" + }, + "src/cannon/MIPS.sol": { + "initCodeHash": "0xaf2ac814f64ccf12e9c6738db7cef865f51f9e39f39105adef9fba11465f6ee1", + "sourceCodeHash": "0x6ab593a4b87007c000c254b2c4ff0507683600f48b60e453148e44bee30030f6" + }, + "src/cannon/PreimageOracle.sol": { + "initCodeHash": "0x9e0d25588d96934044c6f20b62b21444d734c85fe86b305efd8d226024e92725", + "sourceCodeHash": "0xa2d7d5a1de4159a41ff99c2f05d33b9b472c2d00ea62f817b372988f56650153" + }, + "src/dispute/AnchorStateRegistry.sol": { + "initCodeHash": "0x2f8c56069e43e306b0e40fba43109188b29328e83569560021a68aa5d9f2486b", + "sourceCodeHash": "0xba941ad1f941f5a4a066182d50634fa9b190085ed82779decef71c019ba963c5" + }, + "src/dispute/DisputeGameFactory.sol": { + "initCodeHash": "0x80d749a56c1776930fe0deb5c3c646217716e5875ace99c4d036af0452236476", + "sourceCodeHash": "0xf897c1a845a16cb8b217135a1c7819cdb20b315567066282f5860251e48d3611" + }, + "src/dispute/FaultDisputeGame.sol": { + "initCodeHash": "0x9dcd4df1dd3e7a09dab46bfe1ebd9376f533cc533f9edce2f01aa754301e25aa", + "sourceCodeHash": "0xbe89df391f9cd4165389a7f6f65af752db13d0e508a1ec8430737aba5b7174dc" + }, + "src/dispute/weth/DelayedWETH.sol": { + "initCodeHash": "0xf179e4249be6eda22b24ae2b32717f154f35edeb9dee0332aefa6fad3ace4dbe", + "sourceCodeHash": "0x1a37c92242f612588f60256554107ee675678687b49b1f41087411dfcd6aabd3" + }, + "src/legacy/DeployerWhitelist.sol": { + "initCodeHash": "0x8de80fb23b26dd9d849f6328e56ea7c173cd9e9ce1f05c9beea559d1720deb3d", + "sourceCodeHash": "0xb518a9f56136a910f2450098b4823c9982f93883fe4a9ef6f6b0a89355965d38" + }, + "src/legacy/L1BlockNumber.sol": { + "initCodeHash": "0xd586c4f93caf1753e53fcdc05eb547c1f3a69afda2904ae9f9d851b73e1c9c1d", + "sourceCodeHash": "0xed7d0d1695f28bf967626ee58debcf235204ecc5e814f53da369c94a9ed7cf0d" + }, + "src/legacy/LegacyMessagePasser.sol": { + "initCodeHash": "0x024ff54be1762f8946c6dc1796517bd5e622349a26a908f78a31872969f10369", + "sourceCodeHash": "0x31f66f771d912ed4fe06c166f4b1c44d9f2bce8537ab42271c3900360966999f" + }, + "src/periphery/op-nft/AttestationStation.sol": { + "initCodeHash": "0xf9b8ff2ecdcaca2b1521a96f0ebaea2d77aeb986ff1b9b7d82fb0cbc63f9169a", + "sourceCodeHash": "0x81ba07ca8d0bedf3b0d0ff054d68fcc6dca52a4da0ca5c8624cee92f20a87c37" + }, + "src/periphery/op-nft/Optimist.sol": { + "initCodeHash": "0x468354be7d17863a587b1f1daf220c17697e57c76cba8e0082d7afec4aafea49", + "sourceCodeHash": "0x3ceeaab5b013968b226b3c97e202a3af4946590763b2002d1bc36ae8776c78fe" + }, + "src/periphery/op-nft/OptimistAllowlist.sol": { + "initCodeHash": "0xbe1a89f077473c298ce96be5eb5e5a0ec97968f24c7ef843e1f9fee1c57087e4", + "sourceCodeHash": "0x077967c4c1b99396481c91464237e696f12974c864470b2ef39ffa3756a58ac0" + }, + "src/periphery/op-nft/OptimistInviter.sol": { + "initCodeHash": "0xefc67e1be541adfc92f9a5bef36746477299f5e76a4601c12f802af52fb02253", + "sourceCodeHash": "0x323f707d4cebc38f59f9241098a1d7e5e790ffcaf1719065edabf4cb794ac745" + }, + "src/universal/OptimismMintableERC20.sol": { + "initCodeHash": "0x7c6e1cf86cf8622d8beceafa3610ff88eceb3b0fafff0491bfa26a7b876c4d9a", + "sourceCodeHash": "0x52737b23e99bf79dd2c23196b3298e80aa41f740efc6adc7916e696833eb546a" + }, + "src/universal/OptimismMintableERC20Factory.sol": { + "initCodeHash": "0xf6f522681e7ae940cb778db68004f122b25194296a65bba7ad1d792bd593c4a6", + "sourceCodeHash": "0x9b8c73ea139f13028008eedef53a6b07576cd6b08979574e6dde3192656e9268" + }, + "src/universal/OptimismMintableERC721.sol": { + "initCodeHash": "0xb400f430acf4d65bee9635e4935a6e1e3a0284fc50aea40ad8b7818dc826f31c", + "sourceCodeHash": "0xd4bb4d1e16f545976302109ab0234ae785afa52de820553d67ebd9f147e4b994" + }, + "src/universal/OptimismMintableERC721Factory.sol": { + "initCodeHash": "0x5504069cb1377405bf5c6f1b37ea02057fdb452cf85922cc83dffd5390cad7da", + "sourceCodeHash": "0xf8f2f0f6bc3cdbacbb1ef8b3fa31897a1eb749af0ba14b19b0cbc1cf0e6271f8" + }, + "src/universal/StorageSetter.sol": { + "initCodeHash": "0xb656d2aa6aff3e6435e747a0c23236d1b66f1f5c0b45e4b1a10d290a90223c5a", + "sourceCodeHash": "0xebfc968e6b78d7ea355547d427300739f14d000a11ff35f29d9ded3ddb7882da" + } } \ No newline at end of file diff --git a/packages/contracts-bedrock/slither.config.json b/packages/contracts-bedrock/slither.config.json index 3f5fb20b4441..7b1af2283925 100644 --- a/packages/contracts-bedrock/slither.config.json +++ b/packages/contracts-bedrock/slither.config.json @@ -1,15 +1,10 @@ { - "detectors_to_exclude": "incorrect-shift-in-assembly", - "fail_high": true, - "fail_pedantic": false, - "exclude_optimization": true, + "detectors_to_exclude": "arbitrary-send-eth,incorrect-equality,naming-convention,solc-version", + "exclude_dependencies": true, "exclude_informational": true, "exclude_low": true, - "exclude_medium": true, - "solc_disable_warnings": false, - "hardhat_ignore_compile": false, - "disable_color": false, - "exclude_dependencies": true, - "filter_paths": "test,src/vendor,lib,src/cannon/MIPS.sol", + "exclude_optimization": true, + "fail_on": "none", + "filter_paths": "(src/vendor|src/cannon/MIPS.sol|src/EAS/EAS.sol)", "foundry_out_directory": "artifacts" } diff --git a/packages/contracts-bedrock/slither.db.json b/packages/contracts-bedrock/slither.db.json index 49f4b6d35766..f998749201d8 100644 --- a/packages/contracts-bedrock/slither.db.json +++ b/packages/contracts-bedrock/slither.db.json @@ -1,438 +1 @@ -[ - { - "elements": [ - { - "type": "function", - "name": "peel", - "source_mapping": { - "start": 1695, - "length": 824, - "filename_relative": "contracts/periphery/TransferOnion.sol", - "filename_short": "contracts/periphery/TransferOnion.sol", - "is_dependency": false, - "lines": [ - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87 - ], - "starting_column": 5, - "ending_column": 6 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "TransferOnion", - "source_mapping": { - "start": 636, - "length": 1885, - "filename_relative": "contracts/periphery/TransferOnion.sol", - "filename_short": "contracts/periphery/TransferOnion.sol", - "is_dependency": false, - "lines": [ - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88 - ], - "starting_column": 1, - "ending_column": 2 - } - }, - "signature": "peel(TransferOnion.Layer[])" - } - }, - { - "type": "node", - "name": "TOKEN.safeTransferFrom(SENDER,layer.recipient,layer.amount)", - "source_mapping": { - "start": 2300, - "length": 61, - "filename_relative": "contracts/periphery/TransferOnion.sol", - "filename_short": "contracts/periphery/TransferOnion.sol", - "is_dependency": false, - "lines": [ - 78 - ], - "starting_column": 13, - "ending_column": 74 - }, - "type_specific_fields": { - "parent": { - "type": "function", - "name": "peel", - "source_mapping": { - "start": 1695, - "length": 824, - "filename_relative": "contracts/periphery/TransferOnion.sol", - "filename_short": "contracts/periphery/TransferOnion.sol", - "is_dependency": false, - "lines": [ - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87 - ], - "starting_column": 5, - "ending_column": 6 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "TransferOnion", - "source_mapping": { - "start": 636, - "length": 1885, - "filename_relative": "contracts/periphery/TransferOnion.sol", - "filename_short": "contracts/periphery/TransferOnion.sol", - "is_dependency": false, - "lines": [ - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88 - ], - "starting_column": 1, - "ending_column": 2 - } - }, - "signature": "peel(TransferOnion.Layer[])" - } - } - } - } - ], - "description": "TransferOnion.peel(TransferOnion.Layer[]) (contracts/periphery/TransferOnion.sol#62-87) uses arbitrary from in transferFrom: TOKEN.safeTransferFrom(SENDER,layer.recipient,layer.amount) (contracts/periphery/TransferOnion.sol#78)\n", - "markdown": "[TransferOnion.peel(TransferOnion.Layer[])](contracts/periphery/TransferOnion.sol#L62-L87) uses arbitrary from in transferFrom: [TOKEN.safeTransferFrom(SENDER,layer.recipient,layer.amount)](contracts/periphery/TransferOnion.sol#L78)\n", - "first_markdown_element": "contracts/periphery/TransferOnion.sol#L62-L87", - "id": "e4e68870e9d2f8a7caf9d32b8d2b1f57af2bdef51f45724b1b49397f117c3ffe", - "check": "arbitrary-send-erc20", - "impact": "High", - "confidence": "High" - }, - { - "elements": [ - { - "type": "function", - "name": "donate", - "source_mapping": { - "start": 710, - "length": 92, - "filename_relative": "contracts/deployment/PortalSender.sol", - "filename_short": "contracts/deployment/PortalSender.sol", - "is_dependency": false, - "lines": [ - 27, - 28, - 29 - ], - "starting_column": 5, - "ending_column": 6 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "PortalSender", - "source_mapping": { - "start": 328, - "length": 476, - "filename_relative": "contracts/deployment/PortalSender.sol", - "filename_short": "contracts/deployment/PortalSender.sol", - "is_dependency": false, - "lines": [ - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30 - ], - "starting_column": 1, - "ending_column": 2 - } - }, - "signature": "donate()" - } - }, - { - "type": "node", - "name": "PORTAL.donateETH{value: address(this).balance}()", - "source_mapping": { - "start": 745, - "length": 50, - "filename_relative": "contracts/deployment/PortalSender.sol", - "filename_short": "contracts/deployment/PortalSender.sol", - "is_dependency": false, - "lines": [ - 28 - ], - "starting_column": 9, - "ending_column": 59 - }, - "type_specific_fields": { - "parent": { - "type": "function", - "name": "donate", - "source_mapping": { - "start": 710, - "length": 92, - "filename_relative": "contracts/deployment/PortalSender.sol", - "filename_short": "contracts/deployment/PortalSender.sol", - "is_dependency": false, - "lines": [ - 27, - 28, - 29 - ], - "starting_column": 5, - "ending_column": 6 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "PortalSender", - "source_mapping": { - "start": 328, - "length": 476, - "filename_relative": "contracts/deployment/PortalSender.sol", - "filename_short": "contracts/deployment/PortalSender.sol", - "is_dependency": false, - "lines": [ - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30 - ], - "starting_column": 1, - "ending_column": 2 - } - }, - "signature": "donate()" - } - } - } - } - ], - "description": "PortalSender.donate() (contracts/deployment/PortalSender.sol#27-29) sends eth to arbitrary user\n\tDangerous calls:\n\t- PORTAL.donateETH{value: address(this).balance}() (contracts/deployment/PortalSender.sol#28)\n", - "markdown": "[PortalSender.donate()](contracts/deployment/PortalSender.sol#L27-L29) sends eth to arbitrary user\n\tDangerous calls:\n\t- [PORTAL.donateETH{value: address(this).balance}()](contracts/deployment/PortalSender.sol#L28)\n", - "first_markdown_element": "contracts/deployment/PortalSender.sol#L27-L29", - "id": "57ff538ce533c88f5852cca299915d9dd842bfaa1a5c7d1a6d7c44f1a88d0e3c", - "check": "arbitrary-send-eth", - "impact": "High", - "confidence": "Medium" - } -] +[{"elements": [{"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 14716, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353], "starting_column": 13, "ending_column": 52}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480], "starting_column": 1, "ending_column": 11}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}, {"type": "node", "name": "! success && tx.origin == Constants.ESTIMATION_ADDRESS", "source_mapping": {"start": 16916, "length": 53, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [351, 352], "starting_column": 88, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 14716, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353], "starting_column": 13, "ending_column": 52}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480], "starting_column": 1, "ending_column": 11}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}], "description": "OptimismPortal2.finalizeWithdrawalTransaction(Types.WithdrawalTransaction) (src/L1/OptimismPortal2.sol#310-353) uses tx.origin for authorization: ! success && tx.origin == Constants.ESTIMATION_ADDRESS (src/L1/OptimismPortal2.sol#351-352)\n", "markdown": "[OptimismPortal2.finalizeWithdrawalTransaction(Types.WithdrawalTransaction)](src/L1/OptimismPortal2.sol#L310-L353) uses tx.origin for authorization: [! success && tx.origin == Constants.ESTIMATION_ADDRESS](src/L1/OptimismPortal2.sol#L351-L352)\n", "first_markdown_element": "src/L1/OptimismPortal2.sol#L310-L353", "id": "d48d1e372e3b9eedcc9cd7898b5c06c3d9a034fd7b2fe74f33030a43b17ace68", "check": "tx-origin", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 15460, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 23826, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}, {"type": "node", "name": "! success && tx.origin == Constants.ESTIMATION_ADDRESS", "source_mapping": {"start": 17660, "length": 53, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [365], "starting_column": 13, "ending_column": 66}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 15460, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 23826, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}], "description": "OptimismPortal2.finalizeWithdrawalTransaction(Types.WithdrawalTransaction) (src/L1/OptimismPortal2.sol#326-368) uses tx.origin for authorization: ! success && tx.origin == Constants.ESTIMATION_ADDRESS (src/L1/OptimismPortal2.sol#365)\n", "markdown": "[OptimismPortal2.finalizeWithdrawalTransaction(Types.WithdrawalTransaction)](src/L1/OptimismPortal2.sol#L326-L368) uses tx.origin for authorization: [! success && tx.origin == Constants.ESTIMATION_ADDRESS](src/L1/OptimismPortal2.sol#L365)\n", "first_markdown_element": "src/L1/OptimismPortal2.sol#L326-L368", "id": "1ff38a1a3765ac0e84f926b9fc8a4c45324bb734bbf2aab3c9f62e58a99a6859", "check": "tx-origin", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "proveWithdrawalTransaction", "source_mapping": {"start": 10692, "length": 3911, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309], "starting_column": 74, "ending_column": 9}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480], "starting_column": 1, "ending_column": 11}}, "signature": "proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[])"}}, {"type": "node", "name": "(gameType,gameProxy) = disputeGameFactory.gameAtIndex(_disputeGameIndex)", "source_mapping": {"start": 11391, "length": 96, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [250, 251, 252], "starting_column": 34, "ending_column": 47}, "type_specific_fields": {"parent": {"type": "function", "name": "proveWithdrawalTransaction", "source_mapping": {"start": 10692, "length": 3911, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309], "starting_column": 74, "ending_column": 9}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480], "starting_column": 1, "ending_column": 11}}, "signature": "proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[])"}}}}], "description": "OptimismPortal2.proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[]) (src/L1/OptimismPortal2.sol#238-309) ignores return value by (gameType,gameProxy) = disputeGameFactory.gameAtIndex(_disputeGameIndex) (src/L1/OptimismPortal2.sol#250-252)\n", "markdown": "[OptimismPortal2.proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[])](src/L1/OptimismPortal2.sol#L238-L309) ignores return value by [(gameType,gameProxy) = disputeGameFactory.gameAtIndex(_disputeGameIndex)](src/L1/OptimismPortal2.sol#L250-L252)\n", "first_markdown_element": "src/L1/OptimismPortal2.sol#L238-L309", "id": "988135f1cdbc085e5427f69ba7b5c4ad2b9e4332b9f3e009e1df32e8b056deb1", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "proveWithdrawalTransaction", "source_mapping": {"start": 11321, "length": 4026, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 23826, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498], "starting_column": 1, "ending_column": 2}}, "signature": "proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[])"}}, {"type": "node", "name": "(gameType,gameProxy) = disputeGameFactory.gameAtIndex(_disputeGameIndex)", "source_mapping": {"start": 12020, "length": 96, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [264], "starting_column": 9, "ending_column": 105}, "type_specific_fields": {"parent": {"type": "function", "name": "proveWithdrawalTransaction", "source_mapping": {"start": 11321, "length": 4026, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 23826, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498], "starting_column": 1, "ending_column": 2}}, "signature": "proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[])"}}}}], "description": "OptimismPortal2.proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[]) (src/L1/OptimismPortal2.sol#249-322) ignores return value by (gameType,gameProxy) = disputeGameFactory.gameAtIndex(_disputeGameIndex) (src/L1/OptimismPortal2.sol#264)\n", "markdown": "[OptimismPortal2.proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[])](src/L1/OptimismPortal2.sol#L249-L322) ignores return value by [(gameType,gameProxy) = disputeGameFactory.gameAtIndex(_disputeGameIndex)](src/L1/OptimismPortal2.sol#L264)\n", "first_markdown_element": "src/L1/OptimismPortal2.sol#L249-L322", "id": "a456300035f2d7bf357556a28b682d2e5e736e7dd889515683935f960874a7b0", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "l2Sender", "source_mapping": {"start": 2796, "length": 23, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [54], "starting_column": 5, "ending_column": 28}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480], "starting_column": 1, "ending_column": 11}}}}, {"type": "node", "name": "l2Sender = _tx.sender", "source_mapping": {"start": 15617, "length": 21, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [327], "starting_column": 54, "ending_column": 75}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 14716, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353], "starting_column": 13, "ending_column": 52}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480], "starting_column": 1, "ending_column": 11}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}, {"type": "node", "name": "l2Sender = Constants.DEFAULT_L2_SENDER", "source_mapping": {"start": 16411, "length": 38, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [346], "starting_column": 27, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 14716, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353], "starting_column": 13, "ending_column": 52}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480], "starting_column": 1, "ending_column": 11}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}], "description": "OptimismPortal2.l2Sender (src/L1/OptimismPortal2.sol#54) is written in both\n\tl2Sender = _tx.sender (src/L1/OptimismPortal2.sol#327)\n\tl2Sender = Constants.DEFAULT_L2_SENDER (src/L1/OptimismPortal2.sol#346)\n", "markdown": "[OptimismPortal2.l2Sender](src/L1/OptimismPortal2.sol#L54) is written in both\n\t[l2Sender = _tx.sender](src/L1/OptimismPortal2.sol#L327)\n\t[l2Sender = Constants.DEFAULT_L2_SENDER](src/L1/OptimismPortal2.sol#L346)\n", "first_markdown_element": "src/L1/OptimismPortal2.sol#L54", "id": "ec66682a9884e1f71956f493ab54d04460e4827acbde3d42678a3a0a56e2ce43", "check": "write-after-write", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "variable", "name": "l2Sender", "source_mapping": {"start": 2796, "length": 23, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [54], "starting_column": 5, "ending_column": 28}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 23826, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498], "starting_column": 1, "ending_column": 2}}}}, {"type": "node", "name": "l2Sender = _tx.sender", "source_mapping": {"start": 16361, "length": 21, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [344], "starting_column": 9, "ending_column": 30}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 15460, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 23826, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}, {"type": "node", "name": "l2Sender = Constants.DEFAULT_L2_SENDER", "source_mapping": {"start": 17155, "length": 38, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [356], "starting_column": 9, "ending_column": 47}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 15460, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 23826, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}], "description": "OptimismPortal2.l2Sender (src/L1/OptimismPortal2.sol#54) is written in both\n\tl2Sender = _tx.sender (src/L1/OptimismPortal2.sol#344)\n\tl2Sender = Constants.DEFAULT_L2_SENDER (src/L1/OptimismPortal2.sol#356)\n", "markdown": "[OptimismPortal2.l2Sender](src/L1/OptimismPortal2.sol#L54) is written in both\n\t[l2Sender = _tx.sender](src/L1/OptimismPortal2.sol#L344)\n\t[l2Sender = Constants.DEFAULT_L2_SENDER](src/L1/OptimismPortal2.sol#L356)\n", "first_markdown_element": "src/L1/OptimismPortal2.sol#L54", "id": "294dba726d30e30cbad67ac423aff3fb10ccffb8f37fe69888eb06cd2e7faad9", "check": "write-after-write", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "initiator", "source_mapping": {"start": 3840, "length": 119, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [90, 91, 92], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "initiator()"}}, {"type": "function", "name": "readOrHandle", "source_mapping": {"start": 2780, "length": 200, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [61, 62, 63, 64, 65, 66, 67, 68], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "readOrHandle()"}}, {"type": "node", "name": "return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))", "source_mapping": {"start": 7550, "length": 48, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [184], "starting_column": 17, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "_forwardAndHalt", "source_mapping": {"start": 7281, "length": 466, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_forwardAndHalt(bytes32)"}}}}], "description": "DelayedVetoable.initiator() (src/L1/DelayedVetoable.sol#90-92) calls DelayedVetoable.readOrHandle() (src/L1/DelayedVetoable.sol#61-68) which halt the execution return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata)) (src/L1/DelayedVetoable.sol#184)\n", "markdown": "[DelayedVetoable.initiator()](src/L1/DelayedVetoable.sol#L90-L92) calls [DelayedVetoable.readOrHandle()](src/L1/DelayedVetoable.sol#L61-L68) which halt the execution [return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))](src/L1/DelayedVetoable.sol#L184)\n", "first_markdown_element": "src/L1/DelayedVetoable.sol#L90-L92", "id": "2f0ff440c452994f93eeb59d1118c67b60d90509cd44640ed4bcda175849d617", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "vetoer", "source_mapping": {"start": 4050, "length": 107, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [96, 97, 98], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "vetoer()"}}, {"type": "function", "name": "readOrHandle", "source_mapping": {"start": 2780, "length": 200, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [61, 62, 63, 64, 65, 66, 67, 68], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "readOrHandle()"}}, {"type": "node", "name": "return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))", "source_mapping": {"start": 7550, "length": 48, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [184], "starting_column": 17, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "_forwardAndHalt", "source_mapping": {"start": 7281, "length": 466, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_forwardAndHalt(bytes32)"}}}}], "description": "DelayedVetoable.vetoer() (src/L1/DelayedVetoable.sol#96-98) calls DelayedVetoable.readOrHandle() (src/L1/DelayedVetoable.sol#61-68) which halt the execution return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata)) (src/L1/DelayedVetoable.sol#184)\n", "markdown": "[DelayedVetoable.vetoer()](src/L1/DelayedVetoable.sol#L96-L98) calls [DelayedVetoable.readOrHandle()](src/L1/DelayedVetoable.sol#L61-L68) which halt the execution [return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))](src/L1/DelayedVetoable.sol#L184)\n", "first_markdown_element": "src/L1/DelayedVetoable.sol#L96-L98", "id": "c5d34a7c09aed9f0e9eda0a08d720363d155a5c2f8a51262699cd9cda8f6e081", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "target", "source_mapping": {"start": 4248, "length": 99, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [102, 103, 104], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "target()"}}, {"type": "function", "name": "readOrHandle", "source_mapping": {"start": 2780, "length": 200, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [61, 62, 63, 64, 65, 66, 67, 68], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "readOrHandle()"}}, {"type": "node", "name": "return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))", "source_mapping": {"start": 7550, "length": 48, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [184], "starting_column": 17, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "_forwardAndHalt", "source_mapping": {"start": 7281, "length": 466, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_forwardAndHalt(bytes32)"}}}}], "description": "DelayedVetoable.target() (src/L1/DelayedVetoable.sol#102-104) calls DelayedVetoable.readOrHandle() (src/L1/DelayedVetoable.sol#61-68) which halt the execution return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata)) (src/L1/DelayedVetoable.sol#184)\n", "markdown": "[DelayedVetoable.target()](src/L1/DelayedVetoable.sol#L102-L104) calls [DelayedVetoable.readOrHandle()](src/L1/DelayedVetoable.sol#L61-L68) which halt the execution [return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))](src/L1/DelayedVetoable.sol#L184)\n", "first_markdown_element": "src/L1/DelayedVetoable.sol#L102-L104", "id": "40b59d20ec40f1b518e51f0b99ea46375013ec50b66df052612434f826263ed1", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "delay", "source_mapping": {"start": 4422, "length": 96, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [108, 109, 110], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "delay()"}}, {"type": "function", "name": "readOrHandle", "source_mapping": {"start": 2780, "length": 200, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [61, 62, 63, 64, 65, 66, 67, 68], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "readOrHandle()"}}, {"type": "node", "name": "return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))", "source_mapping": {"start": 7550, "length": 48, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [184], "starting_column": 17, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "_forwardAndHalt", "source_mapping": {"start": 7281, "length": 466, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_forwardAndHalt(bytes32)"}}}}], "description": "DelayedVetoable.delay() (src/L1/DelayedVetoable.sol#108-110) calls DelayedVetoable.readOrHandle() (src/L1/DelayedVetoable.sol#61-68) which halt the execution return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata)) (src/L1/DelayedVetoable.sol#184)\n", "markdown": "[DelayedVetoable.delay()](src/L1/DelayedVetoable.sol#L108-L110) calls [DelayedVetoable.readOrHandle()](src/L1/DelayedVetoable.sol#L61-L68) which halt the execution [return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))](src/L1/DelayedVetoable.sol#L184)\n", "first_markdown_element": "src/L1/DelayedVetoable.sol#L108-L110", "id": "f3b27aa640fa9135b6551282605b609c44ebb060ab15e1b568c919a1900278e6", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "queuedAt", "source_mapping": {"start": 4692, "length": 134, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [115, 116, 117], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "queuedAt(bytes32)"}}, {"type": "function", "name": "readOrHandle", "source_mapping": {"start": 2780, "length": 200, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [61, 62, 63, 64, 65, 66, 67, 68], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "readOrHandle()"}}, {"type": "node", "name": "return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))", "source_mapping": {"start": 7550, "length": 48, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [184], "starting_column": 17, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "_forwardAndHalt", "source_mapping": {"start": 7281, "length": 466, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_forwardAndHalt(bytes32)"}}}}], "description": "DelayedVetoable.queuedAt(bytes32) (src/L1/DelayedVetoable.sol#115-117) calls DelayedVetoable.readOrHandle() (src/L1/DelayedVetoable.sol#61-68) which halt the execution return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata)) (src/L1/DelayedVetoable.sol#184)\n", "markdown": "[DelayedVetoable.queuedAt(bytes32)](src/L1/DelayedVetoable.sol#L115-L117) calls [DelayedVetoable.readOrHandle()](src/L1/DelayedVetoable.sol#L61-L68) which halt the execution [return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))](src/L1/DelayedVetoable.sol#L184)\n", "first_markdown_element": "src/L1/DelayedVetoable.sol#L115-L117", "id": "60e2d0b2123f864b56411897c63b8a4d35b8c0fa967e80cddc8f466b40e977f9", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "_handleCall", "source_mapping": {"start": 5192, "length": 2009, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_handleCall()"}}, {"type": "function", "name": "_forwardAndHalt", "source_mapping": {"start": 7281, "length": 466, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_forwardAndHalt(bytes32)"}}, {"type": "node", "name": "return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))", "source_mapping": {"start": 7550, "length": 48, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [184], "starting_column": 17, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "_forwardAndHalt", "source_mapping": {"start": 7281, "length": 466, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_forwardAndHalt(bytes32)"}}}}], "description": "DelayedVetoable._handleCall() (src/L1/DelayedVetoable.sol#127-175) calls DelayedVetoable._forwardAndHalt(bytes32) (src/L1/DelayedVetoable.sol#178-191) which halt the execution return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata)) (src/L1/DelayedVetoable.sol#184)\n", "markdown": "[DelayedVetoable._handleCall()](src/L1/DelayedVetoable.sol#L127-L175) calls [DelayedVetoable._forwardAndHalt(bytes32)](src/L1/DelayedVetoable.sol#L178-L191) which halt the execution [return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))](src/L1/DelayedVetoable.sol#L184)\n", "first_markdown_element": "src/L1/DelayedVetoable.sol#L127-L175", "id": "7de03eb5bb5d87de6cb2002aff77b9a53a4101ff3b1e1d794f3aba799c6452a6", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "readOrHandle", "source_mapping": {"start": 2780, "length": 200, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [61, 62, 63, 64, 65, 66, 67, 68], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "readOrHandle()"}}, {"type": "function", "name": "_handleCall", "source_mapping": {"start": 5192, "length": 2009, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_handleCall()"}}, {"type": "node", "name": "return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))", "source_mapping": {"start": 7550, "length": 48, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [184], "starting_column": 17, "ending_column": 65}, "type_specific_fields": {"parent": {"type": "function", "name": "_forwardAndHalt", "source_mapping": {"start": 7281, "length": 466, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_forwardAndHalt(bytes32)"}}}}], "description": "DelayedVetoable.readOrHandle() (src/L1/DelayedVetoable.sol#61-68) calls DelayedVetoable._handleCall() (src/L1/DelayedVetoable.sol#127-175) which halt the execution return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata)) (src/L1/DelayedVetoable.sol#184)\n", "markdown": "[DelayedVetoable.readOrHandle()](src/L1/DelayedVetoable.sol#L61-L68) calls [DelayedVetoable._handleCall()](src/L1/DelayedVetoable.sol#L127-L175) which halt the execution [return(uint256,uint256)(returndata + 0x20,mload(uint256)(returndata))](src/L1/DelayedVetoable.sol#L184)\n", "first_markdown_element": "src/L1/DelayedVetoable.sol#L61-L68", "id": "12541821582e8769db5cb6534423a56e3cbae828c5a9e26da1db6d6f8c10634a", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "setCode", "source_mapping": {"start": 5022, "length": 1285, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "setCode(bytes)"}}, {"type": "function", "name": "proxyCallIfNotOwner", "source_mapping": {"start": 3867, "length": 237, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [64, 65, 66, 67, 68, 69, 70, 71], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotOwner()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 9403, "length": 29, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [196], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 8349, "length": 1099, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "L1ChugSplashProxy.setCode(bytes) (src/legacy/L1ChugSplashProxy.sol#96-124) calls L1ChugSplashProxy.proxyCallIfNotOwner() (src/legacy/L1ChugSplashProxy.sol#64-71) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/legacy/L1ChugSplashProxy.sol#196)\n", "markdown": "[L1ChugSplashProxy.setCode(bytes)](src/legacy/L1ChugSplashProxy.sol#L96-L124) calls [L1ChugSplashProxy.proxyCallIfNotOwner()](src/legacy/L1ChugSplashProxy.sol#L64-L71) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/legacy/L1ChugSplashProxy.sol#L196)\n", "first_markdown_element": "src/legacy/L1ChugSplashProxy.sol#L96-L124", "id": "4ea64b8e0080de740c9c25e7841217213a680d8680654c8c9f744be145a1431a", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "setStorage", "source_mapping": {"start": 6596, "length": 148, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [130, 131, 132, 133, 134], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "setStorage(bytes32,bytes32)"}}, {"type": "function", "name": "proxyCallIfNotOwner", "source_mapping": {"start": 3867, "length": 237, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [64, 65, 66, 67, 68, 69, 70, 71], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotOwner()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 9403, "length": 29, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [196], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 8349, "length": 1099, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "L1ChugSplashProxy.setStorage(bytes32,bytes32) (src/legacy/L1ChugSplashProxy.sol#130-134) calls L1ChugSplashProxy.proxyCallIfNotOwner() (src/legacy/L1ChugSplashProxy.sol#64-71) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/legacy/L1ChugSplashProxy.sol#196)\n", "markdown": "[L1ChugSplashProxy.setStorage(bytes32,bytes32)](src/legacy/L1ChugSplashProxy.sol#L130-L134) calls [L1ChugSplashProxy.proxyCallIfNotOwner()](src/legacy/L1ChugSplashProxy.sol#L64-L71) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/legacy/L1ChugSplashProxy.sol#L196)\n", "first_markdown_element": "src/legacy/L1ChugSplashProxy.sol#L130-L134", "id": "c116aac23f49ec7d5d6574972abfbf02d56d0521ea2285dc09d239a829e7d2af", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "setOwner", "source_mapping": {"start": 6890, "length": 97, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [138, 139, 140], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "setOwner(address)"}}, {"type": "function", "name": "proxyCallIfNotOwner", "source_mapping": {"start": 3867, "length": 237, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [64, 65, 66, 67, 68, 69, 70, 71], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotOwner()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 9403, "length": 29, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [196], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 8349, "length": 1099, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "L1ChugSplashProxy.setOwner(address) (src/legacy/L1ChugSplashProxy.sol#138-140) calls L1ChugSplashProxy.proxyCallIfNotOwner() (src/legacy/L1ChugSplashProxy.sol#64-71) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/legacy/L1ChugSplashProxy.sol#196)\n", "markdown": "[L1ChugSplashProxy.setOwner(address)](src/legacy/L1ChugSplashProxy.sol#L138-L140) calls [L1ChugSplashProxy.proxyCallIfNotOwner()](src/legacy/L1ChugSplashProxy.sol#L64-L71) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/legacy/L1ChugSplashProxy.sol#L196)\n", "first_markdown_element": "src/legacy/L1ChugSplashProxy.sol#L138-L140", "id": "0b6d0d6699a3fa3c78250e527327e43538895feecaa6cfd8a1793dfcc1d20c72", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "getOwner", "source_mapping": {"start": 7200, "length": 102, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [145, 146, 147], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "getOwner()"}}, {"type": "function", "name": "proxyCallIfNotOwner", "source_mapping": {"start": 3867, "length": 237, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [64, 65, 66, 67, 68, 69, 70, 71], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotOwner()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 9403, "length": 29, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [196], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 8349, "length": 1099, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "L1ChugSplashProxy.getOwner() (src/legacy/L1ChugSplashProxy.sol#145-147) calls L1ChugSplashProxy.proxyCallIfNotOwner() (src/legacy/L1ChugSplashProxy.sol#64-71) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/legacy/L1ChugSplashProxy.sol#196)\n", "markdown": "[L1ChugSplashProxy.getOwner()](src/legacy/L1ChugSplashProxy.sol#L145-L147) calls [L1ChugSplashProxy.proxyCallIfNotOwner()](src/legacy/L1ChugSplashProxy.sol#L64-L71) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/legacy/L1ChugSplashProxy.sol#L196)\n", "first_markdown_element": "src/legacy/L1ChugSplashProxy.sol#L145-L147", "id": "98821b545d4849522091839fbd87144e6fcc256a73b9dd1817676bd127be6d8c", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "getImplementation", "source_mapping": {"start": 7519, "length": 120, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [152, 153, 154], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "getImplementation()"}}, {"type": "function", "name": "proxyCallIfNotOwner", "source_mapping": {"start": 3867, "length": 237, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [64, 65, 66, 67, 68, 69, 70, 71], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotOwner()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 9403, "length": 29, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [196], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 8349, "length": 1099, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "L1ChugSplashProxy.getImplementation() (src/legacy/L1ChugSplashProxy.sol#152-154) calls L1ChugSplashProxy.proxyCallIfNotOwner() (src/legacy/L1ChugSplashProxy.sol#64-71) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/legacy/L1ChugSplashProxy.sol#196)\n", "markdown": "[L1ChugSplashProxy.getImplementation()](src/legacy/L1ChugSplashProxy.sol#L152-L154) calls [L1ChugSplashProxy.proxyCallIfNotOwner()](src/legacy/L1ChugSplashProxy.sol#L64-L71) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/legacy/L1ChugSplashProxy.sol#L196)\n", "first_markdown_element": "src/legacy/L1ChugSplashProxy.sol#L152-L154", "id": "11c5e51d3a0080a2b8f208ae6ec1a4c5617c6df83441ac96c67f322294f73f2b", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "proxyCallIfNotOwner", "source_mapping": {"start": 3867, "length": 237, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [64, 65, 66, 67, 68, 69, 70, 71], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotOwner()"}}, {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 8349, "length": 1099, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 9403, "length": 29, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [196], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 8349, "length": 1099, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1ChugSplashProxy", "source_mapping": {"start": 1025, "length": 9534, "filename_relative": "src/legacy/L1ChugSplashProxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1ChugSplashProxy.sol", "filename_short": "src/legacy/L1ChugSplashProxy.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "L1ChugSplashProxy.proxyCallIfNotOwner() (src/legacy/L1ChugSplashProxy.sol#64-71) calls L1ChugSplashProxy._doProxyCall() (src/legacy/L1ChugSplashProxy.sol#175-198) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/legacy/L1ChugSplashProxy.sol#196)\n", "markdown": "[L1ChugSplashProxy.proxyCallIfNotOwner()](src/legacy/L1ChugSplashProxy.sol#L64-L71) calls [L1ChugSplashProxy._doProxyCall()](src/legacy/L1ChugSplashProxy.sol#L175-L198) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/legacy/L1ChugSplashProxy.sol#L196)\n", "first_markdown_element": "src/legacy/L1ChugSplashProxy.sol#L64-L71", "id": "648de83c485a902ab3df50445e187c6390720ae77705d14edbcc112e4fd8fe1a", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "upgradeTo", "source_mapping": {"start": 2498, "length": 131, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [59, 60, 61], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "upgradeTo(address)"}}, {"type": "function", "name": "proxyCallIfNotAdmin", "source_mapping": {"start": 1295, "length": 237, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotAdmin()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 5922, "length": 29, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [143], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 4928, "length": 1039, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "Proxy.upgradeTo(address) (src/universal/Proxy.sol#59-61) calls Proxy.proxyCallIfNotAdmin() (src/universal/Proxy.sol#26-33) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/universal/Proxy.sol#143)\n", "markdown": "[Proxy.upgradeTo(address)](src/universal/Proxy.sol#L59-L61) calls [Proxy.proxyCallIfNotAdmin()](src/universal/Proxy.sol#L26-L33) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/universal/Proxy.sol#L143)\n", "first_markdown_element": "src/universal/Proxy.sol#L59-L61", "id": "5dbecee956931b503b0ed4fbb7be62ba5f9f64bab10ac87b3c5ba4dab3694bec", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "upgradeToAndCall", "source_mapping": {"start": 2959, "length": 458, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "upgradeToAndCall(address,bytes)"}}, {"type": "function", "name": "proxyCallIfNotAdmin", "source_mapping": {"start": 1295, "length": 237, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotAdmin()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 5922, "length": 29, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [143], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 4928, "length": 1039, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "Proxy.upgradeToAndCall(address,bytes) (src/universal/Proxy.sol#67-81) calls Proxy.proxyCallIfNotAdmin() (src/universal/Proxy.sol#26-33) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/universal/Proxy.sol#143)\n", "markdown": "[Proxy.upgradeToAndCall(address,bytes)](src/universal/Proxy.sol#L67-L81) calls [Proxy.proxyCallIfNotAdmin()](src/universal/Proxy.sol#L26-L33) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/universal/Proxy.sol#L143)\n", "first_markdown_element": "src/universal/Proxy.sol#L67-L81", "id": "2792614492719714cdcff9f7f8e1c602931befa4b0b2d9e0845a2fbf3964f949", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "changeAdmin", "source_mapping": {"start": 3563, "length": 109, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [85, 86, 87], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "changeAdmin(address)"}}, {"type": "function", "name": "proxyCallIfNotAdmin", "source_mapping": {"start": 1295, "length": 237, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotAdmin()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 5922, "length": 29, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [143], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 4928, "length": 1039, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "Proxy.changeAdmin(address) (src/universal/Proxy.sol#85-87) calls Proxy.proxyCallIfNotAdmin() (src/universal/Proxy.sol#26-33) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/universal/Proxy.sol#143)\n", "markdown": "[Proxy.changeAdmin(address)](src/universal/Proxy.sol#L85-L87) calls [Proxy.proxyCallIfNotAdmin()](src/universal/Proxy.sol#L26-L33) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/universal/Proxy.sol#L143)\n", "first_markdown_element": "src/universal/Proxy.sol#L85-L87", "id": "5f00d9ac316494d702da33c92ba3267b0b2a5ab498b5c720e942923a75fd0f50", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "admin", "source_mapping": {"start": 3763, "length": 105, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [91, 92, 93], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "admin()"}}, {"type": "function", "name": "proxyCallIfNotAdmin", "source_mapping": {"start": 1295, "length": 237, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotAdmin()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 5922, "length": 29, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [143], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 4928, "length": 1039, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "Proxy.admin() (src/universal/Proxy.sol#91-93) calls Proxy.proxyCallIfNotAdmin() (src/universal/Proxy.sol#26-33) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/universal/Proxy.sol#143)\n", "markdown": "[Proxy.admin()](src/universal/Proxy.sol#L91-L93) calls [Proxy.proxyCallIfNotAdmin()](src/universal/Proxy.sol#L26-L33) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/universal/Proxy.sol#L143)\n", "first_markdown_element": "src/universal/Proxy.sol#L91-L93", "id": "61c6823d9d96abad705c3e29c3768a5d2ade61e6f226c9241e6f3278063ab469", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "implementation", "source_mapping": {"start": 3967, "length": 123, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [97, 98, 99], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "implementation()"}}, {"type": "function", "name": "proxyCallIfNotAdmin", "source_mapping": {"start": 1295, "length": 237, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotAdmin()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 5922, "length": 29, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [143], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 4928, "length": 1039, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "Proxy.implementation() (src/universal/Proxy.sol#97-99) calls Proxy.proxyCallIfNotAdmin() (src/universal/Proxy.sol#26-33) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/universal/Proxy.sol#143)\n", "markdown": "[Proxy.implementation()](src/universal/Proxy.sol#L97-L99) calls [Proxy.proxyCallIfNotAdmin()](src/universal/Proxy.sol#L26-L33) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/universal/Proxy.sol#L143)\n", "first_markdown_element": "src/universal/Proxy.sol#L97-L99", "id": "1e96b3f3be5c5b827284291533d15f8b70c3f8bc774e863359baa95195e8a79c", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "proxyCallIfNotAdmin", "source_mapping": {"start": 1295, "length": 237, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [26, 27, 28, 29, 30, 31, 32, 33], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "proxyCallIfNotAdmin()"}}, {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 4928, "length": 1039, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}, {"type": "node", "name": "return(uint256,uint256)(0x0,returndatasize()())", "source_mapping": {"start": 5922, "length": 29, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [143], "starting_column": 13, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_doProxyCall", "source_mapping": {"start": 4928, "length": 1039, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Proxy", "source_mapping": {"start": 348, "length": 6312, "filename_relative": "src/universal/Proxy.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/Proxy.sol", "filename_short": "src/universal/Proxy.sol", "is_dependency": false, "lines": [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168], "starting_column": 1, "ending_column": 2}}, "signature": "_doProxyCall()"}}}}], "description": "Proxy.proxyCallIfNotAdmin() (src/universal/Proxy.sol#26-33) calls Proxy._doProxyCall() (src/universal/Proxy.sol#123-145) which halt the execution return(uint256,uint256)(0x0,returndatasize()()) (src/universal/Proxy.sol#143)\n", "markdown": "[Proxy.proxyCallIfNotAdmin()](src/universal/Proxy.sol#L26-L33) calls [Proxy._doProxyCall()](src/universal/Proxy.sol#L123-L145) which halt the execution [return(uint256,uint256)(0x0,returndatasize()())](src/universal/Proxy.sol#L143)\n", "first_markdown_element": "src/universal/Proxy.sol#L26-L33", "id": "d14996b9cc4486d4926155fb1f3d0c1ffc8be9b4af43a61074039356721c7e45", "check": "incorrect-return", "impact": "High", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "blobBaseFee", "source_mapping": {"start": 1899, "length": 26, "filename_relative": "src/L2/L1Block.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L2/L1Block.sol", "filename_short": "src/L2/L1Block.sol", "is_dependency": false, "lines": [50], "starting_column": 5, "ending_column": 31}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1Block", "source_mapping": {"start": 588, "length": 4256, "filename_relative": "src/L2/L1Block.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L2/L1Block.sol", "filename_short": "src/L2/L1Block.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119], "starting_column": 1, "ending_column": 2}}}}, {"type": "function", "name": "setL1BlockValuesEcotone", "source_mapping": {"start": 3886, "length": 956, "filename_relative": "src/L2/L1Block.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L2/L1Block.sol", "filename_short": "src/L2/L1Block.sol", "is_dependency": false, "lines": [101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1Block", "source_mapping": {"start": 588, "length": 4256, "filename_relative": "src/L2/L1Block.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L2/L1Block.sol", "filename_short": "src/L2/L1Block.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119], "starting_column": 1, "ending_column": 2}}, "signature": "setL1BlockValuesEcotone()"}}], "description": "L1Block.blobBaseFee (src/L2/L1Block.sol#50) is never initialized. It is used in:\n\t- L1Block.setL1BlockValuesEcotone() (src/L2/L1Block.sol#101-118)\n", "markdown": "[L1Block.blobBaseFee](src/L2/L1Block.sol#L50) is never initialized. It is used in:\n\t- [L1Block.setL1BlockValuesEcotone()](src/L2/L1Block.sol#L101-L118)\n", "first_markdown_element": "src/L2/L1Block.sol#L50", "id": "fa673f7f315b9ee7fea38da72b4b0b0eb94babc8d0938536b00ce803ecc07fa2", "check": "uninitialized-state", "impact": "High", "confidence": "High"}, {"elements": [{"type": "function", "name": "_metered", "source_mapping": {"start": 3817, "length": 4037, "filename_relative": "src/L1/ResourceMetering.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol", "filename_short": "src/L1/ResourceMetering.sol", "is_dependency": false, "lines": [74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "ResourceMetering", "source_mapping": {"start": 527, "length": 8071, "filename_relative": "src/L1/ResourceMetering.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol", "filename_short": "src/L1/ResourceMetering.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162], "starting_column": 1, "ending_column": 2}}, "signature": "_metered(uint64,uint256)"}}, {"type": "node", "name": "targetResourceLimit = int256(uint256(config.maxResourceLimit)) / int256(uint256(config.elasticityMultiplier))", "source_mapping": {"start": 4072, "length": 128, "filename_relative": "src/L1/ResourceMetering.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol", "filename_short": "src/L1/ResourceMetering.sol", "is_dependency": false, "lines": [79, 80], "starting_column": 9, "ending_column": 100}, "type_specific_fields": {"parent": {"type": "function", "name": "_metered", "source_mapping": {"start": 3817, "length": 4037, "filename_relative": "src/L1/ResourceMetering.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol", "filename_short": "src/L1/ResourceMetering.sol", "is_dependency": false, "lines": [74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "ResourceMetering", "source_mapping": {"start": 527, "length": 8071, "filename_relative": "src/L1/ResourceMetering.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol", "filename_short": "src/L1/ResourceMetering.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162], "starting_column": 1, "ending_column": 2}}, "signature": "_metered(uint64,uint256)"}}}}, {"type": "node", "name": "baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) / (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)))", "source_mapping": {"start": 4630, "length": 168, "filename_relative": "src/L1/ResourceMetering.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol", "filename_short": "src/L1/ResourceMetering.sol", "is_dependency": false, "lines": [87, 88], "starting_column": 13, "ending_column": 94}, "type_specific_fields": {"parent": {"type": "function", "name": "_metered", "source_mapping": {"start": 3817, "length": 4037, "filename_relative": "src/L1/ResourceMetering.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol", "filename_short": "src/L1/ResourceMetering.sol", "is_dependency": false, "lines": [74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "ResourceMetering", "source_mapping": {"start": 527, "length": 8071, "filename_relative": "src/L1/ResourceMetering.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol", "filename_short": "src/L1/ResourceMetering.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162], "starting_column": 1, "ending_column": 2}}, "signature": "_metered(uint64,uint256)"}}}}], "description": "ResourceMetering._metered(uint64,uint256) (src/L1/ResourceMetering.sol#74-146) performs a multiplication on the result of a division:\n\t- targetResourceLimit = int256(uint256(config.maxResourceLimit)) / int256(uint256(config.elasticityMultiplier)) (src/L1/ResourceMetering.sol#79-80)\n\t- baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) / (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator))) (src/L1/ResourceMetering.sol#87-88)\n", "markdown": "[ResourceMetering._metered(uint64,uint256)](src/L1/ResourceMetering.sol#L74-L146) performs a multiplication on the result of a division:\n\t- [targetResourceLimit = int256(uint256(config.maxResourceLimit)) / int256(uint256(config.elasticityMultiplier))](src/L1/ResourceMetering.sol#L79-L80)\n\t- [baseFeeDelta = (int256(uint256(params.prevBaseFee)) * gasUsedDelta) / (targetResourceLimit * int256(uint256(config.baseFeeMaxChangeDenominator)))](src/L1/ResourceMetering.sol#L87-L88)\n", "first_markdown_element": "src/L1/ResourceMetering.sol#L74-L146", "id": "595a94c37aa9f252f126879331b7f976f816b1f68c91143e14e849044bc177c0", "check": "divide-before-multiply", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "contract", "name": "L1BlockNumber", "source_mapping": {"start": 668, "length": 888, "filename_relative": "src/legacy/L1BlockNumber.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol", "filename_short": "src/legacy/L1BlockNumber.sol", "is_dependency": false, "lines": [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "starting_column": 1, "ending_column": 2}}, {"type": "function", "name": "receive", "source_mapping": {"start": 863, "length": 178, "filename_relative": "src/legacy/L1BlockNumber.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol", "filename_short": "src/legacy/L1BlockNumber.sol", "is_dependency": false, "lines": [22, 23, 24, 25, 26, 27, 28], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1BlockNumber", "source_mapping": {"start": 668, "length": 888, "filename_relative": "src/legacy/L1BlockNumber.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol", "filename_short": "src/legacy/L1BlockNumber.sol", "is_dependency": false, "lines": [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "starting_column": 1, "ending_column": 2}}, "signature": "receive()"}}, {"type": "function", "name": "fallback", "source_mapping": {"start": 1145, "length": 179, "filename_relative": "src/legacy/L1BlockNumber.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol", "filename_short": "src/legacy/L1BlockNumber.sol", "is_dependency": false, "lines": [32, 33, 34, 35, 36, 37, 38], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "L1BlockNumber", "source_mapping": {"start": 668, "length": 888, "filename_relative": "src/legacy/L1BlockNumber.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol", "filename_short": "src/legacy/L1BlockNumber.sol", "is_dependency": false, "lines": [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "starting_column": 1, "ending_column": 2}}, "signature": "fallback()"}}], "description": "Contract locking ether found:\n\tContract L1BlockNumber (src/legacy/L1BlockNumber.sol#16-45) has payable functions:\n\t - L1BlockNumber.receive() (src/legacy/L1BlockNumber.sol#22-28)\n\t - L1BlockNumber.fallback() (src/legacy/L1BlockNumber.sol#32-38)\n\tBut does not have a function to withdraw the ether\n", "markdown": "Contract locking ether found:\n\tContract [L1BlockNumber](src/legacy/L1BlockNumber.sol#L16-L45) has payable functions:\n\t - [L1BlockNumber.receive()](src/legacy/L1BlockNumber.sol#L22-L28)\n\t - [L1BlockNumber.fallback()](src/legacy/L1BlockNumber.sol#L32-L38)\n\tBut does not have a function to withdraw the ether\n", "first_markdown_element": "src/legacy/L1BlockNumber.sol#L16-L45", "id": "c0920fe4b6b04a2b81f69b85402d465719d06978441052f49a6582415934a1bf", "check": "locked-ether", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "contract", "name": "SchemaResolver", "source_mapping": {"start": 350, "length": 5868, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165], "starting_column": 1, "ending_column": 2}}, {"type": "function", "name": "attest", "source_mapping": {"start": 565, "length": 82, "filename_relative": "src/EAS/resolver/ISchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/ISchemaResolver.sol", "filename_short": "src/EAS/resolver/ISchemaResolver.sol", "is_dependency": false, "lines": [16], "starting_column": 5, "ending_column": 87}, "type_specific_fields": {"parent": {"type": "contract", "name": "ISchemaResolver", "source_mapping": {"start": 188, "length": 1672, "filename_relative": "src/EAS/resolver/ISchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/ISchemaResolver.sol", "filename_short": "src/EAS/resolver/ISchemaResolver.sol", "is_dependency": false, "lines": [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46], "starting_column": 1, "ending_column": 2}}, "signature": "attest(Attestation)"}}, {"type": "function", "name": "multiAttest", "source_mapping": {"start": 926, "length": 163, "filename_relative": "src/EAS/resolver/ISchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/ISchemaResolver.sol", "filename_short": "src/EAS/resolver/ISchemaResolver.sol", "is_dependency": false, "lines": [22, 23, 24, 25, 26, 27, 28], "starting_column": 5, "ending_column": 24}, "type_specific_fields": {"parent": {"type": "contract", "name": "ISchemaResolver", "source_mapping": {"start": 188, "length": 1672, "filename_relative": "src/EAS/resolver/ISchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/ISchemaResolver.sol", "filename_short": "src/EAS/resolver/ISchemaResolver.sol", "is_dependency": false, "lines": [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46], "starting_column": 1, "ending_column": 2}}, "signature": "multiAttest(Attestation[],uint256[])"}}, {"type": "function", "name": "revoke", "source_mapping": {"start": 1305, "length": 82, "filename_relative": "src/EAS/resolver/ISchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/ISchemaResolver.sol", "filename_short": "src/EAS/resolver/ISchemaResolver.sol", "is_dependency": false, "lines": [33], "starting_column": 5, "ending_column": 87}, "type_specific_fields": {"parent": {"type": "contract", "name": "ISchemaResolver", "source_mapping": {"start": 188, "length": 1672, "filename_relative": "src/EAS/resolver/ISchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/ISchemaResolver.sol", "filename_short": "src/EAS/resolver/ISchemaResolver.sol", "is_dependency": false, "lines": [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46], "starting_column": 1, "ending_column": 2}}, "signature": "revoke(Attestation)"}}, {"type": "function", "name": "multiRevoke", "source_mapping": {"start": 1695, "length": 163, "filename_relative": "src/EAS/resolver/ISchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/ISchemaResolver.sol", "filename_short": "src/EAS/resolver/ISchemaResolver.sol", "is_dependency": false, "lines": [39, 40, 41, 42, 43, 44, 45], "starting_column": 5, "ending_column": 24}, "type_specific_fields": {"parent": {"type": "contract", "name": "ISchemaResolver", "source_mapping": {"start": 188, "length": 1672, "filename_relative": "src/EAS/resolver/ISchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/ISchemaResolver.sol", "filename_short": "src/EAS/resolver/ISchemaResolver.sol", "is_dependency": false, "lines": [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46], "starting_column": 1, "ending_column": 2}}, "signature": "multiRevoke(Attestation[],uint256[])"}}, {"type": "function", "name": "receive", "source_mapping": {"start": 1054, "length": 113, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [41, 42, 43, 44, 45], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "SchemaResolver", "source_mapping": {"start": 350, "length": 5868, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165], "starting_column": 1, "ending_column": 2}}, "signature": "receive()"}}, {"type": "function", "name": "attest", "source_mapping": {"start": 1209, "length": 146, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [48, 49, 50], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "SchemaResolver", "source_mapping": {"start": 350, "length": 5868, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165], "starting_column": 1, "ending_column": 2}}, "signature": "attest(Attestation)"}}, {"type": "function", "name": "multiAttest", "source_mapping": {"start": 1397, "length": 1497, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "SchemaResolver", "source_mapping": {"start": 350, "length": 5868, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165], "starting_column": 1, "ending_column": 2}}, "signature": "multiAttest(Attestation[],uint256[])"}}, {"type": "function", "name": "revoke", "source_mapping": {"start": 2936, "length": 146, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [95, 96, 97], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "SchemaResolver", "source_mapping": {"start": 350, "length": 5868, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165], "starting_column": 1, "ending_column": 2}}, "signature": "revoke(Attestation)"}}, {"type": "function", "name": "multiRevoke", "source_mapping": {"start": 3124, "length": 1496, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "SchemaResolver", "source_mapping": {"start": 350, "length": 5868, "filename_relative": "src/EAS/resolver/SchemaResolver.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol", "filename_short": "src/EAS/resolver/SchemaResolver.sol", "is_dependency": false, "lines": [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165], "starting_column": 1, "ending_column": 2}}, "signature": "multiRevoke(Attestation[],uint256[])"}}], "description": "Contract locking ether found:\n\tContract SchemaResolver (src/EAS/resolver/SchemaResolver.sol#11-165) has payable functions:\n\t - ISchemaResolver.attest(Attestation) (src/EAS/resolver/ISchemaResolver.sol#16)\n\t - ISchemaResolver.multiAttest(Attestation[],uint256[]) (src/EAS/resolver/ISchemaResolver.sol#22-28)\n\t - ISchemaResolver.revoke(Attestation) (src/EAS/resolver/ISchemaResolver.sol#33)\n\t - ISchemaResolver.multiRevoke(Attestation[],uint256[]) (src/EAS/resolver/ISchemaResolver.sol#39-45)\n\t - SchemaResolver.receive() (src/EAS/resolver/SchemaResolver.sol#41-45)\n\t - SchemaResolver.attest(Attestation) (src/EAS/resolver/SchemaResolver.sol#48-50)\n\t - SchemaResolver.multiAttest(Attestation[],uint256[]) (src/EAS/resolver/SchemaResolver.sol#53-92)\n\t - SchemaResolver.revoke(Attestation) (src/EAS/resolver/SchemaResolver.sol#95-97)\n\t - SchemaResolver.multiRevoke(Attestation[],uint256[]) (src/EAS/resolver/SchemaResolver.sol#100-139)\n\tBut does not have a function to withdraw the ether\n", "markdown": "Contract locking ether found:\n\tContract [SchemaResolver](src/EAS/resolver/SchemaResolver.sol#L11-L165) has payable functions:\n\t - [ISchemaResolver.attest(Attestation)](src/EAS/resolver/ISchemaResolver.sol#L16)\n\t - [ISchemaResolver.multiAttest(Attestation[],uint256[])](src/EAS/resolver/ISchemaResolver.sol#L22-L28)\n\t - [ISchemaResolver.revoke(Attestation)](src/EAS/resolver/ISchemaResolver.sol#L33)\n\t - [ISchemaResolver.multiRevoke(Attestation[],uint256[])](src/EAS/resolver/ISchemaResolver.sol#L39-L45)\n\t - [SchemaResolver.receive()](src/EAS/resolver/SchemaResolver.sol#L41-L45)\n\t - [SchemaResolver.attest(Attestation)](src/EAS/resolver/SchemaResolver.sol#L48-L50)\n\t - [SchemaResolver.multiAttest(Attestation[],uint256[])](src/EAS/resolver/SchemaResolver.sol#L53-L92)\n\t - [SchemaResolver.revoke(Attestation)](src/EAS/resolver/SchemaResolver.sol#L95-L97)\n\t - [SchemaResolver.multiRevoke(Attestation[],uint256[])](src/EAS/resolver/SchemaResolver.sol#L100-L139)\n\tBut does not have a function to withdraw the ether\n", "first_markdown_element": "src/EAS/resolver/SchemaResolver.sol#L11-L165", "id": "3e52f3459d6607e6494e893c33e98bfaee52639c20f8e8366a39b97d30efeb9d", "check": "locked-ether", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "function", "name": "_handleCall", "source_mapping": {"start": 5192, "length": 2009, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_handleCall()"}}, {"type": "node", "name": "_forwardAndHalt(callHash)", "source_mapping": {"start": 5929, "length": 25, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [144], "starting_column": 17, "ending_column": 42}, "type_specific_fields": {"parent": {"type": "function", "name": "_handleCall", "source_mapping": {"start": 5192, "length": 2009, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_handleCall()"}}}, "additional_fields": {"underlying_type": "external_calls"}}, {"type": "node", "name": "(success,returndata) = TARGET.call(msg.data)", "source_mapping": {"start": 7415, "length": 63, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [181], "starting_column": 9, "ending_column": 72}, "type_specific_fields": {"parent": {"type": "function", "name": "_forwardAndHalt", "source_mapping": {"start": 7281, "length": 466, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_forwardAndHalt(bytes32)"}}}, "additional_fields": {"underlying_type": "external_calls_sending_eth"}}, {"type": "node", "name": "_queuedAt[callHash] = block.timestamp", "source_mapping": {"start": 5982, "length": 37, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [146], "starting_column": 13, "ending_column": 50}, "type_specific_fields": {"parent": {"type": "function", "name": "_handleCall", "source_mapping": {"start": 5192, "length": 2009, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DelayedVetoable", "source_mapping": {"start": 695, "length": 7054, "filename_relative": "src/L1/DelayedVetoable.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/DelayedVetoable.sol", "filename_short": "src/L1/DelayedVetoable.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192], "starting_column": 1, "ending_column": 2}}, "signature": "_handleCall()"}}}, "additional_fields": {"underlying_type": "variables_written", "variable_name": "_queuedAt"}}], "description": "Reentrancy in DelayedVetoable._handleCall() (src/L1/DelayedVetoable.sol#127-175):\n\tExternal calls:\n\t- _forwardAndHalt(callHash) (src/L1/DelayedVetoable.sol#144)\n\t\t- (success,returndata) = TARGET.call(msg.data) (src/L1/DelayedVetoable.sol#181)\n\tState variables written after the call(s):\n\t- _queuedAt[callHash] = block.timestamp (src/L1/DelayedVetoable.sol#146)\n\tDelayedVetoable._queuedAt (src/L1/DelayedVetoable.sol#55) can be used in cross function reentrancies:\n\t- DelayedVetoable._handleCall() (src/L1/DelayedVetoable.sol#127-175)\n\t- DelayedVetoable.queuedAt(bytes32) (src/L1/DelayedVetoable.sol#115-117)\n", "markdown": "Reentrancy in [DelayedVetoable._handleCall()](src/L1/DelayedVetoable.sol#L127-L175):\n\tExternal calls:\n\t- [_forwardAndHalt(callHash)](src/L1/DelayedVetoable.sol#L144)\n\t\t- [(success,returndata) = TARGET.call(msg.data)](src/L1/DelayedVetoable.sol#L181)\n\tState variables written after the call(s):\n\t- [_queuedAt[callHash] = block.timestamp](src/L1/DelayedVetoable.sol#L146)\n\t[DelayedVetoable._queuedAt](src/L1/DelayedVetoable.sol#L55) can be used in cross function reentrancies:\n\t- [DelayedVetoable._handleCall()](src/L1/DelayedVetoable.sol#L127-L175)\n\t- [DelayedVetoable.queuedAt(bytes32)](src/L1/DelayedVetoable.sol#L115-L117)\n", "first_markdown_element": "src/L1/DelayedVetoable.sol#L127-L175", "id": "791771351f6ef5490cbea5fbd5fe374336617a83ad32ebe163690cdee25b4208", "check": "reentrancy-no-eth", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "peel", "source_mapping": {"start": 1616, "length": 885, "filename_relative": "src/periphery/TransferOnion.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/periphery/TransferOnion.sol", "filename_short": "src/periphery/TransferOnion.sol", "is_dependency": false, "lines": [44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "TransferOnion", "source_mapping": {"start": 633, "length": 1870, "filename_relative": "src/periphery/TransferOnion.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/periphery/TransferOnion.sol", "filename_short": "src/periphery/TransferOnion.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71], "starting_column": 1, "ending_column": 2}}, "signature": "peel(TransferOnion.Layer[])"}}, {"type": "node", "name": "TOKEN.safeTransferFrom(SENDER,layer.recipient,layer.amount)", "source_mapping": {"start": 2282, "length": 61, "filename_relative": "src/periphery/TransferOnion.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/periphery/TransferOnion.sol", "filename_short": "src/periphery/TransferOnion.sol", "is_dependency": false, "lines": [61], "starting_column": 13, "ending_column": 74}, "type_specific_fields": {"parent": {"type": "function", "name": "peel", "source_mapping": {"start": 1616, "length": 885, "filename_relative": "src/periphery/TransferOnion.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/periphery/TransferOnion.sol", "filename_short": "src/periphery/TransferOnion.sol", "is_dependency": false, "lines": [44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "TransferOnion", "source_mapping": {"start": 633, "length": 1870, "filename_relative": "src/periphery/TransferOnion.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/periphery/TransferOnion.sol", "filename_short": "src/periphery/TransferOnion.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71], "starting_column": 1, "ending_column": 2}}, "signature": "peel(TransferOnion.Layer[])"}}}, "additional_fields": {"underlying_type": "external_calls"}}, {"type": "node", "name": "shell = tempShell", "source_mapping": {"start": 2477, "length": 17, "filename_relative": "src/periphery/TransferOnion.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/periphery/TransferOnion.sol", "filename_short": "src/periphery/TransferOnion.sol", "is_dependency": false, "lines": [69], "starting_column": 9, "ending_column": 26}, "type_specific_fields": {"parent": {"type": "function", "name": "peel", "source_mapping": {"start": 1616, "length": 885, "filename_relative": "src/periphery/TransferOnion.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/periphery/TransferOnion.sol", "filename_short": "src/periphery/TransferOnion.sol", "is_dependency": false, "lines": [44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "TransferOnion", "source_mapping": {"start": 633, "length": 1870, "filename_relative": "src/periphery/TransferOnion.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/periphery/TransferOnion.sol", "filename_short": "src/periphery/TransferOnion.sol", "is_dependency": false, "lines": [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71], "starting_column": 1, "ending_column": 2}}, "signature": "peel(TransferOnion.Layer[])"}}}, "additional_fields": {"underlying_type": "variables_written", "variable_name": "shell"}}], "description": "Reentrancy in TransferOnion.peel(TransferOnion.Layer[]) (src/periphery/TransferOnion.sol#44-70):\n\tExternal calls:\n\t- TOKEN.safeTransferFrom(SENDER,layer.recipient,layer.amount) (src/periphery/TransferOnion.sol#61)\n\tState variables written after the call(s):\n\t- shell = tempShell (src/periphery/TransferOnion.sol#69)\n\tTransferOnion.shell (src/periphery/TransferOnion.sol#30) can be used in cross function reentrancies:\n\t- TransferOnion.constructor(ERC20,address,bytes32) (src/periphery/TransferOnion.sol#36-40)\n\t- TransferOnion.shell (src/periphery/TransferOnion.sol#30)\n", "markdown": "Reentrancy in [TransferOnion.peel(TransferOnion.Layer[])](src/periphery/TransferOnion.sol#L44-L70):\n\tExternal calls:\n\t- [TOKEN.safeTransferFrom(SENDER,layer.recipient,layer.amount)](src/periphery/TransferOnion.sol#L61)\n\tState variables written after the call(s):\n\t- [shell = tempShell](src/periphery/TransferOnion.sol#L69)\n\t[TransferOnion.shell](src/periphery/TransferOnion.sol#L30) can be used in cross function reentrancies:\n\t- [TransferOnion.constructor(ERC20,address,bytes32)](src/periphery/TransferOnion.sol#L36-L40)\n\t- [TransferOnion.shell](src/periphery/TransferOnion.sol#L30)\n", "first_markdown_element": "src/periphery/TransferOnion.sol#L44-L70", "id": "1349b68c3b08ecdf27782bd74d9fecadf1739eef738171cbbba403c77a29f424", "check": "reentrancy-no-eth", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "step", "source_mapping": {"start": 4978, "length": 4228, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "step(uint256,bool,bytes,bytes)"}}, {"type": "node", "name": "validStep = VM.step(_stateData,_proof,uuid.raw()) == postState.claim.raw()", "source_mapping": {"start": 8758, "length": 81, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [184], "starting_column": 9, "ending_column": 90}, "type_specific_fields": {"parent": {"type": "function", "name": "step", "source_mapping": {"start": 4978, "length": 4228, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "step(uint256,bool,bytes,bytes)"}}}, "additional_fields": {"underlying_type": "external_calls"}}, {"type": "node", "name": "parent.counteredBy = msg.sender", "source_mapping": {"start": 9168, "length": 31, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [190], "starting_column": 9, "ending_column": 40}, "type_specific_fields": {"parent": {"type": "function", "name": "step", "source_mapping": {"start": 4978, "length": 4228, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "step(uint256,bool,bytes,bytes)"}}}, "additional_fields": {"underlying_type": "variables_written", "variable_name": "claimData"}}], "description": "Reentrancy in FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#124-191):\n\tExternal calls:\n\t- validStep = VM.step(_stateData,_proof,uuid.raw()) == postState.claim.raw() (src/dispute/FaultDisputeGame.sol#184)\n\tState variables written after the call(s):\n\t- parent.counteredBy = msg.sender (src/dispute/FaultDisputeGame.sol#190)\n\tFaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#66) can be used in cross function reentrancies:\n\t- FaultDisputeGame._findStartingAndDisputedOutputs(uint256) (src/dispute/FaultDisputeGame.sol#672-731)\n\t- FaultDisputeGame._findTraceAncestor(Position,uint256,bool) (src/dispute/FaultDisputeGame.sol#645-663)\n\t- FaultDisputeGame.claimData (src/dispute/FaultDisputeGame.sol#66)\n\t- FaultDisputeGame.claimDataLen() (src/dispute/FaultDisputeGame.sol#520-522)\n\t- FaultDisputeGame.initialize() (src/dispute/FaultDisputeGame.sol#464-517)\n\t- FaultDisputeGame.move(uint256,Claim,bool) (src/dispute/FaultDisputeGame.sol#197-286)\n\t- FaultDisputeGame.resolve() (src/dispute/FaultDisputeGame.sol#351-363)\n\t- FaultDisputeGame.resolveClaim(uint256) (src/dispute/FaultDisputeGame.sol#366-438)\n\t- FaultDisputeGame.step(uint256,bool,bytes,bytes) (src/dispute/FaultDisputeGame.sol#124-191)\n", "markdown": "Reentrancy in [FaultDisputeGame.step(uint256,bool,bytes,bytes)](src/dispute/FaultDisputeGame.sol#L124-L191):\n\tExternal calls:\n\t- [validStep = VM.step(_stateData,_proof,uuid.raw()) == postState.claim.raw()](src/dispute/FaultDisputeGame.sol#L184)\n\tState variables written after the call(s):\n\t- [parent.counteredBy = msg.sender](src/dispute/FaultDisputeGame.sol#L190)\n\t[FaultDisputeGame.claimData](src/dispute/FaultDisputeGame.sol#L66) can be used in cross function reentrancies:\n\t- [FaultDisputeGame._findStartingAndDisputedOutputs(uint256)](src/dispute/FaultDisputeGame.sol#L672-L731)\n\t- [FaultDisputeGame._findTraceAncestor(Position,uint256,bool)](src/dispute/FaultDisputeGame.sol#L645-L663)\n\t- [FaultDisputeGame.claimData](src/dispute/FaultDisputeGame.sol#L66)\n\t- [FaultDisputeGame.claimDataLen()](src/dispute/FaultDisputeGame.sol#L520-L522)\n\t- [FaultDisputeGame.initialize()](src/dispute/FaultDisputeGame.sol#L464-L517)\n\t- [FaultDisputeGame.move(uint256,Claim,bool)](src/dispute/FaultDisputeGame.sol#L197-L286)\n\t- [FaultDisputeGame.resolve()](src/dispute/FaultDisputeGame.sol#L351-L363)\n\t- [FaultDisputeGame.resolveClaim(uint256)](src/dispute/FaultDisputeGame.sol#L366-L438)\n\t- [FaultDisputeGame.step(uint256,bool,bytes,bytes)](src/dispute/FaultDisputeGame.sol#L124-L191)\n", "first_markdown_element": "src/dispute/FaultDisputeGame.sol#L124-L191", "id": "a31cc22ac44058d56b0a89d6a2ab1dbe6791d75f6d06397eebf72a6d932e82c2", "check": "reentrancy-no-eth", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "relayMessage", "source_mapping": {"start": 10315, "length": 5066, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "CrossDomainMessenger", "source_mapping": {"start": 3683, "length": 17490, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406], "starting_column": 1, "ending_column": 2}}, "signature": "relayMessage(uint256,address,address,uint256,uint256,bytes)"}}, {"type": "node", "name": "tx.origin == Constants.ESTIMATION_ADDRESS", "source_mapping": {"start": 13912, "length": 41, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [275], "starting_column": 17, "ending_column": 58}, "type_specific_fields": {"parent": {"type": "function", "name": "relayMessage", "source_mapping": {"start": 10315, "length": 5066, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "CrossDomainMessenger", "source_mapping": {"start": 3683, "length": 17490, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406], "starting_column": 1, "ending_column": 2}}, "signature": "relayMessage(uint256,address,address,uint256,uint256,bytes)"}}}}], "description": "CrossDomainMessenger.relayMessage(uint256,address,address,uint256,uint256,bytes) (src/universal/CrossDomainMessenger.sol#207-305) uses tx.origin for authorization: tx.origin == Constants.ESTIMATION_ADDRESS (src/universal/CrossDomainMessenger.sol#275)\n", "markdown": "[CrossDomainMessenger.relayMessage(uint256,address,address,uint256,uint256,bytes)](src/universal/CrossDomainMessenger.sol#L207-L305) uses tx.origin for authorization: [tx.origin == Constants.ESTIMATION_ADDRESS](src/universal/CrossDomainMessenger.sol#L275)\n", "first_markdown_element": "src/universal/CrossDomainMessenger.sol#L207-L305", "id": "baf2bfa9777021d9e36870b76a1020c950de67bbf00d486f604cc72d36c47839", "check": "tx-origin", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "relayMessage", "source_mapping": {"start": 10315, "length": 5066, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "CrossDomainMessenger", "source_mapping": {"start": 3683, "length": 17490, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406], "starting_column": 1, "ending_column": 2}}, "signature": "relayMessage(uint256,address,address,uint256,uint256,bytes)"}}, {"type": "node", "name": "tx.origin == Constants.ESTIMATION_ADDRESS", "source_mapping": {"start": 15234, "length": 41, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [301], "starting_column": 17, "ending_column": 58}, "type_specific_fields": {"parent": {"type": "function", "name": "relayMessage", "source_mapping": {"start": 10315, "length": 5066, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "CrossDomainMessenger", "source_mapping": {"start": 3683, "length": 17490, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406], "starting_column": 1, "ending_column": 2}}, "signature": "relayMessage(uint256,address,address,uint256,uint256,bytes)"}}}}], "description": "CrossDomainMessenger.relayMessage(uint256,address,address,uint256,uint256,bytes) (src/universal/CrossDomainMessenger.sol#207-305) uses tx.origin for authorization: tx.origin == Constants.ESTIMATION_ADDRESS (src/universal/CrossDomainMessenger.sol#301)\n", "markdown": "[CrossDomainMessenger.relayMessage(uint256,address,address,uint256,uint256,bytes)](src/universal/CrossDomainMessenger.sol#L207-L305) uses tx.origin for authorization: [tx.origin == Constants.ESTIMATION_ADDRESS](src/universal/CrossDomainMessenger.sol#L301)\n", "first_markdown_element": "src/universal/CrossDomainMessenger.sol#L207-L305", "id": "3702aae0a8031af92233fa312a75b60518153a9f80ad2e6157debb825eec5ba1", "check": "tx-origin", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 13252, "length": 4839, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal", "source_mapping": {"start": 1199, "length": 20505, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}, {"type": "node", "name": "success == false && tx.origin == Constants.ESTIMATION_ADDRESS", "source_mapping": {"start": 17954, "length": 61, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [360], "starting_column": 13, "ending_column": 74}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 13252, "length": 4839, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal", "source_mapping": {"start": 1199, "length": 20505, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}], "description": "OptimismPortal.finalizeWithdrawalTransaction(Types.WithdrawalTransaction) (src/L1/OptimismPortal.sol#280-363) uses tx.origin for authorization: success == false && tx.origin == Constants.ESTIMATION_ADDRESS (src/L1/OptimismPortal.sol#360)\n", "markdown": "[OptimismPortal.finalizeWithdrawalTransaction(Types.WithdrawalTransaction)](src/L1/OptimismPortal.sol#L280-L363) uses tx.origin for authorization: [success == false && tx.origin == Constants.ESTIMATION_ADDRESS](src/L1/OptimismPortal.sol#L360)\n", "first_markdown_element": "src/L1/OptimismPortal.sol#L280-L363", "id": "b507540468fdf3f9972d33e723efb8c120f8d824ffe54842e1e998244944abaf", "check": "tx-origin", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 14716, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}, {"type": "node", "name": "! success && tx.origin == Constants.ESTIMATION_ADDRESS", "source_mapping": {"start": 16916, "length": 53, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [347], "starting_column": 13, "ending_column": 66}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 14716, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}], "description": "OptimismPortal2.finalizeWithdrawalTransaction(Types.WithdrawalTransaction) (src/L1/OptimismPortal2.sol#308-350) uses tx.origin for authorization: ! success && tx.origin == Constants.ESTIMATION_ADDRESS (src/L1/OptimismPortal2.sol#347)\n", "markdown": "[OptimismPortal2.finalizeWithdrawalTransaction(Types.WithdrawalTransaction)](src/L1/OptimismPortal2.sol#L308-L350) uses tx.origin for authorization: [! success && tx.origin == Constants.ESTIMATION_ADDRESS](src/L1/OptimismPortal2.sol#L347)\n", "first_markdown_element": "src/L1/OptimismPortal2.sol#L308-L350", "id": "7f4e534ab54f269b764a28db827d0820f938651b430bf72145e81408c8d77ef3", "check": "tx-origin", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "grandparentClock", "source_mapping": {"start": 11860, "length": 22, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [235], "starting_column": 9, "ending_column": 31}, "type_specific_fields": {"parent": {"type": "function", "name": "move", "source_mapping": {"start": 9517, "length": 4693, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "move(uint256,Claim,bool)"}}}}], "description": "FaultDisputeGame.move(uint256,Claim,bool).grandparentClock (src/dispute/FaultDisputeGame.sol#235) is a local variable never initialized\n", "markdown": "[FaultDisputeGame.move(uint256,Claim,bool).grandparentClock](src/dispute/FaultDisputeGame.sol#L235) is a local variable never initialized\n", "first_markdown_element": "src/dispute/FaultDisputeGame.sol#L235", "id": "0369380fef18a61639eac6a12773df792e9969e7bb20eddde54ccf3a263a0987", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "currentDepth", "source_mapping": {"start": 33339, "length": 20, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [690], "starting_column": 9, "ending_column": 29}, "type_specific_fields": {"parent": {"type": "function", "name": "_findStartingAndDisputedOutputs", "source_mapping": {"start": 32477, "length": 3446, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "_findStartingAndDisputedOutputs(uint256)"}}}}], "description": "FaultDisputeGame._findStartingAndDisputedOutputs(uint256).currentDepth (src/dispute/FaultDisputeGame.sol#690) is a local variable never initialized\n", "markdown": "[FaultDisputeGame._findStartingAndDisputedOutputs(uint256).currentDepth](src/dispute/FaultDisputeGame.sol#L690) is a local variable never initialized\n", "first_markdown_element": "src/dispute/FaultDisputeGame.sol#L690", "id": "8c229f5475784b2e9526e30d55b066e479489bca4b07c4f062b42b5b70100794", "check": "uninitialized-local", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "relayMessage", "source_mapping": {"start": 10315, "length": 5066, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "CrossDomainMessenger", "source_mapping": {"start": 3683, "length": 17490, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406], "starting_column": 1, "ending_column": 2}}, "signature": "relayMessage(uint256,address,address,uint256,uint256,bytes)"}}, {"type": "node", "name": "(version) = Encoding.decodeVersionedNonce(_nonce)", "source_mapping": {"start": 10787, "length": 58, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [222], "starting_column": 9, "ending_column": 67}, "type_specific_fields": {"parent": {"type": "function", "name": "relayMessage", "source_mapping": {"start": 10315, "length": 5066, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "CrossDomainMessenger", "source_mapping": {"start": 3683, "length": 17490, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406], "starting_column": 1, "ending_column": 2}}, "signature": "relayMessage(uint256,address,address,uint256,uint256,bytes)"}}}}], "description": "CrossDomainMessenger.relayMessage(uint256,address,address,uint256,uint256,bytes) (src/universal/CrossDomainMessenger.sol#207-305) ignores return value by (version) = Encoding.decodeVersionedNonce(_nonce) (src/universal/CrossDomainMessenger.sol#222)\n", "markdown": "[CrossDomainMessenger.relayMessage(uint256,address,address,uint256,uint256,bytes)](src/universal/CrossDomainMessenger.sol#L207-L305) ignores return value by [(version) = Encoding.decodeVersionedNonce(_nonce)](src/universal/CrossDomainMessenger.sol#L222)\n", "first_markdown_element": "src/universal/CrossDomainMessenger.sol#L207-L305", "id": "44386f359246ae057885fdfb55bd224c93990000eb00c0f8a95364098f76f95e", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "proveWithdrawalTransaction", "source_mapping": {"start": 10692, "length": 3911, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476], "starting_column": 1, "ending_column": 2}}, "signature": "proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[])"}}, {"type": "node", "name": "(gameType,gameProxy) = disputeGameFactory.gameAtIndex(_disputeGameIndex)", "source_mapping": {"start": 11391, "length": 96, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [247], "starting_column": 9, "ending_column": 105}, "type_specific_fields": {"parent": {"type": "function", "name": "proveWithdrawalTransaction", "source_mapping": {"start": 10692, "length": 3911, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476], "starting_column": 1, "ending_column": 2}}, "signature": "proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[])"}}}}], "description": "OptimismPortal2.proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[]) (src/L1/OptimismPortal2.sol#232-304) ignores return value by (gameType,gameProxy) = disputeGameFactory.gameAtIndex(_disputeGameIndex) (src/L1/OptimismPortal2.sol#247)\n", "markdown": "[OptimismPortal2.proveWithdrawalTransaction(Types.WithdrawalTransaction,uint256,Types.OutputRootProof,bytes[])](src/L1/OptimismPortal2.sol#L232-L304) ignores return value by [(gameType,gameProxy) = disputeGameFactory.gameAtIndex(_disputeGameIndex)](src/L1/OptimismPortal2.sol#L247)\n", "first_markdown_element": "src/L1/OptimismPortal2.sol#L232-L304", "id": "8830f3dfb5472dfaf7954fb2e77efcce01faa75aece2e030343e61548e8935e0", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "checkTransaction", "source_mapping": {"start": 3201, "length": 1635, "filename_relative": "src/Safe/LivenessGuard.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/Safe/LivenessGuard.sol", "filename_short": "src/Safe/LivenessGuard.sol", "is_dependency": false, "lines": [69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "LivenessGuard", "source_mapping": {"start": 1239, "length": 5732, "filename_relative": "src/Safe/LivenessGuard.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/Safe/LivenessGuard.sol", "filename_short": "src/Safe/LivenessGuard.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159], "starting_column": 1, "ending_column": 2}}, "signature": "checkTransaction(address,uint256,bytes,Enum.Operation,uint256,uint256,uint256,address,address,bytes,address)"}}, {"type": "node", "name": "ownersBefore.add(owners[i])", "source_mapping": {"start": 3884, "length": 27, "filename_relative": "src/Safe/LivenessGuard.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/Safe/LivenessGuard.sol", "filename_short": "src/Safe/LivenessGuard.sol", "is_dependency": false, "lines": [91], "starting_column": 13, "ending_column": 40}, "type_specific_fields": {"parent": {"type": "function", "name": "checkTransaction", "source_mapping": {"start": 3201, "length": 1635, "filename_relative": "src/Safe/LivenessGuard.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/Safe/LivenessGuard.sol", "filename_short": "src/Safe/LivenessGuard.sol", "is_dependency": false, "lines": [69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "LivenessGuard", "source_mapping": {"start": 1239, "length": 5732, "filename_relative": "src/Safe/LivenessGuard.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/Safe/LivenessGuard.sol", "filename_short": "src/Safe/LivenessGuard.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159], "starting_column": 1, "ending_column": 2}}, "signature": "checkTransaction(address,uint256,bytes,Enum.Operation,uint256,uint256,uint256,address,address,bytes,address)"}}}}], "description": "LivenessGuard.checkTransaction(address,uint256,bytes,Enum.Operation,uint256,uint256,uint256,address,address,bytes,address) (src/Safe/LivenessGuard.sol#69-117) ignores return value by ownersBefore.add(owners[i]) (src/Safe/LivenessGuard.sol#91)\n", "markdown": "[LivenessGuard.checkTransaction(address,uint256,bytes,Enum.Operation,uint256,uint256,uint256,address,address,bytes,address)](src/Safe/LivenessGuard.sol#L69-L117) ignores return value by [ownersBefore.add(owners[i])](src/Safe/LivenessGuard.sol#L91)\n", "first_markdown_element": "src/Safe/LivenessGuard.sol#L69-L117", "id": "e7db51bed73ec8725649e136aa53c89b47fb78f106a38ba5583f5f449c3df44c", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "checkAfterExecution", "source_mapping": {"start": 5290, "length": 1252, "filename_relative": "src/Safe/LivenessGuard.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/Safe/LivenessGuard.sol", "filename_short": "src/Safe/LivenessGuard.sol", "is_dependency": false, "lines": [125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "LivenessGuard", "source_mapping": {"start": 1239, "length": 5732, "filename_relative": "src/Safe/LivenessGuard.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/Safe/LivenessGuard.sol", "filename_short": "src/Safe/LivenessGuard.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159], "starting_column": 1, "ending_column": 2}}, "signature": "checkAfterExecution(bytes32,bool)"}}, {"type": "node", "name": "ownersBefore.remove(ownerBefore)", "source_mapping": {"start": 6493, "length": 32, "filename_relative": "src/Safe/LivenessGuard.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/Safe/LivenessGuard.sol", "filename_short": "src/Safe/LivenessGuard.sol", "is_dependency": false, "lines": [147], "starting_column": 13, "ending_column": 45}, "type_specific_fields": {"parent": {"type": "function", "name": "checkAfterExecution", "source_mapping": {"start": 5290, "length": 1252, "filename_relative": "src/Safe/LivenessGuard.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/Safe/LivenessGuard.sol", "filename_short": "src/Safe/LivenessGuard.sol", "is_dependency": false, "lines": [125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "LivenessGuard", "source_mapping": {"start": 1239, "length": 5732, "filename_relative": "src/Safe/LivenessGuard.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/Safe/LivenessGuard.sol", "filename_short": "src/Safe/LivenessGuard.sol", "is_dependency": false, "lines": [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159], "starting_column": 1, "ending_column": 2}}, "signature": "checkAfterExecution(bytes32,bool)"}}}}], "description": "LivenessGuard.checkAfterExecution(bytes32,bool) (src/Safe/LivenessGuard.sol#125-149) ignores return value by ownersBefore.remove(ownerBefore) (src/Safe/LivenessGuard.sol#147)\n", "markdown": "[LivenessGuard.checkAfterExecution(bytes32,bool)](src/Safe/LivenessGuard.sol#L125-L149) ignores return value by [ownersBefore.remove(ownerBefore)](src/Safe/LivenessGuard.sol#L147)\n", "first_markdown_element": "src/Safe/LivenessGuard.sol#L125-L149", "id": "a6b6c14f97b8f53fd719fe31b201e7e3ecd9e1e96588f3169f9b04eb60d2877d", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "games", "source_mapping": {"start": 2565, "length": 342, "filename_relative": "src/dispute/DisputeGameFactory.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol", "filename_short": "src/dispute/DisputeGameFactory.sol", "is_dependency": false, "lines": [64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DisputeGameFactory", "source_mapping": {"start": 1032, "length": 6436, "filename_relative": "src/dispute/DisputeGameFactory.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol", "filename_short": "src/dispute/DisputeGameFactory.sol", "is_dependency": false, "lines": [22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198], "starting_column": 1, "ending_column": 2}}, "signature": "games(GameType,Claim,bytes)"}}, {"type": "node", "name": "(None,timestamp_,proxy_) = _disputeGames[uuid].unpack()", "source_mapping": {"start": 2847, "length": 53, "filename_relative": "src/dispute/DisputeGameFactory.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol", "filename_short": "src/dispute/DisputeGameFactory.sol", "is_dependency": false, "lines": [74], "starting_column": 9, "ending_column": 62}, "type_specific_fields": {"parent": {"type": "function", "name": "games", "source_mapping": {"start": 2565, "length": 342, "filename_relative": "src/dispute/DisputeGameFactory.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol", "filename_short": "src/dispute/DisputeGameFactory.sol", "is_dependency": false, "lines": [64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "DisputeGameFactory", "source_mapping": {"start": 1032, "length": 6436, "filename_relative": "src/dispute/DisputeGameFactory.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol", "filename_short": "src/dispute/DisputeGameFactory.sol", "is_dependency": false, "lines": [22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198], "starting_column": 1, "ending_column": 2}}, "signature": "games(GameType,Claim,bytes)"}}}}], "description": "DisputeGameFactory.games(GameType,Claim,bytes) (src/dispute/DisputeGameFactory.sol#64-75) ignores return value by (None,timestamp_,proxy_) = _disputeGames[uuid].unpack() (src/dispute/DisputeGameFactory.sol#74)\n", "markdown": "[DisputeGameFactory.games(GameType,Claim,bytes)](src/dispute/DisputeGameFactory.sol#L64-L75) ignores return value by [(None,timestamp_,proxy_) = _disputeGames[uuid].unpack()](src/dispute/DisputeGameFactory.sol#L74)\n", "first_markdown_element": "src/dispute/DisputeGameFactory.sol#L64-L75", "id": "004aeb9cde0c34281efe12ecba9cf191a562c14d4840e4037cdfc3de62ace754", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "addLocalData", "source_mapping": {"start": 14579, "length": 2158, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "addLocalData(uint256,uint256,uint256)"}}, {"type": "node", "name": "oracle.loadLocalData(_ident,uuid.raw(),l1Head.raw(),32,_partOffset)", "source_mapping": {"start": 15220, "length": 71, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [310], "starting_column": 13, "ending_column": 84}, "type_specific_fields": {"parent": {"type": "function", "name": "addLocalData", "source_mapping": {"start": 14579, "length": 2158, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "addLocalData(uint256,uint256,uint256)"}}}}], "description": "FaultDisputeGame.addLocalData(uint256,uint256,uint256) (src/dispute/FaultDisputeGame.sol#299-334) ignores return value by oracle.loadLocalData(_ident,uuid.raw(),l1Head.raw(),32,_partOffset) (src/dispute/FaultDisputeGame.sol#310)\n", "markdown": "[FaultDisputeGame.addLocalData(uint256,uint256,uint256)](src/dispute/FaultDisputeGame.sol#L299-L334) ignores return value by [oracle.loadLocalData(_ident,uuid.raw(),l1Head.raw(),32,_partOffset)](src/dispute/FaultDisputeGame.sol#L310)\n", "first_markdown_element": "src/dispute/FaultDisputeGame.sol#L299-L334", "id": "763bb639fb65a7cbbf328c3f8ca871f83d4fec7f6158eac30b24a2930427b3a8", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "addLocalData", "source_mapping": {"start": 14579, "length": 2158, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "addLocalData(uint256,uint256,uint256)"}}, {"type": "node", "name": "oracle.loadLocalData(_ident,uuid.raw(),starting.raw(),32,_partOffset)", "source_mapping": {"start": 15432, "length": 73, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [313], "starting_column": 13, "ending_column": 86}, "type_specific_fields": {"parent": {"type": "function", "name": "addLocalData", "source_mapping": {"start": 14579, "length": 2158, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "addLocalData(uint256,uint256,uint256)"}}}}], "description": "FaultDisputeGame.addLocalData(uint256,uint256,uint256) (src/dispute/FaultDisputeGame.sol#299-334) ignores return value by oracle.loadLocalData(_ident,uuid.raw(),starting.raw(),32,_partOffset) (src/dispute/FaultDisputeGame.sol#313)\n", "markdown": "[FaultDisputeGame.addLocalData(uint256,uint256,uint256)](src/dispute/FaultDisputeGame.sol#L299-L334) ignores return value by [oracle.loadLocalData(_ident,uuid.raw(),starting.raw(),32,_partOffset)](src/dispute/FaultDisputeGame.sol#L313)\n", "first_markdown_element": "src/dispute/FaultDisputeGame.sol#L299-L334", "id": "db2c2eb34d10413c40fe2188f165de643843dd37f48449b9a8619c35c22f0279", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "addLocalData", "source_mapping": {"start": 14579, "length": 2158, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "addLocalData(uint256,uint256,uint256)"}}, {"type": "node", "name": "oracle.loadLocalData(_ident,uuid.raw(),disputed.raw(),32,_partOffset)", "source_mapping": {"start": 15645, "length": 73, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [316], "starting_column": 13, "ending_column": 86}, "type_specific_fields": {"parent": {"type": "function", "name": "addLocalData", "source_mapping": {"start": 14579, "length": 2158, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "addLocalData(uint256,uint256,uint256)"}}}}], "description": "FaultDisputeGame.addLocalData(uint256,uint256,uint256) (src/dispute/FaultDisputeGame.sol#299-334) ignores return value by oracle.loadLocalData(_ident,uuid.raw(),disputed.raw(),32,_partOffset) (src/dispute/FaultDisputeGame.sol#316)\n", "markdown": "[FaultDisputeGame.addLocalData(uint256,uint256,uint256)](src/dispute/FaultDisputeGame.sol#L299-L334) ignores return value by [oracle.loadLocalData(_ident,uuid.raw(),disputed.raw(),32,_partOffset)](src/dispute/FaultDisputeGame.sol#L316)\n", "first_markdown_element": "src/dispute/FaultDisputeGame.sol#L299-L334", "id": "9702aa60c8832889631f0b6de7d749a701854dfdcf73ceef0bace811c65aba71", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "addLocalData", "source_mapping": {"start": 14579, "length": 2158, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "addLocalData(uint256,uint256,uint256)"}}, {"type": "node", "name": "oracle.loadLocalData(_ident,uuid.raw(),bytes32(l2Number << 0xC0),8,_partOffset)", "source_mapping": {"start": 16325, "length": 83, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [327], "starting_column": 13, "ending_column": 96}, "type_specific_fields": {"parent": {"type": "function", "name": "addLocalData", "source_mapping": {"start": 14579, "length": 2158, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "addLocalData(uint256,uint256,uint256)"}}}}], "description": "FaultDisputeGame.addLocalData(uint256,uint256,uint256) (src/dispute/FaultDisputeGame.sol#299-334) ignores return value by oracle.loadLocalData(_ident,uuid.raw(),bytes32(l2Number << 0xC0),8,_partOffset) (src/dispute/FaultDisputeGame.sol#327)\n", "markdown": "[FaultDisputeGame.addLocalData(uint256,uint256,uint256)](src/dispute/FaultDisputeGame.sol#L299-L334) ignores return value by [oracle.loadLocalData(_ident,uuid.raw(),bytes32(l2Number << 0xC0),8,_partOffset)](src/dispute/FaultDisputeGame.sol#L327)\n", "first_markdown_element": "src/dispute/FaultDisputeGame.sol#L299-L334", "id": "ee245b77a502d8e82346325fe49d61108d0bd0ec1604ddcce2fe98109e008cbb", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "addLocalData", "source_mapping": {"start": 14579, "length": 2158, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "addLocalData(uint256,uint256,uint256)"}}, {"type": "node", "name": "oracle.loadLocalData(_ident,uuid.raw(),bytes32(block.chainid << 0xC0),8,_partOffset)", "source_mapping": {"start": 16575, "length": 88, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [330], "starting_column": 13, "ending_column": 101}, "type_specific_fields": {"parent": {"type": "function", "name": "addLocalData", "source_mapping": {"start": 14579, "length": 2158, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "FaultDisputeGame", "source_mapping": {"start": 762, "length": 36758, "filename_relative": "src/dispute/FaultDisputeGame.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol", "filename_short": "src/dispute/FaultDisputeGame.sol", "is_dependency": false, "lines": [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766], "starting_column": 1, "ending_column": 2}}, "signature": "addLocalData(uint256,uint256,uint256)"}}}}], "description": "FaultDisputeGame.addLocalData(uint256,uint256,uint256) (src/dispute/FaultDisputeGame.sol#299-334) ignores return value by oracle.loadLocalData(_ident,uuid.raw(),bytes32(block.chainid << 0xC0),8,_partOffset) (src/dispute/FaultDisputeGame.sol#330)\n", "markdown": "[FaultDisputeGame.addLocalData(uint256,uint256,uint256)](src/dispute/FaultDisputeGame.sol#L299-L334) ignores return value by [oracle.loadLocalData(_ident,uuid.raw(),bytes32(block.chainid << 0xC0),8,_partOffset)](src/dispute/FaultDisputeGame.sol#L330)\n", "first_markdown_element": "src/dispute/FaultDisputeGame.sol#L299-L334", "id": "73fe3972601cc6ea4ff24d94e8df972b992343d997e305b892512f0fe2853f5e", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "hashCrossDomainMessage", "source_mapping": {"start": 2094, "length": 660, "filename_relative": "src/libraries/Hashing.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/libraries/Hashing.sol", "filename_short": "src/libraries/Hashing.sol", "is_dependency": false, "lines": [39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Hashing", "source_mapping": {"start": 255, "length": 5092, "filename_relative": "src/libraries/Hashing.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/libraries/Hashing.sol", "filename_short": "src/libraries/Hashing.sol", "is_dependency": false, "lines": [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124], "starting_column": 1, "ending_column": 2}}, "signature": "hashCrossDomainMessage(uint256,address,address,uint256,uint256,bytes)"}}, {"type": "node", "name": "(version) = Encoding.decodeVersionedNonce(_nonce)", "source_mapping": {"start": 2355, "length": 58, "filename_relative": "src/libraries/Hashing.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/libraries/Hashing.sol", "filename_short": "src/libraries/Hashing.sol", "is_dependency": false, "lines": [51], "starting_column": 9, "ending_column": 67}, "type_specific_fields": {"parent": {"type": "function", "name": "hashCrossDomainMessage", "source_mapping": {"start": 2094, "length": 660, "filename_relative": "src/libraries/Hashing.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/libraries/Hashing.sol", "filename_short": "src/libraries/Hashing.sol", "is_dependency": false, "lines": [39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "Hashing", "source_mapping": {"start": 255, "length": 5092, "filename_relative": "src/libraries/Hashing.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/libraries/Hashing.sol", "filename_short": "src/libraries/Hashing.sol", "is_dependency": false, "lines": [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124], "starting_column": 1, "ending_column": 2}}, "signature": "hashCrossDomainMessage(uint256,address,address,uint256,uint256,bytes)"}}}}], "description": "Hashing.hashCrossDomainMessage(uint256,address,address,uint256,uint256,bytes) (src/libraries/Hashing.sol#39-59) ignores return value by (version) = Encoding.decodeVersionedNonce(_nonce) (src/libraries/Hashing.sol#51)\n", "markdown": "[Hashing.hashCrossDomainMessage(uint256,address,address,uint256,uint256,bytes)](src/libraries/Hashing.sol#L39-L59) ignores return value by [(version) = Encoding.decodeVersionedNonce(_nonce)](src/libraries/Hashing.sol#L51)\n", "first_markdown_element": "src/libraries/Hashing.sol#L39-L59", "id": "1c9189427ab6b52bbec781d0432aed1a62fbec3ef51df7b307691cc1281675ef", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "function", "name": "upgradeAndCall", "source_mapping": {"start": 8644, "length": 631, "filename_relative": "src/universal/ProxyAdmin.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/ProxyAdmin.sol", "filename_short": "src/universal/ProxyAdmin.sol", "is_dependency": false, "lines": [184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "ProxyAdmin", "source_mapping": {"start": 1241, "length": 8036, "filename_relative": "src/universal/ProxyAdmin.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/ProxyAdmin.sol", "filename_short": "src/universal/ProxyAdmin.sol", "is_dependency": false, "lines": [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203], "starting_column": 1, "ending_column": 2}}, "signature": "upgradeAndCall(address,address,bytes)"}}, {"type": "node", "name": "Proxy(_proxy).upgradeToAndCall{value: msg.value}(_implementation,_data)", "source_mapping": {"start": 8923, "length": 74, "filename_relative": "src/universal/ProxyAdmin.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/ProxyAdmin.sol", "filename_short": "src/universal/ProxyAdmin.sol", "is_dependency": false, "lines": [195], "starting_column": 13, "ending_column": 87}, "type_specific_fields": {"parent": {"type": "function", "name": "upgradeAndCall", "source_mapping": {"start": 8644, "length": 631, "filename_relative": "src/universal/ProxyAdmin.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/ProxyAdmin.sol", "filename_short": "src/universal/ProxyAdmin.sol", "is_dependency": false, "lines": [184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "ProxyAdmin", "source_mapping": {"start": 1241, "length": 8036, "filename_relative": "src/universal/ProxyAdmin.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/ProxyAdmin.sol", "filename_short": "src/universal/ProxyAdmin.sol", "is_dependency": false, "lines": [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203], "starting_column": 1, "ending_column": 2}}, "signature": "upgradeAndCall(address,address,bytes)"}}}}], "description": "ProxyAdmin.upgradeAndCall(address,address,bytes) (src/universal/ProxyAdmin.sol#184-202) ignores return value by Proxy(_proxy).upgradeToAndCall{value: msg.value}(_implementation,_data) (src/universal/ProxyAdmin.sol#195)\n", "markdown": "[ProxyAdmin.upgradeAndCall(address,address,bytes)](src/universal/ProxyAdmin.sol#L184-L202) ignores return value by [Proxy(_proxy).upgradeToAndCall{value: msg.value}(_implementation,_data)](src/universal/ProxyAdmin.sol#L195)\n", "first_markdown_element": "src/universal/ProxyAdmin.sol#L184-L202", "id": "81d1f7dc411a9897d1685d2a83e4ef7d0913f0beeec0756a1e90039e750ef319", "check": "unused-return", "impact": "Medium", "confidence": "Medium"}, {"elements": [{"type": "variable", "name": "xDomainMsgSender", "source_mapping": {"start": 5649, "length": 33, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [126], "starting_column": 5, "ending_column": 38}, "type_specific_fields": {"parent": {"type": "contract", "name": "CrossDomainMessenger", "source_mapping": {"start": 3683, "length": 17490, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406], "starting_column": 1, "ending_column": 2}}}}, {"type": "node", "name": "xDomainMsgSender = _sender", "source_mapping": {"start": 14084, "length": 26, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [282], "starting_column": 9, "ending_column": 35}, "type_specific_fields": {"parent": {"type": "function", "name": "relayMessage", "source_mapping": {"start": 10315, "length": 5066, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "CrossDomainMessenger", "source_mapping": {"start": 3683, "length": 17490, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406], "starting_column": 1, "ending_column": 2}}, "signature": "relayMessage(uint256,address,address,uint256,uint256,bytes)"}}}}, {"type": "node", "name": "xDomainMsgSender = Constants.DEFAULT_L2_SENDER", "source_mapping": {"start": 14217, "length": 46, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [284], "starting_column": 9, "ending_column": 55}, "type_specific_fields": {"parent": {"type": "function", "name": "relayMessage", "source_mapping": {"start": 10315, "length": 5066, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "CrossDomainMessenger", "source_mapping": {"start": 3683, "length": 17490, "filename_relative": "src/universal/CrossDomainMessenger.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol", "filename_short": "src/universal/CrossDomainMessenger.sol", "is_dependency": false, "lines": [87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406], "starting_column": 1, "ending_column": 2}}, "signature": "relayMessage(uint256,address,address,uint256,uint256,bytes)"}}}}], "description": "CrossDomainMessenger.xDomainMsgSender (src/universal/CrossDomainMessenger.sol#126) is written in both\n\txDomainMsgSender = _sender (src/universal/CrossDomainMessenger.sol#282)\n\txDomainMsgSender = Constants.DEFAULT_L2_SENDER (src/universal/CrossDomainMessenger.sol#284)\n", "markdown": "[CrossDomainMessenger.xDomainMsgSender](src/universal/CrossDomainMessenger.sol#L126) is written in both\n\t[xDomainMsgSender = _sender](src/universal/CrossDomainMessenger.sol#L282)\n\t[xDomainMsgSender = Constants.DEFAULT_L2_SENDER](src/universal/CrossDomainMessenger.sol#L284)\n", "first_markdown_element": "src/universal/CrossDomainMessenger.sol#L126", "id": "858b95108475bbb08343b6f5701b03c0762d00b73cec53751173e93c3ec10c1a", "check": "write-after-write", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "variable", "name": "l2Sender", "source_mapping": {"start": 2193, "length": 23, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [43], "starting_column": 5, "ending_column": 28}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal", "source_mapping": {"start": 1199, "length": 20505, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433], "starting_column": 1, "ending_column": 2}}}}, {"type": "node", "name": "l2Sender = _tx.sender", "source_mapping": {"start": 16655, "length": 21, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [339], "starting_column": 9, "ending_column": 30}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 13252, "length": 4839, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal", "source_mapping": {"start": 1199, "length": 20505, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}, {"type": "node", "name": "l2Sender = Constants.DEFAULT_L2_SENDER", "source_mapping": {"start": 17449, "length": 38, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [351], "starting_column": 9, "ending_column": 47}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 13252, "length": 4839, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal", "source_mapping": {"start": 1199, "length": 20505, "filename_relative": "src/L1/OptimismPortal.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal.sol", "filename_short": "src/L1/OptimismPortal.sol", "is_dependency": false, "lines": [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}], "description": "OptimismPortal.l2Sender (src/L1/OptimismPortal.sol#43) is written in both\n\tl2Sender = _tx.sender (src/L1/OptimismPortal.sol#339)\n\tl2Sender = Constants.DEFAULT_L2_SENDER (src/L1/OptimismPortal.sol#351)\n", "markdown": "[OptimismPortal.l2Sender](src/L1/OptimismPortal.sol#L43) is written in both\n\t[l2Sender = _tx.sender](src/L1/OptimismPortal.sol#L339)\n\t[l2Sender = Constants.DEFAULT_L2_SENDER](src/L1/OptimismPortal.sol#L351)\n", "first_markdown_element": "src/L1/OptimismPortal.sol#L43", "id": "a43b8cff6d6b33609e8c7e3e89af17a0bc9ec73eb9a1a1b796e69c36ce8bcf71", "check": "write-after-write", "impact": "Medium", "confidence": "High"}, {"elements": [{"type": "variable", "name": "l2Sender", "source_mapping": {"start": 2796, "length": 23, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [54], "starting_column": 5, "ending_column": 28}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476], "starting_column": 1, "ending_column": 2}}}}, {"type": "node", "name": "l2Sender = _tx.sender", "source_mapping": {"start": 15617, "length": 21, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [326], "starting_column": 9, "ending_column": 30}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 14716, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}, {"type": "node", "name": "l2Sender = Constants.DEFAULT_L2_SENDER", "source_mapping": {"start": 16411, "length": 38, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [338], "starting_column": 9, "ending_column": 47}, "type_specific_fields": {"parent": {"type": "function", "name": "finalizeWithdrawalTransaction", "source_mapping": {"start": 14716, "length": 2329, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350], "starting_column": 5, "ending_column": 6}, "type_specific_fields": {"parent": {"type": "contract", "name": "OptimismPortal2", "source_mapping": {"start": 1269, "length": 22759, "filename_relative": "src/L1/OptimismPortal2.sol", "filename_absolute": "/Users/mds/Documents/projects/ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/OptimismPortal2.sol", "filename_short": "src/L1/OptimismPortal2.sol", "is_dependency": false, "lines": [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476], "starting_column": 1, "ending_column": 2}}, "signature": "finalizeWithdrawalTransaction(Types.WithdrawalTransaction)"}}}}], "description": "OptimismPortal2.l2Sender (src/L1/OptimismPortal2.sol#54) is written in both\n\tl2Sender = _tx.sender (src/L1/OptimismPortal2.sol#326)\n\tl2Sender = Constants.DEFAULT_L2_SENDER (src/L1/OptimismPortal2.sol#338)\n", "markdown": "[OptimismPortal2.l2Sender](src/L1/OptimismPortal2.sol#L54) is written in both\n\t[l2Sender = _tx.sender](src/L1/OptimismPortal2.sol#L326)\n\t[l2Sender = Constants.DEFAULT_L2_SENDER](src/L1/OptimismPortal2.sol#L338)\n", "first_markdown_element": "src/L1/OptimismPortal2.sol#L54", "id": "39a1b02450892eee126102ad84facb2bd801987bf64fb0d092e7b428629fd203", "check": "write-after-write", "impact": "Medium", "confidence": "High"}] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/AddressManager.json b/packages/contracts-bedrock/snapshots/abi/AddressManager.json new file mode 100644 index 000000000000..f0efe2ed4d57 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/AddressManager.json @@ -0,0 +1,116 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "setAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "oldAddress", + "type": "address" + } + ], + "name": "AddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/AdminFaucetAuthModule.json b/packages/contracts-bedrock/snapshots/abi/AdminFaucetAuthModule.json new file mode 100644 index 000000000000..7c2112223259 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/AdminFaucetAuthModule.json @@ -0,0 +1,90 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_version", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ADMIN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROOF_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "nonce", + "type": "bytes32" + } + ], + "internalType": "struct Faucet.DripParameters", + "name": "_params", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "_id", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "valid_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json b/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json new file mode 100644 index 000000000000..37ddc45a0ae2 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/AnchorStateRegistry.json @@ -0,0 +1,120 @@ +[ + { + "inputs": [ + { + "internalType": "contract IDisputeGameFactory", + "name": "_disputeGameFactory", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "", + "type": "uint32" + } + ], + "name": "anchors", + "outputs": [ + { + "internalType": "Hash", + "name": "root", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "l2BlockNumber", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disputeGameFactory", + "outputs": [ + { + "internalType": "contract IDisputeGameFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "GameType", + "name": "gameType", + "type": "uint32" + }, + { + "components": [ + { + "internalType": "Hash", + "name": "root", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "l2BlockNumber", + "type": "uint256" + } + ], + "internalType": "struct OutputRoot", + "name": "outputRoot", + "type": "tuple" + } + ], + "internalType": "struct AnchorStateRegistry.StartingAnchorRoot[]", + "name": "_startingAnchorRoots", + "type": "tuple[]" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tryUpdateAnchorState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/AssetReceiver.json b/packages/contracts-bedrock/snapshots/abi/AssetReceiver.json new file mode 100644 index 000000000000..543e32913df9 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/AssetReceiver.json @@ -0,0 +1,326 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "CALL", + "outputs": [ + { + "internalType": "bool", + "name": "success_", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "data_", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "DELEGATECALL", + "outputs": [ + { + "internalType": "bool", + "name": "success_", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "data_", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_asset", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_asset", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "withdrawERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC721", + "name": "_asset", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_to", + "type": "address" + } + ], + "name": "withdrawETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ReceivedETH", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "withdrawer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrewERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "withdrawer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "WithdrewERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "withdrawer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrewETH", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/AttestationStation.json b/packages/contracts-bedrock/snapshots/abi/AttestationStation.json new file mode 100644 index 000000000000..ba7d5f9759e7 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/AttestationStation.json @@ -0,0 +1,128 @@ +[ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "about", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "val", + "type": "bytes" + } + ], + "internalType": "struct AttestationStation.AttestationData[]", + "name": "_attestations", + "type": "tuple[]" + } + ], + "name": "attest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_about", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_key", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_val", + "type": "bytes" + } + ], + "name": "attest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "attestations", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "about", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "val", + "type": "bytes" + } + ], + "name": "AttestationCreated", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/BaseFeeVault.json b/packages/contracts-bedrock/snapshots/abi/BaseFeeVault.json new file mode 100644 index 000000000000..980f6f31551f --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/BaseFeeVault.json @@ -0,0 +1,155 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minWithdrawalAmount", + "type": "uint256" + }, + { + "internalType": "enum FeeVault.WithdrawalNetwork", + "name": "_withdrawalNetwork", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "MIN_WITHDRAWAL_AMOUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RECIPIENT", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WITHDRAWAL_NETWORK", + "outputs": [ + { + "internalType": "enum FeeVault.WithdrawalNetwork", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalProcessed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum FeeVault.WithdrawalNetwork", + "name": "withdrawalNetwork", + "type": "uint8" + } + ], + "name": "Withdrawal", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/BlockOracle.json b/packages/contracts-bedrock/snapshots/abi/BlockOracle.json new file mode 100644 index 000000000000..1b888772334c --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/BlockOracle.json @@ -0,0 +1,89 @@ +[ + { + "inputs": [], + "name": "checkpoint", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_blockNumber", + "type": "uint256" + } + ], + "name": "load", + "outputs": [ + { + "components": [ + { + "internalType": "Hash", + "name": "hash", + "type": "bytes32" + }, + { + "internalType": "Timestamp", + "name": "childTimestamp", + "type": "uint64" + } + ], + "internalType": "struct BlockOracle.BlockInfo", + "name": "blockInfo_", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "Hash", + "name": "blockHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "Timestamp", + "name": "childTimestamp", + "type": "uint64" + } + ], + "name": "Checkpoint", + "type": "event" + }, + { + "inputs": [], + "name": "BlockHashNotPresent", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/Burner.json b/packages/contracts-bedrock/snapshots/abi/Burner.json new file mode 100644 index 000000000000..5fa856267a8b --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/Burner.json @@ -0,0 +1,7 @@ +[ + { + "inputs": [], + "stateMutability": "payable", + "type": "constructor" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/CheckBalanceLow.json b/packages/contracts-bedrock/snapshots/abi/CheckBalanceLow.json new file mode 100644 index 000000000000..6bdf5f033af8 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/CheckBalanceLow.json @@ -0,0 +1,46 @@ +[ + { + "inputs": [ + { + "internalType": "bytes", + "name": "_params", + "type": "bytes" + } + ], + "name": "check", + "outputs": [ + { + "internalType": "bool", + "name": "execute_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct CheckBalanceLow.Params", + "name": "params", + "type": "tuple" + } + ], + "name": "_EventToExposeStructInABI__Params", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/CheckGelatoLow.json b/packages/contracts-bedrock/snapshots/abi/CheckGelatoLow.json new file mode 100644 index 000000000000..7e3b9cbee04a --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/CheckGelatoLow.json @@ -0,0 +1,51 @@ +[ + { + "inputs": [ + { + "internalType": "bytes", + "name": "_params", + "type": "bytes" + } + ], + "name": "check", + "outputs": [ + { + "internalType": "bool", + "name": "execute_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "treasury", + "type": "address" + }, + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "indexed": false, + "internalType": "struct CheckGelatoLow.Params", + "name": "params", + "type": "tuple" + } + ], + "name": "_EventToExposeStructInABI__Params", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/CheckTrue.json b/packages/contracts-bedrock/snapshots/abi/CheckTrue.json new file mode 100644 index 000000000000..8d146c452afb --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/CheckTrue.json @@ -0,0 +1,21 @@ +[ + { + "inputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "check", + "outputs": [ + { + "internalType": "bool", + "name": "execute_", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/Clone.json b/packages/contracts-bedrock/snapshots/abi/Clone.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/Clone.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/CrossDomainMessengerLegacySpacer0.json b/packages/contracts-bedrock/snapshots/abi/CrossDomainMessengerLegacySpacer0.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/CrossDomainMessengerLegacySpacer0.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/CrossDomainMessengerLegacySpacer1.json b/packages/contracts-bedrock/snapshots/abi/CrossDomainMessengerLegacySpacer1.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/CrossDomainMessengerLegacySpacer1.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/DataAvailabilityChallenge.json b/packages/contracts-bedrock/snapshots/abi/DataAvailabilityChallenge.json new file mode 100644 index 000000000000..fdf59e1a0026 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/DataAvailabilityChallenge.json @@ -0,0 +1,584 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bondSize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "challengedBlockNumber", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "challengedCommitment", + "type": "bytes" + } + ], + "name": "challenge", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "challengeWindow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "fixedResolutionCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "challengedBlockNumber", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "challengedCommitment", + "type": "bytes" + } + ], + "name": "getChallenge", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "challenger", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lockedBond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "resolvedBlock", + "type": "uint256" + } + ], + "internalType": "struct Challenge", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "challengedBlockNumber", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "challengedCommitment", + "type": "bytes" + } + ], + "name": "getChallengeStatus", + "outputs": [ + { + "internalType": "enum ChallengeStatus", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_challengeWindow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_resolveWindow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_bondSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_resolverRefundPercentage", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "challengedBlockNumber", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "challengedCommitment", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "resolveData", + "type": "bytes" + } + ], + "name": "resolve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resolveWindow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "resolverRefundPercentage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bondSize", + "type": "uint256" + } + ], + "name": "setBondSize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_resolverRefundPercentage", + "type": "uint256" + } + ], + "name": "setResolverRefundPercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "challengedBlockNumber", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "challengedCommitment", + "type": "bytes" + } + ], + "name": "unlockBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "commitment", + "type": "bytes" + } + ], + "name": "validateCommitment", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "variableResolutionCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "variableResolutionCostPrecision", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "name": "BalanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "challengedBlockNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "challengedCommitment", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "enum ChallengeStatus", + "name": "status", + "type": "uint8" + } + ], + "name": "ChallengeStatusChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "challengeWindow", + "type": "uint256" + } + ], + "name": "RequiredBondSizeChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "resolverRefundPercentage", + "type": "uint256" + } + ], + "name": "ResolverRefundPercentageChanged", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "required", + "type": "uint256" + } + ], + "name": "BondTooLow", + "type": "error" + }, + { + "inputs": [], + "name": "ChallengeExists", + "type": "error" + }, + { + "inputs": [], + "name": "ChallengeNotActive", + "type": "error" + }, + { + "inputs": [], + "name": "ChallengeNotExpired", + "type": "error" + }, + { + "inputs": [], + "name": "ChallengeWindowNotOpen", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "commitmentType", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "expectedLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualLength", + "type": "uint256" + } + ], + "name": "InvalidCommitmentLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "providedDataCommitment", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "expectedCommitment", + "type": "bytes" + } + ], + "name": "InvalidInputData", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "invalidResolverRefundPercentage", + "type": "uint256" + } + ], + "name": "InvalidResolverRefundPercentage", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "commitmentType", + "type": "uint8" + } + ], + "name": "UnknownCommitmentType", + "type": "error" + }, + { + "inputs": [], + "name": "WithdrawalFailed", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/DelayedVetoable.json b/packages/contracts-bedrock/snapshots/abi/DelayedVetoable.json new file mode 100644 index 000000000000..fad9861a1374 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/DelayedVetoable.json @@ -0,0 +1,207 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "vetoer_", + "type": "address" + }, + { + "internalType": "address", + "name": "initiator_", + "type": "address" + }, + { + "internalType": "address", + "name": "target_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "operatingDelay_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "nonpayable", + "type": "fallback" + }, + { + "inputs": [], + "name": "delay", + "outputs": [ + { + "internalType": "uint256", + "name": "delay_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initiator", + "outputs": [ + { + "internalType": "address", + "name": "initiator_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "callHash", + "type": "bytes32" + } + ], + "name": "queuedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "queuedAt_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "target", + "outputs": [ + { + "internalType": "address", + "name": "target_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vetoer", + "outputs": [ + { + "internalType": "address", + "name": "vetoer_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "delay", + "type": "uint256" + } + ], + "name": "DelayActivated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "callHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "Forwarded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "callHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "Initiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "callHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "Vetoed", + "type": "event" + }, + { + "inputs": [], + "name": "ForwardingEarly", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "expected", + "type": "address" + }, + { + "internalType": "address", + "name": "actual", + "type": "address" + } + ], + "name": "Unauthorized", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json b/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json new file mode 100644 index 000000000000..ef58fc35f123 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/DelayedWETH.json @@ -0,0 +1,534 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_delay", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "config", + "outputs": [ + { + "internalType": "contract SuperchainConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "delay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_guy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_wad", + "type": "uint256" + } + ], + "name": "hold", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "contract SuperchainConfig", + "name": "_config", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_wad", + "type": "uint256" + } + ], + "name": "recover", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_guy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_wad", + "type": "uint256" + } + ], + "name": "unlock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_wad", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_guy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_wad", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "withdrawals", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "guy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Unwrap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/DeployerWhitelist.json b/packages/contracts-bedrock/snapshots/abi/DeployerWhitelist.json new file mode 100644 index 000000000000..ca4b49ab5a5a --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/DeployerWhitelist.json @@ -0,0 +1,155 @@ +[ + { + "inputs": [], + "name": "enableArbitraryContractDeployment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_deployer", + "type": "address" + } + ], + "name": "isDeployerAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_deployer", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isWhitelisted", + "type": "bool" + } + ], + "name": "setWhitelistedDeployer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + } + ], + "name": "WhitelistDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "deployer", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "whitelisted", + "type": "bool" + } + ], + "name": "WhitelistStatusChanged", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json b/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json new file mode 100644 index 000000000000..01de0ce1b0a1 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/DisputeGameFactory.json @@ -0,0 +1,452 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "_gameType", + "type": "uint32" + }, + { + "internalType": "Claim", + "name": "_rootClaim", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "create", + "outputs": [ + { + "internalType": "contract IDisputeGame", + "name": "proxy_", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "_gameType", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "_start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_n", + "type": "uint256" + } + ], + "name": "findLatestGames", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "GameId", + "name": "metadata", + "type": "bytes32" + }, + { + "internalType": "Timestamp", + "name": "timestamp", + "type": "uint64" + }, + { + "internalType": "Claim", + "name": "rootClaim", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "internalType": "struct IDisputeGameFactory.GameSearchResult[]", + "name": "games_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "gameAtIndex", + "outputs": [ + { + "internalType": "GameType", + "name": "gameType_", + "type": "uint32" + }, + { + "internalType": "Timestamp", + "name": "timestamp_", + "type": "uint64" + }, + { + "internalType": "contract IDisputeGame", + "name": "proxy_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gameCount", + "outputs": [ + { + "internalType": "uint256", + "name": "gameCount_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "", + "type": "uint32" + } + ], + "name": "gameImpls", + "outputs": [ + { + "internalType": "contract IDisputeGame", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "_gameType", + "type": "uint32" + }, + { + "internalType": "Claim", + "name": "_rootClaim", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "games", + "outputs": [ + { + "internalType": "contract IDisputeGame", + "name": "proxy_", + "type": "address" + }, + { + "internalType": "Timestamp", + "name": "timestamp_", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "_gameType", + "type": "uint32" + }, + { + "internalType": "Claim", + "name": "_rootClaim", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "getGameUUID", + "outputs": [ + { + "internalType": "Hash", + "name": "uuid_", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "", + "type": "uint32" + } + ], + "name": "initBonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "_gameType", + "type": "uint32" + }, + { + "internalType": "contract IDisputeGame", + "name": "_impl", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "_gameType", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "_initBond", + "type": "uint256" + } + ], + "name": "setInitBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "disputeProxy", + "type": "address" + }, + { + "indexed": true, + "internalType": "GameType", + "name": "gameType", + "type": "uint32" + }, + { + "indexed": true, + "internalType": "Claim", + "name": "rootClaim", + "type": "bytes32" + } + ], + "name": "DisputeGameCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "impl", + "type": "address" + }, + { + "indexed": true, + "internalType": "GameType", + "name": "gameType", + "type": "uint32" + } + ], + "name": "ImplementationSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "GameType", + "name": "gameType", + "type": "uint32" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "newBond", + "type": "uint256" + } + ], + "name": "InitBondUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "Hash", + "name": "uuid", + "type": "bytes32" + } + ], + "name": "GameAlreadyExists", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientBond", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "gameType", + "type": "uint32" + } + ], + "name": "NoImplementation", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/Drippie.json b/packages/contracts-bedrock/snapshots/abi/Drippie.json new file mode 100644 index 000000000000..2e0da78d28b2 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/Drippie.json @@ -0,0 +1,660 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "CALL", + "outputs": [ + { + "internalType": "bool", + "name": "success_", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "data_", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "DELEGATECALL", + "outputs": [ + { + "internalType": "bool", + "name": "success_", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "data_", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "components": [ + { + "internalType": "bool", + "name": "reentrant", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "interval", + "type": "uint256" + }, + { + "internalType": "contract IDripCheck", + "name": "dripcheck", + "type": "address" + }, + { + "internalType": "bytes", + "name": "checkparams", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "address payable", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Drippie.DripAction[]", + "name": "actions", + "type": "tuple[]" + } + ], + "internalType": "struct Drippie.DripConfig", + "name": "_config", + "type": "tuple" + } + ], + "name": "create", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "name": "drip", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "name": "drips", + "outputs": [ + { + "internalType": "enum Drippie.DripStatus", + "name": "status", + "type": "uint8" + }, + { + "components": [ + { + "internalType": "bool", + "name": "reentrant", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "interval", + "type": "uint256" + }, + { + "internalType": "contract IDripCheck", + "name": "dripcheck", + "type": "address" + }, + { + "internalType": "bytes", + "name": "checkparams", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "address payable", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Drippie.DripAction[]", + "name": "actions", + "type": "tuple[]" + } + ], + "internalType": "struct Drippie.DripConfig", + "name": "config", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "last", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "name": "executable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "name": "getDripStatus", + "outputs": [ + { + "internalType": "enum Drippie.DripStatus", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "enum Drippie.DripStatus", + "name": "_status", + "type": "uint8" + } + ], + "name": "status", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_asset", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_asset", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "withdrawERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC721", + "name": "_asset", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_to", + "type": "address" + } + ], + "name": "withdrawETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "nameref", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "components": [ + { + "internalType": "bool", + "name": "reentrant", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "interval", + "type": "uint256" + }, + { + "internalType": "contract IDripCheck", + "name": "dripcheck", + "type": "address" + }, + { + "internalType": "bytes", + "name": "checkparams", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "address payable", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct Drippie.DripAction[]", + "name": "actions", + "type": "tuple[]" + } + ], + "indexed": false, + "internalType": "struct Drippie.DripConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "DripCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "nameref", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "DripExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "nameref", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "indexed": false, + "internalType": "enum Drippie.DripStatus", + "name": "status", + "type": "uint8" + } + ], + "name": "DripStatusUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ReceivedETH", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "withdrawer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrewERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "withdrawer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "WithdrewERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "withdrawer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrewETH", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/EAS.json b/packages/contracts-bedrock/snapshots/abi/EAS.json new file mode 100644 index 000000000000..0758dd6218c6 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/EAS.json @@ -0,0 +1,1089 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "schema", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint64", + "name": "expirationTime", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "revocable", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "refUID", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct AttestationRequestData", + "name": "data", + "type": "tuple" + } + ], + "internalType": "struct AttestationRequest", + "name": "request", + "type": "tuple" + } + ], + "name": "attest", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "schema", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint64", + "name": "expirationTime", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "revocable", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "refUID", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct AttestationRequestData", + "name": "data", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "internalType": "struct Signature", + "name": "signature", + "type": "tuple" + }, + { + "internalType": "address", + "name": "attester", + "type": "address" + }, + { + "internalType": "uint64", + "name": "deadline", + "type": "uint64" + } + ], + "internalType": "struct DelegatedAttestationRequest", + "name": "delegatedRequest", + "type": "tuple" + } + ], + "name": "attestByDelegation", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getAttestTypeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + } + ], + "name": "getAttestation", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "schema", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "time", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "expirationTime", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "revocationTime", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "refUID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "attester", + "type": "address" + }, + { + "internalType": "bool", + "name": "revocable", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct Attestation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDomainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getName", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "revoker", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "data", + "type": "bytes32" + } + ], + "name": "getRevokeOffchain", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRevokeTypeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getSchemaRegistry", + "outputs": [ + { + "internalType": "contract ISchemaRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "data", + "type": "bytes32" + } + ], + "name": "getTimestamp", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newNonce", + "type": "uint256" + } + ], + "name": "increaseNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + } + ], + "name": "isAttestationValid", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "schema", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint64", + "name": "expirationTime", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "revocable", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "refUID", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct AttestationRequestData[]", + "name": "data", + "type": "tuple[]" + } + ], + "internalType": "struct MultiAttestationRequest[]", + "name": "multiRequests", + "type": "tuple[]" + } + ], + "name": "multiAttest", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "schema", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint64", + "name": "expirationTime", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "revocable", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "refUID", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct AttestationRequestData[]", + "name": "data", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "internalType": "struct Signature[]", + "name": "signatures", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "attester", + "type": "address" + }, + { + "internalType": "uint64", + "name": "deadline", + "type": "uint64" + } + ], + "internalType": "struct MultiDelegatedAttestationRequest[]", + "name": "multiDelegatedRequests", + "type": "tuple[]" + } + ], + "name": "multiAttestByDelegation", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "", + "type": "bytes32[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "schema", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct RevocationRequestData[]", + "name": "data", + "type": "tuple[]" + } + ], + "internalType": "struct MultiRevocationRequest[]", + "name": "multiRequests", + "type": "tuple[]" + } + ], + "name": "multiRevoke", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "schema", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct RevocationRequestData[]", + "name": "data", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "internalType": "struct Signature[]", + "name": "signatures", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "revoker", + "type": "address" + }, + { + "internalType": "uint64", + "name": "deadline", + "type": "uint64" + } + ], + "internalType": "struct MultiDelegatedRevocationRequest[]", + "name": "multiDelegatedRequests", + "type": "tuple[]" + } + ], + "name": "multiRevokeByDelegation", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "name": "multiRevokeOffchain", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "name": "multiTimestamp", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "schema", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct RevocationRequestData", + "name": "data", + "type": "tuple" + } + ], + "internalType": "struct RevocationRequest", + "name": "request", + "type": "tuple" + } + ], + "name": "revoke", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "schema", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct RevocationRequestData", + "name": "data", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "internalType": "struct Signature", + "name": "signature", + "type": "tuple" + }, + { + "internalType": "address", + "name": "revoker", + "type": "address" + }, + { + "internalType": "uint64", + "name": "deadline", + "type": "uint64" + } + ], + "internalType": "struct DelegatedRevocationRequest", + "name": "delegatedRequest", + "type": "tuple" + } + ], + "name": "revokeByDelegation", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "data", + "type": "bytes32" + } + ], + "name": "revokeOffchain", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "data", + "type": "bytes32" + } + ], + "name": "timestamp", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "attester", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "schemaUID", + "type": "bytes32" + } + ], + "name": "Attested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldNonce", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newNonce", + "type": "uint256" + } + ], + "name": "NonceIncreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "attester", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "schemaUID", + "type": "bytes32" + } + ], + "name": "Revoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "revoker", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "data", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "timestamp", + "type": "uint64" + } + ], + "name": "RevokedOffchain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "data", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "timestamp", + "type": "uint64" + } + ], + "name": "Timestamped", + "type": "event" + }, + { + "inputs": [], + "name": "AccessDenied", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyRevoked", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyRevokedOffchain", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyTimestamped", + "type": "error" + }, + { + "inputs": [], + "name": "DeadlineExpired", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientValue", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAttestation", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAttestations", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidExpirationTime", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidLength", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidNonce", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidOffset", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRegistry", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRevocation", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRevocations", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSchema", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidVerifier", + "type": "error" + }, + { + "inputs": [], + "name": "Irrevocable", + "type": "error" + }, + { + "inputs": [], + "name": "NotFound", + "type": "error" + }, + { + "inputs": [], + "name": "NotPayable", + "type": "error" + }, + { + "inputs": [], + "name": "WrongSchema", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/Faucet.json b/packages/contracts-bedrock/snapshots/abi/Faucet.json new file mode 100644 index 000000000000..f943faed8283 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/Faucet.json @@ -0,0 +1,267 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "ADMIN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IFaucetAuthModule", + "name": "_module", + "type": "address" + }, + { + "components": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "ttl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct Faucet.ModuleConfig", + "name": "_config", + "type": "tuple" + } + ], + "name": "configure", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "nonce", + "type": "bytes32" + } + ], + "internalType": "struct Faucet.DripParameters", + "name": "_params", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "contract IFaucetAuthModule", + "name": "module", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + } + ], + "internalType": "struct Faucet.AuthParameters", + "name": "_auth", + "type": "tuple" + } + ], + "name": "drip", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IFaucetAuthModule", + "name": "_module", + "type": "address" + } + ], + "name": "isModuleEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IFaucetAuthModule", + "name": "", + "type": "address" + } + ], + "name": "modules", + "outputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "ttl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IFaucetAuthModule", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "timeouts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "authModule", + "type": "string" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "userId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "Drip", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/FaultDisputeGame.json b/packages/contracts-bedrock/snapshots/abi/FaultDisputeGame.json new file mode 100644 index 000000000000..cd9ddfee2cb1 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/FaultDisputeGame.json @@ -0,0 +1,754 @@ +[ + { + "inputs": [ + { + "internalType": "GameType", + "name": "_gameType", + "type": "uint32" + }, + { + "internalType": "Claim", + "name": "_absolutePrestate", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_maxGameDepth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_splitDepth", + "type": "uint256" + }, + { + "internalType": "Duration", + "name": "_gameDuration", + "type": "uint64" + }, + { + "internalType": "contract IBigStepper", + "name": "_vm", + "type": "address" + }, + { + "internalType": "contract IDelayedWETH", + "name": "_weth", + "type": "address" + }, + { + "internalType": "contract IAnchorStateRegistry", + "name": "_anchorStateRegistry", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_l2ChainId", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "absolutePrestate", + "outputs": [ + { + "internalType": "Claim", + "name": "absolutePrestate_", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_ident", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_execLeafIdx", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_partOffset", + "type": "uint256" + } + ], + "name": "addLocalData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_parentIndex", + "type": "uint256" + }, + { + "internalType": "Claim", + "name": "_claim", + "type": "bytes32" + } + ], + "name": "attack", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "claimCredit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "claimData", + "outputs": [ + { + "internalType": "uint32", + "name": "parentIndex", + "type": "uint32" + }, + { + "internalType": "address", + "name": "counteredBy", + "type": "address" + }, + { + "internalType": "address", + "name": "claimant", + "type": "address" + }, + { + "internalType": "uint128", + "name": "bond", + "type": "uint128" + }, + { + "internalType": "Claim", + "name": "claim", + "type": "bytes32" + }, + { + "internalType": "Position", + "name": "position", + "type": "uint128" + }, + { + "internalType": "Clock", + "name": "clock", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimDataLen", + "outputs": [ + { + "internalType": "uint256", + "name": "len_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimedBondFlag", + "outputs": [ + { + "internalType": "uint128", + "name": "claimedBondFlag_", + "type": "uint128" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "createdAt", + "outputs": [ + { + "internalType": "Timestamp", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "credit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_parentIndex", + "type": "uint256" + }, + { + "internalType": "Claim", + "name": "_claim", + "type": "bytes32" + } + ], + "name": "defend", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "extraData", + "outputs": [ + { + "internalType": "bytes", + "name": "extraData_", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "gameData", + "outputs": [ + { + "internalType": "GameType", + "name": "gameType_", + "type": "uint32" + }, + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "extraData_", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gameDuration", + "outputs": [ + { + "internalType": "Duration", + "name": "gameDuration_", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gameType", + "outputs": [ + { + "internalType": "GameType", + "name": "gameType_", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "Position", + "name": "_position", + "type": "uint128" + } + ], + "name": "getRequiredBond", + "outputs": [ + { + "internalType": "uint256", + "name": "requiredBond_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "l1Head", + "outputs": [ + { + "internalType": "Hash", + "name": "l1Head_", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "l2BlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "l2BlockNumber_", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "l2ChainId", + "outputs": [ + { + "internalType": "uint256", + "name": "l2ChainId_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxGameDepth", + "outputs": [ + { + "internalType": "uint256", + "name": "maxGameDepth_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_challengeIndex", + "type": "uint256" + }, + { + "internalType": "Claim", + "name": "_claim", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "_isAttack", + "type": "bool" + } + ], + "name": "move", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "resolve", + "outputs": [ + { + "internalType": "enum GameStatus", + "name": "status_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_claimIndex", + "type": "uint256" + } + ], + "name": "resolveClaim", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "resolvedAt", + "outputs": [ + { + "internalType": "Timestamp", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rootClaim", + "outputs": [ + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "splitDepth", + "outputs": [ + { + "internalType": "uint256", + "name": "splitDepth_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startingBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "startingBlockNumber_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startingOutputRoot", + "outputs": [ + { + "internalType": "Hash", + "name": "root", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "l2BlockNumber", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startingRootHash", + "outputs": [ + { + "internalType": "Hash", + "name": "startingRootHash_", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "status", + "outputs": [ + { + "internalType": "enum GameStatus", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_claimIndex", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isAttack", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_stateData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + } + ], + "name": "step", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vm", + "outputs": [ + { + "internalType": "contract IBigStepper", + "name": "vm_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "weth", + "outputs": [ + { + "internalType": "contract IDelayedWETH", + "name": "weth_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "parentIndex", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "Claim", + "name": "claim", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "claimant", + "type": "address" + } + ], + "name": "Move", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "enum GameStatus", + "name": "status", + "type": "uint8" + } + ], + "name": "Resolved", + "type": "event" + }, + { + "inputs": [], + "name": "AlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "AnchorRootNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "BondTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "CannotDefendRootClaim", + "type": "error" + }, + { + "inputs": [], + "name": "ClaimAboveSplit", + "type": "error" + }, + { + "inputs": [], + "name": "ClaimAlreadyExists", + "type": "error" + }, + { + "inputs": [], + "name": "ClaimAlreadyResolved", + "type": "error" + }, + { + "inputs": [], + "name": "ClockNotExpired", + "type": "error" + }, + { + "inputs": [], + "name": "ClockTimeExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateStep", + "type": "error" + }, + { + "inputs": [], + "name": "GameDepthExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "GameNotInProgress", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientBond", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidLocalIdent", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidParent", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPrestate", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSplitDepth", + "type": "error" + }, + { + "inputs": [], + "name": "NoCreditToClaim", + "type": "error" + }, + { + "inputs": [], + "name": "OutOfOrderResolution", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Claim", + "name": "rootClaim", + "type": "bytes32" + } + ], + "name": "UnexpectedRootClaim", + "type": "error" + }, + { + "inputs": [], + "name": "ValidStep", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/GasPriceOracle.json b/packages/contracts-bedrock/snapshots/abi/GasPriceOracle.json new file mode 100644 index 000000000000..8689547c919f --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/GasPriceOracle.json @@ -0,0 +1,203 @@ +[ + { + "inputs": [], + "name": "DECIMALS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseFeeScalar", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blobBaseFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blobBaseFeeScalar", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "gasPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "getL1Fee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "getL1GasUsed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isEcotone", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1BaseFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "overhead", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "scalar", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "setEcotone", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/GovernanceToken.json b/packages/contracts-bedrock/snapshots/abi/GovernanceToken.json new file mode 100644 index 000000000000..a8b9b67342f4 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/GovernanceToken.json @@ -0,0 +1,690 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint32", + "name": "pos", + "type": "uint32" + } + ], + "name": "checkpoints", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "fromBlock", + "type": "uint32" + }, + { + "internalType": "uint224", + "name": "votes", + "type": "uint224" + } + ], + "internalType": "struct ERC20Votes.Checkpoint", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + } + ], + "name": "delegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "delegateBySig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "delegates", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getPastTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getPastVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "numCheckpoints", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "fromDelegate", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "toDelegate", + "type": "address" + } + ], + "name": "DelegateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBalance", + "type": "uint256" + } + ], + "name": "DelegateVotesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L1Block.json b/packages/contracts-bedrock/snapshots/abi/L1Block.json new file mode 100644 index 000000000000..cb7b3029bfef --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L1Block.json @@ -0,0 +1,226 @@ +[ + { + "inputs": [], + "name": "DEPOSITOR_ACCOUNT", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseFeeScalar", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "basefee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "batcherHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blobBaseFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blobBaseFeeScalar", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1FeeOverhead", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1FeeScalar", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "number", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sequenceNumber", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_number", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "_timestamp", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "_basefee", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "_sequenceNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "_batcherHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l1FeeOverhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l1FeeScalar", + "type": "uint256" + } + ], + "name": "setL1BlockValues", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "setL1BlockValuesEcotone", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "timestamp", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L1BlockNumber.json b/packages/contracts-bedrock/snapshots/abi/L1BlockNumber.json new file mode 100644 index 000000000000..096067d25dfb --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L1BlockNumber.json @@ -0,0 +1,36 @@ +[ + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "getL1BlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L1ChugSplashProxy.json b/packages/contracts-bedrock/snapshots/abi/L1ChugSplashProxy.json new file mode 100644 index 000000000000..2c0bcacc48b1 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L1ChugSplashProxy.json @@ -0,0 +1,91 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "setCode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_key", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_value", + "type": "bytes32" + } + ], + "name": "setStorage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json b/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json new file mode 100644 index 000000000000..d330b13b802a --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L1CrossDomainMessenger.json @@ -0,0 +1,464 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "MESSAGE_VERSION", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_GAS_CALLDATA_OVERHEAD", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OTHER_MESSENGER", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PORTAL", + "outputs": [ + { + "internalType": "contract OptimismPortal", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELAY_CALL_OVERHEAD", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELAY_CONSTANT_OVERHEAD", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELAY_GAS_CHECK_BUFFER", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELAY_RESERVED_GAS", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + } + ], + "name": "baseGas", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "failedMessages", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract SuperchainConfig", + "name": "_superchainConfig", + "type": "address" + }, + { + "internalType": "contract OptimismPortal", + "name": "_portal", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "otherMessenger", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "portal", + "outputs": [ + { + "internalType": "contract OptimismPortal", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "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": "_minGasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + } + ], + "name": "relayMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + } + ], + "name": "sendMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "successfulMessages", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "superchainConfig", + "outputs": [ + { + "internalType": "contract SuperchainConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "xDomainMessageSender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + } + ], + "name": "FailedRelayedMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + } + ], + "name": "RelayedMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + } + ], + "name": "SentMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SentMessageExtension1", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json b/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json new file mode 100644 index 000000000000..296d95dd33e6 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L1ERC721Bridge.json @@ -0,0 +1,353 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "MESSENGER", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OTHER_BRIDGE", + "outputs": [ + { + "internalType": "contract StandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC721To", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "deposits", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeBridgeERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "_messenger", + "type": "address" + }, + { + "internalType": "contract SuperchainConfig", + "name": "_superchainConfig", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messenger", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "otherBridge", + "outputs": [ + { + "internalType": "contract StandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "superchainConfig", + "outputs": [ + { + "internalType": "contract SuperchainConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC721BridgeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC721BridgeInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L1FeeVault.json b/packages/contracts-bedrock/snapshots/abi/L1FeeVault.json new file mode 100644 index 000000000000..980f6f31551f --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L1FeeVault.json @@ -0,0 +1,155 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minWithdrawalAmount", + "type": "uint256" + }, + { + "internalType": "enum FeeVault.WithdrawalNetwork", + "name": "_withdrawalNetwork", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "MIN_WITHDRAWAL_AMOUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RECIPIENT", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WITHDRAWAL_NETWORK", + "outputs": [ + { + "internalType": "enum FeeVault.WithdrawalNetwork", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalProcessed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum FeeVault.WithdrawalNetwork", + "name": "withdrawalNetwork", + "type": "uint8" + } + ], + "name": "Withdrawal", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json b/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json new file mode 100644 index 000000000000..ab658ac7e5b2 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L1StandardBridge.json @@ -0,0 +1,822 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "MESSENGER", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OTHER_BRIDGE", + "outputs": [ + { + "internalType": "contract StandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC20To", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeETHTo", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "depositERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "depositERC20To", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "depositETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "depositETHTo", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "deposits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeBridgeERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeBridgeETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeERC20Withdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeETHWithdrawal", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "_messenger", + "type": "address" + }, + { + "internalType": "contract SuperchainConfig", + "name": "_superchainConfig", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l2TokenBridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messenger", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "otherBridge", + "outputs": [ + { + "internalType": "contract StandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "superchainConfig", + "outputs": [ + { + "internalType": "contract SuperchainConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20BridgeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20BridgeInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20DepositInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20WithdrawalFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHBridgeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHBridgeInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHDepositInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHWithdrawalFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L2CrossDomainMessenger.json b/packages/contracts-bedrock/snapshots/abi/L2CrossDomainMessenger.json new file mode 100644 index 000000000000..717bbb6eb6f4 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L2CrossDomainMessenger.json @@ -0,0 +1,433 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "MESSAGE_VERSION", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_GAS_CALLDATA_OVERHEAD", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OTHER_MESSENGER", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELAY_CALL_OVERHEAD", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELAY_CONSTANT_OVERHEAD", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELAY_GAS_CHECK_BUFFER", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RELAY_RESERVED_GAS", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + } + ], + "name": "baseGas", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "failedMessages", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "_l1CrossDomainMessenger", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l1CrossDomainMessenger", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messageNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "otherMessenger", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "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": "_minGasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + } + ], + "name": "relayMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + } + ], + "name": "sendMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "successfulMessages", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "xDomainMessageSender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + } + ], + "name": "FailedRelayedMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + } + ], + "name": "RelayedMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + } + ], + "name": "SentMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SentMessageExtension1", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L2ERC721Bridge.json b/packages/contracts-bedrock/snapshots/abi/L2ERC721Bridge.json new file mode 100644 index 000000000000..e9ae576e943a --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L2ERC721Bridge.json @@ -0,0 +1,306 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "MESSENGER", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OTHER_BRIDGE", + "outputs": [ + { + "internalType": "contract StandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC721To", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeBridgeERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_l1ERC721Bridge", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messenger", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "otherBridge", + "outputs": [ + { + "internalType": "contract StandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC721BridgeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC721BridgeInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L2OutputOracle.json b/packages/contracts-bedrock/snapshots/abi/L2OutputOracle.json new file mode 100644 index 000000000000..d34dd4df0b19 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L2OutputOracle.json @@ -0,0 +1,485 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CHALLENGER", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FINALIZATION_PERIOD_SECONDS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "L2_BLOCK_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROPOSER", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SUBMISSION_INTERVAL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "challenger", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BlockNumber", + "type": "uint256" + } + ], + "name": "computeL2Timestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2OutputIndex", + "type": "uint256" + } + ], + "name": "deleteL2Outputs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "finalizationPeriodSeconds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2OutputIndex", + "type": "uint256" + } + ], + "name": "getL2Output", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "outputRoot", + "type": "bytes32" + }, + { + "internalType": "uint128", + "name": "timestamp", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "l2BlockNumber", + "type": "uint128" + } + ], + "internalType": "struct Types.OutputProposal", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BlockNumber", + "type": "uint256" + } + ], + "name": "getL2OutputAfter", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "outputRoot", + "type": "bytes32" + }, + { + "internalType": "uint128", + "name": "timestamp", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "l2BlockNumber", + "type": "uint128" + } + ], + "internalType": "struct Types.OutputProposal", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BlockNumber", + "type": "uint256" + } + ], + "name": "getL2OutputIndexAfter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_submissionInterval", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2BlockTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startingBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startingTimestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_proposer", + "type": "address" + }, + { + "internalType": "address", + "name": "_challenger", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_finalizationPeriodSeconds", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l2BlockTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestOutputIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextOutputIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_outputRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l2BlockNumber", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l1BlockHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l1BlockNumber", + "type": "uint256" + } + ], + "name": "proposeL2Output", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "proposer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startingBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startingTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "submissionInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "outputRoot", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "l2OutputIndex", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "l2BlockNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "l1Timestamp", + "type": "uint256" + } + ], + "name": "OutputProposed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "prevNextOutputIndex", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "newNextOutputIndex", + "type": "uint256" + } + ], + "name": "OutputsDeleted", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L2StandardBridge.json b/packages/contracts-bedrock/snapshots/abi/L2StandardBridge.json new file mode 100644 index 000000000000..74a2ae477d98 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L2StandardBridge.json @@ -0,0 +1,663 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "MESSENGER", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OTHER_BRIDGE", + "outputs": [ + { + "internalType": "contract StandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC20To", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeETHTo", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "deposits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeBridgeERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeBridgeETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeDeposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract StandardBridge", + "name": "_otherBridge", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l1TokenBridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messenger", + "outputs": [ + { + "internalType": "contract CrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "otherBridge", + "outputs": [ + { + "internalType": "contract StandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "withdrawTo", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "DepositFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20BridgeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20BridgeInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHBridgeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHBridgeInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "WithdrawalInitiated", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json b/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json new file mode 100644 index 000000000000..77e1cf7596b3 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json @@ -0,0 +1,156 @@ +[ + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "MESSAGE_VERSION", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_gasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "initiateWithdrawal", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "messageNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "sentMessages", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "withdrawalHash", + "type": "bytes32" + } + ], + "name": "MessagePassed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawerBalanceBurnt", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/LegacyERC20ETH.json b/packages/contracts-bedrock/snapshots/abi/LegacyERC20ETH.json new file mode 100644 index 000000000000..f46b0f3acc32 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/LegacyERC20ETH.json @@ -0,0 +1,461 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BRIDGE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REMOTE_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_who", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l1Token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2Bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "remoteToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Mint", + "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": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/LegacyFaultDisputeGame.json b/packages/contracts-bedrock/snapshots/abi/LegacyFaultDisputeGame.json new file mode 100644 index 000000000000..f6090b4efff5 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/LegacyFaultDisputeGame.json @@ -0,0 +1,617 @@ +[ + { + "inputs": [ + { + "internalType": "GameType", + "name": "_gameType", + "type": "uint8" + }, + { + "internalType": "Claim", + "name": "_absolutePrestate", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_maxGameDepth", + "type": "uint256" + }, + { + "internalType": "Duration", + "name": "_gameDuration", + "type": "uint64" + }, + { + "internalType": "contract IBigStepper", + "name": "_vm", + "type": "address" + }, + { + "internalType": "contract L2OutputOracle", + "name": "_l2oo", + "type": "address" + }, + { + "internalType": "contract BlockOracle", + "name": "_blockOracle", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ABSOLUTE_PRESTATE", + "outputs": [ + { + "internalType": "Claim", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BLOCK_ORACLE", + "outputs": [ + { + "internalType": "contract BlockOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GAME_DURATION", + "outputs": [ + { + "internalType": "Duration", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "L2_OUTPUT_ORACLE", + "outputs": [ + { + "internalType": "contract L2OutputOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_GAME_DEPTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VM", + "outputs": [ + { + "internalType": "contract IBigStepper", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_ident", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_localContext", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_partOffset", + "type": "uint256" + } + ], + "name": "addLocalData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_parentIndex", + "type": "uint256" + }, + { + "internalType": "Claim", + "name": "_claim", + "type": "bytes32" + } + ], + "name": "attack", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "claimData", + "outputs": [ + { + "internalType": "uint32", + "name": "parentIndex", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "countered", + "type": "bool" + }, + { + "internalType": "Claim", + "name": "claim", + "type": "bytes32" + }, + { + "internalType": "Position", + "name": "position", + "type": "uint128" + }, + { + "internalType": "Clock", + "name": "clock", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimDataLen", + "outputs": [ + { + "internalType": "uint256", + "name": "len_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "createdAt", + "outputs": [ + { + "internalType": "Timestamp", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_parentIndex", + "type": "uint256" + }, + { + "internalType": "Claim", + "name": "_claim", + "type": "bytes32" + } + ], + "name": "defend", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "extraData", + "outputs": [ + { + "internalType": "bytes", + "name": "extraData_", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "gameData", + "outputs": [ + { + "internalType": "GameType", + "name": "gameType_", + "type": "uint8" + }, + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "extraData_", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gameType", + "outputs": [ + { + "internalType": "GameType", + "name": "gameType_", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l1BlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "l1BlockNumber_", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "l1Head", + "outputs": [ + { + "internalType": "Hash", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2BlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "l2BlockNumber_", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_challengeIndex", + "type": "uint256" + }, + { + "internalType": "Claim", + "name": "_claim", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "_isAttack", + "type": "bool" + } + ], + "name": "move", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "proposals", + "outputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "index", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "l2BlockNumber", + "type": "uint128" + }, + { + "internalType": "Hash", + "name": "outputRoot", + "type": "bytes32" + } + ], + "internalType": "struct ILegacyFaultDisputeGame.OutputProposal", + "name": "starting", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint128", + "name": "index", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "l2BlockNumber", + "type": "uint128" + }, + { + "internalType": "Hash", + "name": "outputRoot", + "type": "bytes32" + } + ], + "internalType": "struct ILegacyFaultDisputeGame.OutputProposal", + "name": "disputed", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "resolve", + "outputs": [ + { + "internalType": "enum GameStatus", + "name": "status_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_claimIndex", + "type": "uint256" + } + ], + "name": "resolveClaim", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "rootClaim", + "outputs": [ + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "status", + "outputs": [ + { + "internalType": "enum GameStatus", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_claimIndex", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isAttack", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_stateData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + } + ], + "name": "step", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "parentIndex", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "Claim", + "name": "claim", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "claimant", + "type": "address" + } + ], + "name": "Move", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "enum GameStatus", + "name": "status", + "type": "uint8" + } + ], + "name": "Resolved", + "type": "event" + }, + { + "inputs": [], + "name": "CannotDefendRootClaim", + "type": "error" + }, + { + "inputs": [], + "name": "ClaimAlreadyExists", + "type": "error" + }, + { + "inputs": [], + "name": "ClaimAlreadyResolved", + "type": "error" + }, + { + "inputs": [], + "name": "ClockNotExpired", + "type": "error" + }, + { + "inputs": [], + "name": "ClockTimeExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "GameDepthExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "GameNotInProgress", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidParent", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPrestate", + "type": "error" + }, + { + "inputs": [], + "name": "L1HeadTooOld", + "type": "error" + }, + { + "inputs": [], + "name": "OutOfOrderResolution", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Claim", + "name": "rootClaim", + "type": "bytes32" + } + ], + "name": "UnexpectedRootClaim", + "type": "error" + }, + { + "inputs": [], + "name": "ValidStep", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/LegacyMessagePasser.json b/packages/contracts-bedrock/snapshots/abi/LegacyMessagePasser.json new file mode 100644 index 000000000000..538cadb51569 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/LegacyMessagePasser.json @@ -0,0 +1,47 @@ +[ + { + "inputs": [ + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + } + ], + "name": "passMessageToL1", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "sentMessages", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/LegacyMintableERC20.json b/packages/contracts-bedrock/snapshots/abi/LegacyMintableERC20.json new file mode 100644 index 000000000000..e8d182cae46e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/LegacyMintableERC20.json @@ -0,0 +1,417 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_l2Bridge", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l1Token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2Bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Mint", + "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": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/LivenessGuard.json b/packages/contracts-bedrock/snapshots/abi/LivenessGuard.json new file mode 100644 index 000000000000..e058e21c6b06 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/LivenessGuard.json @@ -0,0 +1,178 @@ +[ + { + "inputs": [ + { + "internalType": "contract Safe", + "name": "_safe", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "checkAfterExecution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "enum Enum.Operation", + "name": "operation", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "safeTxGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gasToken", + "type": "address" + }, + { + "internalType": "address payable", + "name": "refundReceiver", + "type": "address" + }, + { + "internalType": "bytes", + "name": "signatures", + "type": "bytes" + }, + { + "internalType": "address", + "name": "msgSender", + "type": "address" + } + ], + "name": "checkTransaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastLive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "safe", + "outputs": [ + { + "internalType": "contract Safe", + "name": "safe_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "showLiveness", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnerRecorded", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/LivenessModule.json b/packages/contracts-bedrock/snapshots/abi/LivenessModule.json new file mode 100644 index 000000000000..48712a307580 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/LivenessModule.json @@ -0,0 +1,167 @@ +[ + { + "inputs": [ + { + "internalType": "contract Safe", + "name": "_safe", + "type": "address" + }, + { + "internalType": "contract LivenessGuard", + "name": "_livenessGuard", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_livenessInterval", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minOwners", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_fallbackOwner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "canRemove", + "outputs": [ + { + "internalType": "bool", + "name": "canRemove_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fallbackOwner", + "outputs": [ + { + "internalType": "address", + "name": "fallbackOwner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_numOwners", + "type": "uint256" + } + ], + "name": "get75PercentThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "threshold_", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "livenessGuard", + "outputs": [ + { + "internalType": "contract LivenessGuard", + "name": "livenessGuard_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "livenessInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "livenessInterval_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minOwners", + "outputs": [ + { + "internalType": "uint256", + "name": "minOwners_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_previousOwners", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "_ownersToRemove", + "type": "address[]" + } + ], + "name": "removeOwners", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "safe", + "outputs": [ + { + "internalType": "contract Safe", + "name": "safe_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/MIPS.json b/packages/contracts-bedrock/snapshots/abi/MIPS.json new file mode 100644 index 000000000000..e4760d16fc5a --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/MIPS.json @@ -0,0 +1,81 @@ +[ + { + "inputs": [ + { + "internalType": "contract IPreimageOracle", + "name": "_oracle", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BRK_START", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract IPreimageOracle", + "name": "oracle_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_stateData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "_localContext", + "type": "bytes32" + } + ], + "name": "step", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/MintManager.json b/packages/contracts-bedrock/snapshots/abi/MintManager.json new file mode 100644 index 000000000000..36afd1e16719 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/MintManager.json @@ -0,0 +1,166 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_upgrader", + "type": "address" + }, + { + "internalType": "address", + "name": "_governanceToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINT_CAP", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINT_PERIOD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governanceToken", + "outputs": [ + { + "internalType": "contract GovernanceToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mintPermittedAfter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newMintManager", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC20.json b/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC20.json new file mode 100644 index 000000000000..3c6f5e9ab348 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC20.json @@ -0,0 +1,487 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_bridge", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BRIDGE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REMOTE_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l1Token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2Bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "remoteToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Mint", + "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": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC20Factory.json b/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC20Factory.json new file mode 100644 index 000000000000..3f2f14fcbe59 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC20Factory.json @@ -0,0 +1,208 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BRIDGE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "name": "createOptimismMintableERC20", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + } + ], + "name": "createOptimismMintableERC20WithDecimals", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "name": "createStandardL2Token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bridge", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "deployer", + "type": "address" + } + ], + "name": "OptimismMintableERC20Created", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + } + ], + "name": "StandardL2TokenCreated", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC721.json b/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC721.json new file mode 100644 index 000000000000..35250255a9ba --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC721.json @@ -0,0 +1,597 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_bridge", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_remoteChainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BRIDGE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REMOTE_CHAIN_ID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REMOTE_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseTokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "remoteChainId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "remoteToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "safeMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC721Factory.json b/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC721Factory.json new file mode 100644 index 000000000000..14a23db1be69 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OptimismMintableERC721Factory.json @@ -0,0 +1,130 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_bridge", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_remoteChainId", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BRIDGE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REMOTE_CHAIN_ID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "name": "createOptimismMintableERC721", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isOptimismMintableERC721", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "deployer", + "type": "address" + } + ], + "name": "OptimismMintableERC721Created", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json new file mode 100644 index 000000000000..538733986580 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortal.json @@ -0,0 +1,528 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "GUARDIAN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "L2_ORACLE", + "outputs": [ + { + "internalType": "contract L2OutputOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SYSTEM_CONFIG", + "outputs": [ + { + "internalType": "contract SystemConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "_gasLimit", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "_isCreation", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "depositTransaction", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "donateETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct Types.WithdrawalTransaction", + "name": "_tx", + "type": "tuple" + } + ], + "name": "finalizeWithdrawalTransaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "finalizedWithdrawals", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "guardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract L2OutputOracle", + "name": "_l2Oracle", + "type": "address" + }, + { + "internalType": "contract SystemConfig", + "name": "_systemConfig", + "type": "address" + }, + { + "internalType": "contract SuperchainConfig", + "name": "_superchainConfig", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2OutputIndex", + "type": "uint256" + } + ], + "name": "isOutputFinalized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2Oracle", + "outputs": [ + { + "internalType": "contract L2OutputOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2Sender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_byteCount", + "type": "uint64" + } + ], + "name": "minimumGasLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "params", + "outputs": [ + { + "internalType": "uint128", + "name": "prevBaseFee", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "prevBoughtGas", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "prevBlockNum", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "paused_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct Types.WithdrawalTransaction", + "name": "_tx", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "_l2OutputIndex", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "version", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "stateRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "messagePasserStorageRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "latestBlockhash", + "type": "bytes32" + } + ], + "internalType": "struct Types.OutputRootProof", + "name": "_outputRootProof", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "_withdrawalProof", + "type": "bytes[]" + } + ], + "name": "proveWithdrawalTransaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "provenWithdrawals", + "outputs": [ + { + "internalType": "bytes32", + "name": "outputRoot", + "type": "bytes32" + }, + { + "internalType": "uint128", + "name": "timestamp", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "l2OutputIndex", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "superchainConfig", + "outputs": [ + { + "internalType": "contract SuperchainConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "systemConfig", + "outputs": [ + { + "internalType": "contract SystemConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "opaqueData", + "type": "bytes" + } + ], + "name": "TransactionDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "withdrawalHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "name": "WithdrawalFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "withdrawalHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "WithdrawalProven", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json new file mode 100644 index 000000000000..4f3c67ebd4a1 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json @@ -0,0 +1,617 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_proofMaturityDelaySeconds", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_disputeGameFinalityDelaySeconds", + "type": "uint256" + }, + { + "internalType": "GameType", + "name": "_initialRespectedGameType", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "GUARDIAN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SYSTEM_CONFIG", + "outputs": [ + { + "internalType": "contract SystemConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IDisputeGame", + "name": "_disputeGame", + "type": "address" + } + ], + "name": "blacklistDisputeGame", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_withdrawalHash", + "type": "bytes32" + } + ], + "name": "checkWithdrawal", + "outputs": [], + "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": "contract IDisputeGame", + "name": "", + "type": "address" + } + ], + "name": "disputeGameBlacklist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disputeGameFactory", + "outputs": [ + { + "internalType": "contract DisputeGameFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disputeGameFinalityDelaySeconds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "donateETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct Types.WithdrawalTransaction", + "name": "_tx", + "type": "tuple" + } + ], + "name": "finalizeWithdrawalTransaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "finalizedWithdrawals", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "guardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract DisputeGameFactory", + "name": "_disputeGameFactory", + "type": "address" + }, + { + "internalType": "contract SystemConfig", + "name": "_systemConfig", + "type": "address" + }, + { + "internalType": "contract SuperchainConfig", + "name": "_superchainConfig", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l2Sender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_byteCount", + "type": "uint64" + } + ], + "name": "minimumGasLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "params", + "outputs": [ + { + "internalType": "uint128", + "name": "prevBaseFee", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "prevBoughtGas", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "prevBlockNum", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proofMaturityDelaySeconds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct Types.WithdrawalTransaction", + "name": "_tx", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "_disputeGameIndex", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "version", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "stateRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "messagePasserStorageRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "latestBlockhash", + "type": "bytes32" + } + ], + "internalType": "struct Types.OutputRootProof", + "name": "_outputRootProof", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "_withdrawalProof", + "type": "bytes[]" + } + ], + "name": "proveWithdrawalTransaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "provenWithdrawals", + "outputs": [ + { + "internalType": "contract IDisputeGame", + "name": "disputeGameProxy", + "type": "address" + }, + { + "internalType": "uint64", + "name": "timestamp", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "respectedGameType", + "outputs": [ + { + "internalType": "GameType", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "respectedGameTypeUpdatedAt", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "GameType", + "name": "_gameType", + "type": "uint32" + } + ], + "name": "setRespectedGameType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "superchainConfig", + "outputs": [ + { + "internalType": "contract SuperchainConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "systemConfig", + "outputs": [ + { + "internalType": "contract SystemConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "opaqueData", + "type": "bytes" + } + ], + "name": "TransactionDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "withdrawalHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "name": "WithdrawalFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "withdrawalHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "WithdrawalProven", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/Optimist.json b/packages/contracts-bedrock/snapshots/abi/Optimist.json new file mode 100644 index 000000000000..96bbc0591a30 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/Optimist.json @@ -0,0 +1,536 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "address", + "name": "_baseURIAttestor", + "type": "address" + }, + { + "internalType": "contract AttestationStation", + "name": "_attestationStation", + "type": "address" + }, + { + "internalType": "contract OptimistAllowlist", + "name": "_optimistAllowlist", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ATTESTATION_STATION", + "outputs": [ + { + "internalType": "contract AttestationStation", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BASE_URI_ATTESTATION_KEY", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BASE_URI_ATTESTOR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OPTIMIST_ALLOWLIST", + "outputs": [ + { + "internalType": "contract OptimistAllowlist", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseURI", + "outputs": [ + { + "internalType": "string", + "name": "uri_", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "isOnAllowList", + "outputs": [ + { + "internalType": "bool", + "name": "allowed_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "tokenIdOfAddress", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "uri_", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimistAllowlist.json b/packages/contracts-bedrock/snapshots/abi/OptimistAllowlist.json new file mode 100644 index 000000000000..87ac8f8a014f --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OptimistAllowlist.json @@ -0,0 +1,138 @@ +[ + { + "inputs": [ + { + "internalType": "contract AttestationStation", + "name": "_attestationStation", + "type": "address" + }, + { + "internalType": "address", + "name": "_allowlistAttestor", + "type": "address" + }, + { + "internalType": "address", + "name": "_coinbaseQuestAttestor", + "type": "address" + }, + { + "internalType": "address", + "name": "_optimistInviter", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ALLOWLIST_ATTESTOR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ATTESTATION_STATION", + "outputs": [ + { + "internalType": "contract AttestationStation", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "COINBASE_QUEST_ATTESTOR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "COINBASE_QUEST_ELIGIBLE_ATTESTATION_KEY", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OPTIMIST_CAN_MINT_ATTESTATION_KEY", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OPTIMIST_INVITER", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_claimer", + "type": "address" + } + ], + "name": "isAllowedToMint", + "outputs": [ + { + "internalType": "bool", + "name": "allowed_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimistInviter.json b/packages/contracts-bedrock/snapshots/abi/OptimistInviter.json new file mode 100644 index 000000000000..a5300b20a3c1 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/OptimistInviter.json @@ -0,0 +1,282 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_inviteGranter", + "type": "address" + }, + { + "internalType": "contract AttestationStation", + "name": "_attestationStation", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ATTESTATION_STATION", + "outputs": [ + { + "internalType": "contract AttestationStation", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CAN_INVITE_ATTESTATION_KEY", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CLAIMABLE_INVITE_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EIP712_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INVITE_GRANTER", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_COMMITMENT_PERIOD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_claimer", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "issuer", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "nonce", + "type": "bytes32" + } + ], + "internalType": "struct OptimistInviter.ClaimableInvite", + "name": "_claimableInvite", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "claimInvite", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_commitment", + "type": "bytes32" + } + ], + "name": "commitInvite", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "commitmentTimestamps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "inviteCounts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_accounts", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "_inviteCount", + "type": "uint256" + } + ], + "name": "setInviteCounts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "usedNonces", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "issuer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "claimer", + "type": "address" + } + ], + "name": "InviteClaimed", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGame.json b/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGame.json new file mode 100644 index 000000000000..5f804d69ca77 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/PermissionedDisputeGame.json @@ -0,0 +1,769 @@ +[ + { + "inputs": [ + { + "internalType": "GameType", + "name": "_gameType", + "type": "uint32" + }, + { + "internalType": "Claim", + "name": "_absolutePrestate", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_maxGameDepth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_splitDepth", + "type": "uint256" + }, + { + "internalType": "Duration", + "name": "_gameDuration", + "type": "uint64" + }, + { + "internalType": "contract IBigStepper", + "name": "_vm", + "type": "address" + }, + { + "internalType": "contract IDelayedWETH", + "name": "_weth", + "type": "address" + }, + { + "internalType": "contract IAnchorStateRegistry", + "name": "_anchorStateRegistry", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_l2ChainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_proposer", + "type": "address" + }, + { + "internalType": "address", + "name": "_challenger", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "absolutePrestate", + "outputs": [ + { + "internalType": "Claim", + "name": "absolutePrestate_", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_ident", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_execLeafIdx", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_partOffset", + "type": "uint256" + } + ], + "name": "addLocalData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_parentIndex", + "type": "uint256" + }, + { + "internalType": "Claim", + "name": "_claim", + "type": "bytes32" + } + ], + "name": "attack", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "claimCredit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "claimData", + "outputs": [ + { + "internalType": "uint32", + "name": "parentIndex", + "type": "uint32" + }, + { + "internalType": "address", + "name": "counteredBy", + "type": "address" + }, + { + "internalType": "address", + "name": "claimant", + "type": "address" + }, + { + "internalType": "uint128", + "name": "bond", + "type": "uint128" + }, + { + "internalType": "Claim", + "name": "claim", + "type": "bytes32" + }, + { + "internalType": "Position", + "name": "position", + "type": "uint128" + }, + { + "internalType": "Clock", + "name": "clock", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimDataLen", + "outputs": [ + { + "internalType": "uint256", + "name": "len_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimedBondFlag", + "outputs": [ + { + "internalType": "uint128", + "name": "claimedBondFlag_", + "type": "uint128" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "createdAt", + "outputs": [ + { + "internalType": "Timestamp", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "credit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_parentIndex", + "type": "uint256" + }, + { + "internalType": "Claim", + "name": "_claim", + "type": "bytes32" + } + ], + "name": "defend", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "extraData", + "outputs": [ + { + "internalType": "bytes", + "name": "extraData_", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "gameData", + "outputs": [ + { + "internalType": "GameType", + "name": "gameType_", + "type": "uint32" + }, + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "extraData_", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gameDuration", + "outputs": [ + { + "internalType": "Duration", + "name": "gameDuration_", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gameType", + "outputs": [ + { + "internalType": "GameType", + "name": "gameType_", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "Position", + "name": "_position", + "type": "uint128" + } + ], + "name": "getRequiredBond", + "outputs": [ + { + "internalType": "uint256", + "name": "requiredBond_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "l1Head", + "outputs": [ + { + "internalType": "Hash", + "name": "l1Head_", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "l2BlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "l2BlockNumber_", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "l2ChainId", + "outputs": [ + { + "internalType": "uint256", + "name": "l2ChainId_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxGameDepth", + "outputs": [ + { + "internalType": "uint256", + "name": "maxGameDepth_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_challengeIndex", + "type": "uint256" + }, + { + "internalType": "Claim", + "name": "_claim", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "_isAttack", + "type": "bool" + } + ], + "name": "move", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "resolve", + "outputs": [ + { + "internalType": "enum GameStatus", + "name": "status_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_claimIndex", + "type": "uint256" + } + ], + "name": "resolveClaim", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "resolvedAt", + "outputs": [ + { + "internalType": "Timestamp", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rootClaim", + "outputs": [ + { + "internalType": "Claim", + "name": "rootClaim_", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "splitDepth", + "outputs": [ + { + "internalType": "uint256", + "name": "splitDepth_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startingBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "startingBlockNumber_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startingOutputRoot", + "outputs": [ + { + "internalType": "Hash", + "name": "root", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "l2BlockNumber", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startingRootHash", + "outputs": [ + { + "internalType": "Hash", + "name": "startingRootHash_", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "status", + "outputs": [ + { + "internalType": "enum GameStatus", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_claimIndex", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isAttack", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_stateData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + } + ], + "name": "step", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vm", + "outputs": [ + { + "internalType": "contract IBigStepper", + "name": "vm_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "weth", + "outputs": [ + { + "internalType": "contract IDelayedWETH", + "name": "weth_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "parentIndex", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "Claim", + "name": "claim", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "claimant", + "type": "address" + } + ], + "name": "Move", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "enum GameStatus", + "name": "status", + "type": "uint8" + } + ], + "name": "Resolved", + "type": "event" + }, + { + "inputs": [], + "name": "AlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "AnchorRootNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "BadAuth", + "type": "error" + }, + { + "inputs": [], + "name": "BondTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "CannotDefendRootClaim", + "type": "error" + }, + { + "inputs": [], + "name": "ClaimAboveSplit", + "type": "error" + }, + { + "inputs": [], + "name": "ClaimAlreadyExists", + "type": "error" + }, + { + "inputs": [], + "name": "ClaimAlreadyResolved", + "type": "error" + }, + { + "inputs": [], + "name": "ClockNotExpired", + "type": "error" + }, + { + "inputs": [], + "name": "ClockTimeExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateStep", + "type": "error" + }, + { + "inputs": [], + "name": "GameDepthExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "GameNotInProgress", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientBond", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidLocalIdent", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidParent", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPrestate", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSplitDepth", + "type": "error" + }, + { + "inputs": [], + "name": "NoCreditToClaim", + "type": "error" + }, + { + "inputs": [], + "name": "OutOfOrderResolution", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Claim", + "name": "rootClaim", + "type": "bytes32" + } + ], + "name": "UnexpectedRootClaim", + "type": "error" + }, + { + "inputs": [], + "name": "ValidStep", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/PreimageOracle.json b/packages/contracts-bedrock/snapshots/abi/PreimageOracle.json new file mode 100644 index 000000000000..5ba83bc0b514 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/PreimageOracle.json @@ -0,0 +1,901 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minProposalSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_challengePeriod", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "KECCAK_TREE_DEPTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_LEAF_COUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_BOND_SIZE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_uuid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_inputStartBlock", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_input", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_stateCommitments", + "type": "bytes32[]" + }, + { + "internalType": "bool", + "name": "_finalize", + "type": "bool" + } + ], + "name": "addLeavesLPP", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_claimant", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_uuid", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "input", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "stateCommitment", + "type": "bytes32" + } + ], + "internalType": "struct PreimageOracle.Leaf", + "name": "_postState", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_postStateProof", + "type": "bytes32[]" + } + ], + "name": "challengeFirstLPP", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_claimant", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_uuid", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint64[25]", + "name": "state", + "type": "uint64[25]" + } + ], + "internalType": "struct LibKeccak.StateMatrix", + "name": "_stateMatrix", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "input", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "stateCommitment", + "type": "bytes32" + } + ], + "internalType": "struct PreimageOracle.Leaf", + "name": "_preState", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_preStateProof", + "type": "bytes32[]" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "input", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "stateCommitment", + "type": "bytes32" + } + ], + "internalType": "struct PreimageOracle.Leaf", + "name": "_postState", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_postStateProof", + "type": "bytes32[]" + } + ], + "name": "challengeLPP", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "challengePeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "challengePeriod_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_uuid", + "type": "uint256" + } + ], + "name": "getTreeRootLPP", + "outputs": [ + { + "internalType": "bytes32", + "name": "treeRoot_", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_uuid", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_partOffset", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_claimedSize", + "type": "uint32" + } + ], + "name": "initLPP", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_z", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_y", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_commitment", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_partOffset", + "type": "uint256" + } + ], + "name": "loadBlobPreimagePart", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_partOffset", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_preimage", + "type": "bytes" + } + ], + "name": "loadKeccak256PreimagePart", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_ident", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_localContext", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_word", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_size", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_partOffset", + "type": "uint256" + } + ], + "name": "loadLocalData", + "outputs": [ + { + "internalType": "bytes32", + "name": "key_", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_partOffset", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_precompile", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_input", + "type": "bytes" + } + ], + "name": "loadPrecompilePreimagePart", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_partOffset", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_preimage", + "type": "bytes" + } + ], + "name": "loadSha256PreimagePart", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minProposalSize", + "outputs": [ + { + "internalType": "uint256", + "name": "minProposalSize_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "preimageLengths", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "preimagePartOk", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "preimageParts", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "proposalBlocks", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_claimant", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_uuid", + "type": "uint256" + } + ], + "name": "proposalBlocksLen", + "outputs": [ + { + "internalType": "uint256", + "name": "len_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "proposalBonds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "proposalBranches", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proposalCount", + "outputs": [ + { + "internalType": "uint256", + "name": "count_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "proposalMetadata", + "outputs": [ + { + "internalType": "LPPMetaData", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "proposalParts", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "proposals", + "outputs": [ + { + "internalType": "address", + "name": "claimant", + "type": "address" + }, + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_key", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_offset", + "type": "uint256" + } + ], + "name": "readPreimage", + "outputs": [ + { + "internalType": "bytes32", + "name": "dat_", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "datLen_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_claimant", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_uuid", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint64[25]", + "name": "state", + "type": "uint64[25]" + } + ], + "internalType": "struct LibKeccak.StateMatrix", + "name": "_stateMatrix", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "input", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "stateCommitment", + "type": "bytes32" + } + ], + "internalType": "struct PreimageOracle.Leaf", + "name": "_preState", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_preStateProof", + "type": "bytes32[]" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "input", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "stateCommitment", + "type": "bytes32" + } + ], + "internalType": "struct PreimageOracle.Leaf", + "name": "_postState", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_postStateProof", + "type": "bytes32[]" + } + ], + "name": "squeezeLPP", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "zeroHashes", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ActiveProposal", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyFinalized", + "type": "error" + }, + { + "inputs": [], + "name": "BadProposal", + "type": "error" + }, + { + "inputs": [], + "name": "BondTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientBond", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInputSize", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPreimage", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidProof", + "type": "error" + }, + { + "inputs": [], + "name": "NotEOA", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "PartOffsetOOB", + "type": "error" + }, + { + "inputs": [], + "name": "PostStateMatches", + "type": "error" + }, + { + "inputs": [], + "name": "StatesNotContiguous", + "type": "error" + }, + { + "inputs": [], + "name": "TreeSizeOverflow", + "type": "error" + }, + { + "inputs": [], + "name": "WrongStartingBlock", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/ProtocolVersions.json b/packages/contracts-bedrock/snapshots/abi/ProtocolVersions.json new file mode 100644 index 000000000000..d19e991df73b --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/ProtocolVersions.json @@ -0,0 +1,224 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "RECOMMENDED_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REQUIRED_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "ProtocolVersion", + "name": "_required", + "type": "uint256" + }, + { + "internalType": "ProtocolVersion", + "name": "_recommended", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "recommended", + "outputs": [ + { + "internalType": "ProtocolVersion", + "name": "out_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "required", + "outputs": [ + { + "internalType": "ProtocolVersion", + "name": "out_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "ProtocolVersion", + "name": "_recommended", + "type": "uint256" + } + ], + "name": "setRecommended", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "ProtocolVersion", + "name": "_required", + "type": "uint256" + } + ], + "name": "setRequired", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "enum ProtocolVersions.UpdateType", + "name": "updateType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "ConfigUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/Proxy.json b/packages/contracts-bedrock/snapshots/abi/Proxy.json new file mode 100644 index 000000000000..25ce23e3ed11 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/Proxy.json @@ -0,0 +1,129 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/ProxyAdmin.json b/packages/contracts-bedrock/snapshots/abi/ProxyAdmin.json new file mode 100644 index 000000000000..fbf37d51b40d --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/ProxyAdmin.json @@ -0,0 +1,306 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "addressManager", + "outputs": [ + { + "internalType": "contract AddressManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "_newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "implementationName", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isUpgrading", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "proxyType", + "outputs": [ + { + "internalType": "enum ProxyAdmin.ProxyType", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "setAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AddressManager", + "name": "_address", + "type": "address" + } + ], + "name": "setAddressManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "name": "setImplementationName", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "enum ProxyAdmin.ProxyType", + "name": "_type", + "type": "uint8" + } + ], + "name": "setProxyType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_upgrading", + "type": "bool" + } + ], + "name": "setUpgrading", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "_implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/ResolvedDelegateProxy.json b/packages/contracts-bedrock/snapshots/abi/ResolvedDelegateProxy.json new file mode 100644 index 000000000000..a659be953a95 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/ResolvedDelegateProxy.json @@ -0,0 +1,22 @@ +[ + { + "inputs": [ + { + "internalType": "contract AddressManager", + "name": "_addressManager", + "type": "address" + }, + { + "internalType": "string", + "name": "_implementationName", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/SafeSend.json b/packages/contracts-bedrock/snapshots/abi/SafeSend.json new file mode 100644 index 000000000000..aeeca5ed29dd --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/SafeSend.json @@ -0,0 +1,13 @@ +[ + { + "inputs": [ + { + "internalType": "address payable", + "name": "_recipient", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/SchemaRegistry.json b/packages/contracts-bedrock/snapshots/abi/SchemaRegistry.json new file mode 100644 index 000000000000..645c4ecb5e2b --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/SchemaRegistry.json @@ -0,0 +1,137 @@ +[ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + } + ], + "name": "getSchema", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "contract ISchemaResolver", + "name": "resolver", + "type": "address" + }, + { + "internalType": "bool", + "name": "revocable", + "type": "bool" + }, + { + "internalType": "string", + "name": "schema", + "type": "string" + } + ], + "internalType": "struct SchemaRecord", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schema", + "type": "string" + }, + { + "internalType": "contract ISchemaResolver", + "name": "resolver", + "type": "address" + }, + { + "internalType": "bool", + "name": "revocable", + "type": "bool" + } + ], + "name": "register", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "registerer", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + }, + { + "internalType": "contract ISchemaResolver", + "name": "resolver", + "type": "address" + }, + { + "internalType": "bool", + "name": "revocable", + "type": "bool" + }, + { + "internalType": "string", + "name": "schema", + "type": "string" + } + ], + "indexed": false, + "internalType": "struct SchemaRecord", + "name": "schema", + "type": "tuple" + } + ], + "name": "Registered", + "type": "event" + }, + { + "inputs": [], + "name": "AlreadyExists", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/SequencerFeeVault.json b/packages/contracts-bedrock/snapshots/abi/SequencerFeeVault.json new file mode 100644 index 000000000000..568a041b3cc8 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/SequencerFeeVault.json @@ -0,0 +1,168 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minWithdrawalAmount", + "type": "uint256" + }, + { + "internalType": "enum FeeVault.WithdrawalNetwork", + "name": "_withdrawalNetwork", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "MIN_WITHDRAWAL_AMOUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RECIPIENT", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WITHDRAWAL_NETWORK", + "outputs": [ + { + "internalType": "enum FeeVault.WithdrawalNetwork", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1FeeWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalProcessed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum FeeVault.WithdrawalNetwork", + "name": "withdrawalNetwork", + "type": "uint8" + } + ], + "name": "Withdrawal", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/StorageSetter.json b/packages/contracts-bedrock/snapshots/abi/StorageSetter.json new file mode 100644 index 000000000000..22896246e141 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/StorageSetter.json @@ -0,0 +1,188 @@ +[ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + } + ], + "name": "getBool", + "outputs": [ + { + "internalType": "bool", + "name": "value_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + } + ], + "name": "getBytes32", + "outputs": [ + { + "internalType": "bytes32", + "name": "value_", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + } + ], + "name": "getUint", + "outputs": [ + { + "internalType": "uint256", + "name": "value_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "setAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "_value", + "type": "bool" + } + ], + "name": "setBool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "value", + "type": "bytes32" + } + ], + "internalType": "struct StorageSetter.Slot[]", + "name": "slots", + "type": "tuple[]" + } + ], + "name": "setBytes32", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_value", + "type": "bytes32" + } + ], + "name": "setBytes32", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "setUint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/SuperchainConfig.json b/packages/contracts-bedrock/snapshots/abi/SuperchainConfig.json new file mode 100644 index 000000000000..0304f507eb50 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/SuperchainConfig.json @@ -0,0 +1,161 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "GUARDIAN_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSED_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "guardian", + "outputs": [ + { + "internalType": "address", + "name": "guardian_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_guardian", + "type": "address" + }, + { + "internalType": "bool", + "name": "_paused", + "type": "bool" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_identifier", + "type": "string" + } + ], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "paused_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "enum SuperchainConfig.UpdateType", + "name": "updateType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "ConfigUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "identifier", + "type": "string" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Unpaused", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/SystemConfig.json b/packages/contracts-bedrock/snapshots/abi/SystemConfig.json new file mode 100644 index 000000000000..eb334e29d26c --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/SystemConfig.json @@ -0,0 +1,686 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BATCH_INBOX_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "L1_CROSS_DOMAIN_MESSENGER_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "L1_ERC_721_BRIDGE_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "L1_STANDARD_BRIDGE_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "L2_OUTPUT_ORACLE_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OPTIMISM_PORTAL_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "START_BLOCK_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNSAFE_BLOCK_SIGNER_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "batchInbox", + "outputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "batcherHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_overhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_scalar", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_batcherHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "_gasLimit", + "type": "uint64" + }, + { + "internalType": "address", + "name": "_unsafeBlockSigner", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxResourceLimit", + "type": "uint32" + }, + { + "internalType": "uint8", + "name": "elasticityMultiplier", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "baseFeeMaxChangeDenominator", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "minimumBaseFee", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "systemTxMaxGas", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "maximumBaseFee", + "type": "uint128" + } + ], + "internalType": "struct ResourceMetering.ResourceConfig", + "name": "_config", + "type": "tuple" + }, + { + "internalType": "address", + "name": "_batchInbox", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "l1CrossDomainMessenger", + "type": "address" + }, + { + "internalType": "address", + "name": "l1ERC721Bridge", + "type": "address" + }, + { + "internalType": "address", + "name": "l1StandardBridge", + "type": "address" + }, + { + "internalType": "address", + "name": "l2OutputOracle", + "type": "address" + }, + { + "internalType": "address", + "name": "optimismPortal", + "type": "address" + }, + { + "internalType": "address", + "name": "optimismMintableERC20Factory", + "type": "address" + } + ], + "internalType": "struct SystemConfig.Addresses", + "name": "_addresses", + "type": "tuple" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l1CrossDomainMessenger", + "outputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1ERC721Bridge", + "outputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1StandardBridge", + "outputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2OutputOracle", + "outputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minimumGasLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "optimismMintableERC20Factory", + "outputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "optimismPortal", + "outputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "overhead", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resourceConfig", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "maxResourceLimit", + "type": "uint32" + }, + { + "internalType": "uint8", + "name": "elasticityMultiplier", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "baseFeeMaxChangeDenominator", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "minimumBaseFee", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "systemTxMaxGas", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "maximumBaseFee", + "type": "uint128" + } + ], + "internalType": "struct ResourceMetering.ResourceConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "scalar", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_batcherHash", + "type": "bytes32" + } + ], + "name": "setBatcherHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_overhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_scalar", + "type": "uint256" + } + ], + "name": "setGasConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_gasLimit", + "type": "uint64" + } + ], + "name": "setGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "maxResourceLimit", + "type": "uint32" + }, + { + "internalType": "uint8", + "name": "elasticityMultiplier", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "baseFeeMaxChangeDenominator", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "minimumBaseFee", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "systemTxMaxGas", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "maximumBaseFee", + "type": "uint128" + } + ], + "internalType": "struct ResourceMetering.ResourceConfig", + "name": "_config", + "type": "tuple" + } + ], + "name": "setResourceConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_unsafeBlockSigner", + "type": "address" + } + ], + "name": "setUnsafeBlockSigner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "startBlock_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unsafeBlockSigner", + "outputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "enum SystemConfig.UpdateType", + "name": "updateType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "ConfigUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/Transactor.json b/packages/contracts-bedrock/snapshots/abi/Transactor.json new file mode 100644 index 000000000000..b88471ef3f8c --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/Transactor.json @@ -0,0 +1,121 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "CALL", + "outputs": [ + { + "internalType": "bool", + "name": "success_", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "data_", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "DELEGATECALL", + "outputs": [ + { + "internalType": "bool", + "name": "success_", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "data_", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerUpdated", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/TransferOnion.json b/packages/contracts-bedrock/snapshots/abi/TransferOnion.json new file mode 100644 index 000000000000..9bcafbf1ea97 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/TransferOnion.json @@ -0,0 +1,92 @@ +[ + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_shell", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "SENDER", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "shell", + "type": "bytes32" + } + ], + "internalType": "struct TransferOnion.Layer[]", + "name": "_layers", + "type": "tuple[]" + } + ], + "name": "peel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shell", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/WETH9.json b/packages/contracts-bedrock/snapshots/abi/WETH9.json new file mode 100644 index 000000000000..f2a38a109e8b --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/WETH9.json @@ -0,0 +1,286 @@ +[ + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "guy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/WETH98.json b/packages/contracts-bedrock/snapshots/abi/WETH98.json new file mode 100644 index 000000000000..f5380edb3e52 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/WETH98.json @@ -0,0 +1,286 @@ +[ + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "guy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/state-diff/Kontrol-Deploy.json b/packages/contracts-bedrock/snapshots/state-diff/Kontrol-Deploy.json new file mode 100644 index 000000000000..1185fce2f370 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/state-diff/Kontrol-Deploy.json @@ -0,0 +1,12035 @@ +{ + "accountAccesses": [ + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": false, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x34A1D3fff3958843C43aD80F30b94c510645C316", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b50610913806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806353e5d9351161005057806353e5d935146100b7578063d18af54d146100cc578063ec9e80bb146100df57600080fd5b80631688f0b91461006c5780633408e470146100a9575b600080fd5b61007f61007a3660046105d2565b6100f2565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6040514681526020016100a0565b6100bf610194565b6040516100a091906106a5565b61007f6100da3660046106bf565b6101dc565b61007f6100ed3660046105d2565b6102f8565b600080838051906020012083604051602001610118929190918252602082015260400190565b60405160208183030381529060405280519060200120905061013b85858361032a565b60405173ffffffffffffffffffffffffffffffffffffffff8781168252919350908316907f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2359060200160405180910390a2509392505050565b6060604051806020016101a6906104c6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b600080838360405160200161022092919091825260601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602082015260340190565b6040516020818303038152906040528051906020012060001c90506102468686836100f2565b915073ffffffffffffffffffffffffffffffffffffffff8316156102ef576040517f1e52b51800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690631e52b518906102bc9085908a908a908a9060040161072b565b600060405180830381600087803b1580156102d657600080fd5b505af11580156102ea573d6000803e3d6000fd5b505050505b50949350505050565b60008083805190602001208361030b4690565b6040805160208101949094528301919091526060820152608001610118565b6000833b610399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53696e676c65746f6e20636f6e7472616374206e6f74206465706c6f7965640060448201526064015b60405180910390fd5b6000604051806020016103ab906104c6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052610403919073ffffffffffffffffffffffffffffffffffffffff881690602001610775565b6040516020818303038152906040529050828151826020016000f5915073ffffffffffffffffffffffffffffffffffffffff821661049d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f437265617465322063616c6c206661696c6564000000000000000000000000006044820152606401610390565b8351156104be5760008060008651602088016000875af1036104be57600080fd5b509392505050565b61016f8061079883390190565b73ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261053857600080fd5b813567ffffffffffffffff80821115610553576105536104f8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610599576105996104f8565b816040528381528660208588010111156105b257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156105e757600080fd5b83356105f2816104d3565b9250602084013567ffffffffffffffff81111561060e57600080fd5b61061a86828701610527565b925050604084013590509250925092565b60005b8381101561064657818101518382015260200161062e565b83811115610655576000848401525b50505050565b6000815180845261067381602086016020860161062b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106b8602083018461065b565b9392505050565b600080600080608085870312156106d557600080fd5b84356106e0816104d3565b9350602085013567ffffffffffffffff8111156106fc57600080fd5b61070887828801610527565b935050604085013591506060850135610720816104d3565b939692955090935050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152610764608083018561065b565b905082606083015295945050505050565b6000835161078781846020880161062b565b919091019182525060200191905056fe608060405234801561001057600080fd5b5060405161016f38038061016f83398101604081905261002f916100b9565b6001600160a01b0381166100945760405162461bcd60e51b815260206004820152602260248201527f496e76616c69642073696e676c65746f6e20616464726573732070726f766964604482015261195960f21b606482015260840160405180910390fd5b600080546001600160a01b0319166001600160a01b03929092169190911790556100e9565b6000602082840312156100cb57600080fd5b81516001600160a01b03811681146100e257600080fd5b9392505050565b6078806100f76000396000f3fe6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000aa164736f6c634300080f000a", + "deployedCode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c806353e5d9351161005057806353e5d935146100b7578063d18af54d146100cc578063ec9e80bb146100df57600080fd5b80631688f0b91461006c5780633408e470146100a9575b600080fd5b61007f61007a3660046105d2565b6100f2565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6040514681526020016100a0565b6100bf610194565b6040516100a091906106a5565b61007f6100da3660046106bf565b6101dc565b61007f6100ed3660046105d2565b6102f8565b600080838051906020012083604051602001610118929190918252602082015260400190565b60405160208183030381529060405280519060200120905061013b85858361032a565b60405173ffffffffffffffffffffffffffffffffffffffff8781168252919350908316907f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2359060200160405180910390a2509392505050565b6060604051806020016101a6906104c6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052919050565b600080838360405160200161022092919091825260601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602082015260340190565b6040516020818303038152906040528051906020012060001c90506102468686836100f2565b915073ffffffffffffffffffffffffffffffffffffffff8316156102ef576040517f1e52b51800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690631e52b518906102bc9085908a908a908a9060040161072b565b600060405180830381600087803b1580156102d657600080fd5b505af11580156102ea573d6000803e3d6000fd5b505050505b50949350505050565b60008083805190602001208361030b4690565b6040805160208101949094528301919091526060820152608001610118565b6000833b610399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53696e676c65746f6e20636f6e7472616374206e6f74206465706c6f7965640060448201526064015b60405180910390fd5b6000604051806020016103ab906104c6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052610403919073ffffffffffffffffffffffffffffffffffffffff881690602001610775565b6040516020818303038152906040529050828151826020016000f5915073ffffffffffffffffffffffffffffffffffffffff821661049d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f437265617465322063616c6c206661696c6564000000000000000000000000006044820152606401610390565b8351156104be5760008060008651602088016000875af1036104be57600080fd5b509392505050565b61016f8061079883390190565b73ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261053857600080fd5b813567ffffffffffffffff80821115610553576105536104f8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610599576105996104f8565b816040528381528660208588010111156105b257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156105e757600080fd5b83356105f2816104d3565b9250602084013567ffffffffffffffff81111561060e57600080fd5b61061a86828701610527565b925050604084013590509250925092565b60005b8381101561064657818101518382015260200161062e565b83811115610655576000848401525b50505050565b6000815180845261067381602086016020860161062b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006106b8602083018461065b565b9392505050565b600080600080608085870312156106d557600080fd5b84356106e0816104d3565b9350602085013567ffffffffffffffff8111156106fc57600080fd5b61070887828801610527565b935050604085013591506060850135610720816104d3565b939692955090935050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152610764608083018561065b565b905082606083015295945050505050565b6000835161078781846020880161062b565b919091019182525060200191905056fe608060405234801561001057600080fd5b5060405161016f38038061016f83398101604081905261002f916100b9565b6001600160a01b0381166100945760405162461bcd60e51b815260206004820152602260248201527f496e76616c69642073696e676c65746f6e20616464726573732070726f766964604482015261195960f21b606482015260840160405180910390fd5b600080546001600160a01b0319166001600160a01b03929092169190911790556100e9565b6000602082840312156100cb57600080fd5b81516001600160a01b03811681146100e257600080fd5b9392505050565b6078806100f76000396000f3fe6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000aa164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": false, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b506001600455614201806100256000396000f3fe6080604052600436106101d15760003560e01c8063affed0e0116100f7578063e19a9dd911610095578063f08a032311610064578063f08a0323146105f5578063f698da2514610615578063f8dc5dd91461067c578063ffa1ad741461069c5761020d565b8063e19a9dd914610580578063e318b52b146105a0578063e75235b8146105c0578063e86637db146105d55761020d565b8063cc2f8452116100d1578063cc2f8452146104f2578063d4d9bdcd14610520578063d8d11f7814610540578063e009cfde146105605761020d565b8063affed0e01461049c578063b4faba09146104b2578063b63e800d146104d25761020d565b80635624b25b1161016f5780636a7612021161013e5780636a7612021461040f5780637d83297414610422578063934f3a111461045a578063a0e67e2b1461047a5761020d565b80635624b25b146103755780635ae6bd37146103a2578063610b5925146103cf578063694e80c3146103ef5761020d565b80632f54bf6e116101ab5780632f54bf6e146102ea5780633408e4701461030a578063468721a7146103275780635229073f146103475761020d565b80630d582f131461027357806312fb68e0146102955780632d9ad53d146102b55761020d565b3661020d5760405134815233907f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d9060200160405180910390a2005b34801561021957600080fd5b507f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d580548061024457005b36600080373360601b365260008060143601600080855af190503d6000803e8061026d573d6000fd5b503d6000f35b34801561027f57600080fd5b5061029361028e366004613568565b6106e5565b005b3480156102a157600080fd5b506102936102b036600461366e565b610933565b3480156102c157600080fd5b506102d56102d03660046136e3565b610ff7565b60405190151581526020015b60405180910390f35b3480156102f657600080fd5b506102d56103053660046136e3565b61104c565b34801561031657600080fd5b50465b6040519081526020016102e1565b34801561033357600080fd5b506102d561034236600461370f565b61109e565b34801561035357600080fd5b5061036761036236600461370f565b6111d4565b6040516102e19291906137e4565b34801561038157600080fd5b506103956103903660046137ff565b61120a565b6040516102e19190613821565b3480156103ae57600080fd5b506103196103bd366004613834565b60076020526000908152604090205481565b3480156103db57600080fd5b506102936103ea3660046136e3565b611290565b3480156103fb57600080fd5b5061029361040a366004613834565b611479565b6102d561041d366004613896565b611593565b34801561042e57600080fd5b5061031961043d366004613568565b600860209081526000928352604080842090915290825290205481565b34801561046657600080fd5b5061029361047536600461396f565b61198f565b34801561048657600080fd5b5061048f611a0b565b6040516102e19190613a2d565b3480156104a857600080fd5b5061031960055481565b3480156104be57600080fd5b506102936104cd366004613a40565b611b23565b3480156104de57600080fd5b506102936104ed366004613a90565b611b46565b3480156104fe57600080fd5b5061051261050d366004613568565b611c62565b6040516102e1929190613b85565b34801561052c57600080fd5b5061029361053b366004613834565b611ed0565b34801561054c57600080fd5b5061031961055b366004613bbd565b611fa4565b34801561056c57600080fd5b5061029361057b366004613c7e565b611fd1565b34801561058c57600080fd5b5061029361059b3660046136e3565b6121a3565b3480156105ac57600080fd5b506102936105bb366004613cb7565b612344565b3480156105cc57600080fd5b50600454610319565b3480156105e157600080fd5b506103956105f0366004613bbd565b6126bc565b34801561060157600080fd5b506102936106103660046136e3565b612855565b34801561062157600080fd5b5061031960007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b34801561068857600080fd5b50610293610697366004613d02565b6128aa565b3480156106a857600080fd5b506103956040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6106ed612b34565b73ffffffffffffffffffffffffffffffffffffffff821615801590610729575073ffffffffffffffffffffffffffffffffffffffff8216600114155b801561074b575073ffffffffffffffffffffffffffffffffffffffff82163014155b6107b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600260205260409020541615610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b60026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0805473ffffffffffffffffffffffffffffffffffffffff8481166000818152604081208054939094167fffffffffffffffffffffffff0000000000000000000000000000000000000000938416179093556001835283549091161790915560038054916108d783613d72565b909155505060405173ffffffffffffffffffffffffffffffffffffffff8316907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2690600090a2806004541461092f5761092f81611479565b5050565b61093e816041612b9f565b825110156109a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6000808060008060005b86811015610feb576041818102890160208101516040820151919092015160ff16955090935091506000849003610cf857885160208a01208a14610a52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323700000000000000000000000000000000000000000000000000000060448201526064016107ad565b9193508391610a62876041612b9f565b821015610acb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323100000000000000000000000000000000000000000000000000000060448201526064016107ad565b8751610ad8836020612bdb565b1115610b40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323200000000000000000000000000000000000000000000000000000060448201526064016107ad565b602082890181015189519091610b63908390610b5d908790612bdb565b90612bdb565b1115610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323300000000000000000000000000000000000000000000000000000060448201526064016107ad565b6040517f20c13b0b000000000000000000000000000000000000000000000000000000008082528a85016020019173ffffffffffffffffffffffffffffffffffffffff8916906320c13b0b90610c27908f908690600401613daa565b602060405180830381865afa158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c689190613dcf565b7fffffffff000000000000000000000000000000000000000000000000000000001614610cf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323400000000000000000000000000000000000000000000000000000060448201526064016107ad565b5050610eeb565b8360ff16600103610dc65791935083913373ffffffffffffffffffffffffffffffffffffffff84161480610d5b575073ffffffffffffffffffffffffffffffffffffffff851660009081526008602090815260408083208d845290915290205415155b610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323500000000000000000000000000000000000000000000000000000060448201526064016107ad565b610eeb565b601e8460ff161115610e8b576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018b9052600190605c0160405160208183030381529060405280519060200120600486610e2b9190613e11565b6040805160008152602081018083529390935260ff90911690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610e7a573d6000803e3d6000fd5b505050602060405103519450610eeb565b6040805160008152602081018083528c905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610ede573d6000803e3d6000fd5b5050506020604051035194505b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16118015610f4c575073ffffffffffffffffffffffffffffffffffffffff8581166000908152600260205260409020541615155b8015610f6f575073ffffffffffffffffffffffffffffffffffffffff8516600114155b610fd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323600000000000000000000000000000000000000000000000000000060448201526064016107ad565b8495508080610fe390613d72565b9150506109b2565b50505050505050505050565b6000600173ffffffffffffffffffffffffffffffffffffffff831614801590611046575073ffffffffffffffffffffffffffffffffffffffff8281166000908152600160205260409020541615155b92915050565b600073ffffffffffffffffffffffffffffffffffffffff821660011480159061104657505073ffffffffffffffffffffffffffffffffffffffff90811660009081526002602052604090205416151590565b6000336001148015906110d557503360009081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1615155b61113b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b611168858585857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612bf7565b905080156111a05760405133907f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb890600090a26111cc565b60405133907facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37590600090a25b949350505050565b600060606111e48686868661109e565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b60606000611219836020613e34565b67ffffffffffffffff81111561123157611231613594565b6040519080825280601f01601f19166020018201604052801561125b576020820181803683370190505b50905060005b8381101561128857848101546020808302840101528061128081613d72565b915050611261565b509392505050565b611298612b34565b73ffffffffffffffffffffffffffffffffffffffff8116158015906112d4575073ffffffffffffffffffffffffffffffffffffffff8116600114155b61133a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526001602052604090205416156113c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b600160208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f805473ffffffffffffffffffffffffffffffffffffffff848116600081815260408082208054949095167fffffffffffffffffffffffff000000000000000000000000000000000000000094851617909455948552835490911681179092555190917fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844091a250565b611481612b34565b6003548111156114ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001811015611558576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b60048190556040518181527f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c939060200160405180910390a150565b60008060006115ad8e8e8e8e8e8e8e8e8e8e6005546126bc565b6005805491925060006115bf83613d72565b90915550508051602082012091506115d882828661198f565b5060006116037f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c85490565b905073ffffffffffffffffffffffffffffffffffffffff8116156116a3578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b81526004016116709c9b9a99989796959493929190613edb565b600060405180830381600087803b15801561168a57600080fd5b505af115801561169e573d6000803e3d6000fd5b505050505b6116cf6116b28a6109c4613ff1565b603f6116bf8c6040613e34565b6116c99190614009565b90612c3e565b6116db906101f4613ff1565b5a1015611744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313000000000000000000000000000000000000000000000000000000060448201526064016107ad565b60005a90506117b58f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8c6000146117a2578e612bf7565b6109c45a6117b09190614044565b612bf7565b93506117c25a8290612c55565b905083806117cf57508915155b806117d957508715155b61183f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313300000000000000000000000000000000000000000000000000000060448201526064016107ad565b6000881561185757611854828b8b8b8b612c70565b90505b841561189c57837f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8260405161188f91815260200190565b60405180910390a26118d7565b837f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23826040516118ce91815260200190565b60405180910390a25b505073ffffffffffffffffffffffffffffffffffffffff81161561197e576040517f9327136800000000000000000000000000000000000000000000000000000000815260048101839052831515602482015273ffffffffffffffffffffffffffffffffffffffff821690639327136890604401600060405180830381600087803b15801561196557600080fd5b505af1158015611979573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b600454806119f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b611a0584848484610933565b50505050565b6060600060035467ffffffffffffffff811115611a2a57611a2a613594565b604051908082528060200260200182016040528015611a53578160200160208202803683370190505b506001600090815260026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0549192509073ffffffffffffffffffffffffffffffffffffffff165b73ffffffffffffffffffffffffffffffffffffffff8116600114611b1b5780838381518110611ace57611ace61405b565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152918116600090815260029092526040909120541681611b1381613d72565b925050611a9d565b509092915050565b600080825160208401855af480600052503d6020523d600060403e60403d016000fd5b611b848a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508c9250612e01915050565b73ffffffffffffffffffffffffffffffffffffffff841615611ba957611ba9846131ce565b611be98787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061327192505050565b8115611c0057611bfe82600060018685612c70565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b89604051611c4e95949392919061408a565b60405180910390a250505050505050505050565b6060600073ffffffffffffffffffffffffffffffffffffffff841660011480611c8f5750611c8f84610ff7565b611cf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b60008311611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303600000000000000000000000000000000000000000000000000000060448201526064016107ad565b8267ffffffffffffffff811115611d7857611d78613594565b604051908082528060200260200182016040528015611da1578160200160208202803683370190505b5073ffffffffffffffffffffffffffffffffffffffff808616600090815260016020526040812054929450911691505b73ffffffffffffffffffffffffffffffffffffffff821615801590611e0d575073ffffffffffffffffffffffffffffffffffffffff8216600114155b8015611e1857508381105b15611e805781838281518110611e3057611e3061405b565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152928116600090815260019093526040909220549091169080611e7881613d72565b915050611dd1565b73ffffffffffffffffffffffffffffffffffffffff8216600114611ec55782611eaa600183614044565b81518110611eba57611eba61405b565b602002602001015191505b808352509250929050565b3360009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16611f5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333000000000000000000000000000000000000000000000000000000060448201526064016107ad565b336000818152600860209081526040808320858452909152808220600190555183917ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c91a350565b6000611fb98c8c8c8c8c8c8c8c8c8c8c6126bc565b8051906020012090509b9a5050505050505050505050565b611fd9612b34565b73ffffffffffffffffffffffffffffffffffffffff811615801590612015575073ffffffffffffffffffffffffffffffffffffffff8116600114155b61207b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526001602052604090205481169082161461210e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff818116600081815260016020526040808220805487861684528284208054919096167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179095558383528054909416909355915190917faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427691a25050565b6121ab612b34565b73ffffffffffffffffffffffffffffffffffffffff8116156122db576040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fe6d7a83a00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015612251573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122759190614110565b6122db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475333303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b7f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c881815560405173ffffffffffffffffffffffffffffffffffffffff8316907f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa290600090a25050565b61234c612b34565b73ffffffffffffffffffffffffffffffffffffffff811615801590612388575073ffffffffffffffffffffffffffffffffffffffff8116600114155b80156123aa575073ffffffffffffffffffffffffffffffffffffffff81163014155b612410576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260026020526040902054161561249f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8216158015906124db575073ffffffffffffffffffffffffffffffffffffffff8216600114155b612541576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600260205260409020548116908316146125d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260026020526040808220805486861680855283852080549288167fffffffffffffffffffffffff00000000000000000000000000000000000000009384161790559589168452828420805482169096179095558383528054909416909355915190917ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf91a260405173ffffffffffffffffffffffffffffffffffffffff8216907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2690600090a2505050565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d6040516126f6929190614132565b60405190819003812061271c949392918e908e908e908e908e908e908e90602001614142565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012090507f19000000000000000000000000000000000000000000000000000000000000007f01000000000000000000000000000000000000000000000000000000000000006127f060007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b6040517fff0000000000000000000000000000000000000000000000000000000000000093841660208201529290911660218301526022820152604281018290526062016040516020818303038152906040529150509b9a5050505050505050505050565b61285d612b34565b612866816131ce565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b090600090a250565b6128b2612b34565b8060016003546128c29190614044565b101561292a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff821615801590612966575073ffffffffffffffffffffffffffffffffffffffff8216600114155b6129cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260026020526040902054811690831614612a5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260026020526040808220805488861684529183208054929095167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790945591815282549091169091556003805491612ad7836141bf565b909155505060405173ffffffffffffffffffffffffffffffffffffffff8316907ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf90600090a28060045414612b2f57612b2f81611479565b505050565b333014612b9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333100000000000000000000000000000000000000000000000000000060448201526064016107ad565b565b600082600003612bb157506000611046565b6000612bbd8385613e34565b905082612bca8583614009565b14612bd457600080fd5b9392505050565b600080612be88385613ff1565b905083811015612bd457600080fd5b60006001836001811115612c0d57612c0d613e71565b03612c25576000808551602087018986f49050612c35565b600080855160208701888a87f190505b95945050505050565b600081831015612c4e5781612bd4565b5090919050565b600082821115612c6457600080fd5b60006111cc8385614044565b60008073ffffffffffffffffffffffffffffffffffffffff831615612c955782612c97565b325b905073ffffffffffffffffffffffffffffffffffffffff8416612d7657612cd63a8610612cc4573a612cc6565b855b612cd08989612bdb565b90612b9f565b60405190925073ffffffffffffffffffffffffffffffffffffffff82169083156108fc029084906000818181858888f19350505050612d71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313100000000000000000000000000000000000000000000000000000060448201526064016107ad565b612df7565b612d8485612cd08989612bdb565b9150612d91848284613469565b612df7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313200000000000000000000000000000000000000000000000000000060448201526064016107ad565b5095945050505050565b60045415612e6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b8151811115612ed6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001811015612f41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b600160005b8351811015613176576000848281518110612f6357612f6361405b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612fc1575073ffffffffffffffffffffffffffffffffffffffff8116600114155b8015612fe3575073ffffffffffffffffffffffffffffffffffffffff81163014155b801561301b57508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b613081576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600260205260409020541615613110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff928316600090815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016938216939093179092558061316e81613d72565b915050612f46565b5073ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011790559051600355600455565b3073ffffffffffffffffffffffffffffffffffffffff82160361324d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475334303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b7f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d555565b600160008190526020527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5473ffffffffffffffffffffffffffffffffffffffff161561331a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001600081905260208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80547fffffffffffffffffffffffff000000000000000000000000000000000000000016909117905573ffffffffffffffffffffffffffffffffffffffff82161561092f57813b6133f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b6134038260008360015a612bf7565b61092f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6040805173ffffffffffffffffffffffffffffffffffffffff841660248201526044808201849052825180830390910181526064909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781528251600093929184919082896127105a03f13d8015613516576020811461351e5760009350613529565b819350613529565b600051158215171593505b5050509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461355557600080fd5b50565b803561356381613533565b919050565b6000806040838503121561357b57600080fd5b823561358681613533565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126135d457600080fd5b813567ffffffffffffffff808211156135ef576135ef613594565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561363557613635613594565b8160405283815286602085880101111561364e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561368457600080fd5b84359350602085013567ffffffffffffffff808211156136a357600080fd5b6136af888389016135c3565b945060408701359150808211156136c557600080fd5b506136d2878288016135c3565b949793965093946060013593505050565b6000602082840312156136f557600080fd5b8135612bd481613533565b80356002811061356357600080fd5b6000806000806080858703121561372557600080fd5b843561373081613533565b935060208501359250604085013567ffffffffffffffff81111561375357600080fd5b61375f878288016135c3565b92505061376e60608601613700565b905092959194509250565b6000815180845260005b8181101561379f57602081850181015186830182015201613783565b818111156137b1576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b82151581526040602082015260006111cc6040830184613779565b6000806040838503121561381257600080fd5b50508035926020909101359150565b602081526000612bd46020830184613779565b60006020828403121561384657600080fd5b5035919050565b60008083601f84011261385f57600080fd5b50813567ffffffffffffffff81111561387757600080fd5b60208301915083602082850101111561388f57600080fd5b9250929050565b60008060008060008060008060008060006101408c8e0312156138b857600080fd5b6138c18c613558565b9a5060208c0135995067ffffffffffffffff8060408e013511156138e457600080fd5b6138f48e60408f01358f0161384d565b909a50985061390560608e01613700565b975060808d0135965060a08d0135955060c08d0135945061392860e08e01613558565b93506139376101008e01613558565b9250806101208e0135111561394b57600080fd5b5061395d8d6101208e01358e016135c3565b90509295989b509295989b9093969950565b60008060006060848603121561398457600080fd5b83359250602084013567ffffffffffffffff808211156139a357600080fd5b6139af878388016135c3565b935060408601359150808211156139c557600080fd5b506139d2868287016135c3565b9150509250925092565b600081518084526020808501945080840160005b83811015613a2257815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016139f0565b509495945050505050565b602081526000612bd460208301846139dc565b60008060408385031215613a5357600080fd5b8235613a5e81613533565b9150602083013567ffffffffffffffff811115613a7a57600080fd5b613a86858286016135c3565b9150509250929050565b6000806000806000806000806000806101008b8d031215613ab057600080fd5b8a3567ffffffffffffffff80821115613ac857600080fd5b818d0191508d601f830112613adc57600080fd5b813581811115613aeb57600080fd5b8e60208260051b8501011115613b0057600080fd5b60208381019d50909b508d01359950613b1b60408e01613558565b985060608d0135915080821115613b3157600080fd5b50613b3e8d828e0161384d565b9097509550613b51905060808c01613558565b9350613b5f60a08c01613558565b925060c08b01359150613b7460e08c01613558565b90509295989b9194979a5092959850565b604081526000613b9860408301856139dc565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b60008060008060008060008060008060006101408c8e031215613bdf57600080fd5b8b35613bea81613533565b9a5060208c0135995060408c013567ffffffffffffffff811115613c0d57600080fd5b613c198e828f0161384d565b909a509850613c2c905060608d01613700565b965060808c0135955060a08c0135945060c08c0135935060e08c0135613c5181613533565b92506101008c0135613c6281613533565b809250506101208c013590509295989b509295989b9093969950565b60008060408385031215613c9157600080fd5b8235613c9c81613533565b91506020830135613cac81613533565b809150509250929050565b600080600060608486031215613ccc57600080fd5b8335613cd781613533565b92506020840135613ce781613533565b91506040840135613cf781613533565b809150509250925092565b600080600060608486031215613d1757600080fd5b8335613d2281613533565b92506020840135613d3281613533565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613da357613da3613d43565b5060010190565b604081526000613dbd6040830185613779565b8281036020840152612c358185613779565b600060208284031215613de157600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114612bd457600080fd5b600060ff821660ff841680821015613e2b57613e2b613d43565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613e6c57613e6c613d43565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613ed7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b600061016073ffffffffffffffffffffffffffffffffffffffff8f1683528d60208401528060408401528b81840152506101808b8d828501376000818d850101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8d01168301613f51606085018d613ea0565b8a60808501528960a08501528860c0850152613f8560e085018973ffffffffffffffffffffffffffffffffffffffff169052565b73ffffffffffffffffffffffffffffffffffffffff87166101008501528184820301610120850152613fb982820187613779565b92505050613fe061014083018473ffffffffffffffffffffffffffffffffffffffff169052565b9d9c50505050505050505050505050565b6000821982111561400457614004613d43565b500190565b60008261403f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008282101561405657614056613d43565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6080808252810185905260008660a08301825b888110156140da5782356140b081613533565b73ffffffffffffffffffffffffffffffffffffffff1682526020928301929091019060010161409d565b506020840196909652505073ffffffffffffffffffffffffffffffffffffffff9283166040820152911660609091015292915050565b60006020828403121561412257600080fd5b81518015158114612bd457600080fd5b8183823760009101908152919050565b6000610160820190508c825273ffffffffffffffffffffffffffffffffffffffff808d1660208401528b60408401528a6060840152614184608084018b613ea0565b60a083019890985260c082019690965260e0810194909452918516610100840152909316610120820152610140019190915295945050505050565b6000816141ce576141ce613d43565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea164736f6c634300080f000a", + "deployedCode": "0x6080604052600436106101d15760003560e01c8063affed0e0116100f7578063e19a9dd911610095578063f08a032311610064578063f08a0323146105f5578063f698da2514610615578063f8dc5dd91461067c578063ffa1ad741461069c5761020d565b8063e19a9dd914610580578063e318b52b146105a0578063e75235b8146105c0578063e86637db146105d55761020d565b8063cc2f8452116100d1578063cc2f8452146104f2578063d4d9bdcd14610520578063d8d11f7814610540578063e009cfde146105605761020d565b8063affed0e01461049c578063b4faba09146104b2578063b63e800d146104d25761020d565b80635624b25b1161016f5780636a7612021161013e5780636a7612021461040f5780637d83297414610422578063934f3a111461045a578063a0e67e2b1461047a5761020d565b80635624b25b146103755780635ae6bd37146103a2578063610b5925146103cf578063694e80c3146103ef5761020d565b80632f54bf6e116101ab5780632f54bf6e146102ea5780633408e4701461030a578063468721a7146103275780635229073f146103475761020d565b80630d582f131461027357806312fb68e0146102955780632d9ad53d146102b55761020d565b3661020d5760405134815233907f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d9060200160405180910390a2005b34801561021957600080fd5b507f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d580548061024457005b36600080373360601b365260008060143601600080855af190503d6000803e8061026d573d6000fd5b503d6000f35b34801561027f57600080fd5b5061029361028e366004613568565b6106e5565b005b3480156102a157600080fd5b506102936102b036600461366e565b610933565b3480156102c157600080fd5b506102d56102d03660046136e3565b610ff7565b60405190151581526020015b60405180910390f35b3480156102f657600080fd5b506102d56103053660046136e3565b61104c565b34801561031657600080fd5b50465b6040519081526020016102e1565b34801561033357600080fd5b506102d561034236600461370f565b61109e565b34801561035357600080fd5b5061036761036236600461370f565b6111d4565b6040516102e19291906137e4565b34801561038157600080fd5b506103956103903660046137ff565b61120a565b6040516102e19190613821565b3480156103ae57600080fd5b506103196103bd366004613834565b60076020526000908152604090205481565b3480156103db57600080fd5b506102936103ea3660046136e3565b611290565b3480156103fb57600080fd5b5061029361040a366004613834565b611479565b6102d561041d366004613896565b611593565b34801561042e57600080fd5b5061031961043d366004613568565b600860209081526000928352604080842090915290825290205481565b34801561046657600080fd5b5061029361047536600461396f565b61198f565b34801561048657600080fd5b5061048f611a0b565b6040516102e19190613a2d565b3480156104a857600080fd5b5061031960055481565b3480156104be57600080fd5b506102936104cd366004613a40565b611b23565b3480156104de57600080fd5b506102936104ed366004613a90565b611b46565b3480156104fe57600080fd5b5061051261050d366004613568565b611c62565b6040516102e1929190613b85565b34801561052c57600080fd5b5061029361053b366004613834565b611ed0565b34801561054c57600080fd5b5061031961055b366004613bbd565b611fa4565b34801561056c57600080fd5b5061029361057b366004613c7e565b611fd1565b34801561058c57600080fd5b5061029361059b3660046136e3565b6121a3565b3480156105ac57600080fd5b506102936105bb366004613cb7565b612344565b3480156105cc57600080fd5b50600454610319565b3480156105e157600080fd5b506103956105f0366004613bbd565b6126bc565b34801561060157600080fd5b506102936106103660046136e3565b612855565b34801561062157600080fd5b5061031960007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b34801561068857600080fd5b50610293610697366004613d02565b6128aa565b3480156106a857600080fd5b506103956040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b6106ed612b34565b73ffffffffffffffffffffffffffffffffffffffff821615801590610729575073ffffffffffffffffffffffffffffffffffffffff8216600114155b801561074b575073ffffffffffffffffffffffffffffffffffffffff82163014155b6107b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600260205260409020541615610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b60026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0805473ffffffffffffffffffffffffffffffffffffffff8481166000818152604081208054939094167fffffffffffffffffffffffff0000000000000000000000000000000000000000938416179093556001835283549091161790915560038054916108d783613d72565b909155505060405173ffffffffffffffffffffffffffffffffffffffff8316907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2690600090a2806004541461092f5761092f81611479565b5050565b61093e816041612b9f565b825110156109a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6000808060008060005b86811015610feb576041818102890160208101516040820151919092015160ff16955090935091506000849003610cf857885160208a01208a14610a52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323700000000000000000000000000000000000000000000000000000060448201526064016107ad565b9193508391610a62876041612b9f565b821015610acb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323100000000000000000000000000000000000000000000000000000060448201526064016107ad565b8751610ad8836020612bdb565b1115610b40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323200000000000000000000000000000000000000000000000000000060448201526064016107ad565b602082890181015189519091610b63908390610b5d908790612bdb565b90612bdb565b1115610bcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323300000000000000000000000000000000000000000000000000000060448201526064016107ad565b6040517f20c13b0b000000000000000000000000000000000000000000000000000000008082528a85016020019173ffffffffffffffffffffffffffffffffffffffff8916906320c13b0b90610c27908f908690600401613daa565b602060405180830381865afa158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c689190613dcf565b7fffffffff000000000000000000000000000000000000000000000000000000001614610cf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323400000000000000000000000000000000000000000000000000000060448201526064016107ad565b5050610eeb565b8360ff16600103610dc65791935083913373ffffffffffffffffffffffffffffffffffffffff84161480610d5b575073ffffffffffffffffffffffffffffffffffffffff851660009081526008602090815260408083208d845290915290205415155b610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323500000000000000000000000000000000000000000000000000000060448201526064016107ad565b610eeb565b601e8460ff161115610e8b576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018b9052600190605c0160405160208183030381529060405280519060200120600486610e2b9190613e11565b6040805160008152602081018083529390935260ff90911690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610e7a573d6000803e3d6000fd5b505050602060405103519450610eeb565b6040805160008152602081018083528c905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610ede573d6000803e3d6000fd5b5050506020604051035194505b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16118015610f4c575073ffffffffffffffffffffffffffffffffffffffff8581166000908152600260205260409020541615155b8015610f6f575073ffffffffffffffffffffffffffffffffffffffff8516600114155b610fd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330323600000000000000000000000000000000000000000000000000000060448201526064016107ad565b8495508080610fe390613d72565b9150506109b2565b50505050505050505050565b6000600173ffffffffffffffffffffffffffffffffffffffff831614801590611046575073ffffffffffffffffffffffffffffffffffffffff8281166000908152600160205260409020541615155b92915050565b600073ffffffffffffffffffffffffffffffffffffffff821660011480159061104657505073ffffffffffffffffffffffffffffffffffffffff90811660009081526002602052604090205416151590565b6000336001148015906110d557503360009081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1615155b61113b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b611168858585857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612bf7565b905080156111a05760405133907f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb890600090a26111cc565b60405133907facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37590600090a25b949350505050565b600060606111e48686868661109e565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b60606000611219836020613e34565b67ffffffffffffffff81111561123157611231613594565b6040519080825280601f01601f19166020018201604052801561125b576020820181803683370190505b50905060005b8381101561128857848101546020808302840101528061128081613d72565b915050611261565b509392505050565b611298612b34565b73ffffffffffffffffffffffffffffffffffffffff8116158015906112d4575073ffffffffffffffffffffffffffffffffffffffff8116600114155b61133a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526001602052604090205416156113c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b600160208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f805473ffffffffffffffffffffffffffffffffffffffff848116600081815260408082208054949095167fffffffffffffffffffffffff000000000000000000000000000000000000000094851617909455948552835490911681179092555190917fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844091a250565b611481612b34565b6003548111156114ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001811015611558576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b60048190556040518181527f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c939060200160405180910390a150565b60008060006115ad8e8e8e8e8e8e8e8e8e8e6005546126bc565b6005805491925060006115bf83613d72565b90915550508051602082012091506115d882828661198f565b5060006116037f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c85490565b905073ffffffffffffffffffffffffffffffffffffffff8116156116a3578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b81526004016116709c9b9a99989796959493929190613edb565b600060405180830381600087803b15801561168a57600080fd5b505af115801561169e573d6000803e3d6000fd5b505050505b6116cf6116b28a6109c4613ff1565b603f6116bf8c6040613e34565b6116c99190614009565b90612c3e565b6116db906101f4613ff1565b5a1015611744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313000000000000000000000000000000000000000000000000000000060448201526064016107ad565b60005a90506117b58f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8c6000146117a2578e612bf7565b6109c45a6117b09190614044565b612bf7565b93506117c25a8290612c55565b905083806117cf57508915155b806117d957508715155b61183f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313300000000000000000000000000000000000000000000000000000060448201526064016107ad565b6000881561185757611854828b8b8b8b612c70565b90505b841561189c57837f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8260405161188f91815260200190565b60405180910390a26118d7565b837f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d23826040516118ce91815260200190565b60405180910390a25b505073ffffffffffffffffffffffffffffffffffffffff81161561197e576040517f9327136800000000000000000000000000000000000000000000000000000000815260048101839052831515602482015273ffffffffffffffffffffffffffffffffffffffff821690639327136890604401600060405180830381600087803b15801561196557600080fd5b505af1158015611979573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b600454806119f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b611a0584848484610933565b50505050565b6060600060035467ffffffffffffffff811115611a2a57611a2a613594565b604051908082528060200260200182016040528015611a53578160200160208202803683370190505b506001600090815260026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0549192509073ffffffffffffffffffffffffffffffffffffffff165b73ffffffffffffffffffffffffffffffffffffffff8116600114611b1b5780838381518110611ace57611ace61405b565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152918116600090815260029092526040909120541681611b1381613d72565b925050611a9d565b509092915050565b600080825160208401855af480600052503d6020523d600060403e60403d016000fd5b611b848a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508c9250612e01915050565b73ffffffffffffffffffffffffffffffffffffffff841615611ba957611ba9846131ce565b611be98787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061327192505050565b8115611c0057611bfe82600060018685612c70565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b89604051611c4e95949392919061408a565b60405180910390a250505050505050505050565b6060600073ffffffffffffffffffffffffffffffffffffffff841660011480611c8f5750611c8f84610ff7565b611cf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b60008311611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303600000000000000000000000000000000000000000000000000000060448201526064016107ad565b8267ffffffffffffffff811115611d7857611d78613594565b604051908082528060200260200182016040528015611da1578160200160208202803683370190505b5073ffffffffffffffffffffffffffffffffffffffff808616600090815260016020526040812054929450911691505b73ffffffffffffffffffffffffffffffffffffffff821615801590611e0d575073ffffffffffffffffffffffffffffffffffffffff8216600114155b8015611e1857508381105b15611e805781838281518110611e3057611e3061405b565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152928116600090815260019093526040909220549091169080611e7881613d72565b915050611dd1565b73ffffffffffffffffffffffffffffffffffffffff8216600114611ec55782611eaa600183614044565b81518110611eba57611eba61405b565b602002602001015191505b808352509250929050565b3360009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16611f5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333000000000000000000000000000000000000000000000000000000060448201526064016107ad565b336000818152600860209081526040808320858452909152808220600190555183917ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c91a350565b6000611fb98c8c8c8c8c8c8c8c8c8c8c6126bc565b8051906020012090509b9a5050505050505050505050565b611fd9612b34565b73ffffffffffffffffffffffffffffffffffffffff811615801590612015575073ffffffffffffffffffffffffffffffffffffffff8116600114155b61207b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526001602052604090205481169082161461210e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff818116600081815260016020526040808220805487861684528284208054919096167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179095558383528054909416909355915190917faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427691a25050565b6121ab612b34565b73ffffffffffffffffffffffffffffffffffffffff8116156122db576040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fe6d7a83a00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015612251573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122759190614110565b6122db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475333303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b7f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c881815560405173ffffffffffffffffffffffffffffffffffffffff8316907f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa290600090a25050565b61234c612b34565b73ffffffffffffffffffffffffffffffffffffffff811615801590612388575073ffffffffffffffffffffffffffffffffffffffff8116600114155b80156123aa575073ffffffffffffffffffffffffffffffffffffffff81163014155b612410576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260026020526040902054161561249f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8216158015906124db575073ffffffffffffffffffffffffffffffffffffffff8216600114155b612541576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600260205260409020548116908316146125d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260026020526040808220805486861680855283852080549288167fffffffffffffffffffffffff00000000000000000000000000000000000000009384161790559589168452828420805482169096179095558383528054909416909355915190917ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf91a260405173ffffffffffffffffffffffffffffffffffffffff8216907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2690600090a2505050565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d6040516126f6929190614132565b60405190819003812061271c949392918e908e908e908e908e908e908e90602001614142565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012090507f19000000000000000000000000000000000000000000000000000000000000007f01000000000000000000000000000000000000000000000000000000000000006127f060007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b6040517fff0000000000000000000000000000000000000000000000000000000000000093841660208201529290911660218301526022820152604281018290526062016040516020818303038152906040529150509b9a5050505050505050505050565b61285d612b34565b612866816131ce565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b090600090a250565b6128b2612b34565b8060016003546128c29190614044565b101561292a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff821615801590612966575073ffffffffffffffffffffffffffffffffffffffff8216600114155b6129cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260026020526040902054811690831614612a5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303500000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260026020526040808220805488861684529183208054929095167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790945591815282549091169091556003805491612ad7836141bf565b909155505060405173ffffffffffffffffffffffffffffffffffffffff8316907ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf90600090a28060045414612b2f57612b2f81611479565b505050565b333014612b9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330333100000000000000000000000000000000000000000000000000000060448201526064016107ad565b565b600082600003612bb157506000611046565b6000612bbd8385613e34565b905082612bca8583614009565b14612bd457600080fd5b9392505050565b600080612be88385613ff1565b905083811015612bd457600080fd5b60006001836001811115612c0d57612c0d613e71565b03612c25576000808551602087018986f49050612c35565b600080855160208701888a87f190505b95945050505050565b600081831015612c4e5781612bd4565b5090919050565b600082821115612c6457600080fd5b60006111cc8385614044565b60008073ffffffffffffffffffffffffffffffffffffffff831615612c955782612c97565b325b905073ffffffffffffffffffffffffffffffffffffffff8416612d7657612cd63a8610612cc4573a612cc6565b855b612cd08989612bdb565b90612b9f565b60405190925073ffffffffffffffffffffffffffffffffffffffff82169083156108fc029084906000818181858888f19350505050612d71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313100000000000000000000000000000000000000000000000000000060448201526064016107ad565b612df7565b612d8485612cd08989612bdb565b9150612d91848284613469565b612df7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330313200000000000000000000000000000000000000000000000000000060448201526064016107ad565b5095945050505050565b60045415612e6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b8151811115612ed6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303100000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001811015612f41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b600160005b8351811015613176576000848281518110612f6357612f6361405b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612fc1575073ffffffffffffffffffffffffffffffffffffffff8116600114155b8015612fe3575073ffffffffffffffffffffffffffffffffffffffff81163014155b801561301b57508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b613081576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303300000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600260205260409020541615613110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475332303400000000000000000000000000000000000000000000000000000060448201526064016107ad565b73ffffffffffffffffffffffffffffffffffffffff928316600090815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016938216939093179092558061316e81613d72565b915050612f46565b5073ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011790559051600355600455565b3073ffffffffffffffffffffffffffffffffffffffff82160361324d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475334303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b7f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d555565b600160008190526020527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5473ffffffffffffffffffffffffffffffffffffffff161561331a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475331303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6001600081905260208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80547fffffffffffffffffffffffff000000000000000000000000000000000000000016909117905573ffffffffffffffffffffffffffffffffffffffff82161561092f57813b6133f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303200000000000000000000000000000000000000000000000000000060448201526064016107ad565b6134038260008360015a612bf7565b61092f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f475330303000000000000000000000000000000000000000000000000000000060448201526064016107ad565b6040805173ffffffffffffffffffffffffffffffffffffffff841660248201526044808201849052825180830390910181526064909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781528251600093929184919082896127105a03f13d8015613516576020811461351e5760009350613529565b819350613529565b600051158215171593505b5050509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461355557600080fd5b50565b803561356381613533565b919050565b6000806040838503121561357b57600080fd5b823561358681613533565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126135d457600080fd5b813567ffffffffffffffff808211156135ef576135ef613594565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561363557613635613594565b8160405283815286602085880101111561364e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561368457600080fd5b84359350602085013567ffffffffffffffff808211156136a357600080fd5b6136af888389016135c3565b945060408701359150808211156136c557600080fd5b506136d2878288016135c3565b949793965093946060013593505050565b6000602082840312156136f557600080fd5b8135612bd481613533565b80356002811061356357600080fd5b6000806000806080858703121561372557600080fd5b843561373081613533565b935060208501359250604085013567ffffffffffffffff81111561375357600080fd5b61375f878288016135c3565b92505061376e60608601613700565b905092959194509250565b6000815180845260005b8181101561379f57602081850181015186830182015201613783565b818111156137b1576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b82151581526040602082015260006111cc6040830184613779565b6000806040838503121561381257600080fd5b50508035926020909101359150565b602081526000612bd46020830184613779565b60006020828403121561384657600080fd5b5035919050565b60008083601f84011261385f57600080fd5b50813567ffffffffffffffff81111561387757600080fd5b60208301915083602082850101111561388f57600080fd5b9250929050565b60008060008060008060008060008060006101408c8e0312156138b857600080fd5b6138c18c613558565b9a5060208c0135995067ffffffffffffffff8060408e013511156138e457600080fd5b6138f48e60408f01358f0161384d565b909a50985061390560608e01613700565b975060808d0135965060a08d0135955060c08d0135945061392860e08e01613558565b93506139376101008e01613558565b9250806101208e0135111561394b57600080fd5b5061395d8d6101208e01358e016135c3565b90509295989b509295989b9093969950565b60008060006060848603121561398457600080fd5b83359250602084013567ffffffffffffffff808211156139a357600080fd5b6139af878388016135c3565b935060408601359150808211156139c557600080fd5b506139d2868287016135c3565b9150509250925092565b600081518084526020808501945080840160005b83811015613a2257815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016139f0565b509495945050505050565b602081526000612bd460208301846139dc565b60008060408385031215613a5357600080fd5b8235613a5e81613533565b9150602083013567ffffffffffffffff811115613a7a57600080fd5b613a86858286016135c3565b9150509250929050565b6000806000806000806000806000806101008b8d031215613ab057600080fd5b8a3567ffffffffffffffff80821115613ac857600080fd5b818d0191508d601f830112613adc57600080fd5b813581811115613aeb57600080fd5b8e60208260051b8501011115613b0057600080fd5b60208381019d50909b508d01359950613b1b60408e01613558565b985060608d0135915080821115613b3157600080fd5b50613b3e8d828e0161384d565b9097509550613b51905060808c01613558565b9350613b5f60a08c01613558565b925060c08b01359150613b7460e08c01613558565b90509295989b9194979a5092959850565b604081526000613b9860408301856139dc565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b60008060008060008060008060008060006101408c8e031215613bdf57600080fd5b8b35613bea81613533565b9a5060208c0135995060408c013567ffffffffffffffff811115613c0d57600080fd5b613c198e828f0161384d565b909a509850613c2c905060608d01613700565b965060808c0135955060a08c0135945060c08c0135935060e08c0135613c5181613533565b92506101008c0135613c6281613533565b809250506101208c013590509295989b509295989b9093969950565b60008060408385031215613c9157600080fd5b8235613c9c81613533565b91506020830135613cac81613533565b809150509250929050565b600080600060608486031215613ccc57600080fd5b8335613cd781613533565b92506020840135613ce781613533565b91506040840135613cf781613533565b809150509250925092565b600080600060608486031215613d1757600080fd5b8335613d2281613533565b92506020840135613d3281613533565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613da357613da3613d43565b5060010190565b604081526000613dbd6040830185613779565b8281036020840152612c358185613779565b600060208284031215613de157600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114612bd457600080fd5b600060ff821660ff841680821015613e2b57613e2b613d43565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613e6c57613e6c613d43565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613ed7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b600061016073ffffffffffffffffffffffffffffffffffffffff8f1683528d60208401528060408401528b81840152506101808b8d828501376000818d850101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8d01168301613f51606085018d613ea0565b8a60808501528960a08501528860c0850152613f8560e085018973ffffffffffffffffffffffffffffffffffffffff169052565b73ffffffffffffffffffffffffffffffffffffffff87166101008501528184820301610120850152613fb982820187613779565b92505050613fe061014083018473ffffffffffffffffffffffffffffffffffffffff169052565b9d9c50505050505050505050505050565b6000821982111561400457614004613d43565b500190565b60008261403f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008282101561405657614056613d43565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6080808252810185905260008660a08301825b888110156140da5782356140b081613533565b73ffffffffffffffffffffffffffffffffffffffff1682526020928301929091019060010161409d565b506020840196909652505073ffffffffffffffffffffffffffffffffffffffff9283166040820152911660609091015292915050565b60006020828403121561412257600080fd5b81518015158114612bd457600080fd5b8183823760009101908152919050565b6000610160820190508c825273ffffffffffffffffffffffffffffffffffffffff808d1660208401528b60408401528a6060840152614184608084018b613ea0565b60a083019890985260c082019690965260e0810194909452918516610100840152909316610120820152610140019190915295945050505050565b6000816141ce576141ce613d43565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x34A1D3fff3958843C43aD80F30b94c510645C316", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x1688f0b900000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000164b63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x34A1D3fff3958843C43aD80F30b94c510645C316", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x34A1D3fff3958843C43aD80F30b94c510645C316", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b5060405161016f38038061016f83398101604081905261002f916100b9565b6001600160a01b0381166100945760405162461bcd60e51b815260206004820152602260248201527f496e76616c69642073696e676c65746f6e20616464726573732070726f766964604482015261195960f21b606482015260840160405180910390fd5b600080546001600160a01b0319166001600160a01b03929092169190911790556100e9565b6000602082840312156100cb57600080fd5b81516001600160a01b03811681146100e257600080fd5b9392505050565b6078806100f76000396000f3fe6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000a00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "deployedCode": "0x6080604052600073ffffffffffffffffffffffffffffffffffffffff8154167fa619486e00000000000000000000000000000000000000000000000000000000823503604d57808252602082f35b3682833781823684845af490503d82833e806066573d82fd5b503d81f3fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x34A1D3fff3958843C43aD80F30b94c510645C316", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xb63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x34A1D3fff3958843C43aD80F30b94c510645C316", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xb63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f380000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6105ef8061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046104fa565b610106565b6100906100da366004610548565b6101d9565b6100746100ed366004610585565b610215565b6100fa6102d1565b6101046000610352565b565b61010e6102d1565b6000610119836103c7565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff00000000000000000000000000000000000000008316179092559151929350169061017c9085906105a7565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006101e8846103c7565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b61021d6102d1565b73ffffffffffffffffffffffffffffffffffffffff81166102c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ce81610352565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bc565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016103da91906105a7565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261043757600080fd5b813567ffffffffffffffff80821115610452576104526103f7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610498576104986103f7565b816040528381528660208588010111156104b157600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b919050565b6000806040838503121561050d57600080fd5b823567ffffffffffffffff81111561052457600080fd5b61053085828601610426565b92505061053f602084016104d1565b90509250929050565b60006020828403121561055a57600080fd5b813567ffffffffffffffff81111561057157600080fd5b61057d84828501610426565b949350505050565b60006020828403121561059757600080fd5b6105a0826104d1565b9392505050565b6000825160005b818110156105c857602081860181015185830152016105ae565b818111156105d7576000828501525b50919091019291505056fea164736f6c634300080f000a", + "deployedCode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046104fa565b610106565b6100906100da366004610548565b6101d9565b6100746100ed366004610585565b610215565b6100fa6102d1565b6101046000610352565b565b61010e6102d1565b6000610119836103c7565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff00000000000000000000000000000000000000008316179092559151929350169061017c9085906105a7565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006101e8846103c7565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b61021d6102d1565b73ffffffffffffffffffffffffffffffffffffffff81166102c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102ce81610352565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102bc565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016103da91906105a7565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261043757600080fd5b813567ffffffffffffffff80821115610452576104526103f7565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610498576104986103f7565b816040528381528660208588010111156104b157600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b919050565b6000806040838503121561050d57600080fd5b823567ffffffffffffffff81111561052457600080fd5b61053085828601610426565b92505061053f602084016104d1565b90509250929050565b60006020828403121561055a57600080fd5b813567ffffffffffffffff81111561057157600080fd5b61057d84828501610426565b949350505050565b60006020828403121561059757600080fd5b6105a0826104d1565b9392505050565b6000825160005b818110156105c857602081860181015185830152016105ae565b818111156105d7576000828501525b50919091019291505056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": true, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x60806040523480156200001157600080fd5b5060405162001a5f38038062001a5f8339810160408190526200003491620000a1565b6200003f3362000051565b6200004a8162000051565b50620000d3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208284031215620000b457600080fd5b81516001600160a01b0381168114620000cc57600080fd5b9392505050565b61197c80620000e36000396000f3fe60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "deployedCode": "0x60806040526004361061010e5760003560e01c8063860f7cda116100a557806399a88ec411610074578063b794726211610059578063b794726214610329578063f2fde38b14610364578063f3b7dead1461038457600080fd5b806399a88ec4146102e95780639b2ea4bd1461030957600080fd5b8063860f7cda1461026b5780638d52d4a01461028b5780638da5cb5b146102ab5780639623609d146102d657600080fd5b80633ab76e9f116100e15780633ab76e9f146101cc5780636bd9f516146101f9578063715018a6146102365780637eff275e1461024b57600080fd5b80630652b57a1461011357806307c8f7b014610135578063204e1c7a14610155578063238181ae1461019f575b600080fd5b34801561011f57600080fd5b5061013361012e3660046111f9565b6103a4565b005b34801561014157600080fd5b50610133610150366004611216565b6103f3565b34801561016157600080fd5b506101756101703660046111f9565b610445565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101ab57600080fd5b506101bf6101ba3660046111f9565b61066b565b60405161019691906112ae565b3480156101d857600080fd5b506003546101759073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020557600080fd5b506102296102143660046111f9565b60016020526000908152604090205460ff1681565b60405161019691906112f0565b34801561024257600080fd5b50610133610705565b34801561025757600080fd5b50610133610266366004611331565b610719565b34801561027757600080fd5b5061013361028636600461148c565b6108cc565b34801561029757600080fd5b506101336102a63660046114dc565b610903565b3480156102b757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610175565b6101336102e436600461150e565b610977565b3480156102f557600080fd5b50610133610304366004611331565b610b8e565b34801561031557600080fd5b50610133610324366004611584565b610e1e565b34801561033557600080fd5b5060035474010000000000000000000000000000000000000000900460ff166040519015158152602001610196565b34801561037057600080fd5b5061013361037f3660046111f9565b610eb4565b34801561039057600080fd5b5061017561039f3660046111f9565b610f6b565b6103ac6110e1565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103fb6110e1565b6003805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610481576104816112c1565b036104fc578273ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f591906115cb565b9392505050565b6001816002811115610510576105106112c1565b03610560578273ffffffffffffffffffffffffffffffffffffffff1663aaf10f426040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6002816002811115610574576105746112c1565b036105fe5760035473ffffffffffffffffffffffffffffffffffffffff8481166000908152600260205260409081902090517fbf40fac1000000000000000000000000000000000000000000000000000000008152919092169163bf40fac1916105e19190600401611635565b602060405180830381865afa1580156104d1573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f50726f787941646d696e3a20756e6b6e6f776e2070726f78792074797065000060448201526064015b60405180910390fd5b50919050565b60026020526000908152604090208054610684906115e8565b80601f01602080910402602001604051908101604052809291908181526020018280546106b0906115e8565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b505050505081565b61070d6110e1565b6107176000611162565b565b6107216110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff169081600281111561075d5761075d6112c1565b036107e9576040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690638f283970906024015b600060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b50505050505050565b60018160028111156107fd576107fd6112c1565b03610856576040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906313af4035906024016107b2565b600281600281111561086a5761086a6112c1565b036105fe576003546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063f2fde38b906024016107b2565b505050565b6108d46110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090206108c78282611724565b61090b6110e1565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160208190526040909120805483927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091169083600281111561096e5761096e6112c1565b02179055505050565b61097f6110e1565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081205460ff16908160028111156109bb576109bb6112c1565b03610a81576040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851690634f1ef286903490610a16908790879060040161183e565b60006040518083038185885af1158015610a34573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a7b9190810190611875565b50610b88565b610a8b8484610b8e565b60008473ffffffffffffffffffffffffffffffffffffffff163484604051610ab391906118ec565b60006040518083038185875af1925050503d8060008114610af0576040519150601f19603f3d011682016040523d82523d6000602084013e610af5565b606091505b5050905080610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f50726f787941646d696e3a2063616c6c20746f2070726f78792061667465722060448201527f75706772616465206661696c6564000000000000000000000000000000000000606482015260840161065c565b505b50505050565b610b966110e1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604081205460ff1690816002811115610bd257610bd26112c1565b03610c2b576040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152841690633659cfe6906024016107b2565b6001816002811115610c3f57610c3f6112c1565b03610cbe576040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152841690639b0b0fda906044016107b2565b6002816002811115610cd257610cd26112c1565b03610e165773ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604081208054610d07906115e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d33906115e8565b8015610d805780601f10610d5557610100808354040283529160200191610d80565b820191906000526020600020905b815481529060010190602001808311610d6357829003601f168201915b50506003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff1693639b2ea4bd9350610dde92508591508790600401611908565b600060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b5050505050505050565b6108c7611940565b610e266110e1565b6003546040517f9b2ea4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690639b2ea4bd90610e7e9085908590600401611908565b600060405180830381600087803b158015610e9857600080fd5b505af1158015610eac573d6000803e3d6000fd5b505050505050565b610ebc6110e1565b73ffffffffffffffffffffffffffffffffffffffff8116610f5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161065c565b610f6881611162565b50565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081205460ff1681816002811115610fa757610fa76112c1565b03610ff7578273ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600181600281111561100b5761100b6112c1565b0361105b578273ffffffffffffffffffffffffffffffffffffffff1663893d20e86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b600281600281111561106f5761106f6112c1565b036105fe57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161065c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f6857600080fd5b60006020828403121561120b57600080fd5b81356104f5816111d7565b60006020828403121561122857600080fd5b813580151581146104f557600080fd5b60005b8381101561125357818101518382015260200161123b565b83811115610b885750506000910152565b6000815180845261127c816020860160208601611238565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104f56020830184611264565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061132b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561134457600080fd5b823561134f816111d7565b9150602083013561135f816111d7565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156113e0576113e061136a565b604052919050565b600067ffffffffffffffff8211156114025761140261136a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061144161143c846113e8565b611399565b905082815283838301111561145557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261147d57600080fd5b6104f58383356020850161142e565b6000806040838503121561149f57600080fd5b82356114aa816111d7565b9150602083013567ffffffffffffffff8111156114c657600080fd5b6114d28582860161146c565b9150509250929050565b600080604083850312156114ef57600080fd5b82356114fa816111d7565b915060208301356003811061135f57600080fd5b60008060006060848603121561152357600080fd5b833561152e816111d7565b9250602084013561153e816111d7565b9150604084013567ffffffffffffffff81111561155a57600080fd5b8401601f8101861361156b57600080fd5b61157a8682356020840161142e565b9150509250925092565b6000806040838503121561159757600080fd5b823567ffffffffffffffff8111156115ae57600080fd5b6115ba8582860161146c565b925050602083013561135f816111d7565b6000602082840312156115dd57600080fd5b81516104f5816111d7565b600181811c908216806115fc57607f821691505b602082108103610665577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611649816115e8565b8084870152604060018084166000811461166a57600181146116a2576116d0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506116d0565b896000528660002060005b858110156116c85781548b82018601529083019088016116ad565b8a0184019650505b509398975050505050505050565b601f8211156108c757600081815260208120601f850160051c810160208610156117055750805b601f850160051c820191505b81811015610eac57828155600101611711565b815167ffffffffffffffff81111561173e5761173e61136a565b6117528161174c84546115e8565b846116de565b602080601f8311600181146117a5576000841561176f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610eac565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156117f2578886015182559484019460019091019084016117d3565b508582101561182e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061186d6040830184611264565b949350505050565b60006020828403121561188757600080fd5b815167ffffffffffffffff81111561189e57600080fd5b8201601f810184136118af57600080fd5b80516118bd61143c826113e8565b8181528560208385010111156118d257600080fd5b6118e3826020830160208601611238565b95945050505050565b600082516118fe818460208701611238565b9190910192915050565b60408152600061191b6040830185611264565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": true, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": true, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x3ab76e9f", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0652b57a000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": true, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x3ab76e9f", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf2fde38b0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": true, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": true, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x60806040523480156200001157600080fd5b506200001f60008062000025565b62000361565b600054610100900460ff1615808015620000465750600054600160ff909116105b8062000076575062000063306200019460201b620005fd1760201c565b15801562000076575060005460ff166001145b620000de5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff19166001179055801562000102576000805461ff0019166101001790555b6200010d83620001a3565b81156200014857604080518082019091526012815271125b9a5d1a585b1a5e995c881c185d5cd95960721b6020820152620001489062000248565b80156200018f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b620001e9620001d460017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69620002cf565b60001b82620002cb60201b620006191760201c565b6000604080516001600160a01b03841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb910160408051601f19818403018152908290526200023d9162000345565b60405180910390a250565b6200028f6200027960017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7620002cf565b60001b6001620002cb60201b620006191760201c565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea2838181604051620002c0919062000345565b60405180910390a150565b9055565b600082821015620002f057634e487b7160e01b600052601160045260246000fd5b500390565b6000815180845260005b818110156200031d57602081850181015186830182015201620002ff565b8181111562000330576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006200035a6020830184620002f5565b9392505050565b61096b80620003716000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", + "deployedCode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c80635c975abb1161005b5780635c975abb146101255780636da663551461013d5780637fbf7b6a14610150578063c23a451a1461016657600080fd5b80633f4ba83a1461008d578063400ada7514610097578063452a9320146100aa57806354fd4d50146100dc575b600080fd5b61009561016e565b005b6100956100a5366004610746565b610294565b6100b261046d565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101186040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516100d39190610808565b61012d6104a6565b60405190151581526020016100d3565b61009561014b366004610851565b6104d6565b6101586105a4565b6040519081526020016100d3565b6101586105d2565b61017661046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e20756e706175736500000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61026961026360017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60009055565b6040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600054610100900460ff16158080156102b45750600054600160ff909116105b806102ce5750303b1580156102ce575060005460ff166001145b61035a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161022c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156103b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6103c18361061d565b8115610405576104056040518060400160405280601281526020017f496e697469616c697a65722070617573656400000000000000000000000000008152506106d8565b801561046857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006104a161049d60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b5490565b905090565b60006104a161049d60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b6104de61046d565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f5375706572636861696e436f6e6669673a206f6e6c7920677561726469616e2060448201527f63616e2070617573650000000000000000000000000000000000000000000000606482015260840161022c565b6105a1816106d8565b50565b6105cf60017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b81565b6105cf60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b61065061064b60017fd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe69610920565b829055565b60006040805173ffffffffffffffffffffffffffffffffffffffff841660208201527f7b743789cff01dafdeae47739925425aab5dfd02d0c8229e4a508bcd2b9f42bb9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526106cd91610808565b60405180910390a250565b61070c61070660017f54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b7610920565b60019055565b7fc32e6d5d6d1de257f64eac19ddb1f700ba13527983849c9486b1ab007ea283818160405161073b9190610808565b60405180910390a150565b6000806040838503121561075957600080fd5b823573ffffffffffffffffffffffffffffffffffffffff8116811461077d57600080fd5b91506020830135801515811461079257600080fd5b809150509250929050565b6000815180845260005b818110156107c3576020818501810151868301820152016107a7565b818111156107d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061081b602083018461079d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561086357600080fd5b813567ffffffffffffffff8082111561087b57600080fd5b818401915084601f83011261088f57600080fd5b8135818111156108a1576108a1610822565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108e7576108e7610822565b8160405282815287602084870101111561090057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600082821015610959577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" + }, + { + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x452a9320", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xfa60f9b2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044400ada750000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044400ada750000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" + } + ], + "value": 0 + }, + { + "accessor": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9623609d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044400ada750000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x070dca21862da24de5bcba7acd697f207bda1c8caae3812d68f0baee0dd32f38" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x4f1ef286000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000044400ada750000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": true, + "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x400ada750000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": true, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" + }, + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xfa60f9b2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x452a9320", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x452a9320", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x5c975abb", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x5c975abb", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b6" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": true, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x60806040523480156200001157600080fd5b506200002261dead60008062000028565b6200051c565b600054610100900460ff1615808015620000495750600054600160ff909116105b8062000079575062000066306200017e60201b6200053f1760201c565b15801562000079575060005460ff166001145b620000e25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000106576000805461ff0019166101001790555b620001106200018d565b6200011b84620001f5565b620001268362000274565b620001318262000324565b801562000178576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff16620001e95760405162461bcd60e51b815260206004820152602b602482015260008051602062000f4f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d9565b620001f362000385565b565b620001ff620003ec565b6001600160a01b038116620002665760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620000d9565b620002718162000448565b50565b620002ba620002a560017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16200049e565b60001b826200049a60201b6200055b1760201c565b600081604051602001620002d091815260200190565b60408051601f19818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051620003189190620004c4565b60405180910390a35050565b62000355620002a560017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6200049e565b6000816040516020016200036b91815260200190565b60408051601f1981840301815291905290506001620002e5565b600054610100900460ff16620003e15760405162461bcd60e51b815260206004820152602b602482015260008051602062000f4f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000d9565b620001f33362000448565b6033546001600160a01b03163314620001f35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000d9565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b9055565b600082821015620004bf57634e487b7160e01b600052601160045260246000fd5b500390565b600060208083528351808285015260005b81811015620004f357858101830151858201604001528201620004d5565b8181111562000506576000604083870101525b50601f01601f1916929092016040019392505050565b610a23806200052c6000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069", + "deployedCode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e73660046108c3565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101009190610947565b6100ec6101603660046108c3565b61021d565b6100ec61022e565b6100ec61017b36600461098a565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103f7565b6100f6610430565b6100ec6101c63660046109bd565b610460565b6100f6610514565b6100f6600081565b6101e361055f565b6101ec816105e0565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b81565b61022561055f565b6101ec81610698565b61023661055f565b6102406000610712565b565b600054610100900460ff16158080156102625750600054600160ff909116105b8061027c5750303b15801561027c575060005460ff166001145b61030d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561036b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610373610789565b61037c84610460565b610385836105e0565b61038e82610698565b80156103f157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b600061042b61042760017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b5490565b905090565b600061042b61042760017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b61046861055f565b73ffffffffffffffffffffffffffffffffffffffff811661050b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610304565b6101ec81610712565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610304565b61061361060e60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace16109d8565b829055565b60008160405160200161062891815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161068c9190610947565b60405180910390a35050565b6106c661060e60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b6109d8565b6000816040516020016106db91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600161065b565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b610240600054610100900460ff166108ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610304565b61024033610712565b6000602082840312156108d557600080fd5b5035919050565b6000815180845260005b81811015610902576020818501810151868301820152016108e6565b81811115610914576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061095a60208301846108dc565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461098557600080fd5b919050565b60008060006060848603121561099f57600080fd5b6109a884610961565b95602085013595506040909401359392505050565b6000602082840312156109cf57600080fd5b61095a82610961565b600082821015610a11577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": true, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace0" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1a" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "previousValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xdc8452cd", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace0" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xd798b1ac", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1a" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xd2354f20", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000000d" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x38c27159", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000003a" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x67cef446", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000003b" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000416c42991d05b31e9a6dc209e91ad22b79d87ae6000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000647a1ac61e0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000416c42991d05b31e9a6dc209e91ad22b79d87ae6000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000647a1ac61e0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" + } + ], + "value": 0 + }, + { + "accessor": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9623609d000000000000000000000000416c42991d05b31e9a6dc209e91ad22b79d87ae6000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000647a1ac61e0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x9d54a4eb6e745ee152f323ba7a05534bbe68629624a74c9623b7903663b002cf" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x4f1ef286000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000647a1ac61e0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": true, + "newValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x7a1ac61e0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": true, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": true, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace0" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1a" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", + "previousValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xd2354f20", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000000d" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", + "previousValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x38c27159", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000003a" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xdc8452cd", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", + "previousValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xdc8452cd", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace0" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x67cef446", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000003b" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xd798b1ac", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", + "previousValue": "0x000000000000000000000000fbfd64a6c0257f613fefce050aa30ecc3e3d7c3f", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xfbfD64a6C0257F613feFCe050Aa30ecC3E3d7C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xd798b1ac", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x416C42991d05b31E9A6dC209e91AD22b79D87Ae6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1a" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": true, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8B71b41D4dBEb2b6821d44692d3fACAAf77480Bb", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x8B71b41D4dBEb2b6821d44692d3fACAAf77480Bb", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0x8B71b41D4dBEb2b6821d44692d3fACAAf77480Bb", + "isWrite": true, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b50604051610a44380380610a4483398101604081905261002f9161005d565b610057817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b5061008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b6109a88061009c6000396000f3fe60806040526004361061005e5760003560e01c8063893d20e811610043578063893d20e8146100b55780639b0b0fda146100f3578063aaf10f42146101135761006d565b806313af4035146100755780636c5d4ad0146100955761006d565b3661006d5761006b610128565b005b61006b610128565b34801561008157600080fd5b5061006b6100903660046107a2565b6103cb565b3480156100a157600080fd5b5061006b6100b036600461080e565b61045c565b3480156100c157600080fd5b506100ca610611565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ff57600080fd5b5061006b61010e3660046108dd565b6106a8565b34801561011f57600080fd5b506100ca610716565b60006101527fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb7947262000000000000000000000000000000000000000000000000000000001790529051919250600091829173ffffffffffffffffffffffffffffffffffffffff8516916101d4919061093a565b600060405180830381855afa9150503d806000811461020f576040519150601f19603f3d011682016040523d82523d6000602084013e610214565b606091505b5091509150818015610227575080516020145b156102d9576000818060200190518101906102429190610946565b905080156102d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d2069732063757260448201527f72656e746c79206265696e67207570677261646564000000000000000000000060648201526084015b60405180910390fd5b505b60006103037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166103a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201527f6e206973206e6f7420736574207965740000000000000000000000000000000060648201526084016102ce565b3660008037600080366000845af43d6000803e806103c5573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610424575033155b1561045457610451817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b50565b610451610128565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104b5575033155b156104545760006104e47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b9050803f82516020840120036104f8575050565b60405160009061052e907f600d380380600d6000396000f30000000000000000000000000000000000000090859060200161095f565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146105e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527f636f72726563746c79206465706c6f796564000000000000000000000000000060648201526084016102ce565b61060b817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50505050565b600061063b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610672575033155b1561069d57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6106a5610128565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610701575033155b1561070a579055565b610712610128565b5050565b60006107407fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610777575033155b1561069d57507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000602082840312156107b457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146107d857600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561082057600080fd5b813567ffffffffffffffff8082111561083857600080fd5b818401915084601f83011261084c57600080fd5b81358181111561085e5761085e6107df565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108a4576108a46107df565b816040528281528760208487010111156108bd57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156108f057600080fd5b50508035926020909101359150565b6000815160005b818110156109205760208185018101518683015201610906565b8181111561092f576000828601525b509290920192915050565b60006107d882846108ff565b60006020828403121561095857600080fd5b5051919050565b7fffffffffffffffffffffffffff00000000000000000000000000000000000000831681526000610993600d8301846108ff565b94935050505056fea164736f6c634300080f000a000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "deployedCode": "0x60806040526004361061005e5760003560e01c8063893d20e811610043578063893d20e8146100b55780639b0b0fda146100f3578063aaf10f42146101135761006d565b806313af4035146100755780636c5d4ad0146100955761006d565b3661006d5761006b610128565b005b61006b610128565b34801561008157600080fd5b5061006b6100903660046107a2565b6103cb565b3480156100a157600080fd5b5061006b6100b036600461080e565b61045c565b3480156100c157600080fd5b506100ca610611565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ff57600080fd5b5061006b61010e3660046108dd565b6106a8565b34801561011f57600080fd5b506100ca610716565b60006101527fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb7947262000000000000000000000000000000000000000000000000000000001790529051919250600091829173ffffffffffffffffffffffffffffffffffffffff8516916101d4919061093a565b600060405180830381855afa9150503d806000811461020f576040519150601f19603f3d011682016040523d82523d6000602084013e610214565b606091505b5091509150818015610227575080516020145b156102d9576000818060200190518101906102429190610946565b905080156102d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d2069732063757260448201527f72656e746c79206265696e67207570677261646564000000000000000000000060648201526084015b60405180910390fd5b505b60006103037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166103a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201527f6e206973206e6f7420736574207965740000000000000000000000000000000060648201526084016102ce565b3660008037600080366000845af43d6000803e806103c5573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610424575033155b1561045457610451817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b50565b610451610128565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104b5575033155b156104545760006104e47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b9050803f82516020840120036104f8575050565b60405160009061052e907f600d380380600d6000396000f30000000000000000000000000000000000000090859060200161095f565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146105e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527f636f72726563746c79206465706c6f796564000000000000000000000000000060648201526084016102ce565b61060b817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50505050565b600061063b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610672575033155b1561069d57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6106a5610128565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610701575033155b1561070a579055565b610712610128565b5050565b60006107407fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610777575033155b1561069d57507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000602082840312156107b457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146107d857600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561082057600080fd5b813567ffffffffffffffff8082111561083857600080fd5b818401915084601f83011261084c57600080fd5b81358181111561085e5761085e6107df565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108a4576108a46107df565b816040528281528760208487010111156108bd57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156108f057600080fd5b50508035926020909101359150565b6000815160005b818110156109205760208185018101518683015201610906565b8181111561092f576000828601525b509290920192915050565b60006107d882846108ff565b60006020828403121561095857600080fd5b5051919050565b7fffffffffffffffffffffffffff00000000000000000000000000000000000000831681526000610993600d8301846108ff565b94935050505056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": true, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b506040516105f03803806105f083398101604081905261002f91610088565b30600090815260016020908152604080832080546001600160a01b0319166001600160a01b03871617905590829052902061006a8282610203565b5050506102c2565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561009b57600080fd5b82516001600160a01b03811681146100b257600080fd5b602084810151919350906001600160401b03808211156100d157600080fd5b818601915086601f8301126100e557600080fd5b8151818111156100f7576100f7610072565b604051601f8201601f19908116603f0116810190838211818310171561011f5761011f610072565b81604052828152898684870101111561013757600080fd5b600093505b82841015610159578484018601518185018701529285019261013c565b8284111561016a5760008684830101525b8096505050505050509250929050565b600181811c9082168061018e57607f821691505b6020821081036101ae57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156101fe57600081815260208120601f850160051c810160208610156101db5750805b601f850160051c820191505b818110156101fa578281556001016101e7565b5050505b505050565b81516001600160401b0381111561021c5761021c610072565b6102308161022a845461017a565b846101b4565b602080601f831160018114610265576000841561024d5750858301515b600019600386901b1c1916600185901b1785556101fa565b600085815260208120601f198616915b8281101561029457888601518255948401946001909101908401610275565b50858210156102b25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61031f806102d16000396000f3fe608060408181523060009081526001602090815282822054908290529181207fbf40fac1000000000000000000000000000000000000000000000000000000009093529173ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061006d9060846101e2565b602060405180830381865afa15801561008a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ae91906102c5565b905073ffffffffffffffffffffffffffffffffffffffff8116610157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f5265736f6c76656444656c656761746550726f78793a2074617267657420616460448201527f6472657373206d75737420626520696e697469616c697a656400000000000000606482015260840160405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff16600036604051610182929190610302565b600060405180830381855af49150503d80600081146101bd576040519150601f19603f3d011682016040523d82523d6000602084013e6101c2565b606091505b5090925090508115156001036101da57805160208201f35b805160208201fd5b600060208083526000845481600182811c91508083168061020457607f831692505b858310810361023a577f4e487b710000000000000000000000000000000000000000000000000000000085526022600452602485fd5b878601838152602001818015610257576001811461028b576102b6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616825284151560051b820196506102b6565b60008b81526020902060005b868110156102b057815484820152908501908901610297565b83019750505b50949998505050505050505050565b6000602082840312156102d757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146102fb57600080fd5b9392505050565b818382376000910190815291905056fea164736f6c634300080f000a000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c30000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", + "deployedCode": "0x608060408181523060009081526001602090815282822054908290529181207fbf40fac1000000000000000000000000000000000000000000000000000000009093529173ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061006d9060846101e2565b602060405180830381865afa15801561008a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ae91906102c5565b905073ffffffffffffffffffffffffffffffffffffffff8116610157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f5265736f6c76656444656c656761746550726f78793a2074617267657420616460448201527f6472657373206d75737420626520696e697469616c697a656400000000000000606482015260840160405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff16600036604051610182929190610302565b600060405180830381855af49150503d80600081146101bd576040519150601f19603f3d011682016040523d82523d6000602084013e6101c2565b606091505b5090925090508115156001036101da57805160208201f35b805160208201fd5b600060208083526000845481600182811c91508083168061020457607f831692505b858310810361023a577f4e487b710000000000000000000000000000000000000000000000000000000085526022600452602485fd5b878601838152602001818015610257576001811461028b576102b6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616825284151560051b820196506102b6565b60008b81526020902060005b868110156102b057815484820152908501908901610297565b83019750505b50949998505050505050505050565b6000602082840312156102d757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff811681146102fb57600080fd5b9392505050565b818382376000910190815291905056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": true, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4505be7acf20898edfef2b5289635349881ad9bf4b57316a74e81e2abec2be52" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": true, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4505be7acf20898edfef2b5289635349881ad9bf4b57316a74e81e2abec2be52" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x608060405234801561001057600080fd5b5060405161091f38038061091f83398101604081905261002f916100b5565b6100388161003e565b506100e5565b60006100566000805160206108ff8339815191525490565b6000805160206108ff833981519152838155604080516001600160a01b0380851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b6000602082840312156100c757600080fd5b81516001600160a01b03811681146100de57600080fd5b9392505050565b61080b806100f46000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "deployedCode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106dd565b610224565b6100a86100a33660046106f8565b610296565b6040516100b5919061077b565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106dd565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ee565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060c565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81815560405173ffffffffffffffffffffffffffffffffffffffff8316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b60006106367fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038381556040805173ffffffffffffffffffffffffffffffffffffffff80851682528616602082015292935090917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a1505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d857600080fd5b919050565b6000602082840312156106ef57600080fd5b610412826106b4565b60008060006040848603121561070d57600080fd5b610716846106b4565b9250602084013567ffffffffffffffff8082111561073357600080fd5b818601915086601f83011261074757600080fd5b81358181111561075657600080fd5b87602082850101111561076857600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a85785810183015185820160400152820161078c565b818111156107ba576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": true, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf2fde38b000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": true, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x0000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f38", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x60806040523480156200001157600080fd5b50620000206000808062000026565b6200028f565b600054610100900460ff1615808015620000475750600054600160ff909116105b806200007757506200006430620001c160201b62001b741760201c565b15801562000077575060005460ff166001145b620000e05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000104576000805461ff0019166101001790555b603680546001600160a01b03199081166001600160a01b03878116919091179092556037805490911685831617905560358054610100600160a81b03191661010085841602179055603254166200016a57603280546001600160a01b03191661dead1790555b62000174620001d0565b8015620001bb576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff166200023d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d7565b600154600160c01b90046001600160401b03166000036200028d5760408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b02176001555b565b6153ed806200029f6000396000f3fe6080604052600436106101625760003560e01c80638c3152e9116100c0578063c0c53b8b11610074578063e965084c11610059578063e965084c146104c7578063e9e05c4214610553578063f04987501461056657600080fd5b8063c0c53b8b14610406578063cff0ab961461042657600080fd5b80639bf62d82116100a55780639bf62d8214610370578063a14238e71461039d578063a35d99df146103cd57600080fd5b80638c3152e9146103235780639b5f694a1461034357600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102ee578063724c184c1461030e5780638b4c40b01461018757600080fd5b806354fd4d50146102735780635c975abb146102c957600080fd5b806335e80ab31161014857806335e80ab31461020c578063452a93201461023e5780634870496f1461025357600080fd5b80621c2ff61461018e57806333d7e2bd146101df57600080fd5b36610189576101873334620186a0600060405180602001604052806000815250610591565b005b600080fd5b34801561019a57600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101eb57600080fd5b506037546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021857600080fd5b506035546101b590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024a57600080fd5b506101b561082c565b34801561025f57600080fd5b5061018761026e3660046149b4565b6108c4565b34801561027f57600080fd5b506102bc6040518060400160405280600581526020017f322e352e3000000000000000000000000000000000000000000000000000000081525081565b6040516101d69190614b06565b3480156102d557600080fd5b506102de610ef2565b60405190151581526020016101d6565b3480156102fa57600080fd5b506102de610309366004614b19565b610f85565b34801561031a57600080fd5b506101b5611040565b34801561032f57600080fd5b5061018761033e366004614b32565b61104c565b34801561034f57600080fd5b506036546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037c57600080fd5b506032546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a957600080fd5b506102de6103b8366004614b19565b60336020526000908152604090205460ff1681565b3480156103d957600080fd5b506103ed6103e8366004614b8c565b61190d565b60405167ffffffffffffffff90911681526020016101d6565b34801561041257600080fd5b50610187610421366004614ba7565b611926565b34801561043257600080fd5b5060015461048e906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101d6565b3480156104d357600080fd5b506105256104e2366004614b19565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101d6565b610187610561366004614c00565b610591565b34801561057257600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101b5565b8260005a905083156106485773ffffffffffffffffffffffffffffffffffffffff87161561064857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b610652835161190d565b67ffffffffffffffff168567ffffffffffffffff1610156106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161063f565b6201d4c083511115610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161063f565b33328114610784575033731111000000000000000000000000000000001111015b6000348888888860405160200161079f959493929190614c7d565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161080f9190614b06565b60405180910390a450506108238282611b90565b50505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561089b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190614ce2565b905090565b6108cc610ef2565b15610933576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161063f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161063f565b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a869190614d1f565b519050610aa0610a9b36869003860186614d84565b611ebd565b8114610b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161063f565b6000610b3987611f19565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c4f5750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4b9190614d1f565b5114155b610cdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161063f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610da49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d9a888a614dea565b8a60400135611f49565b610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161063f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f61573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190614e6e565b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161103a9173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610ffb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101f9190614d1f565b602001516fffffffffffffffffffffffffffffffff16611f6d565b92915050565b60006108bf61082c565b565b611054610ef2565b156110bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161063f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14611164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161063f565b600061116f82611f19565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff8082169483018590527001000000000000000000000000000000009091041691810191909152929350900361125a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161063f565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112eb9190614e8b565b81602001516fffffffffffffffffffffffffffffffff1610156113b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161063f565b6113d581602001516fffffffffffffffffffffffffffffffff16611f6d565b611487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161063f565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561150e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115329190614d1f565b82518151919250146115ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161063f565b61160b81602001516fffffffffffffffffffffffffffffffff16611f6d565b6116bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161063f565b60008381526033602052604090205460ff161561175c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161063f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a08801516117fe93929190612013565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061186390841515815260200190565b60405180910390a2801580156118795750326001145b15611906576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161063f565b5050505050565b600061191a826010614ed3565b61103a90615208614f03565b600054610100900460ff16158080156119465750600054600160ff909116105b806119605750303b158015611960575060005460ff166001145b6119ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161063f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611a4a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611b0357603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611b0b612071565b8015611b6e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090611bc6907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f2f565b90506000611bd2612184565b90506000816020015160ff16826000015163ffffffff16611bf39190614f75565b90508215611d2a57600154600090611c2a908390700100000000000000000000000000000000900467ffffffffffffffff16614fdd565b90506000836040015160ff1683611c419190615051565b600154611c619084906fffffffffffffffffffffffffffffffff16615051565b611c6b9190614f75565b600154909150600090611cbc90611c959084906fffffffffffffffffffffffffffffffff1661510d565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612245565b90506001861115611ceb57611ce8611c9582876040015160ff1660018a611ce39190614f2f565b612264565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611d5d908490700100000000000000000000000000000000900467ffffffffffffffff16614f03565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611e40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161063f565b600154600090611e6c906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615181565b90506000611e7e48633b9aca006122b9565b611e8890836151be565b905060005a611e979088614f2f565b905080821115611eb357611eb3611eae8284614f2f565b6122d0565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611efc949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611efc9790969591016151d2565b600080611f55866122fe565b9050611f6381868686612330565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa158015611fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120019190614e8b565b61200b9083615229565b421192915050565b6000806000612023866000612360565b905080612059576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff16612108576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161063f565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361104a5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612221573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190615266565b600061225a612254858561237e565b8361238e565b90505b9392505050565b6000670de0b6b3a76400006122a561227c8583614f75565b61228e90670de0b6b3a7640000614fdd565b6122a085670de0b6b3a7640000615051565b61239d565b6122af9086615051565b61225a9190614f75565b6000818310156122c9578161225d565b5090919050565b6000805a90505b825a6122e39083614f2f565b10156122f9576122f282615305565b91506122d7565b505050565b6060818051906020012060405160200161231a91815260200190565b6040516020818303038152906040529050919050565b6000612357846123418786866123ce565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156122c9578161225d565b60008183126122c9578161225d565b600061225d670de0b6b3a7640000836123b586612e4c565b6123bf9190615051565b6123c99190614f75565b613090565b6060600084511161243b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161063f565b6000612446846132cf565b90506000612453866133bb565b905060008460405160200161246a91815260200190565b60405160208183030381529060405290506000805b8451811015612dc357600085828151811061249c5761249c61533d565b602002602001015190508451831115612537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161063f565b826000036125f057805180516020918201206040516125859261255f92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6125eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161063f565b612747565b8051516020116126a6578051805160209182012060405161261a9261255f92910190815260200190565b6125eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161063f565b805184516020808701919091208251919092012014612747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161063f565b61275360106001615229565b8160200151510361292f57845183036128c75761278d81602001516010815181106127805761278061533d565b602002602001015161341e565b96506000875111612820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161063f565b6001865161282e9190614f2f565b82146128bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161063f565b50505050505061225d565b60008584815181106128db576128db61533d565b602001015160f81c60f81b60f81c9050600082602001518260ff16815181106129065761290661533d565b602002602001015190506129198161357e565b9550612926600186615229565b94505050612db0565b600281602001515103612d28576000612947826135a3565b905060008160008151811061295e5761295e61533d565b016020015160f81c9050600061297560028361536c565b61298090600261538e565b90506000612991848360ff166135c7565b9050600061299f8a896135c7565b905060006129ad83836135fd565b905080835114612a3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161063f565b60ff851660021480612a54575060ff85166003145b15612c435780825114612ae9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161063f565b612b0387602001516001815181106127805761278061533d565b9c5060008d5111612b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161063f565b60018c51612ba49190614f2f565b8814612c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161063f565b50505050505050505050505061225d565b60ff85161580612c56575060ff85166001145b15612c9557612c828760200151600181518110612c7557612c7561533d565b602002602001015161357e565b9950612c8e818a615229565b9850612d1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161063f565b505050505050612db0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161063f565b5080612dbb81615305565b91505061247f565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161063f565b6000808213612eb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161063f565b60006060612ec4846136b1565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136130c157506000919050565b680755bf798b4a1bf1e58212613133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161063f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156132ed576132ed6147d4565b60405190808252806020026020018201604052801561333257816020015b604080518082019091526060808252602082015281526020019060019003908161330b5790505b50915060005b818110156133b457604051806040016040528085838151811061335d5761335d61533d565b6020026020010151815260200161338c86848151811061337f5761337f61533d565b6020026020010151613787565b8152508382815181106133a1576133a161533d565b6020908102919091010152600101613338565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613413578060011b82018184015160001a8060041c8253600f8116600183015350506001016133e5565b509295945050505050565b6060600080600061342e8561379a565b919450925090506000816001811115613449576134496153b1565b146134d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161063f565b6134e08284615229565b85511461356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161063f565b61235785602001518484614207565b6060602082600001511061359a576135958261341e565b61103a565b61103a8261429b565b606061103a6135c283602001516000815181106127805761278061533d565b6133bb565b6060825182106135e6575060408051602081019091526000815261103a565b61225d83838486516135f89190614f2f565b6142b1565b6000808251845110613610578251613613565b83515b90505b808210801561369a57508282815181106136325761363261533d565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106136715761367161533d565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156136aa57816001019150613616565b5092915050565b600080821161371c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161063f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061103a61379583614489565b614572565b600080600080846000015111613858576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161063f565b6020840151805160001a607f811161387d576000600160009450945094505050614200565b60b78111613a8b576000613892608083614f2f565b90508087600001511161394d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161063f565b6001838101517fff000000000000000000000000000000000000000000000000000000000000001690821415806139c657507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613a78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161063f565b5060019550935060009250614200915050565b60bf8111613dd9576000613aa060b783614f2f565b905080876000015111613b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161063f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613c39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161063f565b600184015160088302610100031c60378111613cfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161063f565b613d078184615229565b895111613dbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161063f565b613dc7836001615229565b97509550600094506142009350505050565b60f78111613eba576000613dee60c083614f2f565b905080876000015111613ea9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161063f565b600195509350849250614200915050565b6000613ec760f783614f2f565b905080876000015111613f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161063f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161063f565b600184015160088302610100031c60378111614124576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161063f565b61412e8184615229565b8951116141e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161063f565b6141ee836001615229565b97509550600194506142009350505050565b9193909250565b60608167ffffffffffffffff811115614222576142226147d4565b6040519080825280601f01601f19166020018201604052801561424c576020820181803683370190505b509050811561225d5760006142618486615229565b90506020820160005b8481101561428257828101518282015260200161426a565b84811115614291576000858301525b5050509392505050565b606061103a826020015160008460000151614207565b60608182601f011015614320576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161063f565b82828401101561438c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161063f565b818301845110156143f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161063f565b6060821580156144185760405191506000825260208201604052614480565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614451578051835260209283019201614439565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201526000825111614554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161063f565b50604080518082019091528151815260209182019181019190915290565b606060008060006145828561379a565b91945092509050600181600181111561459d5761459d6153b1565b1461462a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161063f565b84516146368385615229565b146146c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161063f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816146da5790505093506000835b86518110156147c85760008061474d6040518060400160405280858c600001516147319190614f2f565b8152602001858c602001516147469190615229565b905261379a565b5091509150604051806040016040528083836147699190615229565b8152602001848b6020015161477e9190615229565b8152508885815181106147935761479361533d565b60209081029190910101526147a9600185615229565b93506147b58183615229565b6147bf9084615229565b92505050614707565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561484a5761484a6147d4565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461487457600080fd5b50565b600082601f83011261488857600080fd5b813567ffffffffffffffff8111156148a2576148a26147d4565b6148d360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614803565b8181528460208386010111156148e857600080fd5b816020850160208301376000918101602001919091529392505050565b600060c0828403121561491757600080fd5b60405160c0810167ffffffffffffffff828210818311171561493b5761493b6147d4565b81604052829350843583526020850135915061495682614852565b8160208401526040850135915061496c82614852565b816040840152606085013560608401526080850135608084015260a085013591508082111561499a57600080fd5b506149a785828601614877565b60a0830152505092915050565b600080600080600085870360e08112156149cd57600080fd5b863567ffffffffffffffff808211156149e557600080fd5b6149f18a838b01614905565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614a2a57600080fd5b60408901955060c0890135925080831115614a4457600080fd5b828901925089601f840112614a5857600080fd5b8235915080821115614a6957600080fd5b508860208260051b8401011115614a7f57600080fd5b959894975092955050506020019190565b60005b83811015614aab578181015183820152602001614a93565b83811115611b6e5750506000910152565b60008151808452614ad4816020860160208601614a90565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225d6020830184614abc565b600060208284031215614b2b57600080fd5b5035919050565b600060208284031215614b4457600080fd5b813567ffffffffffffffff811115614b5b57600080fd5b614b6784828501614905565b949350505050565b803567ffffffffffffffff81168114614b8757600080fd5b919050565b600060208284031215614b9e57600080fd5b61225d82614b6f565b600080600060608486031215614bbc57600080fd5b8335614bc781614852565b92506020840135614bd781614852565b91506040840135614be781614852565b809150509250925092565b801515811461487457600080fd5b600080600080600060a08688031215614c1857600080fd5b8535614c2381614852565b945060208601359350614c3860408701614b6f565b92506060860135614c4881614bf2565b9150608086013567ffffffffffffffff811115614c6457600080fd5b614c7088828901614877565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614cd1816049850160208701614a90565b919091016049019695505050505050565b600060208284031215614cf457600080fd5b815161225d81614852565b80516fffffffffffffffffffffffffffffffff81168114614b8757600080fd5b600060608284031215614d3157600080fd5b6040516060810181811067ffffffffffffffff82111715614d5457614d546147d4565b60405282518152614d6760208401614cff565b6020820152614d7860408401614cff565b60408201529392505050565b600060808284031215614d9657600080fd5b6040516080810181811067ffffffffffffffff82111715614db957614db96147d4565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e0557614e056147d4565b8360051b6020614e16818301614803565b868152918501918181019036841115614e2e57600080fd5b865b84811015614e6257803586811115614e485760008081fd5b614e5436828b01614877565b845250918301918301614e30565b50979650505050505050565b600060208284031215614e8057600080fd5b815161225d81614bf2565b600060208284031215614e9d57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614efa57614efa614ea4565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f2657614f26614ea4565b01949350505050565b600082821015614f4157614f41614ea4565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614f8457614f84614f46565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615614fd857614fd8614ea4565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561501757615017614ea4565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561504b5761504b614ea4565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561509257615092614ea4565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156150cd576150cd614ea4565b600087129250878205871284841616156150e9576150e9614ea4565b878505871281841616156150ff576150ff614ea4565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561514757615147614ea4565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561517b5761517b614ea4565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156151b9576151b9614ea4565b500290565b6000826151cd576151cd614f46565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261521d60c0830184614abc565b98975050505050505050565b6000821982111561523c5761523c614ea4565b500190565b805163ffffffff81168114614b8757600080fd5b805160ff81168114614b8757600080fd5b600060c0828403121561527857600080fd5b60405160c0810181811067ffffffffffffffff8211171561529b5761529b6147d4565b6040526152a783615241565b81526152b560208401615255565b60208201526152c660408401615255565b60408201526152d760608401615241565b60608201526152e860808401615241565b60808201526152f960a08401614cff565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361533657615336614ea4565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061537f5761537f614f46565b8060ff84160691505092915050565b600060ff821660ff8416808210156153a8576153a8614ea4565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", + "deployedCode": "0x6080604052600436106101625760003560e01c80638c3152e9116100c0578063c0c53b8b11610074578063e965084c11610059578063e965084c146104c7578063e9e05c4214610553578063f04987501461056657600080fd5b8063c0c53b8b14610406578063cff0ab961461042657600080fd5b80639bf62d82116100a55780639bf62d8214610370578063a14238e71461039d578063a35d99df146103cd57600080fd5b80638c3152e9146103235780639b5f694a1461034357600080fd5b806354fd4d50116101175780636dbffb78116100fc5780636dbffb78146102ee578063724c184c1461030e5780638b4c40b01461018757600080fd5b806354fd4d50146102735780635c975abb146102c957600080fd5b806335e80ab31161014857806335e80ab31461020c578063452a93201461023e5780634870496f1461025357600080fd5b80621c2ff61461018e57806333d7e2bd146101df57600080fd5b36610189576101873334620186a0600060405180602001604052806000815250610591565b005b600080fd5b34801561019a57600080fd5b5060365473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101eb57600080fd5b506037546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021857600080fd5b506035546101b590610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561024a57600080fd5b506101b561082c565b34801561025f57600080fd5b5061018761026e3660046149b4565b6108c4565b34801561027f57600080fd5b506102bc6040518060400160405280600581526020017f322e352e3000000000000000000000000000000000000000000000000000000081525081565b6040516101d69190614b06565b3480156102d557600080fd5b506102de610ef2565b60405190151581526020016101d6565b3480156102fa57600080fd5b506102de610309366004614b19565b610f85565b34801561031a57600080fd5b506101b5611040565b34801561032f57600080fd5b5061018761033e366004614b32565b61104c565b34801561034f57600080fd5b506036546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b34801561037c57600080fd5b506032546101b59073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a957600080fd5b506102de6103b8366004614b19565b60336020526000908152604090205460ff1681565b3480156103d957600080fd5b506103ed6103e8366004614b8c565b61190d565b60405167ffffffffffffffff90911681526020016101d6565b34801561041257600080fd5b50610187610421366004614ba7565b611926565b34801561043257600080fd5b5060015461048e906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101d6565b3480156104d357600080fd5b506105256104e2366004614b19565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101d6565b610187610561366004614c00565b610591565b34801561057257600080fd5b5060375473ffffffffffffffffffffffffffffffffffffffff166101b5565b8260005a905083156106485773ffffffffffffffffffffffffffffffffffffffff87161561064857604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b610652835161190d565b67ffffffffffffffff168567ffffffffffffffff1610156106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c0000000000000000000000000000000000000000000000000000000000606482015260840161063f565b6201d4c083511115610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c617267650000604482015260640161063f565b33328114610784575033731111000000000000000000000000000000001111015b6000348888888860405160200161079f959493929190614c7d565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c328460405161080f9190614b06565b60405180910390a450506108238282611b90565b50505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561089b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190614ce2565b905090565b6108cc610ef2565b15610933576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161063f565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e747261637400606482015260840161063f565b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810186905260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a869190614d1f565b519050610aa0610a9b36869003860186614d84565b611ebd565b8114610b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f660000000000000000000000000000000000000000000000606482015260840161063f565b6000610b3987611f19565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c4f5750805160365460408084015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4b9190614d1f565b5114155b610cdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e000000000000000000606482015260840161063f565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610da49101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610d9a888a614dea565b8a60400135611f49565b610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f660000000000000000000000000000606482015260840161063f565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6000603560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f61573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190614e6e565b6036546040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810183905260009161103a9173ffffffffffffffffffffffffffffffffffffffff9091169063a25ae55790602401606060405180830381865afa158015610ffb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101f9190614d1f565b602001516fffffffffffffffffffffffffffffffff16611f6d565b92915050565b60006108bf61082c565b565b611054610ef2565b156110bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a2070617573656400000000000000000000604482015260640161063f565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead14611164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e00606482015260840161063f565b600061116f82611f19565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff8082169483018590527001000000000000000000000000000000009091041691810191909152929350900361125a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e207965740000000000000000000000000000606482015260840161063f565b603660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112eb9190614e8b565b81602001516fffffffffffffffffffffffffffffffff1610156113b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a40161063f565b6113d581602001516fffffffffffffffffffffffffffffffff16611f6d565b611487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a40161063f565b60365460408281015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff909116600482015260009173ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa15801561150e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115329190614d1f565b82518151919250146115ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a40161063f565b61160b81602001516fffffffffffffffffffffffffffffffff16611f6d565b6116bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a40161063f565b60008381526033602052604090205460ff161561175c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a65640000000000000000000000606482015260840161063f565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a08801516117fe93929190612013565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061186390841515815260200190565b60405180910390a2801580156118795750326001145b15611906576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161063f565b5050505050565b600061191a826010614ed3565b61103a90615208614f03565b600054610100900460ff16158080156119465750600054600160ff909116105b806119605750303b158015611960575060005460ff166001145b6119ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161063f565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611a4a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603680547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560378054909116858316179055603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101008584160217905560325416611b0357603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b611b0b612071565b8015611b6e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090611bc6907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f2f565b90506000611bd2612184565b90506000816020015160ff16826000015163ffffffff16611bf39190614f75565b90508215611d2a57600154600090611c2a908390700100000000000000000000000000000000900467ffffffffffffffff16614fdd565b90506000836040015160ff1683611c419190615051565b600154611c619084906fffffffffffffffffffffffffffffffff16615051565b611c6b9190614f75565b600154909150600090611cbc90611c959084906fffffffffffffffffffffffffffffffff1661510d565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612245565b90506001861115611ceb57611ce8611c9582876040015160ff1660018a611ce39190614f2f565b612264565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611d5d908490700100000000000000000000000000000000900467ffffffffffffffff16614f03565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611e40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d69740000606482015260840161063f565b600154600090611e6c906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8816615181565b90506000611e7e48633b9aca006122b9565b611e8890836151be565b905060005a611e979088614f2f565b905080821115611eb357611eb3611eae8284614f2f565b6122d0565b5050505050505050565b60008160000151826020015183604001518460600151604051602001611efc949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611efc9790969591016151d2565b600080611f55866122fe565b9050611f6381868686612330565b9695505050505050565b603654604080517ff4daa291000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163f4daa2919160048083019260209291908290030181865afa158015611fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120019190614e8b565b61200b9083615229565b421192915050565b6000806000612023866000612360565b905080612059576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff16612108576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161063f565b6001547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1660000361104a5760408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c08082018352600080835260208301819052828401819052606083018190526080830181905260a083015260375483517fcc731b020000000000000000000000000000000000000000000000000000000081529351929373ffffffffffffffffffffffffffffffffffffffff9091169263cc731b02926004808401939192918290030181865afa158015612221573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190615266565b600061225a612254858561237e565b8361238e565b90505b9392505050565b6000670de0b6b3a76400006122a561227c8583614f75565b61228e90670de0b6b3a7640000614fdd565b6122a085670de0b6b3a7640000615051565b61239d565b6122af9086615051565b61225a9190614f75565b6000818310156122c9578161225d565b5090919050565b6000805a90505b825a6122e39083614f2f565b10156122f9576122f282615305565b91506122d7565b505050565b6060818051906020012060405160200161231a91815260200190565b6040516020818303038152906040529050919050565b6000612357846123418786866123ce565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156122c9578161225d565b60008183126122c9578161225d565b600061225d670de0b6b3a7640000836123b586612e4c565b6123bf9190615051565b6123c99190614f75565b613090565b6060600084511161243b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b65790000000000000000000000604482015260640161063f565b6000612446846132cf565b90506000612453866133bb565b905060008460405160200161246a91815260200190565b60405160208183030381529060405290506000805b8451811015612dc357600085828151811061249c5761249c61533d565b602002602001015190508451831115612537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e677468000000000000000000000000000000000000606482015260840161063f565b826000036125f057805180516020918201206040516125859261255f92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b6125eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f742068617368000000604482015260640161063f565b612747565b8051516020116126a6578051805160209182012060405161261a9261255f92910190815260200190565b6125eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c206861736800000000000000000000000000000000000000000000000000606482015260840161063f565b805184516020808701919091208251919092012014612747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f6520686173680000000000000000000000000000000000000000000000000000606482015260840161063f565b61275360106001615229565b8160200151510361292f57845183036128c75761278d81602001516010815181106127805761278061533d565b602002602001015161341e565b96506000875111612820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e6368290000000000606482015260840161063f565b6001865161282e9190614f2f565b82146128bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e636829000000000000606482015260840161063f565b50505050505061225d565b60008584815181106128db576128db61533d565b602001015160f81c60f81b60f81c9050600082602001518260ff16815181106129065761290661533d565b602002602001015190506129198161357e565b9550612926600186615229565b94505050612db0565b600281602001515103612d28576000612947826135a3565b905060008160008151811061295e5761295e61533d565b016020015160f81c9050600061297560028361536c565b61298090600261538e565b90506000612991848360ff166135c7565b9050600061299f8a896135c7565b905060006129ad83836135fd565b905080835114612a3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b6579000000000000606482015260840161063f565b60ff851660021480612a54575060ff85166003145b15612c435780825114612ae9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e646572000000606482015260840161063f565b612b0387602001516001815181106127805761278061533d565b9c5060008d5111612b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c6561662900000000000000606482015260840161063f565b60018c51612ba49190614f2f565b8814612c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c656166290000000000000000606482015260840161063f565b50505050505050505050505061225d565b60ff85161580612c56575060ff85166001145b15612c9557612c828760200151600181518110612c7557612c7561533d565b602002602001015161357e565b9950612c8e818a615229565b9850612d1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e207072656669780000000000000000000000000000606482015260840161063f565b505050505050612db0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f6465000000000000000000000000000000000000000000000000606482015260840161063f565b5080612dbb81615305565b91505061247f565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e7473000000000000000000000000000000000000000000000000000000606482015260840161063f565b6000808213612eb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161063f565b60006060612ec4846136b1565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136130c157506000919050565b680755bf798b4a1bf1e58212613133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f570000000000000000000000000000000000000000604482015260640161063f565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b80516060908067ffffffffffffffff8111156132ed576132ed6147d4565b60405190808252806020026020018201604052801561333257816020015b604080518082019091526060808252602082015281526020019060019003908161330b5790505b50915060005b818110156133b457604051806040016040528085838151811061335d5761335d61533d565b6020026020010151815260200161338c86848151811061337f5761337f61533d565b6020026020010151613787565b8152508382815181106133a1576133a161533d565b6020908102919091010152600101613338565b5050919050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613413578060011b82018184015160001a8060041c8253600f8116600183015350506001016133e5565b509295945050505050565b6060600080600061342e8561379a565b919450925090506000816001811115613449576134496153b1565b146134d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d00000000000000606482015260840161063f565b6134e08284615229565b85511461356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e646572000000000000000000000000606482015260840161063f565b61235785602001518484614207565b6060602082600001511061359a576135958261341e565b61103a565b61103a8261429b565b606061103a6135c283602001516000815181106127805761278061533d565b6133bb565b6060825182106135e6575060408051602081019091526000815261103a565b61225d83838486516135f89190614f2f565b6142b1565b6000808251845110613610578251613613565b83515b90505b808210801561369a57508282815181106136325761363261533d565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168483815181106136715761367161533d565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156136aa57816001019150613616565b5092915050565b600080821161371c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e45440000000000000000000000000000000000000000000000604482015260640161063f565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061103a61379583614489565b614572565b600080600080846000015111613858576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161063f565b6020840151805160001a607f811161387d576000600160009450945094505050614200565b60b78111613a8b576000613892608083614f2f565b90508087600001511161394d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a40161063f565b6001838101517fff000000000000000000000000000000000000000000000000000000000000001690821415806139c657507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613a78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a40161063f565b5060019550935060009250614200915050565b60bf8111613dd9576000613aa060b783614f2f565b905080876000015111613b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a40161063f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613c39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a40161063f565b600184015160088302610100031c60378111613cfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a40161063f565b613d078184615229565b895111613dbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a40161063f565b613dc7836001615229565b97509550600094506142009350505050565b60f78111613eba576000613dee60c083614f2f565b905080876000015111613ea9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a40161063f565b600195509350849250614200915050565b6000613ec760f783614f2f565b905080876000015111613f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a40161063f565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614060576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a40161063f565b600184015160088302610100031c60378111614124576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a40161063f565b61412e8184615229565b8951116141e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a40161063f565b6141ee836001615229565b97509550600194506142009350505050565b9193909250565b60608167ffffffffffffffff811115614222576142226147d4565b6040519080825280601f01601f19166020018201604052801561424c576020820181803683370190505b509050811561225d5760006142618486615229565b90506020820160005b8481101561428257828101518282015260200161426a565b84811115614291576000858301525b5050509392505050565b606061103a826020015160008460000151614207565b60608182601f011015614320576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161063f565b82828401101561438c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015260640161063f565b818301845110156143f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015260640161063f565b6060821580156144185760405191506000825260208201604052614480565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614451578051835260209283019201614439565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201526000825111614554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a40161063f565b50604080518082019091528151815260209182019181019190915290565b606060008060006145828561379a565b91945092509050600181600181111561459d5761459d6153b1565b1461462a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d0000000000000000606482015260840161063f565b84516146368385615229565b146146c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e6465720000000000000000000000000000606482015260840161063f565b604080516020808252610420820190925290816020015b60408051808201909152600080825260208201528152602001906001900390816146da5790505093506000835b86518110156147c85760008061474d6040518060400160405280858c600001516147319190614f2f565b8152602001858c602001516147469190615229565b905261379a565b5091509150604051806040016040528083836147699190615229565b8152602001848b6020015161477e9190615229565b8152508885815181106147935761479361533d565b60209081029190910101526147a9600185615229565b93506147b58183615229565b6147bf9084615229565b92505050614707565b50845250919392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561484a5761484a6147d4565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461487457600080fd5b50565b600082601f83011261488857600080fd5b813567ffffffffffffffff8111156148a2576148a26147d4565b6148d360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614803565b8181528460208386010111156148e857600080fd5b816020850160208301376000918101602001919091529392505050565b600060c0828403121561491757600080fd5b60405160c0810167ffffffffffffffff828210818311171561493b5761493b6147d4565b81604052829350843583526020850135915061495682614852565b8160208401526040850135915061496c82614852565b816040840152606085013560608401526080850135608084015260a085013591508082111561499a57600080fd5b506149a785828601614877565b60a0830152505092915050565b600080600080600085870360e08112156149cd57600080fd5b863567ffffffffffffffff808211156149e557600080fd5b6149f18a838b01614905565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614a2a57600080fd5b60408901955060c0890135925080831115614a4457600080fd5b828901925089601f840112614a5857600080fd5b8235915080821115614a6957600080fd5b508860208260051b8401011115614a7f57600080fd5b959894975092955050506020019190565b60005b83811015614aab578181015183820152602001614a93565b83811115611b6e5750506000910152565b60008151808452614ad4816020860160208601614a90565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061225d6020830184614abc565b600060208284031215614b2b57600080fd5b5035919050565b600060208284031215614b4457600080fd5b813567ffffffffffffffff811115614b5b57600080fd5b614b6784828501614905565b949350505050565b803567ffffffffffffffff81168114614b8757600080fd5b919050565b600060208284031215614b9e57600080fd5b61225d82614b6f565b600080600060608486031215614bbc57600080fd5b8335614bc781614852565b92506020840135614bd781614852565b91506040840135614be781614852565b809150509250925092565b801515811461487457600080fd5b600080600080600060a08688031215614c1857600080fd5b8535614c2381614852565b945060208601359350614c3860408701614b6f565b92506060860135614c4881614bf2565b9150608086013567ffffffffffffffff811115614c6457600080fd5b614c7088828901614877565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614cd1816049850160208701614a90565b919091016049019695505050505050565b600060208284031215614cf457600080fd5b815161225d81614852565b80516fffffffffffffffffffffffffffffffff81168114614b8757600080fd5b600060608284031215614d3157600080fd5b6040516060810181811067ffffffffffffffff82111715614d5457614d546147d4565b60405282518152614d6760208401614cff565b6020820152614d7860408401614cff565b60408201529392505050565b600060808284031215614d9657600080fd5b6040516080810181811067ffffffffffffffff82111715614db957614db96147d4565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614e0557614e056147d4565b8360051b6020614e16818301614803565b868152918501918181019036841115614e2e57600080fd5b865b84811015614e6257803586811115614e485760008081fd5b614e5436828b01614877565b845250918301918301614e30565b50979650505050505050565b600060208284031215614e8057600080fd5b815161225d81614bf2565b600060208284031215614e9d57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615614efa57614efa614ea4565b02949350505050565b600067ffffffffffffffff808316818516808303821115614f2657614f26614ea4565b01949350505050565b600082821015614f4157614f41614ea4565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614f8457614f84614f46565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615614fd857614fd8614ea4565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561501757615017614ea4565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561504b5761504b614ea4565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561509257615092614ea4565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156150cd576150cd614ea4565b600087129250878205871284841616156150e9576150e9614ea4565b878505871281841616156150ff576150ff614ea4565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561514757615147614ea4565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561517b5761517b614ea4565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156151b9576151b9614ea4565b500290565b6000826151cd576151cd614f46565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261521d60c0830184614abc565b98975050505050505050565b6000821982111561523c5761523c614ea4565b500190565b805163ffffffff81168114614b8757600080fd5b805160ff81168114614b8757600080fd5b600060c0828403121561527857600080fd5b60405160c0810181811067ffffffffffffffff8211171561529b5761529b6147d4565b6040526152a783615241565b81526152b560208401615255565b60208201526152c660408401615255565b60408201526152d760608401615241565b60608201526152e860808401615241565b60808201526152f960a08401614cff565b60a08201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361533657615336614ea4565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061537f5761537f614f46565b8060ff84160691505092915050565b600060ff821660ff8416808210156153a8576153a8614ea4565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": true, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": true, + "newValue": "0x000000000000000100000000000000000000000000000000000000003b9aca00", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xfa60f9b2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": false, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x001c2ff6", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9b5f694a", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf0498750", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x33d7e2bd", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9bf62d82", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "isWrite": false, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "previousValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x60806040523480156200001157600080fd5b506200001f60008062000025565b6200027f565b600054600160a81b900460ff16158080156200004e57506000546001600160a01b90910460ff16105b806200008557506200006b30620001b960201b620014d61760201c565b158015620000855750600054600160a01b900460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff60a01b1916600160a01b17905580156200011c576000805460ff60a81b1916600160a81b1790555b60fb80546001600160a01b038086166001600160a01b03199283161790925560fc8054928516929091169190911790556200016b734200000000000000000000000000000000000007620001c8565b8015620001b4576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054600160a81b900460ff16620002375760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60cc546001600160a01b03166200025d5760cc80546001600160a01b03191661dead1790555b60cf80546001600160a01b0319166001600160a01b0392909216919091179055565b611f94806200028f6000396000f3fe6080604052600436106101805760003560e01c80635c975abb116100d6578063a4e7f8bd1161007f578063d764ad0b11610059578063d764ad0b14610463578063db505d8014610476578063ecc70428146104a357600080fd5b8063a4e7f8bd146103e3578063b1b1b20914610413578063b28ade251461044357600080fd5b806383a74074116100b057806383a74074146103a15780638cbeeef2146102b85780639fce812c146103b857600080fd5b80635c975abb1461033a5780636425666b1461035f5780636e296e451461038c57600080fd5b80633dbb202b116101385780634c1d6a69116101125780634c1d6a69146102b857806354fd4d50146102ce5780635644cfdf1461032457600080fd5b80633dbb202b1461025b5780633f827a5a14610270578063485cc9551461029857600080fd5b80630ff754ea116101695780630ff754ea146101cd5780632828d7e81461021957806335e80ab31461022e57600080fd5b8063028f85f7146101855780630c568498146101b8575b600080fd5b34801561019157600080fd5b5061019a601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101c457600080fd5b5061019a603f81565b3480156101d957600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101af565b34801561022557600080fd5b5061019a604081565b34801561023a57600080fd5b5060fb546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b61026e610269366004611a22565b610508565b005b34801561027c57600080fd5b50610285600181565b60405161ffff90911681526020016101af565b3480156102a457600080fd5b5061026e6102b3366004611a89565b610765565b3480156102c457600080fd5b5061019a619c4081565b3480156102da57600080fd5b506103176040518060400160405280600581526020017f322e332e3000000000000000000000000000000000000000000000000000000081525081565b6040516101af9190611b2d565b34801561033057600080fd5b5061019a61138881565b34801561034657600080fd5b5061034f6109d3565b60405190151581526020016101af565b34801561036b57600080fd5b5060fc546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b34801561039857600080fd5b506101f4610a6c565b3480156103ad57600080fd5b5061019a62030d4081565b3480156103c457600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101f4565b3480156103ef57600080fd5b5061034f6103fe366004611b47565b60ce6020526000908152604090205460ff1681565b34801561041f57600080fd5b5061034f61042e366004611b47565b60cb6020526000908152604090205460ff1681565b34801561044f57600080fd5b5061019a61045e366004611b60565b610b53565b61026e610471366004611bb4565b610bc1565b34801561048257600080fd5b5060cf546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104af57600080fd5b506104fa60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101af565b60cf5461063a9073ffffffffffffffffffffffffffffffffffffffff16610530858585610b53565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061059c60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016105b89796959493929190611c83565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526114f2565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856106bf60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516106d1959493929190611ce2565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b6000547501000000000000000000000000000000000000000000900460ff16158080156107b0575060005460017401000000000000000000000000000000000000000090910460ff16105b806107e25750303b1580156107e2575060005474010000000000000000000000000000000000000000900460ff166001145b610873576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905580156108f957600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc80549285169290911691909117905561096b73420000000000000000000000000000000000000761158b565b80156109ce57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a679190611d30565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff215301610b36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f74207365740000000000000000000000606482015260840161086a565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f610b6f604063ffffffff8816611d81565b610b799190611db1565b610b84601088611d81565b610b919062030d40611dff565b610b9b9190611dff565b610ba59190611dff565b610baf9190611dff565b610bb99190611dff565b949350505050565b610bc96109d3565b15610c30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a2070617573656400000000604482015260640161086a565b60f087901c60028110610ceb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a40161086a565b8061ffff16600003610de0576000610d3c878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506116c7915050565b600081815260cb602052604090205490915060ff1615610dde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c61796564000000000000000000606482015260840161086a565b505b6000610e26898989898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116e692505050565b9050610e30611709565b15610e6857853414610e4457610e44611e2b565b600081815260ce602052604090205460ff1615610e6357610e63611e2b565b610fba565b3415610f1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a40161086a565b600081815260ce602052604090205460ff16610fba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c6179656400000000000000000000000000000000606482015260840161086a565b610fc3876117e5565b15611076576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a40161086a565b600081815260cb602052604090205460ff1615611115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c6179656400000000000000000000606482015260840161086a565b61113685611127611388619c40611dff565b67ffffffffffffffff1661182b565b158061115c575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561127557600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161126e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161086a565b50506114cd565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061130688619c405a6112c99190611e5a565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061184992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156113bc57600082815260cb602052604090205460ff161561135957611359611e2b565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26114c9565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016114c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161086a565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611553908890839089906000908990600401611e71565b6000604051808303818588803b15801561156c57600080fd5b505af1158015611580573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611636576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161086a565b60cc5473ffffffffffffffffffffffffffffffffffffffff166116805760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006116d585858585611863565b805190602001209050949350505050565b60006116f68787878787876118fc565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff1633148015610a67575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156117a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c99190611ec9565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611825575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b60608484848460405160240161187c9493929190611ee6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161191996959493929190611f30565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146119bd57600080fd5b50565b60008083601f8401126119d257600080fd5b50813567ffffffffffffffff8111156119ea57600080fd5b602083019150836020828501011115611a0257600080fd5b9250929050565b803563ffffffff81168114611a1d57600080fd5b919050565b60008060008060608587031215611a3857600080fd5b8435611a438161199b565b9350602085013567ffffffffffffffff811115611a5f57600080fd5b611a6b878288016119c0565b9094509250611a7e905060408601611a09565b905092959194509250565b60008060408385031215611a9c57600080fd5b8235611aa78161199b565b91506020830135611ab78161199b565b809150509250929050565b6000815180845260005b81811015611ae857602081850181015186830182015201611acc565b81811115611afa576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611b406020830184611ac2565b9392505050565b600060208284031215611b5957600080fd5b5035919050565b600080600060408486031215611b7557600080fd5b833567ffffffffffffffff811115611b8c57600080fd5b611b98868287016119c0565b9094509250611bab905060208501611a09565b90509250925092565b600080600080600080600060c0888a031215611bcf57600080fd5b873596506020880135611be18161199b565b95506040880135611bf18161199b565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611c1b57600080fd5b611c278a828b016119c0565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611cd560c083018486611c3a565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611d12608083018688611c3a565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611d4257600080fd5b81518015158114611b4057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611da857611da8611d52565b02949350505050565b600067ffffffffffffffff80841680611df3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611e2257611e22611d52565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611e6c57611e6c611d52565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611ebe60a0830184611ac2565b979650505050505050565b600060208284031215611edb57600080fd5b8151611b408161199b565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611f1f6080830185611ac2565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611f7b60c0830184611ac2565b9897505050505050505056fea164736f6c634300080f000a", + "deployedCode": "0x6080604052600436106101805760003560e01c80635c975abb116100d6578063a4e7f8bd1161007f578063d764ad0b11610059578063d764ad0b14610463578063db505d8014610476578063ecc70428146104a357600080fd5b8063a4e7f8bd146103e3578063b1b1b20914610413578063b28ade251461044357600080fd5b806383a74074116100b057806383a74074146103a15780638cbeeef2146102b85780639fce812c146103b857600080fd5b80635c975abb1461033a5780636425666b1461035f5780636e296e451461038c57600080fd5b80633dbb202b116101385780634c1d6a69116101125780634c1d6a69146102b857806354fd4d50146102ce5780635644cfdf1461032457600080fd5b80633dbb202b1461025b5780633f827a5a14610270578063485cc9551461029857600080fd5b80630ff754ea116101695780630ff754ea146101cd5780632828d7e81461021957806335e80ab31461022e57600080fd5b8063028f85f7146101855780630c568498146101b8575b600080fd5b34801561019157600080fd5b5061019a601081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b3480156101c457600080fd5b5061019a603f81565b3480156101d957600080fd5b5060fc5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101af565b34801561022557600080fd5b5061019a604081565b34801561023a57600080fd5b5060fb546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b61026e610269366004611a22565b610508565b005b34801561027c57600080fd5b50610285600181565b60405161ffff90911681526020016101af565b3480156102a457600080fd5b5061026e6102b3366004611a89565b610765565b3480156102c457600080fd5b5061019a619c4081565b3480156102da57600080fd5b506103176040518060400160405280600581526020017f322e332e3000000000000000000000000000000000000000000000000000000081525081565b6040516101af9190611b2d565b34801561033057600080fd5b5061019a61138881565b34801561034657600080fd5b5061034f6109d3565b60405190151581526020016101af565b34801561036b57600080fd5b5060fc546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b34801561039857600080fd5b506101f4610a6c565b3480156103ad57600080fd5b5061019a62030d4081565b3480156103c457600080fd5b5060cf5473ffffffffffffffffffffffffffffffffffffffff166101f4565b3480156103ef57600080fd5b5061034f6103fe366004611b47565b60ce6020526000908152604090205460ff1681565b34801561041f57600080fd5b5061034f61042e366004611b47565b60cb6020526000908152604090205460ff1681565b34801561044f57600080fd5b5061019a61045e366004611b60565b610b53565b61026e610471366004611bb4565b610bc1565b34801561048257600080fd5b5060cf546101f49073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104af57600080fd5b506104fa60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b6040519081526020016101af565b60cf5461063a9073ffffffffffffffffffffffffffffffffffffffff16610530858585610b53565b347fd764ad0b0000000000000000000000000000000000000000000000000000000061059c60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b338a34898c8c6040516024016105b89796959493929190611c83565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526114f2565b8373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385856106bf60cd547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790565b866040516106d1959493929190611ce2565b60405180910390a260405134815233907f8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d5469060200160405180910390a2505060cd80547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808216600101167fffff0000000000000000000000000000000000000000000000000000000000009091161790555050565b6000547501000000000000000000000000000000000000000000900460ff16158080156107b0575060005460017401000000000000000000000000000000000000000090910460ff16105b806107e25750303b1580156107e2575060005474010000000000000000000000000000000000000000900460ff166001145b610873576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000017905580156108f957600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b60fb805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925560fc80549285169290911691909117905561096b73420000000000000000000000000000000000000761158b565b80156109ce57600080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60fb54604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a679190611d30565b905090565b60cc5460009073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff215301610b36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f43726f7373446f6d61696e4d657373656e6765723a2078446f6d61696e4d657360448201527f7361676553656e646572206973206e6f74207365740000000000000000000000606482015260840161086a565b5060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b6000611388619c4080603f610b6f604063ffffffff8816611d81565b610b799190611db1565b610b84601088611d81565b610b919062030d40611dff565b610b9b9190611dff565b610ba59190611dff565b610baf9190611dff565b610bb99190611dff565b949350505050565b610bc96109d3565b15610c30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f43726f7373446f6d61696e4d657373656e6765723a2070617573656400000000604482015260640161086a565b60f087901c60028110610ceb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f43726f7373446f6d61696e4d657373656e6765723a206f6e6c7920766572736960448201527f6f6e2030206f722031206d657373616765732061726520737570706f7274656460648201527f20617420746869732074696d6500000000000000000000000000000000000000608482015260a40161086a565b8061ffff16600003610de0576000610d3c878986868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f92506116c7915050565b600081815260cb602052604090205490915060ff1615610dde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f43726f7373446f6d61696e4d657373656e6765723a206c65676163792077697460448201527f6864726177616c20616c72656164792072656c61796564000000000000000000606482015260840161086a565b505b6000610e26898989898989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116e692505050565b9050610e30611709565b15610e6857853414610e4457610e44611e2b565b600081815260ce602052604090205460ff1615610e6357610e63611e2b565b610fba565b3415610f1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f43726f7373446f6d61696e4d657373656e6765723a2076616c7565206d75737460448201527f206265207a65726f20756e6c657373206d6573736167652069732066726f6d2060648201527f612073797374656d206164647265737300000000000000000000000000000000608482015260a40161086a565b600081815260ce602052604090205460ff16610fba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520636160448201527f6e6e6f74206265207265706c6179656400000000000000000000000000000000606482015260840161086a565b610fc3876117e5565b15611076576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f43726f7373446f6d61696e4d657373656e6765723a2063616e6e6f742073656e60448201527f64206d65737361676520746f20626c6f636b65642073797374656d206164647260648201527f6573730000000000000000000000000000000000000000000000000000000000608482015260a40161086a565b600081815260cb602052604090205460ff1615611115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f43726f7373446f6d61696e4d657373656e6765723a206d65737361676520686160448201527f7320616c7265616479206265656e2072656c6179656400000000000000000000606482015260840161086a565b61113685611127611388619c40611dff565b67ffffffffffffffff1661182b565b158061115c575060cc5473ffffffffffffffffffffffffffffffffffffffff1661dead14155b1561127557600081815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555182917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff320161126e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161086a565b50506114cd565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16179055600061130688619c405a6112c99190611e5a565b8988888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061184992505050565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055905080156113bc57600082815260cb602052604090205460ff161561135957611359611e2b565b600082815260cb602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26114c9565b600082815260ce602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f91a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff32016114c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f43726f7373446f6d61696e4d657373656e6765723a206661696c656420746f2060448201527f72656c6179206d65737361676500000000000000000000000000000000000000606482015260840161086a565b5050505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60fc546040517fe9e05c4200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063e9e05c42908490611553908890839089906000908990600401611e71565b6000604051808303818588803b15801561156c57600080fd5b505af1158015611580573d6000803e3d6000fd5b505050505050505050565b6000547501000000000000000000000000000000000000000000900460ff16611636576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161086a565b60cc5473ffffffffffffffffffffffffffffffffffffffff166116805760cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790555b60cf80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006116d585858585611863565b805190602001209050949350505050565b60006116f68787878787876118fc565b8051906020012090509695505050505050565b60fc5460009073ffffffffffffffffffffffffffffffffffffffff1633148015610a67575060cf5460fc54604080517f9bf62d82000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691639bf62d82916004808201926020929091908290030181865afa1580156117a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c99190611ec9565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600073ffffffffffffffffffffffffffffffffffffffff8216301480611825575060fc5473ffffffffffffffffffffffffffffffffffffffff8381169116145b92915050565b600080603f83619c4001026040850201603f5a021015949350505050565b600080600080845160208601878a8af19695505050505050565b60608484848460405160240161187c9493929190611ee6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b606086868686868660405160240161191996959493929190611f30565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd764ad0b0000000000000000000000000000000000000000000000000000000017905290509695505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146119bd57600080fd5b50565b60008083601f8401126119d257600080fd5b50813567ffffffffffffffff8111156119ea57600080fd5b602083019150836020828501011115611a0257600080fd5b9250929050565b803563ffffffff81168114611a1d57600080fd5b919050565b60008060008060608587031215611a3857600080fd5b8435611a438161199b565b9350602085013567ffffffffffffffff811115611a5f57600080fd5b611a6b878288016119c0565b9094509250611a7e905060408601611a09565b905092959194509250565b60008060408385031215611a9c57600080fd5b8235611aa78161199b565b91506020830135611ab78161199b565b809150509250929050565b6000815180845260005b81811015611ae857602081850181015186830182015201611acc565b81811115611afa576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611b406020830184611ac2565b9392505050565b600060208284031215611b5957600080fd5b5035919050565b600080600060408486031215611b7557600080fd5b833567ffffffffffffffff811115611b8c57600080fd5b611b98868287016119c0565b9094509250611bab905060208501611a09565b90509250925092565b600080600080600080600060c0888a031215611bcf57600080fd5b873596506020880135611be18161199b565b95506040880135611bf18161199b565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611c1b57600080fd5b611c278a828b016119c0565b989b979a50959850939692959293505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152611cd560c083018486611c3a565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152608060208201526000611d12608083018688611c3a565b905083604083015263ffffffff831660608301529695505050505050565b600060208284031215611d4257600080fd5b81518015158114611b4057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615611da857611da8611d52565b02949350505050565b600067ffffffffffffffff80841680611df3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600067ffffffffffffffff808316818516808303821115611e2257611e22611d52565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082821015611e6c57611e6c611d52565b500390565b73ffffffffffffffffffffffffffffffffffffffff8616815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611ebe60a0830184611ac2565b979650505050505050565b600060208284031215611edb57600080fd5b8151611b408161199b565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152611f1f6080830185611ac2565b905082606083015295945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152611f7b60c0830184611ac2565b9897505050505050505056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": true, + "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000010000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": true, + "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000010000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": true, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": true, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": true, + "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9fce812c", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000007", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xdb505d80", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000007", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0ff754ea", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6425666b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x60806040523480156200001157600080fd5b50620000256001806000808080806200002b565b62000328565b600054610100900460ff16158080156200004c5750600054600160ff909116105b806200007c575062000069306200031960201b6200135d1760201c565b1580156200007c575060005460ff166001145b620000e55760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000109576000805461ff0019166101001790555b60008811620001815760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e20300000000000006064820152608401620000dc565b60008711620001f95760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e20300000000000000000000000006064820152608401620000dc565b428511156200027f5760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401620000dc565b6004889055600587905560018690556002859055600780546001600160a01b038087166001600160a01b0319928316179092556006805492861692909116919091179055600882905580156200030f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6001600160a01b03163b151590565b6115d580620003386000396000f3fe60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a", + "deployedCode": "0x60806040526004361061018a5760003560e01c806389c44cbb116100d6578063ce5db8d61161007f578063dcec334811610059578063dcec33481461049b578063e1a41bcf146104b0578063f4daa291146104c657600080fd5b8063ce5db8d614610445578063cf8e5cf01461045b578063d1de856c1461047b57600080fd5b8063a25ae557116100b0578063a25ae55714610391578063a8e4fb90146103ed578063bffa7f0f1461041a57600080fd5b806389c44cbb1461034857806393991af3146103685780639aaab6481461037e57600080fd5b806369f16eec1161013857806370872aa51161011257806370872aa5146102fc5780637f00642014610312578063887862721461033257600080fd5b806369f16eec146102a75780636abcf563146102bc5780636b4d98dd146102d157600080fd5b8063529933df11610169578063529933df146101ea578063534db0e2146101ff57806354fd4d501461025157600080fd5b80622134cc1461018f5780631c89c97d146101b35780634599c788146101d5575b600080fd5b34801561019b57600080fd5b506005545b6040519081526020015b60405180910390f35b3480156101bf57600080fd5b506101d36101ce3660046113a2565b6104db565b005b3480156101e157600080fd5b506101a06108b6565b3480156101f657600080fd5b506004546101a0565b34801561020b57600080fd5b5060065461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101aa565b34801561025d57600080fd5b5061029a6040518060400160405280600581526020017f312e382e3000000000000000000000000000000000000000000000000000000081525081565b6040516101aa9190611405565b3480156102b357600080fd5b506101a0610929565b3480156102c857600080fd5b506003546101a0565b3480156102dd57600080fd5b5060065473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561030857600080fd5b506101a060015481565b34801561031e57600080fd5b506101a061032d366004611478565b61093b565b34801561033e57600080fd5b506101a060025481565b34801561035457600080fd5b506101d3610363366004611478565b610b4f565b34801561037457600080fd5b506101a060055481565b6101d361038c366004611491565b610de9565b34801561039d57600080fd5b506103b16103ac366004611478565b61124a565b60408051825181526020808401516fffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101aa565b3480156103f957600080fd5b5060075461022c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561042657600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff1661022c565b34801561045157600080fd5b506101a060085481565b34801561046757600080fd5b506103b1610476366004611478565b6112de565b34801561048757600080fd5b506101a0610496366004611478565b611316565b3480156104a757600080fd5b506101a0611346565b3480156104bc57600080fd5b506101a060045481565b3480156104d257600080fd5b506008546101a0565b600054610100900460ff16158080156104fb5750600054600160ff909116105b806105155750303b158015610515575060005460ff166001145b6105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561060457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60008811610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161059d565b60008711610724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d7560448201527f73742062652067726561746572207468616e2030000000000000000000000000606482015260840161059d565b428511156107db576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201527f74696d6500000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60048890556005879055600186905560028590556007805473ffffffffffffffffffffffffffffffffffffffff8087167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556006805492861692909116919091179055600882905580156108ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b6003546000901561092057600380546108d1906001906114f2565b815481106108e1576108e1611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16919050565b6001545b905090565b600354600090610924906001906114f2565b60006109456108b6565b8211156109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e2060648201527f70726f706f736564000000000000000000000000000000000000000000000000608482015260a40161059d565b600354610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f7360648201527f6564207965740000000000000000000000000000000000000000000000000000608482015260a40161059d565b6003546000905b80821015610b485760006002610acc8385611538565b610ad69190611550565b90508460038281548110610aec57610aec611509565b600091825260209091206002909102016001015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff161015610b3e57610b37816001611538565b9250610b42565b8091505b50610ab6565b5092915050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161059d565b6003548110610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e60648201527f6465780000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b60085460038281548110610cc357610cc3611509565b6000918252602090912060016002909202010154610cf3906fffffffffffffffffffffffffffffffff16426114f2565b10610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e60648201527f616c697a65640000000000000000000000000000000000000000000000000000608482015260a40161059d565b6000610db160035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c324f75747075744f7261636c653a206f6e6c79207468652070726f706f736560448201527f7220616464726573732063616e2070726f706f7365206e6577206f757470757460648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a40161059d565b610ebe611346565b8314610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161059d565b42610f7c84611316565b10611009576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161059d565b83611096576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161059d565b81156111525781814014611152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4c324f75747075744f7261636c653a20626c6f636b206861736820646f65732060448201527f6e6f74206d61746368207468652068617368206174207468652065787065637460648201527f6564206865696768740000000000000000000000000000000000000000000000608482015260a40161059d565b8261115c60035490565b857fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161118e91815260200190565b60405180910390a45050604080516060810182529283526fffffffffffffffffffffffffffffffff4281166020850190815292811691840191825260038054600181018255600091909152935160029094027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810194909455915190518216700100000000000000000000000000000000029116177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c90910155565b60408051606081018252600080825260208201819052918101919091526003828154811061127a5761127a611509565b600091825260209182902060408051606081018252600290930290910180548352600101546fffffffffffffffffffffffffffffffff8082169484019490945270010000000000000000000000000000000090049092169181019190915292915050565b604080516060810182526000808252602082018190529181019190915260036113068361093b565b8154811061127a5761127a611509565b60006005546001548361132991906114f2565b611333919061158b565b6002546113409190611538565b92915050565b60006004546113536108b6565b6109249190611538565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b803573ffffffffffffffffffffffffffffffffffffffff8116811461139d57600080fd5b919050565b600080600080600080600060e0888a0312156113bd57600080fd5b873596506020880135955060408801359450606088013593506113e260808901611379565b92506113f060a08901611379565b915060c0880135905092959891949750929550565b600060208083528351808285015260005b8181101561143257858101830151858201604001528201611416565b81811115611444576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561148a57600080fd5b5035919050565b600080600080608085870312156114a757600080fd5b5050823594602084013594506040840135936060013592509050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611504576115046114c3565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561154b5761154b6114c3565b500190565b600082611586577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156115c3576115c36114c3565b50029056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x529933df", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xe1a41bcf", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x002134cc", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x93991af3", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xbffa7f0f", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xa8e4fb90", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000007" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6b4d98dd", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x534db0e2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000006" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf4daa291", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xce5db8d6", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000008" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x70872aa5", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x88786272", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x19652082F846171168Daf378C4fD3ee85a0D4A60", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x60806040523480156200001157600080fd5b506200004962000032600160008051602062002a4783398151915262000c39565b60001b600019620000c960201b62000e061760201c565b6040805160c080820183526001808352602080840182905260028486015260006060808601829052608080870183905260a08088018490528851968701895283875293860183905296850182905284018190529483018590528201849052620000c39361dead9390928392839290918391908290620000cd565b62000d5c565b9055565b600054610100900460ff1615808015620000ee5750600054600160ff909116105b806200011e57506200010b30620004df60201b62000e0a1760201c565b1580156200011e575060005460ff166001145b620001875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015620001ab576000805461ff0019166101001790555b620001b5620004ee565b620001c08a62000556565b620001cb87620005d5565b620001d7898962000627565b620001e2866200068b565b620002197f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0886620000c960201b62000e061760201c565b6200025f6200024a60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc59862000c39565b60001b84620000c960201b62000e061760201c565b620002a96200029060017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce958063762000c39565b60001b8360000151620000c960201b62000e061760201c565b620002f3620002da60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a862000c39565b60001b8360200151620000c960201b62000e061760201c565b6200033d6200032460017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad637762000c39565b60001b8360400151620000c960201b62000e061760201c565b620003876200036e60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a687181662000c39565b60001b8360600151620000c960201b62000e061760201c565b620003d1620003b860017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad62000c39565b60001b8360800151620000c960201b62000e061760201c565b6200041b6200040260017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d62000c39565b60001b8360a00151620000c960201b62000e061760201c565b6200042562000728565b620004308462000799565b6200043a62000add565b6001600160401b0316866001600160401b031610156200048c5760405162461bcd60e51b815260206004820152601f6024820152600080516020620029e783398151915260448201526064016200017e565b8015620004d3576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b6001600160a01b03163b151590565b600054610100900460ff166200054a5760405162461bcd60e51b815260206004820152602b602482015260008051602062002a2783398151915260448201526a6e697469616c697a696e6760a81b60648201526084016200017e565b6200055462000b0a565b565b6200056062000b71565b6001600160a01b038116620005c75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016200017e565b620005d28162000bcd565b50565b60678190556040805160208082018490528251808303909101815290820190915260005b600060008051602062002a07833981519152836040516200061b919062000c53565b60405180910390a35050565b60658290556066819055604080516020810184905290810182905260009060600160408051601f1981840301815291905290506001600060008051602062002a07833981519152836040516200067e919062000c53565b60405180910390a3505050565b6200069562000add565b6001600160401b0316816001600160401b03161015620006e75760405162461bcd60e51b815260206004820152601f6024820152600080516020620029e783398151915260448201526064016200017e565b606880546001600160401b0319166001600160401b0383169081179091556040805160208082019390935281518082039093018352810190526002620005f9565b6200075c62000748600160008051602062002a4783398151915262000c39565b60001b62000c1f60201b62000e261760201c565b60000362000554576200055462000784600160008051602062002a4783398151915262000c39565b60001b43620000c960201b62000e061760201c565b8060a001516001600160801b0316816060015163ffffffff161115620008285760405162461bcd60e51b815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d61782062617365000000000000000000000060648201526084016200017e565b6001816040015160ff1611620008995760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201526e65206c6172676572207468616e203160881b60648201526084016200017e565b606854608082015182516001600160401b0390921691620008bb919062000cab565b63ffffffff161115620009005760405162461bcd60e51b815260206004820152601f6024820152600080516020620029e783398151915260448201526064016200017e565b6000816020015160ff1611620009715760405162461bcd60e51b815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201526e06965722063616e6e6f74206265203608c1b60648201526084016200017e565b8051602082015163ffffffff82169160ff909116906200099390829062000cd6565b6200099f919062000d08565b63ffffffff161462000a1a5760405162461bcd60e51b815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d697400000000000000000060648201526084016200017e565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff96871664ffffffffff199095169490941764010000000060ff948516021764ffffffffff60281b191665010000000000939092169290920263ffffffff60301b19161766010000000000009185169190910217600160501b600160f01b0319166a01000000000000000000009390941692909202600160701b600160f01b03191692909217600160701b6001600160801b0390921691909102179055565b60695460009062000b059063ffffffff6a010000000000000000000082048116911662000d37565b905090565b600054610100900460ff1662000b665760405162461bcd60e51b815260206004820152602b602482015260008051602062002a2783398151915260448201526a6e697469616c697a696e6760a81b60648201526084016200017e565b620005543362000bcd565b6033546001600160a01b03163314620005545760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200017e565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b5490565b634e487b7160e01b600052601160045260246000fd5b60008282101562000c4e5762000c4e62000c23565b500390565b600060208083528351808285015260005b8181101562000c825785810183015185820160400152820162000c64565b8181111562000c95576000604083870101525b50601f01601f1916929092016040019392505050565b600063ffffffff80831681851680830382111562000ccd5762000ccd62000c23565b01949350505050565b600063ffffffff8084168062000cfc57634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b600063ffffffff8083168185168183048111821515161562000d2e5762000d2e62000c23565b02949350505050565b60006001600160401b0382811684821680830382111562000ccd5762000ccd62000c23565b611c7b8062000d6c6000396000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c8063935f029e11610145578063dac6e63a116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610597578063fd32aa0f1461059f578063ffa1ad74146105a757600080fd5b8063f45e65d81461057a578063f68016b71461058357600080fd5b8063dac6e63a1461054e578063e0e2016d14610556578063e81b2c6d1461055e578063f2fde38b1461056757600080fd5b8063bc49ce5f11610114578063c71973f6116100f9578063c71973f6146103f4578063c9b26f6114610407578063cc731b021461041a57600080fd5b8063bc49ce5f146103e4578063c4e8ddfa146103ec57600080fd5b8063935f029e146103ae5780639b7d7f0a146103c1578063a7119869146103c9578063b40a817c146103d157600080fd5b806348cd4cb1116101d857806354fd4d50116101a757806361d157681161018c57806361d1576814610380578063715018a6146103885780638da5cb5b1461039057600080fd5b806354fd4d501461032f5780635d73369c1461037857600080fd5b806348cd4cb1146102d75780634add321d146102df5780634d9f1559146103005780634f16540b1461030857600080fd5b80630c18c162116102145780630c18c162146102ab57806318d13918146102b457806319f5cea8146102c75780631fd19ee1146102cf57600080fd5b806306c9265714610246578063078f29cf146102615780630a49cb031461028e5780630bbb796814610296575b600080fd5b61024e6105af565b6040519081526020015b60405180910390f35b6102696105dd565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610258565b610269610616565b6102a96102a4366004611928565b610646565b005b61024e60655481565b6102a96102c2366004611a55565b610a44565b61024e610a58565b610269610a83565b61024e610aad565b6102e7610add565b60405167ffffffffffffffff9091168152602001610258565b610269610b03565b61024e7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b61036b6040518060400160405280600681526020017f312e31322e30000000000000000000000000000000000000000000000000000081525081565b6040516102589190611ae2565b61024e610b33565b61024e610b5e565b6102a9610b89565b60335473ffffffffffffffffffffffffffffffffffffffff16610269565b6102a96103bc366004611af5565b610b9d565b610269610bb3565b610269610be3565b6102a96103df366004611b17565b610c13565b61024e610c24565b610269610c4f565b6102a9610402366004611b32565b610c7f565b6102a9610415366004611b4e565b610c90565b6104de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102589190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b610269610ca1565b61024e610cd1565b61024e60675481565b6102a9610575366004611a55565b610cfc565b61024e60665481565b6068546102e79067ffffffffffffffff1681565b61024e610db0565b61024e610ddb565b61024e600081565b6105da60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b81565b600061061161060d60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b5490565b905090565b600061061161060d60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b600054610100900460ff16158080156106665750600054600160ff909116105b806106805750303b158015610680575060005460ff166001145b610711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561076f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610777610e2a565b6107808a610cfc565b61078987610ec9565b6107938989610f2a565b61079c86610fbb565b6107c57f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b6107f86107f360017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b849055565b61082c61082660017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b83519055565b61086361085a60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b60208401519055565b61089a61089160017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b60408401519055565b6108d16108c860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b60608401519055565b6109086108ff60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b60808401519055565b61093f61093660017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b60a08401519055565b610947611099565b61095084611101565b610958610add565b67ffffffffffffffff168667ffffffffffffffff1610156109d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b8015610a3857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b610a4c611575565b610a55816115f6565b50565b6105da60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b60006106117f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b600061061161060d60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b6069546000906106119063ffffffff6a0100000000000000000000820481169116611bad565b600061061161060d60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b6105da60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b6105da60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b610b91611575565b610b9b600061167a565b565b610ba5611575565b610baf8282610f2a565b5050565b600061061161060d60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b600061061161060d60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b610c1b611575565b610a5581610fbb565b6105da60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b600061061161060d60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b610c87611575565b610a5581611101565b610c98611575565b610a5581610ec9565b600061061161060d60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b6105da60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b610d04611575565b73ffffffffffffffffffffffffffffffffffffffff8116610da7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610708565b610a558161167a565b6105da60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b6105da60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b5490565b600054610100900460ff16610ec1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610708565b610b9b6116f1565b60678190556040805160208082018490528251808303909101815290820190915260005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610f1e9190611ae2565b60405180910390a35050565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae9190611ae2565b60405180910390a3505050565b610fc3610add565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610eed565b6110c761060d60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b600003610b9b57610b9b6110fc60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b439055565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff1611156111b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610708565b6001816040015160ff1611611248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610708565b6068546080820151825167ffffffffffffffff909216916112699190611bd9565b63ffffffff1611156112d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b6000816020015160ff161161136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610708565b8051602082015163ffffffff82169160ff9091169061138e908290611bf8565b6113989190611c42565b63ffffffff161461142b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610708565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610b9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610708565b61161f7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290506003610eed565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610708565b610b9b3361167a565b803573ffffffffffffffffffffffffffffffffffffffff811681146117b557600080fd5b919050565b803567ffffffffffffffff811681146117b557600080fd5b60405160c0810167ffffffffffffffff8111828210171561181c577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff811681146117b557600080fd5b803560ff811681146117b557600080fd5b600060c0828403121561185957600080fd5b60405160c0810181811067ffffffffffffffff821117156118a3577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050806118b283611822565b81526118c060208401611836565b60208201526118d160408401611836565b60408201526118e260608401611822565b60608201526118f360808401611822565b608082015260a08301356fffffffffffffffffffffffffffffffff8116811461191b57600080fd5b60a0919091015292915050565b6000806000806000806000806000898b0361026081121561194857600080fd5b6119518b611791565b995060208b0135985060408b0135975060608b0135965061197460808c016117ba565b955061198260a08c01611791565b94506119918c60c08d01611847565b93506119a06101808c01611791565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60820112156119d257600080fd5b506119db6117d2565b6119e86101a08c01611791565b81526119f76101c08c01611791565b6020820152611a096101e08c01611791565b6040820152611a1b6102008c01611791565b6060820152611a2d6102208c01611791565b6080820152611a3f6102408c01611791565b60a0820152809150509295985092959850929598565b600060208284031215611a6757600080fd5b611a7082611791565b9392505050565b6000815180845260005b81811015611a9d57602081850181015186830182015201611a81565b81811115611aaf576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611a706020830184611a77565b60008060408385031215611b0857600080fd5b50508035926020909101359150565b600060208284031215611b2957600080fd5b611a70826117ba565b600060c08284031215611b4457600080fd5b611a708383611847565b600060208284031215611b6057600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611ba857611ba8611b67565b500390565b600067ffffffffffffffff808316818516808303821115611bd057611bd0611b67565b01949350505050565b600063ffffffff808316818516808303821115611bd057611bd0611b67565b600063ffffffff80841680611c36577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611c6557611c65611b67565b0294935050505056fea164736f6c634300080f000a53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77001d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069a11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0", + "deployedCode": "0x608060405234801561001057600080fd5b50600436106102415760003560e01c8063935f029e11610145578063dac6e63a116100bd578063f45e65d81161008c578063f8c68de011610071578063f8c68de014610597578063fd32aa0f1461059f578063ffa1ad74146105a757600080fd5b8063f45e65d81461057a578063f68016b71461058357600080fd5b8063dac6e63a1461054e578063e0e2016d14610556578063e81b2c6d1461055e578063f2fde38b1461056757600080fd5b8063bc49ce5f11610114578063c71973f6116100f9578063c71973f6146103f4578063c9b26f6114610407578063cc731b021461041a57600080fd5b8063bc49ce5f146103e4578063c4e8ddfa146103ec57600080fd5b8063935f029e146103ae5780639b7d7f0a146103c1578063a7119869146103c9578063b40a817c146103d157600080fd5b806348cd4cb1116101d857806354fd4d50116101a757806361d157681161018c57806361d1576814610380578063715018a6146103885780638da5cb5b1461039057600080fd5b806354fd4d501461032f5780635d73369c1461037857600080fd5b806348cd4cb1146102d75780634add321d146102df5780634d9f1559146103005780634f16540b1461030857600080fd5b80630c18c162116102145780630c18c162146102ab57806318d13918146102b457806319f5cea8146102c75780631fd19ee1146102cf57600080fd5b806306c9265714610246578063078f29cf146102615780630a49cb031461028e5780630bbb796814610296575b600080fd5b61024e6105af565b6040519081526020015b60405180910390f35b6102696105dd565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610258565b610269610616565b6102a96102a4366004611928565b610646565b005b61024e60655481565b6102a96102c2366004611a55565b610a44565b61024e610a58565b610269610a83565b61024e610aad565b6102e7610add565b60405167ffffffffffffffff9091168152602001610258565b610269610b03565b61024e7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b61036b6040518060400160405280600681526020017f312e31322e30000000000000000000000000000000000000000000000000000081525081565b6040516102589190611ae2565b61024e610b33565b61024e610b5e565b6102a9610b89565b60335473ffffffffffffffffffffffffffffffffffffffff16610269565b6102a96103bc366004611af5565b610b9d565b610269610bb3565b610269610be3565b6102a96103df366004611b17565b610c13565b61024e610c24565b610269610c4f565b6102a9610402366004611b32565b610c7f565b6102a9610415366004611b4e565b610c90565b6104de6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b6040516102589190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b610269610ca1565b61024e610cd1565b61024e60675481565b6102a9610575366004611a55565b610cfc565b61024e60665481565b6068546102e79067ffffffffffffffff1681565b61024e610db0565b61024e610ddb565b61024e600081565b6105da60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b81565b600061061161060d60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b5490565b905090565b600061061161060d60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b600054610100900460ff16158080156106665750600054600160ff909116105b806106805750303b158015610680575060005460ff166001145b610711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561076f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610777610e2a565b6107808a610cfc565b61078987610ec9565b6107938989610f2a565b61079c86610fbb565b6107c57f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08869055565b6107f86107f360017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b849055565b61082c61082660017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b83519055565b61086361085a60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b60208401519055565b61089a61089160017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b60408401519055565b6108d16108c860017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b60608401519055565b6109086108ff60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b60808401519055565b61093f61093660017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b60a08401519055565b610947611099565b61095084611101565b610958610add565b67ffffffffffffffff168667ffffffffffffffff1610156109d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b8015610a3857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b610a4c611575565b610a55816115f6565b50565b6105da60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b60006106117f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b600061061161060d60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b6069546000906106119063ffffffff6a0100000000000000000000820481169116611bad565b600061061161060d60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b6105da60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b6105da60017fe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871816611b96565b610b91611575565b610b9b600061167a565b565b610ba5611575565b610baf8282610f2a565b5050565b600061061161060d60017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d611b96565b600061061161060d60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637611b96565b610c1b611575565b610a5581610fbb565b6105da60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b600061061161060d60017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8611b96565b610c87611575565b610a5581611101565b610c98611575565b610a5581610ec9565b600061061161060d60017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598611b96565b6105da60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b610d04611575565b73ffffffffffffffffffffffffffffffffffffffff8116610da7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610708565b610a558161167a565b6105da60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377611b96565b6105da60017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad611b96565b9055565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b5490565b600054610100900460ff16610ec1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610708565b610b9b6116f1565b60678190556040805160208082018490528251808303909101815290820190915260005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610f1e9190611ae2565b60405180910390a35050565b606582905560668190556040805160208101849052908101829052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529050600160007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be83604051610fae9190611ae2565b60405180910390a3505050565b610fc3610add565b67ffffffffffffffff168167ffffffffffffffff161015611040576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040805160208082019390935281518082039093018352810190526002610eed565b6110c761060d60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b600003610b9b57610b9b6110fc60017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0611b96565b439055565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff1611156111b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d6178206261736500000000000000000000006064820152608401610708565b6001816040015160ff1611611248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e203100000000000000000000000000000000006064820152608401610708565b6068546080820151825167ffffffffffffffff909216916112699190611bd9565b63ffffffff1611156112d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f77006044820152606401610708565b6000816020015160ff161161136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f74206265203000000000000000000000000000000000006064820152608401610708565b8051602082015163ffffffff82169160ff9091169061138e908290611bf8565b6113989190611c42565b63ffffffff161461142b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d69740000000000000000006064820152608401610708565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610b9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610708565b61161f7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290506003610eed565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610708565b610b9b3361167a565b803573ffffffffffffffffffffffffffffffffffffffff811681146117b557600080fd5b919050565b803567ffffffffffffffff811681146117b557600080fd5b60405160c0810167ffffffffffffffff8111828210171561181c577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803563ffffffff811681146117b557600080fd5b803560ff811681146117b557600080fd5b600060c0828403121561185957600080fd5b60405160c0810181811067ffffffffffffffff821117156118a3577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050806118b283611822565b81526118c060208401611836565b60208201526118d160408401611836565b60408201526118e260608401611822565b60608201526118f360808401611822565b608082015260a08301356fffffffffffffffffffffffffffffffff8116811461191b57600080fd5b60a0919091015292915050565b6000806000806000806000806000898b0361026081121561194857600080fd5b6119518b611791565b995060208b0135985060408b0135975060608b0135965061197460808c016117ba565b955061198260a08c01611791565b94506119918c60c08d01611847565b93506119a06101808c01611791565b925060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60820112156119d257600080fd5b506119db6117d2565b6119e86101a08c01611791565b81526119f76101c08c01611791565b6020820152611a096101e08c01611791565b6040820152611a1b6102008c01611791565b6060820152611a2d6102208c01611791565b6080820152611a3f6102408c01611791565b60a0820152809150509295985092959850929598565b600060208284031215611a6757600080fd5b611a7082611791565b9392505050565b6000815180845260005b81811015611a9d57602081850181015186830182015201611a81565b81811115611aaf576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611a706020830184611a77565b60008060408385031215611b0857600080fd5b50508035926020909101359150565b600060208284031215611b2957600080fd5b611a70826117ba565b600060c08284031215611b4457600080fd5b611a708383611847565b600060208284031215611b6057600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611ba857611ba8611b67565b500390565b600067ffffffffffffffff808316818516808303821115611bd057611bd0611b67565b01949350505050565b600063ffffffff808316818516808303821115611bd057611bd0611b67565b600063ffffffff80841680611c36577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615611c6557611c65611b67565b0294935050505056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "previousValue": "0x0000000000000000000000004e59b44847b379578588920ca78fbf26c0b4956c", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000067" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000065" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000066" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc597" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580636" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a7" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6376" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871815" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ac" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320c" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "previousValue": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "reverted": false, + "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000020100000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000020100000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000020100000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xcc731b02", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000020100000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000020100000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "previousValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0c18c162", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000065" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf45e65d8", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000066" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xe81b2c6d", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000067" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf68016b7", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x1fd19ee1", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x48cd4cb1", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "previousValue": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "reverted": false, + "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xdac6e63a", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc597" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xa7119869", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580636" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xc4e8ddfa", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a7" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x078f29cf", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6376" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x4d9f1559", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871815" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0a49cb03", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ac" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9b7d7f0a", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320c" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x60806040523480156200001157600080fd5b506200001f60008062000025565b62000234565b600054610100900460ff1615808015620000465750600054600160ff909116105b8062000076575062000063306200018a60201b620005511760201c565b15801562000076575060005460ff166001145b620000df5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000103576000805461ff0019166101001790555b603280546001600160a01b0319166001600160a01b0384161790556200013e8373420000000000000000000000000000000000001062000199565b801562000185576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002065760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d6565b600380546001600160a01b039384166001600160a01b03199182161790915560048054929093169116179055565b612c4d80620002446000396000f3fe6080604052600436106101795760003560e01c80637f46ddb2116100cb578063927ede2d1161007f578063b1a1a88211610059578063b1a1a882146104fe578063c89701a214610511578063e11013dd1461053e57600080fd5b8063927ede2d146104a05780639a2ac6d5146104cb578063a9f9e675146104de57600080fd5b806387087623116100b0578063870876231461043a5780638f601f661461045a57806391c49bf8146103ef57600080fd5b80637f46ddb2146103ef578063838b25201461041a57600080fd5b80633cb747bf1161012d57806354fd4d501161010757806354fd4d501461035457806358a997f6146103aa5780635c975abb146103ca57600080fd5b80633cb747bf146102e7578063485cc95514610314578063540abf731461033457600080fd5b80631532ec341161015e5780631532ec341461026a5780631635f5fd1461027d57806335e80ab31461029057600080fd5b80630166a07a1461023757806309fc88431461025757600080fd5b3661023257333b15610212576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b610230333362030d406040518060200160405280600081525061056d565b005b600080fd5b34801561024357600080fd5b506102306102523660046126b1565b610580565b610230610265366004612762565b61099a565b6102306102783660046127b5565b610a71565b61023061028b3660046127b5565b610a85565b34801561029c57600080fd5b506032546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102f357600080fd5b506003546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032057600080fd5b5061023061032f366004612828565b610f4e565b34801561034057600080fd5b5061023061034f366004612861565b611137565b34801561036057600080fd5b5061039d6040518060400160405280600581526020017f322e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516102de919061294e565b3480156103b657600080fd5b506102306103c5366004612961565b61117c565b3480156103d657600080fd5b506103df611250565b60405190151581526020016102de565b3480156103fb57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102bd565b34801561042657600080fd5b50610230610435366004612861565b6112e9565b34801561044657600080fd5b50610230610455366004612961565b61132e565b34801561046657600080fd5b50610492610475366004612828565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102de565b3480156104ac57600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102bd565b6102306104d93660046129e4565b611402565b3480156104ea57600080fd5b506102306104f93660046126b1565b611444565b61023061050c366004612762565b611453565b34801561051d57600080fd5b506004546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b61023061054c3660046129e4565b611524565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61057a8484348585611567565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610653575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610617573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063b9190612a47565b73ffffffffffffffffffffffffffffffffffffffff16145b610705576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610209565b61070d611250565b15610774576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610209565b61077d87611731565b156108cb5761078c8787611793565b61083e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610209565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108ae57600080fd5b505af11580156108c2573d6000803e3d6000fd5b5050505061094d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610909908490612a93565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561094d9085856118b3565b610991878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061198792505050565b50505050505050565b333b15610a29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610a6c3333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061156792505050565b505050565b610a7e8585858585610a85565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b58575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b409190612a47565b73ffffffffffffffffffffffffffffffffffffffff16145b610c0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610209565b610c12611250565b15610c79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610209565b823414610d08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610209565b3073ffffffffffffffffffffffffffffffffffffffff851603610dad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610209565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610e58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610209565b610e9a85858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a1592505050565b6000610eb7855a8660405180602001604052806000815250611a88565b905080610f46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610209565b505050505050565b600054610100900460ff1615808015610f6e5750600054600160ff909116105b80610f885750303b158015610f88575060005460ff166001145b611014576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610209565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561107257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556110d083734200000000000000000000000000000000000010611aa2565b8015610a6c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b61099187873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b8c92505050565b333b1561120b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610f4686863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611eb792505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e49190612aaa565b905090565b61099187873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611eb792505050565b333b156113bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610f4686863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b8c92505050565b61057a33858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061056d92505050565b61099187878787878787610580565b333b156114e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610a6c33338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061056d92505050565b61057a3385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061156792505050565b8234146115f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610209565b61160285858584611ec6565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd0000000000000000000000000000000000000000000000000000000090611665908b908b9086908a90602401612acc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526116f892918890600401612b15565b6000604051808303818588803b15801561171157600080fd5b505af1158015611725573d6000803e3d6000fd5b50505050505050505050565b600061175d827f1d1d8b6300000000000000000000000000000000000000000000000000000000611f39565b8061178d575061178d827fec4fc8e300000000000000000000000000000000000000000000000000000000611f39565b92915050565b60006117bf837f1d1d8b6300000000000000000000000000000000000000000000000000000000611f39565b15611868578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561180f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118339190612a47565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905061178d565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561180f573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a6c9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611f5c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516119ff93929190612b5a565b60405180910390a4610f46868686868686612068565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611a74929190612b98565b60405180910390a361057a848484846120f0565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16611b39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610209565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b611b9587611731565b15611ce357611ba48787611793565b611c56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610209565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611cc657600080fd5b505af1158015611cda573d6000803e3d6000fd5b50505050611d77565b611d0573ffffffffffffffffffffffffffffffffffffffff881686308661215d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611d43908490612bb1565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611d858787878787866121bb565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611de9908b908d908c908c908c908b90602401612bc9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611e7c92918790600401612b15565b600060405180830381600087803b158015611e9657600080fd5b505af1158015611eaa573d6000803e3d6000fd5b5050505050505050505050565b61099187878787878787611b8c565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611f25929190612b98565b60405180910390a361057a84848484612249565b6000611f44836122a8565b8015611f555750611f55838361230c565b9392505050565b6000611fbe826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123db9092919063ffffffff16565b805190915015610a6c5780806020019051810190611fdc9190612aaa565b610a6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610209565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd8686866040516120e093929190612b5a565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161214f929190612b98565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261057a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611905565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161223393929190612b5a565b60405180910390a4610f468686868686866123f2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161214f929190612b98565b60006122d4827f01ffc9a70000000000000000000000000000000000000000000000000000000061230c565b801561178d5750612305827fffffffff0000000000000000000000000000000000000000000000000000000061230c565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156123c4575060208210155b80156123d05750600081115b979650505050505050565b60606123ea848460008561246a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf8686866040516120e093929190612b5a565b6060824710156124fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610209565b73ffffffffffffffffffffffffffffffffffffffff85163b61257a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610209565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125a39190612c24565b60006040518083038185875af1925050503d80600081146125e0576040519150601f19603f3d011682016040523d82523d6000602084013e6125e5565b606091505b50915091506123d0828286606083156125ff575081611f55565b82511561260f5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610209919061294e565b73ffffffffffffffffffffffffffffffffffffffff8116811461266557600080fd5b50565b60008083601f84011261267a57600080fd5b50813567ffffffffffffffff81111561269257600080fd5b6020830191508360208285010111156126aa57600080fd5b9250929050565b600080600080600080600060c0888a0312156126cc57600080fd5b87356126d781612643565b965060208801356126e781612643565b955060408801356126f781612643565b9450606088013561270781612643565b93506080880135925060a088013567ffffffffffffffff81111561272a57600080fd5b6127368a828b01612668565b989b979a50959850939692959293505050565b803563ffffffff8116811461275d57600080fd5b919050565b60008060006040848603121561277757600080fd5b61278084612749565b9250602084013567ffffffffffffffff81111561279c57600080fd5b6127a886828701612668565b9497909650939450505050565b6000806000806000608086880312156127cd57600080fd5b85356127d881612643565b945060208601356127e881612643565b935060408601359250606086013567ffffffffffffffff81111561280b57600080fd5b61281788828901612668565b969995985093965092949392505050565b6000806040838503121561283b57600080fd5b823561284681612643565b9150602083013561285681612643565b809150509250929050565b600080600080600080600060c0888a03121561287c57600080fd5b873561288781612643565b9650602088013561289781612643565b955060408801356128a781612643565b9450606088013593506128bc60808901612749565b925060a088013567ffffffffffffffff81111561272a57600080fd5b60005b838110156128f35781810151838201526020016128db565b8381111561057a5750506000910152565b6000815180845261291c8160208601602086016128d8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f556020830184612904565b60008060008060008060a0878903121561297a57600080fd5b863561298581612643565b9550602087013561299581612643565b9450604087013593506129aa60608801612749565b9250608087013567ffffffffffffffff8111156129c657600080fd5b6129d289828a01612668565b979a9699509497509295939492505050565b600080600080606085870312156129fa57600080fd5b8435612a0581612643565b9350612a1360208601612749565b9250604085013567ffffffffffffffff811115612a2f57600080fd5b612a3b87828801612668565b95989497509550505050565b600060208284031215612a5957600080fd5b8151611f5581612643565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612aa557612aa5612a64565b500390565b600060208284031215612abc57600080fd5b81518015158114611f5557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612b0b6080830184612904565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612b446060830185612904565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612b8f6060830184612904565b95945050505050565b8281526040602082015260006123ea6040830184612904565b60008219821115612bc457612bc4612a64565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612c1860c0830184612904565b98975050505050505050565b60008251612c368184602087016128d8565b919091019291505056fea164736f6c634300080f000a", + "deployedCode": "0x6080604052600436106101795760003560e01c80637f46ddb2116100cb578063927ede2d1161007f578063b1a1a88211610059578063b1a1a882146104fe578063c89701a214610511578063e11013dd1461053e57600080fd5b8063927ede2d146104a05780639a2ac6d5146104cb578063a9f9e675146104de57600080fd5b806387087623116100b0578063870876231461043a5780638f601f661461045a57806391c49bf8146103ef57600080fd5b80637f46ddb2146103ef578063838b25201461041a57600080fd5b80633cb747bf1161012d57806354fd4d501161010757806354fd4d501461035457806358a997f6146103aa5780635c975abb146103ca57600080fd5b80633cb747bf146102e7578063485cc95514610314578063540abf731461033457600080fd5b80631532ec341161015e5780631532ec341461026a5780631635f5fd1461027d57806335e80ab31461029057600080fd5b80630166a07a1461023757806309fc88431461025757600080fd5b3661023257333b15610212576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b610230333362030d406040518060200160405280600081525061056d565b005b600080fd5b34801561024357600080fd5b506102306102523660046126b1565b610580565b610230610265366004612762565b61099a565b6102306102783660046127b5565b610a71565b61023061028b3660046127b5565b610a85565b34801561029c57600080fd5b506032546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102f357600080fd5b506003546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032057600080fd5b5061023061032f366004612828565b610f4e565b34801561034057600080fd5b5061023061034f366004612861565b611137565b34801561036057600080fd5b5061039d6040518060400160405280600581526020017f322e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516102de919061294e565b3480156103b657600080fd5b506102306103c5366004612961565b61117c565b3480156103d657600080fd5b506103df611250565b60405190151581526020016102de565b3480156103fb57600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102bd565b34801561042657600080fd5b50610230610435366004612861565b6112e9565b34801561044657600080fd5b50610230610455366004612961565b61132e565b34801561046657600080fd5b50610492610475366004612828565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102de565b3480156104ac57600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102bd565b6102306104d93660046129e4565b611402565b3480156104ea57600080fd5b506102306104f93660046126b1565b611444565b61023061050c366004612762565b611453565b34801561051d57600080fd5b506004546102bd9073ffffffffffffffffffffffffffffffffffffffff1681565b61023061054c3660046129e4565b611524565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61057a8484348585611567565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610653575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610617573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063b9190612a47565b73ffffffffffffffffffffffffffffffffffffffff16145b610705576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610209565b61070d611250565b15610774576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610209565b61077d87611731565b156108cb5761078c8787611793565b61083e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610209565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108ae57600080fd5b505af11580156108c2573d6000803e3d6000fd5b5050505061094d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054610909908490612a93565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561094d9085856118b3565b610991878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061198792505050565b50505050505050565b333b15610a29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610a6c3333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061156792505050565b505050565b610a7e8585858585610a85565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b58575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b409190612a47565b73ffffffffffffffffffffffffffffffffffffffff16145b610c0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610209565b610c12611250565b15610c79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a20706175736564000000000000000000006044820152606401610209565b823414610d08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610209565b3073ffffffffffffffffffffffffffffffffffffffff851603610dad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610209565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610e58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610209565b610e9a85858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a1592505050565b6000610eb7855a8660405180602001604052806000815250611a88565b905080610f46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610209565b505050505050565b600054610100900460ff1615808015610f6e5750600054600160ff909116105b80610f885750303b158015610f88575060005460ff166001145b611014576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610209565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561107257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556110d083734200000000000000000000000000000000000010611aa2565b8015610a6c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b61099187873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b8c92505050565b333b1561120b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610f4686863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611eb792505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e49190612aaa565b905090565b61099187873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611eb792505050565b333b156113bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610f4686863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b8c92505050565b61057a33858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061056d92505050565b61099187878787878787610580565b333b156114e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610209565b610a6c33338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061056d92505050565b61057a3385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061156792505050565b8234146115f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610209565b61160285858584611ec6565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd0000000000000000000000000000000000000000000000000000000090611665908b908b9086908a90602401612acc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526116f892918890600401612b15565b6000604051808303818588803b15801561171157600080fd5b505af1158015611725573d6000803e3d6000fd5b50505050505050505050565b600061175d827f1d1d8b6300000000000000000000000000000000000000000000000000000000611f39565b8061178d575061178d827fec4fc8e300000000000000000000000000000000000000000000000000000000611f39565b92915050565b60006117bf837f1d1d8b6300000000000000000000000000000000000000000000000000000000611f39565b15611868578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561180f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118339190612a47565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905061178d565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561180f573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a6c9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611f5c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516119ff93929190612b5a565b60405180910390a4610f46868686868686612068565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611a74929190612b98565b60405180910390a361057a848484846120f0565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16611b39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610209565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b611b9587611731565b15611ce357611ba48787611793565b611c56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610209565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611cc657600080fd5b505af1158015611cda573d6000803e3d6000fd5b50505050611d77565b611d0573ffffffffffffffffffffffffffffffffffffffff881686308661215d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611d43908490612bb1565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611d858787878787866121bb565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611de9908b908d908c908c908c908b90602401612bc9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611e7c92918790600401612b15565b600060405180830381600087803b158015611e9657600080fd5b505af1158015611eaa573d6000803e3d6000fd5b5050505050505050505050565b61099187878787878787611b8c565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611f25929190612b98565b60405180910390a361057a84848484612249565b6000611f44836122a8565b8015611f555750611f55838361230c565b9392505050565b6000611fbe826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123db9092919063ffffffff16565b805190915015610a6c5780806020019051810190611fdc9190612aaa565b610a6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610209565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd8686866040516120e093929190612b5a565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d848460405161214f929190612b98565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261057a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611905565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039686868660405161223393929190612b5a565b60405180910390a4610f468686868686866123f2565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5848460405161214f929190612b98565b60006122d4827f01ffc9a70000000000000000000000000000000000000000000000000000000061230c565b801561178d5750612305827fffffffff0000000000000000000000000000000000000000000000000000000061230c565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156123c4575060208210155b80156123d05750600081115b979650505050505050565b60606123ea848460008561246a565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf8686866040516120e093929190612b5a565b6060824710156124fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610209565b73ffffffffffffffffffffffffffffffffffffffff85163b61257a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610209565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125a39190612c24565b60006040518083038185875af1925050503d80600081146125e0576040519150601f19603f3d011682016040523d82523d6000602084013e6125e5565b606091505b50915091506123d0828286606083156125ff575081611f55565b82511561260f5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610209919061294e565b73ffffffffffffffffffffffffffffffffffffffff8116811461266557600080fd5b50565b60008083601f84011261267a57600080fd5b50813567ffffffffffffffff81111561269257600080fd5b6020830191508360208285010111156126aa57600080fd5b9250929050565b600080600080600080600060c0888a0312156126cc57600080fd5b87356126d781612643565b965060208801356126e781612643565b955060408801356126f781612643565b9450606088013561270781612643565b93506080880135925060a088013567ffffffffffffffff81111561272a57600080fd5b6127368a828b01612668565b989b979a50959850939692959293505050565b803563ffffffff8116811461275d57600080fd5b919050565b60008060006040848603121561277757600080fd5b61278084612749565b9250602084013567ffffffffffffffff81111561279c57600080fd5b6127a886828701612668565b9497909650939450505050565b6000806000806000608086880312156127cd57600080fd5b85356127d881612643565b945060208601356127e881612643565b935060408601359250606086013567ffffffffffffffff81111561280b57600080fd5b61281788828901612668565b969995985093965092949392505050565b6000806040838503121561283b57600080fd5b823561284681612643565b9150602083013561285681612643565b809150509250929050565b600080600080600080600060c0888a03121561287c57600080fd5b873561288781612643565b9650602088013561289781612643565b955060408801356128a781612643565b9450606088013593506128bc60808901612749565b925060a088013567ffffffffffffffff81111561272a57600080fd5b60005b838110156128f35781810151838201526020016128db565b8381111561057a5750506000910152565b6000815180845261291c8160208601602086016128d8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f556020830184612904565b60008060008060008060a0878903121561297a57600080fd5b863561298581612643565b9550602087013561299581612643565b9450604087013593506129aa60608801612749565b9250608087013567ffffffffffffffff8111156129c657600080fd5b6129d289828a01612668565b979a9699509497509295939492505050565b600080600080606085870312156129fa57600080fd5b8435612a0581612643565b9350612a1360208601612749565b9250604085013567ffffffffffffffff811115612a2f57600080fd5b612a3b87828801612668565b95989497509550505050565b600060208284031215612a5957600080fd5b8151611f5581612643565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612aa557612aa5612a64565b500390565b600060208284031215612abc57600080fd5b81518015158114611f5557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612b0b6080830184612904565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612b446060830185612904565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612b8f6060830184612904565b95945050505050565b8281526040602082015260006123ea6040830184612904565b60008219821115612bc457612bc4612a64565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612c1860c0830184612904565b98975050505050505050565b60008251612c368184602087016128d8565b919091019291505056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": true, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x927ede2d", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x3cb747bf", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x7f46ddb2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000010", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xc89701a2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000010", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x60806040523480156200001157600080fd5b506200001f60008062000025565b62000234565b600054610100900460ff1615808015620000465750600054600160ff909116105b8062000076575062000063306200018a60201b62000b141760201c565b15801562000076575060005460ff166001145b620000df5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000103576000805461ff0019166101001790555b603280546001600160a01b0319166001600160a01b0384161790556200013e8373420000000000000000000000000000000000001462000199565b801562000185576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03163b151590565b600054610100900460ff16620002065760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000d6565b600180546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b6113e980620002446000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600581526020017f322e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", + "deployedCode": "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80635d93a3fc11610081578063927ede2d1161005b578063927ede2d14610231578063aa5574521461024f578063c89701a21461026257600080fd5b80635d93a3fc146101cc578063761f4493146102005780637f46ddb21461021357600080fd5b8063485cc955116100b2578063485cc9551461015857806354fd4d501461016b5780635c975abb146101b457600080fd5b806335e80ab3146100d95780633687011a146101235780633cb747bf14610138575b600080fd5b6032546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610136610131366004610fe1565b610282565b005b6001546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b610136610166366004611064565b61032e565b6101a76040518060400160405280600581526020017f322e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161011a9190611108565b6101bc610518565b604051901515815260200161011a565b6101bc6101da366004611122565b603160209081526000938452604080852082529284528284209052825290205460ff1681565b61013661020e366004611163565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff166100f9565b60015473ffffffffffffffffffffffffffffffffffffffff166100f9565b61013661025d3660046111fb565b610a58565b6002546100f99073ffffffffffffffffffffffffffffffffffffffff1681565b333b15610316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4552433732314272696467653a206163636f756e74206973206e6f742065787460448201527f65726e616c6c79206f776e65640000000000000000000000000000000000000060648201526084015b60405180910390fd5b6103268686333388888888610b30565b505050505050565b600054610100900460ff161580801561034e5750600054600160ff909116105b806103685750303b158015610368575060005460ff166001145b6103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161030d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561045257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556104b083734200000000000000000000000000000000000014610e70565b801561051357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611272565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff16331480156106865750600254600154604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9384169390921691636e296e45916004808201926020929091908290030181865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e9190611294565b73ffffffffffffffffffffffffffffffffffffffff16145b610712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4552433732314272696467653a2066756e6374696f6e2063616e206f6e6c792060448201527f62652063616c6c65642066726f6d20746865206f746865722062726964676500606482015260840161030d565b61071a610518565b15610781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c314552433732314272696467653a2070617573656400000000000000000000604482015260640161030d565b3073ffffffffffffffffffffffffffffffffffffffff881603610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4c314552433732314272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c6600000000000000000000000000000000000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152603160209081526040808320938a1683529281528282208683529052205460ff1615156001146108f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4c314552433732314272696467653a20546f6b656e204944206973206e6f742060448201527f657363726f77656420696e20746865204c312042726964676500000000000000606482015260840161030d565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526031602090815260408083208b8616845282528083208884529091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152918616602483015260448201859052906342842e0e90606401600060405180830381600087803b1580156109b557600080fd5b505af11580156109c9573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f1f39bf6707b5d608453e0ae4c067b562bcc4c85c0f562ef5d2c774d2e7f131ac87878787604051610a4794939291906112fa565b60405180910390a450505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516610afb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4552433732314272696467653a206e667420726563697069656e742063616e6e60448201527f6f74206265206164647265737328302900000000000000000000000000000000606482015260840161030d565b610b0b8787338888888888610b30565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b73ffffffffffffffffffffffffffffffffffffffff8716610bd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4c314552433732314272696467653a2072656d6f746520746f6b656e2063616e60448201527f6e6f742062652061646472657373283029000000000000000000000000000000606482015260840161030d565b600063761f449360e01b888a8989898888604051602401610bfa979695949392919061133a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000959095169490941790935273ffffffffffffffffffffffffffffffffffffffff8c81166000818152603186528381208e8416825286528381208b82529095529382902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590517f23b872dd000000000000000000000000000000000000000000000000000000008152908a166004820152306024820152604481018890529092506323b872dd90606401600060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b50506001546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169450633dbb202b9350610db1929091169085908990600401611397565b600060405180830381600087803b158015610dcb57600080fd5b505af1158015610ddf573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fb7460e2a880f256ebef3406116ff3eee0cee51ebccdc2a40698f87ebb2e9c1a589898888604051610e5d94939291906112fa565b60405180910390a4505050505050505050565b600054610100900460ff16610f07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161030d565b6001805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560028054929093169116179055565b73ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b50565b803563ffffffff81168114610f9357600080fd5b919050565b60008083601f840112610faa57600080fd5b50813567ffffffffffffffff811115610fc257600080fd5b602083019150836020828501011115610fda57600080fd5b9250929050565b60008060008060008060a08789031215610ffa57600080fd5b863561100581610f5a565b9550602087013561101581610f5a565b94506040870135935061102a60608801610f7f565b9250608087013567ffffffffffffffff81111561104657600080fd5b61105289828a01610f98565b979a9699509497509295939492505050565b6000806040838503121561107757600080fd5b823561108281610f5a565b9150602083013561109281610f5a565b809150509250929050565b6000815180845260005b818110156110c3576020818501810151868301820152016110a7565b818111156110d5576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061111b602083018461109d565b9392505050565b60008060006060848603121561113757600080fd5b833561114281610f5a565b9250602084013561115281610f5a565b929592945050506040919091013590565b600080600080600080600060c0888a03121561117e57600080fd5b873561118981610f5a565b9650602088013561119981610f5a565b955060408801356111a981610f5a565b945060608801356111b981610f5a565b93506080880135925060a088013567ffffffffffffffff8111156111dc57600080fd5b6111e88a828b01610f98565b989b979a50959850939692959293505050565b600080600080600080600060c0888a03121561121657600080fd5b873561122181610f5a565b9650602088013561123181610f5a565b9550604088013561124181610f5a565b94506060880135935061125660808901610f7f565b925060a088013567ffffffffffffffff8111156111dc57600080fd5b60006020828403121561128457600080fd5b8151801515811461111b57600080fd5b6000602082840312156112a657600080fd5b815161111b81610f5a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006113306060830184866112b1565b9695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261138a60c0830184866112b1565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006113c6606083018561109d565b905063ffffffff8316604083015294935050505056fea164736f6c634300080f000a", + "initialized": true, + "kind": "Create", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": true, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x7f46ddb2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000014", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xc89701a2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000014", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x927ede2d", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x3cb747bf", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x68ea2a43", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", + "previousValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000017" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xd2354f20", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000000d" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x81143a59", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000834", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000834", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000002b" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0ac77bb5", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x00000000000000000000000000000000000000000000000000000000000f4240", + "previousValue": "0x00000000000000000000000000000000000000000000000000000000000f4240", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000002c" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x2dde36f5", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", + "previousValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000029" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xe7d6cd42", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000015" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9c16360f", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", + "previousValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000016" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000003049623609d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002640bbb79680000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f42400000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc00000000000000000000000000000000000000000000000000000000017d78400000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb000000000000000000000000978e3286eb805934215a88694d80b09aded68d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000003049623609d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002640bbb79680000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f42400000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc00000000000000000000000000000000000000000000000000000000017d78400000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb000000000000000000000000978e3286eb805934215a88694d80b09aded68d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000003", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" + } + ], + "value": 0 + }, + { + "accessor": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9623609d0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002640bbb79680000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f42400000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc00000000000000000000000000000000000000000000000000000000017d78400000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb000000000000000000000000978e3286eb805934215a88694d80b09aded68d90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x727598a658f6983be3a9f29beef55aaee89ef8a176baeeacbe7edf5ff94a781b" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x4f1ef286000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002640bbb79680000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f42400000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc00000000000000000000000000000000000000000000000000000000017d78400000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb000000000000000000000000978e3286eb805934215a88694d80b09aded68d90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0bbb79680000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f42400000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc00000000000000000000000000000000000000000000000000000000017d78400000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb000000000000000000000000978e3286eb805934215a88694d80b09aded68d900000000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000067" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000834", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000065" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x00000000000000000000000000000000000000000000000000000000000f4240", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000066" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc597" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580636" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a7" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6376" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871815" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x000000000000000000000000978e3286eb805934215a88694d80b09aded68d90", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ac" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320c" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", + "previousValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000ffffffffffffffffffffffffffffffff000f42403b9aca00080a01312d00", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000ffffffffffffffffffffffffffffffff000f42403b9aca00080a01312d00", + "previousValue": "0x0000ffffffffffffffffffffffffffffffff000f42403b9aca00080a01312d00", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xcc731b02", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xcc731b02", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000ffffffffffffffffffffffffffffffff000f42403b9aca00080a01312d00", + "previousValue": "0x0000ffffffffffffffffffffffffffffffff000f42403b9aca00080a01312d00", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000069" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xd2354f20", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000000d" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8da5cb5b", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000033" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x81143a59", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000834", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000834", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000002b" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0c18c162", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0c18c162", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000834", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000834", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000065" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0ac77bb5", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x00000000000000000000000000000000000000000000000000000000000f4240", + "previousValue": "0x00000000000000000000000000000000000000000000000000000000000f4240", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000002c" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf45e65d8", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf45e65d8", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x00000000000000000000000000000000000000000000000000000000000f4240", + "previousValue": "0x00000000000000000000000000000000000000000000000000000000000f4240", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000066" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x68ea2a43", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", + "previousValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000017" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xe81b2c6d", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xe81b2c6d", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", + "previousValue": "0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000067" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x2dde36f5", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", + "previousValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000029" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf68016b7", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf68016b7", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", + "previousValue": "0x00000000000000000000000000000000000000000000000000000000017d7840", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000068" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xe7d6cd42", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000015" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x1fd19ee1", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x1fd19ee1", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x102c9aa4", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000039" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x48cd4cb1", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x48cd4cb1", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb19f" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9c16360f", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", + "previousValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000016" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xdac6e63a", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xdac6e63a", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", + "previousValue": "0x000000000000000000000000ff00000000000000000000000000000000000000", + "reverted": false, + "slot": "0x71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc597" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xa7119869", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xa7119869", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "previousValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "reverted": false, + "slot": "0x383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580636" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xc4e8ddfa", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xc4e8ddfa", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", + "previousValue": "0x000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f", + "reverted": false, + "slot": "0x46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a7" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x078f29cf", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x078f29cf", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", + "previousValue": "0x0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", + "reverted": false, + "slot": "0x9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6376" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x4d9f1559", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x4d9f1559", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb", + "previousValue": "0x0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb", + "reverted": false, + "slot": "0xe52a667f71ec761b9b381c7b76ca9b852adf7e8905da0e0ad49986a0a6871815" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0a49cb03", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0a49cb03", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000978e3286eb805934215a88694d80b09aded68d90", + "previousValue": "0x000000000000000000000000978e3286eb805934215a88694d80b09aded68d90", + "reverted": false, + "slot": "0x4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ac" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9b7d7f0a", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "previousValue": "0x000000000000000000000000ffba8944650e26653823658d76a122946f27e2f2", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xffbA8944650e26653823658d76A122946F27e2f2", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9b7d7f0a", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x1c23A6d89F95ef3148BCDA8E242cAb145bf9c0E4", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320c" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6bd9f5160000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa8f0d50211ac8ff1a40793a899dff3ced4762e0466f69b0078ab7b00d037835c" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000448d52d4a00000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000448d52d4a00000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000003", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000003", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000003", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000003", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000003", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" + } + ], + "value": 0 + }, + { + "accessor": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8d52d4a00000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000000000000000000000000000000000000000000001", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa8f0d50211ac8ff1a40793a899dff3ced4762e0466f69b0078ab7b00d037835c" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa8f0d50211ac8ff1a40793a899dff3ced4762e0466f69b0078ab7b00d037835c" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6bd9f5160000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa6", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xa8f0d50211ac8ff1a40793a899dff3ced4762e0466f69b0078ab7b00d037835c" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc95500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc95500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000004", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000004", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000005", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000004", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" + } + ], + "value": 0 + }, + { + "accessor": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9623609d0000000000000000000000000c8b5822b6e02cda722174f19a1439a7495a3fa60000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc95500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xa8f0d50211ac8ff1a40793a899dff3ced4762e0466f69b0078ab7b00d037835c" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xa8f0d50211ac8ff1a40793a899dff3ced4762e0466f69b0078ab7b00d037835c" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9b0b0fda360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": true, + "newValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x485cc95500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xb7947262", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "previousValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x485cc95500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": true, + "newValue": "0x000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": true, + "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": true, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xb7947262", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "previousValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x927ede2d", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xb7947262", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "previousValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x927ede2d", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "previousValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x3cb747bf", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xb7947262", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "previousValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x3cb747bf", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "previousValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x7f46ddb2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xb7947262", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "previousValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x7f46ddb2", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000010", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xc89701a2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xb7947262", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "previousValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xc89701a2", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000010", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000010", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + } + ], + "value": 0 + }, + { + "accessor": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xb7947262", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "previousValue": "0x0000000000000000000000000da314776b267d898dee57f6ede357ae28b3b83c", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x0Da314776B267D898dEE57F6Ede357ae28b3b83c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x0c8b5822b6e02CDa722174F19A1439A7495a3fA6", + "isWrite": false, + "newValue": "0x000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "previousValue": "0x000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd058600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc95500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd058600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc95500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000005", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000005", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000005", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000005", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000005", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" + } + ], + "value": 0 + }, + { + "accessor": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9623609d000000000000000000000000def3bca8c80064589e6787477ffa7dd616b5574f00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd058600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc95500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x191cda7b5a8219e0cc3bb6c2b45be830e3ba520f78e119446a476c4147fcc284" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x4f1ef28600000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd058600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000044485cc95500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": true, + "newValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x485cc95500000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": true, + "newValue": "0x000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": true, + "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": true, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "previousValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x7f46ddb2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "previousValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x7f46ddb2", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000014", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xc89701a2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "previousValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xc89701a2", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000014", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000014", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000002" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x927ede2d", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "previousValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x927ede2d", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "previousValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x3cb747bf", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "previousValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x3cb747bf", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "previousValue": "0x00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "previousValue": "0x00000000000000000000000044637a4292e0cd2b17a55d5f6b2f05afcacd0586", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x44637A4292E0CD2B17A55d5F6B2F05AFcAcD0586", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDeF3bca8c80064589E6787477FFa7Dd616B5574F", + "isWrite": false, + "newValue": "0x000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "previousValue": "0x000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6bd9f51600000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000448d52d4a000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000448d52d4a000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000006", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000007", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" + } + ], + "value": 0 + }, + { + "accessor": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x8d52d4a000000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d0000000000000000000000000000000000000000000000000000000000000002", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6bd9f51600000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x238181ae00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa84149e805fd07fd65e6292517ce28bc2d9d17991b87a6d9c16e7c7cb921ab16" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0xa84149e805fd07fd65e6292517ce28bc2d9d17991b87a6d9c16e7c7cb921ab16" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000084860f7cda00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e6765720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000084860f7cda00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e6765720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000007", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000007", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000007", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000007", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000008", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000007", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" + } + ], + "value": 0 + }, + { + "accessor": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x860f7cda00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x17eb2365d570ef4d1cc4abe9e522ed8632b11233db9c15f3c2c8aa32407b981b" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": true, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x17eb2365d570ef4d1cc4abe9e522ed8632b11233db9c15f3c2c8aa32407b981b" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x238181ae00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x17eb2365d570ef4d1cc4abe9e522ed8632b11233db9c15f3c2c8aa32407b981b" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x17eb2365d570ef4d1cc4abe9e522ed8632b11233db9c15f3c2c8aa32407b981b" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x17eb2365d570ef4d1cc4abe9e522ed8632b11233db9c15f3c2c8aa32407b981b" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000978e3286eb805934215a88694d80b09aded68d90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000e49623609d00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000978e3286eb805934215a88694d80b09aded68d90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000008", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000008", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000008", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000008", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000009", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000008", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" + } + ], + "value": 0 + }, + { + "accessor": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9623609d00000000000000000000000020a42a5a785622c6ba2576b2d6e924aa82bfa11d00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000978e3286eb805934215a88694d80b09aded68d9000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x17eb2365d570ef4d1cc4abe9e522ed8632b11233db9c15f3c2c8aa32407b981b" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x17eb2365d570ef4d1cc4abe9e522ed8632b11233db9c15f3c2c8aa32407b981b" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x17eb2365d570ef4d1cc4abe9e522ed8632b11233db9c15f3c2c8aa32407b981b" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000003" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9b2ea4bd000000000000000000000000000000000000000000000000000000000000004000000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" + }, + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": true, + "newValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x485cc955000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000978e3286eb805934215a88694d80b09aded68d90", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x4505be7acf20898edfef2b5289635349881ad9bf4b57316a74e81e2abec2be52" + } + ], + "value": 0 + }, + { + "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "previousValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "reverted": false, + "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x485cc955000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000978e3286eb805934215a88694d80b09aded68d90", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": true, + "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000010000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": true, + "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000010000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": true, + "newValue": "0x000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": true, + "newValue": "0x000000000000000000000000978e3286eb805934215a88694d80b09aded68d90", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": true, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cc" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": true, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": true, + "newValue": "0x0000000000000000000000010000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000001010000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x4505be7acf20898edfef2b5289635349881ad9bf4b57316a74e81e2abec2be52" + } + ], + "value": 0 + }, + { + "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "previousValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "reverted": false, + "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9fce812c", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x4505be7acf20898edfef2b5289635349881ad9bf4b57316a74e81e2abec2be52" + } + ], + "value": 0 + }, + { + "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "previousValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "reverted": false, + "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9fce812c", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000007", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xdb505d80", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x4505be7acf20898edfef2b5289635349881ad9bf4b57316a74e81e2abec2be52" + } + ], + "value": 0 + }, + { + "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "previousValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "reverted": false, + "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xdb505d80", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x0000000000000000000000004200000000000000000000000000000000000007", + "previousValue": "0x0000000000000000000000004200000000000000000000000000000000000007", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000cf" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0ff754ea", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x4505be7acf20898edfef2b5289635349881ad9bf4b57316a74e81e2abec2be52" + } + ], + "value": 0 + }, + { + "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "previousValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "reverted": false, + "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x0ff754ea", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x000000000000000000000000978e3286eb805934215a88694d80b09aded68d90", + "previousValue": "0x000000000000000000000000978e3286eb805934215a88694d80b09aded68d90", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6425666b", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x4505be7acf20898edfef2b5289635349881ad9bf4b57316a74e81e2abec2be52" + } + ], + "value": 0 + }, + { + "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "previousValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "reverted": false, + "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6425666b", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x000000000000000000000000978e3286eb805934215a88694d80b09aded68d90", + "previousValue": "0x000000000000000000000000978e3286eb805934215a88694d80b09aded68d90", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "previousValue": "0x000000000000000000000000bb2180ebd78ce97360503434ed37fcf4a1df61c3", + "reverted": false, + "slot": "0x540cf4e2f45b866b44f44bde51e109474016dc46a0670fbe1684ad8eaf90fdc3" + }, + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "previousValue": "0x4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000034", + "reverted": false, + "slot": "0x4505be7acf20898edfef2b5289635349881ad9bf4b57316a74e81e2abec2be52" + } + ], + "value": 0 + }, + { + "accessor": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xbf40fac10000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3", + "isWrite": false, + "newValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "previousValue": "0x00000000000000000000000071fa82ea96672797954c28032b337aa40aafc99f", + "reverted": false, + "slot": "0x515216935740e67dfdda5cf8e248ea32b3277787818ab59153061ac875c9385e" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x71fA82Ea96672797954C28032b337aA40AAFC99f", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x20A42a5a785622c6Ba2576B2D6e924aA82BFA11D", + "isWrite": false, + "newValue": "0x000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "previousValue": "0x000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "reverted": false, + "slot": "0x00000000000000000000000000000000000000000000000000000000000000fb" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000978e3286eb805934215a88694d80b09aded68d900000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "previousValue": "0x00000000000000000000000090193c961a926261b756d1e5bb255e67ff9498a1", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x90193C961A926261B756D1E5bb255e67ff9498A1", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x6a761202000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000978e3286eb805934215a88694d80b09aded68d900000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000001804c8ab1f12e6bbf3894d4083f33e07309d1f3800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000009", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000009", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000009", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000009", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": true, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000000a", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000009", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0xd1b0d319c6526317dce66989b393dcfb4435c9a65e399a088b63bbf65d7aee32" + }, + { + "account": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8" + } + ], + "value": 0 + }, + { + "accessor": "0x2601573C28B77dea6C8B73385c25024A28a00C3F", + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9623609d000000000000000000000000978e3286eb805934215a88694d80b09aded68d900000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "previousValue": "0x0000000000000000000000002601573c28b77dea6c8b73385c25024a28a00c3f", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x9302c2c5f397028777ab180924fb28ceaf3af9b6a91b43410c4c0afe36476877" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x4f1ef2860000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064c0c53b8b0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900000000000000000000000000000000000000000000000000000000", + "deployedCode": "0x", + "initialized": true, + "kind": "Call", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "previousValue": "0x000000000000000000000000db8cff278adccf9e9b5da745b44e754fc4ee3c76", + "reverted": false, + "slot": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": true, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xc0c53b8b0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4000000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d70809", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": true, + "newValue": "0x0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": true, + "newValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": true, + "newValue": "0x0000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": true, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": true, + "newValue": "0x000000000000000100000000000000000000000000000000000000003b9aca00", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": true, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000101", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x54fd4d50", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xfa60f9b2", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x9568d36E291c2C4c34fa5593fcE73715abEf6F9c", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0x000000000000000000000000000000000000000000000000000000000000000e" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": false, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x001c2ff6", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x001c2ff6", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb", + "previousValue": "0x0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9b5f694a", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9b5f694a", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb", + "previousValue": "0x0000000000000000000000008b71b41d4dbeb2b6821d44692d3facaaf77480bb", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000036" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf0498750", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0xf0498750", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", + "previousValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x33d7e2bd", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x33d7e2bd", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", + "previousValue": "0x0000000000000000000000001c23a6d89f95ef3148bcda8e242cab145bf9c0e4", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000037" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x724c184c", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x724c184c", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900", + "previousValue": "0x0000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" + } + ], + "value": 0 + }, + { + "accessor": "0x978e3286EB805934215a88694d80b09aDed68D90", + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x452a9320", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x978e3286EB805934215a88694d80b09aDed68D90", + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x452a9320", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x452a9320", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x452a9320", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900", + "previousValue": "0x0000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" + } + ], + "value": 0 + }, + { + "accessor": "0x978e3286EB805934215a88694d80b09aDed68D90", + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x452a9320", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x978e3286EB805934215a88694d80b09aDed68D90", + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x452a9320", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "previousValue": "0x0000000000000000000000009965507d1a55bcc2695c58ba16fb37d819b0a4dc", + "reverted": false, + "slot": "0xd30e835d3f35624761057ff5b27d558f97bd5be034621e62240e5c0b784abe68" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x35e80ab3", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900", + "previousValue": "0x0000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x5c975abb", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x5c975abb", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b6" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x5c975abb", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x5c975abb", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900", + "previousValue": "0x0000000000000000000000deb1e9a6be7baf84208bb6e10ac9f9bbe1d7080900", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000035" + } + ], + "value": 0 + }, + { + "accessor": "0x978e3286EB805934215a88694d80b09aDed68D90", + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x5c975abb", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "previousValue": "0x000000000000000000000000068e44eb31e111028c41598e4535be7468674d0a", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x978e3286EB805934215a88694d80b09aDed68D90", + "account": "0x068E44eB31e111028c41598E4535be7468674D0A", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x5c975abb", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70809", + "isWrite": false, + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "reverted": false, + "slot": "0x54176ff9944c4784e5857ec4e5ef560a462c483bf534eda43f91bb01a470b1b6" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9bf62d82", + "deployedCode": "0x", + "initialized": true, + "kind": "StaticCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "previousValue": "0x0000000000000000000000008887e7568e81405c4e0d4caaabdda949e3b9d4e4", + "reverted": false, + "slot": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" + } + ], + "value": 0 + }, + { + "accessor": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "account": "0x8887E7568E81405c4E0D4cAaabdda949e3B9d4E4", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x9bf62d82", + "deployedCode": "0x", + "initialized": true, + "kind": "DelegateCall", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [ + { + "account": "0x978e3286EB805934215a88694d80b09aDed68D90", + "isWrite": false, + "newValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "previousValue": "0x000000000000000000000000000000000000000000000000000000000000dead", + "reverted": false, + "slot": "0x0000000000000000000000000000000000000000000000000000000000000032" + } + ], + "value": 0 + }, + { + "accessor": "0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496", + "account": "0x7109709ECfa91a80626fF3989D68f67F5b1DD12D", + "chainInfo": { + "chainId": 31337, + "forkId": 0 + }, + "data": "0x", + "deployedCode": "0x", + "initialized": true, + "kind": "Resume", + "newBalance": 0, + "oldBalance": 0, + "reverted": false, + "storageAccesses": [], + "value": 0 + } + ] +} diff --git a/packages/contracts-bedrock/snapshots/storageLayout/AddressManager.json b/packages/contracts-bedrock/snapshots/storageLayout/AddressManager.json new file mode 100644 index 000000000000..656b0f453f49 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/AddressManager.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "20", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "address" + }, + { + "bytes": "32", + "label": "addresses", + "offset": 0, + "slot": "1", + "type": "mapping(bytes32 => address)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/AdminFaucetAuthModule.json b/packages/contracts-bedrock/snapshots/storageLayout/AdminFaucetAuthModule.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/AdminFaucetAuthModule.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json b/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json new file mode 100644 index 000000000000..5da4030ae426 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/AnchorStateRegistry.json @@ -0,0 +1,23 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "32", + "label": "anchors", + "offset": 0, + "slot": "1", + "type": "mapping(GameType => struct OutputRoot)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/AssetReceiver.json b/packages/contracts-bedrock/snapshots/storageLayout/AssetReceiver.json new file mode 100644 index 000000000000..08fcce9479d5 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/AssetReceiver.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "20", + "label": "owner", + "offset": 0, + "slot": "0", + "type": "address" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/AttestationStation.json b/packages/contracts-bedrock/snapshots/storageLayout/AttestationStation.json new file mode 100644 index 000000000000..c3c732cec14d --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/AttestationStation.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "32", + "label": "attestations", + "offset": 0, + "slot": "0", + "type": "mapping(address => mapping(address => mapping(bytes32 => bytes)))" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/BaseFeeVault.json b/packages/contracts-bedrock/snapshots/storageLayout/BaseFeeVault.json new file mode 100644 index 000000000000..ee2c5925c712 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/BaseFeeVault.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "32", + "label": "totalProcessed", + "offset": 0, + "slot": "0", + "type": "uint256" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/BlockOracle.json b/packages/contracts-bedrock/snapshots/storageLayout/BlockOracle.json new file mode 100644 index 000000000000..e897a9201ea8 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/BlockOracle.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "32", + "label": "blocks", + "offset": 0, + "slot": "0", + "type": "mapping(uint256 => struct BlockOracle.BlockInfo)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/Burner.json b/packages/contracts-bedrock/snapshots/storageLayout/Burner.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/Burner.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/CheckBalanceLow.json b/packages/contracts-bedrock/snapshots/storageLayout/CheckBalanceLow.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/CheckBalanceLow.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/CheckGelatoLow.json b/packages/contracts-bedrock/snapshots/storageLayout/CheckGelatoLow.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/CheckGelatoLow.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/CheckTrue.json b/packages/contracts-bedrock/snapshots/storageLayout/CheckTrue.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/CheckTrue.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/Clone.json b/packages/contracts-bedrock/snapshots/storageLayout/Clone.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/Clone.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/CrossDomainMessengerLegacySpacer0.json b/packages/contracts-bedrock/snapshots/storageLayout/CrossDomainMessengerLegacySpacer0.json new file mode 100644 index 000000000000..9bc33d142741 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/CrossDomainMessengerLegacySpacer0.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "20", + "label": "spacer_0_0_20", + "offset": 0, + "slot": "0", + "type": "address" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/CrossDomainMessengerLegacySpacer1.json b/packages/contracts-bedrock/snapshots/storageLayout/CrossDomainMessengerLegacySpacer1.json new file mode 100644 index 000000000000..ff157f517694 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/CrossDomainMessengerLegacySpacer1.json @@ -0,0 +1,65 @@ +[ + { + "bytes": "1600", + "label": "spacer_1_0_1600", + "offset": 0, + "slot": "0", + "type": "uint256[50]" + }, + { + "bytes": "20", + "label": "spacer_51_0_20", + "offset": 0, + "slot": "50", + "type": "address" + }, + { + "bytes": "1568", + "label": "spacer_52_0_1568", + "offset": 0, + "slot": "51", + "type": "uint256[49]" + }, + { + "bytes": "1", + "label": "spacer_101_0_1", + "offset": 0, + "slot": "100", + "type": "bool" + }, + { + "bytes": "1568", + "label": "spacer_102_0_1568", + "offset": 0, + "slot": "101", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "spacer_151_0_32", + "offset": 0, + "slot": "150", + "type": "uint256" + }, + { + "bytes": "1568", + "label": "spacer_152_0_1568", + "offset": 0, + "slot": "151", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "spacer_201_0_32", + "offset": 0, + "slot": "200", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "32", + "label": "spacer_202_0_32", + "offset": 0, + "slot": "201", + "type": "mapping(bytes32 => bool)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/DataAvailabilityChallenge.json b/packages/contracts-bedrock/snapshots/storageLayout/DataAvailabilityChallenge.json new file mode 100644 index 000000000000..95c66157adc8 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/DataAvailabilityChallenge.json @@ -0,0 +1,79 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "uint256[50]" + }, + { + "bytes": "20", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "address" + }, + { + "bytes": "1568", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "challengeWindow", + "offset": 0, + "slot": "101", + "type": "uint256" + }, + { + "bytes": "32", + "label": "resolveWindow", + "offset": 0, + "slot": "102", + "type": "uint256" + }, + { + "bytes": "32", + "label": "bondSize", + "offset": 0, + "slot": "103", + "type": "uint256" + }, + { + "bytes": "32", + "label": "resolverRefundPercentage", + "offset": 0, + "slot": "104", + "type": "uint256" + }, + { + "bytes": "32", + "label": "balances", + "offset": 0, + "slot": "105", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "challenges", + "offset": 0, + "slot": "106", + "type": "mapping(uint256 => mapping(bytes => struct Challenge))" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/DelayedVetoable.json b/packages/contracts-bedrock/snapshots/storageLayout/DelayedVetoable.json new file mode 100644 index 000000000000..7da3cbbe5bd6 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/DelayedVetoable.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "32", + "label": "_delay", + "offset": 0, + "slot": "0", + "type": "uint256" + }, + { + "bytes": "32", + "label": "_queuedAt", + "offset": 0, + "slot": "1", + "type": "mapping(bytes32 => uint256)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json b/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json new file mode 100644 index 000000000000..efc43f45893c --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/DelayedWETH.json @@ -0,0 +1,65 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "uint256[50]" + }, + { + "bytes": "20", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "address" + }, + { + "bytes": "1568", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "balanceOf", + "offset": 0, + "slot": "101", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "allowance", + "offset": 0, + "slot": "102", + "type": "mapping(address => mapping(address => uint256))" + }, + { + "bytes": "32", + "label": "withdrawals", + "offset": 0, + "slot": "103", + "type": "mapping(address => mapping(address => struct IDelayedWETH.WithdrawalRequest))" + }, + { + "bytes": "20", + "label": "config", + "offset": 0, + "slot": "104", + "type": "contract SuperchainConfig" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/DeployerWhitelist.json b/packages/contracts-bedrock/snapshots/storageLayout/DeployerWhitelist.json new file mode 100644 index 000000000000..282418cb9185 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/DeployerWhitelist.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "20", + "label": "owner", + "offset": 0, + "slot": "0", + "type": "address" + }, + { + "bytes": "32", + "label": "whitelist", + "offset": 0, + "slot": "1", + "type": "mapping(address => bool)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/DisputeGameFactory.json b/packages/contracts-bedrock/snapshots/storageLayout/DisputeGameFactory.json new file mode 100644 index 000000000000..f53a86716ca1 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/DisputeGameFactory.json @@ -0,0 +1,65 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "uint256[50]" + }, + { + "bytes": "20", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "address" + }, + { + "bytes": "1568", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "gameImpls", + "offset": 0, + "slot": "101", + "type": "mapping(GameType => contract IDisputeGame)" + }, + { + "bytes": "32", + "label": "initBonds", + "offset": 0, + "slot": "102", + "type": "mapping(GameType => uint256)" + }, + { + "bytes": "32", + "label": "_disputeGames", + "offset": 0, + "slot": "103", + "type": "mapping(Hash => GameId)" + }, + { + "bytes": "32", + "label": "_disputeGameList", + "offset": 0, + "slot": "104", + "type": "GameId[]" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/Drippie.json b/packages/contracts-bedrock/snapshots/storageLayout/Drippie.json new file mode 100644 index 000000000000..77b669eec61e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/Drippie.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "20", + "label": "owner", + "offset": 0, + "slot": "0", + "type": "address" + }, + { + "bytes": "32", + "label": "drips", + "offset": 0, + "slot": "1", + "type": "mapping(string => struct Drippie.DripState)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/EAS.json b/packages/contracts-bedrock/snapshots/storageLayout/EAS.json new file mode 100644 index 000000000000..172d64089dab --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/EAS.json @@ -0,0 +1,44 @@ +[ + { + "bytes": "32", + "label": "_nonces", + "offset": 0, + "slot": "0", + "type": "mapping(address => uint256)" + }, + { + "bytes": "1568", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "_db", + "offset": 0, + "slot": "50", + "type": "mapping(bytes32 => struct Attestation)" + }, + { + "bytes": "32", + "label": "_timestamps", + "offset": 0, + "slot": "51", + "type": "mapping(bytes32 => uint64)" + }, + { + "bytes": "32", + "label": "_revocationsOffchain", + "offset": 0, + "slot": "52", + "type": "mapping(address => mapping(bytes32 => uint64))" + }, + { + "bytes": "1504", + "label": "__gap", + "offset": 0, + "slot": "53", + "type": "uint256[47]" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/Faucet.json b/packages/contracts-bedrock/snapshots/storageLayout/Faucet.json new file mode 100644 index 000000000000..6ea6130d17cd --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/Faucet.json @@ -0,0 +1,23 @@ +[ + { + "bytes": "32", + "label": "modules", + "offset": 0, + "slot": "0", + "type": "mapping(contract IFaucetAuthModule => struct Faucet.ModuleConfig)" + }, + { + "bytes": "32", + "label": "timeouts", + "offset": 0, + "slot": "1", + "type": "mapping(contract IFaucetAuthModule => mapping(bytes32 => uint256))" + }, + { + "bytes": "32", + "label": "nonces", + "offset": 0, + "slot": "2", + "type": "mapping(bytes32 => mapping(bytes32 => bool))" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/FaultDisputeGame.json b/packages/contracts-bedrock/snapshots/storageLayout/FaultDisputeGame.json new file mode 100644 index 000000000000..67383f2a1c48 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/FaultDisputeGame.json @@ -0,0 +1,72 @@ +[ + { + "bytes": "8", + "label": "createdAt", + "offset": 0, + "slot": "0", + "type": "Timestamp" + }, + { + "bytes": "8", + "label": "resolvedAt", + "offset": 8, + "slot": "0", + "type": "Timestamp" + }, + { + "bytes": "1", + "label": "status", + "offset": 16, + "slot": "0", + "type": "enum GameStatus" + }, + { + "bytes": "32", + "label": "claimData", + "offset": 0, + "slot": "1", + "type": "struct IFaultDisputeGame.ClaimData[]" + }, + { + "bytes": "32", + "label": "credit", + "offset": 0, + "slot": "2", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "claims", + "offset": 0, + "slot": "3", + "type": "mapping(ClaimHash => bool)" + }, + { + "bytes": "32", + "label": "subgames", + "offset": 0, + "slot": "4", + "type": "mapping(uint256 => uint256[])" + }, + { + "bytes": "1", + "label": "subgameAtRootResolved", + "offset": 0, + "slot": "5", + "type": "bool" + }, + { + "bytes": "1", + "label": "initialized", + "offset": 1, + "slot": "5", + "type": "bool" + }, + { + "bytes": "64", + "label": "startingOutputRoot", + "offset": 0, + "slot": "6", + "type": "struct OutputRoot" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/GasPriceOracle.json b/packages/contracts-bedrock/snapshots/storageLayout/GasPriceOracle.json new file mode 100644 index 000000000000..9dd2e57a3d14 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/GasPriceOracle.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "1", + "label": "isEcotone", + "offset": 0, + "slot": "0", + "type": "bool" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/GovernanceToken.json b/packages/contracts-bedrock/snapshots/storageLayout/GovernanceToken.json new file mode 100644 index 000000000000..05a0f1223dd5 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/GovernanceToken.json @@ -0,0 +1,79 @@ +[ + { + "bytes": "32", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "mapping(address => mapping(address => uint256))" + }, + { + "bytes": "32", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "uint256" + }, + { + "bytes": "32", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "string" + }, + { + "bytes": "32", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "string" + }, + { + "bytes": "32", + "label": "_nonces", + "offset": 0, + "slot": "5", + "type": "mapping(address => struct Counters.Counter)" + }, + { + "bytes": "32", + "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", + "offset": 0, + "slot": "6", + "type": "bytes32" + }, + { + "bytes": "32", + "label": "_delegates", + "offset": 0, + "slot": "7", + "type": "mapping(address => address)" + }, + { + "bytes": "32", + "label": "_checkpoints", + "offset": 0, + "slot": "8", + "type": "mapping(address => struct ERC20Votes.Checkpoint[])" + }, + { + "bytes": "32", + "label": "_totalSupplyCheckpoints", + "offset": 0, + "slot": "9", + "type": "struct ERC20Votes.Checkpoint[]" + }, + { + "bytes": "20", + "label": "_owner", + "offset": 0, + "slot": "10", + "type": "address" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1Block.json b/packages/contracts-bedrock/snapshots/storageLayout/L1Block.json new file mode 100644 index 000000000000..2928d2147b5c --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1Block.json @@ -0,0 +1,79 @@ +[ + { + "bytes": "8", + "label": "number", + "offset": 0, + "slot": "0", + "type": "uint64" + }, + { + "bytes": "8", + "label": "timestamp", + "offset": 8, + "slot": "0", + "type": "uint64" + }, + { + "bytes": "32", + "label": "basefee", + "offset": 0, + "slot": "1", + "type": "uint256" + }, + { + "bytes": "32", + "label": "hash", + "offset": 0, + "slot": "2", + "type": "bytes32" + }, + { + "bytes": "8", + "label": "sequenceNumber", + "offset": 0, + "slot": "3", + "type": "uint64" + }, + { + "bytes": "4", + "label": "blobBaseFeeScalar", + "offset": 8, + "slot": "3", + "type": "uint32" + }, + { + "bytes": "4", + "label": "baseFeeScalar", + "offset": 12, + "slot": "3", + "type": "uint32" + }, + { + "bytes": "32", + "label": "batcherHash", + "offset": 0, + "slot": "4", + "type": "bytes32" + }, + { + "bytes": "32", + "label": "l1FeeOverhead", + "offset": 0, + "slot": "5", + "type": "uint256" + }, + { + "bytes": "32", + "label": "l1FeeScalar", + "offset": 0, + "slot": "6", + "type": "uint256" + }, + { + "bytes": "32", + "label": "blobBaseFee", + "offset": 0, + "slot": "7", + "type": "uint256" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1BlockNumber.json b/packages/contracts-bedrock/snapshots/storageLayout/L1BlockNumber.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1BlockNumber.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1ChugSplashProxy.json b/packages/contracts-bedrock/snapshots/storageLayout/L1ChugSplashProxy.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1ChugSplashProxy.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1CrossDomainMessenger.json b/packages/contracts-bedrock/snapshots/storageLayout/L1CrossDomainMessenger.json new file mode 100644 index 000000000000..cc9b5cfa86fc --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1CrossDomainMessenger.json @@ -0,0 +1,142 @@ +[ + { + "bytes": "20", + "label": "spacer_0_0_20", + "offset": 0, + "slot": "0", + "type": "address" + }, + { + "bytes": "1", + "label": "_initialized", + "offset": 20, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 21, + "slot": "0", + "type": "bool" + }, + { + "bytes": "1600", + "label": "spacer_1_0_1600", + "offset": 0, + "slot": "1", + "type": "uint256[50]" + }, + { + "bytes": "20", + "label": "spacer_51_0_20", + "offset": 0, + "slot": "51", + "type": "address" + }, + { + "bytes": "1568", + "label": "spacer_52_0_1568", + "offset": 0, + "slot": "52", + "type": "uint256[49]" + }, + { + "bytes": "1", + "label": "spacer_101_0_1", + "offset": 0, + "slot": "101", + "type": "bool" + }, + { + "bytes": "1568", + "label": "spacer_102_0_1568", + "offset": 0, + "slot": "102", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "spacer_151_0_32", + "offset": 0, + "slot": "151", + "type": "uint256" + }, + { + "bytes": "1568", + "label": "spacer_152_0_1568", + "offset": 0, + "slot": "152", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "spacer_201_0_32", + "offset": 0, + "slot": "201", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "32", + "label": "spacer_202_0_32", + "offset": 0, + "slot": "202", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "32", + "label": "successfulMessages", + "offset": 0, + "slot": "203", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "20", + "label": "xDomainMsgSender", + "offset": 0, + "slot": "204", + "type": "address" + }, + { + "bytes": "30", + "label": "msgNonce", + "offset": 0, + "slot": "205", + "type": "uint240" + }, + { + "bytes": "32", + "label": "failedMessages", + "offset": 0, + "slot": "206", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "20", + "label": "otherMessenger", + "offset": 0, + "slot": "207", + "type": "contract CrossDomainMessenger" + }, + { + "bytes": "1376", + "label": "__gap", + "offset": 0, + "slot": "208", + "type": "uint256[43]" + }, + { + "bytes": "20", + "label": "superchainConfig", + "offset": 0, + "slot": "251", + "type": "contract SuperchainConfig" + }, + { + "bytes": "20", + "label": "portal", + "offset": 0, + "slot": "252", + "type": "contract OptimismPortal" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1ERC721Bridge.json b/packages/contracts-bedrock/snapshots/storageLayout/L1ERC721Bridge.json new file mode 100644 index 000000000000..c384762b3ba2 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1ERC721Bridge.json @@ -0,0 +1,58 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "30", + "label": "spacer_0_2_30", + "offset": 2, + "slot": "0", + "type": "bytes30" + }, + { + "bytes": "20", + "label": "messenger", + "offset": 0, + "slot": "1", + "type": "contract CrossDomainMessenger" + }, + { + "bytes": "20", + "label": "otherBridge", + "offset": 0, + "slot": "2", + "type": "contract StandardBridge" + }, + { + "bytes": "1472", + "label": "__gap", + "offset": 0, + "slot": "3", + "type": "uint256[46]" + }, + { + "bytes": "32", + "label": "deposits", + "offset": 0, + "slot": "49", + "type": "mapping(address => mapping(address => mapping(uint256 => bool)))" + }, + { + "bytes": "20", + "label": "superchainConfig", + "offset": 0, + "slot": "50", + "type": "contract SuperchainConfig" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1FeeVault.json b/packages/contracts-bedrock/snapshots/storageLayout/L1FeeVault.json new file mode 100644 index 000000000000..ee2c5925c712 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1FeeVault.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "32", + "label": "totalProcessed", + "offset": 0, + "slot": "0", + "type": "uint256" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1StandardBridge.json b/packages/contracts-bedrock/snapshots/storageLayout/L1StandardBridge.json new file mode 100644 index 000000000000..48ec70c8b508 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1StandardBridge.json @@ -0,0 +1,65 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "30", + "label": "spacer_0_2_30", + "offset": 2, + "slot": "0", + "type": "bytes30" + }, + { + "bytes": "20", + "label": "spacer_1_0_20", + "offset": 0, + "slot": "1", + "type": "address" + }, + { + "bytes": "32", + "label": "deposits", + "offset": 0, + "slot": "2", + "type": "mapping(address => mapping(address => uint256))" + }, + { + "bytes": "20", + "label": "messenger", + "offset": 0, + "slot": "3", + "type": "contract CrossDomainMessenger" + }, + { + "bytes": "20", + "label": "otherBridge", + "offset": 0, + "slot": "4", + "type": "contract StandardBridge" + }, + { + "bytes": "1440", + "label": "__gap", + "offset": 0, + "slot": "5", + "type": "uint256[45]" + }, + { + "bytes": "20", + "label": "superchainConfig", + "offset": 0, + "slot": "50", + "type": "contract SuperchainConfig" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L2CrossDomainMessenger.json b/packages/contracts-bedrock/snapshots/storageLayout/L2CrossDomainMessenger.json new file mode 100644 index 000000000000..dec784b5a32e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L2CrossDomainMessenger.json @@ -0,0 +1,128 @@ +[ + { + "bytes": "20", + "label": "spacer_0_0_20", + "offset": 0, + "slot": "0", + "type": "address" + }, + { + "bytes": "1", + "label": "_initialized", + "offset": 20, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 21, + "slot": "0", + "type": "bool" + }, + { + "bytes": "1600", + "label": "spacer_1_0_1600", + "offset": 0, + "slot": "1", + "type": "uint256[50]" + }, + { + "bytes": "20", + "label": "spacer_51_0_20", + "offset": 0, + "slot": "51", + "type": "address" + }, + { + "bytes": "1568", + "label": "spacer_52_0_1568", + "offset": 0, + "slot": "52", + "type": "uint256[49]" + }, + { + "bytes": "1", + "label": "spacer_101_0_1", + "offset": 0, + "slot": "101", + "type": "bool" + }, + { + "bytes": "1568", + "label": "spacer_102_0_1568", + "offset": 0, + "slot": "102", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "spacer_151_0_32", + "offset": 0, + "slot": "151", + "type": "uint256" + }, + { + "bytes": "1568", + "label": "spacer_152_0_1568", + "offset": 0, + "slot": "152", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "spacer_201_0_32", + "offset": 0, + "slot": "201", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "32", + "label": "spacer_202_0_32", + "offset": 0, + "slot": "202", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "32", + "label": "successfulMessages", + "offset": 0, + "slot": "203", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "20", + "label": "xDomainMsgSender", + "offset": 0, + "slot": "204", + "type": "address" + }, + { + "bytes": "30", + "label": "msgNonce", + "offset": 0, + "slot": "205", + "type": "uint240" + }, + { + "bytes": "32", + "label": "failedMessages", + "offset": 0, + "slot": "206", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "20", + "label": "otherMessenger", + "offset": 0, + "slot": "207", + "type": "contract CrossDomainMessenger" + }, + { + "bytes": "1376", + "label": "__gap", + "offset": 0, + "slot": "208", + "type": "uint256[43]" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L2ERC721Bridge.json b/packages/contracts-bedrock/snapshots/storageLayout/L2ERC721Bridge.json new file mode 100644 index 000000000000..46d4aea469b7 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L2ERC721Bridge.json @@ -0,0 +1,44 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "30", + "label": "spacer_0_2_30", + "offset": 2, + "slot": "0", + "type": "bytes30" + }, + { + "bytes": "20", + "label": "messenger", + "offset": 0, + "slot": "1", + "type": "contract CrossDomainMessenger" + }, + { + "bytes": "20", + "label": "otherBridge", + "offset": 0, + "slot": "2", + "type": "contract StandardBridge" + }, + { + "bytes": "1472", + "label": "__gap", + "offset": 0, + "slot": "3", + "type": "uint256[46]" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L2OutputOracle.json b/packages/contracts-bedrock/snapshots/storageLayout/L2OutputOracle.json new file mode 100644 index 000000000000..ed62ff20d838 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L2OutputOracle.json @@ -0,0 +1,72 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "32", + "label": "startingBlockNumber", + "offset": 0, + "slot": "1", + "type": "uint256" + }, + { + "bytes": "32", + "label": "startingTimestamp", + "offset": 0, + "slot": "2", + "type": "uint256" + }, + { + "bytes": "32", + "label": "l2Outputs", + "offset": 0, + "slot": "3", + "type": "struct Types.OutputProposal[]" + }, + { + "bytes": "32", + "label": "submissionInterval", + "offset": 0, + "slot": "4", + "type": "uint256" + }, + { + "bytes": "32", + "label": "l2BlockTime", + "offset": 0, + "slot": "5", + "type": "uint256" + }, + { + "bytes": "20", + "label": "challenger", + "offset": 0, + "slot": "6", + "type": "address" + }, + { + "bytes": "20", + "label": "proposer", + "offset": 0, + "slot": "7", + "type": "address" + }, + { + "bytes": "32", + "label": "finalizationPeriodSeconds", + "offset": 0, + "slot": "8", + "type": "uint256" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridge.json b/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridge.json new file mode 100644 index 000000000000..f5effc6ae799 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L2StandardBridge.json @@ -0,0 +1,58 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "30", + "label": "spacer_0_2_30", + "offset": 2, + "slot": "0", + "type": "bytes30" + }, + { + "bytes": "20", + "label": "spacer_1_0_20", + "offset": 0, + "slot": "1", + "type": "address" + }, + { + "bytes": "32", + "label": "deposits", + "offset": 0, + "slot": "2", + "type": "mapping(address => mapping(address => uint256))" + }, + { + "bytes": "20", + "label": "messenger", + "offset": 0, + "slot": "3", + "type": "contract CrossDomainMessenger" + }, + { + "bytes": "20", + "label": "otherBridge", + "offset": 0, + "slot": "4", + "type": "contract StandardBridge" + }, + { + "bytes": "1440", + "label": "__gap", + "offset": 0, + "slot": "5", + "type": "uint256[45]" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L2ToL1MessagePasser.json b/packages/contracts-bedrock/snapshots/storageLayout/L2ToL1MessagePasser.json new file mode 100644 index 000000000000..09cc3b544013 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L2ToL1MessagePasser.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "32", + "label": "sentMessages", + "offset": 0, + "slot": "0", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "30", + "label": "msgNonce", + "offset": 0, + "slot": "1", + "type": "uint240" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/LegacyERC20ETH.json b/packages/contracts-bedrock/snapshots/storageLayout/LegacyERC20ETH.json new file mode 100644 index 000000000000..418a98546cf7 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/LegacyERC20ETH.json @@ -0,0 +1,37 @@ +[ + { + "bytes": "32", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "mapping(address => mapping(address => uint256))" + }, + { + "bytes": "32", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "uint256" + }, + { + "bytes": "32", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "string" + }, + { + "bytes": "32", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "string" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/LegacyFaultDisputeGame.json b/packages/contracts-bedrock/snapshots/storageLayout/LegacyFaultDisputeGame.json new file mode 100644 index 000000000000..56aa9cc0b800 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/LegacyFaultDisputeGame.json @@ -0,0 +1,58 @@ +[ + { + "bytes": "8", + "label": "createdAt", + "offset": 0, + "slot": "0", + "type": "Timestamp" + }, + { + "bytes": "1", + "label": "status", + "offset": 8, + "slot": "0", + "type": "enum GameStatus" + }, + { + "bytes": "32", + "label": "l1Head", + "offset": 0, + "slot": "1", + "type": "Hash" + }, + { + "bytes": "32", + "label": "claimData", + "offset": 0, + "slot": "2", + "type": "struct ILegacyFaultDisputeGame.ClaimData[]" + }, + { + "bytes": "128", + "label": "proposals", + "offset": 0, + "slot": "3", + "type": "struct ILegacyFaultDisputeGame.OutputProposals" + }, + { + "bytes": "32", + "label": "claims", + "offset": 0, + "slot": "7", + "type": "mapping(ClaimHash => bool)" + }, + { + "bytes": "32", + "label": "subgames", + "offset": 0, + "slot": "8", + "type": "mapping(uint256 => uint256[])" + }, + { + "bytes": "1", + "label": "subgameAtRootResolved", + "offset": 0, + "slot": "9", + "type": "bool" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/LegacyMessagePasser.json b/packages/contracts-bedrock/snapshots/storageLayout/LegacyMessagePasser.json new file mode 100644 index 000000000000..676c5dd398c6 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/LegacyMessagePasser.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "32", + "label": "sentMessages", + "offset": 0, + "slot": "0", + "type": "mapping(bytes32 => bool)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/LegacyMintableERC20.json b/packages/contracts-bedrock/snapshots/storageLayout/LegacyMintableERC20.json new file mode 100644 index 000000000000..1988a3f25127 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/LegacyMintableERC20.json @@ -0,0 +1,51 @@ +[ + { + "bytes": "32", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "mapping(address => mapping(address => uint256))" + }, + { + "bytes": "32", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "uint256" + }, + { + "bytes": "32", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "string" + }, + { + "bytes": "32", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "string" + }, + { + "bytes": "20", + "label": "l1Token", + "offset": 0, + "slot": "5", + "type": "address" + }, + { + "bytes": "20", + "label": "l2Bridge", + "offset": 0, + "slot": "6", + "type": "address" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/LivenessGuard.json b/packages/contracts-bedrock/snapshots/storageLayout/LivenessGuard.json new file mode 100644 index 000000000000..0e704a8dbb2e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/LivenessGuard.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "32", + "label": "lastLive", + "offset": 0, + "slot": "0", + "type": "mapping(address => uint256)" + }, + { + "bytes": "64", + "label": "ownersBefore", + "offset": 0, + "slot": "1", + "type": "struct EnumerableSet.AddressSet" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/LivenessModule.json b/packages/contracts-bedrock/snapshots/storageLayout/LivenessModule.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/LivenessModule.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/MIPS.json b/packages/contracts-bedrock/snapshots/storageLayout/MIPS.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/MIPS.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/MintManager.json b/packages/contracts-bedrock/snapshots/storageLayout/MintManager.json new file mode 100644 index 000000000000..d82595415d47 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/MintManager.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "20", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "address" + }, + { + "bytes": "32", + "label": "mintPermittedAfter", + "offset": 0, + "slot": "1", + "type": "uint256" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC20.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC20.json new file mode 100644 index 000000000000..418a98546cf7 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC20.json @@ -0,0 +1,37 @@ +[ + { + "bytes": "32", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "mapping(address => mapping(address => uint256))" + }, + { + "bytes": "32", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "uint256" + }, + { + "bytes": "32", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "string" + }, + { + "bytes": "32", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "string" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC20Factory.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC20Factory.json new file mode 100644 index 000000000000..c39454b5e3eb --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC20Factory.json @@ -0,0 +1,37 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "30", + "label": "spacer_0_2_30", + "offset": 2, + "slot": "0", + "type": "bytes30" + }, + { + "bytes": "20", + "label": "bridge", + "offset": 0, + "slot": "1", + "type": "address" + }, + { + "bytes": "1568", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "uint256[49]" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC721.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC721.json new file mode 100644 index 000000000000..b8ed15f66020 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC721.json @@ -0,0 +1,79 @@ +[ + { + "bytes": "32", + "label": "_name", + "offset": 0, + "slot": "0", + "type": "string" + }, + { + "bytes": "32", + "label": "_symbol", + "offset": 0, + "slot": "1", + "type": "string" + }, + { + "bytes": "32", + "label": "_owners", + "offset": 0, + "slot": "2", + "type": "mapping(uint256 => address)" + }, + { + "bytes": "32", + "label": "_balances", + "offset": 0, + "slot": "3", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "_tokenApprovals", + "offset": 0, + "slot": "4", + "type": "mapping(uint256 => address)" + }, + { + "bytes": "32", + "label": "_operatorApprovals", + "offset": 0, + "slot": "5", + "type": "mapping(address => mapping(address => bool))" + }, + { + "bytes": "32", + "label": "_ownedTokens", + "offset": 0, + "slot": "6", + "type": "mapping(address => mapping(uint256 => uint256))" + }, + { + "bytes": "32", + "label": "_ownedTokensIndex", + "offset": 0, + "slot": "7", + "type": "mapping(uint256 => uint256)" + }, + { + "bytes": "32", + "label": "_allTokens", + "offset": 0, + "slot": "8", + "type": "uint256[]" + }, + { + "bytes": "32", + "label": "_allTokensIndex", + "offset": 0, + "slot": "9", + "type": "mapping(uint256 => uint256)" + }, + { + "bytes": "32", + "label": "baseTokenURI", + "offset": 0, + "slot": "10", + "type": "string" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC721Factory.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC721Factory.json new file mode 100644 index 000000000000..2c0076337f50 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismMintableERC721Factory.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "32", + "label": "isOptimismMintableERC721", + "offset": 0, + "slot": "0", + "type": "mapping(address => bool)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json new file mode 100644 index 000000000000..455fdf358772 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal.json @@ -0,0 +1,79 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "32", + "label": "params", + "offset": 0, + "slot": "1", + "type": "struct ResourceMetering.ResourceParams" + }, + { + "bytes": "1536", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "uint256[48]" + }, + { + "bytes": "20", + "label": "l2Sender", + "offset": 0, + "slot": "50", + "type": "address" + }, + { + "bytes": "32", + "label": "finalizedWithdrawals", + "offset": 0, + "slot": "51", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "32", + "label": "provenWithdrawals", + "offset": 0, + "slot": "52", + "type": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal)" + }, + { + "bytes": "1", + "label": "spacer_53_0_1", + "offset": 0, + "slot": "53", + "type": "bool" + }, + { + "bytes": "20", + "label": "superchainConfig", + "offset": 1, + "slot": "53", + "type": "contract SuperchainConfig" + }, + { + "bytes": "20", + "label": "l2Oracle", + "offset": 0, + "slot": "54", + "type": "contract L2OutputOracle" + }, + { + "bytes": "20", + "label": "systemConfig", + "offset": 0, + "slot": "55", + "type": "contract SystemConfig" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json new file mode 100644 index 000000000000..c18c6eb5cc2b --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json @@ -0,0 +1,114 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "32", + "label": "params", + "offset": 0, + "slot": "1", + "type": "struct ResourceMetering.ResourceParams" + }, + { + "bytes": "1536", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "uint256[48]" + }, + { + "bytes": "20", + "label": "l2Sender", + "offset": 0, + "slot": "50", + "type": "address" + }, + { + "bytes": "32", + "label": "finalizedWithdrawals", + "offset": 0, + "slot": "51", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "32", + "label": "spacer_52_0_32", + "offset": 0, + "slot": "52", + "type": "bytes32" + }, + { + "bytes": "1", + "label": "spacer_53_0_1", + "offset": 0, + "slot": "53", + "type": "bool" + }, + { + "bytes": "20", + "label": "superchainConfig", + "offset": 1, + "slot": "53", + "type": "contract SuperchainConfig" + }, + { + "bytes": "20", + "label": "spacer_54_0_20", + "offset": 0, + "slot": "54", + "type": "address" + }, + { + "bytes": "20", + "label": "systemConfig", + "offset": 0, + "slot": "55", + "type": "contract SystemConfig" + }, + { + "bytes": "20", + "label": "disputeGameFactory", + "offset": 0, + "slot": "56", + "type": "contract DisputeGameFactory" + }, + { + "bytes": "32", + "label": "provenWithdrawals", + "offset": 0, + "slot": "57", + "type": "mapping(bytes32 => struct OptimismPortal2.ProvenWithdrawal)" + }, + { + "bytes": "32", + "label": "disputeGameBlacklist", + "offset": 0, + "slot": "58", + "type": "mapping(contract IDisputeGame => bool)" + }, + { + "bytes": "4", + "label": "respectedGameType", + "offset": 0, + "slot": "59", + "type": "GameType" + }, + { + "bytes": "8", + "label": "respectedGameTypeUpdatedAt", + "offset": 4, + "slot": "59", + "type": "uint64" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/Optimist.json b/packages/contracts-bedrock/snapshots/storageLayout/Optimist.json new file mode 100644 index 000000000000..6049beb54245 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/Optimist.json @@ -0,0 +1,86 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "uint256[50]" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "uint256[50]" + }, + { + "bytes": "32", + "label": "_name", + "offset": 0, + "slot": "101", + "type": "string" + }, + { + "bytes": "32", + "label": "_symbol", + "offset": 0, + "slot": "102", + "type": "string" + }, + { + "bytes": "32", + "label": "_owners", + "offset": 0, + "slot": "103", + "type": "mapping(uint256 => address)" + }, + { + "bytes": "32", + "label": "_balances", + "offset": 0, + "slot": "104", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "_tokenApprovals", + "offset": 0, + "slot": "105", + "type": "mapping(uint256 => address)" + }, + { + "bytes": "32", + "label": "_operatorApprovals", + "offset": 0, + "slot": "106", + "type": "mapping(address => mapping(address => bool))" + }, + { + "bytes": "1408", + "label": "__gap", + "offset": 0, + "slot": "107", + "type": "uint256[44]" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "151", + "type": "uint256[50]" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimistAllowlist.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimistAllowlist.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimistAllowlist.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimistInviter.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimistInviter.json new file mode 100644 index 000000000000..5d1a6bbc43c9 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimistInviter.json @@ -0,0 +1,58 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "32", + "label": "_HASHED_NAME", + "offset": 0, + "slot": "1", + "type": "bytes32" + }, + { + "bytes": "32", + "label": "_HASHED_VERSION", + "offset": 0, + "slot": "2", + "type": "bytes32" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "3", + "type": "uint256[50]" + }, + { + "bytes": "32", + "label": "commitmentTimestamps", + "offset": 0, + "slot": "53", + "type": "mapping(bytes32 => uint256)" + }, + { + "bytes": "32", + "label": "usedNonces", + "offset": 0, + "slot": "54", + "type": "mapping(address => mapping(bytes32 => bool))" + }, + { + "bytes": "32", + "label": "inviteCounts", + "offset": 0, + "slot": "55", + "type": "mapping(address => uint256)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/PermissionedDisputeGame.json b/packages/contracts-bedrock/snapshots/storageLayout/PermissionedDisputeGame.json new file mode 100644 index 000000000000..67383f2a1c48 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/PermissionedDisputeGame.json @@ -0,0 +1,72 @@ +[ + { + "bytes": "8", + "label": "createdAt", + "offset": 0, + "slot": "0", + "type": "Timestamp" + }, + { + "bytes": "8", + "label": "resolvedAt", + "offset": 8, + "slot": "0", + "type": "Timestamp" + }, + { + "bytes": "1", + "label": "status", + "offset": 16, + "slot": "0", + "type": "enum GameStatus" + }, + { + "bytes": "32", + "label": "claimData", + "offset": 0, + "slot": "1", + "type": "struct IFaultDisputeGame.ClaimData[]" + }, + { + "bytes": "32", + "label": "credit", + "offset": 0, + "slot": "2", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "claims", + "offset": 0, + "slot": "3", + "type": "mapping(ClaimHash => bool)" + }, + { + "bytes": "32", + "label": "subgames", + "offset": 0, + "slot": "4", + "type": "mapping(uint256 => uint256[])" + }, + { + "bytes": "1", + "label": "subgameAtRootResolved", + "offset": 0, + "slot": "5", + "type": "bool" + }, + { + "bytes": "1", + "label": "initialized", + "offset": 1, + "slot": "5", + "type": "bool" + }, + { + "bytes": "64", + "label": "startingOutputRoot", + "offset": 0, + "slot": "6", + "type": "struct OutputRoot" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/PreimageOracle.json b/packages/contracts-bedrock/snapshots/storageLayout/PreimageOracle.json new file mode 100644 index 000000000000..fbbea6e3d656 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/PreimageOracle.json @@ -0,0 +1,72 @@ +[ + { + "bytes": "32", + "label": "preimageLengths", + "offset": 0, + "slot": "0", + "type": "mapping(bytes32 => uint256)" + }, + { + "bytes": "32", + "label": "preimageParts", + "offset": 0, + "slot": "1", + "type": "mapping(bytes32 => mapping(uint256 => bytes32))" + }, + { + "bytes": "32", + "label": "preimagePartOk", + "offset": 0, + "slot": "2", + "type": "mapping(bytes32 => mapping(uint256 => bool))" + }, + { + "bytes": "512", + "label": "zeroHashes", + "offset": 0, + "slot": "3", + "type": "bytes32[16]" + }, + { + "bytes": "32", + "label": "proposals", + "offset": 0, + "slot": "19", + "type": "struct PreimageOracle.LargePreimageProposalKeys[]" + }, + { + "bytes": "32", + "label": "proposalBranches", + "offset": 0, + "slot": "20", + "type": "mapping(address => mapping(uint256 => bytes32[16]))" + }, + { + "bytes": "32", + "label": "proposalMetadata", + "offset": 0, + "slot": "21", + "type": "mapping(address => mapping(uint256 => LPPMetaData))" + }, + { + "bytes": "32", + "label": "proposalBonds", + "offset": 0, + "slot": "22", + "type": "mapping(address => mapping(uint256 => uint256))" + }, + { + "bytes": "32", + "label": "proposalParts", + "offset": 0, + "slot": "23", + "type": "mapping(address => mapping(uint256 => bytes32))" + }, + { + "bytes": "32", + "label": "proposalBlocks", + "offset": 0, + "slot": "24", + "type": "mapping(address => mapping(uint256 => uint64[]))" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/ProtocolVersions.json b/packages/contracts-bedrock/snapshots/storageLayout/ProtocolVersions.json new file mode 100644 index 000000000000..2f421c299fe3 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/ProtocolVersions.json @@ -0,0 +1,37 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "uint256[50]" + }, + { + "bytes": "20", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "address" + }, + { + "bytes": "1568", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "uint256[49]" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/Proxy.json b/packages/contracts-bedrock/snapshots/storageLayout/Proxy.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/Proxy.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/ProxyAdmin.json b/packages/contracts-bedrock/snapshots/storageLayout/ProxyAdmin.json new file mode 100644 index 000000000000..70f8300e6bed --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/ProxyAdmin.json @@ -0,0 +1,37 @@ +[ + { + "bytes": "20", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "address" + }, + { + "bytes": "32", + "label": "proxyType", + "offset": 0, + "slot": "1", + "type": "mapping(address => enum ProxyAdmin.ProxyType)" + }, + { + "bytes": "32", + "label": "implementationName", + "offset": 0, + "slot": "2", + "type": "mapping(address => string)" + }, + { + "bytes": "20", + "label": "addressManager", + "offset": 0, + "slot": "3", + "type": "contract AddressManager" + }, + { + "bytes": "1", + "label": "upgrading", + "offset": 20, + "slot": "3", + "type": "bool" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/ResolvedDelegateProxy.json b/packages/contracts-bedrock/snapshots/storageLayout/ResolvedDelegateProxy.json new file mode 100644 index 000000000000..18cbb67336fa --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/ResolvedDelegateProxy.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "32", + "label": "implementationName", + "offset": 0, + "slot": "0", + "type": "mapping(address => string)" + }, + { + "bytes": "32", + "label": "addressManager", + "offset": 0, + "slot": "1", + "type": "mapping(address => contract AddressManager)" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/SafeSend.json b/packages/contracts-bedrock/snapshots/storageLayout/SafeSend.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/SafeSend.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/SchemaRegistry.json b/packages/contracts-bedrock/snapshots/storageLayout/SchemaRegistry.json new file mode 100644 index 000000000000..689bc71384eb --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/SchemaRegistry.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "32", + "label": "_registry", + "offset": 0, + "slot": "0", + "type": "mapping(bytes32 => struct SchemaRecord)" + }, + { + "bytes": "1568", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "uint256[49]" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/SequencerFeeVault.json b/packages/contracts-bedrock/snapshots/storageLayout/SequencerFeeVault.json new file mode 100644 index 000000000000..ee2c5925c712 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/SequencerFeeVault.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "32", + "label": "totalProcessed", + "offset": 0, + "slot": "0", + "type": "uint256" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/StorageSetter.json b/packages/contracts-bedrock/snapshots/storageLayout/StorageSetter.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/StorageSetter.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/SuperchainConfig.json b/packages/contracts-bedrock/snapshots/storageLayout/SuperchainConfig.json new file mode 100644 index 000000000000..70e559b7bf6d --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/SuperchainConfig.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/SystemConfig.json b/packages/contracts-bedrock/snapshots/storageLayout/SystemConfig.json new file mode 100644 index 000000000000..f9f63083c274 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/SystemConfig.json @@ -0,0 +1,72 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "1600", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "uint256[50]" + }, + { + "bytes": "20", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "address" + }, + { + "bytes": "1568", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "uint256[49]" + }, + { + "bytes": "32", + "label": "overhead", + "offset": 0, + "slot": "101", + "type": "uint256" + }, + { + "bytes": "32", + "label": "scalar", + "offset": 0, + "slot": "102", + "type": "uint256" + }, + { + "bytes": "32", + "label": "batcherHash", + "offset": 0, + "slot": "103", + "type": "bytes32" + }, + { + "bytes": "8", + "label": "gasLimit", + "offset": 0, + "slot": "104", + "type": "uint64" + }, + { + "bytes": "32", + "label": "_resourceConfig", + "offset": 0, + "slot": "105", + "type": "struct ResourceMetering.ResourceConfig" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/Transactor.json b/packages/contracts-bedrock/snapshots/storageLayout/Transactor.json new file mode 100644 index 000000000000..08fcce9479d5 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/Transactor.json @@ -0,0 +1,9 @@ +[ + { + "bytes": "20", + "label": "owner", + "offset": 0, + "slot": "0", + "type": "address" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/TransferOnion.json b/packages/contracts-bedrock/snapshots/storageLayout/TransferOnion.json new file mode 100644 index 000000000000..5fec815892ce --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/TransferOnion.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "32", + "label": "_status", + "offset": 0, + "slot": "0", + "type": "uint256" + }, + { + "bytes": "32", + "label": "shell", + "offset": 0, + "slot": "1", + "type": "bytes32" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/WETH9.json b/packages/contracts-bedrock/snapshots/storageLayout/WETH9.json new file mode 100644 index 000000000000..ae4f958c6d32 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/WETH9.json @@ -0,0 +1,37 @@ +[ + { + "bytes": "32", + "label": "name", + "offset": 0, + "slot": "0", + "type": "string" + }, + { + "bytes": "32", + "label": "symbol", + "offset": 0, + "slot": "1", + "type": "string" + }, + { + "bytes": "1", + "label": "decimals", + "offset": 0, + "slot": "2", + "type": "uint8" + }, + { + "bytes": "32", + "label": "balanceOf", + "offset": 0, + "slot": "3", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "allowance", + "offset": 0, + "slot": "4", + "type": "mapping(address => mapping(address => uint256))" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/WETH98.json b/packages/contracts-bedrock/snapshots/storageLayout/WETH98.json new file mode 100644 index 000000000000..ac5f38a75a04 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/WETH98.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "32", + "label": "balanceOf", + "offset": 0, + "slot": "0", + "type": "mapping(address => uint256)" + }, + { + "bytes": "32", + "label": "allowance", + "offset": 0, + "slot": "1", + "type": "mapping(address => mapping(address => uint256))" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/EAS/EAS.sol b/packages/contracts-bedrock/src/EAS/EAS.sol index 387688e834be..f4872eeed26e 100644 --- a/packages/contracts-bedrock/src/EAS/EAS.sol +++ b/packages/contracts-bedrock/src/EAS/EAS.sol @@ -16,7 +16,7 @@ import { NotFound, NO_EXPIRATION_TIME, uncheckedInc -} from "./Common.sol"; +} from "src/EAS/Common.sol"; import { Attestation, @@ -31,9 +31,9 @@ import { MultiRevocationRequest, RevocationRequest, RevocationRequestData -} from "./IEAS.sol"; +} from "src/EAS/IEAS.sol"; -import { ISchemaRegistry, SchemaRecord } from "./ISchemaRegistry.sol"; +import { ISchemaRegistry, SchemaRecord } from "src/EAS/ISchemaRegistry.sol"; struct AttestationsResult { uint256 usedValue; // Total ETH amount that was sent to resolvers. @@ -80,11 +80,11 @@ contract EAS is IEAS, ISemver, EIP1271Verifier { uint256[MAX_GAP - 3] private __gap; /// @notice Semantic version. - /// @custom:semver 1.3.0 - string public constant version = "1.3.0"; + /// @custom:semver 1.4.0 + string public constant version = "1.4.0"; /// @dev Creates a new EAS instance. - constructor() EIP1271Verifier("EAS", "1.2.0") { } + constructor() EIP1271Verifier("EAS", "1.3.0") { } /// @inheritdoc IEAS function getSchemaRegistry() external pure returns (ISchemaRegistry) { diff --git a/packages/contracts-bedrock/src/EAS/eip1271/EIP1271Verifier.sol b/packages/contracts-bedrock/src/EAS/eip1271/EIP1271Verifier.sol index 22c5860bab0c..2b9ba7191fb2 100644 --- a/packages/contracts-bedrock/src/EAS/eip1271/EIP1271Verifier.sol +++ b/packages/contracts-bedrock/src/EAS/eip1271/EIP1271Verifier.sol @@ -10,7 +10,7 @@ import { DelegatedAttestationRequest, DelegatedRevocationRequest, RevocationRequestData -} from "../IEAS.sol"; +} from "src/EAS/IEAS.sol"; import { DeadlineExpired, @@ -20,7 +20,7 @@ import { MAX_GAP, stringToBytes32, bytes32ToString -} from "../Common.sol"; +} from "src/EAS/Common.sol"; /// @title EIP1271Verifier /// @notice EIP1271Verifier typed signatures verifier for EAS delegated attestations. @@ -30,13 +30,13 @@ abstract contract EIP1271Verifier is EIP712 { error InvalidNonce(); // The hash of the data type used to relay calls to the attest function. It's the value of - // keccak256("Attest(bytes32 schema,address recipient,uint64 expirationTime,bool revocable,bytes32 refUID,bytes - // data,uint256 value,uint256 nonce,uint64 deadline)"). - bytes32 private constant ATTEST_TYPEHASH = 0xf83bb2b0ede93a840239f7e701a54d9bc35f03701f51ae153d601c6947ff3d3f; + // keccak256("Attest(address attester,bytes32 schema,address recipient,uint64 expirationTime,bool revocable,bytes32 + // refUID,bytes data,uint256 value,uint256 nonce,uint64 deadline)"). + bytes32 private constant ATTEST_TYPEHASH = 0xfeb2925a02bae3dae48d424a0437a2b6ac939aa9230ddc55a1a76f065d988076; // The hash of the data type used to relay calls to the revoke function. It's the value of - // keccak256("Revoke(bytes32 schema,bytes32 uid,uint256 value,uint256 nonce,uint64 deadline)"). - bytes32 private constant REVOKE_TYPEHASH = 0x2d4116d8c9824e4c316453e5c2843a1885580374159ce8768603c49085ef424c; + // keccak256("Revoke(address revoker,bytes32 schema,bytes32 uid,uint256 value,uint256 nonce,uint64 deadline)"). + bytes32 private constant REVOKE_TYPEHASH = 0xb5d556f07587ec0f08cf386545cc4362c702a001650c2058002615ee5c9d1e75; // The user readable name of the signing domain. bytes32 private immutable _name; @@ -116,6 +116,7 @@ abstract contract EIP1271Verifier is EIP712 { keccak256( abi.encode( ATTEST_TYPEHASH, + request.attester, request.schema, data.recipient, data.expirationTime, @@ -150,7 +151,13 @@ abstract contract EIP1271Verifier is EIP712 { bytes32 hash = _hashTypedDataV4( keccak256( abi.encode( - REVOKE_TYPEHASH, request.schema, data.uid, data.value, _nonces[request.revoker]++, request.deadline + REVOKE_TYPEHASH, + request.revoker, + request.schema, + data.uid, + data.value, + _nonces[request.revoker]++, + request.deadline ) ) ); diff --git a/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol b/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol index bd3898bebffc..4e51c3e89c0d 100644 --- a/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol +++ b/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol @@ -1,16 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import { Semver } from "../../universal/Semver.sol"; +import { IEAS, Attestation } from "src/EAS/IEAS.sol"; +import { AccessDenied, InvalidEAS, InvalidLength, uncheckedInc } from "src/EAS/Common.sol"; -import { IEAS, Attestation } from "../IEAS.sol"; -import { AccessDenied, InvalidEAS, InvalidLength, uncheckedInc } from "../Common.sol"; - -import { ISchemaResolver } from "./ISchemaResolver.sol"; +import { ISchemaResolver } from "src/EAS/resolver/ISchemaResolver.sol"; /// @title SchemaResolver /// @notice The base schema resolver contract. -abstract contract SchemaResolver is ISchemaResolver, Semver { +abstract contract SchemaResolver is ISchemaResolver { error InsufficientValue(); error NotPayable(); @@ -19,7 +17,7 @@ abstract contract SchemaResolver is ISchemaResolver, Semver { /// @dev Creates a new resolver. /// @param eas The address of the global EAS contract. - constructor(IEAS eas) Semver(1, 2, 0) { + constructor(IEAS eas) { if (address(eas) == address(0)) { revert InvalidEAS(); } diff --git a/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol b/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol new file mode 100644 index 000000000000..84ba91b8fa98 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/DataAvailabilityChallenge.sol @@ -0,0 +1,445 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import { ISemver } from "src/universal/ISemver.sol"; +import { SafeCall } from "src/libraries/SafeCall.sol"; + +/// @dev An enum representing the status of a DA challenge. +enum ChallengeStatus { + Uninitialized, + Active, + Resolved, + Expired +} + +/// @dev An enum representing known commitment types. +enum CommitmentType { + Keccak256 +} + +/// @dev A struct representing a single DA challenge. +/// @custom:field status The status of the challenge. +/// @custom:field challenger The address that initiated the challenge. +/// @custom:field startBlock The block number at which the challenge was initiated. +struct Challenge { + address challenger; + uint256 lockedBond; + uint256 startBlock; + uint256 resolvedBlock; +} + +/// @title DataAvailabilityChallenge +/// @notice This contract enables data availability of a data commitment at a given block number to be challenged. +/// To challenge a commitment, the challenger must first post a bond (bondSize). +/// Challenging a commitment is only possible within a certain block interval (challengeWindow) after the +/// commitment was made. +/// If the challenge is not resolved within a certain block interval (resolveWindow), the challenge can be +/// expired. +/// If a challenge is expired, the challenger's bond is unlocked and the challenged commitment is added to the +/// chain of expired challenges. +contract DataAvailabilityChallenge is OwnableUpgradeable, ISemver { + /// @notice Error for when the provided resolver refund percentage exceeds 100%. + error InvalidResolverRefundPercentage(uint256 invalidResolverRefundPercentage); + + /// @notice Error for when the challenger's bond is too low. + error BondTooLow(uint256 balance, uint256 required); + + /// @notice Error for when attempting to challenge a commitment that already has a challenge. + error ChallengeExists(); + + /// @notice Error for when attempting to resolve a challenge that is not active. + error ChallengeNotActive(); + + /// @notice Error for when attempting to unlock a bond from a challenge that is not expired. + error ChallengeNotExpired(); + + /// @notice Error for when attempting to challenge a commitment that is not in the challenge window. + error ChallengeWindowNotOpen(); + + /// @notice Error for when the provided input data doesn't match the commitment. + error InvalidInputData(bytes providedDataCommitment, bytes expectedCommitment); + + /// @notice Error for when the call to withdraw a bond failed. + error WithdrawalFailed(); + + /// @notice Error for when a the type of a given commitment is unknown + error UnknownCommitmentType(uint8 commitmentType); + + /// @notice Error for when the commitment length does not match the commitment type + error InvalidCommitmentLength(uint8 commitmentType, uint256 expectedLength, uint256 actualLength); + + /// @notice An event that is emitted when the status of a challenge changes. + /// @param challengedCommitment The commitment that is being challenged. + /// @param challengedBlockNumber The block number at which the commitment was made. + /// @param status The new status of the challenge. + event ChallengeStatusChanged( + uint256 indexed challengedBlockNumber, bytes challengedCommitment, ChallengeStatus status + ); + + /// @notice An event that is emitted when the bond size required to initiate a challenge changes. + event RequiredBondSizeChanged(uint256 challengeWindow); + + /// @notice An event that is emitted when the percentage of the resolving cost to be refunded to the resolver + /// changes. + event ResolverRefundPercentageChanged(uint256 resolverRefundPercentage); + + /// @notice An event that is emitted when a user's bond balance changes. + event BalanceChanged(address account, uint256 balance); + + /// @notice Semantic version. + /// @custom:semver 1.0.0 + string public constant version = "1.0.0"; + + /// @notice The fixed cost of resolving a challenge. + /// @dev The value is estimated by measuring the cost of resolving with `bytes(0)` + uint256 public constant fixedResolutionCost = 72925; + + /// @notice The variable cost of resolving a callenge per byte scaled by the variableResolutionCostPrecision. + /// @dev upper limit; The value is estimated by measuring the cost of resolving with variable size data where each + /// byte is non-zero. + uint256 public constant variableResolutionCost = 16640; + + /// @dev The precision of the variable resolution cost. + uint256 public constant variableResolutionCostPrecision = 1000; + + /// @notice The block interval during which a commitment can be challenged. + uint256 public challengeWindow; + + /// @notice The block interval during which a challenge can be resolved. + uint256 public resolveWindow; + + /// @notice The amount required to post a challenge. + uint256 public bondSize; + + /// @notice The percentage of the resolving cost to be refunded to the resolver. + /// @dev There are no decimals, ie a value of 50 corresponds to 50%. + uint256 public resolverRefundPercentage; + + /// @notice A mapping from addresses to their bond balance in the contract. + mapping(address => uint256) public balances; + + /// @notice A mapping from challenged block numbers to challenged commitments to challenges. + mapping(uint256 => mapping(bytes => Challenge)) internal challenges; + + /// @notice Constructs the DataAvailabilityChallenge contract. Cannot set + /// the owner to `address(0)` due to the Ownable contract's + /// implementation, so set it to `address(0xdEaD)`. + constructor() OwnableUpgradeable() { + initialize({ + _owner: address(0xdEaD), + _challengeWindow: 0, + _resolveWindow: 0, + _bondSize: 0, + _resolverRefundPercentage: 0 + }); + } + + /// @notice Initializes the contract. + /// @param _owner The owner of the contract. + /// @param _challengeWindow The block interval during which a commitment can be challenged. + /// @param _resolveWindow The block interval during which a challenge can be resolved. + /// @param _bondSize The amount required to post a challenge. + function initialize( + address _owner, + uint256 _challengeWindow, + uint256 _resolveWindow, + uint256 _bondSize, + uint256 _resolverRefundPercentage + ) + public + initializer + { + __Ownable_init(); + challengeWindow = _challengeWindow; + resolveWindow = _resolveWindow; + setBondSize(_bondSize); + setResolverRefundPercentage(_resolverRefundPercentage); + _transferOwnership(_owner); + } + + /// @notice Sets the bond size. + /// @param _bondSize The amount required to post a challenge. + function setBondSize(uint256 _bondSize) public onlyOwner { + bondSize = _bondSize; + emit RequiredBondSizeChanged(_bondSize); + } + + /// @notice Sets the percentage of the resolving cost to be refunded to the resolver. + /// @dev The function reverts if the provided percentage is above 100, since the refund logic + /// assumes a value smaller or equal to 100%. + /// @param _resolverRefundPercentage The percentage of the resolving cost to be refunded to the resolver. + function setResolverRefundPercentage(uint256 _resolverRefundPercentage) public onlyOwner { + if (_resolverRefundPercentage > 100) { + revert InvalidResolverRefundPercentage(_resolverRefundPercentage); + } + resolverRefundPercentage = _resolverRefundPercentage; + } + + /// @notice Post a bond as prerequisite for challenging a commitment. + receive() external payable { + deposit(); + } + + /// @notice Post a bond as prerequisite for challenging a commitment. + function deposit() public payable { + balances[msg.sender] += msg.value; + emit BalanceChanged(msg.sender, balances[msg.sender]); + } + + /// @notice Withdraw a user's unlocked bond. + function withdraw() external { + // get caller's balance + uint256 balance = balances[msg.sender]; + + // set caller's balance to 0 + balances[msg.sender] = 0; + emit BalanceChanged(msg.sender, 0); + + // send caller's balance to caller + bool success = SafeCall.send(msg.sender, gasleft(), balance); + if (!success) { + revert WithdrawalFailed(); + } + } + + /// @notice Checks if the current block is within the challenge window for a given challenged block number. + /// @param challengedBlockNumber The block number at which the commitment was made. + /// @return True if the current block is within the challenge window, false otherwise. + function _isInChallengeWindow(uint256 challengedBlockNumber) internal view returns (bool) { + return (block.number >= challengedBlockNumber && block.number <= challengedBlockNumber + challengeWindow); + } + + /// @notice Checks if the current block is within the resolve window for a given challenge start block number. + /// @param challengeStartBlockNumber The block number at which the challenge was initiated. + /// @return True if the current block is within the resolve window, false otherwise. + function _isInResolveWindow(uint256 challengeStartBlockNumber) internal view returns (bool) { + return block.number <= challengeStartBlockNumber + resolveWindow; + } + + /// @notice Returns a challenge for the given block number and commitment. + /// @dev Unlike with a public `challenges` mapping, we can return a Challenge struct instead of tuple. + /// @param challengedBlockNumber The block number at which the commitment was made. + /// @param challengedCommitment The commitment that is being challenged. + /// @return The challenge struct. + function getChallenge( + uint256 challengedBlockNumber, + bytes calldata challengedCommitment + ) + public + view + returns (Challenge memory) + { + return challenges[challengedBlockNumber][challengedCommitment]; + } + + /// @notice Returns the status of a challenge for a given challenged block number and challenged commitment. + /// @param challengedBlockNumber The block number at which the commitment was made. + /// @param challengedCommitment The commitment that is being challenged. + /// @return The status of the challenge. + function getChallengeStatus( + uint256 challengedBlockNumber, + bytes calldata challengedCommitment + ) + public + view + returns (ChallengeStatus) + { + Challenge memory _challenge = challenges[challengedBlockNumber][challengedCommitment]; + // if the address is 0, the challenge is uninitialized + if (_challenge.challenger == address(0)) return ChallengeStatus.Uninitialized; + + // if the challenge has a resolved block, it is resolved + if (_challenge.resolvedBlock != 0) return ChallengeStatus.Resolved; + + // if the challenge's start block is in the resolve window, it is active + if (_isInResolveWindow(_challenge.startBlock)) return ChallengeStatus.Active; + + // if the challenge's start block is not in the resolve window, it is expired + return ChallengeStatus.Expired; + } + + /// @notice Extract the commitment type from a given commitment. + /// @dev The commitment type is located in the first byte of the commitment. + /// @param commitment The commitment from which to extract the commitment type. + /// @return The commitment type of the given commitment. + function _getCommitmentType(bytes calldata commitment) internal pure returns (uint8) { + return uint8(bytes1(commitment)); + } + + /// @notice Validate that a given commitment has a known type and the expected length for this type. + /// @dev The type of a commitment is stored in its first byte. + /// The function reverts with `UnknownCommitmentType` if the type is not known and + /// with `InvalidCommitmentLength` if the commitment has an unexpected length. + /// @param commitment The commitment for which to check the type. + function validateCommitment(bytes calldata commitment) public pure { + uint8 commitmentType = _getCommitmentType(commitment); + if (commitmentType == uint8(CommitmentType.Keccak256)) { + if (commitment.length != 33) { + revert InvalidCommitmentLength(uint8(CommitmentType.Keccak256), 33, commitment.length); + } + return; + } + + revert UnknownCommitmentType(commitmentType); + } + + /// @notice Challenge a commitment at a given block number. + /// @dev The block number parameter is necessary for the contract to verify the challenge window, + /// since the contract cannot access the block number of the commitment. + /// The function reverts if the commitment type (first byte) is unknown, + /// if the caller does not have a bond or if the challenge already exists. + /// @param challengedBlockNumber The block number at which the commitment was made. + /// @param challengedCommitment The commitment that is being challenged. + function challenge(uint256 challengedBlockNumber, bytes calldata challengedCommitment) external payable { + // require the commitment type to be known + validateCommitment(challengedCommitment); + + // deposit value sent with the transaction as bond + deposit(); + + // require the caller to have a bond + if (balances[msg.sender] < bondSize) { + revert BondTooLow(balances[msg.sender], bondSize); + } + + // require the challenge status to be uninitialized + if (getChallengeStatus(challengedBlockNumber, challengedCommitment) != ChallengeStatus.Uninitialized) { + revert ChallengeExists(); + } + + // require the current block to be in the challenge window + if (!_isInChallengeWindow(challengedBlockNumber)) { + revert ChallengeWindowNotOpen(); + } + + // reduce the caller's balance + balances[msg.sender] -= bondSize; + + // store the challenger's address, bond size, and start block of the challenge + challenges[challengedBlockNumber][challengedCommitment] = + Challenge({ challenger: msg.sender, lockedBond: bondSize, startBlock: block.number, resolvedBlock: 0 }); + + // emit an event to notify that the challenge status is now active + emit ChallengeStatusChanged(challengedBlockNumber, challengedCommitment, ChallengeStatus.Active); + } + + /// @notice Resolve a challenge by providing the data corresponding to the challenged commitment. + /// @dev The function computes a commitment from the provided resolveData and verifies that it matches the + /// challenged commitment. + /// It reverts if the commitment type is unknown, if the data doesn't match the commitment, + /// if the challenge is not active or if the resolve window is not open. + /// @param challengedBlockNumber The block number at which the commitment was made. + /// @param challengedCommitment The challenged commitment that is being resolved. + /// @param resolveData The pre-image data corresponding to the challenged commitment. + function resolve( + uint256 challengedBlockNumber, + bytes calldata challengedCommitment, + bytes calldata resolveData + ) + external + { + // require the commitment type to be known + validateCommitment(challengedCommitment); + + // require the challenge to be active (started, not resolved, and resolve window still open) + if (getChallengeStatus(challengedBlockNumber, challengedCommitment) != ChallengeStatus.Active) { + revert ChallengeNotActive(); + } + + // compute the commitment corresponding to the given resolveData + uint8 commitmentType = _getCommitmentType(challengedCommitment); + bytes memory computedCommitment; + if (commitmentType == uint8(CommitmentType.Keccak256)) { + computedCommitment = computeCommitmentKeccak256(resolveData); + } + + // require the provided input data to correspond to the challenged commitment + if (keccak256(computedCommitment) != keccak256(challengedCommitment)) { + revert InvalidInputData(computedCommitment, challengedCommitment); + } + + // store the block number at which the challenge was resolved + Challenge storage activeChallenge = challenges[challengedBlockNumber][challengedCommitment]; + activeChallenge.resolvedBlock = block.number; + + // emit an event to notify that the challenge status is now resolved + emit ChallengeStatusChanged(challengedBlockNumber, challengedCommitment, ChallengeStatus.Resolved); + + // distribute the bond among challenger, resolver and address(0) + _distributeBond(activeChallenge, resolveData.length, msg.sender); + } + + /// @notice Distribute the bond of a resolved challenge among the resolver, challenger and address(0). + /// The challenger is refunded the bond amount exceeding the resolution cost. + /// The resolver is refunded a percentage of the resolution cost based on the `resolverRefundPercentage` + /// state variable. + /// The remaining bond is burned by sending it to address(0). + /// @dev The resolution cost is approximated based on a fixed cost and variable cost depending on the size of the + /// pre-image. + /// The real resolution cost might vary, because calldata is priced differently for zero and non-zero bytes. + /// Computing the exact cost adds too much gas overhead to be worth the tradeoff. + /// @param resolvedChallenge The resolved challenge in storage. + /// @param preImageLength The size of the pre-image used to resolve the challenge. + /// @param resolver The address of the resolver. + function _distributeBond(Challenge storage resolvedChallenge, uint256 preImageLength, address resolver) internal { + uint256 lockedBond = resolvedChallenge.lockedBond; + address challenger = resolvedChallenge.challenger; + + // approximate the cost of resolving a challenge with the provided pre-image size + uint256 resolutionCost = ( + fixedResolutionCost + preImageLength * variableResolutionCost / variableResolutionCostPrecision + ) * block.basefee; + + // refund bond exceeding the resolution cost to the challenger + if (lockedBond > resolutionCost) { + balances[challenger] += lockedBond - resolutionCost; + lockedBond = resolutionCost; + emit BalanceChanged(challenger, balances[challenger]); + } + + // refund a percentage of the resolution cost to the resolver (but not more than the locked bond) + uint256 resolverRefund = resolutionCost * resolverRefundPercentage / 100; + if (resolverRefund > lockedBond) { + resolverRefund = lockedBond; + } + if (resolverRefund > 0) { + balances[resolver] += resolverRefund; + lockedBond -= resolverRefund; + emit BalanceChanged(resolver, balances[resolver]); + } + + // burn the remaining bond + if (lockedBond > 0) { + payable(address(0)).transfer(lockedBond); + } + resolvedChallenge.lockedBond = 0; + } + + /// @notice Unlock the bond associated wth an expired challenge. + /// @dev The function reverts if the challenge is not expired. + /// If the expiration is successful, the challenger's bond is unlocked. + /// @param challengedBlockNumber The block number at which the commitment was made. + /// @param challengedCommitment The commitment that is being challenged. + function unlockBond(uint256 challengedBlockNumber, bytes calldata challengedCommitment) external { + // require the challenge to be active (started, not resolved, and in the resolve window) + if (getChallengeStatus(challengedBlockNumber, challengedCommitment) != ChallengeStatus.Expired) { + revert ChallengeNotExpired(); + } + + // Unlock the bond associated with the challenge + Challenge storage expiredChallenge = challenges[challengedBlockNumber][challengedCommitment]; + balances[expiredChallenge.challenger] += expiredChallenge.lockedBond; + expiredChallenge.lockedBond = 0; + + // Emit balance update event + emit BalanceChanged(expiredChallenge.challenger, balances[expiredChallenge.challenger]); + } +} + +/// @notice Compute the expected commitment for a given blob of data. +/// @param data The blob of data to compute a commitment for. +/// @return The commitment for the given blob of data. +function computeCommitmentKeccak256(bytes memory data) pure returns (bytes memory) { + return bytes.concat(bytes1(uint8(CommitmentType.Keccak256)), keccak256(data)); +} diff --git a/packages/contracts-bedrock/src/L1/DelayedVetoable.sol b/packages/contracts-bedrock/src/L1/DelayedVetoable.sol index 8a1f08cb0ef3..abb40b9ce90f 100644 --- a/packages/contracts-bedrock/src/L1/DelayedVetoable.sol +++ b/packages/contracts-bedrock/src/L1/DelayedVetoable.sol @@ -11,15 +11,9 @@ import { ISemver } from "src/universal/ISemver.sol"; /// of the queuedAt(bytes32) function. This is because of input validation checks which solidity performs at /// runtime on functions which take an argument. contract DelayedVetoable is ISemver { - /// @notice Error for when the delay has already been set. - error AlreadyDelayed(); - /// @notice Error for when attempting to forward too early. error ForwardingEarly(); - /// @notice Error for the target is not set. - error TargetUnitialized(); - /// @notice Error for unauthorized calls. error Unauthorized(address expected, address actual); @@ -170,7 +164,7 @@ contract DelayedVetoable is ISemver { revert Unauthorized(INITIATOR, msg.sender); } - if (_queuedAt[callHash] + _delay < block.timestamp) { + if (_queuedAt[callHash] + _delay > block.timestamp) { // Not enough time has passed, so we'll revert. revert ForwardingEarly(); } diff --git a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol index 5bc5a347e1a4..e9840fef55dc 100644 --- a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol @@ -5,7 +5,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { ISemver } from "src/universal/ISemver.sol"; -import { Constants } from "src/libraries/Constants.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; /// @custom:proxied /// @title L1CrossDomainMessenger @@ -13,45 +13,62 @@ import { Constants } from "src/libraries/Constants.sol"; /// for sending and receiving data on the L1 side. Users are encouraged to use this /// interface instead of interacting with lower-level contracts directly. contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver { - /// @notice Address of the OptimismPortal. The public getter for this - /// is legacy and will be removed in the future. Use `portal()` instead. + /// @notice Contract of the SuperchainConfig. + SuperchainConfig public superchainConfig; + + /// @notice Contract of the OptimismPortal. /// @custom:network-specific - /// @custom:legacy - OptimismPortal public PORTAL; + OptimismPortal public portal; /// @notice Semantic version. - /// @custom:semver 1.7.1 - string public constant version = "1.7.1"; + /// @custom:semver 2.3.0 + string public constant version = "2.3.0"; /// @notice Constructs the L1CrossDomainMessenger contract. - constructor() CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER) { - initialize({ _portal: OptimismPortal(payable(0)) }); + constructor() CrossDomainMessenger() { + initialize({ _superchainConfig: SuperchainConfig(address(0)), _portal: OptimismPortal(payable(address(0))) }); } /// @notice Initializes the contract. - /// @param _portal Address of the OptimismPortal contract on this network. - function initialize(OptimismPortal _portal) public reinitializer(Constants.INITIALIZER) { - PORTAL = _portal; - __CrossDomainMessenger_init(); + /// @param _superchainConfig Contract of the SuperchainConfig contract on this network. + /// @param _portal Contract of the OptimismPortal contract on this network. + function initialize(SuperchainConfig _superchainConfig, OptimismPortal _portal) public initializer { + superchainConfig = _superchainConfig; + portal = _portal; + __CrossDomainMessenger_init({ _otherMessenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER) }); } - /// @notice Getter for the OptimismPortal address. - function portal() external view returns (address) { - return address(PORTAL); + /// @notice Getter function for the OptimismPortal contract on this chain. + /// Public getter is legacy and will be removed in the future. Use `portal()` instead. + /// @return Contract of the OptimismPortal on this chain. + /// @custom:legacy + function PORTAL() external view returns (OptimismPortal) { + return portal; } /// @inheritdoc CrossDomainMessenger function _sendMessage(address _to, uint64 _gasLimit, uint256 _value, bytes memory _data) internal override { - PORTAL.depositTransaction{ value: _value }(_to, _value, _gasLimit, false, _data); + portal.depositTransaction{ value: _value }({ + _to: _to, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: false, + _data: _data + }); } /// @inheritdoc CrossDomainMessenger function _isOtherMessenger() internal view override returns (bool) { - return msg.sender == address(PORTAL) && PORTAL.l2Sender() == OTHER_MESSENGER; + return msg.sender == address(portal) && portal.l2Sender() == address(otherMessenger); } /// @inheritdoc CrossDomainMessenger function _isUnsafeTarget(address _target) internal view override returns (bool) { - return _target == address(this) || _target == address(PORTAL); + return _target == address(this) || _target == address(portal); + } + + /// @inheritdoc CrossDomainMessenger + function paused() public view override returns (bool) { + return superchainConfig.paused(); } } diff --git a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol index 97b6fa8beb50..c4e62c7f9b51 100644 --- a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol @@ -7,7 +7,9 @@ import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; import { ISemver } from "src/universal/ISemver.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; import { Constants } from "src/libraries/Constants.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; /// @title L1ERC721Bridge /// @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to @@ -18,19 +20,32 @@ contract L1ERC721Bridge is ERC721Bridge, ISemver { /// by ID was deposited for a given L2 token. mapping(address => mapping(address => mapping(uint256 => bool))) public deposits; + /// @notice Address of the SuperchainConfig contract. + SuperchainConfig public superchainConfig; + /// @notice Semantic version. - /// @custom:semver 1.4.1 - string public constant version = "1.4.1"; + /// @custom:semver 2.1.0 + string public constant version = "2.1.0"; - /// @notice Constructs the contract. - constructor() ERC721Bridge(Predeploys.L2_ERC721_BRIDGE) { - initialize({ _messenger: CrossDomainMessenger(address(0)) }); + /// @notice Constructs the L1ERC721Bridge contract. + constructor() ERC721Bridge() { + initialize({ _messenger: CrossDomainMessenger(address(0)), _superchainConfig: SuperchainConfig(address(0)) }); } /// @notice Initializes the contract. - /// @param _messenger Address of the CrossDomainMessenger on this network. - function initialize(CrossDomainMessenger _messenger) public reinitializer(Constants.INITIALIZER) { - __ERC721Bridge_init({ _messenger: _messenger }); + /// @param _messenger Contract of the CrossDomainMessenger on this network. + /// @param _superchainConfig Contract of the SuperchainConfig contract on this network. + function initialize(CrossDomainMessenger _messenger, SuperchainConfig _superchainConfig) public initializer { + superchainConfig = _superchainConfig; + __ERC721Bridge_init({ + _messenger: _messenger, + _otherBridge: StandardBridge(payable(Predeploys.L2_ERC721_BRIDGE)) + }); + } + + /// @inheritdoc ERC721Bridge + function paused() public view override returns (bool) { + return superchainConfig.paused(); } /// @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the @@ -54,6 +69,7 @@ contract L1ERC721Bridge is ERC721Bridge, ISemver { external onlyOtherBridge { + require(paused() == false, "L1ERC721Bridge: paused"); require(_localToken != address(this), "L1ERC721Bridge: local token cannot be self"); // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge. @@ -68,7 +84,7 @@ contract L1ERC721Bridge is ERC721Bridge, ISemver { // When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the // withdrawer. - IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId); + IERC721(_localToken).safeTransferFrom({ from: address(this), to: _to, tokenId: _tokenId }); // slither-disable-next-line reentrancy-events emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData); @@ -96,10 +112,10 @@ contract L1ERC721Bridge is ERC721Bridge, ISemver { // Lock token into bridge deposits[_localToken][_remoteToken][_tokenId] = true; - IERC721(_localToken).transferFrom(_from, address(this), _tokenId); + IERC721(_localToken).transferFrom({ from: _from, to: address(this), tokenId: _tokenId }); // Send calldata into L2 - messenger.sendMessage(OTHER_BRIDGE, message, _minGasLimit); + messenger.sendMessage({ _target: address(otherBridge), _message: message, _minGasLimit: _minGasLimit }); emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData); } } diff --git a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol index e4e9914ed8c7..9f399999b5f8 100644 --- a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol +++ b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol @@ -5,6 +5,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; import { ISemver } from "src/universal/ISemver.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { Constants } from "src/libraries/Constants.sol"; /// @custom:proxied @@ -69,17 +70,31 @@ contract L1StandardBridge is StandardBridge, ISemver { ); /// @notice Semantic version. - /// @custom:semver 1.4.1 - string public constant version = "1.4.1"; + /// @custom:semver 2.1.0 + string public constant version = "2.1.0"; + + /// @notice Address of the SuperchainConfig contract. + SuperchainConfig public superchainConfig; /// @notice Constructs the L1StandardBridge contract. - constructor() StandardBridge(StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE))) { - initialize({ _messenger: CrossDomainMessenger(address(0)) }); + constructor() StandardBridge() { + initialize({ _messenger: CrossDomainMessenger(address(0)), _superchainConfig: SuperchainConfig(address(0)) }); + } + + /// @notice Initializer. + /// @param _messenger Contract for the CrossDomainMessenger on this network. + /// @param _superchainConfig Contract for the SuperchainConfig on this network. + function initialize(CrossDomainMessenger _messenger, SuperchainConfig _superchainConfig) public initializer { + superchainConfig = _superchainConfig; + __StandardBridge_init({ + _messenger: _messenger, + _otherBridge: StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)) + }); } - /// @notice Initializer - function initialize(CrossDomainMessenger _messenger) public reinitializer(Constants.INITIALIZER) { - __StandardBridge_init({ _messenger: _messenger }); + /// @inheritdoc StandardBridge + function paused() public view override returns (bool) { + return superchainConfig.paused(); } /// @notice Allows EOAs to bridge ETH by sending directly to the bridge. @@ -202,7 +217,7 @@ contract L1StandardBridge is StandardBridge, ISemver { /// @notice Retrieves the access of the corresponding L2 bridge contract. /// @return Address of the corresponding L2 bridge contract. function l2TokenBridge() external view returns (address) { - return address(OTHER_BRIDGE); + return address(otherBridge); } /// @notice Internal function for initiating an ETH deposit. diff --git a/packages/contracts-bedrock/src/L1/L2OutputOracle.sol b/packages/contracts-bedrock/src/L1/L2OutputOracle.sol index 21535c12d588..fe2c7dd7c8ef 100644 --- a/packages/contracts-bedrock/src/L1/L2OutputOracle.sol +++ b/packages/contracts-bedrock/src/L1/L2OutputOracle.sol @@ -12,26 +12,6 @@ import { Constants } from "src/libraries/Constants.sol"; /// commitment to the state of the L2 chain. Other contracts like the OptimismPortal use /// these outputs to verify information about the state of L2. contract L2OutputOracle is Initializable, ISemver { - /// @notice The interval in L2 blocks at which checkpoints must be submitted. - /// Although this is immutable, it can safely be modified by upgrading the - /// implementation contract. - /// Public getter is legacy and will be removed in the future. Use `submissionInterval` - /// instead. - /// @custom:legacy - uint256 public immutable SUBMISSION_INTERVAL; - - /// @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified. - /// Public getter is legacy and will be removed in the future. Use `l2BlockTime` - /// instead. - /// @custom:legacy - uint256 public immutable L2_BLOCK_TIME; - - /// @notice The minimum time (in seconds) that must elapse before a withdrawal can be finalized. - /// Public getter is legacy and will be removed in the future. Use - // `finalizationPeriodSeconds` instead. - /// @custom:legacy - uint256 public immutable FINALIZATION_PERIOD_SECONDS; - /// @notice The number of the first L2 block recorded in this contract. uint256 public startingBlockNumber; @@ -41,14 +21,26 @@ contract L2OutputOracle is Initializable, ISemver { /// @notice An array of L2 output proposals. Types.OutputProposal[] internal l2Outputs; - /// @notice The address of the challenger. Can be updated via reinitialize. + /// @notice The interval in L2 blocks at which checkpoints must be submitted. + /// @custom:network-specific + uint256 public submissionInterval; + + /// @notice The time between L2 blocks in seconds. Once set, this value MUST NOT be modified. + /// @custom:network-specific + uint256 public l2BlockTime; + + /// @notice The address of the challenger. Can be updated via upgrade. /// @custom:network-specific address public challenger; - /// @notice The address of the proposer. Can be updated via reinitialize. + /// @notice The address of the proposer. Can be updated via upgrade. /// @custom:network-specific address public proposer; + /// @notice The minimum time (in seconds) that must elapse before a withdrawal can be finalized. + /// @custom:network-specific + uint256 public finalizationPeriodSeconds; + /// @notice Emitted when an output is proposed. /// @param outputRoot The output root. /// @param l2OutputIndex The index of the output in the l2Outputs array. @@ -64,84 +56,104 @@ contract L2OutputOracle is Initializable, ISemver { event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); /// @notice Semantic version. - /// @custom:semver 1.6.0 - string public constant version = "1.6.0"; - - /// @notice Constructs the L2OutputOracle contract. - /// @param _submissionInterval Interval in blocks at which checkpoints must be submitted. - /// @param _l2BlockTime The time per L2 block, in seconds. - /// @param _finalizationPeriodSeconds The amount of time that must pass for an output proposal - // to be considered canonical. - constructor(uint256 _submissionInterval, uint256 _l2BlockTime, uint256 _finalizationPeriodSeconds) { - require(_l2BlockTime > 0, "L2OutputOracle: L2 block time must be greater than 0"); - require(_submissionInterval > 0, "L2OutputOracle: submission interval must be greater than 0"); - - SUBMISSION_INTERVAL = _submissionInterval; - L2_BLOCK_TIME = _l2BlockTime; - FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds; - - initialize({ _startingBlockNumber: 0, _startingTimestamp: 0, _proposer: address(0), _challenger: address(0) }); + /// @custom:semver 1.8.0 + string public constant version = "1.8.0"; + + /// @notice Constructs the L2OutputOracle contract. Initializes variables to the same values as + /// in the getting-started config. + constructor() { + initialize({ + _submissionInterval: 1, + _l2BlockTime: 1, + _startingBlockNumber: 0, + _startingTimestamp: 0, + _proposer: address(0), + _challenger: address(0), + _finalizationPeriodSeconds: 0 + }); } /// @notice Initializer. - /// @param _startingBlockNumber Block number for the first recoded L2 block. - /// @param _startingTimestamp Timestamp for the first recoded L2 block. + /// @param _submissionInterval Interval in blocks at which checkpoints must be submitted. + /// @param _l2BlockTime The time per L2 block, in seconds. + /// @param _startingBlockNumber The number of the first L2 block. + /// @param _startingTimestamp The timestamp of the first L2 block. /// @param _proposer The address of the proposer. /// @param _challenger The address of the challenger. + /// @param _finalizationPeriodSeconds The minimum time (in seconds) that must elapse before a withdrawal + /// can be finalized. function initialize( + uint256 _submissionInterval, + uint256 _l2BlockTime, uint256 _startingBlockNumber, uint256 _startingTimestamp, address _proposer, - address _challenger + address _challenger, + uint256 _finalizationPeriodSeconds ) public - reinitializer(Constants.INITIALIZER) + initializer { + require(_submissionInterval > 0, "L2OutputOracle: submission interval must be greater than 0"); + require(_l2BlockTime > 0, "L2OutputOracle: L2 block time must be greater than 0"); require( _startingTimestamp <= block.timestamp, "L2OutputOracle: starting L2 timestamp must be less than current time" ); - startingTimestamp = _startingTimestamp; + submissionInterval = _submissionInterval; + l2BlockTime = _l2BlockTime; startingBlockNumber = _startingBlockNumber; + startingTimestamp = _startingTimestamp; proposer = _proposer; challenger = _challenger; + finalizationPeriodSeconds = _finalizationPeriodSeconds; } - /// @notice Getter for the output proposal submission interval. - function submissionInterval() external view returns (uint256) { - return SUBMISSION_INTERVAL; - } - - /// @notice Getter for the L2 block time. - function l2BlockTime() external view returns (uint256) { - return L2_BLOCK_TIME; + /// @notice Getter for the submissionInterval. + /// Public getter is legacy and will be removed in the future. Use `submissionInterval` instead. + /// @return Submission interval. + /// @custom:legacy + function SUBMISSION_INTERVAL() external view returns (uint256) { + return submissionInterval; } - /// @notice Getter for the finalization period. - function finalizationPeriodSeconds() external view returns (uint256) { - return FINALIZATION_PERIOD_SECONDS; + /// @notice Getter for the l2BlockTime. + /// Public getter is legacy and will be removed in the future. Use `l2BlockTime` instead. + /// @return L2 block time. + /// @custom:legacy + function L2_BLOCK_TIME() external view returns (uint256) { + return l2BlockTime; } - /// @notice Getter for the challenger address. This will be removed - /// in the future, use `challenger` instead. + /// @notice Getter for the challenger address. + /// Public getter is legacy and will be removed in the future. Use `challenger` instead. + /// @return Address of the challenger. /// @custom:legacy function CHALLENGER() external view returns (address) { return challenger; } - /// @notice Getter for the proposer address. This will be removed in the - /// future, use `proposer` instead. + /// @notice Getter for the proposer address. + /// Public getter is legacy and will be removed in the future. Use `proposer` instead. + /// @return Address of the proposer. /// @custom:legacy function PROPOSER() external view returns (address) { return proposer; } + /// @notice Getter for the finalizationPeriodSeconds. + /// Public getter is legacy and will be removed in the future. Use `finalizationPeriodSeconds` instead. + /// @return Finalization period in seconds. + /// @custom:legacy + function FINALIZATION_PERIOD_SECONDS() external view returns (uint256) { + return finalizationPeriodSeconds; + } + /// @notice Deletes all output proposals after and including the proposal that corresponds to /// the given output index. Only the challenger address can delete outputs. /// @param _l2OutputIndex Index of the first L2 output to be deleted. /// All outputs after this output will also be deleted. - // solhint-disable-next-line ordering function deleteL2Outputs(uint256 _l2OutputIndex) external { require(msg.sender == challenger, "L2OutputOracle: only the challenger address can delete outputs"); @@ -152,7 +164,7 @@ contract L2OutputOracle is Initializable, ISemver { // Do not allow deleting any outputs that have already been finalized. require( - block.timestamp - l2Outputs[_l2OutputIndex].timestamp < FINALIZATION_PERIOD_SECONDS, + block.timestamp - l2Outputs[_l2OutputIndex].timestamp < finalizationPeriodSeconds, "L2OutputOracle: cannot delete outputs that have already been finalized" ); @@ -292,13 +304,13 @@ contract L2OutputOracle is Initializable, ISemver { /// @notice Computes the block number of the next L2 block that needs to be checkpointed. /// @return Next L2 block number. function nextBlockNumber() public view returns (uint256) { - return latestBlockNumber() + SUBMISSION_INTERVAL; + return latestBlockNumber() + submissionInterval; } /// @notice Returns the L2 timestamp corresponding to a given L2 block number. /// @param _l2BlockNumber The L2 block number of the target block. /// @return L2 timestamp of the given block. function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) { - return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME); + return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * l2BlockTime); } } diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal.sol b/packages/contracts-bedrock/src/L1/OptimismPortal.sol index 66417a79b572..30e6bd471dd6 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal.sol @@ -5,6 +5,7 @@ import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable import { SafeCall } from "src/libraries/SafeCall.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; @@ -47,23 +48,22 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { /// @notice A mapping of withdrawal hashes to `ProvenWithdrawal` data. mapping(bytes32 => ProvenWithdrawal) public provenWithdrawals; - /// @notice Determines if cross domain messaging is paused. - /// When set to true, withdrawals are paused. - /// This may be removed in the future. - bool public paused; + /// @custom:legacy + /// @custom:spacer paused + /// @notice Spacer for backwards compatibility. + bool private spacer_53_0_1; + + /// @notice Contract of the Superchain Config. + SuperchainConfig public superchainConfig; - /// @notice Address of the L2OutputOracle contract. + /// @notice Contract of the L2OutputOracle. /// @custom:network-specific L2OutputOracle public l2Oracle; - /// @notice Address of the SystemConfig contract. + /// @notice Contract of the SystemConfig. /// @custom:network-specific SystemConfig public systemConfig; - /// @notice Address that has the ability to pause and unpause withdrawals. - /// @custom:network-specific - address public guardian; - /// @notice Emitted when a transaction is deposited from L1 to L2. /// The parameters of this event are read by the rollup node and used to derive deposit /// transactions on L2. @@ -84,86 +84,82 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { /// @param success Whether the withdrawal transaction was successful. event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); - /// @notice Emitted when the pause is triggered. - /// @param account Address of the account triggering the pause. - event Paused(address account); - - /// @notice Emitted when the pause is lifted. - /// @param account Address of the account triggering the unpause. - event Unpaused(address account); - /// @notice Reverts when paused. modifier whenNotPaused() { - require(paused == false, "OptimismPortal: paused"); + require(paused() == false, "OptimismPortal: paused"); _; } /// @notice Semantic version. - /// @custom:semver 1.10.0 - string public constant version = "1.10.0"; + /// @custom:semver 2.5.0 + string public constant version = "2.5.0"; /// @notice Constructs the OptimismPortal contract. constructor() { initialize({ _l2Oracle: L2OutputOracle(address(0)), - _guardian: address(0), _systemConfig: SystemConfig(address(0)), - _paused: true + _superchainConfig: SuperchainConfig(address(0)) }); } /// @notice Initializer. - /// @param _l2Oracle Address of the L2OutputOracle contract. - /// @param _guardian Address that can pause withdrawals. - /// @param _paused Sets the contract's pausability state. - /// @param _systemConfig Address of the SystemConfig contract. + /// @param _l2Oracle Contract of the L2OutputOracle. + /// @param _systemConfig Contract of the SystemConfig. + /// @param _superchainConfig Contract of the SuperchainConfig. function initialize( L2OutputOracle _l2Oracle, - address _guardian, SystemConfig _systemConfig, - bool _paused + SuperchainConfig _superchainConfig ) public - reinitializer(Constants.INITIALIZER) + initializer { - l2Sender = Constants.DEFAULT_L2_SENDER; l2Oracle = _l2Oracle; systemConfig = _systemConfig; - guardian = _guardian; - paused = _paused; + superchainConfig = _superchainConfig; + if (l2Sender == address(0)) { + l2Sender = Constants.DEFAULT_L2_SENDER; + } __ResourceMetering_init(); } - /// @notice Getter for the L2OutputOracle + /// @notice Getter function for the contract of the L2OutputOracle on this chain. + /// Public getter is legacy and will be removed in the future. Use `l2Oracle()` instead. + /// @return Contract of the L2OutputOracle on this chain. /// @custom:legacy function L2_ORACLE() external view returns (L2OutputOracle) { return l2Oracle; } - /// @notice Getter for the SystemConfig + /// @notice Getter function for the contract of the SystemConfig on this chain. + /// Public getter is legacy and will be removed in the future. Use `systemConfig()` instead. + /// @return Contract of the SystemConfig on this chain. /// @custom:legacy function SYSTEM_CONFIG() external view returns (SystemConfig) { return systemConfig; } - /// @notice Getter for the Guardian + /// @notice Getter function for the address of the guardian. + /// Public getter is legacy and will be removed in the future. Use `SuperchainConfig.guardian()` instead. + /// @return Address of the guardian. /// @custom:legacy function GUARDIAN() external view returns (address) { - return guardian; + return guardian(); } - /// @notice Pauses withdrawals. - function pause() external { - require(msg.sender == guardian, "OptimismPortal: only guardian can pause"); - paused = true; - emit Paused(msg.sender); + /// @notice Getter function for the address of the guardian. + /// Public getter is legacy and will be removed in the future. Use `SuperchainConfig.guardian()` instead. + /// @return Address of the guardian. + /// @custom:legacy + function guardian() public view returns (address) { + return superchainConfig.guardian(); } - /// @notice Unpauses withdrawals. - function unpause() external { - require(msg.sender == guardian, "OptimismPortal: only guardian can unpause"); - paused = false; - emit Unpaused(msg.sender); + /// @notice Getter for the current paused status. + /// @return paused_ Whether or not the contract is paused. + function paused() public view returns (bool paused_) { + paused_ = superchainConfig.paused(); } /// @notice Computes the minimum gas limit for a deposit. @@ -181,7 +177,6 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { /// funds be deposited to their address on L2. This is intended as a convenience /// function for EOAs. Contracts should call the depositTransaction() function directly /// otherwise any deposited funds will be lost due to address aliasing. - // solhint-disable-next-line ordering receive() external payable { depositTransaction(msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes("")); } @@ -419,7 +414,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { } /// @notice Determine if a given output is finalized. - /// Reverts if the call to L2_ORACLE.getL2Output reverts. + /// Reverts if the call to l2Oracle.getL2Output reverts. /// Returns a boolean otherwise. /// @param _l2OutputIndex Index of the L2 output to check. /// @return Whether or not the output is finalized. diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol new file mode 100644 index 000000000000..6604c8d23087 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -0,0 +1,490 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; +import { SafeCall } from "src/libraries/SafeCall.sol"; +import { DisputeGameFactory, IDisputeGame } from "src/dispute/DisputeGameFactory.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { Constants } from "src/libraries/Constants.sol"; +import { Types } from "src/libraries/Types.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { SecureMerkleTrie } from "src/libraries/trie/SecureMerkleTrie.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { ISemver } from "src/universal/ISemver.sol"; +import { Constants } from "src/libraries/Constants.sol"; + +import "src/libraries/DisputeTypes.sol"; + +/// @custom:proxied +/// @title OptimismPortal2 +/// @notice The OptimismPortal is a low-level contract responsible for passing messages between L1 +/// and L2. Messages sent directly to the OptimismPortal have no form of replayability. +/// Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface. +contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { + /// @notice Represents a proven withdrawal. + /// @custom:field disputeGameProxy The address of the dispute game proxy that the withdrawal was proven against. + /// @custom:field timestamp Timestamp at whcih the withdrawal was proven. + struct ProvenWithdrawal { + IDisputeGame disputeGameProxy; + uint64 timestamp; + } + + /// @notice The delay between when a withdrawal transaction is proven and when it may be finalized. + uint256 internal immutable PROOF_MATURITY_DELAY_SECONDS; + + /// @notice The delay between when a dispute game is resolved and when a withdrawal proven against it may be + /// finalized. + uint256 internal immutable DISPUTE_GAME_FINALITY_DELAY_SECONDS; + + /// @notice Version of the deposit event. + uint256 internal constant DEPOSIT_VERSION = 0; + + /// @notice The L2 gas limit set when eth is deposited using the receive() function. + uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000; + + /// @notice Address of the L2 account which initiated a withdrawal in this transaction. + /// If the of this variable is the default L2 sender address, then we are NOT inside of + /// a call to finalizeWithdrawalTransaction. + address public l2Sender; + + /// @notice A list of withdrawal hashes which have been successfully finalized. + mapping(bytes32 => bool) public finalizedWithdrawals; + + /// @custom:legacy + /// @custom:spacer provenWithdrawals + /// @notice Spacer taking up the legacy `provenWithdrawals` mapping slot. + bytes32 private spacer_52_0_32; + + /// @custom:legacy + /// @custom:spacer paused + /// @notice Spacer for backwards compatibility. + bool private spacer_53_0_1; + + /// @notice Contract of the Superchain Config. + SuperchainConfig public superchainConfig; + + /// @custom:legacy + /// @custom:spacer l2Oracle + /// @notice Spacer taking up the legacy `l2Oracle` address slot. + address private spacer_54_0_20; + + /// @notice Contract of the SystemConfig. + /// @custom:network-specific + SystemConfig public systemConfig; + + /// @notice Address of the DisputeGameFactory. + /// @custom:network-specific + DisputeGameFactory public disputeGameFactory; + + /// @notice A mapping of withdrawal hashes to `ProvenWithdrawal` data. + mapping(bytes32 => ProvenWithdrawal) public provenWithdrawals; + + /// @notice A mapping of dispute game addresses to whether or not they are blacklisted. + mapping(IDisputeGame => bool) public disputeGameBlacklist; + + /// @notice The game type that the OptimismPortal consults for output proposals. + GameType public respectedGameType; + + /// @notice The timestamp at which the respected game type was last updated. + uint64 public respectedGameTypeUpdatedAt; + + /// @notice Emitted when a transaction is deposited from L1 to L2. + /// The parameters of this event are read by the rollup node and used to derive deposit + /// transactions on L2. + /// @param from Address that triggered the deposit transaction. + /// @param to Address that the deposit transaction is directed to. + /// @param version Version of this deposit transaction event. + /// @param opaqueData ABI encoded deposit data to be parsed off-chain. + event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); + + /// @notice Emitted when a withdrawal transaction is proven. + /// @param withdrawalHash Hash of the withdrawal transaction. + /// @param from Address that triggered the withdrawal transaction. + /// @param to Address that the withdrawal transaction is directed to. + event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to); + + /// @notice Emitted when a withdrawal transaction is finalized. + /// @param withdrawalHash Hash of the withdrawal transaction. + /// @param success Whether the withdrawal transaction was successful. + event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); + + /// @notice Reverts when paused. + modifier whenNotPaused() { + require(!paused(), "OptimismPortal: paused"); + _; + } + + /// @notice Semantic version. + /// @custom:semver 3.3.0 + string public constant version = "3.3.0"; + + /// @notice Constructs the OptimismPortal contract. + constructor( + uint256 _proofMaturityDelaySeconds, + uint256 _disputeGameFinalityDelaySeconds, + GameType _initialRespectedGameType + ) { + PROOF_MATURITY_DELAY_SECONDS = _proofMaturityDelaySeconds; + DISPUTE_GAME_FINALITY_DELAY_SECONDS = _disputeGameFinalityDelaySeconds; + respectedGameType = _initialRespectedGameType; + + initialize({ + _disputeGameFactory: DisputeGameFactory(address(0)), + _systemConfig: SystemConfig(address(0)), + _superchainConfig: SuperchainConfig(address(0)) + }); + } + + /// @notice Initializer. + /// @param _disputeGameFactory Contract of the DisputeGameFactory. + /// @param _systemConfig Contract of the SystemConfig. + /// @param _superchainConfig Contract of the SuperchainConfig. + function initialize( + DisputeGameFactory _disputeGameFactory, + SystemConfig _systemConfig, + SuperchainConfig _superchainConfig + ) + public + initializer + { + disputeGameFactory = _disputeGameFactory; + systemConfig = _systemConfig; + superchainConfig = _superchainConfig; + if (l2Sender == address(0)) { + l2Sender = Constants.DEFAULT_L2_SENDER; + } + __ResourceMetering_init(); + } + + /// @notice Getter function for the contract of the SystemConfig on this chain. + /// Public getter is legacy and will be removed in the future. Use `systemConfig()` instead. + /// @return Contract of the SystemConfig on this chain. + /// @custom:legacy + function SYSTEM_CONFIG() external view returns (SystemConfig) { + return systemConfig; + } + + /// @notice Getter function for the address of the guardian. + /// Public getter is legacy and will be removed in the future. Use `SuperchainConfig.guardian()` instead. + /// @return Address of the guardian. + /// @custom:legacy + function GUARDIAN() external view returns (address) { + return guardian(); + } + + /// @notice Getter function for the address of the guardian. + /// Public getter is legacy and will be removed in the future. Use `SuperchainConfig.guardian()` instead. + /// @return Address of the guardian. + /// @custom:legacy + function guardian() public view returns (address) { + return superchainConfig.guardian(); + } + + /// @notice Getter for the current paused status. + function paused() public view returns (bool) { + return superchainConfig.paused(); + } + + /// @notice Getter for the proof maturity delay. + function proofMaturityDelaySeconds() public view returns (uint256) { + return PROOF_MATURITY_DELAY_SECONDS; + } + + /// @notice Getter for the dispute game finality delay. + function disputeGameFinalityDelaySeconds() public view returns (uint256) { + return DISPUTE_GAME_FINALITY_DELAY_SECONDS; + } + + /// @notice Computes the minimum gas limit for a deposit. + /// The minimum gas limit linearly increases based on the size of the calldata. + /// This is to prevent users from creating L2 resource usage without paying for it. + /// This function can be used when interacting with the portal to ensure forwards + /// compatibility. + /// @param _byteCount Number of bytes in the calldata. + /// @return The minimum gas limit for a deposit. + function minimumGasLimit(uint64 _byteCount) public pure returns (uint64) { + return _byteCount * 16 + 21000; + } + + /// @notice Accepts value so that users can send ETH directly to this contract and have the + /// funds be deposited to their address on L2. This is intended as a convenience + /// function for EOAs. Contracts should call the depositTransaction() function directly + /// otherwise any deposited funds will be lost due to address aliasing. + receive() external payable { + depositTransaction(msg.sender, msg.value, RECEIVE_DEFAULT_GAS_LIMIT, false, bytes("")); + } + + /// @notice Accepts ETH value without triggering a deposit to L2. + /// This function mainly exists for the sake of the migration between the legacy + /// Optimism system and Bedrock. + function donateETH() external payable { + // Intentionally empty. + } + + /// @notice Getter for the resource config. + /// Used internally by the ResourceMetering contract. + /// The SystemConfig is the source of truth for the resource config. + /// @return ResourceMetering ResourceConfig + function _resourceConfig() internal view override returns (ResourceMetering.ResourceConfig memory) { + return systemConfig.resourceConfig(); + } + + /// @notice Proves a withdrawal transaction. + /// @param _tx Withdrawal transaction to finalize. + /// @param _disputeGameIndex Index of the dispute game to prove the withdrawal against. + /// @param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contract's storage root. + /// @param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract. + function proveWithdrawalTransaction( + Types.WithdrawalTransaction memory _tx, + uint256 _disputeGameIndex, + Types.OutputRootProof calldata _outputRootProof, + bytes[] calldata _withdrawalProof + ) + external + whenNotPaused + { + // Prevent users from creating a deposit transaction where this address is the message + // sender on L2. Because this is checked here, we do not need to check again in + // `finalizeWithdrawalTransaction`. + require(_tx.target != address(this), "OptimismPortal: you cannot send messages to the portal contract"); + + // Fetch the dispute game proxy from the `DisputeGameFactory` contract. + (GameType gameType,, IDisputeGame gameProxy) = disputeGameFactory.gameAtIndex(_disputeGameIndex); + Claim outputRoot = gameProxy.rootClaim(); + + // The game type of the dispute game must be the respected game type. + require(gameType.raw() == respectedGameType.raw(), "OptimismPortal: invalid game type"); + + // Verify that the output root can be generated with the elements in the proof. + require( + outputRoot.raw() == Hashing.hashOutputRootProof(_outputRootProof), + "OptimismPortal: invalid output root proof" + ); + + // Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier. + bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx); + ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[withdrawalHash]; + + // We generally want to prevent users from proving the same withdrawal multiple times + // because each successive proof will update the timestamp. A malicious user can take + // advantage of this to prevent other users from finalizing their withdrawal. However, + // in the case that an honest user proves their withdrawal against a dispute game that + // resolves against the root claim, or the dispute game is blacklisted, we allow + // re-proving the withdrawal against a new proposal. + IDisputeGame oldGame = provenWithdrawal.disputeGameProxy; + require( + provenWithdrawal.timestamp == 0 || oldGame.status() == GameStatus.CHALLENGER_WINS + || disputeGameBlacklist[oldGame] || oldGame.gameType().raw() != respectedGameType.raw(), + "OptimismPortal: withdrawal hash has already been proven, and the old dispute game is not invalid" + ); + + // Compute the storage slot of the withdrawal hash in the L2ToL1MessagePasser contract. + // Refer to the Solidity documentation for more information on how storage layouts are + // computed for mappings. + bytes32 storageKey = keccak256( + abi.encode( + withdrawalHash, + uint256(0) // The withdrawals mapping is at the first slot in the layout. + ) + ); + + // Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract + // on L2. If this is true, under the assumption that the SecureMerkleTrie does not have + // bugs, then we know that this withdrawal was actually triggered on L2 and can therefore + // be relayed on L1. + require( + SecureMerkleTrie.verifyInclusionProof( + abi.encode(storageKey), hex"01", _withdrawalProof, _outputRootProof.messagePasserStorageRoot + ), + "OptimismPortal: invalid withdrawal inclusion proof" + ); + + // Designate the withdrawalHash as proven by storing the `disputeGameProxy` & `timestamp` in the + // `provenWithdrawals` mapping. A `withdrawalHash` can only be proven once unless the dispute game it proved + // against resolves against the favor of the root claim. + provenWithdrawals[withdrawalHash] = + ProvenWithdrawal({ disputeGameProxy: gameProxy, timestamp: uint64(block.timestamp) }); + + // Emit a `WithdrawalProven` event. + emit WithdrawalProven(withdrawalHash, _tx.sender, _tx.target); + } + + /// @notice Finalizes a withdrawal transaction. + /// @param _tx Withdrawal transaction to finalize. + function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory _tx) external whenNotPaused { + // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other + // than the default value when a withdrawal transaction is being finalized. This check is + // a defacto reentrancy guard. + require( + l2Sender == Constants.DEFAULT_L2_SENDER, "OptimismPortal: can only trigger one withdrawal per transaction" + ); + + // Compute the withdrawal hash. + bytes32 withdrawalHash = Hashing.hashWithdrawal(_tx); + + // Check that the withdrawal can be finalized. + checkWithdrawal(withdrawalHash); + + // Mark the withdrawal as finalized so it can't be replayed. + finalizedWithdrawals[withdrawalHash] = true; + + // Set the l2Sender so contracts know who triggered this withdrawal on L2. + l2Sender = _tx.sender; + + // Trigger the call to the target contract. We use a custom low level method + // SafeCall.callWithMinGas to ensure two key properties + // 1. Target contracts cannot force this call to run out of gas by returning a very large + // amount of data (and this is OK because we don't care about the returndata here). + // 2. The amount of gas provided to the execution context of the target is at least the + // gas limit specified by the user. If there is not enough gas in the current context + // to accomplish this, `callWithMinGas` will revert. + bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data); + + // Reset the l2Sender back to the default value. + l2Sender = Constants.DEFAULT_L2_SENDER; + + // All withdrawals are immediately finalized. Replayability can + // be achieved through contracts built on top of this contract + emit WithdrawalFinalized(withdrawalHash, success); + + // Reverting here is useful for determining the exact gas cost to successfully execute the + // sub call to the target contract if the minimum gas limit specified by the user would not + // be sufficient to execute the sub call. + if (!success && tx.origin == Constants.ESTIMATION_ADDRESS) { + revert("OptimismPortal: withdrawal failed"); + } + } + + /// @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in + /// deriving deposit transactions. Note that if a deposit is made by a contract, its + /// address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider + /// using the CrossDomainMessenger contracts for a simpler developer experience. + /// @param _to Target address on L2. + /// @param _value ETH value to send to the recipient. + /// @param _gasLimit Amount of L2 gas to purchase by burning gas on L1. + /// @param _isCreation Whether or not the transaction is a contract creation. + /// @param _data Data to trigger the recipient with. + function depositTransaction( + address _to, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + public + payable + metered(_gasLimit) + { + // Just to be safe, make sure that people specify address(0) as the target when doing + // contract creations. + if (_isCreation) { + require(_to == address(0), "OptimismPortal: must send to address(0) when creating a contract"); + } + + // Prevent depositing transactions that have too small of a gas limit. Users should pay + // more for more resource usage. + require(_gasLimit >= minimumGasLimit(uint64(_data.length)), "OptimismPortal: gas limit too small"); + + // Prevent the creation of deposit transactions that have too much calldata. This gives an + // upper limit on the size of unsafe blocks over the p2p network. 120kb is chosen to ensure + // that the transaction can fit into the p2p network policy of 128kb even though deposit + // transactions are not gossipped over the p2p network. + require(_data.length <= 120_000, "OptimismPortal: data too large"); + + // Transform the from-address to its alias if the caller is a contract. + address from = msg.sender; + if (msg.sender != tx.origin) { + from = AddressAliasHelper.applyL1ToL2Alias(msg.sender); + } + + // Compute the opaque data that will be emitted as part of the TransactionDeposited event. + // We use opaque data so that we can update the TransactionDeposited event in the future + // without breaking the current interface. + bytes memory opaqueData = abi.encodePacked(msg.value, _value, _gasLimit, _isCreation, _data); + + // Emit a TransactionDeposited event so that the rollup node can derive a deposit + // transaction for this deposit. + emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData); + } + + /// @notice Blacklists a dispute game. Should only be used in the event that a dispute game resolves incorrectly. + /// @param _disputeGame Dispute game to blacklist. + function blacklistDisputeGame(IDisputeGame _disputeGame) external { + require(msg.sender == guardian(), "OptimismPortal: only the guardian can blacklist dispute games"); + disputeGameBlacklist[_disputeGame] = true; + } + + /// @notice Sets the respected game type. Changing this value can alter the security properties of the system, + /// depending on the new game's behavior. + /// @param _gameType The game type to consult for output proposals. + function setRespectedGameType(GameType _gameType) external { + require(msg.sender == guardian(), "OptimismPortal: only the guardian can set the respected game type"); + respectedGameType = _gameType; + respectedGameTypeUpdatedAt = uint64(block.timestamp); + } + + /// @notice Checks if a withdrawal can be finalized. This function will revert if the withdrawal cannot be + /// finalized, and otherwise has no side-effects. + /// @param _withdrawalHash Hash of the withdrawal to check. + function checkWithdrawal(bytes32 _withdrawalHash) public view { + ProvenWithdrawal memory provenWithdrawal = provenWithdrawals[_withdrawalHash]; + IDisputeGame disputeGameProxy = provenWithdrawal.disputeGameProxy; + + // The dispute game must not be blacklisted. + require(!disputeGameBlacklist[disputeGameProxy], "OptimismPortal: dispute game has been blacklisted"); + + // A withdrawal can only be finalized if it has been proven. We know that a withdrawal has + // been proven at least once when its timestamp is non-zero. Unproven withdrawals will have + // a timestamp of zero. + require(provenWithdrawal.timestamp != 0, "OptimismPortal: withdrawal has not been proven yet"); + + uint64 createdAt = disputeGameProxy.createdAt().raw(); + + // As a sanity check, we make sure that the proven withdrawal's timestamp is greater than + // starting timestamp inside the Dispute Game. Not strictly necessary but extra layer of + // safety against weird bugs in the proving step. + require( + provenWithdrawal.timestamp > createdAt, + "OptimismPortal: withdrawal timestamp less than dispute game creation timestamp" + ); + + // A proven withdrawal must wait at least `PROOF_MATURITY_DELAY_SECONDS` before finalizing. + require( + block.timestamp - provenWithdrawal.timestamp > PROOF_MATURITY_DELAY_SECONDS, + "OptimismPortal: proven withdrawal has not matured yet" + ); + + // A proven withdrawal must wait until the dispute game it was proven against has been + // resolved in favor of the root claim (the output proposal). This is to prevent users + // from finalizing withdrawals proven against non-finalized output roots. + require( + disputeGameProxy.status() == GameStatus.DEFENDER_WINS, + "OptimismPortal: output proposal has not been finalized yet" + ); + + // The game type of the dispute game must be the respected game type. This was also checked in + // `proveWithdrawalTransaction`, but we check it again in case the respected game type has changed since + // the withdrawal was proven. + require(disputeGameProxy.gameType().raw() == respectedGameType.raw(), "OptimismPortal: invalid game type"); + + // The game must have been created after `respectedGameTypeUpdatedAt`. This is to prevent users from creating + // invalid disputes against a deployed game type while the off-chain challenge agents are not watching. + require( + createdAt >= respectedGameTypeUpdatedAt, + "OptimismPortal: dispute game created before respected game type was updated" + ); + + // Before a withdrawal can be finalized, the dispute game it was proven against must have been + // resolved for at least `DISPUTE_GAME_FINALITY_DELAY_SECONDS`. This is to allow for manual + // intervention in the event that a dispute game is resolved incorrectly. + require( + block.timestamp - disputeGameProxy.resolvedAt().raw() > DISPUTE_GAME_FINALITY_DELAY_SECONDS, + "OptimismPortal: output proposal in air-gap" + ); + + // Check that this withdrawal has not already been finalized, this is replay protection. + require(!finalizedWithdrawals[_withdrawalHash], "OptimismPortal: withdrawal has already been finalized"); + } +} diff --git a/packages/contracts-bedrock/src/L1/ProtocolVersions.sol b/packages/contracts-bedrock/src/L1/ProtocolVersions.sol index b7606aa95c68..d3f06b27730b 100644 --- a/packages/contracts-bedrock/src/L1/ProtocolVersions.sol +++ b/packages/contracts-bedrock/src/L1/ProtocolVersions.sol @@ -55,14 +55,7 @@ contract ProtocolVersions is OwnableUpgradeable, ISemver { /// @param _owner Initial owner of the contract. /// @param _required Required protocol version to operate on this chain. /// @param _recommended Recommended protocol version to operate on thi chain. - function initialize( - address _owner, - ProtocolVersion _required, - ProtocolVersion _recommended - ) - public - reinitializer(Constants.INITIALIZER) - { + function initialize(address _owner, ProtocolVersion _required, ProtocolVersion _recommended) public initializer { __Ownable_init(); transferOwnership(_owner); _setRequired(_required); diff --git a/packages/contracts-bedrock/src/L1/ResourceMetering.sol b/packages/contracts-bedrock/src/L1/ResourceMetering.sol index 814548860369..8e425680a319 100644 --- a/packages/contracts-bedrock/src/L1/ResourceMetering.sol +++ b/packages/contracts-bedrock/src/L1/ResourceMetering.sol @@ -156,8 +156,9 @@ abstract contract ResourceMetering is Initializable { /// @notice Sets initial resource parameter values. /// This function must either be called by the initializer function of an upgradeable /// child contract. - // solhint-disable-next-line func-name-mixedcase function __ResourceMetering_init() internal onlyInitializing { - params = ResourceParams({ prevBaseFee: 1 gwei, prevBoughtGas: 0, prevBlockNum: uint64(block.number) }); + if (params.prevBlockNum == 0) { + params = ResourceParams({ prevBaseFee: 1 gwei, prevBoughtGas: 0, prevBlockNum: uint64(block.number) }); + } } } diff --git a/packages/contracts-bedrock/src/L1/SuperchainConfig.sol b/packages/contracts-bedrock/src/L1/SuperchainConfig.sol new file mode 100644 index 000000000000..954e1b5df3c7 --- /dev/null +++ b/packages/contracts-bedrock/src/L1/SuperchainConfig.sol @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; +import { ISemver } from "src/universal/ISemver.sol"; +import { Storage } from "src/libraries/Storage.sol"; + +/// @custom:audit none This contracts is not yet audited. +/// @title SuperchainConfig +/// @notice The SuperchainConfig contract is used to manage configuration of global superchain values. +contract SuperchainConfig is Initializable, ISemver { + /// @notice Enum representing different types of updates. + /// @custom:value GUARDIAN Represents an update to the guardian. + enum UpdateType { + GUARDIAN + } + + /// @notice Whether or not the Superchain is paused. + bytes32 public constant PAUSED_SLOT = bytes32(uint256(keccak256("superchainConfig.paused")) - 1); + + /// @notice The address of the guardian, which can pause withdrawals from the System. + /// It can only be modified by an upgrade. + bytes32 public constant GUARDIAN_SLOT = bytes32(uint256(keccak256("superchainConfig.guardian")) - 1); + + /// @notice Emitted when the pause is triggered. + /// @param identifier A string helping to identify provenance of the pause transaction. + event Paused(string identifier); + + /// @notice Emitted when the pause is lifted. + event Unpaused(); + + /// @notice Emitted when configuration is updated. + /// @param updateType Type of update. + /// @param data Encoded update data. + event ConfigUpdate(UpdateType indexed updateType, bytes data); + + /// @notice Semantic version. + /// @custom:semver 1.1.0 + string public constant version = "1.1.0"; + + /// @notice Constructs the SuperchainConfig contract. + constructor() { + initialize({ _guardian: address(0), _paused: false }); + } + + /// @notice Initializer. + /// @param _guardian Address of the guardian, can pause the OptimismPortal. + /// @param _paused Initial paused status. + function initialize(address _guardian, bool _paused) public initializer { + _setGuardian(_guardian); + if (_paused) { + _pause("Initializer paused"); + } + } + + /// @notice Getter for the guardian address. + function guardian() public view returns (address guardian_) { + guardian_ = Storage.getAddress(GUARDIAN_SLOT); + } + + /// @notice Getter for the current paused status. + function paused() public view returns (bool paused_) { + paused_ = Storage.getBool(PAUSED_SLOT); + } + + /// @notice Pauses withdrawals. + /// @param _identifier (Optional) A string to identify provenance of the pause transaction. + function pause(string memory _identifier) external { + require(msg.sender == guardian(), "SuperchainConfig: only guardian can pause"); + _pause(_identifier); + } + + /// @notice Pauses withdrawals. + /// @param _identifier (Optional) A string to identify provenance of the pause transaction. + function _pause(string memory _identifier) internal { + Storage.setBool(PAUSED_SLOT, true); + emit Paused(_identifier); + } + + /// @notice Unpauses withdrawals. + function unpause() external { + require(msg.sender == guardian(), "SuperchainConfig: only guardian can unpause"); + Storage.setBool(PAUSED_SLOT, false); + emit Unpaused(); + } + + /// @notice Sets the guardian address. This is only callable during initialization, so an upgrade + /// will be required to change the guardian. + /// @param _guardian The new guardian address. + function _setGuardian(address _guardian) internal { + Storage.setAddress(GUARDIAN_SLOT, _guardian); + emit ConfigUpdate(UpdateType.GUARDIAN, abi.encode(_guardian)); + } +} diff --git a/packages/contracts-bedrock/src/L1/SystemConfig.sol b/packages/contracts-bedrock/src/L1/SystemConfig.sol index 72445e9a3aed..5e497e22793a 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfig.sol @@ -26,7 +26,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver { } /// @notice Struct representing the addresses of L1 system contracts. These should be the - /// proxies and will differ for each OP Stack chain. + /// proxies and are network specific. struct Addresses { address l1CrossDomainMessenger; address l1ERC721Bridge; @@ -72,6 +72,9 @@ contract SystemConfig is OwnableUpgradeable, ISemver { /// @notice Storage slot that the batch inbox address is stored at. bytes32 public constant BATCH_INBOX_SLOT = bytes32(uint256(keccak256("systemconfig.batchinbox")) - 1); + /// @notice Storage slot for block at which the op-node can start searching for logs from. + bytes32 public constant START_BLOCK_SLOT = bytes32(uint256(keccak256("systemconfig.startBlock")) - 1); + /// @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation. uint256 public overhead; @@ -97,17 +100,17 @@ contract SystemConfig is OwnableUpgradeable, ISemver { /// @param data Encoded update data. event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); - /// @notice The block at which the op-node can start searching for logs from. - uint256 public startBlock; - /// @notice Semantic version. - /// @custom:semver 1.10.0 - string public constant version = "1.10.0"; + /// @custom:semver 1.12.0 + string public constant version = "1.12.0"; /// @notice Constructs the SystemConfig contract. Cannot set /// the owner to `address(0)` due to the Ownable contract's /// implementation, so set it to `address(0xdEaD)` + /// @dev START_BLOCK_SLOT is set to type(uint256).max here so that it will be a dead value + /// in the singleton and is skipped by initialize when setting the start block. constructor() { + Storage.setUint(START_BLOCK_SLOT, type(uint256).max); initialize({ _owner: address(0xdEaD), _overhead: 0, @@ -123,7 +126,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver { systemTxMaxGas: 0, maximumBaseFee: 0 }), - _startBlock: type(uint256).max, _batchInbox: address(0), _addresses: SystemConfig.Addresses({ l1CrossDomainMessenger: address(0), @@ -145,10 +147,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver { /// @param _gasLimit Initial gas limit. /// @param _unsafeBlockSigner Initial unsafe block signer address. /// @param _config Initial ResourceConfig. - /// @param _startBlock Starting block for the op-node to search for logs from. - /// Contracts that were deployed before this field existed - /// need to have this field set manually via an override. - /// Newly deployed contracts should set this value to uint256(0). /// @param _batchInbox Batch inbox address. An identifier for the op-node to find /// canonical data. /// @param _addresses Set of L1 contract addresses. These should be the proxies. @@ -160,12 +158,11 @@ contract SystemConfig is OwnableUpgradeable, ISemver { uint64 _gasLimit, address _unsafeBlockSigner, ResourceMetering.ResourceConfig memory _config, - uint256 _startBlock, address _batchInbox, SystemConfig.Addresses memory _addresses ) public - reinitializer(Constants.INITIALIZER) + initializer { __Ownable_init(); transferOwnership(_owner); @@ -174,8 +171,8 @@ contract SystemConfig is OwnableUpgradeable, ISemver { _setBatcherHash(_batcherHash); _setGasConfig({ _overhead: _overhead, _scalar: _scalar }); _setGasLimit(_gasLimit); - _setUnsafeBlockSigner(_unsafeBlockSigner); + Storage.setAddress(UNSAFE_BLOCK_SIGNER_SLOT, _unsafeBlockSigner); Storage.setAddress(BATCH_INBOX_SLOT, _batchInbox); Storage.setAddress(L1_CROSS_DOMAIN_MESSENGER_SLOT, _addresses.l1CrossDomainMessenger); Storage.setAddress(L1_ERC_721_BRIDGE_SLOT, _addresses.l1ERC721Bridge); @@ -184,7 +181,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver { Storage.setAddress(OPTIMISM_PORTAL_SLOT, _addresses.optimismPortal); Storage.setAddress(OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT, _addresses.optimismMintableERC20Factory); - _setStartBlock(_startBlock); + _setStartBlock(); _setResourceConfig(_config); require(_gasLimit >= minimumGasLimit(), "SystemConfig: gas limit too low"); @@ -204,7 +201,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver { /// Unsafe blocks can be propagated across the p2p network if they are signed by the /// key corresponding to this address. /// @return addr_ Address of the unsafe block signer. - // solhint-disable-next-line ordering function unsafeBlockSigner() public view returns (address addr_) { addr_ = Storage.getAddress(UNSAFE_BLOCK_SIGNER_SLOT); } @@ -244,25 +240,9 @@ contract SystemConfig is OwnableUpgradeable, ISemver { addr_ = Storage.getAddress(BATCH_INBOX_SLOT); } - /// @notice Sets the start block in a backwards compatible way. Proxies - /// that were initialized before the startBlock existed in storage - /// can have their start block set by a user provided override. - /// A start block of 0 indicates that there is no override and the - /// start block will be set by `block.number`. - /// @dev This logic is used to patch legacy deployments with new storage values. - /// Use the override if it is provided as a non zero value and the value - /// has not already been set in storage. Use `block.number` if the value - /// has already been set in storage - /// @param _startBlock The start block override to set in storage. - function _setStartBlock(uint256 _startBlock) internal { - if (_startBlock != 0 && startBlock == 0) { - // There is an override and it is not already set, this is for legacy chains. - startBlock = _startBlock; - } else if (startBlock == 0) { - // There is no override and it is not set in storage. Set it to the block number. - // This is for newly deployed chains. - startBlock = block.number; - } + /// @notice Getter for the StartBlock number. + function startBlock() external view returns (uint256 startBlock_) { + startBlock_ = Storage.getUint(START_BLOCK_SLOT); } /// @notice Updates the unsafe block signer address. Can only be called by the owner. @@ -329,6 +309,21 @@ contract SystemConfig is OwnableUpgradeable, ISemver { emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data); } + /// @notice Sets the start block in a backwards compatible way. Proxies + /// that were initialized before the startBlock existed in storage + /// can have their start block set by a user provided override. + /// A start block of 0 indicates that there is no override and the + /// start block will be set by `block.number`. + /// @dev This logic is used to patch legacy deployments with new storage values. + /// Use the override if it is provided as a non zero value and the value + /// has not already been set in storage. Use `block.number` if the value + /// has already been set in storage + function _setStartBlock() internal { + if (Storage.getUint(START_BLOCK_SLOT) == 0) { + Storage.setUint(START_BLOCK_SLOT, block.number); + } + } + /// @notice A getter for the resource config. /// Ensures that the struct is returned instead of a tuple. /// @return ResourceConfig diff --git a/packages/contracts-bedrock/src/L2/GasPriceOracle.sol b/packages/contracts-bedrock/src/L2/GasPriceOracle.sol index 30ab88c19d24..194bd68f7395 100644 --- a/packages/contracts-bedrock/src/L2/GasPriceOracle.sol +++ b/packages/contracts-bedrock/src/L2/GasPriceOracle.sol @@ -24,20 +24,31 @@ contract GasPriceOracle is ISemver { uint256 public constant DECIMALS = 6; /// @notice Semantic version. - /// @custom:semver 1.1.0 - string public constant version = "1.1.0"; + /// @custom:semver 1.2.0 + string public constant version = "1.2.0"; + + /// @notice Indicates whether the network has gone through the Ecotone upgrade. + bool public isEcotone; /// @notice Computes the L1 portion of the fee based on the size of the rlp encoded input /// transaction, the current L1 base fee, and the various dynamic parameters. /// @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for. /// @return L1 fee that should be paid for the tx function getL1Fee(bytes memory _data) external view returns (uint256) { - uint256 l1GasUsed = getL1GasUsed(_data); - uint256 l1Fee = l1GasUsed * l1BaseFee(); - uint256 divisor = 10 ** DECIMALS; - uint256 unscaled = l1Fee * scalar(); - uint256 scaled = unscaled / divisor; - return scaled; + if (isEcotone) { + return _getL1FeeEcotone(_data); + } + return _getL1FeeBedrock(_data); + } + + /// @notice Set chain to be Ecotone chain (callable by depositor account) + function setEcotone() external { + require( + msg.sender == L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).DEPOSITOR_ACCOUNT(), + "GasPriceOracle: only the depositor account can set isEcotone flag" + ); + require(isEcotone == false, "GasPriceOracle: Ecotone already active"); + isEcotone = true; } /// @notice Retrieves the current gas price (base fee). @@ -52,15 +63,19 @@ contract GasPriceOracle is ISemver { return block.basefee; } + /// @custom:legacy /// @notice Retrieves the current fee overhead. /// @return Current fee overhead. function overhead() public view returns (uint256) { + require(!isEcotone, "GasPriceOracle: overhead() is deprecated"); return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead(); } + /// @custom:legacy /// @notice Retrieves the current fee scalar. /// @return Current fee scalar. function scalar() public view returns (uint256) { + require(!isEcotone, "GasPriceOracle: scalar() is deprecated"); return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar(); } @@ -70,6 +85,24 @@ contract GasPriceOracle is ISemver { return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee(); } + /// @notice Retrieves the current blob base fee. + /// @return Current blob base fee. + function blobBaseFee() public view returns (uint256) { + return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).blobBaseFee(); + } + + /// @notice Retrieves the current base fee scalar. + /// @return Current base fee scalar. + function baseFeeScalar() public view returns (uint32) { + return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).baseFeeScalar(); + } + + /// @notice Retrieves the current blob base fee scalar. + /// @return Current blob base fee scalar. + function blobBaseFeeScalar() public view returns (uint32) { + return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).blobBaseFeeScalar(); + } + /// @custom:legacy /// @notice Retrieves the number of decimals used in the scalar. /// @return Number of decimals used in the scalar. @@ -77,13 +110,43 @@ contract GasPriceOracle is ISemver { return DECIMALS; } - /// @notice Computes the amount of L1 gas used for a transaction. Adds the overhead which - /// represents the per-transaction gas overhead of posting the transaction and state - /// roots to L1. Adds 68 bytes of padding to account for the fact that the input does - /// not have a signature. + /// @notice Computes the amount of L1 gas used for a transaction. Adds 68 bytes + /// of padding to account for the fact that the input does not have a signature. /// @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for. /// @return Amount of L1 gas used to publish the transaction. function getL1GasUsed(bytes memory _data) public view returns (uint256) { + uint256 l1GasUsed = _getCalldataGas(_data); + if (isEcotone) { + return l1GasUsed; + } + return l1GasUsed + L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead(); + } + + /// @notice Computation of the L1 portion of the fee for Bedrock. + /// @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for. + /// @return L1 fee that should be paid for the tx + function _getL1FeeBedrock(bytes memory _data) internal view returns (uint256) { + uint256 l1GasUsed = _getCalldataGas(_data); + uint256 fee = (l1GasUsed + L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead()) * l1BaseFee() + * L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar(); + return fee / (10 ** DECIMALS); + } + + /// @notice L1 portion of the fee after Ecotone. + /// @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for. + /// @return L1 fee that should be paid for the tx + function _getL1FeeEcotone(bytes memory _data) internal view returns (uint256) { + uint256 l1GasUsed = _getCalldataGas(_data); + uint256 scaledBaseFee = baseFeeScalar() * 16 * l1BaseFee(); + uint256 scaledBlobBaseFee = blobBaseFeeScalar() * blobBaseFee(); + uint256 fee = l1GasUsed * (scaledBaseFee + scaledBlobBaseFee); + return fee / (16 * 10 ** DECIMALS); + } + + /// @notice L1 gas estimation calculation. + /// @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for. + /// @return Amount of L1 gas used to publish the transaction. + function _getCalldataGas(bytes memory _data) internal pure returns (uint256) { uint256 total = 0; uint256 length = _data.length; for (uint256 i = 0; i < length; i++) { @@ -93,7 +156,6 @@ contract GasPriceOracle is ISemver { total += 16; } } - uint256 unsigned = total + overhead(); - return unsigned + (68 * 16); + return total + (68 * 16); } } diff --git a/packages/contracts-bedrock/src/L2/L1Block.sol b/packages/contracts-bedrock/src/L2/L1Block.sol index 7ed45ce0d4b6..fa59e66f78df 100644 --- a/packages/contracts-bedrock/src/L2/L1Block.sol +++ b/packages/contracts-bedrock/src/L2/L1Block.sol @@ -20,7 +20,7 @@ contract L1Block is ISemver { /// @notice The latest L1 timestamp known by the L2 system. uint64 public timestamp; - /// @notice The latest L1 basefee. + /// @notice The latest L1 base fee. uint256 public basefee; /// @notice The latest L1 blockhash. @@ -29,18 +29,30 @@ contract L1Block is ISemver { /// @notice The number of L2 blocks in the same epoch. uint64 public sequenceNumber; + /// @notice The scalar value applied to the L1 blob base fee portion of the blob-capable L1 cost func. + uint32 public blobBaseFeeScalar; + + /// @notice The scalar value applied to the L1 base fee portion of the blob-capable L1 cost func. + uint32 public baseFeeScalar; + /// @notice The versioned hash to authenticate the batcher by. bytes32 public batcherHash; /// @notice The overhead value applied to the L1 portion of the transaction fee. + /// @custom:legacy uint256 public l1FeeOverhead; /// @notice The scalar value applied to the L1 portion of the transaction fee. + /// @custom:legacy uint256 public l1FeeScalar; - /// @custom:semver 1.1.0 - string public constant version = "1.1.0"; + /// @notice The latest L1 blob base fee. + uint256 public blobBaseFee; + + /// @custom:semver 1.2.0 + string public constant version = "1.2.0"; + /// @custom:legacy /// @notice Updates the L1 block values. /// @param _number L1 blocknumber. /// @param _timestamp L1 timestamp. @@ -73,4 +85,35 @@ contract L1Block is ISemver { l1FeeOverhead = _l1FeeOverhead; l1FeeScalar = _l1FeeScalar; } + + /// @notice Updates the L1 block values for an Ecotone upgraded chain. + /// Params are packed and passed in as raw msg.data instead of ABI to reduce calldata size. + /// Params are expected to be in the following order: + /// 1. _baseFeeScalar L1 base fee scalar + /// 2. _blobBaseFeeScalar L1 blob base fee scalar + /// 3. _sequenceNumber Number of L2 blocks since epoch start. + /// 4. _timestamp L1 timestamp. + /// 5. _number L1 blocknumber. + /// 6. _basefee L1 base fee. + /// 7. _blobBaseFee L1 blob base fee. + /// 8. _hash L1 blockhash. + /// 9. _batcherHash Versioned hash to authenticate batcher by. + function setL1BlockValuesEcotone() external { + assembly { + // Revert if the caller is not the depositor account. + if xor(caller(), DEPOSITOR_ACCOUNT) { + mstore(0x00, 0x3cc50b45) // 0x3cc50b45 is the 4-byte selector of "NotDepositor()" + revert(0x1C, 0x04) // returns the stored 4-byte selector from above + } + let data := calldataload(4) + // sequencenum (uint64), blobBaseFeeScalar (uint32), baseFeeScalar (uint32) + sstore(sequenceNumber.slot, shr(128, calldataload(4))) + // number (uint64) and timestamp (uint64) + sstore(number.slot, shr(128, calldataload(20))) + sstore(basefee.slot, calldataload(36)) // uint256 + sstore(blobBaseFee.slot, calldataload(68)) // uint256 + sstore(hash.slot, calldataload(100)) // bytes32 + sstore(batcherHash.slot, calldataload(132)) // bytes32 + } + } } diff --git a/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol index 7867f1b87803..ad0e117d3f7c 100644 --- a/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol @@ -15,26 +15,26 @@ import { Constants } from "src/libraries/Constants.sol"; /// L2 on the L2 side. Users are generally encouraged to use this contract instead of lower /// level message passing contracts. contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver { - /// @custom:semver 1.7.0 - string public constant version = "1.7.0"; + /// @custom:semver 2.0.0 + string public constant version = "2.0.0"; /// @notice Constructs the L2CrossDomainMessenger contract. - /// @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract. - constructor(address _l1CrossDomainMessenger) CrossDomainMessenger(_l1CrossDomainMessenger) { - initialize(); + constructor() CrossDomainMessenger() { + initialize({ _l1CrossDomainMessenger: CrossDomainMessenger(address(0)) }); } /// @notice Initializer. - function initialize() public reinitializer(Constants.INITIALIZER) { - __CrossDomainMessenger_init(); + /// @param _l1CrossDomainMessenger L1CrossDomainMessenger contract on the other network. + function initialize(CrossDomainMessenger _l1CrossDomainMessenger) public initializer { + __CrossDomainMessenger_init({ _otherMessenger: _l1CrossDomainMessenger }); } + /// @notice Getter for the remote messenger. + /// Public getter is legacy and will be removed in the future. Use `otherMessenger()` instead. + /// @return L1CrossDomainMessenger contract. /// @custom:legacy - /// @notice Legacy getter for the remote messenger. - /// Use otherMessenger going forward. - /// @return Address of the L1CrossDomainMessenger contract. - function l1CrossDomainMessenger() public view returns (address) { - return OTHER_MESSENGER; + function l1CrossDomainMessenger() public view returns (CrossDomainMessenger) { + return otherMessenger; } /// @inheritdoc CrossDomainMessenger @@ -46,7 +46,7 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver { /// @inheritdoc CrossDomainMessenger function _isOtherMessenger() internal view override returns (bool) { - return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == OTHER_MESSENGER; + return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == address(otherMessenger); } /// @inheritdoc CrossDomainMessenger diff --git a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol index 11d746f1bf05..ee68427acb17 100644 --- a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol @@ -6,6 +6,7 @@ import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC16 import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { IOptimismMintableERC721 } from "src/universal/IOptimismMintableERC721.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; import { ISemver } from "src/universal/ISemver.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -20,18 +21,21 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; /// wait for the one-week challenge period to elapse before their Optimism-native NFT /// can be refunded on L2. contract L2ERC721Bridge is ERC721Bridge, ISemver { - /// @custom:semver 1.4.0 - string public constant version = "1.4.0"; + /// @custom:semver 1.7.0 + string public constant version = "1.7.0"; /// @notice Constructs the L2ERC721Bridge contract. - /// @param _otherBridge Address of the ERC721 bridge on the other network. - constructor(address _otherBridge) ERC721Bridge(_otherBridge) { - initialize(); + constructor() ERC721Bridge() { + initialize({ _l1ERC721Bridge: payable(address(0)) }); } /// @notice Initializes the contract. - function initialize() public reinitializer(Constants.INITIALIZER) { - __ERC721Bridge_init({ _messenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER) }); + /// @param _l1ERC721Bridge Address of the ERC721 bridge contract on the other network. + function initialize(address payable _l1ERC721Bridge) public initializer { + __ERC721Bridge_init({ + _messenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER), + _otherBridge: StandardBridge(_l1ERC721Bridge) + }); } /// @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the @@ -114,7 +118,7 @@ contract L2ERC721Bridge is ERC721Bridge, ISemver { // Send message to L1 bridge // slither-disable-next-line reentrancy-events - messenger.sendMessage(OTHER_BRIDGE, message, _minGasLimit); + messenger.sendMessage({ _target: address(otherBridge), _message: message, _minGasLimit: _minGasLimit }); // slither-disable-next-line reentrancy-events emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData); diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol index 9e42e13f2b7b..69319560ae10 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol @@ -52,18 +52,21 @@ contract L2StandardBridge is StandardBridge, ISemver { bytes extraData ); - /// @custom:semver 1.4.0 - string public constant version = "1.4.0"; + /// @custom:semver 1.8.0 + string public constant version = "1.8.0"; /// @notice Constructs the L2StandardBridge contract. - /// @param _otherBridge Address of the L1StandardBridge. - constructor(StandardBridge _otherBridge) StandardBridge(_otherBridge) { - initialize(); + constructor() StandardBridge() { + initialize({ _otherBridge: StandardBridge(payable(address(0))) }); } - /// @notice Initializer - function initialize() public reinitializer(Constants.INITIALIZER) { - __StandardBridge_init({ _messenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER) }); + /// @notice Initializer. + /// @param _otherBridge Contract for the corresponding bridge on the other chain. + function initialize(StandardBridge _otherBridge) public initializer { + __StandardBridge_init({ + _messenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER), + _otherBridge: _otherBridge + }); } /// @notice Allows EOAs to bridge ETH by sending directly to the bridge. @@ -154,7 +157,7 @@ contract L2StandardBridge is StandardBridge, ISemver { /// @notice Retrieves the access of the corresponding L1 bridge contract. /// @return Address of the corresponding L1 bridge contract. function l1TokenBridge() external view returns (address) { - return address(OTHER_BRIDGE); + return address(otherBridge); } /// @custom:legacy diff --git a/packages/contracts-bedrock/src/Safe/SafeSigners.sol b/packages/contracts-bedrock/src/Safe/SafeSigners.sol index 32e65913dda5..18c443582eba 100644 --- a/packages/contracts-bedrock/src/Safe/SafeSigners.sol +++ b/packages/contracts-bedrock/src/Safe/SafeSigners.sol @@ -22,7 +22,6 @@ library SafeSigners { pure returns (uint8 v, bytes32 r, bytes32 s) { - // solhint-disable-next-line no-inline-assembly assembly { let signaturePos := mul(0x41, pos) r := mload(add(signatures, add(signaturePos, 0x20))) diff --git a/packages/contracts-bedrock/src/cannon/MIPS.sol b/packages/contracts-bedrock/src/cannon/MIPS.sol index 5ea6560c19e4..09be2d34b499 100644 --- a/packages/contracts-bedrock/src/cannon/MIPS.sol +++ b/packages/contracts-bedrock/src/cannon/MIPS.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; +import { ISemver } from "src/universal/ISemver.sol"; import { IPreimageOracle } from "./interfaces/IPreimageOracle.sol"; import { PreimageKeyLib } from "./PreimageKeyLib.sol"; @@ -19,7 +20,7 @@ import { PreimageKeyLib } from "./PreimageKeyLib.sol"; /// @dev https://en.wikibooks.org/wiki/MIPS_Assembly/Instruction_Formats /// @dev https://github.com/golang/go/blob/master/src/syscall/zerrors_linux_mips.go /// MIPS linux kernel errors used by Go runtime -contract MIPS { +contract MIPS is ISemver { /// @notice Stores the VM state. /// Total state size: 32 + 32 + 6 * 4 + 1 + 1 + 8 + 32 * 4 = 226 bytes /// If nextPC != pc + 4, then the VM is executing a branch/jump delay slot. @@ -41,16 +42,20 @@ contract MIPS { /// @notice Start of the data segment. uint32 public constant BRK_START = 0x40000000; - uint32 constant FD_STDIN = 0; - uint32 constant FD_STDOUT = 1; - uint32 constant FD_STDERR = 2; - uint32 constant FD_HINT_READ = 3; - uint32 constant FD_HINT_WRITE = 4; - uint32 constant FD_PREIMAGE_READ = 5; - uint32 constant FD_PREIMAGE_WRITE = 6; + /// @notice The semantic version of the MIPS contract. + /// @custom:semver 0.1.0 + string public constant version = "0.1.0"; - uint32 constant EBADF = 0x9; - uint32 constant EINVAL = 0x16; + uint32 internal constant FD_STDIN = 0; + uint32 internal constant FD_STDOUT = 1; + uint32 internal constant FD_STDERR = 2; + uint32 internal constant FD_HINT_READ = 3; + uint32 internal constant FD_HINT_WRITE = 4; + uint32 internal constant FD_PREIMAGE_READ = 5; + uint32 internal constant FD_PREIMAGE_WRITE = 6; + + uint32 internal constant EBADF = 0x9; + uint32 internal constant EINVAL = 0x16; /// @notice The preimage oracle contract. IPreimageOracle internal immutable ORACLE; @@ -143,7 +148,7 @@ contract MIPS { /// @notice Handles a syscall. /// @param _localContext The local key context for the preimage oracle. /// @return out_ The hashed MIPS state. - function handleSyscall(uint256 _localContext) internal returns (bytes32 out_) { + function handleSyscall(bytes32 _localContext) internal returns (bytes32 out_) { unchecked { // Load state from memory State memory state; @@ -626,7 +631,7 @@ contract MIPS { /// @param _proof The encoded proof data for leaves within the MIPS VM's memory. /// @param _localContext The local key context for the preimage oracle. Optional, can be set as a constant /// if the caller only requires one set of local keys. - function step(bytes calldata _stateData, bytes calldata _proof, uint256 _localContext) public returns (bytes32) { + function step(bytes calldata _stateData, bytes calldata _proof, bytes32 _localContext) public returns (bytes32) { unchecked { State memory state; diff --git a/packages/contracts-bedrock/src/cannon/PreimageKeyLib.sol b/packages/contracts-bedrock/src/cannon/PreimageKeyLib.sol index 3894fef733c4..c3f36cb881fd 100644 --- a/packages/contracts-bedrock/src/cannon/PreimageKeyLib.sol +++ b/packages/contracts-bedrock/src/cannon/PreimageKeyLib.sol @@ -9,7 +9,7 @@ library PreimageKeyLib { /// @param _ident The identifier of the local data. [0, 32) bytes in size. /// @param _localContext The local context for the key. /// @return key_ The context-specific local key. - function localizeIdent(uint256 _ident, uint256 _localContext) internal view returns (bytes32 key_) { + function localizeIdent(uint256 _ident, bytes32 _localContext) internal view returns (bytes32 key_) { assembly { // Set the type byte in the given identifier to `1` (Local). We only care about // the [1, 32) bytes in this value. @@ -26,7 +26,7 @@ library PreimageKeyLib { /// @param _key The local data key to localize. /// @param _localContext The local context for the key. /// @return localizedKey_ The localized local data key. - function localize(bytes32 _key, uint256 _localContext) internal view returns (bytes32 localizedKey_) { + function localize(bytes32 _key, bytes32 _localContext) internal view returns (bytes32 localizedKey_) { assembly { // Grab the current free memory pointer to restore later. let ptr := mload(0x40) diff --git a/packages/contracts-bedrock/src/cannon/PreimageOracle.sol b/packages/contracts-bedrock/src/cannon/PreimageOracle.sol index 63986c36b849..dfdeaa7fc5b1 100644 --- a/packages/contracts-bedrock/src/cannon/PreimageOracle.sol +++ b/packages/contracts-bedrock/src/cannon/PreimageOracle.sol @@ -2,19 +2,104 @@ pragma solidity 0.8.15; import { IPreimageOracle } from "./interfaces/IPreimageOracle.sol"; +import { ISemver } from "src/universal/ISemver.sol"; import { PreimageKeyLib } from "./PreimageKeyLib.sol"; -import "./libraries/CannonErrors.sol"; +import { LibKeccak } from "@lib-keccak/LibKeccak.sol"; +import "src/cannon/libraries/CannonErrors.sol"; +import "src/cannon/libraries/CannonTypes.sol"; /// @title PreimageOracle /// @notice A contract for storing permissioned pre-images. -contract PreimageOracle is IPreimageOracle { +/// @custom:attribution Solady +/// @custom:attribution Beacon Deposit Contract <0x00000000219ab540356cbb839cbe05303d7705fa> +contract PreimageOracle is IPreimageOracle, ISemver { + //////////////////////////////////////////////////////////////// + // Constants & Immutables // + //////////////////////////////////////////////////////////////// + + /// @notice The duration of the large preimage proposal challenge period. + uint256 internal immutable CHALLENGE_PERIOD; + /// @notice The minimum size of a preimage that can be proposed in the large preimage path. + uint256 internal immutable MIN_LPP_SIZE_BYTES; + /// @notice The minimum bond size for large preimage proposals. + uint256 public constant MIN_BOND_SIZE = 0.25 ether; + /// @notice The depth of the keccak256 merkle tree. Supports up to 65,536 keccak blocks, or ~8.91MB preimages. + uint256 public constant KECCAK_TREE_DEPTH = 16; + /// @notice The maximum number of keccak blocks that can fit into the merkle tree. + uint256 public constant MAX_LEAF_COUNT = 2 ** KECCAK_TREE_DEPTH - 1; + + /// @notice The semantic version of the Preimage Oracle contract. + /// @custom:semver 0.1.0 + string public constant version = "0.1.0"; + + //////////////////////////////////////////////////////////////// + // Authorized Preimage Parts // + //////////////////////////////////////////////////////////////// + /// @notice Mapping of pre-image keys to pre-image lengths. mapping(bytes32 => uint256) public preimageLengths; - /// @notice Mapping of pre-image keys to pre-image parts. + /// @notice Mapping of pre-image keys to pre-image offsets to pre-image parts. mapping(bytes32 => mapping(uint256 => bytes32)) public preimageParts; - /// @notice Mapping of pre-image keys to pre-image part offsets. + /// @notice Mapping of pre-image keys to pre-image part offsets to preimage preparedness. mapping(bytes32 => mapping(uint256 => bool)) public preimagePartOk; + //////////////////////////////////////////////////////////////// + // Large Preimage Proposals // + //////////////////////////////////////////////////////////////// + + /// @notice A raw leaf of the large preimage proposal merkle tree. + struct Leaf { + /// @notice The input absorbed for the block, exactly 136 bytes. + bytes input; + /// @notice The index of the block in the absorption process. + uint256 index; + /// @notice The hash of the internal state after absorbing the input. + bytes32 stateCommitment; + } + + /// @notice Unpacked keys for large preimage proposals. + struct LargePreimageProposalKeys { + /// @notice The claimant of the large preimage proposal. + address claimant; + /// @notice The UUID of the large preimage proposal. + uint256 uuid; + } + + /// @notice Static padding hashes. These values are persisted in storage, but are entirely immutable + /// after the constructor's execution. + bytes32[KECCAK_TREE_DEPTH] public zeroHashes; + /// @notice Append-only array of large preimage proposals for off-chain reference. + LargePreimageProposalKeys[] public proposals; + /// @notice Mapping of claimants to proposal UUIDs to the current branch path of the merkleization process. + mapping(address => mapping(uint256 => bytes32[KECCAK_TREE_DEPTH])) public proposalBranches; + /// @notice Mapping of claimants to proposal UUIDs to the timestamp of creation of the proposal as well as the + /// challenged status. + mapping(address => mapping(uint256 => LPPMetaData)) public proposalMetadata; + /// @notice Mapping of claimants to proposal UUIDs to bond amounts. + mapping(address => mapping(uint256 => uint256)) public proposalBonds; + /// @notice Mapping of claimants to proposal UUIDs to the preimage part picked up during the absorbtion process. + mapping(address => mapping(uint256 => bytes32)) public proposalParts; + /// @notice Mapping of claimants to proposal UUIDs to blocks which leaves were added to the merkle tree. + mapping(address => mapping(uint256 => uint64[])) public proposalBlocks; + + //////////////////////////////////////////////////////////////// + // Constructor // + //////////////////////////////////////////////////////////////// + + constructor(uint256 _minProposalSize, uint256 _challengePeriod) { + MIN_LPP_SIZE_BYTES = _minProposalSize; + CHALLENGE_PERIOD = _challengePeriod; + + // Compute hashes in empty sparse Merkle tree. The first hash is not set, and kept as zero as the identity. + for (uint256 height = 0; height < KECCAK_TREE_DEPTH - 1; height++) { + zeroHashes[height + 1] = keccak256(abi.encodePacked(zeroHashes[height], zeroHashes[height])); + } + } + + //////////////////////////////////////////////////////////////// + // Standard Preimage Route (External) // + //////////////////////////////////////////////////////////////// + /// @inheritdoc IPreimageOracle function readPreimage(bytes32 _key, uint256 _offset) external view returns (bytes32 dat_, uint256 datLen_) { require(preimagePartOk[_key][_offset], "pre-image must exist"); @@ -34,7 +119,7 @@ contract PreimageOracle is IPreimageOracle { /// @inheritdoc IPreimageOracle function loadLocalData( uint256 _ident, - uint256 _localContext, + bytes32 _localContext, bytes32 _word, uint256 _size, uint256 _partOffset @@ -80,8 +165,43 @@ contract PreimageOracle is IPreimageOracle { // len(sig) + len(partOffset) + len(preimage offset) = 4 + 32 + 32 = 0x44 size := calldataload(0x44) - // revert if part offset > size+8 (i.e. parts must be within bounds) - if gt(_partOffset, add(size, 8)) { + // revert if part offset >= size+8 (i.e. parts must be within bounds) + if iszero(lt(_partOffset, add(size, 8))) { + // Store "PartOffsetOOB()" + mstore(0x00, 0xfe254987) + // Revert with "PartOffsetOOB()" + revert(0x1c, 0x04) + } + // we leave solidity slots 0x40 and 0x60 untouched, and everything after as scratch-memory. + let ptr := 0x80 + // put size as big-endian uint64 at start of pre-image + mstore(ptr, shl(192, size)) + ptr := add(ptr, 0x08) + // copy preimage payload into memory so we can hash and read it. + calldatacopy(ptr, _preimage.offset, size) + // Note that it includes the 8-byte big-endian uint64 length prefix. + // this will be zero-padded at the end, since memory at end is clean. + part := mload(add(sub(ptr, 0x08), _partOffset)) + let h := keccak256(ptr, size) // compute preimage keccak256 hash + // mask out prefix byte, replace with type 2 byte + key := or(and(h, not(shl(248, 0xFF))), shl(248, 0x02)) + } + preimagePartOk[key][_partOffset] = true; + preimageParts[key][_partOffset] = part; + preimageLengths[key] = size; + } + + /// @inheritdoc IPreimageOracle + function loadSha256PreimagePart(uint256 _partOffset, bytes calldata _preimage) external { + uint256 size; + bytes32 key; + bytes32 part; + assembly { + // len(sig) + len(partOffset) + len(preimage offset) = 4 + 32 + 32 = 0x44 + size := calldataload(0x44) + + // revert if part offset >= size+8 (i.e. parts must be within bounds) + if iszero(lt(_partOffset, add(size, 8))) { // Store "PartOffsetOOB()" mstore(0, 0xfe254987) // Revert with "PartOffsetOOB()" @@ -98,12 +218,573 @@ contract PreimageOracle is IPreimageOracle { // Note that it includes the 8-byte big-endian uint64 length prefix. // this will be zero-padded at the end, since memory at end is clean. part := mload(add(sub(ptr, 8), _partOffset)) - let h := keccak256(ptr, size) // compute preimage keccak256 hash - // mask out prefix byte, replace with type 2 byte - key := or(and(h, not(shl(248, 0xFF))), shl(248, 2)) + + // compute SHA2-256 hash with pre-compile + let success := + staticcall( + gas(), // Forward all available gas + 0x02, // Address of SHA-256 precompile + ptr, // Start of input data in memory + size, // Size of input data + 0, // Store output in scratch memory + 0x20 // Output is always 32 bytes + ) + // Check if the staticcall succeeded + if iszero(success) { revert(0, 0) } + let h := mload(0) // get return data + // mask out prefix byte, replace with type 4 byte + key := or(and(h, not(shl(248, 0xFF))), shl(248, 4)) } preimagePartOk[key][_partOffset] = true; preimageParts[key][_partOffset] = part; preimageLengths[key] = size; } + + /// @inheritdoc IPreimageOracle + function loadBlobPreimagePart( + uint256 _z, + uint256 _y, + bytes calldata _commitment, + bytes calldata _proof, + uint256 _partOffset + ) + external + { + bytes32 key; + bytes32 part; + assembly { + // Compute the versioned hash. The SHA2 hash of the 48 byte commitment is masked with the version byte, + // which is currently 1. https://eips.ethereum.org/EIPS/eip-4844#parameters + // SAFETY: We're only reading 48 bytes from `_commitment` into scratch space, so we're not reading into the + // free memory ptr region. Since the exact number of btyes that is copied into scratch space is + // the same size as the hash input, there's no concern of dirty memory being read into the hash + // input. + calldatacopy(0x00, _commitment.offset, 0x30) + let success := staticcall(gas(), 0x02, 0x00, 0x30, 0x00, 0x20) + if iszero(success) { + // Store the "ShaFailed()" error selector. + mstore(0x00, 0xf9112969) + // revert with "ShaFailed()" + revert(0x1C, 0x04) + } + // Set the `VERSIONED_HASH_VERSION_KZG` byte = 1 in the high-order byte of the hash. + let versionedHash := or(and(mload(0x00), not(shl(248, 0xFF))), shl(248, 0x01)) + + // we leave solidity slots 0x40 and 0x60 untouched, and everything after as scratch-memory. + let ptr := 0x80 + + // Load the inputs for the point evaluation precompile into memory. The inputs to the point evaluation + // precompile are packed, and not supposed to be ABI-encoded. + mstore(ptr, versionedHash) + mstore(add(ptr, 0x20), _z) + mstore(add(ptr, 0x40), _y) + calldatacopy(add(ptr, 0x60), _commitment.offset, 0x30) + calldatacopy(add(ptr, 0x90), _proof.offset, 0x30) + + // Verify the KZG proof by calling the point evaluation precompile. If the proof is invalid, the precompile + // will revert. + success := + staticcall( + gas(), // forward all gas + 0x0A, // point evaluation precompile address + ptr, // input ptr + 0xC0, // input size = 192 bytes + 0x00, // output ptr + 0x00 // output size + ) + if iszero(success) { + // Store the "InvalidProof()" error selector. + mstore(0x00, 0x09bde339) + // revert with "InvalidProof()" + revert(0x1C, 0x04) + } + + // revert if part offset >= 32+8 (i.e. parts must be within bounds) + if iszero(lt(_partOffset, 0x28)) { + // Store "PartOffsetOOB()" + mstore(0x00, 0xfe254987) + // Revert with "PartOffsetOOB()" + revert(0x1C, 0x04) + } + // Clean the word at `ptr + 0x28` to ensure that data out of bounds of the preimage is zero, if the part + // offset requires a partial read. + mstore(add(ptr, 0x28), 0x00) + // put size (32) as a big-endian uint64 at start of pre-image + mstore(ptr, shl(192, 0x20)) + // copy preimage payload into memory so we can hash and read it. + mstore(add(ptr, 0x08), _y) + // Note that it includes the 8-byte big-endian uint64 length prefix. This will be zero-padded at the end, + // since memory at end is guaranteed to be clean. + part := mload(add(ptr, _partOffset)) + + // Compute the key: `keccak256(commitment ++ z)`. Since the exact number of btyes that is copied into + // scratch space is the same size as the hash input, there's no concern of dirty memory being read into + // the hash input. + calldatacopy(ptr, _commitment.offset, 0x30) + mstore(add(ptr, 0x30), _z) + let h := keccak256(ptr, 0x50) + // mask out prefix byte, replace with type 5 byte + key := or(and(h, not(shl(248, 0xFF))), shl(248, 0x05)) + } + preimagePartOk[key][_partOffset] = true; + preimageParts[key][_partOffset] = part; + preimageLengths[key] = 32; + } + + /// @inheritdoc IPreimageOracle + function loadPrecompilePreimagePart(uint256 _partOffset, address _precompile, bytes calldata _input) external { + bytes32 res; + bytes32 key; + bytes32 part; + uint256 size; + assembly { + // we leave solidity slots 0x40 and 0x60 untouched, and everything after as scratch-memory. + let ptr := 0x80 + + // copy precompile address and input into memory + // len(sig) + len(_partOffset) + address-offset-in-slot + calldatacopy(ptr, 48, 20) + calldatacopy(add(20, ptr), _input.offset, _input.length) + // compute the hash + let h := keccak256(ptr, add(20, _input.length)) + // mask out prefix byte, replace with type 6 byte + key := or(and(h, not(shl(248, 0xFF))), shl(248, 0x06)) + + // Call the precompile to get the result. + res := + staticcall( + gas(), // forward all gas + _precompile, + add(20, ptr), // input ptr + _input.length, + 0x0, // Unused as we don't copy anything + 0x00 // don't copy anything + ) + + size := add(1, returndatasize()) + // revert if part offset >= size+8 (i.e. parts must be within bounds) + if iszero(lt(_partOffset, add(size, 8))) { + // Store "PartOffsetOOB()" + mstore(0, 0xfe254987) + // Revert with "PartOffsetOOB()" + revert(0x1c, 4) + } + + // Reuse the `ptr` to store the preimage part: + // put size as big-endian uint64 at start of pre-image + mstore(ptr, shl(192, size)) + ptr := add(ptr, 0x08) + + // write precompile result status to the first byte of `ptr` + mstore8(ptr, res) + // write precompile return data to the rest of `ptr` + returndatacopy(add(ptr, 0x01), 0x0, returndatasize()) + + // compute part given ofset + part := mload(add(sub(ptr, 0x08), _partOffset)) + } + preimagePartOk[key][_partOffset] = true; + preimageParts[key][_partOffset] = part; + preimageLengths[key] = size; + } + + //////////////////////////////////////////////////////////////// + // Large Preimage Proposals (External) // + //////////////////////////////////////////////////////////////// + + /// @notice Returns the length of the `proposals` array + function proposalCount() external view returns (uint256 count_) { + count_ = proposals.length; + } + + /// @notice Returns the length of the array with the block numbers of `addLeavesLPP` calls for a given large + /// preimage proposal. + function proposalBlocksLen(address _claimant, uint256 _uuid) external view returns (uint256 len_) { + len_ = proposalBlocks[_claimant][_uuid].length; + } + + /// @notice Returns the length of the large preimage proposal challenge period. + function challengePeriod() external view returns (uint256 challengePeriod_) { + challengePeriod_ = CHALLENGE_PERIOD; + } + + /// @notice Returns the minimum size (in bytes) of a large preimage proposal. + function minProposalSize() external view returns (uint256 minProposalSize_) { + minProposalSize_ = MIN_LPP_SIZE_BYTES; + } + + /// @notice Initialize a large preimage proposal. Must be called before adding any leaves. + function initLPP(uint256 _uuid, uint32 _partOffset, uint32 _claimedSize) external payable { + // The bond provided must be at least `MIN_BOND_SIZE`. + if (msg.value < MIN_BOND_SIZE) revert InsufficientBond(); + + // The caller of `addLeavesLPP` must be an EOA, so that the call inputs are always available in block bodies. + if (msg.sender != tx.origin) revert NotEOA(); + + // The part offset must be within the bounds of the claimed size + 8. + if (_partOffset >= _claimedSize + 8) revert PartOffsetOOB(); + + // The claimed size must be at least `MIN_LPP_SIZE_BYTES`. + if (_claimedSize < MIN_LPP_SIZE_BYTES) revert InvalidInputSize(); + + // Initialize the proposal metadata. + LPPMetaData metaData = proposalMetadata[msg.sender][_uuid]; + proposalMetadata[msg.sender][_uuid] = metaData.setPartOffset(_partOffset).setClaimedSize(_claimedSize); + proposals.push(LargePreimageProposalKeys(msg.sender, _uuid)); + + // Assign the bond to the proposal. + proposalBonds[msg.sender][_uuid] = msg.value; + } + + /// @notice Adds a contiguous list of keccak state matrices to the merkle tree. + function addLeavesLPP( + uint256 _uuid, + uint256 _inputStartBlock, + bytes calldata _input, + bytes32[] calldata _stateCommitments, + bool _finalize + ) + external + { + // If we're finalizing, pad the input for the submitter. If not, copy the input into memory verbatim. + bytes memory input; + if (_finalize) { + input = LibKeccak.pad(_input); + } else { + input = _input; + } + + // Pull storage variables onto the stack / into memory for operations. + bytes32[KECCAK_TREE_DEPTH] memory branch = proposalBranches[msg.sender][_uuid]; + LPPMetaData metaData = proposalMetadata[msg.sender][_uuid]; + uint256 blocksProcessed = metaData.blocksProcessed(); + + // The caller of `addLeavesLPP` must be an EOA. + if (msg.sender != tx.origin) revert NotEOA(); + + // Revert if the proposal has not been initialized. 0-size preimages are *not* allowed. + if (metaData.claimedSize() == 0) revert NotInitialized(); + + // Revert if the proposal has already been finalized. No leaves can be added after this point. + if (metaData.timestamp() != 0) revert AlreadyFinalized(); + + // Revert if the starting block is not the next block to be added. This is to aid submitters in ensuring that + // they don't corrupt an in-progress proposal by submitting input out of order. + if (blocksProcessed != _inputStartBlock) revert WrongStartingBlock(); + + // Attempt to extract the preimage part from the input data, if the part offset is present in the current + // chunk of input. This function has side effects, and will persist the preimage part to the caller's large + // preimage proposal storage if the part offset is present in the input data. + _extractPreimagePart(_input, _uuid, _finalize, metaData); + + assembly { + let inputLen := mload(input) + let inputPtr := add(input, 0x20) + + // The input length must be a multiple of 136 bytes + // The input lenth / 136 must be equal to the number of state commitments. + if or(mod(inputLen, 136), iszero(eq(_stateCommitments.length, div(inputLen, 136)))) { + // Store "InvalidInputSize()" error selector + mstore(0x00, 0x7b1daf1) + revert(0x1C, 0x04) + } + + // Allocate a hashing buffer the size of the leaf preimage. + let hashBuf := mload(0x40) + mstore(0x40, add(hashBuf, 0xC8)) + + for { let i := 0 } lt(i, inputLen) { i := add(i, 136) } { + // Copy the leaf preimage into the hashing buffer. + let inputStartPtr := add(inputPtr, i) + mstore(hashBuf, mload(inputStartPtr)) + mstore(add(hashBuf, 0x20), mload(add(inputStartPtr, 0x20))) + mstore(add(hashBuf, 0x40), mload(add(inputStartPtr, 0x40))) + mstore(add(hashBuf, 0x60), mload(add(inputStartPtr, 0x60))) + mstore(add(hashBuf, 0x80), mload(add(inputStartPtr, 0x80))) + mstore(add(hashBuf, 136), blocksProcessed) + mstore(add(hashBuf, 168), calldataload(add(_stateCommitments.offset, shl(0x05, div(i, 136))))) + + // Hash the leaf preimage to get the node to add. + let node := keccak256(hashBuf, 0xC8) + + // Increment the number of blocks processed. + blocksProcessed := add(blocksProcessed, 0x01) + + // Add the node to the tree. + let size := blocksProcessed + for { let height := 0x00 } lt(height, shl(0x05, KECCAK_TREE_DEPTH)) { height := add(height, 0x20) } { + if and(size, 0x01) { + mstore(add(branch, height), node) + break + } + + // Hash the node at `height` in the branch and the node together. + mstore(0x00, mload(add(branch, height))) + mstore(0x20, node) + node := keccak256(0x00, 0x40) + size := shr(0x01, size) + } + } + } + + // Do not allow for posting preimages larger than the merkle tree can support. The incremental merkle tree + // algorithm only supports 2**height - 1 leaves, the right most leaf must always be kept empty. + // Reference: https://daejunpark.github.io/papers/deposit.pdf - Page 10, Section 5.1. + if (blocksProcessed > MAX_LEAF_COUNT) revert TreeSizeOverflow(); + + // Update the proposal metadata to include the number of blocks processed and total bytes processed. + metaData = metaData.setBlocksProcessed(uint32(blocksProcessed)).setBytesProcessed( + uint32(_input.length + metaData.bytesProcessed()) + ); + // If the proposal is being finalized, set the timestamp to the current block timestamp. This begins the + // challenge period, which must be waited out before the proposal can be finalized. + if (_finalize) { + metaData = metaData.setTimestamp(uint64(block.timestamp)); + + // If the number of bytes processed is not equal to the claimed size, the proposal cannot be finalized. + if (metaData.bytesProcessed() != metaData.claimedSize()) revert InvalidInputSize(); + } + + // Perist the latest branch to storage. + proposalBranches[msg.sender][_uuid] = branch; + // Persist the block number that these leaves were added in. This assists off-chain observers in reconstructing + // the proposal merkle tree by querying block bodies. + proposalBlocks[msg.sender][_uuid].push(uint64(block.number)); + // Persist the updated metadata to storage. + proposalMetadata[msg.sender][_uuid] = metaData; + } + + /// @notice Challenge a keccak256 block that was committed to in the merkle tree. + function challengeLPP( + address _claimant, + uint256 _uuid, + LibKeccak.StateMatrix memory _stateMatrix, + Leaf calldata _preState, + bytes32[] calldata _preStateProof, + Leaf calldata _postState, + bytes32[] calldata _postStateProof + ) + external + { + // Verify that both leaves are present in the merkle tree. + bytes32 root = getTreeRootLPP(_claimant, _uuid); + if ( + !( + _verify(_preStateProof, root, _preState.index, _hashLeaf(_preState)) + && _verify(_postStateProof, root, _postState.index, _hashLeaf(_postState)) + ) + ) revert InvalidProof(); + + // Verify that the prestate passed matches the intermediate state claimed in the leaf. + if (keccak256(abi.encode(_stateMatrix)) != _preState.stateCommitment) revert InvalidPreimage(); + + // Verify that the pre/post state are contiguous. + if (_preState.index + 1 != _postState.index) revert StatesNotContiguous(); + + // Absorb and permute the input bytes. + LibKeccak.absorb(_stateMatrix, _postState.input); + LibKeccak.permutation(_stateMatrix); + + // Verify that the post state hash doesn't match the expected hash. + if (keccak256(abi.encode(_stateMatrix)) == _postState.stateCommitment) revert PostStateMatches(); + + // Mark the keccak claim as countered. + proposalMetadata[_claimant][_uuid] = proposalMetadata[_claimant][_uuid].setCountered(true); + + // Pay out the bond to the challenger. + _payoutBond(_claimant, _uuid, msg.sender); + } + + /// @notice Challenge the first keccak256 block that was absorbed. + function challengeFirstLPP( + address _claimant, + uint256 _uuid, + Leaf calldata _postState, + bytes32[] calldata _postStateProof + ) + external + { + // Verify that the leaf is present in the merkle tree. + bytes32 root = getTreeRootLPP(_claimant, _uuid); + if (!_verify(_postStateProof, root, _postState.index, _hashLeaf(_postState))) revert InvalidProof(); + + // The poststate index must be 0 in order to challenge it with this function. + if (_postState.index != 0) revert StatesNotContiguous(); + + // Absorb and permute the input bytes into a fresh state matrix. + LibKeccak.StateMatrix memory stateMatrix; + LibKeccak.absorb(stateMatrix, _postState.input); + LibKeccak.permutation(stateMatrix); + + // Verify that the post state hash doesn't match the expected hash. + if (keccak256(abi.encode(stateMatrix)) == _postState.stateCommitment) revert PostStateMatches(); + + // Mark the keccak claim as countered. + proposalMetadata[_claimant][_uuid] = proposalMetadata[_claimant][_uuid].setCountered(true); + + // Pay out the bond to the challenger. + _payoutBond(_claimant, _uuid, msg.sender); + } + + /// @notice Finalize a large preimage proposal after the challenge period has passed. + function squeezeLPP( + address _claimant, + uint256 _uuid, + LibKeccak.StateMatrix memory _stateMatrix, + Leaf calldata _preState, + bytes32[] calldata _preStateProof, + Leaf calldata _postState, + bytes32[] calldata _postStateProof + ) + external + { + LPPMetaData metaData = proposalMetadata[_claimant][_uuid]; + + // Check if the proposal was countered. + if (metaData.countered()) revert BadProposal(); + + // Check if the challenge period has passed since the proposal was finalized. + if (block.timestamp - metaData.timestamp() <= CHALLENGE_PERIOD) revert ActiveProposal(); + + // Verify that both leaves are present in the merkle tree. + bytes32 root = getTreeRootLPP(_claimant, _uuid); + if ( + !( + _verify(_preStateProof, root, _preState.index, _hashLeaf(_preState)) + && _verify(_postStateProof, root, _postState.index, _hashLeaf(_postState)) + ) + ) revert InvalidProof(); + + // Verify that the prestate passed matches the intermediate state claimed in the leaf. + if (keccak256(abi.encode(_stateMatrix)) != _preState.stateCommitment) revert InvalidPreimage(); + + // Verify that the pre/post state are contiguous. + if (_preState.index + 1 != _postState.index || _postState.index != metaData.blocksProcessed() - 1) { + revert StatesNotContiguous(); + } + + // Absorb and permute the input bytes. We perform no final verification on the state matrix here, since the + // proposal has passed the challenge period and is considered valid. + LibKeccak.absorb(_stateMatrix, _postState.input); + LibKeccak.permutation(_stateMatrix); + bytes32 finalDigest = LibKeccak.squeeze(_stateMatrix); + assembly { + finalDigest := or(and(finalDigest, not(shl(248, 0xFF))), shl(248, 0x02)) + } + + // Write the preimage part to the authorized preimage parts mapping. + uint256 partOffset = metaData.partOffset(); + preimagePartOk[finalDigest][partOffset] = true; + preimageParts[finalDigest][partOffset] = proposalParts[_claimant][_uuid]; + preimageLengths[finalDigest] = metaData.claimedSize(); + + // Pay out the bond to the claimant. + _payoutBond(_claimant, _uuid, _claimant); + } + + /// @notice Gets the current merkle root of the large preimage proposal tree. + function getTreeRootLPP(address _owner, uint256 _uuid) public view returns (bytes32 treeRoot_) { + uint256 size = proposalMetadata[_owner][_uuid].blocksProcessed(); + for (uint256 height = 0; height < KECCAK_TREE_DEPTH; height++) { + if ((size & 1) == 1) { + treeRoot_ = keccak256(abi.encode(proposalBranches[_owner][_uuid][height], treeRoot_)); + } else { + treeRoot_ = keccak256(abi.encode(treeRoot_, zeroHashes[height])); + } + size >>= 1; + } + } + + /// @notice Attempts to persist the preimage part to the caller's large preimage proposal storage, if the preimage + /// part is present in the input data being posted. + /// @param _input The portion of the preimage being posted. + /// @param _uuid The UUID of the large preimage proposal. + /// @param _finalize Whether or not the proposal is being finalized in the current call. + /// @param _metaData The metadata of the large preimage proposal. + function _extractPreimagePart( + bytes calldata _input, + uint256 _uuid, + bool _finalize, + LPPMetaData _metaData + ) + internal + { + uint256 offset = _metaData.partOffset(); + uint256 claimedSize = _metaData.claimedSize(); + uint256 currentSize = _metaData.bytesProcessed(); + + // Check if the part offset is present in the input data being posted. If it is, assign the part to the mapping. + if (offset < 8 && currentSize == 0) { + bytes32 preimagePart; + assembly { + mstore(0x00, shl(192, claimedSize)) + mstore(0x08, calldataload(_input.offset)) + preimagePart := mload(offset) + } + proposalParts[msg.sender][_uuid] = preimagePart; + } else if (offset >= 8 && (offset = offset - 8) >= currentSize && offset < currentSize + _input.length) { + uint256 relativeOffset = offset - currentSize; + + // Revert if the full preimage part is not available in the data we're absorbing. The submitter must + // supply data that contains the full preimage part so that no partial preimage parts are stored in the + // oracle. Partial parts are *only* allowed at the tail end of the preimage, where no more data is available + // to be absorbed. + if (relativeOffset + 32 >= _input.length && !_finalize) revert PartOffsetOOB(); + + // If the preimage part is in the data we're about to absorb, persist the part to the caller's large + // preimaage metadata. + bytes32 preimagePart; + assembly { + preimagePart := calldataload(add(_input.offset, relativeOffset)) + } + proposalParts[msg.sender][_uuid] = preimagePart; + } + } + + /// @notice Check if leaf` at `index` verifies against the Merkle `root` and `branch`. + /// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#is_valid_merkle_branch + function _verify( + bytes32[] calldata _proof, + bytes32 _root, + uint256 _index, + bytes32 _leaf + ) + internal + pure + returns (bool isValid_) + { + /// @solidity memory-safe-assembly + assembly { + function hashTwo(a, b) -> hash { + mstore(0x00, a) + mstore(0x20, b) + hash := keccak256(0x00, 0x40) + } + + let value := _leaf + for { let i := 0x00 } lt(i, KECCAK_TREE_DEPTH) { i := add(i, 0x01) } { + let branchValue := calldataload(add(_proof.offset, shl(0x05, i))) + + switch and(shr(i, _index), 0x01) + case 1 { value := hashTwo(branchValue, value) } + default { value := hashTwo(value, branchValue) } + } + + isValid_ := eq(value, _root) + } + } + + /// @notice Pay out a proposal's bond. Reverts if the transfer fails. + function _payoutBond(address _claimant, uint256 _uuid, address _to) internal { + // Pay out the bond to the claimant. + uint256 bond = proposalBonds[_claimant][_uuid]; + proposalBonds[_claimant][_uuid] = 0; + (bool success,) = _to.call{ value: bond }(""); + if (!success) revert BondTransferFailed(); + } + + /// @notice Hashes leaf data for the preimage proposals tree + function _hashLeaf(Leaf memory _leaf) internal pure returns (bytes32 leaf_) { + leaf_ = keccak256(abi.encodePacked(_leaf.input, _leaf.index, _leaf.stateCommitment)); + } } diff --git a/packages/contracts-bedrock/src/cannon/interfaces/IPreimageOracle.sol b/packages/contracts-bedrock/src/cannon/interfaces/IPreimageOracle.sol index 78b1805185ed..7c4a57b257bd 100644 --- a/packages/contracts-bedrock/src/cannon/interfaces/IPreimageOracle.sol +++ b/packages/contracts-bedrock/src/cannon/interfaces/IPreimageOracle.sol @@ -34,7 +34,7 @@ interface IPreimageOracle { /// └────────────┴────────────────────────┘ function loadLocalData( uint256 _ident, - uint256 _localContext, + bytes32 _localContext, bytes32 _word, uint256 _size, uint256 _partOffset @@ -42,9 +42,39 @@ interface IPreimageOracle { external returns (bytes32 key_); - /// @notice Prepares a preimage to be read by keccak256 key, starting at - /// the given offset and up to 32 bytes (clipped at preimage length, if out of data). + /// @notice Prepares a preimage to be read by keccak256 key, starting at the given offset and up to 32 bytes + /// (clipped at preimage length, if out of data). /// @param _partOffset The offset of the preimage to read. /// @param _preimage The preimage data. function loadKeccak256PreimagePart(uint256 _partOffset, bytes calldata _preimage) external; + + /// @notice Prepares a preimage to be read by sha256 key, starting at the given offset and up to 32 bytes + /// (clipped at preimage length, if out of data). + /// @param _partOffset The offset of the preimage to read. + /// @param _preimage The preimage data. + function loadSha256PreimagePart(uint256 _partOffset, bytes calldata _preimage) external; + + /// @notice Verifies that `p(_z) = _y` given `_commitment` that corresponds to the polynomial `p(x)` and a KZG + // proof. The value `y` is the pre-image, and the preimage key is `5 ++ keccak256(_commitment ++ z)[1:]`. + /// @param _z Big endian point value. Part of the preimage key. + /// @param _y Big endian point value. The preimage for the key. + /// @param _commitment The commitment to the polynomial. 48 bytes, part of the preimage key. + /// @param _proof The KZG proof, part of the preimage key. + /// @param _partOffset The offset of the preimage to store. + function loadBlobPreimagePart( + uint256 _z, + uint256 _y, + bytes calldata _commitment, + bytes calldata _proof, + uint256 _partOffset + ) + external; + + /// @notice Prepares a precompile result to be read by a precompile key for the specified offset. + /// The precompile result data is a concatenation of the precompile call status byte and its return data. + /// The preimage key is `6 ++ keccak256(precompile ++ input)[1:]`. + /// @param _partOffset The offset of the precompile result being loaded. + /// @param _precompile The precompile address + /// @param _input The input to the precompile call. + function loadPrecompilePreimagePart(uint256 _partOffset, address _precompile, bytes calldata _input) external; } diff --git a/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol b/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol index 5448e560d4a3..621c0609a879 100644 --- a/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol +++ b/packages/contracts-bedrock/src/cannon/libraries/CannonErrors.sol @@ -3,3 +3,45 @@ pragma solidity 0.8.15; /// @notice Thrown when a passed part offset is out of bounds. error PartOffsetOOB(); + +/// @notice Thrown when a merkle proof fails to verify. +error InvalidProof(); + +/// @notice Thrown when the prestate preimage doesn't match the claimed preimage. +error InvalidPreimage(); + +/// @notice Thrown when a leaf with an invalid input size is added. +error InvalidInputSize(); + +/// @notice Thrown when data is submitted out of order in a large preimage proposal. +error WrongStartingBlock(); + +/// @notice Thrown when the pre and post states passed aren't contiguous. +error StatesNotContiguous(); + +/// @notice Thrown when the permutation yields the expected result. +error PostStateMatches(); + +/// @notice Thrown when the preimage is too large to fit in the tree. +error TreeSizeOverflow(); + +/// @notice Thrown when the preimage proposal has already been finalized. +error AlreadyFinalized(); + +/// @notice Thrown when the proposal has not matured past the challenge period. +error ActiveProposal(); + +/// @notice Thrown when attempting to finalize a proposal that has been challenged. +error BadProposal(); + +/// @notice Thrown when attempting to add leaves to a preimage proposal that has not been initialized. +error NotInitialized(); + +/// @notice Thrown when the caller of a function is not an EOA. +error NotEOA(); + +/// @notice Thrown when an insufficient bond is provided for a large preimage proposal. +error InsufficientBond(); + +/// @notice Thrown when a bond transfer fails. +error BondTransferFailed(); diff --git a/packages/contracts-bedrock/src/cannon/libraries/CannonTypes.sol b/packages/contracts-bedrock/src/cannon/libraries/CannonTypes.sol new file mode 100644 index 000000000000..2e7c50ed862d --- /dev/null +++ b/packages/contracts-bedrock/src/cannon/libraries/CannonTypes.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +using LPPMetadataLib for LPPMetaData global; + +/// @notice Packed LPP metadata. +/// ┌─────────────┬────────────────────────────────────────────┐ +/// │ Bit Offsets │ Description │ +/// ├─────────────┼────────────────────────────────────────────┤ +/// │ [0, 64) │ Timestamp (Finalized - All data available) │ +/// │ [64, 96) │ Part Offset │ +/// │ [96, 128) │ Claimed Size │ +/// │ [128, 160) │ Blocks Processed (Inclusive of Padding) │ +/// │ [160, 192) │ Bytes Processed (Non-inclusive of Padding) │ +/// │ [192, 256) │ Countered │ +/// └─────────────┴────────────────────────────────────────────┘ +type LPPMetaData is bytes32; + +/// @notice LPP metadata UDT extension functions. +library LPPMetadataLib { + uint256 private constant U64_MASK = 0xFFFFFFFFFFFFFFFF; + uint256 private constant U32_MASK = 0xFFFFFFFF; + + function setTimestamp(LPPMetaData _self, uint64 _timestamp) internal pure returns (LPPMetaData self_) { + assembly { + self_ := or(shl(192, _timestamp), and(_self, not(shl(192, U64_MASK)))) + } + } + + function setPartOffset(LPPMetaData _self, uint32 _partOffset) internal pure returns (LPPMetaData self_) { + assembly { + self_ := or(shl(160, _partOffset), and(_self, not(shl(160, U32_MASK)))) + } + } + + function setClaimedSize(LPPMetaData _self, uint32 _claimedSize) internal pure returns (LPPMetaData self_) { + assembly { + self_ := or(shl(128, _claimedSize), and(_self, not(shl(128, U32_MASK)))) + } + } + + function setBlocksProcessed(LPPMetaData _self, uint32 _blocksProcessed) internal pure returns (LPPMetaData self_) { + assembly { + self_ := or(shl(96, _blocksProcessed), and(_self, not(shl(96, U32_MASK)))) + } + } + + function setBytesProcessed(LPPMetaData _self, uint32 _bytesProcessed) internal pure returns (LPPMetaData self_) { + assembly { + self_ := or(shl(64, _bytesProcessed), and(_self, not(shl(64, U32_MASK)))) + } + } + + function setCountered(LPPMetaData _self, bool _countered) internal pure returns (LPPMetaData self_) { + assembly { + self_ := or(_countered, and(_self, not(U64_MASK))) + } + } + + function timestamp(LPPMetaData _self) internal pure returns (uint64 timestamp_) { + assembly { + timestamp_ := shr(192, _self) + } + } + + function partOffset(LPPMetaData _self) internal pure returns (uint64 partOffset_) { + assembly { + partOffset_ := and(shr(160, _self), U32_MASK) + } + } + + function claimedSize(LPPMetaData _self) internal pure returns (uint32 claimedSize_) { + assembly { + claimedSize_ := and(shr(128, _self), U32_MASK) + } + } + + function blocksProcessed(LPPMetaData _self) internal pure returns (uint32 blocksProcessed_) { + assembly { + blocksProcessed_ := and(shr(96, _self), U32_MASK) + } + } + + function bytesProcessed(LPPMetaData _self) internal pure returns (uint32 bytesProcessed_) { + assembly { + bytesProcessed_ := and(shr(64, _self), U32_MASK) + } + } + + function countered(LPPMetaData _self) internal pure returns (bool countered_) { + assembly { + countered_ := and(_self, U64_MASK) + } + } +} diff --git a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol new file mode 100644 index 000000000000..f9fc42162f33 --- /dev/null +++ b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; +import { ISemver } from "src/universal/ISemver.sol"; + +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; + +import "src/libraries/DisputeTypes.sol"; + +/// @title AnchorStateRegistry +/// @notice The AnchorStateRegistry is a contract that stores the latest "anchor" state for each available +/// FaultDisputeGame type. The anchor state is the latest state that has been proposed on L1 and was not +/// challenged within the challenge period. By using stored anchor states, new FaultDisputeGame instances can +/// be initialized with a more recent starting state which reduces the amount of required offchain computation. +contract AnchorStateRegistry is Initializable, IAnchorStateRegistry, ISemver { + /// @notice Describes an initial anchor state for a game type. + struct StartingAnchorRoot { + GameType gameType; + OutputRoot outputRoot; + } + + /// @notice Semantic version. + /// @custom:semver 0.1.0 + string public constant version = "0.1.0"; + + /// @notice DisputeGameFactory address. + IDisputeGameFactory internal immutable DISPUTE_GAME_FACTORY; + + /// @inheritdoc IAnchorStateRegistry + mapping(GameType => OutputRoot) public anchors; + + /// @param _disputeGameFactory DisputeGameFactory address. + constructor(IDisputeGameFactory _disputeGameFactory) { + DISPUTE_GAME_FACTORY = _disputeGameFactory; + + // Initialize the implementation with an empty array of starting anchor roots. + initialize(new StartingAnchorRoot[](0)); + } + + /// @notice Initializes the contract. + /// @param _startingAnchorRoots An array of starting anchor roots. + function initialize(StartingAnchorRoot[] memory _startingAnchorRoots) public initializer { + for (uint256 i = 0; i < _startingAnchorRoots.length; i++) { + StartingAnchorRoot memory startingAnchorRoot = _startingAnchorRoots[i]; + anchors[startingAnchorRoot.gameType] = startingAnchorRoot.outputRoot; + } + } + + /// @inheritdoc IAnchorStateRegistry + function disputeGameFactory() external view returns (IDisputeGameFactory) { + return DISPUTE_GAME_FACTORY; + } + + /// @inheritdoc IAnchorStateRegistry + function tryUpdateAnchorState() external { + // Grab the game and game data. + IFaultDisputeGame game = IFaultDisputeGame(msg.sender); + (GameType gameType, Claim rootClaim, bytes memory extraData) = game.gameData(); + + // Grab the verified address of the game based on the game data. + // slither-disable-next-line unused-return + (IDisputeGame factoryRegisteredGame,) = + DISPUTE_GAME_FACTORY.games({ _gameType: gameType, _rootClaim: rootClaim, _extraData: extraData }); + + // Must be a valid game. + require( + address(factoryRegisteredGame) == address(game), + "AnchorStateRegistry: fault dispute game not registered with factory" + ); + + // No need to update anything if the anchor state is already newer. + if (game.l2BlockNumber() <= anchors[gameType].l2BlockNumber) { + return; + } + + // Must be a game that resolved in favor of the state. + if (game.status() != GameStatus.DEFENDER_WINS) { + return; + } + + // Actually update the anchor state. + anchors[gameType] = OutputRoot({ l2BlockNumber: game.l2BlockNumber(), root: Hash.wrap(game.rootClaim().raw()) }); + } +} diff --git a/packages/contracts-bedrock/src/dispute/BlockOracle.sol b/packages/contracts-bedrock/src/dispute/BlockOracle.sol deleted file mode 100644 index 89e73ac4e325..000000000000 --- a/packages/contracts-bedrock/src/dispute/BlockOracle.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import "src/libraries/DisputeTypes.sol"; -import "src/libraries/DisputeErrors.sol"; -import { ISemver } from "src/universal/ISemver.sol"; - -/// @title BlockOracle -/// @notice Stores a map of block numbers => block hashes for use in dispute resolution -contract BlockOracle is ISemver { - /// @notice The BlockInfo struct contains a block's hash and child timestamp. - struct BlockInfo { - Hash hash; - Timestamp childTimestamp; - } - - /// @notice Emitted when a block is checkpointed. - event Checkpoint(uint256 indexed blockNumber, Hash indexed blockHash, Timestamp indexed childTimestamp); - - /// @notice Maps block numbers to block hashes and timestamps - mapping(uint256 => BlockInfo) internal blocks; - - /// @notice Semantic version. - /// @custom:semver 0.0.1 - string public constant version = "0.0.1"; - - /// @notice Loads a block hash for a given block number, assuming that the block number - /// has been stored in the oracle. - /// @param _blockNumber The block number to load the block hash and timestamp for. - /// @return blockInfo_ The block hash and timestamp for the given block number. - function load(uint256 _blockNumber) external view returns (BlockInfo memory blockInfo_) { - blockInfo_ = blocks[_blockNumber]; - if (Hash.unwrap(blockInfo_.hash) == 0) revert BlockHashNotPresent(); - } - - /// @notice Stores a block hash for the previous block number. - /// @return blockNumber_ The block number that was checkpointed, which is always - /// `block.number - 1`. - function checkpoint() external returns (uint256 blockNumber_) { - // SAFETY: This block hash will always be accessible by the `BLOCKHASH` opcode, - // and in the case of `block.number = 0`, we'll underflow. - // Persist the block information. - blockNumber_ = block.number - 1; - Hash blockHash = Hash.wrap(blockhash(blockNumber_)); - Timestamp childTimestamp = Timestamp.wrap(uint64(block.timestamp)); - - blocks[blockNumber_] = BlockInfo({ hash: blockHash, childTimestamp: childTimestamp }); - - emit Checkpoint(blockNumber_, blockHash, childTimestamp); - } -} diff --git a/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol b/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol index 909f1e66c6c2..e3f7d441f84a 100644 --- a/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol +++ b/packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity 0.8.15; import { ClonesWithImmutableArgs } from "@cwia/ClonesWithImmutableArgs.sol"; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; @@ -14,33 +14,33 @@ import "src/libraries/DisputeTypes.sol"; import "src/libraries/DisputeErrors.sol"; /// @title DisputeGameFactory -/// @notice A factory contract for creating `IDisputeGame` contracts. All created dispute games -/// are stored in both a mapping and an append only array. The timestamp of the creation -/// time of the dispute game is packed tightly into the storage slot with the address of -/// the dispute game. This is to make offchain discoverability of playable dispute games -/// easier. +/// @notice A factory contract for creating `IDisputeGame` contracts. All created dispute games are stored in both a +/// mapping and an append only array. The timestamp of the creation time of the dispute game is packed tightly +/// into the storage slot with the address of the dispute game to make offchain discoverability of playable +/// dispute games easier. contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver { /// @dev Allows for the creation of clone proxies with immutable arguments. using ClonesWithImmutableArgs for address; + /// @notice Semantic version. + /// @custom:semver 0.2.0 + string public constant version = "0.2.0"; + /// @inheritdoc IDisputeGameFactory mapping(GameType => IDisputeGame) public gameImpls; - /// @notice Mapping of a hash of `gameType || rootClaim || extraData` to - /// the deployed `IDisputeGame` clone. - /// @dev Note: `||` denotes concatenation. + /// @inheritdoc IDisputeGameFactory + mapping(GameType => uint256) public initBonds; + + /// @notice Mapping of a hash of `gameType || rootClaim || extraData` to the deployed `IDisputeGame` clone (where + // `||` denotes concatenation). mapping(Hash => GameId) internal _disputeGames; - /// @notice an append-only array of disputeGames that have been created. - /// @dev this accessor is used by offchain game solvers to efficiently - /// track dispute games + /// @notice An append-only array of disputeGames that have been created. Used by offchain game solvers to + /// efficiently track dispute games. GameId[] internal _disputeGameList; - /// @notice Semantic version. - /// @custom:semver 0.0.6 - string public constant version = "0.0.6"; - - /// @notice constructs a new DisputeGameFactory contract. + /// @notice Constructs a new DisputeGameFactory contract. constructor() OwnableUpgradeable() { initialize(address(0)); } @@ -87,6 +87,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver bytes calldata _extraData ) external + payable returns (IDisputeGame proxy_) { // Grab the implementation contract for the given `GameType`. @@ -95,9 +96,15 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver // If there is no implementation to clone for the given `GameType`, revert. if (address(impl) == address(0)) revert NoImplementation(_gameType); + // If the required initialization bond is not met, revert. + if (msg.value < initBonds[_gameType]) revert InsufficientBond(); + + // Get the hash of the parent block. + bytes32 parentHash = blockhash(block.number - 1); + // Clone the implementation contract and initialize it with the given parameters. - proxy_ = IDisputeGame(address(impl).clone(abi.encodePacked(_rootClaim, _extraData))); - proxy_.initialize(); + proxy_ = IDisputeGame(address(impl).clone(abi.encodePacked(_rootClaim, parentHash, _extraData))); + proxy_.initialize{ value: msg.value }(); // Compute the unique identifier for the dispute game. Hash uuid = getGameUUID(_gameType, _rootClaim, _extraData); @@ -105,6 +112,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver // If a dispute game with the same UUID already exists, revert. if (GameId.unwrap(_disputeGames[uuid]) != bytes32(0)) revert GameAlreadyExists(uuid); + // Pack the game ID. GameId id = LibGameId.pack(_gameType, Timestamp.wrap(uint64(block.timestamp)), proxy_); // Store the dispute game id in the mapping & emit the `DisputeGameCreated` event. @@ -117,40 +125,63 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver function getGameUUID( GameType _gameType, Claim _rootClaim, - bytes memory _extraData + bytes calldata _extraData ) public pure returns (Hash uuid_) { + uuid_ = Hash.wrap(keccak256(abi.encode(_gameType, _rootClaim, _extraData))); + } + + /// @inheritdoc IDisputeGameFactory + function findLatestGames( + GameType _gameType, + uint256 _start, + uint256 _n + ) + external + view + returns (GameSearchResult[] memory games_) + { + // If the `_start` index is greater than or equal to the game array length or `_n == 0`, return an empty array. + if (_start >= _disputeGameList.length || _n == 0) return games_; + + // Allocate enough memory for the full array, but start the array's length at `0`. We may not use all of the + // memory allocated, but we don't know ahead of time the final size of the array. assembly { - // Grab the offsets of the other memory locations we will need to temporarily overwrite. - let gameTypeOffset := sub(_extraData, 0x60) - let rootClaimOffset := add(gameTypeOffset, 0x20) - let pointerOffset := add(rootClaimOffset, 0x20) - - // Copy the memory that we will temporarily overwrite onto the stack - // so we can restore it later - let tempA := mload(gameTypeOffset) - let tempB := mload(rootClaimOffset) - let tempC := mload(pointerOffset) - - // Overwrite the memory with the data we want to hash - mstore(gameTypeOffset, _gameType) - mstore(rootClaimOffset, _rootClaim) - mstore(pointerOffset, 0x60) - - // Compute the length of the memory to hash - // `0x60 + 0x20 + extraData.length` rounded to the *next* multiple of 32. - let hashLen := and(add(mload(_extraData), 0x9F), not(0x1F)) - - // Hash the memory to produce the UUID digest - uuid_ := keccak256(gameTypeOffset, hashLen) - - // Restore the memory prior to `extraData` - mstore(gameTypeOffset, tempA) - mstore(rootClaimOffset, tempB) - mstore(pointerOffset, tempC) + games_ := mload(0x40) + mstore(0x40, add(games_, add(0x20, shl(0x05, _n)))) + } + + // Perform a reverse linear search for the `_n` most recent games of type `_gameType`. + for (uint256 i = _start; i >= 0 && i <= _start;) { + GameId id = _disputeGameList[i]; + (GameType gameType, Timestamp timestamp, IDisputeGame proxy) = id.unpack(); + + if (gameType.raw() == _gameType.raw()) { + // Increase the size of the `games_` array by 1. + // SAFETY: We can safely lazily allocate memory here because we pre-allocated enough memory for the max + // possible size of the array. + assembly { + mstore(games_, add(mload(games_), 0x01)) + } + + bytes memory extraData = proxy.extraData(); + Claim rootClaim = proxy.rootClaim(); + games_[games_.length - 1] = GameSearchResult({ + index: i, + metadata: id, + timestamp: timestamp, + rootClaim: rootClaim, + extraData: extraData + }); + if (games_.length >= _n) break; + } + + unchecked { + i--; + } } } @@ -159,4 +190,10 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver gameImpls[_gameType] = _impl; emit ImplementationSet(address(_impl), _gameType); } + + /// @inheritdoc IDisputeGameFactory + function setInitBond(GameType _gameType, uint256 _initBond) external onlyOwner { + initBonds[_gameType] = _initBond; + emit InitBondUpdated(_gameType, _initBond); + } } diff --git a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol index 7ff3a7562b20..3e2df9d7cd7a 100644 --- a/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol @@ -1,20 +1,19 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity 0.8.15; +import { FixedPointMathLib } from "solady/utils/FixedPointMathLib.sol"; + +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; import { IInitializable } from "src/dispute/interfaces/IInitializable.sol"; -import { IBondManager } from "src/dispute/interfaces/IBondManager.sol"; import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -import { BlockOracle } from "src/dispute/BlockOracle.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; import { Clone } from "src/libraries/Clone.sol"; import { Types } from "src/libraries/Types.sol"; import { ISemver } from "src/universal/ISemver.sol"; -import { LibHashing } from "src/dispute/lib/LibHashing.sol"; -import { LibPosition } from "src/dispute/lib/LibPosition.sol"; -import { LibClock } from "src/dispute/lib/LibClock.sol"; +import { LibClock } from "src/dispute/lib/LibUDT.sol"; import "src/libraries/DisputeTypes.sol"; import "src/libraries/DisputeErrors.sol"; @@ -28,49 +27,53 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { /// @notice The absolute prestate of the instruction trace. This is a constant that is defined /// by the program that is being used to execute the trace. - Claim public immutable ABSOLUTE_PRESTATE; + Claim internal immutable ABSOLUTE_PRESTATE; /// @notice The max depth of the game. - uint256 public immutable MAX_GAME_DEPTH; + uint256 internal immutable MAX_GAME_DEPTH; + + /// @notice The max depth of the output bisection portion of the position tree. Immediately beneath + /// this depth, execution trace bisection begins. + uint256 internal immutable SPLIT_DEPTH; /// @notice The duration of the game. - Duration public immutable GAME_DURATION; + Duration internal immutable GAME_DURATION; /// @notice An onchain VM that performs single instruction steps on a fault proof program trace. - IBigStepper public immutable VM; + IBigStepper internal immutable VM; - /// @notice The trusted L2OutputOracle contract. - L2OutputOracle public immutable L2_OUTPUT_ORACLE; + /// @notice The game type ID. + GameType internal immutable GAME_TYPE; - /// @notice The block hash oracle, used for loading block hashes further back - /// than the `BLOCKHASH` opcode allows as well as their child's timestamp. - BlockOracle public immutable BLOCK_ORACLE; + /// @notice WETH contract for holding ETH. + IDelayedWETH internal immutable WETH; - /// @notice The game type ID - GameType internal immutable GAME_TYPE; + /// @notice The anchor state registry. + IAnchorStateRegistry internal immutable ANCHOR_STATE_REGISTRY; - /// @notice The root claim's position is always at gindex 1. + /// @notice The chain ID of the L2 network this contract argues about. + uint256 internal immutable L2_CHAIN_ID; + + /// @notice The global root claim's position is always at gindex 1. Position internal constant ROOT_POSITION = Position.wrap(1); + /// @notice The flag set in the `bond` field of a `ClaimData` struct to indicate that the bond has been claimed. + uint128 internal constant CLAIMED_BOND_FLAG = type(uint128).max; + /// @notice The starting timestamp of the game Timestamp public createdAt; - /// @inheritdoc IDisputeGame - GameStatus public status; + /// @notice The timestamp of the game's global resolution. + Timestamp public resolvedAt; /// @inheritdoc IDisputeGame - IBondManager public bondManager; - - /// @inheritdoc IFaultDisputeGame - Hash public l1Head; + GameStatus public status; /// @notice An append-only array of all claims made during the dispute game. ClaimData[] public claimData; - /// @notice The starting and disputed output proposal for the game. Includes information about - /// the output indexes in the `L2OutputOracle` and the output roots at the time of - /// game creation. - OutputProposals public proposals; + /// @notice Credited balances for winning participants. + mapping(address => uint256) public credit; /// @notice An internal mapping to allow for constant-time lookups of existing claims. mapping(ClaimHash => bool) internal claims; @@ -81,44 +84,70 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { /// @notice Indicates whether the subgame rooted at the root claim has been resolved. bool internal subgameAtRootResolved; + /// @notice Flag for the `initialize` function to prevent re-initialization. + bool internal initialized; + + /// @notice The latest finalized output root, serving as the anchor for output bisection. + OutputRoot public startingOutputRoot; + /// @notice Semantic version. - /// @custom:semver 0.0.11 - string public constant version = "0.0.11"; + /// @custom:semver 0.8.1 + string public constant version = "0.8.1"; /// @param _gameType The type ID of the game. /// @param _absolutePrestate The absolute prestate of the instruction trace. /// @param _maxGameDepth The maximum depth of bisection. + /// @param _splitDepth The final depth of the output bisection portion of the game. /// @param _gameDuration The duration of the game. - /// @param _vm An onchain VM that performs single instruction steps on a fault proof program - /// trace. - /// @param _l2oo The trusted L2OutputOracle contract. - /// @param _blockOracle The block oracle, used for loading block hashes further back - /// than the `BLOCKHASH` opcode allows as well as their estimated - /// timestamps. + /// @param _vm An onchain VM that performs single instruction steps on an FPP trace. + /// @param _weth WETH contract for holding ETH. + /// @param _anchorStateRegistry The contract that stores the anchor state for each game type. + /// @param _l2ChainId Chain ID of the L2 network this contract argues about. constructor( GameType _gameType, Claim _absolutePrestate, uint256 _maxGameDepth, + uint256 _splitDepth, Duration _gameDuration, IBigStepper _vm, - L2OutputOracle _l2oo, - BlockOracle _blockOracle + IDelayedWETH _weth, + IAnchorStateRegistry _anchorStateRegistry, + uint256 _l2ChainId ) { + // The split depth cannot be greater than or equal to the max game depth. + if (_splitDepth >= _maxGameDepth) revert InvalidSplitDepth(); + GAME_TYPE = _gameType; ABSOLUTE_PRESTATE = _absolutePrestate; MAX_GAME_DEPTH = _maxGameDepth; + SPLIT_DEPTH = _splitDepth; GAME_DURATION = _gameDuration; VM = _vm; - L2_OUTPUT_ORACLE = _l2oo; - BLOCK_ORACLE = _blockOracle; + WETH = _weth; + ANCHOR_STATE_REGISTRY = _anchorStateRegistry; + L2_CHAIN_ID = _l2ChainId; } + /// @notice Receive function to allow the contract to receive ETH. + receive() external payable { } + + /// @notice Fallback function to allow the contract to receive ETH. + fallback() external payable { } + //////////////////////////////////////////////////////////////// // `IFaultDisputeGame` impl // //////////////////////////////////////////////////////////////// /// @inheritdoc IFaultDisputeGame - function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external { + function step( + uint256 _claimIndex, + bool _isAttack, + bytes calldata _stateData, + bytes calldata _proof + ) + public + virtual + { // INVARIANT: Steps cannot be made unless the game is currently in progress. if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); @@ -141,26 +170,30 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // prestate. // If the step is an attack at a trace index > 0, the prestate exists elsewhere in // the game state. - preStateClaim = stepPos.indexAtDepth() == 0 + // NOTE: We localize the `indexAtDepth` for the current execution trace subgame by finding + // the remainder of the index at depth divided by 2 ** (MAX_GAME_DEPTH - SPLIT_DEPTH), + // which is the number of leaves in each execution trace subgame. This is so that we can + // determine whether or not the step position is represents the `ABSOLUTE_PRESTATE`. + preStateClaim = (stepPos.indexAtDepth() % (1 << (MAX_GAME_DEPTH - SPLIT_DEPTH))) == 0 ? ABSOLUTE_PRESTATE - : findTraceAncestor(Position.wrap(Position.unwrap(parentPos) - 1), parent.parentIndex).claim; - + : _findTraceAncestor(Position.wrap(parentPos.raw() - 1), parent.parentIndex, false).claim; // For all attacks, the poststate is the parent claim. postState = parent; } else { // If the step is a defense, the poststate exists elsewhere in the game state, // and the parent claim is the expected pre-state. preStateClaim = parent.claim; - postState = findTraceAncestor(Position.wrap(Position.unwrap(parentPos) + 1), parent.parentIndex); + postState = _findTraceAncestor(Position.wrap(parentPos.raw() + 1), parent.parentIndex, false); } // INVARIANT: The prestate is always invalid if the passed `_stateData` is not the // preimage of the prestate claim hash. // We ignore the highest order byte of the digest because it is used to // indicate the VM Status and is added after the digest is computed. - if (keccak256(_stateData) << 8 != Claim.unwrap(preStateClaim) << 8) { - revert InvalidPrestate(); - } + if (keccak256(_stateData) << 8 != preStateClaim.raw() << 8) revert InvalidPrestate(); + + // Compute the local preimage context for the step. + Hash uuid = _findLocalContext(_claimIndex); // INVARIANT: If a step is an attack, the poststate is valid if the step produces // the same poststate hash as the parent claim's value. @@ -174,44 +207,57 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // SAFETY: While the `attack` path does not need an extra check for the post // state's depth in relation to the parent, we don't need another // branch because (n - n) % 2 == 0. - // TODO(client-pod#94): Once output bisection is implemented, the local context will no longer - // be constant. We will need to pass it in here based off of the ancestor - // disputed output root's L2 block number. - bool validStep = VM.step(_stateData, _proof, 0) == Claim.unwrap(postState.claim); + bool validStep = VM.step(_stateData, _proof, uuid.raw()) == postState.claim.raw(); bool parentPostAgree = (parentPos.depth() - postState.position.depth()) % 2 == 0; if (parentPostAgree == validStep) revert ValidStep(); + // INVARIANT: A step cannot be made against a claim for a second time. + if (parent.counteredBy != address(0)) revert DuplicateStep(); + // Set the parent claim as countered. We do not need to append a new claim to the game; // instead, we can just set the existing parent as countered. - parent.countered = true; + parent.counteredBy = msg.sender; } - /// @notice Internal move function, used by both `attack` and `defend`. + /// @notice Generic move function, used for both `attack` and `defend` moves. /// @param _challengeIndex The index of the claim being moved against. /// @param _claim The claim at the next logical position in the game. /// @param _isAttack Whether or not the move is an attack or defense. - function move(uint256 _challengeIndex, Claim _claim, bool _isAttack) public payable { + function move(uint256 _challengeIndex, Claim _claim, bool _isAttack) public payable virtual { // INVARIANT: Moves cannot be made unless the game is currently in progress. if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); - // INVARIANT: A defense can never be made against the root claim. This is because the root - // claim commits to the entire state. Therefore, the only valid defense is to - // do nothing if it is agreed with. - if (_challengeIndex == 0 && !_isAttack) revert CannotDefendRootClaim(); - // Get the parent. If it does not exist, the call will revert with OOB. ClaimData memory parent = claimData[_challengeIndex]; // Compute the position that the claim commits to. Because the parent's position is already // known, we can compute the next position by moving left or right depending on whether // or not the move is an attack or defense. - Position nextPosition = parent.position.move(_isAttack); + Position parentPos = parent.position; + Position nextPosition = parentPos.move(_isAttack); + uint256 nextPositionDepth = nextPosition.depth(); + + // INVARIANT: A defense can never be made against the root claim of either the output root game or any + // of the execution trace bisection subgames. This is because the root claim commits to the + // entire state. Therefore, the only valid defense is to do nothing if it is agreed with. + if ((_challengeIndex == 0 || nextPositionDepth == SPLIT_DEPTH + 2) && !_isAttack) { + revert CannotDefendRootClaim(); + } // INVARIANT: A move can never surpass the `MAX_GAME_DEPTH`. The only option to counter a // claim at this depth is to perform a single instruction step on-chain via // the `step` function to prove that the state transition produces an unexpected // post-state. - if (nextPosition.depth() > MAX_GAME_DEPTH) revert GameDepthExceeded(); + if (nextPositionDepth > MAX_GAME_DEPTH) revert GameDepthExceeded(); + + // When the next position surpasses the split depth (i.e., it is the root claim of an execution + // trace bisection sub-game), we need to perform some extra verification steps. + if (nextPositionDepth == SPLIT_DEPTH + 1) { + _verifyExecBisectionRoot(_claim, _challengeIndex, parentPos, _isAttack); + } + + // INVARIANT: The `msg.value` must be sufficient to cover the required bond. + if (getRequiredBond(nextPosition) > msg.value) revert InsufficientBond(); // Fetch the grandparent clock, if it exists. // The grandparent clock should always exist unless the parent is the root claim. @@ -226,25 +272,23 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { Duration nextDuration = Duration.wrap( uint64( // First, fetch the duration of the grandparent claim. - Duration.unwrap(grandparentClock.duration()) + grandparentClock.duration().raw() // Second, add the difference between the current block timestamp and the // parent's clock timestamp. - + block.timestamp - Timestamp.unwrap(parent.clock.timestamp()) + + block.timestamp - parent.clock.timestamp().raw() ) ); // INVARIANT: A move can never be made once its clock has exceeded `GAME_DURATION / 2` // seconds of time. - if (Duration.unwrap(nextDuration) > Duration.unwrap(GAME_DURATION) >> 1) { - revert ClockTimeExceeded(); - } + if (nextDuration.raw() > GAME_DURATION.raw() >> 1) revert ClockTimeExceeded(); // Construct the next clock with the new duration and the current block timestamp. Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp))); // INVARIANT: There cannot be multiple identical claims with identical moves on the same challengeIndex. Multiple - // claims - // at the same position may dispute the same challengeIndex. However, the must have different values. + // claims at the same position may dispute the same challengeIndex. However, they must have different + // values. ClaimHash claimHash = _claim.hashClaimPos(nextPosition, _challengeIndex); if (claims[claimHash]) revert ClaimAlreadyExists(); claims[claimHash] = true; @@ -253,19 +297,22 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { claimData.push( ClaimData({ parentIndex: uint32(_challengeIndex), + // This is updated during subgame resolution + counteredBy: address(0), + claimant: msg.sender, + bond: uint128(msg.value), claim: _claim, position: nextPosition, - clock: nextClock, - countered: false + clock: nextClock }) ); - // Set the parent claim as countered. - claimData[_challengeIndex].countered = true; - // Update the subgame rooted at the parent claim. subgames[_challengeIndex].push(claimData.length - 1); + // Deposit the bond. + WETH.deposit{ value: msg.value }(); + // Emit the appropriate event for the attack or defense. emit Move(_challengeIndex, _claim, msg.sender); } @@ -281,73 +328,49 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { } /// @inheritdoc IFaultDisputeGame - function addLocalData(uint256 _ident, uint256 _l2BlockNumber, uint256 _partOffset) external { + function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external { // INVARIANT: Local data can only be added if the game is currently in progress. if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); + (Claim starting, Position startingPos, Claim disputed, Position disputedPos) = + _findStartingAndDisputedOutputs(_execLeafIdx); + Hash uuid = _computeLocalContext(starting, startingPos, disputed, disputedPos); + IPreimageOracle oracle = VM.oracle(); - bytes4 loadLocalDataSelector = IPreimageOracle.loadLocalData.selector; - assembly { - // Store the `loadLocalData(uint256,bytes32,uint256,uint256)` selector - mstore(0x1C, loadLocalDataSelector) - // Store the `_ident` argument - mstore(0x20, _ident) - // Store the `_localContext` argument - mstore(0x40, _l2BlockNumber) - // Store the data to load - let data - switch _ident - case 1 { - // Load the L1 head hash - data := sload(l1Head.slot) - } - case 2 { - // Load the starting proposal's output root. - data := sload(add(proposals.slot, 0x01)) - } - case 3 { - // Load the disputed proposal's output root - data := sload(add(proposals.slot, 0x03)) - } - case 4 { - // Load the starting proposal's L2 block number as a big-endian uint64 in the - // high order 8 bytes of the word. - data := shl(0xC0, shr(0x80, sload(proposals.slot))) - } - case 5 { - // Load the chain ID as a big-endian uint64 in the high order 8 bytes of the word. - data := shl(0xC0, chainid()) - } - default { - // Store the `InvalidLocalIdent()` selector. - mstore(0x00, 0xff137e65) - // Revert with `InvalidLocalIdent()` - revert(0x1C, 0x04) - } - mstore(0x60, data) - // Store the size of the data to load - // _ident > 3 ? 8 : 32 - mstore(0x80, shl(sub(0x05, shl(0x01, gt(_ident, 0x03))), 0x01)) - // Store the part offset of the data - mstore(0xA0, _partOffset) - - // Attempt to add the local data to the preimage oracle and bubble up the revert - // if it fails. - if iszero(call(gas(), oracle, 0x00, 0x1C, 0xA4, 0x00, 0x00)) { - returndatacopy(0x00, 0x00, returndatasize()) - revert(0x00, returndatasize()) - } + if (_ident == LocalPreimageKey.L1_HEAD_HASH) { + // Load the L1 head hash + oracle.loadLocalData(_ident, uuid.raw(), l1Head().raw(), 32, _partOffset); + } else if (_ident == LocalPreimageKey.STARTING_OUTPUT_ROOT) { + // Load the starting proposal's output root. + oracle.loadLocalData(_ident, uuid.raw(), starting.raw(), 32, _partOffset); + } else if (_ident == LocalPreimageKey.DISPUTED_OUTPUT_ROOT) { + // Load the disputed proposal's output root + oracle.loadLocalData(_ident, uuid.raw(), disputed.raw(), 32, _partOffset); + } else if (_ident == LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER) { + // Load the disputed proposal's L2 block number as a big-endian uint64 in the + // high order 8 bytes of the word. + + // We add the index at depth + 1 to the starting block number to get the disputed L2 + // block number. + uint256 l2Number = startingOutputRoot.l2BlockNumber + disputedPos.traceIndex(SPLIT_DEPTH) + 1; + + oracle.loadLocalData(_ident, uuid.raw(), bytes32(l2Number << 0xC0), 8, _partOffset); + } else if (_ident == LocalPreimageKey.CHAIN_ID) { + // Load the chain ID as a big-endian uint64 in the high order 8 bytes of the word. + oracle.loadLocalData(_ident, uuid.raw(), bytes32(L2_CHAIN_ID << 0xC0), 8, _partOffset); + } else { + revert InvalidLocalIdent(); } } /// @inheritdoc IFaultDisputeGame - function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) { - l2BlockNumber_ = _getArgUint256(0x20); + function l1Head() public pure returns (Hash l1Head_) { + l1Head_ = Hash.wrap(_getArgFixedBytes(0x20)); } /// @inheritdoc IFaultDisputeGame - function l1BlockNumber() public pure returns (uint256 l1BlockNumber_) { - l1BlockNumber_ = _getArgUint256(0x40); + function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) { + l2BlockNumber_ = _getArgUint256(0x40); } //////////////////////////////////////////////////////////////// @@ -367,8 +390,15 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { // INVARIANT: Resolution cannot occur unless the absolute root subgame has been resolved. if (!subgameAtRootResolved) revert OutOfOrderResolution(); - status_ = claimData[0].countered ? GameStatus.CHALLENGER_WINS : GameStatus.DEFENDER_WINS; + // Update the global game status; The dispute has concluded. + status_ = claimData[0].counteredBy == address(0) ? GameStatus.DEFENDER_WINS : GameStatus.CHALLENGER_WINS; + resolvedAt = Timestamp.wrap(uint64(block.timestamp)); + + // Update the status and emit the resolved event, note that we're performing an assignment here. emit Resolved(status = status_); + + // Try to update the anchor state, this should not revert. + ANCHOR_STATE_REGISTRY.tryUpdateAnchorState(); } /// @inheritdoc IFaultDisputeGame @@ -379,24 +409,37 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ClaimData storage parent = claimData[_claimIndex]; // INVARIANT: Cannot resolve a subgame unless the clock of its root has expired - if ( - Duration.unwrap(parent.clock.duration()) + (block.timestamp - Timestamp.unwrap(parent.clock.timestamp())) - <= Duration.unwrap(GAME_DURATION) >> 1 - ) { + uint64 parentClockDuration = parent.clock.duration().raw(); + uint64 timeSinceParentMove = uint64(block.timestamp) - parent.clock.timestamp().raw(); + if (parentClockDuration + timeSinceParentMove <= GAME_DURATION.raw() >> 1) { revert ClockNotExpired(); } uint256[] storage challengeIndices = subgames[_claimIndex]; + uint256 challengeIndicesLen = challengeIndices.length; // INVARIANT: Cannot resolve subgames twice - // Uncontested claims are resolved implicitly unless they are the root claim - if (_claimIndex == 0 && subgameAtRootResolved) revert ClaimAlreadyResolved(); - if (challengeIndices.length == 0 && _claimIndex != 0) revert ClaimAlreadyResolved(); + if (_claimIndex == 0 && subgameAtRootResolved) { + revert ClaimAlreadyResolved(); + } - // Assume parent is honest until proven otherwise - bool countered = false; + // Uncontested claims are resolved implicitly unless they are the root claim. Pay out the bond to the claimant + // and return early. + if (challengeIndicesLen == 0 && _claimIndex != 0) { + // In the event that the parent claim is at the max depth, there will always be 0 subgames. If the + // `counteredBy` field is set and there are no subgames, this implies that the parent claim was successfully + // stepped against. In this case, we pay out the bond to the party that stepped against the parent claim. + // Otherwise, the parent claim is uncontested, and the bond is returned to the claimant. + address counteredBy = parent.counteredBy; + address recipient = counteredBy == address(0) ? parent.claimant : counteredBy; + _distributeBond(recipient, parent); + return; + } - for (uint256 i = 0; i < challengeIndices.length; ++i) { + // Assume parent is honest until proven otherwise + address countered = address(0); + Position leftmostCounter = Position.wrap(type(uint128).max); + for (uint256 i = 0; i < challengeIndicesLen; ++i) { uint256 challengeIndex = challengeIndices[i]; // INVARIANT: Cannot resolve a subgame containing an unresolved claim @@ -404,21 +447,30 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { ClaimData storage claim = claimData[challengeIndex]; - // Ignore false claims - if (!claim.countered) { - countered = true; - break; + // If the child subgame is uncountered and further left than the current left-most counter, + // update the parent subgame's `countered` address and the current `leftmostCounter`. + // The left-most correct counter is preferred in bond payouts in order to discourage attackers + // from countering invalid subgame roots via an invalid defense position. As such positions + // cannot be correctly countered. + // Note that correctly positioned defense, but invalid claimes can still be successfully countered. + if (claim.counteredBy == address(0) && leftmostCounter.raw() > claim.position.raw()) { + countered = claim.claimant; + leftmostCounter = claim.position; } } + // If the parent was not successfully countered, pay out the parent's bond to the claimant. + // If the parent was successfully countered, pay out the parent's bond to the challenger. + _distributeBond(countered == address(0) ? parent.claimant : countered, parent); + // Once a subgame is resolved, we percolate the result up the DAG so subsequent calls to // resolveClaim will not need to traverse this subgame. - parent.countered = countered; + parent.counteredBy = countered; // Resolved subgames have no entries delete subgames[_claimIndex]; - // Indicate the game is ready to be resolved + // Indicate the game is ready to be resolved globally. if (_claimIndex == 0) { subgameAtRootResolved = true; } @@ -432,8 +484,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { /// @inheritdoc IDisputeGame function extraData() public pure returns (bytes memory extraData_) { // The extra data starts at the second word within the cwia calldata and - // is 64 bytes long. - extraData_ = _getArgDynBytes(0x20, 0x40); + // is 32 bytes long. + extraData_ = _getArgDynBytes(0x40, 0x20); } /// @inheritdoc IDisputeGame @@ -443,92 +495,83 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { extraData_ = extraData(); } + /// @inheritdoc IFaultDisputeGame + function startingBlockNumber() external view returns (uint256 startingBlockNumber_) { + startingBlockNumber_ = startingOutputRoot.l2BlockNumber; + } + + /// @inheritdoc IFaultDisputeGame + function startingRootHash() external view returns (Hash startingRootHash_) { + startingRootHash_ = startingOutputRoot.root; + } + //////////////////////////////////////////////////////////////// // MISC EXTERNAL // //////////////////////////////////////////////////////////////// /// @inheritdoc IInitializable - function initialize() external { + function initialize() public payable virtual { // SAFETY: Any revert in this function will bubble up to the DisputeGameFactory and // prevent the game from being created. // // Implicit assumptions: // - The `gameStatus` state variable defaults to 0, which is `GameStatus.IN_PROGRESS` + // - The dispute game factory will enforce the required bond to initialize the game. + // + // Explicit checks: + // - The game must not have already been initialized. + // - An output root cannot be proposed at or before the starting block number. - // The VMStatus must indicate (1) 'invalid', to argue that disputed thing is invalid. - // Games that agree with the existing outcome are not allowed. - // NOTE(clabby): This assumption will change in Alpha Chad. - uint8 vmStatus = uint8(Claim.unwrap(rootClaim())[0]); - if (!(vmStatus == VMStatus.unwrap(VMStatuses.INVALID) || vmStatus == VMStatus.unwrap(VMStatuses.PANIC))) { - revert UnexpectedRootClaim(rootClaim()); - } + // INVARIANT: The game must not have already been initialized. + if (initialized) revert AlreadyInitialized(); - // Set the game's starting timestamp - createdAt = Timestamp.wrap(uint64(block.timestamp)); + // Grab the latest anchor root. + (Hash root, uint256 rootBlockNumber) = ANCHOR_STATE_REGISTRY.anchors(GAME_TYPE); + + // Should only happen if this is a new game type that hasn't been set up yet. + if (root.raw() == bytes32(0)) revert AnchorRootNotFound(); + + // Set the starting output root. + startingOutputRoot = OutputRoot({ l2BlockNumber: rootBlockNumber, root: root }); + + // Do not allow the game to be initialized if the root claim corresponds to a block at or before the + // configured starting block number. + if (l2BlockNumber() <= rootBlockNumber) revert UnexpectedRootClaim(rootClaim()); + + // Revert if the calldata size is too large, which signals that the `extraData` contains more than expected. + // This is to prevent adding extra bytes to the `extraData` that result in a different game UUID in the factory, + // but are not used by the game, which would allow for multiple dispute games for the same output proposal to + // be created. + // Expected length: 0x66 (0x04 selector + 0x20 root claim + 0x20 l1 head + 0x20 extraData + 0x02 CWIA bytes) + assembly { + if gt(calldatasize(), 0x66) { + // Store the selector for `ExtraDataTooLong()` & revert + mstore(0x00, 0xc407e025) + revert(0x1C, 0x04) + } + } // Set the root claim claimData.push( ClaimData({ parentIndex: type(uint32).max, + counteredBy: address(0), + claimant: tx.origin, + bond: uint128(msg.value), claim: rootClaim(), position: ROOT_POSITION, - clock: LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))), - countered: false + clock: LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))) }) ); - // Grab the index of the output proposal that commits to the starting L2 head. - // All outputs after this one are disputed. - // TODO(clabby): This is 2 calls too many for the information we need. Maybe - // add a function to the L2OO? - // TODO(clabby): The block hash bisection game will allow us to dispute the first output - // root by using genesis as the starting point. For now, it is critical that - // the first proposed output root of an OP stack chain is done so by an - // honest party. - uint256 proposalIdx = L2_OUTPUT_ORACLE.getL2OutputIndexAfter(l2BlockNumber()); - Types.OutputProposal memory starting = L2_OUTPUT_ORACLE.getL2Output(proposalIdx - 1); - Types.OutputProposal memory disputed = L2_OUTPUT_ORACLE.getL2Output(proposalIdx); - - // SAFETY: This call can revert if the block hash oracle does not have information - // about the block number provided to it. - BlockOracle.BlockInfo memory blockInfo = BLOCK_ORACLE.load(l1BlockNumber()); - - // INVARIANT: The L1 head must contain the disputed output root. If it does not, - // the game cannot be played. - // SAFETY: The block timestamp in the oracle records the timestamp of the - // block *after* the hash stored. This means that the timestamp - // is off by 1 block. This is known, and covered as follows: - // - The timestamp will always be less than the disputed timestamp - // if the checkpoint was made before the proposal. We must revert here. - // - The timestamp will be equal to the disputed timestamp if the - // checkpoint was made in the same block as the proposal, and the - // hash will be the parent block, which does not contain the proposal. - // We must revert here. - // - The timestamp will always be greater than the disputed timestamp - // if the checkpoint was made any block after the proposal. This is - // the only case where we can continue, since we must have the L1 - // head contain the disputed output root to play the game. - if (Timestamp.unwrap(blockInfo.childTimestamp) <= disputed.timestamp) revert L1HeadTooOld(); - - // Persist the output proposals fetched from the oracle. These outputs will be referenced - // for loading local data into the preimage oracle as well as to authenticate the game's - // resolution. If the disputed output has changed in the oracle, the game cannot be - // resolved. - proposals = OutputProposals({ - starting: OutputProposal({ - index: uint128(proposalIdx - 1), - l2BlockNumber: starting.l2BlockNumber, - outputRoot: Hash.wrap(starting.outputRoot) - }), - disputed: OutputProposal({ - index: uint128(proposalIdx), - l2BlockNumber: disputed.l2BlockNumber, - outputRoot: Hash.wrap(disputed.outputRoot) - }) - }); + // Deposit the bond. + WETH.deposit{ value: msg.value }(); - // Persist the L1 head hash of the L1 block number provided. - l1Head = blockInfo.hash; + // Set the game's starting timestamp + createdAt = Timestamp.wrap(uint64(block.timestamp)); + + // Set the game as initialized. + initialized = true; } /// @notice Returns the length of the `claimData` array. @@ -536,25 +579,300 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver { len_ = claimData.length; } + /// @notice Returns the required bond for a given move kind. + /// @param _position The position of the bonded interaction. + /// @return requiredBond_ The required ETH bond for the given move, in wei. + function getRequiredBond(Position _position) public view returns (uint256 requiredBond_) { + uint256 depth = uint256(_position.depth()); + if (depth > MAX_GAME_DEPTH) revert GameDepthExceeded(); + + // Values taken from Big Bonds v1.5 (TM) spec. + uint256 assumedBaseFee = 200 gwei; + uint256 baseGasCharged = 400_000; + uint256 highGasCharged = 200_000_000; + + // Goal here is to compute the fixed multiplier that will be applied to the base gas + // charged to get the required gas amount for the given depth. We apply this multiplier + // some `n` times where `n` is the depth of the position. We are looking for some number + // that, when multiplied by itself `MAX_GAME_DEPTH` times and then multiplied by the base + // gas charged, will give us the maximum gas that we want to charge. + // We want to solve for (highGasCharged/baseGasCharged) ** (1/MAX_GAME_DEPTH). + // We know that a ** (b/c) is equal to e ** (ln(a) * (b/c)). + // We can compute e ** (ln(a) * (b/c)) quite easily with FixedPointMathLib. + + // Set up a, b, and c. + uint256 a = highGasCharged / baseGasCharged; + uint256 b = FixedPointMathLib.WAD; + uint256 c = MAX_GAME_DEPTH * FixedPointMathLib.WAD; + + // Compute ln(a). + // slither-disable-next-line divide-before-multiply + uint256 lnA = uint256(FixedPointMathLib.lnWad(int256(a * FixedPointMathLib.WAD))); + + // Computes (b / c) with full precision using WAD = 1e18. + uint256 bOverC = FixedPointMathLib.divWad(b, c); + + // Compute e ** (ln(a) * (b/c)) + // sMulWad can be used here since WAD = 1e18 maintains the same precision. + uint256 numerator = FixedPointMathLib.mulWad(lnA, bOverC); + int256 base = FixedPointMathLib.expWad(int256(numerator)); + + // Compute the required gas amount. + int256 rawGas = FixedPointMathLib.powWad(base, int256(depth * FixedPointMathLib.WAD)); + uint256 requiredGas = FixedPointMathLib.mulWad(baseGasCharged, uint256(rawGas)); + + // Compute the required bond. + requiredBond_ = assumedBaseFee * requiredGas; + } + + /// @notice Claim the credit belonging to the recipient address. + /// @param _recipient The owner and recipient of the credit. + function claimCredit(address _recipient) external { + // Remove the credit from the recipient prior to performing the external call. + uint256 recipientCredit = credit[_recipient]; + credit[_recipient] = 0; + + // Revert if the recipient has no credit to claim. + if (recipientCredit == 0) { + revert NoCreditToClaim(); + } + + // Try to withdraw the WETH amount so it can be used here. + WETH.withdraw(_recipient, recipientCredit); + + // Transfer the credit to the recipient. + (bool success,) = _recipient.call{ value: recipientCredit }(hex""); + if (!success) revert BondTransferFailed(); + } + + /// @notice Returns the flag set in the `bond` field of a `ClaimData` struct to indicate that the bond has been + /// claimed. + function claimedBondFlag() external pure returns (uint128 claimedBondFlag_) { + claimedBondFlag_ = CLAIMED_BOND_FLAG; + } + + //////////////////////////////////////////////////////////////// + // IMMUTABLE GETTERS // + //////////////////////////////////////////////////////////////// + + /// @notice Returns the absolute prestate of the instruction trace. + function absolutePrestate() external view returns (Claim absolutePrestate_) { + absolutePrestate_ = ABSOLUTE_PRESTATE; + } + + /// @notice Returns the max game depth. + function maxGameDepth() external view returns (uint256 maxGameDepth_) { + maxGameDepth_ = MAX_GAME_DEPTH; + } + + /// @notice Returns the split depth. + function splitDepth() external view returns (uint256 splitDepth_) { + splitDepth_ = SPLIT_DEPTH; + } + + /// @notice Returns the game duration. + function gameDuration() external view returns (Duration gameDuration_) { + gameDuration_ = GAME_DURATION; + } + + /// @notice Returns the address of the VM. + function vm() external view returns (IBigStepper vm_) { + vm_ = VM; + } + + /// @notice Returns the WETH contract for holding ETH. + function weth() external view returns (IDelayedWETH weth_) { + weth_ = WETH; + } + + /// @notice Returns the chain ID of the L2 network this contract argues about. + function l2ChainId() external view returns (uint256 l2ChainId_) { + l2ChainId_ = L2_CHAIN_ID; + } + //////////////////////////////////////////////////////////////// // HELPERS // //////////////////////////////////////////////////////////////// + /// @notice Pays out the bond of a claim to a given recipient. + /// @param _recipient The recipient of the bond. + /// @param _bonded The claim to pay out the bond of. + function _distributeBond(address _recipient, ClaimData storage _bonded) internal { + // Set all bits in the bond value to indicate that the bond has been paid out. + uint256 bond = _bonded.bond; + if (bond == CLAIMED_BOND_FLAG) revert ClaimAlreadyResolved(); + _bonded.bond = CLAIMED_BOND_FLAG; + + // Increase the recipient's credit. + credit[_recipient] += bond; + + // Unlock the bond. + WETH.unlock(_recipient, bond); + } + + /// @notice Verifies the integrity of an execution bisection subgame's root claim. Reverts if the claim + /// is invalid. + /// @param _rootClaim The root claim of the execution bisection subgame. + function _verifyExecBisectionRoot( + Claim _rootClaim, + uint256 _parentIdx, + Position _parentPos, + bool _isAttack + ) + internal + view + { + // The root claim of an execution trace bisection sub-game must: + // 1. Signal that the VM panicked or resulted in an invalid transition if the disputed output root + // was made by the opposing party. + // 2. Signal that the VM resulted in a valid transition if the disputed output root was made by the same party. + + // If the move is a defense, the disputed output could have been made by either party. In this case, we + // need to search for the parent output to determine what the expected status byte should be. + Position disputedLeafPos = Position.wrap(_parentPos.raw() + 1); + ClaimData storage disputed = _findTraceAncestor({ _pos: disputedLeafPos, _start: _parentIdx, _global: true }); + uint8 vmStatus = uint8(_rootClaim.raw()[0]); + + if (_isAttack || disputed.position.depth() % 2 == SPLIT_DEPTH % 2) { + // If the move is an attack, the parent output is always deemed to be disputed. In this case, we only need + // to check that the root claim signals that the VM panicked or resulted in an invalid transition. + // If the move is a defense, and the disputed output and creator of the execution trace subgame disagree, + // the root claim should also signal that the VM panicked or resulted in an invalid transition. + if (!(vmStatus == VMStatuses.INVALID.raw() || vmStatus == VMStatuses.PANIC.raw())) { + revert UnexpectedRootClaim(_rootClaim); + } + } else if (vmStatus != VMStatuses.VALID.raw()) { + // The disputed output and the creator of the execution trace subgame agree. The status byte should + // have signaled that the VM succeeded. + revert UnexpectedRootClaim(_rootClaim); + } + } + /// @notice Finds the trace ancestor of a given position within the DAG. /// @param _pos The position to find the trace ancestor claim of. /// @param _start The index to start searching from. + /// @param _global Whether or not to search the entire dag or just within an execution trace subgame. If set to + /// `true`, and `_pos` is at or above the split depth, this function will revert. /// @return ancestor_ The ancestor claim that commits to the same trace index as `_pos`. - // TODO(clabby): Can we form a relationship between the trace path and the position to avoid - // looping? - function findTraceAncestor(Position _pos, uint256 _start) internal view returns (ClaimData storage ancestor_) { + function _findTraceAncestor( + Position _pos, + uint256 _start, + bool _global + ) + internal + view + returns (ClaimData storage ancestor_) + { // Grab the trace ancestor's expected position. - Position preStateTraceAncestor = _pos.traceAncestor(); + Position traceAncestorPos = _global ? _pos.traceAncestor() : _pos.traceAncestorBounded(SPLIT_DEPTH); // Walk up the DAG to find a claim that commits to the same trace index as `_pos`. It is // guaranteed that such a claim exists. ancestor_ = claimData[_start]; - while (Position.unwrap(ancestor_.position) != Position.unwrap(preStateTraceAncestor)) { + while (ancestor_.position.raw() != traceAncestorPos.raw()) { ancestor_ = claimData[ancestor_.parentIndex]; } } + + /// @notice Finds the starting and disputed output root for a given `ClaimData` within the DAG. This + /// `ClaimData` must be below the `SPLIT_DEPTH`. + /// @param _start The index within `claimData` of the claim to start searching from. + /// @return startingClaim_ The starting output root claim. + /// @return startingPos_ The starting output root position. + /// @return disputedClaim_ The disputed output root claim. + /// @return disputedPos_ The disputed output root position. + function _findStartingAndDisputedOutputs(uint256 _start) + internal + view + returns (Claim startingClaim_, Position startingPos_, Claim disputedClaim_, Position disputedPos_) + { + // Fatch the starting claim. + uint256 claimIdx = _start; + ClaimData storage claim = claimData[claimIdx]; + + // If the starting claim's depth is less than or equal to the split depth, we revert as this is UB. + if (claim.position.depth() <= SPLIT_DEPTH) revert ClaimAboveSplit(); + + // We want to: + // 1. Find the first claim at the split depth. + // 2. Determine whether it was the starting or disputed output for the exec game. + // 3. Find the complimentary claim depending on the info from #2 (pre or post). + + // Walk up the DAG until the ancestor's depth is equal to the split depth. + uint256 currentDepth; + ClaimData storage execRootClaim = claim; + while ((currentDepth = claim.position.depth()) > SPLIT_DEPTH) { + uint256 parentIndex = claim.parentIndex; + + // If we're currently at the split depth + 1, we're at the root of the execution sub-game. + // We need to keep track of the root claim here to determine whether the execution sub-game was + // started with an attack or defense against the output leaf claim. + if (currentDepth == SPLIT_DEPTH + 1) execRootClaim = claim; + + claim = claimData[parentIndex]; + claimIdx = parentIndex; + } + + // Determine whether the start of the execution sub-game was an attack or defense to the output root + // above. This is important because it determines which claim is the starting output root and which + // is the disputed output root. + (Position execRootPos, Position outputPos) = (execRootClaim.position, claim.position); + bool wasAttack = execRootPos.parent().raw() == outputPos.raw(); + + // Determine the starting and disputed output root indices. + // 1. If it was an attack, the disputed output root is `claim`, and the starting output root is + // elsewhere in the DAG (it must commit to the block # index at depth of `outputPos - 1`). + // 2. If it was a defense, the starting output root is `claim`, and the disputed output root is + // elsewhere in the DAG (it must commit to the block # index at depth of `outputPos + 1`). + if (wasAttack) { + // If this is an attack on the first output root (the block directly after the starting + // block number), the starting claim nor position exists in the tree. We leave these as + // 0, which can be easily identified due to 0 being an invalid Gindex. + if (outputPos.indexAtDepth() > 0) { + ClaimData storage starting = _findTraceAncestor(Position.wrap(outputPos.raw() - 1), claimIdx, true); + (startingClaim_, startingPos_) = (starting.claim, starting.position); + } else { + startingClaim_ = Claim.wrap(startingOutputRoot.root.raw()); + } + (disputedClaim_, disputedPos_) = (claim.claim, claim.position); + } else { + ClaimData storage disputed = _findTraceAncestor(Position.wrap(outputPos.raw() + 1), claimIdx, true); + (startingClaim_, startingPos_) = (claim.claim, claim.position); + (disputedClaim_, disputedPos_) = (disputed.claim, disputed.position); + } + } + + /// @notice Finds the local context hash for a given claim index that is present in an execution trace subgame. + /// @param _claimIndex The index of the claim to find the local context hash for. + /// @return uuid_ The local context hash. + function _findLocalContext(uint256 _claimIndex) internal view returns (Hash uuid_) { + (Claim starting, Position startingPos, Claim disputed, Position disputedPos) = + _findStartingAndDisputedOutputs(_claimIndex); + uuid_ = _computeLocalContext(starting, startingPos, disputed, disputedPos); + } + + /// @notice Computes the local context hash for a set of starting/disputed claim values and positions. + /// @param _starting The starting claim. + /// @param _startingPos The starting claim's position. + /// @param _disputed The disputed claim. + /// @param _disputedPos The disputed claim's position. + /// @return uuid_ The local context hash. + function _computeLocalContext( + Claim _starting, + Position _startingPos, + Claim _disputed, + Position _disputedPos + ) + internal + pure + returns (Hash uuid_) + { + // A position of 0 indicates that the starting claim is the absolute prestate. In this special case, + // we do not include the starting claim within the local context hash. + if (_startingPos.raw() == 0) { + uuid_ = Hash.wrap(keccak256(abi.encode(_disputed, _disputedPos))); + } else { + uuid_ = Hash.wrap(keccak256(abi.encode(_starting, _startingPos, _disputed, _disputedPos))); + } + } } diff --git a/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol b/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol new file mode 100644 index 000000000000..6063eb0e5476 --- /dev/null +++ b/packages/contracts-bedrock/src/dispute/PermissionedDisputeGame.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; +import { FaultDisputeGame, IFaultDisputeGame, IBigStepper, IInitializable } from "src/dispute/FaultDisputeGame.sol"; +import "src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeErrors.sol"; + +/// @title PermissionedDisputeGame +/// @notice PermissionedDisputeGame is a contract that inherits from `FaultDisputeGame`, and contains two roles: +/// - The `challenger` role, which is allowed to challenge a dispute. +/// - The `proposer` role, which is allowed to create proposals and participate in their game. +/// This contract exists as a way for networks to support the fault proof iteration of the OptimismPortal +/// contract without needing to support a fully permissionless system. Permissionless systems can introduce +/// costs that certain networks may not wish to support. This contract can also be used as a fallback mechanism +/// in case of a failure in the permissionless fault proof system in the stage one release. +contract PermissionedDisputeGame is FaultDisputeGame { + /// @notice The proposer role is allowed to create proposals and participate in the dispute game. + address internal immutable PROPOSER; + + /// @notice The challenger role is allowed to participate in the dispute game. + address internal immutable CHALLENGER; + + /// @notice Modifier that gates access to the `challenger` and `proposer` roles. + modifier onlyAuthorized() { + if (!(msg.sender == PROPOSER || msg.sender == CHALLENGER)) { + revert BadAuth(); + } + _; + } + + /// @param _gameType The type ID of the game. + /// @param _absolutePrestate The absolute prestate of the instruction trace. + /// @param _maxGameDepth The maximum depth of bisection. + /// @param _splitDepth The final depth of the output bisection portion of the game. + /// @param _gameDuration The duration of the game. + /// @param _vm An onchain VM that performs single instruction steps on an FPP trace. + /// @param _weth WETH contract for holding ETH. + /// @param _anchorStateRegistry The contract that stores the anchor state for each game type. + /// @param _l2ChainId Chain ID of the L2 network this contract argues about. + /// @param _proposer Address that is allowed to create instances of this contract. + /// @param _challenger Address that is allowed to challenge instances of this contract. + constructor( + GameType _gameType, + Claim _absolutePrestate, + uint256 _maxGameDepth, + uint256 _splitDepth, + Duration _gameDuration, + IBigStepper _vm, + IDelayedWETH _weth, + IAnchorStateRegistry _anchorStateRegistry, + uint256 _l2ChainId, + address _proposer, + address _challenger + ) + FaultDisputeGame( + _gameType, + _absolutePrestate, + _maxGameDepth, + _splitDepth, + _gameDuration, + _vm, + _weth, + _anchorStateRegistry, + _l2ChainId + ) + { + PROPOSER = _proposer; + CHALLENGER = _challenger; + } + + /// @inheritdoc IFaultDisputeGame + function step( + uint256 _claimIndex, + bool _isAttack, + bytes calldata _stateData, + bytes calldata _proof + ) + public + override + onlyAuthorized + { + super.step(_claimIndex, _isAttack, _stateData, _proof); + } + + /// @notice Generic move function, used for both `attack` and `defend` moves. + /// @param _challengeIndex The index of the claim being moved against. + /// @param _claim The claim at the next logical position in the game. + /// @param _isAttack Whether or not the move is an attack or defense. + function move(uint256 _challengeIndex, Claim _claim, bool _isAttack) public payable override onlyAuthorized { + super.move(_challengeIndex, _claim, _isAttack); + } + + /// @inheritdoc IInitializable + function initialize() public payable override { + // The creator of the dispute game must be the proposer EOA. + if (tx.origin != PROPOSER) revert BadAuth(); + + // Fallthrough initialization. + super.initialize(); + } +} diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol new file mode 100644 index 000000000000..b10a9dc7712e --- /dev/null +++ b/packages/contracts-bedrock/src/dispute/interfaces/IAnchorStateRegistry.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; + +import "src/libraries/DisputeTypes.sol"; + +/// @title IAnchorStateRegistry +/// @notice Describes a contract that stores the anchor state for each game type. +interface IAnchorStateRegistry { + /// @notice Returns the anchor state for the given game type. + /// @param _gameType The game type to get the anchor state for. + /// @return The anchor state for the given game type. + function anchors(GameType _gameType) external view returns (Hash, uint256); + + /// @notice Returns the DisputeGameFactory address. + /// @return DisputeGameFactory address. + function disputeGameFactory() external view returns (IDisputeGameFactory); + + /// @notice Callable by FaultDisputeGame contracts to update the anchor state. Pulls the anchor state directly from + /// the FaultDisputeGame contract and stores it in the registry if the new anchor state is valid and the + /// state is newer than the current anchor state. + function tryUpdateAnchorState() external; +} diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IBigStepper.sol b/packages/contracts-bedrock/src/dispute/interfaces/IBigStepper.sol index 39265bc5721a..f38e58f9d9d6 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IBigStepper.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IBigStepper.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.0; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; /// @title IBigStepper -/// @notice An interface for a contract with a state transition function that -/// will accept a pre state and return a post state. +/// @notice Describes a state machine that can perform a single instruction step, provided a prestate and an optional +/// proof. /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⠶⢅⠒⢄⢔⣶⡦⣤⡤⠄⣀⠀⠀⠀⠀⠀⠀⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠨⡏⠀⠀⠈⠢⣙⢯⣄⠀⢨⠯⡺⡘⢄⠀⠀⠀⠀⠀ @@ -25,21 +25,21 @@ import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠙⠛⠻⠿⠿⠿⢿⣿⣿⣿⣷⣶⣶⣾⣿⣿⣿⣿⠿⠟⠁ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀ interface IBigStepper { - /// @notice Performs a single instruction step from a given prestate and returns the poststate - /// hash. - /// @param _stateData The preimage of the prestate hash. - /// @param _proof A proof for the inclusion of the prestate's memory in the merkle tree. - /// @param _localContext The local key context for the preimage oracle. Optional, can be set as a constant - /// if the caller only requires one set of local keys. - /// @return postState_ The poststate hash after the instruction step. + /// @notice Performs the state transition from a given prestate and returns the hash of the post state witness. + /// @param _stateData The raw opaque prestate data. + /// @param _proof Opaque proof data, can be used to prove things about the prestate in relation to the state of the + /// interface's implementation. + /// @param _localContext The local key context for the preimage oracle. Optional, can be set as a constant if the + /// implementation only requires one set of local keys. + /// @return postState_ The hash of the post state witness after the state transition. function step( bytes calldata _stateData, bytes calldata _proof, - uint256 _localContext + bytes32 _localContext ) external returns (bytes32 postState_); - /// @notice Returns the preimage oracle used by the stepper. + /// @notice Returns the preimage oracle used by the state machine. function oracle() external view returns (IPreimageOracle oracle_); } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IBondManager.sol b/packages/contracts-bedrock/src/dispute/interfaces/IBondManager.sol deleted file mode 100644 index d3cdbe6bf36a..000000000000 --- a/packages/contracts-bedrock/src/dispute/interfaces/IBondManager.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; - -/// @title IBondManager -/// @notice The Bond Manager holds ether posted as a bond for a bond id. -interface IBondManager { - /// @notice BondPosted is emitted when a bond is posted. - /// @param bondId is the id of the bond. - /// @param owner is the address that owns the bond. - /// @param expiration is the time at which the bond expires. - /// @param amount is the amount of the bond. - event BondPosted(bytes32 bondId, address owner, uint256 expiration, uint256 amount); - - /// @notice BondSeized is emitted when a bond is seized. - /// @param bondId is the id of the bond. - /// @param owner is the address that owns the bond. - /// @param seizer is the address that seized the bond. - /// @param amount is the amount of the bond. - event BondSeized(bytes32 bondId, address owner, address seizer, uint256 amount); - - /// @notice BondReclaimed is emitted when a bond is reclaimed by the owner. - /// @param bondId is the id of the bond. - /// @param claiment is the address that reclaimed the bond. - /// @param amount is the amount of the bond. - event BondReclaimed(bytes32 bondId, address claiment, uint256 amount); - - /// @notice Post a bond with a given id and owner. - /// @dev This function will revert if the provided bondId is already in use. - /// @param _bondId is the id of the bond. - /// @param _bondOwner is the address that owns the bond. - /// @param _minClaimHold is the minimum amount of time the owner - /// must wait before reclaiming their bond. - function post(bytes32 _bondId, address _bondOwner, uint128 _minClaimHold) external payable; - - /// @notice Seizes the bond with the given id. - /// @dev This function will revert if there is no bond at the given id. - /// @param _bondId is the id of the bond. - function seize(bytes32 _bondId) external; - - /// @notice Seizes the bond with the given id and distributes it to recipients. - /// @dev This function will revert if there is no bond at the given id. - /// @param _bondId is the id of the bond. - /// @param _claimRecipients is a set of addresses to split the bond amongst. - /// - function seizeAndSplit(bytes32 _bondId, address[] calldata _claimRecipients) external; - - /// @notice Reclaims the bond of the bond owner. - /// @dev This function will revert if there is no bond at the given id. - /// @param _bondId is the id of the bond. - function reclaim(bytes32 _bondId) external; -} diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol b/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol new file mode 100644 index 000000000000..80b90c69b860 --- /dev/null +++ b/packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IWETH } from "src/dispute/interfaces/IWETH.sol"; + +/// @title IDelayedWETH +/// @notice Interface for the DelayedWETH contract. +interface IDelayedWETH is IWETH { + /// @notice Represents a withdrawal request. + struct WithdrawalRequest { + uint256 amount; + uint256 timestamp; + } + + /// @notice Emitted when an unwrap is started. + /// @param src The address that started the unwrap. + /// @param wad The amount of WETH that was unwrapped. + event Unwrap(address indexed src, uint256 wad); + + /// @notice Returns the withdrawal delay in seconds. + /// @return The withdrawal delay in seconds. + function delay() external view returns (uint256); + + /// @notice Returns a withdrawal request for the given address. + /// @param _owner The address to query the withdrawal request of. + /// @param _guy Sub-account to query the withdrawal request of. + /// @return The withdrawal request for the given address-subaccount pair. + function withdrawals(address _owner, address _guy) external view returns (uint256, uint256); + + /// @notice Unlocks withdrawals for the sender's account, after a time delay. + /// @param _guy Sub-account to unlock. + /// @param _wad The amount of WETH to unlock. + function unlock(address _guy, uint256 _wad) external; + + /// @notice Extension to withdrawal, must provide a sub-account to withdraw from. + /// @param _guy Sub-account to withdraw from. + /// @param _wad The amount of WETH to withdraw. + function withdraw(address _guy, uint256 _wad) external; + + /// @notice Allows the owner to recover from error cases by pulling ETH out of the contract. + /// @param _wad The amount of WETH to recover. + function recover(uint256 _wad) external; + + /// @notice Allows the owner to recover from error cases by pulling ETH from a specific owner. + /// @param _guy The address to recover the WETH from. + /// @param _wad The amount of WETH to recover. + function hold(address _guy, uint256 _wad) external; +} diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGame.sol b/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGame.sol index d6c68c12d9cb..c9d18ad96ed4 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGame.sol @@ -1,8 +1,7 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.0; -import { IBondManager } from "./IBondManager.sol"; -import { IInitializable } from "./IInitializable.sol"; +import { IInitializable } from "src/dispute/interfaces/IInitializable.sol"; import "src/libraries/DisputeTypes.sol"; @@ -17,6 +16,10 @@ interface IDisputeGame is IInitializable { /// @return createdAt_ The timestamp that the DisputeGame contract was created at. function createdAt() external view returns (Timestamp createdAt_); + /// @notice Returns the timestamp that the DisputeGame contract was resolved at. + /// @return resolvedAt_ The timestamp that the DisputeGame contract was resolved at. + function resolvedAt() external view returns (Timestamp resolvedAt_); + /// @notice Returns the current status of the game. /// @return status_ The current status of the game. function status() external view returns (GameStatus status_); @@ -37,10 +40,6 @@ interface IDisputeGame is IInitializable { /// @return extraData_ Any extra data supplied to the dispute game contract by the creator. function extraData() external pure returns (bytes memory extraData_); - /// @notice Returns the address of the `BondManager` used. - /// @return bondManager_ The address of the `BondManager` used. - function bondManager() external view returns (IBondManager bondManager_); - /// @notice If all necessary information has been gathered, this function should mark the game /// status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of /// the resolved game. It is at this stage that the bonds should be awarded to the diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol b/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol index 2c164ceec98e..e528057e8add 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.0; import { IDisputeGame } from "./IDisputeGame.sol"; @@ -19,6 +19,20 @@ interface IDisputeGameFactory { /// @param gameType The type of the DisputeGame. event ImplementationSet(address indexed impl, GameType indexed gameType); + /// @notice Emitted when a game type's initialization bond is updated + /// @param gameType The type of the DisputeGame. + /// @param newBond The new bond (in wei) for initializing the game type. + event InitBondUpdated(GameType indexed gameType, uint256 indexed newBond); + + /// @notice Information about a dispute game found in a `findLatestGames` search. + struct GameSearchResult { + uint256 index; + GameId metadata; + Timestamp timestamp; + Claim rootClaim; + bytes extraData; + } + /// @notice The total number of dispute games created by this factory. /// @return gameCount_ The total number of dispute games created by this factory. function gameCount() external view returns (uint256 gameCount_); @@ -60,6 +74,11 @@ interface IDisputeGameFactory { /// Will be cloned on creation of a new dispute game with the given `gameType`. function gameImpls(GameType _gameType) external view returns (IDisputeGame impl_); + /// @notice Returns the required bonds for initializing a dispute game of the given type. + /// @param _gameType The type of the dispute game. + /// @return bond_ The required bond for initializing a dispute game of the given type. + function initBonds(GameType _gameType) external view returns (uint256 bond_); + /// @notice Creates a new DisputeGame proxy contract. /// @param _gameType The type of the DisputeGame - used to decide the proxy implementation. /// @param _rootClaim The root claim of the DisputeGame. @@ -71,6 +90,7 @@ interface IDisputeGameFactory { bytes calldata _extraData ) external + payable returns (IDisputeGame proxy_); /// @notice Sets the implementation contract for a specific `GameType`. @@ -79,6 +99,12 @@ interface IDisputeGameFactory { /// @param _impl The implementation contract for the given `GameType`. function setImplementation(GameType _gameType, IDisputeGame _impl) external; + /// @notice Sets the bond (in wei) for initializing a game type. + /// @dev May only be called by the `owner`. + /// @param _gameType The type of the DisputeGame. + /// @param _initBond The bond (in wei) for initializing a game type. + function setInitBond(GameType _gameType, uint256 _initBond) external; + /// @notice Returns a unique identifier for the given dispute game parameters. /// @dev Hashes the concatenation of `gameType . rootClaim . extraData` /// without expanding memory. @@ -94,4 +120,18 @@ interface IDisputeGameFactory { external pure returns (Hash uuid_); + + /// @notice Finds the `_n` most recent `GameId`'s of type `_gameType` starting at `_start`. If there are less than + /// `_n` games of type `_gameType` starting at `_start`, then the returned array will be shorter than `_n`. + /// @param _gameType The type of game to find. + /// @param _start The index to start the reverse search from. + /// @param _n The number of games to find. + function findLatestGames( + GameType _gameType, + uint256 _start, + uint256 _n + ) + external + view + returns (GameSearchResult[] memory games_); } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol b/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol index 452770de9832..355140ab338b 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.0; import { IDisputeGame } from "./IDisputeGame.sol"; @@ -9,36 +9,16 @@ import "src/libraries/DisputeTypes.sol"; /// @notice The interface for a fault proof backed dispute game. interface IFaultDisputeGame is IDisputeGame { /// @notice The `ClaimData` struct represents the data associated with a Claim. - /// @dev TODO(clabby): Add bond ID information. struct ClaimData { uint32 parentIndex; - bool countered; + address counteredBy; + address claimant; + uint128 bond; Claim claim; Position position; Clock clock; } - /// @notice The `OutputProposal` struct contains information about an output proposal in - /// the `L2OutputOracle` at a given index. - struct OutputProposal { - uint128 index; - uint128 l2BlockNumber; - Hash outputRoot; - } - - /// @notice A container for two consecutive `OutputProposal`s, used to store the starting - /// and disputed output proposals for a given dispute game. The starting output - /// proposal will be used to determine where the off chain agents should begin - /// running their fault proof program, and the disputed output proposal will be - /// fed into the program and treated as disputed state. The program's exit code - /// expresses its opinion on the validity of the state transition from the starting, - /// trusted output proposal to the disputed output proposal, and ultimately resolves - /// the dispute. - struct OutputProposals { - OutputProposal starting; - OutputProposal disputed; - } - /// @notice Emitted when a new claim is added to the DAG by `claimant` /// @param parentIndex The index within the `claimData` array of the parent claim /// @param claim The claim being added @@ -70,10 +50,9 @@ interface IFaultDisputeGame is IDisputeGame { /// @notice Posts the requested local data to the VM's `PreimageOralce`. /// @param _ident The local identifier of the data to post. - /// @param _l2BlockNumber The L2 block number being disputed. This serves as the local context for the - /// `PreimageOracle` key. + /// @param _execLeafIdx The index of the leaf claim in an execution subgame that requires the local data for a step. /// @param _partOffset The offset of the data to post. - function addLocalData(uint256 _ident, uint256 _l2BlockNumber, uint256 _partOffset) external; + function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external; /// @notice Resolves the subgame rooted at the given claim index. /// @dev This function must be called bottom-up in the DAG @@ -83,15 +62,18 @@ interface IFaultDisputeGame is IDisputeGame { /// @param _claimIndex The index of the subgame root claim to resolve. function resolveClaim(uint256 _claimIndex) external payable; - /// @notice An L1 block hash that contains the disputed output root, fetched from the - /// `BlockOracle` and verified by referencing the timestamp associated with the - /// first L2 Output Proposal in the `L2OutputOracle` that contains the disputed - /// L2 block number. + /// @notice A block hash on the L1 that contains the disputed output root. function l1Head() external view returns (Hash l1Head_); /// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`. function l2BlockNumber() external view returns (uint256 l2BlockNumber_); - /// @notice The l1BlockNumber that Cannon was ran from to generate the root claim. - function l1BlockNumber() external view returns (uint256 l1BlockNumber_); + /// @notice Starting output root and block number of the game. + function startingOutputRoot() external view returns (Hash startingRoot_, uint256 l2BlockNumber_); + + /// @notice Only the starting block number of the game. + function startingBlockNumber() external view returns (uint256 startingBlockNumber_); + + /// @notice Only the starting output root of the game. + function startingRootHash() external view returns (Hash startingRootHash_); } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IInitializable.sol b/packages/contracts-bedrock/src/dispute/interfaces/IInitializable.sol index 1609647c1ea8..5968b45f9bfb 100644 --- a/packages/contracts-bedrock/src/dispute/interfaces/IInitializable.sol +++ b/packages/contracts-bedrock/src/dispute/interfaces/IInitializable.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.0; /// @title IInitializable /// @notice An interface for initializable contracts. interface IInitializable { /// @notice Initializes the contract. /// @dev This function may only be called once. - function initialize() external; + function initialize() external payable; } diff --git a/packages/contracts-bedrock/src/dispute/interfaces/IWETH.sol b/packages/contracts-bedrock/src/dispute/interfaces/IWETH.sol new file mode 100644 index 000000000000..0d736ecac73a --- /dev/null +++ b/packages/contracts-bedrock/src/dispute/interfaces/IWETH.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IWETH +/// @notice Interface for WETH9. +interface IWETH { + /// @notice Emitted when an approval is made. + /// @param src The address that approved the transfer. + /// @param guy The address that was approved to transfer. + /// @param wad The amount that was approved to transfer. + event Approval(address indexed src, address indexed guy, uint256 wad); + + /// @notice Emitted when a transfer is made. + /// @param src The address that transferred the WETH. + /// @param dst The address that received the WETH. + /// @param wad The amount of WETH that was transferred. + event Transfer(address indexed src, address indexed dst, uint256 wad); + + /// @notice Emitted when a deposit is made. + /// @param dst The address that deposited the WETH. + /// @param wad The amount of WETH that was deposited. + event Deposit(address indexed dst, uint256 wad); + + /// @notice Emitted when a withdrawal is made. + /// @param src The address that withdrew the WETH. + /// @param wad The amount of WETH that was withdrawn. + event Withdrawal(address indexed src, uint256 wad); + + /// @notice Returns the name of the token. + /// @return The name of the token. + function name() external pure returns (string memory); + + /// @notice Returns the symbol of the token. + /// @return The symbol of the token. + function symbol() external pure returns (string memory); + + /// @notice Returns the number of decimals the token uses. + /// @return The number of decimals the token uses. + function decimals() external pure returns (uint8); + + /// @notice Returns the balance of the given address. + /// @param owner The address to query the balance of. + /// @return The balance of the given address. + function balanceOf(address owner) external view returns (uint256); + + /// @notice Returns the amount of WETH that the spender can transfer on behalf of the owner. + /// @param owner The address that owns the WETH. + /// @param spender The address that is approved to transfer the WETH. + /// @return The amount of WETH that the spender can transfer on behalf of the owner. + function allowance(address owner, address spender) external view returns (uint256); + + /// @notice Allows WETH to be deposited by sending ether to the contract. + function deposit() external payable; + + /// @notice Withdraws an amount of ETH. + /// @param wad The amount of ETH to withdraw. + function withdraw(uint256 wad) external; + + /// @notice Returns the total supply of WETH. + /// @return The total supply of WETH. + function totalSupply() external view returns (uint256); + + /// @notice Approves the given address to transfer the WETH on behalf of the caller. + /// @param guy The address that is approved to transfer the WETH. + /// @param wad The amount that is approved to transfer. + /// @return True if the approval was successful. + function approve(address guy, uint256 wad) external returns (bool); + + /// @notice Transfers the given amount of WETH to the given address. + /// @param dst The address to transfer the WETH to. + /// @param wad The amount of WETH to transfer. + /// @return True if the transfer was successful. + function transfer(address dst, uint256 wad) external returns (bool); + + /// @notice Transfers the given amount of WETH from the given address to the given address. + /// @param src The address to transfer the WETH from. + /// @param dst The address to transfer the WETH to. + /// @param wad The amount of WETH to transfer. + /// @return True if the transfer was successful. + function transferFrom(address src, address dst, uint256 wad) external returns (bool); +} diff --git a/packages/contracts-bedrock/src/dispute/lib/LibClock.sol b/packages/contracts-bedrock/src/dispute/lib/LibClock.sol deleted file mode 100644 index 5ce8348731ec..000000000000 --- a/packages/contracts-bedrock/src/dispute/lib/LibClock.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; - -import "src/libraries/DisputeTypes.sol"; - -/// @title LibClock -/// @notice This library contains helper functions for working with the `Clock` type. -library LibClock { - /// @notice Packs a `Duration` and `Timestamp` into a `Clock` type. - /// @param _duration The `Duration` to pack into the `Clock` type. - /// @param _timestamp The `Timestamp` to pack into the `Clock` type. - /// @return clock_ The `Clock` containing the `_duration` and `_timestamp`. - function wrap(Duration _duration, Timestamp _timestamp) internal pure returns (Clock clock_) { - assembly { - clock_ := or(shl(0x40, _duration), _timestamp) - } - } - - /// @notice Pull the `Duration` out of a `Clock` type. - /// @param _clock The `Clock` type to pull the `Duration` out of. - /// @return duration_ The `Duration` pulled out of `_clock`. - function duration(Clock _clock) internal pure returns (Duration duration_) { - // Shift the high-order 64 bits into the low-order 64 bits, leaving only the `duration`. - assembly { - duration_ := shr(0x40, _clock) - } - } - - /// @notice Pull the `Timestamp` out of a `Clock` type. - /// @param _clock The `Clock` type to pull the `Timestamp` out of. - /// @return timestamp_ The `Timestamp` pulled out of `_clock`. - function timestamp(Clock _clock) internal pure returns (Timestamp timestamp_) { - // Clean the high-order 192 bits by shifting the clock left and then right again, leaving - // only the `timestamp`. - assembly { - timestamp_ := shr(0xC0, shl(0xC0, _clock)) - } - } -} diff --git a/packages/contracts-bedrock/src/dispute/lib/LibGameId.sol b/packages/contracts-bedrock/src/dispute/lib/LibGameId.sol index a96d81e0df73..2a4657b3246e 100644 --- a/packages/contracts-bedrock/src/dispute/lib/LibGameId.sol +++ b/packages/contracts-bedrock/src/dispute/lib/LibGameId.sol @@ -22,7 +22,7 @@ library LibGameId { returns (GameId gameId_) { assembly { - gameId_ := or(or(shl(248, _gameType), shl(184, _timestamp)), _gameProxy) + gameId_ := or(or(shl(224, _gameType), shl(160, _timestamp)), _gameProxy) } } @@ -37,9 +37,9 @@ library LibGameId { returns (GameType gameType_, Timestamp timestamp_, IDisputeGame gameProxy_) { assembly { - gameType_ := shr(248, _gameId) - timestamp_ := shr(184, and(_gameId, not(shl(248, 0xff)))) - gameProxy_ := and(_gameId, 0xffffffffffffffffffffffffffffffffffffffff) + gameType_ := shr(224, _gameId) + timestamp_ := and(shr(160, _gameId), 0xFFFFFFFFFFFFFFFF) + gameProxy_ := and(_gameId, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) } } } diff --git a/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol b/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol index 2fb2609e281f..abf79fb51b06 100644 --- a/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol +++ b/packages/contracts-bedrock/src/dispute/lib/LibPosition.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.15; import "src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeErrors.sol"; /// @title LibPosition /// @notice This library contains helper functions for working with the `Position` type. @@ -136,9 +137,37 @@ library LibPosition { } } + /// @notice Gets the position of the highest ancestor of `_position` that commits to the same + /// trace index, while still being below `_upperBoundExclusive`. + /// @param _position The position to get the highest ancestor of. + /// @param _upperBoundExclusive The exclusive upper depth bound, used to inform where to stop in order + /// to not escape a sub-tree. + /// @return ancestor_ The highest ancestor of `position` that commits to the same trace index. + function traceAncestorBounded( + Position _position, + uint256 _upperBoundExclusive + ) + internal + pure + returns (Position ancestor_) + { + // This function only works for positions that are below the upper bound. + if (_position.depth() <= _upperBoundExclusive) revert ClaimAboveSplit(); + + // Grab the global trace ancestor. + ancestor_ = traceAncestor(_position); + + // If the ancestor is above or at the upper bound, shift it to be below the upper bound. + // This should be a special case that only covers positions that commit to the final leaf + // in a sub-tree. + if (ancestor_.depth() <= _upperBoundExclusive) { + ancestor_ = ancestor_.rightIndex(_upperBoundExclusive + 1); + } + } + /// @notice Get the move position of `_position`, which is the left child of: - /// 1. `_position + 1` if `_isAttack` is true. - /// 1. `_position` if `_isAttack` is false. + /// 1. `_position` if `_isAttack` is true. + /// 2. `_position | 1` if `_isAttack` is false. /// @param _position The position to get the relative attack/defense position of. /// @param _isAttack Whether or not the move is an attack move. /// @return move_ The move position relative to `position`. @@ -147,4 +176,13 @@ library LibPosition { move_ := shl(1, or(iszero(_isAttack), _position)) } } + + /// @notice Get the value of a `Position` type in the form of the underlying uint128. + /// @param _position The position to get the value of. + /// @return raw_ The value of the `position` as a uint128 type. + function raw(Position _position) internal pure returns (uint128 raw_) { + assembly { + raw_ := _position + } + } } diff --git a/packages/contracts-bedrock/src/dispute/lib/LibUDT.sol b/packages/contracts-bedrock/src/dispute/lib/LibUDT.sol new file mode 100644 index 000000000000..1ea8e33565c5 --- /dev/null +++ b/packages/contracts-bedrock/src/dispute/lib/LibUDT.sol @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import "src/libraries/DisputeTypes.sol"; + +/// @title LibClock +/// @notice This library contains helper functions for working with the `Clock` type. +library LibClock { + /// @notice Packs a `Duration` and `Timestamp` into a `Clock` type. + /// @param _duration The `Duration` to pack into the `Clock` type. + /// @param _timestamp The `Timestamp` to pack into the `Clock` type. + /// @return clock_ The `Clock` containing the `_duration` and `_timestamp`. + function wrap(Duration _duration, Timestamp _timestamp) internal pure returns (Clock clock_) { + assembly { + clock_ := or(shl(0x40, _duration), _timestamp) + } + } + + /// @notice Pull the `Duration` out of a `Clock` type. + /// @param _clock The `Clock` type to pull the `Duration` out of. + /// @return duration_ The `Duration` pulled out of `_clock`. + function duration(Clock _clock) internal pure returns (Duration duration_) { + // Shift the high-order 64 bits into the low-order 64 bits, leaving only the `duration`. + assembly { + duration_ := shr(0x40, _clock) + } + } + + /// @notice Pull the `Timestamp` out of a `Clock` type. + /// @param _clock The `Clock` type to pull the `Timestamp` out of. + /// @return timestamp_ The `Timestamp` pulled out of `_clock`. + function timestamp(Clock _clock) internal pure returns (Timestamp timestamp_) { + // Clean the high-order 192 bits by shifting the clock left and then right again, leaving + // only the `timestamp`. + assembly { + timestamp_ := shr(0xC0, shl(0xC0, _clock)) + } + } + + /// @notice Get the value of a `Clock` type in the form of the underlying uint128. + /// @param _clock The `Clock` type to get the value of. + /// @return clock_ The value of the `Clock` type as a uint128 type. + function raw(Clock _clock) internal pure returns (uint128 clock_) { + assembly { + clock_ := _clock + } + } +} + +/// @title LibClaim +/// @notice This library contains helper functions for working with the `Claim` type. +library LibClaim { + /// @notice Get the value of a `Claim` type in the form of the underlying bytes32. + /// @param _claim The `Claim` type to get the value of. + /// @return claim_ The value of the `Claim` type as a bytes32 type. + function raw(Claim _claim) internal pure returns (bytes32 claim_) { + assembly { + claim_ := _claim + } + } +} + +/// @title LibDuration +/// @notice This library contains helper functions for working with the `Duration` type. +library LibDuration { + /// @notice Get the value of a `Duration` type in the form of the underlying uint64. + /// @param _duration The `Duration` type to get the value of. + /// @return duration_ The value of the `Duration` type as a uint64 type. + function raw(Duration _duration) internal pure returns (uint64 duration_) { + assembly { + duration_ := _duration + } + } +} + +/// @title LibHash +/// @notice This library contains helper functions for working with the `Hash` type. +library LibHash { + /// @notice Get the value of a `Hash` type in the form of the underlying bytes32. + /// @param _hash The `Hash` type to get the value of. + /// @return hash_ The value of the `Hash` type as a bytes32 type. + function raw(Hash _hash) internal pure returns (bytes32 hash_) { + assembly { + hash_ := _hash + } + } +} + +/// @title LibTimestamp +/// @notice This library contains helper functions for working with the `Timestamp` type. +library LibTimestamp { + /// @notice Get the value of a `Timestamp` type in the form of the underlying uint64. + /// @param _timestamp The `Timestamp` type to get the value of. + /// @return timestamp_ The value of the `Timestamp` type as a uint64 type. + function raw(Timestamp _timestamp) internal pure returns (uint64 timestamp_) { + assembly { + timestamp_ := _timestamp + } + } +} + +/// @title LibVMStatus +/// @notice This library contains helper functions for working with the `VMStatus` type. +library LibVMStatus { + /// @notice Get the value of a `VMStatus` type in the form of the underlying uint8. + /// @param _vmstatus The `VMStatus` type to get the value of. + /// @return vmstatus_ The value of the `VMStatus` type as a uint8 type. + function raw(VMStatus _vmstatus) internal pure returns (uint8 vmstatus_) { + assembly { + vmstatus_ := _vmstatus + } + } +} + +/// @title LibGameType +/// @notice This library contains helper functions for working with the `GameType` type. +library LibGameType { + /// @notice Get the value of a `GameType` type in the form of the underlying uint8. + /// @param _gametype The `GameType` type to get the value of. + /// @return gametype_ The value of the `GameType` type as a uint8 type. + function raw(GameType _gametype) internal pure returns (uint8 gametype_) { + assembly { + gametype_ := _gametype + } + } +} diff --git a/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol b/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol new file mode 100644 index 000000000000..7a3d5bb6dece --- /dev/null +++ b/packages/contracts-bedrock/src/dispute/weth/DelayedWETH.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import { ISemver } from "src/universal/ISemver.sol"; + +import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; +import { IWETH } from "src/dispute/interfaces/IWETH.sol"; +import { WETH98 } from "src/dispute/weth/WETH98.sol"; + +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; + +/// @title DelayedWETH +/// @notice DelayedWETH is an extension to WETH9 that allows for delayed withdrawals. Accounts must trigger an unlock +/// function before they can withdraw WETH. Accounts must trigger unlock by specifying a sub-account and an +/// amount of WETH to unlock. Accounts can trigger the unlock function at any time, but must wait a delay +/// period before they can withdraw after the unlock function is triggered. DelayedWETH is designed to be used +/// by the DisputeGame contracts where unlock will only be triggered after a dispute is resolved. DelayedWETH +/// is meant to sit behind a proxy contract and has an owner address that can pull WETH from any account and +/// can recover ETH from the contract itself. Variable and function naming vaguely follows the vibe of WETH9. +/// Not the prettiest contract in the world, but it gets the job done. +contract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver { + /// @notice Semantic version. + /// @custom:semver 0.2.0 + string public constant version = "0.2.0"; + + /// @inheritdoc IDelayedWETH + mapping(address => mapping(address => WithdrawalRequest)) public withdrawals; + + /// @notice Withdrawal delay in seconds. + uint256 internal immutable DELAY_SECONDS; + + /// @notice Address of the SuperchainConfig contract. + SuperchainConfig public config; + + /// @param _delay The delay for withdrawals in seconds. + constructor(uint256 _delay) { + DELAY_SECONDS = _delay; + initialize({ _owner: address(0), _config: SuperchainConfig(address(0)) }); + } + + /// @notice Initializes the contract. + /// @param _owner The address of the owner. + /// @param _config Address of the SuperchainConfig contract. + function initialize(address _owner, SuperchainConfig _config) public initializer { + __Ownable_init(); + _transferOwnership(_owner); + config = _config; + } + + /// @inheritdoc IDelayedWETH + function delay() external view returns (uint256) { + return DELAY_SECONDS; + } + + /// @inheritdoc IDelayedWETH + function unlock(address _guy, uint256 _wad) external { + // Note that the unlock function can be called by any address, but the actual unlocking capability still only + // gives the msg.sender the ability to withdraw from the account. As long as the unlock and withdraw functions + // are called with the proper recipient addresses, this will be safe. Could be made safer by having external + // accounts execute withdrawals themselves but that would have added extra complexity and made DelayedWETH a + // leaky abstraction, so we chose this instead. + WithdrawalRequest storage wd = withdrawals[msg.sender][_guy]; + wd.timestamp = block.timestamp; + wd.amount += _wad; + } + + /// @inheritdoc IWETH + function withdraw(uint256 _wad) public override(WETH98, IWETH) { + withdraw(msg.sender, _wad); + } + + /// @inheritdoc IDelayedWETH + function withdraw(address _guy, uint256 _wad) public { + require(!config.paused(), "DelayedWETH: contract is paused"); + WithdrawalRequest storage wd = withdrawals[msg.sender][_guy]; + require(wd.amount >= _wad, "DelayedWETH: insufficient unlocked withdrawal"); + require(wd.timestamp > 0, "DelayedWETH: withdrawal not unlocked"); + require(wd.timestamp + DELAY_SECONDS <= block.timestamp, "DelayedWETH: withdrawal delay not met"); + wd.amount -= _wad; + super.withdraw(_wad); + } + + /// @inheritdoc IDelayedWETH + function recover(uint256 _wad) external { + require(msg.sender == owner(), "DelayedWETH: not owner"); + uint256 amount = _wad < address(this).balance ? _wad : address(this).balance; + payable(msg.sender).transfer(amount); + } + + /// @inheritdoc IDelayedWETH + function hold(address _guy, uint256 _wad) external { + require(msg.sender == owner(), "DelayedWETH: not owner"); + allowance[_guy][msg.sender] = _wad; + emit Approval(_guy, msg.sender, _wad); + } +} diff --git a/packages/contracts-bedrock/src/dispute/weth/WETH98.sol b/packages/contracts-bedrock/src/dispute/weth/WETH98.sol new file mode 100644 index 000000000000..c52291e0982b --- /dev/null +++ b/packages/contracts-bedrock/src/dispute/weth/WETH98.sol @@ -0,0 +1,85 @@ +// Copyright (C) 2015, 2016, 2017 Dapphub + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// Based on WETH9 by Dapphub. +// Modified by OP Labs. + +pragma solidity 0.8.15; + +import { IWETH } from "src/dispute/interfaces/IWETH.sol"; + +/// @title WETH98 +/// @notice WETH98 is a version of WETH9 upgraded for Solidity 0.8.x. +contract WETH98 is IWETH { + string public constant name = "Wrapped Ether"; + string public constant symbol = "WETH"; + uint8 public constant decimals = 18; + + mapping(address => uint256) public balanceOf; + mapping(address => mapping(address => uint256)) public allowance; + + /// @notice Pipes to deposit. + receive() external payable { + deposit(); + } + + /// @inheritdoc IWETH + function deposit() public payable { + balanceOf[msg.sender] += msg.value; + emit Deposit(msg.sender, msg.value); + } + + /// @inheritdoc IWETH + function withdraw(uint256 wad) public virtual { + require(balanceOf[msg.sender] >= wad); + balanceOf[msg.sender] -= wad; + payable(msg.sender).transfer(wad); + emit Withdrawal(msg.sender, wad); + } + + /// @inheritdoc IWETH + function totalSupply() external view returns (uint256) { + return address(this).balance; + } + + /// @inheritdoc IWETH + function approve(address guy, uint256 wad) external returns (bool) { + allowance[msg.sender][guy] = wad; + emit Approval(msg.sender, guy, wad); + return true; + } + + /// @inheritdoc IWETH + function transfer(address dst, uint256 wad) external returns (bool) { + return transferFrom(msg.sender, dst, wad); + } + + /// @inheritdoc IWETH + function transferFrom(address src, address dst, uint256 wad) public returns (bool) { + require(balanceOf[src] >= wad); + + if (src != msg.sender && allowance[src][msg.sender] != type(uint256).max) { + require(allowance[src][msg.sender] >= wad); + allowance[src][msg.sender] -= wad; + } + + balanceOf[src] -= wad; + balanceOf[dst] += wad; + + emit Transfer(src, dst, wad); + + return true; + } +} diff --git a/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol b/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol index a82ddaa5806e..8bd2e2a8f315 100644 --- a/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol +++ b/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol @@ -28,7 +28,6 @@ contract L1BlockNumber is ISemver { } /// @notice Returns the L1 block number. - // solhint-disable-next-line no-complex-fallback fallback() external payable { uint256 l1BlockNumber = getL1BlockNumber(); assembly { diff --git a/packages/contracts-bedrock/src/legacy/LegacyERC20ETH.sol b/packages/contracts-bedrock/src/legacy/LegacyERC20ETH.sol deleted file mode 100644 index 9f6545774d3c..000000000000 --- a/packages/contracts-bedrock/src/legacy/LegacyERC20ETH.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; - -/// @custom:legacy -/// @custom:proxied -/// @custom:predeploy 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000 -/// @title LegacyERC20ETH -/// @notice LegacyERC20ETH is a legacy contract that held ETH balances before the Bedrock upgrade. -/// All ETH balances held within this contract were migrated to the state trie as part of -/// the Bedrock upgrade. Functions within this contract that mutate state were already -/// disabled as part of the EVM equivalence upgrade. -contract LegacyERC20ETH is OptimismMintableERC20 { - /// @notice Initializes the contract as an Optimism Mintable ERC20. - constructor() OptimismMintableERC20(Predeploys.L2_STANDARD_BRIDGE, address(0), "Ether", "ETH", 18) { } - - /// @notice Returns the ETH balance of the target account. Overrides the base behavior of the - /// contract to preserve the invariant that the balance within this contract always - /// matches the balance in the state trie. - /// @param _who Address of the account to query. - /// @return The ETH balance of the target account. - function balanceOf(address _who) public view virtual override returns (uint256) { - return address(_who).balance; - } - - /// @custom:blocked - /// @notice Mints some amount of ETH. - function mint(address, uint256) public virtual override { - revert("LegacyERC20ETH: mint is disabled"); - } - - /// @custom:blocked - /// @notice Burns some amount of ETH. - function burn(address, uint256) public virtual override { - revert("LegacyERC20ETH: burn is disabled"); - } - - /// @custom:blocked - /// @notice Transfers some amount of ETH. - function transfer(address, uint256) public virtual override returns (bool) { - revert("LegacyERC20ETH: transfer is disabled"); - } - - /// @custom:blocked - /// @notice Approves a spender to spend some amount of ETH. - function approve(address, uint256) public virtual override returns (bool) { - revert("LegacyERC20ETH: approve is disabled"); - } - - /// @custom:blocked - /// @notice Transfers funds from some sender account. - function transferFrom(address, address, uint256) public virtual override returns (bool) { - revert("LegacyERC20ETH: transferFrom is disabled"); - } - - /// @custom:blocked - /// @notice Increases the allowance of a spender. - function increaseAllowance(address, uint256) public virtual override returns (bool) { - revert("LegacyERC20ETH: increaseAllowance is disabled"); - } - - /// @custom:blocked - /// @notice Decreases the allowance of a spender. - function decreaseAllowance(address, uint256) public virtual override returns (bool) { - revert("LegacyERC20ETH: decreaseAllowance is disabled"); - } -} diff --git a/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol b/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol index e668c74ffa5e..c735339a6bb8 100644 --- a/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol +++ b/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol @@ -30,7 +30,6 @@ contract ResolvedDelegateProxy { } /// @notice Fallback, performs a delegatecall to the resolved implementation address. - // solhint-disable-next-line no-complex-fallback fallback() external payable { address target = addressManager[address(this)].getAddress((implementationName[address(this)])); diff --git a/packages/contracts-bedrock/src/libraries/Arithmetic.sol b/packages/contracts-bedrock/src/libraries/Arithmetic.sol index 7ff52848740b..dfd47274f7f9 100644 --- a/packages/contracts-bedrock/src/libraries/Arithmetic.sol +++ b/packages/contracts-bedrock/src/libraries/Arithmetic.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity ^0.8.0; import { SignedMath } from "@openzeppelin/contracts/utils/math/SignedMath.sol"; import { FixedPointMathLib } from "@rari-capital/solmate/src/utils/FixedPointMathLib.sol"; diff --git a/packages/contracts-bedrock/src/libraries/Constants.sol b/packages/contracts-bedrock/src/libraries/Constants.sol index b34fdf15439f..933250d1ecda 100644 --- a/packages/contracts-bedrock/src/libraries/Constants.sol +++ b/packages/contracts-bedrock/src/libraries/Constants.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { ResourceMetering } from "../L1/ResourceMetering.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; /// @title Constants /// @notice Constants is a library for storing constants. Simple! Don't put everything in here, just @@ -43,8 +43,4 @@ library Constants { }); return config; } - - /// @notice The `reinitailizer` input for upgradable contracts. This value must be updated - /// each time that the contracts are deployed. - uint8 internal constant INITIALIZER = 3; } diff --git a/packages/contracts-bedrock/src/libraries/DisputeErrors.sol b/packages/contracts-bedrock/src/libraries/DisputeErrors.sol index 919fce0cad88..382c05c43af9 100644 --- a/packages/contracts-bedrock/src/libraries/DisputeErrors.sol +++ b/packages/contracts-bedrock/src/libraries/DisputeErrors.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; -import "./DisputeTypes.sol"; +import "src/libraries/DisputeTypes.sol"; //////////////////////////////////////////////////////////////// // `DisputeGameFactory` Errors // @@ -24,9 +24,20 @@ error UnexpectedRootClaim(Claim rootClaim); // `FaultDisputeGame` Errors // //////////////////////////////////////////////////////////////// -/// @notice Thrown when a supplied bond is too low to cover the -/// cost of the next possible counter claim. -error BondTooLow(); +/// @notice Thrown when a dispute game has already been initialized. +error AlreadyInitialized(); + +/// @notice Thrown when a supplied bond is too low to cover the cost of the interaction. +error InsufficientBond(); + +/// @notice Thrown when a credit claim is attempted for a value of 0. +error NoCreditToClaim(); + +/// @notice Thrown when the transfer of credit to a recipient account reverts. +error BondTransferFailed(); + +/// @notice Thrown when the `extraData` passed to the CWIA proxy is too long for the `FaultDisputeGame`. +error ExtraDataTooLong(); /// @notice Thrown when a defense against the root claim is attempted. error CannotDefendRootClaim(); @@ -72,32 +83,24 @@ error OutOfOrderResolution(); /// @notice Thrown when resolving a claim that has already been resolved. error ClaimAlreadyResolved(); -//////////////////////////////////////////////////////////////// -// `AttestationDisputeGame` Errors // -//////////////////////////////////////////////////////////////// - -/// @notice Thrown when an invalid signature is submitted to `challenge`. -error InvalidSignature(); +/// @notice Thrown when a parent output root is attempted to be found on a claim that is in +/// the output root portion of the tree. +error ClaimAboveSplit(); -/// @notice Thrown when a signature that has already been used to support the -/// `rootClaim` is submitted to `challenge`. -error AlreadyChallenged(); +/// @notice Thrown on deployment if the split depth is greater than or equal to the max +/// depth of the game. +error InvalidSplitDepth(); -//////////////////////////////////////////////////////////////// -// `Ownable` Errors // -//////////////////////////////////////////////////////////////// +/// @notice Thrown when trying to step against a claim for a second time, after it has already been countered with +/// an instruction step. +error DuplicateStep(); -/// @notice Thrown when a function that is protected by the `onlyOwner` modifier -/// is called from an account other than the owner. -error NotOwner(); +/// @notice Thrown when an anchor root is not found for a given game type. +error AnchorRootNotFound(); //////////////////////////////////////////////////////////////// -// `BlockOracle` Errors // +// `PermissionedDisputeGame` Errors // //////////////////////////////////////////////////////////////// -/// @notice Thrown when a block that is out of the range of the `BLOCKHASH` opcode -/// is attempted to be loaded. -error BlockNumberOOB(); - -/// @notice Thrown when a block hash is attempted to be loaded that has not been stored. -error BlockHashNotPresent(); +/// @notice Thrown when an unauthorized address attempts to interact with the game. +error BadAuth(); diff --git a/packages/contracts-bedrock/src/libraries/DisputeTypes.sol b/packages/contracts-bedrock/src/libraries/DisputeTypes.sol index 84a7966f206a..2480812049c5 100644 --- a/packages/contracts-bedrock/src/libraries/DisputeTypes.sol +++ b/packages/contracts-bedrock/src/libraries/DisputeTypes.sol @@ -1,15 +1,29 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; -import { LibHashing } from "../dispute/lib/LibHashing.sol"; -import { LibPosition } from "../dispute/lib/LibPosition.sol"; -import { LibClock } from "../dispute/lib/LibClock.sol"; -import { LibGameId } from "../dispute/lib/LibGameId.sol"; - +import { LibHashing } from "src/dispute/lib/LibHashing.sol"; +import { + LibClaim, + LibHash, + LibDuration, + LibClock, + LibTimestamp, + LibVMStatus, + LibGameType +} from "src/dispute/lib/LibUDT.sol"; +import { LibPosition } from "src/dispute/lib/LibPosition.sol"; +import { LibGameId } from "src/dispute/lib/LibGameId.sol"; + +using LibClaim for Claim global; using LibHashing for Claim global; +using LibHash for Hash global; using LibPosition for Position global; +using LibDuration for Duration global; using LibClock for Clock global; using LibGameId for GameId global; +using LibTimestamp for Timestamp global; +using LibVMStatus for VMStatus global; +using LibGameType for GameType global; /// @notice A custom type for a generic hash. type Hash is bytes32; @@ -60,15 +74,14 @@ type Clock is uint128; type Position is uint128; /// @notice A `GameType` represents the type of game being played. -type GameType is uint8; +type GameType is uint32; /// @notice A `VMStatus` represents the status of a VM execution. type VMStatus is uint8; /// @notice The current status of the dispute game. -enum GameStatus -// The game is currently in progress, and has not been resolved. -{ +enum GameStatus { + // The game is currently in progress, and has not been resolved. IN_PROGRESS, // The game has concluded, and the `rootClaim` was challenged successfully. CHALLENGER_WINS, @@ -76,30 +89,59 @@ enum GameStatus DEFENDER_WINS } +/// @notice Represents an L2 output root and the L2 block number at which it was generated. +/// @custom:field root The output root. +/// @custom:field l2BlockNumber The L2 block number at which the output root was generated. +struct OutputRoot { + Hash root; + uint256 l2BlockNumber; +} + /// @title GameTypes /// @notice A library that defines the IDs of games that can be played. library GameTypes { - /// @dev The game will use a `IDisputeGame` implementation that utilizes fault proofs. - GameType internal constant FAULT = GameType.wrap(0); + /// @dev A dispute game type the uses the cannon vm. + GameType internal constant CANNON = GameType.wrap(0); - /// @dev The game will use a `IDisputeGame` implementation that utilizes validity proofs. - GameType internal constant VALIDITY = GameType.wrap(1); + /// @dev A permissioned dispute game type the uses the cannon vm. + GameType internal constant PERMISSIONED_CANNON = GameType.wrap(1); - /// @dev The game will use a `IDisputeGame` implementation that utilizes attestation proofs. - GameType internal constant ATTESTATION = GameType.wrap(2); + /// @notice A dispute game type that uses an alphabet vm. + /// Not intended for production use. + GameType internal constant ALPHABET = GameType.wrap(255); } /// @title VMStatuses +/// @notice Named type aliases for the various valid VM status bytes. library VMStatuses { - /// @dev The VM has executed successfully and the outcome is valid. + /// @notice The VM has executed successfully and the outcome is valid. VMStatus internal constant VALID = VMStatus.wrap(0); - /// @dev The VM has executed successfully and the outcome is invalid. + /// @notice The VM has executed successfully and the outcome is invalid. VMStatus internal constant INVALID = VMStatus.wrap(1); - /// @dev The VM has paniced. + /// @notice The VM has paniced. VMStatus internal constant PANIC = VMStatus.wrap(2); - /// @dev The VM execution is still in progress. + /// @notice The VM execution is still in progress. VMStatus internal constant UNFINISHED = VMStatus.wrap(3); } + +/// @title LocalPreimageKey +/// @notice Named type aliases for local `PreimageOracle` key identifiers. +library LocalPreimageKey { + /// @notice The identifier for the L1 head hash. + uint256 internal constant L1_HEAD_HASH = 0x01; + + /// @notice The identifier for the starting output root. + uint256 internal constant STARTING_OUTPUT_ROOT = 0x02; + + /// @notice The identifier for the disputed output root. + uint256 internal constant DISPUTED_OUTPUT_ROOT = 0x03; + + /// @notice The identifier for the disputed L2 block number. + uint256 internal constant DISPUTED_L2_BLOCK_NUMBER = 0x04; + + /// @notice The identifier for the chain ID. + uint256 internal constant CHAIN_ID = 0x05; +} diff --git a/packages/contracts-bedrock/src/libraries/Encoding.sol b/packages/contracts-bedrock/src/libraries/Encoding.sol index 0177ddc65c24..f53d7c59d288 100644 --- a/packages/contracts-bedrock/src/libraries/Encoding.sol +++ b/packages/contracts-bedrock/src/libraries/Encoding.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { Types } from "./Types.sol"; -import { Hashing } from "./Hashing.sol"; -import { RLPWriter } from "./rlp/RLPWriter.sol"; +import { Types } from "src/libraries/Types.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { RLPWriter } from "src/libraries/rlp/RLPWriter.sol"; /// @title Encoding /// @notice Encoding handles Optimism's various different encoding schemes. @@ -133,4 +133,44 @@ library Encoding { } return (nonce, version); } + + /// @notice Returns an appropriately encoded call to L1Block.setL1BlockValuesEcotone + /// @param baseFeeScalar L1 base fee Scalar + /// @param blobBaseFeeScalar L1 blob base fee Scalar + /// @param sequenceNumber Number of L2 blocks since epoch start. + /// @param timestamp L1 timestamp. + /// @param number L1 blocknumber. + /// @param baseFee L1 base fee. + /// @param blobBaseFee L1 blob base fee. + /// @param hash L1 blockhash. + /// @param batcherHash Versioned hash to authenticate batcher by. + function encodeSetL1BlockValuesEcotone( + uint32 baseFeeScalar, + uint32 blobBaseFeeScalar, + uint64 sequenceNumber, + uint64 timestamp, + uint64 number, + uint256 baseFee, + uint256 blobBaseFee, + bytes32 hash, + bytes32 batcherHash + ) + internal + pure + returns (bytes memory) + { + bytes4 functionSignature = bytes4(keccak256("setL1BlockValuesEcotone()")); + return abi.encodePacked( + functionSignature, + baseFeeScalar, + blobBaseFeeScalar, + sequenceNumber, + timestamp, + number, + baseFee, + blobBaseFee, + hash, + batcherHash + ); + } } diff --git a/packages/contracts-bedrock/src/libraries/Hashing.sol b/packages/contracts-bedrock/src/libraries/Hashing.sol index 3133bd36ba01..7546daede7c5 100644 --- a/packages/contracts-bedrock/src/libraries/Hashing.sol +++ b/packages/contracts-bedrock/src/libraries/Hashing.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { Types } from "./Types.sol"; -import { Encoding } from "./Encoding.sol"; +import { Types } from "src/libraries/Types.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; /// @title Hashing /// @notice Hashing handles Optimism's various different hashing schemes. diff --git a/packages/contracts-bedrock/src/libraries/Predeploys.sol b/packages/contracts-bedrock/src/libraries/Predeploys.sol index c52bc3651f23..e06566481933 100644 --- a/packages/contracts-bedrock/src/libraries/Predeploys.sol +++ b/packages/contracts-bedrock/src/libraries/Predeploys.sol @@ -41,6 +41,9 @@ library Predeploys { /// @notice Address of the DeployerWhitelist predeploy. No longer active. address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002; + /// @notice Address of the canonical WETH9 contract. + address internal constant WETH9 = 0x4200000000000000000000000000000000000006; + /// @custom:legacy /// @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the /// state trie as of the Bedrock upgrade. Contract has been locked and write functions @@ -74,4 +77,37 @@ library Predeploys { /// @notice Address of the EAS predeploy. address internal constant EAS = 0x4200000000000000000000000000000000000021; + + /// @notice Address of the MultiCall3 predeploy. + address internal constant MultiCall3 = 0xcA11bde05977b3631167028862bE2a173976CA11; + + /// @notice Address of the Create2Deployer predeploy. + address internal constant Create2Deployer = 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2; + + /// @notice Address of the Safe_v130 predeploy. + address internal constant Safe_v130 = 0x69f4D1788e39c87893C980c06EdF4b7f686e2938; + + /// @notice Address of the SafeL2_v130 predeploy. + address internal constant SafeL2_v130 = 0xfb1bffC9d739B8D520DaF37dF666da4C687191EA; + + /// @notice Address of the MultiSendCallOnly_v130 predeploy. + address internal constant MultiSendCallOnly_v130 = 0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B; + + /// @notice Address of the SafeSingletonFactory predeploy. + address internal constant SafeSingletonFactory = 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7; + + /// @notice Address of the DeterministicDeploymentProxy predeploy. + address internal constant DeterministicDeploymentProxy = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + + /// @notice Address of the MultiSend_v130 predeploy. + address internal constant MultiSend_v130 = 0x998739BFdAAdde7C933B942a68053933098f9EDa; + + /// @notice Address of the Permit2 predeploy. + address internal constant Permit2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3; + + /// @notice Address of the SenderCreator predeploy. + address internal constant SenderCreator = 0x7fc98430eAEdbb6070B35B39D798725049088348; + + /// @notice Address of the EntryPoint predeploy. + address internal constant EntryPoint = 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789; } diff --git a/packages/contracts-bedrock/src/libraries/Storage.sol b/packages/contracts-bedrock/src/libraries/Storage.sol index dc59bea9b973..93aa260f9b7a 100644 --- a/packages/contracts-bedrock/src/libraries/Storage.sol +++ b/packages/contracts-bedrock/src/libraries/Storage.sol @@ -58,7 +58,7 @@ library Storage { /// @notice Stores a bytes32 value in an arbitrary storage slot, `_slot`. /// @param _slot The storage slot to store the address in. - /// @param _value The protocol version to store + /// @param _value The bytes32 value to store. /// @dev WARNING! This function must be used cautiously, as it allows for overwriting values /// in arbitrary storage slots. function setBytes32(bytes32 _slot, bytes32 _value) internal { @@ -66,4 +66,23 @@ library Storage { sstore(_slot, _value) } } + + /// @notice Stores a bool value in an arbitrary storage slot, `_slot`. + /// @param _slot The storage slot to store the bool in. + /// @param _value The bool value to store + /// @dev WARNING! This function must be used cautiously, as it allows for overwriting values + /// in arbitrary storage slots. + function setBool(bytes32 _slot, bool _value) internal { + assembly { + sstore(_slot, _value) + } + } + + /// @notice Returns a bool stored in an arbitrary storage slot. + /// @param _slot The storage slot to retrieve the bool from. + function getBool(bytes32 _slot) internal view returns (bool value_) { + assembly { + value_ := sload(_slot) + } + } } diff --git a/packages/contracts-bedrock/src/libraries/rlp/RLPReader.sol b/packages/contracts-bedrock/src/libraries/rlp/RLPReader.sol index 34d446f7d5c2..179c8f4c7624 100644 --- a/packages/contracts-bedrock/src/libraries/rlp/RLPReader.sol +++ b/packages/contracts-bedrock/src/libraries/rlp/RLPReader.sol @@ -248,7 +248,6 @@ library RLPReader { } // Mostly based on Solidity's copy_memory_to_memory: - // solhint-disable max-line-length // https://github.com/ethereum/solidity/blob/34dd30d71b4da730488be72ff6af7083cf2a91f6/libsolidity/codegen/YulUtilFunctions.cpp#L102-L114 uint256 src = MemoryPointer.unwrap(_src) + _offset; assembly { diff --git a/packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckBalanceHigh.sol b/packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckBalanceHigh.sol deleted file mode 100644 index b531c93acb44..000000000000 --- a/packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckBalanceHigh.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { IDripCheck } from "../IDripCheck.sol"; - -/// @title CheckBalanceHigh -/// @notice DripCheck for checking if an account's balance is above a given threshold. -contract CheckBalanceHigh is IDripCheck { - struct Params { - address target; - uint256 threshold; - } - - /// @notice External event used to help client-side tooling encode parameters. - /// @param params Parameters to encode. - event _EventToExposeStructInABI__Params(Params params); - - /// @inheritdoc IDripCheck - function check(bytes memory _params) external view returns (bool execute_) { - Params memory params = abi.decode(_params, (Params)); - - // Check target balance is above threshold. - execute_ = params.target.balance > params.threshold; - } -} diff --git a/packages/contracts-bedrock/src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol b/packages/contracts-bedrock/src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol index d162b5b2b4ec..115810d9d139 100644 --- a/packages/contracts-bedrock/src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol +++ b/packages/contracts-bedrock/src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol @@ -14,7 +14,7 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 { address public immutable ADMIN; /// @notice EIP712 typehash for the Proof type. - bytes32 public constant PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)"); + bytes32 public immutable PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)"); /// @notice Struct that represents a proof that verifies the admin. /// @custom:field recipient Address that will be receiving the faucet funds. diff --git a/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol b/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol index c36beb497f72..b9af730a71d4 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Semver } from "../../universal/Semver.sol"; +import { ISemver } from "src/universal/ISemver.sol"; /// @title AttestationStation /// @author Optimism Collective /// @author Gitcoin /// @notice Where attestations live. -contract AttestationStation is Semver { +contract AttestationStation is ISemver { /// @notice Struct representing data that is being attested. /// @custom:field about Address for which the attestation is about. /// @custom:field key A bytes32 key for the attestation. @@ -28,8 +28,9 @@ contract AttestationStation is Semver { /// @param val Value of the attestation. event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val); - /// @custom:semver 1.1.2 - constructor() Semver(1, 1, 2) { } + /// @notice Semantic version. + /// @custom:semver 1.2.0 + string public constant version = "1.2.0"; /// @notice Allows anyone to create an attestation. /// @param _about Address that the attestation is about. diff --git a/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol b/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol index 9fef8007b01c..74d04b087d86 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol @@ -1,18 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Semver } from "../../universal/Semver.sol"; +import { ISemver } from "src/universal/ISemver.sol"; import { ERC721BurnableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; -import { AttestationStation } from "./AttestationStation.sol"; -import { OptimistAllowlist } from "./OptimistAllowlist.sol"; +import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; +import { OptimistAllowlist } from "src/periphery/op-nft/OptimistAllowlist.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; /// @author Optimism Collective /// @author Gitcoin /// @title Optimist /// @notice A Soul Bound Token for real humans only(tm). -contract Optimist is ERC721BurnableUpgradeable, Semver { +contract Optimist is ERC721BurnableUpgradeable, ISemver { /// @notice Attestation key used by the attestor to attest the baseURI. bytes32 public constant BASE_URI_ATTESTATION_KEY = bytes32("optimist.base-uri"); @@ -25,7 +25,10 @@ contract Optimist is ERC721BurnableUpgradeable, Semver { /// @notice Address of the OptimistAllowlist contract. OptimistAllowlist public immutable OPTIMIST_ALLOWLIST; - /// @custom:semver 2.0.2 + /// @notice Semantic version. + /// @custom:semver 2.1.0 + string public constant version = "2.1.0"; + /// @param _name Token name. /// @param _symbol Token symbol. /// @param _baseURIAttestor Address of the baseURI attestor. @@ -37,9 +40,7 @@ contract Optimist is ERC721BurnableUpgradeable, Semver { address _baseURIAttestor, AttestationStation _attestationStation, OptimistAllowlist _optimistAllowlist - ) - Semver(2, 0, 2) - { + ) { BASE_URI_ATTESTOR = _baseURIAttestor; ATTESTATION_STATION = _attestationStation; OPTIMIST_ALLOWLIST = _optimistAllowlist; diff --git a/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol b/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol index ad576261bed6..b8212a37c674 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Semver } from "../../universal/Semver.sol"; -import { AttestationStation } from "./AttestationStation.sol"; -import { OptimistConstants } from "./libraries/OptimistConstants.sol"; +import { ISemver } from "src/universal/ISemver.sol"; +import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; +import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; /// @title OptimistAllowlist /// @notice Source of truth for whether an address is able to mint an Optimist NFT. /// isAllowedToMint function checks various signals to return boolean value /// for whether an address is eligible or not. -contract OptimistAllowlist is Semver { +contract OptimistAllowlist is ISemver { /// @notice Attestation key used by the AllowlistAttestor to manually add addresses to the /// allowlist. bytes32 public constant OPTIMIST_CAN_MINT_ATTESTATION_KEY = bytes32("optimist.can-mint"); @@ -30,7 +30,10 @@ contract OptimistAllowlist is Semver { /// attestations. address public immutable OPTIMIST_INVITER; - /// @custom:semver 1.0.2 + /// @notice Semantic version. + /// @custom:semver 1.1.0 + string public constant version = "1.1.0"; + /// @param _attestationStation Address of the AttestationStation contract. /// @param _allowlistAttestor Address of the allowlist attestor. /// @param _coinbaseQuestAttestor Address of the Coinbase Quest attestor. @@ -40,9 +43,7 @@ contract OptimistAllowlist is Semver { address _allowlistAttestor, address _coinbaseQuestAttestor, address _optimistInviter - ) - Semver(1, 0, 2) - { + ) { ATTESTATION_STATION = _attestationStation; ALLOWLIST_ATTESTOR = _allowlistAttestor; COINBASE_QUEST_ATTESTOR = _coinbaseQuestAttestor; diff --git a/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol b/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol index 805a2a648cf7..222405d77c33 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { OptimistConstants } from "./libraries/OptimistConstants.sol"; -import { Semver } from "../../universal/Semver.sol"; -import { AttestationStation } from "./AttestationStation.sol"; +import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; +import { ISemver } from "src/universal/ISemver.sol"; +import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; import { EIP712Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol"; @@ -32,7 +32,7 @@ import { EIP712Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/cry /// 6) claimer waits for the MIN_COMMITMENT_PERIOD to pass. /// 7) claimer reveals the plaintext ClaimableInvite and the signature using the /// claimInvite function, receiving the "optimist.can-mint-from-invite" attestation -contract OptimistInviter is Semver, EIP712Upgradeable { +contract OptimistInviter is ISemver, EIP712Upgradeable { /// @notice Emitted when an invite is claimed. /// @param issuer Address that issued the signature. /// @param claimer Address that claimed the invite. @@ -87,10 +87,13 @@ contract OptimistInviter is Semver, EIP712Upgradeable { /// @notice Maps from addresses to number of invites they have. mapping(address => uint256) public inviteCounts; - /// @custom:semver 1.0.2 + /// @notice Semantic version. + /// @custom:semver 1.1.0 + string public constant version = "1.1.0"; + /// @param _inviteGranter Address of the invite granter. /// @param _attestationStation Address of the AttestationStation contract. - constructor(address _inviteGranter, AttestationStation _attestationStation) Semver(1, 0, 2) { + constructor(address _inviteGranter, AttestationStation _attestationStation) { INVITE_GRANTER = _inviteGranter; ATTESTATION_STATION = _attestationStation; } diff --git a/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol b/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol index 6243266bb31c..b5048d5c7bcc 100644 --- a/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol @@ -114,9 +114,6 @@ abstract contract CrossDomainMessenger is /// call in `relayMessage`. uint64 public constant RELAY_GAS_CHECK_BUFFER = 5_000; - /// @notice Address of the paired CrossDomainMessenger contract on the other chain. - address public immutable OTHER_MESSENGER; - /// @notice Mapping of message hashes to boolean receipt values. Note that a message will only /// be present in this mapping if it has successfully been relayed on this chain, and /// can therefore not be relayed again. @@ -138,10 +135,14 @@ abstract contract CrossDomainMessenger is /// successfully executed on the first attempt. mapping(bytes32 => bool) public failedMessages; + /// @notice CrossDomainMessenger contract on the other chain. + /// @custom:network-specific + CrossDomainMessenger public otherMessenger; + /// @notice Reserve extra slots in the storage layout for future upgrades. - /// A gap size of 41 was chosen here, so that the first slot used in a child contract - /// would be a multiple of 50. - uint256[42] private __gap; + /// A gap size of 43 was chosen here, so that the first slot used in a child contract + /// would be 1 plus a multiple of 50. + uint256[43] private __gap; /// @notice Emitted whenever a message is sent to the other chain. /// @param target Address of the recipient of the message. @@ -165,11 +166,6 @@ abstract contract CrossDomainMessenger is /// @param msgHash Hash of the message that failed to be relayed. event FailedRelayedMessage(bytes32 indexed msgHash); - /// @param _otherMessenger Address of the messenger on the paired chain. - constructor(address _otherMessenger) { - OTHER_MESSENGER = _otherMessenger; - } - /// @notice Sends a message to some target address on the other chain. Note that if the call /// always reverts, then the message will be unrelayable, and any ETH sent will be /// permanently locked. The same will occur if the target on the other chain is @@ -182,14 +178,14 @@ abstract contract CrossDomainMessenger is // message is the amount of gas requested by the user PLUS the base gas value. We want to // guarantee the property that the call to the target contract will always have at least // the minimum gas limit specified by the user. - _sendMessage( - OTHER_MESSENGER, - baseGas(_message, _minGasLimit), - msg.value, - abi.encodeWithSelector( + _sendMessage({ + _to: address(otherMessenger), + _gasLimit: baseGas(_message, _minGasLimit), + _value: msg.value, + _data: abi.encodeWithSelector( this.relayMessage.selector, messageNonce(), msg.sender, _target, msg.value, _minGasLimit, _message - ) - ); + ) + }); emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit); emit SentMessageExtension1(msg.sender, msg.value); @@ -219,6 +215,10 @@ abstract contract CrossDomainMessenger is external payable { + // On L1 this function will check the Portal for its paused status. + // On L2 this function should be a no-op, because paused will always return false. + require(paused() == false, "CrossDomainMessenger: paused"); + (, uint16 version) = Encoding.decodeVersionedNonce(_nonce); require(version < 2, "CrossDomainMessenger: only version 0 or 1 messages are supported at this time"); @@ -284,6 +284,9 @@ abstract contract CrossDomainMessenger is xDomainMsgSender = Constants.DEFAULT_L2_SENDER; if (success) { + // This check is identical to one above, but it ensures that the same message cannot be relayed + // twice, and adds a layer of protection against rentrancy. + assert(successfulMessages[versionedHash] == false); successfulMessages[versionedHash] = true; emit RelayedMessage(versionedHash); } else { @@ -313,6 +316,14 @@ abstract contract CrossDomainMessenger is return xDomainMsgSender; } + /// @notice Retrieves the address of the paired CrossDomainMessenger contract on the other chain + /// Public getter is legacy and will be removed in the future. Use `otherMessenger()` instead. + /// @return CrossDomainMessenger contract on the other chain. + /// @custom:legacy + function OTHER_MESSENGER() public view returns (CrossDomainMessenger) { + return otherMessenger; + } + /// @notice Retrieves the next message nonce. Message version will be added to the upper two /// bytes of the message nonce. Message version allows us to treat messages as having /// different structures. @@ -348,9 +359,16 @@ abstract contract CrossDomainMessenger is } /// @notice Initializer. - // solhint-disable-next-line func-name-mixedcase - function __CrossDomainMessenger_init() internal onlyInitializing { - xDomainMsgSender = Constants.DEFAULT_L2_SENDER; + /// @param _otherMessenger CrossDomainMessenger contract on the other chain. + function __CrossDomainMessenger_init(CrossDomainMessenger _otherMessenger) internal onlyInitializing { + // We only want to set the xDomainMsgSender to the default value if it hasn't been initialized yet, + // meaning that this is a fresh contract deployment. + // This prevents resetting the xDomainMsgSender to the default value during an upgrade, which would enable + // a reentrant withdrawal to sandwhich the upgrade replay a withdrawal twice. + if (xDomainMsgSender == address(0)) { + xDomainMsgSender = Constants.DEFAULT_L2_SENDER; + } + otherMessenger = _otherMessenger; } /// @notice Sends a low-level message to the other messenger. Needs to be implemented by child @@ -376,4 +394,12 @@ abstract contract CrossDomainMessenger is /// @param _target Address of the contract to check. /// @return Whether or not the address is an unsafe system address. function _isUnsafeTarget(address _target) internal view virtual returns (bool); + + /// @notice This function should return true if the contract is paused. + /// On L1 this function will check the SuperchainConfig for its paused status. + /// On L2 this function should be a no-op. + /// @return Whether or not the contract is paused. + function paused() public view virtual returns (bool) { + return false; + } } diff --git a/packages/contracts-bedrock/src/universal/ERC721Bridge.sol b/packages/contracts-bedrock/src/universal/ERC721Bridge.sol index 9c50cb6f41ac..d62c612fca1a 100644 --- a/packages/contracts-bedrock/src/universal/ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/universal/ERC721Bridge.sol @@ -2,22 +2,28 @@ pragma solidity 0.8.15; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; /// @title ERC721Bridge /// @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges. abstract contract ERC721Bridge is Initializable { + /// @custom:spacer ERC721Bridge's initializer slot spacing + /// @notice Spacer to avoid packing into the initializer slot + bytes30 private spacer_0_2_30; + /// @notice Messenger contract on this domain. /// @custom:network-specific CrossDomainMessenger public messenger; - /// @notice Address of the bridge on the other network. - /// @custom:legacy - address public immutable OTHER_BRIDGE; + /// @notice Contract of the bridge on the other network. + /// @custom:network-specific + StandardBridge public otherBridge; /// @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades. - uint256[48] private __gap; + uint256[46] private __gap; /// @notice Emitted when an ERC721 bridge to the other network is initiated. /// @param localToken Address of the token on this domain. @@ -54,34 +60,48 @@ abstract contract ERC721Bridge is Initializable { /// @notice Ensures that the caller is a cross-chain message from the other bridge. modifier onlyOtherBridge() { require( - msg.sender == address(messenger) && messenger.xDomainMessageSender() == OTHER_BRIDGE, + msg.sender == address(messenger) && messenger.xDomainMessageSender() == address(otherBridge), "ERC721Bridge: function can only be called from the other bridge" ); _; } - /// @notice Constructs the contract. - /// @param _otherBridge Address of the ERC721 bridge on the other network. - constructor(address _otherBridge) { - require(_otherBridge != address(0), "ERC721Bridge: other bridge cannot be address(0)"); - OTHER_BRIDGE = _otherBridge; - } - - // @notice Initializes the contract. - /// @param _messenger Address of the CrossDomainMessenger on this network. - function __ERC721Bridge_init(CrossDomainMessenger _messenger) internal onlyInitializing { + /// @notice Initializer. + /// @param _messenger Contract of the CrossDomainMessenger on this network. + /// @param _otherBridge Contract of the ERC721 bridge on the other network. + function __ERC721Bridge_init( + CrossDomainMessenger _messenger, + StandardBridge _otherBridge + ) + internal + onlyInitializing + { messenger = _messenger; + otherBridge = _otherBridge; } - /// @notice Getter for messenger contract. + /// @notice Legacy getter for messenger contract. + /// Public getter is legacy and will be removed in the future. Use `messenger` instead. + /// @return Messenger contract on this domain. + /// @custom:legacy function MESSENGER() external view returns (CrossDomainMessenger) { return messenger; } - /// @notice Getter for other bridge address. - /// @return Address of the bridge on the other network. - function otherBridge() external view returns (address) { - return OTHER_BRIDGE; + /// @notice Legacy getter for other bridge address. + /// Public getter is legacy and will be removed in the future. Use `otherBridge` instead. + /// @return Contract of the bridge on the other network. + /// @custom:legacy + function OTHER_BRIDGE() external view returns (StandardBridge) { + return otherBridge; + } + + /// @notice This function should return true if the contract is paused. + /// On L1 this function will check the SuperchainConfig for its paused status. + /// On L2 this function should be a no-op. + /// @return Whether or not the contract is paused. + function paused() public view virtual returns (bool) { + return false; } /// @notice Initiates a bridge of an NFT to the caller's account on the other chain. Note that diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol index f00474043fa0..43ddd65424f8 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; -import { Semver } from "src/universal/Semver.sol"; +import { ISemver } from "src/universal/ISemver.sol"; /// @title OptimismMintableERC20 /// @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed @@ -12,7 +12,7 @@ import { Semver } from "src/universal/Semver.sol"; /// use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa. /// Designed to be backwards compatible with the older StandardL2ERC20 token which was only /// meant for use on L2. -contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, Semver { +contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, ISemver { /// @notice Address of the corresponding version of this token on the remote chain. address public immutable REMOTE_TOKEN; @@ -38,7 +38,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, _; } - /// @custom:semver 1.2.1 + /// @notice Semantic version. + /// @custom:semver 1.3.0 + string public constant version = "1.3.0"; + /// @param _bridge Address of the L2 standard bridge. /// @param _remoteToken Address of the corresponding L1 token. /// @param _name ERC20 name. @@ -51,7 +54,6 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, uint8 _decimals ) ERC20(_name, _symbol) - Semver(1, 2, 1) { REMOTE_TOKEN = _remoteToken; BRIDGE = _bridge; diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol index b7f86dbadaab..6e7baf31f1fb 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol @@ -2,9 +2,8 @@ pragma solidity 0.8.15; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { ISemver } from "src/universal/ISemver.sol"; -import { Constants } from "src/libraries/Constants.sol"; +import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; /// @custom:proxied /// @custom:predeployed 0x4200000000000000000000000000000000000012 @@ -14,10 +13,19 @@ import { Constants } from "src/libraries/Constants.sol"; /// who may be less familiar with deploying smart contracts. Designed to be backwards /// compatible with the older StandardL2ERC20Factory contract. contract OptimismMintableERC20Factory is ISemver, Initializable { + /// @custom:spacer OptimismMintableERC20Factory's initializer slot spacing + /// @notice Spacer to avoid packing into the initializer slot + bytes30 private spacer_0_2_30; + /// @notice Address of the StandardBridge on this chain. /// @custom:network-specific address public bridge; + /// @notice Reserve extra slots in the storage layout for future upgrades. + /// A gap size of 49 was chosen here, so that the first slot used in a child contract + /// would be 1 plus a multiple of 50. + uint256[49] private __gap; + /// @custom:legacy /// @notice Emitted whenever a new OptimismMintableERC20 is created. Legacy version of the newer /// OptimismMintableERC20Created event. We recommend relying on that event instead. @@ -31,25 +39,27 @@ contract OptimismMintableERC20Factory is ISemver, Initializable { /// @param deployer Address of the account that deployed the token. event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); - /// @notice Semantic version. - /// @custom:semver 1.6.1 - string public constant version = "1.6.1"; - /// @notice The semver MUST be bumped any time that there is a change in /// the OptimismMintableERC20 token contract since this contract /// is responsible for deploying OptimismMintableERC20 contracts. + /// @notice Semantic version. + /// @custom:semver 1.9.0 + string public constant version = "1.9.0"; + + /// @notice Constructs the OptimismMintableERC20Factory contract. constructor() { initialize({ _bridge: address(0) }); } - /// @notice Initializer. + /// @notice Initializes the contract. /// @param _bridge Address of the StandardBridge on this chain. - function initialize(address _bridge) public reinitializer(Constants.INITIALIZER) { + function initialize(address _bridge) public initializer { bridge = _bridge; } - /// @notice Returns the address of the StandardBridge on this chain. - /// This is a legacy getter, use `bridge` instead. + /// @notice Getter function for the address of the StandardBridge on this chain. + /// Public getter is legacy and will be removed in the future. Use `bridge` instead. + /// @return Address of the StandardBridge on this chain. /// @custom:legacy function BRIDGE() external view returns (address) { return bridge; @@ -108,7 +118,7 @@ contract OptimismMintableERC20Factory is ISemver, Initializable { bytes32 salt = keccak256(abi.encode(_remoteToken, _name, _symbol, _decimals)); address localToken = - address(new OptimismMintableERC20{salt: salt}(bridge, _remoteToken, _name, _symbol, _decimals)); + address(new OptimismMintableERC20{ salt: salt }(bridge, _remoteToken, _name, _symbol, _decimals)); // Emit the old event too for legacy support. emit StandardL2TokenCreated(_remoteToken, localToken); diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol index b75f3d90b6a4..9d9cd62c48d6 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol @@ -52,7 +52,7 @@ contract OptimismMintableERC721Factory is ISemver { bytes32 salt = keccak256(abi.encode(_remoteToken, _name, _symbol)); address localToken = - address(new OptimismMintableERC721{salt: salt}(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)); + address(new OptimismMintableERC721{ salt: salt }(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol)); isOptimismMintableERC721[localToken] = true; emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender); diff --git a/packages/contracts-bedrock/src/universal/Proxy.sol b/packages/contracts-bedrock/src/universal/Proxy.sol index 0325a61d3aab..b50b08efca83 100644 --- a/packages/contracts-bedrock/src/universal/Proxy.sol +++ b/packages/contracts-bedrock/src/universal/Proxy.sol @@ -35,7 +35,7 @@ contract Proxy { /// @notice Sets the initial admin during contract deployment. Admin address is stored at the /// EIP-1967 admin storage slot so that accidental storage collision with the /// implementation is not possible. - /// @param _admin Address of the initial contract admin. Admin as the ability to access the + /// @param _admin Address of the initial contract admin. Admin has the ability to access the /// transparent proxy interface. constructor(address _admin) { _changeAdmin(_admin); diff --git a/packages/contracts-bedrock/src/universal/Semver.sol b/packages/contracts-bedrock/src/universal/Semver.sol deleted file mode 100644 index 5f81053a776a..000000000000 --- a/packages/contracts-bedrock/src/universal/Semver.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; - -/// @title Semver -/// @notice Semver is a simple contract for managing contract versions. -contract Semver { - /// @notice Contract version number (major). - uint256 private immutable MAJOR_VERSION; - - /// @notice Contract version number (minor). - uint256 private immutable MINOR_VERSION; - - /// @notice Contract version number (patch). - uint256 private immutable PATCH_VERSION; - - /// @param _major Version number (major). - /// @param _minor Version number (minor). - /// @param _patch Version number (patch). - constructor(uint256 _major, uint256 _minor, uint256 _patch) { - MAJOR_VERSION = _major; - MINOR_VERSION = _minor; - PATCH_VERSION = _patch; - } - - /// @notice Returns the full semver contract version. - /// @return Semver contract version as a string. - function version() public view returns (string memory) { - return string( - abi.encodePacked( - Strings.toString(MAJOR_VERSION), - ".", - Strings.toString(MINOR_VERSION), - ".", - Strings.toString(PATCH_VERSION) - ) - ); - } -} diff --git a/packages/contracts-bedrock/src/universal/StandardBridge.sol b/packages/contracts-bedrock/src/universal/StandardBridge.sol index 665d75ee4cbe..2c2c8c241b0b 100644 --- a/packages/contracts-bedrock/src/universal/StandardBridge.sol +++ b/packages/contracts-bedrock/src/universal/StandardBridge.sol @@ -22,20 +22,10 @@ abstract contract StandardBridge is Initializable { /// @notice The L2 gas limit set when eth is depoisited using the receive() function. uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000; - /// @notice Corresponding bridge on the other domain. This public getter is deprecated - /// and will be removed in the future. Please use `otherBridge` instead. - /// This can safely be an immutable because for the L1StandardBridge, it will - /// be set to the L2StandardBridge address, which is the same for all OP Stack - /// chains. For the L2StandardBridge, there are not multiple proxies using the - /// same implementation. - /// @custom:legacy - /// @custom:network-specific - StandardBridge public immutable OTHER_BRIDGE; - /// @custom:legacy /// @custom:spacer messenger /// @notice Spacer for backwards compatibility. - address private spacer_0_2_20; + bytes30 private spacer_0_2_30; /// @custom:legacy /// @custom:spacer l2TokenBridge @@ -45,15 +35,18 @@ abstract contract StandardBridge is Initializable { /// @notice Mapping that stores deposits for a given pair of local and remote tokens. mapping(address => mapping(address => uint256)) public deposits; - /// @notice Messenger contract on this domain. This public getter is deprecated - /// and will be removed in the future. Please use `messenger` instead. + /// @notice Messenger contract on this domain. /// @custom:network-specific CrossDomainMessenger public messenger; + /// @notice Corresponding bridge on the other domain. + /// @custom:network-specific + StandardBridge public otherBridge; + /// @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades. - /// A gap size of 46 was chosen here, so that the first slot used in a child contract + /// A gap size of 45 was chosen here, so that the first slot used in a child contract /// would be a multiple of 50. - uint256[46] private __gap; + uint256[45] private __gap; /// @notice Emitted when an ETH bridge is initiated to the other chain. /// @param from Address of the sender. @@ -112,22 +105,24 @@ abstract contract StandardBridge is Initializable { /// @notice Ensures that the caller is a cross-chain message from the other bridge. modifier onlyOtherBridge() { require( - msg.sender == address(messenger) && messenger.xDomainMessageSender() == address(OTHER_BRIDGE), + msg.sender == address(messenger) && messenger.xDomainMessageSender() == address(otherBridge), "StandardBridge: function can only be called from the other bridge" ); _; } - /// @param _otherBridge Address of the other StandardBridge contract. - constructor(StandardBridge _otherBridge) { - OTHER_BRIDGE = _otherBridge; - } - /// @notice Initializer. - /// @param _messenger Address of CrossDomainMessenger on this network. - // solhint-disable-next-line func-name-mixedcase - function __StandardBridge_init(CrossDomainMessenger _messenger) internal onlyInitializing { + /// @param _messenger Contract for CrossDomainMessenger on this network. + /// @param _otherBridge Contract for the other StandardBridge contract. + function __StandardBridge_init( + CrossDomainMessenger _messenger, + StandardBridge _otherBridge + ) + internal + onlyInitializing + { messenger = _messenger; + otherBridge = _otherBridge; } /// @notice Allows EOAs to bridge ETH by sending directly to the bridge. @@ -135,15 +130,27 @@ abstract contract StandardBridge is Initializable { receive() external payable virtual; /// @notice Getter for messenger contract. + /// Public getter is legacy and will be removed in the future. Use `messenger` instead. + /// @return Contract of the messenger on this domain. /// @custom:legacy - /// @return Messenger contract on this domain. function MESSENGER() external view returns (CrossDomainMessenger) { return messenger; } - /// @notice Getter for the remote domain bridge contract. - function otherBridge() external view returns (StandardBridge) { - return OTHER_BRIDGE; + /// @notice Getter for the other bridge contract. + /// Public getter is legacy and will be removed in the future. Use `otherBridge` instead. + /// @return Contract of the bridge on the other network. + /// @custom:legacy + function OTHER_BRIDGE() external view returns (StandardBridge) { + return otherBridge; + } + + /// @notice This function should return true if the contract is paused. + /// On L1 this function will check the SuperchainConfig for its paused status. + /// On L2 this function should be a no-op. + /// @return Whether or not the contract is paused. + function paused() public view virtual returns (bool) { + return false; } /// @notice Sends ETH to the sender's address on the other chain. @@ -240,6 +247,7 @@ abstract contract StandardBridge is Initializable { payable onlyOtherBridge { + require(paused() == false, "StandardBridge: paused"); require(msg.value == _amount, "StandardBridge: amount sent does not match amount required"); require(_to != address(this), "StandardBridge: cannot send to self"); require(_to != address(messenger), "StandardBridge: cannot send to messenger"); @@ -273,6 +281,7 @@ abstract contract StandardBridge is Initializable { public onlyOtherBridge { + require(paused() == false, "StandardBridge: paused"); if (_isOptimismMintableERC20(_localToken)) { require( _isCorrectTokenPair(_localToken, _remoteToken), @@ -313,11 +322,11 @@ abstract contract StandardBridge is Initializable { // contracts may override this function in order to emit legacy events as well. _emitETHBridgeInitiated(_from, _to, _amount, _extraData); - messenger.sendMessage{ value: _amount }( - address(OTHER_BRIDGE), - abi.encodeWithSelector(this.finalizeBridgeETH.selector, _from, _to, _amount, _extraData), - _minGasLimit - ); + messenger.sendMessage{ value: _amount }({ + _target: address(otherBridge), + _message: abi.encodeWithSelector(this.finalizeBridgeETH.selector, _from, _to, _amount, _extraData), + _minGasLimit: _minGasLimit + }); } /// @notice Sends ERC20 tokens to a receiver's address on the other chain. @@ -356,9 +365,9 @@ abstract contract StandardBridge is Initializable { // contracts may override this function in order to emit legacy events as well. _emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData); - messenger.sendMessage( - address(OTHER_BRIDGE), - abi.encodeWithSelector( + messenger.sendMessage({ + _target: address(otherBridge), + _message: abi.encodeWithSelector( this.finalizeBridgeERC20.selector, // Because this call will be executed on the remote chain, we reverse the order of // the remote and local token addresses relative to their order in the @@ -369,9 +378,9 @@ abstract contract StandardBridge is Initializable { _to, _amount, _extraData - ), - _minGasLimit - ); + ), + _minGasLimit: _minGasLimit + }); } /// @notice Checks if a given address is an OptimismMintableERC20. Not perfect, but good enough. diff --git a/packages/contracts-bedrock/src/universal/StorageSetter.sol b/packages/contracts-bedrock/src/universal/StorageSetter.sol index dcf07dba451a..53b8ab2affd5 100644 --- a/packages/contracts-bedrock/src/universal/StorageSetter.sol +++ b/packages/contracts-bedrock/src/universal/StorageSetter.sol @@ -9,9 +9,15 @@ import { Storage } from "src/libraries/Storage.sol"; /// WARNING: this contract is not safe to be called by untrusted parties. /// It is only meant as an intermediate step during upgrades. contract StorageSetter is ISemver { + /// @notice Represents a storage slot key value pair. + struct Slot { + bytes32 key; + bytes32 value; + } + /// @notice Semantic version. - /// @custom:semver 1.0.0 - string public constant version = "1.0.0"; + /// @custom:semver 1.2.0 + string public constant version = "1.2.0"; /// @notice Stores a bytes32 `_value` at `_slot`. Any storage slots that /// are packed should be set through this interface. @@ -19,9 +25,17 @@ contract StorageSetter is ISemver { Storage.setBytes32(_slot, _value); } + /// @notice Stores a bytes32 value at each key in `_slots`. + function setBytes32(Slot[] calldata slots) public { + uint256 length = slots.length; + for (uint256 i; i < length; i++) { + Storage.setBytes32(slots[i].key, slots[i].value); + } + } + /// @notice Retrieves a bytes32 value from `_slot`. - function getBytes32(bytes32 _slot) external view returns (bytes32) { - return Storage.getBytes32(_slot); + function getBytes32(bytes32 _slot) external view returns (bytes32 value_) { + value_ = Storage.getBytes32(_slot); } /// @notice Stores a uint256 `_value` at `_slot`. @@ -30,8 +44,8 @@ contract StorageSetter is ISemver { } /// @notice Retrieves a uint256 value from `_slot`. - function getUint(bytes32 _slot) external view returns (uint256) { - return Storage.getUint(_slot); + function getUint(bytes32 _slot) external view returns (uint256 value_) { + value_ = Storage.getUint(_slot); } /// @notice Stores an address `_value` at `_slot`. @@ -40,7 +54,17 @@ contract StorageSetter is ISemver { } /// @notice Retrieves an address value from `_slot`. - function getAddress(bytes32 _slot) external view returns (address) { - return Storage.getAddress(_slot); + function getAddress(bytes32 _slot) external view returns (address addr_) { + addr_ = Storage.getAddress(_slot); + } + + /// @notice Stores a bool `_value` at `_slot`. + function setBool(bytes32 _slot, bool _value) public { + Storage.setBool(_slot, _value); + } + + /// @notice Retrieves a bool value from `_slot`. + function getBool(bytes32 _slot) external view returns (bool value_) { + value_ = Storage.getBool(_slot); } } diff --git a/packages/contracts-bedrock/test/BenchmarkTest.t.sol b/packages/contracts-bedrock/test/BenchmarkTest.t.sol index 780162b66b0d..4722107a314f 100644 --- a/packages/contracts-bedrock/test/BenchmarkTest.t.sol +++ b/packages/contracts-bedrock/test/BenchmarkTest.t.sol @@ -4,19 +4,21 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; -import "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { Types } from "src/libraries/Types.sol"; // Free function for setting the prevBaseFee param in the OptimismPortal. function setPrevBaseFee(Vm _vm, address _op, uint128 _prevBaseFee) { _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee)); } -contract SetPrevBaseFee_Test is Portal_Initializer { +contract SetPrevBaseFee_Test is CommonTest { function test_setPrevBaseFee_succeeds() external { - setPrevBaseFee(vm, address(op), 100 gwei); - (uint128 prevBaseFee,, uint64 prevBlockNum) = op.params(); + setPrevBaseFee(vm, address(optimismPortal), 100 gwei); + (uint128 prevBaseFee,, uint64 prevBlockNum) = optimismPortal.params(); assertEq(uint256(prevBaseFee), 100 gwei); assertEq(uint256(prevBlockNum), block.number); } @@ -27,7 +29,7 @@ contract SetPrevBaseFee_Test is Portal_Initializer { // so that they are nothing more than the call we want measure the gas cost of. // In order to achieve this we make no assertions, and handle everything else in the setUp() // function. -contract GasBenchMark_OptimismPortal is Portal_Initializer { +contract GasBenchMark_OptimismPortal is CommonTest { // Reusable default values for a test withdrawal Types.WithdrawalTransaction _defaultTx; @@ -61,61 +63,64 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer { messagePasserStorageRoot: _storageRoot, latestBlockhash: bytes32(uint256(0)) }); - _proposedBlockNumber = oracle.nextBlockNumber(); - _proposedOutputIndex = oracle.nextOutputIndex(); + _proposedBlockNumber = l2OutputOracle.nextBlockNumber(); + _proposedOutputIndex = l2OutputOracle.nextOutputIndex(); } // Get the system into a nice ready-to-use state. function setUp() public virtual override { // Configure the oracle to return the output root we've prepared. - vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1); - vm.prank(oracle.PROPOSER()); - oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); + vm.warp(l2OutputOracle.computeL2Timestamp(_proposedBlockNumber) + 1); + vm.prank(l2OutputOracle.PROPOSER()); + l2OutputOracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); // Warp beyond the finalization period for the block we've proposed. - vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp( + l2OutputOracle.getL2Output(_proposedOutputIndex).timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + + 1 + ); // Fund the portal so that we can withdraw ETH. - vm.deal(address(op), 0xFFFFFFFF); + vm.deal(address(optimismPortal), 0xFFFFFFFF); } function test_depositTransaction_benchmark() external { - op.depositTransaction{ value: NON_ZERO_VALUE }( - NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA + optimismPortal.depositTransaction{ value: 100 }( + address(1), 0, 50000, false, hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000" ); } function test_depositTransaction_benchmark_1() external { - setPrevBaseFee(vm, address(op), 1 gwei); - op.depositTransaction{ value: NON_ZERO_VALUE }( - NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA + setPrevBaseFee(vm, address(optimismPortal), 1 gwei); + optimismPortal.depositTransaction{ value: 100 }( + address(1), 0, 50000, false, hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000" ); } function test_proveWithdrawalTransaction_benchmark() external { - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); } } -contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer { +contract GasBenchMark_L1CrossDomainMessenger is Bridge_Initializer { function test_sendMessage_benchmark_0() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 1 gwei); + setPrevBaseFee(vm, address(optimismPortal), 1 gwei); // The amount of data typically sent during a bridge deposit. bytes memory data = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; vm.resumeGasMetering(); - L1Messenger.sendMessage(bob, data, uint32(100)); + l1CrossDomainMessenger.sendMessage(bob, data, uint32(100)); } function test_sendMessage_benchmark_1() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 10 gwei); + setPrevBaseFee(vm, address(optimismPortal), 10 gwei); // The amount of data typically sent during a bridge deposit. bytes memory data = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; vm.resumeGasMetering(); - L1Messenger.sendMessage(bob, data, uint32(100)); + l1CrossDomainMessenger.sendMessage(bob, data, uint32(100)); } } @@ -124,28 +129,28 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer { super.setUp(); deal(address(L1Token), alice, 100000, true); vm.startPrank(alice, alice); - L1Token.approve(address(L1Bridge), type(uint256).max); + L1Token.approve(address(l1StandardBridge), type(uint256).max); } function test_depositETH_benchmark_0() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 1 gwei); + setPrevBaseFee(vm, address(optimismPortal), 1 gwei); vm.resumeGasMetering(); - L1Bridge.depositETH{ value: 500 }(50000, hex""); + l1StandardBridge.depositETH{ value: 500 }(50000, hex""); } function test_depositETH_benchmark_1() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 10 gwei); + setPrevBaseFee(vm, address(optimismPortal), 10 gwei); vm.resumeGasMetering(); - L1Bridge.depositETH{ value: 500 }(50000, hex""); + l1StandardBridge.depositETH{ value: 500 }(50000, hex""); } function test_depositERC20_benchmark_0() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 1 gwei); + setPrevBaseFee(vm, address(optimismPortal), 1 gwei); vm.resumeGasMetering(); - L1Bridge.bridgeERC20({ + l1StandardBridge.bridgeERC20({ _localToken: address(L1Token), _remoteToken: address(L2Token), _amount: 100, @@ -156,9 +161,9 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer { function test_depositERC20_benchmark_1() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 10 gwei); + setPrevBaseFee(vm, address(optimismPortal), 10 gwei); vm.resumeGasMetering(); - L1Bridge.bridgeERC20({ + l1StandardBridge.bridgeERC20({ _localToken: address(L1Token), _remoteToken: address(L2Token), _amount: 100, @@ -171,35 +176,36 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer { contract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer { function setUp() public virtual override { super.setUp(); - deal(address(L1Token), address(L1Bridge), 100, true); + deal(address(L1Token), address(l1StandardBridge), 100, true); vm.mockCall( - address(L1Bridge.messenger()), + address(l1StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); - vm.startPrank(address(L1Bridge.messenger())); - vm.deal(address(L1Bridge.messenger()), 100); + vm.startPrank(address(l1StandardBridge.messenger())); + vm.deal(address(l1StandardBridge.messenger()), 100); } function test_finalizeETHWithdrawal_benchmark() external { // TODO: Make this more accurate. It is underestimating the cost because it pranks // the call coming from the messenger, which bypasses the portal // and oracle. - L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex""); + l1StandardBridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex""); } } -contract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer { +contract GasBenchMark_L2OutputOracle is CommonTest { uint256 nextBlockNumber; function setUp() public override { super.setUp(); - nextBlockNumber = oracle.nextBlockNumber(); + nextBlockNumber = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber); + address proposer = deploy.cfg().l2OutputOracleProposer(); vm.startPrank(proposer); } function test_proposeL2Output_benchmark() external { - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); } } diff --git a/packages/contracts-bedrock/test/BlockOracle.t.sol b/packages/contracts-bedrock/test/BlockOracle.t.sol deleted file mode 100644 index c0e0aadcaea6..000000000000 --- a/packages/contracts-bedrock/test/BlockOracle.t.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { Test } from "forge-std/Test.sol"; -import { BlockOracle } from "src/dispute/BlockOracle.sol"; -import "src/libraries/DisputeTypes.sol"; -import "src/libraries/DisputeErrors.sol"; - -contract BlockOracle_Test is Test { - BlockOracle oracle; - - /// @notice Emitted when a block is checkpointed. - event Checkpoint(uint256 indexed blockNumber, Hash indexed blockHash, Timestamp indexed childTimestamp); - - function setUp() public { - oracle = new BlockOracle(); - // Roll the chain forward 1 block. - vm.roll(block.number + 1); - vm.warp(block.timestamp + 13); - } - - /// @notice Tests that checkpointing a block and loading its information succeeds. - function test_checkpointAndLoad_succeeds() public { - vm.expectEmit(true, true, true, false); - emit Checkpoint( - block.number - 1, Hash.wrap(blockhash(block.number - 1)), Timestamp.wrap(uint64(block.timestamp)) - ); - oracle.checkpoint(); - uint256 blockNumber = block.number - 1; - BlockOracle.BlockInfo memory res = oracle.load(blockNumber); - - assertEq(Hash.unwrap(res.hash), blockhash(blockNumber)); - assertEq(Timestamp.unwrap(res.childTimestamp), block.timestamp); - } - - /// @notice Tests that the `load` function reverts if the block hash for the given block - /// number has not been stored. - function test_load_noBlockHash_reverts() public { - vm.expectRevert(BlockHashNotPresent.selector); - oracle.load(0); - } -} diff --git a/packages/contracts-bedrock/test/CheckBalanceHigh.t.sol b/packages/contracts-bedrock/test/CheckBalanceHigh.t.sol deleted file mode 100644 index 3102f560f3c8..000000000000 --- a/packages/contracts-bedrock/test/CheckBalanceHigh.t.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { Test } from "forge-std/Test.sol"; -import { CheckBalanceHigh } from "src/periphery/drippie/dripchecks/CheckBalanceHigh.sol"; - -/// @title CheckBalanceHighTest -/// @notice Tests the CheckBalanceHigh contract via fuzzing both the success case -/// and the failure case. -contract CheckBalanceHighTest is Test { - /// @notice An instance of the CheckBalanceHigh contract. - CheckBalanceHigh c; - - /// @notice Deploy the `CheckTrue` contract. - function setUp() external { - c = new CheckBalanceHigh(); - } - - /// @notice Fuzz the `check` function and assert that it always returns true - /// when the target's balance is larger than the threshold. - function testFuzz_check_succeeds(address _target, uint256 _threshold) external { - CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({ target: _target, threshold: _threshold }); - - // prevent overflows - vm.assume(_threshold != type(uint256).max); - vm.deal(_target, _threshold + 1); - - assertEq(c.check(abi.encode(p)), true); - } - - /// @notice Fuzz the `check` function and assert that it always returns false - /// when the target's balance is smaller than the threshold. - function testFuzz_check_lowBalance_fails(address _target, uint256 _threshold) external { - CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({ target: _target, threshold: _threshold }); - - vm.assume(_target.balance < _threshold); - - assertEq(c.check(abi.encode(p)), false); - } -} diff --git a/packages/contracts-bedrock/test/CommonTest.t.sol b/packages/contracts-bedrock/test/CommonTest.t.sol deleted file mode 100644 index a3a64b6d9b22..000000000000 --- a/packages/contracts-bedrock/test/CommonTest.t.sol +++ /dev/null @@ -1,829 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { Test, StdUtils } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; -import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; -import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; -import { FeeVault } from "src/universal/FeeVault.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { LegacyERC20ETH } from "src/legacy/LegacyERC20ETH.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { Types } from "src/libraries/Types.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { Proxy } from "src/universal/Proxy.sol"; -import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; -import { AddressManager } from "src/legacy/AddressManager.sol"; -import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; -import { IL1ChugSplashDeployer } from "src/legacy/L1ChugSplashProxy.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { Constants } from "src/libraries/Constants.sol"; - -contract CommonTest is Test { - address alice = address(128); - address bob = address(256); - address multisig = address(512); - - address immutable ZERO_ADDRESS = address(0); - address immutable NON_ZERO_ADDRESS = address(1); - uint256 immutable NON_ZERO_VALUE = 100; - uint256 immutable ZERO_VALUE = 0; - uint64 immutable NON_ZERO_GASLIMIT = 50000; - bytes32 nonZeroHash = keccak256(abi.encode("NON_ZERO")); - bytes NON_ZERO_DATA = hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000"; - - event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); - - /// @dev OpenZeppelin Ownable.sol transferOwnership event - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - FFIInterface ffi; - - function setUp() public virtual { - // Give alice and bob some ETH - vm.deal(alice, 1 << 16); - vm.deal(bob, 1 << 16); - vm.deal(multisig, 1 << 16); - - vm.label(alice, "alice"); - vm.label(bob, "bob"); - vm.label(multisig, "multisig"); - - // Make sure we have a non-zero base fee - vm.fee(1000000000); - - ffi = new FFIInterface(); - } - - function emitTransactionDeposited( - address _from, - address _to, - uint256 _mint, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes memory _data - ) - internal - { - emit TransactionDeposited(_from, _to, 0, abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)); - } -} - -contract L2OutputOracle_Initializer is CommonTest { - // Test target - L2OutputOracle oracle; - L2OutputOracle oracleImpl; - - L2ToL1MessagePasser messagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); - - // Constructor arguments - address internal proposer = 0x000000000000000000000000000000000000AbBa; - address internal owner = 0x000000000000000000000000000000000000ACDC; - uint256 internal submissionInterval = 1800; - uint256 internal l2BlockTime = 2; - uint256 internal startingBlockNumber = 200; - uint256 internal startingTimestamp = 1000; - uint256 internal finalizationPeriodSeconds = 7 days; - address guardian; - - // Test data - uint256 initL1Time; - - event OutputProposed( - bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp - ); - - event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); - - // Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output - function warpToProposeTime(uint256 _nextBlockNumber) public { - vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1); - } - - /// @dev Helper function to propose an output. - function proposeAnotherOutput() public { - bytes32 proposedOutput2 = keccak256(abi.encode()); - uint256 nextBlockNumber = oracle.nextBlockNumber(); - uint256 nextOutputIndex = oracle.nextOutputIndex(); - warpToProposeTime(nextBlockNumber); - uint256 proposedNumber = oracle.latestBlockNumber(); - - // Ensure the submissionInterval is enforced - assertEq(nextBlockNumber, proposedNumber + submissionInterval); - - vm.roll(nextBlockNumber + 1); - - vm.expectEmit(true, true, true, true); - emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp); - - vm.prank(proposer); - oracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0); - } - - function setUp() public virtual override { - super.setUp(); - guardian = makeAddr("guardian"); - - // By default the first block has timestamp and number zero, which will cause underflows in the - // tests, so we'll move forward to these block values. - initL1Time = startingTimestamp + 1; - vm.warp(initL1Time); - vm.roll(startingBlockNumber); - // Deploy the L2OutputOracle and transfer owernship to the proposer - oracleImpl = new L2OutputOracle({ - _submissionInterval: submissionInterval, - _l2BlockTime: l2BlockTime, - _finalizationPeriodSeconds: finalizationPeriodSeconds - }); - Proxy proxy = new Proxy(multisig); - vm.prank(multisig); - proxy.upgradeToAndCall( - address(oracleImpl), - abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp, proposer, owner)) - ); - oracle = L2OutputOracle(address(proxy)); - vm.label(address(oracle), "L2OutputOracle"); - - // Set the L2ToL1MessagePasser at the correct address - vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code); - - vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, "L2ToL1MessagePasser"); - } -} - -contract Portal_Initializer is L2OutputOracle_Initializer { - // Test target - OptimismPortal internal opImpl; - OptimismPortal internal op; - SystemConfig systemConfig; - - event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); - event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to); - - function setUp() public virtual override { - super.setUp(); - - Proxy systemConfigProxy = new Proxy(multisig); - - SystemConfig systemConfigImpl = new SystemConfig(); - - vm.prank(multisig); - systemConfigProxy.upgradeToAndCall( - address(systemConfigImpl), - abi.encodeCall( - SystemConfig.initialize, - ( - address(1), //_owner, - 0, //_overhead, - 10000, //_scalar, - bytes32(0), //_batcherHash, - 30_000_000, //_gasLimit, - address(0), //_unsafeBlockSigner, - Constants.DEFAULT_RESOURCE_CONFIG(), //_config, - 0, //_startBlock - address(0xff), // _batchInbox - SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: address(0), - l1ERC721Bridge: address(0), - l1StandardBridge: address(0), - l2OutputOracle: address(oracle), - optimismPortal: address(op), - optimismMintableERC20Factory: address(0) - }) - ) - ) - ); - - systemConfig = SystemConfig(address(systemConfigProxy)); - - opImpl = new OptimismPortal(); - - Proxy proxy = new Proxy(multisig); - vm.prank(multisig); - proxy.upgradeToAndCall( - address(opImpl), abi.encodeCall(OptimismPortal.initialize, (oracle, guardian, systemConfig, false)) - ); - op = OptimismPortal(payable(address(proxy))); - vm.label(address(op), "OptimismPortal"); - } -} - -contract Messenger_Initializer is Portal_Initializer { - AddressManager internal addressManager; - L1CrossDomainMessenger internal L1Messenger; - L2CrossDomainMessenger internal L2Messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER); - - event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); - - event SentMessageExtension1(address indexed sender, uint256 value); - - event MessagePassed( - uint256 indexed nonce, - address indexed sender, - address indexed target, - uint256 value, - uint256 gasLimit, - bytes data, - bytes32 withdrawalHash - ); - - event RelayedMessage(bytes32 indexed msgHash); - event FailedRelayedMessage(bytes32 indexed msgHash); - - event TransactionDeposited( - address indexed from, - address indexed to, - uint256 mint, - uint256 value, - uint64 gasLimit, - bool isCreation, - bytes data - ); - - event WhatHappened(bool success, bytes returndata); - - function setUp() public virtual override { - super.setUp(); - - // Deploy the address manager - vm.prank(multisig); - addressManager = new AddressManager(); - - // Setup implementation - L1CrossDomainMessenger L1MessengerImpl = new L1CrossDomainMessenger(); - - // Setup the address manager and proxy - vm.prank(multisig); - addressManager.setAddress("OVM_L1CrossDomainMessenger", address(L1MessengerImpl)); - ResolvedDelegateProxy proxy = new ResolvedDelegateProxy( - addressManager, - "OVM_L1CrossDomainMessenger" - ); - L1Messenger = L1CrossDomainMessenger(address(proxy)); - L1Messenger.initialize(op); - - vm.etch(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(new L2CrossDomainMessenger(address(L1Messenger))).code); - - L2Messenger.initialize(); - - // Label addresses - vm.label(address(addressManager), "AddressManager"); - vm.label(address(L1MessengerImpl), "L1CrossDomainMessenger_Impl"); - vm.label(address(L1Messenger), "L1CrossDomainMessenger_Proxy"); - vm.label(Predeploys.LEGACY_ERC20_ETH, "LegacyERC20ETH"); - vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger"); - - vm.label(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)), "L1CrossDomainMessenger_aliased"); - } -} - -contract Bridge_Initializer is Messenger_Initializer { - L1StandardBridge L1Bridge; - L2StandardBridge L2Bridge; - OptimismMintableERC20Factory L2TokenFactory; - OptimismMintableERC20Factory L1TokenFactory; - ERC20 L1Token; - ERC20 BadL1Token; - OptimismMintableERC20 L2Token; - LegacyMintableERC20 LegacyL2Token; - ERC20 NativeL2Token; - ERC20 BadL2Token; - OptimismMintableERC20 RemoteL1Token; - - event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data); - - event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes data); - - event ERC20DepositInitiated( - address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data - ); - - event ERC20WithdrawalFinalized( - address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data - ); - - event WithdrawalInitiated( - address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data - ); - - event DepositFinalized( - address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data - ); - - event DepositFailed( - address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data - ); - - event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data); - - event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data); - - event ERC20BridgeInitiated( - address indexed localToken, - address indexed remoteToken, - address indexed from, - address to, - uint256 amount, - bytes data - ); - - event ERC20BridgeFinalized( - address indexed localToken, - address indexed remoteToken, - address indexed from, - address to, - uint256 amount, - bytes data - ); - - function setUp() public virtual override { - super.setUp(); - - vm.label(Predeploys.L2_STANDARD_BRIDGE, "L2StandardBridge"); - vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, "OptimismMintableERC20Factory"); - - // Deploy the L1 bridge and initialize it with the address of the - // L1CrossDomainMessenger - L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig); - vm.mockCall(multisig, abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector), abi.encode(true)); - vm.startPrank(multisig); - proxy.setCode(address(new L1StandardBridge()).code); - vm.clearMockedCalls(); - address L1Bridge_Impl = proxy.getImplementation(); - vm.stopPrank(); - - L1Bridge = L1StandardBridge(payable(address(proxy))); - L1Bridge.initialize({ _messenger: L1Messenger }); - - vm.label(address(proxy), "L1StandardBridge_Proxy"); - vm.label(address(L1Bridge_Impl), "L1StandardBridge_Impl"); - - // Deploy the L2StandardBridge, move it to the correct predeploy - // address and then initialize it. It is safe to call initialize directly - // on the proxy because the bytecode was set in state with `etch`. - vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(new L2StandardBridge(StandardBridge(payable(proxy)))).code); - L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)); - L2Bridge.initialize(); - - // Set up the L2 mintable token factory - OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(); - vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code); - L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); - L2TokenFactory.initialize(Predeploys.L2_STANDARD_BRIDGE); - - vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code); - - L1Token = new ERC20("Native L1 Token", "L1T"); - - LegacyL2Token = new LegacyMintableERC20({ - _l2Bridge: address(L2Bridge), - _l1Token: address(L1Token), - _name: string.concat("LegacyL2-", L1Token.name()), - _symbol: string.concat("LegacyL2-", L1Token.symbol()) - }); - vm.label(address(LegacyL2Token), "LegacyMintableERC20"); - - // Deploy the L2 ERC20 now - L2Token = OptimismMintableERC20( - L2TokenFactory.createStandardL2Token( - address(L1Token), - string(abi.encodePacked("L2-", L1Token.name())), - string(abi.encodePacked("L2-", L1Token.symbol())) - ) - ); - - BadL2Token = OptimismMintableERC20( - L2TokenFactory.createStandardL2Token( - address(1), - string(abi.encodePacked("L2-", L1Token.name())), - string(abi.encodePacked("L2-", L1Token.symbol())) - ) - ); - - NativeL2Token = new ERC20("Native L2 Token", "L2T"); - Proxy factoryProxy = new Proxy(multisig); - OptimismMintableERC20Factory L1TokenFactoryImpl = new OptimismMintableERC20Factory(); - - vm.prank(multisig); - factoryProxy.upgradeToAndCall( - address(L1TokenFactoryImpl), abi.encodeCall(OptimismMintableERC20Factory.initialize, address(L1Bridge)) - ); - - L1TokenFactory = OptimismMintableERC20Factory(address(factoryProxy)); - - RemoteL1Token = OptimismMintableERC20( - L1TokenFactory.createStandardL2Token( - address(NativeL2Token), - string(abi.encodePacked("L1-", NativeL2Token.name())), - string(abi.encodePacked("L1-", NativeL2Token.symbol())) - ) - ); - - BadL1Token = OptimismMintableERC20( - L1TokenFactory.createStandardL2Token( - address(1), - string(abi.encodePacked("L1-", NativeL2Token.name())), - string(abi.encodePacked("L1-", NativeL2Token.symbol())) - ) - ); - } -} - -contract ERC721Bridge_Initializer is Bridge_Initializer { - L1ERC721Bridge L1NFTBridge; - L2ERC721Bridge L2NFTBridge; - - function setUp() public virtual override { - super.setUp(); - - // Deploy the L1ERC721Bridge. - L1ERC721Bridge l1BridgeImpl = new L1ERC721Bridge(); - Proxy l1BridgeProxy = new Proxy(multisig); - - vm.prank(multisig); - l1BridgeProxy.upgradeToAndCall( - address(l1BridgeImpl), abi.encodeCall(L1ERC721Bridge.initialize, (CrossDomainMessenger(L1Messenger))) - ); - - L1NFTBridge = L1ERC721Bridge(address(l1BridgeProxy)); - - // Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address. - L2ERC721Bridge l2BridgeImpl = new L2ERC721Bridge(address(L1NFTBridge)); - Proxy l2BridgeProxy = new Proxy(multisig); - vm.etch(Predeploys.L2_ERC721_BRIDGE, address(l2BridgeProxy).code); - - // set the storage slot for admin - bytes32 OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - vm.store(Predeploys.L2_ERC721_BRIDGE, OWNER_KEY, bytes32(uint256(uint160(multisig)))); - - vm.prank(multisig); - Proxy(payable(Predeploys.L2_ERC721_BRIDGE)).upgradeToAndCall( - address(l2BridgeImpl), abi.encodeCall(L2ERC721Bridge.initialize, ()) - ); - - // Set up a reference to the L2ERC721Bridge. - L2NFTBridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); - - // Label the L1 and L2 bridges. - vm.label(address(L1NFTBridge), "L1ERC721Bridge"); - vm.label(address(L2NFTBridge), "L2ERC721Bridge"); - } -} - -contract FeeVault_Initializer is Bridge_Initializer { - SequencerFeeVault vault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); - address constant recipient = address(1024); - - event Withdrawal(uint256 value, address to, address from); - - event Withdrawal(uint256 value, address to, address from, FeeVault.WithdrawalNetwork withdrawalNetwork); -} - -contract FFIInterface is Test { - function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx) - external - returns (bytes32, bytes32, bytes32, bytes32, bytes[] memory) - { - string[] memory cmds = new string[](9); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "getProveWithdrawalTransactionInputs"; - cmds[3] = vm.toString(_tx.nonce); - cmds[4] = vm.toString(_tx.sender); - cmds[5] = vm.toString(_tx.target); - cmds[6] = vm.toString(_tx.value); - cmds[7] = vm.toString(_tx.gasLimit); - cmds[8] = vm.toString(_tx.data); - - bytes memory result = vm.ffi(cmds); - ( - bytes32 stateRoot, - bytes32 storageRoot, - bytes32 outputRoot, - bytes32 withdrawalHash, - bytes[] memory withdrawalProof - ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[])); - - return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof); - } - - function hashCrossDomainMessage( - uint256 _nonce, - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes memory _data - ) - external - returns (bytes32) - { - string[] memory cmds = new string[](9); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "hashCrossDomainMessage"; - cmds[3] = vm.toString(_nonce); - cmds[4] = vm.toString(_sender); - cmds[5] = vm.toString(_target); - cmds[6] = vm.toString(_value); - cmds[7] = vm.toString(_gasLimit); - cmds[8] = vm.toString(_data); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes32)); - } - - function hashWithdrawal( - uint256 _nonce, - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes memory _data - ) - external - returns (bytes32) - { - string[] memory cmds = new string[](9); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "hashWithdrawal"; - cmds[3] = vm.toString(_nonce); - cmds[4] = vm.toString(_sender); - cmds[5] = vm.toString(_target); - cmds[6] = vm.toString(_value); - cmds[7] = vm.toString(_gasLimit); - cmds[8] = vm.toString(_data); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes32)); - } - - function hashOutputRootProof( - bytes32 _version, - bytes32 _stateRoot, - bytes32 _messagePasserStorageRoot, - bytes32 _latestBlockhash - ) - external - returns (bytes32) - { - string[] memory cmds = new string[](7); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "hashOutputRootProof"; - cmds[3] = Strings.toHexString(uint256(_version)); - cmds[4] = Strings.toHexString(uint256(_stateRoot)); - cmds[5] = Strings.toHexString(uint256(_messagePasserStorageRoot)); - cmds[6] = Strings.toHexString(uint256(_latestBlockhash)); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes32)); - } - - function hashDepositTransaction( - address _from, - address _to, - uint256 _mint, - uint256 _value, - uint64 _gas, - bytes memory _data, - uint64 _logIndex - ) - external - returns (bytes32) - { - string[] memory cmds = new string[](11); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "hashDepositTransaction"; - cmds[3] = "0x0000000000000000000000000000000000000000000000000000000000000000"; - cmds[4] = vm.toString(_logIndex); - cmds[5] = vm.toString(_from); - cmds[6] = vm.toString(_to); - cmds[7] = vm.toString(_mint); - cmds[8] = vm.toString(_value); - cmds[9] = vm.toString(_gas); - cmds[10] = vm.toString(_data); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes32)); - } - - function encodeDepositTransaction(Types.UserDepositTransaction calldata txn) external returns (bytes memory) { - string[] memory cmds = new string[](12); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "encodeDepositTransaction"; - cmds[3] = vm.toString(txn.from); - cmds[4] = vm.toString(txn.to); - cmds[5] = vm.toString(txn.value); - cmds[6] = vm.toString(txn.mint); - cmds[7] = vm.toString(txn.gasLimit); - cmds[8] = vm.toString(txn.isCreation); - cmds[9] = vm.toString(txn.data); - cmds[10] = vm.toString(txn.l1BlockHash); - cmds[11] = vm.toString(txn.logIndex); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes)); - } - - function encodeCrossDomainMessage( - uint256 _nonce, - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes memory _data - ) - external - returns (bytes memory) - { - string[] memory cmds = new string[](9); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "encodeCrossDomainMessage"; - cmds[3] = vm.toString(_nonce); - cmds[4] = vm.toString(_sender); - cmds[5] = vm.toString(_target); - cmds[6] = vm.toString(_value); - cmds[7] = vm.toString(_gasLimit); - cmds[8] = vm.toString(_data); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes)); - } - - function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) { - string[] memory cmds = new string[](4); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "decodeVersionedNonce"; - cmds[3] = vm.toString(nonce); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (uint256, uint256)); - } - - function getMerkleTrieFuzzCase(string memory variant) - external - returns (bytes32, bytes memory, bytes memory, bytes[] memory) - { - string[] memory cmds = new string[](6); - cmds[0] = "./scripts/go-ffi/go-ffi"; - cmds[1] = "trie"; - cmds[2] = variant; - - return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[])); - } - - function getCannonMemoryProof(uint32 pc, uint32 insn) external returns (bytes32, bytes memory) { - string[] memory cmds = new string[](5); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "cannonMemoryProof"; - cmds[3] = vm.toString(pc); - cmds[4] = vm.toString(insn); - bytes memory result = vm.ffi(cmds); - (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); - return (memRoot, proof); - } - - function getCannonMemoryProof( - uint32 pc, - uint32 insn, - uint32 memAddr, - uint32 memVal - ) - external - returns (bytes32, bytes memory) - { - string[] memory cmds = new string[](7); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "cannonMemoryProof"; - cmds[3] = vm.toString(pc); - cmds[4] = vm.toString(insn); - cmds[5] = vm.toString(memAddr); - cmds[6] = vm.toString(memVal); - bytes memory result = vm.ffi(cmds); - (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); - return (memRoot, proof); - } -} - -library EIP1967Helper { - Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - - function getAdmin(address _proxy) internal view returns (address) { - return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_OWNER_ADDRESS)))); - } - - function getImplementation(address _proxy) internal view returns (address) { - return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_IMPLEMENTATION_ADDRESS)))); - } -} - -// Used for testing a future upgrade beyond the current implementations. -// We include some variables so that we can sanity check accessing storage values after an upgrade. -contract NextImpl is Initializable { - // Initializable occupies the zero-th slot. - bytes32 slot1; - bytes32[19] __gap; - bytes32 slot21; - bytes32 public constant slot21Init = bytes32(hex"1337"); - - function initialize(uint8 _init) public reinitializer(_init) { - // Slot21 is unused by an of our upgradeable contracts. - // This is used to verify that we can access this value after an upgrade. - slot21 = slot21Init; - } -} - -contract Reverter { - fallback() external { - revert(); - } -} - -// Useful for testing reentrancy guards -contract CallerCaller { - event WhatHappened(bool success, bytes returndata); - - fallback() external { - (bool success, bytes memory returndata) = msg.sender.call(msg.data); - emit WhatHappened(success, returndata); - assembly { - switch success - case 0 { revert(add(returndata, 0x20), mload(returndata)) } - default { return(add(returndata, 0x20), mload(returndata)) } - } - } -} - -// Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard. -contract ConfigurableCaller { - bool doRevert = true; - address target; - bytes payload; - - event WhatHappened(bool success, bytes returndata); - - /// @notice Call the configured target with the configured payload OR revert. - function call() external { - if (doRevert) { - revert("ConfigurableCaller: revert"); - } else { - (bool success, bytes memory returndata) = address(target).call(payload); - emit WhatHappened(success, returndata); - assembly { - switch success - case 0 { revert(add(returndata, 0x20), mload(returndata)) } - default { return(add(returndata, 0x20), mload(returndata)) } - } - } - } - - /// @notice Set whether or not to have `call` revert. - function setDoRevert(bool _doRevert) external { - doRevert = _doRevert; - } - - /// @notice Set the target for the call made in `call`. - function setTarget(address _target) external { - target = _target; - } - - /// @notice Set the payload for the call made in `call`. - function setPayload(bytes calldata _payload) external { - payload = _payload; - } - - /// @notice Fallback function that reverts if `doRevert` is true. - /// Otherwise, it does nothing. - fallback() external { - if (doRevert) { - revert("ConfigurableCaller: revert"); - } - } -} diff --git a/packages/contracts-bedrock/test/DisputeGameFactory.t.sol b/packages/contracts-bedrock/test/DisputeGameFactory.t.sol deleted file mode 100644 index a745b73fb04c..000000000000 --- a/packages/contracts-bedrock/test/DisputeGameFactory.t.sol +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; - -import "src/libraries/DisputeTypes.sol"; -import "src/libraries/DisputeErrors.sol"; - -import { Test } from "forge-std/Test.sol"; -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; -import { Proxy } from "src/universal/Proxy.sol"; -import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; - -contract DisputeGameFactory_Init is L2OutputOracle_Initializer { - DisputeGameFactory factory; - FakeClone fakeClone; - - event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim); - - event ImplementationSet(address indexed impl, GameType indexed gameType); - - function setUp() public virtual override { - super.setUp(); - - Proxy proxy = new Proxy(address(this)); - DisputeGameFactory impl = new DisputeGameFactory(); - - proxy.upgradeToAndCall({ - _implementation: address(impl), - _data: abi.encodeCall(impl.initialize, (address(this))) - }); - factory = DisputeGameFactory(address(proxy)); - vm.label(address(factory), "DisputeGameFactoryProxy"); - - fakeClone = new FakeClone(); - } -} - -contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init { - /// @dev Tests that the `create` function succeeds when creating a new dispute game - /// with a `GameType` that has an implementation set. - function testFuzz_create_succeeds(uint8 gameType, Claim rootClaim, bytes calldata extraData) public { - // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. - GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); - // Ensure the rootClaim has a VMStatus that disagrees with the validity. - rootClaim = changeClaimStatus(rootClaim, VMStatuses.INVALID); - - // Set all three implementations to the same `FakeClone` contract. - for (uint8 i; i < 3; i++) { - factory.setImplementation(GameType.wrap(i), IDisputeGame(address(fakeClone))); - } - - vm.expectEmit(false, true, true, false); - emit DisputeGameCreated(address(0), gt, rootClaim); - IDisputeGame proxy = factory.create(gt, rootClaim, extraData); - - (IDisputeGame game, Timestamp timestamp) = factory.games(gt, rootClaim, extraData); - - // Ensure that the dispute game was assigned to the `disputeGames` mapping. - assertEq(address(game), address(proxy)); - assertEq(Timestamp.unwrap(timestamp), block.timestamp); - assertEq(factory.gameCount(), 1); - - (, Timestamp timestamp2, IDisputeGame game2) = factory.gameAtIndex(0); - assertEq(address(game2), address(proxy)); - assertEq(Timestamp.unwrap(timestamp2), block.timestamp); - } - - /// @dev Tests that the `create` function reverts when there is no implementation - /// set for the given `GameType`. - function testFuzz_create_noImpl_reverts(uint8 gameType, Claim rootClaim, bytes calldata extraData) public { - // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. - GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); - // Ensure the rootClaim has a VMStatus that disagrees with the validity. - rootClaim = changeClaimStatus(rootClaim, VMStatuses.INVALID); - - vm.expectRevert(abi.encodeWithSelector(NoImplementation.selector, gt)); - factory.create(gt, rootClaim, extraData); - } - - /// @dev Tests that the `create` function reverts when there exists a dispute game with the same UUID. - function testFuzz_create_sameUUID_reverts(uint8 gameType, Claim rootClaim, bytes calldata extraData) public { - // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. - GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); - // Ensure the rootClaim has a VMStatus that disagrees with the validity. - rootClaim = changeClaimStatus(rootClaim, VMStatuses.INVALID); - - // Set all three implementations to the same `FakeClone` contract. - for (uint8 i; i < 3; i++) { - factory.setImplementation(GameType.wrap(i), IDisputeGame(address(fakeClone))); - } - - // Create our first dispute game - this should succeed. - vm.expectEmit(false, true, true, false); - emit DisputeGameCreated(address(0), gt, rootClaim); - IDisputeGame proxy = factory.create(gt, rootClaim, extraData); - - (IDisputeGame game, Timestamp timestamp) = factory.games(gt, rootClaim, extraData); - // Ensure that the dispute game was assigned to the `disputeGames` mapping. - assertEq(address(game), address(proxy)); - assertEq(Timestamp.unwrap(timestamp), block.timestamp); - - // Ensure that the `create` function reverts when called with parameters that would result in the same UUID. - vm.expectRevert( - abi.encodeWithSelector(GameAlreadyExists.selector, factory.getGameUUID(gt, rootClaim, extraData)) - ); - factory.create(gt, rootClaim, extraData); - } - - function changeClaimStatus(Claim _claim, VMStatus _status) public pure returns (Claim out_) { - assembly { - out_ := or(and(not(shl(248, 0xFF)), _claim), shl(248, _status)) - } - } -} - -contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init { - /// @dev Tests that the `setImplementation` function properly sets the implementation for a given `GameType`. - function test_setImplementation_succeeds() public { - // There should be no implementation for the `GameTypes.FAULT` enum value, it has not been set. - assertEq(address(factory.gameImpls(GameTypes.FAULT)), address(0)); - - vm.expectEmit(true, true, true, true, address(factory)); - emit ImplementationSet(address(1), GameTypes.FAULT); - - // Set the implementation for the `GameTypes.FAULT` enum value. - factory.setImplementation(GameTypes.FAULT, IDisputeGame(address(1))); - - // Ensure that the implementation for the `GameTypes.FAULT` enum value is set. - assertEq(address(factory.gameImpls(GameTypes.FAULT)), address(1)); - } - - /// @dev Tests that the `setImplementation` function reverts when called by a non-owner. - function test_setImplementation_notOwner_reverts() public { - // Ensure that the `setImplementation` function reverts when called by a non-owner. - vm.prank(address(0)); - vm.expectRevert("Ownable: caller is not the owner"); - factory.setImplementation(GameTypes.FAULT, IDisputeGame(address(1))); - } -} - -contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init { - /// @dev Tests that the `getGameUUID` function returns the correct hash when comparing - /// against the keccak256 hash of the abi-encoded parameters. - function testDiff_getGameUUID_succeeds(uint8 gameType, Claim rootClaim, bytes calldata extraData) public { - // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. - GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); - - assertEq( - Hash.unwrap(factory.getGameUUID(gt, rootClaim, extraData)), keccak256(abi.encode(gt, rootClaim, extraData)) - ); - } -} - -contract DisputeGameFactory_Owner_Test is DisputeGameFactory_Init { - /// @dev Tests that the `owner` function returns the correct address after deployment. - function test_owner_succeeds() public { - assertEq(factory.owner(), address(this)); - } -} - -contract DisputeGameFactory_TransferOwnership_Test is DisputeGameFactory_Init { - /// @dev Tests that the `transferOwnership` function succeeds when called by the owner. - function test_transferOwnership_succeeds() public { - factory.transferOwnership(address(1)); - assertEq(factory.owner(), address(1)); - } - - /// @dev Tests that the `transferOwnership` function reverts when called by a non-owner. - function test_transferOwnership_notOwner_reverts() public { - vm.prank(address(0)); - vm.expectRevert("Ownable: caller is not the owner"); - factory.transferOwnership(address(1)); - } -} - -/// @dev A fake clone used for testing the `DisputeGameFactory` contract's `create` function. -contract FakeClone { - function initialize() external { - // noop - } -} diff --git a/packages/contracts-bedrock/test/ExtendedPause.t.sol b/packages/contracts-bedrock/test/ExtendedPause.t.sol new file mode 100644 index 000000000000..93e207ac6e9d --- /dev/null +++ b/packages/contracts-bedrock/test/ExtendedPause.t.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { CommonTest } from "test/setup/CommonTest.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; + +/// @dev These tests are somewhat redundant with tests in the SuperchainConfig and other pausable contracts, however +/// it is worthwhile to pull them into one location to ensure that the behavior is consistent. +contract ExtendedPause_Test is CommonTest { + /// @dev Tests that other contracts are paused when the superchain config is paused + function test_pause_fullSystem_succeeds() public { + assertFalse(superchainConfig.paused()); + + vm.prank(superchainConfig.guardian()); + superchainConfig.pause("identifier"); + + // validate the paused state + assertTrue(superchainConfig.paused()); + assertTrue(optimismPortal.paused()); + assertTrue(l1CrossDomainMessenger.paused()); + assertTrue(l1StandardBridge.paused()); + assertTrue(l1ERC721Bridge.paused()); + } + + /// @dev Tests that other contracts are unpaused when the superchain config is paused and then unpaused. + function test_unpause_fullSystem_succeeds() external { + // first use the test above to pause the system + test_pause_fullSystem_succeeds(); + + vm.prank(superchainConfig.guardian()); + superchainConfig.unpause(); + + // validate the unpaused state + assertFalse(superchainConfig.paused()); + assertFalse(optimismPortal.paused()); + assertFalse(l1CrossDomainMessenger.paused()); + assertFalse(l1StandardBridge.paused()); + assertFalse(l1ERC721Bridge.paused()); + } +} diff --git a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol deleted file mode 100644 index 40297b6cc8c0..000000000000 --- a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol +++ /dev/null @@ -1,1129 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; - -import { Test } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; -import { DisputeGameFactory_Init } from "test/DisputeGameFactory.t.sol"; -import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; -import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -import { BlockOracle } from "src/dispute/BlockOracle.sol"; -import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; -import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol"; - -import "src/libraries/DisputeTypes.sol"; -import "src/libraries/DisputeErrors.sol"; -import { Types } from "src/libraries/Types.sol"; -import { LibClock } from "src/dispute/lib/LibClock.sol"; -import { LibPosition } from "src/dispute/lib/LibPosition.sol"; -import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; - -contract FaultDisputeGame_Init is DisputeGameFactory_Init { - /// @dev The type of the game being tested. - GameType internal constant GAME_TYPE = GameType.wrap(0); - - /// @dev The implementation of the game. - FaultDisputeGame internal gameImpl; - /// @dev The `Clone` proxy of the game. - FaultDisputeGame internal gameProxy; - /// @dev The extra data passed to the game for initialization. - bytes internal extraData; - - event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant); - - function init(Claim rootClaim, Claim absolutePrestate) public { - // Set the time to a realistic date. - vm.warp(1690906994); - - // Propose 2 mock outputs - vm.startPrank(oracle.PROPOSER()); - for (uint256 i; i < 2; i++) { - oracle.proposeL2Output(bytes32(i + 1), oracle.nextBlockNumber(), blockhash(i), i); - - // Advance 1 block - vm.roll(block.number + 1); - vm.warp(block.timestamp + 13); - } - vm.stopPrank(); - - // Deploy a new block hash oracle and store the block hash for the genesis block. - BlockOracle blockOracle = new BlockOracle(); - blockOracle.checkpoint(); - - // Set the extra data for the game creation - extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, block.number - 1); - - // Deploy an implementation of the fault game - gameImpl = new FaultDisputeGame( - GAME_TYPE, - absolutePrestate, - 4, - Duration.wrap(7 days), - new AlphabetVM(absolutePrestate), - oracle, - blockOracle - ); - // Register the game implementation with the factory. - factory.setImplementation(GAME_TYPE, gameImpl); - // Create a new game. - gameProxy = FaultDisputeGame(address(factory.create(GAME_TYPE, rootClaim, extraData))); - - // Label the proxy - vm.label(address(gameProxy), "FaultDisputeGame_Clone"); - } -} - -contract FaultDisputeGame_Test is FaultDisputeGame_Init { - /// @dev The root claim of the game. - Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32((uint256(1) << 248) | uint256(10))); - /// @dev The absolute prestate of the trace. - Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32((uint256(3) << 248) | uint256(0))); - - function setUp() public override { - super.setUp(); - super.init(ROOT_CLAIM, ABSOLUTE_PRESTATE); - } - - //////////////////////////////////////////////////////////////// - // `IDisputeGame` Implementation Tests // - //////////////////////////////////////////////////////////////// - - /// @dev Tests that the game's root claim is set correctly. - function test_rootClaim_succeeds() public { - assertEq(Claim.unwrap(gameProxy.rootClaim()), Claim.unwrap(ROOT_CLAIM)); - } - - /// @dev Tests that the game's extra data is set correctly. - function test_extraData_succeeds() public { - assertEq(gameProxy.extraData(), extraData); - } - - /// @dev Tests that the game's starting timestamp is set correctly. - function test_createdAt_succeeds() public { - assertEq(Timestamp.unwrap(gameProxy.createdAt()), block.timestamp); - } - - /// @dev Tests that the game's type is set correctly. - function test_gameType_succeeds() public { - assertEq(GameType.unwrap(gameProxy.gameType()), GameType.unwrap(GAME_TYPE)); - } - - /// @dev Tests that the game's data is set correctly. - function test_gameData_succeeds() public { - (GameType gameType, Claim rootClaim, bytes memory _extraData) = gameProxy.gameData(); - - assertEq(GameType.unwrap(gameType), GameType.unwrap(GAME_TYPE)); - assertEq(Claim.unwrap(rootClaim), Claim.unwrap(ROOT_CLAIM)); - assertEq(_extraData, extraData); - } - - //////////////////////////////////////////////////////////////// - // `IFaultDisputeGame` Implementation Tests // - //////////////////////////////////////////////////////////////// - - /// @dev Tests that a game cannot be created by the factory if the L1 head hash does not - /// contain the disputed L2 output root. - function test_initialize_l1HeadTooOld_reverts() public { - // Store a mock block hash for the genesis block. The timestamp will default to 0. - vm.store(address(gameImpl.BLOCK_ORACLE()), keccak256(abi.encode(0, 0)), bytes32(uint256(1))); - bytes memory _extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, 0); - - vm.expectRevert(L1HeadTooOld.selector); - factory.create(GAME_TYPE, ROOT_CLAIM, _extraData); - } - - /// @dev Tests that a game cannot be created that disputes the first output root proposed. - /// TODO(clabby): This will be solved by the block hash bisection game, where we'll be able - /// to dispute the first output root by using genesis as the starting point. - /// For now, it is critical that the first proposed output root of an OP stack - /// chain is done so by an honest party. - function test_initialize_firstOutput_reverts() public { - vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x11)); - factory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(1800, block.number - 1)); - } - - /// @dev Tests that the `create` function reverts when the rootClaim does not disagree with the outcome. - function testFuzz_initialize_badRootStatus_reverts(Claim rootClaim, bytes calldata extraData) public { - // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. - // Ensure the root claim does not have the correct VM status - uint8 vmStatus = uint8(Claim.unwrap(rootClaim)[0]); - if (vmStatus == 1 || vmStatus == 2) rootClaim = changeClaimStatus(rootClaim, VMStatuses.VALID); - - vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, rootClaim)); - factory.create(GameTypes.FAULT, rootClaim, extraData); - } - - /// @dev Tests that the game is initialized with the correct data. - function test_initialize_correctData_succeeds() public { - // Starting - (FaultDisputeGame.OutputProposal memory startingProp, FaultDisputeGame.OutputProposal memory disputedProp) = - gameProxy.proposals(); - Types.OutputProposal memory starting = oracle.getL2Output(startingProp.index); - assertEq(startingProp.index, 0); - assertEq(startingProp.l2BlockNumber, starting.l2BlockNumber); - assertEq(Hash.unwrap(startingProp.outputRoot), starting.outputRoot); - // Disputed - Types.OutputProposal memory disputed = oracle.getL2Output(disputedProp.index); - assertEq(disputedProp.index, 1); - assertEq(disputedProp.l2BlockNumber, disputed.l2BlockNumber); - assertEq(Hash.unwrap(disputedProp.outputRoot), disputed.outputRoot); - - // L1 head - (, uint256 l1HeadNumber) = abi.decode(gameProxy.extraData(), (uint256, uint256)); - assertEq(blockhash(l1HeadNumber), Hash.unwrap(gameProxy.l1Head())); - - (uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(0); - - assertEq(parentIndex, type(uint32).max); - assertEq(countered, false); - assertEq(Claim.unwrap(claim), Claim.unwrap(ROOT_CLAIM)); - assertEq(Position.unwrap(position), 1); - assertEq( - Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp)))) - ); - } - - /// @dev Tests that a move while the game status is not `IN_PROGRESS` causes the call to revert - /// with the `GameNotInProgress` error - function test_move_gameNotInProgress_reverts() public { - uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS); - - // Replace the game status in storage. It exists in slot 0 at offset 8. - uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0))); - uint256 offset = (8 << 3); - uint256 mask = 0xFF << offset; - // Replace the byte in the slot value with the challenger wins status. - slot = (slot & ~mask) | (chalWins << offset); - vm.store(address(gameProxy), bytes32(uint256(0)), bytes32(slot)); - - // Ensure that the game status was properly updated. - GameStatus status = gameProxy.status(); - assertEq(uint256(status), chalWins); - - // Attempt to make a move. Should revert. - vm.expectRevert(GameNotInProgress.selector); - gameProxy.attack(0, Claim.wrap(0)); - } - - /// @dev Tests that an attempt to defend the root claim reverts with the `CannotDefendRootClaim` error. - function test_move_defendRoot_reverts() public { - vm.expectRevert(CannotDefendRootClaim.selector); - gameProxy.defend(0, Claim.wrap(bytes32(uint256(5)))); - } - - /// @dev Tests that an attempt to move against a claim that does not exist reverts with the - /// `ParentDoesNotExist` error. - function test_move_nonExistentParent_reverts() public { - Claim claim = Claim.wrap(bytes32(uint256(5))); - - // Expect an out of bounds revert for an attack - vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x32)); - gameProxy.attack(1, claim); - - // Expect an out of bounds revert for an attack - vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x32)); - gameProxy.defend(1, claim); - } - - /// @dev Tests that an attempt to move at the maximum game depth reverts with the - /// `GameDepthExceeded` error. - function test_move_gameDepthExceeded_reverts() public { - Claim claim = Claim.wrap(bytes32(uint256(5))); - - uint256 maxDepth = gameProxy.MAX_GAME_DEPTH(); - - for (uint256 i = 0; i <= maxDepth; i++) { - // At the max game depth, the `_move` function should revert with - // the `GameDepthExceeded` error. - if (i == maxDepth) { - vm.expectRevert(GameDepthExceeded.selector); - } - gameProxy.attack(i, claim); - } - } - - /// @dev Tests that a move made after the clock time has exceeded reverts with the - /// `ClockTimeExceeded` error. - function test_move_clockTimeExceeded_reverts() public { - // Warp ahead past the clock time for the first move (3 1/2 days) - vm.warp(block.timestamp + 3 days + 12 hours + 1); - vm.expectRevert(ClockTimeExceeded.selector); - gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); - } - - /// @notice Static unit test for the correctness of the chess clock incrementation. - function test_move_clockCorrectness_succeeds() public { - (,,,, Clock clock) = gameProxy.claimData(0); - assertEq( - Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp)))) - ); - - Claim claim = Claim.wrap(bytes32(uint256(5))); - - vm.warp(block.timestamp + 15); - gameProxy.attack(0, claim); - (,,,, clock) = gameProxy.claimData(1); - assertEq( - Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(15), Timestamp.wrap(uint64(block.timestamp)))) - ); - - vm.warp(block.timestamp + 10); - gameProxy.attack(1, claim); - (,,,, clock) = gameProxy.claimData(2); - assertEq( - Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(10), Timestamp.wrap(uint64(block.timestamp)))) - ); - - vm.warp(block.timestamp + 10); - gameProxy.attack(2, claim); - (,,,, clock) = gameProxy.claimData(3); - assertEq( - Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(25), Timestamp.wrap(uint64(block.timestamp)))) - ); - - vm.warp(block.timestamp + 10); - gameProxy.attack(3, claim); - (,,,, clock) = gameProxy.claimData(4); - assertEq( - Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(20), Timestamp.wrap(uint64(block.timestamp)))) - ); - } - - /// @dev Tests that an identical claim cannot be made twice. The duplicate claim attempt should - /// revert with the `ClaimAlreadyExists` error. - function test_move_duplicateClaim_reverts() public { - Claim claim = Claim.wrap(bytes32(uint256(5))); - - // Make the first move. This should succeed. - gameProxy.attack(0, claim); - - // Attempt to make the same move again. - vm.expectRevert(ClaimAlreadyExists.selector); - gameProxy.attack(0, claim); - } - - /// @dev Static unit test asserting that identical claims at the same position can be made in different subgames. - function test_move_duplicateClaimsDifferentSubgames_succeeds() public { - Claim claimA = Claim.wrap(bytes32(uint256(5))); - Claim claimB = Claim.wrap(bytes32(uint256(6))); - - // Make the first move. This should succeed. - gameProxy.attack(0, claimA); - gameProxy.attack(0, claimB); - - gameProxy.attack(1, claimB); - gameProxy.attack(2, claimA); - } - - /// @dev Static unit test for the correctness of an opening attack. - function test_move_simpleAttack_succeeds() public { - // Warp ahead 5 seconds. - vm.warp(block.timestamp + 5); - - Claim counter = Claim.wrap(bytes32(uint256(5))); - - // Perform the attack. - vm.expectEmit(true, true, true, false); - emit Move(0, counter, address(this)); - gameProxy.attack(0, counter); - - // Grab the claim data of the attack. - (uint32 parentIndex, bool countered, Claim claim, Position position, Clock clock) = gameProxy.claimData(1); - - // Assert correctness of the attack claim's data. - assertEq(parentIndex, 0); - assertEq(countered, false); - assertEq(Claim.unwrap(claim), Claim.unwrap(counter)); - assertEq(Position.unwrap(position), Position.unwrap(Position.wrap(1).move(true))); - assertEq( - Clock.unwrap(clock), Clock.unwrap(LibClock.wrap(Duration.wrap(5), Timestamp.wrap(uint64(block.timestamp)))) - ); - - // Grab the claim data of the parent. - (parentIndex, countered, claim, position, clock) = gameProxy.claimData(0); - - // Assert correctness of the parent claim's data. - assertEq(parentIndex, type(uint32).max); - assertEq(countered, true); - assertEq(Claim.unwrap(claim), Claim.unwrap(ROOT_CLAIM)); - assertEq(Position.unwrap(position), 1); - assertEq( - Clock.unwrap(clock), - Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp - 5)))) - ); - } - - /// @dev Static unit test for the correctness an uncontested root resolution. - function test_resolve_rootUncontested_succeeds() public { - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - gameProxy.resolveClaim(0); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); - } - - /// @dev Static unit test for the correctness an uncontested root resolution. - function test_resolve_rootUncontestedClockNotExpired_succeeds() public { - vm.warp(block.timestamp + 3 days + 12 hours); - vm.expectRevert(ClockNotExpired.selector); - gameProxy.resolveClaim(0); - } - - /// @dev Static unit test asserting that resolve reverts when the absolute root - /// subgame has not been resolved. - function test_resolve_rootUncontestedButUnresolved_reverts() public { - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - vm.expectRevert(OutOfOrderResolution.selector); - gameProxy.resolve(); - } - - /// @dev Static unit test asserting that resolve reverts when the game state is - /// not in progress. - function test_resolve_notInProgress_reverts() public { - uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS); - - // Replace the game status in storage. It exists in slot 0 at offset 8. - uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0))); - uint256 offset = (8 << 3); - uint256 mask = 0xFF << offset; - // Replace the byte in the slot value with the challenger wins status. - slot = (slot & ~mask) | (chalWins << offset); - - vm.store(address(gameProxy), bytes32(uint256(0)), bytes32(slot)); - vm.expectRevert(GameNotInProgress.selector); - gameProxy.resolveClaim(0); - } - - /// @dev Static unit test for the correctness of resolving a single attack game state. - function test_resolve_rootContested_succeeds() public { - gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); - - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - gameProxy.resolveClaim(0); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); - } - - /// @dev Static unit test for the correctness of resolving a game with a contested challenge claim. - function test_resolve_challengeContested_succeeds() public { - gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); - gameProxy.defend(1, Claim.wrap(bytes32(uint256(6)))); - - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - gameProxy.resolveClaim(1); - gameProxy.resolveClaim(0); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); - } - - /// @dev Static unit test for the correctness of resolving a game with multiplayer moves. - function test_resolve_teamDeathmatch_succeeds() public { - gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); - gameProxy.attack(0, Claim.wrap(bytes32(uint256(4)))); - gameProxy.defend(1, Claim.wrap(bytes32(uint256(6)))); - gameProxy.defend(1, Claim.wrap(bytes32(uint256(7)))); - - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - gameProxy.resolveClaim(1); - gameProxy.resolveClaim(0); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); - } - - /// @dev Static unit test for the correctness of resolving a game that reaches max game depth. - function test_resolve_stepReached_succeeds() public { - gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); - gameProxy.attack(1, Claim.wrap(bytes32(uint256(5)))); - gameProxy.attack(2, Claim.wrap(bytes32(uint256(5)))); - gameProxy.attack(3, Claim.wrap(bytes32(uint256(5)))); - - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // resolving claim at 4 isn't necessary - gameProxy.resolveClaim(3); - gameProxy.resolveClaim(2); - gameProxy.resolveClaim(1); - gameProxy.resolveClaim(0); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); - } - - /// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame multiple times - function test_resolve_claimAlreadyResolved_reverts() public { - gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); - gameProxy.attack(1, Claim.wrap(bytes32(uint256(5)))); - - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - gameProxy.resolveClaim(1); - vm.expectRevert(ClaimAlreadyResolved.selector); - gameProxy.resolveClaim(1); - } - - /// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame at max depth - function test_resolve_claimAtMaxDepthAlreadyResolved_reverts() public { - gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); - gameProxy.attack(1, Claim.wrap(bytes32(uint256(5)))); - gameProxy.attack(2, Claim.wrap(bytes32(uint256(5)))); - gameProxy.attack(3, Claim.wrap(bytes32(uint256(5)))); - - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - vm.expectRevert(ClaimAlreadyResolved.selector); - gameProxy.resolveClaim(4); - } - - /// @dev Static unit test asserting that resolve reverts when attempting to resolve subgames out of order - function test_resolve_outOfOrderResolution_reverts() public { - gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); - gameProxy.attack(1, Claim.wrap(bytes32(uint256(5)))); - - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - vm.expectRevert(OutOfOrderResolution.selector); - gameProxy.resolveClaim(0); - } - - /// @dev Tests that adding local data with an out of bounds identifier reverts. - function testFuzz_addLocalData_oob_reverts(uint256 _ident, uint256 _localContext) public { - // [1, 5] are valid local data identifiers. - if (_ident <= 5) _ident = 0; - - vm.expectRevert(InvalidLocalIdent.selector); - gameProxy.addLocalData(_ident, _localContext, 0); - } - - /// @dev Tests that local data is loaded into the preimage oracle correctly. - function test_addLocalData_static_succeeds() public { - IPreimageOracle oracle = IPreimageOracle(address(gameProxy.VM().oracle())); - (FaultDisputeGame.OutputProposal memory starting, FaultDisputeGame.OutputProposal memory disputed) = - gameProxy.proposals(); - - bytes32[5] memory data = [ - Hash.unwrap(gameProxy.l1Head()), - Hash.unwrap(starting.outputRoot), - Hash.unwrap(disputed.outputRoot), - bytes32(uint256(starting.l2BlockNumber) << 0xC0), - bytes32(block.chainid << 0xC0) - ]; - - for (uint256 i = 1; i <= 5; i++) { - uint256 expectedLen = i > 3 ? 8 : 32; - - gameProxy.addLocalData(i, 0, 0); - bytes32 key = _getKey(i, 0); - (bytes32 dat, uint256 datLen) = oracle.readPreimage(key, 0); - assertEq(dat >> 0xC0, bytes32(expectedLen)); - // Account for the length prefix if i > 3 (the data stored - // at identifiers i <= 3 are 32 bytes long, so the expected - // length is already correct. If i > 3, the data is only 8 - // bytes long, so the length prefix + the data is 16 bytes - // total.) - assertEq(datLen, expectedLen + (i > 3 ? 8 : 0)); - - gameProxy.addLocalData(i, 0, 8); - key = _getKey(i, 0); - (dat, datLen) = oracle.readPreimage(key, 8); - assertEq(dat, data[i - 1]); - assertEq(datLen, expectedLen); - } - } - - /// @dev Helper to get the localized key for an identifier in the context of the game proxy. - function _getKey(uint256 _ident, uint256 _localContext) internal view returns (bytes32) { - bytes32 h = keccak256(abi.encode(_ident | (1 << 248), address(gameProxy), _localContext)); - return bytes32((uint256(h) & ~uint256(0xFF << 248)) | (1 << 248)); - } - - function changeClaimStatus(Claim _claim, VMStatus _status) public pure returns (Claim out_) { - assembly { - out_ := or(and(not(shl(248, 0xFF)), _claim), shl(248, _status)) - } - } -} - -/// @notice A generic game player actor with a configurable trace. -/// @dev This actor always responds rationally with respect to their trace. The -/// `play` function can be overridden to change this behavior. -contract GamePlayer { - bool public failedToStep; - FaultDisputeGame public gameProxy; - bytes public trace; - - GamePlayer internal counterParty; - Vm internal vm; - uint256 internal maxDepth; - - /// @notice Initializes the player - function init(FaultDisputeGame _gameProxy, GamePlayer _counterParty, Vm _vm) public { - gameProxy = _gameProxy; - counterParty = _counterParty; - vm = _vm; - maxDepth = _gameProxy.MAX_GAME_DEPTH(); - } - - /// @notice Perform the next move in the game. - function play(uint256 _parentIndex) public virtual { - // Grab the claim data at the parent index. - (uint32 grandparentIndex,, Claim parentClaim, Position parentPos,) = gameProxy.claimData(_parentIndex); - - // The position to move to. - Position movePos; - // May or may not be used. - Position movePos2; - // Signifies whether the move is an attack or not. - bool isAttack; - - if (grandparentIndex == type(uint32).max) { - // If the parent claim is the root claim, begin by attacking. - movePos = parentPos.move(true); - // Flag the move as an attack. - isAttack = true; - } else { - // If the parent claim is not the root claim, check if we disagree with it and/or its grandparent - // to determine our next move(s). - - // Fetch our claim at the parent's position. - Claim ourParentClaim = claimAt(parentPos); - - // Fetch our claim at the grandparent's position. - (,, Claim grandparentClaim, Position grandparentPos,) = gameProxy.claimData(grandparentIndex); - Claim ourGrandparentClaim = claimAt(grandparentPos); - - if (Claim.unwrap(ourParentClaim) != Claim.unwrap(parentClaim)) { - // Attack parent. - movePos = parentPos.move(true); - // If we also disagree with the grandparent, attack it as well. - if (Claim.unwrap(ourGrandparentClaim) != Claim.unwrap(grandparentClaim)) { - movePos2 = grandparentPos.move(true); - } - - // Flag the move as an attack. - isAttack = true; - } else if ( - Claim.unwrap(ourParentClaim) == Claim.unwrap(parentClaim) - && Claim.unwrap(ourGrandparentClaim) == Claim.unwrap(grandparentClaim) - ) { - movePos = parentPos.move(false); - } - } - - // If we are past the maximum depth, break the recursion and step. - if (movePos.depth() > maxDepth) { - bytes memory preStateTrace; - - // First, we need to find the pre/post state index depending on whether we - // are making an attack step or a defense step. If the index at depth of the - // move position is 0, the prestate is the absolute prestate and we need to - // do nothing. - if (movePos.indexAtDepth() > 0) { - Position leafPos = isAttack - ? Position.wrap(Position.unwrap(parentPos) - 1) - : Position.wrap(Position.unwrap(parentPos) + 1); - Position statePos = leafPos.traceAncestor(); - - // Grab the trace up to the prestate's trace index. - if (isAttack) { - preStateTrace = abi.encode(statePos.traceIndex(maxDepth), traceAt(statePos)); - } else { - preStateTrace = abi.encode(parentPos.traceIndex(maxDepth), traceAt(parentPos)); - } - } else { - preStateTrace = abi.encode(15); - } - - // Perform the step and halt recursion. - try gameProxy.step(_parentIndex, isAttack, preStateTrace, hex"") { - // Do nothing, step succeeded. - } catch { - failedToStep = true; - } - } else { - // Find the trace index that our next claim must commit to. - uint256 traceIndex = movePos.traceIndex(maxDepth); - // Grab the claim that we need to make from the helper. - Claim ourClaim = claimAt(traceIndex); - - if (isAttack) { - // Attack the parent claim. - gameProxy.attack(_parentIndex, ourClaim); - // Call out to our counter party to respond. - counterParty.play(gameProxy.claimDataLen() - 1); - - // If we have a second move position, attack the grandparent. - if (Position.unwrap(movePos2) != 0) { - (,,, Position grandparentPos,) = gameProxy.claimData(grandparentIndex); - Claim ourGrandparentClaim = claimAt(grandparentPos.move(true)); - - gameProxy.attack(grandparentIndex, ourGrandparentClaim); - counterParty.play(gameProxy.claimDataLen() - 1); - } - } else { - // Don't defend a claim we would've made ourselves. - if (parentPos.depth() % 2 == 0 && Claim.unwrap(claimAt(15)) == Claim.unwrap(gameProxy.rootClaim())) { - return; - } - - // Defend the parent claim. - gameProxy.defend(_parentIndex, ourClaim); - // Call out to our counter party to respond. - counterParty.play(gameProxy.claimDataLen() - 1); - } - } - } - - /// @notice Returns the state at the trace index within the player's trace. - function traceAt(Position _position) public view returns (uint256 state_) { - return traceAt(_position.traceIndex(maxDepth)); - } - - /// @notice Returns the state at the trace index within the player's trace. - function traceAt(uint256 _traceIndex) public view returns (uint256 state_) { - return uint256(uint8(_traceIndex >= trace.length ? trace[trace.length - 1] : trace[_traceIndex])); - } - - /// @notice Returns the player's claim that commits to a given trace index. - function claimAt(uint256 _traceIndex) public view returns (Claim claim_) { - bytes32 hash = - keccak256(abi.encode(_traceIndex >= trace.length ? trace.length - 1 : _traceIndex, traceAt(_traceIndex))); - assembly { - claim_ := or(and(hash, not(shl(248, 0xFF))), shl(248, 1)) - } - } - - /// @notice Returns the player's claim that commits to a given trace index. - function claimAt(Position _position) public view returns (Claim claim_) { - return claimAt(_position.traceIndex(maxDepth)); - } -} - -contract Resolver { - FaultDisputeGame public gameProxy; - - mapping(uint256 => bool) subgames; - - constructor(FaultDisputeGame gameProxy_) { - gameProxy = gameProxy_; - } - - /// @notice Auto-resolves all subgames in the game - function run() public { - for (uint256 i = gameProxy.claimDataLen() - 1; i > 0; i--) { - (uint32 parentIndex,,,,) = gameProxy.claimData(i); - subgames[parentIndex] = true; - - // Subgames containing only one node are implicitly resolved - // i.e. uncountered claims and claims at MAX_DEPTH - if (!subgames[i]) { - continue; - } - - gameProxy.resolveClaim(i); - } - gameProxy.resolveClaim(0); - } -} - -contract OneVsOne_Arena is FaultDisputeGame_Init { - /// @dev The absolute prestate of the trace. - bytes ABSOLUTE_PRESTATE = abi.encode(15); - /// @dev The absolute prestate claim. - Claim internal constant ABSOLUTE_PRESTATE_CLAIM = - Claim.wrap(bytes32((uint256(3) << 248) | (~uint256(0xFF << 248) & uint256(keccak256(abi.encode(15)))))); - /// @dev The defender. - GamePlayer internal defender; - /// @dev The challenger. - GamePlayer internal challenger; - /// @dev The resolver. - Resolver internal resolver; - - function init(GamePlayer _defender, GamePlayer _challenger, uint256 _finalTraceIndex) public { - Claim rootClaim = _defender.claimAt(_finalTraceIndex); - super.init(rootClaim, ABSOLUTE_PRESTATE_CLAIM); - defender = _defender; - challenger = _challenger; - resolver = new Resolver(gameProxy); - - // Set the counterparties. - defender.init(gameProxy, challenger, vm); - challenger.init(gameProxy, defender, vm); - - // Label actors for trace. - vm.label(address(challenger), "Challenger"); - vm.label(address(defender), "Defender"); - vm.label(address(resolver), "Resolver"); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1 is OneVsOne_Arena { - function setUp() public override { - super.setUp(); - GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 0); - super.init(dishonest, honest, 15); - } - - function test_resolvesCorrectly_succeeds() public { - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the honest player challenged the root - // claim successfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); - assertFalse(defender.failedToStep()); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot1 is OneVsOne_Arena { - function setUp() public override { - super.setUp(); - GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 0); - super.init(honest, dishonest, 15); - } - - function test_resolvesCorrectly_succeeds() public { - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the dishonest player challenged the root - // claim unsuccessfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); - assertTrue(challenger.failedToStep()); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2 is OneVsOne_Arena { - function setUp() public override { - super.setUp(); - GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 7); - super.init(dishonest, honest, 15); - } - - function test_resolvesCorrectly_succeeds() public { - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the honest player challenged the root - // claim successfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); - assertFalse(defender.failedToStep()); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena { - function setUp() public override { - super.setUp(); - GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 7); - super.init(honest, dishonest, 15); - } - - function test_resolvesCorrectly_succeeds() public { - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the dishonest player challenged the root - // claim unsuccessfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); - assertTrue(challenger.failedToStep()); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3 is OneVsOne_Arena { - function setUp() public override { - super.setUp(); - GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 2); - super.init(dishonest, honest, 15); - } - - function test_resolvesCorrectly_succeeds() public { - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the honest player challenged the root - // claim successfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); - assertFalse(defender.failedToStep()); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot3 is OneVsOne_Arena { - function setUp() public override { - super.setUp(); - GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 16, 2); - super.init(honest, dishonest, 15); - } - - function test_resolvesCorrectly_succeeds() public { - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the dishonest player challenged the root - // claim unsuccessfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); - assertTrue(challenger.failedToStep()); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4 is OneVsOne_Arena { - function setUp() public override { - super.setUp(); - GamePlayer honest = new HonestPlayer_HalfTrace(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 8, 5); - super.init(dishonest, honest, 7); - } - - function test_resolvesCorrectly_succeeds() public { - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the honest player challenged the root - // claim successfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); - assertFalse(challenger.failedToStep()); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot4 is OneVsOne_Arena { - function setUp() public override { - super.setUp(); - GamePlayer honest = new HonestPlayer_HalfTrace(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 8, 5); - super.init(honest, dishonest, 7); - } - - function test_resolvesCorrectly_succeeds() public { - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the dishonest player challenged the root - // claim unsuccessfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); - assertTrue(challenger.failedToStep()); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5 is OneVsOne_Arena { - function setUp() public override { - super.setUp(); - GamePlayer honest = new HonestPlayer_QuarterTrace(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 4, 3); - super.init(dishonest, honest, 3); - } - - function test_resolvesCorrectly_succeeds() public { - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the honest player challenged the root - // claim successfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); - assertFalse(challenger.failedToStep()); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot5 is OneVsOne_Arena { - function setUp() public override { - super.setUp(); - GamePlayer honest = new HonestPlayer_QuarterTrace(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer(ABSOLUTE_PRESTATE, 4, 3); - super.init(honest, dishonest, 3); - } - - function test_resolvesCorrectly_succeeds() public { - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the dishonest player challenged the root - // claim unsuccessfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); - assertTrue(challenger.failedToStep()); - } -} - -contract FaultDisputeGame_ResolvesCorrectly_IncorrectRootFuzz is OneVsOne_Arena { - function testFuzz_resolvesCorrectly_succeeds(uint256 _dishonestTraceLength) public { - _dishonestTraceLength = bound(_dishonestTraceLength, 1, 16); - - for (uint256 i = 0; i < _dishonestTraceLength; i++) { - uint256 snapshot = vm.snapshot(); - - GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer( - ABSOLUTE_PRESTATE, - _dishonestTraceLength, - i - ); - super.init(dishonest, honest, _dishonestTraceLength - 1); - - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the honest player challenged the root - // claim successfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); - assertFalse(defender.failedToStep()); - - vm.revertTo(snapshot); - } - } -} - -contract FaultDisputeGame_ResolvesCorrectly_CorrectRootFuzz is OneVsOne_Arena { - function testFuzz_resolvesCorrectly_succeeds(uint256 _dishonestTraceLength) public { - _dishonestTraceLength = bound(_dishonestTraceLength, 1, 16); - for (uint256 i = 0; i < _dishonestTraceLength; i++) { - uint256 snapshot = vm.snapshot(); - - GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); - GamePlayer dishonest = new VariableDivergentPlayer( - ABSOLUTE_PRESTATE, - _dishonestTraceLength, - i - ); - super.init(honest, dishonest, 15); - - // Play the game until a step is forced. - challenger.play(0); - - // Warp ahead to expire the other player's clock. - vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); - - // Resolve the game and assert that the honest player challenged the root - // claim successfully. - resolver.run(); - assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); - assertTrue(challenger.failedToStep()); - - vm.revertTo(snapshot); - } - } -} - -//////////////////////////////////////////////////////////////// -// ACTORS // -//////////////////////////////////////////////////////////////// - -contract HonestPlayer is GamePlayer { - constructor(bytes memory _absolutePrestate) { - uint8 absolutePrestate = uint8(_absolutePrestate[31]); - bytes memory honestTrace = new bytes(16); - for (uint8 i = 0; i < honestTrace.length; i++) { - honestTrace[i] = bytes1(absolutePrestate + i + 1); - } - trace = honestTrace; - } -} - -contract HonestPlayer_HalfTrace is GamePlayer { - constructor(bytes memory _absolutePrestate) { - uint8 absolutePrestate = uint8(_absolutePrestate[31]); - bytes memory halfTrace = new bytes(8); - for (uint8 i = 0; i < halfTrace.length; i++) { - halfTrace[i] = bytes1(absolutePrestate + i + 1); - } - trace = halfTrace; - } -} - -contract HonestPlayer_QuarterTrace is GamePlayer { - constructor(bytes memory _absolutePrestate) { - uint8 absolutePrestate = uint8(_absolutePrestate[31]); - bytes memory halfTrace = new bytes(4); - for (uint8 i = 0; i < halfTrace.length; i++) { - halfTrace[i] = bytes1(absolutePrestate + i + 1); - } - trace = halfTrace; - } -} - -contract VariableDivergentPlayer is GamePlayer { - constructor(bytes memory _absolutePrestate, uint256 _traceLength, uint256 _divergeAt) { - uint8 absolutePrestate = uint8(_absolutePrestate[31]); - bytes memory _trace = new bytes(_traceLength); - for (uint8 i = 0; i < _trace.length; i++) { - // Diverge at trace instruction `_divergeAt`. - _trace[i] = i >= _divergeAt ? bytes1(i) : bytes1(absolutePrestate + i + 1); - } - trace = _trace; - } -} - -//////////////////////////////////////////////////////////////// -// MOCK VMS // -//////////////////////////////////////////////////////////////// - -contract AlphabetVM is IBigStepper { - Claim internal immutable ABSOLUTE_PRESTATE; - IPreimageOracle public oracle; - - constructor(Claim _absolutePrestate) { - ABSOLUTE_PRESTATE = _absolutePrestate; - oracle = new PreimageOracle(); - } - - /// @inheritdoc IBigStepper - function step(bytes calldata _stateData, bytes calldata, uint256) external view returns (bytes32 postState_) { - uint256 traceIndex; - uint256 claim; - if ((keccak256(_stateData) << 8) == (Claim.unwrap(ABSOLUTE_PRESTATE) << 8)) { - // If the state data is empty, then the absolute prestate is the claim. - traceIndex = 0; - (claim) = abi.decode(_stateData, (uint256)); - } else { - // Otherwise, decode the state data. - (traceIndex, claim) = abi.decode(_stateData, (uint256, uint256)); - traceIndex++; - } - // STF: n -> n + 1 - postState_ = keccak256(abi.encode(traceIndex, claim + 1)); - assembly { - postState_ := or(and(postState_, not(shl(248, 0xFF))), shl(248, 1)) - } - } -} diff --git a/packages/contracts-bedrock/test/FeeVault.t.sol b/packages/contracts-bedrock/test/FeeVault.t.sol deleted file mode 100644 index 3b877840935c..000000000000 --- a/packages/contracts-bedrock/test/FeeVault.t.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { Bridge_Initializer } from "test/CommonTest.t.sol"; -import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; - -// Libraries -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract dependencies -import { FeeVault } from "src/universal/FeeVault.sol"; - -// Target contract -import { L1FeeVault } from "src/L2/L1FeeVault.sol"; - -// Test the implementations of the FeeVault -contract FeeVault_Test is Bridge_Initializer { - BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); - L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); - - uint256 constant otherMinimumWithdrawalAmount = 10 ether; - - /// @dev Sets up the test suite. - function setUp() public override { - super.setUp(); - vm.etch( - Predeploys.BASE_FEE_VAULT, - address(new BaseFeeVault(alice, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1)).code - ); - vm.etch( - Predeploys.L1_FEE_VAULT, - address(new L1FeeVault(bob, otherMinimumWithdrawalAmount, FeeVault.WithdrawalNetwork.L2)).code - ); - - vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault"); - vm.label(Predeploys.L1_FEE_VAULT, "L1FeeVault"); - } - - /// @dev Tests that the constructor sets the correct values. - function test_constructor_succeeds() external { - assertEq(baseFeeVault.RECIPIENT(), alice); - assertEq(l1FeeVault.RECIPIENT(), bob); - assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), NON_ZERO_VALUE); - assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), otherMinimumWithdrawalAmount); - assertEq(uint8(baseFeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L1)); - assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L2)); - } -} diff --git a/packages/contracts-bedrock/test/GasPriceOracle.t.sol b/packages/contracts-bedrock/test/GasPriceOracle.t.sol deleted file mode 100644 index 26e571ecb550..000000000000 --- a/packages/contracts-bedrock/test/GasPriceOracle.t.sol +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; - -// Target contract dependencies -import { L1Block } from "src/L2/L1Block.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract -import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; - -contract GasPriceOracle_Test is CommonTest { - event OverheadUpdated(uint256); - event ScalarUpdated(uint256); - event DecimalsUpdated(uint256); - - GasPriceOracle gasOracle; - L1Block l1Block; - address depositor; - - // The initial L1 context values - uint64 constant number = 10; - uint64 constant timestamp = 11; - uint256 constant basefee = 100; - bytes32 constant hash = bytes32(uint256(64)); - uint64 constant sequenceNumber = 0; - bytes32 constant batcherHash = bytes32(uint256(777)); - uint256 constant l1FeeOverhead = 310; - uint256 constant l1FeeScalar = 10; - - /// @dev Sets up the test suite. - function setUp() public virtual override { - super.setUp(); - // place the L1Block contract at the predeploy address - vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code); - - l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); - depositor = l1Block.DEPOSITOR_ACCOUNT(); - - // We are not setting the gas oracle at its predeploy - // address for simplicity purposes. Nothing in this test - // requires it to be at a particular address - gasOracle = new GasPriceOracle(); - - vm.prank(depositor); - l1Block.setL1BlockValues({ - _number: number, - _timestamp: timestamp, - _basefee: basefee, - _hash: hash, - _sequenceNumber: sequenceNumber, - _batcherHash: batcherHash, - _l1FeeOverhead: l1FeeOverhead, - _l1FeeScalar: l1FeeScalar - }); - } - - /// @dev Tests that `l1BaseFee` is set correctly. - function test_l1BaseFee_succeeds() external { - assertEq(gasOracle.l1BaseFee(), basefee); - } - - /// @dev Tests that `gasPrice` is set correctly. - function test_gasPrice_succeeds() external { - vm.fee(100); - uint256 gasPrice = gasOracle.gasPrice(); - assertEq(gasPrice, 100); - } - - /// @dev Tests that `baseFee` is set correctly. - function test_baseFee_succeeds() external { - vm.fee(64); - uint256 gasPrice = gasOracle.baseFee(); - assertEq(gasPrice, 64); - } - - /// @dev Tests that `scalar` is set correctly. - function test_scalar_succeeds() external { - assertEq(gasOracle.scalar(), l1FeeScalar); - } - - /// @dev Tests that `overhead` is set correctly. - function test_overhead_succeeds() external { - assertEq(gasOracle.overhead(), l1FeeOverhead); - } - - /// @dev Tests that `decimals` is set correctly. - function test_decimals_succeeds() external { - assertEq(gasOracle.decimals(), 6); - assertEq(gasOracle.DECIMALS(), 6); - } - - /// @dev Tests that `setGasPrice` reverts since it was removed in bedrock. - function test_setGasPrice_doesNotExist_reverts() external { - (bool success, bytes memory returndata) = - address(gasOracle).call(abi.encodeWithSignature("setGasPrice(uint256)", 1)); - - assertEq(success, false); - assertEq(returndata, hex""); - } - - /// @dev Tests that `setL1BaseFee` reverts since it was removed in bedrock. - function test_setL1BaseFee_doesNotExist_reverts() external { - (bool success, bytes memory returndata) = - address(gasOracle).call(abi.encodeWithSignature("setL1BaseFee(uint256)", 1)); - - assertEq(success, false); - assertEq(returndata, hex""); - } -} diff --git a/packages/contracts-bedrock/test/GovernanceToken.t.sol b/packages/contracts-bedrock/test/GovernanceToken.t.sol deleted file mode 100644 index ec3c7902af7e..000000000000 --- a/packages/contracts-bedrock/test/GovernanceToken.t.sol +++ /dev/null @@ -1,173 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; - -// Target contract -import { GovernanceToken } from "src/governance/GovernanceToken.sol"; - -contract GovernanceToken_Test is CommonTest { - address constant owner = address(0x1234); - address constant rando = address(0x5678); - GovernanceToken internal gov; - - /// @dev Sets up the test suite. - function setUp() public virtual override { - super.setUp(); - vm.prank(owner); - gov = new GovernanceToken(); - } - - /// @dev Tests that the constructor sets the correct initial state. - function test_constructor_succeeds() external { - assertEq(gov.owner(), owner); - assertEq(gov.name(), "Optimism"); - assertEq(gov.symbol(), "OP"); - assertEq(gov.decimals(), 18); - assertEq(gov.totalSupply(), 0); - } - - /// @dev Tests that the owner can successfully call `mint`. - function test_mint_fromOwner_succeeds() external { - // Mint 100 tokens. - vm.prank(owner); - gov.mint(owner, 100); - - // Balances have updated correctly. - assertEq(gov.balanceOf(owner), 100); - assertEq(gov.totalSupply(), 100); - } - - /// @dev Tests that `mint` reverts when called by a non-owner. - function test_mint_fromNotOwner_reverts() external { - // Mint 100 tokens as rando. - vm.prank(rando); - vm.expectRevert("Ownable: caller is not the owner"); - gov.mint(owner, 100); - - // Balance does not update. - assertEq(gov.balanceOf(owner), 0); - assertEq(gov.totalSupply(), 0); - } - - /// @dev Tests that the owner can successfully call `burn`. - function test_burn_succeeds() external { - // Mint 100 tokens to rando. - vm.prank(owner); - gov.mint(rando, 100); - - // Rando burns their tokens. - vm.prank(rando); - gov.burn(50); - - // Balances have updated correctly. - assertEq(gov.balanceOf(rando), 50); - assertEq(gov.totalSupply(), 50); - } - - /// @dev Tests that the owner can successfully call `burnFrom`. - function test_burnFrom_succeeds() external { - // Mint 100 tokens to rando. - vm.prank(owner); - gov.mint(rando, 100); - - // Rando approves owner to burn 50 tokens. - vm.prank(rando); - gov.approve(owner, 50); - - // Owner burns 50 tokens from rando. - vm.prank(owner); - gov.burnFrom(rando, 50); - - // Balances have updated correctly. - assertEq(gov.balanceOf(rando), 50); - assertEq(gov.totalSupply(), 50); - } - - /// @dev Tests that `transfer` correctly transfers tokens. - function test_transfer_succeeds() external { - // Mint 100 tokens to rando. - vm.prank(owner); - gov.mint(rando, 100); - - // Rando transfers 50 tokens to owner. - vm.prank(rando); - gov.transfer(owner, 50); - - // Balances have updated correctly. - assertEq(gov.balanceOf(owner), 50); - assertEq(gov.balanceOf(rando), 50); - assertEq(gov.totalSupply(), 100); - } - - /// @dev Tests that `approve` correctly sets allowances. - function test_approve_succeeds() external { - // Mint 100 tokens to rando. - vm.prank(owner); - gov.mint(rando, 100); - - // Rando approves owner to spend 50 tokens. - vm.prank(rando); - gov.approve(owner, 50); - - // Allowances have updated. - assertEq(gov.allowance(rando, owner), 50); - } - - /// @dev Tests that `transferFrom` correctly transfers tokens. - function test_transferFrom_succeeds() external { - // Mint 100 tokens to rando. - vm.prank(owner); - gov.mint(rando, 100); - - // Rando approves owner to spend 50 tokens. - vm.prank(rando); - gov.approve(owner, 50); - - // Owner transfers 50 tokens from rando to owner. - vm.prank(owner); - gov.transferFrom(rando, owner, 50); - - // Balances have updated correctly. - assertEq(gov.balanceOf(owner), 50); - assertEq(gov.balanceOf(rando), 50); - assertEq(gov.totalSupply(), 100); - } - - /// @dev Tests that `increaseAllowance` correctly increases allowances. - function test_increaseAllowance_succeeds() external { - // Mint 100 tokens to rando. - vm.prank(owner); - gov.mint(rando, 100); - - // Rando approves owner to spend 50 tokens. - vm.prank(rando); - gov.approve(owner, 50); - - // Rando increases allowance by 50 tokens. - vm.prank(rando); - gov.increaseAllowance(owner, 50); - - // Allowances have updated. - assertEq(gov.allowance(rando, owner), 100); - } - - /// @dev Tests that `decreaseAllowance` correctly decreases allowances. - function test_decreaseAllowance_succeeds() external { - // Mint 100 tokens to rando. - vm.prank(owner); - gov.mint(rando, 100); - - // Rando approves owner to spend 100 tokens. - vm.prank(rando); - gov.approve(owner, 100); - - // Rando decreases allowance by 50 tokens. - vm.prank(rando); - gov.decreaseAllowance(owner, 50); - - // Allowances have updated. - assertEq(gov.allowance(rando, owner), 50); - } -} diff --git a/packages/contracts-bedrock/test/Helpers.sol b/packages/contracts-bedrock/test/Helpers.sol deleted file mode 100644 index a27da6e2b2fb..000000000000 --- a/packages/contracts-bedrock/test/Helpers.sol +++ /dev/null @@ -1,221 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol"; -import { ERC721 } from "@rari-capital/solmate/src/tokens/ERC721.sol"; -import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; -import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol"; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { ECDSAUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol"; -import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; - -contract TestERC20 is ERC20 { - constructor() ERC20("TEST", "TST", 18) { } - - function mint(address to, uint256 value) public { - _mint(to, value); - } -} - -contract TestERC721 is ERC721 { - constructor() ERC721("TEST", "TST") { } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function tokenURI(uint256) public pure virtual override returns (string memory) { } -} - -contract CallRecorder { - struct CallInfo { - address sender; - bytes data; - uint256 gas; - uint256 value; - } - - CallInfo public lastCall; - - function record() public payable { - lastCall.sender = msg.sender; - lastCall.data = msg.data; - lastCall.gas = gasleft(); - lastCall.value = msg.value; - } -} - -contract Reverter { - function doRevert() public pure { - revert("Reverter reverted"); - } -} - -contract SimpleStorage { - mapping(bytes32 => bytes32) public db; - - function set(bytes32 _key, bytes32 _value) public payable { - db[_key] = _value; - } - - function get(bytes32 _key) public view returns (bytes32) { - return db[_key]; - } -} - -/// @notice Simple helper contract that helps with testing flow and signature for -/// OptimistInviter contract. Made this a separate contract instead of including -/// in OptimistInviter.t.sol for reusability. -contract OptimistInviterHelper { - /// @notice EIP712 typehash for the ClaimableInvite type. - bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = keccak256("ClaimableInvite(address issuer,bytes32 nonce)"); - - /// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature. - bytes32 public constant EIP712_DOMAIN_TYPEHASH = - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); - - /// @notice Address of OptimistInviter contract we are testing. - OptimistInviter public optimistInviter; - - /// @notice OptimistInviter contract name. Used to construct the EIP-712 domain. - string public name; - - /// @notice Keeps track of current nonce to generate new nonces for each invite. - uint256 public currentNonce; - - constructor(OptimistInviter _optimistInviter, string memory _name) { - optimistInviter = _optimistInviter; - name = _name; - } - - /// @notice Returns the hash of the struct ClaimableInvite. - /// @param _claimableInvite ClaimableInvite struct to hash. - /// @return EIP-712 typed struct hash. - function getClaimableInviteStructHash(OptimistInviter.ClaimableInvite memory _claimableInvite) - public - pure - returns (bytes32) - { - return keccak256(abi.encode(CLAIMABLE_INVITE_TYPEHASH, _claimableInvite.issuer, _claimableInvite.nonce)); - } - - /// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use - /// pseudorandom nonces. - /// @return Nonce that should be used as part of ClaimableInvite. - function consumeNonce() public returns (bytes32) { - return bytes32(keccak256(abi.encode(currentNonce++))); - } - - /// @notice Returns a ClaimableInvite with the issuer and current nonce. - /// @param _issuer Issuer to include in the ClaimableInvite. - /// @return ClaimableInvite that can be hashed & signed. - function getClaimableInviteWithNewNonce(address _issuer) public returns (OptimistInviter.ClaimableInvite memory) { - return OptimistInviter.ClaimableInvite(_issuer, consumeNonce()); - } - - /// @notice Computes the EIP712 digest with default correct parameters. - /// @param _claimableInvite ClaimableInvite struct to hash. - /// @return EIP-712 compatible digest. - function getDigest(OptimistInviter.ClaimableInvite calldata _claimableInvite) public view returns (bytes32) { - return getDigestWithEIP712Domain( - _claimableInvite, - bytes(name), - bytes(optimistInviter.EIP712_VERSION()), - block.chainid, - address(optimistInviter) - ); - } - - /// @notice Computes the EIP712 digest with the given domain parameters. - /// Used for testing that different domain parameters fail. - /// @param _claimableInvite ClaimableInvite struct to hash. - /// @param _name Contract name to use in the EIP712 domain. - /// @param _version Contract version to use in the EIP712 domain. - /// @param _chainid Chain ID to use in the EIP712 domain. - /// @param _verifyingContract Address to use in the EIP712 domain. - /// @return EIP-712 compatible digest. - function getDigestWithEIP712Domain( - OptimistInviter.ClaimableInvite calldata _claimableInvite, - bytes memory _name, - bytes memory _version, - uint256 _chainid, - address _verifyingContract - ) - public - pure - returns (bytes32) - { - bytes32 domainSeparator = keccak256( - abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract) - ); - return ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite)); - } -} - -/// @notice Simple ERC1271 wallet that can be used to test the ERC1271 signature checker. -/// @notice https://github.com/OpenZeppelin/openzeppelin-contracts/ -/// blob/master/contracts/mocks/ERC1271WalletMock.sol -contract TestERC1271Wallet is Ownable, IERC1271 { - constructor(address originalOwner) { - transferOwnership(originalOwner); - } - - function isValidSignature(bytes32 hash, bytes memory signature) public view override returns (bytes4 magicValue) { - return ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0); - } -} - -/// @notice Simple helper contract that helps with testing the Faucet contract. -contract FaucetHelper { - /// @notice EIP712 typehash for the Proof type. - bytes32 public constant PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)"); - - /// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature. - bytes32 public constant EIP712_DOMAIN_TYPEHASH = - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); - - /// @notice Keeps track of current nonce to generate new nonces for each drip. - uint256 public currentNonce; - - /// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use - /// pseudorandom nonces. - /// @return Nonce that should be used as part of drip parameters. - function consumeNonce() public returns (bytes32) { - return bytes32(keccak256(abi.encode(currentNonce++))); - } - - /// @notice Returns the hash of the struct Proof. - /// @param _proof Proof struct to hash. - /// @return EIP-712 typed struct hash. - function getProofStructHash(AdminFaucetAuthModule.Proof memory _proof) public pure returns (bytes32) { - return keccak256(abi.encode(PROOF_TYPEHASH, _proof.recipient, _proof.nonce, _proof.id)); - } - - /// @notice Computes the EIP712 digest with the given domain parameters. - /// Used for testing that different domain parameters fail. - /// @param _proof Proof struct to hash. - /// @param _name Contract name to use in the EIP712 domain. - /// @param _version Contract version to use in the EIP712 domain. - /// @param _chainid Chain ID to use in the EIP712 domain. - /// @param _verifyingContract Address to use in the EIP712 domain. - /// @param _verifyingContract Address to use in the EIP712 domain. - /// @param _verifyingContract Address to use in the EIP712 domain. - /// @return EIP-712 compatible digest. - function getDigestWithEIP712Domain( - AdminFaucetAuthModule.Proof memory _proof, - bytes memory _name, - bytes memory _version, - uint256 _chainid, - address _verifyingContract - ) - public - pure - returns (bytes32) - { - bytes32 domainSeparator = keccak256( - abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract) - ); - return ECDSAUpgradeable.toTypedDataHash(domainSeparator, getProofStructHash(_proof)); - } -} diff --git a/packages/contracts-bedrock/test/Initializable.t.sol b/packages/contracts-bedrock/test/Initializable.t.sol deleted file mode 100644 index e96989d8f680..000000000000 --- a/packages/contracts-bedrock/test/Initializable.t.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; -import { console } from "forge-std/console.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; - -/// @title Initializer_Test -/// @dev Ensures that the `initialize()` function on contracts cannot be called more than -/// once. This contract inherits from `ERC721Bridge_Initializer` because it is the -/// deepest contract in the inheritance chain for setting up the system contracts. -contract Initializer_Test is ERC721Bridge_Initializer { - function test_cannotReinitializeL1_succeeds() public { - vm.expectRevert("Initializable: contract is already initialized"); - L1Messenger.initialize(OptimismPortal(payable(address(0)))); - - vm.expectRevert("Initializable: contract is already initialized"); - L1Bridge.initialize(CrossDomainMessenger(address(0))); - - vm.expectRevert("Initializable: contract is already initialized"); - oracle.initialize(0, 0, address(0), address(0)); - - vm.expectRevert("Initializable: contract is already initialized"); - op.initialize(L2OutputOracle(address(0)), address(0), SystemConfig(address(0)), false); - - vm.expectRevert("Initializable: contract is already initialized"); - systemConfig.initialize({ - _owner: address(0xdEaD), - _overhead: 0, - _scalar: 0, - _batcherHash: bytes32(0), - _gasLimit: 1, - _unsafeBlockSigner: address(0), - _config: ResourceMetering.ResourceConfig({ - maxResourceLimit: 1, - elasticityMultiplier: 1, - baseFeeMaxChangeDenominator: 2, - minimumBaseFee: 0, - systemTxMaxGas: 0, - maximumBaseFee: 0 - }), - _startBlock: type(uint256).max, - _batchInbox: address(0), - _addresses: SystemConfig.Addresses({ - l1CrossDomainMessenger: address(0), - l1ERC721Bridge: address(0), - l1StandardBridge: address(0), - l2OutputOracle: address(0), - optimismPortal: address(0), - optimismMintableERC20Factory: address(0) - }) - }); - - vm.expectRevert("Initializable: contract is already initialized"); - L1NFTBridge.initialize(CrossDomainMessenger(address(0))); - } -} diff --git a/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol b/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol new file mode 100644 index 000000000000..34e98be77bae --- /dev/null +++ b/packages/contracts-bedrock/test/L1/DataAvailabilityChallenge.t.sol @@ -0,0 +1,534 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { + DataAvailabilityChallenge, + ChallengeStatus, + Challenge, + CommitmentType, + computeCommitmentKeccak256 +} from "src/L1/DataAvailabilityChallenge.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; + +contract DataAvailabilityChallengeTest is CommonTest { + function setUp() public virtual override { + super.enablePlasma(); + super.setUp(); + } + + function testDeposit() public { + assertEq(dataAvailabilityChallenge.balances(address(this)), 0); + dataAvailabilityChallenge.deposit{ value: 1000 }(); + assertEq(dataAvailabilityChallenge.balances(address(this)), 1000); + } + + function testReceive() public { + assertEq(dataAvailabilityChallenge.balances(address(this)), 0); + (bool success,) = payable(address(dataAvailabilityChallenge)).call{ value: 1000 }(""); + assertTrue(success); + assertEq(dataAvailabilityChallenge.balances(address(this)), 1000); + } + + function testWithdraw(address sender, uint256 amount) public { + assumePayable(sender); + assumeNotPrecompile(sender); + vm.assume(sender != address(dataAvailabilityChallenge)); + vm.assume(sender.balance == 0); + vm.deal(sender, amount); + + vm.prank(sender); + dataAvailabilityChallenge.deposit{ value: amount }(); + + assertEq(dataAvailabilityChallenge.balances(sender), amount); + assertEq(sender.balance, 0); + + vm.prank(sender); + dataAvailabilityChallenge.withdraw(); + + assertEq(dataAvailabilityChallenge.balances(sender), 0); + assertEq(sender.balance, amount); + } + + function testChallengeSuccess(address challenger, uint256 challengedBlockNumber, bytes calldata preImage) public { + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + + // Assume the challenger is not the 0 address + vm.assume(challenger != address(0)); + + // Assume the block number is not close to the max uint256 value + vm.assume( + challengedBlockNumber + < type(uint256).max - dataAvailabilityChallenge.challengeWindow() + - dataAvailabilityChallenge.resolveWindow() + ); + uint256 requiredBond = dataAvailabilityChallenge.bondSize(); + + // Move to a block after the challenged block + vm.roll(challengedBlockNumber + 1); + + // Deposit the required bond + vm.deal(challenger, requiredBond); + vm.prank(challenger); + dataAvailabilityChallenge.deposit{ value: requiredBond }(); + + // Expect the challenge status to be uninitialized + assertEq( + uint8(dataAvailabilityChallenge.getChallengeStatus(challengedBlockNumber, challengedCommitment)), + uint8(ChallengeStatus.Uninitialized) + ); + + // Challenge a (blockNumber,hash) tuple + vm.prank(challenger); + dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); + + // Challenge should have been created + Challenge memory challenge = dataAvailabilityChallenge.getChallenge(challengedBlockNumber, challengedCommitment); + assertEq(challenge.challenger, challenger); + assertEq(challenge.startBlock, block.number); + assertEq(challenge.resolvedBlock, 0); + assertEq(challenge.lockedBond, requiredBond); + assertEq( + uint8(dataAvailabilityChallenge.getChallengeStatus(challengedBlockNumber, challengedCommitment)), + uint8(ChallengeStatus.Active) + ); + + // Challenge should have decreased the challenger's bond size + assertEq(dataAvailabilityChallenge.balances(challenger), 0); + } + + function testChallengeDeposit(address challenger, uint256 challengedBlockNumber, bytes memory preImage) public { + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + + // Assume the challenger is not the 0 address + vm.assume(challenger != address(0)); + + // Assume the block number is not close to the max uint256 value + vm.assume( + challengedBlockNumber + < type(uint256).max - dataAvailabilityChallenge.challengeWindow() + - dataAvailabilityChallenge.resolveWindow() + ); + uint256 requiredBond = dataAvailabilityChallenge.bondSize(); + + // Move to a block after the challenged block + vm.roll(challengedBlockNumber + 1); + + // Expect the challenge status to be uninitialized + assertEq( + uint8(dataAvailabilityChallenge.getChallengeStatus(challengedBlockNumber, challengedCommitment)), + uint8(ChallengeStatus.Uninitialized) + ); + + // Deposit the required bond as part of the challenge transaction + vm.deal(challenger, requiredBond); + vm.prank(challenger); + dataAvailabilityChallenge.challenge{ value: requiredBond }(challengedBlockNumber, challengedCommitment); + + // Challenge should have been created + Challenge memory challenge = dataAvailabilityChallenge.getChallenge(challengedBlockNumber, challengedCommitment); + assertEq(challenge.challenger, challenger); + assertEq(challenge.startBlock, block.number); + assertEq(challenge.resolvedBlock, 0); + assertEq(challenge.lockedBond, requiredBond); + assertEq( + uint8(dataAvailabilityChallenge.getChallengeStatus(challengedBlockNumber, challengedCommitment)), + uint8(ChallengeStatus.Active) + ); + + // Challenge should have decreased the challenger's bond size + assertEq(dataAvailabilityChallenge.balances(challenger), 0); + } + + function testChallengeFailBondTooLow() public { + uint256 requiredBond = dataAvailabilityChallenge.bondSize(); + uint256 actualBond = requiredBond - 1; + dataAvailabilityChallenge.deposit{ value: actualBond }(); + + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.BondTooLow.selector, actualBond, requiredBond)); + dataAvailabilityChallenge.challenge(0, computeCommitmentKeccak256("some hash")); + } + + function testChallengeFailChallengeExists() public { + // Move to a block after the hash to challenge + vm.roll(2); + + // First challenge succeeds + bytes memory challengedCommitment = computeCommitmentKeccak256("some data"); + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + dataAvailabilityChallenge.challenge(0, challengedCommitment); + + // Second challenge of the same hash/blockNumber fails + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeExists.selector)); + dataAvailabilityChallenge.challenge(0, challengedCommitment); + + // Challenge succeed if the challenged block number is different + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + dataAvailabilityChallenge.challenge(1, challengedCommitment); + + // Challenge succeed if the challenged hash is different + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + dataAvailabilityChallenge.challenge(0, computeCommitmentKeccak256("some other hash")); + } + + function testChallengeFailBeforeChallengeWindow() public { + uint256 challengedBlockNumber = 1; + bytes memory challengedCommitment = computeCommitmentKeccak256("some hash"); + + // Move to challenged block + vm.roll(challengedBlockNumber - 1); + + // Challenge fails because the current block number must be after the challenged block + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeWindowNotOpen.selector)); + dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); + } + + function testChallengeFailAfterChallengeWindow() public { + uint256 challengedBlockNumber = 1; + bytes memory challengedCommitment = computeCommitmentKeccak256("some hash"); + + // Move to block after the challenge window + vm.roll(challengedBlockNumber + dataAvailabilityChallenge.challengeWindow() + 1); + + // Challenge fails because the block number is after the challenge window + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeWindowNotOpen.selector)); + dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); + } + + function testResolveSuccess( + address challenger, + address resolver, + bytes memory preImage, + uint256 challengedBlockNumber, + uint256 resolverRefundPercentage, + uint128 txGasPrice + ) + public + { + // Assume neither the challenger nor resolver is address(0) and that they're not the same entity + vm.assume(challenger != address(0)); + vm.assume(resolver != address(0)); + vm.assume(challenger != resolver); + + // Bound the resolver refund percentage to 100 + resolverRefundPercentage = bound(resolverRefundPercentage, 0, 100); + + // Set the gas price to a fuzzed value to test bond distribution logic + vm.txGasPrice(txGasPrice); + + // Change the resolver refund percentage + vm.prank(dataAvailabilityChallenge.owner()); + dataAvailabilityChallenge.setResolverRefundPercentage(resolverRefundPercentage); + + // Assume the block number is not close to the max uint256 value + vm.assume( + challengedBlockNumber + < type(uint256).max - dataAvailabilityChallenge.challengeWindow() + - dataAvailabilityChallenge.resolveWindow() + ); + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + + // Move to block after challenged block + vm.roll(challengedBlockNumber + 1); + + // Challenge the hash + uint256 bondSize = dataAvailabilityChallenge.bondSize(); + vm.deal(challenger, bondSize); + vm.prank(challenger); + dataAvailabilityChallenge.challenge{ value: bondSize }(challengedBlockNumber, challengedCommitment); + + // Store the address(0) balance before resolving to assert the burned amount later + uint256 zeroAddressBalanceBeforeResolve = address(0).balance; + + // Resolve the challenge + vm.prank(resolver); + dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); + + // Expect the challenge to be resolved + Challenge memory challenge = dataAvailabilityChallenge.getChallenge(challengedBlockNumber, challengedCommitment); + + assertEq(challenge.challenger, challenger); + assertEq(challenge.lockedBond, 0); + assertEq(challenge.startBlock, block.number); + assertEq(challenge.resolvedBlock, block.number); + assertEq( + uint8(dataAvailabilityChallenge.getChallengeStatus(challengedBlockNumber, challengedCommitment)), + uint8(ChallengeStatus.Resolved) + ); + + // Assert challenger balance after bond distribution + uint256 resolutionCost = ( + dataAvailabilityChallenge.fixedResolutionCost() + + preImage.length * dataAvailabilityChallenge.variableResolutionCost() + / dataAvailabilityChallenge.variableResolutionCostPrecision() + ) * block.basefee; + uint256 challengerRefund = bondSize > resolutionCost ? bondSize - resolutionCost : 0; + assertEq(dataAvailabilityChallenge.balances(challenger), challengerRefund, "challenger refund"); + + // Assert resolver balance after bond distribution + uint256 resolverRefund = resolutionCost * dataAvailabilityChallenge.resolverRefundPercentage() / 100; + resolverRefund = resolverRefund > resolutionCost ? resolutionCost : resolverRefund; + resolverRefund = resolverRefund > bondSize ? bondSize : resolverRefund; + assertEq(dataAvailabilityChallenge.balances(resolver), resolverRefund, "resolver refund"); + + // Assert burned amount after bond distribution + uint256 burned = bondSize - challengerRefund - resolverRefund; + assertEq(address(0).balance - zeroAddressBalanceBeforeResolve, burned, "burned bond"); + } + + function testResolveFailNonExistentChallenge() public { + bytes memory preImage = "some preimage"; + uint256 challengedBlockNumber = 1; + + // Move to block after challenged block + vm.roll(challengedBlockNumber + 1); + + // Resolving a non-existent challenge fails + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotActive.selector)); + dataAvailabilityChallenge.resolve(challengedBlockNumber, computeCommitmentKeccak256(preImage), preImage); + } + + function testResolveFailResolved() public { + bytes memory preImage = "some preimage"; + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + uint256 challengedBlockNumber = 1; + + // Move to block after challenged block + vm.roll(challengedBlockNumber + 1); + + // Challenge the hash + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); + + // Resolve the challenge + dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); + + // Resolving an already resolved challenge fails + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotActive.selector)); + dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); + } + + function testResolveFailExpired() public { + bytes memory preImage = "some preimage"; + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + uint256 challengedBlockNumber = 1; + + // Move to block after challenged block + vm.roll(challengedBlockNumber + 1); + + // Challenge the hash + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); + + // Move to a block after the resolve window + vm.roll(block.number + dataAvailabilityChallenge.resolveWindow() + 1); + + // Resolving an expired challenge fails + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotActive.selector)); + dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); + } + + function testResolveFailAfterResolveWindow() public { + bytes memory preImage = "some preimage"; + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + uint256 challengedBlockNumber = 1; + + // Move to block after challenged block + vm.roll(challengedBlockNumber + 1); + + // Challenge the hash + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); + + // Move to block after resolve window + vm.roll(block.number + dataAvailabilityChallenge.resolveWindow() + 1); + + // Resolve the challenge + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotActive.selector)); + dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); + } + + function testUnlockBondSuccess(bytes memory preImage, uint256 challengedBlockNumber) public { + // Assume the block number is not close to the max uint256 value + vm.assume( + challengedBlockNumber + < type(uint256).max - dataAvailabilityChallenge.challengeWindow() + - dataAvailabilityChallenge.resolveWindow() + ); + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + + // Move to block after challenged block + vm.roll(challengedBlockNumber + 1); + + // Challenge the hash + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); + + // Move to a block after the resolve window + vm.roll(block.number + dataAvailabilityChallenge.resolveWindow() + 1); + + uint256 balanceBeforeUnlock = dataAvailabilityChallenge.balances(address(this)); + + // Unlock the bond associated with the challenge + dataAvailabilityChallenge.unlockBond(challengedBlockNumber, challengedCommitment); + + // Expect the balance to be increased by the bond size + uint256 balanceAfterUnlock = dataAvailabilityChallenge.balances(address(this)); + assertEq(balanceAfterUnlock, balanceBeforeUnlock + dataAvailabilityChallenge.bondSize()); + + // Expect the bond to be unlocked + Challenge memory challenge = dataAvailabilityChallenge.getChallenge(challengedBlockNumber, challengedCommitment); + + assertEq(challenge.challenger, address(this)); + assertEq(challenge.lockedBond, 0); + assertEq(challenge.startBlock, challengedBlockNumber + 1); + assertEq(challenge.resolvedBlock, 0); + assertEq( + uint8(dataAvailabilityChallenge.getChallengeStatus(challengedBlockNumber, challengedCommitment)), + uint8(ChallengeStatus.Expired) + ); + + // Unlock the bond again, expect the balance to remain the same + dataAvailabilityChallenge.unlockBond(challengedBlockNumber, challengedCommitment); + assertEq(dataAvailabilityChallenge.balances(address(this)), balanceAfterUnlock); + } + + function testUnlockBondFailNonExistentChallenge() public { + bytes memory preImage = "some preimage"; + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + uint256 challengedBlockNumber = 1; + + // Move to block after challenged block + vm.roll(challengedBlockNumber + 1); + + // Unlock a bond of a non-existent challenge fails + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotExpired.selector)); + dataAvailabilityChallenge.unlockBond(challengedBlockNumber, challengedCommitment); + } + + function testUnlockBondFailResolvedChallenge() public { + bytes memory preImage = "some preimage"; + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + uint256 challengedBlockNumber = 1; + + // Move to block after challenged block + vm.roll(challengedBlockNumber + 1); + + // Challenge the hash + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); + + // Resolve the challenge + dataAvailabilityChallenge.resolve(challengedBlockNumber, challengedCommitment, preImage); + + // Attempting to unlock a bond of a resolved challenge fails + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotExpired.selector)); + dataAvailabilityChallenge.unlockBond(challengedBlockNumber, challengedCommitment); + } + + function testUnlockBondExpiredChallengeTwice() public { + bytes memory preImage = "some preimage"; + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + uint256 challengedBlockNumber = 1; + + // Move to block after challenged block + vm.roll(challengedBlockNumber + 1); + + // Challenge the hash + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); + + // Move to a block after the challenge window + vm.roll(block.number + dataAvailabilityChallenge.resolveWindow() + 1); + + // Unlock the bond + dataAvailabilityChallenge.unlockBond(challengedBlockNumber, challengedCommitment); + + uint256 balanceAfterUnlock = dataAvailabilityChallenge.balances(address(this)); + + // Unlock the bond again doesn't change the balance + dataAvailabilityChallenge.unlockBond(challengedBlockNumber, challengedCommitment); + assertEq(dataAvailabilityChallenge.balances(address(this)), balanceAfterUnlock); + } + + function testUnlockFailResolveWindowNotClosed() public { + bytes memory preImage = "some preimage"; + bytes memory challengedCommitment = computeCommitmentKeccak256(preImage); + uint256 challengedBlockNumber = 1; + + // Move to block after challenged block + vm.roll(challengedBlockNumber + 1); + + // Challenge the hash + dataAvailabilityChallenge.deposit{ value: dataAvailabilityChallenge.bondSize() }(); + dataAvailabilityChallenge.challenge(challengedBlockNumber, challengedCommitment); + + vm.roll(block.number + dataAvailabilityChallenge.resolveWindow() - 1); + + // Expiring the challenge before the resolve window closes fails + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.ChallengeNotExpired.selector)); + dataAvailabilityChallenge.unlockBond(challengedBlockNumber, challengedCommitment); + } + + function testSetBondSize() public { + uint256 requiredBond = dataAvailabilityChallenge.bondSize(); + uint256 actualBond = requiredBond - 1; + dataAvailabilityChallenge.deposit{ value: actualBond }(); + + // Expect the challenge to fail because the bond is too low + bytes memory challengedCommitment = computeCommitmentKeccak256("some hash"); + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.BondTooLow.selector, actualBond, requiredBond)); + dataAvailabilityChallenge.challenge(0, challengedCommitment); + + // Reduce the required bond + vm.prank(dataAvailabilityChallenge.owner()); + dataAvailabilityChallenge.setBondSize(actualBond); + + // Expect the challenge to succeed + dataAvailabilityChallenge.challenge(0, challengedCommitment); + } + + function testSetResolverRefundPercentage(uint256 resolverRefundPercentage) public { + resolverRefundPercentage = bound(resolverRefundPercentage, 0, 100); + vm.prank(dataAvailabilityChallenge.owner()); + dataAvailabilityChallenge.setResolverRefundPercentage(resolverRefundPercentage); + assertEq(dataAvailabilityChallenge.resolverRefundPercentage(), resolverRefundPercentage); + } + + function testSetResolverRefundPercentageFail() public { + address owner = dataAvailabilityChallenge.owner(); + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.InvalidResolverRefundPercentage.selector, 101)); + vm.prank(owner); + dataAvailabilityChallenge.setResolverRefundPercentage(101); + } + + function testSetBondSizeFailOnlyOwner(address notOwner, uint256 newBondSize) public { + vm.assume(notOwner != dataAvailabilityChallenge.owner()); + + // Expect setting the bond size to fail because the sender is not the owner + vm.prank(notOwner); + vm.expectRevert("Ownable: caller is not the owner"); + dataAvailabilityChallenge.setBondSize(newBondSize); + } + + function testValidateCommitment() public { + // Should not revert given a valid commitment + bytes memory validCommitment = abi.encodePacked(CommitmentType.Keccak256, keccak256("test")); + dataAvailabilityChallenge.validateCommitment(validCommitment); + + // Should revert if the commitment type is unknown + vm.expectRevert(abi.encodeWithSelector(DataAvailabilityChallenge.UnknownCommitmentType.selector, uint8(1))); + bytes memory unknownType = abi.encodePacked(uint8(1), keccak256("test")); + dataAvailabilityChallenge.validateCommitment(unknownType); + + // Should revert if the commitment length does not match + vm.expectRevert( + abi.encodeWithSelector(DataAvailabilityChallenge.InvalidCommitmentLength.selector, uint8(0), 33, 34) + ); + bytes memory invalidLength = abi.encodePacked(CommitmentType.Keccak256, keccak256("test"), "x"); + dataAvailabilityChallenge.validateCommitment(invalidLength); + } +} diff --git a/packages/contracts-bedrock/test/DelayedVetoable.t.sol b/packages/contracts-bedrock/test/L1/DelayedVetoable.t.sol similarity index 78% rename from packages/contracts-bedrock/test/DelayedVetoable.t.sol rename to packages/contracts-bedrock/test/L1/DelayedVetoable.t.sol index 27d0670a5875..5e67a7ba5cf9 100644 --- a/packages/contracts-bedrock/test/DelayedVetoable.t.sol +++ b/packages/contracts-bedrock/test/L1/DelayedVetoable.t.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; import { DelayedVetoable } from "src/L1/DelayedVetoable.sol"; -contract DelayedVetoable_Init is CommonTest { +contract DelayedVetoable_Init is Test { error Unauthorized(address expected, address actual); error ForwardingEarly(); @@ -12,17 +12,22 @@ contract DelayedVetoable_Init is CommonTest { event Forwarded(bytes32 indexed callHash, bytes data); event Vetoed(bytes32 indexed callHash, bytes data); - address target = address(0xabba); - address initiator = alice; - address vetoer = bob; + address target; + address initiator; + address vetoer; uint256 operatingDelay = 14 days; DelayedVetoable delayedVetoable; - function setUp() public override { - super.setUp(); + function setUp() public { + initiator = makeAddr("initiator"); + vetoer = makeAddr("vetoer"); + target = makeAddr("target"); + vm.deal(initiator, 10000 ether); + vm.deal(vetoer, 10000 ether); + delayedVetoable = new DelayedVetoable({ - initiator_: alice, - vetoer_: bob, + initiator_: initiator, + vetoer_: vetoer, target_: address(target), operatingDelay_: operatingDelay }); @@ -145,9 +150,9 @@ contract DelayedVetoable_HandleCall_Test is DelayedVetoable_Init { contract DelayedVetoable_HandleCall_TestFail is DelayedVetoable_Init { /// @dev Only the initiator can initiate a call. function test_handleCall_unauthorizedInitiation_reverts() external { - vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, initiator, address(this))); - (bool success,) = address(delayedVetoable).call(NON_ZERO_DATA); - assertTrue(success); + vm.expectRevert(abi.encodeWithSelector(DelayedVetoable.Unauthorized.selector, initiator, address(this))); + (bool revertsAsExpected,) = address(delayedVetoable).call(hex"00001234"); + assertTrue(revertsAsExpected); } /// @dev The call cannot be forwarded until the delay has passed. @@ -155,10 +160,11 @@ contract DelayedVetoable_HandleCall_TestFail is DelayedVetoable_Init { assumeNoClash(data); vm.prank(initiator); (bool success,) = address(delayedVetoable).call(data); + assertTrue(success); - vm.expectRevert(abi.encodeWithSelector(ForwardingEarly.selector)); - (success,) = address(delayedVetoable).call(data); - success; + vm.expectRevert(DelayedVetoable.ForwardingEarly.selector); + (bool revertsAsExpected,) = address(delayedVetoable).call(data); + assertTrue(revertsAsExpected); } /// @dev The call cannot be forwarded a second time. @@ -179,10 +185,10 @@ contract DelayedVetoable_HandleCall_TestFail is DelayedVetoable_Init { (success,) = address(delayedVetoable).call(data); assertTrue(success); - // Attempt to foward the same call again. - vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, initiator, address(this))); - (success,) = address(delayedVetoable).call(data); - assertTrue(success); + // Attempt to forward the same call again. + vm.expectRevert(abi.encodeWithSelector(DelayedVetoable.Unauthorized.selector, initiator, address(this))); + (bool revertsAsExpected,) = address(delayedVetoable).call(data); + assertTrue(revertsAsExpected); } /// @dev If the target reverts, it is bubbled up. @@ -197,7 +203,7 @@ contract DelayedVetoable_HandleCall_TestFail is DelayedVetoable_Init { // Initiate the call vm.prank(initiator); (bool success,) = address(delayedVetoable).call(inData); - success; + assertTrue(success); vm.warp(block.timestamp + operatingDelay); vm.expectEmit(true, false, false, true, address(delayedVetoable)); @@ -207,12 +213,37 @@ contract DelayedVetoable_HandleCall_TestFail is DelayedVetoable_Init { // Forward the call vm.expectRevert(outData); - (bool success2,) = address(delayedVetoable).call(inData); - success2; + (bool revertsAsExpected,) = address(delayedVetoable).call(inData); + assertTrue(revertsAsExpected); + } + + function testFuzz_handleCall_forwardingTargetRetValue_succeeds( + bytes calldata inData, + bytes calldata outData + ) + external + { + assumeNoClash(inData); + + // Initiate the call + vm.prank(initiator); + (bool success,) = address(delayedVetoable).call(inData); + assertTrue(success); + + vm.warp(block.timestamp + operatingDelay); + vm.expectEmit(true, false, false, true, address(delayedVetoable)); + emit Forwarded(keccak256(inData), inData); + + vm.mockCall(target, inData, outData); + + // Forward the call + (bool success2, bytes memory retData) = address(delayedVetoable).call(inData); + assertTrue(success2); + assertEq(keccak256(retData), keccak256(outData)); } /// @dev A test documenting the single instance in which the contract is not 'transparent' to the initiator. - function testFuzz_handleCall_queuedAtClash_reverts(bytes memory outData) external { + function testFuzz_handleCall_queuedAtClash_reverts() external { // This will get us calldata with the same function selector as the queuedAt function, but // with the incorrect input data length. bytes memory inData = abi.encodePacked(keccak256("queuedAt(bytes32)")); @@ -221,8 +252,8 @@ contract DelayedVetoable_HandleCall_TestFail is DelayedVetoable_Init { vm.store(address(delayedVetoable), bytes32(uint256(0)), bytes32(uint256(0))); vm.prank(initiator); - vm.expectRevert(outData); - (bool success,) = address(delayedVetoable).call(inData); - success; + vm.expectRevert(bytes("")); + (bool revertsAsExpected,) = address(delayedVetoable).call(inData); + assertTrue(revertsAsExpected); } } diff --git a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol new file mode 100644 index 000000000000..1f8054609073 --- /dev/null +++ b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol @@ -0,0 +1,701 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; +import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol"; + +// Libraries +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; +import { Constants } from "src/libraries/Constants.sol"; + +// Target contract dependencies +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; + +contract L1CrossDomainMessenger_Test is Bridge_Initializer { + /// @dev The receiver address + address recipient = address(0xabbaacdc); + + /// @dev The storage slot of the l2Sender + uint256 constant senderSlotIndex = 50; + + /// @dev Tests that the implementation is initialized correctly. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function test_constructor_succeeds() external virtual { + L1CrossDomainMessenger impl = L1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessenger")); + assertEq(address(impl.superchainConfig()), address(0)); + assertEq(address(impl.PORTAL()), address(0)); + assertEq(address(impl.portal()), address(0)); + assertEq(address(impl.OTHER_MESSENGER()), Predeploys.L2_CROSS_DOMAIN_MESSENGER); + assertEq(address(impl.otherMessenger()), Predeploys.L2_CROSS_DOMAIN_MESSENGER); + } + + /// @dev Tests that the proxy is initialized correctly. + function test_initialize_succeeds() external { + assertEq(address(l1CrossDomainMessenger.superchainConfig()), address(superchainConfig)); + assertEq(address(l1CrossDomainMessenger.PORTAL()), address(optimismPortal)); + assertEq(address(l1CrossDomainMessenger.portal()), address(optimismPortal)); + assertEq(address(l1CrossDomainMessenger.OTHER_MESSENGER()), Predeploys.L2_CROSS_DOMAIN_MESSENGER); + assertEq(address(l1CrossDomainMessenger.otherMessenger()), Predeploys.L2_CROSS_DOMAIN_MESSENGER); + } + + /// @dev Tests that the version can be decoded from the message nonce. + function test_messageVersion_succeeds() external { + (, uint16 version) = Encoding.decodeVersionedNonce(l1CrossDomainMessenger.messageNonce()); + assertEq(version, l1CrossDomainMessenger.MESSAGE_VERSION()); + } + + /// @dev Tests that the sendMessage function is able to send a single message. + /// TODO: this same test needs to be done with the legacy message type + /// by setting the message version to 0 + function test_sendMessage_succeeds() external { + // deposit transaction on the optimism portal should be called + vm.expectCall( + address(optimismPortal), + abi.encodeWithSelector( + OptimismPortal.depositTransaction.selector, + Predeploys.L2_CROSS_DOMAIN_MESSENGER, + 0, + l1CrossDomainMessenger.baseGas(hex"ff", 100), + false, + Encoding.encodeCrossDomainMessage( + l1CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff" + ) + ) + ); + + // TransactionDeposited event + vm.expectEmit(address(optimismPortal)); + emitTransactionDeposited( + AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), + Predeploys.L2_CROSS_DOMAIN_MESSENGER, + 0, + 0, + l1CrossDomainMessenger.baseGas(hex"ff", 100), + false, + Encoding.encodeCrossDomainMessage(l1CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff") + ); + + // SentMessage event + vm.expectEmit(address(l1CrossDomainMessenger)); + emit SentMessage(recipient, alice, hex"ff", l1CrossDomainMessenger.messageNonce(), 100); + + // SentMessageExtension1 event + vm.expectEmit(address(l1CrossDomainMessenger)); + emit SentMessageExtension1(alice, 0); + + vm.prank(alice); + l1CrossDomainMessenger.sendMessage(recipient, hex"ff", uint32(100)); + } + + /// @dev Tests that the sendMessage function is able to send + /// the same message twice. + function test_sendMessage_twice_succeeds() external { + uint256 nonce = l1CrossDomainMessenger.messageNonce(); + l1CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000)); + l1CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000)); + // the nonce increments for each message sent + assertEq(nonce + 2, l1CrossDomainMessenger.messageNonce()); + } + + /// @dev Tests that the xDomainMessageSender reverts when not set. + function test_xDomainSender_notSet_reverts() external { + vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); + l1CrossDomainMessenger.xDomainMessageSender(); + } + + /// @dev Tests that the relayMessage function reverts when + /// the message version is not 0 or 1. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function test_relayMessage_v2_reverts() external virtual { + address target = address(0xabcd); + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + + // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + + // Expect a revert. + vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time"); + + // Try to relay a v2 message. + vm.prank(address(optimismPortal)); + l2CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce + sender, + target, + 0, // value + 0, + hex"1111" + ); + } + + /// @dev Tests that the relayMessage function is able to relay a message + /// successfully by calling the target contract. + function test_relayMessage_succeeds() external { + address target = address(0xabcd); + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + + vm.expectCall(target, hex"1111"); + + // set the value of op.l2Sender() to be the L2 Cross Domain Messenger. + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.prank(address(optimismPortal)); + + vm.expectEmit(address(l1CrossDomainMessenger)); + + bytes32 hash = Hashing.hashCrossDomainMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, hex"1111" + ); + + emit RelayedMessage(hash); + + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce + sender, + target, + 0, // value + 0, + hex"1111" + ); + + // the message hash is in the successfulMessages mapping + assert(l1CrossDomainMessenger.successfulMessages(hash)); + // it is not in the received messages mapping + assertEq(l1CrossDomainMessenger.failedMessages(hash), false); + } + + /// @dev Tests that relayMessage reverts if attempting to relay a message + /// sent to an L1 system contract. + function test_relayMessage_toSystemContract_reverts() external { + // set the target to be the OptimismPortal + address target = address(optimismPortal); + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + bytes memory message = hex"1111"; + + vm.prank(address(optimismPortal)); + vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message + ); + + vm.store(address(optimismPortal), 0, bytes32(abi.encode(sender))); + vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message + ); + } + + /// @dev Tests that the relayMessage function reverts if eth is + /// sent from a contract other than the standard bridge. + function test_replayMessage_withValue_reverts() external { + address target = address(0xabcd); + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + bytes memory message = hex"1111"; + + vm.expectRevert("CrossDomainMessenger: value must be zero unless message is from a system address"); + l1CrossDomainMessenger.relayMessage{ value: 100 }( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message + ); + } + + /// @dev Tests that the xDomainMessageSender is reset to the original value + /// after a message is relayed. + function test_xDomainMessageSender_reset_succeeds() external { + vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); + l1CrossDomainMessenger.xDomainMessageSender(); + + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), address(0), address(0), 0, 0, hex"" + ); + + vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); + l1CrossDomainMessenger.xDomainMessageSender(); + } + + /// @dev Tests that relayMessage should successfully call the target contract after + /// the first message fails and ETH is stuck, but the second message succeeds + /// with a version 1 message. + function test_relayMessage_retryAfterFailure_succeeds() external { + address target = address(0xabcd); + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + uint256 value = 100; + + vm.expectCall(target, hex"1111"); + + bytes32 hash = Hashing.hashCrossDomainMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, value, 0, hex"1111" + ); + + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.etch(target, address(new Reverter()).code); + vm.deal(address(optimismPortal), value); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage{ value: value }( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + + assertEq(address(l1CrossDomainMessenger).balance, value); + assertEq(address(target).balance, 0); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), false); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); + + vm.expectEmit(address(l1CrossDomainMessenger)); + + emit RelayedMessage(hash); + + vm.etch(target, address(0).code); + vm.prank(address(sender)); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + + assertEq(address(l1CrossDomainMessenger).balance, 0); + assertEq(address(target).balance, value); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); + } + + /// @dev Tests that relayMessage should successfully call the target contract after + /// the first message fails and ETH is stuck, but the second message succeeds + /// with a legacy message. + function test_relayMessage_legacy_succeeds() external { + address target = address(0xabcd); + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + + // Compute the message hash. + bytes32 hash = Hashing.hashCrossDomainMessageV1( + // Using a legacy nonce with version 0. + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), + sender, + target, + 0, + 0, + hex"1111" + ); + + // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + + // Target should be called with expected data. + vm.expectCall(target, hex"1111"); + + // Expect RelayedMessage event to be emitted. + vm.expectEmit(address(l1CrossDomainMessenger)); + emit RelayedMessage(hash); + + // Relay the message. + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce + sender, + target, + 0, // value + 0, + hex"1111" + ); + + // Message was successfully relayed. + assertEq(l1CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l1CrossDomainMessenger.failedMessages(hash), false); + } + + /// @dev Tests that relayMessage should revert if the message is already replayed. + function test_relayMessage_legacyOldReplay_reverts() external { + address target = address(0xabcd); + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + + // Compute the message hash. + bytes32 hash = Hashing.hashCrossDomainMessageV1( + // Using a legacy nonce with version 0. + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), + sender, + target, + 0, + 0, + hex"1111" + ); + + // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + // Mark legacy message as already relayed. + uint256 successfulMessagesSlot = 203; + bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex"1111", 0); + bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot)); + vm.store(address(l1CrossDomainMessenger), slot, bytes32(uint256(1))); + + // Expect revert. + vm.expectRevert("CrossDomainMessenger: legacy withdrawal already relayed"); + + // Relay the message. + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce + sender, + target, + 0, // value + 0, + hex"1111" + ); + + // Message was not relayed. + assertEq(l1CrossDomainMessenger.successfulMessages(hash), false); + assertEq(l1CrossDomainMessenger.failedMessages(hash), false); + } + + /// @dev Tests that relayMessage can be retried after a failure with a legacy message. + function test_relayMessage_legacyRetryAfterFailure_succeeds() external { + address target = address(0xabcd); + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + uint256 value = 100; + + // Compute the message hash. + bytes32 hash = Hashing.hashCrossDomainMessageV1( + // Using a legacy nonce with version 0. + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), + sender, + target, + value, + 0, + hex"1111" + ); + + // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + + // Turn the target into a Reverter. + vm.etch(target, address(new Reverter()).code); + + // Target should be called with expected data. + vm.expectCall(target, hex"1111"); + + // Expect FailedRelayedMessage event to be emitted. + vm.expectEmit(address(l1CrossDomainMessenger)); + emit FailedRelayedMessage(hash); + + // Relay the message. + vm.deal(address(optimismPortal), value); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage{ value: value }( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + + // Message failed. + assertEq(address(l1CrossDomainMessenger).balance, value); + assertEq(address(target).balance, 0); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), false); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); + + // Make the target not revert anymore. + vm.etch(target, address(0).code); + + // Target should be called with expected data. + vm.expectCall(target, hex"1111"); + + // Expect RelayedMessage event to be emitted. + vm.expectEmit(address(l1CrossDomainMessenger)); + emit RelayedMessage(hash); + + // Retry the message. + vm.prank(address(sender)); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + + // Message was successfully relayed. + assertEq(address(l1CrossDomainMessenger).balance, 0); + assertEq(address(target).balance, value); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); + } + + /// @dev Tests that relayMessage cannot be retried after success with a legacy message. + function test_relayMessage_legacyRetryAfterSuccess_reverts() external { + address target = address(0xabcd); + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + uint256 value = 100; + + // Compute the message hash. + bytes32 hash = Hashing.hashCrossDomainMessageV1( + // Using a legacy nonce with version 0. + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), + sender, + target, + value, + 0, + hex"1111" + ); + + // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + + // Target should be called with expected data. + vm.expectCall(target, hex"1111"); + + // Expect RelayedMessage event to be emitted. + vm.expectEmit(address(l1CrossDomainMessenger)); + emit RelayedMessage(hash); + + // Relay the message. + vm.deal(address(optimismPortal), value); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage{ value: value }( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + + // Message was successfully relayed. + assertEq(address(l1CrossDomainMessenger).balance, 0); + assertEq(address(target).balance, value); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l1CrossDomainMessenger.failedMessages(hash), false); + + // Expect a revert. + vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); + + // Retry the message. + vm.prank(address(sender)); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + } + + /// @dev Tests that relayMessage cannot be called after a failure and a successful replay. + function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external { + address target = address(0xabcd); + address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + uint256 value = 100; + + // Compute the message hash. + bytes32 hash = Hashing.hashCrossDomainMessageV1( + // Using a legacy nonce with version 0. + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), + sender, + target, + value, + 0, + hex"1111" + ); + + // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + + // Turn the target into a Reverter. + vm.etch(target, address(new Reverter()).code); + + // Target should be called with expected data. + vm.expectCall(target, hex"1111"); + + // Relay the message. + vm.deal(address(optimismPortal), value); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage{ value: value }( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + + // Message failed. + assertEq(address(l1CrossDomainMessenger).balance, value); + assertEq(address(target).balance, 0); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), false); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); + + // Make the target not revert anymore. + vm.etch(target, address(0).code); + + // Target should be called with expected data. + vm.expectCall(target, hex"1111"); + + // Expect RelayedMessage event to be emitted. + vm.expectEmit(address(l1CrossDomainMessenger)); + emit RelayedMessage(hash); + + // Retry the message + vm.prank(address(sender)); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + + // Message was successfully relayed. + assertEq(address(l1CrossDomainMessenger).balance, 0); + assertEq(address(target).balance, value); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); + + // Expect a revert. + vm.expectRevert("CrossDomainMessenger: message has already been relayed"); + + // Retry the message again. + vm.prank(address(sender)); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + } + + /// @dev Tests that the relayMessage function is able to relay a message + /// successfully by calling the target contract. + function test_relayMessage_paused_reverts() external { + vm.prank(superchainConfig.guardian()); + superchainConfig.pause("identifier"); + vm.expectRevert("CrossDomainMessenger: paused"); + + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce + address(0), + address(0), + 0, // value + 0, + hex"1111" + ); + } + + /// @dev Tests that the superchain config is called by the messengers paused function + function test_pause_callsSuperchainConfig_succeeds() external { + vm.expectCall(address(superchainConfig), abi.encodeWithSelector(SuperchainConfig.paused.selector)); + l1CrossDomainMessenger.paused(); + } + + /// @dev Tests that changing the superchain config paused status changes the return value of the messenger + function test_pause_matchesSuperchainConfig_succeeds() external { + assertFalse(l1CrossDomainMessenger.paused()); + assertEq(l1CrossDomainMessenger.paused(), superchainConfig.paused()); + + vm.prank(superchainConfig.guardian()); + superchainConfig.pause("identifier"); + + assertTrue(l1CrossDomainMessenger.paused()); + assertEq(l1CrossDomainMessenger.paused(), superchainConfig.paused()); + } +} + +/// @dev A regression test against a reentrancy vulnerability in the CrossDomainMessenger contract, which +/// was possible by intercepting and sandwhiching a signed Safe Transaction to upgrade it. +contract L1CrossDomainMessenger_ReinitReentryTest is Bridge_Initializer { + bool attacked; + + // Common values used across functions + uint256 constant messageValue = 50; + bytes constant selector = abi.encodeWithSelector(this.reinitAndReenter.selector); + address sender; + bytes32 hash; + address target; + + function setUp() public override { + super.setUp(); + target = address(this); + sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; + hash = Hashing.hashCrossDomainMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, messageValue, 0, selector + ); + vm.deal(address(l1CrossDomainMessenger), messageValue * 2); + } + + /// @dev This method will be called by the relayed message, and will attempt to reenter the relayMessage function + /// exactly once. + function reinitAndReenter() public payable { + // only attempt the attack once + if (!attacked) { + attacked = true; + // set initialized to false + vm.store(address(l1CrossDomainMessenger), 0, bytes32(uint256(0))); + + // call the initializer function + l1CrossDomainMessenger.initialize(SuperchainConfig(superchainConfig), OptimismPortal(optimismPortal)); + + // attempt to re-replay the withdrawal + vm.expectEmit(address(l1CrossDomainMessenger)); + emit FailedRelayedMessage(hash); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce + sender, + target, + messageValue, + 0, + selector + ); + } + } + + /// @dev Tests that the relayMessage function cannot be reentered by calling the `initialize()` function within the + /// relayed message. + function test_relayMessage_replayStraddlingReinit_reverts() external { + uint256 balanceBeforeThis = address(this).balance; + uint256 balanceBeforeMessenger = address(l1CrossDomainMessenger).balance; + + // A requisite for the attack is that the message has already been attempted and written to the failedMessages + // mapping, so that it can be replayed. + vm.store(address(l1CrossDomainMessenger), keccak256(abi.encode(hash, 206)), bytes32(uint256(1))); + assertTrue(l1CrossDomainMessenger.failedMessages(hash)); + + vm.expectEmit(address(l1CrossDomainMessenger)); + emit FailedRelayedMessage(hash); + l1CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce + sender, + target, + messageValue, + 0, + selector + ); + + // The message hash is not in the successfulMessages mapping. + assertFalse(l1CrossDomainMessenger.successfulMessages(hash)); + // The balance of this contract is unchanged. + assertEq(address(this).balance, balanceBeforeThis); + // The balance of the messenger contract is unchanged. + assertEq(address(l1CrossDomainMessenger).balance, balanceBeforeMessenger); + } +} diff --git a/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol new file mode 100644 index 000000000000..5d2444525bf7 --- /dev/null +++ b/packages/contracts-bedrock/test/L1/L1ERC721Bridge.t.sol @@ -0,0 +1,373 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; +import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; + +// Target contract dependencies +import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; + +// Target contract +import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; + +/// @dev Test ERC721 contract. +contract TestERC721 is ERC721 { + constructor() ERC721("Test", "TST") { } + + function mint(address to, uint256 tokenId) public { + _mint(to, tokenId); + } +} + +contract L1ERC721Bridge_Test is Bridge_Initializer { + TestERC721 internal localToken; + TestERC721 internal remoteToken; + uint256 internal constant tokenId = 1; + + event ERC721BridgeInitiated( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 tokenId, + bytes extraData + ); + + event ERC721BridgeFinalized( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 tokenId, + bytes extraData + ); + + /// @dev Sets up the testing environment. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function setUp() public virtual override { + super.setUp(); + + localToken = new TestERC721(); + remoteToken = new TestERC721(); + + // Mint alice a token. + localToken.mint(alice, tokenId); + + // Approve the bridge to transfer the token. + vm.prank(alice); + localToken.approve(address(l1ERC721Bridge), tokenId); + } + + /// @dev Tests that the impl is created with the correct values. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function test_constructor_succeeds() public virtual { + L1ERC721Bridge impl = L1ERC721Bridge(deploy.mustGetAddress("L1ERC721Bridge")); + assertEq(address(impl.MESSENGER()), address(0)); + assertEq(address(impl.messenger()), address(0)); + assertEq(address(impl.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE); + assertEq(address(impl.otherBridge()), Predeploys.L2_ERC721_BRIDGE); + assertEq(address(impl.superchainConfig()), address(0)); + } + + /// @dev Tests that the proxy is initialized with the correct values. + function test_initialize_succeeds() public { + assertEq(address(l1ERC721Bridge.MESSENGER()), address(l1CrossDomainMessenger)); + assertEq(address(l1ERC721Bridge.messenger()), address(l1CrossDomainMessenger)); + assertEq(address(l1ERC721Bridge.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE); + assertEq(address(l1ERC721Bridge.otherBridge()), Predeploys.L2_ERC721_BRIDGE); + assertEq(address(l1ERC721Bridge.superchainConfig()), address(superchainConfig)); + } + + /// @dev Tests that the ERC721 can be bridged successfully. + function test_bridgeERC721_succeeds() public { + // Expect a call to the messenger. + vm.expectCall( + address(l1CrossDomainMessenger), + abi.encodeCall( + l1CrossDomainMessenger.sendMessage, + ( + address(l2ERC721Bridge), + abi.encodeCall( + L2ERC721Bridge.finalizeBridgeERC721, + (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678") + ), + 1234 + ) + ) + ); + + // Expect an event to be emitted. + vm.expectEmit(true, true, true, true); + emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + + // Bridge the token. + vm.prank(alice); + l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + + // Token is locked in the bridge. + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), true); + assertEq(localToken.ownerOf(tokenId), address(l1ERC721Bridge)); + } + + /// @dev Tests that the ERC721 bridge reverts for non externally owned accounts. + function test_bridgeERC721_fromContract_reverts() external { + // Bridge the token. + vm.etch(alice, hex"01"); + vm.prank(alice); + vm.expectRevert("ERC721Bridge: account is not externally owned"); + l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that the ERC721 bridge reverts for a zero address local token. + function test_bridgeERC721_localTokenZeroAddress_reverts() external { + // Bridge the token. + vm.prank(alice); + vm.expectRevert(bytes("")); + l1ERC721Bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that the ERC721 bridge reverts for a zero address remote token. + function test_bridgeERC721_remoteTokenZeroAddress_reverts() external { + // Bridge the token. + vm.prank(alice); + vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)"); + l1ERC721Bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that the ERC721 bridge reverts for an incorrect owner. + function test_bridgeERC721_wrongOwner_reverts() external { + // Bridge the token. + vm.prank(bob); + vm.expectRevert("ERC721: transfer from incorrect owner"); + l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that the ERC721 bridge successfully sends a token + /// to a different address than the owner. + function test_bridgeERC721To_succeeds() external { + // Expect a call to the messenger. + vm.expectCall( + address(l1CrossDomainMessenger), + abi.encodeCall( + l1CrossDomainMessenger.sendMessage, + ( + address(Predeploys.L2_ERC721_BRIDGE), + abi.encodeCall( + L2ERC721Bridge.finalizeBridgeERC721, + (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") + ), + 1234 + ) + ) + ); + + // Expect an event to be emitted. + vm.expectEmit(true, true, true, true); + emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, bob, tokenId, hex"5678"); + + // Bridge the token. + vm.prank(alice); + l1ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); + + // Token is locked in the bridge. + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), true); + assertEq(localToken.ownerOf(tokenId), address(l1ERC721Bridge)); + } + + /// @dev Tests that the ERC721 bridge reverts for non externally owned accounts + /// when sending to a different address than the owner. + function test_bridgeERC721To_localTokenZeroAddress_reverts() external { + // Bridge the token. + vm.prank(alice); + vm.expectRevert(bytes("")); + l1ERC721Bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that the ERC721 bridge reverts for a zero address remote token + /// when sending to a different address than the owner. + function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external { + // Bridge the token. + vm.prank(alice); + vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)"); + l1ERC721Bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that the ERC721 bridge reverts for an incorrect owner + //// when sending to a different address than the owner. + function test_bridgeERC721To_wrongOwner_reverts() external { + // Bridge the token. + vm.prank(bob); + vm.expectRevert("ERC721: transfer from incorrect owner"); + l1ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that the ERC721 bridge successfully finalizes a withdrawal. + function test_finalizeBridgeERC721_succeeds() external { + // Bridge the token. + vm.prank(alice); + l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + + // Expect an event to be emitted. + vm.expectEmit(true, true, true, true); + emit ERC721BridgeFinalized(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + + // Finalize a withdrawal. + vm.mockCall( + address(l1CrossDomainMessenger), + abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(Predeploys.L2_ERC721_BRIDGE) + ); + vm.prank(address(l1CrossDomainMessenger)); + l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + + // Token is not locked in the bridge. + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that the ERC721 bridge finalize reverts when not called + /// by the remote bridge. + function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external { + // Finalize a withdrawal. + vm.prank(alice); + vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); + l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + } + + /// @dev Tests that the ERC721 bridge finalize reverts when not called + /// from the remote messenger. + function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { + // Finalize a withdrawal. + vm.mockCall( + address(l1CrossDomainMessenger), + abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(alice) + ); + vm.prank(address(l1CrossDomainMessenger)); + vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); + l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + } + + /// @dev Tests that the ERC721 bridge finalize reverts when the local token + /// is set as the bridge itself. + function test_finalizeBridgeERC721_selfToken_reverts() external { + // Finalize a withdrawal. + vm.mockCall( + address(l1CrossDomainMessenger), + abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(Predeploys.L2_ERC721_BRIDGE) + ); + vm.prank(address(l1CrossDomainMessenger)); + vm.expectRevert("L1ERC721Bridge: local token cannot be self"); + l1ERC721Bridge.finalizeBridgeERC721( + address(l1ERC721Bridge), address(remoteToken), alice, alice, tokenId, hex"5678" + ); + } + + /// @dev Tests that the ERC721 bridge finalize reverts when the remote token + /// is not escrowed in the L1 bridge. + function test_finalizeBridgeERC721_notEscrowed_reverts() external { + // Finalize a withdrawal. + vm.mockCall( + address(l1CrossDomainMessenger), + abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(Predeploys.L2_ERC721_BRIDGE) + ); + vm.prank(address(l1CrossDomainMessenger)); + vm.expectRevert("L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge"); + l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + } +} + +contract L1ERC721Bridge_Pause_Test is Bridge_Initializer { + /// @dev Verifies that the `paused` accessor returns the same value as the `paused` function of the + /// `superchainConfig`. + function test_paused_succeeds() external { + assertEq(l1ERC721Bridge.paused(), superchainConfig.paused()); + } + + /// @dev Ensures that the `paused` function of the bridge contract actually calls the `paused` function of the + /// `superchainConfig`. + function test_pause_callsSuperchainConfig_succeeds() external { + vm.expectCall(address(superchainConfig), abi.encodeWithSelector(SuperchainConfig.paused.selector)); + l1ERC721Bridge.paused(); + } + + /// @dev Checks that the `paused` state of the bridge matches the `paused` state of the `superchainConfig` after + /// it's been changed. + function test_pause_matchesSuperchainConfig_succeeds() external { + assertFalse(l1StandardBridge.paused()); + assertEq(l1StandardBridge.paused(), superchainConfig.paused()); + + vm.prank(superchainConfig.guardian()); + superchainConfig.pause("identifier"); + + assertTrue(l1StandardBridge.paused()); + assertEq(l1StandardBridge.paused(), superchainConfig.paused()); + } +} + +contract L1ERC721Bridge_Pause_TestFail is Bridge_Initializer { + /// @dev Sets up the test by pausing the bridge, giving ether to the bridge and mocking + /// the calls to the xDomainMessageSender so that it returns the correct value. + function setUp() public override { + super.setUp(); + vm.prank(superchainConfig.guardian()); + superchainConfig.pause("identifier"); + assertTrue(l1ERC721Bridge.paused()); + + vm.mockCall( + address(l1ERC721Bridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1ERC721Bridge.otherBridge())) + ); + } + + // @dev Ensures that the `bridgeERC721` function reverts when the bridge is paused. + function test_pause_finalizeBridgeERC721_reverts() external { + vm.prank(address(l1ERC721Bridge.messenger())); + vm.expectRevert("L1ERC721Bridge: paused"); + l1ERC721Bridge.finalizeBridgeERC721({ + _localToken: address(0), + _remoteToken: address(0), + _from: address(0), + _to: address(0), + _tokenId: 0, + _extraData: hex"" + }); + } +} diff --git a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol new file mode 100644 index 000000000000..0d0b7dc8c308 --- /dev/null +++ b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol @@ -0,0 +1,758 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { stdStorage, StdStorage } from "forge-std/Test.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Target contract dependencies +import { StandardBridge } from "src/universal/StandardBridge.sol"; +import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; +import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; +import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; + +// Target contract +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; + +contract L1StandardBridge_Getter_Test is Bridge_Initializer { + /// @dev Test that the accessors return the correct initialized values. + function test_getters_succeeds() external view { + assert(l1StandardBridge.l2TokenBridge() == address(l2StandardBridge)); + assert(l1StandardBridge.OTHER_BRIDGE() == l2StandardBridge); + assert(l1StandardBridge.messenger() == l1CrossDomainMessenger); + assert(l1StandardBridge.MESSENGER() == l1CrossDomainMessenger); + } +} + +contract L1StandardBridge_Initialize_Test is Bridge_Initializer { + /// @dev Test that the constructor sets the correct values. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function test_constructor_succeeds() external virtual { + L1StandardBridge impl = L1StandardBridge(deploy.mustGetAddress("L1StandardBridge")); + assertEq(address(impl.superchainConfig()), address(0)); + assertEq(address(impl.MESSENGER()), address(0)); + assertEq(address(impl.messenger()), address(0)); + assertEq(address(impl.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE); + assertEq(address(impl.otherBridge()), Predeploys.L2_STANDARD_BRIDGE); + assertEq(address(l2StandardBridge), Predeploys.L2_STANDARD_BRIDGE); + } + + /// @dev Test that the initialize function sets the correct values. + function test_initialize_succeeds() external { + assertEq(address(l1StandardBridge.superchainConfig()), address(superchainConfig)); + assertEq(address(l1StandardBridge.MESSENGER()), address(l1CrossDomainMessenger)); + assertEq(address(l1StandardBridge.messenger()), address(l1CrossDomainMessenger)); + assertEq(address(l1StandardBridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE); + assertEq(address(l1StandardBridge.otherBridge()), Predeploys.L2_STANDARD_BRIDGE); + assertEq(address(l2StandardBridge), Predeploys.L2_STANDARD_BRIDGE); + } +} + +contract L1StandardBridge_Pause_Test is Bridge_Initializer { + /// @dev Verifies that the `paused` accessor returns the same value as the `paused` function of the + /// `superchainConfig`. + function test_paused_succeeds() external { + assertEq(l1StandardBridge.paused(), superchainConfig.paused()); + } + + /// @dev Ensures that the `paused` function of the bridge contract actually calls the `paused` function of the + /// `superchainConfig`. + function test_pause_callsSuperchainConfig_succeeds() external { + vm.expectCall(address(superchainConfig), abi.encodeWithSelector(SuperchainConfig.paused.selector)); + l1StandardBridge.paused(); + } + + /// @dev Checks that the `paused` state of the bridge matches the `paused` state of the `superchainConfig` after + /// it's been changed. + function test_pause_matchesSuperchainConfig_succeeds() external { + assertFalse(l1StandardBridge.paused()); + assertEq(l1StandardBridge.paused(), superchainConfig.paused()); + + vm.prank(superchainConfig.guardian()); + superchainConfig.pause("identifier"); + + assertTrue(l1StandardBridge.paused()); + assertEq(l1StandardBridge.paused(), superchainConfig.paused()); + } +} + +contract L1StandardBridge_Pause_TestFail is Bridge_Initializer { + /// @dev Sets up the test by pausing the bridge, giving ether to the bridge and mocking + /// the calls to the xDomainMessageSender so that it returns the correct value. + function setUp() public override { + super.setUp(); + vm.prank(superchainConfig.guardian()); + superchainConfig.pause("identifier"); + assertTrue(l1StandardBridge.paused()); + + vm.deal(address(l1StandardBridge.messenger()), 1 ether); + + vm.mockCall( + address(l1StandardBridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1StandardBridge.otherBridge())) + ); + } + + /// @dev Confirms that the `finalizeBridgeETH` function reverts when the bridge is paused. + function test_pause_finalizeBridgeETH_reverts() external { + vm.prank(address(l1StandardBridge.messenger())); + vm.expectRevert("StandardBridge: paused"); + l1StandardBridge.finalizeBridgeETH{ value: 100 }({ + _from: address(2), + _to: address(3), + _amount: 100, + _extraData: hex"" + }); + } + + /// @dev Confirms that the `finalizeETHWithdrawal` function reverts when the bridge is paused. + function test_pause_finalizeETHWithdrawal_reverts() external { + vm.prank(address(l1StandardBridge.messenger())); + vm.expectRevert("StandardBridge: paused"); + l1StandardBridge.finalizeETHWithdrawal{ value: 100 }({ + _from: address(2), + _to: address(3), + _amount: 100, + _extraData: hex"" + }); + } + + /// @dev Confirms that the `finalizeERC20Withdrawal` function reverts when the bridge is paused. + function test_pause_finalizeERC20Withdrawal_reverts() external { + vm.prank(address(l1StandardBridge.messenger())); + vm.expectRevert("StandardBridge: paused"); + l1StandardBridge.finalizeERC20Withdrawal({ + _l1Token: address(0), + _l2Token: address(0), + _from: address(0), + _to: address(0), + _amount: 0, + _extraData: hex"" + }); + } + + /// @dev Confirms that the `finalizeBridgeERC20` function reverts when the bridge is paused. + function test_pause_finalizeBridgeERC20_reverts() external { + vm.prank(address(l1StandardBridge.messenger())); + vm.expectRevert("StandardBridge: paused"); + l1StandardBridge.finalizeBridgeERC20({ + _localToken: address(0), + _remoteToken: address(0), + _from: address(0), + _to: address(0), + _amount: 0, + _extraData: hex"" + }); + } +} + +contract L1StandardBridge_Initialize_TestFail is Bridge_Initializer { } + +contract L1StandardBridge_Receive_Test is Bridge_Initializer { + /// @dev Tests receive bridges ETH successfully. + function test_receive_succeeds() external { + assertEq(address(optimismPortal).balance, 0); + + // The legacy event must be emitted for backwards compatibility + vm.expectEmit(address(l1StandardBridge)); + emit ETHDepositInitiated(alice, alice, 100, hex""); + + vm.expectEmit(address(l1StandardBridge)); + emit ETHBridgeInitiated(alice, alice, 100, hex""); + + vm.expectCall( + address(l1CrossDomainMessenger), + abi.encodeWithSelector( + CrossDomainMessenger.sendMessage.selector, + address(l2StandardBridge), + abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""), + 200_000 + ) + ); + + vm.prank(alice, alice); + (bool success,) = address(l1StandardBridge).call{ value: 100 }(hex""); + assertEq(success, true); + assertEq(address(optimismPortal).balance, 100); + } +} + +contract L1StandardBridge_Receive_TestFail { } + +contract PreBridgeETH is Bridge_Initializer { + /// @dev Asserts the expected calls and events for bridging ETH depending + /// on whether the bridge call is legacy or not. + function _preBridgeETH(bool isLegacy) internal { + assertEq(address(optimismPortal).balance, 0); + uint256 nonce = l1CrossDomainMessenger.messageNonce(); + uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION + address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); + + bytes memory message = + abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 500, hex"dead"); + + if (isLegacy) { + vm.expectCall( + address(l1StandardBridge), + 500, + abi.encodeWithSelector(l1StandardBridge.depositETH.selector, 50000, hex"dead") + ); + } else { + vm.expectCall( + address(l1StandardBridge), + 500, + abi.encodeWithSelector(l1StandardBridge.bridgeETH.selector, 50000, hex"dead") + ); + } + vm.expectCall( + address(l1CrossDomainMessenger), + 500, + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 50000) + ); + + bytes memory innerMessage = abi.encodeWithSelector( + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l1StandardBridge), + address(l2StandardBridge), + 500, + 50000, + message + ); + + uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 50000); + vm.expectCall( + address(optimismPortal), + 500, + abi.encodeWithSelector( + OptimismPortal.depositTransaction.selector, + address(l2CrossDomainMessenger), + 500, + baseGas, + false, + innerMessage + ) + ); + + bytes memory opaqueData = abi.encodePacked(uint256(500), uint256(500), baseGas, false, innerMessage); + + vm.expectEmit(address(l1StandardBridge)); + emit ETHDepositInitiated(alice, alice, 500, hex"dead"); + + vm.expectEmit(address(l1StandardBridge)); + emit ETHBridgeInitiated(alice, alice, 500, hex"dead"); + + // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call + vm.expectEmit(address(optimismPortal)); + emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData); + + // SentMessage event emitted by the CrossDomainMessenger + vm.expectEmit(address(l1CrossDomainMessenger)); + emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 50000); + + // SentMessageExtension1 event emitted by the CrossDomainMessenger + vm.expectEmit(address(l1CrossDomainMessenger)); + emit SentMessageExtension1(address(l1StandardBridge), 500); + + vm.prank(alice, alice); + } +} + +contract L1StandardBridge_DepositETH_Test is PreBridgeETH { + /// @dev Tests that depositing ETH succeeds. + /// Emits ETHDepositInitiated and ETHBridgeInitiated events. + /// Calls depositTransaction on the OptimismPortal. + /// Only EOA can call depositETH. + /// ETH ends up in the optimismPortal. + function test_depositETH_succeeds() external { + _preBridgeETH({ isLegacy: true }); + l1StandardBridge.depositETH{ value: 500 }(50000, hex"dead"); + assertEq(address(optimismPortal).balance, 500); + } +} + +contract L1StandardBridge_BridgeETH_Test is PreBridgeETH { + /// @dev Tests that bridging ETH succeeds. + /// Emits ETHDepositInitiated and ETHBridgeInitiated events. + /// Calls depositTransaction on the OptimismPortal. + /// Only EOA can call bridgeETH. + /// ETH ends up in the optimismPortal. + function test_bridgeETH_succeeds() external { + _preBridgeETH({ isLegacy: false }); + l1StandardBridge.bridgeETH{ value: 500 }(50000, hex"dead"); + assertEq(address(optimismPortal).balance, 500); + } +} + +contract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer { + /// @dev Tests that depositing ETH reverts if the call is not from an EOA. + function test_depositETH_notEoa_reverts() external { + vm.etch(alice, address(L1Token).code); + vm.expectRevert("StandardBridge: function can only be called from an EOA"); + vm.prank(alice); + l1StandardBridge.depositETH{ value: 1 }(300, hex""); + } +} + +contract PreBridgeETHTo is Bridge_Initializer { + /// @dev Asserts the expected calls and events for bridging ETH to a different + /// address depending on whether the bridge call is legacy or not. + function _preBridgeETHTo(bool isLegacy) internal { + assertEq(address(optimismPortal).balance, 0); + uint256 nonce = l1CrossDomainMessenger.messageNonce(); + uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION + address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); + + if (isLegacy) { + vm.expectCall( + address(l1StandardBridge), + 600, + abi.encodeWithSelector(l1StandardBridge.depositETHTo.selector, bob, 60000, hex"dead") + ); + } else { + vm.expectCall( + address(l1StandardBridge), + 600, + abi.encodeWithSelector(l1StandardBridge.bridgeETHTo.selector, bob, 60000, hex"dead") + ); + } + + bytes memory message = + abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, bob, 600, hex"dead"); + + // the L1 bridge should call + // L1CrossDomainMessenger.sendMessage + vm.expectCall( + address(l1CrossDomainMessenger), + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 60000) + ); + + bytes memory innerMessage = abi.encodeWithSelector( + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l1StandardBridge), + address(l2StandardBridge), + 600, + 60000, + message + ); + + uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 60000); + vm.expectCall( + address(optimismPortal), + abi.encodeWithSelector( + OptimismPortal.depositTransaction.selector, + address(l2CrossDomainMessenger), + 600, + baseGas, + false, + innerMessage + ) + ); + + bytes memory opaqueData = abi.encodePacked(uint256(600), uint256(600), baseGas, false, innerMessage); + + vm.expectEmit(address(l1StandardBridge)); + emit ETHDepositInitiated(alice, bob, 600, hex"dead"); + + vm.expectEmit(address(l1StandardBridge)); + emit ETHBridgeInitiated(alice, bob, 600, hex"dead"); + + // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call + vm.expectEmit(address(optimismPortal)); + emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData); + + // SentMessage event emitted by the CrossDomainMessenger + vm.expectEmit(address(l1CrossDomainMessenger)); + emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 60000); + + // SentMessageExtension1 event emitted by the CrossDomainMessenger + vm.expectEmit(address(l1CrossDomainMessenger)); + emit SentMessageExtension1(address(l1StandardBridge), 600); + + // deposit eth to bob + vm.prank(alice, alice); + } +} + +contract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo { + /// @dev Tests that depositing ETH to a different address succeeds. + /// Emits ETHDepositInitiated event. + /// Calls depositTransaction on the OptimismPortal. + /// EOA or contract can call depositETHTo. + /// ETH ends up in the optimismPortal. + function test_depositETHTo_succeeds() external { + _preBridgeETHTo({ isLegacy: true }); + l1StandardBridge.depositETHTo{ value: 600 }(bob, 60000, hex"dead"); + assertEq(address(optimismPortal).balance, 600); + } +} + +contract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo { + /// @dev Tests that bridging ETH to a different address succeeds. + /// Emits ETHDepositInitiated and ETHBridgeInitiated events. + /// Calls depositTransaction on the OptimismPortal. + /// Only EOA can call bridgeETHTo. + /// ETH ends up in the optimismPortal. + function test_bridgeETHTo_succeeds() external { + _preBridgeETHTo({ isLegacy: false }); + l1StandardBridge.bridgeETHTo{ value: 600 }(bob, 60000, hex"dead"); + assertEq(address(optimismPortal).balance, 600); + } +} + +contract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer { } + +contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer { + using stdStorage for StdStorage; + + // depositERC20 + // - updates bridge.deposits + // - emits ERC20DepositInitiated + // - calls optimismPortal.depositTransaction + // - only callable by EOA + + /// @dev Tests that depositing ERC20 to the bridge succeeds. + /// Bridge deposits are updated. + /// Emits ERC20DepositInitiated event. + /// Calls depositTransaction on the OptimismPortal. + /// Only EOA can call depositERC20. + function test_depositERC20_succeeds() external { + uint256 nonce = l1CrossDomainMessenger.messageNonce(); + uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION + address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); + + // Deal Alice's ERC20 State + deal(address(L1Token), alice, 100000, true); + vm.prank(alice); + L1Token.approve(address(l1StandardBridge), type(uint256).max); + + // The l1StandardBridge should transfer alice's tokens to itself + vm.expectCall( + address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(l1StandardBridge), 100) + ); + + bytes memory message = abi.encodeWithSelector( + StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, alice, 100, hex"" + ); + + // the L1 bridge should call L1CrossDomainMessenger.sendMessage + vm.expectCall( + address(l1CrossDomainMessenger), + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 10000) + ); + + bytes memory innerMessage = abi.encodeWithSelector( + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l1StandardBridge), + address(l2StandardBridge), + 0, + 10000, + message + ); + + uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 10000); + vm.expectCall( + address(optimismPortal), + abi.encodeWithSelector( + OptimismPortal.depositTransaction.selector, + address(l2CrossDomainMessenger), + 0, + baseGas, + false, + innerMessage + ) + ); + + bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage); + + // Should emit both the bedrock and legacy events + vm.expectEmit(address(l1StandardBridge)); + emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex""); + + vm.expectEmit(address(l1StandardBridge)); + emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex""); + + // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call + vm.expectEmit(address(optimismPortal)); + emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData); + + // SentMessage event emitted by the CrossDomainMessenger + vm.expectEmit(address(l1CrossDomainMessenger)); + emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 10000); + + // SentMessageExtension1 event emitted by the CrossDomainMessenger + vm.expectEmit(address(l1CrossDomainMessenger)); + emit SentMessageExtension1(address(l1StandardBridge), 0); + + vm.prank(alice); + l1StandardBridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex""); + assertEq(l1StandardBridge.deposits(address(L1Token), address(L2Token)), 100); + } +} + +contract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer { + /// @dev Tests that depositing an ERC20 to the bridge reverts + /// if the caller is not an EOA. + function test_depositERC20_notEoa_reverts() external { + // turn alice into a contract + vm.etch(alice, hex"ffff"); + + vm.expectRevert("StandardBridge: function can only be called from an EOA"); + vm.prank(alice, alice); + l1StandardBridge.depositERC20(address(0), address(0), 100, 100, hex""); + } +} + +contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer { + /// @dev Tests that depositing ERC20 to the bridge succeeds when + /// sent to a different address. + /// Bridge deposits are updated. + /// Emits ERC20DepositInitiated event. + /// Calls depositTransaction on the OptimismPortal. + /// Contracts can call depositERC20. + function test_depositERC20To_succeeds() external { + uint256 nonce = l1CrossDomainMessenger.messageNonce(); + uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION + address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); + + bytes memory message = abi.encodeWithSelector( + StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, bob, 1000, hex"" + ); + + bytes memory innerMessage = abi.encodeWithSelector( + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l1StandardBridge), + address(l2StandardBridge), + 0, + 10000, + message + ); + + uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 10000); + bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage); + + deal(address(L1Token), alice, 100000, true); + + vm.prank(alice); + L1Token.approve(address(l1StandardBridge), type(uint256).max); + + // Should emit both the bedrock and legacy events + vm.expectEmit(address(l1StandardBridge)); + emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex""); + + vm.expectEmit(address(l1StandardBridge)); + emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex""); + + // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call + vm.expectEmit(address(optimismPortal)); + emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData); + + // SentMessage event emitted by the CrossDomainMessenger + vm.expectEmit(address(l1CrossDomainMessenger)); + emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 10000); + + // SentMessageExtension1 event emitted by the CrossDomainMessenger + vm.expectEmit(address(l1CrossDomainMessenger)); + emit SentMessageExtension1(address(l1StandardBridge), 0); + + // the L1 bridge should call L1CrossDomainMessenger.sendMessage + vm.expectCall( + address(l1CrossDomainMessenger), + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 10000) + ); + // The L1 XDM should call OptimismPortal.depositTransaction + vm.expectCall( + address(optimismPortal), + abi.encodeWithSelector( + OptimismPortal.depositTransaction.selector, + address(l2CrossDomainMessenger), + 0, + baseGas, + false, + innerMessage + ) + ); + vm.expectCall( + address(L1Token), + abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(l1StandardBridge), 1000) + ); + + vm.prank(alice); + l1StandardBridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex""); + + assertEq(l1StandardBridge.deposits(address(L1Token), address(L2Token)), 1000); + } +} + +contract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer { + using stdStorage for StdStorage; + + /// @dev Tests that finalizing an ETH withdrawal succeeds. + /// Emits ETHWithdrawalFinalized event. + /// Only callable by the L2 bridge. + function test_finalizeETHWithdrawal_succeeds() external { + uint256 aliceBalance = alice.balance; + + vm.expectEmit(address(l1StandardBridge)); + emit ETHWithdrawalFinalized(alice, alice, 100, hex""); + + vm.expectEmit(address(l1StandardBridge)); + emit ETHBridgeFinalized(alice, alice, 100, hex""); + + vm.expectCall(alice, hex""); + + vm.mockCall( + address(l1StandardBridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) + ); + // ensure that the messenger has ETH to call with + vm.deal(address(l1StandardBridge.messenger()), 100); + vm.prank(address(l1StandardBridge.messenger())); + l1StandardBridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex""); + + assertEq(address(l1StandardBridge.messenger()).balance, 0); + assertEq(aliceBalance + 100, alice.balance); + } +} + +contract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer { } + +contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer { + using stdStorage for StdStorage; + + /// @dev Tests that finalizing an ERC20 withdrawal succeeds. + /// Bridge deposits are updated. + /// Emits ERC20WithdrawalFinalized event. + /// Only callable by the L2 bridge. + function test_finalizeERC20Withdrawal_succeeds() external { + deal(address(L1Token), address(l1StandardBridge), 100, true); + + uint256 slot = stdstore.target(address(l1StandardBridge)).sig("deposits(address,address)").with_key( + address(L1Token) + ).with_key(address(L2Token)).find(); + + // Give the L1 bridge some ERC20 tokens + vm.store(address(l1StandardBridge), bytes32(slot), bytes32(uint256(100))); + assertEq(l1StandardBridge.deposits(address(L1Token), address(L2Token)), 100); + + vm.expectEmit(address(l1StandardBridge)); + emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); + + vm.expectEmit(address(l1StandardBridge)); + emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); + + vm.expectCall(address(L1Token), abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)); + + vm.mockCall( + address(l1StandardBridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) + ); + vm.prank(address(l1StandardBridge.messenger())); + l1StandardBridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); + + assertEq(L1Token.balanceOf(address(l1StandardBridge)), 0); + assertEq(L1Token.balanceOf(address(alice)), 100); + } +} + +contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer { + /// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge. + function test_finalizeERC20Withdrawal_notMessenger_reverts() external { + vm.mockCall( + address(l1StandardBridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) + ); + vm.prank(address(28)); + vm.expectRevert("StandardBridge: function can only be called from the other bridge"); + l1StandardBridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); + } + + /// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge. + function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external { + vm.mockCall( + address(l1StandardBridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(address(0))) + ); + vm.prank(address(l1StandardBridge.messenger())); + vm.expectRevert("StandardBridge: function can only be called from the other bridge"); + l1StandardBridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); + } +} + +contract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { + /// @dev Tests that finalizing bridged ETH succeeds. + function test_finalizeBridgeETH_succeeds() external { + address messenger = address(l1StandardBridge.messenger()); + vm.mockCall( + messenger, + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) + ); + vm.deal(messenger, 100); + vm.prank(messenger); + + vm.expectEmit(address(l1StandardBridge)); + emit ETHBridgeFinalized(alice, alice, 100, hex""); + + l1StandardBridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); + } +} + +contract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer { + /// @dev Tests that finalizing bridged ETH reverts if the amount is incorrect. + function test_finalizeBridgeETH_incorrectValue_reverts() external { + address messenger = address(l1StandardBridge.messenger()); + vm.mockCall( + messenger, + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) + ); + vm.deal(messenger, 100); + vm.prank(messenger); + vm.expectRevert("StandardBridge: amount sent does not match amount required"); + l1StandardBridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex""); + } + + /// @dev Tests that finalizing bridged ETH reverts if the destination is the L1 bridge. + function test_finalizeBridgeETH_sendToSelf_reverts() external { + address messenger = address(l1StandardBridge.messenger()); + vm.mockCall( + messenger, + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) + ); + vm.deal(messenger, 100); + vm.prank(messenger); + vm.expectRevert("StandardBridge: cannot send to self"); + l1StandardBridge.finalizeBridgeETH{ value: 100 }(alice, address(l1StandardBridge), 100, hex""); + } + + /// @dev Tests that finalizing bridged ETH reverts if the destination is the messenger. + function test_finalizeBridgeETH_sendToMessenger_reverts() external { + address messenger = address(l1StandardBridge.messenger()); + vm.mockCall( + messenger, + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) + ); + vm.deal(messenger, 100); + vm.prank(messenger); + vm.expectRevert("StandardBridge: cannot send to messenger"); + l1StandardBridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex""); + } +} diff --git a/packages/contracts-bedrock/test/L1/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/L1/L2OutputOracle.t.sol new file mode 100644 index 000000000000..7f712e8ff8f7 --- /dev/null +++ b/packages/contracts-bedrock/test/L1/L2OutputOracle.t.sol @@ -0,0 +1,503 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { stdError } from "forge-std/Test.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; +import { NextImpl } from "test/mocks/NextImpl.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Libraries +import { Types } from "src/libraries/Types.sol"; +import { Constants } from "src/libraries/Constants.sol"; + +// Target contract dependencies +import { Proxy } from "src/universal/Proxy.sol"; + +// Target contract +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; + +contract L2OutputOracle_constructor_Test is CommonTest { + /// @dev Tests that constructor sets the initial values correctly. + function test_constructor_succeeds() external { + L2OutputOracle oracleImpl = new L2OutputOracle(); + + assertEq(oracleImpl.SUBMISSION_INTERVAL(), 1); + assertEq(oracleImpl.submissionInterval(), 1); + assertEq(oracleImpl.L2_BLOCK_TIME(), 1); + assertEq(oracleImpl.l2BlockTime(), 1); + assertEq(oracleImpl.latestBlockNumber(), 0); + assertEq(oracleImpl.startingBlockNumber(), 0); + assertEq(oracleImpl.startingTimestamp(), 0); + assertEq(oracleImpl.PROPOSER(), address(0)); + assertEq(oracleImpl.proposer(), address(0)); + assertEq(oracleImpl.CHALLENGER(), address(0)); + assertEq(oracleImpl.challenger(), address(0)); + assertEq(oracleImpl.finalizationPeriodSeconds(), 0); + assertEq(oracleImpl.FINALIZATION_PERIOD_SECONDS(), 0); + } + + /// @dev Tests that the proxy is initialized with the correct values. + function test_initialize_succeeds() external { + address proposer = deploy.cfg().l2OutputOracleProposer(); + address challenger = deploy.cfg().l2OutputOracleChallenger(); + uint256 submissionInterval = deploy.cfg().l2OutputOracleSubmissionInterval(); + uint256 startingBlockNumber = deploy.cfg().l2OutputOracleStartingBlockNumber(); + uint256 startingTimestamp = deploy.cfg().l2OutputOracleStartingTimestamp(); + uint256 l2BlockTime = deploy.cfg().l2BlockTime(); + uint256 finalizationPeriodSeconds = deploy.cfg().finalizationPeriodSeconds(); + + assertEq(l2OutputOracle.SUBMISSION_INTERVAL(), submissionInterval); + assertEq(l2OutputOracle.submissionInterval(), submissionInterval); + assertEq(l2OutputOracle.L2_BLOCK_TIME(), l2BlockTime); + assertEq(l2OutputOracle.l2BlockTime(), l2BlockTime); + assertEq(l2OutputOracle.latestBlockNumber(), startingBlockNumber); + assertEq(l2OutputOracle.startingBlockNumber(), startingBlockNumber); + assertEq(l2OutputOracle.startingTimestamp(), startingTimestamp); + assertEq(l2OutputOracle.finalizationPeriodSeconds(), finalizationPeriodSeconds); + assertEq(l2OutputOracle.PROPOSER(), proposer); + assertEq(l2OutputOracle.proposer(), proposer); + assertEq(l2OutputOracle.CHALLENGER(), challenger); + assertEq(l2OutputOracle.FINALIZATION_PERIOD_SECONDS(), finalizationPeriodSeconds); + assertEq(l2OutputOracle.challenger(), challenger); + } +} + +contract L2OutputOracle_getter_Test is CommonTest { + bytes32 proposedOutput1 = keccak256(abi.encode(1)); + + /// @dev Tests that `latestBlockNumber` returns the correct value. + function test_latestBlockNumber_succeeds() external { + uint256 proposedNumber = l2OutputOracle.nextBlockNumber(); + + // Roll to after the block number we'll propose + warpToProposeTime(proposedNumber); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0); + assertEq(l2OutputOracle.latestBlockNumber(), proposedNumber); + } + + /// @dev Tests that `getL2Output` returns the correct value. + function test_getL2Output_succeeds() external { + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex(); + warpToProposeTime(nextBlockNumber); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0); + + Types.OutputProposal memory proposal = l2OutputOracle.getL2Output(nextOutputIndex); + assertEq(proposal.outputRoot, proposedOutput1); + assertEq(proposal.timestamp, block.timestamp); + + // The block number is larger than the latest proposed output: + vm.expectRevert(stdError.indexOOBError); + l2OutputOracle.getL2Output(nextOutputIndex + 1); + } + + /// @dev Tests that `getL2OutputIndexAfter` returns the correct value + /// when the input is the exact block number of the proposal. + function test_getL2OutputIndexAfter_sameBlock_succeeds() external { + bytes32 output1 = keccak256(abi.encode(1)); + uint256 nextBlockNumber1 = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber1); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); + + // Querying with exact same block as proposed returns the proposal. + uint256 index1 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber1); + assertEq(index1, 0); + } + + /// @dev Tests that `getL2OutputIndexAfter` returns the correct value + /// when the input is the previous block number of the proposal. + function test_getL2OutputIndexAfter_previousBlock_succeeds() external { + bytes32 output1 = keccak256(abi.encode(1)); + uint256 nextBlockNumber1 = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber1); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); + + // Querying with previous block returns the proposal too. + uint256 index1 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber1 - 1); + assertEq(index1, 0); + } + + /// @dev Tests that `getL2OutputIndexAfter` returns the correct value. + function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external { + bytes32 output1 = keccak256(abi.encode(1)); + uint256 nextBlockNumber1 = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber1); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); + + bytes32 output2 = keccak256(abi.encode(2)); + uint256 nextBlockNumber2 = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber2); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output2, nextBlockNumber2, 0, 0); + + bytes32 output3 = keccak256(abi.encode(3)); + uint256 nextBlockNumber3 = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber3); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output3, nextBlockNumber3, 0, 0); + + bytes32 output4 = keccak256(abi.encode(4)); + uint256 nextBlockNumber4 = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber4); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output4, nextBlockNumber4, 0, 0); + + // Querying with a block number between the first and second proposal + uint256 index1 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber1 + 1); + assertEq(index1, 1); + + // Querying with a block number between the second and third proposal + uint256 index2 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber2 + 1); + assertEq(index2, 2); + + // Querying with a block number between the third and fourth proposal + uint256 index3 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber3 + 1); + assertEq(index3, 3); + } + + /// @dev Tests that `getL2OutputIndexAfter` reverts when no output exists. + function test_getL2OutputIndexAfter_noOutputsExis_reverts() external { + vm.expectRevert("L2OutputOracle: cannot get output as no outputs have been proposed yet"); + l2OutputOracle.getL2OutputIndexAfter(0); + } + + /// @dev Tests that `nextBlockNumber` returns the correct value. + function test_nextBlockNumber_succeeds() external { + assertEq( + l2OutputOracle.nextBlockNumber(), + // The return value should match this arithmetic + l2OutputOracle.latestBlockNumber() + l2OutputOracle.SUBMISSION_INTERVAL() + ); + } + + /// @dev Tests that `computeL2Timestamp` returns the correct value. + function test_computeL2Timestamp_succeeds() external { + uint256 startingBlockNumber = deploy.cfg().l2OutputOracleStartingBlockNumber(); + uint256 startingTimestamp = deploy.cfg().l2OutputOracleStartingTimestamp(); + uint256 l2BlockTime = deploy.cfg().l2BlockTime(); + + // reverts if timestamp is too low + vm.expectRevert(stdError.arithmeticError); + l2OutputOracle.computeL2Timestamp(startingBlockNumber - 1); + + // check timestamp for the very first block + assertEq(l2OutputOracle.computeL2Timestamp(startingBlockNumber), startingTimestamp); + + // check timestamp for the first block after the starting block + assertEq(l2OutputOracle.computeL2Timestamp(startingBlockNumber + 1), startingTimestamp + l2BlockTime); + + // check timestamp for some other block number + assertEq( + l2OutputOracle.computeL2Timestamp(startingBlockNumber + 96024), startingTimestamp + l2BlockTime * 96024 + ); + } +} + +contract L2OutputOracle_proposeL2Output_Test is CommonTest { + /// @dev Test that `proposeL2Output` succeeds for a valid input + /// and when a block hash and number are not specified. + function test_proposeL2Output_proposeAnotherOutput_succeeds() public { + proposeAnotherOutput(); + } + + /// @dev Tests that `proposeL2Output` succeeds when given valid input and + /// when a block hash and number are specified for reorg protection. + function test_proposeWithBlockhashAndHeight_succeeds() external { + // Get the number and hash of a previous block in the chain + uint256 prevL1BlockNumber = block.number - 1; + bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber); + + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber); + } + + /// @dev Tests that `proposeL2Output` reverts when called by a party + /// that is not the proposer. + function test_proposeL2Output_notProposer_reverts() external { + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber); + + vm.prank(address(128)); + vm.expectRevert("L2OutputOracle: only the proposer address can propose new outputs"); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); + } + + /// @dev Tests that `proposeL2Output` reverts when given a zero blockhash. + function test_proposeL2Output_emptyOutput_reverts() external { + bytes32 outputToPropose = bytes32(0); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + vm.expectRevert("L2OutputOracle: L2 output proposal cannot be the zero hash"); + l2OutputOracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0); + } + + /// @dev Tests that `proposeL2Output` reverts when given a block number + /// that does not match the next expected block number. + function test_proposeL2Output_unexpectedBlockNumber_reverts() external { + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + vm.expectRevert("L2OutputOracle: block number must be equal to next expected block number"); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0); + } + + /// @dev Tests that `proposeL2Output` reverts when given a block number + /// that has a timestamp in the future. + function test_proposeL2Output_futureTimetamp_reverts() external { + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + uint256 nextTimestamp = l2OutputOracle.computeL2Timestamp(nextBlockNumber); + vm.warp(nextTimestamp); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + vm.expectRevert("L2OutputOracle: cannot propose L2 output in the future"); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); + } + + /// @dev Tests that `proposeL2Output` reverts when given a block number + /// whose hash does not match the given block hash. + function test_proposeL2Output_wrongFork_reverts() external { + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height"); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, bytes32(uint256(0x01)), block.number); + } + + /// @dev Tests that `proposeL2Output` reverts when given a block number + /// whose block hash does not match the given block hash. + function test_proposeL2Output_unmatchedBlockhash_reverts() external { + // Move ahead to block 100 so that we can reference historical blocks + vm.roll(100); + + // Get the number and hash of a previous block in the chain + uint256 l1BlockNumber = block.number - 1; + bytes32 l1BlockHash = blockhash(l1BlockNumber); + + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + warpToProposeTime(nextBlockNumber); + vm.prank(deploy.cfg().l2OutputOracleProposer()); + + // This will fail when foundry no longer returns zerod block hashes + vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height"); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1); + } +} + +contract L2OutputOracle_deleteOutputs_Test is CommonTest { + /// @dev Tests that `deleteL2Outputs` succeeds for a single output. + function test_deleteOutputs_singleOutput_succeeds() external { + proposeAnotherOutput(); + proposeAnotherOutput(); + + uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber(); + uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex(); + Types.OutputProposal memory newLatestOutput = l2OutputOracle.getL2Output(latestOutputIndex - 1); + + vm.prank(l2OutputOracle.CHALLENGER()); + vm.prank(l2OutputOracle.challenger()); + vm.expectEmit(true, true, false, false); + emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex); + l2OutputOracle.deleteL2Outputs(latestOutputIndex); + + // validate latestBlockNumber has been reduced + uint256 latestBlockNumberAfter = l2OutputOracle.latestBlockNumber(); + uint256 latestOutputIndexAfter = l2OutputOracle.latestOutputIndex(); + uint256 submissionInterval = deploy.cfg().l2OutputOracleSubmissionInterval(); + assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter); + + // validate that the new latest output is as expected. + Types.OutputProposal memory proposal = l2OutputOracle.getL2Output(latestOutputIndexAfter); + assertEq(newLatestOutput.outputRoot, proposal.outputRoot); + assertEq(newLatestOutput.timestamp, proposal.timestamp); + } + + /// @dev Tests that `deleteL2Outputs` succeeds for multiple outputs. + function test_deleteOutputs_multipleOutputs_succeeds() external { + proposeAnotherOutput(); + proposeAnotherOutput(); + proposeAnotherOutput(); + proposeAnotherOutput(); + + uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber(); + uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex(); + Types.OutputProposal memory newLatestOutput = l2OutputOracle.getL2Output(latestOutputIndex - 3); + + vm.prank(l2OutputOracle.CHALLENGER()); + vm.prank(l2OutputOracle.challenger()); + vm.expectEmit(true, true, false, false); + emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2); + l2OutputOracle.deleteL2Outputs(latestOutputIndex - 2); + + // validate latestBlockNumber has been reduced + uint256 latestBlockNumberAfter = l2OutputOracle.latestBlockNumber(); + uint256 latestOutputIndexAfter = l2OutputOracle.latestOutputIndex(); + uint256 submissionInterval = deploy.cfg().l2OutputOracleSubmissionInterval(); + assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter); + + // validate that the new latest output is as expected. + Types.OutputProposal memory proposal = l2OutputOracle.getL2Output(latestOutputIndexAfter); + assertEq(newLatestOutput.outputRoot, proposal.outputRoot); + assertEq(newLatestOutput.timestamp, proposal.timestamp); + } + + /// @dev Tests that `deleteL2Outputs` reverts when not called by the challenger. + function test_deleteL2Outputs_ifNotChallenger_reverts() external { + uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber(); + + vm.expectRevert("L2OutputOracle: only the challenger address can delete outputs"); + l2OutputOracle.deleteL2Outputs(latestBlockNumber); + } + + /// @dev Tests that `deleteL2Outputs` reverts for a non-existant output index. + function test_deleteL2Outputs_nonExistent_reverts() external { + proposeAnotherOutput(); + + uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber(); + + vm.prank(l2OutputOracle.CHALLENGER()); + vm.prank(l2OutputOracle.challenger()); + vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index"); + l2OutputOracle.deleteL2Outputs(latestBlockNumber + 1); + } + + /// @dev Tests that `deleteL2Outputs` reverts when trying to delete outputs + /// after the latest output index. + function test_deleteL2Outputs_afterLatest_reverts() external { + proposeAnotherOutput(); + proposeAnotherOutput(); + proposeAnotherOutput(); + + // Delete the latest two outputs + uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex(); + vm.prank(l2OutputOracle.CHALLENGER()); + vm.prank(l2OutputOracle.challenger()); + l2OutputOracle.deleteL2Outputs(latestOutputIndex - 2); + + // Now try to delete the same output again + vm.prank(l2OutputOracle.CHALLENGER()); + vm.prank(l2OutputOracle.challenger()); + vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index"); + l2OutputOracle.deleteL2Outputs(latestOutputIndex - 2); + } + + /// @dev Tests that `deleteL2Outputs` reverts for finalized outputs. + function test_deleteL2Outputs_finalized_reverts() external { + proposeAnotherOutput(); + + // Warp past the finalization period + 1 second + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + + uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex(); + + // Try to delete a finalized output + vm.prank(l2OutputOracle.CHALLENGER()); + vm.prank(l2OutputOracle.challenger()); + vm.expectRevert("L2OutputOracle: cannot delete outputs that have already been finalized"); + l2OutputOracle.deleteL2Outputs(latestOutputIndex); + } +} + +contract L2OutputOracleUpgradeable_Test is CommonTest { + /// @dev Tests that the proxy can be successfully upgraded. + function test_upgrading_succeeds() external { + Proxy proxy = Proxy(deploy.mustGetAddress("L2OutputOracleProxy")); + // Check an unused slot before upgrading. + bytes32 slot21Before = vm.load(address(l2OutputOracle), bytes32(uint256(21))); + assertEq(bytes32(0), slot21Before); + + NextImpl nextImpl = new NextImpl(); + vm.startPrank(EIP1967Helper.getAdmin(address(proxy))); + // Reviewer note: the NextImpl() still uses reinitializer. If we want to remove that, we'll need to use a + // two step upgrade with the Storage lib. + proxy.upgradeToAndCall(address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, 2)); + assertEq(proxy.implementation(), address(nextImpl)); + + // Verify that the NextImpl contract initialized its values according as expected + bytes32 slot21After = vm.load(address(l2OutputOracle), bytes32(uint256(21))); + bytes32 slot21Expected = NextImpl(address(l2OutputOracle)).slot21Init(); + assertEq(slot21Expected, slot21After); + } + + /// @dev Tests that initialize reverts if the submissionInterval is zero. + function test_initialize_submissionInterval_reverts() external { + // Reset the initialized field in the 0th storage slot + // so that initialize can be called again. + vm.store(address(l2OutputOracle), bytes32(uint256(0)), bytes32(uint256(0))); + + uint256 l2BlockTime = deploy.cfg().l2BlockTime(); + uint256 startingBlockNumber = deploy.cfg().l2OutputOracleStartingBlockNumber(); + uint256 startingTimestamp = deploy.cfg().l2OutputOracleStartingTimestamp(); + address proposer = deploy.cfg().l2OutputOracleProposer(); + address challenger = deploy.cfg().l2OutputOracleChallenger(); + uint256 finalizationPeriodSeconds = deploy.cfg().finalizationPeriodSeconds(); + + vm.expectRevert("L2OutputOracle: submission interval must be greater than 0"); + l2OutputOracle.initialize({ + _submissionInterval: 0, + _l2BlockTime: l2BlockTime, + _startingBlockNumber: startingBlockNumber, + _startingTimestamp: startingTimestamp, + _proposer: proposer, + _challenger: challenger, + _finalizationPeriodSeconds: finalizationPeriodSeconds + }); + } + + /// @dev Tests that initialize reverts if the l2BlockTime is invalid. + function test_initialize_l2BlockTimeZero_reverts() external { + // Reset the initialized field in the 0th storage slot + // so that initialize can be called again. + vm.store(address(l2OutputOracle), bytes32(uint256(0)), bytes32(uint256(0))); + + uint256 submissionInterval = deploy.cfg().l2OutputOracleSubmissionInterval(); + uint256 startingBlockNumber = deploy.cfg().l2OutputOracleStartingBlockNumber(); + uint256 startingTimestamp = deploy.cfg().l2OutputOracleStartingTimestamp(); + address proposer = deploy.cfg().l2OutputOracleProposer(); + address challenger = deploy.cfg().l2OutputOracleChallenger(); + uint256 finalizationPeriodSeconds = deploy.cfg().finalizationPeriodSeconds(); + + vm.expectRevert("L2OutputOracle: L2 block time must be greater than 0"); + l2OutputOracle.initialize({ + _submissionInterval: submissionInterval, + _l2BlockTime: 0, + _startingBlockNumber: startingBlockNumber, + _startingTimestamp: startingTimestamp, + _proposer: proposer, + _challenger: challenger, + _finalizationPeriodSeconds: finalizationPeriodSeconds + }); + } + + /// @dev Tests that initialize reverts if the starting timestamp is invalid. + function test_initialize_badTimestamp_reverts() external { + // Reset the initialized field in the 0th storage slot + // so that initialize can be called again. + vm.store(address(l2OutputOracle), bytes32(uint256(0)), bytes32(uint256(0))); + + uint256 submissionInterval = deploy.cfg().l2OutputOracleSubmissionInterval(); + uint256 l2BlockTime = deploy.cfg().l2BlockTime(); + uint256 startingBlockNumber = deploy.cfg().l2OutputOracleStartingBlockNumber(); + address proposer = deploy.cfg().l2OutputOracleProposer(); + address challenger = deploy.cfg().l2OutputOracleChallenger(); + uint256 finalizationPeriodSeconds = deploy.cfg().finalizationPeriodSeconds(); + + vm.expectRevert("L2OutputOracle: starting L2 timestamp must be less than current time"); + l2OutputOracle.initialize({ + _submissionInterval: submissionInterval, + _l2BlockTime: l2BlockTime, + _startingBlockNumber: startingBlockNumber, + _startingTimestamp: block.timestamp + 1, + _proposer: proposer, + _challenger: challenger, + _finalizationPeriodSeconds: finalizationPeriodSeconds + }); + } +} diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol new file mode 100644 index 000000000000..58679b313ee9 --- /dev/null +++ b/packages/contracts-bedrock/test/L1/OptimismPortal.t.sol @@ -0,0 +1,1029 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { stdError } from "forge-std/Test.sol"; + +import { CommonTest } from "test/setup/CommonTest.sol"; +import { NextImpl } from "test/mocks/NextImpl.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Libraries +import { Types } from "src/libraries/Types.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { Constants } from "src/libraries/Constants.sol"; + +// Target contract dependencies +import { Proxy } from "src/universal/Proxy.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; + +contract OptimismPortal_Test is CommonTest { + address depositor; + + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function setUp() public virtual override { + super.setUp(); + depositor = makeAddr("depositor"); + } + + /// @dev Tests that the constructor sets the correct values. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function test_constructor_succeeds() external virtual { + OptimismPortal opImpl = OptimismPortal(payable(deploy.mustGetAddress("OptimismPortal"))); + assertEq(address(opImpl.L2_ORACLE()), address(0)); + assertEq(address(opImpl.l2Oracle()), address(0)); + assertEq(address(opImpl.SYSTEM_CONFIG()), address(0)); + assertEq(address(opImpl.systemConfig()), address(0)); + assertEq(address(opImpl.superchainConfig()), address(0)); + assertEq(opImpl.l2Sender(), Constants.DEFAULT_L2_SENDER); + (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = opImpl.params(); + assertEq(prevBaseFee, 1 gwei); + assertEq(prevBoughtGas, 0); + assertEq(prevBlockNum, uint64(block.number)); + } + + /// @dev Tests that the initializer sets the correct values. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function test_initialize_succeeds() external virtual { + address guardian = deploy.cfg().superchainConfigGuardian(); + assertEq(address(optimismPortal.L2_ORACLE()), address(l2OutputOracle)); + assertEq(address(optimismPortal.l2Oracle()), address(l2OutputOracle)); + assertEq(address(optimismPortal.SYSTEM_CONFIG()), address(systemConfig)); + assertEq(address(optimismPortal.systemConfig()), address(systemConfig)); + assertEq(optimismPortal.GUARDIAN(), guardian); + assertEq(optimismPortal.guardian(), guardian); + assertEq(address(optimismPortal.superchainConfig()), address(superchainConfig)); + assertEq(optimismPortal.l2Sender(), Constants.DEFAULT_L2_SENDER); + assertEq(optimismPortal.paused(), false); + (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params(); + assertEq(prevBaseFee, 1 gwei); + assertEq(prevBoughtGas, 0); + assertEq(prevBlockNum, uint64(block.number)); + } + + /// @dev Tests that `pause` successfully pauses + /// when called by the GUARDIAN. + function test_pause_succeeds() external { + address guardian = optimismPortal.GUARDIAN(); + + assertEq(optimismPortal.paused(), false); + + vm.expectEmit(address(superchainConfig)); + emit Paused("identifier"); + + vm.prank(guardian); + superchainConfig.pause("identifier"); + + assertEq(optimismPortal.paused(), true); + } + + /// @dev Tests that `pause` reverts when called by a non-GUARDIAN. + function test_pause_onlyGuardian_reverts() external { + assertEq(optimismPortal.paused(), false); + + assertTrue(optimismPortal.GUARDIAN() != alice); + vm.expectRevert("SuperchainConfig: only guardian can pause"); + vm.prank(alice); + superchainConfig.pause("identifier"); + + assertEq(optimismPortal.paused(), false); + } + + /// @dev Tests that `unpause` successfully unpauses + /// when called by the GUARDIAN. + function test_unpause_succeeds() external { + address guardian = optimismPortal.GUARDIAN(); + + vm.prank(guardian); + superchainConfig.pause("identifier"); + assertEq(optimismPortal.paused(), true); + + vm.expectEmit(address(superchainConfig)); + emit Unpaused(); + vm.prank(guardian); + superchainConfig.unpause(); + + assertEq(optimismPortal.paused(), false); + } + + /// @dev Tests that `unpause` reverts when called by a non-GUARDIAN. + function test_unpause_onlyGuardian_reverts() external { + address guardian = optimismPortal.GUARDIAN(); + + vm.prank(guardian); + superchainConfig.pause("identifier"); + assertEq(optimismPortal.paused(), true); + + assertTrue(optimismPortal.GUARDIAN() != alice); + vm.expectRevert("SuperchainConfig: only guardian can unpause"); + vm.prank(alice); + superchainConfig.unpause(); + + assertEq(optimismPortal.paused(), true); + } + + /// @dev Tests that `receive` successdully deposits ETH. + function testFuzz_receive_succeeds(uint256 _value) external { + vm.expectEmit(address(optimismPortal)); + emitTransactionDeposited({ + _from: alice, + _to: alice, + _value: _value, + _mint: _value, + _gasLimit: 100_000, + _isCreation: false, + _data: hex"" + }); + + // give alice money and send as an eoa + vm.deal(alice, _value); + vm.prank(alice, alice); + (bool s,) = address(optimismPortal).call{ value: _value }(hex""); + + assertTrue(s); + assertEq(address(optimismPortal).balance, _value); + } + + /// @dev Tests that `depositTransaction` reverts when the destination address is non-zero + /// for a contract creation deposit. + function test_depositTransaction_contractCreation_reverts() external { + // contract creation must have a target of address(0) + vm.expectRevert("OptimismPortal: must send to address(0) when creating a contract"); + optimismPortal.depositTransaction(address(1), 1, 0, true, hex""); + } + + /// @dev Tests that `depositTransaction` reverts when the data is too large. + /// This places an upper bound on unsafe blocks sent over p2p. + function test_depositTransaction_largeData_reverts() external { + uint256 size = 120_001; + uint64 gasLimit = optimismPortal.minimumGasLimit(uint64(size)); + vm.expectRevert("OptimismPortal: data too large"); + optimismPortal.depositTransaction({ + _to: address(0), + _value: 0, + _gasLimit: gasLimit, + _isCreation: false, + _data: new bytes(size) + }); + } + + /// @dev Tests that `depositTransaction` reverts when the gas limit is too small. + function test_depositTransaction_smallGasLimit_reverts() external { + vm.expectRevert("OptimismPortal: gas limit too small"); + optimismPortal.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" }); + } + + /// @dev Tests that `depositTransaction` succeeds for small, + /// but sufficient, gas limits. + function testFuzz_depositTransaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external { + uint64 gasLimit = optimismPortal.minimumGasLimit(uint64(_data.length)); + if (_shouldFail) { + gasLimit = uint64(bound(gasLimit, 0, gasLimit - 1)); + vm.expectRevert("OptimismPortal: gas limit too small"); + } + + optimismPortal.depositTransaction({ + _to: address(0x40), + _value: 0, + _gasLimit: gasLimit, + _isCreation: false, + _data: _data + }); + } + + /// @dev Tests that `minimumGasLimit` succeeds for small calldata sizes. + /// The gas limit should be 21k for 0 calldata and increase linearly + /// for larger calldata sizes. + function test_minimumGasLimit_succeeds() external { + assertEq(optimismPortal.minimumGasLimit(0), 21_000); + assertTrue(optimismPortal.minimumGasLimit(2) > optimismPortal.minimumGasLimit(1)); + assertTrue(optimismPortal.minimumGasLimit(3) > optimismPortal.minimumGasLimit(2)); + } + + /// @dev Tests that `depositTransaction` succeeds for an EOA. + function testFuzz_depositTransaction_eoa_succeeds( + address _to, + uint64 _gasLimit, + uint256 _value, + uint256 _mint, + bool _isCreation, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound( + _gasLimit, + optimismPortal.minimumGasLimit(uint64(_data.length)), + systemConfig.resourceConfig().maxResourceLimit + ) + ); + if (_isCreation) _to = address(0); + + // EOA emulation + vm.expectEmit(address(optimismPortal)); + emitTransactionDeposited({ + _from: depositor, + _to: _to, + _value: _value, + _mint: _mint, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + + vm.deal(depositor, _mint); + vm.prank(depositor, depositor); + optimismPortal.depositTransaction{ value: _mint }({ + _to: _to, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + assertEq(address(optimismPortal).balance, _mint); + } + + /// @dev Tests that `depositTransaction` succeeds for a contract. + function testFuzz_depositTransaction_contract_succeeds( + address _to, + uint64 _gasLimit, + uint256 _value, + uint256 _mint, + bool _isCreation, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound( + _gasLimit, + optimismPortal.minimumGasLimit(uint64(_data.length)), + systemConfig.resourceConfig().maxResourceLimit + ) + ); + if (_isCreation) _to = address(0); + + vm.expectEmit(address(optimismPortal)); + emitTransactionDeposited({ + _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), + _to: _to, + _value: _value, + _mint: _mint, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + + vm.deal(address(this), _mint); + vm.prank(address(this)); + optimismPortal.depositTransaction{ value: _mint }({ + _to: _to, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + assertEq(address(optimismPortal).balance, _mint); + } + + /// @dev Tests that `isOutputFinalized` succeeds for an EOA depositing a tx with ETH and data. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function test_simple_isOutputFinalized_succeeds() external virtual { + uint256 startingBlockNumber = deploy.cfg().l2OutputOracleStartingBlockNumber(); + + uint256 ts = block.timestamp; + vm.mockCall( + address(optimismPortal.l2Oracle()), + abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encode(Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))) + ); + + // warp to the finalization period + vm.warp(ts + l2OutputOracle.FINALIZATION_PERIOD_SECONDS()); + assertEq(optimismPortal.isOutputFinalized(0), false); + + // warp past the finalization period + vm.warp(ts + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + assertEq(optimismPortal.isOutputFinalized(0), true); + } + + /// @dev Tests `isOutputFinalized` for a finalized output. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function test_isOutputFinalized_succeeds() external virtual { + uint256 checkpoint = l2OutputOracle.nextBlockNumber(); + uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex(); + vm.roll(checkpoint); + vm.warp(l2OutputOracle.computeL2Timestamp(checkpoint) + 1); + vm.prank(l2OutputOracle.PROPOSER()); + l2OutputOracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0); + + // warp to the final second of the finalization period + uint256 finalizationHorizon = block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS(); + vm.warp(finalizationHorizon); + // The checkpointed block should not be finalized until 1 second from now. + assertEq(optimismPortal.isOutputFinalized(nextOutputIndex), false); + // Nor should a block after it + vm.expectRevert(stdError.indexOOBError); + assertEq(optimismPortal.isOutputFinalized(nextOutputIndex + 1), false); + // warp past the finalization period + vm.warp(finalizationHorizon + 1); + // It should now be finalized. + assertEq(optimismPortal.isOutputFinalized(nextOutputIndex), true); + // But not the block after it. + vm.expectRevert(stdError.indexOOBError); + assertEq(optimismPortal.isOutputFinalized(nextOutputIndex + 1), false); + } +} + +contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest { + // Reusable default values for a test withdrawal + Types.WithdrawalTransaction _defaultTx; + + uint256 _proposedOutputIndex; + uint256 _proposedBlockNumber; + bytes32 _stateRoot; + bytes32 _storageRoot; + bytes32 _outputRoot; + bytes32 _withdrawalHash; + bytes[] _withdrawalProof; + Types.OutputRootProof internal _outputRootProof; + + // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls. + constructor() { + super.setUp(); + _defaultTx = Types.WithdrawalTransaction({ + nonce: 0, + sender: alice, + target: bob, + value: 100, + gasLimit: 100_000, + data: hex"" + }); + // Get withdrawal proof data we can use for testing. + (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = + ffi.getProveWithdrawalTransactionInputs(_defaultTx); + + // Setup a dummy output root proof for reuse. + _outputRootProof = Types.OutputRootProof({ + version: bytes32(uint256(0)), + stateRoot: _stateRoot, + messagePasserStorageRoot: _storageRoot, + latestBlockhash: bytes32(uint256(0)) + }); + _proposedBlockNumber = l2OutputOracle.nextBlockNumber(); + _proposedOutputIndex = l2OutputOracle.nextOutputIndex(); + } + + /// @dev Setup the system for a ready-to-use state. + function setUp() public override { + // Configure the oracle to return the output root we've prepared. + vm.warp(l2OutputOracle.computeL2Timestamp(_proposedBlockNumber) + 1); + vm.prank(l2OutputOracle.PROPOSER()); + l2OutputOracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); + + // Warp beyond the finalization period for the block we've proposed. + vm.warp( + l2OutputOracle.getL2Output(_proposedOutputIndex).timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + + 1 + ); + // Fund the portal so that we can withdraw ETH. + vm.deal(address(optimismPortal), 0xFFFFFFFF); + } + + /// @dev Asserts that the reentrant call will revert. + function callPortalAndExpectRevert() external payable { + vm.expectRevert("OptimismPortal: can only trigger one withdrawal per transaction"); + // Arguments here don't matter, as the require check is the first thing that happens. + // We assume that this has already been proven. + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + // Assert that the withdrawal was not finalized. + assertFalse(optimismPortal.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx))); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts when paused. + function test_proveWithdrawalTransaction_paused_reverts() external { + vm.prank(optimismPortal.GUARDIAN()); + superchainConfig.pause("identifier"); + + vm.expectRevert("OptimismPortal: paused"); + optimismPortal.proveWithdrawalTransaction({ + _tx: _defaultTx, + _l2OutputIndex: _proposedOutputIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts when the target is the portal contract. + function test_proveWithdrawalTransaction_onSelfCall_reverts() external { + _defaultTx.target = address(optimismPortal); + vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract"); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts when + /// the outputRootProof does not match the output root + function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external { + // Modify the version to invalidate the withdrawal proof. + _outputRootProof.version = bytes32(uint256(1)); + vm.expectRevert("OptimismPortal: invalid output root proof"); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal is missing. + function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external { + // modify the default test values to invalidate the proof. + _defaultTx.data = hex"abcd"; + vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key"); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal has already + /// been proven. + function test_proveWithdrawalTransaction_replayProve_reverts() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + vm.expectRevert("OptimismPortal: withdrawal hash has already been proven"); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + } + + /// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already + /// been proven and the output root has changed and the l2BlockNumber stays the same. + function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash` + // inside of the `provenWithdrawal`s mapping. + bytes32 slot; + assembly { + mstore(0x00, sload(_withdrawalHash.slot)) + mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in the OptimismPortal + slot := keccak256(0x00, 0x40) + } + + // Store a different output root within the `provenWithdrawals` mapping without + // touching the l2BlockNumber or timestamp. + vm.store(address(optimismPortal), slot, bytes32(0)); + + // Warp ahead 1 second + vm.warp(block.timestamp + 1); + + // Even though we have already proven this withdrawalHash, we should be allowed to re-submit + // our proof with a changed outputRoot + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + // Ensure that the withdrawal was updated within the mapping + (, uint128 timestamp,) = optimismPortal.provenWithdrawals(_withdrawalHash); + assertEq(timestamp, block.timestamp); + } + + /// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already + /// been proven and the output root, output index, and l2BlockNumber have changed. + function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash` + // inside of the `provenWithdrawal`s mapping. + bytes32 slot; + assembly { + mstore(0x00, sload(_withdrawalHash.slot)) + mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in OptimismPortal + slot := keccak256(0x00, 0x40) + } + + // Store a dummy output root within the `provenWithdrawals` mapping without touching the + // l2BlockNumber or timestamp. + vm.store(address(optimismPortal), slot, bytes32(0)); + + // Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle + Types.OutputProposal memory proposal = optimismPortal.l2Oracle().getL2Output(_proposedOutputIndex); + + // Propose the same output root again, creating the same output at a different index + l2BlockNumber. + vm.startPrank(optimismPortal.l2Oracle().PROPOSER()); + optimismPortal.l2Oracle().proposeL2Output( + proposal.outputRoot, optimismPortal.l2Oracle().nextBlockNumber(), blockhash(block.number), block.number + ); + vm.stopPrank(); + + // Warp ahead 1 second + vm.warp(block.timestamp + 1); + + // Even though we have already proven this withdrawalHash, we should be allowed to re-submit + // our proof with a changed outputRoot + a different output index + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction( + _defaultTx, _proposedOutputIndex + 1, _outputRootProof, _withdrawalProof + ); + + // Ensure that the withdrawal was updated within the mapping + (, uint128 timestamp,) = optimismPortal.provenWithdrawals(_withdrawalHash); + assertEq(timestamp, block.timestamp); + } + + /// @dev Tests that `proveWithdrawalTransaction` succeeds. + function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` succeeds. + function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external { + uint256 bobBalanceBefore = address(bob).balance; + + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.expectEmit(true, true, false, true); + emit WithdrawalFinalized(_withdrawalHash, true); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + + assert(address(bob).balance == bobBalanceBefore + 100); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the contract is paused. + function test_finalizeWithdrawalTransaction_paused_reverts() external { + vm.prank(optimismPortal.GUARDIAN()); + superchainConfig.pause("identifier"); + + vm.expectRevert("OptimismPortal: paused"); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been + function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + vm.expectRevert("OptimismPortal: withdrawal has not been proven yet"); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + + assert(address(bob).balance == bobBalanceBefore); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been + /// proven long enough ago. + function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + // Mock a call where the resulting output root is anything but the original output root. In + // this case we just use bytes32(uint256(1)). + vm.mockCall( + address(optimismPortal.l2Oracle()), + abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encode(bytes32(uint256(1)), _proposedBlockNumber) + ); + + vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + + assert(address(bob).balance == bobBalanceBefore); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the provenWithdrawal's timestamp + /// is less than the L2 output oracle's starting timestamp. + function test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + // Prove our withdrawal + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + // Warp to after the finalization period + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + + // Mock a startingTimestamp change on the L2 Oracle + vm.mockCall( + address(optimismPortal.l2Oracle()), + abi.encodeWithSignature("startingTimestamp()"), + abi.encode(block.timestamp + 1) + ); + + // Attempt to finalize the withdrawal + vm.expectRevert("OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp"); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + + // Ensure that bob's balance has remained the same + assertEq(bobBalanceBefore, address(bob).balance); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the output root proven is not the + /// same as the output root at the time of finalization. + function test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + // Prove our withdrawal + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + // Warp to after the finalization period + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + + // Mock an outputRoot change on the output proposal before attempting + // to finalize the withdrawal. + vm.mockCall( + address(optimismPortal.l2Oracle()), + abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encode( + Types.OutputProposal(bytes32(uint256(0)), uint128(block.timestamp), uint128(_proposedBlockNumber)) + ) + ); + + // Attempt to finalize the withdrawal + vm.expectRevert("OptimismPortal: output root proven is not the same as current output root"); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + + // Ensure that bob's balance has remained the same + assertEq(bobBalanceBefore, address(bob).balance); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the output proposal's timestamp + /// has not passed the finalization period. + function test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + // Prove our withdrawal + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + // Warp to after the finalization period + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + + // Mock a timestamp change on the output proposal that has not passed the + // finalization period. + vm.mockCall( + address(optimismPortal.l2Oracle()), + abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encode(Types.OutputProposal(_outputRoot, uint128(block.timestamp + 1), uint128(_proposedBlockNumber))) + ); + + // Attempt to finalize the withdrawal + vm.expectRevert("OptimismPortal: output proposal finalization period has not elapsed"); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + + // Ensure that bob's balance has remained the same + assertEq(bobBalanceBefore, address(bob).balance); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the target reverts. + function test_finalizeWithdrawalTransaction_targetFails_fails() external { + uint256 bobBalanceBefore = address(bob).balance; + vm.etch(bob, hex"fe"); // Contract with just the invalid opcode. + + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.expectEmit(true, true, true, true); + emit WithdrawalFinalized(_withdrawalHash, false); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + + assert(address(bob).balance == bobBalanceBefore); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the finalization period + /// has not yet passed. + function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external { + // Setup the Oracle to return an output with a recent timestamp + uint256 recentTimestamp = block.timestamp - 1; + vm.mockCall( + address(optimismPortal.l2Oracle()), + abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encode(Types.OutputProposal(_outputRoot, uint128(recentTimestamp), uint128(_proposedBlockNumber))) + ); + + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has already been + /// finalized. + function test_finalizeWithdrawalTransaction_onReplay_reverts() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.expectEmit(true, true, true, true); + emit WithdrawalFinalized(_withdrawalHash, true); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + + vm.expectRevert("OptimismPortal: withdrawal has already been finalized"); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal transaction + /// does not have enough gas to execute. + function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external { + // This number was identified through trial and error. + uint256 gasLimit = 150_000; + Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({ + nonce: 0, + sender: alice, + target: bob, + value: 100, + gasLimit: gasLimit, + data: hex"" + }); + + // Get updated proof inputs. + (bytes32 stateRoot, bytes32 storageRoot,,, bytes[] memory withdrawalProof) = + ffi.getProveWithdrawalTransactionInputs(insufficientGasTx); + Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({ + version: bytes32(0), + stateRoot: stateRoot, + messagePasserStorageRoot: storageRoot, + latestBlockhash: bytes32(0) + }); + + vm.mockCall( + address(optimismPortal.l2Oracle()), + abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encode( + Types.OutputProposal( + Hashing.hashOutputRootProof(outputRootProof), + uint128(block.timestamp), + uint128(_proposedBlockNumber) + ) + ) + ); + + optimismPortal.proveWithdrawalTransaction( + insufficientGasTx, _proposedOutputIndex, outputRootProof, withdrawalProof + ); + + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.expectRevert("SafeCall: Not enough gas"); + optimismPortal.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if a sub-call attempts to finalize + /// another withdrawal. + function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + // Copy and modify the default test values to attempt a reentrant call by first calling to + // this contract's callPortalAndExpectRevert() function above. + Types.WithdrawalTransaction memory _testTx = _defaultTx; + _testTx.target = address(this); + _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector); + + // Get modified proof inputs. + ( + bytes32 stateRoot, + bytes32 storageRoot, + bytes32 outputRoot, + bytes32 withdrawalHash, + bytes[] memory withdrawalProof + ) = ffi.getProveWithdrawalTransactionInputs(_testTx); + Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({ + version: bytes32(0), + stateRoot: stateRoot, + messagePasserStorageRoot: storageRoot, + latestBlockhash: bytes32(0) + }); + + // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp. + uint256 finalizedTimestamp = block.timestamp - l2OutputOracle.FINALIZATION_PERIOD_SECONDS() - 1; + vm.mockCall( + address(optimismPortal.l2Oracle()), + abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encode(Types.OutputProposal(outputRoot, uint128(finalizedTimestamp), uint128(_proposedBlockNumber))) + ); + + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(withdrawalHash, alice, address(this)); + optimismPortal.proveWithdrawalTransaction(_testTx, _proposedBlockNumber, outputRootProof, withdrawalProof); + + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.expectCall(address(this), _testTx.data); + vm.expectEmit(true, true, true, true); + emit WithdrawalFinalized(withdrawalHash, true); + optimismPortal.finalizeWithdrawalTransaction(_testTx); + + // Ensure that bob's balance was not changed by the reentrant call. + assert(address(bob).balance == bobBalanceBefore); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` succeeds. + function testDiff_finalizeWithdrawalTransaction_succeeds( + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) + external + { + vm.assume( + _target != address(optimismPortal) // Cannot call the optimism portal or a contract + && _target.code.length == 0 // No accounts with code + && _target != CONSOLE // The console has no code but behaves like a contract + && uint160(_target) > 9 // No precompiles (or zero address) + ); + + // Total ETH supply is currently about 120M ETH. + uint256 value = bound(_value, 0, 200_000_000 ether); + vm.deal(address(optimismPortal), value); + + uint256 gasLimit = bound(_gasLimit, 0, 50_000_000); + uint256 nonce = l2ToL1MessagePasser.messageNonce(); + + // Get a withdrawal transaction and mock proof from the differential testing script. + Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({ + nonce: nonce, + sender: _sender, + target: _target, + value: value, + gasLimit: gasLimit, + data: _data + }); + ( + bytes32 stateRoot, + bytes32 storageRoot, + bytes32 outputRoot, + bytes32 withdrawalHash, + bytes[] memory withdrawalProof + ) = ffi.getProveWithdrawalTransactionInputs(_tx); + + // Create the output root proof + Types.OutputRootProof memory proof = Types.OutputRootProof({ + version: bytes32(uint256(0)), + stateRoot: stateRoot, + messagePasserStorageRoot: storageRoot, + latestBlockhash: bytes32(uint256(0)) + }); + + // Ensure the values returned from ffi are correct + assertEq(outputRoot, Hashing.hashOutputRootProof(proof)); + assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx)); + + // Setup the Oracle to return the outputRoot + vm.mockCall( + address(l2OutputOracle), + abi.encodeWithSelector(l2OutputOracle.getL2Output.selector), + abi.encode(outputRoot, block.timestamp, 100) + ); + + // Prove the withdrawal transaction + optimismPortal.proveWithdrawalTransaction( + _tx, + 100, // l2BlockNumber + proof, + withdrawalProof + ); + (bytes32 _root,,) = optimismPortal.provenWithdrawals(withdrawalHash); + assertTrue(_root != bytes32(0)); + + // Warp past the finalization period + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + + // Finalize the withdrawal transaction + vm.expectCallMinGas(_tx.target, _tx.value, uint64(_tx.gasLimit), _tx.data); + optimismPortal.finalizeWithdrawalTransaction(_tx); + assertTrue(optimismPortal.finalizedWithdrawals(withdrawalHash)); + } +} + +contract OptimismPortalUpgradeable_Test is CommonTest { + /// @dev Tests that the proxy is initialized correctly. + function test_params_initValuesOnProxy_succeeds() external { + (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params(); + ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); + + assertEq(prevBaseFee, rcfg.minimumBaseFee); + assertEq(prevBoughtGas, 0); + assertEq(prevBlockNum, block.number); + } + + /// @dev Tests that the proxy can be upgraded. + function test_upgradeToAndCall_upgrading_succeeds() external { + // Check an unused slot before upgrading. + bytes32 slot21Before = vm.load(address(optimismPortal), bytes32(uint256(21))); + assertEq(bytes32(0), slot21Before); + + NextImpl nextImpl = new NextImpl(); + + vm.startPrank(EIP1967Helper.getAdmin(address(optimismPortal))); + // The value passed to the initialize must be larger than the last value + // that initialize was called with. + Proxy(payable(address(optimismPortal))).upgradeToAndCall( + address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, 2) + ); + assertEq(Proxy(payable(address(optimismPortal))).implementation(), address(nextImpl)); + + // Verify that the NextImpl contract initialized its values according as expected + bytes32 slot21After = vm.load(address(optimismPortal), bytes32(uint256(21))); + bytes32 slot21Expected = NextImpl(address(optimismPortal)).slot21Init(); + assertEq(slot21Expected, slot21After); + } +} + +/// @title OptimismPortalResourceFuzz_Test +/// @dev Test various values of the resource metering config to ensure that deposits cannot be +/// broken by changing the config. +contract OptimismPortalResourceFuzz_Test is CommonTest { + /// @dev The max gas limit observed throughout this test. Setting this too high can cause + /// the test to take too long to run. + uint256 constant MAX_GAS_LIMIT = 30_000_000; + + /// @dev Test that various values of the resource metering config will not break deposits. + function testFuzz_systemConfigDeposit_succeeds( + uint32 _maxResourceLimit, + uint8 _elasticityMultiplier, + uint8 _baseFeeMaxChangeDenominator, + uint32 _minimumBaseFee, + uint32 _systemTxMaxGas, + uint128 _maximumBaseFee, + uint64 _gasLimit, + uint64 _prevBoughtGas, + uint128 _prevBaseFee, + uint8 _blockDiff + ) + external + { + // Get the set system gas limit + uint64 gasLimit = systemConfig.gasLimit(); + // Bound resource config + _maxResourceLimit = uint32(bound(_maxResourceLimit, 21000, MAX_GAS_LIMIT / 8)); + _gasLimit = uint64(bound(_gasLimit, 21000, _maxResourceLimit)); + _prevBaseFee = uint128(bound(_prevBaseFee, 0, 3 gwei)); + // Prevent values that would cause reverts + vm.assume(gasLimit >= _gasLimit); + vm.assume(_minimumBaseFee < _maximumBaseFee); + vm.assume(_baseFeeMaxChangeDenominator > 1); + vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit); + vm.assume(_elasticityMultiplier > 0); + vm.assume(((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) == _maxResourceLimit); + _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit)); + _blockDiff = uint8(bound(_blockDiff, 0, 3)); + // Pick a pseudorandom block number + vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max) + uint256(_blockDiff)); + + // Create a resource config to mock the call to the system config with + ResourceMetering.ResourceConfig memory rcfg = ResourceMetering.ResourceConfig({ + maxResourceLimit: _maxResourceLimit, + elasticityMultiplier: _elasticityMultiplier, + baseFeeMaxChangeDenominator: _baseFeeMaxChangeDenominator, + minimumBaseFee: _minimumBaseFee, + systemTxMaxGas: _systemTxMaxGas, + maximumBaseFee: _maximumBaseFee + }); + vm.mockCall( + address(systemConfig), abi.encodeWithSelector(systemConfig.resourceConfig.selector), abi.encode(rcfg) + ); + + // Set the resource params + uint256 _prevBlockNum = block.number - _blockDiff; + vm.store( + address(optimismPortal), + bytes32(uint256(1)), + bytes32((_prevBlockNum << 192) | (uint256(_prevBoughtGas) << 128) | _prevBaseFee) + ); + // Ensure that the storage setting is correct + (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params(); + assertEq(prevBaseFee, _prevBaseFee); + assertEq(prevBoughtGas, _prevBoughtGas); + assertEq(prevBlockNum, _prevBlockNum); + + // Do a deposit, should not revert + optimismPortal.depositTransaction{ gas: MAX_GAS_LIMIT }({ + _to: address(0x20), + _value: 0x40, + _gasLimit: _gasLimit, + _isCreation: false, + _data: hex"" + }); + } +} diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol new file mode 100644 index 000000000000..3c7c14625977 --- /dev/null +++ b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol @@ -0,0 +1,1193 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { stdError } from "forge-std/Test.sol"; + +import { CommonTest } from "test/setup/CommonTest.sol"; +import { NextImpl } from "test/mocks/NextImpl.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Libraries +import { Types } from "src/libraries/Types.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { Constants } from "src/libraries/Constants.sol"; + +// Target contract dependencies +import { Proxy } from "src/universal/Proxy.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; + +import { FaultDisputeGame, IDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import "src/libraries/DisputeTypes.sol"; + +contract OptimismPortal2_Test is CommonTest { + address depositor; + + function setUp() public override { + super.enableFaultProofs(); + super.setUp(); + + depositor = makeAddr("depositor"); + } + + /// @dev Tests that the constructor sets the correct values. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function test_constructor_succeeds() external virtual { + OptimismPortal2 opImpl = OptimismPortal2(payable(deploy.mustGetAddress("OptimismPortal2"))); + assertEq(address(opImpl.disputeGameFactory()), address(0)); + assertEq(address(opImpl.SYSTEM_CONFIG()), address(0)); + assertEq(address(opImpl.systemConfig()), address(0)); + assertEq(address(opImpl.superchainConfig()), address(0)); + assertEq(opImpl.l2Sender(), Constants.DEFAULT_L2_SENDER); + assertEq(opImpl.respectedGameType().raw(), deploy.cfg().respectedGameType()); + } + + /// @dev Tests that the initializer sets the correct values. + /// @notice Marked virtual to be overridden in + /// test/kontrol/deployment/DeploymentSummary.t.sol + function test_initialize_succeeds() external virtual { + address guardian = deploy.cfg().superchainConfigGuardian(); + assertEq(address(optimismPortal2.disputeGameFactory()), address(disputeGameFactory)); + assertEq(address(optimismPortal2.SYSTEM_CONFIG()), address(systemConfig)); + assertEq(address(optimismPortal2.systemConfig()), address(systemConfig)); + assertEq(optimismPortal2.GUARDIAN(), guardian); + assertEq(optimismPortal2.guardian(), guardian); + assertEq(address(optimismPortal2.superchainConfig()), address(superchainConfig)); + assertEq(optimismPortal2.l2Sender(), Constants.DEFAULT_L2_SENDER); + assertEq(optimismPortal2.paused(), false); + assertEq(optimismPortal2.respectedGameType().raw(), deploy.cfg().respectedGameType()); + } + + /// @dev Tests that `pause` successfully pauses + /// when called by the GUARDIAN. + function test_pause_succeeds() external { + address guardian = optimismPortal2.GUARDIAN(); + + assertEq(optimismPortal2.paused(), false); + + vm.expectEmit(address(superchainConfig)); + emit Paused("identifier"); + + vm.prank(guardian); + superchainConfig.pause("identifier"); + + assertEq(optimismPortal2.paused(), true); + } + + /// @dev Tests that `pause` reverts when called by a non-GUARDIAN. + function test_pause_onlyGuardian_reverts() external { + assertEq(optimismPortal2.paused(), false); + + assertTrue(optimismPortal2.GUARDIAN() != alice); + vm.expectRevert("SuperchainConfig: only guardian can pause"); + vm.prank(alice); + superchainConfig.pause("identifier"); + + assertEq(optimismPortal2.paused(), false); + } + + /// @dev Tests that `unpause` successfully unpauses + /// when called by the GUARDIAN. + function test_unpause_succeeds() external { + address guardian = optimismPortal2.GUARDIAN(); + + vm.prank(guardian); + superchainConfig.pause("identifier"); + assertEq(optimismPortal2.paused(), true); + + vm.expectEmit(address(superchainConfig)); + emit Unpaused(); + vm.prank(guardian); + superchainConfig.unpause(); + + assertEq(optimismPortal2.paused(), false); + } + + /// @dev Tests that `unpause` reverts when called by a non-GUARDIAN. + function test_unpause_onlyGuardian_reverts() external { + address guardian = optimismPortal2.GUARDIAN(); + + vm.prank(guardian); + superchainConfig.pause("identifier"); + assertEq(optimismPortal2.paused(), true); + + assertTrue(optimismPortal2.GUARDIAN() != alice); + vm.expectRevert("SuperchainConfig: only guardian can unpause"); + vm.prank(alice); + superchainConfig.unpause(); + + assertEq(optimismPortal2.paused(), true); + } + + /// @dev Tests that `receive` successdully deposits ETH. + function testFuzz_receive_succeeds(uint256 _value) external { + vm.expectEmit(address(optimismPortal2)); + emitTransactionDeposited({ + _from: alice, + _to: alice, + _value: _value, + _mint: _value, + _gasLimit: 100_000, + _isCreation: false, + _data: hex"" + }); + + // give alice money and send as an eoa + vm.deal(alice, _value); + vm.prank(alice, alice); + (bool s,) = address(optimismPortal2).call{ value: _value }(hex""); + + assertTrue(s); + assertEq(address(optimismPortal2).balance, _value); + } + + /// @dev Tests that `depositTransaction` reverts when the destination address is non-zero + /// for a contract creation deposit. + function test_depositTransaction_contractCreation_reverts() external { + // contract creation must have a target of address(0) + vm.expectRevert("OptimismPortal: must send to address(0) when creating a contract"); + optimismPortal2.depositTransaction(address(1), 1, 0, true, hex""); + } + + /// @dev Tests that `depositTransaction` reverts when the data is too large. + /// This places an upper bound on unsafe blocks sent over p2p. + function test_depositTransaction_largeData_reverts() external { + uint256 size = 120_001; + uint64 gasLimit = optimismPortal2.minimumGasLimit(uint64(size)); + vm.expectRevert("OptimismPortal: data too large"); + optimismPortal2.depositTransaction({ + _to: address(0), + _value: 0, + _gasLimit: gasLimit, + _isCreation: false, + _data: new bytes(size) + }); + } + + /// @dev Tests that `depositTransaction` reverts when the gas limit is too small. + function test_depositTransaction_smallGasLimit_reverts() external { + vm.expectRevert("OptimismPortal: gas limit too small"); + optimismPortal2.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" }); + } + + /// @dev Tests that `depositTransaction` succeeds for small, + /// but sufficient, gas limits. + function testFuzz_depositTransaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external { + uint64 gasLimit = optimismPortal2.minimumGasLimit(uint64(_data.length)); + if (_shouldFail) { + gasLimit = uint64(bound(gasLimit, 0, gasLimit - 1)); + vm.expectRevert("OptimismPortal: gas limit too small"); + } + + optimismPortal2.depositTransaction({ + _to: address(0x40), + _value: 0, + _gasLimit: gasLimit, + _isCreation: false, + _data: _data + }); + } + + /// @dev Tests that `minimumGasLimit` succeeds for small calldata sizes. + /// The gas limit should be 21k for 0 calldata and increase linearly + /// for larger calldata sizes. + function test_minimumGasLimit_succeeds() external { + assertEq(optimismPortal2.minimumGasLimit(0), 21_000); + assertTrue(optimismPortal2.minimumGasLimit(2) > optimismPortal2.minimumGasLimit(1)); + assertTrue(optimismPortal2.minimumGasLimit(3) > optimismPortal2.minimumGasLimit(2)); + } + + /// @dev Tests that `depositTransaction` succeeds for an EOA. + function testFuzz_depositTransaction_eoa_succeeds( + address _to, + uint64 _gasLimit, + uint256 _value, + uint256 _mint, + bool _isCreation, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound( + _gasLimit, + optimismPortal2.minimumGasLimit(uint64(_data.length)), + systemConfig.resourceConfig().maxResourceLimit + ) + ); + if (_isCreation) _to = address(0); + + // EOA emulation + vm.expectEmit(address(optimismPortal2)); + emitTransactionDeposited({ + _from: depositor, + _to: _to, + _value: _value, + _mint: _mint, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + + vm.deal(depositor, _mint); + vm.prank(depositor, depositor); + optimismPortal2.depositTransaction{ value: _mint }({ + _to: _to, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + assertEq(address(optimismPortal2).balance, _mint); + } + + /// @dev Tests that `depositTransaction` succeeds for a contract. + function testFuzz_depositTransaction_contract_succeeds( + address _to, + uint64 _gasLimit, + uint256 _value, + uint256 _mint, + bool _isCreation, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound( + _gasLimit, + optimismPortal2.minimumGasLimit(uint64(_data.length)), + systemConfig.resourceConfig().maxResourceLimit + ) + ); + if (_isCreation) _to = address(0); + + vm.expectEmit(address(optimismPortal2)); + emitTransactionDeposited({ + _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), + _to: _to, + _value: _value, + _mint: _mint, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + + vm.deal(address(this), _mint); + vm.prank(address(this)); + optimismPortal2.depositTransaction{ value: _mint }({ + _to: _to, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + assertEq(address(optimismPortal2).balance, _mint); + } +} + +contract OptimismPortal2_FinalizeWithdrawal_Test is CommonTest { + // Reusable default values for a test withdrawal + Types.WithdrawalTransaction _defaultTx; + + FaultDisputeGame game; + uint256 _proposedGameIndex; + uint256 _proposedBlockNumber; + bytes32 _stateRoot; + bytes32 _storageRoot; + bytes32 _outputRoot; + bytes32 _withdrawalHash; + bytes[] _withdrawalProof; + Types.OutputRootProof internal _outputRootProof; + + // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls. + constructor() { + super.enableFaultProofs(); + super.setUp(); + + _defaultTx = Types.WithdrawalTransaction({ + nonce: 0, + sender: alice, + target: bob, + value: 100, + gasLimit: 100_000, + data: hex"" + }); + // Get withdrawal proof data we can use for testing. + (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = + ffi.getProveWithdrawalTransactionInputs(_defaultTx); + + // Setup a dummy output root proof for reuse. + _outputRootProof = Types.OutputRootProof({ + version: bytes32(uint256(0)), + stateRoot: _stateRoot, + messagePasserStorageRoot: _storageRoot, + latestBlockhash: bytes32(uint256(0)) + }); + } + + /// @dev Setup the system for a ready-to-use state. + function setUp() public override { + _proposedBlockNumber = 0xFF; + game = FaultDisputeGame( + payable( + address( + disputeGameFactory.create( + optimismPortal2.respectedGameType(), Claim.wrap(_outputRoot), abi.encode(_proposedBlockNumber) + ) + ) + ) + ); + _proposedGameIndex = disputeGameFactory.gameCount() - 1; + + // Warp beyond the chess clocks and finalize the game. + vm.warp(block.timestamp + game.gameDuration().raw() / 2 + 1 seconds); + + // Fund the portal so that we can withdraw ETH. + vm.deal(address(optimismPortal2), 0xFFFFFFFF); + } + + /// @dev Asserts that the reentrant call will revert. + function callPortalAndExpectRevert() external payable { + vm.expectRevert("OptimismPortal: can only trigger one withdrawal per transaction"); + // Arguments here don't matter, as the require check is the first thing that happens. + // We assume that this has already been proven. + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + // Assert that the withdrawal was not finalized. + assertFalse(optimismPortal2.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx))); + } + + /// @dev Tests that `blacklistDisputeGame` reverts when called by a non-guardian. + function testFuzz_blacklist_onlyGuardian_reverts(address _act) external { + vm.assume(_act != address(optimismPortal2.guardian())); + + vm.expectRevert("OptimismPortal: only the guardian can blacklist dispute games"); + optimismPortal2.blacklistDisputeGame(IDisputeGame(address(0xdead))); + } + + /// @dev Tests that the guardian role can blacklist any dispute game. + function testFuzz_blacklist_guardian_succeeds(address _addr) external { + vm.prank(optimismPortal2.guardian()); + optimismPortal2.blacklistDisputeGame(IDisputeGame(_addr)); + + assertTrue(optimismPortal2.disputeGameBlacklist(IDisputeGame(_addr))); + } + + /// @dev Tests that `setRespectedGameType` reverts when called by a non-guardian. + function testFuzz_setRespectedGameType_onlyGuardian_reverts(address _act, GameType _ty) external { + vm.assume(_act != address(optimismPortal2.guardian())); + + vm.prank(_act); + vm.expectRevert("OptimismPortal: only the guardian can set the respected game type"); + optimismPortal2.setRespectedGameType(_ty); + } + + /// @dev Tests that the guardian role can set the respected game type to anything they want. + function testFuzz_setRespectedGameType_guardian_succeeds(GameType _ty) external { + vm.prank(optimismPortal2.guardian()); + optimismPortal2.setRespectedGameType(_ty); + + assertEq(optimismPortal2.respectedGameType().raw(), _ty.raw()); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts when paused. + function test_proveWithdrawalTransaction_paused_reverts() external { + vm.prank(optimismPortal2.GUARDIAN()); + superchainConfig.pause("identifier"); + + vm.expectRevert("OptimismPortal: paused"); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts when the target is the portal contract. + function test_proveWithdrawalTransaction_onSelfCall_reverts() external { + _defaultTx.target = address(optimismPortal2); + vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract"); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts when the outputRootProof does not match the output root + function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external { + // Modify the version to invalidate the withdrawal proof. + _outputRootProof.version = bytes32(uint256(1)); + vm.expectRevert("OptimismPortal: invalid output root proof"); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal is missing. + function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external { + // modify the default test values to invalidate the proof. + _defaultTx.data = hex"abcd"; + vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key"); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal has already + /// been proven. + function test_proveWithdrawalTransaction_replayProve_reverts() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + vm.expectRevert( + "OptimismPortal: withdrawal hash has already been proven, and the old dispute game is not invalid" + ); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `proveWithdrawalTransaction` reverts if the dispute game being proven against is not of the + /// respected game type. + function test_proveWithdrawalTransaction_badGameType_reverts() external { + vm.mockCall( + address(disputeGameFactory), + abi.encodeCall(disputeGameFactory.gameAtIndex, (_proposedGameIndex)), + abi.encode(GameType.wrap(0xFF), Timestamp.wrap(uint64(block.timestamp)), IDisputeGame(address(game))) + ); + + vm.expectRevert("OptimismPortal: invalid game type"); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `proveWithdrawalTransaction` can be re-executed if the dispute game proven against has been + /// blacklisted. + function test_proveWithdrawalTransaction_replayProveBlacklisted_suceeds() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Blacklist the dispute dispute game. + vm.prank(optimismPortal2.guardian()); + optimismPortal2.blacklistDisputeGame(IDisputeGame(address(game))); + + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `proveWithdrawalTransaction` can be re-executed if the dispute game proven against has resolved + /// against the favor of the root claim. + function test_proveWithdrawalTransaction_replayProveBadProposal_suceeds() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + vm.mockCall(address(game), abi.encodeCall(game.status, ()), abi.encode(GameStatus.CHALLENGER_WINS)); + + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `proveWithdrawalTransaction` can be re-executed if the dispute game proven against is no longer + /// of the respected game type. + function test_proveWithdrawalTransaction_replayRespectedGameTypeChanged_suceeds() external { + // Prove the withdrawal against a game with the current respected game type. + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Update the respected game type to 0xbeef. + vm.prank(optimismPortal2.guardian()); + optimismPortal2.setRespectedGameType(GameType.wrap(0xbeef)); + + // Create a new game and mock the game type as 0xbeef in the factory. + IDisputeGame newGame = + disputeGameFactory.create(GameType.wrap(0), Claim.wrap(_outputRoot), abi.encode(_proposedBlockNumber + 1)); + vm.mockCall( + address(disputeGameFactory), + abi.encodeCall(disputeGameFactory.gameAtIndex, (_proposedGameIndex + 1)), + abi.encode(GameType.wrap(0xbeef), Timestamp.wrap(uint64(block.timestamp)), IDisputeGame(address(newGame))) + ); + + // Re-proving should be successful against the new game. + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex + 1, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `proveWithdrawalTransaction` succeeds. + function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` succeeds. + function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external { + uint256 bobBalanceBefore = address(bob).balance; + + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Warp and resolve the dispute game. + game.resolveClaim(0); + game.resolve(); + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1 seconds); + + vm.expectEmit(true, true, false, true); + emit WithdrawalFinalized(_withdrawalHash, true); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + assert(address(bob).balance == bobBalanceBefore + 100); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the contract is paused. + function test_finalizeWithdrawalTransaction_paused_reverts() external { + vm.prank(optimismPortal2.GUARDIAN()); + superchainConfig.pause("identifier"); + + vm.expectRevert("OptimismPortal: paused"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been + function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + vm.expectRevert("OptimismPortal: withdrawal has not been proven yet"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + assert(address(bob).balance == bobBalanceBefore); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been + /// proven long enough ago. + function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + vm.expectRevert("OptimismPortal: proven withdrawal has not matured yet"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + assert(address(bob).balance == bobBalanceBefore); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the provenWithdrawal's timestamp + /// is less than the dispute game's creation timestamp. + function test_finalizeWithdrawalTransaction_timestampLessThanGameCreation_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + // Prove our withdrawal + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Warp to after the finalization period + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + + // Mock a createdAt change in the dispute game. + vm.mockCall(address(game), abi.encodeWithSignature("createdAt()"), abi.encode(block.timestamp + 1)); + + // Attempt to finalize the withdrawal + vm.expectRevert("OptimismPortal: withdrawal timestamp less than dispute game creation timestamp"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + // Ensure that bob's balance has remained the same + assertEq(bobBalanceBefore, address(bob).balance); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the dispute game has not resolved in favor of the + /// root claim. + function test_finalizeWithdrawalTransaction_ifDisputeGameNotResolved_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + // Prove our withdrawal + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Warp to after the finalization period + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + + // Attempt to finalize the withdrawal + vm.expectRevert("OptimismPortal: output proposal has not been finalized yet"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + // Ensure that bob's balance has remained the same + assertEq(bobBalanceBefore, address(bob).balance); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the target reverts. + function test_finalizeWithdrawalTransaction_targetFails_fails() external { + uint256 bobBalanceBefore = address(bob).balance; + vm.etch(bob, hex"fe"); // Contract with just the invalid opcode. + + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Resolve the dispute game. + game.resolveClaim(0); + game.resolve(); + + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + vm.expectEmit(true, true, true, true); + emit WithdrawalFinalized(_withdrawalHash, false); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + assert(address(bob).balance == bobBalanceBefore); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has already been + /// finalized. + function test_finalizeWithdrawalTransaction_onReplay_reverts() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Resolve the dispute game. + game.resolveClaim(0); + game.resolve(); + + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + vm.expectEmit(true, true, true, true); + emit WithdrawalFinalized(_withdrawalHash, true); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + vm.expectRevert("OptimismPortal: withdrawal has already been finalized"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal transaction + /// does not have enough gas to execute. + function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external { + // This number was identified through trial and error. + uint256 gasLimit = 150_000; + Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({ + nonce: 0, + sender: alice, + target: bob, + value: 100, + gasLimit: gasLimit, + data: hex"" + }); + + // Get updated proof inputs. + (bytes32 stateRoot, bytes32 storageRoot,,, bytes[] memory withdrawalProof) = + ffi.getProveWithdrawalTransactionInputs(insufficientGasTx); + Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({ + version: bytes32(0), + stateRoot: stateRoot, + messagePasserStorageRoot: storageRoot, + latestBlockhash: bytes32(0) + }); + + vm.mockCall( + address(game), abi.encodeCall(game.rootClaim, ()), abi.encode(Hashing.hashOutputRootProof(outputRootProof)) + ); + + optimismPortal2.proveWithdrawalTransaction({ + _tx: insufficientGasTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: outputRootProof, + _withdrawalProof: withdrawalProof + }); + + // Resolve the dispute game. + game.resolveClaim(0); + game.resolve(); + + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + vm.expectRevert("SafeCall: Not enough gas"); + optimismPortal2.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if a sub-call attempts to finalize + /// another withdrawal. + function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external { + uint256 bobBalanceBefore = address(bob).balance; + + // Copy and modify the default test values to attempt a reentrant call by first calling to + // this contract's callPortalAndExpectRevert() function above. + Types.WithdrawalTransaction memory _testTx = _defaultTx; + _testTx.target = address(this); + _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector); + + // Get modified proof inputs. + ( + bytes32 stateRoot, + bytes32 storageRoot, + bytes32 outputRoot, + bytes32 withdrawalHash, + bytes[] memory withdrawalProof + ) = ffi.getProveWithdrawalTransactionInputs(_testTx); + Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({ + version: bytes32(0), + stateRoot: stateRoot, + messagePasserStorageRoot: storageRoot, + latestBlockhash: bytes32(0) + }); + + // Return a mock output root from the game. + vm.mockCall(address(game), abi.encodeCall(game.rootClaim, ()), abi.encode(outputRoot)); + + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(withdrawalHash, alice, address(this)); + optimismPortal2.proveWithdrawalTransaction(_testTx, _proposedGameIndex, outputRootProof, withdrawalProof); + + // Resolve the dispute game. + game.resolveClaim(0); + game.resolve(); + + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + vm.expectCall(address(this), _testTx.data); + vm.expectEmit(true, true, true, true); + emit WithdrawalFinalized(withdrawalHash, true); + optimismPortal2.finalizeWithdrawalTransaction(_testTx); + + // Ensure that bob's balance was not changed by the reentrant call. + assert(address(bob).balance == bobBalanceBefore); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` succeeds. + function testDiff_finalizeWithdrawalTransaction_succeeds( + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) + external + { + vm.assume( + _target != address(optimismPortal2) // Cannot call the optimism portal or a contract + && _target.code.length == 0 // No accounts with code + && _target != CONSOLE // The console has no code but behaves like a contract + && uint160(_target) > 9 // No precompiles (or zero address) + ); + + // Total ETH supply is currently about 120M ETH. + uint256 value = bound(_value, 0, 200_000_000 ether); + vm.deal(address(optimismPortal2), value); + + uint256 gasLimit = bound(_gasLimit, 0, 50_000_000); + uint256 nonce = l2ToL1MessagePasser.messageNonce(); + + // Get a withdrawal transaction and mock proof from the differential testing script. + Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({ + nonce: nonce, + sender: _sender, + target: _target, + value: value, + gasLimit: gasLimit, + data: _data + }); + ( + bytes32 stateRoot, + bytes32 storageRoot, + bytes32 outputRoot, + bytes32 withdrawalHash, + bytes[] memory withdrawalProof + ) = ffi.getProveWithdrawalTransactionInputs(_tx); + + // Create the output root proof + Types.OutputRootProof memory proof = Types.OutputRootProof({ + version: bytes32(uint256(0)), + stateRoot: stateRoot, + messagePasserStorageRoot: storageRoot, + latestBlockhash: bytes32(uint256(0)) + }); + + // Ensure the values returned from ffi are correct + assertEq(outputRoot, Hashing.hashOutputRootProof(proof)); + assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx)); + + // Setup the dispute game to return the output root + vm.mockCall(address(game), abi.encodeCall(game.rootClaim, ()), abi.encode(outputRoot)); + + // Prove the withdrawal transaction + optimismPortal2.proveWithdrawalTransaction(_tx, _proposedGameIndex, proof, withdrawalProof); + (IDisputeGame _game,) = optimismPortal2.provenWithdrawals(withdrawalHash); + assertTrue(_game.rootClaim().raw() != bytes32(0)); + + // Resolve the dispute game + game.resolveClaim(0); + game.resolve(); + + // Warp past the finalization period + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + + // Finalize the withdrawal transaction + vm.expectCallMinGas(_tx.target, _tx.value, uint64(_tx.gasLimit), _tx.data); + optimismPortal2.finalizeWithdrawalTransaction(_tx); + assertTrue(optimismPortal2.finalizedWithdrawals(withdrawalHash)); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal's dispute game has been blacklisted. + function test_finalizeWithdrawalTransaction_blacklisted_reverts() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Resolve the dispute game. + game.resolveClaim(0); + game.resolve(); + + vm.prank(optimismPortal2.guardian()); + optimismPortal2.blacklistDisputeGame(IDisputeGame(address(game))); + + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + + vm.expectRevert("OptimismPortal: dispute game has been blacklisted"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal's dispute game is still in the air + /// gap. + function test_finalizeWithdrawalTransaction_gameInAirGap_reverts() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Warp past the finalization period. + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + + // Resolve the dispute game. + game.resolveClaim(0); + game.resolve(); + + // Attempt to finalize the withdrawal directly after the game resolves. This should fail. + vm.expectRevert("OptimismPortal: output proposal in air-gap"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + // Finalize the withdrawal transaction. This should succeed. + vm.warp(block.timestamp + optimismPortal2.disputeGameFinalityDelaySeconds() + 1); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + assertTrue(optimismPortal2.finalizedWithdrawals(_withdrawalHash)); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the respected game type has changed since the + /// withdrawal was proven. + function test_finalizeWithdrawalTransaction_respectedTypeChangedSinceProving_reverts() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Warp past the finalization period. + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + + // Resolve the dispute game. + game.resolveClaim(0); + game.resolve(); + + // Change the respected game type in the portal. + vm.prank(optimismPortal2.guardian()); + optimismPortal2.setRespectedGameType(GameType.wrap(0xFF)); + + vm.expectRevert("OptimismPortal: invalid game type"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + } + + /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the respected game type was updated after the + /// dispute game was created. + function test_finalizeWithdrawalTransaction_gameOlderThanRespectedGameTypeUpdate_reverts() external { + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Warp past the finalization period. + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + + // Resolve the dispute game. + game.resolveClaim(0); + game.resolve(); + + // Change the respected game type in the portal. + vm.prank(optimismPortal2.guardian()); + optimismPortal2.setRespectedGameType(GameType.wrap(0xFF)); + + // Mock the game's type so that we pass the correct game type check. + vm.mockCall(address(game), abi.encodeCall(game.gameType, ()), abi.encode(GameType.wrap(0xFF))); + + vm.expectRevert("OptimismPortal: dispute game created before respected game type was updated"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + } + + /// @dev Tests an e2e prove -> finalize path, checking the edges of each delay for correctness. + function test_finalizeWithdrawalTransaction_delayEdges_succeeds() external { + // Prove the withdrawal transaction. + vm.expectEmit(true, true, true, true); + emit WithdrawalProven(_withdrawalHash, alice, bob); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + + // Attempt to finalize the withdrawal transaction 1 second before the proof has matured. This should fail. + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds()); + vm.expectRevert("OptimismPortal: proven withdrawal has not matured yet"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + // Warp 1 second in the future, past the proof maturity delay, and attempt to finalize the withdrawal. + // This should also fail, since the dispute game has not resolved yet. + vm.warp(block.timestamp + 1 seconds); + vm.expectRevert("OptimismPortal: output proposal has not been finalized yet"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + // Finalize the dispute game and attempt to finalize the withdrawal again. This should also fail, since the + // air gap dispute game delay has not elapsed. + game.resolveClaim(0); + game.resolve(); + vm.warp(block.timestamp + optimismPortal2.disputeGameFinalityDelaySeconds()); + vm.expectRevert("OptimismPortal: output proposal in air-gap"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + // Warp 1 second in the future, past the air gap dispute game delay, and attempt to finalize the withdrawal. + // This should succeed. + vm.warp(block.timestamp + 1 seconds); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + assertTrue(optimismPortal2.finalizedWithdrawals(_withdrawalHash)); + } +} + +contract OptimismPortal2_Upgradeable_Test is CommonTest { + function setUp() public override { + super.enableFaultProofs(); + super.setUp(); + } + + /// @dev Tests that the proxy is initialized correctly. + function test_params_initValuesOnProxy_succeeds() external { + (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal2.params(); + ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); + + assertEq(prevBaseFee, rcfg.minimumBaseFee); + assertEq(prevBoughtGas, 0); + assertEq(prevBlockNum, block.number); + } + + /// @dev Tests that the proxy can be upgraded. + function test_upgradeToAndCall_upgrading_succeeds() external { + // Check an unused slot before upgrading. + bytes32 slot21Before = vm.load(address(optimismPortal2), bytes32(uint256(21))); + assertEq(bytes32(0), slot21Before); + + NextImpl nextImpl = new NextImpl(); + + vm.startPrank(EIP1967Helper.getAdmin(address(optimismPortal2))); + // The value passed to the initialize must be larger than the last value + // that initialize was called with. + Proxy(payable(address(optimismPortal2))).upgradeToAndCall( + address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, 2) + ); + assertEq(Proxy(payable(address(optimismPortal2))).implementation(), address(nextImpl)); + + // Verify that the NextImpl contract initialized its values according as expected + bytes32 slot21After = vm.load(address(optimismPortal2), bytes32(uint256(21))); + bytes32 slot21Expected = NextImpl(address(optimismPortal2)).slot21Init(); + assertEq(slot21Expected, slot21After); + } +} + +/// @title OptimismPortal2_ResourceFuzz_Test +/// @dev Test various values of the resource metering config to ensure that deposits cannot be +/// broken by changing the config. +contract OptimismPortal2_ResourceFuzz_Test is CommonTest { + /// @dev The max gas limit observed throughout this test. Setting this too high can cause + /// the test to take too long to run. + uint256 constant MAX_GAS_LIMIT = 30_000_000; + + function setUp() public override { + super.enableFaultProofs(); + super.setUp(); + } + + /// @dev Test that various values of the resource metering config will not break deposits. + function testFuzz_systemConfigDeposit_succeeds( + uint32 _maxResourceLimit, + uint8 _elasticityMultiplier, + uint8 _baseFeeMaxChangeDenominator, + uint32 _minimumBaseFee, + uint32 _systemTxMaxGas, + uint128 _maximumBaseFee, + uint64 _gasLimit, + uint64 _prevBoughtGas, + uint128 _prevBaseFee, + uint8 _blockDiff + ) + external + { + // Get the set system gas limit + uint64 gasLimit = systemConfig.gasLimit(); + // Bound resource config + _maxResourceLimit = uint32(bound(_maxResourceLimit, 21000, MAX_GAS_LIMIT / 8)); + _gasLimit = uint64(bound(_gasLimit, 21000, _maxResourceLimit)); + _prevBaseFee = uint128(bound(_prevBaseFee, 0, 3 gwei)); + // Prevent values that would cause reverts + vm.assume(gasLimit >= _gasLimit); + vm.assume(_minimumBaseFee < _maximumBaseFee); + vm.assume(_baseFeeMaxChangeDenominator > 1); + vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit); + vm.assume(_elasticityMultiplier > 0); + vm.assume(((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) == _maxResourceLimit); + _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit)); + _blockDiff = uint8(bound(_blockDiff, 0, 3)); + // Pick a pseudorandom block number + vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max) + uint256(_blockDiff)); + + // Create a resource config to mock the call to the system config with + ResourceMetering.ResourceConfig memory rcfg = ResourceMetering.ResourceConfig({ + maxResourceLimit: _maxResourceLimit, + elasticityMultiplier: _elasticityMultiplier, + baseFeeMaxChangeDenominator: _baseFeeMaxChangeDenominator, + minimumBaseFee: _minimumBaseFee, + systemTxMaxGas: _systemTxMaxGas, + maximumBaseFee: _maximumBaseFee + }); + vm.mockCall( + address(systemConfig), abi.encodeWithSelector(systemConfig.resourceConfig.selector), abi.encode(rcfg) + ); + + // Set the resource params + uint256 _prevBlockNum = block.number - _blockDiff; + vm.store( + address(optimismPortal2), + bytes32(uint256(1)), + bytes32((_prevBlockNum << 192) | (uint256(_prevBoughtGas) << 128) | _prevBaseFee) + ); + // Ensure that the storage setting is correct + (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal2.params(); + assertEq(prevBaseFee, _prevBaseFee); + assertEq(prevBoughtGas, _prevBoughtGas); + assertEq(prevBlockNum, _prevBlockNum); + + // Do a deposit, should not revert + optimismPortal2.depositTransaction{ gas: MAX_GAS_LIMIT }({ + _to: address(0x20), + _value: 0x40, + _gasLimit: _gasLimit, + _isCreation: false, + _data: hex"" + }); + } +} diff --git a/packages/contracts-bedrock/test/ProtocolVersions.t.sol b/packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol similarity index 81% rename from packages/contracts-bedrock/test/ProtocolVersions.t.sol rename to packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol index 814c36ec9639..4a05fee431b3 100644 --- a/packages/contracts-bedrock/test/ProtocolVersions.t.sol +++ b/packages/contracts-bedrock/test/L1/ProtocolVersions.t.sol @@ -2,7 +2,8 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; @@ -14,44 +15,27 @@ import { Proxy } from "src/universal/Proxy.sol"; import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; contract ProtocolVersions_Init is CommonTest { - ProtocolVersions protocolVersions; - ProtocolVersions protocolVersionsImpl; - event ConfigUpdate(uint256 indexed version, ProtocolVersions.UpdateType indexed updateType, bytes data); - // Dummy values used to test getters - ProtocolVersion constant required = ProtocolVersion.wrap(0xabcd); - ProtocolVersion constant recommended = ProtocolVersion.wrap(0x1234); + ProtocolVersion required; + ProtocolVersion recommended; function setUp() public virtual override { super.setUp(); - - Proxy proxy = new Proxy(multisig); - protocolVersionsImpl = new ProtocolVersions(); - - vm.prank(multisig); - proxy.upgradeToAndCall( - address(protocolVersionsImpl), - abi.encodeCall( - ProtocolVersions.initialize, - ( - alice, // _owner, - required, - recommended - ) - ) - ); - - protocolVersions = ProtocolVersions(address(proxy)); + required = ProtocolVersion.wrap(deploy.cfg().requiredProtocolVersion()); + recommended = ProtocolVersion.wrap(deploy.cfg().recommendedProtocolVersion()); } } contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { /// @dev Tests that initialization sets the correct values. function test_initialize_values_succeeds() external { + ProtocolVersions protocolVersionsImpl = ProtocolVersions(deploy.mustGetAddress("ProtocolVersions")); + address owner = deploy.cfg().finalSystemOwner(); + assertEq(ProtocolVersion.unwrap(protocolVersions.required()), ProtocolVersion.unwrap(required)); assertEq(ProtocolVersion.unwrap(protocolVersions.recommended()), ProtocolVersion.unwrap(recommended)); - assertEq(protocolVersions.owner(), alice); + assertEq(protocolVersions.owner(), owner); assertEq(ProtocolVersion.unwrap(protocolVersionsImpl.required()), 0); assertEq(ProtocolVersion.unwrap(protocolVersionsImpl.recommended()), 0); @@ -60,6 +44,7 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { /// @dev Ensures that the events are emitted during initialization. function test_initialize_events_succeeds() external { + ProtocolVersions protocolVersionsImpl = ProtocolVersions(deploy.mustGetAddress("ProtocolVersions")); assertEq(protocolVersionsImpl.owner(), address(0xdEad)); // Wipe out the initialized slot so the proxy can be initialized again @@ -71,7 +56,7 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { vm.expectEmit(true, true, true, true, address(protocolVersions)); emit ConfigUpdate(0, ProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(recommended)); - vm.prank(multisig); + vm.prank(EIP1967Helper.getAdmin(address(protocolVersions))); Proxy(payable(address(protocolVersions))).upgradeToAndCall( address(protocolVersionsImpl), abi.encodeCall( diff --git a/packages/contracts-bedrock/test/ResourceMetering.t.sol b/packages/contracts-bedrock/test/L1/ResourceMetering.t.sol similarity index 96% rename from packages/contracts-bedrock/test/ResourceMetering.t.sol rename to packages/contracts-bedrock/test/L1/ResourceMetering.t.sol index 01fcab1c9264..99633fe67ec7 100644 --- a/packages/contracts-bedrock/test/ResourceMetering.t.sol +++ b/packages/contracts-bedrock/test/L1/ResourceMetering.t.sol @@ -71,6 +71,20 @@ contract ResourceMetering_Test is Test { assertEq(prevBlockNum, initialBlockNum); } + /// @dev Tests that reinitializing the resource params are set correctly. + function test_meter_reinitializedResourceParams_succeeds() external { + (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = meter.params(); + + // Reset the initialized slot to enable reinitialization. + vm.store(address(meter), bytes32(uint256(0)), bytes32(uint256(0))); + meter.initialize(); + + (uint128 postBaseFee, uint64 postBoughtGas, uint64 postBlockNum) = meter.params(); + assertEq(prevBaseFee, postBaseFee); + assertEq(prevBoughtGas, postBoughtGas); + assertEq(prevBlockNum, postBlockNum); + } + /// @dev Tests that updating the resource params to the same values works correctly. function test_meter_updateParamsNoChange_succeeds() external { meter.use(0); // equivalent to just updating the base fee and block number diff --git a/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol b/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol new file mode 100644 index 000000000000..d1f58eed71c7 --- /dev/null +++ b/packages/contracts-bedrock/test/L1/SuperchainConfig.t.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { CommonTest } from "test/setup/CommonTest.sol"; + +// Libraries +import { Types } from "src/libraries/Types.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; + +// Target contract dependencies +import { Proxy } from "src/universal/Proxy.sol"; + +// Target contract +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; + +contract SuperchainConfig_Init_Test is CommonTest { + /// @dev Tests that initialization sets the correct values. These are defined in CommonTest.sol. + function test_initialize_unpaused_succeeds() external { + assertFalse(superchainConfig.paused()); + assertEq(superchainConfig.guardian(), deploy.cfg().superchainConfigGuardian()); + } + + /// @dev Tests that it can be intialized as paused. + function test_initialize_paused_succeeds() external { + Proxy newProxy = new Proxy(alice); + SuperchainConfig newImpl = new SuperchainConfig(); + + vm.startPrank(alice); + newProxy.upgradeToAndCall( + address(newImpl), + abi.encodeWithSelector(SuperchainConfig.initialize.selector, deploy.cfg().superchainConfigGuardian(), true) + ); + + assertTrue(SuperchainConfig(address(newProxy)).paused()); + assertEq(SuperchainConfig(address(newProxy)).guardian(), deploy.cfg().superchainConfigGuardian()); + } +} + +contract SuperchainConfig_Pause_TestFail is CommonTest { + /// @dev Tests that `pause` reverts when called by a non-guardian. + function test_pause_notGuardian_reverts() external { + assertFalse(superchainConfig.paused()); + + assertTrue(superchainConfig.guardian() != alice); + vm.expectRevert("SuperchainConfig: only guardian can pause"); + vm.prank(alice); + superchainConfig.pause("identifier"); + + assertFalse(superchainConfig.paused()); + } +} + +contract SuperchainConfig_Pause_Test is CommonTest { + /// @dev Tests that `pause` successfully pauses + /// when called by the guardian. + function test_pause_succeeds() external { + assertFalse(superchainConfig.paused()); + + vm.expectEmit(address(superchainConfig)); + emit Paused("identifier"); + + vm.prank(superchainConfig.guardian()); + superchainConfig.pause("identifier"); + + assertTrue(superchainConfig.paused()); + } +} + +contract SuperchainConfig_Unpause_TestFail is CommonTest { + /// @dev Tests that `unpause` reverts when called by a non-guardian. + function test_unpause_notGuardian_reverts() external { + vm.prank(superchainConfig.guardian()); + superchainConfig.pause("identifier"); + assertEq(superchainConfig.paused(), true); + + assertTrue(superchainConfig.guardian() != alice); + vm.expectRevert("SuperchainConfig: only guardian can unpause"); + vm.prank(alice); + superchainConfig.unpause(); + + assertTrue(superchainConfig.paused()); + } +} + +contract SuperchainConfig_Unpause_Test is CommonTest { + /// @dev Tests that `unpause` successfully unpauses + /// when called by the guardian. + function test_unpause_succeeds() external { + vm.startPrank(superchainConfig.guardian()); + superchainConfig.pause("identifier"); + assertEq(superchainConfig.paused(), true); + + vm.expectEmit(address(superchainConfig)); + emit Unpaused(); + superchainConfig.unpause(); + + assertFalse(superchainConfig.paused()); + } +} diff --git a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol new file mode 100644 index 000000000000..c8b89b5045c3 --- /dev/null +++ b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol @@ -0,0 +1,339 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; + +// Libraries +import { Constants } from "src/libraries/Constants.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Target contract dependencies +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { Proxy } from "src/universal/Proxy.sol"; + +// Target contract +import { SystemConfig } from "src/L1/SystemConfig.sol"; + +contract SystemConfig_Init is CommonTest { + event ConfigUpdate(uint256 indexed version, SystemConfig.UpdateType indexed updateType, bytes data); +} + +contract SystemConfig_Initialize_Test is SystemConfig_Init { + address batchInbox; + address owner; + uint256 overhead; + uint256 scalar; + bytes32 batcherHash; + uint64 gasLimit; + address unsafeBlockSigner; + address systemConfigImpl; + address optimismMintableERC20Factory; + + function setUp() public virtual override { + super.setUp(); + batchInbox = deploy.cfg().batchInboxAddress(); + owner = deploy.cfg().finalSystemOwner(); + overhead = deploy.cfg().gasPriceOracleOverhead(); + scalar = deploy.cfg().gasPriceOracleScalar(); + batcherHash = bytes32(uint256(uint160(deploy.cfg().batchSenderAddress()))); + gasLimit = uint64(deploy.cfg().l2GenesisBlockGasLimit()); + unsafeBlockSigner = deploy.cfg().p2pSequencerAddress(); + systemConfigImpl = deploy.mustGetAddress("SystemConfig"); + optimismMintableERC20Factory = deploy.mustGetAddress("OptimismMintableERC20FactoryProxy"); + } + + /// @dev Tests that constructor sets the correct values. + function test_constructor_succeeds() external { + SystemConfig impl = SystemConfig(systemConfigImpl); + assertEq(impl.owner(), address(0xdEaD)); + assertEq(impl.overhead(), 0); + assertEq(impl.scalar(), 0); + assertEq(impl.batcherHash(), bytes32(0)); + assertEq(impl.gasLimit(), 1); + assertEq(impl.unsafeBlockSigner(), address(0)); + ResourceMetering.ResourceConfig memory actual = impl.resourceConfig(); + assertEq(actual.maxResourceLimit, 1); + assertEq(actual.elasticityMultiplier, 1); + assertEq(actual.baseFeeMaxChangeDenominator, 2); + assertEq(actual.minimumBaseFee, 0); + assertEq(actual.systemTxMaxGas, 0); + assertEq(actual.maximumBaseFee, 0); + assertEq(impl.startBlock(), type(uint256).max); + assertEq(address(impl.batchInbox()), address(0)); + // Check addresses + assertEq(address(impl.l1CrossDomainMessenger()), address(0)); + assertEq(address(impl.l1ERC721Bridge()), address(0)); + assertEq(address(impl.l1StandardBridge()), address(0)); + assertEq(address(impl.l2OutputOracle()), address(0)); + assertEq(address(impl.optimismPortal()), address(0)); + assertEq(address(impl.optimismMintableERC20Factory()), address(0)); + } + + /// @dev Tests that initailization sets the correct values. + function test_initialize_succeeds() external { + assertEq(systemConfig.owner(), owner); + assertEq(systemConfig.overhead(), overhead); + assertEq(systemConfig.scalar(), scalar); + assertEq(systemConfig.batcherHash(), batcherHash); + assertEq(systemConfig.gasLimit(), gasLimit); + assertEq(systemConfig.unsafeBlockSigner(), unsafeBlockSigner); + // Depends on `initialize` being called with defaults + ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); + ResourceMetering.ResourceConfig memory actual = systemConfig.resourceConfig(); + assertEq(actual.maxResourceLimit, rcfg.maxResourceLimit); + assertEq(actual.elasticityMultiplier, rcfg.elasticityMultiplier); + assertEq(actual.baseFeeMaxChangeDenominator, rcfg.baseFeeMaxChangeDenominator); + assertEq(actual.minimumBaseFee, rcfg.minimumBaseFee); + assertEq(actual.systemTxMaxGas, rcfg.systemTxMaxGas); + assertEq(actual.maximumBaseFee, rcfg.maximumBaseFee); + // Depends on start block being set to 0 in `initialize` + uint256 cfgStartBlock = deploy.cfg().systemConfigStartBlock(); + assertEq(systemConfig.startBlock(), (cfgStartBlock == 0 ? block.number : cfgStartBlock)); + assertEq(address(systemConfig.batchInbox()), address(batchInbox)); + // Check addresses + assertEq(address(systemConfig.l1CrossDomainMessenger()), address(l1CrossDomainMessenger)); + assertEq(address(systemConfig.l1ERC721Bridge()), address(l1ERC721Bridge)); + assertEq(address(systemConfig.l1StandardBridge()), address(l1StandardBridge)); + assertEq(address(systemConfig.l2OutputOracle()), address(l2OutputOracle)); + assertEq(address(systemConfig.optimismPortal()), address(optimismPortal)); + assertEq(address(systemConfig.optimismMintableERC20Factory()), address(optimismMintableERC20Factory)); + } +} + +contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { + /// @dev Tests that initialization reverts if the gas limit is too low. + function test_initialize_lowGasLimit_reverts() external { + uint64 minimumGasLimit = systemConfig.minimumGasLimit(); + + // Wipe out the initialized slot so the proxy can be initialized again + vm.store(address(systemConfig), bytes32(0), bytes32(0)); + + address admin = address(uint160(uint256(vm.load(address(systemConfig), Constants.PROXY_OWNER_ADDRESS)))); + vm.prank(admin); + + vm.expectRevert("SystemConfig: gas limit too low"); + systemConfig.initialize({ + _owner: alice, + _overhead: 2100, + _scalar: 1000000, + _batcherHash: bytes32(hex"abcd"), + _gasLimit: minimumGasLimit - 1, + _unsafeBlockSigner: address(1), + _config: Constants.DEFAULT_RESOURCE_CONFIG(), + _batchInbox: address(0), + _addresses: SystemConfig.Addresses({ + l1CrossDomainMessenger: address(0), + l1ERC721Bridge: address(0), + l1StandardBridge: address(0), + l2OutputOracle: address(0), + optimismPortal: address(0), + optimismMintableERC20Factory: address(0) + }) + }); + } + + /// @dev Tests that startBlock is updated correctly when it's zero. + function test_startBlock_update_succeeds() external { + // Wipe out the initialized slot so the proxy can be initialized again + vm.store(address(systemConfig), bytes32(0), bytes32(0)); + // Set slot startBlock to zero + vm.store(address(systemConfig), systemConfig.START_BLOCK_SLOT(), bytes32(uint256(0))); + + // Initialize and check that StartBlock updates to current block number + vm.prank(systemConfig.owner()); + systemConfig.initialize({ + _owner: alice, + _overhead: 2100, + _scalar: 1000000, + _batcherHash: bytes32(hex"abcd"), + _gasLimit: gasLimit, + _unsafeBlockSigner: address(1), + _config: Constants.DEFAULT_RESOURCE_CONFIG(), + _batchInbox: address(0), + _addresses: SystemConfig.Addresses({ + l1CrossDomainMessenger: address(0), + l1ERC721Bridge: address(0), + l1StandardBridge: address(0), + l2OutputOracle: address(0), + optimismPortal: address(0), + optimismMintableERC20Factory: address(0) + }) + }); + assertEq(systemConfig.startBlock(), block.number); + } + + /// @dev Tests that startBlock is not updated when it's not zero. + function test_startBlock_update_fails() external { + // Wipe out the initialized slot so the proxy can be initialized again + vm.store(address(systemConfig), bytes32(0), bytes32(0)); + // Set slot startBlock to non-zero value 1 + vm.store(address(systemConfig), systemConfig.START_BLOCK_SLOT(), bytes32(uint256(1))); + + // Initialize and check that StartBlock doesn't update + vm.prank(systemConfig.owner()); + systemConfig.initialize({ + _owner: alice, + _overhead: 2100, + _scalar: 1000000, + _batcherHash: bytes32(hex"abcd"), + _gasLimit: gasLimit, + _unsafeBlockSigner: address(1), + _config: Constants.DEFAULT_RESOURCE_CONFIG(), + _batchInbox: address(0), + _addresses: SystemConfig.Addresses({ + l1CrossDomainMessenger: address(0), + l1ERC721Bridge: address(0), + l1StandardBridge: address(0), + l2OutputOracle: address(0), + optimismPortal: address(0), + optimismMintableERC20Factory: address(0) + }) + }); + assertEq(systemConfig.startBlock(), 1); + } +} + +contract SystemConfig_Setters_TestFail is SystemConfig_Init { + /// @dev Tests that `setBatcherHash` reverts if the caller is not the owner. + function test_setBatcherHash_notOwner_reverts() external { + vm.expectRevert("Ownable: caller is not the owner"); + systemConfig.setBatcherHash(bytes32(hex"")); + } + + /// @dev Tests that `setGasConfig` reverts if the caller is not the owner. + function test_setGasConfig_notOwner_reverts() external { + vm.expectRevert("Ownable: caller is not the owner"); + systemConfig.setGasConfig(0, 0); + } + + /// @dev Tests that `setGasLimit` reverts if the caller is not the owner. + function test_setGasLimit_notOwner_reverts() external { + vm.expectRevert("Ownable: caller is not the owner"); + systemConfig.setGasLimit(0); + } + + /// @dev Tests that `setUnsafeBlockSigner` reverts if the caller is not the owner. + function test_setUnsafeBlockSigner_notOwner_reverts() external { + vm.expectRevert("Ownable: caller is not the owner"); + systemConfig.setUnsafeBlockSigner(address(0x20)); + } + + /// @dev Tests that `setResourceConfig` reverts if the caller is not the owner. + function test_setResourceConfig_notOwner_reverts() external { + ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG(); + vm.expectRevert("Ownable: caller is not the owner"); + systemConfig.setResourceConfig(config); + } + + /// @dev Tests that `setResourceConfig` reverts if the min base fee + /// is greater than the maximum allowed base fee. + function test_setResourceConfig_badMinMax_reverts() external { + ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ + maxResourceLimit: 20_000_000, + elasticityMultiplier: 10, + baseFeeMaxChangeDenominator: 8, + systemTxMaxGas: 1_000_000, + minimumBaseFee: 2 gwei, + maximumBaseFee: 1 gwei + }); + vm.prank(systemConfig.owner()); + vm.expectRevert("SystemConfig: min base fee must be less than max base"); + systemConfig.setResourceConfig(config); + } + + /// @dev Tests that `setResourceConfig` reverts if the baseFeeMaxChangeDenominator + /// is zero. + function test_setResourceConfig_zeroDenominator_reverts() external { + ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ + maxResourceLimit: 20_000_000, + elasticityMultiplier: 10, + baseFeeMaxChangeDenominator: 0, + systemTxMaxGas: 1_000_000, + minimumBaseFee: 1 gwei, + maximumBaseFee: 2 gwei + }); + vm.prank(systemConfig.owner()); + vm.expectRevert("SystemConfig: denominator must be larger than 1"); + systemConfig.setResourceConfig(config); + } + + /// @dev Tests that `setResourceConfig` reverts if the gas limit is too low. + function test_setResourceConfig_lowGasLimit_reverts() external { + uint64 gasLimit = systemConfig.gasLimit(); + + ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ + maxResourceLimit: uint32(gasLimit), + elasticityMultiplier: 10, + baseFeeMaxChangeDenominator: 8, + systemTxMaxGas: uint32(gasLimit), + minimumBaseFee: 1 gwei, + maximumBaseFee: 2 gwei + }); + vm.prank(systemConfig.owner()); + vm.expectRevert("SystemConfig: gas limit too low"); + systemConfig.setResourceConfig(config); + } + + /// @dev Tests that `setResourceConfig` reverts if the elasticity multiplier + /// and max resource limit are configured such that there is a loss of precision. + function test_setResourceConfig_badPrecision_reverts() external { + ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ + maxResourceLimit: 20_000_000, + elasticityMultiplier: 11, + baseFeeMaxChangeDenominator: 8, + systemTxMaxGas: 1_000_000, + minimumBaseFee: 1 gwei, + maximumBaseFee: 2 gwei + }); + vm.prank(systemConfig.owner()); + vm.expectRevert("SystemConfig: precision loss with target resource limit"); + systemConfig.setResourceConfig(config); + } +} + +contract SystemConfig_Setters_Test is SystemConfig_Init { + /// @dev Tests that `setBatcherHash` updates the batcher hash successfully. + function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external { + vm.expectEmit(true, true, true, true); + emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash)); + + vm.prank(systemConfig.owner()); + systemConfig.setBatcherHash(newBatcherHash); + assertEq(systemConfig.batcherHash(), newBatcherHash); + } + + /// @dev Tests that `setGasConfig` updates the overhead and scalar successfully. + function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external { + vm.expectEmit(true, true, true, true); + emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(newOverhead, newScalar)); + + vm.prank(systemConfig.owner()); + systemConfig.setGasConfig(newOverhead, newScalar); + assertEq(systemConfig.overhead(), newOverhead); + assertEq(systemConfig.scalar(), newScalar); + } + + /// @dev Tests that `setGasLimit` updates the gas limit successfully. + function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external { + uint64 minimumGasLimit = systemConfig.minimumGasLimit(); + newGasLimit = uint64(bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))); + + vm.expectEmit(true, true, true, true); + emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit)); + + vm.prank(systemConfig.owner()); + systemConfig.setGasLimit(newGasLimit); + assertEq(systemConfig.gasLimit(), newGasLimit); + } + + /// @dev Tests that `setUnsafeBlockSigner` updates the block signer successfully. + function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external { + vm.expectEmit(true, true, true, true); + emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(newUnsafeSigner)); + + vm.prank(systemConfig.owner()); + systemConfig.setUnsafeBlockSigner(newUnsafeSigner); + assertEq(systemConfig.unsafeBlockSigner(), newUnsafeSigner); + } +} diff --git a/packages/contracts-bedrock/test/L1Block.t.sol b/packages/contracts-bedrock/test/L1Block.t.sol deleted file mode 100644 index f44f606a6270..000000000000 --- a/packages/contracts-bedrock/test/L1Block.t.sol +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; - -// Target contract -import { L1Block } from "src/L2/L1Block.sol"; - -contract L1BlockTest is CommonTest { - L1Block lb; - address depositor; - bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1)); - - /// @dev Sets up the test suite. - function setUp() public virtual override { - super.setUp(); - lb = new L1Block(); - depositor = lb.DEPOSITOR_ACCOUNT(); - vm.prank(depositor); - lb.setL1BlockValues({ - _number: uint64(1), - _timestamp: uint64(2), - _basefee: 3, - _hash: NON_ZERO_HASH, - _sequenceNumber: uint64(4), - _batcherHash: bytes32(0), - _l1FeeOverhead: 2, - _l1FeeScalar: 3 - }); - } - - /// @dev Tests that `setL1BlockValues` updates the values correctly. - function testFuzz_updatesValues_succeeds( - uint64 n, - uint64 t, - uint256 b, - bytes32 h, - uint64 s, - bytes32 bt, - uint256 fo, - uint256 fs - ) - external - { - vm.prank(depositor); - lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs); - assertEq(lb.number(), n); - assertEq(lb.timestamp(), t); - assertEq(lb.basefee(), b); - assertEq(lb.hash(), h); - assertEq(lb.sequenceNumber(), s); - assertEq(lb.batcherHash(), bt); - assertEq(lb.l1FeeOverhead(), fo); - assertEq(lb.l1FeeScalar(), fs); - } - - /// @dev Tests that `number` returns the correct value. - function test_number_succeeds() external { - assertEq(lb.number(), uint64(1)); - } - - /// @dev Tests that `timestamp` returns the correct value. - function test_timestamp_succeeds() external { - assertEq(lb.timestamp(), uint64(2)); - } - - /// @dev Tests that `basefee` returns the correct value. - function test_basefee_succeeds() external { - assertEq(lb.basefee(), 3); - } - - /// @dev Tests that `hash` returns the correct value. - function test_hash_succeeds() external { - assertEq(lb.hash(), NON_ZERO_HASH); - } - - /// @dev Tests that `sequenceNumber` returns the correct value. - function test_sequenceNumber_succeeds() external { - assertEq(lb.sequenceNumber(), uint64(4)); - } - - /// @dev Tests that `setL1BlockValues` can set max values. - function test_updateValues_succeeds() external { - vm.prank(depositor); - lb.setL1BlockValues({ - _number: type(uint64).max, - _timestamp: type(uint64).max, - _basefee: type(uint256).max, - _hash: keccak256(abi.encode(1)), - _sequenceNumber: type(uint64).max, - _batcherHash: bytes32(type(uint256).max), - _l1FeeOverhead: type(uint256).max, - _l1FeeScalar: type(uint256).max - }); - } -} diff --git a/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol deleted file mode 100644 index 77f966f310d6..000000000000 --- a/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol +++ /dev/null @@ -1,564 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { Messenger_Initializer, Reverter, ConfigurableCaller } from "test/CommonTest.t.sol"; -import { L2OutputOracle_Initializer } from "test/L2OutputOracle.t.sol"; - -// Libraries -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { Hashing } from "src/libraries/Hashing.sol"; -import { Encoding } from "src/libraries/Encoding.sol"; - -// Target contract dependencies -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; - -// Target contract -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; - -contract L1CrossDomainMessenger_Test is Messenger_Initializer { - /// @dev The receiver address - address recipient = address(0xabbaacdc); - - /// @dev The storage slot of the l2Sender - uint256 constant senderSlotIndex = 50; - - /// @dev Tests that the version can be decoded from the message nonce. - function test_messageVersion_succeeds() external { - (, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce()); - assertEq(version, L1Messenger.MESSAGE_VERSION()); - } - - /// @dev Tests that the sendMessage function is able to send a single message. - /// TODO: this same test needs to be done with the legacy message type - /// by setting the message version to 0 - function test_sendMessage_succeeds() external { - // deposit transaction on the optimism portal should be called - vm.expectCall( - address(op), - abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, - Predeploys.L2_CROSS_DOMAIN_MESSENGER, - 0, - L1Messenger.baseGas(hex"ff", 100), - false, - Encoding.encodeCrossDomainMessage(L1Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff") - ) - ); - - // TransactionDeposited event - vm.expectEmit(true, true, true, true); - emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)), - Predeploys.L2_CROSS_DOMAIN_MESSENGER, - 0, - 0, - L1Messenger.baseGas(hex"ff", 100), - false, - Encoding.encodeCrossDomainMessage(L1Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff") - ); - - // SentMessage event - vm.expectEmit(true, true, true, true); - emit SentMessage(recipient, alice, hex"ff", L1Messenger.messageNonce(), 100); - - // SentMessageExtension1 event - vm.expectEmit(true, true, true, true); - emit SentMessageExtension1(alice, 0); - - vm.prank(alice); - L1Messenger.sendMessage(recipient, hex"ff", uint32(100)); - } - - /// @dev Tests that the sendMessage function is able to send - /// the same message twice. - function test_sendMessage_twice_succeeds() external { - uint256 nonce = L1Messenger.messageNonce(); - L1Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); - L1Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); - // the nonce increments for each message sent - assertEq(nonce + 2, L1Messenger.messageNonce()); - } - - /// @dev Tests that the xDomainMessageSender reverts when not set. - function test_xDomainSender_notSet_reverts() external { - vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L1Messenger.xDomainMessageSender(); - } - - /// @dev Tests that the relayMessage function reverts when - /// the message version is not 0 or 1. - function test_relayMessage_v2_reverts() external { - address target = address(0xabcd); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - - // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - - // Expect a revert. - vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time"); - - // Try to relay a v2 message. - vm.prank(address(op)); - L2Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce - sender, - target, - 0, // value - 0, - hex"1111" - ); - } - - /// @dev Tests that the relayMessage function is able to relay a message - /// successfully by calling the target contract. - function test_relayMessage_succeeds() external { - address target = address(0xabcd); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - - vm.expectCall(target, hex"1111"); - - // set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - vm.prank(address(op)); - - vm.expectEmit(true, true, true, true); - - bytes32 hash = Hashing.hashCrossDomainMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, hex"1111" - ); - - emit RelayedMessage(hash); - - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce - sender, - target, - 0, // value - 0, - hex"1111" - ); - - // the message hash is in the successfulMessages mapping - assert(L1Messenger.successfulMessages(hash)); - // it is not in the received messages mapping - assertEq(L1Messenger.failedMessages(hash), false); - } - - /// @dev Tests that relayMessage reverts if attempting to relay a message - /// sent to an L1 system contract. - function test_relayMessage_toSystemContract_reverts() external { - // set the target to be the OptimismPortal - address target = address(op); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - bytes memory message = hex"1111"; - - vm.prank(address(op)); - vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message - ); - - vm.store(address(op), 0, bytes32(abi.encode(sender))); - vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message - ); - } - - /// @dev Tests that the relayMessage function reverts if eth is - /// sent from a contract other than the standard bridge. - function test_replayMessage_withValue_reverts() external { - address target = address(0xabcd); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - bytes memory message = hex"1111"; - - vm.expectRevert("CrossDomainMessenger: value must be zero unless message is from a system address"); - L1Messenger.relayMessage{ value: 100 }( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message - ); - } - - /// @dev Tests that the xDomainMessageSender is reset to the original value - /// after a message is relayed. - function test_xDomainMessageSender_reset_succeeds() external { - vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L1Messenger.xDomainMessageSender(); - - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - vm.prank(address(op)); - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), address(0), address(0), 0, 0, hex"" - ); - - vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L1Messenger.xDomainMessageSender(); - } - - /// @dev Tests that relayMessage should successfully call the target contract after - /// the first message fails and ETH is stuck, but the second message succeeds - /// with a version 1 message. - function test_relayMessage_retryAfterFailure_succeeds() external { - address target = address(0xabcd); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - uint256 value = 100; - - vm.expectCall(target, hex"1111"); - - bytes32 hash = Hashing.hashCrossDomainMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, value, 0, hex"1111" - ); - - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - vm.etch(target, address(new Reverter()).code); - vm.deal(address(op), value); - vm.prank(address(op)); - L1Messenger.relayMessage{ value: value }( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - - assertEq(address(L1Messenger).balance, value); - assertEq(address(target).balance, 0); - assertEq(L1Messenger.successfulMessages(hash), false); - assertEq(L1Messenger.failedMessages(hash), true); - - vm.expectEmit(true, true, true, true); - - emit RelayedMessage(hash); - - vm.etch(target, address(0).code); - vm.prank(address(sender)); - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - - assertEq(address(L1Messenger).balance, 0); - assertEq(address(target).balance, value); - assertEq(L1Messenger.successfulMessages(hash), true); - assertEq(L1Messenger.failedMessages(hash), true); - } - - /// @dev Tests that relayMessage should successfully call the target contract after - /// the first message fails and ETH is stuck, but the second message succeeds - /// with a legacy message. - function test_relayMessage_legacy_succeeds() external { - address target = address(0xabcd); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - - // Compute the message hash. - bytes32 hash = Hashing.hashCrossDomainMessageV1( - // Using a legacy nonce with version 0. - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), - sender, - target, - 0, - 0, - hex"1111" - ); - - // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - - // Target should be called with expected data. - vm.expectCall(target, hex"1111"); - - // Expect RelayedMessage event to be emitted. - vm.expectEmit(true, true, true, true); - emit RelayedMessage(hash); - - // Relay the message. - vm.prank(address(op)); - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce - sender, - target, - 0, // value - 0, - hex"1111" - ); - - // Message was successfully relayed. - assertEq(L1Messenger.successfulMessages(hash), true); - assertEq(L1Messenger.failedMessages(hash), false); - } - - /// @dev Tests that relayMessage should revert if the message is already replayed. - function test_relayMessage_legacyOldReplay_reverts() external { - address target = address(0xabcd); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - - // Compute the message hash. - bytes32 hash = Hashing.hashCrossDomainMessageV1( - // Using a legacy nonce with version 0. - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), - sender, - target, - 0, - 0, - hex"1111" - ); - - // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - - // Mark legacy message as already relayed. - uint256 successfulMessagesSlot = 203; - bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex"1111", 0); - bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot)); - vm.store(address(L1Messenger), slot, bytes32(uint256(1))); - - // Expect revert. - vm.expectRevert("CrossDomainMessenger: legacy withdrawal already relayed"); - - // Relay the message. - vm.prank(address(op)); - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce - sender, - target, - 0, // value - 0, - hex"1111" - ); - - // Message was not relayed. - assertEq(L1Messenger.successfulMessages(hash), false); - assertEq(L1Messenger.failedMessages(hash), false); - } - - /// @dev Tests that relayMessage can be retried after a failure with a legacy message. - function test_relayMessage_legacyRetryAfterFailure_succeeds() external { - address target = address(0xabcd); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - uint256 value = 100; - - // Compute the message hash. - bytes32 hash = Hashing.hashCrossDomainMessageV1( - // Using a legacy nonce with version 0. - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), - sender, - target, - value, - 0, - hex"1111" - ); - - // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - - // Turn the target into a Reverter. - vm.etch(target, address(new Reverter()).code); - - // Target should be called with expected data. - vm.expectCall(target, hex"1111"); - - // Expect FailedRelayedMessage event to be emitted. - vm.expectEmit(true, true, true, true); - emit FailedRelayedMessage(hash); - - // Relay the message. - vm.deal(address(op), value); - vm.prank(address(op)); - L1Messenger.relayMessage{ value: value }( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - - // Message failed. - assertEq(address(L1Messenger).balance, value); - assertEq(address(target).balance, 0); - assertEq(L1Messenger.successfulMessages(hash), false); - assertEq(L1Messenger.failedMessages(hash), true); - - // Make the target not revert anymore. - vm.etch(target, address(0).code); - - // Target should be called with expected data. - vm.expectCall(target, hex"1111"); - - // Expect RelayedMessage event to be emitted. - vm.expectEmit(true, true, true, true); - emit RelayedMessage(hash); - - // Retry the message. - vm.prank(address(sender)); - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - - // Message was successfully relayed. - assertEq(address(L1Messenger).balance, 0); - assertEq(address(target).balance, value); - assertEq(L1Messenger.successfulMessages(hash), true); - assertEq(L1Messenger.failedMessages(hash), true); - } - - /// @dev Tests that relayMessage cannot be retried after success with a legacy message. - function test_relayMessage_legacyRetryAfterSuccess_reverts() external { - address target = address(0xabcd); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - uint256 value = 100; - - // Compute the message hash. - bytes32 hash = Hashing.hashCrossDomainMessageV1( - // Using a legacy nonce with version 0. - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), - sender, - target, - value, - 0, - hex"1111" - ); - - // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - - // Target should be called with expected data. - vm.expectCall(target, hex"1111"); - - // Expect RelayedMessage event to be emitted. - vm.expectEmit(true, true, true, true); - emit RelayedMessage(hash); - - // Relay the message. - vm.deal(address(op), value); - vm.prank(address(op)); - L1Messenger.relayMessage{ value: value }( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - - // Message was successfully relayed. - assertEq(address(L1Messenger).balance, 0); - assertEq(address(target).balance, value); - assertEq(L1Messenger.successfulMessages(hash), true); - assertEq(L1Messenger.failedMessages(hash), false); - - // Expect a revert. - vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); - - // Retry the message. - vm.prank(address(sender)); - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - } - - /// @dev Tests that relayMessage cannot be called after a failure and a successful replay. - function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external { - address target = address(0xabcd); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - uint256 value = 100; - - // Compute the message hash. - bytes32 hash = Hashing.hashCrossDomainMessageV1( - // Using a legacy nonce with version 0. - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), - sender, - target, - value, - 0, - hex"1111" - ); - - // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - - // Turn the target into a Reverter. - vm.etch(target, address(new Reverter()).code); - - // Target should be called with expected data. - vm.expectCall(target, hex"1111"); - - // Relay the message. - vm.deal(address(op), value); - vm.prank(address(op)); - L1Messenger.relayMessage{ value: value }( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - - // Message failed. - assertEq(address(L1Messenger).balance, value); - assertEq(address(target).balance, 0); - assertEq(L1Messenger.successfulMessages(hash), false); - assertEq(L1Messenger.failedMessages(hash), true); - - // Make the target not revert anymore. - vm.etch(target, address(0).code); - - // Target should be called with expected data. - vm.expectCall(target, hex"1111"); - - // Expect RelayedMessage event to be emitted. - vm.expectEmit(true, true, true, true); - emit RelayedMessage(hash); - - // Retry the message - vm.prank(address(sender)); - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - - // Message was successfully relayed. - assertEq(address(L1Messenger).balance, 0); - assertEq(address(target).balance, value); - assertEq(L1Messenger.successfulMessages(hash), true); - assertEq(L1Messenger.failedMessages(hash), true); - - // Expect a revert. - vm.expectRevert("CrossDomainMessenger: message has already been relayed"); - - // Retry the message again. - vm.prank(address(sender)); - L1Messenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - } -} diff --git a/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol deleted file mode 100644 index b57c8b7ef70d..000000000000 --- a/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol +++ /dev/null @@ -1,293 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; -import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; - -// Target contract dependencies -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; - -/// @dev Test ERC721 contract. -contract TestERC721 is ERC721 { - constructor() ERC721("Test", "TST") { } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } -} - -contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { - TestERC721 internal localToken; - TestERC721 internal remoteToken; - uint256 internal constant tokenId = 1; - - event ERC721BridgeInitiated( - address indexed localToken, - address indexed remoteToken, - address indexed from, - address to, - uint256 tokenId, - bytes extraData - ); - - event ERC721BridgeFinalized( - address indexed localToken, - address indexed remoteToken, - address indexed from, - address to, - uint256 tokenId, - bytes extraData - ); - - /// @dev Sets up the testing environment. - function setUp() public override { - super.setUp(); - - localToken = new TestERC721(); - remoteToken = new TestERC721(); - - // Mint alice a token. - localToken.mint(alice, tokenId); - - // Approve the bridge to transfer the token. - vm.prank(alice); - localToken.approve(address(L1NFTBridge), tokenId); - } - - /// @dev Tests that the constructor sets the correct values. - function test_constructor_succeeds() public { - assertEq(address(L1NFTBridge.MESSENGER()), address(L1Messenger)); - assertEq(address(L1NFTBridge.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE); - assertEq(address(L1NFTBridge.messenger()), address(L1Messenger)); - assertEq(address(L1NFTBridge.otherBridge()), Predeploys.L2_ERC721_BRIDGE); - } - - /// @dev Tests that the ERC721 can be bridged successfully. - function test_bridgeERC721_succeeds() public { - // Expect a call to the messenger. - vm.expectCall( - address(L1Messenger), - abi.encodeCall( - L1Messenger.sendMessage, - ( - address(L2NFTBridge), - abi.encodeCall( - L2ERC721Bridge.finalizeBridgeERC721, - (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678") - ), - 1234 - ) - ) - ); - - // Expect an event to be emitted. - vm.expectEmit(true, true, true, true); - emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - - // Bridge the token. - vm.prank(alice); - L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); - - // Token is locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), true); - assertEq(localToken.ownerOf(tokenId), address(L1NFTBridge)); - } - - /// @dev Tests that the ERC721 bridge reverts for non externally owned accounts. - function test_bridgeERC721_fromContract_reverts() external { - // Bridge the token. - vm.etch(alice, hex"01"); - vm.prank(alice); - vm.expectRevert("ERC721Bridge: account is not externally owned"); - L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that the ERC721 bridge reverts for a zero address local token. - function test_bridgeERC721_localTokenZeroAddress_reverts() external { - // Bridge the token. - vm.prank(alice); - vm.expectRevert(); - L1NFTBridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that the ERC721 bridge reverts for a zero address remote token. - function test_bridgeERC721_remoteTokenZeroAddress_reverts() external { - // Bridge the token. - vm.prank(alice); - vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)"); - L1NFTBridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that the ERC721 bridge reverts for an incorrect owner. - function test_bridgeERC721_wrongOwner_reverts() external { - // Bridge the token. - vm.prank(bob); - vm.expectRevert("ERC721: transfer from incorrect owner"); - L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that the ERC721 bridge successfully sends a token - /// to a different address than the owner. - function test_bridgeERC721To_succeeds() external { - // Expect a call to the messenger. - vm.expectCall( - address(L1Messenger), - abi.encodeCall( - L1Messenger.sendMessage, - ( - address(Predeploys.L2_ERC721_BRIDGE), - abi.encodeCall( - L2ERC721Bridge.finalizeBridgeERC721, - (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") - ), - 1234 - ) - ) - ); - - // Expect an event to be emitted. - vm.expectEmit(true, true, true, true); - emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, bob, tokenId, hex"5678"); - - // Bridge the token. - vm.prank(alice); - L1NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); - - // Token is locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), true); - assertEq(localToken.ownerOf(tokenId), address(L1NFTBridge)); - } - - /// @dev Tests that the ERC721 bridge reverts for non externally owned accounts - /// when sending to a different address than the owner. - function test_bridgeERC721To_localTokenZeroAddress_reverts() external { - // Bridge the token. - vm.prank(alice); - vm.expectRevert(); - L1NFTBridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that the ERC721 bridge reverts for a zero address remote token - /// when sending to a different address than the owner. - function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external { - // Bridge the token. - vm.prank(alice); - vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)"); - L1NFTBridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that the ERC721 bridge reverts for an incorrect owner - //// when sending to a different address than the owner. - function test_bridgeERC721To_wrongOwner_reverts() external { - // Bridge the token. - vm.prank(bob); - vm.expectRevert("ERC721: transfer from incorrect owner"); - L1NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that the ERC721 bridge successfully finalizes a withdrawal. - function test_finalizeBridgeERC721_succeeds() external { - // Bridge the token. - vm.prank(alice); - L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); - - // Expect an event to be emitted. - vm.expectEmit(true, true, true, true); - emit ERC721BridgeFinalized(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - - // Finalize a withdrawal. - vm.mockCall( - address(L1Messenger), - abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), - abi.encode(Predeploys.L2_ERC721_BRIDGE) - ); - vm.prank(address(L1Messenger)); - L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - - // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that the ERC721 bridge finalize reverts when not called - /// by the remote bridge. - function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external { - // Finalize a withdrawal. - vm.prank(alice); - vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); - L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - } - - /// @dev Tests that the ERC721 bridge finalize reverts when not called - /// from the remote messenger. - function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { - // Finalize a withdrawal. - vm.mockCall( - address(L1Messenger), abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), abi.encode(alice) - ); - vm.prank(address(L1Messenger)); - vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); - L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - } - - /// @dev Tests that the ERC721 bridge finalize reverts when the local token - /// is set as the bridge itself. - function test_finalizeBridgeERC721_selfToken_reverts() external { - // Finalize a withdrawal. - vm.mockCall( - address(L1Messenger), - abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), - abi.encode(Predeploys.L2_ERC721_BRIDGE) - ); - vm.prank(address(L1Messenger)); - vm.expectRevert("L1ERC721Bridge: local token cannot be self"); - L1NFTBridge.finalizeBridgeERC721(address(L1NFTBridge), address(remoteToken), alice, alice, tokenId, hex"5678"); - } - - /// @dev Tests that the ERC721 bridge finalize reverts when the remote token - /// is not escrowed in the L1 bridge. - function test_finalizeBridgeERC721_notEscrowed_reverts() external { - // Finalize a withdrawal. - vm.mockCall( - address(L1Messenger), - abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), - abi.encode(Predeploys.L2_ERC721_BRIDGE) - ); - vm.prank(address(L1Messenger)); - vm.expectRevert("L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge"); - L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - } -} diff --git a/packages/contracts-bedrock/test/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1StandardBridge.t.sol deleted file mode 100644 index c8966dd8b62f..000000000000 --- a/packages/contracts-bedrock/test/L1StandardBridge.t.sol +++ /dev/null @@ -1,588 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { stdStorage, StdStorage } from "forge-std/Test.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { Bridge_Initializer } from "test/CommonTest.t.sol"; - -// Libraries -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { Constants } from "src/libraries/Constants.sol"; - -// Target contract dependencies -import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; - -// Target contract -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; - -contract L1StandardBridge_Getter_Test is Bridge_Initializer { - /// @dev Test that the accessors return the correct initialized values. - function test_getters_succeeds() external view { - assert(L1Bridge.l2TokenBridge() == address(L2Bridge)); - assert(L1Bridge.OTHER_BRIDGE() == L2Bridge); - assert(L1Bridge.messenger() == L1Messenger); - assert(L1Bridge.MESSENGER() == L1Messenger); - } -} - -contract L1StandardBridge_Initialize_Test is Bridge_Initializer { - /// @dev Test that the initialize function sets the correct values. - function test_initialize_succeeds() external { - assertEq(address(L1Bridge.messenger()), address(L1Messenger)); - assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE); - assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE); - bytes32 slot0 = vm.load(address(L1Bridge), bytes32(uint256(0))); - assertEq(slot0, bytes32(uint256(Constants.INITIALIZER))); - } -} - -contract L1StandardBridge_Initialize_TestFail is Bridge_Initializer { } - -contract L1StandardBridge_Receive_Test is Bridge_Initializer { - /// @dev Tests receive bridges ETH successfully. - function test_receive_succeeds() external { - assertEq(address(op).balance, 0); - - // The legacy event must be emitted for backwards compatibility - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ETHDepositInitiated(alice, alice, 100, hex""); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ETHBridgeInitiated(alice, alice, 100, hex""); - - vm.expectCall( - address(L1Messenger), - abi.encodeWithSelector( - CrossDomainMessenger.sendMessage.selector, - address(L2Bridge), - abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""), - 200_000 - ) - ); - - vm.prank(alice, alice); - (bool success,) = address(L1Bridge).call{ value: 100 }(hex""); - assertEq(success, true); - assertEq(address(op).balance, 100); - } -} - -contract L1StandardBridge_Receive_TestFail { } - -contract PreBridgeETH is Bridge_Initializer { - /// @dev Asserts the expected calls and events for bridging ETH depending - /// on whether the bridge call is legacy or not. - function _preBridgeETH(bool isLegacy) internal { - assertEq(address(op).balance, 0); - uint256 nonce = L1Messenger.messageNonce(); - uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION - address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); - - bytes memory message = - abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 500, hex"dead"); - - if (isLegacy) { - vm.expectCall( - address(L1Bridge), 500, abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex"dead") - ); - } else { - vm.expectCall(address(L1Bridge), 500, abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex"dead")); - } - vm.expectCall( - address(L1Messenger), - 500, - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 50000) - ); - - bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 500, 50000, message - ); - - uint64 baseGas = L1Messenger.baseGas(message, 50000); - vm.expectCall( - address(op), - 500, - abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, address(L2Messenger), 500, baseGas, false, innerMessage - ) - ); - - bytes memory opaqueData = abi.encodePacked(uint256(500), uint256(500), baseGas, false, innerMessage); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ETHDepositInitiated(alice, alice, 500, hex"dead"); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ETHBridgeInitiated(alice, alice, 500, hex"dead"); - - // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call - vm.expectEmit(true, true, true, true, address(op)); - emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); - - // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 50000); - - // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessageExtension1(address(L1Bridge), 500); - - vm.prank(alice, alice); - } -} - -contract L1StandardBridge_DepositETH_Test is PreBridgeETH { - /// @dev Tests that depositing ETH succeeds. - /// Emits ETHDepositInitiated and ETHBridgeInitiated events. - /// Calls depositTransaction on the OptimismPortal. - /// Only EOA can call depositETH. - /// ETH ends up in the optimismPortal. - function test_depositETH_succeeds() external { - _preBridgeETH({ isLegacy: true }); - L1Bridge.depositETH{ value: 500 }(50000, hex"dead"); - assertEq(address(op).balance, 500); - } -} - -contract L1StandardBridge_BridgeETH_Test is PreBridgeETH { - /// @dev Tests that bridging ETH succeeds. - /// Emits ETHDepositInitiated and ETHBridgeInitiated events. - /// Calls depositTransaction on the OptimismPortal. - /// Only EOA can call bridgeETH. - /// ETH ends up in the optimismPortal. - function test_bridgeETH_succeeds() external { - _preBridgeETH({ isLegacy: false }); - L1Bridge.bridgeETH{ value: 500 }(50000, hex"dead"); - assertEq(address(op).balance, 500); - } -} - -contract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer { - /// @dev Tests that depositing ETH reverts if the call is not from an EOA. - function test_depositETH_notEoa_reverts() external { - vm.etch(alice, address(L1Token).code); - vm.expectRevert("StandardBridge: function can only be called from an EOA"); - vm.prank(alice); - L1Bridge.depositETH{ value: 1 }(300, hex""); - } -} - -contract PreBridgeETHTo is Bridge_Initializer { - /// @dev Asserts the expected calls and events for bridging ETH to a different - /// address depending on whether the bridge call is legacy or not. - function _preBridgeETHTo(bool isLegacy) internal { - assertEq(address(op).balance, 0); - uint256 nonce = L1Messenger.messageNonce(); - uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION - address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); - - if (isLegacy) { - vm.expectCall( - address(L1Bridge), 600, abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex"dead") - ); - } else { - vm.expectCall( - address(L1Bridge), 600, abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex"dead") - ); - } - - bytes memory message = - abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, bob, 600, hex"dead"); - - // the L1 bridge should call - // L1CrossDomainMessenger.sendMessage - vm.expectCall( - address(L1Messenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 60000) - ); - - bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 600, 60000, message - ); - - uint64 baseGas = L1Messenger.baseGas(message, 60000); - vm.expectCall( - address(op), - abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, address(L2Messenger), 600, baseGas, false, innerMessage - ) - ); - - bytes memory opaqueData = abi.encodePacked(uint256(600), uint256(600), baseGas, false, innerMessage); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ETHDepositInitiated(alice, bob, 600, hex"dead"); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ETHBridgeInitiated(alice, bob, 600, hex"dead"); - - // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call - vm.expectEmit(true, true, true, true, address(op)); - emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); - - // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 60000); - - // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessageExtension1(address(L1Bridge), 600); - - // deposit eth to bob - vm.prank(alice, alice); - } -} - -contract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo { - /// @dev Tests that depositing ETH to a different address succeeds. - /// Emits ETHDepositInitiated event. - /// Calls depositTransaction on the OptimismPortal. - /// EOA or contract can call depositETHTo. - /// ETH ends up in the optimismPortal. - function test_depositETHTo_succeeds() external { - _preBridgeETHTo({ isLegacy: true }); - L1Bridge.depositETHTo{ value: 600 }(bob, 60000, hex"dead"); - assertEq(address(op).balance, 600); - } -} - -contract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo { - /// @dev Tests that bridging ETH to a different address succeeds. - /// Emits ETHDepositInitiated and ETHBridgeInitiated events. - /// Calls depositTransaction on the OptimismPortal. - /// Only EOA can call bridgeETHTo. - /// ETH ends up in the optimismPortal. - function test_bridgeETHTo_succeeds() external { - _preBridgeETHTo({ isLegacy: false }); - L1Bridge.bridgeETHTo{ value: 600 }(bob, 60000, hex"dead"); - assertEq(address(op).balance, 600); - } -} - -contract L1StandardBridge_DepositETHTo_TestFail is Bridge_Initializer { } - -contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer { - using stdStorage for StdStorage; - - // depositERC20 - // - updates bridge.deposits - // - emits ERC20DepositInitiated - // - calls optimismPortal.depositTransaction - // - only callable by EOA - - /// @dev Tests that depositing ERC20 to the bridge succeeds. - /// Bridge deposits are updated. - /// Emits ERC20DepositInitiated event. - /// Calls depositTransaction on the OptimismPortal. - /// Only EOA can call depositERC20. - function test_depositERC20_succeeds() external { - uint256 nonce = L1Messenger.messageNonce(); - uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION - address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); - - // Deal Alice's ERC20 State - deal(address(L1Token), alice, 100000, true); - vm.prank(alice); - L1Token.approve(address(L1Bridge), type(uint256).max); - - // The L1Bridge should transfer alice's tokens to itself - vm.expectCall( - address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100) - ); - - bytes memory message = abi.encodeWithSelector( - StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, alice, 100, hex"" - ); - - // the L1 bridge should call L1CrossDomainMessenger.sendMessage - vm.expectCall( - address(L1Messenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 10000) - ); - - bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 0, 10000, message - ); - - uint64 baseGas = L1Messenger.baseGas(message, 10000); - vm.expectCall( - address(op), - abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, address(L2Messenger), 0, baseGas, false, innerMessage - ) - ); - - bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage); - - // Should emit both the bedrock and legacy events - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex""); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex""); - - // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call - vm.expectEmit(true, true, true, true, address(op)); - emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); - - // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000); - - // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessageExtension1(address(L1Bridge), 0); - - vm.prank(alice); - L1Bridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex""); - assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100); - } -} - -contract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer { - /// @dev Tests that depositing an ERC20 to the bridge reverts - /// if the caller is not an EOA. - function test_depositERC20_notEoa_reverts() external { - // turn alice into a contract - vm.etch(alice, hex"ffff"); - - vm.expectRevert("StandardBridge: function can only be called from an EOA"); - vm.prank(alice, alice); - L1Bridge.depositERC20(address(0), address(0), 100, 100, hex""); - } -} - -contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer { - /// @dev Tests that depositing ERC20 to the bridge succeeds when - /// sent to a different address. - /// Bridge deposits are updated. - /// Emits ERC20DepositInitiated event. - /// Calls depositTransaction on the OptimismPortal. - /// Contracts can call depositERC20. - function test_depositERC20To_succeeds() external { - uint256 nonce = L1Messenger.messageNonce(); - uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION - address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); - - bytes memory message = abi.encodeWithSelector( - StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, bob, 1000, hex"" - ); - - bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 0, 10000, message - ); - - uint64 baseGas = L1Messenger.baseGas(message, 10000); - bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage); - - deal(address(L1Token), alice, 100000, true); - - vm.prank(alice); - L1Token.approve(address(L1Bridge), type(uint256).max); - - // Should emit both the bedrock and legacy events - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex""); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex""); - - // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call - vm.expectEmit(true, true, true, true, address(op)); - emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); - - // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000); - - // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessageExtension1(address(L1Bridge), 0); - - // the L1 bridge should call L1CrossDomainMessenger.sendMessage - vm.expectCall( - address(L1Messenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 10000) - ); - // The L1 XDM should call OptimismPortal.depositTransaction - vm.expectCall( - address(op), - abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, address(L2Messenger), 0, baseGas, false, innerMessage - ) - ); - vm.expectCall( - address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000) - ); - - vm.prank(alice); - L1Bridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex""); - - assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 1000); - } -} - -contract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer { - using stdStorage for StdStorage; - - /// @dev Tests that finalizing an ETH withdrawal succeeds. - /// Emits ETHWithdrawalFinalized event. - /// Only callable by the L2 bridge. - function test_finalizeETHWithdrawal_succeeds() external { - uint256 aliceBalance = alice.balance; - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ETHWithdrawalFinalized(alice, alice, 100, hex""); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ETHBridgeFinalized(alice, alice, 100, hex""); - - vm.expectCall(alice, hex""); - - vm.mockCall( - address(L1Bridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) - ); - // ensure that the messenger has ETH to call with - vm.deal(address(L1Bridge.messenger()), 100); - vm.prank(address(L1Bridge.messenger())); - L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex""); - - assertEq(address(L1Bridge.messenger()).balance, 0); - assertEq(aliceBalance + 100, alice.balance); - } -} - -contract L1StandardBridge_FinalizeETHWithdrawal_TestFail is Bridge_Initializer { } - -contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer { - using stdStorage for StdStorage; - - /// @dev Tests that finalizing an ERC20 withdrawal succeeds. - /// Bridge deposits are updated. - /// Emits ERC20WithdrawalFinalized event. - /// Only callable by the L2 bridge. - function test_finalizeERC20Withdrawal_succeeds() external { - deal(address(L1Token), address(L1Bridge), 100, true); - - uint256 slot = stdstore.target(address(L1Bridge)).sig("deposits(address,address)").with_key(address(L1Token)) - .with_key(address(L2Token)).find(); - - // Give the L1 bridge some ERC20 tokens - vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100))); - assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); - - vm.expectCall(address(L1Token), abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)); - - vm.mockCall( - address(L1Bridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) - ); - vm.prank(address(L1Bridge.messenger())); - L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); - - assertEq(L1Token.balanceOf(address(L1Bridge)), 0); - assertEq(L1Token.balanceOf(address(alice)), 100); - } -} - -contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer { - /// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge. - function test_finalizeERC20Withdrawal_notMessenger_reverts() external { - vm.mockCall( - address(L1Bridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) - ); - vm.prank(address(28)); - vm.expectRevert("StandardBridge: function can only be called from the other bridge"); - L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); - } - - /// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge. - function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external { - vm.mockCall( - address(L1Bridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(address(0))) - ); - vm.prank(address(L1Bridge.messenger())); - vm.expectRevert("StandardBridge: function can only be called from the other bridge"); - L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); - } -} - -contract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { - /// @dev Tests that finalizing bridged ETH succeeds. - function test_finalizeBridgeETH_succeeds() external { - address messenger = address(L1Bridge.messenger()); - vm.mockCall( - messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) - ); - vm.deal(messenger, 100); - vm.prank(messenger); - - vm.expectEmit(true, true, true, true, address(L1Bridge)); - emit ETHBridgeFinalized(alice, alice, 100, hex""); - - L1Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); - } -} - -contract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer { - /// @dev Tests that finalizing bridged ETH reverts if the amount is incorrect. - function test_finalizeBridgeETH_incorrectValue_reverts() external { - address messenger = address(L1Bridge.messenger()); - vm.mockCall( - messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) - ); - vm.deal(messenger, 100); - vm.prank(messenger); - vm.expectRevert("StandardBridge: amount sent does not match amount required"); - L1Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex""); - } - - /// @dev Tests that finalizing bridged ETH reverts if the destination is the L1 bridge. - function test_finalizeBridgeETH_sendToSelf_reverts() external { - address messenger = address(L1Bridge.messenger()); - vm.mockCall( - messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) - ); - vm.deal(messenger, 100); - vm.prank(messenger); - vm.expectRevert("StandardBridge: cannot send to self"); - L1Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L1Bridge), 100, hex""); - } - - /// @dev Tests that finalizing bridged ETH reverts if the destination is the messenger. - function test_finalizeBridgeETH_sendToMessenger_reverts() external { - address messenger = address(L1Bridge.messenger()); - vm.mockCall( - messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) - ); - vm.deal(messenger, 100); - vm.prank(messenger); - vm.expectRevert("StandardBridge: cannot send to messenger"); - L1Bridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex""); - } -} diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol b/packages/contracts-bedrock/test/L2/CrossDomainOwnable.t.sol similarity index 84% rename from packages/contracts-bedrock/test/CrossDomainOwnable.t.sol rename to packages/contracts-bedrock/test/L2/CrossDomainOwnable.t.sol index 27c8757066f7..1e7c10556a53 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol +++ b/packages/contracts-bedrock/test/L2/CrossDomainOwnable.t.sol @@ -2,17 +2,18 @@ pragma solidity 0.8.15; // Testing utilities -import { Vm, VmSafe } from "forge-std/Vm.sol"; -import { CommonTest, Portal_Initializer } from "test/CommonTest.t.sol"; +import { VmSafe } from "forge-std/Vm.sol"; +import { Test } from "forge-std/Test.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; // Target contract dependencies -import { AddressAliasHelper } from "../src/vendor/AddressAliasHelper.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; // Target contract -import { CrossDomainOwnable } from "../src/L2/CrossDomainOwnable.sol"; +import { CrossDomainOwnable } from "src/L2/CrossDomainOwnable.sol"; contract XDomainSetter is CrossDomainOwnable { uint256 public value; @@ -22,11 +23,10 @@ contract XDomainSetter is CrossDomainOwnable { } } -contract CrossDomainOwnable_Test is CommonTest { +contract CrossDomainOwnable_Test is Test { XDomainSetter setter; - function setUp() public override { - super.setUp(); + function setUp() public { setter = new XDomainSetter(); } @@ -46,7 +46,7 @@ contract CrossDomainOwnable_Test is CommonTest { } } -contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer { +contract CrossDomainOwnableThroughPortal_Test is CommonTest { XDomainSetter setter; /// @dev Sets up the test suite. @@ -63,7 +63,7 @@ contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer { vm.recordLogs(); vm.prank(alice); - op.depositTransaction({ + optimismPortal.depositTransaction({ _to: address(setter), _value: 0, _gasLimit: 30_000, diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol b/packages/contracts-bedrock/test/L2/CrossDomainOwnable2.t.sol similarity index 78% rename from packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol rename to packages/contracts-bedrock/test/L2/CrossDomainOwnable2.t.sol index c059872c784a..fa1244a0b0e1 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol +++ b/packages/contracts-bedrock/test/L2/CrossDomainOwnable2.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest, Messenger_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; // Libraries import { Hashing } from "src/libraries/Hashing.sol"; @@ -10,10 +10,10 @@ import { Encoding } from "src/libraries/Encoding.sol"; import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; // Target contract dependencies -import { AddressAliasHelper } from "../src/vendor/AddressAliasHelper.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; // Target contract -import { CrossDomainOwnable2 } from "../src/L2/CrossDomainOwnable2.sol"; +import { CrossDomainOwnable2 } from "src/L2/CrossDomainOwnable2.sol"; contract XDomainSetter2 is CrossDomainOwnable2 { uint256 public value; @@ -23,7 +23,7 @@ contract XDomainSetter2 is CrossDomainOwnable2 { } } -contract CrossDomainOwnable2_Test is Messenger_Initializer { +contract CrossDomainOwnable2_Test is Bridge_Initializer { XDomainSetter2 setter; /// @dev Sets up the test suite. @@ -44,9 +44,9 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { // set the xDomainMsgSender storage slot bytes32 key = bytes32(uint256(204)); bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice)); - vm.store(address(L2Messenger), key, value); + vm.store(address(l2CrossDomainMessenger), key, value); - vm.prank(address(L2Messenger)); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("CrossDomainOwnable2: caller is not the owner"); setter.set(1); } @@ -69,8 +69,10 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { vm.expectEmit(true, true, true, true); emit FailedRelayedMessage(hash); - vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); - L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message); + vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger))); + l2CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message + ); assertEq(setter.value(), 0); } @@ -81,8 +83,8 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { // Simulate the L2 execution where the call is coming from // the L1CrossDomainMessenger - vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); - L2Messenger.relayMessage( + vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger))); + l2CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce(1, 1), owner, address(setter), diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol b/packages/contracts-bedrock/test/L2/CrossDomainOwnable3.t.sol similarity index 91% rename from packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol rename to packages/contracts-bedrock/test/L2/CrossDomainOwnable3.t.sol index dbe2c9af3b4c..24eab5f55a48 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol +++ b/packages/contracts-bedrock/test/L2/CrossDomainOwnable3.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest, Messenger_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; // Libraries import { Hashing } from "src/libraries/Hashing.sol"; @@ -23,7 +23,7 @@ contract XDomainSetter3 is CrossDomainOwnable3 { } } -contract CrossDomainOwnable3_Test is Messenger_Initializer { +contract CrossDomainOwnable3_Test is Bridge_Initializer { XDomainSetter3 setter; /// @dev CrossDomainOwnable3.sol transferOwnership event @@ -73,9 +73,9 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { // set the xDomainMsgSender storage slot bytes32 key = bytes32(uint256(204)); bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob); - vm.store(address(L2Messenger), key, value); + vm.store(address(l2CrossDomainMessenger), key, value); - vm.prank(address(L2Messenger)); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("CrossDomainOwnable3: caller is not the owner"); setter.set(1); } @@ -109,11 +109,13 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { // It should be a failed message. The revert is caught, // so we cannot expectRevert here. - vm.expectEmit(true, true, true, true, address(L2Messenger)); + vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger)); emit FailedRelayedMessage(hash); - vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); - L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message); + vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger))); + l2CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message + ); assertEq(setter.value(), 0); } @@ -212,8 +214,8 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { // Simulate the L2 execution where the call is coming from // the L1CrossDomainMessenger - vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); - L2Messenger.relayMessage( + vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger))); + l2CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce(1, 1), bob, address(setter), diff --git a/packages/contracts-bedrock/test/L2/GasPriceOracle.t.sol b/packages/contracts-bedrock/test/L2/GasPriceOracle.t.sol new file mode 100644 index 000000000000..f829d207d02e --- /dev/null +++ b/packages/contracts-bedrock/test/L2/GasPriceOracle.t.sol @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; + +// Libraries +import { Encoding } from "src/libraries/Encoding.sol"; + +contract GasPriceOracle_Test is CommonTest { + event OverheadUpdated(uint256); + event ScalarUpdated(uint256); + event DecimalsUpdated(uint256); + + address depositor; + + // The initial L1 context values + uint64 constant number = 10; + uint64 constant timestamp = 11; + uint256 constant baseFee = 2 * (10 ** 6); + uint256 constant blobBaseFee = 3 * (10 ** 6); + bytes32 constant hash = bytes32(uint256(64)); + uint64 constant sequenceNumber = 0; + bytes32 constant batcherHash = bytes32(uint256(777)); + uint256 constant l1FeeOverhead = 310; + uint256 constant l1FeeScalar = 10; + uint32 constant blobBaseFeeScalar = 15; + uint32 constant baseFeeScalar = 20; + + /// @dev Sets up the test suite. + function setUp() public virtual override { + super.setUp(); + depositor = l1Block.DEPOSITOR_ACCOUNT(); + } +} + +contract GasPriceOracleBedrock_Test is GasPriceOracle_Test { + /// @dev Sets up the test suite. + function setUp() public virtual override { + super.setUp(); + + vm.prank(depositor); + l1Block.setL1BlockValues({ + _number: number, + _timestamp: timestamp, + _basefee: baseFee, + _hash: hash, + _sequenceNumber: sequenceNumber, + _batcherHash: batcherHash, + _l1FeeOverhead: l1FeeOverhead, + _l1FeeScalar: l1FeeScalar + }); + } + + /// @dev Tests that `l1BaseFee` is set correctly. + function test_l1BaseFee_succeeds() external { + assertEq(gasPriceOracle.l1BaseFee(), baseFee); + } + + /// @dev Tests that `gasPrice` is set correctly. + function test_gasPrice_succeeds() external { + vm.fee(100); + uint256 gasPrice = gasPriceOracle.gasPrice(); + assertEq(gasPrice, 100); + } + + /// @dev Tests that `baseFee` is set correctly. + function test_baseFee_succeeds() external { + vm.fee(64); + uint256 gasPrice = gasPriceOracle.baseFee(); + assertEq(gasPrice, 64); + } + + /// @dev Tests that `scalar` is set correctly. + function test_scalar_succeeds() external { + assertEq(gasPriceOracle.scalar(), l1FeeScalar); + } + + /// @dev Tests that `overhead` is set correctly. + function test_overhead_succeeds() external { + assertEq(gasPriceOracle.overhead(), l1FeeOverhead); + } + + /// @dev Tests that `decimals` is set correctly. + function test_decimals_succeeds() external { + assertEq(gasPriceOracle.decimals(), 6); + assertEq(gasPriceOracle.DECIMALS(), 6); + } + + /// @dev Tests that `setGasPrice` reverts since it was removed in bedrock. + function test_setGasPrice_doesNotExist_reverts() external { + (bool success, bytes memory returndata) = + address(gasPriceOracle).call(abi.encodeWithSignature("setGasPrice(uint256)", 1)); + + assertEq(success, false); + assertEq(returndata, hex""); + } + + /// @dev Tests that `setL1BaseFee` reverts since it was removed in bedrock. + function test_setL1BaseFee_doesNotExist_reverts() external { + (bool success, bytes memory returndata) = + address(gasPriceOracle).call(abi.encodeWithSignature("setL1BaseFee(uint256)", 1)); + + assertEq(success, false); + assertEq(returndata, hex""); + } +} + +contract GasPriceOracleEcotone_Test is GasPriceOracle_Test { + /// @dev Sets up the test suite. + function setUp() public virtual override { + super.setUp(); + + bytes memory calldataPacked = Encoding.encodeSetL1BlockValuesEcotone( + baseFeeScalar, blobBaseFeeScalar, sequenceNumber, timestamp, number, baseFee, blobBaseFee, hash, batcherHash + ); + + // Execute the function call + vm.prank(depositor); + (bool success,) = address(l1Block).call(calldataPacked); + require(success, "Function call failed"); + + vm.prank(depositor); + gasPriceOracle.setEcotone(); + } + + /// @dev Tests that `setEcotone` is only callable by the depositor. + function test_setEcotone_wrongCaller_reverts() external { + vm.expectRevert("GasPriceOracle: only the depositor account can set isEcotone flag"); + gasPriceOracle.setEcotone(); + } + + /// @dev Tests that `gasPrice` is set correctly. + function test_gasPrice_succeeds() external { + vm.fee(100); + uint256 gasPrice = gasPriceOracle.gasPrice(); + assertEq(gasPrice, 100); + } + + /// @dev Tests that `baseFee` is set correctly. + function test_baseFee_succeeds() external { + vm.fee(64); + uint256 gasPrice = gasPriceOracle.baseFee(); + assertEq(gasPrice, 64); + } + + /// @dev Tests that `overhead` reverts since it was removed in ecotone. + function test_overhead_legacyFunction_reverts() external { + vm.expectRevert("GasPriceOracle: overhead() is deprecated"); + gasPriceOracle.overhead(); + } + + /// @dev Tests that `scalar` reverts since it was removed in ecotone. + function test_scalar_legacyFunction_reverts() external { + vm.expectRevert("GasPriceOracle: scalar() is deprecated"); + gasPriceOracle.scalar(); + } + + /// @dev Tests that `l1BaseFee` is set correctly. + function test_l1BaseFee_succeeds() external { + assertEq(gasPriceOracle.l1BaseFee(), baseFee); + } + + /// @dev Tests that `blobBaseFee` is set correctly. + function test_blobBaseFee_succeeds() external { + assertEq(gasPriceOracle.blobBaseFee(), blobBaseFee); + } + + /// @dev Tests that `baseFeeScalar` is set correctly. + function test_baseFeeScalar_succeeds() external { + assertEq(gasPriceOracle.baseFeeScalar(), baseFeeScalar); + } + + /// @dev Tests that `blobBaseFeeScalar` is set correctly. + function test_blobBaseFeeScalar_succeeds() external { + assertEq(gasPriceOracle.blobBaseFeeScalar(), blobBaseFeeScalar); + } + + /// @dev Tests that `decimals` is set correctly. + function test_decimals_succeeds() external { + assertEq(gasPriceOracle.decimals(), 6); + assertEq(gasPriceOracle.DECIMALS(), 6); + } + + /// @dev Tests that `getL1GasUsed` and `getL1Fee` return expected values + function test_getL1Fee_succeeds() external { + bytes memory data = hex"0000010203"; // 2 zero bytes, 3 non-zero bytes + // (2*4) + (3*16) + (68*16) == 1144 + uint256 gas = gasPriceOracle.getL1GasUsed(data); + assertEq(gas, 1144); + uint256 price = gasPriceOracle.getL1Fee(data); + // gas * (2M*16*20 + 3M*15) / 16M == 48977.5 + assertEq(price, 48977); + } +} diff --git a/packages/contracts-bedrock/test/L2/L1Block.t.sol b/packages/contracts-bedrock/test/L2/L1Block.t.sol new file mode 100644 index 000000000000..18fd7efea582 --- /dev/null +++ b/packages/contracts-bedrock/test/L2/L1Block.t.sol @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; + +// Libraries +import { Encoding } from "src/libraries/Encoding.sol"; + +// Target contract +import { L1Block } from "src/L2/L1Block.sol"; + +contract L1BlockTest is CommonTest { + address depositor; + + /// @dev Sets up the test suite. + function setUp() public virtual override { + super.setUp(); + depositor = l1Block.DEPOSITOR_ACCOUNT(); + } +} + +contract L1BlockBedrock_Test is L1BlockTest { + // @dev Tests that `setL1BlockValues` updates the values correctly. + function testFuzz_updatesValues_succeeds( + uint64 n, + uint64 t, + uint256 b, + bytes32 h, + uint64 s, + bytes32 bt, + uint256 fo, + uint256 fs + ) + external + { + vm.prank(depositor); + l1Block.setL1BlockValues(n, t, b, h, s, bt, fo, fs); + assertEq(l1Block.number(), n); + assertEq(l1Block.timestamp(), t); + assertEq(l1Block.basefee(), b); + assertEq(l1Block.hash(), h); + assertEq(l1Block.sequenceNumber(), s); + assertEq(l1Block.batcherHash(), bt); + assertEq(l1Block.l1FeeOverhead(), fo); + assertEq(l1Block.l1FeeScalar(), fs); + } + + /// @dev Tests that `setL1BlockValues` can set max values. + function test_updateValues_succeeds() external { + vm.prank(depositor); + l1Block.setL1BlockValues({ + _number: type(uint64).max, + _timestamp: type(uint64).max, + _basefee: type(uint256).max, + _hash: keccak256(abi.encode(1)), + _sequenceNumber: type(uint64).max, + _batcherHash: bytes32(type(uint256).max), + _l1FeeOverhead: type(uint256).max, + _l1FeeScalar: type(uint256).max + }); + } +} + +contract L1BlockEcotone_Test is L1BlockTest { + /// @dev Tests that setL1BlockValuesEcotone updates the values appropriately. + function testFuzz_setL1BlockValuesEcotone_succeeds( + uint32 baseFeeScalar, + uint32 blobBaseFeeScalar, + uint64 sequenceNumber, + uint64 timestamp, + uint64 number, + uint256 baseFee, + uint256 blobBaseFee, + bytes32 hash, + bytes32 batcherHash + ) + external + { + bytes memory functionCallDataPacked = Encoding.encodeSetL1BlockValuesEcotone( + baseFeeScalar, blobBaseFeeScalar, sequenceNumber, timestamp, number, baseFee, blobBaseFee, hash, batcherHash + ); + + vm.prank(depositor); + (bool success,) = address(l1Block).call(functionCallDataPacked); + assertTrue(success, "Function call failed"); + + assertEq(l1Block.baseFeeScalar(), baseFeeScalar); + assertEq(l1Block.blobBaseFeeScalar(), blobBaseFeeScalar); + assertEq(l1Block.sequenceNumber(), sequenceNumber); + assertEq(l1Block.timestamp(), timestamp); + assertEq(l1Block.number(), number); + assertEq(l1Block.basefee(), baseFee); + assertEq(l1Block.blobBaseFee(), blobBaseFee); + assertEq(l1Block.hash(), hash); + assertEq(l1Block.batcherHash(), batcherHash); + + // ensure we didn't accidentally pollute the 128 bits of the sequencenum+scalars slot that + // should be empty + bytes32 scalarsSlot = vm.load(address(l1Block), bytes32(uint256(3))); + bytes32 mask128 = hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"; + + assertEq(0, scalarsSlot & mask128); + + // ensure we didn't accidentally pollute the 128 bits of the number & timestamp slot that + // should be empty + bytes32 numberTimestampSlot = vm.load(address(l1Block), bytes32(uint256(0))); + assertEq(0, numberTimestampSlot & mask128); + } + + /// @dev Tests that `setL1BlockValuesEcotone` succeeds if sender address is the depositor + function test_setL1BlockValuesEcotone_isDepositor_succeeds() external { + bytes memory functionCallDataPacked = Encoding.encodeSetL1BlockValuesEcotone( + type(uint32).max, + type(uint32).max, + type(uint64).max, + type(uint64).max, + type(uint64).max, + type(uint256).max, + type(uint256).max, + bytes32(type(uint256).max), + bytes32(type(uint256).max) + ); + + vm.prank(depositor); + (bool success,) = address(l1Block).call(functionCallDataPacked); + assertTrue(success, "function call failed"); + } + + /// @dev Tests that `setL1BlockValuesEcotone` fails if sender address is not the depositor + function test_setL1BlockValuesEcotone_notDepositor_fails() external { + bytes memory functionCallDataPacked = Encoding.encodeSetL1BlockValuesEcotone( + type(uint32).max, + type(uint32).max, + type(uint64).max, + type(uint64).max, + type(uint64).max, + type(uint256).max, + type(uint256).max, + bytes32(type(uint256).max), + bytes32(type(uint256).max) + ); + + (bool success, bytes memory data) = address(l1Block).call(functionCallDataPacked); + assertTrue(!success, "function call should have failed"); + // make sure return value is the expected function selector for "NotDepositor()" + bytes memory expReturn = hex"3cc50b45"; + assertEq(data, expReturn); + } +} diff --git a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol new file mode 100644 index 000000000000..eb9e1f30a91b --- /dev/null +++ b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; +import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Libraries +import { Hashing } from "src/libraries/Hashing.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; +import { Types } from "src/libraries/Types.sol"; + +// Target contract dependencies +import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; +import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; + +contract L2CrossDomainMessenger_Test is Bridge_Initializer { + /// @dev Receiver address for testing + address recipient = address(0xabbaacdc); + + /// @dev Tests that the implementation is initialized correctly. + function test_constructor_succeeds() external { + L2CrossDomainMessenger impl = + L2CrossDomainMessenger(EIP1967Helper.getImplementation(deploy.mustGetAddress("L2CrossDomainMessenger"))); + assertEq(address(impl.OTHER_MESSENGER()), address(0)); + assertEq(address(impl.otherMessenger()), address(0)); + assertEq(address(impl.l1CrossDomainMessenger()), address(0)); + } + + /// @dev Tests that the proxy is initialized correctly. + function test_initialize_succeeds() external { + assertEq(address(l2CrossDomainMessenger.OTHER_MESSENGER()), address(l1CrossDomainMessenger)); + assertEq(address(l2CrossDomainMessenger.otherMessenger()), address(l1CrossDomainMessenger)); + assertEq(address(l2CrossDomainMessenger.l1CrossDomainMessenger()), address(l1CrossDomainMessenger)); + } + + /// @dev Tests that `messageNonce` can be decoded correctly. + function test_messageVersion_succeeds() external { + (, uint16 version) = Encoding.decodeVersionedNonce(l2CrossDomainMessenger.messageNonce()); + assertEq(version, l2CrossDomainMessenger.MESSAGE_VERSION()); + } + + /// @dev Tests that `sendMessage` executes successfully. + function test_sendMessage_succeeds() external { + bytes memory xDomainCallData = + Encoding.encodeCrossDomainMessage(l2CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff"); + vm.expectCall( + address(l2ToL1MessagePasser), + abi.encodeWithSelector( + L2ToL1MessagePasser.initiateWithdrawal.selector, + address(l1CrossDomainMessenger), + l2CrossDomainMessenger.baseGas(hex"ff", 100), + xDomainCallData + ) + ); + + // MessagePassed event + vm.expectEmit(true, true, true, true); + emit MessagePassed( + l2ToL1MessagePasser.messageNonce(), + address(l2CrossDomainMessenger), + address(l1CrossDomainMessenger), + 0, + l2CrossDomainMessenger.baseGas(hex"ff", 100), + xDomainCallData, + Hashing.hashWithdrawal( + Types.WithdrawalTransaction({ + nonce: l2ToL1MessagePasser.messageNonce(), + sender: address(l2CrossDomainMessenger), + target: address(l1CrossDomainMessenger), + value: 0, + gasLimit: l2CrossDomainMessenger.baseGas(hex"ff", 100), + data: xDomainCallData + }) + ) + ); + + vm.prank(alice); + l2CrossDomainMessenger.sendMessage(recipient, hex"ff", uint32(100)); + } + + /// @dev Tests that `sendMessage` can be called twice and that + /// the nonce increments correctly. + function test_sendMessage_twice_succeeds() external { + uint256 nonce = l2CrossDomainMessenger.messageNonce(); + l2CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000)); + l2CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000)); + // the nonce increments for each message sent + assertEq(nonce + 2, l2CrossDomainMessenger.messageNonce()); + } + + /// @dev Tests that `sendMessage` reverts if the recipient is the zero address. + function test_xDomainSender_senderNotSet_reverts() external { + vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); + l2CrossDomainMessenger.xDomainMessageSender(); + } + + /// @dev Tests that `sendMessage` reverts if the message version is not supported. + function test_relayMessage_v2_reverts() external { + address target = address(0xabcd); + address sender = address(l1CrossDomainMessenger); + address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); + + // Expect a revert. + vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time"); + + // Try to relay a v2 message. + vm.prank(caller); + l2CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce(0, 2), // nonce + sender, + target, + 0, // value + 0, + hex"1111" + ); + } + + /// @dev Tests that `relayMessage` executes successfully. + function test_relayMessage_succeeds() external { + address target = address(0xabcd); + address sender = address(l1CrossDomainMessenger); + address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); + + vm.expectCall(target, hex"1111"); + + vm.prank(caller); + + vm.expectEmit(true, true, true, true); + + bytes32 hash = + Hashing.hashCrossDomainMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, hex"1111"); + + emit RelayedMessage(hash); + + l2CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce(0, 1), // nonce + sender, + target, + 0, // value + 0, + hex"1111" + ); + + // the message hash is in the successfulMessages mapping + assert(l2CrossDomainMessenger.successfulMessages(hash)); + // it is not in the received messages mapping + assertEq(l2CrossDomainMessenger.failedMessages(hash), false); + } + + /// @dev Tests that `relayMessage` reverts if attempting to relay + /// a message sent to an L1 system contract. + function test_relayMessage_toSystemContract_reverts() external { + address target = address(l2ToL1MessagePasser); + address sender = address(l1CrossDomainMessenger); + address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); + bytes memory message = hex"1111"; + + vm.prank(caller); + vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); + l1CrossDomainMessenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, message); + } + + /// @dev Tests that `relayMessage` correctly resets the `xDomainMessageSender` + /// to the original value after a message is relayed. + function test_xDomainMessageSender_reset_succeeds() external { + vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); + l2CrossDomainMessenger.xDomainMessageSender(); + + address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); + vm.prank(caller); + l2CrossDomainMessenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), address(0), address(0), 0, 0, hex""); + + vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); + l2CrossDomainMessenger.xDomainMessageSender(); + } + + /// @dev Tests that `relayMessage` is able to send a successful call + /// to the target contract after the first message fails and ETH + /// gets stuck, but the second message succeeds. + function test_relayMessage_retry_succeeds() external { + address target = address(0xabcd); + address sender = address(l1CrossDomainMessenger); + address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); + uint256 value = 100; + + bytes32 hash = + Hashing.hashCrossDomainMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, value, 0, hex"1111"); + + vm.etch(target, address(new Reverter()).code); + vm.deal(address(caller), value); + vm.prank(caller); + l2CrossDomainMessenger.relayMessage{ value: value }( + Encoding.encodeVersionedNonce(0, 1), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + + assertEq(address(l2CrossDomainMessenger).balance, value); + assertEq(address(target).balance, 0); + assertEq(l2CrossDomainMessenger.successfulMessages(hash), false); + assertEq(l2CrossDomainMessenger.failedMessages(hash), true); + + vm.expectEmit(true, true, true, true); + + emit RelayedMessage(hash); + + vm.etch(target, address(0).code); + vm.prank(address(sender)); + l2CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce(0, 1), // nonce + sender, + target, + value, + 0, + hex"1111" + ); + + assertEq(address(l2CrossDomainMessenger).balance, 0); + assertEq(address(target).balance, value); + assertEq(l2CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l2CrossDomainMessenger.failedMessages(hash), true); + } +} diff --git a/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol new file mode 100644 index 000000000000..af79149b2a90 --- /dev/null +++ b/packages/contracts-bedrock/test/L2/L2ERC721Bridge.t.sol @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { console } from "forge-std/console.sol"; + +// Testing utilities +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; + +// Target contract dependencies +import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; + +// Target contract +import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; + +contract TestERC721 is ERC721 { + constructor() ERC721("Test", "TST") { } + + function mint(address to, uint256 tokenId) public { + _mint(to, tokenId); + } +} + +contract TestMintableERC721 is OptimismMintableERC721 { + constructor( + address _bridge, + address _remoteToken + ) + OptimismMintableERC721(_bridge, 1, _remoteToken, "Test", "TST") + { } + + function mint(address to, uint256 tokenId) public { + _mint(to, tokenId); + } +} + +contract L2ERC721Bridge_Test is Bridge_Initializer { + TestMintableERC721 internal localToken; + TestERC721 internal remoteToken; + uint256 internal constant tokenId = 1; + + event ERC721BridgeInitiated( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 tokenId, + bytes extraData + ); + + event ERC721BridgeFinalized( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 tokenId, + bytes extraData + ); + + /// @dev Sets up the test suite. + function setUp() public override { + super.setUp(); + + remoteToken = new TestERC721(); + localToken = new TestMintableERC721(address(l2ERC721Bridge), address(remoteToken)); + + // Mint alice a token. + localToken.mint(alice, tokenId); + + // Approve the bridge to transfer the token. + vm.prank(alice); + localToken.approve(address(l2ERC721Bridge), tokenId); + } + + /// @dev Tests that the constructor sets the correct variables. + function test_constructor_succeeds() public { + assertEq(address(l2ERC721Bridge.MESSENGER()), address(l2CrossDomainMessenger)); + assertEq(address(l2ERC721Bridge.OTHER_BRIDGE()), address(l1ERC721Bridge)); + assertEq(address(l2ERC721Bridge.messenger()), address(l2CrossDomainMessenger)); + assertEq(address(l2ERC721Bridge.otherBridge()), address(l1ERC721Bridge)); + } + + /// @dev Ensures that the L2ERC721Bridge is always not paused. The pausability + /// happens on L1 and not L2. + function test_paused_succeeds() external { + assertFalse(l2ERC721Bridge.paused()); + } + + /// @dev Tests that `bridgeERC721` correctly bridges a token and + /// burns it on the origin chain. + function test_bridgeERC721_succeeds() public { + // Expect a call to the messenger. + vm.expectCall( + address(l2CrossDomainMessenger), + abi.encodeCall( + l2CrossDomainMessenger.sendMessage, + ( + address(l1ERC721Bridge), + abi.encodeCall( + L2ERC721Bridge.finalizeBridgeERC721, + (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678") + ), + 1234 + ) + ) + ); + + // Expect an event to be emitted. + vm.expectEmit(true, true, true, true); + emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + + // Bridge the token. + vm.prank(alice); + l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + + // Token is burned. + vm.expectRevert("ERC721: invalid token ID"); + localToken.ownerOf(tokenId); + } + + /// @dev Tests that `bridgeERC721` reverts if the owner is not an EOA. + function test_bridgeERC721_fromContract_reverts() external { + // Bridge the token. + vm.etch(alice, hex"01"); + vm.prank(alice); + vm.expectRevert("ERC721Bridge: account is not externally owned"); + l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that `bridgeERC721` reverts if the local token is the zero address. + function test_bridgeERC721_localTokenZeroAddress_reverts() external { + // Bridge the token. + vm.prank(alice); + vm.expectRevert(bytes("")); + l2ERC721Bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that `bridgeERC721` reverts if the remote token is the zero address. + function test_bridgeERC721_remoteTokenZeroAddress_reverts() external { + // Bridge the token. + vm.prank(alice); + vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)"); + l2ERC721Bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that `bridgeERC721` reverts if the caller is not the token owner. + function test_bridgeERC721_wrongOwner_reverts() external { + // Bridge the token. + vm.prank(bob); + vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner"); + l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that `bridgeERC721To` correctly bridges a token + /// and burns it on the origin chain. + function test_bridgeERC721To_succeeds() external { + // Expect a call to the messenger. + vm.expectCall( + address(l2CrossDomainMessenger), + abi.encodeCall( + l2CrossDomainMessenger.sendMessage, + ( + address(l1ERC721Bridge), + abi.encodeCall( + L1ERC721Bridge.finalizeBridgeERC721, + (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") + ), + 1234 + ) + ) + ); + + // Expect an event to be emitted. + vm.expectEmit(true, true, true, true); + emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, bob, tokenId, hex"5678"); + + // Bridge the token. + vm.prank(alice); + l2ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); + + // Token is burned. + vm.expectRevert("ERC721: invalid token ID"); + localToken.ownerOf(tokenId); + } + + /// @dev Tests that `bridgeERC721To` reverts if the local token is the zero address. + function test_bridgeERC721To_localTokenZeroAddress_reverts() external { + // Bridge the token. + vm.prank(alice); + vm.expectRevert(bytes("")); + l2ERC721Bridge.bridgeERC721To(address(0), address(l1ERC721Bridge), bob, tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that `bridgeERC721To` reverts if the remote token is the zero address. + function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external { + // Bridge the token. + vm.prank(alice); + vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)"); + l2ERC721Bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that `bridgeERC721To` reverts if the caller is not the token owner. + function test_bridgeERC721To_wrongOwner_reverts() external { + // Bridge the token. + vm.prank(bob); + vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner"); + l2ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); + + // Token is not locked in the bridge. + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that `finalizeBridgeERC721` correctly finalizes a bridged token. + function test_finalizeBridgeERC721_succeeds() external { + // Bridge the token. + vm.prank(alice); + l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + + // Expect an event to be emitted. + vm.expectEmit(true, true, true, true); + emit ERC721BridgeFinalized(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + + // Finalize a withdrawal. + vm.mockCall( + address(l2CrossDomainMessenger), + abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(l1ERC721Bridge) + ); + vm.prank(address(l2CrossDomainMessenger)); + l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + + // Token is not locked in the bridge. + assertEq(localToken.ownerOf(tokenId), alice); + } + + /// @dev Tests that `finalizeBridgeERC721` reverts if the token is not compliant + /// with the `IOptimismMintableERC721` interface. + function test_finalizeBridgeERC721_interfaceNotCompliant_reverts() external { + // Create a non-compliant token + NonCompliantERC721 nonCompliantToken = new NonCompliantERC721(alice); + + // Bridge the non-compliant token. + vm.prank(alice); + l2ERC721Bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex"5678"); + + // Attempt to finalize the withdrawal. Should revert because the token does not claim + // to be compliant with the `IOptimismMintableERC721` interface. + vm.mockCall( + address(l2CrossDomainMessenger), + abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(l1ERC721Bridge) + ); + vm.prank(address(l2CrossDomainMessenger)); + vm.expectRevert("L2ERC721Bridge: local token interface is not compliant"); + l2ERC721Bridge.finalizeBridgeERC721( + address(address(nonCompliantToken)), address(address(0x01)), alice, alice, tokenId, hex"5678" + ); + } + + /// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge. + function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external { + // Finalize a withdrawal. + vm.prank(alice); + vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); + l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + } + + /// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge. + function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { + // Finalize a withdrawal. + vm.mockCall( + address(l2CrossDomainMessenger), + abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(alice) + ); + vm.prank(address(l2CrossDomainMessenger)); + vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); + l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + } + + /// @dev Tests that `finalizeBridgeERC721` reverts when the local token is the + /// address of the bridge itself. + function test_finalizeBridgeERC721_selfToken_reverts() external { + // Finalize a withdrawal. + vm.mockCall( + address(l2CrossDomainMessenger), + abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1ERC721Bridge)) + ); + vm.prank(address(l2CrossDomainMessenger)); + vm.expectRevert("L2ERC721Bridge: local token cannot be self"); + l2ERC721Bridge.finalizeBridgeERC721( + address(l2ERC721Bridge), address(remoteToken), alice, alice, tokenId, hex"5678" + ); + } + + /// @dev Tests that `finalizeBridgeERC721` reverts when already finalized. + function test_finalizeBridgeERC721_alreadyExists_reverts() external { + // Finalize a withdrawal. + vm.mockCall( + address(l2CrossDomainMessenger), + abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1ERC721Bridge)) + ); + vm.prank(address(l2CrossDomainMessenger)); + vm.expectRevert("ERC721: token already minted"); + l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + } +} + +/// @dev A non-compliant ERC721 token that does not implement the full ERC721 interface. +/// This is used to test that the bridge will revert if the token does not claim to +/// support the ERC721 interface. +contract NonCompliantERC721 { + address internal immutable owner; + + constructor(address _owner) { + owner = _owner; + } + + function ownerOf(uint256) external view returns (address) { + return owner; + } + + function remoteToken() external pure returns (address) { + return address(0x01); + } + + function burn(address, uint256) external { + // Do nothing. + } + + function supportsInterface(bytes4) external pure returns (bool) { + return false; + } +} diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol new file mode 100644 index 000000000000..db6560dafecb --- /dev/null +++ b/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol @@ -0,0 +1,532 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Target contract is imported by the `Bridge_Initializer` +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; +import { stdStorage, StdStorage } from "forge-std/Test.sol"; +import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +// Libraries +import { Hashing } from "src/libraries/Hashing.sol"; +import { Types } from "src/libraries/Types.sol"; + +// Target contract dependencies +import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; +import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; + +contract L2StandardBridge_Test is Bridge_Initializer { + using stdStorage for StdStorage; + + /// @dev Test that the bridge's constructor sets the correct values. + function test_constructor_succeeds() external { + L2StandardBridge impl = + L2StandardBridge(payable(EIP1967Helper.getImplementation(deploy.mustGetAddress("L2StandardBridge")))); + assertEq(address(impl.MESSENGER()), address(0)); + assertEq(address(impl.messenger()), address(0)); + assertEq(address(impl.OTHER_BRIDGE()), address(0)); + assertEq(address(impl.otherBridge()), address(0)); + } + + /// @dev Tests that the bridge is initialized correctly. + function test_initialize_succeeds() external { + assertEq(address(l2StandardBridge.MESSENGER()), address(l2CrossDomainMessenger)); + assertEq(address(l2StandardBridge.messenger()), address(l2CrossDomainMessenger)); + assertEq(l1StandardBridge.l2TokenBridge(), address(l2StandardBridge)); + assertEq(address(l2StandardBridge.OTHER_BRIDGE()), address(l1StandardBridge)); + assertEq(address(l2StandardBridge.otherBridge()), address(l1StandardBridge)); + } + + /// @dev Ensures that the L2StandardBridge is always not paused. The pausability + /// happens on L1 and not L2. + function test_paused_succeeds() external { + assertFalse(l2StandardBridge.paused()); + } + + /// @dev Tests that the bridge receives ETH and successfully initiates a withdrawal. + function test_receive_succeeds() external { + assertEq(address(l2ToL1MessagePasser).balance, 0); + uint256 nonce = l2CrossDomainMessenger.messageNonce(); + + bytes memory message = + abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""); + uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 200_000); + bytes memory withdrawalData = abi.encodeWithSelector( + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l2StandardBridge), + address(l1StandardBridge), + 100, + 200_000, + message + ); + bytes32 withdrawalHash = Hashing.hashWithdrawal( + Types.WithdrawalTransaction({ + nonce: nonce, + sender: address(l2CrossDomainMessenger), + target: address(l1CrossDomainMessenger), + value: 100, + gasLimit: baseGas, + data: withdrawalData + }) + ); + + vm.expectEmit(true, true, true, true); + emit WithdrawalInitiated(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex""); + + vm.expectEmit(true, true, true, true); + emit ETHBridgeInitiated(alice, alice, 100, hex""); + + // L2ToL1MessagePasser will emit a MessagePassed event + vm.expectEmit(true, true, true, true, address(l2ToL1MessagePasser)); + emit MessagePassed( + nonce, + address(l2CrossDomainMessenger), + address(l1CrossDomainMessenger), + 100, + baseGas, + withdrawalData, + withdrawalHash + ); + + // SentMessage event emitted by the CrossDomainMessenger + vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger)); + emit SentMessage(address(l1StandardBridge), address(l2StandardBridge), message, nonce, 200_000); + + // SentMessageExtension1 event emitted by the CrossDomainMessenger + vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger)); + emit SentMessageExtension1(address(l2StandardBridge), 100); + + vm.expectCall( + address(l2CrossDomainMessenger), + abi.encodeWithSelector( + CrossDomainMessenger.sendMessage.selector, + address(l1StandardBridge), + message, + 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT + ) + ); + + vm.expectCall( + Predeploys.L2_TO_L1_MESSAGE_PASSER, + abi.encodeWithSelector( + L2ToL1MessagePasser.initiateWithdrawal.selector, + address(l1CrossDomainMessenger), + baseGas, + withdrawalData + ) + ); + + vm.prank(alice, alice); + (bool success,) = address(l2StandardBridge).call{ value: 100 }(hex""); + assertEq(success, true); + assertEq(address(l2ToL1MessagePasser).balance, 100); + } + + /// @dev Tests that `withdraw` reverts if the amount is not equal to the value sent. + function test_withdraw_insufficientValue_reverts() external { + assertEq(address(l2ToL1MessagePasser).balance, 0); + + vm.expectRevert("StandardBridge: bridging ETH must include sufficient ETH value"); + vm.prank(alice, alice); + l2StandardBridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex""); + } + + /// @dev Tests that the legacy `withdraw` interface on the L2StandardBridge + /// successfully initiates a withdrawal. + function test_withdraw_ether_succeeds() external { + assertTrue(alice.balance >= 100); + assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0); + + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); + emit WithdrawalInitiated({ + l1Token: address(0), + l2Token: Predeploys.LEGACY_ERC20_ETH, + from: alice, + to: alice, + amount: 100, + data: hex"" + }); + + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); + emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex"" }); + + vm.prank(alice, alice); + l2StandardBridge.withdraw{ value: 100 }({ + _l2Token: Predeploys.LEGACY_ERC20_ETH, + _amount: 100, + _minGasLimit: 1000, + _extraData: hex"" + }); + + assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 100); + } +} + +contract PreBridgeERC20 is Bridge_Initializer { + /// @dev Sets up expected calls and emits for a successful ERC20 withdrawal. + function _preBridgeERC20(bool _isLegacy, address _l2Token) internal { + // Alice has 100 L2Token + deal(_l2Token, alice, 100, true); + assertEq(ERC20(_l2Token).balanceOf(alice), 100); + uint256 nonce = l2CrossDomainMessenger.messageNonce(); + bytes memory message = abi.encodeWithSelector( + StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, alice, 100, hex"" + ); + uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 1000); + bytes memory withdrawalData = abi.encodeWithSelector( + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l2StandardBridge), + address(l1StandardBridge), + 0, + 1000, + message + ); + bytes32 withdrawalHash = Hashing.hashWithdrawal( + Types.WithdrawalTransaction({ + nonce: nonce, + sender: address(l2CrossDomainMessenger), + target: address(l1CrossDomainMessenger), + value: 0, + gasLimit: baseGas, + data: withdrawalData + }) + ); + + if (_isLegacy) { + vm.expectCall( + address(l2StandardBridge), + abi.encodeWithSelector(l2StandardBridge.withdraw.selector, _l2Token, 100, 1000, hex"") + ); + } else { + vm.expectCall( + address(l2StandardBridge), + abi.encodeWithSelector( + l2StandardBridge.bridgeERC20.selector, _l2Token, address(L1Token), 100, 1000, hex"" + ) + ); + } + + vm.expectCall( + address(l2CrossDomainMessenger), + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 1000) + ); + + vm.expectCall( + Predeploys.L2_TO_L1_MESSAGE_PASSER, + abi.encodeWithSelector( + L2ToL1MessagePasser.initiateWithdrawal.selector, + address(l1CrossDomainMessenger), + baseGas, + withdrawalData + ) + ); + + // The l2StandardBridge should burn the tokens + vm.expectCall(_l2Token, abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)); + + vm.expectEmit(true, true, true, true); + emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex""); + + vm.expectEmit(true, true, true, true); + emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, alice, 100, hex""); + + vm.expectEmit(true, true, true, true); + emit MessagePassed( + nonce, + address(l2CrossDomainMessenger), + address(l1CrossDomainMessenger), + 0, + baseGas, + withdrawalData, + withdrawalHash + ); + + // SentMessage event emitted by the CrossDomainMessenger + vm.expectEmit(true, true, true, true); + emit SentMessage(address(l1StandardBridge), address(l2StandardBridge), message, nonce, 1000); + + // SentMessageExtension1 event emitted by the CrossDomainMessenger + vm.expectEmit(true, true, true, true); + emit SentMessageExtension1(address(l2StandardBridge), 0); + + vm.prank(alice, alice); + } +} + +contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 { + // withdraw + // - token is burned + // - emits WithdrawalInitiated + // - calls Withdrawer.initiateWithdrawal + function test_withdraw_withdrawingERC20_succeeds() external { + _preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) }); + l2StandardBridge.withdraw(address(L2Token), 100, 1000, hex""); + + assertEq(L2Token.balanceOf(alice), 0); + } + + // BridgeERC20 + // - token is burned + // - emits WithdrawalInitiated + // - calls Withdrawer.initiateWithdrawal + function test_bridgeERC20_succeeds() external { + _preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) }); + l2StandardBridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex""); + + assertEq(L2Token.balanceOf(alice), 0); + } + + function test_withdrawLegacyERC20_succeeds() external { + _preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) }); + l2StandardBridge.withdraw(address(LegacyL2Token), 100, 1000, hex""); + + assertEq(L2Token.balanceOf(alice), 0); + } + + function test_bridgeLegacyERC20_succeeds() external { + _preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) }); + l2StandardBridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex""); + + assertEq(L2Token.balanceOf(alice), 0); + } + + function test_withdraw_notEOA_reverts() external { + // This contract has 100 L2Token + deal(address(L2Token), address(this), 100, true); + + vm.expectRevert("StandardBridge: function can only be called from an EOA"); + l2StandardBridge.withdraw(address(L2Token), 100, 1000, hex""); + } +} + +contract PreBridgeERC20To is Bridge_Initializer { + // withdrawTo and BridgeERC20To should behave the same when transferring ERC20 tokens + // so they should share the same setup and expectEmit calls + function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal { + deal(_l2Token, alice, 100, true); + assertEq(ERC20(L2Token).balanceOf(alice), 100); + uint256 nonce = l2CrossDomainMessenger.messageNonce(); + bytes memory message = abi.encodeWithSelector( + StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, bob, 100, hex"" + ); + uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 1000); + bytes memory withdrawalData = abi.encodeWithSelector( + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l2StandardBridge), + address(l1StandardBridge), + 0, + 1000, + message + ); + bytes32 withdrawalHash = Hashing.hashWithdrawal( + Types.WithdrawalTransaction({ + nonce: nonce, + sender: address(l2CrossDomainMessenger), + target: address(l1CrossDomainMessenger), + value: 0, + gasLimit: baseGas, + data: withdrawalData + }) + ); + + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); + emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex""); + + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); + emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex""); + + vm.expectEmit(true, true, true, true, address(l2ToL1MessagePasser)); + emit MessagePassed( + nonce, + address(l2CrossDomainMessenger), + address(l1CrossDomainMessenger), + 0, + baseGas, + withdrawalData, + withdrawalHash + ); + + // SentMessage event emitted by the CrossDomainMessenger + vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger)); + emit SentMessage(address(l1StandardBridge), address(l2StandardBridge), message, nonce, 1000); + + // SentMessageExtension1 event emitted by the CrossDomainMessenger + vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger)); + emit SentMessageExtension1(address(l2StandardBridge), 0); + + if (_isLegacy) { + vm.expectCall( + address(l2StandardBridge), + abi.encodeWithSelector(l2StandardBridge.withdrawTo.selector, _l2Token, bob, 100, 1000, hex"") + ); + } else { + vm.expectCall( + address(l2StandardBridge), + abi.encodeWithSelector( + l2StandardBridge.bridgeERC20To.selector, _l2Token, address(L1Token), bob, 100, 1000, hex"" + ) + ); + } + + vm.expectCall( + address(l2CrossDomainMessenger), + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 1000) + ); + + vm.expectCall( + Predeploys.L2_TO_L1_MESSAGE_PASSER, + abi.encodeWithSelector( + L2ToL1MessagePasser.initiateWithdrawal.selector, + address(l1CrossDomainMessenger), + baseGas, + withdrawalData + ) + ); + + // The l2StandardBridge should burn the tokens + vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)); + + vm.prank(alice, alice); + } +} + +contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To { + /// @dev Tests that `withdrawTo` burns the tokens, emits `WithdrawalInitiated`, + /// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`. + function test_withdrawTo_withdrawingERC20_succeeds() external { + _preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) }); + l2StandardBridge.withdrawTo(address(L2Token), bob, 100, 1000, hex""); + + assertEq(L2Token.balanceOf(alice), 0); + } + + /// @dev Tests that `bridgeERC20To` burns the tokens, emits `WithdrawalInitiated`, + /// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`. + function test_bridgeERC20To_succeeds() external { + _preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) }); + l2StandardBridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex""); + assertEq(L2Token.balanceOf(alice), 0); + } +} + +contract L2StandardBridge_Bridge_Test is Bridge_Initializer { + /// @dev Tests that `finalizeDeposit` succeeds. It should: + /// - only be callable by the l1TokenBridge + /// - emit `DepositFinalized` if the token pair is supported + /// - call `Withdrawer.initiateWithdrawal` if the token pair is not supported + function test_finalizeDeposit_depositingERC20_succeeds() external { + vm.mockCall( + address(l2StandardBridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) + ); + + vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)); + + // Should emit both the bedrock and legacy events + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); + emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); + + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); + emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex""); + + vm.prank(address(l2CrossDomainMessenger)); + l2StandardBridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex""); + } + + /// @dev Tests that `finalizeDeposit` succeeds when depositing ETH. + function test_finalizeDeposit_depositingETH_succeeds() external { + vm.mockCall( + address(l2StandardBridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) + ); + + // Should emit both the bedrock and legacy events + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); + emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); + + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); + emit ERC20BridgeFinalized( + address(L2Token), // localToken + address(L1Token), // remoteToken + alice, + alice, + 100, + hex"" + ); + + vm.prank(address(l2CrossDomainMessenger)); + l2StandardBridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex""); + } + + /// @dev Tests that `finalizeDeposit` reverts if the amounts do not match. + function test_finalizeBridgeETH_incorrectValue_reverts() external { + vm.mockCall( + address(l2StandardBridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) + ); + vm.deal(address(l2CrossDomainMessenger), 100); + vm.prank(address(l2CrossDomainMessenger)); + vm.expectRevert("StandardBridge: amount sent does not match amount required"); + l2StandardBridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex""); + } + + /// @dev Tests that `finalizeDeposit` reverts if the receipient is the other bridge. + function test_finalizeBridgeETH_sendToSelf_reverts() external { + vm.mockCall( + address(l2StandardBridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) + ); + vm.deal(address(l2CrossDomainMessenger), 100); + vm.prank(address(l2CrossDomainMessenger)); + vm.expectRevert("StandardBridge: cannot send to self"); + l2StandardBridge.finalizeBridgeETH{ value: 100 }(alice, address(l2StandardBridge), 100, hex""); + } + + /// @dev Tests that `finalizeDeposit` reverts if the receipient is the messenger. + function test_finalizeBridgeETH_sendToMessenger_reverts() external { + vm.mockCall( + address(l2StandardBridge.messenger()), + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) + ); + vm.deal(address(l2CrossDomainMessenger), 100); + vm.prank(address(l2CrossDomainMessenger)); + vm.expectRevert("StandardBridge: cannot send to messenger"); + l2StandardBridge.finalizeBridgeETH{ value: 100 }(alice, address(l2CrossDomainMessenger), 100, hex""); + } +} + +contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { + /// @dev Tests that `finalizeBridgeETH` succeeds. + function test_finalizeBridgeETH_succeeds() external { + address messenger = address(l2StandardBridge.messenger()); + vm.mockCall( + messenger, + abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) + ); + vm.deal(messenger, 100); + vm.prank(messenger); + + vm.expectEmit(true, true, true, true); + emit DepositFinalized(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex""); + + vm.expectEmit(true, true, true, true); + emit ETHBridgeFinalized(alice, alice, 100, hex""); + + l2StandardBridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); + } +} diff --git a/packages/contracts-bedrock/test/L2/L2ToL1MessagePasser.t.sol b/packages/contracts-bedrock/test/L2/L2ToL1MessagePasser.t.sol new file mode 100644 index 000000000000..0c2c6c8b869a --- /dev/null +++ b/packages/contracts-bedrock/test/L2/L2ToL1MessagePasser.t.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; + +// Libraries +import { Types } from "src/libraries/Types.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; + +contract L2ToL1MessagePasserTest is CommonTest { + /// @dev Tests that `initiateWithdrawal` succeeds and correctly sets the state + /// of the message passer for the withdrawal hash. + function testFuzz_initiateWithdrawal_succeeds( + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) + external + { + uint256 nonce = l2ToL1MessagePasser.messageNonce(); + + bytes32 withdrawalHash = Hashing.hashWithdrawal( + Types.WithdrawalTransaction({ + nonce: nonce, + sender: _sender, + target: _target, + value: _value, + gasLimit: _gasLimit, + data: _data + }) + ); + + vm.expectEmit(address(l2ToL1MessagePasser)); + emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash); + + vm.deal(_sender, _value); + vm.prank(_sender); + l2ToL1MessagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data); + + assertEq(l2ToL1MessagePasser.sentMessages(withdrawalHash), true); + + bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0))); + + assertEq(vm.load(address(l2ToL1MessagePasser), slot), bytes32(uint256(1))); + } + + /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed + /// log when called by a contract. + function testFuzz_initiateWithdrawal_fromContract_succeeds( + address _target, + uint256 _gasLimit, + uint256 _value, + bytes memory _data + ) + external + { + bytes32 withdrawalHash = Hashing.hashWithdrawal( + Types.WithdrawalTransaction({ + nonce: l2ToL1MessagePasser.messageNonce(), + sender: address(this), + target: _target, + value: _value, + gasLimit: _gasLimit, + data: _data + }) + ); + + vm.expectEmit(address(l2ToL1MessagePasser)); + emit MessagePassed( + l2ToL1MessagePasser.messageNonce(), address(this), _target, _value, _gasLimit, _data, withdrawalHash + ); + + vm.deal(address(this), _value); + l2ToL1MessagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data); + } + + /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed + /// log when called by an EOA. + function testFuzz_initiateWithdrawal_fromEOA_succeeds( + uint256 _gasLimit, + address _target, + uint256 _value, + bytes memory _data + ) + external + { + uint256 nonce = l2ToL1MessagePasser.messageNonce(); + + // EOA emulation + vm.prank(alice, alice); + vm.deal(alice, _value); + bytes32 withdrawalHash = + Hashing.hashWithdrawal(Types.WithdrawalTransaction(nonce, alice, _target, _value, _gasLimit, _data)); + + vm.expectEmit(address(l2ToL1MessagePasser)); + emit MessagePassed(nonce, alice, _target, _value, _gasLimit, _data, withdrawalHash); + + l2ToL1MessagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); + + // the sent messages mapping is filled + assertEq(l2ToL1MessagePasser.sentMessages(withdrawalHash), true); + // the nonce increments + assertEq(nonce + 1, l2ToL1MessagePasser.messageNonce()); + } + + /// @dev Tests that `burn` succeeds and destroys the ETH held in the contract. + function testFuzz_burn_succeeds(uint256 _value, address _target, uint256 _gasLimit, bytes memory _data) external { + vm.deal(address(this), _value); + + l2ToL1MessagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); + + assertEq(address(l2ToL1MessagePasser).balance, _value); + emit WithdrawerBalanceBurnt(_value); + l2ToL1MessagePasser.burn(); + + // The Withdrawer should have no balance + assertEq(address(l2ToL1MessagePasser).balance, 0); + } +} diff --git a/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol b/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol new file mode 100644 index 000000000000..f0956064c4b8 --- /dev/null +++ b/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; +import { Reverter } from "test/mocks/Callers.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Target contract dependencies +import { FeeVault } from "src/universal/FeeVault.sol"; + +// Target contract +import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; + +contract SequencerFeeVault_Test is CommonTest { + address recipient; + + /// @dev Sets up the test suite. + function setUp() public override { + super.setUp(); + recipient = deploy.cfg().sequencerFeeVaultRecipient(); + } + + /// @dev Tests that the minimum withdrawal amount is correct. + function test_minWithdrawalAmount_succeeds() external { + assertEq(sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount()); + } + + /// @dev Tests that the l1 fee wallet is correct. + function test_constructor_succeeds() external { + assertEq(sequencerFeeVault.l1FeeWallet(), recipient); + } + + /// @dev Tests that the fee vault is able to receive ETH. + function test_receive_succeeds() external { + uint256 balance = address(sequencerFeeVault).balance; + + vm.prank(alice); + (bool success,) = address(sequencerFeeVault).call{ value: 100 }(hex""); + + assertEq(success, true); + assertEq(address(sequencerFeeVault).balance, balance + 100); + } + + /// @dev Tests that `withdraw` reverts if the balance is less than the minimum + /// withdrawal amount. + function test_withdraw_notEnough_reverts() external { + assert(address(sequencerFeeVault).balance < sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT()); + + vm.expectRevert("FeeVault: withdrawal amount must be greater than minimum withdrawal amount"); + sequencerFeeVault.withdraw(); + } + + /// @dev Tests that `withdraw` successfully initiates a withdrawal to L1. + function test_withdraw_toL1_succeeds() external { + uint256 amount = sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT() + 1; + vm.deal(address(sequencerFeeVault), amount); + + // No ether has been withdrawn yet + assertEq(sequencerFeeVault.totalProcessed(), 0); + + vm.expectEmit(address(Predeploys.SEQUENCER_FEE_WALLET)); + emit Withdrawal(address(sequencerFeeVault).balance, sequencerFeeVault.RECIPIENT(), address(this)); + vm.expectEmit(address(Predeploys.SEQUENCER_FEE_WALLET)); + emit Withdrawal( + address(sequencerFeeVault).balance, + sequencerFeeVault.RECIPIENT(), + address(this), + FeeVault.WithdrawalNetwork.L1 + ); + + // The entire vault's balance is withdrawn + vm.expectCall( + Predeploys.L2_STANDARD_BRIDGE, + address(sequencerFeeVault).balance, + abi.encodeWithSelector( + StandardBridge.bridgeETHTo.selector, sequencerFeeVault.l1FeeWallet(), 35_000, bytes("") + ) + ); + + sequencerFeeVault.withdraw(); + + // The withdrawal was successful + assertEq(sequencerFeeVault.totalProcessed(), amount); + assertEq(address(sequencerFeeVault).balance, 0); + assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, amount); + } +} + +contract SequencerFeeVault_L2Withdrawal_Test is CommonTest { + /// @dev a cache for the config fee recipient + address recipient; + + /// @dev Sets up the test suite. + function setUp() public override { + super.setUp(); + + // Alter the deployment to use WithdrawalNetwork.L2 + vm.etch( + EIP1967Helper.getImplementation(Predeploys.SEQUENCER_FEE_WALLET), + address( + new SequencerFeeVault( + deploy.cfg().sequencerFeeVaultRecipient(), + deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount(), + FeeVault.WithdrawalNetwork.L2 + ) + ).code + ); + + recipient = deploy.cfg().sequencerFeeVaultRecipient(); + } + + /// @dev Tests that `withdraw` successfully initiates a withdrawal to L2. + function test_withdraw_toL2_succeeds() external { + uint256 amount = sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT() + 1; + vm.deal(address(sequencerFeeVault), amount); + + // No ether has been withdrawn yet + assertEq(sequencerFeeVault.totalProcessed(), 0); + + vm.expectEmit(address(Predeploys.SEQUENCER_FEE_WALLET)); + emit Withdrawal(address(sequencerFeeVault).balance, sequencerFeeVault.RECIPIENT(), address(this)); + vm.expectEmit(address(Predeploys.SEQUENCER_FEE_WALLET)); + emit Withdrawal( + address(sequencerFeeVault).balance, + sequencerFeeVault.RECIPIENT(), + address(this), + FeeVault.WithdrawalNetwork.L2 + ); + + // The entire vault's balance is withdrawn + vm.expectCall(recipient, address(sequencerFeeVault).balance, bytes("")); + + sequencerFeeVault.withdraw(); + + // The withdrawal was successful + assertEq(sequencerFeeVault.totalProcessed(), amount); + assertEq(address(sequencerFeeVault).balance, 0); + assertEq(recipient.balance, amount); + } + + /// @dev Tests that `withdraw` fails if the Recipient reverts. This also serves to simulate + /// a situation where insufficient gas is provided to the RECIPIENT. + function test_withdraw_toL2recipientReverts_fails() external { + uint256 amount = sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(); + + vm.deal(address(sequencerFeeVault), amount); + // No ether has been withdrawn yet + assertEq(sequencerFeeVault.totalProcessed(), 0); + + // Ensure the RECIPIENT reverts + vm.etch(sequencerFeeVault.RECIPIENT(), type(Reverter).runtimeCode); + + // The entire vault's balance is withdrawn + vm.expectCall(recipient, address(sequencerFeeVault).balance, bytes("")); + vm.expectRevert("FeeVault: failed to send ETH to L2 fee recipient"); + sequencerFeeVault.withdraw(); + assertEq(sequencerFeeVault.totalProcessed(), 0); + } +} diff --git a/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol deleted file mode 100644 index ead28756af6d..000000000000 --- a/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol +++ /dev/null @@ -1,214 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { Messenger_Initializer, Reverter, ConfigurableCaller } from "test/CommonTest.t.sol"; - -// Libraries -import { Hashing } from "src/libraries/Hashing.sol"; -import { Encoding } from "src/libraries/Encoding.sol"; -import { Types } from "src/libraries/Types.sol"; - -// Target contract dependencies -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; - -// Target contract -import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; - -contract L2CrossDomainMessenger_Test is Messenger_Initializer { - /// @dev Receiver address for testing - address recipient = address(0xabbaacdc); - - /// @dev Tests that `messageNonce` can be decoded correctly. - function test_messageVersion_succeeds() external { - (, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce()); - assertEq(version, L2Messenger.MESSAGE_VERSION()); - } - - /// @dev Tests that `sendMessage` executes successfully. - function test_sendMessage_succeeds() external { - bytes memory xDomainCallData = - Encoding.encodeCrossDomainMessage(L2Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff"); - vm.expectCall( - address(messagePasser), - abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, - address(L1Messenger), - L2Messenger.baseGas(hex"ff", 100), - xDomainCallData - ) - ); - - // MessagePassed event - vm.expectEmit(true, true, true, true); - emit MessagePassed( - messagePasser.messageNonce(), - address(L2Messenger), - address(L1Messenger), - 0, - L2Messenger.baseGas(hex"ff", 100), - xDomainCallData, - Hashing.hashWithdrawal( - Types.WithdrawalTransaction({ - nonce: messagePasser.messageNonce(), - sender: address(L2Messenger), - target: address(L1Messenger), - value: 0, - gasLimit: L2Messenger.baseGas(hex"ff", 100), - data: xDomainCallData - }) - ) - ); - - vm.prank(alice); - L2Messenger.sendMessage(recipient, hex"ff", uint32(100)); - } - - /// @dev Tests that `sendMessage` can be called twice and that - /// the nonce increments correctly. - function test_sendMessage_twice_succeeds() external { - uint256 nonce = L2Messenger.messageNonce(); - L2Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); - L2Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); - // the nonce increments for each message sent - assertEq(nonce + 2, L2Messenger.messageNonce()); - } - - /// @dev Tests that `sendMessage` reverts if the recipient is the zero address. - function test_xDomainSender_senderNotSet_reverts() external { - vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L2Messenger.xDomainMessageSender(); - } - - /// @dev Tests that `sendMessage` reverts if the message version is not supported. - function test_relayMessage_v2_reverts() external { - address target = address(0xabcd); - address sender = address(L1Messenger); - address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); - - // Expect a revert. - vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time"); - - // Try to relay a v2 message. - vm.prank(caller); - L2Messenger.relayMessage( - Encoding.encodeVersionedNonce(0, 2), // nonce - sender, - target, - 0, // value - 0, - hex"1111" - ); - } - - /// @dev Tests that `relayMessage` executes successfully. - function test_relayMessage_succeeds() external { - address target = address(0xabcd); - address sender = address(L1Messenger); - address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); - - vm.expectCall(target, hex"1111"); - - vm.prank(caller); - - vm.expectEmit(true, true, true, true); - - bytes32 hash = - Hashing.hashCrossDomainMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, hex"1111"); - - emit RelayedMessage(hash); - - L2Messenger.relayMessage( - Encoding.encodeVersionedNonce(0, 1), // nonce - sender, - target, - 0, // value - 0, - hex"1111" - ); - - // the message hash is in the successfulMessages mapping - assert(L2Messenger.successfulMessages(hash)); - // it is not in the received messages mapping - assertEq(L2Messenger.failedMessages(hash), false); - } - - /// @dev Tests that `relayMessage` reverts if attempting to relay - /// a message sent to an L1 system contract. - function test_relayMessage_toSystemContract_reverts() external { - address target = address(messagePasser); - address sender = address(L1Messenger); - address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); - bytes memory message = hex"1111"; - - vm.prank(caller); - vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); - L1Messenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, message); - } - - /// @dev Tests that `relayMessage` correctly resets the `xDomainMessageSender` - /// to the original value after a message is relayed. - function test_xDomainMessageSender_reset_succeeds() external { - vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L2Messenger.xDomainMessageSender(); - - address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); - vm.prank(caller); - L2Messenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), address(0), address(0), 0, 0, hex""); - - vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L2Messenger.xDomainMessageSender(); - } - - /// @dev Tests that `relayMessage` is able to send a successful call - /// to the target contract after the first message fails and ETH - /// gets stuck, but the second message succeeds. - function test_relayMessage_retry_succeeds() external { - address target = address(0xabcd); - address sender = address(L1Messenger); - address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); - uint256 value = 100; - - bytes32 hash = - Hashing.hashCrossDomainMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, value, 0, hex"1111"); - - vm.etch(target, address(new Reverter()).code); - vm.deal(address(caller), value); - vm.prank(caller); - L2Messenger.relayMessage{ value: value }( - Encoding.encodeVersionedNonce(0, 1), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - - assertEq(address(L2Messenger).balance, value); - assertEq(address(target).balance, 0); - assertEq(L2Messenger.successfulMessages(hash), false); - assertEq(L2Messenger.failedMessages(hash), true); - - vm.expectEmit(true, true, true, true); - - emit RelayedMessage(hash); - - vm.etch(target, address(0).code); - vm.prank(address(sender)); - L2Messenger.relayMessage( - Encoding.encodeVersionedNonce(0, 1), // nonce - sender, - target, - value, - 0, - hex"1111" - ); - - assertEq(address(L2Messenger).balance, 0); - assertEq(address(target).balance, value); - assertEq(L2Messenger.successfulMessages(hash), true); - assertEq(L2Messenger.failedMessages(hash), true); - } -} diff --git a/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol deleted file mode 100644 index 03567f3beae1..000000000000 --- a/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol +++ /dev/null @@ -1,343 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; - -// Target contract dependencies -import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; -import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; - -// Target contract -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; - -contract TestERC721 is ERC721 { - constructor() ERC721("Test", "TST") { } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } -} - -contract TestMintableERC721 is OptimismMintableERC721 { - constructor( - address _bridge, - address _remoteToken - ) - OptimismMintableERC721(_bridge, 1, _remoteToken, "Test", "TST") - { } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } -} - -contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { - TestMintableERC721 internal localToken; - TestERC721 internal remoteToken; - uint256 internal constant tokenId = 1; - - event ERC721BridgeInitiated( - address indexed localToken, - address indexed remoteToken, - address indexed from, - address to, - uint256 tokenId, - bytes extraData - ); - - event ERC721BridgeFinalized( - address indexed localToken, - address indexed remoteToken, - address indexed from, - address to, - uint256 tokenId, - bytes extraData - ); - - /// @dev Sets up the test suite. - function setUp() public override { - super.setUp(); - - remoteToken = new TestERC721(); - localToken = new TestMintableERC721(address(L2NFTBridge), address(remoteToken)); - - // Mint alice a token. - localToken.mint(alice, tokenId); - - // Approve the bridge to transfer the token. - vm.prank(alice); - localToken.approve(address(L2NFTBridge), tokenId); - } - - /// @dev Tests that the constructor sets the correct variables. - function test_constructor_succeeds() public { - assertEq(address(L2NFTBridge.MESSENGER()), address(L2Messenger)); - assertEq(address(L2NFTBridge.OTHER_BRIDGE()), address(L1NFTBridge)); - assertEq(address(L2NFTBridge.messenger()), address(L2Messenger)); - assertEq(address(L2NFTBridge.otherBridge()), address(L1NFTBridge)); - } - - /// @dev Tests that `bridgeERC721` correctly bridges a token and - /// burns it on the origin chain. - function test_bridgeERC721_succeeds() public { - // Expect a call to the messenger. - vm.expectCall( - address(L2Messenger), - abi.encodeCall( - L2Messenger.sendMessage, - ( - address(L1NFTBridge), - abi.encodeCall( - L2ERC721Bridge.finalizeBridgeERC721, - (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678") - ), - 1234 - ) - ) - ); - - // Expect an event to be emitted. - vm.expectEmit(true, true, true, true); - emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - - // Bridge the token. - vm.prank(alice); - L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); - - // Token is burned. - vm.expectRevert("ERC721: invalid token ID"); - localToken.ownerOf(tokenId); - } - - /// @dev Tests that `bridgeERC721` reverts if the owner is not an EOA. - function test_bridgeERC721_fromContract_reverts() external { - // Bridge the token. - vm.etch(alice, hex"01"); - vm.prank(alice); - vm.expectRevert("ERC721Bridge: account is not externally owned"); - L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that `bridgeERC721` reverts if the local token is the zero address. - function test_bridgeERC721_localTokenZeroAddress_reverts() external { - // Bridge the token. - vm.prank(alice); - vm.expectRevert(); - L2NFTBridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that `bridgeERC721` reverts if the remote token is the zero address. - function test_bridgeERC721_remoteTokenZeroAddress_reverts() external { - // Bridge the token. - vm.prank(alice); - vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)"); - L2NFTBridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that `bridgeERC721` reverts if the caller is not the token owner. - function test_bridgeERC721_wrongOwner_reverts() external { - // Bridge the token. - vm.prank(bob); - vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner"); - L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that `bridgeERC721To` correctly bridges a token - /// and burns it on the origin chain. - function test_bridgeERC721To_succeeds() external { - // Expect a call to the messenger. - vm.expectCall( - address(L2Messenger), - abi.encodeCall( - L2Messenger.sendMessage, - ( - address(L1NFTBridge), - abi.encodeCall( - L1ERC721Bridge.finalizeBridgeERC721, - (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") - ), - 1234 - ) - ) - ); - - // Expect an event to be emitted. - vm.expectEmit(true, true, true, true); - emit ERC721BridgeInitiated(address(localToken), address(remoteToken), alice, bob, tokenId, hex"5678"); - - // Bridge the token. - vm.prank(alice); - L2NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); - - // Token is burned. - vm.expectRevert("ERC721: invalid token ID"); - localToken.ownerOf(tokenId); - } - - /// @dev Tests that `bridgeERC721To` reverts if the local token is the zero address. - function test_bridgeERC721To_localTokenZeroAddress_reverts() external { - // Bridge the token. - vm.prank(alice); - vm.expectRevert(); - L2NFTBridge.bridgeERC721To(address(0), address(L1NFTBridge), bob, tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that `bridgeERC721To` reverts if the remote token is the zero address. - function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external { - // Bridge the token. - vm.prank(alice); - vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)"); - L2NFTBridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that `bridgeERC721To` reverts if the caller is not the token owner. - function test_bridgeERC721To_wrongOwner_reverts() external { - // Bridge the token. - vm.prank(bob); - vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner"); - L2NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); - - // Token is not locked in the bridge. - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that `finalizeBridgeERC721` correctly finalizes a bridged token. - function test_finalizeBridgeERC721_succeeds() external { - // Bridge the token. - vm.prank(alice); - L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); - - // Expect an event to be emitted. - vm.expectEmit(true, true, true, true); - emit ERC721BridgeFinalized(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - - // Finalize a withdrawal. - vm.mockCall( - address(L2Messenger), - abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), - abi.encode(L1NFTBridge) - ); - vm.prank(address(L2Messenger)); - L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - - // Token is not locked in the bridge. - assertEq(localToken.ownerOf(tokenId), alice); - } - - /// @dev Tests that `finalizeBridgeERC721` reverts if the token is not compliant - /// with the `IOptimismMintableERC721` interface. - function test_finalizeBridgeERC721_interfaceNotCompliant_reverts() external { - // Create a non-compliant token - NonCompliantERC721 nonCompliantToken = new NonCompliantERC721(alice); - - // Bridge the non-compliant token. - vm.prank(alice); - L2NFTBridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex"5678"); - - // Attempt to finalize the withdrawal. Should revert because the token does not claim - // to be compliant with the `IOptimismMintableERC721` interface. - vm.mockCall( - address(L2Messenger), - abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), - abi.encode(L1NFTBridge) - ); - vm.prank(address(L2Messenger)); - vm.expectRevert("L2ERC721Bridge: local token interface is not compliant"); - L2NFTBridge.finalizeBridgeERC721( - address(address(nonCompliantToken)), address(address(0x01)), alice, alice, tokenId, hex"5678" - ); - } - - /// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge. - function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external { - // Finalize a withdrawal. - vm.prank(alice); - vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); - L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - } - - /// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge. - function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { - // Finalize a withdrawal. - vm.mockCall( - address(L2Messenger), abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), abi.encode(alice) - ); - vm.prank(address(L2Messenger)); - vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); - L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - } - - /// @dev Tests that `finalizeBridgeERC721` reverts when the local token is the - /// address of the bridge itself. - function test_finalizeBridgeERC721_selfToken_reverts() external { - // Finalize a withdrawal. - vm.mockCall( - address(L2Messenger), - abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), - abi.encode(address(L1NFTBridge)) - ); - vm.prank(address(L2Messenger)); - vm.expectRevert("L2ERC721Bridge: local token cannot be self"); - L2NFTBridge.finalizeBridgeERC721(address(L2NFTBridge), address(remoteToken), alice, alice, tokenId, hex"5678"); - } - - /// @dev Tests that `finalizeBridgeERC721` reverts when already finalized. - function test_finalizeBridgeERC721_alreadyExists_reverts() external { - // Finalize a withdrawal. - vm.mockCall( - address(L2Messenger), - abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), - abi.encode(address(L1NFTBridge)) - ); - vm.prank(address(L2Messenger)); - vm.expectRevert("ERC721: token already minted"); - L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); - } -} - -/// @dev A non-compliant ERC721 token that does not implement the full ERC721 interface. -/// This is used to test that the bridge will revert if the token does not claim to -/// support the ERC721 interface. -contract NonCompliantERC721 { - address internal immutable owner; - - constructor(address _owner) { - owner = _owner; - } - - function ownerOf(uint256) external view returns (address) { - return owner; - } - - function remoteToken() external pure returns (address) { - return address(0x01); - } - - function burn(address, uint256) external { - // Do nothing. - } - - function supportsInterface(bytes4) external pure returns (bool) { - return false; - } -} diff --git a/packages/contracts-bedrock/test/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/L2OutputOracle.t.sol deleted file mode 100644 index 52b87b450aa8..000000000000 --- a/packages/contracts-bedrock/test/L2OutputOracle.t.sol +++ /dev/null @@ -1,477 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { stdError } from "forge-std/Test.sol"; -import { L2OutputOracle_Initializer, NextImpl, EIP1967Helper } from "test/CommonTest.t.sol"; - -// Libraries -import { Types } from "src/libraries/Types.sol"; -import { Constants } from "src/libraries/Constants.sol"; - -// Target contract dependencies -import { Proxy } from "src/universal/Proxy.sol"; - -// Target contract -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; - -contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { - /// @dev Tests that constructor sets the initial values correctly. - function test_constructor_succeeds() external { - assertEq(oracle.PROPOSER(), proposer); - assertEq(oracle.proposer(), proposer); - assertEq(oracle.CHALLENGER(), owner); - assertEq(oracle.challenger(), owner); - assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval); - assertEq(oracle.submissionInterval(), submissionInterval); - assertEq(oracle.latestBlockNumber(), startingBlockNumber); - assertEq(oracle.startingBlockNumber(), startingBlockNumber); - assertEq(oracle.startingTimestamp(), startingTimestamp); - assertEq(oracle.L2_BLOCK_TIME(), l2BlockTime); - assertEq(oracle.l2BlockTime(), l2BlockTime); - assertEq(oracle.finalizationPeriodSeconds(), finalizationPeriodSeconds); - assertEq(oracle.FINALIZATION_PERIOD_SECONDS(), finalizationPeriodSeconds); - } - - /// @dev Tests that the constructor reverts if the l2BlockTime is invalid. - function test_constructor_l2BlockTimeZero_reverts() external { - vm.expectRevert("L2OutputOracle: L2 block time must be greater than 0"); - new L2OutputOracle({ - _submissionInterval: submissionInterval, - _l2BlockTime: 0, - _finalizationPeriodSeconds: 7 days - }); - } - - /// @dev Tests that the constructor reverts if the submissionInterval is zero. - function test_constructor_submissionInterval_reverts() external { - vm.expectRevert("L2OutputOracle: submission interval must be greater than 0"); - new L2OutputOracle({ - _submissionInterval: 0, - _l2BlockTime: l2BlockTime, - _finalizationPeriodSeconds: 7 days - }); - } - - /// @dev Tests that initialize reverts if the starting timestamp is invalid. - function test_initialize_badTimestamp_reverts() external { - // Reset the initialized field in the 0th storage slot - // so that initialize can be called again. - vm.store(address(oracle), bytes32(uint256(0)), bytes32(uint256(0))); - vm.expectRevert("L2OutputOracle: starting L2 timestamp must be less than current time"); - oracle.initialize({ - _startingBlockNumber: 0, - _startingTimestamp: block.timestamp + 1, - _proposer: address(0), - _challenger: address(0) - }); - } -} - -contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer { - bytes32 proposedOutput1 = keccak256(abi.encode(1)); - - /// @dev Tests that `latestBlockNumber` returns the correct value. - function test_latestBlockNumber_succeeds() external { - uint256 proposedNumber = oracle.nextBlockNumber(); - - // Roll to after the block number we'll propose - warpToProposeTime(proposedNumber); - vm.prank(proposer); - oracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0); - assertEq(oracle.latestBlockNumber(), proposedNumber); - } - - /// @dev Tests that `getL2Output` returns the correct value. - function test_getL2Output_succeeds() external { - uint256 nextBlockNumber = oracle.nextBlockNumber(); - uint256 nextOutputIndex = oracle.nextOutputIndex(); - warpToProposeTime(nextBlockNumber); - vm.prank(proposer); - oracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0); - - Types.OutputProposal memory proposal = oracle.getL2Output(nextOutputIndex); - assertEq(proposal.outputRoot, proposedOutput1); - assertEq(proposal.timestamp, block.timestamp); - - // The block number is larger than the latest proposed output: - vm.expectRevert(stdError.indexOOBError); - oracle.getL2Output(nextOutputIndex + 1); - } - - /// @dev Tests that `getL2OutputIndexAfter` returns the correct value - /// when the input is the exact block number of the proposal. - function test_getL2OutputIndexAfter_sameBlock_succeeds() external { - bytes32 output1 = keccak256(abi.encode(1)); - uint256 nextBlockNumber1 = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber1); - vm.prank(proposer); - oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); - - // Querying with exact same block as proposed returns the proposal. - uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1); - assertEq(index1, 0); - } - - /// @dev Tests that `getL2OutputIndexAfter` returns the correct value - /// when the input is the previous block number of the proposal. - function test_getL2OutputIndexAfter_previousBlock_succeeds() external { - bytes32 output1 = keccak256(abi.encode(1)); - uint256 nextBlockNumber1 = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber1); - vm.prank(proposer); - oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); - - // Querying with previous block returns the proposal too. - uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 - 1); - assertEq(index1, 0); - } - - /// @dev Tests that `getL2OutputIndexAfter` returns the correct value. - function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external { - bytes32 output1 = keccak256(abi.encode(1)); - uint256 nextBlockNumber1 = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber1); - vm.prank(proposer); - oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); - - bytes32 output2 = keccak256(abi.encode(2)); - uint256 nextBlockNumber2 = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber2); - vm.prank(proposer); - oracle.proposeL2Output(output2, nextBlockNumber2, 0, 0); - - bytes32 output3 = keccak256(abi.encode(3)); - uint256 nextBlockNumber3 = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber3); - vm.prank(proposer); - oracle.proposeL2Output(output3, nextBlockNumber3, 0, 0); - - bytes32 output4 = keccak256(abi.encode(4)); - uint256 nextBlockNumber4 = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber4); - vm.prank(proposer); - oracle.proposeL2Output(output4, nextBlockNumber4, 0, 0); - - // Querying with a block number between the first and second proposal - uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 + 1); - assertEq(index1, 1); - - // Querying with a block number between the second and third proposal - uint256 index2 = oracle.getL2OutputIndexAfter(nextBlockNumber2 + 1); - assertEq(index2, 2); - - // Querying with a block number between the third and fourth proposal - uint256 index3 = oracle.getL2OutputIndexAfter(nextBlockNumber3 + 1); - assertEq(index3, 3); - } - - /// @dev Tests that `getL2OutputIndexAfter` reverts when no output exists. - function test_getL2OutputIndexAfter_noOutputsExis_reverts() external { - vm.expectRevert("L2OutputOracle: cannot get output as no outputs have been proposed yet"); - oracle.getL2OutputIndexAfter(0); - } - - /// @dev Tests that `nextBlockNumber` returns the correct value. - function test_nextBlockNumber_succeeds() external { - assertEq( - oracle.nextBlockNumber(), - // The return value should match this arithmetic - oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL() - ); - } - - /// @dev Tests that `computeL2Timestamp` returns the correct value. - function test_computeL2Timestamp_succeeds() external { - // reverts if timestamp is too low - vm.expectRevert(stdError.arithmeticError); - oracle.computeL2Timestamp(startingBlockNumber - 1); - - // check timestamp for the very first block - assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp); - - // check timestamp for the first block after the starting block - assertEq(oracle.computeL2Timestamp(startingBlockNumber + 1), startingTimestamp + l2BlockTime); - - // check timestamp for some other block number - assertEq(oracle.computeL2Timestamp(startingBlockNumber + 96024), startingTimestamp + l2BlockTime * 96024); - } -} - -contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer { - /// @dev Test that `proposeL2Output` succeeds for a valid input - /// and when a block hash and number are not specified. - function test_proposeL2Output_proposeAnotherOutput_succeeds() public { - proposeAnotherOutput(); - } - - /// @dev Tests that `proposeL2Output` succeeds when given valid input and - /// when a block hash and number are specified for reorg protection. - function test_proposeWithBlockhashAndHeight_succeeds() external { - // Get the number and hash of a previous block in the chain - uint256 prevL1BlockNumber = block.number - 1; - bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber); - - uint256 nextBlockNumber = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber); - vm.prank(proposer); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber); - } - - /// @dev Tests that `proposeL2Output` reverts when called by a party - /// that is not the proposer. - function test_proposeL2Output_notProposer_reverts() external { - uint256 nextBlockNumber = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber); - - vm.prank(address(128)); - vm.expectRevert("L2OutputOracle: only the proposer address can propose new outputs"); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); - } - - /// @dev Tests that `proposeL2Output` reverts when given a zero blockhash. - function test_proposeL2Output_emptyOutput_reverts() external { - bytes32 outputToPropose = bytes32(0); - uint256 nextBlockNumber = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber); - vm.prank(proposer); - vm.expectRevert("L2OutputOracle: L2 output proposal cannot be the zero hash"); - oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0); - } - - /// @dev Tests that `proposeL2Output` reverts when given a block number - /// that does not match the next expected block number. - function test_proposeL2Output_unexpectedBlockNumber_reverts() external { - uint256 nextBlockNumber = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber); - vm.prank(proposer); - vm.expectRevert("L2OutputOracle: block number must be equal to next expected block number"); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0); - } - - /// @dev Tests that `proposeL2Output` reverts when given a block number - /// that has a timestamp in the future. - function test_proposeL2Output_futureTimetamp_reverts() external { - uint256 nextBlockNumber = oracle.nextBlockNumber(); - uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber); - vm.warp(nextTimestamp); - vm.prank(proposer); - vm.expectRevert("L2OutputOracle: cannot propose L2 output in the future"); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); - } - - /// @dev Tests that `proposeL2Output` reverts when given a block number - /// whose hash does not match the given block hash. - function test_proposeL2Output_wrongFork_reverts() external { - uint256 nextBlockNumber = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber); - vm.prank(proposer); - vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height"); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, bytes32(uint256(0x01)), block.number - 1); - } - - /// @dev Tests that `proposeL2Output` reverts when given a block number - /// whose block hash does not match the given block hash. - function test_proposeL2Output_unmatchedBlockhash_reverts() external { - // Move ahead to block 100 so that we can reference historical blocks - vm.roll(100); - - // Get the number and hash of a previous block in the chain - uint256 l1BlockNumber = block.number - 1; - bytes32 l1BlockHash = blockhash(l1BlockNumber); - - uint256 nextBlockNumber = oracle.nextBlockNumber(); - warpToProposeTime(nextBlockNumber); - vm.prank(proposer); - - // This will fail when foundry no longer returns zerod block hashes - vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height"); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1); - } -} - -contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { - /// @dev Tests that `deleteL2Outputs` succeeds for a single output. - function test_deleteOutputs_singleOutput_succeeds() external { - proposeAnotherOutput(); - proposeAnotherOutput(); - - uint256 latestBlockNumber = oracle.latestBlockNumber(); - uint256 latestOutputIndex = oracle.latestOutputIndex(); - Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 1); - - vm.prank(owner); - vm.expectEmit(true, true, false, false); - emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex); - oracle.deleteL2Outputs(latestOutputIndex); - - // validate latestBlockNumber has been reduced - uint256 latestBlockNumberAfter = oracle.latestBlockNumber(); - uint256 latestOutputIndexAfter = oracle.latestOutputIndex(); - assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter); - - // validate that the new latest output is as expected. - Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter); - assertEq(newLatestOutput.outputRoot, proposal.outputRoot); - assertEq(newLatestOutput.timestamp, proposal.timestamp); - } - - /// @dev Tests that `deleteL2Outputs` succeeds for multiple outputs. - function test_deleteOutputs_multipleOutputs_succeeds() external { - proposeAnotherOutput(); - proposeAnotherOutput(); - proposeAnotherOutput(); - proposeAnotherOutput(); - - uint256 latestBlockNumber = oracle.latestBlockNumber(); - uint256 latestOutputIndex = oracle.latestOutputIndex(); - Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 3); - - vm.prank(owner); - vm.expectEmit(true, true, false, false); - emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2); - oracle.deleteL2Outputs(latestOutputIndex - 2); - - // validate latestBlockNumber has been reduced - uint256 latestBlockNumberAfter = oracle.latestBlockNumber(); - uint256 latestOutputIndexAfter = oracle.latestOutputIndex(); - assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter); - - // validate that the new latest output is as expected. - Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter); - assertEq(newLatestOutput.outputRoot, proposal.outputRoot); - assertEq(newLatestOutput.timestamp, proposal.timestamp); - } - - /// @dev Tests that `deleteL2Outputs` reverts when not called by the challenger. - function test_deleteL2Outputs_ifNotChallenger_reverts() external { - uint256 latestBlockNumber = oracle.latestBlockNumber(); - - vm.expectRevert("L2OutputOracle: only the challenger address can delete outputs"); - oracle.deleteL2Outputs(latestBlockNumber); - } - - /// @dev Tests that `deleteL2Outputs` reverts for a non-existant output index. - function test_deleteL2Outputs_nonExistent_reverts() external { - proposeAnotherOutput(); - - uint256 latestBlockNumber = oracle.latestBlockNumber(); - - vm.prank(owner); - vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index"); - oracle.deleteL2Outputs(latestBlockNumber + 1); - } - - /// @dev Tests that `deleteL2Outputs` reverts when trying to delete outputs - /// after the latest output index. - function test_deleteL2Outputs_afterLatest_reverts() external { - proposeAnotherOutput(); - proposeAnotherOutput(); - proposeAnotherOutput(); - - // Delete the latest two outputs - uint256 latestOutputIndex = oracle.latestOutputIndex(); - vm.prank(owner); - oracle.deleteL2Outputs(latestOutputIndex - 2); - - // Now try to delete the same output again - vm.prank(owner); - vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index"); - oracle.deleteL2Outputs(latestOutputIndex - 2); - } - - /// @dev Tests that `deleteL2Outputs` reverts for finalized outputs. - function test_deleteL2Outputs_finalized_reverts() external { - proposeAnotherOutput(); - - // Warp past the finalization period + 1 second - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - - uint256 latestOutputIndex = oracle.latestOutputIndex(); - - // Try to delete a finalized output - vm.prank(owner); - vm.expectRevert("L2OutputOracle: cannot delete outputs that have already been finalized"); - oracle.deleteL2Outputs(latestOutputIndex); - } -} - -contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { - Proxy internal proxy; - - function setUp() public override { - super.setUp(); - proxy = Proxy(payable(address(oracle))); - } - - /// @dev Tests that the proxy is initialized with the correct values. - function test_initValuesOnProxy_succeeds() external { - assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval); - assertEq(oracle.submissionInterval(), submissionInterval); - assertEq(oracle.L2_BLOCK_TIME(), l2BlockTime); - assertEq(oracle.l2BlockTime(), l2BlockTime); - assertEq(oracle.startingBlockNumber(), startingBlockNumber); - assertEq(oracle.startingTimestamp(), startingTimestamp); - assertEq(oracle.finalizationPeriodSeconds(), finalizationPeriodSeconds); - assertEq(oracle.PROPOSER(), proposer); - assertEq(oracle.proposer(), proposer); - assertEq(oracle.CHALLENGER(), owner); - assertEq(oracle.challenger(), owner); - } - - /// @dev Tests that the impl is created with the correct values. - function test_initValuesOnImpl_succeeds() external { - assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL()); - assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME()); - - // The values that are set in the initialize function should be all - // zero values in the implementation contract. - assertEq(oracleImpl.startingBlockNumber(), 0); - assertEq(oracleImpl.startingTimestamp(), 0); - assertEq(oracleImpl.PROPOSER(), address(0)); - assertEq(oracleImpl.proposer(), address(0)); - assertEq(oracleImpl.CHALLENGER(), address(0)); - assertEq(oracleImpl.challenger(), address(0)); - } - - /// @dev Tests that the proxy cannot be initialized twice. - function test_initializeProxy_alreadyInitialized_reverts() external { - vm.expectRevert("Initializable: contract is already initialized"); - L2OutputOracle(payable(proxy)).initialize({ - _startingBlockNumber: startingBlockNumber, - _startingTimestamp: startingTimestamp, - _proposer: address(1), - _challenger: address(2) - }); - } - - /// @dev Tests that the implementation contract cannot be initialized twice. - function test_initializeImpl_alreadyInitialized_reverts() external { - vm.expectRevert("Initializable: contract is already initialized"); - L2OutputOracle(oracleImpl).initialize({ - _startingBlockNumber: startingBlockNumber, - _startingTimestamp: startingTimestamp, - _proposer: address(1), - _challenger: address(2) - }); - } - - /// @dev Tests that the proxy can be successfully upgraded. - function test_upgrading_succeeds() external { - // Check an unused slot before upgrading. - bytes32 slot21Before = vm.load(address(oracle), bytes32(uint256(21))); - assertEq(bytes32(0), slot21Before); - - NextImpl nextImpl = new NextImpl(); - vm.startPrank(EIP1967Helper.getAdmin(address(proxy))); - proxy.upgradeToAndCall( - address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, Constants.INITIALIZER + 1) - ); - assertEq(proxy.implementation(), address(nextImpl)); - - // Verify that the NextImpl contract initialized its values according as expected - bytes32 slot21After = vm.load(address(oracle), bytes32(uint256(21))); - bytes32 slot21Expected = NextImpl(address(oracle)).slot21Init(); - assertEq(slot21Expected, slot21After); - } -} diff --git a/packages/contracts-bedrock/test/L2StandardBridge.t.sol b/packages/contracts-bedrock/test/L2StandardBridge.t.sol deleted file mode 100644 index be7dd6ff639c..000000000000 --- a/packages/contracts-bedrock/test/L2StandardBridge.t.sol +++ /dev/null @@ -1,468 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -// Target contract is imported by the `Bridge_Initializer` -import { Bridge_Initializer } from "test/CommonTest.t.sol"; -import { stdStorage, StdStorage } from "forge-std/Test.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - -// Libraries -import { Hashing } from "src/libraries/Hashing.sol"; -import { Types } from "src/libraries/Types.sol"; - -// Target contract dependencies -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; - -contract L2StandardBridge_Test is Bridge_Initializer { - using stdStorage for StdStorage; - - /// @dev Tests that the bridge is initialized correctly. - function test_initialize_succeeds() external { - assertEq(address(L2Bridge.messenger()), address(L2Messenger)); - assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge)); - assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge)); - } - - /// @dev Tests that the bridge receives ETH and successfully initiates a withdrawal. - function test_receive_succeeds() external { - assertEq(address(messagePasser).balance, 0); - uint256 nonce = L2Messenger.messageNonce(); - - bytes memory message = - abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""); - uint64 baseGas = L2Messenger.baseGas(message, 200_000); - bytes memory withdrawalData = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, - nonce, - address(L2Bridge), - address(L1Bridge), - 100, - 200_000, - message - ); - bytes32 withdrawalHash = Hashing.hashWithdrawal( - Types.WithdrawalTransaction({ - nonce: nonce, - sender: address(L2Messenger), - target: address(L1Messenger), - value: 100, - gasLimit: baseGas, - data: withdrawalData - }) - ); - - vm.expectEmit(true, true, true, true); - emit WithdrawalInitiated(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex""); - - vm.expectEmit(true, true, true, true); - emit ETHBridgeInitiated(alice, alice, 100, hex""); - - // L2ToL1MessagePasser will emit a MessagePassed event - vm.expectEmit(true, true, true, true, address(messagePasser)); - emit MessagePassed( - nonce, address(L2Messenger), address(L1Messenger), 100, baseGas, withdrawalData, withdrawalHash - ); - - // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L2Messenger)); - emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 200_000); - - // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L2Messenger)); - emit SentMessageExtension1(address(L2Bridge), 100); - - vm.expectCall( - address(L2Messenger), - abi.encodeWithSelector( - CrossDomainMessenger.sendMessage.selector, - address(L1Bridge), - message, - 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT - ) - ); - - vm.expectCall( - Predeploys.L2_TO_L1_MESSAGE_PASSER, - abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData - ) - ); - - vm.prank(alice, alice); - (bool success,) = address(L2Bridge).call{ value: 100 }(hex""); - assertEq(success, true); - assertEq(address(messagePasser).balance, 100); - } - - /// @dev Tests that `withdraw` reverts if the amount is not equal to the value sent. - function test_withdraw_insufficientValue_reverts() external { - assertEq(address(messagePasser).balance, 0); - - vm.expectRevert("StandardBridge: bridging ETH must include sufficient ETH value"); - vm.prank(alice, alice); - L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex""); - } - - /// @dev Tests that the legacy `withdraw` interface on the L2StandardBridge - /// successfully initiates a withdrawal. - function test_withdraw_ether_succeeds() external { - assertTrue(alice.balance >= 100); - assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0); - - vm.expectEmit(true, true, true, true, address(L2Bridge)); - emit WithdrawalInitiated({ - l1Token: address(0), - l2Token: Predeploys.LEGACY_ERC20_ETH, - from: alice, - to: alice, - amount: 100, - data: hex"" - }); - - vm.expectEmit(true, true, true, true, address(L2Bridge)); - emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex"" }); - - vm.prank(alice, alice); - L2Bridge.withdraw{ value: 100 }({ - _l2Token: Predeploys.LEGACY_ERC20_ETH, - _amount: 100, - _minGasLimit: 1000, - _extraData: hex"" - }); - - assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 100); - } -} - -contract PreBridgeERC20 is Bridge_Initializer { - /// @dev Sets up expected calls and emits for a successful ERC20 withdrawal. - function _preBridgeERC20(bool _isLegacy, address _l2Token) internal { - // Alice has 100 L2Token - deal(_l2Token, alice, 100, true); - assertEq(ERC20(_l2Token).balanceOf(alice), 100); - uint256 nonce = L2Messenger.messageNonce(); - bytes memory message = abi.encodeWithSelector( - StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, alice, 100, hex"" - ); - uint64 baseGas = L2Messenger.baseGas(message, 1000); - bytes memory withdrawalData = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L2Bridge), address(L1Bridge), 0, 1000, message - ); - bytes32 withdrawalHash = Hashing.hashWithdrawal( - Types.WithdrawalTransaction({ - nonce: nonce, - sender: address(L2Messenger), - target: address(L1Messenger), - value: 0, - gasLimit: baseGas, - data: withdrawalData - }) - ); - - if (_isLegacy) { - vm.expectCall( - address(L2Bridge), abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex"") - ); - } else { - vm.expectCall( - address(L2Bridge), - abi.encodeWithSelector(L2Bridge.bridgeERC20.selector, _l2Token, address(L1Token), 100, 1000, hex"") - ); - } - - vm.expectCall( - address(L2Messenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L1Bridge), message, 1000) - ); - - vm.expectCall( - Predeploys.L2_TO_L1_MESSAGE_PASSER, - abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData - ) - ); - - // The L2Bridge should burn the tokens - vm.expectCall(_l2Token, abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)); - - vm.expectEmit(true, true, true, true); - emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex""); - - vm.expectEmit(true, true, true, true); - emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, alice, 100, hex""); - - vm.expectEmit(true, true, true, true); - emit MessagePassed( - nonce, address(L2Messenger), address(L1Messenger), 0, baseGas, withdrawalData, withdrawalHash - ); - - // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true); - emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000); - - // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true); - emit SentMessageExtension1(address(L2Bridge), 0); - - vm.prank(alice, alice); - } -} - -contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 { - // withdraw - // - token is burned - // - emits WithdrawalInitiated - // - calls Withdrawer.initiateWithdrawal - function test_withdraw_withdrawingERC20_succeeds() external { - _preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) }); - L2Bridge.withdraw(address(L2Token), 100, 1000, hex""); - - assertEq(L2Token.balanceOf(alice), 0); - } - - // BridgeERC20 - // - token is burned - // - emits WithdrawalInitiated - // - calls Withdrawer.initiateWithdrawal - function test_bridgeERC20_succeeds() external { - _preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) }); - L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex""); - - assertEq(L2Token.balanceOf(alice), 0); - } - - function test_withdrawLegacyERC20_succeeds() external { - _preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) }); - L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex""); - - assertEq(L2Token.balanceOf(alice), 0); - } - - function test_bridgeLegacyERC20_succeeds() external { - _preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) }); - L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex""); - - assertEq(L2Token.balanceOf(alice), 0); - } - - function test_withdraw_notEOA_reverts() external { - // This contract has 100 L2Token - deal(address(L2Token), address(this), 100, true); - - vm.expectRevert("StandardBridge: function can only be called from an EOA"); - L2Bridge.withdraw(address(L2Token), 100, 1000, hex""); - } -} - -contract PreBridgeERC20To is Bridge_Initializer { - // withdrawTo and BridgeERC20To should behave the same when transferring ERC20 tokens - // so they should share the same setup and expectEmit calls - function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal { - deal(_l2Token, alice, 100, true); - assertEq(ERC20(L2Token).balanceOf(alice), 100); - uint256 nonce = L2Messenger.messageNonce(); - bytes memory message = abi.encodeWithSelector( - StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, bob, 100, hex"" - ); - uint64 baseGas = L2Messenger.baseGas(message, 1000); - bytes memory withdrawalData = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L2Bridge), address(L1Bridge), 0, 1000, message - ); - bytes32 withdrawalHash = Hashing.hashWithdrawal( - Types.WithdrawalTransaction({ - nonce: nonce, - sender: address(L2Messenger), - target: address(L1Messenger), - value: 0, - gasLimit: baseGas, - data: withdrawalData - }) - ); - - vm.expectEmit(true, true, true, true, address(L2Bridge)); - emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex""); - - vm.expectEmit(true, true, true, true, address(L2Bridge)); - emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex""); - - vm.expectEmit(true, true, true, true, address(messagePasser)); - emit MessagePassed( - nonce, address(L2Messenger), address(L1Messenger), 0, baseGas, withdrawalData, withdrawalHash - ); - - // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L2Messenger)); - emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000); - - // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L2Messenger)); - emit SentMessageExtension1(address(L2Bridge), 0); - - if (_isLegacy) { - vm.expectCall( - address(L2Bridge), abi.encodeWithSelector(L2Bridge.withdrawTo.selector, _l2Token, bob, 100, 1000, hex"") - ); - } else { - vm.expectCall( - address(L2Bridge), - abi.encodeWithSelector( - L2Bridge.bridgeERC20To.selector, _l2Token, address(L1Token), bob, 100, 1000, hex"" - ) - ); - } - - vm.expectCall( - address(L2Messenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L1Bridge), message, 1000) - ); - - vm.expectCall( - Predeploys.L2_TO_L1_MESSAGE_PASSER, - abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData - ) - ); - - // The L2Bridge should burn the tokens - vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)); - - vm.prank(alice, alice); - } -} - -contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To { - /// @dev Tests that `withdrawTo` burns the tokens, emits `WithdrawalInitiated`, - /// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`. - function test_withdrawTo_withdrawingERC20_succeeds() external { - _preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) }); - L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex""); - - assertEq(L2Token.balanceOf(alice), 0); - } - - /// @dev Tests that `bridgeERC20To` burns the tokens, emits `WithdrawalInitiated`, - /// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`. - function test_bridgeERC20To_succeeds() external { - _preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) }); - L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex""); - assertEq(L2Token.balanceOf(alice), 0); - } -} - -contract L2StandardBridge_Bridge_Test is Bridge_Initializer { - /// @dev Tests that `finalizeDeposit` succeeds. It should: - /// - only be callable by the l1TokenBridge - /// - emit `DepositFinalized` if the token pair is supported - /// - call `Withdrawer.initiateWithdrawal` if the token pair is not supported - function test_finalizeDeposit_depositingERC20_succeeds() external { - vm.mockCall( - address(L2Bridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) - ); - - vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)); - - // Should emit both the bedrock and legacy events - vm.expectEmit(true, true, true, true, address(L2Bridge)); - emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); - - vm.expectEmit(true, true, true, true, address(L2Bridge)); - emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex""); - - vm.prank(address(L2Messenger)); - L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex""); - } - - /// @dev Tests that `finalizeDeposit` succeeds when depositing ETH. - function test_finalizeDeposit_depositingETH_succeeds() external { - vm.mockCall( - address(L2Bridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) - ); - - // Should emit both the bedrock and legacy events - vm.expectEmit(true, true, true, true, address(L2Bridge)); - emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); - - vm.expectEmit(true, true, true, true, address(L2Bridge)); - emit ERC20BridgeFinalized( - address(L2Token), // localToken - address(L1Token), // remoteToken - alice, - alice, - 100, - hex"" - ); - - vm.prank(address(L2Messenger)); - L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex""); - } - - /// @dev Tests that `finalizeDeposit` reverts if the amounts do not match. - function test_finalizeBridgeETH_incorrectValue_reverts() external { - vm.mockCall( - address(L2Bridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) - ); - vm.deal(address(L2Messenger), 100); - vm.prank(address(L2Messenger)); - vm.expectRevert("StandardBridge: amount sent does not match amount required"); - L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex""); - } - - /// @dev Tests that `finalizeDeposit` reverts if the receipient is the other bridge. - function test_finalizeBridgeETH_sendToSelf_reverts() external { - vm.mockCall( - address(L2Bridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) - ); - vm.deal(address(L2Messenger), 100); - vm.prank(address(L2Messenger)); - vm.expectRevert("StandardBridge: cannot send to self"); - L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex""); - } - - /// @dev Tests that `finalizeDeposit` reverts if the receipient is the messenger. - function test_finalizeBridgeETH_sendToMessenger_reverts() external { - vm.mockCall( - address(L2Bridge.messenger()), - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) - ); - vm.deal(address(L2Messenger), 100); - vm.prank(address(L2Messenger)); - vm.expectRevert("StandardBridge: cannot send to messenger"); - L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Messenger), 100, hex""); - } -} - -contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { - /// @dev Tests that `finalizeBridgeETH` succeeds. - function test_finalizeBridgeETH_succeeds() external { - address messenger = address(L2Bridge.messenger()); - vm.mockCall( - messenger, - abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) - ); - vm.deal(messenger, 100); - vm.prank(messenger); - - vm.expectEmit(true, true, true, true); - emit DepositFinalized(address(0), Predeploys.LEGACY_ERC20_ETH, alice, alice, 100, hex""); - - vm.expectEmit(true, true, true, true); - emit ETHBridgeFinalized(alice, alice, 100, hex""); - - L2Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); - } -} diff --git a/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol b/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol deleted file mode 100644 index 9e62c74944b4..000000000000 --- a/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; - -// Libraries -import { Types } from "src/libraries/Types.sol"; -import { Hashing } from "src/libraries/Hashing.sol"; - -// Target contract -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; - -contract L2ToL1MessagePasserTest is CommonTest { - L2ToL1MessagePasser messagePasser; - - event MessagePassed( - uint256 indexed nonce, - address indexed sender, - address indexed target, - uint256 value, - uint256 gasLimit, - bytes data, - bytes32 withdrawalHash - ); - - event WithdrawerBalanceBurnt(uint256 indexed amount); - - /// @dev Sets up the test suite. - function setUp() public virtual override { - super.setUp(); - messagePasser = new L2ToL1MessagePasser(); - } - - /// @dev Tests that `initiateWithdrawal` succeeds and correctly sets the state - /// of the message passer for the withdrawal hash. - function testFuzz_initiateWithdrawal_succeeds( - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes memory _data - ) - external - { - uint256 nonce = messagePasser.messageNonce(); - - bytes32 withdrawalHash = Hashing.hashWithdrawal( - Types.WithdrawalTransaction({ - nonce: nonce, - sender: _sender, - target: _target, - value: _value, - gasLimit: _gasLimit, - data: _data - }) - ); - - vm.expectEmit(true, true, true, true); - emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash); - - vm.deal(_sender, _value); - vm.prank(_sender); - messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data); - - assertEq(messagePasser.sentMessages(withdrawalHash), true); - - bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0))); - - assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1))); - } - - /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed - /// log when called by a contract. - function test_initiateWithdrawal_fromContract_succeeds() external { - bytes32 withdrawalHash = Hashing.hashWithdrawal( - Types.WithdrawalTransaction(messagePasser.messageNonce(), address(this), address(4), 100, 64000, hex"") - ); - - vm.expectEmit(true, true, true, true); - emit MessagePassed(messagePasser.messageNonce(), address(this), address(4), 100, 64000, hex"", withdrawalHash); - - vm.deal(address(this), 2 ** 64); - messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex""); - } - - /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed - /// log when called by an EOA. - function test_initiateWithdrawal_fromEOA_succeeds() external { - uint256 gasLimit = 64000; - address target = address(4); - uint256 value = 100; - bytes memory data = hex"ff"; - uint256 nonce = messagePasser.messageNonce(); - - // EOA emulation - vm.prank(alice, alice); - vm.deal(alice, 2 ** 64); - bytes32 withdrawalHash = - Hashing.hashWithdrawal(Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data)); - - vm.expectEmit(true, true, true, true); - emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash); - - messagePasser.initiateWithdrawal{ value: value }(target, gasLimit, data); - - // the sent messages mapping is filled - assertEq(messagePasser.sentMessages(withdrawalHash), true); - // the nonce increments - assertEq(nonce + 1, messagePasser.messageNonce()); - } - - /// @dev Tests that `burn` succeeds and destroys the ETH held in the contract. - function test_burn_succeeds() external { - messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(NON_ZERO_ADDRESS, NON_ZERO_GASLIMIT, NON_ZERO_DATA); - - assertEq(address(messagePasser).balance, NON_ZERO_VALUE); - vm.expectEmit(true, false, false, false); - emit WithdrawerBalanceBurnt(NON_ZERO_VALUE); - messagePasser.burn(); - - // The Withdrawer should have no balance - assertEq(address(messagePasser).balance, 0); - } -} diff --git a/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol b/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol deleted file mode 100644 index 126fdfe661e2..000000000000 --- a/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; - -// Target contract dependencies -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract -import { LegacyERC20ETH } from "src/legacy/LegacyERC20ETH.sol"; - -contract LegacyERC20ETH_Test is CommonTest { - LegacyERC20ETH eth; - - /// @dev Sets up the test suite. - function setUp() public virtual override { - super.setUp(); - eth = new LegacyERC20ETH(); - } - - /// @dev Tests that the default metadata was set correctly. - function test_metadata_succeeds() external { - assertEq(eth.name(), "Ether"); - assertEq(eth.symbol(), "ETH"); - assertEq(eth.decimals(), 18); - } - - /// @dev Tests that `l2Bridge` and `l1Token` return the correct values. - function test_crossDomain_succeeds() external { - assertEq(eth.l2Bridge(), Predeploys.L2_STANDARD_BRIDGE); - assertEq(eth.l1Token(), address(0)); - } - - /// @dev Tests that `transfer` reverts since it does not exist. - function test_transfer_doesNotExist_reverts() external { - vm.expectRevert("LegacyERC20ETH: transfer is disabled"); - eth.transfer(alice, 100); - } - - /// @dev Tests that `approve` reverts since it does not exist. - function test_approve_doesNotExist_reverts() external { - vm.expectRevert("LegacyERC20ETH: approve is disabled"); - eth.approve(alice, 100); - } - - /// @dev Tests that `transferFrom` reverts since it does not exist. - function test_transferFrom_doesNotExist_reverts() external { - vm.expectRevert("LegacyERC20ETH: transferFrom is disabled"); - eth.transferFrom(bob, alice, 100); - } - - /// @dev Tests that `increaseAllowance` reverts since it does not exist. - function test_increaseAllowance_doesNotExist_reverts() external { - vm.expectRevert("LegacyERC20ETH: increaseAllowance is disabled"); - eth.increaseAllowance(alice, 100); - } - - /// @dev Tests that `decreaseAllowance` reverts since it does not exist. - function test_decreaseAllowance_doesNotExist_reverts() external { - vm.expectRevert("LegacyERC20ETH: decreaseAllowance is disabled"); - eth.decreaseAllowance(alice, 100); - } - - /// @dev Tests that `mint` reverts since it does not exist. - function test_mint_doesNotExist_reverts() external { - vm.expectRevert("LegacyERC20ETH: mint is disabled"); - eth.mint(alice, 100); - } - - /// @dev Tests that `burn` reverts since it does not exist. - function test_burn_doesNotExist_reverts() external { - vm.expectRevert("LegacyERC20ETH: burn is disabled"); - eth.burn(alice, 100); - } -} diff --git a/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol b/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol deleted file mode 100644 index abf841e3e79e..000000000000 --- a/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; - -// Testing contract dependencies -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract -import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; - -contract LegacyMessagePasser_Test is CommonTest { - LegacyMessagePasser messagePasser; - - /// @dev Sets up the test suite. - function setUp() public virtual override { - super.setUp(); - messagePasser = new LegacyMessagePasser(); - } - - /// @dev Tests that `passMessageToL1` succeeds. - function test_passMessageToL1_succeeds() external { - vm.prank(alice); - messagePasser.passMessageToL1(hex"ff"); - assert(messagePasser.sentMessages(keccak256(abi.encodePacked(hex"ff", alice)))); - } -} diff --git a/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol deleted file mode 100644 index a09ea0f94df7..000000000000 --- a/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { Bridge_Initializer } from "test/CommonTest.t.sol"; - -contract OptimismMintableTokenFactory_Test is Bridge_Initializer { - event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); - event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); - - function setUp() public override { - super.setUp(); - } - - function test_bridge_succeeds() external { - assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge)); - } - - function test_createStandardL2Token_succeeds() external { - address remote = address(4); - - // Defaults to 18 decimals - address local = calculateTokenAddress(remote, "Beep", "BOOP", 18); - - vm.expectEmit(true, true, true, true); - emit StandardL2TokenCreated(remote, local); - - vm.expectEmit(true, true, true, true); - emit OptimismMintableERC20Created(local, remote, alice); - - vm.prank(alice); - address addr = L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); - assertTrue(addr == local); - assertTrue(OptimismMintableERC20(local).decimals() == 18); - } - - function test_createStandardL2TokenWithDecimals_succeeds() external { - address remote = address(4); - address local = calculateTokenAddress(remote, "Beep", "BOOP", 6); - - vm.expectEmit(true, true, true, true); - emit StandardL2TokenCreated(remote, local); - - vm.expectEmit(true, true, true, true); - emit OptimismMintableERC20Created(local, remote, alice); - - vm.prank(alice); - address addr = L2TokenFactory.createOptimismMintableERC20WithDecimals(remote, "Beep", "BOOP", 6); - assertTrue(addr == local); - - assertTrue(OptimismMintableERC20(local).decimals() == 6); - } - - function test_createStandardL2Token_sameTwice_reverts() external { - address remote = address(4); - - vm.prank(alice); - L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); - - vm.expectRevert(); - - vm.prank(alice); - L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); - } - - function test_createStandardL2Token_remoteIsZero_reverts() external { - address remote = address(0); - vm.expectRevert("OptimismMintableERC20Factory: must provide remote token address"); - L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); - } - - function calculateTokenAddress( - address _remote, - string memory _name, - string memory _symbol, - uint8 _decimals - ) - internal - view - returns (address) - { - bytes memory constructorArgs = abi.encode(address(L2Bridge), _remote, _name, _symbol, _decimals); - bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC20).creationCode, constructorArgs); - bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol, _decimals)); - bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(L2TokenFactory), salt, keccak256(bytecode))); - return address(uint160(uint256(hash))); - } -} diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol deleted file mode 100644 index d116ff17c275..000000000000 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ /dev/null @@ -1,1038 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { stdError } from "forge-std/Test.sol"; -import { Portal_Initializer, CommonTest, NextImpl } from "test/CommonTest.t.sol"; - -// Libraries -import { Types } from "src/libraries/Types.sol"; -import { Hashing } from "src/libraries/Hashing.sol"; -import { Constants } from "src/libraries/Constants.sol"; - -// Target contract dependencies -import { Proxy } from "src/universal/Proxy.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; - -// Target contract -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; - -contract OptimismPortal_Test is Portal_Initializer { - event Paused(address); - event Unpaused(address); - - /// @dev Tests that the constructor sets the correct values. - function test_constructor_succeeds() external { - assertEq(address(op.L2_ORACLE()), address(oracle)); - assertEq(address(op.l2Oracle()), address(oracle)); - assertEq(op.GUARDIAN(), guardian); - assertEq(op.guardian(), guardian); - assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD); - assertEq(op.paused(), false); - } - - /// @dev Tests that `pause` successfully pauses - /// when called by the GUARDIAN. - function test_pause_succeeds() external { - address guardian = op.GUARDIAN(); - - assertEq(op.paused(), false); - - vm.expectEmit(true, true, true, true, address(op)); - emit Paused(guardian); - - vm.prank(guardian); - op.pause(); - - assertEq(op.paused(), true); - } - - /// @dev Tests that `pause` reverts when called by a non-GUARDIAN. - function test_pause_onlyGuardian_reverts() external { - assertEq(op.paused(), false); - - assertTrue(op.GUARDIAN() != alice); - vm.expectRevert("OptimismPortal: only guardian can pause"); - vm.prank(alice); - op.pause(); - - assertEq(op.paused(), false); - } - - /// @dev Tests that `unpause` successfully unpauses - /// when called by the GUARDIAN. - function test_unpause_succeeds() external { - address guardian = op.GUARDIAN(); - - vm.prank(guardian); - op.pause(); - assertEq(op.paused(), true); - - vm.expectEmit(true, true, true, true, address(op)); - emit Unpaused(guardian); - vm.prank(guardian); - op.unpause(); - - assertEq(op.paused(), false); - } - - /// @dev Tests that `unpause` reverts when called by a non-GUARDIAN. - function test_unpause_onlyGuardian_reverts() external { - address guardian = op.GUARDIAN(); - - vm.prank(guardian); - op.pause(); - assertEq(op.paused(), true); - - assertTrue(op.GUARDIAN() != alice); - vm.expectRevert("OptimismPortal: only guardian can unpause"); - vm.prank(alice); - op.unpause(); - - assertEq(op.paused(), true); - } - - /// @dev Tests that `receive` successdully deposits ETH. - function test_receive_succeeds() external { - vm.expectEmit(true, true, false, true); - emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex""); - - // give alice money and send as an eoa - vm.deal(alice, 2 ** 64); - vm.prank(alice, alice); - (bool s,) = address(op).call{ value: 100 }(hex""); - - assert(s); - assertEq(address(op).balance, 100); - } - - /// @dev Tests that `depositTransaction` reverts when the destination address is non-zero - /// for a contract creation deposit. - function test_depositTransaction_contractCreation_reverts() external { - // contract creation must have a target of address(0) - vm.expectRevert("OptimismPortal: must send to address(0) when creating a contract"); - op.depositTransaction(address(1), 1, 0, true, hex""); - } - - /// @dev Tests that `depositTransaction` reverts when the data is too large. - /// This places an upper bound on unsafe blocks sent over p2p. - function test_depositTransaction_largeData_reverts() external { - uint256 size = 120_001; - uint64 gasLimit = op.minimumGasLimit(uint64(size)); - vm.expectRevert("OptimismPortal: data too large"); - op.depositTransaction({ - _to: address(0), - _value: 0, - _gasLimit: gasLimit, - _isCreation: false, - _data: new bytes(size) - }); - } - - /// @dev Tests that `depositTransaction` reverts when the gas limit is too small. - function test_depositTransaction_smallGasLimit_reverts() external { - vm.expectRevert("OptimismPortal: gas limit too small"); - op.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" }); - } - - /// @dev Tests that `depositTransaction` succeeds for small, - /// but sufficient, gas limits. - function testFuzz_depositTransaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external { - vm.assume(_data.length <= type(uint64).max); - - uint64 gasLimit = op.minimumGasLimit(uint64(_data.length)); - if (_shouldFail) { - gasLimit = uint64(bound(gasLimit, 0, gasLimit - 1)); - vm.expectRevert("OptimismPortal: gas limit too small"); - } - - op.depositTransaction({ _to: address(0x40), _value: 0, _gasLimit: gasLimit, _isCreation: false, _data: _data }); - } - - /// @dev Tests that `minimumGasLimit` succeeds for small calldata sizes. - /// The gas limit should be 21k for 0 calldata and increase linearly - /// for larger calldata sizes. - function test_minimumGasLimit_succeeds() external { - assertEq(op.minimumGasLimit(0), 21_000); - assertTrue(op.minimumGasLimit(2) > op.minimumGasLimit(1)); - assertTrue(op.minimumGasLimit(3) > op.minimumGasLimit(2)); - } - - /// @dev Tests that `depositTransaction` succeeds for an EOA depositing a tx with 0 value. - function test_depositTransaction_noValueEOA_succeeds() external { - // EOA emulation - vm.prank(address(this), address(this)); - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - address(this), NON_ZERO_ADDRESS, ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA - ); - - op.depositTransaction(NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA); - } - - /// @dev Tests that `depositTransaction` succeeds for a contract depositing a tx with 0 value. - function test_depositTransaction_noValueContract_succeeds() external { - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(this)), - NON_ZERO_ADDRESS, - ZERO_VALUE, - ZERO_VALUE, - NON_ZERO_GASLIMIT, - false, - NON_ZERO_DATA - ); - - op.depositTransaction(NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA); - } - - /// @dev Tests that `depositTransaction` succeeds for an EOA - /// depositing a contract creation with 0 value. - function test_depositTransaction_createWithZeroValueForEOA_succeeds() external { - // EOA emulation - vm.prank(address(this), address(this)); - - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - address(this), ZERO_ADDRESS, ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA - ); - - op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA); - } - - /// @dev Tests that `depositTransaction` succeeds for a contract - /// depositing a contract creation with 0 value. - function test_depositTransaction_createWithZeroValueForContract_succeeds() external { - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(this)), - ZERO_ADDRESS, - ZERO_VALUE, - ZERO_VALUE, - NON_ZERO_GASLIMIT, - true, - NON_ZERO_DATA - ); - - op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA); - } - - /// @dev Tests that `depositTransaction` succeeds for an EOA depositing a tx with ETH. - function test_depositTransaction_withEthValueFromEOA_succeeds() external { - // EOA emulation - vm.prank(address(this), address(this)); - - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - address(this), NON_ZERO_ADDRESS, NON_ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA - ); - - op.depositTransaction{ value: NON_ZERO_VALUE }( - NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA - ); - assertEq(address(op).balance, NON_ZERO_VALUE); - } - - /// @dev Tests that `depositTransaction` succeeds for a contract depositing a tx with ETH. - function test_depositTransaction_withEthValueFromContract_succeeds() external { - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(this)), - NON_ZERO_ADDRESS, - NON_ZERO_VALUE, - ZERO_VALUE, - NON_ZERO_GASLIMIT, - false, - NON_ZERO_DATA - ); - - op.depositTransaction{ value: NON_ZERO_VALUE }( - NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA - ); - } - - /// @dev Tests that `depositTransaction` succeeds for an EOA depositing a contract creation with ETH. - function test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() external { - // EOA emulation - vm.prank(address(this), address(this)); - - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - address(this), ZERO_ADDRESS, NON_ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, true, hex"" - ); - - op.depositTransaction{ value: NON_ZERO_VALUE }(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, hex""); - assertEq(address(op).balance, NON_ZERO_VALUE); - } - - /// @dev Tests that `depositTransaction` succeeds for a contract depositing a contract creation with ETH. - function test_depositTransaction_withEthValueAndContractContractCreation_succeeds() external { - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(this)), - ZERO_ADDRESS, - NON_ZERO_VALUE, - ZERO_VALUE, - NON_ZERO_GASLIMIT, - true, - NON_ZERO_DATA - ); - - op.depositTransaction{ value: NON_ZERO_VALUE }(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA); - assertEq(address(op).balance, NON_ZERO_VALUE); - } - - /// @dev Tests that `isOutputFinalized` succeeds for an EOA depositing a tx with ETH and data. - function test_simple_isOutputFinalized_succeeds() external { - uint256 ts = block.timestamp; - vm.mockCall( - address(op.L2_ORACLE()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), - abi.encode(Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))) - ); - - // warp to the finalization period - vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS()); - assertEq(op.isOutputFinalized(0), false); - - // warp past the finalization period - vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - assertEq(op.isOutputFinalized(0), true); - } - - /// @dev Tests `isOutputFinalized` for a finalized output. - function test_isOutputFinalized_succeeds() external { - uint256 checkpoint = oracle.nextBlockNumber(); - uint256 nextOutputIndex = oracle.nextOutputIndex(); - vm.roll(checkpoint); - vm.warp(oracle.computeL2Timestamp(checkpoint) + 1); - vm.prank(oracle.PROPOSER()); - oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0); - - // warp to the final second of the finalization period - uint256 finalizationHorizon = block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS(); - vm.warp(finalizationHorizon); - // The checkpointed block should not be finalized until 1 second from now. - assertEq(op.isOutputFinalized(nextOutputIndex), false); - // Nor should a block after it - vm.expectRevert(stdError.indexOOBError); - assertEq(op.isOutputFinalized(nextOutputIndex + 1), false); - - // warp past the finalization period - vm.warp(finalizationHorizon + 1); - // It should now be finalized. - assertEq(op.isOutputFinalized(nextOutputIndex), true); - // But not the block after it. - vm.expectRevert(stdError.indexOOBError); - assertEq(op.isOutputFinalized(nextOutputIndex + 1), false); - } -} - -contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { - // Reusable default values for a test withdrawal - Types.WithdrawalTransaction _defaultTx; - - uint256 _proposedOutputIndex; - uint256 _proposedBlockNumber; - bytes32 _stateRoot; - bytes32 _storageRoot; - bytes32 _outputRoot; - bytes32 _withdrawalHash; - bytes[] _withdrawalProof; - Types.OutputRootProof internal _outputRootProof; - - // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls. - constructor() { - super.setUp(); - _defaultTx = Types.WithdrawalTransaction({ - nonce: 0, - sender: alice, - target: bob, - value: 100, - gasLimit: 100_000, - data: hex"" - }); - // Get withdrawal proof data we can use for testing. - (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = - ffi.getProveWithdrawalTransactionInputs(_defaultTx); - - // Setup a dummy output root proof for reuse. - _outputRootProof = Types.OutputRootProof({ - version: bytes32(uint256(0)), - stateRoot: _stateRoot, - messagePasserStorageRoot: _storageRoot, - latestBlockhash: bytes32(uint256(0)) - }); - _proposedBlockNumber = oracle.nextBlockNumber(); - _proposedOutputIndex = oracle.nextOutputIndex(); - } - - /// @dev Setup the system for a ready-to-use state. - function setUp() public override { - // Configure the oracle to return the output root we've prepared. - vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1); - vm.prank(oracle.PROPOSER()); - oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); - - // Warp beyond the finalization period for the block we've proposed. - vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - // Fund the portal so that we can withdraw ETH. - vm.deal(address(op), 0xFFFFFFFF); - } - - /// @dev Asserts that the reentrant call will revert. - function callPortalAndExpectRevert() external payable { - vm.expectRevert("OptimismPortal: can only trigger one withdrawal per transaction"); - // Arguments here don't matter, as the require check is the first thing that happens. - // We assume that this has already been proven. - op.finalizeWithdrawalTransaction(_defaultTx); - // Assert that the withdrawal was not finalized. - assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx))); - } - - /// @dev Tests that `proveWithdrawalTransaction` reverts when paused. - function test_proveWithdrawalTransaction_paused_reverts() external { - vm.prank(op.GUARDIAN()); - op.pause(); - - vm.expectRevert("OptimismPortal: paused"); - op.proveWithdrawalTransaction({ - _tx: _defaultTx, - _l2OutputIndex: _proposedOutputIndex, - _outputRootProof: _outputRootProof, - _withdrawalProof: _withdrawalProof - }); - } - - /// @dev Tests that `proveWithdrawalTransaction` reverts when the target is the portal contract. - function test_proveWithdrawalTransaction_onSelfCall_reverts() external { - _defaultTx.target = address(op); - vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract"); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - } - - /// @dev Tests that `proveWithdrawalTransaction` reverts when - /// the outputRootProof does not match the output root - function test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() external { - // Modify the version to invalidate the withdrawal proof. - _outputRootProof.version = bytes32(uint256(1)); - vm.expectRevert("OptimismPortal: invalid output root proof"); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - } - - /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal is missing. - function test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() external { - // modify the default test values to invalidate the proof. - _defaultTx.data = hex"abcd"; - vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key"); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - } - - /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal has already - /// been proven. - function test_proveWithdrawalTransaction_replayProve_reverts() external { - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - vm.expectRevert("OptimismPortal: withdrawal hash has already been proven"); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - } - - /// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already - /// been proven and the output root has changed and the l2BlockNumber stays the same. - function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external { - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash` - // inside of the `provenWithdrawal`s mapping. - bytes32 slot; - assembly { - mstore(0x00, sload(_withdrawalHash.slot)) - mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in the OptimismPortal - slot := keccak256(0x00, 0x40) - } - - // Store a different output root within the `provenWithdrawals` mapping without - // touching the l2BlockNumber or timestamp. - vm.store(address(op), slot, bytes32(0)); - - // Warp ahead 1 second - vm.warp(block.timestamp + 1); - - // Even though we have already proven this withdrawalHash, we should be allowed to re-submit - // our proof with a changed outputRoot - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - // Ensure that the withdrawal was updated within the mapping - (, uint128 timestamp,) = op.provenWithdrawals(_withdrawalHash); - assertEq(timestamp, block.timestamp); - } - - /// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already - /// been proven and the output root, output index, and l2BlockNumber have changed. - function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() external { - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash` - // inside of the `provenWithdrawal`s mapping. - bytes32 slot; - assembly { - mstore(0x00, sload(_withdrawalHash.slot)) - mstore(0x20, 52) // 52 is the slot of the `provenWithdrawals` mapping in OptimismPortal - slot := keccak256(0x00, 0x40) - } - - // Store a dummy output root within the `provenWithdrawals` mapping without touching the - // l2BlockNumber or timestamp. - vm.store(address(op), slot, bytes32(0)); - - // Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle - Types.OutputProposal memory proposal = op.L2_ORACLE().getL2Output(_proposedOutputIndex); - - // Propose the same output root again, creating the same output at a different index + l2BlockNumber. - vm.startPrank(op.L2_ORACLE().PROPOSER()); - op.L2_ORACLE().proposeL2Output( - proposal.outputRoot, op.L2_ORACLE().nextBlockNumber(), blockhash(block.number), block.number - ); - vm.stopPrank(); - - // Warp ahead 1 second - vm.warp(block.timestamp + 1); - - // Even though we have already proven this withdrawalHash, we should be allowed to re-submit - // our proof with a changed outputRoot + a different output index - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex + 1, _outputRootProof, _withdrawalProof); - - // Ensure that the withdrawal was updated within the mapping - (, uint128 timestamp,) = op.provenWithdrawals(_withdrawalHash); - assertEq(timestamp, block.timestamp); - } - - /// @dev Tests that `proveWithdrawalTransaction` succeeds. - function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external { - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` succeeds. - function test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() external { - uint256 bobBalanceBefore = address(bob).balance; - - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - vm.expectEmit(true, true, false, true); - emit WithdrawalFinalized(_withdrawalHash, true); - op.finalizeWithdrawalTransaction(_defaultTx); - - assert(address(bob).balance == bobBalanceBefore + 100); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the contract is paused. - function test_finalizeWithdrawalTransaction_paused_reverts() external { - vm.prank(op.GUARDIAN()); - op.pause(); - - vm.expectRevert("OptimismPortal: paused"); - op.finalizeWithdrawalTransaction(_defaultTx); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been - function test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() external { - uint256 bobBalanceBefore = address(bob).balance; - - vm.expectRevert("OptimismPortal: withdrawal has not been proven yet"); - op.finalizeWithdrawalTransaction(_defaultTx); - - assert(address(bob).balance == bobBalanceBefore); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been - /// proven long enough ago. - function test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() external { - uint256 bobBalanceBefore = address(bob).balance; - - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - // Mock a call where the resulting output root is anything but the original output root. In - // this case we just use bytes32(uint256(1)). - vm.mockCall( - address(op.L2_ORACLE()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), - abi.encode(bytes32(uint256(1)), _proposedBlockNumber) - ); - - vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); - op.finalizeWithdrawalTransaction(_defaultTx); - - assert(address(bob).balance == bobBalanceBefore); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the provenWithdrawal's timestamp - /// is less than the L2 output oracle's starting timestamp. - function test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() external { - uint256 bobBalanceBefore = address(bob).balance; - - // Prove our withdrawal - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - // Warp to after the finalization period - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - - // Mock a startingTimestamp change on the L2 Oracle - vm.mockCall( - address(op.L2_ORACLE()), abi.encodeWithSignature("startingTimestamp()"), abi.encode(block.timestamp + 1) - ); - - // Attempt to finalize the withdrawal - vm.expectRevert("OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp"); - op.finalizeWithdrawalTransaction(_defaultTx); - - // Ensure that bob's balance has remained the same - assertEq(bobBalanceBefore, address(bob).balance); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the output root proven is not the - /// same as the output root at the time of finalization. - function test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() external { - uint256 bobBalanceBefore = address(bob).balance; - - // Prove our withdrawal - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - // Warp to after the finalization period - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - - // Mock an outputRoot change on the output proposal before attempting - // to finalize the withdrawal. - vm.mockCall( - address(op.L2_ORACLE()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), - abi.encode( - Types.OutputProposal(bytes32(uint256(0)), uint128(block.timestamp), uint128(_proposedBlockNumber)) - ) - ); - - // Attempt to finalize the withdrawal - vm.expectRevert("OptimismPortal: output root proven is not the same as current output root"); - op.finalizeWithdrawalTransaction(_defaultTx); - - // Ensure that bob's balance has remained the same - assertEq(bobBalanceBefore, address(bob).balance); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the output proposal's timestamp - /// has not passed the finalization period. - function test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() external { - uint256 bobBalanceBefore = address(bob).balance; - - // Prove our withdrawal - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - // Warp to after the finalization period - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - - // Mock a timestamp change on the output proposal that has not passed the - // finalization period. - vm.mockCall( - address(op.L2_ORACLE()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), - abi.encode(Types.OutputProposal(_outputRoot, uint128(block.timestamp + 1), uint128(_proposedBlockNumber))) - ); - - // Attempt to finalize the withdrawal - vm.expectRevert("OptimismPortal: output proposal finalization period has not elapsed"); - op.finalizeWithdrawalTransaction(_defaultTx); - - // Ensure that bob's balance has remained the same - assertEq(bobBalanceBefore, address(bob).balance); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the target reverts. - function test_finalizeWithdrawalTransaction_targetFails_fails() external { - uint256 bobBalanceBefore = address(bob).balance; - vm.etch(bob, hex"fe"); // Contract with just the invalid opcode. - - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - vm.expectEmit(true, true, true, true); - emit WithdrawalFinalized(_withdrawalHash, false); - op.finalizeWithdrawalTransaction(_defaultTx); - - assert(address(bob).balance == bobBalanceBefore); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the finalization period - /// has not yet passed. - function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external { - // Setup the Oracle to return an output with a recent timestamp - uint256 recentTimestamp = block.timestamp - 1000; - vm.mockCall( - address(op.L2_ORACLE()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), - abi.encode(Types.OutputProposal(_outputRoot, uint128(recentTimestamp), uint128(_proposedBlockNumber))) - ); - - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); - op.finalizeWithdrawalTransaction(_defaultTx); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has already been - /// finalized. - function test_finalizeWithdrawalTransaction_onReplay_reverts() external { - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - vm.expectEmit(true, true, true, true); - emit WithdrawalFinalized(_withdrawalHash, true); - op.finalizeWithdrawalTransaction(_defaultTx); - - vm.expectRevert("OptimismPortal: withdrawal has already been finalized"); - op.finalizeWithdrawalTransaction(_defaultTx); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal transaction - /// does not have enough gas to execute. - function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external { - // This number was identified through trial and error. - uint256 gasLimit = 150_000; - Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({ - nonce: 0, - sender: alice, - target: bob, - value: 100, - gasLimit: gasLimit, - data: hex"" - }); - - // Get updated proof inputs. - (bytes32 stateRoot, bytes32 storageRoot,,, bytes[] memory withdrawalProof) = - ffi.getProveWithdrawalTransactionInputs(insufficientGasTx); - Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({ - version: bytes32(0), - stateRoot: stateRoot, - messagePasserStorageRoot: storageRoot, - latestBlockhash: bytes32(0) - }); - - vm.mockCall( - address(op.L2_ORACLE()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), - abi.encode( - Types.OutputProposal( - Hashing.hashOutputRootProof(outputRootProof), - uint128(block.timestamp), - uint128(_proposedBlockNumber) - ) - ) - ); - - op.proveWithdrawalTransaction(insufficientGasTx, _proposedOutputIndex, outputRootProof, withdrawalProof); - - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - vm.expectRevert("SafeCall: Not enough gas"); - op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if a sub-call attempts to finalize - /// another withdrawal. - function test_finalizeWithdrawalTransaction_onReentrancy_reverts() external { - uint256 bobBalanceBefore = address(bob).balance; - - // Copy and modify the default test values to attempt a reentrant call by first calling to - // this contract's callPortalAndExpectRevert() function above. - Types.WithdrawalTransaction memory _testTx = _defaultTx; - _testTx.target = address(this); - _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector); - - // Get modified proof inputs. - ( - bytes32 stateRoot, - bytes32 storageRoot, - bytes32 outputRoot, - bytes32 withdrawalHash, - bytes[] memory withdrawalProof - ) = ffi.getProveWithdrawalTransactionInputs(_testTx); - Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({ - version: bytes32(0), - stateRoot: stateRoot, - messagePasserStorageRoot: storageRoot, - latestBlockhash: bytes32(0) - }); - - // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp. - uint256 finalizedTimestamp = block.timestamp - oracle.FINALIZATION_PERIOD_SECONDS() - 1; - vm.mockCall( - address(op.L2_ORACLE()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), - abi.encode(Types.OutputProposal(outputRoot, uint128(finalizedTimestamp), uint128(_proposedBlockNumber))) - ); - - vm.expectEmit(true, true, true, true); - emit WithdrawalProven(withdrawalHash, alice, address(this)); - op.proveWithdrawalTransaction(_testTx, _proposedBlockNumber, outputRootProof, withdrawalProof); - - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - vm.expectCall(address(this), _testTx.data); - vm.expectEmit(true, true, true, true); - emit WithdrawalFinalized(withdrawalHash, true); - op.finalizeWithdrawalTransaction(_testTx); - - // Ensure that bob's balance was not changed by the reentrant call. - assert(address(bob).balance == bobBalanceBefore); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` succeeds. - function testDiff_finalizeWithdrawalTransaction_succeeds( - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes memory _data - ) - external - { - vm.assume( - _target != address(op) // Cannot call the optimism portal or a contract - && _target.code.length == 0 // No accounts with code - && _target != CONSOLE // The console has no code but behaves like a contract - && uint160(_target) > 9 // No precompiles (or zero address) - ); - - // Total ETH supply is currently about 120M ETH. - uint256 value = bound(_value, 0, 200_000_000 ether); - vm.deal(address(op), value); - - uint256 gasLimit = bound(_gasLimit, 0, 50_000_000); - uint256 nonce = messagePasser.messageNonce(); - - // Get a withdrawal transaction and mock proof from the differential testing script. - Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({ - nonce: nonce, - sender: _sender, - target: _target, - value: value, - gasLimit: gasLimit, - data: _data - }); - ( - bytes32 stateRoot, - bytes32 storageRoot, - bytes32 outputRoot, - bytes32 withdrawalHash, - bytes[] memory withdrawalProof - ) = ffi.getProveWithdrawalTransactionInputs(_tx); - - // Create the output root proof - Types.OutputRootProof memory proof = Types.OutputRootProof({ - version: bytes32(uint256(0)), - stateRoot: stateRoot, - messagePasserStorageRoot: storageRoot, - latestBlockhash: bytes32(uint256(0)) - }); - - // Ensure the values returned from ffi are correct - assertEq(outputRoot, Hashing.hashOutputRootProof(proof)); - assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx)); - - // Setup the Oracle to return the outputRoot - vm.mockCall( - address(oracle), - abi.encodeWithSelector(oracle.getL2Output.selector), - abi.encode(outputRoot, block.timestamp, 100) - ); - - // Prove the withdrawal transaction - op.proveWithdrawalTransaction( - _tx, - 100, // l2BlockNumber - proof, - withdrawalProof - ); - (bytes32 _root,,) = op.provenWithdrawals(withdrawalHash); - assertTrue(_root != bytes32(0)); - - // Warp past the finalization period - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - - // Finalize the withdrawal transaction - vm.expectCallMinGas(_tx.target, _tx.value, uint64(_tx.gasLimit), _tx.data); - op.finalizeWithdrawalTransaction(_tx); - assertTrue(op.finalizedWithdrawals(withdrawalHash)); - } -} - -contract OptimismPortalUpgradeable_Test is Portal_Initializer { - Proxy internal proxy; - uint64 initialBlockNum; - - /// @dev Sets up the test. - function setUp() public override { - super.setUp(); - initialBlockNum = uint64(block.number); - proxy = Proxy(payable(address(op))); - } - - /// @dev Tests that the proxy is initialized correctly. - function test_params_initValuesOnProxy_succeeds() external { - OptimismPortal p = OptimismPortal(payable(address(proxy))); - - (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = p.params(); - - ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); - assertEq(prevBaseFee, rcfg.minimumBaseFee); - assertEq(prevBoughtGas, 0); - assertEq(prevBlockNum, initialBlockNum); - } - - /// @dev Tests that the proxy cannot be initialized twice. - function test_initialize_cannotInitProxy_reverts() external { - vm.expectRevert("Initializable: contract is already initialized"); - OptimismPortal(payable(proxy)).initialize({ - _l2Oracle: L2OutputOracle(address(0)), - _systemConfig: SystemConfig(address(0)), - _guardian: address(0), - _paused: false - }); - } - - /// @dev Tests that the implementation cannot be initialized twice. - function test_initialize_cannotInitImpl_reverts() external { - vm.expectRevert("Initializable: contract is already initialized"); - OptimismPortal(opImpl).initialize({ - _l2Oracle: L2OutputOracle(address(0)), - _systemConfig: SystemConfig(address(0)), - _guardian: address(0), - _paused: false - }); - } - - /// @dev Tests that the proxy can be upgraded. - function test_upgradeToAndCall_upgrading_succeeds() external { - // Check an unused slot before upgrading. - bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21))); - assertEq(bytes32(0), slot21Before); - - NextImpl nextImpl = new NextImpl(); - vm.startPrank(multisig); - // The value passed to the initialize must be larger than the last value - // that initialize was called with. - proxy.upgradeToAndCall( - address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, Constants.INITIALIZER + 1) - ); - assertEq(proxy.implementation(), address(nextImpl)); - - // Verify that the NextImpl contract initialized its values according as expected - bytes32 slot21After = vm.load(address(op), bytes32(uint256(21))); - bytes32 slot21Expected = NextImpl(address(op)).slot21Init(); - assertEq(slot21Expected, slot21After); - } -} - -/// @title OptimismPortalResourceFuzz_Test -/// @dev Test various values of the resource metering config to ensure that deposits cannot be -/// broken by changing the config. -contract OptimismPortalResourceFuzz_Test is Portal_Initializer { - /// @dev The max gas limit observed throughout this test. Setting this too high can cause - /// the test to take too long to run. - uint256 constant MAX_GAS_LIMIT = 30_000_000; - - /// @dev Test that various values of the resource metering config will not break deposits. - function testFuzz_systemConfigDeposit_succeeds( - uint32 _maxResourceLimit, - uint8 _elasticityMultiplier, - uint8 _baseFeeMaxChangeDenominator, - uint32 _minimumBaseFee, - uint32 _systemTxMaxGas, - uint128 _maximumBaseFee, - uint64 _gasLimit, - uint64 _prevBoughtGas, - uint128 _prevBaseFee, - uint8 _blockDiff - ) - external - { - // Get the set system gas limit - uint64 gasLimit = systemConfig.gasLimit(); - // Bound resource config - _maxResourceLimit = uint32(bound(_maxResourceLimit, 21000, MAX_GAS_LIMIT / 8)); - _gasLimit = uint64(bound(_gasLimit, 21000, _maxResourceLimit)); - _prevBaseFee = uint128(bound(_prevBaseFee, 0, 3 gwei)); - // Prevent values that would cause reverts - vm.assume(gasLimit >= _gasLimit); - vm.assume(_minimumBaseFee < _maximumBaseFee); - vm.assume(_baseFeeMaxChangeDenominator > 1); - vm.assume(uint256(_maxResourceLimit) + uint256(_systemTxMaxGas) <= gasLimit); - vm.assume(_elasticityMultiplier > 0); - vm.assume(((_maxResourceLimit / _elasticityMultiplier) * _elasticityMultiplier) == _maxResourceLimit); - _prevBoughtGas = uint64(bound(_prevBoughtGas, 0, _maxResourceLimit - _gasLimit)); - _blockDiff = uint8(bound(_blockDiff, 0, 3)); - // Pick a pseudorandom block number - vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max) + uint256(_blockDiff)); - - // Create a resource config to mock the call to the system config with - ResourceMetering.ResourceConfig memory rcfg = ResourceMetering.ResourceConfig({ - maxResourceLimit: _maxResourceLimit, - elasticityMultiplier: _elasticityMultiplier, - baseFeeMaxChangeDenominator: _baseFeeMaxChangeDenominator, - minimumBaseFee: _minimumBaseFee, - systemTxMaxGas: _systemTxMaxGas, - maximumBaseFee: _maximumBaseFee - }); - vm.mockCall( - address(systemConfig), abi.encodeWithSelector(systemConfig.resourceConfig.selector), abi.encode(rcfg) - ); - - // Set the resource params - uint256 _prevBlockNum = block.number - _blockDiff; - vm.store( - address(op), - bytes32(uint256(1)), - bytes32((_prevBlockNum << 192) | (uint256(_prevBoughtGas) << 128) | _prevBaseFee) - ); - // Ensure that the storage setting is correct - (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = op.params(); - assertEq(prevBaseFee, _prevBaseFee); - assertEq(prevBoughtGas, _prevBoughtGas); - assertEq(prevBlockNum, _prevBlockNum); - - // Do a deposit, should not revert - op.depositTransaction{ gas: MAX_GAS_LIMIT }({ - _to: address(0x20), - _value: 0x40, - _gasLimit: _gasLimit, - _isCreation: false, - _data: hex"" - }); - } -} diff --git a/packages/contracts-bedrock/test/Predeploys.t.sol b/packages/contracts-bedrock/test/Predeploys.t.sol new file mode 100644 index 000000000000..51305bc8ffe2 --- /dev/null +++ b/packages/contracts-bedrock/test/Predeploys.t.sol @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { CommonTest } from "test/setup/CommonTest.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; + +interface IEIP712 { + function DOMAIN_SEPARATOR() external view returns (bytes32); +} + +/// @title PredeploysTest +contract PredeploysTest is CommonTest { + ////////////////////////////////////////////////////// + /// Internal helpers + ////////////////////////////////////////////////////// + + /// @dev Function to compute the expected address of the predeploy implementation + /// in the genesis state. + function _predeployToCodeNamespace(address _addr) internal pure returns (address) { + return address( + uint160(uint256(uint160(_addr)) & 0xffff | uint256(uint160(0xc0D3C0d3C0d3C0D3c0d3C0d3c0D3C0d3c0d30000))) + ); + } + + /// @dev Returns true if the address is a predeploy. + function _isPredeploy(address _addr) internal pure returns (bool) { + return _addr == Predeploys.L2_TO_L1_MESSAGE_PASSER || _addr == Predeploys.L2_CROSS_DOMAIN_MESSENGER + || _addr == Predeploys.L2_STANDARD_BRIDGE || _addr == Predeploys.L2_ERC721_BRIDGE + || _addr == Predeploys.SEQUENCER_FEE_WALLET || _addr == Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY + || _addr == Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY || _addr == Predeploys.L1_BLOCK_ATTRIBUTES + || _addr == Predeploys.GAS_PRICE_ORACLE || _addr == Predeploys.DEPLOYER_WHITELIST || _addr == Predeploys.WETH9 + || _addr == Predeploys.L1_BLOCK_NUMBER || _addr == Predeploys.LEGACY_MESSAGE_PASSER + || _addr == Predeploys.PROXY_ADMIN || _addr == Predeploys.BASE_FEE_VAULT || _addr == Predeploys.L1_FEE_VAULT + || _addr == Predeploys.GOVERNANCE_TOKEN || _addr == Predeploys.SCHEMA_REGISTRY || _addr == Predeploys.EAS; + } + + /// @dev Returns true if the adress is not proxied. + function _notProxied(address _addr) internal pure returns (bool) { + return _addr == Predeploys.LEGACY_ERC20_ETH || _addr == Predeploys.GOVERNANCE_TOKEN || _addr == Predeploys.WETH9 + || _addr == Predeploys.MultiCall3 || _addr == Predeploys.Create2Deployer || _addr == Predeploys.Safe_v130 + || _addr == Predeploys.SafeL2_v130 || _addr == Predeploys.MultiSendCallOnly_v130 + || _addr == Predeploys.SafeSingletonFactory || _addr == Predeploys.DeterministicDeploymentProxy + || _addr == Predeploys.MultiSend_v130 || _addr == Predeploys.Permit2 || _addr == Predeploys.SenderCreator + || _addr == Predeploys.EntryPoint; + } + + /// @dev Tests that the predeploy addresses are set correctly. They have code + /// and the proxied accounts have the correct admin. + function test_predeploysSet_succeeds() external { + uint256 count = 2048; + uint160 prefix = uint160(0x420) << 148; + for (uint256 i = 0; i < count; i++) { + address addr = address(prefix | uint160(i)); + bytes memory code = addr.code; + assertTrue(code.length > 0); + + bool proxied = _notProxied(addr) == false; + bool isPredeploy = _isPredeploy(addr); + + // Skip the accounts that do not have a proxy + if (proxied == false) { + continue; + } + + // Only the defined predeploys have their implementation slot set + if (proxied && isPredeploy) { + assertEq( + EIP1967Helper.getImplementation(addr), + _predeployToCodeNamespace(addr), + string.concat("Implementation mismatch for ", vm.toString(addr)) + ); + } + + // The code is a proxy + assertEq(code, vm.getDeployedCode("Proxy.sol")); + + // All of the defined predeploys have their admin set to the proxy admin + assertEq(EIP1967Helper.getAdmin(addr), Predeploys.PROXY_ADMIN, "Admin mismatch"); + } + } + + /// @dev The domain separator commits to the chainid of the chain + function test_preinstall_permit2_succeeds() external { + bytes32 domainSeparator = IEIP712(Predeploys.Permit2).DOMAIN_SEPARATOR(); + bytes32 typeHash = + keccak256(abi.encodePacked("EIP712Domain(string name,uint256 chainId,address verifyingContract)")); + bytes32 nameHash = keccak256(abi.encodePacked("Permit2")); + uint256 chainId = block.chainid; + bytes memory encoded = abi.encode(typeHash, nameHash, chainId, Predeploys.Permit2); + bytes32 expectedDomainSeparator = keccak256(encoded); + assertEq(domainSeparator, expectedDomainSeparator, "Domain separator mismatch"); + } + + ////////////////////////////////////////////////////// + /// Code Assertion Tests + ////////////////////////////////////////////////////// + + function test_preinstall_multicall3_succeeds() external { + assertEq( + Predeploys.MultiCall3.code, + hex"6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033" + ); + } + + function test_preinstall_create2Deployer_succeeds() external { + assertEq( + Predeploys.Create2Deployer.code, + hex"6080604052600436106100435760003560e01c8063076c37b21461004f578063481286e61461007157806356299481146100ba57806366cfa057146100da57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a366004610327565b6100fa565b005b34801561007d57600080fd5b5061009161008c366004610327565b61014a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100c657600080fd5b506100916100d5366004610349565b61015d565b3480156100e657600080fd5b5061006f6100f53660046103ca565b610172565b61014582826040518060200161010f9061031a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052610183565b505050565b600061015683836102e7565b9392505050565b600061016a8484846102f0565b949350505050565b61017d838383610183565b50505050565b6000834710156101f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b815160000361025f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f60448201526064016101eb565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610156576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f790000000000000060448201526064016101eb565b60006101568383305b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b61014e806104ad83390190565b6000806040838503121561033a57600080fd5b50508035926020909101359150565b60008060006060848603121561035e57600080fd5b8335925060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156103df57600080fd5b8335925060208401359150604084013567ffffffffffffffff8082111561040557600080fd5b818601915086601f83011261041957600080fd5b81358181111561042b5761042b61039b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156104715761047161039b565b8160405282815289602084870101111561048a57600080fd5b826020860160208301376000602084830101528095505050505050925092509256fe608060405234801561001057600080fd5b5061012e806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063249cb3fa14602d575b600080fd5b603c603836600460b1565b604e565b60405190815260200160405180910390f35b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16608857600060aa565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b45b9392505050565b6000806040838503121560c357600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811460ed57600080fd5b80915050925092905056fea26469706673582212205ffd4e6cede7d06a5daf93d48d0541fc68189eeb16608c1999a82063b666eb1164736f6c63430008130033a2646970667358221220fdc4a0fe96e3b21c108ca155438d37c9143fb01278a3c1d274948bad89c564ba64736f6c63430008130033" + ); + } + + function test_preinstall_safev130_succeeds() external { + assertEq( + Predeploys.Safe_v130.code, + hex"6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506127d7565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b81019080803590602001909291908035906020019092919050505061280d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b8101908080359060200190929190505050612894565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506128ac565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612c3e565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d78565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506132b5565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506132da565b005b348015610d3457600080fd5b50610d3d613369565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613512565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613518565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061353a565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff1690602001909291905050506136f8565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613820565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613a12565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613bb1565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bde565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f6f565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ff3565b005b34801561148957600080fd5b50611492614665565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061466f565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614817565b005b3480156116a457600080fd5b506116ad614878565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506148f6565b005b34801561174a57600080fd5b50611753614d29565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612c3e565b5b5050565b611bd2604182614e0590919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614e3f565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614e0590919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614e6e90919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614e6e90919063ffffffff16565b614e6e90919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156126bc5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b61272e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61273b858585855a614e8d565b9050801561278b573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a26127cf565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b600060606127e7868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561282b57600080fd5b506040519080825280601f01601f19166020018201604052801561285e5781602001600182028036833780820191505090505b50905060005b8381101561288957808501548060208302602085010152508080600101915050612864565b508091505092915050565b60076020528060005260406000206000915090505481565b6128b4614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561291e5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612a91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612c46614d62565b600354811115612cbe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612d35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000806000612d928e8e8e8e8e8e8e8e8e8e60055461466f565b905060056000815480929190600101919050555080805190602001209150612dbb8282866132da565b506000612dc6614ed9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612fac578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612e6957fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015612f3b578082015181840152602081019050612f20565b50505050905090810190601f168015612f685780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015612f9357600080fd5b505af1158015612fa7573d6000803e3d6000fd5b505050505b6101f4612fd36109c48b01603f60408d0281612fc457fe5b04614f0a90919063ffffffff16565b015a1015613049576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506130b28f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d146130a7578e6130ad565b6109c45a035b614e8d565b93506130c75a82614f2490919063ffffffff16565b905083806130d6575060008a14155b806130e2575060008814155b613154576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008089111561316e5761316b828b8b8b8b614f44565b90505b84156131b8577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a16131f8565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146132a4578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561328b57600080fd5b505af115801561329f573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111613357576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61336384848484611bbe565b50505050565b6060600060035467ffffffffffffffff8111801561338657600080fd5b506040519080825280602002602001820160405280156133b55781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613509578083838151811061346057fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061341f565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6135858a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508961514a565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146135c3576135c28461564a565b5b6136118787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615679565b600082111561362b5761362982600060018685614f44565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061374f878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a614e8d565b61375857600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156137e55780820151818401526020810190506137ca565b50505050905090810190601f1680156138125780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561383b57600080fd5b5060405190808252806020026020018201604052801561386a5781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561393d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561394857508482105b15613a03578084838151811061395a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506138d3565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613b14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613bc68c8c8c8c8c8c8c8c8c8c8c61466f565b8051906020012090509b9a5050505050505050505050565b613be6614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c505750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613cc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613dc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f77614d62565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613ffb614d62565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156140655750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561409d57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61410f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614210576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561427a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6142ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146143ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561470057fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b61478c614878565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61481f614d62565b6148288161564a565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6148a66125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b6148fe614d62565b806001600354031015614979576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156149e35750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614a55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614b55576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614d2457614d2381612c3e565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614e03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614e185760009050614e39565b6000828402905082848281614e2957fe5b0414614e3457600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614e8357600080fd5b8091505092915050565b6000600180811115614e9b57fe5b836001811115614ea757fe5b1415614ec0576000808551602087018986f49050614ed0565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015614f1a5781614f1c565b825b905092915050565b600082821115614f3357600080fd5b600082840390508091505092915050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614614f815782614f83565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561509b57614fed3a8610614fca573a614fcc565b855b614fdf888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615096576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615140565b6150c0856150b2888a614e6e90919063ffffffff16565b614e0590919063ffffffff16565b91506150cd8482846158b4565b61513f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600454146151c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615239576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156152b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156155b65760008482815181106152d057fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153445750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561537c57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156153b457508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b615426576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506152b9565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461577b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146158b05761583d8260008360015a614e8d565b6158af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d6000811461595b5760208114615963576000935061596e565b81935061596e565b600051158215171593505b505050939250505056fea26469706673582212203874bcf92e1722cc7bfa0cef1a0985cf0dc3485ba0663db3747ccdf1605df53464736f6c63430007060033" + ); + } + + function test_preinstall_safeL2v130_succeeds() external { + assertEq( + Predeploys.SafeL2_v130.code, + hex"6080604052600436106101dc5760003560e01c8063affed0e011610102578063e19a9dd911610095578063f08a032311610064578063f08a032314611647578063f698da2514611698578063f8dc5dd9146116c3578063ffa1ad741461173e57610231565b8063e19a9dd91461139b578063e318b52b146113ec578063e75235b81461147d578063e86637db146114a857610231565b8063cc2f8452116100d1578063cc2f8452146110e8578063d4d9bdcd146111b5578063d8d11f78146111f0578063e009cfde1461132a57610231565b8063affed0e014610d94578063b4faba0914610dbf578063b63e800d14610ea7578063c4ca3a9c1461101757610231565b80635624b25b1161017a5780636a761202116101495780636a761202146109945780637d83297414610b50578063934f3a1114610bbf578063a0e67e2b14610d2857610231565b80635624b25b146107fb5780635ae6bd37146108b9578063610b592514610908578063694e80c31461095957610231565b80632f54bf6e116101b65780632f54bf6e146104d35780633408e4701461053a578063468721a7146105655780635229073f1461067a57610231565b80630d582f131461029e57806312fb68e0146102f95780632d9ad53d1461046c57610231565b36610231573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561023d57600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061027257600080f35b36600080373360601b365260008060143601600080855af13d6000803e80610299573d6000fd5b3d6000f35b3480156102aa57600080fd5b506102f7600480360360408110156102c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506117ce565b005b34801561030557600080fd5b5061046a6004803603608081101561031c57600080fd5b81019080803590602001909291908035906020019064010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103da57600080fd5b8201836020820111156103ec57600080fd5b8035906020019184600183028401116401000000008311171561040e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611bbe565b005b34801561047857600080fd5b506104bb6004803603602081101561048f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612440565b60405180821515815260200191505060405180910390f35b3480156104df57600080fd5b50610522600480360360208110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612512565b60405180821515815260200191505060405180910390f35b34801561054657600080fd5b5061054f6125e4565b6040518082815260200191505060405180910390f35b34801561057157600080fd5b506106626004803603608081101561058857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105cf57600080fd5b8201836020820111156105e157600080fd5b8035906020019184600183028401116401000000008311171561060357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506125f1565b60405180821515815260200191505060405180910390f35b34801561068657600080fd5b506107776004803603608081101561069d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106e457600080fd5b8201836020820111156106f657600080fd5b8035906020019184600183028401116401000000008311171561071857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff1690602001909291905050506126fc565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107bf5780820151818401526020810190506107a4565b50505050905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561080757600080fd5b5061083e6004803603604081101561081e57600080fd5b810190808035906020019092919080359060200190929190505050612732565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561087e578082015181840152602081019050610863565b50505050905090810190601f1680156108ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108c557600080fd5b506108f2600480360360208110156108dc57600080fd5b81019080803590602001909291905050506127b9565b6040518082815260200191505060405180910390f35b34801561091457600080fd5b506109576004803603602081101561092b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506127d1565b005b34801561096557600080fd5b506109926004803603602081101561097c57600080fd5b8101908080359060200190929190505050612b63565b005b610b3860048036036101408110156109ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109f257600080fd5b820183602082011115610a0457600080fd5b80359060200191846001830284011164010000000083111715610a2657600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ab257600080fd5b820183602082011115610ac457600080fd5b80359060200191846001830284011164010000000083111715610ae657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612c9d565b60405180821515815260200191505060405180910390f35b348015610b5c57600080fd5b50610ba960048036036040811015610b7357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612edc565b6040518082815260200191505060405180910390f35b348015610bcb57600080fd5b50610d2660048036036060811015610be257600080fd5b810190808035906020019092919080359060200190640100000000811115610c0957600080fd5b820183602082011115610c1b57600080fd5b80359060200191846001830284011164010000000083111715610c3d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ca057600080fd5b820183602082011115610cb257600080fd5b80359060200191846001830284011164010000000083111715610cd457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612f01565b005b348015610d3457600080fd5b50610d3d612f90565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610d80578082015181840152602081019050610d65565b505050509050019250505060405180910390f35b348015610da057600080fd5b50610da9613139565b6040518082815260200191505060405180910390f35b348015610dcb57600080fd5b50610ea560048036036040811015610de257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610e1f57600080fd5b820183602082011115610e3157600080fd5b80359060200191846001830284011164010000000083111715610e5357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061313f565b005b348015610eb357600080fd5b506110156004803603610100811015610ecb57600080fd5b8101908080359060200190640100000000811115610ee857600080fd5b820183602082011115610efa57600080fd5b80359060200191846020830284011164010000000083111715610f1c57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f6757600080fd5b820183602082011115610f7957600080fd5b80359060200191846001830284011164010000000083111715610f9b57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613161565b005b34801561102357600080fd5b506110d26004803603608081101561103a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561108157600080fd5b82018360208201111561109357600080fd5b803590602001918460018302840111640100000000831117156110b557600080fd5b9091929391929390803560ff16906020019092919050505061331f565b6040518082815260200191505060405180910390f35b3480156110f457600080fd5b506111416004803603604081101561110b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613447565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156111a0578082015181840152602081019050611185565b50505050905001935050505060405180910390f35b3480156111c157600080fd5b506111ee600480360360208110156111d857600080fd5b8101908080359060200190929190505050613639565b005b3480156111fc57600080fd5b50611314600480360361014081101561121457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561125b57600080fd5b82018360208201111561126d57600080fd5b8035906020019184600183028401116401000000008311171561128f57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506137d8565b6040518082815260200191505060405180910390f35b34801561133657600080fd5b506113996004803603604081101561134d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613805565b005b3480156113a757600080fd5b506113ea600480360360208110156113be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b96565b005b3480156113f857600080fd5b5061147b6004803603606081101561140f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613c1a565b005b34801561148957600080fd5b5061149261428c565b6040518082815260200191505060405180910390f35b3480156114b457600080fd5b506115cc60048036036101408110156114cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561151357600080fd5b82018360208201111561152557600080fd5b8035906020019184600183028401116401000000008311171561154757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614296565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561160c5780820151818401526020810190506115f1565b50505050905090810190601f1680156116395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561165357600080fd5b506116966004803603602081101561166a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061443e565b005b3480156116a457600080fd5b506116ad61449f565b6040518082815260200191505060405180910390f35b3480156116cf57600080fd5b5061173c600480360360608110156116e657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061451d565b005b34801561174a57600080fd5b50611753614950565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611793578082015181840152602081019050611778565b50505050905090810190601f1680156117c05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6117d6614989565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156118405750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561187857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6118ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611bba57611bb981612b63565b5b5050565b611bd2604182614a2c90919063ffffffff16565b82511015611c48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b8681101561243457611c648882614a66565b80945081955082965050505060008460ff16141561206d578260001c9450611c96604188614a2c90919063ffffffff16565b8260001c1015611d0e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611d2760208460001c614a9590919063ffffffff16565b1115611d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a01015190508851611dd182611dc360208760001c614a9590919063ffffffff16565b614a9590919063ffffffff16565b1115611e45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015611ee7578082015181840152602081019050611ecc565b50505050905090810190601f168015611f145780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015611f4d578082015181840152602081019050611f32565b50505050905090810190601f168015611f7a5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6020811015611fc357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612066576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b50506122b2565b60018460ff161415612181578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061210a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6122b1565b601e8460ff1611156122495760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612238573d6000803e3d6000fd5b5050506020604051035194506122b0565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156122a3573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156123795750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156123b25750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611c52565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561250b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156125dd5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b60007fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018060200183600181111561266b57fe5b8152602001828103825284818151815260200191508051906020019080838360005b838110156126a857808201518184015260208101905061268d565b50505050905090810190601f1680156126d55780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a16126f285858585614ab4565b9050949350505050565b6000606061270c868686866125f1565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff8111801561275057600080fd5b506040519080825280601f01601f1916602001820160405280156127835781602001600182028036833780820191505090505b50905060005b838110156127ae57808501548060208302602085010152508080600101915050612789565b508091505092915050565b60076020528060005260406000206000915090505481565b6127d9614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156128435750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b6128b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146129b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612b6b614989565b600354811115612be3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612c5a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000606060055433600454604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612d5057fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184810384528e8e82818152602001925080828437600081840152601f19601f820116905080830192505050848103835286818151815260200191508051906020019080838360005b83811015612e0a578082015181840152602081019050612def565b50505050905090810190601f168015612e375780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b83811015612e70578082015181840152602081019050612e55565b50505050905090810190601f168015612e9d5780820380516001836020036101000a031916815260200191505b509f5050505050505050505050505050505060405180910390a1612eca8d8d8d8d8d8d8d8d8d8d8d614c9a565b9150509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b6000600454905060008111612f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612f8a84848484611bbe565b50505050565b6060600060035467ffffffffffffffff81118015612fad57600080fd5b50604051908082528060200260200182016040528015612fdc5781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613130578083838151811061308757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050613046565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6131ac8a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050896151d7565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146131ea576131e9846156d7565b5b6132388787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615706565b60008211156132525761325082600060018685615941565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a9050613376878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615b47565b61337f57600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561340c5780820151818401526020810190506133f1565b50505050905090810190601f1680156134395780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561346257600080fd5b506040519080825280602002602001820160405280156134915781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156135645750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561356f57508482105b1561362a578084838151811061358157fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081806001019250506134fa565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561373b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b60006137ed8c8c8c8c8c8c8c8c8c8c8c614296565b8051906020012090509b9a5050505050505050505050565b61380d614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156138775750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b6138e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146139e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613b9e614989565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613c22614989565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613c8c5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613cc457503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613d36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613e37576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613ea15750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b613f13576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614013576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561432757fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6143b361449f565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b614446614989565b61444f816156d7565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6144cd6125e4565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b614525614989565b8060016003540310156145a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561460a5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b61467c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461477c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1806004541461494b5761494a81612b63565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614a2a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614a3f5760009050614a60565b6000828402905082848281614a5057fe5b0414614a5b57600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614aaa57600080fd5b8091505092915050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015614b7f5750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b614bf1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b614bfe858585855a615b47565b90508015614c4e573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a2614c92565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000806000614cb48e8e8e8e8e8e8e8e8e8e600554614296565b905060056000815480929190600101919050555080805190602001209150614cdd828286612f01565b506000614ce8615b93565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614614ece578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115614d8b57fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015614e5d578082015181840152602081019050614e42565b50505050905090810190601f168015614e8a5780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b158015614eb557600080fd5b505af1158015614ec9573d6000803e3d6000fd5b505050505b6101f4614ef56109c48b01603f60408d0281614ee657fe5b04615bc490919063ffffffff16565b015a1015614f6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a9050614fd48f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008d14614fc9578e614fcf565b6109c45a035b615b47565b9350614fe95a82615bde90919063ffffffff16565b90508380614ff8575060008a14155b80615004575060008814155b615076576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808911156150905761508d828b8b8b8b615941565b90505b84156150da577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8482604051808381526020018281526020019250505060405180910390a161511a565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238482604051808381526020018281526020019250505060405180910390a15b5050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146151c6578073ffffffffffffffffffffffffffffffffffffffff16639327136883856040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b1580156151ad57600080fd5b505af11580156151c1573d6000803e3d6000fd5b505050505b50509b9a5050505050505050505050565b60006004541461524f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b81518111156152c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600181101561533d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b835181101561564357600084828151811061535d57fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156153d15750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561540957503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561544157508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b6154b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146155b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550809250508080600101915050615346565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615808576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461593d576158ca8260008360015a615b47565b61593c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461597e5782615980565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615a98576159ea3a86106159c7573a6159c9565b855b6159dc888a614a9590919063ffffffff16565b614a2c90919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615a93576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615b3d565b615abd85615aaf888a614a9590919063ffffffff16565b614a2c90919063ffffffff16565b9150615aca848284615bfe565b615b3c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600180811115615b5557fe5b836001811115615b6157fe5b1415615b7a576000808551602087018986f49050615b8a565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015615bd45781615bd6565b825b905092915050565b600082821115615bed57600080fd5b600082840390508091505092915050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d60008114615ca55760208114615cad5760009350615cb8565b819350615cb8565b600051158215171593505b505050939250505056fea2646970667358221220047fac33099ca576d1c4f1ac6a8abdb0396e42ad6a397d2cb2f4dc1624cc0c5b64736f6c63430007060033" + ); + } + + function test_preinstall_multisendCallOnlyv130_succeeds() external { + assertEq( + Predeploys.MultiSendCallOnly_v130.code, + hex"60806040526004361061001e5760003560e01c80638d80ff0a14610023575b600080fd5b6100dc6004803603602081101561003957600080fd5b810190808035906020019064010000000081111561005657600080fd5b82018360208201111561006857600080fd5b8035906020019184600183028401116401000000008311171561008a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100de565b005b805160205b8181101561015f578083015160f81c6001820184015160601c60158301850151603584018601516055850187016000856000811461012857600181146101385761013d565b6000808585888a5af1915061013d565b600080fd5b50600081141561014c57600080fd5b82605501870196505050505050506100e3565b50505056fea264697066735822122035246402746c96964495cae5b36461fd44dfb89f8e6cf6f6b8d60c0aa89f414864736f6c63430007060033" + ); + } + + function test_preinstall_safeSingletonFactory_succeeds() external { + assertEq( + Predeploys.SafeSingletonFactory.code, + hex"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" + ); + } + + function test_preinstall_deterministicDeploymentProxy_succeeds() external { + assertEq( + Predeploys.DeterministicDeploymentProxy.code, + hex"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" + ); + } + + function test_preinstall_multisendv130_succeeds() external { + assertEq( + Predeploys.MultiSend_v130.code, + hex"60806040526004361061001e5760003560e01c80638d80ff0a14610023575b600080fd5b6100dc6004803603602081101561003957600080fd5b810190808035906020019064010000000081111561005657600080fd5b82018360208201111561006857600080fd5b8035906020019184600183028401116401000000008311171561008a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100de565b005b7f000000000000000000000000998739bfdaadde7c933b942a68053933098f9eda73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161415610183576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806102106030913960400191505060405180910390fd5b805160205b8181101561020a578083015160f81c6001820184015160601c6015830185015160358401860151605585018701600085600081146101cd57600181146101dd576101e8565b6000808585888a5af191506101e8565b6000808585895af491505b5060008114156101f757600080fd5b8260550187019650505050505050610188565b50505056fe4d756c746953656e642073686f756c64206f6e6c792062652063616c6c6564207669612064656c656761746563616c6ca26469706673582212205c784303626eec02b71940b551976170b500a8a36cc5adcbeb2c19751a76d05464736f6c63430007060033" + ); + } + + function test_preinstall_senderCreator_succeeds() external { + assertEq( + Predeploys.SenderCreator.code, + hex"6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033" + ); + } + + function test_preinstall_entrypoint_succeeds() external { + assertEq( + Predeploys.EntryPoint.code, + hex"60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000007fc98430eaedbb6070b35b39d798725049088348165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f0000000000000000000000007fc98430eaedbb6070b35b39d7987250490883481690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f0000000000000000000000007fc98430eaedbb6070b35b39d7987250490883481690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033" + ); + } +} diff --git a/packages/contracts-bedrock/test/PreimageOracle.t.sol b/packages/contracts-bedrock/test/PreimageOracle.t.sol deleted file mode 100644 index 5da715a8e82a..000000000000 --- a/packages/contracts-bedrock/test/PreimageOracle.t.sol +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { Test } from "forge-std/Test.sol"; - -import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; -import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol"; -import "src/cannon/libraries/CannonErrors.sol"; - -contract PreimageOracle_Test is Test { - PreimageOracle oracle; - - /// @notice Sets up the testing suite. - function setUp() public { - oracle = new PreimageOracle(); - vm.label(address(oracle), "PreimageOracle"); - } - - /// @notice Test the pre-image key computation with a known pre-image. - function test_keccak256PreimageKey_succeeds() public { - bytes memory preimage = hex"deadbeef"; - bytes32 key = PreimageKeyLib.keccak256PreimageKey(preimage); - bytes32 known = 0x02fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1; - assertEq(key, known); - } - - /// @notice Tests that context-specific data [0, 24] bytes in length can be loaded correctly. - function test_loadLocalData_onePart_succeeds() public { - uint256 ident = 1; - bytes32 word = bytes32(uint256(0xdeadbeef) << 224); - uint8 size = 4; - uint8 partOffset = 0; - - // Load the local data into the preimage oracle under the test contract's context. - bytes32 contextKey = oracle.loadLocalData(ident, 0, word, size, partOffset); - - // Validate that the pre-image part is set - bool ok = oracle.preimagePartOk(contextKey, partOffset); - assertTrue(ok); - - // Validate the local data part - bytes32 expectedPart = 0x0000000000000004deadbeef0000000000000000000000000000000000000000; - assertEq(oracle.preimageParts(contextKey, partOffset), expectedPart); - - // Validate the local data length - uint256 length = oracle.preimageLengths(contextKey); - assertEq(length, size); - } - - /// @notice Tests that multiple local key contexts can be used by the same address for the - /// same local data identifier. - function test_loadLocalData_multipleContexts_succeeds() public { - uint256 ident = 1; - uint8 size = 4; - uint8 partOffset = 0; - - // Form the words we'll be storing - bytes32[2] memory words = [bytes32(uint256(0xdeadbeef) << 224), bytes32(uint256(0xbeefbabe) << 224)]; - - for (uint256 i; i < words.length; i++) { - // Load the local data into the preimage oracle under the test contract's context - // and the given local context. - bytes32 contextKey = oracle.loadLocalData(ident, i, words[i], size, partOffset); - - // Validate that the pre-image part is set - bool ok = oracle.preimagePartOk(contextKey, partOffset); - assertTrue(ok); - - // Validate the local data part - bytes32 expectedPart = bytes32(uint256(words[i] >> 64) | uint256(size) << 192); - assertEq(oracle.preimageParts(contextKey, partOffset), expectedPart); - - // Validate the local data length - uint256 length = oracle.preimageLengths(contextKey); - assertEq(length, size); - } - } - - /// @notice Tests that context-specific data [0, 32] bytes in length can be loaded correctly. - function testFuzz_loadLocalData_varyingLength_succeeds( - uint256 ident, - uint256 localContext, - bytes32 word, - uint256 size, - uint256 partOffset - ) - public - { - // Bound the size to [0, 32] - size = bound(size, 0, 32); - // Bound the part offset to [0, size + 8] - partOffset = bound(partOffset, 0, size + 8); - - // Load the local data into the preimage oracle under the test contract's context. - bytes32 contextKey = oracle.loadLocalData(ident, localContext, word, uint8(size), uint8(partOffset)); - - // Validate that the first local data part is set - bool ok = oracle.preimagePartOk(contextKey, partOffset); - assertTrue(ok); - // Validate the first local data part - bytes32 expectedPart; - assembly { - mstore(0x20, 0x00) - - mstore(0x00, shl(192, size)) - mstore(0x08, word) - - expectedPart := mload(partOffset) - } - assertEq(oracle.preimageParts(contextKey, partOffset), expectedPart); - - // Validate the local data length - uint256 length = oracle.preimageLengths(contextKey); - assertEq(length, size); - } - - /// @notice Tests that a pre-image is correctly set. - function test_loadKeccak256PreimagePart_succeeds() public { - // Set the pre-image - bytes memory preimage = hex"deadbeef"; - bytes32 key = PreimageKeyLib.keccak256PreimageKey(preimage); - uint256 offset = 0; - oracle.loadKeccak256PreimagePart(offset, preimage); - - // Validate the pre-image part - bytes32 part = oracle.preimageParts(key, offset); - bytes32 expectedPart = 0x0000000000000004deadbeef0000000000000000000000000000000000000000; - assertEq(part, expectedPart); - - // Validate the pre-image length - uint256 length = oracle.preimageLengths(key); - assertEq(length, preimage.length); - - // Validate that the pre-image part is set - bool ok = oracle.preimagePartOk(key, offset); - assertTrue(ok); - } - - /// @notice Tests that a pre-image cannot be set with an out-of-bounds offset. - function test_loadLocalData_outOfBoundsOffset_reverts() public { - bytes32 preimage = bytes32(uint256(0xdeadbeef)); - uint256 offset = preimage.length + 9; - - vm.expectRevert(PartOffsetOOB.selector); - oracle.loadLocalData(1, 0, preimage, 32, offset); - } - - /// @notice Tests that a pre-image cannot be set with an out-of-bounds offset. - function test_loadKeccak256PreimagePart_outOfBoundsOffset_reverts() public { - bytes memory preimage = hex"deadbeef"; - uint256 offset = preimage.length + 9; - - vm.expectRevert(PartOffsetOOB.selector); - oracle.loadKeccak256PreimagePart(offset, preimage); - } - - /// @notice Reading a pre-image part that has not been set should revert. - function testFuzz_readPreimage_missingPreimage_reverts(bytes32 key, uint256 offset) public { - vm.expectRevert("pre-image must exist"); - oracle.readPreimage(key, offset); - } -} diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/Safe/LivenessGuard.t.sol similarity index 96% rename from packages/contracts-bedrock/test/LivenessGuard.t.sol rename to packages/contracts-bedrock/test/Safe/LivenessGuard.t.sol index e1f7cdd761b2..2ea2159d25dc 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/Safe/LivenessGuard.t.sol @@ -47,7 +47,7 @@ contract LivenessGuard_Constructor_Test is LivenessGuard_TestInit { function test_constructor_works() external { address[] memory owners = safeInstance.owners; livenessGuard = new WrappedGuard(safeInstance.safe); - for (uint256 i = 0; i < owners.length; i++) { + for (uint256 i; i < owners.length; i++) { assertEq(livenessGuard.lastLive(owners[i]), initTime); } } @@ -242,7 +242,7 @@ contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, Liveness (address[] memory ownerAddrs, uint256[] memory ownerkeys) = SafeTestLib.makeAddrsAndKeys("safeTest", initialOwners); // record the private keys for later use - for (uint256 i = 0; i < ownerAddrs.length; i++) { + for (uint256 i; i < ownerAddrs.length; i++) { privateKeys[ownerAddrs[i]] = ownerkeys[i]; } @@ -251,7 +251,7 @@ contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, Liveness livenessGuard = new WrappedGuard(safeInstance.safe); safeInstance.setGuard(address(livenessGuard)); - for (uint256 i = 0; i < changes.length; i++) { + for (uint256 i; i < changes.length; i++) { vm.warp(block.timestamp + changes[i].timeDelta); OwnerChange memory change = changes[i]; address[] memory currentOwners = safeInstance.safe.getOwners(); @@ -312,16 +312,16 @@ contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, Liveness // Looks up the private key for each owner uint256[] memory unsortedOwnerPKs = new uint256[](instance.owners.length); - for (uint256 j = 0; j < instance.owners.length; j++) { - unsortedOwnerPKs[j] = privateKeys[instance.owners[j]]; + for (uint256 i; i < instance.owners.length; i++) { + unsortedOwnerPKs[i] = privateKeys[instance.owners[i]]; } // Sort the keys by address and store them in the SafeInstance instance.ownerPKs = SafeTestLib.sortPKsByComputedAddress(unsortedOwnerPKs); // Overwrite the SafeInstances owners array with the computed addresses from the ownerPKs array - for (uint256 k; k < instance.owners.length; k++) { - instance.owners[k] = SafeTestLib.getAddr(instance.ownerPKs[k]); + for (uint256 i; i < instance.owners.length; i++) { + instance.owners[i] = SafeTestLib.getAddr(instance.ownerPKs[i]); } } } diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/Safe/LivenessModule.t.sol similarity index 91% rename from packages/contracts-bedrock/test/LivenessModule.t.sol rename to packages/contracts-bedrock/test/Safe/LivenessModule.t.sol index adc1af45666c..a1976279c5fc 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/Safe/LivenessModule.t.sol @@ -199,7 +199,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { uint256 numOwners = safeInstance.owners.length; address[] memory ownersToRemove = new address[](numOwners); - for (uint256 i = 0; i < numOwners; i++) { + for (uint256 i; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); @@ -218,7 +218,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { uint256 numOwners = safeInstance.owners.length - 2; address[] memory ownersToRemove = new address[](numOwners); - for (uint256 i = 0; i < numOwners; i++) { + for (uint256 i; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); @@ -236,7 +236,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { uint256 numOwners = safeInstance.owners.length - 1; address[] memory ownersToRemove = new address[](numOwners); - for (uint256 i = 0; i < numOwners; i++) { + for (uint256 i; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); @@ -297,7 +297,7 @@ contract LivenessModule_RemoveOwners_Test is LivenessModule_TestInit { uint256 numOwners = safeInstance.owners.length; address[] memory ownersToRemove = new address[](numOwners); - for (uint256 i = 0; i < numOwners; i++) { + for (uint256 i; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); @@ -323,9 +323,12 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { /// @dev Options for handling the event that the number of owners remaining is less than minOwners enum ShutDownBehavior { - Correct, // Correctly removes the owners and transfers to the shutDown owner - DoesNotTransferToFallbackOwner, // Removes all but one owner, and does not transfer to the shutDown owner - DoesNotRemoveAllOwners // Leaves more than one owner when below minOwners + // Correctly removes the owners and transfers to the shutDown owner + Correct, + // Removes all but one owner, and does not transfer to the shutDown owner + DoesNotTransferToFallbackOwner, + // Leaves more than one owner when below minOwners + DoesNotRemoveAllOwners } /// @dev This contract inherits the storage layout from the LivenessModule_TestInit contract, but we @@ -348,15 +351,12 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // // _numOwners must be at least 4, so that _minOwners can be set to at least 3 by the following bound() call. // Limiting the owner set to 20 helps to keep the runtime of the test reasonable. - console.log("bounding numOwners"); numOwners_ = bound(_numOwners, 4, 20); // _minOwners must be at least 3, otherwise we don't have any range below _minOwners in which to test all of the // ShutDownBehavior options. - console.log("bounding minOwners"); minOwners_ = bound(_minOwners, 3, numOwners_ - 1); // Ensure that _numLiveOwners is less than _numOwners so that we can remove at least one owner. - console.log("bounding numLiveOwners"); numLiveOwners_ = bound(_numLiveOwners, 0, numOwners_ - 1); // The above bounds are a bit tricky, so we assert that the resulting parameters enable us to test all possible @@ -374,12 +374,12 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { safeInstance = _setupSafe(keys, threshold); livenessGuard = new LivenessGuard(safeInstance.safe); livenessModule = new LivenessModule({ - _safe: safeInstance.safe, - _livenessGuard: livenessGuard, - _livenessInterval: livenessInterval, - _minOwners: minOwners_, - _fallbackOwner: fallbackOwner - }); + _safe: safeInstance.safe, + _livenessGuard: livenessGuard, + _livenessInterval: livenessInterval, + _minOwners: minOwners_, + _fallbackOwner: fallbackOwner + }); safeInstance.setGuard(address(livenessGuard)); safeInstance.enableModule(address(livenessModule)); @@ -402,20 +402,19 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // Create an array of live owners, and call showLiveness for each of them address[] memory liveOwners = new address[](numLiveOwners); - for (uint256 i = 0; i < numLiveOwners; i++) { + for (uint256 i; i < numLiveOwners; i++) { liveOwners[i] = safeInstance.owners[i]; vm.prank(safeInstance.owners[i]); livenessGuard.showLiveness(); } address[] memory nonLiveOwners = new address[](numOwners - numLiveOwners); - for (uint256 i = 0; i < numOwners - numLiveOwners; i++) { + for (uint256 i; i < numOwners - numLiveOwners; i++) { nonLiveOwners[i] = safeInstance.owners[i + numLiveOwners]; } address[] memory prevOwners; if (numLiveOwners >= minOwners) { - console.log("No shutdown"); // The safe will remain above the minimum number of owners, so we can remove only those owners which are not // live. prevOwners = safeInstance.getPrevOwners(nonLiveOwners); @@ -424,10 +423,10 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // Validate the resulting state of the Safe assertEq(safeInstance.safe.getOwners().length, numLiveOwners); assertEq(safeInstance.safe.getThreshold(), get75PercentThreshold(numLiveOwners)); - for (uint256 i = 0; i < numLiveOwners; i++) { + for (uint256 i; i < numLiveOwners; i++) { assertTrue(safeInstance.safe.isOwner(liveOwners[i])); } - for (uint256 i = 0; i < nonLiveOwners.length; i++) { + for (uint256 i; i < nonLiveOwners.length; i++) { assertFalse(safeInstance.safe.isOwner(nonLiveOwners[i])); } } else { @@ -439,14 +438,10 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // The safe is below the minimum number of owners. // The ShutDownBehavior enum determines how we handle this case. if (shutDownBehavior == ShutDownBehavior.Correct) { - console.log("Correct Shutdown"); // We remove all owners, and transfer ownership to the shutDown owner. // but we need to do remove the non-live owners first, so we reverse the owners array, since // the first owners in the array were the ones to call showLiveness. - // ownersToRemove = new address[](numOwners); - for (uint256 i = 0; i < numOwners; i++) { - // ownersToRemove[numOwners - i - 1] = safeInstance.owners[i]; - // ownersToRemove[i] = safeInstance.owners[numOwners - i - 1]; + for (uint256 i; i < numOwners; i++) { ownersToRemove.push(safeInstance.owners[numOwners - i - 1]); } prevOwners = safeInstance.getPrevOwners(ownersToRemove); @@ -461,14 +456,11 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // trigger that behavior. We initialize that value here then set it in the if statements below. uint256 numOwnersToRemoveinShutDown; if (shutDownBehavior == ShutDownBehavior.DoesNotRemoveAllOwners) { - console.log("Shutdown DoesNotRemoveAllOwners"); // In the DoesNotRemoveAllOwners case, we should have more than 1 of the pre-existing owners // remaining - console.log("bounding numOwnersToRemoveinShutDown"); numOwnersToRemoveinShutDown = bound(_numOwnersToRemoveinShutDown, numOwners - minOwners + 1, numOwners - 2); - uint256 i = 0; - for (i; i < numOwnersToRemoveinShutDown; i++) { + for (uint256 i; i < numOwnersToRemoveinShutDown; i++) { // Add non-live owners to remove first if (i < nonLiveOwners.length) { ownersToRemove.push(nonLiveOwners[i]); @@ -483,11 +475,9 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { ); livenessModule.removeOwners(prevOwners, ownersToRemove); } else if (shutDownBehavior == ShutDownBehavior.DoesNotTransferToFallbackOwner) { - console.log("Shutdown DoesNotTransferToFallbackOwner"); // In the DoesNotRemoveAllOwners case, we should have exactly 1 pre-existing owners remaining numOwnersToRemoveinShutDown = numOwners - 1; - uint256 i = 0; - for (i; i < numOwnersToRemoveinShutDown; i++) { + for (uint256 i; i < numOwnersToRemoveinShutDown; i++) { // Add non-live owners to remove first if (i < nonLiveOwners.length) { ownersToRemove.push(nonLiveOwners[i]); @@ -503,8 +493,8 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // For both of the incorrect behaviors, verify no change to the Safe state assertEq(safeInstance.safe.getOwners().length, numOwners); assertEq(safeInstance.safe.getThreshold(), get75PercentThreshold(numOwners)); - for (uint256 j = 0; j < numOwners; j++) { - assertTrue(safeInstance.safe.isOwner(safeInstance.owners[j])); + for (uint256 i; i < numOwners; i++) { + assertTrue(safeInstance.safe.isOwner(safeInstance.owners[i])); } } } diff --git a/packages/contracts-bedrock/test/SafeSigners.t.sol b/packages/contracts-bedrock/test/Safe/SafeSigners.t.sol similarity index 98% rename from packages/contracts-bedrock/test/SafeSigners.t.sol rename to packages/contracts-bedrock/test/Safe/SafeSigners.t.sol index b79386a52238..d94d91382fa3 100644 --- a/packages/contracts-bedrock/test/SafeSigners.t.sol +++ b/packages/contracts-bedrock/test/Safe/SafeSigners.t.sol @@ -40,7 +40,7 @@ contract SafeSigners_Test is Test, SafeTestTools { uint256 numSigs = bound(_numSigs, 1, 25); (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys("getSigsTest", numSigs); - for (uint256 i = 0; i < keys.length; i++) { + for (uint256 i; i < keys.length; i++) { if (sigType(keys[i]) == SigTypes.Contract) { keys[i] = SafeTestLib.encodeSmartContractWalletAsPK(SafeTestLib.decodeSmartContractWalletAsAddress(keys[i])); @@ -91,7 +91,7 @@ contract SafeSigners_Test is Test, SafeTestTools { // the validation checks that the Safe contract performs on the value of s on contract // signatures. The Safe contract checks that s correctly points to additional data appended // after the signatures, and that the length of the data is within bounds. - for (uint256 i = 0; i < contractSigs; i++) { + for (uint256 i; i < contractSigs; i++) { signatures = bytes.concat(signatures, abi.encode(32, 1)); } diff --git a/packages/contracts-bedrock/test/Semver.t.sol b/packages/contracts-bedrock/test/Semver.t.sol deleted file mode 100644 index 08d0dae64f06..000000000000 --- a/packages/contracts-bedrock/test/Semver.t.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { CommonTest } from "test/CommonTest.t.sol"; -import { Semver } from "src/universal/Semver.sol"; -import { Proxy } from "src/universal/Proxy.sol"; - -/// @notice Test the Semver contract that is used for semantic versioning -/// of various contracts. -contract Semver_Test is CommonTest { - /// @notice Global semver contract deployed in setUp. This is used in - /// the test cases. - Semver semver; - - /// @notice Deploy a Semver contract - function setUp() public virtual override { - semver = new Semver(7, 8, 0); - } - - /// @notice Test the version getter - function test_version_succeeds() external { - assertEq(semver.version(), "7.8.0"); - } - - /// @notice Since the versions are all immutable, they should - /// be able to be accessed from behind a proxy without needing - /// to initialize the contract. - function test_behindProxy_succeeds() external { - Proxy proxy = new Proxy(alice); - vm.prank(alice); - proxy.upgradeTo(address(semver)); - - assertEq(Semver(address(proxy)).version(), "7.8.0"); - } -} diff --git a/packages/contracts-bedrock/test/SequencerFeeVault.t.sol b/packages/contracts-bedrock/test/SequencerFeeVault.t.sol deleted file mode 100644 index 9c6b391a9194..000000000000 --- a/packages/contracts-bedrock/test/SequencerFeeVault.t.sol +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { FeeVault_Initializer, Reverter } from "test/CommonTest.t.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; - -// Libraries -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract dependencies -import { FeeVault } from "src/universal/FeeVault.sol"; - -// Target contract -import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; - -contract SequencerFeeVault_Test is FeeVault_Initializer { - /// @dev Sets up the test suite. - function setUp() public override { - super.setUp(); - vm.etch( - Predeploys.SEQUENCER_FEE_WALLET, - address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1)).code - ); - vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault"); - } - - /// @dev Tests that the minimum withdrawal amount is correct. - function test_minWithdrawalAmount_succeeds() external { - assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), NON_ZERO_VALUE); - } - - /// @dev Tests that the l1 fee wallet is correct. - function test_constructor_succeeds() external { - assertEq(vault.l1FeeWallet(), recipient); - } - - /// @dev Tests that the fee vault is able to receive ETH. - function test_receive_succeeds() external { - uint256 balance = address(vault).balance; - - vm.prank(alice); - (bool success,) = address(vault).call{ value: 100 }(hex""); - - assertEq(success, true); - assertEq(address(vault).balance, balance + 100); - } - - /// @dev Tests that `withdraw` reverts if the balance is less than the minimum - /// withdrawal amount. - function test_withdraw_notEnough_reverts() external { - assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT()); - - vm.expectRevert("FeeVault: withdrawal amount must be greater than minimum withdrawal amount"); - vault.withdraw(); - } - - /// @dev Tests that `withdraw` successfully initiates a withdrawal to L1. - function test_withdraw_toL1_succeeds() external { - uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1; - vm.deal(address(vault), amount); - - // No ether has been withdrawn yet - assertEq(vault.totalProcessed(), 0); - - vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); - emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this)); - vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); - emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this), FeeVault.WithdrawalNetwork.L1); - - // The entire vault's balance is withdrawn - vm.expectCall( - Predeploys.L2_STANDARD_BRIDGE, - address(vault).balance, - abi.encodeWithSelector(StandardBridge.bridgeETHTo.selector, vault.l1FeeWallet(), 35_000, bytes("")) - ); - - vault.withdraw(); - - // The withdrawal was successful - assertEq(vault.totalProcessed(), amount); - assertEq(address(vault).balance, ZERO_VALUE); - assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, amount); - } -} - -contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer { - /// @dev Sets up the test suite. - function setUp() public override { - super.setUp(); - vm.etch( - Predeploys.SEQUENCER_FEE_WALLET, - address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L2)).code - ); - vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault"); - } - - /// @dev Tests that `withdraw` successfully initiates a withdrawal to L2. - function test_withdraw_toL2_succeeds() external { - uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1; - vm.deal(address(vault), amount); - - // No ether has been withdrawn yet - assertEq(vault.totalProcessed(), 0); - - vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); - emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this)); - vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); - emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this), FeeVault.WithdrawalNetwork.L2); - - // The entire vault's balance is withdrawn - vm.expectCall(recipient, address(vault).balance, bytes("")); - - vault.withdraw(); - - // The withdrawal was successful - assertEq(vault.totalProcessed(), amount); - assertEq(address(vault).balance, ZERO_VALUE); - assertEq(recipient.balance, amount); - } - - /// @dev Tests that `withdraw` fails if the Recipient reverts. This also serves to simulate - /// a situation where insufficient gas is provided to the RECIPIENT. - function test_withdraw_toL2recipientReverts_fails() external { - uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT(); - - vm.deal(address(vault), amount); - // No ether has been withdrawn yet - assertEq(vault.totalProcessed(), 0); - - // Ensure the RECIPIENT reverts - vm.etch(vault.RECIPIENT(), type(Reverter).runtimeCode); - - // The entire vault's balance is withdrawn - vm.expectCall(recipient, address(vault).balance, bytes("")); - vm.expectRevert("FeeVault: failed to send ETH to L2 fee recipient"); - vault.withdraw(); - assertEq(vault.totalProcessed(), 0); - } -} diff --git a/packages/contracts-bedrock/test/Specs.t.sol b/packages/contracts-bedrock/test/Specs.t.sol new file mode 100644 index 000000000000..ee6747fbff85 --- /dev/null +++ b/packages/contracts-bedrock/test/Specs.t.sol @@ -0,0 +1,537 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import { CommonTest } from "test/setup/CommonTest.sol"; +import { Executables } from "scripts/Executables.sol"; +import { console2 as console } from "forge-std/console2.sol"; +import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { DataAvailabilityChallenge } from "src/L1/DataAvailabilityChallenge.sol"; +import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol"; + +/// @title Specification_Test +/// @dev Specifies common security properties of entrypoints to L1 contracts, including authorization and +/// pausability. +/// When adding new functions to the L1 system, the `setUp` function must be updated to document the security +/// properties of the new function. The `Spec` struct reppresents this documentation. However, this contract does +/// not actually test to verify these properties, only that a spec is defined. +contract Specification_Test is CommonTest { + struct AbiEntry { + string fnName; + bytes4 sel; + } + + struct Abi { + string contractName; + AbiEntry[] entries; + } + + enum Role { + NOAUTH, + PROPOSER, + CHALLENGER, + SYSTEMCONFIGOWNER, + GUARDIAN, + MESSENGER, + L1PROXYADMINOWNER, + GOVERNANCETOKENOWNER, + MINTMANAGEROWNER, + DATAAVAILABILITYCHALLENGEOWNER + } + + /// @notice Represents the specification of a function. + /// @custom:field name Contract name + /// @custom:field sel Function selector + /// @custom:field auth Specifies authentication as a requirement + /// @custom:field pausable Specifies that the function is pausable + struct Spec { + string name; + bytes4 sel; + Role auth; + bool pausable; + } + + mapping(string => mapping(bytes4 => Spec)) specs; + mapping(string => uint256) public numEntries; + + function setUp() public override { + super.setUp(); + + // DataAvailabilityChallenge + _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("owner()") }); + _addSpec({ + _name: "DataAvailabilityChallenge", + _sel: _getSel("renounceOwnership()"), + _auth: Role.DATAAVAILABILITYCHALLENGEOWNER + }); + _addSpec({ + _name: "DataAvailabilityChallenge", + _sel: _getSel("transferOwnership(address)"), + _auth: Role.DATAAVAILABILITYCHALLENGEOWNER + }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("version()") }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("fixedResolutionCost()") }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("variableResolutionCost()") }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("variableResolutionCostPrecision()") }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("bondSize()") }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("challengeWindow()") }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("resolveWindow()") }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("resolverRefundPercentage()") }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: _getSel("balances(address)") }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.initialize.selector }); + _addSpec({ + _name: "DataAvailabilityChallenge", + _sel: DataAvailabilityChallenge.setBondSize.selector, + _auth: Role.DATAAVAILABILITYCHALLENGEOWNER + }); + _addSpec({ + _name: "DataAvailabilityChallenge", + _sel: DataAvailabilityChallenge.setResolverRefundPercentage.selector, + _auth: Role.DATAAVAILABILITYCHALLENGEOWNER + }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.deposit.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.withdraw.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.getChallenge.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.getChallengeStatus.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.validateCommitment.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.challenge.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.resolve.selector }); + _addSpec({ _name: "DataAvailabilityChallenge", _sel: DataAvailabilityChallenge.unlockBond.selector }); + + // DelayedVetoable + _addSpec({ _name: "DelayedVetoable", _sel: _getSel("delay()") }); + _addSpec({ _name: "DelayedVetoable", _sel: _getSel("initiator()") }); + _addSpec({ _name: "DelayedVetoable", _sel: _getSel("queuedAt(bytes32)") }); + _addSpec({ _name: "DelayedVetoable", _sel: _getSel("target()") }); + _addSpec({ _name: "DelayedVetoable", _sel: _getSel("version()") }); + _addSpec({ _name: "DelayedVetoable", _sel: _getSel("vetoer()") }); + + // L1CrossDomainMessenger + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("MESSAGE_VERSION()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("MIN_GAS_CALLDATA_OVERHEAD()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("OTHER_MESSENGER()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("PORTAL()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("RELAY_CALL_OVERHEAD()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("RELAY_CONSTANT_OVERHEAD()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("RELAY_GAS_CHECK_BUFFER()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("RELAY_RESERVED_GAS()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("baseGas(bytes,uint32)") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("failedMessages(bytes32)") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("initialize(address,address)") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("messageNonce()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("paused()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("otherMessenger()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("portal()") }); + _addSpec({ + _name: "L1CrossDomainMessenger", + _sel: _getSel("relayMessage(uint256,address,address,uint256,uint256,bytes)"), + _pausable: true + }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("sendMessage(address,bytes,uint32)") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("successfulMessages(bytes32)") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("superchainConfig()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("version()") }); + _addSpec({ _name: "L1CrossDomainMessenger", _sel: _getSel("xDomainMessageSender()") }); + + // L1ERC721Bridge + _addSpec({ _name: "L1ERC721Bridge", _sel: _getSel("MESSENGER()") }); + _addSpec({ _name: "L1ERC721Bridge", _sel: _getSel("OTHER_BRIDGE()") }); + _addSpec({ _name: "L1ERC721Bridge", _sel: _getSel("bridgeERC721(address,address,uint256,uint32,bytes)") }); + _addSpec({ + _name: "L1ERC721Bridge", + _sel: _getSel("bridgeERC721To(address,address,address,uint256,uint32,bytes)") + }); + _addSpec({ _name: "L1ERC721Bridge", _sel: _getSel("deposits(address,address,uint256)") }); + _addSpec({ + _name: "L1ERC721Bridge", + _sel: _getSel("finalizeBridgeERC721(address,address,address,address,uint256,bytes)"), + _pausable: true + }); + _addSpec({ _name: "L1ERC721Bridge", _sel: _getSel("messenger()") }); + _addSpec({ _name: "L1ERC721Bridge", _sel: _getSel("otherBridge()") }); + _addSpec({ _name: "L1ERC721Bridge", _sel: _getSel("version()") }); + _addSpec({ _name: "L1ERC721Bridge", _sel: _getSel("superchainConfig()") }); + _addSpec({ _name: "L1ERC721Bridge", _sel: _getSel("paused()") }); + _addSpec({ _name: "L1ERC721Bridge", _sel: _getSel("initialize(address,address)") }); + + // L1StandardBridge + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("MESSENGER()") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("OTHER_BRIDGE()") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("bridgeERC20(address,address,uint256,uint32,bytes)") }); + _addSpec({ + _name: "L1StandardBridge", + _sel: _getSel("bridgeERC20To(address,address,address,uint256,uint32,bytes)") + }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("bridgeETH(uint32,bytes)") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("bridgeETHTo(address,uint32,bytes)") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("depositERC20(address,address,uint256,uint32,bytes)") }); + _addSpec({ + _name: "L1StandardBridge", + _sel: _getSel("depositERC20To(address,address,address,uint256,uint32,bytes)") + }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("depositETH(uint32,bytes)") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("depositETHTo(address,uint32,bytes)") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("deposits(address,address)") }); + _addSpec({ + _name: "L1StandardBridge", + _sel: _getSel("finalizeBridgeERC20(address,address,address,address,uint256,bytes)"), + _auth: Role.MESSENGER, + _pausable: true + }); + _addSpec({ + _name: "L1StandardBridge", + _sel: _getSel("finalizeBridgeETH(address,address,uint256,bytes)"), + _auth: Role.MESSENGER, + _pausable: true + }); + _addSpec({ + _name: "L1StandardBridge", + _sel: _getSel("finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)"), + _auth: Role.MESSENGER, + _pausable: true + }); + _addSpec({ + _name: "L1StandardBridge", + _sel: _getSel("finalizeETHWithdrawal(address,address,uint256,bytes)"), + _auth: Role.MESSENGER, + _pausable: true + }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("initialize(address,address)") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("l2TokenBridge()") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("messenger()") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("otherBridge()") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("paused()") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("superchainConfig()") }); + _addSpec({ _name: "L1StandardBridge", _sel: _getSel("version()") }); + + // L2OutputOracle + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("CHALLENGER()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("FINALIZATION_PERIOD_SECONDS()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("L2_BLOCK_TIME()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("PROPOSER()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("SUBMISSION_INTERVAL()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("challenger()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("computeL2Timestamp(uint256)") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("deleteL2Outputs(uint256)"), _auth: Role.CHALLENGER }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("finalizationPeriodSeconds()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("getL2Output(uint256)") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("getL2OutputAfter(uint256)") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("getL2OutputIndexAfter(uint256)") }); + _addSpec({ + _name: "L2OutputOracle", + _sel: _getSel("initialize(uint256,uint256,uint256,uint256,address,address,uint256)") + }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("l2BlockTime()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("latestBlockNumber()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("latestOutputIndex()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("nextBlockNumber()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("nextOutputIndex()") }); + _addSpec({ + _name: "L2OutputOracle", + _sel: _getSel("proposeL2Output(bytes32,uint256,bytes32,uint256)"), + _auth: Role.PROPOSER + }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("proposer()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("startingBlockNumber()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("startingTimestamp()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("submissionInterval()") }); + _addSpec({ _name: "L2OutputOracle", _sel: _getSel("version()") }); + + // OptimismPortal + _addSpec({ _name: "OptimismPortal", _sel: _getSel("GUARDIAN()") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("L2_ORACLE()") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("SYSTEM_CONFIG()") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("depositTransaction(address,uint256,uint64,bool,bytes)") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("donateETH()") }); + _addSpec({ + _name: "OptimismPortal", + _sel: OptimismPortal.finalizeWithdrawalTransaction.selector, + _pausable: true + }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("finalizedWithdrawals(bytes32)") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("guardian()") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("initialize(address,address,address)") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("isOutputFinalized(uint256)") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("l2Oracle()") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("l2Sender()") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("minimumGasLimit(uint64)") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("params()") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("paused()") }); + _addSpec({ _name: "OptimismPortal", _sel: OptimismPortal.proveWithdrawalTransaction.selector, _pausable: true }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("provenWithdrawals(bytes32)") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("superchainConfig()") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("systemConfig()") }); + _addSpec({ _name: "OptimismPortal", _sel: _getSel("version()") }); + + // OptimismPortal2 + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("GUARDIAN()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("SYSTEM_CONFIG()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("depositTransaction(address,uint256,uint64,bool,bytes)") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("donateETH()") }); + _addSpec({ + _name: "OptimismPortal2", + _sel: OptimismPortal2.finalizeWithdrawalTransaction.selector, + _pausable: true + }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("finalizedWithdrawals(bytes32)") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("guardian()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("initialize(address,address,address)") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("l2Sender()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("minimumGasLimit(uint64)") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("params()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("paused()") }); + _addSpec({ _name: "OptimismPortal2", _sel: OptimismPortal2.proveWithdrawalTransaction.selector, _pausable: true }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("provenWithdrawals(bytes32)") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("superchainConfig()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("systemConfig()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("version()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("disputeGameFactory()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("disputeGameBlacklist(address)") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("respectedGameType()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("blacklistDisputeGame(address)"), _auth: Role.GUARDIAN }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("setRespectedGameType(uint32)"), _auth: Role.GUARDIAN }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("checkWithdrawal(bytes32)") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("proofMaturityDelaySeconds()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("disputeGameFinalityDelaySeconds()") }); + _addSpec({ _name: "OptimismPortal2", _sel: _getSel("respectedGameTypeUpdatedAt()") }); + + // ProtocolVersions + _addSpec({ _name: "ProtocolVersions", _sel: _getSel("RECOMMENDED_SLOT()") }); + _addSpec({ _name: "ProtocolVersions", _sel: _getSel("REQUIRED_SLOT()") }); + _addSpec({ _name: "ProtocolVersions", _sel: _getSel("VERSION()") }); + _addSpec({ _name: "ProtocolVersions", _sel: ProtocolVersions.initialize.selector }); + _addSpec({ _name: "ProtocolVersions", _sel: _getSel("owner()") }); + _addSpec({ _name: "ProtocolVersions", _sel: ProtocolVersions.recommended.selector }); + _addSpec({ _name: "ProtocolVersions", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER }); + _addSpec({ _name: "ProtocolVersions", _sel: ProtocolVersions.required.selector }); + _addSpec({ + _name: "ProtocolVersions", + _sel: ProtocolVersions.setRequired.selector, + _auth: Role.SYSTEMCONFIGOWNER + }); + _addSpec({ + _name: "ProtocolVersions", + _sel: ProtocolVersions.setRecommended.selector, + _auth: Role.SYSTEMCONFIGOWNER + }); + _addSpec({ _name: "ProtocolVersions", _sel: _getSel("transferOwnership(address)") }); + _addSpec({ _name: "ProtocolVersions", _sel: _getSel("version()") }); + + // ResourceMetering + _addSpec({ _name: "ResourceMetering", _sel: _getSel("params()") }); + + // SuperchainConfig + _addSpec({ _name: "SuperchainConfig", _sel: _getSel("GUARDIAN_SLOT()") }); + _addSpec({ _name: "SuperchainConfig", _sel: _getSel("PAUSED_SLOT()") }); + _addSpec({ _name: "SuperchainConfig", _sel: _getSel("guardian()") }); + _addSpec({ _name: "SuperchainConfig", _sel: _getSel("initialize(address,bool)") }); + _addSpec({ _name: "SuperchainConfig", _sel: _getSel("pause(string)"), _auth: Role.GUARDIAN }); + _addSpec({ _name: "SuperchainConfig", _sel: _getSel("paused()") }); + _addSpec({ _name: "SuperchainConfig", _sel: _getSel("unpause()"), _auth: Role.GUARDIAN }); + _addSpec({ _name: "SuperchainConfig", _sel: _getSel("version()") }); + + // SystemConfig + _addSpec({ _name: "SystemConfig", _sel: _getSel("UNSAFE_BLOCK_SIGNER_SLOT()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("START_BLOCK_SLOT()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("VERSION()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("batcherHash()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("gasLimit()") }); + _addSpec({ _name: "SystemConfig", _sel: SystemConfig.initialize.selector }); + _addSpec({ _name: "SystemConfig", _sel: SystemConfig.minimumGasLimit.selector }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("overhead()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("owner()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER }); + _addSpec({ _name: "SystemConfig", _sel: SystemConfig.resourceConfig.selector }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("scalar()") }); + _addSpec({ _name: "SystemConfig", _sel: SystemConfig.setBatcherHash.selector, _auth: Role.SYSTEMCONFIGOWNER }); + _addSpec({ _name: "SystemConfig", _sel: SystemConfig.setGasConfig.selector, _auth: Role.SYSTEMCONFIGOWNER }); + _addSpec({ _name: "SystemConfig", _sel: SystemConfig.setGasLimit.selector, _auth: Role.SYSTEMCONFIGOWNER }); + _addSpec({ _name: "SystemConfig", _sel: SystemConfig.setResourceConfig.selector, _auth: Role.SYSTEMCONFIGOWNER }); + _addSpec({ + _name: "SystemConfig", + _sel: SystemConfig.setUnsafeBlockSigner.selector, + _auth: Role.SYSTEMCONFIGOWNER + }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("transferOwnership(address)"), _auth: Role.SYSTEMCONFIGOWNER }); + _addSpec({ _name: "SystemConfig", _sel: SystemConfig.unsafeBlockSigner.selector }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("version()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("l1CrossDomainMessenger()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("l1ERC721Bridge()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("l1StandardBridge()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("l2OutputOracle()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("optimismPortal()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("optimismMintableERC20Factory()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("batchInbox()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("startBlock()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("L1_CROSS_DOMAIN_MESSENGER_SLOT()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("L1_ERC_721_BRIDGE_SLOT()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("L1_STANDARD_BRIDGE_SLOT()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("L2_OUTPUT_ORACLE_SLOT()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("OPTIMISM_PORTAL_SLOT()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT()") }); + _addSpec({ _name: "SystemConfig", _sel: _getSel("BATCH_INBOX_SLOT()") }); + + // ProxyAdmin + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("addressManager()") }); + _addSpec({ + _name: "ProxyAdmin", + _sel: _getSel("changeProxyAdmin(address,address)"), + _auth: Role.L1PROXYADMINOWNER + }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("getProxyAdmin(address)") }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("getProxyImplementation(address)") }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("implementationName(address)") }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("isUpgrading()") }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("owner()") }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("proxyType(address)") }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("renounceOwnership()"), _auth: Role.L1PROXYADMINOWNER }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("setAddress(string,address)"), _auth: Role.L1PROXYADMINOWNER }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("setAddressManager(address)"), _auth: Role.L1PROXYADMINOWNER }); + _addSpec({ + _name: "ProxyAdmin", + _sel: _getSel("setImplementationName(address,string)"), + _auth: Role.L1PROXYADMINOWNER + }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("setProxyType(address,uint8)"), _auth: Role.L1PROXYADMINOWNER }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("setUpgrading(bool)") }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("transferOwnership(address)"), _auth: Role.L1PROXYADMINOWNER }); + _addSpec({ _name: "ProxyAdmin", _sel: _getSel("upgrade(address,address)") }); + _addSpec({ + _name: "ProxyAdmin", + _sel: _getSel("upgradeAndCall(address,address,bytes)"), + _auth: Role.L1PROXYADMINOWNER + }); + + // GovernanceToken + _addSpec({ _name: "GovernanceToken", _sel: _getSel("DOMAIN_SEPARATOR()") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("allowance(address,address)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("approve(address,uint256)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("balanceOf(address)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("burn(uint256)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("burnFrom(address,uint256)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("checkpoints(address,uint32)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("decimals()") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("decreaseAllowance(address,uint256)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("delegate(address)") }); + _addSpec({ + _name: "GovernanceToken", + _sel: _getSel("delegateBySig(address,uint256,uint256,uint8,bytes32,bytes32)") + }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("delegates(address)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("getPastTotalSupply(uint256)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("getPastVotes(address,uint256)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("getVotes(address)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("increaseAllowance(address,uint256)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("mint(address,uint256)"), _auth: Role.GOVERNANCETOKENOWNER }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("name()") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("nonces(address)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("numCheckpoints(address)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("owner()") }); + _addSpec({ + _name: "GovernanceToken", + _sel: _getSel("permit(address,address,uint256,uint256,uint8,bytes32,bytes32)") + }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("renounceOwnership()") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("symbol()") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("totalSupply()") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("transfer(address,uint256)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("transferFrom(address,address,uint256)") }); + _addSpec({ _name: "GovernanceToken", _sel: _getSel("transferOwnership(address)") }); + + // MintManager + _addSpec({ _name: "MintManager", _sel: _getSel("DENOMINATOR()") }); + _addSpec({ _name: "MintManager", _sel: _getSel("MINT_CAP()") }); + _addSpec({ _name: "MintManager", _sel: _getSel("MINT_PERIOD()") }); + _addSpec({ _name: "MintManager", _sel: _getSel("governanceToken()") }); + _addSpec({ _name: "MintManager", _sel: _getSel("mint(address,uint256)"), _auth: Role.MINTMANAGEROWNER }); + _addSpec({ _name: "MintManager", _sel: _getSel("mintPermittedAfter()") }); + _addSpec({ _name: "MintManager", _sel: _getSel("owner()") }); + _addSpec({ _name: "MintManager", _sel: _getSel("renounceOwnership()"), _auth: Role.MINTMANAGEROWNER }); + _addSpec({ _name: "MintManager", _sel: _getSel("transferOwnership(address)"), _auth: Role.MINTMANAGEROWNER }); + _addSpec({ _name: "MintManager", _sel: _getSel("upgrade(address)"), _auth: Role.MINTMANAGEROWNER }); + } + + /// @dev Computes the selector from a function signature. + function _getSel(string memory _name) internal pure returns (bytes4) { + return bytes4(keccak256(abi.encodePacked(_name))); + } + + /// @dev Adds a spec for a function. + function _addSpec(string memory _name, bytes4 _sel, Role _auth, bool _pausable) internal { + specs[_name][_sel] = Spec({ name: _name, sel: _sel, auth: _auth, pausable: _pausable }); + numEntries[_name]++; + } + + /// @dev Adds a spec for a function with no auth. + function _addSpec(string memory _name, bytes4 _sel, bool _pausable) internal { + _addSpec({ _name: _name, _sel: _sel, _auth: Role.NOAUTH, _pausable: _pausable }); + } + + /// @dev Adds a spec for a function with no pausability. + function _addSpec(string memory _name, bytes4 _sel, Role _auth) internal { + _addSpec({ _name: _name, _sel: _sel, _auth: _auth, _pausable: false }); + } + + /// @dev Adds a spec for a function with no auth and no pausability. + function _addSpec(string memory _name, bytes4 _sel) internal { + _addSpec({ _name: _name, _sel: _sel, _auth: Role.NOAUTH, _pausable: false }); + } + + /// @notice Ensures that there's an auth spec for every L1 contract function. + function testContractAuth() public { + Abi[] memory abis = _getL1ContractFunctionAbis(); + + for (uint256 i = 0; i < abis.length; i++) { + string memory contractName = abis[i].contractName; + assertEq( + abis[i].entries.length, numEntries[contractName], "Specification_Test: invalid number of ABI entries" + ); + + for (uint256 j = 0; j < abis[i].entries.length; j++) { + AbiEntry memory abiEntry = abis[i].entries[j]; + console.log( + "Checking auth spec for %s: %s(%x)", contractName, abiEntry.fnName, uint256(uint32(abiEntry.sel)) + ); + Spec memory spec = specs[contractName][abiEntry.sel]; + assertTrue(spec.sel != bytes4(0), "Specification_Test: missing spec definition"); + assertEq(abiEntry.sel, spec.sel, "Specification_Test: invalid ABI"); + } + } + } + + /// @dev Returns the function ABIs of all L1 contracts. + function _getL1ContractFunctionAbis() internal returns (Abi[] memory abis_) { + string[] memory command = new string[](3); + command[0] = Executables.bash; + command[1] = "-c"; + command[2] = string.concat( + Executables.find, + " src/{L1,governance,universal/ProxyAdmin.sol} -type f -exec basename {} \\;", + " | ", + Executables.sed, + " 's/\\.[^.]*$//'", + " | ", + Executables.jq, + " -R -s 'split(\"\n\")[:-1]'" + ); + string[] memory contractNames = abi.decode(vm.parseJson(string(vm.ffi(command))), (string[])); + + abis_ = new Abi[](contractNames.length); + + for (uint256 i; i < contractNames.length; i++) { + string memory contractName = contractNames[i]; + string[] memory methodIdentifiers = ForgeArtifacts.getMethodIdentifiers(contractName); + abis_[i].contractName = contractName; + abis_[i].entries = new AbiEntry[](methodIdentifiers.length); + for (uint256 j; j < methodIdentifiers.length; j++) { + string memory fnName = methodIdentifiers[j]; + bytes4 sel = bytes4(keccak256(abi.encodePacked(fnName))); + abis_[i].entries[j] = AbiEntry({ fnName: fnName, sel: sel }); + } + } + } +} diff --git a/packages/contracts-bedrock/test/Storage.t.sol b/packages/contracts-bedrock/test/Storage.t.sol deleted file mode 100644 index 62dd2d3d8e41..000000000000 --- a/packages/contracts-bedrock/test/Storage.t.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Target contract -import { Storage } from "src/libraries/Storage.sol"; -import { StorageSetter } from "src/universal/StorageSetter.sol"; -import { Test } from "forge-std/Test.sol"; - -/// @title Storage_Roundtrip_Test -/// @notice Tests the storage setting and getting through the StorageSetter contract. -/// This contract simply wraps the Storage library, this is required as to -/// not poison the storage of the `Test` contract. -contract Storage_Roundtrip_Test is Test { - StorageSetter setter; - - function setUp() external { - setter = new StorageSetter(); - } - - function test_setGetUint_succeeds(bytes32 slot, uint256 num) external { - setter.setUint(slot, num); - assertEq(setter.getUint(slot), num); - assertEq(num, uint256(vm.load(address(setter), slot))); - } - - function test_setGetAddress_succeeds(bytes32 slot, address addr) external { - setter.setAddress(slot, addr); - assertEq(setter.getAddress(slot), addr); - assertEq(addr, address(uint160(uint256(vm.load(address(setter), slot))))); - } - - function test_setGetBytes32_succeeds(bytes32 slot, bytes32 hash) external { - setter.setBytes32(slot, hash); - assertEq(setter.getBytes32(slot), hash); - assertEq(hash, vm.load(address(setter), slot)); - } -} diff --git a/packages/contracts-bedrock/test/SystemConfig.t.sol b/packages/contracts-bedrock/test/SystemConfig.t.sol deleted file mode 100644 index b6cb18cf7d7c..000000000000 --- a/packages/contracts-bedrock/test/SystemConfig.t.sol +++ /dev/null @@ -1,414 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; - -// Libraries -import { Constants } from "src/libraries/Constants.sol"; - -// Target contract dependencies -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { Proxy } from "src/universal/Proxy.sol"; - -// Target contract -import { SystemConfig } from "src/L1/SystemConfig.sol"; - -contract SystemConfig_Init is CommonTest { - SystemConfig sysConf; - SystemConfig systemConfigImpl; - - event ConfigUpdate(uint256 indexed version, SystemConfig.UpdateType indexed updateType, bytes data); - - // Dummy addresses used to test getters - address constant batchInbox = address(0x18); - address constant l1CrossDomainMessenger = address(0x20); - address constant l1ERC721Bridge = address(0x21); - address constant l1StandardBridge = address(0x22); - address constant l2OutputOracle = address(0x23); - address constant optimismPortal = address(0x24); - address constant optimismMintableERC20Factory = address(0x25); - uint256 constant overhead = 2100; - uint256 constant scalar = 1000000; - bytes32 constant batcherHash = bytes32(hex"abcd"); - uint64 constant gasLimit = 30_000_000; - address constant unsafeBlockSigner = address(1); - - function setUp() public virtual override { - super.setUp(); - - Proxy proxy = new Proxy(multisig); - systemConfigImpl = new SystemConfig(); - - vm.prank(multisig); - proxy.upgradeToAndCall( - address(systemConfigImpl), - abi.encodeCall( - SystemConfig.initialize, - ( - alice, // _owner, - overhead, // _overhead, - scalar, // _scalar, - batcherHash, // _batcherHash - gasLimit, // _gasLimit, - unsafeBlockSigner, // _unsafeBlockSigner, - Constants.DEFAULT_RESOURCE_CONFIG(), // _config, - 0, // _startBlock - batchInbox, // _batchInbox - SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: l1CrossDomainMessenger, - l1ERC721Bridge: l1ERC721Bridge, - l1StandardBridge: l1StandardBridge, - l2OutputOracle: l2OutputOracle, - optimismPortal: optimismPortal, - optimismMintableERC20Factory: optimismMintableERC20Factory - }) - ) - ) - ); - - sysConf = SystemConfig(address(proxy)); - } -} - -contract SystemConfig_Initialize_Test is SystemConfig_Init { - /// @dev Tests that initailization sets the correct values. - function test_initialize_values_succeeds() external { - assertEq(sysConf.l1CrossDomainMessenger(), l1CrossDomainMessenger); - assertEq(sysConf.l1ERC721Bridge(), l1ERC721Bridge); - assertEq(sysConf.l1StandardBridge(), l1StandardBridge); - assertEq(sysConf.l2OutputOracle(), l2OutputOracle); - assertEq(sysConf.optimismPortal(), optimismPortal); - assertEq(sysConf.optimismMintableERC20Factory(), optimismMintableERC20Factory); - assertEq(sysConf.batchInbox(), batchInbox); - assertEq(sysConf.owner(), alice); - assertEq(sysConf.overhead(), overhead); - assertEq(sysConf.scalar(), scalar); - assertEq(sysConf.batcherHash(), batcherHash); - assertEq(sysConf.gasLimit(), gasLimit); - assertEq(sysConf.unsafeBlockSigner(), unsafeBlockSigner); - // Depends on start block being set to 0 in `initialize` - assertEq(sysConf.startBlock(), block.number); - // Depends on `initialize` being called with defaults - ResourceMetering.ResourceConfig memory cfg = Constants.DEFAULT_RESOURCE_CONFIG(); - ResourceMetering.ResourceConfig memory actual = sysConf.resourceConfig(); - assertEq(actual.maxResourceLimit, cfg.maxResourceLimit); - assertEq(actual.elasticityMultiplier, cfg.elasticityMultiplier); - assertEq(actual.baseFeeMaxChangeDenominator, cfg.baseFeeMaxChangeDenominator); - assertEq(actual.minimumBaseFee, cfg.minimumBaseFee); - assertEq(actual.systemTxMaxGas, cfg.systemTxMaxGas); - assertEq(actual.maximumBaseFee, cfg.maximumBaseFee); - } - - /// @dev Ensures that the start block override can be used to set the start block. - function test_initialize_startBlockOverride_succeeds() external { - uint256 startBlock = 100; - - // Wipe out the initialized slot so the proxy can be initialized again - vm.store(address(sysConf), bytes32(0), bytes32(0)); - - assertEq(sysConf.startBlock(), block.number); - // the startBlock slot is 106, wipe it out - vm.store(address(sysConf), bytes32(uint256(106)), bytes32(0)); - assertEq(sysConf.startBlock(), 0); - - vm.prank(multisig); - Proxy(payable(address(sysConf))).upgradeToAndCall( - address(systemConfigImpl), - abi.encodeCall( - SystemConfig.initialize, - ( - alice, // _owner, - overhead, // _overhead, - scalar, // _scalar, - batcherHash, // _batcherHash - gasLimit, // _gasLimit, - unsafeBlockSigner, // _unsafeBlockSigner, - Constants.DEFAULT_RESOURCE_CONFIG(), // _config, - startBlock, // _startBlock - batchInbox, // _batchInbox - SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: l1CrossDomainMessenger, - l1ERC721Bridge: l1ERC721Bridge, - l1StandardBridge: l1StandardBridge, - l2OutputOracle: l2OutputOracle, - optimismPortal: optimismPortal, - optimismMintableERC20Factory: optimismMintableERC20Factory - }) - ) - ) - ); - assertEq(sysConf.startBlock(), startBlock); - } - - /// @dev Tests that initialization with start block already set is a noop. - function test_initialize_startBlockNoop_reverts() external { - // wipe out initialized slot so we can initialize again - vm.store(address(sysConf), bytes32(0), bytes32(0)); - // the startBlock slot is 106, set it to something non zero - vm.store(address(sysConf), bytes32(uint256(106)), bytes32(uint256(0xff))); - - // Initialize with a non zero start block, should see a revert - vm.prank(multisig); - // The call to initialize reverts due to: "SystemConfig: cannot override an already set start block" - // but the proxy revert message bubbles up. - Proxy(payable(address(sysConf))).upgradeToAndCall( - address(systemConfigImpl), - abi.encodeCall( - SystemConfig.initialize, - ( - alice, // _owner, - overhead, // _overhead, - scalar, // _scalar, - batcherHash, // _batcherHash - gasLimit, // _gasLimit, - unsafeBlockSigner, // _unsafeBlockSigner, - Constants.DEFAULT_RESOURCE_CONFIG(), // _config, - 1, // _startBlock - batchInbox, // _batchInbox - SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: l1CrossDomainMessenger, - l1ERC721Bridge: l1ERC721Bridge, - l1StandardBridge: l1StandardBridge, - l2OutputOracle: l2OutputOracle, - optimismPortal: optimismPortal, - optimismMintableERC20Factory: optimismMintableERC20Factory - }) - ) - ) - ); - - // It was initialized with 1 but it was already set so the override - // should be ignored. - uint256 startBlock = sysConf.startBlock(); - assertEq(startBlock, 0xff); - } - - /// @dev Ensures that the events are emitted during initialization. - function test_initialize_events_succeeds() external { - // Wipe out the initialized slot so the proxy can be initialized again - vm.store(address(sysConf), bytes32(0), bytes32(0)); - vm.store(address(sysConf), bytes32(uint256(106)), bytes32(0)); - assertEq(sysConf.startBlock(), 0); - - // The order depends here - vm.expectEmit(true, true, true, true, address(sysConf)); - emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(batcherHash)); - vm.expectEmit(true, true, true, true, address(sysConf)); - emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(overhead, scalar)); - vm.expectEmit(true, true, true, true, address(sysConf)); - emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(gasLimit)); - vm.expectEmit(true, true, true, true, address(sysConf)); - emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(unsafeBlockSigner)); - - vm.prank(multisig); - Proxy(payable(address(sysConf))).upgradeToAndCall( - address(systemConfigImpl), - abi.encodeCall( - SystemConfig.initialize, - ( - alice, // _owner, - overhead, // _overhead, - scalar, // _scalar, - batcherHash, // _batcherHash - gasLimit, // _gasLimit, - unsafeBlockSigner, // _unsafeBlockSigner, - Constants.DEFAULT_RESOURCE_CONFIG(), // _config, - 0, // _startBlock - batchInbox, // _batchInbox - SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: l1CrossDomainMessenger, - l1ERC721Bridge: l1ERC721Bridge, - l1StandardBridge: l1StandardBridge, - l2OutputOracle: l2OutputOracle, - optimismPortal: optimismPortal, - optimismMintableERC20Factory: optimismMintableERC20Factory - }) - ) - ) - ); - } -} - -contract SystemConfig_Initialize_TestFail is SystemConfig_Init { - /// @dev Tests that initialization reverts if the gas limit is too low. - function test_initialize_lowGasLimit_reverts() external { - uint64 minimumGasLimit = sysConf.minimumGasLimit(); - - // Wipe out the initialized slot so the proxy can be initialized again - vm.store(address(sysConf), bytes32(0), bytes32(0)); - vm.prank(multisig); - // The call to initialize reverts due to: "SystemConfig: gas limit too low" - // but the proxy revert message bubbles up. - vm.expectRevert("Proxy: delegatecall to new implementation contract failed"); - Proxy(payable(address(sysConf))).upgradeToAndCall( - address(systemConfigImpl), - abi.encodeCall( - SystemConfig.initialize, - ( - alice, // _owner, - 2100, // _overhead, - 1000000, // _scalar, - bytes32(hex"abcd"), // _batcherHash, - minimumGasLimit - 1, // _gasLimit, - address(1), // _unsafeBlockSigner, - Constants.DEFAULT_RESOURCE_CONFIG(), // _config, - 0, // _startBlock - address(0), // _batchInbox - SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: address(0), - l1ERC721Bridge: address(0), - l1StandardBridge: address(0), - l2OutputOracle: address(0), - optimismPortal: address(0), - optimismMintableERC20Factory: address(0) - }) - ) - ) - ); - } -} - -contract SystemConfig_Setters_TestFail is SystemConfig_Init { - /// @dev Tests that `setBatcherHash` reverts if the caller is not the owner. - function test_setBatcherHash_notOwner_reverts() external { - vm.expectRevert("Ownable: caller is not the owner"); - sysConf.setBatcherHash(bytes32(hex"")); - } - - /// @dev Tests that `setGasConfig` reverts if the caller is not the owner. - function test_setGasConfig_notOwner_reverts() external { - vm.expectRevert("Ownable: caller is not the owner"); - sysConf.setGasConfig(0, 0); - } - - /// @dev Tests that `setGasLimit` reverts if the caller is not the owner. - function test_setGasLimit_notOwner_reverts() external { - vm.expectRevert("Ownable: caller is not the owner"); - sysConf.setGasLimit(0); - } - - /// @dev Tests that `setUnsafeBlockSigner` reverts if the caller is not the owner. - function test_setUnsafeBlockSigner_notOwner_reverts() external { - vm.expectRevert("Ownable: caller is not the owner"); - sysConf.setUnsafeBlockSigner(address(0x20)); - } - - /// @dev Tests that `setResourceConfig` reverts if the caller is not the owner. - function test_setResourceConfig_notOwner_reverts() external { - ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG(); - vm.expectRevert("Ownable: caller is not the owner"); - sysConf.setResourceConfig(config); - } - - /// @dev Tests that `setResourceConfig` reverts if the min base fee - /// is greater than the maximum allowed base fee. - function test_setResourceConfig_badMinMax_reverts() external { - ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ - maxResourceLimit: 20_000_000, - elasticityMultiplier: 10, - baseFeeMaxChangeDenominator: 8, - systemTxMaxGas: 1_000_000, - minimumBaseFee: 2 gwei, - maximumBaseFee: 1 gwei - }); - vm.prank(sysConf.owner()); - vm.expectRevert("SystemConfig: min base fee must be less than max base"); - sysConf.setResourceConfig(config); - } - - /// @dev Tests that `setResourceConfig` reverts if the baseFeeMaxChangeDenominator - /// is zero. - function test_setResourceConfig_zeroDenominator_reverts() external { - ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ - maxResourceLimit: 20_000_000, - elasticityMultiplier: 10, - baseFeeMaxChangeDenominator: 0, - systemTxMaxGas: 1_000_000, - minimumBaseFee: 1 gwei, - maximumBaseFee: 2 gwei - }); - vm.prank(sysConf.owner()); - vm.expectRevert("SystemConfig: denominator must be larger than 1"); - sysConf.setResourceConfig(config); - } - - /// @dev Tests that `setResourceConfig` reverts if the gas limit is too low. - function test_setResourceConfig_lowGasLimit_reverts() external { - uint64 gasLimit = sysConf.gasLimit(); - - ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ - maxResourceLimit: uint32(gasLimit), - elasticityMultiplier: 10, - baseFeeMaxChangeDenominator: 8, - systemTxMaxGas: uint32(gasLimit), - minimumBaseFee: 1 gwei, - maximumBaseFee: 2 gwei - }); - vm.prank(sysConf.owner()); - vm.expectRevert("SystemConfig: gas limit too low"); - sysConf.setResourceConfig(config); - } - - /// @dev Tests that `setResourceConfig` reverts if the elasticity multiplier - /// and max resource limit are configured such that there is a loss of precision. - function test_setResourceConfig_badPrecision_reverts() external { - ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ - maxResourceLimit: 20_000_000, - elasticityMultiplier: 11, - baseFeeMaxChangeDenominator: 8, - systemTxMaxGas: 1_000_000, - minimumBaseFee: 1 gwei, - maximumBaseFee: 2 gwei - }); - vm.prank(sysConf.owner()); - vm.expectRevert("SystemConfig: precision loss with target resource limit"); - sysConf.setResourceConfig(config); - } -} - -contract SystemConfig_Setters_Test is SystemConfig_Init { - /// @dev Tests that `setBatcherHash` updates the batcher hash successfully. - function testFuzz_setBatcherHash_succeeds(bytes32 newBatcherHash) external { - vm.expectEmit(true, true, true, true); - emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash)); - - vm.prank(sysConf.owner()); - sysConf.setBatcherHash(newBatcherHash); - assertEq(sysConf.batcherHash(), newBatcherHash); - } - - /// @dev Tests that `setGasConfig` updates the overhead and scalar successfully. - function testFuzz_setGasConfig_succeeds(uint256 newOverhead, uint256 newScalar) external { - vm.expectEmit(true, true, true, true); - emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(newOverhead, newScalar)); - - vm.prank(sysConf.owner()); - sysConf.setGasConfig(newOverhead, newScalar); - assertEq(sysConf.overhead(), newOverhead); - assertEq(sysConf.scalar(), newScalar); - } - - /// @dev Tests that `setGasLimit` updates the gas limit successfully. - function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external { - uint64 minimumGasLimit = sysConf.minimumGasLimit(); - newGasLimit = uint64(bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))); - - vm.expectEmit(true, true, true, true); - emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit)); - - vm.prank(sysConf.owner()); - sysConf.setGasLimit(newGasLimit); - assertEq(sysConf.gasLimit(), newGasLimit); - } - - /// @dev Tests that `setUnsafeBlockSigner` updates the block signer successfully. - function testFuzz_setUnsafeBlockSigner_succeeds(address newUnsafeSigner) external { - vm.expectEmit(true, true, true, true); - emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(newUnsafeSigner)); - - vm.prank(sysConf.owner()); - sysConf.setUnsafeBlockSigner(newUnsafeSigner); - assertEq(sysConf.unsafeBlockSigner(), newUnsafeSigner); - } -} diff --git a/packages/contracts-bedrock/test/actors/FaultDisputeActors.sol b/packages/contracts-bedrock/test/actors/FaultDisputeActors.sol new file mode 100644 index 000000000000..d1bf6456e2c8 --- /dev/null +++ b/packages/contracts-bedrock/test/actors/FaultDisputeActors.sol @@ -0,0 +1,418 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import { CommonBase } from "forge-std/Base.sol"; + +import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; + +import "src/libraries/DisputeTypes.sol"; + +/// @title GameSolver +/// @notice The `GameSolver` contract is a contract that can produce an array of available +/// moves for a given `FaultDisputeGame` contract, from the eyes of an honest +/// actor. The `GameSolver` does not implement functionality for acting on the `Move`s +/// it suggests. +abstract contract GameSolver is CommonBase { + /// @notice The `FaultDisputeGame` proxy that the `GameSolver` will be solving. + FaultDisputeGame public immutable GAME; + /// @notice The split depth of the game + uint256 internal immutable SPLIT_DEPTH; + /// @notice The max depth of the game + uint256 internal immutable MAX_DEPTH; + /// @notice The maximum L2 block number that the output bisection portion of the position tree + /// can handle. + uint256 internal immutable MAX_L2_BLOCK_NUMBER; + + /// @notice The L2 outputs that the `GameSolver` will be representing, keyed by L2 block number - 1. + uint256[] public l2Outputs; + /// @notice The execution trace that the `GameSolver` will be representing. + bytes public trace; + /// @notice The raw absolute prestate data. + bytes public absolutePrestateData; + /// @notice The offset of previously processed claims in the `GAME` contract's `claimData` array. + /// Starts at 0 and increments by 1 for each claim processed. + uint256 public processedBuf; + /// @notice Signals whether or not the `GameSolver` agrees with the root claim of the + /// `GAME` contract. + bool public agreeWithRoot; + + /// @notice The `MoveKind` enum represents a kind of interaction with the `FaultDisputeGame` contract. + enum MoveKind { + Attack, + Defend, + Step, + AddLocalData + } + + /// @notice The `Move` struct represents a move in the game, and contains information + /// about the kind of move, the sender of the move, and the calldata to be sent + /// to the `FaultDisputeGame` contract by a consumer of this contract. + struct Move { + MoveKind kind; + bytes data; + uint256 value; + } + + constructor( + FaultDisputeGame _gameProxy, + uint256[] memory _l2Outputs, + bytes memory _trace, + bytes memory _preStateData + ) { + GAME = _gameProxy; + SPLIT_DEPTH = GAME.splitDepth(); + MAX_DEPTH = GAME.maxGameDepth(); + MAX_L2_BLOCK_NUMBER = 2 ** (MAX_DEPTH - SPLIT_DEPTH); + + l2Outputs = _l2Outputs; + trace = _trace; + absolutePrestateData = _preStateData; + } + + /// @notice Returns an array of `Move`s that can be taken from the perspective of an honest + /// actor in the `FaultDisputeGame` contract. + function solveGame() external virtual returns (Move[] memory moves_); +} + +/// @title HonestGameSolver +/// @notice The `HonestGameSolver` is an implementation of `GameSolver` which responds accordingly depending +/// on the state of the `FaultDisputeGame` contract in relation to their local opinion of the correct +/// order of output roots and the execution trace between each block `n` -> `n + 1` state transition. +contract HonestGameSolver is GameSolver { + /// @notice The `Direction` enum represents the direction of a proposed move in the game, + /// or a lack thereof. + enum Direction { + Defend, + Attack, + Noop + } + + constructor( + FaultDisputeGame _gameProxy, + uint256[] memory _l2Outputs, + bytes memory _trace, + bytes memory _preStateData + ) + GameSolver(_gameProxy, _l2Outputs, _trace, _preStateData) + { + // Mark agreement with the root claim if the local opinion of the root claim is the same as the + // observed root claim. + agreeWithRoot = Claim.unwrap(outputAt(MAX_L2_BLOCK_NUMBER)) == Claim.unwrap(_gameProxy.rootClaim()); + } + + //////////////////////////////////////////////////////////////// + // EXTERNAL // + //////////////////////////////////////////////////////////////// + + /// @notice Returns an array of `Move`s that can be taken from the perspective of an honest + /// actor in the `FaultDisputeGame` contract. + function solveGame() external override returns (Move[] memory moves_) { + uint256 numClaims = GAME.claimDataLen(); + + // Pre-allocate the `moves_` array to the maximum possible length. Test environment, so + // over-allocation is fine, and more easy to read than making a linked list in asm. + moves_ = new Move[](numClaims - processedBuf); + + uint256 numMoves = 0; + for (uint256 i = processedBuf; i < numClaims; i++) { + // Grab the observed claim. + IFaultDisputeGame.ClaimData memory observed = getClaimData(i); + + // Determine the direction of the next move to be taken. + (Direction moveDirection, Position movePos) = determineDirection(observed); + + // Continue if there is no move to be taken against the observed claim. + if (moveDirection == Direction.Noop) continue; + + if (movePos.depth() <= MAX_DEPTH) { + // bisection + moves_[numMoves++] = handleBisectionMove(moveDirection, movePos, i); + } else { + // instruction step + moves_[numMoves++] = handleStepMove(moveDirection, observed.position, movePos, i); + } + } + + // Update the length of the `moves_` array to the number of moves that were added. This is + // always a no-op or a truncation operation. + assembly { + mstore(moves_, numMoves) + } + + // Increment `processedBuf` by the number of claims processed, so that next time around, + // we don't attempt to process the same claims again. + processedBuf += numClaims - processedBuf; + } + + //////////////////////////////////////////////////////////////// + // INTERNAL // + //////////////////////////////////////////////////////////////// + + /// @dev Helper function to determine the direction of the next move to be taken. + function determineDirection(IFaultDisputeGame.ClaimData memory _claimData) + internal + view + returns (Direction direction_, Position movePos_) + { + bool rightLevel = isRightLevel(_claimData.position); + bool localAgree = Claim.unwrap(claimAt(_claimData.position)) == Claim.unwrap(_claimData.claim); + if (_claimData.parentIndex == type(uint32).max) { + // If we agree with the parent claim and it is on a level we agree with, ignore it. + if (localAgree && rightLevel) { + return (Direction.Noop, Position.wrap(0)); + } + + // The parent claim is the root claim. We must attack if we disagree per the game rules. + direction_ = Direction.Attack; + movePos_ = _claimData.position.move(true); + } else { + // Never attempt to defend an execution trace subgame root. Only attack if we disagree with it, + // otherwise do nothing. + // NOTE: This is not correct behavior in the context of the honest actor; The alphabet game has + // a constant status byte, and is not safe from someone being dishonest in output bisection + // and then posting a correct execution trace bisection root claim. + if (_claimData.position.depth() == SPLIT_DEPTH + 1 && localAgree) { + return (Direction.Noop, Position.wrap(0)); + } + + // If the parent claim is not the root claim, first check if the observed claim is on a level that + // agrees with the local view of the root claim. If it is, noop. If it is not, perform an attack or + // defense depending on the local view of the observed claim. + if (rightLevel) { + // Never move against a claim on the right level. Even if it's wrong, if it's uncountered, it furthers + // our goals. + return (Direction.Noop, Position.wrap(0)); + } else { + // Fetch the local opinion of the parent claim. + Claim localParent = claimAt(_claimData.position); + + // NOTE: Poison not handled. + if (Claim.unwrap(localParent) != Claim.unwrap(_claimData.claim)) { + // If we disagree with the observed claim, we must attack it. + movePos_ = _claimData.position.move(true); + direction_ = Direction.Attack; + } else { + // If we agree with the observed claim, we must defend the observed claim. + movePos_ = _claimData.position.move(false); + direction_ = Direction.Defend; + } + } + } + } + + /// @notice Returns a `Move` struct that represents an attack or defense move in the bisection portion + /// of the game. + /// + /// @dev Note: This function assumes that the `movePos` and `challengeIndex` are valid within the + /// output bisection context. This is enforced by the `solveGame` function. + function handleBisectionMove( + Direction _direction, + Position _movePos, + uint256 _challengeIndex + ) + internal + view + returns (Move memory move_) + { + bool isAttack = _direction == Direction.Attack; + + uint256 bond = GAME.getRequiredBond(_movePos); + + move_ = Move({ + kind: isAttack ? MoveKind.Attack : MoveKind.Defend, + value: bond, + data: abi.encodeCall(FaultDisputeGame.move, (_challengeIndex, claimAt(_movePos), isAttack)) + }); + } + + /// @notice Returns a `Move` struct that represents a step move in the execution trace + /// bisection portion of the dispute game. + /// @dev Note: This function assumes that the `movePos` and `challengeIndex` are valid within the + /// execution trace bisection context. This is enforced by the `solveGame` function. + function handleStepMove( + Direction _direction, + Position _parentPos, + Position _movePos, + uint256 _challengeIndex + ) + internal + view + returns (Move memory move_) + { + bool isAttack = _direction == Direction.Attack; + bytes memory preStateTrace; + + // First, we need to find the pre/post state index depending on whether we + // are making an attack step or a defense step. If the relative index at depth of the + // move position is 0, the prestate is the absolute prestate and we need to + // do nothing. + if ((_movePos.indexAtDepth() % (2 ** (MAX_DEPTH - SPLIT_DEPTH))) != 0) { + // Grab the trace up to the prestate's trace index. + if (isAttack) { + Position leafPos = Position.wrap(Position.unwrap(_parentPos) - 1); + preStateTrace = abi.encode(leafPos.traceIndex(MAX_DEPTH), stateAt(leafPos)); + } else { + preStateTrace = abi.encode(_parentPos.traceIndex(MAX_DEPTH), stateAt(_parentPos)); + } + } else { + preStateTrace = absolutePrestateData; + } + + move_ = Move({ + kind: MoveKind.Step, + value: 0, + data: abi.encodeCall(FaultDisputeGame.step, (_challengeIndex, isAttack, preStateTrace, hex"")) + }); + } + + //////////////////////////////////////////////////////////////// + // HELPERS // + //////////////////////////////////////////////////////////////// + + /// @dev Helper function to get the `ClaimData` struct at a given index in the `GAME` contract's + /// `claimData` array. + function getClaimData(uint256 _claimIndex) internal view returns (IFaultDisputeGame.ClaimData memory claimData_) { + // thanks, solc + ( + uint32 parentIndex, + address countered, + address claimant, + uint128 bond, + Claim claim, + Position position, + Clock clock + ) = GAME.claimData(_claimIndex); + claimData_ = IFaultDisputeGame.ClaimData({ + parentIndex: parentIndex, + counteredBy: countered, + claimant: claimant, + bond: bond, + claim: claim, + position: position, + clock: clock + }); + } + + /// @notice Returns the player's claim that commits to a given position, swapping between + /// output bisection claims and execution trace bisection claims depending on the depth. + /// @dev Prefer this function over `outputAt` or `statehashAt` directly. + function claimAt(Position _position) internal view returns (Claim claim_) { + return _position.depth() > SPLIT_DEPTH ? statehashAt(_position) : outputAt(_position); + } + + /// @notice Returns the mock output at the given position. + function outputAt(Position _position) internal view returns (Claim claim_) { + // Don't allow for positions that are deeper than the split depth. + if (_position.depth() > SPLIT_DEPTH) { + revert("GameSolver: invalid position depth"); + } + + return outputAt(_position.traceIndex(SPLIT_DEPTH) + 1); + } + + /// @notice Returns the mock output at the given L2 block number. + function outputAt(uint256 _l2BlockNumber) internal view returns (Claim claim_) { + return Claim.wrap(bytes32(l2Outputs[_l2BlockNumber - 1])); + } + + /// @notice Returns the player's claim that commits to a given trace index. + function statehashAt(uint256 _traceIndex) internal view returns (Claim claim_) { + bytes32 hash = + keccak256(abi.encode(_traceIndex >= trace.length ? trace.length - 1 : _traceIndex, stateAt(_traceIndex))); + assembly { + claim_ := or(and(hash, not(shl(248, 0xFF))), shl(248, 1)) + } + } + + /// @notice Returns the player's claim that commits to a given trace index. + function statehashAt(Position _position) internal view returns (Claim claim_) { + return statehashAt(_position.traceIndex(MAX_DEPTH)); + } + + /// @notice Returns the state at the trace index within the player's trace. + function stateAt(Position _position) internal view returns (uint256 state_) { + return stateAt(_position.traceIndex(MAX_DEPTH)); + } + + /// @notice Returns the state at the trace index within the player's trace. + function stateAt(uint256 _traceIndex) internal view returns (uint256 state_) { + return uint256(uint8(_traceIndex >= trace.length ? trace[trace.length - 1] : trace[_traceIndex])); + } + + /// @notice Returns whether or not the position is on a level which opposes the local opinion of the + /// root claim. + function isRightLevel(Position _position) internal view returns (bool isRightLevel_) { + isRightLevel_ = agreeWithRoot == (_position.depth() % 2 == 0); + } +} + +/// @title DisputeActor +/// @notice The `DisputeActor` contract is an abstract contract that represents an actor +/// that consumes the suggested moves from a `GameSolver` contract. +abstract contract DisputeActor { + /// @notice The `GameSolver` contract used to determine the moves to be taken. + GameSolver public solver; + + /// @notice Performs all available moves deemed by the attached solver. + /// @return numMoves_ The number of moves that the actor took. + /// @return success_ True if all moves were successful, false otherwise. + function move() external virtual returns (uint256 numMoves_, bool success_); +} + +/// @title HonestDisputeActor +/// @notice An actor that consumes the suggested moves from an `HonestGameSolver` contract. Note +/// that this actor *can* be dishonest if the trace is faulty, but it will always follow +/// the rules of the honest actor. +contract HonestDisputeActor is DisputeActor { + FaultDisputeGame public immutable GAME; + + constructor( + FaultDisputeGame _gameProxy, + uint256[] memory _l2Outputs, + bytes memory _trace, + bytes memory _preStateData + ) { + GAME = _gameProxy; + solver = GameSolver(new HonestGameSolver(_gameProxy, _l2Outputs, _trace, _preStateData)); + } + + /// @inheritdoc DisputeActor + function move() external override returns (uint256 numMoves_, bool success_) { + GameSolver.Move[] memory moves = solver.solveGame(); + numMoves_ = moves.length; + + // Optimistically assume success, will be set to false if any move fails. + success_ = true; + + // Perform all available moves given to the actor by the solver. + for (uint256 i = 0; i < moves.length; i++) { + GameSolver.Move memory localMove = moves[i]; + + // If the move is a step, we first need to add the starting L2 block number to the `PreimageOracle` + // via the `FaultDisputeGame` contract. + // TODO: This is leaky. Could be another move kind. + if (localMove.kind == GameSolver.MoveKind.Step) { + bytes memory moveData = localMove.data; + uint256 challengeIndex; + assembly { + challengeIndex := mload(add(moveData, 0x24)) + } + GAME.addLocalData({ + _ident: LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER, + _execLeafIdx: challengeIndex, + _partOffset: 0 + }); + } + + (bool innerSuccess,) = address(GAME).call{ value: localMove.value }(localMove.data); + assembly { + success_ := and(success_, innerSuccess) + } + } + } + + fallback() external payable { } + + receive() external payable { } +} diff --git a/packages/contracts-bedrock/test/MIPS.t.sol b/packages/contracts-bedrock/test/cannon/MIPS.t.sol similarity index 99% rename from packages/contracts-bedrock/test/MIPS.t.sol rename to packages/contracts-bedrock/test/cannon/MIPS.t.sol index 7f1dfdead49a..eb7843fd7cc9 100644 --- a/packages/contracts-bedrock/test/MIPS.t.sol +++ b/packages/contracts-bedrock/test/cannon/MIPS.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { MIPS } from "src/cannon/MIPS.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import "src/libraries/DisputeTypes.sol"; @@ -12,7 +12,7 @@ contract MIPS_Test is CommonTest { function setUp() public virtual override { super.setUp(); - oracle = new PreimageOracle(); + oracle = new PreimageOracle(0, 0); mips = new MIPS(oracle); vm.store(address(mips), 0x0, bytes32(abi.encode(address(oracle)))); vm.label(address(oracle), "PreimageOracle"); diff --git a/packages/contracts-bedrock/test/cannon/PreimageOracle.t.sol b/packages/contracts-bedrock/test/cannon/PreimageOracle.t.sol new file mode 100644 index 000000000000..2ca5f08cbc78 --- /dev/null +++ b/packages/contracts-bedrock/test/cannon/PreimageOracle.t.sol @@ -0,0 +1,1365 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test, console2 as console } from "forge-std/Test.sol"; + +import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; +import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol"; +import { LibKeccak } from "@lib-keccak/LibKeccak.sol"; +import { Bytes } from "src/libraries/Bytes.sol"; +import "src/cannon/libraries/CannonErrors.sol"; +import "src/cannon/libraries/CannonTypes.sol"; + +contract PreimageOracle_Test is Test { + PreimageOracle oracle; + + /// @notice Sets up the testing suite. + function setUp() public { + oracle = new PreimageOracle(0, 0); + vm.label(address(oracle), "PreimageOracle"); + } + + /// @notice Test the pre-image key computation with a known pre-image. + function test_keccak256PreimageKey_succeeds() public { + bytes memory preimage = hex"deadbeef"; + bytes32 key = PreimageKeyLib.keccak256PreimageKey(preimage); + bytes32 known = 0x02fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1; + assertEq(key, known); + } + + /// @notice Tests that context-specific data [0, 24] bytes in length can be loaded correctly. + function test_loadLocalData_onePart_succeeds() public { + uint256 ident = 1; + bytes32 word = bytes32(uint256(0xdeadbeef) << 224); + uint8 size = 4; + uint8 partOffset = 0; + + // Load the local data into the preimage oracle under the test contract's context. + bytes32 contextKey = oracle.loadLocalData(ident, 0, word, size, partOffset); + + // Validate that the pre-image part is set + bool ok = oracle.preimagePartOk(contextKey, partOffset); + assertTrue(ok); + + // Validate the local data part + bytes32 expectedPart = 0x0000000000000004deadbeef0000000000000000000000000000000000000000; + assertEq(oracle.preimageParts(contextKey, partOffset), expectedPart); + + // Validate the local data length + uint256 length = oracle.preimageLengths(contextKey); + assertEq(length, size); + } + + /// @notice Tests that multiple local key contexts can be used by the same address for the + /// same local data identifier. + function test_loadLocalData_multipleContexts_succeeds() public { + uint256 ident = 1; + uint8 size = 4; + uint8 partOffset = 0; + + // Form the words we'll be storing + bytes32[2] memory words = [bytes32(uint256(0xdeadbeef) << 224), bytes32(uint256(0xbeefbabe) << 224)]; + + for (uint256 i; i < words.length; i++) { + // Load the local data into the preimage oracle under the test contract's context + // and the given local context. + bytes32 contextKey = oracle.loadLocalData(ident, bytes32(i), words[i], size, partOffset); + + // Validate that the pre-image part is set + bool ok = oracle.preimagePartOk(contextKey, partOffset); + assertTrue(ok); + + // Validate the local data part + bytes32 expectedPart = bytes32(uint256(words[i] >> 64) | uint256(size) << 192); + assertEq(oracle.preimageParts(contextKey, partOffset), expectedPart); + + // Validate the local data length + uint256 length = oracle.preimageLengths(contextKey); + assertEq(length, size); + } + } + + /// @notice Tests that context-specific data [0, 32] bytes in length can be loaded correctly. + function testFuzz_loadLocalData_varyingLength_succeeds( + uint256 ident, + bytes32 localContext, + bytes32 word, + uint256 size, + uint256 partOffset + ) + public + { + // Bound the size to [0, 32] + size = bound(size, 0, 32); + // Bound the part offset to [0, size + 8] + partOffset = bound(partOffset, 0, size + 8); + + // Load the local data into the preimage oracle under the test contract's context. + bytes32 contextKey = oracle.loadLocalData(ident, localContext, word, uint8(size), uint8(partOffset)); + + // Validate that the first local data part is set + bool ok = oracle.preimagePartOk(contextKey, partOffset); + assertTrue(ok); + // Validate the first local data part + bytes32 expectedPart; + assembly { + mstore(0x20, 0x00) + + mstore(0x00, shl(192, size)) + mstore(0x08, word) + + expectedPart := mload(partOffset) + } + assertEq(oracle.preimageParts(contextKey, partOffset), expectedPart); + + // Validate the local data length + uint256 length = oracle.preimageLengths(contextKey); + assertEq(length, size); + } + + /// @notice Tests that a pre-image is correctly set. + function test_loadKeccak256PreimagePart_succeeds() public { + // Set the pre-image + bytes memory preimage = hex"deadbeef"; + bytes32 key = PreimageKeyLib.keccak256PreimageKey(preimage); + uint256 offset = 0; + oracle.loadKeccak256PreimagePart(offset, preimage); + + // Validate the pre-image part + bytes32 part = oracle.preimageParts(key, offset); + bytes32 expectedPart = 0x0000000000000004deadbeef0000000000000000000000000000000000000000; + assertEq(part, expectedPart); + + // Validate the pre-image length + uint256 length = oracle.preimageLengths(key); + assertEq(length, preimage.length); + + // Validate that the pre-image part is set + bool ok = oracle.preimagePartOk(key, offset); + assertTrue(ok); + } + + /// @notice Tests that adding a global keccak256 pre-image at the part boundary reverts. + function test_loadKeccak256PreimagePart_partBoundary_reverts() public { + bytes memory preimage = hex"deadbeef"; + uint256 offset = preimage.length + 8; + + vm.expectRevert(PartOffsetOOB.selector); + oracle.loadKeccak256PreimagePart(offset, preimage); + } + + /// @notice Tests that a pre-image cannot be set with an out-of-bounds offset. + function test_loadLocalData_outOfBoundsOffset_reverts() public { + bytes32 preimage = bytes32(uint256(0xdeadbeef)); + uint256 offset = preimage.length + 9; + + vm.expectRevert(PartOffsetOOB.selector); + oracle.loadLocalData(1, 0, preimage, 32, offset); + } + + /// @notice Tests that a pre-image cannot be set with an out-of-bounds offset. + function test_loadKeccak256PreimagePart_outOfBoundsOffset_reverts() public { + bytes memory preimage = hex"deadbeef"; + uint256 offset = preimage.length + 9; + + vm.expectRevert(PartOffsetOOB.selector); + oracle.loadKeccak256PreimagePart(offset, preimage); + } + + /// @notice Reading a pre-image part that has not been set should revert. + function testFuzz_readPreimage_missingPreimage_reverts(bytes32 key, uint256 offset) public { + vm.expectRevert("pre-image must exist"); + oracle.readPreimage(key, offset); + } + + /// @notice Tests that a precompile pre-image result is correctly set. + function test_loadPrecompilePreimagePart_succeeds() public { + bytes memory input = hex"deadbeef"; + uint256 offset = 0; + address precompile = address(bytes20(uint160(0x02))); // sha256 + bytes32 key = precompilePreimageKey(precompile, input); + oracle.loadPrecompilePreimagePart(offset, precompile, input); + + bytes32 part = oracle.preimageParts(key, offset); + // size prefix - 1-byte result + 32-byte sha return data + assertEq(hex"0000000000000021", bytes8(part)); + // precompile result + assertEq(bytes1(0x01), bytes1(part << 64)); + // precompile call return data + assertEq(bytes23(sha256(input)), bytes23(part << 72)); + + // Validate the local data length + uint256 length = oracle.preimageLengths(key); + assertEq(length, 1 + 32); + + // Validate that the first local data part is set + bool ok = oracle.preimagePartOk(key, offset); + assertTrue(ok); + } + + /// @notice Tests that a precompile pre-image result is correctly set at its return data offset. + function test_loadPrecompilePreimagePart_atReturnOffset_succeeds() public { + bytes memory input = hex"deadbeef"; + uint256 offset = 9; + address precompile = address(bytes20(uint160(0x02))); // sha256 + bytes32 key = precompilePreimageKey(precompile, input); + oracle.loadPrecompilePreimagePart(offset, precompile, input); + + bytes32 part = oracle.preimageParts(key, offset); + // 32-byte sha return data + assertEq(sha256(input), part); + + // Validate the local data length + uint256 length = oracle.preimageLengths(key); + assertEq(length, 1 + 32); + + // Validate that the first local data part is set + bool ok = oracle.preimagePartOk(key, offset); + assertTrue(ok); + } + + /// @notice Tests that a failed precompile call has a zero status byte in preimage + function test_loadPrecompilePreimagePart_failedCall_succeeds() public { + bytes memory input = new bytes(193); // invalid input to induce a failed precompile call + uint256 offset = 0; + address precompile = address(bytes20(uint160(0x08))); // bn256Pairing + bytes32 key = precompilePreimageKey(precompile, input); + oracle.loadPrecompilePreimagePart(offset, precompile, input); + + bytes32 part = oracle.preimageParts(key, offset); + // size prefix - 1-byte result + 0-byte sha return data + assertEq(hex"0000000000000001", bytes8(part)); + // precompile result + assertEq(bytes1(0x00), bytes1(part << 64)); + // precompile call return data + assertEq(bytes23(0), bytes23(part << 72)); + + // Validate the local data length + uint256 length = oracle.preimageLengths(key); + assertEq(length, 1); + + // Validate that the first local data part is set + bool ok = oracle.preimagePartOk(key, offset); + assertTrue(ok); + } + + /// @notice Tests that adding a global precompile result at the part boundary reverts. + function test_loadPrecompilePreimagePart_partBoundary_reverts() public { + bytes memory input = hex"deadbeef"; + uint256 offset = 41; // 8-byte prefix + 1-byte result + 32-byte sha return data + address precompile = address(bytes20(uint160(0x02))); // sha256 + vm.expectRevert(PartOffsetOOB.selector); + oracle.loadPrecompilePreimagePart(offset, precompile, input); + } + + /// @notice Tests that a global precompile result cannot be set with an out-of-bounds offset. + function test_loadPrecompilePreimagePart_outOfBoundsOffset_reverts() public { + bytes memory input = hex"deadbeef"; + uint256 offset = 42; + address precompile = address(bytes20(uint160(0x02))); // sha256 + vm.expectRevert(PartOffsetOOB.selector); + oracle.loadPrecompilePreimagePart(offset, precompile, input); + } +} + +contract PreimageOracle_LargePreimageProposals_Test is Test { + uint256 internal constant MIN_SIZE_BYTES = 0; + uint256 internal constant CHALLENGE_PERIOD = 1 days; + uint256 internal constant TEST_UUID = 0xFACADE; + + PreimageOracle internal oracle; + + /// @notice Sets up the testing suite. + function setUp() public { + oracle = new PreimageOracle({ _minProposalSize: MIN_SIZE_BYTES, _challengePeriod: CHALLENGE_PERIOD }); + vm.label(address(oracle), "PreimageOracle"); + + // Set `tx.origin` and `msg.sender` to `address(this)` so that it may behave like an EOA for `addLeavesLPP`. + vm.startPrank(address(this), address(this)); + + // Give this address some ETH to work with. + vm.deal(address(this), 100 ether); + } + + /// @notice Tests that the `initLPP` function reverts when the part offset is out of bounds of the full preimage. + function test_initLPP_partOffsetOOB_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + uint256 bondSize = oracle.MIN_BOND_SIZE(); + vm.expectRevert(PartOffsetOOB.selector); + oracle.initLPP{ value: bondSize }(TEST_UUID, 136 + 8, uint32(data.length)); + } + + /// @notice Tests that the `initLPP` function reverts when the part offset is out of bounds of the full preimage. + function test_initLPP_sizeTooSmall_reverts() public { + oracle = new PreimageOracle({ _minProposalSize: 1000, _challengePeriod: CHALLENGE_PERIOD }); + + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + uint256 bondSize = oracle.MIN_BOND_SIZE(); + vm.expectRevert(InvalidInputSize.selector); + oracle.initLPP{ value: bondSize }(TEST_UUID, 0, uint32(data.length)); + } + + /// @notice Gas snapshot for `addLeaves` + function test_addLeaves_gasSnapshot() public { + // Allocate the preimage data. + bytes memory data = new bytes(136 * 500); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree (2 keccak blocks.) + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + + // Allocate the calldata so it isn't included in the gas measurement. + bytes memory cd = abi.encodeCall(oracle.addLeavesLPP, (TEST_UUID, 0, data, stateCommitments, true)); + + uint256 gas = gasleft(); + (bool success,) = address(oracle).call(cd); + uint256 gasUsed = gas - gasleft(); + assertTrue(success); + + console.log("Gas used: %d", gasUsed); + console.log("Gas per byte (%d bytes streamed): %d", data.length, gasUsed / data.length); + console.log("Gas for 4MB: %d", (gasUsed / data.length) * 4000000); + } + + /// @notice Tests that `addLeavesLPP` sets the proposal as countered when `_finalize = true` and the number of + /// bytes processed is less than the claimed size. + function test_addLeaves_mismatchedSize_succeeds() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length + 1)); + + // Add the leaves to the tree (2 keccak blocks.) + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + + vm.expectRevert(InvalidInputSize.selector); + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + } + + /// @notice Tests that the `addLeavesLPP` function may never be called when `tx.origin != msg.sender` + function test_addLeaves_notEOA_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136 * 500); + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree (2 keccak blocks.) + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + + // Replace the global prank, set `tx.origin` to `address(0)`, and set `msg.sender` to `address(this)`. + vm.stopPrank(); + vm.prank(address(0), address(this)); + + vm.expectRevert(NotEOA.selector); + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + } + + /// @notice Tests that the `addLeavesLPP` function reverts when the starting block index is not what is expected. + function test_addLeaves_notContiguous_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136 * 500); + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree (2 keccak blocks.) + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + + vm.expectRevert(WrongStartingBlock.selector); + oracle.addLeavesLPP(TEST_UUID, 1, data, stateCommitments, true); + } + + /// @notice Tests that leaves can be added the large preimage proposal mapping and proven to be contained within + /// the computed merkle root. + function test_addLeaves_multipleParts_succeeds() public { + // Allocate the preimage data. + bytes memory data = new bytes(136 * 3); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + // Ensure that the proposal keys are present in the array. + (address claimant, uint256 uuid) = oracle.proposals(0); + assertEq(oracle.proposalCount(), 1); + assertEq(claimant, address(this)); + assertEq(uuid, TEST_UUID); + + // Add the leaves to the tree (2 keccak blocks.) + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + + uint256 midPoint = stateCommitments.length / 2; + bytes32[] memory commitmentsA = new bytes32[](midPoint); + bytes32[] memory commitmentsB = new bytes32[](midPoint); + for (uint256 i = 0; i < midPoint; i++) { + commitmentsA[i] = stateCommitments[i]; + commitmentsB[i] = stateCommitments[i + midPoint]; + } + + oracle.addLeavesLPP(TEST_UUID, 0, Bytes.slice(data, 0, 136 * 2), commitmentsA, false); + + // MetaData assertions + LPPMetaData metaData = oracle.proposalMetadata(address(this), TEST_UUID); + assertEq(metaData.timestamp(), 0); + assertEq(metaData.partOffset(), 0); + assertEq(metaData.claimedSize(), data.length); + assertEq(metaData.blocksProcessed(), 2); + assertEq(metaData.bytesProcessed(), 136 * 2); + assertFalse(metaData.countered()); + + // Move ahead one block. + vm.roll(block.number + 1); + + oracle.addLeavesLPP(TEST_UUID, 2, Bytes.slice(data, 136 * 2, 136), commitmentsB, true); + + // MetaData assertions + metaData = oracle.proposalMetadata(address(this), TEST_UUID); + assertEq(metaData.timestamp(), 1); + assertEq(metaData.partOffset(), 0); + assertEq(metaData.claimedSize(), data.length); + assertEq(metaData.blocksProcessed(), 4); + assertEq(metaData.bytesProcessed(), data.length); + assertFalse(metaData.countered()); + + // Preimage part assertions + bytes32 expectedPart = bytes32((~uint256(0) & ~(uint256(type(uint64).max) << 192)) | (data.length << 192)); + assertEq(oracle.proposalParts(address(this), TEST_UUID), expectedPart); + + assertEq(oracle.proposalBlocks(address(this), TEST_UUID, 0), block.number - 1); + assertEq(oracle.proposalBlocks(address(this), TEST_UUID, 1), block.number); + + // Should revert if we try to add new leaves. + vm.expectRevert(AlreadyFinalized.selector); + oracle.addLeavesLPP(TEST_UUID, 4, data, stateCommitments, true); + } + + /// @notice Tests that leaves cannot be added until the large preimage proposal has been initialized. + function test_addLeaves_notInitialized_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136 * 500); + + // Add the leaves to the tree (2 keccak blocks.) + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + + // Allocate the calldata so it isn't included in the gas measurement. + vm.expectRevert(NotInitialized.selector); + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + } + + /// @notice Tests that leaves can be added the large preimage proposal mapping and finalized to be added to the + /// authorized mappings. + function test_squeeze_challengePeriodPassed_succeeds() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree (2 keccak blocks.) + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, data); + + // Create a proof array with 16 elements. + bytes32[] memory preProof = new bytes32[](16); + preProof[0] = _hashLeaf(leaves[1]); + bytes32[] memory postProof = new bytes32[](16); + postProof[0] = _hashLeaf(leaves[0]); + for (uint256 i = 1; i < preProof.length; i++) { + bytes32 zeroHash = oracle.zeroHashes(i); + preProof[i] = zeroHash; + postProof[i] = zeroHash; + } + + vm.warp(block.timestamp + oracle.challengePeriod() + 1 seconds); + + // Finalize the proposal. + uint256 balanceBefore = address(this).balance; + oracle.squeezeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: _stateMatrixAtBlockIndex(data, 1), + _preState: leaves[0], + _preStateProof: preProof, + _postState: leaves[1], + _postStateProof: postProof + }); + assertEq(address(this).balance, balanceBefore + oracle.MIN_BOND_SIZE()); + assertEq(oracle.proposalBonds(address(this), TEST_UUID), 0); + + bytes32 finalDigest = _setStatusByte(keccak256(data), 2); + bytes32 expectedPart = bytes32((~uint256(0) & ~(uint256(type(uint64).max) << 192)) | (data.length << 192)); + assertTrue(oracle.preimagePartOk(finalDigest, 0)); + assertEq(oracle.preimageLengths(finalDigest), data.length); + assertEq(oracle.preimageParts(finalDigest, 0), expectedPart); + } + + /// @notice Tests that a proposal cannot be finalized until it has passed the challenge period. + function test_squeeze_proposalChallenged_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + bytes memory phonyData = new bytes(136); + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree with mismatching state commitments. + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, phonyData, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, phonyData); + leaves[0].stateCommitment = stateCommitments[0]; + leaves[1].stateCommitment = stateCommitments[1]; + + // Create a proof array with 16 elements. + bytes32[] memory preProof = new bytes32[](16); + preProof[0] = _hashLeaf(leaves[1]); + bytes32[] memory postProof = new bytes32[](16); + postProof[0] = _hashLeaf(leaves[0]); + for (uint256 i = 1; i < preProof.length; i++) { + bytes32 zeroHash = oracle.zeroHashes(i); + preProof[i] = zeroHash; + postProof[i] = zeroHash; + } + + // Should succeed since the commitment was wrong. + oracle.challengeFirstLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _postState: leaves[0], + _postStateProof: preProof + }); + + LPPMetaData metaData = oracle.proposalMetadata(address(this), TEST_UUID); + assertTrue(metaData.countered()); + + vm.warp(block.timestamp + oracle.challengePeriod() + 1 seconds); + + // Finalize the proposal. + vm.expectRevert(BadProposal.selector); + oracle.squeezeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: _stateMatrixAtBlockIndex(data, 1), + _preState: leaves[0], + _preStateProof: preProof, + _postState: leaves[1], + _postStateProof: postProof + }); + } + + /// @notice Tests that a proposal cannot be finalized until it has passed the challenge period. + function test_squeeze_challengePeriodActive_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree (2 keccak blocks.) + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, data); + + // Finalize the proposal. + vm.expectRevert(ActiveProposal.selector); + oracle.squeezeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: _stateMatrixAtBlockIndex(data, 1), + _preState: leaves[0], + _preStateProof: new bytes32[](16), + _postState: leaves[1], + _postStateProof: new bytes32[](16) + }); + } + + /// @notice Tests that a proposal cannot be finalized until it has passed the challenge period. + function test_squeeze_incompleteAbsorbtion_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, data); + + // Finalize the proposal. + vm.expectRevert(ActiveProposal.selector); + oracle.squeezeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: _stateMatrixAtBlockIndex(data, 1), + _preState: leaves[0], + _preStateProof: new bytes32[](16), + _postState: leaves[1], + _postStateProof: new bytes32[](16) + }); + } + + /// @notice Tests that the `squeeze` function reverts when the passed states are not contiguous. + function test_squeeze_statesNotContiguous_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree (2 keccak blocks.) + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, data); + + // Create a proof array with 16 elements. + bytes32[] memory preProof = new bytes32[](16); + preProof[0] = _hashLeaf(leaves[1]); + bytes32[] memory postProof = new bytes32[](16); + postProof[0] = _hashLeaf(leaves[0]); + for (uint256 i = 1; i < preProof.length; i++) { + bytes32 zeroHash = oracle.zeroHashes(i); + preProof[i] = zeroHash; + postProof[i] = zeroHash; + } + + vm.warp(block.timestamp + oracle.challengePeriod() + 1 seconds); + + // Finalize the proposal. + vm.expectRevert(StatesNotContiguous.selector); + oracle.squeezeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: _stateMatrixAtBlockIndex(data, 2), + _preState: leaves[1], + _preStateProof: postProof, + _postState: leaves[0], + _postStateProof: preProof + }); + } + + /// @notice Tests that the `squeeze` function reverts when the post state passed + function test_squeeze_invalidPreimage_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree (2 keccak blocks.) + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, data); + + // Create a proof array with 16 elements. + bytes32[] memory preProof = new bytes32[](16); + preProof[0] = _hashLeaf(leaves[1]); + bytes32[] memory postProof = new bytes32[](16); + postProof[0] = _hashLeaf(leaves[0]); + for (uint256 i = 1; i < preProof.length; i++) { + bytes32 zeroHash = oracle.zeroHashes(i); + preProof[i] = zeroHash; + postProof[i] = zeroHash; + } + + vm.warp(block.timestamp + oracle.challengePeriod() + 1 seconds); + + // Finalize the proposal. + vm.expectRevert(InvalidPreimage.selector); + oracle.squeezeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: _stateMatrixAtBlockIndex(data, 2), + _preState: leaves[0], + _preStateProof: preProof, + _postState: leaves[1], + _postStateProof: postProof + }); + } + + /// @notice Tests that squeezing a large preimage proposal after the challenge period has passed always succeeds and + /// persists the correct data. + function testFuzz_squeeze_succeeds(uint256 _numBlocks, uint32 _partOffset) public { + _numBlocks = bound(_numBlocks, 1, 2 ** 8); + _partOffset = uint32(bound(_partOffset, 0, _numBlocks * LibKeccak.BLOCK_SIZE_BYTES + 8 - 1)); + + // Allocate the preimage data. + bytes memory data = new bytes(136 * _numBlocks); + for (uint256 i; i < data.length; i++) { + data[i] = bytes1(uint8(i % 256)); + } + + // Propose and squeeze a large preimage. + { + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, _partOffset, uint32(data.length)); + + // Add the leaves to the tree with correct state commitments. + LibKeccak.StateMatrix memory matrixA; + bytes32[] memory stateCommitments = _generateStateCommitments(matrixA, data); + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrixB; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrixB, data); + + // Fetch the merkle proofs for the pre/post state leaves in the proposal tree. + bytes32 canonicalRoot = oracle.getTreeRootLPP(address(this), TEST_UUID); + (bytes32 rootA, bytes32[] memory preProof) = _generateProof(leaves.length - 2, leaves); + assertEq(rootA, canonicalRoot); + (bytes32 rootB, bytes32[] memory postProof) = _generateProof(leaves.length - 1, leaves); + assertEq(rootB, canonicalRoot); + + // Warp past the challenge period. + vm.warp(block.timestamp + CHALLENGE_PERIOD + 1 seconds); + + // Squeeze the LPP. + LibKeccak.StateMatrix memory preMatrix = _stateMatrixAtBlockIndex(data, leaves.length - 1); + oracle.squeezeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: preMatrix, + _preState: leaves[leaves.length - 2], + _preStateProof: preProof, + _postState: leaves[leaves.length - 1], + _postStateProof: postProof + }); + } + + // Validate the preimage part + { + bytes32 finalDigest = _setStatusByte(keccak256(data), 2); + bytes32 expectedPart; + assembly { + switch lt(_partOffset, 0x08) + case true { + mstore(0x00, shl(192, mload(data))) + mstore(0x08, mload(add(data, 0x20))) + expectedPart := mload(_partOffset) + } + default { + // Clean the word after `data` so we don't get any dirty bits. + mstore(add(add(data, 0x20), mload(data)), 0x00) + expectedPart := mload(add(add(data, 0x20), sub(_partOffset, 0x08))) + } + } + + assertTrue(oracle.preimagePartOk(finalDigest, _partOffset)); + assertEq(oracle.preimageLengths(finalDigest), data.length); + assertEq(oracle.preimageParts(finalDigest, _partOffset), expectedPart); + } + } + + /// @notice Tests that a valid leaf cannot be countered with the `challengeFirst` function. + function test_challengeFirst_validCommitment_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree with mismatching state commitments. + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, data); + + // Create a proof array with 16 elements. + bytes32[] memory p = new bytes32[](16); + p[0] = _hashLeaf(leaves[1]); + for (uint256 i = 1; i < p.length; i++) { + p[i] = oracle.zeroHashes(i); + } + + vm.expectRevert(PostStateMatches.selector); + oracle.challengeFirstLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _postState: leaves[0], + _postStateProof: p + }); + + LPPMetaData metaData = oracle.proposalMetadata(address(this), TEST_UUID); + assertFalse(metaData.countered()); + } + + /// @notice Tests that an invalid leaf cannot be countered with `challengeFirst` if it is not the first leaf. + function test_challengeFirst_statesNotContiguous_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + bytes memory phonyData = new bytes(136); + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree with mismatching state commitments. + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, phonyData, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, phonyData); + leaves[0].stateCommitment = stateCommitments[0]; + leaves[1].stateCommitment = stateCommitments[1]; + + // Create a proof array with 16 elements. + bytes32[] memory p = new bytes32[](16); + p[0] = _hashLeaf(leaves[0]); + for (uint256 i = 1; i < p.length; i++) { + p[i] = oracle.zeroHashes(i); + } + + // Should succeed since the commitment was wrong. + vm.expectRevert(StatesNotContiguous.selector); + oracle.challengeFirstLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _postState: leaves[1], + _postStateProof: p + }); + } + + /// @notice Tests that an invalid leaf can be countered with the `challengeFirst` function. + function test_challengeFirst_invalidCommitment_succeeds() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + bytes memory phonyData = new bytes(136); + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree with mismatching state commitments. + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, phonyData, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, phonyData); + leaves[0].stateCommitment = stateCommitments[0]; + leaves[1].stateCommitment = stateCommitments[1]; + + // Create a proof array with 16 elements. + bytes32[] memory p = new bytes32[](16); + p[0] = _hashLeaf(leaves[1]); + for (uint256 i = 1; i < p.length; i++) { + p[i] = oracle.zeroHashes(i); + } + + // Should succeed since the commitment was wrong. + uint256 balanceBefore = address(this).balance; + oracle.challengeFirstLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _postState: leaves[0], + _postStateProof: p + }); + assertEq(address(this).balance, balanceBefore + oracle.MIN_BOND_SIZE()); + assertEq(oracle.proposalBonds(address(this), TEST_UUID), 0); + + LPPMetaData metaData = oracle.proposalMetadata(address(this), TEST_UUID); + assertTrue(metaData.countered()); + } + + /// @notice Tests that challenging the first divergence in a large preimage proposal at an arbitrary location + /// in the leaf values always succeeds. + function testFuzz_challenge_arbitraryLocation_succeeds(uint256 _lastCorrectLeafIdx, uint256 _numBlocks) public { + _numBlocks = bound(_numBlocks, 1, 2 ** 8); + _lastCorrectLeafIdx = bound(_lastCorrectLeafIdx, 0, _numBlocks - 1); + + // Allocate the preimage data. + bytes memory data = new bytes(136 * _numBlocks); + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree with corrupted state commitments. + LibKeccak.StateMatrix memory matrixA; + bytes32[] memory stateCommitments = _generateStateCommitments(matrixA, data); + for (uint256 i = _lastCorrectLeafIdx + 1; i < stateCommitments.length; i++) { + stateCommitments[i] = 0; + } + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added and corrupt the state commitments. + LibKeccak.StateMatrix memory matrixB; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrixB, data); + for (uint256 i = _lastCorrectLeafIdx + 1; i < leaves.length; i++) { + leaves[i].stateCommitment = 0; + } + + // Avoid stack too deep + uint256 agreedLeafIdx = _lastCorrectLeafIdx; + uint256 disputedLeafIdx = agreedLeafIdx + 1; + + // Fetch the merkle proofs for the pre/post state leaves in the proposal tree. + bytes32 canonicalRoot = oracle.getTreeRootLPP(address(this), TEST_UUID); + (bytes32 rootA, bytes32[] memory preProof) = _generateProof(agreedLeafIdx, leaves); + assertEq(rootA, canonicalRoot); + (bytes32 rootB, bytes32[] memory postProof) = _generateProof(disputedLeafIdx, leaves); + assertEq(rootB, canonicalRoot); + + LibKeccak.StateMatrix memory preMatrix = _stateMatrixAtBlockIndex(data, disputedLeafIdx); + oracle.challengeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: preMatrix, + _preState: leaves[agreedLeafIdx], + _preStateProof: preProof, + _postState: leaves[disputedLeafIdx], + _postStateProof: postProof + }); + + LPPMetaData metaData = oracle.proposalMetadata(address(this), TEST_UUID); + assertTrue(metaData.countered()); + } + + /// @notice Tests that challenging the a divergence in a large preimage proposal at the first leaf always succeeds. + function testFuzz_challengeFirst_succeeds(uint256 _numBlocks) public { + _numBlocks = bound(_numBlocks, 1, 2 ** 8); + + // Allocate the preimage data. + bytes memory data = new bytes(136 * _numBlocks); + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree with corrupted state commitments. + bytes32[] memory stateCommitments = new bytes32[](_numBlocks + 1); + for (uint256 i = 0; i < stateCommitments.length; i++) { + stateCommitments[i] = 0; + } + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added and corrupt the state commitments. + LibKeccak.StateMatrix memory matrixB; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrixB, data); + for (uint256 i = 0; i < leaves.length; i++) { + leaves[i].stateCommitment = 0; + } + + // Fetch the merkle proofs for the pre/post state leaves in the proposal tree. + bytes32 canonicalRoot = oracle.getTreeRootLPP(address(this), TEST_UUID); + (bytes32 rootA, bytes32[] memory postProof) = _generateProof(0, leaves); + assertEq(rootA, canonicalRoot); + + oracle.challengeFirstLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _postState: leaves[0], + _postStateProof: postProof + }); + + LPPMetaData metaData = oracle.proposalMetadata(address(this), TEST_UUID); + assertTrue(metaData.countered()); + } + + /// @notice Tests that a valid leaf cannot be countered with the `challenge` function in the middle of the tree. + function test_challenge_validCommitment_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree with mismatching state commitments. + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, data, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, data); + + // Create a proof array with 16 elements. + bytes32[] memory preProof = new bytes32[](16); + preProof[0] = _hashLeaf(leaves[1]); + bytes32[] memory postProof = new bytes32[](16); + postProof[0] = _hashLeaf(leaves[0]); + for (uint256 i = 1; i < preProof.length; i++) { + bytes32 zeroHash = oracle.zeroHashes(i); + preProof[i] = zeroHash; + postProof[i] = zeroHash; + } + + LibKeccak.StateMatrix memory preMatrix = _stateMatrixAtBlockIndex(data, 1); + + vm.expectRevert(PostStateMatches.selector); + oracle.challengeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: preMatrix, + _preState: leaves[0], + _preStateProof: preProof, + _postState: leaves[1], + _postStateProof: postProof + }); + + LPPMetaData metaData = oracle.proposalMetadata(address(this), TEST_UUID); + assertFalse(metaData.countered()); + } + + /// @notice Tests that an invalid leaf can not be countered with non-contiguous states. + function test_challenge_statesNotContiguous_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136 * 2); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + bytes memory phonyData = new bytes(136 * 2); + for (uint256 i = 0; i < phonyData.length / 2; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree with mismatching state commitments. + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, phonyData, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, phonyData); + leaves[0].stateCommitment = stateCommitments[0]; + leaves[1].stateCommitment = stateCommitments[1]; + leaves[2].stateCommitment = stateCommitments[2]; + + // Create a proof array with 16 elements. + bytes32[] memory preProof = new bytes32[](16); + preProof[0] = _hashLeaf(leaves[1]); + preProof[1] = keccak256(abi.encode(_hashLeaf(leaves[2]), bytes32(0))); + bytes32[] memory postProof = new bytes32[](16); + postProof[0] = _hashLeaf(leaves[0]); + postProof[1] = keccak256(abi.encode(_hashLeaf(leaves[2]), bytes32(0))); + for (uint256 i = 2; i < preProof.length; i++) { + bytes32 zeroHash = oracle.zeroHashes(i); + preProof[i] = zeroHash; + postProof[i] = zeroHash; + } + + LibKeccak.StateMatrix memory preMatrix = _stateMatrixAtBlockIndex(data, 2); + + vm.expectRevert(StatesNotContiguous.selector); + oracle.challengeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: preMatrix, + _preState: leaves[1], + _preStateProof: postProof, + _postState: leaves[0], + _postStateProof: preProof + }); + } + + /// @notice Tests that an invalid leaf can not be countered with an incorrect prestate matrix reveal. + function test_challenge_invalidPreimage_reverts() public { + // Allocate the preimage data. + bytes memory data = new bytes(136 * 2); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + bytes memory phonyData = new bytes(136 * 2); + for (uint256 i = 0; i < phonyData.length / 2; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree with mismatching state commitments. + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, phonyData, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, phonyData); + leaves[0].stateCommitment = stateCommitments[0]; + leaves[1].stateCommitment = stateCommitments[1]; + leaves[2].stateCommitment = stateCommitments[2]; + + // Create a proof array with 16 elements. + bytes32[] memory preProof = new bytes32[](16); + preProof[0] = _hashLeaf(leaves[1]); + preProof[1] = keccak256(abi.encode(_hashLeaf(leaves[2]), bytes32(0))); + bytes32[] memory postProof = new bytes32[](16); + postProof[0] = _hashLeaf(leaves[0]); + postProof[1] = keccak256(abi.encode(_hashLeaf(leaves[2]), bytes32(0))); + for (uint256 i = 2; i < preProof.length; i++) { + bytes32 zeroHash = oracle.zeroHashes(i); + preProof[i] = zeroHash; + postProof[i] = zeroHash; + } + + LibKeccak.StateMatrix memory preMatrix = _stateMatrixAtBlockIndex(data, 2); + + vm.expectRevert(InvalidPreimage.selector); + oracle.challengeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: preMatrix, + _preState: leaves[0], + _preStateProof: preProof, + _postState: leaves[1], + _postStateProof: postProof + }); + } + + /// @notice Tests that an invalid leaf can be countered with the `challenge` function in the middle of the tree. + function test_challenge_invalidCommitment_succeeds() public { + // Allocate the preimage data. + bytes memory data = new bytes(136 * 2); + for (uint256 i; i < data.length; i++) { + data[i] = 0xFF; + } + bytes memory phonyData = new bytes(136 * 2); + for (uint256 i = 0; i < phonyData.length / 2; i++) { + data[i] = 0xFF; + } + + // Initialize the proposal. + oracle.initLPP{ value: oracle.MIN_BOND_SIZE() }(TEST_UUID, 0, uint32(data.length)); + + // Add the leaves to the tree with mismatching state commitments. + LibKeccak.StateMatrix memory stateMatrix; + bytes32[] memory stateCommitments = _generateStateCommitments(stateMatrix, data); + oracle.addLeavesLPP(TEST_UUID, 0, phonyData, stateCommitments, true); + + // Construct the leaf preimage data for the blocks added. + LibKeccak.StateMatrix memory matrix; + PreimageOracle.Leaf[] memory leaves = _generateLeaves(matrix, phonyData); + leaves[0].stateCommitment = stateCommitments[0]; + leaves[1].stateCommitment = stateCommitments[1]; + leaves[2].stateCommitment = stateCommitments[2]; + + // Create a proof array with 16 elements. + bytes32[] memory preProof = new bytes32[](16); + preProof[0] = _hashLeaf(leaves[1]); + preProof[1] = keccak256(abi.encode(_hashLeaf(leaves[2]), bytes32(0))); + bytes32[] memory postProof = new bytes32[](16); + postProof[0] = _hashLeaf(leaves[0]); + postProof[1] = keccak256(abi.encode(_hashLeaf(leaves[2]), bytes32(0))); + for (uint256 i = 2; i < preProof.length; i++) { + bytes32 zeroHash = oracle.zeroHashes(i); + preProof[i] = zeroHash; + postProof[i] = zeroHash; + } + + uint256 balanceBefore = address(this).balance; + LibKeccak.StateMatrix memory preMatrix = _stateMatrixAtBlockIndex(data, 1); + oracle.challengeLPP({ + _claimant: address(this), + _uuid: TEST_UUID, + _stateMatrix: preMatrix, + _preState: leaves[0], + _preStateProof: preProof, + _postState: leaves[1], + _postStateProof: postProof + }); + assertEq(address(this).balance, balanceBefore + oracle.MIN_BOND_SIZE()); + assertEq(oracle.proposalBonds(address(this), TEST_UUID), 0); + + LPPMetaData metaData = oracle.proposalMetadata(address(this), TEST_UUID); + assertTrue(metaData.countered()); + } + + /// @notice Hashes leaf data for the preimage proposals tree + function _hashLeaf(PreimageOracle.Leaf memory _leaf) internal pure returns (bytes32 leaf_) { + leaf_ = keccak256(abi.encodePacked(_leaf.input, _leaf.index, _leaf.stateCommitment)); + } + + /// @notice Helper to construct the keccak merkle tree's leaves from a given input `_data`. + function _generateLeaves( + LibKeccak.StateMatrix memory _stateMatrix, + bytes memory _data + ) + internal + pure + returns (PreimageOracle.Leaf[] memory leaves_) + { + bytes memory data = LibKeccak.padMemory(_data); + uint256 numCommitments = data.length / LibKeccak.BLOCK_SIZE_BYTES; + + leaves_ = new PreimageOracle.Leaf[](numCommitments); + for (uint256 i = 0; i < numCommitments; i++) { + bytes memory blockSlice = Bytes.slice(data, i * LibKeccak.BLOCK_SIZE_BYTES, LibKeccak.BLOCK_SIZE_BYTES); + LibKeccak.absorb(_stateMatrix, blockSlice); + LibKeccak.permutation(_stateMatrix); + + leaves_[i] = PreimageOracle.Leaf({ + input: blockSlice, + index: uint32(i), + stateCommitment: keccak256(abi.encode(_stateMatrix)) + }); + } + } + + /// @notice Helper to get the keccak state matrix before applying the block at `_blockIndex` within `_data`. + function _stateMatrixAtBlockIndex( + bytes memory _data, + uint256 _blockIndex + ) + internal + pure + returns (LibKeccak.StateMatrix memory matrix_) + { + bytes memory data = LibKeccak.padMemory(_data); + + for (uint256 i = 0; i < _blockIndex; i++) { + bytes memory blockSlice = Bytes.slice(data, i * LibKeccak.BLOCK_SIZE_BYTES, LibKeccak.BLOCK_SIZE_BYTES); + LibKeccak.absorb(matrix_, blockSlice); + LibKeccak.permutation(matrix_); + } + } + + /// @notice Helper to construct the keccak state commitments for each block processed in the input `_data`. + function _generateStateCommitments( + LibKeccak.StateMatrix memory _stateMatrix, + bytes memory _data + ) + internal + pure + returns (bytes32[] memory stateCommitments_) + { + bytes memory data = LibKeccak.padMemory(_data); + uint256 numCommitments = data.length / LibKeccak.BLOCK_SIZE_BYTES; + + stateCommitments_ = new bytes32[](numCommitments); + for (uint256 i = 0; i < numCommitments; i++) { + bytes memory blockSlice = Bytes.slice(data, i * LibKeccak.BLOCK_SIZE_BYTES, LibKeccak.BLOCK_SIZE_BYTES); + LibKeccak.absorb(_stateMatrix, blockSlice); + LibKeccak.permutation(_stateMatrix); + + stateCommitments_[i] = keccak256(abi.encode(_stateMatrix)); + } + } + + /// @notice Calls out to the `go-ffi` tool to generate a merkle proof for the leaf at `_leafIdx` in a merkle tree + /// constructed with `_leaves`. + function _generateProof( + uint256 _leafIdx, + PreimageOracle.Leaf[] memory _leaves + ) + internal + returns (bytes32 root_, bytes32[] memory proof_) + { + bytes32[] memory leaves = new bytes32[](_leaves.length); + for (uint256 i = 0; i < _leaves.length; i++) { + leaves[i] = _hashLeaf(_leaves[i]); + } + + string[] memory commands = new string[](5); + commands[0] = "scripts/go-ffi/go-ffi"; + commands[1] = "merkle"; + commands[2] = "gen_proof"; + commands[3] = vm.toString(abi.encodePacked(leaves)); + commands[4] = vm.toString(_leafIdx); + (root_, proof_) = abi.decode(vm.ffi(commands), (bytes32, bytes32[])); + } + + fallback() external payable { } + + receive() external payable { } +} + +/// @notice Sets the status byte of a hash. +function _setStatusByte(bytes32 _hash, uint8 _status) pure returns (bytes32 out_) { + assembly { + out_ := or(and(not(shl(248, 0xFF)), _hash), shl(248, _status)) + } +} + +/// @notice Computes a precompile key for a given precompile address and input. +function precompilePreimageKey(address _precompile, bytes memory _input) pure returns (bytes32 key_) { + bytes memory p = abi.encodePacked(_precompile, _input); + uint256 sz = 20 + _input.length; + assembly { + let h := keccak256(add(0x20, p), sz) + // Mask out prefix byte, replace with type 6 byte + key_ := or(and(h, not(shl(248, 0xFF))), shl(248, 6)) + } +} diff --git a/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol b/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol new file mode 100644 index 000000000000..5089337b9d34 --- /dev/null +++ b/packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import "src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeErrors.sol"; + +import { Test } from "forge-std/Test.sol"; +import { FaultDisputeGame_Init, _changeClaimStatus } from "test/dispute/FaultDisputeGame.t.sol"; + +contract AnchorStateRegistry_Init is FaultDisputeGame_Init { + function setUp() public virtual override { + // Duplicating the initialization/setup logic of FaultDisputeGame_Test. + // See that test for more information, actual values here not really important. + Claim rootClaim = Claim.wrap(bytes32((uint256(1) << 248) | uint256(10))); + bytes memory absolutePrestateData = abi.encode(0); + Claim absolutePrestate = _changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData)), VMStatuses.UNFINISHED); + + super.setUp(); + super.init({ rootClaim: rootClaim, absolutePrestate: absolutePrestate, l2BlockNumber: 0x10 }); + } +} + +contract AnchorStateRegistry_Initialize_Test is AnchorStateRegistry_Init { + /// @dev Tests that initialization is successful. + function test_initialize_succeeds() public { + (Hash cannonRoot, uint256 cannonL2BlockNumber) = anchorStateRegistry.anchors(GameTypes.CANNON); + (Hash permissionedCannonRoot, uint256 permissionedCannonL2BlockNumber) = + anchorStateRegistry.anchors(GameTypes.PERMISSIONED_CANNON); + (Hash alphabetRoot, uint256 alphabetL2BlockNumber) = anchorStateRegistry.anchors(GameTypes.ALPHABET); + assertEq(cannonRoot.raw(), 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF); + assertEq(cannonL2BlockNumber, 0); + assertEq(permissionedCannonRoot.raw(), 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF); + assertEq(permissionedCannonL2BlockNumber, 0); + assertEq(alphabetRoot.raw(), 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF); + assertEq(alphabetL2BlockNumber, 0); + } +} + +contract AnchorStateRegistry_TryUpdateAnchorState_Test is AnchorStateRegistry_Init { + /// @dev Tests that updating the anchor state succeeds when the game state is valid and newer. + function test_tryUpdateAnchorState_validNewerState_succeeds() public { + // Confirm that the anchor state is older than the game state. + (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assert(l2BlockNumber < gameProxy.l2BlockNumber()); + + // Mock the state that we want. + vm.mockCall( + address(gameProxy), abi.encodeWithSelector(gameProxy.status.selector), abi.encode(GameStatus.DEFENDER_WINS) + ); + + // Try to update the anchor state. + vm.prank(address(gameProxy)); + anchorStateRegistry.tryUpdateAnchorState(); + + // Confirm that the anchor state is now the same as the game state. + (root, l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assertEq(l2BlockNumber, gameProxy.l2BlockNumber()); + assertEq(root.raw(), gameProxy.rootClaim().raw()); + } + + /// @dev Tests that updating the anchor state fails when the game state is valid but older. + function test_tryUpdateAnchorState_validOlderState_fails() public { + // Confirm that the anchor state is newer than the game state. + vm.mockCall(address(gameProxy), abi.encodeWithSelector(gameProxy.l2BlockNumber.selector), abi.encode(0)); + (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assert(l2BlockNumber >= gameProxy.l2BlockNumber()); + + // Mock the state that we want. + vm.mockCall(address(gameProxy), abi.encodeWithSelector(gameProxy.l2BlockNumber.selector), abi.encode(0)); + vm.mockCall( + address(gameProxy), abi.encodeWithSelector(gameProxy.status.selector), abi.encode(GameStatus.DEFENDER_WINS) + ); + + // Try to update the anchor state. + vm.prank(address(gameProxy)); + anchorStateRegistry.tryUpdateAnchorState(); + + // Confirm that the anchor state has not updated. + (Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assertEq(updatedL2BlockNumber, l2BlockNumber); + assertEq(updatedRoot.raw(), root.raw()); + } + + /// @dev Tests that updating the anchor state fails when the game state is invalid. + function test_tryUpdateAnchorState_invalidNewerState_fails() public { + // Confirm that the anchor state is older than the game state. + (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assert(l2BlockNumber < gameProxy.l2BlockNumber()); + + // Mock the state that we want. + vm.mockCall( + address(gameProxy), + abi.encodeWithSelector(gameProxy.status.selector), + abi.encode(GameStatus.CHALLENGER_WINS) + ); + + // Try to update the anchor state. + vm.prank(address(gameProxy)); + anchorStateRegistry.tryUpdateAnchorState(); + + // Confirm that the anchor state has not updated. + (Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assertEq(updatedL2BlockNumber, l2BlockNumber); + assertEq(updatedRoot.raw(), root.raw()); + } + + /// @dev Tests that updating the anchor state fails when the game is not registered with the factory. + function test_tryUpdateAnchorState_invalidGame_fails() public { + // Confirm that the anchor state is older than the game state. + (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assert(l2BlockNumber < gameProxy.l2BlockNumber()); + + // Mock the state that we want. + vm.mockCall( + address(disputeGameFactory), + abi.encodeWithSelector( + disputeGameFactory.games.selector, gameProxy.gameType(), gameProxy.rootClaim(), gameProxy.extraData() + ), + abi.encode(address(0), 0) + ); + + // Try to update the anchor state. + vm.prank(address(gameProxy)); + vm.expectRevert("AnchorStateRegistry: fault dispute game not registered with factory"); + anchorStateRegistry.tryUpdateAnchorState(); + + // Confirm that the anchor state has not updated. + (Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assertEq(updatedL2BlockNumber, l2BlockNumber); + assertEq(updatedRoot.raw(), root.raw()); + } +} diff --git a/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol b/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol new file mode 100644 index 000000000000..c7afeae684e1 --- /dev/null +++ b/packages/contracts-bedrock/test/dispute/DelayedWETH.t.sol @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import "src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeErrors.sol"; + +import { Test } from "forge-std/Test.sol"; +import { DisputeGameFactory, IDisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; + +contract DelayedWETH_Init is CommonTest { + event Approval(address indexed src, address indexed guy, uint256 wad); + event Transfer(address indexed src, address indexed dst, uint256 wad); + event Deposit(address indexed dst, uint256 wad); + event Withdrawal(address indexed src, uint256 wad); + event Unwrap(address indexed src, uint256 wad); + + function setUp() public virtual override { + super.enableFaultProofs(); + super.setUp(); + + // Transfer ownership of delayed WETH to the test contract. + vm.prank(deploy.mustGetAddress("SystemOwnerSafe")); + delayedWeth.transferOwnership(address(this)); + } +} + +contract DelayedWETH_Initialize_Test is DelayedWETH_Init { + /// @dev Tests that initialization is successful. + function test_initialize_succeeds() public { + assertEq(delayedWeth.owner(), address(this)); + assertEq(address(delayedWeth.config()), address(superchainConfig)); + } +} + +contract DelayedWETH_Unlock_Test is DelayedWETH_Init { + /// @dev Tests that unlocking once is successful. + function test_unlock_once_succeeds() public { + delayedWeth.unlock(alice, 1 ether); + (uint256 amount, uint256 timestamp) = delayedWeth.withdrawals(address(this), alice); + assertEq(amount, 1 ether); + assertEq(timestamp, block.timestamp); + } + + /// @dev TEsts that unlocking twice is successful and timestamp/amount is updated. + function test_unlock_twice_succeeds() public { + // Unlock once. + uint256 ts = block.timestamp; + delayedWeth.unlock(alice, 1 ether); + (uint256 amount1, uint256 timestamp1) = delayedWeth.withdrawals(address(this), alice); + assertEq(amount1, 1 ether); + assertEq(timestamp1, ts); + + // Go forward in time. + vm.warp(ts + 1); + + // Unlock again works. + delayedWeth.unlock(alice, 1 ether); + (uint256 amount2, uint256 timestamp2) = delayedWeth.withdrawals(address(this), alice); + assertEq(amount2, 2 ether); + assertEq(timestamp2, ts + 1); + } +} + +contract DelayedWETH_Withdraw_Test is DelayedWETH_Init { + /// @dev Tests that withdrawing while unlocked and delay has passed is successful. + function test_withdraw_whileUnlocked_succeeds() public { + // Deposit some WETH. + vm.prank(alice); + delayedWeth.deposit{ value: 1 ether }(); + uint256 balance = address(alice).balance; + + // Unlock the withdrawal. + vm.prank(alice); + delayedWeth.unlock(alice, 1 ether); + + // Wait for the delay. + vm.warp(block.timestamp + delayedWeth.delay() + 1); + + // Withdraw the WETH. + vm.expectEmit(true, true, false, false); + emit Withdrawal(address(alice), 1 ether); + vm.prank(alice); + delayedWeth.withdraw(alice, 1 ether); + assertEq(address(alice).balance, balance + 1 ether); + } + + /// @dev Tests that withdrawing when unlock was not called fails. + function test_withdraw_whileLocked_fails() public { + // Deposit some WETH. + vm.prank(alice); + delayedWeth.deposit{ value: 1 ether }(); + uint256 balance = address(alice).balance; + + // Withdraw fails when unlock not called. + vm.expectRevert("DelayedWETH: withdrawal not unlocked"); + vm.prank(alice); + delayedWeth.withdraw(alice, 0 ether); + assertEq(address(alice).balance, balance); + } + + /// @dev Tests that withdrawing while locked and delay has not passed fails. + function test_withdraw_whileLockedNotLongEnough_fails() public { + // Deposit some WETH. + vm.prank(alice); + delayedWeth.deposit{ value: 1 ether }(); + uint256 balance = address(alice).balance; + + // Call unlock. + vm.prank(alice); + delayedWeth.unlock(alice, 1 ether); + + // Wait for the delay, but not long enough. + vm.warp(block.timestamp + delayedWeth.delay() - 1); + + // Withdraw fails when delay not met. + vm.expectRevert("DelayedWETH: withdrawal delay not met"); + vm.prank(alice); + delayedWeth.withdraw(alice, 1 ether); + assertEq(address(alice).balance, balance); + } + + /// @dev Tests that withdrawing more than unlocked amount fails. + function test_withdraw_tooMuch_fails() public { + // Deposit some WETH. + vm.prank(alice); + delayedWeth.deposit{ value: 1 ether }(); + uint256 balance = address(alice).balance; + + // Unlock the withdrawal. + vm.prank(alice); + delayedWeth.unlock(alice, 1 ether); + + // Wait for the delay. + vm.warp(block.timestamp + delayedWeth.delay() + 1); + + // Withdraw too much fails. + vm.expectRevert("DelayedWETH: insufficient unlocked withdrawal"); + vm.prank(alice); + delayedWeth.withdraw(alice, 2 ether); + assertEq(address(alice).balance, balance); + } + + /// @dev Tests that withdrawing while paused fails. + function test_withdraw_whenPaused_fails() public { + // Deposit some WETH. + vm.prank(alice); + delayedWeth.deposit{ value: 1 ether }(); + + // Unlock the withdrawal. + vm.prank(alice); + delayedWeth.unlock(alice, 1 ether); + + // Wait for the delay. + vm.warp(block.timestamp + delayedWeth.delay() + 1); + + // Pause the contract. + address guardian = optimismPortal.GUARDIAN(); + vm.prank(guardian); + superchainConfig.pause("identifier"); + + // Withdraw fails. + vm.expectRevert("DelayedWETH: contract is paused"); + vm.prank(alice); + delayedWeth.withdraw(alice, 1 ether); + } +} + +contract DelayedWETH_Recover_Test is DelayedWETH_Init { + /// @dev Tests that recovering WETH succeeds. + function test_recover_succeeds() public { + // Transfer ownership to alice. + delayedWeth.transferOwnership(alice); + + // Give the contract some WETH to recover. + vm.deal(address(delayedWeth), 1 ether); + + // Record the initial balance. + uint256 initialBalance = address(alice).balance; + + // Recover the WETH. + vm.prank(alice); + delayedWeth.recover(1 ether); + + // Verify the WETH was recovered. + assertEq(address(delayedWeth).balance, 0); + assertEq(address(alice).balance, initialBalance + 1 ether); + } + + /// @dev Tests that recovering WETH by non-owner fails. + function test_recover_byNonOwner_fails() public { + // Pretend to be a non-owner. + vm.prank(alice); + + // Recover fails. + vm.expectRevert("DelayedWETH: not owner"); + delayedWeth.recover(1 ether); + } + + /// @dev Tests that recovering more than the balance recovers what it can. + function test_recover_moreThanBalance_succeeds() public { + // Transfer ownership to alice. + delayedWeth.transferOwnership(alice); + + // Give the contract some WETH to recover. + vm.deal(address(delayedWeth), 0.5 ether); + + // Record the initial balance. + uint256 initialBalance = address(alice).balance; + + // Recover the WETH. + vm.prank(alice); + delayedWeth.recover(1 ether); + + // Verify the WETH was recovered. + assertEq(address(delayedWeth).balance, 0); + assertEq(address(alice).balance, initialBalance + 0.5 ether); + } +} + +contract DelayedWETH_Hold_Test is DelayedWETH_Init { + /// @dev Tests that holding WETH succeeds. + function test_hold_succeeds() public { + uint256 amount = 1 ether; + + // Pretend to be alice and deposit some WETH. + vm.prank(alice); + delayedWeth.deposit{ value: amount }(); + + // Hold some WETH. + vm.expectEmit(true, true, true, false); + emit Approval(alice, address(this), amount); + delayedWeth.hold(alice, amount); + + // Verify the allowance. + assertEq(delayedWeth.allowance(alice, address(this)), amount); + + // We can transfer. + delayedWeth.transferFrom(alice, address(this), amount); + + // Verify the transfer. + assertEq(delayedWeth.balanceOf(address(this)), amount); + } + + /// @dev Tests that holding WETH by non-owner fails. + function test_hold_byNonOwner_fails() public { + // Pretend to be a non-owner. + vm.prank(alice); + + // Hold fails. + vm.expectRevert("DelayedWETH: not owner"); + delayedWeth.hold(bob, 1 ether); + } +} diff --git a/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol b/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol new file mode 100644 index 000000000000..10e2e9a03060 --- /dev/null +++ b/packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import "src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeErrors.sol"; + +import { Test } from "forge-std/Test.sol"; +import { DisputeGameFactory, IDisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; + +contract DisputeGameFactory_Init is CommonTest { + FakeClone fakeClone; + + event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim); + event ImplementationSet(address indexed impl, GameType indexed gameType); + event InitBondUpdated(GameType indexed gameType, uint256 indexed newBond); + + function setUp() public virtual override { + super.enableFaultProofs(); + super.setUp(); + fakeClone = new FakeClone(); + + // Transfer ownership of the factory to the test contract. + vm.prank(deploy.mustGetAddress("SystemOwnerSafe")); + disputeGameFactory.transferOwnership(address(this)); + } +} + +contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init { + /// @dev Tests that the `create` function succeeds when creating a new dispute game + /// with a `GameType` that has an implementation set. + function testFuzz_create_succeeds( + uint8 gameType, + Claim rootClaim, + bytes calldata extraData, + uint256 _value + ) + public + { + // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. + GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); + // Ensure the rootClaim has a VMStatus that disagrees with the validity. + rootClaim = changeClaimStatus(rootClaim, VMStatuses.INVALID); + + // Set all three implementations to the same `FakeClone` contract. + for (uint8 i; i < 3; i++) { + GameType lgt = GameType.wrap(i); + disputeGameFactory.setImplementation(lgt, IDisputeGame(address(fakeClone))); + disputeGameFactory.setInitBond(lgt, _value); + } + + vm.deal(address(this), _value); + + vm.expectEmit(false, true, true, false); + emit DisputeGameCreated(address(0), gt, rootClaim); + IDisputeGame proxy = disputeGameFactory.create{ value: _value }(gt, rootClaim, extraData); + + (IDisputeGame game, Timestamp timestamp) = disputeGameFactory.games(gt, rootClaim, extraData); + + // Ensure that the dispute game was assigned to the `disputeGames` mapping. + assertEq(address(game), address(proxy)); + assertEq(Timestamp.unwrap(timestamp), block.timestamp); + assertEq(disputeGameFactory.gameCount(), 1); + + (, Timestamp timestamp2, IDisputeGame game2) = disputeGameFactory.gameAtIndex(0); + assertEq(address(game2), address(proxy)); + assertEq(Timestamp.unwrap(timestamp2), block.timestamp); + + // Ensure that the game proxy received the bonded ETH. + assertEq(address(proxy).balance, _value); + } + + /// @dev Tests that the `create` function reverts when creating a new dispute game with an insufficient bond. + function testFuzz_create_insufficientBond_reverts( + uint8 gameType, + Claim rootClaim, + bytes calldata extraData + ) + public + { + // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. + GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); + // Ensure the rootClaim has a VMStatus that disagrees with the validity. + rootClaim = changeClaimStatus(rootClaim, VMStatuses.INVALID); + + // Set all three implementations to the same `FakeClone` contract. + for (uint8 i; i < 3; i++) { + GameType lgt = GameType.wrap(i); + disputeGameFactory.setImplementation(lgt, IDisputeGame(address(fakeClone))); + disputeGameFactory.setInitBond(lgt, 1 ether); + } + + vm.expectRevert(InsufficientBond.selector); + disputeGameFactory.create(gt, rootClaim, extraData); + } + + /// @dev Tests that the `create` function reverts when there is no implementation + /// set for the given `GameType`. + function testFuzz_create_noImpl_reverts(uint32 gameType, Claim rootClaim, bytes calldata extraData) public { + // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. We skip over + // game type = 0, since the deploy script set the implementation for that game type. + GameType gt = GameType.wrap(uint32(bound(gameType, 2, type(uint32).max))); + // Ensure the rootClaim has a VMStatus that disagrees with the validity. + rootClaim = changeClaimStatus(rootClaim, VMStatuses.INVALID); + + vm.expectRevert(abi.encodeWithSelector(NoImplementation.selector, gt)); + disputeGameFactory.create(gt, rootClaim, extraData); + } + + /// @dev Tests that the `create` function reverts when there exists a dispute game with the same UUID. + function testFuzz_create_sameUUID_reverts(uint8 gameType, Claim rootClaim, bytes calldata extraData) public { + // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. + GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); + // Ensure the rootClaim has a VMStatus that disagrees with the validity. + rootClaim = changeClaimStatus(rootClaim, VMStatuses.INVALID); + + // Set all three implementations to the same `FakeClone` contract. + for (uint8 i; i < 3; i++) { + disputeGameFactory.setImplementation(GameType.wrap(i), IDisputeGame(address(fakeClone))); + } + + // Create our first dispute game - this should succeed. + vm.expectEmit(false, true, true, false); + emit DisputeGameCreated(address(0), gt, rootClaim); + IDisputeGame proxy = disputeGameFactory.create(gt, rootClaim, extraData); + + (IDisputeGame game, Timestamp timestamp) = disputeGameFactory.games(gt, rootClaim, extraData); + // Ensure that the dispute game was assigned to the `disputeGames` mapping. + assertEq(address(game), address(proxy)); + assertEq(Timestamp.unwrap(timestamp), block.timestamp); + + // Ensure that the `create` function reverts when called with parameters that would result in the same UUID. + vm.expectRevert( + abi.encodeWithSelector(GameAlreadyExists.selector, disputeGameFactory.getGameUUID(gt, rootClaim, extraData)) + ); + disputeGameFactory.create(gt, rootClaim, extraData); + } + + function changeClaimStatus(Claim _claim, VMStatus _status) public pure returns (Claim out_) { + assembly { + out_ := or(and(not(shl(248, 0xFF)), _claim), shl(248, _status)) + } + } +} + +contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init { + /// @dev Tests that the `setImplementation` function properly sets the implementation for a given `GameType`. + function test_setImplementation_succeeds() public { + vm.expectEmit(true, true, true, true, address(disputeGameFactory)); + emit ImplementationSet(address(1), GameTypes.CANNON); + + // Set the implementation for the `GameTypes.CANNON` enum value. + disputeGameFactory.setImplementation(GameTypes.CANNON, IDisputeGame(address(1))); + + // Ensure that the implementation for the `GameTypes.CANNON` enum value is set. + assertEq(address(disputeGameFactory.gameImpls(GameTypes.CANNON)), address(1)); + } + + /// @dev Tests that the `setImplementation` function reverts when called by a non-owner. + function test_setImplementation_notOwner_reverts() public { + // Ensure that the `setImplementation` function reverts when called by a non-owner. + vm.prank(address(0)); + vm.expectRevert("Ownable: caller is not the owner"); + disputeGameFactory.setImplementation(GameTypes.CANNON, IDisputeGame(address(1))); + } +} + +contract DisputeGameFactory_SetInitBond_Test is DisputeGameFactory_Init { + /// @dev Tests that the `setInitBond` function properly sets the init bond for a given `GameType`. + function test_setInitBond_succeeds() public { + // There should be no init bond for the `GameTypes.CANNON` enum value, it has not been set. + assertEq(disputeGameFactory.initBonds(GameTypes.CANNON), 0); + + vm.expectEmit(true, true, true, true, address(disputeGameFactory)); + emit InitBondUpdated(GameTypes.CANNON, 1 ether); + + // Set the init bond for the `GameTypes.CANNON` enum value. + disputeGameFactory.setInitBond(GameTypes.CANNON, 1 ether); + + // Ensure that the init bond for the `GameTypes.CANNON` enum value is set. + assertEq(disputeGameFactory.initBonds(GameTypes.CANNON), 1 ether); + } + + /// @dev Tests that the `setInitBond` function reverts when called by a non-owner. + function test_setInitBond_notOwner_reverts() public { + // Ensure that the `setInitBond` function reverts when called by a non-owner. + vm.prank(address(0)); + vm.expectRevert("Ownable: caller is not the owner"); + disputeGameFactory.setInitBond(GameTypes.CANNON, 1 ether); + } +} + +contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init { + /// @dev Tests that the `getGameUUID` function returns the correct hash when comparing + /// against the keccak256 hash of the abi-encoded parameters. + function testDiff_getGameUUID_succeeds(uint8 gameType, Claim rootClaim, bytes calldata extraData) public { + // Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. + GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2))); + + assertEq( + Hash.unwrap(disputeGameFactory.getGameUUID(gt, rootClaim, extraData)), + keccak256(abi.encode(gt, rootClaim, extraData)) + ); + } +} + +contract DisputeGameFactory_Owner_Test is DisputeGameFactory_Init { + /// @dev Tests that the `owner` function returns the correct address after deployment. + function test_owner_succeeds() public { + assertEq(disputeGameFactory.owner(), address(this)); + } +} + +contract DisputeGameFactory_TransferOwnership_Test is DisputeGameFactory_Init { + /// @dev Tests that the `transferOwnership` function succeeds when called by the owner. + function test_transferOwnership_succeeds() public { + disputeGameFactory.transferOwnership(address(1)); + assertEq(disputeGameFactory.owner(), address(1)); + } + + /// @dev Tests that the `transferOwnership` function reverts when called by a non-owner. + function test_transferOwnership_notOwner_reverts() public { + vm.prank(address(0)); + vm.expectRevert("Ownable: caller is not the owner"); + disputeGameFactory.transferOwnership(address(1)); + } +} + +contract DisputeGameFactory_FindLatestGames_Test is DisputeGameFactory_Init { + function setUp() public override { + super.setUp(); + + // Set three implementations to the same `FakeClone` contract. + for (uint8 i; i < 3; i++) { + GameType lgt = GameType.wrap(i); + disputeGameFactory.setImplementation(lgt, IDisputeGame(address(fakeClone))); + disputeGameFactory.setInitBond(lgt, 0); + } + } + + /// @dev Tests that `findLatestGames` returns an empty array when the passed starting index is greater than or equal + /// to the game count. + function testFuzz_findLatestGames_greaterThanLength_succeeds(uint256 _start) public { + // Create some dispute games of varying game types. + for (uint256 i; i < 1 << 5; i++) { + disputeGameFactory.create(GameType.wrap(uint8(i % 2)), Claim.wrap(bytes32(i)), abi.encode(i)); + } + + // Bound the starting index to a number greater than the length of the game list. + uint256 gameCount = disputeGameFactory.gameCount(); + _start = bound(_start, gameCount, type(uint256).max); + + // The array's length should always be 0. + IDisputeGameFactory.GameSearchResult[] memory games = + disputeGameFactory.findLatestGames(GameTypes.CANNON, _start, 1); + assertEq(games.length, 0); + } + + /// @dev Tests that `findLatestGames` returns the correct games. + function test_findLatestGames_static_succeeds() public { + // Create some dispute games of varying game types. + for (uint256 i; i < 1 << 5; i++) { + disputeGameFactory.create(GameType.wrap(uint8(i % 3)), Claim.wrap(bytes32(i)), abi.encode(i)); + } + + uint256 gameCount = disputeGameFactory.gameCount(); + + IDisputeGameFactory.GameSearchResult[] memory games; + + games = disputeGameFactory.findLatestGames(GameType.wrap(0), gameCount - 1, 1); + assertEq(games.length, 1); + assertEq(games[0].index, 30); + (GameType gameType, Timestamp createdAt, IDisputeGame game) = games[0].metadata.unpack(); + assertEq(gameType.raw(), 0); + assertEq(createdAt.raw(), block.timestamp); + + games = disputeGameFactory.findLatestGames(GameType.wrap(1), gameCount - 1, 1); + assertEq(games.length, 1); + assertEq(games[0].index, 31); + (gameType, createdAt, game) = games[0].metadata.unpack(); + assertEq(gameType.raw(), 1); + assertEq(createdAt.raw(), block.timestamp); + + games = disputeGameFactory.findLatestGames(GameType.wrap(2), gameCount - 1, 1); + assertEq(games.length, 1); + assertEq(games[0].index, 29); + (gameType, createdAt, game) = games[0].metadata.unpack(); + assertEq(gameType.raw(), 2); + assertEq(createdAt.raw(), block.timestamp); + } + + /// @dev Tests that `findLatestGames` returns the correct games, if there are less than `_n` games of the given type + /// available. + function test_findLatestGames_lessThanNAvailable_succeeds() public { + // Create some dispute games of varying game types. + disputeGameFactory.create(GameType.wrap(1), Claim.wrap(bytes32(0)), abi.encode(0)); + disputeGameFactory.create(GameType.wrap(1), Claim.wrap(bytes32(uint256(1))), abi.encode(1)); + for (uint256 i; i < 1 << 3; i++) { + disputeGameFactory.create(GameType.wrap(0), Claim.wrap(bytes32(i)), abi.encode(i)); + } + + uint256 gameCount = disputeGameFactory.gameCount(); + + IDisputeGameFactory.GameSearchResult[] memory games; + + games = disputeGameFactory.findLatestGames(GameType.wrap(2), gameCount - 1, 5); + assertEq(games.length, 0); + + games = disputeGameFactory.findLatestGames(GameType.wrap(1), gameCount - 1, 5); + assertEq(games.length, 2); + assertEq(games[0].index, 1); + assertEq(games[1].index, 0); + } + + /// @dev Tests that the expected number of games are returned when `findLatestGames` is called. + function testFuzz_findLatestGames_correctAmount_succeeds( + uint256 _numGames, + uint256 _numSearchedGames, + uint256 _n + ) + public + { + _numGames = bound(_numGames, 0, 1 << 8); + _numSearchedGames = bound(_numSearchedGames, 0, _numGames); + _n = bound(_n, 0, _numSearchedGames); + + // Create `_numGames` dispute games, with at least `_numSearchedGames` games. + for (uint256 i; i < _numGames; i++) { + uint8 gameType = i < _numSearchedGames ? 0 : 1; + disputeGameFactory.create(GameType.wrap(gameType), Claim.wrap(bytes32(i)), abi.encode(i)); + } + + // Ensure that the correct number of games are returned. + uint256 start = _numGames == 0 ? 0 : _numGames - 1; + IDisputeGameFactory.GameSearchResult[] memory games = + disputeGameFactory.findLatestGames(GameType.wrap(0), start, _n); + assertEq(games.length, _n); + } +} + +/// @dev A fake clone used for testing the `DisputeGameFactory` contract's `create` function. +contract FakeClone { + function initialize() external payable { + // noop + } + + function extraData() external pure returns (bytes memory) { + return hex"FF0420"; + } + + function parentHash() external pure returns (bytes32) { + return bytes32(0); + } + + function rootClaim() external pure returns (Claim) { + return Claim.wrap(bytes32(0)); + } +} diff --git a/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol new file mode 100644 index 000000000000..3e9d6d65c6a0 --- /dev/null +++ b/packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol @@ -0,0 +1,1619 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import { Test } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; +import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; + +import "src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeErrors.sol"; +import { LibClock } from "src/dispute/lib/LibUDT.sol"; +import { LibPosition } from "src/dispute/lib/LibPosition.sol"; +import { IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; +import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; +import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; + +import { DisputeActor, HonestDisputeActor } from "test/actors/FaultDisputeActors.sol"; + +contract FaultDisputeGame_Init is DisputeGameFactory_Init { + /// @dev The type of the game being tested. + GameType internal constant GAME_TYPE = GameType.wrap(0); + + /// @dev The implementation of the game. + FaultDisputeGame internal gameImpl; + /// @dev The `Clone` proxy of the game. + FaultDisputeGame internal gameProxy; + + /// @dev The extra data passed to the game for initialization. + bytes internal extraData; + + event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant); + + function init(Claim rootClaim, Claim absolutePrestate, uint256 l2BlockNumber) public { + // Set the time to a realistic date. + vm.warp(1690906994); + + // Set the extra data for the game creation + extraData = abi.encode(l2BlockNumber); + + AlphabetVM _vm = new AlphabetVM(absolutePrestate, new PreimageOracle(0, 0)); + + // Deploy an implementation of the fault game + gameImpl = new FaultDisputeGame({ + _gameType: GAME_TYPE, + _absolutePrestate: absolutePrestate, + _maxGameDepth: 2 ** 3, + _splitDepth: 2 ** 2, + _gameDuration: Duration.wrap(7 days), + _vm: _vm, + _weth: delayedWeth, + _anchorStateRegistry: anchorStateRegistry, + _l2ChainId: 10 + }); + + // Register the game implementation with the factory. + disputeGameFactory.setImplementation(GAME_TYPE, gameImpl); + // Create a new game. + gameProxy = FaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, rootClaim, extraData)))); + + // Check immutables + assertEq(gameProxy.gameType().raw(), GAME_TYPE.raw()); + assertEq(gameProxy.absolutePrestate().raw(), absolutePrestate.raw()); + assertEq(gameProxy.maxGameDepth(), 2 ** 3); + assertEq(gameProxy.splitDepth(), 2 ** 2); + assertEq(gameProxy.gameDuration().raw(), 7 days); + assertEq(address(gameProxy.vm()), address(_vm)); + + // Label the proxy + vm.label(address(gameProxy), "FaultDisputeGame_Clone"); + } + + fallback() external payable { } + + receive() external payable { } +} + +contract FaultDisputeGame_Test is FaultDisputeGame_Init { + /// @dev The root claim of the game. + Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32((uint256(1) << 248) | uint256(10))); + + /// @dev The preimage of the absolute prestate claim + bytes internal absolutePrestateData; + /// @dev The absolute prestate of the trace. + Claim internal absolutePrestate; + + /// @dev Minimum bond value that covers all possible moves. + uint256 internal constant MIN_BOND = 50 ether; + + function setUp() public override { + absolutePrestateData = abi.encode(0); + absolutePrestate = _changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData)), VMStatuses.UNFINISHED); + + super.setUp(); + super.init({ rootClaim: ROOT_CLAIM, absolutePrestate: absolutePrestate, l2BlockNumber: 0x10 }); + } + + //////////////////////////////////////////////////////////////// + // `IDisputeGame` Implementation Tests // + //////////////////////////////////////////////////////////////// + + /// @dev Tests that the constructor of the `FaultDisputeGame` reverts when the `_splitDepth` + /// parameter is greater than or equal to the `MAX_GAME_DEPTH` + function test_constructor_wrongArgs_reverts(uint256 _splitDepth) public { + AlphabetVM alphabetVM = new AlphabetVM(absolutePrestate, new PreimageOracle(0, 0)); + + // Test that the constructor reverts when the `_splitDepth` parameter is greater than or equal + // to the `MAX_GAME_DEPTH` parameter. + _splitDepth = bound(_splitDepth, 2 ** 3, type(uint256).max); + vm.expectRevert(InvalidSplitDepth.selector); + new FaultDisputeGame({ + _gameType: GAME_TYPE, + _absolutePrestate: absolutePrestate, + _maxGameDepth: 2 ** 3, + _splitDepth: _splitDepth, + _gameDuration: Duration.wrap(7 days), + _vm: alphabetVM, + _weth: DelayedWETH(payable(address(0))), + _anchorStateRegistry: IAnchorStateRegistry(address(0)), + _l2ChainId: 10 + }); + } + + /// @dev Tests that the game's root claim is set correctly. + function test_rootClaim_succeeds() public { + assertEq(gameProxy.rootClaim().raw(), ROOT_CLAIM.raw()); + } + + /// @dev Tests that the game's extra data is set correctly. + function test_extraData_succeeds() public { + assertEq(gameProxy.extraData(), extraData); + } + + /// @dev Tests that the game's starting timestamp is set correctly. + function test_createdAt_succeeds() public { + assertEq(gameProxy.createdAt().raw(), block.timestamp); + } + + /// @dev Tests that the game's type is set correctly. + function test_gameType_succeeds() public { + assertEq(gameProxy.gameType().raw(), GAME_TYPE.raw()); + } + + /// @dev Tests that the game's data is set correctly. + function test_gameData_succeeds() public { + (GameType gameType, Claim rootClaim, bytes memory _extraData) = gameProxy.gameData(); + + assertEq(gameType.raw(), GAME_TYPE.raw()); + assertEq(rootClaim.raw(), ROOT_CLAIM.raw()); + assertEq(_extraData, extraData); + } + + //////////////////////////////////////////////////////////////// + // `IFaultDisputeGame` Implementation Tests // + //////////////////////////////////////////////////////////////// + + /// @dev Tests that the game cannot be initialized with an output root that commits to <= the configured starting + /// block number + function testFuzz_initialize_cannotProposeGenesis_reverts(uint256 _blockNumber) public { + (, uint256 startingL2Block) = gameProxy.startingOutputRoot(); + _blockNumber = bound(_blockNumber, 0, startingL2Block); + + Claim claim = _dummyClaim(); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, claim)); + gameProxy = + FaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, claim, abi.encode(_blockNumber))))); + } + + /// @dev Tests that the proxy receives ETH from the dispute game factory. + function test_initialize_receivesETH_succeeds(uint128 _value) public { + _value = uint128(bound(_value, gameProxy.getRequiredBond(Position.wrap(1)), type(uint128).max)); + vm.deal(address(this), _value); + + assertEq(address(gameProxy).balance, 0); + gameProxy = FaultDisputeGame( + payable(address(disputeGameFactory.create{ value: _value }(GAME_TYPE, ROOT_CLAIM, abi.encode(1)))) + ); + assertEq(address(gameProxy).balance, 0); + assertEq(delayedWeth.balanceOf(address(gameProxy)), _value); + } + + /// @dev Tests that the game cannot be initialized with extra data > 64 bytes long (root claim + l2 block number + /// concatenated) + function testFuzz_initialize_extraDataTooLong_reverts(uint256 _extraDataLen) public { + // The `DisputeGameFactory` will pack the root claim and the extra data into a single array, which is enforced + // to be at least 64 bytes long. + // We bound the upper end to 23.5KB to ensure that the minimal proxy never surpasses the contract size limit + // in this test, as CWIA proxies store the immutable args in their bytecode. + // [33 bytes, 23.5 KB] + _extraDataLen = bound(_extraDataLen, 33, 23_500); + bytes memory _extraData = new bytes(_extraDataLen); + + // Assign the first 32 bytes in `extraData` to a valid L2 block number passed the starting block. + (, uint256 startingL2Block) = gameProxy.startingOutputRoot(); + assembly { + mstore(add(_extraData, 0x20), add(startingL2Block, 1)) + } + + Claim claim = _dummyClaim(); + vm.expectRevert(abi.encodeWithSelector(ExtraDataTooLong.selector)); + gameProxy = FaultDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, claim, _extraData)))); + } + + /// @dev Tests that the game is initialized with the correct data. + function test_initialize_correctData_succeeds() public { + // Assert that the root claim is initialized correctly. + ( + uint32 parentIndex, + address counteredBy, + address claimant, + uint128 bond, + Claim claim, + Position position, + Clock clock + ) = gameProxy.claimData(0); + assertEq(parentIndex, type(uint32).max); + assertEq(counteredBy, address(0)); + assertEq(claimant, DEFAULT_SENDER); + assertEq(bond, 0); + assertEq(claim.raw(), ROOT_CLAIM.raw()); + assertEq(position.raw(), 1); + assertEq(clock.raw(), LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))).raw()); + + // Assert that the `createdAt` timestamp is correct. + assertEq(gameProxy.createdAt().raw(), block.timestamp); + + // Assert that the blockhash provided is correct. + assertEq(gameProxy.l1Head().raw(), blockhash(block.number - 1)); + } + + /// @dev Tests that the game cannot be initialized twice. + function test_initialize_onlyOnce_succeeds() public { + vm.expectRevert(AlreadyInitialized.selector); + gameProxy.initialize(); + } + + /// @dev Tests that the bond during the bisection game depths is correct. + function test_getRequiredBond_succeeds() public { + for (uint64 i = 0; i < uint64(gameProxy.splitDepth()); i++) { + Position pos = LibPosition.wrap(i, 0); + uint256 bond = gameProxy.getRequiredBond(pos); + + // Reasonable approximation for a max depth of 8. + uint256 expected = 0.08 ether; + for (uint64 j = 0; j < i; j++) { + expected = expected * 217456; + expected = expected / 100000; + } + + assertApproxEqAbs(bond, expected, 0.01 ether); + } + } + + /// @dev Tests that the bond at a depth greater than the maximum game depth reverts. + function test_getRequiredBond_outOfBounds_reverts() public { + Position pos = LibPosition.wrap(uint64(gameProxy.maxGameDepth() + 1), 0); + vm.expectRevert(GameDepthExceeded.selector); + gameProxy.getRequiredBond(pos); + } + + /// @dev Tests that a move while the game status is not `IN_PROGRESS` causes the call to revert + /// with the `GameNotInProgress` error + function test_move_gameNotInProgress_reverts() public { + uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS); + + // Replace the game status in storage. It exists in slot 0 at offset 16. + uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0))); + uint256 offset = 16 << 3; + uint256 mask = 0xFF << offset; + // Replace the byte in the slot value with the challenger wins status. + slot = (slot & ~mask) | (chalWins << offset); + vm.store(address(gameProxy), bytes32(0), bytes32(slot)); + + // Ensure that the game status was properly updated. + GameStatus status = gameProxy.status(); + assertEq(uint256(status), chalWins); + + // Attempt to make a move. Should revert. + vm.expectRevert(GameNotInProgress.selector); + gameProxy.attack(0, Claim.wrap(0)); + } + + /// @dev Tests that an attempt to defend the root claim reverts with the `CannotDefendRootClaim` error. + function test_move_defendRoot_reverts() public { + vm.expectRevert(CannotDefendRootClaim.selector); + gameProxy.defend(0, _dummyClaim()); + } + + /// @dev Tests that an attempt to move against a claim that does not exist reverts with the + /// `ParentDoesNotExist` error. + function test_move_nonExistentParent_reverts() public { + Claim claim = _dummyClaim(); + + // Expect an out of bounds revert for an attack + vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x32)); + gameProxy.attack(1, claim); + + // Expect an out of bounds revert for a defense + vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x32)); + gameProxy.defend(1, claim); + } + + /// @dev Tests that an attempt to move at the maximum game depth reverts with the + /// `GameDepthExceeded` error. + function test_move_gameDepthExceeded_reverts() public { + Claim claim = _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC); + + uint256 maxDepth = gameProxy.maxGameDepth(); + + for (uint256 i = 0; i <= maxDepth; i++) { + // At the max game depth, the `_move` function should revert with + // the `GameDepthExceeded` error. + if (i == maxDepth) { + vm.expectRevert(GameDepthExceeded.selector); + } + gameProxy.attack{ value: MIN_BOND }(i, claim); + } + } + + /// @dev Tests that a move made after the clock time has exceeded reverts with the + /// `ClockTimeExceeded` error. + function test_move_clockTimeExceeded_reverts() public { + // Warp ahead past the clock time for the first move (3 1/2 days) + vm.warp(block.timestamp + 3 days + 12 hours + 1); + vm.expectRevert(ClockTimeExceeded.selector); + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + } + + /// @notice Static unit test for the correctness of the chess clock incrementation. + function test_move_clockCorrectness_succeeds() public { + (,,,,,, Clock clock) = gameProxy.claimData(0); + assertEq(clock.raw(), LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))).raw()); + + Claim claim = _dummyClaim(); + + vm.warp(block.timestamp + 15); + gameProxy.attack{ value: MIN_BOND }(0, claim); + (,,,,,, clock) = gameProxy.claimData(1); + assertEq(clock.raw(), LibClock.wrap(Duration.wrap(15), Timestamp.wrap(uint64(block.timestamp))).raw()); + + vm.warp(block.timestamp + 10); + gameProxy.attack{ value: MIN_BOND }(1, claim); + (,,,,,, clock) = gameProxy.claimData(2); + assertEq(clock.raw(), LibClock.wrap(Duration.wrap(10), Timestamp.wrap(uint64(block.timestamp))).raw()); + + // We are at the split depth, so we need to set the status byte of the claim + // for the next move. + claim = _changeClaimStatus(claim, VMStatuses.PANIC); + + vm.warp(block.timestamp + 10); + gameProxy.attack{ value: MIN_BOND }(2, claim); + (,,,,,, clock) = gameProxy.claimData(3); + assertEq(clock.raw(), LibClock.wrap(Duration.wrap(25), Timestamp.wrap(uint64(block.timestamp))).raw()); + + vm.warp(block.timestamp + 10); + gameProxy.attack{ value: MIN_BOND }(3, claim); + (,,,,,, clock) = gameProxy.claimData(4); + assertEq(clock.raw(), LibClock.wrap(Duration.wrap(20), Timestamp.wrap(uint64(block.timestamp))).raw()); + } + + /// @dev Tests that an identical claim cannot be made twice. The duplicate claim attempt should + /// revert with the `ClaimAlreadyExists` error. + function test_move_duplicateClaim_reverts() public { + Claim claim = _dummyClaim(); + + // Make the first move. This should succeed. + gameProxy.attack{ value: MIN_BOND }(0, claim); + + // Attempt to make the same move again. + vm.expectRevert(ClaimAlreadyExists.selector); + gameProxy.attack{ value: MIN_BOND }(0, claim); + } + + /// @dev Static unit test asserting that identical claims at the same position can be made in different subgames. + function test_move_duplicateClaimsDifferentSubgames_succeeds() public { + Claim claimA = _dummyClaim(); + Claim claimB = _dummyClaim(); + + // Make the first moves. This should succeed. + gameProxy.attack{ value: MIN_BOND }(0, claimA); + gameProxy.attack{ value: MIN_BOND }(0, claimB); + + // Perform an attack at the same position with the same claim value in both subgames. + // These both should succeed. + gameProxy.attack{ value: MIN_BOND }(1, claimA); + gameProxy.attack{ value: MIN_BOND }(2, claimA); + } + + /// @dev Static unit test for the correctness of an opening attack. + function test_move_simpleAttack_succeeds() public { + // Warp ahead 5 seconds. + vm.warp(block.timestamp + 5); + + Claim counter = _dummyClaim(); + + // Perform the attack. + vm.expectEmit(true, true, true, false); + emit Move(0, counter, address(this)); + gameProxy.attack{ value: MIN_BOND }(0, counter); + + // Grab the claim data of the attack. + ( + uint32 parentIndex, + address counteredBy, + address claimant, + uint128 bond, + Claim claim, + Position position, + Clock clock + ) = gameProxy.claimData(1); + + // Assert correctness of the attack claim's data. + assertEq(parentIndex, 0); + assertEq(counteredBy, address(0)); + assertEq(claimant, address(this)); + assertEq(bond, MIN_BOND); + assertEq(claim.raw(), counter.raw()); + assertEq(position.raw(), Position.wrap(1).move(true).raw()); + assertEq(clock.raw(), LibClock.wrap(Duration.wrap(5), Timestamp.wrap(uint64(block.timestamp))).raw()); + + // Grab the claim data of the parent. + (parentIndex, counteredBy, claimant, bond, claim, position, clock) = gameProxy.claimData(0); + + // Assert correctness of the parent claim's data. + assertEq(parentIndex, type(uint32).max); + assertEq(counteredBy, address(0)); + assertEq(claimant, DEFAULT_SENDER); + assertEq(bond, 0); + assertEq(claim.raw(), ROOT_CLAIM.raw()); + assertEq(position.raw(), 1); + assertEq(clock.raw(), LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp - 5))).raw()); + } + + /// @dev Tests that making a claim at the execution trace bisection root level with an invalid status + /// byte reverts with the `UnexpectedRootClaim` error. + function test_move_incorrectStatusExecRoot_reverts() public { + for (uint256 i; i < 4; i++) { + gameProxy.attack{ value: MIN_BOND }(i, _dummyClaim()); + } + + vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, bytes32(0))); + gameProxy.attack{ value: MIN_BOND }(4, Claim.wrap(bytes32(0))); + } + + /// @dev Tests that making a claim at the execution trace bisection root level with a valid status + /// byte succeeds. + function test_move_correctStatusExecRoot_succeeds() public { + for (uint256 i; i < 4; i++) { + gameProxy.attack{ value: MIN_BOND }(i, _dummyClaim()); + } + gameProxy.attack{ value: MIN_BOND }(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC)); + } + + /// @dev Static unit test asserting that a move reverts when the bond is insufficient. + function test_move_insufficientBond_reverts() public { + vm.expectRevert(InsufficientBond.selector); + gameProxy.attack{ value: 0 }(0, _dummyClaim()); + } + + /// @dev Tests that a claim cannot be stepped against twice. + function test_step_duplicateStep_reverts() public { + // Give the test contract some ether + vm.deal(address(this), 1000 ether); + + // Make claims all the way down the tree. + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(1, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(2, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(3, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC)); + gameProxy.attack{ value: MIN_BOND }(5, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(6, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(7, _dummyClaim()); + gameProxy.addLocalData(LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER, 8, 0); + gameProxy.step(8, true, absolutePrestateData, hex""); + + vm.expectRevert(DuplicateStep.selector); + gameProxy.step(8, true, absolutePrestateData, hex""); + } + + /// @dev Static unit test for the correctness an uncontested root resolution. + function test_resolve_rootUncontested_succeeds() public { + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + gameProxy.resolveClaim(0); + assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); + } + + /// @dev Static unit test for the correctness an uncontested root resolution. + function test_resolve_rootUncontestedClockNotExpired_succeeds() public { + vm.warp(block.timestamp + 3 days + 12 hours); + vm.expectRevert(ClockNotExpired.selector); + gameProxy.resolveClaim(0); + } + + /// @dev Static unit test asserting that resolve reverts when the absolute root + /// subgame has not been resolved. + function test_resolve_rootUncontestedButUnresolved_reverts() public { + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + vm.expectRevert(OutOfOrderResolution.selector); + gameProxy.resolve(); + } + + /// @dev Static unit test asserting that resolve reverts when the game state is + /// not in progress. + function test_resolve_notInProgress_reverts() public { + uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS); + + // Replace the game status in storage. It exists in slot 0 at offset 16. + uint256 slot = uint256(vm.load(address(gameProxy), bytes32(0))); + uint256 offset = 16 << 3; + uint256 mask = 0xFF << offset; + // Replace the byte in the slot value with the challenger wins status. + slot = (slot & ~mask) | (chalWins << offset); + + vm.store(address(gameProxy), bytes32(uint256(0)), bytes32(slot)); + vm.expectRevert(GameNotInProgress.selector); + gameProxy.resolveClaim(0); + } + + /// @dev Static unit test for the correctness of resolving a single attack game state. + function test_resolve_rootContested_succeeds() public { + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + + gameProxy.resolveClaim(0); + assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); + } + + /// @dev Static unit test for the correctness of resolving a game with a contested challenge claim. + function test_resolve_challengeContested_succeeds() public { + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + gameProxy.defend{ value: MIN_BOND }(1, _dummyClaim()); + + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + + gameProxy.resolveClaim(1); + gameProxy.resolveClaim(0); + assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); + } + + /// @dev Static unit test for the correctness of resolving a game with multiplayer moves. + function test_resolve_teamDeathmatch_succeeds() public { + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + gameProxy.defend{ value: MIN_BOND }(1, _dummyClaim()); + gameProxy.defend{ value: MIN_BOND }(1, _dummyClaim()); + + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + + gameProxy.resolveClaim(1); + gameProxy.resolveClaim(0); + assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); + } + + /// @dev Static unit test for the correctness of resolving a game that reaches max game depth. + function test_resolve_stepReached_succeeds() public { + Claim claim = _dummyClaim(); + for (uint256 i; i < gameProxy.splitDepth(); i++) { + gameProxy.attack{ value: MIN_BOND }(i, claim); + } + + claim = _changeClaimStatus(claim, VMStatuses.PANIC); + for (uint256 i = gameProxy.claimDataLen() - 1; i < gameProxy.maxGameDepth(); i++) { + gameProxy.attack{ value: MIN_BOND }(i, claim); + } + + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + + // resolving claim at 8 isn't necessary + for (uint256 i = 8; i > 0; i--) { + gameProxy.resolveClaim(i - 1); + } + assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); + } + + /// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame multiple times + function test_resolve_claimAlreadyResolved_reverts() public { + vm.deal(address(this), 2 * MIN_BOND); + + Claim claim = _dummyClaim(); + gameProxy.attack{ value: MIN_BOND }(0, claim); + gameProxy.attack{ value: MIN_BOND }(1, claim); + + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + + assertEq(address(this).balance, 0); + gameProxy.resolveClaim(1); + + // Wait for the withdrawal delay. + vm.warp(block.timestamp + delayedWeth.delay() + 1 seconds); + + gameProxy.claimCredit(address(this)); + assertEq(address(this).balance, MIN_BOND); + + vm.expectRevert(ClaimAlreadyResolved.selector); + gameProxy.resolveClaim(1); + assertEq(address(this).balance, MIN_BOND); + } + + /// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame at max depth + function test_resolve_claimAtMaxDepthAlreadyResolved_reverts() public { + Claim claim = _dummyClaim(); + for (uint256 i; i < gameProxy.splitDepth(); i++) { + gameProxy.attack{ value: MIN_BOND }(i, claim); + } + + vm.deal(address(this), 10000 ether); + claim = _changeClaimStatus(claim, VMStatuses.PANIC); + for (uint256 i = gameProxy.claimDataLen() - 1; i < gameProxy.maxGameDepth(); i++) { + gameProxy.attack{ value: MIN_BOND }(i, claim); + } + + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + + // Resolve to claim bond + uint256 balanceBefore = address(this).balance; + gameProxy.resolveClaim(8); + + // Wait for the withdrawal delay. + vm.warp(block.timestamp + delayedWeth.delay() + 1 seconds); + + gameProxy.claimCredit(address(this)); + assertEq(address(this).balance, balanceBefore + MIN_BOND); + + vm.expectRevert(ClaimAlreadyResolved.selector); + gameProxy.resolveClaim(8); + } + + /// @dev Static unit test asserting that resolve reverts when attempting to resolve subgames out of order + function test_resolve_outOfOrderResolution_reverts() public { + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(1, _dummyClaim()); + + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + + vm.expectRevert(OutOfOrderResolution.selector); + gameProxy.resolveClaim(0); + } + + /// @dev Static unit test asserting that resolve pays out bonds on step, output bisection, and execution trace + /// moves. + function test_resolve_bondPayouts_succeeds() public { + // Give the test contract some ether + uint256 bal = 1000 ether; + vm.deal(address(this), bal); + + // Make claims all the way down the tree. + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(1, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(2, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(3, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC)); + gameProxy.attack{ value: MIN_BOND }(5, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(6, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(7, _dummyClaim()); + gameProxy.addLocalData(LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER, 8, 0); + gameProxy.step(8, true, absolutePrestateData, hex""); + + // Ensure that the step successfully countered the leaf claim. + (, address counteredBy,,,,,) = gameProxy.claimData(8); + assertEq(counteredBy, address(this)); + + // Ensure we bonded the correct amounts + uint256 bonded = (gameProxy.claimDataLen() - 1) * MIN_BOND; + assertEq(address(this).balance, bal - bonded); + assertEq(address(gameProxy).balance, 0); + assertEq(delayedWeth.balanceOf(address(gameProxy)), bonded); + + // Resolve all claims + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + for (uint256 i = gameProxy.claimDataLen(); i > 0; i--) { + (bool success,) = address(gameProxy).call(abi.encodeCall(gameProxy.resolveClaim, (i - 1))); + assertTrue(success); + } + gameProxy.resolve(); + + // Wait for the withdrawal delay. + vm.warp(block.timestamp + delayedWeth.delay() + 1 seconds); + + gameProxy.claimCredit(address(this)); + + // Ensure that bonds were paid out correctly. + assertEq(address(this).balance, bal); + assertEq(address(gameProxy).balance, 0); + assertEq(delayedWeth.balanceOf(address(gameProxy)), 0); + + // Ensure that the init bond for the game is 0, in case we change it in the test suite in the future. + assertEq(disputeGameFactory.initBonds(GAME_TYPE), 0); + } + + /// @dev Static unit test asserting that resolve pays out bonds on step, output bisection, and execution trace + /// moves with 2 actors and a dishonest root claim. + function test_resolve_bondPayoutsSeveralActors_succeeds() public { + // Give the test contract and bob some ether + uint256 bal = 1000 ether; + address bob = address(0xb0b); + vm.deal(address(this), bal); + vm.deal(bob, bal); + + // Make claims all the way down the tree, trading off between bob and the test contract. + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + + vm.prank(bob); + gameProxy.attack{ value: MIN_BOND }(1, _dummyClaim()); + + gameProxy.attack{ value: MIN_BOND }(2, _dummyClaim()); + + vm.prank(bob); + gameProxy.attack{ value: MIN_BOND }(3, _dummyClaim()); + + gameProxy.attack{ value: MIN_BOND }(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC)); + + vm.prank(bob); + gameProxy.attack{ value: MIN_BOND }(5, _dummyClaim()); + + gameProxy.attack{ value: MIN_BOND }(6, _dummyClaim()); + + vm.prank(bob); + gameProxy.attack{ value: MIN_BOND }(7, _dummyClaim()); + + gameProxy.addLocalData(LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER, 8, 0); + gameProxy.step(8, true, absolutePrestateData, hex""); + + // Ensure that the step successfully countered the leaf claim. + (, address counteredBy,,,,,) = gameProxy.claimData(8); + assertEq(counteredBy, address(this)); + + // Ensure we bonded the correct amounts + uint256 bonded = ((gameProxy.claimDataLen() - 1) / 2) * MIN_BOND; + assertEq(address(this).balance, bal - bonded); + assertEq(bob.balance, bal - bonded); + assertEq(address(gameProxy).balance, 0); + assertEq(delayedWeth.balanceOf(address(gameProxy)), bonded * 2); + + // Resolve all claims + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + for (uint256 i = gameProxy.claimDataLen(); i > 0; i--) { + (bool success,) = address(gameProxy).call(abi.encodeCall(gameProxy.resolveClaim, (i - 1))); + assertTrue(success); + } + gameProxy.resolve(); + + // Wait for the withdrawal delay. + vm.warp(block.timestamp + delayedWeth.delay() + 1 seconds); + + gameProxy.claimCredit(address(this)); + + // Bob's claim should revert since it's value is 0 + vm.expectRevert(NoCreditToClaim.selector); + gameProxy.claimCredit(bob); + + // Ensure that bonds were paid out correctly. + assertEq(address(this).balance, bal + bonded); + assertEq(bob.balance, bal - bonded); + assertEq(address(gameProxy).balance, 0); + assertEq(delayedWeth.balanceOf(address(gameProxy)), 0); + + // Ensure that the init bond for the game is 0, in case we change it in the test suite in the future. + assertEq(disputeGameFactory.initBonds(GAME_TYPE), 0); + } + + /// @dev Static unit test asserting that resolve pays out bonds on moves to the leftmost actor + /// in subgames containing successful counters. + function test_resolve_leftmostBondPayout_succeeds() public { + uint256 bal = 1000 ether; + address alice = address(0xa11ce); + address bob = address(0xb0b); + address charlie = address(0xc0c); + vm.deal(address(this), bal); + vm.deal(alice, bal); + vm.deal(bob, bal); + vm.deal(charlie, bal); + + // Make claims with bob, charlie and the test contract on defense, and alice as the challenger + // charlie is successfully countered by alice + // alice is successfully countered by both bob and the test contract + vm.prank(alice); + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + + vm.prank(bob); + gameProxy.defend{ value: MIN_BOND }(1, _dummyClaim()); + vm.prank(charlie); + gameProxy.attack{ value: MIN_BOND }(1, _dummyClaim()); + gameProxy.attack{ value: MIN_BOND }(1, _dummyClaim()); + + vm.prank(alice); + gameProxy.attack{ value: MIN_BOND }(3, _dummyClaim()); + + // Resolve all claims + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + for (uint256 i = gameProxy.claimDataLen(); i > 0; i--) { + (bool success,) = address(gameProxy).call(abi.encodeCall(gameProxy.resolveClaim, (i - 1))); + assertTrue(success); + } + gameProxy.resolve(); + + // Wait for the withdrawal delay. + vm.warp(block.timestamp + delayedWeth.delay() + 1 seconds); + + gameProxy.claimCredit(address(this)); + gameProxy.claimCredit(alice); + gameProxy.claimCredit(bob); + + // Charlie's claim should revert since it's value is 0 + vm.expectRevert(NoCreditToClaim.selector); + gameProxy.claimCredit(charlie); + + // Ensure that bonds were paid out correctly. + uint256 aliceLosses = MIN_BOND; + uint256 charlieLosses = MIN_BOND; + assertEq(address(this).balance, bal + aliceLosses, "incorrect this balance"); + assertEq(alice.balance, bal - aliceLosses + charlieLosses, "incorrect alice balance"); + assertEq(bob.balance, bal, "incorrect bob balance"); + assertEq(charlie.balance, bal - charlieLosses, "incorrect charlie balance"); + assertEq(address(gameProxy).balance, 0); + + // Ensure that the init bond for the game is 0, in case we change it in the test suite in the future. + assertEq(disputeGameFactory.initBonds(GAME_TYPE), 0); + } + + /// @dev Static unit test asserting that the anchor state updates when the game resolves in + /// favor of the defender and the anchor state is older than the game state. + function test_resolve_validNewerStateUpdatesAnchor_succeeds() public { + // Confirm that the anchor state is older than the game state. + (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assert(l2BlockNumber < gameProxy.l2BlockNumber()); + + // Resolve the game. + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + gameProxy.resolveClaim(0); + assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); + + // Confirm that the anchor state is now the same as the game state. + (root, l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assertEq(l2BlockNumber, gameProxy.l2BlockNumber()); + assertEq(root.raw(), gameProxy.rootClaim().raw()); + } + + /// @dev Static unit test asserting that the anchor state does not change when the game + /// resolves in favor of the defender but the game state is not newer than the anchor state. + function test_resolve_validOlderStateSameAnchor_succeeds() public { + // Mock the game block to be older than the game state. + vm.mockCall(address(gameProxy), abi.encodeWithSelector(gameProxy.l2BlockNumber.selector), abi.encode(0)); + + // Confirm that the anchor state is newer than the game state. + (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assert(l2BlockNumber >= gameProxy.l2BlockNumber()); + + // Resolve the game. + vm.mockCall(address(gameProxy), abi.encodeWithSelector(gameProxy.l2BlockNumber.selector), abi.encode(0)); + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + gameProxy.resolveClaim(0); + assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); + + // Confirm that the anchor state is the same as the initial anchor state. + (Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assertEq(updatedL2BlockNumber, l2BlockNumber); + assertEq(updatedRoot.raw(), root.raw()); + } + + /// @dev Static unit test asserting that the anchor state does not change when the game + /// resolves in favor of the challenger, even if the game state is newer than the anchor. + function test_resolve_invalidStateSameAnchor_succeeds() public { + // Confirm that the anchor state is older than the game state. + (Hash root, uint256 l2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assert(l2BlockNumber < gameProxy.l2BlockNumber()); + + // Challenge the claim and resolve it. + gameProxy.attack{ value: MIN_BOND }(0, _dummyClaim()); + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + gameProxy.resolveClaim(0); + assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); + + // Confirm that the anchor state is the same as the initial anchor state. + (Hash updatedRoot, uint256 updatedL2BlockNumber) = anchorStateRegistry.anchors(gameProxy.gameType()); + assertEq(updatedL2BlockNumber, l2BlockNumber); + assertEq(updatedRoot.raw(), root.raw()); + } + + /// @dev Static unit test asserting that credit may not be drained past allowance through reentrancy. + function test_claimCredit_claimAlreadyResolved_reverts() public { + ClaimCreditReenter reenter = new ClaimCreditReenter(gameProxy, vm); + vm.startPrank(address(reenter)); + + // Give the test contract some ether to bond. + vm.deal(address(reenter), MIN_BOND * 2); + // Give the game proxy 1 extra ether, unregistered. + vm.deal(address(gameProxy), 1 ether); + + // Perform a bonded move. + Claim claim = _dummyClaim(); + gameProxy.attack{ value: MIN_BOND }(0, claim); + gameProxy.attack{ value: MIN_BOND }(1, claim); + + // Warp past the finalization period + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + + // Ensure that we bonded all the test contract's ETH + assertEq(address(reenter).balance, 0); + // Ensure the game proxy has 1 ether in it. + assertEq(address(gameProxy).balance, 1 ether); + // Ensure the game has a balance of 2 * MIN_BOND in the delayedWeth contract. + assertEq(delayedWeth.balanceOf(address(gameProxy)), MIN_BOND * 2); + + // Resolve the claim at gindex 1 and claim the reenter contract's credit. + gameProxy.resolveClaim(1); + + // Ensure that the game registered the `reenter` contract's credit. + assertEq(gameProxy.credit(address(reenter)), MIN_BOND); + + // Wait for the withdrawal delay. + vm.warp(block.timestamp + delayedWeth.delay() + 1 seconds); + + // Initiate the reentrant credit claim. + reenter.claimCredit(address(reenter)); + + // The reenter contract should have performed 2 calls to `claimCredit`. + // Once all the credit is claimed, all subsequent calls will revert since there is 0 credit left to claim. + // The claimant must only have received the amount bonded for the gindex 1 subgame. + // The root claim bond and the unregistered ETH should still exist in the game proxy. + assertEq(reenter.numCalls(), 2); + assertEq(address(reenter).balance, MIN_BOND); + assertEq(address(gameProxy).balance, 1 ether); + assertEq(delayedWeth.balanceOf(address(gameProxy)), MIN_BOND); + + vm.stopPrank(); + } + + /// @dev Tests that adding local data with an out of bounds identifier reverts. + function testFuzz_addLocalData_oob_reverts(uint256 _ident) public { + // Get a claim below the split depth so that we can add local data for an execution trace subgame. + for (uint256 i; i < 4; i++) { + gameProxy.attack{ value: MIN_BOND }(i, _dummyClaim()); + } + gameProxy.attack{ value: MIN_BOND }(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC)); + + // [1, 5] are valid local data identifiers. + if (_ident <= 5) _ident = 0; + + vm.expectRevert(InvalidLocalIdent.selector); + gameProxy.addLocalData(_ident, 5, 0); + } + + /// @dev Tests that local data is loaded into the preimage oracle correctly in the subgame + /// that is disputing the transition from `GENESIS -> GENESIS + 1` + function test_addLocalDataGenesisTransition_static_succeeds() public { + IPreimageOracle oracle = IPreimageOracle(address(gameProxy.vm().oracle())); + + // Get a claim below the split depth so that we can add local data for an execution trace subgame. + for (uint256 i; i < 4; i++) { + gameProxy.attack{ value: MIN_BOND }(i, Claim.wrap(bytes32(i))); + } + gameProxy.attack{ value: MIN_BOND }(4, _changeClaimStatus(_dummyClaim(), VMStatuses.PANIC)); + + // Expected start/disputed claims + (Hash root,) = gameProxy.startingOutputRoot(); + bytes32 startingClaim = root.raw(); + bytes32 disputedClaim = bytes32(uint256(3)); + Position disputedPos = LibPosition.wrap(4, 0); + + // Expected local data + bytes32[5] memory data = [ + gameProxy.l1Head().raw(), + startingClaim, + disputedClaim, + bytes32(uint256(1) << 0xC0), + bytes32(gameProxy.l2ChainId() << 0xC0) + ]; + + for (uint256 i = 1; i <= 5; i++) { + uint256 expectedLen = i > 3 ? 8 : 32; + bytes32 key = _getKey(i, keccak256(abi.encode(disputedClaim, disputedPos))); + + gameProxy.addLocalData(i, 5, 0); + (bytes32 dat, uint256 datLen) = oracle.readPreimage(key, 0); + assertEq(dat >> 0xC0, bytes32(expectedLen)); + // Account for the length prefix if i > 3 (the data stored + // at identifiers i <= 3 are 32 bytes long, so the expected + // length is already correct. If i > 3, the data is only 8 + // bytes long, so the length prefix + the data is 16 bytes + // total.) + assertEq(datLen, expectedLen + (i > 3 ? 8 : 0)); + + gameProxy.addLocalData(i, 5, 8); + (dat, datLen) = oracle.readPreimage(key, 8); + assertEq(dat, data[i - 1]); + assertEq(datLen, expectedLen); + } + } + + /// @dev Tests that local data is loaded into the preimage oracle correctly. + function test_addLocalDataMiddle_static_succeeds() public { + IPreimageOracle oracle = IPreimageOracle(address(gameProxy.vm().oracle())); + + // Get a claim below the split depth so that we can add local data for an execution trace subgame. + for (uint256 i; i < 4; i++) { + gameProxy.attack{ value: MIN_BOND }(i, Claim.wrap(bytes32(i))); + } + gameProxy.defend{ value: MIN_BOND }(4, _changeClaimStatus(ROOT_CLAIM, VMStatuses.VALID)); + + // Expected start/disputed claims + bytes32 startingClaim = bytes32(uint256(3)); + Position startingPos = LibPosition.wrap(4, 0); + bytes32 disputedClaim = bytes32(uint256(2)); + Position disputedPos = LibPosition.wrap(3, 0); + + // Expected local data + bytes32[5] memory data = [ + gameProxy.l1Head().raw(), + startingClaim, + disputedClaim, + bytes32(uint256(2) << 0xC0), + bytes32(gameProxy.l2ChainId() << 0xC0) + ]; + + for (uint256 i = 1; i <= 5; i++) { + uint256 expectedLen = i > 3 ? 8 : 32; + bytes32 key = _getKey(i, keccak256(abi.encode(startingClaim, startingPos, disputedClaim, disputedPos))); + + gameProxy.addLocalData(i, 5, 0); + (bytes32 dat, uint256 datLen) = oracle.readPreimage(key, 0); + assertEq(dat >> 0xC0, bytes32(expectedLen)); + // Account for the length prefix if i > 3 (the data stored + // at identifiers i <= 3 are 32 bytes long, so the expected + // length is already correct. If i > 3, the data is only 8 + // bytes long, so the length prefix + the data is 16 bytes + // total.) + assertEq(datLen, expectedLen + (i > 3 ? 8 : 0)); + + gameProxy.addLocalData(i, 5, 8); + (dat, datLen) = oracle.readPreimage(key, 8); + assertEq(dat, data[i - 1]); + assertEq(datLen, expectedLen); + } + } + + /// @dev Helper to return a pseudo-random claim + function _dummyClaim() internal view returns (Claim) { + return Claim.wrap(keccak256(abi.encode(gasleft()))); + } + + /// @dev Helper to get the localized key for an identifier in the context of the game proxy. + function _getKey(uint256 _ident, bytes32 _localContext) internal view returns (bytes32) { + bytes32 h = keccak256(abi.encode(_ident | (1 << 248), address(gameProxy), _localContext)); + return bytes32((uint256(h) & ~uint256(0xFF << 248)) | (1 << 248)); + } +} + +contract FaultDispute_1v1_Actors_Test is FaultDisputeGame_Init { + /// @dev The honest actor + DisputeActor internal honest; + /// @dev The dishonest actor + DisputeActor internal dishonest; + + function setUp() public override { + // Setup the `FaultDisputeGame` + super.setUp(); + } + + /// @notice Fuzz test for a 1v1 output bisection dispute. + /// @dev The alphabet game has a constant status byte, and is not safe from someone being dishonest in + /// output bisection and then posting a correct execution trace bisection root claim. This test + /// does not cover this case (i.e. root claim of output bisection is dishonest, root claim of + /// execution trace bisection is made by the dishonest actor but is honest, honest actor cannot + /// attack it without risk of losing). + function testFuzz_outputBisection1v1honestRoot_succeeds(uint8 _divergeOutput, uint8 _divergeStep) public { + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + uint256 divergeAtOutput = bound(_divergeOutput, 0, 15); + uint256 divergeAtStep = bound(_divergeStep, 0, 7); + uint256 divergeStepOffset = (divergeAtOutput << 4) + divergeAtStep; + + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i >= divergeAtOutput ? 0xFF : i + 1; + } + bytes memory dishonestTrace = new bytes(256); + for (uint256 i; i < dishonestTrace.length; i++) { + dishonestTrace[i] = i >= divergeStepOffset ? bytes1(uint8(0xFF)) : bytes1(uint8(i)); + } + + // Run the actor test + _actorTest({ + _rootClaim: 16, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.DEFENDER_WINS + }); + } + + /// @notice Static unit test for a 1v1 output bisection dispute. + function test_static_1v1honestRootGenesisAbsolutePrestate_succeeds() public { + // The honest l2 outputs are from [1, 16] in this game. + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + // The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of bytes [0, 255]. + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + // The dishonest l2 outputs are from [2, 17] in this game. + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i + 2; + } + // The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of all set bits. + bytes memory dishonestTrace = new bytes(256); + for (uint256 i; i < dishonestTrace.length; i++) { + dishonestTrace[i] = bytes1(0xFF); + } + + // Run the actor test + _actorTest({ + _rootClaim: 16, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.DEFENDER_WINS + }); + } + + /// @notice Static unit test for a 1v1 output bisection dispute. + function test_static_1v1dishonestRootGenesisAbsolutePrestate_succeeds() public { + // The honest l2 outputs are from [1, 16] in this game. + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + // The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of bytes [0, 255]. + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + // The dishonest l2 outputs are from [2, 17] in this game. + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i + 2; + } + // The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of all set bits. + bytes memory dishonestTrace = new bytes(256); + for (uint256 i; i < dishonestTrace.length; i++) { + dishonestTrace[i] = bytes1(0xFF); + } + + // Run the actor test + _actorTest({ + _rootClaim: 17, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.CHALLENGER_WINS + }); + } + + /// @notice Static unit test for a 1v1 output bisection dispute. + function test_static_1v1honestRoot_succeeds() public { + // The honest l2 outputs are from [1, 16] in this game. + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + // The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of bytes [0, 255]. + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + // The dishonest l2 outputs are from [2, 17] in this game. + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i + 2; + } + // The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of all zeros. + bytes memory dishonestTrace = new bytes(256); + + // Run the actor test + _actorTest({ + _rootClaim: 16, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.DEFENDER_WINS + }); + } + + /// @notice Static unit test for a 1v1 output bisection dispute. + function test_static_1v1dishonestRoot_succeeds() public { + // The honest l2 outputs are from [1, 16] in this game. + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + // The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of bytes [0, 255]. + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + // The dishonest l2 outputs are from [2, 17] in this game. + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i + 2; + } + // The dishonest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of all zeros. + bytes memory dishonestTrace = new bytes(256); + + // Run the actor test + _actorTest({ + _rootClaim: 17, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.CHALLENGER_WINS + }); + } + + /// @notice Static unit test for a 1v1 output bisection dispute. + function test_static_1v1correctRootHalfWay_succeeds() public { + // The honest l2 outputs are from [1, 16] in this game. + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + // The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of bytes [0, 255]. + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + // The dishonest l2 outputs are half correct, half incorrect. + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1; + } + // The dishonest trace is half correct, half incorrect. + bytes memory dishonestTrace = new bytes(256); + for (uint256 i; i < dishonestTrace.length; i++) { + dishonestTrace[i] = i > (127 + 4) ? bytes1(0xFF) : bytes1(uint8(i)); + } + + // Run the actor test + _actorTest({ + _rootClaim: 16, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.DEFENDER_WINS + }); + } + + /// @notice Static unit test for a 1v1 output bisection dispute. + function test_static_1v1dishonestRootHalfWay_succeeds() public { + // The honest l2 outputs are from [1, 16] in this game. + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + // The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of bytes [0, 255]. + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + // The dishonest l2 outputs are half correct, half incorrect. + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1; + } + // The dishonest trace is half correct, half incorrect. + bytes memory dishonestTrace = new bytes(256); + for (uint256 i; i < dishonestTrace.length; i++) { + dishonestTrace[i] = i > (127 + 4) ? bytes1(0xFF) : bytes1(uint8(i)); + } + + // Run the actor test + _actorTest({ + _rootClaim: 0xFF, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.CHALLENGER_WINS + }); + } + + /// @notice Static unit test for a 1v1 output bisection dispute. + function test_static_1v1correctAbsolutePrestate_succeeds() public { + // The honest l2 outputs are from [1, 16] in this game. + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + // The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of bytes [0, 255]. + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + // The dishonest l2 outputs are half correct, half incorrect. + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1; + } + // The dishonest trace correct is half correct, half incorrect. + bytes memory dishonestTrace = new bytes(256); + for (uint256 i; i < dishonestTrace.length; i++) { + dishonestTrace[i] = i > 127 ? bytes1(0xFF) : bytes1(uint8(i)); + } + + // Run the actor test + _actorTest({ + _rootClaim: 16, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.DEFENDER_WINS + }); + } + + /// @notice Static unit test for a 1v1 output bisection dispute. + function test_static_1v1dishonestAbsolutePrestate_succeeds() public { + // The honest l2 outputs are from [1, 16] in this game. + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + // The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of bytes [0, 255]. + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + // The dishonest l2 outputs are half correct, half incorrect. + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1; + } + // The dishonest trace correct is half correct, half incorrect. + bytes memory dishonestTrace = new bytes(256); + for (uint256 i; i < dishonestTrace.length; i++) { + dishonestTrace[i] = i > 127 ? bytes1(0xFF) : bytes1(uint8(i)); + } + + // Run the actor test + _actorTest({ + _rootClaim: 0xFF, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.CHALLENGER_WINS + }); + } + + /// @notice Static unit test for a 1v1 output bisection dispute. + function test_static_1v1honestRootFinalInstruction_succeeds() public { + // The honest l2 outputs are from [1, 16] in this game. + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + // The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of bytes [0, 255]. + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + // The dishonest l2 outputs are half correct, half incorrect. + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1; + } + // The dishonest trace is half correct, and correct all the way up to the final instruction of the exec + // subgame. + bytes memory dishonestTrace = new bytes(256); + for (uint256 i; i < dishonestTrace.length; i++) { + dishonestTrace[i] = i > (127 + 7) ? bytes1(0xFF) : bytes1(uint8(i)); + } + + // Run the actor test + _actorTest({ + _rootClaim: 16, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.DEFENDER_WINS + }); + } + + /// @notice Static unit test for a 1v1 output bisection dispute. + function test_static_1v1dishonestRootFinalInstruction_succeeds() public { + // The honest l2 outputs are from [1, 16] in this game. + uint256[] memory honestL2Outputs = new uint256[](16); + for (uint256 i; i < honestL2Outputs.length; i++) { + honestL2Outputs[i] = i + 1; + } + // The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting + // of bytes [0, 255]. + bytes memory honestTrace = new bytes(256); + for (uint256 i; i < honestTrace.length; i++) { + honestTrace[i] = bytes1(uint8(i)); + } + + // The dishonest l2 outputs are half correct, half incorrect. + uint256[] memory dishonestL2Outputs = new uint256[](16); + for (uint256 i; i < dishonestL2Outputs.length; i++) { + dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1; + } + // The dishonest trace is half correct, and correct all the way up to the final instruction of the exec + // subgame. + bytes memory dishonestTrace = new bytes(256); + for (uint256 i; i < dishonestTrace.length; i++) { + dishonestTrace[i] = i > (127 + 7) ? bytes1(0xFF) : bytes1(uint8(i)); + } + + // Run the actor test + _actorTest({ + _rootClaim: 0xFF, + _absolutePrestateData: 0, + _honestTrace: honestTrace, + _honestL2Outputs: honestL2Outputs, + _dishonestTrace: dishonestTrace, + _dishonestL2Outputs: dishonestL2Outputs, + _expectedStatus: GameStatus.CHALLENGER_WINS + }); + } + + //////////////////////////////////////////////////////////////// + // HELPERS // + //////////////////////////////////////////////////////////////// + + /// @dev Helper to run a 1v1 actor test + function _actorTest( + uint256 _rootClaim, + uint256 _absolutePrestateData, + bytes memory _honestTrace, + uint256[] memory _honestL2Outputs, + bytes memory _dishonestTrace, + uint256[] memory _dishonestL2Outputs, + GameStatus _expectedStatus + ) + internal + { + // Setup the environment + bytes memory absolutePrestateData = + _setup({ _absolutePrestateData: _absolutePrestateData, _rootClaim: _rootClaim }); + + // Create actors + _createActors({ + _honestTrace: _honestTrace, + _honestPreStateData: absolutePrestateData, + _honestL2Outputs: _honestL2Outputs, + _dishonestTrace: _dishonestTrace, + _dishonestPreStateData: absolutePrestateData, + _dishonestL2Outputs: _dishonestL2Outputs + }); + + // Exhaust all moves from both actors + _exhaustMoves(); + + // Resolve the game and assert that the defender won + _warpAndResolve(); + assertEq(uint8(gameProxy.status()), uint8(_expectedStatus)); + } + + /// @dev Helper to setup the 1v1 test + function _setup( + uint256 _absolutePrestateData, + uint256 _rootClaim + ) + internal + returns (bytes memory absolutePrestateData_) + { + absolutePrestateData_ = abi.encode(_absolutePrestateData); + Claim absolutePrestateExec = + _changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData_)), VMStatuses.UNFINISHED); + Claim rootClaim = Claim.wrap(bytes32(uint256(_rootClaim))); + super.init({ rootClaim: rootClaim, absolutePrestate: absolutePrestateExec, l2BlockNumber: _rootClaim }); + } + + /// @dev Helper to create actors for the 1v1 dispute. + function _createActors( + bytes memory _honestTrace, + bytes memory _honestPreStateData, + uint256[] memory _honestL2Outputs, + bytes memory _dishonestTrace, + bytes memory _dishonestPreStateData, + uint256[] memory _dishonestL2Outputs + ) + internal + { + honest = new HonestDisputeActor({ + _gameProxy: gameProxy, + _l2Outputs: _honestL2Outputs, + _trace: _honestTrace, + _preStateData: _honestPreStateData + }); + dishonest = new HonestDisputeActor({ + _gameProxy: gameProxy, + _l2Outputs: _dishonestL2Outputs, + _trace: _dishonestTrace, + _preStateData: _dishonestPreStateData + }); + + vm.deal(address(honest), 100 ether); + vm.deal(address(dishonest), 100 ether); + vm.label(address(honest), "HonestActor"); + vm.label(address(dishonest), "DishonestActor"); + } + + /// @dev Helper to exhaust all moves from both actors. + function _exhaustMoves() internal { + while (true) { + // Allow the dishonest actor to make their moves, and then the honest actor. + (uint256 numMovesA,) = dishonest.move(); + (uint256 numMovesB, bool success) = honest.move(); + + require(success, "Honest actor's moves should always be successful"); + + // If both actors have run out of moves, we're done. + if (numMovesA == 0 && numMovesB == 0) break; + } + } + + /// @dev Helper to warp past the chess clock and resolve all claims within the dispute game. + function _warpAndResolve() internal { + // Warp past the chess clock + vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds); + + // Resolve all claims in reverse order. We allow `resolveClaim` calls to fail due to + // the check that prevents claims with no subgames attached from being passed to + // `resolveClaim`. There's also a check in `resolve` to ensure all children have been + // resolved before global resolution, which catches any unresolved subgames here. + for (uint256 i = gameProxy.claimDataLen(); i > 0; i--) { + (bool success,) = address(gameProxy).call(abi.encodeCall(gameProxy.resolveClaim, (i - 1))); + assertTrue(success); + } + gameProxy.resolve(); + } +} + +contract ClaimCreditReenter { + Vm internal immutable vm; + FaultDisputeGame internal immutable GAME; + uint256 public numCalls; + + constructor(FaultDisputeGame _gameProxy, Vm _vm) { + GAME = _gameProxy; + vm = _vm; + } + + function claimCredit(address _recipient) public { + numCalls += 1; + if (numCalls > 1) { + vm.expectRevert(NoCreditToClaim.selector); + } + GAME.claimCredit(_recipient); + } + + receive() external payable { + if (numCalls == 5) { + return; + } + claimCredit(address(this)); + } +} + +/// @dev Helper to change the VM status byte of a claim. +function _changeClaimStatus(Claim _claim, VMStatus _status) pure returns (Claim out_) { + assembly { + out_ := or(and(not(shl(248, 0xFF)), _claim), shl(248, _status)) + } +} diff --git a/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol b/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol new file mode 100644 index 000000000000..02191968f69c --- /dev/null +++ b/packages/contracts-bedrock/test/dispute/PermissionedDisputeGame.t.sol @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import { Test } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; +import { DisputeGameFactory_Init } from "test/dispute/DisputeGameFactory.t.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol"; +import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; +import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol"; + +import "src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeErrors.sol"; +import { Types } from "src/libraries/Types.sol"; +import { LibClock } from "src/dispute/lib/LibUDT.sol"; +import { LibPosition } from "src/dispute/lib/LibPosition.sol"; +import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; +import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; + +import { DisputeActor, HonestDisputeActor } from "test/actors/FaultDisputeActors.sol"; + +contract PermissionedDisputeGame_Init is DisputeGameFactory_Init { + /// @dev The type of the game being tested. + GameType internal constant GAME_TYPE = GameType.wrap(1); + /// @dev Mock proposer key + address internal constant PROPOSER = address(0xfacade9); + /// @dev Mock challenger key + address internal constant CHALLENGER = address(0xfacadec); + + /// @dev The implementation of the game. + PermissionedDisputeGame internal gameImpl; + /// @dev The `Clone` proxy of the game. + PermissionedDisputeGame internal gameProxy; + + /// @dev The extra data passed to the game for initialization. + bytes internal extraData; + + event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant); + + function init(Claim rootClaim, Claim absolutePrestate, uint256 l2BlockNumber) public { + // Set the time to a realistic date. + vm.warp(1690906994); + + // Set the extra data for the game creation + extraData = abi.encode(l2BlockNumber); + + AlphabetVM _vm = new AlphabetVM(absolutePrestate, new PreimageOracle(0, 0)); + + // Use a 7 day delayed WETH to simulate withdrawals. + DelayedWETH _weth = new DelayedWETH(7 days); + + // Deploy an implementation of the fault game + gameImpl = new PermissionedDisputeGame({ + _gameType: GAME_TYPE, + _absolutePrestate: absolutePrestate, + _maxGameDepth: 2 ** 3, + _splitDepth: 2 ** 2, + _gameDuration: Duration.wrap(7 days), + _vm: _vm, + _weth: _weth, + _anchorStateRegistry: anchorStateRegistry, + _l2ChainId: 10, + _proposer: PROPOSER, + _challenger: CHALLENGER + }); + // Register the game implementation with the factory. + disputeGameFactory.setImplementation(GAME_TYPE, gameImpl); + // Create a new game. + vm.prank(PROPOSER, PROPOSER); + gameProxy = + PermissionedDisputeGame(payable(address(disputeGameFactory.create(GAME_TYPE, rootClaim, extraData)))); + + // Check immutables + assertEq(gameProxy.gameType().raw(), GAME_TYPE.raw()); + assertEq(gameProxy.absolutePrestate().raw(), absolutePrestate.raw()); + assertEq(gameProxy.maxGameDepth(), 2 ** 3); + assertEq(gameProxy.splitDepth(), 2 ** 2); + assertEq(gameProxy.gameDuration().raw(), 7 days); + assertEq(address(gameProxy.vm()), address(_vm)); + + // Label the proxy + vm.label(address(gameProxy), "FaultDisputeGame_Clone"); + } + + fallback() external payable { } + + receive() external payable { } +} + +contract PermissionedDisputeGame_Test is PermissionedDisputeGame_Init { + /// @dev The root claim of the game. + Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32((uint256(1) << 248) | uint256(10))); + /// @dev Minimum bond value that covers all possible moves. + uint256 internal constant MIN_BOND = 50 ether; + + /// @dev The preimage of the absolute prestate claim + bytes internal absolutePrestateData; + /// @dev The absolute prestate of the trace. + Claim internal absolutePrestate; + + function setUp() public override { + absolutePrestateData = abi.encode(0); + absolutePrestate = _changeClaimStatus(Claim.wrap(keccak256(absolutePrestateData)), VMStatuses.UNFINISHED); + + super.setUp(); + super.init({ rootClaim: ROOT_CLAIM, absolutePrestate: absolutePrestate, l2BlockNumber: 0x10 }); + } + + /// @dev Tests that the proposer can create a permissioned dispute game. + function test_createGame_proposer_succeeds() public { + vm.prank(PROPOSER, PROPOSER); + disputeGameFactory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(0x420)); + } + + /// @dev Tests that the permissioned game cannot be created by any address other than the proposer. + function testFuzz_createGame_notProposer_reverts(address _p) public { + vm.assume(_p != PROPOSER); + + vm.prank(_p, _p); + vm.expectRevert(BadAuth.selector); + disputeGameFactory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(0x420)); + } + + /// @dev Tests that the challenger can participate in a permissioned dispute game. + function test_participateInGame_challenger_succeeds() public { + vm.startPrank(CHALLENGER, CHALLENGER); + vm.deal(CHALLENGER, MIN_BOND * 3); + gameProxy.attack{ value: MIN_BOND }(0, Claim.wrap(0)); + gameProxy.defend{ value: MIN_BOND }(1, Claim.wrap(0)); + gameProxy.move{ value: MIN_BOND }(2, Claim.wrap(0), true); + vm.stopPrank(); + } + + /// @dev Tests that the proposer can participate in a permissioned dispute game. + function test_participateInGame_proposer_succeeds() public { + vm.startPrank(PROPOSER, PROPOSER); + vm.deal(PROPOSER, MIN_BOND * 3); + gameProxy.attack{ value: MIN_BOND }(0, Claim.wrap(0)); + gameProxy.defend{ value: MIN_BOND }(1, Claim.wrap(0)); + gameProxy.move{ value: MIN_BOND }(2, Claim.wrap(0), true); + vm.stopPrank(); + } + + /// @dev Tests that addresses that are not the proposer or challenger cannot participate in a permissioned dispute + /// game. + function test_participateInGame_notAuthorized_reverts(address _p) public { + vm.assume(_p != PROPOSER && _p != CHALLENGER); + + vm.startPrank(_p, _p); + vm.expectRevert(BadAuth.selector); + gameProxy.attack(0, Claim.wrap(0)); + vm.expectRevert(BadAuth.selector); + gameProxy.defend(1, Claim.wrap(0)); + vm.expectRevert(BadAuth.selector); + gameProxy.move(2, Claim.wrap(0), true); + vm.stopPrank(); + } +} + +/// @dev Helper to change the VM status byte of a claim. +function _changeClaimStatus(Claim _claim, VMStatus _status) pure returns (Claim out_) { + assembly { + out_ := or(and(not(shl(248, 0xFF)), _claim), shl(248, _status)) + } +} diff --git a/packages/contracts-bedrock/test/LibClock.t.sol b/packages/contracts-bedrock/test/dispute/lib/LibClock.t.sol similarity index 93% rename from packages/contracts-bedrock/test/LibClock.t.sol rename to packages/contracts-bedrock/test/dispute/lib/LibClock.t.sol index 41b5ae184976..6d39c7df2125 100644 --- a/packages/contracts-bedrock/test/LibClock.t.sol +++ b/packages/contracts-bedrock/test/dispute/lib/LibClock.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.15; import { Test } from "forge-std/Test.sol"; -import { LibClock } from "../src/dispute/lib/LibClock.sol"; +import { LibClock } from "src/dispute/lib/LibUDT.sol"; import "src/libraries/DisputeTypes.sol"; /// @notice Tests for `LibClock` diff --git a/packages/contracts-bedrock/test/LibGameId.t.sol b/packages/contracts-bedrock/test/dispute/lib/LibGameId.t.sol similarity index 100% rename from packages/contracts-bedrock/test/LibGameId.t.sol rename to packages/contracts-bedrock/test/dispute/lib/LibGameId.t.sol diff --git a/packages/contracts-bedrock/test/LibPosition.t.sol b/packages/contracts-bedrock/test/dispute/lib/LibPosition.t.sol similarity index 93% rename from packages/contracts-bedrock/test/LibPosition.t.sol rename to packages/contracts-bedrock/test/dispute/lib/LibPosition.t.sol index a60f5e2bafca..0dda3330672f 100644 --- a/packages/contracts-bedrock/test/LibPosition.t.sol +++ b/packages/contracts-bedrock/test/dispute/lib/LibPosition.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.15; import { Test } from "forge-std/Test.sol"; -import { LibPosition } from "../src/dispute/lib/LibPosition.sol"; +import { LibPosition } from "src/dispute/lib/LibPosition.sol"; import "src/libraries/DisputeTypes.sol"; /// @notice Tests for `LibPosition` @@ -11,8 +11,10 @@ contract LibPosition_Test is Test { /// @dev At the lowest level of the tree, this allows for 2 ** 63 leaves. In reality, the max game depth /// will likely be much lower. uint8 internal constant MAX_DEPTH = 63; + /// @dev Arbitrary split depth around half way down the tree. + uint8 internal constant SPLIT_DEPTH = 30; - function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal view returns (uint64) { + function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal pure returns (uint64) { // Index at depth bound: [0, 2 ** _depth-1] if (_depth > 0) { return uint64(bound(_indexAtDepth, 0, 2 ** (_depth - 1))); @@ -91,6 +93,27 @@ contract LibPosition_Test is Test { assertEq(Position.unwrap(ancestor), Position.unwrap(loopAncestor)); } + /// @notice Tests that the `traceAncestorBounded` function correctly computes the position of the + /// highest ancestor (below `SPLIT_DEPTH`) that commits to the same trace index. + function testFuzz_traceAncestorBounded_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public { + _depth = uint8(bound(_depth, SPLIT_DEPTH + 1, MAX_DEPTH)); + _indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth); + + Position position = LibPosition.wrap(_depth, _indexAtDepth); + Position ancestor = position.traceAncestorBounded(SPLIT_DEPTH); + Position loopAncestor = position; + + // Stop at 1 below the split depth. + while ( + loopAncestor.parent().traceIndex(MAX_DEPTH) == position.traceIndex(MAX_DEPTH) + && loopAncestor.depth() != SPLIT_DEPTH + 1 + ) { + loopAncestor = loopAncestor.parent(); + } + + assertEq(Position.unwrap(ancestor), Position.unwrap(loopAncestor)); + } + /// @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative /// to a given position. function testFuzz_rightIndex_correctness_succeeds(uint64 _maxDepth, uint8 _depth, uint64 _indexAtDepth) public { diff --git a/packages/contracts-bedrock/test/governance/GovernanceToken.t.sol b/packages/contracts-bedrock/test/governance/GovernanceToken.t.sol new file mode 100644 index 000000000000..93f0585b3ee0 --- /dev/null +++ b/packages/contracts-bedrock/test/governance/GovernanceToken.t.sol @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; + +contract GovernanceToken_Test is CommonTest { + address owner; + address rando; + + /// @dev Sets up the test suite. + function setUp() public virtual override { + super.setUp(); + owner = governanceToken.owner(); + rando = makeAddr("rando"); + } + + /// @dev Tests that the constructor sets the correct initial state. + function test_constructor_succeeds() external { + assertEq(governanceToken.owner(), owner); + assertEq(governanceToken.name(), "Optimism"); + assertEq(governanceToken.symbol(), "OP"); + assertEq(governanceToken.decimals(), 18); + assertEq(governanceToken.totalSupply(), 0); + } + + /// @dev Tests that the owner can successfully call `mint`. + function test_mint_fromOwner_succeeds() external { + // Mint 100 tokens. + vm.prank(owner); + governanceToken.mint(owner, 100); + + // Balances have updated correctly. + assertEq(governanceToken.balanceOf(owner), 100); + assertEq(governanceToken.totalSupply(), 100); + } + + /// @dev Tests that `mint` reverts when called by a non-owner. + function test_mint_fromNotOwner_reverts() external { + // Mint 100 tokens as rando. + vm.prank(rando); + vm.expectRevert("Ownable: caller is not the owner"); + governanceToken.mint(owner, 100); + + // Balance does not update. + assertEq(governanceToken.balanceOf(owner), 0); + assertEq(governanceToken.totalSupply(), 0); + } + + /// @dev Tests that the owner can successfully call `burn`. + function test_burn_succeeds() external { + // Mint 100 tokens to rando. + vm.prank(owner); + governanceToken.mint(rando, 100); + + // Rando burns their tokens. + vm.prank(rando); + governanceToken.burn(50); + + // Balances have updated correctly. + assertEq(governanceToken.balanceOf(rando), 50); + assertEq(governanceToken.totalSupply(), 50); + } + + /// @dev Tests that the owner can successfully call `burnFrom`. + function test_burnFrom_succeeds() external { + // Mint 100 tokens to rando. + vm.prank(owner); + governanceToken.mint(rando, 100); + + // Rando approves owner to burn 50 tokens. + vm.prank(rando); + governanceToken.approve(owner, 50); + + // Owner burns 50 tokens from rando. + vm.prank(owner); + governanceToken.burnFrom(rando, 50); + + // Balances have updated correctly. + assertEq(governanceToken.balanceOf(rando), 50); + assertEq(governanceToken.totalSupply(), 50); + } + + /// @dev Tests that `transfer` correctly transfers tokens. + function test_transfer_succeeds() external { + // Mint 100 tokens to rando. + vm.prank(owner); + governanceToken.mint(rando, 100); + + // Rando transfers 50 tokens to owner. + vm.prank(rando); + governanceToken.transfer(owner, 50); + + // Balances have updated correctly. + assertEq(governanceToken.balanceOf(owner), 50); + assertEq(governanceToken.balanceOf(rando), 50); + assertEq(governanceToken.totalSupply(), 100); + } + + /// @dev Tests that `approve` correctly sets allowances. + function test_approve_succeeds() external { + // Mint 100 tokens to rando. + vm.prank(owner); + governanceToken.mint(rando, 100); + + // Rando approves owner to spend 50 tokens. + vm.prank(rando); + governanceToken.approve(owner, 50); + + // Allowances have updated. + assertEq(governanceToken.allowance(rando, owner), 50); + } + + /// @dev Tests that `transferFrom` correctly transfers tokens. + function test_transferFrom_succeeds() external { + // Mint 100 tokens to rando. + vm.prank(owner); + governanceToken.mint(rando, 100); + + // Rando approves owner to spend 50 tokens. + vm.prank(rando); + governanceToken.approve(owner, 50); + + // Owner transfers 50 tokens from rando to owner. + vm.prank(owner); + governanceToken.transferFrom(rando, owner, 50); + + // Balances have updated correctly. + assertEq(governanceToken.balanceOf(owner), 50); + assertEq(governanceToken.balanceOf(rando), 50); + assertEq(governanceToken.totalSupply(), 100); + } + + /// @dev Tests that `increaseAllowance` correctly increases allowances. + function test_increaseAllowance_succeeds() external { + // Mint 100 tokens to rando. + vm.prank(owner); + governanceToken.mint(rando, 100); + + // Rando approves owner to spend 50 tokens. + vm.prank(rando); + governanceToken.approve(owner, 50); + + // Rando increases allowance by 50 tokens. + vm.prank(rando); + governanceToken.increaseAllowance(owner, 50); + + // Allowances have updated. + assertEq(governanceToken.allowance(rando, owner), 100); + } + + /// @dev Tests that `decreaseAllowance` correctly decreases allowances. + function test_decreaseAllowance_succeeds() external { + // Mint 100 tokens to rando. + vm.prank(owner); + governanceToken.mint(rando, 100); + + // Rando approves owner to spend 100 tokens. + vm.prank(rando); + governanceToken.approve(owner, 100); + + // Rando decreases allowance by 50 tokens. + vm.prank(rando); + governanceToken.decreaseAllowance(owner, 50); + + // Allowances have updated. + assertEq(governanceToken.allowance(rando, owner), 50); + } +} diff --git a/packages/contracts-bedrock/test/MintManager.t.sol b/packages/contracts-bedrock/test/governance/MintManager.t.sol similarity index 98% rename from packages/contracts-bedrock/test/MintManager.t.sol rename to packages/contracts-bedrock/test/governance/MintManager.t.sol index 92fceec0ae1a..00cc791b98c2 100644 --- a/packages/contracts-bedrock/test/MintManager.t.sol +++ b/packages/contracts-bedrock/test/governance/MintManager.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Target contract dependencies import { GovernanceToken } from "src/governance/GovernanceToken.sol"; diff --git a/packages/contracts-bedrock/test/invariants/AddressAliasHelper.t.sol b/packages/contracts-bedrock/test/invariants/AddressAliasHelper.t.sol index fd5bcc8c7cad..d61be07f7c32 100644 --- a/packages/contracts-bedrock/test/invariants/AddressAliasHelper.t.sol +++ b/packages/contracts-bedrock/test/invariants/AddressAliasHelper.t.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +import { InvariantTest } from "test/invariants/InvariantTest.sol"; contract AddressAliasHelper_Converter { bool public failedRoundtrip; @@ -23,10 +24,11 @@ contract AddressAliasHelper_Converter { } } -contract AddressAliasHelper_AddressAliasing_Invariant is StdInvariant, Test { +contract AddressAliasHelper_AddressAliasing_Invariant is StdInvariant, InvariantTest { AddressAliasHelper_Converter internal actor; - function setUp() public { + function setUp() public override { + super.setUp(); // Create a converter actor. actor = new AddressAliasHelper_Converter(); diff --git a/packages/contracts-bedrock/test/invariants/Burn.Eth.t.sol b/packages/contracts-bedrock/test/invariants/Burn.Eth.t.sol index 0fdfcdbbb194..2948cf8dcfc5 100644 --- a/packages/contracts-bedrock/test/invariants/Burn.Eth.t.sol +++ b/packages/contracts-bedrock/test/invariants/Burn.Eth.t.sol @@ -7,6 +7,7 @@ import { Vm } from "forge-std/Vm.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; import { Burn } from "src/libraries/Burn.sol"; +import { InvariantTest } from "test/invariants/InvariantTest.sol"; contract Burn_EthBurner is StdUtils { Vm internal vm; @@ -41,10 +42,11 @@ contract Burn_EthBurner is StdUtils { } } -contract Burn_BurnEth_Invariant is StdInvariant, Test { +contract Burn_BurnEth_Invariant is StdInvariant, InvariantTest { Burn_EthBurner internal actor; - function setUp() public { + function setUp() public override { + super.setUp(); // Create a Eth burner actor. actor = new Burn_EthBurner(vm); diff --git a/packages/contracts-bedrock/test/invariants/Burn.Gas.t.sol b/packages/contracts-bedrock/test/invariants/Burn.Gas.t.sol index 4e9145a08d77..6ba4fa6fe345 100644 --- a/packages/contracts-bedrock/test/invariants/Burn.Gas.t.sol +++ b/packages/contracts-bedrock/test/invariants/Burn.Gas.t.sol @@ -7,6 +7,7 @@ import { Vm } from "forge-std/Vm.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; import { Burn } from "src/libraries/Burn.sol"; +import { InvariantTest } from "test/invariants/InvariantTest.sol"; contract Burn_GasBurner is StdUtils { Vm internal vm; @@ -42,10 +43,11 @@ contract Burn_GasBurner is StdUtils { } } -contract Burn_BurnGas_Invariant is StdInvariant, Test { +contract Burn_BurnGas_Invariant is StdInvariant, InvariantTest { Burn_GasBurner internal actor; - function setUp() public { + function setUp() public override { + super.setUp(); // Create a gas burner actor. actor = new Burn_GasBurner(vm); diff --git a/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol index 6eef617f5095..5d5c19cea756 100644 --- a/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol @@ -5,12 +5,12 @@ import { StdUtils } from "forge-std/StdUtils.sol"; import { Vm } from "forge-std/Vm.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { Messenger_Initializer } from "test/CommonTest.t.sol"; -import { Types } from "src/libraries/Types.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Encoding } from "src/libraries/Encoding.sol"; import { Hashing } from "src/libraries/Hashing.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; contract RelayActor is StdUtils { // Storage slot of the l2Sender @@ -88,7 +88,7 @@ contract RelayActor is StdUtils { } } -contract XDM_MinGasLimits is Messenger_Initializer { +contract XDM_MinGasLimits is Bridge_Initializer { RelayActor actor; function init(bool doFail) public virtual { @@ -96,10 +96,10 @@ contract XDM_MinGasLimits is Messenger_Initializer { super.setUp(); // Deploy a relay actor - actor = new RelayActor(op, L1Messenger, vm, doFail); + actor = new RelayActor(optimismPortal, l1CrossDomainMessenger, vm, doFail); // Give the portal some ether to send to `relayMessage` - vm.deal(address(op), type(uint128).max); + vm.deal(address(optimismPortal), type(uint128).max); // Target the `RelayActor` contract targetContract(address(actor)); @@ -107,6 +107,13 @@ contract XDM_MinGasLimits is Messenger_Initializer { // Don't allow the estimation address to be the sender excludeSender(Constants.ESTIMATION_ADDRESS); + // Don't allow the predeploys to be the senders + uint160 prefix = uint160(0x420) << 148; + for (uint256 i = 0; i < 2048; i++) { + address addr = address(prefix | uint160(i)); + excludeContract(addr); + } + // Target the actor's `relay` function bytes4[] memory selectors = new bytes4[](1); selectors[0] = actor.relay.selector; @@ -138,9 +145,9 @@ contract XDM_MinGasLimits_Succeeds is XDM_MinGasLimits { for (uint256 i = 0; i < length; ++i) { bytes32 hash = actor.hashes(i); // The message hash is set in the successfulMessages mapping - assertTrue(L1Messenger.successfulMessages(hash)); + assertTrue(l1CrossDomainMessenger.successfulMessages(hash)); // The message hash is not set in the failedMessages mapping - assertFalse(L1Messenger.failedMessages(hash)); + assertFalse(l1CrossDomainMessenger.failedMessages(hash)); } assertFalse(actor.reverted()); } @@ -171,9 +178,9 @@ contract XDM_MinGasLimits_Reverts is XDM_MinGasLimits { for (uint256 i = 0; i < length; ++i) { bytes32 hash = actor.hashes(i); // The message hash is not set in the successfulMessages mapping - assertFalse(L1Messenger.successfulMessages(hash)); + assertFalse(l1CrossDomainMessenger.successfulMessages(hash)); // The message hash is set in the failedMessages mapping - assertTrue(L1Messenger.failedMessages(hash)); + assertTrue(l1CrossDomainMessenger.failedMessages(hash)); } assertFalse(actor.reverted()); } diff --git a/packages/contracts-bedrock/test/invariants/Encoding.t.sol b/packages/contracts-bedrock/test/invariants/Encoding.t.sol index 566c82903e01..94289876975f 100644 --- a/packages/contracts-bedrock/test/invariants/Encoding.t.sol +++ b/packages/contracts-bedrock/test/invariants/Encoding.t.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; import { Encoding } from "src/libraries/Encoding.sol"; +import { InvariantTest } from "test/invariants/InvariantTest.sol"; contract Encoding_Converter { bool public failedRoundtripAToB; @@ -48,10 +49,11 @@ contract Encoding_Converter { } } -contract Encoding_Invariant is StdInvariant, Test { +contract Encoding_Invariant is StdInvariant, InvariantTest { Encoding_Converter internal actor; - function setUp() public { + function setUp() public override { + super.setUp(); // Create a converter actor. actor = new Encoding_Converter(); diff --git a/packages/contracts-bedrock/test/invariants/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/invariants/FaultDisputeGame.t.sol new file mode 100644 index 000000000000..88f550e08a26 --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/FaultDisputeGame.t.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Vm } from "forge-std/Vm.sol"; +import { StdUtils } from "forge-std/StdUtils.sol"; +import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import { FaultDisputeGame_Init } from "test/dispute/FaultDisputeGame.t.sol"; + +import "src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeErrors.sol"; + +contract FaultDisputeGame_Solvency_Invariant is FaultDisputeGame_Init { + Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32(uint256(10))); + Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32((uint256(3) << 248) | uint256(0))); + + RandomClaimActor internal actor; + uint256 internal defaultSenderBalance; + + function setUp() public override { + super.setUp(); + super.init({ rootClaim: ROOT_CLAIM, absolutePrestate: ABSOLUTE_PRESTATE, l2BlockNumber: 0x10 }); + + actor = new RandomClaimActor(gameProxy, vm); + + targetContract(address(actor)); + vm.startPrank(address(actor)); + } + + /// @custom:invariant FaultDisputeGame always returns all ETH on total resolution + /// + /// The FaultDisputeGame contract should always return all ETH in the contract to the correct recipients upon + /// resolution of all outstanding claims. There may never be any ETH left in the contract after a full resolution. + function invariant_faultDisputeGame_solvency() public { + vm.warp(block.timestamp + 7 days + 1 seconds); + + (,,, uint256 rootBond,,,) = gameProxy.claimData(0); + + for (uint256 i = gameProxy.claimDataLen(); i > 0; i--) { + (bool success,) = address(gameProxy).call(abi.encodeCall(gameProxy.resolveClaim, (i - 1))); + assertTrue(success); + } + gameProxy.resolve(); + + // Wait for the withdrawal delay. + vm.warp(block.timestamp + 7 days + 1 seconds); + + if (gameProxy.credit(address(this)) == 0) { + vm.expectRevert(NoCreditToClaim.selector); + gameProxy.claimCredit(address(this)); + } else { + gameProxy.claimCredit(address(this)); + } + + if (gameProxy.credit(address(actor)) == 0) { + vm.expectRevert(NoCreditToClaim.selector); + gameProxy.claimCredit(address(actor)); + } else { + gameProxy.claimCredit(address(actor)); + } + + if (gameProxy.status() == GameStatus.DEFENDER_WINS) { + assertEq(address(this).balance, type(uint96).max); + assertEq(address(actor).balance, actor.totalBonded() - rootBond); + } else if (gameProxy.status() == GameStatus.CHALLENGER_WINS) { + assertEq(DEFAULT_SENDER.balance, type(uint96).max - rootBond); + assertEq(address(actor).balance, actor.totalBonded() + rootBond); + } else { + revert("unreachable"); + } + + assertEq(address(gameProxy).balance, 0); + } +} + +contract RandomClaimActor is StdUtils { + FaultDisputeGame internal immutable GAME; + Vm internal immutable VM; + + uint256 public totalBonded; + + constructor(FaultDisputeGame _gameProxy, Vm _vm) { + GAME = _gameProxy; + VM = _vm; + } + + function move(bool _isAttack, uint256 _parentIndex, Claim _claim, uint64 _bondAmount) public { + _parentIndex = bound(_parentIndex, 0, GAME.claimDataLen()); + VM.deal(address(this), _bondAmount); + + totalBonded += _bondAmount; + + GAME.move{ value: _bondAmount }(_parentIndex, _claim, _isAttack); + } + + fallback() external payable { } + + receive() external payable { } +} diff --git a/packages/contracts-bedrock/test/invariants/Hashing.t.sol b/packages/contracts-bedrock/test/invariants/Hashing.t.sol index c972148f12b0..f60013b1cfab 100644 --- a/packages/contracts-bedrock/test/invariants/Hashing.t.sol +++ b/packages/contracts-bedrock/test/invariants/Hashing.t.sol @@ -5,6 +5,7 @@ import { Test } from "forge-std/Test.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; import { Encoding } from "src/libraries/Encoding.sol"; import { Hashing } from "src/libraries/Hashing.sol"; +import { InvariantTest } from "test/invariants/InvariantTest.sol"; contract Hash_CrossDomainHasher { bool public failedCrossDomainHashHighVersion; @@ -93,10 +94,11 @@ contract Hash_CrossDomainHasher { } } -contract Hashing_Invariant is StdInvariant, Test { +contract Hashing_Invariant is StdInvariant, InvariantTest { Hash_CrossDomainHasher internal actor; - function setUp() public { + function setUp() public override { + super.setUp(); // Create a hasher actor. actor = new Hash_CrossDomainHasher(); diff --git a/packages/contracts-bedrock/test/invariants/InvariantTest.sol b/packages/contracts-bedrock/test/invariants/InvariantTest.sol new file mode 100644 index 000000000000..a188bcdf27a0 --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/InvariantTest.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { FFIInterface } from "test/setup/FFIInterface.sol"; +import { Deploy } from "scripts/Deploy.s.sol"; +import { Test } from "forge-std/Test.sol"; + +/// @title InvariantTest +/// @dev An extension to `Test` that sets up excluded contracts for invariant testing. +contract InvariantTest is Test { + FFIInterface constant ffi = FFIInterface(address(uint160(uint256(keccak256(abi.encode("optimism.ffi")))))); + Deploy internal constant deploy = Deploy(address(uint160(uint256(keccak256(abi.encode("optimism.deploy")))))); + + function setUp() public virtual { + excludeContract(address(ffi)); + excludeContract(address(deploy)); + } +} diff --git a/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol index 79d637fca9d6..c688ef419617 100644 --- a/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { Vm } from "forge-std/Vm.sol"; @@ -29,14 +29,14 @@ contract L2OutputOracle_Proposer { } } -contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_Initializer { +contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is CommonTest { L2OutputOracle_Proposer internal actor; function setUp() public override { super.setUp(); // Create a proposer actor. - actor = new L2OutputOracle_Proposer(oracle, vm); + actor = new L2OutputOracle_Proposer(l2OutputOracle, vm); // Set the target contract to the proposer actor. targetContract(address(actor)); @@ -57,6 +57,6 @@ contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_In /// correspond to a block number that is less than the current output. function invariant_monotonicBlockNumIncrease() external { // Assert that the block number of proposals must monotonically increase. - assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber()); + assertTrue(l2OutputOracle.nextBlockNumber() >= l2OutputOracle.latestBlockNumber()); } } diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol index af38e6536bb8..81df17cc8a63 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol @@ -6,13 +6,11 @@ import { Vm } from "forge-std/Vm.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Constants } from "src/libraries/Constants.sol"; -import { Portal_Initializer } from "test/CommonTest.t.sol"; -import { EIP1967Helper } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Types } from "src/libraries/Types.sol"; contract OptimismPortal_Depositor is StdUtils, ResourceMetering { @@ -74,7 +72,7 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering { } } -contract OptimismPortal_Invariant_Harness is Portal_Initializer { +contract OptimismPortal_Invariant_Harness is CommonTest { // Reusable default values for a test withdrawal Types.WithdrawalTransaction _defaultTx; @@ -109,28 +107,31 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer { messagePasserStorageRoot: _storageRoot, latestBlockhash: bytes32(uint256(0)) }); - _proposedBlockNumber = oracle.nextBlockNumber(); - _proposedOutputIndex = oracle.nextOutputIndex(); + _proposedBlockNumber = l2OutputOracle.nextBlockNumber(); + _proposedOutputIndex = l2OutputOracle.nextOutputIndex(); // Configure the oracle to return the output root we've prepared. - vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1); - vm.prank(oracle.PROPOSER()); - oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); + vm.warp(l2OutputOracle.computeL2Timestamp(_proposedBlockNumber) + 1); + vm.prank(l2OutputOracle.PROPOSER()); + l2OutputOracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); // Warp beyond the finalization period for the block we've proposed. - vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp( + l2OutputOracle.getL2Output(_proposedOutputIndex).timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + + 1 + ); // Fund the portal so that we can withdraw ETH. - vm.deal(address(op), 0xFFFFFFFF); + vm.deal(address(optimismPortal), 0xFFFFFFFF); } } -contract OptimismPortal_Deposit_Invariant is Portal_Initializer { +contract OptimismPortal_Deposit_Invariant is CommonTest { OptimismPortal_Depositor internal actor; function setUp() public override { super.setUp(); // Create a deposit actor. - actor = new OptimismPortal_Depositor(vm, op); + actor = new OptimismPortal_Depositor(vm, optimismPortal); targetContract(address(actor)); @@ -155,12 +156,12 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness { super.setUp(); // Prove the withdrawal transaction - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Set the target contract to the portal proxy - targetContract(address(op)); + targetContract(address(optimismPortal)); // Exclude the proxy admin from the senders so that the proxy cannot be upgraded - excludeSender(EIP1967Helper.getAdmin(address(op))); + excludeSender(EIP1967Helper.getAdmin(address(optimismPortal))); } /// @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization @@ -170,7 +171,7 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness { /// until after the finalization period has elapsed. function invariant_cannotFinalizeBeforePeriodHasPassed() external { vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); } } @@ -179,18 +180,18 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness super.setUp(); // Prove the withdrawal transaction - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Warp past the finalization period. - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); // Finalize the withdrawal transaction. - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); // Set the target contract to the portal proxy - targetContract(address(op)); + targetContract(address(optimismPortal)); // Exclude the proxy admin from the senders so that the proxy cannot be upgraded - excludeSender(EIP1967Helper.getAdmin(address(op))); + excludeSender(EIP1967Helper.getAdmin(address(optimismPortal))); } /// @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal @@ -200,7 +201,7 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness /// allows a withdrawal to be finalized twice. function invariant_cannotFinalizeTwice() external { vm.expectRevert("OptimismPortal: withdrawal has already been finalized"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); } } @@ -209,15 +210,15 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant super.setUp(); // Prove the withdrawal transaction - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Warp past the finalization period. - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); // Set the target contract to the portal proxy - targetContract(address(op)); + targetContract(address(optimismPortal)); // Exclude the proxy admin from the senders so that the proxy cannot be upgraded - excludeSender(EIP1967Helper.getAdmin(address(op))); + excludeSender(EIP1967Helper.getAdmin(address(optimismPortal))); } /// @custom:invariant A withdrawal should **always** be able to be finalized @@ -230,7 +231,7 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant function invariant_canAlwaysFinalize() external { uint256 bobBalanceBefore = address(bob).balance; - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value); } diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol new file mode 100644 index 000000000000..5d32ba3a5826 --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { StdUtils } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; + +import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { Constants } from "src/libraries/Constants.sol"; + +import { CommonTest } from "test/setup/CommonTest.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +import { Types } from "src/libraries/Types.sol"; + +import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; +import "src/libraries/DisputeTypes.sol"; + +contract OptimismPortal2_Depositor is StdUtils, ResourceMetering { + Vm internal vm; + OptimismPortal2 internal portal; + bool public failedToComplete; + + constructor(Vm _vm, OptimismPortal2 _portal) { + vm = _vm; + portal = _portal; + initialize(); + } + + function initialize() internal initializer { + __ResourceMetering_init(); + } + + function resourceConfig() public pure returns (ResourceMetering.ResourceConfig memory) { + return _resourceConfig(); + } + + function _resourceConfig() internal pure override returns (ResourceMetering.ResourceConfig memory) { + ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); + return rcfg; + } + + // A test intended to identify any unexpected halting conditions + function depositTransactionCompletes( + address _to, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + public + payable + { + vm.assume((!_isCreation || _to == address(0)) && _data.length <= 120_000); + + uint256 preDepositvalue = bound(_value, 0, type(uint128).max); + // Give the depositor some ether + vm.deal(address(this), preDepositvalue); + // cache the contract's eth balance + uint256 preDepositBalance = address(this).balance; + uint256 value = bound(preDepositvalue, 0, preDepositBalance); + + (, uint64 cachedPrevBoughtGas,) = ResourceMetering(address(portal)).params(); + ResourceMetering.ResourceConfig memory rcfg = resourceConfig(); + uint256 maxResourceLimit = uint64(rcfg.maxResourceLimit); + uint64 gasLimit = uint64( + bound(_gasLimit, portal.minimumGasLimit(uint64(_data.length)), maxResourceLimit - cachedPrevBoughtGas) + ); + + try portal.depositTransaction{ value: value }(_to, value, gasLimit, _isCreation, _data) { + // Do nothing; Call succeeded + } catch { + failedToComplete = true; + } + } +} + +contract OptimismPortal2_Invariant_Harness is CommonTest { + // Reusable default values for a test withdrawal + Types.WithdrawalTransaction _defaultTx; + + uint256 _proposedGameIndex; + uint256 _proposedBlockNumber; + bytes32 _stateRoot; + bytes32 _storageRoot; + bytes32 _outputRoot; + bytes32 _withdrawalHash; + bytes[] _withdrawalProof; + Types.OutputRootProof internal _outputRootProof; + + function setUp() public virtual override { + super.enableFaultProofs(); + super.setUp(); + + _defaultTx = Types.WithdrawalTransaction({ + nonce: 0, + sender: alice, + target: bob, + value: 100, + gasLimit: 100_000, + data: hex"" + }); + // Get withdrawal proof data we can use for testing. + (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = + ffi.getProveWithdrawalTransactionInputs(_defaultTx); + + // Setup a dummy output root proof for reuse. + _outputRootProof = Types.OutputRootProof({ + version: bytes32(uint256(0)), + stateRoot: _stateRoot, + messagePasserStorageRoot: _storageRoot, + latestBlockhash: bytes32(uint256(0)) + }); + + // Create a dispute game with the output root we've proposed. + _proposedBlockNumber = 0xFF; + FaultDisputeGame game = FaultDisputeGame( + payable( + address( + disputeGameFactory.create( + optimismPortal2.respectedGameType(), Claim.wrap(_outputRoot), abi.encode(_proposedBlockNumber) + ) + ) + ) + ); + _proposedGameIndex = disputeGameFactory.gameCount() - 1; + + // Warp beyond the finalization period for the dispute game and resolve it. + vm.warp(block.timestamp + game.gameDuration().raw() + 1 seconds); + game.resolveClaim(0); + game.resolve(); + + // Fund the portal so that we can withdraw ETH. + vm.deal(address(optimismPortal2), 0xFFFFFFFF); + } +} + +contract OptimismPortal2_Deposit_Invariant is CommonTest { + OptimismPortal2_Depositor internal actor; + + function setUp() public override { + super.setUp(); + // Create a deposit actor. + actor = new OptimismPortal2_Depositor(vm, optimismPortal2); + + targetContract(address(actor)); + + bytes4[] memory selectors = new bytes4[](1); + selectors[0] = actor.depositTransactionCompletes.selector; + FuzzSelector memory selector = FuzzSelector({ addr: address(actor), selectors: selectors }); + targetSelector(selector); + } + + /// @custom:invariant Deposits of any value should always succeed unless + /// `_to` = `address(0)` or `_isCreation` = `true`. + /// + /// All deposits, barring creation transactions and transactions + /// sent to `address(0)`, should always succeed. + function invariant_deposit_completes() external { + assertEq(actor.failedToComplete(), false); + } +} + +contract OptimismPortal2_CannotTimeTravel is OptimismPortal2_Invariant_Harness { + function setUp() public override { + super.setUp(); + + // Prove the withdrawal transaction + optimismPortal2.proveWithdrawalTransaction(_defaultTx, _proposedGameIndex, _outputRootProof, _withdrawalProof); + + // Set the target contract to the portal proxy + targetContract(address(optimismPortal2)); + // Exclude the proxy admin from the senders so that the proxy cannot be upgraded + excludeSender(EIP1967Helper.getAdmin(address(optimismPortal2))); + } + + /// @custom:invariant `finalizeWithdrawalTransaction` should revert if the proof maturity period has not elapsed. + /// + /// A withdrawal that has been proven should not be able to be finalized + /// until after the proof maturity period has elapsed. + function invariant_cannotFinalizeBeforePeriodHasPassed() external { + vm.expectRevert("OptimismPortal: proven withdrawal has not matured yet"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + } +} + +contract OptimismPortal2_CannotFinalizeTwice is OptimismPortal2_Invariant_Harness { + function setUp() public override { + super.setUp(); + + // Prove the withdrawal transaction + optimismPortal2.proveWithdrawalTransaction(_defaultTx, _proposedGameIndex, _outputRootProof, _withdrawalProof); + + // Warp past the proof maturity period. + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + + // Finalize the withdrawal transaction. + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + // Set the target contract to the portal proxy + targetContract(address(optimismPortal2)); + // Exclude the proxy admin from the senders so that the proxy cannot be upgraded + excludeSender(EIP1967Helper.getAdmin(address(optimismPortal2))); + } + + /// @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. + /// + /// Ensures that there is no chain of calls that can be made that allows a withdrawal to be + /// finalized twice. + function invariant_cannotFinalizeTwice() external { + vm.expectRevert("OptimismPortal: withdrawal has already been finalized"); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + } +} + +contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal2_Invariant_Harness { + function setUp() public override { + super.setUp(); + + // Prove the withdrawal transaction + optimismPortal2.proveWithdrawalTransaction(_defaultTx, _proposedGameIndex, _outputRootProof, _withdrawalProof); + + // Warp past the proof maturity period. + vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); + + // Set the target contract to the portal proxy + targetContract(address(optimismPortal2)); + // Exclude the proxy admin from the senders so that the proxy cannot be upgraded + excludeSender(EIP1967Helper.getAdmin(address(optimismPortal2))); + } + + /// @custom:invariant A withdrawal should **always** be able to be finalized `PROOF_MATURITY_DELAY_SECONDS` after + /// it was successfully proven, if the game has resolved and passed the air-gap. + /// + /// This invariant asserts that there is no chain of calls that can be made that will prevent a + /// withdrawal from being finalized exactly `PROOF_MATURITY_DELAY_SECONDS` after it was + /// successfully proven and the game has resolved and passed the air-gap. + function invariant_canAlwaysFinalize() external { + uint256 bobBalanceBefore = address(bob).balance; + + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + + assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value); + } +} diff --git a/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol b/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol index 866861331219..091bc54adae2 100644 --- a/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol +++ b/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol @@ -8,8 +8,8 @@ import { StdInvariant } from "forge-std/StdInvariant.sol"; import { Arithmetic } from "src/libraries/Arithmetic.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { Proxy } from "src/universal/Proxy.sol"; import { Constants } from "src/libraries/Constants.sol"; +import { InvariantTest } from "test/invariants/InvariantTest.sol"; contract ResourceMetering_User is StdUtils, ResourceMetering { bool public failedMaxGasPerBlock; @@ -137,10 +137,11 @@ contract ResourceMetering_User is StdUtils, ResourceMetering { function _burnInternal(uint64 _gasToBurn) private metered(_gasToBurn) { } } -contract ResourceMetering_Invariant is StdInvariant, Test { +contract ResourceMetering_Invariant is StdInvariant, InvariantTest { ResourceMetering_User internal actor; - function setUp() public { + function setUp() public override { + super.setUp(); // Create a actor. actor = new ResourceMetering_User(); diff --git a/packages/contracts-bedrock/test/invariants/SafeCall.t.sol b/packages/contracts-bedrock/test/invariants/SafeCall.t.sol index 66fbc0be115b..849154aa2d65 100644 --- a/packages/contracts-bedrock/test/invariants/SafeCall.t.sol +++ b/packages/contracts-bedrock/test/invariants/SafeCall.t.sol @@ -5,11 +5,13 @@ import { Test } from "forge-std/Test.sol"; import { StdUtils } from "forge-std/StdUtils.sol"; import { Vm } from "forge-std/Vm.sol"; import { SafeCall } from "src/libraries/SafeCall.sol"; +import { InvariantTest } from "test/invariants/InvariantTest.sol"; -contract SafeCall_Succeeds_Invariants is Test { +contract SafeCall_Succeeds_Invariants is InvariantTest { SafeCaller_Actor actor; - function setUp() public { + function setUp() public override { + super.setUp(); // Create a new safe caller actor. actor = new SafeCaller_Actor(vm, false); @@ -37,10 +39,11 @@ contract SafeCall_Succeeds_Invariants is Test { } } -contract SafeCall_Fails_Invariants is Test { +contract SafeCall_Fails_Invariants is InvariantTest { SafeCaller_Actor actor; - function setUp() public { + function setUp() public override { + super.setUp(); // Create a new safe caller actor. actor = new SafeCaller_Actor(vm, true); diff --git a/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol b/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol index 436148cd609c..75b4e6c2b265 100644 --- a/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol @@ -4,15 +4,9 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { Proxy } from "src/universal/Proxy.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Constants } from "src/libraries/Constants.sol"; contract SystemConfig_GasLimitLowerBound_Invariant is Test { - struct FuzzInterface { - address target; - string[] artifacts; - } - SystemConfig public config; function setUp() external { @@ -31,8 +25,7 @@ contract SystemConfig_GasLimitLowerBound_Invariant is Test { bytes32(hex"abcd"), // batcher hash 30_000_000, // gas limit address(1), // unsafe block signer - Constants.DEFAULT_RESOURCE_CONFIG(), // resource config - 0, //_startBlock + Constants.DEFAULT_RESOURCE_CONFIG(), address(0), // _batchInbox SystemConfig.Addresses({ // _addrs l1CrossDomainMessenger: address(0), @@ -59,19 +52,14 @@ contract SystemConfig_GasLimitLowerBound_Invariant is Test { selectors[0] = config.setGasLimit.selector; FuzzSelector memory selector = FuzzSelector({ addr: address(config), selectors: selectors }); targetSelector(selector); - } - - /// @dev Allows the SystemConfig contract to be the target of the invariant test - /// when it is behind a proxy. Foundry calls this function under the hood to - /// know the ABI to use when calling the target contract. - function targetInterfaces() public view returns (FuzzInterface[] memory) { - require(address(config) != address(0), "SystemConfig not initialized"); - FuzzInterface[] memory targets = new FuzzInterface[](1); + /// Allows the SystemConfig contract to be the target of the invariant test + /// when it is behind a proxy. Foundry calls this function under the hood to + /// know the ABI to use when calling the target contract. string[] memory artifacts = new string[](1); artifacts[0] = "SystemConfig"; - targets[0] = FuzzInterface(address(config), artifacts); - return targets; + FuzzInterface memory target = FuzzInterface(address(config), artifacts); + targetInterface(target); } /// @custom:invariant The gas limit of the `SystemConfig` contract can never be lower diff --git a/packages/contracts-bedrock/test/kontrol/README.md b/packages/contracts-bedrock/test/kontrol/README.md new file mode 100644 index 000000000000..341715601568 --- /dev/null +++ b/packages/contracts-bedrock/test/kontrol/README.md @@ -0,0 +1,194 @@ +# Kontrol Verification + + + + +- [Getting Started](#getting-started) + - [Overview](#overview) + - [Directory structure](#directory-structure) + - [Installation](#installation) +- [Usage](#usage) + - [Build Deployment Summary](#build-deployment-summary) + - [Execute Proofs](#execute-proofs) + - [Add New Proofs](#add-new-proofs) +- [Implementation Details](#implementation-details) + - [Assumptions](#assumptions) + - [Deployment Summary Process](#deployment-summary-process) + + + +## Getting Started + +### Overview + +[Kontrol](https://github.com/runtimeverification/kontrol) is a tool by [Runtime Verification](https://runtimeverification.com/) (RV) that enables formal verification of Ethereum smart contracts. Quoting from the Kontrol [docs](https://docs.runtimeverification.com/kontrol/overview/readme): + +> Kontrol combines [KEVM](https://github.com/runtimeverification/evm-semantics) and [Foundry](https://book.getfoundry.sh/) to grant developers the ability to perform [formal verification](https://en.wikipedia.org/wiki/Formal_verification) without learning a new language or tool. This is especially useful for those who are not verification engineers. Additionally, developers can leverage Foundry test suites they have already developed and use symbolic execution to increase the level of confidence. +> +> KEVM is a tool that enables formal verification of smart contracts on the Ethereum blockchain. It provides a mathematical foundation for specifying and implementing smart contracts. Developers can use KEVM to rigorously reason about the behavior of their smart contracts, ensuring correctness and reducing the likelihood of vulnerabilities in the contract code. + +This document details the Kontrol setup used in this repo to run various proofs against the contracts in the [`contracts-bedrock`](../../) directory. + +### Directory structure + +The directory is structured as follows + +
+├── pausability-lemmas.md: File containing the necessary lemmas for this project
+├── deployment: Custom deploy sequence for Kontrol proofs and tests for its fast summarization
+│   ├── KontrolDeployment.sol: Simplified deployment sequence for Kontrol proofs
+│   └── DeploymentSummary.t.sol: Tests for the summarization of custom deployment
+├── proofs: Where the proofs (tests) themselves live
+│   ├── *.k.sol: Symbolic property tests for contracts
+│   ├── interfaces: Interface files for src contracts, to avoid unnecessary compilation of contracts
+│   └── utils: Proof dependencies, including the autogenerated deployment summary contracts
+└── scripts: Where the scripts of the projects live
+    ├── json: Data cleaning scripts for the output of KontrolDeployment.sol
+    ├── make-summary-deployment.sh: Executes KontrolDeployment.sol, curates the result and writes the summary deployment contract
+    └── run-kontrol.sh: Wrapper around the kontrol CLI to run the proofs
+
+ +### Installation + +1. `cd` to the root of this repo. +2. Install Foundry by running `pnpm install:foundry`. This installs `foundryup`, the foundry toolchain installer, then installs the required foundry version. +3. Install Kontrol by running `pnpm install:kontrol`. This installs `kup`, the package manager for RV tools, then installs the required kontrol version. +4. Install Docker. + +## Usage + +Verifying proofs has two steps: build, and execute. + +### Build Deployment Summary + +First, generate a deployment summary contract from the deploy script in [`KontrolDeployment.sol`](./deployment/KontrolDeployment.sol) by running the following command: + +``` +./test/kontrol/scripts/make-summary-deployment.sh [container|local|dev] +``` + +The [`make-summary-deployment.sh`](./scripts/make-summary-deployment.sh) supports the same execution modes as `run-kontrol.sh` below. + +[`KontrolDeployment.sol`](./deployment/KontrolDeployment.sol) contains the minimal deployment sequence required by the proofs. +The [`make-summary-deployment.sh`](./scripts/make-summary-deployment.sh) script will generate a JSON state diff. This state diff is used in two ways by Kontrol. +First, Kontrol generates a summary contract recreating the state diffs recorded in the JSON. This contract is used to test that the information contained in the generated JSON is correct and aids in the specification of the symbolic property tests. The generation of this contract is also handled by the `make-summary-deployment.sh` script. +Second, the state diff JSON is used to load the post-deployment state directly into Kontrol when running the proofs. + +This step is optional if an up-to-date summary contract already exists, which will be the case until the `KontrolDeployment` contract changes, or any of the source contracts under test change. +See the [Implementation Details](#implementation-details) section for more information, and to learn about the CI check that ensures the committed autogenerated files from this step are up-to-date. + +The summary contract can be found in [`DeploymentSummary.sol`](./proofs/utils/DeploymentSummary.sol), which is summarization (state changes) of the [`KontrolDeployment.sol`](./deployment/KontrolDeployment.sol) contract. + +### Execute Proofs + +Use the [`run-kontrol.sh`](./scripts/run-kontrol.sh) script to runs the proofs in all `*.k.sol` files. + +``` +./test/kontrol/scripts/run-kontrol.sh [container|local|dev] [script|tests] +``` + +The `run-kontrol.sh` script supports three modes of proof execution: + +- `container`: Runs the proofs using the same Docker image used in CI. This is the default execution mode—if no arguments are provided, the proofs will be executed in this mode. +- `local`: Runs the proofs with your local Kontrol install, and enforces that the Kontrol version matches the one used in CI, which is specified in [`versions.json`](../../../../versions.json). +- `dev`: Run the proofs with your local Kontrol install, without enforcing any version in particular. The intended use case is proof development and related matters. + +It also supports two methods for specifying which tests to execute: + +- `script`: Runs the tests specified in the `test_list` variable +- `tests`: Names of the tests to be executed. `tests` can have two forms: + - `ContractName.testName`: e.g., `run-kontrol.sh ContractName.test1 ContractName.test2` + - Empty, executing all the functions starting with `test`, `prove` or `check` present in the defined `out` directory. For instance, `./test/kontrol/scripts/run-kontrol.sh` will execute all `prove_*` functions in the [proofs](./proofs/) directory using the same Docker image as in CI. [Warning: executing all proofs in parallel is _very_ resource intensive] + +For a similar description of the options run `run-kontrol.sh --help`. + +### Add New Proofs + +These are the instructions to add a new proof to this project. If all functions involved in the new proof are from a contract already deployed by [`KontrolDeployment`](./deployment/KontrolDeployment.sol) the first two steps can be skipped. + +#### Make Kontrol aware of the new contract being tested + +The `runKontrolDeployment` function of [`KontrolDeployment`](./deployment/KontrolDeployment.sol) partially reproduces the deployment process laid out in the `_run` function of [`Deploy.s.sol`](../../scripts/Deploy.s.sol). `runKontrolDeployment` has the `stateDiff` modifier to make use of [Foundry's state diff cheatcodes](https://book.getfoundry.sh/cheatcodes/start-state-diff-recording). Kontrol utilizes the JSON resulting from this modifier for two purposes: +1. Load all the state updates generated by `runKontrolDeployment` as the initial configuration for all proofs, effectively offloading the computation of the deployment process to `forge` and thus improving performance. +2. Produce the [`DeploymentSummary`](./proofs/utils/DeploymentSummary.sol) script contract to test that the produced JSON contains correct updates. + +Hence, in order to write a proof for a contract which is not present in `KontrolDeployment` it must be added there first. To add a new contract, properly inspect the above-mentioned `_run` function and place the corresponding deployment steps of the contract appropriately within the `runKontrolDeployment` function. + +Once new deployment steps have been added to `runKontrolDeployment` the state-diff files have to [be rebuilt](#build-deployment-summary). + +#### Include existing tests on the new state-diff recorded bytecode + +The next step is to include tests for the newly included state updates in [`DeploymentSummary.t.sol`](deployment/DeploymentSummary.t.sol). These tests inherit the tests from [`test`](../L1) of the contracts deployed by `runKontrolDeployment`. This ensures that deployment steps were implemented correctly and that the state updates are correct. + +It might be necessary to set some of the existing tests from [`test`](../L1) as virtual because they can't be executed as is. See [`DeploymentSummary.t.sol`](deployment/DeploymentSummary.t.sol) for more concrete examples. + +#### Add function signatures to [`KontrolInterfaces`](./proofs/interfaces/KontrolInterfaces.sol) + +So far we've got all the state updates ready to be added to the initial configuration of each proof, but we cannot yet write any proof about the function. We still need to add the relevant signatures into `KontrolInterfaces`. The reason for having `KontrolInterfaces` instead of using directly the contracts is to reduce the amount of compiled contracts by Kontrol. +In the future there might interfaces for all contracts under `contracts-bedrock`, which would imply the removal of `KontrolInterfaces`. + +#### Write the proof + +Write your proof in a `.k.sol` file in the [`proofs`](./proofs/) folder, which is the `test` directory used by the `kprove` profile to run the proofs (see [Deployment Summary Process](#deployment-summary-process)). The name of the new proofs should start with `prove` (or `check`) instead of `test` to avoid `forge test` running them. The reason for this is that if Kontrol cheatcodes (see [Kontrol's own cheatcodes](https://github.com/runtimeverification/kontrol-cheatcodes/blob/master/src/KontrolCheats.sol)) are used in a test, it will not be runnable by `forge`. Currently, none of the tests are using custom Kontrol cheatcodes, but this is something to bear in mind. + +To reference the correct addresses for writing the tests, first import the signatures as in this example: +```solidity +import { + IOptimismPortal as OptimismPortal, + ISuperchainConfig as SuperchainConfig +} from "./interfaces/KontrolInterfaces.sol"; +``` +Declare the correspondent variables and cast the correct signatures to the correct addresses: +```solidity +OptimismPortal optimismPortal; +SuperchainConfig superchainConfig; + +function setUp() public { + optimismPortal = OptimismPortal(payable(optimismPortalProxyAddress)); + superchainConfig = SuperchainConfig(superchainConfigProxyAddress); +} +``` +Note that the names of the addresses come from [`DeploymentSummary.t.sol`](deployment/DeploymentSummary.t.sol) and are automatically generated by the [`make-summary-deployment.sh`](./scripts/make-summary-deployment.sh) script. + +#### Add your test to [`run-kontrol.sh`](./scripts/run-kontrol.sh) + +As described in [Execute Proofs](#execute-proofs), there's a `script` mode for specifying which proofs to run, and that is the mode used in CI. To run the new proofs with the `script` option, add `ContractName.prove_functionName_paused` to the variable `test_list` in the `run-kontrol.sh` script. + +## Implementation Details + +### Assumptions + +1. A critical invariant of the `KontrolDeployment.sol` contract is that it stays in sync with the original `Deploy.s.sol` contract. + Currently, this is partly enforced by running some of the standard post-`setUp` deployment assertions in `DeploymentSummary.t.sol`. + A more rigorous approach may be to leverage the `ChainAssertions` library, but more investigation is required to determine if this is feasible without large changes to the deploy script. + +2. Size of `bytes[]` arguments. In [`OptimismPortal.k.sol`](./proofs/OptimismPortal.k.sol), the `prove_proveWithdrawalTransaction_paused` proof is broken down into 11 different proofs, each corresponding to a different size of the `_withdrawalProof` argument, which is of type `bytes[]`. We execute the same logic for lengths of `_withdrawalProof` ranging from 0 to 10, setting the length of each symbolic `bytes` element to 600. + - The reason for a max length of 10 is that it provides a conservative upper bound based on [historical data](https://dune.com/queries/3433954/5768623) for proof sizes. + - The reason for choosing 600 as the length for the elements of `_withdrawalProof` is that each element is `17 * 32 = 544` bytes long, so adding a 10% margin for RLP encoding and rounding up yields 600 bytes. The same historical data confirms this is a valid bound. + - All other symbolic `bytes` arguments that are not part of a `bytes` array have a symbolic length bounded by `2^63`. + +### Deployment Summary Process + +As mentioned above, a deployment summary contract is first generated before executing the proofs. +This is because the proof execution leverages Kontrol's [fast summarization](https://github.com/runtimeverification/kontrol/pull/271) feature, which allows loading the post-`setUp` state directly into Kontrol. +This provides a significant reduction in proof execution time, as it avoids the need to execute the deployment script every time the proofs are run. + +All code executed in Kontrol—even when execution is concrete and not symbolic—is significantly slower than in Foundry, due to the mathematical representation of the EVM in Kontrol. +Therefore we want to minimize the amount of code executed in Kontrol, and the fast summarization feature allows us to reduce `setUp` execution time. + +This project uses two different [`foundry.toml` profiles](../../foundry.toml), `kdeploy` and `kprove`, to facilitate usage of this fast summarization feature.: + +- `kdeploy`: Used by [`make-summary-deployment.sh`](./scripts/make-summary-deployment.sh) to generate the [`DeploymentSummary.sol`](./proofs/utils/DeploymentSummary.sol) contract based on execution of the [`KontrolDeployment.sol`](./deployment/KontrolDeployment.sol) contract using Foundry's state diff recording cheatcodes. + This is where all necessary [`src/L1`](../../src/L1) files are compiled with their bytecode saved into the [`DeploymentSummaryCode.sol`](./proofs/utils/DeploymentSummaryCode.sol) file, which is inherited by `DeploymentSummary`. + +- `kprove`: Used by the [`run-kontrol.sh`](./scrpts/run-kontrol.sh) script to execute proofs, which can be run once a `DeploymentSummary.sol` contract is present. This profile's `src` and `script` paths point to a test folder because we only want to compile what is in the `test/kontrol/proofs` folder, since that folder contains all bytecode and proofs. + +The `make-summary-deployment.sh` scripts saves off the generated JSON state diff to `snapshots/state-diff/Kontrol-Deploy.json`, and is run as part of the `snapshots` script in `package.json`. +Therefore, the snapshots CI check will fail if the committed Kontrol state diff is out of sync. +Note that the CI check only compares the JSON state diff, not the generated `DeploymentSummary.sol` or `DeploymentSummaryCode` contracts. +This is for simplicity, as those three files will be in sync upon successful execution of the `make-summary-deployment.sh` script. +We commit the `DeploymentSummary.sol` and `DeploymentSummaryCode.sol` contracts, because forge fails to build if those contracts are not present—it is simpler to commit these autogenerated files than to workaround their absence in forge builds. + +During `make-summary-deployment.sh`, the `mustGetAddress` usage in `Deploy.s.sol` is temporarily replaced by `getAddress`—the former reverts if the deployed contract does not exist, while the latter returns the zero address. +This is required because the deploy script in `KontrolDeployment.sol` is does not fully reproduce all deployments in `Deploy.s.sol`, so the `mustGetAddress` usage would cause the script to revert since some contracts are not deployed. +`KontrolDeployment.sol` is a simplified, minimal deployment sequence for Kontrol proofs, and is not intended to be a full deployment sequence for the contracts in `contracts-bedrock`. diff --git a/packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummary.t.sol b/packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummary.t.sol new file mode 100644 index 000000000000..90b73b9e987e --- /dev/null +++ b/packages/contracts-bedrock/test/kontrol/deployment/DeploymentSummary.t.sol @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Libraries +import { Constants } from "src/libraries/Constants.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Target contract dependencies +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { DeploymentSummary } from "../proofs/utils/DeploymentSummary.sol"; +import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol"; + +// Tests +import { L1CrossDomainMessenger_Test } from "test/L1/L1CrossDomainMessenger.t.sol"; +import { OptimismPortal_Test } from "test/L1/OptimismPortal.t.sol"; +import { L1ERC721Bridge_Test, TestERC721 } from "test/L1/L1ERC721Bridge.t.sol"; +import { + L1StandardBridge_Getter_Test, + L1StandardBridge_Initialize_Test, + L1StandardBridge_Pause_Test +} from "test/L1/L1StandardBridge.t.sol"; + +/// @dev Contract testing the deployment summary correctness +contract DeploymentSummary_TestOptimismPortal is DeploymentSummary, OptimismPortal_Test { + /// @notice super.setUp is not called on purpose + function setUp() public override { + // Recreate Deployment Summary state changes + DeploymentSummary deploymentSummary = new DeploymentSummary(); + deploymentSummary.recreateDeployment(); + + // Set summary addresses + optimismPortal = OptimismPortal(payable(optimismPortalProxyAddress)); + superchainConfig = SuperchainConfig(superchainConfigProxyAddress); + l2OutputOracle = L2OutputOracle(l2OutputOracleProxyAddress); + systemConfig = SystemConfig(systemConfigProxyAddress); + + // Set up utilized addresses + depositor = makeAddr("depositor"); + alice = makeAddr("alice"); + bob = makeAddr("bob"); + vm.deal(alice, 10000 ether); + vm.deal(bob, 10000 ether); + } + + /// @dev Skips the first line of `super.test_constructor_succeeds` because + /// we're not exercising the `Deploy` logic in these tests. However, + /// the remaining assertions of the test are important to check + function test_constructor_succeeds() external override { + // OptimismPortal opImpl = OptimismPortal(payable(deploy.mustGetAddress("OptimismPortal"))); + OptimismPortal opImpl = OptimismPortal(payable(optimismPortalAddress)); + assertEq(address(opImpl.L2_ORACLE()), address(0)); + assertEq(address(opImpl.l2Oracle()), address(0)); + assertEq(address(opImpl.SYSTEM_CONFIG()), address(0)); + assertEq(address(opImpl.systemConfig()), address(0)); + assertEq(address(opImpl.superchainConfig()), address(0)); + assertEq(opImpl.l2Sender(), Constants.DEFAULT_L2_SENDER); + } + + /// @dev Skips the first line of `super.test_initialize_succeeds` because + /// we're not exercising the `Deploy` logic in these tests. However, + /// the remaining assertions of the test are important to check + function test_initialize_succeeds() external override { + // address guardian = deploy.cfg().superchainConfigGuardian(); + address guardian = superchainConfig.guardian(); + assertEq(address(optimismPortal.L2_ORACLE()), address(l2OutputOracle)); + assertEq(address(optimismPortal.l2Oracle()), address(l2OutputOracle)); + assertEq(address(optimismPortal.SYSTEM_CONFIG()), address(systemConfig)); + assertEq(address(optimismPortal.systemConfig()), address(systemConfig)); + assertEq(optimismPortal.GUARDIAN(), guardian); + assertEq(optimismPortal.guardian(), guardian); + assertEq(address(optimismPortal.superchainConfig()), address(superchainConfig)); + assertEq(optimismPortal.l2Sender(), Constants.DEFAULT_L2_SENDER); + assertEq(optimismPortal.paused(), false); + } + + /// @notice This test is overridden because `KontrolDeployment` doesn't initialize + /// the L2OutputOracle, which is needed in this test + function test_simple_isOutputFinalized_succeeds() external override { } + + /// @notice This test is overridden because `KontrolDeployment` doesn't initialize + /// the L2OutputOracle, which is needed in this test + function test_isOutputFinalized_succeeds() external override { } +} + +contract DeploymentSummary_TestL1CrossDomainMessenger is DeploymentSummary, L1CrossDomainMessenger_Test { + /// @notice super.setUp is not called on purpose + function setUp() public override { + // Recreate Deployment Summary state changes + DeploymentSummary deploymentSummary = new DeploymentSummary(); + deploymentSummary.recreateDeployment(); + + // Set summary addresses + optimismPortal = OptimismPortal(payable(optimismPortalProxyAddress)); + superchainConfig = SuperchainConfig(superchainConfigProxyAddress); + l2OutputOracle = L2OutputOracle(l2OutputOracleProxyAddress); + systemConfig = SystemConfig(systemConfigProxyAddress); + l1CrossDomainMessenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxyAddress); + + // Set up utilized addresses + alice = makeAddr("alice"); + bob = makeAddr("bob"); + vm.deal(alice, 10000 ether); + vm.deal(bob, 10000 ether); + } + + /// @dev Skips the first line of `super.test_constructor_succeeds` because + /// we're not exercising the `Deploy` logic in these tests. However, + /// the remaining assertions of the test are important to check + function test_constructor_succeeds() external override { + // L1CrossDomainMessenger impl = L1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessenger")); + L1CrossDomainMessenger impl = L1CrossDomainMessenger(l1CrossDomainMessengerAddress); + assertEq(address(impl.superchainConfig()), address(0)); + assertEq(address(impl.PORTAL()), address(0)); + assertEq(address(impl.portal()), address(0)); + assertEq(address(impl.OTHER_MESSENGER()), Predeploys.L2_CROSS_DOMAIN_MESSENGER); + assertEq(address(impl.otherMessenger()), Predeploys.L2_CROSS_DOMAIN_MESSENGER); + } + + /// @notice This test is overridden because `KontrolDeployment` doesn't deploy + /// L2CrossDomainMessenger, which is needed in this test + function test_relayMessage_v2_reverts() external override { } +} + +contract DeploymentSummary_TestL1ERC721Bridge is DeploymentSummary, L1ERC721Bridge_Test { + /// @notice super.setUp is not called on purpose + function setUp() public override { + // Recreate Deployment Summary state changes + DeploymentSummary deploymentSummary = new DeploymentSummary(); + deploymentSummary.recreateDeployment(); + + // Set summary addresses + optimismPortal = OptimismPortal(payable(optimismPortalProxyAddress)); + superchainConfig = SuperchainConfig(superchainConfigProxyAddress); + l2OutputOracle = L2OutputOracle(l2OutputOracleProxyAddress); + systemConfig = SystemConfig(systemConfigProxyAddress); + l1CrossDomainMessenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxyAddress); + l1ERC721Bridge = L1ERC721Bridge(l1ERC721BridgeProxyAddress); + + // Set up utilized addresses + alice = makeAddr("alice"); + bob = makeAddr("bob"); + vm.deal(alice, 10000 ether); + vm.deal(bob, 10000 ether); + + // Bridge_Initializer setUp + L1Token = new ERC20("Native L1 Token", "L1T"); + + LegacyL2Token = new LegacyMintableERC20({ + _l2Bridge: address(l2StandardBridge), + _l1Token: address(L1Token), + _name: string.concat("LegacyL2-", L1Token.name()), + _symbol: string.concat("LegacyL2-", L1Token.symbol()) + }); + vm.label(address(LegacyL2Token), "LegacyMintableERC20"); + + // Deploy the L2 ERC20 now + // L2Token = OptimismMintableERC20( + // l2OptimismMintableERC20Factory.createStandardL2Token( + // address(L1Token), + // string(abi.encodePacked("L2-", L1Token.name())), + // string(abi.encodePacked("L2-", L1Token.symbol())) + // ) + // ); + + // BadL2Token = OptimismMintableERC20( + // l2OptimismMintableERC20Factory.createStandardL2Token( + // address(1), + // string(abi.encodePacked("L2-", L1Token.name())), + // string(abi.encodePacked("L2-", L1Token.symbol())) + // ) + // ); + + NativeL2Token = new ERC20("Native L2 Token", "L2T"); + + // RemoteL1Token = OptimismMintableERC20( + // l1OptimismMintableERC20Factory.createStandardL2Token( + // address(NativeL2Token), + // string(abi.encodePacked("L1-", NativeL2Token.name())), + // string(abi.encodePacked("L1-", NativeL2Token.symbol())) + // ) + // ); + + // BadL1Token = OptimismMintableERC20( + // l1OptimismMintableERC20Factory.createStandardL2Token( + // address(1), + // string(abi.encodePacked("L1-", NativeL2Token.name())), + // string(abi.encodePacked("L1-", NativeL2Token.symbol())) + // ) + // ); + + // L1ERC721Bridge_Test setUp + localToken = new TestERC721(); + remoteToken = new TestERC721(); + + // Mint alice a token. + localToken.mint(alice, tokenId); + + // Approve the bridge to transfer the token. + vm.prank(alice); + localToken.approve(address(l1ERC721Bridge), tokenId); + } + + /// @dev Skips the first line of `super.test_constructor_succeeds` because + /// we're not exercising the `Deploy` logic in these tests. However, + /// the remaining assertions of the test are important to check + function test_constructor_succeeds() public override { + // L1ERC721Bridge impl = L1ERC721Bridge(deploy.mustGetAddress("L1ERC721Bridge")); + L1ERC721Bridge impl = L1ERC721Bridge(l1ERC721BridgeAddress); + assertEq(address(impl.MESSENGER()), address(0)); + assertEq(address(impl.messenger()), address(0)); + assertEq(address(impl.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE); + assertEq(address(impl.otherBridge()), Predeploys.L2_ERC721_BRIDGE); + assertEq(address(impl.superchainConfig()), address(0)); + } +} + +contract DeploymentSummary_TestL1StandardBridge is + DeploymentSummary, + L1StandardBridge_Getter_Test, + L1StandardBridge_Initialize_Test, + L1StandardBridge_Pause_Test +{ + /// @notice super.setUp is not called on purpose + function setUp() public override { + // Recreate Deployment Summary state changes + DeploymentSummary deploymentSummary = new DeploymentSummary(); + deploymentSummary.recreateDeployment(); + + // Set summary addresses + optimismPortal = OptimismPortal(payable(optimismPortalProxyAddress)); + superchainConfig = SuperchainConfig(superchainConfigProxyAddress); + l2OutputOracle = L2OutputOracle(l2OutputOracleProxyAddress); + systemConfig = SystemConfig(systemConfigProxyAddress); + l1CrossDomainMessenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxyAddress); + l1ERC721Bridge = L1ERC721Bridge(l1ERC721BridgeProxyAddress); + l1StandardBridge = L1StandardBridge(payable(l1StandardBridgeProxyAddress)); + } + + /// @dev Skips the first line of `super.test_constructor_succeeds` because + /// we're not exercising the `Deploy` logic in these tests. However, + /// the remaining assertions of the test are important to check + function test_constructor_succeeds() external override { + // L1StandardBridge impl = L1StandardBridge(deploy.mustGetAddress("L1StandardBridge")); + L1StandardBridge impl = L1StandardBridge(payable(l1StandardBridgeAddress)); + assertEq(address(impl.superchainConfig()), address(0)); + assertEq(address(impl.MESSENGER()), address(0)); + assertEq(address(impl.messenger()), address(0)); + assertEq(address(impl.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE); + assertEq(address(impl.otherBridge()), Predeploys.L2_STANDARD_BRIDGE); + assertEq(address(l2StandardBridge), Predeploys.L2_STANDARD_BRIDGE); + } +} diff --git a/packages/contracts-bedrock/test/kontrol/deployment/KontrolDeployment.sol b/packages/contracts-bedrock/test/kontrol/deployment/KontrolDeployment.sol new file mode 100644 index 000000000000..ae88bdb0c3cd --- /dev/null +++ b/packages/contracts-bedrock/test/kontrol/deployment/KontrolDeployment.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Deploy } from "scripts/Deploy.s.sol"; + +contract KontrolDeployment is Deploy { + function runKontrolDeployment() public stateDiff { + deploySafe(); + setupSuperchain(); + + // deployProxies(); + deployERC1967Proxy("OptimismPortalProxy"); + deployERC1967Proxy("L2OutputOracleProxy"); + deployERC1967Proxy("SystemConfigProxy"); + deployL1StandardBridgeProxy(); + deployL1CrossDomainMessengerProxy(); + deployERC1967Proxy("L1ERC721BridgeProxy"); + transferAddressManagerOwnership(); // to the ProxyAdmin + + // deployImplementations(); + deployOptimismPortal(); + deployL1CrossDomainMessenger(); + deployL2OutputOracle(); + deploySystemConfig(); + deployL1StandardBridge(); + deployL1ERC721Bridge(); + + // initializeImplementations(); + initializeSystemConfig(); + initializeL1StandardBridge(); + initializeL1ERC721Bridge(); + initializeL1CrossDomainMessenger(); + initializeOptimismPortal(); + } +} diff --git a/packages/contracts-bedrock/test/kontrol/pausability-lemmas.md b/packages/contracts-bedrock/test/kontrol/pausability-lemmas.md new file mode 100644 index 000000000000..a522a5709e61 --- /dev/null +++ b/packages/contracts-bedrock/test/kontrol/pausability-lemmas.md @@ -0,0 +1,225 @@ +Kontrol Lemmas +============== + +Lemmas are K rewrite rules that enhance the reasoning power of Kontrol. For more information on lemmas, please consult [this section](https://docs.runtimeverification.com/kontrol/guides/advancing-proofs) of the Kontrol documentation. + +This file contains the lemmas required to run the proofs included in the [proofs](./proofs) folder. Some of these lemmas are general enough to likely be incorporated into future versions of Kontrol, while others are specific to the challenges presented by the proofs. + +Similarly to other files such as [`cheatcodes.md`](https://github.com/runtimeverification/kontrol/blob/master/src/kontrol/kdist/cheatcodes.md), we use the idiomatic way of programming in Kontrol, which is [literate programming](https://en.wikipedia.org/wiki/Literate_programming), allowing for better documentation of the code. + +## Imports + +For writing the lemmas, we use the [`foundry.md`](https://github.com/runtimeverification/kontrol/blob/master/src/kontrol/kdist/foundry.md) file. This file contains and imports all of the definitions from KEVM and Kontrol on top of which we write the lemmas. + +```k +requires "foundry.md" + +module PAUSABILITY-LEMMAS + imports BOOL + imports FOUNDRY + imports INT-SYMBOLIC +``` + +## Arithmetic + +Lemmas on arithmetic reasoning. Specifically, on: cancellativity, inequalites in which the two sides are of different signs; and the rounding-up mechanism of the Solidity compiler (expressed through `notMaxUInt5 &Int ( X +Int 31 )`, which rounds up `X` to the nearest multiple of 32). + +```k + // Cancellativity #1 + rule A +Int ( (B -Int A) +Int C ) => B +Int C [simplification] + + // Cancellativity #2 + rule (A -Int B) -Int (C -Int B) => A -Int C [simplification] + + // Cancellativity #3 + rule A -Int (A +Int B) => 0 -Int B [simplification] + + // Various inequalities + rule X true requires X true requires X true requires X true + requires 0 <=Int Y + [simplification] + + // Bounds on notMaxUInt5 &Int ( X +Int 31 ) + rule X <=Int notMaxUInt5 &Int ( X +Int 31 ) => true requires 0 <=Int X [simplification] + rule X <=Int notMaxUInt5 &Int ( Y +Int 31 ) => true requires X <=Int 0 andBool 0 <=Int Y [simplification, concrete(X)] + rule X <=Int ( notMaxUInt5 &Int ( X +Int 31 ) ) +Int Y => true requires 0 <=Int X andBool 0 <=Int Y [simplification, concrete(Y)] + + rule notMaxUInt5 &Int X +Int 31 true requires 0 <=Int X andBool X +Int 32 <=Int Y [simplification, concrete(Y)] + + rule notMaxUInt5 &Int X +Int 31 true requires 0 <=Int X [simplification] +``` + +## `#asWord` + +Lemmas about [`#asWord`](https://github.com/runtimeverification/evm-semantics/blob/master/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/evm-types.md#bytes-helper-functions). `#asWord(B)` interprets the byte array `B` as a single word (with MSB first). + +```k + // Move to function parameters + rule { #asWord ( BA1 ) #Equals #asWord ( BA2 ) } => #Top + requires BA1 ==K BA2 + [simplification] + + // #asWord ignores leading zeros + rule #asWord ( BA1 +Bytes BA2 ) => #asWord ( BA2 ) + requires #asInteger(BA1) ==Int 0 + [simplification, concrete(BA1)] + + // `#asWord` of a byte array cannot equal a number that cannot fit within the byte array + rule #asWord ( BA ) ==Int Y => false + requires lengthBytes(BA) <=Int 32 + andBool (2 ^Int (8 *Int lengthBytes(BA))) <=Int Y + [concrete(Y), simplification] +``` + +## `#asInteger` + +Lemmas about [`#asInteger`](https://github.com/runtimeverification/evm-semantics/blob/master/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/evm-types.md#bytes-helper-functions). `#asInteger(X)` interprets the byte array `X` as a single arbitrary-precision integer (with MSB first). + +```k + // Conversion from bytes always yields a non-negative integer + rule 0 <=Int #asInteger ( _ ) => true [simplification] +``` + +## `#padRightToWidth` + +Lemmas about [`#padRightToWidth`](https://github.com/runtimeverification/evm-semantics/blob/master/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/evm-types.md#bytes-helper-functions). `#padRightToWidth(W, BA)` right-pads the byte array `BA` with zeros so that the resulting byte array has length `W`. + +```k + // Definitional expansion + rule #padRightToWidth (W, BA) => BA +Bytes #buf(W -Int lengthBytes(BA), 0) + [concrete(W), simplification] +``` + +## `#range(BA, START, WIDTH)` + +Lemmas about [`#range(BA, START, WIDTH)`](https://github.com/runtimeverification/evm-semantics/blob/master/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/evm-types.md#bytes-helper-functions). `#range(BA, START, WIDTH)` returns the range of `BA` from index `START` of width `WIDTH`. + +```k + // Parameter equality + rule { #range (BA, S, W1) #Equals #range (BA, S, W2) } => #Top + requires W1 ==Int W2 + [simplification] +``` + +## Byte array indexing and update + +Lemmas about [`BA [ I ]` and `BA1 [ S := BA2 ]`](https://github.com/runtimeverification/evm-semantics/blob/master/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/evm-types.md#element-access). `BA [ I ]` returns the integer representation of the `I`-th byte of byte array `BA`. `BA1 [ S := BA2 ]` updates the byte array `BA1` with byte array `BA2` from index `S`. + + +```k + // Byte indexing in terms of #asWord + rule BA [ X ] => #asWord ( #range (BA, X, 1) ) + requires X <=Int lengthBytes(BA) + [simplification(40)] + + // Empty update has no effect + rule BA [ START := b"" ] => BA + requires 0 <=Int START andBool START <=Int lengthBytes(BA) + [simplification] + + // Update passes to right operand of concat if start position is beyond the left operand + rule ( BA1 +Bytes BA2 ) [ S := BA ] => BA1 +Bytes ( BA2 [ S -Int lengthBytes(BA1) := BA ] ) + requires lengthBytes(BA1) <=Int S + [simplification] + + // Consecutive quasi-contiguous byte-array update + rule BA [ S1 := BA1 ] [ S2 := BA2 ] => BA [ S1 := #range(BA1, 0, S2 -Int S1) +Bytes BA2 ] + requires 0 <=Int S1 andBool S1 <=Int S2 andBool S2 <=Int S1 +Int lengthBytes(BA1) + [simplification] + + // Parameter equality: byte-array update + rule { BA1:Bytes [ S1 := BA2 ] #Equals BA3:Bytes [ S2 := BA4 ] } => #Top + requires BA1 ==K BA3 andBool S1 ==Int S2 andBool BA2 ==K BA4 + [simplification] +``` + +Summaries +--------- + +Functions summaries are rewrite rules that capture (summarize) the effects of executing a function. Such rules allow Kontrol to, instead of executing the function itself, just apply the summary rule. + +## `copy_memory_to_memory` summary + +The following rule summarises the behavior of the `copy_memory_to_memory` function. This function is automatically generated by the Solidity compiler. In its Yul form, it is as follows: + +```solidity +function copy_memory_to_memory(src, dst, length) { + let i := 0 + for { } lt(i, length) { i := add(i, 32) } + { + mstore(add(dst, i), mload(add(src, i))) + } + if gt(i, length) + { + // clear end + mstore(add(dst, length), 0) + } +} +``` + +It is used to copy `length` bytes of memory from index `src` to index `dest`, doing so in steps of 32 bytes, and right-padding with zeros to a multiple of 32. + +Following the compiler constraints, we enforce a limit on the length of byte arrays and indices into byte arrays. + +```k + syntax Int ::= "maxBytesLength" [alias] + rule maxBytesLength => 9223372036854775808 +``` + +The summary lemma is as follows, with commentary inlined: + +```k + rule [copy-memory-to-memory-summary]: + #execute ... + false + SHANGHAI + JUMPDESTS + // The program and program counter are symbolic, focusing on the part we will be executing (CP) + PROGRAM + PCOUNT => PCOUNT +Int 53 + // The word stack has the appropriate form, as per the compiled code + LENGTH : _ : SRC : DEST : WS + // The program copies LENGTH bytes of memory from SRC +Int 32 to DEST +Int OFFSET, + // padded with 32 zeros in case LENGTH is not divisible by 32 + + LM => LM [ DEST +Int 32 := #range ( LM, SRC +Int 32, LENGTH ) +Bytes + #buf ( ( ( notMaxUInt5 &Int ( LENGTH +Int maxUInt5 ) ) -Int LENGTH ) , 0 ) +Bytes + #buf ( ( ( ( 32 -Int ( ( notMaxUInt5 &Int ( LENGTH +Int maxUInt5 ) ) -Int LENGTH ) ) ) modInt 32 ), 0 ) ] + + requires + // The current program we are executing differs from the original one only in the hardcoded jump addresses, + // which are now relative to PCOUNT, and the hardcoded offset, which is now symbolic. + #range(PROGRAM, PCOUNT, 53) ==K b"`\x00[\x81\x81\x10\x15b\x00\x81`W` \x81\x85\x01\x81\x01Q\x86\x83\x01\x82\x01R\x01b\x00\x81BV[\x81\x81\x11\x15b\x00\x81sW`\x00` \x83\x87\x01\x01R[P" + [ 08 := #buf(3, PCOUNT +Int 32) ] + [ 28 := #buf(3, PCOUNT +Int 2) ] + [ 38 := #buf(3, PCOUNT +Int 51) ] + + // Various well-formedness constraints. In particular, the maxBytesLength-related ones are present to + // remove various chops that would otherwise creep into the execution, and are reasonable since byte + // arrays in actual programs would never reach that size. + andBool 0 <=Int PCOUNT + andBool 0 <=Int LENGTH andBool LENGTH &2 ; } + +# usage function for the run-kontrol.sh script +usage_run_kontrol() { + echo "Usage: $0 [-h|--help] [container|local|dev] [script|tests]" 1>&2 + echo "" 1>&2 + echo " -h, --help Display this help message." 1>&2 + echo "" 1>&2 + echo "Execution modes:" + echo " container Run in docker container. Reproduce CI execution. (Default)" 1>&2 + echo " local Run locally, enforces registered versions.json version for better reproducibility. (Recommended)" 1>&2 + echo " dev Run locally, does NOT enforce registered version. (Useful for developing with new versions and features)" 1>&2 + echo "" 1>&2 + echo "Tests executed:" + echo " script Execute the tests recorded in run-kontrol.sh" 1>&2 + echo " tests Execute the tests provided as arguments" 1>&2 + exit 0 +} + +# usage function for the make-summary-deployment.sh script +usage_make_summary() { + echo "Usage: $0 [-h|--help] [container|local|dev]" 1>&2 + echo "" 1>&2 + echo " -h, --help Display this help message." 1>&2 + echo "" 1>&2 + echo "Execution modes:" + echo " container Run in docker container. Reproduce CI execution. (Default)" 1>&2 + echo " local Run locally, enforces registered versions.json version for better reproducibility. (Recommended)" 1>&2 + echo " dev Run locally, does NOT enforce registered version. (Useful for developing with new versions and features)" 1>&2 + exit 0 +} + +# Set Run Directory /packages/contracts-bedrock +WORKSPACE_DIR=$( cd "$SCRIPT_HOME/../../.." >/dev/null 2>&1 && pwd ) + +# Variables +export CONTAINER_NAME=kontrol-tests +KONTROLRC=$(jq -r .kontrol < "$WORKSPACE_DIR/../../versions.json") +export KONTROL_RELEASE=$KONTROLRC +export LOCAL=false +export SCRIPT_TESTS=false +SCRIPT_OPTION=false +export CUSTOM_TESTS=0 # Store the position where custom tests start, interpreting 0 as no tests +CUSTOM_OPTION=0 +export RUN_KONTROL=false # true if any functions are called from run-kontrol.sh + +# General usage function, which discerns from which script is being called and displays the appropriate message +usage() { + if [ "$RUN_KONTROL" = "true" ]; then + usage_run_kontrol + else + usage_make_summary + fi +} + + +# Argument Parsing +# The logic behind argument parsing is the following (in order): +# - Execution mode argument: container (or empty), local, dev +# - Tests arguments (first if execution mode empty): script, specific test names +parse_args() { + if [ $# -eq 0 ]; then + export LOCAL=false + export SCRIPT_TESTS=false + export CUSTOM_TESTS=0 + # `script` argument caps the total possible arguments to its position + elif { [ $# -gt 1 ] && [ "$1" == "script" ]; } || { [ $# -gt 2 ] && [ "$2" == "script" ]; }; then + usage + elif [ $# -eq 1 ]; then + SCRIPT_OPTION=false + CUSTOM_OPTION=0 + parse_first_arg "$1" + elif [ $# -eq 2 ] && [ "$2" == "script" ]; then + if [ "$1" != "container" ] && [ "$1" != "local" ] && [ "$1" != "dev" ]; then + notif "Invalid first argument. Must be \`container\`, \`local\` or \`dev\`" + exit 1 + fi + SCRIPT_OPTION=true + CUSTOM_OPTION=0 + parse_first_arg "$1" + else + SCRIPT_OPTION=false + CUSTOM_OPTION=2 + parse_first_arg "$1" + fi +} + +# Parse the first argument passed to `run-kontrol.sh` +parse_first_arg() { + if [ "$1" == "container" ]; then + notif "Running in docker container (DEFAULT)" + export LOCAL=false + export SCRIPT_TESTS=$SCRIPT_OPTION + export CUSTOM_TESTS=$CUSTOM_OPTION + elif [ "$1" == "-h" ] || [ "$1" == "--help" ]; then + usage + elif [ "$1" == "local" ]; then + notif "Running with LOCAL install, .kontrolrc CI version ENFORCED" + export SCRIPT_TESTS=$SCRIPT_OPTION + export CUSTOM_TESTS=$CUSTOM_OPTION + check_kontrol_version + elif [ "$1" == "dev" ]; then + notif "Running with LOCAL install, IGNORING .kontrolrc version" + export LOCAL=true + export SCRIPT_TESTS=$SCRIPT_OPTION + export CUSTOM_TESTS=$CUSTOM_OPTION + pushd "$WORKSPACE_DIR" > /dev/null || exit + elif [ "$1" == "script" ]; then + notif "Running in docker container (DEFAULT)" + export LOCAL=false + NEGATED_SCRIPT_TESTS=$([[ "${SCRIPT_OPTION}" == "true" ]] && echo false || echo true) + export SCRIPT_TESTS=$NEGATED_SCRIPT_TESTS + export CUSTOM_TESTS=$CUSTOM_OPTION + else + notif "Running in docker container (DEFAULT)" + export LOCAL=false + export SCRIPT_TESTS=$SCRIPT_OPTION + export CUSTOM_TESTS=1 # Store the position where custom tests start + fi +} + +check_kontrol_version() { + if [ "$(kontrol version | awk -F': ' '{print$2}')" == "$KONTROLRC" ]; then + notif "Kontrol version matches $KONTROLRC" + export LOCAL=true + pushd "$WORKSPACE_DIR" > /dev/null || exit + else + notif "Kontrol version does NOT match $KONTROLRC" + notif "Please run 'kup install kontrol --version v$KONTROLRC'" + exit 1 + fi +} + +conditionally_start_docker() { + if [ "$LOCAL" == false ]; then + # Is old docker container running? + if [ "$(docker ps -q -f name="$CONTAINER_NAME")" ]; then + # Stop old docker container + notif "Stopping old docker container" + clean_docker + fi + start_docker + fi +} + +start_docker () { + docker run \ + --name "$CONTAINER_NAME" \ + --rm \ + --interactive \ + --detach \ + --env FOUNDRY_PROFILE="$FOUNDRY_PROFILE" \ + --workdir /home/user/workspace \ + runtimeverificationinc/kontrol:ubuntu-jammy-"$KONTROL_RELEASE" + + copy_to_docker +} + +copy_to_docker() { + # Copy test content to container. We need to avoid copying node_modules because + # it results in the below error, so we copy the workspace to a temp directory + # and then copy it to the container. + # Error response from daemon: invalid symlink "/home/user/workspace/node_modules/@typescript-eslint/eslint-plugin" -> "../../../../node_modules/.pnpm/@typescript-eslint+eslint-plugin@6.19.1_@typescript-eslint+parser@6.19.1_eslint@8.56.0_typescript@5.3.3/node_modules/@typescript-eslint/eslint-plugin" + # Even though we use a bind mount, we still need to copy the files to the + # container because we are running Docker on a remote host. + if [ "$LOCAL" == false ]; then + TMP_DIR=$(mktemp -d) + cp -r "$WORKSPACE_DIR/." "$TMP_DIR" + rm -rf "$TMP_DIR/node_modules" + docker cp --follow-link "$TMP_DIR/." $CONTAINER_NAME:/home/user/workspace + rm -rf "$TMP_DIR" + + docker exec --user root "$CONTAINER_NAME" chown -R user:user /home/user + fi +} + +clean_docker(){ + notif "Stopping Docker Container" + docker stop "$CONTAINER_NAME" +} + + +docker_exec () { + docker exec --user user --workdir /home/user/workspace $CONTAINER_NAME "${@}" +} + +run () { + if [ "$LOCAL" = true ]; then + notif "Running local" + # shellcheck disable=SC2086 + "${@}" + else + notif "Running in docker" + docker_exec "${@}" + fi +} diff --git a/packages/contracts-bedrock/test/kontrol/scripts/json/clean_json.py b/packages/contracts-bedrock/test/kontrol/scripts/json/clean_json.py new file mode 100644 index 000000000000..70f97fad40cd --- /dev/null +++ b/packages/contracts-bedrock/test/kontrol/scripts/json/clean_json.py @@ -0,0 +1,61 @@ +""" +Description: + Unescapes the JSON produced by the stateDiff modifier + defined in contracts-bedrock/scripts/Deploy.s.sol + This script is used in ../make-summary-deployment.sh + +Usage: + After producing a state diff JSON with the stateDiff modifier + (e.g. by executing KontrolDeployment::runKontrolDeployment), the JSON is + saved under contracts-bedrock/snapshots/state-diff/Deploy.json. To unescape + it, run: python3 clean_json.py $path_to_state_diff_json + The unescaped JSON will rewrite the input file +""" + +import sys +import json + +def clean_json(input_file): + with open(input_file, 'r') as file: + input_string = file.read() + + result = input_string + + # Remove backslashes + result = result.replace('\\', '') + + # Remove " between ] and , + result = result.replace(']",', '],') + + # Remove " between } and ] + result = result.replace('}"]', '}]') + + # Remove " between [ and { + result = result.replace('["{', '[{') + + # Remove " between } and , + result = result.replace('}",', '},') + + # Remove " between , and { + result = result.replace(',"{', ',{') + + # Remove " before [{ + result = result.replace('"[{', '[{') + + # Remove " after }] + result = result.replace('}]"', '}]') + + with open(input_file, 'w') as file: + file.write(result) + +if __name__ == "__main__": + # Check if a file path is provided as a command line argument + if len(sys.argv) != 2: + print("Usage: clean_json.py ") + sys.exit(1) + + input_file_path = sys.argv[1] + + clean_json(input_file_path) + + print(f"Operation completed. Result saved to {input_file_path}") diff --git a/packages/contracts-bedrock/test/kontrol/scripts/json/reverse_key_values.py b/packages/contracts-bedrock/test/kontrol/scripts/json/reverse_key_values.py new file mode 100644 index 000000000000..bc3816db9f7a --- /dev/null +++ b/packages/contracts-bedrock/test/kontrol/scripts/json/reverse_key_values.py @@ -0,0 +1,46 @@ +""" +Description: + Reverses the key-value pairs of a given JSON + The use case for this script within the project is to reverse the key-value + pairs of the auto generated file contracts-bedrock/deployments/hardhat/.deployment + so that it can be fed as the `--contract-names` argument to `kontrol summary` + This script is used in ../make-summary-deployment.sh + +Usage: + To reverse the order of an $input_file and save it to an $output_file run + `python3 reverse_key_values.py $input_file $output_file` +""" + +import sys +import json + +def reverse_json(input_file, output_file): + try: + with open(input_file, 'r') as file: + json_data = json.load(file) + + reversed_json = {str(value): key[0].lower() + key[1:] for key, value in json_data.items()} + + with open(output_file, 'w') as file: + json.dump(reversed_json, file, indent=2) + + print(f"Reversed JSON saved to {output_file}") + + except FileNotFoundError: + print(f"Error: File not found: {input_file}") + sys.exit(1) + except json.JSONDecodeError: + print(f"Error: Invalid JSON format in file: {input_file}") + sys.exit(1) + +if __name__ == "__main__": + # Check if both input and output file paths are provided + if len(sys.argv) != 3: + print("Usage: reverse_key_values.py ") + sys.exit(1) + + input_file_path = sys.argv[1] + output_file_path = sys.argv[2] + + # Execute the function to reverse JSON and save to the output file + reverse_json(input_file_path, output_file_path) diff --git a/packages/contracts-bedrock/test/kontrol/scripts/make-summary-deployment.sh b/packages/contracts-bedrock/test/kontrol/scripts/make-summary-deployment.sh new file mode 100755 index 000000000000..589f52c30764 --- /dev/null +++ b/packages/contracts-bedrock/test/kontrol/scripts/make-summary-deployment.sh @@ -0,0 +1,91 @@ +#!/bin/bash +set -euo pipefail + +export FOUNDRY_PROFILE=kdeploy + +SCRIPT_HOME="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +# shellcheck source=/dev/null +source "$SCRIPT_HOME/common.sh" +# Sanity check on arguments +if [ $# -gt 1 ]; then + echo "At most one argument can be provided. Instead $# were provided" 1>&2 + exit 1 +elif [ $# -eq 1 ]; then + if [ "$1" != "-h" ] && [ "$1" != "--help" ] && [ "$1" != "container" ] && [ "$1" != "local" ] && [ "$1" != "dev" ]; then + notif "Invalid argument. Must be \`container\`, \`local\`, \`dev\`, \`-h\` or \`--help\`" + exit 1 + else + parse_first_arg "$@" + fi +fi + +cleanup() { + # Restore the original script from the backup + if [ -f "$DEPLOY_SCRIPT.bak" ]; then + cp "$DEPLOY_SCRIPT.bak" "$DEPLOY_SCRIPT" + rm "$DEPLOY_SCRIPT.bak" + fi + + if [ -f "snapshots/state-diff/Deploy.json" ]; then + rm "snapshots/state-diff/Deploy.json" + fi + + if [ "$LOCAL" = false ]; then + clean_docker + fi +} + +# Set trap to call cleanup function on exit +trap cleanup EXIT + +# create deployments/hardhat/.deploy and snapshots/state-diff/Deploy.json if necessary +if [ ! -d "deployments/hardhat" ]; then + mkdir deployments/hardhat; +fi +if [ ! -f "deployments/hardhat/.deploy" ]; then + touch deployments/hardhat/.deploy; +fi +if [ ! -d "snapshots/state-diff" ]; then + mkdir snapshots/state-diff; +fi +if [ ! -f "snapshots/state-diff/Deploy.json" ]; then + touch snapshots/state-diff/Deploy.json; +fi + +DEPLOY_SCRIPT="./scripts/Deploy.s.sol" +conditionally_start_docker + +# Create a backup +cp $DEPLOY_SCRIPT $DEPLOY_SCRIPT.bak + +# Replace mustGetAddress by getAddress in Deploy.s.sol +# This is needed because the Kontrol deployment is only a partial +# version of the full Optimism deployment. Since not all the components +# of the system are deployed, we'd get some reverts on the `mustGetAddress` functions +awk '{gsub(/mustGetAddress/, "getAddress")}1' $DEPLOY_SCRIPT > temp && mv temp $DEPLOY_SCRIPT + +forge script -vvv test/kontrol/deployment/KontrolDeployment.sol:KontrolDeployment --sig 'runKontrolDeployment()' +echo "Created state diff json" + +# Clean and store the state diff json in snapshots/state-diff/Kontrol-Deploy.json +JSON_SCRIPTS=test/kontrol/scripts/json +GENERATED_STATEDIFF=Deploy.json # Name of the statediff json produced by the deployment script +STATEDIFF=Kontrol-$GENERATED_STATEDIFF # Name of the Kontrol statediff +mv snapshots/state-diff/$GENERATED_STATEDIFF snapshots/state-diff/$STATEDIFF +python3 $JSON_SCRIPTS/clean_json.py snapshots/state-diff/$STATEDIFF +jq . snapshots/state-diff/$STATEDIFF > temp && mv temp snapshots/state-diff/$STATEDIFF # Prettify json +echo "Cleaned state diff json" + +CONTRACT_NAMES=deployments/hardhat/.deploy +python3 $JSON_SCRIPTS/reverse_key_values.py $CONTRACT_NAMES ${CONTRACT_NAMES}Reversed +CONTRACT_NAMES=${CONTRACT_NAMES}Reversed + +SUMMARY_DIR=test/kontrol/proofs/utils +SUMMARY_NAME=DeploymentSummary +LICENSE=MIT + +copy_to_docker # Copy the newly generated files to the docker container +run kontrol load-state-diff $SUMMARY_NAME snapshots/state-diff/$STATEDIFF --contract-names $CONTRACT_NAMES --output-dir $SUMMARY_DIR --license $LICENSE +forge fmt $SUMMARY_DIR/$SUMMARY_NAME.sol +forge fmt $SUMMARY_DIR/${SUMMARY_NAME}Code.sol +echo "Added state updates to $SUMMARY_DIR/$SUMMARY_NAME.sol" diff --git a/packages/contracts-bedrock/test/kontrol/scripts/run-kontrol.sh b/packages/contracts-bedrock/test/kontrol/scripts/run-kontrol.sh new file mode 100755 index 000000000000..5b37edf796f5 --- /dev/null +++ b/packages/contracts-bedrock/test/kontrol/scripts/run-kontrol.sh @@ -0,0 +1,186 @@ +#!/bin/bash +set -euo pipefail + +export FOUNDRY_PROFILE=kprove + +SCRIPT_HOME="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +# shellcheck source=/dev/null +source "$SCRIPT_HOME/common.sh" +export RUN_KONTROL=true +parse_args "$@" + +############# +# Functions # +############# +kontrol_build() { + notif "Kontrol Build" + # shellcheck disable=SC2086 + run kontrol build \ + --verbose \ + --require $lemmas \ + --module-import $module \ + $rekompile +} + +kontrol_prove() { + notif "Kontrol Prove" + # shellcheck disable=SC2086 + run kontrol prove \ + --max-depth $max_depth \ + --max-iterations $max_iterations \ + --smt-timeout $smt_timeout \ + --workers $workers \ + $reinit \ + $bug_report \ + $break_on_calls \ + $break_every_step \ + $auto_abstract \ + $tests \ + $use_booster \ + --init-node-from $state_diff \ + --xml-test-report +} + +dump_log_results(){ + trap clean_docker ERR + RESULTS_FILE="results-$(date +'%Y-%m-%d-%H-%M-%S').tar.gz" + LOG_PATH="test/kontrol/logs" + RESULTS_LOG="$LOG_PATH/$RESULTS_FILE" + + if [ ! -d $LOG_PATH ]; then + mkdir $LOG_PATH + fi + + notif "Generating Results Log: $LOG_PATH" + + run tar -czvf results.tar.gz kout-proofs/ > /dev/null 2>&1 + if [ "$LOCAL" = true ]; then + mv results.tar.gz "$RESULTS_LOG" + else + docker cp "$CONTAINER_NAME:/home/user/workspace/results.tar.gz" "$RESULTS_LOG" + fi + if [ -f "$RESULTS_LOG" ]; then + cp "$RESULTS_LOG" "$LOG_PATH/kontrol-results_latest.tar.gz" + else + notif "Results Log: $RESULTS_LOG not found, skipping.." + fi + # Report where the file was generated and placed + notif "Results Log: $(dirname "$RESULTS_LOG") generated" + + if [ "$LOCAL" = false ]; then + notif "Results Log: $RESULTS_LOG generated" + RUN_LOG="run-kontrol-$(date +'%Y-%m-%d-%H-%M-%S').log" + docker logs "$CONTAINER_NAME" > "$LOG_PATH/$RUN_LOG" + fi +} + +# Define the function to run on failure +on_failure() { + dump_log_results + + if [ "$LOCAL" = false ]; then + clean_docker + fi + + notif "Cleanup complete." + exit 1 +} + +# Set up the trap to run the function on failure +trap on_failure ERR INT + +######################### +# kontrol build options # +######################### +# NOTE: This script has a recurring pattern of setting and unsetting variables, +# such as `rekompile`. Such a pattern is intended for easy use while locally +# developing and executing the proofs via this script. Comment/uncomment the +# empty assignment to activate/deactivate the corresponding flag +lemmas=test/kontrol/pausability-lemmas.md +base_module=PAUSABILITY-LEMMAS +module=OptimismPortalKontrol:$base_module +rekompile=--rekompile +rekompile= +regen=--regen +# shellcheck disable=SC2034 +regen= + +################################# +# Tests to symbolically execute # +################################# + +# Temporarily unexecuted tests +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused0" \ +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused1" \ +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused2" \ +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused3" \ +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused4" \ +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused5" \ +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused6" \ +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused7" \ +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused8" \ +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused9" \ +# "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused10" \ + +test_list=() +if [ "$SCRIPT_TESTS" == true ]; then + test_list=( "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused0" \ + "OptimismPortalKontrol.prove_proveWithdrawalTransaction_paused1" \ + "OptimismPortalKontrol.prove_finalizeWithdrawalTransaction_paused" \ + "L1StandardBridgeKontrol.prove_finalizeBridgeERC20_paused" \ + "L1StandardBridgeKontrol.prove_finalizeBridgeETH_paused" \ + "L1ERC721BridgeKontrol.prove_finalizeBridgeERC721_paused" \ + "L1CrossDomainMessengerKontrol.prove_relayMessage_paused" + ) +elif [ "$CUSTOM_TESTS" != 0 ]; then + test_list=( "${@:${CUSTOM_TESTS}}" ) +fi +tests="" +for test_name in "${test_list[@]}"; do + tests+="--match-test $test_name " +done + +######################### +# kontrol prove options # +######################### +max_depth=10000 +max_iterations=10000 +smt_timeout=100000 +max_workers=7 # Set to 7 since the CI machine has 8 CPUs +# workers is the minimum between max_workers and the length of test_list +# unless no test arguments are provided, in which case we default to max_workers +if [ "$CUSTOM_TESTS" == 0 ] && [ "$SCRIPT_TESTS" == false ]; then + workers=${max_workers} +else + workers=$((${#test_list[@]}>max_workers ? max_workers : ${#test_list[@]})) +fi +reinit=--reinit +reinit= +break_on_calls=--no-break-on-calls +# break_on_calls= +break_every_step=--break-every-step +break_every_step= +auto_abstract=--auto-abstract-gas +auto_abstract= +bug_report=--bug-report +bug_report= +use_booster=--use-booster +# use_booster= +state_diff="./snapshots/state-diff/Kontrol-Deploy.json" + +############# +# RUN TESTS # +############# +conditionally_start_docker + +kontrol_build +kontrol_prove + +dump_log_results + +if [ "$LOCAL" == false ]; then + notif "Stopping docker container" + clean_docker +fi + +notif "DONE" diff --git a/packages/contracts-bedrock/test/DeployerWhitelist.t.sol b/packages/contracts-bedrock/test/legacy/DeployerWhitelist.t.sol similarity index 83% rename from packages/contracts-bedrock/test/DeployerWhitelist.t.sol rename to packages/contracts-bedrock/test/legacy/DeployerWhitelist.t.sol index a3096fd373f8..19dc879d44a2 100644 --- a/packages/contracts-bedrock/test/DeployerWhitelist.t.sol +++ b/packages/contracts-bedrock/test/legacy/DeployerWhitelist.t.sol @@ -2,16 +2,16 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; // Target contract import { DeployerWhitelist } from "src/legacy/DeployerWhitelist.sol"; -contract DeployerWhitelist_Test is CommonTest { +contract DeployerWhitelist_Test is Test { DeployerWhitelist list; /// @dev Sets up the test suite. - function setUp() public virtual override { + function setUp() public { list = new DeployerWhitelist(); } diff --git a/packages/contracts-bedrock/test/L1BlockNumber.t.sol b/packages/contracts-bedrock/test/legacy/L1BlockNumber.t.sol similarity index 100% rename from packages/contracts-bedrock/test/L1BlockNumber.t.sol rename to packages/contracts-bedrock/test/legacy/L1BlockNumber.t.sol diff --git a/packages/contracts-bedrock/test/legacy/LegacyMessagePasser.t.sol b/packages/contracts-bedrock/test/legacy/LegacyMessagePasser.t.sol new file mode 100644 index 000000000000..39eb479a3ac0 --- /dev/null +++ b/packages/contracts-bedrock/test/legacy/LegacyMessagePasser.t.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; + +contract LegacyMessagePasser_Test is CommonTest { + /// @dev Tests that `passMessageToL1` succeeds. + function test_passMessageToL1_succeeds() external { + vm.prank(alice); + legacyMessagePasser.passMessageToL1(hex"ff"); + assert(legacyMessagePasser.sentMessages(keccak256(abi.encodePacked(hex"ff", alice)))); + } +} diff --git a/packages/contracts-bedrock/test/ResolvedDelegateProxy.t.sol b/packages/contracts-bedrock/test/legacy/ResolvedDelegateProxy.t.sol similarity index 100% rename from packages/contracts-bedrock/test/ResolvedDelegateProxy.t.sol rename to packages/contracts-bedrock/test/legacy/ResolvedDelegateProxy.t.sol diff --git a/packages/contracts-bedrock/test/Bytes.t.sol b/packages/contracts-bedrock/test/libraries/Bytes.t.sol similarity index 100% rename from packages/contracts-bedrock/test/Bytes.t.sol rename to packages/contracts-bedrock/test/libraries/Bytes.t.sol diff --git a/packages/contracts-bedrock/test/Clones.t.sol b/packages/contracts-bedrock/test/libraries/Clone.t.sol similarity index 100% rename from packages/contracts-bedrock/test/Clones.t.sol rename to packages/contracts-bedrock/test/libraries/Clone.t.sol diff --git a/packages/contracts-bedrock/test/Constants.t.sol b/packages/contracts-bedrock/test/libraries/Constants.t.sol similarity index 100% rename from packages/contracts-bedrock/test/Constants.t.sol rename to packages/contracts-bedrock/test/libraries/Constants.t.sol diff --git a/packages/contracts-bedrock/test/Encoding.t.sol b/packages/contracts-bedrock/test/libraries/Encoding.t.sol similarity index 98% rename from packages/contracts-bedrock/test/Encoding.t.sol rename to packages/contracts-bedrock/test/libraries/Encoding.t.sol index 14ac3c81a0f7..35e9300f834e 100644 --- a/packages/contracts-bedrock/test/Encoding.t.sol +++ b/packages/contracts-bedrock/test/libraries/Encoding.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; diff --git a/packages/contracts-bedrock/test/Hashing.t.sol b/packages/contracts-bedrock/test/libraries/Hashing.t.sol similarity index 98% rename from packages/contracts-bedrock/test/Hashing.t.sol rename to packages/contracts-bedrock/test/libraries/Hashing.t.sol index fc79c24422bd..98fa7ae485a0 100644 --- a/packages/contracts-bedrock/test/Hashing.t.sol +++ b/packages/contracts-bedrock/test/libraries/Hashing.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; diff --git a/packages/contracts-bedrock/test/SafeCall.t.sol b/packages/contracts-bedrock/test/libraries/SafeCall.t.sol similarity index 92% rename from packages/contracts-bedrock/test/SafeCall.t.sol rename to packages/contracts-bedrock/test/libraries/SafeCall.t.sol index 550e7dd982b4..e3a9e05fdbb2 100644 --- a/packages/contracts-bedrock/test/SafeCall.t.sol +++ b/packages/contracts-bedrock/test/libraries/SafeCall.t.sol @@ -2,18 +2,18 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; // Target contract import { SafeCall } from "src/libraries/SafeCall.sol"; -contract SafeCall_Test is CommonTest { +contract SafeCall_Test is Test { /// @dev Tests that the `send` function succeeds. function testFuzz_send_succeeds(address from, address to, uint256 gas, uint64 value) external { vm.assume(from.balance == 0); vm.assume(to.balance == 0); // no precompiles (mainnet) - assumeNoPrecompiles(to, 1); + assumeNotPrecompile(to); // don't call the vm vm.assume(to != address(vm)); vm.assume(from != address(vm)); @@ -21,8 +21,7 @@ contract SafeCall_Test is CommonTest { vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67)); // don't call the create2 deployer vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C)); - // don't call the ffi interface - vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f)); + vm.assume(to != address(this)); assertEq(from.balance, 0, "from balance is 0"); vm.deal(from, value); @@ -48,7 +47,7 @@ contract SafeCall_Test is CommonTest { vm.assume(from.balance == 0); vm.assume(to.balance == 0); // no precompiles (mainnet) - assumeNoPrecompiles(to, 1); + assumeNotPrecompile(to); // don't call the vm vm.assume(to != address(vm)); vm.assume(from != address(vm)); @@ -56,8 +55,7 @@ contract SafeCall_Test is CommonTest { vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67)); // don't call the create2 deployer vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C)); - // don't call the ffi interface - vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f)); + vm.assume(to != address(this)); assertEq(from.balance, 0, "from balance is 0"); vm.deal(from, value); @@ -91,7 +89,7 @@ contract SafeCall_Test is CommonTest { vm.assume(from.balance == 0); vm.assume(to.balance == 0); // no precompiles (mainnet) - assumeNoPrecompiles(to, 1); + assumeNotPrecompile(to); // don't call the vm vm.assume(to != address(vm)); vm.assume(from != address(vm)); @@ -99,8 +97,7 @@ contract SafeCall_Test is CommonTest { vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67)); // don't call the create2 deployer vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C)); - // don't call the FFIInterface - vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f)); + vm.assume(to != address(this)); assertEq(from.balance, 0, "from balance is 0"); vm.deal(from, value); diff --git a/packages/contracts-bedrock/test/libraries/Storage.t.sol b/packages/contracts-bedrock/test/libraries/Storage.t.sol new file mode 100644 index 000000000000..86a8d6b0ff7f --- /dev/null +++ b/packages/contracts-bedrock/test/libraries/Storage.t.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Target contract +import { Storage } from "src/libraries/Storage.sol"; +import { StorageSetter } from "src/universal/StorageSetter.sol"; +import { Test } from "forge-std/Test.sol"; + +/// @title Storage_Roundtrip_Test +/// @notice Tests the storage setting and getting through the StorageSetter contract. +/// This contract simply wraps the Storage library, this is required as to +/// not poison the storage of the `Test` contract. +contract Storage_Roundtrip_Test is Test { + StorageSetter setter; + + /// @notice A set of storage slots to pass to `setBytes32`. + StorageSetter.Slot[] slots; + /// @notice Used to deduplicate slots passed to `setBytes32`. + mapping(bytes32 => bool) keys; + + function setUp() external { + setter = new StorageSetter(); + } + + function test_setGetUint_succeeds(bytes32 slot, uint256 num) external { + setter.setUint(slot, num); + assertEq(setter.getUint(slot), num); + assertEq(num, uint256(vm.load(address(setter), slot))); + } + + function test_setGetAddress_succeeds(bytes32 slot, address addr) external { + setter.setAddress(slot, addr); + assertEq(setter.getAddress(slot), addr); + assertEq(addr, address(uint160(uint256(vm.load(address(setter), slot))))); + } + + function test_setGetBytes32_succeeds(bytes32 slot, bytes32 hash) external { + setter.setBytes32(slot, hash); + assertEq(setter.getBytes32(slot), hash); + assertEq(hash, vm.load(address(setter), slot)); + } + + function test_setGetBool_succeeds(bytes32 slot, bool value) external { + setter.setBool(slot, value); + assertEq(setter.getBool(slot), value); + assertEq(value, vm.load(address(setter), slot) == bytes32(uint256(1))); + } + + /// @dev All keys must be unique in the input so deduplication is required. + function testFuzz_setGetBytes32Multi_succeeds(StorageSetter.Slot[] calldata _slots) external { + for (uint256 i; i < _slots.length; i++) { + if (keys[_slots[i].key]) { + continue; + } + slots.push(_slots[i]); + keys[_slots[i].key] = true; + } + + setter.setBytes32(slots); + for (uint256 i; i < slots.length; i++) { + assertEq(setter.getBytes32(slots[i].key), slots[i].value); + assertEq(slots[i].value, vm.load(address(setter), slots[i].key)); + } + } +} diff --git a/packages/contracts-bedrock/test/RLPReader.t.sol b/packages/contracts-bedrock/test/libraries/rlp/RLPReader.t.sol similarity index 98% rename from packages/contracts-bedrock/test/RLPReader.t.sol rename to packages/contracts-bedrock/test/libraries/rlp/RLPReader.t.sol index 17fe69c817c0..7d4cf189fbe9 100644 --- a/packages/contracts-bedrock/test/RLPReader.t.sol +++ b/packages/contracts-bedrock/test/libraries/rlp/RLPReader.t.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.15; import { stdError } from "forge-std/Test.sol"; -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; import { RLPReader } from "src/libraries/rlp/RLPReader.sol"; -contract RLPReader_readBytes_Test is CommonTest { +contract RLPReader_readBytes_Test is Test { function test_readBytes_bytestring00_succeeds() external { assertEq(RLPReader.readBytes(hex"00"), hex"00"); } @@ -44,7 +44,7 @@ contract RLPReader_readBytes_Test is CommonTest { } } -contract RLPReader_readList_Test is CommonTest { +contract RLPReader_readList_Test is Test { function test_readList_empty_succeeds() external { RLPReader.RLPItem[] memory list = RLPReader.readList(hex"c0"); assertEq(list.length, 0); diff --git a/packages/contracts-bedrock/test/RLPWriter.t.sol b/packages/contracts-bedrock/test/libraries/rlp/RLPWriter.t.sol similarity index 98% rename from packages/contracts-bedrock/test/RLPWriter.t.sol rename to packages/contracts-bedrock/test/libraries/rlp/RLPWriter.t.sol index b1735578ad44..86faffd05fc5 100644 --- a/packages/contracts-bedrock/test/RLPWriter.t.sol +++ b/packages/contracts-bedrock/test/libraries/rlp/RLPWriter.t.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.15; import { RLPWriter } from "src/libraries/rlp/RLPWriter.sol"; -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; -contract RLPWriter_writeString_Test is CommonTest { +contract RLPWriter_writeString_Test is Test { function test_writeString_empty_succeeds() external { assertEq(RLPWriter.writeString(""), hex"80"); } @@ -49,7 +49,7 @@ contract RLPWriter_writeString_Test is CommonTest { } } -contract RLPWriter_writeUint_Test is CommonTest { +contract RLPWriter_writeUint_Test is Test { function test_writeUint_zero_succeeds() external { assertEq(RLPWriter.writeUint(0x0), hex"80"); } @@ -83,7 +83,7 @@ contract RLPWriter_writeUint_Test is CommonTest { } } -contract RLPWriter_writeList_Test is CommonTest { +contract RLPWriter_writeList_Test is Test { function test_writeList_empty_succeeds() external { assertEq(RLPWriter.writeList(new bytes[](0)), hex"c0"); } diff --git a/packages/contracts-bedrock/test/MerkleTrie.t.sol b/packages/contracts-bedrock/test/libraries/trie/MerkleTrie.t.sol similarity index 97% rename from packages/contracts-bedrock/test/MerkleTrie.t.sol rename to packages/contracts-bedrock/test/libraries/trie/MerkleTrie.t.sol index 59673f06e2ae..b989f513dc4f 100644 --- a/packages/contracts-bedrock/test/MerkleTrie.t.sol +++ b/packages/contracts-bedrock/test/libraries/trie/MerkleTrie.t.sol @@ -1,10 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; import { MerkleTrie } from "src/libraries/trie/MerkleTrie.sol"; +import { FFIInterface } from "test/setup/FFIInterface.sol"; + +contract MerkleTrie_get_Test is Test { + FFIInterface constant ffi = FFIInterface(address(uint160(uint256(keccak256(abi.encode("optimism.ffi")))))); + + function setUp() public { + vm.etch(address(ffi), vm.getDeployedCode("FFIInterface.sol:FFIInterface")); + vm.label(address(ffi), "FFIInterface"); + } -contract MerkleTrie_get_Test is CommonTest { function test_get_validProof1_succeeds() external { bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f; bytes memory key = hex"6b6579326262"; diff --git a/packages/contracts-bedrock/test/mocks/AlphabetVM.sol b/packages/contracts-bedrock/test/mocks/AlphabetVM.sol new file mode 100644 index 000000000000..e7488f5384ec --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/AlphabetVM.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; +import { PreimageOracle, PreimageKeyLib } from "src/cannon/PreimageOracle.sol"; +import "src/libraries/DisputeTypes.sol"; + +/// @title AlphabetVM +/// @dev A mock VM for the purpose of testing the dispute game infrastructure. Note that this only works +/// for games with an execution trace subgame max depth of 3 (8 instructions per subgame). +contract AlphabetVM is IBigStepper { + Claim internal immutable ABSOLUTE_PRESTATE; + IPreimageOracle public oracle; + + constructor(Claim _absolutePrestate, PreimageOracle _oracle) { + ABSOLUTE_PRESTATE = _absolutePrestate; + oracle = _oracle; + } + + /// @inheritdoc IBigStepper + function step( + bytes calldata _stateData, + bytes calldata, + bytes32 _localContext + ) + external + view + returns (bytes32 postState_) + { + uint256 traceIndex; + uint256 claim; + if ((keccak256(_stateData) << 8) == (Claim.unwrap(ABSOLUTE_PRESTATE) << 8)) { + // If the state data is empty, then the absolute prestate is the claim. + (bytes32 dat,) = oracle.readPreimage( + PreimageKeyLib.localizeIdent(LocalPreimageKey.DISPUTED_L2_BLOCK_NUMBER, _localContext), 0 + ); + uint256 startingL2BlockNumber = ((uint256(dat) >> 128) & 0xFFFFFFFF) - 1; + traceIndex = startingL2BlockNumber << 4; + (uint256 absolutePrestateClaim) = abi.decode(_stateData, (uint256)); + claim = absolutePrestateClaim + traceIndex; + } else { + // Otherwise, decode the state data. + (traceIndex, claim) = abi.decode(_stateData, (uint256, uint256)); + traceIndex++; + claim++; + } + + // STF: n -> n + 1 + postState_ = keccak256(abi.encode(traceIndex, claim)); + assembly { + postState_ := or(and(postState_, not(shl(248, 0xFF))), shl(248, 1)) + } + } +} diff --git a/packages/contracts-bedrock/test/mocks/Callers.sol b/packages/contracts-bedrock/test/mocks/Callers.sol new file mode 100644 index 000000000000..aa7a2dc8b228 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/Callers.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract CallRecorder { + struct CallInfo { + address sender; + bytes data; + uint256 gas; + uint256 value; + } + + CallInfo public lastCall; + + function record() public payable { + lastCall.sender = msg.sender; + lastCall.data = msg.data; + lastCall.gas = gasleft(); + lastCall.value = msg.value; + } +} + +/// @dev Useful for testing reentrancy guards +contract CallerCaller { + event WhatHappened(bool success, bytes returndata); + + fallback() external { + (bool success, bytes memory returndata) = msg.sender.call(msg.data); + emit WhatHappened(success, returndata); + assembly { + switch success + case 0 { revert(add(returndata, 0x20), mload(returndata)) } + default { return(add(returndata, 0x20), mload(returndata)) } + } + } +} + +/// @dev Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard. +contract ConfigurableCaller { + bool doRevert = true; + address target; + bytes payload; + + event WhatHappened(bool success, bytes returndata); + + /// @notice Call the configured target with the configured payload OR revert. + function call() external { + if (doRevert) { + revert("ConfigurableCaller: revert"); + } else { + (bool success, bytes memory returndata) = address(target).call(payload); + emit WhatHappened(success, returndata); + assembly { + switch success + case 0 { revert(add(returndata, 0x20), mload(returndata)) } + default { return(add(returndata, 0x20), mload(returndata)) } + } + } + } + + /// @notice Set whether or not to have `call` revert. + function setDoRevert(bool _doRevert) external { + doRevert = _doRevert; + } + + /// @notice Set the target for the call made in `call`. + function setTarget(address _target) external { + target = _target; + } + + /// @notice Set the payload for the call made in `call`. + function setPayload(bytes calldata _payload) external { + payload = _payload; + } + + /// @notice Fallback function that reverts if `doRevert` is true. + /// Otherwise, it does nothing. + fallback() external { + if (doRevert) { + revert("ConfigurableCaller: revert"); + } + } +} + +/// @dev Any call will revert +contract Reverter { + function doRevert() public pure { + revert("Reverter reverted"); + } + + fallback() external { + revert(); + } +} diff --git a/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol b/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol new file mode 100644 index 000000000000..a9330890d112 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Vm } from "forge-std/Vm.sol"; + +/// @title EIP1967Helper +/// @dev Testing library to help with reading EIP 1967 variables from state +library EIP1967Helper { + /// @notice The storage slot that holds the address of a proxy implementation. + /// @dev `bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)` + bytes32 internal constant PROXY_IMPLEMENTATION_ADDRESS = + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + + /// @notice The storage slot that holds the address of the owner. + /// @dev `bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)` + bytes32 internal constant PROXY_OWNER_ADDRESS = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + + Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + function getAdmin(address _proxy) internal view returns (address) { + return address(uint160(uint256(vm.load(address(_proxy), PROXY_OWNER_ADDRESS)))); + } + + function getImplementation(address _proxy) internal view returns (address) { + return address(uint160(uint256(vm.load(address(_proxy), PROXY_IMPLEMENTATION_ADDRESS)))); + } +} diff --git a/packages/contracts-bedrock/test/mocks/FaucetHelper.sol b/packages/contracts-bedrock/test/mocks/FaucetHelper.sol new file mode 100644 index 000000000000..e9023e2d93e8 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/FaucetHelper.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ECDSAUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol"; +import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; + +/// @notice Simple helper contract that helps with testing the Faucet contract. +contract FaucetHelper { + /// @notice EIP712 typehash for the Proof type. + bytes32 public constant PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)"); + + /// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature. + bytes32 public constant EIP712_DOMAIN_TYPEHASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + + /// @notice Keeps track of current nonce to generate new nonces for each drip. + uint256 public currentNonce; + + /// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use + /// pseudorandom nonces. + /// @return Nonce that should be used as part of drip parameters. + function consumeNonce() public returns (bytes32) { + return bytes32(keccak256(abi.encode(currentNonce++))); + } + + /// @notice Returns the hash of the struct Proof. + /// @param _proof Proof struct to hash. + /// @return EIP-712 typed struct hash. + function getProofStructHash(AdminFaucetAuthModule.Proof memory _proof) public pure returns (bytes32) { + return keccak256(abi.encode(PROOF_TYPEHASH, _proof.recipient, _proof.nonce, _proof.id)); + } + + /// @notice Computes the EIP712 digest with the given domain parameters. + /// Used for testing that different domain parameters fail. + /// @param _proof Proof struct to hash. + /// @param _name Contract name to use in the EIP712 domain. + /// @param _version Contract version to use in the EIP712 domain. + /// @param _chainid Chain ID to use in the EIP712 domain. + /// @param _verifyingContract Address to use in the EIP712 domain. + /// @param _verifyingContract Address to use in the EIP712 domain. + /// @param _verifyingContract Address to use in the EIP712 domain. + /// @return EIP-712 compatible digest. + function getDigestWithEIP712Domain( + AdminFaucetAuthModule.Proof memory _proof, + bytes memory _name, + bytes memory _version, + uint256 _chainid, + address _verifyingContract + ) + public + pure + returns (bytes32) + { + bytes32 domainSeparator = keccak256( + abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract) + ); + return ECDSAUpgradeable.toTypedDataHash(domainSeparator, getProofStructHash(_proof)); + } +} diff --git a/packages/contracts-bedrock/test/mocks/NextImpl.sol b/packages/contracts-bedrock/test/mocks/NextImpl.sol new file mode 100644 index 000000000000..3d857cfdc2d0 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/NextImpl.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; + +/// @title NextImpl +/// @dev Used for testing a future upgrade beyond the current implementations. +// We include some variables so that we can sanity check accessing storage values after an upgrade. +contract NextImpl is Initializable { + // Initializable occupies the zero-th slot. + bytes32 slot1; + bytes32[19] __gap; + bytes32 slot21; + bytes32 public constant slot21Init = bytes32(hex"1337"); + + function initialize(uint8 _init) public reinitializer(_init) { + // Slot21 is unused by an of our upgradeable contracts. + // This is used to verify that we can access this value after an upgrade. + slot21 = slot21Init; + } +} diff --git a/packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol b/packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol new file mode 100644 index 000000000000..ebc2289f9c10 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; + +/// @notice Simple helper contract that helps with testing flow and signature for +/// OptimistInviter contract. Made this a separate contract instead of including +/// in OptimistInviter.t.sol for reusability. +contract OptimistInviterHelper { + /// @notice EIP712 typehash for the ClaimableInvite type. + bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = keccak256("ClaimableInvite(address issuer,bytes32 nonce)"); + + /// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature. + bytes32 public constant EIP712_DOMAIN_TYPEHASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + + /// @notice Address of OptimistInviter contract we are testing. + OptimistInviter public optimistInviter; + + /// @notice OptimistInviter contract name. Used to construct the EIP-712 domain. + string public name; + + /// @notice Keeps track of current nonce to generate new nonces for each invite. + uint256 public currentNonce; + + constructor(OptimistInviter _optimistInviter, string memory _name) { + optimistInviter = _optimistInviter; + name = _name; + } + + /// @notice Returns the hash of the struct ClaimableInvite. + /// @param _claimableInvite ClaimableInvite struct to hash. + /// @return EIP-712 typed struct hash. + function getClaimableInviteStructHash(OptimistInviter.ClaimableInvite memory _claimableInvite) + public + pure + returns (bytes32) + { + return keccak256(abi.encode(CLAIMABLE_INVITE_TYPEHASH, _claimableInvite.issuer, _claimableInvite.nonce)); + } + + /// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use + /// pseudorandom nonces. + /// @return Nonce that should be used as part of ClaimableInvite. + function consumeNonce() public returns (bytes32) { + return bytes32(keccak256(abi.encode(currentNonce++))); + } + + /// @notice Returns a ClaimableInvite with the issuer and current nonce. + /// @param _issuer Issuer to include in the ClaimableInvite. + /// @return ClaimableInvite that can be hashed & signed. + function getClaimableInviteWithNewNonce(address _issuer) public returns (OptimistInviter.ClaimableInvite memory) { + return OptimistInviter.ClaimableInvite(_issuer, consumeNonce()); + } + + /// @notice Computes the EIP712 digest with default correct parameters. + /// @param _claimableInvite ClaimableInvite struct to hash. + /// @return EIP-712 compatible digest. + function getDigest(OptimistInviter.ClaimableInvite calldata _claimableInvite) public view returns (bytes32) { + return getDigestWithEIP712Domain( + _claimableInvite, + bytes(name), + bytes(optimistInviter.EIP712_VERSION()), + block.chainid, + address(optimistInviter) + ); + } + + /// @notice Computes the EIP712 digest with the given domain parameters. + /// Used for testing that different domain parameters fail. + /// @param _claimableInvite ClaimableInvite struct to hash. + /// @param _name Contract name to use in the EIP712 domain. + /// @param _version Contract version to use in the EIP712 domain. + /// @param _chainid Chain ID to use in the EIP712 domain. + /// @param _verifyingContract Address to use in the EIP712 domain. + /// @return EIP-712 compatible digest. + function getDigestWithEIP712Domain( + OptimistInviter.ClaimableInvite calldata _claimableInvite, + bytes memory _name, + bytes memory _version, + uint256 _chainid, + address _verifyingContract + ) + public + pure + returns (bytes32) + { + bytes32 domainSeparator = keccak256( + abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract) + ); + return ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite)); + } +} diff --git a/packages/contracts-bedrock/test/mocks/SimpleStorage.sol b/packages/contracts-bedrock/test/mocks/SimpleStorage.sol new file mode 100644 index 000000000000..218505b24c05 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/SimpleStorage.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract SimpleStorage { + mapping(bytes32 => bytes32) public db; + + function set(bytes32 _key, bytes32 _value) public payable { + db[_key] = _value; + } + + function get(bytes32 _key) public view returns (bytes32) { + return db[_key]; + } +} diff --git a/packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol b/packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol new file mode 100644 index 000000000000..c04ed608b7d7 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol"; +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; + +/// @notice Simple ERC1271 wallet that can be used to test the ERC1271 signature checker. +/// @notice https://github.com/OpenZeppelin/openzeppelin-contracts/ +/// blob/master/contracts/mocks/ERC1271WalletMock.sol +contract TestERC1271Wallet is Ownable, IERC1271 { + constructor(address originalOwner) { + transferOwnership(originalOwner); + } + + function isValidSignature(bytes32 hash, bytes memory signature) public view override returns (bytes4 magicValue) { + return ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0); + } +} diff --git a/packages/contracts-bedrock/test/mocks/TestERC20.sol b/packages/contracts-bedrock/test/mocks/TestERC20.sol new file mode 100644 index 000000000000..0c6603ce401f --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/TestERC20.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol"; + +contract TestERC20 is ERC20 { + constructor() ERC20("TEST", "TST", 18) { } + + function mint(address to, uint256 value) public { + _mint(to, value); + } +} diff --git a/packages/contracts-bedrock/test/mocks/TestERC721.sol b/packages/contracts-bedrock/test/mocks/TestERC721.sol new file mode 100644 index 000000000000..294b4a93c7e5 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/TestERC721.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ERC721 } from "@rari-capital/solmate/src/tokens/ERC721.sol"; + +contract TestERC721 is ERC721 { + constructor() ERC721("TEST", "TST") { } + + function mint(address to, uint256 tokenId) public { + _mint(to, tokenId); + } + + function tokenURI(uint256) public pure virtual override returns (string memory) { } +} diff --git a/packages/contracts-bedrock/test/mocks/block.json b/packages/contracts-bedrock/test/mocks/block.json new file mode 100644 index 000000000000..7de13ed6135a --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/block.json @@ -0,0 +1,27 @@ +{ + "hash": "0xfd3c5e25a80f54a53c58bd3ad8c076dc1c0cdbd44ec2164d2d2b8cc50481cb78", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "miner": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "number": "0x0", + "gasUsed": "0x0", + "gasLimit": "0x1c9c380", + "extraData": "0x", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "0x654caabb", + "difficulty": "0x0", + "totalDifficulty": "0x0", + "sealFields": [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000" + ], + "uncles": [], + "transactions": [], + "size": "0x202", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x3b9aca00" +} diff --git a/packages/contracts-bedrock/test/AssetReceiver.t.sol b/packages/contracts-bedrock/test/periphery/AssetReceiver.t.sol similarity index 93% rename from packages/contracts-bedrock/test/AssetReceiver.t.sol rename to packages/contracts-bedrock/test/periphery/AssetReceiver.t.sol index 87c14e2608dd..d2a6b938f714 100644 --- a/packages/contracts-bedrock/test/AssetReceiver.t.sol +++ b/packages/contracts-bedrock/test/periphery/AssetReceiver.t.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { TestERC20 } from "test/Helpers.sol"; -import { TestERC721 } from "test/Helpers.sol"; +import { TestERC20 } from "test/mocks/TestERC20.sol"; +import { TestERC721 } from "test/mocks/TestERC721.sol"; import { AssetReceiver } from "src/periphery/AssetReceiver.sol"; contract AssetReceiver_Initializer is Test { @@ -53,7 +53,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer { // Check that contract balance is 0 initially assertEq(address(assetReceiver).balance, 0); - vm.expectEmit(true, true, true, true, address(assetReceiver)); + vm.expectEmit(address(assetReceiver)); emit ReceivedETH(alice, 100); // Send funds vm.prank(alice); @@ -75,7 +75,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer { assertEq(address(alice).balance, 1 ether); - vm.expectEmit(true, true, true, true, address(assetReceiver)); + vm.expectEmit(address(assetReceiver)); emit WithdrewETH(alice, alice, 1 ether); // call withdrawETH @@ -103,7 +103,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer { assertEq(address(alice).balance, 1 ether); - vm.expectEmit(true, true, true, true, address(assetReceiver)); + vm.expectEmit(address(assetReceiver)); emit WithdrewETH(alice, alice, 0.5 ether); // call withdrawETH @@ -131,7 +131,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer { assertEq(testERC20.balanceOf(address(assetReceiver)), 100_000); assertEq(testERC20.balanceOf(alice), 0); - vm.expectEmit(true, true, true, true, address(assetReceiver)); + vm.expectEmit(address(assetReceiver)); emit WithdrewERC20(alice, alice, address(testERC20), 100_000); // call withdrawERC20 @@ -159,7 +159,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer { assertEq(testERC20.balanceOf(address(assetReceiver)), 100_000); assertEq(testERC20.balanceOf(alice), 0); - vm.expectEmit(true, true, true, true, address(assetReceiver)); + vm.expectEmit(address(assetReceiver)); emit WithdrewERC20(alice, alice, address(testERC20), 50_000); // call withdrawERC20 @@ -188,7 +188,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer { testERC721.transferFrom(alice, address(assetReceiver), DEFAULT_TOKEN_ID); assertEq(testERC721.ownerOf(DEFAULT_TOKEN_ID), address(assetReceiver)); - vm.expectEmit(true, true, true, true, address(assetReceiver)); + vm.expectEmit(address(assetReceiver)); emit WithdrewERC721(alice, alice, address(testERC721), DEFAULT_TOKEN_ID); // Call withdrawERC721 diff --git a/packages/contracts-bedrock/test/Transactor.t.sol b/packages/contracts-bedrock/test/periphery/Transactor.t.sol similarity index 96% rename from packages/contracts-bedrock/test/Transactor.t.sol rename to packages/contracts-bedrock/test/periphery/Transactor.t.sol index 70c02e53d813..af6ce0fba1ca 100644 --- a/packages/contracts-bedrock/test/Transactor.t.sol +++ b/packages/contracts-bedrock/test/periphery/Transactor.t.sol @@ -3,8 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { CallRecorder } from "test/Helpers.sol"; -import { Reverter } from "test/Helpers.sol"; +import { CallRecorder, Reverter } from "test/mocks/Callers.sol"; import { Transactor } from "src/periphery/Transactor.sol"; contract Transactor_Initializer is Test { diff --git a/packages/contracts-bedrock/test/TransferOnion.t.sol b/packages/contracts-bedrock/test/periphery/TransferOnion.t.sol similarity index 100% rename from packages/contracts-bedrock/test/TransferOnion.t.sol rename to packages/contracts-bedrock/test/periphery/TransferOnion.t.sol diff --git a/packages/contracts-bedrock/test/Drippie.t.sol b/packages/contracts-bedrock/test/periphery/drippie/Drippie.t.sol similarity index 96% rename from packages/contracts-bedrock/test/Drippie.t.sol rename to packages/contracts-bedrock/test/periphery/drippie/Drippie.t.sol index 758011448608..748abdf309d8 100644 --- a/packages/contracts-bedrock/test/Drippie.t.sol +++ b/packages/contracts-bedrock/test/periphery/drippie/Drippie.t.sol @@ -5,7 +5,7 @@ import { Test } from "forge-std/Test.sol"; import { Drippie } from "src/periphery/drippie/Drippie.sol"; import { IDripCheck } from "src/periphery/drippie/IDripCheck.sol"; import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol"; -import { SimpleStorage } from "test/Helpers.sol"; +import { SimpleStorage } from "test/mocks/SimpleStorage.sol"; /// @title TestDrippie /// @notice This is a wrapper contract around Drippie used for testing. @@ -116,7 +116,7 @@ contract Drippie_Test is Test { /// @notice Creates a drip and asserts that it was configured as expected. function test_create_succeeds() external { Drippie.DripConfig memory cfg = _defaultConfig(); - vm.expectEmit(true, true, true, true); + vm.expectEmit(address(drippie)); emit DripCreated(dripName, dripName, cfg); if (cfg.reentrant) { @@ -170,7 +170,7 @@ contract Drippie_Test is Test { /// @notice The owner should be able to set the status of the drip. function test_set_status_succeeds() external { - vm.expectEmit(true, true, true, true); + vm.expectEmit(address(drippie)); emit DripCreated(dripName, dripName, _defaultConfig()); _createDefaultDrip(dripName); @@ -183,7 +183,7 @@ contract Drippie_Test is Test { vm.prank(owner); - vm.expectEmit(true, true, true, true); + vm.expectEmit(address(drippie)); emit DripStatusUpdated({ nameref: dripName, name: dripName, status: Drippie.DripStatus.ACTIVE }); drippie.status(dripName, Drippie.DripStatus.ACTIVE); @@ -195,7 +195,7 @@ contract Drippie_Test is Test { vm.prank(owner); - vm.expectEmit(true, true, true, true); + vm.expectEmit(address(drippie)); emit DripStatusUpdated({ nameref: dripName, name: dripName, status: Drippie.DripStatus.PAUSED }); drippie.status(dripName, Drippie.DripStatus.PAUSED); @@ -238,7 +238,7 @@ contract Drippie_Test is Test { vm.prank(owner); - vm.expectEmit(true, true, true, true); + vm.expectEmit(address(drippie)); emit DripStatusUpdated({ nameref: dripName, name: dripName, status: Drippie.DripStatus.ARCHIVED }); drippie.status(dripName, Drippie.DripStatus.ARCHIVED); @@ -321,7 +321,7 @@ contract Drippie_Test is Test { _warpToExecutable(dripName); - vm.expectEmit(true, true, true, true); + vm.expectEmit(address(drippie)); emit DripExecuted({ nameref: dripName, name: dripName, executor: address(this), timestamp: block.timestamp }); Drippie.DripAction[] memory actions = drippie.dripConfigActions(dripName); @@ -358,7 +358,7 @@ contract Drippie_Test is Test { vm.expectCall(address(simpleStorage), 0, abi.encodeWithSelector(SimpleStorage.set.selector, key, value)); - vm.expectEmit(true, true, true, true, address(drippie)); + vm.expectEmit(address(drippie)); emit DripExecuted(dripName, dripName, address(this), block.timestamp); drippie.drip(dripName); @@ -402,7 +402,7 @@ contract Drippie_Test is Test { vm.expectCall(address(simpleStorage), 0, abi.encodeWithSelector(SimpleStorage.set.selector, keyTwo, valueTwo)); - vm.expectEmit(true, true, true, true, address(drippie)); + vm.expectEmit(address(drippie)); emit DripExecuted(dripName, dripName, address(this), block.timestamp); drippie.drip(dripName); @@ -434,7 +434,7 @@ contract Drippie_Test is Test { _warpToExecutable(dripName); - vm.expectEmit(true, true, true, true, address(drippie)); + vm.expectEmit(address(drippie)); emit DripExecuted({ nameref: dripName, name: dripName, executor: address(this), timestamp: block.timestamp }); drippie.drip(dripName); @@ -472,7 +472,7 @@ contract Drippie_Test is Test { cfg.interval = 0; vm.prank(owner); - vm.expectEmit(true, true, true, true, address(drippie)); + vm.expectEmit(address(drippie)); emit DripCreated(dripName, dripName, cfg); drippie.create(dripName, cfg); diff --git a/packages/contracts-bedrock/test/CheckBalanceLow.t.sol b/packages/contracts-bedrock/test/periphery/drippie/dripchecks/CheckBalanceLow.t.sol similarity index 100% rename from packages/contracts-bedrock/test/CheckBalanceLow.t.sol rename to packages/contracts-bedrock/test/periphery/drippie/dripchecks/CheckBalanceLow.t.sol diff --git a/packages/contracts-bedrock/test/CheckGelatoLow.t.sol b/packages/contracts-bedrock/test/periphery/drippie/dripchecks/CheckGelatoLow.t.sol similarity index 96% rename from packages/contracts-bedrock/test/CheckGelatoLow.t.sol rename to packages/contracts-bedrock/test/periphery/drippie/dripchecks/CheckGelatoLow.t.sol index fb213742c917..b8a25a72e3b3 100644 --- a/packages/contracts-bedrock/test/CheckGelatoLow.t.sol +++ b/packages/contracts-bedrock/test/periphery/drippie/dripchecks/CheckGelatoLow.t.sol @@ -20,7 +20,7 @@ contract MockGelatoTreasury is IGelatoTreasury { } /// @title CheckGelatoLowTest -/// @notice Tests the CheckBalanceHigh contract via fuzzing both the success case +/// @notice Tests the CheckGelatoLow contract via fuzzing both the success case /// and the failure case. contract CheckGelatoLowTest is Test { /// @notice An instance of the CheckGelatoLow contract. diff --git a/packages/contracts-bedrock/test/CheckTrue.t.sol b/packages/contracts-bedrock/test/periphery/drippie/dripchecks/CheckTrue.t.sol similarity index 100% rename from packages/contracts-bedrock/test/CheckTrue.t.sol rename to packages/contracts-bedrock/test/periphery/drippie/dripchecks/CheckTrue.t.sol diff --git a/packages/contracts-bedrock/test/Faucet.t.sol b/packages/contracts-bedrock/test/periphery/faucet/Faucet.t.sol similarity index 98% rename from packages/contracts-bedrock/test/Faucet.t.sol rename to packages/contracts-bedrock/test/periphery/faucet/Faucet.t.sol index 3c4da9c98798..087c8c56fca4 100644 --- a/packages/contracts-bedrock/test/Faucet.t.sol +++ b/packages/contracts-bedrock/test/periphery/faucet/Faucet.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { Faucet } from "src/periphery/faucet/Faucet.sol"; import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; -import { FaucetHelper } from "test/Helpers.sol"; +import { FaucetHelper } from "test/mocks/FaucetHelper.sol"; contract Faucet_Initializer is Test { event Drip(string indexed authModule, bytes32 indexed userId, uint256 amount, address indexed recipient); @@ -50,11 +50,7 @@ contract Faucet_Initializer is Test { vm.deal(address(faucetContractAdmin), 5 ether); vm.deal(address(nonAdmin), 5 ether); - optimistNftFam = new AdminFaucetAuthModule( - faucetAuthAdmin, - optimistNftFamName, - optimistNftFamVersion - ); + optimistNftFam = new AdminFaucetAuthModule(faucetAuthAdmin, optimistNftFamName, optimistNftFamVersion); githubFam = new AdminFaucetAuthModule(faucetAuthAdmin, githubFamName, githubFamVersion); faucetHelper = new FaucetHelper(); diff --git a/packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol b/packages/contracts-bedrock/test/periphery/faucet/authmodules/AdminFaucetAuthModule.t.sol similarity index 98% rename from packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol rename to packages/contracts-bedrock/test/periphery/faucet/authmodules/AdminFaucetAuthModule.t.sol index 340bbfe4aa83..93a10329b452 100644 --- a/packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol +++ b/packages/contracts-bedrock/test/periphery/faucet/authmodules/AdminFaucetAuthModule.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; import { Faucet } from "src/periphery/faucet/Faucet.sol"; -import { FaucetHelper } from "test/Helpers.sol"; +import { FaucetHelper } from "test/mocks/FaucetHelper.sol"; /// @title AdminFaucetAuthModuleTest /// @notice Tests the AdminFaucetAuthModule contract. diff --git a/packages/contracts-bedrock/test/AttestationStation.t.sol b/packages/contracts-bedrock/test/periphery/op-nft/AttestationStation.t.sol similarity index 100% rename from packages/contracts-bedrock/test/AttestationStation.t.sol rename to packages/contracts-bedrock/test/periphery/op-nft/AttestationStation.t.sol diff --git a/packages/contracts-bedrock/test/Optimist.t.sol b/packages/contracts-bedrock/test/periphery/op-nft/Optimist.t.sol similarity index 99% rename from packages/contracts-bedrock/test/Optimist.t.sol rename to packages/contracts-bedrock/test/periphery/op-nft/Optimist.t.sol index a7a84e2b9854..e0dcb83e7537 100644 --- a/packages/contracts-bedrock/test/Optimist.t.sol +++ b/packages/contracts-bedrock/test/periphery/op-nft/Optimist.t.sol @@ -7,7 +7,7 @@ import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol" import { Optimist } from "src/periphery/op-nft/Optimist.sol"; import { OptimistAllowlist } from "src/periphery/op-nft/OptimistAllowlist.sol"; import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; -import { OptimistInviterHelper } from "test/Helpers.sol"; +import { OptimistInviterHelper } from "test/mocks/OptimistInviterHelper.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; @@ -173,10 +173,8 @@ contract Optimist_Initializer is Test { vm.expectEmit(true, true, false, false); emit Initialized(1); - optimistInviter = new OptimistInviter({ - _inviteGranter: eve_inviteGranter, - _attestationStation: attestationStation - }); + optimistInviter = + new OptimistInviter({ _inviteGranter: eve_inviteGranter, _attestationStation: attestationStation }); optimistInviter.initialize("OptimistInviter"); diff --git a/packages/contracts-bedrock/test/OptimistAllowlist.t.sol b/packages/contracts-bedrock/test/periphery/op-nft/OptimistAllowlist.t.sol similarity index 97% rename from packages/contracts-bedrock/test/OptimistAllowlist.t.sol rename to packages/contracts-bedrock/test/periphery/op-nft/OptimistAllowlist.t.sol index d7f53ff8c23c..d4a9d1e4ae12 100644 --- a/packages/contracts-bedrock/test/OptimistAllowlist.t.sol +++ b/packages/contracts-bedrock/test/periphery/op-nft/OptimistAllowlist.t.sol @@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol"; import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; import { OptimistAllowlist } from "src/periphery/op-nft/OptimistAllowlist.sol"; import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; -import { OptimistInviterHelper } from "test/Helpers.sol"; +import { OptimistInviterHelper } from "test/mocks/OptimistInviterHelper.sol"; import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; contract OptimistAllowlist_Initializer is Test { @@ -112,10 +112,7 @@ contract OptimistAllowlist_Initializer is Test { optimistInviter.initialize("OptimistInviter"); optimistAllowlist = new OptimistAllowlist( - attestationStation, - alice_allowlistAttestor, - sally_coinbaseQuestAttestor, - address(optimistInviter) + attestationStation, alice_allowlistAttestor, sally_coinbaseQuestAttestor, address(optimistInviter) ); optimistInviterHelper = new OptimistInviterHelper(optimistInviter, "OptimistInviter"); diff --git a/packages/contracts-bedrock/test/OptimistInviter.t.sol b/packages/contracts-bedrock/test/periphery/op-nft/OptimistInviter.t.sol similarity index 99% rename from packages/contracts-bedrock/test/OptimistInviter.t.sol rename to packages/contracts-bedrock/test/periphery/op-nft/OptimistInviter.t.sol index 677dceb7d151..53d24105d122 100644 --- a/packages/contracts-bedrock/test/OptimistInviter.t.sol +++ b/packages/contracts-bedrock/test/periphery/op-nft/OptimistInviter.t.sol @@ -7,8 +7,8 @@ import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol" import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; import { Optimist } from "src/periphery/op-nft/Optimist.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { TestERC1271Wallet } from "test/Helpers.sol"; -import { OptimistInviterHelper } from "test/Helpers.sol"; +import { TestERC1271Wallet } from "test/mocks/TestERC1271Wallet.sol"; +import { OptimistInviterHelper } from "test/mocks/OptimistInviterHelper.sol"; import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; contract OptimistInviter_Initializer is Test { diff --git a/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol b/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol index a0efa0e68b26..caefc4cee1c0 100644 --- a/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol +++ b/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol @@ -162,7 +162,6 @@ contract CompatibilityFallbackHandler is DefaultCallbackHandler, ISignatureValid targetContract; calldataPayload; - // solhint-disable-next-line no-inline-assembly assembly { let internalCalldata := mload(0x40) // Store `simulateAndRevert.selector`. diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index f4ff521ff0c9..040b8e4efe64 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -2,7 +2,7 @@ pragma solidity >=0.7.0 <0.9.0; import "forge-std/Test.sol"; -import "scripts/libraries/LibSort.sol"; +import { LibSort } from "solady/utils/LibSort.sol"; import { Safe as GnosisSafe, OwnerManager, ModuleManager, GuardManager } from "safe-contracts/Safe.sol"; import { SafeProxyFactory as GnosisSafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; @@ -212,17 +212,10 @@ library SafeTestLib { address[] memory _ownersList ) internal - view - returns ( - // pure - address prevOwner_ - ) + pure + returns (address prevOwner_) { - // console.log("getPrevOwnerFromList"); - for (uint256 i = 0; i < _ownersList.length; i++) { - // console.log(i); - // console.log(_owner); - // console.log("_ownersList[i]:", _ownersList[i]); + for (uint256 i; i < _ownersList.length; i++) { if (_ownersList[i] != _owner) continue; if (i == 0) { prevOwner_ = SENTINEL_OWNERS; @@ -230,8 +223,6 @@ library SafeTestLib { } prevOwner_ = _ownersList[i - 1]; } - - console.log("prevOwner_:", prevOwner_); } /// @dev Given an array of owners to remove, this function will return an array of the previous owners @@ -250,7 +241,7 @@ library SafeTestLib { OwnerSimulator ownerSimulator = new OwnerSimulator(instance.owners, 1); prevOwners_ = new address[](_ownersToRemove.length); address[] memory currentOwners; - for (uint256 i = 0; i < _ownersToRemove.length; i++) { + for (uint256 i; i < _ownersToRemove.length; i++) { currentOwners = ownerSimulator.getOwners(); prevOwners_[i] = SafeTestLib.getPrevOwnerFromList(_ownersToRemove[i], currentOwners); diff --git a/packages/contracts-bedrock/test/setup/Bridge_Initializer.sol b/packages/contracts-bedrock/test/setup/Bridge_Initializer.sol new file mode 100644 index 000000000000..6b931712935e --- /dev/null +++ b/packages/contracts-bedrock/test/setup/Bridge_Initializer.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { CommonTest } from "test/setup/CommonTest.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; +import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol"; + +/// @title Bridge_Initializer +/// @dev This contract extends the CommonTest contract with token deployments +/// meant to be used with the bridge contracts. +contract Bridge_Initializer is CommonTest { + ERC20 L1Token; + ERC20 BadL1Token; + OptimismMintableERC20 L2Token; + LegacyMintableERC20 LegacyL2Token; + ERC20 NativeL2Token; + ERC20 BadL2Token; + OptimismMintableERC20 RemoteL1Token; + + function setUp() public virtual override { + super.setUp(); + + L1Token = new ERC20("Native L1 Token", "L1T"); + + LegacyL2Token = new LegacyMintableERC20({ + _l2Bridge: address(l2StandardBridge), + _l1Token: address(L1Token), + _name: string.concat("LegacyL2-", L1Token.name()), + _symbol: string.concat("LegacyL2-", L1Token.symbol()) + }); + vm.label(address(LegacyL2Token), "LegacyMintableERC20"); + + // Deploy the L2 ERC20 now + L2Token = OptimismMintableERC20( + l2OptimismMintableERC20Factory.createStandardL2Token( + address(L1Token), + string(abi.encodePacked("L2-", L1Token.name())), + string(abi.encodePacked("L2-", L1Token.symbol())) + ) + ); + + BadL2Token = OptimismMintableERC20( + l2OptimismMintableERC20Factory.createStandardL2Token( + address(1), + string(abi.encodePacked("L2-", L1Token.name())), + string(abi.encodePacked("L2-", L1Token.symbol())) + ) + ); + + NativeL2Token = new ERC20("Native L2 Token", "L2T"); + + RemoteL1Token = OptimismMintableERC20( + l1OptimismMintableERC20Factory.createStandardL2Token( + address(NativeL2Token), + string(abi.encodePacked("L1-", NativeL2Token.name())), + string(abi.encodePacked("L1-", NativeL2Token.symbol())) + ) + ); + + BadL1Token = OptimismMintableERC20( + l1OptimismMintableERC20Factory.createStandardL2Token( + address(1), + string(abi.encodePacked("L1-", NativeL2Token.name())), + string(abi.encodePacked("L1-", NativeL2Token.symbol())) + ) + ); + } +} diff --git a/packages/contracts-bedrock/test/setup/CommonTest.sol b/packages/contracts-bedrock/test/setup/CommonTest.sol new file mode 100644 index 000000000000..3b35bb53ebb9 --- /dev/null +++ b/packages/contracts-bedrock/test/setup/CommonTest.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test } from "forge-std/Test.sol"; +import { Setup } from "test/setup/Setup.sol"; +import { Events } from "test/setup/Events.sol"; +import { FFIInterface } from "test/setup/FFIInterface.sol"; +import "scripts/DeployConfig.s.sol"; + +/// @title CommonTest +/// @dev An extenstion to `Test` that sets up the optimism smart contracts. +contract CommonTest is Test, Setup, Events { + address alice; + address bob; + + bytes32 constant nonZeroHash = keccak256(abi.encode("NON_ZERO")); + + FFIInterface constant ffi = FFIInterface(address(uint160(uint256(keccak256(abi.encode("optimism.ffi")))))); + + bool usePlasmaOverride; + + function setUp() public virtual override { + alice = makeAddr("alice"); + bob = makeAddr("bob"); + vm.deal(alice, 10000 ether); + vm.deal(bob, 10000 ether); + + Setup.setUp(); + + // Override the plasma config after the deploy script initialized the config + if (usePlasmaOverride) { + deploy.cfg().setUsePlasma(true); + } + + vm.etch(address(ffi), vm.getDeployedCode("FFIInterface.sol:FFIInterface")); + vm.label(address(ffi), "FFIInterface"); + + // Exclude contracts for the invariant tests + excludeContract(address(ffi)); + excludeContract(address(deploy)); + excludeContract(address(deploy.cfg())); + + // Make sure the base fee is non zero + vm.fee(1 gwei); + + // Set sane initialize block numbers + vm.warp(deploy.cfg().l2OutputOracleStartingTimestamp() + 1); + vm.roll(deploy.cfg().l2OutputOracleStartingBlockNumber() + 1); + + // Deploy L1 + Setup.L1(); + // Deploy L2 + Setup.L2(); + } + + /// @dev Helper function that wraps `TransactionDeposited` event. + /// The magic `0` is the version. + function emitTransactionDeposited( + address _from, + address _to, + uint256 _mint, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + internal + { + emit TransactionDeposited(_from, _to, 0, abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)); + } + + // @dev Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output + function warpToProposeTime(uint256 _nextBlockNumber) public { + vm.warp(l2OutputOracle.computeL2Timestamp(_nextBlockNumber) + 1); + } + + /// @dev Helper function to propose an output. + function proposeAnotherOutput() public { + bytes32 proposedOutput2 = keccak256(abi.encode()); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex(); + warpToProposeTime(nextBlockNumber); + uint256 proposedNumber = l2OutputOracle.latestBlockNumber(); + + uint256 submissionInterval = deploy.cfg().l2OutputOracleSubmissionInterval(); + // Ensure the submissionInterval is enforced + assertEq(nextBlockNumber, proposedNumber + submissionInterval); + + vm.roll(nextBlockNumber + 1); + + vm.expectEmit(true, true, true, true); + emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp); + + address proposer = deploy.cfg().l2OutputOracleProposer(); + vm.prank(proposer); + l2OutputOracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0); + } + + function enableFaultProofs() public { + // Check if the system has already been deployed, based off of the heuristic that alice and bob have not been + // set by the `setUp` function yet. + if (!(alice == address(0) && bob == address(0))) { + revert("CommonTest: Cannot enable fault proofs after deployment. Consider overriding `setUp`."); + } + + // Set `useFaultProofs` to `true` in the deploy config so that the deploy script deploys the Fault Proof system. + // This directly overrides the deploy config's `useFaultProofs` value, if the test requires it. + vm.store( + address(uint160(uint256(keccak256(abi.encode("optimism.deployconfig"))))), + USE_FAULT_PROOFS_SLOT, + bytes32(uint256(1)) + ); + } + + function enablePlasma() public { + // Check if the system has already been deployed, based off of the heuristic that alice and bob have not been + // set by the `setUp` function yet. + if (!(alice == address(0) && bob == address(0))) { + revert("CommonTest: Cannot enable plasma after deployment. Consider overriding `setUp`."); + } + + usePlasmaOverride = true; + } +} diff --git a/packages/contracts-bedrock/test/setup/Events.sol b/packages/contracts-bedrock/test/setup/Events.sol new file mode 100644 index 000000000000..fabe171df625 --- /dev/null +++ b/packages/contracts-bedrock/test/setup/Events.sol @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { FeeVault } from "src/universal/FeeVault.sol"; + +/// @title Events +/// @dev Contains various events that are tested against. This contract needs to +/// exist until we either modularize the implementations or use a newer version of +/// solc that allows for referencing events from other contracts. +contract Events { + /// @dev OpenZeppelin Ownable.sol transferOwnership event + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); + + event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); + event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to); + + event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); + event SentMessageExtension1(address indexed sender, uint256 value); + event MessagePassed( + uint256 indexed nonce, + address indexed sender, + address indexed target, + uint256 value, + uint256 gasLimit, + bytes data, + bytes32 withdrawalHash + ); + event WithdrawerBalanceBurnt(uint256 indexed amount); + event RelayedMessage(bytes32 indexed msgHash); + event FailedRelayedMessage(bytes32 indexed msgHash); + event TransactionDeposited( + address indexed from, + address indexed to, + uint256 mint, + uint256 value, + uint64 gasLimit, + bool isCreation, + bytes data + ); + event WhatHappened(bool success, bytes returndata); + + event OutputProposed( + bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp + ); + + event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); + + event Withdrawal(uint256 value, address to, address from); + event Withdrawal(uint256 value, address to, address from, FeeVault.WithdrawalNetwork withdrawalNetwork); + + event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data); + + event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes data); + + event ERC20DepositInitiated( + address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data + ); + + event ERC20WithdrawalFinalized( + address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data + ); + + event WithdrawalInitiated( + address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data + ); + + event DepositFinalized( + address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data + ); + + event DepositFailed( + address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data + ); + + event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data); + + event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data); + + event ERC20BridgeInitiated( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 amount, + bytes data + ); + + event ERC20BridgeFinalized( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 amount, + bytes data + ); + + event Paused(string identifier); + + event Unpaused(); +} diff --git a/packages/contracts-bedrock/test/setup/FFIInterface.sol b/packages/contracts-bedrock/test/setup/FFIInterface.sol new file mode 100644 index 000000000000..34f509633ff5 --- /dev/null +++ b/packages/contracts-bedrock/test/setup/FFIInterface.sol @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Types } from "src/libraries/Types.sol"; +import { Vm } from "forge-std/Vm.sol"; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; + +/// @title FFIInterface +/// @notice This contract is set into state using `etch` and therefore must not have constructor logic. +/// It also MUST be compiled with `0.8.15` because `vm.getDeployedCode` will break if there +/// are multiple artifacts for different compiler versions. +contract FFIInterface { + Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx) + external + returns (bytes32, bytes32, bytes32, bytes32, bytes[] memory) + { + string[] memory cmds = new string[](9); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "getProveWithdrawalTransactionInputs"; + cmds[3] = vm.toString(_tx.nonce); + cmds[4] = vm.toString(_tx.sender); + cmds[5] = vm.toString(_tx.target); + cmds[6] = vm.toString(_tx.value); + cmds[7] = vm.toString(_tx.gasLimit); + cmds[8] = vm.toString(_tx.data); + + bytes memory result = vm.ffi(cmds); + ( + bytes32 stateRoot, + bytes32 storageRoot, + bytes32 outputRoot, + bytes32 withdrawalHash, + bytes[] memory withdrawalProof + ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[])); + + return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof); + } + + function hashCrossDomainMessage( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) + external + returns (bytes32) + { + string[] memory cmds = new string[](9); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "hashCrossDomainMessage"; + cmds[3] = vm.toString(_nonce); + cmds[4] = vm.toString(_sender); + cmds[5] = vm.toString(_target); + cmds[6] = vm.toString(_value); + cmds[7] = vm.toString(_gasLimit); + cmds[8] = vm.toString(_data); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes32)); + } + + function hashWithdrawal( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) + external + returns (bytes32) + { + string[] memory cmds = new string[](9); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "hashWithdrawal"; + cmds[3] = vm.toString(_nonce); + cmds[4] = vm.toString(_sender); + cmds[5] = vm.toString(_target); + cmds[6] = vm.toString(_value); + cmds[7] = vm.toString(_gasLimit); + cmds[8] = vm.toString(_data); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes32)); + } + + function hashOutputRootProof( + bytes32 _version, + bytes32 _stateRoot, + bytes32 _messagePasserStorageRoot, + bytes32 _latestBlockhash + ) + external + returns (bytes32) + { + string[] memory cmds = new string[](7); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "hashOutputRootProof"; + cmds[3] = Strings.toHexString(uint256(_version)); + cmds[4] = Strings.toHexString(uint256(_stateRoot)); + cmds[5] = Strings.toHexString(uint256(_messagePasserStorageRoot)); + cmds[6] = Strings.toHexString(uint256(_latestBlockhash)); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes32)); + } + + function hashDepositTransaction( + address _from, + address _to, + uint256 _mint, + uint256 _value, + uint64 _gas, + bytes memory _data, + uint64 _logIndex + ) + external + returns (bytes32) + { + string[] memory cmds = new string[](11); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "hashDepositTransaction"; + cmds[3] = "0x0000000000000000000000000000000000000000000000000000000000000000"; + cmds[4] = vm.toString(_logIndex); + cmds[5] = vm.toString(_from); + cmds[6] = vm.toString(_to); + cmds[7] = vm.toString(_mint); + cmds[8] = vm.toString(_value); + cmds[9] = vm.toString(_gas); + cmds[10] = vm.toString(_data); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes32)); + } + + function encodeDepositTransaction(Types.UserDepositTransaction calldata txn) external returns (bytes memory) { + string[] memory cmds = new string[](12); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "encodeDepositTransaction"; + cmds[3] = vm.toString(txn.from); + cmds[4] = vm.toString(txn.to); + cmds[5] = vm.toString(txn.value); + cmds[6] = vm.toString(txn.mint); + cmds[7] = vm.toString(txn.gasLimit); + cmds[8] = vm.toString(txn.isCreation); + cmds[9] = vm.toString(txn.data); + cmds[10] = vm.toString(txn.l1BlockHash); + cmds[11] = vm.toString(txn.logIndex); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes)); + } + + function encodeCrossDomainMessage( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) + external + returns (bytes memory) + { + string[] memory cmds = new string[](9); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "encodeCrossDomainMessage"; + cmds[3] = vm.toString(_nonce); + cmds[4] = vm.toString(_sender); + cmds[5] = vm.toString(_target); + cmds[6] = vm.toString(_value); + cmds[7] = vm.toString(_gasLimit); + cmds[8] = vm.toString(_data); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes)); + } + + function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) { + string[] memory cmds = new string[](4); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "decodeVersionedNonce"; + cmds[3] = vm.toString(nonce); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (uint256, uint256)); + } + + function getMerkleTrieFuzzCase(string memory variant) + external + returns (bytes32, bytes memory, bytes memory, bytes[] memory) + { + string[] memory cmds = new string[](6); + cmds[0] = "./scripts/go-ffi/go-ffi"; + cmds[1] = "trie"; + cmds[2] = variant; + + return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[])); + } + + function getCannonMemoryProof(uint32 pc, uint32 insn) external returns (bytes32, bytes memory) { + string[] memory cmds = new string[](5); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "cannonMemoryProof"; + cmds[3] = vm.toString(pc); + cmds[4] = vm.toString(insn); + bytes memory result = vm.ffi(cmds); + (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); + return (memRoot, proof); + } + + function getCannonMemoryProof( + uint32 pc, + uint32 insn, + uint32 memAddr, + uint32 memVal + ) + external + returns (bytes32, bytes memory) + { + string[] memory cmds = new string[](7); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "cannonMemoryProof"; + cmds[3] = vm.toString(pc); + cmds[4] = vm.toString(insn); + cmds[5] = vm.toString(memAddr); + cmds[6] = vm.toString(memVal); + bytes memory result = vm.ffi(cmds); + (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); + return (memRoot, proof); + } +} diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol new file mode 100644 index 000000000000..0adf339aeea3 --- /dev/null +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; +import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; +import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; +import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; +import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; +import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; +import { L1FeeVault } from "src/L2/L1FeeVault.sol"; +import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; +import { L1Block } from "src/L2/L1Block.sol"; +import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; +import { GovernanceToken } from "src/governance/GovernanceToken.sol"; +import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; +import { FeeVault } from "src/universal/FeeVault.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; +import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { DeployConfig } from "scripts/DeployConfig.s.sol"; +import { Deploy } from "scripts/Deploy.s.sol"; +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; +import { AddressManager } from "src/legacy/AddressManager.sol"; +import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +import { Executables } from "scripts/Executables.sol"; +import { Vm } from "forge-std/Vm.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { DataAvailabilityChallenge } from "src/L1/DataAvailabilityChallenge.sol"; + +/// @title Setup +/// @dev This contact is responsible for setting up the contracts in state. It currently +/// sets the L2 contracts directly at the predeploy addresses instead of setting them +/// up behind proxies. In the future we will migrate to importing the genesis JSON +/// file that is created to set up the L2 contracts instead of setting them up manually. +contract Setup { + /// @notice The address of the foundry Vm contract. + Vm private constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + /// @notice The address of the Deploy contract. Set into state with `etch` to avoid + /// mutating any nonces. MUST not have constructor logic. + Deploy internal constant deploy = Deploy(address(uint160(uint256(keccak256(abi.encode("optimism.deploy")))))); + + OptimismPortal optimismPortal; + OptimismPortal2 optimismPortal2; + DisputeGameFactory disputeGameFactory; + DelayedWETH delayedWeth; + L2OutputOracle l2OutputOracle; + SystemConfig systemConfig; + L1StandardBridge l1StandardBridge; + L1CrossDomainMessenger l1CrossDomainMessenger; + AddressManager addressManager; + L1ERC721Bridge l1ERC721Bridge; + OptimismMintableERC20Factory l1OptimismMintableERC20Factory; + ProtocolVersions protocolVersions; + SuperchainConfig superchainConfig; + DataAvailabilityChallenge dataAvailabilityChallenge; + AnchorStateRegistry anchorStateRegistry; + + L2CrossDomainMessenger l2CrossDomainMessenger = + L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); + L2StandardBridge l2StandardBridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)); + L2ToL1MessagePasser l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); + OptimismMintableERC20Factory l2OptimismMintableERC20Factory = + OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); + L2ERC721Bridge l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); + BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); + SequencerFeeVault sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); + L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); + GasPriceOracle gasPriceOracle = GasPriceOracle(Predeploys.GAS_PRICE_ORACLE); + L1Block l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); + LegacyMessagePasser legacyMessagePasser = LegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); + GovernanceToken governanceToken = GovernanceToken(Predeploys.GOVERNANCE_TOKEN); + + /// @dev Deploys the Deploy contract without including its bytecode in the bytecode + /// of this contract by fetching the bytecode dynamically using `vm.getCode()`. + /// If the Deploy bytecode is included in this contract, then it will double + /// the compile time and bloat all of the test contract artifacts since they + /// will also need to include the bytecode for the Deploy contract. + /// This is a hack as we are pushing solidity to the edge. + function setUp() public virtual { + vm.etch(address(deploy), vm.getDeployedCode("Deploy.s.sol:Deploy")); + vm.allowCheatcodes(address(deploy)); + deploy.setUp(); + } + + /// @dev Sets up the L1 contracts. + function L1() public { + // Set the deterministic deployer in state to ensure that it is there + vm.etch( + 0x4e59b44847b379578588920cA78FbF26c0B4956C, + hex"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" + ); + + deploy.run(); + + optimismPortal = OptimismPortal(deploy.mustGetAddress("OptimismPortalProxy")); + optimismPortal2 = OptimismPortal2(deploy.mustGetAddress("OptimismPortalProxy")); + disputeGameFactory = DisputeGameFactory(deploy.mustGetAddress("DisputeGameFactoryProxy")); + delayedWeth = DelayedWETH(deploy.mustGetAddress("DelayedWETHProxy")); + l2OutputOracle = L2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy")); + systemConfig = SystemConfig(deploy.mustGetAddress("SystemConfigProxy")); + l1StandardBridge = L1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy")); + l1CrossDomainMessenger = L1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessengerProxy")); + addressManager = AddressManager(deploy.mustGetAddress("AddressManager")); + l1ERC721Bridge = L1ERC721Bridge(deploy.mustGetAddress("L1ERC721BridgeProxy")); + l1OptimismMintableERC20Factory = + OptimismMintableERC20Factory(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy")); + protocolVersions = ProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy")); + superchainConfig = SuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy")); + anchorStateRegistry = AnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy")); + + vm.label(address(l2OutputOracle), "L2OutputOracle"); + vm.label(deploy.mustGetAddress("L2OutputOracleProxy"), "L2OutputOracleProxy"); + vm.label(address(optimismPortal), "OptimismPortal"); + vm.label(deploy.mustGetAddress("OptimismPortalProxy"), "OptimismPortalProxy"); + vm.label(address(disputeGameFactory), "DisputeGameFactory"); + vm.label(deploy.mustGetAddress("DisputeGameFactoryProxy"), "DisputeGameFactoryProxy"); + vm.label(address(delayedWeth), "DelayedWETH"); + vm.label(deploy.mustGetAddress("DelayedWETHProxy"), "DelayedWETHProxy"); + vm.label(address(systemConfig), "SystemConfig"); + vm.label(deploy.mustGetAddress("SystemConfigProxy"), "SystemConfigProxy"); + vm.label(address(l1StandardBridge), "L1StandardBridge"); + vm.label(deploy.mustGetAddress("L1StandardBridgeProxy"), "L1StandardBridgeProxy"); + vm.label(address(l1CrossDomainMessenger), "L1CrossDomainMessenger"); + vm.label(deploy.mustGetAddress("L1CrossDomainMessengerProxy"), "L1CrossDomainMessengerProxy"); + vm.label(address(addressManager), "AddressManager"); + vm.label(address(l1ERC721Bridge), "L1ERC721Bridge"); + vm.label(deploy.mustGetAddress("L1ERC721BridgeProxy"), "L1ERC721BridgeProxy"); + vm.label(address(l1OptimismMintableERC20Factory), "OptimismMintableERC20Factory"); + vm.label(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy"), "OptimismMintableERC20FactoryProxy"); + vm.label(address(protocolVersions), "ProtocolVersions"); + vm.label(deploy.mustGetAddress("ProtocolVersionsProxy"), "ProtocolVersionsProxy"); + vm.label(address(superchainConfig), "SuperchainConfig"); + vm.label(deploy.mustGetAddress("SuperchainConfigProxy"), "SuperchainConfigProxy"); + vm.label(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), "L1CrossDomainMessenger_aliased"); + + if (deploy.cfg().usePlasma()) { + dataAvailabilityChallenge = + DataAvailabilityChallenge(deploy.mustGetAddress("DataAvailabilityChallengeProxy")); + vm.label(address(dataAvailabilityChallenge), "DataAvailabilityChallengeProxy"); + vm.label(deploy.mustGetAddress("DataAvailabilityChallenge"), "DataAvailabilityChallenge"); + } + } + + /// @dev Sets up the L2 contracts. Depends on `L1()` being called first. + function L2() public { + string memory allocsPath = string.concat(vm.projectRoot(), "/.testdata/genesis.json"); + if (vm.isFile(allocsPath) == false) { + string[] memory args = new string[](3); + args[0] = Executables.bash; + args[1] = "-c"; + args[2] = string.concat(vm.projectRoot(), "/scripts/generate-l2-genesis.sh"); + vm.ffi(args); + } + + // Prevent race condition where the genesis.json file is not yet created + while (vm.isFile(allocsPath) == false) { + vm.sleep(1); + } + + vm.loadAllocs(allocsPath); + + // Set the governance token's owner to be the final system owner + address finalSystemOwner = deploy.cfg().finalSystemOwner(); + vm.prank(governanceToken.owner()); + governanceToken.transferOwnership(finalSystemOwner); + + vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, "OptimismMintableERC20Factory"); + vm.label(Predeploys.L2_STANDARD_BRIDGE, "L2StandardBridge"); + vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger"); + vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, "L2ToL1MessagePasser"); + vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault"); + vm.label(Predeploys.L2_ERC721_BRIDGE, "L2ERC721Bridge"); + vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault"); + vm.label(Predeploys.L1_FEE_VAULT, "L1FeeVault"); + vm.label(Predeploys.L1_BLOCK_ATTRIBUTES, "L1Block"); + vm.label(Predeploys.GAS_PRICE_ORACLE, "GasPriceOracle"); + vm.label(Predeploys.LEGACY_MESSAGE_PASSER, "LegacyMessagePasser"); + vm.label(Predeploys.GOVERNANCE_TOKEN, "GovernanceToken"); + vm.label(Predeploys.EAS, "EAS"); + vm.label(Predeploys.SCHEMA_REGISTRY, "SchemaRegistry"); + } +} diff --git a/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/universal/CrossDomainMessenger.t.sol similarity index 75% rename from packages/contracts-bedrock/test/CrossDomainMessenger.t.sol rename to packages/contracts-bedrock/test/universal/CrossDomainMessenger.t.sol index f525adc21c1a..a254b7312eee 100644 --- a/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/universal/CrossDomainMessenger.t.sol @@ -2,26 +2,29 @@ pragma solidity 0.8.15; // Testing utilities -import { Messenger_Initializer, Reverter, CallerCaller, CommonTest } from "test/CommonTest.t.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { Test } from "forge-std/Test.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; +import { CallerCaller, Reverter } from "test/mocks/Callers.sol"; // Libraries -import { Predeploys } from "../src/libraries/Predeploys.sol"; -import { Hashing } from "../src/libraries/Hashing.sol"; -import { Encoding } from "../src/libraries/Encoding.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; + +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; // CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2 // CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract. -contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { +contract CrossDomainMessenger_BaseGas_Test is Bridge_Initializer { /// @dev Ensure that baseGas passes for the max value of _minGasLimit, /// this is about 4 Billion. function test_baseGas_succeeds() external view { - L1Messenger.baseGas(hex"ff", type(uint32).max); + l1CrossDomainMessenger.baseGas(hex"ff", type(uint32).max); } /// @dev Fuzz for other values which might cause a revert in baseGas. function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view { - L1Messenger.baseGas(hex"ff", _minGasLimit); + l1CrossDomainMessenger.baseGas(hex"ff", _minGasLimit); } /// @notice The baseGas function should always return a value greater than @@ -30,8 +33,8 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { /// gas to the OptimismPortal. function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit) external { vm.assume(_data.length <= type(uint64).max); - uint64 baseGas = L1Messenger.baseGas(_data, _minGasLimit); - uint64 minGasLimit = op.minimumGasLimit(uint64(_data.length)); + uint64 baseGas = l1CrossDomainMessenger.baseGas(_data, _minGasLimit); + uint64 minGasLimit = optimismPortal.minimumGasLimit(uint64(_data.length)); assertTrue(baseGas >= minGasLimit); } } @@ -39,21 +42,21 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { /// @title ExternalRelay /// @notice A mock external contract called via the SafeCall inside /// the CrossDomainMessenger's `relayMessage` function. -contract ExternalRelay is CommonTest { +contract ExternalRelay is Test { address internal op; address internal fuzzedSender; - L1CrossDomainMessenger internal L1Messenger; + L1CrossDomainMessenger internal l1CrossDomainMessenger; event FailedRelayedMessage(bytes32 indexed msgHash); constructor(L1CrossDomainMessenger _l1Messenger, address _op) { - L1Messenger = _l1Messenger; + l1CrossDomainMessenger = _l1Messenger; op = _op; } /// @notice Internal helper function to relay a message and perform assertions. function _internalRelay(address _innerSender) internal { - address initialSender = L1Messenger.xDomainMessageSender(); + address initialSender = l1CrossDomainMessenger.xDomainMessageSender(); bytes memory callMessage = getCallData(); @@ -70,7 +73,7 @@ contract ExternalRelay is CommonTest { emit FailedRelayedMessage(hash); vm.prank(address(op)); - L1Messenger.relayMessage({ + l1CrossDomainMessenger.relayMessage({ _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), _sender: _innerSender, _target: address(this), @@ -79,9 +82,9 @@ contract ExternalRelay is CommonTest { _message: callMessage }); - assertTrue(L1Messenger.failedMessages(hash)); - assertFalse(L1Messenger.successfulMessages(hash)); - assertEq(initialSender, L1Messenger.xDomainMessageSender()); + assertTrue(l1CrossDomainMessenger.failedMessages(hash)); + assertFalse(l1CrossDomainMessenger.successfulMessages(hash)); + assertEq(initialSender, l1CrossDomainMessenger.xDomainMessageSender()); } /// @notice externalCallWithMinGas is called by the CrossDomainMessenger. @@ -108,7 +111,7 @@ contract ExternalRelay is CommonTest { /// @title CrossDomainMessenger_RelayMessage_Test /// @notice Fuzz tests re-entrancy into the CrossDomainMessenger relayMessage function. -contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { +contract CrossDomainMessenger_RelayMessage_Test is Bridge_Initializer { // Storage slot of the l2Sender uint256 constant senderSlotIndex = 50; @@ -116,7 +119,7 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { function setUp() public override { super.setUp(); - er = new ExternalRelay(L1Messenger, address(op)); + er = new ExternalRelay(l1CrossDomainMessenger, address(optimismPortal)); } /// @dev This test mocks an OptimismPortal call to the L1CrossDomainMessenger via @@ -148,9 +151,9 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { }); // set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - vm.prank(address(op)); - L1Messenger.relayMessage({ + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage({ _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), _sender: sender, _target: target, @@ -159,11 +162,11 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { _message: callMessage }); - assertTrue(L1Messenger.successfulMessages(hash)); - assertEq(L1Messenger.failedMessages(hash), false); + assertTrue(l1CrossDomainMessenger.successfulMessages(hash)); + assertEq(l1CrossDomainMessenger.failedMessages(hash), false); // Ensures that the `xDomainMsgSender` is set back to `Predeploys.L2_CROSS_DOMAIN_MESSENGER` vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L1Messenger.xDomainMessageSender(); + l1CrossDomainMessenger.xDomainMessageSender(); } } diff --git a/packages/contracts-bedrock/test/universal/FeeVault.t.sol b/packages/contracts-bedrock/test/universal/FeeVault.t.sol new file mode 100644 index 000000000000..83a8cc031291 --- /dev/null +++ b/packages/contracts-bedrock/test/universal/FeeVault.t.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; + +// Target contract +import { FeeVault } from "src/universal/FeeVault.sol"; + +// Test the implementations of the FeeVault +contract FeeVault_Test is Bridge_Initializer { + /// @dev Tests that the constructor sets the correct values. + function test_constructor_l1FeeVault_succeeds() external { + assertEq(l1FeeVault.RECIPIENT(), deploy.cfg().l1FeeVaultRecipient()); + assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().l1FeeVaultMinimumWithdrawalAmount()); + assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L1)); + } + + /// @dev Tests that the constructor sets the correct values. + function test_constructor_baseFeeVault_succeeds() external { + assertEq(baseFeeVault.RECIPIENT(), deploy.cfg().baseFeeVaultRecipient()); + assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().baseFeeVaultMinimumWithdrawalAmount()); + assertEq(uint8(baseFeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L1)); + } +} diff --git a/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol similarity index 84% rename from packages/contracts-bedrock/test/OptimismMintableERC20.t.sol rename to packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol index 40233eded0f8..6bb332473ecd 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/universal/OptimismMintableERC20.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; @@ -14,7 +14,7 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { } function test_bridge_succeeds() external { - assertEq(L2Token.bridge(), address(L2Bridge)); + assertEq(L2Token.bridge(), address(l2StandardBridge)); } function test_l1Token_succeeds() external { @@ -22,7 +22,7 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { } function test_l2Bridge_succeeds() external { - assertEq(L2Token.l2Bridge(), address(L2Bridge)); + assertEq(L2Token.l2Bridge(), address(l2StandardBridge)); } function test_legacy_succeeds() external { @@ -31,16 +31,16 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { assertEq(L2Token.remoteToken(), address(L1Token)); assertEq(L2Token.l1Token(), address(L1Token)); // Getters for the bridge - assertEq(L2Token.BRIDGE(), address(L2Bridge)); - assertEq(L2Token.bridge(), address(L2Bridge)); - assertEq(L2Token.l2Bridge(), address(L2Bridge)); + assertEq(L2Token.BRIDGE(), address(l2StandardBridge)); + assertEq(L2Token.bridge(), address(l2StandardBridge)); + assertEq(L2Token.l2Bridge(), address(l2StandardBridge)); } function test_mint_succeeds() external { vm.expectEmit(true, true, true, true); emit Mint(alice, 100); - vm.prank(address(L2Bridge)); + vm.prank(address(l2StandardBridge)); L2Token.mint(alice, 100); assertEq(L2Token.balanceOf(alice), 100); @@ -54,13 +54,13 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { } function test_burn_succeeds() external { - vm.prank(address(L2Bridge)); + vm.prank(address(l2StandardBridge)); L2Token.mint(alice, 100); vm.expectEmit(true, true, true, true); emit Burn(alice, 100); - vm.prank(address(L2Bridge)); + vm.prank(address(l2StandardBridge)); L2Token.burn(alice, 100); assertEq(L2Token.balanceOf(alice), 0); diff --git a/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol b/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol new file mode 100644 index 000000000000..08ee0343e53f --- /dev/null +++ b/packages/contracts-bedrock/test/universal/OptimismMintableERC20Factory.t.sol @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; +import { NextImpl } from "test/mocks/NextImpl.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Target contract dependencies +import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; +import { Proxy } from "src/universal/Proxy.sol"; + +// Target contract +import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; + +contract OptimismMintableTokenFactory_Test is Bridge_Initializer { + event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); + event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); + + /// @dev Tests that the constructor is initialized correctly. + function test_constructor_succeeds() external { + OptimismMintableERC20Factory impl = new OptimismMintableERC20Factory(); + assertEq(address(impl.BRIDGE()), address(0)); + assertEq(address(impl.bridge()), address(0)); + } + + /// @dev Tests that the proxy is initialized correctly. + function test_initialize_succeeds() external { + assertEq(address(l1OptimismMintableERC20Factory.BRIDGE()), address(l1StandardBridge)); + assertEq(address(l1OptimismMintableERC20Factory.bridge()), address(l1StandardBridge)); + } + + function test_upgrading_succeeds() external { + Proxy proxy = Proxy(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy")); + // Check an unused slot before upgrading. + bytes32 slot21Before = vm.load(address(l1OptimismMintableERC20Factory), bytes32(uint256(21))); + assertEq(bytes32(0), slot21Before); + + NextImpl nextImpl = new NextImpl(); + vm.startPrank(EIP1967Helper.getAdmin(address(proxy))); + // Reviewer note: the NextImpl() still uses reinitializer. If we want to remove that, we'll need to use a + // two step upgrade with the Storage lib. + proxy.upgradeToAndCall(address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, 2)); + assertEq(proxy.implementation(), address(nextImpl)); + + // Verify that the NextImpl contract initialized its values according as expected + bytes32 slot21After = vm.load(address(l1OptimismMintableERC20Factory), bytes32(uint256(21))); + bytes32 slot21Expected = NextImpl(address(l1OptimismMintableERC20Factory)).slot21Init(); + assertEq(slot21Expected, slot21After); + } + + function test_createStandardL2Token_succeeds() external { + address remote = address(4); + + // Defaults to 18 decimals + address local = calculateTokenAddress(remote, "Beep", "BOOP", 18); + + vm.expectEmit(true, true, true, true); + emit StandardL2TokenCreated(remote, local); + + vm.expectEmit(true, true, true, true); + emit OptimismMintableERC20Created(local, remote, alice); + + vm.prank(alice); + address addr = l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP"); + assertTrue(addr == local); + assertTrue(OptimismMintableERC20(local).decimals() == 18); + } + + function test_createStandardL2TokenWithDecimals_succeeds() external { + address remote = address(4); + address local = calculateTokenAddress(remote, "Beep", "BOOP", 6); + + vm.expectEmit(true, true, true, true); + emit StandardL2TokenCreated(remote, local); + + vm.expectEmit(true, true, true, true); + emit OptimismMintableERC20Created(local, remote, alice); + + vm.prank(alice); + address addr = l2OptimismMintableERC20Factory.createOptimismMintableERC20WithDecimals(remote, "Beep", "BOOP", 6); + assertTrue(addr == local); + + assertTrue(OptimismMintableERC20(local).decimals() == 6); + } + + function test_createStandardL2Token_sameTwice_reverts() external { + address remote = address(4); + + vm.prank(alice); + l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP"); + + vm.expectRevert(bytes("")); + + vm.prank(alice); + l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP"); + } + + function test_createStandardL2Token_remoteIsZero_reverts() external { + address remote = address(0); + vm.expectRevert("OptimismMintableERC20Factory: must provide remote token address"); + l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP"); + } + + function calculateTokenAddress( + address _remote, + string memory _name, + string memory _symbol, + uint8 _decimals + ) + internal + view + returns (address) + { + bytes memory constructorArgs = abi.encode(address(l2StandardBridge), _remote, _name, _symbol, _decimals); + bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC20).creationCode, constructorArgs); + bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol, _decimals)); + bytes32 hash = keccak256( + abi.encodePacked(bytes1(0xff), address(l2OptimismMintableERC20Factory), salt, keccak256(bytecode)) + ); + return address(uint160(uint256(hash))); + } +} diff --git a/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol b/packages/contracts-bedrock/test/universal/OptimismMintableERC721.t.sol similarity index 87% rename from packages/contracts-bedrock/test/OptimismMintableERC721.t.sol rename to packages/contracts-bedrock/test/universal/OptimismMintableERC721.t.sol index 5aac93b2eb4c..56eb056c3d1e 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol +++ b/packages/contracts-bedrock/test/universal/OptimismMintableERC721.t.sol @@ -5,10 +5,10 @@ import { ERC721, IERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { OptimismMintableERC721, IOptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; -contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { +contract OptimismMintableERC721_Test is Bridge_Initializer { ERC721 internal L1NFT; OptimismMintableERC721 internal L2NFT; @@ -23,13 +23,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { // Set up the token pair. L1NFT = new ERC721("L1NFT", "L1T"); - L2NFT = new OptimismMintableERC721( - address(L2NFTBridge), - 1, - address(L1NFT), - "L2NFT", - "L2T" - ); + L2NFT = new OptimismMintableERC721(address(l2ERC721Bridge), 1, address(L1NFT), "L2NFT", "L2T"); // Label the addresses for nice traces. vm.label(address(L1NFT), "L1ERC721Token"); @@ -40,10 +34,10 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { assertEq(L2NFT.name(), "L2NFT"); assertEq(L2NFT.symbol(), "L2T"); assertEq(L2NFT.remoteToken(), address(L1NFT)); - assertEq(L2NFT.bridge(), address(L2NFTBridge)); + assertEq(L2NFT.bridge(), address(l2ERC721Bridge)); assertEq(L2NFT.remoteChainId(), 1); assertEq(L2NFT.REMOTE_TOKEN(), address(L1NFT)); - assertEq(L2NFT.BRIDGE(), address(L2NFTBridge)); + assertEq(L2NFT.BRIDGE(), address(l2ERC721Bridge)); assertEq(L2NFT.REMOTE_CHAIN_ID(), 1); } @@ -69,7 +63,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { emit Mint(alice, 1); // Mint the token. - vm.prank(address(L2NFTBridge)); + vm.prank(address(l2ERC721Bridge)); L2NFT.safeMint(alice, 1); // Token should be owned by alice. @@ -85,7 +79,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { function test_burn_succeeds() external { // Mint the token first. - vm.prank(address(L2NFTBridge)); + vm.prank(address(l2ERC721Bridge)); L2NFT.safeMint(alice, 1); // Expect a transfer event. @@ -97,7 +91,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { emit Burn(alice, 1); // Burn the token. - vm.prank(address(L2NFTBridge)); + vm.prank(address(l2ERC721Bridge)); L2NFT.burn(alice, 1); // Token should be owned by address(0). @@ -107,7 +101,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { function test_burn_notBridge_reverts() external { // Mint the token first. - vm.prank(address(L2NFTBridge)); + vm.prank(address(l2ERC721Bridge)); L2NFT.safeMint(alice, 1); // Try to burn the token. @@ -118,7 +112,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { function test_tokenURI_succeeds() external { // Mint the token first. - vm.prank(address(L2NFTBridge)); + vm.prank(address(l2ERC721Bridge)); L2NFT.safeMint(alice, 1); // Token URI should be correct. diff --git a/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol b/packages/contracts-bedrock/test/universal/OptimismMintableERC721Factory.t.sol similarity index 86% rename from packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol rename to packages/contracts-bedrock/test/universal/OptimismMintableERC721Factory.t.sol index ee70e3ff9f3b..04a084f392d1 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol +++ b/packages/contracts-bedrock/test/universal/OptimismMintableERC721Factory.t.sol @@ -2,11 +2,11 @@ pragma solidity 0.8.15; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; -contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { +contract OptimismMintableERC721Factory_Test is Bridge_Initializer { OptimismMintableERC721Factory internal factory; event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer); @@ -15,14 +15,14 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { super.setUp(); // Set up the token pair. - factory = new OptimismMintableERC721Factory(address(L2NFTBridge), 1); + factory = new OptimismMintableERC721Factory(address(l2ERC721Bridge), 1); // Label the addresses for nice traces. vm.label(address(factory), "OptimismMintableERC721Factory"); } function test_constructor_succeeds() external { - assertEq(factory.BRIDGE(), address(L2NFTBridge)); + assertEq(factory.BRIDGE(), address(l2ERC721Bridge)); assertEq(factory.REMOTE_CHAIN_ID(), 1); } @@ -49,7 +49,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { assertEq(created.name(), "L2Token"); assertEq(created.symbol(), "L2T"); assertEq(created.REMOTE_TOKEN(), remote); - assertEq(created.BRIDGE(), address(L2NFTBridge)); + assertEq(created.BRIDGE(), address(l2ERC721Bridge)); assertEq(created.REMOTE_CHAIN_ID(), 1); } @@ -59,7 +59,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { vm.prank(alice); factory.createOptimismMintableERC721(remote, "L2Token", "L2T"); - vm.expectRevert(); + vm.expectRevert(bytes("")); vm.prank(alice); factory.createOptimismMintableERC721(remote, "L2Token", "L2T"); @@ -80,7 +80,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { view returns (address) { - bytes memory constructorArgs = abi.encode(address(L2NFTBridge), 1, _remote, _name, _symbol); + bytes memory constructorArgs = abi.encode(address(l2ERC721Bridge), 1, _remote, _name, _symbol); bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC721).creationCode, constructorArgs); bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol)); bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(factory), salt, keccak256(bytecode))); diff --git a/packages/contracts-bedrock/test/Proxy.t.sol b/packages/contracts-bedrock/test/universal/Proxy.t.sol similarity index 98% rename from packages/contracts-bedrock/test/Proxy.t.sol rename to packages/contracts-bedrock/test/universal/Proxy.t.sol index fa794dd295b2..66c3f1d24268 100644 --- a/packages/contracts-bedrock/test/Proxy.t.sol +++ b/packages/contracts-bedrock/test/universal/Proxy.t.sol @@ -76,7 +76,7 @@ contract Proxy_Test is Test { // The implementation does not have a `upgradeTo` // method, calling `upgradeTo` not as the owner // should revert. - vm.expectRevert(); + vm.expectRevert(bytes("")); proxy.upgradeTo(address(64)); // Call `upgradeTo` as the owner, it should succeed @@ -95,7 +95,7 @@ contract Proxy_Test is Test { function test_ownerProxyCall_notAdmin_succeeds() external { // Calling `changeAdmin` not as the owner should revert // as the implementation does not have a `changeAdmin` method. - vm.expectRevert(); + vm.expectRevert(bytes("")); proxy.changeAdmin(address(1)); // Call `changeAdmin` as the owner, it should succeed @@ -108,7 +108,7 @@ contract Proxy_Test is Test { // Calling `admin` not as the owner should // revert as the implementation does not have // a `admin` method. - vm.expectRevert(); + vm.expectRevert(bytes("")); proxy.admin(); // Calling `admin` as the owner should work. @@ -186,7 +186,7 @@ contract Proxy_Test is Test { // The attempt to `upgradeToAndCall` // should revert when it is not called by the owner. - vm.expectRevert(); + vm.expectRevert(bytes("")); proxy.upgradeToAndCall(address(simpleStorage), abi.encodeWithSelector(simpleStorage.set.selector, 1, 1)); } diff --git a/packages/contracts-bedrock/test/ProxyAdmin.t.sol b/packages/contracts-bedrock/test/universal/ProxyAdmin.t.sol similarity index 99% rename from packages/contracts-bedrock/test/ProxyAdmin.t.sol rename to packages/contracts-bedrock/test/universal/ProxyAdmin.t.sol index 083ba04c2fe5..9cd3e1772f64 100644 --- a/packages/contracts-bedrock/test/ProxyAdmin.t.sol +++ b/packages/contracts-bedrock/test/universal/ProxyAdmin.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; -import { SimpleStorage } from "test/Proxy.t.sol"; +import { SimpleStorage } from "test/universal/Proxy.t.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; diff --git a/packages/contracts-bedrock/test/StandardBridge.t.sol b/packages/contracts-bedrock/test/universal/StandardBridge.t.sol similarity index 92% rename from packages/contracts-bedrock/test/StandardBridge.t.sol rename to packages/contracts-bedrock/test/universal/StandardBridge.t.sol index 000d2334ae34..c64e816dc0e7 100644 --- a/packages/contracts-bedrock/test/StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/universal/StandardBridge.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { OptimismMintableERC20, ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; @@ -10,12 +10,7 @@ import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; /// @notice Simple wrapper around the StandardBridge contract that exposes /// internal functions so they can be more easily tested directly. contract StandardBridgeTester is StandardBridge { - constructor( - address payable _messenger, - address payable _otherBridge - ) - StandardBridge(StandardBridge(_otherBridge)) - { } + constructor() StandardBridge() { } function isOptimismMintableERC20(address _token) external view returns (bool) { return _isOptimismMintableERC20(_token); @@ -65,10 +60,7 @@ contract StandardBridge_Stateless_Test is CommonTest { function setUp() public override { super.setUp(); - bridge = new StandardBridgeTester({ - _messenger: payable(address(0)), - _otherBridge: payable(address(0)) - }); + bridge = new StandardBridgeTester(); mintable = new OptimismMintableERC20({ _bridge: address(0), @@ -114,7 +106,12 @@ contract StandardBridge_Stateless_Test is CommonTest { assertFalse(bridge.isCorrectTokenPair(address(legacy), address(0x20))); // A token that doesn't support either modern or legacy interface // will revert - vm.expectRevert(); + vm.expectRevert(bytes("")); bridge.isCorrectTokenPair(address(erc20), address(1)); } + + /// @notice The bridge by default should be unpaused. + function test_paused_succeeds() external { + assertFalse(bridge.paused()); + } } diff --git a/packages/contracts-bedrock/test/AddressAliasHelper.t.sol b/packages/contracts-bedrock/test/vendor/AddressAliasHelper.t.sol similarity index 100% rename from packages/contracts-bedrock/test/AddressAliasHelper.t.sol rename to packages/contracts-bedrock/test/vendor/AddressAliasHelper.t.sol diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol new file mode 100644 index 000000000000..ad72791e95d1 --- /dev/null +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -0,0 +1,455 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; +import { Executables } from "scripts/Executables.sol"; +import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol"; +import "src/L1/ProtocolVersions.sol"; +import "scripts/Deployer.sol"; + +/// @title Initializer_Test +/// @dev Ensures that the `initialize()` function on contracts cannot be called more than +/// once. This contract inherits from `ERC721Bridge_Initializer` because it is the +/// deepest contract in the inheritance chain for setting up the system contracts. +/// For each L1 contract both the implementation and the proxy are tested. +contract Initializer_Test is Bridge_Initializer { + /// @notice Contains the address of an `Initializable` contract and the calldata + /// used to initialize it. + struct InitializeableContract { + address target; + bytes initCalldata; + uint8 initializedSlotVal; + } + + /// @notice Contains the addresses of the contracts to test as well as the calldata + /// used to initialize them. + InitializeableContract[] contracts; + + function setUp() public override { + super.enablePlasma(); + // Run the `Bridge_Initializer`'s `setUp()` function. + super.setUp(); + + // Initialize the `contracts` array with the addresses of the contracts to test, the + // calldata used to initialize them, and the storage slot of their `_initialized` flag. + + // SuperchainConfigImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("SuperchainConfig"), + initCalldata: abi.encodeCall(superchainConfig.initialize, (address(0), false)), + initializedSlotVal: deploy.loadInitializedSlot("SuperchainConfig") + }) + ); + // SuperchainConfigProxy + contracts.push( + InitializeableContract({ + target: address(superchainConfig), + initCalldata: abi.encodeCall(superchainConfig.initialize, (address(0), false)), + initializedSlotVal: deploy.loadInitializedSlot("SuperchainConfigProxy") + }) + ); + // L1CrossDomainMessengerImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("L1CrossDomainMessenger"), + initCalldata: abi.encodeCall(l1CrossDomainMessenger.initialize, (superchainConfig, optimismPortal)), + initializedSlotVal: deploy.loadInitializedSlot("L1CrossDomainMessenger") + }) + ); + // L1CrossDomainMessengerProxy + contracts.push( + InitializeableContract({ + target: address(l1CrossDomainMessenger), + initCalldata: abi.encodeCall(l1CrossDomainMessenger.initialize, (superchainConfig, optimismPortal)), + initializedSlotVal: deploy.loadInitializedSlot("L1CrossDomainMessengerProxy") + }) + ); + // DisputeGameFactoryImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("DisputeGameFactory"), + initCalldata: abi.encodeCall(disputeGameFactory.initialize, (address(0))), + initializedSlotVal: deploy.loadInitializedSlot("DisputeGameFactory") + }) + ); + // DisputeGameFactoryProxy + contracts.push( + InitializeableContract({ + target: address(disputeGameFactory), + initCalldata: abi.encodeCall(disputeGameFactory.initialize, (address(0))), + initializedSlotVal: deploy.loadInitializedSlot("DisputeGameFactoryProxy") + }) + ); + // DelayedWETHImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("DelayedWETH"), + initCalldata: abi.encodeCall(delayedWeth.initialize, (address(0), SuperchainConfig(address(0)))), + initializedSlotVal: deploy.loadInitializedSlot("DelayedWETH") + }) + ); + // DelayedWETHProxy + contracts.push( + InitializeableContract({ + target: address(delayedWeth), + initCalldata: abi.encodeCall(delayedWeth.initialize, (address(0), SuperchainConfig(address(0)))), + initializedSlotVal: deploy.loadInitializedSlot("DelayedWETHProxy") + }) + ); + // L2OutputOracleImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("L2OutputOracle"), + initCalldata: abi.encodeCall(l2OutputOracle.initialize, (0, 0, 0, 0, address(0), address(0), 0)), + initializedSlotVal: deploy.loadInitializedSlot("L2OutputOracle") + }) + ); + // L2OutputOracleProxy + contracts.push( + InitializeableContract({ + target: address(l2OutputOracle), + initCalldata: abi.encodeCall(l2OutputOracle.initialize, (0, 0, 0, 0, address(0), address(0), 0)), + initializedSlotVal: deploy.loadInitializedSlot("L2OutputOracleProxy") + }) + ); + // OptimismPortalImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("OptimismPortal"), + initCalldata: abi.encodeCall(optimismPortal.initialize, (l2OutputOracle, systemConfig, superchainConfig)), + initializedSlotVal: deploy.loadInitializedSlot("OptimismPortal") + }) + ); + // OptimismPortal2Impl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("OptimismPortal2"), + initCalldata: abi.encodeCall( + optimismPortal2.initialize, (disputeGameFactory, systemConfig, superchainConfig) + ), + initializedSlotVal: deploy.loadInitializedSlot("OptimismPortal2") + }) + ); + // OptimismPortalProxy + contracts.push( + InitializeableContract({ + target: address(optimismPortal), + initCalldata: abi.encodeCall(optimismPortal.initialize, (l2OutputOracle, systemConfig, superchainConfig)), + initializedSlotVal: deploy.loadInitializedSlot("OptimismPortalProxy") + }) + ); + // SystemConfigImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("SystemConfig"), + initCalldata: abi.encodeCall( + systemConfig.initialize, + ( + address(0xdead), + 0, + 0, + bytes32(0), + 1, + address(0), + ResourceMetering.ResourceConfig({ + maxResourceLimit: 1, + elasticityMultiplier: 1, + baseFeeMaxChangeDenominator: 2, + minimumBaseFee: 0, + systemTxMaxGas: 0, + maximumBaseFee: 0 + }), + address(0), + SystemConfig.Addresses({ + l1CrossDomainMessenger: address(0), + l1ERC721Bridge: address(0), + l1StandardBridge: address(0), + l2OutputOracle: address(0), + optimismPortal: address(0), + optimismMintableERC20Factory: address(0) + }) + ) + ), + initializedSlotVal: deploy.loadInitializedSlot("SystemConfig") + }) + ); + // SystemConfigProxy + contracts.push( + InitializeableContract({ + target: address(systemConfig), + initCalldata: abi.encodeCall( + systemConfig.initialize, + ( + address(0xdead), + 0, + 0, + bytes32(0), + 1, + address(0), + ResourceMetering.ResourceConfig({ + maxResourceLimit: 1, + elasticityMultiplier: 1, + baseFeeMaxChangeDenominator: 2, + minimumBaseFee: 0, + systemTxMaxGas: 0, + maximumBaseFee: 0 + }), + address(0), + SystemConfig.Addresses({ + l1CrossDomainMessenger: address(0), + l1ERC721Bridge: address(0), + l1StandardBridge: address(0), + l2OutputOracle: address(0), + optimismPortal: address(0), + optimismMintableERC20Factory: address(0) + }) + ) + ), + initializedSlotVal: deploy.loadInitializedSlot("SystemConfigProxy") + }) + ); + // ProtocolVersionsImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("ProtocolVersions"), + initCalldata: abi.encodeCall( + protocolVersions.initialize, (address(0), ProtocolVersion.wrap(1), ProtocolVersion.wrap(2)) + ), + initializedSlotVal: deploy.loadInitializedSlot("ProtocolVersions") + }) + ); + // ProtocolVersionsProxy + contracts.push( + InitializeableContract({ + target: address(protocolVersions), + initCalldata: abi.encodeCall( + protocolVersions.initialize, (address(0), ProtocolVersion.wrap(1), ProtocolVersion.wrap(2)) + ), + initializedSlotVal: deploy.loadInitializedSlot("ProtocolVersionsProxy") + }) + ); + // L2CrossDomainMessenger + contracts.push( + InitializeableContract({ + target: address(l2CrossDomainMessenger), + initCalldata: abi.encodeCall(l2CrossDomainMessenger.initialize, (l1CrossDomainMessenger)), + initializedSlotVal: deploy.loadInitializedSlot("L2CrossDomainMessenger") + }) + ); + // L1StandardBridgeImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("L1StandardBridge"), + initCalldata: abi.encodeCall(l1StandardBridge.initialize, (l1CrossDomainMessenger, superchainConfig)), + initializedSlotVal: deploy.loadInitializedSlot("L1StandardBridge") + }) + ); + // L1StandardBridgeProxy + contracts.push( + InitializeableContract({ + target: address(l1StandardBridge), + initCalldata: abi.encodeCall(l1StandardBridge.initialize, (l1CrossDomainMessenger, superchainConfig)), + initializedSlotVal: deploy.loadInitializedSlot("L1StandardBridgeProxy") + }) + ); + // L2StandardBridge + contracts.push( + InitializeableContract({ + target: address(l2StandardBridge), + initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge)), + initializedSlotVal: deploy.loadInitializedSlot("L2StandardBridge") + }) + ); + // L1ERC721BridgeImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("L1ERC721Bridge"), + initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)), + initializedSlotVal: deploy.loadInitializedSlot("L1ERC721Bridge") + }) + ); + // L1ERC721BridgeProxy + contracts.push( + InitializeableContract({ + target: address(l1ERC721Bridge), + initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)), + initializedSlotVal: deploy.loadInitializedSlot("L1ERC721BridgeProxy") + }) + ); + // L2ERC721Bridge + contracts.push( + InitializeableContract({ + target: address(l2ERC721Bridge), + initCalldata: abi.encodeCall(l2ERC721Bridge.initialize, (payable(address(l1ERC721Bridge)))), + initializedSlotVal: deploy.loadInitializedSlot("L2ERC721Bridge") + }) + ); + // OptimismMintableERC20FactoryImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("OptimismMintableERC20Factory"), + initCalldata: abi.encodeCall(l1OptimismMintableERC20Factory.initialize, (address(l1StandardBridge))), + initializedSlotVal: deploy.loadInitializedSlot("OptimismMintableERC20Factory") + }) + ); + // OptimismMintableERC20FactoryProxy + contracts.push( + InitializeableContract({ + target: address(l1OptimismMintableERC20Factory), + initCalldata: abi.encodeCall(l1OptimismMintableERC20Factory.initialize, (address(l1StandardBridge))), + initializedSlotVal: deploy.loadInitializedSlot("OptimismMintableERC20FactoryProxy") + }) + ); + // DataAvailabilityChallengeImpl + contracts.push( + InitializeableContract({ + target: deploy.mustGetAddress("DataAvailabilityChallenge"), + initCalldata: abi.encodeCall(dataAvailabilityChallenge.initialize, (address(0), 0, 0, 0, 0)), + initializedSlotVal: deploy.loadInitializedSlot("DataAvailabilityChallenge") + }) + ); + // DataAvailabilityChallengeProxy + contracts.push( + InitializeableContract({ + target: address(dataAvailabilityChallenge), + initCalldata: abi.encodeCall(dataAvailabilityChallenge.initialize, (address(0), 0, 0, 0, 0)), + initializedSlotVal: deploy.loadInitializedSlot("DataAvailabilityChallengeProxy") + }) + ); + } + + /// @notice Tests that: + /// 1. All `Initializable` contracts in `src/L1` and `src/L2` are accounted for in the `contracts` array. + /// 2. The `_initialized` flag of each contract is properly set to `1`, signifying that the + /// contracts are initialized. + /// 3. The `initialize()` function of each contract cannot be called more than once. + function test_cannotReinitialize_succeeds() public { + // Ensure that all L1, L2 `Initializable` contracts are accounted for, in addition to + // OptimismMintableERC20FactoryImpl, OptimismMintableERC20FactoryProxy, OptimismPortal2, + // DisputeGameFactoryImpl, DisputeGameFactoryProxy, DelayedWETHImpl, DelayedWETHProxy. + assertEq(_getNumInitializable() + 5, contracts.length); + + // Attempt to re-initialize all contracts within the `contracts` array. + for (uint256 i; i < contracts.length; i++) { + InitializeableContract memory _contract = contracts[i]; + uint256 size; + address target = _contract.target; + assembly { + size := extcodesize(target) + } + // Assert that the contract is already initialized. + assertEq(_contract.initializedSlotVal, 1); + + // Then, attempt to re-initialize the contract. This should fail. + (bool success, bytes memory returnData) = _contract.target.call(_contract.initCalldata); + assertFalse(success); + assertEq(_extractErrorString(returnData), "Initializable: contract is already initialized"); + } + } + + /// @dev Returns the number of contracts that are `Initializable` in `src/L1` and `src/L2`. + /// For L1 contracts, implementations are considered in addition to proxies + function _getNumInitializable() internal returns (uint256 numContracts_) { + string[] memory command = new string[](3); + command[0] = Executables.bash; + command[1] = "-c"; + // Start by getting L1 contracts + command[2] = string.concat( + Executables.find, + " src/L1 -type f -exec basename {} \\;", + " | ", + Executables.sed, + " 's/\\.[^.]*$//'", + " | ", + Executables.jq, + " -R -s 'split(\"\n\")[:-1]'" + ); + string[] memory l1ContractNames = abi.decode(vm.parseJson(string(vm.ffi(command))), (string[])); + + for (uint256 i; i < l1ContractNames.length; i++) { + string memory contractName = l1ContractNames[i]; + string memory contractAbi = ForgeArtifacts.getAbi(contractName); + + // Query the contract's ABI for an `initialize()` function. + command[2] = string.concat( + Executables.echo, + " '", + contractAbi, + "'", + " | ", + Executables.jq, + " '.[] | select(.name == \"initialize\" and .type == \"function\")'" + ); + bytes memory res = vm.ffi(command); + + // If the contract has an `initialize()` function, the resulting query will be non-empty. + // In this case, increment the number of `Initializable` contracts. + if (res.length > 0) { + // Count Proxy + Impl + numContracts_ += 2; + } + } + + // Then get L2 contracts + command[2] = string.concat( + Executables.find, + " src/L2 -type f -exec basename {} \\;", + " | ", + Executables.sed, + " 's/\\.[^.]*$//'", + " | ", + Executables.jq, + " -R -s 'split(\"\n\")[:-1]'" + ); + string[] memory l2ContractNames = abi.decode(vm.parseJson(string(vm.ffi(command))), (string[])); + + for (uint256 i; i < l2ContractNames.length; i++) { + string memory contractName = l2ContractNames[i]; + string memory contractAbi = ForgeArtifacts.getAbi(contractName); + + // Query the contract's ABI for an `initialize()` function. + command[2] = string.concat( + Executables.echo, + " '", + contractAbi, + "'", + " | ", + Executables.jq, + " '.[] | select(.name == \"initialize\" and .type == \"function\")'" + ); + bytes memory res = vm.ffi(command); + + // If the contract has an `initialize()` function, the resulting query will be non-empty. + // In this case, increment the number of `Initializable` contracts. + if (res.length > 0) { + numContracts_++; + } + } + } + + /// @dev Extracts the revert string from returndata encoded in the form of `Error(string)`. + function _extractErrorString(bytes memory _returnData) internal pure returns (string memory error_) { + // The first 4 bytes of the return data should be the selector for `Error(string)`. If not, revert. + if (bytes4(_returnData) == 0x08c379a0) { + // Extract the error string from the returndata. The error string is located 68 bytes after + // the pointer to `returnData`. + // + // 32 bytes: `returnData` length + // 4 bytes: `Error(string)` selector + // 32 bytes: ABI encoding metadata; String offset + // = 68 bytes + assembly { + error_ := add(_returnData, 0x44) + } + } else { + revert("Initializer_Test: Invalid returndata format. Expected `Error(string)`"); + } + } +} diff --git a/packages/contracts-ts/CODE_GEN.md b/packages/contracts-ts/CODE_GEN.md index 262e7984f581..bd637ff536b0 100644 --- a/packages/contracts-ts/CODE_GEN.md +++ b/packages/contracts-ts/CODE_GEN.md @@ -3,7 +3,7 @@ Summary - - This package is generated from [contracts-bedrock](../contracts-bedrock/) -- It's version is kept in sync with contracts bedrock via the [changeset config](../../.changeset/config.json) e.g. if contracts-bedrock is `4.2.0` this package will have the same version. +- Its version is kept in sync with contracts bedrock via the [changeset config](../../.changeset/config.json) e.g. if contracts-bedrock is `4.2.0` this package will have the same version. ## Code gen instructions diff --git a/packages/contracts-ts/package.json b/packages/contracts-ts/package.json index 9cd089f4c3fe..11057df5c1d3 100644 --- a/packages/contracts-ts/package.json +++ b/packages/contracts-ts/package.json @@ -37,7 +37,6 @@ "scripts": { "build": "tsup", "clean": "rm -rf ./dist", - "preinstall": "npx only-allow pnpm", "generate": "wagmi generate && pnpm build && pnpm lint:fix", "generate:check": "pnpm generate && git diff --exit-code ./addresses.json && git diff --exit-code ./abis.json", "lint": "prettier --check .", @@ -48,25 +47,26 @@ }, "devDependencies": { "@eth-optimism/contracts-bedrock": "workspace:*", - "@testing-library/jest-dom": "^6.1.4", + "@testing-library/jest-dom": "^6.4.2", "@testing-library/react-hooks": "^8.0.1", "@types/glob": "^8.1.0", - "@vitest/coverage-istanbul": "^0.34.6", - "@wagmi/cli": "^1.5.2", - "@wagmi/core": "^1.4.5", - "abitype": "^0.10.1", + "@vitest/coverage-istanbul": "^1.2.2", + "@wagmi/cli": "^2.1.2", + "@wagmi/core": "^2.6.3", + "abitype": "^1.0.2", "glob": "^10.3.10", "isomorphic-fetch": "^3.0.0", "jest-dom": "link:@types/@testing-library/jest-dom", - "jsdom": "^22.1.0", - "tsup": "^7.2.0", - "typescript": "^5.2.2", - "vite": "^4.5.0", - "vitest": "^0.34.2" + "jsdom": "^24.0.0", + "tsup": "^8.0.1", + "typescript": "^5.3.3", + "vite": "^5.1.5", + "wagmi": "^2.5.5", + "vitest": "^1.2.2" }, "peerDependencies": { - "@wagmi/core": ">1.0.0", - "wagmi": ">1.0.0" + "@wagmi/core": "^2.6.3", + "wagmi": "^2.5.5" }, "peerDependenciesMeta": { "wagmi": { @@ -77,11 +77,11 @@ } }, "dependencies": { - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^14.2.1", "@types/change-case": "^2.3.1", "change-case": "4.1.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "viem": "^1.18.0" + "viem": "^2.7.19" } } diff --git a/packages/contracts-ts/wagmi.config.ts b/packages/contracts-ts/wagmi.config.ts index d9f8b19fc748..7dd906baeb37 100644 --- a/packages/contracts-ts/wagmi.config.ts +++ b/packages/contracts-ts/wagmi.config.ts @@ -261,7 +261,7 @@ const getContractConfigs = (filterDuplicates = false) => { .filter(([_, implementation]) => implementation) .forEach(([chain, implementation], i) => { if (implementation) { - // make the first one cannonical. This will be mainnet or op mainnet if they exist + // make the first one canonical. This will be mainnet or op mainnet if they exist const name = i === 0 ? contract.name : `${contract.name}_${chains[chain]}` const nextConfig = { diff --git a/packages/core-utils/package.json b/packages/core-utils/package.json index ec7ad4020352..3b54061c0369 100644 --- a/packages/core-utils/package.json +++ b/packages/core-utils/package.json @@ -11,7 +11,6 @@ "all": "pnpm clean && pnpm build && pnpm test && pnpm lint:fix && pnpm lint", "build": "tsc -p tsconfig.json", "clean": "rimraf dist/ ./tsconfig.tsbuildinfo", - "preinstall": "npx only-allow pnpm", "lint": "pnpm lint:fix && pnpm lint:check", "lint:check": "eslint . --max-warnings=0", "lint:fix": "pnpm lint:check --fix", @@ -49,7 +48,7 @@ "node-fetch": "^2.6.7" }, "devDependencies": { - "@types/node": "^20.8.9", + "@types/node": "^20.11.17", "mocha": "^10.2.0" } } diff --git a/packages/fee-estimation/README.md b/packages/fee-estimation/README.md index ca2952fed8ae..6b9bff2ad273 100644 --- a/packages/fee-estimation/README.md +++ b/packages/fee-estimation/README.md @@ -56,7 +56,7 @@ const fees = await estimateFees({ */ functionName: 'burn', abi: optimistABI, - args: [tokenid], + args: [tokenId], account: optimistOwnerAddress, to: '0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5', }) diff --git a/packages/fee-estimation/package.json b/packages/fee-estimation/package.json index 6cbc34b80625..e39b1b8bdd77 100644 --- a/packages/fee-estimation/package.json +++ b/packages/fee-estimation/package.json @@ -35,18 +35,18 @@ }, "devDependencies": { "@eth-optimism/contracts-ts": "workspace:^", - "@testing-library/jest-dom": "^6.1.4", + "@testing-library/jest-dom": "^6.4.2", "@testing-library/react-hooks": "^8.0.1", - "@vitest/coverage-istanbul": "^0.34.6", - "abitype": "^0.10.1", + "@vitest/coverage-istanbul": "^1.2.2", + "abitype": "^1.0.2", "isomorphic-fetch": "^3.0.0", "jest-dom": "link:@types/@testing-library/jest-dom", - "jsdom": "^22.1.0", - "tsup": "^7.2.0", - "typescript": "^5.2.2", - "viem": "^1.18.0", - "vite": "^4.5.0", - "vitest": "^0.34.2" + "jsdom": "^24.0.0", + "tsup": "^8.0.1", + "typescript": "^5.3.3", + "viem": "^2.7.19", + "vite": "^5.1.5", + "vitest": "^1.2.2" }, "peerDependencies": { "viem": "^0.3.30" diff --git a/packages/fee-estimation/src/estimateFees.ts b/packages/fee-estimation/src/estimateFees.ts index 246c2abbb30d..4a7ba0f1f191 100644 --- a/packages/fee-estimation/src/estimateFees.ts +++ b/packages/fee-estimation/src/estimateFees.ts @@ -58,7 +58,7 @@ const knownChains = [ type ClientOptions = // for known chains like base don't require an rpcUrl | { - chainId: typeof knownChains[number] + chainId: (typeof knownChains)[number] rpcUrl?: string nativeCurrency?: chains.Chain['nativeCurrency'] } diff --git a/packages/sdk/CHANGELOG.md b/packages/sdk/CHANGELOG.md index 820020bd7af3..3064cc2591c0 100644 --- a/packages/sdk/CHANGELOG.md +++ b/packages/sdk/CHANGELOG.md @@ -1,5 +1,56 @@ # @eth-optimism/sdk +## 3.2.2 + +### Patch Changes + +- [#9805](https://github.com/ethereum-optimism/optimism/pull/9805) [`3ccd12fe5c8c4c5a6acbf370d474ffa8db816562`](https://github.com/ethereum-optimism/optimism/commit/3ccd12fe5c8c4c5a6acbf370d474ffa8db816562) Thanks [@alecananian](https://github.com/alecananian)! - Fixed an issue where Vercel builds were failing due to the `preinstall` command. + +## 3.2.1 + +### Patch Changes + +- [#9663](https://github.com/ethereum-optimism/optimism/pull/9663) [`a1329f21f33ecafe409990964d3af7bf05a8a756`](https://github.com/ethereum-optimism/optimism/commit/a1329f21f33ecafe409990964d3af7bf05a8a756) Thanks [@smartcontracts](https://github.com/smartcontracts)! - Fixes a bug in the SDK that would sometimes cause proof submission reverts. + +## 3.2.0 + +### Minor Changes + +- [#9325](https://github.com/ethereum-optimism/optimism/pull/9325) [`44a2d9cec5f3b309b723b3e4dd8d29b5b70f1cc8`](https://github.com/ethereum-optimism/optimism/commit/44a2d9cec5f3b309b723b3e4dd8d29b5b70f1cc8) Thanks [@smartcontracts](https://github.com/smartcontracts)! - Updates the SDK to support FPAC in a backwards compatible way. + +### Patch Changes + +- [#9367](https://github.com/ethereum-optimism/optimism/pull/9367) [`d99d425a4f73fba19ffcf180deb0ef48ff3b9a6a`](https://github.com/ethereum-optimism/optimism/commit/d99d425a4f73fba19ffcf180deb0ef48ff3b9a6a) Thanks [@smartcontracts](https://github.com/smartcontracts)! - Fixes a bug in the SDK for finalizing fpac withdrawals. + +- [#9244](https://github.com/ethereum-optimism/optimism/pull/9244) [`73a748575e7c3d67c293814a12bf41eee216163c`](https://github.com/ethereum-optimism/optimism/commit/73a748575e7c3d67c293814a12bf41eee216163c) Thanks [@roninjin10](https://github.com/roninjin10)! - Added maintence mode warning to sdk + +- Updated dependencies [[`79effc52e8b82d15b5eda43acf540ac6c5f8d5d7`](https://github.com/ethereum-optimism/optimism/commit/79effc52e8b82d15b5eda43acf540ac6c5f8d5d7)]: + - @eth-optimism/contracts-bedrock@0.17.1 + +## 3.1.8 + +### Patch Changes + +- [#8902](https://github.com/ethereum-optimism/optimism/pull/8902) [`18becd7e4`](https://github.com/ethereum-optimism/optimism/commit/18becd7e457577c105f6bc03597e069334cb7433) Thanks [@smartcontracts](https://github.com/smartcontracts)! - Fixes a bug in the SDK that would fail if unsupported fields were provided. + +## 3.1.7 + +### Patch Changes + +- [#8836](https://github.com/ethereum-optimism/optimism/pull/8836) [`6ec80fd19`](https://github.com/ethereum-optimism/optimism/commit/6ec80fd19d9155b17a0873672fb095d323f6e8fb) Thanks [@smartcontracts](https://github.com/smartcontracts)! - Fixes a bug in l1 gas cost estimation. + +## 3.1.6 + +### Patch Changes + +- [#8212](https://github.com/ethereum-optimism/optimism/pull/8212) [`dd0e46986`](https://github.com/ethereum-optimism/optimism/commit/dd0e46986f19dcceb304fc48f2bd410685ecd179) Thanks [@smartcontracts](https://github.com/smartcontracts)! - Simplifies getMessageStatus to use an O(1) lookup instead of an event query + +## 3.1.5 + +### Patch Changes + +- [#8155](https://github.com/ethereum-optimism/optimism/pull/8155) [`2534eabb5`](https://github.com/ethereum-optimism/optimism/commit/2534eabb50afe76f176407f83cc1f1c606e6de69) Thanks [@smartcontracts](https://github.com/smartcontracts)! - Fixed bug with tokenBridge checks throwing + ## 3.1.4 ### Patch Changes diff --git a/packages/sdk/README.md b/packages/sdk/README.md index 284aa86cd55d..46b37ec96f2d 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -5,6 +5,23 @@ The `@eth-optimism/sdk` package provides a set of tools for interacting with Optimism. +## Warning!!! + +`@eth-optimism/sdk` has been superseded by `op-viem`. For most developers we suggest you migrate to [viem](https://viem.sh/op-stack) which has native built in op-stack support built in. It also has additional benefits. + +**The OP Labs team has no plans to update @eth-optimism/sdk and it is in maintenance mode at the moment** + +- an intuitive API that learned from this package and is now revamped +- great treeshaking with a 10x+ improvement to bundlesize +- Better performance +- Updated to use the latest op stack contracts. At times it will save you gas compared to using viem. + +If viem does not have what you need please let us know by opening an issue in the viem repo or here. Letting us know helps us advocate to upstream more functionality to viem. Viem is missing the following functionality: + +- ERC20 support + +If viem doesn't have what you need, the extensions for viem, [op-viem extensions](https://github.com/base-org/op-viem), likely have it too. + ## Installation ``` @@ -15,6 +32,10 @@ npm install @eth-optimism/sdk You can find auto-generated API documentation over at [sdk.optimism.io](https://sdk.optimism.io). +## Contributing + +Most of the core functionality is in the [CrossChainMessenger](./src/cross-chain-messenger.ts) file. + ## Using the SDK ### CrossChainMessenger diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 8588f45b2590..f7711ff5f2d2 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@eth-optimism/sdk", - "version": "3.1.4", + "version": "3.2.2", "description": "[Optimism] Tools for working with Optimism", "main": "dist/index", "types": "dist/index", @@ -12,7 +12,6 @@ "all": "pnpm clean && pnpm build && pnpm test && pnpm lint:fix && pnpm lint", "build": "tsc -p tsconfig.json", "clean": "rimraf dist/ ./tsconfig.tsbuildinfo", - "preinstall": "npx only-allow pnpm", "lint": "pnpm lint:fix && pnpm lint:check", "lint:check": "eslint . --max-warnings=0", "lint:fix": "pnpm lint:check --fix", @@ -41,23 +40,24 @@ "@ethersproject/transactions": "^5.7.0", "@nomiclabs/hardhat-ethers": "^2.2.3", "@nomiclabs/hardhat-waffle": "^2.0.1", - "@types/chai": "^4.3.8", - "@types/chai-as-promised": "^7.1.5", - "@types/mocha": "^10.0.3", - "@types/node": "^20.8.9", + "@types/chai": "^4.3.11", + "@types/chai-as-promised": "^7.1.8", + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.17", + "@types/semver": "^7.5.7", "chai-as-promised": "^7.1.1", "ethereum-waffle": "^4.0.10", "ethers": "^5.7.2", - "hardhat": "^2.18.3", - "hardhat-deploy": "^0.11.43", + "hardhat": "^2.20.1", + "hardhat-deploy": "^0.11.44", "isomorphic-fetch": "^3.0.0", "mocha": "^10.2.0", "nyc": "^15.1.0", - "ts-node": "^10.9.1", - "typedoc": "^0.25.2", - "typescript": "^5.2.2", - "viem": "^1.18.0", - "vitest": "^0.34.2", + "ts-node": "^10.9.2", + "typedoc": "^0.25.7", + "typescript": "^5.3.3", + "viem": "^2.7.19", + "vitest": "^1.2.2", "zod": "^3.22.4" }, "dependencies": { @@ -65,8 +65,9 @@ "@eth-optimism/contracts-bedrock": "workspace:*", "@eth-optimism/core-utils": "workspace:*", "lodash": "^4.17.21", - "merkletreejs": "^0.3.10", - "rlp": "^2.2.7" + "merkletreejs": "^0.3.11", + "rlp": "^2.2.7", + "semver": "^7.6.0" }, "peerDependencies": { "ethers": "^5" diff --git a/packages/sdk/src/adapters/standard-bridge.ts b/packages/sdk/src/adapters/standard-bridge.ts index 41e71c360385..46d30880611b 100644 --- a/packages/sdk/src/adapters/standard-bridge.ts +++ b/packages/sdk/src/adapters/standard-bridge.ts @@ -156,46 +156,33 @@ export class StandardBridgeAdapter implements IBridgeAdapter { l1Token: AddressLike, l2Token: AddressLike ): Promise { - try { - const contract = new Contract( - toAddress(l2Token), - optimismMintableERC20.abi, - this.messenger.l2Provider - ) - // Don't support ETH deposits or withdrawals via this bridge. - if ( - hexStringEquals(toAddress(l1Token), ethers.constants.AddressZero) || - hexStringEquals(toAddress(l2Token), predeploys.OVM_ETH) - ) { - return false - } - - // Make sure the L1 token matches. - const remoteL1Token = await contract.l1Token() + const contract = new Contract( + toAddress(l2Token), + optimismMintableERC20.abi, + this.messenger.l2Provider + ) + // Don't support ETH deposits or withdrawals via this bridge. + if ( + hexStringEquals(toAddress(l1Token), ethers.constants.AddressZero) || + hexStringEquals(toAddress(l2Token), predeploys.OVM_ETH) + ) { + return false + } - if (!hexStringEquals(remoteL1Token, toAddress(l1Token))) { - return false - } + // Make sure the L1 token matches. + const remoteL1Token = await contract.l1Token() - // Make sure the L2 bridge matches. - const remoteL2Bridge = await contract.l2Bridge() - if (!hexStringEquals(remoteL2Bridge, this.l2Bridge.address)) { - return false - } + if (!hexStringEquals(remoteL1Token, toAddress(l1Token))) { + return false + } - return true - } catch (err) { - // If the L2 token is not an L2StandardERC20, it may throw an error. If there's a call - // exception then we assume that the token is not supported. Other errors are thrown. Since - // the JSON-RPC API is not well-specified, we need to handle multiple possible error codes. - if ( - !err?.message?.toString().includes('CALL_EXCEPTION') && - !err?.stack?.toString().includes('execution reverted') - ) { - console.error('Unexpected error when checking bridge', err) - } + // Make sure the L2 bridge matches. + const remoteL2Bridge = await contract.l2Bridge() + if (!hexStringEquals(remoteL2Bridge, this.l2Bridge.address)) { return false } + + return true } public async approval( diff --git a/packages/sdk/src/cross-chain-messenger.ts b/packages/sdk/src/cross-chain-messenger.ts index fa227c181ba9..5483df77307f 100644 --- a/packages/sdk/src/cross-chain-messenger.ts +++ b/packages/sdk/src/cross-chain-messenger.ts @@ -19,7 +19,6 @@ import { remove0x, toHexString, toRpcHexString, - hashCrossDomainMessage, encodeCrossDomainMessageV0, encodeCrossDomainMessageV1, BedrockOutputData, @@ -32,6 +31,7 @@ import { } from '@eth-optimism/core-utils' import { getContractInterface, predeploys } from '@eth-optimism/contracts' import * as rlp from 'rlp' +import semver from 'semver' import { OEContracts, @@ -72,6 +72,8 @@ import { DEPOSIT_CONFIRMATION_BLOCKS, CHAIN_BLOCK_TIMES, hashMessageHash, + getContractInterfaceBedrock, + toJsonRpcProvider, } from './utils' export class CrossChainMessenger { @@ -120,6 +122,11 @@ export class CrossChainMessenger { */ public bedrock: boolean + /** + * Cache for output root validation. Output roots are expensive to verify, so we cache them. + */ + private _outputCache: Array<{ root: string; valid: boolean }> = [] + /** * Creates a new CrossChainProvider instance. * @@ -228,6 +235,29 @@ export class CrossChainMessenger { } } + /** + * Uses portal version to determine if the messenger is using fpac contracts. Better not to cache + * this value as it will change during the fpac upgrade and we want clients to automatically + * begin using the new logic without throwing any errors. + * + * @returns Whether or not the messenger is using fpac contracts. + */ + public async fpac(): Promise { + if ( + this.contracts.l1.OptimismPortal.address === ethers.constants.AddressZero + ) { + // Only really relevant for certain SDK tests where the portal is not deployed. We should + // probably just update the tests so the portal gets deployed but feels like it's out of + // scope for the FPAC changes. + return false + } else { + return semver.gte( + await this.contracts.l1.OptimismPortal.version(), + '3.0.0' + ) + } + } + /** * Retrieves all cross chain messages sent within a given transaction. * @@ -490,8 +520,17 @@ export class CrossChainMessenger { ): Promise { const bridges: IBridgeAdapter[] = [] for (const bridge of Object.values(this.bridges)) { - if (await bridge.supportsTokenPair(l1Token, l2Token)) { - bridges.push(bridge) + try { + if (await bridge.supportsTokenPair(l1Token, l2Token)) { + bridges.push(bridge) + } + } catch (err) { + if ( + !err?.message?.toString().includes('CALL_EXCEPTION') && + !err?.stack?.toString().includes('execution reverted') + ) { + console.error('Unexpected error when checking bridge', err) + } } } @@ -658,25 +697,55 @@ export class CrossChainMessenger { toBlockOrBlockHash?: BlockTag ): Promise { const resolved = await this.toCrossChainMessage(message, messageIndex) - const receipt = await this.getMessageReceipt( - resolved, - messageIndex, - fromBlockOrBlockHash, - toBlockOrBlockHash + // legacy withdrawals relayed prebedrock are v1 + const messageHashV0 = hashCrossDomainMessagev0( + resolved.target, + resolved.sender, + resolved.message, + resolved.messageNonce ) + // bedrock withdrawals are v1 + // legacy withdrawals relayed postbedrock are v1 + // there is no good way to differentiate between the two types of legacy + // so what we will check for both + const messageHashV1 = hashCrossDomainMessagev1( + resolved.messageNonce, + resolved.sender, + resolved.target, + resolved.value, + resolved.minGasLimit, + resolved.message + ) + + // Here we want the messenger that will receive the message, not the one that sent it. + const messenger = + resolved.direction === MessageDirection.L1_TO_L2 + ? this.contracts.l2.L2CrossDomainMessenger + : this.contracts.l1.L1CrossDomainMessenger + + const success = + (await messenger.successfulMessages(messageHashV0)) || + (await messenger.successfulMessages(messageHashV1)) + + // Avoid the extra query if we already know the message was successful. + if (success) { + return MessageStatus.RELAYED + } + + const failure = + (await messenger.failedMessages(messageHashV0)) || + (await messenger.failedMessages(messageHashV1)) if (resolved.direction === MessageDirection.L1_TO_L2) { - if (receipt === null) { - return MessageStatus.UNCONFIRMED_L1_TO_L2_MESSAGE + if (failure) { + return MessageStatus.FAILED_L1_TO_L2_MESSAGE } else { - if (receipt.receiptStatus === MessageReceiptStatus.RELAYED_SUCCEEDED) { - return MessageStatus.RELAYED - } else { - return MessageStatus.FAILED_L1_TO_L2_MESSAGE - } + return MessageStatus.UNCONFIRMED_L1_TO_L2_MESSAGE } } else { - if (receipt === null) { + if (failure) { + return MessageStatus.READY_FOR_RELAY + } else { let timestamp: number if (this.bedrock) { const output = await this.getMessageBedrockOutput( @@ -693,11 +762,16 @@ export class CrossChainMessenger { messageIndex ) + // Pick portal based on FPAC compatibility. + const portal = (await this.fpac()) + ? this.contracts.l1.OptimismPortal2 + : this.contracts.l1.OptimismPortal + // Attempt to fetch the proven withdrawal. - const provenWithdrawal = - await this.contracts.l1.OptimismPortal.provenWithdrawals( - hashLowLevelMessage(withdrawal) - ) + const provenWithdrawal = await portal.provenWithdrawals( + hashLowLevelMessage(withdrawal) + ) + // If the withdrawal hash has not been proven on L1, // return `READY_TO_PROVE` if (provenWithdrawal.timestamp.eq(BigNumber.from(0))) { @@ -720,19 +794,57 @@ export class CrossChainMessenger { timestamp = block.timestamp } - const challengePeriod = await this.getChallengePeriodSeconds() - const latestBlock = await this.l1Provider.getBlock('latest') + if (await this.fpac()) { + // Convert the message to the low level message that was proven. + const withdrawal = await this.toLowLevelMessage( + resolved, + messageIndex + ) - if (timestamp + challengePeriod > latestBlock.timestamp) { - return MessageStatus.IN_CHALLENGE_PERIOD - } else { - return MessageStatus.READY_FOR_RELAY - } - } else { - if (receipt.receiptStatus === MessageReceiptStatus.RELAYED_SUCCEEDED) { - return MessageStatus.RELAYED + // Get the withdrawal hash. + const withdrawalHash = hashLowLevelMessage(withdrawal) + + // Grab the proven withdrawal data. + const provenWithdrawal = + await this.contracts.l1.OptimismPortal2.provenWithdrawals( + withdrawalHash + ) + + // Attach to the FaultDisputeGame. + const game = new ethers.Contract( + provenWithdrawal.disputeGameProxy, + getContractInterfaceBedrock('FaultDisputeGame'), + this.l1SignerOrProvider + ) + + // Check if the game resolved to status 1 = "CHALLENGER_WINS". If so, the withdrawal was + // proven against a proposal that was invalidated and will need to be reproven. We throw + // an error here instead of creating a new status mostly because it's easier to integrate + // into the SDK. + const status = await game.status() + if (status === 1) { + throw new Error(`withdrawal proposal was invalidated, must reprove`) + } + + try { + // If this doesn't revert then we should be fine to relay. + await this.contracts.l1.OptimismPortal2.checkWithdrawal( + hashLowLevelMessage(withdrawal) + ) + + return MessageStatus.READY_FOR_RELAY + } catch (err) { + return MessageStatus.IN_CHALLENGE_PERIOD + } } else { - return MessageStatus.READY_FOR_RELAY + const challengePeriod = await this.getChallengePeriodSeconds() + const latestBlock = await this.l1Provider.getBlock('latest') + + if (timestamp + challengePeriod > latestBlock.timestamp) { + return MessageStatus.IN_CHALLENGE_PERIOD + } else { + return MessageStatus.READY_FOR_RELAY + } } } } @@ -1180,29 +1292,157 @@ export class CrossChainMessenger { throw new Error(`cannot get a state root for an L1 to L2 message`) } - // Try to find the output index that corresponds to the block number attached to the message. - // We'll explicitly handle "cannot get output" errors as a null return value, but anything else - // needs to get thrown. Might need to revisit this in the future to be a little more robust - // when connected to RPCs that don't return nice error messages. + let proposal: any let l2OutputIndex: BigNumber - try { - l2OutputIndex = - await this.contracts.l1.L2OutputOracle.getL2OutputIndexAfter( - resolved.blockNumber + if (await this.fpac()) { + // Get the respected game type from the portal. + const gameType = + await this.contracts.l1.OptimismPortal2.respectedGameType() + + // Get the total game count from the DisputeGameFactory since that will give us the end of + // the array that we're searching over. We'll then use that to find the latest games. + const gameCount = await this.contracts.l1.DisputeGameFactory.gameCount() + + // Find the latest 100 games (or as many as we can up to 100). + const latestGames = + await this.contracts.l1.DisputeGameFactory.findLatestGames( + gameType, + Math.max(0, gameCount.sub(1).toNumber()), + Math.min(100, gameCount.toNumber()) ) - } catch (err) { - if (err.message.includes('L2OutputOracle: cannot get output')) { + + // Find all games that are for proposals about blocks newer than the message block. + const matches: any[] = [] + for (const game of latestGames) { + try { + const [blockNumber] = ethers.utils.defaultAbiCoder.decode( + ['uint256'], + game.extraData + ) + if (blockNumber.gte(resolved.blockNumber)) { + matches.push({ + ...game, + l2BlockNumber: blockNumber, + }) + } + } catch (err) { + // If we can't decode the extra data then we just skip this game. + continue + } + } + + // Shuffle the list of matches. We shuffle here to avoid potential DoS vectors where the + // latest games are all invalid and the SDK would be forced to make a bunch of archive calls. + for (let i = matches.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)) + ;[matches[i], matches[j]] = [matches[j], matches[i]] + } + + // Now we verify the proposals in the matches array. + let match: any + for (const option of matches) { + // Use the cache if we can. + const cached = this._outputCache.find((other) => { + return other.root === option.rootClaim + }) + + // Skip if we can use the cached. + if (cached) { + if (cached.valid) { + match = option + break + } else { + continue + } + } + + // If the cache ever gets to 10k elements, clear out the first half. Works well enough + // since the cache will generally tend to be used in a FIFO manner. + if (this._outputCache.length > 10000) { + this._outputCache = this._outputCache.slice(5000) + } + + // We didn't hit the cache so we're going to have to do the work. + try { + // Make sure this is a JSON RPC provider. + const provider = toJsonRpcProvider(this.l2Provider) + + // Grab the block and storage proof at the same time. + const [block, proof] = await Promise.all([ + provider.send('eth_getBlockByNumber', [ + toRpcHexString(option.l2BlockNumber), + false, + ]), + makeStateTrieProof( + provider, + option.l2BlockNumber, + this.contracts.l2.OVM_L2ToL1MessagePasser.address, + ethers.constants.HashZero + ), + ]) + + // Compute the output. + const output = ethers.utils.solidityKeccak256( + ['bytes32', 'bytes32', 'bytes32', 'bytes32'], + [ + ethers.constants.HashZero, + block.stateRoot, + proof.storageRoot, + block.hash, + ] + ) + + // If the output matches the proposal then we're good. + if (output === option.rootClaim) { + this._outputCache.push({ root: option.rootClaim, valid: true }) + match = option + break + } else { + this._outputCache.push({ root: option.rootClaim, valid: false }) + } + } catch (err) { + // Just skip this option, whatever. If it was a transient error then we'll try again in + // the next loop iteration. If it was a permanent error then we'll get the same thing. + continue + } + } + + // If there's no match then we can't prove the message to the portal. + if (!match) { return null - } else { - throw err } - } - // Now pull the proposal out given the output index. Should always work as long as the above - // codepath completed successfully. - const proposal = await this.contracts.l1.L2OutputOracle.getL2Output( - l2OutputIndex - ) + // Put the result into the same format as the old logic for now to reduce added code. + l2OutputIndex = match.index + proposal = { + outputRoot: match.rootClaim, + timestamp: match.timestamp, + l2BlockNumber: match.l2BlockNumber, + } + } else { + // Try to find the output index that corresponds to the block number attached to the message. + // We'll explicitly handle "cannot get output" errors as a null return value, but anything else + // needs to get thrown. Might need to revisit this in the future to be a little more robust + // when connected to RPCs that don't return nice error messages. + try { + l2OutputIndex = + await this.contracts.l1.L2OutputOracle.getL2OutputIndexAfter( + resolved.blockNumber + ) + } catch (err) { + if (err.message.includes('L2OutputOracle: cannot get output')) { + return null + } else { + throw err + } + } + + // Now pull the proposal out given the output index. Should always work as long as the above + // codepath completed successfully. + proposal = await this.contracts.l1.L2OutputOracle.getL2Output( + l2OutputIndex + ) + } // Format everything and return it nicely. return { @@ -1441,7 +1681,7 @@ export class CrossChainMessenger { ) const stateTrieProof = await makeStateTrieProof( - this.l2Provider as ethers.providers.JsonRpcProvider, + toJsonRpcProvider(this.l2Provider), resolved.blockNumber, this.contracts.l2.OVM_L2ToL1MessagePasser.address, messageSlot @@ -1487,16 +1727,16 @@ export class CrossChainMessenger { const hash = hashLowLevelMessage(withdrawal) const messageSlot = hashMessageHash(hash) + const provider = toJsonRpcProvider(this.l2Provider) + const stateTrieProof = await makeStateTrieProof( - this.l2Provider as ethers.providers.JsonRpcProvider, + provider, output.l2BlockNumber, this.contracts.l2.BedrockMessagePasser.address, messageSlot ) - const block = await ( - this.l2Provider as ethers.providers.JsonRpcProvider - ).send('eth_getBlockByNumber', [ + const block = await provider.send('eth_getBlockByNumber', [ toRpcHexString(output.l2BlockNumber), false, ]) diff --git a/packages/sdk/src/interfaces/types.ts b/packages/sdk/src/interfaces/types.ts index c31d9e61f3aa..f6b6b1c4eac0 100644 --- a/packages/sdk/src/interfaces/types.ts +++ b/packages/sdk/src/interfaces/types.ts @@ -50,6 +50,9 @@ export interface OEL1Contracts { // Bedrock OptimismPortal: Contract L2OutputOracle: Contract + // FPAC + OptimismPortal2?: Contract + DisputeGameFactory?: Contract } /** diff --git a/packages/sdk/src/l2-provider.ts b/packages/sdk/src/l2-provider.ts index 36b689693055..6c410d2b2f47 100644 --- a/packages/sdk/src/l2-provider.ts +++ b/packages/sdk/src/l2-provider.ts @@ -72,12 +72,19 @@ export const estimateL1Gas = async ( const gpo = connectGasPriceOracle(l2Provider) return gpo.getL1GasUsed( serialize({ - data: tx.data, to: tx.to, + gasLimit: tx.gasLimit, gasPrice: tx.gasPrice, + maxFeePerGas: tx.maxFeePerGas, + maxPriorityFeePerGas: tx.maxPriorityFeePerGas, + data: tx.data, + value: tx.value, + chainId: tx.chainId, type: tx.type, - gasLimit: tx.gasLimit, - nonce: await getNonceForTx(l2Provider, tx), + accessList: tx.accessList, + nonce: tx.nonce + ? BigNumber.from(tx.nonce).toNumber() + : await getNonceForTx(l2Provider, tx), }) ) } @@ -96,12 +103,19 @@ export const estimateL1GasCost = async ( const gpo = connectGasPriceOracle(l2Provider) return gpo.getL1Fee( serialize({ - data: tx.data, to: tx.to, + gasLimit: tx.gasLimit, gasPrice: tx.gasPrice, + maxFeePerGas: tx.maxFeePerGas, + maxPriorityFeePerGas: tx.maxPriorityFeePerGas, + data: tx.data, + value: tx.value, + chainId: tx.chainId, type: tx.type, - gasLimit: tx.gasLimit, - nonce: await getNonceForTx(l2Provider, tx), + accessList: tx.accessList, + nonce: tx.nonce + ? BigNumber.from(tx.nonce).toNumber() + : await getNonceForTx(l2Provider, tx), }) ) } diff --git a/packages/sdk/src/utils/chain-constants.ts b/packages/sdk/src/utils/chain-constants.ts index 30cea4a5a618..c9dccd49b214 100644 --- a/packages/sdk/src/utils/chain-constants.ts +++ b/packages/sdk/src/utils/chain-constants.ts @@ -1,49 +1,36 @@ import { predeploys } from '@eth-optimism/core-utils' import { ethers } from 'ethers' -import portalArtifactsMainnet from '@eth-optimism/contracts-bedrock/deployments/mainnet/OptimismPortalProxy.json' -import portalArtifactsGoerli from '@eth-optimism/contracts-bedrock/deployments/goerli/OptimismPortalProxy.json' -import portalArtifactsSepolia from '@eth-optimism/contracts-bedrock/deployments/sepolia/OptimismPortalProxy.json' -import l2OutputOracleArtifactsMainnet from '@eth-optimism/contracts-bedrock/deployments/mainnet/L2OutputOracleProxy.json' -import l2OutputOracleArtifactsGoerli from '@eth-optimism/contracts-bedrock/deployments/goerli/L2OutputOracleProxy.json' -import l2OutputOracleArtifactsSepolia from '@eth-optimism/contracts-bedrock/deployments/sepolia/L2OutputOracleProxy.json' -import addressManagerArtifactMainnet from '@eth-optimism/contracts-bedrock/deployments/mainnet/AddressManager.json' -import addressManagerArtifactGoerli from '@eth-optimism/contracts-bedrock/deployments/goerli/AddressManager.json' -import addressManagerArtifactSepolia from '@eth-optimism/contracts-bedrock/deployments/sepolia/AddressManager.json' -import l1StandardBridgeArtifactMainnet from '@eth-optimism/contracts-bedrock/deployments/mainnet/L1StandardBridgeProxy.json' -import l1StandardBridgeArtifactGoerli from '@eth-optimism/contracts-bedrock/deployments/goerli/L1StandardBridgeProxy.json' -import l1StandardBridgeArtifactSepolia from '@eth-optimism/contracts-bedrock/deployments/sepolia/L1StandardBridgeProxy.json' -import l1CrossDomainMessengerArtifactMainnet from '@eth-optimism/contracts-bedrock/deployments/mainnet/L1CrossDomainMessengerProxy.json' -import l1CrossDomainMessengerArtifactGoerli from '@eth-optimism/contracts-bedrock/deployments/goerli/L1CrossDomainMessengerProxy.json' -import l1CrossDomainMessengerArtifactSepolia from '@eth-optimism/contracts-bedrock/deployments/sepolia/L1CrossDomainMessengerProxy.json' + +// The addresses below should be for the proxy if it is a proxied contract. const portalAddresses = { - mainnet: portalArtifactsMainnet.address, - goerli: portalArtifactsGoerli.address, - sepolia: portalArtifactsSepolia.address, + mainnet: '0xbEb5Fc579115071764c7423A4f12eDde41f106Ed', + goerli: '0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383', + sepolia: '0x16Fc5058F25648194471939df75CF27A2fdC48BC', } const l2OutputOracleAddresses = { - mainnet: l2OutputOracleArtifactsMainnet.address, - goerli: l2OutputOracleArtifactsGoerli.address, - sepolia: l2OutputOracleArtifactsSepolia.address, + mainnet: '0xdfe97868233d1aa22e815a266982f2cf17685a27', + goerli: '0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0', + sepolia: '0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F', } const addressManagerAddresses = { - mainnet: addressManagerArtifactMainnet.address, - goerli: addressManagerArtifactGoerli.address, - sepolia: addressManagerArtifactSepolia.address, + mainnet: '0xdE1FCfB0851916CA5101820A69b13a4E276bd81F', + goerli: '0xa6f73589243a6A7a9023b1Fa0651b1d89c177111', + sepolia: '0x9bFE9c5609311DF1c011c47642253B78a4f33F4B', } const l1StandardBridgeAddresses = { - mainnet: l1StandardBridgeArtifactMainnet.address, - goerli: l1StandardBridgeArtifactGoerli.address, - sepolia: l1StandardBridgeArtifactSepolia.address, + mainnet: '0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1', + goerli: '0x636Af16bf2f682dD3109e60102b8E1A089FedAa8', + sepolia: '0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1', } const l1CrossDomainMessengerAddresses = { - mainnet: l1CrossDomainMessengerArtifactMainnet.address, - goerli: l1CrossDomainMessengerArtifactGoerli.address, - sepolia: l1CrossDomainMessengerArtifactSepolia.address, + mainnet: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1', + goerli: '0x5086d1eEF304eb5284A0f6720f79403b4e9bE294', + sepolia: '0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef', } // legacy @@ -133,9 +120,16 @@ const getL1ContractsByNetworkName = (network: string): OEL1ContractsLike => { BondManager: ethers.constants.AddressZero, OptimismPortal: portalAddresses[network], L2OutputOracle: l2OutputOracleAddresses[network], + OptimismPortal2: portalAddresses[network], + DisputeGameFactory: ethers.constants.AddressZero, } } +/** + * List of contracts that are ignorable when checking for contracts on a given network. + */ +export const IGNORABLE_CONTRACTS = ['OptimismPortal2', 'DisputeGameFactory'] + /** * Mapping of L1 chain IDs to the appropriate contract addresses for the OE deployments to the * given network. Simplifies the process of getting the correct contract addresses for a given @@ -170,6 +164,8 @@ export const CONTRACT_ADDRESSES: { // FIXME OptimismPortal: '0x0000000000000000000000000000000000000000' as const, L2OutputOracle: '0x0000000000000000000000000000000000000000' as const, + OptimismPortal2: '0x0000000000000000000000000000000000000000' as const, + DisputeGameFactory: '0x0000000000000000000000000000000000000000' as const, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, }, @@ -186,6 +182,8 @@ export const CONTRACT_ADDRESSES: { BondManager: '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707' as const, OptimismPortal: '0x0000000000000000000000000000000000000000' as const, L2OutputOracle: '0x0000000000000000000000000000000000000000' as const, + OptimismPortal2: '0x0000000000000000000000000000000000000000' as const, + DisputeGameFactory: '0x0000000000000000000000000000000000000000' as const, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, }, @@ -202,6 +200,8 @@ export const CONTRACT_ADDRESSES: { BondManager: '0x0000000000000000000000000000000000000000' as const, OptimismPortal: '0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8' as const, L2OutputOracle: '0x3A234299a14De50027eA65dCdf1c0DaC729e04A6' as const, + OptimismPortal2: '0x0000000000000000000000000000000000000000' as const, + DisputeGameFactory: '0x0000000000000000000000000000000000000000' as const, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, }, @@ -218,6 +218,8 @@ export const CONTRACT_ADDRESSES: { BondManager: '0x0000000000000000000000000000000000000000' as const, OptimismPortal: '0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA' as const, L2OutputOracle: '0x2A35891ff30313CcFa6CE88dcf3858bb075A2298' as const, + OptimismPortal2: '0x0000000000000000000000000000000000000000' as const, + DisputeGameFactory: '0x0000000000000000000000000000000000000000' as const, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, }, @@ -234,6 +236,8 @@ export const CONTRACT_ADDRESSES: { BondManager: '0x0000000000000000000000000000000000000000' as const, OptimismPortal: '0x49f53e41452C74589E85cA1677426Ba426459e85' as const, L2OutputOracle: '0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254' as const, + OptimismPortal2: '0x0000000000000000000000000000000000000000' as const, + DisputeGameFactory: '0x0000000000000000000000000000000000000000' as const, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, }, @@ -250,6 +254,8 @@ export const CONTRACT_ADDRESSES: { BondManager: '0x0000000000000000000000000000000000000000' as const, OptimismPortal: '0x49048044D57e1C92A77f79988d21Fa8fAF74E97e' as const, L2OutputOracle: '0x56315b90c40730925ec5485cf004d835058518A0' as const, + OptimismPortal2: '0x0000000000000000000000000000000000000000' as const, + DisputeGameFactory: '0x0000000000000000000000000000000000000000' as const, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, }, @@ -267,6 +273,8 @@ export const CONTRACT_ADDRESSES: { BondManager: '0x0000000000000000000000000000000000000000' as const, OptimismPortal: '0xDb9F51790365e7dc196e7D072728df39Be958ACe' as const, L2OutputOracle: '0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00' as const, + OptimismPortal2: '0x0000000000000000000000000000000000000000' as const, + DisputeGameFactory: '0x0000000000000000000000000000000000000000' as const, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, }, @@ -283,6 +291,8 @@ export const CONTRACT_ADDRESSES: { BondManager: '0x0000000000000000000000000000000000000000' as const, OptimismPortal: '0x1a0ad011913A150f69f6A19DF447A0CfD9551054' as const, L2OutputOracle: '0x9E6204F750cD866b299594e2aC9eA824E2e5f95c' as const, + OptimismPortal2: '0x0000000000000000000000000000000000000000' as const, + DisputeGameFactory: '0x0000000000000000000000000000000000000000' as const, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, }, diff --git a/packages/sdk/src/utils/coercion.ts b/packages/sdk/src/utils/coercion.ts index eb5497f319bd..b57f8ba04418 100644 --- a/packages/sdk/src/utils/coercion.ts +++ b/packages/sdk/src/utils/coercion.ts @@ -53,6 +53,26 @@ export const toProvider = (provider: ProviderLike): Provider => { } } +/** + * Converts a ProviderLike into a JsonRpcProvider. + * + * @param provider ProviderLike to turn into a JsonRpcProvider. + * @returns Input as a JsonRpcProvider. + */ +export const toJsonRpcProvider = ( + provider: ProviderLike +): ethers.providers.JsonRpcProvider => { + const coerced = toProvider(provider) + if ('send' in coerced) { + // Existence of "send" is basically the only function that matters for determining if we can + // use this provider as a JsonRpcProvider, because "send" is the function that we usually want + // access to when we specifically care about having a JsonRpcProvider. + return coerced as ethers.providers.JsonRpcProvider + } else { + throw new Error('Invalid JsonRpcProvider, does not have "send" function') + } +} + /** * Pulls a transaction hash out of a TransactionLike object. * diff --git a/packages/sdk/src/utils/contracts.ts b/packages/sdk/src/utils/contracts.ts index 64d08fd940b6..a1c786a4631b 100644 --- a/packages/sdk/src/utils/contracts.ts +++ b/packages/sdk/src/utils/contracts.ts @@ -14,6 +14,9 @@ import l2ERC721Bridge from '@eth-optimism/contracts-bedrock/forge-artifacts/L2ER import l1Block from '@eth-optimism/contracts-bedrock/forge-artifacts/L1Block.sol/L1Block.json' import l2ToL1MessagePasser from '@eth-optimism/contracts-bedrock/forge-artifacts/L2ToL1MessagePasser.sol/L2ToL1MessagePasser.json' import gasPriceOracle from '@eth-optimism/contracts-bedrock/forge-artifacts/GasPriceOracle.sol/GasPriceOracle.json' +import disputeGameFactory from '@eth-optimism/contracts-bedrock/forge-artifacts/DisputeGameFactory.sol/DisputeGameFactory.json' +import optimismPortal2 from '@eth-optimism/contracts-bedrock/forge-artifacts/OptimismPortal2.sol/OptimismPortal2.json' +import faultDisputeGame from '@eth-optimism/contracts-bedrock/forge-artifacts/FaultDisputeGame.sol/FaultDisputeGame.json' import { toAddress } from './coercion' import { DeepPartial } from './type-utils' @@ -23,6 +26,7 @@ import { CONTRACT_ADDRESSES, DEFAULT_L2_CONTRACT_ADDRESSES, BRIDGE_ADAPTER_DATA, + IGNORABLE_CONTRACTS, } from './chain-constants' import { OEContracts, @@ -45,7 +49,9 @@ const NAME_REMAPPING = { BedrockMessagePasser: 'L2ToL1MessagePasser' as const, } -const getContractInterfaceBedrock = (name: string): ethers.utils.Interface => { +export const getContractInterfaceBedrock = ( + name: string +): ethers.utils.Interface => { let artifact: any = '' switch (name) { case 'Lib_AddressManager': @@ -94,6 +100,15 @@ const getContractInterfaceBedrock = (name: string): ethers.utils.Interface => { case 'GasPriceOracle': artifact = gasPriceOracle break + case 'DisputeGameFactory': + artifact = disputeGameFactory + break + case 'OptimismPortal2': + artifact = optimismPortal2 + break + case 'FaultDisputeGame': + artifact = faultDisputeGame + break } return new ethers.utils.Interface(artifact.abi) } @@ -119,11 +134,19 @@ export const getOEContract = ( signerOrProvider?: ethers.Signer | ethers.providers.Provider } = {} ): Contract => { + // Generally we want to throw an error if a contract address is not provided but there are some + // exceptions, particularly for contracts that are part of an upgrade that has not yet been + // deployed. It's OK to not provide an address for these contracts with the caveat that this may + // cause a runtime error if the contract does actually need to be used. const addresses = CONTRACT_ADDRESSES[l2ChainId] if (addresses === undefined && opts.address === undefined) { - throw new Error( - `cannot get contract ${contractName} for unknown L2 chain ID ${l2ChainId}, you must provide an address` - ) + if (IGNORABLE_CONTRACTS.includes(contractName)) { + return undefined + } else { + throw new Error( + `cannot get contract ${contractName} for unknown L2 chain ID ${l2ChainId}, you must provide an address` + ) + } } // Bedrock interfaces are backwards compatible. We can prefer Bedrock interfaces over legacy @@ -177,6 +200,8 @@ export const getAllOEContracts = ( BondManager: undefined, OptimismPortal: undefined, L2OutputOracle: undefined, + DisputeGameFactory: undefined, + OptimismPortal2: undefined, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, } diff --git a/packages/sdk/src/utils/merkle-utils.ts b/packages/sdk/src/utils/merkle-utils.ts index 50244328ddff..2080ca6306c9 100644 --- a/packages/sdk/src/utils/merkle-utils.ts +++ b/packages/sdk/src/utils/merkle-utils.ts @@ -6,6 +6,7 @@ import { toRpcHexString, } from '@eth-optimism/core-utils' import { MerkleTree } from 'merkletreejs' +import * as rlp from 'rlp' /** * Generates a Merkle proof (using the particular scheme we use within Lib_MerkleTree). @@ -44,6 +45,42 @@ export const makeMerkleTreeProof = ( return proof } +/** + * Fix for the case where the final proof element is less than 32 bytes and the element exists + * inside of a branch node. Current implementation of the onchain MPT contract can't handle this + * natively so we instead append an extra proof element to handle it instead. + * + * @param key Key that the proof is for. + * @param proof Proof to potentially modify. + * @returns Modified proof. + */ +export const maybeAddProofNode = (key: string, proof: string[]) => { + const modifiedProof = [...proof] + const finalProofEl = modifiedProof[modifiedProof.length - 1] + const finalProofElDecoded = rlp.decode(finalProofEl) as any + if (finalProofElDecoded.length === 17) { + for (const item of finalProofElDecoded) { + // Find any nodes located inside of the branch node. + if (Array.isArray(item)) { + // Check if the key inside the node matches the key we're looking for. We remove the first + // two characters (0x) and then we remove one more character (the first nibble) since this + // is the identifier for the type of node we're looking at. In this case we don't actually + // care what type of node it is because a branch node would only ever be the final proof + // element if (1) it includes the leaf node we're looking for or (2) it stores the value + // within itself. If (1) then this logic will work, if (2) then this won't find anything + // and we won't append any proof elements, which is exactly what we would want. + const suffix = toHexString(item[0]).slice(3) + if (key.endsWith(suffix)) { + modifiedProof.push(toHexString(rlp.encode(item))) + } + } + } + } + + // Return the modified proof. + return modifiedProof +} + /** * Generates a Merkle-Patricia trie proof for a given account and storage slot. * @@ -70,6 +107,11 @@ export const makeStateTrieProof = async ( toRpcHexString(blockNumber), ]) + proof.storageProof[0].proof = maybeAddProofNode( + ethers.utils.keccak256(slot), + proof.storageProof[0].proof + ) + return { accountProof: proof.accountProof, storageProof: proof.storageProof[0].proof, diff --git a/packages/sdk/tasks/deposit-erc20.ts b/packages/sdk/tasks/deposit-erc20.ts index cad8bd5d16c4..9b62aea1eac4 100644 --- a/packages/sdk/tasks/deposit-erc20.ts +++ b/packages/sdk/tasks/deposit-erc20.ts @@ -158,6 +158,8 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.') BondManager: ethers.constants.AddressZero, OptimismPortal: json.OptimismPortalProxy, L2OutputOracle: json.L2OutputOracleProxy, + OptimismPortal2: json.OptimismPortalProxy, + DisputeGameFactory: json.DisputeGameFactoryProxy, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, } as OEContractsLike diff --git a/packages/sdk/tasks/deposit-eth.ts b/packages/sdk/tasks/deposit-eth.ts index 62a9539f8ded..a6766a8646c3 100644 --- a/packages/sdk/tasks/deposit-eth.ts +++ b/packages/sdk/tasks/deposit-eth.ts @@ -103,6 +103,8 @@ task('deposit-eth', 'Deposits ether to L2.') BondManager: ethers.constants.AddressZero, OptimismPortal: json.OptimismPortalProxy, L2OutputOracle: json.L2OutputOracleProxy, + OptimismPortal2: json.OptimismPortalProxy, + DisputeGameFactory: json.DisputeGameFactoryProxy, }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, } as OEContractsLike diff --git a/packages/sdk/test/contracts/MockMessenger.sol b/packages/sdk/test/contracts/MockMessenger.sol index 724d90ed6778..1f7b3d8cf737 100644 --- a/packages/sdk/test/contracts/MockMessenger.sol +++ b/packages/sdk/test/contracts/MockMessenger.sol @@ -8,6 +8,8 @@ contract MockMessenger is ICrossDomainMessenger { } uint256 public nonce; + mapping (bytes32 => bool) public successfulMessages; + mapping (bytes32 => bool) public failedMessages; // Empty function to satisfy the interface. function sendMessage( @@ -81,6 +83,7 @@ contract MockMessenger is ICrossDomainMessenger { ) public { for (uint256 i = 0; i < _params.length; i++) { emit RelayedMessage(_params[i]); + successfulMessages[_params[i]] = true; } } @@ -89,6 +92,7 @@ contract MockMessenger is ICrossDomainMessenger { ) public { for (uint256 i = 0; i < _params.length; i++) { emit FailedRelayedMessage(_params[i]); + failedMessages[_params[i]] = true; } } } diff --git a/packages/sdk/test/cross-chain-messenger.spec.ts b/packages/sdk/test/cross-chain-messenger.spec.ts index 1d1b59470543..13a59348207d 100644 --- a/packages/sdk/test/cross-chain-messenger.spec.ts +++ b/packages/sdk/test/cross-chain-messenger.spec.ts @@ -16,6 +16,7 @@ import { ETHBridgeAdapter, L1ChainID, L2ChainID, + IGNORABLE_CONTRACTS, } from '../src' import { DUMMY_MESSAGE, DUMMY_EXTENDED_MESSAGE } from './helpers' @@ -234,7 +235,7 @@ describe('CrossChainMessenger', () => { if (overrides.l1[contractName]) { const contract = messenger.contracts.l1[contractName] expect(contract.address).to.equal(overrides.l1[contractName]) - } else { + } else if (!IGNORABLE_CONTRACTS.includes(contractName)) { const contract = messenger.contracts.l1[contractName] expect(contract.address).to.equal(contractAddress) } diff --git a/packages/sdk/test/utils/merkle-utils.spec.ts b/packages/sdk/test/utils/merkle-utils.spec.ts new file mode 100644 index 000000000000..5c9fbcbf009a --- /dev/null +++ b/packages/sdk/test/utils/merkle-utils.spec.ts @@ -0,0 +1,60 @@ +import { ethers } from 'ethers' + +import { expect } from '../setup' +import { maybeAddProofNode } from '../../src/utils/merkle-utils' + +describe('Merkle Utils', () => { + describe('maybeAddProofNode', () => { + // Test taken from opBNB testnet withdrawal. + it('should add a proof node when final node is inside of a branch', () => { + const key = ethers.utils.keccak256( + '0x5cd60ecef836e75dd12539abe8ad5f4ba0dc4fcaae2c45024c69bd9e20746eba' + ) + const proof = [ + '0xf90211a0feb6c6afca5ea568e0b7183d7292c112e9d28a1c846d889636d5c8822463aa77a0df719a24d8049d04a47e0e07ba493110fed0665d897c0ffdb05a7ce474782026a01bec363c069dc337ce16b4ca5cffa11d20e305fd7dcf6d87547b151c31aabf0ca00583d5a451bfa01f5e51d992e129ee17e65adda9495bda77898187484625aa9ea0bd9fef27cd52c2721e519bcd40c63a818095374e505a3bbd88db29c6c4521982a009a31937313c5b2bc06da6fec4075110f19526a9dbde3629ebe36aa8cd8e0851a0555f89002a34f6570bab438e69c5d8b855f2664e31f5dd59b807d0956577cc81a07e6f59ec99405b7afa436bf62abd098a85b43861fd3a9da3214a5d46b2d12543a03e7e883b0406cb781e5bf2a71cafc02ebbcdb0684ac03439633faf339d1259e2a0fa154fcf0bedd25aacac74e9864e4b96742c3d06f58c170cd320ade69db16c88a07e34154a031da5e50a3886efcb15c6681deeb20832726f083f80b03678b56d33a0d24408a39fb57838fdfe85c68f7eac74daab709ec3c22dfd0a579c1dbd64861aa093c1837ab2907fc51de7e918b81b997d60a6c8a18e3538720ee0d0f369530c26a0fca1af24293865f21d18d5eb823e0ecc007306823864f11d59c1c5c370fb22c2a0de8c894b5067d637df401aa6b963a3fc52b774abbedf6688e25bbf9a29672b7ca021c85d42de67601599e605d9ed1257451d1ce403d2478496d0a99d60db643d5280', + '0xf90211a02288f14667ef872b449e0f0f5526c2ad3634dcdb7376616d18fd87f6af9293bfa027223b95acda1508dbc42caac8edfb422759eedd13628e4dff0c5bf79d275182a0352a96940c817156a6e33c6f6cb2010ac216296f6e912c335982ba75ffb11898a0c3b7339a174d0a5fd842d3bb946a2ba6d9c1088215d9c3f56449af4dabb59e1ca03b331c72db0a3e0b51167ecb4d0ee76126181e3a54718e7cdefbf89ae0ae0d7ea03f162cadc26daa12d91e9ba459c9e61008ef57314e9cb810f074a878f2b81910a00dc670d0489ec214e2a636274d1e8b2df9db343218503ae2bf7ed868d8ab553fa0bffdd8cf5fe58452a64254f44e28ecd886964898fbab68711749423478d9c94ea0ca722fcaddd052f5a8ddce25c0c4161cd9e5552a0697ceccba540b0520cfcb61a0ffc0036ebf8ed2d9603de8c22d36cdc3fb451dd92a23adefe5593a4d8a12299da0bff43610f0c3d44e73e741d58f34f4d8e25aa3f67e0796241210bf321c2f1117a0341dcdbf2722bd7eacc3af46b6a9d80bb775dace93808a6737a1e135b9b225f3a07b3c3ec4c199c11374ba2dd28227e8c1efdbd8cb065768eff27e3918647eaccfa0e5a903a66eedfe8ea6d28a0f93cc91fc5f00f612a54aeeff100dafe84182a815a0203b138ec5130556a58d06184fdc399cb726954d28fe9fc68131f23d211382f5a057e92c1aec0a5b4e723cbbb3928d1008c9a9b4a26206656fccf70c14136a77de80', + '0xf90211a0437a65e2661356d938aa5321927d85003770566f25f121ec0dba4ad4acae9a8ca04acf516468076bf35f8c10e6aa904612fe08fcfba5c7b76bd87a5fe38e212c4da08db4fa1d774e1653468078c4c6a26cc6236025d6ab88dd1c02dae7c8bc7b19f7a03fb292d186e2d63e163788b3af313403cd12bc4b839037be4ad15a6fbbee217aa0dc569eab6a0b0a1d1dd7d12a24512bff7d4a6f5dc55a5a2dea31ed1a5415d383a0e4eaab256b73b4abc3402f44b6fa90a0854b733cdd5b884915ae8c07f5c78002a075ccef6818cc6c2870a70a0b41e3904ba2355937e028b02cb54a7ab321492357a0b059014d41d68c6c28b7de8f06b57c015210167d64c8589f9d7801dd4f025a60a07bf03f4912eaba2dd295222c1e01c1ddd7baedad61cf90d4e5987fc7ae1c6beaa0309d5aff3d1194cf259389cbb365e43548291aa9125d0550ab4908d1cc958844a0ff3fa5bba3bd95b08506336101c1c71cb920dd3ee68d8120654dac8f4b05d390a03a7b3de7b7476d9bf665396b718a28f8d746828bbf51a396e43669a4c90ca770a0913bc7b7ef04689a19cebf2c785f4eea68ccf9c97be94bb5bdd1346d4b145147a0cc21ab258bc2d961534438ddbbf185de30f8387acbc40f89857d88a23f90047ea0cf8b6876bd0cfd19ddd39fcfe88470d76757f64ba8496cfc382c92ed65706586a051de24dd2a27ffce89bb1dfcd6aa33469a91b50c4332ff9ef45d3cc917613a5c80', + '0xf90211a00aaeb3f8caea8f7167815fcdf1470777f7e100c781bc9ed79afefac295bb0d03a04b9f1d4ade00185fc62732b28abfb243afff140ebfa034daa4f139e0015a2195a0f9608d7d4346638e5ad4219ef6ea0769aa9fdb4bc6207831cf0f64854b072c2da0b953f4ee5f8ae17d9da8e3c1efaf9a822d0301dab05cae4b776fbd666fce8158a0bd8460bbbcfa3e02af0909445883176e3b65c85a63c6f91c2994fa2979228726a024f9c1c9952c2b6edec11955b50eaccd1ef44099db309f807f85aa4c4130b31ea056ad08d1e812df59fb54d2b847b1e7fa0872aaa1f3ac8f4e314d6893baece56aa02ca9f7cf8514dcca9401081f94b824f03b4d74dc690dfeed6779ddee4a9ad72ba050dffdadd79fbb8d857ad658864cd9cb19e69c73f8ba9c241fc2b451e2124320a00377a910bb501d1b22b7b03a3fa60aa47facf33515c10b0742fb76bd5a3d7a6ca0abcffd053ac378f2aa4d90e95c64dd7cc450fe6f961f9f55722cc49ef7b47f7ba042a8b3431675d5909bad710d519dd2c5d3287f3af8641122cce53b137087ce6ba0b77542431b232d0aabbbdf27e1c1adab761e144d396d0658ec1a84a712906a73a099ca74decdad4e079c0d1f35c8da403acbe65bf284253dab1be788f1808687eba06d866839d5ce08a75b3c8a2383b7eec6120ab32c7dfbe9b036831fc3101c8250a0fd315d671bf51da89b2db014d0f199be522fbf8e19d0276d0a14a1c66c1df8ac80', + '0xf901f1a0d6228395f59dea0ead05458d95d54c315c7feddf6416bb41aed62dc165446a6ca051e1ecb5424d948d386c0d291bb674fac4c47349f67e40a77850f54254b612b5a0e3b1d858fc2bb8001052eb3a36c9e2bea2966c795848aff0e5fb3cd779cfb565a0046a3c69a3639aa8bc1b3cf2c052d54424a88d2ea90a6388595b160ef5ef161780a0b2b1a778cbd8a3257ff7114116d892491a3ab148be723e22262b842680a9b29ea026da2284e756fcade15d922c0b8f6282a008e1c842e5030a307b3ea2e9a55726a026c0862e8e9e06ddef9ce37044fe2228a3ba9863faaf0cf1ad0863d41f7d7f13a0bcfbf48375296ad05ade4710ffe7e2b419fe246623369f7a6a4fa6f720bb185fa0d982dbbef7671cf7add6efd8612d47477b77f40d62e11983fe4478e959c0a86da0b3bf440462efb53c7056f5ff3ea134a072363a95a15a6945b83e416e6adee245a00396e89cb82998271f55ef0e892d456a7bbf624c23bf751f1ea2da6a7690be42a06f2588a03a07740fe4d300795096252abeb6b984e41b4f7027df84c1c520ea84a0ce163ce486c3de11ca2f6656f5dcf82e62496cb0d5472e042dede34d0e1aedd8a0fec8a8bfbf3e3418c4730c3c7c047cd73695c4c429f6ec6babc7165b9b27e635a002711d0ce2951376bac13daf1d3bcf359a90f68bc804b6b2b2e9efe09a8157af80', + '0xf89180808080808080a0326fe6fc4a847e4db1144153b15d0d3811f0317239f2885cc2a383825ccb1d8480a04455f6e0d1f8a2022ea33d5e6a537e384483dfccd19d07d21047e9b264b56e3c808080a06174ffa3ff6accab10abb5d61000db050324c608b10c0344a3eec6fa0107a079a0d494a04c23ba556fc3bdbe234562fe6825d55f3aaaa81e43415b8070a733d0bd8080', + '0xe482000fa03cb626e2849a157c57ca2e62c3dd139cf803efe281f5b6331b3ba92280dd8c42', + '0xf84d8080808080de9c332c35a4d03ec6ab9b3ffd06c69652ce8e02ff95537f98b7a0feb29c01808080de9c36620d27102d4799d259fe08f690c0a21b80d0a1a903db682417a23f0180808080808080', + ] + const modifiedProof = maybeAddProofNode(key, proof) + expect(modifiedProof).to.deep.equal([ + ...proof, + '0xde9c36620d27102d4799d259fe08f690c0a21b80d0a1a903db682417a23f01', + ]) + }) + + // Test taken from opBNB testnet withdrawal. + it('should not add a proof node when final node is a leaf node', () => { + const key = ethers.utils.keccak256( + '0x55b08006167f308d31af5ea9f302384725df906124e39e0eb2c6d040498e0fae' + ) + const proof = [ + '0xf90211a08c7918779c1c4435737b269573de96df28e1ec8c5847d7317906971b4c5fa73fa018679d112e60f815616a167692ea7d821691f34bed06df12c7b121a4c7b8384ba06b0a09649c9e7df1bde1c7448243c954dfecae8301b7f6bbe7d8f0b781733194a0258988e63a01754eafaffa3837ccc321c4f99d50869d04c09e7ab587988ecfa6a0a5b325ae646fd16ad7daac9d6da2ea244d456fa1a219f828cb9a5785f01bbf4ea0532b1427977ae09ee5344667910500207fd500912f9e1c6f5e7aa6b8b333a717a04a32b16d0d56f217216a9dae9eea953883ff3bcf1a9578d60d6bb28bbf4b6655a009e8cabb94c504eeb5cf15a151ed4b99be678bf969ee30be5d8aaf1312210079a0938dedf6ad32b04a9a2da09f29e481c51d7cf440d62651ed570355e12a4858d8a0b6bae212efc7179842abc76e9d6b2850b05336720b81dac467e942f7f6cd6b9ba0be45a8205c8c75ebe83c10cc9e87a597820d7e3ca691f9d1549e12a6f050a296a0c65bd95874adb4054ae8b346f2d2ccc88e76555c662b230d62072db36933508ca0e21442e3384b11c414e4a6bc2d56e71dbbbc672c38ac00bd63386ad55c590955a0d3d178f5be5f808d97ce22d48adce909ecf326cc5d9a0e7b64af616ca2d3e12ca09475833e7206cd83f7301f995617825f6d7050c782e17495ce5eb0556c2b68c4a09638ed778938e150e4c68cbcaf9bd47f97e1a6a6d6d2bbf9bc516450166a1ed980', + '0xf90211a0a3f8f3795f08496d4cd1b0c054c337d10d28fa2e9725162da7714c20d3b30c88a05856b0aa4c58cd715545c05ddb8bd93835dcd0ecbc7c2b139266af1c1850a671a000b3e2386218f9308469c731f6d53d5fb27512082390826956c8a234854a88aca0e525d6f4fa38fec4694f5cdb589156dc3a4d829861e1228b502c0130a4834ceaa0a414e804e76eb8863d1804ae04189237119b0415bf57c8a6a4ab176ad9f78eeca022aa4baf04a82bb83148c6ff6261dec1165f5d2f9bdf0ce73dfb2c9719fb8597a06fe7a289928f7fbd860aafb95945dcc2699bf7bf2010d6aa83b9f49308e968c9a008d5e746de17a948d6e7fc864286215d008e7f2d592cf7269df4dab0a3486215a0c39c7aa088d057db66179d7354b3f0d48f6d3ed2e62f8a840d9117b7b66a64bda0dd4ccdc76f721cf04cdf14d1d8a1821501d89c3d44ed5ed92b5a820431b36990a06c89982d73cc213516be264bb2fb6c969131f542afbc460ff781b839290e42f8a09954b3cbc392cdefb5664bc8483e1400def7846c631728d814b1a163ba871c44a0215b32a1491899a86be9c986dd695612a3964235b20e73158e501e6005cec689a0c1a8d7e66e95c7b661018c01dce2732f0f88614caa69e0e0848f5a750c8a9bbaa01aab317da329eee7bcdb91ee23d9a776f2a662bc672cc89f9d8f1c40cf94a4d5a013b5fc28d7d795f1203db98a7f49493ec4dbc6e7f19415131fd724274d53b93b80', + '0xf90211a099cf6b57cf52d79d997c6c7cacc880d9eecba4d91b711e94567d153a4e7a0586a05dd28dc2c3001cd399773fec132570d32a88cf439c15d8ed1750692892019bbda0419a8369667afcc1bd0eb25aa2ee01aa9914389f1c4c5b8cfdb76c7387b1efeda0c31b4168d817e9e6c1f8d9241cb61d3e40417396438799cae60b21036c569585a02cb6faef5768eb7381530c01c30a69ee9d6b74b63ad7875df8dce0d3f9e33beea0722b13f67dcc8e022e2f2f6cf42b697330425f910499f9f69455e9b9dc7a5696a0c2da3ee274178cd500418aa82c86116f8a19c03f50680589689cd76c526885baa0de4fcbd8ef4edef419cac8f12a67f76c27a7d53a47d0408251c89b191599e2a6a01bec2c60b7ab411ffe01ef36723a82b1e36df58759e4356b90f0b939cf9f7feca0823b67e452e64a3986da2836b6398bfe6dd6257b1313b649bd38b8109b442e86a0fe8fd7cf12be37c649531fa445116c53258d76664ba95b84f6adac356015f469a04d68070a9bd5b183068eafc1edfec122dba0ded10725ebc468cb0b7b7fba15d6a051b612dfba41f35f8c827ee18387bf6e3316cb8494fd30d88a091b5405bc5d8ca01c622f8ce84c20a5d1055a984e405638509e2e8683d1fa89725b4855500f353aa01e795b4bd4df111c9528d22c7964d89f96cdb5f7217fda91132b10b30782965fa0d91eacec2f75501bb1e9c7c3dd7d2cdf12d206627f096da1408573f2775646ce80', + '0xf90211a03b7d6150ad44f8399b7fa60d27034db408b0fe2f42770312dbc12220205ba6b2a0c34225fedb6a5a5351429e52c6dc637abed3bde536318fbb9e592630dbaa9ff8a0a3a4cbf9ee86518067c263c9ea3c59683306519f5ad518f8c7ccb298e8b405dda0bb9847a6a1e58287f2f5e0dd2fc9a7e78118639f1d9768d970114fd72cf4bb94a00bd41abbd004fc6aabb2ad6ca5ad6c8adc9188263b41e3c5c1c640bc6cdad909a01ddb2f8f80a1856248f813e3f066f12a0699c83c7a620a3a156f8d7320887901a0716be43af95da7bb5b22ffd86b67790da8f6470bdb771a1c72c3d8b918101f77a08e844b3e7b41dbf69f7cb59df673d21dd0d0679b387d136e77e91e01c2aa83cda01086f25f4f678183dc4a5398a0c608f28578619d5ef25890457f266dfd0b2b45a05c463dd5c575e7440ceea9322b3a50fc1111f45f15d8a2bb822efe430cb321e9a0deb669961500f680770e94ee2253cd5fbb20d30a0d2cb10a35efd0c1a7827ebaa090fb4c646e0a7d00b427d27372532e003f6e430fef4a896b26da3d334b5e35bea0e00315beb0ceadcbfe33727cfdb08d98c86dca534ceb50e799f2bf914e18da66a0b32fcca5247e924812fedc00a2f6c72ef36dfb28896a315bbbad8f7dac09623ca07e5d50949d89b497620383abcc9fe952911f4821b50184261c3dda6e46a0b815a039921c389fef00713e4ad8897bc5c68781fee90d0873a42cfd814b8709152c4380', + '0xf901f1a01dd4ceeb1ab5bc49adb270f4c031783adcc6d4b8b2c874778310b84188fe9b64a0747c08e80562666c517c00dfb2648e71273377b1412b56ad5e45f633f952229aa0991ce5972ae42c944f7d7fafb8cf01913a0658efd48ea4beff7dfc4c45c0f21aa0fe8c9b0e45134639ea41c880910a73d49d3c5fb8e3cf003eda7ceb48891b9d12a0d5748723a79117e595d805b90c5da4f28a88ca06ab8a3b540509fc5f74487be2a04724502db500742f7bf9f64bd6d0c9cecb150dcacd8f41b235baa3228120c3dc80a05ba19409d69154ee9397c0451ce8fe478a4a17097c49df7f25aa349243522455a01f16b5317ef849b7d520e74f02e3a1b5d3aa5454a009c398f6917ef72d12fd3aa0354fbfecc5fe46c76395042141308381ef0f59e0ffae159d1758b287dcd92c2ea065df8dd7ad7fe8accdc96ae5bf97802b1425dec3cef9c148f49c736dc8151faaa0eb440cd657329946458789ab7ba02df5dcd77a28095009305001fe5124424079a05fa06e6354a138012417afd550c71a9a08164bceccf652f150d1ea6a31f89d20a06cc7b02dce36338aa84041a725bb47b87bc93090b676776b53c0a7c654d93361a02c4ec483c0b8b4d148c133e2ea471b3432d310ed7c43d2b983203bd08adbb3eda025964bfbdd4d19d5d5f094ac4ca8bb2476047f3c5328cb1c84a24ee5bea5fdcb80', + '0xf851808080a045d583df49281f7f8c545ab91f4d35ba48873cc4da6deb2c0703135959fc8ec080808080a0ca2836f17b4c1af21e2531f7036a069ba8ef535650495820731ca669590dfddb8080808080808080', + '0xe09e202ec4eafbdfe1b7f218e5f087854c923c7f41b85d3ada15c32bef29588a01', + ] + const modifiedProof = maybeAddProofNode(key, proof) + expect(modifiedProof).to.deep.equal(proof) + }) + + // Test taken from MerkleTrie solidity test suite. + it('should not add a proof node when the value itself is inside a branch node', () => { + const key = '0x6b657933' + const proof = [ + '0xe68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779', + '0xf87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080', + '0xf839808080808080c9823363856176616c338080808080808080809f31323334353637383930313233343536373839303132333435363738393031', + ] + const modifiedProof = maybeAddProofNode(key, proof) + expect(modifiedProof).to.deep.equal(proof) + }) + }) +}) diff --git a/packages/web3js-plugin/README.md b/packages/web3js-plugin/README.md index 5dd1df0cafc3..f4c3392c96b0 100644 --- a/packages/web3js-plugin/README.md +++ b/packages/web3js-plugin/README.md @@ -601,4 +601,4 @@ console.log(version) // 1.0.0 [1]: https://docs.web3js.org/api/web3-types#DataFormat [2]: https://docs.web3js.org/api/web3-types#DEFAULT_RETURN_FORMAT -[3]: https://docs.web3js.org/api/web3-types#DataFormat \ No newline at end of file +[3]: https://docs.web3js.org/api/web3-types#DataFormat diff --git a/packages/web3js-plugin/package.json b/packages/web3js-plugin/package.json index d64bbb6179b0..d5cbb29a4006 100644 --- a/packages/web3js-plugin/package.json +++ b/packages/web3js-plugin/package.json @@ -33,17 +33,17 @@ }, "devDependencies": { "@eth-optimism/contracts-ts": "workspace:^", - "@swc/core": "^1.3.95", - "@vitest/coverage-istanbul": "^0.34.6", - "tsup": "^7.2.0", - "typescript": "^5.2.2", - "viem": "^1.18.0", - "vite": "^4.5.0", - "vitest": "^0.34.1", + "@swc/core": "^1.4.6", + "@vitest/coverage-istanbul": "^1.2.2", + "tsup": "^8.0.1", + "typescript": "^5.3.3", + "viem": "^2.7.19", + "vite": "^5.1.5", + "vitest": "^1.2.2", "zod": "^3.22.4" }, "dependencies": { - "@ethereumjs/rlp": "^5.0.0", + "@ethereumjs/rlp": "^5.0.2", "web3-eth": "^4.0.3", "web3-eth-accounts": "^4.0.3" }, diff --git a/packages/web3js-plugin/src/plugin.spec.ts b/packages/web3js-plugin/src/plugin.spec.ts index 094b25796d1d..11c10b35bb53 100644 --- a/packages/web3js-plugin/src/plugin.spec.ts +++ b/packages/web3js-plugin/src/plugin.spec.ts @@ -231,15 +231,13 @@ describe('OptimismPlugin', () => { test('estimateFees', async () => expect( - await web3.op.estimateFees( - { - chainId: 10, - data: encodedBurnMethod, - type: 2, - to: optimistAddress[10], - from: '0x77194aa25a06f932c10c0f25090f3046af2c85a6', - } - ) + await web3.op.estimateFees({ + chainId: 10, + data: encodedBurnMethod, + type: 2, + to: optimistAddress[10], + from: '0x77194aa25a06f932c10c0f25090f3046af2c85a6', + }) ).toBeTypeOf('bigint')) }) diff --git a/packages/web3js-plugin/src/plugin.ts b/packages/web3js-plugin/src/plugin.ts index e28d243bdc27..0776a0a70529 100644 --- a/packages/web3js-plugin/src/plugin.ts +++ b/packages/web3js-plugin/src/plugin.ts @@ -128,9 +128,7 @@ export class OptimismPlugin extends Web3PluginBase { return Web3.utils.format( { format: 'uint' }, await this._getPriceOracleContractInstance() - .methods.getL1GasUsed( - this._serializeTransaction(transaction) - ) + .methods.getL1GasUsed(this._serializeTransaction(transaction)) .call(), returnFormat ?? DEFAULT_RETURN_FORMAT ) @@ -257,10 +255,7 @@ export class OptimismPlugin extends Web3PluginBase { */ public async estimateFees< ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT - >( - transaction: Transaction, - returnFormat?: ReturnFormat - ) { + >(transaction: Transaction, returnFormat?: ReturnFormat) { const [l1Fee, l2Fee] = await Promise.all([ this.getL1Fee(transaction), this.getL2Fee(transaction), diff --git a/packages/web3js-plugin/tsup.config.ts b/packages/web3js-plugin/tsup.config.ts index b0813d584dbd..869dbc7c3c51 100644 --- a/packages/web3js-plugin/tsup.config.ts +++ b/packages/web3js-plugin/tsup.config.ts @@ -10,5 +10,5 @@ export default defineConfig({ splitting: false, sourcemap: true, clean: false, - dts: true + dts: true, }) diff --git a/patches/@changesets+cli+2.26.0.patch b/patches/@changesets+cli+2.26.0.patch deleted file mode 100644 index 9421a834c823..000000000000 --- a/patches/@changesets+cli+2.26.0.patch +++ /dev/null @@ -1,66 +0,0 @@ -diff --git a/node_modules/@changesets/cli/dist/cli.cjs.dev.js b/node_modules/@changesets/cli/dist/cli.cjs.dev.js -index b158219..6fdfb6e 100644 ---- a/node_modules/@changesets/cli/dist/cli.cjs.dev.js -+++ b/node_modules/@changesets/cli/dist/cli.cjs.dev.js -@@ -937,7 +937,7 @@ async function publishPackages({ - }) { - const packagesByName = new Map(packages.map(x => [x.packageJson.name, x])); - const publicPackages = packages.filter(pkg => !pkg.packageJson.private); -- const unpublishedPackagesInfo = await getUnpublishedPackages(publicPackages, preState); -+ const unpublishedPackagesInfo = await getUnpublishedPackages(packages, preState); - - if (unpublishedPackagesInfo.length === 0) { - return []; -@@ -957,20 +957,27 @@ async function publishAPackage(pkg, access, twoFactorState, tag) { - const { - name, - version, -- publishConfig -+ publishConfig, -+ private: isPrivate - } = pkg.packageJson; - const localAccess = publishConfig === null || publishConfig === void 0 ? void 0 : publishConfig.access; -- logger.info(`Publishing ${chalk__default['default'].cyan(`"${name}"`)} at ${chalk__default['default'].green(`"${version}"`)}`); -- const publishDir = publishConfig !== null && publishConfig !== void 0 && publishConfig.directory ? path.join(pkg.dir, publishConfig.directory) : pkg.dir; -- const publishConfirmation = await publish(name, { -- cwd: publishDir, -- access: localAccess || access, -- tag -- }, twoFactorState); -+ let published; -+ if (!isPrivate) { -+ logger.info(`Publishing ${chalk__default['default'].cyan(`"${name}"`)} at ${chalk__default['default'].green(`"${version}"`)}`); -+ const publishDir = publishConfig !== null && publishConfig !== void 0 && publishConfig.directory ? path.join(pkg.dir, publishConfig.directory) : pkg.dir; -+ const publishConfirmation = await publish(name, { -+ cwd: publishDir, -+ access: localAccess || access, -+ tag -+ }, twoFactorState); -+ published = publishConfirmation.published; -+ } else { -+ published = true; -+ } - return { - name, - newVersion: version, -- published: publishConfirmation.published -+ published - }; - } - -@@ -1140,8 +1147,13 @@ async function tagPublish(tool, packageReleases, cwd) { - if (tool !== "root") { - for (const pkg of packageReleases) { - const tag = `${pkg.name}@${pkg.newVersion}`; -- logger.log("New tag: ", tag); -- await git.tag(tag, cwd); -+ const allTags = await git.getAllTags(cwd); -+ if (allTags.has(tag)) { -+ logger.log("Skipping existing tag: ", tag); -+ } else { -+ logger.log("New tag: ", tag); -+ await git.tag(tag, cwd); -+ } - } - } else { - const tag = `v${packageReleases[0].newVersion}`; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8152a3e6c086..e961e6545f4a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,36 +9,33 @@ importers: .: dependencies: '@changesets/cli': - specifier: ^2.26.0 - version: 2.26.0 - '@codechecks/client': - specifier: ^0.1.11 - version: 0.1.12(typescript@5.2.2) + specifier: ^2.27.1 + version: 2.27.1 devDependencies: '@babel/eslint-parser': - specifier: ^7.18.2 - version: 7.22.15(@babel/core@7.22.10)(eslint@8.52.0) + specifier: ^7.23.10 + version: 7.23.10(@babel/core@7.22.10)(eslint@8.56.0) '@changesets/changelog-github': specifier: ^0.4.8 version: 0.4.8 '@types/chai': - specifier: ^4.3.8 - version: 4.3.8 + specifier: ^4.3.11 + version: 4.3.11 '@types/chai-as-promised': - specifier: ^7.1.4 - version: 7.1.5 + specifier: ^7.1.8 + version: 7.1.8 '@types/mocha': - specifier: ^10.0.3 - version: 10.0.3 + specifier: ^10.0.6 + version: 10.0.6 '@types/node': - specifier: ^20.8.9 - version: 20.8.9 + specifier: ^20.11.17 + version: 20.11.17 '@typescript-eslint/eslint-plugin': - specifier: ^6.9.0 - version: 6.9.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2) + specifier: ^6.21.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: ^6.9.0 - version: 6.9.0(eslint@8.52.0)(typescript@5.2.2) + specifier: ^6.21.0 + version: 6.21.0(eslint@8.56.0)(typescript@5.3.3) chai: specifier: ^4.3.10 version: 4.3.10 @@ -49,71 +46,59 @@ importers: specifier: ^2.2.0 version: 2.2.1 eslint: - specifier: ^8.52.0 - version: 8.52.0 + specifier: ^8.56.0 + version: 8.56.0 eslint-config-prettier: - specifier: ^8.3.0 - version: 8.3.0(eslint@8.52.0) + specifier: ^9.1.0 + version: 9.1.0(eslint@8.56.0) eslint-config-standard: specifier: ^16.0.3 - version: 16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.52.0) + version: 16.0.3(eslint-plugin-import@2.29.1)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.56.0) eslint-plugin-import: - specifier: ^2.29.0 - version: 2.29.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0) + specifier: ^2.29.1 + version: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.56.0) eslint-plugin-jsdoc: - specifier: ^35.1.2 - version: 35.5.1(eslint@8.52.0) + specifier: ^48.0.6 + version: 48.0.6(eslint@8.56.0) eslint-plugin-node: specifier: ^11.1.0 - version: 11.1.0(eslint@8.52.0) + version: 11.1.0(eslint@8.56.0) eslint-plugin-prefer-arrow: specifier: ^1.2.3 - version: 1.2.3(eslint@8.52.0) + version: 1.2.3(eslint@8.56.0) eslint-plugin-prettier: specifier: ^4.0.0 - version: 4.2.1(eslint-config-prettier@8.3.0)(eslint@8.52.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@2.8.8) eslint-plugin-promise: specifier: ^5.1.0 - version: 5.2.0(eslint@8.52.0) + version: 5.2.0(eslint@8.56.0) eslint-plugin-react: specifier: ^7.24.0 - version: 7.33.2(eslint@8.52.0) + version: 7.33.2(eslint@8.56.0) eslint-plugin-unicorn: - specifier: ^48.0.1 - version: 48.0.1(eslint@8.52.0) + specifier: ^50.0.1 + version: 50.0.1(eslint@8.56.0) husky: - specifier: ^8.0.3 - version: 8.0.3 + specifier: ^9.0.10 + version: 9.0.10 lint-staged: - specifier: 15.0.2 - version: 15.0.2 - markdownlint: - specifier: ^0.31.0 - version: 0.31.1 - markdownlint-cli2: - specifier: 0.4.0 - version: 0.4.0 + specifier: 15.2.0 + version: 15.2.0 mocha: specifier: ^10.2.0 version: 10.2.0 nx: - specifier: 17.0.2 - version: 17.0.2 + specifier: 18.1.2 + version: 18.1.2 nx-cloud: specifier: latest - version: 16.5.2 + version: 18.0.0 nyc: specifier: ^15.1.0 version: 15.1.0 - patch-package: - specifier: ^8.0.0 - version: 8.0.0 prettier: specifier: ^2.8.0 version: 2.8.8 - prettier-plugin-solidity: - specifier: ^1.0.0-beta.13 - version: 1.0.0-beta.18(prettier@2.8.8) rimraf: specifier: ^5.0.5 version: 5.0.5 @@ -121,21 +106,19 @@ importers: specifier: ^10.0.0 version: 10.0.0(mocha@10.2.0) typescript: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.3.3 + version: 5.3.3 endpoint-monitor: {} indexer/api-ts: devDependencies: tsup: - specifier: ^7.2.0 - version: 7.2.0(@swc/core@1.3.95)(typescript@5.2.2) + specifier: ^8.0.1 + version: 8.0.1(@swc/core@1.4.6)(typescript@5.3.3) vitest: - specifier: ^0.34.4 - version: 0.34.4 - - op-exporter: {} + specifier: ^1.2.2 + version: 1.2.2(@types/node@20.11.17)(jsdom@24.0.0) packages/chain-mon: dependencies: @@ -164,8 +147,8 @@ importers: specifier: ^4.5.1 version: 4.5.1 dotenv: - specifier: ^16.3.1 - version: 16.3.1 + specifier: ^16.4.5 + version: 16.4.5 ethers: specifier: ^5.7.2 version: 5.7.2 @@ -175,19 +158,19 @@ importers: version: 5.7.0 '@nomiclabs/hardhat-ethers': specifier: ^2.2.3 - version: 2.2.3(ethers@5.7.2)(hardhat@2.18.3) + version: 2.2.3(ethers@5.7.2)(hardhat@2.20.1) '@nomiclabs/hardhat-waffle': specifier: ^2.0.6 - version: 2.0.6(@nomiclabs/hardhat-ethers@2.2.3)(@types/sinon-chai@3.2.5)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.18.3) + version: 2.0.6(@nomiclabs/hardhat-ethers@2.2.3)(@types/sinon-chai@3.2.5)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.20.1) hardhat: - specifier: ^2.18.3 - version: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) + specifier: ^2.20.1 + version: 2.20.1(ts-node@10.9.2)(typescript@5.3.3) ts-node: - specifier: ^10.9.1 - version: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) + specifier: ^10.9.2 + version: 10.9.2(@types/node@20.11.17)(typescript@5.3.3) tsx: - specifier: ^3.14.0 - version: 3.14.0 + specifier: ^4.7.0 + version: 4.7.0 packages/common-ts: dependencies: @@ -195,8 +178,8 @@ importers: specifier: workspace:* version: link:../core-utils '@sentry/node': - specifier: ^7.75.0 - version: 7.75.0 + specifier: ^7.99.0 + version: 7.99.0 bcfg: specifier: ^0.2.1 version: 0.2.1 @@ -207,8 +190,8 @@ importers: specifier: ^11.1.0 version: 11.1.0 dotenv: - specifier: ^16.3.1 - version: 16.3.1 + specifier: ^16.4.5 + version: 16.4.5 envalid: specifier: ^8.0.0 version: 8.0.0 @@ -219,8 +202,8 @@ importers: specifier: ^4.18.2 version: 4.18.2 express-prom-bundle: - specifier: ^6.6.0 - version: 6.6.0(prom-client@14.2.0) + specifier: ^7.0.0 + version: 7.0.0(prom-client@14.2.0) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -228,8 +211,8 @@ importers: specifier: ^1.10.0 version: 1.10.0 pino: - specifier: ^8.16.1 - version: 8.16.1 + specifier: ^8.19.0 + version: 8.19.0 pino-multi-stream: specifier: ^6.0.0 version: 6.0.0 @@ -247,44 +230,44 @@ importers: specifier: ^5.7.0 version: 5.7.0 '@types/express': - specifier: ^4.17.19 - version: 4.17.19 + specifier: ^4.17.21 + version: 4.17.21 '@types/morgan': - specifier: ^1.9.7 - version: 1.9.7 + specifier: ^1.9.9 + version: 1.9.9 '@types/pino': specifier: ^7.0.5 version: 7.0.5 '@types/pino-multi-stream': - specifier: ^5.1.5 - version: 5.1.5 + specifier: ^5.1.6 + version: 5.1.6 chai: specifier: ^4.3.10 version: 4.3.10 supertest: - specifier: ^6.3.3 - version: 6.3.3 + specifier: ^6.3.4 + version: 6.3.4 packages/contracts-bedrock: devDependencies: '@typescript-eslint/eslint-plugin': - specifier: ^6.9.0 - version: 6.9.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2) + specifier: ^6.21.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: ^6.9.0 - version: 6.9.0(eslint@8.52.0)(typescript@5.2.2) + specifier: ^6.21.0 + version: 6.21.0(eslint@8.56.0)(typescript@5.3.3) tsx: - specifier: ^3.14.0 - version: 3.14.0 + specifier: ^4.7.0 + version: 4.7.0 typescript: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.3.3 + version: 5.3.3 packages/contracts-ts: dependencies: '@testing-library/react': - specifier: ^14.0.0 - version: 14.0.0(react-dom@18.2.0)(react@18.2.0) + specifier: ^14.2.1 + version: 14.2.1(react-dom@18.2.0)(react@18.2.0) '@types/change-case': specifier: ^2.3.1 version: 2.3.1 @@ -298,18 +281,15 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) viem: - specifier: ^1.18.0 - version: 1.18.0(typescript@5.2.2)(zod@3.22.4) - wagmi: - specifier: '>1.0.0' - version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) + specifier: ^2.7.19 + version: 2.7.19(typescript@5.3.3)(zod@3.22.4) devDependencies: '@eth-optimism/contracts-bedrock': specifier: workspace:* version: link:../contracts-bedrock '@testing-library/jest-dom': - specifier: ^6.1.4 - version: 6.1.4(vitest@0.34.2) + specifier: ^6.4.2 + version: 6.4.2(vitest@1.2.2) '@testing-library/react-hooks': specifier: ^8.0.1 version: 8.0.1(react-dom@18.2.0)(react@18.2.0) @@ -317,17 +297,17 @@ importers: specifier: ^8.1.0 version: 8.1.0 '@vitest/coverage-istanbul': - specifier: ^0.34.6 - version: 0.34.6(vitest@0.34.2) + specifier: ^1.2.2 + version: 1.2.2(vitest@1.2.2) '@wagmi/cli': - specifier: ^1.5.2 - version: 1.5.2(@wagmi/core@1.4.5)(typescript@5.2.2)(wagmi@1.0.1) + specifier: ^2.1.2 + version: 2.1.2(typescript@5.3.3) '@wagmi/core': - specifier: ^1.4.5 - version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) + specifier: ^2.6.3 + version: 2.6.3(react@18.2.0)(typescript@5.3.3)(viem@2.7.19) abitype: - specifier: ^0.10.1 - version: 0.10.1(typescript@5.2.2) + specifier: ^1.0.2 + version: 1.0.2(typescript@5.3.3) glob: specifier: ^10.3.10 version: 10.3.10 @@ -338,20 +318,23 @@ importers: specifier: link:@types/@testing-library/jest-dom version: link:@types/@testing-library/jest-dom jsdom: - specifier: ^22.1.0 - version: 22.1.0 + specifier: ^24.0.0 + version: 24.0.0 tsup: - specifier: ^7.2.0 - version: 7.2.0(@swc/core@1.3.95)(typescript@5.2.2) + specifier: ^8.0.1 + version: 8.0.1(@swc/core@1.4.6)(typescript@5.3.3) typescript: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.5.0 - version: 4.5.0(@types/node@20.8.9) + specifier: ^5.1.5 + version: 5.1.5(@types/node@20.11.17) vitest: - specifier: ^0.34.2 - version: 0.34.2(jsdom@22.1.0) + specifier: ^1.2.2 + version: 1.2.2(@types/node@20.11.17)(jsdom@24.0.0) + wagmi: + specifier: ^2.5.5 + version: 2.5.5(@tanstack/react-query@5.17.1)(react-dom@18.2.0)(react-native@0.73.1)(react@18.2.0)(typescript@5.3.3)(viem@2.7.19) packages/core-utils: dependencies: @@ -399,8 +382,8 @@ importers: version: 2.6.7 devDependencies: '@types/node': - specifier: ^20.8.9 - version: 20.8.9 + specifier: ^20.11.17 + version: 20.11.17 mocha: specifier: ^10.2.0 version: 10.2.0 @@ -411,17 +394,17 @@ importers: specifier: workspace:^ version: link:../contracts-ts '@testing-library/jest-dom': - specifier: ^6.1.4 - version: 6.1.4(vitest@0.34.2) + specifier: ^6.4.2 + version: 6.4.2(vitest@1.2.2) '@testing-library/react-hooks': specifier: ^8.0.1 version: 8.0.1(react@17.0.2) '@vitest/coverage-istanbul': - specifier: ^0.34.6 - version: 0.34.6(vitest@0.34.2) + specifier: ^1.2.2 + version: 1.2.2(vitest@1.2.2) abitype: - specifier: ^0.10.1 - version: 0.10.1(typescript@5.2.2) + specifier: ^1.0.2 + version: 1.0.2(typescript@5.3.3) isomorphic-fetch: specifier: ^3.0.0 version: 3.0.0 @@ -429,23 +412,23 @@ importers: specifier: link:@types/@testing-library/jest-dom version: link:@types/@testing-library/jest-dom jsdom: - specifier: ^22.1.0 - version: 22.1.0 + specifier: ^24.0.0 + version: 24.0.0 tsup: - specifier: ^7.2.0 - version: 7.2.0(@swc/core@1.3.95)(typescript@5.2.2) + specifier: ^8.0.1 + version: 8.0.1(@swc/core@1.4.6)(typescript@5.3.3) typescript: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.3.3 + version: 5.3.3 viem: - specifier: ^1.18.0 - version: 1.18.0(typescript@5.2.2)(zod@3.22.4) + specifier: ^2.7.19 + version: 2.7.19(typescript@5.3.3)(zod@3.22.4) vite: - specifier: ^4.5.0 - version: 4.5.0(@types/node@20.8.9) + specifier: ^5.1.5 + version: 5.1.5(@types/node@20.11.17) vitest: - specifier: ^0.34.2 - version: 0.34.2(jsdom@22.1.0) + specifier: ^1.2.2 + version: 1.2.2(@types/node@20.11.17)(jsdom@24.0.0) packages/sdk: dependencies: @@ -462,11 +445,14 @@ importers: specifier: ^4.17.21 version: 4.17.21 merkletreejs: - specifier: ^0.3.10 - version: 0.3.10 + specifier: ^0.3.11 + version: 0.3.11 rlp: specifier: ^2.2.7 version: 2.2.7 + semver: + specifier: ^7.6.0 + version: 7.6.0 devDependencies: '@ethersproject/abstract-provider': specifier: ^5.7.0 @@ -479,37 +465,40 @@ importers: version: 5.7.0 '@nomiclabs/hardhat-ethers': specifier: ^2.2.3 - version: 2.2.3(ethers@5.7.2)(hardhat@2.18.3) + version: 2.2.3(ethers@5.7.2)(hardhat@2.20.1) '@nomiclabs/hardhat-waffle': specifier: ^2.0.1 - version: 2.0.1(@nomiclabs/hardhat-ethers@2.2.3)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.18.3) + version: 2.0.1(@nomiclabs/hardhat-ethers@2.2.3)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.20.1) '@types/chai': - specifier: ^4.3.8 - version: 4.3.8 + specifier: ^4.3.11 + version: 4.3.11 '@types/chai-as-promised': - specifier: ^7.1.5 - version: 7.1.5 + specifier: ^7.1.8 + version: 7.1.8 '@types/mocha': - specifier: ^10.0.3 - version: 10.0.3 + specifier: ^10.0.6 + version: 10.0.6 '@types/node': - specifier: ^20.8.9 - version: 20.8.9 + specifier: ^20.11.17 + version: 20.11.17 + '@types/semver': + specifier: ^7.5.7 + version: 7.5.7 chai-as-promised: specifier: ^7.1.1 version: 7.1.1(chai@4.3.10) ethereum-waffle: specifier: ^4.0.10 - version: 4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typescript@5.2.2) + version: 4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typescript@5.3.3) ethers: specifier: ^5.7.2 version: 5.7.2 hardhat: - specifier: ^2.18.3 - version: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) + specifier: ^2.20.1 + version: 2.20.1(ts-node@10.9.2)(typescript@5.3.3) hardhat-deploy: - specifier: ^0.11.43 - version: 0.11.43 + specifier: ^0.11.44 + version: 0.11.44 isomorphic-fetch: specifier: ^3.0.0 version: 3.0.0 @@ -520,20 +509,20 @@ importers: specifier: ^15.1.0 version: 15.1.0 ts-node: - specifier: ^10.9.1 - version: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) + specifier: ^10.9.2 + version: 10.9.2(@types/node@20.11.17)(typescript@5.3.3) typedoc: - specifier: ^0.25.2 - version: 0.25.2(typescript@5.2.2) + specifier: ^0.25.7 + version: 0.25.7(typescript@5.3.3) typescript: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.3.3 + version: 5.3.3 viem: - specifier: ^1.18.0 - version: 1.18.0(typescript@5.2.2)(zod@3.22.4) + specifier: ^2.7.19 + version: 2.7.19(typescript@5.3.3)(zod@3.22.4) vitest: - specifier: ^0.34.2 - version: 0.34.2 + specifier: ^1.2.2 + version: 1.2.2(@types/node@20.11.17)(jsdom@24.0.0) zod: specifier: ^3.22.4 version: 3.22.4 @@ -541,8 +530,8 @@ importers: packages/web3js-plugin: dependencies: '@ethereumjs/rlp': - specifier: ^5.0.0 - version: 5.0.0 + specifier: ^5.0.2 + version: 5.0.2 web3: specifier: '>= 4.0.3 < 5.x' version: 4.0.3 @@ -557,26 +546,26 @@ importers: specifier: workspace:^ version: link:../contracts-ts '@swc/core': - specifier: ^1.3.95 - version: 1.3.95 + specifier: ^1.4.6 + version: 1.4.6 '@vitest/coverage-istanbul': - specifier: ^0.34.6 - version: 0.34.6(vitest@0.34.1) + specifier: ^1.2.2 + version: 1.2.2(vitest@1.2.2) tsup: - specifier: ^7.2.0 - version: 7.2.0(@swc/core@1.3.95)(typescript@5.2.2) + specifier: ^8.0.1 + version: 8.0.1(@swc/core@1.4.6)(typescript@5.3.3) typescript: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.3.3 + version: 5.3.3 viem: - specifier: ^1.18.0 - version: 1.18.0(typescript@5.2.2)(zod@3.22.4) + specifier: ^2.7.19 + version: 2.7.19(typescript@5.3.3)(zod@3.22.4) vite: - specifier: ^4.5.0 - version: 4.5.0(@types/node@20.8.9) + specifier: ^5.1.5 + version: 5.1.5(@types/node@20.11.17) vitest: - specifier: ^0.34.1 - version: 0.34.1 + specifier: ^1.2.2 + version: 1.2.2(@types/node@20.11.17)(jsdom@24.0.0) zod: specifier: ^3.22.4 version: 3.22.4 @@ -588,12 +577,12 @@ packages: engines: {node: '>=0.10.0'} dev: true - /@adobe/css-tools@4.3.1: - resolution: {integrity: sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==} + /@adobe/css-tools@4.3.2: + resolution: {integrity: sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw==} dev: true - /@adraffy/ens-normalize@1.9.4: - resolution: {integrity: sha512-UK0bHA7hh9cR39V+4gl2/NnBBjoXIxkuWAPCaY4X7fbH4L/azIi7ilWOCjMUYfpJgraLUAqkRi2BqrjME8Rynw==} + /@adraffy/ens-normalize@1.10.0: + resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} /@ampproject/remapping@2.2.1: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} @@ -603,23 +592,15 @@ packages: '@jridgewell/trace-mapping': 0.3.19 dev: true - /@babel/code-frame@7.22.10: - resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.22.10 - chalk: 2.4.2 - /@babel/code-frame@7.22.13: resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.22.20 chalk: 2.4.2 - dev: true - /@babel/compat-data@7.22.9: - resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} + /@babel/compat-data@7.23.5: + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} engines: {node: '>=6.9.0'} dev: true @@ -628,15 +609,15 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.3 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.22.10) '@babel/helpers': 7.22.10 - '@babel/parser': 7.22.10 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.10 - '@babel/types': 7.22.10 + '@babel/parser': 7.23.6 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.6 convert-source-map: 1.9.0 debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 @@ -646,8 +627,8 @@ packages: - supports-color dev: true - /@babel/eslint-parser@7.22.15(@babel/core@7.22.10)(eslint@8.52.0): - resolution: {integrity: sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg==} + /@babel/eslint-parser@7.23.10(@babel/core@7.22.10)(eslint@8.56.0): + resolution: {integrity: sha512-3wSYDPZVnhseRnxRJH6ZVTNknBz76AEnyC+AYYhasjP3Yy23qz0ERR7Fcd2SHmYuSFJ2kY9gaaDd3vyqU09eSw==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: '@babel/core': ^7.11.0 @@ -655,58 +636,94 @@ packages: dependencies: '@babel/core': 7.22.10 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 - eslint: 8.52.0 + eslint: 8.56.0 eslint-visitor-keys: 2.1.0 semver: 6.3.1 dev: true - /@babel/generator@7.22.10: - resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==} + /@babel/generator@7.23.3: + resolution: {integrity: sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.10 + '@babel/types': 7.23.6 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.19 jsesc: 2.5.2 dev: true - /@babel/generator@7.23.0: - resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} + /@babel/helper-annotate-as-pure@7.22.5: + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 - jsesc: 2.5.2 + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: + resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 dev: true - /@babel/helper-compilation-targets@7.22.10: - resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==} + /@babel/helper-compilation-targets@7.23.6: + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.22.9 - '@babel/helper-validator-option': 7.22.5 - browserslist: 4.21.10 + '@babel/compat-data': 7.23.5 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.22.2 lru-cache: 5.1.1 semver: 6.3.1 dev: true - /@babel/helper-environment-visitor@7.22.20: - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + /@babel/helper-create-class-features-plugin@7.23.7(@babel/core@7.22.10): + resolution: {integrity: sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.22.10) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 dev: true - /@babel/helper-environment-visitor@7.22.5: - resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} + /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.22.10): + resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-annotate-as-pure': 7.22.5 + regexpu-core: 5.3.2 + semver: 6.3.1 dev: true - /@babel/helper-function-name@7.22.5: - resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} - engines: {node: '>=6.9.0'} + /@babel/helper-define-polyfill-provider@0.4.4(@babel/core@7.22.10): + resolution: {integrity: sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.22.10 + '@babel/core': 7.22.10 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + debug: 4.3.4(supports-color@8.1.1) + lodash.debounce: 4.0.8 + resolve: 1.22.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} dev: true /@babel/helper-function-name@7.23.0: @@ -714,89 +731,135 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.15 - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-member-expression-to-functions@7.23.0: + resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 dev: true - /@babel/helper-module-imports@7.22.5: - resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.10 + '@babel/types': 7.23.6 dev: true - /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.10): - resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} + /@babel/helper-module-transforms@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-module-imports': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/helper-optimise-call-expression@7.22.5: + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-plugin-utils@7.22.5: + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.22.10): + resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-wrap-function': 7.22.20 + dev: true + + /@babel/helper-replace-supers@7.22.20(@babel/core@7.22.10): + resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 dev: true /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.10 + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: + resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true - /@babel/helper-string-parser@7.22.5: - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} engines: {node: '>=6.9.0'} dev: true /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-validator-identifier@7.22.5: - resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} + dev: true - /@babel/helper-validator-option@7.22.5: - resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} + /@babel/helper-wrap-function@7.22.20: + resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==} engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.23.0 + '@babel/template': 7.22.15 + '@babel/types': 7.23.6 dev: true /@babel/helpers@7.22.10: resolution: {integrity: sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.10 - '@babel/types': 7.22.10 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.6 transitivePeerDependencies: - supports-color dev: true - /@babel/highlight@7.22.10: - resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.22.5 - chalk: 2.4.2 - js-tokens: 4.0.0 - /@babel/highlight@7.22.20: resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} engines: {node: '>=6.9.0'} @@ -804,2388 +867,4173 @@ packages: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 - dev: true - /@babel/parser@7.22.10: - resolution: {integrity: sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==} + /@babel/parser@7.23.0: + resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.22.10 + '@babel/types': 7.23.6 dev: true - /@babel/parser@7.23.0: - resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} + /@babel/parser@7.23.6: + resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.22.10 + '@babel/types': 7.23.6 dev: true - /@babel/runtime@7.20.7: - resolution: {integrity: sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==} + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 dependencies: - regenerator-runtime: 0.13.11 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@babel/runtime@7.22.6: - resolution: {integrity: sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==} + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 dependencies: - regenerator-runtime: 0.13.11 + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.22.10) + dev: true - /@babel/template@7.22.15: - resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.7(@babel/core@7.22.10): + resolution: {integrity: sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 dependencies: - '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/core': 7.22.10 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/template@7.22.5: - resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} + /@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.22.10): + resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead. + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/code-frame': 7.22.10 - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 + '@babel/core': 7.22.10 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.22.10) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.10) dev: true - /@babel/traverse@7.22.10: - resolution: {integrity: sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==} + /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.22.10): + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead. + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 - debug: 4.3.4(supports-color@8.1.1) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.22.10 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/traverse@7.23.2: - resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} + /@babel/plugin-proposal-export-default-from@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-Q23MpLZfSGZL1kU7fWqV262q65svLSCIP5kZ/JCW/rKTCm/FrLjpvEd2kfUYMVeHh4QhV/xzyoRAHWrAZJrE3Q==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.0 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 - debug: 4.3.4(supports-color@8.1.1) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-export-default-from': 7.23.3(@babel/core@7.22.10) dev: true - /@babel/types@7.22.10: - resolution: {integrity: sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==} + /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.22.10): + resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead. + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - to-fast-properties: 2.0.0 + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.10) dev: true - /@babel/types@7.23.0: - resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} + /@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.22.10): + resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead. + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.10) dev: true - /@chainsafe/as-sha256@0.3.1: - resolution: {integrity: sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg==} + /@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.22.10): + resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/core': 7.22.10 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.22.10) dev: true - /@chainsafe/persistent-merkle-tree@0.4.2: - resolution: {integrity: sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ==} + /@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.22.10): + resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead. + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@chainsafe/as-sha256': 0.3.1 + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.10) dev: true - /@chainsafe/persistent-merkle-tree@0.5.0: - resolution: {integrity: sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw==} + /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.22.10): + resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead. + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@chainsafe/as-sha256': 0.3.1 + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.10) dev: true - /@chainsafe/ssz@0.10.2: - resolution: {integrity: sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg==} + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.10): + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@chainsafe/as-sha256': 0.3.1 - '@chainsafe/persistent-merkle-tree': 0.5.0 + '@babel/core': 7.22.10 dev: true - /@chainsafe/ssz@0.9.4: - resolution: {integrity: sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ==} + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.10): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@chainsafe/as-sha256': 0.3.1 - '@chainsafe/persistent-merkle-tree': 0.4.2 - case: 1.6.3 + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@changesets/apply-release-plan@6.1.3: - resolution: {integrity: sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg==} + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.10): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/runtime': 7.22.6 - '@changesets/config': 2.3.0 - '@changesets/get-version-range-type': 0.3.2 - '@changesets/git': 2.0.0 - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.8.8 - resolve-from: 5.0.0 - semver: 5.7.2 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/assemble-release-plan@5.2.3: - resolution: {integrity: sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g==} + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.22.10): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/runtime': 7.22.6 - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.5 - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - semver: 5.7.2 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/changelog-git@0.1.14: - resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.22.10): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@changesets/types': 5.2.1 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/changelog-github@0.4.8: - resolution: {integrity: sha512-jR1DHibkMAb5v/8ym77E4AMNWZKB5NPzw5a5Wtqm1JepAuIF+hrKp2u04NKM14oBZhHglkCfrla9uq8ORnK/dw==} + /@babel/plugin-syntax-export-default-from@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-KeENO5ck1IeZ/l2lFZNy+mpobV3D2Zy5C1YFnWm+YuY5mQiAWc4yAp13dqgguwsBsFVLh4LPCEqCa5qW13N+hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@changesets/get-github-info': 0.5.2 - '@changesets/types': 5.2.1 - dotenv: 8.6.0 - transitivePeerDependencies: - - encoding + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@changesets/cli@2.26.0: - resolution: {integrity: sha512-0cbTiDms+ICTVtEwAFLNW0jBNex9f5+fFv3I771nBvdnV/mOjd1QJ4+f8KtVSOrwD9SJkk9xbDkWFb0oXd8d1Q==} - hasBin: true + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.10): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/runtime': 7.20.7 - '@changesets/apply-release-plan': 6.1.3 - '@changesets/assemble-release-plan': 5.2.3 - '@changesets/changelog-git': 0.1.14 - '@changesets/config': 2.3.0 - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.5 - '@changesets/get-release-plan': 3.0.16 - '@changesets/git': 2.0.0 - '@changesets/logger': 0.0.5 - '@changesets/pre': 1.0.14 - '@changesets/read': 0.5.9 - '@changesets/types': 5.2.1 - '@changesets/write': 0.2.3 - '@manypkg/get-packages': 1.1.3 - '@types/is-ci': 3.0.0 - '@types/semver': 6.2.3 - ansi-colors: 4.1.3 - chalk: 2.4.2 - enquirer: 2.3.6 - external-editor: 3.1.0 - fs-extra: 7.0.1 - human-id: 1.0.2 - is-ci: 3.0.1 - meow: 6.1.1 - outdent: 0.5.0 - p-limit: 2.3.0 - preferred-pm: 3.0.3 - resolve-from: 5.0.0 - semver: 5.7.2 - spawndamnit: 2.0.0 - term-size: 2.2.1 - tty-table: 4.1.6 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/config@2.3.0: - resolution: {integrity: sha512-EgP/px6mhCx8QeaMAvWtRrgyxW08k/Bx2tpGT+M84jEdX37v3VKfh4Cz1BkwrYKuMV2HZKeHOh8sHvja/HcXfQ==} + /@babel/plugin-syntax-flow@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.5 - '@changesets/logger': 0.0.5 - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - micromatch: 4.0.5 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/errors@0.1.4: - resolution: {integrity: sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==} + /@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - extendable-error: 0.1.7 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/get-dependents-graph@1.3.5: - resolution: {integrity: sha512-w1eEvnWlbVDIY8mWXqWuYE9oKhvIaBhzqzo4ITSJY9hgoqQ3RoBqwlcAzg11qHxv/b8ReDWnMrpjpKrW6m1ZTA==} + /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - chalk: 2.4.2 - fs-extra: 7.0.1 - semver: 5.7.2 - dev: false - - /@changesets/get-github-info@0.5.2: - resolution: {integrity: sha512-JppheLu7S114aEs157fOZDjFqUDpm7eHdq5E8SSR0gUBTEK0cNSHsrSR5a66xs0z3RWuo46QvA3vawp8BxDHvg==} - dependencies: - dataloader: 1.4.0 - node-fetch: 2.6.12 - transitivePeerDependencies: - - encoding + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@changesets/get-release-plan@3.0.16: - resolution: {integrity: sha512-OpP9QILpBp1bY2YNIKFzwigKh7Qe9KizRsZomzLe6pK8IUo8onkAAVUD8+JRKSr8R7d4+JRuQrfSSNlEwKyPYg==} + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.10): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/runtime': 7.22.6 - '@changesets/assemble-release-plan': 5.2.3 - '@changesets/config': 2.3.0 - '@changesets/pre': 1.0.14 - '@changesets/read': 0.5.9 - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - dev: false - - /@changesets/get-version-range-type@0.3.2: - resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/git@2.0.0: - resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.10): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/runtime': 7.22.6 - '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - is-subdir: 1.2.0 - micromatch: 4.0.5 - spawndamnit: 2.0.0 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/logger@0.0.5: - resolution: {integrity: sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==} + /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - chalk: 2.4.2 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/parse@0.3.16: - resolution: {integrity: sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==} + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.10): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@changesets/types': 5.2.1 - js-yaml: 3.14.1 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/pre@1.0.14: - resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.10): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/runtime': 7.22.6 - '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.1 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/read@0.5.9: - resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.10): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/runtime': 7.22.6 - '@changesets/git': 2.0.0 - '@changesets/logger': 0.0.5 - '@changesets/parse': 0.3.16 - '@changesets/types': 5.2.1 - chalk: 2.4.2 - fs-extra: 7.0.1 - p-filter: 2.1.0 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/types@4.1.0: - resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} - dev: false + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.10): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/types@5.2.1: - resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.10): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@changesets/write@0.2.3: - resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.10): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/runtime': 7.22.6 - '@changesets/types': 5.2.1 - fs-extra: 7.0.1 - human-id: 1.0.2 - prettier: 2.8.8 - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@codechecks/client@0.1.12(typescript@5.2.2): - resolution: {integrity: sha512-2GHHvhO3kaOyxFXxOaiznlY8ARmz33/p+WQdhc2y6wzWw5eOl2wSwg1eZxx3LsWlAnB963Y4bd1YjZcGIhKRzA==} - engines: {node: '>=6'} - hasBin: true + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.22.10): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - bluebird: 3.7.2 - chalk: 2.4.2 - commander: 2.20.3 - debug: 4.3.4(supports-color@8.1.1) - execa: 1.0.0 - glob: 7.2.3 - graceful-fs: 4.2.11 - js-yaml: 3.14.1 - json5: 2.2.3 - lodash: 4.17.21 - marked: 0.7.0 - marked-terminal: 3.3.0(marked@0.7.0) - mkdirp: 0.5.6 - ms: 2.1.3 - promise: 8.1.0 - request: 2.88.2 - request-promise: 4.2.6(request@2.88.2) - ts-essentials: 1.0.4 - ts-node: 8.10.2(typescript@5.2.2) - url-join: 4.0.1 - transitivePeerDependencies: - - supports-color - - typescript - dev: false + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@coinbase/wallet-sdk@3.7.1: - resolution: {integrity: sha512-LjyoDCB+7p0waQXfK+fUgcAs3Ezk6S6e+LYaoFjpJ6c9VTop3NyZF40Pi7df4z7QJohCwzuIDjz0Rhtig6Y7Pg==} - engines: {node: '>= 10.0.0'} + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.10): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@metamask/safe-event-emitter': 2.0.0 - '@solana/web3.js': 1.78.0 - bind-decorator: 1.0.11 - bn.js: 5.2.1 - buffer: 6.0.3 - clsx: 1.2.1 - eth-block-tracker: 6.1.0 - eth-json-rpc-filters: 5.1.0 - eth-rpc-errors: 4.0.2 - json-rpc-engine: 6.1.0 - keccak: 3.0.3 - preact: 10.16.0 - qs: 6.11.2 - rxjs: 6.6.7 - sha.js: 2.4.11 - stream-browserify: 3.0.0 - util: 0.12.5 - transitivePeerDependencies: - - bufferutil - - encoding - - supports-color - - utf-8-validate + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} + /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@jridgewell/trace-mapping': 0.3.9 + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@ensdomains/ens@0.4.5: - resolution: {integrity: sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==} - deprecated: Please use @ensdomains/ens-contracts + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.22.10): + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 dependencies: - bluebird: 3.7.2 - eth-ens-namehash: 2.0.8 - solc: 0.4.26 - testrpc: 0.0.1 - web3-utils: 1.10.1 + '@babel/core': 7.22.10 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@ensdomains/resolver@0.2.4: - resolution: {integrity: sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==} - deprecated: Please use @ensdomains/ens-contracts + /@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@es-joy/jsdoccomment@0.9.0-alpha.1: - resolution: {integrity: sha512-Clxxc0PwpISoYYBibA+1L2qFJ7gvFVhI2Hos87S06K+Q0cXdOhZQJNKWuaQGPAeHjZEuUB/YoWOfwjuF2wirqA==} - engines: {node: '>=12.0.0'} + /@babel/plugin-transform-async-generator-functions@7.23.7(@babel/core@7.22.10): + resolution: {integrity: sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - comment-parser: 1.1.6-beta.0 - esquery: 1.5.0 - jsdoc-type-pratt-parser: 1.0.4 + '@babel/core': 7.22.10 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.22.10) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.10) dev: true - /@esbuild/android-arm64@0.16.17: - resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true + /@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/android-arm64@0.18.15: - resolution: {integrity: sha512-NI/gnWcMl2kXt1HJKOn2H69SYn4YNheKo6NZt1hyfKWdMbaGadxjZIkcj4Gjk/WPxnbFXs9/3HjGHaknCqjrww==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true + /@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/android-arm64@0.18.20: - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true + /@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/android-arm@0.16.17: - resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true + /@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/android-arm@0.18.15: - resolution: {integrity: sha512-wlkQBWb79/jeEEoRmrxt/yhn5T1lU236OCNpnfRzaCJHZ/5gf82uYx1qmADTBWE0AR/v7FiozE1auk2riyQd3w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true + /@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/android-arm@0.18.20: - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true + /@babel/plugin-transform-classes@7.23.5(@babel/core@7.22.10): + resolution: {integrity: sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.22.10) + '@babel/helper-split-export-declaration': 7.22.6 + globals: 11.12.0 dev: true - optional: true - /@esbuild/android-x64@0.16.17: - resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true + /@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.22.15 dev: true - optional: true - /@esbuild/android-x64@0.18.15: - resolution: {integrity: sha512-FM9NQamSaEm/IZIhegF76aiLnng1kEsZl2eve/emxDeReVfRuRNmvT28l6hoFD9TsCxpK+i4v8LPpEj74T7yjA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true + /@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/android-x64@0.18.20: - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true + /@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/darwin-arm64@0.16.17: - resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true + /@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/darwin-arm64@0.18.15: - resolution: {integrity: sha512-XmrFwEOYauKte9QjS6hz60FpOCnw4zaPAb7XV7O4lx1r39XjJhTN7ZpXqJh4sN6q60zbP6QwAVVA8N/wUyBH/w==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true + /@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/darwin-arm64@0.18.20: - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true + /@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/darwin-x64@0.16.17: - resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true + /@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/darwin-x64@0.18.15: - resolution: {integrity: sha512-bMqBmpw1e//7Fh5GLetSZaeo9zSC4/CMtrVFdj+bqKPGJuKyfNJ5Nf2m3LknKZTS+Q4oyPiON+v3eaJ59sLB5A==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true + /@babel/plugin-transform-flow-strip-types@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/darwin-x64@0.18.20: - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true + /@babel/plugin-transform-for-of@7.23.6(@babel/core@7.22.10): + resolution: {integrity: sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: true - optional: true - /@esbuild/freebsd-arm64@0.16.17: - resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true + /@babel/plugin-transform-function-name@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/freebsd-arm64@0.18.15: - resolution: {integrity: sha512-LoTK5N3bOmNI9zVLCeTgnk5Rk0WdUTrr9dyDAQGVMrNTh9EAPuNwSTCgaKOKiDpverOa0htPcO9NwslSE5xuLA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true + /@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/freebsd-arm64@0.18.20: - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true + /@babel/plugin-transform-literals@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/freebsd-x64@0.16.17: - resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true + /@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/freebsd-x64@0.18.15: - resolution: {integrity: sha512-62jX5n30VzgrjAjOk5orYeHFq6sqjvsIj1QesXvn5OZtdt5Gdj0vUNJy9NIpjfdNdqr76jjtzBJKf+h2uzYuTQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true + /@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/freebsd-x64@0.18.20: - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true + /@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-arm64@0.16.17: - resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 dev: true - optional: true - /@esbuild/linux-arm64@0.18.15: - resolution: {integrity: sha512-BWncQeuWDgYv0jTNzJjaNgleduV4tMbQjmk/zpPh/lUdMcNEAxy+jvneDJ6RJkrqloG7tB9S9rCrtfk/kuplsQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-modules-systemjs@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 dev: true - optional: true - /@esbuild/linux-arm64@0.18.20: - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-arm@0.16.17: - resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.22.10): + resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-arm@0.18.15: - resolution: {integrity: sha512-dT4URUv6ir45ZkBqhwZwyFV6cH61k8MttIwhThp2BGiVtagYvCToF+Bggyx2VI57RG4Fbt21f9TmXaYx0DeUJg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-new-target@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-arm@0.18.20: - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/linux-ia32@0.16.17: - resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/linux-ia32@0.18.15: - resolution: {integrity: sha512-JPXORvgHRHITqfms1dWT/GbEY89u848dC08o0yK3fNskhp0t2TuNUnsrrSgOdH28ceb1hJuwyr8R/1RnyPwocw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-object-rest-spread@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/core': 7.22.10 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/linux-ia32@0.18.20: - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-object-super@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/linux-loong64@0.16.17: - resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/linux-loong64@0.18.15: - resolution: {integrity: sha512-kArPI0DopjJCEplsVj/H+2Qgzz7vdFSacHNsgoAKpPS6W/Ndh8Oe24HRDQ5QCu4jHgN6XOtfFfLpRx3TXv/mEg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/linux-loong64@0.18.20: - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-parameters@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-mips64el@0.16.17: - resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-mips64el@0.18.15: - resolution: {integrity: sha512-b/tmngUfO02E00c1XnNTw/0DmloKjb6XQeqxaYuzGwHe0fHVgx5/D6CWi+XH1DvkszjBUkK9BX7n1ARTOst59w==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/linux-mips64el@0.18.20: - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-ppc64@0.16.17: - resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-react-display-name@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-ppc64@0.18.15: - resolution: {integrity: sha512-KXPY69MWw79QJkyvUYb2ex/OgnN/8N/Aw5UDPlgoRtoEfcBqfeLodPr42UojV3NdkoO4u10NXQdamWm1YEzSKw==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-ppc64@0.18.20: - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-riscv64@0.16.17: - resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-react-jsx@7.23.4(@babel/core@7.22.10): + resolution: {integrity: sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.22.10) + '@babel/types': 7.23.6 dev: true - optional: true - /@esbuild/linux-riscv64@0.18.15: - resolution: {integrity: sha512-komK3NEAeeGRnvFEjX1SfVg6EmkfIi5aKzevdvJqMydYr9N+pRQK0PGJXk+bhoPZwOUgLO4l99FZmLGk/L1jWg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + regenerator-transform: 0.15.2 dev: true - optional: true - /@esbuild/linux-riscv64@0.18.20: - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-s390x@0.16.17: - resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-runtime@7.23.7(@babel/core@7.22.10): + resolution: {integrity: sha512-fa0hnfmiXc9fq/weK34MUV0drz2pOL/vfKWvN7Qw127hiUPabFCUMgAbYWcchRzMJit4o5ARsK/s+5h0249pLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + babel-plugin-polyfill-corejs2: 0.4.7(@babel/core@7.22.10) + babel-plugin-polyfill-corejs3: 0.8.7(@babel/core@7.22.10) + babel-plugin-polyfill-regenerator: 0.5.4(@babel/core@7.22.10) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color dev: true - optional: true - /@esbuild/linux-s390x@0.18.15: - resolution: {integrity: sha512-632T5Ts6gQ2WiMLWRRyeflPAm44u2E/s/TJvn+BP6M5mnHSk93cieaypj3VSMYO2ePTCRqAFXtuYi1yv8uZJNA==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-shorthand-properties@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-s390x@0.18.20: - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-spread@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: true - optional: true - /@esbuild/linux-x64@0.16.17: - resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-x64@0.18.15: - resolution: {integrity: sha512-MsHtX0NgvRHsoOtYkuxyk4Vkmvk3PLRWfA4okK7c+6dT0Fu4SUqXAr9y4Q3d8vUf1VWWb6YutpL4XNe400iQ1g==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/linux-x64@0.18.20: - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true + /@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/netbsd-x64@0.16.17: - resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true + /@babel/plugin-transform-typescript@7.23.6(@babel/core@7.22.10): + resolution: {integrity: sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/netbsd-x64@0.18.15: - resolution: {integrity: sha512-djST6s+jQiwxMIVQ5rlt24JFIAr4uwUnzceuFL7BQT4CbrRtqBPueS4GjXSiIpmwVri1Icj/9pFRJ7/aScvT+A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true + /@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/netbsd-x64@0.18.20: - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true + /@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/openbsd-x64@0.16.17: - resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true + /@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/openbsd-x64@0.18.15: - resolution: {integrity: sha512-naeRhUIvhsgeounjkF5mvrNAVMGAm6EJWiabskeE5yOeBbLp7T89tAEw0j5Jm/CZAwyLe3c67zyCWH6fsBLCpw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true + /@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.10) + '@babel/helper-plugin-utils': 7.22.5 dev: true - optional: true - /@esbuild/openbsd-x64@0.18.20: - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true + /@babel/preset-env@7.23.7(@babel/core@7.22.10): + resolution: {integrity: sha512-SY27X/GtTz/L4UryMNJ6p4fH4nsgWbz84y9FE0bQeWJP6O5BhgVCt53CotQKHCOeXJel8VyhlhujhlltKms/CA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/core': 7.22.10 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.23.7(@babel/core@7.22.10) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.10) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.10) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.10) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.10) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-syntax-import-assertions': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.10) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.10) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.10) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.10) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.10) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.22.10) + '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-async-generator-functions': 7.23.7(@babel/core@7.22.10) + '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-classes': 7.23.5(@babel/core@7.22.10) + '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-dotall-regex': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-duplicate-keys': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-dynamic-import': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-exponentiation-operator': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-for-of': 7.23.6(@babel/core@7.22.10) + '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-json-strings': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-logical-assignment-operators': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-modules-amd': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-modules-systemjs': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-modules-umd': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.10) + '@babel/plugin-transform-new-target': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-numeric-separator': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-object-rest-spread': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-optional-catch-binding': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-regenerator': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-reserved-words': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-typeof-symbol': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-unicode-escapes': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-unicode-property-regex': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-unicode-sets-regex': 7.23.3(@babel/core@7.22.10) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.22.10) + babel-plugin-polyfill-corejs2: 0.4.7(@babel/core@7.22.10) + babel-plugin-polyfill-corejs3: 0.8.7(@babel/core@7.22.10) + babel-plugin-polyfill-regenerator: 0.5.4(@babel/core@7.22.10) + core-js-compat: 3.35.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color dev: true - optional: true - /@esbuild/sunos-x64@0.16.17: - resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true + /@babel/preset-flow@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-transform-flow-strip-types': 7.23.3(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/sunos-x64@0.18.15: - resolution: {integrity: sha512-qkT2+WxyKbNIKV1AEhI8QiSIgTHMcRctzSaa/I3kVgMS5dl3fOeoqkb7pW76KwxHoriImhx7Mg3TwN/auMDsyQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.22.10): + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/types': 7.23.6 + esutils: 2.0.3 dev: true - optional: true - /@esbuild/sunos-x64@0.18.20: - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true + /@babel/preset-typescript@7.23.3(@babel/core@7.22.10): + resolution: {integrity: sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.22.10) dev: true - optional: true - /@esbuild/win32-arm64@0.16.17: - resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true + /@babel/register@7.23.7(@babel/core@7.22.10): + resolution: {integrity: sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + clone-deep: 4.0.1 + find-cache-dir: 2.1.0 + make-dir: 2.1.0 + pirates: 4.0.6 + source-map-support: 0.5.21 dev: true - optional: true - /@esbuild/win32-arm64@0.18.15: - resolution: {integrity: sha512-HC4/feP+pB2Vb+cMPUjAnFyERs+HJN7E6KaeBlFdBv799MhD+aPJlfi/yk36SED58J9TPwI8MAcVpJgej4ud0A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true + /@babel/regjsgen@0.8.0: + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} dev: true - optional: true - /@esbuild/win32-arm64@0.18.20: - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true + /@babel/runtime@7.22.6: + resolution: {integrity: sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 dev: true - optional: true - /@esbuild/win32-ia32@0.16.17: - resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true + /@babel/runtime@7.23.7: + resolution: {integrity: sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 - /@esbuild/win32-ia32@0.18.15: - resolution: {integrity: sha512-ovjwoRXI+gf52EVF60u9sSDj7myPixPxqzD5CmkEUmvs+W9Xd0iqISVBQn8xcx4ciIaIVlWCuTbYDOXOnOL44Q==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 dev: true - optional: true - /@esbuild/win32-ia32@0.18.20: - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true + /@babel/traverse@7.23.3: + resolution: {integrity: sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.3 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + debug: 4.3.4(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color dev: true - optional: true - /@esbuild/win32-x64@0.16.17: - resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true + /@babel/types@7.23.6: + resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 dev: true - optional: true - /@esbuild/win32-x64@0.18.15: - resolution: {integrity: sha512-imUxH9a3WJARyAvrG7srLyiK73XdX83NXQkjKvQ+7vPh3ZxoLrzvPkQKKw2DwZ+RV2ZB6vBfNHP8XScAmQC3aA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true + /@changesets/apply-release-plan@7.0.0: + resolution: {integrity: sha512-vfi69JR416qC9hWmFGSxj7N6wA5J222XNBmezSVATPWDVPIF7gkd4d8CpbEbXmRWbVrkoli3oerGS6dcL/BGsQ==} + dependencies: + '@babel/runtime': 7.23.7 + '@changesets/config': 3.0.0 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.6.0 + dev: false - /@esbuild/win32-x64@0.18.20: - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@eslint-community/eslint-utils@4.4.0(eslint@8.52.0): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + /@changesets/assemble-release-plan@6.0.0: + resolution: {integrity: sha512-4QG7NuisAjisbW4hkLCmGW2lRYdPrKzro+fCtZaILX+3zdUELSvYjpL4GTv0E4aM9Mef3PuIQp89VmHJ4y2bfw==} dependencies: - eslint: 8.52.0 - eslint-visitor-keys: 3.4.3 - dev: true + '@babel/runtime': 7.23.7 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.0.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.6.0 + dev: false - /@eslint-community/regexpp@4.6.2: - resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true + /@changesets/changelog-git@0.2.0: + resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} + dependencies: + '@changesets/types': 6.0.0 + dev: false - /@eslint/eslintrc@2.1.2: - resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@changesets/changelog-github@0.4.8: + resolution: {integrity: sha512-jR1DHibkMAb5v/8ym77E4AMNWZKB5NPzw5a5Wtqm1JepAuIF+hrKp2u04NKM14oBZhHglkCfrla9uq8ORnK/dw==} dependencies: - ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) - espree: 9.6.1 - globals: 13.21.0 - ignore: 5.2.4 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 + '@changesets/get-github-info': 0.5.2 + '@changesets/types': 5.2.1 + dotenv: 8.6.0 transitivePeerDependencies: - - supports-color - dev: true - - /@eslint/js@8.52.0: - resolution: {integrity: sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + - encoding dev: true - /@eth-optimism/contracts-periphery@1.0.8: - resolution: {integrity: sha512-n8a9rmlMxl1lWSiC1zHUlr5Qk6qy85nhsmSgpU12El1WY75MOIPknSTQKj+yJhEmrTtI0PViWlKfgviY09pwUg==} + /@changesets/cli@2.27.1: + resolution: {integrity: sha512-iJ91xlvRnnrJnELTp4eJJEOPjgpF3NOh4qeQehM6Ugiz9gJPRZ2t+TsXun6E3AMN4hScZKjqVXl0TX+C7AB3ZQ==} + hasBin: true + dependencies: + '@babel/runtime': 7.23.7 + '@changesets/apply-release-plan': 7.0.0 + '@changesets/assemble-release-plan': 6.0.0 + '@changesets/changelog-git': 0.2.0 + '@changesets/config': 3.0.0 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.0.0 + '@changesets/get-release-plan': 4.0.0 + '@changesets/git': 3.0.0 + '@changesets/logger': 0.1.0 + '@changesets/pre': 2.0.0 + '@changesets/read': 0.6.0 + '@changesets/types': 6.0.0 + '@changesets/write': 0.3.0 + '@manypkg/get-packages': 1.1.3 + '@types/semver': 7.5.7 + ansi-colors: 4.1.3 + chalk: 2.4.2 + ci-info: 3.8.0 + enquirer: 2.3.6 + external-editor: 3.1.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + meow: 6.1.1 + outdent: 0.5.0 + p-limit: 2.3.0 + preferred-pm: 3.0.3 + resolve-from: 5.0.0 + semver: 7.6.0 + spawndamnit: 2.0.0 + term-size: 2.2.1 + tty-table: 4.1.6 dev: false - /@eth-optimism/contracts@0.6.0(ethers@5.7.2): - resolution: {integrity: sha512-vQ04wfG9kMf1Fwy3FEMqH2QZbgS0gldKhcBeBUPfO8zu68L61VI97UDXmsMQXzTsEAxK8HnokW3/gosl4/NW3w==} - peerDependencies: - ethers: ^5 + /@changesets/config@3.0.0: + resolution: {integrity: sha512-o/rwLNnAo/+j9Yvw9mkBQOZySDYyOr/q+wptRLcAVGlU6djOeP9v1nlalbL9MFsobuBVQbZCTp+dIzdq+CLQUA==} dependencies: - '@eth-optimism/core-utils': 0.12.0 - '@ethersproject/abstract-provider': 5.7.0 - '@ethersproject/abstract-signer': 5.7.0 - ethers: 5.7.2 - transitivePeerDependencies: - - bufferutil - - utf-8-validate + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.0.0 + '@changesets/logger': 0.1.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.5 dev: false - /@eth-optimism/core-utils@0.12.0: - resolution: {integrity: sha512-qW+7LZYCz7i8dRa7SRlUKIo1VBU8lvN0HeXCxJR+z+xtMzMQpPds20XJNCMclszxYQHkXY00fOT6GvFw9ZL6nw==} + /@changesets/errors@0.2.0: + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} dependencies: - '@ethersproject/abi': 5.7.0 - '@ethersproject/abstract-provider': 5.7.0 - '@ethersproject/address': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/constants': 5.7.0 - '@ethersproject/contracts': 5.7.0 - '@ethersproject/hash': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/providers': 5.7.2 - '@ethersproject/rlp': 5.7.0 - '@ethersproject/transactions': 5.7.0 - '@ethersproject/web': 5.7.1 - bufio: 1.2.0 - chai: 4.3.10 - transitivePeerDependencies: - - bufferutil - - utf-8-validate + extendable-error: 0.1.7 dev: false - /@ethereum-waffle/chai@4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2): - resolution: {integrity: sha512-X5RepE7Dn8KQLFO7HHAAe+KeGaX/by14hn90wePGBhzL54tq4Y8JscZFu+/LCwCl6TnkAAy5ebiMoqJ37sFtWw==} - engines: {node: '>=10.0'} - peerDependencies: - ethers: '*' + /@changesets/get-dependents-graph@2.0.0: + resolution: {integrity: sha512-cafUXponivK4vBgZ3yLu944mTvam06XEn2IZGjjKc0antpenkYANXiiE6GExV/yKdsCnE8dXVZ25yGqLYZmScA==} dependencies: - '@ethereum-waffle/provider': 4.0.5(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2) - debug: 4.3.4(supports-color@8.1.1) - ethers: 5.7.2 - json-bigint: 1.0.0 - transitivePeerDependencies: - - '@ensdomains/ens' - - '@ensdomains/resolver' - - supports-color - dev: true + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + chalk: 2.4.2 + fs-extra: 7.0.1 + semver: 7.6.0 + dev: false - /@ethereum-waffle/compiler@4.0.3(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(solc@0.8.15)(typechain@8.3.1)(typescript@5.2.2): - resolution: {integrity: sha512-5x5U52tSvEVJS6dpCeXXKvRKyf8GICDwiTwUvGD3/WD+DpvgvaoHOL82XqpTSUHgV3bBq6ma5/8gKUJUIAnJCw==} - engines: {node: '>=10.0'} - peerDependencies: - ethers: '*' - solc: '*' - typechain: ^8.0.0 + /@changesets/get-github-info@0.5.2: + resolution: {integrity: sha512-JppheLu7S114aEs157fOZDjFqUDpm7eHdq5E8SSR0gUBTEK0cNSHsrSR5a66xs0z3RWuo46QvA3vawp8BxDHvg==} dependencies: - '@resolver-engine/imports': 0.3.3 - '@resolver-engine/imports-fs': 0.3.3 - '@typechain/ethers-v5': 10.2.1(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.1)(typescript@5.2.2) - '@types/mkdirp': 0.5.2 - '@types/node-fetch': 2.6.4 - ethers: 5.7.2 - mkdirp: 0.5.6 + dataloader: 1.4.0 node-fetch: 2.6.12 - solc: 0.8.15 - typechain: 8.3.1(typescript@5.2.2) transitivePeerDependencies: - - '@ethersproject/abi' - - '@ethersproject/providers' - encoding - - supports-color - - typescript dev: true - /@ethereum-waffle/ens@4.0.3(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2): - resolution: {integrity: sha512-PVLcdnTbaTfCrfSOrvtlA9Fih73EeDvFS28JQnT5M5P4JMplqmchhcZB1yg/fCtx4cvgHlZXa0+rOCAk2Jk0Jw==} - engines: {node: '>=10.0'} - peerDependencies: - '@ensdomains/ens': ^0.4.4 - '@ensdomains/resolver': ^0.2.4 - ethers: '*' + /@changesets/get-release-plan@4.0.0: + resolution: {integrity: sha512-9L9xCUeD/Tb6L/oKmpm8nyzsOzhdNBBbt/ZNcjynbHC07WW4E1eX8NMGC5g5SbM5z/V+MOrYsJ4lRW41GCbg3w==} dependencies: - '@ensdomains/ens': 0.4.5 - '@ensdomains/resolver': 0.2.4 - ethers: 5.7.2 - dev: true + '@babel/runtime': 7.23.7 + '@changesets/assemble-release-plan': 6.0.0 + '@changesets/config': 3.0.0 + '@changesets/pre': 2.0.0 + '@changesets/read': 0.6.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + dev: false - /@ethereum-waffle/mock-contract@4.0.4(ethers@5.7.2): - resolution: {integrity: sha512-LwEj5SIuEe9/gnrXgtqIkWbk2g15imM/qcJcxpLyAkOj981tQxXmtV4XmQMZsdedEsZ/D/rbUAOtZbgwqgUwQA==} - engines: {node: '>=10.0'} - peerDependencies: - ethers: '*' + /@changesets/get-version-range-type@0.4.0: + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + dev: false + + /@changesets/git@3.0.0: + resolution: {integrity: sha512-vvhnZDHe2eiBNRFHEgMiGd2CT+164dfYyrJDhwwxTVD/OW0FUD6G7+4DIx1dNwkwjHyzisxGAU96q0sVNBns0w==} dependencies: - ethers: 5.7.2 - dev: true + '@babel/runtime': 7.23.7 + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.5 + spawndamnit: 2.0.0 + dev: false - /@ethereum-waffle/provider@4.0.5(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2): - resolution: {integrity: sha512-40uzfyzcrPh+Gbdzv89JJTMBlZwzya1YLDyim8mVbEqYLP5VRYWoGp0JMyaizgV3hMoUFRqJKVmIUw4v7r3hYw==} - engines: {node: '>=10.0'} - peerDependencies: - ethers: '*' + /@changesets/logger@0.1.0: + resolution: {integrity: sha512-pBrJm4CQm9VqFVwWnSqKEfsS2ESnwqwH+xR7jETxIErZcfd1u2zBSqrHbRHR7xjhSgep9x2PSKFKY//FAshA3g==} dependencies: - '@ethereum-waffle/ens': 4.0.3(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2) - '@ganache/ethereum-options': 0.1.4 - debug: 4.3.4(supports-color@8.1.1) - ethers: 5.7.2 - ganache: 7.4.3 - transitivePeerDependencies: - - '@ensdomains/ens' - - '@ensdomains/resolver' - - supports-color - dev: true + chalk: 2.4.2 + dev: false - /@ethereumjs/block@3.6.2: - resolution: {integrity: sha512-mOqYWwMlAZpYUEOEqt7EfMFuVL2eyLqWWIzcf4odn6QgXY8jBI2NhVuJncrMCKeMZrsJAe7/auaRRB6YcdH+Qw==} + /@changesets/parse@0.4.0: + resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} dependencies: - '@ethereumjs/common': 2.6.4 - '@ethereumjs/tx': 3.5.1 - ethereumjs-util: 7.1.5 - merkle-patricia-tree: 4.2.4 + '@changesets/types': 6.0.0 + js-yaml: 3.14.1 + dev: false + + /@changesets/pre@2.0.0: + resolution: {integrity: sha512-HLTNYX/A4jZxc+Sq8D1AMBsv+1qD6rmmJtjsCJa/9MSRybdxh0mjbTvE6JYZQ/ZiQ0mMlDOlGPXTm9KLTU3jyw==} + dependencies: + '@babel/runtime': 7.23.7 + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + dev: false + + /@changesets/read@0.6.0: + resolution: {integrity: sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==} + dependencies: + '@babel/runtime': 7.23.7 + '@changesets/git': 3.0.0 + '@changesets/logger': 0.1.0 + '@changesets/parse': 0.4.0 + '@changesets/types': 6.0.0 + chalk: 2.4.2 + fs-extra: 7.0.1 + p-filter: 2.1.0 + dev: false + + /@changesets/types@4.1.0: + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + dev: false + + /@changesets/types@5.2.1: + resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} dev: true - /@ethereumjs/blockchain@5.5.2: - resolution: {integrity: sha512-Jz26iJmmsQtngerW6r5BDFaew/f2mObLrRZo3rskLOx1lmtMZ8+TX/vJexmivrnWgmAsTdNWhlKUYY4thPhPig==} + /@changesets/types@6.0.0: + resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} + dev: false + + /@changesets/write@0.3.0: + resolution: {integrity: sha512-slGLb21fxZVUYbyea+94uFiD6ntQW0M2hIKNznFizDhZPDgn2c/fv1UzzlW43RVzh1BEDuIqW6hzlJ1OflNmcw==} dependencies: - '@ethereumjs/block': 3.6.2 - '@ethereumjs/common': 2.6.4 - '@ethereumjs/ethash': 1.1.0 - debug: 4.3.4(supports-color@8.1.1) - ethereumjs-util: 7.1.5 - level-mem: 5.0.1 - lru-cache: 5.1.1 - semaphore-async-await: 1.5.1 + '@babel/runtime': 7.23.7 + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + dev: false + + /@coinbase/wallet-sdk@3.9.1: + resolution: {integrity: sha512-cGUE8wm1/cMI8irRMVOqbFWYcnNugqCtuy2lnnHfgloBg+GRLs9RsrkOUDMdv/StfUeeKhCDyYudsXXvcL1xIA==} + dependencies: + bn.js: 5.2.1 + buffer: 6.0.3 + clsx: 1.2.1 + eth-block-tracker: 7.1.0 + eth-json-rpc-filters: 6.0.1 + eventemitter3: 5.0.1 + keccak: 3.0.3 + preact: 10.16.0 + sha.js: 2.4.11 transitivePeerDependencies: - supports-color dev: true - /@ethereumjs/common@2.6.0: - resolution: {integrity: sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==} + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} dependencies: - crc-32: 1.2.2 - ethereumjs-util: 7.1.5 + '@jridgewell/trace-mapping': 0.3.9 dev: true - /@ethereumjs/common@2.6.4: - resolution: {integrity: sha512-RDJh/R/EAr+B7ZRg5LfJ0BIpf/1LydFgYdvZEuTraojCbVypO2sQ+QnpP5u2wJf9DASyooKqu8O4FJEWUV6NXw==} + /@emotion/babel-plugin@11.11.0: + resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} dependencies: - crc-32: 1.2.2 - ethereumjs-util: 7.1.5 + '@babel/helper-module-imports': 7.22.15 + '@babel/runtime': 7.23.7 + '@emotion/hash': 0.9.1 + '@emotion/memoize': 0.8.1 + '@emotion/serialize': 1.1.3 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.2.0 dev: true - /@ethereumjs/ethash@1.1.0: - resolution: {integrity: sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==} + /@emotion/cache@11.11.0: + resolution: {integrity: sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==} dependencies: - '@ethereumjs/block': 3.6.2 - '@types/levelup': 4.3.3 - buffer-xor: 2.0.2 - ethereumjs-util: 7.1.5 - miller-rabin: 4.0.1 + '@emotion/memoize': 0.8.1 + '@emotion/sheet': 1.2.2 + '@emotion/utils': 1.2.1 + '@emotion/weak-memoize': 0.3.1 + stylis: 4.2.0 dev: true - /@ethereumjs/rlp@4.0.1: - resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} - engines: {node: '>=14'} - hasBin: true + /@emotion/hash@0.9.1: + resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + dev: true - /@ethereumjs/rlp@5.0.0: - resolution: {integrity: sha512-WuS1l7GJmB0n0HsXLozCoEFc9IwYgf3l0gCkKVYgR67puVF1O4OpEaN0hWmm1c+iHUHFCKt1hJrvy5toLg+6ag==} - engines: {node: '>=18'} - hasBin: true - dev: false - - /@ethereumjs/tx@3.4.0: - resolution: {integrity: sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==} + /@emotion/is-prop-valid@1.2.1: + resolution: {integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==} dependencies: - '@ethereumjs/common': 2.6.4 - ethereumjs-util: 7.1.5 + '@emotion/memoize': 0.8.1 dev: true - /@ethereumjs/tx@3.5.1: - resolution: {integrity: sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==} - dependencies: - '@ethereumjs/common': 2.6.4 - ethereumjs-util: 7.1.5 + /@emotion/memoize@0.8.1: + resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: true - /@ethereumjs/util@8.1.0: - resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} - engines: {node: '>=14'} + /@emotion/react@11.11.3(react@18.2.0): + resolution: {integrity: sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==} + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true dependencies: - '@ethereumjs/rlp': 4.0.1 - ethereum-cryptography: 2.1.2 - micro-ftch: 0.3.1 + '@babel/runtime': 7.23.7 + '@emotion/babel-plugin': 11.11.0 + '@emotion/cache': 11.11.0 + '@emotion/serialize': 1.1.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@emotion/utils': 1.2.1 + '@emotion/weak-memoize': 0.3.1 + hoist-non-react-statics: 3.3.2 + react: 18.2.0 + dev: true - /@ethereumjs/vm@5.6.0: - resolution: {integrity: sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==} + /@emotion/serialize@1.1.3: + resolution: {integrity: sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==} dependencies: - '@ethereumjs/block': 3.6.2 - '@ethereumjs/blockchain': 5.5.2 - '@ethereumjs/common': 2.6.4 - '@ethereumjs/tx': 3.5.1 - async-eventemitter: 0.2.4 - core-js-pure: 3.16.2 - debug: 2.6.9 - ethereumjs-util: 7.1.5 - functional-red-black-tree: 1.0.1 - mcl-wasm: 0.7.8 - merkle-patricia-tree: 4.2.4 - rustbn.js: 0.2.0 - transitivePeerDependencies: - - supports-color + '@emotion/hash': 0.9.1 + '@emotion/memoize': 0.8.1 + '@emotion/unitless': 0.8.1 + '@emotion/utils': 1.2.1 + csstype: 3.1.2 dev: true - /@ethersproject/abi@5.7.0: - resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} - dependencies: - '@ethersproject/address': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/constants': 5.7.0 - '@ethersproject/hash': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/strings': 5.7.0 + /@emotion/sheet@1.2.2: + resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} + dev: true - /@ethersproject/abstract-provider@5.7.0: - resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} + /@emotion/styled@11.11.0(@emotion/react@11.11.3)(react@18.2.0): + resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==} + peerDependencies: + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true dependencies: - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/networks': 5.7.1 - '@ethersproject/properties': 5.7.0 - '@ethersproject/transactions': 5.7.0 - '@ethersproject/web': 5.7.1 + '@babel/runtime': 7.23.7 + '@emotion/babel-plugin': 11.11.0 + '@emotion/is-prop-valid': 1.2.1 + '@emotion/react': 11.11.3(react@18.2.0) + '@emotion/serialize': 1.1.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@emotion/utils': 1.2.1 + react: 18.2.0 + dev: true - /@ethersproject/abstract-signer@5.7.0: - resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} - dependencies: - '@ethersproject/abstract-provider': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 + /@emotion/unitless@0.8.1: + resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} + dev: true - /@ethersproject/address@5.7.0: - resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} + /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0): + resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} + peerDependencies: + react: '>=16.8.0' dependencies: - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/rlp': 5.7.0 + react: 18.2.0 + dev: true - /@ethersproject/base64@5.7.0: - resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} - dependencies: - '@ethersproject/bytes': 5.7.0 + /@emotion/utils@1.2.1: + resolution: {integrity: sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==} + dev: true - /@ethersproject/basex@5.7.0: - resolution: {integrity: sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==} - dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/properties': 5.7.0 + /@emotion/weak-memoize@0.3.1: + resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} + dev: true - /@ethersproject/bignumber@5.7.0: - resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} + /@ensdomains/ens@0.4.5: + resolution: {integrity: sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==} + deprecated: Please use @ensdomains/ens-contracts dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - bn.js: 5.2.1 + bluebird: 3.7.2 + eth-ens-namehash: 2.0.8 + solc: 0.4.26 + testrpc: 0.0.1 + web3-utils: 1.10.1 + dev: true - /@ethersproject/bytes@5.7.0: - resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} - dependencies: - '@ethersproject/logger': 5.7.0 + /@ensdomains/resolver@0.2.4: + resolution: {integrity: sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==} + deprecated: Please use @ensdomains/ens-contracts + dev: true - /@ethersproject/constants@5.7.0: - resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} + /@es-joy/jsdoccomment@0.42.0: + resolution: {integrity: sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==} + engines: {node: '>=16'} dependencies: - '@ethersproject/bignumber': 5.7.0 + comment-parser: 1.4.1 + esquery: 1.5.0 + jsdoc-type-pratt-parser: 4.0.0 + dev: true - /@ethersproject/contracts@5.7.0: - resolution: {integrity: sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==} - dependencies: - '@ethersproject/abi': 5.7.0 - '@ethersproject/abstract-provider': 5.7.0 - '@ethersproject/abstract-signer': 5.7.0 - '@ethersproject/address': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/constants': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/transactions': 5.7.0 + /@esbuild/aix-ppc64@0.19.10: + resolution: {integrity: sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true - /@ethersproject/hash@5.7.0: - resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} - dependencies: - '@ethersproject/abstract-signer': 5.7.0 - '@ethersproject/address': 5.7.0 - '@ethersproject/base64': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/strings': 5.7.0 + /@esbuild/android-arm64@0.19.10: + resolution: {integrity: sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true - /@ethersproject/hdnode@5.7.0: - resolution: {integrity: sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==} - dependencies: - '@ethersproject/abstract-signer': 5.7.0 - '@ethersproject/basex': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/pbkdf2': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/sha2': 5.7.0 - '@ethersproject/signing-key': 5.7.0 - '@ethersproject/strings': 5.7.0 - '@ethersproject/transactions': 5.7.0 - '@ethersproject/wordlists': 5.7.0 + /@esbuild/android-arm64@0.19.7: + resolution: {integrity: sha512-YEDcw5IT7hW3sFKZBkCAQaOCJQLONVcD4bOyTXMZz5fr66pTHnAet46XAtbXAkJRfIn2YVhdC6R9g4xa27jQ1w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true - /@ethersproject/json-wallets@5.7.0: - resolution: {integrity: sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==} - dependencies: - '@ethersproject/abstract-signer': 5.7.0 - '@ethersproject/address': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/hdnode': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/pbkdf2': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/random': 5.7.0 - '@ethersproject/strings': 5.7.0 - '@ethersproject/transactions': 5.7.0 - aes-js: 3.0.0 - scrypt-js: 3.0.1 + /@esbuild/android-arm@0.19.10: + resolution: {integrity: sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true - /@ethersproject/keccak256@5.7.0: - resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} - dependencies: - '@ethersproject/bytes': 5.7.0 - js-sha3: 0.8.0 + /@esbuild/android-arm@0.19.7: + resolution: {integrity: sha512-YGSPnndkcLo4PmVl2tKatEn+0mlVMr3yEpOOT0BeMria87PhvoJb5dg5f5Ft9fbCVgtAz4pWMzZVgSEGpDAlww==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true - /@ethersproject/logger@5.7.0: - resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} + /@esbuild/android-x64@0.19.10: + resolution: {integrity: sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true - /@ethersproject/networks@5.7.1: - resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} - dependencies: - '@ethersproject/logger': 5.7.0 + /@esbuild/android-x64@0.19.7: + resolution: {integrity: sha512-jhINx8DEjz68cChFvM72YzrqfwJuFbfvSxZAk4bebpngGfNNRm+zRl4rtT9oAX6N9b6gBcFaJHFew5Blf6CvUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true - /@ethersproject/pbkdf2@5.7.0: - resolution: {integrity: sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==} - dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/sha2': 5.7.0 + /@esbuild/darwin-arm64@0.19.10: + resolution: {integrity: sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true - /@ethersproject/properties@5.7.0: - resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} - dependencies: - '@ethersproject/logger': 5.7.0 + /@esbuild/darwin-arm64@0.19.7: + resolution: {integrity: sha512-dr81gbmWN//3ZnBIm6YNCl4p3pjnabg1/ZVOgz2fJoUO1a3mq9WQ/1iuEluMs7mCL+Zwv7AY5e3g1hjXqQZ9Iw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true - /@ethersproject/providers@5.7.2: + /@esbuild/darwin-x64@0.19.10: + resolution: {integrity: sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.19.7: + resolution: {integrity: sha512-Lc0q5HouGlzQEwLkgEKnWcSazqr9l9OdV2HhVasWJzLKeOt0PLhHaUHuzb8s/UIya38DJDoUm74GToZ6Wc7NGQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.19.10: + resolution: {integrity: sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.19.7: + resolution: {integrity: sha512-+y2YsUr0CxDFF7GWiegWjGtTUF6gac2zFasfFkRJPkMAuMy9O7+2EH550VlqVdpEEchWMynkdhC9ZjtnMiHImQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.19.10: + resolution: {integrity: sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.19.7: + resolution: {integrity: sha512-CdXOxIbIzPJmJhrpmJTLx+o35NoiKBIgOvmvT+jeSadYiWJn0vFKsl+0bSG/5lwjNHoIDEyMYc/GAPR9jxusTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.19.10: + resolution: {integrity: sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.19.7: + resolution: {integrity: sha512-inHqdOVCkUhHNvuQPT1oCB7cWz9qQ/Cz46xmVe0b7UXcuIJU3166aqSunsqkgSGMtUCWOZw3+KMwI6otINuC9g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.19.10: + resolution: {integrity: sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.19.7: + resolution: {integrity: sha512-Y+SCmWxsJOdQtjcBxoacn/pGW9HDZpwsoof0ttL+2vGcHokFlfqV666JpfLCSP2xLxFpF1lj7T3Ox3sr95YXww==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.19.10: + resolution: {integrity: sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.19.7: + resolution: {integrity: sha512-2BbiL7nLS5ZO96bxTQkdO0euGZIUQEUXMTrqLxKUmk/Y5pmrWU84f+CMJpM8+EHaBPfFSPnomEaQiG/+Gmh61g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.19.10: + resolution: {integrity: sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.19.7: + resolution: {integrity: sha512-BVFQla72KXv3yyTFCQXF7MORvpTo4uTA8FVFgmwVrqbB/4DsBFWilUm1i2Oq6zN36DOZKSVUTb16jbjedhfSHw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.19.10: + resolution: {integrity: sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.19.7: + resolution: {integrity: sha512-DzAYckIaK+pS31Q/rGpvUKu7M+5/t+jI+cdleDgUwbU7KdG2eC3SUbZHlo6Q4P1CfVKZ1lUERRFP8+q0ob9i2w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.19.10: + resolution: {integrity: sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.19.7: + resolution: {integrity: sha512-JQ1p0SmUteNdUaaiRtyS59GkkfTW0Edo+e0O2sihnY4FoZLz5glpWUQEKMSzMhA430ctkylkS7+vn8ziuhUugQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.19.10: + resolution: {integrity: sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.19.7: + resolution: {integrity: sha512-xGwVJ7eGhkprY/nB7L7MXysHduqjpzUl40+XoYDGC4UPLbnG+gsyS1wQPJ9lFPcxYAaDXbdRXd1ACs9AE9lxuw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.19.10: + resolution: {integrity: sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.19.7: + resolution: {integrity: sha512-U8Rhki5PVU0L0nvk+E8FjkV8r4Lh4hVEb9duR6Zl21eIEYEwXz8RScj4LZWA2i3V70V4UHVgiqMpszXvG0Yqhg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.19.10: + resolution: {integrity: sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.19.7: + resolution: {integrity: sha512-ZYZopyLhm4mcoZXjFt25itRlocKlcazDVkB4AhioiL9hOWhDldU9n38g62fhOI4Pth6vp+Mrd5rFKxD0/S+7aQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.19.10: + resolution: {integrity: sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.19.7: + resolution: {integrity: sha512-/yfjlsYmT1O3cum3J6cmGG16Fd5tqKMcg5D+sBYLaOQExheAJhqr8xOAEIuLo8JYkevmjM5zFD9rVs3VBcsjtQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.19.10: + resolution: {integrity: sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.19.7: + resolution: {integrity: sha512-MYDFyV0EW1cTP46IgUJ38OnEY5TaXxjoDmwiTXPjezahQgZd+j3T55Ht8/Q9YXBM0+T9HJygrSRGV5QNF/YVDQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.19.10: + resolution: {integrity: sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.19.7: + resolution: {integrity: sha512-JcPvgzf2NN/y6X3UUSqP6jSS06V0DZAV/8q0PjsZyGSXsIGcG110XsdmuWiHM+pno7/mJF6fjH5/vhUz/vA9fw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.19.10: + resolution: {integrity: sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.19.7: + resolution: {integrity: sha512-ZA0KSYti5w5toax5FpmfcAgu3ZNJxYSRm0AW/Dao5up0YV1hDVof1NvwLomjEN+3/GMtaWDI+CIyJOMTRSTdMw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.19.10: + resolution: {integrity: sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.19.7: + resolution: {integrity: sha512-CTOnijBKc5Jpk6/W9hQMMvJnsSYRYgveN6O75DTACCY18RA2nqka8dTZR+x/JqXCRiKk84+5+bRKXUSbbwsS0A==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.19.10: + resolution: {integrity: sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.19.7: + resolution: {integrity: sha512-gRaP2sk6hc98N734luX4VpF318l3w+ofrtTu9j5L8EQXF+FzQKV6alCOHMVoJJHvVK/mGbwBXfOL1HETQu9IGQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.56.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.6.2: + resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4(supports-color@8.1.1) + espree: 9.6.1 + globals: 13.21.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.56.0: + resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@eth-optimism/contracts-periphery@1.0.8: + resolution: {integrity: sha512-n8a9rmlMxl1lWSiC1zHUlr5Qk6qy85nhsmSgpU12El1WY75MOIPknSTQKj+yJhEmrTtI0PViWlKfgviY09pwUg==} + dev: false + + /@eth-optimism/contracts@0.6.0(ethers@5.7.2): + resolution: {integrity: sha512-vQ04wfG9kMf1Fwy3FEMqH2QZbgS0gldKhcBeBUPfO8zu68L61VI97UDXmsMQXzTsEAxK8HnokW3/gosl4/NW3w==} + peerDependencies: + ethers: ^5 + dependencies: + '@eth-optimism/core-utils': 0.12.0 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + ethers: 5.7.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /@eth-optimism/core-utils@0.12.0: + resolution: {integrity: sha512-qW+7LZYCz7i8dRa7SRlUKIo1VBU8lvN0HeXCxJR+z+xtMzMQpPds20XJNCMclszxYQHkXY00fOT6GvFw9ZL6nw==} + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/contracts': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/providers': 5.7.2 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + bufio: 1.2.0 + chai: 4.3.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /@ethereum-waffle/chai@4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2): + resolution: {integrity: sha512-X5RepE7Dn8KQLFO7HHAAe+KeGaX/by14hn90wePGBhzL54tq4Y8JscZFu+/LCwCl6TnkAAy5ebiMoqJ37sFtWw==} + engines: {node: '>=10.0'} + peerDependencies: + ethers: '*' + dependencies: + '@ethereum-waffle/provider': 4.0.5(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2) + debug: 4.3.4(supports-color@8.1.1) + ethers: 5.7.2 + json-bigint: 1.0.0 + transitivePeerDependencies: + - '@ensdomains/ens' + - '@ensdomains/resolver' + - supports-color + dev: true + + /@ethereum-waffle/compiler@4.0.3(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(solc@0.8.15)(typechain@8.3.1)(typescript@5.3.3): + resolution: {integrity: sha512-5x5U52tSvEVJS6dpCeXXKvRKyf8GICDwiTwUvGD3/WD+DpvgvaoHOL82XqpTSUHgV3bBq6ma5/8gKUJUIAnJCw==} + engines: {node: '>=10.0'} + peerDependencies: + ethers: '*' + solc: '*' + typechain: ^8.0.0 + dependencies: + '@resolver-engine/imports': 0.3.3 + '@resolver-engine/imports-fs': 0.3.3 + '@typechain/ethers-v5': 10.2.1(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.1)(typescript@5.3.3) + '@types/mkdirp': 0.5.2 + '@types/node-fetch': 2.6.4 + ethers: 5.7.2 + mkdirp: 0.5.6 + node-fetch: 2.6.12 + solc: 0.8.15 + typechain: 8.3.1(typescript@5.3.3) + transitivePeerDependencies: + - '@ethersproject/abi' + - '@ethersproject/providers' + - encoding + - supports-color + - typescript + dev: true + + /@ethereum-waffle/ens@4.0.3(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2): + resolution: {integrity: sha512-PVLcdnTbaTfCrfSOrvtlA9Fih73EeDvFS28JQnT5M5P4JMplqmchhcZB1yg/fCtx4cvgHlZXa0+rOCAk2Jk0Jw==} + engines: {node: '>=10.0'} + peerDependencies: + '@ensdomains/ens': ^0.4.4 + '@ensdomains/resolver': ^0.2.4 + ethers: '*' + dependencies: + '@ensdomains/ens': 0.4.5 + '@ensdomains/resolver': 0.2.4 + ethers: 5.7.2 + dev: true + + /@ethereum-waffle/mock-contract@4.0.4(ethers@5.7.2): + resolution: {integrity: sha512-LwEj5SIuEe9/gnrXgtqIkWbk2g15imM/qcJcxpLyAkOj981tQxXmtV4XmQMZsdedEsZ/D/rbUAOtZbgwqgUwQA==} + engines: {node: '>=10.0'} + peerDependencies: + ethers: '*' + dependencies: + ethers: 5.7.2 + dev: true + + /@ethereum-waffle/provider@4.0.5(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2): + resolution: {integrity: sha512-40uzfyzcrPh+Gbdzv89JJTMBlZwzya1YLDyim8mVbEqYLP5VRYWoGp0JMyaizgV3hMoUFRqJKVmIUw4v7r3hYw==} + engines: {node: '>=10.0'} + peerDependencies: + ethers: '*' + dependencies: + '@ethereum-waffle/ens': 4.0.3(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2) + '@ganache/ethereum-options': 0.1.4 + debug: 4.3.4(supports-color@8.1.1) + ethers: 5.7.2 + ganache: 7.4.3 + transitivePeerDependencies: + - '@ensdomains/ens' + - '@ensdomains/resolver' + - supports-color + dev: true + + /@ethereumjs/block@3.6.2: + resolution: {integrity: sha512-mOqYWwMlAZpYUEOEqt7EfMFuVL2eyLqWWIzcf4odn6QgXY8jBI2NhVuJncrMCKeMZrsJAe7/auaRRB6YcdH+Qw==} + dependencies: + '@ethereumjs/common': 2.6.4 + '@ethereumjs/tx': 3.5.1 + ethereumjs-util: 7.1.5 + merkle-patricia-tree: 4.2.4 + dev: true + + /@ethereumjs/blockchain@5.5.2: + resolution: {integrity: sha512-Jz26iJmmsQtngerW6r5BDFaew/f2mObLrRZo3rskLOx1lmtMZ8+TX/vJexmivrnWgmAsTdNWhlKUYY4thPhPig==} + dependencies: + '@ethereumjs/block': 3.6.2 + '@ethereumjs/common': 2.6.4 + '@ethereumjs/ethash': 1.1.0 + debug: 4.3.4(supports-color@8.1.1) + ethereumjs-util: 7.1.5 + level-mem: 5.0.1 + lru-cache: 5.1.1 + semaphore-async-await: 1.5.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@ethereumjs/common@2.6.0: + resolution: {integrity: sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==} + dependencies: + crc-32: 1.2.2 + ethereumjs-util: 7.1.5 + dev: true + + /@ethereumjs/common@2.6.4: + resolution: {integrity: sha512-RDJh/R/EAr+B7ZRg5LfJ0BIpf/1LydFgYdvZEuTraojCbVypO2sQ+QnpP5u2wJf9DASyooKqu8O4FJEWUV6NXw==} + dependencies: + crc-32: 1.2.2 + ethereumjs-util: 7.1.5 + dev: true + + /@ethereumjs/common@3.2.0: + resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==} + dependencies: + '@ethereumjs/util': 8.1.0 + crc-32: 1.2.2 + dev: true + + /@ethereumjs/ethash@1.1.0: + resolution: {integrity: sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==} + dependencies: + '@ethereumjs/block': 3.6.2 + '@types/levelup': 4.3.3 + buffer-xor: 2.0.2 + ethereumjs-util: 7.1.5 + miller-rabin: 4.0.1 + dev: true + + /@ethereumjs/rlp@4.0.1: + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + /@ethereumjs/rlp@5.0.2: + resolution: {integrity: sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==} + engines: {node: '>=18'} + hasBin: true + dev: false + + /@ethereumjs/tx@3.4.0: + resolution: {integrity: sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==} + dependencies: + '@ethereumjs/common': 2.6.4 + ethereumjs-util: 7.1.5 + dev: true + + /@ethereumjs/tx@3.5.1: + resolution: {integrity: sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==} + dependencies: + '@ethereumjs/common': 2.6.4 + ethereumjs-util: 7.1.5 + dev: true + + /@ethereumjs/tx@4.2.0: + resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==} + engines: {node: '>=14'} + dependencies: + '@ethereumjs/common': 3.2.0 + '@ethereumjs/rlp': 4.0.1 + '@ethereumjs/util': 8.1.0 + ethereum-cryptography: 2.1.2 + dev: true + + /@ethereumjs/util@8.1.0: + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} + dependencies: + '@ethereumjs/rlp': 4.0.1 + ethereum-cryptography: 2.1.2 + micro-ftch: 0.3.1 + + /@ethereumjs/vm@5.6.0: + resolution: {integrity: sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==} + dependencies: + '@ethereumjs/block': 3.6.2 + '@ethereumjs/blockchain': 5.5.2 + '@ethereumjs/common': 2.6.4 + '@ethereumjs/tx': 3.5.1 + async-eventemitter: 0.2.4 + core-js-pure: 3.16.2 + debug: 2.6.9 + ethereumjs-util: 7.1.5 + functional-red-black-tree: 1.0.1 + mcl-wasm: 0.7.8 + merkle-patricia-tree: 4.2.4 + rustbn.js: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@ethersproject/abi@5.7.0: + resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + /@ethersproject/abstract-provider@5.7.0: + resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + + /@ethersproject/abstract-signer@5.7.0: + resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + + /@ethersproject/address@5.7.0: + resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/rlp': 5.7.0 + + /@ethersproject/base64@5.7.0: + resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} + dependencies: + '@ethersproject/bytes': 5.7.0 + + /@ethersproject/basex@5.7.0: + resolution: {integrity: sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/properties': 5.7.0 + + /@ethersproject/bignumber@5.7.0: + resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + bn.js: 5.2.1 + + /@ethersproject/bytes@5.7.0: + resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} + dependencies: + '@ethersproject/logger': 5.7.0 + + /@ethersproject/constants@5.7.0: + resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} + dependencies: + '@ethersproject/bignumber': 5.7.0 + + /@ethersproject/contracts@5.7.0: + resolution: {integrity: sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==} + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + + /@ethersproject/hash@5.7.0: + resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + /@ethersproject/hdnode@5.7.0: + resolution: {integrity: sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==} + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/wordlists': 5.7.0 + + /@ethersproject/json-wallets@5.7.0: + resolution: {integrity: sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==} + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + aes-js: 3.0.0 + scrypt-js: 3.0.1 + + /@ethersproject/keccak256@5.7.0: + resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} + dependencies: + '@ethersproject/bytes': 5.7.0 + js-sha3: 0.8.0 + + /@ethersproject/logger@5.7.0: + resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} + + /@ethersproject/networks@5.7.1: + resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} + dependencies: + '@ethersproject/logger': 5.7.0 + + /@ethersproject/pbkdf2@5.7.0: + resolution: {integrity: sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/sha2': 5.7.0 + + /@ethersproject/properties@5.7.0: + resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} + dependencies: + '@ethersproject/logger': 5.7.0 + + /@ethersproject/providers@5.7.2: resolution: {integrity: sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==} dependencies: - '@ethersproject/abstract-provider': 5.7.0 - '@ethersproject/abstract-signer': 5.7.0 - '@ethersproject/address': 5.7.0 - '@ethersproject/base64': 5.7.0 - '@ethersproject/basex': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/constants': 5.7.0 - '@ethersproject/hash': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/networks': 5.7.1 - '@ethersproject/properties': 5.7.0 - '@ethersproject/random': 5.7.0 - '@ethersproject/rlp': 5.7.0 - '@ethersproject/sha2': 5.7.0 - '@ethersproject/strings': 5.7.0 - '@ethersproject/transactions': 5.7.0 - '@ethersproject/web': 5.7.1 - bech32: 1.1.4 - ws: 7.4.6 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + bech32: 1.1.4 + ws: 7.4.6 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + /@ethersproject/random@5.7.0: + resolution: {integrity: sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + + /@ethersproject/rlp@5.7.0: + resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + + /@ethersproject/sha2@5.7.0: + resolution: {integrity: sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + hash.js: 1.1.7 + + /@ethersproject/signing-key@5.7.0: + resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + bn.js: 5.2.1 + elliptic: 6.5.4 + hash.js: 1.1.7 + + /@ethersproject/solidity@5.7.0: + resolution: {integrity: sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==} + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/strings': 5.7.0 + + /@ethersproject/strings@5.7.0: + resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + + /@ethersproject/transactions@5.7.0: + resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + + /@ethersproject/units@5.7.0: + resolution: {integrity: sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==} + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + + /@ethersproject/wallet@5.7.0: + resolution: {integrity: sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==} + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/json-wallets': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/wordlists': 5.7.0 + + /@ethersproject/web@5.7.1: + resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} + dependencies: + '@ethersproject/base64': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + /@ethersproject/wordlists@5.7.0: + resolution: {integrity: sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==} + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + /@ganache/ethereum-address@0.1.4: + resolution: {integrity: sha512-sTkU0M9z2nZUzDeHRzzGlW724xhMLXo2LeX1hixbnjHWY1Zg1hkqORywVfl+g5uOO8ht8T0v+34IxNxAhmWlbw==} + dependencies: + '@ganache/utils': 0.1.4 + dev: true + + /@ganache/ethereum-options@0.1.4: + resolution: {integrity: sha512-i4l46taoK2yC41FPkcoDlEVoqHS52wcbHPqJtYETRWqpOaoj9hAg/EJIHLb1t6Nhva2CdTO84bG+qlzlTxjAHw==} + dependencies: + '@ganache/ethereum-address': 0.1.4 + '@ganache/ethereum-utils': 0.1.4 + '@ganache/options': 0.1.4 + '@ganache/utils': 0.1.4 + bip39: 3.0.4 + seedrandom: 3.0.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@ganache/ethereum-utils@0.1.4: + resolution: {integrity: sha512-FKXF3zcdDrIoCqovJmHLKZLrJ43234Em2sde/3urUT/10gSgnwlpFmrv2LUMAmSbX3lgZhW/aSs8krGhDevDAg==} + dependencies: + '@ethereumjs/common': 2.6.0 + '@ethereumjs/tx': 3.4.0 + '@ethereumjs/vm': 5.6.0 + '@ganache/ethereum-address': 0.1.4 + '@ganache/rlp': 0.1.4 + '@ganache/utils': 0.1.4 + emittery: 0.10.0 + ethereumjs-abi: 0.6.8 + ethereumjs-util: 7.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@ganache/options@0.1.4: + resolution: {integrity: sha512-zAe/craqNuPz512XQY33MOAG6Si1Xp0hCvfzkBfj2qkuPcbJCq6W/eQ5MB6SbXHrICsHrZOaelyqjuhSEmjXRw==} + dependencies: + '@ganache/utils': 0.1.4 + bip39: 3.0.4 + seedrandom: 3.0.5 + dev: true + + /@ganache/rlp@0.1.4: + resolution: {integrity: sha512-Do3D1H6JmhikB+6rHviGqkrNywou/liVeFiKIpOBLynIpvZhRCgn3SEDxyy/JovcaozTo/BynHumfs5R085MFQ==} + dependencies: + '@ganache/utils': 0.1.4 + rlp: 2.2.6 + dev: true + + /@ganache/utils@0.1.4: + resolution: {integrity: sha512-oatUueU3XuXbUbUlkyxeLLH3LzFZ4y5aSkNbx6tjSIhVTPeh+AuBKYt4eQ73FFcTB3nj/gZoslgAh5CN7O369w==} + dependencies: + emittery: 0.10.0 + keccak: 3.0.1 + seedrandom: 3.0.5 + optionalDependencies: + '@trufflesuite/bigint-buffer': 1.1.9 + dev: true + + /@hapi/hoek@9.3.0: + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + dev: true + + /@hapi/topo@5.1.0: + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + dependencies: + '@hapi/hoek': 9.3.0 + dev: true + + /@humanwhocodes/config-array@0.11.13: + resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 2.0.1 + debug: 4.3.4(supports-color@8.1.1) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.1: + resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + dev: true + + /@ioredis/commands@1.2.0: + resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + dev: true + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true + + /@isaacs/ttlcache@1.4.1: + resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} + engines: {node: '>=12'} + dev: true + + /@istanbuljs/load-nyc-config@1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/create-cache-key-function@29.7.0: + resolution: {integrity: sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + dev: true + + /@jest/environment@29.7.0: + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.11.17 + jest-mock: 29.7.0 + dev: true + + /@jest/fake-timers@29.7.0: + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.11.17 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + dev: true + + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 + dev: true + + /@jest/types@26.6.2: + resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==} + engines: {node: '>= 10.14.2'} + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.11.17 + '@types/yargs': 15.0.19 + chalk: 4.1.2 + dev: true + + /@jest/types@29.6.3: + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.11.17 + '@types/yargs': 17.0.32 + chalk: 4.1.2 + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/source-map@0.3.5: + resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.19: + resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@lit-labs/ssr-dom-shim@1.1.1: + resolution: {integrity: sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ==} + dev: true + + /@lit/reactive-element@1.6.2: + resolution: {integrity: sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==} + dependencies: + '@lit-labs/ssr-dom-shim': 1.1.1 + dev: true + + /@manypkg/find-root@1.1.0: + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + dependencies: + '@babel/runtime': 7.23.7 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + dev: false + + /@manypkg/get-packages@1.1.3: + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + dependencies: + '@babel/runtime': 7.23.7 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + dev: false + + /@metamask/eth-json-rpc-provider@1.0.1: + resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==} + engines: {node: '>=14.0.0'} + dependencies: + '@metamask/json-rpc-engine': 7.3.1 + '@metamask/safe-event-emitter': 3.0.0 + '@metamask/utils': 5.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@metamask/eth-sig-util@4.0.0: + resolution: {integrity: sha512-LczOjjxY4A7XYloxzyxJIHONELmUxVZncpOLoClpEcTiebiVdM46KRPYXGuULro9oNNR2xdVx3yoKiQjdfWmoA==} + engines: {node: '>=12.0.0'} + dependencies: + ethereumjs-abi: 0.6.8 + ethereumjs-util: 6.2.1 + ethjs-util: 0.1.6 + tweetnacl: 1.0.3 + tweetnacl-util: 0.15.1 + dev: true + + /@metamask/json-rpc-engine@7.3.1: + resolution: {integrity: sha512-OVxccX/IFOjPzCzSFAEceccPIAf7A7IwnvjyWjyHCkLrO+LWV4e7Tpe79JNXiORywNulHxrg+q6QrmrnGEwssQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@metamask/rpc-errors': 6.1.0 + '@metamask/safe-event-emitter': 3.0.0 + '@metamask/utils': 8.2.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@metamask/object-multiplex@1.3.0: + resolution: {integrity: sha512-czcQeVYdSNtabd+NcYQnrM69MciiJyd1qvKH8WM2Id3C0ZiUUX5Xa/MK+/VUk633DBhVOwdNzAKIQ33lGyA+eQ==} + engines: {node: '>=12.0.0'} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + readable-stream: 2.3.8 + dev: true + + /@metamask/onboarding@1.0.1: + resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==} + dependencies: + bowser: 2.11.0 + dev: true + + /@metamask/post-message-stream@6.2.0: + resolution: {integrity: sha512-WunZ0bruClF862mvbKQGETn5SM0XKGmocPMQR1Ew6sYix9/FDzeoZnoI8RkXk01E+70FCdxhTE/r8kk5SFOuTw==} + engines: {node: '>=14.0.0'} + dependencies: + '@metamask/utils': 5.0.2 + readable-stream: 2.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@metamask/providers@10.2.1: + resolution: {integrity: sha512-p2TXw2a1Nb8czntDGfeIYQnk4LLVbd5vlcb3GY//lylYlKdSqp+uUTegCvxiFblRDOT68jsY8Ib1VEEzVUOolA==} + engines: {node: '>=14.0.0'} + dependencies: + '@metamask/object-multiplex': 1.3.0 + '@metamask/safe-event-emitter': 2.0.0 + '@types/chrome': 0.0.136 + detect-browser: 5.3.0 + eth-rpc-errors: 4.0.3 + extension-port-stream: 2.1.1 + fast-deep-equal: 2.0.1 + is-stream: 2.0.1 + json-rpc-engine: 6.1.0 + json-rpc-middleware-stream: 4.2.3 + pump: 3.0.0 + webextension-polyfill-ts: 0.25.0 + dev: true + + /@metamask/rpc-errors@6.1.0: + resolution: {integrity: sha512-JQElKxai26FpDyRKO/yH732wI+BV90i1u6pOuDOpdADSbppB2g1pPh3AGST1zkZqEE9eIKIUw8UdBQ4rp3VTSg==} + engines: {node: '>=16.0.0'} + dependencies: + '@metamask/utils': 8.2.1 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@metamask/safe-event-emitter@2.0.0: + resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} + dev: true + + /@metamask/safe-event-emitter@3.0.0: + resolution: {integrity: sha512-j6Z47VOmVyGMlnKXZmL0fyvWfEYtKWCA9yGZkU3FCsGZUT5lHGmvaV9JA5F2Y+010y7+ROtR3WMXIkvl/nVzqQ==} + engines: {node: '>=12.0.0'} + dev: true + + /@metamask/sdk-communication-layer@0.14.1: + resolution: {integrity: sha512-K1KhkKMdAAPi079G/bX/cIazqT6qnkRnykrs7nA1sU2BouG7BYD4qPgv7ridc3BNIewnFg9eMzzYIgOgfXzJKw==} + dependencies: + bufferutil: 4.0.8 + cross-fetch: 3.1.8 + date-fns: 2.30.0 + eciesjs: 0.3.18 + eventemitter2: 6.4.9 + socket.io-client: 4.7.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) + utf-8-validate: 6.0.3 + uuid: 8.3.2 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@metamask/sdk-install-modal-web@0.14.1(react-native@0.73.1): + resolution: {integrity: sha512-emT8HKbnfVwGhPxyUfMja6DWzvtJvDEBQxqCVx93H0HsyrrOzOC43iGCAosslw6o5h7gOfRKLqWmK8V7jQAS2Q==} + dependencies: + '@emotion/react': 11.11.3(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.3)(react@18.2.0) + i18next: 22.5.1 + qr-code-styling: 1.6.0-rc.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-i18next: 13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.73.1)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - react-native + dev: true + + /@metamask/sdk@0.14.1(react-dom@18.2.0)(react-native@0.73.1)(react@18.2.0): + resolution: {integrity: sha512-52kfvnlyMXRO8/oPGoQOFMevSjgkLzpl8aGG6Ivx/6jiqSv5ScuOg6YdSWXR937Ts0zWE0V8KTUBMfnGGt0S9Q==} + peerDependencies: + react: ^18.2.0 + react-native: '*' + peerDependenciesMeta: + react: + optional: true + react-native: + optional: true + dependencies: + '@metamask/onboarding': 1.0.1 + '@metamask/post-message-stream': 6.2.0 + '@metamask/providers': 10.2.1 + '@metamask/sdk-communication-layer': 0.14.1 + '@metamask/sdk-install-modal-web': 0.14.1(react-native@0.73.1) + '@react-native-async-storage/async-storage': 1.21.0(react-native@0.73.1) + '@types/dom-screen-wake-lock': 1.0.3 + bowser: 2.11.0 + cross-fetch: 4.0.0 + eciesjs: 0.3.18 + eth-rpc-errors: 4.0.3 + eventemitter2: 6.4.9 + extension-port-stream: 2.1.1 + i18next: 22.5.1 + i18next-browser-languagedetector: 7.2.0 + obj-multiplex: 1.0.0 + pump: 3.0.0 + qrcode-terminal-nooctal: 0.12.1 + react: 18.2.0 + react-i18next: 13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.73.1)(react@18.2.0) + react-native: 0.73.1(@babel/core@7.22.10)(@babel/preset-env@7.23.7)(react@18.2.0) + react-native-webview: 11.26.1(react-native@0.73.1)(react@18.2.0) + readable-stream: 2.3.8 + rollup-plugin-visualizer: 5.12.0 + socket.io-client: 4.7.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) + util: 0.12.5 + uuid: 8.3.2 transitivePeerDependencies: + - '@types/react' - bufferutil + - encoding + - react-dom + - rollup + - supports-color - utf-8-validate + dev: true - /@ethersproject/random@5.7.0: - resolution: {integrity: sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==} + /@metamask/utils@5.0.2: + resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} + engines: {node: '>=14.0.0'} dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 + '@ethereumjs/tx': 4.2.0 + '@types/debug': 4.1.12 + debug: 4.3.4(supports-color@8.1.1) + semver: 7.6.0 + superstruct: 1.0.3 + transitivePeerDependencies: + - supports-color + dev: true - /@ethersproject/rlp@5.7.0: - resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} + /@metamask/utils@8.2.1: + resolution: {integrity: sha512-dlnpow8r0YHDDL1xKCEwUoTGOAo9icdv+gaJG0EbgDnkD/BDqW2eH1XMtm9i7rPaiHWo/aLtcrh9WBhkCq/viw==} + engines: {node: '>=16.0.0'} dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 + '@ethereumjs/tx': 4.2.0 + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + '@types/debug': 4.1.12 + debug: 4.3.4(supports-color@8.1.1) + pony-cause: 2.1.10 + semver: 7.6.0 + superstruct: 1.0.3 + transitivePeerDependencies: + - supports-color + dev: true - /@ethersproject/sha2@5.7.0: - resolution: {integrity: sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==} + /@motionone/animation@10.15.1: + resolution: {integrity: sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==} dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - hash.js: 1.1.7 + '@motionone/easing': 10.15.1 + '@motionone/types': 10.15.1 + '@motionone/utils': 10.15.1 + tslib: 2.6.2 + dev: true + + /@motionone/dom@10.16.2: + resolution: {integrity: sha512-bnuHdNbge1FutZXv+k7xub9oPWcF0hsu8y1HTH/qg6av58YI0VufZ3ngfC7p2xhMJMnoh0LXFma2EGTgPeCkeg==} + dependencies: + '@motionone/animation': 10.15.1 + '@motionone/generators': 10.15.1 + '@motionone/types': 10.15.1 + '@motionone/utils': 10.15.1 + hey-listen: 1.0.8 + tslib: 2.6.2 + dev: true + + /@motionone/easing@10.15.1: + resolution: {integrity: sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==} + dependencies: + '@motionone/utils': 10.15.1 + tslib: 2.6.2 + dev: true + + /@motionone/generators@10.15.1: + resolution: {integrity: sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==} + dependencies: + '@motionone/types': 10.15.1 + '@motionone/utils': 10.15.1 + tslib: 2.6.2 + dev: true + + /@motionone/svelte@10.16.2: + resolution: {integrity: sha512-38xsroKrfK+aHYhuQlE6eFcGy0EwrB43Q7RGjF73j/kRUTcLNu/LAaKiLLsN5lyqVzCgTBVt4TMT/ShWbTbc5Q==} + dependencies: + '@motionone/dom': 10.16.2 + tslib: 2.6.2 + dev: true + + /@motionone/types@10.15.1: + resolution: {integrity: sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==} + dev: true + + /@motionone/utils@10.15.1: + resolution: {integrity: sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==} + dependencies: + '@motionone/types': 10.15.1 + hey-listen: 1.0.8 + tslib: 2.6.2 + dev: true + + /@motionone/vue@10.16.2: + resolution: {integrity: sha512-7/dEK/nWQXOkJ70bqb2KyNfSWbNvWqKKq1C8juj+0Mg/AorgD8O5wE3naddK0G+aXuNMqRuc4jlsYHHWHtIzVw==} + deprecated: Motion One for Vue is deprecated. Use Oku Motion instead https://oku-ui.com/motion + dependencies: + '@motionone/dom': 10.16.2 + tslib: 2.6.2 + dev: true + + /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: + resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} + dependencies: + eslint-scope: 5.1.1 + dev: true + + /@noble/curves@1.1.0: + resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} + dependencies: + '@noble/hashes': 1.3.1 + + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + + /@noble/hashes@1.2.0: + resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==} + dev: true + + /@noble/hashes@1.3.1: + resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==} + engines: {node: '>= 16'} + + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + + /@noble/secp256k1@1.7.1: + resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 - /@ethersproject/signing-key@5.7.0: - resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} + /@nomicfoundation/ethereumjs-block@5.0.4: + resolution: {integrity: sha512-AcyacJ9eX/uPEvqsPiB+WO1ymE+kyH48qGGiGV+YTojdtas8itUTW5dehDSOXEEItWGbbzEJ4PRqnQZlWaPvDw==} + engines: {node: '>=18'} dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - bn.js: 5.2.1 - elliptic: 6.5.4 - hash.js: 1.1.7 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-trie': 6.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + ethereum-cryptography: 0.1.3 + transitivePeerDependencies: + - c-kzg + dev: true - /@ethersproject/solidity@5.7.0: - resolution: {integrity: sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==} + /@nomicfoundation/ethereumjs-blockchain@7.0.4: + resolution: {integrity: sha512-jYsd/kwzbmpnxx86tXsYV8wZ5xGvFL+7/P0c6OlzpClHsbFzeF41KrYA9scON8Rg6bZu3ZTv6JOAgj3t7USUfg==} + engines: {node: '>=18'} dependencies: - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/sha2': 5.7.0 - '@ethersproject/strings': 5.7.0 + '@nomicfoundation/ethereumjs-block': 5.0.4 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-ethash': 3.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-trie': 6.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + debug: 4.3.4(supports-color@8.1.1) + ethereum-cryptography: 0.1.3 + lru-cache: 10.1.0 + transitivePeerDependencies: + - c-kzg + - supports-color + dev: true - /@ethersproject/strings@5.7.0: - resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} + /@nomicfoundation/ethereumjs-common@4.0.4: + resolution: {integrity: sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==} dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/constants': 5.7.0 - '@ethersproject/logger': 5.7.0 + '@nomicfoundation/ethereumjs-util': 9.0.4 + transitivePeerDependencies: + - c-kzg + dev: true - /@ethersproject/transactions@5.7.0: - resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} + /@nomicfoundation/ethereumjs-ethash@3.0.4: + resolution: {integrity: sha512-xvIrwIMl9sSaiYKRem68+O7vYdj7Q2XWv5P7JXiIkn83918QzWHvqbswTRsH7+r6X1UEvdsURRnZbvZszEjAaQ==} + engines: {node: '>=18'} dependencies: - '@ethersproject/address': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/constants': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/rlp': 5.7.0 - '@ethersproject/signing-key': 5.7.0 + '@nomicfoundation/ethereumjs-block': 5.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + bigint-crypto-utils: 3.3.0 + ethereum-cryptography: 0.1.3 + transitivePeerDependencies: + - c-kzg + dev: true - /@ethersproject/units@5.7.0: - resolution: {integrity: sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==} + /@nomicfoundation/ethereumjs-evm@2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2): + resolution: {integrity: sha512-lTyZZi1KpeMHzaO6cSVisR2tjiTTedjo7PcmhI/+GNFo9BmyY6QYzGeSti0sFttmjbEMioHgXxl5yrLNRg6+1w==} + engines: {node: '>=18'} dependencies: - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/constants': 5.7.0 - '@ethersproject/logger': 5.7.0 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-statemanager': 2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + '@types/debug': 4.1.12 + debug: 4.3.4(supports-color@8.1.1) + ethereum-cryptography: 0.1.3 + rustbn-wasm: 0.2.0 + transitivePeerDependencies: + - '@nomicfoundation/ethereumjs-verkle' + - c-kzg + - supports-color + dev: true - /@ethersproject/wallet@5.7.0: - resolution: {integrity: sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==} + /@nomicfoundation/ethereumjs-rlp@5.0.4: + resolution: {integrity: sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==} + engines: {node: '>=18'} + hasBin: true + dev: true + + /@nomicfoundation/ethereumjs-statemanager@2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2): + resolution: {integrity: sha512-HPDjeFrxw6llEi+BzqXkZ+KkvFnTOPczuHBtk21hRlDiuKuZz32dPzlhpRsDBGV1b5JTmRDUVqCS1lp3Gghw4Q==} + peerDependencies: + '@nomicfoundation/ethereumjs-verkle': 0.0.2 + peerDependenciesMeta: + '@nomicfoundation/ethereumjs-verkle': + optional: true dependencies: - '@ethersproject/abstract-provider': 5.7.0 - '@ethersproject/abstract-signer': 5.7.0 - '@ethersproject/address': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/hash': 5.7.0 - '@ethersproject/hdnode': 5.7.0 - '@ethersproject/json-wallets': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/random': 5.7.0 - '@ethersproject/signing-key': 5.7.0 - '@ethersproject/transactions': 5.7.0 - '@ethersproject/wordlists': 5.7.0 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-trie': 6.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + '@nomicfoundation/ethereumjs-verkle': 0.0.2 + debug: 4.3.4(supports-color@8.1.1) + ethereum-cryptography: 0.1.3 + js-sdsl: 4.4.2 + lru-cache: 10.1.0 + transitivePeerDependencies: + - c-kzg + - supports-color + dev: true - /@ethersproject/web@5.7.1: - resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} + /@nomicfoundation/ethereumjs-trie@6.0.4: + resolution: {integrity: sha512-3nSwQiFMvr2VFe/aZUyinuohYvtytUqZCUCvIWcPJ/BwJH6oQdZRB42aNFBJ/8nAh2s3OcroWpBLskzW01mFKA==} + engines: {node: '>=18'} dependencies: - '@ethersproject/base64': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/strings': 5.7.0 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + '@types/readable-stream': 2.3.15 + ethereum-cryptography: 0.1.3 + lru-cache: 10.1.0 + readable-stream: 3.6.2 + transitivePeerDependencies: + - c-kzg + dev: true - /@ethersproject/wordlists@5.7.0: - resolution: {integrity: sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==} + /@nomicfoundation/ethereumjs-tx@5.0.4: + resolution: {integrity: sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==} + engines: {node: '>=18'} + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/hash': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/properties': 5.7.0 - '@ethersproject/strings': 5.7.0 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + ethereum-cryptography: 0.1.3 + dev: true - /@ganache/ethereum-address@0.1.4: - resolution: {integrity: sha512-sTkU0M9z2nZUzDeHRzzGlW724xhMLXo2LeX1hixbnjHWY1Zg1hkqORywVfl+g5uOO8ht8T0v+34IxNxAhmWlbw==} + /@nomicfoundation/ethereumjs-util@9.0.4: + resolution: {integrity: sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==} + engines: {node: '>=18'} + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true dependencies: - '@ganache/utils': 0.1.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + ethereum-cryptography: 0.1.3 dev: true - /@ganache/ethereum-options@0.1.4: - resolution: {integrity: sha512-i4l46taoK2yC41FPkcoDlEVoqHS52wcbHPqJtYETRWqpOaoj9hAg/EJIHLb1t6Nhva2CdTO84bG+qlzlTxjAHw==} + /@nomicfoundation/ethereumjs-verkle@0.0.2: + resolution: {integrity: sha512-bjnfZElpYGK/XuuVRmLS3yDvr+cDs85D9oonZ0YUa5A3lgFgokWMp76zXrxX2jVQ0BfHaw12y860n1+iOi6yFQ==} + engines: {node: '>=18'} dependencies: - '@ganache/ethereum-address': 0.1.4 - '@ganache/ethereum-utils': 0.1.4 - '@ganache/options': 0.1.4 - '@ganache/utils': 0.1.4 - bip39: 3.0.4 - seedrandom: 3.0.5 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + lru-cache: 10.1.0 + rust-verkle-wasm: 0.0.1 transitivePeerDependencies: - - supports-color + - c-kzg dev: true - /@ganache/ethereum-utils@0.1.4: - resolution: {integrity: sha512-FKXF3zcdDrIoCqovJmHLKZLrJ43234Em2sde/3urUT/10gSgnwlpFmrv2LUMAmSbX3lgZhW/aSs8krGhDevDAg==} + /@nomicfoundation/ethereumjs-vm@7.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2): + resolution: {integrity: sha512-gsA4IhmtWHI4BofKy3kio9W+dqZQs5Ji5mLjLYxHCkat+JQBUt5szjRKra2F9nGDJ2XcI/wWb0YWUFNgln4zRQ==} + engines: {node: '>=18'} dependencies: - '@ethereumjs/common': 2.6.0 - '@ethereumjs/tx': 3.4.0 - '@ethereumjs/vm': 5.6.0 - '@ganache/ethereum-address': 0.1.4 - '@ganache/rlp': 0.1.4 - '@ganache/utils': 0.1.4 - emittery: 0.10.0 - ethereumjs-abi: 0.6.8 - ethereumjs-util: 7.1.3 + '@nomicfoundation/ethereumjs-block': 5.0.4 + '@nomicfoundation/ethereumjs-blockchain': 7.0.4 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-evm': 2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-statemanager': 2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/ethereumjs-trie': 6.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + debug: 4.3.4(supports-color@8.1.1) + ethereum-cryptography: 0.1.3 transitivePeerDependencies: + - '@nomicfoundation/ethereumjs-verkle' + - c-kzg - supports-color dev: true - /@ganache/options@0.1.4: - resolution: {integrity: sha512-zAe/craqNuPz512XQY33MOAG6Si1Xp0hCvfzkBfj2qkuPcbJCq6W/eQ5MB6SbXHrICsHrZOaelyqjuhSEmjXRw==} + /@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1: + resolution: {integrity: sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1: + resolution: {integrity: sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1: + resolution: {integrity: sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1: + resolution: {integrity: sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1: + resolution: {integrity: sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1: + resolution: {integrity: sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1: + resolution: {integrity: sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1: + resolution: {integrity: sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1: + resolution: {integrity: sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1: + resolution: {integrity: sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@nomicfoundation/solidity-analyzer@0.1.1: + resolution: {integrity: sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==} + engines: {node: '>= 12'} + optionalDependencies: + '@nomicfoundation/solidity-analyzer-darwin-arm64': 0.1.1 + '@nomicfoundation/solidity-analyzer-darwin-x64': 0.1.1 + '@nomicfoundation/solidity-analyzer-freebsd-x64': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-arm64-musl': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-x64-gnu': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-x64-musl': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-arm64-msvc': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-ia32-msvc': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.1 + dev: true + + /@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.20.1): + resolution: {integrity: sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==} + peerDependencies: + ethers: ^5.0.0 + hardhat: ^2.0.0 dependencies: - '@ganache/utils': 0.1.4 - bip39: 3.0.4 - seedrandom: 3.0.5 + ethers: 5.7.2 + hardhat: 2.20.1(ts-node@10.9.2)(typescript@5.3.3) dev: true - /@ganache/rlp@0.1.4: - resolution: {integrity: sha512-Do3D1H6JmhikB+6rHviGqkrNywou/liVeFiKIpOBLynIpvZhRCgn3SEDxyy/JovcaozTo/BynHumfs5R085MFQ==} + /@nomiclabs/hardhat-waffle@2.0.1(@nomiclabs/hardhat-ethers@2.2.3)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.20.1): + resolution: {integrity: sha512-2YR2V5zTiztSH9n8BYWgtv3Q+EL0N5Ltm1PAr5z20uAY4SkkfylJ98CIqt18XFvxTD5x4K2wKBzddjV9ViDAZQ==} + peerDependencies: + '@nomiclabs/hardhat-ethers': ^2.0.0 + ethereum-waffle: ^3.2.0 + ethers: ^5.0.0 + hardhat: ^2.0.0 dependencies: - '@ganache/utils': 0.1.4 - rlp: 2.2.6 + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.20.1) + '@types/sinon-chai': 3.2.5 + '@types/web3': 1.0.19 + ethereum-waffle: 4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typescript@5.3.3) + ethers: 5.7.2 + hardhat: 2.20.1(ts-node@10.9.2)(typescript@5.3.3) dev: true - /@ganache/utils@0.1.4: - resolution: {integrity: sha512-oatUueU3XuXbUbUlkyxeLLH3LzFZ4y5aSkNbx6tjSIhVTPeh+AuBKYt4eQ73FFcTB3nj/gZoslgAh5CN7O369w==} + /@nomiclabs/hardhat-waffle@2.0.6(@nomiclabs/hardhat-ethers@2.2.3)(@types/sinon-chai@3.2.5)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.20.1): + resolution: {integrity: sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg==} + peerDependencies: + '@nomiclabs/hardhat-ethers': ^2.0.0 + '@types/sinon-chai': ^3.2.3 + ethereum-waffle: '*' + ethers: ^5.0.0 + hardhat: ^2.0.0 dependencies: - emittery: 0.10.0 - keccak: 3.0.1 - seedrandom: 3.0.5 - optionalDependencies: - '@trufflesuite/bigint-buffer': 1.1.9 + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.20.1) + '@types/sinon-chai': 3.2.5 + ethereum-waffle: 4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typescript@5.3.3) + ethers: 5.7.2 + hardhat: 2.20.1(ts-node@10.9.2)(typescript@5.3.3) dev: true - /@humanwhocodes/config-array@0.11.13: - resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} - engines: {node: '>=10.10.0'} + /@nrwl/nx-cloud@18.0.0: + resolution: {integrity: sha512-rjjcJgzDmKwFD1QVIMs5O3X4SoMQIk0bzh3pL90ZP/B5YJUlTySv7+R0JoGQ6ROGwVQHjPFMVKKLB09zl5perA==} dependencies: - '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4(supports-color@8.1.1) - minimatch: 3.1.2 + nx-cloud: 18.0.0 transitivePeerDependencies: - - supports-color - dev: true - - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - dev: true - - /@humanwhocodes/object-schema@2.0.1: - resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + - debug dev: true - /@isaacs/cliui@8.0.2: - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + /@nrwl/tao@18.1.2: + resolution: {integrity: sha512-IA+osZ5TlKMwJmcP7TECW7TO0JdNNQud9Dgkh1ZfJ4GWnT7WEkE9b2Yf1IFeeB81kCTXXq8jfISa8ZY21MjRaQ==} + hasBin: true dependencies: - string-width: 5.1.2 - string-width-cjs: /string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: /strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: /wrap-ansi@7.0.0 + nx: 18.1.2 + tslib: 2.6.2 + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - debug dev: true - /@istanbuljs/load-nyc-config@1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 + /@nx/nx-darwin-arm64@18.1.2: + resolution: {integrity: sha512-KduC9WBmeTLP8HyTg4NOgQGLk9LEd5qd9dGuYKPU0jA4b+eJIa0rRHEjFdc5WulQrcUAvTIKfmScRCgzR96ogg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true dev: true + optional: true - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} + /@nx/nx-darwin-x64@18.1.2: + resolution: {integrity: sha512-mBf3X8m4P4QHoW8g/L/YoK8zkndDyIw4bojLg8Q3xc47s5JZFCqSSMeOXZ9NicM2DpPiDWSQALtQX7A8lIsoAA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true dev: true + optional: true - /@jest/schemas@29.6.3: - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@sinclair/typebox': 0.27.8 + /@nx/nx-freebsd-x64@18.1.2: + resolution: {integrity: sha512-ZqzT2BTsOHhWip1PvNm7AZ4Pzn4I+IZNRvtRgpETYvIH+nqoCmi5rrEi1avnhnr6P5hyzh2mISRSyk186SbZew==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + requiresBuild: true dev: true + optional: true - /@jridgewell/gen-mapping@0.3.3: - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.19 + /@nx/nx-linux-arm-gnueabihf@18.1.2: + resolution: {integrity: sha512-V9Dp9uuuce+/f50dXxaYz1C9ULo5+5VS35yc6gN7b6SchCWjNK+xg1YcHBTRNc2ChBtayO2z+mBQ1s6wMDNs/Q==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true dev: true + optional: true - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} - engines: {node: '>=6.0.0'} + /@nx/nx-linux-arm64-gnu@18.1.2: + resolution: {integrity: sha512-aM860T4Hy2JCLcU56mtARIp1MdT1Ms7cGUQzE+a5irM8ZdaHsPdRnYqIgEKd3hoF6PQ6/piHFXWa4xm7pe/2KA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true dev: true + optional: true - /@jridgewell/set-array@1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} + /@nx/nx-linux-arm64-musl@18.1.2: + resolution: {integrity: sha512-BgBoOeIgCQ56xii7fKNWiE7UIP/0G+OQhdWJQmh+q6NN0kk78WsdCSq+f7f7LQIji5HiNqUUVx9fd1s6xRSb/w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true dev: true + optional: true - /@jridgewell/sourcemap-codec@1.4.15: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + /@nx/nx-linux-x64-gnu@18.1.2: + resolution: {integrity: sha512-WDOjtk+K2Tc9SNjGe+zmyy05VUerZpEQ5kvB6Ude0v/W2bMnmpVrLZwwTF5Yrq0ebbUlXM/9wtc1Zjjc75MU2g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true dev: true + optional: true - /@jridgewell/trace-mapping@0.3.19: - resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + /@nx/nx-linux-x64-musl@18.1.2: + resolution: {integrity: sha512-I7jTmbfR5CHC3KVlU3SkqYKJnn25MbH8pdRZJY4gaHnqL9JzbHw9rxddhKBj41lez7jQZTGLnPFUV7JPLXTzKg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true dev: true + optional: true - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + /@nx/nx-win32-arm64-msvc@18.1.2: + resolution: {integrity: sha512-KQobKvkrdkmaJmx0Pyt2lzHkNugO0gE7q9F4h22KIECyGW1tC3nSPAB4F3mmdE2KuWKgYG5WLafvzusysLsR7g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true dev: true + optional: true - /@json-rpc-tools/provider@1.7.6: - resolution: {integrity: sha512-z7D3xvJ33UfCGv77n40lbzOYjZKVM3k2+5cV7xS8G6SCvKTzMkhkUYuD/qzQUNT4cG/lv0e9mRToweEEVLVVmA==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - dependencies: - '@json-rpc-tools/utils': 1.7.6 - axios: 0.21.4(debug@4.3.4) - safe-json-utils: 1.1.1 - ws: 7.5.9 - transitivePeerDependencies: - - bufferutil - - debug - - utf-8-validate - - /@json-rpc-tools/types@1.7.6: - resolution: {integrity: sha512-nDSqmyRNEqEK9TZHtM15uNnDljczhCUdBmRhpNZ95bIPKEDQ+nTDmGMFd2lLin3upc5h2VVVd9tkTDdbXUhDIQ==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - dependencies: - keyvaluestorage-interface: 1.0.0 - - /@json-rpc-tools/utils@1.7.6: - resolution: {integrity: sha512-HjA8x/U/Q78HRRe19yh8HVKoZ+Iaoo3YZjakJYxR+rw52NHo6jM+VE9b8+7ygkCFXl/EHID5wh/MkXaE/jGyYw==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - dependencies: - '@json-rpc-tools/types': 1.7.6 - '@pedrouid/environment': 1.0.1 - - /@ledgerhq/connect-kit-loader@1.1.0: - resolution: {integrity: sha512-HUy12FEczoWY2FPubnsm1uOA8tkVWc0j90i47suThV3C9NL2xx69ZAIEU3Ytzs2bwLek9S1Q2S1VQJvA+3Ygkg==} - - /@lit-labs/ssr-dom-shim@1.1.1: - resolution: {integrity: sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ==} - - /@lit/reactive-element@1.6.2: - resolution: {integrity: sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==} - dependencies: - '@lit-labs/ssr-dom-shim': 1.1.1 - - /@manypkg/find-root@1.1.0: - resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} - dependencies: - '@babel/runtime': 7.22.6 - '@types/node': 12.20.55 - find-up: 4.1.0 - fs-extra: 8.1.0 - dev: false - - /@manypkg/get-packages@1.1.3: - resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - dependencies: - '@babel/runtime': 7.22.6 - '@changesets/types': 4.1.0 - '@manypkg/find-root': 1.1.0 - fs-extra: 8.1.0 - globby: 11.1.0 - read-yaml-file: 1.1.0 - dev: false - - /@metamask/eth-sig-util@4.0.0: - resolution: {integrity: sha512-LczOjjxY4A7XYloxzyxJIHONELmUxVZncpOLoClpEcTiebiVdM46KRPYXGuULro9oNNR2xdVx3yoKiQjdfWmoA==} - engines: {node: '>=12.0.0'} - dependencies: - ethereumjs-abi: 0.6.8 - ethereumjs-util: 6.2.1 - ethjs-util: 0.1.6 - tweetnacl: 1.0.3 - tweetnacl-util: 0.15.1 + /@nx/nx-win32-x64-msvc@18.1.2: + resolution: {integrity: sha512-uvJvROSwHBwkTOoOPkb56jEsKJjr4LnZ3fCHmEbrtGhAUC0gAUL+dWJUDHoatrGzN+bM2VqrvgNCGkityK96hw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true dev: true + optional: true - /@metamask/safe-event-emitter@2.0.0: - resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} - - /@metamask/utils@3.6.0: - resolution: {integrity: sha512-9cIRrfkWvHblSiNDVXsjivqa9Ak0RYo/1H6tqTqTbAx+oBK2Sva0lWDHxGchOqA7bySGUJKAWSNJvH6gdHZ0gQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@types/debug': 4.1.8 - debug: 4.3.4(supports-color@8.1.1) - semver: 7.5.4 - superstruct: 1.0.3 - transitivePeerDependencies: - - supports-color - - /@motionone/animation@10.15.1: - resolution: {integrity: sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==} - dependencies: - '@motionone/easing': 10.15.1 - '@motionone/types': 10.15.1 - '@motionone/utils': 10.15.1 - tslib: 2.6.2 - - /@motionone/dom@10.16.2: - resolution: {integrity: sha512-bnuHdNbge1FutZXv+k7xub9oPWcF0hsu8y1HTH/qg6av58YI0VufZ3ngfC7p2xhMJMnoh0LXFma2EGTgPeCkeg==} - dependencies: - '@motionone/animation': 10.15.1 - '@motionone/generators': 10.15.1 - '@motionone/types': 10.15.1 - '@motionone/utils': 10.15.1 - hey-listen: 1.0.8 - tslib: 2.6.2 - - /@motionone/easing@10.15.1: - resolution: {integrity: sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==} - dependencies: - '@motionone/utils': 10.15.1 - tslib: 2.6.2 - - /@motionone/generators@10.15.1: - resolution: {integrity: sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==} - dependencies: - '@motionone/types': 10.15.1 - '@motionone/utils': 10.15.1 - tslib: 2.6.2 - - /@motionone/svelte@10.16.2: - resolution: {integrity: sha512-38xsroKrfK+aHYhuQlE6eFcGy0EwrB43Q7RGjF73j/kRUTcLNu/LAaKiLLsN5lyqVzCgTBVt4TMT/ShWbTbc5Q==} - dependencies: - '@motionone/dom': 10.16.2 - tslib: 2.6.2 + /@parcel/watcher-android-arm64@2.3.0: + resolution: {integrity: sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true - /@motionone/types@10.15.1: - resolution: {integrity: sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==} + /@parcel/watcher-darwin-arm64@2.3.0: + resolution: {integrity: sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true - /@motionone/utils@10.15.1: - resolution: {integrity: sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==} - dependencies: - '@motionone/types': 10.15.1 - hey-listen: 1.0.8 - tslib: 2.6.2 + /@parcel/watcher-darwin-x64@2.3.0: + resolution: {integrity: sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true - /@motionone/vue@10.16.2: - resolution: {integrity: sha512-7/dEK/nWQXOkJ70bqb2KyNfSWbNvWqKKq1C8juj+0Mg/AorgD8O5wE3naddK0G+aXuNMqRuc4jlsYHHWHtIzVw==} - dependencies: - '@motionone/dom': 10.16.2 - tslib: 2.6.2 + /@parcel/watcher-freebsd-x64@2.3.0: + resolution: {integrity: sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true - /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: - resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} - dependencies: - eslint-scope: 5.1.1 + /@parcel/watcher-linux-arm-glibc@2.3.0: + resolution: {integrity: sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true dev: true + optional: true - /@noble/curves@1.1.0: - resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} - dependencies: - '@noble/hashes': 1.3.1 + /@parcel/watcher-linux-arm64-glibc@2.3.0: + resolution: {integrity: sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true - /@noble/curves@1.2.0: - resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} - dependencies: - '@noble/hashes': 1.3.2 + /@parcel/watcher-linux-arm64-musl@2.3.0: + resolution: {integrity: sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true - /@noble/hashes@1.2.0: - resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==} + /@parcel/watcher-linux-x64-glibc@2.3.0: + resolution: {integrity: sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true dev: true + optional: true - /@noble/hashes@1.3.1: - resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==} - engines: {node: '>= 16'} + /@parcel/watcher-linux-x64-musl@2.3.0: + resolution: {integrity: sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true - /@noble/hashes@1.3.2: - resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} - engines: {node: '>= 16'} + /@parcel/watcher-wasm@2.3.0: + resolution: {integrity: sha512-ejBAX8H0ZGsD8lSICDNyMbSEtPMWgDL0WFCt/0z7hyf5v8Imz4rAM8xY379mBsECkq/Wdqa5WEDLqtjZ+6NxfA==} + engines: {node: '>= 10.0.0'} + dependencies: + is-glob: 4.0.3 + micromatch: 4.0.5 + napi-wasm: 1.1.0 + dev: true + bundledDependencies: + - napi-wasm - /@noble/secp256k1@1.7.1: - resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} + /@parcel/watcher-win32-arm64@2.3.0: + resolution: {integrity: sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + requiresBuild: true dev: true + optional: true - /@nodelib/fs.scandir@2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 + /@parcel/watcher-win32-ia32@2.3.0: + resolution: {integrity: sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true - /@nodelib/fs.stat@2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + /@parcel/watcher-win32-x64@2.3.0: + resolution: {integrity: sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true - /@nodelib/fs.walk@1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + /@parcel/watcher@2.3.0: + resolution: {integrity: sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ==} + engines: {node: '>= 10.0.0'} dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.5 + node-addon-api: 7.0.0 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.3.0 + '@parcel/watcher-darwin-arm64': 2.3.0 + '@parcel/watcher-darwin-x64': 2.3.0 + '@parcel/watcher-freebsd-x64': 2.3.0 + '@parcel/watcher-linux-arm-glibc': 2.3.0 + '@parcel/watcher-linux-arm64-glibc': 2.3.0 + '@parcel/watcher-linux-arm64-musl': 2.3.0 + '@parcel/watcher-linux-x64-glibc': 2.3.0 + '@parcel/watcher-linux-x64-musl': 2.3.0 + '@parcel/watcher-win32-arm64': 2.3.0 + '@parcel/watcher-win32-ia32': 2.3.0 + '@parcel/watcher-win32-x64': 2.3.0 + dev: true - /@nomicfoundation/ethereumjs-block@5.0.2: - resolution: {integrity: sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q==} + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - dependencies: - '@nomicfoundation/ethereumjs-common': 4.0.2 - '@nomicfoundation/ethereumjs-rlp': 5.0.2 - '@nomicfoundation/ethereumjs-trie': 6.0.2 - '@nomicfoundation/ethereumjs-tx': 5.0.2 - '@nomicfoundation/ethereumjs-util': 9.0.2 - ethereum-cryptography: 0.1.3 - ethers: 5.7.2 - transitivePeerDependencies: - - bufferutil - - utf-8-validate + requiresBuild: true dev: true + optional: true - /@nomicfoundation/ethereumjs-blockchain@7.0.2: - resolution: {integrity: sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w==} - engines: {node: '>=14'} + /@react-native-async-storage/async-storage@1.21.0(react-native@0.73.1): + resolution: {integrity: sha512-JL0w36KuFHFCvnbOXRekqVAUplmOyT/OuCQkogo6X98MtpSaJOKEAeZnYO8JB0U/RIEixZaGI5px73YbRm/oag==} + peerDependencies: + react-native: ^0.0.0-0 || >=0.60 <1.0 dependencies: - '@nomicfoundation/ethereumjs-block': 5.0.2 - '@nomicfoundation/ethereumjs-common': 4.0.2 - '@nomicfoundation/ethereumjs-ethash': 3.0.2 - '@nomicfoundation/ethereumjs-rlp': 5.0.2 - '@nomicfoundation/ethereumjs-trie': 6.0.2 - '@nomicfoundation/ethereumjs-tx': 5.0.2 - '@nomicfoundation/ethereumjs-util': 9.0.2 - abstract-level: 1.0.3 - debug: 4.3.4(supports-color@8.1.1) - ethereum-cryptography: 0.1.3 - level: 8.0.0 - lru-cache: 5.1.1 - memory-level: 1.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate + merge-options: 3.0.4 + react-native: 0.73.1(@babel/core@7.22.10)(@babel/preset-env@7.23.7)(react@18.2.0) dev: true - /@nomicfoundation/ethereumjs-common@4.0.2: - resolution: {integrity: sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg==} + /@react-native-community/cli-clean@12.3.0: + resolution: {integrity: sha512-iAgLCOWYRGh9ukr+eVQnhkV/OqN3V2EGd/in33Ggn/Mj4uO6+oUncXFwB+yjlyaUNz6FfjudhIz09yYGSF+9sg==} dependencies: - '@nomicfoundation/ethereumjs-util': 9.0.2 - crc-32: 1.2.2 + '@react-native-community/cli-tools': 12.3.0 + chalk: 4.1.2 + execa: 5.1.1 + transitivePeerDependencies: + - encoding dev: true - /@nomicfoundation/ethereumjs-ethash@3.0.2: - resolution: {integrity: sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg==} - engines: {node: '>=14'} + /@react-native-community/cli-config@12.3.0: + resolution: {integrity: sha512-BrTn5ndFD9uOxO8kxBQ32EpbtOvAsQExGPI7SokdI4Zlve70FziLtTq91LTlTUgMq1InVZn/jJb3VIDk6BTInQ==} dependencies: - '@nomicfoundation/ethereumjs-block': 5.0.2 - '@nomicfoundation/ethereumjs-rlp': 5.0.2 - '@nomicfoundation/ethereumjs-util': 9.0.2 - abstract-level: 1.0.3 - bigint-crypto-utils: 3.3.0 - ethereum-cryptography: 0.1.3 + '@react-native-community/cli-tools': 12.3.0 + chalk: 4.1.2 + cosmiconfig: 5.2.1 + deepmerge: 4.3.1 + glob: 7.2.3 + joi: 17.11.0 transitivePeerDependencies: - - bufferutil - - utf-8-validate + - encoding dev: true - /@nomicfoundation/ethereumjs-evm@2.0.2: - resolution: {integrity: sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ==} - engines: {node: '>=14'} + /@react-native-community/cli-debugger-ui@12.3.0: + resolution: {integrity: sha512-w3b0iwjQlk47GhZWHaeTG8kKH09NCMUJO729xSdMBXE8rlbm4kHpKbxQY9qKb6NlfWSJN4noGY+FkNZS2rRwnQ==} dependencies: - '@ethersproject/providers': 5.7.2 - '@nomicfoundation/ethereumjs-common': 4.0.2 - '@nomicfoundation/ethereumjs-tx': 5.0.2 - '@nomicfoundation/ethereumjs-util': 9.0.2 - debug: 4.3.4(supports-color@8.1.1) - ethereum-cryptography: 0.1.3 - mcl-wasm: 0.7.8 - rustbn.js: 0.2.0 + serve-static: 1.15.0 transitivePeerDependencies: - - bufferutil - supports-color - - utf-8-validate dev: true - /@nomicfoundation/ethereumjs-rlp@5.0.2: - resolution: {integrity: sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA==} - engines: {node: '>=14'} - hasBin: true + /@react-native-community/cli-doctor@12.3.0: + resolution: {integrity: sha512-BPCwNNesoQMkKsxB08Ayy6URgGQ8Kndv6mMhIvJSNdST3J1+x3ehBHXzG9B9Vfi+DrTKRb8lmEl/b/7VkDlPkA==} + dependencies: + '@react-native-community/cli-config': 12.3.0 + '@react-native-community/cli-platform-android': 12.3.0 + '@react-native-community/cli-platform-ios': 12.3.0 + '@react-native-community/cli-tools': 12.3.0 + chalk: 4.1.2 + command-exists: 1.2.9 + deepmerge: 4.3.1 + envinfo: 7.11.0 + execa: 5.1.1 + hermes-profile-transformer: 0.0.6 + ip: 1.1.9 + node-stream-zip: 1.15.0 + ora: 5.4.1 + semver: 7.6.0 + strip-ansi: 5.2.0 + wcwidth: 1.0.1 + yaml: 2.3.4 + transitivePeerDependencies: + - encoding dev: true - /@nomicfoundation/ethereumjs-statemanager@2.0.2: - resolution: {integrity: sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA==} + /@react-native-community/cli-hermes@12.3.0: + resolution: {integrity: sha512-G6FxpeZBO4AimKZwtWR3dpXRqTvsmEqlIkkxgwthdzn3LbVjDVIXKpVYU9PkR5cnT+KuAUxO0WwthrJ6Nmrrlg==} dependencies: - '@nomicfoundation/ethereumjs-common': 4.0.2 - '@nomicfoundation/ethereumjs-rlp': 5.0.2 - debug: 4.3.4(supports-color@8.1.1) - ethereum-cryptography: 0.1.3 - ethers: 5.7.2 - js-sdsl: 4.4.2 + '@react-native-community/cli-platform-android': 12.3.0 + '@react-native-community/cli-tools': 12.3.0 + chalk: 4.1.2 + hermes-profile-transformer: 0.0.6 + ip: 1.1.9 transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate + - encoding dev: true - /@nomicfoundation/ethereumjs-trie@6.0.2: - resolution: {integrity: sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ==} - engines: {node: '>=14'} + /@react-native-community/cli-platform-android@12.3.0: + resolution: {integrity: sha512-VU1NZw63+GLU2TnyQ919bEMThpHQ/oMFju9MCfrd3pyPJz4Sn+vc3NfnTDUVA5Z5yfLijFOkHIHr4vo/C9bjnw==} dependencies: - '@nomicfoundation/ethereumjs-rlp': 5.0.2 - '@nomicfoundation/ethereumjs-util': 9.0.2 - '@types/readable-stream': 2.3.15 - ethereum-cryptography: 0.1.3 - readable-stream: 3.6.2 + '@react-native-community/cli-tools': 12.3.0 + chalk: 4.1.2 + execa: 5.1.1 + fast-xml-parser: 4.3.2 + glob: 7.2.3 + logkitty: 0.7.1 + transitivePeerDependencies: + - encoding dev: true - /@nomicfoundation/ethereumjs-tx@5.0.2: - resolution: {integrity: sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g==} - engines: {node: '>=14'} + /@react-native-community/cli-platform-ios@12.3.0: + resolution: {integrity: sha512-H95Sgt3wT7L8V75V0syFJDtv4YgqK5zbu69ko4yrXGv8dv2EBi6qZP0VMmkqXDamoPm9/U7tDTdbcf26ctnLfg==} dependencies: - '@chainsafe/ssz': 0.9.4 - '@ethersproject/providers': 5.7.2 - '@nomicfoundation/ethereumjs-common': 4.0.2 - '@nomicfoundation/ethereumjs-rlp': 5.0.2 - '@nomicfoundation/ethereumjs-util': 9.0.2 - ethereum-cryptography: 0.1.3 + '@react-native-community/cli-tools': 12.3.0 + chalk: 4.1.2 + execa: 5.1.1 + fast-xml-parser: 4.3.2 + glob: 7.2.3 + ora: 5.4.1 transitivePeerDependencies: - - bufferutil - - utf-8-validate + - encoding dev: true - /@nomicfoundation/ethereumjs-util@9.0.2: - resolution: {integrity: sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ==} - engines: {node: '>=14'} - dependencies: - '@chainsafe/ssz': 0.10.2 - '@nomicfoundation/ethereumjs-rlp': 5.0.2 - ethereum-cryptography: 0.1.3 + /@react-native-community/cli-plugin-metro@12.3.0: + resolution: {integrity: sha512-tYNHIYnNmxrBcsqbE2dAnLMzlKI3Cp1p1xUgTrNaOMsGPDN1epzNfa34n6Nps3iwKElSL7Js91CzYNqgTalucA==} dev: true - /@nomicfoundation/ethereumjs-vm@7.0.2: - resolution: {integrity: sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA==} - engines: {node: '>=14'} + /@react-native-community/cli-server-api@12.3.0: + resolution: {integrity: sha512-Rode8NrdyByC+lBKHHn+/W8Zu0c+DajJvLmOWbe2WY/ECvnwcd9MHHbu92hlT2EQaJ9LbLhGrSbQE3cQy9EOCw==} dependencies: - '@nomicfoundation/ethereumjs-block': 5.0.2 - '@nomicfoundation/ethereumjs-blockchain': 7.0.2 - '@nomicfoundation/ethereumjs-common': 4.0.2 - '@nomicfoundation/ethereumjs-evm': 2.0.2 - '@nomicfoundation/ethereumjs-rlp': 5.0.2 - '@nomicfoundation/ethereumjs-statemanager': 2.0.2 - '@nomicfoundation/ethereumjs-trie': 6.0.2 - '@nomicfoundation/ethereumjs-tx': 5.0.2 - '@nomicfoundation/ethereumjs-util': 9.0.2 - debug: 4.3.4(supports-color@8.1.1) - ethereum-cryptography: 0.1.3 - mcl-wasm: 0.7.8 - rustbn.js: 0.2.0 + '@react-native-community/cli-debugger-ui': 12.3.0 + '@react-native-community/cli-tools': 12.3.0 + compression: 1.7.4 + connect: 3.7.0 + errorhandler: 1.5.1 + nocache: 3.0.4 + pretty-format: 26.6.2 + serve-static: 1.15.0 + ws: 7.5.9 transitivePeerDependencies: - bufferutil + - encoding - supports-color - utf-8-validate dev: true - /@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1: - resolution: {integrity: sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true + /@react-native-community/cli-tools@12.3.0: + resolution: {integrity: sha512-2GafnCr8D88VdClwnm9KZfkEb+lzVoFdr/7ybqhdeYM0Vnt/tr2N+fM1EQzwI1DpzXiBzTYemw8GjRq+Utcz2Q==} + dependencies: + appdirsjs: 1.2.7 + chalk: 4.1.2 + find-up: 5.0.0 + mime: 2.6.0 + node-fetch: 2.6.12 + open: 6.4.0 + ora: 5.4.1 + semver: 7.6.0 + shell-quote: 1.8.1 + sudo-prompt: 9.2.1 + transitivePeerDependencies: + - encoding dev: true - optional: true - /@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1: - resolution: {integrity: sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - requiresBuild: true + /@react-native-community/cli-types@12.3.0: + resolution: {integrity: sha512-MgOkmrXH4zsGxhte4YqKL7d+N8ZNEd3w1wo56MZlhu5WabwCJh87wYpU5T8vyfujFLYOFuFK5jjlcbs8F4/WDw==} + dependencies: + joi: 17.11.0 + dev: true + + /@react-native-community/cli@12.3.0: + resolution: {integrity: sha512-XeQohi2E+S2+MMSz97QcEZ/bWpi8sfKiQg35XuYeJkc32Til2g0b97jRpn0/+fV0BInHoG1CQYWwHA7opMsrHg==} + engines: {node: '>=18'} + hasBin: true + dependencies: + '@react-native-community/cli-clean': 12.3.0 + '@react-native-community/cli-config': 12.3.0 + '@react-native-community/cli-debugger-ui': 12.3.0 + '@react-native-community/cli-doctor': 12.3.0 + '@react-native-community/cli-hermes': 12.3.0 + '@react-native-community/cli-plugin-metro': 12.3.0 + '@react-native-community/cli-server-api': 12.3.0 + '@react-native-community/cli-tools': 12.3.0 + '@react-native-community/cli-types': 12.3.0 + chalk: 4.1.2 + commander: 9.5.0 + deepmerge: 4.3.1 + execa: 5.1.1 + find-up: 4.1.0 + fs-extra: 8.1.0 + graceful-fs: 4.2.11 + prompts: 2.4.2 + semver: 7.6.0 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate dev: true - optional: true - /@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1: - resolution: {integrity: sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [freebsd] - requiresBuild: true + /@react-native/assets-registry@0.73.1: + resolution: {integrity: sha512-2FgAbU7uKM5SbbW9QptPPZx8N9Ke2L7bsHb+EhAanZjFZunA9PaYtyjUQ1s7HD+zDVqOQIvjkpXSv7Kejd2tqg==} + engines: {node: '>=18'} dev: true - optional: true - /@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1: - resolution: {integrity: sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true + /@react-native/babel-plugin-codegen@0.71.3(@babel/preset-env@7.23.7): + resolution: {integrity: sha512-udPH9oWVTO0q7OJL672k7pmBzMA7Ei83hQwk/dxUlveTwjHz1ChHwMXhDJBhG/dNFijl9wcHrD1aXrI8WchZQg==} + dependencies: + react-native-codegen: 0.71.6(@babel/preset-env@7.23.7) + transitivePeerDependencies: + - '@babel/preset-env' + - supports-color dev: true - optional: true - /@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1: - resolution: {integrity: sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true + /@react-native/babel-preset@0.74.0(@babel/core@7.22.10)(@babel/preset-env@7.23.7): + resolution: {integrity: sha512-k+1aaYQeLn+GBmGA5Qs3NKI8uzhLvRRMML+pB/+43ZL6DvCklbuJ5KO5oqRRpF3KZ2t/VKUqqSichpXfFrXGjg==} + engines: {node: '>=18'} + peerDependencies: + '@babel/core': '*' + dependencies: + '@babel/core': 7.22.10 + '@babel/plugin-proposal-async-generator-functions': 7.20.7(@babel/core@7.22.10) + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.22.10) + '@babel/plugin-proposal-export-default-from': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.22.10) + '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.22.10) + '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.22.10) + '@babel/plugin-proposal-optional-catch-binding': 7.18.6(@babel/core@7.22.10) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.22.10) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-syntax-export-default-from': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-classes': 7.23.5(@babel/core@7.22.10) + '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-flow-strip-types': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.10) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-react-display-name': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-runtime': 7.23.7(@babel/core@7.22.10) + '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.22.10) + '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.22.10) + '@babel/template': 7.22.15 + '@react-native/babel-plugin-codegen': 0.71.3(@babel/preset-env@7.23.7) + babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.22.10) + react-refresh: 0.14.0 + transitivePeerDependencies: + - '@babel/preset-env' + - supports-color dev: true - optional: true - /@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1: - resolution: {integrity: sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true + /@react-native/codegen@0.73.2(@babel/preset-env@7.23.7): + resolution: {integrity: sha512-lfy8S7umhE3QLQG5ViC4wg5N1Z+E6RnaeIw8w1voroQsXXGPB72IBozh8dAHR3+ceTxIU0KX3A8OpJI8e1+HpQ==} + engines: {node: '>=18'} + peerDependencies: + '@babel/preset-env': ^7.1.6 + dependencies: + '@babel/parser': 7.23.6 + '@babel/preset-env': 7.23.7(@babel/core@7.22.10) + flow-parser: 0.206.0 + glob: 7.2.3 + invariant: 2.2.4 + jscodeshift: 0.14.0(@babel/preset-env@7.23.7) + mkdirp: 0.5.6 + nullthrows: 1.1.1 + transitivePeerDependencies: + - supports-color dev: true - optional: true - /@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1: - resolution: {integrity: sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true + /@react-native/community-cli-plugin@0.73.11(@babel/core@7.22.10)(@babel/preset-env@7.23.7): + resolution: {integrity: sha512-s0bprwljKS1Al8wOKathDDmRyF+70CcNE2G/aqZ7+L0NoOE0Uxxx/5P2BxlM2Mfht7O33B4SeMNiPdE/FqIubQ==} + engines: {node: '>=18'} + dependencies: + '@react-native-community/cli-server-api': 12.3.0 + '@react-native-community/cli-tools': 12.3.0 + '@react-native/dev-middleware': 0.73.6 + '@react-native/metro-babel-transformer': 0.73.12(@babel/core@7.22.10)(@babel/preset-env@7.23.7) + chalk: 4.1.2 + execa: 5.1.1 + metro: 0.80.3 + metro-config: 0.80.3 + metro-core: 0.80.3 + node-fetch: 2.6.12 + readline: 1.3.0 + transitivePeerDependencies: + - '@babel/core' + - '@babel/preset-env' + - bufferutil + - encoding + - supports-color + - utf-8-validate dev: true - optional: true - /@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1: - resolution: {integrity: sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - requiresBuild: true + /@react-native/debugger-frontend@0.73.3: + resolution: {integrity: sha512-RgEKnWuoo54dh7gQhV7kvzKhXZEhpF9LlMdZolyhGxHsBqZ2gXdibfDlfcARFFifPIiaZ3lXuOVVa4ei+uPgTw==} + engines: {node: '>=18'} dev: true - optional: true - /@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1: - resolution: {integrity: sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - requiresBuild: true + /@react-native/dev-middleware@0.73.6: + resolution: {integrity: sha512-9SD7gIso+hO1Jy1Y/Glbd+JWQwyH7Xjnwebtkxdm5TMB51LQPjaGtMcwEigbIZyAtvoaDGmhWmudwbKpDlS+gA==} + engines: {node: '>=18'} + dependencies: + '@isaacs/ttlcache': 1.4.1 + '@react-native/debugger-frontend': 0.73.3 + chrome-launcher: 0.15.2 + chromium-edge-launcher: 1.0.0 + connect: 3.7.0 + debug: 2.6.9 + node-fetch: 2.6.12 + open: 7.4.2 + serve-static: 1.15.0 + temp-dir: 2.0.0 + transitivePeerDependencies: + - encoding + - supports-color dev: true - optional: true - /@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1: - resolution: {integrity: sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - requiresBuild: true + /@react-native/gradle-plugin@0.73.4: + resolution: {integrity: sha512-PMDnbsZa+tD55Ug+W8CfqXiGoGneSSyrBZCMb5JfiB3AFST3Uj5e6lw8SgI/B6SKZF7lG0BhZ6YHZsRZ5MlXmg==} + engines: {node: '>=18'} dev: true - optional: true - /@nomicfoundation/solidity-analyzer@0.1.1: - resolution: {integrity: sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==} - engines: {node: '>= 12'} - optionalDependencies: - '@nomicfoundation/solidity-analyzer-darwin-arm64': 0.1.1 - '@nomicfoundation/solidity-analyzer-darwin-x64': 0.1.1 - '@nomicfoundation/solidity-analyzer-freebsd-x64': 0.1.1 - '@nomicfoundation/solidity-analyzer-linux-arm64-gnu': 0.1.1 - '@nomicfoundation/solidity-analyzer-linux-arm64-musl': 0.1.1 - '@nomicfoundation/solidity-analyzer-linux-x64-gnu': 0.1.1 - '@nomicfoundation/solidity-analyzer-linux-x64-musl': 0.1.1 - '@nomicfoundation/solidity-analyzer-win32-arm64-msvc': 0.1.1 - '@nomicfoundation/solidity-analyzer-win32-ia32-msvc': 0.1.1 - '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.1 + /@react-native/js-polyfills@0.73.1: + resolution: {integrity: sha512-ewMwGcumrilnF87H4jjrnvGZEaPFCAC4ebraEK+CurDDmwST/bIicI4hrOAv+0Z0F7DEK4O4H7r8q9vH7IbN4g==} + engines: {node: '>=18'} dev: true - /@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.18.3): - resolution: {integrity: sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==} + /@react-native/metro-babel-transformer@0.73.12(@babel/core@7.22.10)(@babel/preset-env@7.23.7): + resolution: {integrity: sha512-VmxN5aaoOprzDzUR+8c3XYhG0FoMOO6n0ToylCW6EeZCuf5RTY7HWVOhacabGoB1mHrWzJ0wWEsqX+eD4iFxoA==} + engines: {node: '>=18'} peerDependencies: - ethers: ^5.0.0 - hardhat: ^2.0.0 + '@babel/core': '*' dependencies: - ethers: 5.7.2 - hardhat: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) + '@babel/core': 7.22.10 + '@react-native/babel-preset': 0.74.0(@babel/core@7.22.10)(@babel/preset-env@7.23.7) + babel-preset-fbjs: 3.4.0(@babel/core@7.22.10) + hermes-parser: 0.15.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@babel/preset-env' + - supports-color dev: true - /@nomiclabs/hardhat-waffle@2.0.1(@nomiclabs/hardhat-ethers@2.2.3)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.18.3): - resolution: {integrity: sha512-2YR2V5zTiztSH9n8BYWgtv3Q+EL0N5Ltm1PAr5z20uAY4SkkfylJ98CIqt18XFvxTD5x4K2wKBzddjV9ViDAZQ==} + /@react-native/normalize-colors@0.73.2: + resolution: {integrity: sha512-bRBcb2T+I88aG74LMVHaKms2p/T8aQd8+BZ7LuuzXlRfog1bMWWn/C5i0HVuvW4RPtXQYgIlGiXVDy9Ir1So/w==} + dev: true + + /@react-native/virtualized-lists@0.73.4(react-native@0.73.1): + resolution: {integrity: sha512-HpmLg1FrEiDtrtAbXiwCgXFYyloK/dOIPIuWW3fsqukwJEWAiTzm1nXGJ7xPU5XTHiWZ4sKup5Ebaj8z7iyWog==} + engines: {node: '>=18'} peerDependencies: - '@nomiclabs/hardhat-ethers': ^2.0.0 - ethereum-waffle: ^3.2.0 - ethers: ^5.0.0 - hardhat: ^2.0.0 + react-native: '*' dependencies: - '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.18.3) - '@types/sinon-chai': 3.2.5 - '@types/web3': 1.0.19 - ethereum-waffle: 4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typescript@5.2.2) - ethers: 5.7.2 - hardhat: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) + invariant: 2.2.4 + nullthrows: 1.1.1 + react-native: 0.73.1(@babel/core@7.22.10)(@babel/preset-env@7.23.7)(react@18.2.0) dev: true - /@nomiclabs/hardhat-waffle@2.0.6(@nomiclabs/hardhat-ethers@2.2.3)(@types/sinon-chai@3.2.5)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.18.3): - resolution: {integrity: sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg==} - peerDependencies: - '@nomiclabs/hardhat-ethers': ^2.0.0 - '@types/sinon-chai': ^3.2.3 - ethereum-waffle: '*' - ethers: ^5.0.0 - hardhat: ^2.0.0 + /@resolver-engine/core@0.3.3: + resolution: {integrity: sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==} dependencies: - '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.18.3) - '@types/sinon-chai': 3.2.5 - ethereum-waffle: 4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typescript@5.2.2) - ethers: 5.7.2 - hardhat: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) + debug: 3.2.7 + is-url: 1.2.4 + request: 2.88.2 + transitivePeerDependencies: + - supports-color dev: true - /@nrwl/nx-cloud@16.5.2: - resolution: {integrity: sha512-oHO5T1HRJsR9mbRd8eUqMBPCgqVZLSbAh3zJoPFmhEmjbM4YB9ePRpgYFT8dRNeZUOUd/8Yt7Pb6EVWOHvpD/w==} + /@resolver-engine/fs@0.3.3: + resolution: {integrity: sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==} dependencies: - nx-cloud: 16.5.2 + '@resolver-engine/core': 0.3.3 + debug: 3.2.7 transitivePeerDependencies: - - debug + - supports-color dev: true - /@nrwl/tao@17.0.2: - resolution: {integrity: sha512-H+htIRzQR6Ibael34rhQkpNkpFFFmaSTsIzdqkBqL4j5+FzSpZh67NJnWSY8vsYQGQL8Ncc+MHvpQC+7pyfgGw==} - hasBin: true + /@resolver-engine/imports-fs@0.3.3: + resolution: {integrity: sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==} dependencies: - nx: 17.0.2 - tslib: 2.6.2 + '@resolver-engine/fs': 0.3.3 + '@resolver-engine/imports': 0.3.3 + debug: 3.2.7 transitivePeerDependencies: - - '@swc-node/register' - - '@swc/core' - - debug + - supports-color dev: true - /@nx/nx-darwin-arm64@17.0.2: - resolution: {integrity: sha512-OSZLRfV8VplYPEqMcIg3mbAsJXlXEHKrdlJ0KUTk8Hih2+wl7cxuSEwG7X7qfBUOz+ognxaqicL+hueNrgwjlQ==} - engines: {node: '>= 10'} + /@resolver-engine/imports@0.3.3: + resolution: {integrity: sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==} + dependencies: + '@resolver-engine/core': 0.3.3 + debug: 3.2.7 + hosted-git-info: 2.8.9 + path-browserify: 1.0.1 + url: 0.11.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@rollup/rollup-android-arm-eabi@4.5.1: + resolution: {integrity: sha512-YaN43wTyEBaMqLDYeze+gQ4ZrW5RbTEGtT5o1GVDkhpdNcsLTnLRcLccvwy3E9wiDKWg9RIhuoy3JQKDRBfaZA==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-android-arm64@4.5.1: + resolution: {integrity: sha512-n1bX+LCGlQVuPlCofO0zOKe1b2XkFozAVRoczT+yxWZPGnkEAKTTYVOGZz8N4sKuBnKMxDbfhUsB1uwYdup/sw==} cpu: [arm64] - os: [darwin] + os: [android] requiresBuild: true dev: true optional: true - /@nx/nx-darwin-x64@17.0.2: - resolution: {integrity: sha512-olGt5R2dWYwdl1+I2RfJ8LdZO1elqhr9yDPnMIx//ZuN6T6wJA+Wdp2P3qpM1bY0F1lI/6AgjqzRyrTLUZ9cDA==} - engines: {node: '>= 10'} - cpu: [x64] + /@rollup/rollup-darwin-arm64@4.5.1: + resolution: {integrity: sha512-QqJBumdvfBqBBmyGHlKxje+iowZwrHna7pokj/Go3dV1PJekSKfmjKrjKQ/e6ESTGhkfPNLq3VXdYLAc+UtAQw==} + cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /@nx/nx-freebsd-x64@17.0.2: - resolution: {integrity: sha512-+mta0J2G2byd+rfZ275oZs0aYXC/s92nI9ySBFQFQZnKJ6bsAagdZHe+uETsnE4xdhFXD8kvNMJU1WTGlyFyjg==} - engines: {node: '>= 10'} + /@rollup/rollup-darwin-x64@4.5.1: + resolution: {integrity: sha512-RrkDNkR/P5AEQSPkxQPmd2ri8WTjSl0RYmuFOiEABkEY/FSg0a4riihWQGKDJ4LnV9gigWZlTMx2DtFGzUrYQw==} cpu: [x64] - os: [freebsd] + os: [darwin] requiresBuild: true dev: true optional: true - /@nx/nx-linux-arm-gnueabihf@17.0.2: - resolution: {integrity: sha512-m80CmxHHyNAJ8j/0rkjc0hg/eGQlf6V2sLsV+gEJkz2sTEEdgSOK4DvnWcZRWO/SWBnqigxoHX4Kf5TH1nmoHA==} - engines: {node: '>= 10'} + /@rollup/rollup-linux-arm-gnueabihf@4.5.1: + resolution: {integrity: sha512-ZFPxvUZmE+fkB/8D9y/SWl/XaDzNSaxd1TJUSE27XAKlRpQ2VNce/86bGd9mEUgL3qrvjJ9XTGwoX0BrJkYK/A==} cpu: [arm] os: [linux] requiresBuild: true dev: true optional: true - /@nx/nx-linux-arm64-gnu@17.0.2: - resolution: {integrity: sha512-AsD1H6wt68MK1u6vkmtNaFaxDMcyuk6dpo5kq1YT9cfUd614ys3qMUjVp3P2CXxzXh+0UDZeGrc6qotNKOkpJw==} - engines: {node: '>= 10'} + /@rollup/rollup-linux-arm64-gnu@4.5.1: + resolution: {integrity: sha512-FEuAjzVIld5WVhu+M2OewLmjmbXWd3q7Zcx+Rwy4QObQCqfblriDMMS7p7+pwgjZoo9BLkP3wa9uglQXzsB9ww==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@nx/nx-linux-arm64-musl@17.0.2: - resolution: {integrity: sha512-f8pUFoZHBFQtHnopHgTEuwIiu0Rzem0dD7iK8SyyBy/lRAADtHCAHxaPAG+iatHAJ9h4DFIB50k9ybYxDtH2mg==} - engines: {node: '>= 10'} + /@rollup/rollup-linux-arm64-musl@4.5.1: + resolution: {integrity: sha512-f5Gs8WQixqGRtI0Iq/cMqvFYmgFzMinuJO24KRfnv7Ohi/HQclwrBCYkzQu1XfLEEt3DZyvveq9HWo4bLJf1Lw==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@nx/nx-linux-x64-gnu@17.0.2: - resolution: {integrity: sha512-PISrHjLTxv5w8bz50vPZH6puYos88xu28o4IbVyYWrUrhoFsAx9Zbn1D6gWDPMSaKJU32v1l+5bTciQjQJU8fQ==} - engines: {node: '>= 10'} + /@rollup/rollup-linux-x64-gnu@4.5.1: + resolution: {integrity: sha512-CWPkPGrFfN2vj3mw+S7A/4ZaU3rTV7AkXUr08W9lNP+UzOvKLVf34tWCqrKrfwQ0NTk5GFqUr2XGpeR2p6R4gw==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@nx/nx-linux-x64-musl@17.0.2: - resolution: {integrity: sha512-2wsqyBRjsxmAjxW+0lnGFtJLTk+AxgW7gjMv8NgLK8P1bc/sJYQB+g0o5op2z+szXRG3Noi0RZ9C0fG39EPFZw==} - engines: {node: '>= 10'} + /@rollup/rollup-linux-x64-musl@4.5.1: + resolution: {integrity: sha512-ZRETMFA0uVukUC9u31Ed1nx++29073goCxZtmZARwk5aF/ltuENaeTtRVsSQzFlzdd4J6L3qUm+EW8cbGt0CKQ==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@nx/nx-win32-arm64-msvc@17.0.2: - resolution: {integrity: sha512-Sc3sQUcS5xdk05PABe/knG6orG5rmHZdSUj6SMRpvYfN2tM3ziNn6/wCF/LJoW6n70OxrOEXXwLSRK/5WigXbA==} - engines: {node: '>= 10'} + /@rollup/rollup-win32-arm64-msvc@4.5.1: + resolution: {integrity: sha512-ihqfNJNb2XtoZMSCPeoo0cYMgU04ksyFIoOw5S0JUVbOhafLot+KD82vpKXOurE2+9o/awrqIxku9MRR9hozHQ==} cpu: [arm64] os: [win32] requiresBuild: true dev: true - optional: true - - /@nx/nx-win32-x64-msvc@17.0.2: - resolution: {integrity: sha512-XhET0BDk6fbvTBCs7m5gZii8+2WhLpiC1sZchJw4LAJN2VJBiy3I3xnvpQYGFOAWaCb/iUGpuN/qP/NlQ+LNgA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@pedrouid/environment@1.0.1: - resolution: {integrity: sha512-HaW78NszGzRZd9SeoI3JD11JqY+lubnaOx7Pewj5pfjqWXOEATpeKIFb9Z4t2WBUK2iryiXX3lzWwmYWgUL0Ug==} - - /@pkgjs/parseargs@0.11.0: - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - requiresBuild: true - dev: true - optional: true - - /@resolver-engine/core@0.3.3: - resolution: {integrity: sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==} - dependencies: - debug: 3.2.7 - is-url: 1.2.4 - request: 2.88.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@resolver-engine/fs@0.3.3: - resolution: {integrity: sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==} - dependencies: - '@resolver-engine/core': 0.3.3 - debug: 3.2.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@resolver-engine/imports-fs@0.3.3: - resolution: {integrity: sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==} - dependencies: - '@resolver-engine/fs': 0.3.3 - '@resolver-engine/imports': 0.3.3 - debug: 3.2.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@resolver-engine/imports@0.3.3: - resolution: {integrity: sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==} - dependencies: - '@resolver-engine/core': 0.3.3 - debug: 3.2.7 - hosted-git-info: 2.8.9 - path-browserify: 1.0.1 - url: 0.11.1 - transitivePeerDependencies: - - supports-color - dev: true + optional: true - /@safe-global/safe-apps-provider@0.15.2: - resolution: {integrity: sha512-BaoGAuY7h6jLBL7P+M6b7hd+1QfTv8uMyNF3udhiNUwA0XwfzH2ePQB13IEV3Mn7wdcIMEEUDS5kHbtAsj60qQ==} - dependencies: - '@safe-global/safe-apps-sdk': 7.9.0 - events: 3.3.0 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate + /@rollup/rollup-win32-ia32-msvc@4.5.1: + resolution: {integrity: sha512-zK9MRpC8946lQ9ypFn4gLpdwr5a01aQ/odiIJeL9EbgZDMgbZjjT/XzTqJvDfTmnE1kHdbG20sAeNlpc91/wbg==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.5.1: + resolution: {integrity: sha512-5I3Nz4Sb9TYOtkRwlH0ow+BhMH2vnh38tZ4J4mggE48M/YyJyp/0sPSxhw1UeS1+oBgQ8q7maFtSeKpeRJu41Q==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true - /@safe-global/safe-apps-provider@0.17.1(typescript@5.2.2): - resolution: {integrity: sha512-lYfRqrbbK1aKU1/UGkYWc/X7PgySYcumXKc5FB2uuwAs2Ghj8uETuW5BrwPqyjBknRxutFbTv+gth/JzjxAhdQ==} + /@safe-global/safe-apps-provider@0.18.1(typescript@5.3.3): + resolution: {integrity: sha512-V4a05A3EgJcriqtDoJklDz1BOinWhC6P0hjUSxshA4KOZM7rGPCTto/usXs09zr1vvL28evl/NldSTv97j2bmg==} dependencies: - '@safe-global/safe-apps-sdk': 8.0.0(typescript@5.2.2) + '@safe-global/safe-apps-sdk': 8.1.0(typescript@5.3.3) events: 3.3.0 transitivePeerDependencies: - bufferutil @@ -3195,31 +5043,11 @@ packages: - zod dev: true - /@safe-global/safe-apps-sdk@7.11.0: - resolution: {integrity: sha512-RDamzPM1Lhhiiz0O+Dn6FkFqIh47jmZX+HCV/BBnBBOSKfBJE//IGD3+02zMgojXHTikQAburdPes9qmH1SA1A==} - dependencies: - '@safe-global/safe-gateway-typescript-sdk': 3.7.3 - ethers: 5.7.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - - /@safe-global/safe-apps-sdk@7.9.0: - resolution: {integrity: sha512-S2EI+JL8ocSgE3uGNaDZCzKmwfhtxXZFDUP76vN0FeaY35itFMyi8F0Vhxu0XnZm3yLzJE3tp5px6GhuQFLU6w==} - dependencies: - '@safe-global/safe-gateway-typescript-sdk': 3.7.3 - ethers: 5.7.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - - /@safe-global/safe-apps-sdk@8.0.0(typescript@5.2.2): - resolution: {integrity: sha512-gYw0ki/EAuV1oSyMxpqandHjnthZjYYy+YWpTAzf8BqfXM3ItcZLpjxfg+3+mXW8HIO+3jw6T9iiqEXsqHaMMw==} + /@safe-global/safe-apps-sdk@8.1.0(typescript@5.3.3): + resolution: {integrity: sha512-XJbEPuaVc7b9n23MqlF6c+ToYIS3f7P2Sel8f3cSBQ9WORE4xrSuvhMpK9fDSFqJ7by/brc+rmJR/5HViRr0/w==} dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.7.3 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) + viem: 1.20.3(typescript@5.3.3) transitivePeerDependencies: - bufferutil - encoding @@ -3234,6 +5062,7 @@ packages: cross-fetch: 3.1.8 transitivePeerDependencies: - encoding + dev: true /@scure/base@1.1.3: resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} @@ -3273,13 +5102,13 @@ packages: '@noble/hashes': 1.3.2 '@scure/base': 1.1.3 - /@sentry-internal/tracing@7.75.0: - resolution: {integrity: sha512-/j4opF/jB9j8qnSiQK75/lFLtkfqXS5/MoOKc2KWK/pOaf15W+6uJzGQ8jRBHLYd9dDg6AyqsF48Wqy561/mNg==} + /@sentry-internal/tracing@7.99.0: + resolution: {integrity: sha512-z3JQhHjoM1KdM20qrHwRClKJrNLr2CcKtCluq7xevLtXHJWNAQQbafnWD+Aoj85EWXBzKt9yJMv2ltcXJ+at+w==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.75.0 - '@sentry/types': 7.75.0 - '@sentry/utils': 7.75.0 + '@sentry/core': 7.99.0 + '@sentry/types': 7.99.0 + '@sentry/utils': 7.99.0 dev: false /@sentry/core@5.30.0: @@ -3293,12 +5122,12 @@ packages: tslib: 1.14.1 dev: true - /@sentry/core@7.75.0: - resolution: {integrity: sha512-vXg3cdJgwzP24oTS9zFCgLW4MgTkMZqXx+ESRq7gTD9qJTpcmAmYT+Ckmvebg8K6DBThV6+0v61r50na2+XdrA==} + /@sentry/core@7.99.0: + resolution: {integrity: sha512-vOAtzcAXEUtS/oW7wi3wMkZ3hsb5Ch96gKyrrj/mXdOp2zrcwdNV6N9/pawq2E9P/7Pw8AXw4CeDZztZrjQLuA==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.75.0 - '@sentry/utils': 7.75.0 + '@sentry/types': 7.99.0 + '@sentry/utils': 7.99.0 dev: false /@sentry/hub@5.30.0: @@ -3336,17 +5165,14 @@ packages: - supports-color dev: true - /@sentry/node@7.75.0: - resolution: {integrity: sha512-z5Xanf9QeTd4YrEuZiJfvtAy2C874Zg4KpurEo3okJ8uYjnbXMsQ3EwVHbKEoYSwE3ExTrqOggPfk2NNSJIECA==} + /@sentry/node@7.99.0: + resolution: {integrity: sha512-34wYtLddnPcQ8qvKq62AfxowaMFw+GMUZGv7fIs9FxeBqqqn6Ckl0gFCTADudIIBQ3rSbmN7sHJIXdyiQv+pcw==} engines: {node: '>=8'} dependencies: - '@sentry-internal/tracing': 7.75.0 - '@sentry/core': 7.75.0 - '@sentry/types': 7.75.0 - '@sentry/utils': 7.75.0 - https-proxy-agent: 5.0.1 - transitivePeerDependencies: - - supports-color + '@sentry-internal/tracing': 7.99.0 + '@sentry/core': 7.99.0 + '@sentry/types': 7.99.0 + '@sentry/utils': 7.99.0 dev: false /@sentry/tracing@5.30.0: @@ -3365,8 +5191,8 @@ packages: engines: {node: '>=6'} dev: true - /@sentry/types@7.75.0: - resolution: {integrity: sha512-xG8OLADxG7HpGhMxrF4v4tKq/v/gqmLsTZ858R51pz0xCWM8SK6ZSWOKudkAGBIpRjI6RUHMnkBtRAN2aKDOkQ==} + /@sentry/types@7.99.0: + resolution: {integrity: sha512-94qwOw4w40sAs5mCmzcGyj8ZUu/KhnWnuMZARRq96k+SjRW/tHFAOlIdnFSrt3BLPvSOK7R3bVAskZQ0N4FTmA==} engines: {node: '>=8'} dev: false @@ -3378,13 +5204,27 @@ packages: tslib: 1.14.1 dev: true - /@sentry/utils@7.75.0: - resolution: {integrity: sha512-UHWKeevhUNRp+mAWDbMVFOMgseoq8t/xFgdUywO/2PC14qZKRBH+0k1BKoNkp5sOzDT06ETj2w6wYoYhy6i+dA==} + /@sentry/utils@7.99.0: + resolution: {integrity: sha512-cYZy5WNTkWs5GgggGnjfGqC44CWir0pAv4GVVSx0fsup4D4pMKBJPrtub15f9uC+QkUf3vVkqwpBqeFxtmJQTQ==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.75.0 + '@sentry/types': 7.99.0 dev: false + /@sideway/address@4.1.4: + resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==} + dependencies: + '@hapi/hoek': 9.3.0 + dev: true + + /@sideway/formula@3.0.1: + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + dev: true + + /@sideway/pinpoint@2.0.0: + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + dev: true + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true @@ -3395,58 +5235,41 @@ packages: type-detect: 4.0.8 dev: true - /@sinonjs/fake-timers@7.1.2: - resolution: {integrity: sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==} + /@sinonjs/commons@3.0.0: + resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} dependencies: - '@sinonjs/commons': 1.8.3 + type-detect: 4.0.8 dev: true - /@solana/buffer-layout@4.0.1: - resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} - engines: {node: '>=5.10'} + /@sinonjs/fake-timers@10.3.0: + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} dependencies: - buffer: 6.0.3 + '@sinonjs/commons': 3.0.0 + dev: true - /@solana/web3.js@1.78.0: - resolution: {integrity: sha512-CSjCjo+RELJ5puoZALfznN5EF0YvL1V8NQrQYovsdjE1lCV6SqbKAIZD0+9LlqCBoa1ibuUaR7G2SooYzvzmug==} + /@sinonjs/fake-timers@7.1.2: + resolution: {integrity: sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==} dependencies: - '@babel/runtime': 7.22.6 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 - '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.3.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.1 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.1.0 - node-fetch: 2.6.12 - rpc-websockets: 7.5.1 - superstruct: 0.14.2 - transitivePeerDependencies: - - bufferutil - - encoding - - supports-color - - utf-8-validate + '@sinonjs/commons': 1.8.3 + dev: true - /@solidity-parser/parser@0.13.2: - resolution: {integrity: sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw==} - dependencies: - antlr4ts: 0.5.0-alpha.4 + /@socket.io/component-emitter@3.1.0: + resolution: {integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==} dev: true /@stablelib/aead@1.0.1: resolution: {integrity: sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg==} + dev: true /@stablelib/binary@1.0.1: resolution: {integrity: sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==} dependencies: '@stablelib/int': 1.0.1 + dev: true /@stablelib/bytes@1.0.1: resolution: {integrity: sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==} + dev: true /@stablelib/chacha20poly1305@1.0.1: resolution: {integrity: sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA==} @@ -3457,15 +5280,18 @@ packages: '@stablelib/constant-time': 1.0.1 '@stablelib/poly1305': 1.0.1 '@stablelib/wipe': 1.0.1 + dev: true /@stablelib/chacha@1.0.1: resolution: {integrity: sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg==} dependencies: '@stablelib/binary': 1.0.1 '@stablelib/wipe': 1.0.1 + dev: true /@stablelib/constant-time@1.0.1: resolution: {integrity: sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==} + dev: true /@stablelib/ed25519@1.0.3: resolution: {integrity: sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==} @@ -3473,9 +5299,11 @@ packages: '@stablelib/random': 1.0.2 '@stablelib/sha512': 1.0.1 '@stablelib/wipe': 1.0.1 + dev: true /@stablelib/hash@1.0.1: resolution: {integrity: sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==} + dev: true /@stablelib/hkdf@1.0.1: resolution: {integrity: sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g==} @@ -3483,6 +5311,7 @@ packages: '@stablelib/hash': 1.0.1 '@stablelib/hmac': 1.0.1 '@stablelib/wipe': 1.0.1 + dev: true /@stablelib/hmac@1.0.1: resolution: {integrity: sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA==} @@ -3490,26 +5319,31 @@ packages: '@stablelib/constant-time': 1.0.1 '@stablelib/hash': 1.0.1 '@stablelib/wipe': 1.0.1 + dev: true /@stablelib/int@1.0.1: resolution: {integrity: sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==} + dev: true /@stablelib/keyagreement@1.0.1: resolution: {integrity: sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==} dependencies: '@stablelib/bytes': 1.0.1 + dev: true /@stablelib/poly1305@1.0.1: resolution: {integrity: sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==} dependencies: '@stablelib/constant-time': 1.0.1 '@stablelib/wipe': 1.0.1 + dev: true /@stablelib/random@1.0.2: resolution: {integrity: sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==} dependencies: '@stablelib/binary': 1.0.1 '@stablelib/wipe': 1.0.1 + dev: true /@stablelib/sha256@1.0.1: resolution: {integrity: sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ==} @@ -3517,6 +5351,7 @@ packages: '@stablelib/binary': 1.0.1 '@stablelib/hash': 1.0.1 '@stablelib/wipe': 1.0.1 + dev: true /@stablelib/sha512@1.0.1: resolution: {integrity: sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==} @@ -3524,9 +5359,11 @@ packages: '@stablelib/binary': 1.0.1 '@stablelib/hash': 1.0.1 '@stablelib/wipe': 1.0.1 + dev: true /@stablelib/wipe@1.0.1: resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==} + dev: true /@stablelib/x25519@1.0.3: resolution: {integrity: sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==} @@ -3534,9 +5371,10 @@ packages: '@stablelib/keyagreement': 1.0.1 '@stablelib/random': 1.0.2 '@stablelib/wipe': 1.0.1 + dev: true - /@swc/core-darwin-arm64@1.3.95: - resolution: {integrity: sha512-VAuBAP3MNetO/yBIBzvorUXq7lUBwhfpJxYViSxyluMwtoQDhE/XWN598TWMwMl1ZuImb56d7eUsuFdjgY7pJw==} + /@swc/core-darwin-arm64@1.4.6: + resolution: {integrity: sha512-bpggpx/BfLFyy48aUKq1PsNUxb7J6CINlpAUk0V4yXfmGnpZH80Gp1pM3GkFDQyCfq7L7IpjPrIjWQwCrL4hYw==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] @@ -3544,8 +5382,8 @@ packages: dev: true optional: true - /@swc/core-darwin-x64@1.3.95: - resolution: {integrity: sha512-20vF2rvUsN98zGLZc+dsEdHvLoCuiYq/1B+TDeE4oolgTFDmI1jKO+m44PzWjYtKGU9QR95sZ6r/uec0QC5O4Q==} + /@swc/core-darwin-x64@1.4.6: + resolution: {integrity: sha512-vJn+/ZuBTg+vtNkcmgZdH6FQpa0hFVdnB9bAeqYwKkyqP15zaPe6jfC+qL2y/cIeC7ASvHXEKrnCZgBLxfVQ9w==} engines: {node: '>=10'} cpu: [x64] os: [darwin] @@ -3553,8 +5391,8 @@ packages: dev: true optional: true - /@swc/core-linux-arm-gnueabihf@1.3.95: - resolution: {integrity: sha512-oEudEM8PST1MRNGs+zu0cx5i9uP8TsLE4/L9HHrS07Ck0RJ3DCj3O2fU832nmLe2QxnAGPwBpSO9FntLfOiWEQ==} + /@swc/core-linux-arm-gnueabihf@1.4.6: + resolution: {integrity: sha512-hEmYcB/9XBAl02MtuVHszhNjQpjBzhk/NFulnU33tBMbNZpy2TN5yTsitezMq090QXdDz8sKIALApDyg07ZR8g==} engines: {node: '>=10'} cpu: [arm] os: [linux] @@ -3562,8 +5400,8 @@ packages: dev: true optional: true - /@swc/core-linux-arm64-gnu@1.3.95: - resolution: {integrity: sha512-pIhFI+cuC1aYg+0NAPxwT/VRb32f2ia8oGxUjQR6aJg65gLkUYQzdwuUmpMtFR2WVf7WVFYxUnjo4UyMuyh3ng==} + /@swc/core-linux-arm64-gnu@1.4.6: + resolution: {integrity: sha512-/UCYIVoGpm2YVvGHZM2QOA3dexa28BjcpLAIYnoCbgH5f7ulDhE8FAIO/9pasj+kixDBsdqewHfsNXFYlgGJjQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] @@ -3571,8 +5409,8 @@ packages: dev: true optional: true - /@swc/core-linux-arm64-musl@1.3.95: - resolution: {integrity: sha512-ZpbTr+QZDT4OPJfjPAmScqdKKaT+wGurvMU5AhxLaf85DuL8HwUwwlL0n1oLieLc47DwIJEMuKQkYhXMqmJHlg==} + /@swc/core-linux-arm64-musl@1.4.6: + resolution: {integrity: sha512-LGQsKJ8MA9zZ8xHCkbGkcPSmpkZL2O7drvwsGKynyCttHhpwVjj9lguhD4DWU3+FWIsjvho5Vu0Ggei8OYi/Lw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] @@ -3580,8 +5418,8 @@ packages: dev: true optional: true - /@swc/core-linux-x64-gnu@1.3.95: - resolution: {integrity: sha512-n9SuHEFtdfSJ+sHdNXNRuIOVprB8nbsz+08apKfdo4lEKq6IIPBBAk5kVhPhkjmg2dFVHVo4Tr/OHXM1tzWCCw==} + /@swc/core-linux-x64-gnu@1.4.6: + resolution: {integrity: sha512-10JL2nLIreMQDKvq2TECnQe5fCuoqBHu1yW8aChqgHUyg9d7gfZX/kppUsuimqcgRBnS0AjTDAA+JF6UsG/2Yg==} engines: {node: '>=10'} cpu: [x64] os: [linux] @@ -3589,8 +5427,8 @@ packages: dev: true optional: true - /@swc/core-linux-x64-musl@1.3.95: - resolution: {integrity: sha512-L1JrVlsXU3LC0WwmVnMK9HrOT2uhHahAoPNMJnZQpc18a0paO9fqifPG8M/HjNRffMUXR199G/phJsf326UvVg==} + /@swc/core-linux-x64-musl@1.4.6: + resolution: {integrity: sha512-EGyjFVzVY6Do89x8sfah7I3cuP4MwtwzmA6OlfD/KASqfCFf5eIaEBMbajgR41bVfMV7lK72lwAIea5xEyq1AQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] @@ -3598,8 +5436,8 @@ packages: dev: true optional: true - /@swc/core-win32-arm64-msvc@1.3.95: - resolution: {integrity: sha512-YaP4x/aZbUyNdqCBpC2zL8b8n58MEpOUpmOIZK6G1SxGi+2ENht7gs7+iXpWPc0sy7X3YPKmSWMAuui0h8lgAA==} + /@swc/core-win32-arm64-msvc@1.4.6: + resolution: {integrity: sha512-gfW9AuXvwSyK07Vb8Y8E9m2oJZk21WqcD+X4BZhkbKB0TCZK0zk1j/HpS2UFlr1JB2zPKPpSWLU3ll0GEHRG2A==} engines: {node: '>=10'} cpu: [arm64] os: [win32] @@ -3607,8 +5445,8 @@ packages: dev: true optional: true - /@swc/core-win32-ia32-msvc@1.3.95: - resolution: {integrity: sha512-w0u3HI916zT4BC/57gOd+AwAEjXeUlQbGJ9H4p/gzs1zkSHtoDQghVUNy3n/ZKp9KFod/95cA8mbVF9t1+6epQ==} + /@swc/core-win32-ia32-msvc@1.4.6: + resolution: {integrity: sha512-ZuQm81FhhvNVYtVb9GfZ+Du6e7fZlkisWvuCeBeRiyseNt1tcrQ8J3V67jD2nxje8CVXrwG3oUIbPcybv2rxfQ==} engines: {node: '>=10'} cpu: [ia32] os: [win32] @@ -3616,8 +5454,8 @@ packages: dev: true optional: true - /@swc/core-win32-x64-msvc@1.3.95: - resolution: {integrity: sha512-5RGnMt0S6gg4Gc6QtPUJ3Qs9Un4sKqccEzgH/tj7V/DVTJwKdnBKxFZfgQ34OR2Zpz7zGOn889xwsFVXspVWNA==} + /@swc/core-win32-x64-msvc@1.4.6: + resolution: {integrity: sha512-UagPb7w5V0uzWSjrXwOavGa7s9iv3wrVdEgWy+/inm0OwY4lj3zpK9qDnMWAwYLuFwkI3UG4Q3dH8wD+CUUcjw==} engines: {node: '>=10'} cpu: [x64] os: [win32] @@ -3625,8 +5463,8 @@ packages: dev: true optional: true - /@swc/core@1.3.95: - resolution: {integrity: sha512-PMrNeuqIusq9DPDooV3FfNEbZuTu5jKAc04N3Hm6Uk2Fl49cqElLFQ4xvl4qDmVDz97n3n/C1RE0/f6WyGPEiA==} + /@swc/core@1.4.6: + resolution: {integrity: sha512-A7iK9+1qzTCIuc3IYcS8gPHCm9bZVKUJrfNnwveZYyo6OFp3jLno4WOM2yBy5uqedgYATEiWgBYHKq37KrU6IA==} engines: {node: '>=10'} requiresBuild: true peerDependencies: @@ -3635,73 +5473,48 @@ packages: '@swc/helpers': optional: true dependencies: - '@swc/counter': 0.1.1 + '@swc/counter': 0.1.3 '@swc/types': 0.1.5 optionalDependencies: - '@swc/core-darwin-arm64': 1.3.95 - '@swc/core-darwin-x64': 1.3.95 - '@swc/core-linux-arm-gnueabihf': 1.3.95 - '@swc/core-linux-arm64-gnu': 1.3.95 - '@swc/core-linux-arm64-musl': 1.3.95 - '@swc/core-linux-x64-gnu': 1.3.95 - '@swc/core-linux-x64-musl': 1.3.95 - '@swc/core-win32-arm64-msvc': 1.3.95 - '@swc/core-win32-ia32-msvc': 1.3.95 - '@swc/core-win32-x64-msvc': 1.3.95 + '@swc/core-darwin-arm64': 1.4.6 + '@swc/core-darwin-x64': 1.4.6 + '@swc/core-linux-arm-gnueabihf': 1.4.6 + '@swc/core-linux-arm64-gnu': 1.4.6 + '@swc/core-linux-arm64-musl': 1.4.6 + '@swc/core-linux-x64-gnu': 1.4.6 + '@swc/core-linux-x64-musl': 1.4.6 + '@swc/core-win32-arm64-msvc': 1.4.6 + '@swc/core-win32-ia32-msvc': 1.4.6 + '@swc/core-win32-x64-msvc': 1.4.6 dev: true - /@swc/counter@0.1.1: - resolution: {integrity: sha512-xVRaR4u9hcYjFvcSg71Lz5Bo4//CyjAAfMxa7UsaDSYxAshflUkVJWiyVWrfxC59z2kP1IzI4/1BEpnhI9o3Mw==} + /@swc/counter@0.1.3: + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} dev: true /@swc/types@0.1.5: resolution: {integrity: sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==} dev: true - /@tanstack/query-core@4.29.25: - resolution: {integrity: sha512-DI4y4VC6Uw4wlTpOocEXDky69xeOScME1ezLKsj+hOk7DguC9fkqXtp6Hn39BVb9y0b5IBrY67q6kIX623Zj4Q==} - - /@tanstack/query-persist-client-core@4.29.25: - resolution: {integrity: sha512-jC1JlZxUaO4bJdeN0GcLwnNIbtsdzkL54hZP1rjTbp2tzfEHNQFkMjaIMZtnsxgdrU9LclXz8loOd1ufQ6C44w==} - dependencies: - '@tanstack/query-core': 4.29.25 - - /@tanstack/query-sync-storage-persister@4.29.25: - resolution: {integrity: sha512-X6kweYH4eooI1tPpKEt4Gdav4JvjAbX6lwWyvvHnLBsS1t8dV/9liemCIWCaPb9g17e5g9EfBTb7P3AImsZq2g==} - dependencies: - '@tanstack/query-persist-client-core': 4.29.25 - - /@tanstack/react-query-persist-client@4.29.25(@tanstack/react-query@4.29.25): - resolution: {integrity: sha512-Vm4E+iPZ7rPGfN0jhsK35vZ5EUFvKyE3Kg0uthlqmqmy2rzm43f1EIFpA1++j0dWST/swIOj3pfiSBxJ/6s5zA==} - peerDependencies: - '@tanstack/react-query': 4.29.25 - dependencies: - '@tanstack/query-persist-client-core': 4.29.25 - '@tanstack/react-query': 4.29.25(react-dom@18.2.0)(react@18.2.0) + /@tanstack/query-core@5.17.1: + resolution: {integrity: sha512-kUXozQmU7NBtzX5dM6qfFNZN+YK/9Ct37hnG/ogdgI4mExIx7VH/qRepsPhKfNrJz2w81/JykmM3Uug6sVpUSw==} + dev: true - /@tanstack/react-query@4.29.25(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-c1+Ezu+XboYrdAMdusK2fTdRqXPMgPAnyoTrzHOZQqr8Hqz6PNvV9DSKl8agUo6nXX4np7fdWabIprt+838dLg==} + /@tanstack/react-query@5.17.1(react@18.2.0): + resolution: {integrity: sha512-4JYgX0kU+pvwVQi5eRiHGvBK7WnahEl6lmaxd32ZVSKmByAxLgaewoxBR03cdDNse8lUD2zGOe0sx3M/EGRlmA==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-native: '*' - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true + react: ^18.0.0 dependencies: - '@tanstack/query-core': 4.29.25 + '@tanstack/query-core': 5.17.1 react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - use-sync-external-store: 1.2.0(react@18.2.0) + dev: true /@testing-library/dom@9.3.1: resolution: {integrity: sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==} engines: {node: '>=14'} dependencies: - '@babel/code-frame': 7.22.10 - '@babel/runtime': 7.22.6 + '@babel/code-frame': 7.22.13 + '@babel/runtime': 7.23.7 '@types/aria-query': 5.0.1 aria-query: 5.1.3 chalk: 4.1.2 @@ -3710,17 +5523,20 @@ packages: pretty-format: 27.5.1 dev: false - /@testing-library/jest-dom@6.1.4(vitest@0.34.2): - resolution: {integrity: sha512-wpoYrCYwSZ5/AxcrjLxJmCU6I5QAJXslEeSiMQqaWmP2Kzpd1LvF/qxmAIW2qposULGWq2gw30GgVNFLSc2Jnw==} + /@testing-library/jest-dom@6.4.2(vitest@1.2.2): + resolution: {integrity: sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} peerDependencies: '@jest/globals': '>= 28' + '@types/bun': latest '@types/jest': '>= 28' jest: '>= 28' vitest: '>= 0.32' peerDependenciesMeta: '@jest/globals': optional: true + '@types/bun': + optional: true '@types/jest': optional: true jest: @@ -3728,15 +5544,15 @@ packages: vitest: optional: true dependencies: - '@adobe/css-tools': 4.3.1 - '@babel/runtime': 7.22.6 + '@adobe/css-tools': 4.3.2 + '@babel/runtime': 7.23.7 aria-query: 5.3.0 chalk: 3.0.0 css.escape: 1.5.1 - dom-accessibility-api: 0.5.16 + dom-accessibility-api: 0.6.3 lodash: 4.17.21 redent: 3.0.0 - vitest: 0.34.2(jsdom@22.1.0) + vitest: 1.2.2(@types/node@20.11.17)(jsdom@24.0.0) dev: true /@testing-library/react-hooks@8.0.1(react-dom@18.2.0)(react@18.2.0): @@ -3782,14 +5598,14 @@ packages: react-error-boundary: 3.1.4(react@17.0.2) dev: true - /@testing-library/react@14.0.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-S04gSNJbYE30TlIMLTzv6QCTzt9AqIF5y6s6SzVFILNcNvbV/jU96GeiTPillGQo+Ny64M/5PV7klNYYgv5Dfg==} + /@testing-library/react@14.2.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-sGdjws32ai5TLerhvzThYFbpnF9XtL65Cjf+gB0Dhr29BGqK+mAeN7SURSdu+eqgET4ANcWoC7FQpkaiGvBr+A==} engines: {node: '>=14'} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 dependencies: - '@babel/runtime': 7.22.6 + '@babel/runtime': 7.23.7 '@testing-library/dom': 9.3.1 '@types/react-dom': 18.2.7 react: 18.2.0 @@ -3815,11 +5631,6 @@ packages: - supports-color dev: true - /@tootallnate/once@2.0.0: - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - dev: true - /@trufflesuite/bigint-buffer@1.1.10: resolution: {integrity: sha512-pYIQC5EcMmID74t26GCC67946mgTJFiLXOT/BYozgrd4UEY2JHEGLhWi9cMiQCt5BSqFEvKkCHNnoj82SRjiEw==} engines: {node: '>= 14.0.0'} @@ -3853,7 +5664,7 @@ packages: resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} dev: true - /@typechain/ethers-v5@10.2.1(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.1)(typescript@5.2.2): + /@typechain/ethers-v5@10.2.1(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.3.1)(typescript@5.3.3): resolution: {integrity: sha512-n3tQmCZjRE6IU4h6lqUGiQ1j866n5MTCBJreNEHHVWXa2u9GJTaeYyU1/k+1qLutkyw+sS6VAN+AbeiTqsxd/A==} peerDependencies: '@ethersproject/abi': ^5.0.0 @@ -3866,9 +5677,9 @@ packages: '@ethersproject/providers': 5.7.2 ethers: 5.7.2 lodash: 4.17.21 - ts-essentials: 7.0.3(typescript@5.2.2) - typechain: 8.3.1(typescript@5.2.2) - typescript: 5.2.2 + ts-essentials: 7.0.3(typescript@5.3.3) + typechain: 8.3.1(typescript@5.3.3) + typescript: 5.3.3 dev: true /@types/abstract-leveldown@5.0.2: @@ -3882,40 +5693,29 @@ packages: /@types/bn.js@4.11.6: resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 dev: true /@types/bn.js@5.1.0: resolution: {integrity: sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 dev: true /@types/body-parser@1.19.1: resolution: {integrity: sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==} dependencies: '@types/connect': 3.4.35 - '@types/node': 20.8.9 - dev: true - - /@types/chai-as-promised@7.1.5: - resolution: {integrity: sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==} - dependencies: - '@types/chai': 4.3.8 - dev: true + '@types/node': 20.11.17 - /@types/chai-subset@1.3.3: - resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} + /@types/chai-as-promised@7.1.8: + resolution: {integrity: sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==} dependencies: - '@types/chai': 4.3.8 - dev: true - - /@types/chai@4.3.7: - resolution: {integrity: sha512-/k+vesl92vMvMygmQrFe9Aimxi6oQXFUX9mA5HanTrKUSAMoLauSi6PNFOdRw0oeqilaW600GNx2vSaT2f8aIQ==} + '@types/chai': 4.3.11 dev: true - /@types/chai@4.3.8: - resolution: {integrity: sha512-yW/qTM4mRBBcsA9Xw9FbcImYtFPY7sgr+G/O5RDYVmxiy9a+pE5FyoFUi8JYCZY5nicj8atrr1pcfPiYpeNGOA==} + /@types/chai@4.3.11: + resolution: {integrity: sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==} dev: true /@types/change-case@2.3.1: @@ -3925,50 +5725,88 @@ packages: change-case: 4.1.2 dev: false + /@types/chrome@0.0.136: + resolution: {integrity: sha512-XDEiRhLkMd+SB7Iw3ZUIj/fov3wLd4HyTdLltVszkgl1dBfc3Rb7oPMVZ2Mz2TLqnF7Ow+StbR8E7r9lqpb4DA==} + dependencies: + '@types/filesystem': 0.0.35 + '@types/har-format': 1.2.15 + dev: true + /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 /@types/dateformat@5.0.0: resolution: {integrity: sha512-SZg4JdHIWHQGEokbYGZSDvo5wA4TLYPXaqhigs/wH+REDOejcJzgH+qyY+HtEUtWOZxEUkbhbdYPqQDiEgrXeA==} dev: false - /@types/debug@4.1.8: - resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==} + /@types/debug@4.1.12: + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} dependencies: '@types/ms': 0.7.31 + dev: true + + /@types/dom-screen-wake-lock@1.0.3: + resolution: {integrity: sha512-3Iten7X3Zgwvk6kh6/NRdwN7WbZ760YgFCsF5AxDifltUQzW1RaW+WRmcVtgwFzLjaNu64H+0MPJ13yRa8g3Dw==} + dev: true + + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: true /@types/express-serve-static-core@4.17.35: resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 '@types/send': 0.17.1 - dev: true - /@types/express@4.17.19: - resolution: {integrity: sha512-UtOfBtzN9OvpZPPbnnYunfjM7XCI4jyk1NvnFhTVz5krYAnW4o5DCoIekvms+8ApqhB4+9wSge1kBijdfTSmfg==} + /@types/express@4.17.21: + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} dependencies: '@types/body-parser': 1.19.1 '@types/express-serve-static-core': 4.17.35 '@types/qs': 6.9.7 '@types/serve-static': 1.13.10 + + /@types/filesystem@0.0.35: + resolution: {integrity: sha512-1eKvCaIBdrD2mmMgy5dwh564rVvfEhZTWVQQGRNn0Nt4ZEnJ0C8oSUCzvMKRA4lGde5oEVo+q2MrTTbV/GHDCQ==} + dependencies: + '@types/filewriter': 0.0.32 + dev: true + + /@types/filewriter@0.0.32: + resolution: {integrity: sha512-Kpi2GXQyYJdjL8mFclL1eDgihn1SIzorMZjD94kdPZh9E4VxGOeyjPxi5LpsM4Zku7P0reqegZTt2GxhmA9VBg==} dev: true /@types/glob@8.1.0: resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.8.8 + '@types/node': 20.11.16 + dev: true + + /@types/har-format@1.2.15: + resolution: {integrity: sha512-RpQH4rXLuvTXKR0zqHq3go0RVXYv/YVqv4TnPH95VbwUxZdQlK1EtcMvQvMpDngHbt13Csh9Z4qT9AbkiQH5BA==} + dev: true + + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} dev: true - /@types/is-ci@3.0.0: - resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} + /@types/istanbul-lib-report@3.0.3: + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} dependencies: - ci-info: 3.8.0 - dev: false + '@types/istanbul-lib-coverage': 2.0.6 + dev: true + + /@types/istanbul-reports@3.0.4: + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + dependencies: + '@types/istanbul-lib-report': 3.0.3 + dev: true /@types/json-schema@7.0.12: resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} @@ -3988,7 +5826,7 @@ packages: dependencies: '@types/abstract-leveldown': 5.0.2 '@types/level-errors': 3.0.0 - '@types/node': 20.8.9 + '@types/node': 20.11.17 dev: true /@types/lru-cache@5.1.1: @@ -4003,7 +5841,6 @@ packages: /@types/mime@1.3.2: resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} - dev: true /@types/minimatch@3.0.5: resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} @@ -4020,26 +5857,27 @@ packages: /@types/mkdirp@0.5.2: resolution: {integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 dev: true - /@types/mocha@10.0.3: - resolution: {integrity: sha512-RsOPImTriV/OE4A9qKjMtk2MnXiuLLbcO3nCXK+kvq4nr0iMfFgpjaX3MPLb6f7+EL1FGSelYvuJMV6REH+ZPQ==} + /@types/mocha@10.0.6: + resolution: {integrity: sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==} dev: true - /@types/morgan@1.9.7: - resolution: {integrity: sha512-4sJFBUBrIZkP5EvMm1L6VCXp3SQe8dnXqlVpe1jsmTjS1JQVmSjnpMNs8DosQd6omBi/K7BSKJ6z/Mc3ki0K9g==} + /@types/morgan@1.9.9: + resolution: {integrity: sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.11.16 dev: true /@types/ms@0.7.31: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + dev: true /@types/node-fetch@2.6.4: resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 form-data: 3.0.1 dev: true @@ -4049,15 +5887,16 @@ packages: /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: false - /@types/node@20.8.8: - resolution: {integrity: sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==} + /@types/node@20.11.16: + resolution: {integrity: sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==} dependencies: - undici-types: 5.25.3 + undici-types: 5.26.5 dev: true - /@types/node@20.8.9: - resolution: {integrity: sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==} + /@types/node@20.11.17: + resolution: {integrity: sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==} dependencies: undici-types: 5.26.5 @@ -4071,11 +5910,11 @@ packages: /@types/pbkdf2@3.1.0: resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 dev: true - /@types/pino-multi-stream@5.1.5: - resolution: {integrity: sha512-md4VfNYACuZZVgBbYqv9D4msKIyLmIdyf/kdjT7HG/xhjM18pKseDGylME0nPvNR66bpYQ2i4v4zPWe8FzwZPA==} + /@types/pino-multi-stream@5.1.6: + resolution: {integrity: sha512-LEDs2CdCkFwu4zWPZonZdfKfrAyG3OVqxVvBluRwrPF21Xr9dSw1A3k1NHhSXoBFp91cOFv2T7aLUxP6IO6LUw==} dependencies: '@types/pino': 6.3.11 dev: true @@ -4089,13 +5928,13 @@ packages: /@types/pino-std-serializers@2.4.1: resolution: {integrity: sha512-17XcksO47M24IVTVKPeAByWUd3Oez7EbIjXpSbzMPhXVzgjGtrOa49gKBwxH9hb8dKv58OelsWQ+A1G1l9S3wQ==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 dev: true /@types/pino@6.3.11: resolution: {integrity: sha512-S7+fLONqSpHeW9d7TApUqO6VN47KYgOXhCNKwGBVLHObq8HhaAYlVqUNdfnvoXjCMiwE5xcPm/5R2ZUh8bgaXQ==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 '@types/pino-pretty': 4.7.1 '@types/pino-std-serializers': 2.4.1 sonic-boom: 2.8.0 @@ -4105,7 +5944,7 @@ packages: resolution: {integrity: sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg==} deprecated: This is a stub types definition. pino provides its own type definitions, so you do not need this installed. dependencies: - pino: 8.16.1 + pino: 8.19.0 dev: true /@types/prettier@2.3.2: @@ -4118,11 +5957,9 @@ packages: /@types/qs@6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} - dev: true /@types/range-parser@1.2.4: resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} - dev: true /@types/react-dom@18.2.7: resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} @@ -4141,7 +5978,7 @@ packages: /@types/readable-stream@2.3.15: resolution: {integrity: sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 safe-buffer: 5.1.2 dev: true @@ -4149,42 +5986,35 @@ packages: resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} dev: false - /@types/secp256k1@4.0.3: - resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} + /@types/secp256k1@4.0.6: + resolution: {integrity: sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 dev: true /@types/seedrandom@3.0.1: resolution: {integrity: sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw==} dev: true - /@types/semver@6.2.3: - resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} - dev: false - - /@types/semver@7.5.0: - resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} - dev: true + /@types/semver@7.5.7: + resolution: {integrity: sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==} /@types/send@0.17.1: resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} dependencies: '@types/mime': 1.3.2 - '@types/node': 20.8.9 - dev: true + '@types/node': 20.11.17 /@types/serve-static@1.13.10: resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} dependencies: '@types/mime': 1.3.2 - '@types/node': 20.8.9 - dev: true + '@types/node': 20.11.17 /@types/sinon-chai@3.2.5: resolution: {integrity: sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ==} dependencies: - '@types/chai': 4.3.8 + '@types/chai': 4.3.11 '@types/sinon': 10.0.2 dev: true @@ -4194,8 +6024,13 @@ packages: '@sinonjs/fake-timers': 7.1.2 dev: true + /@types/stack-utils@2.0.3: + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + dev: true + /@types/trusted-types@2.0.3: resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==} + dev: true /@types/underscore@1.11.3: resolution: {integrity: sha512-Fl1TX1dapfXyDqFg2ic9M+vlXRktcPJrc4PR7sRc7sdVrjavg/JHlbUXBt8qWWqhJrmSqg3RNAkAPRiOYw6Ahw==} @@ -4212,19 +6047,30 @@ packages: '@types/underscore': 1.11.3 dev: true - /@types/ws@7.4.7: - resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} - dependencies: - '@types/node': 20.8.9 - /@types/ws@8.5.3: resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} dependencies: - '@types/node': 20.8.9 + '@types/node': 20.11.17 dev: false - /@typescript-eslint/eslint-plugin@6.9.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==} + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + dev: true + + /@types/yargs@15.0.19: + resolution: {integrity: sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==} + dependencies: + '@types/yargs-parser': 21.0.3 + dev: true + + /@types/yargs@17.0.32: + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + dependencies: + '@types/yargs-parser': 21.0.3 + dev: true + + /@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -4235,25 +6081,25 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 6.9.0(eslint@8.52.0)(typescript@5.2.2) - '@typescript-eslint/scope-manager': 6.9.0 - '@typescript-eslint/type-utils': 6.9.0(eslint@8.52.0)(typescript@5.2.2) - '@typescript-eslint/utils': 6.9.0(eslint@8.52.0)(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.9.0 + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.52.0 + eslint: 8.56.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 - semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.2.2) - typescript: 5.2.2 + semver: 7.6.0 + ts-api-utils: 1.0.1(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.9.0(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==} + /@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -4262,27 +6108,27 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.9.0 - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/typescript-estree': 6.9.0(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.9.0 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.52.0 - typescript: 5.2.2 + eslint: 8.56.0 + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@6.9.0: - resolution: {integrity: sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==} + /@typescript-eslint/scope-manager@6.21.0: + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/visitor-keys': 6.9.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 dev: true - /@typescript-eslint/type-utils@6.9.0(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==} + /@typescript-eslint/type-utils@6.21.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -4291,23 +6137,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.9.0(typescript@5.2.2) - '@typescript-eslint/utils': 6.9.0(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) debug: 4.3.4(supports-color@8.1.1) - eslint: 8.52.0 - ts-api-utils: 1.0.1(typescript@5.2.2) - typescript: 5.2.2 + eslint: 8.56.0 + ts-api-utils: 1.0.1(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@6.9.0: - resolution: {integrity: sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==} + /@typescript-eslint/types@6.21.0: + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.9.0(typescript@5.2.2): - resolution: {integrity: sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==} + /@typescript-eslint/typescript-estree@6.21.0(typescript@5.3.3): + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -4315,42 +6161,43 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/visitor-keys': 6.9.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.2.2) - typescript: 5.2.2 + minimatch: 9.0.3 + semver: 7.6.0 + ts-api-utils: 1.0.1(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.9.0(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==} + /@typescript-eslint/utils@6.21.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@types/json-schema': 7.0.12 - '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 6.9.0 - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/typescript-estree': 6.9.0(typescript@5.2.2) - eslint: 8.52.0 - semver: 7.5.4 + '@types/semver': 7.5.7 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + eslint: 8.56.0 + semver: 7.6.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@6.9.0: - resolution: {integrity: sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==} + /@typescript-eslint/visitor-keys@6.21.0: + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.9.0 + '@typescript-eslint/types': 6.21.0 eslint-visitor-keys: 3.4.3 dev: true @@ -4358,158 +6205,68 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vitest/coverage-istanbul@0.34.6(vitest@0.34.1): - resolution: {integrity: sha512-5KaBNZPDSk2ybavC3rZ1pWGniw7sJ5usuwVGRUYzJwiBfWvnLpuUer7bjw7qUCRGdKJXrBgb/Dsgif9rkwMX/A==} - peerDependencies: - vitest: '>=0.32.0 <1' - dependencies: - istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 6.0.0 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.5 - picocolors: 1.0.0 - test-exclude: 6.0.0 - vitest: 0.34.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@vitest/coverage-istanbul@0.34.6(vitest@0.34.2): - resolution: {integrity: sha512-5KaBNZPDSk2ybavC3rZ1pWGniw7sJ5usuwVGRUYzJwiBfWvnLpuUer7bjw7qUCRGdKJXrBgb/Dsgif9rkwMX/A==} + /@vitest/coverage-istanbul@1.2.2(vitest@1.2.2): + resolution: {integrity: sha512-tJybwO8JT4H9ANz0T0/tJ1M5g3BkuHKYF1w5YO3z9sAiHBdGANrxN9c5lomJx1WSnLzCxQR5xxlJ4TLKbzrR3w==} peerDependencies: - vitest: '>=0.32.0 <1' + vitest: ^1.0.0 dependencies: - istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 6.0.0 + debug: 4.3.4(supports-color@8.1.1) + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.1 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.5 + istanbul-reports: 3.1.6 + magicast: 0.3.3 picocolors: 1.0.0 test-exclude: 6.0.0 - vitest: 0.34.2(jsdom@22.1.0) + vitest: 1.2.2(@types/node@20.11.17)(jsdom@24.0.0) transitivePeerDependencies: - supports-color dev: true - /@vitest/expect@0.34.1: - resolution: {integrity: sha512-q2CD8+XIsQ+tHwypnoCk8Mnv5e6afLFvinVGCq3/BOT4kQdVQmY6rRfyKkwcg635lbliLPqbunXZr+L1ssUWiQ==} - dependencies: - '@vitest/spy': 0.34.1 - '@vitest/utils': 0.34.1 - chai: 4.3.10 - dev: true - - /@vitest/expect@0.34.2: - resolution: {integrity: sha512-EZm2dMNlLyIfDMha17QHSQcg2KjeAZaXd65fpPzXY5bvnfx10Lcaz3N55uEe8PhF+w4pw+hmrlHLLlRn9vkBJg==} - dependencies: - '@vitest/spy': 0.34.2 - '@vitest/utils': 0.34.2 - chai: 4.3.10 - dev: true - - /@vitest/expect@0.34.4: - resolution: {integrity: sha512-XlMKX8HyYUqB8dsY8Xxrc64J2Qs9pKMt2Z8vFTL4mBWXJsg4yoALHzJfDWi8h5nkO4Zua4zjqtapQ/IluVkSnA==} + /@vitest/expect@1.2.2: + resolution: {integrity: sha512-3jpcdPAD7LwHUUiT2pZTj2U82I2Tcgg2oVPvKxhn6mDI2On6tfvPQTjAI4628GUGDZrCm4Zna9iQHm5cEexOAg==} dependencies: - '@vitest/spy': 0.34.4 - '@vitest/utils': 0.34.4 + '@vitest/spy': 1.2.2 + '@vitest/utils': 1.2.2 chai: 4.3.10 dev: true - /@vitest/runner@0.34.1: - resolution: {integrity: sha512-YfQMpYzDsYB7yqgmlxZ06NI4LurHWfrH7Wy3Pvf/z/vwUSgq1zLAb1lWcItCzQG+NVox+VvzlKQrYEXb47645g==} - dependencies: - '@vitest/utils': 0.34.1 - p-limit: 4.0.0 - pathe: 1.1.1 - dev: true - - /@vitest/runner@0.34.2: - resolution: {integrity: sha512-8ydGPACVX5tK3Dl0SUwxfdg02h+togDNeQX3iXVFYgzF5odxvaou7HnquALFZkyVuYskoaHUOqOyOLpOEj5XTA==} + /@vitest/runner@1.2.2: + resolution: {integrity: sha512-JctG7QZ4LSDXr5CsUweFgcpEvrcxOV1Gft7uHrvkQ+fsAVylmWQvnaAr/HDp3LAH1fztGMQZugIheTWjaGzYIg==} dependencies: - '@vitest/utils': 0.34.2 - p-limit: 4.0.0 - pathe: 1.1.1 - dev: true - - /@vitest/runner@0.34.4: - resolution: {integrity: sha512-hwwdB1StERqUls8oV8YcpmTIpVeJMe4WgYuDongVzixl5hlYLT2G8afhcdADeDeqCaAmZcSgLTLtqkjPQF7x+w==} - dependencies: - '@vitest/utils': 0.34.4 - p-limit: 4.0.0 - pathe: 1.1.1 - dev: true - - /@vitest/snapshot@0.34.1: - resolution: {integrity: sha512-0O9LfLU0114OqdF8lENlrLsnn024Tb1CsS9UwG0YMWY2oGTQfPtkW+B/7ieyv0X9R2Oijhi3caB1xgGgEgclSQ==} - dependencies: - magic-string: 0.30.1 - pathe: 1.1.1 - pretty-format: 29.7.0 - dev: true - - /@vitest/snapshot@0.34.2: - resolution: {integrity: sha512-qhQ+xy3u4mwwLxltS4Pd4SR+XHv4EajiTPNY3jkIBLUApE6/ce72neJPSUQZ7bL3EBuKI+NhvzhGj3n5baRQUQ==} - dependencies: - magic-string: 0.30.1 + '@vitest/utils': 1.2.2 + p-limit: 5.0.0 pathe: 1.1.1 - pretty-format: 29.7.0 dev: true - /@vitest/snapshot@0.34.4: - resolution: {integrity: sha512-GCsh4coc3YUSL/o+BPUo7lHQbzpdttTxL6f4q0jRx2qVGoYz/cyTRDJHbnwks6TILi6560bVWoBpYC10PuTLHw==} + /@vitest/snapshot@1.2.2: + resolution: {integrity: sha512-SmGY4saEw1+bwE1th6S/cZmPxz/Q4JWsl7LvbQIky2tKE35US4gd0Mjzqfr84/4OD0tikGWaWdMja/nWL5NIPA==} dependencies: - magic-string: 0.30.1 + magic-string: 0.30.5 pathe: 1.1.1 pretty-format: 29.7.0 dev: true - /@vitest/spy@0.34.1: - resolution: {integrity: sha512-UT4WcI3EAPUNO8n6y9QoEqynGGEPmmRxC+cLzneFFXpmacivjHZsNbiKD88KUScv5DCHVDgdBsLD7O7s1enFcQ==} + /@vitest/spy@1.2.2: + resolution: {integrity: sha512-k9Gcahssw8d7X3pSLq3e3XEu/0L78mUkCjivUqCQeXJm9clfXR/Td8+AP+VC1O6fKPIDLcHDTAmBOINVuv6+7g==} dependencies: - tinyspy: 2.1.1 - dev: true - - /@vitest/spy@0.34.2: - resolution: {integrity: sha512-yd4L9OhfH6l0Av7iK3sPb3MykhtcRN5c5K5vm1nTbuN7gYn+yvUVVsyvzpHrjqS7EWqn9WsPJb7+0c3iuY60tA==} - dependencies: - tinyspy: 2.1.1 - dev: true - - /@vitest/spy@0.34.4: - resolution: {integrity: sha512-PNU+fd7DUPgA3Ya924b1qKuQkonAW6hL7YUjkON3wmBwSTIlhOSpy04SJ0NrRsEbrXgMMj6Morh04BMf8k+w0g==} - dependencies: - tinyspy: 2.1.1 - dev: true - - /@vitest/utils@0.34.1: - resolution: {integrity: sha512-/ql9dsFi4iuEbiNcjNHQWXBum7aL8pyhxvfnD9gNtbjR9fUKAjxhj4AA3yfLXg6gJpMGGecvtF8Au2G9y3q47Q==} - dependencies: - diff-sequences: 29.6.3 - loupe: 2.3.6 - pretty-format: 29.7.0 - dev: true - - /@vitest/utils@0.34.2: - resolution: {integrity: sha512-Lzw+kAsTPubhoQDp1uVAOP6DhNia1GMDsI9jgB0yMn+/nDaPieYQ88lKqz/gGjSHL4zwOItvpehec9OY+rS73w==} - dependencies: - diff-sequences: 29.6.3 - loupe: 2.3.6 - pretty-format: 29.7.0 + tinyspy: 2.2.0 dev: true - /@vitest/utils@0.34.4: - resolution: {integrity: sha512-yR2+5CHhp/K4ySY0Qtd+CAL9f5Yh1aXrKfAT42bq6CtlGPh92jIDDDSg7ydlRow1CP+dys4TrOrbELOyNInHSg==} + /@vitest/utils@1.2.2: + resolution: {integrity: sha512-WKITBHLsBHlpjnDQahr+XK6RE7MiAsgrIkr0pGhQ9ygoxBfUeG0lUG5iLlzqjmKSlBv3+j5EGsriBzh+C3Tq9g==} dependencies: diff-sequences: 29.6.3 - loupe: 2.3.6 + estree-walker: 3.0.3 + loupe: 2.3.7 pretty-format: 29.7.0 dev: true /@vue/compiler-core@3.3.4: resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==} dependencies: - '@babel/parser': 7.23.0 + '@babel/parser': 7.23.6 '@vue/shared': 3.3.4 estree-walker: 2.0.2 source-map-js: 1.0.2 @@ -4525,15 +6282,15 @@ packages: /@vue/compiler-sfc@3.3.4: resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} dependencies: - '@babel/parser': 7.23.0 + '@babel/parser': 7.23.6 '@vue/compiler-core': 3.3.4 '@vue/compiler-dom': 3.3.4 '@vue/compiler-ssr': 3.3.4 '@vue/reactivity-transform': 3.3.4 '@vue/shared': 3.3.4 estree-walker: 2.0.2 - magic-string: 0.30.1 - postcss: 8.4.27 + magic-string: 0.30.5 + postcss: 8.4.35 source-map-js: 1.0.2 dev: true @@ -4547,326 +6304,206 @@ packages: /@vue/reactivity-transform@3.3.4: resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==} dependencies: - '@babel/parser': 7.23.0 + '@babel/parser': 7.23.6 '@vue/compiler-core': 3.3.4 '@vue/shared': 3.3.4 estree-walker: 2.0.2 - magic-string: 0.30.1 + magic-string: 0.30.5 dev: true /@vue/shared@3.3.4: resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} dev: true - /@wagmi/chains@0.2.22(typescript@5.2.2): - resolution: {integrity: sha512-TdiOzJT6TO1JrztRNjTA5Quz+UmQlbvWFG8N41u9tta0boHA1JCAzGGvU6KuIcOmJfRJkKOUIt67wlbopCpVHg==} - peerDependencies: - typescript: '>=4.9.4' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - typescript: 5.2.2 - - /@wagmi/cli@1.5.2(@wagmi/core@1.4.5)(typescript@5.2.2)(wagmi@1.0.1): - resolution: {integrity: sha512-UfLMYhW6mQBCjR8A5s01Chf9GpHzdpcuuBuzJ36QGXcMSJAxylz5ImVZWfCRV0ct1UruydjKVSW1QSI6azNxRQ==} - engines: {node: '>=14'} + /@wagmi/cli@2.1.2(typescript@5.3.3): + resolution: {integrity: sha512-gJLjPDD+xc7IN6OJYQdOl3xhfnf7nXZoaELCchNo9Pt+1hUVFYq2uC4HGBXYvUQ03RJNmZca1X8qP8pJeuJFYA==} hasBin: true peerDependencies: - '@wagmi/core': '>=1.0.0' typescript: '>=5.0.4' - wagmi: '>=1.0.0' peerDependenciesMeta: - '@wagmi/core': - optional: true typescript: optional: true - wagmi: - optional: true dependencies: - '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) - abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) - abort-controller: 3.0.0 - bundle-require: 3.1.2(esbuild@0.16.17) + abitype: 0.9.8(typescript@5.3.3)(zod@3.22.4) + bundle-require: 4.0.2(esbuild@0.19.10) cac: 6.7.14 change-case: 4.1.2 chokidar: 3.5.3 dedent: 0.7.0 - detect-package-manager: 2.0.1 - dotenv: 16.3.1 + dotenv: 16.4.5 dotenv-expand: 10.0.0 - esbuild: 0.16.17 - execa: 6.1.0 + esbuild: 0.19.10 + execa: 8.0.1 find-up: 6.3.0 - fs-extra: 10.1.0 + fs-extra: 11.1.1 globby: 13.2.2 - node-fetch: 3.3.2 ora: 6.3.1 pathe: 1.1.1 picocolors: 1.0.0 - prettier: 2.8.8 - typescript: 5.2.2 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.3) - wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) - zod: 3.22.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: true - - /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): - resolution: {integrity: sha512-fl01vym19DE1uoE+MlASw5zo3Orr/YXlJRjOKLaKYtV+Q7jOLY4TwHgq7sEMs+JYOvFICFBEAlWNNxidr51AqQ==} - peerDependencies: - '@wagmi/chains': '>=0.2.0' - typescript: '>=4.9.4' - viem: ~0.3.18 - peerDependenciesMeta: - '@wagmi/chains': - optional: true - typescript: - optional: true - dependencies: - '@coinbase/wallet-sdk': 3.7.1 - '@ledgerhq/connect-kit-loader': 1.1.0 - '@safe-global/safe-apps-provider': 0.15.2 - '@safe-global/safe-apps-sdk': 7.11.0 - '@wagmi/chains': 0.2.22(typescript@5.2.2) - '@walletconnect/ethereum-provider': 2.7.2(@web3modal/standalone@2.4.3) - '@walletconnect/legacy-provider': 2.0.0 - '@web3modal/standalone': 2.4.3(react@18.2.0) - abitype: 0.8.1(typescript@5.2.2) - eventemitter3: 4.0.7 - typescript: 5.2.2 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) + prettier: 3.1.1 + typescript: 5.3.3 + viem: 2.7.19(typescript@5.3.3)(zod@3.22.4) + zod: 3.22.4 transitivePeerDependencies: - - '@react-native-async-storage/async-storage' - bufferutil - - debug - - encoding - - lokijs - - react - - supports-color - utf-8-validate - - zod + dev: true - /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): - resolution: {integrity: sha512-UgwsQKQDFObJVJMf9pDfFoXTv710o4zrTHyhIWKBTMMkLpCMsMxN5+ZaDhBYt/BgoRinfRYQo8uwuwLhxE6Log==} + /@wagmi/connectors@4.1.12(@wagmi/core@2.6.3)(react-dom@18.2.0)(react-native@0.73.1)(react@18.2.0)(typescript@5.3.3)(viem@2.7.19): + resolution: {integrity: sha512-zqCJMOwpi8ssFjndVxVh3iUMwzcA7dPCjswhcy4xZyy1jm/VvGYC3o1wotq/gTCqUrz0SPIMGimZm4S6865b8A==} peerDependencies: + '@wagmi/core': 2.6.3 typescript: '>=5.0.4' - viem: '>=0.3.35' + viem: 2.x peerDependenciesMeta: typescript: optional: true dependencies: - '@coinbase/wallet-sdk': 3.7.1 - '@ledgerhq/connect-kit-loader': 1.1.0 - '@safe-global/safe-apps-provider': 0.17.1(typescript@5.2.2) - '@safe-global/safe-apps-sdk': 8.0.0(typescript@5.2.2) - '@walletconnect/ethereum-provider': 2.10.2(@walletconnect/modal@2.6.2) - '@walletconnect/legacy-provider': 2.0.0 + '@coinbase/wallet-sdk': 3.9.1 + '@metamask/sdk': 0.14.1(react-dom@18.2.0)(react-native@0.73.1)(react@18.2.0) + '@safe-global/safe-apps-provider': 0.18.1(typescript@5.3.3) + '@safe-global/safe-apps-sdk': 8.1.0(typescript@5.3.3) + '@wagmi/core': 2.6.3(react@18.2.0)(typescript@5.3.3)(viem@2.7.19) + '@walletconnect/ethereum-provider': 2.11.0(react@18.2.0) '@walletconnect/modal': 2.6.2(react@18.2.0) - '@walletconnect/utils': 2.10.2 - abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) - eventemitter3: 4.0.7 - typescript: 5.2.2 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) + typescript: 5.3.3 + viem: 2.7.19(typescript@5.3.3)(zod@3.22.4) transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' - '@react-native-async-storage/async-storage' - '@types/react' + - '@upstash/redis' + - '@vercel/kv' - bufferutil - encoding - - lokijs - react + - react-dom + - react-native + - rollup - supports-color - utf-8-validate - zod dev: true - /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): - resolution: {integrity: sha512-Zzg4Ob92QMF9NsC+z5/8JZjMn3NCCnwVWGJlv79qRX9mp5Ku40OzJNvqDnjcSGjshe6H0L/KtFZAqTlmu8lT7w==} - peerDependencies: - typescript: '>=4.9.4' - viem: ~0.3.18 - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@wagmi/chains': 0.2.22(typescript@5.2.2) - '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) - abitype: 0.8.1(typescript@5.2.2) - eventemitter3: 4.0.7 - typescript: 5.2.2 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) - zustand: 4.3.9(react@18.2.0) - transitivePeerDependencies: - - '@react-native-async-storage/async-storage' - - bufferutil - - debug - - encoding - - immer - - lokijs - - react - - supports-color - - utf-8-validate - - zod - - /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): - resolution: {integrity: sha512-N9luRb1Uk4tBN9kaYcQSWKE9AsRt/rvZaFt5IZech4JPzNN2sQlfhKd9GEjOXYRDqEPHdDvos7qyBKiDNTz4GA==} + /@wagmi/core@2.6.3(react@18.2.0)(typescript@5.3.3)(viem@2.7.19): + resolution: {integrity: sha512-hHvJkXFqfj56nAD0SH5bAHYxBItUBDIn6yGUBguMu121v6R4NxhwciEeff56lSjnKhmXjaWdJCEJ9C1YwkmDVw==} peerDependencies: + '@tanstack/query-core': '>=5.0.0' typescript: '>=5.0.4' - viem: '>=0.3.35' + viem: 2.x peerDependenciesMeta: + '@tanstack/query-core': + optional: true typescript: optional: true dependencies: - '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) - abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) - eventemitter3: 4.0.7 - typescript: 5.2.2 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) - zustand: 4.3.9(react@18.2.0) + eventemitter3: 5.0.1 + mipd: 0.0.5(typescript@5.3.3) + typescript: 5.3.3 + viem: 2.7.19(typescript@5.3.3)(zod@3.22.4) + zustand: 4.4.1(react@18.2.0) transitivePeerDependencies: - - '@react-native-async-storage/async-storage' - '@types/react' - bufferutil - - encoding - immer - - lokijs - react - - supports-color - utf-8-validate - zod dev: true - /@walletconnect/core@2.10.2: - resolution: {integrity: sha512-JQz/xp3SLEpTeRQctdck2ugSBVEpMxoSE+lFi2voJkZop1hv6P+uqr6E4PzjFluAjeAnKlT1xvra0aFWjPWVcw==} + /@walletconnect/core@2.11.0: + resolution: {integrity: sha512-2Tjp5BCevI7dbmqo/OrCjX4tqgMqwJNQLlQAlphqPfvwlF9+tIu6pGcVbSN3U9zyXzWIZCeleqEaWUeSeET4Ew==} dependencies: '@walletconnect/heartbeat': 1.2.1 '@walletconnect/jsonrpc-provider': 1.0.13 '@walletconnect/jsonrpc-types': 1.0.3 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/jsonrpc-ws-connection': 1.0.13 - '@walletconnect/keyvaluestorage': 1.0.2 + '@walletconnect/jsonrpc-ws-connection': 1.0.14 + '@walletconnect/keyvaluestorage': 1.1.1 '@walletconnect/logger': 2.0.1 '@walletconnect/relay-api': 1.0.9 '@walletconnect/relay-auth': 1.0.4 '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.10.2 - '@walletconnect/utils': 2.10.2 + '@walletconnect/types': 2.11.0 + '@walletconnect/utils': 2.11.0 events: 3.3.0 + isomorphic-unfetch: 3.1.0 lodash.isequal: 4.5.0 uint8arrays: 3.1.1 transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' - bufferutil - - lokijs + - encoding + - supports-color - utf-8-validate dev: true - /@walletconnect/core@2.7.2: - resolution: {integrity: sha512-gInSwh3uLpTEkDGArfOFoOVgiXW+zkZJpGqfARVi5fhSxsnL1jYNpqO2k8KAXUPfB4MIzLyaGruiaywncLAczA==} - dependencies: - '@walletconnect/heartbeat': 1.2.1 - '@walletconnect/jsonrpc-provider': 1.0.13 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/jsonrpc-ws-connection': 1.0.13 - '@walletconnect/keyvaluestorage': 1.0.2 - '@walletconnect/logger': 2.0.1 - '@walletconnect/relay-api': 1.0.9 - '@walletconnect/relay-auth': 1.0.4 - '@walletconnect/safe-json': 1.0.2 - '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.7.2 - '@walletconnect/utils': 2.7.2 - events: 3.3.0 - lodash.isequal: 4.5.0 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - '@react-native-async-storage/async-storage' - - bufferutil - - lokijs - - utf-8-validate - - /@walletconnect/crypto@1.0.3: - resolution: {integrity: sha512-+2jdORD7XQs76I2Odgr3wwrtyuLUXD/kprNVsjWRhhhdO9Mt6WqVzOPu0/t7OHSmgal8k7SoBQzUc5hu/8zL/g==} - dependencies: - '@walletconnect/encoding': 1.0.2 - '@walletconnect/environment': 1.0.1 - '@walletconnect/randombytes': 1.0.3 - aes-js: 3.1.2 - hash.js: 1.1.7 - tslib: 1.14.1 - - /@walletconnect/encoding@1.0.2: - resolution: {integrity: sha512-CrwSBrjqJ7rpGQcTL3kU+Ief+Bcuu9PH6JLOb+wM6NITX1GTxR/MfNwnQfhLKK6xpRAyj2/nM04OOH6wS8Imag==} - dependencies: - is-typedarray: 1.0.0 - tslib: 1.14.1 - typedarray-to-buffer: 3.1.5 - /@walletconnect/environment@1.0.1: resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} dependencies: tslib: 1.14.1 + dev: true - /@walletconnect/ethereum-provider@2.10.2(@walletconnect/modal@2.6.2): - resolution: {integrity: sha512-QMYFZ6+rVq2CJLdIPdKK0j1Qm66UA27oQU5V2SrL8EVwl7wFfm0Bq7fnL+qAWeDpn612dNeNErpk/ROa1zWlWg==} - peerDependencies: - '@walletconnect/modal': '>=2' - peerDependenciesMeta: - '@walletconnect/modal': - optional: true + /@walletconnect/ethereum-provider@2.11.0(react@18.2.0): + resolution: {integrity: sha512-YrTeHVjuSuhlUw7SQ6xBJXDuJ6iAC+RwINm9nVhoKYJSHAy3EVSJZOofMKrnecL0iRMtD29nj57mxAInIBRuZA==} dependencies: '@walletconnect/jsonrpc-http-connection': 1.0.7 '@walletconnect/jsonrpc-provider': 1.0.13 '@walletconnect/jsonrpc-types': 1.0.3 '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/modal': 2.6.2(react@18.2.0) - '@walletconnect/sign-client': 2.10.2 - '@walletconnect/types': 2.10.2 - '@walletconnect/universal-provider': 2.10.2 - '@walletconnect/utils': 2.10.2 + '@walletconnect/sign-client': 2.11.0 + '@walletconnect/types': 2.11.0 + '@walletconnect/universal-provider': 2.11.0 + '@walletconnect/utils': 2.11.0 events: 3.3.0 transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/kv' - bufferutil - encoding - - lokijs + - react + - supports-color - utf-8-validate dev: true - /@walletconnect/ethereum-provider@2.7.2(@web3modal/standalone@2.4.3): - resolution: {integrity: sha512-bvmutLrKKLlQ1WxKCvvX5p5YVox1D1f3Enp6hzAiZf4taN+n/M5rmwfAcLgLhp4cTAUDhl3zgtZErzDyJnvGvQ==} - peerDependencies: - '@web3modal/standalone': '>=2' - peerDependenciesMeta: - '@web3modal/standalone': - optional: true - dependencies: - '@walletconnect/jsonrpc-http-connection': 1.0.7 - '@walletconnect/jsonrpc-provider': 1.0.13 - '@walletconnect/jsonrpc-types': 1.0.3 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/sign-client': 2.7.2 - '@walletconnect/types': 2.7.2 - '@walletconnect/universal-provider': 2.7.2 - '@walletconnect/utils': 2.7.2 - '@web3modal/standalone': 2.4.3(react@18.2.0) - events: 3.3.0 - transitivePeerDependencies: - - '@react-native-async-storage/async-storage' - - bufferutil - - debug - - encoding - - lokijs - - utf-8-validate - /@walletconnect/events@1.0.1: resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} dependencies: keyvaluestorage-interface: 1.0.0 tslib: 1.14.1 + dev: true /@walletconnect/heartbeat@1.2.1: resolution: {integrity: sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q==} @@ -4874,6 +6511,7 @@ packages: '@walletconnect/events': 1.0.1 '@walletconnect/time': 1.0.2 tslib: 1.14.1 + dev: true /@walletconnect/jsonrpc-http-connection@1.0.7: resolution: {integrity: sha512-qlfh8fCfu8LOM9JRR9KE0s0wxP6ZG9/Jom8M0qsoIQeKF3Ni0FyV4V1qy/cc7nfI46SLQLSl4tgWSfLiE1swyQ==} @@ -4884,6 +6522,7 @@ packages: tslib: 1.14.1 transitivePeerDependencies: - encoding + dev: true /@walletconnect/jsonrpc-provider@1.0.13: resolution: {integrity: sha512-K73EpThqHnSR26gOyNEL+acEex3P7VWZe6KE12ZwKzAt2H4e5gldZHbjsu2QR9cLeJ8AXuO7kEMOIcRv1QEc7g==} @@ -4891,12 +6530,14 @@ packages: '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/safe-json': 1.0.2 tslib: 1.14.1 + dev: true /@walletconnect/jsonrpc-types@1.0.3: resolution: {integrity: sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw==} dependencies: keyvaluestorage-interface: 1.0.0 tslib: 1.14.1 + dev: true /@walletconnect/jsonrpc-utils@1.0.8: resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} @@ -4904,90 +6545,52 @@ packages: '@walletconnect/environment': 1.0.1 '@walletconnect/jsonrpc-types': 1.0.3 tslib: 1.14.1 + dev: true - /@walletconnect/jsonrpc-ws-connection@1.0.13: - resolution: {integrity: sha512-mfOM7uFH4lGtQxG+XklYuFBj6dwVvseTt5/ahOkkmpcAEgz2umuzu7fTR+h5EmjQBdrmYyEBOWADbeaFNxdySg==} + /@walletconnect/jsonrpc-ws-connection@1.0.14: + resolution: {integrity: sha512-Jsl6fC55AYcbkNVkwNM6Jo+ufsuCQRqViOQ8ZBPH9pRREHH9welbBiszuTLqEJiQcO/6XfFDl6bzCJIkrEi8XA==} dependencies: '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/safe-json': 1.0.2 events: 3.3.0 - tslib: 1.14.1 ws: 7.5.9 transitivePeerDependencies: - bufferutil - utf-8-validate + dev: true - /@walletconnect/keyvaluestorage@1.0.2: - resolution: {integrity: sha512-U/nNG+VLWoPFdwwKx0oliT4ziKQCEoQ27L5Hhw8YOFGA2Po9A9pULUYNWhDgHkrb0gYDNt//X7wABcEWWBd3FQ==} + /@walletconnect/keyvaluestorage@1.1.1: + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} peerDependencies: '@react-native-async-storage/async-storage': 1.x - lokijs: 1.x peerDependenciesMeta: '@react-native-async-storage/async-storage': optional: true - lokijs: - optional: true - dependencies: - safe-json-utils: 1.1.1 - tslib: 1.14.1 - - /@walletconnect/legacy-client@2.0.0: - resolution: {integrity: sha512-v5L7rYk9loVnfvUf0mF+76bUPFaU5/Vh7mzL6/950CD/yoGdzYZ3Kj+L7mkC6HPMEGeQsBP1+sqBuiVGZ/aODA==} dependencies: - '@walletconnect/crypto': 1.0.3 - '@walletconnect/encoding': 1.0.2 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/legacy-types': 2.0.0 - '@walletconnect/legacy-utils': 2.0.0 '@walletconnect/safe-json': 1.0.2 - '@walletconnect/window-getters': 1.0.1 - '@walletconnect/window-metadata': 1.0.1 - detect-browser: 5.3.0 - query-string: 6.14.1 - - /@walletconnect/legacy-modal@2.0.0: - resolution: {integrity: sha512-jckNd8lMhm4X7dX9TDdxM3bXKJnaqkRs6K2Mo5j6GmbIF9Eyx40jZ5+q457RVxvM6ciZEDT5s1wBHWdWoOo+9Q==} - dependencies: - '@walletconnect/legacy-types': 2.0.0 - '@walletconnect/legacy-utils': 2.0.0 - copy-to-clipboard: 3.3.3 - preact: 10.16.0 - qrcode: 1.5.3 - - /@walletconnect/legacy-provider@2.0.0: - resolution: {integrity: sha512-A8xPebMI1A+50HbWwTpFCbwP7G+1NGKdTKyg8BUUg3h3Y9JucpC1W6w/x0v1Xw7qFEqQnz74LoIN/A3ytH9xrQ==} - dependencies: - '@walletconnect/jsonrpc-http-connection': 1.0.7 - '@walletconnect/jsonrpc-provider': 1.0.13 - '@walletconnect/legacy-client': 2.0.0 - '@walletconnect/legacy-modal': 2.0.0 - '@walletconnect/legacy-types': 2.0.0 - '@walletconnect/legacy-utils': 2.0.0 + idb-keyval: 6.2.1 + unstorage: 1.10.1(idb-keyval@6.2.1) transitivePeerDependencies: - - encoding - - /@walletconnect/legacy-types@2.0.0: - resolution: {integrity: sha512-sOVrA7HUdbI1OwKyPOQU0/DdvTSVFlsXWpAk2K2WvP2erTkBWPMTJq6cv2BmKdoJ3p6gLApT7sd+jHi3OF71uw==} - dependencies: - '@walletconnect/jsonrpc-types': 1.0.3 - - /@walletconnect/legacy-utils@2.0.0: - resolution: {integrity: sha512-CPWxSVVXw0kgNCxvU126g4GiV3mzXmC8IPJ15twE46aJ1FX+RHEIfAzFMFz2F2+fEhBxL63A7dwNQKDXorRPcQ==} - dependencies: - '@walletconnect/encoding': 1.0.2 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/legacy-types': 2.0.0 - '@walletconnect/safe-json': 1.0.2 - '@walletconnect/window-getters': 1.0.1 - '@walletconnect/window-metadata': 1.0.1 - detect-browser: 5.3.0 - query-string: 6.14.1 + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/kv' + - supports-color + dev: true /@walletconnect/logger@2.0.1: resolution: {integrity: sha512-SsTKdsgWm+oDTBeNE/zHxxr5eJfZmE9/5yp/Ku+zJtcTAjELb3DXueWkDXmE9h8uHIbJzIb5wj5lPdzyrjT6hQ==} dependencies: pino: 7.11.0 tslib: 1.14.1 + dev: true /@walletconnect/modal-core@2.6.2(react@18.2.0): resolution: {integrity: sha512-cv8ibvdOJQv2B+nyxP9IIFdxvQznMz8OOr/oR/AaUZym4hjXNL/l1a2UlSQBXrVjo3xxbouMxLb3kBsHoYP2CA==} @@ -5020,19 +6623,12 @@ packages: - react dev: true - /@walletconnect/randombytes@1.0.3: - resolution: {integrity: sha512-35lpzxcHFbTN3ABefC9W+uBpNZl1GC4Wpx0ed30gibfO/y9oLdy1NznbV96HARQKSBV9J9M/rrtIvf6a23jfYw==} - dependencies: - '@walletconnect/encoding': 1.0.2 - '@walletconnect/environment': 1.0.1 - randombytes: 2.1.0 - tslib: 1.14.1 - /@walletconnect/relay-api@1.0.9: resolution: {integrity: sha512-Q3+rylJOqRkO1D9Su0DPE3mmznbAalYapJ9qmzDgK28mYF9alcP3UwG/og5V7l7CFOqzCLi7B8BvcBUrpDj0Rg==} dependencies: '@walletconnect/jsonrpc-types': 1.0.3 tslib: 1.14.1 + dev: true /@walletconnect/relay-auth@1.0.4: resolution: {integrity: sha512-kKJcS6+WxYq5kshpPaxGHdwf5y98ZwbfuS4EE/NkQzqrDFm5Cj+dP8LofzWvjrrLkZq7Afy7WrQMXdLy8Sx7HQ==} @@ -5043,203 +6639,152 @@ packages: '@walletconnect/time': 1.0.2 tslib: 1.14.1 uint8arrays: 3.1.1 + dev: true /@walletconnect/safe-json@1.0.2: resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} dependencies: tslib: 1.14.1 - - /@walletconnect/sign-client@2.10.2: - resolution: {integrity: sha512-vviSLV3f92I0bReX+OLr1HmbH0uIzYEQQFd1MzIfDk9PkfFT/LLAHhUnDaIAMkIdippqDcJia+5QEtT4JihL3Q==} - dependencies: - '@walletconnect/core': 2.10.2 - '@walletconnect/events': 1.0.1 - '@walletconnect/heartbeat': 1.2.1 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/logger': 2.0.1 - '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.10.2 - '@walletconnect/utils': 2.10.2 - events: 3.3.0 - transitivePeerDependencies: - - '@react-native-async-storage/async-storage' - - bufferutil - - lokijs - - utf-8-validate dev: true - /@walletconnect/sign-client@2.7.2: - resolution: {integrity: sha512-JOYPmrgR4YG4M2comNcXaa8cLIws0ZJj/SCpF0XJzRZP2+OXWouK19UaI32ROQrcwNodBNeYFRfT5hSM5xjfKg==} + /@walletconnect/sign-client@2.11.0: + resolution: {integrity: sha512-H2ukscibBS+6WrzQWh+WyVBqO5z4F5et12JcwobdwgHnJSlqIoZxqnUYYWNCI5rUR5UKsKWaUyto4AE9N5dw4Q==} dependencies: - '@walletconnect/core': 2.7.2 + '@walletconnect/core': 2.11.0 '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.1 '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/logger': 2.0.1 '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.7.2 - '@walletconnect/utils': 2.7.2 + '@walletconnect/types': 2.11.0 + '@walletconnect/utils': 2.11.0 events: 3.3.0 transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' - bufferutil - - lokijs + - encoding + - supports-color - utf-8-validate + dev: true /@walletconnect/time@1.0.2: resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} dependencies: tslib: 1.14.1 - - /@walletconnect/types@2.10.2: - resolution: {integrity: sha512-luNV+07Wdla4STi9AejseCQY31tzWKQ5a7C3zZZaRK/di+rFaAAb7YW04OP4klE7tw/mJRGPTlekZElmHxO8kQ==} - dependencies: - '@walletconnect/events': 1.0.1 - '@walletconnect/heartbeat': 1.2.1 - '@walletconnect/jsonrpc-types': 1.0.3 - '@walletconnect/keyvaluestorage': 1.0.2 - '@walletconnect/logger': 2.0.1 - events: 3.3.0 - transitivePeerDependencies: - - '@react-native-async-storage/async-storage' - - lokijs dev: true - /@walletconnect/types@2.7.2: - resolution: {integrity: sha512-1O2UefakZpT0ErRfEAXY7Ls3qdUrKDky/DsK088xR6klyfkQOx+aSVH0fJYLhmnqPTuvp3lrqNbsDc0s6/6nvg==} + /@walletconnect/types@2.11.0: + resolution: {integrity: sha512-AB5b1lrEbCGHxqS2vqfCkIoODieH+ZAUp9rA1O2ftrhnqDJiJK983Df87JhYhECsQUBHHfALphA8ydER0q+9sw==} dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.1 '@walletconnect/jsonrpc-types': 1.0.3 - '@walletconnect/keyvaluestorage': 1.0.2 - '@walletconnect/logger': 2.0.1 - events: 3.3.0 - transitivePeerDependencies: - - '@react-native-async-storage/async-storage' - - lokijs - - /@walletconnect/universal-provider@2.10.2: - resolution: {integrity: sha512-wFgI0LbQ3D56sgaUMsgOHCM5m8WLxiC71BGuCKQfApgsbNMVKugYVy2zWHyUyi8sqTQHI+uSaVpDev4UHq9LEw==} - dependencies: - '@walletconnect/jsonrpc-http-connection': 1.0.7 - '@walletconnect/jsonrpc-provider': 1.0.13 - '@walletconnect/jsonrpc-types': 1.0.3 - '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1 '@walletconnect/logger': 2.0.1 - '@walletconnect/sign-client': 2.10.2 - '@walletconnect/types': 2.10.2 - '@walletconnect/utils': 2.10.2 events: 3.3.0 transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' - '@react-native-async-storage/async-storage' - - bufferutil - - encoding - - lokijs - - utf-8-validate + - '@upstash/redis' + - '@vercel/kv' + - supports-color dev: true - /@walletconnect/universal-provider@2.7.2: - resolution: {integrity: sha512-5glu7vCmq3SFUYgniICf7CUZMwrd6FNS/qnCjrnfgW8T55Opms9YkhRpWTJFHpBdNRWF7n6z/Kss2J8olKTxKw==} + /@walletconnect/universal-provider@2.11.0: + resolution: {integrity: sha512-zgJv8jDvIMP4Qse/D9oIRXGdfoNqonsrjPZanQ/CHNe7oXGOBiQND2IIeX+tS0H7uNA0TPvctljCLiIN9nw4eA==} dependencies: '@walletconnect/jsonrpc-http-connection': 1.0.7 '@walletconnect/jsonrpc-provider': 1.0.13 '@walletconnect/jsonrpc-types': 1.0.3 '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/logger': 2.0.1 - '@walletconnect/sign-client': 2.7.2 - '@walletconnect/types': 2.7.2 - '@walletconnect/utils': 2.7.2 - eip1193-provider: 1.0.1 + '@walletconnect/sign-client': 2.11.0 + '@walletconnect/types': 2.11.0 + '@walletconnect/utils': 2.11.0 events: 3.3.0 transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' - bufferutil - - debug - encoding - - lokijs + - supports-color - utf-8-validate - - /@walletconnect/utils@2.10.2: - resolution: {integrity: sha512-syxXRpc2yhSknMu3IfiBGobxOY7fLfLTJuw+ppKaeO6WUdZpIit3wfuGOcc0Ms3ZPFCrGfyGOoZsCvgdXtptRg==} - dependencies: - '@stablelib/chacha20poly1305': 1.0.1 - '@stablelib/hkdf': 1.0.1 - '@stablelib/random': 1.0.2 - '@stablelib/sha256': 1.0.1 - '@stablelib/x25519': 1.0.3 - '@walletconnect/relay-api': 1.0.9 - '@walletconnect/safe-json': 1.0.2 - '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.10.2 - '@walletconnect/window-getters': 1.0.1 - '@walletconnect/window-metadata': 1.0.1 - detect-browser: 5.3.0 - query-string: 7.1.3 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - '@react-native-async-storage/async-storage' - - lokijs dev: true - /@walletconnect/utils@2.7.2: - resolution: {integrity: sha512-b2lU/JoWqwCOLMudPSRTt3pliBnv6qQHCBWiMBYi1vL14AW3usO5QmK1wF90AVwpdPJ7wFZ6MgHymeWWfhYnGQ==} + /@walletconnect/utils@2.11.0: + resolution: {integrity: sha512-hxkHPlTlDQILHfIKXlmzgNJau/YcSBC3XHUSuZuKZbNEw3duFT6h6pm3HT/1+j1a22IG05WDsNBuTCRkwss+BQ==} dependencies: '@stablelib/chacha20poly1305': 1.0.1 '@stablelib/hkdf': 1.0.1 '@stablelib/random': 1.0.2 '@stablelib/sha256': 1.0.1 '@stablelib/x25519': 1.0.3 - '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/relay-api': 1.0.9 '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.7.2 + '@walletconnect/types': 2.11.0 '@walletconnect/window-getters': 1.0.1 '@walletconnect/window-metadata': 1.0.1 detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: 3.1.1 transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' - '@react-native-async-storage/async-storage' - - lokijs + - '@upstash/redis' + - '@vercel/kv' + - supports-color + dev: true /@walletconnect/window-getters@1.0.1: resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} dependencies: tslib: 1.14.1 + dev: true /@walletconnect/window-metadata@1.0.1: resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} dependencies: '@walletconnect/window-getters': 1.0.1 tslib: 1.14.1 - - /@web3modal/core@2.4.3(react@18.2.0): - resolution: {integrity: sha512-7Z/sDe9RIYQ2k9ITcxgEa/u7FvlI76vcVVZn9UY4ISivefqrH4JAS3GX4JmVNUUlovwuiZdyqBv4llAQOMK6Rg==} - dependencies: - buffer: 6.0.3 - valtio: 1.10.5(react@18.2.0) - transitivePeerDependencies: - - react - - /@web3modal/standalone@2.4.3(react@18.2.0): - resolution: {integrity: sha512-5ATXBoa4GGm+TIUSsKWsfWCJunv1XevOizpgTFhqyeGgRDmWhqsz9UIPzH/1mk+g0iJ/xqMKs5F6v9D2QeKxag==} - deprecated: This package has been deprecated in favor of @walletconnect/modal. Please read more at https://docs.walletconnect.com - dependencies: - '@web3modal/core': 2.4.3(react@18.2.0) - '@web3modal/ui': 2.4.3(react@18.2.0) - transitivePeerDependencies: - - react - - /@web3modal/ui@2.4.3(react@18.2.0): - resolution: {integrity: sha512-J989p8CdtEhI9gZHf/rZ/WFqYlrAHWw9GmAhFoiNODwjAp0BoG/uoaPiijJMchXdngihZOjLGCQwDXU16DHiKg==} - dependencies: - '@web3modal/core': 2.4.3(react@18.2.0) - lit: 2.7.5 - motion: 10.16.2 - qrcode: 1.5.3 - transitivePeerDependencies: - - react + dev: true /@yarnpkg/lockfile@1.1.0: resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} @@ -5260,83 +6805,48 @@ packages: argparse: 2.0.1 dev: true - /JSONStream@1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} - hasBin: true - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 - - /abab@2.0.6: - resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} - dev: true - - /abitype@0.10.1(typescript@5.2.2): - resolution: {integrity: sha512-nFx5F2RniXGXw2Ci1uu6iDGnP/z3hW+H65G7cxrs5JDF3Ot9GuYkBJCRAB9EZ5QIi3dNByZaCrGFUn8LLkLQbw==} + /abitype@0.9.8(typescript@5.3.3)(zod@3.22.4): + resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} peerDependencies: typescript: '>=5.0.4' - zod: ^3 >=3.22.0 - peerDependenciesMeta: - typescript: - optional: true - zod: - optional: true - dependencies: - typescript: 5.2.2 - dev: true - - /abitype@0.8.1(typescript@5.2.2): - resolution: {integrity: sha512-n8Di6AWb3i7HnEkBvecU6pG0a5nj5YwMvdAIwPLsQK95ulRy/XS113s/RXvSfTX1iOQJYFrEO3/q4SMWu7OwTA==} - peerDependencies: - typescript: '>=4.9.4' zod: ^3 >=3.19.1 peerDependenciesMeta: - zod: + typescript: optional: true - dependencies: - typescript: 5.2.2 - - /abitype@0.8.7(typescript@5.2.2)(zod@3.22.3): - resolution: {integrity: sha512-wQ7hV8Yg/yKmGyFpqrNZufCxbszDe5es4AZGYPBitocfSqXtjrTG9JMWFcc4N30ukl2ve48aBTwt7NJxVQdU3w==} - peerDependencies: - typescript: '>=5.0.4' - zod: ^3 >=3.19.1 - peerDependenciesMeta: zod: optional: true dependencies: - typescript: 5.2.2 - zod: 3.22.3 + typescript: 5.3.3 + zod: 3.22.4 dev: true - /abitype@0.9.8(typescript@5.2.2)(zod@3.22.3): - resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} + /abitype@1.0.0(typescript@5.3.3)(zod@3.22.4): + resolution: {integrity: sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==} peerDependencies: typescript: '>=5.0.4' - zod: ^3 >=3.19.1 + zod: ^3 >=3.22.0 peerDependenciesMeta: typescript: optional: true zod: optional: true dependencies: - typescript: 5.2.2 - zod: 3.22.3 - dev: true + typescript: 5.3.3 + zod: 3.22.4 - /abitype@0.9.8(typescript@5.2.2)(zod@3.22.4): - resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} + /abitype@1.0.2(typescript@5.3.3): + resolution: {integrity: sha512-aFt4k2H+eiAKy/zxtnORa9iIb10BMBeWL18l8v4+QuwYEBXPxxjSB1bFZCzQmKPoj8m7j68K705l3uY+E2gAjg==} peerDependencies: typescript: '>=5.0.4' - zod: ^3 >=3.19.1 + zod: ^3 >=3.22.0 peerDependenciesMeta: typescript: optional: true zod: optional: true dependencies: - typescript: 5.2.2 - zod: 3.22.4 + typescript: 5.3.3 + dev: true /abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} @@ -5344,19 +6854,6 @@ packages: dependencies: event-target-shim: 5.0.1 - /abstract-level@1.0.3: - resolution: {integrity: sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==} - engines: {node: '>=12'} - dependencies: - buffer: 6.0.3 - catering: 2.1.1 - is-buffer: 2.0.5 - level-supports: 4.0.1 - level-transcoder: 1.0.1 - module-error: 1.0.2 - queue-microtask: 1.2.3 - dev: true - /abstract-leveldown@6.2.3: resolution: {integrity: sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==} engines: {node: '>=6'} @@ -5397,7 +6894,6 @@ packages: dependencies: mime-types: 2.1.35 negotiator: 0.6.3 - dev: false /acorn-jsx@5.3.2(acorn@8.10.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -5407,8 +6903,13 @@ packages: acorn: 8.10.0 dev: true - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + /acorn-walk@8.3.0: + resolution: {integrity: sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} dev: true @@ -5426,9 +6927,6 @@ packages: /aes-js@3.0.0: resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} - /aes-js@3.1.2: - resolution: {integrity: sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==} - /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -5436,16 +6934,16 @@ packages: debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color + dev: true - /agentkeepalive@4.3.0: - resolution: {integrity: sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==} - engines: {node: '>= 8.0.0'} + /agent-base@7.1.0: + resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} + engines: {node: '>= 14'} dependencies: debug: 4.3.4(supports-color@8.1.1) - depd: 2.0.0 - humanize-ms: 1.2.1 transitivePeerDependencies: - supports-color + dev: true /aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} @@ -5462,6 +6960,7 @@ packages: fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 + dev: true /anchor-markdown-header@0.6.0: resolution: {integrity: sha512-v7HJMtE1X7wTpNFseRhxsY/pivP4uAJbidVhPT+yhz4i/vV1+qx371IXuV9V7bN6KjFtheLJxqaSm0Y/8neJTA==} @@ -5469,6 +6968,16 @@ packages: emoji-regex: 10.1.0 dev: true + /anser@1.4.10: + resolution: {integrity: sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==} + dev: true + + /ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + dependencies: + string-width: 4.2.3 + dev: true + /ansi-colors@4.1.1: resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} engines: {node: '>=6'} @@ -5478,11 +6987,6 @@ packages: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} - /ansi-escapes@3.2.0: - resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} - engines: {node: '>=4'} - dev: false - /ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -5490,11 +6994,19 @@ packages: type-fest: 0.21.3 dev: true - /ansi-escapes@5.0.0: - resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} - engines: {node: '>=12'} + /ansi-escapes@6.2.0: + resolution: {integrity: sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==} + engines: {node: '>=14.16'} dependencies: - type-fest: 1.4.0 + type-fest: 3.13.1 + dev: true + + /ansi-fragments@0.2.1: + resolution: {integrity: sha512-DykbNHxuXQwUDRv5ibc2b0x7uw7wmwOGLBUd5RmaQ5z8Lhx19vwvKV+FAsM5rEA6dEcHxX+/Ad5s9eF2k2bB+w==} + dependencies: + colorette: 1.4.0 + slice-ansi: 2.1.0 + strip-ansi: 5.2.0 dev: true /ansi-regex@2.1.1: @@ -5502,6 +7014,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + dev: true + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -5536,14 +7053,6 @@ packages: engines: {node: '>=12'} dev: true - /ansicolors@0.3.2: - resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} - dev: false - - /antlr4ts@0.5.0-alpha.4: - resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==} - dev: true - /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} dev: true @@ -5556,6 +7065,10 @@ packages: picomatch: 2.3.1 dev: true + /appdirsjs@1.2.7: + resolution: {integrity: sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw==} + dev: true + /append-transform@2.0.0: resolution: {integrity: sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==} engines: {node: '>=8'} @@ -5563,12 +7076,22 @@ packages: default-require-extensions: 3.0.0 dev: true + /arch@2.2.0: + resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} + dev: true + /archy@1.0.0: resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} dev: true + /are-docs-informative@0.0.2: + resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} + engines: {node: '>=14'} + dev: true + /arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -5642,11 +7165,6 @@ packages: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - /array-union@3.0.1: - resolution: {integrity: sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==} - engines: {node: '>=12'} - dev: true - /array.prototype.findlastindex@1.2.3: resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==} engines: {node: '>= 0.4'} @@ -5658,16 +7176,6 @@ packages: get-intrinsic: 1.2.1 dev: true - /array.prototype.flat@1.3.1: - resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 - es-shim-unscopables: 1.0.0 - dev: false - /array.prototype.flat@1.3.2: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} engines: {node: '>= 0.4'} @@ -5676,7 +7184,6 @@ packages: define-properties: 1.2.0 es-abstract: 1.22.1 es-shim-unscopables: 1.0.0 - dev: true /array.prototype.flatmap@1.3.1: resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} @@ -5730,29 +7237,49 @@ packages: /asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + dev: true /asn1@0.2.4: resolution: {integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==} dependencies: safer-buffer: 2.1.2 + dev: true /assert-plus@1.0.0: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} + dev: true /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + /ast-types@0.15.2: + resolution: {integrity: sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==} + engines: {node: '>=4'} + dependencies: + tslib: 2.6.2 + dev: true + + /astral-regex@1.0.0: + resolution: {integrity: sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==} + engines: {node: '>=4'} + dev: true + /async-eventemitter@0.2.4: resolution: {integrity: sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==} dependencies: async: 2.6.4 dev: true + /async-limiter@1.0.1: + resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + dev: true + /async-mutex@0.2.6: resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==} dependencies: tslib: 2.6.2 + dev: true /async@2.6.4: resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} @@ -5768,10 +7295,6 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - /at-least-node@1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} dev: true /atomic-sleep@1.0.0: @@ -5784,48 +7307,153 @@ packages: /aws-sign2@0.7.0: resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + dev: true /aws4@1.11.0: resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} + dev: true /axios@0.21.4(debug@4.3.4): resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} dependencies: - follow-redirects: 1.15.2(debug@4.3.4) + follow-redirects: 1.15.5(debug@4.3.4) transitivePeerDependencies: - debug + dev: true /axios@1.1.3: resolution: {integrity: sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==} dependencies: - follow-redirects: 1.15.2(debug@4.3.4) + follow-redirects: 1.15.5(debug@4.3.4) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug dev: true - /axios@1.5.1: - resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} + /axios@1.6.7: + resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} dependencies: - follow-redirects: 1.15.2(debug@4.3.4) + follow-redirects: 1.15.5(debug@4.3.4) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug dev: true + /babel-core@7.0.0-bridge.0(@babel/core@7.22.10): + resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + dev: true + + /babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + dependencies: + '@babel/runtime': 7.23.7 + cosmiconfig: 7.1.0 + resolve: 1.22.4 + dev: true + + /babel-plugin-polyfill-corejs2@0.4.7(@babel/core@7.22.10): + resolution: {integrity: sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/core': 7.22.10 + '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.22.10) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3@0.8.7(@babel/core@7.22.10): + resolution: {integrity: sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.22.10) + core-js-compat: 3.35.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator@0.5.4(@babel/core@7.22.10): + resolution: {integrity: sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.22.10) + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-syntax-trailing-function-commas@7.0.0-beta.0: + resolution: {integrity: sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==} + dev: true + + /babel-plugin-transform-flow-enums@0.0.2(@babel/core@7.22.10): + resolution: {integrity: sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==} + dependencies: + '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.22.10) + transitivePeerDependencies: + - '@babel/core' + dev: true + + /babel-preset-fbjs@3.4.0(@babel/core@7.22.10): + resolution: {integrity: sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.10 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.22.10) + '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.22.10) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.10) + '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.10) + '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-classes': 7.23.5(@babel/core@7.22.10) + '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-flow-strip-types': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-for-of': 7.23.6(@babel/core@7.22.10) + '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-react-display-name': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.22.10) + '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.22.10) + '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.22.10) + babel-plugin-syntax-trailing-function-commas: 7.0.0-beta.0 + dev: true + /bail@1.0.5: resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} dev: true /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true /base-x@3.0.8: resolution: {integrity: sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==} dependencies: safe-buffer: 5.2.1 + dev: true /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -5848,6 +7476,7 @@ packages: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} dependencies: tweetnacl: 0.14.5 + dev: true /bech32@1.1.4: resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} @@ -5859,13 +7488,6 @@ packages: is-windows: 1.0.2 dev: false - /bigint-buffer@1.1.5: - resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} - engines: {node: '>= 10.0.0'} - requiresBuild: true - dependencies: - bindings: 1.5.0 - /bigint-crypto-utils@3.3.0: resolution: {integrity: sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg==} engines: {node: '>=14.0.0'} @@ -5879,14 +7501,6 @@ packages: engines: {node: '>=8'} dev: true - /bind-decorator@1.0.11: - resolution: {integrity: sha512-yzkH0uog6Vv/vQ9+rhSKxecnqGUZHYncg7qS7voz3Q76+TAi1SGiOKk2mlOvusQnFz9Dc4BC/NMkeXu11YgjJg==} - - /bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - dependencies: - file-uri-to-path: 1.0.0 - /bintrees@1.0.1: resolution: {integrity: sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==} dev: false @@ -5922,6 +7536,7 @@ packages: /bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + dev: true /bn.js@4.11.6: resolution: {integrity: sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==} @@ -5937,7 +7552,7 @@ packages: engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} dependencies: bytes: 3.1.2 - content-type: 1.0.4 + content-type: 1.0.5 debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 @@ -5972,18 +7587,30 @@ packages: - supports-color dev: false - /borsh@0.7.0: - resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + /bowser@2.11.0: + resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + dev: true + + /boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} dependencies: - bn.js: 5.2.1 - bs58: 4.0.1 - text-encoding-utf-8: 1.0.2 + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + dev: true /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 + dev: true /brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} @@ -6006,15 +7633,6 @@ packages: /brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - /browser-level@1.0.1: - resolution: {integrity: sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==} - dependencies: - abstract-level: 1.0.3 - catering: 2.1.1 - module-error: 1.0.2 - run-parallel-limit: 1.1.0 - dev: true - /browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} dev: true @@ -6030,21 +7648,22 @@ packages: safe-buffer: 5.2.1 dev: true - /browserslist@4.21.10: - resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} + /browserslist@4.22.2: + resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001520 - electron-to-chromium: 1.4.491 - node-releases: 2.0.13 - update-browserslist-db: 1.0.11(browserslist@4.21.10) + caniuse-lite: 1.0.30001574 + electron-to-chromium: 1.4.621 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.22.2) dev: true /bs58@4.0.1: resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} dependencies: base-x: 3.0.8 + dev: true /bs58check@2.1.2: resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} @@ -6054,6 +7673,12 @@ packages: safe-buffer: 5.2.1 dev: true + /bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + /bsert@0.0.10: resolution: {integrity: sha512-NHNwlac+WPy4t2LoNh8pXk8uaIGH3NSaIUbTTRXGpE2WEbq0te/tDykYHkFK57YKLPjv/aGHmbqvnGeVWDz57Q==} engines: {node: '>=8.0.0'} @@ -6061,6 +7686,7 @@ packages: /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true /buffer-reverse@1.0.1: resolution: {integrity: sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg==} @@ -6098,12 +7724,13 @@ packages: dev: true optional: true - /bufferutil@4.0.7: - resolution: {integrity: sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==} + /bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} engines: {node: '>=6.14.2'} requiresBuild: true dependencies: node-gyp-build: 4.6.0 + dev: true /bufio@1.2.0: resolution: {integrity: sha512-UlFk8z/PwdhYQTXSQQagwGAdtRI83gib2n4uy4rQnenxUM2yQi8lBDzF230BNk+3wAoZDxYRoBwVVUPgHa9MCA==} @@ -6115,23 +7742,23 @@ packages: engines: {node: '>=6'} dev: true - /bundle-require@3.1.2(esbuild@0.16.17): - resolution: {integrity: sha512-Of6l6JBAxiyQ5axFxUM6dYeP/W7X2Sozeo/4EYB9sJhL+dqL7TKjg+shwxp6jlu/6ZSERfsYtIpSJ1/x3XkAEA==} + /bundle-require@4.0.1(esbuild@0.19.7): + resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} peerDependencies: - esbuild: '>=0.13' + esbuild: '>=0.17' dependencies: - esbuild: 0.16.17 + esbuild: 0.19.7 load-tsconfig: 0.2.5 dev: true - /bundle-require@4.0.1(esbuild@0.18.15): - resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==} + /bundle-require@4.0.2(esbuild@0.19.10): + resolution: {integrity: sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} peerDependencies: esbuild: '>=0.17' dependencies: - esbuild: 0.18.15 + esbuild: 0.19.10 load-tsconfig: 0.2.5 dev: true @@ -6142,6 +7769,11 @@ packages: streamsearch: 1.1.0 dev: true + /bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + dev: true + /bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -6164,13 +7796,32 @@ packages: /call-bind@1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 get-intrinsic: 1.2.1 + /caller-callsite@2.0.0: + resolution: {integrity: sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==} + engines: {node: '>=4'} + dependencies: + callsites: 2.0.0 + dev: true + + /caller-path@2.0.0: + resolution: {integrity: sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==} + engines: {node: '>=4'} + dependencies: + caller-callsite: 2.0.0 + dev: true + /callsite@1.0.0: resolution: {integrity: sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==} dev: true + /callsites@2.0.0: + resolution: {integrity: sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==} + engines: {node: '>=4'} + dev: true + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -6205,8 +7856,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite@1.0.30001520: - resolution: {integrity: sha512-tahF5O9EiiTzwTUqAeFjIZbn4Dnqxzz7ktrgGlMYNLH43Ul26IgTMH/zvL3DG0lZxBYnlT04axvInszUsZULdA==} + /caniuse-lite@1.0.30001574: + resolution: {integrity: sha512-BtYEK4r/iHt/txm81KBudCUcTy7t+s9emrIaHqjYurQ10x71zJ5VQ9x1dYPcz/b+pKSp4y/v1xSI67A+LzpNyg==} dev: true /capital-case@1.0.4: @@ -6216,21 +7867,9 @@ packages: tslib: 2.6.2 upper-case-first: 2.0.2 - /cardinal@2.1.1: - resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} - hasBin: true - dependencies: - ansicolors: 0.3.2 - redeyed: 2.1.1 - dev: false - - /case@1.6.3: - resolution: {integrity: sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==} - engines: {node: '>= 0.8.0'} - dev: true - /caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + dev: true /catering@2.1.1: resolution: {integrity: sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==} @@ -6257,22 +7896,9 @@ packages: check-error: 1.0.3 deep-eql: 4.1.3 get-func-name: 2.0.2 - loupe: 2.3.6 - pathval: 1.1.1 - type-detect: 4.0.8 - - /chai@4.3.9: - resolution: {integrity: sha512-tH8vhfA1CfuYMkALXj+wmZcqiwqOfshU9Gry+NYiiLqIddrobkBhALv6XD4yDz68qapphYI4vSaqhqAdThCAAA==} - engines: {node: '>=4'} - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.3 - get-func-name: 2.0.2 - loupe: 2.3.6 + loupe: 2.3.7 pathval: 1.1.1 type-detect: 4.0.8 - dev: true /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -6362,6 +7988,32 @@ packages: engines: {node: '>=10'} dev: true + /chrome-launcher@0.15.2: + resolution: {integrity: sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==} + engines: {node: '>=12.13.0'} + hasBin: true + dependencies: + '@types/node': 20.11.17 + escape-string-regexp: 4.0.0 + is-wsl: 2.2.0 + lighthouse-logger: 1.4.2 + transitivePeerDependencies: + - supports-color + dev: true + + /chromium-edge-launcher@1.0.0: + resolution: {integrity: sha512-pgtgjNKZ7i5U++1g1PWv75umkHvhVTDOQIZ+sjeUX9483S7Y6MUvO0lrd7ShGlQlFHMN4SwKTCq/X8hWrbv2KA==} + dependencies: + '@types/node': 20.11.17 + escape-string-regexp: 4.0.0 + is-wsl: 2.2.0 + lighthouse-logger: 1.4.2 + mkdirp: 1.0.4 + rimraf: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + /ci-info@2.0.0: resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} dev: true @@ -6370,6 +8022,11 @@ packages: resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} engines: {node: '>=8'} + /ci-info@4.0.0: + resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} + engines: {node: '>=8'} + dev: true + /cipher-base@1.0.4: resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} dependencies: @@ -6377,16 +8034,10 @@ packages: safe-buffer: 5.2.1 dev: true - /classic-level@1.3.0: - resolution: {integrity: sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==} - engines: {node: '>=12'} - requiresBuild: true + /citty@0.1.5: + resolution: {integrity: sha512-AS7n5NSc0OQVMV9v6wt3ByujNIrne0/cTjiC2MYqhvao57VNfiuVksTSr2p17nVOhEr2KtqiAkGwHcgMC/qUuQ==} dependencies: - abstract-level: 1.0.3 - catering: 2.1.1 - module-error: 1.0.2 - napi-macros: 2.2.2 - node-gyp-build: 4.6.0 + consola: 3.2.3 dev: true /clean-regexp@1.0.0: @@ -6401,6 +8052,11 @@ packages: engines: {node: '>=6'} dev: true + /cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + dev: true + /cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -6425,19 +8081,21 @@ packages: engines: {node: '>=6'} dev: true - /cli-table@0.3.6: - resolution: {integrity: sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==} - engines: {node: '>= 0.2.0'} + /cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} dependencies: - colors: 1.0.3 - dev: false + slice-ansi: 5.0.0 + string-width: 7.0.0 + dev: true - /cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + /clipboardy@3.0.0: + resolution: {integrity: sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: - slice-ansi: 5.0.0 - string-width: 5.1.2 + arch: 2.2.0 + execa: 5.1.1 + is-wsl: 2.2.0 dev: true /cliui@3.2.0: @@ -6471,6 +8129,15 @@ packages: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + /clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + dev: true + /clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} @@ -6478,6 +8145,12 @@ packages: /clsx@1.2.1: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} + dev: true + + /cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + dev: true /code-point-at@1.1.0: resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} @@ -6501,20 +8174,20 @@ packages: /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + /colorette@1.4.0: + resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} + dev: true + /colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} dev: true - /colors@1.0.3: - resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} - engines: {node: '>=0.1.90'} - dev: false - /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 + dev: true /command-exists@1.2.9: resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} @@ -6561,22 +8234,67 @@ packages: engines: {node: '>= 12'} dev: true - /comment-parser@1.1.6-beta.0: - resolution: {integrity: sha512-q3cA8TSMyqW7wcPSYWzbO/rMahnXgzs4SLG/UIWXdEsnXTFPZkEkWAdNgPiHig2OzxgpPLOh4WwsmClDxndwHw==} - engines: {node: '>= 10.0.0'} + /commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + dev: true + + /comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} + dev: true + + /commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + + /component-emitter@1.3.0: + resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + dev: true + + /compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /compression@1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.8 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + /connect@3.7.0: + resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} + engines: {node: '>= 0.10.0'} + dependencies: + debug: 2.6.9 + finalhandler: 1.1.2 + parseurl: 1.3.3 + utils-merge: 1.0.1 + transitivePeerDependencies: + - supports-color dev: true - /component-emitter@1.3.0: - resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + /consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} dev: true - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - /constant-case@3.0.4: resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} dependencies: @@ -6611,6 +8329,10 @@ packages: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} dev: true + /cookie-es@1.0.0: + resolution: {integrity: sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==} + dev: true + /cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} dev: false @@ -6630,10 +8352,11 @@ packages: requiresBuild: true dev: true - /copy-to-clipboard@3.3.3: - resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + /core-js-compat@3.35.0: + resolution: {integrity: sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==} dependencies: - toggle-selection: 1.0.6 + browserslist: 4.22.2 + dev: true /core-js-pure@3.16.2: resolution: {integrity: sha512-oxKe64UH049mJqrKkynWp6Vu0Rlm/BTXO/bJZuN2mmR3RtOFNepLlSWDd1eo16PzHpQAoNG97rLU1V/YxesJjw==} @@ -6643,6 +8366,17 @@ packages: /core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + dev: true + + /cosmiconfig@5.2.1: + resolution: {integrity: sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==} + engines: {node: '>=4'} + dependencies: + import-fresh: 2.0.0 + is-directory: 0.3.1 + js-yaml: 3.14.1 + parse-json: 4.0.0 + dev: true /cosmiconfig@7.1.0: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} @@ -6692,6 +8426,14 @@ packages: transitivePeerDependencies: - encoding + /cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + dependencies: + node-fetch: 2.6.12 + transitivePeerDependencies: + - encoding + dev: true + /cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} dependencies: @@ -6700,17 +8442,6 @@ packages: which: 1.3.1 dev: false - /cross-spawn@6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} - engines: {node: '>=4.8'} - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.2 - shebang-command: 1.2.0 - which: 1.3.1 - dev: false - /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -6720,24 +8451,23 @@ packages: which: 2.0.2 dev: true - /crypto-js@3.3.0: - resolution: {integrity: sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==} + /crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} dev: false /css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} dev: true - /cssstyle@3.0.0: - resolution: {integrity: sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==} - engines: {node: '>=14'} + /cssstyle@4.0.1: + resolution: {integrity: sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==} + engines: {node: '>=18'} dependencies: rrweb-cssom: 0.6.0 dev: true /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} - dev: false /csv-generate@3.4.3: resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} @@ -6766,29 +8496,35 @@ packages: engines: {node: '>=0.10'} dependencies: assert-plus: 1.0.0 - - /data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} dev: true - /data-urls@4.0.0: - resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==} - engines: {node: '>=14'} + /data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} dependencies: - abab: 2.0.6 - whatwg-mimetype: 3.0.0 - whatwg-url: 12.0.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.0.0 dev: true /dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} dev: true + /date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + dependencies: + '@babel/runtime': 7.23.7 + dev: true + /dateformat@4.5.1: resolution: {integrity: sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q==} dev: false + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: true + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -6821,6 +8557,7 @@ packages: dependencies: ms: 2.1.2 supports-color: 8.1.1 + dev: true /decamelize-keys@1.1.0: resolution: {integrity: sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==} @@ -6846,6 +8583,7 @@ packages: /decode-uri-component@0.2.2: resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} engines: {node: '>=0.10'} + dev: true /dedent@0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} @@ -6889,6 +8627,11 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + /default-require-extensions@3.0.0: resolution: {integrity: sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==} engines: {node: '>=8'} @@ -6921,13 +8664,23 @@ packages: has-property-descriptors: 1.0.0 object-keys: 1.1.1 - /delay@5.0.0: - resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} - engines: {node: '>=10'} + /defu@6.1.3: + resolution: {integrity: sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ==} + dev: true /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + dev: true + + /denodeify@1.2.1: + resolution: {integrity: sha512-KNTihKNmQENUZeKu5fzfpzRqR5S2VMp4gl9RFHiWzj9DfvYQPMJ6XHKNaQxaGCXwPk6y9yme3aUoaiAe+KX+vg==} + dev: true + + /denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + dev: true /depcheck@1.4.7: resolution: {integrity: sha512-1lklS/bV5chOxwNKA/2XUUk/hPORp8zihZsXflr8x0kLwmcZ9Y9BsS6Hs3ssvA+2wUVbG0U2Ciqvm1SokNjPkA==} @@ -6935,7 +8688,7 @@ packages: hasBin: true dependencies: '@babel/parser': 7.23.0 - '@babel/traverse': 7.23.2 + '@babel/traverse': 7.23.3 '@vue/compiler-sfc': 3.3.4 callsite: 1.0.0 camelcase: 6.3.0 @@ -6955,7 +8708,7 @@ packages: require-package-name: 2.0.1 resolve: 1.22.4 resolve-from: 5.0.0 - semver: 7.5.4 + semver: 7.6.0 yargs: 16.2.0 transitivePeerDependencies: - supports-color @@ -6965,6 +8718,15 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + /deprecated-react-native-prop-types@5.0.0: + resolution: {integrity: sha512-cIK8KYiiGVOFsKdPMmm1L3tA/Gl+JopXL6F5+C7x39MyPsQYnP57Im/D6bNUzcborD7fcMwiwZqcBdBXXZucYQ==} + engines: {node: '>=18'} + dependencies: + '@react-native/normalize-colors': 0.73.2 + invariant: 2.2.4 + prop-types: 15.8.1 + dev: true + /deps-regex@0.2.0: resolution: {integrity: sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==} dev: true @@ -6974,13 +8736,17 @@ packages: engines: {node: '>=6'} dev: true + /destr@2.0.2: + resolution: {integrity: sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg==} + dev: true + /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dev: false /detect-browser@5.3.0: resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + dev: true /detect-file@1.0.0: resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==} @@ -6992,11 +8758,10 @@ packages: engines: {node: '>=8'} dev: false - /detect-package-manager@2.0.1: - resolution: {integrity: sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==} - engines: {node: '>=12'} - dependencies: - execa: 5.1.1 + /detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true dev: true /dezalgo@1.0.4: @@ -7019,6 +8784,7 @@ packages: /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} + dev: true /diff@5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} @@ -7027,6 +8793,7 @@ packages: /dijkstrajs@1.0.3: resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + dev: true /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} @@ -7064,6 +8831,11 @@ packages: /dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dev: false + + /dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dev: true /dom-serializer@1.4.1: resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} @@ -7077,13 +8849,6 @@ packages: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} dev: true - /domexception@4.0.0: - resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} - engines: {node: '>=12'} - dependencies: - webidl-conversions: 7.0.0 - dev: true - /domhandler@4.3.1: resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} engines: {node: '>= 4'} @@ -7115,8 +8880,13 @@ packages: engines: {node: '>=10'} dev: true - /dotenv@16.3.1: - resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + /dotenv@16.3.2: + resolution: {integrity: sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==} + engines: {node: '>=12'} + dev: true + + /dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} /dotenv@8.6.0: @@ -7145,23 +8915,21 @@ packages: dependencies: jsbn: 0.1.1 safer-buffer: 2.1.2 + dev: true + + /eciesjs@0.3.18: + resolution: {integrity: sha512-RQhegEtLSyIiGJmFTZfvCTHER/fymipXFVx6OwSRYD6hOuy+6Kjpk0dGvIfP9kxn/smBpxQy71uxpGO406ITCw==} + dependencies: + '@types/secp256k1': 4.0.6 + futoin-hkdf: 1.5.3 + secp256k1: 5.0.0 + dev: true /ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - dev: false - - /eip1193-provider@1.0.1: - resolution: {integrity: sha512-kSuqwQ26d7CzuS/t3yRXo2Su2cVH0QfvyKbr2H7Be7O5YDyIq4hQGCNTo5wRdP07bt+E2R/8nPCzey4ojBHf7g==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - dependencies: - '@json-rpc-tools/provider': 1.7.6 - transitivePeerDependencies: - - bufferutil - - debug - - utf-8-validate - /electron-to-chromium@1.4.491: - resolution: {integrity: sha512-ZzPqGKghdVzlQJ+qpfE+r6EB321zed7e5JsvHIlMM4zPFF8okXUkF5Of7h7F3l3cltPL0rG7YVmlp5Qro7RQLA==} + /electron-to-chromium@1.4.621: + resolution: {integrity: sha512-MGJM6S0MuF/wTzM9NoItWXN56J1kolrHS/vzl/KlhXAbVkogTy0wzKYliQDJgNypxSCFjxdRhHYS3bffyYUGEw==} dev: true /elliptic@6.5.4: @@ -7184,6 +8952,10 @@ packages: resolution: {integrity: sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==} dev: true + /emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + dev: true + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -7193,11 +8965,11 @@ packages: /encode-utf8@1.0.3: resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + dev: true /encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} - dev: false /encoding-down@6.3.0: resolution: {integrity: sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==} @@ -7214,16 +8986,31 @@ packages: dependencies: once: 1.4.0 + /engine.io-client@6.5.3(bufferutil@4.0.8)(utf-8-validate@6.0.3): + resolution: {integrity: sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==} + dependencies: + '@socket.io/component-emitter': 3.1.0 + debug: 4.3.4(supports-color@8.1.1) + engine.io-parser: 5.2.1 + ws: 8.11.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) + xmlhttprequest-ssl: 2.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /engine.io-parser@5.2.1: + resolution: {integrity: sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==} + engines: {node: '>=10.0.0'} + dev: true + /enquirer@2.3.6: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} dependencies: ansi-colors: 4.1.3 - /entities@2.1.0: - resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} - dev: true - /entities@2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} dev: true @@ -7250,6 +9037,12 @@ packages: tslib: 2.6.2 dev: false + /envinfo@7.11.0: + resolution: {integrity: sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==} + engines: {node: '>=4'} + hasBin: true + dev: true + /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} hasBin: true @@ -7262,6 +9055,20 @@ packages: dependencies: is-arrayish: 0.2.1 + /error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + dependencies: + stackframe: 1.3.4 + dev: true + + /errorhandler@1.5.1: + resolution: {integrity: sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==} + engines: {node: '>= 0.8'} + dependencies: + accepts: 1.3.8 + escape-html: 1.0.3 + dev: true + /es-abstract@1.22.1: resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==} engines: {node: '>= 0.4'} @@ -7328,7 +9135,7 @@ packages: define-properties: 1.2.0 es-abstract: 1.22.1 es-set-tostringtag: 2.0.1 - function-bind: 1.1.1 + function-bind: 1.1.2 get-intrinsic: 1.2.1 globalthis: 1.0.3 has-property-descriptors: 1.0.0 @@ -7364,102 +9171,65 @@ packages: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} dev: true - /es6-promise@4.2.8: - resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} - - /es6-promisify@5.0.0: - resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} - dependencies: - es6-promise: 4.2.8 - - /esbuild@0.16.17: - resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.16.17 - '@esbuild/android-arm64': 0.16.17 - '@esbuild/android-x64': 0.16.17 - '@esbuild/darwin-arm64': 0.16.17 - '@esbuild/darwin-x64': 0.16.17 - '@esbuild/freebsd-arm64': 0.16.17 - '@esbuild/freebsd-x64': 0.16.17 - '@esbuild/linux-arm': 0.16.17 - '@esbuild/linux-arm64': 0.16.17 - '@esbuild/linux-ia32': 0.16.17 - '@esbuild/linux-loong64': 0.16.17 - '@esbuild/linux-mips64el': 0.16.17 - '@esbuild/linux-ppc64': 0.16.17 - '@esbuild/linux-riscv64': 0.16.17 - '@esbuild/linux-s390x': 0.16.17 - '@esbuild/linux-x64': 0.16.17 - '@esbuild/netbsd-x64': 0.16.17 - '@esbuild/openbsd-x64': 0.16.17 - '@esbuild/sunos-x64': 0.16.17 - '@esbuild/win32-arm64': 0.16.17 - '@esbuild/win32-ia32': 0.16.17 - '@esbuild/win32-x64': 0.16.17 - dev: true - - /esbuild@0.18.15: - resolution: {integrity: sha512-3WOOLhrvuTGPRzQPU6waSDWrDTnQriia72McWcn6UCi43GhCHrXH4S59hKMeez+IITmdUuUyvbU9JIp+t3xlPQ==} + /esbuild@0.19.10: + resolution: {integrity: sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.18.15 - '@esbuild/android-arm64': 0.18.15 - '@esbuild/android-x64': 0.18.15 - '@esbuild/darwin-arm64': 0.18.15 - '@esbuild/darwin-x64': 0.18.15 - '@esbuild/freebsd-arm64': 0.18.15 - '@esbuild/freebsd-x64': 0.18.15 - '@esbuild/linux-arm': 0.18.15 - '@esbuild/linux-arm64': 0.18.15 - '@esbuild/linux-ia32': 0.18.15 - '@esbuild/linux-loong64': 0.18.15 - '@esbuild/linux-mips64el': 0.18.15 - '@esbuild/linux-ppc64': 0.18.15 - '@esbuild/linux-riscv64': 0.18.15 - '@esbuild/linux-s390x': 0.18.15 - '@esbuild/linux-x64': 0.18.15 - '@esbuild/netbsd-x64': 0.18.15 - '@esbuild/openbsd-x64': 0.18.15 - '@esbuild/sunos-x64': 0.18.15 - '@esbuild/win32-arm64': 0.18.15 - '@esbuild/win32-ia32': 0.18.15 - '@esbuild/win32-x64': 0.18.15 - dev: true - - /esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + '@esbuild/aix-ppc64': 0.19.10 + '@esbuild/android-arm': 0.19.10 + '@esbuild/android-arm64': 0.19.10 + '@esbuild/android-x64': 0.19.10 + '@esbuild/darwin-arm64': 0.19.10 + '@esbuild/darwin-x64': 0.19.10 + '@esbuild/freebsd-arm64': 0.19.10 + '@esbuild/freebsd-x64': 0.19.10 + '@esbuild/linux-arm': 0.19.10 + '@esbuild/linux-arm64': 0.19.10 + '@esbuild/linux-ia32': 0.19.10 + '@esbuild/linux-loong64': 0.19.10 + '@esbuild/linux-mips64el': 0.19.10 + '@esbuild/linux-ppc64': 0.19.10 + '@esbuild/linux-riscv64': 0.19.10 + '@esbuild/linux-s390x': 0.19.10 + '@esbuild/linux-x64': 0.19.10 + '@esbuild/netbsd-x64': 0.19.10 + '@esbuild/openbsd-x64': 0.19.10 + '@esbuild/sunos-x64': 0.19.10 + '@esbuild/win32-arm64': 0.19.10 + '@esbuild/win32-ia32': 0.19.10 + '@esbuild/win32-x64': 0.19.10 + dev: true + + /esbuild@0.19.7: + resolution: {integrity: sha512-6brbTZVqxhqgbpqBR5MzErImcpA0SQdoKOkcWK/U30HtQxnokIpG3TX2r0IJqbFUzqLjhU/zC1S5ndgakObVCQ==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 + '@esbuild/android-arm': 0.19.7 + '@esbuild/android-arm64': 0.19.7 + '@esbuild/android-x64': 0.19.7 + '@esbuild/darwin-arm64': 0.19.7 + '@esbuild/darwin-x64': 0.19.7 + '@esbuild/freebsd-arm64': 0.19.7 + '@esbuild/freebsd-x64': 0.19.7 + '@esbuild/linux-arm': 0.19.7 + '@esbuild/linux-arm64': 0.19.7 + '@esbuild/linux-ia32': 0.19.7 + '@esbuild/linux-loong64': 0.19.7 + '@esbuild/linux-mips64el': 0.19.7 + '@esbuild/linux-ppc64': 0.19.7 + '@esbuild/linux-riscv64': 0.19.7 + '@esbuild/linux-s390x': 0.19.7 + '@esbuild/linux-x64': 0.19.7 + '@esbuild/netbsd-x64': 0.19.7 + '@esbuild/openbsd-x64': 0.19.7 + '@esbuild/sunos-x64': 0.19.7 + '@esbuild/win32-arm64': 0.19.7 + '@esbuild/win32-ia32': 0.19.7 + '@esbuild/win32-x64': 0.19.7 dev: true /escalade@3.1.1: @@ -7468,27 +9238,31 @@ packages: /escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - dev: false /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} dev: true - /eslint-config-prettier@8.3.0(eslint@8.52.0): - resolution: {integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==} + /eslint-config-prettier@9.1.0(eslint@8.56.0): + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.52.0 + eslint: 8.56.0 dev: true - /eslint-config-standard@16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.52.0): + /eslint-config-standard@16.0.3(eslint-plugin-import@2.29.1)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.56.0): resolution: {integrity: sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==} peerDependencies: eslint: ^7.12.1 @@ -7496,10 +9270,10 @@ packages: eslint-plugin-node: ^11.1.0 eslint-plugin-promise: ^4.2.1 || ^5.0.0 dependencies: - eslint: 8.52.0 - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0) - eslint-plugin-node: 11.1.0(eslint@8.52.0) - eslint-plugin-promise: 5.2.0(eslint@8.52.0) + eslint: 8.56.0 + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.56.0) + eslint-plugin-node: 11.1.0(eslint@8.56.0) + eslint-plugin-promise: 5.2.0(eslint@8.56.0) dev: true /eslint-import-resolver-node@0.3.9: @@ -7512,7 +9286,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.9.0)(eslint-import-resolver-node@0.3.9)(eslint@8.52.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -7533,27 +9307,27 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.9.0(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) debug: 3.2.7 - eslint: 8.52.0 + eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-es@3.0.1(eslint@8.52.0): + /eslint-plugin-es@3.0.1(eslint@8.56.0): resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=4.19.1' dependencies: - eslint: 8.52.0 + eslint: 8.56.0 eslint-utils: 2.1.0 regexpp: 3.2.0 dev: true - /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0): - resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==} + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.56.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -7562,16 +9336,16 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.9.0(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.52.0 + eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.9.0)(eslint-import-resolver-node@0.3.9)(eslint@8.52.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -7580,41 +9354,41 @@ packages: object.groupby: 1.0.1 object.values: 1.1.7 semver: 6.3.1 - tsconfig-paths: 3.14.2 + tsconfig-paths: 3.15.0 transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color dev: true - /eslint-plugin-jsdoc@35.5.1(eslint@8.52.0): - resolution: {integrity: sha512-pPYPWtsykwVEue1tYEyoppBj4dgF7XicF67tLLLraY6RQYBq7qMKjUHji19+hfiTtYKKBD0YfeK8hgjPAE5viw==} - engines: {node: '>=12'} + /eslint-plugin-jsdoc@48.0.6(eslint@8.56.0): + resolution: {integrity: sha512-LgwXOX6TWxxFYcbdVe+BJ94Kl/pgjSPYHLzqEdAMXTA1BH9WDx7iJ+9/iDajPF64LtzWX8C1mCfpbMZjJGhAOw==} + engines: {node: '>=18'} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 dependencies: - '@es-joy/jsdoccomment': 0.9.0-alpha.1 - comment-parser: 1.1.6-beta.0 + '@es-joy/jsdoccomment': 0.42.0 + are-docs-informative: 0.0.2 + comment-parser: 1.4.1 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.52.0 - esquery: 1.4.0 - jsdoc-type-pratt-parser: 1.1.1 - lodash: 4.17.21 - regextras: 0.8.0 - semver: 7.5.4 - spdx-expression-parse: 3.0.1 + escape-string-regexp: 4.0.0 + eslint: 8.56.0 + esquery: 1.5.0 + is-builtin-module: 3.2.1 + semver: 7.6.0 + spdx-expression-parse: 4.0.0 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-node@11.1.0(eslint@8.52.0): + /eslint-plugin-node@11.1.0(eslint@8.56.0): resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=5.16.0' dependencies: - eslint: 8.52.0 - eslint-plugin-es: 3.0.1(eslint@8.52.0) + eslint: 8.56.0 + eslint-plugin-es: 3.0.1(eslint@8.56.0) eslint-utils: 2.1.0 ignore: 5.2.4 minimatch: 3.1.2 @@ -7622,15 +9396,15 @@ packages: semver: 6.3.1 dev: true - /eslint-plugin-prefer-arrow@1.2.3(eslint@8.52.0): + /eslint-plugin-prefer-arrow@1.2.3(eslint@8.56.0): resolution: {integrity: sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==} peerDependencies: eslint: '>=2.0.0' dependencies: - eslint: 8.52.0 + eslint: 8.56.0 dev: true - /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.3.0)(eslint@8.52.0)(prettier@2.8.8): + /eslint-plugin-prettier@4.2.1(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@2.8.8): resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -7641,22 +9415,22 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.52.0 - eslint-config-prettier: 8.3.0(eslint@8.52.0) + eslint: 8.56.0 + eslint-config-prettier: 9.1.0(eslint@8.56.0) prettier: 2.8.8 prettier-linter-helpers: 1.0.0 dev: true - /eslint-plugin-promise@5.2.0(eslint@8.52.0): + /eslint-plugin-promise@5.2.0(eslint@8.56.0): resolution: {integrity: sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: eslint: ^7.0.0 dependencies: - eslint: 8.52.0 + eslint: 8.56.0 dev: true - /eslint-plugin-react@7.33.2(eslint@8.52.0): + /eslint-plugin-react@7.33.2(eslint@8.56.0): resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} engines: {node: '>=4'} peerDependencies: @@ -7667,7 +9441,7 @@ packages: array.prototype.tosorted: 1.1.1 doctrine: 2.1.0 es-iterator-helpers: 1.0.13 - eslint: 8.52.0 + eslint: 8.56.0 estraverse: 5.3.0 jsx-ast-utils: 3.2.0 minimatch: 3.1.2 @@ -7681,28 +9455,31 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-unicorn@48.0.1(eslint@8.52.0): - resolution: {integrity: sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==} + /eslint-plugin-unicorn@50.0.1(eslint@8.56.0): + resolution: {integrity: sha512-KxenCZxqSYW0GWHH18okDlOQcpezcitm5aOSz6EnobyJ6BIByiPDviQRjJIUAjG/tMN11958MxaQ+qCoU6lfDA==} engines: {node: '>=16'} peerDependencies: - eslint: '>=8.44.0' + eslint: '>=8.56.0' dependencies: - '@babel/helper-validator-identifier': 7.22.5 - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) - ci-info: 3.8.0 + '@babel/helper-validator-identifier': 7.22.20 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint/eslintrc': 2.1.4 + ci-info: 4.0.0 clean-regexp: 1.0.0 - eslint: 8.52.0 + core-js-compat: 3.35.0 + eslint: 8.56.0 esquery: 1.5.0 indent-string: 4.0.0 is-builtin-module: 3.2.1 jsesc: 3.0.2 - lodash: 4.17.21 pluralize: 8.0.0 read-pkg-up: 7.0.1 regexp-tree: 0.1.27 regjsparser: 0.10.0 - semver: 7.5.4 + semver: 7.6.0 strip-indent: 3.0.0 + transitivePeerDependencies: + - supports-color dev: true /eslint-scope@5.1.1: @@ -7743,15 +9520,15 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.52.0: - resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==} + /eslint@8.56.0: + resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@eslint-community/regexpp': 4.6.2 - '@eslint/eslintrc': 2.1.2 - '@eslint/js': 8.52.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.56.0 '@humanwhocodes/config-array': 0.11.13 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -7804,13 +9581,6 @@ packages: engines: {node: '>=4'} hasBin: true - /esquery@1.4.0: - resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} - engines: {node: '>=0.10'} - dependencies: - estraverse: 5.3.0 - dev: true - /esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} @@ -7839,6 +9609,12 @@ packages: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} dev: true + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.5 + dev: true + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -7847,18 +9623,19 @@ packages: /etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - dev: false - /eth-block-tracker@6.1.0: - resolution: {integrity: sha512-K9SY8+/xMBi4M5HHTDdxnpEqEEGjbNpzHFqvxyjMZej8InV/B+CkFRKM6W+uvrFJ7m8Zd1E0qUkseU3vdIDFYQ==} + /eth-block-tracker@7.1.0: + resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==} engines: {node: '>=14.0.0'} dependencies: - '@metamask/safe-event-emitter': 2.0.0 - '@metamask/utils': 3.6.0 + '@metamask/eth-json-rpc-provider': 1.0.1 + '@metamask/safe-event-emitter': 3.0.0 + '@metamask/utils': 5.0.2 json-rpc-random-id: 1.0.1 pify: 3.0.0 transitivePeerDependencies: - supports-color + dev: true /eth-ens-namehash@2.0.8: resolution: {integrity: sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==} @@ -7867,26 +9644,29 @@ packages: js-sha3: 0.5.7 dev: true - /eth-json-rpc-filters@5.1.0: - resolution: {integrity: sha512-fos+9xmoa1A2Ytsc9eYof17r81BjdJOUcGcgZn4K/tKdCCTb+a8ytEtwlu1op5qsXFDlgGmstTELFrDEc89qEQ==} + /eth-json-rpc-filters@6.0.1: + resolution: {integrity: sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==} engines: {node: '>=14.0.0'} dependencies: - '@metamask/safe-event-emitter': 2.0.0 + '@metamask/safe-event-emitter': 3.0.0 async-mutex: 0.2.6 eth-query: 2.1.2 json-rpc-engine: 6.1.0 pify: 5.0.0 + dev: true /eth-query@2.1.2: resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} dependencies: json-rpc-random-id: 1.0.1 xtend: 4.0.2 + dev: true - /eth-rpc-errors@4.0.2: - resolution: {integrity: sha512-n+Re6Gu8XGyfFy1it0AwbD1x0MUzspQs0D5UiPs1fFPCr6WAwZM+vbIhXheBFrpgosqN9bs5PqlB4Q61U/QytQ==} + /eth-rpc-errors@4.0.3: + resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==} dependencies: fast-safe-stringify: 2.1.1 + dev: true /ethereum-bloom-filters@1.0.10: resolution: {integrity: sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==} @@ -7897,7 +9677,7 @@ packages: resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} dependencies: '@types/pbkdf2': 3.1.0 - '@types/secp256k1': 4.0.3 + '@types/secp256k1': 4.0.6 blakejs: 1.1.1 browserify-aes: 1.2.0 bs58check: 2.1.2 @@ -7930,7 +9710,7 @@ packages: '@scure/bip32': 1.3.1 '@scure/bip39': 1.2.1 - /ethereum-waffle@4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typescript@5.2.2): + /ethereum-waffle@4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typescript@5.3.3): resolution: {integrity: sha512-iw9z1otq7qNkGDNcMoeNeLIATF9yKl1M8AIeu42ElfNBplq0e+5PeasQmm8ybY/elkZ1XyRO0JBQxQdVRb8bqQ==} engines: {node: '>=10.0'} hasBin: true @@ -7938,12 +9718,12 @@ packages: ethers: '*' dependencies: '@ethereum-waffle/chai': 4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2) - '@ethereum-waffle/compiler': 4.0.3(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(solc@0.8.15)(typechain@8.3.1)(typescript@5.2.2) + '@ethereum-waffle/compiler': 4.0.3(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(solc@0.8.15)(typechain@8.3.1)(typescript@5.3.3) '@ethereum-waffle/mock-contract': 4.0.4(ethers@5.7.2) '@ethereum-waffle/provider': 4.0.5(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(ethers@5.7.2) ethers: 5.7.2 solc: 0.8.15 - typechain: 8.3.1(typescript@5.2.2) + typechain: 8.3.1(typescript@5.3.3) transitivePeerDependencies: - '@ensdomains/ens' - '@ensdomains/resolver' @@ -8052,8 +9832,9 @@ packages: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} - /eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + /eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + dev: true /eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} @@ -8070,19 +9851,6 @@ packages: safe-buffer: 5.2.1 dev: true - /execa@1.0.0: - resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} - engines: {node: '>=6'} - dependencies: - cross-spawn: 6.0.5 - get-stream: 4.1.0 - is-stream: 1.1.0 - npm-run-path: 2.0.2 - p-finally: 1.0.0 - signal-exit: 3.0.7 - strip-eof: 1.0.0 - dev: false - /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -8098,21 +9866,6 @@ packages: strip-final-newline: 2.0.0 dev: true - /execa@6.1.0: - resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 3.0.1 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.1.0 - onetime: 6.0.0 - signal-exit: 3.0.7 - strip-final-newline: 3.0.0 - dev: true - /execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -8135,15 +9888,19 @@ packages: homedir-polyfill: 1.0.3 dev: true - /express-prom-bundle@6.6.0(prom-client@14.2.0): - resolution: {integrity: sha512-tZh2P2p5a8/yxQ5VbRav011Poa4R0mHqdFwn9Swe/obXDe5F0jY9wtRAfNYnqk4LXY7akyvR/nrvAHxQPWUjsQ==} - engines: {node: '>=10'} + /express-prom-bundle@7.0.0(prom-client@14.2.0): + resolution: {integrity: sha512-VwVaCyGBGHkHdecpTqRdW1Jm2fXK8weCUKjGjNWorc9g4M+cZ3xoj+N9uQzfRWfIPXJG5QOaiAziOIalQzMwgA==} + engines: {node: '>=18'} peerDependencies: - prom-client: '>=12.0.0' + prom-client: '>=15.0.0' dependencies: + '@types/express': 4.17.21 + express: 4.18.2 on-finished: 2.4.1 prom-client: 14.2.0 url-value-parser: 2.0.3 + transitivePeerDependencies: + - supports-color dev: false /express@4.18.2: @@ -8187,11 +9944,19 @@ packages: /extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true /extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} dev: false + /extension-port-stream@2.1.1: + resolution: {integrity: sha512-qknp5o5rj2J9CRKfVB8KJr+uXQlrojNZzdESUPhKYLXf97TPcGf6qWWKmpsNNtUyOdzFhab1ON0jzouNxHHvow==} + engines: {node: '>=12.0.0'} + dependencies: + webextension-polyfill: 0.10.0 + dev: true + /external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -8204,17 +9969,20 @@ packages: /extsprintf@1.3.0: resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} engines: {'0': node >=0.6.0} + dev: true /extsprintf@1.4.0: resolution: {integrity: sha512-6NW8DZ8pWBc5NbGYUiqqccj9dXnuSzilZYqprdKJBZsQodGH9IyUoFOGxIWVDcBzHMb8ET24aqx9p66tZEWZkA==} engines: {'0': node >=0.6.0} + dev: true - /eyes@0.1.8: - resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} - engines: {node: '> 0.1.90'} + /fast-deep-equal@2.0.1: + resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} + dev: true /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true /fast-diff@1.2.0: resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} @@ -8232,6 +10000,7 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -8243,9 +10012,14 @@ packages: /fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + dev: true - /fast-stable-stringify@1.0.0: - resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + /fast-xml-parser@4.3.2: + resolution: {integrity: sha512-rmrXUXwbJedoXkStenj1kkljNF7ugn5ZjR9FJcwmCfcCbtOMDghPajbc+Tck6vE6F5XsDmx+Pr2le9fw8+pXBg==} + hasBin: true + dependencies: + strnum: 1.0.5 + dev: true /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} @@ -8258,12 +10032,10 @@ packages: format: 0.2.2 dev: true - /fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} + /fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.2.1 + bser: 2.1.1 dev: true /figures@3.2.0: @@ -8280,9 +10052,6 @@ packages: flat-cache: 3.0.4 dev: true - /file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -8292,6 +10061,22 @@ packages: /filter-obj@1.1.0: resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} engines: {node: '>=0.10.0'} + dev: true + + /finalhandler@1.1.2: + resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} + engines: {node: '>= 0.8'} + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.3.0 + parseurl: 1.3.3 + statuses: 1.5.0 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true /finalhandler@1.2.0: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} @@ -8308,6 +10093,15 @@ packages: - supports-color dev: false + /find-cache-dir@2.1.0: + resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} + engines: {node: '>=6'} + dependencies: + commondir: 1.0.1 + make-dir: 2.1.0 + pkg-dir: 3.0.0 + dev: true + /find-cache-dir@3.3.2: resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} engines: {node: '>=8'} @@ -8324,6 +10118,10 @@ packages: array-back: 3.1.0 dev: true + /find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + dev: true + /find-up@1.1.2: resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} engines: {node: '>=0.10.0'} @@ -8339,6 +10137,13 @@ packages: locate-path: 2.0.0 dev: true + /find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + dependencies: + locate-path: 3.0.0 + dev: true + /find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -8368,12 +10173,6 @@ packages: pkg-dir: 4.2.0 dev: false - /find-yarn-workspace-root@2.0.0: - resolution: {integrity: sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==} - dependencies: - micromatch: 4.0.5 - dev: true - /findup-sync@5.0.0: resolution: {integrity: sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==} engines: {node: '>= 10.13.0'} @@ -8401,14 +10200,28 @@ packages: resolution: {integrity: sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==} dev: true + /flow-enums-runtime@0.0.6: + resolution: {integrity: sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==} + dev: true + + /flow-parser@0.185.2: + resolution: {integrity: sha512-2hJ5ACYeJCzNtiVULov6pljKOLygy0zddoqSI1fFetM+XRPpRshFdGEijtqlamA1XwyZ+7rhryI6FQFzvtLWUQ==} + engines: {node: '>=0.4.0'} + dev: true + + /flow-parser@0.206.0: + resolution: {integrity: sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w==} + engines: {node: '>=0.4.0'} + dev: true + /fmix@0.1.0: resolution: {integrity: sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==} dependencies: imul: 1.0.1 dev: true - /follow-redirects@1.15.2(debug@4.3.4): - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + /follow-redirects@1.15.5(debug@4.3.4): + resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -8417,6 +10230,7 @@ packages: optional: true dependencies: debug: 4.3.4(supports-color@8.1.1) + dev: true /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -8441,6 +10255,7 @@ packages: /forever-agent@0.6.1: resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + dev: true /form-data@2.3.3: resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} @@ -8449,6 +10264,7 @@ packages: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 + dev: true /form-data@3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} @@ -8473,13 +10289,6 @@ packages: engines: {node: '>=0.4.x'} dev: true - /formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - dependencies: - fetch-blob: 3.2.0 - dev: true - /formidable@2.1.2: resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} dependencies: @@ -8505,7 +10314,6 @@ packages: /fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} - dev: false /fromentries@1.3.2: resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} @@ -8556,19 +10364,8 @@ packages: engines: {node: '>=6 <7 || >=8'} dependencies: graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - dev: false - - /fs-extra@9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: true + jsonfile: 4.0.0 + universalify: 0.1.2 /fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} @@ -8579,6 +10376,7 @@ packages: /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true /fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} @@ -8588,9 +10386,6 @@ packages: dev: true optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -8610,6 +10405,11 @@ packages: /functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + /futoin-hkdf@1.5.3: + resolution: {integrity: sha512-SewY5KdMpaoCeh7jachEWFsh1nNlaDjNHZXWqL5IGwtpEYHTgkr2+AMCgNwKWkcc0wpSYrZfR7he4WdmHFtDxQ==} + engines: {node: '>=8'} + dev: true + /ganache@7.4.3: resolution: {integrity: sha512-RpEDUiCkqbouyE7+NMXG26ynZ+7sGiODU84Kz+FVoXUnQ4qQM4M8wif3Y4qUCt+D/eM1RVeGq0my62FPD6Y1KA==} hasBin: true @@ -8661,13 +10461,18 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + /get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + dev: true + /get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} /get-intrinsic@1.2.1: resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 has: 1.0.3 has-proto: 1.0.1 has-symbols: 1.0.3 @@ -8677,12 +10482,9 @@ packages: engines: {node: '>=8.0.0'} dev: true - /get-stream@4.1.0: - resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} - engines: {node: '>=6'} - dependencies: - pump: 3.0.0 - dev: false + /get-port-please@3.1.1: + resolution: {integrity: sha512-3UBAyM3u4ZBVYDsxOQfJDxEa6XTbpBDrOjp4mf7ExFRt5BKs/QywQQiJsh2B+hxcZLSapWqCRvElUe8DnKcFHA==} + dev: true /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} @@ -8711,6 +10513,7 @@ packages: resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} dependencies: assert-plus: 1.0.0 + dev: true /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -8737,17 +10540,6 @@ packages: path-scurry: 1.10.1 dev: true - /glob@7.1.4: - resolution: {integrity: sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - /glob@7.1.6: resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} dependencies: @@ -8790,6 +10582,7 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 + dev: true /global-modules@1.0.0: resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==} @@ -8840,18 +10633,6 @@ packages: merge2: 1.4.1 slash: 3.0.0 - /globby@12.1.0: - resolution: {integrity: sha512-YULDaNwsoUZkRy9TWSY/M7Obh0abamTKoKzTfOI3uU+hfpX2FZqOq8LFDxsjYheF1RH7ITdArgbQnsNBFgcdBA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - array-union: 3.0.1 - dir-glob: 3.0.1 - fast-glob: 3.3.1 - ignore: 5.2.4 - merge2: 1.4.1 - slash: 4.0.0 - dev: true - /globby@13.2.2: resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -8879,9 +10660,23 @@ packages: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true + /h3@1.9.0: + resolution: {integrity: sha512-+F3ZqrNV/CFXXfZ2lXBINHi+rM4Xw3CDC5z2CDK3NMPocjonKipGLLDSkrqY9DOrioZNPTIdDMWfQKm//3X2DA==} + dependencies: + cookie-es: 1.0.0 + defu: 6.1.3 + destr: 2.0.2 + iron-webcrypto: 1.0.0 + radix3: 1.1.0 + ufo: 1.3.2 + uncrypto: 0.1.3 + unenv: 1.8.0 + dev: true + /har-schema@2.0.0: resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} engines: {node: '>=4'} + dev: true /har-validator@5.1.5: resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} @@ -8890,14 +10685,15 @@ packages: dependencies: ajv: 6.12.6 har-schema: 2.0.0 + dev: true /hard-rejection@2.1.0: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} engines: {node: '>=6'} dev: false - /hardhat-deploy@0.11.43: - resolution: {integrity: sha512-D760CjDtinwjOCpKOvdyRtIJYLQIYXmhfgkFe+AkxlYM9bPZ/T4tZ/xIB2tR89ZT+z0hF1YuZFBXIL3/G/9T5g==} + /hardhat-deploy@0.11.44: + resolution: {integrity: sha512-kAkCvTYPpdIvnWCc3F0xg3AbVsa/SgH9aePPO7e7nHUOkg07LGKuknU/UaVAfWwHe7Zs57pQIAolAQyKI+mnXw==} dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/abstract-signer': 5.7.0 @@ -8929,8 +10725,8 @@ packages: - utf-8-validate dev: true - /hardhat@2.18.3(ts-node@10.9.1)(typescript@5.2.2): - resolution: {integrity: sha512-JuYaTG+4ZHVjEHCW5Hn6jCHH3LpO75dtgznZpM/dLv12RcSlw/xHbeQh3FAsGahQr1epKryZcZEMHvztVZHe0g==} + /hardhat@2.20.1(ts-node@10.9.2)(typescript@5.3.3): + resolution: {integrity: sha512-q75xDQiQtCZcTMBwjTovrXEU5ECr49baxr4/OBkIu/ULTPzlB20yk1dRWNmD2IFbAeAeXggaWvQAdpiScaHtPw==} hasBin: true peerDependencies: ts-node: '*' @@ -8943,16 +10739,17 @@ packages: dependencies: '@ethersproject/abi': 5.7.0 '@metamask/eth-sig-util': 4.0.0 - '@nomicfoundation/ethereumjs-block': 5.0.2 - '@nomicfoundation/ethereumjs-blockchain': 7.0.2 - '@nomicfoundation/ethereumjs-common': 4.0.2 - '@nomicfoundation/ethereumjs-evm': 2.0.2 - '@nomicfoundation/ethereumjs-rlp': 5.0.2 - '@nomicfoundation/ethereumjs-statemanager': 2.0.2 - '@nomicfoundation/ethereumjs-trie': 6.0.2 - '@nomicfoundation/ethereumjs-tx': 5.0.2 - '@nomicfoundation/ethereumjs-util': 9.0.2 - '@nomicfoundation/ethereumjs-vm': 7.0.2 + '@nomicfoundation/ethereumjs-block': 5.0.4 + '@nomicfoundation/ethereumjs-blockchain': 7.0.4 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-evm': 2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-statemanager': 2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/ethereumjs-trie': 6.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + '@nomicfoundation/ethereumjs-verkle': 0.0.2 + '@nomicfoundation/ethereumjs-vm': 7.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) '@nomicfoundation/solidity-analyzer': 0.1.1 '@sentry/node': 5.30.0 '@types/bn.js': 5.1.0 @@ -8960,6 +10757,7 @@ packages: adm-zip: 0.4.16 aggregate-error: 3.1.0 ansi-escapes: 4.3.2 + boxen: 5.1.2 chalk: 2.4.2 chokidar: 3.5.3 ci-info: 2.0.0 @@ -8985,14 +10783,15 @@ packages: solc: 0.7.3(debug@4.3.4) source-map-support: 0.5.21 stacktrace-parser: 0.1.10 - ts-node: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) + ts-node: 10.9.2(@types/node@20.11.17)(typescript@5.3.3) tsort: 0.0.1 - typescript: 5.2.2 + typescript: 5.3.3 undici: 5.24.0 uuid: 8.3.2 ws: 7.5.9 transitivePeerDependencies: - bufferutil + - c-kzg - supports-color - utf-8-validate dev: true @@ -9000,11 +10799,6 @@ packages: /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - /has-flag@2.0.0: - resolution: {integrity: sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==} - engines: {node: '>=0.10.0'} - dev: false - /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -9036,7 +10830,7 @@ packages: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 /hash-base@3.1.0: resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} @@ -9078,6 +10872,33 @@ packages: capital-case: 1.0.4 tslib: 2.6.2 + /hermes-estree@0.15.0: + resolution: {integrity: sha512-lLYvAd+6BnOqWdnNbP/Q8xfl8LOGw4wVjfrNd9Gt8eoFzhNBRVD95n4l2ksfMVOoxuVyegs85g83KS9QOsxbVQ==} + dev: true + + /hermes-estree@0.18.2: + resolution: {integrity: sha512-KoLsoWXJ5o81nit1wSyEZnWUGy9cBna9iYMZBR7skKh7okYAYKqQ9/OczwpMHn/cH0hKDyblulGsJ7FknlfVxQ==} + dev: true + + /hermes-parser@0.15.0: + resolution: {integrity: sha512-Q1uks5rjZlE9RjMMjSUCkGrEIPI5pKJILeCtK1VmTj7U4pf3wVPoo+cxfu+s4cBAPy2JzikIIdCZgBoR6x7U1Q==} + dependencies: + hermes-estree: 0.15.0 + dev: true + + /hermes-parser@0.18.2: + resolution: {integrity: sha512-1eQfvib+VPpgBZ2zYKQhpuOjw1tH+Emuib6QmjkJWJMhyjM8xnXMvA+76o9LhF0zOAJDZgPfQhg43cyXEyl5Ew==} + dependencies: + hermes-estree: 0.18.2 + dev: true + + /hermes-profile-transformer@0.0.6: + resolution: {integrity: sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ==} + engines: {node: '>=8'} + dependencies: + source-map: 0.7.4 + dev: true + /hexoid@1.0.0: resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} engines: {node: '>=8'} @@ -9085,6 +10906,7 @@ packages: /hey-listen@1.0.8: resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + dev: true /hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} @@ -9093,6 +10915,12 @@ packages: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + /hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: true + /homedir-polyfill@1.0.3: resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} engines: {node: '>=0.10.0'} @@ -9103,17 +10931,23 @@ packages: /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - /html-encoding-sniffer@3.0.0: - resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} - engines: {node: '>=12'} + /html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} dependencies: - whatwg-encoding: 2.0.0 + whatwg-encoding: 3.1.1 dev: true /html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true + /html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + dependencies: + void-elements: 3.1.0 + dev: true + /htmlparser2@7.2.0: resolution: {integrity: sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==} dependencies: @@ -9133,17 +10967,21 @@ packages: statuses: 2.0.1 toidentifier: 1.0.1 - /http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} + /http-proxy-agent@7.0.0: + resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} + engines: {node: '>= 14'} dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2 + agent-base: 7.1.0 debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true + /http-shutdown@1.2.2: + resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + /http-signature@1.2.0: resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} engines: {node: '>=0.8', npm: '>=1.3.7'} @@ -9151,6 +10989,7 @@ packages: assert-plus: 1.0.0 jsprim: 1.4.1 sshpk: 1.16.1 + dev: true /https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} @@ -9160,6 +10999,17 @@ packages: debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color + dev: true + + /https-proxy-agent@7.0.2: + resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + dev: true /human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} @@ -9170,25 +11020,27 @@ packages: engines: {node: '>=10.17.0'} dev: true - /human-signals@3.0.1: - resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==} - engines: {node: '>=12.20.0'} - dev: true - /human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} dev: true - /humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + /husky@9.0.10: + resolution: {integrity: sha512-TQGNknoiy6bURzIO77pPRu+XHi6zI7T93rX+QnJsoYFf3xdjKOur+IlfqzJGMHIK/wXrLg+GsvMs8Op7vI2jVA==} + engines: {node: '>=18'} + hasBin: true + dev: true + + /i18next-browser-languagedetector@7.2.0: + resolution: {integrity: sha512-U00DbDtFIYD3wkWsr2aVGfXGAj2TgnELzOX9qv8bT0aJtvPV9CRO77h+vgmHFBMe7LAxdwvT/7VkCWGya6L3tA==} dependencies: - ms: 2.1.3 + '@babel/runtime': 7.23.7 + dev: true - /husky@8.0.3: - resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} - engines: {node: '>=14'} - hasBin: true + /i18next@22.5.1: + resolution: {integrity: sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==} + dependencies: + '@babel/runtime': 7.23.7 dev: true /iconv-lite@0.4.24: @@ -9204,6 +11056,10 @@ packages: safer-buffer: 2.1.2 dev: true + /idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + dev: true + /idna-uts46-hx@2.3.1: resolution: {integrity: sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==} engines: {node: '>=4.0.0'} @@ -9218,6 +11074,14 @@ packages: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} + /image-size@1.1.1: + resolution: {integrity: sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==} + engines: {node: '>=16.x'} + hasBin: true + dependencies: + queue: 6.0.2 + dev: true + /immediate@3.2.3: resolution: {integrity: sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg==} dev: true @@ -9230,6 +11094,14 @@ packages: resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} dev: true + /import-fresh@2.0.0: + resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==} + engines: {node: '>=4'} + dependencies: + caller-path: 2.0.0 + resolve-from: 3.0.0 + dev: true + /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -9257,6 +11129,7 @@ packages: dependencies: once: 1.4.0 wrappy: 1.0.2 + dev: true /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -9273,6 +11146,12 @@ packages: has: 1.0.3 side-channel: 1.0.4 + /invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: true + /invert-kv@1.0.0: resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==} engines: {node: '>=0.10.0'} @@ -9284,11 +11163,36 @@ packages: fp-ts: 1.19.5 dev: true + /ioredis@5.3.2: + resolution: {integrity: sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==} + engines: {node: '>=12.22.0'} + dependencies: + '@ioredis/commands': 1.2.0 + cluster-key-slot: 1.1.2 + debug: 4.3.4(supports-color@8.1.1) + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /ip@1.1.9: + resolution: {integrity: sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==} + dev: true + /ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} dev: false + /iron-webcrypto@1.0.0: + resolution: {integrity: sha512-anOK1Mktt8U1Xi7fCM3RELTuYbnFikQY5VtrDj7kPgpejV7d43tWKhzgioO0zpkazLEL/j/iayRqnJhrGfqUsg==} + dev: true + /is-alphabetical@1.0.4: resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} dev: true @@ -9359,13 +11263,6 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - /is-ci@3.0.1: - resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} - hasBin: true - dependencies: - ci-info: 3.8.0 - dev: false - /is-core-module@2.13.0: resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} dependencies: @@ -9387,6 +11284,11 @@ packages: resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} dev: true + /is-directory@0.3.1: + resolution: {integrity: sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==} + engines: {node: '>=0.10.0'} + dev: true + /is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} @@ -9410,6 +11312,11 @@ packages: number-is-nan: 1.0.1 dev: true + /is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + dev: true + /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -9419,6 +11326,13 @@ packages: engines: {node: '>=12'} dev: true + /is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + dependencies: + get-east-asian-width: 1.2.0 + dev: true + /is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} @@ -9439,6 +11353,11 @@ packages: resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} dev: true + /is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + dev: true + /is-interactive@2.0.0: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} @@ -9490,6 +11409,13 @@ packages: engines: {node: '>=8'} dev: true + /is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + /is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} dev: true @@ -9513,11 +11439,6 @@ packages: dependencies: call-bind: 1.0.2 - /is-stream@1.1.0: - resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} - engines: {node: '>=0.10.0'} - dev: false - /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -9555,6 +11476,7 @@ packages: /is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + dev: true /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} @@ -9592,6 +11514,11 @@ packages: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} + /is-wsl@1.1.0: + resolution: {integrity: sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==} + engines: {node: '>=4'} + dev: true + /is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} @@ -9599,12 +11526,21 @@ packages: is-docker: 2.2.1 dev: true + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true + /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + /isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: true + /isomorphic-fetch@3.0.0: resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} dependencies: @@ -9614,19 +11550,21 @@ packages: - encoding dev: true - /isomorphic-ws@4.0.1(ws@7.5.9): - resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} - peerDependencies: - ws: '*' + /isomorphic-unfetch@3.1.0: + resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} dependencies: - ws: 7.5.9 + node-fetch: 2.6.12 + unfetch: 4.2.0 + transitivePeerDependencies: + - encoding + dev: true - /isomorphic-ws@5.0.0(ws@8.13.0): + /isomorphic-ws@5.0.0(ws@8.16.0): resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} peerDependencies: ws: '*' dependencies: - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + ws: 8.16.0 dev: false /isows@1.0.3(ws@8.13.0): @@ -9634,18 +11572,19 @@ packages: peerDependencies: ws: '*' dependencies: - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + ws: 8.13.0 /isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + dev: true /istanbul-lib-coverage@3.0.0: resolution: {integrity: sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==} engines: {node: '>=8'} dev: true - /istanbul-lib-coverage@3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} dev: true @@ -9662,21 +11601,21 @@ packages: dependencies: '@babel/core': 7.22.10 '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /istanbul-lib-instrument@6.0.0: - resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==} + /istanbul-lib-instrument@6.0.1: + resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==} engines: {node: '>=10'} dependencies: '@babel/core': 7.22.10 - '@babel/parser': 7.22.10 + '@babel/parser': 7.23.6 '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 - semver: 7.5.4 + istanbul-lib-coverage: 3.2.2 + semver: 7.6.0 transitivePeerDependencies: - supports-color dev: true @@ -9687,7 +11626,7 @@ packages: dependencies: archy: 1.0.0 cross-spawn: 7.0.3 - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 make-dir: 3.1.0 p-map: 3.0.0 rimraf: 3.0.2 @@ -9698,7 +11637,7 @@ packages: resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} engines: {node: '>=8'} dependencies: - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 make-dir: 3.1.0 supports-color: 7.2.0 dev: true @@ -9707,7 +11646,7 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} dependencies: - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 make-dir: 4.0.0 supports-color: 7.2.0 dev: true @@ -9717,7 +11656,7 @@ packages: engines: {node: '>=8'} dependencies: debug: 4.3.4(supports-color@8.1.1) - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color @@ -9728,7 +11667,7 @@ packages: engines: {node: '>=10'} dependencies: debug: 4.3.4(supports-color@8.1.1) - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color @@ -9742,8 +11681,8 @@ packages: istanbul-lib-report: 3.0.1 dev: true - /istanbul-reports@3.1.5: - resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} + /istanbul-reports@3.1.6: + resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} engines: {node: '>=8'} dependencies: html-escaper: 2.0.2 @@ -9769,27 +11708,6 @@ packages: '@pkgjs/parseargs': 0.11.0 dev: true - /jayson@4.1.0: - resolution: {integrity: sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==} - engines: {node: '>=8'} - hasBin: true - dependencies: - '@types/connect': 3.4.35 - '@types/node': 12.20.55 - '@types/ws': 7.4.7 - JSONStream: 1.3.5 - commander: 2.20.3 - delay: 5.0.0 - es6-promisify: 5.0.0 - eyes: 0.1.8 - isomorphic-ws: 4.0.1(ws@7.5.9) - json-stringify-safe: 5.0.1 - uuid: 8.3.2 - ws: 7.5.9 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - /jest-diff@29.7.0: resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9800,11 +11718,96 @@ packages: pretty-format: 29.7.0 dev: true + /jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.11.17 + jest-mock: 29.7.0 + jest-util: 29.7.0 + dev: true + /jest-get-type@29.6.3: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true + /jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.22.13 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + dev: true + + /jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.11.17 + jest-util: 29.7.0 + dev: true + + /jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.11.17 + chalk: 4.1.2 + ci-info: 3.8.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + dev: true + + /jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + dev: true + + /jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 20.11.17 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + dev: true + + /joi@17.11.0: + resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==} + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.4 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + dev: true + /joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -9840,35 +11843,67 @@ packages: /jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + dev: true - /jsdoc-type-pratt-parser@1.0.4: - resolution: {integrity: sha512-jzmW9gokeq9+bHPDR1nCeidMyFUikdZlbOhKzh9+/nJqB75XhpNKec1/UuxW5c4+O+Pi31Gc/dCboyfSm/pSpQ==} - engines: {node: '>=12.0.0'} + /jsc-android@250231.0.0: + resolution: {integrity: sha512-rS46PvsjYmdmuz1OAWXY/1kCYG7pnf1TBqeTiOJr1iDz7s5DLxxC9n/ZMknLDxzYzNVfI7R95MH10emSSG1Wuw==} + dev: true + + /jsc-safe-url@0.2.4: + resolution: {integrity: sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==} + dev: true + + /jscodeshift@0.14.0(@babel/preset-env@7.23.7): + resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} + hasBin: true + peerDependencies: + '@babel/preset-env': ^7.1.6 + dependencies: + '@babel/core': 7.22.10 + '@babel/parser': 7.23.6 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.22.10) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.22.10) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.22.10) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.22.10) + '@babel/preset-env': 7.23.7(@babel/core@7.22.10) + '@babel/preset-flow': 7.23.3(@babel/core@7.22.10) + '@babel/preset-typescript': 7.23.3(@babel/core@7.22.10) + '@babel/register': 7.23.7(@babel/core@7.22.10) + babel-core: 7.0.0-bridge.0(@babel/core@7.22.10) + chalk: 4.1.2 + flow-parser: 0.206.0 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + neo-async: 2.6.2 + node-dir: 0.1.17 + recast: 0.21.5 + temp: 0.8.4 + write-file-atomic: 2.4.3 + transitivePeerDependencies: + - supports-color dev: true - /jsdoc-type-pratt-parser@1.1.1: - resolution: {integrity: sha512-uelRmpghNwPBuZScwgBG/OzodaFk5RbO5xaivBdsAY70icWfShwZ7PCMO0x1zSkOa8T1FzHThmrdoyg/0AwV5g==} + /jsdoc-type-pratt-parser@4.0.0: + resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==} engines: {node: '>=12.0.0'} dev: true - /jsdom@22.1.0: - resolution: {integrity: sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==} - engines: {node: '>=16'} + /jsdom@24.0.0: + resolution: {integrity: sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==} + engines: {node: '>=18'} peerDependencies: - canvas: ^2.5.0 + canvas: ^2.11.2 peerDependenciesMeta: canvas: optional: true dependencies: - abab: 2.0.6 - cssstyle: 3.0.0 - data-urls: 4.0.0 + cssstyle: 4.0.1 + data-urls: 5.0.0 decimal.js: 10.4.3 - domexception: 4.0.0 form-data: 4.0.0 - html-encoding-sniffer: 3.0.0 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 is-potential-custom-element-name: 1.0.1 nwsapi: 2.2.7 parse5: 7.1.2 @@ -9876,13 +11911,13 @@ packages: saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 4.1.3 - w3c-xmlserializer: 4.0.0 + w3c-xmlserializer: 5.0.0 webidl-conversions: 7.0.0 - whatwg-encoding: 2.0.0 - whatwg-mimetype: 3.0.0 - whatwg-url: 12.0.1 - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) - xml-name-validator: 4.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.0.0 + ws: 8.16.0 + xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil - supports-color @@ -9912,6 +11947,10 @@ packages: bignumber.js: 9.0.1 dev: true + /json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + dev: true + /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -9920,29 +11959,37 @@ packages: engines: {node: '>=10.0.0'} dependencies: '@metamask/safe-event-emitter': 2.0.0 - eth-rpc-errors: 4.0.2 + eth-rpc-errors: 4.0.3 + dev: true + + /json-rpc-middleware-stream@4.2.3: + resolution: {integrity: sha512-4iFb0yffm5vo3eFKDbQgke9o17XBcLQ2c3sONrXSbcOLzP8LTojqo8hRGVgtJShhm5q4ZDSNq039fAx9o65E1w==} + engines: {node: '>=14.0.0'} + dependencies: + '@metamask/safe-event-emitter': 3.0.0 + json-rpc-engine: 6.1.0 + readable-stream: 2.3.8 + dev: true /json-rpc-random-id@1.0.1: resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==} + dev: true /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true /json-schema@0.2.3: resolution: {integrity: sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==} + dev: true /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true - /json-stable-stringify@1.0.2: - resolution: {integrity: sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==} - dependencies: - jsonify: 0.0.1 - dev: true - /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: true /json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} @@ -9956,6 +12003,7 @@ packages: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true + dev: true /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} @@ -9980,14 +12028,6 @@ packages: graceful-fs: 4.2.11 dev: true - /jsonify@0.0.1: - resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} - dev: true - - /jsonparse@1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} - /jsonpointer@5.0.1: resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} engines: {node: '>=0.10.0'} @@ -10001,12 +12041,13 @@ packages: extsprintf: 1.3.0 json-schema: 0.2.3 verror: 1.10.0 + dev: true /jsx-ast-utils@3.2.0: resolution: {integrity: sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==} engines: {node: '>=4.0'} dependencies: - array-includes: 3.1.6 + array-includes: 3.1.7 object.assign: 4.1.4 dev: true @@ -10037,20 +12078,15 @@ packages: node-addon-api: 2.0.2 node-gyp-build: 4.6.0 readable-stream: 3.6.2 + dev: true /keyvaluestorage-interface@1.0.0: resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + dev: true /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - dev: false - - /klaw-sync@6.0.0: - resolution: {integrity: sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==} - dependencies: - graceful-fs: 4.2.11 - dev: true /klaw@1.3.1: resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} @@ -10058,6 +12094,11 @@ packages: graceful-fs: 4.2.11 dev: true + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + /kleur@4.1.5: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} @@ -10133,19 +12174,6 @@ packages: engines: {node: '>=10'} dev: true - /level-supports@4.0.1: - resolution: {integrity: sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==} - engines: {node: '>=12'} - dev: true - - /level-transcoder@1.0.1: - resolution: {integrity: sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==} - engines: {node: '>=12'} - dependencies: - buffer: 6.0.3 - module-error: 1.0.2 - dev: true - /level-ws@2.0.0: resolution: {integrity: sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==} engines: {node: '>=6'} @@ -10155,14 +12183,6 @@ packages: xtend: 4.0.2 dev: true - /level@8.0.0: - resolution: {integrity: sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==} - engines: {node: '>=12'} - dependencies: - browser-level: 1.0.1 - classic-level: 1.3.0 - dev: true - /leveldown@6.1.0: resolution: {integrity: sha512-8C7oJDT44JXxh04aSSsfcMI8YiaGRhOFI9/pMEL7nWJLVsWajDPTRxsSHTM2WcTVY5nXM+SuRHzPPi0GbnDX+w==} engines: {node: '>=10.12.0'} @@ -10184,6 +12204,11 @@ packages: xtend: 4.0.2 dev: true + /leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -10192,11 +12217,25 @@ packages: type-check: 0.4.0 dev: true + /lighthouse-logger@1.4.2: + resolution: {integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==} + dependencies: + debug: 2.6.9 + marky: 1.2.5 + transitivePeerDependencies: + - supports-color + dev: true + /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} dev: true + /lilconfig@3.0.0: + resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + engines: {node: '>=14'} + dev: true + /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -10205,20 +12244,8 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true - /linkify-it@3.0.3: - resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} - dependencies: - uc.micro: 1.0.6 - dev: true - - /linkify-it@4.0.1: - resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} - dependencies: - uc.micro: 1.0.6 - dev: true - - /lint-staged@15.0.2: - resolution: {integrity: sha512-vnEy7pFTHyVuDmCAIFKR5QDO8XLVlPFQQyujQ/STOxe40ICWqJ6knS2wSJ/ffX/Lw0rz83luRDh+ET7toN+rOw==} + /lint-staged@15.2.0: + resolution: {integrity: sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==} engines: {node: '>=18.12.0'} hasBin: true dependencies: @@ -10226,26 +12253,49 @@ packages: commander: 11.1.0 debug: 4.3.4(supports-color@8.1.1) execa: 8.0.1 - lilconfig: 2.1.0 - listr2: 7.0.2 + lilconfig: 3.0.0 + listr2: 8.0.0 micromatch: 4.0.5 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.3.3 + yaml: 2.3.4 transitivePeerDependencies: - supports-color dev: true - /listr2@7.0.2: - resolution: {integrity: sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==} - engines: {node: '>=16.0.0'} + /listhen@1.5.5: + resolution: {integrity: sha512-LXe8Xlyh3gnxdv4tSjTjscD1vpr/2PRpzq8YIaMJgyKzRG8wdISlWVWnGThJfHnlJ6hmLt2wq1yeeix0TEbuoA==} + hasBin: true + dependencies: + '@parcel/watcher': 2.3.0 + '@parcel/watcher-wasm': 2.3.0 + citty: 0.1.5 + clipboardy: 3.0.0 + consola: 3.2.3 + defu: 6.1.3 + get-port-please: 3.1.1 + h3: 1.9.0 + http-shutdown: 1.2.2 + jiti: 1.21.0 + mlly: 1.4.2 + node-forge: 1.3.1 + pathe: 1.1.1 + std-env: 3.6.0 + ufo: 1.3.2 + untun: 0.1.2 + uqr: 0.1.2 + dev: true + + /listr2@8.0.0: + resolution: {integrity: sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg==} + engines: {node: '>=18.0.0'} dependencies: - cli-truncate: 3.1.0 + cli-truncate: 4.0.0 colorette: 2.0.20 eventemitter3: 5.0.1 - log-update: 5.0.1 + log-update: 6.0.0 rfdc: 1.3.0 - wrap-ansi: 8.1.0 + wrap-ansi: 9.0.0 dev: true /lit-element@3.3.2: @@ -10254,18 +12304,13 @@ packages: '@lit-labs/ssr-dom-shim': 1.1.1 '@lit/reactive-element': 1.6.2 lit-html: 2.8.0 + dev: true /lit-html@2.8.0: resolution: {integrity: sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==} dependencies: '@types/trusted-types': 2.0.3 - - /lit@2.7.5: - resolution: {integrity: sha512-i/cH7Ye6nBDUASMnfwcictBnsTN91+aBjXoTHF2xARghXScKxpD4F4WYI+VLXg9lqbMinDfvoI7VnZXjyHgdfQ==} - dependencies: - '@lit/reactive-element': 1.6.2 - lit-element: 3.3.2 - lit-html: 2.8.0 + dev: true /lit@2.8.0: resolution: {integrity: sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==} @@ -10301,9 +12346,12 @@ packages: strip-bom: 3.0.0 dev: false - /local-pkg@0.4.3: - resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + /local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} + dependencies: + mlly: 1.4.2 + pkg-types: 1.0.3 dev: true /locate-path@2.0.0: @@ -10314,6 +12362,14 @@ packages: path-exists: 3.0.0 dev: true + /locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + dev: true + /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -10341,12 +12397,25 @@ packages: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: true + /lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + dev: true + /lodash.flattendeep@4.4.0: resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} dev: true + /lodash.isarguments@3.1.0: + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} + dev: true + /lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + dev: true /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -10360,6 +12429,10 @@ packages: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} dev: false + /lodash.throttle@4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + dev: true + /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -10379,15 +12452,24 @@ packages: is-unicode-supported: 1.3.0 dev: true - /log-update@5.0.1: - resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + /log-update@6.0.0: + resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} + engines: {node: '>=18'} dependencies: - ansi-escapes: 5.0.0 + ansi-escapes: 6.2.0 cli-cursor: 4.0.0 - slice-ansi: 5.0.0 + slice-ansi: 7.1.0 strip-ansi: 7.1.0 - wrap-ansi: 8.1.0 + wrap-ansi: 9.0.0 + dev: true + + /logkitty@0.7.1: + resolution: {integrity: sha512-/3ER20CTTbahrCrpYfPn7Xavv9diBROZpoXGVZDWMw4b/X4uuUwAC0ki85tgsdMRONURyIJbcOvS94QsUBYPbQ==} + hasBin: true + dependencies: + ansi-fragments: 0.2.1 + dayjs: 1.11.10 + yargs: 15.4.1 dev: true /longest-streak@2.0.4: @@ -10400,8 +12482,8 @@ packages: dependencies: js-tokens: 4.0.0 - /loupe@2.3.6: - resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} dependencies: get-func-name: 2.0.2 @@ -10410,8 +12492,8 @@ packages: dependencies: tslib: 2.6.2 - /lru-cache@10.0.1: - resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==} + /lru-cache@10.1.0: + resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} engines: {node: 14 || >=16.14} dev: true @@ -10451,13 +12533,29 @@ packages: hasBin: true dev: false - /magic-string@0.30.1: - resolution: {integrity: sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==} + /magic-string@0.30.5: + resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /magicast@0.3.3: + resolution: {integrity: sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==} + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + source-map-js: 1.0.2 + dev: true + + /make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + dependencies: + pify: 4.0.1 + semver: 5.7.2 + dev: true + /make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -10469,11 +12567,18 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} dependencies: - semver: 7.5.4 + semver: 7.6.0 dev: true /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true /map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} @@ -10485,106 +12590,22 @@ packages: engines: {node: '>=8'} dev: false - /markdown-it@12.3.2: - resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} - hasBin: true - dependencies: - argparse: 2.0.1 - entities: 2.1.0 - linkify-it: 3.0.3 - mdurl: 1.0.1 - uc.micro: 1.0.6 - dev: true - - /markdown-it@13.0.1: - resolution: {integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==} - hasBin: true - dependencies: - argparse: 2.0.1 - entities: 3.0.1 - linkify-it: 4.0.1 - mdurl: 1.0.1 - uc.micro: 1.0.6 - dev: true - /markdown-table@2.0.0: resolution: {integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==} dependencies: repeat-string: 1.6.1 dev: true - /markdownlint-cli2-formatter-default@0.0.3(markdownlint-cli2@0.4.0): - resolution: {integrity: sha512-QEAJitT5eqX1SNboOD+SO/LNBpu4P4je8JlR02ug2cLQAqmIhh8IJnSK7AcaHBHhNADqdGydnPpQOpsNcEEqCw==} - peerDependencies: - markdownlint-cli2: '>=0.0.4' - dependencies: - markdownlint-cli2: 0.4.0 - dev: true - - /markdownlint-cli2@0.4.0: - resolution: {integrity: sha512-EcwP5tAbyzzL3ACI0L16LqbNctmh8wNX56T+aVvIxWyTAkwbYNx2V7IheRkXS3mE7R/pnaApZ/RSXcXuzRVPjg==} - engines: {node: '>=12'} - hasBin: true - dependencies: - globby: 12.1.0 - markdownlint: 0.25.1 - markdownlint-cli2-formatter-default: 0.0.3(markdownlint-cli2@0.4.0) - markdownlint-rule-helpers: 0.16.0 - micromatch: 4.0.4 - strip-json-comments: 4.0.0 - yaml: 1.10.2 - dev: true - - /markdownlint-micromark@0.1.7: - resolution: {integrity: sha512-BbRPTC72fl5vlSKv37v/xIENSRDYL/7X/XoFzZ740FGEbs9vZerLrIkFRY0rv7slQKxDczToYuMmqQFN61fi4Q==} - engines: {node: '>=16'} - dev: true - - /markdownlint-rule-helpers@0.16.0: - resolution: {integrity: sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==} - dev: true - - /markdownlint@0.25.1: - resolution: {integrity: sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==} - engines: {node: '>=12'} - dependencies: - markdown-it: 12.3.2 - dev: true - - /markdownlint@0.31.1: - resolution: {integrity: sha512-CKMR2hgcIBrYlIUccDCOvi966PZ0kJExDrUi1R+oF9PvqQmCrTqjOsgIvf2403OmJ+CWomuzDoylr6KbuMyvHA==} - engines: {node: '>=16'} - dependencies: - markdown-it: 13.0.1 - markdownlint-micromark: 0.1.7 - dev: true - - /marked-terminal@3.3.0(marked@0.7.0): - resolution: {integrity: sha512-+IUQJ5VlZoAFsM5MHNT7g3RHSkA3eETqhRCdXv4niUMAKHQ7lb1yvAcuGPmm4soxhmtX13u4Li6ZToXtvSEH+A==} - peerDependencies: - marked: ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0 - dependencies: - ansi-escapes: 3.2.0 - cardinal: 2.1.1 - chalk: 2.4.2 - cli-table: 0.3.6 - marked: 0.7.0 - node-emoji: 1.11.0 - supports-hyperlinks: 1.0.1 - dev: false - - /marked@0.7.0: - resolution: {integrity: sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==} - engines: {node: '>=0.10.0'} - hasBin: true - dev: false - /marked@4.3.0: resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} engines: {node: '>= 12'} hasBin: true dev: true + /marky@1.2.5: + resolution: {integrity: sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==} + dev: true + /match-all@1.2.6: resolution: {integrity: sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ==} dev: true @@ -10695,10 +12716,6 @@ packages: resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} dev: true - /mdurl@1.0.1: - resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} - dev: true - /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -10716,13 +12733,8 @@ packages: safe-buffer: 5.2.1 dev: true - /memory-level@1.0.0: - resolution: {integrity: sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==} - engines: {node: '>=12'} - dependencies: - abstract-level: 1.0.3 - functional-red-black-tree: 1.0.1 - module-error: 1.0.2 + /memoize-one@5.2.1: + resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} dev: true /memorystream@0.3.1: @@ -10751,6 +12763,13 @@ packages: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} dev: false + /merge-options@3.0.4: + resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==} + engines: {node: '>=10'} + dependencies: + is-plain-obj: 2.1.0 + dev: true + /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true @@ -10770,13 +12789,13 @@ packages: semaphore-async-await: 1.5.1 dev: true - /merkletreejs@0.3.10: - resolution: {integrity: sha512-lin42tKfRdkW+6iE5pjtQ9BnH+1Hk3sJ5Fn9hUUSjcXRcJbSISHgPCfYvMNEXiNqZPhz/TyRPEV30qgnujsQ7A==} + /merkletreejs@0.3.11: + resolution: {integrity: sha512-LJKTl4iVNTndhL+3Uz/tfkjD0klIWsHlUzgtuNnNrsf7bAlXR30m+xYB7lHr5Z/l6e/yAIsr26Dabx6Buo4VGQ==} engines: {node: '>= 7.6.0'} dependencies: bignumber.js: 9.0.1 buffer-reverse: 1.0.1 - crypto-js: 3.3.0 + crypto-js: 4.2.0 treeify: 1.1.0 web3-utils: 1.10.1 dev: false @@ -10785,6 +12804,217 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} + /metro-babel-transformer@0.80.3: + resolution: {integrity: sha512-Si1GO9fhiLi3DfHseFDaZcU+Y6iYHx54rszILnBIx80aas3pRZpL3z/UsEZ7coTQZTFsblt2QDIE+Izxlq4mwQ==} + engines: {node: '>=18'} + dependencies: + '@babel/core': 7.22.10 + hermes-parser: 0.18.2 + nullthrows: 1.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /metro-cache-key@0.80.3: + resolution: {integrity: sha512-WNrtDpbhtW2Yqjp1t0WxJhKNR/Zbo1LZ4WvHsdv/PraAs2mr+SaM5bbiptBSKOOGJkV/FIQveW5riZi53JnCbw==} + engines: {node: '>=18'} + dev: true + + /metro-cache@0.80.3: + resolution: {integrity: sha512-7gHcOIXdAHCBzsovF4b+VgcfIZtCpCIFiT2zx9amU58xrmkx+PRIl1KZDIUfRBbGrO9HJtZxH7lr7/hoiLIUWA==} + engines: {node: '>=18'} + dependencies: + metro-core: 0.80.3 + rimraf: 3.0.2 + dev: true + + /metro-config@0.80.3: + resolution: {integrity: sha512-cE7KPT1Usdrd2nLEVpzukKWmeBU1PufHPkuD9BjjtoABbzdj35gMLDnK+mhjSq9km2vF2QEPtE0M+WKvq9pXfQ==} + engines: {node: '>=18'} + dependencies: + connect: 3.7.0 + cosmiconfig: 5.2.1 + jest-validate: 29.7.0 + metro: 0.80.3 + metro-cache: 0.80.3 + metro-core: 0.80.3 + metro-runtime: 0.80.3 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /metro-core@0.80.3: + resolution: {integrity: sha512-X2ZfAvR55TdD/Rv9i4gYVI68JpRPHcpKpkr6IVtidFPoNjf4Fodh1qH7gEAJUnO5FL3a1JyPffbW6eFaXPxkFw==} + engines: {node: '>=18'} + dependencies: + lodash.throttle: 4.1.1 + metro-resolver: 0.80.3 + dev: true + + /metro-file-map@0.80.3: + resolution: {integrity: sha512-4qu1ABPZRvboGGB8Q2RlQ26kZRWRCMDiktgCCrX/57V6cnWgdbdTrpnsgmU3i0Q7iiw+FevOGlfD4HqdauQ59g==} + engines: {node: '>=18'} + dependencies: + anymatch: 3.1.3 + debug: 2.6.9 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + invariant: 2.2.4 + jest-worker: 29.7.0 + micromatch: 4.0.5 + node-abort-controller: 3.1.1 + nullthrows: 1.1.1 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /metro-minify-terser@0.80.3: + resolution: {integrity: sha512-gVFwoL86emFoYbI2DZKk1Ved2CklYv//huWriF0UpLJHmVEO9ii2ajTx3aIxgSeuxFLPJhdp8RgUB2EDCooaJw==} + engines: {node: '>=18'} + dependencies: + terser: 5.26.0 + dev: true + + /metro-resolver@0.80.3: + resolution: {integrity: sha512-zwa0i32rj/TI3NivcvMXHJwTG2gUgo2dXdcnAJlhEKKQvyN+7AfhNdQSlDdDqMQmU7FaLRdeWORnQJbYCrprQQ==} + engines: {node: '>=18'} + dev: true + + /metro-runtime@0.80.3: + resolution: {integrity: sha512-16RKcwpxriNnPdE5eKWJu7/KLgxE+AaDAdYthoS6zbzjaOu7RiY2zPM1Elz175Rw//74kOwtKXgxTW8ADHB8SQ==} + engines: {node: '>=18'} + dependencies: + '@babel/runtime': 7.23.7 + dev: true + + /metro-source-map@0.80.3: + resolution: {integrity: sha512-5DYcOLPjDLx84ZCZ1i0DuWSPU7AY5G/7tR+u/WN6CZNxLyYEe3TwUBdIUgQj4HgZJl/zZ/7bGYJQOHd7ubuO0w==} + engines: {node: '>=18'} + dependencies: + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.6 + invariant: 2.2.4 + metro-symbolicate: 0.80.3 + nullthrows: 1.1.1 + ob1: 0.80.3 + source-map: 0.5.7 + vlq: 1.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /metro-symbolicate@0.80.3: + resolution: {integrity: sha512-baIt8Ss2vTGbxolRTa5yg+tKVAIAB1OpwMzJ0FSUjLs+HDAzaOtSpGbNd3DPc+pzX8Gj/rdbDOA0wPuOhVsHKQ==} + engines: {node: '>=18'} + hasBin: true + dependencies: + invariant: 2.2.4 + metro-source-map: 0.80.3 + nullthrows: 1.1.1 + source-map: 0.5.7 + through2: 2.0.5 + vlq: 1.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /metro-transform-plugins@0.80.3: + resolution: {integrity: sha512-/2hGGRdJPrNfB9lz8unukaqQpGpDhYwNM0Odfh37OVFjygMB30Ffd8neQ4FNqnHnFxhl5j8VTcopUg6QhygMGQ==} + engines: {node: '>=18'} + dependencies: + '@babel/core': 7.22.10 + '@babel/generator': 7.23.3 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.3 + nullthrows: 1.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /metro-transform-worker@0.80.3: + resolution: {integrity: sha512-10ZwMDuSWyHwqNnZ50baNtHNuHhOnqThbTOgv03PsrmPHWmSv4/rrmm7711tEyLUxptY3A1hEgJ+LKYyOIQiUA==} + engines: {node: '>=18'} + dependencies: + '@babel/core': 7.22.10 + '@babel/generator': 7.23.3 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + metro: 0.80.3 + metro-babel-transformer: 0.80.3 + metro-cache: 0.80.3 + metro-cache-key: 0.80.3 + metro-source-map: 0.80.3 + metro-transform-plugins: 0.80.3 + nullthrows: 1.1.1 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /metro@0.80.3: + resolution: {integrity: sha512-7u6HjWVQR7wA/HbxzB0n6iQ0GI9s/fr49N++dZQ41BcrcFxrguIGaRe4W8VI5DtYifCVCjXDIFw6e9+MAccx/Q==} + engines: {node: '>=18'} + hasBin: true + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/core': 7.22.10 + '@babel/generator': 7.23.3 + '@babel/parser': 7.23.6 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.6 + accepts: 1.3.8 + chalk: 4.1.2 + ci-info: 2.0.0 + connect: 3.7.0 + debug: 2.6.9 + denodeify: 1.2.1 + error-stack-parser: 2.1.4 + graceful-fs: 4.2.11 + hermes-parser: 0.18.2 + image-size: 1.1.1 + invariant: 2.2.4 + jest-worker: 29.7.0 + jsc-safe-url: 0.2.4 + lodash.throttle: 4.1.1 + metro-babel-transformer: 0.80.3 + metro-cache: 0.80.3 + metro-cache-key: 0.80.3 + metro-config: 0.80.3 + metro-core: 0.80.3 + metro-file-map: 0.80.3 + metro-minify-terser: 0.80.3 + metro-resolver: 0.80.3 + metro-runtime: 0.80.3 + metro-source-map: 0.80.3 + metro-symbolicate: 0.80.3 + metro-transform-plugins: 0.80.3 + metro-transform-worker: 0.80.3 + mime-types: 2.1.35 + node-fetch: 2.6.12 + nullthrows: 1.1.1 + rimraf: 3.0.2 + serialize-error: 2.1.0 + source-map: 0.5.7 + strip-ansi: 6.0.1 + throat: 5.0.0 + ws: 7.5.9 + yargs: 17.7.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + /micro-ftch@0.3.1: resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} @@ -10860,14 +13090,6 @@ packages: - supports-color dev: true - /micromatch@4.0.4: - resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true - /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -10897,7 +13119,6 @@ packages: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} hasBin: true - dev: false /mime@2.6.0: resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} @@ -10905,6 +13126,12 @@ packages: hasBin: true dev: true + /mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + dev: true + /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -10925,16 +13152,11 @@ packages: /minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - /minimatch@3.0.5: - resolution: {integrity: sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==} - dependencies: - brace-expansion: 1.1.11 - dev: true - /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 + dev: true /minimatch@5.0.1: resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} @@ -10968,6 +13190,7 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true /minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} @@ -10989,6 +13212,22 @@ packages: yallist: 4.0.0 dev: true + /mipd@0.0.5(typescript@5.3.3): + resolution: {integrity: sha512-gbKA784D2WKb5H/GtqEv+Ofd1S9Zj+Z/PGDIl1u1QAbswkxD28BQ5bSXQxkeBzPBABg1iDSbiwGG1XqlOxRspA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + typescript: 5.3.3 + viem: 1.20.3(typescript@5.3.3) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + dev: true + /mixme@0.5.4: resolution: {integrity: sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw==} engines: {node: '>= 8.0.0'} @@ -10999,6 +13238,7 @@ packages: hasBin: true dependencies: minimist: 1.2.8 + dev: true /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} @@ -11006,13 +13246,13 @@ packages: hasBin: true dev: true - /mlly@1.4.0: - resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==} + /mlly@1.4.2: + resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==} dependencies: acorn: 8.10.0 pathe: 1.1.1 pkg-types: 1.0.3 - ufo: 1.1.2 + ufo: 1.3.2 dev: true /mnemonist@0.38.3: @@ -11049,11 +13289,6 @@ packages: yargs-unparser: 2.0.0 dev: true - /module-error@1.0.2: - resolution: {integrity: sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==} - engines: {node: '>=10'} - dev: true - /morgan@1.10.0: resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==} engines: {node: '>= 0.8.0'} @@ -11076,18 +13311,26 @@ packages: '@motionone/types': 10.15.1 '@motionone/utils': 10.15.1 '@motionone/vue': 10.16.2 + dev: true + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: true /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} /multiformats@9.9.0: resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + dev: true /multimatch@5.0.0: resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} @@ -11122,8 +13365,8 @@ packages: hasBin: true dev: true - /nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: true @@ -11132,8 +13375,8 @@ packages: resolution: {integrity: sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==} dev: true - /napi-macros@2.2.2: - resolution: {integrity: sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==} + /napi-wasm@1.1.0: + resolution: {integrity: sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg==} dev: true /natural-compare@1.4.0: @@ -11143,11 +13386,10 @@ packages: /negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} - dev: false - /nice-try@1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - dev: false + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true /no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -11155,19 +13397,37 @@ packages: lower-case: 2.0.2 tslib: 2.6.2 + /nocache@3.0.4: + resolution: {integrity: sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==} + engines: {node: '>=12.0.0'} + dev: true + + /node-abort-controller@3.1.1: + resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + dev: true + /node-addon-api@2.0.2: resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + dev: true + + /node-addon-api@5.1.0: + resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + dev: true - /node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} + /node-addon-api@7.0.0: + resolution: {integrity: sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==} dev: true - /node-emoji@1.11.0: - resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + /node-dir@0.1.17: + resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} + engines: {node: '>= 0.10.5'} dependencies: - lodash: 4.17.21 - dev: false + minimatch: 3.1.2 + dev: true + + /node-fetch-native@1.4.1: + resolution: {integrity: sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w==} + dev: true /node-fetch@2.6.12: resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==} @@ -11192,13 +13452,9 @@ packages: whatwg-url: 5.0.0 dev: false - /node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 + /node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} dev: true /node-gyp-build@4.3.0: @@ -11216,6 +13472,11 @@ packages: /node-gyp-build@4.6.0: resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} hasBin: true + dev: true + + /node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + dev: true /node-machine-id@1.1.12: resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} @@ -11228,8 +13489,13 @@ packages: process-on-spawn: 1.0.0 dev: true - /node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + dev: true + + /node-stream-zip@1.15.0: + resolution: {integrity: sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==} + engines: {node: '>=0.12.0'} dev: true /normalize-package-data@2.5.0: @@ -11245,13 +13511,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /npm-run-path@2.0.2: - resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} - engines: {node: '>=4'} - dependencies: - path-key: 2.0.1 - dev: false - /npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -11266,6 +13525,10 @@ packages: path-key: 4.0.0 dev: true + /nullthrows@1.1.1: + resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + dev: true + /number-is-nan@1.0.1: resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} engines: {node: '>=0.10.0'} @@ -11282,11 +13545,11 @@ packages: resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} dev: true - /nx-cloud@16.5.2: - resolution: {integrity: sha512-1t1Ii9gojl8r/8hFGaZ/ZyYR0Cb0hzvXLCsaFuvg+EJEFdvua3P4cfNya/0bdRrm+7Eb/ITUOskbvYq4TSlyGg==} + /nx-cloud@18.0.0: + resolution: {integrity: sha512-VpPywcHmFIU3GSWb3KV3nQ+TAMLc06DTO39vTFsM+HreB6qRloDxbADRvfM5eHAbY26TNmwflT7wxd0fluv2+A==} hasBin: true dependencies: - '@nrwl/nx-cloud': 16.5.2 + '@nrwl/nx-cloud': 18.0.0 axios: 1.1.3 chalk: 4.1.2 dotenv: 10.0.0 @@ -11300,12 +13563,12 @@ packages: - debug dev: true - /nx@17.0.2: - resolution: {integrity: sha512-utk9ufxLlRd210nEV6cKjMLVK0gup2ZMlNT41lLgUX/gp3Q59G1NkyLo3o29DxBh3AhNJ9q5MKgybmzDNdpudA==} + /nx@18.1.2: + resolution: {integrity: sha512-E414xp6lVtiTGdDUMVo72G96G66t7oJMqmcHRMEZ/mVq5ZpNWUhfMuRq5Fh8orXPtrM3xk5SHokmmFvo5PKC+g==} hasBin: true requiresBuild: true peerDependencies: - '@swc-node/register': ^1.6.7 + '@swc-node/register': ^1.8.0 '@swc/core': ^1.3.85 peerDependenciesMeta: '@swc-node/register': @@ -11313,52 +13576,51 @@ packages: '@swc/core': optional: true dependencies: - '@nrwl/tao': 17.0.2 + '@nrwl/tao': 18.1.2 '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.6 - axios: 1.5.1 + axios: 1.6.7 chalk: 4.1.2 cli-cursor: 3.1.0 cli-spinners: 2.6.1 cliui: 8.0.1 - dotenv: 16.3.1 + dotenv: 16.3.2 dotenv-expand: 10.0.0 enquirer: 2.3.6 figures: 3.2.0 flat: 5.0.2 fs-extra: 11.1.1 - glob: 7.1.4 ignore: 5.2.4 jest-diff: 29.7.0 js-yaml: 4.1.0 jsonc-parser: 3.2.0 lines-and-columns: 2.0.3 - minimatch: 3.0.5 + minimatch: 9.0.3 node-machine-id: 1.1.12 npm-run-path: 4.0.1 open: 8.4.2 - semver: 7.5.3 + ora: 5.3.0 + semver: 7.6.0 string-width: 4.2.3 strong-log-transformer: 2.1.0 tar-stream: 2.2.0 tmp: 0.2.1 tsconfig-paths: 4.2.0 tslib: 2.6.2 - v8-compile-cache: 2.3.0 yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 17.0.2 - '@nx/nx-darwin-x64': 17.0.2 - '@nx/nx-freebsd-x64': 17.0.2 - '@nx/nx-linux-arm-gnueabihf': 17.0.2 - '@nx/nx-linux-arm64-gnu': 17.0.2 - '@nx/nx-linux-arm64-musl': 17.0.2 - '@nx/nx-linux-x64-gnu': 17.0.2 - '@nx/nx-linux-x64-musl': 17.0.2 - '@nx/nx-win32-arm64-msvc': 17.0.2 - '@nx/nx-win32-x64-msvc': 17.0.2 + '@nx/nx-darwin-arm64': 18.1.2 + '@nx/nx-darwin-x64': 18.1.2 + '@nx/nx-freebsd-x64': 18.1.2 + '@nx/nx-linux-arm-gnueabihf': 18.1.2 + '@nx/nx-linux-arm64-gnu': 18.1.2 + '@nx/nx-linux-arm64-musl': 18.1.2 + '@nx/nx-linux-x64-gnu': 18.1.2 + '@nx/nx-linux-x64-musl': 18.1.2 + '@nx/nx-win32-arm64-msvc': 18.1.2 + '@nx/nx-win32-x64-msvc': 18.1.2 transitivePeerDependencies: - debug dev: true @@ -11401,6 +13663,20 @@ packages: /oauth-sign@0.9.0: resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + dev: true + + /ob1@0.80.3: + resolution: {integrity: sha512-lKJ/Wp6eSyYKYKYds1lgiDRtD2j9nNhrhx4hwegxYXTBkWz4dqermZV+Bq0iw0SszUIb+fC+btNSXwc4AG1lBQ==} + engines: {node: '>=18'} + dev: true + + /obj-multiplex@1.0.0: + resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + readable-stream: 2.3.8 + dev: true /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} @@ -11496,6 +13772,14 @@ packages: resolution: {integrity: sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==} dev: true + /ofetch@1.3.3: + resolution: {integrity: sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg==} + dependencies: + destr: 2.0.2 + node-fetch-native: 1.4.1 + ufo: 1.3.2 + dev: true + /on-exit-leak-free@0.2.0: resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} @@ -11507,19 +13791,16 @@ packages: engines: {node: '>= 0.8'} dependencies: ee-first: 1.1.1 - dev: false /on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} dependencies: ee-first: 1.1.1 - dev: false /on-headers@1.0.2: resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} engines: {node: '>= 0.8'} - dev: false /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -11540,6 +13821,13 @@ packages: mimic-fn: 4.0.0 dev: true + /open@6.4.0: + resolution: {integrity: sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==} + engines: {node: '>=8'} + dependencies: + is-wsl: 1.1.0 + dev: true + /open@7.4.2: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} @@ -11569,6 +13857,35 @@ packages: type-check: 0.4.0 dev: true + /ora@5.3.0: + resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} + engines: {node: '>=10'} + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.0 + is-interactive: 1.0.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + dev: true + + /ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.0 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + dev: true + /ora@6.3.1: resolution: {integrity: sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -11606,11 +13923,6 @@ packages: p-map: 2.1.0 dev: false - /p-finally@1.0.0: - resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} - engines: {node: '>=4'} - dev: false - /p-limit@1.3.0: resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} engines: {node: '>=4'} @@ -11637,6 +13949,13 @@ packages: yocto-queue: 1.0.0 dev: true + /p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + dependencies: + yocto-queue: 1.0.0 + dev: true + /p-locate@2.0.0: resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} engines: {node: '>=4'} @@ -11644,6 +13963,13 @@ packages: p-limit: 1.3.0 dev: true + /p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + dependencies: + p-limit: 2.3.0 + dev: true + /p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -11732,11 +14058,19 @@ packages: error-ex: 1.3.2 dev: true + /parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + dev: true + /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.22.13 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -11755,7 +14089,6 @@ packages: /parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} - dev: false /pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} @@ -11763,28 +14096,6 @@ packages: no-case: 3.0.4 tslib: 2.6.2 - /patch-package@8.0.0: - resolution: {integrity: sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==} - engines: {node: '>=14', npm: '>5'} - hasBin: true - dependencies: - '@yarnpkg/lockfile': 1.1.0 - chalk: 4.1.2 - ci-info: 3.8.0 - cross-spawn: 7.0.3 - find-yarn-workspace-root: 2.0.0 - fs-extra: 9.1.0 - json-stable-stringify: 1.0.2 - klaw-sync: 6.0.0 - minimist: 1.2.8 - open: 7.4.2 - rimraf: 2.7.1 - semver: 7.5.4 - slash: 2.0.0 - tmp: 0.0.33 - yaml: 2.3.1 - dev: true - /path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} dev: true @@ -11819,11 +14130,7 @@ packages: /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} - - /path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - dev: false + dev: true /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} @@ -11842,7 +14149,7 @@ packages: resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} engines: {node: '>=16 || 14 >=14.17'} dependencies: - lru-cache: 10.0.1 + lru-cache: 10.1.0 minipass: 7.0.3 dev: true @@ -11883,6 +14190,7 @@ packages: /performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + dev: true /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -11906,15 +14214,16 @@ packages: /pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} + dev: true /pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - dev: false /pify@5.0.0: resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} engines: {node: '>=10'} + dev: true /pinkie-promise@2.0.1: resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} @@ -11952,13 +14261,11 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - '@sentry/node': 7.75.0 + '@sentry/node': 7.99.0 commander: 2.20.3 pumpify: 2.0.1 split2: 3.2.2 through2: 3.0.2 - transitivePeerDependencies: - - supports-color dev: false /pino-std-serializers@4.0.0: @@ -11983,8 +14290,8 @@ packages: sonic-boom: 2.8.0 thread-stream: 0.15.2 - /pino@8.16.1: - resolution: {integrity: sha512-3bKsVhBmgPjGV9pyn4fO/8RtoVDR8ssW1ev819FsRXlRNgW8gR/9Kx+gCK4UPWd4JjrRDLWpzd/pb1AyWm3MGA==} + /pino@8.19.0: + resolution: {integrity: sha512-oswmokxkav9bADfJ2ifrvfHUwad6MLp73Uat0IkQWY3iAw5xTRoznXbXksZs8oaOUMpmhVWD+PZogNzllWpJaA==} hasBin: true dependencies: atomic-sleep: 1.0.0 @@ -11992,7 +14299,7 @@ packages: on-exit-leak-free: 2.1.0 pino-abstract-transport: 1.1.0 pino-std-serializers: 6.2.2 - process-warning: 2.2.0 + process-warning: 3.0.0 quick-format-unescaped: 4.0.4 real-require: 0.2.0 safe-stable-stringify: 2.4.3 @@ -12004,6 +14311,13 @@ packages: engines: {node: '>= 6'} dev: true + /pkg-dir@3.0.0: + resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} + engines: {node: '>=6'} + dependencies: + find-up: 3.0.0 + dev: true + /pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -12014,7 +14328,7 @@ packages: resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} dependencies: jsonc-parser: 3.2.0 - mlly: 1.4.0 + mlly: 1.4.2 pathe: 1.1.1 dev: true @@ -12032,6 +14346,12 @@ packages: /pngjs@5.0.0: resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} engines: {node: '>=10.13.0'} + dev: true + + /pony-cause@2.1.10: + resolution: {integrity: sha512-3IKLNXclQgkU++2fSi93sQ6BznFuxSLB11HdvZQ6JW/spahf/P1pAHBQEahr20rs0htZW0UDkM1HmA+nZkXKsw==} + engines: {node: '>=12.0.0'} + dev: true /postcss-load-config@4.0.1: resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} @@ -12046,20 +14366,30 @@ packages: optional: true dependencies: lilconfig: 2.1.0 - yaml: 2.3.2 + yaml: 2.3.4 + dev: true + + /postcss@8.4.32: + resolution: {integrity: sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 dev: true - /postcss@8.4.27: - resolution: {integrity: sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==} + /postcss@8.4.35: + resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.6 + nanoid: 3.3.7 picocolors: 1.0.0 source-map-js: 1.0.2 dev: true /preact@10.16.0: resolution: {integrity: sha512-XTSj3dJ4roKIC93pald6rWuB2qQJO9gO2iLLyTe87MrjQN+HklueLsmskbywEWqCHlclgz3/M4YLL2iBr9UmMA==} + dev: true /preferred-pm@3.0.3: resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} @@ -12083,26 +14413,27 @@ packages: fast-diff: 1.2.0 dev: true - /prettier-plugin-solidity@1.0.0-beta.18(prettier@2.8.8): - resolution: {integrity: sha512-ezWdsG/jIeClmYBzg8V9Voy8jujt+VxWF8OS3Vld+C3c+3cPVib8D9l8ahTod7O5Df1anK9zo+WiiS5wb1mLmg==} - engines: {node: '>=12'} - peerDependencies: - prettier: ^2.3.0 - dependencies: - '@solidity-parser/parser': 0.13.2 - emoji-regex: 9.2.2 - escape-string-regexp: 4.0.0 - prettier: 2.8.8 - semver: 7.5.4 - solidity-comments-extractor: 0.0.7 - string-width: 4.2.3 - dev: true - /prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} hasBin: true + /prettier@3.1.1: + resolution: {integrity: sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /pretty-format@26.6.2: + resolution: {integrity: sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==} + engines: {node: '>= 10'} + dependencies: + '@jest/types': 26.6.2 + ansi-regex: 5.0.1 + ansi-styles: 4.3.0 + react-is: 17.0.2 + dev: true + /pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12121,6 +14452,14 @@ packages: react-is: 18.2.0 dev: true + /process-nextick-args@1.0.7: + resolution: {integrity: sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==} + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + /process-on-spawn@1.0.0: resolution: {integrity: sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==} engines: {node: '>=8'} @@ -12131,8 +14470,8 @@ packages: /process-warning@1.0.0: resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} - /process-warning@2.2.0: - resolution: {integrity: sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==} + /process-warning@3.0.0: + resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} /process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} @@ -12145,11 +14484,19 @@ packages: tdigest: 0.1.1 dev: false - /promise@8.1.0: - resolution: {integrity: sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==} + /promise@8.3.0: + resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} dependencies: asap: 2.0.6 - dev: false + dev: true + + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true /prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -12169,6 +14516,7 @@ packages: /proxy-compare@2.5.1: resolution: {integrity: sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA==} + dev: true /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -12184,13 +14532,13 @@ packages: /psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + dev: true /pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} dependencies: end-of-stream: 1.4.4 once: 1.4.0 - dev: false /pumpify@2.0.1: resolution: {integrity: sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==} @@ -12209,9 +14557,25 @@ packages: engines: {node: '>=6'} dev: true - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + dev: true + + /qr-code-styling@1.6.0-rc.1: + resolution: {integrity: sha512-ModRIiW6oUnsP18QzrRYZSc/CFKFKIdj7pUs57AEVH20ajlglRpN3HukjHk0UbNMTlKGuaYl7Gt6/O5Gg2NU2Q==} + dependencies: + qrcode-generator: 1.4.4 + dev: true + + /qrcode-generator@1.4.4: + resolution: {integrity: sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==} + dev: true + + /qrcode-terminal-nooctal@0.12.1: + resolution: {integrity: sha512-jy/kkD0iIMDjTucB+5T6KBsnirlhegDH47vHgrj5MejchSQmi/EAMM0xMFeePgV9CJkkAapNakpVUWYgHvtdKg==} + hasBin: true + dev: true /qrcode@1.5.3: resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} @@ -12222,6 +14586,7 @@ packages: encode-utf8: 1.0.3 pngjs: 5.0.0 yargs: 15.4.1 + dev: true /qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} @@ -12235,19 +14600,12 @@ packages: engines: {node: '>=0.6'} dependencies: side-channel: 1.0.4 + dev: true /qs@6.5.3: resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} engines: {node: '>=0.6'} - - /query-string@6.14.1: - resolution: {integrity: sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==} - engines: {node: '>=6'} - dependencies: - decode-uri-component: 0.2.2 - filter-obj: 1.1.0 - split-on-first: 1.1.0 - strict-uri-encode: 2.0.0 + dev: true /query-string@7.1.3: resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} @@ -12257,6 +14615,7 @@ packages: filter-obj: 1.1.0 split-on-first: 1.1.0 strict-uri-encode: 2.0.0 + dev: true /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} @@ -12265,6 +14624,12 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + /queue@6.0.2: + resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} + dependencies: + inherits: 2.0.4 + dev: true + /quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} @@ -12273,6 +14638,10 @@ packages: engines: {node: '>=8'} dev: false + /radix3@1.1.0: + resolution: {integrity: sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A==} + dev: true + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: @@ -12281,7 +14650,6 @@ packages: /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - dev: false /raw-body@2.5.1: resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} @@ -12302,6 +14670,16 @@ packages: iconv-lite: 0.4.24 unpipe: 1.0.0 + /react-devtools-core@4.28.5: + resolution: {integrity: sha512-cq/o30z9W2Wb4rzBefjv5fBalHU0rJGZCHAkf/RHSBWSSYwh8PlQTqqOJmgIIbBtpj27T6FIPXeomIjZtCNVqA==} + dependencies: + shell-quote: 1.8.1 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + /react-dom@18.2.0(react@18.2.0): resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -12317,7 +14695,7 @@ packages: peerDependencies: react: '>=16.13.1' dependencies: - '@babel/runtime': 7.22.6 + '@babel/runtime': 7.23.7 react: 17.0.2 dev: true @@ -12327,8 +14705,29 @@ packages: peerDependencies: react: '>=16.13.1' dependencies: - '@babel/runtime': 7.22.6 + '@babel/runtime': 7.23.7 + react: 18.2.0 + dev: true + + /react-i18next@13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.73.1)(react@18.2.0): + resolution: {integrity: sha512-CFJ5NDGJ2MUyBohEHxljOq/39NQ972rh1ajnadG9BjTk+UXbHLq4z5DKEbEQBDoIhUmmbuS/fIMJKo6VOax1HA==} + peerDependencies: + i18next: '>= 23.2.3' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@babel/runtime': 7.23.7 + html-parse-stringify: 3.0.1 + i18next: 22.5.1 react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-native: 0.73.1(@babel/core@7.22.10)(@babel/preset-env@7.23.7)(react@18.2.0) dev: true /react-is@16.13.1: @@ -12337,12 +14736,104 @@ packages: /react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - dev: false /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true + /react-native-codegen@0.71.6(@babel/preset-env@7.23.7): + resolution: {integrity: sha512-e5pR4VldIhEaFctfSAEgxbng0uG4gjBQxAHes3EKLdosH/Av90pQfSe9IDVdFIngvNPzt8Y14pNjrtqov/yNIg==} + dependencies: + '@babel/parser': 7.23.6 + flow-parser: 0.185.2 + jscodeshift: 0.14.0(@babel/preset-env@7.23.7) + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@babel/preset-env' + - supports-color + dev: true + + /react-native-webview@11.26.1(react-native@0.73.1)(react@18.2.0): + resolution: {integrity: sha512-hC7BkxOpf+z0UKhxFSFTPAM4shQzYmZHoELa6/8a/MspcjEP7ukYKpuSUTLDywQditT8yI9idfcKvfZDKQExGw==} + peerDependencies: + react: '*' + react-native: '*' + dependencies: + escape-string-regexp: 2.0.0 + invariant: 2.2.4 + react: 18.2.0 + react-native: 0.73.1(@babel/core@7.22.10)(@babel/preset-env@7.23.7)(react@18.2.0) + dev: true + + /react-native@0.73.1(@babel/core@7.22.10)(@babel/preset-env@7.23.7)(react@18.2.0): + resolution: {integrity: sha512-nLl9O2yKRh1nMXwsk4SUiD0ddd19RqlKgNU9AU8bTK/zD2xwnVOG56YK1/22SN67niWyoeG83vVg1eTk+S6ReA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + react: 18.2.0 + dependencies: + '@jest/create-cache-key-function': 29.7.0 + '@react-native-community/cli': 12.3.0 + '@react-native-community/cli-platform-android': 12.3.0 + '@react-native-community/cli-platform-ios': 12.3.0 + '@react-native/assets-registry': 0.73.1 + '@react-native/codegen': 0.73.2(@babel/preset-env@7.23.7) + '@react-native/community-cli-plugin': 0.73.11(@babel/core@7.22.10)(@babel/preset-env@7.23.7) + '@react-native/gradle-plugin': 0.73.4 + '@react-native/js-polyfills': 0.73.1 + '@react-native/normalize-colors': 0.73.2 + '@react-native/virtualized-lists': 0.73.4(react-native@0.73.1) + abort-controller: 3.0.0 + anser: 1.4.10 + ansi-regex: 5.0.1 + base64-js: 1.5.1 + deprecated-react-native-prop-types: 5.0.0 + event-target-shim: 5.0.1 + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + jest-environment-node: 29.7.0 + jsc-android: 250231.0.0 + memoize-one: 5.2.1 + metro-runtime: 0.80.3 + metro-source-map: 0.80.3 + mkdirp: 0.5.6 + nullthrows: 1.1.1 + pretty-format: 26.6.2 + promise: 8.3.0 + react: 18.2.0 + react-devtools-core: 4.28.5 + react-refresh: 0.14.0 + react-shallow-renderer: 16.15.0(react@18.2.0) + regenerator-runtime: 0.13.11 + scheduler: 0.24.0-canary-efb381bbf-20230505 + stacktrace-parser: 0.1.10 + whatwg-fetch: 3.6.17 + ws: 6.2.2 + yargs: 17.7.2 + transitivePeerDependencies: + - '@babel/core' + - '@babel/preset-env' + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /react-refresh@0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + dev: true + + /react-shallow-renderer@16.15.0(react@18.2.0): + resolution: {integrity: sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + object-assign: 4.1.1 + react: 18.2.0 + react-is: 18.2.0 + dev: true + /react@17.0.2: resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==} engines: {node: '>=0.10.0'} @@ -12401,6 +14892,30 @@ packages: strip-bom: 3.0.0 dev: false + /readable-stream@2.3.3: + resolution: {integrity: sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==} + dependencies: + core-util-is: 1.0.2 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 1.0.7 + safe-buffer: 5.1.2 + string_decoder: 1.0.3 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.2 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + /readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -12426,6 +14941,10 @@ packages: picomatch: 2.3.1 dev: true + /readline@1.3.0: + resolution: {integrity: sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==} + dev: true + /real-require@0.1.0: resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} engines: {node: '>= 12.13.0'} @@ -12434,6 +14953,16 @@ packages: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} + /recast@0.21.5: + resolution: {integrity: sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg==} + engines: {node: '>= 4'} + dependencies: + ast-types: 0.15.2 + esprima: 4.0.1 + source-map: 0.6.1 + tslib: 2.6.2 + dev: true + /redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -12441,11 +14970,17 @@ packages: indent-string: 4.0.0 strip-indent: 3.0.0 - /redeyed@2.1.1: - resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} + /redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + dev: true + + /redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} dependencies: - esprima: 4.0.1 - dev: false + redis-errors: 1.2.0 + dev: true /reduce-flatten@2.0.0: resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} @@ -12464,8 +14999,29 @@ packages: which-builtin-type: 1.1.3 dev: true + /regenerate-unicode-properties@10.1.1: + resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + dev: true + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + /regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + dependencies: + '@babel/runtime': 7.23.7 + dev: true /regexp-tree@0.1.27: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} @@ -12485,9 +15041,16 @@ packages: engines: {node: '>=8'} dev: true - /regextras@0.8.0: - resolution: {integrity: sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==} - engines: {node: '>=0.1.14'} + /regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 dev: true /regjsparser@0.10.0: @@ -12497,6 +15060,13 @@ packages: jsesc: 0.5.0 dev: true + /regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + /release-zalgo@1.0.0: resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} engines: {node: '>=4'} @@ -12542,30 +15112,6 @@ packages: engines: {node: '>=0.10'} dev: true - /request-promise-core@1.1.4(request@2.88.2): - resolution: {integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==} - engines: {node: '>=0.10.0'} - peerDependencies: - request: ^2.34 - dependencies: - lodash: 4.17.21 - request: 2.88.2 - dev: false - - /request-promise@4.2.6(request@2.88.2): - resolution: {integrity: sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==} - engines: {node: '>=0.10.0'} - deprecated: request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 - peerDependencies: - request: ^2.34 - dependencies: - bluebird: 3.7.2 - request: 2.88.2 - request-promise-core: 1.1.4(request@2.88.2) - stealthy-require: 1.1.1 - tough-cookie: 2.5.0 - dev: false - /request@2.88.2: resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} engines: {node: '>= 6'} @@ -12591,6 +15137,7 @@ packages: tough-cookie: 2.5.0 tunnel-agent: 0.6.0 uuid: 3.4.0 + dev: true /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} @@ -12629,6 +15176,11 @@ packages: global-modules: 1.0.0 dev: true + /resolve-from@3.0.0: + resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} + engines: {node: '>=4'} + dev: true + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -12652,7 +15204,7 @@ packages: resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} hasBin: true dependencies: - is-core-module: 2.13.0 + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: true @@ -12669,7 +15221,7 @@ packages: resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} hasBin: true dependencies: - is-core-module: 2.13.0 + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: true @@ -12698,6 +15250,13 @@ packages: resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} dev: true + /rimraf@2.6.3: + resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + /rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} hasBin: true @@ -12740,50 +15299,65 @@ packages: dependencies: bn.js: 5.2.1 - /rollup@3.28.0: - resolution: {integrity: sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} + /rollup-plugin-visualizer@5.12.0: + resolution: {integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==} + engines: {node: '>=14'} hasBin: true - optionalDependencies: - fsevents: 2.3.3 + peerDependencies: + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rollup: + optional: true + dependencies: + open: 8.4.2 + picomatch: 2.3.1 + source-map: 0.7.4 + yargs: 17.7.2 dev: true - /rpc-websockets@7.5.1: - resolution: {integrity: sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w==} - dependencies: - '@babel/runtime': 7.22.6 - eventemitter3: 4.0.7 - uuid: 8.3.2 - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + /rollup@4.5.1: + resolution: {integrity: sha512-0EQribZoPKpb5z1NW/QYm3XSR//Xr8BeEXU49Lc/mQmpmVVG5jPUVrpc2iptup/0WMrY9mzas0fxH+TjYvG2CA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true optionalDependencies: - bufferutil: 4.0.7 - utf-8-validate: 5.0.10 + '@rollup/rollup-android-arm-eabi': 4.5.1 + '@rollup/rollup-android-arm64': 4.5.1 + '@rollup/rollup-darwin-arm64': 4.5.1 + '@rollup/rollup-darwin-x64': 4.5.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.5.1 + '@rollup/rollup-linux-arm64-gnu': 4.5.1 + '@rollup/rollup-linux-arm64-musl': 4.5.1 + '@rollup/rollup-linux-x64-gnu': 4.5.1 + '@rollup/rollup-linux-x64-musl': 4.5.1 + '@rollup/rollup-win32-arm64-msvc': 4.5.1 + '@rollup/rollup-win32-ia32-msvc': 4.5.1 + '@rollup/rollup-win32-x64-msvc': 4.5.1 + fsevents: 2.3.3 + dev: true /rrweb-cssom@0.6.0: resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} dev: true - /run-parallel-limit@1.1.0: - resolution: {integrity: sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==} + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 + + /rust-verkle-wasm@0.0.1: + resolution: {integrity: sha512-BN6fiTsxcd2dCECz/cHtGTt9cdLJR925nh7iAuRcj8ymKw7OOaPmCneQZ7JePOJ/ia27TjEL91VdOi88Yf+mcA==} dev: true - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + /rustbn-wasm@0.2.0: + resolution: {integrity: sha512-FThvYFNTqrEKGqXuseeg0zR7yROh/6U1617mCHF68OVqrN1tNKRN7Tdwy4WayPVsCmmK+eMxtIZX1qL6JxTkMg==} dependencies: - queue-microtask: 1.2.3 + '@scure/base': 1.1.3 + dev: true /rustbn.js@0.2.0: resolution: {integrity: sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==} dev: true - /rxjs@6.6.7: - resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} - engines: {npm: '>=2.0.0'} - dependencies: - tslib: 1.14.1 - /safe-array-concat@1.0.0: resolution: {integrity: sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==} engines: {node: '>=0.4'} @@ -12799,9 +15373,6 @@ packages: /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - /safe-json-utils@1.1.1: - resolution: {integrity: sha512-SAJWGKDs50tAbiDXLf89PDwt9XYkWyANFWVzn4dTXl5QyI8t2o/bW5/OJl3lvc2WVU4MEpTo9Yz5NVFNsp+OJQ==} - /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: @@ -12828,6 +15399,12 @@ packages: dependencies: loose-envify: 1.4.0 + /scheduler@0.24.0-canary-efb381bbf-20230505: + resolution: {integrity: sha512-ABvovCDe/k9IluqSh4/ISoq8tIJnW8euVAWYt5j/bg6dRnqwQwiGO1F/V4AyK96NGF/FB04FhOUDuWj8IKfABA==} + dependencies: + loose-envify: 1.4.0 + dev: true + /scrypt-js@3.0.1: resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} @@ -12841,6 +15418,16 @@ packages: node-gyp-build: 4.6.0 dev: true + /secp256k1@5.0.0: + resolution: {integrity: sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==} + engines: {node: '>=14.0.0'} + requiresBuild: true + dependencies: + elliptic: 6.5.4 + node-addon-api: 5.1.0 + node-gyp-build: 4.6.0 + dev: true + /seedrandom@3.0.5: resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==} dev: true @@ -12863,16 +15450,8 @@ packages: hasBin: true dev: true - /semver@7.5.3: - resolution: {integrity: sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} engines: {node: '>=10'} hasBin: true dependencies: @@ -12897,7 +15476,6 @@ packages: statuses: 2.0.1 transitivePeerDependencies: - supports-color - dev: false /sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} @@ -12906,6 +15484,11 @@ packages: tslib: 2.6.2 upper-case-first: 2.0.2 + /serialize-error@2.1.0: + resolution: {integrity: sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==} + engines: {node: '>=0.10.0'} + dev: true + /serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: @@ -12922,7 +15505,6 @@ packages: send: 0.18.0 transitivePeerDependencies: - supports-color - dev: false /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -12939,6 +15521,14 @@ packages: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 + dev: true + + /shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + dependencies: + kind-of: 6.0.3 + dev: true /shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} @@ -12964,8 +15554,12 @@ packages: engines: {node: '>=8'} dev: true - /shiki@0.14.3: - resolution: {integrity: sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==} + /shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + dev: true + + /shiki@0.14.7: + resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} dependencies: ansi-sequence-parser: 1.1.1 jsonc-parser: 3.2.0 @@ -12992,9 +15586,8 @@ packages: engines: {node: '>=14'} dev: true - /slash@2.0.0: - resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} - engines: {node: '>=6'} + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} dev: true /slash@3.0.0: @@ -13006,6 +15599,15 @@ packages: engines: {node: '>=12'} dev: true + /slice-ansi@2.1.0: + resolution: {integrity: sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==} + engines: {node: '>=6'} + dependencies: + ansi-styles: 3.2.1 + astral-regex: 1.0.0 + is-fullwidth-code-point: 2.0.0 + dev: true + /slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} @@ -13014,12 +15616,20 @@ packages: is-fullwidth-code-point: 4.0.0 dev: true + /slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + dev: true + /smartwrap@2.0.2: resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} engines: {node: '>=6'} hasBin: true dependencies: - array.prototype.flat: 1.3.1 + array.prototype.flat: 1.3.2 breakword: 1.0.5 grapheme-splitter: 1.0.4 strip-ansi: 6.0.1 @@ -13033,6 +15643,30 @@ packages: dot-case: 3.0.4 tslib: 2.6.2 + /socket.io-client@4.7.3(bufferutil@4.0.8)(utf-8-validate@6.0.3): + resolution: {integrity: sha512-nU+ywttCyBitXIl9Xe0RSEfek4LneYkJxCeNnKCuhwoH4jGXO1ipIUw/VA/+Vvv2G1MTym11fzFC0SxkrcfXDw==} + engines: {node: '>=10.0.0'} + dependencies: + '@socket.io/component-emitter': 3.1.0 + debug: 4.3.4(supports-color@8.1.1) + engine.io-client: 6.5.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) + socket.io-parser: 4.2.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /socket.io-parser@4.2.4: + resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} + engines: {node: '>=10.0.0'} + dependencies: + '@socket.io/component-emitter': 3.1.0 + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + dev: true + /solc@0.4.26: resolution: {integrity: sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==} hasBin: true @@ -13051,7 +15685,7 @@ packages: dependencies: command-exists: 1.2.9 commander: 3.0.2 - follow-redirects: 1.15.2(debug@4.3.4) + follow-redirects: 1.15.5(debug@4.3.4) fs-extra: 0.30.0 js-sha3: 0.8.0 memorystream: 0.3.1 @@ -13069,7 +15703,7 @@ packages: dependencies: command-exists: 1.2.9 commander: 8.3.0 - follow-redirects: 1.15.2(debug@4.3.4) + follow-redirects: 1.15.5(debug@4.3.4) js-sha3: 0.8.0 memorystream: 0.3.1 semver: 5.7.2 @@ -13078,10 +15712,6 @@ packages: - debug dev: true - /solidity-comments-extractor@0.0.7: - resolution: {integrity: sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==} - dev: true - /sonic-boom@2.8.0: resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} dependencies: @@ -13102,10 +15732,22 @@ packages: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 + dev: true + + /source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + dev: true /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: true /source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} @@ -13148,12 +15790,20 @@ packages: spdx-exceptions: 2.3.0 spdx-license-ids: 3.0.10 + /spdx-expression-parse@4.0.0: + resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.10 + dev: true + /spdx-license-ids@3.0.10: resolution: {integrity: sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==} /split-on-first@1.1.0: resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} engines: {node: '>=6'} + dev: true /split2@3.2.2: resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} @@ -13182,11 +15832,23 @@ packages: jsbn: 0.1.1 safer-buffer: 2.1.2 tweetnacl: 0.14.5 + dev: true + + /stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true /stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true + /stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + dev: true + /stacktrace-parser@0.1.10: resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==} engines: {node: '>=6'} @@ -13194,12 +15856,21 @@ packages: type-fest: 0.7.1 dev: true + /standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + dev: true + + /statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + dev: true + /statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - /std-env@3.3.3: - resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==} + /std-env@3.6.0: + resolution: {integrity: sha512-aFZ19IgVmhdB2uX599ve2kE6BIE3YMnQ6Gp6BURhW/oIzpXGKr878TQfAQZn1+i0Flcc/UKUy1gOlcfaUBCryg==} dev: true /stdin-discarder@0.1.0: @@ -13209,11 +15880,6 @@ packages: bl: 5.1.0 dev: true - /stealthy-require@1.1.1: - resolution: {integrity: sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==} - engines: {node: '>=0.10.0'} - dev: false - /stop-iteration-iterator@1.0.0: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} @@ -13221,12 +15887,6 @@ packages: internal-slot: 1.0.5 dev: false - /stream-browserify@3.0.0: - resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} - dependencies: - inherits: 2.0.4 - readable-stream: 3.6.2 - /stream-shift@1.0.1: resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} @@ -13244,6 +15904,7 @@ packages: /strict-uri-encode@2.0.0: resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} engines: {node: '>=4'} + dev: true /string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} @@ -13280,6 +15941,15 @@ packages: strip-ansi: 7.1.0 dev: true + /string-width@7.0.0: + resolution: {integrity: sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==} + engines: {node: '>=18'} + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + dev: true + /string.prototype.matchall@4.0.8: resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} dependencies: @@ -13315,6 +15985,18 @@ packages: define-properties: 1.2.0 es-abstract: 1.22.1 + /string_decoder@1.0.3: + resolution: {integrity: sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: @@ -13327,6 +16009,13 @@ packages: ansi-regex: 2.1.1 dev: true + /strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + dependencies: + ansi-regex: 4.1.1 + dev: true + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -13356,11 +16045,6 @@ packages: engines: {node: '>=8'} dev: true - /strip-eof@1.0.0: - resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} - engines: {node: '>=0.10.0'} - dev: false - /strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -13388,17 +16072,16 @@ packages: engines: {node: '>=8'} dev: true - /strip-json-comments@4.0.0: - resolution: {integrity: sha512-LzWcbfMbAsEDTRmhjWIioe8GcDRl0fa35YMXFoJKDdiD/quGFmjJjdgPjFJJNwCMaLyQqFIDqCdHD2V4HfLgYA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - - /strip-literal@1.0.1: - resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} + /strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} dependencies: acorn: 8.10.0 dev: true + /strnum@1.0.5: + resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + dev: true + /strong-log-transformer@2.1.0: resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} engines: {node: '>=4'} @@ -13409,6 +16092,10 @@ packages: through: 2.3.8 dev: true + /stylis@4.2.0: + resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + dev: true + /sucrase@3.34.0: resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==} engines: {node: '>=8'} @@ -13423,6 +16110,10 @@ packages: ts-interface-checker: 0.1.13 dev: true + /sudo-prompt@9.2.1: + resolution: {integrity: sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==} + dev: true + /superagent@8.1.2: resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} engines: {node: '>=6.4.0 <13 || >=14'} @@ -13436,20 +16127,18 @@ packages: methods: 1.1.2 mime: 2.6.0 qs: 6.11.2 - semver: 7.5.4 + semver: 7.6.0 transitivePeerDependencies: - supports-color dev: true - /superstruct@0.14.2: - resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} - /superstruct@1.0.3: resolution: {integrity: sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg==} engines: {node: '>=14.0.0'} + dev: true - /supertest@6.3.3: - resolution: {integrity: sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==} + /supertest@6.3.4: + resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==} engines: {node: '>=6.4.0'} dependencies: methods: 1.1.2 @@ -13475,14 +16164,7 @@ packages: engines: {node: '>=10'} dependencies: has-flag: 4.0.0 - - /supports-hyperlinks@1.0.1: - resolution: {integrity: sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==} - engines: {node: '>=4'} - dependencies: - has-flag: 2.0.0 - supports-color: 5.5.0 - dev: false + dev: true /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} @@ -13531,11 +16213,34 @@ packages: bintrees: 1.0.1 dev: false + /temp-dir@2.0.0: + resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} + engines: {node: '>=8'} + dev: true + + /temp@0.8.4: + resolution: {integrity: sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==} + engines: {node: '>=6.0.0'} + dependencies: + rimraf: 2.6.3 + dev: true + /term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} dev: false + /terser@5.26.0: + resolution: {integrity: sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.5 + acorn: 8.10.0 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + /test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -13550,9 +16255,6 @@ packages: deprecated: testrpc has been renamed to ganache-cli, please use this package from now on. dev: true - /text-encoding-utf-8@1.0.2: - resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} - /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -13580,6 +16282,17 @@ packages: dependencies: real-require: 0.2.0 + /throat@5.0.0: + resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} + dev: true + + /through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + dev: true + /through2@3.0.2: resolution: {integrity: sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==} dependencies: @@ -13589,18 +16302,19 @@ packages: /through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true - /tinybench@2.5.0: - resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} + /tinybench@2.5.1: + resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==} dev: true - /tinypool@0.7.0: - resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + /tinypool@0.8.2: + resolution: {integrity: sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==} engines: {node: '>=14.0.0'} dev: true - /tinyspy@2.1.1: - resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} + /tinyspy@2.2.0: + resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==} engines: {node: '>=14.0.0'} dev: true @@ -13617,6 +16331,10 @@ packages: rimraf: 3.0.2 dev: true + /tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -13628,9 +16346,6 @@ packages: dependencies: is-number: 7.0.0 - /toggle-selection@1.0.6: - resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} - /toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -13640,14 +16355,15 @@ packages: engines: {node: '>=0.8'} dependencies: psl: 1.9.0 - punycode: 2.3.0 + punycode: 2.3.1 + dev: true /tough-cookie@4.1.3: resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'} dependencies: psl: 1.9.0 - punycode: 2.3.0 + punycode: 2.3.1 universalify: 0.2.0 url-parse: 1.5.10 dev: true @@ -13658,14 +16374,14 @@ packages: /tr46@1.0.1: resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: true - /tr46@4.1.1: - resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} - engines: {node: '>=14'} + /tr46@5.0.0: + resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + engines: {node: '>=18'} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: true /traverse@0.6.6: @@ -13691,13 +16407,13 @@ packages: resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} dev: true - /ts-api-utils@1.0.1(typescript@5.2.2): + /ts-api-utils@1.0.1(typescript@5.3.3): resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==} engines: {node: '>=16.13.0'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.2.2 + typescript: 5.3.3 dev: true /ts-command-line-args@2.5.1: @@ -13710,16 +16426,12 @@ packages: string-format: 2.0.0 dev: true - /ts-essentials@1.0.4: - resolution: {integrity: sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==} - dev: false - - /ts-essentials@7.0.3(typescript@5.2.2): + /ts-essentials@7.0.3(typescript@5.3.3): resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} peerDependencies: typescript: '>=3.7.0' dependencies: - typescript: 5.2.2 + typescript: 5.3.3 dev: true /ts-interface-checker@0.1.13: @@ -13736,11 +16448,11 @@ packages: mocha: 10.2.0 ts-node: 7.0.1 optionalDependencies: - tsconfig-paths: 3.14.2 + tsconfig-paths: 3.15.0 dev: true - /ts-node@10.9.1(@types/node@20.8.9)(typescript@5.2.2): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + /ts-node@10.9.2(@types/node@20.11.17)(typescript@5.3.3): + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: '@swc/core': '>=1.2.50' @@ -13758,14 +16470,14 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.8.9 + '@types/node': 20.11.17 acorn: 8.10.0 - acorn-walk: 8.2.0 + acorn-walk: 8.3.0 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.2.2 + typescript: 5.3.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 dev: true @@ -13785,23 +16497,8 @@ packages: yn: 2.0.0 dev: true - /ts-node@8.10.2(typescript@5.2.2): - resolution: {integrity: sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==} - engines: {node: '>=6.0.0'} - hasBin: true - peerDependencies: - typescript: '>=2.7' - dependencies: - arg: 4.1.3 - diff: 4.0.2 - make-error: 1.3.6 - source-map-support: 0.5.21 - typescript: 5.2.2 - yn: 3.1.1 - dev: false - - /tsconfig-paths@3.14.2: - resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} + /tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} requiresBuild: true dependencies: '@types/json5': 0.0.29 @@ -13821,6 +16518,7 @@ packages: /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} @@ -13829,15 +16527,18 @@ packages: resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} dev: true - /tsup@7.2.0(@swc/core@1.3.95)(typescript@5.2.2): - resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==} - engines: {node: '>=16.14'} + /tsup@8.0.1(@swc/core@1.4.6)(typescript@5.3.3): + resolution: {integrity: sha512-hvW7gUSG96j53ZTSlT4j/KL0q1Q2l6TqGBFc6/mu/L46IoNWqLLUzLRLP1R8Q7xrJTmkDxxDoojV5uCVs1sVOg==} + engines: {node: '>=18'} hasBin: true peerDependencies: + '@microsoft/api-extractor': ^7.36.0 '@swc/core': ^1 postcss: ^8.4.12 - typescript: '>=4.1.0' + typescript: '>=4.5.0' peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true '@swc/core': optional: true postcss: @@ -13845,34 +16546,34 @@ packages: typescript: optional: true dependencies: - '@swc/core': 1.3.95 - bundle-require: 4.0.1(esbuild@0.18.15) + '@swc/core': 1.4.6 + bundle-require: 4.0.1(esbuild@0.19.7) cac: 6.7.14 chokidar: 3.5.3 debug: 4.3.4(supports-color@8.1.1) - esbuild: 0.18.15 + esbuild: 0.19.7 execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 postcss-load-config: 4.0.1 resolve-from: 5.0.0 - rollup: 3.28.0 + rollup: 4.5.1 source-map: 0.8.0-beta.0 sucrase: 3.34.0 tree-kill: 1.2.2 - typescript: 5.2.2 + typescript: 5.3.3 transitivePeerDependencies: - supports-color - ts-node dev: true - /tsx@3.14.0: - resolution: {integrity: sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==} + /tsx@4.7.0: + resolution: {integrity: sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==} + engines: {node: '>=18.0.0'} hasBin: true dependencies: - esbuild: 0.18.20 + esbuild: 0.19.10 get-tsconfig: 4.7.2 - source-map-support: 0.5.21 optionalDependencies: fsevents: 2.3.3 dev: true @@ -13895,6 +16596,7 @@ packages: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: safe-buffer: 5.2.1 + dev: true /tweetnacl-util@0.15.1: resolution: {integrity: sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==} @@ -13902,6 +16604,7 @@ packages: /tweetnacl@0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + dev: true /tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} @@ -13946,9 +16649,9 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} - /type-fest@1.4.0: - resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} - engines: {node: '>=10'} + /type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} dev: true /type-is@1.6.18: @@ -13959,7 +16662,7 @@ packages: mime-types: 2.1.35 dev: false - /typechain@8.3.1(typescript@5.2.2): + /typechain@8.3.1(typescript@5.3.3): resolution: {integrity: sha512-fA7clol2IP/56yq6vkMTR+4URF1nGjV82Wx6Rf09EsqD4tkzMAvEaqYxVFCavJm/1xaRga/oD55K+4FtuXwQOQ==} hasBin: true peerDependencies: @@ -13974,8 +16677,8 @@ packages: mkdirp: 1.0.4 prettier: 2.8.8 ts-command-line-args: 2.5.1 - ts-essentials: 7.0.3(typescript@5.2.2) - typescript: 5.2.2 + ts-essentials: 7.0.3(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true @@ -14018,19 +16721,20 @@ packages: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} dependencies: is-typedarray: 1.0.0 + dev: true - /typedoc@0.25.2(typescript@5.2.2): - resolution: {integrity: sha512-286F7BeATBiWe/qC4PCOCKlSTwfnsLbC/4cZ68oGBbvAqb9vV33quEOXx7q176OXotD+JdEerdQ1OZGJ818lnA==} + /typedoc@0.25.7(typescript@5.3.3): + resolution: {integrity: sha512-m6A6JjQRg39p2ZVRIN3NKXgrN8vzlHhOS+r9ymUYtcUP/TIQPvWSq7YgE5ZjASfv5Vd5BW5xrir6Gm2XNNcOow==} engines: {node: '>= 16'} hasBin: true peerDependencies: - typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x + typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x dependencies: lunr: 2.3.9 marked: 4.3.0 minimatch: 9.0.3 - shiki: 0.14.3 - typescript: 5.2.2 + shiki: 0.14.7 + typescript: 5.3.3 dev: true /typescript@4.9.5: @@ -14039,8 +16743,8 @@ packages: hasBin: true dev: true - /typescript@5.2.2: - resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} engines: {node: '>=14.17'} hasBin: true @@ -14054,18 +16758,15 @@ packages: engines: {node: '>=8'} dev: true - /uc.micro@1.0.6: - resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} - dev: true - - /ufo@1.1.2: - resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} + /ufo@1.3.2: + resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} dev: true /uint8arrays@3.1.1: resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} dependencies: multiformats: 9.9.0 + dev: true /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} @@ -14075,12 +16776,12 @@ packages: has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 - /underscore@1.13.4: - resolution: {integrity: sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==} + /uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} dev: true - /undici-types@5.25.3: - resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==} + /underscore@1.13.4: + resolution: {integrity: sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==} dev: true /undici-types@5.26.5: @@ -14093,6 +16794,43 @@ packages: busboy: 1.6.0 dev: true + /unenv@1.8.0: + resolution: {integrity: sha512-uIGbdCWZfhRRmyKj1UioCepQ0jpq638j/Cf0xFTn4zD1nGJ2lSdzYHLzfdXN791oo/0juUiSWW1fBklXMTsuqg==} + dependencies: + consola: 3.2.3 + defu: 6.1.3 + mime: 3.0.0 + node-fetch-native: 1.4.1 + pathe: 1.1.1 + dev: true + + /unfetch@4.2.0: + resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} + dev: true + + /unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + /unified@9.2.2: resolution: {integrity: sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==} dependencies: @@ -14140,13 +16878,79 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - /update-browserslist-db@1.0.11(browserslist@4.21.10): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + /unstorage@1.10.1(idb-keyval@6.2.1): + resolution: {integrity: sha512-rWQvLRfZNBpF+x8D3/gda5nUCQL2PgXy2jNG4U7/Rc9BGEv9+CAJd0YyGCROUBKs9v49Hg8huw3aih5Bf5TAVw==} + peerDependencies: + '@azure/app-configuration': ^1.4.1 + '@azure/cosmos': ^4.0.0 + '@azure/data-tables': ^13.2.2 + '@azure/identity': ^3.3.2 + '@azure/keyvault-secrets': ^4.7.0 + '@azure/storage-blob': ^12.16.0 + '@capacitor/preferences': ^5.0.6 + '@netlify/blobs': ^6.2.0 + '@planetscale/database': ^1.11.0 + '@upstash/redis': ^1.23.4 + '@vercel/kv': ^0.2.3 + idb-keyval: ^6.2.1 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/kv': + optional: true + idb-keyval: + optional: true + dependencies: + anymatch: 3.1.3 + chokidar: 3.5.3 + destr: 2.0.2 + h3: 1.9.0 + idb-keyval: 6.2.1 + ioredis: 5.3.2 + listhen: 1.5.5 + lru-cache: 10.1.0 + mri: 1.2.0 + node-fetch-native: 1.4.1 + ofetch: 1.3.3 + ufo: 1.3.2 + transitivePeerDependencies: + - supports-color + dev: true + + /untun@0.1.2: + resolution: {integrity: sha512-wLAMWvxfqyTiBODA1lg3IXHQtjggYLeTK7RnSfqtOXixWJ3bAa2kK/HHmOOg19upteqO3muLvN6O/icbyQY33Q==} + hasBin: true + dependencies: + citty: 0.1.5 + consola: 3.2.3 + pathe: 1.1.1 + dev: true + + /update-browserslist-db@1.0.13(browserslist@4.22.2): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.21.10 + browserslist: 4.22.2 escalade: 3.1.1 picocolors: 1.0.0 dev: true @@ -14165,14 +16969,15 @@ packages: dependencies: tslib: 2.6.2 + /uqr@0.1.2: + resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} + dev: true + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - punycode: 2.3.0 - - /url-join@4.0.1: - resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} - dev: false + punycode: 2.3.1 + dev: true /url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} @@ -14199,22 +17004,24 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: react: 18.2.0 + dev: true - /utf-8-validate@5.0.10: - resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + /utf-8-validate@5.0.7: + resolution: {integrity: sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==} engines: {node: '>=6.14.2'} requiresBuild: true dependencies: node-gyp-build: 4.6.0 + dev: true + optional: true - /utf-8-validate@5.0.7: - resolution: {integrity: sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==} + /utf-8-validate@6.0.3: + resolution: {integrity: sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==} engines: {node: '>=6.14.2'} requiresBuild: true dependencies: node-gyp-build: 4.6.0 dev: true - optional: true /utf8@3.0.0: resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} @@ -14234,44 +17041,28 @@ packages: /utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} - dev: false /uuid@3.4.0: resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. hasBin: true + dev: true /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true + dev: true /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true - /v8-compile-cache@2.3.0: - resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} - dev: true - /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: spdx-correct: 3.1.1 spdx-expression-parse: 3.0.1 - /valtio@1.10.5(react@18.2.0): - resolution: {integrity: sha512-jTp0k63VXf4r5hPoaC6a6LCG4POkVSh629WLi1+d5PlajLsbynTMd7qAgEiOSPxzoX5iNvbN7iZ/k/g29wrNiQ==} - engines: {node: '>=12.20.0'} - peerDependencies: - react: '>=16.8' - peerDependenciesMeta: - react: - optional: true - dependencies: - proxy-compare: 2.5.1 - react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) - /valtio@1.11.2(react@18.2.0): resolution: {integrity: sha512-1XfIxnUXzyswPAPXo1P3Pdx2mq/pIqZICkWN60Hby0d9Iqb+MEIpqgYVlbflvHdrp2YR/q3jyKWRPJJ100yxaw==} engines: {node: '>=12.20.0'} @@ -14292,7 +17083,6 @@ packages: /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - dev: false /verror@1.10.0: resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} @@ -14301,6 +17091,7 @@ packages: assert-plus: 1.0.0 core-util-is: 1.0.2 extsprintf: 1.4.0 + dev: true /vfile-message@2.0.4: resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} @@ -14318,181 +17109,78 @@ packages: vfile-message: 2.0.4 dev: true - /viem@1.18.0(typescript@5.2.2)(zod@3.22.3): - resolution: {integrity: sha512-NeKi5RFj7fHdsnk5pojivHFLkTyBWyehxeSE/gSPTDJKCWnR9i+Ra0W++VwN5ghciEG55O8b4RdpYhzGmhnr7A==} + /viem@1.20.3(typescript@5.3.3): + resolution: {integrity: sha512-7CrmeCb2KYkeCgUmUyb1hsf+IX/PLwi+Np+Vm4YUTPeG82y3HRSgGHSaCOp3d0YtR2kXD3nv9y5kE7LBFE+wWw==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: typescript: optional: true dependencies: - '@adraffy/ens-normalize': 1.9.4 + '@adraffy/ens-normalize': 1.10.0 '@noble/curves': 1.2.0 '@noble/hashes': 1.3.2 '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 - abitype: 0.9.8(typescript@5.2.2)(zod@3.22.3) + abitype: 0.9.8(typescript@5.3.3)(zod@3.22.4) isows: 1.0.3(ws@8.13.0) - typescript: 5.2.2 - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + typescript: 5.3.3 + ws: 8.13.0 transitivePeerDependencies: - bufferutil - utf-8-validate - zod dev: true - /viem@1.18.0(typescript@5.2.2)(zod@3.22.4): - resolution: {integrity: sha512-NeKi5RFj7fHdsnk5pojivHFLkTyBWyehxeSE/gSPTDJKCWnR9i+Ra0W++VwN5ghciEG55O8b4RdpYhzGmhnr7A==} + /viem@2.7.19(typescript@5.3.3)(zod@3.22.4): + resolution: {integrity: sha512-UOMeqy+8p2709ra2j9HEOL1NfjsXZzlJ8gwR6YO/zXH8KIZvyzW07t4iQARF5+ShVZ/7+/1ec8oPjVi1M//33A==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: typescript: optional: true dependencies: - '@adraffy/ens-normalize': 1.9.4 + '@adraffy/ens-normalize': 1.10.0 '@noble/curves': 1.2.0 '@noble/hashes': 1.3.2 '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 - abitype: 0.9.8(typescript@5.2.2)(zod@3.22.4) - isows: 1.0.3(ws@8.13.0) - typescript: 5.2.2 - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - zod - - /vite-node@0.34.1(@types/node@20.8.9): - resolution: {integrity: sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==} - engines: {node: '>=v14.18.0'} - hasBin: true - dependencies: - cac: 6.7.14 - debug: 4.3.4(supports-color@8.1.1) - mlly: 1.4.0 - pathe: 1.1.1 - picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.8.9) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: true - - /vite-node@0.34.2(@types/node@20.8.8): - resolution: {integrity: sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA==} - engines: {node: '>=v14.18.0'} - hasBin: true - dependencies: - cac: 6.7.14 - debug: 4.3.4(supports-color@8.1.1) - mlly: 1.4.0 - pathe: 1.1.1 - picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.8.8) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: true - - /vite-node@0.34.2(@types/node@20.8.9): - resolution: {integrity: sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA==} - engines: {node: '>=v14.18.0'} - hasBin: true - dependencies: - cac: 6.7.14 - debug: 4.3.4(supports-color@8.1.1) - mlly: 1.4.0 - pathe: 1.1.1 - picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.8.9) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: true - - /vite-node@0.34.4(@types/node@20.8.8): - resolution: {integrity: sha512-ho8HtiLc+nsmbwZMw8SlghESEE3KxJNp04F/jPUCLVvaURwt0d+r9LxEqCX5hvrrOQ0GSyxbYr5ZfRYhQ0yVKQ==} - engines: {node: '>=v14.18.0'} - hasBin: true - dependencies: - cac: 6.7.14 - debug: 4.3.4(supports-color@8.1.1) - mlly: 1.4.0 - pathe: 1.1.1 - picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.8.8) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: true - - /vite@4.4.10(@types/node@20.8.8): - resolution: {integrity: sha512-TzIjiqx9BEXF8yzYdF2NTf1kFFbjMjUSV0LFZ3HyHoI3SGSPLnnFUKiIQtL3gl2AjHvMrprOvQ3amzaHgQlAxw==} - engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true + abitype: 1.0.0(typescript@5.3.3)(zod@3.22.4) + isows: 1.0.3(ws@8.13.0) + typescript: 5.3.3 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + /vite-node@1.2.2(@types/node@20.11.17): + resolution: {integrity: sha512-1as4rDTgVWJO3n1uHmUYqq7nsFgINQ9u+mRcXpjeOMJUmviqNKjcZB7UfRZrlM7MjYXMKpuWp5oGkjaFLnjawg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true dependencies: - '@types/node': 20.8.8 - esbuild: 0.18.20 - postcss: 8.4.27 - rollup: 3.28.0 - optionalDependencies: - fsevents: 2.3.3 + cac: 6.7.14 + debug: 4.3.4(supports-color@8.1.1) + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 5.1.5(@types/node@20.11.17) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser dev: true - /vite@4.5.0(@types/node@20.8.8): - resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} - engines: {node: ^14.18.0 || >=16.0.0} + /vite@5.0.12(@types/node@20.11.17): + resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': '>= 14' + '@types/node': ^18.0.0 || >=20.0.0 less: '*' lightningcss: ^1.21.0 sass: '*' @@ -14515,20 +17203,20 @@ packages: terser: optional: true dependencies: - '@types/node': 20.8.8 - esbuild: 0.18.20 - postcss: 8.4.27 - rollup: 3.28.0 + '@types/node': 20.11.17 + esbuild: 0.19.10 + postcss: 8.4.32 + rollup: 4.5.1 optionalDependencies: fsevents: 2.3.3 dev: true - /vite@4.5.0(@types/node@20.8.9): - resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} - engines: {node: ^14.18.0 || >=16.0.0} + /vite@5.1.5(@types/node@20.11.17): + resolution: {integrity: sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': '>= 14' + '@types/node': ^18.0.0 || >=20.0.0 less: '*' lightningcss: ^1.21.0 sass: '*' @@ -14551,94 +17239,29 @@ packages: terser: optional: true dependencies: - '@types/node': 20.8.9 - esbuild: 0.18.20 - postcss: 8.4.27 - rollup: 3.28.0 + '@types/node': 20.11.17 + esbuild: 0.19.10 + postcss: 8.4.35 + rollup: 4.5.1 optionalDependencies: fsevents: 2.3.3 dev: true - /vitest@0.34.1: - resolution: {integrity: sha512-G1PzuBEq9A75XSU88yO5G4vPT20UovbC/2osB2KEuV/FisSIIsw7m5y2xMdB7RsAGHAfg2lPmp2qKr3KWliVlQ==} - engines: {node: '>=v14.18.0'} + /vitest@1.2.2(@types/node@20.11.17)(jsdom@24.0.0): + resolution: {integrity: sha512-d5Ouvrnms3GD9USIK36KG8OZ5bEvKEkITFtnGv56HFaSlbItJuYr7hv2Lkn903+AvRAgSixiamozUVfORUekjw==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@vitest/browser': '*' - '@vitest/ui': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': ^1.0.0 + '@vitest/ui': ^1.0.0 happy-dom: '*' jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true - dependencies: - '@types/chai': 4.3.8 - '@types/chai-subset': 1.3.3 - '@types/node': 20.8.9 - '@vitest/expect': 0.34.1 - '@vitest/runner': 0.34.1 - '@vitest/snapshot': 0.34.1 - '@vitest/spy': 0.34.1 - '@vitest/utils': 0.34.1 - acorn: 8.10.0 - acorn-walk: 8.2.0 - cac: 6.7.14 - chai: 4.3.10 - debug: 4.3.4(supports-color@8.1.1) - local-pkg: 0.4.3 - magic-string: 0.30.1 - pathe: 1.1.1 - picocolors: 1.0.0 - std-env: 3.3.3 - strip-literal: 1.0.1 - tinybench: 2.5.0 - tinypool: 0.7.0 - vite: 4.5.0(@types/node@20.8.9) - vite-node: 0.34.1(@types/node@20.8.9) - why-is-node-running: 2.2.2 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: true - - /vitest@0.34.2: - resolution: {integrity: sha512-WgaIvBbjsSYMq/oiMlXUI7KflELmzM43BEvkdC/8b5CAod4ryAiY2z8uR6Crbi5Pjnu5oOmhKa9sy7uk6paBxQ==} - engines: {node: '>=v14.18.0'} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@vitest/browser': '*' - '@vitest/ui': '*' - happy-dom: '*' - jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' - peerDependenciesMeta: - '@edge-runtime/vm': + '@types/node': optional: true '@vitest/browser': optional: true @@ -14648,36 +17271,29 @@ packages: optional: true jsdom: optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true dependencies: - '@types/chai': 4.3.8 - '@types/chai-subset': 1.3.3 - '@types/node': 20.8.9 - '@vitest/expect': 0.34.2 - '@vitest/runner': 0.34.2 - '@vitest/snapshot': 0.34.2 - '@vitest/spy': 0.34.2 - '@vitest/utils': 0.34.2 - acorn: 8.10.0 - acorn-walk: 8.2.0 + '@types/node': 20.11.17 + '@vitest/expect': 1.2.2 + '@vitest/runner': 1.2.2 + '@vitest/snapshot': 1.2.2 + '@vitest/spy': 1.2.2 + '@vitest/utils': 1.2.2 + acorn-walk: 8.3.2 cac: 6.7.14 chai: 4.3.10 debug: 4.3.4(supports-color@8.1.1) - local-pkg: 0.4.3 - magic-string: 0.30.1 + execa: 8.0.1 + jsdom: 24.0.0 + local-pkg: 0.5.0 + magic-string: 0.30.5 pathe: 1.1.1 picocolors: 1.0.0 - std-env: 3.3.3 - strip-literal: 1.0.1 - tinybench: 2.5.0 - tinypool: 0.7.0 - vite: 4.5.0(@types/node@20.8.9) - vite-node: 0.34.2(@types/node@20.8.9) + std-env: 3.6.0 + strip-literal: 1.3.0 + tinybench: 2.5.1 + tinypool: 0.8.2 + vite: 5.0.12(@types/node@20.11.17) + vite-node: 1.2.2(@types/node@20.11.17) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -14689,135 +17305,13 @@ packages: - terser dev: true - /vitest@0.34.2(jsdom@22.1.0): - resolution: {integrity: sha512-WgaIvBbjsSYMq/oiMlXUI7KflELmzM43BEvkdC/8b5CAod4ryAiY2z8uR6Crbi5Pjnu5oOmhKa9sy7uk6paBxQ==} - engines: {node: '>=v14.18.0'} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@vitest/browser': '*' - '@vitest/ui': '*' - happy-dom: '*' - jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true - dependencies: - '@types/chai': 4.3.7 - '@types/chai-subset': 1.3.3 - '@types/node': 20.8.8 - '@vitest/expect': 0.34.2 - '@vitest/runner': 0.34.2 - '@vitest/snapshot': 0.34.2 - '@vitest/spy': 0.34.2 - '@vitest/utils': 0.34.2 - acorn: 8.10.0 - acorn-walk: 8.2.0 - cac: 6.7.14 - chai: 4.3.10 - debug: 4.3.4(supports-color@8.1.1) - jsdom: 22.1.0 - local-pkg: 0.4.3 - magic-string: 0.30.1 - pathe: 1.1.1 - picocolors: 1.0.0 - std-env: 3.3.3 - strip-literal: 1.0.1 - tinybench: 2.5.0 - tinypool: 0.7.0 - vite: 4.5.0(@types/node@20.8.8) - vite-node: 0.34.2(@types/node@20.8.8) - why-is-node-running: 2.2.2 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser + /vlq@1.0.1: + resolution: {integrity: sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==} dev: true - /vitest@0.34.4: - resolution: {integrity: sha512-SE/laOsB6995QlbSE6BtkpXDeVNLJc1u2LHRG/OpnN4RsRzM3GQm4nm3PQCK5OBtrsUqnhzLdnT7se3aeNGdlw==} - engines: {node: '>=v14.18.0'} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@vitest/browser': '*' - '@vitest/ui': '*' - happy-dom: '*' - jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true - dependencies: - '@types/chai': 4.3.7 - '@types/chai-subset': 1.3.3 - '@types/node': 20.8.8 - '@vitest/expect': 0.34.4 - '@vitest/runner': 0.34.4 - '@vitest/snapshot': 0.34.4 - '@vitest/spy': 0.34.4 - '@vitest/utils': 0.34.4 - acorn: 8.10.0 - acorn-walk: 8.2.0 - cac: 6.7.14 - chai: 4.3.9 - debug: 4.3.4(supports-color@8.1.1) - local-pkg: 0.4.3 - magic-string: 0.30.1 - pathe: 1.1.1 - picocolors: 1.0.0 - std-env: 3.3.3 - strip-literal: 1.0.1 - tinybench: 2.5.0 - tinypool: 0.7.0 - vite: 4.4.10(@types/node@20.8.8) - vite-node: 0.34.4(@types/node@20.8.8) - why-is-node-running: 2.2.2 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser + /void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} dev: true /vscode-oniguruma@1.7.0: @@ -14828,55 +17322,68 @@ packages: resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} dev: true - /w3c-xmlserializer@4.0.0: - resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} - engines: {node: '>=14'} + /w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} dependencies: - xml-name-validator: 4.0.0 + xml-name-validator: 5.0.0 dev: true - /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): - resolution: {integrity: sha512-+2UkZG9eA3tKqXj1wvlvI8mL0Bcff7Tf5CKfUOyQsdKcY+J5rfwYYya25G+jja57umpHFtfxRaL7xDkNjehrRg==} + /wagmi@2.5.5(@tanstack/react-query@5.17.1)(react-dom@18.2.0)(react-native@0.73.1)(react@18.2.0)(typescript@5.3.3)(viem@2.7.19): + resolution: {integrity: sha512-U9F5+e4bFXhSvIAWaImP4oCDXnOG/7q1xnBlkWBwbGy+oWg3BBiD01BZUnkplFGu6scSZ+TPURGtOkwH0rnxBQ==} peerDependencies: - react: '>=17.0.0' - typescript: '>=4.9.4' - viem: ~0.3.18 + '@tanstack/react-query': '>=5.0.0' + react: '>=18' + typescript: '>=5.0.4' + viem: 2.x peerDependenciesMeta: typescript: optional: true dependencies: - '@tanstack/query-sync-storage-persister': 4.29.25 - '@tanstack/react-query': 4.29.25(react-dom@18.2.0)(react@18.2.0) - '@tanstack/react-query-persist-client': 4.29.25(@tanstack/react-query@4.29.25) - '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) - abitype: 0.8.1(typescript@5.2.2) + '@tanstack/react-query': 5.17.1(react@18.2.0) + '@wagmi/connectors': 4.1.12(@wagmi/core@2.6.3)(react-dom@18.2.0)(react-native@0.73.1)(react@18.2.0)(typescript@5.3.3)(viem@2.7.19) + '@wagmi/core': 2.6.3(react@18.2.0)(typescript@5.3.3)(viem@2.7.19) react: 18.2.0 - typescript: 5.2.2 + typescript: 5.3.3 use-sync-external-store: 1.2.0(react@18.2.0) - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) + viem: 2.7.19(typescript@5.3.3)(zod@3.22.4) transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@tanstack/query-core' + - '@types/react' + - '@upstash/redis' + - '@vercel/kv' - bufferutil - - debug - encoding - immer - - lokijs - react-dom - react-native + - rollup - supports-color - utf-8-validate - zod + dev: true + + /walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + dev: true /wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: defaults: 1.0.4 - /web-streams-polyfill@3.2.1: - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} - engines: {node: '>= 8'} - dev: true - /web3-core@4.1.0: resolution: {integrity: sha512-fVGmPInWNlT/lGj1aKDmmSDIqYO5iwVlZ3NdD4q/u/i9j8/o7a8S0jz8Js8oS/fqoBqF25WSJ8il2KKdSDGzXw==} engines: {node: '>=14', npm: '>=6.12.0'} @@ -14886,7 +17393,7 @@ packages: web3-providers-http: 4.0.4 web3-providers-ws: 4.0.4 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 optionalDependencies: web3-providers-ipc: 4.0.5 @@ -14910,7 +17417,6 @@ packages: dependencies: web3-types: 1.1.1 dev: false - optional: true /web3-eth-abi@4.1.0: resolution: {integrity: sha512-qd+zCGKi2YsL2KkbM5M8Qztles/WPOvFpw6Lg3a904DRIVxkIvWdQfoK0JbA6Vbt8DSVKCc4rpZ15D6I/wfBKQ==} @@ -14920,7 +17426,7 @@ packages: '@ethersproject/bignumber': 5.7.0 web3-errors: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 dev: false /web3-eth-accounts@4.0.3: @@ -14945,7 +17451,7 @@ packages: ethereum-cryptography: 2.1.2 web3-errors: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 dev: false @@ -14958,7 +17464,7 @@ packages: web3-eth: 4.1.0 web3-eth-abi: 4.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 transitivePeerDependencies: - bufferutil @@ -14970,14 +17476,14 @@ packages: resolution: {integrity: sha512-CCaPO/EQZe4wJQp4SUVB75brEWPh+Sd/dUW6/vI41liurr8Q4yD86j2FfoQQScgQhvByMs4OKNQ3QuTVRIyVKA==} engines: {node: '>=14', npm: '>=6.12.0'} dependencies: - '@adraffy/ens-normalize': 1.9.4 + '@adraffy/ens-normalize': 1.10.0 web3-core: 4.1.0 web3-errors: 1.1.0 web3-eth: 4.1.0 web3-eth-contract: 4.0.4 web3-net: 4.0.4 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 transitivePeerDependencies: - bufferutil @@ -14991,7 +17497,7 @@ packages: dependencies: web3-errors: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 dev: false @@ -15003,7 +17509,7 @@ packages: web3-eth: 4.1.0 web3-rpc-methods: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 transitivePeerDependencies: - bufferutil @@ -15045,7 +17551,7 @@ packages: web3-providers-ws: 4.0.4 web3-rpc-methods: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 transitivePeerDependencies: - bufferutil @@ -15060,7 +17566,7 @@ packages: web3-core: 4.1.0 web3-rpc-methods: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 transitivePeerDependencies: - bufferutil - encoding @@ -15074,7 +17580,7 @@ packages: cross-fetch: 3.1.8 web3-errors: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 transitivePeerDependencies: - encoding dev: false @@ -15095,11 +17601,11 @@ packages: engines: {node: '>=14', npm: '>=6.12.0'} dependencies: '@types/ws': 8.5.3 - isomorphic-ws: 5.0.0(ws@8.13.0) + isomorphic-ws: 5.0.0(ws@8.16.0) web3-errors: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + web3-utils: 4.0.5 + ws: 8.16.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -15128,7 +17634,6 @@ packages: engines: {node: '>=14', npm: '>=6.12.0'} requiresBuild: true dev: false - optional: true /web3-utils@1.10.1: resolution: {integrity: sha512-r6iUUw/uMnNcWXjhRv33Nyrhxq3VGOPBXeSzxhOXIci4SvC/LPTpROY0uTrMX7ztKyODYrHp8WhTkEf+ZnHssw==} @@ -15156,14 +17661,12 @@ packages: /web3-utils@4.0.5: resolution: {integrity: sha512-43xIM7rr3htYNzliVQLpWLQmEf4XX8IXgjvqLcEuC/xje14O5UQM4kamRCtz8v3JZN3X6QTfsV6Zgby67mVmCg==} engines: {node: '>=14', npm: '>=6.12.0'} - requiresBuild: true dependencies: ethereum-cryptography: 2.1.2 web3-errors: 1.1.1 web3-types: 1.1.1 web3-validator: 2.0.1 dev: false - optional: true /web3-validator@1.0.2: resolution: {integrity: sha512-orx1CQAEnwJUnl/8iF2II2zSA4wiooNJvFmVE0Dbmt/kE370SugIDViQP76snhxtouG2AXzz4GyKbPCMlLGh/A==} @@ -15198,7 +17701,6 @@ packages: web3-types: 1.1.1 zod: 3.22.4 dev: false - optional: true /web3@4.0.3: resolution: {integrity: sha512-rUMxui5f52yPWjiMRQV6xqIrTQSovYM2CNhl57y+xj/fGXNLbI1D5FsLPnUMZjMaFHJBTteaBxq/sTEaw/1jNA==} @@ -15226,6 +17728,21 @@ packages: - utf-8-validate dev: false + /webextension-polyfill-ts@0.25.0: + resolution: {integrity: sha512-ikQhwwHYkpBu00pFaUzIKY26I6L87DeRI+Q6jBT1daZUNuu8dSrg5U9l/ZbqdaQ1M/TTSPKeAa3kolP5liuedw==} + deprecated: This project has moved to @types/webextension-polyfill + dependencies: + webextension-polyfill: 0.7.0 + dev: true + + /webextension-polyfill@0.10.0: + resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} + dev: true + + /webextension-polyfill@0.7.0: + resolution: {integrity: sha512-su48BkMLxqzTTvPSE1eWxKToPS2Tv5DLGxKexLEVpwFd6Po6N8hhSLIvG6acPAg7qERoEaDL+Y5HQJeJeml5Aw==} + dev: true + /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -15238,9 +17755,9 @@ packages: engines: {node: '>=12'} dev: true - /whatwg-encoding@2.0.0: - resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} - engines: {node: '>=12'} + /whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} dependencies: iconv-lite: 0.6.3 dev: true @@ -15249,16 +17766,16 @@ packages: resolution: {integrity: sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ==} dev: true - /whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} + /whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} dev: true - /whatwg-url@12.0.1: - resolution: {integrity: sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==} - engines: {node: '>=14'} + /whatwg-url@14.0.0: + resolution: {integrity: sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==} + engines: {node: '>=18'} dependencies: - tr46: 4.1.1 + tr46: 5.0.0 webidl-conversions: 7.0.0 dev: true @@ -15359,6 +17876,13 @@ packages: stackback: 0.0.2 dev: true + /widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + dependencies: + string-width: 4.2.3 + dev: true + /window-size@0.2.0: resolution: {integrity: sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==} engines: {node: '>= 0.10.0'} @@ -15410,9 +17934,26 @@ packages: strip-ansi: 7.1.0 dev: true + /wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + dependencies: + ansi-styles: 6.2.1 + string-width: 7.0.0 + strip-ansi: 7.1.0 + dev: true + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + /write-file-atomic@2.4.3: + resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} + dependencies: + graceful-fs: 4.2.11 + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + /write-file-atomic@3.0.3: resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} dependencies: @@ -15422,6 +17963,20 @@ packages: typedarray-to-buffer: 3.1.5 dev: true + /ws@6.2.2: + resolution: {integrity: sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + async-limiter: 1.0.1 + dev: true + /ws@7.4.6: resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} engines: {node: '>=8.3.0'} @@ -15445,8 +18000,25 @@ packages: optional: true utf-8-validate: optional: true + dev: true + + /ws@8.11.0(bufferutil@4.0.8)(utf-8-validate@6.0.3): + resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + bufferutil: 4.0.8 + utf-8-validate: 6.0.3 + dev: true - /ws@8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10): + /ws@8.13.0: resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} engines: {node: '>=10.0.0'} peerDependencies: @@ -15457,19 +18029,33 @@ packages: optional: true utf-8-validate: optional: true - dependencies: - bufferutil: 4.0.7 - utf-8-validate: 5.0.10 - /xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} + /ws@8.16.0: + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + /xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} dev: true /xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} dev: true + /xmlhttprequest-ssl@2.0.0: + resolution: {integrity: sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==} + engines: {node: '>=0.4.0'} + dev: true + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -15501,18 +18087,8 @@ packages: engines: {node: '>= 6'} dev: true - /yaml@2.3.1: - resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} - engines: {node: '>= 14'} - dev: true - - /yaml@2.3.2: - resolution: {integrity: sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==} - engines: {node: '>= 14'} - dev: true - - /yaml@2.3.3: - resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==} + /yaml@2.3.4: + resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} engines: {node: '>= 14'} dev: true @@ -15622,6 +18198,7 @@ packages: /yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} + dev: true /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} @@ -15640,20 +18217,19 @@ packages: ethers: 5.7.2 dev: true - /zod@3.22.3: - resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} - dev: true - /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} - /zustand@4.3.9(react@18.2.0): - resolution: {integrity: sha512-Tat5r8jOMG1Vcsj8uldMyqYKC5IZvQif8zetmLHs9WoZlntTHmIoNM8TpLRY31ExncuUvUOXehd0kvahkuHjDw==} + /zustand@4.4.1(react@18.2.0): + resolution: {integrity: sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==} engines: {node: '>=12.7.0'} peerDependencies: + '@types/react': '>=16.8' immer: '>=9.0' react: '>=16.8' peerDependenciesMeta: + '@types/react': + optional: true immer: optional: true react: @@ -15661,6 +18237,7 @@ packages: dependencies: react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) + dev: true /zwitch@1.0.5: resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e7993650e8ce..d357a4260cd9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,4 @@ packages: - 'packages/*' - 'endpoint-monitor' - - 'op-exporter' - 'indexer/api-ts' diff --git a/proxyd/README.md b/proxyd/README.md index e3ec1caad533..4a3a84bafc49 100644 --- a/proxyd/README.md +++ b/proxyd/README.md @@ -9,7 +9,7 @@ This tool implements `proxyd`, an RPC request router and proxy. It does the foll 5. Re-write requests and responses to enforce consensus. 6. Load balance requests across backend services. 7. Cache immutable responses from backends. -8. Provides metrics the measure request latency, error rates, and the like. +8. Provides metrics to measure request latency, error rates, and the like. ## Usage diff --git a/proxyd/backend.go b/proxyd/backend.go index 6c699f0391b3..f00e951dbf11 100644 --- a/proxyd/backend.go +++ b/proxyd/backend.go @@ -17,14 +17,14 @@ import ( "sync" "time" + sw "github.com/ethereum-optimism/optimism/proxyd/pkg/avg-sliding-window" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" "github.com/gorilla/websocket" "github.com/prometheus/client_golang/prometheus" + "github.com/xaionaro-go/weightedshuffle" "golang.org/x/sync/semaphore" - - sw "github.com/ethereum-optimism/optimism/proxyd/pkg/avg-sliding-window" ) const ( @@ -139,6 +139,7 @@ type Backend struct { wsURL string authUsername string authPassword string + headers map[string]string client *LimitedHTTPClient dialer *websocket.Dialer maxRetries int @@ -159,6 +160,8 @@ type Backend struct { latencySlidingWindow *sw.AvgSlidingWindow networkRequestsSlidingWindow *sw.AvgSlidingWindow networkErrorsSlidingWindow *sw.AvgSlidingWindow + + weight int } type BackendOpt func(b *Backend) @@ -170,6 +173,12 @@ func WithBasicAuth(username, password string) BackendOpt { } } +func WithHeaders(headers map[string]string) BackendOpt { + return func(b *Backend) { + b.headers = headers + } +} + func WithTimeout(timeout time.Duration) BackendOpt { return func(b *Backend) { b.client.Timeout = timeout @@ -239,6 +248,12 @@ func WithConsensusForcedCandidate(forcedCandidate bool) BackendOpt { } } +func WithWeight(weight int) BackendOpt { + return func(b *Backend) { + b.weight = weight + } +} + func WithMaxDegradedLatencyThreshold(maxDegradedLatencyThreshold time.Duration) BackendOpt { return func(b *Backend) { b.maxDegradedLatencyThreshold = maxDegradedLatencyThreshold @@ -269,6 +284,8 @@ type indexedReqRes struct { res *RPCRes } +const proxydHealthzMethod = "proxyd_healthz" + const ConsensusGetReceiptsMethod = "consensus_getReceipts" const ReceiptsTargetDebugGetRawReceipts = "debug_getRawReceipts" @@ -535,6 +552,10 @@ func (b *Backend) doForward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool httpReq.Header.Set("content-type", "application/json") httpReq.Header.Set("X-Forwarded-For", xForwardedFor) + for name, value := range b.headers { + httpReq.Header.Set(name, value) + } + start := time.Now() httpRes, err := b.client.DoLimited(httpReq) if err != nil { @@ -683,9 +704,10 @@ func sortBatchRPCResponse(req []*RPCReq, res []*RPCRes) { } type BackendGroup struct { - Name string - Backends []*Backend - Consensus *ConsensusPoller + Name string + Backends []*Backend + WeightedRouting bool + Consensus *ConsensusPoller } func (bg *BackendGroup) Forward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool) ([]*RPCRes, string, error) { @@ -693,7 +715,7 @@ func (bg *BackendGroup) Forward(ctx context.Context, rpcReqs []*RPCReq, isBatch return nil, "", nil } - backends := bg.Backends + backends := bg.orderedBackendsForRequest() overriddenResponses := make([]*indexedReqRes, 0) rewrittenReqs := make([]*RPCReq, 0, len(rpcReqs)) @@ -701,7 +723,6 @@ func (bg *BackendGroup) Forward(ctx context.Context, rpcReqs []*RPCReq, isBatch if bg.Consensus != nil { // When `consensus_aware` is set to `true`, the backend group acts as a load balancer // serving traffic from any backend that agrees in the consensus group - backends = bg.loadBalancedConsensusGroup() // We also rewrite block tags to enforce compliance with consensus rctx := RewriteContext{ @@ -845,6 +866,27 @@ func (bg *BackendGroup) ProxyWS(ctx context.Context, clientConn *websocket.Conn, return nil, ErrNoBackends } +func weightedShuffle(backends []*Backend) { + weight := func(i int) float64 { + return float64(backends[i].weight) + } + + weightedshuffle.ShuffleInplace(backends, weight, nil) +} + +func (bg *BackendGroup) orderedBackendsForRequest() []*Backend { + if bg.Consensus != nil { + return bg.loadBalancedConsensusGroup() + } else if bg.WeightedRouting { + result := make([]*Backend, len(bg.Backends)) + copy(result, bg.Backends) + weightedShuffle(result) + return result + } else { + return bg.Backends + } +} + func (bg *BackendGroup) loadBalancedConsensusGroup() []*Backend { cg := bg.Consensus.GetConsensusGroup() @@ -872,6 +914,10 @@ func (bg *BackendGroup) loadBalancedConsensusGroup() []*Backend { backendsDegraded[i], backendsDegraded[j] = backendsDegraded[j], backendsDegraded[i] }) + if bg.WeightedRouting { + weightedShuffle(backendsHealthy) + } + // healthy are put into a priority position // degraded backends are used as fallback backendsHealthy = append(backendsHealthy, backendsDegraded...) diff --git a/proxyd/cache.go b/proxyd/cache.go index a93a39371357..5add4f23627e 100644 --- a/proxyd/cache.go +++ b/proxyd/cache.go @@ -21,8 +21,6 @@ type Cache interface { const ( // assuming an average RPCRes size of 3 KB memoryCacheLimit = 4096 - // Set a large ttl to avoid expirations. However, a ttl must be set for volatile-lru to take effect. - redisTTL = 30 * 7 * 24 * time.Hour ) type cache struct { @@ -49,10 +47,11 @@ func (c *cache) Put(ctx context.Context, key string, value string) error { type redisCache struct { rdb *redis.Client prefix string + ttl time.Duration } -func newRedisCache(rdb *redis.Client, prefix string) *redisCache { - return &redisCache{rdb, prefix} +func newRedisCache(rdb *redis.Client, prefix string, ttl time.Duration) *redisCache { + return &redisCache{rdb, prefix, ttl} } func (c *redisCache) namespaced(key string) string { @@ -78,7 +77,7 @@ func (c *redisCache) Get(ctx context.Context, key string) (string, error) { func (c *redisCache) Put(ctx context.Context, key string, value string) error { start := time.Now() - err := c.rdb.SetEx(ctx, c.namespaced(key), value, redisTTL).Err() + err := c.rdb.SetEx(ctx, c.namespaced(key), value, c.ttl).Err() redisCacheDurationSumm.WithLabelValues("SETEX").Observe(float64(time.Since(start).Milliseconds())) if err != nil { diff --git a/proxyd/cache_test.go b/proxyd/cache_test.go index da47e7c4d60d..1a5d543227ae 100644 --- a/proxyd/cache_test.go +++ b/proxyd/cache_test.go @@ -183,7 +183,7 @@ func TestRPCCacheUnsupportedMethod(t *testing.T) { name: "eth_call", req: &RPCReq{ JSONRPC: "2.0", - Method: "eth_gasPrice", + Method: "eth_call", ID: ID, }, }, diff --git a/proxyd/cmd/proxyd/main.go b/proxyd/cmd/proxyd/main.go index 10a1518cdb6f..3daa80b38710 100644 --- a/proxyd/cmd/proxyd/main.go +++ b/proxyd/cmd/proxyd/main.go @@ -1,17 +1,22 @@ package main import ( + "fmt" "net" "net/http" "net/http/pprof" "os" "os/signal" "strconv" + "strings" "syscall" "github.com/BurntSushi/toml" - "github.com/ethereum-optimism/optimism/proxyd" + "golang.org/x/exp/slog" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/proxyd" ) var ( @@ -23,12 +28,7 @@ var ( func main() { // Set up logger with a default INFO level in case we fail to parse flags. // Otherwise the final critical log won't show what the parsing error was. - log.Root().SetHandler( - log.LvlFilterHandler( - log.LvlInfo, - log.StreamHandler(os.Stdout, log.JSONFormat()), - ), - ) + proxyd.SetLogLevel(slog.LevelInfo) log.Info("starting proxyd", "version", GitVersion, "commit", GitCommit, "date", GitDate) @@ -42,19 +42,14 @@ func main() { } // update log level from config - logLevel, err := log.LvlFromString(config.Server.LogLevel) + logLevel, err := LevelFromString(config.Server.LogLevel) if err != nil { - logLevel = log.LvlInfo + logLevel = log.LevelInfo if config.Server.LogLevel != "" { log.Warn("invalid server.log_level set: " + config.Server.LogLevel) } } - log.Root().SetHandler( - log.LvlFilterHandler( - logLevel, - log.StreamHandler(os.Stdout, log.JSONFormat()), - ), - ) + proxyd.SetLogLevel(logLevel) if config.Server.EnablePprof { log.Info("starting pprof", "addr", "0.0.0.0", "port", "6060") @@ -79,6 +74,30 @@ func main() { shutdown() } +// LevelFromString returns the appropriate Level from a string name. +// Useful for parsing command line args and configuration files. +// It also converts strings to lowercase. +// Note: copied from op-service/log to avoid monorepo dependency +func LevelFromString(lvlString string) (slog.Level, error) { + lvlString = strings.ToLower(lvlString) // ignore case + switch lvlString { + case "trace", "trce": + return log.LevelTrace, nil + case "debug", "dbug": + return log.LevelDebug, nil + case "info": + return log.LevelInfo, nil + case "warn": + return log.LevelWarn, nil + case "error", "eror": + return log.LevelError, nil + case "crit": + return log.LevelCrit, nil + default: + return log.LevelDebug, fmt.Errorf("unknown level: %v", lvlString) + } +} + func StartPProf(hostname string, port int) *http.Server { mux := http.NewServeMux() diff --git a/proxyd/config.go b/proxyd/config.go index fefca9f6e500..3c622f86ddb6 100644 --- a/proxyd/config.go +++ b/proxyd/config.go @@ -22,14 +22,15 @@ type ServerConfig struct { MaxUpstreamBatchSize int `toml:"max_upstream_batch_size"` - EnableRequestLog bool `toml:"enable_request_log"` - MaxRequestBodyLogLen int `toml:"max_request_body_log_len"` - EnablePprof bool `toml:"enable_pprof"` + EnableRequestLog bool `toml:"enable_request_log"` + MaxRequestBodyLogLen int `toml:"max_request_body_log_len"` + EnablePprof bool `toml:"enable_pprof"` EnableXServedByHeader bool `toml:"enable_served_by_header"` } type CacheConfig struct { - Enabled bool `toml:"enabled"` + Enabled bool `toml:"enabled"` + TTL TOMLDuration `toml:"ttl"` } type RedisConfig struct { @@ -51,6 +52,7 @@ type RateLimitConfig struct { ExemptUserAgents []string `toml:"exempt_user_agents"` ErrorMessage string `toml:"error_message"` MethodOverrides map[string]*RateLimitMethodOverride `toml:"method_overrides"` + IPHeaderOverride string `toml:"ip_header_override"` } type RateLimitMethodOverride struct { @@ -82,17 +84,20 @@ type BackendOptions struct { } type BackendConfig struct { - Username string `toml:"username"` - Password string `toml:"password"` - RPCURL string `toml:"rpc_url"` - WSURL string `toml:"ws_url"` - WSPort int `toml:"ws_port"` - MaxRPS int `toml:"max_rps"` - MaxWSConns int `toml:"max_ws_conns"` - CAFile string `toml:"ca_file"` - ClientCertFile string `toml:"client_cert_file"` - ClientKeyFile string `toml:"client_key_file"` - StripTrailingXFF bool `toml:"strip_trailing_xff"` + Username string `toml:"username"` + Password string `toml:"password"` + RPCURL string `toml:"rpc_url"` + WSURL string `toml:"ws_url"` + WSPort int `toml:"ws_port"` + MaxRPS int `toml:"max_rps"` + MaxWSConns int `toml:"max_ws_conns"` + CAFile string `toml:"ca_file"` + ClientCertFile string `toml:"client_cert_file"` + ClientKeyFile string `toml:"client_key_file"` + StripTrailingXFF bool `toml:"strip_trailing_xff"` + Headers map[string]string `toml:"headers"` + + Weight int `toml:"weight"` ConsensusSkipPeerCountCheck bool `toml:"consensus_skip_peer_count"` ConsensusForcedCandidate bool `toml:"consensus_forced_candidate"` @@ -104,6 +109,8 @@ type BackendsConfig map[string]*BackendConfig type BackendGroupConfig struct { Backends []string `toml:"backends"` + WeightedRouting bool `toml:"weighted_routing"` + ConsensusAware bool `toml:"consensus_aware"` ConsensusAsyncHandler string `toml:"consensus_handler"` @@ -116,6 +123,7 @@ type BackendGroupConfig struct { ConsensusHA bool `toml:"consensus_ha"` ConsensusHAHeartbeatInterval TOMLDuration `toml:"consensus_ha_heartbeat_interval"` ConsensusHALockPeriod TOMLDuration `toml:"consensus_ha_lock_period"` + ConsensusHARedis RedisConfig `toml:"consensus_ha_redis"` } type BackendGroupsConfig map[string]*BackendGroupConfig @@ -129,6 +137,7 @@ type BatchConfig struct { // SenderRateLimitConfig configures the sender-based rate limiter // for eth_sendRawTransaction requests. +// To enable pre-eip155 transactions, add '0' to allowed_chain_ids. type SenderRateLimitConfig struct { Enabled bool Interval TOMLDuration diff --git a/proxyd/consensus_tracker.go b/proxyd/consensus_tracker.go index 158c31bdc683..77e0fdba9912 100644 --- a/proxyd/consensus_tracker.go +++ b/proxyd/consensus_tracker.go @@ -194,10 +194,12 @@ func (ct *RedisConsensusTracker) stateHeartbeat() { val, err := ct.client.Get(ct.ctx, key).Result() if err != nil && err != redis.Nil { log.Error("failed to read the lock", "err", err) + RecordGroupConsensusError(ct.backendGroup, "read_lock", err) if ct.leader { ok, err := ct.redlock.Unlock() if err != nil || !ok { log.Error("failed to release the lock after error", "err", err) + RecordGroupConsensusError(ct.backendGroup, "leader_release_lock", err) return } ct.leader = false @@ -210,9 +212,11 @@ func (ct *RedisConsensusTracker) stateHeartbeat() { ok, err := ct.redlock.Extend() if err != nil || !ok { log.Error("failed to extend lock", "err", err, "mutex", ct.redlock.Name(), "val", ct.redlock.Value()) + RecordGroupConsensusError(ct.backendGroup, "leader_extend_lock", err) ok, err := ct.redlock.Unlock() if err != nil || !ok { log.Error("failed to release the lock after error", "err", err) + RecordGroupConsensusError(ct.backendGroup, "leader_release_lock", err) return } ct.leader = false @@ -224,6 +228,7 @@ func (ct *RedisConsensusTracker) stateHeartbeat() { leaderName, err := ct.client.Get(ct.ctx, ct.key(fmt.Sprintf("leader:%s", val))).Result() if err != nil && err != redis.Nil { log.Error("failed to read the remote leader", "err", err) + RecordGroupConsensusError(ct.backendGroup, "read_leader", err) return } ct.leaderName = leaderName @@ -232,16 +237,19 @@ func (ct *RedisConsensusTracker) stateHeartbeat() { val, err := ct.client.Get(ct.ctx, ct.key(fmt.Sprintf("state:%s", val))).Result() if err != nil && err != redis.Nil { log.Error("failed to read the remote state", "err", err) + RecordGroupConsensusError(ct.backendGroup, "read_state", err) return } if val == "" { log.Error("remote state is missing (recent leader election maybe?)") + RecordGroupConsensusError(ct.backendGroup, "read_state_missing", err) return } state := &ConsensusTrackerState{} err = json.Unmarshal([]byte(val), state) if err != nil { log.Error("failed to unmarshal the remote state", "err", err) + RecordGroupConsensusError(ct.backendGroup, "read_unmarshal_state", err) return } @@ -316,13 +324,26 @@ func (ct *RedisConsensusTracker) postPayload(mutexVal string) { jsonState, err := json.Marshal(ct.local.state) if err != nil { log.Error("failed to marshal local", "err", err) + RecordGroupConsensusError(ct.backendGroup, "leader_marshal_local_state", err) + ct.leader = false + return + } + err = ct.client.Set(ct.ctx, ct.key(fmt.Sprintf("state:%s", mutexVal)), jsonState, ct.lockPeriod).Err() + if err != nil { + log.Error("failed to post the state", "err", err) + RecordGroupConsensusError(ct.backendGroup, "leader_post_state", err) ct.leader = false return } - ct.client.Set(ct.ctx, ct.key(fmt.Sprintf("state:%s", mutexVal)), jsonState, ct.lockPeriod) leader, _ := os.LookupEnv("HOSTNAME") - ct.client.Set(ct.ctx, ct.key(fmt.Sprintf("leader:%s", mutexVal)), leader, ct.lockPeriod) + err = ct.client.Set(ct.ctx, ct.key(fmt.Sprintf("leader:%s", mutexVal)), leader, ct.lockPeriod).Err() + if err != nil { + log.Error("failed to post the leader", "err", err) + RecordGroupConsensusError(ct.backendGroup, "leader_post_leader", err) + ct.leader = false + return + } log.Debug("posted state", "state", string(jsonState), "leader", leader) diff --git a/proxyd/example.config.toml b/proxyd/example.config.toml index cce4896926d5..b54b342f5189 100644 --- a/proxyd/example.config.toml +++ b/proxyd/example.config.toml @@ -98,6 +98,8 @@ backends = ["infura"] # consensus_max_update_threshold = "20s" # Maximum block lag, default 8 # consensus_max_block_lag = 16 +# Maximum block range (for eth_getLogs method), no default +# consensus_max_block_range = 20000 # Minimum peer count, default 3 # consensus_min_peer_count = 4 diff --git a/proxyd/go.mod b/proxyd/go.mod index cbab0d5c30d3..d207332e3570 100644 --- a/proxyd/go.mod +++ b/proxyd/go.mod @@ -6,7 +6,7 @@ require ( github.com/BurntSushi/toml v1.3.2 github.com/alicebob/miniredis v2.5.0+incompatible github.com/emirpasic/gods v1.18.1 - github.com/ethereum/go-ethereum v1.13.4 + github.com/ethereum/go-ethereum v1.13.8 github.com/go-redsync/redsync/v4 v4.10.0 github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb github.com/gorilla/mux v1.8.0 @@ -18,7 +18,9 @@ require ( github.com/rs/cors v1.10.1 github.com/stretchr/testify v1.8.4 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - golang.org/x/sync v0.4.0 + github.com/xaionaro-go/weightedshuffle v0.0.0-20211213010739-6a74fbc7d24a + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa + golang.org/x/sync v0.5.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -38,22 +40,23 @@ require ( github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.3.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/getsentry/sentry-go v0.25.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/gomodule/redigo v1.8.9 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.2.3 // indirect + github.com/holiman/uint256 v1.2.4 // indirect github.com/klauspost/compress v1.17.1 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -73,12 +76,11 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yuin/gopher-lua v1.1.0 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.14.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.15.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/proxyd/go.sum b/proxyd/go.sum index e759ce561aa5..9b7fd5e3a4cc 100644 --- a/proxyd/go.sum +++ b/proxyd/go.sum @@ -42,6 +42,8 @@ github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/Yj github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -60,12 +62,14 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.13.4 h1:25HJnaWVg3q1O7Z62LaaI6S9wVq8QCw3K88g8wEzrcM= -github.com/ethereum/go-ethereum v1.13.4/go.mod h1:I0U5VewuuTzvBtVzKo7b3hJzDhXOUtn9mJW7SsIPB0Q= +github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= +github.com/ethereum/go-ethereum v1.13.8/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= @@ -81,8 +85,6 @@ github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F4 github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= github.com/go-redsync/redsync/v4 v4.10.0 h1:hTeAak4C73mNBQSTq6KCKDFaiIlfC+z5yTTl8fCJuBs= github.com/go-redsync/redsync/v4 v4.10.0/go.mod h1:ZfayzutkgeBmEmBlUR3j+rF6kN44UUGtEdfzhBFZTPc= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -94,7 +96,6 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -103,7 +104,6 @@ github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs0 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= @@ -120,8 +120,8 @@ github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iP github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= -github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -138,7 +138,6 @@ github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= @@ -199,6 +198,8 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/xaionaro-go/weightedshuffle v0.0.0-20211213010739-6a74fbc7d24a h1:WS5nQycV+82Ndezq0UcMcGVG416PZgcJPqI/bLM824A= +github.com/xaionaro-go/weightedshuffle v0.0.0-20211213010739-6a74fbc7d24a/go.mod h1:0KAUfC65le2kMu4fnBxm7Xj3PkQ3MBpJbF5oMmqufBc= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= @@ -208,14 +209,14 @@ github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -223,14 +224,14 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -246,19 +247,19 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -270,9 +271,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/proxyd/integration_tests/smoke_test.go b/proxyd/integration_tests/smoke_test.go new file mode 100644 index 000000000000..5fed7571bcec --- /dev/null +++ b/proxyd/integration_tests/smoke_test.go @@ -0,0 +1,51 @@ +package integration_tests + +import ( + "fmt" + "io" + "os" + "strings" + "testing" + + "github.com/ethereum-optimism/optimism/proxyd" + "github.com/ethereum/go-ethereum/log" + "github.com/stretchr/testify/require" +) + +func TestInitProxyd(t *testing.T) { + goodBackend := NewMockBackend(BatchedResponseHandler(200, goodResponse)) + defer goodBackend.Close() + + require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", goodBackend.URL())) + + config := ReadConfig("smoke") + + sysStdOut := os.Stdout + r, w, err := os.Pipe() + require.NoError(t, err) + os.Stdout = w + + proxyd.SetLogLevel(log.LevelInfo) + + defer func() { + w.Close() + out, _ := io.ReadAll(r) + require.True(t, strings.Contains(string(out), "started proxyd")) + require.True(t, strings.Contains(string(out), "shutting down proxyd")) + fmt.Println(string(out)) + os.Stdout = sysStdOut + }() + + _, shutdown, err := proxyd.Start(config) + require.NoError(t, err) + defer shutdown() + + t.Run("initialization", func(t *testing.T) { + client := NewProxydClient("http://127.0.0.1:8545") + res, code, err := client.SendRPC(ethChainID, nil) + require.NoError(t, err) + require.Equal(t, 200, code) + require.NotNil(t, res) + }) + +} diff --git a/proxyd/integration_tests/testdata/sender_rate_limit.toml b/proxyd/integration_tests/testdata/sender_rate_limit.toml index 024858a1e76f..c99959d84a91 100644 --- a/proxyd/integration_tests/testdata/sender_rate_limit.toml +++ b/proxyd/integration_tests/testdata/sender_rate_limit.toml @@ -18,7 +18,7 @@ eth_chainId = "main" eth_sendRawTransaction = "main" [sender_rate_limit] +allowed_chain_ids = [0, 420] # adding 0 allows pre-EIP-155 transactions enabled = true interval = "1s" limit = 1 -allowed_chain_ids = [420] diff --git a/proxyd/integration_tests/testdata/smoke.toml b/proxyd/integration_tests/testdata/smoke.toml new file mode 100644 index 000000000000..a2187a25055d --- /dev/null +++ b/proxyd/integration_tests/testdata/smoke.toml @@ -0,0 +1,18 @@ +[server] +rpc_port = 8545 + +[backend] +response_timeout_seconds = 1 + +[backends] +[backends.good] +rpc_url = "$GOOD_BACKEND_RPC_URL" +ws_url = "$GOOD_BACKEND_RPC_URL" + +[backend_groups] +[backend_groups.main] +backends = ["good"] + +[rpc_method_mappings] +eth_chainId = "main" + diff --git a/proxyd/integration_tests/testdata/testdata.txt b/proxyd/integration_tests/testdata/testdata.txt index 7e31927baa10..14c91246b5f1 100644 --- a/proxyd/integration_tests/testdata/testdata.txt +++ b/proxyd/integration_tests/testdata/testdata.txt @@ -10,4 +10,5 @@ valid transaction data - simple send|{"jsonrpc":"2.0","method":"eth_sendRawTrans valid transaction data - contract call|{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0x02f8b28201a406849502f931849502f931830147f9948f3ddd0fbf3e78ca1d6cd17379ed88e261249b5280b84447e7ef2400000000000000000000000089c8b1b2774201bac50f627403eac1b732459cf70000000000000000000000000000000000000000000000056bc75e2d63100000c080a0473c95566026c312c9664cd61145d2f3e759d49209fe96011ac012884ec5b017a0763b58f6fa6096e6ba28ee08bfac58f58fb3b8bcef5af98578bdeaddf40bde42"],"id":1}|{"id": 123, "jsonrpc": "2.0", "result": "dummy"} valid chain id - simple send|{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0x02f8748201a415843b9aca31843b9aca3182520894f80267194936da1e98db10bce06f3147d580a62e880de0b6b3a764000080c001a0b50ee053102360ff5fedf0933b912b7e140c90fe57fa07a0cebe70dbd72339dda072974cb7bfe5c3dc54dde110e2b049408ccab8a879949c3b4d42a3a7555a618b"],"id":1}|{"id": 123, "jsonrpc": "2.0", "result": "dummy"} invalid chain id - simple send|{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0x02f87683ab41308217af84773594008504a817c80082520894be53e587975603a13d0923d0aa6d37c5233dd750865af3107a400080c001a04ae265f17e882b922d39f0f0cb058a6378df1dc89da8b8165ab6bc53851b426aa0682079486be2aa23bc7514477473362cc7d63afa12c99f7d8fb15e68d69d9a48"],"id":1}|{"jsonrpc":"2.0","error":{"code":-32000,"message":"invalid sender"},"id":1} +no chain id (pre eip-155) - simple send|{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0xf865808609184e72a00082271094000000000000000000000000000000000000000001001ba0d937ddb66e7788f917864b8e6974cac376b091154db1c25ff8429a6e61016e74a054ced39349e7658b7efceccfabc461e02418eb510124377949cfae8ccf1831af"],"id":1}|{"id": 123, "jsonrpc": "2.0", "result": "dummy"} batch with mixed results|[{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0x02f87683ab41308217af84773594008504a817c80082520894be53e587975603a13d0923d0aa6d37c5233dd750865af3107a400080c001a04ae265f17e882b922d39f0f0cb058a6378df1dc89da8b8165ab6bc53851b426aa0682079486be2aa23bc7514477473362cc7d63afa12c99f7d8fb15e68d69d9a48"],"id":1},{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0x02f8748201a415843b9aca31843b9aca3182520894f80267194936da1e98db10bce06f3147d580a62e880de0b6b3a764000080c001a0b50ee053102360ff5fedf0933b912b7e140c90fe57fa07a0cebe70dbd72339dda072974cb7bfe5c3dc54dde110e2b049408ccab8a879949c3b4d42a3a7555a618b"],"id":1},{"bad":"json"},{"jsonrpc":"2.0","method":"eth_fooTheBar","params":[],"id":123}]|[{"jsonrpc":"2.0","error":{"code":-32000,"message":"invalid sender"},"id":1},{"id": 123, "jsonrpc": "2.0", "result": "dummy"},{"jsonrpc":"2.0","error":{"code":-32600,"message":"invalid JSON-RPC version"},"id":null},{"jsonrpc":"2.0","error":{"code":-32001,"message":"rpc method is not whitelisted"},"id":123}] diff --git a/proxyd/integration_tests/util_test.go b/proxyd/integration_tests/util_test.go index db52d2f43bc6..36edce13ef78 100644 --- a/proxyd/integration_tests/util_test.go +++ b/proxyd/integration_tests/util_test.go @@ -10,13 +10,14 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/log" - + "github.com/BurntSushi/toml" "github.com/gorilla/websocket" + "github.com/stretchr/testify/require" + "golang.org/x/exp/slog" + + "github.com/ethereum/go-ethereum/log" - "github.com/BurntSushi/toml" "github.com/ethereum-optimism/optimism/proxyd" - "github.com/stretchr/testify/require" ) type ProxydHTTPClient struct { @@ -129,8 +130,10 @@ type WSMessage struct { Body []byte } -type ProxydWSClientOnMessage func(msgType int, data []byte) -type ProxydWSClientOnClose func(err error) +type ( + ProxydWSClientOnMessage func(msgType int, data []byte) + ProxydWSClientOnClose func(err error) +) func NewProxydWSClient( url string, @@ -183,11 +186,6 @@ func (h *ProxydWSClient) WriteControlMessage(msgType int, msg []byte) error { } func InitLogger() { - log.Root().SetHandler( - log.LvlFilterHandler(log.LvlDebug, - log.StreamHandler( - os.Stdout, - log.TerminalFormat(false), - )), - ) + log.SetDefault(log.NewLogger(slog.NewJSONHandler( + os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug}))) } diff --git a/proxyd/integration_tests/ws_test.go b/proxyd/integration_tests/ws_test.go index bd41991fdf1d..1548f2aa15bf 100644 --- a/proxyd/integration_tests/ws_test.go +++ b/proxyd/integration_tests/ws_test.go @@ -3,91 +3,15 @@ package integration_tests import ( "os" "strings" - "sync" "sync/atomic" "testing" "time" "github.com/ethereum-optimism/optimism/proxyd" - "github.com/ethereum/go-ethereum/log" "github.com/gorilla/websocket" "github.com/stretchr/testify/require" ) -// TestConcurrentWSPanic tests for a panic in the websocket proxy -// that occurred when messages were sent from the upstream to the -// client right after the client sent an invalid request. -func TestConcurrentWSPanic(t *testing.T) { - var backendToProxyConn *websocket.Conn - var setOnce sync.Once - - readyCh := make(chan struct{}, 1) - quitC := make(chan struct{}) - - // Pull out the backend -> proxyd conn so that we can spam it directly. - // Use a sync.Once to make sure we only do that once, for the first - // connection. - backend := NewMockWSBackend(func(conn *websocket.Conn) { - setOnce.Do(func() { - backendToProxyConn = conn - readyCh <- struct{}{} - }) - }, nil, nil) - defer backend.Close() - - require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", backend.URL())) - - config := ReadConfig("ws") - _, shutdown, err := proxyd.Start(config) - require.NoError(t, err) - client, err := NewProxydWSClient("ws://127.0.0.1:8546", nil, nil) - require.NoError(t, err) - defer shutdown() - - // suppress tons of log messages - oldHandler := log.Root().GetHandler() - log.Root().SetHandler(log.DiscardHandler()) - defer func() { - log.Root().SetHandler(oldHandler) - }() - - <-readyCh - - var wg sync.WaitGroup - wg.Add(2) - // spam messages - go func() { - for { - select { - case <-quitC: - wg.Done() - return - default: - _ = backendToProxyConn.WriteMessage(websocket.TextMessage, []byte("garbage")) - } - } - }() - - // spam invalid RPCs - go func() { - for { - select { - case <-quitC: - wg.Done() - return - default: - _ = client.WriteMessage(websocket.TextMessage, []byte("{\"id\": 1, \"method\": \"eth_foo\", \"params\": [\"newHeads\"]}")) - } - } - }() - - // 1 second is enough to trigger the panic due to - // concurrent write to websocket connection - time.Sleep(time.Second) - close(quitC) - wg.Wait() -} - type backendHandler struct { msgCB atomic.Value closeCB atomic.Value diff --git a/proxyd/metrics.go b/proxyd/metrics.go index 68ca4e89874d..90a79ab7cc6d 100644 --- a/proxyd/metrics.go +++ b/proxyd/metrics.go @@ -2,6 +2,8 @@ package proxyd import ( "context" + "fmt" + "regexp" "strconv" "strings" "time" @@ -262,6 +264,14 @@ var ( "backend_group_name", }) + consensusHAError = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: MetricsNamespace, + Name: "group_consensus_ha_error", + Help: "Consensus HA error count", + }, []string{ + "error", + }) + consensusHALatestBlock = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: MetricsNamespace, Name: "group_consensus_ha_latest_block", @@ -465,6 +475,16 @@ func RecordBatchSize(size int) { batchSizeHistogram.Observe(float64(size)) } +var nonAlphanumericRegex = regexp.MustCompile(`[^a-zA-Z ]+`) + +func RecordGroupConsensusError(group *BackendGroup, label string, err error) { + errClean := nonAlphanumericRegex.ReplaceAllString(err.Error(), "") + errClean = strings.ReplaceAll(errClean, " ", "_") + errClean = strings.ReplaceAll(errClean, "__", "_") + label = fmt.Sprintf("%s.%s", label, errClean) + consensusHAError.WithLabelValues(label).Inc() +} + func RecordGroupConsensusHALatestBlock(group *BackendGroup, leader string, blockNumber hexutil.Uint64) { consensusHALatestBlock.WithLabelValues(group.Name, leader).Set(float64(blockNumber)) } diff --git a/proxyd/proxyd.go b/proxyd/proxyd.go index 84051ab559a4..0727efe995ac 100644 --- a/proxyd/proxyd.go +++ b/proxyd/proxyd.go @@ -13,9 +13,15 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/redis/go-redis/v9" + "golang.org/x/exp/slog" "golang.org/x/sync/semaphore" ) +func SetLogLevel(logLevel slog.Leveler) { + log.SetDefault(log.NewLogger(slog.NewJSONHandler( + os.Stdout, &slog.HandlerOptions{Level: logLevel}))) +} + func Start(config *Config) (*Server, func(), error) { if len(config.Backends) == 0 { return nil, nil, errors.New("must define at least one backend") @@ -130,6 +136,18 @@ func Start(config *Config) (*Server, func(), error) { } opts = append(opts, WithBasicAuth(cfg.Username, passwordVal)) } + + headers := map[string]string{} + for headerName, headerValue := range cfg.Headers { + headerValue, err := ReadFromEnvOrConfig(headerValue) + if err != nil { + return nil, nil, err + } + + headers[headerName] = headerValue + } + opts = append(opts, WithHeaders(headers)) + tlsConfig, err := configureBackendTLS(cfg) if err != nil { return nil, nil, err @@ -144,6 +162,7 @@ func Start(config *Config) (*Server, func(), error) { opts = append(opts, WithProxydIP(os.Getenv("PROXYD_IP"))) opts = append(opts, WithConsensusSkipPeerCountCheck(cfg.ConsensusSkipPeerCountCheck)) opts = append(opts, WithConsensusForcedCandidate(cfg.ConsensusForcedCandidate)) + opts = append(opts, WithWeight(cfg.Weight)) receiptsTarget, err := ReadFromEnvOrConfig(cfg.ConsensusReceiptsTarget) if err != nil { @@ -174,11 +193,12 @@ func Start(config *Config) (*Server, func(), error) { } backends = append(backends, backendsByName[bName]) } - group := &BackendGroup{ - Name: bgName, - Backends: backends, + + backendGroups[bgName] = &BackendGroup{ + Name: bgName, + Backends: backends, + WeightedRouting: bg.WeightedRouting, } - backendGroups[bgName] = group } var wsBackendGroup *BackendGroup @@ -221,7 +241,11 @@ func Start(config *Config) (*Server, func(), error) { log.Warn("redis is not configured, using in-memory cache") cache = newMemoryCache() } else { - cache = newRedisCache(redisClient, config.Redis.Namespace) + ttl := defaultCacheTtl + if config.Cache.TTL != 0 { + ttl = time.Duration(config.Cache.TTL) + } + cache = newRedisCache(redisClient, config.Redis.Namespace, ttl) } rpcCache = newRPCCache(newCacheWithCompression(cache)) } @@ -317,8 +341,8 @@ func Start(config *Config) (*Server, func(), error) { var tracker ConsensusTracker if bgcfg.ConsensusHA { - if redisClient == nil { - log.Crit("cant start - consensus high availability requires redis") + if bgcfg.ConsensusHARedis.URL == "" { + log.Crit("must specify a consensus_ha_redis config when consensus_ha is true") } topts := make([]RedisConsensusTrackerOpt, 0) if bgcfg.ConsensusHALockPeriod > 0 { @@ -327,7 +351,11 @@ func Start(config *Config) (*Server, func(), error) { if bgcfg.ConsensusHAHeartbeatInterval > 0 { topts = append(topts, WithLockPeriod(time.Duration(bgcfg.ConsensusHAHeartbeatInterval))) } - tracker = NewRedisConsensusTracker(context.Background(), redisClient, bg, bg.Name, topts...) + consensusHARedisClient, err := NewRedisClient(bgcfg.ConsensusHARedis.URL) + if err != nil { + return nil, nil, err + } + tracker = NewRedisConsensusTracker(context.Background(), consensusHARedisClient, bg, bg.Name, topts...) copts = append(copts, WithTracker(tracker)) } diff --git a/proxyd/rpc.go b/proxyd/rpc.go index 0c30d6439d88..902e26699b49 100644 --- a/proxyd/rpc.go +++ b/proxyd/rpc.go @@ -110,7 +110,7 @@ func ParseRPCRes(r io.Reader) (*RPCRes, error) { res := new(RPCRes) if err := json.Unmarshal(body, res); err != nil { - return nil, wrapErr(err, "error unmarshaling RPC response") + return nil, wrapErr(err, "error unmarshalling RPC response") } return res, nil diff --git a/proxyd/server.go b/proxyd/server.go index 2b7a1bd966f6..3fa3e0003c13 100644 --- a/proxyd/server.go +++ b/proxyd/server.go @@ -42,8 +42,10 @@ const ( defaultWSHandshakeTimeout = 10 * time.Second defaultWSReadTimeout = 2 * time.Minute defaultWSWriteTimeout = 10 * time.Second + defaultCacheTtl = 1 * time.Hour maxRequestBodyLogLen = 2000 defaultMaxUpstreamBatchSize = 10 + defaultRateLimitHeader = "X-Forwarded-For" ) var emptyArrayResponse = json.RawMessage("[]") @@ -73,6 +75,7 @@ type Server struct { wsServer *http.Server cache RPCCache srvMu sync.Mutex + rateLimitHeader string } type limiterFunc func(method string) bool @@ -168,6 +171,11 @@ func NewServer( senderLim = limiterFactory(time.Duration(senderRateLimitConfig.Interval), senderRateLimitConfig.Limit, "senders") } + rateLimitHeader := defaultRateLimitHeader + if rateLimitConfig.IPHeaderOverride != "" { + rateLimitHeader = rateLimitConfig.IPHeaderOverride + } + return &Server{ BackendGroups: backendGroups, wsBackendGroup: wsBackendGroup, @@ -192,6 +200,7 @@ func NewServer( allowedChainIds: senderRateLimitConfig.AllowedChainIds, limExemptOrigins: limExemptOrigins, limExemptUserAgents: limExemptUserAgents, + rateLimitHeader: rateLimitHeader, }, nil } @@ -427,6 +436,16 @@ func (s *Server) handleBatchRPC(ctx context.Context, reqs []json.RawMessage, isL continue } + // Simple health check + if len(reqs) == 1 && parsedReq.Method == proxydHealthzMethod { + res := &RPCRes{ + ID: parsedReq.ID, + JSONRPC: JSONRPCVersion, + Result: "OK", + } + return []*RPCRes{res}, false, "", nil + } + if err := ValidateRPCReq(parsedReq); err != nil { RecordRPCError(ctx, BackendProxyd, MethodUnknown, err) responses[i] = NewRPCErrorRes(nil, err) @@ -608,7 +627,7 @@ func (s *Server) HandleWS(w http.ResponseWriter, r *http.Request) { func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context.Context { vars := mux.Vars(r) authorization := vars["authorization"] - xff := r.Header.Get("X-Forwarded-For") + xff := r.Header.Get(s.rateLimitHeader) if xff == "" { ipPort := strings.Split(r.RemoteAddr, ":") if len(ipPort) == 2 { @@ -669,7 +688,7 @@ func (s *Server) isGlobalLimit(method string) bool { func (s *Server) rateLimitSender(ctx context.Context, req *RPCReq) error { var params []string if err := json.Unmarshal(req.Params, ¶ms); err != nil { - log.Debug("error unmarshaling raw transaction params", "err", err, "req_Id", GetReqID(ctx)) + log.Debug("error unmarshalling raw transaction params", "err", err, "req_Id", GetReqID(ctx)) return ErrParseErr } diff --git a/specs/LICENSE b/specs/LICENSE deleted file mode 100644 index 670154e35388..000000000000 --- a/specs/LICENSE +++ /dev/null @@ -1,116 +0,0 @@ -CC0 1.0 Universal - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator and -subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for the -purpose of contributing to a commons of creative, cultural and scientific -works ("Commons") that the public can reliably and without fear of later -claims of infringement build upon, modify, incorporate in other works, reuse -and redistribute as freely as possible in any form whatsoever and for any -purposes, including without limitation commercial purposes. These owners may -contribute to the Commons to promote the ideal of a free culture and the -further production of creative, cultural and scientific works, or to gain -reputation or greater distribution for their Work in part through the use and -efforts of others. - -For these and/or other purposes and motivations, and without any expectation -of additional consideration or compensation, the person associating CC0 with a -Work (the "Affirmer"), to the extent that he or she is an owner of Copyright -and Related Rights in the Work, voluntarily elects to apply CC0 to the Work -and publicly distribute the Work under its terms, with knowledge of his or her -Copyright and Related Rights in the Work and the meaning and intended legal -effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not limited -to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, communicate, - and translate a Work; - - ii. moral rights retained by the original author(s) and/or performer(s); - - iii. publicity and privacy rights pertaining to a person's image or likeness - depicted in a Work; - - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - - v. rights protecting the extraction, dissemination, use and reuse of data in - a Work; - - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - - vii. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer's Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer's heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer's express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, -non transferable, non sublicensable, non exclusive, irrevocable and -unconditional license to exercise Affirmer's Copyright and Related Rights in -the Work (i) in all territories worldwide, (ii) for the maximum duration -provided by applicable law or treaty (including future time extensions), (iii) -in any current or future medium and for any number of copies, and (iv) for any -purpose whatsoever, including without limitation commercial, advertising or -promotional purposes (the "License"). The License shall be deemed effective as -of the date CC0 was applied by Affirmer to the Work. Should any part of the -License for any reason be judged legally invalid or ineffective under -applicable law, such partial invalidity or ineffectiveness shall not -invalidate the remainder of the License, and in such case Affirmer hereby -affirms that he or she will not (i) exercise any of his or her remaining -Copyright and Related Rights in the Work or (ii) assert any associated claims -and causes of action with respect to the Work, in either case contrary to -Affirmer's express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - - b. Affirmer offers the Work as-is and makes no representations or warranties - of any kind concerning the Work, express, implied, statutory or otherwise, - including without limitation warranties of title, merchantability, fitness - for a particular purpose, non infringement, or the absence of latent or - other defects, accuracy, or the present or absence of errors, whether or not - discoverable, all to the greatest extent permissible under applicable law. - - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without limitation - any person's Copyright and Related Rights in the Work. Further, Affirmer - disclaims responsibility for obtaining any necessary consents, permissions - or other rights required for any use of the Work. - - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to this - CC0 or use of the Work. - -For more information, please see - diff --git a/specs/README.md b/specs/README.md index fd6c570e3daa..e75cc2b9f668 100644 --- a/specs/README.md +++ b/specs/README.md @@ -1,63 +1,3 @@ - -# Optimism Bedrock specs +# Specs Have Moved -This directory contains the plain english specs for Optimism, a minimal optimistic rollup protocol -that maintains 1:1 compatibility with Ethereum. - -## Specification Contents - -- [Introduction](introduction.md) -- [Overview](overview.md) -- [Deposits](deposits.md) -- [Withdrawals](withdrawals.md) -- [Execution Engine](exec-engine.md) -- [L2 Output Root Proposals](proposals.md) -- [Rollup Node](rollup-node.md) -- [Rollup Node P2p](rollup-node-p2p.md) -- [L2 Chain Derivation](derivation.md) -- [Superchain Upgrades](superchain-upgrades.md) -- [System Config](system_config.md) -- [Batch Submitter](batcher.md) -- [Guaranteed Gas Market](guaranteed-gas-market.md) -- [Messengers](messengers.md) -- [Bridges](bridges.md) -- [Predeploys](predeploys.md) -- [Glossary](glossary.md) - -### Experimental - -Specifications of new features in active development. - -- [Fault Proof](./fault-proof.md) -- [Dispute Game Interface](./dispute-game-interface.md) -- [Fault Dispute Game](./fault-dispute-game.md) -- [Cannon VM](./cannon-fault-proof-vm.md) - -## Design Goals - -Our aim is to design a protocol specification that is: - -- **Fast:** When users send transactions, they get reliable confirmations with low-latency. - For example when swapping on Uniswap you should see that your transaction succeed in less than 2 - seconds. -- **Scalable:** It should be possible to handle an enormous number of transactions - per second which will enable the system to charge low fees. - V1.0 will enable Optimism to scale up to and even past the gas limit on L1. - Later iterations should scale much further. -- **Modular:** Our designs will use modularity to reduce complexity and enable parallel - contributions. Coming up with good conceptual frameworks & composable atoms of software enables us - to build extremely complex software even when any one person cannot hold that much in their brain. -- **Minimal:** Rollups should be minimal to best take advantage of the battle-tested infrastructure - (like Geth) that already runs Ethereum. An ideal optimistic rollup design should be representable - as a *diff* against Ethereum client software. -- **Developer Driven:** Our designs will be developer driven to ensure we are actually building - something that people want to use. We must constantly engage with the developers who will be using - our software to avoid creating a system no one wants to use. -- **Clear and Readable:** The specs we write are written to be read. So tight feedback loop with the - systems team consuming the spec is also key! -- **Secure:** This is self-evident. - User’s assets are at stake. Every component of the system must be incredibly secure. -- **Decentralizable:** Optimism must be designed to avail itself of the security and - censorship-resistant guarantees achieved by a decentralized system. - Currently centralized components of the system should have a clear path towards decentralization. - Already decentralized components of the system should be protected and preserved. +Specs have moved to a [dedicated repository](https://github.com/ethereum-optimism/specs). \ No newline at end of file diff --git a/specs/assets/attack.png b/specs/assets/attack.png deleted file mode 100755 index 9857ecdbcd7a..000000000000 Binary files a/specs/assets/attack.png and /dev/null differ diff --git a/specs/assets/batch-deriv-chain.svg b/specs/assets/batch-deriv-chain.svg deleted file mode 100644 index 52426d0bca6e..000000000000 --- a/specs/assets/batch-deriv-chain.svg +++ /dev/null @@ -1,839 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
100
-
-
-
100 -
-
- - - - - - - -
-
-
102
-
-
-
102 -
-
- - - - - - - -
-
-
101
-
-
-
101 -
-
- - - - - - - -
-
-
3
-
-
-
3 -
-
- - - - - - - -
-
-
4
-
-
-
4 -
-
- - - - - - - -
-
-
5
-
-
-
5 -
-
- - - - - - - -
-
-
6
-
-
-
6 -
-
- - - - - - - -
-
-
7
-
-
-
7 -
-
- - - - - - - -
-
-
8
-
-
-
8 -
-
- - - - - - - - - - -
-
-
Compressed & encoded batch data
-
-
-
Compressed & encoded batch data -
-
- - - - - -
-
-
A0
-
-
-
A0 -
-
- - - - -
-
-
B0
-
-
-
B0 -
-
- - - - -
-
-
B1
-
-
-
B1 -
-
- - - - - - - - -
-
-
9
-
-
-
9 -
-
- - - - - - - -
-
-
10
-
-
-
10 -
-
- - - - - - - -
-
-
11
-
-
-
11 -
-
- - - - - - - - - - - - -
-
-
A1
-
-
-
A1 -
-
- - - - -
-
-
B2
-
-
-
B2 -
-
- - - - - - - - - - - - - - - - - -
-
-
L1 Transactions,
~128 KB each
-
-
-
L1 Transactions,... -
-
- - - - -
-
-
Channels,
with timeout
-
-
-
Channels,... -
-
- - - - -
-
-
Batches,
1 batch = 1 L2 block tx list
-
-
-
Batches,... -
-
- - - - -
-
-
L2 Blocks
(a.k.a. execution payloads)
-
-
-
L2 Blocks... -
-
- - - - -
-
-
Channel A, Frame 0
-
-
-
Channel A, Frame 0 -
-
- - - - -
-
-
Channel A, Frame 1
-
-
-
Channel A, Frame 1 -
-
- - - - -
-
-
Channel B,
Frame 0
-
-
-
Channel B,... -
-
- - - - -
-
-
Channel B, Frame 1
-
-
-
Channel B, Frame 1 -
-
- - - - -
-
-
Channel B, Frame 2
-
-
-
Channel B, Frame 2 -
-
- - - - -
-
-
Channel C, etc...
-
-
-
Channel C, etc... -
-
- - - - -
-
-
L1 Blocks,
These may not be as
frequent/consistent
as L2 blocks.
-
-
-
L1 Blocks,... -
-
- - - - -
-
-
Actual inclusion on L1:
channels are valid
within a timeout
-
-
-
Actual inclusion on L1:... -
-
- - - - -
-
-
Channel B was seen first,
and will be decoded into batches first.
-
-
-
Channel B was seen first,... -
-
- - - - - - - - - - - - - -
-
-
Batches can be buffered
for up to a full sequencing window
worth of L1 blocks
to get the L2 ordering back.
-
-
-
Batches can be buffered... -
-
- - - - -
-
-
Time
-
-
-
Time -
-
- - - - - -
-
-
older L2 data
-
-
-
older L2 data -
-
- - - - -
-
-
B1
-
-
-
B1 -
-
- - - - -
-
-
B0
-
-
-
B0 -
-
- - - - -
-
-
A1
-
-
-
A1 -
-
- - - - - -
-
-
B2
-
-
-
B2 -
-
- - - - -
-
-
A0
-
-
-
A0 -
-
- - - - -
-
-
100-0
-
-
-
100-0 -
-
- - - - -
-
-
100-1
-
-
-
100-1 -
-
- - - - -
-
-
100-2
-
-
-
100-2 -
-
- - - - -
-
-
100-3
-
-
-
100-3 -
-
- - - - -
-
-
100-4
-
-
-
100-4 -
-
- - - - -
-
-
101-0
-
-
-
101-0 -
-
- - - - -
-
-
99-5
-
-
-
99-5 -
-
- - - - -
-
-
99-4
-
-
-
99-4 -
-
- - - - -
-
-
99-3
-
-
-
99-3 -
-
- - - - -
-
-
99-2
-
-
-
99-2 -
-
- - - - - - - -
-
-
99
-
-
-
99 -
-
- - - - -
-
-
Each L2 block has a tx with info
about the "origin" L1 block
-
-
-
Each L2 block has a tx with info... -
-
- - - - -
-
-
The "sequence number"
helps differentiate between
L2 blocks with the same origin.
-
-
-
The "sequence number"... -
-
- - - - -
-
-
deposit
-
-
-
deposit -
-
- - - - -
-
-
deposit
-
-
-
deposit -
-
- - - - -
-
-
Deposits are L1 log events,
parsed from EVM receipts
-
-
-
Deposits are L1 log events,... -
-
- - - - -
-
-
deposit
-
-
-
deposit -
-
- - - - -
-
-
deposit
-
-
-
deposit -
-
- - - - -
-
-
Deposits get included
the first L2 block that
adopts the L1 origin the
deposits were made in.
-
-
-
Deposits get included... -
-
- - - - -
-
-
Security types on L2:
- "unsafe": not submitted on L1
- "safe": is confirmed on L1
- "finalized": fully derived from finalized L1 data
-
-
-
Security types on L2:... -
-
- - - - -
-
-
Security types on L1:
- "unsafe": very new
- "safe": decent attestation ratio
- "finalized": with FFG finality gadget
-
-
-
Security types on L1:... -
-
-
- - Text is not SVG - cannot display - -
diff --git a/specs/assets/batch-deriv-pipeline.svg b/specs/assets/batch-deriv-pipeline.svg deleted file mode 100644 index 324a845ab70b..000000000000 --- a/specs/assets/batch-deriv-pipeline.svg +++ /dev/null @@ -1,609 +0,0 @@ - - - - - - - - - - -
-
-
110
-
-
-
110 -
-
- - - - -
-
-
110
-
-
-
110 -
-
- - - - -
-
-
110
-
-
-
110 -
-
- - - - - -
-
-
100
-
-
-
100 -
-
- - - - -
-
-
Batch Queue
-
-
-
Batch Queue -
-
- - - - -
-
-
Engine Queue
-
-
-
Engine Queue -
-
- - - - -
-
-
-
PayloadAttributes
-
Queue
-
-
-
-
PayloadAttributes... -
-
- - - - -
-
-
-
Channel
-
Input-reader
-
-
-
-
Channel... -
-
- - - - -
-
-
-
Channel
-
Bank
-
-
-
-
Channel... -
-
- - - - -
-
-
L1 Traversal
-
-
-
L1 Traversal -
-
- - - - -
-
-
100
-
-
-
100 -
-
- - - - - -
-
-
110
-
-
-
110 -
-
- - - - -
-
-
L1 Deposits
-
-
-
L1 Deposits -
-
- - - - -
-
-
130
-
-
-
130 -
-
- - - - -
-
-
110
-
-
-
110 -
-
- - - - -
-
-
110
-
-
-
110 -
-
- - - - -
-
-
110
-
-
-
110 -
-
- - - - -
-
-
100
-
-
-
100 -
-
- - - - -
-
-
100
-
-
-
100 -
-
- - - - -
-
-
130
-
-
-
130 -
-
- - - - -
-
-
130
-
-
-
130 -
-
- - - - -
-
-
130
-
-
-
130 -
-
- - - - -
-
-
130
-
-
-
130 -
-
- - - - -
-
-
130
-
-
-
130 -
-
- - - - -
-
-
130
-
-
-
130 -
-
- - - - -
-
-
1) find safe L2 block
with canonical L1 origin
-
-
-
1) find safe L2 block... -
-
- - - - -
-
-
3) reset all stage origins,
traverse chain back
-
-
-
3) reset all stage orig... -
-
- - - - -
-
-
4) dry-run pipeline
to heal stage buffers
-
-
-
4) dry-run pipeline... -
-
- - - - -
-
-
5) new L1 data
can now stream into L2
-
-
-
5) new L1 data... -
-
- - - - -
-
-
2) Stages with gaps will
reconstruct buffer data
-
-
-
2) Stages with gaps wi... -
-
- - - - - - -
-
-
Numbers for illustration,
referring to L1 origin
block numbers
-
-
-
Numbers for illustrati... -
-
- - - - -
-
-
"ResetStep":
reset stage with
distance from next
-
-
-
"ResetStep":... -
-
- - - - -
-
-
"Step":
progress pipeline.
Start closest to L2,
visit previous stage
for more input data.
-
-
-
"Step":... -
-
- - - - -
-
-
L1 block hash > Data TXs > Channel Frames > Batches > Ordered batches > PayloadAttributes > L2 payloads
-
-
-
L1 block hash > Data TXs > Channel Frames > Batches > Ordered batches > PayloadAttributes > L2 payl... -
-
- - - - -
-
-
Resets
Channel
timeout
-
-
-
Resets... -
-
- - - - -
-
-
-
Resets
Sequencing
window -
-
-
-
ResetsSequenc... -
-
- - - - -
-
-
L1 Retrieval
-
-
-
L1 Retrieval -
-
- - - - -
-
-
100
-
-
-
100 -
-
- - - - -
-
-
100
-
-
-
100 -
-
- - - - -
-
-
130
-
-
-
130 -
-
- - - - - - -
-
-
L1 Data
-
-
-
L1 Data -
-
- - - - -
-
-
L1 Chain
-
-
-
L1 Chain -
-
- - - - -
-
-
L2 Exec
Engine
-
-
-
L2 Exec... -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
Reset:
-
-
-
Reset: -
-
- - - - -
-
-
-
110
-
-
-
-
110 -
-
- - - - -
-
-
110
-
-
-
110 -
-
-
- - Text is not SVG - cannot display - -
\ No newline at end of file diff --git a/specs/assets/challenger_attestation.png b/specs/assets/challenger_attestation.png deleted file mode 100644 index 4f28ab675851..000000000000 Binary files a/specs/assets/challenger_attestation.png and /dev/null differ diff --git a/specs/assets/challenger_attestation_dispute_game_created.png b/specs/assets/challenger_attestation_dispute_game_created.png deleted file mode 100644 index 58fc2bae0574..000000000000 Binary files a/specs/assets/challenger_attestation_dispute_game_created.png and /dev/null differ diff --git a/specs/assets/challenger_attestation_output_proposed.png b/specs/assets/challenger_attestation_output_proposed.png deleted file mode 100644 index 8f41fc587107..000000000000 Binary files a/specs/assets/challenger_attestation_output_proposed.png and /dev/null differ diff --git a/specs/assets/components.svg b/specs/assets/components.svg deleted file mode 100644 index 410204e1896c..000000000000 --- a/specs/assets/components.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
OptimismPortal
OptimismPortal
L2OutputOracle
L2OutputOracle
Rollup
Node
Rollup...
Batch Submitter
Batch Submitter
L2 Execution Engine
(L2 Geth)
L2 Execution Engine...
BatchInbox
BatchInbox
L1
L1
L2
L2
Output Submitter
Output Submitter
Legend
Legend
Sequencer
Sequencer
Verifier
Verifier
Text is not SVG - cannot display
\ No newline at end of file diff --git a/specs/assets/defend.png b/specs/assets/defend.png deleted file mode 100755 index 9909ed4ec079..000000000000 Binary files a/specs/assets/defend.png and /dev/null differ diff --git a/specs/assets/derivation-1.svg b/specs/assets/derivation-1.svg deleted file mode 100644 index b22b32a1cebf..000000000000 --- a/specs/assets/derivation-1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
1
1
2
2
3
3
4
4
Sequencing Window (Epoch 1)
Sequencing Window (Epoch 1)
5
5
Sequencing Window (Epoch 2)
Sequencing Window (Epoch 2)
L1
L1
Text is not SVG - cannot display
\ No newline at end of file diff --git a/specs/assets/derivation-2.svg b/specs/assets/derivation-2.svg deleted file mode 100644 index 32738befbe60..000000000000 --- a/specs/assets/derivation-2.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
1
1
2
2
3
3
4
4
Sequencing Window (Epoch 1)
Sequencing Window (Epoch 1)
5
5
Sequencing Window (Epoch 2)
Sequencing Window (Epoch 2)
L1
L1
Deposit
Deposit
Tx Batch
Tx Batch
Tx Batch
Tx Batch
Tx Batch
Tx Batch
Tx Batch
Tx Batch
Rollup
Node
Data
Rollup...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/specs/assets/derivation-3.svg b/specs/assets/derivation-3.svg deleted file mode 100644 index 4fd603be9529..000000000000 --- a/specs/assets/derivation-3.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
1
1
2
2
3
3
4
4
Sequencing Window (Epoch 1)
Sequencing Window (Epoch 1)
5
5
Sequencing Window (Epoch 2)
Sequencing Window (Epoch 2)
L1
L1
Deposit
Deposit
Tx Batch
Tx Batch
Tx Batch
Tx Batch
Tx Batch
Tx Batch
Tx Batch
Tx Batch
Rollup
Node
Data
Rollup...
2
2
3
3
4
4
L1 Info
L1 Info
5
5
L2
L2
Text is not SVG - cannot display
\ No newline at end of file diff --git a/specs/assets/engine.svg b/specs/assets/engine.svg deleted file mode 100644 index ff96fd1f5c88..000000000000 --- a/specs/assets/engine.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Rollup Driver
Rollup Driver
Engine API
Engine API
PayloadAttributes

- timestamp
- random
- suggestedFeeRecipient
- transactions
PayloadAttributes...
ForkChoiceState

- headBlockHash
- safeBlockHash
- finalizedBlockHash
ForkChoiceState...
FCS
FCS
PA
PA
payloadID
payloadID
Initiate block
production
Initiate block...
engine_forkchoiceUpdatedV2
engine_forkchoiceUpdatedV2
payload
payload
engine_getPayloadV2
(payloadID)
engine_getPayloadV2...
engine_newPayloadV2
(payload)
engine_newPayloadV2...
engine_forkchoiceUpdatedV2
engine_forkchoiceUpdatedV2
FCS
FCS
Current L2
block hash
Current L2...
payload.blockHash
payload.blockHash
Text is not SVG - cannot display
diff --git a/specs/assets/fault-proof.svg b/specs/assets/fault-proof.svg deleted file mode 100644 index 51a998145f32..000000000000 --- a/specs/assets/fault-proof.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
L2 Oracle
L2 Oracle
L2 Engine API
L2 Engine API
L2 OracleEngine
L2 OracleEngine
OracleBackedL2Chain
OracleBackedL2Chain
L2 pre-image
fetcher
L2 pre-image...
Main configuration: chain and rollup configs
Main configuration:...
Preimage KV Store
Preimage KV Store
L1 OracleEthClient
L1 OracleEthClient
prologue:
dispute and
L1 lookup
prologue:...
Pre-image Oracle
Client
Pre-image Oracle...
L1 Oracle
L1 Oracle
epilogue:
output root construction
& claim check
epilogue:...
Program Client:
- stateless
- no temp errors
- no environment access
- onchain
Program Client:...
Program Host / VM:
- stateful
- pre-image store on disk
- offchain
Program Host / VM:...
execution trace
execution trace
Pre-image Hint
Writer
Pre-image Hint...
derivation loop
derivation loop
Pre-image Hint
Reader
Pre-image Hint...
Pre-image Oracle
Server
Pre-image Oracle...
Program tools:
- pre-image fetching
- retry on fetch errors
Program tools:...
L1 pre-image
fetcher
L1 pre-image...
Pre-image hint router
Pre-image hint router
No-op when onchain / readonly
No-op when onchain / readon...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/specs/assets/network-participants-overview.svg b/specs/assets/network-participants-overview.svg deleted file mode 100644 index 9eeac12aecc1..000000000000 --- a/specs/assets/network-participants-overview.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Ethereum L1 Chain
Ethereum L1 Chain

Network Participants Overview

Network Participants Overview
Query data
(eg. block explorers)
Query data...
Submit transactions
Submit transactions
Submit deposits
Submit deposits
Users
Users
Submit batches and assertions
Submit batches and assertions
P2P Realtime Updates
P2P Realtime Updates
Verifiers
Verifi...
Verify block hash assertions &
submit fault proofs
Verify block hash assertions &...
Sequencers
Viewer does not support full SVG 1.1
diff --git a/specs/assets/propagation.svg b/specs/assets/propagation.svg deleted file mode 100644 index 7410bfd96914..000000000000 --- a/specs/assets/propagation.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Engine API
Engine API
Rollup
Node
Rollup...
EE
EE
L1
L1
L2
L2
Batch Submitter
Batch Submitter
Output Submitter
Output Submitter
BatchInbox
BatchInbox
OptimismPortal
OptimismPortal
Rollup
Node
Rollup...
EE
EE
Unsafe
Block
Propagation
Unsafe...
TX Sync
TX Sync
State Sync
State Sync
Legend
Legend
Sequencer
Sequencer
Verifier
Verifier
Text is not SVG - cannot display
\ No newline at end of file diff --git a/specs/assets/sequencer-block-gen.svg b/specs/assets/sequencer-block-gen.svg deleted file mode 100644 index 8b463b07b860..000000000000 --- a/specs/assets/sequencer-block-gen.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Epoch 3
Epoch 3
Epoch 2
Epoch 2
Epoch 1
Epoch 1
L1
L1
D1
D1
B1
B1
L2
L2
D2
D2
B3
B3
B2
B2
D2
D2
B1
B1
D1
D1
B3
B3
B4
B4
B5
B5
B4
B4
B2
B2
B5
B5
D3
D3
B6
B6
B7
B7
B6
B6
B7
B7
D3
D3
Text is not SVG - cannot display
\ No newline at end of file diff --git a/specs/assets/sequencer-handling-deposits-and-transactions.svg b/specs/assets/sequencer-handling-deposits-and-transactions.svg deleted file mode 100644 index eea840e1ddc6..000000000000 --- a/specs/assets/sequencer-handling-deposits-and-transactions.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
3. Insert deposit block
3. Insert deposit block
Rollup Node
Rollup Node
2. Get Blocks (including deposit event)
2. Get Blocks (including deposit event)
Ethereum L1 Chain
Ethereum L1 Chain
Rollup(
Rollup(
)
)
L1
L1
L2
L2
Fault Proof VM
Fault Proof VM
Executes blocks in the fault proof VM and
generates witnesses.
Executes blocks in the fault proof VM an...
Data to generate the witnesses
(eg. storage, blocks...)
is fetched from L1 & L2 nodes.
Data to generate the witnesses...
Transform latest L1 blocks
into L2 block inputs
Transform latest L1 blocks...
Execution Engine (mining mode)
Execution Engine (mining mode)
(eg. Geth)
(eg. Geth)
Accept transactions, build blocks,
store the chain, serve RPC requests.
Accept transactions, build blocks,...
EVM
EVM
Chain
Chain
State
State
RPC
RPC
4
4
5. Get
latest
sequencer
blocks
5. Get...
6. Submit sequencer blocks
(ie. a batch) to the batch inbox
6. Submit sequencer blocks...
Sequencer
Batch Submitter
Sequencer...
Queries for all
sequencer blocks &
submits them to
the batch inbox.
Queries for all...
Batch Inbox
Batch Inbox

Sequencer Syncing Deposits & Accepting a Transaction 

Sequencer Syncing Deposits & Accepting a Transaction 
RPC
RPC
TxPool
TxPool
4. Send Transaction
4. Send Transaction
1. Submit Deposit
1. Submit Deposit
User
User
Note:  Sequencer will likely run a consensus
protocol not demonstrated in this diagram.
Note:  Sequencer will likely run a consen...
!!
!!
7. Get latest assertable block hash
7. Get latest assertable block hash
9. Submit validated
block hash assertion
9. Submit validated...
L2 Output Submitter
L2 Output Submitter
Queries for the next
assertable block hash &
submits it to the
L2 Output Oracle.
Queries for the next...
L2 Output Oracle
L2 Output Oracle
8. Verify block hash in the fault proof VM
to detect on-chain<->off-chain divergence
8. Verify block hash in the fault proof VM...
Text is not SVG - cannot display
diff --git a/specs/assets/user-withdrawing-to-l1.svg b/specs/assets/user-withdrawing-to-l1.svg deleted file mode 100644 index 99fd8419063f..000000000000 --- a/specs/assets/user-withdrawing-to-l1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Ethereum L1 Chain
Ethereum L1 Chain
Batch Inbox
Batch Inbox
L2 Output Oracle
L2 Output Oracle
3. Assert block hash
containing withdrawal
commitment
3. Assert block hash...
2. Post batch
with withdrawal
transaction data
2. Post batch...
1. Send
initiate
withdrawal

transaction
1. Send...
5. Send
execute
withdrawal

transaction
5. Send...
4. Wait for block
hash to finalize
4. Wait for block...
User
User
ERC20
ERC20
6. Verify
withdrawal
in finalized
block hash
6. Verify...
7.
Transfer
tokens
7....
Bridge
Bridge
Sequencers
Text is not SVG - cannot display
\ No newline at end of file diff --git a/specs/assets/valid-moves.png b/specs/assets/valid-moves.png deleted file mode 100755 index da9d43465e5a..000000000000 Binary files a/specs/assets/valid-moves.png and /dev/null differ diff --git a/specs/assets/verifier-executing-fraud-proof.svg b/specs/assets/verifier-executing-fraud-proof.svg deleted file mode 100644 index d05881d5c2b9..000000000000 --- a/specs/assets/verifier-executing-fraud-proof.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
2. Insert and reorg blocks
2. Insert and reorg blocks
Rollup Node
Rollup Node
1. Get Blocks
1. Get Blocks
Ethereum L1 Chain
Ethereum L1 Chain
Rollup(
Rollup(
)
)
L1
L1
L2
L2
Transform latest L1 blocks
into L2 block inputs
Transform latest L1 blocks...
Execution Engine
Execution Engine
(eg. Geth)
(eg. Geth)
Execute blocks, store the chain,
serve RPC calls.
Execute blocks, store the chai...
EVM
EVM
Chain
Chain
State
State
RPC
RPC
3. Read
BlockHash
Assertion
3. Read...
4. Get
corresponding
block hash
4. Get...
5. Get witness
for invalid assertion
5. Get witness...
6. Isolate disputed
state transition
6. Isolate disputed...
7. Verify disputed
state transition
7. Verify disputed...
Challenger Agent
Challenger Agent
Watches L1 chain for fault & performs
challenges.
Watches L1 chain for fault & perform...
local_blockhash ≠ assertion_blockhash
local_blockhash ≠ assertion_blockhash
Fault Proof VM
Fault Proof VM
Executes blocks in the fault proof VM and
generates witnesses.
Executes blocks in the fault proof VM an...
Data to generate the witnesses
(eg. storage, blocks...)
is fetched from L1 & L2 nodes.
Data to generate the witnesses...
L2 Output Oracle Contract
L2 Output Oracle Contract
k-section
game
k-section...
Single-step
verifier
Single-step...

Verifier Detecting & Executing a Fault Proof

Verifier Detecting & Executing a Fault Proof
Text is not SVG - cannot display
diff --git a/specs/batcher.md b/specs/batcher.md deleted file mode 100644 index 91e42404c119..000000000000 --- a/specs/batcher.md +++ /dev/null @@ -1,25 +0,0 @@ - -# Batch Submitter - -The batch submitter, also referred to as the batcher, is the entity submitting the L2 sequencer data to L1, -to make it available for verifiers. - -[derivation spec]: derivation.md - -The format of the data transactions is defined in the [derivation spec]: -the data is constructed from L2 blocks in the reverse order as it is derived from data into L2 blocks. - -The timing, operation and transaction signing is implementation-specific: any data can be submitted at any time, -but only the data that matches the [derivation spec] rules will be valid from the verifier perspective. - -The most minimal batcher implementation can be defined as a loop of the following operations: - -1. See if the `unsafe` L2 block number is past the `safe` block number: `unsafe` data needs to be submitted. -2. Iterate over all unsafe L2 blocks, skip any that were previously submitted. -3. Open a channel, buffer all the L2 block data to be submitted, - while applying the encoding and compression as defined in the [derivation spec]. -4. Pull frames from the channel to fill data transactions with, until the channel is empty. -5. Submit the data transactions to L1 - -The L2 view of safe/unsafe does not instantly update after data is submitted, nor when it gets confirmed on L1, -so special care may have to be taken to not duplicate data submissions. diff --git a/specs/bond-manager.md b/specs/bond-manager.md deleted file mode 100644 index 77746bda09af..000000000000 --- a/specs/bond-manager.md +++ /dev/null @@ -1,147 +0,0 @@ -# Bond Manager Interface - - - -**Table of Contents** - -- [Overview](#overview) -- [The Bond Problem](#the-bond-problem) - - [Simple Bond](#simple-bond) - - [Variable Bond](#variable-bond) -- [Contract Interface](#contract-interface) -- [Bond Manager Implementation](#bond-manager-implementation) - - - -## Overview - -In the context of permissionless output proposals, bonds are a value that must -be attached to an output proposal. In this case, the bond will be paid in ether. - -By requiring a bond to be posted with an output proposal, spam and invalid outputs -are disincentivized. Explicitly, if invalid outputs are proposed, challenge agents -can delete the invalid output via a [dispute-game](./dispute-game-interface.md) and seize the -proposer's bond. So, posting invalid outputs is directly disincentivized in this way -since the proposer would lose their bond if the challenge agents seize it. - -Concretely, outputs will be permissionlessly proposed to the `L2OutputOracle` contract. -When submitting an output proposal, the ether value is sent as the bond. This bond is -then held by a bond manager contract. The bond manager contract is responsible for -both the [dispute-games](./dispute-game-interface.md) and the `L2OutputOracle` (further detailed -in [proposals](./proposals.md)). - -The bond manager will need to handle bond logic for a variety of different -[dispute-games](./dispute-game-interface.md). In the simplest "attestation" dispute game, -bonds will not be required since the attestors are a permissioned set of trusted entities. -But in more complex games, such as the fault dispute game, challengers and defenders -perform a series of alternating onchain transactions requiring bonds at each step. - -## The Bond Problem - -At its core, the bond manager is straightforward - it escrows or holds ether and can be claimed -at maturity or seized if forfeited. But the uncertainty of introducing bonds lies in the -bond _sizing_, i.e. how much should a bond be? Sizing bonds correctly is a function of -the bond invariant: the bond must be greater than or equal to the cost of the next step. -If bonds are priced too low, then the bond invariant is violated and there isn't an economic -incentive to execute the next step. If bonds are priced too high, then the actors posting -bonds can be priced out. - -Below, we outline two different approaches to sizing bonds and the tradeoffs of each. - -### Simple Bond - -The _Simple Bond_ is a very conservative approach to bond management, establishing a **fixed** bond -size. The idea behind simple bond pricing is to establish the worst case gas cost for -the next step in the dispute game. - -With this approach, the size of the bond is computed up-front when a dispute game is created. -For example, in an attestation dispute game, this bond size can be computed as such: - -```md -bond_size = (signer_threshold * (challenge_gas + security overhead)) + resolution_gas(signer_threshold) -``` - -Notice that since the bond size is linearly proportional to the number of signers, the economic -security a given bond size provides decreases as the number of signers increases. Also note, the -`resolution_gas` function is split out from the `challenge_gas` cost because only the _last_ challenger -will pay for the gas cost to resolve the game in the attestation dispute game. - -Working backwards, if we assume the number of signers to be `5`, a negligible resolution gas cost, and -a `100,000` gas cost to progress the game, then the bond size should cover `500,000` gas. Meaning, a bond -of `1 ether` would cover the cost of progressing the game for `5` signers as long as the gas price -(base fee) does not exceed `2,000 gwei` for the entire finalization window. It would be prohibitively -expensive to keep the settlement layer base fee this high. - -### Variable Bond - -Better bond heuristics can be used to establish a bond price that accounts for -the time-weighted gas price. One instance of this called _Varable Bonds_ use a -separate oracle contract, `GasPriceFluctuationTracker`, that tracks gas fluctuations -within a pre-determined bounds. This replaces the ideal solution of tracking -challenge costs over all L1 blocks, but provides a reasonable bounds. The initial -actors posting this bond are responsible for funding this contract. - -## Contract Interface - -Below is a minimal interface for the bond manager contract. - -```solidity -/** - * @title IBondManager - * @notice The IBondManager is an interface for a contract that handles bond management. - */ -interface IBondManager { - /** - * @notice Post a bond with a given id and owner. - * @dev This function will revert if the provided bondId is already in use. - * @param bondId is the id of the bond. - * @param owner is the address that owns the bond. - * @param minClaimHold is the minimum amount of time the owner must wait before reclaiming their bond. - */ - function post(bytes32 bondId, address owner, uint64 minClaimHold) external payable; - - /** - * @notice Seizes the bond with the given id. - * @dev This function will revert if there is no bond at the given id. - * @param bondId is the id of the bond. - */ - function seize(bytes32 bondId) external; - - /** - * @notice Seizes the bond with the given id and distributes it to recipients. - * @dev This function will revert if there is no bond at the given id. - * @param bondId is the id of the bond. - * @param recipients is a set of addresses to split the bond amongst. - */ - function seizeAndSplit(bytes32 bondId, address[] calldata recipients) external; - - /** - * @notice Reclaims the bond of the bond owner. - * @dev This function will revert if there is no bond at the given id. - * @param bondId is the id of the bond. - */ - function reclaim(bytes32 bondId) external; -} -``` - -**Note** - -The `bytes32 bondId` can be constructed using the `keccak256` hash of a given identifier. -For example, the `L2OutputOracle` can create a `bondId` by taking the `keccak256` hash of -the `l2BlockNumber` associated with the output proposal since there will only ever be one -outstanding output proposal for a given `l2BlockNumber`. -This also avoids the issue where an output proposer can have multiple bonds if bonds were -instead tied to the address of the output proposer. - -## Bond Manager Implementation - -Initially, the bond manager will only be used by the `L2OutputOracle` contract -for output proposals in the attestation [dispute game](./dispute-game-interface.md). Since -the attestation dispute game has a permissioned set of attestors, there are no -intermediate steps in the game that would require bonds. - -In the future however, Fault-based dispute games will be introduced and will -require bond management. In addition to the bond posted by the output proposer, -bonds will be posted at each step of the dispute game. Once the game is resolved, -bonds are dispersed to either the output challengers or defenders -(including the proposer). diff --git a/specs/bridges.md b/specs/bridges.md deleted file mode 100644 index 3c87747b202d..000000000000 --- a/specs/bridges.md +++ /dev/null @@ -1,51 +0,0 @@ -# Standard Bridges - - - -**Table of Contents** - -- [Token Depositing](#token-depositing) -- [Upgradability](#upgradability) - - - -The standard bridges are responsible for allowing cross domain -ETH and ERC20 token transfers. They are built on top of the cross domain -messenger contracts and give a standard interface for depositing tokens. - -The bridge works for both L1 native tokens and L2 native tokens. The legacy API -is preserved to ensure that existing applications will not experience any -problems with the Bedrock `StandardBridge` contracts. - -The `L2StandardBridge` is a predeploy contract located at -`0x4200000000000000000000000000000000000010`. - -```solidity -interface StandardBridge { - event ERC20BridgeFinalized(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData); - event ERC20BridgeInitiated(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData); - event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData); - event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData); - - function bridgeERC20(address _localToken, address _remoteToken, uint256 _amount, uint32 _minGasLimit, bytes memory _extraData) external; - function bridgeERC20To(address _localToken, address _remoteToken, address _to, uint256 _amount, uint32 _minGasLimit, bytes memory _extraData) external; - function bridgeETH(uint32 _minGasLimit, bytes memory _extraData) payable external; - function bridgeETHTo(address _to, uint32 _minGasLimit, bytes memory _extraData) payable external; - function deposits(address, address) view external returns (uint256); - function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes memory _extraData) external; - function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) payable external; - function messenger() view external returns (address); - function OTHER_BRIDGE() view external returns (address); -} -``` - -## Token Depositing - -The `bridgeERC20` function is used to send a token from one domain to another -domain. An `OptimismMintableERC20` token contract must exist on the remote -domain to be able to deposit tokens to that domain. One of these tokens can be -deployed using the `OptimismMintableERC20Factory` contract. - -## Upgradability - -Both the L1 and L2 standard bridges should be behind upgradable proxies. diff --git a/specs/cannon-fault-proof-vm.md b/specs/cannon-fault-proof-vm.md deleted file mode 100644 index c603b622b0e1..000000000000 --- a/specs/cannon-fault-proof-vm.md +++ /dev/null @@ -1,218 +0,0 @@ -# Cannon Fault Proof Virtual Machine Specification - - - -**Table of Contents** - -- [Overview](#overview) -- [State](#state) - - [State Hash](#state-hash) -- [Memory](#memory) - - [Heap](#heap) -- [Delay Slots](#delay-slots) -- [Syscalls](#syscalls) -- [I/O](#io) - - [Standard Streams](#standard-streams) - - [Hint Communication](#hint-communication) - - [Pre-image Communication](#pre-image-communication) - - [Pre-image I/O Alignment](#pre-image-io-alignment) -- [Exceptions](#exceptions) - - - -## Overview - -This is a description of the Cannon Fault Proof Virtual Machine (FPVM). The Cannon FPVM emulates -a minimal Linux-based system running on big-endian 32-bit MIPS32 architecture. -Alot of its behaviors are copied from Linux/MIPS with a few tweaks made for fault proofs. -For the rest of this doc, we refer to the Cannon FPVM as simply the FPVM. - -Operationally, the FPVM is a state transition function. This state transition is referred to as a *Step*, -that executes a single instruction. We say the VM is a function $f$, given an input state $S_{pre}$, steps on a -single instruction encoded in the state to produce a new state $S_{post}$. -$$f(S_{pre}) \rightarrow S_{post}$$ - -Thus, the trace of a program executed by the FPVM is an ordered set of VM states. - -## State - -The virtual machine state highlights the effects of running a Fault Proof Program on the VM. -It consists of the following fields: - -1. `memRoot` - A `bytes32` value representing the merkle root of VM memory. -2. `preimageKey` - `bytes32` value of the last requested pre-image key. -3. `preimageOffset` - The 32-bit value of the last requested pre-image offset. -4. `pc` - 32-bit program counter. -5. `nextPC` - 32-bit next program counter. Note that this value may not always be $pc+4$ - when executing a branch/jump delay slot. -6. `lo` - 32-bit MIPS LO special register. -7. `hi` - 32-bit MIPS HI special register. -8. `heap` - 32-bit base address of the most recent memory allocation via mmap. -9. `exitCode` - 8-bit exit code. -10. `exited` - 1-bit indicator that the VM has exited. -11. `registers` - General-purpose MIPS32 registers. Each register is a 32-bit value. - -The state is represented by packing the above fields, in order, into a 226-byte buffer. - -### State Hash - -The state hash is computed by hashing the 226-byte state buffer with the Keccak256 hash function -and then setting the high-order byte to the respective VM status. - -The VM status can be derived from the state's `exited` and `exitCode` fields. - -```rs -enum VmStatus { - Valid = 0, - Invalid = 1, - Panic = 2, - Unfinished = 3, -} - -fn vm_status(exit_code: u8, exited: bool) -> u8 { - if exited { - match exit_code { - 0 => VmStatus::Valid, - 1 => VmStatus::Invalid, - _ => VmStatus::Panic, - } - } else { - VmStatus::Unfinished - } -} -``` - -## Memory - -Memory is represented as a binary merkle tree. -The tree has a fixed-depth of 27 levels, with leaf values of 32 bytes each. -This spans the full 32-bit address space, where each leaf contains the memory at that part of the tree. -The state `memRoot` represents the merkle root of the tree, reflecting the effects of memory writes. -As a result of this memory representation, all memory operations are 4-byte aligned. -Memory access doesn't require any privileges. An instruction step can access any memory -location as the entire address space is unprotected. - -### Heap - -FPVM state contains a `heap` that tracks the base address of the most recent memory allocation. -Heap pages are bump allocated at the page boundary, per `mmap` syscall. -mmap-ing is purely to satisfy program runtimes that need the memory-pointer -result of the syscall to locate free memory. The page size is 4096. - -The FPVM has a fixed program break at `0x40000000`. However, the FPVM is permitted to extend the -heap beyond this limit via mmap syscalls. -For simplicity, there are no memory protections against "heap overruns" against other memory segments. -Such VM steps are still considered valid state transitions. - -Specification of memory mappings is outside the scope of this document as it is irrelevant to -the VM state. FPVM implementers may refer to the Linux/MIPS kernel for inspiration. - -## Delay Slots - -The post-state of a step updates the `nextPC`, indicating the instruction following the `pc`. -However, in the case of where a branch instruction is being stepped, the `nextPC` post-state is -set to the branch target. And the `pc` post-state set to the branch delay slot as usual. - -A VM state transition is invalid whenever the current instruction is a delay slot that is filled -with jump or branch type instruction. -That is, where $nextPC \neq pc + 4$ while stepping on a jump/branch instruction. -Otherwise, there would be two consecutive delay slots. While this is considered "undefined" -behavior in typical MIPS implementations, FPVM must raise an exception when stepping on such states. - -## Syscalls - -Syscalls work similar to [Linux/MIPS](https://www.linux-mips.org/wiki/Syscall), including the -syscall calling conventions and general syscall handling behavior. -However, the FPVM supports a subset of Linux/MIPS syscalls with slightly different behaviors. -The following table list summarizes the supported syscalls and their behaviors. - -| $v0 | system call | $a0 | $a1 | $a2 | Effect | -| -- | -- | -- | -- | -- | -- | -| 4090 | mmap | uint32 addr | uint32 len | | Allocates a page from the heap. See [heap](#heap) for details. | -| 4045 | brk | | | | Returns a fixed address for the program break at `0x40000000` | -| 4120 | clone | | | | Returns 1 | -| 4246 | exit_group | uint8 exit_code | | | Sets the Exited and ExitCode states to `true` and `$a0` respectively. | -| 4003 | read | uint32 fd | char *buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned reads. See [I/O](#io) for more details. | -| 4004 | write | uint32 fd | char *buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned writes. See [I/O](#io) for more details. | -| 4055 | fcntl | uint32 fd | int32 cmd | | Similar behavior as Linux/MIPS. Only the `F_GETFL` (3) cmd is supported. Sets errno to `0x16` for all other commands | - -For all of the above syscalls, an error is indicated by setting the return -register (`$v0`) to `0xFFFFFFFF` (-1) and `errno` (`$a3`) is set accordingly. -The VM must not modify any register other than `$v0` and `$a3` during syscall handling. -For unsupported syscalls, the VM must do nothing except to zero out the syscall return (`$v0`) -and errno (`$a3`) registers. - -Note that the above syscalls have identical syscall numbers and ABIs as Linux/MIPS. - -## I/O - -The VM does not support Linux open(2). However, the VM can read from and write to a predefined set of file descriptors. -| Name | File descriptor | Description | -| ---- | --------------- | ----------- | -| stdin | 0 | read-only standard input stream. | -| stdout | 1 | write-only standaard output stream. | -| stderr | 2 | write-only standard error stream. | -| hint response | 3 | read-only. Used to read the status of [pre-image hinting](./fault-proof.md#hinting). | -| hint request | 4 | write-only. Used to provide [pre-image hints](./fault-proof.md#hinting) | -| pre-image response | 5 | read-only. Used to [read pre-images](./fault-proof.md#pre-image-communication). | -| pre-image request | 6 | write-only. Used to [request pre-images](./fault-proof.md#pre-image-communication). | - -Syscalls referencing unnkown file descriptors fail with an `EBADF` errno as done on Linux. - -Writing to and reading from standard output, input and error streams have no effect on the FPVM state. -FPVM implementations may use them for debugging purposes as long as I/O is stateless. - -All I/O operations are restricted to a maximum of 4 bytes per operation. -Any read or write syscall request exceeding this limit will be truncated to 4 bytes. -Consequently, the return value of read/write syscalls is at most 4, indicating the actual number of bytes read/written. - -### Standard Streams - -Writing to stderr/stdout standard stream always succeeds with the write count input returned, -effectively continuing execution without writing work. -Reading from stdin has no effect other than to return zero and errno set to 0, signalling that there is no input. - -### Hint Communication - -Hint requests and responses have no effect on the VM state other than setting the `$v0` return -register to the requested read/write count. -VM implementations may utilize hints to setup subsequent pre-image requests. - -### Pre-image Communication - -The `preimageKey` and `preimageOffset` state are updated via read/write syscalls to the pre-image -read and write file descriptors (see [I/O](#io)). -The `preimageKey` buffers the stream of bytes written to the pre-image write fd. -The `preimageKey` buffer is shifted to accomodate new bytes written to the end of it. -A write also resets the `preimageOffset` to 0, indicating the intent to read a new pre-image. - -When handling pre-image reads, the `preimageKey` is used to lookup the pre-image data from an Oracle. -A max 4-byte chunk of the pre-image at the `preimageOffset` is read to the specified address. -Each read operation increases the `preimageOffset` by the number of bytes requested -(truncated to 4 bytes and subject to alignment contraints). - -#### Pre-image I/O Alignment - -As mentioned earlier in [memory](#memory), all memory operations are 4-byte aligned. -Since pre-image I/O occurs on memory, all pre-image I/O operations must strictly adhere to alignment boundaries. -This means the start and end of a read/write operation must fall within the same alignment boundary. -If an operation were to violate this, the input `count` of the read/write syscall must be -truncated such that the effective address of the last byte read/written matches the input effective address. - -The VM must read/write the maximum amount of bytes possible without crossing the input address alignment boundary. -For example, the effect of a write request for a 3-byte aligned buffer must be exactly 3 bytes. -If the buffer is misaligned, then the VM may write less than 3 bytes depending on the size of the misalignment. - -## Exceptions - -The FPVM may raise an exception rather than output a post-state to signal an invalid state -transition. Nominally, the FPVM must raise an exception in at least the following cases: - -- Invalid instruction (either via an invalid opcode or an instruction referencing registers -outside the general purpose registers). -- Pre-image read at an offset larger than the size of the pre-image. -- Delay slot contains branch/jump instruction types. - -VM implementations may raise an exception in other cases that is specific to the implementation. -For example, an on-chain FPVM that relies on pre-supplied merkle proofs for memory access may -raise an exception if the supplied merkle proof does not match the pre-state `memRoot`. diff --git a/specs/deposits.md b/specs/deposits.md deleted file mode 100644 index 1535fa445dc7..000000000000 --- a/specs/deposits.md +++ /dev/null @@ -1,370 +0,0 @@ -# Deposits - - -[g-transaction-type]: glossary.md#transaction-type -[g-derivation]: glossary.md#L2-chain-derivation -[g-deposited]: glossary.md#deposited -[g-deposits]: glossary.md#deposits -[g-l1-attr-deposit]: glossary.md#l1-attributes-deposited-transaction -[g-user-deposited]: glossary.md#user-deposited-transaction -[g-eoa]: glossary.md#eoa -[g-exec-engine]: glossary.md#execution-engine - -[Deposited transactions][g-deposited], also known as [deposits][g-deposits] are transactions which -are initiated on L1, and executed on L2. This document outlines a new [transaction -type][g-transaction-type] for deposits. It also describes how deposits are initiated on L1, along -with the authorization and validation conditions on L2. - -**Vocabulary note**: *deposited transaction* refers specifically to an L2 transaction, while -*deposit* can refer to the transaction at various stages (for instance when it is deposited on L1). - - - -**Table of Contents** - -- [The Deposited Transaction Type](#the-deposited-transaction-type) - - [Source hash computation](#source-hash-computation) - - [Kinds of Deposited Transactions](#kinds-of-deposited-transactions) - - [Validation and Authorization of Deposited Transactions](#validation-and-authorization-of-deposited-transactions) - - [Execution](#execution) - - [Nonce Handling](#nonce-handling) -- [Deposit Receipt](#deposit-receipt) -- [L1 Attributes Deposited Transaction](#l1-attributes-deposited-transaction) -- [Special Accounts on L2](#special-accounts-on-l2) - - [L1 Attributes Depositor Account](#l1-attributes-depositor-account) - - [L1 Attributes Predeployed Contract](#l1-attributes-predeployed-contract) - - [L1 Attributes Predeployed Contract: Reference Implementation](#l1-attributes-predeployed-contract-reference-implementation) -- [User-Deposited Transactions](#user-deposited-transactions) - - [Deposit Contract](#deposit-contract) - - [Address Aliasing](#address-aliasing) - - [Deposit Contract Implementation: Optimism Portal](#deposit-contract-implementation-optimism-portal) - - - -## The Deposited Transaction Type - -[deposited-tx-type]: #the-deposited-transaction-type - -[Deposited transactions][g-deposited] have the following notable distinctions from existing -transaction types: - -1. They are derived from Layer 1 blocks, and must be included as part of the protocol. -2. They do not include signature validation (see [User-Deposited Transactions][user-deposited] - for the rationale). -3. They buy their L2 gas on L1 and, as such, the L2 gas is not refundable. - -We define a new [EIP-2718] compatible transaction type with the prefix `0x7E` to represent a deposit transaction. - -A deposit has the following fields -(rlp encoded in the order they appear here): - -[EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718 - -- `bytes32 sourceHash`: the source-hash, uniquely identifies the origin of the deposit. -- `address from`: The address of the sender account. -- `address to`: The address of the recipient account, or the null (zero-length) address if the - deposited transaction is a contract creation. -- `uint256 mint`: The ETH value to mint on L2. -- `uint256 value`: The ETH value to send to the recipient account. -- `uint64 gas`: The gas limit for the L2 transaction. -- `bool isSystemTx`: If true, the transaction does not interact with the L2 block gas pool. - - Note: boolean is disabled (enforced to be `false`) starting from the Regolith upgrade. -- `bytes data`: The calldata. - -In contrast to [EIP-155] transactions, this transaction type: - -- Does not include a `nonce`, since it is identified by the `sourceHash`. - API responses still include a `nonce` attribute: - - Before Regolith: the `nonce` is always `0` - - With Regolith: the `nonce` is set to the `depositNonce` attribute of the corresponding transaction receipt. -- Does not include signature information, and makes the `from` address explicit. - API responses contain zeroed signature `v`, `r`, `s` values for backwards compatibility. -- Includes new `sourceHash`, `from`, `mint`, and `isSystemTx` attributes. - API responses contain these as additional fields. - -[EIP-155]:https://eips.ethereum.org/EIPS/eip-155 - -We select `0x7E` because transaction type identifiers are currently allowed to go up to `0x7F`. -Picking a high identifier minimizes the risk that the identifier will be used be claimed by another -transaction type on the L1 chain in the future. We don't pick `0x7F` itself in case it becomes used -for a variable-length encoding scheme. - -### Source hash computation - -The `sourceHash` of a deposit transaction is computed based on the origin: - -- User-deposited: - `keccak256(bytes32(uint256(0)), keccak256(l1BlockHash, bytes32(uint256(l1LogIndex))))`. - Where the `l1BlockHash`, and `l1LogIndex` all refer to the inclusion of the deposit log event on L1. - `l1LogIndex` is the index of the deposit event log in the combined list of log events of the block. -- L1 attributes deposited: - `keccak256(bytes32(uint256(1)), keccak256(l1BlockHash, bytes32(uint256(seqNumber))))`. - Where `l1BlockHash` refers to the L1 block hash of which the info attributes are deposited. - And `seqNumber = l2BlockNum - l2EpochStartBlockNum`, - where `l2BlockNum` is the L2 block number of the inclusion of the deposit tx in L2, - and `l2EpochStartBlockNum` is the L2 block number of the first L2 block in the epoch. - -Without a `sourceHash` in a deposit, two different deposited transactions could have the same exact hash. - -The outer `keccak256` hashes the actual uniquely identifying information with a domain, -to avoid collisions between different types of sources. - -We do not use the sender's nonce to ensure uniqueness because this would require an extra L2 EVM state read from the -[execution engine][g-exec-engine] during block-derivation. - -### Kinds of Deposited Transactions - -Although we define only one new transaction type, we can distinguish between two kinds of deposited -transactions, based on their positioning in the L2 block: - -1. The first transaction MUST be a [L1 attributes deposited transaction][l1-attr-deposit], followed by -2. an array of zero-or-more [user-deposited transactions][user-deposited] - submitted to the deposit feed contract on L1 (called `OptimismPortal`). - User-deposited transactions are only present in the first block of a L2 epoch. - -We only define a single new transaction type in order to minimize modifications to L1 client -software, and complexity in general. - -### Validation and Authorization of Deposited Transactions - -[authorization]: #validation-and-authorization-of-deposited-transaction - -As noted above, the deposited transaction type does not include a signature for validation. Rather, -authorization is handled by the [L2 chain derivation][g-derivation] process, which when correctly -applied will only derive transactions with a `from` address attested to by the logs of the [L1 -deposit contract][deposit-contract]. - -### Execution - -In order to execute a deposited transaction: - -First, the balance of the `from` account MUST be increased by the amount of `mint`. -This is unconditional, and does not revert on deposit failure. - -Then, the execution environment for a deposited transaction is initialized based on the -transaction's attributes, in exactly the same manner as it would be for an EIP-155 transaction. - -The deposit transaction is processed exactly like a type-3 (EIP-1559) transaction, with the exception of: - -- No fee fields are verified: the deposit does not have any, as it pays for gas on L1. -- No `nonce` field is verified: the deposit does not have any, it's uniquely identified by its `sourceHash`. -- No access-list is processed: the deposit has no access-list, and it is thus processed as if the access-list is empty. -- No check if `from` is an Externally Owner Account (EOA): the deposit is ensured not to be an EOA through L1 address - masking, this may change in future L1 contract-deployments to e.g. enable an account-abstraction like mechanism. -- Before the Regolith upgrade: - - The execution output states a non-standard gas usage: - - If `isSystemTx` is false: execution output states it uses `gasLimit` gas. - - If `isSystemTx` is true: execution output states it uses `0` gas. -- No gas is refunded as ETH. (either by not refunding or utilizing the fact the gas-price of the deposit is `0`) -- No transaction priority fee is charged. No payment is made to the block fee-recipient. -- No L1-cost fee is charged, as deposits are derived from L1 and do not have to be submitted as data back to it. -- No base fee is charged. The total base fee accounting does not change. - -Note that this includes contract-deployment behavior like with regular transactions, -and gas metering is the same (with the exception of fee related changes above), including metering of intrinsic gas. - -Any non-EVM state-transition error emitted by the EVM execution is processed in a special way: - -- It is transformed into an EVM-error: - i.e. the deposit will always be included, but its receipt will indicate a failure - if it runs into a non-EVM state-transition error, e.g. failure to transfer the specified - `value` amount of ETH due to insufficient account-balance. -- The world state is rolled back to the start of the EVM processing, after the minting part of the deposit. -- The `nonce` of `from` in the world state is incremented by 1, making the error equivalent to a native EVM failure. - Note that a previous `nonce` increment may have happened during EVM processing, but this would be rolled back first. - -Finally, after the above processing, the execution post-processing runs the same: -i.e. the gas pool and receipt are processed identical to a regular transaction. -Starting with the Regolith upgrade however, the receipt of deposit transactions is extended with an additional -`depositNonce` value, storing the `nonce` value of the `from` sender as registered *before* the EVM processing. - -Note that the gas used as stated by the execution output is subtracted from the gas pool, -but this execution output value has special edge cases before the Regolith upgrade. - -Note for application developers: because `CALLER` and `ORIGIN` are set to `from`, the -semantics of using the `tx.origin == msg.sender` check will not work to determine whether -or not a caller is an EOA during a deposit transaction. Instead, the check could only be useful for -identifying the first call in the L2 deposit transaction. However this check does still satisfy -the common case in which developers are using this check to ensure that the `CALLER` is unable to -execute code before and after the call. - -#### Nonce Handling - -Despite the lack of signature validation, we still increment the nonce of the `from` account when a -deposit transaction is executed. In the context of a deposit-only roll up, this is not necessary -for transaction ordering or replay prevention, however it maintains consistency with the use of -nonces during [contract creation][create-nonce]. It may also simplify integration with downstream -tooling (such as wallets and block explorers). - -[create-nonce]: https://github.com/ethereum/execution-specs/blob/617903a8f8d7b50cf71bf1aa733c37897c8d75c1/src/ethereum/frontier/utils/address.py#L40 - -## Deposit Receipt - -Transaction receipts use standard typing as per [EIP-2718]. -The Deposit transaction receipt type is equal to a regular receipt, -but extended with an optional `depositNonce` field. - -The RLP-encoded consensus-enforced fields are: - -- `postStateOrStatus` (standard): this contains the transaction status, see [EIP-658]. -- `cumulativeGasUsed` (standard): gas used in the block thus far, including this transaction. - - The actual gas used is derived from the difference in `CumulativeGasUsed` with the previous transaction. - - Starting with Regolith, this accounts for the actual gas usage by the deposit, like regular transactions. -- `bloom` (standard): bloom filter of the transaction logs. -- `logs` (standard): log events emitted by the EVM processing. -- `depositNonce` (unique extension): Optional field. The deposit transaction persists the nonce used during execution. - - Before Regolith, this `depositNonce` field must always be omitted. - - With Regolith, this `depositNonce` field must always be included. - -Starting with Regolith, the receipt API responses utilize the receipt changes for more accurate response data: - -- The `depositNonce` is included in the receipt JSON data in API responses -- For contract-deployments (when `to == null`), the `depositNonce` helps derive the correct `contractAddress` meta-data, - instead of assuming the nonce was zero. -- The `cumulativeGasUsed` accounts for the actual gas usage, as metered in the EVM processing. - -[EIP-658]: https://eips.ethereum.org/EIPS/eip-658 - -## L1 Attributes Deposited Transaction - -[l1-attr-deposit]: #l1-attributes-deposited-transaction - -An [L1 attributes deposited transaction][g-l1-attr-deposit] is a deposit transaction sent to the [L1 -attributes predeployed contract][predeploy]. - -This transaction MUST have the following values: - -1. `from` is `0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001` (the address of the -[L1 Attributes depositor account][depositor-account]) -2. `to` is `0x4200000000000000000000000000000000000015` (the address of the [L1 attributes predeployed - contract][predeploy]). -3. `mint` is `0` -4. `value` is `0` -5. `gasLimit` is set to 150,000,000. -6. `isSystemTx` is set to `true`. -7. `data` is an [ABI] encoded call to the [L1 attributes predeployed contract][predeploy]'s - `setL1BlockValues()` function with correct values associated with the corresponding L1 block (cf. - [reference implementation][l1-attr-ref-implem]). - -If the Regolith upgrade is active, some fields are overridden: - -1. `gasLimit` is set to 1,000,000 -2. `isSystemTx` is set to `false` - -This system-initiated transaction for L1 attributes is not charged any ETH for its allocated `gasLimit`, -as it is effectively part of the state-transition processing. - -## Special Accounts on L2 - -The L1 attributes deposit transaction involves two special purpose accounts: - -1. The L1 attributes depositor account -2. The L1 attributes predeployed contract - -### L1 Attributes Depositor Account - -[depositor-account]: #l1-attributes-depositor-account - -The depositor account is an [EOA][g-eoa] with no known private key. It has the address -`0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001`. Its value is returned by the `CALLER` and `ORIGIN` -opcodes during execution of the L1 attributes deposited transaction. - -### L1 Attributes Predeployed Contract - -[predeploy]: #l1-attributes-predeployed-contract - -A predeployed contract on L2 at address `0x4200000000000000000000000000000000000015`, which holds -certain block variables from the corresponding L1 block in storage, so that they may be accessed -during the execution of the subsequent deposited transactions. - -The predeploy stores the following values: - -- L1 block attributes: - - `number` (`uint64`) - - `timestamp` (`uint64`) - - `basefee` (`uint256`) - - `hash` (`bytes32`) -- `sequenceNumber` (`uint64`): This equals the L2 block number relative to the start of the epoch, - i.e. the L2 block distance to the L2 block height that the L1 attributes last changed, - and reset to 0 at the start of a new epoch. -- System configurables tied to the L1 block, see [System configuration specification](./system_config.md): - - `batcherHash` (`bytes32`): A versioned commitment to the batch-submitter(s) currently operating. - - `overhead` (`uint256`): The L1 fee overhead to apply to L1 cost computation of transactions in this L2 block. - - `scalar` (`uint256`): The L1 fee scalar to apply to L1 cost computation of transactions in this L2 block. - -The contract implements an authorization scheme, such that it only accepts state-changing calls from -the [depositor account][depositor-account]. - -The contract has the following solidity interface, and can be interacted with according to the -[contract ABI specification][ABI]. - -[ABI]: https://docs.soliditylang.org/en/v0.8.10/abi-spec.html - -#### L1 Attributes Predeployed Contract: Reference Implementation - -[l1-attr-ref-implem]: #l1-attributes-predeployed-contract-reference-implementation - -A reference implementation of the L1 Attributes predeploy contract can be found in [L1Block.sol]. - -[L1Block.sol]: ../packages/contracts-bedrock/src/L2/L1Block.sol - -After running `pnpm build` in the `packages/contracts-bedrock` directory, the bytecode to add to -the genesis file will be located in the `deployedBytecode` field of the build artifacts file at -`/packages/contracts-bedrock/forge-artifacts/L1Block.sol/L1Block.json`. - -## User-Deposited Transactions - -[user-deposited]: #user-deposited-transactions - -[User-deposited transactions][g-user-deposited] are [deposited transactions][deposited-tx-type] -generated by the [L2 Chain Derivation][g-derivation] process. The content of each user-deposited -transaction are determined by the corresponding `TransactionDeposited` event emitted by the -[deposit contract][deposit-contract] on L1. - -1. `from` is unchanged from the emitted value (though it may - have been transformed to an alias in `OptimismPortal`, the deposit feed contract). -2. `to` is any 20-byte address (including the zero address) - - In case of a contract creation (cf. `isCreation`), this address is set to `null`. -3. `mint` is set to the emitted value. -4. `value` is set to the emitted value. -5. `gaslimit` is unchanged from the emitted value. It must be at least 21000. -6. `isCreation` is set to `true` if the transaction is a contract creation, `false` otherwise. -7. `data` is unchanged from the emitted value. Depending on the value of `isCreation` it is handled - as either calldata or contract initialization code. -8. `isSystemTx` is set by the rollup node for certain transactions that have unmetered execution. - It is `false` for user deposited transactions - -### Deposit Contract - -[deposit-contract]: #deposit-contract - -The deposit contract is deployed to L1. Deposited transactions are derived from the values in -the `TransactionDeposited` event(s) emitted by the deposit contract. - -The deposit contract is responsible for maintaining the [guaranteed gas market](./guaranteed-gas-market.md), -charging deposits for gas to be used on L2, and ensuring that the total amount of guaranteed -gas in a single L1 block does not exceed the L2 block gas limit. - -The deposit contract handles two special cases: - -1. A contract creation deposit, which is indicated by setting the `isCreation` flag to `true`. - In the event that the `to` address is non-zero, the contract will revert. -2. A call from a contract account, in which case the `from` value is transformed to its L2 - [alias][address-aliasing]. - -#### Address Aliasing - -[address-aliasing]: #address-aliasing - -If the caller is a contract, the address will be transformed by adding -`0x1111000000000000000000000000000000001111` to it. The math is `unchecked` and done on a -Solidity `uint160` so the value will overflow. This prevents attacks in which a -contract on L1 has the same address as a contract on L2 but doesn't have the same code. We can safely ignore this -for EOAs because they're guaranteed to have the same "code" (i.e. no code at all). This also makes -it possible for users to interact with contracts on L2 even when the Sequencer is down. - -#### Deposit Contract Implementation: Optimism Portal - -A reference implementation of the deposit contract can be found in [OptimismPortal.sol]. - -[OptimismPortal.sol]: ../packages/contracts-bedrock/src/L1/OptimismPortal.sol diff --git a/specs/derivation.md b/specs/derivation.md deleted file mode 100644 index 7201d54a5d98..000000000000 --- a/specs/derivation.md +++ /dev/null @@ -1,951 +0,0 @@ -# L2 Chain Derivation Specification - - -[g-derivation]: glossary.md#L2-chain-derivation -[g-payload-attr]: glossary.md#payload-attributes -[g-block]: glossary.md#block -[g-exec-engine]: glossary.md#execution-engine -[g-reorg]: glossary.md#chain-re-organization -[g-receipts]: glossary.md#receipt -[g-inception]: glossary.md#L2-chain-inception -[g-deposit-contract]: glossary.md#deposit-contract -[g-deposited]: glossary.md#deposited-transaction -[g-l1-attr-deposit]: glossary.md#l1-attributes-deposited-transaction -[g-user-deposited]: glossary.md#user-deposited-transaction -[g-deposits]: glossary.md#deposits -[g-deposit-contract]: glossary.md#deposit-contract -[g-l1-attr-predeploy]: glossary.md#l1-attributes-predeployed-contract -[g-depositing-call]: glossary.md#depositing-call -[g-depositing-transaction]: glossary.md#depositing-transaction -[g-sequencing]: glossary.md#sequencing -[g-sequencer]: glossary.md#sequencer -[g-sequencing-epoch]: glossary.md#sequencing-epoch -[g-sequencing-window]: glossary.md#sequencing-window -[g-sequencer-batch]: glossary.md#sequencer-batch -[g-l2-genesis]: glossary.md#l2-genesis-block -[g-l2-chain-inception]: glossary.md#L2-chain-inception -[g-batcher-transaction]: glossary.md#batcher-transaction -[g-avail-provider]: glossary.md#data-availability-provider -[g-batcher]: glossary.md#batcher -[g-l2-output]: glossary.md#l2-output-root -[g-fault-proof]: glossary.md#fault-proof -[g-channel]: glossary.md#channel -[g-channel-frame]: glossary.md#channel-frame -[g-rollup-node]: glossary.md#rollup-node -[g-channel-timeout]: glossary.md#channel-timeout -[g-block-time]: glossary.md#block-time -[g-time-slot]: glossary.md#time-slot -[g-consolidation]: glossary.md#unsafe-block-consolidation -[g-safe-l2-head]: glossary.md#safe-l2-head -[g-safe-l2-block]: glossary.md#safe-l2-block -[g-unsafe-l2-head]: glossary.md#unsafe-l2-head -[g-unsafe-l2-block]: glossary.md#unsafe-l2-block -[g-unsafe-sync]: glossary.md#unsafe-sync -[g-l1-origin]: glossary.md#l1-origin -[g-deposit-tx-type]: glossary.md#deposited-transaction-type -[g-finalized-l2-head]: glossary.md#finalized-l2-head -[g-system-config]: glossary.md#system-configuration - - - -**Table of Contents** - -- [Overview](#overview) - - [Eager Block Derivation](#eager-block-derivation) -- [Batch Submission](#batch-submission) - - [Sequencing & Batch Submission Overview](#sequencing--batch-submission-overview) - - [Batch Submission Wire Format](#batch-submission-wire-format) - - [Batcher Transaction Format](#batcher-transaction-format) - - [Frame Format](#frame-format) - - [Channel Format](#channel-format) - - [Batch Format](#batch-format) -- [Architecture](#architecture) - - [L2 Chain Derivation Pipeline](#l2-chain-derivation-pipeline) - - [L1 Traversal](#l1-traversal) - - [L1 Retrieval](#l1-retrieval) - - [Frame Queue](#frame-queue) - - [Channel Bank](#channel-bank) - - [Pruning](#pruning) - - [Timeouts](#timeouts) - - [Reading](#reading) - - [Loading frames](#loading-frames) - - [Channel Reader (Batch Decoding)](#channel-reader-batch-decoding) - - [Batch Queue](#batch-queue) - - [Payload Attributes Derivation](#payload-attributes-derivation) - - [Engine Queue](#engine-queue) - - [Engine API usage](#engine-api-usage) - - [Forkchoice synchronization](#forkchoice-synchronization) - - [L1-consolidation: payload attributes matching](#l1-consolidation-payload-attributes-matching) - - [L1-sync: payload attributes processing](#l1-sync-payload-attributes-processing) - - [Processing unsafe payload attributes](#processing-unsafe-payload-attributes) - - [Resetting the Pipeline](#resetting-the-pipeline) - - [Finding the sync starting point](#finding-the-sync-starting-point) - - [Resetting derivation stages](#resetting-derivation-stages) - - [About reorgs Post-Merge](#about-reorgs-post-merge) -- [Deriving Payload Attributes](#deriving-payload-attributes) - - [Deriving the Transaction List](#deriving-the-transaction-list) - - [Building Individual Payload Attributes](#building-individual-payload-attributes) - - - -# Overview - -> **Note** the following assumes a single sequencer and batcher. In the future, the design will be adapted to -> accommodate multiple such entities. - -[L2 chain derivation][g-derivation] — deriving L2 [blocks][g-block] from L1 data — is one of the main responsibility of -the [rollup node][g-rollup-node], both in validator mode, and in sequencer mode (where derivation acts as a sanity check -on sequencing, and enables detecting L1 chain [re-organizations][g-reorg]). - -The L2 chain is derived from the L1 chain. In particular, each L1 block is mapped to an L2 [sequencing -epoch][g-sequencing-epoch] comprising multiple L2 blocks. The epoch number is defined to be equal to the corresponding -L1 block number. - -To derive the L2 blocks in an epoch `E`, we need the following inputs: - -- The L1 [sequencing window][g-sequencing-window] for epoch `E`: the L1 blocks in the range `[E, E + SWS)` where `SWS` - is the sequencing window size (note that this means that epochs are overlapping). In particular, we need: - - The [batcher transactions][g-batcher-transaction] included in the sequencing window. These allow us to - reconstruct [sequencer batches][g-sequencer-batch] containing the transactions to include in L2 blocks (each batch - contains a list of L2 blocks). - - Note that it is impossible to have a batcher transaction containing a batch relative to epoch `E` on L1 block - `E`, as the batch must contain the hash of L1 block `E`. - - The [deposits][g-deposits] made in L1 block `E` (in the form of events emitted by the [deposit - contract][g-deposit-contract]). - - The L1 block attributes from L1 block `E` (to derive the [L1 attributes deposited transaction][g-l1-attr-deposit]). -- The state of the L2 chain after the last L2 block of epoch `E - 1`, or — if epoch `E - 1` does not exist — the - [L2 genesis state][g-l2-genesis]. - - An epoch `E` does not exist if `E <= L2CI`, where `L2CI` is the [L2 chain inception][g-l2-chain-inception]. - -To derive the whole L2 chain from scratch, we simply start with the [L2 genesis state][g-l2-genesis], and the [L2 chain -inception][g-l2-chain-inception] as first epoch, then process all sequencing windows in order. Refer to the -[Architecture section][architecture] for more information on how we implement this in practice. -The L2 chain may contain pre-Bedrock history, but the L2 genesis here refers to the first Bedrock L2 block. - -Each epoch may contain a variable number of L2 blocks (one every `l2_block_time`, 2s on Optimism), at the discretion of -[the sequencer][g-sequencer], but subject to the following constraints for each block: - -- `min_l2_timestamp <= block.timestamp <= max_l2_timestamp`, where - - all these values are denominated in seconds - - `min_l2_timestamp = l1_timestamp` - - This ensures that the L2 timestamp is not behind the L1 origin timestamp. - - `block.timestamp = prev_l2_timestamp + l2_block_time` - - `prev_l2_timestamp` is the timestamp of the last L2 block of the previous epoch - - `l2_block_time` is a configurable parameter of the time between L2 blocks (on Optimism, 2s) - - `max_l2_timestamp = max(l1_timestamp + max_sequencer_drift, min_l2_timestamp + l2_block_time)` - - `l1_timestamp` is the timestamp of the L1 block associated with the L2 block's epoch - - `max_sequencer_drift` is the most a sequencer is allowed to get ahead of L1 - -Put together, these constraints mean that there must be an L2 block every `l2_block_time` seconds, and that the -timestamp for the first L2 block of an epoch must never fall behind the timestamp of the L1 block matching the epoch. - -Post-merge, Ethereum has a fixed [block time][g-block-time] of 12s (though some slots can be skipped). It is thus -expected that with a 2-second L2 block time, most of the time, each epoch will contain `12/2 = 6` L2 blocks. -The sequencer can however lengthen or shorten epochs (subject to above constraints). -The rationale is to maintain liveness in case of either a skipped slot on L1, or a temporary loss of connection to L1 — -which requires longer epochs. -Shorter epochs are then required to avoid L2 timestamps drifting further and further ahead of L1. - -Note that `min_l2_timestamp + l2_block_time` ensures that a new L2 batch can always be processed, even if the -`max_sequencer_drift` is exceeded. However, when exceeding the `max_sequencer_drift`, progression to the next L1 origin -is enforced, with an exception to ensure the minimum timestamp bound (based on this next L1 origin) can be met in the -next L2 batch, and `len(batch.transactions) == 0` continues to be enforced while the `max_sequencer_drift` is exceeded. -See [Batch Queue] for more details. - -## Eager Block Derivation - -In practice, it is often not necessary to wait for a full sequencing window of L1 blocks in order to start deriving the -L2 blocks in an epoch. Indeed, as long as we are able to reconstruct sequential batches, we can start deriving the -corresponding L2 blocks. We call this *eager block derivation*. - -However, in the very worst case, we can only reconstruct the batch for the first L2 block in the epoch by reading the -last L1 block of the sequencing window. This happens when some data for that batch is included in the last L1 block of -the window. In that case, not only can we not derive the first L2 block in the epoch, we also cannot derive any further -L2 block in the epoch until then, as they need the state that results from applying the epoch's first L2 block. -(Note that this only applies to *block* derivation. Batches can still be derived and tentatively queued, -we just won't be able to create blocks from them.) - ------------------------------------------------------------------------------------------------------------------------- - -# Batch Submission - -## Sequencing & Batch Submission Overview - -The [sequencer][g-sequencer] accepts L2 transactions from users. It is responsible for building blocks out of these. For -each such block, it also creates a corresponding [sequencer batch][g-sequencer-batch]. It is also responsible for -submitting each batch to a [data availability provider][g-avail-provider] (e.g. Ethereum calldata), which it does via -its [batcher][g-batcher] component. - -The difference between an L2 block and a batch is subtle but important: the block includes an L2 state root, whereas the -batch only commits to transactions at a given L2 timestamp (equivalently: L2 block number). A block also includes a -reference to the previous block (\*). - -(\*) This matters in some edge case where a L1 reorg would occur and a batch would be reposted to the L1 chain but not -the preceding batch, whereas the predecessor of an L2 block cannot possibly change. - -This means that even if the sequencer applies a state transition incorrectly, the transactions in the batch will still -be considered part of the canonical L2 chain. Batches are still subject to validity checks (i.e. they have to be encoded -correctly), and so are individual transactions within the batch (e.g. signatures have to be valid). Invalid batches and -invalid individual transactions within an otherwise valid batch are discarded by correct nodes. - -If the sequencer applies a state transition incorrectly and posts an [output root][g-l2-output], then this output root -will be incorrect. The incorrect output root which will be challenged by a [fault proof][g-fault-proof], then replaced -by a correct output root **for the existing sequencer batches.** - -Refer to the [Batch Submission specification][batcher-spec] for more information. - -[batcher-spec]: batcher.md - -## Batch Submission Wire Format - -[wire-format]: #batch-submission-wire-format - -Batch submission is closely tied to L2 chain derivation because the derivation process must decode the batches that have -been encoded for the purpose of batch submission. - -The [batcher][g-batcher] submits [batcher transactions][g-batcher-transaction] to a [data availability -provider][g-avail-provider]. These transactions contain one or multiple [channel frames][g-channel-frame], which are -chunks of data belonging to a [channel][g-channel]. - -A [channel][g-channel] is a sequence of [sequencer batches][g-sequencer-batch] (for any L2 blocks) compressed -together. The reason to group multiple batches together is simply to obtain a better compression rate, hence reducing -data availability costs. - -Channels might be too large to fit in a single [batcher transaction][g-batcher-transaction], hence we need to split it -into chunks known as [channel frames][g-channel-frame]. A single batcher transaction can also carry multiple frames -(belonging to the same or to different channels). - -This design gives use the maximum flexibility in how we aggregate batches into channels, and split channels over batcher -transactions. It notably allows us to maximize data utilisation in a batcher transaction: for instance it allows us to -pack the final (small) frame of a window with large frames from the next window. - -In the future this channel identification feature also allows the [batcher][g-batcher] to employ multiple signers -(private keys) to submit one or multiple channels in parallel (1). - -(1) This helps alleviate issues where, because of transaction nonce values affecting the L2 tx-pool and thus inclusion: -multiple transactions made by the same signer are stuck waiting on the inclusion of a previous transaction. - -Also note that we use a streaming compression scheme, and we do not need to know how many blocks a channel will end up -containing when we start a channel, or even as we send the first frames in the channel. - -And by splitting channels across multiple data transactions, the L2 can have larger block data than the -data-availability layer may support. - -All of this is illustrated in the following diagram. Explanations below. - -![batch derivation chain diagram](./assets/batch-deriv-chain.svg) - -The first line represents L1 blocks with their numbers. The boxes under the L1 blocks represent [batcher -transactions][g-batcher-transaction] included within the block. The squiggles under the L1 blocks represent -[deposits][g-deposits] (more specifically, events emitted by the [deposit contract][g-deposit-contract]). - -Each colored chunk within the boxes represents a [channel frame][g-channel-frame]. So `A` and `B` are -[channels][g-channel] whereas `A0`, `A1`, `B0`, `B1`, `B2` are frames. Notice that: - -- multiple channels are interleaved -- frames do not need to be transmitted in order -- a single batcher transaction can carry frames from multiple channels - -In the next line, the rounded boxes represent individual [sequencer batches][g-sequencer-batch] that were extracted from -the channels. The four blue/purple/pink were derived from channel `A` while the other were derived from channel `B`. -These batches are here represented in the order they were decoded from batches (in this case `B` is decoded first). - -> **Note** The caption here says "Channel B was seen first and will be decoded into batches first", but this is not a -> requirement. For instance, it would be equally acceptable for an implementation to peek into the channels and decode -> the one that contains the oldest batches first. - -The rest of the diagram is conceptually distinct from the first part and illustrates L2 chain derivation after the -channels have been reordered. - -The first line shows batcher transactions. Note that in this case, there exists an ordering of the batches that makes -all frames within the channels appear contiguously. This is not true in general. For instance, in the second -transaction, the position of `A1` and `B0` could have been inverted for exactly the same result — no changes needed in -the rest of the diagram. - -The second line shows the reconstructed channels in proper order. The third line shows the batches extracted from the -channel. Because the channels are ordered and the batches within a channel are sequential, this means the batches are -ordered too. The fourth line shows the [L2 block][g-block] derived from each batch. Note that we have a 1-1 batch to -block mapping here but, as we'll see later, empty blocks that do not map to batches can be inserted in cases where there -are "gaps" in the batches posted on L1. - -The fifth line shows the [L1 attributes deposited transaction][g-l1-attr-deposit] which, within each L2 block, records -information about the L1 block that matches the L2 block's epoch. The first number denotes the epoch/L1x number, while -the second number (the "sequence number") denotes the position within the epoch. - -Finally, the sixth line shows [user-deposited transactions][g-user-deposited] derived from the [deposit -contract][g-deposit-contract] event mentioned earlier. - -Note the `101-0` L1 attributes transaction on the bottom right of the diagram. Its presence there is only possible if -frame `B2` indicates that it is the last frame within the channel and (2) no empty blocks must be inserted. - -The diagram does not specify the sequencing window size in use, but from this we can infer that it must be at least 4 -blocks, because the last frame of channel `A` appears in block 102, but belong to epoch 99. - -As for the comment on "security types", it explains the classification of blocks as used on L1 and L2. - -- [Unsafe L2 blocks][g-unsafe-l2-block]: -- [Safe L2 blocks][g-safe-l2-block]: -- Finalized L2 blocks: refer to block that have been derived from [finalized][g-finalized-l2-head] L1 data. - -These security levels map to the `headBlockHash`, `safeBlockHash` and `finalizedBlockHash` values transmitted when -interacting with the [execution-engine API][exec-engine]. - -### Batcher Transaction Format - -Batcher transactions are encoded as `version_byte ++ rollup_payload` (where `++` denotes concatenation). - -| `version_byte` | `rollup_payload` | -|----------------|------------------------------------------------| -| 0 | `frame ...` (one or more frames, concatenated) | - -Unknown versions make the batcher transaction invalid (it must be ignored by the rollup node). -All frames in a batcher transaction must be parseable. If any one frame fails to parse, the all frames in the -transaction are rejected. - -Batch transactions are authenticated by verifying that the `to` address of the transaction matches the batch inbox -address, and the `from` address matches the batch-sender address in the [system configuration][g-system-config] at the -time of the L1 block that the transaction data is read from. - -### Frame Format - -A [channel frame][g-channel-frame] is encoded as: - -```text -frame = channel_id ++ frame_number ++ frame_data_length ++ frame_data ++ is_last - -channel_id = bytes16 -frame_number = uint16 -frame_data_length = uint32 -frame_data = bytes -is_last = bool -``` - -Where `uint32` and `uint16` are all big-endian unsigned integers. Type names should be interpreted to and -encoded according to [the Solidity ABI][solidity-abi]. - -[solidity-abi]: https://docs.soliditylang.org/en/v0.8.16/abi-spec.html - -All data in a frame is fixed-size, except the `frame_data`. The fixed overhead is `16 + 2 + 4 + 1 = 23 bytes`. -Fixed-size frame metadata avoids a circular dependency with the target total data length, -to simplify packing of frames with varying content length. - -where: - -- `channel_id` is an opaque identifier for the channel. It should not be reused and is suggested to be random; however, -outside of timeout rules, it is not checked for validity -- `frame_number` identifies the index of the frame within the channel -- `frame_data_length` is the length of `frame_data` in bytes. It is capped to 1,000,000 bytes. -- `frame_data` is a sequence of bytes belonging to the channel, logically after the bytes from the previous frames -- `is_last` is a single byte with a value of 1 if the frame is the last in the channel, 0 if there are frames in the - channel. Any other value makes the frame invalid (it must be ignored by the rollup node). - -[batcher-spec]: batching.md - -### Channel Format - -A channel is encoded as `channel_encoding`, defined as: - -```text -rlp_batches = [] -for batch in batches: - rlp_batches.append(batch) -channel_encoding = compress(rlp_batches) -``` - -where: - -- `batches` is the input, a sequence of batches byte-encoded as per the next section ("Batch Encoding") -- `rlp_batches` is the concatenation of the RLP-encoded batches -- `compress` is a function performing compression, using the ZLIB algorithm (as specified in [RFC-1950][rfc1950]) with - no dictionary -- `channel_encoding` is the compressed version of `rlp_batches` - -[rfc1950]: https://www.rfc-editor.org/rfc/rfc1950.html - -When decompressing a channel, we limit the amount of decompressed data to `MAX_RLP_BYTES_PER_CHANNEL` (currently -10,000,000 bytes), in order to avoid "zip-bomb" types of attack (where a small compressed input decompresses to a -humongous amount of data). If the decompressed data exceeds the limit, things proceeds as though the channel contained -only the first `MAX_RLP_BYTES_PER_CHANNEL` decompressed bytes. The limit is set on RLP decoding, so all batches that -can be decoded in `MAX_RLP_BYTES_PER_CHANNEL` will be accepted even if the size of the channel is greater than -`MAX_RLP_BYTES_PER_CHANNEL`. The exact requirement is that `length(input) <= MAX_RLP_BYTES_PER_CHANNEL`. - -While the above pseudocode implies that all batches are known in advance, it is possible to perform streaming -compression and decompression of RLP-encoded batches. This means it is possible to start including channel frames in a -[batcher transaction][g-batcher-transaction] before we know how many batches (and how many frames) the channel will -contain. - -### Batch Format - -[batch-format]: #batch-format - -Recall that a batch contains a list of transactions to be included in a specific L2 block. - -A batch is encoded as `batch_version ++ content`, where `content` depends on the `batch_version`: - -| `batch_version` | `content` | -|-----------------|------------------------------------------------------------------------------------| -| 0 | `rlp_encode([parent_hash, epoch_number, epoch_hash, timestamp, transaction_list])` | - -where: - -- `batch_version` is a single byte, prefixed before the RLP contents, alike to transaction typing. -- `rlp_encode` is a function that encodes a batch according to the [RLP format], and `[x, y, z]` denotes a list - containing items `x`, `y` and `z` -- `parent_hash` is the block hash of the previous L2 block -- `epoch_number` and `epoch_hash` are the number and hash of the L1 block corresponding to the [sequencing - epoch][g-sequencing-epoch] of the L2 block -- `timestamp` is the timestamp of the L2 block -- `transaction_list` is an RLP-encoded list of [EIP-2718] encoded transactions. - -[RLP format]: https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/ -[EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718 - -Unknown versions make the batch invalid (it must be ignored by the rollup node), as do malformed contents. - -The `epoch_number` and the `timestamp` must also respect the constraints listed in the [Batch Queue][batch-queue] -section, otherwise the batch is considered invalid and will be ignored. - ------------------------------------------------------------------------------------------------------------------------- - -# Architecture - -[architecture]: #architecture - -The above primarily describes the general encodings used in L2 chain derivation, -primarily how batches are encoded within [batcher transactions][g-batcher-transaction]. - -This section describes how the L2 chain is produced from the L1 batches using a pipeline architecture. - -A verifier may implement this differently, but must be semantically equivalent to not diverge from the L2 chain. - -## L2 Chain Derivation Pipeline - -[pipeline]: #l2-chain-derivation-pipeline - -Our architecture decomposes the derivation process into a pipeline made up of the following stages: - -1. L1 Traversal -2. L1 Retrieval -3. Frame Queue -4. Channel Bank -5. Channel Reader (Batch Decoding) -6. Batch Queue -7. Payload Attributes Derivation -8. Engine Queue - -The data flows from the start (outer) of the pipeline towards the end (inner). -From the innermost stage the data is pulled from the outermost stage. - -However, data is *processed* in reverse order. Meaning that if there is any data to be processed in the last stage, it -will be processed first. Processing proceeds in "steps" that can be taken at each stage. We try to take as many steps as -possible in the last (most inner) stage before taking any steps in its outer stage, etc. - -This ensures that we use the data we already have before pulling more data and minimizes the latency of data traversing -the derivation pipeline. - -Each stage can maintain its own inner state as necessary. In particular, each stage maintains a L1 block reference -(number + hash) to the latest L1 block such that all data originating from previous blocks has been fully processed, and -the data from that block is being or has been processed. This allows the innermost stage to account for finalization of -the L1 data-availability used to produce the L2 chain, to reflect in the L2 chain forkchoice when the L2 chain inputs -become irreversible. - -Let's briefly describe each stage of the pipeline. - -### L1 Traversal - -In the *L1 Traversal* stage, we simply read the header of the next L1 block. In normal operations, these will be new -L1 blocks as they get created, though we can also read old blocks while syncing, or in case of an L1 [re-org][g-reorg]. - -Upon traversal of the L1 block, the [system configuration][g-system-config] copy used by the L1 retrieval stage is -updated, such that the batch-sender authentication is always accurate to the exact L1 block that is read by the stage. - -### L1 Retrieval - -In the *L1 Retrieval* stage, we read the block we get from the outer stage (L1 traversal), and extract data from it. -By default, the rollup operates on calldata retrieved from [batcher transactions][g-batcher-transaction] in the block, -for each transaction: - -- The receiver must be the configured batcher inbox address. -- The sender must match the batcher address loaded from the system config matching the L1 block of the data. - -Each data-transaction is versioned and contains a series of [channel frames][g-channel-frame] to be read by the -Frame Queue, see [Batch Submission Wire Format][wire-format]. - -### Frame Queue - -The Frame Queue buffers one data-transaction at a time, -decoded into [channel frames][g-channel-frame], to be consumed by the next stage. -See [Batcher transaction format](#batcher-transaction-format) and [Frame format](#frame-format) specifications. - -### Channel Bank - -The *Channel Bank* stage is responsible for managing buffering from the channel bank that was written to by the L1 -retrieval stage. A step in the channel bank stage tries to read data from channels that are "ready". - -Channels are currently fully buffered until read or dropped, -streaming channels may be supported in a future version of the ChannelBank. - -To bound resource usage, the Channel Bank prunes based on channel size, and times out old channels. - -Channels are recorded in FIFO order in a structure called the *channel queue*. A channel is added to the channel -queue the first time a frame belonging to the channel is seen. - -#### Pruning - -After successfully inserting a new frame, the ChannelBank is pruned: -channels are dropped in FIFO order, until `total_size <= MAX_CHANNEL_BANK_SIZE`, where: - -- `total_size` is the sum of the sizes of each channel, which is the sum of all buffered frame data of the channel, - with an additional frame-overhead of `200` bytes per frame. -- `MAX_CHANNEL_BANK_SIZE` is a protocol constant of 100,000,000 bytes. - -#### Timeouts - -The L1 origin that the channel was opened in is tracked with the channel as `channel.open_l1_block`, -and determines the maximum span of L1 blocks that the channel data is retained for, before being pruned. - -A channel is timed out if: `current_l1_block.number > channel.open_l1_block.number + CHANNEL_TIMEOUT`, where: - -- `current_l1_block` is the L1 origin that the stage is currently traversing. -- `CHANNEL_TIMEOUT` is a rollup-configurable, expressed in number of L1 blocks. - -New frames for timed-out channels are dropped instead of buffered. - -#### Reading - -Upon reading, while the first opened channel is timed-out, remove it from the channel-bank. - -Prior to the Canyon network upgrade, once the first opened channel, if any, is not timed-out and is ready, -then it is read and removed from the channel-bank. After the Canyon network upgrade, the entire channel bank -is scanned in FIFO order (by open time) & the first ready (i.e. not timed-out) channel will be returned. - -The canyon behavior will activate when frames from a L1 block whose timestamp is greater than or equal to the -canyon time first enter the channel queue. - -A channel is ready if: - -- The channel is closed -- The channel has a contiguous sequence of frames until the closing frame - -If no channel is ready, the next frame is read and ingested into the channel bank. - -#### Loading frames - -When a channel ID referenced by a frame is not already present in the Channel Bank, -a new channel is opened, tagged with the current L1 block, and appended to the channel-queue. - -Frame insertion conditions: - -- New frames matching timed-out channels that have not yet been pruned from the channel-bank are dropped. -- Duplicate frames (by frame number) for frames that have not been pruned from the channel-bank are dropped. -- Duplicate closes (new frame `is_last == 1`, but the channel has already seen a closing frame and has not yet been - pruned from the channel-bank) are dropped. - -If a frame is closing (`is_last == 1`) any existing higher-numbered frames are removed from the channel. - -Note that while this allows channel IDs to be reused once they have been pruned from the channel-bank, it is recommended -that batcher implementations use unique channel IDs. - -### Channel Reader (Batch Decoding) - -In this stage, we decompress the channel we pull from the last stage, and then parse -[batches][g-sequencer-batch] from the decompressed byte stream. - -See [Batch Format][batch-format] for decompression and decoding specification. - -### Batch Queue - -[batch-queue]: #batch-queue - -During the *Batch Buffering* stage, we reorder batches by their timestamps. If batches are missing for some [time -slots][g-time-slot] and a valid batch with a higher timestamp exists, this stage also generates empty batches to fill -the gaps. - -Batches are pushed to the next stage whenever there is one sequential batch directly following the timestamp -of the current [safe L2 head][g-safe-l2-head] (the last block that can be derived from the canonical L1 chain). -The parent hash of the batch must also match the hash of the current safe L2 head. - -Note that the presence of any gaps in the batches derived from L1 means that this stage will need to buffer for a whole -[sequencing window][g-sequencing-window] before it can generate empty batches (because the missing batch(es) could have -data in the last L1 block of the window in the worst case). - -A batch can have 4 different forms of validity: - -- `drop`: the batch is invalid, and will always be in the future, unless we reorg. It can be removed from the buffer. -- `accept`: the batch is valid and should be processed. -- `undecided`: we are lacking L1 information until we can proceed batch filtering. -- `future`: the batch may be valid, but cannot be processed yet and should be checked again later. - -The batches are processed in order of the inclusion on L1: if multiple batches can be `accept`-ed the first is applied. -An implementation can defer `future` batches a later derivation step to reduce validation work. - -The batches validity is derived as follows: - -Definitions: - -- `batch` as defined in the [Batch format section][batch-format]. -- `epoch = safe_l2_head.l1_origin` a [L1 origin][g-l1-origin] coupled to the batch, with properties: - `number` (L1 block number), `hash` (L1 block hash), and `timestamp` (L1 block timestamp). -- `inclusion_block_number` is the L1 block number when `batch` was first *fully* derived, - i.e. decoded and output by the previous stage. -- `next_timestamp = safe_l2_head.timestamp + block_time` is the expected L2 timestamp the next batch should have, - see [block time information][g-block-time]. -- `next_epoch` may not be known yet, but would be the L1 block after `epoch` if available. -- `batch_origin` is either `epoch` or `next_epoch`, depending on validation. - -Note that processing of a batch can be deferred until `batch.timestamp <= next_timestamp`, -since `future` batches will have to be retained anyway. - -Rules, in validation order: - -- `batch.timestamp > next_timestamp` -> `future`: i.e. the batch must be ready to process. -- `batch.timestamp < next_timestamp` -> `drop`: i.e. the batch must not be too old. -- `batch.parent_hash != safe_l2_head.hash` -> `drop`: i.e. the parent hash must be equal to the L2 safe head block hash. -- `batch.epoch_num + sequence_window_size < inclusion_block_number` -> `drop`: i.e. the batch must be included timely. -- `batch.epoch_num < epoch.number` -> `drop`: i.e. the batch origin is not older than that of the L2 safe head. -- `batch.epoch_num == epoch.number`: define `batch_origin` as `epoch`. -- `batch.epoch_num == epoch.number+1`: - - If `next_epoch` is not known -> `undecided`: - i.e. a batch that changes the L1 origin cannot be processed until we have the L1 origin data. - - If known, then define `batch_origin` as `next_epoch` -- `batch.epoch_num > epoch.number+1` -> `drop`: i.e. the L1 origin cannot change by more than one L1 block per L2 block. -- `batch.epoch_hash != batch_origin.hash` -> `drop`: i.e. a batch must reference a canonical L1 origin, - to prevent batches from being replayed onto unexpected L1 chains. -- `batch.timestamp < batch_origin.time` -> `drop`: enforce the min L2 timestamp rule. -- `batch.timestamp > batch_origin.time + max_sequencer_drift`: enforce the L2 timestamp drift rule, - but with exceptions to preserve above min L2 timestamp invariant: - - `len(batch.transactions) == 0`: - - `epoch.number == batch.epoch_num`: - this implies the batch does not already advance the L1 origin, and must thus be checked against `next_epoch`. - - If `next_epoch` is not known -> `undecided`: - without the next L1 origin we cannot yet determine if time invariant could have been kept. - - If `batch.timestamp >= next_epoch.time` -> `drop`: - the batch could have adopted the next L1 origin without breaking the `L2 time >= L1 time` invariant. - - `len(batch.transactions) > 0`: -> `drop`: - when exceeding the sequencer time drift, never allow the sequencer to include transactions. -- `batch.transactions`: `drop` if the `batch.transactions` list contains a transaction - that is invalid or derived by other means exclusively: - - any transaction that is empty (zero length byte string) - - any [deposited transactions][g-deposit-tx-type] (identified by the transaction type prefix byte) - -If no batch can be `accept`-ed, and the stage has completed buffering of all batches that can fully be read from the L1 -block at height `epoch.number + sequence_window_size`, and the `next_epoch` is available, -then an empty batch can be derived with the following properties: - -- `parent_hash = safe_l2_head.hash` -- `timestamp = next_timestamp` -- `transactions` is empty, i.e. no sequencer transactions. Deposited transactions may be added in the next stage. -- If `next_timestamp < next_epoch.time`: the current L1 origin is repeated, to preserve the L2 time invariant. - - `epoch_num = epoch.number` - - `epoch_hash = epoch.hash` -- If the batch is the first batch of the epoch, that epoch is used instead of advancing the epoch to ensure that -there is at least one L2 block per epoch. - - `epoch_num = epoch.number` - - `epoch_hash = epoch.hash` -- Otherwise, - - `epoch_num = next_epoch.number` - - `epoch_hash = next_epoch.hash` - -### Payload Attributes Derivation - -In the *Payload Attributes Derivation* stage, we convert the batches we get from the previous stage into instances of -the [`PayloadAttributes`][g-payload-attr] structure. Such a structure encodes the transactions that need to figure into -a block, as well as other block inputs (timestamp, fee recipient, etc). Payload attributes derivation is detailed in the -section [Deriving Payload Attributes section][deriving-payload-attr] below. - -This stage maintains its own copy of the [system configuration][g-system-config], independent of the L1 retrieval stage. -The system configuration is updated with L1 log events whenever the L1 epoch referenced by the batch input changes. - -### Engine Queue - -In the *Engine Queue* stage, the previously derived `PayloadAttributes` structures are buffered and sent to the -[execution engine][g-exec-engine] to be executed and converted into a proper L2 block. - -The stage maintains references to three L2 blocks: - -- The [finalized L2 head][g-finalized-l2-head]: everything up to and including this block can be fully derived from the - [finalized][l1-finality] (i.e. canonical and forever irreversible) part of the L1 chain. -- The [safe L2 head][g-safe-l2-head]: everything up to and including this block can be fully derived from the - currently canonical L1 chain. -- The [unsafe L2 head][g-unsafe-l2-head]: blocks between the safe and unsafe heads are [unsafe - blocks][g-unsafe-l2-block] that have not been derived from L1. These blocks either come from sequencing (in sequencer - mode) or from [unsafe sync][g-unsafe-sync] to the sequencer (in validator mode). - This is also known as the "latest" head. - -Additionally, it buffers a short history of references to recently processed safe L2 blocks, along with references -from which L1 blocks each was derived. -This history does not have to be complete, but enables later L1 finality signals to be translated into L2 finality. - -#### Engine API usage - -To interact with the engine, the [execution engine API][exec-engine] is used, with the following JSON-RPC methods: - -[exec-engine]: exec-engine.md - -- [`engine_forkchoiceUpdatedV2`] — updates the forkchoice (i.e. the chain head) to `headBlockHash` if different, and - instructs the engine to start building an execution payload if the payload attributes parameter is not `null`. -- [`engine_getPayloadV2`] — retrieves a previously requested execution payload build. -- [`engine_newPayloadV2`] — executes an execution payload to create a block. - -The current version of `op-node` uses the `v2` RPC methods from the engine API, whereas prior versions used the `v1` -equivalents. The `v2` methods are backwards compatible with `v1` payloads but support Shanghai. - -[`engine_forkchoiceUpdatedV2`]: exec-engine.md#engine_forkchoiceupdatedv2 -[`engine_getPayloadV2`]: exec-engine.md#engine_getpayloadv2 -[`engine_newPayloadV2`]: exec-engine.md#engine_newpayloadv2 - -The execution payload is an object of type [`ExecutionPayloadV2`][eth-payload]. - -[eth-payload]: https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#payloadattributesv2 - -With V2 of the execution payload, before Canyon the withdrawals field is required to be nil. After Canyon the -withdrawals field is required to be non-nil. The op-node should set the withdrawals field to be an empty list. - -#### Forkchoice synchronization - -If there are any forkchoice updates to be applied, before additional inputs are derived or processed, then these are -applied to the engine first. - -This synchronization may happen when: - -- A L1 finality signal finalizes one or more L2 blocks: updating the "finalized" L2 block. -- A successful consolidation of unsafe L2 blocks: updating the "safe" L2 block. -- The first thing after a derivation pipeline reset, to ensure a consistent execution engine forkchoice state. - -The new forkchoice state is applied with `engine_forkchoiceUpdatedV2`. -On forkchoice-state validity errors the derivation pipeline must be reset to recover to consistent state. - -#### L1-consolidation: payload attributes matching - -If the unsafe head is ahead of the safe head, then [consolidation][g-consolidation] is attempted, verifying that -existing unsafe L2 chain matches the derived L2 inputs as derived from the canonical L1 data. - -During consolidation, we consider the oldest unsafe L2 block, i.e. the unsafe L2 block directly after the safe head. If -the payload attributes match this oldest unsafe L2 block, then that block can be considered "safe" and becomes the new -safe head. - -The following fields of the derived L2 payload attributes are checked for equality with the L2 block: - -- `parent_hash` -- `timestamp` -- `randao` -- `fee_recipient` -- `transactions_list` (first length, then equality of each of the encoded transactions, including deposits) - -If consolidation succeeds, the forkchoice change will synchronize as described in the section above. - -If consolidation fails, the L2 payload attributes will be processed immediately as described in the section below. -The payload attributes are chosen in favor of the previous unsafe L2 block, creating an L2 chain reorg on top of the -current safe block. Immediately processing the new alternative attributes enables execution engines like go-ethereum to -enact the change, as linear rewinds of the tip of the chain may not be supported. - -#### L1-sync: payload attributes processing - -[exec-engine-comm]: exec-engine.md#engine-api - -If the safe and unsafe L2 heads are identical (whether because of failed consolidation or not), we send the L2 payload -attributes to the execution engine to be constructed into a proper L2 block. -This L2 block will then become both the new L2 safe and unsafe head. - -If a payload attributes created from a batch cannot be inserted into the chain because of a validation error (i.e. there -was an invalid transaction or state transition in the block) the batch should be dropped & the safe head should not be -advanced. The engine queue will attempt to use the next batch for that timestamp from the batch queue. If no valid batch -is found, the rollup node will create a deposit only batch which should always pass validation because deposits are -always valid. - -Interaction with the execution engine via the execution engine API is detailed in the [Communication with the Execution -Engine][exec-engine-comm] section. - -The payload attributes are then processed with a sequence of: - -- `engine_forkchoiceUpdatedV2` with current forkchoice state of the stage, and the attributes to start block building. - - Non-deterministic sources, like the tx-pool, must be disabled to reconstruct the expected block. -- `engine_getPayload` to retrieve the payload, by the payload-ID in the result of the previous step. -- `engine_newPayload` to import the new payload into the execution engine. -- `engine_forkchoiceUpdatedV2` to make the new payload canonical, - now with a change of both `safe` and `unsafe` fields to refer to the payload, and no payload attributes. - -Engine API Error handling: - -- On RPC-type errors the payload attributes processing should be re-attempted in a future step. -- On payload processing errors the attributes must be dropped, and the forkchoice state must be left unchanged. - - Eventually the derivation pipeline will produce alternative payload attributes, with or without batches. - - If the payload attributes only contained deposits, then it is a critical derivation error if these are invalid. -- On forkchoice-state validity errors the derivation pipeline must be reset to recover to consistent state. - -#### Processing unsafe payload attributes - -If no forkchoice updates or L1 data remain to be processed, and if the next possible L2 block is already available -through an unsafe source such as the sequencer publishing it via the p2p network, then it is optimistically processed as -an "unsafe" block. This reduces later derivation work to just consolidation with L1 in the happy case, and enables the -user to see the head of the L2 chain faster than the L1 may confirm the L2 batches. - -To process unsafe payloads, the payload must: - -- Have a block number higher than the current safe L2 head. - - The safe L2 head may only be reorged out due to L1 reorgs. -- Have a parent blockhash that matches the current unsafe L2 head. - - This prevents the execution engine individually syncing a larger gap in the unsafe L2 chain. - - This prevents unsafe L2 blocks from reorging other previously validated L2 blocks. - - This check may change in the future versions to adopt e.g. the L1 snap-sync protocol. - -The payload is then processed with a sequence of: - -- `engine_newPayloadV2`: process the payload. It does not become canonical yet. -- `engine_forkchoiceUpdatedV2`: make the payload the canonical unsafe L2 head, and keep the safe/finalized L2 heads. - -Engine API Error handling: - -- On RPC-type errors the payload processing should be re-attempted in a future step. -- On payload processing errors the payload must be dropped, and not be marked as canonical. -- On forkchoice-state validity errors the derivation pipeline must be reset to recover to consistent state. - -### Resetting the Pipeline - -It is possible to reset the pipeline, for instance if we detect an L1 [reorg (reorganization)][g-reorg]. -**This enables the rollup node to handle L1 chain reorg events.** - -Resetting will recover the pipeline into a state that produces the same outputs as a full L2 derivation process, -but starting from an existing L2 chain that is traversed back just enough to reconcile with the current L1 chain. - -Note that this algorithm covers several important use-cases: - -- Initialize the pipeline without starting from 0, e.g. when the rollup node restarts with an existing engine instance. -- Recover the pipeline if it becomes inconsistent with the execution engine chain, e.g. when the engine syncs/changes. -- Recover the pipeline when the L1 chain reorganizes, e.g. a late L1 block is orphaned, or a larger attestation failure. -- Initialize the pipeline to derive a disputed L2 block with prior L1 and L2 history inside a fault-proof program. - -Handling these cases also means a node can be configured to eagerly sync L1 data with 0 confirmations, -as it can undo the changes if the L1 later does recognize the data as canonical, enabling safe low-latency usage. - -The Engine Queue is first reset, to determine the L1 and L2 starting points to continue derivation from. -After this, the other stages are reset independent of each other. - -#### Finding the sync starting point - -To find the starting point, there are several steps, relative to the head of the chain traversing back: - -1. Find the current L2 forkchoice state - - If no `finalized` block can be found, start at the Bedrock genesis block. - - If no `safe` block can be found, fallback to the `finalized` block. - - The `unsafe` block should always be available and consistent with the above - (it may not be in rare engine-corruption recovery cases, this is being reviewed). -2. Find the first L2 block with plausible L1 reference to be the new `unsafe` starting point, - starting from previous `unsafe`, back to `finalized` and no further. - - Plausible iff: the L1 origin of the L2 block is known and canonical, or unknown and has a block-number ahead of L1. -3. Find the first L2 block with an L1 reference older than the sequencing window, to be the new `safe` starting point, - starting at the above plausible `unsafe` head, back to `finalized` and no further. - - If at any point the L1 origin is known but not canonical, the `unsafe` head is revised to parent of the current. - - The highest L2 block with known canonical L1 origin is remembered as `highest`. - - If at any point the L1 origin in the block is corrupt w.r.t. derivation rules, then error. Corruption includes: - - Inconsistent L1 origin block number or parent-hash with parent L1 origin - - Inconsistent L1 sequence number (always changes to `0` for a L1 origin change, or increments by `1` if not) - - If the L1 origin of the L2 block `n` is older than the L1 origin of `highest` by more than a sequence window, - and `n.sequence_number == 0`, then the parent L2 block of `n` will be the `safe` starting point. -4. The `finalized` L2 block persists as the `finalized` starting point. -5. Find the first L2 block with an L1 reference older than the channel-timeout - - The L1 origin referenced by this block which we call `l2base` will be the `base` for the L2 pipeline derivation: - By starting here, the stages can buffer any necessary data, while dropping incomplete derivation outputs until - L1 traversal has caught up with the actual L2 safe head. - -While traversing back the L2 chain, an implementation may sanity-check that the starting point is never set too far -back compared to the existing forkchoice state, to avoid an intensive reorg because of misconfiguration. - -Implementers note: step 1-4 are known as `FindL2Heads`. Step 5 is currently part of the Engine Queue reset. -This may change to isolate the starting-point search from the bare reset logic. - -#### Resetting derivation stages - -1. L1 Traversal: start at L1 `base` as first block to be pulled by next stage. -2. L1 Retrieval: empty previous data, and fetch the `base` L1 data, or defer the fetching work to a later pipeline step. -3. Frame Queue: empty the queue. -4. Channel Bank: empty the channel bank. -5. Channel Reader: reset any batch decoding state. -6. Batch Queue: empty the batch queue, use `base` as initial L1 point of reference. -7. Payload Attributes Derivation: empty any batch/attributes state. -8. Engine Queue: - - Initialize L2 forkchoice state with syncing start point state. (`finalized`/`safe`/`unsafe`) - - Initialize the L1 point of reference of the stage to `base`. - - Require a forkchoice update as first task - - Reset any finality data - -Where necessary, stages starting at `base` can initialize their system-config from data encoded in the `l2base` block. - -#### About reorgs Post-Merge - -Note that post-[merge], the depth of reorgs will be bounded by the [L1 finality delay][l1-finality] -(2 L1 beacon epochs, or approximately 13 minutes, unless more than 1/3 of the network consistently disagrees). -New L1 blocks may be finalized every L1 beacon epoch (approximately 6.4 minutes), and depending on these -finality-signals and batch-inclusion, the derived L2 chain will become irreversible as well. - -Note that this form of finalization only affects inputs, and nodes can then subjectively say the chain is irreversible, -by reproducing the chain from these irreversible inputs and the set protocol rules and parameters. - -This is however completely unrelated to the outputs posted on L1, which require a form of proof like a fault-proof or -zk-proof to finalize. Optimistic-rollup outputs like withdrawals on L1 are only labeled "finalized" after passing a week -without dispute (fault proof challenge window), a name-collision with the proof-of-stake finalization. - -[merge]: https://ethereum.org/en/upgrades/merge/ -[l1-finality]: https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/#finality - ------------------------------------------------------------------------------------------------------------------------- - -# Deriving Payload Attributes - -[deriving-payload-attr]: #deriving-payload-attributes - -For every L2 block derived from L1 data, we need to build [payload attributes][g-payload-attr], -represented by an [expanded version][expanded-payload] of the [`PayloadAttributesV1`][eth-payload] object, -which includes additional `transactions` and `noTxPool` fields. - -This process happens during the payloads-attributes queue ran by a verifier node, as well as during block-production -ran by a sequencer node (the sequencer may enable the tx-pool usage if the transactions are batch-submitted). - -[expanded-payload]: exec-engine.md#extended-payloadattributesv1 -[eth-payload]: https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#payloadattributesv1 - -## Deriving the Transaction List - -For each L2 block to be created by the sequencer, we start from a [sequencer batch][g-sequencer-batch] matching the -target L2 block number. This could potentially be an empty auto-generated batch, if the L1 chain did not include a batch -for the target L2 block number. [Remember][batch-format] that the batch includes a [sequencing -epoch][g-sequencing-epoch] number, an L2 timestamp, and a transaction list. - -This block is part of a [sequencing epoch][g-sequencing-epoch], -whose number matches that of an L1 block (its *[L1 origin][g-l1-origin]*). -This L1 block is used to derive L1 attributes and (for the first L2 block in the epoch) user deposits. - -Therefore, a [`PayloadAttributesV1`][expanded-payload] object must include the following transactions: - -- one or more [deposited transactions][g-deposited], of two kinds: - - a single *[L1 attributes deposited transaction][g-l1-attr-deposit]*, derived from the L1 origin. - - for the first L2 block in the epoch, zero or more *[user-deposited transactions][g-user-deposited]*, derived from - the [receipts][g-receipts] of the L1 origin. -- zero or more *[sequenced transactions][g-sequencing]*: regular transactions signed by L2 users, included in the - sequencer batch. - -Transactions **must** appear in this order in the payload attributes. - -The L1 attributes are read from the L1 block header, while deposits are read from the L1 block's [receipts][g-receipts]. -Refer to the [**deposit contract specification**][deposit-contract-spec] for details on how deposits are encoded as log -entries. - -[deposit-contract-spec]: deposits.md#deposit-contract - -## Building Individual Payload Attributes - -[payload attributes]: #building-individual-payload-attributes - -After deriving the transactions list, the rollup node constructs a [`PayloadAttributesV1`][extended-attributes] as -follows: - -- `timestamp` is set to the batch's timestamp. -- `random` is set to the `prev_randao` L1 block attribute. -- `suggestedFeeRecipient` is set to the Sequencer Fee Vault address. See [Fee Vaults] specification. -- `transactions` is the array of the derived transactions: deposited transactions and sequenced transactions, all - encoded with [EIP-2718]. -- `noTxPool` is set to `true`, to use the exact above `transactions` list when constructing the block. -- `gasLimit` is set to the current `gasLimit` value in the [system configuration][g-system-config] of this payload. - -[extended-attributes]: exec-engine.md#extended-payloadattributesv1 -[Fee Vaults]: exec-engine.md#fee-vaults diff --git a/specs/dispute-game-interface.md b/specs/dispute-game-interface.md deleted file mode 100644 index 37d8b75c1e3a..000000000000 --- a/specs/dispute-game-interface.md +++ /dev/null @@ -1,236 +0,0 @@ -# Dispute Game Interface - - - -**Table of Contents** - -- [Overview](#overview) -- [Types](#types) -- [`DisputeGameFactory` Interface](#disputegamefactory-interface) -- [`DisputeGame` Interface](#disputegame-interface) - - - -## Overview - -A dispute game is played between multiple parties when contesting the truthiness -of a claim. In the context of an optimistic rollup, claims are made about the -state of the layer two network to enable withdrawals to the layer one. A proposer -makes a claim about the layer two state such that they can withdraw and a -challenger can dispute the validity of the claim. The security of the layer two -comes from the ability of fraudulent withdrawals being able to be disputed. - -A dispute game interface is defined to allow for multiple implementations of -dispute games to exist. If multiple dispute games run in production, it gives -a similar security model as having multiple protocol clients, as a bug in a -single dispute game will not result in the bug becoming consensus. - -## Types - -For added context, we define a few types that are used in the following snippets. - -```solidity - -/// @notice A custom type for a generic hash. -type Hash is bytes32; - -/// @notice A dedicated timestamp type. -type Timestamp is uint64; - -/// @notice The type of proof system being used. -enum GameType { - /// @dev The game will use a `IDisputeGame` implementation that utilizes fault proofs. - FAULT, - /// @dev The game will use a `IDisputeGame` implementation that utilizes validity proofs. - VALIDITY, - /// @dev The game will use a `IDisputeGame` implementation that utilizes attestation proofs. - ATTESTATION -} - -/// @notice The current status of the dispute game. -enum GameStatus { - /// @dev The game is currently in progress, and has not been resolved. - IN_PROGRESS, - /// @dev The game has concluded, and the `rootClaim` was challenged successfully. - CHALLENGER_WINS, - /// @dev The game has concluded, and the `rootClaim` could not be contested. - DEFENDER_WINS -} - -/// @notice A `Claim` type represents a 32 byte hash or other unique identifier for a claim about -/// a certain piece of information. -/// @dev For the `FAULT` `GameType`, this will be a root of the merklized state of the fault proof -/// program at the end of the state transition. -/// For the `ATTESTATION` `GameType`, this will be an output root. -type Claim is bytes32; -``` - -## `DisputeGameFactory` Interface - -The dispute game factory is responsible for creating new `DisputeGame` contracts -given a `GameType` and a root `Claim`. Challenger agents will listen to the -`DisputeGameCreated` events that are emitted by the factory as well as other events -that pertain to detecting fault (i.e. `OutputProposed(bytes32,uint256,uint256,uint256)`) in order to keep up -with on-going disputes in the protocol. - -A [`clones-with-immutable-args`](https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args) factory -(originally by @wighawag, but forked by @Saw-mon-and-Natalie) is used to create Clones. Each `GameType` has -a corresponding implementation within the factory, and when a new game is created, the factory creates a -clone of the `GameType`'s pre-deployed implementation contract. - -The `rootClaim` of created dispute games can either be a claim that the creator agrees or disagrees with. -This is an implementation detail that is left up to the `IDisputeGame` to handle within its `resolve` function. - -When the `DisputeGameFactory` creates a new `DisputeGame` contract, it calls `initialize()` on the clone to -set up the game. - -```solidity -/// @title IDisputeGameFactory -/// @notice The interface for a DisputeGameFactory contract. -interface IDisputeGameFactory { - /// @notice Emitted when a new dispute game is created - /// @param disputeProxy The address of the dispute game proxy - /// @param gameType The type of the dispute game proxy's implementation - /// @param rootClaim The root claim of the dispute game - event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim); - - /// @notice Emitted when a new game implementation added to the factory - /// @param impl The implementation contract for the given `GameType`. - /// @param gameType The type of the DisputeGame. - event ImplementationSet(address indexed impl, GameType indexed gameType); - - /// @notice The total number of dispute games created by this factory. - /// @return gameCount_ The total number of dispute games created by this factory. - function gameCount() external view returns (uint256 gameCount_); - - /// @notice `games` queries an internal mapping that maps the hash of - /// `gameType ++ rootClaim ++ extraData` to the deployed `DisputeGame` clone. - /// @dev `++` equates to concatenation. - /// @param _gameType The type of the DisputeGame - used to decide the proxy implementation - /// @param _rootClaim The root claim of the DisputeGame. - /// @param _extraData Any extra data that should be provided to the created dispute game. - /// @return proxy_ The clone of the `DisputeGame` created with the given parameters. - /// Returns `address(0)` if nonexistent. - /// @return timestamp_ The timestamp of the creation of the dispute game. - function games(GameType _gameType, Claim _rootClaim, bytes calldata _extraData) - external - view - returns (IDisputeGame proxy_, Timestamp timestamp_); - - /// @notice `gameAtIndex` returns the dispute game contract address and its creation timestamp - /// at the given index. Each created dispute game increments the underlying index. - /// @param _index The index of the dispute game. - /// @return gameType_ The type of the DisputeGame - used to decide the proxy implementation. - /// @return timestamp_ The timestamp of the creation of the dispute game. - /// @return proxy_ The clone of the `DisputeGame` created with the given parameters. - /// Returns `address(0)` if nonexistent. - function gameAtIndex(uint256 _index) - external - view - returns (GameType gameType_, Timestamp timestamp_, IDisputeGame proxy_); - - /// @notice `gameImpls` is a mapping that maps `GameType`s to their respective - /// `IDisputeGame` implementations. - /// @param _gameType The type of the dispute game. - /// @return impl_ The address of the implementation of the game type. - /// Will be cloned on creation of a new dispute game with the given `gameType`. - function gameImpls(GameType _gameType) external view returns (IDisputeGame impl_); - - /// @notice Creates a new DisputeGame proxy contract. - /// @param _gameType The type of the DisputeGame - used to decide the proxy implementation. - /// @param _rootClaim The root claim of the DisputeGame. - /// @param _extraData Any extra data that should be provided to the created dispute game. - /// @return proxy_ The address of the created DisputeGame proxy. - function create(GameType _gameType, Claim _rootClaim, bytes calldata _extraData) - external - returns (IDisputeGame proxy_); - - /// @notice Sets the implementation contract for a specific `GameType`. - /// @dev May only be called by the `owner`. - /// @param _gameType The type of the DisputeGame. - /// @param _impl The implementation contract for the given `GameType`. - function setImplementation(GameType _gameType, IDisputeGame _impl) external; - - /// @notice Returns a unique identifier for the given dispute game parameters. - /// @dev Hashes the concatenation of `gameType . rootClaim . extraData` - /// without expanding memory. - /// @param _gameType The type of the DisputeGame. - /// @param _rootClaim The root claim of the DisputeGame. - /// @param _extraData Any extra data that should be provided to the created dispute game. - /// @return uuid_ The unique identifier for the given dispute game parameters. - function getGameUUID(GameType _gameType, Claim _rootClaim, bytes memory _extraData) - external - pure - returns (Hash uuid_); -} -``` - -## `DisputeGame` Interface - -The dispute game interface should be generic enough to allow it to work with any -proof system. This means that it should work fault proofs, validity proofs, -an attestation based proof system, or any other source of truth that adheres to -the interface. - -Clones of the `IDisputeGame`'s `initialize` functions will be called by the `DisputeGameFactory` upon creation. - -```solidity -//////////////////////////////////////////////////////////////// -// GENERIC DISPUTE GAME // -//////////////////////////////////////////////////////////////// - -/// @title IDisputeGame -/// @notice The generic interface for a DisputeGame contract. -interface IDisputeGame { - /// @notice Initializes the DisputeGame contract. - /// @custom:invariant The `initialize` function may only be called once. - function initialize() external; - - /// @notice Emitted when the game is resolved. - /// @param status The status of the game after resolution. - event Resolved(GameStatus indexed status); - - /// @notice Returns the timestamp that the DisputeGame contract was created at. - function createdAt() external pure returns (Timestamp createdAt_); - - /// @notice Returns the current status of the game. - function status() external view returns (GameStatus status_); - - /// @notice Getter for the game type. - /// @dev `clones-with-immutable-args` argument #1 - /// @dev The reference impl should be entirely different depending on the type (fault, validity) - /// i.e. The game type should indicate the security model. - /// @return gameType_ The type of proof system being used. - function gameType() external view returns (GameType gameType_); - - /// @notice Getter for the root claim. - /// @return rootClaim_ The root claim of the DisputeGame. - /// @dev `clones-with-immutable-args` argument #2 - function rootClaim() external view returns (Claim rootClaim_); - - /// @notice Getter for the extra data. - /// @dev `clones-with-immutable-args` argument #3 - /// @return extraData_ Any extra data supplied to the dispute game contract by the creator. - function extraData() external view returns (bytes memory extraData_); - - /// @notice Returns the address of the `BondManager` used - function bondManager() public view returns (IBondManager bondManager_); - - /// @notice If all necessary information has been gathered, this function should mark the game - /// status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of - /// the resolved game. It is at this stage that the bonds should be awarded to the - /// necessary parties. - /// @dev May only be called if the `status` is `IN_PROGRESS`. - /// @return status_ The status of the game after resolution. - function resolve() public returns (GameStatus status_); - - /// @notice A compliant implementation of this interface should return the components of the - /// game UUID's preimage provided in the cwia payload. The preimage of the UUID is - /// constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes - /// concatenation. - /// @return gameType_ The type of proof system being used. - /// @return rootClaim_ The root claim of the DisputeGame. - /// @return extraData_ Any extra data supplied to the dispute game contract by the creator. - function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_); -} -``` diff --git a/specs/exec-engine.md b/specs/exec-engine.md deleted file mode 100644 index b72372ea78f3..000000000000 --- a/specs/exec-engine.md +++ /dev/null @@ -1,310 +0,0 @@ -# L2 Execution Engine - - - -**Table of Contents** - -- [Deposited transaction processing](#deposited-transaction-processing) - - [Deposited transaction boundaries](#deposited-transaction-boundaries) -- [Fees](#fees) - - [Fee Vaults](#fee-vaults) - - [Priority fees (Sequencer Fee Vault)](#priority-fees-sequencer-fee-vault) - - [Base fees (Base Fee Vault)](#base-fees-base-fee-vault) - - [L1-Cost fees (L1 Fee Vault)](#l1-cost-fees-l1-fee-vault) -- [Engine API](#engine-api) - - [`engine_forkchoiceUpdatedV2`](#engine_forkchoiceupdatedv2) - - [Extended PayloadAttributesV1](#extended-payloadattributesv1) - - [`engine_newPayloadV2`](#engine_newpayloadv2) - - [`engine_getPayloadV2`](#engine_getpayloadv2) - - [`engine_signalSuperchainV1`](#engine_signalsuperchainv1) -- [Networking](#networking) -- [Sync](#sync) - - [Happy-path sync](#happy-path-sync) - - [Worst-case sync](#worst-case-sync) - - - -This document outlines the modifications, configuration and usage of a L1 execution engine for L2. - -## Deposited transaction processing - -The Engine interfaces abstract away transaction types with [EIP-2718][eip-2718]. - -To support rollup functionality, processing of a new Deposit [`TransactionType`][eip-2718-transactions] -is implemented by the engine, see the [deposits specification][deposit-spec]. - -This type of transaction can mint L2 ETH, run EVM, -and introduce L1 information to enshrined contracts in the execution state. - -[deposit-spec]: deposits.md - -### Deposited transaction boundaries - -Transactions cannot be blindly trusted, trust is established through authentication. -Unlike other transaction types deposits are not authenticated by a signature: -the rollup node authenticates them, outside of the engine. - -To process deposited transactions safely, the deposits MUST be authenticated first: - -- Ingest directly through trusted Engine API -- Part of sync towards a trusted block hash (trusted through previous Engine API instruction) - -Deposited transactions MUST never be consumed from the transaction pool. -*The transaction pool can be disabled in a deposits-only rollup* - -## Fees - -Sequenced transactions (i.e. not applicable to deposits) are charged with 3 types of fees: -priority fees, base fees, and L1-cost fees. - -### Fee Vaults - -The three types of fees are collected in 3 distinct L2 fee-vault deployments for accounting purposes: -fee payments are not registered as internal EVM calls, and thus distinguished better this way. - -These are hardcoded addresses, pointing at pre-deployed proxy contracts. -The proxies are backed by vault contract deployments, based on `FeeVault`, to route vault funds to L1 securely. - -| Vault Name | Predeploy | -|---------------------|----------------------------------------------------------| -| Sequencer Fee Vault | [`SequencerFeeVault`](./predeploys.md#SequencerFeeVault) | -| Base Fee Vault | [`BaseFeeVault`](./predeploys.md#BaseFeeVault) | -| L1 Fee Vault | [`L1FeeVault`](./predeploys.md#L1FeeVault) | - -### Priority fees (Sequencer Fee Vault) - -Priority fees follow the [eip-1559] specification, and are collected by the fee-recipient of the L2 block. -The block fee-recipient (a.k.a. coinbase address) is set to the Sequencer Fee Vault address. - -### Base fees (Base Fee Vault) - -Base fees largely follow the [eip-1559] specification, with the exception that base fees are not burned, -but add up to the Base Fee Vault ETH account balance. - -### L1-Cost fees (L1 Fee Vault) - -The protocol funds batch-submission of sequenced L2 transactions by charging L2 users an additional fee -based on the estimated batch-submission costs. -This fee is charged from the L2 transaction-sender ETH balance, and collected into the L1 Fee Vault. - -The exact L1 cost function to determine the L1-cost fee component of a L2 transaction is calculated as: -`(rollupDataGas + l1FeeOverhead) * l1Basefee * l1FeeScalar / 1000000` -(big-int computation, result in Wei and `uint256` range) -Where: - -- `rollupDataGas` is determined from the *full* encoded transaction - (standard EIP-2718 transaction encoding, including signature fields): - - Before Regolith fork: `rollupDataGas = zeroes * 4 + (ones + 68) * 16` - - The addition of `68` non-zero bytes is a remnant of a pre-Bedrock L1-cost accounting function, - which accounted for the worst-case non-zero bytes addition to complement unsigned transactions, unlike Bedrock. - - With Regolith fork: `rollupDataGas = zeroes * 4 + ones * 16` -- `l1FeeOverhead` is the Gas Price Oracle `overhead` value. -- `l1FeeScalar` is the Gas Price Oracle `scalar` value. -- `l1Basefee` is the L1 Base fee of the latest L1 origin registered in the L2 chain. - -Note that the `rollupDataGas` uses the same byte cost accounting as defined in [eip-2028], -except the full L2 transaction now counts towards the bytes charged in the L1 calldata. -This behavior matches pre-Bedrock L1-cost estimation of L2 transactions. - -Compression, batching, and intrinsic gas costs of the batch transactions are accounted for by the protocol -with the Gas Price Oracle `overhead` and `scalar` parameters. - -The Gas Price Oracle `l1FeeOverhead` and `l1FeeScalar`, as well as the `l1Basefee` of the L1 origin, -can be accessed in two interchangeable ways: - -- read from the deposited L1 attributes (`l1FeeOverhead`, `l1FeeScalar`, `basefee`) of the current L2 block -- read from the L1 Block Info contract (`0x4200000000000000000000000000000000000015`) - - using the respective solidity `uint256`-getter functions (`l1FeeOverhead`, `l1FeeScalar`, `basefee`) - - using direct storage-reads: - - L1 basefee as big-endian `uint256` in slot `1` - - Overhead as big-endian `uint256` in slot `5` - - Scalar as big-endian `uint256` in slot `6` - -## Engine API - - - -### `engine_forkchoiceUpdatedV2` - -This updates which L2 blocks the engine considers to be canonical (`forkchoiceState` argument), -and optionally initiates block production (`payloadAttributes` argument). - -Within the rollup, the types of forkchoice updates translate as: - -- `headBlockHash`: block hash of the head of the canonical chain. Labeled `"unsafe"` in user JSON-RPC. - Nodes may apply L2 blocks out of band ahead of time, and then reorg when L1 data conflicts. -- `safeBlockHash`: block hash of the canonical chain, derived from L1 data, unlikely to reorg. -- `finalizedBlockHash`: irreversible block hash, matches lower boundary of the dispute period. - -To support rollup functionality, one backwards-compatible change is introduced -to [`engine_forkchoiceUpdatedV2`][engine_forkchoiceUpdatedV2]: the extended `PayloadAttributesV1` - -#### Extended PayloadAttributesV1 - -[`PayloadAttributesV1`][PayloadAttributesV1] is extended to: - -```js -PayloadAttributesV1: { - timestamp: QUANTITY - random: DATA (32 bytes) - suggestedFeeRecipient: DATA (20 bytes) - transactions: array of DATA - noTxPool: bool - gasLimit: QUANTITY or null -} -``` - -The type notation used here refers to the [HEX value encoding] used by the [Ethereum JSON-RPC API -specification][JSON-RPC-API], as this structure will need to be sent over JSON-RPC. `array` refers -to a JSON array. - -Each item of the `transactions` array is a byte list encoding a transaction: `TransactionType || -TransactionPayload` or `LegacyTransaction`, as defined in [EIP-2718][eip-2718]. -This is equivalent to the `transactions` field in [`ExecutionPayloadV1`][ExecutionPayloadV1] - -The `transactions` field is optional: - -- If empty or missing: no changes to engine behavior. The sequencers will (if enabled) build a block - by consuming transactions from the transaction pool. -- If present and non-empty: the payload MUST be produced starting with this exact list of transactions. - The [rollup driver][rollup-driver] determines the transaction list based on deterministic L1 inputs. - -The `noTxPool` is optional as well, and extends the `transactions` meaning: - -- If `false`, the execution engine is free to pack additional transactions from external sources like the tx pool - into the payload, after any of the `transactions`. This is the default behavior a L1 node implements. -- If `true`, the execution engine must not change anything about the given list of `transactions`. - -If the `transactions` field is present, the engine must execute the transactions in order and return `STATUS_INVALID` -if there is an error processing the transactions. It must return `STATUS_VALID` if all of the transactions could -be executed without error. **Note**: The state transition rules have been modified such that deposits will never fail -so if `engine_forkchoiceUpdatedV2` returns `STATUS_INVALID` it is because a batched transaction is invalid. - -The `gasLimit` is optional w.r.t. compatibility with L1, but required when used as rollup. -This field overrides the gas limit used during block-building. -If not specified as rollup, a `STATUS_INVALID` is returned. - -[rollup-driver]: rollup-node.md - -### `engine_newPayloadV2` - -No modifications to [`engine_newPayloadV2`][engine_newPayloadV2]. -Applies a L2 block to the engine state. - -### `engine_getPayloadV2` - -No modifications to [`engine_getPayloadV2`][engine_getPayloadV2]. -Retrieves a payload by ID, prepared by `engine_forkchoiceUpdatedV2` when called with `payloadAttributes`. - -### `engine_signalSuperchainV1` - -Optional extension to the Engine API. Signals superchain information to the Engine: -V1 signals which protocol version is recommended and required. - -Types: - -```javascript -SuperchainSignal: { - recommended: ProtocolVersion - required: ProtocolVersion -} -``` - -`ProtocolVersion`: encoded for RPC as defined in -[Protocol Version format specification](./superchain-upgrades.md#protocol-version-format). - -Parameters: - -- `signal`: `SuperchainSignal`, the signaled superchain information. - -Returns: - -- `ProtocolVersion`: the latest supported OP-Stack protocol version of the execution engine. - -The execution engine SHOULD warn the user when the recommended version is newer than -the current version supported by the execution engine. - -The execution engine SHOULD take safety precautions if it does not meet the required protocol version. -This may include halting the engine, with consent of the execution engine operator. - -## Networking - -The execution engine can acquire all data through the rollup node, as derived from L1: -*P2P networking is strictly optional.* - -However, to not bottleneck on L1 data retrieval speed, the P2P network functionality SHOULD be enabled, serving: - -- Peer discovery ([Disc v5][discv5]) -- [`eth/66`][eth66]: - - Transaction pool (consumed by sequencer nodes) - - State sync (happy-path for fast trustless db replication) - - Historical block header and body retrieval - - *New blocks are acquired through the consensus layer instead (rollup node)* - -No modifications to L1 network functionality are required, except configuration: - -- [`networkID`][network-id]: Distinguishes the L2 network from L1 and testnets. - Equal to the [`chainID`][chain-id] of the rollup network. -- Activate Merge fork: Enables Engine API and disables propagation of blocks, - as block headers cannot be authenticated without consensus layer. -- Bootnode list: DiscV5 is a shared network, - [bootstrap][discv5-rationale] is faster through connecting with L2 nodes first. - -[discv5]: https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md -[eth66]: https://github.com/ethereum/devp2p/blob/master/caps/eth.md -[network-id]: https://github.com/ethereum/devp2p/blob/master/caps/eth.md#status-0x00 -[chain-id]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md -[discv5-rationale]: https://github.com/ethereum/devp2p/blob/master/discv5/discv5-rationale.md - -## Sync - -The execution engine can operate sync in different ways: - -- Happy-path: rollup node informs engine of the desired chain head as determined by L1, completes through engine P2P. -- Worst-case: rollup node detects stalled engine, completes sync purely from L1 data, no peers required. - -The happy-path is more suitable to bring new nodes online quickly, -as the engine implementation can sync state faster through methods like [snap-sync][snap-sync]. - -[snap-sync]: https://github.com/ethereum/devp2p/blob/master/caps/snap.md - -### Happy-path sync - -1. The rollup node informs the engine of the L2 chain head, unconditionally (part of regular node operation): - - [`engine_newPayloadV2`][engine_newPayloadV2] is called with latest L2 block received from P2P. - - [`engine_forkchoiceUpdatedV2`][engine_forkchoiceUpdatedV2] is called with the current - `unsafe`/`safe`/`finalized` L2 block hashes. -2. The engine requests headers from peers, in reverse till the parent hash matches the local chain -3. The engine catches up: - a) A form of state sync is activated towards the finalized or head block hash - b) A form of block sync pulls block bodies and processes towards head block hash - -The exact P2P based sync is out of scope for the L2 specification: -the operation within the engine is the exact same as with L1 (although with an EVM that supports deposits). - -### Worst-case sync - -1. Engine is out of sync, not peered and/or stalled due other reasons. -2. The rollup node maintains latest head from engine (poll `eth_getBlockByNumber` and/or maintain a header subscription) -3. The rollup node activates sync if the engine is out of sync but not syncing through P2P (`eth_syncing`) -4. The rollup node inserts blocks, derived from L1, one by one, potentially adapting to L1 reorg(s), - as outlined in the [rollup node spec] (`engine_forkchoiceUpdatedV2`, `engine_newPayloadV2`) - -[rollup node spec]: rollup-node.md - -[eip-1559]: https://eips.ethereum.org/EIPS/eip-1559 -[eip-2028]: https://eips.ethereum.org/EIPS/eip-2028 -[eip-2718]: https://eips.ethereum.org/EIPS/eip-2718 -[eip-2718-transactions]: https://eips.ethereum.org/EIPS/eip-2718#transactions -[exec-api-data]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md#structures -[l1-api-spec]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md -[PayloadAttributesV1]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md#PayloadAttributesV1 -[ExecutionPayloadV1]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md#ExecutionPayloadV1 -[engine_forkchoiceUpdatedV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_forkchoiceupdatedv2 -[engine_newPayloadV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_newpayloadv2 -[engine_getPayloadV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_getpayloadv2 -[HEX value encoding]: https://eth.wiki/json-rpc/API#hex-value-encoding -[JSON-RPC-API]: https://github.com/ethereum/execution-apis diff --git a/specs/fault-dispute-game.md b/specs/fault-dispute-game.md deleted file mode 100644 index b04faa4ba6e1..000000000000 --- a/specs/fault-dispute-game.md +++ /dev/null @@ -1,358 +0,0 @@ -# Fault Dispute Game - - - -**Table of Contents** - -- [Overview](#overview) -- [Definitions](#definitions) - - [Virtual Machine (VM)](#virtual-machine-vm) - - [PreimageOracle](#preimageoracle) - - [Execution Trace](#execution-trace) - - [Claims](#claims) - - [DAG](#dag) - - [Game Tree](#game-tree) - - [Position](#position) - - [GAME_DURATION](#game_duration) -- [Game Mechanics](#game-mechanics) - - [Actors](#actors) - - [Moves](#moves) - - [Attack](#attack) - - [Defend](#defend) - - [Step](#step) - - [Step Types](#step-types) - - [PreimageOracle Interaction](#preimageoracle-interaction) - - [Team Dynamics](#team-dynamics) - - [Game Clock](#game-clock) - - [Resolution](#resolution) - - - -## Overview - -The Fault Dispute Game (FDG) is a specific type of -[dispute game](./dispute-game-interface.md) that verifies the validity of a -root claim by iteratively bisecting an execution trace down to a single instruction step. -It relies on a Virtual Machine (VM) to falsify invalid claims made -at a single instruction step. - -Actors, i.e. Players, interact with the game by making claims that dispute other claims in the FDG. -Each claim made narrows the execution trace until the source of dispute is a single state transition. -Once a time limit is reached, the dispute game is _resolved_, based on -claims made that are disputed and which aren't, to determine the winners of the game. - -## Definitions - -### Virtual Machine (VM) - -This is a state transition function (STF) that takes a _pre-state_ and computes the post-state. -The VM may access data referenced during the STF and as such, it also accepts a _proof_ of this data. -Typically, the pre-state contains a commitment to the _proof_ to verify the integrity of the data referenced. - -Mathematically, we define the STF as $VM(S_i,P_i)$ where - -- $S_i$ is the pre-state -- $P_i$ is an optional proof needed for the transition from $S_i$ to $S_{i+1}$. - -### PreimageOracle - -This is a pre-image data store. It is often used by VMs to read external data during its STF. -Before successfully executing a VM STF, it may be necessary to preload the PreimageOracle with pertinent data. -The method for key-based retrieval of these pre-images varies according to the specific VM. - -### Execution Trace - -An execution trace $T$ is a sequence $(S_0,S_1,S_2,...,S_n)$ where each $S_i$ is a VM state and -for each $i$, $0 \le i \lt n$, $S_{n+1} = VM(S_i, P_i)$. -Every execution trace has a unique starting state, $S_0$, that's preset to a FDG implementation. -We refer to this state as the **ABSOLUTE\_PRESTATE**. - -### Claims - -Claims assert an execution trace. This is represented as `ClaimHash`, a `bytes32` commitment to -the last VM state in a trace. A FDG is initialized with a root claim, which commits to the entire -execution trace. As we'll see later, there can be multiple claims, committing to different states in the FDG. - -### DAG - -A Directed Acyclic Graph $G = (V,E)$ representing the relationship between claims, where: - -- $V$ is the set of nodes, each representing a claim. Formally, $V = \{C_1,C_2,...,C_n\}$, -where $C_i$ is a claim. -- $E$ is the set of _directed_ edges. An edge $(C_i,C_j)$ exists if $C_j$ is a direct dispute -against $C_i$ through either an "Attack" or "Defend" [move](#moves). - -### Game Tree - -The Game Tree is a binary tree of positions. Every claim in the DAG references a position in the Game Tree. - The Game Tree has a maximum depth, `MAX_GAME_DEPTH`, that's preset to an FDG implementation. -Thus, the Game Tree contains $2^{d-1}$ positions, where $d$ is the `MAX_GAME_DEPTH` -(unless $d=0$, in which case there's only 1 position). - -### Position - -A position represents the location of a claim in the Game Tree. This is represented by a -"generalized index" (or **gindex**) where the high-order bit is the level in the tree and the remaining -bits is a unique bit pattern, allowing a unique identifier for each node in the tree. - -The **gindex** of a position $n$ can be calculated as $2^{d(n)} + idx(n)$, where: - -- $d(n)$ is a function returning the depth of the position in the Game Tree -- $idx(n)$ is a function returning the index of the position at its depth (starting from the left). - -Positions at the deepest level of the game tree correspond to indices in the execution trace. -Positions higher up the game tree also cover the deepest, right-most positions relative to the current position. -We refer to this coverage as the **trace index** of a Position. - -> This means claims commit to an execution trace that terminates at the same index as their Position's trace index. -> That is, for a given trace index $n$, its ClaimHash corresponds to the $S_n$ th state in the trace. - -Note that there can be multiple positions covering the same _trace index_. - -### GAME_DURATION - -This is an immutable, preset to a FDG implementation, representing the duration of the game. - -## Game Mechanics - -### Actors - -The game involves two types of participants (or Players): **Challengers** and **Defenders**. -These players are grouped into separate teams, each employing distinct strategies to interact with the game. -Team members share a common goal regarding the game's outcome. Players interact with the game primarily through _moves_. - -### Moves - -A Move is a challenge against a claim's execution trace and must include an alternate claim asserting a different trace. -Moves can either be attacks or defenses and serve to update to DAG by adding nodes and edges targeting the disputed -claim. - -Initially, claims added to the DAG are _uncontesteed_ (i.e. not **countered**). Once a move targets a claim, that claim - is considered countered. -The status of a claim — whether it's countered or not — helps determine its validity and, ultimately, the - game's winner. - -#### Attack - -A logical move made when a claim is disagreed with. -A claim at the relative attack position to a node, `n`, in the Game Tree commits to half -of the trace of the `n`’s claim. -The attack position relative to a node can be calculated by multiplying its gindex by 2. - -To illustrate this, here's a Game Tree highlighting an attack on a Claim positioned at 6. - -![Attacking node 6](assets/attack.png) - -Attacking the node at 6 moves creates a new claim positioned at 12. - -#### Defend - -The logical move against a claim when you agree with both it and its parent. -A defense at the relative position to a node, `n``, in the Game Tree commits to the first half of n + 1’s trace range. - -![Defend at 4](assets/defend.png) - -Note that because of this, some nodes may never exist within the Game Tree. -However, they're not necessary as these nodes have complimentary, valid positions -with the same trace index within the tree. For example, a Position with gindex 5 has the same -trace index as another Position with gindex 2. We can verify that all trace indices have valid moves within the game: - -![Game Tree Showing All Valid Move Positions](assets/valid-moves.png) - -There may be multiple claims at the same position, so long as their `ClaimHash` are unique. - -Each move adds new claims to the Game Tree at strictly increasing depth. -Once a claim is at `MAX_GAME_DEPTH`, the only way to dispute such claims is to **step**. - -### Step - -At `MAX_GAME_DEPTH`, the position of claims correspond to indices of an execution trace. -It's at this point that the FDG is able to query the VM to determine the validity of claims, -by checking the states they're committing to. -This is done by applying the VM's STF to the state a claim commits to. -If the STF post-state does not match the claimed state, the challenge succeeds. - -```solidity -/// @notice Perform an instruction step via an on-chain fault proof processor. -/// @dev This function should point to a fault proof processor in order to execute -/// a step in the fault proof program on-chain. The interface of the fault proof -/// processor contract should adhere to the `IBigStepper` interface. -/// @param _claimIndex The index of the challenged claim within `claimData`. -/// @param _isAttack Whether or not the step is an attack or a defense. -/// @param _stateData The stateData of the step is the preimage of the claim at the given -/// prestate, which is at `_stateIndex` if the move is an attack and `_claimIndex` if -/// the move is a defense. If the step is an attack on the first instruction, it is -/// the absolute prestate of the fault proof VM. -/// @param _proof Proof to access memory nodes in the VM's merkle state tree. -function step(uint256 _claimIndex, bool isAttack, bytes calldata _stateData, bytes calldata _proof) external; -``` - -### Step Types - -Similar to moves, there are two ways to step on a claim; attack or defend. -These determine the pre-state input to the VM STF and the expected output. - -- **Attack Step** - Challenges a claim by providing a pre-state, proving an invalid state transition. -It uses the previous state in the execution trace as input and expects the disputed claim's state as output. -There must exist a claim in the DAG that commits to the input. -- **Defense Step** - Challenges a claim by proving it was an invalid attack, -thereby defending the disputed ancestor's claim. It uses the disputed claim's state as input and expects -the next state in the execution trace as output. There must exist a claim in the DAG that commits to the - expected output. - -The FDG step handles the inputs to the VM and asserts the expected output. -A step that successfully proves an invalid post-state (when attacking) or pre-state (when defending) is a -successful counter against the disputed claim. -Players interface with `step` by providing an indicator of attack and state data (including any proofs) -that corresponds to the expected pre/post state (depending on whether it's an attack or defend). -The FDG will assert that an existing claim commits to the state data provided by players. - -### PreimageOracle Interaction - -Certain steps (VM state transitions) require external data to be available by the `PreimageOracle`. -To ensure a successful state transition, players should provide this data in advance. -The FDG provides the following interface to manage data loaded to the `PreimageOracle`: - -```solidity -/// @notice Posts the requested local data to the VM's `PreimageOralce`. -/// @param _ident The local identifier of the data to post. -/// @param _partOffset The offset of the data to post. -function addLocalData(uint256 _ident, uint256 _partOffset) external; -``` - -The `addLocalData` function loads parts of a pre-image to VM's `PreimageOracle`. -Players use this to ensure pre-image parts are available to the VM during a step. - -### Team Dynamics - -Challengers seek to dispute the root claim, while Defenders aim to support it. -Both types of actors will move accordingly to support their team. For Challengers, this means -attacking the root claim and disputing claims positioned at even depths in the Game Tree. -Defenders do the opposite by disputing claims positioned at odd depths. - -Players on either team are motivated to support the actions of their teammates. -This involves countering disputes against claims made by their team (assuming these claims are honest). -Uncontested claims are likely to result in a loss, as explained later under [Resolution](#resolution). - -### Game Clock - -Every claim in the game has a Clock. A claim's inherits the clock of its grandparent claim in the - DAG (and so on). Akin to a chess clock, it keeps track of the total time each team takes to make - moves, preventing delays. -Making a move resumes the clock for the disputed claim and puases it for the newly added one. - -A move against a particular claim is no longer possible once the parent of the disputed claim's Clock - has exceeded half of the `GAME_DURATION`. By which point, the claim's clock has _expired_. - -### Resolution - -Resolving the FDG determines which team won the game. To do this, we use the internal sub game structure. -Each claim within the game is the root of its own sub game. These subgames are modeled as nested DAGs, each with a max -depth of 1. In order for a claim to be considered countered, only one of its children must be uncountered. Subgames -can also not be resolved until all of their children, which are subgames themselves, have been resolved and -the potential opponent's chess clock has run out. Because each claim is the root of its own sub-game, -truth percolates upwards towards the root claim by resolving each individual sub-game bottom-up. - -In a game like the one below, we can resolve up from the deepest subgames. Here, we'd resolve `b0` -to uncountered and `a0` to countered by walking up from their deepest children, and once all children of the -root game are recursively resolved, we can resolve the root to countered due to `b0` remaining uncountered. - - - - - -Another example is this game, which has a slightly different structure. Here, the root claim will also -be countered due to `b0` remaining uncountered. - - - - -

- -

- -Given these rules, players are motivated to move quickly to challenge all dishonest claims. -Each move bisects the execution trace and eventually, `MAX_GAME_DEPTH` is reached where disputes -can be settled conclusively. Dishonest players are disincentivized to participate, via backwards induction, -as an invalid claim won't remain uncontested. Further incentives can be added to the game by requiring -claims to be bonded, while rewarding game winners using the bonds of dishonest claims. diff --git a/specs/fault-proof.md b/specs/fault-proof.md deleted file mode 100644 index b6d30af7a731..000000000000 --- a/specs/fault-proof.md +++ /dev/null @@ -1,422 +0,0 @@ -# Fault Proof - - - -**Table of Contents** - -- [Overview](#overview) -- [Pre-image Oracle](#pre-image-oracle) - - [Pre-image key types](#pre-image-key-types) - - [Type `0`: Zero key](#type-0-zero-key) - - [Type `1`: Local key](#type-1-local-key) - - [Type `2`: Global keccak256 key](#type-2-global-keccak256-key) - - [Type `3`: Global generic key](#type-3-global-generic-key) - - [Type `4-128`: reserved range](#type-4-128-reserved-range) - - [Type `129-255`: application usage](#type-129-255-application-usage) - - [Bootstrapping](#bootstrapping) - - [Hinting](#hinting) - - [Pre-image communication](#pre-image-communication) -- [Fault Proof Program](#fault-proof-program) - - [Prologue](#prologue) - - [Main content](#main-content) - - [Epilogue](#epilogue) - - [Pre-image hinting routes](#pre-image-hinting-routes) - - [`l1-block-header `](#l1-block-header-blockhash) - - [`l1-transactions `](#l1-transactions-blockhash) - - [`l1-receipts `](#l1-receipts-blockhash) - - [`l2-block-header `](#l2-block-header-blockhash) - - [`l2-transactions `](#l2-transactions-blockhash) - - [`l2-code `](#l2-code-codehash) - - [`l2-state-node `](#l2-state-node-nodehash) - - [`l2-output `](#l2-output-outputroot) -- [Fault Proof VM](#fault-proof-vm) -- [Fault Proof Interactive Dispute Game](#fault-proof-interactive-dispute-game) - - - -## Overview - -A fault proof, also known as fraud proof or interactive game, consists of 3 components: - -- [Program]: given a commitment to all rollup inputs (L1 data) and the dispute, verify the dispute statelessly. -- [VM]: given a stateless program and its inputs, trace any instruction step, and prove it on L1. -- [Interactive Dispute Game]: bisect a dispute down to a single instruction, and resolve the base-case using the VM. - -Each of these 3 components may have different implementations, which can be combined into different proof stacks, -and contribute to proof diversity when resolving a dispute. - -"Stateless execution" of the program, and its individual instructions, refers to reproducing -the exact same computation by authenticating the inputs with a [Pre-image Oracle][oracle]. - -![Diagram of Program and VM architecture](./assets/fault-proof.svg) - -## Pre-image Oracle - -[oracle]: #Pre-image-Oracle - -The pre-image oracle is the only form of communication between -the [Program] (in the [Client](#client) role) and the [VM] (in the [Server](#server) role). - -The program uses the pre-image oracle to query any input data that is understood to be available to the user: - -- The initial inputs to bootstrap the program. See [Bootstrapping](#bootstrapping). -- External data not already part of the program code. See [Pre-image hinting routes](#pre-image-hinting-routes). - -The communication happens over a simple request-response wire protocol, -see [Pre-image communcation](#pre-image-communication). - -### Pre-image key types - -Pre-images are identified by a `bytes32` type-prefixed key: - -- The first byte identifies the type of request. -- The remaining 31 bytes identify the pre-image key. - -#### Type `0`: Zero key - -The zero prefix is illegal. This ensures all pre-image keys are non-zero, -enabling storage lookup optimizations and avoiding easy mistakes with invalid zeroed keys in the EVM. - -#### Type `1`: Local key - -Information specific to the dispute: the remainder of the key may be an index, a string, a hash, etc. -Only the contract(s) managing this dispute instance may serve the value for this key: -it is localized and context-dependent. - -This type of key is used for program bootstrapping, to identify the initial input arguments by index or name. - -#### Type `2`: Global keccak256 key - -This type of key uses a global pre-image store contract, and is fully context-independent and permissionless. -I.e. every key must have a single unique value, regardless of chain history or time. - -Using a global store reduces duplicate pre-image registration work, -and avoids unnecessary contract redeployments per dispute. - -This global store contract should be non-upgradeable. - -Since `keccak256` is a safe 32-byte hash input, the first byte is overwritten with a `2` to derive the key, -while keeping the rest of the key "readable" (matching the original hash). - -#### Type `3`: Global generic key - -Reserved. This scheme allows for unlimited application-layer pre-image types without fault-proof VM redeployments. - -This is a generic version of a global key store: `key = 0x03 ++ keccak256(x, sender)[1:]`, where: - -- `x` is a `bytes32`, which can be a hash of an arbitrary-length type of cryptographically secure commitment. -- `sender` is a `bytes32` identifying the pre-image inserter address (left-padded to 32 bytes) - -This global store contract should be non-upgradeable. - -The global contract is permissionless: users can standardize around external contracts that verify pre-images -(i.e. a specific `sender` will always be trusted for a specific kind of pre-image). -The external contract verifies the pre-image before inserting it into the global store for usage by all -fault proof VMs without requiring the VM or global store contract to be changed. - -Users may standardize around upgradeable external pre-image contracts, -in case the implementation of the verification of the pre-image is expected to change. - -The store update function is `update(x bytes32, offset uint64, span uint8, value bytes32)`: - -- `x` is the `bytes32` `x` that the pre-image `key` is computed with. -- Only part of the pre-image, starting at `offset`, and up to (incl.) 32 bytes `span` can be inserted at a time. -- Pre-images may have an undefined length (e.g. a stream), we only need to know how many bytes of `value` are usable. -- The key and offset will be hashed together to uniquely store the `value` and `span`, for later pre-image serving. - -This enables fault proof programs to adopt any new pre-image schemes without VM update or contract redeployment. - -It is up to the user to index the special pre-image values by this key scheme, -as there is no way to revert it to the original commitment without knowing said commitment or value. - -#### Type `4-128`: reserved range - -Range start and end both inclusive. - -This range of key types is reserved for future usage by the core protocol. -E.g. version changes, contract migrations, chain-data, additional core features, etc. - -`128` specifically (`1000 0000` in binary) is reserved for key-type length-extension -(reducing the content part to `30` or less key bytes), if the need arises. - -#### Type `129-255`: application usage - -This range of key types may be used by forks or customized versions of the fault proof protocol. - -### Bootstrapping - -Initial inputs are deterministic, but not necessarily singular or global: -there may be multiple different disputes at the same time, each with its own disputed claims and L1 context. - -To bootstrap, the program requests the initial inputs from the VM, using pre-image key type `1`. - -The VM is aware of the external context, and maps requested pre-image keys based on their type, i.e. -a local lookup for type `1`, or global one for `2`, and optionally support other key-types. - -### Hinting - -There is one more form of optional communication between client and server: pre-image hinting. -Hinting is optional, and *is a no-op* in a L1 VM implementation. - -The hint itself comes at very low cost onchain: the hint can be a single `write` sys-call, -which is instant as the memory to write as hint does not actually need to be loaded as part of the onchain proof. - -Hinting allows the program, when generating a proof offchain, -to instruct the VM what data it is interested in. - -The VM can choose to execute the requested hint at any time: either locally (for standard requests), -or in a modular form by redirecting the hint to tooling that may come with the VM program. - -Hints do not have to be executed directly: they may first just be logged to show the intents of the program, -and the latest hint may be buffered for lazy execution, or dropped entirely when in read-only mode (like onchain). - -When the pre-image oracle serves a request, and the request cannot be served from an existing collection of pre-images -(e.g. a local pre-image cache) then the VM can execute the hint to retrieve the missing pre-image(s). -It is the responsibility of the program to provide sufficient hinting for every pre-image request. -Some hints may have to be repeated: the VM only has to execute the last hint when handling a missing pre-image. - -Note that hints may produce multiple pre-images: -e.g. a hint for an ethereum block with transaction list may prepare pre-images for the header, -each of the transactions, and the intermediate merkle-nodes that form the transactions-list Merkle Patricia Trie. - -Hinting is implemented with a request-acknowledgement wire-protocol over a blocking two-way stream: - -```text - := - - := - - := big-endian uint32 # length of - := byte sequence - := 1-byte zero value -``` - -The ack informs the client that the hint has been processed. Servers may respond to hints and pre-image (see below) -requests asynchronously as they are on separate streams. To avoid requesting pre-images that are not yet fetched, -clients should request the pre-image only after it has observed the hint acknowledgement. - -### Pre-image communication - -Pre-images are communicated with a minimal wire-protocol over a blocking two-way stream. -This protocol can be implemented with blocking read/write syscalls. - -```text - := # the type-prefixed pre-image key - - := - - := big-endian uint64 # length of , note: uint64 -``` - -The `` here may be arbitrarily high: -the client can stop reading at any time if the required part of the pre-image has been read. - -After the client writes new `` bytes, the server should be prepared to respond with -the pre-image starting from `offset == 0` upon `read` calls. - -The server may limit `read` results artificially to only a small amount of bytes at a time, -even though the full pre-image is ready: this is expected regular IO protocol, -and the client will just have to continue to read the small results at a time, -until 0 bytes are read, indicating EOF. -This enables the server to serve e.g. at most 32 bytes at a time or align reads with VM memory structure, -to limit the amount of VM state that changes per syscall instruction, -and thus keep the proof size per instruction bounded. - -## Fault Proof Program - -[Program]: #Fault-Proof-Program - -The Fault Proof Program defines the verification of claims of the state-transition outputs -of the L2 rollup as a pure function of L1 data. - -The `op-program` is the reference implementation of the program, based on `op-node` and `op-geth` implementations. - -The program consists of: - -- Prologue: load the inputs, given minimal bootstrapping, with possible test-overrides. -- Main content: process the L2 state-transition, i.e. derive the state changes from the L1 inputs. -- Epilogue: inspect the state changes to verify the claim. - -### Prologue - -The program is bootstrapped with two primary inputs: - -- `l1_head`: the L1 block hash that will be perceived as the tip of the L1 chain, - authenticating all prior L1 history. -- `dispute`: identity of the claim to verify. - -Bootstrapping happens through special input requests to the host of the program. - -Additionally, there are *implied* inputs, which are *derived from the above primary inputs*, -but can be overridden for testing purposes: - -- `l2_head`: the L2 block hash that will be perceived as the previously agreed upon tip of the L2 chain, - authenticating all prior L2 history. -- Chain configurations: chain configuration may be baked into the program, - or determined from attributes of the identified `dispute` on L1. - - `l1_chain_config`: The chain-configuration of the L1 chain (also known as `l1_genesis.json`) - - `l2_chain_config`: The chain-configuration of the L2 chain (also known as `l2_genesis.json`) - - `rollup_config`: The rollup configuration used by the rollup-node (also known as `rollup.json`) - -The implied inputs rely on L1-introspection to load attributes of the `dispute` through the -[dispute game interface](./dispute-game-interface.md), in the L1 history up and till the specified `l1_head`. -The `dispute` may be the claim itself, or a pointer to specific prior claimed data in L1, -depending on the dispute game interface. - -Implied inputs are loaded in a "prologue" before the actual core state-transition function executes. -During testing a simplified prologue that loads the overrides may be used. - -> Note: only the test-prologues are currently supported, since the dispute game interface is actively changing. - -### Main content - -To verify a claim about L2 state, the program first reproduces -the L2 state by applying L1 data to prior agreed L2 history. - -This process is also known as the [L2 derivation process](./derivation.md), -and matches the processing in the [rollup node](./rollup-node.md) and [execution-engine](./exec-engine.md). - -The difference is that rather than retrieving inputs from an RPC and applying state changes to disk, -the inputs are loaded through the [pre-image oracle][oracle] and the changes accumulate in memory. - -The derivation executes with two data-sources: - -- Interface to read-only L1 chain, backed by the pre-image oracle: - - The `l1_head` determines the view over the available L1 data: no later L1 data is available. - - The implementation of the chain traverses the header-chain from the `l1_head` down to serve by-number queries. - - The `l1_head` is the L1 unsafe head, safe head, and finalized head. -- Interface to L2 engine API - - Prior L2 chain history is backed by the pre-image oracle, similar to the L1 chain: - - The initial `l2_head` determines the view over the initial available L2 history: no later L2 data is available. - - The implementation of the chain traverses the header-chain from the `l2_head` down to serve by-number queries. - - The `l2_head` is the initial L2 unsafe head, safe head, and finalized head. - - New L2 chain history accumulates in memory. - - Although the pre-image oracle can be used to retrieve data by hash if memory is limited, - the program should prefer to keep the newly created chain data in memory, to minimize pre-image oracle access. - - The L2 unsafe head, safe head, and finalized L2 head will potentially change as derivation progresses. - - L2 state consists of the diff of changes in memory, - and any unchanged state nodes accessible through the read-only L2 history view. - -See [Pre-image routes](#pre-image-routes) for specifications of the pre-image oracle backing of these data sources. - -Using these data-sources, the derivation pipeline is processed till we hit one of two conditions: - -- `EOF`: when we run out of L1 data, the L2 chain will not change further, and the epilogue can start. -- Eager epilogue condition: depending on the type of claim to verify, - if the L2 result is irreversible (i.e. no later L1 inputs can override it), - the processing may end early when the result is ready. - E.g. when asserting state at a specific L2 block, rather than the very tip of the L2 chain. - -### Epilogue - -While the main-content produces the disputed L2 state already, -the epilogue concludes what this means for the disputed claim. - -The program produces a binary output to verify the claim, using a standard single-byte Unix exit-code: - -- a `0` for success, i.e. the claim is correct. -- a non-zero code for failure, i.e. the claim is incorrect. - - `1` should be preferred for identifying an incorrect claim. - - Other non-zero exit codes may indicate runtime failure, - e.g. a bug in the program code may resolve in a kind of `panic` or unexpected error. - Safety should be preferred over liveness in this case, and the `claim` will fail. - -To assert the disputed claim, the epilogue, like the main content, -can introspect L1 and L2 chain data and post-process it further, -to then make a statement about the claim with the final exit code. - -A disputed output-root may be disproven by first producing the output-root, and then comparing it: - -1. Retrieve the output attributes from the L2 chain view: the state-root, block-hash, withdrawals storage-root. -2. Compute the output-root, as the [proposer should compute it](./proposals.md#l2-output-commitment-construction). -3. If the output-root matches the `claim`, exit with code 0. Otherwise, exit with code 1. - -> Note: the dispute game interface is actively changing, and may require additional claim assertions. -> the output-root epilogue may be replaced or extended for general L2 message proving. - -### Pre-image hinting routes - -The fault proof program implements hint handling for the VM to use, -as well as any program testing outside of VM environment. -This can be exposed via a CLI, or alternative inter-process API. - -Every instance of `` in the below routes is `0x`-prefixed, lowercase, hex-encoded. - -#### `l1-block-header ` - -Requests the host to prepare the L1 block header RLP pre-image of the block ``. - -#### `l1-transactions ` - -Requests the host to prepare the list of transactions of the L1 block with ``: -prepare the RLP pre-images of each of them, including transactions-list MPT nodes. - -#### `l1-receipts ` - -Requests the host to prepare the list of receipts of the L1 block with ``: -prepare the RLP pre-images of each of them, including receipts-list MPT nodes. - -#### `l2-block-header ` - -Requests the host to prepare the L2 block header RLP pre-image of the block ``. - -#### `l2-transactions ` - -Requests the host to prepare the list of transactions of the L2 block with ``: -prepare the RLP pre-images of each of them, including transactions-list MPT nodes. - -#### `l2-code ` - -Requests the host to prepare the L2 smart-contract code with the given ``. - -#### `l2-state-node ` - -Requests the host to prepare the L2 MPT node preimage with the given ``. - -#### `l2-output ` - -Requests the host to prepare the L2 Output at the l2 output root ``. -The L2 Output is the preimage of a [computed output root](./proposals.md#l2-output-commitment-construction). - -## Fault Proof VM - -[VM]: #Fault-Proof-VM - -A fault proof VM implements: - -- a smart-contract to verify a single execution-trace step, e.g. a single MIPS instruction. -- a CLI command to generate a proof of a single execution-trace step. -- a CLI command to compute a VM state-root at step N - -A fault proof VM relies on a fault proof program to provide an interface -for fetching any missing pre-images based on hints. - -The VM emulates the program, as prepared for the VM target architecture, -and generates the state-root or instruction proof data as requested through the VM CLI. - -Refer to the documentation of the fault proof VM for further usage information. - -Fault Proof VMs: - -- [Cannon]: big-endian 32-bit MIPS proof, by OP Labs, in active development. -- [Asterisc]: little-endian 64-bit RISC-V proof, by `@protolambda`, in active development. - -[Cannon]: https://github.com/ethereum-optimism/cannon -[Asterisc]: https://github.com/protolambda/asterisc - -## Fault Proof Interactive Dispute Game - -[Interactive Dispute Game]: #Fault-Proof-Interactive-Dispute-Game - -The interactive dispute game allows actors to resolve a dispute with an onchain challenge-response game -that bisects the execution trace of the VM, bounded with a base-case that proves a VM trace step. - -The game is multi-player: different non-aligned actors may participate when bonded. - -Response time is allocated based on the remaining time in the branch of the tree and alignment with the claim. -The allocated response time is limited by the dispute-game window, -and any additional time necessary based on L1 fee changes when bonds are insufficient. - -> Note: the timed, bonded, bisection dispute game is in development. -> Also see [fault dispute-game specs](./fault-dispute-game.md) for fault dispute game system specifications, -> And [dispute-game-interface specs](./dispute-game-interface.md) for dispute game interface specifications. diff --git a/specs/glossary.md b/specs/glossary.md deleted file mode 100644 index fc954bc5534f..000000000000 --- a/specs/glossary.md +++ /dev/null @@ -1,805 +0,0 @@ -# Glossary - - - -**Table of Contents** - -- [General Terms](#general-terms) - - [Layer 1 (L1)](#layer-1-l1) - - [Layer 2 (L2)](#layer-2-l2) - - [Block](#block) - - [EOA](#eoa) - - [Merkle Patricia Trie](#merkle-patricia-trie) - - [Chain Re-Organization](#chain-re-organization) - - [Predeployed Contract ("Predeploy")](#predeployed-contract-predeploy) - - [Receipt](#receipt) - - [Transaction Type](#transaction-type) - - [Fork Choice Rule](#fork-choice-rule) - - [Priority Gas Auction](#priority-gas-auction) -- [Sequencing](#sequencing) - - [Sequencer](#sequencer) - - [Sequencing Window](#sequencing-window) - - [Sequencing Epoch](#sequencing-epoch) - - [L1 Origin](#l1-origin) -- [Deposits](#deposits) - - [Deposited Transaction](#deposited-transaction) - - [L1 Attributes Deposited Transaction](#l1-attributes-deposited-transaction) - - [User-Deposited Transaction](#user-deposited-transaction) - - [Depositing Call](#depositing-call) - - [Depositing Transaction](#depositing-transaction) - - [Depositor](#depositor) - - [Deposited Transaction Type](#deposited-transaction-type) - - [Deposit Contract](#deposit-contract) -- [Withdrawals](#withdrawals) - - [Relayer](#relayer) - - [Finalization Period](#finalization-period) -- [Batch Submission](#batch-submission) - - [Data Availability](#data-availability) - - [Data Availability Provider](#data-availability-provider) - - [Sequencer Batch](#sequencer-batch) - - [Channel](#channel) - - [Channel Frame](#channel-frame) - - [Batcher](#batcher) - - [Batcher Transaction](#batcher-transaction) - - [Channel Timeout](#channel-timeout) -- [L2 Chain Derivation](#l2-chain-derivation) - - [L2 Derivation Inputs](#l2-derivation-inputs) - - [System Configuration](#system-configuration) - - [Payload Attributes](#payload-attributes) - - [L2 Genesis Block](#l2-genesis-block) - - [L2 Chain Inception](#l2-chain-inception) - - [Safe L2 Block](#safe-l2-block) - - [Safe L2 Head](#safe-l2-head) - - [Unsafe L2 Block](#unsafe-l2-block) - - [Unsafe L2 Head](#unsafe-l2-head) - - [Unsafe Block Consolidation](#unsafe-block-consolidation) - - [Finalized L2 Head](#finalized-l2-head) -- [Other L2 Chain Concepts](#other-l2-chain-concepts) - - [Address Aliasing](#address-aliasing) - - [Rollup Node](#rollup-node) - - [Rollup Driver](#rollup-driver) - - [L1 Attributes Predeployed Contract](#l1-attributes-predeployed-contract) - - [L2 Output Root](#l2-output-root) - - [L2 Output Oracle Contract](#l2-output-oracle-contract) - - [Validator](#validator) - - [Fault Proof](#fault-proof) - - [Time Slot](#time-slot) - - [Block Time](#block-time) - - [Unsafe Sync](#unsafe-sync) -- [Execution Engine Concepts](#execution-engine-concepts) - - [Execution Engine](#execution-engine) - - - ------------------------------------------------------------------------------------------------------------------------- - -# General Terms - -## Layer 1 (L1) - -[L1]: glossary.md#layer-1-L1 - -Refers the Ethereum blockchain, used in contrast to [layer 2][L2], which refers to Optimism. - -## Layer 2 (L2) - -[L2]: glossary.md#layer-2-L2 - -Refers to the Optimism blockchain (specified in this repository), used in contrast to [layer 1][L1], which -refers to the Ethereum blockchain. - -## Block - -[block]: glossary.md#block - -Can refer to an [L1] block, or to an [L2] block, which are structured similarly. - -A block is a sequential list of transactions, along with a couple of properties stored in the *header* of the block. A -description of these properties can be found in code comments [here][nano-header], or in the [Ethereum yellow paper -(pdf)][yellow], section 4.3. - -It is useful to distinguish between input block properties, which are known before executing the transactions in the -block, and output block properties, which are derived after executing the block's transactions. These include various -[Merkle Patricia Trie roots][mpt] that notably commit to the L2 state and to the log events emitted during execution. - -## EOA - -[EOA]: glossary.md#EOA - -"Externally Owned Account", an Ethereum term to designate addresses operated by users, as opposed to contract addresses. - -## Merkle Patricia Trie - -[mpt]: glossary.md#merkle-patricia-trie - -A [Merkle Patricia Trie (MPT)][mpt-details] is a sparse trie, which is a tree-like structure that maps keys to values. -The root hash of a MPT is a commitment to the contents of the tree, which allows a -proof to be constructed for any key-value mapping encoded in the tree. Such a proof is called a Merkle proof, and can be -verified against the Merkle root. - -## Chain Re-Organization - -[reorg]: glossary.md#chain-re-organization - -A re-organization, or re-org for short, is whenever the head of a blockchain (its last block) changes (as dictated by -the [fork choice rule][fork-choice-rule]) to a block that is not a child of the previous head. - -L1 re-orgs can happen because of network conditions or attacks. L2 re-orgs are a consequence of L1 re-orgs, mediated via -[L2 chain derivation][derivation]. - -## Predeployed Contract ("Predeploy") - -[predeploy]: glossary.md#predeployed-contract-predeploy - -A contract placed in the L2 genesis state (i.e. at the start of the chain). - -All predeploy contracts are specified in the [predeploys specification][./predeploys.md]. - -## Receipt - -[receipt]: glossary.md#receipt - -A receipt is an output generated by a transaction, comprising a status code, the amount of gas used, a list of log -entries, and a [bloom filter] indexing these entries. Log entries are most notably used to encode [Solidity events]. - -Receipts are not stored in blocks, but blocks store a [Merkle Patricia Trie root][mpt] for a tree containing the receipt -for every transaction in the block. - -Receipts are specified in the [yellow paper (pdf)][yellow] section 4.3.1. - -## Transaction Type - -[transaction-type]: glossary.md#transaction-type - -Ethereum provides a mechanism (as described in [EIP-2718]) for defining different transaction types. -Different transaction types can contain different payloads, and be handled differently by the protocol. - -[EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718 - -## Fork Choice Rule - -[fork-choice-rule]: glossary.md#fork-choice-rule - -The fork choice rule is the rule used to determine which block is to be considered as the head of a blockchain. On L1, -this is determined by the proof of stake rules. - -L2 also has a fork choice rule, although the rules vary depending on whether we want the [safe L2 head][safe-l2-head], -the [unsafe L2 head][unsafe-l2-head] or the [finalized L2 head][finalized-l2-head]. - -## Priority Gas Auction - -Transactions in ethereum are ordered by the price that the transaction pays to the miner. Priority Gas Auctions -(PGAs) occur when multiple parties are competing to be the first transaction in a block. Each party continuously -updates the gas price of their transaction. PGAs occur when there is value in submitting a transaction before other -parties (like being the first deposit or submitting a deposit before there is not more guaranteed gas remaining). -PGAs tend to have negative externalities on the network due to a large amount of transactions being submitted in a -very short amount of time. - ------------------------------------------------------------------------------------------------------------------------- - -# Sequencing - -[sequencing]: glossary.md#sequencing - -Transactions in the rollup can be included in two ways: - -- Through a [deposited transaction](#deposited-transaction), enforced by the system -- Through a regular transaction, embedded in a [sequencer batch](#sequencer-batch) - -Submitting transactions for inclusion in a batch saves costs by reducing overhead, and enables the sequencer to -pre-confirm the transactions before the L1 confirms the data. - -## Sequencer - -[sequencer]: glossary.md#sequencer - -A sequencer is either a [rollup node][rollup-node] ran in sequencer mode, or the operator of this rollup node. - -The sequencer is a priviledged actor, which receives L2 transactions from L2 users, creates L2 blocks using them, which -it then submits to [data availability provider][avail-provider] (via a [batcher]). It also submits [output -roots][l2-output] to L1. - -## Sequencing Window - -[sequencing-window]: glossary.md#sequencing-window - -A sequencing window is a range of L1 blocks from which a [sequencing epoch][sequencing-epoch] can be derived. - -A sequencing window whose first L1 block has number `N` contains [batcher transactions][batcher-transaction] for epoch -`N`. The window contains blocks `[N, N + SWS)` where `SWS` is the sequencer window size. - -The current default `sws` is 3600 epochs. - -Additionally, the first block in the window defines the [depositing transactions][depositing-tx] which determine the -[deposits] to be included in the first L2 block of the epoch. - -## Sequencing Epoch - -[sequencing-epoch]: glossary.md#sequencing-epoch - -A sequencing epoch is sequential range of L2 blocks derived from a [sequencing window](#sequencing-window) of L1 blocks. - -Each epoch is identified by an epoch number, which is equal to the block number of the first L1 block in the -sequencing window. - -Epochs can have variable size, subject to some constraints. See the [L2 chain derivation specification][derivation-spec] -for more details. - -## L1 Origin - -[l1-origin]: glossary.md#l1-origin - -The L1 origin of an L2 block is the L1 block corresponding to its [sequencing epoch][sequencing-epoch]. - ------------------------------------------------------------------------------------------------------------------------- - -# Deposits - -[deposits]: glossary.md#deposits - -In general, a deposit is an L2 transaction derived from an L1 block (by the [rollup driver]). - -While transaction deposits are notably (but not only) used to "deposit" (bridge) ETH and tokens to L2, the word -*deposit* should be understood as "a transaction *deposited* to L2 from L1". - -This term *deposit* is somewhat ambiguous as these "transactions" exist at multiple levels. This section disambiguates -all deposit-related terms. - -Notably, a *deposit* can refer to: - -- A [deposited transaction][deposited] (on L2) that is part of a [deposit block][deposit-block]. -- A [depositing call][depositing-call] that causes a [deposited transaction][deposited] to be derived. -- The event/log data generated by the [depositing call][depositing-call], which is what the [rollup driver] reads to - derive the [deposited transaction][deposited]. - -We sometimes also talk about *user deposit* which is a similar term that explicitly excludes [L1 attributes deposited -transactions][l1-attr-deposit]. - -Deposits are specified in the [deposits specification][deposits-spec]. - -[deposits-spec]: deposits.md - -## Deposited Transaction - -[deposited]: glossary.md#deposited-transaction - -A *deposited transaction* is a L2 transaction that was derived from L1 and included in a L2 block. - -There are two kinds of deposited transactions: - -- [L1 attributes deposited transaction][l1-attr-deposit], which submits the L1 block's attributes to the [L1 Attributes - Predeployed Contract][l1-attr-predeploy]. -- [User-deposited transactions][user-deposited], which are transactions derived from an L1 call to the [deposit - contract][deposit-contract]. - -[deposits-spec]: deposits.md - -## L1 Attributes Deposited Transaction - -[l1-attr-deposit]: glossary.md#l1-attributes-deposited-transaction - -An *L1 attributes deposited transaction* is [deposited transaction][deposited] that is used to register the L1 block -attributes (number, timestamp, ...) on L2 via a call to the [L1 Attributes Predeployed Contract][l1-attr-predeploy]. -That contract can then be used to read the attributes of the L1 block corresponding to the current L2 block. - -L1 attributes deposited transactions are specified in the [L1 Attributes Deposit][l1-attributes-tx-spec] section of the -deposits specification. - -[l1-attributes-tx-spec]: deposits.md#l1-attributes-deposited-transaction - -## User-Deposited Transaction - -[user-deposited]: glossary.md#user-deposited-transaction - -A *user-deposited transaction* is a [deposited transaction][deposited] which is derived from an L1 call to the [deposit - contract][deposit-contract] (a [depositing call][depositing-call]). - -User-deposited transactions are specified in the [Transaction Deposits][tx-deposits-spec] section of the deposits -specification. - -[tx-deposits-spec]: deposits.md#user-deposited-transactions - -## Depositing Call - -[depositing-call]: glossary.md#depositing-call - -A *depositing call* is an L1 call to the [deposit contract][deposit-contract], which will be derived to a -[user-deposited transaction][user-deposited] by the [rollup driver]. - -This call specifies all the data (destination, value, calldata, ...) for the deposited transaction. - -## Depositing Transaction - -[depositing-tx]: glossary.md#depositing-transaction - -A *depositing transaction* is an L1 transaction that makes one or more [depositing calls][depositing-call]. - -## Depositor - -[depositor]: glossary.md#depositor - -The *depositor* is the L1 account (contract or [EOA]) that makes (is the `msg.sender` of) the [depositing -call][depositing-call]. The *depositor* is **NOT** the originator of the depositing transaction (i.e. `tx.origin`). - -## Deposited Transaction Type - -[deposit-tx-type]: glossary.md#deposited-transaction-type - -The *deposited transaction type* is an [EIP-2718] [transaction type][transaction-type], which specifies the input fields -and correct handling of a [deposited transaction][deposited]. - -See the [corresponding section][spec-deposit-tx-type] of the deposits spec for more information. - -[spec-deposit-tx-type]: deposits.md#the-deposited-transaction-type - -## Deposit Contract - -[deposit-contract]: glossary.md#deposit-contract - -The *deposit contract* is an [L1] contract to which [EOAs][EOA] and contracts may send [deposits]. The deposits are -emitted as log records (in Solidity, these are called *events*) for consumption by [rollup nodes][rollup-node]. - -Advanced note: the deposits are not stored in calldata because they can be sent by contracts, in which case the calldata -is part of the *internal* execution between contracts, and this intermediate calldata is not captured in one of the -[Merkle Patricia Trie roots][mpt] included in the L1 block. - -cf. [Deposits Specification](deposits.md) - ------------------------------------------------------------------------------------------------------------------------- - -# Withdrawals - -> **TODO** expand this whole section to be clearer - -[withdrawals]: glossary.md#withdrawals - -In general, a withdrawal is a transaction sent from L2 to L1 that may transfer data and/or value. - -The term *withdrawal* is somewhat ambiguous as these "transactions" exist at multiple levels. In order to differentiate - between the L1 and L2 components of a withdrawal we introduce the following terms: - -- A *withdrawal initiating transaction* refers specifically to a transaction on L2 sent to the Withdrawals predeploy. -- A *withdrawal finalizing transaction* refers specifically to an L1 transaction which finalizes and relays the - withdrawal. - -## Relayer - -[relayer]: glossary.md#withdrawals - -An EOA on L1 which finalizes a withdrawal by submitting the data necessary to verify its inclusion on L2. - -## Finalization Period - -[finalization-period]: glossary.md#finalization-period - -The finalization period — sometimes also called *withdrawal delay* — is the minimum amount of time (in seconds) that -must elapse before a [withdrawal][withrawals] can be finalized. - -The finalization period is necessary to afford sufficient time for [validators][validator] to make a [fault -proof][fault-proof]. - -> **TODO** specify current value for finalization period - ------------------------------------------------------------------------------------------------------------------------- - -# Batch Submission - -[batch-submission]: glossary.md#batch-submission - -## Data Availability - - [data-availability]: glossary.md#data-availability - -Data availability is the guarantee that some data will be "available" (i.e. *retrievable*) during a reasonably long time -window. In Optimism's case, the data in question are [sequencer batches][sequencer-batch] that [validators][validator] -need in order to verify the sequencer's work and validate the L2 chain. - -The [finalization period][finalization-period] should be taken as the lower bound on the availability window, since -that is when data availability is the most crucial, as it is needed to perform a [fault proof][fault-proof]. - -"Availability" **does not** mean guaranteed long-term storage of the data. - -## Data Availability Provider - -[avail-provider]: glossary.md#data-availability-provider - -A data availability provider is a service that can be used to make data available. See the [Data -Availability][data-availability] for more information on what this means. - -Ideally, a good data availability provider provides strong *verifiable* guarantees of data availability - -Currently, the only supported data availability provider is Ethereum call data. [Ethereum data blobs][eip4844] will be -supported when they get deployed on Ethereum. - -## Sequencer Batch - -[sequencer-batch]: glossary.md#sequencer-batch - -A sequencer batch is list of L2 transactions (that were submitted to a sequencer) tagged with an [epoch -number](#sequencing-epoch) and an L2 block timestamp (which can trivially be converted to a block number, given our -block time is constant). - -Sequencer batches are part of the [L2 derivation inputs][deriv-inputs]. Each batch represents the inputs needed to build -**one** L2 block (given the existing L2 chain state) — except for the first block of each epoch, which also needs -information about deposits (cf. the section on [L2 derivation inputs][deriv-inputs]). - -## Channel - -[channel]: glossary.md#channel - -A channel is a sequence of [sequencer batches][sequencer-batch] (for sequential blocks) compressed together. The reason -to group multiple batches together is simply to obtain a better compression rate, hence reducing data availability -costs. - -A channel can be split in [frames][channel-frame] in order to be transmitted via [batcher -transactions][batcher-transaction]. The reason to split a channel into frames is that a channel might be too large to -include in a single batcher transaction. - -A channel is uniquely identified by its timestamp (UNIX time at which the channel was created) and a random value. See -the [Frame Format][frame-format] section of the L2 Chain Derivation specification for more information. - -[frame-format]: derivation.md#frame-format - -On the side of the [rollup node][rollup-node] (which is the consumer of channels), a channel is considered to be -*opened* if its final frame (explicitly marked as such) has not been read, or closed otherwise. - -## Channel Frame - -[channel-frame]: glossary.md#channel-frame - -A channel frame is a chunk of data belonging to a [channel]. [Batcher transactions][batcher-transaction] carry one or -multiple frames. The reason to split a channel into frames is that a channel might too large to include in a single -batcher transaction. - -## Batcher - -[batcher]: glossary.md#batcher - -A batcher is a software component (independant program) that is responsible to make channels available on a data -availability provider. The batcher communicates with the rollup node in order to retrieve the channels. The channels are -then made available using [batcher transactions][batcher-transaction]. - -> **TODO** In the future, we might want to make the batcher responsible for constructing the channels, letting it only -> query the rollup node for L2 block inputs. - -## Batcher Transaction - -[batcher-transaction]: glossary.md#batcher-transaction - -A batcher transaction is a transaction submitted by a [batcher] to a data availability provider, in order to make -channels available. These transactions carry one or more full frames, which may belong to different channels. A -channel's frame may be split between multiple batcher transactions. - -When submitted to Ethereum calldata, the batcher transaction's receiver must be the sequencer inbox address. The -transaction must also be signed by a recognized batch submitter account. The recognized batch submitter account -is stored in the [System Configuration][system-config]. - -## Channel Timeout - -[channel-timeout]: glossary.md#channel-timeout - -The channel timeout is a duration (in L1 blocks) during which [channel frames][channel-frame] may land on L1 within -[batcher transactions][batcher-transaction]. - -The acceptable time range for the frames of a [channel][channel] is `[channel_id.timestamp, channel_id.timestamp + -CHANNEL_TIMEOUT]`. The acceptable L1 block range for these frames are any L1 block whose timestamp falls inside this -time range. (Note that `channel_id.timetamp` must be lower than the L1 block timestamp of any L1 block in which frames -of the channel are seen, or else these frames are ignored.) - -The purpose of channel timeouts is dual: - -- Avoid keeping old unclosed channel data around forever (an unclosed channel is a channel whose final frame was not - sent). -- Bound the number of L1 blocks we have to look back in order to decode [sequencer batches][sequencer-batch] from - channels. This is particularly relevant during L1 re-orgs, see the [Resetting Channel Buffering][reset-channel-buffer] - section of the L2 Chain Derivation specifiction for more information. - -[reset-channel-buffer]: derivation.md#resetting-channel-buffering - -> **TODO** specify `CHANNEL_TIMEOUT` - ------------------------------------------------------------------------------------------------------------------------- - -# L2 Chain Derivation - -[derivation]: glossary.md#L2-chain-derivation - -L2 chain derivation is a process that reads [L2 derivation inputs][deriv-inputs] from L1 in order to derive the L2 -chain. - -See the [L2 chain derivation specification][derivation-spec] for more details. - -## L2 Derivation Inputs - -[deriv-inputs]: glossary.md#l2-chain-derivation-inputs - -This term refers to data that is found in L1 blocks and is read by the [rollup node][rollup-node] to construct [payload -attributes][payload-attr]. - -L2 derivation inputs include: - -- L1 block attributes - - block number - - timestamp - - basefee -- [deposits] (as log data) -- [sequencer batches][sequencer-batch] (as transaction data) -- [System configuration][system-config] updates (as log data) - -## System Configuration - -[system-config]: glossary.md#system-configuration - -This term refers to the collection of dynamically configurable rollup parameters maintained -by the [`SystemConfig`](./system_config.md) contract on L1 and read by the L2 [derivation] process. -These parameters enable keys to be rotated regularly and external cost parameters to be adjusted -without the network upgrade overhead of a hardfork. - -## Payload Attributes - -[payload-attr]: glossary.md#payload-attributes - -This term refers to an object that can be derived from [L2 chain derivation inputs][deriv-inputs] found on L1, which are -then passed to the [execution engine][execution-engine] to construct L2 blocks. - -The payload attributes object essentially encodes [a block without output properties][block]. - -Payload attributes are originally specified in the [Ethereum Engine API specification][engine-api], which we expand in -the [Execution Engine Specification](exec-engine.md). - -See also the [Building The Payload Attributes][building-payload-attr] section of the rollup node specification. - -[building-payload-attr]: rollup-node.md#building-the-payload-attributes - -## L2 Genesis Block - -[l2-genesis]: glossary.md#l2-genesis-block - -The L2 genesis block is the first block of the L2 chain in its current version. - -The state of the L2 genesis block comprises: - -- State inherited from the previous version of the L2 chain. - - This state was possibly modified by "state surgeries". For instance, the migration to Bedrock entailed changes on - how native ETH balances were stored in the storage trie. -- [Predeployed contracts][predeploy] - -The timestap of the L2 genesis block must be a multiple of the [block time][block-time] (i.e. a even number, since the -block time is 2 seconds). - -When updating the rollup protocol to a new version, we may perform a *squash fork*, a process that entails the creation -of a new L2 genesis block. This new L2 genesis block will have block number `X + 1`, where `X` is the block number of -the final L2 block before the update. - -A squash fork is not to be confused with a *re-genesis*, a similar process that we employed in the past, which also -resets L2 block numbers, such that the new L2 genesis block has number 0. We will not employ re-genesis in the future. - -Squash forks are superior to re-geneses because they avoid duplicating L2 block numbers, which breaks a lot of external -tools. - -## L2 Chain Inception - -[l2-chain-inception]: glossary.md#L2-chain-inception - -The L1 block number at which the output roots for the [genesis block][l2-genesis] were proposed on the [output -oracle][output-oracle] contract. - -In the current implementation, this is the L1 block number at which the output oracle contract was deployed or upgraded. - -## Safe L2 Block - -[safe-l2-block]: glossary.md#safe-l2-block - -A safe L2 block is an L2 block that can be derived entirely from L1 by a [rollup node][rollup-node]. This can vary -between different nodes, based on their view of the L1 chain. - -## Safe L2 Head - -[safe-l2-head]: glossary.md#safe-l2-head - -The safe L2 head is the highest [safe L2 block][safe-l2-block] that a [rollup node][rollup-node] knows about. - -## Unsafe L2 Block - -[unsafe-l2-block]: glossary.md#unsafe-l2-block - -An unsafe L2 block is an L2 block that a [rollup node][rollup-node] knows about, but which was not derived from the L1 -chain. In sequencer mode, this will be a block sequenced by the sequencer itself. In validator mode, this will be a -block acquired from the sequencer via [unsafe sync][unsafe-sync]. - -## Unsafe L2 Head - -[unsafe-l2-head]: glossary.md#unsafe-l2-head - -The unsafe L2 head is the highest [unsafe L2 block][unsafe-l2-block] that a [rollup node][rollup-node] knows about. - -## Unsafe Block Consolidation - -[consolidation]: glossary.md#unsafe-block-consolidation - -Unsafe block consolidation is the process through which the [rollup node][rollup-node] attempts to move the [safe L2 -head] a block forward, so that the oldest [unsafe L2 block][unsafe-l2-block] becomes the new safe L2 head. - -In order to perform consolidation, the node verifies that the [payload attributes][payload-attr] derived from the L1 -chain match the oldest unsafe L2 block exactly. - -See the [Engine Queue section][engine-queue] of the L2 chain derivatiaon spec for more information. - -[engine-queue]: derivation.md#engine-queue - -## Finalized L2 Head - -[finalized-l2-head]: glossary.md#finalized-l2-head - -The finalized L2 head is the highest L2 block that can be derived from *[finalized][finality]* L1 blocks — i.e. L1 -blocks older than two L1 epochs (64 L1 [time slots][time-slot]). - -[finality]: *finalized* L1 data. - ------------------------------------------------------------------------------------------------------------------------- - -# Other L2 Chain Concepts - -## Address Aliasing - -[address-aliasing]: glossary.md#address-aliasing - -When a contract submits a [deposit][deposits] from L1 to L2, its address (as returned by `ORIGIN` and `CALLER`) will be -aliased with a modified representation of the address of a contract. - -- cf. [Deposit Specification](deposits.md#address-aliasing) - -## Rollup Node - -[rollup-node]: glossary.md#rollup-node - -The rollup node is responsible for [deriving the L2 chain][derivation] from the L1 chain (L1 [blocks][block] and their -associated [receipts][receipt]). - -The rollup node can run either in *validator* or *sequencer* mode. - -In sequencer mode, the rollup node receives L2 transactions from users, which it uses to create L2 blocks. These are -then submitted to a [data availability provider][avail-provider] via [batch submission][batch-submission]. The L2 chain -derivation then acts as a sanity check and a way to detect L1 chain [re-orgs][reorg]. - -In validator mode, the rollup node performs derivation as indicated above, but is also able to "run ahead" of the L1 -chain by getting blocks directly from the sequencer, in which case derivation serves to validate the sequencer's -behaviour. - -A rollup node running in validator mode is sometimes called *a replica*. - -> **TODO** expand this to include output root submission - -See the [rollup node specification][rollup-node-spec] for more information. - -## Rollup Driver - -[rollup driver]: glossary.md#rollup-driver - -The rollup driver is the [rollup node][rollup-node] component responsible for [deriving the L2 chain][derivation] -from the L1 chain (L1 [blocks][block] and their associated [receipts][receipt]). - -> **TODO** delete this entry, alongside its reference — can be replaced by "derivation process" or "derivation logic" -> where needed - -## L1 Attributes Predeployed Contract - -[l1-attr-predeploy]: glossary.md#l1-attributes-predeployed-contract - -A [predeployed contract][predeploy] on L2 that can be used to retrieve the L1 block attributes of L1 blocks with a given -block number or a given block hash. - -cf. [L1 Attributes Predeployed Contract Specification](deposits.md#l1-attributes-predeployed-contract) - -## L2 Output Root - -[l2-output]: glossary.md#l2-output-root - -A 32 byte value which serves as a commitment to the current state of the L2 chain. - -cf. [Proposing L2 output commitments](proposals.md#l2-output-root-proposals-specification) - -## L2 Output Oracle Contract - -[output-oracle]: glossary.md#l2-output-oracle-contract - -An L1 contract to which [L2 output roots][l2-output] are posted by the [sequencer]. - -> **TODO** expand - -## Validator - -[validator]: glossary.md#validator - -A validator is an entity (individual or organization) that runs a [rollup node][rollup-node] in validator mode. - -Doing so grants a lot of benefits similar to running an Ethereum node, such as the ability to simulate L2 transactions -locally, without rate limiting. - -It also lets the validator verify the work of the [sequencer], by re-deriving [output roots][l2-output] and comparing -them against those submitted by the sequencer. In case of a mismatch, the validator can perform a [fault -proof][fault-proof]. - -## Fault Proof - -[fault-proof]: glossary.md#fault-proof - -An on-chain *interactive* proof, performed by [validators][validator], that demonstrates that a [sequencer] provided -erroneous [output roots][l2-output]. - -Fault proofs are not specified yet. For now, the best place to find information about fault proofs is the [Cannon -repository][cannon]. - -> **TODO** expand - -## Time Slot - -[time-slot]: glossary.md#time-slot - -On L2, there is a block every 2 second (this duration is known as the [block time][block-time]). - -We say that there is a "time slot" every multiple of 2s after the timestamp of the [L2 genesis block][l2-genesis]. - -On L1, post-[merge], the time slots are every 12s. However, an L1 block may not be produced for every time slot, in case -of even benign consensus issues. - -## Block Time - -[block-time]: glossary.md#block-time - -The L2 block time is 2 second, meaning there is an L2 block at every 2s [time slot][time-slot]. - -Post-[merge], it could be said the that L1 block time is 12s as that is the L1 [time slot][time-slot]. However, in -reality the block time is variable as some time slots might be skipped. - -Pre-merge, the L1 block time is variable, though it is on average 13s. - -## Unsafe Sync - -[unsafe-sync]: glossary.md#unsafe-sync - -Unsafe sync is the process through which a [validator][validator] learns about [unsafe L2 blocks][unsafe-l2-block] from -the [sequencer][sequencer]. - -These unsafe blocks will later need to be confirmed by the L1 chain (via [unsafe block consolidation][consolidation]). - ------------------------------------------------------------------------------------------------------------------------- - -# Execution Engine Concepts - -## Execution Engine - -[execution-engine]: glossary.md#execution-engine - -The execution engine is responsible for executing transactions in blocks and computing the resulting state roots, -receipts roots and block hash. - -Both L1 (post-[merge]) and L2 have an execution engine. - -On L1, the executed blocks can come from L1 block synchronization; or from a block freshly minted by the execution -engine (using transactions from the L1 [mempool]), at the request of the L1 consensus layer. - -On L2, the executed blocks are freshly minted by the execution engine at the request of the [rollup node][rollup-node], -using transactions [derived from L1 blocks][derivation]. - -In these specifications, "execution engine" always refer to the L2 execution engine, unless otherwise specified. - -- cf. [Execution Engine Specification](exec-engine.md) - - -[derivation-spec]: derivation.md -[rollup-node-spec]: rollup-node.md - - -[mpt-details]: https://github.com/norswap/nanoeth/blob/d4c0c89cc774d4225d16970aa44c74114c1cfa63/src/com/norswap/nanoeth/trees/patricia/README.md -[trie]: https://en.wikipedia.org/wiki/Trie -[bloom filter]: https://en.wikipedia.org/wiki/Bloom_filter -[Solidity events]: https://docs.soliditylang.org/en/latest/contracts.html?highlight=events#events -[nano-header]: https://github.com/norswap/nanoeth/blob/cc5d94a349c90627024f3cd629a2d830008fec72/src/com/norswap/nanoeth/blocks/BlockHeader.java#L22-L156 -[yellow]: https://ethereum.github.io/yellowpaper/paper.pdf -[engine-api]: https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#PayloadAttributesV1 -[merge]: https://ethereum.org/en/eth2/merge/ -[mempool]: https://www.quicknode.com/guides/defi/how-to-access-ethereum-mempool -[L1 consensus layer]: https://github.com/ethereum/consensus-specs/#readme -[cannon]: https://github.com/ethereum-optimism/cannon -[eip4844]: https://www.eip4844.com/ diff --git a/specs/guaranteed-gas-market.md b/specs/guaranteed-gas-market.md deleted file mode 100644 index f1abadb557c4..000000000000 --- a/specs/guaranteed-gas-market.md +++ /dev/null @@ -1,155 +0,0 @@ -# Guaranteed Gas Fee Market - - - -**Table of Contents** - -- [Gas Stipend](#gas-stipend) -- [Default Values](#default-values) -- [Limiting Guaranteed Gas](#limiting-guaranteed-gas) -- [Rationale for burning L1 Gas](#rationale-for-burning-l1-gas) -- [On Preventing Griefing Attacks](#on-preventing-griefing-attacks) - - - -[Deposited transaction](./glossary.md#deposited-transaction) are transactions on L2 that are -initiated on L1. The gas that they use on L2 is bought on L1 via a gas burn (or a direct payment -in the future). We maintain a fee market and hard cap on the amount of gas provided to all deposits -in a single L1 block. - -The gas provided to deposited transactions is sometimes called "guaranteed gas". The gas provided to -deposited transactions is unique in the regard that it is not refundable. It cannot be refunded as -it is sometimes paid for with a gas burn and there may not be any ETH left to refund. - -The **guaranteed gas** is composed of a gas stipend, and of any guaranteed gas the user would like -to purchase (on L1) on top of that. - -Guaranteed gas on L2 is bought in the following manner. An L2 gas price is calculated via an -EIP-1559-style algorithm. The total amount of ETH required to buy that gas is then calculated as -(`guaranteed gas * L2 deposit basefee`). The contract then accepts that amount of ETH (in a future -upgrade) or (only method right now), burns an amount of L1 gas that corresponds to the L2 cost -(`L2 cost / L1 Basefee`). The L2 gas price for guaranteed gas is not synchronized with the basefee -on L2 and will likely be different. - -## Gas Stipend - -To offset the gas spent on the deposit event, we credit `gas spent * L1 basefee` ETH to the cost of -the L2 gas, where `gas spent` is the amount of L1 gas spent processing the deposit. If the ETH value -of this credit is greater than the ETH value of the requested guaranteed gas -(`requested guaranteed gas * L2 gas price`), no L1 gas is burnt. - -## Default Values - -| Variable | Value | -| ------------------------------- | ----------------- | -| Max Resource Limit | 20,000,000 | -| Elasticity Multiplier | 10 | -| Base Fee Max Change Denominator | 8 | -| Minimum Base Fee | 1 gwei | -| Maximum Base Fee | type(uint128).max | -| System Tx Max Gas | 1,000,000 | - -## Limiting Guaranteed Gas - -The total amount of guaranteed gas that can be bought in a single L1 block must be limited to -prevent a denial of service attack against L2 as well as ensure the total amount of guaranteed gas -stays below the L2 block gas limit. - -We set a guaranteed gas limit of 8,000,000 gas per L1 block and a target of 2,000,000 gas per L1 -block. These numbers enabled occasional large transactions while staying within our target and -maximum gas usage on L2. - -Because the amount of guaranteed L2 gas that can be purchased in a single block is now limited, -we implement an EIP-1559-style fee market to reduce congestion on deposits. By setting the limit -at a multiple of the target, we enable deposits to temporarily use more L2 gas at a greater cost. - -```python -# Pseudocode to update the L2 Deposit Basefee and cap the amount of guaranteed gas -# bought in a block. Calling code must handle the gas burn and validity checks on -# the ability of the account to afford this gas. -BASE_FEE_MAX_CHANGE_DENOMINATOR = 8 -ELASTICITY_MULTIPLIER = 4 -MAX_RESOURCE_LIMIT = 8_000_000 -TARGET_RESOURCE_LIMIT = MAX_RESOURCE_LIMIT / ELASTICITY_MULTIPLIER -MINIMUM_BASEFEE = 10000 - -# prev_basefee is a u128, prev_bought_gas and prev_num are u64s -prev_basefee, prev_bought_gas, prev_num = -now_num = block.number - -# Clamp the full basefee to a specific range. The minimum value in the range should be around 100-1000 -# to enable faster responses in the basefee. This replaces the `max` mechanism in the ethereum 1559 -# implementation (it also serves to enable the basefee to increase if it is very small). -def clamp(v: i256, min: u128, max: u128) -> u128: - if v < i256(min): - return min - elif v > i256(max): - return max - else: - return u128(v) - -# If this is a new block, update the basefee and reset the total gas -# If not, just update the total gas -if prev_num == now_num: - now_basefee = prev_basefee - now_bought_gas = prev_bought_gas + requested_gas -elif prev_num != now_num: - # Width extension and conversion to signed integer math - gas_used_delta = int128(prev_bought_gas) - int128(TARGET_RESOURCE_LIMIT) - # Use truncating (round to 0) division - solidity's default. - # Sign extend gas_used_delta & prev_basefee to 256 bits to avoid overflows here. - base_fee_per_gas_delta = prev_basefee * gas_used_delta / TARGET_RESOURCE_LIMIT / BASE_FEE_MAX_CHANGE_DENOMINATOR - now_basefee_wide = prev_basefee + base_fee_per_gas_delta - - now_basefee = clamp(now_basefee_wide, min=MINIMUM_BASEFEE, max=UINT_128_MAX_VALUE) - now_bought_gas = requested_gas - - # If we skipped multiple blocks between the previous block and now update the basefee again. - # This is not exactly the same as iterating the above function, but quite close for reasonable - # gas target values. It is also constant time wrt the number of missed blocks which is important - # for keeping gas usage stable. - if prev_num + 1 < now_num: - n = now_num - prev_num - 1 - # Apply 7/8 reduction to prev_basefee for the n empty blocks in a row. - now_basefee_wide = now_basefee * pow(1-(1/BASE_FEE_MAX_CHANGE_DENOMINATOR), n) - now_basefee = clamp(now_basefee_wide, min=MINIMUM_BASEFEE, max=type(uint128).max) - -require(now_bought_gas < MAX_RESOURCE_LIMIT) - -store_values(now_basefee, now_bought_gas, now_num) -``` - -## Rationale for burning L1 Gas - -There must be a sybil resistance mechanism for usage of the network. If it is very cheap to get -guaranteed gas on L2, then it would be possible to spam the network. Burning a dynamic amount -of gas on L1 acts as a sybil resistance mechanism as it becomes more expensive with more demand. - -If we collect ETH directly to pay for L2 gas, every (indirect) caller of the deposit function will need -to be marked with the payable selector. This won't be possible for many existing projects. Unfortunately -this is quite wasteful. As such, we will provide two options to buy L2 gas: - -1. Burn L1 Gas -2. Send ETH to the Optimism Portal (Not yet supported) - -The payable version (Option 2) will likely have discount applied to it (or conversely, #1 has a -premium applied to it). - -For the initial release of bedrock, only #1 is supported. - -## On Preventing Griefing Attacks - -The cost of purchasing all of the deposit gas in every block must be expensive -enough to prevent attackers from griefing all deposits to the network. -An attacker would observe a deposit in the mempool and frontrun it with a deposit -that purchases enough gas such that the other deposit reverts. -The smaller the max resource limit is, the easier this attack is to pull off. -This attack is mitigated by having a large resource limit as well as a large -elastcity multiplier. This means that the target resource usage is kept small, -giving a lot of room for the deposit base fee to rise when the max resource limit -is being purchased. - -This attack should be too expensive to pull off in practice, but if an extremely -wealthy adversary does decide to grief network deposits for an extended period -of time, efforts will be placed to ensure that deposits are able to be processed -on the network. diff --git a/specs/honest-challenger-fdg.md b/specs/honest-challenger-fdg.md deleted file mode 100644 index f5e6cd15c04b..000000000000 --- a/specs/honest-challenger-fdg.md +++ /dev/null @@ -1,143 +0,0 @@ -# Honest Challenger (Fault Dispute Game) - - - -**Table of Contents** - -- [Overview](#overview) -- [FDG Responses](#fdg-responses) - - [Root Claims](#root-claims) - - [Counter Claims](#counter-claims) - - [Steps](#steps) -- [Resolution](#resolution) - - - -The honest challenger is an agent interacting in the [Fault Dispute Game](./fault-dispute-game.md) -(FDG) that supports honest claims and disputes false claims. -An honest challenger strives to ensure a correct, truthful, game resolution. -The honest challenger is also _rational_ as any deviation from its behavior will result in -negative outcomes. -This document specifies the expected behavior of an honest challenger. - -## Overview - -The Honest Challenger has two primary duties: - -1. Support valid root claims in Fault Dispute Games. -2. Dispute invalid root claims in Fault Dispute Games. - -The honest challenger polls the `DisputeGameFactory` contract for new and on-going Fault -Dispute Games. -For verifying the legitimacy of claims, it relies on a synced, trusted rollup node -as well as a trace provider (ex: [Cannon](./cannon-fault-proof-vm.md)). -The trace provider must be configured with the [ABSOLUTE_PRESTATE](./fault-dispute-game.md#execution-trace) -of the FDG being interacted with to generate the traces needed to make truthful claims. - -## FDG Responses - -### Root Claims - -When a `FaultDisputeGame` is created, the honest challenger has two possible correct responses -to its root claim: - -1. [**Attack**](./fault-dispute-game.md#attack) if they disagree with the root claim. -The root claim commits to the entire execution trace, so the first move here is to -attack with the [ClaimHash](./fault-dispute-game.md#claims) at the midpoint -instruction within their execution trace. -2. **Do Nothing** if they agree with the root claim. They do nothing because if the root -claim is left un-countered, the game resolves to their agreement. -NOTE: The honest challenger will still track this game in order to defend any subsequent -claims made against the root claim - in effect, "playing the game". - -### Counter Claims - -For every claim made in a dispute game with a [game tree](./fault-dispute-game.md#game-tree) -depth in the range of `[1, MAX_DEPTH]`, the honest challenger processes them and performs -a response. - -To determine the appropriate response, the challenger first needs to know which -[_team_](./fault-dispute-game.md#team-dynamics) it belongs to. -This determines the set of claims it should respond to in the FDG. -If the agent determines itself to be a Defender, which aims to support the root claim, -then it must dispute claims positioned at odd depths in the game tree. -Otherwise, it disputes claims positioned at even depths in the game tree. -This means an honest challenger only responds to claims made by the opposing team. - -The next step is to determine if the claim, now known to be for the opposing team, -disputes another claim the honest challenger _agrees_ with. -An honest challenger agrees with a claim iff every other claim along its path to the -root claim commits to a valid `ClaimHash`. Put differently, an honest challenger will -avoid countering a claim if it disagrees with the path of claims leading to that -specific claim. But if the honest challenger agrees with the path leading to the claim, -then the claim is countered. - -The last step is to determine whether the claim has a valid commitment (i.e. `ClaimHash`). -If the `ClaimHash` matches the honest challenger's at the same trace index, then we -disagree with the claim's stance by moving to [defend](./fault-dispute-game.md#defend). -Otherwise, the claim is [attacked](./fault-dispute-game.md#attack). - -The following pseudocode illustrates the response logic. - -```python -class Team(Enum): - DEFENDER = 0 - CHALLENGER = 1 - -class Claim: - parent: Claim - position: uint64 - claim_hash: ClaimHash - -MAX_TRACE = 2**MAX_GAME_DEPTH - -def agree_with(claim: Claim, chal_trace: List[ClaimHash, MAX_TRACE]): - if chal_trace[claim.trace_index] != claim.claim_hash: - return False - grand_parent = claim.parent.parent if claim.parent is not None else None - if grand_parent is not None: - return agree_with(grand_parent) - return True - -def respond(claim: Claim, chal: Team, chal_trace: List[ClaimHash, MAX_TRACE]): - if depth(claim.position) % 2 != chal.value: - if claim.parent is None or agree_with(claim.parent, chal_trace): - if chal_trace[trace_index(claim.position)] == claim.claim_hash: - defend() - else: - attack() - else: pass # avoid supporting invalid claims on the same team -``` - -In attack or defense, the honest challenger submit a `ClaimHash` corresponding to the -state identified by the trace index of their response position. - -The honest challenger responds to claims as soon as possible to avoid the clock of its -counter-claim from expiring. - -### Steps - -At the max depth of the game, claims represent commitments to the state of the fault proof VM -at a single instruction step interval. -Because the game can no longer bisect further, when the honest challenger has a valid move -against these claims (valid defined by the response in [Counter Claims](#counter-claims)), -the only option for an honest challenger is to execute a VM step on-chain to disprove the claim at `MAX_GAME_DEPTH`. - -Similar to the above section, the honest challenger will issue an -[attack step](./fault-dispute-game.md#step-types) when in response to such claims with -invalid `ClaimHash` commitments. Otherwise, it issues a _defense step_. - -## Resolution - -When the [chess clock](./fault-dispute-game.md#game-clock) of a -[subgame root](./fault-dispute-game.md#resolution) has run out, the subgame can be resolved. -The honest challenger should resolve all subgames in bottom-up order, until the subgame -rooted at the FDG root is resolved. - -The honest challenger accomplishes this by calling the `resolveClaim` function on the -`FaultDisputeGame` contract. Once the root claim's subgame is resolved, -the challenger then finally calls the `resolve` function to resolve the entire game. - -The `FaultDisputeGame` does not put a time cap on resolution - because of the liveness -assumption on honest challengers and the bonds attached to the claims they’ve countered, -challengers are economically incentivized to resolve the game promptly to capture the bonds. diff --git a/specs/introduction.md b/specs/introduction.md deleted file mode 100644 index c613c1c0d22a..000000000000 --- a/specs/introduction.md +++ /dev/null @@ -1,161 +0,0 @@ -# Introduction - - - -**Table of Contents** - -- [Foundations](#foundations) - - [What is Ethereum scalability?](#what-is-ethereum-scalability) - - [What is an Optimistic Rollup?](#what-is-an-optimistic-rollup) - - [What is EVM Equivalence?](#what-is-evm-equivalence) - - [🎶 All together now 🎶](#-all-together-now-) -- [Protocol Guarantees](#protocol-guarantees) -- [Network Participants](#network-participants) - - [Users](#users) - - [Sequencers](#sequencers) - - [Verifiers](#verifiers) -- [Key Interaction Diagrams](#key-interaction-diagrams) - - [Depositing and Sending Transactions](#depositing-and-sending-transactions) - - [Withdrawing](#withdrawing) -- [Next Steps](#next-steps) - - - -Optimism is an _EVM equivalent_, _optimistic rollup_ protocol designed to _scale Ethereum_ while remaining maximally -compatible with existing Ethereum infrastructure. This document provides an overview of the protocol to provide context -for the rest of the specification. - -## Foundations - -### What is Ethereum scalability? - -Scaling Ethereum means increasing the number of useful transactions the Ethereum network can process. Ethereum's -limited resources, specifically bandwidth, computation, and storage, constrain the number of transactions which can be -processed on the network. Of the three resources, computation and storage are currently the most significant -bottlenecks. These bottlenecks limit the supply of transactions, leading to extremely high fees. Scaling ethereum and -reducing fees can be achieved by better utilizing bandwidth, computation and storage. - -### What is an Optimistic Rollup? - -[Optimistic rollup](https://vitalik.ca/general/2021/01/05/rollup.html) is a layer 2 scalability technique which -increases the computation & storage capacity of Ethereum without sacrificing security or decentralization. Transaction -data is submitted on-chain but executed off-chain. If there is an error in the off-chain execution, a fault proof can -be submitted on-chain to correct the error and protect user funds. In the same way you don't go to court unless there -is a dispute, you don't execute transactions on on-chain unless there is an error. - -### What is EVM Equivalence? - -[EVM Equivalence](https://medium.com/ethereum-optimism/introducing-evm-equivalence-5c2021deb306) is complete compliance -with the state transition function described in the Ethereum yellow paper, the formal definition of the protocol. By -conforming to the Ethereum standard across EVM equivalent rollups, smart contract developers can write once and deploy -anywhere. - -### 🎶 All together now 🎶 - -**Optimism is an _EVM equivalent_, _optimistic rollup_ protocol designed to _scale Ethereum_.** - -## Protocol Guarantees - -In order to scale Ethereum without sacrificing security, we must preserve 3 critical properties of Ethereum layer 1: -liveness, availability, and validity. - -1. **Liveness** - Anyone must be able to extend the rollup chain by sending transactions at any time. - - There are two ways transactions can be sent to the rollup chain: 1) via the sequencer, and 2) directly on layer 1. -The sequencer provides low latency & low cost transactions, while sending transactions directly to layer 1 provides -censorship resistance. -1. **Availability** - Anyone must be able to download the rollup chain. - - All information required to derive the chain is embedded into layer 1 blocks. That way as long as the layer 1 -chain is available, so is the rollup. -1. **Validity** - All transactions must be correctly executed and all withdrawals correctly processed. - - The rollup state and withdrawals are managed on an L1 contract called the `L2OutputOracle`. This oracle is -guaranteed to _only_ finalize correct (ie. valid) rollup block hashes given a **single honest verifier** assumption. If -there is ever an invalid block hash asserted on layer 1, an honest verifier will prove it is invalid and win a bond. - -**Footnote**: There are two main ways to enforce validity of a rollup: fault proofs (optimistic rollup) and validity -proofs (zkRollup). For the purposes of this spec we only focus on fault proofs but it is worth noting that validity -proofs can also be plugged in once they have been made feasible. - -## Network Participants - -There are three actors in Optimism: users, sequencers, and verifiers. - -![Network Overview](./assets/network-participants-overview.svg) - -### Users - -At the heart of the network are users (us!). Users can: - -1. Deposit or withdraw arbitrary transactions on L2 by sending data to a contract on Ethereum mainnet. -2. Use EVM smart contracts on layer 2 by sending transactions to the sequencers. -3. View the status of transactions using block explorers provided by network verifiers. - -### Sequencers - -The sequencer is the primary block producer. -There may be one sequencer **or** many using a consensus protocol. -For 1.0.0, there is just one sequencer (currently operated under the oversight of the Optimism Foundation). -In general, specifications may use "the sequencer" to be a stand-in term -for the consensus protocol operated by multiple sequencers. - -The sequencer: - -1. Accepts user off-chain transactions -2. Observes on-chain transactions (primarily, deposit events coming from L1) -3. Consolidates both kinds of transactions into L2 blocks with a specific ordering. -4. Propagates consolidated L2 blocks to L1, by submitting two things as calldata to L1: - - The pending off-chain transactions accepted in step 1. - - Sufficient information about the ordering of the on-chain transactions to successfully reconstruct the blocks -from step 3., purely by watching L1. - -The sequencer also provides access to block data as early as step 3., so that users may access real-time state in -advance of L1 confirmation if they so choose. - -### Verifiers - -Verifiers serve two purposes: - -1. Serving rollup data to users; and -2. Verifying rollup integrity and disputing invalid assertions. - -In order for the network to remain secure there must be **at least** one honest verifier who is able to verify the -integrity of the rollup chain & serve blockchain data to users. - -## Key Interaction Diagrams - -The following diagrams demonstrate how protocol components are utilized during key user interactions in order to -provide context when diving into any particular component specification. - -### Depositing and Sending Transactions - -Users will often begin their L2 journey by depositing ETH from L1. -Once they have ETH to pay fees, they'll start sending transactions on L2. -The following diagram demonstrates this interaction and all key Optimism components which are or should be utilized: - -![Diagram of Depositing and Sending Transactions](./assets/sequencer-handling-deposits-and-transactions.svg) - -Links to components mentioned in this diagram: - - -- [Rollup Node](./rollup-node.md) -- [Execution Engine](./exec-engine.md) - -- [L2 Output Oracle](./proposals.md#l2-output-oracle-smart-contract) -- [L2 Output Submitter](./proposals.md#proposing-l2-output-commitments) - - -### Withdrawing - -Just as important as depositing, it is critical that users can withdraw from the rollup. Withdrawals are initiated by -normal transactions on L2, but then completed using a transaction on L1 after the dispute period has elapsed. - -![Diagram of Withdrawing](./assets/user-withdrawing-to-l1.svg) - -Links to components mentioned in this diagram: - -- [L2 Output Oracle](./proposals.md#l2-output-oracle-smart-contract) - -## Next Steps - -This is a choose your own adventure. Are you interested in how a verifier works under the hood? Maybe you want to dive -deep into the bit flippin' Fault Proof VM? All key components have been linked at least once in this doc, so you should -now have the context you need to dive in deeper. [The world is yours](https://www.youtube.com/watch?v=e5PnuIRnJW8)! diff --git a/specs/messengers.md b/specs/messengers.md deleted file mode 100644 index cc72b5a691ae..000000000000 --- a/specs/messengers.md +++ /dev/null @@ -1,129 +0,0 @@ -# Cross Domain Messengers - - - -**Table of Contents** - -- [Message Passing](#message-passing) -- [Upgradability](#upgradability) -- [Message Versioning](#message-versioning) - - [Message Version 0](#message-version-0) - - [Message Version 1](#message-version-1) -- [Backwards Compatibility Notes](#backwards-compatibility-notes) - - - -The cross domain messengers are responsible for providing a higher level API for -developers who are interested in sending cross domain messages. They allow for -the ability to replay cross domain messages and sit directly on top of the lower -level system contracts responsible for cross domain messaging on L1 and L2. - -The `CrossDomainMessenger` is extended to create both an -`L1CrossDomainMessenger` and well as a `L2CrossDomainMessenger`. -These contracts are then extended with their legacy APIs to provide backwards -compatibility for applications that integrated before the Bedrock system -upgrade. - -The `L2CrossDomainMessenger` is a predeploy contract located at -`0x4200000000000000000000000000000000000007`. - -The base `CrossDomainMessenger` interface is: - -```solidity -interface CrossDomainMessenger { - event FailedRelayedMessage(bytes32 indexed msgHash); - event RelayedMessage(bytes32 indexed msgHash); - event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); - event SentMessageExtension1(address indexed sender, uint256 value); - - function MESSAGE_VERSION() external view returns (uint16); - function MIN_GAS_CALLDATA_OVERHEAD() external view returns (uint64); - function MIN_GAS_CONSTANT_OVERHEAD() external view returns (uint64); - function MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR() external view returns (uint64); - function MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR() external view returns (uint64); - function OTHER_MESSENGER() external view returns (address); - function baseGas(bytes memory _message, uint32 _minGasLimit) external pure returns (uint64); - function failedMessages(bytes32) external view returns (bool); - function messageNonce() external view returns (uint256); - function relayMessage( - uint256 _nonce, - address _sender, - address _target, - uint256 _value, - uint256 _minGasLimit, - bytes memory _message - ) external payable; - function sendMessage(address _target, bytes memory _message, uint32 _minGasLimit) external payable; - function successfulMessages(bytes32) external view returns (bool); - function xDomainMessageSender() external view returns (address); -} -``` - -## Message Passing - -The `sendMessage` function is used to send a cross domain message. To trigger -the execution on the other side, the `relayMessage` function is called. -Successful messages have their hash stored in the `successfulMessages` mapping -while unsuccessful messages have their hash stored in the `failedMessages` -mapping. - -The user experience when sending from L1 to L2 is a bit different than when -sending a transaction from L2 to L1. When going into L1 from L2, the user does -not need to call `relayMessage` on L2 themselves. The user pays for L2 gas on L1 -and the transaction is automatically pulled into L2 where it is executed on L2. -When going from L2 into L1, the user proves their withdrawal on OptimismPortal, -then waits for the finalization window to pass, and then finalizes the withdrawal -on the OptimismPortal, which calls `relayMessage` on the -`L1CrossDomainMessenger` to finalize the withdrawal. - -## Upgradability - -The L1 and L2 cross domain messengers should be deployed behind upgradable -proxies. This will allow for updating the message version. - -## Message Versioning - -Messages are versioned based on the first 2 bytes of their nonce. Depending on -the version, messages can have a different serialization and hashing scheme. -The first two bytes of the nonce are reserved for version metadata because -a version field was not originally included in the messages themselves, but -a `uint256` nonce is so large that we can very easily pack additional data -into that field. - -### Message Version 0 - -```solidity -abi.encodeWithSignature( - "relayMessage(address,address,bytes,uint256)", - _target, - _sender, - _message, - _messageNonce -); -``` - -### Message Version 1 - -```solidity -abi.encodeWithSignature( - "relayMessage(uint256,address,address,uint256,uint256,bytes)", - _nonce, - _sender, - _target, - _value, - _gasLimit, - _data -); -``` - -## Backwards Compatibility Notes - -An older version of the messenger contracts had the concept of blocked messages -in a `blockedMessages` mapping. This functionality was removed from the -messengers because a smart attacker could get around any message blocking -attempts. It also saves gas on finalizing withdrawals. - -The concept of a "relay id" and the `relayedMessages` mapping was removed. -It was built as a way to be able to fund third parties who relayed messages -on the behalf of users, but it was improperly implemented as it was impossible -to know if the relayed message actually succeeded. diff --git a/specs/meta/README.md b/specs/meta/README.md deleted file mode 100644 index 5039d5a6c019..000000000000 --- a/specs/meta/README.md +++ /dev/null @@ -1,8 +0,0 @@ - -# Meta Processes - -This directory describes processes that we use to lint/test the specification. - -- [Linting](linting.md): how to lint source files. -- [Markdown Style Guide](markdown-style.md): how to format and structure Markdown files. -- [Devnet introduction](devnet.md): how to run a devnet. diff --git a/specs/meta/devnet.md b/specs/meta/devnet.md deleted file mode 100644 index b39a55a04d4f..000000000000 --- a/specs/meta/devnet.md +++ /dev/null @@ -1,53 +0,0 @@ - -# Bedrock Local Devnet Setup - - - -**Table of Contents** - -- [Bedrock Local Devnet Setup](#bedrock-local-devnet-setup) - - - -You can spin up a local devnet via `docker compose`. -For convenience, we have defined `make` targets to start and stop the devnet with a single command. -To run the devnet, you will need `docker` installed. -Then, as a precondition, make sure that you have compiled the contracts by `cd`ing into `packages/contracts-bedrock` -and running `pnpm i` followed by `pnpm build`. You'll only need to do this if you change the contracts in the future. - -Then, run the following: - -```bash -make devnet-up # starts the devnet -make devnet-down # stops the devnet -make devnet-clean # removes the devnet by deleting images and persistent volumes -``` - -L1 is accessible at `http://localhost:8545`, and L2 is accessible at `http://localhost:9545`. -Any Ethereum tool - Metamask, `seth`, etc. - can use these endpoints. -Note that you will need to specify the L2 chain ID manually if you use Metamask. The devnet's L2 chain ID is 901. - -The devnet comes with a pre-funded account you can use as a faucet: - -- Address: `0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266` -- Private key: `ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80` - -The faucet account exists on both L1 and L2. To deposit onto L2 from L1, you can use the `deposit` hardhat task. -Run the following from the `packags/contracts` directory: - -```bash -npx hardhat deposit --amount-eth --to
-```` - -You'll need a `.env` with the following contents: - -```bash -L1_PROVIDER_URL=http://localhost:8545 -L2_PROVIDER_URL=http://localhost:9545 -PRIVATE_KEY=bf7604d9d3a1c7748642b1b7b05c2bd219c9faa91458b370f85e5a40f3b03af7 -``` - -The batch submitter uses the account below to submit batches to L1: - -- Address: `0xde3829a23df1479438622a08a116e8eb3f620bb5` -- Private key: `bf7604d9d3a1c7748642b1b7b05c2bd219c9faa91458b370f85e5a40f3b03af7` diff --git a/specs/meta/linting.md b/specs/meta/linting.md deleted file mode 100644 index 42b39936b062..000000000000 --- a/specs/meta/linting.md +++ /dev/null @@ -1,68 +0,0 @@ -# Linting - - - -**Table of Contents** - -- [Markdown](#markdown) -- [Go](#go) - - - -## Markdown - -See - -- [markdownlint rule reference](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md) -- [exemple .markdownlint.json file](https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.jsonc) - -Justification for linting rules in [.markdownlint.json](/.markdownlint.json): - -- *line_length* (`!strict && stern`): don't trip up on url lines -- *no-blanks-blockquote*: enable multiple consecutive blockquotes separated by white lines -- *single-title*: enable reusing `

` for content -- *no-emphasis-as-heading*: enable emphasized paragraphs - -```shell -pnpm i # Install dependencies -pnpm lint:specs:check # Run linter -pnpm lint:specs:fix # Fix lint issues -pnpm lint:specs:toc # Update TOC docs - -# Check links -docker run --init -it -v `pwd`:/input lycheeverse/lychee --verbose --no-progress --exclude-loopback --exclude twitter.com --exclude-mail /input/README.md "/input/specs/**/*.md" -``` - -To check links, you'll need to install [lychee]. The [version ran in CI][lychee-ci] is 0.8.1, but -you should install lychee 0.8.2 locally with `cargo install --version 0.8.2 lychee` (there are some -reported build problems with 0.8.1). - -You can install cargo (the Rust package manager) via [rustup]. - -[lychee]: https://github.com/lycheeverse/lychee -[lychee-ci]: https://github.com/lycheeverse/lychee-action/blob/f76b8412c668f78311212d16d33c4784a7d8762c/Dockerfile -[rustup]: https://www.rust-lang.org/tools/install - -To update the TOC, we run [doctoc], installed through the dev-dependencies in `package.json`. - -[doctoc]: https://github.com/thlorenz/doctoc - -## Go - -See - -- [golangci-lint docs](https://golangci-lint.run/usage/install/#local-installation) -- [golangci-lint github](https://github.com/golangci/golangci-lint) -- [github action github](https://github.com/golangci/golangci-lint-action) - -Justification for linting rules: - -- *asciicheck*: no symbol names with invisible unicode and such -- *goimports*: group local and external import - -```shell -# Install linter globally (should not affect go.mod) -go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.48.0 -# run linter, add --fix option to fix problems (where supported) -golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 2m -e "errors.As" -e "errors.Is" ./... -``` diff --git a/specs/meta/markdown-style.md b/specs/meta/markdown-style.md deleted file mode 100644 index 81ee837c43c2..000000000000 --- a/specs/meta/markdown-style.md +++ /dev/null @@ -1,53 +0,0 @@ -# Markdown Style Guide - - - -**Table of Contents** - -- [Linting](#linting) -- [Links](#links) - - [Glossary](#glossary) -- [Internal (In-File) Links](#internal-in-file-links) - - - -## Linting - -Respect the [linting rules] (you can run the linter with `pnpm lint`). - -Notably: - -- lines should be < 120 characters long - - in practice, some of our files are justified at 100 characters, some at 120 - -[linting rules]: linting.md#markdown - -## Links - -In general: - -- Use link references preferentially. - - e.g. `[my text][link-ref]` and then on its own line `[link-ref]: https://mylink.com` - - e.g. `[my text]` and then on its own line: `[my text]: https://mylink.com` - - exceptions: where it fits neatly on a single line, in particular in lists of links -- Excepted for internal and glossary links (see below), add the link reference definition directly - after the paragraph where the link first appears. - -### Glossary - -- Use links to the [glossary] liberally. -- Include the references to all the glossary links at the top of the file, under the top-level - title. -- A glossary link reference should start with the `g-` prefix. This enables to see what links to the - glossary at a glance when editing the specification. - - e.g. `[g-block]: glossary.md#block` -- Example: [Rollup Node Specification source][rollup-node] - -[glossary]: ../glossary.md -[rollup-node]: https://raw.githubusercontent.com/ethereum-optimism/optimistic-specs/main/specs/rollup-node.md - -## Internal (In-File) Links - -If linking to another heading to the same file, add the link reference directly under that heading. -This makes it easier to keep the heading and the link in-sync, and signals that the heading is being -linked to from elsewhere. diff --git a/specs/meta/versioning.md b/specs/meta/versioning.md deleted file mode 100644 index 10e981e2db3a..000000000000 --- a/specs/meta/versioning.md +++ /dev/null @@ -1,42 +0,0 @@ -# Versioning - - - -**Table of Contents** - -- [Go modules](#go-modules) - - [versioning process](#versioning-process) -- [Typescript](#typescript) - - - -## Go modules - -Go modules that are currently versioned: - -```text -./op-service -./op-bindings -./op-batcher -./op-node -./op-proposer -./op-e2e -``` - -Go modules which are not yet versioned: - -```text -./indexer (changesets) -./op-exporter (changesets) -./proxyd (changesets) -``` - -### 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. diff --git a/specs/overview.md b/specs/overview.md deleted file mode 100644 index eac97a9c24de..000000000000 --- a/specs/overview.md +++ /dev/null @@ -1,199 +0,0 @@ -# Optimism Overview - - - -**Table of Contents** - -- [Architecture Design Goals](#architecture-design-goals) -- [Components](#components) - - [L1 Components](#l1-components) - - [L2 Components](#l2-components) - - [Transaction/Block Propagation](#transactionblock-propagation) -- [Key Interactions In Depth](#key-interactions-in-depth) - - [Deposits](#deposits) - - [Block Derivation](#block-derivation) - - [Overview](#overview) - - [Epochs and the Sequencing Window](#epochs-and-the-sequencing-window) - - [Block Derivation Loop](#block-derivation-loop) - - [Engine API](#engine-api) - - - -This document is a high-level technical overview of the Optimism protocol. It aims to explain how the protocol works in -an informal manner, and direct readers to other parts of the specification so that they may learn more. - -This document assumes you've read the [introduction](./introduction.md). - -## Architecture Design Goals - -- **Execution-Level EVM Equivalence:** The developer experience should be identical to L1 except where L2 introduces a -fundamental difference. - - No special compiler. - - No unexpected gas costs. - - Transaction traces work out-of-the-box. - - All existing Ethereum tooling works - all you have to do is change the chain ID. -- **Maximal compatibility with ETH1 nodes:** The implementation should minimize any differences with a vanilla Geth -node, and leverage as many existing L1 standards as possible. - - The execution engine/rollup node use the ETH2 Engine API to build the canonical L2 chain. - - The execution engine leverages Geth's existing mempool and sync implementations, including snap sync. -- **Minimize state and complexity:** - - Whenever possible, services contributing to the rollup infrastructure are stateless. - - Stateful services can recover to full operation from a fresh DB using the peer-to-peer network and on-chain sync -mechanisms. - - Running a replica is as simple as running a Geth node. - -## Components - -![Components](./assets/components.svg) - -### L1 Components - -- **OptimismPortal**: A feed of L2 transactions which originated as smart contract calls in the L1 state. - - The `OptimismPortal` contract emits `TransactionDeposited` events, which the rollup driver reads in order to process -deposits. - - Deposits are guaranteed to be reflected in the L2 state within the _sequencing window_. - - Beware that _transactions_ are deposited, not tokens. However deposited transactions are a key part of implementing -token deposits (tokens are locked on L1, then minted on L2 via a deposited transaction). -- **BatchInbox**: An L1 address to which the Batch Submitter submits transaction batches. - - Transaction batches include L2 transaction calldata, timestamps, and ordering information. - - The BatchInbox is a regular EOA address. This lets us pass on gas cost savings by not executing any EVM code. - -- **L2OutputOracle**: A smart contract that stores [L2 output roots](./glossary.md#l2-output) for use with withdrawals -and fault proofs. - -### L2 Components - -- **Rollup Node**: - - A standalone, stateless binary. - - Receives L2 transactions from users. - - Syncs and verifies rollup data on L1. - - Applies rollup-specific block production rules to synthesize blocks from L1. - - Appends blocks to the L2 chain using the Engine API. - - Handles L1 reorgs. - - Distributes unsubmitted blocks to other rollup nodes. -- **Execution Engine (EE)**: - - A vanilla Geth node with minor modifications to support Optimism. - - Maintains L2 state. - - Sync state to other L2 nodes for fast onboarding. - - Serves the Engine API to the rollup node. -- **Batch Submitter** - - A background process that submits [transaction batches](./glossary.md#sequencer-batch) to the `BatchInbox` address. -- **Output Submitter** - - A background process that submits L2 output commitments to the `L2OutputOracle`. - -### Transaction/Block Propagation - -**Spec links:** - -- [Execution Engine](./exec-engine.md) - -Since the EE uses Geth under the hood, Optimism uses Geth's built-in peer-to-peer network and transaction pool to -propagate transactions. The same network can also be used to propagate submitted blocks and support snap-sync. - -Unsubmitted blocks, however, are propagated using a separate peer-to-peer network of Rollup Nodes. This is optional, -however, and is provided as a convenience to lower latency for verifiers and their JSON-RPC clients. - -The below diagram illustrates how the sequencer and verifiers fit together: - -![Propagation](./assets/propagation.svg) - -## Key Interactions In Depth - -### Deposits - -**Spec links:** - -- [Deposits](./deposits.md) - -Optimism supports two types of deposits: user deposits, and L1 attributes deposits. To perform a user deposit, users -call the `depositTransaction` method on the `OptimismPortal` contract. This in turn emits `TransactionDeposited` events, -which the rollup node reads during block derivation. - -L1 attributes deposits are used to register L1 block attributes (number, timestamp, etc.) on L2 via a call to the L1 -Attributes Predeploy. They cannot be initiated by users, and are instead added to L2 blocks automatically by the rollup -node. - -Both deposit types are represented by a single custom EIP-2718 transaction type on L2. - -### Block Derivation - -#### Overview - -The rollup chain can be deterministically derived given an L1 Ethereum chain. The fact that the entire rollup chain can -be derived based on L1 blocks is _what makes Optimism a rollup_. This process can be represented as: - -```text -derive_rollup_chain(l1_blockchain) -> rollup_blockchain -``` - -Optimism's block derivation function is designed such that it: - -- Requires no state other than what is easily accessible using L1 and L2 execution engine APIs. -- Supports sequencers and sequencer consensus. -- Is resilient to sequencer censorship. - -#### Epochs and the Sequencing Window - -The rollup chain is subdivided into epochs. There is a 1:1 correspondence between L1 block numbers and epoch numbers. - -For L1 block number `n`, there is a corresponding rollup epoch `n` which can only be derived after a _sequencing window_ -worth of blocks has passed, i.e. after L1 block number `n + SEQUENCING_WINDOW_SIZE` is added to the L1 chain. - -Each epoch contains at least one block. Every block in the epoch contains an L1 info transaction which contains -contextual information about L1 such as the block hash and timestamp. The first block in the epoch also contains all -deposits initiated via the `OptimismPortal` contract on L1. All L2 blocks can also contain _sequenced transactions_, -i.e. transactions submitted directly to the sequencer. - -Whenever the sequencer creates a new L2 block for a given epoch, it must submit it to L1 as part of a _batch_, within -the epoch's sequencing window (i.e. the batch must land before L1 block `n + SEQUENCING_WINDOW_SIZE`). These batches are -(along with the `TransactionDeposited` L1 events) what allows the derivation of the L2 chain from the L1 chain. - -The sequencer does not need for a L2 block to be batch-submitted to L1 in order to build on top of it. In fact, batches -typically contain multiple L2 blocks worth of sequenced transaction. This is what enables -_fast transaction confirmations_ on the sequencer. - -Since transaction batches for a given epoch can be submitted anywhere within the sequencing window, verifiers must -search all blocks within the window for transaction batches. This protects against the uncertainty of transaction -inclusion of L1. This uncertainty is also why we need the sequencing window in the first place: otherwise the sequencer -could retroactively add blocks to an old epoch, and validators wouldn't know when they can finalize an epoch. - -The sequencing window also prevents censorship by the sequencer: deposits made on a given L1 block will be included in -the L2 chain at worst after `SEQUENCING_WINDOW_SIZE` L1 blocks have passed. - -The following diagram describes this relationship, and how L2 blocks are derived from L1 blocks (L1 info transactions -have been elided): - -![Epochs and Sequencing Windows](./assets/sequencer-block-gen.svg) - -#### Block Derivation Loop - -A sub-component of the rollup node called the _rollup driver_ is actually responsible for performing block derivation. -The rollup driver is essentially an infinite loop that runs the block derivation function. For each epoch, the block -derivation function performs the following steps: - -1. Downloads deposit and transaction batch data for each block in the sequencing window. -2. Converts the deposit and transaction batch data into payload attributes for the Engine API. -3. Submits the payload attributes to the Engine API, where they are converted into blocks and added to the canonical -chain. - -This process is then repeated with incrementing epochs until the tip of L1 is reached. - -### Engine API - -The rollup driver doesn't actually create blocks. Instead, it directs the execution engine to do so via the Engine API. -For each iteration of the block derivation loop described above, the rollup driver will craft a _payload attributes_ -object and send it to the execution engine. The execution engine will then convert the payload attributes object into a -block, and add it to the chain. The basic sequence the rollup driver is as follows: - -1. Call `engine_forkchoiceUpdatedV2` with the payload attributes object. We'll skip over the details of the fork choice -state parameter for now - just know that one of its fields is the L2 chain's `headBlockHash`, and that it is set to the -block hash of the tip of the L2 chain. The Engine API returns a payload ID. -2. Call `engine_getPayloadV2` with the payload ID returned in step 1. The engine API returns a payload object that -includes a block hash as one of its fields. -3. Call `engine_newPayloadV2` with the payload returned in step 2. -4. Call `engine_forkchoiceUpdatedV2` with the fork choice parameter's `headBlockHash` set to the block hash returned in -step 2. The tip of the L2 chain is now the block created in step 1. - -The swimlane diagram below visualizes the process: - -![Engine API](./assets/engine.svg) diff --git a/specs/predeploys.md b/specs/predeploys.md deleted file mode 100644 index f3942821c755..000000000000 --- a/specs/predeploys.md +++ /dev/null @@ -1,334 +0,0 @@ -# Predeploys - - - -**Table of Contents** - -- [Overview](#overview) -- [LegacyMessagePasser](#legacymessagepasser) -- [L2ToL1MessagePasser](#l2tol1messagepasser) -- [DeployerWhitelist](#deployerwhitelist) -- [LegacyERC20ETH](#legacyerc20eth) -- [WETH9](#weth9) -- [L2CrossDomainMessenger](#l2crossdomainmessenger) -- [L2StandardBridge](#l2standardbridge) -- [L1BlockNumber](#l1blocknumber) -- [GasPriceOracle](#gaspriceoracle) -- [L1Block](#l1block) -- [ProxyAdmin](#proxyadmin) -- [SequencerFeeVault](#sequencerfeevault) -- [OptimismMintableERC20Factory](#optimismmintableerc20factory) -- [OptimismMintableERC721Factory](#optimismmintableerc721factory) -- [BaseFeeVault](#basefeevault) -- [L1FeeVault](#l1feevault) -- [SchemaRegistry](#schemaregistry) -- [EAS](#eas) - - - -## Overview - -[Predeployed smart contracts](./glossary.md#predeployed-contract-predeploy) exist on Optimism -at predetermined addresses in the genesis state. They are similar to precompiles but instead run -directly in the EVM instead of running native code outside of the EVM. - -Predeploys are used instead of precompiles to make it easier for multiclient -implementations as well as allowing for more integration with hardhat/foundry -network forking. - -Predeploy addresses exist in 1 byte namespace `0x42000000000000000000000000000000000000xx`. -Proxies are set at each possible predeploy address except for the -`GovernanceToken` and the `ProxyAdmin`. - -The `LegacyERC20ETH` predeploy lives at a special address `0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000` -and there is no proxy deployed at that account. - -The following table includes each of the predeploys. The system version -indicates when the predeploy was introduced. The possible values are `Legacy` -or `Bedrock`. Deprecated contracts should not be used. - -| Name | Address | Introduced | Deprecated | Proxied | -| ----------------------------- | ------------------------------------------ | ---------- | ---------- |---------| -| LegacyMessagePasser | 0x4200000000000000000000000000000000000000 | Legacy | Yes | Yes | -| DeployerWhitelist | 0x4200000000000000000000000000000000000002 | Legacy | Yes | Yes | -| LegacyERC20ETH | 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000 | Legacy | Yes | No | -| WETH9 | 0x4200000000000000000000000000000000000006 | Legacy | No | No | -| L2CrossDomainMessenger | 0x4200000000000000000000000000000000000007 | Legacy | No | Yes | -| L2StandardBridge | 0x4200000000000000000000000000000000000010 | Legacy | No | Yes | -| SequencerFeeVault | 0x4200000000000000000000000000000000000011 | Legacy | No | Yes | -| OptimismMintableERC20Factory | 0x4200000000000000000000000000000000000012 | Legacy | No | Yes | -| L1BlockNumber | 0x4200000000000000000000000000000000000013 | Legacy | Yes | Yes | -| GasPriceOracle | 0x420000000000000000000000000000000000000F | Legacy | No | Yes | -| GovernanceToken | 0x4200000000000000000000000000000000000042 | Legacy | No | No | -| L1Block | 0x4200000000000000000000000000000000000015 | Bedrock | No | Yes | -| L2ToL1MessagePasser | 0x4200000000000000000000000000000000000016 | Bedrock | No | Yes | -| L2ERC721Bridge | 0x4200000000000000000000000000000000000014 | Legacy | No | Yes | -| OptimismMintableERC721Factory | 0x4200000000000000000000000000000000000017 | Bedrock | No | Yes | -| ProxyAdmin | 0x4200000000000000000000000000000000000018 | Bedrock | No | Yes | -| BaseFeeVault | 0x4200000000000000000000000000000000000019 | Bedrock | No | Yes | -| L1FeeVault | 0x420000000000000000000000000000000000001a | Bedrock | No | Yes | -| SchemaRegistry | 0x4200000000000000000000000000000000000020 | Bedrock | No | Yes | -| EAS | 0x4200000000000000000000000000000000000021 | Bedrock | No | Yes | - -## LegacyMessagePasser - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/legacy/LegacyMessagePasser.sol) - -Address: `0x4200000000000000000000000000000000000000` - -The `LegacyMessagePasser` contract stores commitments to withdrawal -transactions before the Bedrock upgrade. A merkle proof to a particular -storage slot that commits to the withdrawal transaction is used as part -of the withdrawing transaction on L1. The expected account that includes -the storage slot is hardcoded into the L1 logic. After the bedrock upgrade, -the `L2ToL1MessagePasser` is used instead. Finalizing withdrawals from this -contract will no longer be supported after the Bedrock and is only left -to allow for alternative bridges that may depend on it. This contract does -not forward calls to the `L2ToL1MessagePasser` and calling it is considered -a no-op in context of doing withdrawals through the `CrossDomainMessenger` -system. - -Any pending withdrawals that have not been finalized are migrated to the -`L2ToL1MessagePasser` as part of the upgrade so that they can still be -finalized. - -## L2ToL1MessagePasser - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol) - -Address: `0x4200000000000000000000000000000000000016` - -The `L2ToL1MessagePasser` stores commitments to withdrawal transactions. -When a user is submitting the withdrawing transaction on L1, they provide a -proof that the transaction that they withdrew on L2 is in the `sentMessages` -mapping of this contract. - -Any withdrawn ETH accumulates into this contract on L2 and can be -permissionlessly removed from the L2 supply by calling the `burn()` function. - -## DeployerWhitelist - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/legacy/DeployerWhitelist.sol) - -Address: `0x4200000000000000000000000000000000000002` - -The `DeployerWhitelist` is a predeploy that was used to provide additional safety -during the initial phases of Optimism. -It previously defined the accounts that are allowed to deploy contracts to the network. - -Arbitrary contract deployment was subsequently enabled and it is not possible to turn -off. In the legacy system, this contract was hooked into `CREATE` and -`CREATE2` to ensure that the deployer was allowlisted. - -In the Bedrock system, this contract will no longer be used as part of the -`CREATE` codepath. - -This contract is deprecated and its usage should be avoided. - -## LegacyERC20ETH - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/legacy/LegacyERC20ETH.sol) - -Address: `0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000` - -The `LegacyERC20ETH` predeploy represents all ether in the system before the -Bedrock upgrade. All ETH was represented as an ERC20 token and users could opt -into the ERC20 interface or the native ETH interface. - -The upgrade to Bedrock migrates all ether out of this contract and moves it to -its native representation. All of the stateful methods in this contract will -revert after the Bedrock upgrade. - -This contract is deprecated and its usage should be avoided. - -## WETH9 - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/vendor/WETH9.sol) - -Address: `0x4200000000000000000000000000000000000006` - -`WETH9` is the standard implementation of Wrapped Ether on Optimism. It is a -commonly used contract and is placed as a predeploy so that it is at a -deterministic address across Optimism based networks. - -## L2CrossDomainMessenger - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol) - -Address: `0x4200000000000000000000000000000000000007` - -The `L2CrossDomainMessenger` gives a higher level API for sending cross domain -messages compared to directly calling the `L2ToL1MessagePasser`. -It maintains a mapping of L1 messages that have been relayed to L2 -to prevent replay attacks and also allows for replayability if the L1 to L2 -transaction reverts on L2. - -Any calls to the `L1CrossDomainMessenger` on L1 are serialized such that they -go through the `L2CrossDomainMessenger` on L2. - -The `relayMessage` function executes a transaction from the remote domain while -the `sendMessage` function sends a transaction to be executed on the remote -domain through the remote domain's `relayMessage` function. - -## L2StandardBridge - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2StandardBridge.sol) - -Address: `0x4200000000000000000000000000000000000010` - -The `L2StandardBridge` is a higher level API built on top of the -`L2CrossDomainMessenger` that gives a standard interface for sending ETH or -ERC20 tokens across domains. - -To deposit a token from L1 to L2, the `L1StandardBridge` locks the token and -sends a cross domain message to the `L2StandardBridge` which then mints the -token to the specified account. - -To withdraw a token from L2 to L1, the user will burn the token on L2 and the -`L2StandardBridge` will send a message to the `L1StandardBridge` which will -unlock the underlying token and transfer it to the specified account. - -The `OptimismMintableERC20Factory` can be used to create an ERC20 token contract -on a remote domain that maps to an ERC20 token contract on the local domain -where tokens can be deposited to the remote domain. It deploys an -`OptimismMintableERC20` which has the interface that works with the -`StandardBridge`. - -This contract can also be deployed on L1 to allow for L2 native tokens to be -withdrawn to L1. - -## L1BlockNumber - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol) - -Address: `0x4200000000000000000000000000000000000013` - -The `L1BlockNumber` returns the last known L1 block number. This contract was -introduced in the legacy system and should be backwards compatible by calling -out to the `L1Block` contract under the hood. - -It is recommended to use the `L1Block` contract for getting information about -L1 on L2. - -## GasPriceOracle - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/GasPriceOracle.sol) - -Address: `0x420000000000000000000000000000000000000F` - -In the legacy system, the `GasPriceOracle` was a permissioned contract -that was pushed the L1 basefee and the L2 gas price by an offchain actor. -The offchain actor observes the L1 blockheaders to get the -L1 basefee as well as the gas usage on L2 to compute what the L2 gas price -should be based on a congestion control algorithm. - -After Bedrock, the `GasPriceOracle` is no longer a permissioned contract -and only exists to preserve the API for offchain gas estimation. The -function `getL1Fee(bytes)` accepts an unsigned RLP transaction and will return -the L1 portion of the fee. This fee pays for using L1 as a data availability -layer and should be added to the L2 portion of the fee, which pays for -execution, to compute the total transaction fee. - -The values used to compute the L2 portion of the fee are: - -- scalar -- overhead -- decimals - -After the Bedrock upgrade, these values are instead managed by the -`SystemConfig` contract on L2. The `scalar` and `overhead` values -are sent to the `L1Block` contract each block and the `decimals` value -has been hardcoded to 6. - -## L1Block - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L1Block.sol) - -Address: `0x4200000000000000000000000000000000000015` - -[l1-block-predeploy]: glossary.md#l1-attributes-predeployed-contract - -The [L1Block][l1-block-predeploy] was introduced in Bedrock and is responsible for -maintaining L1 context in L2. This allows for L1 state to be accessed in L2. - -## ProxyAdmin - -[ProxyAdmin](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/ProxyAdmin.sol) -Address: `0x4200000000000000000000000000000000000018` - -The `ProxyAdmin` is the owner of all of the proxy contracts set at the -predeploys. It is itself behind a proxy. The owner of the `ProxyAdmin` will -have the ability to upgrade any of the other predeploy contracts. - -## SequencerFeeVault - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol) - -Address: `0x4200000000000000000000000000000000000011` - -The `SequencerFeeVault` accumulates any transaction priority fee and is the value of -`block.coinbase`. -When enough fees accumulate in this account, they can be withdrawn to an immutable L1 address. - -To change the L1 address that fees are withdrawn to, the contract must be -upgraded by changing its proxy's implementation key. - -## OptimismMintableERC20Factory - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol) - -Address: `0x4200000000000000000000000000000000000012` - -The `OptimismMintableERC20Factory` is responsible for creating ERC20 contracts on L2 that can be -used for depositing native L1 tokens into. These ERC20 contracts can be created permisionlessly -and implement the interface required by the `StandardBridge` to just work with deposits and withdrawals. - -Each ERC20 contract that is created by the `OptimismMintableERC20Factory` allows for the `L2StandardBridge` to mint -and burn tokens, depending on if the user is depositing from L1 to L2 or withdrawaing from L2 to L1. - -## OptimismMintableERC721Factory - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol) - -Address: `0x4200000000000000000000000000000000000017` - -The `OptimismMintableERC721Factory` is responsible for creating ERC721 contracts on L2 that can be used for -depositing native L1 NFTs into. - -## BaseFeeVault - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/BaseFeeVault.sol) - -Address: `0x4200000000000000000000000000000000000019` - -The `BaseFeeVault` predeploy receives the basefees on L2. The basefee is not -burnt on L2 like it is on L1. Once the contract has received a certain amount -of fees, the ETH can be withdrawn to an immutable address on -L1. - -## L1FeeVault - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L1FeeVault.sol) - -Address: `0x420000000000000000000000000000000000001a` - -The `L1FeeVault` predeploy receives the L1 portion of the transaction fees. -Once the contract has received a certain amount of fees, the ETH can be -withdrawn to an immutable address on L1. - -## SchemaRegistry - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/EAS/SchemaRegistry.sol) - -Address: `0x4200000000000000000000000000000000000020` - -The `SchemaRegistry` predeploy implements the global attestation schemas for the `Ethereum Attestation Service` -protocol. - -## EAS - -[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/EAS/EAS.sol) - -Address: `0x4200000000000000000000000000000000000021` - -The `EAS` predeploy implements the `Ethereum Attestation Service` protocol. diff --git a/specs/proposals.md b/specs/proposals.md deleted file mode 100644 index 35de72008e53..000000000000 --- a/specs/proposals.md +++ /dev/null @@ -1,176 +0,0 @@ -# L2 Output Root Proposals Specification - - - -[g-rollup-node]: glossary.md#rollup-node -[g-mpt]: glossary.md#merkle-patricia-trie - - - -**Table of Contents** - -- [Proposing L2 Output Commitments](#proposing-l2-output-commitments) - - [L2OutputOracle v1.0.0](#l2outputoracle-v100) -- [L2 Output Commitment Construction](#l2-output-commitment-construction) -- [L2 Output Oracle Smart Contract](#l2-output-oracle-smart-contract) - - [Configuration](#configuration) -- [Security Considerations](#security-considerations) - - [L1 Reorgs](#l1-reorgs) - - - -After processing one or more blocks the outputs will need to be synchronized with the settlement layer (L1) -for trustless execution of L2-to-L1 messaging, such as withdrawals. -These output proposals act as the bridge's view into the L2 state. -Actors called "Proposers" submit the output roots to the settlement layer (L1) and can be contested with a fault proof, -with a bond at stake if the proof is wrong. The [op-proposer](../op-proposer/) in one such implementation of a proposer. - -_Note_: Fault proofs on Optimism are not fully specified at this time. Although fault proof -construction and verification [is implemented in Cannon][cannon], -the fault proof game specification and integration of a output-root challenger into the [rollup-node][g-rollup-node] -are part of later specification milestones. - -[cannon]: https://github.com/ethereum-optimism/cannon - -## Proposing L2 Output Commitments - -The proposer's role is to construct and submit output roots, which are commitments to the L2's state, -to the `L2OutputOracle` contract on L1 (the settlement layer). To do this, the proposer periodically -queries the [rollup node](./rollup-node.md) for the latest output root derived from the latest -[finalized](rollup-node.md#finalization-guarantees) L1 block. It then takes the output root and -submits it to the `L2OutputOracle` contract on the settlement layer (L1). - -### L2OutputOracle v1.0.0 - -The submission of output proposals is permissioned to a single account. It is expected that this -account continues to submit output proposals over time to ensure that user withdrawals do not halt. - -The [L2 output proposer](../op-proposer) is expected to submit output roots on a deterministic -interval based on the configured `SUBMISSION_INTERVAL` in the `L2OutputOracle`. The larger -the `SUBMISSION_INTERVAL`, the less often L1 transactions need to be sent to the `L2OutputOracle` -contract, but L2 users will need to wait a bit longer for an output root to be included in L1 (the settlement layer) -that includes their intention to withdrawal from the system. - -The honest `op-proposer` algorithm assumes a connection to the `L2OutputOracle` contract to know -the L2 block number that corresponds to the next output proposal that must be submitted. It also -assumes a connection to an `op-node` to be able to query the `optimism_syncStatus` RPC endpoint. - -```python -import time - -while True: - next_checkpoint_block = L2OutputOracle.nextBlockNumber() - rollup_status = op_node_client.sync_status() - if rollup_status.finalized_l2.number >= next_checkpoint_block: - output = op_node_client.output_at_block(next_checkpoint_block) - tx = send_transaction(output) - time.sleep(poll_interval) -``` - -A `CHALLENGER` account can delete multiple output roots by calling the `deleteL2Outputs()` function -and specifying the index of the first output to delete, this will also delete all subsequent outputs. - -## L2 Output Commitment Construction - -The `output_root` is a 32 byte string, which is derived based on the a versioned scheme: - -```pseudocode -output_root = keccak256(version_byte || payload) -``` - -where: - -1. `version_byte` (`bytes32`) a simple version string which increments anytime the construction of the output root - is changed. - -2. `payload` (`bytes`) is a byte string of arbitrary length. - -In the initial version of the output commitment construction, the version is `bytes32(0)`, and the payload is defined -as: - -```pseudocode -payload = state_root || withdrawal_storage_root || latest_block_hash -``` - -where: - -1. The `latest_block_hash` (`bytes32`) is the block hash for the latest L2 block. - -1. The `state_root` (`bytes32`) is the Merkle-Patricia-Trie ([MPT][g-mpt]) root of all execution-layer accounts. - This value is frequently used and thus elevated closer to the L2 output root, which removes the need to prove its - inclusion in the pre-image of the `latest_block_hash`. This reduces the merkle proof depth and cost of accessing the - L2 state root on L1. - -1. The `withdrawal_storage_root` (`bytes32`) elevates the Merkle-Patricia-Trie ([MPT][g-mpt]) root of the [Message - Passer contract](./withdrawals.md#the-l2tol1messagepasser-contract) storage. Instead of making an MPT proof for a - withdrawal against the state root (proving first the storage root of the L2toL1MessagePasser against the state root, - then the withdrawal against that storage root), we can prove against the L2toL1MessagePasser's storage root directly, - thus reducing the verification cost of withdrawals on L1. - -## L2 Output Oracle Smart Contract - -L2 blocks are produced at a constant rate of `L2_BLOCK_TIME` (2 seconds). -A new L2 output MUST be appended to the chain once per `SUBMISSION_INTERVAL` which is based on a number of blocks. -The exact number is yet to be determined, and will depend on the design of the fault proving game. - -The L2 Output Oracle contract implements the following interface: - -```solidity -/** - * @notice The number of the first L2 block recorded in this contract. - */ -uint256 public startingBlockNumber; - -/** - * @notice The timestamp of the first L2 block recorded in this contract. - */ -uint256 public startingTimestamp; - -/** - * @notice Accepts an L2 outputRoot and the timestamp of the corresponding L2 block. The - * timestamp must be equal to the current value returned by `nextTimestamp()` in order to be - * accepted. - * This function may only be called by the Proposer. - * - * @param _l2Output The L2 output of the checkpoint block. - * @param _l2BlockNumber The L2 block number that resulted in _l2Output. - * @param _l1Blockhash A block hash which must be included in the current chain. - * @param _l1BlockNumber The block number with the specified block hash. -*/ - function proposeL2Output( - bytes32 _l2Output, - uint256 _l2BlockNumber, - bytes32 _l1Blockhash, - uint256 _l1BlockNumber - ) - -/** - * @notice Deletes all output proposals after and including the proposal that corresponds to - * the given output index. Only the challenger address can delete outputs. - * - * @param _l2OutputIndex Index of the first L2 output to be deleted. All outputs after this - * output will also be deleted. - */ -function deleteL2Outputs(uint256 _l2OutputIndex) external - -/** - * @notice Computes the block number of the next L2 block that needs to be checkpointed. - */ -function nextBlockNumber() public view returns (uint256) -``` - -### Configuration - -The `startingBlockNumber` must be at least the number of the first Bedrock block. -The `startingTimestamp` MUST be the same as the timestamp of the start block. - -The first `outputRoot` proposed will thus be at height `startingBlockNumber + SUBMISSION_INTERVAL` - -## Security Considerations - -### L1 Reorgs - -If the L1 has a reorg after an output has been generated and submitted, the L2 state and correct output may change -leading to a faulty proposal. This is mitigated against by allowing the proposer to submit an -L1 block number and hash to the Output Oracle when appending a new output; in the event of a reorg, the block hash -will not match that of the block with that number and the call will revert. diff --git a/specs/rollup-node-p2p.md b/specs/rollup-node-p2p.md deleted file mode 100644 index 2733d4122046..000000000000 --- a/specs/rollup-node-p2p.md +++ /dev/null @@ -1,420 +0,0 @@ -# Rollup-node P2P interface - -The [rollup node](./rollup-node.md) has an optional peer-to-peer (P2P) network service to improve the latency between -the view of sequencers and the rest of the network by bypassing the L1 in the happy case, -without relying on a single centralized endpoint. - -This also enables faster historical sync to be bootstrapped by providing block headers to sync towards, -and only having to compare the L2 chain inputs to the L1 data as compared to processing everything one block at a time. - -The rollup node will *always* prioritize L1 and reorganize to match the canonical chain. -The L2 data retrieved via the P2P interface is strictly a speculative extension, also known as the "unsafe" chain, -to improve the happy case performance. - -This also means that P2P behavior is a soft-rule: nodes keep each other in check with scoring and eventual banning -of malicious peers by identity or IP. Any behavior on the P2P layer does not affect the rollup security, at worst nodes -rely on higher-latency data from L1 to serve. - -In summary, the P2P stack looks like: - -- Discovery to find peers: [Discv5][discv5] -- Connections, peering, transport security, multiplexing, gossip: [LibP2P][libp2p] -- Application-layer publishing and validation of gossiped messages like L2 blocks. - -This document only specifies the composition and configuration of these network libraries. -These components have their own standards, implementations in Go/Rust/Java/Nim/JS/more, -and are adopted by several other blockchains, most notably the [L1 consensus layer (Eth2)][eth2-p2p]. - - - -**Table of Contents** - -- [P2P configuration](#p2p-configuration) - - [Identification](#identification) - - [Discv5](#discv5) - - [Structure](#structure) - - [LibP2P](#libp2p) - - [Transport](#transport) - - [Dialing](#dialing) - - [NAT](#nat) - - [Peer management](#peer-management) - - [Transport security](#transport-security) - - [Protocol negotiation](#protocol-negotiation) - - [Identify](#identify) - - [Ping](#ping) - - [Multiplexing](#multiplexing) - - [GossipSub](#gossipsub) - - [Content-based message identification](#content-based-message-identification) - - [Message compression and limits](#message-compression-and-limits) - - [Message ID computation](#message-id-computation) - - [Heartbeat and parameters](#heartbeat-and-parameters) - - [Topic configuration](#topic-configuration) - - [Topic validation](#topic-validation) -- [Gossip Topics](#gossip-topics) - - [`blocksv1`](#blocksv1) - - [`blocksv2`](#blocksv2) - - [Block encoding](#block-encoding) - - [Block signatures](#block-signatures) - - [Block validation](#block-validation) - - [Block processing](#block-processing) - - [Block topic scoring parameters](#block-topic-scoring-parameters) -- [Req-Resp](#req-resp) - - [`payload_by_number`](#payload_by_number) - - - -## P2P configuration - -### Identification - -Nodes have a **separate** network- and consensus-identity. -The network identity is a `secp256k1` key, used for both discovery and active LibP2P connections. - -Common representations of network identity: - -- `PeerID`: a LibP2P specific ID derived from the pubkey (through protobuf encoding, typing and hashing) -- `NodeID`: a Discv5 specific ID derived from the pubkey (through hashing, used in the DHT) -- `Multi-address`: an unsigned address, containing: IP, TCP port, PeerID -- `ENR`: a signed record used for discovery, containing: IP, TCP port, UDP port, signature (pubkey can be derived) - and L2 network identification. Generally encoded in base64. - -### Discv5 - -#### Structure - -The Ethereum Node Record (ENR) for an Optimism rollup node must contain the following values, identified by unique keys: - -- An IPv4 address (`ip` field) and/or IPv6 address (`ip6` field). -- A TCP port (`tcp` field) representing the local libp2p listening port. -- A UDP port (`udp` field) representing the local discv5 listening port. -- An OpStack (`opstack` field) L2 network identifier - -The `opstack` value is encoded as a single RLP `bytes` value, the concatenation of: - -- chain ID (`unsigned varint`) -- fork ID (`unsigned varint`) - -Note that DiscV5 is a shared DHT (Distributed Hash Table): the L1 consensus and execution nodes, -as well as testnet nodes, and even external IOT nodes, all communicate records in this large common DHT. -This makes it more difficult to censor the discovery of node records. - -The discovery process in Optimism is a pipeline of node records: - -1. Fill the table with `FINDNODES` if necessary (Performed by Discv5 library) -2. Pull additional records with searches to random Node IDs if necessary - (e.g. iterate [`RandomNodes()`][discv5-random-nodes] in Go implementation) -3. Pull records from the DiscV5 module when looking for peers -4. Check if the record contains the `opstack` entry, verify it matches the chain ID and current or future fork number -5. If not already connected, and not recently disconnected or put on deny-list, attempt to dial. - -### LibP2P - -#### Transport - -TCP transport. Additional transports are supported by LibP2P, but not required. - -#### Dialing - -Nodes should be publicly dialable, not rely on relay extensions, and able to dial both IPv4 and IPv6. - -#### NAT - -The listening endpoint must be publicly facing, but may be configured behind a NAT. -LibP2P will use PMP / UPNP based techniques to track the external IP of the node. -It is recommended to disable the above if the external IP is static and configured manually. - -#### Peer management - -The default is to maintain a peer count with a tide-system based on active peer count: - -- At "low tide" the node starts to actively search for additional peer connections. -- At "high tide" the node starts to prune active connections, - except those that are marked as trusted or have a grace period. - -Peers will have a grace period for a configurable amount of time after joining. -In emergency, when memory runs low, the node should start pruning more aggressively. - -Peer records can be persisted to disk to quickly reconnect with known peers after restarting the rollup node. - -The discovery process feeds the peerstore with peer records to connect to, tagged with a time-to-live (TTL). -The current P2P processes do not require selective topic-specific peer connections, -other than filtering for the basic network participation requirement. - -Peers may be banned if their performance score is too low, or if an objectively malicious action was detected. - -Banned peers will be persisted to the same data-store as the peerstore records. - -TODO: the connection gater does currently not gate by IP address on the dial Accept-callback. - -#### Transport security - -[Libp2p-noise][libp2p-noise], `XX` handshake, with the `secp256k1` P2P identity, as popularized in Eth2. -The TLS option is available as well, but `noise` should be prioritized in negotiation. - -#### Protocol negotiation - -[Multistream-select 1.0][multistream-select] (`/multistream/1.0.0`) is an interactive protocol -used to negotiate sub-protocols supported in LibP2P peers. Multistream-select 2.0 may be used in the future. - -#### Identify - -LibP2P offers a minimal identification module to share client version and programming language. -This is optional and can be disabled for enhanced privacy. -It also includes the same protocol negotiation information, which can speed up initial connections. - -#### Ping - -LibP2P includes a simple ping protocol to track latency between connections. -This should be enabled to help provide insight into the network health. - -#### Multiplexing - -For async communication over different channels over the same connection, multiplexing is used. -[mplex][mplex] (`/mplex/6.7.0`) is required, and [yamux][yamux] (`/yamux/1.0.0`) is recommended but optional - -#### GossipSub - -[GossipSub 1.1][gossipsub] (`/meshsub/1.1.0`, i.e. with peer-scoring extension) is a pubsub protocol for mesh-networks, -deployed on L1 consensus (Eth2) and other protocols such as Filecoin, offering lots of customization options. - -##### Content-based message identification - -Messages are deduplicated, and filtered through application-layer signature verification. -Thus origin-stamping is disabled and published messages must only contain application data, -enforced through a [`StrictNoSign` Signature Policy][signature-policy] - -This provides greater privacy, and allows sequencers (consensus identity) to maintain -multiple network identities for redundancy. - -##### Message compression and limits - -The application contents are compressed with [snappy][snappy] single-block-compression -(as opposed to frame-compression), and constrained to 10 MiB. - -##### Message ID computation - -[Same as L1][l1-message-id], with recognition of compression: - -- If `message.data` has a valid snappy decompression, set `message-id` to the first 20 bytes of the `SHA256` hash of - the concatenation of `MESSAGE_DOMAIN_VALID_SNAPPY` with the snappy decompressed message data, - i.e. `SHA256(MESSAGE_DOMAIN_VALID_SNAPPY + snappy_decompress(message.data))[:20]`. -- Otherwise, set `message-id` to the first 20 bytes of the `SHA256` hash of - the concatenation of `MESSAGE_DOMAIN_INVALID_SNAPPY` with the raw message data, - i.e. `SHA256(MESSAGE_DOMAIN_INVALID_SNAPPY + message.data)[:20]`. - -#### Heartbeat and parameters - -GossipSub [parameters][gossip-parameters]: - -- `D` (topic stable mesh target count): 8 -- `D_low` (topic stable mesh low watermark): 6 -- `D_high` (topic stable mesh high watermark): 12 -- `D_lazy` (gossip target): 6 -- `heartbeat_interval` (interval of heartbeat, in seconds): 0.5 -- `fanout_ttl` (ttl for fanout maps for topics we are not subscribed to but have published to, in seconds): 24 -- `mcache_len` (number of windows to retain full messages in cache for `IWANT` responses): 12 -- `mcache_gossip` (number of windows to gossip about): 3 -- `seen_ttl` (number of heartbeat intervals to retain message IDs): 130 (= 65 seconds) - -Notable differences from L1 consensus (Eth2): - -- `seen_ttl` does not need to cover a full L1 epoch (6.4 minutes), but rather just a small window covering latest blocks -- `fanout_ttl`: adjusted to lower than `seen_ttl` -- `mcache_len`: a larger number of heartbeats can be retained since the gossip is much less noisy. -- `heartbeat_interval`: faster interval to reduce latency, bandwidth should still be reasonable since - there are far fewer messages to gossip about each interval than on L1 which uses an interval of 0.7 seconds. - -#### Topic configuration - -Topics have string identifiers and are communicated with messages and subscriptions. -`/optimism/chain_id/hardfork_version/Name` - -- `chain_id`: replace with decimal representation of chain ID -- `hardfork_version`: replace with decimal representation of hardfork, starting at `0` -- `Name`: topic application-name - -Note that the topic encoding depends on the topic, unlike L1, -since there are less topics, and all are snappy-compressed. - -#### Topic validation - -To ensure only valid messages are relayed, and malicious peers get scored based on application behavior, -an [extended validator][extended-validator] checks the message before it is relayed or processed. -The extended validator emits one of the following validation signals: - -- `ACCEPT` valid, relayed to other peers and passed to local topic subscriber -- `IGNORE` scored like inactivity, message is dropped and not processed -- `REJECT` score penalties, message is dropped - -## Gossip Topics - -There are two topics for distributing blocks to other nodes faster than proxying through L1 would. These are: - -### `blocksv1` - -Pre-Canyon/Shanghai blocks are broadcast on `/optimism//0/blocks`. - -### `blocksv2` - -Post-Canyon/Shanghai blocks are broadcast on `/optimism//1/blocks`. - -#### Block encoding - -A block is structured as the concatenation of: - -- `signature`: A `secp256k1` signature, always 65 bytes, `r (uint256), s (uint256), y_parity (uint8)` -- `payload`: A SSZ-encoded `ExecutionPayload`, always the remaining bytes. - -The topic uses Snappy block-compression (i.e. no snappy frames): -the above needs to be compressed after encoding, and decompressed before decoding. - -#### Block signatures - -The `signature` is a `secp256k1` signature, and signs over a message: -`keccak256(domain ++ chain_id ++ payload_hash)`, where: - -- `domain` is 32 bytes, reserved for message types and versioning info. All zero for this signature. -- `chain_id` is a big-endian encoded `uint256`. -- `payload_hash` is `keccak256(payload)`, where `payload` is the SSZ-encoded `ExecutionPayload` - -The `secp256k1` signature must have `y_parity = 1 or 0`, the `chain_id` is already signed over. - -#### Block validation - -An [extended-validator] checks the incoming messages as follows, in order of operation: - -- `[REJECT]` if the compression is not valid -- `[REJECT]` if the block encoding is not valid -- `[REJECT]` if the `payload.timestamp` is older than 60 seconds in the past - (graceful boundary for worst-case propagation and clock skew) -- `[REJECT]` if the `payload.timestamp` is more than 5 seconds into the future -- `[REJECT]` if the `block_hash` in the `payload` is not valid -- `[REJECT]` if the block is on the V1 topic and has withdrawals -- `[REJECT]` if the block is on the V2 topic and does not have withdrawals -- `[REJECT]` if the block is on the V2 topic and has a non-zero amount of withdrawals -- `[REJECT]` if more than 5 different blocks have been seen with the same block height -- `[IGNORE]` if the block has already been seen -- `[REJECT]` if the signature by the sequencer is not valid -- Mark the block as seen for the given block height - -The block is signed by the corresponding sequencer, to filter malicious messages. -The sequencer model is singular but may change to multiple sequencers in the future. -A default sequencer pubkey is distributed with rollup nodes and should be configurable. - -Note that blocks that a block may still be propagated even if the L1 already confirmed a different block. -The local L1 view of the node may be wrong, and the time and signature validation will prevent spam. -Hence, calling into the execution engine with a block lookup every propagation step is not worth the added delay. - -##### Block processing - -A node may apply the block to their local engine ahead of L1 availability, if it ensures that: - -- The application of the block is reversible, in case of a conflict with delayed L1 information -- The subsequent forkchoice-update ensures this block is recognized as "unsafe" - (see [`engine_forkchoiceUpdatedV2`](./exec-engine.md#engine_forkchoiceupdatedv2)) - -##### Block topic scoring parameters - -TODO: GossipSub per-topic scoring to fine-tune incentives for ideal propagation delay and bandwidth usage. - -## Req-Resp - -The op-node implements a similar request-response encoding for its sync protocols as the L1 ethereum Beacon-Chain. -See [L1 P2P-interface req-resp specification][eth2-p2p-reqresp] and [Altair P2P update][eth2-p2p-altair-reqresp]. - -However, the protocol is simplified, to avoid several issues seen in L1: - -- Error strings in responses, if there is any alternative response, - should not need to be compressed or have an artificial global length limit. -- Payload lengths should be fixed-length: byte-by-byte uvarint reading from the underlying stream is undesired. -- `` are relaxed to encode a `uint32`, rather than a beacon-chain `ForkDigest`. -- Payload-encoding may change per hardfork, so is not part of the protocol-ID. -- Usage of response-chunks is specific to the req-resp method: most basic req-resp does not need chunked responses. -- Compression is encouraged to be part of the payload-encoding, specific to the req-resp method, where necessary: - pings and such do not need streaming frame compression etc. - -And the protocol ID format follows the same scheme as L1, -except the trailing encoding schema part, which is now message-specific: - -```text -/ProtocolPrefix/MessageName/SchemaVersion/ -``` - -The req-resp protocols served by the op-node all have `/ProtocolPrefix` set to `/opstack/req`. - -Individual methods may include the chain ID as part of the `/MessageName` segment, -so it's immediately clear which chain the method applies to, if the communication is chain-specific. -Other methods may include chain-information in the request and/or response data, -such as the `ForkDigest` `` in L1 beacon chain req-resp protocols. - -Each segment starts with a `/`, and may contain multiple `/`, and the final protocol ID is suffixed with a `/`. - -### `payload_by_number` - -This is an optional chain syncing method, to request/serve execution payloads by number. -This serves as a method to fill gaps upon missed gossip, and sync short to medium ranges of unsafe L2 blocks. - -Protocol ID: `/opstack/req/payload_by_number//0/` - -- `/MessageName` is `/block_by_number/` where `` is set to the op-node L2 chain ID. -- `/SchemaVersion` is `/0` - -Request format: ``: a little-endian `uint64` - the block number to request. - -Response format: ` = ` - -- `` is a byte code describing the result. - - `0` on success, `` should follow. - - `1` if valid request, but unavailable payload. - - `2` if invalid request - - `3+` if other error - - The `>= 128` range is reserved for future use. -- `` is a little-endian `uint32`, identifying the type of `ExecutionPayload` (fork-specific) -- `` is an encoded block, read till stream EOF. - -The input of `` should be limited, as well as any generated decompressed output, -to avoid unexpected resource usage or zip-bomb type attacks. -A 10 MB limit is recommended, to ensure all blocks may be synced. -Implementations may opt for a different limit, since this sync method is optional. - -`` list: - -- `0`: SSZ-encoded `ExecutionPayload`, with Snappy framing compression, - matching the `ExecutionPayload` SSZ definition of the L1 Merge, L2 Bedrock and L2 Regolith versions. -- Other versions may be listed here with future network upgrades, such as the L1 Shanghai upgrade. - -The request is by block-number, enabling parallel fetching of a chain across many peers. - -A `res = 0` response should be verified to: - -- Have a block-number matching the requested block number. -- Have a consistent `blockhash` w.r.t. the other block contents. -- Build towards a known canonical block. - - This can be verified by checking if the parent-hash of a previous trusted canonical block matches - that of the verified hash of the retrieved block. - - For unsafe blocks this may be relaxed to verification against the parent-hash of any previously trusted block: - - The gossip validation process limits the amount of blocks that may be trusted to sync towards. - - The unsafe blocks should be queued for processing, the latest received L2 unsafe blocks should always - override any previous chain, until the final L2 chain can be reproduced from L1 data. - -A `res > 0` response code should not be accepted. The result code is helpful for debugging, -but the client should regard any error like any any other unanswered request, as the responding peer cannot be trusted. - ----- - -[libp2p]: https://libp2p.io/ -[discv5]: https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md -[discv5-random-nodes]: https://pkg.go.dev/github.com/ethereum/go-ethereum@v1.10.12/p2p/discover#UDPv5.RandomNodes -[eth2-p2p]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md -[eth2-p2p-reqresp]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-reqresp-domain -[eth2-p2p-altair-reqresp]: https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/p2p-interface.md#the-reqresp-domain -[libp2p-noise]: https://github.com/libp2p/specs/tree/master/noise -[multistream-select]: https://github.com/multiformats/multistream-select/ -[mplex]: https://github.com/libp2p/specs/tree/master/mplex -[yamux]: https://github.com/hashicorp/yamux/blob/master/spec.md -[gossipsub]: https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md -[signature-policy]: https://github.com/libp2p/specs/blob/master/pubsub/README.md#signature-policy-options -[snappy]: https://github.com/google/snappy -[l1-message-id]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#topics-and-messages -[gossip-parameters]: https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.0.md#parameters -[extended-validator]: https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#extended-validators diff --git a/specs/rollup-node.md b/specs/rollup-node.md deleted file mode 100644 index 9c79bd2d953e..000000000000 --- a/specs/rollup-node.md +++ /dev/null @@ -1,92 +0,0 @@ -# Rollup Node Specification - - -[g-rollup-node]: glossary.md#rollup-node -[g-derivation]: glossary.md#L2-chain-derivation -[g-payload-attr]: glossary.md#payload-attributes -[g-block]: glossary.md#block -[g-exec-engine]: glossary.md#execution-engine -[g-reorg]: glossary.md#re-organization -[g-rollup-driver]: glossary.md#rollup-driver -[g-receipts]: glossary.md#receipt - -The [rollup node][g-rollup-node] is the component responsible for [deriving the L2 chain][g-derivation] from L1 blocks -(and their associated [receipts][g-receipts]). - -The part of the rollup node that derives the L2 chain is called the [rollup driver][g-rollup-driver]. This document is -currently only concerned with the specification of the rollup driver. - - - -**Table of Contents** - -- [Driver](#driver) - - [Derivation](#derivation) -- [L2 Output RPC method](#l2-output-rpc-method) - - [Output Method API](#output-method-api) -- [Protocol Version tracking](#protocol-version-tracking) - - - -## Driver - -The task of the [driver][g-rollup-driver] in the [rollup node][g-rollup-node] -is to manage the [derivation][g-derivation] process: - -- Keep track of L1 head block -- Keep track of the L2 chain sync progress -- Iterate over the derivation steps as new inputs become available - -### Derivation - -This process happens in three steps: - -1. Select inputs from the L1 chain, on top of the last L2 block: - a list of blocks, with transactions and associated data and receipts. -2. Read L1 information, deposits, and sequencing batches in order to generate [payload attributes][g-payload-attr] - (essentially [a block without output properties][g-block]). -3. Pass the payload attributes to the [execution engine][g-exec-engine], so that the L2 block (including [output block - properties][g-block]) may be computed. - -While this process is conceptually a pure function from the L1 chain to the L2 chain, it is in practice incremental. The -L2 chain is extended whenever new L1 blocks are added to the L1 chain. Similarly, the L2 chain re-organizes whenever the -L1 chain [re-organizes][g-reorg]. - -For a complete specification of the L2 block derivation, refer to the [L2 block derivation document](./derivation.md). - -## L2 Output RPC method - -The Rollup node has its own RPC method, `optimism_outputAtBlock` which returns a 32 -byte hash corresponding to the [L2 output root](./proposals.md#l2-output-commitment-construction). - -[SSZ]: https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md - -### Output Method API - -The input and return types here are as defined by the [engine API specs][engine-structures]). - -[engine-structures]: https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#structures - -- method: `optimism_outputAtBlock` -- params: - 1. `blockNumber`: `QUANTITY`, 64 bits - L2 integer block number. -- returns: - 1. `version`: `DATA`, 32 Bytes - the output root version number, beginning with 0. - 1. `l2OutputRoot`: `DATA`, 32 Bytes - the output root. - -## Protocol Version tracking - -The rollup-node should monitor the recommended and required protocol version by monitoring -the Protocol Version contract on L1, as specified in the [Superchain Version Signaling specifications]. - -[Superchain Version Signaling specifications]: ./superchain-upgrades.md#superchain-version-signaling - -This can be implemented through polling in the [Driver](#driver) loop. -After polling the Protocol Version, the rollup node SHOULD communicate it with the execution-engine through an -[`engine_signalSuperchainV1`](./exec-engine.md#enginesignalsuperchainv1) call. - -The rollup node SHOULD warn the user when the recommended version is newer than -the current version supported by the rollup node. - -The rollup node SHOULD take safety precautions if it does not meet the required protocol version. -This may include halting the engine, with consent of the rollup node operator. diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md deleted file mode 100644 index 25068268372b..000000000000 --- a/specs/safe-liveness-checking.md +++ /dev/null @@ -1,162 +0,0 @@ -# Safe Liveness Checking - - - -**Table of Contents** - -- [Liveness checking Mechanism](#liveness-checking-mechanism) -- [Liveness checking methodology](#liveness-checking-methodology) - - [The liveness guard](#the-liveness-guard) - - [The liveness module](#the-liveness-module) - - [Owner removal call flow](#owner-removal-call-flow) - - [Shutdown](#shutdown) - - [Security Properties](#security-properties) - - [Interdependency between the guard and module](#interdependency-between-the-guard-and-module) - - [Deploying the liveness checking system](#deploying-the-liveness-checking-system) - - [Modify the liveness checking system](#modify-the-liveness-checking-system) - - [Replacing the module](#replacing-the-module) - - [Replacing the guard](#replacing-the-guard) - - - -## Liveness checking Mechanism - -The Security Security Council uses a specially extended Safe multisig contract to ensure that -any loss of access to a signer's keys is identified and addressed within a predictable period of -time. - -This mechanism is intended only to be used to remove signers who have lost access to their keys, or -are otherwise inactive. It is not intended to be used to remove signers who are acting in bad faith, -or any other subjective criteria, such cases should be addressed by governance, and the removal -handled via the standard Safe ownership management functionality. - -## Liveness checking methodology - -This is achieved using two types of contracts which the Safe contract has built-in support for: - -1. **Guard contracts:** can execute pre- and post- transaction checks. -1. **Module contracts:** a contract which is added to the Safe by the signers, and thenceforth is - authorized to execute transactions via the Safe. This means the module must properly implement - auth conditions internally. - -### The liveness guard - -For implementing liveness checks a `LivenessGuard` is created which receives the signatures from -each executed transaction, and tracks the latest time at which a transaction was signed by each -signer. This time is made publicly available by calling a `lastLive(address)(Timestamp)` method. - -Signers may also call the contract's `showLiveness()()` method directly in order to prove liveness. - -### The liveness module - -A `LivenessModule` is also created which does the following: - -1. Has a function `removeOwners()` that anyone may call to specify one or more owners to be removed from the - Safe. -1. The Module would then check the `LivenessGuard.lastLive()` to determine if the signer is - eligible for removal. -1. If so, it will call the Safe's `removeSigner()` to remove the non-live signer, and if necessary - reduce the threshold. -1. When a member is removed, the signing parameters are modified such that `M/N` is the lowest ratio - which remains greater than or equal to 75%. Using integer math, this can be expressed as `M = (N * 75 + 99) / 100`. - -### Owner removal call flow - -The following diagram illustrates the flow for removing a single owner. The `verifyFinalState` -box indicates calls to the Safe which ensure the final state is valid. - -```mermaid -sequenceDiagram - participant User - participant LivenessModule - participant LivenessGuard - participant Safe - User->>LivenessModule: removeOwners([previousOwner], [owner]) - LivenessModule->>LivenessGuard: lastLive(owner) - LivenessModule->>Safe: getOwners() - LivenessModule->>Safe: removeOwner(previousOwner, owner) - - alt verifyFinalState - LivenessModule->>Safe: getOwners() - LivenessModule->>Safe: getThreshold() - LivenessModule->>Safe: getGuard() - end -``` - -### Shutdown - -In the unlikely event that the signer set (`N`) is reduced below the allowed threshold, then (and only then) is a - shutdown mechanism activated which removes the existing signers, and hands control of the - multisig over to a predetermined entity. - -### Security Properties - -The following security properties must be upheld: - -1. Signatures are assigned to the correct signer. -1. Non-signers are unable to create a record of having signed. -1. A signer cannot be censored or griefed such that their signing is not recorded. -1. Signers may demonstrate liveness either by signing a transaction or by calling directly to the - guard. -1. The module only removes a signer if they have demonstrated liveness during the interval, or - if necessary to convert the safe to a 1 of 1. -1. The module sets the correct 75% threshold upon removing a signer. -1. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1. -1. It must be impossible for the guard's checkTransaction or checkAfterExecution to permanently - revert given any calldata and the current state. - -Note: neither the module nor guard attempt to prevent a quorum of owners from removing either the liveness -module or guard. There are legitimate reasons they might wish to do so. Moreover, if such a quorum -of owners exists, there is no benefit to removing them, as they are defacto 'sufficiently live'. - -### Interdependency between the guard and module - -The guard has no dependency on the module, and can be used independently to track liveness of -Safe owners. - -This means that the module can be removed or replaced without any affect on the guard. - -The module however does have a dependency on the guard; if the guard is removed from the Safe, then -the module will no longer be functional and calls to its `removeOwners` function will revert. - -### Deploying the liveness checking system - -[deploying]: #deploying-the-liveness-checking-system - -The module and guard are intended to be deployed and installed on the safe in the following -sequence: - -1. Deploy the guard contract - 2. The guard's constructor will read the Safe's owners and set a timestamp -1. Deploy the module. -1. Set the guard on the safe. -1. Enable the module on the safe. - -This order of operations is necessary to satisfy the constructor checks in the module, and is -intended to prevent owners from being immediately removable. - -Note that changes to the owners set should not be made between the time the module is deployed, and -when it is enabled on the Safe, otherwise the checks made in the module's constructor may be -invalidated. If such changes are made, a new module should be deployed. - -### Modify the liveness checking system - -Changes to the liveness checking system should be done in the following manner: - -#### Replacing the module - -The module can safely be removed without affecting the operation of the guard. A new module can then -be added. - -Note: none of the module's parameters are modifiable. In order to update the security properties -enforced by the module, it must be replaced. - -#### Replacing the guard - -The safe can only have one guard contract at a time, and if the guard is removed the module will -cease to function. This does not affect the ability of the Safe to operate normally, however the -module should be removed as a best practice. - -If a new guard is added, eg. as a means of upgrading it, then a new module will also need to be -deployed and enabled. Once both the guard and module have been removed, they can be replaced -according to the steps in the [Deployment][deploying] section above. diff --git a/specs/span-batches.md b/specs/span-batches.md deleted file mode 100644 index 0b0738497e03..000000000000 --- a/specs/span-batches.md +++ /dev/null @@ -1,338 +0,0 @@ -# Span-batches - - -[g-deposit-tx-type]: glossary.md#deposited-transaction-type - - - -**Table of Contents** - -- [Introduction](#introduction) -- [Span batch format](#span-batch-format) -- [Optimization Strategies](#optimization-strategies) - - [Truncating information and storing only necessary data](#truncating-information-and-storing-only-necessary-data) - - [`tx_data_headers` removal from initial specs](#tx_data_headers-removal-from-initial-specs) - - [`Chain ID` removal from initial specs](#chain-id-removal-from-initial-specs) - - [Reorganization of constant length transaction fields](#reorganization-of-constant-length-transaction-fields) - - [RLP encoding for only variable length fields](#rlp-encoding-for-only-variable-length-fields) - - [Store `y_parity` instead of `v`](#store-y_parity-instead-of-v) - - [Adjust `txs` Data Layout for Better Compression](#adjust-txs-data-layout-for-better-compression) - - [`fee_recipients` Encoding Scheme](#fee_recipients-encoding-scheme) -- [How derivation works with Span Batch?](#how-derivation-works-with-span-batch) -- [Integration](#integration) - - [Channel Reader (Batch Decoding)](#channel-reader-batch-decoding) - - [Batch Queue](#batch-queue) - - [Batcher](#batcher) - - - -> The span-batches spec is experimental :shipit: -> -> *this feature is in active R&D and not yet part of any hard fork - -## Introduction - -Span-batches reduce overhead of OP-stack chains. -This enables sparse and low-throughput OP-stack chains. - -The overhead is reduced by representing a span of -consecutive L2 blocks in a more efficient manner, -while preserving the same consistency checks as regular batch data. - -Note that the [channel](./derivation.md#channel-format) and -[frame](./derivation.md#frame-format) formats stay the same: -data slicing, packing and multi-transaction transport is already optimized. - -The overhead in the [V0 batch format](./derivation.md) comes from: - -- The meta-data attributes are repeated for every L2 block, while these are mostly implied already: - - parent hash (32 bytes) - - L1 epoch: blockhash (32 bytes) and block number (~4 bytes) - - timestamp (~4 bytes) -- The organization of block data is inefficient: - - Similar attributes are far apart, diminishing any chances of effective compression. - - Random data like hashes are positioned in-between the more compressible application data. -- The RLP encoding of the data adds unnecessary overhead - - The outer list does not have to be length encoded, the attributes are known - - Fixed-length attributes do not need any encoding - - The batch-format is static and can be optimized further -- Remaining meta-data for consistency checks can be optimized further: - - The metadata only needs to be secure for consistency checks. E.g. 20 bytes of a hash may be enough. - -Span-batches address these inefficiencies, with a new batch format version. - -## Span batch format - -Note that span-batches, unlike previous singular batches, -encode *a range of consecutive* L2 blocks at the same time. - -Introduce version `1` to the [batch-format](./derivation.md#batch-format) table: - -| `batch_version` | `content` | -|-----------------|---------------------| -| 1 | `prefix ++ payload` | - -Notation: - -- `++`: concatenation of byte-strings -- `span_start`: first L2 block in the span -- `span_end`: last L2 block in the span -- `uvarint`: unsigned Base128 varint, as defined in [protobuf spec] -- `rlp_encode`: a function that encodes a batch according to the [RLP format], - and `[x, y, z]` denotes a list containing items `x`, `y` and `z` - -[protobuf spec]: https://protobuf.dev/programming-guides/encoding/#varints - -Where: - -- `prefix = rel_timestamp ++ l1_origin_num ++ parent_check ++ l1_origin_check` - - `rel_timestamp`: `uvarint` relative timestamp since L2 genesis, - i.e. `span_start.timestamp - config.genesis.timestamp`. - - `l1_origin_num`: `uvarint` number of last l1 origin number. i.e. `span_end.l1_origin.number` - - `parent_check`: first 20 bytes of parent hash, the hash is truncated to 20 bytes for efficiency, - i.e. `span_start.parent_hash[:20]`. - - `l1_origin_check`: the block hash of the last L1 origin is referenced. - The hash is truncated to 20 bytes for efficiency, i.e. `span_end.l1_origin.hash[:20]`. -- `payload = block_count ++ origin_bits ++ block_tx_counts ++ txs`: - - `block_count`: `uvarint` number of L2 blocks. This is at least 1, empty span batches are invalid. - - `origin_bits`: bitlist of `block_count` bits, right-padded to a multiple of 8 bits: - 1 bit per L2 block, indicating if the L1 origin changed this L2 block. - - `block_tx_counts`: for each block, a `uvarint` of `len(block.transactions)`. - - `txs`: L2 transactions which is reorganized and encoded as below. -- `txs = contract_creation_bits ++ y_parity_bits ++ tx_sigs ++ tx_tos ++ tx_datas ++ tx_nonces ++ tx_gases` - - `contract_creation_bits`: bit list of `sum(block_tx_counts)` bits, right-padded to a multiple of 8 bits, - 1 bit per L2 transactions, indicating if transaction is a contract creation transaction. - - `y_parity_bits`: bit list of `sum(block_tx_counts)` bits, right-padded to a multiple of 8 bits, - 1 bit per L2 transactions, indicating the y parity value when recovering transaction sender address. - - `tx_sigs`: concatenated list of transaction signatures - - `r` is encoded as big-endian `uint256` - - `s` is encoded as big-endian `uint256` - - `tx_tos`: concatenated list of `to` field. `to` field in contract creation transaction will be `nil` and ignored. - - `tx_datas`: concatenated list of variable length rlp encoded data, - matching the encoding of the fields as in the [EIP-2718] format of the `TransactionType`. - - `legacy`: `rlp_encode(value, gasPrice, data)` - - `1`: ([EIP-2930]): `0x01 ++ rlp_encode(value, gasPrice, data, accessList)` - - `2`: ([EIP-1559]): `0x02 ++ rlp_encode(value, max_priority_fee_per_gas, max_fee_per_gas, data, access_list)` - - `tx_nonces`: concatenated list of `uvarint` of `nonce` field. - - `tx_gases`: concatenated list of `uvarint` of gas limits. - - `legacy`: `gasLimit` - - `1`: ([EIP-2930]): `gasLimit` - - `2`: ([EIP-1559]): `gas_limit` - -Introduce version `2` to the [batch-format](./derivation.md#batch-format) table: - -| `batch_version` | `content` | -|-----------------|---------------------| -| 2 | `prefix ++ payload` | - -Where: - -- `prefix = rel_timestamp ++ l1_origin_num ++ parent_check ++ l1_origin_check`: - - Identical to `batch_version` 1 -- `payload = block_count ++ origin_bits ++ block_tx_counts ++ txs ++ fee_recipients`: - - An empty span-batch, i.e. with `block_count == 0`, is invalid and must not be processed. - - Every field definition identical to `batch_version` 1 except that `fee_recipients` is - added to support more decentralized sequencing. - - `fee_recipients = fee_recipients_idxs + fee_recipients_set` - - `fee_recipients_set`: concatenated list of unique L2 fee recipient address. - - `fee_recipients_idxs`: for each block, - `uvarint` number of index to decode fee recipients from `fee_recipients_set`. - -[EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718 - -[EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930 - -[EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559 - -Total size of encoded span batch is limited to `MAX_SPAN_BATCH_SIZE` (currently 10,000,000 bytes, -equal to `MAX_RLP_BYTES_PER_CHANNEL`). Therefore every field size of span batch will be implicitly limited to -`MAX_SPAN_BATCH_SIZE` . There can be at least single span batch per channel, and channel size is limited -to `MAX_RLP_BYTES_PER_CHANNEL` and you may think that there is already an implicit limit. However, having an explicit -limit for span batch is helpful for several reasons. We may save computation costs by avoiding malicious input while -decoding. For example, lets say bad batcher wrote span batch which `block_count = max.Uint64`. We may early return using -the explicit limit, not trying to consume data until EOF is reached. We can also safely preallocate memory for decoding -because we know the upper limit of memory usage. - -## Optimization Strategies - -### Truncating information and storing only necessary data - -The following fields stores truncated data: - -- `rel_timestamp`: We can save two bytes by storing `rel_timestamp` instead of the full `span_start.timestamp`. -- `parent_check` and `l1_origin_check`: We can save twelve bytes by truncating twelve bytes from the full hash, - while having enough safety. - -### `tx_data_headers` removal from initial specs - -We do not need to store length per each `tx_datas` elements even if those are variable length, -because the elements itself is RLP encoded, containing their length in RLP prefix. - -### `Chain ID` removal from initial specs - -Every transaction has chain id. We do not need to include chain id in span batch because L2 already knows its chain id, -and use its own value for processing span batches while derivation. - -### Reorganization of constant length transaction fields - -`signature`, `nonce`, `gaslimit`, `to` field are constant size, so these were split up completely and -are grouped into individual arrays. -This adds more complexity, but organizes data for improved compression by grouping data with similar data pattern. - -### RLP encoding for only variable length fields - -Further size optimization can be done by packing variable length fields, such as `access_list`. -However, doing this will introduce much more code complexity, comparing to benefiting by size reduction. - -Our goal is to find the sweet spot on code complexity - span batch size tradeoff. -I decided that using RLP for all variable length fields will be the best option, -not risking codebase with gnarly custom encoding/decoding implementations. - -### Store `y_parity` instead of `v` - -For legacy type transactions, `v = 2 * ChainID + y_parity`. For other types of transactions, `v = y_parity`. -We may only store `y_parity`, which is single bit per L2 transaction. - -This optimization will benefit more when ratio between number of legacy type transactions over number of transactions -excluding deposit tx is higher. -Deposit transactions are excluded in batches and are never written at L1 so excluded while analyzing. - -### Adjust `txs` Data Layout for Better Compression - -There are (7 choose 2) * 5! = 2520 permutations of ordering fields of `txs`. -It is not 7! because `contract_creation_bits` must be first decoded in order to decode `tx_tos`. -We experimented to find out the best layout for compression. -It turned out placing random data together(`TxSigs`, `TxTos`, `TxDatas`), -then placing leftovers helped gzip to gain more size reduction. - -### `fee_recipients` Encoding Scheme - -Let `K` := number of unique fee recipients(cardinality) per span batch. Let `N` := number of L2 blocks. -If we naively encode each fee recipients by concatenating every fee recipients, it will need `20 * N` bytes. -If we manage `fee_recipients_idxs` and `fee_recipients_set`, It will need at most `max uvarint size * N = 8 * N`, -`20 * K` bytes each. If `20 * N > 8 * N + 20 * K` then maintaining an index of fee recipients is reduces the size. - -we thought sequencer rotation happens not much often, so assumed that `K` will be much lesser than `N`. -The assumption makes upper inequality to hold. Therefore, we decided to manage `fee_recipients_idxs` and -`fee_recipients_set` separately. This adds complexity but reduces data. - -## How derivation works with Span Batch? - -- Block Timestamp - - The first L2 block's block timestamp is `rel_timestamp + L2Genesis.Timestamp`. - - Then we can derive other blocks timestamp by adding L2 block time for each. -- L1 Origin Number - - The parent of the first L2 block's L1 origin number is `l1_origin_num - sum(origin_bits)` - - Then we can derive other blocks' L1 origin number with `origin_bits` - - `ith block's L1 origin number = (i-1)th block's L1 origin number + (origin_bits[i] ? 1 : 0)` -- L1 Origin Hash - - We only need the `l1_origin_check`, the truncated L1 origin hash of the last L2 block of Span Batch. - - If the last block references canonical L1 chain as its origin, - we can ensure the all other blocks' origins are consistent with the canonical L1 chain. -- Parent hash - - In V0 Batch spec, we need batch's parent hash to validate if batch's parent is consistent with current L2 safe head. - - But in the case of Span Batch, because it contains consecutive L2 blocks in the span, - we do not need to validate all blocks' parent hash except the first block. -- Transactions - - Deposit transactions can be derived from its L1 origin, identical with V0 batch. - - User transactions can be derived by following way: - - Recover `V` value of TX signature from `y_parity_bits` and L2 chainId, as described in optimization strategies. - - When parsing `tx_tos`, `contract_creation_bits` is used to determine if the TX has `to` value or not. - -## Integration - -### Channel Reader (Batch Decoding) - -The Channel Reader decodes the span-batch, as described in the [span-batch format](#span-batch-format). - -A set of derived attributes is computed as described above. Then cached with the decoded result: - -### Batch Queue - -A span-batch is buffered as a singular large batch, -by its starting timestamp (transformed `rel_timestamp`). - -Span-batches share the same queue with v0 batches: batches are processed in L1 inclusion order. - -A set of modified validation rules apply to the span-batches. - -Rules are enforced with the [contextual definitions](./derivation.md#batch-queue) as v0-batch validation: -`batch`, `epoch`, `inclusion_block_number`, `next_timestamp`, `next_epoch`, `batch_origin` - -Span-batch rules, in validation order: - -- `batch.start_timestamp > next_timestamp` -> `future`: i.e. the batch must be ready to process. -- `batch.start_timestamp < next_timestamp` -> `drop`: i.e. the batch must not be too old. -- `batch.parent_check != safe_l2_head.hash[:20]` -> `drop`: i.e. the checked part of the parent hash must be equal - to the L2 safe head block hash. -- Sequencing-window checks: - - Note: The sequencing window is enforced for the *batch as a whole*: - if the batch was partially invalid instead, it would drop the oldest L2 blocks, - which makes the later L2 blocks invalid. - - Variables: - - `origin_changed_bit = origin_bits[0]`: `true` if the first L2 block changed its L1 origin, `false` otherwise. - - `start_epoch_num = batch.l1_origin_num - sum(origin_bits) + (origin_changed_bit ? 1 : 0)` - - `end_epoch_num = batch.l1_origin_num` - - Rules: - - `start_epoch_num + sequence_window_size < inclusion_block_number` -> `drop`: - i.e. the batch must be included timely. - - `start_epoch_num > epoch.number + 1` -> `drop`: - i.e. the L1 origin cannot change by more than one L1 block per L2 block. - - If `batch.l1_origin_check` does not match the canonical L1 chain at `end_epoch_num` -> `drop`: - verify the batch is intended for this L1 chain. - - After upper `l1_origin_check` check is passed, we don't need to check if the origin - is past `inclusion_block_number` because of the following invariant. - - Invariant: the epoch-num in the batch is always less than the inclusion block number, - if and only if the L1 epoch hash is correct. - - `start_epoch_num < epoch.number` -> `drop`: must have been duplicate batch, - we may be past this L1 block in the safe L2 chain. If a span-batch overlaps with older information, - it is dropped, since partially valid span-batches are not accepted. -- Max Sequencer time-drift checks: - - Note: The max time-drift is enforced for the *batch as a whole*, to keep the possible output variants small. - - Variables: - - `block_input`: an L2 block from the span-batch, - with L1 origin as derived from the `origin_bits` and now established canonical L1 chain. - - `next_epoch`: `block_input.origin`'s next L1 block. - It may reach to the next origin outside the L1 origins of the span. - - Rules: - - For each `block_input` that can be read from the span-batch: - - `block_input.timestamp < block_input.origin.time` -> `drop`: enforce the min L2 timestamp rule. - - `block_input.timestamp > block_input.origin.time + max_sequencer_drift`: enforce the L2 timestamp drift rule, - but with exceptions to preserve above min L2 timestamp invariant: - - `len(block_input.transactions) == 0`: - - `origin_bits[i] == 0`: `i` is the index of `block_input` in the span batch. - So this implies the block_input did not advance the L1 origin, - and must thus be checked against `next_epoch`. - - If `next_epoch` is not known -> `undecided`: - without the next L1 origin we cannot yet determine if time invariant could have been kept. - - If `block_input.timestamp >= next_epoch.time` -> `drop`: - the batch could have adopted the next L1 origin without breaking the `L2 time >= L1 time` invariant. - - `len(block_input.transactions) > 0`: -> `drop`: - when exceeding the sequencer time drift, never allow the sequencer to include transactions. -- And for all transactions: - - `drop` if the `batch.tx_datas` list contains a transaction - that is invalid or derived by other means exclusively: - - any transaction that is empty (zero length `tx_data`) - - any [deposited transactions][g-deposit-tx-type] (identified by the transaction type prefix byte in `tx_data`) - -Once validated, the batch-queue then emits a block-input for each of the blocks included in the span-batch. -The next derivation stage is thus only aware of individual block inputs, similar to the previous V0 batch, -although not strictly a "v0 batch" anymore. - -### Batcher - -Instead of transforming L2 blocks into batches, -the blocks should be buffered to form a span-batch. - -Ideally the L2 blocks are buffered as block-inputs, to maximize the span of blocks covered by the span-batch: -span-batches of single L2 blocks do not increase efficiency as much as with larger spans. - -This means that the `(c *channelBuilder) AddBlock` function is changed to -not directly call `(co *ChannelOut) AddBatch` but defer that until a minimum number of blocks have been buffered. - -Output-size estimation of the queued up blocks is not possible until the span-batch is written to the channel. -Past a given number of blocks, the channel may be written for estimation, and then re-written if more blocks arrive. - -The [batcher functionality](./batcher.md) stays the same otherwise: unsafe blocks are transformed into batches, -encoded in compressed channels, and then split into frames for submission to L1. -Batcher implementations can implement different heuristics and re-attempts to build the most gas-efficient data-txs. diff --git a/specs/superchain-upgrades.md b/specs/superchain-upgrades.md deleted file mode 100644 index d606c7eebfdd..000000000000 --- a/specs/superchain-upgrades.md +++ /dev/null @@ -1,275 +0,0 @@ -# Superchain Upgrades - -Superchain upgrades, also known as forks or hardforks, implement consensus-breaking changes. - -A Superchain upgrade requires the node software to support up to a given Protocol Version. -The version indicates support, the upgrade indicates the activation of new functionality. - -This document lists the protocol versions of the OP-Stack, starting at the Bedrock upgrade, -as well as the default Superchain Targets. - -Activation rule parameters of network upgrades are configured as part of the Superchain Target specification: -chains following the same Superchain Target upgrade synchronously. - - - -**Table of Contents** - -- [Protocol Version](#protocol-version) - - [Protocol Version Format](#protocol-version-format) - - [Build identifier](#build-identifier) - - [Major versions](#major-versions) - - [Minor versions](#minor-versions) - - [Patch versions](#patch-versions) - - [Pre-releases](#pre-releases) - - [Protocol Version Exposure](#protocol-version-exposure) -- [Superchain Target](#superchain-target) - - [Superchain Version signaling](#superchain-version-signaling) - - [`ProtocolVersions` L1 contract](#protocolversions-l1-contract) -- [Activation rules](#activation-rules) - - [L2 Block-number based activation (deprecated)](#l2-block-number-based-activation-deprecated) - - [L2 Block-timestamp based activation](#l2-block-timestamp-based-activation) -- [OP-Stack Protocol versions](#op-stack-protocol-versions) -- [Post-Bedrock Network upgrades](#post-bedrock-network-upgrades) - - [Regolith](#regolith) - - - -## Protocol Version - -The Protocol Version documents the progression of the total set of canonical OP-Stack specifications. -Components of the OP-Stack implement the subset of their respective protocol component domain, -up to a given Protocol Version of the OP-Stack. - -OP-Stack mods, i.e. non-canonical extensions to the OP-Stack, are not included in the versioning of the Protocol. -Instead, mods must specify which upstream Protocol Version they are based on and where breaking changes are made. -This ensures tooling of the OP-Stack can be shared and collaborated on with OP-Stack mods. - -The Protocol Version is NOT a hardfork identifier, but rather indicates software-support for a well-defined set -of features introduced in past and future hardforks, not the activation of said hardforks. - -Changes that can be included in prospective Protocol Versions may be included in the specifications as proposals, -with explicit notice of the Protocol Version they are based on. -This enables an iterative integration process into the canonical set of specifications, -but does not guarantee the proposed specifications become canonical. - -Note that the Protocol Version only applies to the Protocol specifications with the Superchain Targets specified within. -This versioning is independent of the [Semver] versioning used in OP Stack smart-contracts, -and the [Semver]-versioned reference software of the OP-Stack. - -### Protocol Version Format - -The Protocol Version is [Semver]-compatible. -It is encoded as a single 32 bytes long ``. -The version must be encoded as 32 bytes of `DATA` in JSON RPC usage. - -The encoding is typed, to ensure future-compatibility. - -```text - ::= - ::= - ::= <31 bytes> -``` - -version-type `0`: - -```text - - ::= <7 zeroed bytes> - ::= <8 bytes> - ::= - ::= - ::= - ::= -``` - -The `` bytes of the Protocol Version are reserved for future extensions. - -Protocol versions with a different `` should not be compared directly. - -[Semver]: https://semver.org/ - -#### Build identifier - -The `` identifier, as defined by [Semver], is ignored when determining version precedence. -The `` must be non-zero to apply to the protocol version. - -Modifications of the OP-Stack should define a `` to distinguish from the canonical protocol feature-set. -Changes to the `` may be encoded in the `` itself to stay aligned with the upstream protocol. -The major/minor/patch versions should align with that of the upstream protocol that the modifications are based on. -Users of the protocol can choose to implement custom support for the alternative ``, -but may work out of the box if the major features are consistent with that of the upstream protocol version. - -The 8 byte `` identifier may be presented as string for human readability if the contents are alpha-numeric, -including `-` and `.`, as outlined in the [Semver] format specs. Trailing `0` bytes can be used for padding. -It may be presented as `0x`-prefixed hex string otherwise. - -#### Major versions - -Major version changes indicate support for new consensus-breaking functionality. -Major versions should retain support for functionality of previous major versions for -syncing/indexing of historical chain data. -Implementations may drop support for previous Major versions, when there are viable alternatives, -e.g. `l2geth` for pre-Bedrock data. - -#### Minor versions - -Minor version changes indicate support for backward compatible extensions, -including backward-compatible additions to the set of chains in a Superchain Target. -Backward-compatibility is defined by the requirement for existing end-users to upgrade nodes and tools or not. -Minor version changes may also include optional offchain functionality, such as additional syncing protocols. - -#### Patch versions - -Patch version changes indicate backward compatible bug fixes and improvements. - -#### Pre-releases - -Pre-releases of the protocol are proposals: these are not stable targets for production usage. -A pre-release might not satisfy the intended compatibility requirements as denoted by its associated normal version. -The `` must be non-zero to apply to the protocol version. -The `` `0`-value is reserved for non-prereleases, i.e. `v3.1.0` is higher than `v3.1.0-1`. - -Node-software may support a pre-release, but must not activate any protocol changes without the user explicitly -opting in through the means of a feature-flag or configuration change. - -A pre-release is not an official version, and meant for protocol developers to communicate an experimental changeset -before the changeset is reviewed by governance. Pre-releases are subject to change. - -### Protocol Version Exposure - -The Protocol Version is not exposed to the application-layer environment: -hardforks already expose the change of functionality upon activation as required, -and the Protocol Version is meant for offchain usage only. -The protocol version indicates support rather than activation of functionality. -There is one exception however: signaling by onchain components to offchain components. -More about this in [Superchain Version signaling]. - -## Superchain Target - -Changes to the L2 state-transition function are transitioned into deterministically across all nodes -through an **activation rule**. - -Changes to L1 smart-contracts must be compatible with the latest activated L2 functionality, -and are executed through **L1 contract-upgrades**. - -A Superchain Target defines a set of activation rules and L1 contract upgrades shared between OP-Stack chains, -to upgrade the chains collectively. - -### Superchain Version signaling - -Each Superchain Target tracks the protocol changes, and signals the `recommended` and `required` -Protocol Version ahead of activation of new breaking functionality. - -- `recommended`: a signal in advance of a network upgrade, to alert users of the protocol change to be prepared for. - Node software is recommended to signal the recommendation to users through logging and metrics. -- `required`: a signal shortly in advance of a breaking network upgrade, to alert users of breaking changes. - Users may opt in to elevated alerts or preventive measures, to ensure consistency with the upgrade. - -Signaling is done through a L1 smart-contract that is monitored by the OP-Stack software. -Not all components of the OP-Stack are required to directly monitor L1 however: -cross-component APIs like the Engine API may be used to forward the Protocol Version signals, -to keep components encapsulated from L1. -See [`engine_signalOPStackVersionV1`](./exec-engine.md#enginesignalopstackversionv1). - -### `ProtocolVersions` L1 contract - -The `ProtocolVersions` contract on L1 enables L2 nodes to pick up on superchain protocol version signals. - -The interface is: - -- Required storage slot: `bytes32(uint256(keccak256("protocolversion.required")) - 1)` -- Recommended storage slot: `bytes32(uint256(keccak256("protocolversion.recommended")) - 1)` -- Required getter: `required()` returns `ProtocolVersion` -- Recommended getter `recommended()` returns `ProtocolVersion` -- Version updates also emit a typed event: - `event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data)` - -## Activation rules - -The below L2-block based activation rules may be applied in two contexts: - -- The rollup node, specified through the rollup configuration (known as `rollup.json`), - referencing L2 blocks (or block input-attributes) that pass through the derivation pipeline. -- The execution engine, specified through the chain configuration (known as the `config` part of `genesis.json`), - referencing blocks or input-attributes that are part of, or applied to, the L2 chain. - -For both types of configurations, some activation parameters may apply to all chains within the superchain, -and are then retrieved from the superchain target configuration. - -### L2 Block-number based activation (deprecated) - -Activation rule: `x != null && x >= upgradeNumber` - -This block number based method has commonly been used in L1 up until the Bellatrix/Paris upgrade, a.k.a. The Merge, -which was upgraded through special rules. - -This method is not superchain-compatible, as the activation-parameter is chain-specific -(different chains may have different block-heights at the same moment in time). - -Starting at, and including, the L2 `block` with `block.number == x`, the upgrade rules apply. -If the upgrade block-number `x` is not specified in the configuration, the upgrade is ignored. - -This applies to the L2 block number, not to the L1-origin block number. -This means that an L2 upgrade may be inactive, and then active, without changing the L1-origin. - -### L2 Block-timestamp based activation - -Activation rule: `x != null && x >= upgradeTime` - -This is the preferred superchain upgrade activation-parameter type: -it is synchronous between all L2 chains and compatible with post-Merge timestamp-based chain upgrades in L1. - -Starting at, and including, the L2 `block` with `block.timestamp == x`, the upgrade rules apply. -If the upgrade block-timestamp `x` is not specified in the configuration, the upgrade is ignored. - -This applies to the L2 block timestamp, not to the L1-origin block timestamp. -This means that an L2 upgrade may be inactive, and then active, without changing the L1-origin. - -This timestamp based method has become the default on L1 after the Bellatrix/Paris upgrade, a.k.a. The Merge, -because it can be planned in accordance with beacon-chain epochs and slots. - -Note that the L2 version is not limited to timestamps that match L1 beacon-chain slots or epochs. -A timestamp may be chosen to be synchronous with a specific slot or epoch on L1, -but the matching L1-origin information may not be present at the time of activation on L2. - -## OP-Stack Protocol versions - -- `v1.0.0`: 2021 Jan 16th - Mainnet Soft Launch, based on OVM. - ([announcement](https://medium.com/ethereum-optimism/mainnet-soft-launch-7cacc0143cd5)) -- `v1.1.0`: 2021 Aug 19th - Community launch. - ([announcement](https://medium.com/ethereum-optimism/community-launch-7c9a2a9d3e84)) -- `v2.0.0`: 2021 Nov 12th - the EVM-Equivalence update, also known as OVM 2.0 and chain regenesis. - ([announcement](https://twitter.com/optimismfnd/status/1458953238867165192)) -- `v2.1.0`: 2022 May 31st - Optimism Collective. - ([announcement](https://optimism.mirror.xyz/gQWKlrDqHzdKPsB1iUnI-cVN3v0NvsWnazK7ajlt1fI)). -- `v3.0.0-1`: 2023 Jan 13th - Bedrock pre-release, deployed on OP-Goerli, and later Base-Goerli. -- `v3.0.0`: 2023 Jun 6th - Bedrock, including the Regolith hardfork improvements, first deployed on OP-Mainnet. - -## Post-Bedrock Network upgrades - -### Regolith - -The Regolith upgrade, named after a material best described as "deposited dust on top of a layer of bedrock", -implements minor changes to deposit processing, based on reports of the Sherlock Audit-contest and findings in -the Bedrock Optimism Goerli testnet. - -Summary of changes: - -- The `isSystemTx` boolean is disabled, system transactions now use the same gas accounting rules as regular deposits. -- The actual deposit gas-usage is recorded in the receipt of the deposit transaction, - and subtracted from the L2 block gas-pool. - Unused gas of deposits is not refunded with ETH however, as it is burned on L1. -- The `nonce` value of the deposit sender account, before the transaction state-transition, is recorded in a new - optional field (`depositNonce`), extending the transaction receipt (i.e. not present in pre-Regolith receipts). -- The recorded deposit `nonce` is used to correct the transaction and receipt metadata in RPC responses, - including the `contractAddress` field of deposits that deploy contracts. -- The `gas` and `depositNonce` data is committed to as part of the consensus-representation of the receipt, - enabling the data to be safely synced between independent L2 nodes. -- The L1-cost function was corrected to more closely match pre-Bedrock behavior. - -The [deposit specification](./deposits.md) specifies the deposit changes of the Regolith upgrade in more detail. -The [execution engine specification](./exec-engine.md) specifies the L1 cost function difference. - -The Regolith upgrade uses a *L2 block-timestamp* activation-rule, and is specified in both the -rollup-node (`regolith_time`) and execution engine (`config.regolithTime`). diff --git a/specs/system_config.md b/specs/system_config.md deleted file mode 100644 index 1b02ec053543..000000000000 --- a/specs/system_config.md +++ /dev/null @@ -1,95 +0,0 @@ -# System Config - - - -**Table of Contents** - -- [System config contents (version 0)](#system-config-contents-version-0) - - [`batcherHash` (`bytes32`)](#batcherhash-bytes32) - - [`overhead` and `scalar` (`uint256,uint256`)](#overhead-and-scalar-uint256uint256) - - [`gasLimit` (`uint64`)](#gaslimit-uint64) - - [`unsafeBlockSigner` (`address`)](#unsafeblocksigner-address) -- [Writing the system config](#writing-the-system-config) -- [Reading the system config](#reading-the-system-config) - - - -The `SystemConfig` is a contract on L1 that can emit rollup configuration changes as log events. -The rollup [block derivation process](./derivation.md) picks up on these log events and applies the changes. - -## System config contents (version 0) - -Version 0 of the system configuration contract defines the following parameters: - -### `batcherHash` (`bytes32`) - -A versioned hash of the current authorized batcher sender(s), to rotate keys as batch-submitter. -The first byte identifies the version. - -Version `0` embeds the current batch submitter ethereum address (`bytes20`) in the last 20 bytes of the versioned hash. - -In the future this versioned hash may become a commitment to a more extensive configuration, -to enable more extensive redundancy and/or rotation configurations. - -### `overhead` and `scalar` (`uint256,uint256`) - -The L1 fee parameters, also known as Gas Price Oracle (GPO) parameters, -are updated in conjunction and apply new L1 costs to the L2 transactions. - -### `gasLimit` (`uint64`) - -The gas limit of the L2 blocks is configured through the system config. -Changes to the L2 gas limit are fully applied in the first L2 block with the L1 origin that introduced the change, -as opposed to the 1/1024 adjustments towards a target as seen in limit updates of L1 blocks. - -### `unsafeBlockSigner` (`address`) - -Blocks are gossiped around the p2p network before they are made available on L1. -To prevent denial of service on the p2p layer, these unsafe blocks must be -signed with a particular key to be accepted as "canonical" unsafe blocks. -The address corresponding to this key is the `unsafeBlockSigner`. To ensure -that its value can be fetched with a storage proof in a storage layout independent -manner, it is stored at a special storage slot corresponding to -`keccak256("systemconfig.unsafeblocksigner")`. - -Unlike the other values, the `unsafeBlockSigner` only operates on blockchain -policy. It is not a consensus level parameter. - -## Writing the system config - -The `SystemConfig` contract applies authentication to all writing contract functions, -the configuration management can be configured to be any type of ethereum account or contract. - -On a write, an event is emitted for the change to be picked up by the L2 system, -and a copy of the new written configuration variable is retained in L1 state to read with L1 contracts. - -## Reading the system config - -A rollup node initializes its derivation process by finding a starting point based on its past L2 chain: - -- When started from L2 genesis, the initial system configuration is retrieved from the rollup chain configuration. -- When started from an existing L2 chain, a previously included L1 block is determined as derivation starting point, - and the system config can thus be retrieved from the last L2 block that referenced the L1 block as L1 origin: - - `batcherHash`, `overhead` and `scalar` are retrieved from the L1 block info transaction. - - `gasLimit` is retrieved from the L2 block header. - - other future variables may also be retrieved from other contents of the L2 block, such as the header. - -After preparing the initial system configuration for the given L1 starting input, -the system configuration is updated by processing all receipts from each new L1 block. - -The contained log events are filtered and processed as follows: - -- the log event contract address must match the rollup `SystemConfig` deployment -- the first log event topic must match the ABI hash of `ConfigUpdate(uint256,uint8,bytes)` -- the second topic determines the version. Unknown versions are critical derivation errors. -- the third topic determines the type of update. Unknown types are critical derivation errors. -- the remaining event data is opaque, encoded as ABI bytes (i.e. includes offset and length data), - and encodes the configuration update. In version `0` the following types are supported: - - type `0`: `batcherHash` overwrite, as `bytes32` payload. - - type `1`: `overhead` and `scalar` overwrite, as two packed `uint256` entries. - - type `2`: `gasLimit` overwrite, as `uint64` payload. - - type `3`: `unsafeBlockSigner` overwrite, as `address` payload. - -Note that individual derivation stages may be processing different L1 blocks, -and should thus maintain individual system configuration copies, -and apply the event-based changes as the stage traverses to the next L1 block. diff --git a/specs/withdrawals.md b/specs/withdrawals.md deleted file mode 100644 index 410813d2b31a..000000000000 --- a/specs/withdrawals.md +++ /dev/null @@ -1,231 +0,0 @@ -# Withdrawals - - - -[g-deposits]: glossary.md#deposits -[g-deposited]: glossary.md#deposited-transaction -[deposit-tx-type]: glossary.md#deposited-transaction-type -[g-withdrawal]: glossary.md#withdrawal -[g-mpt]: glossary.md#merkle-patricia-trie -[g-relayer]: glossary.md#withdrawals -[g-execution-engine]: glossary.md#execution-engine - -[Withdrawals][g-withdrawal] are cross domain transactions which are initiated on L2, and finalized by a transaction -executed on L1. Notably, withdrawals may be used by an L2 account to call an L1 contract, or to transfer ETH from -an L2 account to an L1 account. - -**Vocabulary note**: _withdrawal_ can refer to the transaction at various stages of the process, but we introduce -more specific terms to differentiate: - -- A _withdrawal initiating transaction_ refers specifically to a transaction on L2 sent to the Withdrawals predeploy. -- A _withdrawal proving transaction_ refers specifically to an L1 transaction - which proves the withdrawal is correct (that it has been included in a merkle - tree whose root is available on L1). -- A _withdrawal finalizing transaction_ refers specifically to an L1 transaction which finalizes and relays the - withdrawal. - -Withdrawals are initiated on L2 via a call to the Message Passer predeploy contract, which records the important -properties of the message in its storage. -Withdrawals are proven on L1 via a call to the `OptimismPortal`, which proves the inclusion of this withdrawal message. -Withdrawals are finalized on L1 via a call to the `OptimismPortal` contract, -which verifies that the fault challenge period has passed since the withdrawal message has been proved. - -In this way, withdrawals are different from [deposits][g-deposits] which make use of a special transaction type in the -[execution engine][g-execution-engine] client. Rather, withdrawals transaction must use smart contracts on L1 for -finalization. - - - -**Table of Contents** - -- [Withdrawal Flow](#withdrawal-flow) - - [On L2](#on-l2) - - [On L1](#on-l1) -- [The L2ToL1MessagePasser Contract](#the-l2tol1messagepasser-contract) - - [Addresses are not Aliased on Withdrawals](#addresses-are-not-aliased-on-withdrawals) -- [The Optimism Portal Contract](#the-optimism-portal-contract) -- [Withdrawal Verification and Finalization](#withdrawal-verification-and-finalization) -- [Security Considerations](#security-considerations) - - [Key Properties of Withdrawal Verification](#key-properties-of-withdrawal-verification) - - [Handling Successfully Verified Messages That Fail When Relayed](#handling-successfully-verified-messages-that-fail-when-relayed) - - [OptimismPortal can send abitrary messages on L1](#optimismportal-can-send-abitrary-messages-on-l1) - - - -## Withdrawal Flow - -We first describe the end to end flow of initiating and finalizing a withdrawal: - -### On L2 - -An L2 account sends a withdrawal message (and possibly also ETH) to the `L2ToL1MessagePasser` predeploy contract. -This is a very simple contract that stores the hash of the withdrawal data. - -### On L1 - -1. A [relayer][g-relayer] submits a withdrawal proving transaction with the required inputs - to the `OptimismPortal` contract. - The relayer is not necessarily the same entity which initiated the withdrawal on L2. - These inputs include the withdrawal transaction data, inclusion proofs, and a block number. The block number - must be one for which an L2 output root exists, which commits to the withdrawal as registered on L2. -1. The `OptimismPortal` contract retrieves the output root for the given block number from the `L2OutputOracle`'s - `getL2Output()` function, and performs the remainder of the verification process internally. -1. If proof verification fails, the call reverts. Otherwise the hash is recorded to prevent it from being re-proven. - Note that the withdrawal can be proven more than once if the corresponding output root changes. -1. After the withdrawal is proven, it enters a 7 day challenge period, allowing time for other network participants - to challenge the integrity of the corresponding output root. -1. Once the challenge period has passed, a relayer submits a withdrawal finalizing transaction to the - `OptimismPortal` contract. - The relayer doesn't need to be the same entity that initiated the withdrawal on L2. -1. The `OptimismPortal` contract receives the withdrawal transaction data and verifies that the withdrawal has - both been proven and passed the challenge period. -1. If the requirements are not met, the call reverts. Otherwise the call is forwarded, and the hash is recorded to - prevent it from being replayed. - -## The L2ToL1MessagePasser Contract - -[message-passer-contract]: #the-l2tol1messagepasser-contract - -A withdrawal is initiated by calling the L2ToL1MessagePasser contract's `initiateWithdrawal` function. -The L2ToL1MessagePasser is a simple predeploy contract at `0x4200000000000000000000000000000000000016` -which stores messages to be withdrawn. - -```js -interface L2ToL1MessagePasser { - event MessagePassed( - uint256 indexed nonce, // this is a global nonce value for all withdrawal messages - address indexed sender, - address indexed target, - uint256 value, - uint256 gasLimit, - bytes data, - bytes32 withdrawalHash - ); - - event WithdrawerBalanceBurnt(uint256 indexed amount); - - function burn() external; - - function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) payable external; - - function messageNonce() public view returns (uint256); - - function sentMessages(bytes32) view external returns (bool); -} - -``` - -The `MessagePassed` event includes all of the data that is hashed and -stored in the `sentMessages` mapping, as well as the hash itself. - -### Addresses are not Aliased on Withdrawals - -[address-aliasing]: #no-address-aliasing - -When a contract makes a deposit, the sender's address is [aliased](./deposits.md#address-aliasing). The same is not true -of withdrawals, which do not modify the sender's address. The difference is that: - -- on L2, the deposit sender's address is returned by the `CALLER` opcode, meaning a contract cannot easily tell if the - call originated on L1 or L2, whereas -- on L1, the withdrawal sender's address is accessed by calling the `l2Sender()` function on the `OptimismPortal` - contract. - -Calling `l2Sender()` removes any ambiguity about which domain the call originated from. Still, developers will need to -recognize that having the same address does not imply that a contract on L2 will behave the same as a contract on L1. - -## The Optimism Portal Contract - -The Optimism Portal serves as both the entry and exit point to the Optimism L2. It is a contract which inherits from -the [OptimismPortal](./deposits.md#deposit-contract) contract, and in addition provides the following interface for -withdrawals: - -- [`WithdrawalTransaction` type] -- [`OutputRootProof` type] - -```js -interface OptimismPortal { - - event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); - - - function l2Sender() returns(address) external; - - function proveWithdrawalTransaction( - Types.WithdrawalTransaction memory _tx, - uint256 _l2OutputIndex, - Types.OutputRootProof calldata _outputRootProof, - bytes[] calldata _withdrawalProof - ) external; - - function finalizeWithdrawalTransaction( - Types.WithdrawalTransaction memory _tx - ) external; -} -``` - -## Withdrawal Verification and Finalization - -The following inputs are required to prove and finalize a withdrawal: - -- Withdrawal transaction data: - - `nonce`: Nonce for the provided message. - - `sender`: Message sender address on L2. - - `target`: Target address on L1. - - `value`: ETH to send to the target. - - `data`: Data to send to the target. - - `gasLimit`: Gas to be forwarded to the target. -- Proof and verification data: - - `l2OutputIndex`: The index in the L2 outputs where the applicable output root may be found. - - `outputRootProof`: Four `bytes32` values which are used to derive the output root. - - `withdrawalProof`: An inclusion proof for the given withdrawal in the L2ToL1MessagePasser contract. - -These inputs must satisfy the following conditions: - -1. The `l2OutputIndex` must be the index in the L2 outputs that contains the applicable output root. -1. `L2OutputOracle.getL2Output(l2OutputIndex)` returns a non-zero `OutputProposal`. -1. The keccak256 hash of the `outputRootProof` values is equal to the `outputRoot`. -1. The `withdrawalProof` is a valid inclusion proof demonstrating that a hash of the Withdrawal transaction data - is contained in the storage of the L2ToL1MessagePasser contract on L2. - -## Security Considerations - -### Key Properties of Withdrawal Verification - -1. It should not be possible to 'double spend' a withdrawal, ie. to relay a withdrawal on L1 which does not - correspond to a message initiated on L2. For reference, see [this writeup][polygon-dbl-spend] of a vulnerability - of this type found on Polygon. - - [polygon-dbl-spend]: https://gerhard-wagner.medium.com/double-spending-bug-in-polygons-plasma-bridge-2e0954ccadf1 - -1. For each withdrawal initiated on L2 (i.e. with a unique `messageNonce()`), the following properties must hold: - 1. It should only be possible to prove the withdrawal once, unless the outputRoot for the withdrawal - has changed. - 1. It should only be possible to finalize the withdrawal once. - 1. It should not be possible to relay the message with any of its fields modified, ie. - 1. Modifying the `sender` field would enable a 'spoofing' attack. - 1. Modifying the `target`, `data`, or `value` fields would enable an attacker to dangerously change the - intended outcome of the withdrawal. - 1. Modifying the `gasLimit` could make the cost of relaying too high, or allow the relayer to cause execution - to fail (out of gas) in the `target`. - -### Handling Successfully Verified Messages That Fail When Relayed - -If the execution of the relayed call fails in the `target` contract, it is unfortunately not possible to determine -whether or not it was 'supposed' to fail, and whether or not it should be 'replayable'. For this reason, and to -minimize complexity, we have not provided any replay functionality, this may be implemented in external utility -contracts if desired. - -[`WithdrawalTransaction` type]: https://github.com/ethereum-optimism/optimism/blob/08daf8dbd38c9ffdbd18fc9a211c227606cdb0ad/packages/contracts-bedrock/src/libraries/Types.sol#L62-L69 -[`OutputRootProof` type]: https://github.com/ethereum-optimism/optimism/blob/08daf8dbd38c9ffdbd18fc9a211c227606cdb0ad/packages/contracts-bedrock/src/libraries/Types.sol#L25-L30 - -### OptimismPortal can send abitrary messages on L1 - -The `L2ToL1MessagePasser` contract's `initiateWithdrawal` function accepts a `_target` address and `_data` bytes, -which is passed to a `CALL` opcode on L1 when `finalizeWithdrawalTransaction` is called after the challenge -period. This means that, by design, the `OptimismPortal` contract can be used to send arbitrary transactions on -the L1, with the `OptimismPortal` as the `msg.sender`. - -This means users of the `OptimismPortal` contract should be careful what permissions they grant to the portal. -For example, any ERC20 tokens mistakenly sent to the `OptimismPortal` contract are essentially lost, as they can -be claimed by anybody that pre-approves transfers of this token out of the portal, using the L2 to initiate the -approval and the L1 to prove and finalize the approval (after the challenge period). diff --git a/ufm-test-services/README.md b/ufm-test-services/README.md index 80eea8522613..6ff6959858c4 100644 --- a/ufm-test-services/README.md +++ b/ufm-test-services/README.md @@ -12,9 +12,9 @@ Starting from left to right in the above diagram: 1. Github Workflow files are created for each time interval Test Services should be ran - All Test Services that should be ran for a specific time interval (e.g. 1 hour) should be defined in the same Github Workflow file -2. Github will run a workflow at it's specified time interval, triggering all of it's defined Test Services to run +2. Github will run a workflow at its specified time interval, triggering all of it's defined Test Services to run 3. `docker-compose.yml` builds and runs each Test Service, setting any environment variables that can be sourced from Github secrets -4. Each Test Service will run it's defined tasks, generate it's metrics, and push them to an already deployed instance of Prometheus Pushgateway +4. Each Test Service will run its defined tasks, generate its metrics, and push them to an already deployed instance of Prometheus Pushgateway 5. An already deployed instance of Prometheus will scrape the Pushgateway for metrics 6. An already deployed Grafana dashboard will query Prometheus for metric data to display @@ -59,7 +59,7 @@ Starting from left to right in the above diagram: - `PROMETHEUS_SERVER_URL` and `PROMETHEUS_PUSHGATEWAY_URL` 3. You'll need to setup some sort of scheduler to run your Test Services at specific time intervals - For Linux/MacOS this can be accomplished using `cron` - - Edit your `cron` job file using `crontrab -e` + - Edit your `cron` job file using `crontab -e` - Here is some example code to get you started, also found in `crontab.example` file: ```bash # Needs to point to docker, otherwise you'll get the error: exec: "docker": executable file not found in $PATH @@ -71,7 +71,7 @@ Starting from left to right in the above diagram: # Runs every 1 day 0 12 * * * /usr/local/bin/docker-compose -f /path/to/docker-compose.yml --profile 1day up -d - # Runs every 7 day + # Runs every 7 days 0 12 */7 * * /usr/local/bin/docker-compose -f /path/to/docker-compose.yml --profile 7day up -d ``` @@ -84,4 +84,4 @@ Starting from left to right in the above diagram: ## Test Services -If you're trying to run a specific Test Service, make sure to check our their `README.md`s, as they may have some required prerequisites to setup before they'll run as expected +If you're trying to run a specific Test Service, make sure to check out their `README.md`s, as they may have some required prerequisites to setup before they'll run as expected diff --git a/ufm-test-services/metamask/Dockerfile b/ufm-test-services/metamask/Dockerfile index 1e9631470ab0..58632416a992 100644 --- a/ufm-test-services/metamask/Dockerfile +++ b/ufm-test-services/metamask/Dockerfile @@ -7,6 +7,8 @@ WORKDIR /app # Update PATH ENV PATH /app/node_modules/.bin:$PATH +RUN npm i -g pnpm + RUN if [ "$METAMASK_PLAYWRIGHT_RUN_HEADLESS" != "false" ]; then \ apt-get update && \ apt-get install -y xvfb && \ @@ -14,8 +16,8 @@ RUN if [ "$METAMASK_PLAYWRIGHT_RUN_HEADLESS" != "false" ]; then \ fi # Copy necessary files and directories -COPY package.json /app/ -RUN npm install +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml /app/ +RUN pnpm install --frozen-lockfile --ignore-scripts COPY tests /app/tests/ COPY playwright.config.ts /app/ COPY start.sh /app/ diff --git a/ufm-test-services/metamask/package.json b/ufm-test-services/metamask/package.json index 5e42934b74f4..4e4c6a5a5ecd 100644 --- a/ufm-test-services/metamask/package.json +++ b/ufm-test-services/metamask/package.json @@ -14,20 +14,27 @@ "clean": "rm -rf node_modules packages/*/node_modules && echo 'Finished cleaning'", "lint": "prettier --check .", "lint:fix": "prettier --write .", - "start:metamask-dapp": "npx static-server node_modules/@metamask/test-dapp/dist --port 9011", + "start:metamask-dapp": "npx serve -l 9011 node_modules/@metamask/test-dapp/dist", "test": "npx playwright test" }, "devDependencies": { - "@metamask/test-dapp": "^7.1.0", - "@playwright/test": "1.37.1", - "@synthetixio/synpress": "3.7.2-beta.7", + "@metamask/test-dapp": "^8.1.0", + "@playwright/test": "1.40.1", + "@synthetixio/synpress": "3.7.2-beta.9", "dotenv": "^16.3.1", - "static-server": "^2.2.1", - "typescript": "^5.1.6", - "viem": "^1.10.8" + "serve": "^14.2.1", + "typescript": "^5.3.3", + "viem": "^1.20.0" }, "dependencies": { - "prom-client": "^14.2.0", - "zod": "^3.22.2" + "prom-client": "^15.0.0", + "zod": "^3.22.4" + }, + "pnpm": { + "overrides": { + "@cypress/request": "^3.0.1", + "axios": "^1.6.2", + "got": "^11.8.6" + } } } diff --git a/ufm-test-services/metamask/pnpm-lock.yaml b/ufm-test-services/metamask/pnpm-lock.yaml index 99b1aa1b35ed..2a7105f9ca7c 100644 --- a/ufm-test-services/metamask/pnpm-lock.yaml +++ b/ufm-test-services/metamask/pnpm-lock.yaml @@ -4,47 +4,48 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@cypress/request': ^3.0.1 + axios: ^1.6.2 + got: ^11.8.6 + importers: .: dependencies: prom-client: - specifier: ^14.2.0 - version: 14.2.0 + specifier: ^15.0.0 + version: 15.0.0 zod: - specifier: ^3.22.2 - version: 3.22.3 + specifier: ^3.22.4 + version: 3.22.4 devDependencies: '@metamask/test-dapp': - specifier: ^7.1.0 - version: 7.1.0 + specifier: ^8.1.0 + version: 8.1.0 '@playwright/test': - specifier: 1.37.1 - version: 1.37.1 + specifier: 1.40.1 + version: 1.40.1 '@synthetixio/synpress': - specifier: 3.7.2-beta.7 - version: 3.7.2-beta.7(@babel/core@7.22.20)(@babel/preset-env@7.22.20)(babel-loader@9.1.3)(react-dom@18.2.0)(react@18.2.0)(typescript@5.1.6)(webpack@5.88.2)(zod@3.22.3) + specifier: 3.7.2-beta.9 + version: 3.7.2-beta.9(@babel/core@7.23.6)(@babel/preset-env@7.23.6)(babel-loader@9.1.3)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)(webpack@5.89.0)(zod@3.22.4) dotenv: specifier: ^16.3.1 version: 16.3.1 - static-server: - specifier: ^2.2.1 - version: 2.2.1 + serve: + specifier: ^14.2.1 + version: 14.2.1 typescript: - specifier: ^5.1.6 - version: 5.1.6 + specifier: ^5.3.3 + version: 5.3.3 viem: - specifier: ^1.10.8 - version: 1.10.8(typescript@5.1.6)(zod@3.22.3) + specifier: ^1.20.0 + version: 1.20.0(typescript@5.3.3)(zod@3.22.4) packages: - /@adraffy/ens-normalize@1.9.2: - resolution: {integrity: sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg==} - dev: true - - /@adraffy/ens-normalize@1.9.4: - resolution: {integrity: sha512-UK0bHA7hh9cR39V+4gl2/NnBBjoXIxkuWAPCaY4X7fbH4L/azIi7ilWOCjMUYfpJgraLUAqkRi2BqrjME8Rynw==} + /@adraffy/ens-normalize@1.10.0: + resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} dev: true /@ampproject/remapping@2.2.1: @@ -52,37 +53,37 @@ packages: engines: {node: '>=6.0.0'} dependencies: '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 dev: true - /@babel/code-frame@7.22.13: - resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.22.13 + '@babel/highlight': 7.23.4 chalk: 2.4.2 dev: true - /@babel/compat-data@7.22.20: - resolution: {integrity: sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==} + /@babel/compat-data@7.23.5: + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} engines: {node: '>=6.9.0'} dev: true - /@babel/core@7.22.20: - resolution: {integrity: sha512-Y6jd1ahLubuYweD/zJH+vvOY141v4f9igNQAQ+MBgq9JlHS2iTsZKn1aMsb3vGccZsXI16VzTBw52Xx0DWmtnA==} + /@babel/core@7.23.6: + resolution: {integrity: sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.22.15 - '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-module-transforms': 7.22.20(@babel/core@7.22.20) - '@babel/helpers': 7.22.15 - '@babel/parser': 7.22.16 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.6) + '@babel/helpers': 7.23.6 + '@babel/parser': 7.23.6 '@babel/template': 7.22.15 - '@babel/traverse': 7.23.2 - '@babel/types': 7.22.19 - convert-source-map: 1.9.0 + '@babel/traverse': 7.23.6 + '@babel/types': 7.23.6 + convert-source-map: 2.0.0 debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 @@ -91,23 +92,13 @@ packages: - supports-color dev: true - /@babel/generator@7.22.15: - resolution: {integrity: sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==} + /@babel/generator@7.23.6: + resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.19 + '@babel/types': 7.23.6 '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 - jsesc: 2.5.2 - dev: true - - /@babel/generator@7.23.0: - resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.0 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 jsesc: 2.5.2 dev: true @@ -115,68 +106,68 @@ packages: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true - /@babel/helper-compilation-targets@7.22.15: - resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} + /@babel/helper-compilation-targets@7.23.6: + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.22.20 - '@babel/helper-validator-option': 7.22.15 - browserslist: 4.21.10 + '@babel/compat-data': 7.23.5 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.22.2 lru-cache: 5.1.1 semver: 6.3.1 dev: true - /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==} + /@babel/helper-create-class-features-plugin@7.23.6(@babel/core@7.23.6): + resolution: {integrity: sha512-cBXU1vZni/CpGF29iTu4YRbOZt3Wat6zCoMDxRF1MayiEc4URxOj31tT65HUM0CRpMowA3HCJaAOVOUnMf96cw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 - '@babel/helper-member-expression-to-functions': 7.22.15 + '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.22.20) + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.6) '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 semver: 6.3.1 dev: true - /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.22.20): + /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.6): resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-annotate-as-pure': 7.22.5 regexpu-core: 5.3.2 semver: 6.3.1 dev: true - /@babel/helper-define-polyfill-provider@0.4.2(@babel/core@7.22.20): - resolution: {integrity: sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==} + /@babel/helper-define-polyfill-provider@0.4.4(@babel/core@7.23.6): + resolution: {integrity: sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-compilation-targets': 7.22.15 + '@babel/core': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 debug: 4.3.4(supports-color@8.1.1) lodash.debounce: 4.0.8 - resolve: 1.22.6 + resolve: 1.22.8 transitivePeerDependencies: - supports-color dev: true @@ -191,37 +182,37 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.15 - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true - /@babel/helper-member-expression-to-functions@7.22.15: - resolution: {integrity: sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==} + /@babel/helper-member-expression-to-functions@7.23.0: + resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.19 + '@babel/types': 7.23.6 dev: true - /@babel/helper-module-transforms@7.22.20(@babel/core@7.22.20): - resolution: {integrity: sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A==} + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 @@ -233,7 +224,7 @@ packages: resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-plugin-utils@7.22.5: @@ -241,27 +232,27 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.22.20): + /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.6): resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-wrap-function': 7.22.20 dev: true - /@babel/helper-replace-supers@7.22.20(@babel/core@7.22.20): + /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.6): resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-member-expression-to-functions': 7.22.15 + '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 dev: true @@ -269,25 +260,25 @@ packages: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.19 + '@babel/types': 7.23.6 dev: true /@babel/helper-skip-transparent-expression-wrappers@7.22.5: resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true - /@babel/helper-string-parser@7.22.5: - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} engines: {node: '>=6.9.0'} dev: true @@ -296,8 +287,8 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-validator-option@7.22.15: - resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} dev: true @@ -307,22 +298,22 @@ packages: dependencies: '@babel/helper-function-name': 7.23.0 '@babel/template': 7.22.15 - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true - /@babel/helpers@7.22.15: - resolution: {integrity: sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==} + /@babel/helpers@7.23.6: + resolution: {integrity: sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.15 - '@babel/traverse': 7.23.2 - '@babel/types': 7.22.19 + '@babel/traverse': 7.23.6 + '@babel/types': 7.23.6 transitivePeerDependencies: - supports-color dev: true - /@babel/highlight@7.22.13: - resolution: {integrity: sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==} + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-validator-identifier': 7.22.20 @@ -330,853 +321,857 @@ packages: js-tokens: 4.0.0 dev: true - /@babel/parser@7.22.16: - resolution: {integrity: sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==} + /@babel/parser@7.23.6: + resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.22.19 + '@babel/types': 7.23.6 dev: true - /@babel/parser@7.23.0: - resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.23.0 - dev: true - - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==} + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==} + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-transform-optional-chaining': 7.22.15(@babel/core@7.22.20) + '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.6) + dev: true + + /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.20): + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.6): resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.20): + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.6): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.20): + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.6): resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.22.20): + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.6): resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.22.20): + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.6): resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.20): + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.6): resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==} + /@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==} + /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.20): + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.6): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.20): + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.6): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.20): + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.6): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.20): + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.6): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.20): + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.6): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.20): + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.6): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.20): + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.6): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.20): + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.6): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.22.20): + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.6): resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.20): + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.6): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.22.20): + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.6): resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==} + /@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-async-generator-functions@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==} + /@babel/plugin-transform-async-generator-functions@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.22.20) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.20) + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.6) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==} + /@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.22.20) + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==} + /@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-block-scoping@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-G1czpdJBZCtngoK1sJgloLiOHUnkb/bLZwqVZD8kXmq0ZnVfTTWUcs9OWtp0mBtYJ+4LQY1fllqBkOIPhXmFmw==} + /@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==} + /@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-create-class-features-plugin': 7.23.6(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.22.20): - resolution: {integrity: sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==} + /@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-create-class-features-plugin': 7.23.6(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.20) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-classes@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==} + /@babel/plugin-transform-classes@7.23.5(@babel/core@7.23.6): + resolution: {integrity: sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.22.20) + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.6) '@babel/helper-split-export-declaration': 7.22.6 globals: 11.12.0 dev: true - /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==} + /@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 '@babel/template': 7.22.15 dev: true - /@babel/plugin-transform-destructuring@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-HzG8sFl1ZVGTme74Nw+X01XsUTqERVQ6/RLHo3XjGRzm7XD6QTtfS3NJotVgCGy8BzkDqRjRBD8dAyJn5TuvSQ==} + /@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==} + /@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==} + /@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-dynamic-import@7.22.11(@babel/core@7.22.20): - resolution: {integrity: sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==} + /@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.20) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==} + /@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-export-namespace-from@7.22.11(@babel/core@7.22.20): - resolution: {integrity: sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==} + /@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.20) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-for-of@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==} + /@babel/plugin-transform-for-of@7.23.6(@babel/core@7.23.6): + resolution: {integrity: sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: true - /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==} + /@babel/plugin-transform-function-name@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-compilation-targets': 7.22.15 + '@babel/core': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-function-name': 7.23.0 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.22.20): - resolution: {integrity: sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==} + /@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.20) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-literals@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==} + /@babel/plugin-transform-literals@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-logical-assignment-operators@7.22.11(@babel/core@7.22.20): - resolution: {integrity: sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==} + /@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.20) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==} + /@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-modules-amd@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==} + /@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-module-transforms': 7.22.20(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-modules-commonjs@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==} + /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-module-transforms': 7.22.20(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-simple-access': 7.22.5 dev: true - /@babel/plugin-transform-modules-systemjs@7.22.11(@babel/core@7.22.20): - resolution: {integrity: sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA==} + /@babel/plugin-transform-modules-systemjs@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.22.20(@babel/core@7.22.20) + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-validator-identifier': 7.22.20 dev: true - /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==} + /@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-module-transforms': 7.22.20(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.22.20): + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.6): resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==} + /@babel/plugin-transform-new-target@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-nullish-coalescing-operator@7.22.11(@babel/core@7.22.20): - resolution: {integrity: sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==} + /@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.20) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-numeric-separator@7.22.11(@babel/core@7.22.20): - resolution: {integrity: sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==} + /@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.20) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-object-rest-spread@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==} + /@babel/plugin-transform-object-rest-spread@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.22.20 - '@babel/core': 7.22.20 - '@babel/helper-compilation-targets': 7.22.15 + '@babel/compat-data': 7.23.5 + '@babel/core': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.20) - '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.22.20) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.6) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==} + /@babel/plugin-transform-object-super@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.22.20) + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.22.20): - resolution: {integrity: sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==} + /@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.20) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-optional-chaining@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-ngQ2tBhq5vvSJw2Q2Z9i7ealNkpDMU0rGWnHPKqRZO0tzZ5tlaoz4hDvhXioOoaE0X2vfNss1djwg0DXlfu30A==} + /@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.20) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-parameters@7.22.15(@babel/core@7.22.20): - resolution: {integrity: sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==} + /@babel/plugin-transform-parameters@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==} + /@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-create-class-features-plugin': 7.23.6(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.22.20): - resolution: {integrity: sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==} + /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.23.6): + resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.22.20) + '@babel/helper-create-class-features-plugin': 7.23.6(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.20) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.6) dev: true - /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==} + /@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.22.20): - resolution: {integrity: sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==} + /@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 regenerator-transform: 0.15.2 dev: true - /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==} + /@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==} + /@babel/plugin-transform-shorthand-properties@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-spread@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==} + /@babel/plugin-transform-spread@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: true - /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==} + /@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==} + /@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==} + /@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-unicode-escapes@7.22.10(@babel/core@7.22.20): - resolution: {integrity: sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==} + /@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==} + /@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==} + /@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.22.20): - resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==} + /@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.6) '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/preset-env@7.22.20(@babel/core@7.22.20): - resolution: {integrity: sha512-11MY04gGC4kSzlPHRfvVkNAZhUxOvm7DCJ37hPDnUENwe06npjIRAfInEMTGSb4LZK5ZgDFkv5hw0lGebHeTyg==} + /@babel/preset-env@7.23.6(@babel/core@7.23.6): + resolution: {integrity: sha512-2XPn/BqKkZCpzYhUUNZ1ssXw7DcXfKQEjv/uXZUXgaebCMYmkEsfZ2yY+vv+xtXv50WmL5SGhyB6/xsWxIvvOQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.22.20 - '@babel/core': 7.22.20 - '@babel/helper-compilation-targets': 7.22.15 + '@babel/compat-data': 7.23.5 + '@babel/core': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.22.15 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.20) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.20) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.20) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.20) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.20) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.20) - '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.20) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.20) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.20) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.20) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.20) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.20) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.20) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.20) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.20) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.20) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.22.20) - '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-async-generator-functions': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-block-scoping': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-class-static-block': 7.22.11(@babel/core@7.22.20) - '@babel/plugin-transform-classes': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-destructuring': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-dynamic-import': 7.22.11(@babel/core@7.22.20) - '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-export-namespace-from': 7.22.11(@babel/core@7.22.20) - '@babel/plugin-transform-for-of': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-json-strings': 7.22.11(@babel/core@7.22.20) - '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-logical-assignment-operators': 7.22.11(@babel/core@7.22.20) - '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-modules-amd': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-modules-commonjs': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-transform-modules-systemjs': 7.22.11(@babel/core@7.22.20) - '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-nullish-coalescing-operator': 7.22.11(@babel/core@7.22.20) - '@babel/plugin-transform-numeric-separator': 7.22.11(@babel/core@7.22.20) - '@babel/plugin-transform-object-rest-spread': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-optional-catch-binding': 7.22.11(@babel/core@7.22.20) - '@babel/plugin-transform-optional-chaining': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.22.20) - '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-private-property-in-object': 7.22.11(@babel/core@7.22.20) - '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-regenerator': 7.22.10(@babel/core@7.22.20) - '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-unicode-escapes': 7.22.10(@babel/core@7.22.20) - '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.22.20) - '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.22.20) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.22.20) - '@babel/types': 7.23.0 - babel-plugin-polyfill-corejs2: 0.4.5(@babel/core@7.22.20) - babel-plugin-polyfill-corejs3: 0.8.3(@babel/core@7.22.20) - babel-plugin-polyfill-regenerator: 0.5.2(@babel/core@7.22.20) - core-js-compat: 3.32.2 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.6) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.6) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.6) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.6) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.6) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.6) + '@babel/plugin-syntax-import-assertions': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.6) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.6) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.6) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.6) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.6) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.6) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.6) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.6) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.6) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.6) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.6) + '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-async-generator-functions': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-classes': 7.23.5(@babel/core@7.23.6) + '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-dotall-regex': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-duplicate-keys': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-dynamic-import': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-exponentiation-operator': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-for-of': 7.23.6(@babel/core@7.23.6) + '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-json-strings': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-logical-assignment-operators': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-modules-amd': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-modules-systemjs': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-modules-umd': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.6) + '@babel/plugin-transform-new-target': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-numeric-separator': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-object-rest-spread': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-optional-catch-binding': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.23.6) + '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-regenerator': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-reserved-words': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-typeof-symbol': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-unicode-escapes': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-unicode-property-regex': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-unicode-sets-regex': 7.23.3(@babel/core@7.23.6) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.6) + babel-plugin-polyfill-corejs2: 0.4.7(@babel/core@7.23.6) + babel-plugin-polyfill-corejs3: 0.8.7(@babel/core@7.23.6) + babel-plugin-polyfill-regenerator: 0.5.4(@babel/core@7.23.6) + core-js-compat: 3.34.0 semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.22.20): + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.6): resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 esutils: 2.0.3 dev: true @@ -1184,16 +1179,16 @@ packages: resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} dev: true - /@babel/runtime-corejs3@7.22.15: - resolution: {integrity: sha512-SAj8oKi8UogVi6eXQXKNPu8qZ78Yzy7zawrlTr0M+IuW/g8Qe9gVDhGcF9h1S69OyACpYoLxEzpjs1M15sI5wQ==} + /@babel/runtime-corejs3@7.23.6: + resolution: {integrity: sha512-Djs/ZTAnpyj0nyg7p1J6oiE/tZ9G2stqAFlLGZynrW+F3k2w2jGK2mLOBxzYIOcZYA89+c3d3wXKpYLcpwcU6w==} engines: {node: '>=6.9.0'} dependencies: - core-js-pure: 3.32.2 + core-js-pure: 3.34.0 regenerator-runtime: 0.14.0 dev: true - /@babel/runtime@7.22.15: - resolution: {integrity: sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==} + /@babel/runtime@7.23.6: + resolution: {integrity: sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 @@ -1203,43 +1198,34 @@ packages: resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 dev: true - /@babel/traverse@7.23.2: - resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} + /@babel/traverse@7.23.6: + resolution: {integrity: sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.0 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/types@7.22.19: - resolution: {integrity: sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 - dev: true - - /@babel/types@7.23.0: - resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} + /@babel/types@7.23.6: + resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-string-parser': 7.22.5 + '@babel/helper-string-parser': 7.23.4 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 dev: true @@ -1251,8 +1237,8 @@ packages: dev: true optional: true - /@cypress/code-coverage@3.12.0(@babel/core@7.22.20)(@babel/preset-env@7.22.20)(babel-loader@9.1.3)(cypress@12.17.3)(webpack@5.88.2): - resolution: {integrity: sha512-Z4Lk/ckBc9Mv11vXMp1ike5MtIYsHCCu7Wtp4uWTcFEshi9uSbBNS6v2cwhf0beUThph0EXsVtKMi7EFAdM1Mw==} + /@cypress/code-coverage@3.12.14(@babel/core@7.23.6)(@babel/preset-env@7.23.6)(babel-loader@9.1.3)(cypress@12.17.3)(webpack@5.89.0): + resolution: {integrity: sha512-uTlt0cdfohRWkH/HaXHRnyc+uj/Jb2on9V6H6CB6hdQvUfsmvHgTbc+qoqdwVOXI/33ctnreZpLjVkbuH0gYvw==} peerDependencies: '@babel/core': ^7.0.1 '@babel/preset-env': ^7.0.0 @@ -1260,26 +1246,26 @@ packages: cypress: '*' webpack: ^4 || ^5 dependencies: - '@babel/core': 7.22.20 - '@babel/preset-env': 7.22.20(@babel/core@7.22.20) - '@cypress/webpack-preprocessor': 5.17.1(@babel/core@7.22.20)(@babel/preset-env@7.22.20)(babel-loader@9.1.3)(webpack@5.88.2) - babel-loader: 9.1.3(@babel/core@7.22.20)(webpack@5.88.2) + '@babel/core': 7.23.6 + '@babel/preset-env': 7.23.6(@babel/core@7.23.6) + '@cypress/webpack-preprocessor': 6.0.0(@babel/core@7.23.6)(@babel/preset-env@7.23.6)(babel-loader@9.1.3)(webpack@5.89.0) + babel-loader: 9.1.3(@babel/core@7.23.6)(webpack@5.89.0) chalk: 4.1.2 cypress: 12.17.3 - dayjs: 1.11.9 + dayjs: 1.11.10 debug: 4.3.4(supports-color@8.1.1) execa: 4.1.0 - globby: 11.0.4 - istanbul-lib-coverage: 3.0.0 + globby: 11.1.0 + istanbul-lib-coverage: 3.2.2 js-yaml: 4.1.0 nyc: 15.1.0 - webpack: 5.88.2 + webpack: 5.89.0 transitivePeerDependencies: - supports-color dev: true - /@cypress/request@2.88.12: - resolution: {integrity: sha512-tOn+0mDZxASFM+cuAP9szGUGPI1HwWVSvdzm7V4cCsPdFTx6qMj29CwaQmRAMIEhORIUBFBsYROYJcveK4uOjA==} + /@cypress/request@3.0.1: + resolution: {integrity: sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==} engines: {node: '>= 6'} dependencies: aws-sign2: 0.7.0 @@ -1302,19 +1288,19 @@ packages: uuid: 8.3.2 dev: true - /@cypress/webpack-dev-server@3.6.1(debug@4.3.4)(webpack@5.88.2): - resolution: {integrity: sha512-v9tn8SW5ot9jxlei0LqnU1hmR8Cy/A4mOKJOmrcU8KI0qWH6cadwmtiifRMgn8obQCJxiBSAeSWP3l2P4XoSAA==} + /@cypress/webpack-dev-server@3.7.1(debug@4.3.4)(webpack@5.89.0): + resolution: {integrity: sha512-f2S0VWpYhryyaliJiPdESeF+nOi/t2mPargRS8hVToJHQHbfiGPPFcjsz0Wz39jSuBYNhX7D3ylnaU2USSZ1EA==} dependencies: find-up: 6.3.0 fs-extra: 9.1.0 - html-webpack-plugin-4: /html-webpack-plugin@4.5.2(webpack@5.88.2) - html-webpack-plugin-5: /html-webpack-plugin@5.5.3(webpack@5.88.2) + html-webpack-plugin-4: /html-webpack-plugin@4.5.2(webpack@5.89.0) + html-webpack-plugin-5: /html-webpack-plugin@5.5.4(webpack@5.89.0) local-pkg: 0.4.1 semver: 7.5.4 - speed-measure-webpack-plugin: 1.4.2(webpack@5.88.2) + speed-measure-webpack-plugin: 1.4.2(webpack@5.89.0) tslib: 2.6.2 - webpack-dev-server: 4.15.1(debug@4.3.4)(webpack@5.88.2) - webpack-merge: 5.9.0 + webpack-dev-server: 4.15.1(debug@4.3.4)(webpack@5.89.0) + webpack-merge: 5.10.0 transitivePeerDependencies: - bufferutil - debug @@ -1324,21 +1310,21 @@ packages: - webpack-cli dev: true - /@cypress/webpack-preprocessor@5.17.1(@babel/core@7.22.20)(@babel/preset-env@7.22.20)(babel-loader@9.1.3)(webpack@5.88.2): - resolution: {integrity: sha512-FE/e8ikPc8z4EVopJCaior3RGy0jd2q9Xcp5NtiwNG4XnLfEnUFTZlAGwXe75sEh4fNMPrBJW1KIz77PX5vGAw==} + /@cypress/webpack-preprocessor@6.0.0(@babel/core@7.23.6)(@babel/preset-env@7.23.6)(babel-loader@9.1.3)(webpack@5.89.0): + resolution: {integrity: sha512-1AS1Et5CNPJii0+DdBZBS8e0hlM2BkBNmYRdZO4/16A3KS3em1sjPZtFw7jJF00m6DYAdB9iy6QW/lLZ2bN0gg==} peerDependencies: '@babel/core': ^7.0.1 '@babel/preset-env': ^7.0.0 - babel-loader: ^8.0.2 || ^9 + babel-loader: ^8.3 || ^9 webpack: ^4 || ^5 dependencies: - '@babel/core': 7.22.20 - '@babel/preset-env': 7.22.20(@babel/core@7.22.20) - babel-loader: 9.1.3(@babel/core@7.22.20)(webpack@5.88.2) + '@babel/core': 7.23.6 + '@babel/preset-env': 7.23.6(@babel/core@7.23.6) + babel-loader: 9.1.3(@babel/core@7.23.6)(webpack@5.89.0) bluebird: 3.7.1 debug: 4.3.4(supports-color@8.1.1) lodash: 4.17.21 - webpack: 5.88.2 + webpack: 5.89.0 transitivePeerDependencies: - supports-color dev: true @@ -1356,7 +1342,7 @@ packages: resolution: {integrity: sha512-VWsdOZTsu8ABNVplFQUniHSLsCAQIJh+HDTUP6CllxXBe2pgFQKQ6RGxAS/QRTUcPprQCGpB3zH+gqNnvRRTmQ==} dependencies: chance: 1.1.11 - core-js: 3.32.2 + core-js: 3.34.0 dev: true /@foundry-rs/easy-foundryup@0.1.3: @@ -1396,10 +1382,10 @@ packages: resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==} engines: {node: '>= 10.14.2'} dependencies: - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.1 - '@types/node': 20.6.3 - '@types/yargs': 15.0.15 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.10.4 + '@types/yargs': 15.0.19 chalk: 4.1.2 dev: true @@ -1409,7 +1395,7 @@ packages: dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 dev: true /@jridgewell/resolve-uri@3.1.1: @@ -1426,15 +1412,15 @@ packages: resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} dependencies: '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} dev: true - /@jridgewell/trace-mapping@0.3.19: - resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + /@jridgewell/trace-mapping@0.3.20: + resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} dependencies: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 @@ -1444,9 +1430,9 @@ packages: resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==} dev: true - /@metamask/test-dapp@7.1.0: - resolution: {integrity: sha512-uqnno8JmpNMuyxDqQ6rq8+T9hf6Rsuy7rJnHHQd0RFRmva02v6N8rJZpEmftM61ciAaMolSB8XbZPPRsMIdQ8w==} - engines: {node: '>= 16.0.0'} + /@metamask/test-dapp@8.1.0: + resolution: {integrity: sha512-NM6o8EpIyT7ZhTDPf4rfLoklzpsWZ9DSA3iNJ/XdmrQY+D3dZVhwIpJBhNJqC4MSB+gAC4qqRKimTkWnoVhBHQ==} + engines: {node: '>= 18.0.0'} dev: true /@noble/curves@1.2.0: @@ -1455,19 +1441,11 @@ packages: '@noble/hashes': 1.3.2 dev: true - /@noble/hashes@1.1.2: - resolution: {integrity: sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==} - dev: true - /@noble/hashes@1.3.2: resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} engines: {node: '>= 16'} dev: true - /@noble/secp256k1@1.7.1: - resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} - dev: true - /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1489,19 +1467,21 @@ packages: fastq: 1.15.0 dev: true - /@playwright/test@1.37.1: - resolution: {integrity: sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==} + /@opentelemetry/api@1.7.0: + resolution: {integrity: sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==} + engines: {node: '>=8.0.0'} + dev: false + + /@playwright/test@1.40.1: + resolution: {integrity: sha512-EaaawMTOeEItCRvfmkI9v6rBkF1svM8wjl/YPRrg2N2Wmp+4qJYkWtJsbew1szfKKDm6fPLy4YAanBhIlf9dWw==} engines: {node: '>=16'} hasBin: true dependencies: - '@types/node': 20.6.0 - playwright-core: 1.37.1 - optionalDependencies: - fsevents: 2.3.2 + playwright: 1.40.1 dev: true - /@scure/base@1.1.3: - resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} + /@scure/base@1.1.5: + resolution: {integrity: sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==} dev: true /@scure/bip32@1.3.2: @@ -1509,14 +1489,14 @@ packages: dependencies: '@noble/curves': 1.2.0 '@noble/hashes': 1.3.2 - '@scure/base': 1.1.3 + '@scure/base': 1.1.5 dev: true /@scure/bip39@1.2.1: resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} dependencies: '@noble/hashes': 1.3.2 - '@scure/base': 1.1.3 + '@scure/base': 1.1.5 dev: true /@sideway/address@4.1.4: @@ -1533,48 +1513,48 @@ packages: resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} dev: true - /@sindresorhus/is@0.7.0: - resolution: {integrity: sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==} - engines: {node: '>=4'} + /@sindresorhus/is@4.6.0: + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} dev: true - /@synthetixio/synpress@3.7.2-beta.7(@babel/core@7.22.20)(@babel/preset-env@7.22.20)(babel-loader@9.1.3)(react-dom@18.2.0)(react@18.2.0)(typescript@5.1.6)(webpack@5.88.2)(zod@3.22.3): - resolution: {integrity: sha512-V5Z59fbzMIv3BVjzfMElD+eR+3C1q3mKPR6RJh9C0GpAnsBLtH2c2cPgBV2QgHBdmaJLFxEQBBud6Sb05w2jcw==} + /@synthetixio/synpress@3.7.2-beta.9(@babel/core@7.23.6)(@babel/preset-env@7.23.6)(babel-loader@9.1.3)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)(webpack@5.89.0)(zod@3.22.4): + resolution: {integrity: sha512-1fnr3jzQA2op6YnXxx6ERZ4babB+Ib1Xc5URGTcndH891Oa5uVlIaP0zRm5udTJuNdENOTLgkAdjv4WTGurBVA==} engines: {node: '>=14'} hasBin: true dependencies: - '@cypress/code-coverage': 3.12.0(@babel/core@7.22.20)(@babel/preset-env@7.22.20)(babel-loader@9.1.3)(cypress@12.17.3)(webpack@5.88.2) - '@cypress/webpack-dev-server': 3.6.1(debug@4.3.4)(webpack@5.88.2) + '@cypress/code-coverage': 3.12.14(@babel/core@7.23.6)(@babel/preset-env@7.23.6)(babel-loader@9.1.3)(cypress@12.17.3)(webpack@5.89.0) + '@cypress/webpack-dev-server': 3.7.1(debug@4.3.4)(webpack@5.89.0) '@drptbl/gremlins.js': 2.2.1 '@foundry-rs/easy-foundryup': 0.1.3 - '@playwright/test': 1.37.1 + '@playwright/test': 1.40.1 '@testing-library/cypress': 9.0.0(cypress@12.17.3) - '@testing-library/react': 14.0.0(react-dom@18.2.0)(react@18.2.0) - '@types/testing-library__cypress': 5.0.9 + '@testing-library/react': 14.1.2(react-dom@18.2.0)(react@18.2.0) + '@types/testing-library__cypress': 5.0.13 '@viem/anvil': 0.0.6(debug@4.3.4) app-root-path: 3.1.0 - axios: 1.5.0(debug@4.3.4) + axios: 1.6.2(debug@4.3.4) babel-plugin-istanbul: 6.1.1 babel-plugin-react-generate-property: 1.1.2 babel-plugin-react-remove-properties: 0.3.0 babel-plugin-transform-react-qa-classes: 1.6.0 babel-plugin-transform-react-styled-components-qa: 2.1.0 bytes32: 0.0.3 - commander: 11.0.0 + commander: 11.1.0 cypress: 12.17.3 cypress-wait-until: 2.0.1 debug: 4.3.4(supports-color@8.1.1) dotenv: 16.3.1 dotenv-parse-variables: 2.0.0 download: 8.0.0 - ethers: 6.7.1 + ethers: 6.9.0 etherscan-api: 10.3.0(debug@4.3.4) find-config: 1.0.0 get-port: 7.0.0 node-fetch: 2.7.0 underscore: 1.13.6 - viem: 1.10.8(typescript@5.1.6)(zod@3.22.3) - wait-on: 7.0.1(debug@4.3.4) + viem: 1.20.0(typescript@5.3.3)(zod@3.22.4) + wait-on: 7.2.0(debug@4.3.4) transitivePeerDependencies: - '@babel/core' - '@babel/preset-env' @@ -1591,13 +1571,20 @@ packages: - zod dev: true + /@szmarczak/http-timer@4.0.6: + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + dependencies: + defer-to-connect: 2.0.1 + dev: true + /@testing-library/cypress@9.0.0(cypress@12.17.3): resolution: {integrity: sha512-c1XiCGeHGGTWn0LAU12sFUfoX3qfId5gcSE2yHode+vsyHDWraxDPALjVnHd4/Fa3j4KBcc5k++Ccy6A9qnkMA==} engines: {node: '>=12', npm: '>=6'} peerDependencies: cypress: ^12.0.0 dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.6 '@testing-library/dom': 8.20.1 cypress: 12.17.3 dev: true @@ -1606,8 +1593,8 @@ packages: resolution: {integrity: sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==} engines: {node: '>=10'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/runtime': 7.22.15 + '@babel/code-frame': 7.23.5 + '@babel/runtime': 7.23.6 '@types/aria-query': 4.2.2 aria-query: 4.2.2 chalk: 4.1.2 @@ -1620,9 +1607,9 @@ packages: resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==} engines: {node: '>=12'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/runtime': 7.22.15 - '@types/aria-query': 5.0.1 + '@babel/code-frame': 7.23.5 + '@babel/runtime': 7.23.6 + '@types/aria-query': 5.0.4 aria-query: 5.1.3 chalk: 4.1.2 dom-accessibility-api: 0.5.16 @@ -1630,13 +1617,13 @@ packages: pretty-format: 27.5.1 dev: true - /@testing-library/dom@9.3.1: - resolution: {integrity: sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==} + /@testing-library/dom@9.3.3: + resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==} engines: {node: '>=14'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/runtime': 7.22.15 - '@types/aria-query': 5.0.1 + '@babel/code-frame': 7.23.5 + '@babel/runtime': 7.23.6 + '@types/aria-query': 5.0.4 aria-query: 5.1.3 chalk: 4.1.2 dom-accessibility-api: 0.5.16 @@ -1644,16 +1631,16 @@ packages: pretty-format: 27.5.1 dev: true - /@testing-library/react@14.0.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-S04gSNJbYE30TlIMLTzv6QCTzt9AqIF5y6s6SzVFILNcNvbV/jU96GeiTPillGQo+Ny64M/5PV7klNYYgv5Dfg==} + /@testing-library/react@14.1.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-z4p7DVBTPjKM5qDZ0t5ZjzkpSNb+fZy1u6bzO7kk8oeGagpPCAtgh4cx1syrfp7a+QWkM021jGqjJaxJJnXAZg==} engines: {node: '>=14'} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 dependencies: - '@babel/runtime': 7.22.15 - '@testing-library/dom': 9.3.1 - '@types/react-dom': 18.2.7 + '@babel/runtime': 7.23.6 + '@testing-library/dom': 9.3.3 + '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true @@ -1662,70 +1649,79 @@ packages: resolution: {integrity: sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==} dev: true - /@types/aria-query@5.0.1: - resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} + /@types/aria-query@5.0.4: + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + dev: true + + /@types/body-parser@1.19.5: + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.10.4 dev: true - /@types/body-parser@1.19.2: - resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} + /@types/bonjour@3.5.13: + resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} dependencies: - '@types/connect': 3.4.36 - '@types/node': 20.6.3 + '@types/node': 20.10.4 dev: true - /@types/bonjour@3.5.10: - resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==} + /@types/cacheable-request@6.0.3: + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} dependencies: - '@types/node': 20.6.3 + '@types/http-cache-semantics': 4.0.4 + '@types/keyv': 3.1.4 + '@types/node': 20.10.4 + '@types/responselike': 1.0.3 dev: true - /@types/connect-history-api-fallback@1.5.1: - resolution: {integrity: sha512-iaQslNbARe8fctL5Lk+DsmgWOM83lM+7FzP0eQUJs1jd3kBE8NWqBTIT2S8SqQOJjxvt2eyIjpOuYeRXq2AdMw==} + /@types/connect-history-api-fallback@1.5.4: + resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} dependencies: - '@types/express-serve-static-core': 4.17.36 - '@types/node': 20.6.3 + '@types/express-serve-static-core': 4.17.41 + '@types/node': 20.10.4 dev: true - /@types/connect@3.4.36: - resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==} + /@types/connect@3.4.38: + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 20.6.3 + '@types/node': 20.10.4 dev: true - /@types/eslint-scope@3.7.4: - resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} + /@types/eslint-scope@3.7.7: + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} dependencies: - '@types/eslint': 8.44.2 - '@types/estree': 1.0.1 + '@types/eslint': 8.44.9 + '@types/estree': 1.0.5 dev: true - /@types/eslint@8.44.2: - resolution: {integrity: sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==} + /@types/eslint@8.44.9: + resolution: {integrity: sha512-6yBxcvwnnYoYT1Uk2d+jvIfsuP4mb2EdIxFnrPABj5a/838qe5bGkNLFOiipX4ULQ7XVQvTxOh7jO+BTAiqsEw==} dependencies: - '@types/estree': 1.0.1 - '@types/json-schema': 7.0.13 + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 dev: true - /@types/estree@1.0.1: - resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} dev: true - /@types/express-serve-static-core@4.17.36: - resolution: {integrity: sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q==} + /@types/express-serve-static-core@4.17.41: + resolution: {integrity: sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==} dependencies: - '@types/node': 20.6.3 - '@types/qs': 6.9.8 - '@types/range-parser': 1.2.4 - '@types/send': 0.17.1 + '@types/node': 20.10.4 + '@types/qs': 6.9.10 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 dev: true - /@types/express@4.17.17: - resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} + /@types/express@4.17.21: + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} dependencies: - '@types/body-parser': 1.19.2 - '@types/express-serve-static-core': 4.17.36 - '@types/qs': 6.9.8 - '@types/serve-static': 1.15.2 + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.17.41 + '@types/qs': 6.9.10 + '@types/serve-static': 1.15.5 dev: true /@types/html-minifier-terser@5.1.2: @@ -1736,202 +1732,210 @@ packages: resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} dev: true - /@types/http-errors@2.0.1: - resolution: {integrity: sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==} + /@types/http-cache-semantics@4.0.4: + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} dev: true - /@types/http-proxy@1.17.11: - resolution: {integrity: sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==} + /@types/http-errors@2.0.4: + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + dev: true + + /@types/http-proxy@1.17.14: + resolution: {integrity: sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==} dependencies: - '@types/node': 20.6.3 + '@types/node': 20.10.4 dev: true - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} dev: true - /@types/istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + /@types/istanbul-lib-report@3.0.3: + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} dependencies: - '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-lib-coverage': 2.0.6 dev: true - /@types/istanbul-reports@3.0.1: - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + /@types/istanbul-reports@3.0.4: + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} dependencies: - '@types/istanbul-lib-report': 3.0.0 + '@types/istanbul-lib-report': 3.0.3 dev: true - /@types/json-schema@7.0.13: - resolution: {integrity: sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==} + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 20.6.3 + '@types/node': 20.10.4 dev: true - /@types/mime@1.3.2: - resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} + /@types/mime@1.3.5: + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} dev: true - /@types/mime@3.0.1: - resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} + /@types/mime@3.0.4: + resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} dev: true - /@types/node@16.18.50: - resolution: {integrity: sha512-OiDU5xRgYTJ203v4cprTs0RwOCd5c5Zjv+K5P8KSqfiCsB1W3LcamTUMcnQarpq5kOYbhHfSOgIEJvdPyb5xyw==} + /@types/node-forge@1.3.10: + resolution: {integrity: sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==} + dependencies: + '@types/node': 20.10.4 dev: true - /@types/node@18.15.13: - resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} + /@types/node@16.18.68: + resolution: {integrity: sha512-sG3hPIQwJLoewrN7cr0dwEy+yF5nD4D/4FxtQpFciRD/xwUzgD+G05uxZHv5mhfXo4F9Jkp13jjn0CC2q325sg==} dev: true - /@types/node@20.6.0: - resolution: {integrity: sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==} + /@types/node@18.15.13: + resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} dev: true - /@types/node@20.6.3: - resolution: {integrity: sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA==} + /@types/node@20.10.4: + resolution: {integrity: sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==} + dependencies: + undici-types: 5.26.5 dev: true - /@types/prop-types@15.7.5: - resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + /@types/prop-types@15.7.11: + resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} dev: true - /@types/qs@6.9.8: - resolution: {integrity: sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==} + /@types/qs@6.9.10: + resolution: {integrity: sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==} dev: true - /@types/range-parser@1.2.4: - resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} + /@types/range-parser@1.2.7: + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} dev: true - /@types/react-dom@18.2.7: - resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} + /@types/react-dom@18.2.17: + resolution: {integrity: sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==} dependencies: - '@types/react': 18.2.21 + '@types/react': 18.2.45 dev: true - /@types/react@18.2.21: - resolution: {integrity: sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==} + /@types/react@18.2.45: + resolution: {integrity: sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg==} dependencies: - '@types/prop-types': 15.7.5 - '@types/scheduler': 0.16.3 - csstype: 3.1.2 + '@types/prop-types': 15.7.11 + '@types/scheduler': 0.16.8 + csstype: 3.1.3 dev: true - /@types/responselike@1.0.0: - resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} + /@types/responselike@1.0.3: + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} dependencies: - '@types/node': 20.6.3 + '@types/node': 20.10.4 dev: true /@types/retry@0.12.0: resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} dev: true - /@types/scheduler@0.16.3: - resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} + /@types/scheduler@0.16.8: + resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} dev: true - /@types/send@0.17.1: - resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} + /@types/send@0.17.4: + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} dependencies: - '@types/mime': 1.3.2 - '@types/node': 20.6.3 + '@types/mime': 1.3.5 + '@types/node': 20.10.4 dev: true - /@types/serve-index@1.9.1: - resolution: {integrity: sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==} + /@types/serve-index@1.9.4: + resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} dependencies: - '@types/express': 4.17.17 + '@types/express': 4.17.21 dev: true - /@types/serve-static@1.15.2: - resolution: {integrity: sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==} + /@types/serve-static@1.15.5: + resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} dependencies: - '@types/http-errors': 2.0.1 - '@types/mime': 3.0.1 - '@types/node': 20.6.3 + '@types/http-errors': 2.0.4 + '@types/mime': 3.0.4 + '@types/node': 20.10.4 dev: true /@types/sinonjs__fake-timers@8.1.1: resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==} dev: true - /@types/sizzle@2.3.3: - resolution: {integrity: sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==} + /@types/sizzle@2.3.8: + resolution: {integrity: sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==} dev: true - /@types/sockjs@0.3.33: - resolution: {integrity: sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==} + /@types/sockjs@0.3.36: + resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} dependencies: - '@types/node': 20.6.3 + '@types/node': 20.10.4 dev: true - /@types/source-list-map@0.1.2: - resolution: {integrity: sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==} + /@types/source-list-map@0.1.6: + resolution: {integrity: sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==} dev: true - /@types/tapable@1.0.9: - resolution: {integrity: sha512-fOHIwZua0sRltqWzODGUM6b4ffZrf/vzGUmNXdR+4DzuJP42PMbM5dLKcdzlYvv8bMJ3GALOzkk1q7cDm2zPyA==} + /@types/tapable@1.0.12: + resolution: {integrity: sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==} dev: true - /@types/testing-library__cypress@5.0.9: - resolution: {integrity: sha512-WTiIZhZKWDnV+Tgo42pxff8YfHdmaNFQz/bFoTlmfw2vbXcstCcb39VRaRi5yFHj/lb7t3K47btKYEbR1fci+Q==} + /@types/testing-library__cypress@5.0.13: + resolution: {integrity: sha512-lkxNGVFBEX825Z/FrHA8FLuKv1q5L6Bccqm08Zds2MUG4gd5al32hCpplzVumke3br+hkhtVmuPTfwQadIkc5w==} dependencies: '@testing-library/dom': 7.31.2 - cypress: 12.17.4 + cypress: 12.17.3 dev: true - /@types/uglify-js@3.17.2: - resolution: {integrity: sha512-9SjrHO54LINgC/6Ehr81NjAxAYvwEZqjUHLjJYvC4Nmr9jbLQCIZbWSvl4vXQkkmR1UAuaKDycau3O1kWGFyXQ==} + /@types/uglify-js@3.17.4: + resolution: {integrity: sha512-Hm/T0kV3ywpJyMGNbsItdivRhYNCQQf1IIsYsXnoVPES4t+FMLyDe0/K+Ea7ahWtMtSNb22ZdY7MIyoD9rqARg==} dependencies: source-map: 0.6.1 dev: true - /@types/webpack-sources@3.2.0: - resolution: {integrity: sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==} + /@types/webpack-sources@3.2.3: + resolution: {integrity: sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw==} dependencies: - '@types/node': 20.6.3 - '@types/source-list-map': 0.1.2 + '@types/node': 20.10.4 + '@types/source-list-map': 0.1.6 source-map: 0.7.4 dev: true - /@types/webpack@4.41.33: - resolution: {integrity: sha512-PPajH64Ft2vWevkerISMtnZ8rTs4YmRbs+23c402J0INmxDKCrhZNvwZYtzx96gY2wAtXdrK1BS2fiC8MlLr3g==} + /@types/webpack@4.41.38: + resolution: {integrity: sha512-oOW7E931XJU1mVfCnxCVgv8GLFL768pDO5u2Gzk82i8yTIgX6i7cntyZOkZYb/JtYM8252SN9bQp9tgkVDSsRw==} dependencies: - '@types/node': 20.6.3 - '@types/tapable': 1.0.9 - '@types/uglify-js': 3.17.2 - '@types/webpack-sources': 3.2.0 + '@types/node': 20.10.4 + '@types/tapable': 1.0.12 + '@types/uglify-js': 3.17.4 + '@types/webpack-sources': 3.2.3 anymatch: 3.1.3 source-map: 0.6.1 dev: true - /@types/ws@8.5.5: - resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==} + /@types/ws@8.5.10: + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 20.6.0 + '@types/node': 20.10.4 dev: true - /@types/yargs-parser@21.0.0: - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} dev: true - /@types/yargs@15.0.15: - resolution: {integrity: sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==} + /@types/yargs@15.0.19: + resolution: {integrity: sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==} dependencies: - '@types/yargs-parser': 21.0.0 + '@types/yargs-parser': 21.0.3 dev: true - /@types/yauzl@2.10.0: - resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} + /@types/yauzl@2.10.3: + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 20.6.3 + '@types/node': 20.10.4 dev: true optional: true @@ -1941,7 +1945,7 @@ packages: execa: 7.2.0 get-port: 6.1.2 http-proxy: 1.18.1(debug@4.3.4) - ws: 8.14.1 + ws: 8.15.1 transitivePeerDependencies: - bufferutil - debug @@ -2062,7 +2066,11 @@ packages: resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} dev: true - /abitype@0.9.8(typescript@5.1.6)(zod@3.22.3): + /@zeit/schemas@2.29.0: + resolution: {integrity: sha512-g5QiLIfbg3pLuYUJPlisNKY+epQJTcMDsOnVNkscrDP1oi7vmJnzOANYJI/1pZcVJ6umUkBv3aFtlg1UvUHGzA==} + dev: true + + /abitype@0.9.8(typescript@5.3.3)(zod@3.22.4): resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} peerDependencies: typescript: '>=5.0.4' @@ -2073,8 +2081,8 @@ packages: zod: optional: true dependencies: - typescript: 5.1.6 - zod: 3.22.3 + typescript: 5.3.3 + zod: 3.22.4 dev: true /accepts@1.3.8: @@ -2085,16 +2093,16 @@ packages: negotiator: 0.6.3 dev: true - /acorn-import-assertions@1.9.0(acorn@8.10.0): + /acorn-import-assertions@1.9.0(acorn@8.11.2): resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} peerDependencies: acorn: ^8 dependencies: - acorn: 8.10.0 + acorn: 8.11.2 dev: true - /acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + /acorn@8.11.2: + resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} hasBin: true dev: true @@ -2148,6 +2156,15 @@ packages: uri-js: 4.4.1 dev: true + /ajv@8.11.0: + resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + /ajv@8.12.0: resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} dependencies: @@ -2157,6 +2174,12 @@ packages: uri-js: 4.4.1 dev: true + /ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + dependencies: + string-width: 4.2.3 + dev: true + /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -2175,11 +2198,6 @@ packages: hasBin: true dev: true - /ansi-regex@0.2.1: - resolution: {integrity: sha512-sGwIGMjhYdW26/IhwK2gkWWI8DRCVO6uj3hYgHT+zD+QL1pa37tM3ujhyfcJIYSbsxp7Gxhy7zrRW/1AHm4BmA==} - engines: {node: '>=0.10.0'} - dev: true - /ansi-regex@2.1.1: resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} @@ -2190,9 +2208,9 @@ packages: engines: {node: '>=8'} dev: true - /ansi-styles@1.1.0: - resolution: {integrity: sha512-f2PKUkN5QngiSemowa6Mrk9MPCdtFiOSmibjZ+j1qhLGHHYsqZwmBMRF3IRMVXo8sybDqx2fJl2d/8OphBoWkA==} - engines: {node: '>=0.10.0'} + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} dev: true /ansi-styles@3.2.1: @@ -2214,6 +2232,11 @@ packages: engines: {node: '>=10'} dev: true + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -2249,6 +2272,10 @@ packages: resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} dev: true + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: true + /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: @@ -2263,20 +2290,20 @@ packages: resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} engines: {node: '>=6.0'} dependencies: - '@babel/runtime': 7.22.15 - '@babel/runtime-corejs3': 7.22.15 + '@babel/runtime': 7.23.6 + '@babel/runtime-corejs3': 7.23.6 dev: true /aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} dependencies: - deep-equal: 2.2.2 + deep-equal: 2.2.3 dev: true /array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 is-array-buffer: 3.0.2 dev: true @@ -2309,9 +2336,9 @@ packages: resolution: {integrity: sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 es-array-method-boxes-properly: 1.0.0 is-string: 1.0.7 dev: true @@ -2321,10 +2348,10 @@ packages: engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.0 - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 - get-intrinsic: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 is-array-buffer: 3.0.2 is-shared-array-buffer: 1.0.2 dev: true @@ -2351,8 +2378,8 @@ packages: lodash: 4.17.21 dev: true - /async@3.2.4: - resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} + /async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} dev: true /asynckit@0.4.0: @@ -2377,46 +2404,27 @@ packages: resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} dev: true - /axios@0.27.2(debug@4.3.4): - resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} - dependencies: - follow-redirects: 1.15.2(debug@4.3.4) - form-data: 4.0.0 - transitivePeerDependencies: - - debug - dev: true - - /axios@1.2.2(debug@4.3.4): - resolution: {integrity: sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==} + /axios@1.6.2(debug@4.3.4): + resolution: {integrity: sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==} dependencies: - follow-redirects: 1.15.2(debug@4.3.4) + follow-redirects: 1.15.6(debug@4.3.4) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug dev: true - /axios@1.5.0(debug@4.3.4): - resolution: {integrity: sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==} - dependencies: - follow-redirects: 1.15.2(debug@4.3.4) - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: true - - /babel-loader@9.1.3(@babel/core@7.22.20)(webpack@5.88.2): + /babel-loader@9.1.3(@babel/core@7.23.6)(webpack@5.89.0): resolution: {integrity: sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==} engines: {node: '>= 14.15.0'} peerDependencies: '@babel/core': ^7.12.0 webpack: '>=5' dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.88.2 + webpack: 5.89.0 dev: true /babel-plugin-istanbul@6.1.1: @@ -2432,38 +2440,38 @@ packages: - supports-color dev: true - /babel-plugin-polyfill-corejs2@0.4.5(@babel/core@7.22.20): - resolution: {integrity: sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==} + /babel-plugin-polyfill-corejs2@0.4.7(@babel/core@7.23.6): + resolution: {integrity: sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/compat-data': 7.22.20 - '@babel/core': 7.22.20 - '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.20) + '@babel/compat-data': 7.23.5 + '@babel/core': 7.23.6 + '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.23.6) semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-corejs3@0.8.3(@babel/core@7.22.20): - resolution: {integrity: sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==} + /babel-plugin-polyfill-corejs3@0.8.7(@babel/core@7.23.6): + resolution: {integrity: sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.20) - core-js-compat: 3.32.2 + '@babel/core': 7.23.6 + '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.23.6) + core-js-compat: 3.34.0 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-regenerator@0.5.2(@babel/core@7.22.20): - resolution: {integrity: sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==} + /babel-plugin-polyfill-regenerator@0.5.4(@babel/core@7.23.6): + resolution: {integrity: sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.22.20 - '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.20) + '@babel/core': 7.23.6 + '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.23.6) transitivePeerDependencies: - supports-color dev: true @@ -2596,6 +2604,20 @@ packages: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} dev: true + /boxen@7.0.0: + resolution: {integrity: sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==} + engines: {node: '>=14.16'} + dependencies: + ansi-align: 3.0.1 + camelcase: 7.0.1 + chalk: 5.0.1 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 + dev: true + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -2610,15 +2632,15 @@ packages: fill-range: 7.0.1 dev: true - /browserslist@4.21.10: - resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} + /browserslist@4.22.2: + resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001529 - electron-to-chromium: 1.4.513 - node-releases: 2.0.13 - update-browserslist-db: 1.0.11(browserslist@4.21.10) + caniuse-lite: 1.0.30001570 + electron-to-chromium: 1.4.613 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.22.2) dev: true /buffer-alloc-unsafe@1.1.0: @@ -2666,16 +2688,22 @@ packages: engines: {node: '>= 0.8'} dev: true - /cacheable-request@2.1.4: - resolution: {integrity: sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==} + /cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + dev: true + + /cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} dependencies: clone-response: 1.0.2 - get-stream: 3.0.0 - http-cache-semantics: 3.8.1 - keyv: 3.0.0 - lowercase-keys: 1.0.0 - normalize-url: 2.0.1 - responselike: 1.0.2 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 dev: true /cachedir@2.4.0: @@ -2693,11 +2721,12 @@ packages: write-file-atomic: 3.0.3 dev: true - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 dev: true /camel-case@4.1.2: @@ -2712,23 +2741,24 @@ packages: engines: {node: '>=6'} dev: true - /caniuse-lite@1.0.30001529: - resolution: {integrity: sha512-n2pUQYGAkrLG4QYj2desAh+NqsJpHbNmVZz87imptDdxLAtjxary7Df/psdfyDGmskJK/9Dt9cPnx5RZ3CU4Og==} + /camelcase@7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} + dev: true + + /caniuse-lite@1.0.30001570: + resolution: {integrity: sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==} dev: true /caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} dev: true - /chalk@0.5.1: - resolution: {integrity: sha512-bIKA54hP8iZhyDT81TOsJiQvR1gW+ZYSXFaZUAvoD4wCHdbHY2actmpTE4x344ZlFqHbvoxKOaESULTZN2gstg==} - engines: {node: '>=0.10.0'} + /chalk-template@0.4.0: + resolution: {integrity: sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==} + engines: {node: '>=12'} dependencies: - ansi-styles: 1.1.0 - escape-string-regexp: 1.0.5 - has-ansi: 0.1.0 - strip-ansi: 0.3.0 - supports-color: 0.2.0 + chalk: 4.1.2 dev: true /chalk@2.4.2: @@ -2748,6 +2778,11 @@ packages: supports-color: 7.2.0 dev: true + /chalk@5.0.1: + resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + /chance@1.1.11: resolution: {integrity: sha512-kqTg3WWywappJPqtgrdvbA380VoXO2eu9VCV895JgbyHsaErXdyHK9LOZ911OvAk6L0obK7kDk9CGs8+oBawVA==} dev: true @@ -2777,8 +2812,8 @@ packages: engines: {node: '>=6.0'} dev: true - /ci-info@3.8.0: - resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} dev: true @@ -2789,8 +2824,8 @@ packages: source-map: 0.6.1 dev: true - /clean-css@5.3.2: - resolution: {integrity: sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==} + /clean-css@5.3.3: + resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} engines: {node: '>= 10.0'} dependencies: source-map: 0.6.1 @@ -2801,6 +2836,11 @@ packages: engines: {node: '>=6'} dev: true + /cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + dev: true + /cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -2825,6 +2865,15 @@ packages: string-width: 4.2.3 dev: true + /clipboardy@3.0.0: + resolution: {integrity: sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + arch: 2.2.0 + execa: 5.1.1 + is-wsl: 2.2.0 + dev: true + /cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} dependencies: @@ -2884,8 +2933,8 @@ packages: resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} dev: true - /commander@11.0.0: - resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==} + /commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} dev: true @@ -2952,6 +3001,11 @@ packages: engines: {node: '>=0.8'} dev: true + /content-disposition@0.5.2: + resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} + engines: {node: '>= 0.6'} + dev: true + /content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -2968,6 +3022,10 @@ packages: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} dev: true + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + /cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} dev: true @@ -2977,14 +3035,14 @@ packages: engines: {node: '>= 0.6'} dev: true - /core-js-compat@3.32.2: - resolution: {integrity: sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ==} + /core-js-compat@3.34.0: + resolution: {integrity: sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==} dependencies: - browserslist: 4.21.10 + browserslist: 4.22.2 dev: true - /core-js-pure@3.32.2: - resolution: {integrity: sha512-Y2rxThOuNywTjnX/PgA5vWM6CZ9QB9sz9oGeCixV8MqXZO70z/5SHzf9EeBrEBK0PN36DnEBBu9O/aGWzKuMZQ==} + /core-js-pure@3.34.0: + resolution: {integrity: sha512-pmhivkYXkymswFfbXsANmBAewXx86UBfmagP+w0wkK06kLsLlTK5oQmsURPivzMkIBQiYq2cjamcZExIwlFQIg==} requiresBuild: true dev: true @@ -2994,8 +3052,8 @@ packages: requiresBuild: true dev: true - /core-js@3.32.2: - resolution: {integrity: sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==} + /core-js@3.34.0: + resolution: {integrity: sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==} requiresBuild: true dev: true @@ -3031,8 +3089,8 @@ packages: engines: {node: '>= 6'} dev: true - /csstype@3.1.2: - resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} dev: true /cypress-wait-until@2.0.1: @@ -3045,61 +3103,11 @@ packages: hasBin: true requiresBuild: true dependencies: - '@cypress/request': 2.88.12 - '@cypress/xvfb': 1.2.4(supports-color@8.1.1) - '@types/node': 16.18.50 - '@types/sinonjs__fake-timers': 8.1.1 - '@types/sizzle': 2.3.3 - arch: 2.2.0 - blob-util: 2.0.2 - bluebird: 3.7.2 - buffer: 5.7.1 - cachedir: 2.4.0 - chalk: 4.1.2 - check-more-types: 2.24.0 - cli-cursor: 3.1.0 - cli-table3: 0.6.3 - commander: 6.2.1 - common-tags: 1.8.2 - dayjs: 1.11.9 - debug: 4.3.4(supports-color@8.1.1) - enquirer: 2.4.1 - eventemitter2: 6.4.7 - execa: 4.1.0 - executable: 4.1.1 - extract-zip: 2.0.1(supports-color@8.1.1) - figures: 3.2.0 - fs-extra: 9.1.0 - getos: 3.2.1 - is-ci: 3.0.1 - is-installed-globally: 0.4.0 - lazy-ass: 1.6.0 - listr2: 3.14.0(enquirer@2.4.1) - lodash: 4.17.21 - log-symbols: 4.1.0 - minimist: 1.2.8 - ospath: 1.2.2 - pretty-bytes: 5.6.0 - proxy-from-env: 1.0.0 - request-progress: 3.0.0 - semver: 7.5.4 - supports-color: 8.1.1 - tmp: 0.2.1 - untildify: 4.0.0 - yauzl: 2.10.0 - dev: true - - /cypress@12.17.4: - resolution: {integrity: sha512-gAN8Pmns9MA5eCDFSDJXWKUpaL3IDd89N9TtIupjYnzLSmlpVr+ZR+vb4U/qaMp+lB6tBvAmt7504c3Z4RU5KQ==} - engines: {node: ^14.0.0 || ^16.0.0 || >=18.0.0} - hasBin: true - requiresBuild: true - dependencies: - '@cypress/request': 2.88.12 + '@cypress/request': 3.0.1 '@cypress/xvfb': 1.2.4(supports-color@8.1.1) - '@types/node': 16.18.50 + '@types/node': 16.18.68 '@types/sinonjs__fake-timers': 8.1.1 - '@types/sizzle': 2.3.3 + '@types/sizzle': 2.3.8 arch: 2.2.0 blob-util: 2.0.2 bluebird: 3.7.2 @@ -3111,7 +3119,7 @@ packages: cli-table3: 0.6.3 commander: 6.2.1 common-tags: 1.8.2 - dayjs: 1.11.9 + dayjs: 1.11.10 debug: 4.3.4(supports-color@8.1.1) enquirer: 2.4.1 eventemitter2: 6.4.7 @@ -3130,7 +3138,6 @@ packages: minimist: 1.2.8 ospath: 1.2.2 pretty-bytes: 5.6.0 - process: 0.11.10 proxy-from-env: 1.0.0 request-progress: 3.0.0 semver: 7.5.4 @@ -3147,8 +3154,8 @@ packages: assert-plus: 1.0.0 dev: true - /dayjs@1.11.9: - resolution: {integrity: sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==} + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} dev: true /debug@2.6.9: @@ -3192,16 +3199,11 @@ packages: engines: {node: '>=0.10.0'} dev: true - /decode-uri-component@0.2.2: - resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} - engines: {node: '>=0.10'} - dev: true - - /decompress-response@3.3.0: - resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} - engines: {node: '>=4'} + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} dependencies: - mimic-response: 1.0.1 + mimic-response: 3.1.0 dev: true /decompress-tar@4.1.1: @@ -3257,13 +3259,14 @@ packages: strip-dirs: 2.1.0 dev: true - /deep-equal@2.2.2: - resolution: {integrity: sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==} + /deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.0 - call-bind: 1.0.2 + call-bind: 1.0.5 es-get-iterator: 1.1.3 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 is-arguments: 1.1.1 is-array-buffer: 3.0.2 is-date-object: 1.0.5 @@ -3272,12 +3275,17 @@ packages: isarray: 2.0.5 object-is: 1.1.5 object-keys: 1.1.1 - object.assign: 4.1.4 + object.assign: 4.1.5 regexp.prototype.flags: 1.5.1 side-channel: 1.0.4 which-boxed-primitive: 1.0.2 which-collection: 1.0.1 - which-typed-array: 1.1.11 + which-typed-array: 1.1.13 + dev: true + + /deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} dev: true /default-gateway@6.0.3: @@ -3294,13 +3302,18 @@ packages: strip-bom: 4.0.0 dev: true - /define-data-property@1.1.0: - resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==} + /defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + dev: true + + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 gopd: 1.0.1 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.1 dev: true /define-lazy-prop@2.0.0: @@ -3312,8 +3325,8 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.0 - has-property-descriptors: 1.0.0 + define-data-property: 1.1.1 + has-property-descriptors: 1.0.1 object-keys: 1.1.1 dev: true @@ -3429,14 +3442,14 @@ packages: file-type: 11.1.0 filenamify: 3.0.0 get-stream: 4.1.0 - got: 8.3.2 + got: 11.8.6 make-dir: 2.1.0 p-event: 2.3.1 pify: 4.0.1 dev: true - /duplexer3@0.1.5: - resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true /ecc-jsbn@0.1.2: @@ -3450,8 +3463,8 @@ packages: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} dev: true - /electron-to-chromium@1.4.513: - resolution: {integrity: sha512-cOB0xcInjm+E5qIssHeXJ29BaUyWpMyFKT5RB3bsLENDheCja0wMkHJyiPl0NBE/VzDI7JDuNEQWhe6RitEUcw==} + /electron-to-chromium@1.4.613: + resolution: {integrity: sha512-r4x5+FowKG6q+/Wj0W9nidx7QO31BJwmR2uEo+Qh3YLGQ8SbBAFuDFpTxzly/I2gsbrFwBuIjrMp423L3O5U3w==} dev: true /email-addresses@3.1.0: @@ -3462,6 +3475,10 @@ packages: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + /emojis-list@3.0.0: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} engines: {node: '>= 4'} @@ -3498,26 +3515,26 @@ packages: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} dev: true - /es-abstract@1.22.2: - resolution: {integrity: sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==} + /es-abstract@1.22.3: + resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.0 arraybuffer.prototype.slice: 1.0.2 available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - es-set-tostringtag: 2.0.1 + call-bind: 1.0.5 + es-set-tostringtag: 2.0.2 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 get-symbol-description: 1.0.0 globalthis: 1.0.3 gopd: 1.0.1 - has: 1.0.3 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.1 has-proto: 1.0.1 has-symbols: 1.0.3 - internal-slot: 1.0.5 + hasown: 2.0.0 + internal-slot: 1.0.6 is-array-buffer: 3.0.2 is-callable: 1.2.7 is-negative-zero: 2.0.2 @@ -3526,9 +3543,9 @@ packages: is-string: 1.0.7 is-typed-array: 1.1.12 is-weakref: 1.0.2 - object-inspect: 1.12.3 + object-inspect: 1.13.1 object-keys: 1.1.1 - object.assign: 4.1.4 + object.assign: 4.1.5 regexp.prototype.flags: 1.5.1 safe-array-concat: 1.0.1 safe-regex-test: 1.0.0 @@ -3540,7 +3557,7 @@ packages: typed-array-byte-offset: 1.0.0 typed-array-length: 1.0.4 unbox-primitive: 1.0.2 - which-typed-array: 1.1.11 + which-typed-array: 1.1.13 dev: true /es-array-method-boxes-properly@1.0.0: @@ -3550,8 +3567,8 @@ packages: /es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 has-symbols: 1.0.3 is-arguments: 1.1.1 is-map: 2.0.2 @@ -3561,17 +3578,17 @@ packages: stop-iteration-iterator: 1.0.0 dev: true - /es-module-lexer@1.3.1: - resolution: {integrity: sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==} + /es-module-lexer@1.4.1: + resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} dev: true - /es-set-tostringtag@2.0.1: - resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + /es-set-tostringtag@2.0.2: + resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.1 - has: 1.0.3 + get-intrinsic: 1.2.2 has-tostringtag: 1.0.0 + hasown: 2.0.0 dev: true /es-to-primitive@1.2.1: @@ -3642,13 +3659,13 @@ packages: engines: {node: '>= 0.6'} dev: true - /ethers@6.7.1: - resolution: {integrity: sha512-qX5kxIFMfg1i+epfgb0xF4WM7IqapIIu50pOJ17aebkxxa4BacW5jFrQRmCJpDEg2ZK2oNtR5QjrQ1WDBF29dA==} + /ethers@6.9.0: + resolution: {integrity: sha512-pmfNyQzc2mseLe91FnT2vmNaTt8dDzhxZ/xItAV7uGsF4dI4ek2ufMu3rAkgQETL/TIs0GS5A+U05g9QyWnv3Q==} engines: {node: '>=14.0.0'} dependencies: - '@adraffy/ens-normalize': 1.9.2 - '@noble/hashes': 1.1.2 - '@noble/secp256k1': 1.7.1 + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 '@types/node': 18.15.13 aes-js: 4.0.0-beta.5 tslib: 2.4.0 @@ -3661,7 +3678,7 @@ packages: /etherscan-api@10.3.0(debug@4.3.4): resolution: {integrity: sha512-XH+E7J2c6Wq750stvFuIIMdiLv5v65nTRftQojXuQXNfEsQaZOOgeY11WHdrGh6yh90ekDJQldgf033tIS1rCw==} dependencies: - axios: 1.2.2(debug@4.3.4) + axios: 1.6.2(debug@4.3.4) gh-pages: 4.0.0 querystring: 0.2.1 transitivePeerDependencies: @@ -3800,7 +3817,7 @@ packages: get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: - '@types/yauzl': 2.10.0 + '@types/yauzl': 2.10.3 transitivePeerDependencies: - supports-color dev: true @@ -3814,8 +3831,8 @@ packages: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true - /fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3829,6 +3846,12 @@ packages: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true + /fast-url-parser@1.1.3: + resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==} + dependencies: + punycode: 1.4.1 + dev: true + /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: @@ -3855,10 +3878,6 @@ packages: escape-string-regexp: 1.0.5 dev: true - /file-size@0.0.5: - resolution: {integrity: sha512-ZW056dw8Ta1RWHVOQue3LMZe+mSOnHkcM7AN9is8JoHSIHRiLD5szwPAHM3fM7P5SGJ1bkAmCv3PvUTGoluDqA==} - dev: true - /file-type@11.1.0: resolution: {integrity: sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==} engines: {node: '>=6'} @@ -3969,8 +3988,13 @@ packages: path-exists: 5.0.0 dev: true - /follow-redirects@1.15.2(debug@4.3.4): - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + /flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + dev: true + + /follow-redirects@1.15.6(debug@4.3.4): + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -4027,13 +4051,6 @@ packages: engines: {node: '>= 0.6'} dev: true - /from2@2.3.0: - resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} - dependencies: - inherits: 2.0.4 - readable-stream: 2.3.8 - dev: true - /fromentries@1.3.2: resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} dev: true @@ -4058,11 +4075,11 @@ packages: at-least-node: 1.0.0 graceful-fs: 4.2.11 jsonfile: 6.1.0 - universalify: 2.0.0 + universalify: 2.0.1 dev: true - /fs-monkey@1.0.4: - resolution: {integrity: sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==} + /fs-monkey@1.0.5: + resolution: {integrity: sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==} dev: true /fs.realpath@1.0.0: @@ -4085,17 +4102,17 @@ packages: dev: true optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} dev: true /function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 functions-have-names: 1.2.3 dev: true @@ -4113,13 +4130,13 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: - function-bind: 1.1.1 - has: 1.0.3 + function-bind: 1.1.2 has-proto: 1.0.1 has-symbols: 1.0.3 + hasown: 2.0.0 dev: true /get-package-type@0.1.0: @@ -4145,11 +4162,6 @@ packages: pinkie-promise: 2.0.1 dev: true - /get-stream@3.0.0: - resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} - engines: {node: '>=4'} - dev: true - /get-stream@4.1.0: resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} engines: {node: '>=6'} @@ -4173,14 +4185,14 @@ packages: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 dev: true /getos@3.2.1: resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} dependencies: - async: 3.2.4 + async: 3.2.5 dev: true /getpass@0.1.7: @@ -4244,14 +4256,14 @@ packages: define-properties: 1.2.1 dev: true - /globby@11.0.4: - resolution: {integrity: sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==} + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.1 - ignore: 5.2.4 + fast-glob: 3.3.2 + ignore: 5.3.0 merge2: 1.4.1 slash: 3.0.0 dev: true @@ -4270,32 +4282,24 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 dev: true - /got@8.3.2: - resolution: {integrity: sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==} - engines: {node: '>=4'} + /got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} dependencies: - '@sindresorhus/is': 0.7.0 - '@types/keyv': 3.1.4 - '@types/responselike': 1.0.0 - cacheable-request: 2.1.4 - decompress-response: 3.3.0 - duplexer3: 0.1.5 - get-stream: 3.0.0 - into-stream: 3.1.0 - is-retry-allowed: 1.2.0 - isurl: 1.0.0 - lowercase-keys: 1.0.1 - mimic-response: 1.0.1 - p-cancelable: 0.4.1 - p-timeout: 2.0.1 - pify: 3.0.0 - safe-buffer: 5.2.1 - timed-out: 4.0.1 - url-parse-lax: 3.0.0 - url-to-options: 1.0.1 + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 dev: true /graceful-fs@4.2.11: @@ -4306,14 +4310,6 @@ packages: resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} dev: true - /has-ansi@0.1.0: - resolution: {integrity: sha512-1YsTg1fk2/6JToQhtZkArMkurq8UoWU1Qe0aR3VUHjgij4nOylSWLWAtBXoZ4/dXOmugfLGm1c+QhuD0JyedFA==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - ansi-regex: 0.2.1 - dev: true - /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} dev: true @@ -4328,10 +4324,10 @@ packages: engines: {node: '>=8'} dev: true - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + /has-property-descriptors@1.0.1: + resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 dev: true /has-proto@1.0.1: @@ -4339,21 +4335,11 @@ packages: engines: {node: '>= 0.4'} dev: true - /has-symbol-support-x@1.4.2: - resolution: {integrity: sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==} - dev: true - /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} dev: true - /has-to-string-tag-x@1.4.1: - resolution: {integrity: sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==} - dependencies: - has-symbol-support-x: 1.4.2 - dev: true - /has-tostringtag@1.0.0: resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} engines: {node: '>= 0.4'} @@ -4361,13 +4347,6 @@ packages: has-symbols: 1.0.3 dev: true - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - dev: true - /hasha@5.2.2: resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} engines: {node: '>=8'} @@ -4376,6 +4355,13 @@ packages: type-fest: 0.8.1 dev: true + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + /he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true @@ -4418,34 +4404,34 @@ packages: hasBin: true dependencies: camel-case: 4.1.2 - clean-css: 5.3.2 + clean-css: 5.3.3 commander: 8.3.0 he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.20.0 + terser: 5.26.0 dev: true - /html-webpack-plugin@4.5.2(webpack@5.88.2): + /html-webpack-plugin@4.5.2(webpack@5.89.0): resolution: {integrity: sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A==} engines: {node: '>=6.9'} peerDependencies: webpack: ^4.0.0 || ^5.0.0 dependencies: '@types/html-minifier-terser': 5.1.2 - '@types/tapable': 1.0.9 - '@types/webpack': 4.41.33 + '@types/tapable': 1.0.12 + '@types/webpack': 4.41.38 html-minifier-terser: 5.1.1 loader-utils: 1.4.2 lodash: 4.17.21 pretty-error: 2.1.2 tapable: 1.1.3 util.promisify: 1.0.0 - webpack: 5.88.2 + webpack: 5.89.0 dev: true - /html-webpack-plugin@5.5.3(webpack@5.88.2): - resolution: {integrity: sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==} + /html-webpack-plugin@5.5.4(webpack@5.89.0): + resolution: {integrity: sha512-3wNSaVVxdxcu0jd4FpQFoICdqgxs4zIQQvj+2yQKFfBOnLETQ6X5CDWdeasuGlSsooFlMkEioWDTqBv1wvw5Iw==} engines: {node: '>=10.13.0'} peerDependencies: webpack: ^5.20.0 @@ -4455,7 +4441,7 @@ packages: lodash: 4.17.21 pretty-error: 4.0.0 tapable: 2.2.1 - webpack: 5.88.2 + webpack: 5.89.0 dev: true /htmlparser2@6.1.0: @@ -4467,8 +4453,8 @@ packages: entities: 2.2.0 dev: true - /http-cache-semantics@3.8.1: - resolution: {integrity: sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==} + /http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} dev: true /http-deceiver@1.2.7: @@ -4500,7 +4486,7 @@ packages: resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} dev: true - /http-proxy-middleware@2.0.6(@types/express@4.17.17)(debug@4.3.4): + /http-proxy-middleware@2.0.6(@types/express@4.17.21)(debug@4.3.4): resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -4509,8 +4495,8 @@ packages: '@types/express': optional: true dependencies: - '@types/express': 4.17.17 - '@types/http-proxy': 1.17.11 + '@types/express': 4.17.21 + '@types/http-proxy': 1.17.14 http-proxy: 1.18.1(debug@4.3.4) is-glob: 4.0.3 is-plain-obj: 3.0.0 @@ -4524,7 +4510,7 @@ packages: engines: {node: '>=8.0.0'} dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.2(debug@4.3.4) + follow-redirects: 1.15.6(debug@4.3.4) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -4536,7 +4522,15 @@ packages: dependencies: assert-plus: 1.0.0 jsprim: 2.0.2 - sshpk: 1.17.0 + sshpk: 1.18.0 + dev: true + + /http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 dev: true /human-signals@1.1.1: @@ -4565,8 +4559,8 @@ packages: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: true - /ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + /ignore@5.3.0: + resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} dev: true @@ -4595,28 +4589,24 @@ packages: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: true + /ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: true + /ini@2.0.0: resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} engines: {node: '>=10'} dev: true - /internal-slot@1.0.5: - resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + /internal-slot@1.0.6: + resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.1 - has: 1.0.3 + get-intrinsic: 1.2.2 + hasown: 2.0.0 side-channel: 1.0.4 dev: true - /into-stream@3.1.0: - resolution: {integrity: sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==} - engines: {node: '>=4'} - dependencies: - from2: 2.3.0 - p-is-promise: 1.1.0 - dev: true - /ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -4631,15 +4621,15 @@ packages: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-tostringtag: 1.0.0 dev: true /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-typed-array: 1.1.12 dev: true @@ -4660,7 +4650,7 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-tostringtag: 1.0.0 dev: true @@ -4673,13 +4663,13 @@ packages: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true dependencies: - ci-info: 3.8.0 + ci-info: 3.9.0 dev: true - /is-core-module@2.13.0: - resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: - has: 1.0.3 + hasown: 2.0.0 dev: true /is-date-object@1.0.5: @@ -4745,10 +4735,6 @@ packages: engines: {node: '>=0.12.0'} dev: true - /is-object@1.0.2: - resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==} - dev: true - /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} @@ -4771,19 +4757,19 @@ packages: isobject: 3.0.1 dev: true + /is-port-reachable@4.0.0: + resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-tostringtag: 1.0.0 dev: true - /is-retry-allowed@1.2.0: - resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} - engines: {node: '>=0.10.0'} - dev: true - /is-set@2.0.2: resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} dev: true @@ -4791,7 +4777,7 @@ packages: /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 dev: true /is-stream@1.1.0: @@ -4838,7 +4824,7 @@ packages: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} dependencies: - which-typed-array: 1.1.11 + which-typed-array: 1.1.13 dev: true /is-typedarray@1.0.0: @@ -4857,14 +4843,14 @@ packages: /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 dev: true /is-weakset@2.0.2: resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 dev: true /is-windows@1.0.2: @@ -4872,11 +4858,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-wsl@1.1.0: - resolution: {integrity: sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==} - engines: {node: '>=4'} - dev: true - /is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} @@ -4901,8 +4882,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /isomorphic-ws@5.0.0(ws@8.13.0): - resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + /isows@1.0.3(ws@8.13.0): + resolution: {integrity: sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==} peerDependencies: ws: '*' dependencies: @@ -4913,13 +4894,8 @@ packages: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} dev: true - /istanbul-lib-coverage@3.0.0: - resolution: {integrity: sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==} - engines: {node: '>=8'} - dev: true - - /istanbul-lib-coverage@3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} dev: true @@ -4934,9 +4910,9 @@ packages: resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.22.20 + '@babel/core': 7.23.6 '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -4946,10 +4922,10 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.22.20 - '@babel/parser': 7.22.16 + '@babel/core': 7.23.6 + '@babel/parser': 7.23.6 '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -4961,7 +4937,7 @@ packages: dependencies: archy: 1.0.0 cross-spawn: 7.0.3 - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 p-map: 3.0.0 rimraf: 3.0.2 uuid: 8.3.2 @@ -4971,7 +4947,7 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} dependencies: - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 make-dir: 4.0.0 supports-color: 7.2.0 dev: true @@ -4981,7 +4957,7 @@ packages: engines: {node: '>=10'} dependencies: debug: 4.3.4(supports-color@8.1.1) - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color @@ -4995,25 +4971,17 @@ packages: istanbul-lib-report: 3.0.1 dev: true - /isurl@1.0.0: - resolution: {integrity: sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==} - engines: {node: '>= 4'} - dependencies: - has-to-string-tag-x: 1.4.1 - is-object: 1.0.2 - dev: true - /jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.6.3 + '@types/node': 20.10.4 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /joi@17.10.1: - resolution: {integrity: sha512-vIiDxQKmRidUVp8KngT8MZSOcmRVm2zV7jbMjNYWuHcJWI0bUck3nRTGQjhpPlQenIQIBC5Vp9AhcnHbWQqafw==} + /joi@17.11.0: + resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==} dependencies: '@hapi/hoek': 9.3.0 '@hapi/topo': 5.1.0 @@ -5056,8 +5024,8 @@ packages: hasBin: true dev: true - /json-buffer@3.0.0: - resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} dev: true /json-parse-even-better-errors@2.3.1: @@ -5102,7 +5070,7 @@ packages: /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} dependencies: - universalify: 2.0.0 + universalify: 2.0.1 optionalDependencies: graceful-fs: 4.2.11 dev: true @@ -5117,10 +5085,10 @@ packages: verror: 1.10.0 dev: true - /keyv@3.0.0: - resolution: {integrity: sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==} + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: - json-buffer: 3.0.0 + json-buffer: 3.0.1 dev: true /kind-of@6.0.3: @@ -5128,8 +5096,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /launch-editor@2.6.0: - resolution: {integrity: sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==} + /launch-editor@2.6.1: + resolution: {integrity: sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==} dependencies: picocolors: 1.0.0 shell-quote: 1.8.1 @@ -5260,14 +5228,9 @@ packages: tslib: 2.6.2 dev: true - /lowercase-keys@1.0.0: - resolution: {integrity: sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==} - engines: {node: '>=0.10.0'} - dev: true - - /lowercase-keys@1.0.1: - resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} - engines: {node: '>=0.10.0'} + /lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} dev: true /lru-cache@5.1.1: @@ -5326,7 +5289,7 @@ packages: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} dependencies: - fs-monkey: 1.0.4 + fs-monkey: 1.0.5 dev: true /merge-descriptors@1.0.1: @@ -5355,11 +5318,23 @@ packages: picomatch: 2.3.1 dev: true + /mime-db@1.33.0: + resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==} + engines: {node: '>= 0.6'} + dev: true + /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} dev: true + /mime-types@2.1.18: + resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.33.0 + dev: true + /mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} @@ -5388,6 +5363,11 @@ packages: engines: {node: '>=4'} dev: true + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: true + /minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} dev: true @@ -5462,8 +5442,8 @@ packages: process-on-spawn: 1.0.0 dev: true - /node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} dev: true /normalize-path@3.0.0: @@ -5471,13 +5451,9 @@ packages: engines: {node: '>=0.10.0'} dev: true - /normalize-url@2.0.1: - resolution: {integrity: sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==} - engines: {node: '>=4'} - dependencies: - prepend-http: 2.0.0 - query-string: 5.1.1 - sort-keys: 2.0.0 + /normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} dev: true /npm-run-path@4.0.1: @@ -5515,7 +5491,7 @@ packages: foreground-child: 2.0.0 get-package-type: 0.1.0 glob: 7.2.3 - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 istanbul-lib-hook: 3.0.0 istanbul-lib-instrument: 4.0.3 istanbul-lib-processinfo: 2.0.3 @@ -5541,15 +5517,15 @@ packages: engines: {node: '>=0.10.0'} dev: true - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} dev: true /object-is@1.1.5: resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 dev: true @@ -5558,11 +5534,11 @@ packages: engines: {node: '>= 0.4'} dev: true - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 @@ -5573,9 +5549,9 @@ packages: engines: {node: '>= 0.8'} dependencies: array.prototype.reduce: 1.0.6 - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 safe-array-concat: 1.0.1 dev: true @@ -5624,13 +5600,6 @@ packages: is-wsl: 2.2.0 dev: true - /opn@5.5.0: - resolution: {integrity: sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==} - engines: {node: '>=4'} - dependencies: - is-wsl: 1.1.0 - dev: true - /os-homedir@1.0.2: resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} engines: {node: '>=0.10.0'} @@ -5640,9 +5609,9 @@ packages: resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==} dev: true - /p-cancelable@0.4.1: - resolution: {integrity: sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==} - engines: {node: '>=4'} + /p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} dev: true /p-event@2.3.1: @@ -5657,11 +5626,6 @@ packages: engines: {node: '>=4'} dev: true - /p-is-promise@1.1.0: - resolution: {integrity: sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==} - engines: {node: '>=4'} - dev: true - /p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -5773,6 +5737,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /path-is-inside@1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + dev: true + /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -5791,6 +5759,10 @@ packages: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} dev: true + /path-to-regexp@2.2.1: + resolution: {integrity: sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==} + dev: true + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -5854,15 +5826,20 @@ packages: find-up: 6.3.0 dev: true - /playwright-core@1.37.1: - resolution: {integrity: sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==} + /playwright-core@1.40.1: + resolution: {integrity: sha512-+hkOycxPiV534c4HhpfX6yrlawqVUzITRKwHAmYfmsVreltEl6fAZJ3DPfLMOODw0H3s1Itd6MDCWmP1fl/QvQ==} engines: {node: '>=16'} hasBin: true dev: true - /prepend-http@2.0.0: - resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==} - engines: {node: '>=4'} + /playwright@1.40.1: + resolution: {integrity: sha512-2eHI7IioIpQ0bS1Ovg/HszsN/XKNwEG1kbzSDDmADpclKc7CyqkHw7Mg2JCz/bbCxg25QUPcjksoMW7JcIFQmw==} + engines: {node: '>=16'} + hasBin: true + dependencies: + playwright-core: 1.40.1 + optionalDependencies: + fsevents: 2.3.2 dev: true /pretty-bytes@5.6.0: @@ -5914,15 +5891,11 @@ packages: fromentries: 1.3.2 dev: true - /process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - dev: true - - /prom-client@14.2.0: - resolution: {integrity: sha512-sF308EhTenb/pDRPakm+WgiN+VdM/T1RaHj1x+MvAuT8UiQP8JmOEbxVqtkbfR4LrvOg5n7ic01kRBDGXjYikA==} - engines: {node: '>=10'} + /prom-client@15.0.0: + resolution: {integrity: sha512-UocpgIrKyA2TKLVZDSfm8rGkL13C19YrQBAiG3xo3aDFWcHedxRxI3z+cIcucoxpSO0h5lff5iv/SXoxyeopeA==} + engines: {node: ^16 || ^18 || >=20} dependencies: + '@opentelemetry/api': 1.7.0 tdigest: 0.1.2 dev: false @@ -5953,8 +5926,12 @@ packages: once: 1.4.0 dev: true - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + dev: true + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} dev: true @@ -5972,15 +5949,6 @@ packages: side-channel: 1.0.4 dev: true - /query-string@5.1.1: - resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==} - engines: {node: '>=0.10.0'} - dependencies: - decode-uri-component: 0.2.2 - object-assign: 4.1.1 - strict-uri-encode: 1.1.0 - dev: true - /querystring@0.2.1: resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==} engines: {node: '>=0.4.x'} @@ -5995,12 +5963,22 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true + /quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: true + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 dev: true + /range-parser@1.2.0: + resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==} + engines: {node: '>= 0.6'} + dev: true + /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -6016,6 +5994,16 @@ packages: unpipe: 1.0.0 dev: true + /rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + dev: true + /react-dom@18.2.0(react@18.2.0): resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -6087,14 +6075,14 @@ packages: /regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.6 dev: true /regexp.prototype.flags@1.5.1: resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 set-function-name: 2.0.1 dev: true @@ -6111,6 +6099,20 @@ packages: unicode-match-property-value-ecmascript: 2.1.0 dev: true + /registry-auth-token@3.3.2: + resolution: {integrity: sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==} + dependencies: + rc: 1.2.8 + safe-buffer: 5.2.1 + dev: true + + /registry-url@3.1.0: + resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==} + engines: {node: '>=0.10.0'} + dependencies: + rc: 1.2.8 + dev: true + /regjsparser@0.9.1: resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} hasBin: true @@ -6153,7 +6155,7 @@ packages: /request-progress@3.0.0: resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==} dependencies: - throttleit: 1.0.0 + throttleit: 1.0.1 dev: true /require-directory@2.1.1: @@ -6174,24 +6176,28 @@ packages: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} dev: true + /resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + dev: true + /resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} dev: true - /resolve@1.22.6: - resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==} + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true dependencies: - is-core-module: 2.13.0 + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: true - /responselike@1.0.2: - resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==} + /responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} dependencies: - lowercase-keys: 1.0.1 + lowercase-keys: 2.0.0 dev: true /restore-cursor@3.1.0: @@ -6239,8 +6245,8 @@ packages: resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} engines: {node: '>=0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 has-symbols: 1.0.3 isarray: 2.0.5 dev: true @@ -6256,8 +6262,8 @@ packages: /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-regex: 1.1.4 dev: true @@ -6275,7 +6281,7 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/json-schema': 7.0.13 + '@types/json-schema': 7.0.15 ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) dev: true @@ -6284,7 +6290,7 @@ packages: resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} engines: {node: '>= 12.13.0'} dependencies: - '@types/json-schema': 7.0.13 + '@types/json-schema': 7.0.15 ajv: 8.12.0 ajv-formats: 2.1.1(ajv@8.12.0) ajv-keywords: 5.1.0(ajv@8.12.0) @@ -6301,10 +6307,11 @@ packages: resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} dev: true - /selfsigned@2.1.1: - resolution: {integrity: sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==} + /selfsigned@2.4.1: + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} dependencies: + '@types/node-forge': 1.3.10 node-forge: 1.3.1 dev: true @@ -6353,6 +6360,19 @@ packages: randombytes: 2.1.0 dev: true + /serve-handler@6.1.5: + resolution: {integrity: sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==} + dependencies: + bytes: 3.0.0 + content-disposition: 0.5.2 + fast-url-parser: 1.1.3 + mime-types: 2.1.18 + minimatch: 3.1.2 + path-is-inside: 1.0.2 + path-to-regexp: 2.2.1 + range-parser: 1.2.0 + dev: true + /serve-index@1.9.1: resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} engines: {node: '>= 0.8.0'} @@ -6380,17 +6400,47 @@ packages: - supports-color dev: true + /serve@14.2.1: + resolution: {integrity: sha512-48er5fzHh7GCShLnNyPBRPEjs2I6QBozeGr02gaacROiyS/8ARADlj595j39iZXAqBbJHH/ivJJyPRWY9sQWZA==} + engines: {node: '>= 14'} + hasBin: true + dependencies: + '@zeit/schemas': 2.29.0 + ajv: 8.11.0 + arg: 5.0.2 + boxen: 7.0.0 + chalk: 5.0.1 + chalk-template: 0.4.0 + clipboardy: 3.0.0 + compression: 1.7.4 + is-port-reachable: 4.0.0 + serve-handler: 6.1.5 + update-check: 1.5.4 + transitivePeerDependencies: + - supports-color + dev: true + /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + /set-function-name@2.0.1: resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.0 + define-data-property: 1.1.1 functions-have-names: 1.2.3 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.1 dev: true /setprototypeof@1.1.0: @@ -6427,9 +6477,9 @@ packages: /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + object-inspect: 1.13.1 dev: true /signal-exit@3.0.7: @@ -6481,13 +6531,6 @@ packages: is-plain-obj: 1.1.0 dev: true - /sort-keys@2.0.0: - resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} - engines: {node: '>=4'} - dependencies: - is-plain-obj: 1.1.0 - dev: true - /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -6543,22 +6586,22 @@ packages: - supports-color dev: true - /speed-measure-webpack-plugin@1.4.2(webpack@5.88.2): + /speed-measure-webpack-plugin@1.4.2(webpack@5.89.0): resolution: {integrity: sha512-AtVzD0bnIy2/B0fWqJpJgmhcrfWFhBlduzSo0uwplr/QvB33ZNZj2NEth3NONgdnZJqicK0W0mSxnLSbsVCDbw==} engines: {node: '>=6.0.0'} peerDependencies: webpack: ^1 || ^2 || ^3 || ^4 || ^5 dependencies: chalk: 4.1.2 - webpack: 5.88.2 + webpack: 5.89.0 dev: true /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true - /sshpk@1.17.0: - resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} + /sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} engines: {node: '>=0.10.0'} hasBin: true dependencies: @@ -6573,18 +6616,6 @@ packages: tweetnacl: 0.14.5 dev: true - /static-server@2.2.1: - resolution: {integrity: sha512-j5eeW6higxYNmXMIT8iHjsdiViTpQDthg7o+SHsRtqdbxscdHqBHXwrXjHC8hL3F0Tsu34ApUpDkwzMBPBsrLw==} - engines: {node: '>=4'} - hasBin: true - dependencies: - chalk: 0.5.1 - commander: 2.20.3 - file-size: 0.0.5 - mime: 1.6.0 - opn: 5.5.0 - dev: true - /statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -6599,12 +6630,7 @@ packages: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} dependencies: - internal-slot: 1.0.5 - dev: true - - /strict-uri-encode@1.1.0: - resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} - engines: {node: '>=0.10.0'} + internal-slot: 1.0.6 dev: true /string-width@4.2.3: @@ -6616,29 +6642,38 @@ packages: strip-ansi: 6.0.1 dev: true + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: true + /string.prototype.trim@1.2.8: resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 dev: true /string.prototype.trimend@1.0.7: resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 dev: true /string.prototype.trimstart@1.0.7: resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 define-properties: 1.2.1 - es-abstract: 1.22.2 + es-abstract: 1.22.3 dev: true /string_decoder@1.1.1: @@ -6653,14 +6688,6 @@ packages: safe-buffer: 5.2.1 dev: true - /strip-ansi@0.3.0: - resolution: {integrity: sha512-DerhZL7j6i6/nEnVG0qViKXI0OKouvvpsAiaj7c+LfqZZZxdwZtv8+UiA/w4VUJpT8UzX0pR1dcHOii1GbmruQ==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - ansi-regex: 0.2.1 - dev: true - /strip-ansi@3.0.1: resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} engines: {node: '>=0.10.0'} @@ -6675,6 +6702,13 @@ packages: ansi-regex: 5.0.1 dev: true + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + /strip-bom@4.0.0: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} @@ -6696,6 +6730,11 @@ packages: engines: {node: '>=12'} dev: true + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: true + /strip-outer@1.0.1: resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} engines: {node: '>=0.10.0'} @@ -6703,12 +6742,6 @@ packages: escape-string-regexp: 1.0.5 dev: true - /supports-color@0.2.0: - resolution: {integrity: sha512-tdCZ28MnM7k7cJDJc7Eq80A9CsRFAAOZUy41npOZCs++qSjfIy7o5Rh46CBk+Dk5FbKJ33X3Tqg4YrV07N5RaA==} - engines: {node: '>=0.10.0'} - hasBin: true - dev: true - /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -6764,7 +6797,7 @@ packages: bintrees: 1.0.2 dev: false - /terser-webpack-plugin@5.3.9(webpack@5.88.2): + /terser-webpack-plugin@5.3.9(webpack@5.89.0): resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} engines: {node: '>= 10.13.0'} peerDependencies: @@ -6780,12 +6813,12 @@ packages: uglify-js: optional: true dependencies: - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.1 - terser: 5.20.0 - webpack: 5.88.2 + terser: 5.26.0 + webpack: 5.89.0 dev: true /terser@4.8.1: @@ -6793,19 +6826,19 @@ packages: engines: {node: '>=6.0.0'} hasBin: true dependencies: - acorn: 8.10.0 + acorn: 8.11.2 commander: 2.20.3 source-map: 0.6.1 source-map-support: 0.5.21 dev: true - /terser@5.20.0: - resolution: {integrity: sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==} + /terser@5.26.0: + resolution: {integrity: sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==} engines: {node: '>=10'} hasBin: true dependencies: '@jridgewell/source-map': 0.3.5 - acorn: 8.10.0 + acorn: 8.11.2 commander: 2.20.3 source-map-support: 0.5.21 dev: true @@ -6819,8 +6852,8 @@ packages: minimatch: 3.1.2 dev: true - /throttleit@1.0.0: - resolution: {integrity: sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==} + /throttleit@1.0.1: + resolution: {integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==} dev: true /through@2.3.8: @@ -6831,11 +6864,6 @@ packages: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} dev: true - /timed-out@4.0.1: - resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} - engines: {node: '>=0.10.0'} - dev: true - /tmp@0.2.1: resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} engines: {node: '>=8.17.0'} @@ -6874,7 +6902,7 @@ packages: engines: {node: '>=6'} dependencies: psl: 1.9.0 - punycode: 2.3.0 + punycode: 2.3.1 universalify: 0.2.0 url-parse: 1.5.10 dev: true @@ -6922,6 +6950,11 @@ packages: engines: {node: '>=8'} dev: true + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: true + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -6934,8 +6967,8 @@ packages: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-typed-array: 1.1.12 dev: true @@ -6943,7 +6976,7 @@ packages: resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -6954,7 +6987,7 @@ packages: engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -6963,7 +6996,7 @@ packages: /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 is-typed-array: 1.1.12 dev: true @@ -6974,8 +7007,8 @@ packages: is-typedarray: 1.0.0 dev: true - /typescript@5.1.6: - resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} engines: {node: '>=14.17'} hasBin: true dev: true @@ -6983,7 +7016,7 @@ packages: /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 @@ -7000,6 +7033,11 @@ packages: resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} dev: true + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + requiresBuild: true + dev: true + /unicode-canonical-property-names-ecmascript@2.0.0: resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} engines: {node: '>=4'} @@ -7033,8 +7071,8 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /universalify@2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} dev: true @@ -7048,28 +7086,28 @@ packages: engines: {node: '>=8'} dev: true - /update-browserslist-db@1.0.11(browserslist@4.21.10): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + /update-browserslist-db@1.0.13(browserslist@4.22.2): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.21.10 + browserslist: 4.22.2 escalade: 3.1.1 picocolors: 1.0.0 dev: true - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + /update-check@1.5.4: + resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==} dependencies: - punycode: 2.3.0 + registry-auth-token: 3.3.2 + registry-url: 3.1.0 dev: true - /url-parse-lax@3.0.0: - resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} - engines: {node: '>=4'} + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - prepend-http: 2.0.0 + punycode: 2.3.1 dev: true /url-parse@1.5.10: @@ -7079,11 +7117,6 @@ packages: requires-port: 1.0.0 dev: true - /url-to-options@1.0.1: - resolution: {integrity: sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==} - engines: {node: '>= 4'} - dev: true - /user-home@2.0.0: resolution: {integrity: sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==} engines: {node: '>=0.10.0'} @@ -7130,23 +7163,22 @@ packages: extsprintf: 1.3.0 dev: true - /viem@1.10.8(typescript@5.1.6)(zod@3.22.3): - resolution: {integrity: sha512-/kVDjc9j1OVoDsxV0E1iw1ehPuWPXv5x/9Yc1H0wKky6ACWRoKsURDeLi0Xwtli7vmFcJne+MMPhA96zVu5iIg==} + /viem@1.20.0(typescript@5.3.3)(zod@3.22.4): + resolution: {integrity: sha512-yPjV9pJr10xi28C/9LEvs5zdZNEMiru3Kz7nufghVYABJAfeSkoZQXb6b23n7MscS7c55JO5nmUI3xKkd9g6Yg==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: typescript: optional: true dependencies: - '@adraffy/ens-normalize': 1.9.4 + '@adraffy/ens-normalize': 1.10.0 '@noble/curves': 1.2.0 '@noble/hashes': 1.3.2 '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 - '@types/ws': 8.5.5 - abitype: 0.9.8(typescript@5.1.6)(zod@3.22.3) - isomorphic-ws: 5.0.0(ws@8.13.0) - typescript: 5.1.6 + abitype: 0.9.8(typescript@5.3.3)(zod@3.22.4) + isows: 1.0.3(ws@8.13.0) + typescript: 5.3.3 ws: 8.13.0 transitivePeerDependencies: - bufferutil @@ -7154,13 +7186,13 @@ packages: - zod dev: true - /wait-on@7.0.1(debug@4.3.4): - resolution: {integrity: sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog==} + /wait-on@7.2.0(debug@4.3.4): + resolution: {integrity: sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==} engines: {node: '>=12.0.0'} hasBin: true dependencies: - axios: 0.27.2(debug@4.3.4) - joi: 17.10.1 + axios: 1.6.2(debug@4.3.4) + joi: 17.11.0 lodash: 4.17.21 minimist: 1.2.8 rxjs: 7.8.1 @@ -7186,7 +7218,7 @@ packages: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true - /webpack-dev-middleware@5.3.3(webpack@5.88.2): + /webpack-dev-middleware@5.3.3(webpack@5.89.0): resolution: {integrity: sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -7197,10 +7229,10 @@ packages: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.88.2 + webpack: 5.89.0 dev: true - /webpack-dev-server@4.15.1(debug@4.3.4)(webpack@5.88.2): + /webpack-dev-server@4.15.1(debug@4.3.4)(webpack@5.89.0): resolution: {integrity: sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==} engines: {node: '>= 12.13.0'} hasBin: true @@ -7213,13 +7245,13 @@ packages: webpack-cli: optional: true dependencies: - '@types/bonjour': 3.5.10 - '@types/connect-history-api-fallback': 1.5.1 - '@types/express': 4.17.17 - '@types/serve-index': 1.9.1 - '@types/serve-static': 1.15.2 - '@types/sockjs': 0.3.33 - '@types/ws': 8.5.5 + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.21 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.5 + '@types/sockjs': 0.3.36 + '@types/ws': 8.5.10 ansi-html-community: 0.0.8 bonjour-service: 1.1.1 chokidar: 3.5.3 @@ -7230,20 +7262,20 @@ packages: express: 4.18.2 graceful-fs: 4.2.11 html-entities: 2.4.0 - http-proxy-middleware: 2.0.6(@types/express@4.17.17)(debug@4.3.4) + http-proxy-middleware: 2.0.6(@types/express@4.17.21)(debug@4.3.4) ipaddr.js: 2.1.0 - launch-editor: 2.6.0 + launch-editor: 2.6.1 open: 8.4.2 p-retry: 4.6.2 rimraf: 3.0.2 schema-utils: 4.2.0 - selfsigned: 2.1.1 + selfsigned: 2.4.1 serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.88.2 - webpack-dev-middleware: 5.3.3(webpack@5.88.2) - ws: 8.14.1 + webpack: 5.89.0 + webpack-dev-middleware: 5.3.3(webpack@5.89.0) + ws: 8.15.1 transitivePeerDependencies: - bufferutil - debug @@ -7251,11 +7283,12 @@ packages: - utf-8-validate dev: true - /webpack-merge@5.9.0: - resolution: {integrity: sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==} + /webpack-merge@5.10.0: + resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} engines: {node: '>=10.0.0'} dependencies: clone-deep: 4.0.1 + flat: 5.0.2 wildcard: 2.0.1 dev: true @@ -7264,8 +7297,8 @@ packages: engines: {node: '>=10.13.0'} dev: true - /webpack@5.88.2: - resolution: {integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==} + /webpack@5.89.0: + resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -7274,17 +7307,17 @@ packages: webpack-cli: optional: true dependencies: - '@types/eslint-scope': 3.7.4 - '@types/estree': 1.0.1 + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.5 '@webassemblyjs/ast': 1.11.6 '@webassemblyjs/wasm-edit': 1.11.6 '@webassemblyjs/wasm-parser': 1.11.6 - acorn: 8.10.0 - acorn-import-assertions: 1.9.0(acorn@8.10.0) - browserslist: 4.21.10 + acorn: 8.11.2 + acorn-import-assertions: 1.9.0(acorn@8.11.2) + browserslist: 4.22.2 chrome-trace-event: 1.0.3 enhanced-resolve: 5.15.0 - es-module-lexer: 1.3.1 + es-module-lexer: 1.4.1 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 @@ -7295,7 +7328,7 @@ packages: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.9(webpack@5.88.2) + terser-webpack-plugin: 5.3.9(webpack@5.89.0) watchpack: 2.4.0 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -7348,12 +7381,12 @@ packages: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} dev: true - /which-typed-array@1.1.11: - resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} + /which-typed-array@1.1.13: + resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 @@ -7367,6 +7400,13 @@ packages: isexe: 2.0.0 dev: true + /widest-line@4.0.1: + resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + dev: true + /wildcard@2.0.1: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} dev: true @@ -7389,6 +7429,15 @@ packages: strip-ansi: 6.0.1 dev: true + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: true + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true @@ -7415,8 +7464,8 @@ packages: optional: true dev: true - /ws@8.14.1: - resolution: {integrity: sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A==} + /ws@8.15.1: + resolution: {integrity: sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -7495,5 +7544,5 @@ packages: engines: {node: '>=12.20'} dev: true - /zod@3.22.3: - resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} + /zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} diff --git a/versions.json b/versions.json new file mode 100644 index 000000000000..cace6e6c340b --- /dev/null +++ b/versions.json @@ -0,0 +1,8 @@ +{ + "abigen": "v1.10.25", + "foundry": "a170021b0e058925047a2c9697ba61f10fc0b2ce", + "geth": "v1.13.4", + "nvm": "v20.9.0", + "slither": "0.10.0", + "kontrol": "0.1.196" +}